gravitation-3+dfsg1.orig/0000755000175000017500000000000010762704661014151 5ustar pabspabsgravitation-3+dfsg1.orig/game5/0000755000175000017500000000000010762704671015150 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/0000755000175000017500000000000010762704666016253 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/win32/0000755000175000017500000000000010770165273017207 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/win32/Gravitation.ico0000644000175000017500000000137610762054365022201 0ustar pabspabs ш( @Жmmmџџџџmmџ""""""""DDDD""""""""DDDD""""""""DDDD""""""""DDDD""""""""DDDD""""""""DDDD""""""""DDDD""""""""DDDD""""3333DDDD""""3333DDDD""""3333DDDD""""3333DDDD""""3333DDDD""""3333DDDD""""3333DDDD""""3333DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDgravitation-3+dfsg1.orig/game5/build/win32/iconSource.png0000644000175000017500000000021510762054365022024 0ustar pabspabs‰PNG  IHDR ќэЃTIDATHЧcЬЭЭeР&1ђpˆ31аŒZ0jх€q O\:ўџЧ‘ђFу`д‚‘c##v4DЃ ] XЖуh1LžL’AлGу`д‚ЁkМ п8МdIENDЎB`‚gravitation-3+dfsg1.orig/game5/build/win32/iconSource.ppm0000644000175000017500000000601510762054365022040 0ustar pabspabsP6 32 32 255 mmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmgravitation-3+dfsg1.orig/game5/build/win32/iconSource_256.png0000644000175000017500000000020110762054365022413 0ustar pabspabs‰PNG  IHDR DЄŠЦPLTEmmmџmmЖџџџџе‚„c-IDAT8Ыc`€F4Р€†Й&(`†(€+Ё ``Є)@O0€‘Ђ†ЗHдA‘нѓЉIENDЎB`‚gravitation-3+dfsg1.orig/game5/build/win32/iconSource_256.ppm0000644000175000017500000000601510762054365022434 0ustar pabspabsP6 32 32 255 mmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmЖЖЖЖЖЖЖЖџџџџџџџџџџџџџџџџџmmџmmџmmџmmџmmџmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖЖmmmmmmmmmmmmmmmmmmmmmmmmgravitation-3+dfsg1.orig/game5/build/makeDistributions0000755000175000017500000000167510762054011021670 0ustar pabspabs#!/bin/sh # # Modification History # # 2007-November-12 Jason Rohrer # Copied from Cultivation build. # if [ $# -lt 2 ] ; then echo "Usage: $0 release_name unix_platform_name" exit 1 fi rm -rf unix rm -rf windows mkdir windows mkdir unix # work on unix tree first mkdir unix/Gravitation mkdir unix/Gravitation/graphics mkdir unix/Gravitation/music mkdir unix/Gravitation/settings cp ../documentation/Readme.txt unix/Gravitation/ cp ../gameSource/graphics/*.tga unix/Gravitation/graphics cp ../gameSource/music/*.tga unix/Gravitation/music cp ../gameSource/settings/*.ini unix/Gravitation/settings # duplicate unix tree so far to make windows tree cp -r unix/Gravitation windows/ cp ../gameSource/Gravitation unix/Gravitation/ cp win32/Gravitation.exe win32/*.dll windows/Gravitation/ cd unix tar cf "Gravitation_$1_$2.tar" Gravitation gzip "Gravitation_$1_$2.tar" cd ../windows zip -r "Gravitation_$1_Windows.zip" Gravitation gravitation-3+dfsg1.orig/game5/build/makeDistributionMacOSX0000755000175000017500000000220710762054011022510 0ustar pabspabs#!/bin/sh # # Modification History # # 2007-November-12 Jason Rohrer # Copied from Cultivation build. # if [ $# -lt 3 ] ; then echo "Usage: $0 release_name unix_platform_name path_to_SDL.framework" exit 1 fi rm -rf mac mkdir mac mkdir mac/Gravitation mkdir mac/Gravitation/graphics mkdir mac/Gravitation/music mkdir mac/Gravitation/settings cp ../documentation/Readme.txt mac/Gravitation/ cp ../gameSource/graphics/*.tga mac/Gravitation/graphics cp ../gameSource/music/*.tga mac/Gravitation/music cp ../gameSource/settings/*.ini mac/Gravitation/settings cp -r macOSX/Gravitation.app mac/Gravitation/Gravitation.app cp ../gameSource/Gravitation mac/Gravitation/Gravitation.app/Contents/MacOS rm -r mac/Gravitation/Gravitation.app/CVS rm -r mac/Gravitation/Gravitation.app/Contents/CVS rm -r mac/Gravitation/Gravitation.app/Contents/MacOS/CVS rm -r mac/Gravitation/Gravitation.app/Contents/Resources/CVS rm -r mac/Gravitation/Gravitation.app/Contents/Frameworks/CVS # install SDL framework cp -r $3 mac/Gravitation/Gravitation.app/Contents/Frameworks/ cd mac tar cf "Gravitation_$1_$2.tar" Gravitation gzip "Gravitation_$1_$2.tar" gravitation-3+dfsg1.orig/game5/build/macOSX/0000755000175000017500000000000010762704665017404 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/macOSX/iconMask.png0000644000175000017500000000033410762054364021650 0ustar pabspabs‰PNG  IHDR€€L\іœЃIDATxкэн Р@ Бfќ9g$VН~В TЪhкЮІ$sГэ}žс(@@@@@@@€oЄэюфъЖїёAу0@@@@@@@€xСЂ y+ђv„IENDЎB`‚gravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/0000755000175000017500000000000010762704665022452 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/0000755000175000017500000000000010762704665024247 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/MacOS/0000755000175000017500000000000010762704665025211 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/MacOS/dummy.txt0000644000175000017500000000012510762054364027075 0ustar pabspabsA placeholder file so that "cvs export" will include this otherwise empty directory.gravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/PkgInfo0000644000175000017500000000001010762054364025510 0ustar pabspabsAPPL????gravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/Resources/0000755000175000017500000000000010762704665026221 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/Resources/Gravitation.icns0000644000175000017500000004304010762065674031367 0ustar pabspabsicnsF it32YНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџНYНџYЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџЈнџYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈНYНЈYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYПYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнНYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYНYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYџYПYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYНџYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнYнНYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYННYНYt8mk@џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/Resources/Gravitation.rsrc0000644000175000017500000000552710762054365031407 0ustar pabspabs ЇЇА;)This application needs at least a MacPlus"This application needs more memory!This application is out of memory*This application needs at least System 8.6 About this wxWindows Application}This application needs Appearance extension (built in with System 8) - this restriction will be relieved in the final release"џџџ§AboutЩ-Dр01Ц#b""#b1Ц0рр№јќ?ў?ў?ў?ў?ўќј№рDD№ˆp @@€€№јј№№рРР€€D!@€@€@€@€!€Ррp8?€џРџРџРџРџРР?р№ј|>Dр№88< ngc†aЦ`цpv0<јр@№?ј<<~џo†чЧcцсїpўp~<<ќ№@D€€€€€€р№№№№PPPРРРРРРр№?ј?ј?ј?ј?ј?ј?ј?ј DР@@Р1€Gў€€ў€@Р@РР€?€РРРР?€ўџџџџџўџРџРџРџРџ€?€D€`Œу€€€€Рј€р№ќџџџџџџџџџџџџјD@x`ќqЮy†|~И|0l0F00РxрќёўћџџЯџџџОџќўxџxяјЯј‡јјD>~ўў>6b`РР?џџџџїѓсрРD€Рр€€€ќќ€€€рР€€Рр№јР?ў?ў?ў?ўРј№рР€D€Рр€ˆŒ?ўŒˆ€рР€€Рр№ шм?ўџ?ўм ш№рР€D Ррp8?—ус!№1ј:|<<>??€ Dxpp`HрР€€H88xўќјp№№щ№Чр‡Р„Œ>\<<8|ќќD @јє *Ј№€8`€>|pрќ?ііўќј?№Рјр AРЂ№ЅќKџзџРёџџ№рџќ€џџџ€џџџ€?џў€џџў€?џњРџџіџџю_џџоџџџОЯџџѓџўџфџ§ўс?ћќрOїјря№xпр?Р€?€р?x><И№`AРу№чќЯџпџРџџџ№џџџќџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџўџџџќџџџјџџџ№џџрџџРџџ€џџўќј№`@ Р№ыќŽџЏў—ўпўяњПч‹цХм0и0`Р Р№џќџџџџџџџџџџџџџўџќ?ј№рР€ь oРоНжfoРоЛюeffoРтЭОЛfffnь,Ѕffff`сТІffffаННцfffmРџіffff\Рьпfffm џќ пffPпќ]Р пm џР uР апќ mР џРЮeЯќнoРѕїыё+ѕјˆ‚Vвввьёјљћ^^§‚яАьвввьёїѕ­]33^‡^‚гвввввы§‚33Ќевывввввввѕˆ33_явввввввв€ћ^]]евввввввв€і§џжьвввввввв€++ѕўїєяыввввв€іљџ§ўі+Wў№ывв€іVџџї~ЊіїWѓь€+Vџџї1Э†іїњ+Vџџїѕzы€іVџџї*Ћь€+џџї[Ћ№§їš STR#RMENU^MBARjcarbvldes‚CURSšICN#Nics#Zics4fics8r€џџ?џџeџџm€џџsџџ‰ џџŸ џџч џџ/ џџwџџПџџџџOџџ—џџпџџ'џџoџџЗџџџџџGџџ€џџз€џџл€џџ€џџЃSimple Alert Messagesgravitation-3+dfsg1.orig/game5/build/macOSX/Gravitation.app/Contents/Info.plist0000644000175000017500000000201210762054364026204 0ustar pabspabs CFBundleInfoDictionaryVersion 6.0 CFBundleIdentifier org.passage CFBundleDevelopmentRegion English CFBundleExecutable Gravitation CFBundleIconFile Gravitation.icns CFBundleName Gravitation CFBundlePackageType APPL CFBundleSignature ???? CFBundleVersion 0 CFBundleShortVersionString 0 CFBundleGetInfoString Gravitation CFBundleLongVersionString 0 NSHumanReadableCopyright Public Domain, 2008 LSRequiresCarbon CSResourcesFileMapped gravitation-3+dfsg1.orig/game5/build/macOSX/iconColor.png0000644000175000017500000000045310762054364022035 0ustar pabspabs‰PNG  IHDR€€L\іœђIDATxкэдб € @A0.ч0eйEЦУ)См пИ”%ГЛь]Kоџ(њ4 €@ €€TŸфЎьЬ™Лk&Р$€@ €@€ьjЭ]L€@ €@ ыwŽˆмzпњ† №  €@ €А~/OY Я4‘ФьIENDЎB`‚gravitation-3+dfsg1.orig/game5/build/source/0000755000175000017500000000000010762704666017553 5ustar pabspabsgravitation-3+dfsg1.orig/game5/build/source/runToBuild0000755000175000017500000000075710762054365021573 0ustar pabspabs#!/bin/bash # # Modification History # # 2007-November-12 Jason Rohrer # Copied from Cultivation. # cd game5/gameSource chmod u+x ./configure ./configure echo "Building Gravitation..." make cd ../.. mkdir graphics mkdir music mkdir settings cp game5/gameSource/Gravitation ./Gravitation cp game5/documentation/Readme.txt . cp game5/gameSource/graphics/* ./graphics cp game5/gameSource/music/* ./music cp game5/gameSource/settings/* ./settings echo "Run Gravitation to play." gravitation-3+dfsg1.orig/game5/build/source/exportSrc0000755000175000017500000000027310762054365021466 0ustar pabspabscvs -z3 -d:ext:jcr13@minorgems.cvs.sourceforge.net:/cvsroot/minorgems export -r HEAD minorGems cvs -z3 -d:ext:jcr13@hcsoftware.cvs.sourceforge.net:/cvsroot/hcsoftware export -r HEAD game5gravitation-3+dfsg1.orig/game5/build/source/cleanSrc0000755000175000017500000000042210762054365021223 0ustar pabspabsrm -r minorGems/ai rm -r minorGems/bench rm -r minorGems/doc rm -r minorGems/examples rm -r minorGems/sound rm -r minorGems/temp rm -r minorGems/graphics/openGL rm -r minorGems/network rm -r minorGems/math rm -r game5/documentation/concept rm -r game5/documentation/html gravitation-3+dfsg1.orig/game5/gameSource/0000755000175000017500000000000010762704673017244 5ustar pabspabsgravitation-3+dfsg1.orig/game5/gameSource/mac/0000755000175000017500000000000010762704673020004 5ustar pabspabsgravitation-3+dfsg1.orig/game5/gameSource/mac/SDLMain.h0000644000175000017500000000046310734770150021377 0ustar pabspabs/* SDLMain.m - main entry point for our Cocoa-ized SDL app Initial Version: Darrell Walisser Non-NIB-Code & other changes: Max Horn Feel free to customize this file to suit your needs */ #import @interface SDLMain : NSObject @end gravitation-3+dfsg1.orig/game5/gameSource/mac/SDLMain.m0000644000175000017500000002572410734770150021413 0ustar pabspabs/* SDLMain.m - main entry point for our Cocoa-ized SDL app Initial Version: Darrell Walisser Non-NIB-Code & other changes: Max Horn Feel free to customize this file to suit your needs */ #import #import "SDLMain.h" #import /* for MAXPATHLEN */ #import /* For some reaon, Apple removed setAppleMenu from the headers in 10.4, but the method still is there and works. To avoid warnings, we declare it ourselves here. */ @interface NSApplication(SDL_Missing_Methods) - (void)setAppleMenu:(NSMenu *)menu; @end /* Use this flag to determine whether we use SDLMain.nib or not */ #define SDL_USE_NIB_FILE 0 /* Use this flag to determine whether we use CPS (docking) or not */ #define SDL_USE_CPS 1 #ifdef SDL_USE_CPS /* Portions of CPS.h */ typedef struct CPSProcessSerNum { UInt32 lo; UInt32 hi; } CPSProcessSerNum; extern OSErr CPSGetCurrentProcess( CPSProcessSerNum *psn); extern OSErr CPSEnableForegroundOperation( CPSProcessSerNum *psn, UInt32 _arg2, UInt32 _arg3, UInt32 _arg4, UInt32 _arg5); extern OSErr CPSSetFrontProcess( CPSProcessSerNum *psn); #endif /* SDL_USE_CPS */ static int gArgc; static char **gArgv; static BOOL gFinderLaunch; static BOOL gCalledAppMainline = FALSE; static NSString *getApplicationName(void) { NSDictionary *dict; NSString *appName = 0; /* Determine the application name */ dict = (NSDictionary *)CFBundleGetInfoDictionary(CFBundleGetMainBundle()); if (dict) appName = [dict objectForKey: @"CFBundleName"]; if (![appName length]) appName = [[NSProcessInfo processInfo] processName]; return appName; } #if SDL_USE_NIB_FILE /* A helper category for NSString */ @interface NSString (ReplaceSubString) - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString; @end #endif @interface SDLApplication : NSApplication @end @implementation SDLApplication /* Invoked from the Quit menu item */ - (void)terminate:(id)sender { /* Post a SDL_QUIT event */ SDL_Event event; event.type = SDL_QUIT; SDL_PushEvent(&event); } @end /* The main class of the application, the application's delegate */ @implementation SDLMain /* Set the working directory to the .app's parent directory */ - (void) setupWorkingDirectory:(BOOL)shouldChdir { if (shouldChdir) { char parentdir[MAXPATHLEN]; CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle()); CFURLRef url2 = CFURLCreateCopyDeletingLastPathComponent(0, url); if (CFURLGetFileSystemRepresentation(url2, true, (UInt8 *)parentdir, MAXPATHLEN)) { assert ( chdir (parentdir) == 0 ); /* chdir to the binary app's parent */ } CFRelease(url); CFRelease(url2); } } #if SDL_USE_NIB_FILE /* Fix menu to contain the real app name instead of "SDL App" */ - (void)fixMenu:(NSMenu *)aMenu withAppName:(NSString *)appName { NSRange aRange; NSEnumerator *enumerator; NSMenuItem *menuItem; aRange = [[aMenu title] rangeOfString:@"SDL App"]; if (aRange.length != 0) [aMenu setTitle: [[aMenu title] stringByReplacingRange:aRange with:appName]]; enumerator = [[aMenu itemArray] objectEnumerator]; while ((menuItem = [enumerator nextObject])) { aRange = [[menuItem title] rangeOfString:@"SDL App"]; if (aRange.length != 0) [menuItem setTitle: [[menuItem title] stringByReplacingRange:aRange with:appName]]; if ([menuItem hasSubmenu]) [self fixMenu:[menuItem submenu] withAppName:appName]; } [ aMenu sizeToFit ]; } #else static void setApplicationMenu(void) { /* warning: this code is very odd */ NSMenu *appleMenu; NSMenuItem *menuItem; NSString *title; NSString *appName; appName = getApplicationName(); appleMenu = [[NSMenu alloc] initWithTitle:@""]; /* Add menu items */ title = [@"About " stringByAppendingString:appName]; [appleMenu addItemWithTitle:title action:@selector(orderFrontStandardAboutPanel:) keyEquivalent:@""]; [appleMenu addItem:[NSMenuItem separatorItem]]; title = [@"Hide " stringByAppendingString:appName]; [appleMenu addItemWithTitle:title action:@selector(hide:) keyEquivalent:@"h"]; menuItem = (NSMenuItem *)[appleMenu addItemWithTitle:@"Hide Others" action:@selector(hideOtherApplications:) keyEquivalent:@"h"]; [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)]; [appleMenu addItemWithTitle:@"Show All" action:@selector(unhideAllApplications:) keyEquivalent:@""]; [appleMenu addItem:[NSMenuItem separatorItem]]; title = [@"Quit " stringByAppendingString:appName]; [appleMenu addItemWithTitle:title action:@selector(terminate:) keyEquivalent:@"q"]; /* Put menu into the menubar */ menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""]; [menuItem setSubmenu:appleMenu]; [[NSApp mainMenu] addItem:menuItem]; /* Tell the application object that this is now the application menu */ [NSApp setAppleMenu:appleMenu]; /* Finally give up our references to the objects */ [appleMenu release]; [menuItem release]; } /* Create a window menu */ static void setupWindowMenu(void) { NSMenu *windowMenu; NSMenuItem *windowMenuItem; NSMenuItem *menuItem; windowMenu = [[NSMenu alloc] initWithTitle:@"Window"]; /* "Minimize" item */ menuItem = [[NSMenuItem alloc] initWithTitle:@"Minimize" action:@selector(performMiniaturize:) keyEquivalent:@"m"]; [windowMenu addItem:menuItem]; [menuItem release]; /* Put menu into the menubar */ windowMenuItem = [[NSMenuItem alloc] initWithTitle:@"Window" action:nil keyEquivalent:@""]; [windowMenuItem setSubmenu:windowMenu]; [[NSApp mainMenu] addItem:windowMenuItem]; /* Tell the application object that this is now the window menu */ [NSApp setWindowsMenu:windowMenu]; /* Finally give up our references to the objects */ [windowMenu release]; [windowMenuItem release]; } /* Replacement for NSApplicationMain */ static void CustomApplicationMain (int argc, char **argv) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; SDLMain *sdlMain; /* Ensure the application object is initialised */ [SDLApplication sharedApplication]; #ifdef SDL_USE_CPS { CPSProcessSerNum PSN; /* Tell the dock about us */ if (!CPSGetCurrentProcess(&PSN)) if (!CPSEnableForegroundOperation(&PSN,0x03,0x3C,0x2C,0x1103)) if (!CPSSetFrontProcess(&PSN)) [SDLApplication sharedApplication]; } #endif /* SDL_USE_CPS */ /* Set up the menubar */ [NSApp setMainMenu:[[NSMenu alloc] init]]; setApplicationMenu(); setupWindowMenu(); /* Create SDLMain and make it the app delegate */ sdlMain = [[SDLMain alloc] init]; [NSApp setDelegate:sdlMain]; /* Start the main event loop */ [NSApp run]; [sdlMain release]; [pool release]; } #endif /* * Catch document open requests...this lets us notice files when the app * was launched by double-clicking a document, or when a document was * dragged/dropped on the app's icon. You need to have a * CFBundleDocumentsType section in your Info.plist to get this message, * apparently. * * Files are added to gArgv, so to the app, they'll look like command line * arguments. Previously, apps launched from the finder had nothing but * an argv[0]. * * This message may be received multiple times to open several docs on launch. * * This message is ignored once the app's mainline has been called. */ - (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename { const char *temparg; size_t arglen; char *arg; char **newargv; if (!gFinderLaunch) /* MacOS is passing command line args. */ return FALSE; if (gCalledAppMainline) /* app has started, ignore this document. */ return FALSE; temparg = [filename UTF8String]; arglen = SDL_strlen(temparg) + 1; arg = (char *) SDL_malloc(arglen); if (arg == NULL) return FALSE; newargv = (char **) realloc(gArgv, sizeof (char *) * (gArgc + 2)); if (newargv == NULL) { SDL_free(arg); return FALSE; } gArgv = newargv; SDL_strlcpy(arg, temparg, arglen); gArgv[gArgc++] = arg; gArgv[gArgc] = NULL; return TRUE; } /* Called when the internal event loop has just started running */ - (void) applicationDidFinishLaunching: (NSNotification *) note { int status; /* Set the working directory to the .app's parent directory */ [self setupWorkingDirectory:gFinderLaunch]; #if SDL_USE_NIB_FILE /* Set the main menu to contain the real app name instead of "SDL App" */ [self fixMenu:[NSApp mainMenu] withAppName:getApplicationName()]; #endif /* Hand off to main application code */ gCalledAppMainline = TRUE; status = SDL_main (gArgc, gArgv); /* We're done, thank you for playing */ exit(status); } @end @implementation NSString (ReplaceSubString) - (NSString *)stringByReplacingRange:(NSRange)aRange with:(NSString *)aString { unsigned int bufferSize; unsigned int selfLen = [self length]; unsigned int aStringLen = [aString length]; unichar *buffer; NSRange localRange; NSString *result; bufferSize = selfLen + aStringLen - aRange.length; buffer = NSAllocateMemoryPages(bufferSize*sizeof(unichar)); /* Get first part into buffer */ localRange.location = 0; localRange.length = aRange.location; [self getCharacters:buffer range:localRange]; /* Get middle part into buffer */ localRange.location = 0; localRange.length = aStringLen; [aString getCharacters:(buffer+aRange.location) range:localRange]; /* Get last part into buffer */ localRange.location = aRange.location + aRange.length; localRange.length = selfLen - localRange.location; [self getCharacters:(buffer+aRange.location+aStringLen) range:localRange]; /* Build output string */ result = [NSString stringWithCharacters:buffer length:bufferSize]; NSDeallocateMemoryPages(buffer, bufferSize); return result; } @end #ifdef main # undef main #endif /* Main entry point to executable - should *not* be SDL_main! */ int main (int argc, char **argv) { /* Copy the arguments into a global variable */ /* This is passed if we are launched by double-clicking */ if ( argc >= 2 && strncmp (argv[1], "-psn", 4) == 0 ) { gArgv = (char **) SDL_malloc(sizeof (char *) * 2); gArgv[0] = argv[0]; gArgv[1] = NULL; gArgc = 1; gFinderLaunch = YES; } else { int i; gArgc = argc; gArgv = (char **) SDL_malloc(sizeof (char *) * (argc+1)); for (i = 0; i <= argc; i++) gArgv[i] = argv[i]; gFinderLaunch = NO; } #if SDL_USE_NIB_FILE [SDLApplication poseAsClass:[NSApplication class]]; NSApplicationMain (argc, argv); #else CustomApplicationMain (argc, argv); #endif return 0; } gravitation-3+dfsg1.orig/game5/gameSource/Envelope.h0000644000175000017500000000230410734770146021166 0ustar pabspabs class Envelope { public: /** * Constructs an envelope. * * All parameters are in range 0..1, and sum of the three time * parameters must be <= 1. * * @param inMaxNoteLengthInGridSteps the maximum note length to * cover. Exact envelopes will be generated for notes up * to this length. * @param inGridStepDurationInSamples the number of samples * per grid step. */ Envelope( double inAttackTime, double inDecayTime, double inSustainLevel, double inReleaseTime, int inMaxNoteLengthInGridSteps, int inGridStepDurationInSamples ); ~Envelope(); /** * Gets an evenlope for a given note length. * * @return an evelope of values in [0,1] that can be indexed by * sample number. Will be destroyed when this class is destroyed. */ double *getEnvelope( int inNoteLengthInGridSteps ); private: int mNumComputedEnvelopes; int *mEvelopeLengths; double **mComputedEnvelopes; }; gravitation-3+dfsg1.orig/game5/gameSource/Makefile.GnuLinux0000644000175000017500000000023110734770146022445 0ustar pabspabsPLATFORM_PATH = linux PLATFORM_NAME = Linux TIME_PLATFORM_PATH = unix TIME_PLATFORM_NAME = Unix PLATFORM_COMPILE_FLAGS = PLATFORM_LINK_FLAGS = -lSDL gravitation-3+dfsg1.orig/game5/gameSource/background.png0000644000175000017500000001630510760402514022061 0ustar pabspabs‰PNG  IHDRcТE†њ ŒIDATxкэЩr$Gr†sЉЌ … t“ДЁЈ1йH#™i$гQzНКш є КQo WLДЁй,F’Э^аиkЏЪL]Фє/Л"€`$Ф?Nь\НТџvїpї?ўт‹/ЂЦx<ЎцoоМЉц777еœђaё‹ƒп[нSkJк'IУЉWЏ^9џЁВ#оПиD[Щgзp№пм‡ƒœkˆqМЇ8x­яžеq­)iŸ$ Ї...юД_ˆ;<ЇлэоЫџђй5<ЧgsqЮсѓщ|У‡eМŸUЏ5%э“Є‚с” |~œS8їйAОћјтPОѓ}ƘЯєнГIœK~ŸДO’ SGGGwъ3u˜ф;оыѕœчаЗb\ŒЧ}ўЃЯ.krŽ/–Яч:mI­)iŸ$ ЇИ7зd_Ќ‰mEЛЬ‡eМ/ЦдФПѓЭy>ёh6›Uѓљ|ю|уnТ)iŸ$е.ПЯWій,>_xФk}іK“˜‘oюГyїˆSœћтше}ДІЄ}’T0œj‚G>,h/ЇŸхУAŸ еф|wпo!Ў9§P­)iŸ$ Їˆ#їеэ&~япФњИИГhыљьGпsЋїзš’іIR­УЉ&y›О|є&1#Ÿ=u_лЊ žњrО|я ќ)iŸ$е.œj’{щѓщ|8ѕ!ОлcиYОмњАќ.љ}в>I*б™KЅ5%э“Є‚сk_œўЮ-s_Й/†Эgљ0‚ЃЩs}qz_mГ3зМ‰ЭЅ5%э“Є‚с”ЯюhRЇв$ж“26”Є|иїiRЛУAЬšNЇNЬ"VњъјЈ5%э“Є‚сuл‡ О:d_*ЫК-›ЏЂ.Ў…ћ%Нч;S˜_Ю(_Џ+Ю}§Ї„Sв>I*&G“XОo€9ыДХ”.э“ЄТу{uвfёХ€hЫxїьѓuњЈŒq­k|5У>мс9ОїЇЭХѓ}з*>%э“ЄТудлЗoЋ?|1uЮЙ?ш‹я$РЏAпlД‘ЕNˆК]ф+х‘гvѓХк}ёrnњ№ЎIЯхyJћ$Љ№8ХОУФ gЏИ[ьЏХ’шKnџЮgЫјќJ_Ž‚ЏŸŒoпаЗџHАВПДІЄ}’T0œтФъЙo?Ю‡SNПщН9qїiRЫТѓ˜ђоq_>Њяœ>Ѓж”ДO’ †SОо›Д58|>—_Иwц‹Сs4Щƒ'ŽјpЪЩѓоЕїЊЛжš’іIRСpŠ:ЬЙЯєХ|флCєљwMјšє>n’ цУPк•^kMIћ$Љ`8EФGoR‡мЄŸЇ/NфуŒ№еШ}šФу8Ћ5%э“ЄBИ” "њˆ‘uуYbdNIRэТ)1Вn1ВJћ$Љvс”YoПЇ2ЭЄ}’Txœ#ыц}ФШ*э“Єк…SbdНgхїIћ$Љ№8%FжЭчŠ‘Uк'IЕ ЇФШК9ФШ*э“Єкыї‰‘uѓндGк'I…Ч)1Вnтš: Jћ$Љvс”YoЎ*ЖЅ}’T{qJŒЌяЃ5%э“Є‚с”Y7}X1ВJћ$Љvс”Y7пMŒЌв>IЊ]8%FжM,#ЋДO’jN‰‘ЕЁЭЅ5%э“Є‚с”Яю#ы{s­)iŸ$ ЇФШК‰qЪŸ’іIRэТ)1Вў№žbd•іIRmХ)1Во~­тSв>I*ФШкбХШКљ,1В Ї$Љvс”Y7‡YЅ}’TЛpJŒЌЗпS™fв>I*bd•іIRэТ)1ВоŽГђћЄ}’Txœ#ыцsХШ*э“Єк…Sbdнbd•іIRэѕћФШКљnъ€#э“ЄТу”Y7qMЅ}’TЛpJŒЌЗ?Wлв>IЊН8%FжїЮбš’іIRСpJŒЌ›>ЌYЅ}’TЛpJŒЌ›я&FViŸ$е.œ#ы&–‰‘Uк'IЕ ЇФШкацвš’іIRСpЪgwˆ‘ѕНЙж”ДO’ †SbdнФ8хOIћ$Љvс”YxO1ВJћ$ЉЖт”YoПVё)iŸ$ЇФШъx1ВJћ$ЉVс”Y7Џ#ЋДO’jNё1Вот3jMIћ$Љ`8%Fжл‡тSв>I*I*Lэк­ТоГ›Ьё>юЮЊЮцЊ5%э“Є‚сдh42LСŽЃOokгѓНЁ]Л}bик3Ќ)№УЌsxЇ…нчrjчœ_кЛѕ&†}щ 狉ћнšЭUkJк'IУ)_VЋБžЅŠŒИw{ЋZЄV­sЕАf9gGУŽ~МУmtKсKЎЎэa+УЌќ§‡bs•п'э“ЄТуT“ЎZЬ:ЋљS)vЊззfЇ\_N}wm?ЬdfіW?6ЌщБiЊНnъЮЭмŽ€Ёёні‘/ѓ­Јu’.7нS­)iŸ$ Їš0й{mиSГЕaжwWІџпL `.fІџƒТ*0ћ‹‹w2tфŠ '…йVѓТŽ:vI*0Nљ:вєuY`w$8œх3JѓкЮmО_Tѓg‰?Тў]кГw{бЗsж‰гgХцмЮ_­a+БЙ :яа†ZЖhЎV†Х—Ћžж”ДO’ ŒS>fz_LЧWUЁSФіу>Эа 'ВŒл~4‡M„јTfїйп1ŸёХ‹sЛvЫ€g lњњѕN5?=3пpЙ f!;ЎЬј5_сœеж”ДO’j‘пчЋm}cчпфЇ=еYё„œЌXћ}в>I*4Nљpч1XUН eШ'шvэўƒў˜Х|+Лvћh9і-ьќ|ЬNŠœЯЈtтiYУйTkJк'IЕЇюЫ8ш;Ч‡MѕК™вiээZ koн!Vцдžйпtf~пЋSЋ2??7Псћ(няS{g—/Ќ5%э“Є‚с”/ПбWэgМ@lЋVg‡ъjьФЕЎйMУ-2)к9пОВгdjОлbiј5žи|Б`Х6bRнЛ™`ЕІЄ}’TЛpЪW;тЫџ$#XTЫ“Д9RЭЃŽOБНЦЅйкАigТQ;~ueј8_А;D„9ыŠэœ^Зчў–LАZSв>IЊ]8хыSЗГLЗЩ6. G.ж6ЛВsnV`g~э”Жзж-Ьзл.‘3Еd]ž;ЮU‹Ч'ю| ц…н‹ VkJк'IУ)Ÿ UгaјM‹в0шleё Ws›_,3`:ДУc^BZš6Ц§ЛЌ…ŽG+6]‰ФЮk бньВЮ}­)iŸ$ Ї|ь7АЊЎc›_›ОZЬшэТђ*чyтєJc2ъа_CЎ))bю?к}V№шuЕФ;ЧЈ=d‡ДA=`5зš’іIRСpЪзс˜~й тA/—ы9Х|‘Лc=§ФА`˜šндCŽвnЧц;Ј•f}М[фєћV№%'xŸВ0<эgЖ?и•Юї)Q\CFV1^Hћ$Љ№8Еb#‚>кЪєіћњРЃeфо;ы!gђАkЙнЯћ6uм˜ХњОњ%”%ѓЖь…Ьћш™—€ v„˜њіРlРУ=ыiE#энЛwТ)iŸ$е"œš,С\šš§2)‘‹”[тEZUФz˜—Д :6}М…:•ŒЌ‡РJO>}Нqюhm9œkбЃъbn§‹Ыё6|Щ_–m~1їЂъЙЌ5%э“Є‚сдyaЕЛгиь‹YdН4gБсW~O‰Ї>†qЈјГІvўВЦШъfВgэЮlfиWcЌg}ONЦWЫНЙКРЕЈуя9ЕІЄ}’ThœB\|lZЇvМРЬ§Вк­аПЉ0џё|iїЬ ›vаo9eўСїDН!АЬЧ4Э|ычєя˜KEfБ*VЅ5%э“Є‚суP9Ћ’‘‹xѓЖy9ш(oО\Ѓ™)бqЅyфљЕ~%ъђЂЕг^ѓ —LV2ž#ІCiŸ$ЇЪўщg‡Ќі‰ŽЂј^`оРх uyј‘ЪФќЪЌsYЭwѓЗvНVтв)M8f|ЬЋО:ЁŠGkJк'IФЉ=ЇOчЗ›ЂЛЯёдњВVff%изcЛрN1С9ž|tЧЬ‡0ИЊYк'IbdmŒшџњoџ^§ёефИšџiнtn/=(^яА9ћџg ehGѓbtчЕ),вƒиЂt‘€Э5ГЎѕ§ьlЎв>с”$ ЇЏeж‘я|m;9vCY­УŒћ­ž §йЖПеe7™в/ЕŽюtи:ЃрЛАЂVl„шvIВ.™…Ш˜–УšuГЙVЌж”ДO’ †S§дєџЈk;‚зшњ>€ўo MЯЗ†';ц‘ўъФpaРюkЬнqЮЇ6џу;{Зo.эк7WЈœЎХЈ6(PUДJЗpAvьИ=mэ8Hћ$Љ№85ZДП—РbFCзєіxЯЮ9š ї€GG#FЮ GОП4\X€щ0'ЋOiЯњh™ћБ=wКpГSАЮ<ВяКШ-›n/БŽєндоDВЇЄ}’TЫpjkЫќЛВƒЌА>X"RtKD‰Ьб5œЯЦ†яРXџхЉaа+dmЌ ІаТ>BїxРZ4_хN_’›ЙЬ"Й.ь[ЎK›o#л­{WѕЖж”ДO’ †Sь8^М†oѕfaОвjiўрndY№Я3ЫМІІѓШ4{scБљяІЈ @Š[3Уb­tк_hd­ fmиЗЬ`[]–Ж|лЗ ;№kХчк•іIRЁq*G|Ifї™1 ЮnаYfЩИ•сдЌ;xИЛ5ЇЈЎŒЃЁ›F}ЛџёШюЙе]:?`ВАw{;†нДшза9Ќ4|&ТFЌЊdП@@Л`—t=OїwПvbгсpъМ–#ЖђкЩВыДЙІ8NццЃ2І>њ!AkJк'IЕЇ8jЌ5fv–`.{„[=ѓ+‡кщ›нDЖh_Z;їћxэЩШ|З]язxŸЃŽНУGШYпOЎЕІЄ}’T`œК7у3уЏ5rжЙїYXПтVѓГл{іб}y?&"ч>CЭqчz›"фahMIћ$Љ`8UuіМ›rнсxв1м)z–sа‹-†н›лўZ:E~fnvж˜3noЂO—zjnhо-—јсQgs›}ѕУТw K•Хш­МiŸ$ЇњшјЩœЃВtcVЭэыкЕбшФŽЇЖЖ˜иqНВ}Н `г—ЏlŸn8ђЋуS_8}Ни8NЯ,Fўюнpfімhхіk182MїДІЄ}’T`œЪctЯТ~мšl5†х&‹й>W—ић‡?5^€ёЌЊ‹Е]ћћгgЮŸŽЙQGˆa‘ѕp‰ДŠ‹SЛњђмОe1cбѓкщчњŠT7#э“ЄТудKјeg`рbŽxЩ‚w…ќѕ1ZЁ,‹%|F;Ю>-lЗЋЙaмWo-‡рнФlЎ!ђ<‰S=0^ŒцпuзЬ -Ж˜Ђ(ъА3a'гš’іIRqъ`Њ™Ќбё5(ЕшyьаўїќФШнQаЗgW"t Ьš/ЩШŠzЬwQWќ‹Ь|Кaцf тЈ3№АЮ Ž…њ%Hћ$Ља8u,ЈсЮНЛFn<Š|Чн]ш'[4йSЩђКл1ЬкъйЗ 22DэxЏgx4кЖž 9њР,–Т)iŸ$Ї˜7Р”ј‘_шБй\йЋ“LakvnЮьx7iMIћ$ЉР8•Цq Gг†њщи\Н8…уuЛR}]Є}’ThœJтv§\Б'зIъgmOеlєсМh›ЋњyJћ$)сдmcUЄА­ Г&ќ™ЭUkJк'I…ЧЉјnJН‡rщnй+Œ=W и\з?!›k•Ч 5%э“ЄB 1В6–д?ќЫWГ8ƒ1В~Ш№АЙFжс№ЯЃпIћ„S’T`ЫГ‰-шУ NЫY?Аkб;АЙІ}­)iŸ$ЇиЩД†A‰ƒŽFІУ;YQ9‰ ‹Ч`d-ЫЛ}Uй\Qк9аš’іIRqjЇoњyВmИГ |9иВљŸэтјЮ?ЁЫWn•гo.-ђџŒЌМO3œrW$ЬJ‹ОЬOДІЄ}’T`œ:˜mђЗЧІшэ`з0ЅЮƒй`'ZЬэјЛ ›_ ћЬзgkЇнTѓн>€‘ЕЖЁYF Ќ(ї`ЩU1дš’іIRqjЏАL‡оФ2JS(њLпЭ­šљЭм2VШЖШбнfОfЇи,+w‡ŠфYййО™чwЧbвš’іIRсьЉт[гfЦ­W)ќ УЃѓ…93џшfэЦ"DюЃG„ŒЌ†•ХШJќђcVЌ5%э“ЄкjOЅ†нV;œЦР/;gžЛmЈвгЭ‹>Бщ``vYРŠ‘ѕь†y­™ж”ДO’z 8еC№)эИЛ25VUѓs :іY)ˆЇvf7§њ…aг?=2#+YЄы]яшђЃ5%э“Є‚сŸ“˜ЙNБП2ЬћшXк)Шz9э,кPЯGжўя‘еКPOб…z•ЛcXNЯPkJк'IУ)ў#gЊп7}>щ[чrЯtўЊаљёмАу -цзЈє!O#FV_е’‡‘•їфГи­9›,%UIћ$Ља8EЛЉŽХ'ЧGfзœ|RЭџŒ†W`яzsmєэйЖ•%/\Nт;qч1Ÿ•xцєOйMu˜ЊS—ДO’ S§ОХkЋљ'lvг1О2УВwcѓуf+t/элАП&/0j,rѓЫюЭШЙ§J^Ы{ЮV]З?‹{іKа:ь‹ЦqwЌ5%э“ЄудіЎБЇюe=фF-б™љп‹9‹є S†]цВЇАЇабцY9ˆMП{ћЬyЯѓ)˜ck}иM‡щM5џ(;Зу‰pJк'I…ЦЉЫhЏњcuc8rКœР™Т3=П^иќхи„~…мtж?#+й‰MМчXFpˆЊGЉuљк‹Џ ЏЫЅж”ДO’ ŒSџ§ЮlјŒё#wWvюпƒ:/‘o…уСШЪ1ХОЯЇХwю`пpP‹Cfuq\qtiŸ$ЇОŸdїК єф”“AАIК'#ыТЭШ{SЧy#фI$ЦD|юГ>ъЎ#АГЦьR(œ’іIRЁq*/hуэƒYёг‘yб“ЯХzуAfАЧC™QЗZZОћvзŽb)бЈ&Ўњ›јЈ5%э“Є‚сд};Щ?F:m%тЮСШі ]З­ДгГљѓ‘9™Ya~мфЦія’ТќЧї™GštЕІЄ}’T‹p*mг!оa„ž|/і /пР~~YdqД^aЙZйкттНЬіИ/I6з"w3aTs­)iŸ$ѕdьЉЧДЇиїюєкlŸё|эЖщ€5мlЈ}ьіьž}дю,vВЙжYЇŸ’іIRТЉњXЌ GоЇќXJиVgVгC†еэЫцЊ5%э“Є„SŽQ lБКuzрI*4NЕƒ‘5z ‡Й{u.YЋlЎ)и\Ћќ­)iŸ$jˆ‘ЕБЄ~оŒЌв>IJ’z –g{ючРШЊ5%IIRэХЉŸ#Ћж”ДO’zк8ЕнЇdXГƒуG`^§ьЬЋ[юъžЖ1ВjMIћ$ЉЇSФЃO ŽwЬV ЇюЬffз иаЯШzFжI{YАж”ДO’ †SГЅсТЫKУ Ы)тJ%|ДмЃDЕqчщ3ВjMIR’Tpœ‚пє§ХxсжђВђкг%ЇнŒЌZSв>IЊ­8yp$/яr„~„ %FViŸ†$ѕ#pъё3їХШ*эгЄЇjUбЬ™ђАnеN*нqёЇУШz‡gЈ5%э“Є‚сд0sГ’]чpфЮлЄ>ЏNO‘U8%э“Єк…SѓЩ6KlВае/ЭW:кёy­[э~{ўєY…Sв>IЊН8ѕЯПйuъ3эІдСє;vвйФь&ц[2НЭŒЌїŠЭiMIR’T0œzБ{lt2^™П6EОхSdd-Ы{т”ђ<Ѕ}’TpœњŸЏЯю<Љєє-xŠŒЌм- аЬBZSв>I*N§чя—їК€˜ѕtYСъƒЭKюcЦžМжЊFZkJк'IУЉяЎяаn5#+~ј дELm†В}ьcіq|Ж4 =ПУНДO’ SџŸYї‡ЈFс_ЗуfOќьШ0‘}#NЏ,oыЗšiMIћ$ЉР8ѕфYћ6џd7u^;˜]Ж=0Š{‘Ii{CАЙ.GзZSв>I*0N=}FV0ЂчL‚ОhЋmwрŸЎьќА‰MЎо>Fc­)iŸ$ѕФьЉЧТШЪо2%БЉgxєёевiБWЬbnЕаГБљ}BŒв>IJ8Uїgdх[!jnомЌq p^ФР>ЗэVГщатІЫих*гš’іIRТЉ‡є яАВšq=шбО.R­)iŸ$Їž>#ыCсZщƒ˜ЃЅ}’TрёПŸhaИ’сRщIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/Gradient.h0000644000175000017500000000075710761044030021142 0ustar pabspabs#ifndef GRADIENT_INCLUDED #define GRADIENT_INCLUDED #include "common.h" #include "minorGems/util/SimpleVector.h" class Gradient { public: Gradient( int inNumPoints, double *inPointAnchors, rgbColor *inPointColors ); // samples from location in range [0,1] along gradient rgbColor sample( double inLocation ); private: SimpleVector mAnchors; SimpleVector mColors; }; #endif gravitation-3+dfsg1.orig/game5/gameSource/tileTemplate.png0000644000175000017500000000031710734770147022402 0ustar pabspabs‰PNG  IHDR˜V ?Ÿ–IDATHЧнеС Р @h: ѓ9 Ур2ьbџ-˜дњMМˆ"`Ў  RЧfтю[ЃW”Y‘ˆДщ+AL{"`_зцtэtх9ГЭщыСџCІ˜#jŠЌнCzp ј2+лЗџƒюu]`JG$а<сЪsЇ%šв Ќеƒ CІ–#jŠЌнCzаMGТEZŸjЩ…ф€TтSХЁцо8‚KE/uZ)7ЄЪk!q*‚*ЙGN\jTW=€ё!­h>дJUф)В#H‚LМ[œT УЌ?тЪ!<V3oџѓцЭћЭ~ Bw#aѕzzns]zDі[ЬпуРјƺРJЅмN:­;’Е ‰TЬяЮžєѓЕPt(:K{$k‘sgLњ;W€\ZВV'GKЩWuЗYЊ“яОLu|}э˜Л-БлюTK‰ъ0ЕN'UдЩOHubє/eЫcЯ0Bw3VчПХХгV,™*:я”N"–Lщ"Ьм(:q’u<ѓO_ќИєQjgeсђфИ!0sЃ Лƒп+ЏЭНљќЛИdо{і№Тспхт.OОіљн…žх‹Ї%kЙUbGŽМє\}ФЧё!ж|œщЪ4SЉМјS32€Ѕ”iš…&`Wещhиs6tьf­fяbW•Rъб˜_)ѕJUv)nmЙЛ§{И\‘ВH.WЋ•8&\™=㇋оэ70ІiЎУ((Ѕ~†Љ?“Ќe$ ЅS'Nxб%Йзdь&ЋЛЌЌ+O$,ЎИ%зЂˆз?ДЎЦЃf/—љжђvUŽšћИЗъv“зЁаtEЊ§М|БЌ!ѓјр0pыОš€B“@ШTЫ x—8Ц_Сх ЧUоYVуQSїуюлВЭ%ПTЮз$ПTЙ&вЫeŽƒ<ђG\†@Ђцџ\ў!\"^nняp!Y(хk2џPЪ )7dћyч=ЋўDцЪЇ5ЙДTіDТС €— р…Єгщ Яхb,:N~nюцъЦЋ##ƒјЦрёЖmчЎЬхл\^>thѕЩЮу=Црл=З3щДЉъ{№hрyяa`эG{ќЪрбРљwЯ+]ыVЫ )oдЫѕЛллSч’Sч’_6dЖxЇѓЇ”,”2•JІRYtœЗ.\XtœdЁєgПћН\К­—г\ШT*mW[dw‰мzф[№єйєЗрuNrМ5~Zфrѕzw‚fЋуo+УУmQОЯ[[џ8ЕDё.‘ъVhЃеЕœШО g77лћЬnnŠДО/WЋ•Їkz6t ј Rе{9]ЫћIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/Timbre.cpp0000644000175000017500000001043110761564355021171 0ustar pabspabs#include "Timbre.h" #include "minorGems/util/stringUtils.h" #include #include double twelthRootOfTwo = pow( 2, 1.0/12 ); // for major scale // W, W, H, W, W, W, H int halfstepMap[ 7 ] = { 0, 2, 4, 5, 7, 9, 11 }; // minor scale // W,H,W,W,H,W,W //int halfstepMap[ 7 ] = { 0, 2, 3, 5, 7, 8, 10 }; // gets frequency of note in our scale double getFrequency( double inBaseFrequency, int inScaleNoteNumber ) { int octavesUp = inScaleNoteNumber / 7; int numHalfsteps = halfstepMap[ inScaleNoteNumber % 7 ] + octavesUp * 12; return inBaseFrequency * pow( twelthRootOfTwo, numHalfsteps ); } /* Was used during testing #include "minorGems/sound/formats/aiff.h" int outputFileNumber = 0; // outputs a wave table as an AIFF void outputWaveTable( Sint16 *inTable, int inLength, int inSampleRate ) { // generate the header int headerSize; unsigned char *aiffHeader = getAIFFHeader( 1, 16, inSampleRate, inLength, &headerSize ); char *fileName = autoSprintf( "waveTable%d.aiff", outputFileNumber ); outputFileNumber++; FILE *aiffFile = fopen( fileName, "wb" ); delete [] fileName; //printf( "Header size = %d\n", headerSize ); fwrite( aiffHeader, 1, headerSize, aiffFile ); delete [] aiffHeader; for( int i=0; i> 8 & 0xFF; unsigned char lsb = val && 0xFF; fwrite( &msb, 1, 1, aiffFile ); fwrite( &lsb, 1, 1, aiffFile ); } fclose( aiffFile ); } */ Timbre::Timbre( int inSampleRate, double inLoudness, double inBaseFrequency, int inNumWaveTableEntries, double( *inWaveFunction )( double ) ) : mNumWaveTableEntries( inNumWaveTableEntries ), mWaveTable( new Sint16*[ inNumWaveTableEntries ] ), mWaveTableLengths( new int[ inNumWaveTableEntries ] ) { // build wave table for each possible pitch in image for( int i=0; i maxValue ) { maxValue = waveValue; } else if( -waveValue > maxValue ) { maxValue = -waveValue; } } // now normalize and convert to int for( s=0; sиˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚5з‚5з‚5з‚5зƒ7зƒ7зƒ7зƒ7з…:з…:з…:з…:иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚5з‚5з‚5з‚5зƒ7зƒ7зƒ7зƒ7з…:з…:з…:з…:иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚5з‚5з‚5з‚5зƒ7зƒ7зƒ7зƒ7з…:з…:з…:з…:иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџз›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ˜–”˜–”˜–”з›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ˜–”˜–”˜–”з›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ˜–”˜–”˜–”з›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ˜–”˜–”˜–”зšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›…›…›…›…“‘“‘“‘зšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›…›…›…›…“‘“‘“‘зšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›…›…›…›…“‘“‘“‘зšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›…›…›…›…“‘“‘“‘з™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™bж™bж™bж™bж™cж™cж™cж™cв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰Œ‹Œ‹Œ‹з™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™bж™bж™bж™bж™cж™cж™cж™cв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰Œ‹Œ‹Œ‹з™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™bж™bж™bж™bж™cж™cж™cж™cв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰Œ‹Œ‹Œ‹з™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™bж™bж™bж™bж™cж™cж™cж™cв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰Œ‹Œ‹Œ‹з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з™`з™`з™`з™`з›cз›cз›cз›cз›dз›dз›dз›dз›eз›eз›eз›eж›eж›eж›eж›eв›jв›jв›jв›jЩ {Щ {Щ {Щ {ОЉ–ОЉ–ОЉ–ОЉ–ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™•••••••••з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з™`з™`з™`з™`з›cз›cз›cз›cз›dз›dз›dз›dз›eз›eз›eз›eж›eж›eж›eж›eв›jв›jв›jв›jЩ {Щ {Щ {Щ {ОЉ–ОЉ–ОЉ–ОЉ–ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™•••••••••з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з™`з™`з™`з™`з›cз›cз›cз›cз›dз›dз›dз›dз›eз›eз›eз›eж›eж›eж›eж›eв›jв›jв›jв›jЩ {Щ {Щ {Щ {ОЉ–ОЉ–ОЉ–ОЉ–ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™•••••••••з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з™`з™`з™`з™`з›cз›cз›cз›cз›dз›dз›dз›dз›eз›eз›eз›eж›eж›eж›eж›eв›jв›jв›jв›jЩ {Щ {Щ {Щ {ОЉ–ОЉ–ОЉ–ОЉ–ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™•••••••••з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з˜^з˜^з˜^з˜^йgйgйgйgнЉyнЉyнЉyнЉyпЏ‚пЏ‚пЏ‚пЏ‚пЏƒпЏƒпЏƒпЏƒл­ƒл­ƒл­ƒл­ƒЯЊ‡ЯЊ‡ЯЊ‡ЯЊ‡РЋ˜РЋ˜РЋ˜РЋ˜ЙВЋЙВЋЙВЋЙВЋЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЊЊЊЊЊЊЊЊЊЊЊЊЉЉЉЉЉЉЉЉЉз—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з˜^з˜^з˜^з˜^йgйgйgйgнЉyнЉyнЉyнЉyпЏ‚пЏ‚пЏ‚пЏ‚пЏƒпЏƒпЏƒпЏƒл­ƒл­ƒл­ƒл­ƒЯЊ‡ЯЊ‡ЯЊ‡ЯЊ‡РЋ˜РЋ˜РЋ˜РЋ˜ЙВЋЙВЋЙВЋЙВЋЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЊЊЊЊЊЊЊЊЊЊЊЊЉЉЉЉЉЉЉЉЉз—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з˜^з˜^з˜^з˜^йgйgйgйgнЉyнЉyнЉyнЉyпЏ‚пЏ‚пЏ‚пЏ‚пЏƒпЏƒпЏƒпЏƒл­ƒл­ƒл­ƒл­ƒЯЊ‡ЯЊ‡ЯЊ‡ЯЊ‡РЋ˜РЋ˜РЋ˜РЋ˜ЙВЋЙВЋЙВЋЙВЋЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЊЊЊЊЊЊЊЊЊЊЊЊЉЉЉЉЉЉЉЉЉз—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з˜^з˜^з˜^з˜^йgйgйgйgнЉyнЉyнЉyнЉyпЏ‚пЏ‚пЏ‚пЏ‚пЏƒпЏƒпЏƒпЏƒл­ƒл­ƒл­ƒл­ƒЯЊ‡ЯЊ‡ЯЊ‡ЯЊ‡РЋ˜РЋ˜РЋ˜РЋ˜ЙВЋЙВЋЙВЋЙВЋЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЊЊЊЊЊЊЊЊЊЊЊЊЉЉЉЉЉЉЉЉЉз–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з—]з—]з—]з—]лЂoлЂoлЂoлЂoуЗŽуЗŽуЗŽуЗŽчТ чТ чТ чТ чФЃчФЃчФЃчФЃтФЈтФЈтФЈтФЈжТЏжТЏжТЏжТЏХМДХМДХМДХМДЛИДЛИДЛИДЛИДИЖДИЖДИЖДИЖДДДГДДГДДГДДГББББББББББББВВВВВВВВВВВВГГГГГГГГГз–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з—]з—]з—]з—]лЂoлЂoлЂoлЂoуЗŽуЗŽуЗŽуЗŽчТ чТ чТ чТ чФЃчФЃчФЃчФЃтФЈтФЈтФЈтФЈжТЏжТЏжТЏжТЏХМДХМДХМДХМДЛИДЛИДЛИДЛИДИЖДИЖДИЖДИЖДДДГДДГДДГДДГББББББББББББВВВВВВВВВВВВГГГГГГГГГз–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з—]з—]з—]з—]лЂoлЂoлЂoлЂoуЗŽуЗŽуЗŽуЗŽчТ чТ чТ чТ чФЃчФЃчФЃчФЃтФЈтФЈтФЈтФЈжТЏжТЏжТЏжТЏХМДХМДХМДХМДЛИДЛИДЛИДЛИДИЖДИЖДИЖДИЖДДДГДДГДДГДДГББББББББББББВВВВВВВВВВВВГГГГГГГГГз–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з—]з—]з—]з—]лЂoлЂoлЂoлЂoуЗŽуЗŽуЗŽуЗŽчТ чТ чТ чТ чФЃчФЃчФЃчФЃтФЈтФЈтФЈтФЈжТЏжТЏжТЏжТЏХМДХМДХМДХМДЛИДЛИДЛИДЛИДИЖДИЖДИЖДИЖДДДГДДГДДГДДГББББББББББББВВВВВВВВВВВВГГГГГГГГГз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз–Zз–Zз–Zз–Zй›cй›cй›cй›cнЇuнЇuнЇuнЇuп­~п­~п­~п­~рЏ‚рЏ‚рЏ‚рЏ‚сЖсЖсЖсЖпТЈпТЈпТЈпТЈеР­еР­еР­еР­ХГЂХГЂХГЂХГЂПБЄПБЄПБЄПБЄМЖАМЖАМЖАМЖАЖЕГЖЕГЖЕГЖЕГГГГГГГГГГГГГГГГГГГГГГз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз–Zз–Zз–Zз–Zй›cй›cй›cй›cнЇuнЇuнЇuнЇuп­~п­~п­~п­~рЏ‚рЏ‚рЏ‚рЏ‚сЖсЖсЖсЖпТЈпТЈпТЈпТЈеР­еР­еР­еР­ХГЂХГЂХГЂХГЂПБЄПБЄПБЄПБЄМЖАМЖАМЖАМЖАЖЕГЖЕГЖЕГЖЕГГГГГГГГГГГГГГГГГГГГГГз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз–Zз–Zз–Zз–Zй›cй›cй›cй›cнЇuнЇuнЇuнЇuп­~п­~п­~п­~рЏ‚рЏ‚рЏ‚рЏ‚сЖсЖсЖсЖпТЈпТЈпТЈпТЈеР­еР­еР­еР­ХГЂХГЂХГЂХГЂПБЄПБЄПБЄПБЄМЖАМЖАМЖАМЖАЖЕГЖЕГЖЕГЖЕГГГГГГГГГГГГГГГГГГГГГГз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз–Zз–Zз–Zз–Zй›cй›cй›cй›cнЇuнЇuнЇuнЇuп­~п­~п­~п­~рЏ‚рЏ‚рЏ‚рЏ‚сЖсЖсЖсЖпТЈпТЈпТЈпТЈеР­еР­еР­еР­ХГЂХГЂХГЂХГЂПБЄПБЄПБЄПБЄМЖАМЖАМЖАМЖАЖЕГЖЕГЖЕГЖЕГГГГГГГГГГГГГГГГГГГГГГз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз•Xз•Xз•Xз•Xз–[з–[з–[з–[и—\и—\и—\и—\и™^и™^и™^и™^кžgкžgкžgкžgмЇvмЇvмЇvмЇvйЇ{йЇ{йЇ{йЇ{бЁvбЁvбЁvбЁvЮЇƒЮЇƒЮЇƒЮЇƒЩГŸЩГŸЩГŸЩГŸЗБЋЗБЋЗБЋЗБЋ­ЌЌ­ЌЌ­ЌЌ­ЌЌ­­­­­­­­­з”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз•Xз•Xз•Xз•Xз–[з–[з–[з–[и—\и—\и—\и—\и™^и™^и™^и™^кžgкžgкžgкžgмЇvмЇvмЇvмЇvйЇ{йЇ{йЇ{йЇ{бЁvбЁvбЁvбЁvЮЇƒЮЇƒЮЇƒЮЇƒЩГŸЩГŸЩГŸЩГŸЗБЋЗБЋЗБЋЗБЋ­ЌЌ­ЌЌ­ЌЌ­ЌЌ­­­­­­­­­з”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз•Xз•Xз•Xз•Xз–[з–[з–[з–[и—\и—\и—\и—\и™^и™^и™^и™^кžgкžgкžgкžgмЇvмЇvмЇvмЇvйЇ{йЇ{йЇ{йЇ{бЁvбЁvбЁvбЁvЮЇƒЮЇƒЮЇƒЮЇƒЩГŸЩГŸЩГŸЩГŸЗБЋЗБЋЗБЋЗБЋ­ЌЌ­ЌЌ­ЌЌ­ЌЌ­­­­­­­­­з”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз•Xз•Xз•Xз•Xз–[з–[з–[з–[и—\и—\и—\и—\и™^и™^и™^и™^кžgкžgкžgкžgмЇvмЇvмЇvмЇvйЇ{йЇ{йЇ{йЇ{бЁvбЁvбЁvбЁvЮЇƒЮЇƒЮЇƒЮЇƒЩГŸЩГŸЩГŸЩГŸЗБЋЗБЋЗБЋЗБЋ­ЌЌ­ЌЌ­ЌЌ­ЌЌ­­­­­­­­­ж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе”Vе”Vе”Vе”Vг•Zг•Zг•Zг•Zг–[г–[г–[г–[г—[г—[г—[г—[д—[д—[д—[д—[ж–[ж–[ж–[ж–[з–Zз–Zз–Zз–Zж•Zж•Zж•Zж•ZеšdеšdеšdеšdЩЂ}ЩЂ}ЩЂ}ЩЂ}БЂ•БЂ•БЂ•БЂ•ЅЃЁЅЃЁЅЃЁЅЃЁЄЄЄЄЄЄЄЄЄж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе”Vе”Vе”Vе”Vг•Zг•Zг•Zг•Zг–[г–[г–[г–[г—[г—[г—[г—[д—[д—[д—[д—[ж–[ж–[ж–[ж–[з–Zз–Zз–Zз–Zж•Zж•Zж•Zж•ZеšdеšdеšdеšdЩЂ}ЩЂ}ЩЂ}ЩЂ}БЂ•БЂ•БЂ•БЂ•ЅЃЁЅЃЁЅЃЁЅЃЁЄЄЄЄЄЄЄЄЄж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе”Vе”Vе”Vе”Vг•Zг•Zг•Zг•Zг–[г–[г–[г–[г—[г—[г—[г—[д—[д—[д—[д—[ж–[ж–[ж–[ж–[з–Zз–Zз–Zз–Zж•Zж•Zж•Zж•ZеšdеšdеšdеšdЩЂ}ЩЂ}ЩЂ}ЩЂ}БЂ•БЂ•БЂ•БЂ•ЅЃЁЅЃЁЅЃЁЅЃЁЄЄЄЄЄЄЄЄЄж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж•Yж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе”Vе”Vе”Vе”Vг•Zг•Zг•Zг•Zг–[г–[г–[г–[г—[г—[г—[г—[д—[д—[д—[д—[ж–[ж–[ж–[ж–[з–Zз–Zз–Zз–Zж•Zж•Zж•Zж•ZеšdеšdеšdеšdЩЂ}ЩЂ}ЩЂ}ЩЂ}БЂ•БЂ•БЂ•БЂ•ЅЃЁЅЃЁЅЃЁЅЃЁЄЄЄЄЄЄЄЄЄб sб sб sб sгЁtгЁtгЁtгЁtдЂuдЂuдЂuдЂuдЂuдЂuдЂuдЂuеЂtеЂtеЂtеЂtеŸmеŸmеŸmеŸmз™aз™aз™aз™aз–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌМЌМЌМЌМЌТІwТІwТІwТІwЭ›cЭ›cЭ›cЭ›cд”Vд”Vд”Vд”Vе’Sе’Sе’Sе’Sд“Vд“Vд“Vд“VЦ•hЦ•hЦ•hЦ•hЌ™†Ќ™†Ќ™†Ќ™†Ÿœ˜Ÿœ˜Ÿœ˜Ÿœ˜œœœœœœœœœб sб sб sб sгЁtгЁtгЁtгЁtдЂuдЂuдЂuдЂuдЂuдЂuдЂuдЂuеЂtеЂtеЂtеЂtеŸmеŸmеŸmеŸmз™aз™aз™aз™aз–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌМЌМЌМЌМЌТІwТІwТІwТІwЭ›cЭ›cЭ›cЭ›cд”Vд”Vд”Vд”Vе’Sе’Sе’Sе’Sд“Vд“Vд“Vд“VЦ•hЦ•hЦ•hЦ•hЌ™†Ќ™†Ќ™†Ќ™†Ÿœ˜Ÿœ˜Ÿœ˜Ÿœ˜œœœœœœœœœб sб sб sб sгЁtгЁtгЁtгЁtдЂuдЂuдЂuдЂuдЂuдЂuдЂuдЂuеЂtеЂtеЂtеЂtеŸmеŸmеŸmеŸmз™aз™aз™aз™aз–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌМЌМЌМЌМЌТІwТІwТІwТІwЭ›cЭ›cЭ›cЭ›cд”Vд”Vд”Vд”Vе’Sе’Sе’Sе’Sд“Vд“Vд“Vд“VЦ•hЦ•hЦ•hЦ•hЌ™†Ќ™†Ќ™†Ќ™†Ÿœ˜Ÿœ˜Ÿœ˜Ÿœ˜œœœœœœœœœб sб sб sб sгЁtгЁtгЁtгЁtдЂuдЂuдЂuдЂuдЂuдЂuдЂuдЂuеЂtеЂtеЂtеЂtеŸmеŸmеŸmеŸmз™aз™aз™aз™aз–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌМЌМЌМЌМЌТІwТІwТІwТІwЭ›cЭ›cЭ›cЭ›cд”Vд”Vд”Vд”Vе’Sе’Sе’Sе’Sд“Vд“Vд“Vд“VЦ•hЦ•hЦ•hЦ•hЌ™†Ќ™†Ќ™†Ќ™†Ÿœ˜Ÿœ˜Ÿœ˜Ÿœ˜œœœœœœœœœЧДЂЧДЂЧДЂЧДЂвП­вП­вП­вП­йЦДйЦДйЦДйЦДкЧЕкЧЕкЧЕкЧЕлЦГлЦГлЦГлЦГмПЅмПЅмПЅмПЅоГŠоГŠоГŠоГŠпЋ{пЋ{пЋ{пЋ{нЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫŸЫЗŸЫЗŸЫЗŸЫЗЗВ‹ЗВ‹ЗВ‹ЗВ‹ЬœdЬœdЬœdЬœdд’Tд’Tд’Tд’Tе‘Rе‘Rе‘Rе‘RЪ’_Ъ’_Ъ’_Ъ’_Г–|Г–|Г–|Г–|Ѓš’Ѓš’Ѓš’Ѓš’›š›š›šЧДЂЧДЂЧДЂЧДЂвП­вП­вП­вП­йЦДйЦДйЦДйЦДкЧЕкЧЕкЧЕкЧЕлЦГлЦГлЦГлЦГмПЅмПЅмПЅмПЅоГŠоГŠоГŠоГŠпЋ{пЋ{пЋ{пЋ{нЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫŸЫЗŸЫЗŸЫЗŸЫЗЗВ‹ЗВ‹ЗВ‹ЗВ‹ЬœdЬœdЬœdЬœdд’Tд’Tд’Tд’Tе‘Rе‘Rе‘Rе‘RЪ’_Ъ’_Ъ’_Ъ’_Г–|Г–|Г–|Г–|Ѓš’Ѓš’Ѓš’Ѓš’›š›š›šЧДЂЧДЂЧДЂЧДЂвП­вП­вП­вП­йЦДйЦДйЦДйЦДкЧЕкЧЕкЧЕкЧЕлЦГлЦГлЦГлЦГмПЅмПЅмПЅмПЅоГŠоГŠоГŠоГŠпЋ{пЋ{пЋ{пЋ{нЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫŸЫЗŸЫЗŸЫЗŸЫЗЗВ‹ЗВ‹ЗВ‹ЗВ‹ЬœdЬœdЬœdЬœdд’Tд’Tд’Tд’Tе‘Rе‘Rе‘Rе‘RЪ’_Ъ’_Ъ’_Ъ’_Г–|Г–|Г–|Г–|Ѓš’Ѓš’Ѓš’Ѓš’›š›š›šЧДЂЧДЂЧДЂЧДЂвП­вП­вП­вП­йЦДйЦДйЦДйЦДкЧЕкЧЕкЧЕкЧЕлЦГлЦГлЦГлЦГмПЅмПЅмПЅмПЅоГŠоГŠоГŠоГŠпЋ{пЋ{пЋ{пЋ{нЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫ”жЫŸЫЗŸЫЗŸЫЗŸЫЗЗВ‹ЗВ‹ЗВ‹ЗВ‹ЬœdЬœdЬœdЬœdд’Tд’Tд’Tд’Tе‘Rе‘Rе‘Rе‘RЪ’_Ъ’_Ъ’_Ъ’_Г–|Г–|Г–|Г–|Ѓš’Ѓš’Ѓš’Ѓš’›š›š›šЗДВЗДВЗДВЗДВЯЬЩЯЬЩЯЬЩЯЬЩфспфспфспфспэъшэъшэъшэъшяычяычяычяычюсжюсжюсжюсжыЯЖыЯЖыЯЖыЯЖщУ щУ щУ щУ уДˆуДˆуДˆуДˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі}юі}юі}юі}юі„чщ„чщ„чщ„чщ™бТ™бТ™бТ™бТЗБ‰ЗБ‰ЗБ‰ЗБ‰Э™_Э™_Э™_Э™_еQеQеQеQбUбUбUбUУ“hУ“hУ“hУ“hБ™‚Б™‚Б™‚Б™‚Ѕœ•Ѕœ•Ѕœ•ЗДВЗДВЗДВЗДВЯЬЩЯЬЩЯЬЩЯЬЩфспфспфспфспэъшэъшэъшэъшяычяычяычяычюсжюсжюсжюсжыЯЖыЯЖыЯЖыЯЖщУ щУ щУ щУ уДˆуДˆуДˆуДˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі}юі}юі}юі}юі„чщ„чщ„чщ„чщ™бТ™бТ™бТ™бТЗБ‰ЗБ‰ЗБ‰ЗБ‰Э™_Э™_Э™_Э™_еQеQеQеQбUбUбUбUУ“hУ“hУ“hУ“hБ™‚Б™‚Б™‚Б™‚Ѕœ•Ѕœ•Ѕœ•ЗДВЗДВЗДВЗДВЯЬЩЯЬЩЯЬЩЯЬЩфспфспфспфспэъшэъшэъшэъшяычяычяычяычюсжюсжюсжюсжыЯЖыЯЖыЯЖыЯЖщУ щУ щУ щУ уДˆуДˆуДˆуДˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі}юі}юі}юі}юі„чщ„чщ„чщ„чщ™бТ™бТ™бТ™бТЗБ‰ЗБ‰ЗБ‰ЗБ‰Э™_Э™_Э™_Э™_еQеQеQеQбUбUбUбUУ“hУ“hУ“hУ“hБ™‚Б™‚Б™‚Б™‚Ѕœ•Ѕœ•Ѕœ•ЗДВЗДВЗДВЗДВЯЬЩЯЬЩЯЬЩЯЬЩфспфспфспфспэъшэъшэъшэъшяычяычяычяычюсжюсжюсжюсжыЯЖыЯЖыЯЖыЯЖщУ щУ щУ щУ уДˆуДˆуДˆуДˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі}юі}юі}юі}юі„чщ„чщ„чщ„чщ™бТ™бТ™бТ™бТЗБ‰ЗБ‰ЗБ‰ЗБ‰Э™_Э™_Э™_Э™_еQеQеQеQбUбUбUбUУ“hУ“hУ“hУ“hБ™‚Б™‚Б™‚Б™‚Ѕœ•Ѕœ•Ѕœ•ЅЅЅЅЅЅЅЅЅЅЅЅККККККККККККккккккккккккё№яё№яё№яё№яјѕёјѕёјѕёјѕёіщніщніщніщнюбЖюбЖюбЖюбЖчН–чН–чН–чН–рЉvрЉvрЉvрЉvзš^зš^зš^зš^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§zёњzёњzёњzёњ„чш„чш„чш„чшŸЪЕŸЪЕŸЪЕŸЪЕУЃqУЃqУЃqУЃqд‘Qд‘Qд‘Qд‘QеŽMеŽMеŽMеŽMаUаUаUаUФ”hФ”hФ”hФ”hИš~Иš~Иš~ЅЅЅЅЅЅЅЅЅЅЅЅККККККККККККккккккккккккё№яё№яё№яё№яјѕёјѕёјѕёјѕёіщніщніщніщнюбЖюбЖюбЖюбЖчН–чН–чН–чН–рЉvрЉvрЉvрЉvзš^зš^зš^зš^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§zёњzёњzёњzёњ„чш„чш„чш„чшŸЪЕŸЪЕŸЪЕŸЪЕУЃqУЃqУЃqУЃqд‘Qд‘Qд‘Qд‘QеŽMеŽMеŽMеŽMаUаUаUаUФ”hФ”hФ”hФ”hИš~Иš~Иš~ЅЅЅЅЅЅЅЅЅЅЅЅККККККККККККккккккккккккё№яё№яё№яё№яјѕёјѕёјѕёјѕёіщніщніщніщнюбЖюбЖюбЖюбЖчН–чН–чН–чН–рЉvрЉvрЉvрЉvзš^зš^зš^зš^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§zёњzёњzёњzёњ„чш„чш„чш„чшŸЪЕŸЪЕŸЪЕŸЪЕУЃqУЃqУЃqУЃqд‘Qд‘Qд‘Qд‘QеŽMеŽMеŽMеŽMаUаUаUаUФ”hФ”hФ”hФ”hИš~Иš~Иš~ЅЅЅЅЅЅЅЅЅЅЅЅККККККККККККккккккккккккё№яё№яё№яё№яјѕёјѕёјѕёјѕёіщніщніщніщнюбЖюбЖюбЖюбЖчН–чН–чН–чН–рЉvрЉvрЉvрЉvзš^зš^зš^зš^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§zёњzёњzёњzёњ„чш„чш„чш„чшŸЪЕŸЪЕŸЪЕŸЪЕУЃqУЃqУЃqУЃqд‘Qд‘Qд‘Qд‘QеŽMеŽMеŽMеŽMаUаUаUаUФ”hФ”hФ”hФ”hИš~Иš~Иš~ЇЇЇЇЇЇЇЇЇЇЇЇППОППОППОППОмжбмжбмжбмжбэнЮэнЮэнЮэнЮяжПяжПяжПяжПыШЈыШЈыШЈыШЈхЕ‹хЕ‹хЕ‹хЕ‹мžeмžeмžeмžeд“Uд“Uд“Uд“UНЈzНЈzНЈzНЈz”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЈzНЈzНЈzНЈzгPгPгPгPжJжJжJжJеKеKеKеKбRбRбRбRЬ’\Ь’\Ь’\ЇЇЇЇЇЇЇЇЇЇЇЇППОППОППОППОмжбмжбмжбмжбэнЮэнЮэнЮэнЮяжПяжПяжПяжПыШЈыШЈыШЈыШЈхЕ‹хЕ‹хЕ‹хЕ‹мžeмžeмžeмžeд“Uд“Uд“Uд“UНЈzНЈzНЈzНЈz”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЈzНЈzНЈzНЈzгPгPгPгPжJжJжJжJеKеKеKеKбRбRбRбRЬ’\Ь’\Ь’\ЇЇЇЇЇЇЇЇЇЇЇЇППОППОППОППОмжбмжбмжбмжбэнЮэнЮэнЮэнЮяжПяжПяжПяжПыШЈыШЈыШЈыШЈхЕ‹хЕ‹хЕ‹хЕ‹мžeмžeмžeмžeд“Uд“Uд“Uд“UНЈzНЈzНЈzНЈz”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЈzНЈzНЈzНЈzгPгPгPгPжJжJжJжJеKеKеKеKбRбRбRбRЬ’\Ь’\Ь’\ЇЇЇЇЇЇЇЇЇЇЇЇППОППОППОППОмжбмжбмжбмжбэнЮэнЮэнЮэнЮяжПяжПяжПяжПыШЈыШЈыШЈыШЈхЕ‹хЕ‹хЕ‹хЕ‹мžeмžeмžeмžeд“Uд“Uд“Uд“UНЈzНЈzНЈzНЈz”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЈzНЈzНЈzНЈzгPгPгPгPжJжJжJжJеKеKеKеKбRбRбRбRЬ’\Ь’\Ь’\œœœœœœœœœœœœ  Ÿ  Ÿ  Ÿ  ŸЋЉЇЋЉЇЋЉЇЋЉЇРБЃРБЃРБЃРБЃжЏ‹жЏ‹жЏ‹жЏ‹пЊzпЊzпЊzпЊzрЇsрЇsрЇsрЇsнŸgнŸgнŸgнŸgй“Tй“Tй“Tй“Tг‘Pг‘Pг‘Pг‘PНЇyНЇyНЇyНЇy”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЇyНЇyНЇyНЇyгNгNгNгNжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHеŒJеŒJеŒJœœœœœœœœœœœœ  Ÿ  Ÿ  Ÿ  ŸЋЉЇЋЉЇЋЉЇЋЉЇРБЃРБЃРБЃРБЃжЏ‹жЏ‹жЏ‹жЏ‹пЊzпЊzпЊzпЊzрЇsрЇsрЇsрЇsнŸgнŸgнŸgнŸgй“Tй“Tй“Tй“Tг‘Pг‘Pг‘Pг‘PНЇyНЇyНЇyНЇy”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЇyНЇyНЇyНЇyгNгNгNгNжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHеŒJеŒJеŒJœœœœœœœœœœœœ  Ÿ  Ÿ  Ÿ  ŸЋЉЇЋЉЇЋЉЇЋЉЇРБЃРБЃРБЃРБЃжЏ‹жЏ‹жЏ‹жЏ‹пЊzпЊzпЊzпЊzрЇsрЇsрЇsрЇsнŸgнŸgнŸgнŸgй“Tй“Tй“Tй“Tг‘Pг‘Pг‘Pг‘PНЇyНЇyНЇyНЇy”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЇyНЇyНЇyНЇyгNгNгNгNжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHеŒJеŒJеŒJœœœœœœœœœœœœ  Ÿ  Ÿ  Ÿ  ŸЋЉЇЋЉЇЋЉЇЋЉЇРБЃРБЃРБЃРБЃжЏ‹жЏ‹жЏ‹жЏ‹пЊzпЊzпЊzпЊzрЇsрЇsрЇsрЇsнŸgнŸgнŸgнŸgй“Tй“Tй“Tй“Tг‘Pг‘Pг‘Pг‘PНЇyНЇyНЇyНЇy”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyєџyєџyєџyєџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ”дШ”дШ”дШ”дШНЇyНЇyНЇyНЇyгNгNгNгNжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHжŒHеŒJеŒJеŒJœœœœœœœœœœœœŸžžŸžžŸžžŸžžЄЁŸЄЁŸЄЁŸЄЁŸГŸŒГŸŒГŸŒГŸŒЪ•eЪ•eЪ•eЪ•eжPжPжPжPзŽLзŽLзŽLзŽLзJзJзJзJзŒGзŒGзŒGзŒGдŽKдŽKдŽKдŽKУ lУ lУ lУ lŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВУ lУ lУ lУ lдŽKдŽKдŽKдŽKж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Eж‹Eж‹Eж‹Eж‹Fж‹Fж‹FœœœœœœœœœœœœŸžžŸžžŸžžŸžžЄЁŸЄЁŸЄЁŸЄЁŸГŸŒГŸŒГŸŒГŸŒЪ•eЪ•eЪ•eЪ•eжPжPжPжPзŽLзŽLзŽLзŽLзJзJзJзJзŒGзŒGзŒGзŒGдŽKдŽKдŽKдŽKУ lУ lУ lУ lŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВУ lУ lУ lУ lдŽKдŽKдŽKдŽKж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Eж‹Eж‹Eж‹Eж‹Fж‹Fж‹FœœœœœœœœœœœœŸžžŸžžŸžžŸžžЄЁŸЄЁŸЄЁŸЄЁŸГŸŒГŸŒГŸŒГŸŒЪ•eЪ•eЪ•eЪ•eжPжPжPжPзŽLзŽLзŽLзŽLзJзJзJзJзŒGзŒGзŒGзŒGдŽKдŽKдŽKдŽKУ lУ lУ lУ lŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВУ lУ lУ lУ lдŽKдŽKдŽKдŽKж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Eж‹Eж‹Eж‹Eж‹Fж‹Fж‹FœœœœœœœœœœœœŸžžŸžžŸžžŸžžЄЁŸЄЁŸЄЁŸЄЁŸГŸŒГŸŒГŸŒГŸŒЪ•eЪ•eЪ•eЪ•eжPжPжPжPзŽLзŽLзŽLзŽLзJзJзJзJзŒGзŒGзŒGзŒGдŽKдŽKдŽKдŽKУ lУ lУ lУ lŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВУ lУ lУ lУ lдŽKдŽKдŽKдŽKж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Fж‹Eж‹Eж‹Eж‹Eж‹Fж‹Fж‹F™™™™™™™™™™™™œœœœЃ Ѓ Ѓ Ѓ А›‰А›‰А›‰А›‰Ч‘`Ч‘`Ч‘`Ч‘`д‹Hд‹Hд‹Hд‹HжŠCжŠCжŠCжŠCзŠCзŠCзŠCзŠCжŠCжŠCжŠCжŠCе‹Eе‹Eе‹Eе‹EЭ”TЭ”TЭ”TЭ”TЗ­€З­€З­€З­€™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Eе‹Eе‹Eе‹EжŠDжŠDжŠDжŠDзŠCзŠCзŠCзŠCзŠDзŠDзŠDзŠDзŠDзŠDзŠD™™™™™™™™™™™™œœœœЃ Ѓ Ѓ Ѓ А›‰А›‰А›‰А›‰Ч‘`Ч‘`Ч‘`Ч‘`д‹Hд‹Hд‹Hд‹HжŠCжŠCжŠCжŠCзŠCзŠCзŠCзŠCжŠCжŠCжŠCжŠCе‹Eе‹Eе‹Eе‹EЭ”TЭ”TЭ”TЭ”TЗ­€З­€З­€З­€™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Eе‹Eе‹Eе‹EжŠDжŠDжŠDжŠDзŠCзŠCзŠCзŠCзŠDзŠDзŠDзŠDзŠDзŠDзŠD™™™™™™™™™™™™œœœœЃ Ѓ Ѓ Ѓ А›‰А›‰А›‰А›‰Ч‘`Ч‘`Ч‘`Ч‘`д‹Hд‹Hд‹Hд‹HжŠCжŠCжŠCжŠCзŠCзŠCзŠCзŠCжŠCжŠCжŠCжŠCе‹Eе‹Eе‹Eе‹EЭ”TЭ”TЭ”TЭ”TЗ­€З­€З­€З­€™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Eе‹Eе‹Eе‹EжŠDжŠDжŠDжŠDзŠCзŠCзŠCзŠCзŠDзŠDзŠDзŠDзŠDзŠDзŠD™™™™™™™™™™™™œœœœЃ Ѓ Ѓ Ѓ А›‰А›‰А›‰А›‰Ч‘`Ч‘`Ч‘`Ч‘`д‹Hд‹Hд‹Hд‹HжŠCжŠCжŠCжŠCзŠCзŠCзŠCзŠCжŠCжŠCжŠCжŠCе‹Eе‹Eе‹Eе‹EЭ”TЭ”TЭ”TЭ”TЗ­€З­€З­€З­€™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Eе‹Eе‹Eе‹EжŠDжŠDжŠDжŠDзŠCзŠCзŠCзŠCзŠDзŠDзŠDзŠDзŠDзŠDзŠD–”’–”’–”’–”’š™˜š™˜š™˜š™˜ › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т’fТ’fТ’fТ’fв‹Kв‹Kв‹Kв‹Kж‰Cж‰Cж‰Cж‰Cз‰Bз‰Bз‰Bз‰Bз‰Aз‰Aз‰Aз‰Aж‰Aж‰Aж‰Aж‰Aд‹Dд‹Dд‹Dд‹DЬ”VЬ”VЬ”VЬ”VЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Eд‹Eд‹Eд‹Eж‰Bж‰Bж‰Bж‰Bз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰A–”’–”’–”’–”’š™˜š™˜š™˜š™˜ › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т’fТ’fТ’fТ’fв‹Kв‹Kв‹Kв‹Kж‰Cж‰Cж‰Cж‰Cз‰Bз‰Bз‰Bз‰Bз‰Aз‰Aз‰Aз‰Aж‰Aж‰Aж‰Aж‰Aд‹Dд‹Dд‹Dд‹DЬ”VЬ”VЬ”VЬ”VЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Eд‹Eд‹Eд‹Eж‰Bж‰Bж‰Bж‰Bз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰A–”’–”’–”’–”’š™˜š™˜š™˜š™˜ › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т’fТ’fТ’fТ’fв‹Kв‹Kв‹Kв‹Kж‰Cж‰Cж‰Cж‰Cз‰Bз‰Bз‰Bз‰Bз‰Aз‰Aз‰Aз‰Aж‰Aж‰Aж‰Aж‰Aд‹Dд‹Dд‹Dд‹DЬ”VЬ”VЬ”VЬ”VЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Eд‹Eд‹Eд‹Eж‰Bж‰Bж‰Bж‰Bз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰A–”’–”’–”’–”’š™˜š™˜š™˜š™˜ › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т’fТ’fТ’fТ’fв‹Kв‹Kв‹Kв‹Kж‰Cж‰Cж‰Cж‰Cз‰Bз‰Bз‰Bз‰Bз‰Aз‰Aз‰Aз‰Aж‰Aж‰Aж‰Aж‰Aд‹Dд‹Dд‹Dд‹DЬ”VЬ”VЬ”VЬ”VЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Eд‹Eд‹Eд‹Eж‰Bж‰Bж‰Bж‰Bз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰Aз‰AЁ‘‚Ё‘‚Ё‘‚Ё‘‚ž˜’ž˜’ž˜’ž˜’ЁŸœЁŸœЁŸœЁŸœЋž“Ћž“Ћž“Ћž“О—sО—sО—sО—sЯŽSЯŽSЯŽSЯŽSеŠFеŠFеŠFеŠFж‰Dж‰Dж‰Dж‰Dж‰Cж‰Cж‰Cж‰Cжˆ@жˆ@жˆ@жˆ@жˆ?жˆ?жˆ?жˆ?дŠCдŠCдŠCдŠCЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCжˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?Ё‘‚Ё‘‚Ё‘‚Ё‘‚ž˜’ž˜’ž˜’ž˜’ЁŸœЁŸœЁŸœЁŸœЋž“Ћž“Ћž“Ћž“О—sО—sО—sО—sЯŽSЯŽSЯŽSЯŽSеŠFеŠFеŠFеŠFж‰Dж‰Dж‰Dж‰Dж‰Cж‰Cж‰Cж‰Cжˆ@жˆ@жˆ@жˆ@жˆ?жˆ?жˆ?жˆ?дŠCдŠCдŠCдŠCЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCжˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?Ё‘‚Ё‘‚Ё‘‚Ё‘‚ž˜’ž˜’ž˜’ž˜’ЁŸœЁŸœЁŸœЁŸœЋž“Ћž“Ћž“Ћž“О—sО—sО—sО—sЯŽSЯŽSЯŽSЯŽSеŠFеŠFеŠFеŠFж‰Dж‰Dж‰Dж‰Dж‰Cж‰Cж‰Cж‰Cжˆ@жˆ@жˆ@жˆ@жˆ?жˆ?жˆ?жˆ?дŠCдŠCдŠCдŠCЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCжˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?Ё‘‚Ё‘‚Ё‘‚Ё‘‚ž˜’ž˜’ž˜’ž˜’ЁŸœЁŸœЁŸœЁŸœЋž“Ћž“Ћž“Ћž“О—sО—sО—sО—sЯŽSЯŽSЯŽSЯŽSеŠFеŠFеŠFеŠFж‰Dж‰Dж‰Dж‰Dж‰Cж‰Cж‰Cж‰Cжˆ@жˆ@жˆ@жˆ@жˆ?жˆ?жˆ?жˆ?дŠCдŠCдŠCдŠCЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCжˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?жˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?зˆ?О“lО“lО“lО“lЗЄ“ЗЄ“ЗЄ“ЗЄ“ЖЏЉЖЏЉЖЏЉЖЏЉЛ­ЁЛ­ЁЛ­ЁЛ­ЁЦЅ…ЦЅ…ЦЅ…ЦЅ…аnаnаnаnг›gг›gг›gг›gдšdдšdдšdдšdе–\е–\е–\е–\еŽMеŽMеŽMеŽMе‰Dе‰Dе‰Dе‰Dе‰Cе‰Cе‰Cе‰CеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=О“lО“lО“lО“lЗЄ“ЗЄ“ЗЄ“ЗЄ“ЖЏЉЖЏЉЖЏЉЖЏЉЛ­ЁЛ­ЁЛ­ЁЛ­ЁЦЅ…ЦЅ…ЦЅ…ЦЅ…аnаnаnаnг›gг›gг›gг›gдšdдšdдšdдšdе–\е–\е–\е–\еŽMеŽMеŽMеŽMе‰Dе‰Dе‰Dе‰Dе‰Cе‰Cе‰Cе‰CеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=О“lО“lО“lО“lЗЄ“ЗЄ“ЗЄ“ЗЄ“ЖЏЉЖЏЉЖЏЉЖЏЉЛ­ЁЛ­ЁЛ­ЁЛ­ЁЦЅ…ЦЅ…ЦЅ…ЦЅ…аnаnаnаnг›gг›gг›gг›gдšdдšdдšdдšdе–\е–\е–\е–\еŽMеŽMеŽMеŽMе‰Dе‰Dе‰Dе‰Dе‰Cе‰Cе‰Cе‰CеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=О“lО“lО“lО“lЗЄ“ЗЄ“ЗЄ“ЗЄ“ЖЏЉЖЏЉЖЏЉЖЏЉЛ­ЁЛ­ЁЛ­ЁЛ­ЁЦЅ…ЦЅ…ЦЅ…ЦЅ…аnаnаnаnг›gг›gг›gг›gдšdдšdдšdдšdе–\е–\е–\е–\еŽMеŽMеŽMеŽMе‰Dе‰Dе‰Dе‰Dе‰Cе‰Cе‰Cе‰CеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=з‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=ж‡=д•\д•\д•\д•\жЏŒжЏŒжЏŒжЏŒзНІзНІзНІзНІзРЋзРЋзРЋзРЋиРЊиРЊиРЊиРЊиРЉиРЉиРЉиРЉйСЊйСЊйСЊйСЊкСЋкСЋкСЋкСЋйИšйИšйИšйИšеЅyеЅyеЅyеЅyд›gд›gд›gд›gдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;ж…;ж…;ж…;ж…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;ж…;ж…;ж…;ж…;ж…<ж…<ж…<ж…<д†=д†=д†=д•\д•\д•\д•\жЏŒжЏŒжЏŒжЏŒзНІзНІзНІзНІзРЋзРЋзРЋзРЋиРЊиРЊиРЊиРЊиРЉиРЉиРЉиРЉйСЊйСЊйСЊйСЊкСЋкСЋкСЋкСЋйИšйИšйИšйИšеЅyеЅyеЅyеЅyд›gд›gд›gд›gдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;ж…;ж…;ж…;ж…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;ж…;ж…;ж…;ж…;ж…<ж…<ж…<ж…<д†=д†=д†=д•\д•\д•\д•\жЏŒжЏŒжЏŒжЏŒзНІзНІзНІзНІзРЋзРЋзРЋзРЋиРЊиРЊиРЊиРЊиРЉиРЉиРЉиРЉйСЊйСЊйСЊйСЊкСЋкСЋкСЋкСЋйИšйИšйИšйИšеЅyеЅyеЅyеЅyд›gд›gд›gд›gдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;ж…;ж…;ж…;ж…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;ж…;ж…;ж…;ж…;ж…<ж…<ж…<ж…<д†=д†=д†=д•\д•\д•\д•\жЏŒжЏŒжЏŒжЏŒзНІзНІзНІзНІзРЋзРЋзРЋзРЋиРЊиРЊиРЊиРЊиРЉиРЉиРЉиРЉйСЊйСЊйСЊйСЊкСЋкСЋкСЋкСЋйИšйИšйИšйИšеЅyеЅyеЅyеЅyд›gд›gд›gд›gдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;ж…;ж…;ж…;ж…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;з…;ж…;ж…;ж…;ж…;ж…<ж…<ж…<ж…<д†=д†=д†=иŒFиŒFиŒFиŒFл™]л™]л™]л™]нЂlнЂlнЂlнЂlп­~п­~п­~п­~уОžуОžуОžуОžхЩБхЩБхЩБхЩБчвПчвПчвПчвПъовъовъовъовчлЯчлЯчлЯчлЯоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<з„9з„9з„9з„9з„9з„9з„9з„9з„8з„8з„8з„8з„9з„9з„9з„9з„9з„9з„9з„9ж„:ж„:ж„:ж„:в…@в…@в…@в…@ЪˆLЪˆLЪˆLиŒFиŒFиŒFиŒFл™]л™]л™]л™]нЂlнЂlнЂlнЂlп­~п­~п­~п­~уОžуОžуОžуОžхЩБхЩБхЩБхЩБчвПчвПчвПчвПъовъовъовъовчлЯчлЯчлЯчлЯоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<з„9з„9з„9з„9з„9з„9з„9з„9з„8з„8з„8з„8з„9з„9з„9з„9з„9з„9з„9з„9ж„:ж„:ж„:ж„:в…@в…@в…@в…@ЪˆLЪˆLЪˆLиŒFиŒFиŒFиŒFл™]л™]л™]л™]нЂlнЂlнЂlнЂlп­~п­~п­~п­~уОžуОžуОžуОžхЩБхЩБхЩБхЩБчвПчвПчвПчвПъовъовъовъовчлЯчлЯчлЯчлЯоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<з„9з„9з„9з„9з„9з„9з„9з„9з„8з„8з„8з„8з„9з„9з„9з„9з„9з„9з„9з„9ж„:ж„:ж„:ж„:в…@в…@в…@в…@ЪˆLЪˆLЪˆLиŒFиŒFиŒFиŒFл™]л™]л™]л™]нЂlнЂlнЂlнЂlп­~п­~п­~п­~уОžуОžуОžуОžхЩБхЩБхЩБхЩБчвПчвПчвПчвПъовъовъовъовчлЯчлЯчлЯчлЯоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<з„9з„9з„9з„9з„9з„9з„9з„9з„8з„8з„8з„8з„9з„9з„9з„9з„9з„9з„9з„9ж„:ж„:ж„:ж„:в…@в…@в…@в…@ЪˆLЪˆLЪˆLз„8з„8з„8з„8з†;з†;з†;з†;иˆ?иˆ?иˆ?иˆ?кJкJкJкJн›^н›^н›^н›^рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊэвЛэвЛэвЛэвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ6зƒ6зƒ6зƒ6зƒ7зƒ7зƒ7зƒ7жƒ7жƒ7жƒ7жƒ7еƒ9еƒ9еƒ9еƒ9Щ†IЩ†IЩ†IЩ†IГ‹gГ‹gГ‹gз„8з„8з„8з„8з†;з†;з†;з†;иˆ?иˆ?иˆ?иˆ?кJкJкJкJн›^н›^н›^н›^рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊэвЛэвЛэвЛэвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ6зƒ6зƒ6зƒ6зƒ7зƒ7зƒ7зƒ7жƒ7жƒ7жƒ7жƒ7еƒ9еƒ9еƒ9еƒ9Щ†IЩ†IЩ†IЩ†IГ‹gГ‹gГ‹gз„8з„8з„8з„8з†;з†;з†;з†;иˆ?иˆ?иˆ?иˆ?кJкJкJкJн›^н›^н›^н›^рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊэвЛэвЛэвЛэвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ6зƒ6зƒ6зƒ6зƒ7зƒ7зƒ7зƒ7жƒ7жƒ7жƒ7жƒ7еƒ9еƒ9еƒ9еƒ9Щ†IЩ†IЩ†IЩ†IГ‹gГ‹gГ‹gз„8з„8з„8з„8з†;з†;з†;з†;иˆ?иˆ?иˆ?иˆ?кJкJкJкJн›^н›^н›^н›^рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊэвЛэвЛэвЛэвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ7зƒ6зƒ6зƒ6зƒ6зƒ7зƒ7зƒ7зƒ7жƒ7жƒ7жƒ7жƒ7еƒ9еƒ9еƒ9еƒ9Щ†IЩ†IЩ†IЩ†IГ‹gГ‹gГ‹gз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚5з‚5з‚5з‚5зƒ7зƒ7зƒ7зƒ7з…:з…:з…:з…:иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„KТ„KТ„KТ„KЁ‡pЁ‡pЁ‡pз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚5з‚5з‚5з‚5зƒ7зƒ7зƒ7зƒ7з…:з…:з…:з…:иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„KТ„KТ„KТ„KЁ‡pЁ‡pЁ‡pз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚5з‚5з‚5з‚5зƒ7зƒ7зƒ7зƒ7з…:з…:з…:з…:иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„KТ„KТ„KТ„KЁ‡pЁ‡pЁ‡pз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚5з‚5з‚5з‚5зƒ7зƒ7зƒ7зƒ7з…:з…:з…:з…:иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5з‚5ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„KТ„KТ„KТ„KЁ‡pЁ‡pЁ‡pз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7ПIПIПIПI™k™k™kз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7ПIПIПIПI™k™k™kз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7ПIПIПIПI™k™k™kз‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7ПIПIПIПI™k™k™kџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџз›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜—————————з›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜—————————з›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜—————————з›dз›dз›dз›dз›dз›dз›dз›dзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdз›dз›dз›dз›dз›dз›dз›dз›dз›eз›eз›eз›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бšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜—————————зšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšdеšdеšdеšdвœjвœjвœjвœjЫœpЫœpЫœpЫœpС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšdеšdеšdеšdвœjвœjвœjвœjЫœpЫœpЫœpЫœpС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšdеšdеšdеšdвœjвœjвœjвœjЫœpЫœpЫœpЫœpС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšdеšdеšdеšdвœjвœjвœjвœjЫœpЫœpЫœpЫœpС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™aж™aж™aж™aжšbжšbжšbжšbвœiвœiвœiвœiЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡з™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™aж™aж™aж™aжšbжšbжšbжšbвœiвœiвœiвœiЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡з™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™aж™aж™aж™aжšbжšbжšbжšbвœiвœiвœiвœiЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡з™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aз™aж™aж™aж™aж™aжšbжšbжšbжšbвœiвœiвœiвœiЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_ж˜_ж˜_ж˜_ж˜_вšfвšfвšfвšfЩ zЩ zЩ zЩ zОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡………………………з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_ж˜_ж˜_ж˜_ж˜_вšfвšfвšfвšfЩ zЩ zЩ zЩ zОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡………………………з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_ж˜_ж˜_ж˜_ж˜_вšfвšfвšfвšfЩ zЩ zЩ zЩ zОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡………………………з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_з˜_ж˜_ж˜_ж˜_ж˜_вšfвšfвšfвšfЩ zЩ zЩ zЩ zОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡………………………з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅ‹ПЅ‹ПЅ‹ПЅ‹ЙБЈЙБЈЙБЈЙБЈЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽŽŽŽŽŠ‰‰Š‰‰Š‰‰з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅ‹ПЅ‹ПЅ‹ПЅ‹ЙБЈЙБЈЙБЈЙБЈЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽŽŽŽŽŠ‰‰Š‰‰Š‰‰з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅ‹ПЅ‹ПЅ‹ПЅ‹ЙБЈЙБЈЙБЈЙБЈЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽŽŽŽŽŠ‰‰Š‰‰Š‰‰з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]з—]ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅ‹ПЅ‹ПЅ‹ПЅ‹ЙБЈЙБЈЙБЈЙБЈЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽŽŽŽŽŠ‰‰Š‰‰Š‰‰з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[ж–[ж–[ж–[ж–[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ            œœœœœœœœœœœœœœ›œœ›œœ›œœ›žœšžœšžœšз–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[ж–[ж–[ж–[ж–[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ            œœœœœœœœœœœœœœ›œœ›œœ›œœ›žœšžœšžœšз–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[ж–[ж–[ж–[ж–[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ            œœœœœœœœœœœœœœ›œœ›œœ›œœ›žœšžœšžœšз–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[з–[ж–[ж–[ж–[ж–[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ            œœœœœœœœœœœœœœ›œœ›œœ›œœ›žœšžœšžœšж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yж•Yж•Yж•Yж•Yв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЌЌЌЌЌЌЌЌЌЌЌЌЊЊЊЊЊЊЊЊЊЊЊЊЏЏЎЏЏЎЏЏЎЏЏЎИДАИДАИДАИДАФЙЏФЙЏФЙЏж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yж•Yж•Yж•Yж•Yв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЌЌЌЌЌЌЌЌЌЌЌЌЊЊЊЊЊЊЊЊЊЊЊЊЏЏЎЏЏЎЏЏЎЏЏЎИДАИДАИДАИДАФЙЏФЙЏФЙЏж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yж•Yж•Yж•Yж•Yв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЌЌЌЌЌЌЌЌЌЌЌЌЊЊЊЊЊЊЊЊЊЊЊЊЏЏЎЏЏЎЏЏЎЏЏЎИДАИДАИДАИДАФЙЏФЙЏФЙЏж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xж•Xз•Xз•Xз•Xз•Xз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yз•Yж•Yж•Yж•Yж•Yв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЌЌЌЌЌЌЌЌЌЌЌЌЊЊЊЊЊЊЊЊЊЊЊЊЏЏЎЏЏЎЏЏЎЏЏЎИДАИДАИДАИДАФЙЏФЙЏФЙЏе”Xе”Xе”Xе”Xе”Wе”Wе”Wе”Wж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vж”Vж”Vж”Vж”Vж”Xж”Xж”Xж”Xв–^в–^в–^в–^Э™hЭ™hЭ™hЭ™hЪ›pЪ›pЪ›pЪ›pСŸСŸСŸСŸГІ™ГІ™ГІ™ГІ™ЌЋЉЌЋЉЌЋЉЌЋЉЌЌЌЌЌЌЌЌЌЌЌЌЋЋЋЋЋЋЋЋЋЋЋЋВВВВВВВВВВВВРПОРПОРПОРПОЫТЛЫТЛЫТЛЫТЛбМЉбМЉбМЉе”Xе”Xе”Xе”Xе”Wе”Wе”Wе”Wж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vж”Vж”Vж”Vж”Vж”Xж”Xж”Xж”Xв–^в–^в–^в–^Э™hЭ™hЭ™hЭ™hЪ›pЪ›pЪ›pЪ›pСŸСŸСŸСŸГІ™ГІ™ГІ™ГІ™ЌЋЉЌЋЉЌЋЉЌЋЉЌЌЌЌЌЌЌЌЌЌЌЌЋЋЋЋЋЋЋЋЋЋЋЋВВВВВВВВВВВВРПОРПОРПОРПОЫТЛЫТЛЫТЛЫТЛбМЉбМЉбМЉе”Xе”Xе”Xе”Xе”Wе”Wе”Wе”Wж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vж”Vж”Vж”Vж”Vж”Xж”Xж”Xж”Xв–^в–^в–^в–^Э™hЭ™hЭ™hЭ™hЪ›pЪ›pЪ›pЪ›pСŸСŸСŸСŸГІ™ГІ™ГІ™ГІ™ЌЋЉЌЋЉЌЋЉЌЋЉЌЌЌЌЌЌЌЌЌЌЌЌЋЋЋЋЋЋЋЋЋЋЋЋВВВВВВВВВВВВРПОРПОРПОРПОЫТЛЫТЛЫТЛЫТЛбМЉбМЉбМЉе”Xе”Xе”Xе”Xе”Wе”Wе”Wе”Wж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vж”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vз”Vж”Vж”Vж”Vж”Vж”Xж”Xж”Xж”Xв–^в–^в–^в–^Э™hЭ™hЭ™hЭ™hЪ›pЪ›pЪ›pЪ›pСŸСŸСŸСŸГІ™ГІ™ГІ™ГІ™ЌЋЉЌЋЉЌЋЉЌЋЉЌЌЌЌЌЌЌЌЌЌЌЌЋЋЋЋЋЋЋЋЋЋЋЋВВВВВВВВВВВВРПОРПОРПОРПОЫТЛЫТЛЫТЛЫТЛбМЉбМЉбМЉЯšiЯšiЯšiЯšiв–^в–^в–^в–^д”Yд”Yд”Yд”Yе”Xе”Xе”Xе”Xж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе“Vе“Vе“Vе“Vг•Zг•Zг•Zг•Zб–^б–^б–^б–^Я—aЯ—aЯ—aЯ—aУ™pУ™pУ™pУ™p­žŽ­žŽ­žŽ­žŽЄЂ ЄЂ ЄЂ ЄЂ ЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЈЈЈЈЈЈЈЈЈЈЈЈВББВББВББВББЙЕАЙЕАЙЕАЙЕАПГЉПГЉПГЉЯšiЯšiЯšiЯšiв–^в–^в–^в–^д”Yд”Yд”Yд”Yе”Xе”Xе”Xе”Xж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе“Vе“Vе“Vе“Vг•Zг•Zг•Zг•Zб–^б–^б–^б–^Я—aЯ—aЯ—aЯ—aУ™pУ™pУ™pУ™p­žŽ­žŽ­žŽ­žŽЄЂ ЄЂ ЄЂ ЄЂ ЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЈЈЈЈЈЈЈЈЈЈЈЈВББВББВББВББЙЕАЙЕАЙЕАЙЕАПГЉПГЉПГЉЯšiЯšiЯšiЯšiв–^в–^в–^в–^д”Yд”Yд”Yд”Yе”Xе”Xе”Xе”Xж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе“Vе“Vе“Vе“Vг•Zг•Zг•Zг•Zб–^б–^б–^б–^Я—aЯ—aЯ—aЯ—aУ™pУ™pУ™pУ™p­žŽ­žŽ­žŽ­žŽЄЂ ЄЂ ЄЂ ЄЂ ЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЈЈЈЈЈЈЈЈЈЈЈЈВББВББВББВББЙЕАЙЕАЙЕАЙЕАПГЉПГЉПГЉЯšiЯšiЯšiЯšiв–^в–^в–^в–^д”Yд”Yд”Yд”Yе”Xе”Xе”Xе”Xж”Xж”Xж”Xж”Xж”Wж”Wж”Wж”Wж“Vж“Vж“Vж“Vж“Uж“Uж“Uж“Uз“Uз“Uз“Uз“Uз“Tз“Tз“Tз“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tж“Tе“Vе“Vе“Vе“Vг•Zг•Zг•Zг•Zб–^б–^б–^б–^Я—aЯ—aЯ—aЯ—aУ™pУ™pУ™pУ™p­žŽ­žŽ­žŽ­žŽЄЂ ЄЂ ЄЂ ЄЂ ЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЈЈЈЈЈЈЈЈЈЈЈЈВББВББВББВББЙЕАЙЕАЙЕАЙЕАПГЉПГЉПГЉТІТІТІТІЩ zЩ zЩ zЩ zЭqЭqЭqЭqЯžpЯžpЯžpЯžpбžpбžpбžpбžpвœkвœkвœkвœkж˜_ж˜_ж˜_ж˜_з–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌКЌƒКЌƒКЌƒКЌƒВЈŠВЈŠВЈŠВЈŠЃЁ–ЃЁ–ЃЁ–ЃЁ–œœœœœœœœœœœœœœœœ››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁІІЅІІЅІІЅІІЅЎ­ЋЎ­ЋЎ­ЋТІТІТІТІЩ zЩ zЩ zЩ zЭqЭqЭqЭqЯžpЯžpЯžpЯžpбžpбžpбžpбžpвœkвœkвœkвœkж˜_ж˜_ж˜_ж˜_з–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌКЌƒКЌƒКЌƒКЌƒВЈŠВЈŠВЈŠВЈŠЃЁ–ЃЁ–ЃЁ–ЃЁ–œœœœœœœœœœœœœœœœ››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁІІЅІІЅІІЅІІЅЎ­ЋЎ­ЋЎ­ЋТІТІТІТІЩ zЩ zЩ zЩ zЭqЭqЭqЭqЯžpЯžpЯžpЯžpбžpбžpбžpбžpвœkвœkвœkвœkж˜_ж˜_ж˜_ж˜_з–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌКЌƒКЌƒКЌƒКЌƒВЈŠВЈŠВЈŠВЈŠЃЁ–ЃЁ–ЃЁ–ЃЁ–œœœœœœœœœœœœœœœœ››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁІІЅІІЅІІЅІІЅЎ­ЋЎ­ЋЎ­ЋТІТІТІТІЩ zЩ zЩ zЩ zЭqЭqЭqЭqЯžpЯžpЯžpЯžpбžpбžpбžpбžpвœkвœkвœkвœkж˜_ж˜_ж˜_ж˜_з–Yз–Yз–Yз–Yз”Vз”Vз”Vз”Vз“Sз“Sз“Sз“Sж’Sж’Sж’Sж’Sд”Uд”Uд”Uд”UЭ›bЭ›bЭ›bЭ›bТІwТІwТІwТІwМЌМЌМЌМЌКЌƒКЌƒКЌƒКЌƒВЈŠВЈŠВЈŠВЈŠЃЁ–ЃЁ–ЃЁ–ЃЁ–œœœœœœœœœœœœœœœœ››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁІІЅІІЅІІЅІІЅЎ­ЋЎ­ЋЎ­ЋЖЎЈЖЎЈЖЎЈЖЎЈКЌžКЌžКЌžКЌžНЋšНЋšНЋšНЋšР­›Р­›Р­›Р­›Т­›Т­›Т­›Т­›Щ­“Щ­“Щ­“Щ­“жЋ„жЋ„жЋ„жЋ„нЊzнЊzнЊzнЊzнЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ’жЭ’жЭ’жЭ’жЭ’ЬЧ’ЬЧ’ЬЧ’ЬЧ”ЗЖ”ЗЖ”ЗЖ”ЗƘЅІ˜ЅІ˜ЅІ˜ЅІšœšœšœšœšššššššššššš››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЉЉЉЉЉЉЉЉЉЖЎЈЖЎЈЖЎЈЖЎЈКЌžКЌžКЌžКЌžНЋšНЋšНЋšНЋšР­›Р­›Р­›Р­›Т­›Т­›Т­›Т­›Щ­“Щ­“Щ­“Щ­“жЋ„жЋ„жЋ„жЋ„нЊzнЊzнЊzнЊzнЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ’жЭ’жЭ’жЭ’жЭ’ЬЧ’ЬЧ’ЬЧ’ЬЧ”ЗЖ”ЗЖ”ЗЖ”ЗƘЅІ˜ЅІ˜ЅІ˜ЅІšœšœšœšœšššššššššššš››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЉЉЉЉЉЉЉЉЉЖЎЈЖЎЈЖЎЈЖЎЈКЌžКЌžКЌžКЌžНЋšНЋšНЋšНЋšР­›Р­›Р­›Р­›Т­›Т­›Т­›Т­›Щ­“Щ­“Щ­“Щ­“жЋ„жЋ„жЋ„жЋ„нЊzнЊzнЊzнЊzнЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ’жЭ’жЭ’жЭ’жЭ’ЬЧ’ЬЧ’ЬЧ’ЬЧ”ЗЖ”ЗЖ”ЗЖ”ЗƘЅІ˜ЅІ˜ЅІ˜ЅІšœšœšœšœšššššššššššš››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЉЉЉЉЉЉЉЉЉЖЎЈЖЎЈЖЎЈЖЎЈКЌžКЌžКЌžКЌžНЋšНЋšНЋšНЋšР­›Р­›Р­›Р­›Т­›Т­›Т­›Т­›Щ­“Щ­“Щ­“Щ­“жЋ„жЋ„жЋ„жЋ„нЊzнЊzнЊzнЊzнЃnнЃnнЃnнЃnй˜\й˜\й˜\й˜\е”Uе”Uе”Uе”UЬœdЬœdЬœdЬœdЗБ‹ЗБ‹ЗБ‹ЗБ‹ŸЪЗŸЪЗŸЪЗŸЪЗ”жЫ”жЫ”жЫ”жЫ’жЭ’жЭ’жЭ’жЭ’ЬЧ’ЬЧ’ЬЧ’ЬЧ”ЗЖ”ЗЖ”ЗЖ”ЗƘЅІ˜ЅІ˜ЅІ˜ЅІšœšœšœšœšššššššššššš››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЉЉЉЉЉЉЉЉЉ­­Ћ­­Ћ­­Ћ­­ЋЎЌЊЎЌЊЎЌЊЎЌЊЎЋЉЎЋЉЎЋЉЎЋЉ­ЊЈ­ЊЈ­ЊЈ­ЊЈ­ЉЇ­ЉЇ­ЉЇ­ЉЇЗЏЈЗЏЈЗЏЈЗЏЈЮЛЈЮЛЈЮЛЈЮЛЈрО рО рО рО тГˆтГˆтГˆтГˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі|яї|яї|яї|яї~ш№~ш№~ш№~ш№†ел†ел†ел†ел’КН’КН’КН’КН›ЅЄ›ЅЄ›ЅЄ›ЅЄžšžšžšžšžœšžœšžœšžœšœ›œ›œ›œ›ŸŸŸŸŸŸŸŸŸŸŸŸЅЅЅЅЅЅЅЅЅ­­Ћ­­Ћ­­Ћ­­ЋЎЌЊЎЌЊЎЌЊЎЌЊЎЋЉЎЋЉЎЋЉЎЋЉ­ЊЈ­ЊЈ­ЊЈ­ЊЈ­ЉЇ­ЉЇ­ЉЇ­ЉЇЗЏЈЗЏЈЗЏЈЗЏЈЮЛЈЮЛЈЮЛЈЮЛЈрО рО рО рО тГˆтГˆтГˆтГˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі|яї|яї|яї|яї~ш№~ш№~ш№~ш№†ел†ел†ел†ел’КН’КН’КН’КН›ЅЄ›ЅЄ›ЅЄ›ЅЄžšžšžšžšžœšžœšžœšžœšœ›œ›œ›œ›ŸŸŸŸŸŸŸŸŸŸŸŸЅЅЅЅЅЅЅЅЅ­­Ћ­­Ћ­­Ћ­­ЋЎЌЊЎЌЊЎЌЊЎЌЊЎЋЉЎЋЉЎЋЉЎЋЉ­ЊЈ­ЊЈ­ЊЈ­ЊЈ­ЉЇ­ЉЇ­ЉЇ­ЉЇЗЏЈЗЏЈЗЏЈЗЏЈЮЛЈЮЛЈЮЛЈЮЛЈрО рО рО рО тГˆтГˆтГˆтГˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі|яї|яї|яї|яї~ш№~ш№~ш№~ш№†ел†ел†ел†ел’КН’КН’КН’КН›ЅЄ›ЅЄ›ЅЄ›ЅЄžšžšžšžšžœšžœšžœšžœšœ›œ›œ›œ›ŸŸŸŸŸŸŸŸŸŸŸŸЅЅЅЅЅЅЅЅЅ­­Ћ­­Ћ­­Ћ­­ЋЎЌЊЎЌЊЎЌЊЎЌЊЎЋЉЎЋЉЎЋЉЎЋЉ­ЊЈ­ЊЈ­ЊЈ­ЊЈ­ЉЇ­ЉЇ­ЉЇ­ЉЇЗЏЈЗЏЈЗЏЈЗЏЈЮЛЈЮЛЈЮЛЈЮЛЈрО рО рО рО тГˆтГˆтГˆтГˆкžfкžfкžfкžfЮ›bЮ›bЮ›bЮ›bЗБ‰ЗБ‰ЗБ‰ЗБ‰™бТ™бТ™бТ™бТ„чщ„чщ„чщ„чщ}юі}юі}юі}юі|яї|яї|яї|яї~ш№~ш№~ш№~ш№†ел†ел†ел†ел’КН’КН’КН’КН›ЅЄ›ЅЄ›ЅЄ›ЅЄžšžšžšžšžœšžœšžœšžœšœ›œ›œ›œ›ŸŸŸŸŸŸŸŸŸŸŸŸЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂ  Ÿ  Ÿ  Ÿ  ŸŸŸŸŸŸŸŸŸŸŸŸŸЅЃЁЅЃЁЅЃЁЅЃЁЖЊŸЖЊŸЖЊŸЖЊŸЫЋЫЋЫЋЫЋзЃtзЃtзЃtзЃtе™^е™^е™^е™^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§yёќyёќyёќyёќ~шё~шё~шё~шёЯбЯбЯбЯбЃЎЂЃЎЂЃЎЂЃЎЂЌŒЌŒЌŒЌŒЊ›Њ›Њ›Њ›Ѓœ–Ѓœ–Ѓœ–Ѓœ–ž›ž›ž›ž›ЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂ  Ÿ  Ÿ  Ÿ  ŸŸŸŸŸŸŸŸŸŸŸŸŸЅЃЁЅЃЁЅЃЁЅЃЁЖЊŸЖЊŸЖЊŸЖЊŸЫЋЫЋЫЋЫЋзЃtзЃtзЃtзЃtе™^е™^е™^е™^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§yёќyёќyёќyёќ~шё~шё~шё~шёЯбЯбЯбЯбЃЎЂЃЎЂЃЎЂЃЎЂЌŒЌŒЌŒЌŒЊ›Њ›Њ›Њ›Ѓœ–Ѓœ–Ѓœ–Ѓœ–ž›ž›ž›ž›ЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂ  Ÿ  Ÿ  Ÿ  ŸŸŸŸŸŸŸŸŸŸŸŸŸЅЃЁЅЃЁЅЃЁЅЃЁЖЊŸЖЊŸЖЊŸЖЊŸЫЋЫЋЫЋЫЋзЃtзЃtзЃtзЃtе™^е™^е™^е™^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§yёќyёќyёќyёќ~шё~шё~шё~шёЯбЯбЯбЯбЃЎЂЃЎЂЃЎЂЃЎЂЌŒЌŒЌŒЌŒЊ›Њ›Њ›Њ›Ѓœ–Ѓœ–Ѓœ–Ѓœ–ž›ž›ž›ž›ЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂ  Ÿ  Ÿ  Ÿ  ŸŸŸŸŸŸŸŸŸŸŸŸŸЅЃЁЅЃЁЅЃЁЅЃЁЖЊŸЖЊŸЖЊŸЖЊŸЫЋЫЋЫЋЫЋзЃtзЃtзЃtзЃtе™^е™^е™^е™^УЅsУЅsУЅsУЅsŸЪЕŸЪЕŸЪЕŸЪЕ„чш„чш„чш„чшzёњzёњzёњzёњyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§yёќyёќyёќyёќ~шё~шё~шё~шёЯбЯбЯбЯбЃЎЂЃЎЂЃЎЂЃЎЂЌŒЌŒЌŒЌŒЊ›Њ›Њ›Њ›Ѓœ–Ѓœ–Ѓœ–Ѓœ–ž›ž›ž›ž›ššššššššššššœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››››œ››œ››œ››œœ›œ›œ›œ›Є˜Є˜Є˜Є˜ГˆГˆГˆГˆХ—mХ—mХ—mХ—mЮ”[Ю”[Ю”[Ю”[МЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў|юї|юї|юї|юїзбзбзбзбВ­ŒВ­ŒВ­ŒВ­ŒУ–hУ–hУ–hУ–hР•mР•mР•mР•mВ™ƒВ™ƒВ™ƒВ™ƒЄ›”Є›”Є›”Є›”œ›™œ›™œ›™ššššššššššššœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››››œ››œ››œ››œœ›œ›œ›œ›Є˜Є˜Є˜Є˜ГˆГˆГˆГˆХ—mХ—mХ—mХ—mЮ”[Ю”[Ю”[Ю”[МЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў|юї|юї|юї|юїзбзбзбзбВ­ŒВ­ŒВ­ŒВ­ŒУ–hУ–hУ–hУ–hР•mР•mР•mР•mВ™ƒВ™ƒВ™ƒВ™ƒЄ›”Є›”Є›”Є›”œ›™œ›™œ›™ššššššššššššœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››››œ››œ››œ››œœ›œ›œ›œ›Є˜Є˜Є˜Є˜ГˆГˆГˆГˆХ—mХ—mХ—mХ—mЮ”[Ю”[Ю”[Ю”[МЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў|юї|юї|юї|юїзбзбзбзбВ­ŒВ­ŒВ­ŒВ­ŒУ–hУ–hУ–hУ–hР•mР•mР•mР•mВ™ƒВ™ƒВ™ƒВ™ƒЄ›”Є›”Є›”Є›”œ›™œ›™œ›™ššššššššššššœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››››œ››œ››œ››œœ›œ›œ›œ›Є˜Є˜Є˜Є˜ГˆГˆГˆГˆХ—mХ—mХ—mХ—mЮ”[Ю”[Ю”[Ю”[МЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў|юї|юї|юї|юїзбзбзбзбВ­ŒВ­ŒВ­ŒВ­ŒУ–hУ–hУ–hУ–hР•mР•mР•mР•mВ™ƒВ™ƒВ™ƒВ™ƒЄ›”Є›”Є›”Є›”œ›™œ›™œ›™™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ›ŸœŸœŸœŸœЈž–Јž–Јž–Јž–И™}И™}И™}И™}Ш”bШ”bШ”bШ”bМЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ“дЩ“дЩ“дЩ“дЩЛЈ{ЛЈ{ЛЈ{ЛЈ{а‘Rа‘Rа‘Rа‘RаRаRаRаRФ“fФ“fФ“fФ“f˜€В˜€В˜€В˜€Ѓš‘Ѓš‘Ѓš‘™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ›ŸœŸœŸœŸœЈž–Јž–Јž–Јž–И™}И™}И™}И™}Ш”bШ”bШ”bШ”bМЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ“дЩ“дЩ“дЩ“дЩЛЈ{ЛЈ{ЛЈ{ЛЈ{а‘Rа‘Rа‘Rа‘RаRаRаRаRФ“fФ“fФ“fФ“f˜€В˜€В˜€В˜€Ѓš‘Ѓš‘Ѓš‘™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ›ŸœŸœŸœŸœЈž–Јž–Јž–Јž–И™}И™}И™}И™}Ш”bШ”bШ”bШ”bМЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ“дЩ“дЩ“дЩ“дЩЛЈ{ЛЈ{ЛЈ{ЛЈ{а‘Rа‘Rа‘Rа‘RаRаRаRаRФ“fФ“fФ“fФ“f˜€В˜€В˜€В˜€Ѓš‘Ѓš‘Ѓš‘™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ›ŸœŸœŸœŸœЈž–Јž–Јž–Јž–И™}И™}И™}И™}Ш”bШ”bШ”bШ”bМЈ{МЈ{МЈ{МЈ{”дШ”дШ”дШ”дШ}юѕ}юѕ}юѕ}юѕyѓўyѓўyѓўyѓўyѓџyѓџyѓџyѓџyєџyєџyєџyєџyѓўyѓўyѓўyѓў}юѕ}юѕ}юѕ}юѕ“дЩ“дЩ“дЩ“дЩЛЈ{ЛЈ{ЛЈ{ЛЈ{а‘Rа‘Rа‘Rа‘RаRаRаRаRФ“fФ“fФ“fФ“f˜€В˜€В˜€В˜€Ѓš‘Ѓš‘Ѓš‘œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžžЄ œЄ œЄ œЄ œБ›†Б›†Б›†Б›†Х”dХ”dХ”dХ”dРЁpРЁpРЁpРЁpŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВТ lТ lТ lТ lгŽKгŽKгŽKгŽKд‹Hд‹Hд‹Hд‹HЯPЯPЯPЯPС‘dС‘dС‘dС‘dБ•zБ•zБ•zœœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžžЄ œЄ œЄ œЄ œБ›†Б›†Б›†Б›†Х”dХ”dХ”dХ”dРЁpРЁpРЁpРЁpŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВТ lТ lТ lТ lгŽKгŽKгŽKгŽKд‹Hд‹Hд‹Hд‹HЯPЯPЯPЯPС‘dС‘dС‘dС‘dБ•zБ•zБ•zœœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžžЄ œЄ œЄ œЄ œБ›†Б›†Б›†Б›†Х”dХ”dХ”dХ”dРЁpРЁpРЁpРЁpŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВТ lТ lТ lТ lгŽKгŽKгŽKгŽKд‹Hд‹Hд‹Hд‹HЯPЯPЯPЯPС‘dС‘dС‘dС‘dБ•zБ•zБ•zœœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžžЄ œЄ œЄ œЄ œБ›†Б›†Б›†Б›†Х”dХ”dХ”dХ”dРЁpРЁpРЁpРЁpŸШВŸШВŸШВŸШВ„цч„цч„цч„цчz№њz№њz№њz№њyђ§yђ§yђ§yђ§yђ§yђ§yђ§yђ§z№њz№њz№њz№њ„цч„цч„цч„цчŸШВŸШВŸШВŸШВТ lТ lТ lТ lгŽKгŽKгŽKгŽKд‹Hд‹Hд‹Hд‹HЯPЯPЯPЯPС‘dС‘dС‘dС‘dБ•zБ•zБ•zŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™œœœœЂŸЂŸЂŸЂŸА›ˆА›ˆА›ˆА›ˆЦ’aЦ’aЦ’aЦ’aЫ•YЫ•YЫ•YЫ•YЗ­З­З­З­™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Fе‹Fе‹Fе‹FдŠGдŠGдŠGдŠGЯŒNЯŒNЯŒNЯŒNФ^Ф^Ф^Ф^К“nК“nК“nŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™œœœœЂŸЂŸЂŸЂŸА›ˆА›ˆА›ˆА›ˆЦ’aЦ’aЦ’aЦ’aЫ•YЫ•YЫ•YЫ•YЗ­З­З­З­™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Fе‹Fе‹Fе‹FдŠGдŠGдŠGдŠGЯŒNЯŒNЯŒNЯŒNФ^Ф^Ф^Ф^К“nК“nК“nŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™œœœœЂŸЂŸЂŸЂŸА›ˆА›ˆА›ˆА›ˆЦ’aЦ’aЦ’aЦ’aЫ•YЫ•YЫ•YЫ•YЗ­З­З­З­™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Fе‹Fе‹Fе‹FдŠGдŠGдŠGдŠGЯŒNЯŒNЯŒNЯŒNФ^Ф^Ф^Ф^К“nК“nК“nŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™œœœœЂŸЂŸЂŸЂŸА›ˆА›ˆА›ˆА›ˆЦ’aЦ’aЦ’aЦ’aЫ•YЫ•YЫ•YЫ•YЗ­З­З­З­™ЮН™ЮН™ЮН™ЮН„цч„цч„цч„цч}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ}эѕ„цч„цч„цч„цч™ЮН™ЮН™ЮН™ЮНЗ­З­З­З­Э”UЭ”UЭ”UЭ”Uе‹Fе‹Fе‹Fе‹FдŠGдŠGдŠGдŠGЯŒNЯŒNЯŒNЯŒNФ^Ф^Ф^Ф^К“nК“nК“nЅЅЅЅЅЅЅЅЅЅЅЅЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™ŠЉ™ŠЉ™ŠЉ™ŠЃ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т“gТ“gТ“gТ“gаNаNаNаNЫ•WЫ•WЫ•WЫ•WЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Fд‹Fд‹Fд‹FбŠIбŠIбŠIбŠIЩVЩVЩVЩVП‘fП‘fП‘fП‘fГ•zГ•zГ•zГ•z­™†­™†­™†ЅЅЅЅЅЅЅЅЅЅЅЅЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™ŠЉ™ŠЉ™ŠЉ™ŠЃ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т“gТ“gТ“gТ“gаNаNаNаNЫ•WЫ•WЫ•WЫ•WЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Fд‹Fд‹Fд‹FбŠIбŠIбŠIбŠIЩVЩVЩVЩVП‘fП‘fП‘fП‘fГ•zГ•zГ•zГ•z­™†­™†­™†ЅЅЅЅЅЅЅЅЅЅЅЅЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™ŠЉ™ŠЉ™ŠЉ™ŠЃ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т“gТ“gТ“gТ“gаNаNаNаNЫ•WЫ•WЫ•WЫ•WЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Fд‹Fд‹Fд‹FбŠIбŠIбŠIбŠIЩVЩVЩVЩVП‘fП‘fП‘fП‘fГ•zГ•zГ•zГ•z­™†­™†­™†ЅЅЅЅЅЅЅЅЅЅЅЅЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™ŠЉ™ŠЉ™ŠЉ™ŠЃ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– › › › ›Ќ›‹Ќ›‹Ќ›‹Ќ›‹Т“gТ“gТ“gТ“gаNаNаNаNЫ•WЫ•WЫ•WЫ•WЗЌ€ЗЌ€ЗЌ€ЗЌ€ŸЦАŸЦАŸЦАŸЦА”гХ”гХ”гХ”гХ”гХ”гХ”гХ”гХŸЦАŸЦАŸЦАŸЦАЗЌ€ЗЌ€ЗЌ€ЗЌ€Ь”VЬ”VЬ”VЬ”Vд‹Fд‹Fд‹Fд‹FбŠIбŠIбŠIбŠIЩVЩVЩVЩVП‘fП‘fП‘fП‘fГ•zГ•zГ•zГ•z­™†­™†­™†ЏЎЎЏЎЎЏЎЎЏЎЎГЌІГЌІГЌІГЌІКЃŽКЃŽКЃŽКЃŽР–oР–oР–oР–oКiКiКiКiЉ‘|Љ‘|Љ‘|Љ‘|ž—‘ž—‘ž—‘ž—‘ŸšŸšŸšŸšЊœЊœЊœЊœО•nО•nО•nО•nЯŒNЯŒNЯŒNЯŒNгŠEгŠEгŠEгŠEЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCдˆCдˆCдˆCдˆCЩŒSЩŒSЩŒSЩŒSЗ“qЗ“qЗ“qЗ“qЋ˜‡Ћ˜‡Ћ˜‡Ћ˜‡Єœ•Єœ•Єœ•Єœ•ЂžœЂžœЂžœЏЎЎЏЎЎЏЎЎЏЎЎГЌІГЌІГЌІГЌІКЃŽКЃŽКЃŽКЃŽР–oР–oР–oР–oКiКiКiКiЉ‘|Љ‘|Љ‘|Љ‘|ž—‘ž—‘ž—‘ž—‘ŸšŸšŸšŸšЊœЊœЊœЊœО•nО•nО•nО•nЯŒNЯŒNЯŒNЯŒNгŠEгŠEгŠEгŠEЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCдˆCдˆCдˆCдˆCЩŒSЩŒSЩŒSЩŒSЗ“qЗ“qЗ“qЗ“qЋ˜‡Ћ˜‡Ћ˜‡Ћ˜‡Єœ•Єœ•Єœ•Єœ•ЂžœЂžœЂžœЏЎЎЏЎЎЏЎЎЏЎЎГЌІГЌІГЌІГЌІКЃŽКЃŽКЃŽКЃŽР–oР–oР–oР–oКiКiКiКiЉ‘|Љ‘|Љ‘|Љ‘|ž—‘ž—‘ž—‘ž—‘ŸšŸšŸšŸšЊœЊœЊœЊœО•nО•nО•nО•nЯŒNЯŒNЯŒNЯŒNгŠEгŠEгŠEгŠEЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCдˆCдˆCдˆCдˆCЩŒSЩŒSЩŒSЩŒSЗ“qЗ“qЗ“qЗ“qЋ˜‡Ћ˜‡Ћ˜‡Ћ˜‡Єœ•Єœ•Єœ•Єœ•ЂžœЂžœЂžœЏЎЎЏЎЎЏЎЎЏЎЎГЌІГЌІГЌІГЌІКЃŽКЃŽКЃŽКЃŽР–oР–oР–oР–oКiКiКiКiЉ‘|Љ‘|Љ‘|Љ‘|ž—‘ž—‘ž—‘ž—‘ŸšŸšŸšŸšЊœЊœЊœЊœО•nО•nО•nО•nЯŒNЯŒNЯŒNЯŒNгŠEгŠEгŠEгŠEЭ’QЭ’QЭ’QЭ’QТžgТžgТžgТžgМЄrМЄrМЄrМЄrМЄrМЄrМЄrМЄrТgТgТgТgЭ‘QЭ‘QЭ‘QЭ‘QдŠCдŠCдŠCдŠCдˆCдˆCдˆCдˆCЩŒSЩŒSЩŒSЩŒSЗ“qЗ“qЗ“qЗ“qЋ˜‡Ћ˜‡Ћ˜‡Ћ˜‡Єœ•Єœ•Єœ•Єœ•ЂžœЂžœЂžœДГБДГБДГБДГБЛБЇЛБЇЛБЇЛБЇЬЌЬЌЬЌЬЌеЅxеЅxеЅxеЅxЯŸsЯŸsЯŸsЯŸsОŸ‚ОŸ‚ОŸ‚ОŸ‚ЎЄšЎЄšЎЄšЎЄšЋЇЄЋЇЄЋЇЄЋЇЄДЃ“ДЃ“ДЃ“ДЃ“Х–kХ–kХ–kХ–kбŒMбŒMбŒMбŒMе‰Dе‰Dе‰Dе‰DеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?е‡>е‡>е‡>е‡>ЯˆFЯˆFЯˆFЯˆFН`Н`Н`Н`Ї”ƒЇ”ƒЇ”ƒЇ”ƒžš•žš•žš•žš•žžœžžœžžœžžœЂЁЁЂЁЁЂЁЁДГБДГБДГБДГБЛБЇЛБЇЛБЇЛБЇЬЌЬЌЬЌЬЌеЅxеЅxеЅxеЅxЯŸsЯŸsЯŸsЯŸsОŸ‚ОŸ‚ОŸ‚ОŸ‚ЎЄšЎЄšЎЄšЎЄšЋЇЄЋЇЄЋЇЄЋЇЄДЃ“ДЃ“ДЃ“ДЃ“Х–kХ–kХ–kХ–kбŒMбŒMбŒMбŒMе‰Dе‰Dе‰Dе‰DеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?е‡>е‡>е‡>е‡>ЯˆFЯˆFЯˆFЯˆFН`Н`Н`Н`Ї”ƒЇ”ƒЇ”ƒЇ”ƒžš•žš•žš•žš•žžœžžœžžœžžœЂЁЁЂЁЁЂЁЁДГБДГБДГБДГБЛБЇЛБЇЛБЇЛБЇЬЌЬЌЬЌЬЌеЅxеЅxеЅxеЅxЯŸsЯŸsЯŸsЯŸsОŸ‚ОŸ‚ОŸ‚ОŸ‚ЎЄšЎЄšЎЄšЎЄšЋЇЄЋЇЄЋЇЄЋЇЄДЃ“ДЃ“ДЃ“ДЃ“Х–kХ–kХ–kХ–kбŒMбŒMбŒMбŒMе‰Dе‰Dе‰Dе‰DеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?е‡>е‡>е‡>е‡>ЯˆFЯˆFЯˆFЯˆFН`Н`Н`Н`Ї”ƒЇ”ƒЇ”ƒЇ”ƒžš•žš•žš•žš•žžœžžœžžœžžœЂЁЁЂЁЁЂЁЁДГБДГБДГБДГБЛБЇЛБЇЛБЇЛБЇЬЌЬЌЬЌЬЌеЅxеЅxеЅxеЅxЯŸsЯŸsЯŸsЯŸsОŸ‚ОŸ‚ОŸ‚ОŸ‚ЎЄšЎЄšЎЄšЎЄšЋЇЄЋЇЄЋЇЄЋЇЄДЃ“ДЃ“ДЃ“ДЃ“Х–kХ–kХ–kХ–kбŒMбŒMбŒMбŒMе‰Dе‰Dе‰Dе‰DеŠEеŠEеŠEеŠEдHдHдHдHгIгIгIгIг‹Fг‹Fг‹Fг‹FгŠCгŠCгŠCгŠCеˆ?еˆ?еˆ?еˆ?е‡>е‡>е‡>е‡>ЯˆFЯˆFЯˆFЯˆFН`Н`Н`Н`Ї”ƒЇ”ƒЇ”ƒЇ”ƒžš•žš•žš•žš•žžœžžœžžœžžœЂЁЁЂЁЁЂЁЁАЏЎАЏЎАЏЎАЏЎКГ­КГ­КГ­КГ­аЛЇаЛЇаЛЇаЛЇоО оО оО оО лПЅлПЅлПЅлПЅгСАгСАгСАгСАЬФНЬФНЬФНЬФНЪЦТЪЦТЪЦТЪЦТЬМЎЬМЎЬМЎЬМЎаЇ‚аЇ‚аЇ‚аЇ‚гœiгœiгœiгœiдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;д†>д†>д†>д†>ЧˆOЧˆOЧˆOЧˆO­Žp­Žp­Žp­Žp›“‹›“‹›“‹›“‹˜–•˜–•˜–•˜–•››››››››››››ЁЁЁЁЁЁЁЁЁАЏЎАЏЎАЏЎАЏЎКГ­КГ­КГ­КГ­аЛЇаЛЇаЛЇаЛЇоО оО оО оО лПЅлПЅлПЅлПЅгСАгСАгСАгСАЬФНЬФНЬФНЬФНЪЦТЪЦТЪЦТЪЦТЬМЎЬМЎЬМЎЬМЎаЇ‚аЇ‚аЇ‚аЇ‚гœiгœiгœiгœiдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;д†>д†>д†>д†>ЧˆOЧˆOЧˆOЧˆO­Žp­Žp­Žp­Žp›“‹›“‹›“‹›“‹˜–•˜–•˜–•˜–•››››››››››››ЁЁЁЁЁЁЁЁЁАЏЎАЏЎАЏЎАЏЎКГ­КГ­КГ­КГ­аЛЇаЛЇаЛЇаЛЇоО оО оО оО лПЅлПЅлПЅлПЅгСАгСАгСАгСАЬФНЬФНЬФНЬФНЪЦТЪЦТЪЦТЪЦТЬМЎЬМЎЬМЎЬМЎаЇ‚аЇ‚аЇ‚аЇ‚гœiгœiгœiгœiдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;д†>д†>д†>д†>ЧˆOЧˆOЧˆOЧˆO­Žp­Žp­Žp­Žp›“‹›“‹›“‹›“‹˜–•˜–•˜–•˜–•››››››››››››ЁЁЁЁЁЁЁЁЁАЏЎАЏЎАЏЎАЏЎКГ­КГ­КГ­КГ­аЛЇаЛЇаЛЇаЛЇоО оО оО оО лПЅлПЅлПЅлПЅгСАгСАгСАгСАЬФНЬФНЬФНЬФНЪЦТЪЦТЪЦТЪЦТЬМЎЬМЎЬМЎЬМЎаЇ‚аЇ‚аЇ‚аЇ‚гœiгœiгœiгœiдšeдšeдšeдšeзœeзœeзœeзœeмŸfмŸfмŸfмŸfмš]мš]мš]мš]иŽIиŽIиŽIиŽIж‡=ж‡=ж‡=ж‡=ж†;ж†;ж†;ж†;д†>д†>д†>д†>ЧˆOЧˆOЧˆOЧˆO­Žp­Žp­Žp­Žp›“‹›“‹›“‹›“‹˜–•˜–•˜–•˜–•››››››››››››ЁЁЁЁЁЁЁЁЁІЄЃІЄЃІЄЃІЄЃЏІžЏІžЏІžЏІžХЉХЉХЉХЉйЏ‰йЏ‰йЏ‰йЏ‰тПŸтПŸтПŸтПŸфЩБфЩБфЩБфЩБхвСхвСхвСхвСшоешоешоешоецлвцлвцлвцлвоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<ж„:ж„:ж„:ж„:а†Bа†Bа†Bа†BМŠ]МŠ]МŠ]МŠ]Ђ~Ђ~Ђ~Ђ~•’•’•’•’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸІЄЃІЄЃІЄЃІЄЃЏІžЏІžЏІžЏІžХЉХЉХЉХЉйЏ‰йЏ‰йЏ‰йЏ‰тПŸтПŸтПŸтПŸфЩБфЩБфЩБфЩБхвСхвСхвСхвСшоешоешоешоецлвцлвцлвцлвоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<ж„:ж„:ж„:ж„:а†Bа†Bа†Bа†BМŠ]МŠ]МŠ]МŠ]Ђ~Ђ~Ђ~Ђ~•’•’•’•’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸІЄЃІЄЃІЄЃІЄЃЏІžЏІžЏІžЏІžХЉХЉХЉХЉйЏ‰йЏ‰йЏ‰йЏ‰тПŸтПŸтПŸтПŸфЩБфЩБфЩБфЩБхвСхвСхвСхвСшоешоешоешоецлвцлвцлвцлвоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<ж„:ж„:ж„:ж„:а†Bа†Bа†Bа†BМŠ]МŠ]МŠ]МŠ]Ђ~Ђ~Ђ~Ђ~•’•’•’•’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸІЄЃІЄЃІЄЃІЄЃЏІžЏІžЏІžЏІžХЉХЉХЉХЉйЏ‰йЏ‰йЏ‰йЏ‰тПŸтПŸтПŸтПŸфЩБфЩБфЩБфЩБхвСхвСхвСхвСшоешоешоешоецлвцлвцлвцлвоЫИоЫИоЫИоЫИйСЊйСЊйСЊйСЊйПЇйПЇйПЇйПЇнНЁнНЁнНЁнНЁуЙ“уЙ“уЙ“уЙ“тЋxтЋxтЋxтЋxл“Qл“Qл“Qл“Qз†<з†<з†<з†<ж„:ж„:ж„:ж„:а†Bа†Bа†Bа†BМŠ]МŠ]МŠ]МŠ]Ђ~Ђ~Ђ~Ђ~•’•’•’•’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸžš—žš—žš—žš—Њ–…Њ–…Њ–…Њ–…ТcТcТcТcе‘Tе‘Tе‘Tе‘Tн›_н›_н›_н›_рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊьвЛьвЛьвЛьвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8еƒ9еƒ9еƒ9еƒ9Ш†JШ†JШ†JШ†JЎnЎnЎnЎnš‘‰š‘‰š‘‰š‘‰’‘’‘’‘’‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••›››››››››žš—žš—žš—žš—Њ–…Њ–…Њ–…Њ–…ТcТcТcТcе‘Tе‘Tе‘Tе‘Tн›_н›_н›_н›_рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊьвЛьвЛьвЛьвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8еƒ9еƒ9еƒ9еƒ9Ш†JШ†JШ†JШ†JЎnЎnЎnЎnš‘‰š‘‰š‘‰š‘‰’‘’‘’‘’‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••›››››››››žš—žš—žš—žš—Њ–…Њ–…Њ–…Њ–…ТcТcТcТcе‘Tе‘Tе‘Tе‘Tн›_н›_н›_н›_рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊьвЛьвЛьвЛьвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8еƒ9еƒ9еƒ9еƒ9Ш†JШ†JШ†JШ†JЎnЎnЎnЎnš‘‰š‘‰š‘‰š‘‰’‘’‘’‘’‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••›››››››››žš—žš—žš—žš—Њ–…Њ–…Њ–…Њ–…ТcТcТcТcе‘Tе‘Tе‘Tе‘Tн›_н›_н›_н›_рЄlрЄlрЄlрЄlфВƒфВƒфВƒфВƒыЩЊыЩЊыЩЊыЩЊьвЛьвЛьвЛьвЛшЮЖшЮЖшЮЖшЮЖхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎуОœуОœуОœуОœсЊyсЊyсЊyсЊyнš[нš[нš[нš[й‹Dй‹Dй‹Dй‹Dз„8з„8з„8з„8еƒ9еƒ9еƒ9еƒ9Ш†JШ†JШ†JШ†JЎnЎnЎnЎnš‘‰š‘‰š‘‰š‘‰’‘’‘’‘’‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••››››››››› — — — —БqБqБqБqШ‡KШ‡KШ‡KШ‡Kд„;д„;д„;д„;з…;з…;з…;з…;иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„LТ„LТ„LТ„LЃŠsЃŠsЃŠsЃŠs“‹“‹“‹“‹ŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’ — — — —БqБqБqБqШ‡KШ‡KШ‡KШ‡Kд„;д„;д„;д„;з…;з…;з…;з…;иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„LТ„LТ„LТ„LЃŠsЃŠsЃŠsЃŠs“‹“‹“‹“‹ŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’ — — — —БqБqБqБqШ‡KШ‡KШ‡KШ‡Kд„;д„;д„;д„;з…;з…;з…;з…;иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„LТ„LТ„LТ„LЃŠsЃŠsЃŠsЃŠs“‹“‹“‹“‹ŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’ — — — —БqБqБqБqШ‡KШ‡KШ‡KШ‡Kд„;д„;д„;д„;з…;з…;з…;з…;иˆ>иˆ>иˆ>иˆ>кIкIкIкIпœ^пœ^пœ^пœ^сЂiсЂiсЂiсЂiрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhнš]нš]нš]нš]кŽHкŽHкŽHкŽHи†;и†;и†;и†;зƒ7зƒ7зƒ7зƒ7ж‚5ж‚5ж‚5ж‚5д‚8д‚8д‚8д‚8Т„LТ„LТ„LТ„LЃŠsЃŠsЃŠsЃŠs“‹“‹“‹“‹ŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’Ј–†Ј–†Ј–†Ј–†О‹]О‹]О‹]О‹]Я„>Я„>Я„>Я„>ж‚5ж‚5ж‚5ж‚5ж‚4ж‚4ж‚4ж‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7П‚IП‚IП‚IП‚Iœ„nœ„nœ„nœ„n‰†‰†‰†‰†ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰Ј–†Ј–†Ј–†Ј–†О‹]О‹]О‹]О‹]Я„>Я„>Я„>Я„>ж‚5ж‚5ж‚5ж‚5ж‚4ж‚4ж‚4ж‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7П‚IП‚IП‚IП‚Iœ„nœ„nœ„nœ„n‰†‰†‰†‰†ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰Ј–†Ј–†Ј–†Ј–†О‹]О‹]О‹]О‹]Я„>Я„>Я„>Я„>ж‚5ж‚5ж‚5ж‚5ж‚4ж‚4ж‚4ж‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7П‚IП‚IП‚IП‚Iœ„nœ„nœ„nœ„n‰†‰†‰†‰†ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰Ј–†Ј–†Ј–†Ј–†О‹]О‹]О‹]О‹]Я„>Я„>Я„>Я„>ж‚5ж‚5ж‚5ж‚5ж‚4ж‚4ж‚4ж‚4з‚4з‚4з‚4з‚4зƒ6зƒ6зƒ6зƒ6з…9з…9з…9з…9з†;з†;з†;з†;и†;и†;и†;и†;и†;и†;и†;и†;з†;з†;з†;з†;з„9з„9з„9з„9зƒ6зƒ6зƒ6зƒ6з‚4з‚4з‚4з‚4з‚4з‚4з‚4з‚4ж‚4ж‚4ж‚4ж‚4г7г7г7г7П‚IП‚IП‚IП‚Iœ„nœ„nœ„nœ„n‰†‰†‰†‰†ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџдšdдšdдšdдšdеšdеšdеšdеšdжšdжšdжšdжšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdж›dж›dж›dж›dж›eж›eж›eж›eе›eе›eе›eе›eд›fд›fд›fд›fбšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜™™™™™™™™™дšdдšdдšdдšdеšdеšdеšdеšdжšdжšdжšdжšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdж›dж›dж›dж›dж›eж›eж›eж›eе›eе›eе›eе›eд›fд›fд›fд›fбšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜™™™™™™™™™дšdдšdдšdдšdеšdеšdеšdеšdжšdжšdжšdжšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdж›dж›dж›dж›dж›eж›eж›eж›eе›eе›eе›eе›eд›fд›fд›fд›fбšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜™™™™™™™™™дšdдšdдšdдšdеšdеšdеšdеšdжšdжšdжšdжšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdзšdж›dж›dж›dж›dж›eж›eж›eж›eе›eе›eе›eе›eд›fд›fд›fд›fбšhбšhбšhбšhјsјsјsјsІ–ˆІ–ˆІ–ˆІ–ˆ—”’—”’—”’—”’‘‘‘‘‘‘‘‘‘‘‘‘””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜™™™™™™™™™Ф’eФ’eФ’eФ’eЯ—cЯ—cЯ—cЯ—cж™cж™cж™cж™cжšcжšcжšcжšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’Ф’eФ’eФ’eФ’eЯ—cЯ—cЯ—cЯ—cж™cж™cж™cж™cжšcжšcжšcжšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’Ф’eФ’eФ’eФ’eЯ—cЯ—cЯ—cЯ—cж™cж™cж™cж™cжšcжšcжšcжšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’Ф’eФ’eФ’eФ’eЯ—cЯ—cЯ—cЯ—cж™cж™cж™cж™cжšcжšcжšcжšcзšcзšcзšcзšcзšcзšcзšcзšcжšcжšcжšcжšcжšcжšcжšcжšcеšeеšeеšeеšeвœkвœkвœkвœkЫœqЫœqЫœqЫœqС—pС—pС—pС—pБ’uБ’uБ’uБ’u›„›„›„›„’Ž’Ž’Ž’ŽŽŽŽŽŽŽŽŽŽŽŽŽ’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’’ВŠfВŠfВŠfВŠfШ“bШ“bШ“bШ“bд˜aд˜aд˜aд˜aж™aж™aж™aж™aж™aж™aж™aж™aз™aз™aз™aз™aж™aж™aж™aж™aж™bж™bж™bж™bв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ………………………ВŠfВŠfВŠfВŠfШ“bШ“bШ“bШ“bд˜aд˜aд˜aд˜aж™aж™aж™aж™aж™aж™aж™aж™aз™aз™aз™aз™aж™aж™aж™aж™aж™bж™bж™bж™bв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ………………………ВŠfВŠfВŠfВŠfШ“bШ“bШ“bШ“bд˜aд˜aд˜aд˜aж™aж™aж™aж™aж™aж™aж™aж™aз™aз™aз™aз™aж™aж™aж™aж™aж™bж™bж™bж™bв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ………………………ВŠfВŠfВŠfВŠfШ“bШ“bШ“bШ“bд˜aд˜aд˜aд˜aж™aж™aж™aж™aж™aж™aж™aж™aз™aз™aз™aз™aж™aж™aж™aж™aж™bж™bж™bж™bв›jв›jв›jв›jЩЁ{ЩЁ{ЩЁ{ЩЁ{Й ‰Й ‰Й ‰Й ‰І•†І•†І•†І•†›Žƒ›Žƒ›Žƒ›Žƒ’‰’‰’‰’‰ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡ˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ………………………ЕlЕlЕlЕlШ”eШ”eШ”eШ”eв—aв—aв—aв—aе˜_е˜_е˜_е˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_в™fв™fв™fв™fЩŸzЩŸzЩŸzЩŸzОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡„„„„„„„„„„„„………………………………‰‰‰‰‰‰‰‰‰‰‰‰ЕlЕlЕlЕlШ”eШ”eШ”eШ”eв—aв—aв—aв—aе˜_е˜_е˜_е˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_в™fв™fв™fв™fЩŸzЩŸzЩŸzЩŸzОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡„„„„„„„„„„„„………………………………‰‰‰‰‰‰‰‰‰‰‰‰ЕlЕlЕlЕlШ”eШ”eШ”eШ”eв—aв—aв—aв—aе˜_е˜_е˜_е˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_в™fв™fв™fв™fЩŸzЩŸzЩŸzЩŸzОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡„„„„„„„„„„„„………………………………‰‰‰‰‰‰‰‰‰‰‰‰ЕlЕlЕlЕlШ”eШ”eШ”eШ”eв—aв—aв—aв—aе˜_е˜_е˜_е˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_ж˜_в™fв™fв™fв™fЩŸzЩŸzЩŸzЩŸzОЉ•ОЉ•ОЉ•ОЉ•ВЊЃВЊЃВЊЃВЊЃЃ Ѓ Ѓ Ѓ œš™œš™œš™œš™šš™šš™šš™šš™••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ‰‰‰‰‰‰‰‰‰‰‰‰‡‡‡‡‡‡‡‡‡‡‡‡„„„„„„„„„„„„………………………………‰‰‰‰‰‰‰‰‰‰‰‰Ћ”~Ћ”~Ћ”~Ћ”~М—tМ—tМ—tМ—tШ—kШ—kШ—kШ—kа–bа–bа–bа–bе–^е–^е–^е–^ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅŒПЅŒПЅŒПЅŒЙБЉЙБЉЙБЉЙБЉЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒЁЁЁЁЁЁЁЁЁЁЁЁЋЋЋЋЋЋЋЋЋЋЋЋЃЃЃЃЃЃЃЃЃЃЃЃ—————————Ћ”~Ћ”~Ћ”~Ћ”~М—tМ—tМ—tМ—tШ—kШ—kШ—kШ—kа–bа–bа–bа–bе–^е–^е–^е–^ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅŒПЅŒПЅŒПЅŒЙБЉЙБЉЙБЉЙБЉЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒЁЁЁЁЁЁЁЁЁЁЁЁЋЋЋЋЋЋЋЋЋЋЋЋЃЃЃЃЃЃЃЃЃЃЃЃ—————————Ћ”~Ћ”~Ћ”~Ћ”~М—tМ—tМ—tМ—tШ—kШ—kШ—kШ—kа–bа–bа–bа–bе–^е–^е–^е–^ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅŒПЅŒПЅŒПЅŒЙБЉЙБЉЙБЉЙБЉЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒЁЁЁЁЁЁЁЁЁЁЁЁЋЋЋЋЋЋЋЋЋЋЋЋЃЃЃЃЃЃЃЃЃЃЃЃ—————————Ћ”~Ћ”~Ћ”~Ћ”~М—tМ—tМ—tМ—tШ—kШ—kШ—kШ—kа–bа–bа–bа–bе–^е–^е–^е–^ж—]ж—]ж—]ж—]е—_е—_е—_е—_Ю›lЮ›lЮ›lЮ›lПЅŒПЅŒПЅŒПЅŒЙБЉЙБЉЙБЉЙБЉЖДГЖДГЖДГЖДГЎ­­Ў­­Ў­­Ў­­ЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЉЅЅЅЅЅЅЅЅЅЅЅЅœœœœœœœœœœœœ””””””””””””ŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆŒŒŒŒŒŒŒŒŒŒŒŒЁЁЁЁЁЁЁЁЁЁЁЁЋЋЋЋЋЋЋЋЋЋЋЋЃЃЃЃЃЃЃЃЃЃЃЃ—————————––––Ј™ŒЈ™ŒЈ™ŒЈ™ŒВ˜В˜В˜В˜С•nС•nС•nС•nЯ•`Я•`Я•`Я•`е•[е•[е•[е•[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ ŸŸ ŸŸ ŸŸ ŸŸ›™˜›™˜›™˜›™˜›™–›™–›™–›™–›™›™›™›™ЊЉЉЊЉЉЊЉЉЊЉЉШШЧШШЧШШЧШШЧггггггггггггЧЧЧЧЧЧЧЧЧЧЧЧККККККККК––––Ј™ŒЈ™ŒЈ™ŒЈ™ŒВ˜В˜В˜В˜С•nС•nС•nС•nЯ•`Я•`Я•`Я•`е•[е•[е•[е•[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ ŸŸ ŸŸ ŸŸ ŸŸ›™˜›™˜›™˜›™˜›™–›™–›™–›™–›™›™›™›™ЊЉЉЊЉЉЊЉЉЊЉЉШШЧШШЧШШЧШШЧггггггггггггЧЧЧЧЧЧЧЧЧЧЧЧККККККККК––––Ј™ŒЈ™ŒЈ™ŒЈ™ŒВ˜В˜В˜В˜С•nС•nС•nС•nЯ•`Я•`Я•`Я•`е•[е•[е•[е•[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ ŸŸ ŸŸ ŸŸ ŸŸ›™˜›™˜›™˜›™˜›™–›™–›™–›™–›™›™›™›™ЊЉЉЊЉЉЊЉЉЊЉЉШШЧШШЧШШЧШШЧггггггггггггЧЧЧЧЧЧЧЧЧЧЧЧККККККККК––––Ј™ŒЈ™ŒЈ™ŒЈ™ŒВ˜В˜В˜В˜С•nС•nС•nС•nЯ•`Я•`Я•`Я•`е•[е•[е•[е•[е–]е–]е–]е–]ЮškЮškЮškЮškРЄŠРЄŠРЄŠРЄŠЙЏІЙЏІЙЏІЙЏІЗДБЗДБЗДБЗДБГВАГВАГВАГВАБААБААБААБААВВВВВВВВВВВВААААААААААААЈЈЈЈЈЈЈЈЈЈЈЈ ŸŸ ŸŸ ŸŸ ŸŸ›™˜›™˜›™˜›™˜›™–›™–›™–›™–›™›™›™›™ЊЉЉЊЉЉЊЉЉЊЉЉШШЧШШЧШШЧШШЧггггггггггггЧЧЧЧЧЧЧЧЧЧЧЧКККККККККœœ›œœ›œœ›œœ› ž› ž› ž› ž›Ѕ•Ѕ•Ѕ•Ѕ•В˜€В˜€В˜€В˜€Ш•gШ•gШ•gШ•gд•[д•[д•[д•[ж•Zж•Zж•Zж•Zв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЋЋЊЋЋЊЋЋЊЋЋЊЈЃŸЈЃŸЈЃŸЈЃŸЉž“Љž“Љž“Љž“ВЃ•ВЃ•ВЃ•ВЃ•РЕЊРЕЊРЕЊРЕЊЫЧУЫЧУЫЧУЫЧУззжззжззжззжжжжжжжжжжжжжТТТТТТТТТТТТБББББББББœœ›œœ›œœ›œœ› ž› ž› ž› ž›Ѕ•Ѕ•Ѕ•Ѕ•В˜€В˜€В˜€В˜€Ш•gШ•gШ•gШ•gд•[д•[д•[д•[ж•Zж•Zж•Zж•Zв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЋЋЊЋЋЊЋЋЊЋЋЊЈЃŸЈЃŸЈЃŸЈЃŸЉž“Љž“Љž“Љž“ВЃ•ВЃ•ВЃ•ВЃ•РЕЊРЕЊРЕЊРЕЊЫЧУЫЧУЫЧУЫЧУззжззжззжззжжжжжжжжжжжжжТТТТТТТТТТТТБББББББББœœ›œœ›œœ›œœ› ž› ž› ž› ž›Ѕ•Ѕ•Ѕ•Ѕ•В˜€В˜€В˜€В˜€Ш•gШ•gШ•gШ•gд•[д•[д•[д•[ж•Zж•Zж•Zж•Zв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЋЋЊЋЋЊЋЋЊЋЋЊЈЃŸЈЃŸЈЃŸЈЃŸЉž“Љž“Љž“Љž“ВЃ•ВЃ•ВЃ•ВЃ•РЕЊРЕЊРЕЊРЕЊЫЧУЫЧУЫЧУЫЧУззжззжззжззжжжжжжжжжжжжжТТТТТТТТТТТТБББББББББœœ›œœ›œœ›œœ› ž› ž› ž› ž›Ѕ•Ѕ•Ѕ•Ѕ•В˜€В˜€В˜€В˜€Ш•gШ•gШ•gШ•gд•[д•[д•[д•[ж•Zж•Zж•Zж•Zв–`в–`в–`в–`ЩœsЩœsЩœsЩœsРЄ‹РЄ‹РЄ‹РЄ‹МЈ—МЈ—МЈ—МЈ—ИЊžИЊžИЊžИЊžДЎЊДЎЊДЎЊДЎЊВББВББВББВББААААААААААААЋЋЊЋЋЊЋЋЊЋЋЊЈЃŸЈЃŸЈЃŸЈЃŸЉž“Љž“Љž“Љž“ВЃ•ВЃ•ВЃ•ВЃ•РЕЊРЕЊРЕЊРЕЊЫЧУЫЧУЫЧУЫЧУззжззжззжззжжжжжжжжжжжжжТТТТТТТТТТТТБББББББББ            ЂЂЂЂЂЂЂЂЂЂЂЂЈЅЂЈЅЂЈЅЂЈЅЂВЃ•ВЃ•ВЃ•ВЃ•ХxХxХxХxб—aб—aб—aб—aе”Yе”Yе”Yе”Yе”Xе”Xе”Xе”Xв•^в•^в•^в•^ޘhޘhޘhޘhЪšoЪšoЪšoЪšoСž~Сž~Сž~Сž~ГЅ™ГЅ™ГЅ™ГЅ™ЌЊЉЌЊЉЌЊЉЌЊЉЌЌЋЌЌЋЌЌЋЌЌЋЋЉЈЋЉЈЋЉЈЋЉЈ­Є­Є­Є­ЄДž‹Дž‹Дž‹Дž‹ОЂŠОЂŠОЂŠОЂŠЧВžЧВžЧВžЧВžЦОЖЦОЖЦОЖЦОЖТСРТСРТСРТСРППППППППППППЕЕЕЕЕЕЕЕЕЕЕЕЋЋЋЋЋЋЋЋЋ            ЂЂЂЂЂЂЂЂЂЂЂЂЈЅЂЈЅЂЈЅЂЈЅЂВЃ•ВЃ•ВЃ•ВЃ•ХxХxХxХxб—aб—aб—aб—aе”Yе”Yе”Yе”Yе”Xе”Xе”Xе”Xв•^в•^в•^в•^ޘhޘhޘhޘhЪšoЪšoЪšoЪšoСž~Сž~Сž~Сž~ГЅ™ГЅ™ГЅ™ГЅ™ЌЊЉЌЊЉЌЊЉЌЊЉЌЌЋЌЌЋЌЌЋЌЌЋЋЉЈЋЉЈЋЉЈЋЉЈ­Є­Є­Є­ЄДž‹Дž‹Дž‹Дž‹ОЂŠОЂŠОЂŠОЂŠЧВžЧВžЧВžЧВžЦОЖЦОЖЦОЖЦОЖТСРТСРТСРТСРППППППППППППЕЕЕЕЕЕЕЕЕЕЕЕЋЋЋЋЋЋЋЋЋ            ЂЂЂЂЂЂЂЂЂЂЂЂЈЅЂЈЅЂЈЅЂЈЅЂВЃ•ВЃ•ВЃ•ВЃ•ХxХxХxХxб—aб—aб—aб—aе”Yе”Yе”Yе”Yе”Xе”Xе”Xе”Xв•^в•^в•^в•^ޘhޘhޘhޘhЪšoЪšoЪšoЪšoСž~Сž~Сž~Сž~ГЅ™ГЅ™ГЅ™ГЅ™ЌЊЉЌЊЉЌЊЉЌЊЉЌЌЋЌЌЋЌЌЋЌЌЋЋЉЈЋЉЈЋЉЈЋЉЈ­Є­Є­Є­ЄДž‹Дž‹Дž‹Дž‹ОЂŠОЂŠОЂŠОЂŠЧВžЧВžЧВžЧВžЦОЖЦОЖЦОЖЦОЖТСРТСРТСРТСРППППППППППППЕЕЕЕЕЕЕЕЕЕЕЕЋЋЋЋЋЋЋЋЋ            ЂЂЂЂЂЂЂЂЂЂЂЂЈЅЂЈЅЂЈЅЂЈЅЂВЃ•ВЃ•ВЃ•ВЃ•ХxХxХxХxб—aб—aб—aб—aе”Yе”Yе”Yе”Yе”Xе”Xе”Xе”Xв•^в•^в•^в•^ޘhޘhޘhޘhЪšoЪšoЪšoЪšoСž~Сž~Сž~Сž~ГЅ™ГЅ™ГЅ™ГЅ™ЌЊЉЌЊЉЌЊЉЌЊЉЌЌЋЌЌЋЌЌЋЌЌЋЋЉЈЋЉЈЋЉЈЋЉЈ­Є­Є­Є­ЄДž‹Дž‹Дž‹Дž‹ОЂŠОЂŠОЂŠОЂŠЧВžЧВžЧВžЧВžЦОЖЦОЖЦОЖЦОЖТСРТСРТСРТСРППППППППППППЕЕЕЕЕЕЕЕЕЕЕЕЋЋЋЋЋЋЋЋЋžžžžžžžžžžžž            ЇІЅЇІЅЇІЅЇІЅАЊЄАЊЄАЊЄАЊЄОЈ“ОЈ“ОЈ“ОЈ“ЪžvЪžvЪžvЪžvв—`в—`в—`в—`д”Xд”Xд”Xд”Xе“Vе“Vе“Vе“Vе“Wе“Wе“Wе“Wв”Zв”Zв”Zв”ZХ—kХ—kХ—kХ—kЏœ‹Џœ‹Џœ‹Џœ‹ЄЂŸЄЂŸЄЂŸЄЂŸЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЃЂЂЃЂЂЃЂЂІЁІЁІЁІЁЌ –Ќ –Ќ –Ќ –ВЄ–ВЄ–ВЄ–ВЄ–И­ЂИ­ЂИ­ЂИ­ЂЗВЎЗВЎЗВЎЗВЎДДГДДГДДГДДГЕЕЕЕЕЕЕЕЕЕЕЕГГГГГГГГГГГГЏЏЏЏЏЏЏЏЏžžžžžžžžžžžž            ЇІЅЇІЅЇІЅЇІЅАЊЄАЊЄАЊЄАЊЄОЈ“ОЈ“ОЈ“ОЈ“ЪžvЪžvЪžvЪžvв—`в—`в—`в—`д”Xд”Xд”Xд”Xе“Vе“Vе“Vе“Vе“Wе“Wе“Wе“Wв”Zв”Zв”Zв”ZХ—kХ—kХ—kХ—kЏœ‹Џœ‹Џœ‹Џœ‹ЄЂŸЄЂŸЄЂŸЄЂŸЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЃЂЂЃЂЂЃЂЂІЁІЁІЁІЁЌ –Ќ –Ќ –Ќ –ВЄ–ВЄ–ВЄ–ВЄ–И­ЂИ­ЂИ­ЂИ­ЂЗВЎЗВЎЗВЎЗВЎДДГДДГДДГДДГЕЕЕЕЕЕЕЕЕЕЕЕГГГГГГГГГГГГЏЏЏЏЏЏЏЏЏžžžžžžžžžžžž            ЇІЅЇІЅЇІЅЇІЅАЊЄАЊЄАЊЄАЊЄОЈ“ОЈ“ОЈ“ОЈ“ЪžvЪžvЪžvЪžvв—`в—`в—`в—`д”Xд”Xд”Xд”Xе“Vе“Vе“Vе“Vе“Wе“Wе“Wе“Wв”Zв”Zв”Zв”ZХ—kХ—kХ—kХ—kЏœ‹Џœ‹Џœ‹Џœ‹ЄЂŸЄЂŸЄЂŸЄЂŸЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЃЂЂЃЂЂЃЂЂІЁІЁІЁІЁЌ –Ќ –Ќ –Ќ –ВЄ–ВЄ–ВЄ–ВЄ–И­ЂИ­ЂИ­ЂИ­ЂЗВЎЗВЎЗВЎЗВЎДДГДДГДДГДДГЕЕЕЕЕЕЕЕЕЕЕЕГГГГГГГГГГГГЏЏЏЏЏЏЏЏЏžžžžžžžžžžžž            ЇІЅЇІЅЇІЅЇІЅАЊЄАЊЄАЊЄАЊЄОЈ“ОЈ“ОЈ“ОЈ“ЪžvЪžvЪžvЪžvв—`в—`в—`в—`д”Xд”Xд”Xд”Xе“Vе“Vе“Vе“Vе“Wе“Wе“Wе“Wв”Zв”Zв”Zв”ZХ—kХ—kХ—kХ—kЏœ‹Џœ‹Џœ‹Џœ‹ЄЂŸЄЂŸЄЂŸЄЂŸЃЃЃЃЃЃЃЃЃЃЃЃЃЂЂЃЂЂЃЂЂЃЂЂІЁІЁІЁІЁЌ –Ќ –Ќ –Ќ –ВЄ–ВЄ–ВЄ–ВЄ–И­ЂИ­ЂИ­ЂИ­ЂЗВЎЗВЎЗВЎЗВЎДДГДДГДДГДДГЕЕЕЕЕЕЕЕЕЕЕЕГГГГГГГГГГГГЏЏЏЏЏЏЏЏЏššššššššššššœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЊЉЈЊЉЈЊЉЈЊЉЈД­ІД­ІД­ІД­ІПЈ“ПЈ“ПЈ“ПЈ“Щ zЩ zЩ zЩ zЮšiЮšiЮšiЮšiв•\в•\в•\в•\г’Vг’Vг’Vг’Vв’Wв’Wв’Wв’WФ”hФ”hФ”hФ”hЋ™ˆЋ™ˆЋ™ˆЋ™ˆžœšžœšžœšžœšœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ› žœ žœ žœ žœЅЃЁЅЃЁЅЃЁЅЃЁ­ЋЊ­ЋЊ­ЋЊ­ЋЊБААБААБААБААГГГГГГГГГГГГДДДДДДДДДДДДББББББББББББ­­­­­­­­­ššššššššššššœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЊЉЈЊЉЈЊЉЈЊЉЈД­ІД­ІД­ІД­ІПЈ“ПЈ“ПЈ“ПЈ“Щ zЩ zЩ zЩ zЮšiЮšiЮšiЮšiв•\в•\в•\в•\г’Vг’Vг’Vг’Vв’Wв’Wв’Wв’WФ”hФ”hФ”hФ”hЋ™ˆЋ™ˆЋ™ˆЋ™ˆžœšžœšžœšžœšœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ› žœ žœ žœ žœЅЃЁЅЃЁЅЃЁЅЃЁ­ЋЊ­ЋЊ­ЋЊ­ЋЊБААБААБААБААГГГГГГГГГГГГДДДДДДДДДДДДББББББББББББ­­­­­­­­­ššššššššššššœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЊЉЈЊЉЈЊЉЈЊЉЈД­ІД­ІД­ІД­ІПЈ“ПЈ“ПЈ“ПЈ“Щ zЩ zЩ zЩ zЮšiЮšiЮšiЮšiв•\в•\в•\в•\г’Vг’Vг’Vг’Vв’Wв’Wв’Wв’WФ”hФ”hФ”hФ”hЋ™ˆЋ™ˆЋ™ˆЋ™ˆžœšžœšžœšžœšœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ› žœ žœ žœ žœЅЃЁЅЃЁЅЃЁЅЃЁ­ЋЊ­ЋЊ­ЋЊ­ЋЊБААБААБААБААГГГГГГГГГГГГДДДДДДДДДДДДББББББББББББ­­­­­­­­­ššššššššššššœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЊЉЈЊЉЈЊЉЈЊЉЈД­ІД­ІД­ІД­ІПЈ“ПЈ“ПЈ“ПЈ“Щ zЩ zЩ zЩ zЮšiЮšiЮšiЮšiв•\в•\в•\в•\г’Vг’Vг’Vг’Vв’Wв’Wв’Wв’WФ”hФ”hФ”hФ”hЋ™ˆЋ™ˆЋ™ˆЋ™ˆžœšžœšžœšžœšœœœœœœœœœœœœ››››››››››››œœ›œœ›œœ›œœ› žœ žœ žœ žœЅЃЁЅЃЁЅЃЁЅЃЁ­ЋЊ­ЋЊ­ЋЊ­ЋЊБААБААБААБААГГГГГГГГГГГГДДДДДДДДДДДДББББББББББББ­­­­­­­­­™™™™™™™™™™™™››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЈЈЈЈЈЈЈЈЈЈЈЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ЕЎЈЕЎЈЕЎЈЕЎЈКЋœКЋœКЋœКЋœПЄ‹ПЄ‹ПЄ‹ПЄ‹ХœuХœuХœuХœuЧ–hЧ–hЧ–hЧ–hШ•eШ•eШ•eШ•eОšsОšsОšsОšsІЄ”ІЄ”ІЄ”ІЄ”›ЃЁ›ЃЁ›ЃЁ›ЃЁšššššššššššššššš››››››››››››ЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЌЌЌЌЌЌЌЌЌ™™™™™™™™™™™™››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЈЈЈЈЈЈЈЈЈЈЈЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ЕЎЈЕЎЈЕЎЈЕЎЈКЋœКЋœКЋœКЋœПЄ‹ПЄ‹ПЄ‹ПЄ‹ХœuХœuХœuХœuЧ–hЧ–hЧ–hЧ–hШ•eШ•eШ•eШ•eОšsОšsОšsОšsІЄ”ІЄ”ІЄ”ІЄ”›ЃЁ›ЃЁ›ЃЁ›ЃЁšššššššššššššššš››››››››››››ЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЌЌЌЌЌЌЌЌЌ™™™™™™™™™™™™››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЈЈЈЈЈЈЈЈЈЈЈЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ЕЎЈЕЎЈЕЎЈЕЎЈКЋœКЋœКЋœКЋœПЄ‹ПЄ‹ПЄ‹ПЄ‹ХœuХœuХœuХœuЧ–hЧ–hЧ–hЧ–hШ•eШ•eШ•eШ•eОšsОšsОšsОšsІЄ”ІЄ”ІЄ”ІЄ”›ЃЁ›ЃЁ›ЃЁ›ЃЁšššššššššššššššš››››››››››››ЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЌЌЌЌЌЌЌЌЌ™™™™™™™™™™™™››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЈЈЈЈЈЈЈЈЈЈЈЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ЕЎЈЕЎЈЕЎЈЕЎЈКЋœКЋœКЋœКЋœПЄ‹ПЄ‹ПЄ‹ПЄ‹ХœuХœuХœuХœuЧ–hЧ–hЧ–hЧ–hШ•eШ•eШ•eШ•eОšsОšsОšsОšsІЄ”ІЄ”ІЄ”ІЄ”›ЃЁ›ЃЁ›ЃЁ›ЃЁšššššššššššššššš››››››››››››ЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЌЌЌЌЌЌЌЌЌœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЈЈЈЈЈЈЈЈЈЈЈЈЌЌЋЌЌЋЌЌЋЌЌЋ­­Ћ­­Ћ­­Ћ­­ЋЎЌЉЎЌЉЎЌЉЎЌЉЎЈЁЎЈЁЎЈЁЎЈЁЏЁ“ЏЁ“ЏЁ“ЏЁ“Џ›‰Џ›‰Џ›‰Џ›‰В›ƒВ›ƒВ›ƒВ›ƒ­ІŽ­ІŽ­ІŽ­ІŽ™КВ™КВ™КВ™КВ”ЗИ”ЗИ”ЗИ”ЗИ™ЈЉ™ЈЉ™ЈЉ™ЈЉ›ЁЁ›ЁЁ›ЁЁ›ЁЁ›ŸŸ›ŸŸ›ŸŸ›ŸŸœœœœŸ  Ÿ  Ÿ  Ÿ  ІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЈЈЈЈЈЈЈЈЈЈЈЈЌЌЋЌЌЋЌЌЋЌЌЋ­­Ћ­­Ћ­­Ћ­­ЋЎЌЉЎЌЉЎЌЉЎЌЉЎЈЁЎЈЁЎЈЁЎЈЁЏЁ“ЏЁ“ЏЁ“ЏЁ“Џ›‰Џ›‰Џ›‰Џ›‰В›ƒВ›ƒВ›ƒВ›ƒ­ІŽ­ІŽ­ІŽ­ІŽ™КВ™КВ™КВ™КВ”ЗИ”ЗИ”ЗИ”ЗИ™ЈЉ™ЈЉ™ЈЉ™ЈЉ›ЁЁ›ЁЁ›ЁЁ›ЁЁ›ŸŸ›ŸŸ›ŸŸ›ŸŸœœœœŸ  Ÿ  Ÿ  Ÿ  ІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЈЈЈЈЈЈЈЈЈЈЈЈЌЌЋЌЌЋЌЌЋЌЌЋ­­Ћ­­Ћ­­Ћ­­ЋЎЌЉЎЌЉЎЌЉЎЌЉЎЈЁЎЈЁЎЈЁЎЈЁЏЁ“ЏЁ“ЏЁ“ЏЁ“Џ›‰Џ›‰Џ›‰Џ›‰В›ƒВ›ƒВ›ƒВ›ƒ­ІŽ­ІŽ­ІŽ­ІŽ™КВ™КВ™КВ™КВ”ЗИ”ЗИ”ЗИ”ЗИ™ЈЉ™ЈЉ™ЈЉ™ЈЉ›ЁЁ›ЁЁ›ЁЁ›ЁЁ›ŸŸ›ŸŸ›ŸŸ›ŸŸœœœœŸ  Ÿ  Ÿ  Ÿ  ІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЈЈЈЈЈЈЈЈЈЈЈЈЌЌЋЌЌЋЌЌЋЌЌЋ­­Ћ­­Ћ­­Ћ­­ЋЎЌЉЎЌЉЎЌЉЎЌЉЎЈЁЎЈЁЎЈЁЎЈЁЏЁ“ЏЁ“ЏЁ“ЏЁ“Џ›‰Џ›‰Џ›‰Џ›‰В›ƒВ›ƒВ›ƒВ›ƒ­ІŽ­ІŽ­ІŽ­ІŽ™КВ™КВ™КВ™КВ”ЗИ”ЗИ”ЗИ”ЗИ™ЈЉ™ЈЉ™ЈЉ™ЈЉ›ЁЁ›ЁЁ›ЁЁ›ЁЁ›ŸŸ›ŸŸ›ŸŸ›ŸŸœœœœŸ  Ÿ  Ÿ  Ÿ  ІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌЌŸŸŸŸŸŸŸŸŸŸŸŸ            ЂЂЂЂЂЂЂЂЂЂЂЂЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЃЃЄЃЃЄЃЃЄЃЃЃЂ ЃЂ ЃЂ ЃЂ  žœ žœ žœ žœŸœ™Ÿœ™Ÿœ™Ÿœ™ — — — —œЊЄœЊЄœЊЄœЊЄХЦХЦХЦХЦ‹Эг‹Эг‹Эг‹ЭгСХСХСХСХ”ЗК”ЗК”ЗК”ЗК—БГ—БГ—БГ—БГšІЇšІЇšІЇšІЇŸ Ÿ Ÿ Ÿ ŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸ            ЂЂЂЂЂЂЂЂЂЂЂЂЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЃЃЄЃЃЄЃЃЄЃЃЃЂ ЃЂ ЃЂ ЃЂ  žœ žœ žœ žœŸœ™Ÿœ™Ÿœ™Ÿœ™ — — — —œЊЄœЊЄœЊЄœЊЄХЦХЦХЦХЦ‹Эг‹Эг‹Эг‹ЭгСХСХСХСХ”ЗК”ЗК”ЗК”ЗК—БГ—БГ—БГ—БГšІЇšІЇšІЇšІЇŸ Ÿ Ÿ Ÿ ŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸ            ЂЂЂЂЂЂЂЂЂЂЂЂЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЃЃЄЃЃЄЃЃЄЃЃЃЂ ЃЂ ЃЂ ЃЂ  žœ žœ žœ žœŸœ™Ÿœ™Ÿœ™Ÿœ™ — — — —œЊЄœЊЄœЊЄœЊЄХЦХЦХЦХЦ‹Эг‹Эг‹Эг‹ЭгСХСХСХСХ”ЗК”ЗК”ЗК”ЗК—БГ—БГ—БГ—БГšІЇšІЇšІЇšІЇŸ Ÿ Ÿ Ÿ ŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸ            ЂЂЂЂЂЂЂЂЂЂЂЂЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЃЃЄЃЃЄЃЃЄЃЃЃЂ ЃЂ ЃЂ ЃЂ  žœ žœ žœ žœŸœ™Ÿœ™Ÿœ™Ÿœ™ — — — —œЊЄœЊЄœЊЄœЊЄХЦХЦХЦХЦ‹Эг‹Эг‹Эг‹ЭгСХСХСХСХ”ЗК”ЗК”ЗК”ЗК—БГ—БГ—БГ—БГšІЇšІЇšІЇšІЇŸ Ÿ Ÿ Ÿ ŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œ››œ››œ››œ›››œ››œ››œ››œ›šЄЄšЄЄšЄЄšЄЄ”КМ”КМ”КМ”КМŠажŠажŠажŠаж…кт…кт…кт…кт„кт„кт„кт„кт‰би‰би‰би‰би“МП“МП“МП“МПšЇЈšЇЈšЇЈšЇЈ›žž›žž›žž›žžœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››ššššššššš            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œ››œ››œ››œ›››œ››œ››œ››œ›šЄЄšЄЄšЄЄšЄЄ”КМ”КМ”КМ”КМŠажŠажŠажŠаж…кт…кт…кт…кт„кт„кт„кт„кт‰би‰би‰би‰би“МП“МП“МП“МПšЇЈšЇЈšЇЈšЇЈ›žž›žž›žž›žžœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››ššššššššš            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œ››œ››œ››œ›››œ››œ››œ››œ›šЄЄšЄЄšЄЄšЄЄ”КМ”КМ”КМ”КМŠажŠажŠажŠаж…кт…кт…кт…кт„кт„кт„кт„кт‰би‰би‰би‰би“МП“МП“МП“МПšЇЈšЇЈšЇЈšЇЈ›žž›žž›žž›žžœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››ššššššššš            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œ››œ››œ››œ›››œ››œ››œ››œ›šЄЄšЄЄšЄЄšЄЄ”КМ”КМ”КМ”КМŠажŠажŠажŠаж…кт…кт…кт…кт„кт„кт„кт„кт‰би‰би‰би‰би“МП“МП“МП“МПšЇЈšЇЈšЇЈšЇЈ›žž›žž›žž›žžœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››šššššššššЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœ Ÿ Ÿ Ÿ ŸœЋЌœЋЌœЋЌœЋЌ‘ТЦ‘ТЦ‘ТЦ‘ТЦ‚пш‚пш‚пш‚пш{эї{эї{эї{эї}щђ}щђ}щђ}щђ‡жм‡жм‡жм‡жм”ЙК”ЙК”ЙК”ЙК›ЃЁ›ЃЁ›ЃЁ›ЃЁ›™›™›™›™œ›˜œ›˜œ›˜œ›˜››š››š››š››š™™™™™™™™™™™™–––––––––ЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœ Ÿ Ÿ Ÿ ŸœЋЌœЋЌœЋЌœЋЌ‘ТЦ‘ТЦ‘ТЦ‘ТЦ‚пш‚пш‚пш‚пш{эї{эї{эї{эї}щђ}щђ}щђ}щђ‡жм‡жм‡жм‡жм”ЙК”ЙК”ЙК”ЙК›ЃЁ›ЃЁ›ЃЁ›ЃЁ›™›™›™›™œ›˜œ›˜œ›˜œ›˜››š››š››š››š™™™™™™™™™™™™–––––––––ЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœ Ÿ Ÿ Ÿ ŸœЋЌœЋЌœЋЌœЋЌ‘ТЦ‘ТЦ‘ТЦ‘ТЦ‚пш‚пш‚пш‚пш{эї{эї{эї{эї}щђ}щђ}щђ}щђ‡жм‡жм‡жм‡жм”ЙК”ЙК”ЙК”ЙК›ЃЁ›ЃЁ›ЃЁ›ЃЁ›™›™›™›™œ›˜œ›˜œ›˜œ›˜››š››š››š››š™™™™™™™™™™™™–––––––––ЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœ››››››››››››œœœœœœœœœœœœ Ÿ Ÿ Ÿ ŸœЋЌœЋЌœЋЌœЋЌ‘ТЦ‘ТЦ‘ТЦ‘ТЦ‚пш‚пш‚пш‚пш{эї{эї{эї{эї}щђ}щђ}щђ}щђ‡жм‡жм‡жм‡жм”ЙК”ЙК”ЙК”ЙК›ЃЁ›ЃЁ›ЃЁ›ЃЁ›™›™›™›™œ›˜œ›˜œ›˜œ›˜››š››š››š››š™™™™™™™™™™™™–––––––––ЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžŸŸžŸŸžŸŸžŸŸŸЅІŸЅІŸЅІŸЅІ•КН•КН•КН•КН„нх„нх„нх„нхzяњzяњzяњzяњ{яј{яј{яј{яј…пт…пт…пт…пт–РИ–РИ–РИ–РИЃЃ•ЃЃ•ЃЃ•ЃЃ•Ї˜ˆЇ˜ˆЇ˜ˆЇ˜ˆЄ—ŠЄ—ŠЄ—ŠЄ—Šž˜’ž˜’ž˜’ž˜’˜–”˜–”˜–”˜–”“’‘“’‘“’‘ЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžŸŸžŸŸžŸŸžŸŸŸЅІŸЅІŸЅІŸЅІ•КН•КН•КН•КН„нх„нх„нх„нхzяњzяњzяњzяњ{яј{яј{яј{яј…пт…пт…пт…пт–РИ–РИ–РИ–РИЃЃ•ЃЃ•ЃЃ•ЃЃ•Ї˜ˆЇ˜ˆЇ˜ˆЇ˜ˆЄ—ŠЄ—ŠЄ—ŠЄ—Šž˜’ž˜’ž˜’ž˜’˜–”˜–”˜–”˜–”“’‘“’‘“’‘ЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžŸŸžŸŸžŸŸžŸŸŸЅІŸЅІŸЅІŸЅІ•КН•КН•КН•КН„нх„нх„нх„нхzяњzяњzяњzяњ{яј{яј{яј{яј…пт…пт…пт…пт–РИ–РИ–РИ–РИЃЃ•ЃЃ•ЃЃ•ЃЃ•Ї˜ˆЇ˜ˆЇ˜ˆЇ˜ˆЄ—ŠЄ—ŠЄ—ŠЄ—Šž˜’ž˜’ž˜’ž˜’˜–”˜–”˜–”˜–”“’‘“’‘“’‘ЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžŸŸžŸŸžŸŸžŸŸŸЅІŸЅІŸЅІŸЅІ•КН•КН•КН•КН„нх„нх„нх„нхzяњzяњzяњzяњ{яј{яј{яј{яј…пт…пт…пт…пт–РИ–РИ–РИ–РИЃЃ•ЃЃ•ЃЃ•ЃЃ•Ї˜ˆЇ˜ˆЇ˜ˆЇ˜ˆЄ—ŠЄ—ŠЄ—ŠЄ—Šž˜’ž˜’ž˜’ž˜’˜–”˜–”˜–”˜–”“’‘“’‘“’‘ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІЂЂЂЂЂЂЂЂЂЂЂЂ            ЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™ŸЄЄŸЄЄŸЄЄŸЄЄ–ИК–ИК–ИК–ИК…кс…кс…кс…кс}ыѓ}ыѓ}ыѓ}ыѓ‚цъ‚цъ‚цъ‚цъ’ЯЦ’ЯЦ’ЯЦ’ЯЦІА™ІА™ІА™ІА™Б›}Б›}Б›}Б›}Г“vГ“vГ“vГ“vЌ“|Ќ“|Ќ“|Ќ“|Ђ”‡Ђ”‡Ђ”‡Ђ”‡œ‘‡œ‘‡œ‘‡œ‘‡”‡”‡”‡ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІЂЂЂЂЂЂЂЂЂЂЂЂ            ЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™ŸЄЄŸЄЄŸЄЄŸЄЄ–ИК–ИК–ИК–ИК…кс…кс…кс…кс}ыѓ}ыѓ}ыѓ}ыѓ‚цъ‚цъ‚цъ‚цъ’ЯЦ’ЯЦ’ЯЦ’ЯЦІА™ІА™ІА™ІА™Б›}Б›}Б›}Б›}Г“vГ“vГ“vГ“vЌ“|Ќ“|Ќ“|Ќ“|Ђ”‡Ђ”‡Ђ”‡Ђ”‡œ‘‡œ‘‡œ‘‡œ‘‡”‡”‡”‡ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІЂЂЂЂЂЂЂЂЂЂЂЂ            ЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™ŸЄЄŸЄЄŸЄЄŸЄЄ–ИК–ИК–ИК–ИК…кс…кс…кс…кс}ыѓ}ыѓ}ыѓ}ыѓ‚цъ‚цъ‚цъ‚цъ’ЯЦ’ЯЦ’ЯЦ’ЯЦІА™ІА™ІА™ІА™Б›}Б›}Б›}Б›}Г“vГ“vГ“vГ“vЌ“|Ќ“|Ќ“|Ќ“|Ђ”‡Ђ”‡Ђ”‡Ђ”‡œ‘‡œ‘‡œ‘‡œ‘‡”‡”‡”‡ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІЂЂЂЂЂЂЂЂЂЂЂЂ            ЂЂЂЂЂЂЂЂЂЂЂЂЂЁЁЂЁЁЂЁЁЂЁЁ žœ žœ žœ žœœš˜œš˜œš˜œš˜šš™šš™šš™šš™ŸЄЄŸЄЄŸЄЄŸЄЄ–ИК–ИК–ИК–ИК…кс…кс…кс…кс}ыѓ}ыѓ}ыѓ}ыѓ‚цъ‚цъ‚цъ‚цъ’ЯЦ’ЯЦ’ЯЦ’ЯЦІА™ІА™ІА™ІА™Б›}Б›}Б›}Б›}Г“vГ“vГ“vГ“vЌ“|Ќ“|Ќ“|Ќ“|Ђ”‡Ђ”‡Ђ”‡Ђ”‡œ‘‡œ‘‡œ‘‡œ‘‡”‡”‡”‡ЂЂЂЂЂЂЂЂЂЂЂЂІІІІІІІІІІІІ­­­­­­­­­­­­­­­­­­­­­­­­ЈЈЈЈЈЈЈЈЈЈЈЈІІІІІІІІІІІІЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™‹Љ™‹Љ™‹Љ™‹Ѓ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– Ÿ Ÿ Ÿ Ÿ™АА™АА™АА™АА‘ЩЩ‘ЩЩ‘ЩЩ‘ЩЩŽдбŽдбŽдбŽдб’ЬХ’ЬХ’ЬХ’ЬХ ДЄ ДЄ ДЄ ДЄЉЁЉЁЉЁЉЁЊš‰Њš‰Њš‰Њš‰Ј—‡Ј—‡Ј—‡Ј—‡Ѕ–‰Ѕ–‰Ѕ–‰Ѕ–‰Ѓ•‰Ѓ•‰Ѓ•‰Ѓ•‰Ѕ}Ѕ}Ѕ}Ѕ}Ё‹wЁ‹wЁ‹wЂЂЂЂЂЂЂЂЂЂЂЂІІІІІІІІІІІІ­­­­­­­­­­­­­­­­­­­­­­­­ЈЈЈЈЈЈЈЈЈЈЈЈІІІІІІІІІІІІЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™‹Љ™‹Љ™‹Љ™‹Ѓ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– Ÿ Ÿ Ÿ Ÿ™АА™АА™АА™АА‘ЩЩ‘ЩЩ‘ЩЩ‘ЩЩŽдбŽдбŽдбŽдб’ЬХ’ЬХ’ЬХ’ЬХ ДЄ ДЄ ДЄ ДЄЉЁЉЁЉЁЉЁЊš‰Њš‰Њš‰Њš‰Ј—‡Ј—‡Ј—‡Ј—‡Ѕ–‰Ѕ–‰Ѕ–‰Ѕ–‰Ѓ•‰Ѓ•‰Ѓ•‰Ѓ•‰Ѕ}Ѕ}Ѕ}Ѕ}Ё‹wЁ‹wЁ‹wЂЂЂЂЂЂЂЂЂЂЂЂІІІІІІІІІІІІ­­­­­­­­­­­­­­­­­­­­­­­­ЈЈЈЈЈЈЈЈЈЈЈЈІІІІІІІІІІІІЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™‹Љ™‹Љ™‹Љ™‹Ѓ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– Ÿ Ÿ Ÿ Ÿ™АА™АА™АА™АА‘ЩЩ‘ЩЩ‘ЩЩ‘ЩЩŽдбŽдбŽдбŽдб’ЬХ’ЬХ’ЬХ’ЬХ ДЄ ДЄ ДЄ ДЄЉЁЉЁЉЁЉЁЊš‰Њš‰Њš‰Њš‰Ј—‡Ј—‡Ј—‡Ј—‡Ѕ–‰Ѕ–‰Ѕ–‰Ѕ–‰Ѓ•‰Ѓ•‰Ѓ•‰Ѓ•‰Ѕ}Ѕ}Ѕ}Ѕ}Ё‹wЁ‹wЁ‹wЂЂЂЂЂЂЂЂЂЂЂЂІІІІІІІІІІІІ­­­­­­­­­­­­­­­­­­­­­­­­ЈЈЈЈЈЈЈЈЈЈЈЈІІІІІІІІІІІІЉЇЅЉЇЅЉЇЅЉЇЅЊЃœЊЃœЊЃœЊЃœЉ™‹Љ™‹Љ™‹Љ™‹Ѓ”…Ѓ”…Ѓ”…Ѓ”…›”›”›”›”š˜–š˜–š˜–š˜– Ÿ Ÿ Ÿ Ÿ™АА™АА™АА™АА‘ЩЩ‘ЩЩ‘ЩЩ‘ЩЩŽдбŽдбŽдбŽдб’ЬХ’ЬХ’ЬХ’ЬХ ДЄ ДЄ ДЄ ДЄЉЁЉЁЉЁЉЁЊš‰Њš‰Њš‰Њš‰Ј—‡Ј—‡Ј—‡Ј—‡Ѕ–‰Ѕ–‰Ѕ–‰Ѕ–‰Ѓ•‰Ѓ•‰Ѓ•‰Ѓ•‰Ѕ}Ѕ}Ѕ}Ѕ}Ё‹wЁ‹wЁ‹wŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЈЈЈЈЈЈЈЈЈЈЈЈ­­­­­­­­­­­­­­­­­­­­­­­­Ў­­Ў­­Ў­­Ў­­ВЋЅВЋЅВЋЅВЋЅЙЁŒЙЁŒЙЁŒЙЁŒП”lП”lП”lП”lКeКeКeКeЉŽvЉŽvЉŽvЉŽvž”Œž”Œž”Œž”ŒŸ›˜Ÿ›˜Ÿ›˜Ÿ›˜ЃЂ›ЃЂ›ЃЂ›ЃЂ›ЉЊ—ЉЊ—ЉЊ—ЉЊ—ЊЌ“ЊЌ“ЊЌ“ЊЌ“ЂЊ›ЂЊ›ЂЊ›ЂЊ›ЁЂ™ЁЂ™ЁЂ™ЁЂ™Ђž˜Ђž˜Ђž˜Ђž˜Ђž›Ђž›Ђž›Ђž› › › › ›Ÿœ™Ÿœ™Ÿœ™Ÿœ™Ёš”Ёš”Ёš”Ёš”Ї•…Ї•…Ї•…Ї•…ЎuЎuЎuŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЈЈЈЈЈЈЈЈЈЈЈЈ­­­­­­­­­­­­­­­­­­­­­­­­Ў­­Ў­­Ў­­Ў­­ВЋЅВЋЅВЋЅВЋЅЙЁŒЙЁŒЙЁŒЙЁŒП”lП”lП”lП”lКeКeКeКeЉŽvЉŽvЉŽvЉŽvž”Œž”Œž”Œž”ŒŸ›˜Ÿ›˜Ÿ›˜Ÿ›˜ЃЂ›ЃЂ›ЃЂ›ЃЂ›ЉЊ—ЉЊ—ЉЊ—ЉЊ—ЊЌ“ЊЌ“ЊЌ“ЊЌ“ЂЊ›ЂЊ›ЂЊ›ЂЊ›ЁЂ™ЁЂ™ЁЂ™ЁЂ™Ђž˜Ђž˜Ђž˜Ђž˜Ђž›Ђž›Ђž›Ђž› › › › ›Ÿœ™Ÿœ™Ÿœ™Ÿœ™Ёš”Ёš”Ёš”Ёš”Ї•…Ї•…Ї•…Ї•…ЎuЎuЎuŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЈЈЈЈЈЈЈЈЈЈЈЈ­­­­­­­­­­­­­­­­­­­­­­­­Ў­­Ў­­Ў­­Ў­­ВЋЅВЋЅВЋЅВЋЅЙЁŒЙЁŒЙЁŒЙЁŒП”lП”lП”lП”lКeКeКeКeЉŽvЉŽvЉŽvЉŽvž”Œž”Œž”Œž”ŒŸ›˜Ÿ›˜Ÿ›˜Ÿ›˜ЃЂ›ЃЂ›ЃЂ›ЃЂ›ЉЊ—ЉЊ—ЉЊ—ЉЊ—ЊЌ“ЊЌ“ЊЌ“ЊЌ“ЂЊ›ЂЊ›ЂЊ›ЂЊ›ЁЂ™ЁЂ™ЁЂ™ЁЂ™Ђž˜Ђž˜Ђž˜Ђž˜Ђž›Ђž›Ђž›Ђž› › › › ›Ÿœ™Ÿœ™Ÿœ™Ÿœ™Ёš”Ёš”Ёš”Ёš”Ї•…Ї•…Ї•…Ї•…ЎuЎuЎuŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЈЈЈЈЈЈЈЈЈЈЈЈ­­­­­­­­­­­­­­­­­­­­­­­­Ў­­Ў­­Ў­­Ў­­ВЋЅВЋЅВЋЅВЋЅЙЁŒЙЁŒЙЁŒЙЁŒП”lП”lП”lП”lКeКeКeКeЉŽvЉŽvЉŽvЉŽvž”Œž”Œž”Œž”ŒŸ›˜Ÿ›˜Ÿ›˜Ÿ›˜ЃЂ›ЃЂ›ЃЂ›ЃЂ›ЉЊ—ЉЊ—ЉЊ—ЉЊ—ЊЌ“ЊЌ“ЊЌ“ЊЌ“ЂЊ›ЂЊ›ЂЊ›ЂЊ›ЁЂ™ЁЂ™ЁЂ™ЁЂ™Ђž˜Ђž˜Ђž˜Ђž˜Ђž›Ђž›Ђž›Ђž› › › › ›Ÿœ™Ÿœ™Ÿœ™Ÿœ™Ёš”Ёš”Ёš”Ёš”Ї•…Ї•…Ї•…Ї•…ЎuЎuЎu››››››››››››œœœœœœœœœœœœЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊЏЏЏЏЏЏЏЏЏЏЏЏВБЏВБЏВБЏВБЏИ­ЃИ­ЃИ­ЃИ­ЃФЄ‡ФЄ‡ФЄ‡ФЄ‡Э™iЭ™iЭ™iЭ™iЬXЬXЬXЬXПŽaПŽaПŽaПŽaА’wА’wА’wА’w­—‚­—‚­—‚­—‚Д˜~Ę~Ę~Ę~Н–oН–oН–oН–oЖ”rЖ”rЖ”rЖ”rЄ˜‰Є˜‰Є˜‰Є˜‰›—›—›—›—žžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЁЁЂЁЁЂЁЁЂЁЁ ŸŸ ŸŸ ŸŸ ŸŸ ž ž ž žЂœ–Ђœ–Ђœ–Ђœ–Ї™ŒЇ™ŒЇ™Œ››››››››››››œœœœœœœœœœœœЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊЏЏЏЏЏЏЏЏЏЏЏЏВБЏВБЏВБЏВБЏИ­ЃИ­ЃИ­ЃИ­ЃФЄ‡ФЄ‡ФЄ‡ФЄ‡Э™iЭ™iЭ™iЭ™iЬXЬXЬXЬXПŽaПŽaПŽaПŽaА’wА’wА’wА’w­—‚­—‚­—‚­—‚Д˜~Ę~Ę~Ę~Н–oН–oН–oН–oЖ”rЖ”rЖ”rЖ”rЄ˜‰Є˜‰Є˜‰Є˜‰›—›—›—›—žžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЁЁЂЁЁЂЁЁЂЁЁ ŸŸ ŸŸ ŸŸ ŸŸ ž ž ž žЂœ–Ђœ–Ђœ–Ђœ–Ї™ŒЇ™ŒЇ™Œ››››››››››››œœœœœœœœœœœœЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊЏЏЏЏЏЏЏЏЏЏЏЏВБЏВБЏВБЏВБЏИ­ЃИ­ЃИ­ЃИ­ЃФЄ‡ФЄ‡ФЄ‡ФЄ‡Э™iЭ™iЭ™iЭ™iЬXЬXЬXЬXПŽaПŽaПŽaПŽaА’wА’wА’wА’w­—‚­—‚­—‚­—‚Д˜~Ę~Ę~Ę~Н–oН–oН–oН–oЖ”rЖ”rЖ”rЖ”rЄ˜‰Є˜‰Є˜‰Є˜‰›—›—›—›—žžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЁЁЂЁЁЂЁЁЂЁЁ ŸŸ ŸŸ ŸŸ ŸŸ ž ž ž žЂœ–Ђœ–Ђœ–Ђœ–Ї™ŒЇ™ŒЇ™Œ››››››››››››œœœœœœœœœœœœЂЂЂЂЂЂЂЂЂЂЂЂЊЊЊЊЊЊЊЊЊЊЊЊЏЏЏЏЏЏЏЏЏЏЏЏВБЏВБЏВБЏВБЏИ­ЃИ­ЃИ­ЃИ­ЃФЄ‡ФЄ‡ФЄ‡ФЄ‡Э™iЭ™iЭ™iЭ™iЬXЬXЬXЬXПŽaПŽaПŽaПŽaА’wА’wА’wА’w­—‚­—‚­—‚­—‚Д˜~Ę~Ę~Ę~Н–oН–oН–oН–oЖ”rЖ”rЖ”rЖ”rЄ˜‰Є˜‰Є˜‰Є˜‰›—›—›—›—žžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЁЁЂЁЁЂЁЁЂЁЁ ŸŸ ŸŸ ŸŸ ŸŸ ž ž ž žЂœ–Ђœ–Ђœ–Ђœ–Ї™ŒЇ™ŒЇ™Œ™™™™™™™™™™™™————————————ЅЅЅЅЅЅЅЅЅЅЅЅЊЊЊЊЊЊЊЊЊЊЊЊЎ­ЌЎ­ЌЎ­ЌЎ­ЌДЏЉДЏЉДЏЉДЏЉУГЄУГЄУГЄУГЄбГ–бГ–бГ–бГ–гЅzгЅzгЅzгЅzЮœoЮœoЮœoЮœoЧwЧwЧwЧwЧ ~Ч ~Ч ~Ч ~ЭЃ~ЭЃ~ЭЃ~ЭЃ~ШŸzШŸzШŸzШŸzЏ–€Џ–€Џ–€Џ–€›”›”›”›”˜––˜––˜––˜––››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸžŸŸžŸŸžŸŸžžœžœžœžœžœšžœšžœš™™™™™™™™™™™™————————————ЅЅЅЅЅЅЅЅЅЅЅЅЊЊЊЊЊЊЊЊЊЊЊЊЎ­ЌЎ­ЌЎ­ЌЎ­ЌДЏЉДЏЉДЏЉДЏЉУГЄУГЄУГЄУГЄбГ–бГ–бГ–бГ–гЅzгЅzгЅzгЅzЮœoЮœoЮœoЮœoЧwЧwЧwЧwЧ ~Ч ~Ч ~Ч ~ЭЃ~ЭЃ~ЭЃ~ЭЃ~ШŸzШŸzШŸzШŸzЏ–€Џ–€Џ–€Џ–€›”›”›”›”˜––˜––˜––˜––››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸžŸŸžŸŸžŸŸžžœžœžœžœžœšžœšžœš™™™™™™™™™™™™————————————ЅЅЅЅЅЅЅЅЅЅЅЅЊЊЊЊЊЊЊЊЊЊЊЊЎ­ЌЎ­ЌЎ­ЌЎ­ЌДЏЉДЏЉДЏЉДЏЉУГЄУГЄУГЄУГЄбГ–бГ–бГ–бГ–гЅzгЅzгЅzгЅzЮœoЮœoЮœoЮœoЧwЧwЧwЧwЧ ~Ч ~Ч ~Ч ~ЭЃ~ЭЃ~ЭЃ~ЭЃ~ШŸzШŸzШŸzШŸzЏ–€Џ–€Џ–€Џ–€›”›”›”›”˜––˜––˜––˜––››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸžŸŸžŸŸžŸŸžžœžœžœžœžœšžœšžœš™™™™™™™™™™™™————————————ЅЅЅЅЅЅЅЅЅЅЅЅЊЊЊЊЊЊЊЊЊЊЊЊЎ­ЌЎ­ЌЎ­ЌЎ­ЌДЏЉДЏЉДЏЉДЏЉУГЄУГЄУГЄУГЄбГ–бГ–бГ–бГ–гЅzгЅzгЅzгЅzЮœoЮœoЮœoЮœoЧwЧwЧwЧwЧ ~Ч ~Ч ~Ч ~ЭЃ~ЭЃ~ЭЃ~ЭЃ~ШŸzШŸzШŸzШŸzЏ–€Џ–€Џ–€Џ–€›”›”›”›”˜––˜––˜––˜––››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸžŸŸžŸŸžŸŸžžœžœžœžœžœšžœšžœš˜˜˜˜˜˜˜˜˜˜˜˜““““““““““““˜˜˜˜˜˜˜˜˜˜˜˜žžžžžžžžžžžžЂЂЂЂЂЂЂЂЂЂЂЂЅЄЄЅЄЄЅЄЄЅЄЄЎЌЋЎЌЋЎЌЋЎЌЋЦСМЦСМЦСМЦСМлаХлаХлаХлаХнЩЖнЩЖнЩЖнЩЖйСЋйСЋйСЋйСЋиПЉиПЉиПЉиПЉкОЅкОЅкОЅкОЅлЛŸлЛŸлЛŸлЛŸШБžШБžШБžШБžЇž–Їž–Їž–Їž––”’–”’–”’–”’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœ›››››››››˜˜˜˜˜˜˜˜˜˜˜˜““““““““““““˜˜˜˜˜˜˜˜˜˜˜˜žžžžžžžžžžžžЂЂЂЂЂЂЂЂЂЂЂЂЅЄЄЅЄЄЅЄЄЅЄЄЎЌЋЎЌЋЎЌЋЎЌЋЦСМЦСМЦСМЦСМлаХлаХлаХлаХнЩЖнЩЖнЩЖнЩЖйСЋйСЋйСЋйСЋиПЉиПЉиПЉиПЉкОЅкОЅкОЅкОЅлЛŸлЛŸлЛŸлЛŸШБžШБžШБžШБžЇž–Їž–Їž–Їž––”’–”’–”’–”’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœ›››››››››˜˜˜˜˜˜˜˜˜˜˜˜““““““““““““˜˜˜˜˜˜˜˜˜˜˜˜žžžžžžžžžžžžЂЂЂЂЂЂЂЂЂЂЂЂЅЄЄЅЄЄЅЄЄЅЄЄЎЌЋЎЌЋЎЌЋЎЌЋЦСМЦСМЦСМЦСМлаХлаХлаХлаХнЩЖнЩЖнЩЖнЩЖйСЋйСЋйСЋйСЋиПЉиПЉиПЉиПЉкОЅкОЅкОЅкОЅлЛŸлЛŸлЛŸлЛŸШБžШБžШБžШБžЇž–Їž–Їž–Їž––”’–”’–”’–”’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœ›››››››››˜˜˜˜˜˜˜˜˜˜˜˜““““““““““““˜˜˜˜˜˜˜˜˜˜˜˜žžžžžžžžžžžžЂЂЂЂЂЂЂЂЂЂЂЂЅЄЄЅЄЄЅЄЄЅЄЄЎЌЋЎЌЋЎЌЋЎЌЋЦСМЦСМЦСМЦСМлаХлаХлаХлаХнЩЖнЩЖнЩЖнЩЖйСЋйСЋйСЋйСЋиПЉиПЉиПЉиПЉкОЅкОЅкОЅкОЅлЛŸлЛŸлЛŸлЛŸШБžШБžШБžШБžЇž–Їž–Їž–Їž––”’–”’–”’–”’••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœ›››››››››’’’’’’’’’’’’““““““““““““™™™™™™™™™™™™ššššššššššššžœšžœšžœšžœšЎІŸЎІŸЎІŸЎІŸЯНЌЯНЌЯНЌЯНЌхЭЗхЭЗхЭЗхЭЗчЭЕчЭЕчЭЕчЭЕхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎсОžсОžсОžсОžвЎŒвЎŒвЎŒвЎŒЕЃ“ЕЃ“ЕЃ“ЕЃ“™–™–™–™–’’’’’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜’’’’’’’’’’’’““““““““““““™™™™™™™™™™™™ššššššššššššžœšžœšžœšžœšЎІŸЎІŸЎІŸЎІŸЯНЌЯНЌЯНЌЯНЌхЭЗхЭЗхЭЗхЭЗчЭЕчЭЕчЭЕчЭЕхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎсОžсОžсОžсОžвЎŒвЎŒвЎŒвЎŒЕЃ“ЕЃ“ЕЃ“ЕЃ“™–™–™–™–’’’’’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜’’’’’’’’’’’’““““““““““““™™™™™™™™™™™™ššššššššššššžœšžœšžœšžœšЎІŸЎІŸЎІŸЎІŸЯНЌЯНЌЯНЌЯНЌхЭЗхЭЗхЭЗхЭЗчЭЕчЭЕчЭЕчЭЕхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎсОžсОžсОžсОžвЎŒвЎŒвЎŒвЎŒЕЃ“ЕЃ“ЕЃ“ЕЃ“™–™–™–™–’’’’’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜’’’’’’’’’’’’““““““““““““™™™™™™™™™™™™ššššššššššššžœšžœšžœšžœšЎІŸЎІŸЎІŸЎІŸЯНЌЯНЌЯНЌЯНЌхЭЗхЭЗхЭЗхЭЗчЭЕчЭЕчЭЕчЭЕхЪБхЪБхЪБхЪБфШЎфШЎфШЎфШЎсОžсОžсОžсОžвЎŒвЎŒвЎŒвЎŒЕЃ“ЕЃ“ЕЃ“ЕЃ“™–™–™–™–’’’’’’’’’’’’‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜††††††††††††………………………………————————————˜—–˜—–˜—–˜—–Ÿ—Ÿ—Ÿ—Ÿ—Г˜~Ø~Ø~Ø~ЯpЯpЯpЯpоЂkоЂkоЂkоЂkрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhкš`кš`кš`кš`Ц_Ц_Ц_Ц_ЄŽzЄŽzЄŽzЄŽz””””ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘“““““““““““““““““““““††††††††††††………………………………————————————˜—–˜—–˜—–˜—–Ÿ—Ÿ—Ÿ—Ÿ—Г˜~Ø~Ø~Ø~ЯpЯpЯpЯpоЂkоЂkоЂkоЂkрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhкš`кš`кš`кš`Ц_Ц_Ц_Ц_ЄŽzЄŽzЄŽzЄŽz””””ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘“““““““““““““““““““““††††††††††††………………………………————————————˜—–˜—–˜—–˜—–Ÿ—Ÿ—Ÿ—Ÿ—Г˜~Ø~Ø~Ø~ЯpЯpЯpЯpоЂkоЂkоЂkоЂkрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhкš`кš`кš`кš`Ц_Ц_Ц_Ц_ЄŽzЄŽzЄŽzЄŽz””””ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘“““““““““““““““““““““††††††††††††………………………………————————————˜—–˜—–˜—–˜—–Ÿ—Ÿ—Ÿ—Ÿ—Г˜~Ø~Ø~Ø~ЯpЯpЯpЯpоЂkоЂkоЂkоЂkрЃjрЃjрЃjрЃjрЂjрЂjрЂjрЂjпЁhпЁhпЁhпЁhкš`кš`кš`кš`Ц_Ц_Ц_Ц_ЄŽzЄŽzЄŽzЄŽz””””ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘“““““““““““““““““““““~~~~~~~~~~~~€€€€€€€€€€€€˜˜˜˜˜˜˜˜˜˜˜˜™—”™—”™—”™—”І”ƒІ”ƒІ”ƒІ”ƒОŒ_ОŒ_ОŒ_ОŒ_б‡Dб‡Dб‡Dб‡Dз†<з†<з†<з†<и†<и†<и†<и†<и†;и†;и†;и†;з†;з†;з†;з†;д„<д„<д„<д„<ПƒLПƒLПƒLПƒLœ„oœ„oœ„oœ„oŠ‡Š‡Š‡Š‡ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽ~~~~~~~~~~~~€€€€€€€€€€€€˜˜˜˜˜˜˜˜˜˜˜˜™—”™—”™—”™—”І”ƒІ”ƒІ”ƒІ”ƒОŒ_ОŒ_ОŒ_ОŒ_б‡Dб‡Dб‡Dб‡Dз†<з†<з†<з†<и†<и†<и†<и†<и†;и†;и†;и†;з†;з†;з†;з†;д„<д„<д„<д„<ПƒLПƒLПƒLПƒLœ„oœ„oœ„oœ„oŠ‡Š‡Š‡Š‡ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽ~~~~~~~~~~~~€€€€€€€€€€€€˜˜˜˜˜˜˜˜˜˜˜˜™—”™—”™—”™—”І”ƒІ”ƒІ”ƒІ”ƒОŒ_ОŒ_ОŒ_ОŒ_б‡Dб‡Dб‡Dб‡Dз†<з†<з†<з†<и†<и†<и†<и†<и†;и†;и†;и†;з†;з†;з†;з†;д„<д„<д„<д„<ПƒLПƒLПƒLПƒLœ„oœ„oœ„oœ„oŠ‡Š‡Š‡Š‡ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽ~~~~~~~~~~~~€€€€€€€€€€€€˜˜˜˜˜˜˜˜˜˜˜˜™—”™—”™—”™—”І”ƒІ”ƒІ”ƒІ”ƒОŒ_ОŒ_ОŒ_ОŒ_б‡Dб‡Dб‡Dб‡Dз†<з†<з†<з†<и†<и†<и†<и†<и†;и†;и†;и†;з†;з†;з†;з†;д„<д„<д„<д„<ПƒLПƒLПƒLПƒLœ„oœ„oœ„oœ„oŠ‡Š‡Š‡Š‡ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmsssssssssssssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiioooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnooooooooouuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvv„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽ››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}žžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠžžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””vvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||ЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmsssssssssssssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiioooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnooooooooouuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvv„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽ››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}žžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠžžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””vvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||ЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџkkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmssssssssskkkkkkkkkkkkyyyyyyyyyyyyŽŽŽŽŽŽŽŽŽŽŽŽ————————————••••••••••••””””””””””””˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••’’’’’’’’’’’’””””””””””””————————————˜˜˜˜˜˜˜˜˜˜˜˜————————————””””””””””””„„„„„„„„„„„„}}}}}}}}}}}}{{{{{{{{{{{{wwwwwwwwwwwwnnnnnnnnnnnnkkkkkkkkkkkkmmmmmmmmmmmmsssssssssssssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiiooooooooossssssssssss€€€€€€€€€€€€••••••••••••’’’’’’’’’’’’‹‹‹‹‹‹‹‹‹‹‹‹‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚zzzzzzzzzzzzuuuuuuuuuuuupppppppppppphhhhhhhhhhhhffffffffffffiiiiiiiiiiiioooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnoooooooooyyyyyyyyyyyy††††††††††††‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““””””””””””””””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽŽŽŽˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€yyyyyyyyyyyyssssssssssssoooooooooooonnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnnooooooooouuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu‚‚‚‚‚‚‚‚‚‚‚‚‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒŠŠŠŠŠŠŠŠŠŠŠŠ‹‹‹‹‹‹‹‹‹‹‹‹““““““““““““ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ————————————‘‘‘‘‘‘‘‘‘‘‘‘‰‰‰‰‰‰‰‰‰‰‰‰{{{{{{{{{{{{yyyyyyyyyyyy}}}}}}}}}}}}zzzzzzzzzzzzrrrrrrrrruuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvvuuuuuuuuuuuu„„„„„„„„„„„„………………………………ŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’žžžžžžžžžžžž­­­­­­­­­­­­ГГГГГГГГГГГГ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊІІІІІІІІІІІІ            ””””””””””””‡‡‡‡‡‡‡‡‡‡‡‡}}}}}}}}}}}}zzzzzzzzzzzz€€€€€€€€€€€€„„„„„„„„„„„„~~~~~~~~~~~~vvvvvvvvv„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwww„„„„„„„„„„„„ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ††††††††††††––––––––––––————————————šš™šš™šš™šš™ЃЂЂЃЂЂЃЂЂЃЂЂЏЏЎЏЏЎЏЏЎЏЏЎЕЕДЕЕДЕЕДЕЕДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЋЋЋЋЋЋЋЋЋЋЋЋЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ€€€€€€€€€€€€wwwwwwwwwwwwvvvvvvvvvvvvzzzzzzzzzzzz{{{{{{{{{{{{xxxxxxxxxxxxwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwšššššššššššš™™™™™™™™™™™™••••••••••••ššššššššššššžžžžžžžžžžžžŸŸžŸŸžŸŸžŸŸžЄ Є Є Є ЏЈЁЏЈЁЏЈЁЏЈЁВЎЋВЎЋВЎЋВЎЋЏЎЎЏЎЎЏЎЎЏЎЎЎЎЎЎЎЎЎЎЎЎЎЎЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄ{{{{{{{{{{{{‚‚‚‚‚‚‚‚‚‚‚‚}}}}}}}}}}}}vvvvvvvvvvvvwwwwwwwwwЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxЇЇЇЇЇЇЇЇЇЇЇЇЋЋЋЋЋЋЋЋЋЋЋЋЊЊЊЊЊЊЊЊЊЊЊЊЇЇЇЇЇЇЇЇЇЇЇЇЅЅЅЅЅЅЅЅЅЅЅЅЃЃЃЃЃЃЃЃЃЃЃЃЂЂЂЂЂЂЂЂЂЂЂЂІЅЄІЅЄІЅЄІЅЄ­І ­І ­І ­І ЖЉЖЉЖЉЖЉД­ІД­ІД­ІД­ІЏЎ­ЏЎ­ЏЎ­ЏЎ­ЏЏЏЏЏЏЏЏЏЏЏЏ­­­­­­­­­­­­ЉЉЉЉЉЉЉЉЉЉЉЉЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ’’’’’’’’’’’’ƒƒƒƒƒƒƒƒƒƒƒƒ‡‡‡‡‡‡‡‡‡‡‡‡………………………………zzzzzzzzzzzzxxxxxxxxxААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЇІІЇІІЇІІЇІІЏЌЈЏЌЈЏЌЈЏЌЈЕЎЈЕЎЈЕЎЈЕЎЈГАЌГАЌГАЌГАЌББАББАББАББАГГГГГГГГГГГГВВВВВВВВВВВВ­­­­­­­­­­­­ЇЇЇЇЇЇЇЇЇЇЇЇŸŸŸŸŸŸŸŸŸŸŸŸ““““““““““““„„„„„„„„„„„„‰‰‰‰‰‰‰‰‰‰‰‰‹‹‹‹‹‹‹‹‹‹‹‹„„„„„„„„„„„„ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂœœœœœœœœœœœœœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁЉЉЈЉЉЈЉЉЈЉЉЈЏЎ­ЏЎ­ЏЎ­ЏЎ­ББАББАББАББАГГГГГГГГГГГГГГГГГГГГГГГГББББББББББББЊЊЊЊЊЊЊЊЊЊЊЊЂЂЂЂЂЂЂЂЂЂЂЂ››››››››››››••••••••••••‹‹‹‹‹‹‹‹‹‹‹‹ˆˆˆˆˆˆˆˆˆˆˆˆŽŽŽŽŽŽŽŽŽŽŽŽ””””””””””””••••••••••••’’’’’’’’’’’’ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ДДДДДДДДДДДДВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉЁЁЁЁЁЁЁЁЁЁЁЁ››››››››››››››››››››››››žžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЌЌЌЌЌЌЌЌЌЌЌЌААААААААААААВВВВВВВВВВВВВВВВВВВВВВВВЏЏЏЏЏЏЏЏЏЏЏЏЉЉЉЉЉЉЉЉЉЉЉЉ            ››››››››››››™™™™™™™™™™™™––––––––––––––––––––––––™™™™™™™™™™™™œœœœœœœœœœœœ™™™™™™™™™™™™•••••••••ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЎЎЎЎЎЎЎЎЎЎЎЎ­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœЁЁЁЁЁЁЁЁЁЁЁЁІІІІІІІІІІІІЊЊЊЊЊЊЊЊЊЊЊЊ­­­­­­­­­­­­­­­­­­­­­­­­ЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЄЄЄЄЄЄЄЄЄЄЄЄŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜”””””””””ЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЄЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЂЂЂЂЂЂЂЂЂЂЂЂЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЅЅЅЅЅЅЅЅЅЅЅЅЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ™™™™™™™™™™™™””””””””””””’’’’’’’’’’’’ŽŽŽŽŽŽŽŽŽ››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………››››››››››››››››››››››››œœœœœœœœœœœœžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸ                        žžžžžžžžžžžž››››››››››››››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››˜˜˜˜˜˜˜˜˜˜˜˜ŠŠŠŠŠŠŠŠŠŠŠŠˆˆˆˆˆˆˆˆˆˆˆˆ………………………šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}šššššššššššš™™™™™™™™™™™™››››››››››››œœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂЁЁЁЁЁЁЁЁЁЁЁЁžžžžžžžžžžžž››››››››››››šššššššššššš››››››››››››œœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            žžžžžžžžžžžž————————————‡‡‡‡‡‡‡‡‡‡‡‡~~~~~~~~~~~~}}}}}}}}}žžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœœœœœœœœœœœœœžžžžžžžžžžžž            ““““““““““““ˆˆˆˆˆˆˆˆˆˆˆˆ€€€€€€€€€€€€||||||||||||{{{{{{{{{{{{zzzzzzzzzЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸЃЃЃЃЃЃЃЃЃЃЃЃІІІІІІІІІІІІЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЁЁЁЁЁЁЁЁЁЁЁЁ            ЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››ƒƒƒƒƒƒƒƒƒƒƒƒ{{{{{{{{{{{{xxxxxxxxxxxxzzzzzzzzzzzz~~~~~~~~~ЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠЃЃЃЃЃЃЃЃЃЃЃЃ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžž            ЄЄЄЄЄЄЄЄЄЄЄЄЇЇЇЇЇЇЇЇЇЇЇЇЈЈЈЈЈЈЈЈЈЈЈЈЇЇЇЇЇЇЇЇЇЇЇЇЄЄЄЄЄЄЄЄЄЄЄЄЃЃЃЃЃЃЃЃЃЃЃЃЁЁЁЁЁЁЁЁЁЁЁЁŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››››››››››››››œœœœœœœœœœœœ˜˜˜˜˜˜˜˜˜˜˜˜ƒƒƒƒƒƒƒƒƒƒƒƒzzzzzzzzzzzzyyyyyyyyyyyyŠŠŠŠŠŠŠŠŠžžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””žžžžžžžžžžžžœœœœœœœœœœœœ››››››››››››šššššššššššš››››››››››››ŸŸŸŸŸŸŸŸŸŸŸŸЄЄЄЄЄЄЄЄЄЄЄЄЉЉЉЉЉЉЉЉЉЉЉЉЌЌЌЌЌЌЌЌЌЌЌЌЉЉЉЉЉЉЉЉЉЉЉЉЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžœœœœœœœœœœœœšššššššššššš••••••••••••ŒŒŒŒŒŒŒŒŒŒŒŒ„„„„„„„„„„„„„„„„„„„„„„„„ŒŒŒŒŒŒŒŒŒŒŒŒ”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””““““““““““““————————————ššššššššššššžžžžžžžžžžžžЅЅЅЅЅЅЅЅЅЅЅЅЈЈЈЈЈЈЈЈЈЈЈЈЅЅЅЅЅЅЅЅЅЅЅЅžžžžžžžžžžžž››››››››››››žžžžžžžžžžžžЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžšššššššššššš••••••••••••‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘”””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””{{{{{{{{{{{{€€€€€€€€€€€€‚‚‚‚‚‚‚‚‚‚‚‚ƒƒƒƒƒƒƒƒƒƒƒƒŠŠŠŠŠŠŠŠŠŠŠŠ““““““““““““••••••••••••ššššššššššššžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸ››››››››››››————————————————————————››››››››››››ЁЁЁЁЁЁЁЁЁЁЁЁЂЂЂЂЂЂЂЂЂЂЂЂ            ŸŸŸŸŸŸŸŸŸŸŸŸžžžžžžžžžžžžžžžžžžžžžžžžŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœ””””””””””””vvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆvvvvvvvvvvvv{{{{{{{{{{{{}}}}}}}}}}}}~~~~~~~~~~~~ˆˆˆˆˆˆˆˆˆˆˆˆ‘‘‘‘‘‘‘‘‘‘‘‘’’’’’’’’’’’’––––––––––––™™™™™™™™™™™™™™™™™™™™™™™™••••••••••••““““““““““““••••••••••••ššššššššššššŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸŸœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœœšššššššššššš““““““““““““ŒŒŒŒŒŒŒŒŒŒŒŒˆˆˆˆˆˆˆˆˆ‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡‡{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ‹‹‹‹‹‹‹‹‹‹‹‹ŒŒŒŒŒŒŒŒŒŒŒŒ““““““““““““————————————––––––––––––””””””””””””‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘‘••••••••••••™™™™™™™™™™™™˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••––––––––––––˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜˜••••••••••••‡‡‡‡‡‡‡‡‡‡‡‡            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||            ™™™™™™™™™™™™ˆˆˆˆˆˆˆˆˆˆˆˆ{{{{{{{{{{{{ƒƒƒƒƒƒƒƒƒƒƒƒ………………………………————————————••••••••••••““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽŽ‘‘‘‘‘‘‘‘‘‘‘‘““““““““““““““““““““““““’’’’’’’’’’’’ŠŠŠŠŠŠŠŠŠŠŠŠ‚‚‚‚‚‚‚‚‚‚‚‚|||||||||ЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyyЏЏЏЏЏЏЏЏЏЏЏЏЃЃЃЃЃЃЃЃЃЃЃЃŒŒŒŒŒŒŒŒŒŒŒŒ€€€€€€€€€€€€————————————““““““““““““ŽŽŽŽŽŽŽŽŽŽŽŽ‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰‰ˆˆˆˆˆˆˆˆˆˆˆˆ‰‰‰‰‰‰‰‰‰‰‰‰ŒŒŒŒŒŒŒŒŒŒŒŒŽŽŽŽŽŽŽŽŽŽŽŽŒŒŒŒŒŒŒŒŒŒŒŒ‹‹‹‹‹‹‹‹‹‹‹‹ŠŠŠŠŠŠŠŠŠŠŠŠ††††††††††††yyyyyyyyygravitation-3+dfsg1.orig/game5/gameSource/graphics/prize.tga0000644000175000017500000000530510760571177022674 0ustar pabspabs Sџџџџоо›оо›оо›оо›оо›оо›оо›џџџџџџоо›џџџџџџџџџыыЄџџџџџџџџВыыЄџџоо›џџџџџџџџџџџџџџџџџџџџВџџџџџџџџВоо›џџџџџџыыЄџџџџџџџџВџџџџџџџџйџџВоо›џџџыыЄџџџџџџџџВџџџџџџџџџџџџџџВоо›ыыЄџџџџџџџџџџџџџџџџџџџџџџџџџџВоо›џџџџџџџџџџџџџџџџџйџџџџџџџџэџџВоо›џџџџџВџџџџџџџџйџџџџџџџџэџџџџџВоо›џџџџџџџџџџџйџџџџџџџџэџџџџџџџџВџџџџВџџџџџйџџџџџџџџџџџџџџџџџВџџџџџџџџВџџВџџВџџВџџВџџВџџВџџџџџџџџџџџџџџџџџџџТЗmоо›оо›ююЭooNююЭТЗmџџџџџџрлЖџєйьцйьцйѕѕбmgZmgZџєОЫРsџџююЭmgZ€xc€xc€zmmgZ€zm€xH€xcьцйџџВююЭ€€€mgZvsM€zm€}v€zR€zmmgZ€€mџџиююЭ€€€f`:€zm€}v€}Y€}v€zmmgZџџџџџВоо›хпЙџїтџљьџќѕџќѕ€}v€zmџїтйЮГџџВТЗmџщГџяЦџєйџєйџќѕ€z_џљьџяЦџщІйЮ}оо›йЮГйЮ}йЮГџєйџєОџљьйЮГйЮІйЮГџџВоо›џџџџџџџџџйޘџяЦйЮГџџэџџџџџџџџВџџџџВџџџџџййЮГџщГйЮГџџџџџџџџВџџџџџџџџВџџВџџВйЮ}џџВџџВџџВџџџџџџџџџџџџџџџџџџџТЗmоо›оо›оо›оо›оо›ТЗmџџџџџџТЗmџщГйЮГйЮГыыЄйЮГйЮГџщ}ЫРsџџоо›йЮГџяЦџяЦџєййЮГџєйџяџяЦйЮГџџВоо›џџџйЮГыц™џєйџљьџєЃџєййЮГџџйџџВоо›џџџЫРsџєйџљьџљВџљьџєййЮГџџџџџВоо›ЫРsџяЦџєйџљьџљьџљьџєйџяЦйЮГџџВТЗmџщГџяЦџєйџєйџљьџєОџєйџяЦџщІйЮ}оо›йЮГйЮ}йЮГџєйџєОџєййЮГйЮІйЮГџџВоо›џџџџџџџџџйޘџяЦйЮГџџэџџџџџџџџВџџџџВџџџџџййЮГџщГйЮГџџџџџџџџВџџџџџџџџВџџВџџВйЮ}џџВџџВџџВџџџџџџџџџџџџџџџџџџџТЗmоо›оо›оо›оо›оо›ТЗmџџџџџџТЗmџщГйЮГйЮГыыЄйЮГйЮГџщ}ЫРsџџоо›йЮГџяЦџяЦџєййЮГџєйџяџяЦйЮГџџВоо›џџџйЮГыц™џєйџљьџєЃџєййЮГџџйџџВоо›џџџЫРsџєйџљьџљВџљьџєййЮГџџџџџВоо›ЫРsџяЦџєйџљьџљьџљьџєйџяЦйЮГџџВТЗmџщГџяЦџєйџєйџљьџєОџєйџяЦџщІйЮ}оо›йЮГйЮ}йЮГџєйџєОџєййЮГйЮІ€[џџоо›џџџџџџџџџйޘџШ@€[џџџџџџџџџџџџВџџџџџй€[џЖ€[џџџџџџџџџџџџџџџџџџ€[џџџџџџџџџџџџџџџџџџџџџџџџџТЗmоо›оо›оо›оо›оо›ТЗmџџџџџџТЗmџщГйЮГйЮГыыЄйЮГйЮГџщ}ЫРsџџоо›йЮГџяЦџяЦџєййЮГџєйџяџяЦйЮГџџоо›џџџйЮГыц™џєйџљьџєЃџєй€[џџџџоо›џџџЫРsџк€џьПџьПџьПџк€€[џџџџоо›ЫРsџяЦџк€џьПџьПџьПџк€џШ@€[џџ€[џЖџШ@џк€џк€џьПџк€џк€џШ@џЖ€[џџ€[€[€[џк€џк€џк€€[€[€[џџџџџџџџџџ€[џШ@€[џџџџџџџџџџџџџџџџ€[џЖ€[џџџџџџџџџџџџџџџџџџ€[џџџџџџџџџџџџџџџџџџџџџџџџџТЗmоо›оо›оо›оо›оо›ТЗmџџџџџџТЗmџщГйЮГйЮГыыЄ€[€[џщ}ЫРsџџџџ€[џШ@џШ@џк€йЮГџк€џШ@џШ@€[џџџџџџ€[џк€џк€џьПџк€џк€€[џџџџџџџџ€[џк€џьПџьПџьПџк€€[џџџџџџ€[џШ@џк€џьПџьПџьПџк€џШ@€[џџ€[џЖџШ@џк€џк€џьПџк€џк€џШ@џЖ€[џџ€[€[€[џк€џк€џк€€[€[€[џџџџџџџџџџ€[џШ@€[џџџџџџџџџџџџџџџџ€[џЖ€[џџџџџџџџџџџџџџџџџџ€[џџџџџџџџџџџџџџџџџџџџџџџџџ€[џџџџџџџџџџ€[џџџџџџ€[џЖ€[€[џџ€[€[џЖ€[џџџџ€[џШ@џШ@џк€€[џк€џШ@џШ@€[џџџџџџ€[џк€џк€џьПџк€џк€€[џџџџџџџџ€[џк€џьПџьПџьПџк€€[џџџџџџ€[џШ@џк€џьПџьПџьПџк€џШ@€[џџ€[џЖџШ@џк€џк€џьПџк€џк€џШ@џЖ€[џџ€[€[€[џк€џк€џк€€[€[€[џџџџџџџџџџ€[џШ@€[џџџџџџџџџџџџџџџџ€[џЖ€[џџџџџџџџџџџџџџџџџџ€[џџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/numeralsBlack.tga0000644000175000017500000000071310750237627024322 0ustar pabspabs1џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/kilnAshPit.tga0000644000175000017500000000510110760405311023565 0ustar pabspabsO лл9VImЖFh­ImЖImЖNtТImЖImЖFh­ImЖ„Яллџлл9VImЖFh­ImЖImЖNtТImЖImЖFh­ImЖ„Яллџлл9VImЖFh­ImЖImЖNtТImЖImЖFh­ImЖ„Яллџлл9VImЖFh­ImЖImЖNtТImЖImЖFh­ImЖ„Яллџлл9VImЖFh­ImЖImЖNtТImЖImЖFh­ImЖ„Яллл?_žNtТFh­„ЯrТ„ЯrТrТ„Я„ЯImЖImЖrТлџл?_žNtТFh­„ЯrТ„ЯrТrТ„Я„ЯImЖImЖrТлџл?_žNtТFh­„ЯrТ„ЯrТrТ„Я„ЯImЖImЖrТлџл?_žNtТFh­„ЯrТ„ЯrТrТ„Я„ЯImЖImЖrТлџл?_žNtТFh­„ЯrТ„ЯrТrТ„Я„ЯImЖImЖrТл9VImЖImЖ„ЯлллЖЖЖЖЖЖлллЖЖЖ?_žImЖImЖrТџ9VImЖImЖ„Я’’’лллЖЖЖЖЖЖлллЖЖЖ’’’?_žImЖImЖrТџ9VImЖImЖ„Я’’’лллЖЖЖЖЖЖлллЖЖЖ’’’?_žImЖImЖrТџ9VImЖImЖ„Я’’’лллЖЖЖЖЖЖлллЖЖЖ’’’?_žImЖImЖrТџ9VImЖImЖ„Я’’’лллЖЖЖЖЖЖлллЖЖЖ’’’?_žImЖImЖrТ?_žImЖ„Я9VImЖ„Яџ?_žImЖ„ЯЖЖЖлллллл’’’ллл9VImЖ„Яџ?_žImЖ„ЯлллЖЖЖЖЖЖлллллл’’’лллЖЖЖллл9VImЖ„Яџ?_žImЖ„ЯлллЖЖЖЖЖЖлллллл’’’лллЖЖЖллл9VImЖ„Яџ?_žImЖ„ЯлллЖЖЖЖЖЖлллллл’’’лллЖЖЖллл9VImЖ„Я9VImЖrТ?_žImЖrТџ9VImЖrТ?_žImЖrТџ9VImЖrТ’’’лллЖЖЖЖЖЖлллЖЖЖллл?_žImЖrТџ9VImЖrТЖЖЖ’’’лллЖЖЖЖЖЖлллЖЖЖлллЖЖЖ?_žImЖrТџ9VImЖrТЖЖЖ’’’лллЖЖЖЖЖЖлллЖЖЖлллЖЖЖ?_žImЖrТ?_žImЖrТ9VImЖ„Яџ?_žImЖrТ9VImЖ„Яџ?_žImЖrТ9VImЖ„Яџ?_žImЖrТллл’’’ллл’’’ллл9VImЖ„Яџ?_žImЖrТ’’’лллллл’’’ллл’’’лллллл’’’9VImЖ„Я?_žImЖImЖrТ9VImЖImЖ„Яџ?_žImЖImЖrТ9VImЖImЖ„Яџ?_žImЖImЖrТ9VImЖImЖ„Яџ?_žImЖImЖrТ9VImЖImЖ„Яџ?_žImЖImЖrТ’’’лллЖЖЖлллЖЖЖ9VImЖImЖ„Я9VImЖImЖ„Я?_žImЖImЖrТџ9VImЖImЖ„Я?_žImЖImЖrТџ9VImЖImЖ„Я?_žImЖImЖrТџ9VImЖImЖ„Я?_žImЖImЖrТџ9VImЖImЖ„Я?_žImЖImЖrТл9VImЖImЖrТ9VImЖFh­rТлџл9VImЖImЖrТ9VImЖFh­rТлџл9VImЖImЖrТ9VImЖFh­rТлџл9VImЖImЖrТ9VImЖFh­rТлџл9VImЖImЖrТ9VImЖFh­rТлл?_žImЖFh­ImЖ?_ž9V?_ž?_ž9VImЖNtТImЖ„Ялџл?_žImЖFh­ImЖ?_ž9V?_ž?_ž9VImЖNtТImЖ„Ялџл?_žImЖFh­ImЖ?_ž9V?_ž?_ž9VImЖNtТImЖ„Ялџл?_žImЖFh­ImЖ?_ž9V?_ž?_ž9VImЖNtТImЖ„Ялџл?_žImЖFh­ImЖ?_ž9V?_ž?_ž9VImЖNtТImЖ„Яллл9VImЖImЖFh­NtТNtТFh­ImЖImЖFh­rТллџлл9VImЖImЖFh­NtТNtТFh­ImЖImЖFh­rТллџлл9VImЖImЖFh­NtТNtТFh­ImЖImЖFh­rТллџлл9VImЖImЖFh­NtТNtТFh­ImЖImЖFh­rТллџлл9VImЖImЖFh­NtТNtТFh­ImЖImЖFh­rТллgravitation-3+dfsg1.orig/game5/gameSource/graphics/mad.tga0000644000175000017500000000065210760377351022302 0ustar pabspabsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ^џџџџџџџџџџ^џџџџџџџ^џџџџџџџџџџџџџџџџ^џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ^џџџџ^џџџџџџџџџџџџџ^џџџџџџџџџџ^џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/numeralsYellow.tga0000644000175000017500000000071310757561560024564 0ustar pabspabs1ењўењўnзђnзђ.є.єHЕHЕџџџењўnзђnзђ.є.є.єHЕџџџењўnзђ.єHЕHЕHЕџџџењўењўnзђnзђ.є.єHЕHЕџџџењўењўnзђ.єHЕHЕHЕџџџењўnзђnзђnзђ.є.єHЕџџџењўењўnзђ.є.єHЕHЕџџџењўењўењўnзђ.єHЕHЕџџџењўењўењўnзђ.є.єHЕџџџењўењўnзђnзђ.є.єHЕHЕgravitation-3+dfsg1.orig/game5/gameSource/graphics/kilnSmoke.tga0000644000175000017500000000245310747763353023504 0ustar pabspabsWџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/map.tga0000644000175000017500000001307010762047445022314 0ustar pabspabs вџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/title.tga0000644000175000017500000007202610761041046022654 0ustar pabspabscdжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџжљџГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњГюњтітітітітітітітітітітітітітітітітітітіmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђmжђXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓXНѓCЄѓCЄѓCЄѓ-Œє-Œє-Œє-Œє-Œє#uп#uп^Ъ^ЪGЕGЕGЕGЕGЕGЕgravitation-3+dfsg1.orig/game5/gameSource/graphics/kiln.tga0000644000175000017500000000350710760405311022464 0ustar pabspabs)џџџџџџrТ„ЯrТ„ЯrТrТrТ„Я„ЯrТrТџџџџџџ?_žrТ€[€[9VrТ?_ž„Я€[€[€[€[€[€[9V„Я9V„Я€[€[€[?_ž„Я?_žrТ€[€[?_žrТ9V„Я€[€[?_žrТ9V„Я€[€[9V„Я?_žrТ€[€[?_ž„Я9VrТ€[€[€[€[€[€[9VrТ?_ž„Я€[€[9V„Я?_žImЖrТ€[€[9VImЖ„Я9VFh­ImЖ„Я€[?_žFh­NtТ„Я9VNtТFh­NtТ9V?_ž?_ž9V?_ž9V9VImЖFh­ImЖrТџџџ?_žImЖImЖImЖFh­ImЖImЖImЖFh­ImЖFh­ImЖrТџџџџџџџџџ?_ž9VFh­ImЖ9VImЖFh­ImЖFh­„Я„Яџџџџџџџџџџџџџџџџџџ?_žImЖImЖ9VImЖImЖrТџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖ9V9V9VImЖ„Яџџџџџџџџџџџџџџџџџџџџџџџџ9VNtТImЖImЖNtТ9V„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VNtТFh­ImЖ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖImЖImЖrТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VFh­„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖrТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?_žNtТ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VNtТ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?_žNtТ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖrТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?_žFh­„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VFh­rТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖrТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖrТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VFh­„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?_žImЖ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?_žImЖrТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?_žImЖ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VFh­„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖrТџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VNtТ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ?_žImЖ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ9VImЖ„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$mImЖNtТFh­„Яџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ$mrТџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/heart.tga0000644000175000017500000000065210744167325022644 0ustar pabspabsџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/characterSprite.tga0000644000175000017500000000327210761574426024670 0ustar pabspabsGmmmmmmmmmџџџЖЖЖmmmmmmmmmmmmmmmmmm0aТ0aТmmmmmmmmmmmmmmmmmm’Жџ0aТmmmmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmm’Жџ’Жџo‡o‡mmmmmmmmmmmm’Жџџo‡o‡mmmmmmmmmmmmo‡o‡o‡mmmmmmmmmџџџџџџџџџџџџџџџџџџџџџџџџmmmџџџЖЖЖmmmЖЖЖџџџmmmmmmmmmmmm0aТ$I’$I’0aТmmmmmmmmmmmmmmm0aТ0aТmmmmmmmmmmmmmmm’Жџ$$$$$$’Жџmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmm’Жџ’Жџo‡o‡mmmmmmmmmmmm’Жџџo‡o‡mmmmmmmmmmmmo‡o‡o‡mmmmmmmmmџџџџџџџџџџџџџџџџџџџџџџџџmmmmmmmmmmmmџџџЖЖЖmmmmmmmmmmmmmmmmmm0aТ0aТmmmmmmmmm’Жџ$$$0aТ0aТmmmmmmmmmmmm’Жџ$$$$$$$$$mmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmm’Жџ’Жџo‡o‡mmmmmmmmmmmm’Жџџo‡o‡mmmmmmmmmmmmo‡o‡o‡mmmmmmmmmmmmџџџџџџџџџџџџџџџџџџџџџџџџmmmmmmџџџЖЖЖmmmЖЖЖџџџmmmmmmmmmmmm0aТ$I’$I’0aТmmmmmm’Жџ$$$0aТ0aТ0aТmmmmmmmmm’Жџ$$$$$$$$$mmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmm’Жџ’Жџo‡o‡mmmmmmmmmmmm’Жџџo‡o‡mmmmmmmmmmmmo‡o‡o‡mmmmmmmmmmmmџџџџџџџџџџџџџџџџџџџџџџџџmmmmmmmmmЖЖЖџџџmmmmmmmmmmmmmmmmmm0aТ0aТmmmmmmmmmmmmmmmmmm0aТ’Жџmmmmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmmo‡o‡’Жџ’Жџmmmmmmmmmmmmo‡o‡џ’Жџmmmmmmmmmmmmmmmo‡o‡o‡mmmmmmџџџџџџџџџџџџџџџџџџџџџџџџmmmmmmџџџЖЖЖmmmЖЖЖџџџmmmmmmmmm0aТ$I’$I’0aТmmmmmmmmmmmmmmm0aТ0aТmmmmmmmmmmmmmmm’Жџ$$$$$$’Жџmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmmo‡o‡’Жџ’Жџmmmmmmmmmmmmo‡o‡џ’Жџmmmmmmmmmmmmmmmo‡o‡o‡mmmmmmџџџџџџџџџџџџџџџџџџџџџџџџmmmmmmЖЖЖџџџmmmmmmmmmmmmmmmmmm0aТ0aТmmmmmmmmmmmmmmmmmmmmm0aТ0aТ$$$’Жџmmmmmmmmmmmm$$$$$$$$$’Жџmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmmo‡o‡’Жџ’Жџmmmmmmmmmmmmo‡o‡џ’Жџmmmmmmmmmmmmmmmo‡o‡o‡mmmџџџџџџџџџџџџџџџџџџџџџџџџmmmџџџЖЖЖmmmЖЖЖџџџmmmmmmmmm0aТ$I’$I’0aТmmmmmmmmmmmmmmm0aТ0aТ0aТ$$$’Жџmmmmmmmmmmmm$$$$$$$$$’Жџmmmmmmmmmmmmmmm$$$$$$mmmmmmmmmmmmmmmo‡o‡’Жџ’Жџmmmmmmmmmmmmo‡o‡џ’Жџmmmmmmmmmmmmmmmo‡o‡o‡mmmgravitation-3+dfsg1.orig/game5/gameSource/graphics/numerals.tga0000644000175000017500000000071310734770150023360 0ustar pabspabs1џЖџЖџШ@џШ@џк€џк€џьПџьПџџџџЖџШ@џШ@џк€џк€џк€џьПџџџџЖџШ@џк€џьПџьПџьПџџџџЖџЖџШ@џШ@џк€џк€џьПџьПџџџџЖџЖџШ@џк€џьПџьПџьПџџџџЖџШ@џШ@џШ@џк€џк€џьПџџџџЖџЖџШ@џк€џк€џьПџьПџџџџЖџЖџЖџШ@џк€џьПџьПџџџџЖџЖџЖџШ@џк€џк€џьПџџџџЖџЖџШ@џШ@џк€џк€џьПџьПgravitation-3+dfsg1.orig/game5/gameSource/graphics/prizeOrb.tga0000644000175000017500000000013510747773647023346 0ustar pabspabsџЖџШ@џЖџЖџШ@џк€џШ@џЖџШ@џк€џьПџк€џШ@џЖџШ@џк€џШ@џЖџЖџШ@џЖgravitation-3+dfsg1.orig/game5/gameSource/graphics/tileSet.tga0000644000175000017500000016102110761677257023161 0ustar pabspabs_ЫIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒлIm’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒлIm’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒлIm’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒлIm’Im’Im’Im’Im’Im’FiŒIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џIm’FiŒIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џIm’FiŒIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џIm’FiŒIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џIm’FiŒIm’Im’лIm’Im’Im’Im’FiŒIm’џIm’FiŒIm’Im’лIm’Im’Im’Im’FiŒIm’џIm’FiŒIm’Im’лIm’Im’Im’Im’FiŒIm’џIm’FiŒIm’Im’лIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џIm’Im’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џIm’Im’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џIm’Im’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џIm’Im’Im’Im’лIm’Im’Im’Im’FiŒIm’џIm’Im’Im’Im’лIm’Im’Im’Im’FiŒIm’џIm’Im’Im’Im’лIm’Im’Im’Im’FiŒIm’џIm’Im’Im’Im’лIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’џIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’џIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’џIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’џIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’џIm’Im’Im’лIm’FiŒIm’Im’Im’Im’Im’џIm’Im’Im’лIm’FiŒIm’Im’Im’Im’Im’џIm’Im’Im’лIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’ЖIm’Im’џIm’Im’Im’Im’Im’Im’ЖЖЖIm’Im’џIm’Im’Im’лIm’Im’ЖЖЖIm’Im’џIm’Im’Im’лIm’Im’ЖЖЖIm’Im’Im’FiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џIm’FiŒIm’џџџIm’FiŒIm’Im’Im’Im’Im’џIm’FiŒIm’џџџIm’FiŒIm’Im’Im’Im’Im’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џЖЖIm’Im’Im’FiŒIm’Im’Im’ЖЖџЖЖIm’Im’Im’FiŒIm’Im’Im’ЖЖџЖЖIm’Im’Im’ЖIm’Im’Im’ЖЖџЖЖIm’Im’Im’ЖIm’Im’Im’ЖЖIm’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’ыыыIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’ыыыIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’ЖIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’ЖIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’ЖIm’Im’ЖIm’лIm’Im’Im’џIm’Im’ЖIm’Im’ЖIm’лIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џџџџIm’ыыыIm’Im’Im’џџџIm’Im’FiŒыыыџџџџIm’ыыыIm’Im’Im’џџџIm’Im’FiŒыыыџIm’Im’ыыыIm’Im’Im’Im’Im’Im’FiŒIm’џIm’Im’џџџIm’Im’Im’Im’Im’Im’FiŒIm’џIm’Im’ЖIm’Im’Im’Im’лIm’FiŒIm’џIm’Im’ЖIm’Im’Im’Im’лIm’FiŒIm’џIm’Im’ЖIm’Im’Im’Im’лIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џџџџыыыџџџџџџIm’Im’Im’џџџIm’ыыыџџџџџџџыыыџџџџџџIm’Im’Im’џџџIm’ыыыџџџџџџџыыыџџџIm’Im’Im’Im’џџџIm’ыыыџџџџIm’џџџIm’Im’Im’Im’лIm’Im’ыыыIm’џIm’џџџIm’ЖIm’Im’лIm’Im’ыыыIm’џIm’џџџIm’ЖIm’Im’лIm’Im’ыыыIm’џIm’џџџIm’ЖIm’Im’лIm’Im’ыыыIm’FiŒIm’Im’Im’Im’FiŒIm’Im’Im’FiŒIm’џџџџџџџџџџIm’Im’FiŒIm’Im’џџџџџџџџџџџџџџџџџџџIm’Im’FiŒIm’Im’џџџџџџџџџџџџџџџџIm’Im’Im’FiŒIm’Im’џџџџџџџџџџџџџIm’Im’Im’Im’FiŒлIm’Im’ыыыџџџџџџџIm’Im’Im’Im’FiŒлIm’Im’ыыыџџџџџџџIm’Im’ЖIm’FiŒлIm’Im’ыыыџџџџџџџIm’Im’ЖIm’FiŒлIm’Im’ыыыџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџџџџIm’Im’Im’Im’лIm’Im’Im’Im’џџџџџџџIm’Im’Im’Im’лIm’Im’Im’Im’џџџџџџџIm’Im’Im’Im’лIm’Im’Im’Im’џџџџџџџIm’Im’Im’Im’лIm’Im’Im’Im’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’лIm’Im’Im’Im’Im’џIm’Im’Im’Im’Im’лIm’Im’Im’Im’Im’џIm’Im’Im’Im’Im’лIm’Im’Im’Im’Im’џIm’Im’Im’Im’Im’лIm’Im’Im’Im’Im’Im’FiŒIm’Im’FiŒFiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’FiŒFiŒыыыIm’Im’FiŒIm’џIm’FiŒIm’Im’FiŒFiŒыыыIm’Im’FiŒIm’џIm’FiŒIm’Im’FiŒFiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’FiŒлIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’FiŒллIm’Im’FiŒIm’џIm’FiŒIm’Im’FiŒлллIm’FiŒIm’џIm’FiŒIm’Im’FiŒлллIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’FiŒIm’Im’Im’џIm’Im’Im’Im’Im’Im’ыыыFiŒIm’Im’Im’џIm’Im’Im’Im’Im’Im’ыыыFiŒIm’Im’Im’џIm’Im’Im’Im’Im’Im’Im’FiŒIm’Im’Im’џIm’Im’Im’Im’Im’лIm’FiŒIm’Im’Im’џIm’Im’Im’Im’Im’лIm’FiŒIm’Im’Im’џIm’ЖIm’Im’Im’лIm’FiŒлIm’Im’џIm’ЖIm’Im’Im’лIm’FiŒлIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’ыыыџџџџџџIm’Im’Im’џIm’Im’Im’Im’Im’ыыыџџџџџџIm’Im’Im’џIm’Im’Im’Im’Im’Im’ыыыIm’Im’Im’Im’џIm’Im’Im’ЖIm’Im’Im’Im’Im’Im’Im’џIm’Im’Im’ЖЖЖIm’Im’Im’Im’Im’џIm’ЖIm’ЖЖЖIm’Im’Im’Im’Im’џIm’ЖIm’ЖЖЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’ыыыџџџџџџџџџIm’Im’џIm’Im’Im’Im’Im’ыыыџџџџџџџџџIm’Im’џIm’Im’Im’Im’Im’Im’ыыыџџџIm’Im’Im’џIm’Im’ЖIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’ЖIm’Im’лЖIm’Im’Im’Im’џIm’ЖЖIm’Im’лЖIm’Im’Im’Im’џIm’ЖЖIm’Im’лЖIm’Im’Im’Im’Im’FiŒIm’Im’FiŒIm’Im’Im’FiŒIm’Im’џIm’ыыыџџџIm’ыыыџџџџџџџџџџџџIm’Im’џIm’ыыыџџџIm’ыыыџџџџџџџџџџџџIm’Im’џIm’FiŒIm’Im’FiŒыыыџџџџџџFiŒIm’Im’џЖЖIm’Im’FiŒIm’Im’ыыыFiŒЖЖџЖЖIm’Im’лIm’Im’ЖFiŒЖЖџЖЖIm’Im’лIm’Im’ЖFiŒЖЖџЖЖIm’Im’лIm’Im’ЖFiŒЖЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џџџџџџџџџџыыыџџџџџџџџџџџџџџџIm’џџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџIm’џџџџIm’ыыыIm’Im’ыыыџџџџџџџџџџџџIm’Im’џIm’Im’Im’Im’Im’Im’Im’ыыыЖIm’Im’џIm’Im’ЖIm’лIm’Im’Im’ЖIm’Im’џIm’Im’ЖIm’лIm’Im’Im’ЖIm’Im’џIm’Im’ЖIm’лIm’Im’Im’ЖIm’Im’Im’Im’Im’Im’Im’Im’Im’FiŒFiŒIm’Im’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџIm’џџџџIm’ыыыIm’Im’Im’Im’Im’ыыыџџџIm’Im’џIm’Im’Im’ЖлIm’Im’ЖFiŒЖIm’џIm’Im’Im’ЖлIm’Im’ЖFiŒЖIm’џIm’Im’Im’ЖлIm’Im’ЖFiŒЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџIm’Im’Im’џџџЖыыыџџџIm’џџџџIm’Im’Im’Im’ЖЖЖыыыIm’Im’Im’џIm’Im’Im’Im’ЖЖЖыыыIm’ЖIm’џIm’Im’Im’Im’ЖЖЖыыыIm’ЖIm’Im’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’Im’џџџыыыџџџџџџFiŒџџџџIm’ыыыIm’Im’Im’FiŒIm’ыыыџџџFiŒIm’џIm’ыыыIm’Im’Im’лIm’ыыыЖFiŒIm’џIm’ыыыIm’Im’Im’лIm’ыыыЖFiŒIm’XƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАлџџџџџџлџџџџџџџџџџџџџџџџXƒАXƒАлџџџџџџлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’лIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’лIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’лIm’Im’ЖIm’XƒАџIm’Im’Im’Im’Im’лIm’Im’ЖIm’XƒАIm’FiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒIm’Im’Im’Im’лIm’Im’FiŒXƒАџIm’FiŒIm’Im’Im’Im’лIm’Im’FiŒXƒАџIm’FiŒIm’Im’Im’Im’лЖIm’FiŒXƒАџIm’FiŒIm’Im’Im’Im’лЖIm’FiŒXƒАIm’Im’Im’FiŒIm’Im’FiŒIm’FiŒIm’XƒАџIm’Im’Im’FiŒIm’Im’FiŒIm’FiŒIm’XƒАџIm’Im’Im’FiŒIm’Im’FiŒIm’FiŒIm’XƒАџIm’Im’Im’FiŒIm’Im’FiŒIm’FiŒIm’XƒАџIm’Im’Im’FiŒIm’Im’лIm’FiŒIm’XƒАџIm’Im’Im’FiŒЖЖлIm’FiŒIm’XƒАџIm’ЖIm’FiŒЖЖлIm’FiŒIm’XƒАџIm’ЖIm’FiŒЖЖлIm’FiŒIm’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’ЖIm’Im’Im’лIm’Im’XƒАџIm’Im’ЖЖIm’Im’Im’лллXƒАџIm’Im’ЖЖIm’Im’Im’лллXƒАIm’Im’Im’Im’FiŒIm’FiŒIm’Im’Im’XƒАџIm’Im’Im’Im’FiŒIm’FiŒIm’Im’Im’XƒАџIm’Im’Im’Im’FiŒIm’FiŒIm’Im’Im’XƒАџIm’Im’Im’Im’FiŒIm’FiŒIm’Im’Im’XƒАџIm’Im’ЖIm’FiŒIm’FiŒIm’Im’Im’XƒАџIm’Im’ЖIm’FiŒIm’FiŒлIm’Im’XƒАџIm’Im’ЖIm’FiŒIm’FiŒлIm’Im’XƒАџIm’Im’ЖIm’FiŒIm’FiŒлIm’Im’XƒАIm’Im’Im’Im’Im’Im’FiŒFiŒIm’FiŒXƒАџIm’Im’Im’Im’Im’Im’FiŒFiŒIm’FiŒXƒАџIm’Im’Im’Im’Im’Im’FiŒFiŒIm’FiŒXƒАџIm’Im’Im’Im’Im’Im’FiŒFiŒIm’FiŒXƒАџЖЖIm’Im’Im’Im’FiŒFiŒIm’FiŒXƒАџЖЖIm’Im’Im’Im’ллIm’FiŒXƒАџЖЖIm’Im’Im’лллIm’FiŒXƒАџЖЖIm’Im’Im’лллIm’FiŒXƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’ыыыџџџIm’Im’Im’Im’XƒАџIm’Im’Im’Im’ыыыџџџIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’лIm’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’лIm’Im’Im’Im’Im’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’ыыыIm’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’ыыыIm’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’џџџIm’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’ллIm’XƒАџIm’Im’Im’Im’Im’Im’Im’ллллџIm’Im’Im’Im’Im’Im’Im’ллллIm’Im’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџџџџџџџыыыџџџIm’Im’Im’Im’Im’Im’XƒАџџџџџџџыыыџџџIm’Im’Im’Im’Im’Im’XƒАџџџџыыыџџџFiŒIm’Im’Im’Im’Im’Im’XƒАџIm’ыыыIm’FiŒлIm’Im’Im’Im’Im’XƒАџIm’ыыыIm’ллIm’лIm’Im’Im’XƒАџIm’ыыыIm’ллIm’лIm’лIm’XƒАџIm’ыыыIm’ллIm’лIm’лIm’XƒАIm’Im’Im’Im’Im’Im’Im’FiŒIm’FiŒXƒАџџџџџџџџџџIm’Im’Im’Im’FiŒIm’FiŒXƒАџџџџџџџџџџIm’Im’Im’Im’FiŒIm’FiŒXƒАџџџџџџџIm’Im’Im’Im’Im’FiŒIm’FiŒXƒАџџџџџџџIm’Im’Im’лIm’FiŒIm’FiŒXƒАџџџџџџџIm’Im’Im’лIm’FiŒIm’FiŒXƒАџџџџџџџлIm’Im’лIm’FiŒIm’FiŒXƒАџџџџџџџлIm’Im’лIm’FiŒIm’FiŒXƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’лIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’лIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’лIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’лIm’Im’Im’Im’XƒАIm’FiŒFiŒIm’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒыыыIm’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒыыыIm’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒFiŒIm’Im’Im’Im’Im’Im’FiŒXƒАџIm’FiŒFiŒIm’Im’лIm’Im’Im’FiŒXƒАџIm’FiŒFiŒIm’Im’лIm’Im’Im’FiŒXƒАџIm’ЖFiŒIm’Im’лIm’Im’лFiŒXƒАџIm’ЖFiŒIm’Im’лIm’Im’лFiŒXƒАIm’FiŒIm’Im’Im’FiŒIm’Im’Im’Im’XƒАџIm’FiŒыыыIm’Im’FiŒIm’Im’Im’Im’XƒАџIm’FiŒыыыIm’Im’FiŒIm’Im’Im’Im’XƒАџIm’FiŒIm’Im’Im’FiŒIm’Im’Im’Im’XƒАџIm’FiŒIm’Im’Im’FiŒлIm’Im’Im’XƒАџIm’FiŒIm’Im’Im’FiŒлIm’Im’Im’XƒАџIm’FiŒЖIm’Im’FiŒллIm’Im’XƒАџIm’FiŒЖIm’Im’FiŒллIm’Im’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’ыыыџџџџџџџџџIm’Im’Im’Im’Im’џџџџIm’ыыыџџџџџџџџџIm’Im’Im’Im’Im’џџџџIm’Im’ыыыIm’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’лIm’Im’XƒАџIm’Im’ЖIm’ЖIm’Im’лIm’Im’XƒАџIm’Im’ЖIm’ЖIm’Im’лIm’Im’XƒАџIm’Im’ЖIm’ЖIm’Im’лIm’Im’XƒАIm’Im’FiŒIm’FiŒIm’Im’Im’Im’Im’XƒАџIm’ыыыџџџџџџџџџIm’Im’Im’Im’ыыыџџџџIm’ыыыџџџџџџџџџIm’Im’Im’Im’ыыыџџџџIm’Im’ыыыџџџFiŒIm’Im’Im’Im’Im’XƒАџIm’Im’FiŒIm’FiŒIm’Im’лIm’Im’XƒАџIm’Im’FiŒЖFiŒЖIm’лIm’Im’XƒАџIm’Im’FiŒЖFiŒЖIm’лIm’Im’XƒАџIm’Im’FiŒЖFiŒЖIm’лIm’Im’XƒАIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’ыыыџџџџџџџџџџџџIm’Im’Im’ыыыџџџџIm’ыыыџџџџџџџџџџџџIm’Im’Im’ыыыџџџџIm’ыыыџџџџџџџџџFiŒIm’Im’Im’FiŒџџџџЖЖЖыыыIm’FiŒлIm’Im’FiŒXƒАџЖЖЖIm’Im’FiŒлЖIm’FiŒXƒАџЖЖЖIm’Im’FiŒлЖIm’ЖXƒАџЖЖЖIm’Im’FiŒлЖIm’ЖXƒАIm’Im’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџFiŒIm’ыыыџџџџџџџџџџџџџџџџџџџџџџџџџFiŒIm’ыыыџџџџџџџIm’ыыыџџџџџџџџџIm’FiŒIm’Im’Im’џџџџIm’Im’Im’ыыыIm’Im’FiŒIm’Im’Im’XƒАџIm’Im’Im’Im’Im’лFiŒIm’Im’Im’XƒАџIm’Im’ЖIm’Im’лFiŒIm’ЖIm’XƒАџIm’Im’ЖIm’Im’лFiŒIm’ЖIm’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџыыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’Im’ыыыыыыџџџџIm’џџџIm’ыыыџџџIm’Im’Im’Im’Im’џџџџIm’Im’Im’Im’Im’лIm’Im’Im’Im’XƒАџIm’ЖIm’Im’Im’лIm’Im’Im’Im’XƒАџIm’ЖIm’Im’Im’лIm’Im’Im’Im’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыыыыџџџџџџџџџџџџџџџџыыыџџџџџџIm’Im’Im’Im’ыыыџџџџIm’Im’ыыыIm’лIm’лIm’Im’Im’џџџџIm’Im’ыыыIm’лIm’лллIm’џџџџIm’Im’ыыыIm’лIm’лллIm’џџџIm’FiŒIm’Im’Im’Im’Im’FiŒIm’FiŒXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’џџџFiŒыыыџџџџџџџIm’ыыыџџџлIm’Im’Im’FiŒыыыыыыџџџџIm’ыыыллIm’Im’Im’FiŒыыыыыыџџџџIm’ыыыллIm’Im’Im’FiŒыыыыыыџџџXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџлџџџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџлџџџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0HaЖ0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0HaЖ0Ha0Ha0Ha0Ha0HaIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’лIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’лIm’Im’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’лIm’Im’Im’Im’Im’џIm’ЖЖIm’Im’лIm’Im’Im’Im’Im’џIm’ЖЖIm’Im’лIm’Im’Im’Im’Im’Im’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’Im’џIm’Im’Im’FiŒFiŒIm’ЖЖIm’Im’Im’џIm’Im’Im’FiŒлIm’ЖЖIm’Im’Im’џIm’Im’Im’ЖлIm’ЖЖIm’Im’Im’џIm’Im’Im’ЖлIm’ЖЖIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џIm’Im’FiŒIm’Im’Im’Im’Im’ЖIm’Im’џIm’Im’FiŒIm’ЖIm’ЖIm’ЖIm’Im’џIm’Im’FiŒIm’ЖIm’ЖIm’ЖIm’Im’џIm’Im’FiŒIm’ЖIm’ЖIm’ЖIm’Im’Im’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’Im’ыыыIm’Im’FiŒIm’Im’ыыыFiŒIm’џIm’Im’ыыыIm’Im’FiŒIm’Im’ыыыFiŒIm’џIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒIm’џЖЖIm’Im’Im’FiŒIm’Im’Im’ЖЖџЖЖIm’Im’ЖFiŒЖIm’Im’ЖЖџЖЖIm’Im’ЖFiŒЖIm’Im’ЖЖџЖЖIm’Im’ЖFiŒЖIm’Im’ЖЖIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’џIm’Im’ыыыIm’FiŒIm’Im’Im’ыыыIm’Im’џIm’Im’ыыыIm’FiŒIm’Im’Im’ыыыIm’Im’џIm’Im’ыыыIm’FiŒIm’Im’Im’ыыыIm’Im’џIm’Im’ЖIm’FiŒIm’Im’Im’Im’Im’Im’џIm’Im’ЖЖлЖIm’Im’Im’Im’Im’џIm’Im’ЖЖлЖIm’Im’Im’Im’Im’џIm’Im’ЖЖлЖIm’Im’Im’Im’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’Im’џџџџыыыIm’FiŒIm’Im’Im’Im’Im’ыыыџџџџџџџыыыIm’FiŒIm’Im’Im’Im’Im’ыыыџџџџIm’ыыыIm’FiŒIm’Im’Im’Im’Im’ыыыIm’џIm’Im’Im’FiŒлIm’Im’Im’Im’Im’Im’џIm’Im’Im’FiŒлIm’ЖIm’Im’Im’Im’џIm’Im’Im’FiŒлIm’ЖIm’Im’Im’Im’џIm’Im’Im’FiŒлIm’ЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џџџџIm’ыыыџџџIm’Im’Im’Im’ыыыџџџџџџџџџџIm’ыыыџџџIm’Im’Im’Im’ыыыџџџџџџџџџџIm’џџџIm’Im’Im’Im’Im’Im’џџџџџџџIm’Im’ыыыIm’лIm’Im’Im’Im’џџџIm’џIm’Im’ыыыIm’лIm’Im’Im’Im’џџџIm’џIm’Im’лIm’лIm’Im’ЖЖџџџIm’џIm’Im’лIm’лIm’Im’ЖЖџџџIm’Im’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’џџџџыыыџџџIm’Im’FiŒIm’Im’Im’ыыыџџџџџџџыыыџџџIm’Im’FiŒIm’Im’Im’ыыыџџџџџџџџџџIm’Im’Im’FiŒIm’Im’Im’Im’џџџџџџџџџџIm’Im’ллIm’Im’Im’Im’џџџџџџџџџџIm’Im’ллIm’Im’Im’Im’џџџџџџџџџџIm’лллIm’Im’Im’Im’џџџџџџџџџџIm’лллIm’Im’Im’Im’џџџIm’Im’FiŒIm’Im’Im’Im’FiŒIm’Im’Im’џџџџIm’FiŒIm’Im’Im’Im’FiŒIm’Im’џџџџџџџIm’FiŒIm’Im’Im’Im’FiŒIm’Im’џџџџџџџIm’FiŒIm’Im’Im’Im’FiŒIm’Im’џџџџџџџIm’FiŒIm’Im’лIm’FiŒIm’Im’џџџџџџџIm’FiŒIm’Im’лIm’FiŒIm’Im’џџџџџџџIm’FiŒIm’Im’лIm’FiŒIm’Im’џџџџџџџIm’FiŒIm’Im’лIm’FiŒIm’Im’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0HaЖ0Ha0Ha0Ha0Ha0Ha0Haџ0Ha0Ha0Ha0HaЖ0Ha0Ha0Ha0Ha0Ha0HaIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џIm’FiŒIm’Im’Im’FiŒIm’ЖIm’FiŒIm’џIm’FiŒIm’ЖIm’FiŒIm’ЖЖFiŒIm’џIm’FiŒIm’ЖIm’FiŒIm’ЖЖFiŒIm’Im’Im’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒFiŒIm’ыыыIm’Im’Im’џIm’Im’Im’Im’FiŒFiŒIm’ыыыIm’Im’Im’џIm’Im’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’џIm’Im’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’џIm’Im’Im’ЖFiŒFiŒЖIm’Im’Im’Im’џIm’Im’Im’ЖFiŒFiŒЖIm’Im’ЖIm’џIm’Im’Im’ЖFiŒFiŒЖIm’Im’ЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’ыыыIm’Im’Im’џIm’Im’Im’Im’Im’Im’Im’ыыыIm’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’Im’ЖIm’Im’ЖIm’Im’Im’Im’џIm’Im’Im’ЖIm’Im’ЖIm’Im’Im’Im’џIm’Im’Im’ЖIm’Im’ЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’џIm’Im’ыыыIm’Im’Im’ыыыџџџџџџIm’Im’џIm’Im’ыыыIm’Im’Im’ыыыџџџџџџIm’Im’џIm’Im’Im’Im’Im’Im’Im’ыыыIm’Im’Im’џIm’Im’ЖIm’Im’Im’ЖIm’Im’Im’Im’џIm’Im’ЖIm’Im’Im’ЖIm’Im’Im’Im’џIm’Im’ЖIm’Im’Im’ЖIm’Im’Im’Im’џIm’Im’ЖIm’Im’Im’ЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’Im’FiŒIm’Im’џIm’Im’ыыыIm’Im’Im’ыыыџџџџџџIm’Im’џIm’Im’ыыыIm’Im’Im’ыыыџџџџџџIm’Im’џIm’Im’Im’Im’Im’Im’Im’ыыыFiŒIm’Im’џЖЖIm’Im’Im’Im’Im’ЖЖЖЖџЖЖIm’Im’Im’ЖЖЖЖЖЖџЖЖIm’Im’Im’ЖЖЖЖЖЖџЖЖIm’Im’Im’ЖЖЖЖЖЖIm’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’џџџџыыыџџџџџџFiŒыыыџџџџџџџџџIm’џџџџџџџыыыџџџџџџFiŒыыыџџџџџџџџџIm’џџџџIm’Im’ыыыIm’FiŒIm’ыыыџџџџџџIm’Im’џIm’ЖIm’Im’FiŒIm’Im’ыыыIm’Im’Im’џIm’ЖIm’ЖЖIm’Im’ЖIm’Im’Im’џIm’ЖIm’ЖЖIm’Im’ЖIm’Im’Im’џIm’ЖIm’ЖЖIm’Im’ЖIm’Im’Im’FiŒIm’Im’Im’FiŒFiŒIm’Im’Im’Im’Im’џџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџыыыџџџIm’FiŒыыыџџџџџџџџџIm’џџџџFiŒIm’Im’Im’FiŒFiŒыыыџџџIm’Im’Im’џFiŒIm’ЖIm’FiŒFiŒЖIm’Im’Im’Im’џFiŒIm’ЖIm’FiŒFiŒЖIm’Im’Im’Im’џFiŒIm’ЖIm’FiŒFiŒЖIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’FiŒIm’Im’Im’Im’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыыыыџџџџџџџџџџџџџџџџџџџџџџIm’ыыыIm’Im’ыыыџџџџџџџџџIm’џџџџIm’Im’Im’ЖЖIm’ЖIm’Im’Im’Im’џIm’ЖIm’ЖЖIm’ЖIm’Im’Im’Im’џIm’ЖIm’ЖЖIm’ЖIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’Im’Im’Im’FiŒIm’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџIm’ыыыџџџџџџџџџыыыџџџџIm’ыыыIm’Im’Im’Im’Im’Im’ыыыџџџIm’џIm’ыыыIm’Im’ЖIm’Im’ЖыыыџџџIm’џIm’ыыыIm’Im’ЖIm’Im’ЖыыыџџџIm’XƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџлXƒАXƒАџџџлџџџџџџџџџџџџџџџџџџџлXƒАXƒАџџџлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0HaЖ0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0HaЖ0Ha0Ha0HaџџIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒлIm’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒлIm’Im’FiŒXƒАIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’ЖIm’Im’Im’Im’Im’лIm’Im’XƒАџIm’ЖIm’Im’Im’Im’Im’лIm’Im’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’ллIm’Im’XƒАџIm’Im’ЖIm’Im’Im’ллIm’Im’XƒАџIm’Im’ЖIm’Im’Im’ллIm’Im’XƒАIm’Im’FiŒIm’Im’Im’Im’FiŒFiŒIm’XƒАџIm’Im’FiŒIm’Im’Im’Im’FiŒFiŒIm’XƒАџIm’Im’FiŒIm’Im’Im’Im’FiŒFiŒIm’XƒАџIm’Im’FiŒIm’Im’Im’Im’FiŒFiŒIm’XƒАџIm’Im’FiŒIm’Im’Im’Im’FiŒFiŒIm’XƒАџIm’Im’ЖIm’Im’лIm’FiŒFiŒIm’XƒАџIm’Im’ЖIm’Im’лIm’FiŒFiŒIm’XƒАџIm’Im’ЖIm’Im’лIm’FiŒFiŒIm’XƒАIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’џџџFiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’џџџFiŒIm’Im’Im’FiŒXƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’FiŒXƒАџЖIm’Im’Im’лFiŒIm’Im’Im’FiŒXƒАџЖЖIm’Im’лFiŒЖIm’Im’FiŒXƒАџЖЖIm’Im’лFiŒЖЖЖFiŒXƒАџЖЖIm’Im’лFiŒЖЖЖFiŒXƒАIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџIm’Im’Im’ыыыIm’FiŒIm’Im’Im’Im’XƒАџIm’Im’Im’ыыыIm’FiŒIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџIm’ЖIm’Im’лFiŒIm’Im’Im’Im’XƒАџIm’ЖIm’Im’лЖIm’Im’Im’Im’XƒАџIm’ЖIm’Im’лЖIm’Im’Im’Im’XƒАџIm’ЖIm’Im’лЖIm’Im’Im’Im’XƒАIm’Im’FiŒFiŒIm’Im’Im’Im’Im’Im’XƒАџџџџIm’FiŒыыыIm’Im’Im’Im’Im’Im’XƒАџџџџIm’FiŒыыыIm’Im’Im’Im’Im’Im’XƒАџIm’Im’FiŒыыыIm’Im’Im’Im’Im’Im’XƒАџIm’Im’ЖЖIm’лIm’Im’Im’Im’XƒАџIm’Im’ЖЖIm’лIm’ллIm’XƒАџIm’Im’ЖЖIm’лIm’ллIm’XƒАџIm’Im’ЖЖIm’лIm’ллIm’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџыыыыыыџџџџџџIm’Im’Im’Im’Im’XƒАџџџџыыыыыыџџџџџџIm’Im’Im’Im’Im’XƒАџџџџIm’ыыыџџџIm’Im’Im’Im’Im’Im’XƒАџIm’Im’џџџIm’Im’ллIm’Im’Im’XƒАџIm’Im’џџџIm’Im’ллIm’Im’Im’XƒАџIm’Im’ЖIm’Im’ллIm’Im’лXƒАџIm’Im’ЖIm’Im’ллIm’Im’лXƒАIm’FiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџџџџџџџџџџџџџIm’Im’Im’Im’Im’FiŒXƒАџџџџџџџџџџџџџIm’Im’Im’Im’Im’FiŒXƒАџџџџџџџџџџIm’Im’Im’Im’Im’Im’FiŒXƒАџџџџџџџIm’Im’Im’лIm’Im’Im’FiŒXƒАџџџџџџџIm’Im’Im’лIm’Im’Im’FiŒXƒАџџџџЖIm’Im’Im’лIm’Im’лFiŒXƒАџџџџЖIm’Im’Im’лIm’Im’лFiŒXƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0HaџџIm’FiŒIm’Im’FiŒFiŒIm’Im’Im’FiŒXƒАџIm’FiŒIm’Im’FiŒFiŒIm’Im’Im’FiŒXƒАџIm’FiŒIm’Im’FiŒFiŒIm’Im’Im’FiŒXƒАџIm’FiŒIm’Im’FiŒFiŒIm’Im’Im’FiŒXƒАџIm’FiŒIm’Im’FiŒFiŒIm’Im’Im’FiŒXƒАџIm’FiŒIm’Im’FiŒЖIm’Im’Im’FiŒXƒАџIm’FiŒIm’Im’FiŒЖллIm’FiŒXƒАџIm’FiŒIm’Im’FiŒЖллIm’FiŒXƒАIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџIm’Im’Im’Im’ыыыFiŒIm’Im’Im’Im’XƒАџIm’Im’Im’Im’ыыыFiŒIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџIm’Im’Im’Im’ЖFiŒIm’Im’Im’Im’XƒАџIm’Im’Im’Im’ЖЖIm’Im’Im’Im’XƒАџIm’Im’Im’Im’ЖЖIm’Im’Im’Im’XƒАџIm’Im’Im’Im’ЖЖIm’Im’Im’Im’XƒАIm’Im’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’FiŒыыыџџџIm’Im’Im’Im’XƒАџIm’Im’Im’FiŒыыыџџџIm’Im’Im’Im’XƒАџIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’ЖIm’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’ЖIm’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’ЖIm’Im’Im’Im’Im’џOOXƒАџIm’Im’Im’ЖIm’Im’Im’Im’Im’џOOXƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџIm’Im’Im’ыыыџџџџџџџџџIm’Im’Im’џџџџIm’Im’Im’ыыыџџџџџџџџџIm’Im’Im’џџџџIm’Im’Im’Im’ыыыIm’Im’Im’Im’Im’XƒАџIm’Im’Im’ЖЖIm’Im’Im’Im’Im’XƒАџIm’Im’Im’ЖЖIm’Im’Im’Im’џOOXƒАџIm’Im’Im’ЖЖIm’Im’Im’џOOџџџOOџIm’Im’Im’ЖЖIm’Im’Im’џOOџџџOOIm’FiŒIm’Im’Im’FiŒIm’Im’Im’Im’XƒАџFiŒыыыыыыџџџџџџџџџџџџIm’Im’ыыыџџџџFiŒыыыыыыџџџџџџџџџџџџIm’Im’ыыыџџџџIm’Im’Im’ыыыџџџџџџIm’Im’Im’Im’XƒАџЖЖЖIm’ыыыЖIm’Im’Im’Im’XƒАџЖЖЖIm’Im’ЖIm’Im’ЖIm’XƒАџЖЖЖIm’Im’ЖIm’Im’ЖџOOXƒАџЖЖЖIm’Im’ЖIm’Im’ЖџOOXƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџыыыыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыыыыџџџџџџџIm’ыыыыыыџџџџџџџџџџџџIm’Im’Im’џџџџIm’Im’Im’Im’ыыыЖЖЖIm’Im’XƒАџIm’Im’Im’ЖIm’ЖЖЖIm’Im’XƒАџIm’Im’Im’ЖIm’ЖЖЖIm’Im’XƒАџIm’Im’Im’ЖIm’ЖЖЖIm’Im’XƒАIm’Im’Im’FiŒIm’FiŒIm’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’Im’ыыыџџџџIm’Im’ыыыыыыџџџFiŒыыыIm’Im’Im’XƒАџIm’Im’Im’FiŒыыыЖIm’Im’Im’Im’XƒАџIm’Im’Im’ЖыыыЖIm’Im’Im’Im’XƒАџIm’Im’Im’ЖыыыЖIm’Im’Im’Im’XƒАIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџIm’ыыыџџџџџџџџџџыыыџџџџџџџџџIm’ыыыIm’Im’Im’џџџџIm’ыыыIm’ыыыџџџIm’лIm’Im’Im’XƒАџIm’ллыыыџџџIm’лIm’Im’Im’XƒАџIm’ллыыыџџџIm’лIm’Im’Im’XƒАIm’FiŒIm’Im’Im’FiŒIm’Im’Im’FiŒXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџIm’ыыыыыыџџџџIm’ыыыIm’ыыыџџџFiŒџџџIm’Im’џџџXƒАџIm’ыыыIm’ыыыџџџFiŒџџџлIm’џџџXƒАџIm’ыыыIm’ыыыџџџFiŒџџџлIm’џџџXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’лFiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’лFiŒллIm’FiŒIm’џ0HaFiŒIm’Im’лFiŒлллFiŒIm’џ0HaFiŒIm’Im’лFiŒлллFiŒIm’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’лIm’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’лIm’Im’Im’Im’Im’лIm’џ0HaIm’Im’лIm’Im’Im’Im’Im’лIm’0HaFiŒIm’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaFiŒIm’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaFiŒIm’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaFiŒIm’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaFiŒIm’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaFiŒлIm’Im’Im’Im’FiŒIm’Im’Im’џ0HaллIm’лIm’Im’FiŒIm’Im’Im’џ0HaллIm’лIm’Im’FiŒIm’Im’Im’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’ыыыIm’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’ыыыIm’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џЖIm’Im’Im’лIm’Im’Im’Im’Im’Im’џЖIm’Im’Im’лIm’Im’Im’Im’Im’Im’0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’FiŒIm’ыыыџџџIm’Im’џ0HaFiŒIm’Im’Im’FiŒIm’ыыыџџџIm’Im’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’FiŒIm’ЖЖЖЖџ0HaFiŒIm’Im’Im’FiŒIm’ЖЖЖЖџ0HaFiŒIm’Im’Im’FiŒIm’ЖЖЖЖџ0HaFiŒIm’Im’Im’FiŒIm’ЖЖЖЖ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’ыыыџџџџџџIm’џ0HaIm’Im’Im’Im’Im’Im’ыыыџџџџџџIm’џ0HaIm’Im’Im’Im’Im’Im’Im’ыыыIm’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’ллIm’Im’ЖIm’Im’Im’Im’џ0HaIm’ллIm’Im’ЖIm’Im’Im’Im’џ0HaIm’ллIm’Im’ЖIm’Im’Im’Im’0HaIm’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џ0HaIm’Im’Im’Im’Im’Im’Im’ыыыџџџџџџџ0HaIm’Im’Im’Im’Im’Im’Im’ыыыџџџџџџџ0HaIm’Im’Im’Im’Im’Im’Im’ыыыџџџIm’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’ыыыIm’џ0HaIm’Im’Im’лIm’ЖIm’Im’ыыыIm’џЖлIm’Im’лIm’ЖIm’Im’ЖIm’џЖлIm’Im’лIm’ЖIm’Im’ЖIm’0HaIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’FiŒIm’Im’Im’Im’Im’ыыыџџџџџџџ0HaIm’FiŒIm’Im’Im’Im’Im’ыыыџџџџџџџ0HaIm’FiŒIm’Im’Im’Im’Im’ыыыџџџџџџџ0HaIm’FiŒIm’Im’лIm’Im’Im’ыыыIm’џ0HaIm’FiŒIm’Im’лIm’ЖIm’ыыыIm’џ0HaIm’FiŒIm’Im’лIm’ЖЖыыыIm’џ0HaIm’FiŒIm’Im’лIm’ЖЖыыыIm’0HaFiŒIm’Im’Im’FiŒIm’FiŒIm’Im’FiŒџ0HaFiŒIm’Im’Im’FiŒIm’FiŒIm’ыыыџџџџ0HaFiŒIm’Im’Im’FiŒIm’FiŒIm’ыыыџџџџ0HaFiŒIm’Im’Im’FiŒIm’FiŒIm’ыыыџџџџ0HaFiŒIm’Im’Im’лIm’FiŒIm’ыыыџџџџ0HaFiŒIm’Im’Im’лIm’FiŒIm’ыыыџџџџ0HaFiŒIm’Im’Im’лIm’FiŒIm’ыыыџџџџ0HaFiŒIm’Im’Im’лIm’FiŒIm’ыыыџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’0HaFiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’џыыыFiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’џыыыFiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’лIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’лIm’Im’Im’Im’Im’џ0HaFiŒIm’лIm’лIm’Im’Im’Im’Im’џ0HaFiŒIm’лIm’лIm’Im’Im’Im’Im’0HaIm’Im’Im’FiŒIm’Im’Im’Im’FiŒIm’џыыыџџџIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џыыыџџџIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џ0HaIm’Im’Im’FiŒIm’Im’Im’Im’FiŒIm’џ0HaIm’Im’Im’FiŒлIm’Im’Im’FiŒIm’џ0HaIm’Im’Im’FiŒллIm’Im’FiŒIm’џ0HaIm’Im’лFiŒллIm’ЖFiŒIm’џ0HaIm’Im’лFiŒллIm’ЖFiŒIm’0HaIm’Im’FiŒIm’Im’Im’FiŒIm’Im’Im’џыыыџџџџџџFiŒIm’Im’Im’FiŒIm’Im’Im’џыыыџџџџџџFiŒIm’Im’Im’FiŒIm’Im’Im’џыыыIm’Im’FiŒIm’Im’Im’FiŒIm’Im’Im’џ0HaIm’Im’FiŒIm’лIm’FiŒIm’Im’Im’џ0HaIm’Im’FiŒллIm’лIm’Im’Im’џ0HaIm’Im’FiŒллIm’лIm’ЖIm’џ0HaIm’Im’FiŒллIm’лIm’ЖIm’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џыыыџџџџџџIm’Im’Im’Im’Im’Im’Im’Im’џыыыџџџџџџIm’Im’Im’Im’Im’Im’Im’Im’џыыыIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’ЖЖЖлЖIm’Im’ЖIm’џ0HaIm’ЖЖЖлЖлIm’ЖIm’џ0HaIm’ЖЖЖлЖлIm’ЖIm’0HaFiŒIm’Im’Im’Im’Im’Im’Im’FiŒIm’џыыыџџџџџџџџџIm’Im’Im’Im’Im’ыыыIm’џыыыџџџџџџџџџIm’Im’Im’Im’Im’ыыыIm’џыыыџџџџџџIm’Im’Im’Im’Im’Im’FiŒIm’џ0HaыыыIm’Im’Im’Im’Im’ЖЖЖЖџ0HaFiŒIm’Im’лIm’Im’ЖЖЖЖџ0HaЖIm’Im’лIm’Im’лЖЖЖџ0HaЖIm’Im’лIm’Im’лЖЖЖ0HaIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џыыыџџџџџџџџџџџџIm’Im’Im’Im’ыыыџџџџыыыџџџџџџџџџџџџIm’Im’Im’Im’ыыыџџџџыыыџџџџџџџџџIm’Im’Im’Im’Im’ыыыIm’џ0HaыыыџџџIm’Im’Im’Im’Im’Im’ЖIm’џ0HaIm’FiŒлIm’Im’Im’Im’Im’ЖIm’џЖЖFiŒлIm’Im’Im’Im’Im’ЖIm’џЖЖFiŒлIm’Im’Im’Im’Im’ЖIm’0HaIm’Im’FiŒFiŒIm’Im’Im’Im’FiŒIm’џыыыџџџџџџџџџџџџIm’Im’Im’ыыыџџџџџџџыыыџџџџџџџџџџџџIm’Im’Im’ыыыџџџџџџџыыыџџџџџџџџџFiŒIm’Im’Im’Im’ыыыџџџџыыыџџџIm’FiŒFiŒIm’Im’Im’Im’ыыыIm’џ0HaIm’Im’лFiŒIm’Im’Im’ЖFiŒIm’џ0HaIm’Im’лFiŒIm’Im’Im’ЖFiŒIm’џ0HaIm’Im’лFiŒIm’Im’Im’ЖFiŒIm’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џыыыџџџџџџџџџџџџIm’ыыыыыыџџџџџџџџџџыыыџџџџџџџџџџџџIm’ыыыыыыџџџџџџџџџџыыыџџџџџџџџџџџџIm’Im’Im’ыыыџџџџџџџыыыџџџIm’ыыыIm’Im’Im’Im’Im’ыыыџџџџ0HaыыыIm’Im’Im’Im’Im’ЖIm’ыыыIm’џ0HaыыыIm’лIm’Im’Im’ЖIm’ыыыIm’џ0HaыыыIm’лIm’Im’Im’ЖIm’ыыыIm’0HaIm’Im’Im’Im’FiŒIm’Im’Im’FiŒIm’џыыыџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџFiŒыыыыыыџџџџџџџџџџыыыџџџIm’ыыыџџџFiŒIm’Im’ыыыџџџџџџџыыыыыыIm’ыыыIm’FiŒIm’Im’Im’ыыыIm’џыыыыыыIm’лIm’FiŒIm’ЖIm’ыыыIm’џыыыыыыIm’лIm’FiŒIm’ЖIm’ыыыIm’џџXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџлџџџXƒАXƒАXƒАлџџџџџџџџџџџџџџџлџџџXƒАXƒАXƒАлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0HaIm’Im’Im’FiŒIm’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’FiŒIm’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’FiŒIm’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’FiŒIm’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’FiŒлIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’FiŒлIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’FiŒлIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’FiŒлIm’Im’Im’Im’XƒА0HaFiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’лIm’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’лIm’Im’Im’FiŒXƒАџ0HaFiŒлIm’Im’лIm’Im’Im’FiŒXƒАџ0HaFiŒлIm’Im’лIm’Im’Im’FiŒXƒА0HaIm’Im’FiŒIm’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’лIm’Im’Im’XƒАџ0HaIm’Im’FiŒлIm’лIm’Im’Im’XƒАџ0HaIm’Im’ллIm’лIm’Im’лXƒАџ0HaIm’Im’ллIm’лIm’Im’лXƒА0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’ллIm’XƒАџ0HaIm’Im’FiŒIm’Im’Im’ллIm’XƒАџ0HaIm’Im’FiŒIm’Im’Im’ллIm’XƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’лIm’Im’Im’Im’Im’лIm’XƒАџ0HaIm’лIm’Im’Im’Im’Im’лIm’XƒАџ0HaIm’лIm’Im’Im’Im’Im’лIm’XƒА0HaFiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaлIm’лIm’Im’Im’Im’Im’Im’XƒАџ0HaлIm’лIm’Im’Im’Im’Im’ллџ0HaлIm’лIm’Im’Im’Im’Im’лл0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’лFiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’лFiŒIm’Im’Im’Im’XƒАџ0HaлIm’Im’лFiŒIm’Im’Im’Im’XƒАџ0HaлIm’Im’лFiŒIm’Im’Im’Im’XƒА0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’лIm’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’лллFiŒIm’Im’XƒАџЖIm’Im’Im’лллFiŒIm’Im’XƒАџЖIm’Im’Im’лллFiŒIm’Im’XƒА0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’лIm’Im’XƒАџ0HaIm’Im’Im’Im’лIm’лIm’Im’XƒА0HaFiŒIm’Im’FiŒIm’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’FiŒIm’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’FiŒIm’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’FiŒIm’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’FiŒлIm’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’FiŒлIm’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’FiŒлIm’лIm’FiŒXƒАџ0HaFiŒIm’Im’FiŒлIm’лIm’FiŒXƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’лFiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’лFiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’лFiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’лFiŒIm’Im’Im’XƒА0HaFiŒIm’Im’FiŒIm’Im’Im’FiŒIm’XƒАџыыыFiŒIm’Im’FiŒIm’Im’Im’FiŒIm’XƒАџыыыFiŒIm’Im’FiŒIm’Im’Im’FiŒIm’XƒАџ0HaFiŒIm’Im’FiŒIm’Im’Im’FiŒIm’XƒАџ0HaFiŒIm’Im’FiŒлIm’Im’FiŒIm’XƒАџ0HaFiŒIm’Im’FiŒлIm’Im’FiŒIm’XƒАџ0HaFiŒIm’Im’FiŒлIm’Im’FiŒIm’XƒАџ0HaFiŒIm’Im’FiŒлIm’Im’FiŒIm’XƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџыыыIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџыыыIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’XƒАџ0HaIm’лIm’Im’лIm’Im’Im’Im’XƒАџ0HaллIm’Im’лIm’Im’Im’Im’XƒАџ0HaллIm’Im’лIm’Im’Im’Im’XƒА0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџыыыџџџџџџIm’Im’Im’Im’FiŒIm’Im’XƒАџыыыџџџџџџIm’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’лFiŒIm’Im’XƒАџ0HaIm’Im’ллIm’лFiŒIm’Im’XƒАџЖIm’Im’ллIm’лFiŒIm’Im’XƒАџЖIm’Im’ллIm’лFiŒIm’Im’XƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџыыыџџџџџџџџџIm’Im’ыыыIm’Im’Im’XƒАџыыыџџџџџџџџџIm’Im’ыыыIm’Im’Im’XƒАџыыыIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’лIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’лллIm’XƒАџ0HaIm’Im’Im’Im’Im’лллIm’XƒАџ0HaIm’Im’Im’Im’Im’лллIm’XƒА0HaFiŒIm’Im’Im’Im’Im’Im’Im’FiŒXƒАџыыыџџџџџџџџџIm’ыыыџџџIm’Im’FiŒXƒАџыыыџџџџџџџџџIm’ыыыџџџIm’Im’FiŒXƒАџыыыџџџџџџIm’Im’Im’Im’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’лIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’лIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’лIm’Im’ллџ0HaFiŒIm’Im’Im’Im’лIm’Im’лл0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџыыыџџџџџџџџџыыыџџџџџџџџџџџџIm’XƒАџыыыџџџџџџџџџыыыџџџџџџџџџџџџIm’XƒАџыыыџџџџџџIm’Im’ыыыIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’ллIm’Im’Im’Im’XƒАџ0HaIm’ЖџIm’ллIm’лIm’Im’XƒАџ0HaIm’ЖџIm’ллIm’лIm’Im’XƒА0HaIm’FiŒIm’Im’FiŒIm’FiŒIm’Im’XƒАџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАџыыыџџџџџџџџџIm’ыыыџџџџџџџџџIm’XƒАџыыыIm’FiŒIm’Im’ыыыIm’FiŒIm’Im’XƒАџ0HaIm’FiŒлIm’FiŒIm’FiŒIm’Im’XƒАџ0HaIm’џ$џлIm’FiŒIm’FiŒлIm’XƒАџ0HaIm’џ$џлIm’FiŒIm’FiŒлIm’XƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџыыыџџџџџџџџџџџџџџџXƒАџыыыIm’ыыыIm’Im’ыыыџџџџџџIm’Im’XƒАџыыыIm’џ$џIm’Im’Im’Im’Im’Im’Im’XƒАџЖџџ$џџџџ$џЖџIm’Im’Im’Im’Im’XƒАџЖџџ$џџџџ$џЖџIm’Im’Im’Im’Im’XƒА0HaFiŒIm’FiŒIm’Im’Im’Im’Im’FiŒXƒАџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыыыыџџџџџџIm’ыыыџџџџџџIm’џџџXƒАџыыыџџџџџџFiŒIm’Im’Im’Im’Im’џџџXƒАџыыыџџџџ$џFiŒIm’Im’Im’Im’Im’џџџXƒАџыыыџџџџ$џFiŒIm’Im’Im’Im’Im’џџџXƒАџџXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџџџЖџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџџџЖџџџџXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’Im’џ0HaFiŒIm’Im’Im’лIm’Im’Im’ЖIm’џ0HaFiŒIm’Im’Im’лIm’Im’Im’ЖIm’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’ЖЖIm’Im’Im’Im’џЖIm’Im’Im’Im’ЖЖIm’ЖIm’Im’џЖIm’Im’Im’Im’ЖЖIm’ЖIm’Im’0HaIm’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’FiŒIm’џ0HaIm’Im’Im’Im’Im’Im’ЖIm’FiŒIm’џ0HaIm’Im’Im’ЖлIm’ЖIm’FiŒIm’џ0HaЖIm’Im’ЖлIm’ЖIm’FiŒIm’џ0HaЖIm’Im’ЖлIm’ЖIm’FiŒIm’0HaIm’Im’Im’Im’FiŒIm’Im’FiŒIm’Im’џ0HaIm’Im’Im’Im’FiŒIm’Im’FiŒIm’Im’џ0HaIm’Im’Im’Im’FiŒIm’Im’FiŒIm’Im’џ0HaIm’Im’Im’Im’FiŒIm’Im’FiŒIm’Im’џ0HaIm’Im’Im’Im’FiŒIm’Im’ЖIm’Im’џ0HaIm’ЖЖIm’лIm’Im’ЖIm’Im’џ0HaIm’ЖЖIm’лIm’Im’ЖIm’Im’џ0HaIm’ЖЖIm’лIm’Im’ЖIm’Im’0HaFiŒIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џ0HaFiŒIm’Im’FiŒIm’Im’џџџIm’FiŒIm’џ0HaFiŒIm’Im’FiŒIm’Im’џџџIm’FiŒIm’џ0HaFiŒIm’Im’FiŒIm’Im’Im’Im’FiŒIm’џ0HaFiŒIm’Im’FiŒIm’Im’Im’Im’ЖЖџ0HaFiŒIm’Im’FiŒIm’лIm’Im’ЖЖџ0HaFiŒIm’Im’FiŒIm’лIm’Im’ЖЖџ0HaFiŒIm’Im’FiŒIm’лIm’Im’ЖЖ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’ыыыџџџIm’Im’Im’џ0HaIm’Im’Im’Im’Im’ыыыџџџIm’Im’Im’џ0HaIm’Im’Im’Im’Im’ыыыIm’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’лIm’лIm’Im’Im’џ0HaIm’Im’Im’Im’лIm’лIm’Im’Im’0HaIm’FiŒFiŒIm’Im’Im’FiŒIm’Im’Im’џ0HaIm’FiŒFiŒIm’Im’ыыыFiŒIm’Im’џџџџ0HaIm’FiŒFiŒIm’Im’ыыыFiŒIm’Im’џџџџ0HaIm’FiŒFiŒIm’Im’ыыыFiŒIm’Im’Im’џ0HaIm’FiŒFiŒIm’лIm’FiŒIm’Im’Im’џ0HaIm’лFiŒIm’лIm’FiŒIm’Im’Im’џ0HaIm’лFiŒIm’лIm’лIm’Im’Im’џ0HaIm’лFiŒIm’лIm’лIm’Im’Im’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’ыыыџџџџџџIm’ыыыџџџџ0HaIm’Im’Im’Im’ыыыџџџџџџIm’ыыыџџџџ0HaIm’Im’Im’Im’Im’ыыыџџџIm’ыыыџџџџ0HaIm’Im’Im’Im’лIm’Im’Im’ыыыIm’џ0HaIm’Im’лIm’лIm’Im’Im’ыыыIm’џЖлIm’лIm’лIm’Im’Im’ыыыIm’џЖлIm’лIm’лIm’Im’Im’ыыыIm’0HaFiŒIm’Im’Im’Im’Im’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’Im’ыыыџџџџџџџџџџџџџ0HaFiŒIm’Im’Im’Im’ыыыџџџџџџџџџџџџџ0HaFiŒIm’Im’Im’Im’Im’Im’џџџџџџџџџџ0HaFiŒIm’Im’лIm’Im’Im’ыыыџџџџџџџ0HaFiŒIm’Im’лIm’Im’Im’ыыыџџџџџџџ0HaFiŒIm’Im’лIm’Im’Im’ыыыџџџџџџџ0HaFiŒIm’Im’лIm’Im’Im’ыыыџџџџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџ0HaIm’Im’Im’Im’лIm’Im’Im’Im’џџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒЖIm’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒЖIm’Im’FiŒIm’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’ыыыIm’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’ыыыIm’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’ЖIm’Im’Im’Im’Im’џ0HaIm’Im’Im’Im’ЖIm’Im’Im’Im’Im’0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaIm’Im’Im’Im’Im’ыыыFiŒIm’Im’Im’џ0HaIm’Im’Im’Im’Im’ыыыFiŒIm’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’Im’џ0HaIm’Im’Im’Im’ЖIm’FiŒIm’Im’Im’џЖЖIm’Im’Im’ЖIm’FiŒIm’Im’Im’џЖЖIm’Im’Im’ЖIm’FiŒIm’Im’Im’0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’Im’џ0HaIm’Im’FiŒIm’ыыыџџџIm’Im’Im’Im’џ0HaIm’Im’FiŒIm’ыыыџџџIm’Im’Im’Im’џ0HaIm’Im’FiŒIm’Im’ыыыIm’Im’Im’Im’џ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’Im’џ0HaIm’ЖFiŒIm’Im’ЖIm’Im’Im’Im’џ0HaIm’ЖFiŒIm’Im’ЖIm’Im’Im’Im’џ0HaIm’ЖFiŒIm’Im’ЖIm’Im’Im’Im’0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒIm’џыыыFiŒIm’Im’ыыыџџџџџџџџџIm’FiŒIm’џыыыFiŒIm’Im’ыыыџџџџџџџџџIm’FiŒIm’џ0HaFiŒIm’Im’Im’ыыыџџџIm’Im’FiŒIm’џ0HaFiŒIm’Im’Im’FiŒЖЖЖЖЖџ0HaFiŒЖIm’Im’FiŒЖЖЖЖЖџ0HaFiŒЖIm’Im’FiŒЖЖЖЖЖџ0HaFiŒЖIm’Im’FiŒЖЖЖЖЖ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’FiŒџыыыџџџIm’FiŒыыыџџџџџџџџџIm’Im’џџџџыыыџџџIm’FiŒыыыџџџџџџџџџIm’Im’џџџџыыыIm’Im’FiŒIm’ыыыџџџIm’Im’Im’FiŒџ0HaIm’Im’FiŒIm’ЖыыыЖIm’Im’FiŒџ0HaIm’Im’ЖЖЖIm’ЖIm’Im’FiŒџ0HaIm’Im’ЖЖЖIm’ЖIm’Im’FiŒџ0HaIm’Im’ЖЖЖIm’ЖIm’Im’FiŒ0HaIm’FiŒIm’Im’Im’Im’Im’Im’Im’Im’џыыыџџџыыыыыыџџџџџџџџџџџџIm’џџџџџџџыыыџџџыыыыыыџџџџџџџџџџџџIm’џџџџџџџыыыIm’FiŒIm’ыыыџџџџџџџџџIm’Im’џџџџ0HaIm’FiŒIm’Im’Im’ыыыIm’Im’Im’Im’џ0HaIm’ЖIm’Im’Im’Im’ЖIm’Im’Im’џ0HaIm’ЖIm’Im’Im’Im’ЖIm’Im’Im’џ0HaIm’ЖIm’Im’Im’Im’ЖIm’Im’Im’0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’Im’џыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџIm’ыыыџџџџџџџџџџџџIm’ыыыџџџџыыыIm’Im’Im’Im’ыыыџџџџџџIm’Im’џџџџыыыIm’Im’ЖIm’џџџIm’ЖIm’Im’Im’џ0HaIm’џџЖIm’џџџIm’ЖIm’Im’Im’џ0HaIm’џџЖIm’џџџIm’ЖIm’Im’Im’0HaIm’Im’Im’Im’FiŒIm’Im’Im’FiŒIm’џыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџыыыџџџџџџџџџџџџџџџыыыџџџџџџџыыыџџџџџџIm’ыыыџџџџџџџџџIm’ыыыџџџџыыыIm’џџIm’Im’џџџIm’Im’Im’ыыыIm’џ0Haџџ$I’џџIm’ЖЖIm’ЖыыыIm’џ0Haџџ$I’џџIm’ЖЖIm’ЖыыыIm’џџXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАXƒАџџџџџџXƒАџџџџџџџџџџџџXƒАџџXƒАXƒАџџџџџџXƒАлџџџџџџџџџXƒАџџXƒАXƒАџџџџџџXƒАлџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’Im’FiŒIm’Im’FiŒXƒА0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’лIm’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’лIm’XƒА0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’FiŒIm’Im’Im’XƒАџ0HaЈЈџIm’ЈЈџIm’Im’FiŒлIm’Im’XƒАџ0HaЈЈџIm’ЈЈџIm’Im’FiŒлIm’Im’XƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’ЈЈџIm’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’џџIm’Im’лIm’лIm’Im’XƒАџ0HaIm’џџIm’Im’лIm’лIm’Im’XƒА0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒXƒАџ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒXƒАџ0HaFiŒIm’лIm’FiŒIm’Im’ллXƒАџ0HaЈЈџIm’ЈЈџлFiŒIm’Im’лллџ0HaЈЈџIm’ЈЈџлFiŒIm’Im’ллл0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’лIm’Im’XƒАџ0HaIm’Im’Im’лIm’Im’лIm’Im’XƒАџ0HaIm’Im’Im’лIm’Im’лIm’Im’XƒАџ0HaIm’Im’Im’лIm’Im’лIm’Im’XƒА0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’ллIm’Im’лIm’Im’XƒАџ0HaIm’Im’ллIm’Im’лIm’Im’XƒАџ0HaIm’Im’ллIm’Im’лIm’Im’XƒАџ0HaIm’Im’ллIm’Im’лIm’Im’XƒА0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’ллFiŒIm’Im’XƒАџ0HaIm’лIm’Im’ллFiŒIm’Im’XƒАџ0HaIm’лIm’Im’ллFiŒIm’Im’XƒАџ0HaIm’лIm’Im’ллFiŒIm’Im’XƒА0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaFiŒIm’Im’Im’лIm’Im’Im’Im’XƒАџ0HaллIm’Im’лIm’Im’Im’Im’XƒАџЖллIm’Im’лIm’ллIm’XƒАџЖллIm’Im’лIm’ллIm’XƒА0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’лIm’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’лIm’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’лIm’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’лIm’FiŒIm’Im’XƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџџџџ0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Ha0Haџџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’Im’Im’FiŒЖЖЖЖXƒАџ0HaIm’Im’Im’Im’FiŒЖЖЖЖXƒАџ0HaIm’Im’Im’Im’FiŒЖЖЖЖXƒАџ0HaIm’Im’Im’Im’FiŒЖЖЖЖXƒА0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’Im’Im’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’ЖIm’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’ЖIm’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’ЖIm’FiŒIm’Im’XƒАџ0HaIm’Im’Im’Im’ЖIm’FiŒIm’Im’XƒА0HaIm’Im’FiŒIm’FiŒIm’Im’Im’Im’XƒАџыыыIm’Im’FiŒIm’FiŒIm’ыыыIm’Im’XƒАџыыыIm’Im’FiŒIm’FiŒIm’ыыыIm’Im’XƒАџ0HaIm’Im’FiŒIm’FiŒIm’Im’Im’Im’XƒАџ0HaIm’Im’FiŒIm’ЖIm’Im’Im’Im’XƒАџ0HaIm’Im’FiŒЖЖIm’Im’лIm’XƒАџ0HaIm’Im’FiŒЖЖIm’Im’лIm’XƒАџ0HaIm’Im’FiŒЖЖIm’Im’лIm’XƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџыыыIm’Im’Im’Im’Im’Im’ыыыџџџIm’XƒАџыыыIm’Im’Im’Im’Im’Im’ыыыџџџIm’XƒАџ0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’ЖЖIm’Im’Im’Im’Im’XƒАџ0HaIm’Im’ЖЖIm’ЖлIm’Im’XƒАџ0HaIm’Im’ЖЖIm’ЖлџџџIm’XƒАџ0HaIm’Im’ЖЖIm’ЖлџџџIm’XƒА0HaFiŒFiŒIm’Im’Im’Im’Im’Im’Im’XƒАџыыыџџџFiŒIm’Im’Im’Im’ыыыџџџIm’XƒАџыыыџџџFiŒIm’Im’Im’Im’ыыыџџџIm’XƒАџыыыFiŒFiŒIm’Im’Im’Im’Im’Im’Im’XƒАџ0HaFiŒFiŒIm’Im’Im’Im’Im’Im’Im’XƒАџ0HaFiŒFiŒЖIm’Im’Im’Im’џџџIm’XƒАџ0HaFiŒFiŒЖIm’Im’Im’џџџЖџџџџXƒАџ0HaFiŒFiŒЖIm’Im’Im’џџџЖџџџџXƒА0HaIm’Im’Im’Im’Im’Im’Im’Im’Im’XƒАџыыыџџџIm’Im’Im’ыыыыыыџџџџџџIm’XƒАџыыыџџџIm’Im’Im’ыыыыыыџџџџџџIm’XƒАџыыыџџџIm’Im’Im’Im’Im’ыыыIm’Im’XƒАџ0HaџџџIm’Im’Im’Im’Im’Im’Im’Im’XƒАџ0HaIm’Im’ЖЖIm’Im’Im’Im’Im’XƒАџ0HaIm’Im’ЖЖIm’Im’Im’џџџIm’XƒАџ0HaIm’Im’ЖЖIm’Im’Im’џџџIm’XƒА0HaIm’FiŒIm’Im’Im’FiŒIm’Im’Im’XƒАџыыыџџџџџџџџџыыыыыыџџџџџџџџџџџџXƒАџыыыџџџџџџџџџыыыыыыџџџџџџџџџџџџXƒАџыыыџџџFiŒIm’Im’Im’ыыыџџџџџџIm’XƒАџ0HaџџџFiŒIm’Im’Im’FiŒыыыIm’Im’XƒАџ0HaџџџFiŒIm’ЖЖFiŒIm’Im’Im’XƒАџ0HaџџџлIm’ЖЖлIm’Im’Im’XƒАџ0HaџџџлIm’ЖЖлIm’Im’Im’XƒА0HaIm’Im’Im’Im’Im’FiŒFiŒIm’Im’XƒАџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџIm’ыыыџџџџџџџџџџџџXƒАџыыыџџџџџџIm’Im’Im’ыыыџџџIm’Im’XƒАџыыыџџџIm’Im’Im’Im’FiŒFiŒIm’Im’XƒАџыыыџџџIm’Im’Im’Im’FiŒллIm’XƒАџыыыџџџIm’Im’Im’Im’FiŒллIm’XƒА0HaFiŒIm’Im’Im’FiŒIm’Im’Im’FiŒXƒАџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџыыыџџџџџџџџџџџџџџџџџџџыыыџџџџџџџџџIm’FiŒыыыџџџIm’џџџXƒАџыыыџџџџџџIm’Im’FiŒыыыIm’Im’FiŒXƒАџыыыџџџџџџIm’Im’FiŒыыылIm’ллџыыыџџџџџџIm’Im’FiŒыыылIm’ллџџXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАыыыџџџџџџџџџџџџџџџџџџџџџџџџџџXƒАXƒАџџџџџџџџџXƒАџџџџџџџџџџџџџџXƒАXƒАџџџлџџџXƒАџџџџџџџџџџџџџџXƒАXƒАџџџлџџџXƒАџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџџgravitation-3+dfsg1.orig/game5/gameSource/graphics/mezSprite.tga0000644000175000017500000000065210761547350023522 0ustar pabspabsmmmmmmmmmmmm’mmmmmmmmmmmmmmmmmmџџ“M|mmmmmmmmmmmmmmmmmmџџNFџ’Жџmmmmmmmmmmmmmmmџџ’Жџ’Жџmmmmmmmmmmmmmmmџџџ’Жџmmmmmmmmmmmmmmmmmmџџџџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmџџџџџџџџmmmmmmmmmmmm’mmmmmmmmmmmmmmmmmmџџ“M|’ЖџmmmmmmmmmmmmmmmџџNFџmmmmmmmmmmmmmmmmmmџџ’Жџ’Жџmmmmmmmmmmmmmmmџџџ’Жџmmmmmmmmmmmmmmmmmmџџџџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmgravitation-3+dfsg1.orig/game5/gameSource/graphics/ball.tga0000644000175000017500000000032210761547350022444 0ustar pabspabsmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmЖЖmmmmmmmmmmmmmmmЖџџmmџmmmmmmmmmmmmЖџџџџmmџmmmmmmmmmmmmmmmmmџmmџmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmgravitation-3+dfsg1.orig/game5/gameSource/graphics/kilnFire.tga0000644000175000017500000000304110747757344023310 0ustar pabspabs /nзђnзђењўењўењўењўењўnзђењўnзђ.є.єnзђењўењўnзђ.єnзђnзђењў.є.єењўењў.є.є.єnзђ.є.єnзђењў.є.є.єnзђењўnзђ.єHЕ.єnзђnзђ.є.є.єHЕHЕџџџџџџџџџџџ.єењўењўnзђењўењўењўењўењўnзђ.єnзђnзђ.єnзђnзђењўењўnзђ.є.єnзђ.є.єnзђењўnзђnзђ.є.є.єnзђ.є.єHЕ.є.є.єHЕџџџџџџџџџџџnзђењўењўnзђењўењўењўењўењўnзђnзђ.єnзђењўnзђnзђењўењўењўењўnзђ.є.єnзђ.є.єењўnзђењўењў.є.є.єnзђ.єењўnзђ.єHЕ.єnзђењўnзђ.єnзђ.є.єHЕџџџџџџџџџџџnзђењўењўењўењўењўењўењўењўењў.є.єnзђењўењўnзђnзђ.єnзђnзђnзђ.є.єnзђењўењўnзђ.є.є.є.єnзђењў.є.є.є.єHЕgravitation-3+dfsg1.orig/game5/gameSource/backgroundLayers.xcf0000644000175000017500000002407310756173465023255 0ustar pabspabsgimp xcf fileBBI gimp-commentCreated with The GIMPgimp-image-gridў(style solid) (fgcolor (color-rgba 0.000000 0.000000 0.000000 1.000000)) (bgcolor (color-rgba 1.000000 1.000000 1.000000 1.000000)) (xspacing 1.000000) (yspacing 1.000000) (spacing-unit inches) (xoffset 0.000000) (yoffset 0.000000) (offset-unit inches) фпƒ @бb~} ["#g'd New Layer#11џ      џџџі•ЉЙчј{›Ё‚ŸЋЄѕ‘Ё™n‘zЖИ є“œœqˆwf‘ЌЋЇ є•™„ž‚o€„r є …Є•xˆris‰„їšvtu…jpnчј{›Ё‚ŸЋЄѕ‘Ё™n‘zЖИ є“œœqˆwf‘ЌЋЇ є•™„ž‚o€„r є …Є•xˆris‰„їšvtu…jpnчј{›Ё‚ŸЋЄѕ‘Ё™n‘zЖИ є“œœqˆwf‘ЌЋЇ є•™„ž‚o€„r є …Є•xˆris‰„їšvtu…jpnчџ џ џ џ џџ New Layer#10џ     џџџќˆœЌз˜ћ™›—ЂіЄЊЃЁЅЃššœ іЂЏАВГВ­Ќ  є“–š”–­ААИЖА ђŠ‹›˜žЄДЗЖЊЏ{ё‡’ks˜Ё­ЖЙЗЕГРяr{kŒŸ“pžЇВЏЕА Зђgtq€‹ƒ}{›Ё‚Ÿ їƒmgh_df‘дз˜ћ™›—ЂіЄЊЃЁЅЃššœ іЂЏАВГВ­Ќ  є“–š”–­ААИЖА ђŠ‹›˜žЄДЗЖЊЏ{ё‡’ks˜Ё­ЖЙЗЕГРяr{kŒŸ“pžЇВЏЕА Зђgtq€‹ƒ}{›Ё‚Ÿ їƒmgh_df‘дз˜ћ™›—ЂіЄЊЃЁЅЃššœ іЂЏАВГВ­Ќ  є“–š”–­ААИЖА ђŠ‹›˜žЄДЗЖЊЏ{ё‡’ks˜Ё­ЖЙЗЕГРяr{kŒŸ“pžЇВЏЕА Зђgtq€‹ƒ}{›Ё‚Ÿ їƒmgh_df‘дзџџџ џ џџџ џ џе New Layer#9џ      +?O ўŒћ‡~Ž–љ‹Š‘‹…ї†ˆ‡…†ї’–—’“‰“–і–ž˜›™Ž˜Ёšіž œœ  ЈЄ™ЃјžЁЈЈ•їЇІ  ЅЇЄїЇІЁ–  ЁіІЄЃ  ›–˜ іЄЁŸš›˜˜™›іЃŸŸЄЊЃЁЅЃѕ ЂЏАВГВ­Ќ ѕ–š”–­ААИЖАѕ›˜žЄДЗЖЊЏЊ ѕ˜Ё­ЖЙЗЕГРЙѕЇВЏЕА ЗХИЈ ѕ›Ё‚ŸЋЄЖЏЁї™n‘zЖИїœqˆwf‘ЌЋї™„ž‚o€„іm …Є•xˆriј—–švtu…ќŸlb ўŒћ‡~Ž–љ‹Š‘‹…ї†ˆ‡…†ї’–—’“‰“–і–ž˜›™Ž˜Ёšіž œœ  ЈЄ™ЃјžЁЈЈ•їЇІ  ЅЇЄїЇІЁ–  ЁіІЄЃ  ›–˜ іЄЁŸš›˜˜™›іЃŸŸЄЊЃЁЅЃѕ ЂЏАВГВ­Ќ ѕ–š”–­ААИЖАѕ›˜žЄДЗЖЊЏЊ ѕ˜Ё­ЖЙЗЕГРЙѕЇВЏЕА ЗХИЈ ѕ›Ё‚ŸЋЄЖЏЁї™n‘zЖИїœqˆwf‘ЌЋї™„ž‚o€„іm …Є•xˆriј—–švtu…ќŸlb ўŒћ‡~Ž–љ‹Š‘‹…ї†ˆ‡…†ї’–—’“‰“–і–ž˜›™Ž˜Ёšіž œœ  ЈЄ™ЃјžЁЈЈ•їЇІ  ЅЇЄїЇІЁ–  ЁіІЄЃ  ›–˜ іЄЁŸš›˜˜™›іЃŸŸЄЊЃЁЅЃѕ ЂЏАВГВ­Ќ ѕ–š”–­ААИЖАѕ›˜žЄДЗЖЊЏЊ ѕ˜Ё­ЖЙЗЕГРЙѕЇВЏЕА ЗХИЈ ѕ›Ё‚ŸЋЄЖЏЁї™n‘zЖИїœqˆwf‘ЌЋї™„ž‚o€„іm …Є•xˆriј—–švtu…ќŸlb ўџџџџџџџџџџџџџ џ џ џ џ џ џџџџџџџ  New Layer#8џ     џџџџ ш ќ Јќ„Š– ќ|‹њ‚‰ŒŒƒяw~††ˆ‡…†…’•…~эuvy„Œ’–—’“‰“–Šƒ‘šŠэ„€y†’–ž˜›™Ž˜Ёš‘—šюvy‹’™ž œœ  ЈЄ™œ“ьyxv~…ЃЃžЁЈЈ•“–э}ˆ‘’˜—™ЇІ  ЅЇЄЂž›љˆ”ž–˜Ђї–  Ё Ÿљ‡Ž”›њ›–˜ šњz†wŠ—ўwСЈќ„Š– ќ|‹њ‚‰ŒŒƒяw~††ˆ‡…†…’•…~эuvy„Œ’–—’“‰“–Šƒ‘šŠэ„€y†’–ž˜›™Ž˜Ёš‘—šюvy‹’™ž œœ  ЈЄ™œ“ьyxv~…ЃЃžЁЈЈ•“–э}ˆ‘’˜—™ЇІ  ЅЇЄЂž›љˆ”ž–˜Ђї–  Ё Ÿљ‡Ž”›њ›–˜ šњz†wŠ—ўwСЈќ„Š– ќ|‹њ‚‰ŒŒƒяw~††ˆ‡…†…’•…~эuvy„Œ’–—’“‰“–Šƒ‘šŠэ„€y†’–ž˜›™Ž˜Ёš‘—šюvy‹’™ž œœ  ЈЄ™œ“ьyxv~…ЃЃžЁЈЈ•“–э}ˆ‘’˜—™ЇІ  ЅЇЄЂž›љˆ”ž–˜Ђї–  Ё Ÿљ‡Ž”›њ›–˜ šњz†wŠ—ўwСЈџ џџ џџџџџџџџџџџўџС New Layer#7џ     џџџљџџџјyЈќ„Š– ќ|‹њ‚‰ŒŒƒяw~††ˆ‡…†…’•…~эuvy„Œ’–—’“‰“–Šƒ‘šŠэ„€y†’–ž˜›™Ž˜Ёš‘—šюvy‹’™ž œœ  ЈЄ™œ“ьyxv~…ЃЃžЁЈЈ•“–э}ˆ‘’˜—™ЇІ  ЅЇЄЂž›љˆ”ž–˜Ђї–  Ё Ÿљ‡Ž”›њ›–˜ šњz†wŠ—ўwСЈќ„Š– ќ|‹њ‚‰ŒŒƒяw~††ˆ‡…†…’•…~эuvy„Œ’–—’“‰“–Šƒ‘šŠэ„€y†’–ž˜›™Ž˜Ёš‘—šюvy‹’™ž œœ  ЈЄ™œ“ьyxv~…ЃЃžЁЈЈ•“–э}ˆ‘’˜—™ЇІ  ЅЇЄЂž›љˆ”ž–˜Ђї–  Ё Ÿљ‡Ž”›њ›–˜ šњz†wŠ—ўwСЈќ„Š– ќ|‹њ‚‰ŒŒƒяw~††ˆ‡…†…’•…~эuvy„Œ’–—’“‰“–Šƒ‘šŠэ„€y†’–ž˜›™Ž˜Ёš‘—šюvy‹’™ž œœ  ЈЄ™œ“ьyxv~…ЃЃžЁЈЈ•“–э}ˆ‘’˜—™ЇІ  ЅЇЄЂž›љˆ”ž–˜Ђї–  Ё Ÿљ‡Ž”›њ›–˜ šњz†wŠ—ўwСЈџ џџ џџџџџџџџџџџўџС New Layer#6џ      .fšў—њЉЄЄ“ѕ˜Ё–“•ЈЈЁ єЈЇŸ›žЂЄЇЅ  ѓ ЂŸŸ Ё  –Ё ѓЃЅž™šš ˜–›   ѓЄš›Ђ—›™˜˜›šŸ є—œššЃЅЁЃЊЄŸ єЂ Ќ­ВГВАЏЂіЖИАА­–”š–їЗДЄž˜›‹їЙЖ­Ё˜skјЏВЇžp“ї‚Ё›{}ƒ‹і™Ё‘fd_hgmј“tv^\]vњ‹|hulefšў—њЉЄЄ“ѕ˜Ё–“•ЈЈЁ єЈЇŸ›žЂЄЇЅ  ѓ ЂŸŸ Ё  –Ё ѓЃЅž™šš ˜–›   ѓЄš›Ђ—›™˜˜›šŸ є—œššЃЅЁЃЊЄŸ єЂ Ќ­ВГВАЏЂіЖИАА­–”š–їЗДЄž˜›‹їЙЖ­Ё˜skјЏВЇžp“ї‚Ё›{}ƒ‹і™Ё‘fd_hgmј“tv^\]vњ‹|hulefšў—њЉЄЄ“ѕ˜Ё–“•ЈЈЁ єЈЇŸ›žЂЄЇЅ  ѓ ЂŸŸ Ё  –Ё ѓЃЅž™šš ˜–›   ѓЄš›Ђ—›™˜˜›šŸ є—œššЃЅЁЃЊЄŸ єЂ Ќ­ВГВАЏЂіЖИАА­–”š–їЗДЄž˜›‹їЙЖ­Ё˜skјЏВЇžp“ї‚Ё›{}ƒ‹і™Ё‘fd_hgmј“tv^\]vњ‹|hulefџџ џ џ џ џ џ џ џџџџџџџџџf New Layer#5џ     џџџњџџџўЊОЮДћnqorљurpx|јx‰tow~†іpuuvy„Œ’–ѓtv„€y†’–ž˜›™ ѓ}vy‹’™ž œœ  їЃЃžЁЈјЇІ  ЅЇ ў˜њІЁ– љЅІЄЃ  аДћnqorљurpx|јx‰tow~†іpuuvy„Œ’–ѓtv„€y†’–ž˜›™ ѓ}vy‹’™ž œœ  їЃЃžЁЈјЇІ  ЅЇ ў˜њІЁ– љЅІЄЃ  аДћnqorљurpx|јx‰tow~†іpuuvy„Œ’–ѓtv„€y†’–ž˜›™ ѓ}vy‹’™ž œœ  їЃЃžЁЈјЇІ  ЅЇ ў˜њІЁ– љЅІЄЃ  аДџџџџ џ џџџўџџџб New Layer#4џ     џџџќ&:JnўЂј Ё ŸŸЂї–˜ šš™žЅї˜™›—Ђ›šЄѕЃЁЅЃššœ——™іГВ­Ќ Ђž›ѕАИЖА ŸЈЎЇВ єДЗЖЊЏЊЋЉВЇІјРЙЌЊžЃњИЈ—w–ћЁvœњИЏЂЋљЌЋЇœ‘qљrojsњis‰„ŒnўЂј Ё ŸŸЂї–˜ šš™žЅї˜™›—Ђ›šЄѕЃЁЅЃššœ——™іГВ­Ќ Ђž›ѕАИЖА ŸЈЎЇВ єДЗЖЊЏЊЋЉВЇІјРЙЌЊžЃњИЈ—w–ћЁvœњИЏЂЋљЌЋЇœ‘qљrojsњis‰„ŒnўЂј Ё ŸŸЂї–˜ šš™žЅї˜™›—Ђ›šЄѕЃЁЅЃššœ——™іГВ­Ќ Ђž›ѕАИЖА ŸЈЎЇВ єДЗЖЊЏЊЋЉВЇІјРЙЌЊžЃњИЈ—w–ћЁvœњИЏЂЋљЌЋЇœ‘qљrojsњis‰„Œnўџџџџ џџ џ џџџџџџџџž New Layer#3џ     џџџћ  %9Iгѕ›˜žЄДЗЖЊЏЊ ђks˜Ё­ЖЙЗЕГРЙЌэ{kŒŸ“pžЇВЏЕА ЗХИЈэgtq€‹ƒ}{›Ё‚ŸЋЄЖЏюpƒmgh_df‘Ё™n‘zЖёXev]\^vt“œœqˆw љfzluh|§UVѓгѕ›˜žЄДЗЖЊЏЊ ђks˜Ё­ЖЙЗЕГРЙЌэ{kŒŸ“pžЇВЏЕА ЗХИЈэgtq€‹ƒ}{›Ё‚ŸЋЄЖЏюpƒmgh_df‘Ё™n‘zЖёXev]\^vt“œœqˆw љfzluh|§UVѓгѕ›˜žЄДЗЖЊЏЊ ђks˜Ё­ЖЙЗЕГРЙЌэ{kŒŸ“pžЇВЏЕА ЗХИЈэgtq€‹ƒ}{›Ё‚ŸЋЄЖЏюpƒmgh_df‘Ё™n‘zЖёXev]\^vt“œœqˆw љfzluh|§UVѓг џ џџџџ џ џџє New Layer#2џ     џџџљ ЏУгв§™žј~…ЃЃђˆ‘’˜—™ЇІ  ЅЇ №ˆ”ž–˜ЂЅЇІЁ–  Ё №”›ЅІЄЃ  ›–˜ š ђ—œЃЄЁŸš›˜˜™›— ѕЃŸŸЄЊЃЁЅЃšњВГВ­Ќхв§™žј~…ЃЃђˆ‘’˜—™ЇІ  ЅЇ №ˆ”ž–˜ЂЅЇІЁ–  Ё №”›ЅІЄЃ  ›–˜ š ђ—œЃЄЁŸš›˜˜™›— ѕЃŸŸЄЊЃЁЅЃšњВГВ­Ќхв§™žј~…ЃЃђˆ‘’˜—™ЇІ  ЅЇ №ˆ”ž–˜ЂЅЇІЁ–  Ё №”›ЅІЄЃ  ›–˜ š ђ—œЃЄЁŸš›˜˜™›— ѕЃŸŸЄЊЃЁЅЃšњВГВ­Ќхвџџ џ џ џ џ џџц New Layer#1џ      !!!'=џџШџШџЈџџџШ2џџџШџ Шv=џџШџШџЈџџџШ2џџџШџ Шv=џџШџШџЈџџџШ2џџџШџ Шv=џ џџЈџџџџ2џџ џ џv New Layerџ     "Ћ"П"ЯЗџџџџџџџџЗєєєєєєєєЗyyyyyyyyЗџџџџџџџџBackground copyџ     $$'$745ў455487ў877ћ:9::99ќ:9:99:9ћ:99;<<;§<;<<;ћ<;;<;;>ў=>>ў=>>=ї>==>=>==>>ў=@@ў?@@љ?@?@@?@@?@ў?B BўABBњABABBD DўCDDўCDDќCDDFFўGF FEFHњIHIHIHHJќKJKJJўKJJўKJ JMёLMLMLLMLLMMLLMLLMLONOўNOONQPQўPQQіPQPPQPQQPS SјRSSRSSRSSўRUUўVU UўTUUљXWWXWXWWўXW WќVWYZZYўZYY\[ў\[[љ\[[\[\[[ѓ^]^]]^^]^]]^]]ћ^]^]``ў_``і_`__`_`_`__ bab§abaa§baddўcddўcdd§cdcc§dcffўgf fefўef‚§ƒ‚ƒƒ‚ƒ‚ƒќ‚ƒ‚ƒƒў‚„„ќƒ„ƒ„„ƒ„ќƒ„ƒ„„ћƒ„ƒƒ… …ў„……њ„…„……„„ў…† †…†ў…††‡ўˆ‡‡ў†‡‡ў‰ˆˆљ‡ˆŠ‰ŠŠ‰‰Š‰Š‰‹Šћ‹ŠŠ‹ŠŠо‹Š‹Œ‹Œ‹Œ‹Œ‹ŒŒ‹ŒŒ‹‹Œ‹‹ŒŒ‹‹Œ‹ŒŒŒŒŒŒјŒŽŽŽŽ§ŽŽŽќŽŽўŽўŽŽќŽў §‘’‘‘§’“’’ў“’’§“”““ў”““ў”“ “і”••””•””•””ў•””ў•””•– •ў–••ћ—–——––§—–——–ў—––˜—§˜—˜˜ў—˜˜э—˜——˜——˜—˜™˜™˜˜™˜˜™™ў˜™™ šў™ššў™šš§™š› ›ўš› ›œў›œœqзqџ Backgroundџ     ( ((/q4q‚qзgravitation-3+dfsg1.orig/game5/gameSource/score.h0000644000175000017500000000165010754104452020520 0ustar pabspabs#include #include "minorGems/graphics/Image.h" class ScoreDrawer { public: ScoreDrawer( const char *inNumeralFileName ); ~ScoreDrawer(); int getScoreHeight(); // draws score in upper-right corner of image void drawScore( Uint32 *inImage, int inWidth, int inHeight, int inScore ); // draws score in an image using a specific offset void drawScore( Uint32 *inImage, int inWidth, int inHeight, int inScore, int inXOffset, int inYOffset, int inZeroPadding = 0 ); private: Image *numeralImage; int numeralW; int numeralH; int imagePixelCount; double *numeralRed; double *numeralGreen; double *numeralBlue; Uint32 *numeralARGB; }; gravitation-3+dfsg1.orig/game5/gameSource/configure0000755000175000017500000000236610734771344021160 0ustar pabspabs#!/bin/bash # # Modification History # # 2007-December-27 Jason Rohrer # Copied/modified from Passage (gamma256) project. # while [ -z "$platformSelection" ] do echo "select platform:" echo " 1 -- GNU/Linux" echo " 2 -- MacOSX" echo " 3 -- Win32 using MinGW" echo " q -- quit" echo "" echo -n "> " read platformSelection if [ "$platformSelection" = "q" ] then exit fi # use ASCII comparison. if [[ "$platformSelection" > "3" ]] then platformSelection="" fi if [[ "$platformSelection" < "1" ]] then platformSelection="" fi done platformName="Generic" platformMakefile="generic" case "$platformSelection" in "1" ) platformName="GNU/Linux" platformMakefile="Makefile.GnuLinux" ;; "2" ) platformName="MacOSX" platformMakefile="Makefile.MacOSX" ;; "3" ) platformName="Win32 MinGW" platformMakefile="Makefile.MinGW" ;; esac rm -f Makefile.temp echo "# Auto-generated by game5/gameSource/configure for the $platformName platform. Do not edit manually." > Makefile.temp rm -f Makefile cat Makefile.temp $platformMakefile Makefile.all > Makefile rm Makefile.temp exit gravitation-3+dfsg1.orig/game5/gameSource/numeralsBlack.png0000644000175000017500000000022610750237626022531 0ustar pabspabs‰PNG  IHDR1ј„N]IDATг}Q DWїПѓыЃbPљЈiб[HZчО†<  Y+-Эйсp ћG'ПaџKЛ kMѕО~>оЏсЗтЫOТС|&2 +_ииЌCSущ*Otо=SƒёхF{œЙхЕЧЏотЊ>|њЖ^XИŸžtМlWькqц“3Љ{ќBwKWИ3mЯјЯy)%ЙЎЫэ5>Щ=+_(^ЭЅз;‡МtнODЗЗ№-3ODхrйѓ/ЭgвК—Šџx‘a {)ЅДŽv#љр_d”хмё}џћі;>fю€O€аЌ•œьLЇwЙјЈxо=›Жgy"6яДu0оHе:пцёхz-G\X“fЏ?фB$eЙхЕ•тжŸЕKьј_оkBн*IENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/blowUp.cpp0000644000175000017500000000642010755214622021212 0ustar pabspabs#include "blowUp.h" #include void blowupOntoScreen( Uint32 *inImage, int inWidth, int inHeight, int inBlowFactor, SDL_Surface *inScreen ) { int newWidth = inBlowFactor * inWidth; int newHeight = inBlowFactor * inHeight; int yOffset = ( inScreen->h - newHeight ) / 2; int xOffset = ( inScreen->w - newWidth ) / 2; // pitch is in bytes // convert to width in pixels int scanlineWidth = inScreen->pitch / 4; Uint32 *pixels = (Uint32 *)( inScreen->pixels ); // looping across the smaller image, instead of across the larger screen, // was discovered using the profiler. // an entire screen row is repeated inBlowFactor times down the screen // (as a row of pixel boxes) // Thus, we can offload a lot more work onto memcpy if we assemble one // of these rows and then memcpy it onto the screen inBlowFactor times Uint32 *screenRow = new Uint32[ newWidth ]; for( int y=0; y // these can be called once at beginning and end of app execution // since loaded graphics can be reused for multiple games void loadWorldGraphics(); void destroyWorldGraphics(); // these should be called at the beginning and end of each new game void initWorld(); void destroyWorld(); Uint32 sampleFromWorld( int inX, int inY, double inWeight = 1.0 ); // sample a rectangle from the world void sampleFromWorld( int inX, int inY, int inWidth, int inHeight, Uint32 *outDestination ); void startHeartAnimation( int inX, int inY ); void setPlayerPosition( int inX, int inY ); void setPlayerSpriteFrame( int inFrame ); char isMezOnScreen(); void hideMez(); char isMezHidden(); void getMezPosition( int *outX, int *outY ); char mezHasBall(); // true if Mez still waiting before being ready to throw ball again char mezWaiting(); void throwBall(); void getBallPosition( int *outX, int *outY ); void getBallVelocity( double *outDX, double *outDY ); void returnBallToMez(); char stepBall(); // is a prize present at a given pixel location char isPrize( int inX, int inY ); // frozen prizes block player char isBlockedByPrize( int inX, int inY ); // touches a prize and causes it to fall to bottom of world void touchPrize( int inX, int inY ); double pushPrize( int inX, int inY, double inForce ); void stepPrizes(); // push animations forward one step void stepAnimations(); int getTileWidth(); int getTileHeight(); gravitation-3+dfsg1.orig/game5/gameSource/kilnSmoke.png0000644000175000017500000000036310747763345021714 0ustar pabspabs‰PNG  IHDRWCKNКIDAT8Ы­”IУ C%^яeuбтOyX№јх@з"–}€lПзђЦ{OXч/л+б>в;ї—ЫŸ§Ыќu}:#пі‹ыя‡x НЪ|”ы?x<З=ЬS/&и'?yfYўŽ'фѕў4^Щ7цcцE_ПВžšъ—ŸGЕОœцЅЏ;§Ђ§џѕј~XОю‹yв—z­Ћјb^›џŸЙЁZВї!пјоЈч=шAx1O_\ —}IENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/map.cpp0000644000175000017500000000253410762074032020516 0ustar pabspabs#include "map.h" extern int tileH; extern int tileW; #include "GraphicContainer.h" GraphicContainer *mapContainer; void loadMapGraphics() { mapContainer = new GraphicContainer( "map.tga" ); } void destroyMapGraphics() { delete mapContainer; } char isBlocked( int inX, int inY ) { // reduce to grid coordinates int gridX = inX / tileW; int gridY = inY / tileH; // blocked outside map if( gridX < 0 || gridX >= mapContainer->mW ) { return true; } if( gridY < 0 || gridY >= mapContainer->mH ) { return true; } else { char blocked = mapContainer->mRed[ gridY * mapContainer->mW + gridX ] == 0; return blocked; } } int getMapWidth() { return mapContainer->mW * tileW; } int getMapHeight() { return mapContainer->mH * tileH; } char isPrizeStartingSpot( int inGridX, int inGridY ) { // blocked outside map if( inGridX < 0 || inGridX >= mapContainer->mW ) { return false; } if( inGridY < 0 || inGridY >= mapContainer->mH ) { return false; } else { return mapContainer->mRed[ inGridY * mapContainer->mW + inGridX ] != 0 && mapContainer->mGreen[ inGridY * mapContainer->mW + inGridX ] != 0; } } gravitation-3+dfsg1.orig/game5/gameSource/map.png0000644000175000017500000000076210762047445020531 0ustar pabspabs‰PNG  IHDR в }ЋЙIDATXУэX]oФ ‹џџ/{OЇвр„РнІIз>LкQHœ;д,~`f šqxZxкИ6nЂ[уы'Ьgтѕ+Ѕ=FіЦгўШ^†Я"{ѓKЭ92n…;2Gˆ№aјЫ<яH|јАK|КG_„=цљгјјV}:|ўJ_йЃЪ_Й7mYŸaŽ Б[OLHКФwэCР=M2Ыu&ƒ}=сЅJЬhI€ќ Ш}i З~нƒ<фш›уљдчSŸO}цk=т6KАв†`ŒT:Нжї*†iN†ЗзуPЛ39ЭjГŸ\ЦE`g‚НдcгЌЫЩюА‹y‚‡5!ЫђJј<пч*JЉПе5ы~šмчsTˆѕЦZ6ƒ•zЩьІБГRahИьП/ЕЙС?Й•ПйпвŽ]˜‹§ ШЌoа4]]Ÿє_–ПЯjъ§оHП‚(AќПрќ;ŠюMЈUtѓ—Д˜I}žѓЕк“nкМпъ;lжгЃ}‰„“S……п‚rфђ~Ы?ЗjЂ%УP™Ыq'йS?ѕ„х5Rœzњ-ЁEюшОšŠШ^‰{k1+Гpб-с6Q2џц~”=?„~КmR\iIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/title.png0000644000175000017500000000061110761041043021051 0ustar pabspabs‰PNG  IHDRcd\zPIDATxкэжБJBQ` )1Œ\\м„žЃ!к›zСЁоЂAшQЄЁЁh \@ШBШХсp=їzН7ДП‘ѓџїџџs<.ЗRізСякž.OЂЬеѓ‡лŒНоЖ &їкћ}ЇT~}=\ќЭ№"E5;=лaй†ХљйюNSП{+ЕQT“lџџ›ЊДšQтѓх&|B&фЃВd˜^Џ,ZЭЭVkвХщ]ЂфMGНљщЈТЈ>3ŸŸЬпЈд№uЇ*ЂZКЁо阏ж;ЕvЙnt—‹йxЌotgуA­н_~g‰Жˆ&ЄkB˜9'yЊuПb›7Ukїч“сбщuўMEOCЫ|2ŒЪж5FCr&ПЉџїіп<пЃxаq7љ4І[ТгЈ2FХ™B˜lХ™{ež`ЇmЛ"ЗцIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/music.png0000644000175000017500000000237210761565661021077 0ustar pabspabs‰PNG  IHDR€ƒЪШ„2СIDATxкэm’Г*…СЪR^wф:\ŒыpGоНp”4"bтsjjŠI:аєю#1ЅдЄў0киŸiп(P рЙалЊ *™ˆ Ѕx(^„р\гZѕоЖжь€rВROZЋхg№Ж7іЦ;*А"шz3ћW˜љЯљыоЙј;ќoТЙЬŸПŒiQЫOяm tјЕВ\ќў7щK+2ЕTЫџЏП8+@\ˆй‚у4Дў•А1џRRФиŸhNЏlO  C€x Lзr№„ЇkњUТ‡аИ>Ы&г![ЋЪP=о-lКўgRD‰Йˆj@( !‡ьНc# hЈOћёЂyIИШ$ўKb%" PIp%ЋIBXxђ}ѕ*‰ONЌš[8ЧЁ1л4иM‰W’н”оТЅгEjJМн\8ŽЎdтэe(р(@@†ўИ+ЂВ=:ыŠ0€UИ]ш;ПzаYЎѕtчq‘‰5э_9 Я[iдїYщчлћzе+™€QOJЕ“}gдЈпƒ]O†эdТЉіОфc лЫ—)Тѓ№ѓ`ђеQ† џ„C‹C дБŠЈ љJ‘ЏŽc§ч+О8r|ШyэK–яви–лы?gЇJ|N hŽџК3ћй™vў}Š€лэѓћџ ПJ†^)+э}]ЋА—–нЗ#Р•ЙёKљвФ„ќyмYаЖа]QДЏЇЁ№lpWDepWDe{tze{jE@Јx`LЋuТяд1шŠ дР#CWЅeЋ.к—Е‘‰Ша'Уў—ДЏo“"HAШPP_†‚ZрЎˆЪіIŠ0E@€јyAч6њ№S 6 г6ЃлТO%иЬU{2`ӘхЯ" dbujв-9Ы:Зs­РfпOСь|ШŸ$›ВEИ3­~М]i=, Еmєж#“РfгO‰ Ќў$й\€т[r§,јЖ1X 6e§?ц|^WЈ ѕ“ЄЃœGмЦ$АйїSвљ#ўШmЁЕ.ЧбеLЌ-CgA 2єyрЎˆЪішtЎЮЦ5ЧШEŠ№|ќ+<ŸŸuŽН՘vwѓpтЫ?#Л§ŸО–рє‘fГfmЃДь xgВh~ж2œlhŸкЫУ7iНБЧtї†Œ њэЎџ "гПўЕ1ьчIi­šйiы5GЎHž­ВїњSєпoШОZоРI)ЊS„0{Ѕ/1}ўг$ЅQЏŸ8kmƒаdмJVt|Г&љ™ZNц”kЏєcя e]ьО!ўM ^уc_ЎpиеS†vВš}ДG&юлkQD†І)W‰<ШH)’Tfћй˜эЗ›Л’4IБ+я"вж W‰-Sш…ЎЦ5BЃA?›PzšцyЪWж"{њ$хY‰Ўt 4M­§ФxчYј™"tЏT#м’IќGєЏы„pbkŸЁ€КЋўcIWNŠ[}оЙдШ—v~z 9q:$$йѓNMиgRн:џ8Z.ѕ.г Bg$—ig}M2є.іМ#V рЙрЎˆЪј№Wџ„˜IENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/kiln.png0000644000175000017500000000114010760405310020663 0ustar pabspabs‰PNG  IHDR)eAф6'IDAT8Ы­T=Oм@lяY{ВБc AR „"Ё“REPх Э/ pDj  L 7щBљ Škв'RhђUЄC‘R ]ЄDЙ ,[6кГ7Ц)Цчи>sgK™b=;ž}ћfvf ЮЫж]HхгоNсЏCђvыБ"“ ПЏъFс—PиП:Л=ЧјќR{qѓйoаhno—…ŠLJНЅRЋppьJиРx4тМ)ЋђFёЊ3€ЊL\2е`B‰XI ьL№хkDYƒЗFŠLj`зˆrDХJЅиџЇ'т8ЮюжWІuд•ЙжЃН1иŠL№uЦtёСњЪƒй)?р”ˆŠL>М{ѓѕ№ХЈ(§€w{ъ)ЅrlЬ:сZxб$ЪЃ5—…Г†J‰иэ9 г:у%"убќRpЖLФq|ДБ63йLs—6ez€ѓ#ъg'їюnŸпjЪп~кH§‡sѕчњњЗЧ.Џњ3“MЦЃиЛќuv*Р…пЇDT[Ыл/Ÿ'M Ž-TŸЌjTЦ:p(s­ћO3Ў ЬФ{ѓјуwлѓžффітУіюўˆл~§г*Й,Lв4ƒŽ•Ќy‹чиRRŸx{AR‹iiв{U7—…Њnф bZаБАE„в№СmxŽ-рЇъ‹чиI ~опUuУsl\ГCЗиr""§DJIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/heart.png0000644000175000017500000000020610744167324021047 0ustar pabspabs‰PNG  IHDRoДzMIDATгЅK DщўWžaj%ЙqќМI9…J_рй…и‚йШ|jh6Я›\ L~О!  †=]Y№н‡.fй+К ]вGIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/particles.h0000644000175000017500000000126610761044031021370 0ustar pabspabs#include #include "common.h" #include "Gradient.h" // uses extern int mapWidth, mapHeight for size of particle field class Particle{ public: Gradient *mGradient; double mGradientPosition; double mDeltaGradientPosition; double mFade; double mDFade; char mAdditive; double mX, mY; double mDX, mDY; }; void addParticle( Particle inParticle ); void stepParticles(); // draws particles into an image void drawParticles( double inFade, int inX, int inY, int inWidth, int inHeight, Uint32 *inImage ); gravitation-3+dfsg1.orig/game5/gameSource/backgroundBaseBlurred.png0000644000175000017500000001004310756177162024202 0ustar pabspabs‰PNG  IHDRКО† pHYs  šœtIMEи(*6Щ!ГТIDAThоН™IdIR€msK,ЙWVoгъ™ˆ$8ђ8qуO№ цЗAюќ)ФЁХ 3jfzЩЊЬЪШŒх-Θq№ШWQYU]]­~ЩццЖ}ц/ёч?џЙїОЊ*ADD$"UЭ9›"€ˆ‘™9чDd†ћћ{3++‹Хххх|>fffёоQyXUЫgDTе"ДHDtЮЉjz]зхœХ f€"KD˜Ыъ"ЂьФЬUU™й0 )Ѕqooo@ЪщDЄШ2Г"ЎЖ|(вБlЦЬо{3Ы9ЧSJ!„ЃTU5=YŒ2ЉPОN?•-ЫŒ™;8чЪgч\Ю9ч<ŽcQ­(2)8щRU3чœЫ|ЮЙiя§ДX Ц8 дuн4sЎОЈPЌ^ќSv*ѓefZCDвu]пїУ0”EХ­Хй@cŒ‡VK)•YЬ,лэ6ЅT‚e:3—P€‡QОцœЇЭŠЃЪšђAŠјЩ•%ˆЪVі0Š ђиneCq{7зu]ЂF9lyfŠоВг4_fЄЎыЂs‘uшЧCэ7˜є--Св4M9—snJЃbОbšУS”$-ZLq7m,оћтьIJ9TйsŠƒP)ЅшЊZ™Bх0ФЧq,Ё8‰.KЇp-ЫrЮ%Б'Yх' !” Э,„B`цЖmЇѓNХ‘˜E8ЅЂћЄЧО4­зы’"cьћо9Wz˜RY5%`pno„iAQVњОŸі?tY]Њ ЉA0юrV9ŽrЌRšФЬRJУ0” /—t)3etЈбb НZ,–šSт<ч,SŒ”Т6йЛœqJFfіЬŒyЌЂц\ьлu]YB3ЋЊЪ{_4šlWЖ-I)‰ˆG4е”т8 9чЂA9VŒБы:)%xЊыХЛн.чьНŸŠmб7ЦИлэЦq,СLDЅXяkaЮyЛнNuYDІL.ц˜"Лфf1eYРЬЮЙb_йзТЂs]з“OѓЃH)Љуœ+‡˜’,ЦXSŠ"х‡bЉ"хQ!-Жу‡c,_‹еЦq† ўhCўѕ—П,:?5"ŽЩЎТбWіГ;М0b€’JVcјШНјМО:с ѕ}ЏЊR@ђ:Ј‰Ш{™I}FеyыыЪ"  Љ‹У2юц6ифbD”тˆзAˆОj>hONgѓгуъИe&&ннСцYŒRёf]зЮЙ—хщЈГ!ИvЖ<›З‡1іš ]-ЫJєцaдJUJ)y&†ŒDH Fфh|;дсdН†Ц ƒUГЦ}Мд%dЧОn@sŠ1NE\жЙi9VІPЊ1#PЪе:UЙпQ/6Ž‘зщшйvБктOfјq#sQІ}Нн3эY_;8rС‘’* eЊьДж–ЖЂBг6›СИЪ‘Ѓs9M Р РŠDЁИ@P™˜|eЇ§gOячuvќнwѕъN4чKXA№ЮBВбrЉбЅ9І `­цwZЈ*бv?§h§љх]утэЊО_Й­xuР”g0ŠdЇ”у>ŒJьћ‰жKR"ЖA1.ъєщёцууЭВ Lи˜Œˆ€`JmЫcЯЧ}TPі0 ` JЃ†žBKN”I›:yŸЧИ№1Оя™^ЖМ€–#моzЧѓЉm"/Чnрaє)!РЫFъАымћБišCИчœ‡AЏžWлT>ЯкДœЧvСзicBfD›кЯЂк^ж!™CЛЄЎмб‘vЯгЩN‡м2,НyBГœR!Д™ЩдpMэdJ)gMЩЬ,%bЕСй7нЩ:ЖŒЖ@}Тс„уœЂУ!щУWЛ^dC6T@C3GкfЗ‹~­­nЭЖšNRќ юЮœЦЉРШD-PђU;t@Ётр0#B2ф ЌШй((ЌѕY’"ДvBIмОљ‘”’їОm[$юВмmqЛыQЛЪЃwЪŒЊАd9Ѓ$iUК,СxЬ|=Vd‘<-h_`Ф{ПX,ЮЯЯёХнvляzм*єdFФN‘NыGл$WCѓ"4С$(ЏЎ#€Ы4IiТsЮлнюлпџўnНAUш4зр"xЪЇЕ!й.fдхФj8Bu›`†ф|ѕеWѓљМЎыЎыЎЏЏSJЮybJQrN9чТ=ч+fBCBD5П…ЃlUcлVYЎЎЎкЖ­ЊЊ\=JQNЉм›Ф9_љ,kЋoCTБ”р Ў3 †8ŠїKАMИŸ:шaг6\1CЕЦй]j! € eƒГ,‹щЩЉЩ{йФGkжќ$в1І6@сЁЉ.тЄВњTJsQ2qТњ„"d'4S:шX pŸn6ЕшhРои§QЙ§/ПјХъ!кU<њ­ўьжЮ32!0BЁ]Љ&jдіъ54~Z­ўlі\šІ)ŒC"чйaХQA5]ЬyVQсЖю‚^oтnдœ,/x;‹' ˜™Э ўђЬт1|ЛЖџH*€Џ  зИ­†№эўpŸj1FЋ(_жнЧѕЎІXэ№X+ЁWŒn ЄЏs{=TQ)ш" Ё-$Й0,ЧЛˆљ‰ђ+ЩLzђ&nџчеХm_g%D32oЂ ‚5™ЧtЬƒ0Nю3D;nЦ7rОќюЩ}_Ћэ-s BЬŒ`BhPТБ]ЮЛЗqћf3яC•”…Ш Г0!0‹ щƒщmQ…'ѓнKn юЙНЈ‚ckЭe^sХvтр’:†ЁO  ЇОяВU АtoM7Gx<уЯŸдŸœљЫЅUK§‹gіь*u9ЫOы›чaў"ЭuˆиGџЂ›mЦЪqfДCnй7ŸЬdVгВсŸœUчsв(hŠQUљўўяs6ŽрX Аuiц#“eЅћЁљЭѓ‹џњЃЏяNМдžј“™Ь,œ ЄœГfƒ˜В8ŽQSoеЦd7VПНО „]№чГ<ці*lњєМЖе.+#43GоСБšЧдђиXъеВсzЈ§ьЩЭvжњЏsћz5УМV ЅwBГVъКЮ†Gц.€г€]D@bѓѕ}U`jЩhКОnя2tёсeD‰išЦ Zч[П7Џ#№}Џ}мwjє& ZЩИƒŠИїd7ЎeћйB"љЋ­[–дњ ЗлдGЕ7•ѓУ9йПI‘Y%H@Ÿ.чgрГТэ.…Ј!=ќф{8дu]yГ+т|ECТ›ИВ1БЪаЂ"НSжЭЭЭ!Ј7Vг7ЋШ"@*FЩ ?‘вѕƒ>ulF;АХe­8пi§шF €я{ЏuЮ1<ОQг[лЃџ7nџЭ?џъћWМЗё{ЅМЗпжX§nПMж;Й}пу‹џюVovКєz“„ш5Ї|ЗgщГг=ЗГ€||ьЯюљ:Q…вЛИ}—jБr$e6Cоэƒ>:ухід%"F„ЈйрЧpћ•X=Ќ_?šлoъЩ~ЗСЌœЮ l’…яЯэв!э‚ОиЦ.ЈйЋВ~(З/ыON§“ЅЋ…nЛєеѓсХ6=ŽеЪэŠ– zцЯf<$џг3ЗлыuЋfxлЕ_~їtQ…?}rНЈFxхО-|:ужh‡Ё#D€ee ?љqL€їчіKГ“1э[НlhFяЧэЩqMЇ пxЂЎЖБ‹j†Cњсм>ѕљIўтгњтЈн њЛ›сv›Bв>фU—п›лŸЯзŸ.кЮŠе'ЇnгЧmnЗщыћМо“л lwї7›šлvЖ‰]юьщТ-ф§Ин‡МЙюЎћUUїИь›ћМY‘вћqћ›]}ŸъxHбC†m€ ФїуіџіЫA%[AœНdМ/ЗЗЉв—”,џzobяe•ИСЗƒњ‡sћџЖ}ЖёIšIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/characterSprite.png0000644000175000017500000000064410761574426023101 0ustar pabspabs‰PNG  IHDRGЕc‘ekIDAT8Ые”=NУ@…Ÿ ЂrE…(‘ЉшIЕEфьh‘]'plDыр>{WTNПЉQhи*R0Х8о[ aЋБŸцйŸоЬišbЎУg*оОžBяэtО›ŒgŒ@ЇY.Ј8FT}6ї/Ыї…|]увщRR!’[чєРuХYрБвЦŠыjЕбННŠ.Жwr§бZБЂŽSЁтDѓ\AAг4:С_Ё`QС"џЏИЎ”ы„ЖCѓœЕУqаІ3Vиб@Юt”]Д fR]&•гA!Ў6šHаёћЧIP‰l@P•Х€р…xаC3V“ёl:пй№ц6šЩ#“JJ м$IтttЉuSj$@аЭcHVdb‡И!4ЯUœФЉ ЬџXо і&:бВЂж<џйі[Ћ>c88ŸЮFyŒПМƒ§јN№а*‘йЗh8И€Ž`Чр/Ј-%эы™ўIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/testMusicPlayer.cpp0000644000175000017500000000117310734770147023105 0ustar pabspabs#include "musicPlayer.h" #include "minorGems/system/Thread.h" #include extern void loadMusicImage( char *inTGAFileName ); extern void audioCallback( void *inUserData, Uint8 *inStream, int inLengthToFill ); int main() { // don't actually start SDL loop, because profiler can't pick // up callbacks (why not?) loadMusicImage( "music.tga" ); int length = 512; Uint8 *fakeStream = new Uint8[ length ]; for( int i=0; i<20000; i++ ) { int x = 5 + 1; x ++; audioCallback( NULL, fakeStream, length ); } } gravitation-3+dfsg1.orig/game5/gameSource/common.h0000644000175000017500000000223610761044031020670 0ustar pabspabs#ifndef COMMON_INCLUDED #define COMMON_INCLUDED #include "minorGems/graphics/Image.h" #include // reads a TGA file from the default ("graphics") folder Image *readTGA( char *inFileName ); Image *readTGA( char *inFolderName, char *inFileName ); void writeTGAFromRGBA( Uint32 *inImage, int inWidth, int inHeight, char *inFileName ); struct rgbColorStruct { double r; double g; double b; }; typedef struct rgbColorStruct rgbColor; #include "minorGems/system/endian.h" // use struct/union data type for fast // access to color components without invoking shift operator // Found in Gamasutra article about fast alpha blending #if __BYTE_ORDER == __LITTLE_ENDIAN struct ColorChannels { unsigned char b; unsigned char g; unsigned char r; unsigned char a; }; #else struct ColorChannels { unsigned char a; unsigned char r; unsigned char g; unsigned char b; }; #endif union Pixel32 { ColorChannels channels; Uint32 argbValue; }; // convert from rgbColor tp Pixel32 Pixel32 rgbColorToPixel32( rgbColor inColor ); #endif gravitation-3+dfsg1.orig/game5/gameSource/blowUp.h0000644000175000017500000000043210734770146020661 0ustar pabspabs #include #include /** * Blows an image up onto the screen using nearest neighbor (pixelated) * interpolation. */ void blowupOntoScreen( Uint32 *inImage, int inWidth, int inHeight, int inBlowFactor, SDL_Surface *inScreen ); gravitation-3+dfsg1.orig/game5/gameSource/numerals.png0000644000175000017500000000030410734770147021573 0ustar pabspabs‰PNG  IHDR1ј„N‹IDATг‘Ы Х Чш–вЈŠkШ-5PЂ…ЭСz|$ЄФhWГksVUБШп@n@`bw„XtЕџпq 0—/ސЋr•uЛ“>9lШ'Lв.• .Пц€i’†у—Ћж extern int mapWidth; extern int mapHeight; SimpleVector particleList; void addParticle( Particle inParticle ) { particleList.push_back( inParticle ); } inline int clampZero255( int inValue ) { if( inValue > 255 ) { inValue = 255; } else if( inValue < 0 ) { inValue = 0; } return inValue; } void stepParticles() { for( int i=0; imX += p->mDX; p->mY += p->mDY; p->mFade += p->mDFade; p->mGradientPosition += p->mDeltaGradientPosition; if( p->mGradientPosition < 0.0 ) { p->mGradientPosition = 0.0; } if( p->mGradientPosition > 1.0 ) { p->mGradientPosition = 1.0; } int x = (int)round( p->mX ); int y = (int)round( p->mY ); if( x < 0 || x >= mapWidth || y < 0 || y >= mapHeight || p->mFade <= 0 ) { // out of bounds or faded out // remove particleList.deleteElement( i ); i--; } if( p->mFade > 1.0 ) { // cap p->mFade = 1.0; } } } inline double clamp255( double inValue ) { if( inValue > 255 ) { inValue = 255; } return inValue; } // draws particles into an image void drawParticles( double inFade, int inX, int inY, int inWidth, int inHeight, Uint32 *inImage ) { for( int i=0; imX ); int y = (int)round( p->mY ); if( x >= inX && x < inX + inWidth && y >= inY && y < inY + inHeight ) { // particle on inImage // index to point on inImage int index = ( y - inY) * inWidth + ( x - inX ); double particleFade = inFade * p->mFade; double imageFade; if( p->mAdditive ) { imageFade = 1; } else { imageFade = 1 - particleFade; } Pixel32 particlePixel, imagePixel, blendPixel; particlePixel = rgbColorToPixel32( p->mGradient->sample( p->mGradientPosition ) ); imagePixel.argbValue = inImage[index]; // always clamp, in case we are in additive blend mode blendPixel.channels.r = (unsigned char)( clamp255( particleFade * particlePixel.channels.r + imageFade * imagePixel.channels.r ) ); blendPixel.channels.g = (unsigned char)( clamp255( particleFade * particlePixel.channels.g + imageFade * imagePixel.channels.g ) ); blendPixel.channels.b = (unsigned char)( clamp255( particleFade * particlePixel.channels.b + imageFade * imagePixel.channels.b ) ); inImage[ index ] = blendPixel.argbValue; } } } gravitation-3+dfsg1.orig/game5/gameSource/Timbre.h0000644000175000017500000000207710734770146020642 0ustar pabspabs #include class Timbre { public: /** * Constructs a timbre and fills its wavetables. * * @param inSampleRate number of samples per second. * @param inLoudness a scale factor in [0,1]. * @param inBaseFrequency the lowest note in the wave table, in Hz. * This is also the key for the major scale held in the wave table. * @param inNumWaveTableEntries the number of wavetable entries. * @param inWaveFunction a function mapping a double parameter t * to a wave height in [-1,1]. Must have a period of 2pi. */ Timbre( int inSampleRate, double inLoudness, double inBaseFrequency, int inNumWaveTableEntries, double( *inWaveFunction )( double ) ); ~Timbre(); int mNumWaveTableEntries; // mWaveTable[x] corresponds to a wave with frequency of // getFrequency(x) Sint16 **mWaveTable; int *mWaveTableLengths; }; gravitation-3+dfsg1.orig/game5/gameSource/score.cpp0000644000175000017500000000563310754104452021060 0ustar pabspabs#include "score.h" #include "common.h" #include "minorGems/util/stringUtils.h" ScoreDrawer::ScoreDrawer( const char *inNumeralFileName ) { numeralImage = readTGA( (char *)inNumeralFileName ); imagePixelCount = numeralImage->getWidth() * numeralImage->getHeight(); numeralW = numeralImage->getWidth(); numeralH = ( ( numeralImage->getHeight() + 1 ) / 10 ) - 1; numeralRed = new double[ imagePixelCount ]; numeralGreen = new double[ imagePixelCount ]; numeralBlue = new double[ imagePixelCount ]; numeralARGB = new Uint32[ imagePixelCount ]; for( int i=0; igetChannel(0)[ i ]; numeralGreen[i] = 255 * numeralImage->getChannel(1)[ i ]; numeralBlue[i] = 255 * numeralImage->getChannel(2)[ i ]; unsigned char r = (unsigned char)( numeralRed[ i ] ); unsigned char g = (unsigned char)( numeralGreen[ i ] ); unsigned char b = (unsigned char)( numeralBlue[ i ] ); numeralARGB[i] = r << 16 | g << 8 | b; } } int ScoreDrawer::getScoreHeight() { return numeralH; } void ScoreDrawer::drawScore( Uint32 *inImage, int inWidth, int inHeight, int inScore ) { drawScore( inImage, inWidth, inHeight, inScore, inWidth, 0 ); } void ScoreDrawer::drawScore( Uint32 *inImage, int inWidth, int inHeight, int inScore, int inXOffset, int inYOffset, int inZeroPadding ) { char *formatString; if( inZeroPadding > 0 ) { formatString = autoSprintf( "%%0%dd", inZeroPadding ); } else { formatString = stringDuplicate( "%d" ); } char *scoreString = autoSprintf( formatString, inScore ); delete [] formatString; int numDigits = strlen( scoreString ); int xPosition = inXOffset - numDigits * ( numeralW + 1 ); for( int i=0; iч<г49чѕz}vv6ŸЯwwwЛЎKџхœыКўЩ'ŸЬЬЬєїї[–%Ѕ@т„šІyžЇыzEОя“t!DЃб€0 Iw!DWWзъеЋ=Яsgfffnn. CQ.—3™L&“Q…1&„њEгД ШFлЖЧ1M“1–ЩdQUеЎЎ.ЫВ4M›ššВm›)Š277gY–Ђ(œsDdŒ!b† „‚РЖэ H:чмѓМ\.gYж… ‚ ˜žžюъъBDA^'Є”œѓD„”2 У\.A†===ОяыК^Џзƒ BlкД‰sEQЃбИ§ілdГйwоyGг4!ФЖmлІЇЇ Узu)ŽRJ!љдѓ<а4­н!Œs>44D0ЦЮ;Чѓ}пu]ЧqЄ”žчeГY]зЧЧЧ+•Š”в0ŒŽaЃЃЃˆHfRr‹Eг4u]'§“эГГГ…BAA™‘h'ЅdˆX(Ш(ч8ŽяћєЄ”2ŠЂ0 ]зпї-Ыš˜˜@DЫВhБыК"“Щ\Нz•sž$Н-пїIzAEŠЂa’[ У№}пї}FжЎYГЦ4M!DЉTВ,‹‚€ъ)Š"ЧqQQњ‘4 ‚Рѓ<пїУ0$9bеЊUЊЊ&iбггCБЃlPUЃ(BDQDЫЃд1 CUUзui ЯeГYв<ЯS%›ЭfГYDд4Є'ЩEѕDkв ysžЯчЃ(ЊVЋœsЪЃzНоггC/ ьЃŒŸœœBиЖнВ€QšDQtщвЅ‰‰‰jЕкh4‘JнЖm!D&“‰ЂЈ^ЏK)mл&EкˆK—.€išйl6 УЉЉ)MгrЙœЎыщ,“RъКžЫх2™Œmл•JЅ}€Z­І(J.—B(ŠВfЭšЄЃЙЎыК•JEёмћ=Ўы*ŠR(кpj‰Œ1ђКЊЊFЃZ­RтŒŽŽ ! …eг-њх?ќTЃ„ ”еЂP(LMM]О|ybbТЖmъb§§§хrYзѕооо(ŠЂ("]зНѕж[ЇЇЇ5MЋеjQ]Йr% CjжbbbbуЦ]]]ѕz§мЙs7п|sЉTвuєWUеї§Z­жггЃ(Šу8AT*UUЉƒЇ›5пО}{Л•JХВЌщщiъ6RЪ?ўи4MЧq†‡‡UUхœS—RіііR ‹ Z ,•Jдз3™ЬхЫ—“J:sц хwКЎŸ={іЎЛюJ7kЁыz­VЃцU*•Ј%-‡L›7oЖm›JјТ… q ]зчцц …x™dЂОЄ(ŠeY–eЁ„OэѓНя-jзuџMќqЧ'ї­;=;;›Ц8+ dc,ŸЯ‹EEQfggƒ шюю6M!ОGј“UoRѓIc\ т .‹l~љW}-J<јu›4ЦХв ~ьБЧО pњєщDЪРРРK/НDЏЄ’І~ЉЊЊРцABYЯѓдї<="@$Рїсє–-[nIw$Œ‹%@}фЪv†№`зН?šйпyГ ОНu"щŽєИ‚šHs) Cв\{7 †a†у8їчNq†№јЖsщюhaœ?ђ…›§?М53цy^†єЊWЊлџўЁŸ?єЙ3§П5ёпП2ЈлљО›6v›6&„p]ЗZ­FQдлл+„ ˜ UUПЌўдїХыѕпИ №ГН‡g‹E".aМ‘xfllŒФI)ER+_coбћй=–?Н“žЄ^FєL0>99ЉЊ*АxDaLAƒХ_Л%-‹R‘†*)Ѕу84o&УY–EЃ"aнЖmЦи? о‘Шz№+І1†!ЭŒ1КO0ŽGMРKdІ!EзuЧq Уиuя8ВNQ”(Š@зu8hо$|SUЕP(”Ых\.gFЙ\VU•И@YrјŸћрЄЛƒšZЙ\6 #—Ы•ЫeЂЅч\а–&3 ЩєЂiкѓ?кШŽЭ|ф,<ВхŸї<ЏZ­цѓyУ0\зЕ,ы#Ї—”B†№1Ќ?япДVžяРэFЃ‘љтХ‹хr9ЭэСъm c)˜њ|Т7‰ююnŠ=•$н“Ї8чЎыОїо{APЌOTњ8H” ›б@ йїїуў§ћ)‰hX7 ƒШьКn>Ÿ'Њ–юMW{тЉ…Q…kя‹Х"УV8’8”qЂHF_?5n?§дSЫѕвзОuЇYPУBPwт6Р‚ ЦE6›mѕЮTЋoкЙ§лOŽЄ=яaЈџ& >j§ЅЙѕ?џВкИ Пќn,§ю'G]џЋ(ву=LдЬŽ1шШэД‚џѕн€ОССA)Ѕ‚ ъt*&Fi*†††bŒзvО9пкjšЦв ІВ`МY" zƒ}iŒ›ЇhЭwšЧC‡yžїjэžІё•Цэя?ЛG6Уwў-]зMKŒБЎЎ.h4јХПN_?}єpKрОИТУ7Ÿ!>НIчмВ,v_ў 0в.N=z˜–-Бg™LцUЇigqј:^ŒcKaœЈZ{†# _\Хс•ЉЯ,†qС9wЧѓМzп!P/!‹RяеЪ]_вўЖGœsG‚ Рз^{­^ЏSч УЖЙ{vŽДњђ {(<џђчqЦ9r$Š"г4щˆёјёуЕZ дžч}ѓѓ‰ Џў`O{#ќ‹YњЅZ­ЦёиБc•J%9“!Ыƒ 8хяho~oшzxۘ(•J‹–i‡…к0tnА№тGФї{^йћЛpтФ‰ žL=Žmj,нlйRО№Т thC‡L”>ѕz]QпїUЖ-š& %ђzНN›т|>ŸЯч)›Љдщlъ7•KПЖWcš‰ bќ7љ:AИxё"mЁзЏ_пОСŽ9„Аi/нА+љРРРВ@нlAёп6n#‚ Il1PџkЅ”b Г лAфѓљ–УндЏУy Ю ‚ІiI $€И6ЈqбДњ_ф6>ёФ7ъ3€išш,4DЖY'S_%ЦLZ№„Q,љTќ(:ьКЙ?{ї“УщвoЉПХИ\w?9‚ CчЉсvSd‹}r>№пџТlZV"zћг#‚c‡fДЗiПѕ7†žЇLbИC0жЁ{zrЁŽщфЄыЯ6љО•Jх~ѓ”`И0F‹s›Е­90vћз oб~Тu]F|qл в‚HnЫlЮХbQUUк[АxХВЙMЫ8ЦшMc\0œw;2r)nЗ_щCѕІяYм7.ХmђзПNнО—_~™0ЮОёяђІuьZВhЛї™‘{Ÿ™‡ёюнЛУ0DDѓЙtRј№5Йнr9r8@ ў‰}OК„_џгУЫфі|Я9x№`PЗ‘ѕšм–дsbP хАыу6АфXтшО>†РYлШKaI%j:P< ЇСССPпwп}АћЙyЭўНPY|у7кwдkзЎMїЉŒ=ѓ­JvиE JйP?ћnaџЛДуˆѕ_ЗЗnнк ъщлтqЄ ,—лŒБж5ыІeq;Еo­! зУэд‹$аџЗ?ѓзУŸкоБSiнЗ9ЦШљџЫmќќгУзц6Фм†дlsщŠИ=/Žђ~%мžЭЧ+фі‚жИBnЇЯ]WЪэјмH0X9ЗсK7BчѓБ53лoДO<KќёЗтќЃg†лЛЩ p№+џ0œdоJЙНѓ‡;ДСуv:Ž+фЖрЏь]АыйЄоѓЅЗќ§ЖјъъїbYЏюїыючF<Ž‹gVšлsss;wюL~ЂnuмЦ“'OжjЕ 6$?э7Еqоu8>ЦІє&+…mл'kwР™љHdХљЮ“„“ЌІw`гz'ІњтBУЎЙ>n'лБ€ЎлI1Џœлџ?ѕ…;eЎšIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/Gradient.cpp0000644000175000017500000000340110761041043021463 0ustar pabspabs#include "Gradient.h" Gradient::Gradient( int inNumPoints, double *inPointAnchors, rgbColor *inPointColors ) { for( int i=0; i= inLocation ) { closestPointAbove = i+1; closestPointBelow = i; foundPoints = true; } } double positionAbove = *( mAnchors.getElement( closestPointAbove ) ); double positionBelow = *( mAnchors.getElement( closestPointBelow ) ); double spread = positionAbove - positionBelow; rgbColor colorAbove = *( mColors.getElement( closestPointAbove ) ); rgbColor colorBelow = *( mColors.getElement( closestPointBelow ) ); // avoid divide-by-zero below if( spread == 0 ) { return colorAbove; } double weightAbove = (inLocation - positionBelow) / spread; double weightBelow = (positionAbove - inLocation) / spread; rgbColor returnColor; returnColor.r = weightAbove * colorAbove.r + weightBelow * colorBelow.r; returnColor.g = weightAbove * colorAbove.g + weightBelow * colorBelow.g; returnColor.b = weightAbove * colorAbove.b + weightBelow * colorBelow.b; return returnColor; } gravitation-3+dfsg1.orig/game5/gameSource/GraphicContainer.h0000644000175000017500000000301310736002326022615 0ustar pabspabs #ifndef GRAPHIC_CONTAINER_INCLUDED #define GRAPHIC_CONTAINER_INCLUDED #include #include "common.h" #include "minorGems/graphics/Image.h" class GraphicContainer { public: GraphicContainer( char *inTGAFileName ) { Image *image = readTGA( inTGAFileName ); mW = image->getWidth(); mH = image->getHeight(); int imagePixelCount = mW * mH; mRed = new double[ imagePixelCount ]; mGreen = new double[ imagePixelCount ]; mBlue = new double[ imagePixelCount ]; mCompositePixels = new Uint32[ imagePixelCount ]; for( int i=0; igetChannel(0)[ i ]; mGreen[i] = 255 * image->getChannel(1)[ i ]; mBlue[i] = 255 * image->getChannel(2)[ i ]; mCompositePixels[i] = (int)mRed[i] << 16 | (int)mGreen[i] << 8 | (int)mBlue[i]; } delete image; } ~GraphicContainer() { delete [] mRed; delete [] mGreen; delete [] mBlue; delete [] mCompositePixels; } double *mRed; double *mGreen; double *mBlue; Uint32 *mCompositePixels; int mW; int mH; }; #endif gravitation-3+dfsg1.orig/game5/gameSource/prizeOrb.png0000644000175000017500000000015710747773646021562 0ustar pabspabs‰PNG  IHDR БВ6IDATзM‹Б ФR0 Щдд”NУ oо™*)@*ЖHF*œp€JйФrЋОVЭѓя?YjМсЅф§IENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/tileSet.png0000644000175000017500000001220010761677257021364 0ustar pabspabs‰PNG  IHDR_Ы‡йиїGIDATxкэ?hIжР_ЗЇЗ’a/X8XE—Ш|_Жсay{@ШЁ…БЬlt,L^срУЋ@ŸCyƒИу’6Rh#PпъИp#sЌ’/’"w` Ч9ѓoєцЭЋЊзЏЛчtžЦ˜QЯoКЋЊЋЋоŸzЏ"шїA=њQ}ЊL ѓcо:ѓж™ЗЮМuц­3oyыЬ[gо:ѓУwD§y(­§ў›ыЁЏ<пC}ЄЏ]&ФМ}БўеяК :kЯїшOЗЬФDЇQџЫОIкщнг_пЙмBшќт’Ц†;ыѕ€QЊs5˜^ЏЗ0ЪЛЬћOЗ=йўѓТТB7kuђCQžnжТrіzННэ o™9ƒfYЇћ&jќ|~qy~q)Ю§илоРЂРшгЃKЬЫ€gм?o'З^m=ђ–Y0eEžЇoіZ˜˜К ПЈв.Н^OЏU)ѓђлћX о@TФgя!CќЋ­GтjШ`™ГДШвТ-32YVГљє(ЯгCІћг+щ|ѕЄ›Ѕи/Ј‹UbтвйTSЏ3ƒЭ‡џ#уjЊ:#ЧДœъcСfDб™Йž5зГ&фЯ€Еяїu?@™ЏЊѓіХ:yЉМ YђсЃ(ъїпМX_{ОџіХCЮ"ƒжШvzwэљ~Зѕ%bQEEєўУG8;—ъAS№d‰3нЌхКt\ћ|7БЋтgЮtГДsx§ДvиМHэLl—;\/•k3.eКYыќтвл@ЎЏŠˆ.‚~ЈД@sЇзt=xУ hТФюЄ’ФіЖ7\Ч›ИЂ…С{QбЗмУGх!W[|ЮЎыbŒL"ь,Ў§…ŠВХtГVЧЦ<{|я7ПОSЩюГsАВ‹МОћУ€й\=Тg~~q‰ірБ3 ЗГˆrгчgяЁ ŸљњжktћWeФНSь>XюЯ€Т[цQlcІ0д j3Б;aЙнЯйœБмыZ1s=Ћ?K‰Ћš#|LSfjк•o(Уek ЛL]Θ2S*яL”ёЏЊдѕЌЉ1^ и+ђИбkЛйБЫpП•…ЙюзІЈlœ•}В #ѕЉg]‡ЈО*бК•"+*ђ$зГt&†›ЖвkрB`ž9QЅR†чпб™Идњ_ЊЕЯŠб2о$ ™Нц­’;š†тH7Ÿ ЦН`ˆIм‘Ћ?Ёбqj яі^FМ‚!Sgv~X_™˜8TФ\pГЏ@`gцzVЬ.>‹Ьѕ2JЫЧWg( ~#тГtІN|–7уW цхЗїн˜œГЋа<њa@’ˆсB—ўOeцёYФреy№_ћyžк™:ёYшlщЉсjC%B ж`4‘Ч(OїXˆb”К”2#ђŽЂяК•WjeaИ‹Ъ‹Q‚ХбZЈWИp‚;Тм…eU™XQgJeжвR˜Yњйу{Н^Џ“КхY|Зш><Боisѕˆ4Ь,-2qU–юР5žq‘?MДвЏї‘ѕ‚iчЫ0ъФОV‰ЉцЯrkхЭ"Љ0–{Mo\е ЅN Ы 8.”Ы‹™сBІ+†N™XЗЊ)Нi:ŒkЭуMЖsАKWѕЩ Ї%уззТЬHєТk—ТЄ УsъзБ3hЌRьd›O8“Ѕц^Д0#veeTІ)І!cЙW †єЃR†"љ,ŒЩОУ}UM˜™и‰ємM:3зГјГргŽЯђЏWvНFD)‘бWПЭСBTйЭŽГЌp™МHI#)e’кUY+л€бehE.w{СhdкнЅЯН Еc)уЯsЊћЁјgWqƒџУ­юр<З%‹,оуbЈЛfЏ lТXюЪ_Ё0<~†&ЃЊLЌŒлЅgмg^ЉwF8^м,А"ue Ц/+пˆ3Т3х2ф™zџ•Ю\ы<Їbe…7џ)2дJo$rˆЙжyNѓ<хљ|ЧХ№‰Zgцz–v$oџїЁђ5Цgщ{cЌгDђj5dаoegbЏ‹>П1ФЯXzŸТMОўsіzНў•Eў,В+Ё? АЬ^†„/#Ч‚ЩЎгBфФ?бџ’ho.y.ў{‘І'dpXБ3еіБ™BuГїŠђ№7ИкZ+K Џ:†ГѕтЛХкŒЫQъъtьУо_‰~AžТЭеЃХw‹ЁН~6Wn?uУЄкŒIЯzљэ§'л†ЋpM~9в3-Œ{†wђЗ/жз˜Чj$Ž~є1\SW˜Е?ілwж-ŒIЯЂнЯм„C{л˜[ШТ№3о-зxAГДШо-zн,Ђ xнўіўkbжўиѓ&z№ ПћЅLЕuƒ”ЅS<ѓЊŒзЅЇД‚љэ-љэ­њэџ^З0rмБЌП1Ќ5Ыѓ@c‚…бw sЗCLх8 с№ЎЭXю%мr E 1QћыeЅс1џљ7Ÿ*3зГT=ЋлбF>Œc‚~_БћN”ёЦUM‰СЖRЂ“тПБ0ЅїВ”Ї”ёŽжТfЄ3ж|ƒ$уŠbUeP\vыЦMє˜Dјj0Т„ЮГОAЏ ‚Œђj”2xоMmю1#бP -e\ БšЏї‚!FцС№j"ХvmFHоС|ЪT†Lo0:c Ж|unШФ•Є5W'ЈЧ(їrНš^†ŸїцNі2јЯЮ$тQ+Ёл”Bp,Lш^”€~С@ˆnРћtИЧиx™ФЋ|ъщЏ 3T>G7оѓыŘn`мšЫxƒГФKъm‘3КВЗдcxЕбWхЎМд™OHЯкЭŽqљЖ™ыYЊžЅћГѕ‘’Ы”љЊ&Чx‚Г&:0ˆxэљЙЋ,ŒєgЙБZгbм?СЅjqѕ *-СoE œ2Q}vfgbЏ<ЂЬЃуЊПЂL„ђ rcЋp!ацY#ОЊw#лбЦXv&~iЎža5…!заЖФ>QЄj+5OB‡5й9X eЁЇ`кLlŒЩЂš„jeaШ“ЧћˆЋЉq•2бмШ`Х6WpŸ$ЁŒ…‰ђNPЉС–ъt Дq‹pHUbФБОѕњеж#КWtшё4№ї[ зF3.&б] г9МљШyЁХz?САЋ13БНbPД œК=Ш§‰W„UтЊt_Ms&oSЉŽѓРxлТЫhёY^§EфgmЮXюb(ŠžПrrщq˜Ю$?ŸќГєКLћdљgјЇЫДO–ГЌ@эЉ}В џŒЬ\ЯRѕ,œeCЙ4q–EПOˆСXЇ 1hR˜ЛVwяtООѕšЖьс _шoa0 _П1ЎІУ}U™и(црєLKu„МggИŠп‹NЂNH *‚эHŸ02УшЖwIМo“WЂuѓ%Sn#ƒUr_.дBіЖ7:ьWJ — эYЬsz ™ТЪ$Мзш ЅнЪ“оаБ1РV}yaю 9Г„иЂ8y2‰x­Jз6g(- Ят;AлжGьWю“AБsА’­Žle4.ЦяЯђŽAЄ+raЏЃп‹ћГјyОяед˜„?m]љœ#–FY[щfдs”МHЁ€zŒЖ^љІ|цƒїШљƒ•вWљЯбГJ˜ЯЏJ™ЙžеРŸuMтГ&Д7єћф–ЊЭј§Yxf:ёY:ƒB&f&$†\WбiDeІь…Фœ}vFM-Іx ІхcKј*\ЯўIkJ0aƒˆскло8ћьŒ3›OџНhg’&юJ}#5 C'Рі[ыф‡Bƒ#˜Џ*УпК3:Цъ fыfLЭќЪЏЖ•&tсљEuœИ=БЛ/Oh'ГPк4nB&Ё‰Y€n)j,‘CШчэe,їЂ•{tžа†˜V6Ÿ ЛВˆ !†7G)3В3]hП`н’P‰ЁЦоNnaПР/;+Єšв РЅgdpљуцъQžЇ˜ЯТ№x.‰У–0+oЦF§^–ђlЎaЪMEеhШXwтЅeк4XИc…сyCŒЙН*.Р‡Ќ0дGмЌ"&V\HЁв7d,їЂ?љƒU™Эе#r]!Cљ.ŒŒ5Я)-PoЮXю5&/<qˆ]5tfЎgќYЁcŸѕИЊкŒх^уbМy™ьŒ?тк;ЁŠИЊz ЪНHЊф3QˆЁh!JŒ'Q„ ‘Цj9%‡L†КёwПџQѓЖ†Тр ƒ1|$1iЁ<з<пbЗ*SIкЎz(M)М8Ір^Г:“„7Х% Э™аН\„…ЁŽуexўДJLЌШizzЯ 1Јћ•В”ЁDg!&ЯгL\UЛ™CОPЩ›^‚ё††Я*ќрuЯ„ЫjјО]€%pДEœ_\z˜;&&g ЕЂЋЮ„!вЫрлсePт і;SAЯš уf‘lШgБЮЬѕЌў,˜]|–gч,#œP!†ЖФђЦg…˜’|ƒ3‰ЯТƒђ’YšчD3•“ч БWШ ѕ“ Ььѓ К,!LcК;ьuƒс1”‰=ФРЩPіЃ №ЅLPGŸhтAзKAЅtН:|uїF‚% Lьч—ю*—ёЪD^&Э оŽужЪе˜†zВз#v“ЃMЙUС&ЎхМ!ЬћХ?гѓTjea€Ѕуn<…špf~,Юб]Х…С уe‚бkCћuЦ}ИЁШ4 CЕ1ЪQ—сћgqfdбd-&i2|4qћщ€/иЬЯ€Јв™ИдЃф5Pєz==Ѓ …РЊmЎˆ*Л‹‘’оK#упШ9Р$B'фCВwžЛуWf\їтљ+јš@ž †л€ŒLО]kйGьбБмЫТшzVmfЎg5№g‹Я ,жiьŒwпЋЉ1Б%пЈ№UбyсР22юѕCIб$JcdШлЁ38еcbЫЛM0НТ&7‹G)#тГ# Šт‘ф‰ жJg,з 1жœq"ИœРИШ[ЪxubИТС MНЇоэf-.‘GaМLЌ8о-žФZwaaмJ†ž›ЋU•к ИздЏg–]Чe*ьŸ…K>Н‘y•§^ТWUŸedx к™jћg‰„”Ех^ЂЌJ\gœќѕ…и‹/ІД3‰ђl•ёhњŒWK"gNiјzŒS<Ё•qv†Џ—№2|ѕХ$-ЏЛwўš&cœO'ЧФp§Y\<› ѓџљ7јnWGхIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/numerals3.png0000644000175000017500000000022010734770147021653 0ustar pabspabs‰PNG  IHDR'EweШWIDATг1!gЩ§џЫk/RXЉ8Ю"В HT5эJр™;^м\пb{т’ш4JомaЉ] §MiQЪц>ю4†h˜ЦіIšИј9ГЖЛfbвИЄ\IENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/musicPlayer.h0000644000175000017500000000050110734770147021704 0ustar pabspabs // starts playing music, reading notes from a TGA graphics file // the file must be in the "music" directory void startMusic( char *inTGAFileName ); // set loudness in range [0.0,1.0] void setMusicLoudness( double inLoudness ); // causes music to jump back to beginning void restartMusic(); void stopMusic(); gravitation-3+dfsg1.orig/game5/gameSource/Makefile.all0000644000175000017500000000436310762046604021452 0ustar pabspabs ROOT_PATH = ../.. COMPILE = g++ ${PLATFORM_COMPILE_FLAGS} -Wall -g -I${ROOT_PATH} -c LINK = g++ -I${ROOT_PATH} MG_PATH = ${ROOT_PATH}/minorGems MINOR_GEMS_SOURCES = \ ${MG_PATH}/io/file/${PLATFORM_PATH}/Path${PLATFORM_NAME}.cpp \ ${MG_PATH}/util/stringUtils.cpp \ ${MG_PATH}/util/StringBufferOutputStream.cpp \ ${MG_PATH}/util/SettingsManager.cpp \ ${MG_PATH}/system/${TIME_PLATFORM_PATH}/Time${TIME_PLATFORM_NAME}.cpp \ ${MG_PATH}/system/${PLATFORM_PATH}/Thread${PLATFORM_NAME}.cpp \ MINOR_GEMS_OBJECTS = ${MINOR_GEMS_SOURCES:.cpp=.o} GAME_SOURCES = \ game.cpp \ blowUp.cpp \ World.cpp \ map.cpp \ particles.cpp \ Gradient.cpp \ common.cpp \ score.cpp \ musicPlayer.cpp \ Timbre.cpp \ Envelope.cpp \ GAME_GRAPHICS = \ graphics/map.tga \ graphics/tileSet.tga \ graphics/background.tga \ graphics/characterSprite.tga \ graphics/mezSprite.tga \ graphics/ball.tga \ graphics/prize.tga \ graphics/prizeOrb.tga \ graphics/numeralsBlack.tga \ graphics/numerals.tga \ graphics/numeralsYellow.tga \ graphics/heart.tga \ graphics/mad.tga \ graphics/kiln.tga \ graphics/kilnFire.tga \ graphics/kilnSmoke.tga \ graphics/kilnAshPit.tga \ graphics/title.tga \ music/music.tga \ GAME_OBJECTS = ${GAME_SOURCES:.cpp=.o} # auto-generate dependency list DEPENDENCY_FILE = Makefile.dependencies all: Gravitation ${GAME_GRAPHICS} ${DEPENDENCY_FILE} clean: rm *.o graphics/*.tga music/*.tga Gravitation ${DEPENDENCY_FILE} Gravitation: ${GAME_OBJECTS} ${MINOR_GEMS_OBJECTS} ${LINK} -o Gravitation ${GAME_OBJECTS} ${MINOR_GEMS_OBJECTS} ${PLATFORM_LINK_FLAGS} testMusicPlayer: ${GAME_OBJECTS} testMusicPlayer.o common.o Timbre.o Envelope.o ${MINOR_GEMS_OBJECTS} ${LINK} -o testMusicPlayer musicPlayer.o testMusicPlayer.o common.o Timbre.o Envelope.o ${MINOR_GEMS_OBJECTS} ${PLATFORM_LINK_FLAGS} # build the dependency file ${DEPENDENCY_FILE}: ${MINOR_GEMS_SOURCES} ${GAME_SOURCES} rm -f ${DEPENDENCY_FILE} ${COMPILE} -MM ${MINOR_GEMS_SOURCES} ${GAME_SOURCES} >> ${DEPENDENCY_FILE} include ${DEPENDENCY_FILE} # # Generic: # # Map all .cpp C++ and C files into .o object files # # $@ represents the name.o file # $< represents the name.cpp file # .cpp.o: ${COMPILE} -o $@ $< .c.o: ${COMPILE} -o $@ $< graphics/%.tga: %.png convert $< $@ music/%.tga: %.png convert $< $@ gravitation-3+dfsg1.orig/game5/gameSource/Envelope.cpp0000644000175000017500000000545710734770146021535 0ustar pabspabs#include "Envelope.h" #include // #include Envelope::Envelope( double inAttackTime, double inDecayTime, double inSustainLevel, double inReleaseTime, int inMaxNoteLengthInGridSteps, int inGridStepDurationInSamples ) : mNumComputedEnvelopes( inMaxNoteLengthInGridSteps ), mEvelopeLengths( new int[ inMaxNoteLengthInGridSteps ] ), mComputedEnvelopes( new double*[ inMaxNoteLengthInGridSteps ] ) { for( int i=0; i 0 ); mComputedEnvelopes[i][s] = t / inAttackTime; } else if( t < inAttackTime + inDecayTime ) { // assert( inDecayTime > 0 ); // decay down to sustain level mComputedEnvelopes[i][s] = ( 1.0 - inSustainLevel ) * ( inAttackTime + inDecayTime - t ) / ( inDecayTime ) + inSustainLevel; } else if( 1.0 - t > inReleaseTime ) { mComputedEnvelopes[i][s] = inSustainLevel; } else { if( inReleaseTime > 0 ) { mComputedEnvelopes[i][s] = inSustainLevel - inSustainLevel * ( inReleaseTime - ( 1.0 - t ) ) / inReleaseTime; } else { // release time 0 // hold sustain until end mComputedEnvelopes[i][s] = inSustainLevel; } } } // test code to output evelopes for plotting in gnuplot if( false && i == 0 ) { FILE *file = fopen( "env0.txt", "w" ); for( int s=0; s #include #include #include #include // for memcpy #include // let SDL override our main function with SDLMain #include // must do this before SDL include to prevent WinMain linker errors on win32 int mainFunction( int inArgCount, char **inArgs ); int main( int inArgCount, char **inArgs ) { return mainFunction( inArgCount, inArgs ); } #include #include "blowUp.h" #include "World.h" #include "map.h" #include "Gradient.h" #include "particles.h" #include "score.h" #include "common.h" #include "musicPlayer.h" #include "minorGems/system/Time.h" #include "minorGems/system/Thread.h" #include "minorGems/util/stringUtils.h" #include "minorGems/util/SettingsManager.h" #include "minorGems/util/random/StdRandomSource.h" StdRandomSource randSource; // size of game image int width = 99; int height = 90; ScoreDrawer *scoreDrawer; // area above game image for score int scoreHeight = 5; double totalTime = 480.0; double timeLeft = totalTime; ScoreDrawer *timeLeftDrawer; // size of game image plus scoreboard at top and time board at bottom int totalImageHeight = height + scoreHeight + scoreHeight; // size of screen for fullscreen mode int screenWidth = 640; int screenHeight = 480; //int screenWidth = 100; //int screenHeight = 16; // blow-up factor when projecting game onto screen // Max defined by image size vs screen size. // This is the cap for in-game user-directed blowup adjustment. int maxBlowUpFactor; // current blow-up setting int blowUpFactor; // step to take when user hits blowUp key int blowUpStep = -1; // flag to force update of entire screen int blowUpChanged = true; char fullScreen = true; // lock down to 15 fps int lockedFrameRate = 15; // target length of game int gameTime = 8 * 60; //int gameTime = 30; // timeLeft that passes per frame double timeDelta = - ( timeLeft / ( gameTime * lockedFrameRate ) ); //double timeDelta = -0.0; // the joystick to read from, or NULL if there's no available joystick SDL_Joystick *joystick; // catch an interrupt signal void catch_int(int sig_num) { printf( "Quiting...\n" ); SDL_Quit(); exit( 0 ); signal( SIGINT, catch_int ); } char getKeyDown( int inKeyCode ) { SDL_PumpEvents(); Uint8 *keys = SDL_GetKeyState( NULL ); return keys[ inKeyCode ] == SDL_PRESSED; } char getHatDown( Uint8 inHatPosition ) { if( joystick == NULL ) { return false; } SDL_JoystickUpdate(); Uint8 hatPosition = SDL_JoystickGetHat( joystick, 0 ); if( hatPosition & inHatPosition ) { return true; } else { return false; } } int joyThreshold = 25000; char getJoyPushed( Uint8 inHatPosition ) { Sint16 x = SDL_JoystickGetAxis(joystick, 0); Sint16 y = SDL_JoystickGetAxis(joystick, 1); switch( inHatPosition ) { case SDL_HAT_DOWN: return y > joyThreshold; break; case SDL_HAT_UP: return y < -joyThreshold; break; case SDL_HAT_LEFT: return x < - joyThreshold; break; case SDL_HAT_RIGHT: return x > joyThreshold; break; default: return false; } } // returns true if hit, returns false if user quits before hitting char waitForKeyOrButton() { SDL_Event event; while( true ) { while( SDL_WaitEvent( &event ) ) { switch( event.type ) { case SDL_JOYHATMOTION: case SDL_JOYBUTTONDOWN: case SDL_JOYBUTTONUP: case SDL_KEYDOWN: case SDL_KEYUP: return true; break; // watch for quit event case SDL_QUIT: return false; break; default: break; } } } return false; } Uint32 *gameImage; // flips back buffer onto screen (or updates rect) void flipScreen( SDL_Surface *inScreen ) { // unlock the screen if necessary if( SDL_MUSTLOCK( inScreen ) ) { SDL_UnlockSurface( inScreen ); } if( ( inScreen->flags & SDL_DOUBLEBUF ) == SDL_DOUBLEBUF ) { // need to flip buffer SDL_Flip( inScreen ); } else if( !blowUpChanged ) { // just update center // small area in center that we actually draw in, black around it int yOffset = ( inScreen->h - totalImageHeight * blowUpFactor ) / 2; int xOffset = ( inScreen->w - width * blowUpFactor ) / 2; SDL_UpdateRect( inScreen, xOffset, yOffset, width * blowUpFactor, totalImageHeight * blowUpFactor ); } else { // update the whole thing SDL_UpdateRect( inScreen, 0, 0, inScreen->w, inScreen->h ); // reset flag blowUpChanged = false; } } void lockScreen( SDL_Surface * inScreen ) { // check if we need to lock the screen if( SDL_MUSTLOCK( inScreen ) ) { if( SDL_LockSurface( inScreen ) < 0 ) { printf( "Couldn't lock screen: %s\n", SDL_GetError() ); } } } void flipGameImageOntoScreen( SDL_Surface *inScreen ) { if( blowUpChanged && ( inScreen->flags & SDL_DOUBLEBUF ) == SDL_DOUBLEBUF ) { // blow up size has changed, and we are double-buffered // flip onto screen an additional time. // This will cause us to black-out the background in both buffers. lockScreen( inScreen ); // when blow-up factor changes: // clear screen to prepare for next draw, // which will be bigger or smaller SDL_FillRect( inScreen, NULL, 0x00000000 ); blowupOntoScreen( gameImage, width, totalImageHeight, blowUpFactor, inScreen ); flipScreen( inScreen ); } lockScreen( inScreen ); if( blowUpChanged ) { SDL_FillRect( inScreen, NULL, 0x00000000 ); } blowupOntoScreen( gameImage, width, totalImageHeight, blowUpFactor, inScreen ); flipScreen( inScreen ); // we've handled any blow up change blowUpChanged = false; } SDL_Surface *screen = NULL; // play a complete game, from title screen to end, on screen // returns false if player quits char playGame(); void createScreen() { if( screen != NULL ) { // destroy old one first SDL_FreeSurface( screen ); } int displayW = width * blowUpFactor; int displayH = totalImageHeight * blowUpFactor; Uint32 flags = SDL_HWSURFACE | SDL_DOUBLEBUF; if( fullScreen ) { flags = flags | SDL_FULLSCREEN; // use letterbox mode in full screen displayW = screenWidth; displayH = screenHeight; } printf( "Creating %dx%d screen for a %dx%d game image\n", displayW, displayH, width * blowUpFactor, totalImageHeight * blowUpFactor ); screen = SDL_SetVideoMode( displayW, displayH, 32, flags ); if ( screen == NULL ) { printf( "Couldn't set %dx%dx32 video mode: %s\n", displayW, displayH, SDL_GetError() ); } } int mainFunction( int inArgCount, char **inArgs ) { // let catch_int handle interrupt (^c) signal( SIGINT, catch_int ); Uint32 initFlags = SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_NOPARACHUTE; #ifdef __mac__ // SDL_Init is dreadfully slow if we try to init JOYSTICK on MacOSX // not sure why---maybe it's searching all devices or something like // that. // Couldn't find anything online about this. initFlags = SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE; #endif if( SDL_Init( initFlags ) < 0 ) { printf( "Couldn't initialize SDL: %s\n", SDL_GetError() ); return -1; } SDL_ShowCursor( SDL_DISABLE ); // read screen size from settings char widthFound = false; int readWidth = SettingsManager::getIntSetting( "screenWidth", &widthFound ); char heightFound = false; int readHeight = SettingsManager::getIntSetting( "screenHeight", &heightFound ); if( widthFound && heightFound ) { // override hard-coded defaults screenWidth = readWidth; screenHeight = readHeight; } printf( "Screen dimensions for fullscreen mode: %dx%d\n", screenWidth, screenHeight ); // set maxBlowUpFactor here, since screenWidth and screenHeight may // have changed from default // don't assume w > height if( width >= totalImageHeight ) { maxBlowUpFactor = screenWidth / width; } else { maxBlowUpFactor = screenHeight / totalImageHeight; } // default to max blowUpFactor = maxBlowUpFactor; char fullscreenFound = false; int readFullscreen = SettingsManager::getIntSetting( "fullscreen", &fullscreenFound ); if( fullscreenFound ) { fullScreen = readFullscreen; } printf( "Starting game in " ); if( fullScreen ) { printf( "fullscreen" ); } else { printf( "windowed" ); } printf( " mode.\n" ); createScreen(); // try to open joystick int numJoysticks = SDL_NumJoysticks(); printf( "Found %d joysticks\n", numJoysticks ); if( numJoysticks > 0 ) { // open first one by default joystick = SDL_JoystickOpen( 0 ); if( joystick == NULL ) { printf( "Couldn't open joystick 0: %s\n", SDL_GetError() ); } int numHats = SDL_JoystickNumHats( joystick ); if( numHats <= 0 ) { printf( "No d-pad found on joystick\n" ); SDL_JoystickClose( joystick ); joystick = NULL; } } else { joystick = NULL; } #ifdef __mac__ // make sure working directory is the same as the directory // that the app resides in // this is especially important on the mac platform, which // doesn't set a proper working directory for double-clicked // app bundles // arg 0 is the path to the app executable char *appDirectoryPath = stringDuplicate( inArgs[ 0 ] ); printf( "Mac: app path %s\n", appDirectoryPath ); char *appNamePointer = strstr( appDirectoryPath, "Gravitation.app" ); if( appNamePointer != NULL ) { // terminate full app path to get parent directory appNamePointer[0] = '\0'; printf( "Mac: changing working dir to %s\n", appDirectoryPath ); chdir( appDirectoryPath ); } delete [] appDirectoryPath; #endif // load graphics only once, after setting current working dir, if needed scoreDrawer = new ScoreDrawer( "numerals.tga" ); timeLeftDrawer = new ScoreDrawer( "numeralsYellow.tga" ); loadMapGraphics(); loadWorldGraphics(); setMusicLoudness( 0 ); startMusic( "music.tga" ); // keep playing until player quits while( playGame() ) { } stopMusic(); destroyWorldGraphics(); destroyMapGraphics(); delete scoreDrawer; delete timeLeftDrawer; if( joystick != NULL ) { SDL_JoystickClose( joystick ); } SDL_Quit(); return 0; } char isBlockedOrPrize( int inX, int inY ) { return isBlocked( inX, inY ) || isBlockedByPrize( inX, inY ); } int score = 0; // 1 = manic // 0 = depressed double playerEmotion = 0.4; // change in player emotion per frame //double defaultDeltaPlayerEmotion = -0.0005; double defaultDeltaPlayerEmotion = -0.0010; double deltaPlayerEmotion = defaultDeltaPlayerEmotion; // used during natural depression recovery double upswingDeltaPlayerEmotion = 0; // upswing 2 times faster that base downswing rate // ** Actually, since downswing rate increased, these rates are now equal // thus, if you're stuck away from catch-with-Mez, you don't spend // the rest of the game waiting for the natural upswing to complete //double defaultUpswingAmount = 0.0010; double defaultUpswingAmount = 0.0010; // used to adjust player motion smoothly toward a target value // (to avoid abrupt jumps in emotion) // -1 means no current target double playerEmotionSmoothTransitionTarget = -1; double smoothTransitionDelta = 0.02; // gradient used for hair fire double fireGradientAnchors[4] = { 0.0, 0.3333, 0.6666, 1.0 }; rgbColor fireGradientColors[4] = { { 0.71, 0.28, 0.06 }, { 0.96, 0.55, 0.18 }, { 0.95, 0.84, 0.43 }, { 1.0, 0.98, 0.84 } }; Gradient fireGradient( 4, fireGradientAnchors, fireGradientColors ); char playGame() { // true == right char playerFacing = true; char playerPushing = false; int currentSpriteIndex = 2; double playerX, playerY; playerEmotion = 0.4; deltaPlayerEmotion = defaultDeltaPlayerEmotion; upswingDeltaPlayerEmotion = 0; timeLeft = totalTime; double maxPlayerX = 0; score = 0; initWorld(); // room at top for score int totalGameImagePixels = width * totalImageHeight; gameImage = new Uint32[ totalGameImagePixels ]; int i; // fill with black for( i=0; igetWidth() * titleImage->getHeight(); double *titleRed = titleImage->getChannel( 0 ); double *titleGreen = titleImage->getChannel( 1 ); double *titleBlue = titleImage->getChannel( 2 ); Uint32 *titlePixels = new Uint32[ numTitlePixels ]; for( int i=0; i= getMapHeight() ) { startScreenY -= ( startScreenY + height ) - getMapHeight(); } sampleFromWorld( startScreenX, startScreenY, width, height, // skip scoreboard &( gameImage[ scoreHeight * width ] ) ); // draw particle layer, using emotion as fade factor // only draw them when emotions > 0.9 if( playerEmotion >= 0.9 ) { drawParticles( ( playerEmotion - 0.9 ) / 0.1, startScreenX, startScreenY, width, height, // skip scoreboard &( gameImage[ scoreHeight * width ] ) ); } // draw black, except clear box around player, depending on emotion Uint32 *gameImageAfterScoreboard = &( gameImage[ scoreHeight * width ] ); // int borderWidth = (int)( 40 - playerEmotion * 40 ); double clearRadius = 10 + playerEmotion * 40; double clearCenterX = (int)playerX; double clearCenterY = (int)playerY - startScreenY - 4; // prevent clear box from going off edge of screen if( clearCenterX - clearRadius < 0 ) { clearCenterX = clearRadius; } if( clearCenterX + clearRadius > width - 1 ) { clearCenterX = width - 1 - clearRadius; } if( clearCenterY - clearRadius < 0 ) { clearCenterY = clearRadius; } if( clearCenterY + clearRadius > height - 1 ) { clearCenterY = height - 1 - clearRadius; } for( int y=0; y= clearCenterY ) { distY = y - clearCenterY; } else { distY = clearCenterY - y; } for( int x=0; x= clearCenterX ) { distX = x - clearCenterX; } else { distX = clearCenterX - x; } double maxDist = distY; if( maxDist < distX ) { maxDist = distX; } if( maxDist > clearRadius + 1 ) { gameImageAfterScoreboard[ index ] = 0; } else if( maxDist > clearRadius ) { // fuzzy border to smooth transitions as border changes double fuzzFactor = 1.0 - ( maxDist - clearRadius ); if( fuzzFactor < 1.0 ) { // right on border // darken according to fuzz factor Uint32 pixel = gameImageAfterScoreboard[ index ]; int r = pixel >> 16 & 0xFF; int g = pixel >> 8 & 0xFF; int b = pixel & 0xFF; r = (int)( r * fuzzFactor ); g = (int)( g * fuzzFactor ); b = (int)( b * fuzzFactor ); gameImageAfterScoreboard[ index ] = r << 16 | g << 8 | b; } } } } // center above/below kiln int scoreX = 86; scoreDrawer->drawScore( gameImage, width, height, score, scoreX, 0, // zero pad to keep centered 3 ); // now draw remaining fire time at bottom of screen int timerY = totalImageHeight - scoreHeight + 1; // zero padded, so we don't need to worry about covering up old // digits as our count shrinks timeLeftDrawer->drawScore( gameImage, width, height, (int)timeLeft, scoreX, timerY, // zero pad 3 ); if( gameOver ) { // fade to title screen double titleWeight = titleFadeFrame / (double)( numTitleFadeFrames - 1 ); // now that we hold title after fade, titleFadeFrame will // eventually be larger than numTitleFadeFrames // Don't let titleWeight go over 1 if( titleWeight > 1 ) { titleWeight = 1; } double gameWeight = 1 - titleWeight; // wipe from left to right during fade // int wipePosition = (int)( titleWeight * width ); // don't wipe int wipePosition = width; // fade out music while we do it // music already faded out during last 5th of game // setMusicLoudness( 1.0 - titleWeight ); for( i=0; i> 16 & 0xFF; unsigned char gameGreen = gamePixel >> 8 & 0xFF; unsigned char gameBlue = gamePixel & 0xFF; Uint32 titlePixel = titlePixels[i]; unsigned char titleRed = titlePixel >> 16 & 0xFF; unsigned char titleGreen = titlePixel >> 8 & 0xFF; unsigned char titleBlue = titlePixel & 0xFF; unsigned char red = (unsigned char)( gameWeight * gameRed + titleWeight * titleRed ); unsigned char green = (unsigned char)( gameWeight * gameGreen + titleWeight * titleGreen ); unsigned char blue = (unsigned char)( gameWeight * gameBlue + titleWeight * titleBlue ); int x = i % width; if( x <= wipePosition ) { gameImage[i] = red << 16 | green << 8 | blue; } } titleFadeFrame ++; if( titleFadeFrame == numTitleFadeFrames + numTitleHoldFrames ) { done = true; } } flipGameImageOntoScreen( screen ); // done with frame double newTimestamp = Time::getCurrentTime(); double frameTime = newTimestamp - lastFrameTimeStamp; double extraTime = 1.0 / lockedFrameRate - frameTime; if( extraTime > 0 ) { Thread::staticSleep( (int)( extraTime * 1000 ) ); } // start timing next frame lastFrameTimeStamp = Time::getCurrentTime(); int moveDelta = 1; if( getKeyDown( SDLK_b ) ) { // adjust blowup factor blowUpFactor += blowUpStep; if( blowUpFactor > maxBlowUpFactor ) { blowUpStep *= -1; blowUpFactor = maxBlowUpFactor - 1; } if( blowUpFactor < 1 ) { blowUpStep *= -1; blowUpFactor = 2; } if( fullScreen ) { // force redraw of whole screen blowUpChanged = true; } else { // create a new screen using the new size createScreen(); } } if( getKeyDown( SDLK_f ) ) { // toggle fullscreen mode fullScreen = ! fullScreen; // create a new screen surface (and destroy old one) createScreen(); } playerPushing = false; if( getKeyDown( SDLK_LEFT ) || getJoyPushed( SDL_HAT_LEFT ) ) { char notBlocked = !isBlockedOrPrize( (int)( playerX - 2 - moveDelta ), (int)playerY ) && !isBlockedOrPrize( (int)( playerX - 2 - moveDelta ), (int)playerY - 7 ); if( notBlocked ) { playerX -= moveDelta; if( playerX < 0 ) { // undo playerX += moveDelta; } else { // update screen position //dX -= moveDelta; // pick sprite frame based on position in world if( ( (int)playerX / 2 ) % 2 == 0 ) { currentSpriteIndex = 6; } else { currentSpriteIndex = 7; } // left playerFacing = false; } } // don't ever need to show pushing animations to left, // since we can only push prizes right. } else if( getKeyDown( SDLK_RIGHT ) || getJoyPushed( SDL_HAT_RIGHT )) { char pushingPrize = false; // push a prize if there is one // push harder if emotion > 0.90 (in mania) // Thus, in full mania, we can push 4 blocks as easily as 1 // plus, we can push a single block twice as fast // (Blocks never slide more than 1 pixel per frame, // but their base rate is 0.5 pixels per frame.) double extraForce = 0; if( playerEmotion > 0.90 ) { extraForce = 4 * ( ( playerEmotion - 0.90) / 0.10 ); } double moveAmount = pushPrize( (int)( playerX + 1 + moveDelta ), (int)playerY, 0.5 + extraForce ); if( moveAmount > 0 ) { pushingPrize = true; } // now check if we're blocked char notBlocked = !isBlockedOrPrize( (int)( playerX + 1 + moveDelta ), (int)playerY ) && !isBlockedOrPrize( (int)( playerX + 1 + moveDelta ), (int)playerY - 7); if( notBlocked ) { //dX += moveDelta; playerX += moveDelta; // pick sprite frame based on position in world if( ( (int)playerX / 2 ) % 2 == 0 ) { currentSpriteIndex = 3; } else { currentSpriteIndex = 2; } // right playerFacing = true; } // only show pushing animation if we're blocked by a prize // or pushing a prize (i.e., not when we're pushing // against a wall) char blockedByPrize = isBlockedByPrize( (int)( playerX + 1 + moveDelta ), (int)playerY ) || isBlockedByPrize( (int)( playerX + 1 + moveDelta ), (int)playerY - 7); if( blockedByPrize || pushingPrize ) { // pushing against something, or a prize is moving // out of our way // pick sprite frame based on position in world if( ( (int)playerX ) % 2 == 0 ) { currentSpriteIndex = 0; } else { currentSpriteIndex = 1; } playerPushing = true; } } else { // not moving // switch to standing sprite if( playerFacing ) { currentSpriteIndex = 3; } else { currentSpriteIndex = 7; } } // character can move up with upward velocity if unblocked char notBlockedUp = !isBlockedOrPrize( (int)playerX - 2, (int)( playerY - 7 - moveDelta ) ) && !isBlockedOrPrize( (int)playerX + 1, (int)( playerY - 7 - moveDelta ) ); if( notBlockedUp && verticalVelocity < 0 ) { // slow our rise verticalVelocity += moveDelta * ( 1.0 - playerEmotion ); dY += verticalVelocity; playerY += verticalVelocity; // avoid accumulation errors that make y motion jerky // when dY is tiny playerY = (int)playerY; dY = (int)dY; while( isBlockedOrPrize( (int)playerX - 2, (int)( playerY - 7 ) ) || isBlockedOrPrize( (int)playerX + 1, (int)( playerY - 7 ) ) ) { // hit head inside an obstacle // first, stop rising verticalVelocity = 0; // back off playerY = (int)playerY; playerY ++; dY ++; } } else { // stop rising if( verticalVelocity < 0 ) { verticalVelocity = 0; } } // character falls if nothing's below him char notBlockedDown = !isBlockedOrPrize( (int)playerX - 2, (int)( playerY + moveDelta ) ) && !isBlockedOrPrize( (int)playerX + 1, (int)( playerY + moveDelta ) ); if( notBlockedDown && verticalVelocity >= 0) { // gravity verticalVelocity += moveDelta; if( verticalVelocity > 5 ) { // cap it verticalVelocity = 5; } dY += verticalVelocity; playerY += verticalVelocity; // avoid accumulation errors that make y motion jerky // when dY is tiny playerY = (int)playerY; dY = (int)dY; while( isBlockedOrPrize( (int)playerX - 2, (int)( playerY ) ) || isBlockedOrPrize( (int)playerX + 1, (int)( playerY ) ) ) { // landed inside an obstacle // first, stop falling verticalVelocity = 0; // back off playerY = (int)playerY; playerY --; dY --; } } else if( !notBlockedDown ) { // stop falling if( verticalVelocity > 0 ) { verticalVelocity = 0; } // standing on firm ground // allow a jump if( getKeyDown( SDLK_SPACE ) ) { verticalVelocity = -5; } } setPlayerPosition( (int)playerX, (int)playerY ); if( !notBlockedDown ) { // use standard walking sprite setPlayerSpriteFrame( currentSpriteIndex ); } else { // override to jumping sprite (legs open frame from walking) if( playerFacing ) { setPlayerSpriteFrame( 2 ); } else { setPlayerSpriteFrame( 6 ); } } // check for events to quit SDL_Event event; while( SDL_PollEvent(&event) ) { switch( event.type ) { case SDL_KEYDOWN: switch( event.key.keysym.sym ) { case SDLK_q: case SDLK_ESCAPE: done = true; quit = true; break; default: break; } break; case SDL_QUIT: done = true; quit = true; break; default: break; } } //t +=0.25; frameCount ++; // add particles for "hair on fire" effect Particle p; p.mGradient = &fireGradient; // start out cream colored p.mGradientPosition = 1.0; p.mFade = 1.0; p.mAdditive = false; // rises slowly p.mDX = 0; p.mDY = -0.5; // fades out double baseDFade = -0.1; double baseDeltaGradient = -0.2; // 7 hair pixels, each which generates fire particles // offset of hair pixels from player position int hairOffsetX[7]; int hairOffsetY[7]; hairOffsetY[0] = -5; hairOffsetY[1] = -5; hairOffsetY[2] = -6; hairOffsetY[3] = -6; hairOffsetY[4] = -7; hairOffsetY[5] = -7; hairOffsetY[6] = -7; if( playerFacing ) { // facing right hairOffsetX[0] = -2; hairOffsetX[1] = -1; hairOffsetX[2] = -2; hairOffsetX[3] = -1; hairOffsetX[4] = -1; hairOffsetX[5] = 0; hairOffsetX[6] = 1; if( playerPushing ) { // head moves right by one for( int h=0; h<7; h++ ) { hairOffsetX[h] ++; } } } else { //facing left hairOffsetX[0] = 0; hairOffsetX[1] = 1; hairOffsetX[2] = 0; hairOffsetX[3] = 1; hairOffsetX[4] = -2; hairOffsetX[5] = -1; hairOffsetX[6] = 0; } // reuse particle object for each spot on hair // double number of particles placed to make them thicker for( int s=0; s<2; s++ ) { for( int h=0; h<7; h++ ) { p.mX = (int)playerX + hairOffsetX[h]; p.mY = (int)playerY + hairOffsetY[h]; // fade out faster farther from center p.mDFade = baseDFade * ( 1 + 0.25 * fabs( hairOffsetX[h] ) ); // random vertical speed p.mDY = randSource.getRandomBoundedDouble( -2, -0.1 ); // randomly scale gradient delta double deltaScale = randSource.getRandomBoundedDouble( 0.75, 1 ); p.mDeltaGradientPosition = baseDeltaGradient * deltaScale; // half are additive // this allows some pixels to look like smoke when they // become darker at the top p.mAdditive = randSource.getRandomBoolean(); addParticle( p ); } } // step particles right after placing them to disguise initial // placement pattern stepParticles(); // other animations run independent of whether player is moving stepAnimations(); timeLeft += timeDelta; if( timeLeft <= 0 ) { gameOver = true; timeLeft = 0; } // last 3/8 of game if( timeLeft <= 0.375 * totalTime ) { // mez "sneaks" away if he's off screen near the end of the game if( ! isMezOnScreen() ) { hideMez(); } } // last 1/8 of game if( timeLeft <= 0.125 * totalTime ) { // music fades out toward end of fire dying setMusicLoudness( timeLeft / ( 0.125 * totalTime ) ); } if( isMezHidden() ) { // fix ball in front of where Mez usually stands returnBallToMez(); } else { // mez visible... handle throw-catch logic int mezX, mezY; getMezPosition( &mezX, &mezY ); int distanceFromMez = (int) sqrt( pow( mezX - playerX, 2 ) + pow( mezY - playerY, 2 ) ); if( distanceFromMez < 30 && // not too close distanceFromMez > 15 && // standing at same level as Mez mezY == (int)playerY - 3 && mezHasBall() ) { throwBall(); } char mezCaughtBall = stepBall(); if( mezCaughtBall ) { playerEmotionSmoothTransitionTarget = playerEmotion + 0.15; if( playerEmotionSmoothTransitionTarget > 1 ) { playerEmotionSmoothTransitionTarget = 1; } /* playerEmotion += 0.15; if( playerEmotion > 1.0 ) { playerEmotion = 1.0; } */ // return to default descent deltaPlayerEmotion = defaultDeltaPlayerEmotion; // continue any upswing // upswingDeltaPlayerEmotion = 0; } } if( isPrize( (int)playerX, (int)playerY ) ) { touchPrize( (int)playerX, (int)playerY ); } stepPrizes(); if( playerEmotionSmoothTransitionTarget != -1 ) { // move emotion toward target if( playerEmotion <= playerEmotionSmoothTransitionTarget ) { playerEmotion += smoothTransitionDelta; if( playerEmotion >= playerEmotionSmoothTransitionTarget ) { // hit target playerEmotion = playerEmotionSmoothTransitionTarget; playerEmotionSmoothTransitionTarget = -1; } } else if( playerEmotion > playerEmotionSmoothTransitionTarget ) { playerEmotion -= smoothTransitionDelta; if( playerEmotion <= playerEmotionSmoothTransitionTarget ) { // hit target playerEmotion = playerEmotionSmoothTransitionTarget; playerEmotionSmoothTransitionTarget = -1; } } } else if( upswingDeltaPlayerEmotion == 0 ) { // player emotion gradually decreases with time playerEmotion += deltaPlayerEmotion; } else { // in upswing playerEmotion += upswingDeltaPlayerEmotion; } if( upswingDeltaPlayerEmotion != 0 && playerEmotion >= 0.5 ) { // halfway through a natural upswing // return to default descent rate (for when after upswing is over) deltaPlayerEmotion = defaultDeltaPlayerEmotion; } if( playerEmotion < 0 ) { playerEmotion = 0; // hit bottom, move naturally upward upswingDeltaPlayerEmotion = defaultUpswingAmount; // keep whatever descent rate (deltaPlayerEmotion) we have, for // now, in case we hit another prize to cancel our natural upswing } else if( playerEmotion > 1 ) { playerEmotion = 1; // upswing over upswingDeltaPlayerEmotion = 0; } } unsigned long netTime = time( NULL ) - startTime; double frameRate = frameCount / (double)netTime; printf( "Frame rate = %f fps (%d frames)\n", frameRate, frameCount ); printf( "Game time = %d:%d\n", (int)netTime / 60, (int)netTime % 60 ); fflush( stdout ); delete titleImage; delete [] gameImage; delete [] titlePixels; destroyWorld(); if( quit ) { return false; } else { return true; } } gravitation-3+dfsg1.orig/game5/gameSource/ball.png0000644000175000017500000000017310761547341020661 0ustar pabspabs‰PNG  IHDRKm)мBIDATзcЬЭЭeР˜p„Ф$†IH,Ъsђd†џџ'хххa1Š‘нЈэЙЙлЖ30фЁ‘#ЪU ­ Шш1)PIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/musicPlayer.cpp0000644000175000017500000004646610761570214022254 0ustar pabspabs #include "common.h" #include "Timbre.h" #include "Envelope.h" #include "minorGems/util/SimpleVector.h" #include #include #include #include // smoothly fade in particular tracks based on player emotion // low emotion plays only first track... high emotion plays all tracks extern double playerEmotion; int sampleRate = 22050; //int sampleRate = 11025; Image *musicImage = NULL; int w, h; // total number of samples played so far int streamSamples = 0; // offset into grid at start // for testing int gridStartOffset = 0; // overal loudness of music double musicLoudness = 1.0; // one grid step in seconds double gridStepDuration = 0.25; int gridStepDurationInSamples = (int)( gridStepDuration * sampleRate ); double entireGridDuraton; // c double keyFrequency = 261.63; int numTimbres = 6; Timbre *musicTimbres[ 6 ]; int numEnvelopes = 6; Envelope *musicEnvelopes[ 6 ]; class Note { public: // index into musicTimbres array int mTimbreNumber; // index into musicEnvelopes array int mEnvelopeNumber; int mScaleNoteNumber; // additional loudness adjustment // places note in stereo space double mLoudnessLeft; double mLoudnessRight; // start time, in seconds from start of note grid double mStartTime; // duration in seconds double mDuration; // used when note is currently playing to track progress in note // negative if we should wait before starting to play the note int mCurrentSampleNumber; // duration in samples int mNumSamples; }; // isomorphic to our music image, except only has an entry for each note // start (all others, including grid spots that contain note continuations, // are NULL) // indexed as noteGrid[y][x] Note ***noteGrid; SimpleVector currentlyPlayingNotes; // need to synch these with audio thread void setMusicLoudness( double inLoudness ) { SDL_LockAudio(); musicLoudness = inLoudness; SDL_UnlockAudio(); } void restartMusic() { SDL_LockAudio(); // return to beginning (and forget samples we've played so far) streamSamples = 0; // drop all currently-playing notes currentlyPlayingNotes.deleteAll(); SDL_UnlockAudio(); } // called by SDL to get more samples void audioCallback( void *inUserData, Uint8 *inStream, int inLengthToFill ) { // 2 bytes for each channel of stereo sample int numSamples = inLengthToFill / 4; Sint16 *samplesL = new Sint16[ numSamples ]; Sint16 *samplesR = new Sint16[ numSamples ]; // first, zero-out the buffer to prepare it for our sum of note samples // each sample is 2 bytes memset( samplesL, 0, 2 * numSamples ); memset( samplesR, 0, 2 * numSamples ); int i; // hop through all grid steps that *start* in this stream buffer // add notes that start during this stream buffer // how far into stream buffer before we hit our first grid step? int startOfFirstGridStep = streamSamples % gridStepDurationInSamples; if( startOfFirstGridStep != 0 ) { startOfFirstGridStep = gridStepDurationInSamples - startOfFirstGridStep; } // hop from start of grid step to start of next grid step // ignore samples in between, since notes don't start there, // and all we're doing right now is finding notes that start for( i=startOfFirstGridStep; imCurrentSampleNumber = -i; } } } streamSamples += numSamples; // loop over all current notes and add their samples to buffer for( int n=0; nmScaleNoteNumber; Timbre *timbre = musicTimbres[ note->mTimbreNumber ]; int tableLength = timbre->mWaveTableLengths[ waveTableNumber ]; Sint16 *waveTable = timbre->mWaveTable[ waveTableNumber ]; Envelope *env = musicEnvelopes[ note->mEnvelopeNumber ]; double *envLevels = env->getEnvelope( // index envelope by number of grid steps in note note->mNumSamples / gridStepDurationInSamples ); double noteLoudnessL = note->mLoudnessLeft; double noteLoudnessR = note->mLoudnessRight; // do this outside inner loop noteLoudnessL *= musicLoudness; noteLoudnessR *= musicLoudness; // factor in player emotion // level from 0..(numTimbres-1) double trackFadeInLevel = playerEmotion * (numTimbres-1); // level for this track based on trackFadeInLevel double thisTrackLevel; if( trackFadeInLevel >= note->mTimbreNumber ) { // full volume thisTrackLevel = 1.0; } else if( trackFadeInLevel > note->mTimbreNumber - 1 ) { // linear fade in for this track thisTrackLevel = trackFadeInLevel - (int)trackFadeInLevel; } else { // track silent thisTrackLevel = 0; } noteLoudnessL *= thisTrackLevel; noteLoudnessR *= thisTrackLevel; int noteStartInBuffer = 0; int noteEndInBuffer = numSamples; if( note->mCurrentSampleNumber < 0 ) { // delay before note starts in this sample buffer noteStartInBuffer = - note->mCurrentSampleNumber; // we've taken account of the delay note->mCurrentSampleNumber = 0; } char endNote = false; int numSamplesLeftInNote = note->mNumSamples - note->mCurrentSampleNumber; if( noteStartInBuffer + numSamplesLeftInNote < noteEndInBuffer ) { // note ends before end of buffer noteEndInBuffer = noteStartInBuffer + numSamplesLeftInNote; endNote = true; } int waveTablePos = note->mCurrentSampleNumber % tableLength; int currentSampleNumber = note->mCurrentSampleNumber; for( i=noteStartInBuffer; i != noteEndInBuffer; i++ ) { double envelope = envLevels[ currentSampleNumber ]; double monoSample = envelope * waveTable[ waveTablePos ]; samplesL[i] += (Sint16)( noteLoudnessL * monoSample ); samplesR[i] += (Sint16)( noteLoudnessR * monoSample ); currentSampleNumber ++; waveTablePos ++; // avoid using mod operator (%) in inner loop // found with profiler if( waveTablePos == tableLength ) { // back to start of table waveTablePos = 0; } } note->mCurrentSampleNumber += ( noteEndInBuffer - noteStartInBuffer ); if( endNote ) { // note ended in this buffer currentlyPlayingNotes.deleteElement( n ); n--; } } // now copy samples into Uint8 buffer int streamPosition = 0; for( i=0; i != numSamples; i++ ) { Sint16 intSampleL = samplesL[i]; Sint16 intSampleR = samplesR[i]; inStream[ streamPosition ] = (Uint8)( intSampleL & 0xFF ); inStream[ streamPosition + 1 ] = (Uint8)( ( intSampleL >> 8 ) & 0xFF ); inStream[ streamPosition + 2 ] = (Uint8)( intSampleR & 0xFF ); inStream[ streamPosition + 3 ] = (Uint8)( ( intSampleR >> 8 ) & 0xFF ); streamPosition += 4; } delete [] samplesL; delete [] samplesR; } // limit on n, based on Nyquist, when summing sine components //int nLimit = (int)( sampleRate * M_PI ); // actually, this is way too many: it takes forever to compute // use a lower limit instead // This produces fine results (almost perfect square wave) int nLimit = 40; // square wave with period of 2pi double squareWave( double inT ) { double sum = 0; for( int n=1; ngetWidth(); h = musicImage->getHeight(); // notes are in red and green channel double *redChannel = musicImage->getChannel( 0 ); double *greenChannel = musicImage->getChannel( 1 ); entireGridDuraton = gridStepDuration * w; // jump ahead in stream, if needed streamSamples += gridStartOffset * gridStepDurationInSamples; // blank line of pixels between timbres int heightPerTimbre = (h+1) / numTimbres - 1; // find the maximum number of simultaneous notes in the song // take loudness into account double maxNoteLoudnessInAColumn = 0; int x, y; for( x=0; x 0 || greenChannel[ imageIndex ] > 0 ) ) { noteLoudnessInColumnL += greenChannel[ imageIndex ]; noteLoudnessInColumnR += redChannel[ imageIndex ]; } } // pick loudest channel for this column and compare it to // loudest column/channel seen so far if( maxNoteLoudnessInAColumn < noteLoudnessInColumnL ) { maxNoteLoudnessInAColumn = noteLoudnessInColumnL; } if( maxNoteLoudnessInAColumn < noteLoudnessInColumnR ) { maxNoteLoudnessInAColumn = noteLoudnessInColumnR; } } // divide loudness amoung timbres to avoid clipping double loudnessPerTimbre = 1.0 / maxNoteLoudnessInAColumn; // further adjust loudness per channel here as we construct // each timbre. // This is easier than tweaking loundness of a given part by hand // using a painting program musicTimbres[0] = new Timbre( sampleRate, 0.15 * loudnessPerTimbre, keyFrequency / 4, heightPerTimbre, squareWave ); musicTimbres[1] = new Timbre( sampleRate, loudnessPerTimbre, keyFrequency, heightPerTimbre, sin ); musicTimbres[2] = new Timbre( sampleRate, 0.35 * loudnessPerTimbre, keyFrequency / 2, heightPerTimbre, sawWave ); musicTimbres[3] = new Timbre( sampleRate, 0.5 * loudnessPerTimbre, keyFrequency / 4, heightPerTimbre, smoothedWhiteNoise ); musicTimbres[4] = new Timbre( sampleRate, loudnessPerTimbre, keyFrequency * 2, heightPerTimbre, sin ); musicTimbres[5] = new Timbre( sampleRate, 0.65 * loudnessPerTimbre, keyFrequency, heightPerTimbre, sawWave ); // next, compute the longest note in the song int maxNoteLength = 0; for( y=0; y 0 || greenChannel[ imageIndex ] > 0 ) ) { currentNoteLength ++; } else { currentNoteLength = 0; } if( currentNoteLength > maxNoteLength ) { maxNoteLength = currentNoteLength; } } } printf( "Max note length in song = %d\n", maxNoteLength ); musicEnvelopes[0] = new Envelope( 0.25, 0.0, 1.0, 0.1, maxNoteLength, gridStepDurationInSamples ); musicEnvelopes[1] = new Envelope( 0.1, 0.9, 0.0, 0.0, maxNoteLength, gridStepDurationInSamples ); musicEnvelopes[2] = new Envelope( 0.05, 0.7, 0.25, 0.1, maxNoteLength, gridStepDurationInSamples ); musicEnvelopes[3] = new Envelope( 0.0, 0.2, 0.0, 0.0, maxNoteLength, gridStepDurationInSamples ); musicEnvelopes[4] = new Envelope( 0.1, 0.9, 0.0, 0.0, maxNoteLength, gridStepDurationInSamples ); musicEnvelopes[5] = new Envelope( 0.05, 0.7, 0.25, 0.1, maxNoteLength, gridStepDurationInSamples ); noteGrid = new Note**[ h ]; for( int y=0; y 0 || greenChannel[ imageIndex ] > 0 ) ) { if( notePlaying ) { // part of note that's already playing // one more grid step noteStart->mDuration += gridStepDuration; noteStart->mNumSamples += gridStepDurationInSamples; } else { // start a new note noteGrid[y][x] = new Note(); noteGrid[y][x]->mScaleNoteNumber = noteNumber; noteGrid[y][x]->mTimbreNumber = y / ( heightPerTimbre + 1 ); // same as timbre number noteGrid[y][x]->mEnvelopeNumber = noteGrid[y][x]->mTimbreNumber; // left loudness from green brightness noteGrid[y][x]->mLoudnessLeft = greenChannel[ imageIndex ]; // right loudness from red brightness noteGrid[y][x]->mLoudnessRight = redChannel[ imageIndex ]; noteGrid[y][x]->mStartTime = gridStepDuration * x; // one grid step so far noteGrid[y][x]->mDuration = gridStepDuration; noteGrid[y][x]->mNumSamples = gridStepDurationInSamples; // track if it needs to be continued notePlaying = true; noteStart = noteGrid[y][x]; } } else { // no tone if( notePlaying ) { // stop it notePlaying = false; noteStart = NULL; } } } } } void startMusic( char *inTGAFileName ) { loadMusicImage( inTGAFileName ); SDL_AudioSpec audioFormat; /* Set 16-bit stereo audio at 22Khz */ audioFormat.freq = sampleRate; audioFormat.format = AUDIO_S16; audioFormat.channels = 2; audioFormat.samples = 512; /* A good value for games */ audioFormat.callback = audioCallback; audioFormat.userdata = NULL; /* Open the audio device and start playing sound! */ if( SDL_OpenAudio( &audioFormat, NULL ) < 0 ) { printf( "Unable to open audio: %s\n", SDL_GetError() ); } // set pause to 0 to start audio SDL_PauseAudio(0); } void stopMusic() { SDL_CloseAudio(); if( musicImage != NULL ) { delete musicImage; musicImage = NULL; } for( int y=0; y> 16 & 0xFF ) / 255.0; g[i] = ( inImage[i] >> 8 & 0xFF ) / 255.0; b[i] = ( inImage[i] & 0xFF ) / 255.0; } File tgaFile( NULL, inFileName ); FileOutputStream tgaStream( &tgaFile ); TGAImageConverter converter; converter.formatImage( &outImage, &tgaStream ); } Pixel32 rgbColorToPixel32( rgbColor inColor ) { Pixel32 p; p.channels.a = 0; p.channels.r = (unsigned char)( inColor.r * 255 ); p.channels.g = (unsigned char)( inColor.g * 255 ); p.channels.b = (unsigned char)( inColor.b * 255 ); return p; } gravitation-3+dfsg1.orig/game5/gameSource/World.cpp0000644000175000017500000015543710762625742021055 0ustar pabspabs#include "World.h" #include "common.h" #include "map.h" #include "GraphicContainer.h" #include "minorGems/graphics/Image.h" #include "minorGems/util/SimpleVector.h" #include "minorGems/util/random/StdRandomSource.h" extern double playerEmotion; extern double deltaPlayerEmotion; extern double upswingDeltaPlayerEmotion; extern double playerEmotionSmoothTransitionTarget; extern StdRandomSource randSource; GraphicContainer *tileContainer; GraphicContainer *backgroundContainer; GraphicContainer *spriteContainer; GraphicContainer *mezContainer; GraphicContainer *ballContainer; GraphicContainer *prizeContainer; GraphicContainer *prizeOrbContainer; GraphicContainer *numeralContainer; GraphicContainer *kilnContainer; GraphicContainer *kilnFireContainer; GraphicContainer *kilnSmokeContainer; GraphicContainer *kilnAshPitContainer; GraphicContainer *heartContainer; GraphicContainer *madContainer; // dimensions of one tile. TileImage contains 13 tiles, stacked vertically, // with blank lines between tiles int tileW = 11; int tileH = 11; int tileImageW; int tileImageH; int numTileSets; int backgroundW = 99; int backgroundH = 100; int backgroundImageW; int backgroundImageH; int numBackgrounds; class Animation { public: Animation( int inX, int inY, int inFrameW, int inFrameH, char inAutoStep, char inRemoveAtEnd, GraphicContainer *inGraphics ) : mX( inX ), mY( inY ), mFrameW( inFrameW ), mFrameH( inFrameH ), mPageNumber( 0 ), mFrameNumber( 0 ), mAutoStep( inAutoStep ), mStepsPerFrame( 6 ), mTotalStepCount( 0 ), mRemoveAtEnd( inRemoveAtEnd ), mHide( false ), mOnScreen( true ), mTransparency( 1.0 ), mAdditiveBlend( false ), mGraphics( inGraphics ) { mImageW = mGraphics->mW; mNumFrames = ( mGraphics->mH - mFrameH ) / mFrameH + 1; mNumPages = ( mGraphics->mW - mFrameW ) / mFrameW + 1; } // default constructor so that we can build a vector // of Animations Animation() { } // replaces graphics of animation void swapGraphics( GraphicContainer *inNewGraphics ) { mGraphics = inNewGraphics; mImageW = mGraphics->mW; mNumFrames = ( mGraphics->mH - mFrameH ) / mFrameH + 1; mNumPages = ( mGraphics->mW - mFrameW ) / mFrameW + 1; if( mPageNumber >= mNumPages ) { mPageNumber = mNumPages - 1; } if( mFrameNumber >= mNumFrames ) { mFrameNumber = mNumFrames - 1; } } int mX, mY; int mFrameW, mFrameH; int mImageW; // can blend between pages double mPageNumber; int mNumPages; int mFrameNumber; int mNumFrames; char mAutoStep; // can be used to slow an animtion down. char mStepsPerFrame; int mTotalStepCount; char mRemoveAtEnd; char mHide; // was this animation on the screen the last // time the screen was drawn? char mOnScreen; double mTransparency; char mAdditiveBlend; GraphicContainer *mGraphics; }; // Set default size larger than what we'll ever need // thus, vector will never be resized, so we can obtain pointers // to elements of the vector safely. // This is an abuse of the SimpleVector interface (since we shouldn't be // able to depend on pointers into the vector, especially when items are being // added and deleted). However, this makes memory management much cleaner (if // we were storying Animation* objects in the vector, they would each need to // be allocated on the heap and freed when they are removed). // Also, all the Animations that we add/remove mid-game are at the end of the // vector, past the point where our more static animations (like player and // prizes, etc.) are located. Thus, adding and removing items from the end // won't invalidate these static pointers in to the vector. // // Still, it would be nice to make this cleaner and safer... but it works SimpleVector animationList( 500 ); class PrizeStatus { public: PrizeStatus() : mAnimation( NULL ), mScoreAnimation( NULL ), mTouched( false ), mFalling( false ), mFrozen( false ), mScoreTickTimer( 0 ), mScore( 9 ), mSlidingIntoFire( false ), mMelting( false ), mMeltTimer( 0 ), mOrbSent( false ), mDY( 0 ), mStartY( 0 ), mPushAccumulation( 0 ) { } PrizeStatus( Animation *inAnimation ) : mAnimation( inAnimation ), mScoreAnimation( NULL ), mTouched( false ), mFalling( false ), mFrozen( false ), mScoreTickTimer( 0 ), mScore( 9 ), mSlidingIntoFire( false ), mMelting( false ), mMeltTimer( 0 ), mOrbSent( false ), mDY( 0 ), mStartY( 0 ), mPushAccumulation( 0 ) { } Animation *mAnimation; Animation *mScoreAnimation; char mTouched; char mFalling; char mFrozen; // used for timing score numeral transitions int mScoreTickTimer; int mScore; char mSlidingIntoFire; char mMelting; // used for timing melting frames int mMeltTimer; char mOrbSent; double mDY; double mStartY; // where sub-pixel pushes can accumulate to finally move // the prize a full pixel double mPushAccumulation; }; SimpleVector prizeList; Animation *spriteAnimation; Animation *mezAnimation; Animation *ballAnimation; #define numKilnFireAnimations 3 Animation *kilnFireAnimations[ numKilnFireAnimations ]; // update one each timestep int kilnFireAnimationToUpdate = 0; // starting y for fires (they shrink downward int kilnFireStartingY; #define numKilnSmokeAnimations 3 Animation *kilnSmokeAnimations[ numKilnSmokeAnimations ]; // update one each timestep int kilnSmokeAnimationToUpdate = 0; double kilnSmokeStartingAlpha; Animation *kilnAshPitAnimation; Animation *prizeOrbAnimation; char equals( rgbColor inA, rgbColor inB ) { return inA.r == inB.r && inA.g == inB.g && inA.b == inB.b; } Uint32 *preRenderedMap; int mapWidth, mapHeight, mapPixels; // true where transparent // false where opaque char *mapTransparency; // precompute the result of multiplying an alpha value of 0..255 by a color // value of 0..255 unsigned char alphaBlendMap[256][256]; void initWorld() { // precompute alpha map for( int a=0; a<256; a++ ) { for( int c=0; c<256; c++ ) { alphaBlendMap[a][c] = (unsigned char)( (a / 255.0) * c ); } } prizeList.deleteAll(); animationList.deleteAll(); // orb front-most Animation prizeOrb( 0, 0, 5, 5, false, false, prizeOrbContainer ); prizeOrb.mAdditiveBlend = true; prizeOrb.mTransparency = 1.0; prizeOrb.mHide = true; animationList.push_back( prizeOrb ); // get pointer to animation in vector prizeOrbAnimation = animationList.getElement( animationList.size() - 1 ); // kiln smoke in front of everything Animation kilnSmoke( 7 * tileW + 2, getMapHeight() - tileH - 40 - 10, 5, 21, false, false, kilnSmokeContainer ); kilnSmoke.mFrameNumber = 0; kilnSmokeStartingAlpha = 0.25; kilnSmoke.mTransparency = kilnSmokeStartingAlpha; kilnSmoke.mAdditiveBlend = false; for( int k=0; kmFrameNumber = p.mScore; prizeList.push_back( p ); } } } // kiln behind prizes Animation kiln( 7 * tileW + 2, getMapHeight() - tileH - 20, 15, 41, false, false, kilnContainer ); kiln.mFrameNumber = 0; animationList.push_back( kiln ); } char isSpriteTransparent( GraphicContainer *inContainer, int inSpriteIndex ) { // take transparent color from corner return inContainer->mRed[ inSpriteIndex ] == inContainer->mRed[ 0 ] && inContainer->mGreen[ inSpriteIndex ] == inContainer->mGreen[ 0 ] && inContainer->mBlue[ inSpriteIndex ] == inContainer->mBlue[ 0 ]; } #include void sampleFromWorld( int inX, int inY, int inWidth, int inHeight, Uint32 *outDestination ) { // first draw from pre-rendered map // for now, assume x = 0 and inWidth = mapWidth // used to select y window on map int skipPixels = inY * mapWidth; int numPixels = inWidth * inHeight; // blend between two tile sets // skip first tile set (emotion 0 maps to tileset 1) // tileset 0 is kept as a base tileset for working convenience int tileSetA = (int)( playerEmotion * (numTileSets - 2) ) + 1; int tileSetB = tileSetA + 1; if( tileSetB >= numTileSets ) { tileSetB = tileSetA; } double bTileWeight = ( playerEmotion * (numTileSets - 2) + 1) - tileSetA; // extra offset to index tile sets Uint32 *mapPixelsAfterSkipA = &( preRenderedMap[ tileSetA * mapPixels + skipPixels ] ); Uint32 *mapPixelsAfterSkipB = &( preRenderedMap[ tileSetB * mapPixels + skipPixels ] ); unsigned char bTileAlpha = (unsigned char)( bTileWeight * 255 ); unsigned char aTileAlpha = 255 - bTileAlpha; unsigned char *aTileAlphaMap = alphaBlendMap[ aTileAlpha ]; unsigned char *bTileAlphaMap = alphaBlendMap[ bTileAlpha ]; // draw background to fill in transparent spots char *transparencyValuesAfterSkip = &( mapTransparency[ skipPixels ] ); // do same style of alpha blending for the background pixels // blend between two backgroundImages int backgroundSetA = (int)( playerEmotion * (numBackgrounds - 1) ); int backgroundSetB = backgroundSetA + 1; if( backgroundSetB >= numBackgrounds ) { backgroundSetB = backgroundSetA; } double bBackgroundWeight = ( playerEmotion * (numBackgrounds - 1) ) - backgroundSetA; // offset between backgrounds int backgroundSetOffset = backgroundW * ( backgroundH + 1 ); Uint32 *backgroundPixels = backgroundContainer->mCompositePixels; // apply offset to index background sets Uint32 *backgroundPixelsAfterSkipA = &( backgroundPixels[ backgroundSetA * backgroundSetOffset ] ); Uint32 *backgroundPixelsAfterSkipB = &( backgroundPixels[ backgroundSetB * backgroundSetOffset] ); unsigned char bBackgroundAlpha = (unsigned char)( bBackgroundWeight * 255 ); unsigned char aBackgroundAlpha = 255 - bBackgroundAlpha; unsigned char *aBackgroundAlphaMap = alphaBlendMap[ aBackgroundAlpha ]; unsigned char *bBackgroundAlphaMap = alphaBlendMap[ bBackgroundAlpha ]; int i; for( i=0; i=0; i-- ) { Animation a = *( animationList.getElement( i ) ); int animW = a.mFrameW; int animH = a.mFrameH; // anim centered at mX and mY int animStartX = a.mX - animW / 2; int animEndX = a.mX + animW - 1; int animStartY = a.mY - animH / 2; int animEndY = a.mY + animH - 1; // is anim visible and on screen? if( ! a.mHide && ( animStartX >= inX && animStartX <= inX + inWidth || animEndX >= inX && animEndX <= inX + inWidth || animStartX <= inX && animEndX >= inX + inWidth ) && ( animStartY >= inY && animStartY <= inY + inHeight || animEndY >= inY && animEndY <= inY + inHeight || animStartY <= inY && animEndY >= inY + inHeight ) ) { // cannot access mOnScreen in a, because it's a copy animationList.getElement( i )->mOnScreen = true; // draw pixels for( int y=0; y< a.mFrameH; y++ ) { int screenY = animStartY + y; if( screenY >= inY && screenY < inY + inHeight ) { // y coordinate on screen for( int x=0; x< a.mFrameW; x++ ) { int screenX = animStartX + x; if( screenX >= inX && screenX < inX + inHeight ) { // x coordinate on screen int animIndex = y * a.mImageW + x; // skip to appropriate anim page animIndex += (int)a.mPageNumber * (animW + 1); // skip to appropriate anim frame animIndex += a.mFrameNumber * a.mImageW * ( animH + 1 ); // page to blend with int animBlendIndex = animIndex + animW + 1; double blendWeight = a.mPageNumber - (int)a.mPageNumber; if( !isSpriteTransparent( a.mGraphics, animIndex ) ) { // in non-transparent part rgbColor pixelColor; if( blendWeight != 0 ) { pixelColor.r = ( 1 - blendWeight ) * a.mGraphics->mRed[ animIndex ] + blendWeight * a.mGraphics->mRed[ animBlendIndex ]; pixelColor.g = ( 1 - blendWeight ) * a.mGraphics->mGreen[ animIndex ] + blendWeight * a.mGraphics->mGreen[ animBlendIndex ]; pixelColor.b = ( 1 - blendWeight ) * a.mGraphics->mBlue[ animIndex ] + blendWeight * a.mGraphics->mBlue[ animBlendIndex ]; } else { // no blend pixelColor.r = a.mGraphics->mRed[ animIndex ]; pixelColor.g = a.mGraphics->mGreen[ animIndex ]; pixelColor.b = a.mGraphics->mBlue[ animIndex ]; } char transparent = false; if( a.mTransparency < 1 ) { pixelColor.r *= a.mTransparency; pixelColor.g *= a.mTransparency; pixelColor.b *= a.mTransparency; transparent = true; } unsigned char r = (unsigned char) pixelColor.r; unsigned char g = (unsigned char) pixelColor.g; unsigned char b = (unsigned char) pixelColor.b; if( transparent || a.mAdditiveBlend ) { // mix with underlying pixel color Uint32 oldPixel = outDestination[ ( screenY - inY ) * inWidth + ( screenX - inX ) ]; unsigned char oldR = ( oldPixel >> 16 ) & 0xFF; unsigned char oldG = ( oldPixel >> 8 ) & 0xFF; unsigned char oldB = oldPixel & 0xFF; double t = a.mTransparency; double invT = 1-t; double rFloat; double gFloat; double bFloat; if( !a.mAdditiveBlend ) { rFloat = t * r + invT * oldR; gFloat = t * g + invT * oldG; bFloat = t * g + invT * oldB; } else { rFloat = t * r + oldR; gFloat = t * g + oldG; bFloat = t * b + oldB; if( rFloat > 255 ) { rFloat = 255; } if( gFloat > 255 ) { gFloat = 255; } if( bFloat > 255 ) { bFloat = 255; } } r = (unsigned char)rFloat; g = (unsigned char)gFloat; b = (unsigned char)bFloat; } // set pixel outDestination[ ( screenY - inY ) * inWidth + ( screenX - inX ) ] = r << 16 | g << 8 | b; } } } } } } // end check for animation on screen else { // cannot access mOnScreen in a, because it's a copy animationList.getElement( i )->mOnScreen = false; } } // end loop over animations } // gets tile index in tile set for a given map position int getTileIndex( int inMapX, int inMapY ) { int tileIndex; char blocked = isBlocked( inMapX, inMapY ); if( !blocked ) { // empty tile tileIndex = 0; } else { int neighborsBlockedBinary = 0; if( isBlocked( inMapX, inMapY - tileH ) ) { // top neighborsBlockedBinary = neighborsBlockedBinary | 1; } if( isBlocked( inMapX + tileW, inMapY ) ) { // right neighborsBlockedBinary = neighborsBlockedBinary | 1 << 1; } if( isBlocked( inMapX, inMapY + tileH ) ) { // bottom neighborsBlockedBinary = neighborsBlockedBinary | 1 << 2; } if( isBlocked( inMapX - tileW, inMapY ) ) { // left neighborsBlockedBinary = neighborsBlockedBinary | 1 << 3; } // skip empty tile, treat as tile index neighborsBlockedBinary += 1; tileIndex = neighborsBlockedBinary; } return tileIndex; } int getTileWidth() { return tileW; } int getTileHeight() { return tileH; } void destroyWorld() { /* printf( "%d hits, %d misses, %f hit ratio\n", hitCount, missCount, hitCount / (double)( hitCount + missCount ) ); */ } void stepAnimations() { for( int i=0; imAutoStep ) { a->mTotalStepCount ++; if( a->mTotalStepCount % a->mStepsPerFrame == 0 ) { if( a->mFrameNumber < a->mNumFrames - 1 ) { a->mFrameNumber ++; } else if( a->mRemoveAtEnd ) { // remove it animationList.deleteElement( i ); // back up in list for next loop iteration i--; } } } } } void startHeartAnimation( int inX, int inY ) { Animation a( inX, inY, 8, 8, true, true, heartContainer ); animationList.push_back( a ); } void setPlayerPosition( int inX, int inY ) { char moving = false; if( inX != spriteAnimation->mX ) { moving = true; } spriteAnimation->mX = inX; // player position centered at sprite's feet int newSpriteY = inY - spriteAnimation->mFrameH / 2 + 1; if( newSpriteY != spriteAnimation->mY ) { moving = true; } spriteAnimation->mY = newSpriteY; } void setPlayerSpriteFrame( int inFrame ) { spriteAnimation->mFrameNumber = inFrame; } void loadWorldGraphics() { tileContainer = new GraphicContainer( "tileSet.tga" ); tileImageW = tileContainer->mW; tileImageH = tileContainer->mH; // 1-pixel border between tilesets numTileSets = (tileImageW + 1) / (tileW + 1); printf( "%d tileSets\n", numTileSets ); spriteContainer = new GraphicContainer( "characterSprite.tga" ); mezContainer = new GraphicContainer( "mezSprite.tga" ); ballContainer = new GraphicContainer( "ball.tga" ); prizeContainer = new GraphicContainer( "prize.tga" ); prizeOrbContainer = new GraphicContainer( "prizeOrb.tga" ); numeralContainer = new GraphicContainer( "numeralsBlack.tga" ); heartContainer = new GraphicContainer( "heart.tga" ); madContainer = new GraphicContainer( "mad.tga" ); kilnContainer = new GraphicContainer( "kiln.tga" ); kilnFireContainer = new GraphicContainer( "kilnFire.tga" ); kilnSmokeContainer = new GraphicContainer( "kilnSmoke.tga" ); kilnAshPitContainer = new GraphicContainer( "kilnAshPit.tga" ); mapWidth = getMapWidth(); mapHeight = getMapHeight(); mapPixels = mapWidth * mapHeight; backgroundContainer = new GraphicContainer( "background.tga" ); backgroundImageW = backgroundContainer->mW; backgroundImageH = backgroundContainer->mH; // 1-pixel border between backgrounds numBackgrounds = ( backgroundImageH + 1 ) / ( backgroundH + 1 ); preRenderedMap = new Uint32[ numTileSets * mapHeight * mapWidth ]; mapTransparency = new char[ mapHeight * mapWidth ]; // transparency defined by upper left corner of tile sheet Uint32 transColor = tileContainer->mCompositePixels[0]; int t; int mapTileHeight = mapHeight / tileH; int mapTileWidth = mapWidth / tileW; // make a pre-rendered tile map for each tile set for( t=0; tmCompositePixels[ tileRowStartImageIndex ] ), tileW * 4 ); } } } } // go back over first pre-rendered map to get map transparency t = 0; for( int y=0; ymOnScreen || mezAnimation->mOnScreen; } void hideMez() { mezAnimation->mHide = true; } char isMezHidden() { return mezAnimation->mHide; } void getMezPosition( int *outX, int *outY ) { *outX = mezAnimation->mX; *outY = mezAnimation->mY; } char mezHasBallFlag = true; // steps to wait before throwing ball again int mezWaitingCount = 0; char mezHasBall() { return mezHasBallFlag; } double ballDX, ballDY; void throwBall() { if( mezWaitingCount == 0 ) { mezHasBallFlag = false; ballDX = 1; ballDY = randSource.getRandomBoundedDouble( -4.5, -2 ); // raise hands mezAnimation->mFrameNumber = 1; } } void getBallPosition( int *outX, int *outY ) { *outX = ballAnimation->mX; *outY = ballAnimation->mY; } void getBallVelocity( double *outDX, double *outDY ) { *outDX = ballDX; *outDY = ballDY; } // is ball moving back toward Mez? char ballHeadingToMez = false; void returnBallToMez() { mezHasBallFlag = true; ballHeadingToMez = false; ballAnimation->mX = mezAnimation->mX + 4; ballAnimation->mY = mezAnimation->mY + 2; ballDX = 0; ballDY = 0; mezAnimation->mFrameNumber = 0; } char stepBall() { if( mezWaitingCount > 0 ) { // freeze ball while mez waits mezWaitingCount --; /* if( mezWaitingCount == 0 && ! mezHasBallFlag ) { // mez waiting to throw, and wait count just expired // (throw starts on next frame) // raise hands mezAnimation->mFrameNumber = 1; } */ return false; } if( mezHasBallFlag ) { // do nothing, he's holding the ball return false; } ballAnimation->mX += (int)( ballDX ); ballAnimation->mY += (int)( ballDY ); // apply gravity ballDY += 0.2; char returnValue = false; if( isBlocked( ballAnimation->mX, ballAnimation->mY ) || isBlockedByPrize( ballAnimation->mX, ballAnimation->mY ) ) { if( ballHeadingToMez ) { // Mez catches ball thrown by parent startHeartAnimation( mezAnimation->mX, mezAnimation->mY - 6 ); returnValue = true; } else { // parent missed ball Animation a( mezAnimation->mX, mezAnimation->mY - 6, 8, 8, true, true, madContainer ); animationList.push_back( a ); // wait before throwing again mezWaitingCount = 20; } returnBallToMez(); } else if( !ballHeadingToMez ) { // check if ball hits player int distanceFromPlayer = (int) sqrt( pow( ballAnimation->mX - spriteAnimation->mX, 2 ) + pow( ballAnimation->mY - spriteAnimation->mY, 2 ) ); if( distanceFromPlayer <= 4 ) { // send ball back other way (back to Mez) ballDX *= -1; ballDY *= -1; ballHeadingToMez = true; } } // ball heading back to mez will return to mez when it hits the ground return returnValue; } PrizeStatus *getPrizeAt( int inX, int inY ) { for( int i=0; imAnimation; if( fabs( inX - prize->mX ) < prize->mFrameW / 2 + 1 && fabs( inY - prize->mY ) < prize->mFrameH / 2 + 1 ) { return status; } } return NULL; } char isPrize( int inX, int inY ) { if( getPrizeAt( inX, inY ) != NULL ) { return true; } else { return false; } } char isBlockedByPrize( int inX, int inY ) { PrizeStatus *status = getPrizeAt( inX, inY ); if( status != NULL ) { if( status->mFrozen && ! status->mAnimation->mHide ) { return true; } } return false; } void touchPrize( int inX, int inY ) { PrizeStatus *status = getPrizeAt( inX, inY ); if( status->mTouched == false ) { status->mTouched = true; status->mFalling = true; // start with some base velocity status->mDY = 1; // renew mania playerEmotionSmoothTransitionTarget = 1.0; // accellerated descent toward depression deltaPlayerEmotion *= 2; // end upswing upswingDeltaPlayerEmotion = 0; } } // gets whether there is a falling prize somewhere along the x span of inPrize // in y direction inDY // used by getPrizeFallingBelow // Checks x span from right to left, so returns rightmost prize first char getPrizeFallingY( PrizeStatus *inPrize, int inDY ) { Animation *anim = inPrize->mAnimation; int prizeStartX = anim->mX - anim->mFrameW/2; int prizeEndX = anim->mX + anim->mFrameW/2; int y = anim->mY + inDY; for( int x=prizeEndX; x>=prizeStartX; x-- ) { PrizeStatus *otherPrize = getPrizeAt( x, y ); if( otherPrize != NULL ) { if( otherPrize->mFalling ) { return true; } } } return false; } // gets whether there is a prize somewhere along the x span of inPrize // in y direction inDY // used by getPrizeAbove and getPrizeBelow // Checks x span from right to left, so returns rightmost prize first PrizeStatus *getPrizeTouchingY( PrizeStatus *inPrize, int inDY ) { Animation *anim = inPrize->mAnimation; int prizeStartX = anim->mX - anim->mFrameW/2; int prizeEndX = anim->mX + anim->mFrameW/2; // hack: // check one more units to right if we're looking above if( inDY < 0 ) { prizeEndX += 1; } int y = anim->mY + inDY; for( int x=prizeEndX; x>=prizeStartX; x-- ) { if( isBlockedByPrize( x, y ) ) { return getPrizeAt( x, y ); } } return NULL; } // gets whether there is a prize somewhere along the y span of inPrize // in x direction inDX // used by getPrizeRight PrizeStatus *getPrizeTouchingX( PrizeStatus *inPrize, int inDX ) { Animation *anim = inPrize->mAnimation; int prizeStartY = anim->mY - anim->mFrameH/2; int prizeEndY = anim->mY + anim->mFrameH/2; int x = anim->mX + inDX; for( int y=prizeStartY; y<=prizeEndY; y++ ) { if( isBlockedByPrize( x, y ) ) { return getPrizeAt( x, y ); } } return NULL; } PrizeStatus *getPrizeAbove( PrizeStatus *inPrize ) { return getPrizeTouchingY( inPrize, - inPrize->mAnimation->mFrameH/2 - 1 ); } PrizeStatus *getPrizeBelow( PrizeStatus *inPrize ) { return getPrizeTouchingY( inPrize, inPrize->mAnimation->mFrameH/2 + 1 ); } PrizeStatus *getPrizeRight( PrizeStatus *inPrize ) { return getPrizeTouchingX( inPrize, inPrize->mAnimation->mFrameW/2 + 1 ); } PrizeStatus *getPrizeLeft( PrizeStatus *inPrize ) { return getPrizeTouchingX( inPrize, - inPrize->mAnimation->mFrameW/2 - 1 ); } char getPrizeFallingBelow( PrizeStatus *inPrize ) { return getPrizeFallingY( inPrize, inPrize->mAnimation->mFrameH/2 + 1 ); } char isPushable( PrizeStatus *inStatus ) { if( inStatus != NULL && inStatus->mTouched && !inStatus->mFalling && !inStatus->mMelting && !inStatus->mSlidingIntoFire ) { PrizeStatus *prizeAbove = getPrizeAbove( inStatus ); if( prizeAbove != NULL ) { // one above us, but if we're not supporting it, we should // keep sliding until we're up against it's support // see what's supporting it (the right-most prize under it) PrizeStatus *support = getPrizeBelow( prizeAbove ); if( support == inStatus || support == NULL ) { // we're the main support // or there's no support (falling past us) // we're sandwitched, we can't move return false; } } PrizeStatus *prizeRight = getPrizeRight( inStatus ); if( prizeRight == NULL ) { // unblocked to right return true; } else { return isPushable( prizeRight ); } } else { // not on solid ground yet return false; } } double pushPrize( PrizeStatus *inStatus, double inForce ) { if( isPushable( inStatus ) ) { PrizeStatus *prizeRight = getPrizeRight( inStatus ); double move = 0; if( prizeRight == NULL ) { // unblocked to right inStatus->mPushAccumulation += inForce; move = inStatus->mPushAccumulation; } else { // push this train (recursive) // our force decays as the train gets longer // 0.45 makes it slower to push a train of 2 prizes than // to push them singly, one after the other // The speed for a train of n prizes is 0.45^(n-1) // # prizes | Decay Factor Train | Effective Decay separate // 1 | 1 | 1 // 2 | 0.45 | 0.5 // 3 | 0.20 | 0.333... // 4 | 0.09 | 0.25 // 5 | 0.041 | 0.20 // thus, we have a good trade-off between fetching a bunch // of prizes on one jumping trip and then pushing the resulting // train, vs. taking multiple jumping trips and pushing // the prizes one at a time move = pushPrize( prizeRight, inForce * 0.45 ); } if( move >= 1 ) { // cap move at max of 1 unit per push move = 1; inStatus->mAnimation->mX += (int)move; // reset accumulator inStatus->mPushAccumulation = 0; /* if( inStatus->mAnimation->mX == kilnFireAnimations[0]->mX && inStatus->mAnimation->mY == kilnFireAnimations[0]->mY ) { // in fire inStatus->mMelting = true; } */ } return move; } else { return 0; } } double pushPrize( int inX, int inY, double inForce ) { PrizeStatus *status = getPrizeAt( inX, inY ); return pushPrize( status, inForce ); } extern int score; extern double timeLeft; extern double totalTime; void stepPrizes() { // first, cycle fire animations for( int k=0; kmFrameNumber; while( kilnFireAnimations[k]->mFrameNumber == oldFrameNumber ) { kilnFireAnimations[k]->mFrameNumber = randSource.getRandomBoundedInt( 0, kilnFireAnimations[k]->mNumFrames - 1 ); } } } kilnFireAnimationToUpdate ++; if( kilnFireAnimationToUpdate >= numKilnFireAnimations ) { kilnFireAnimationToUpdate = 0; } // next, cycle smoke animations for( int k=0; kmFrameNumber; while( kilnSmokeAnimations[k]->mFrameNumber == oldFrameNumber ) { kilnSmokeAnimations[k]->mFrameNumber = randSource.getRandomBoundedInt( 0, kilnSmokeAnimations[k]->mNumFrames - 1 ); } } } kilnSmokeAnimationToUpdate ++; if( kilnSmokeAnimationToUpdate >= numKilnSmokeAnimations ) { kilnSmokeAnimationToUpdate = 0; } // cycle through ash pit pages based on time left kilnAshPitAnimation->mPageNumber = ( 1 - timeLeft / totalTime ) * ( kilnAshPitAnimation->mNumPages - 1 ); // shrink fire down and fade smoke during last 1/2 of time if( timeLeft <= 0.5 * totalTime ) { // decreases as timeLeft -> 0 double fadeFactor = timeLeft / ( 0.5 * totalTime ); // increases as timeLeft -> 0 double shrinkFactor = 1 - fadeFactor; int maxOffset = tileH - 2; int yOffset = (int)( shrinkFactor * maxOffset ); double newSmokeAlpha = fadeFactor * kilnSmokeStartingAlpha; int k; for( k=0; kmY = kilnFireStartingY + yOffset; } for( k=0; kmTransparency = newSmokeAlpha; } } // now step prizes for( int i=0; imAnimation; if( status->mFalling ) { prize->mY += (int)( status->mDY ); // apply gravity status->mDY += 0.2; // cap it if( status->mDY > 5 ) { status->mDY = 5; } // change animation frame between 0 and 4 at beginning // of fall // don't do this if we've already finished animation // otherwise, we may play animation again if block starts falling // again (after hitting bottom) w/in 50 y units from mStartY if( prize->mFrameNumber < 4 ) { prize->mFrameNumber = (int)( 4 * (prize->mY - status->mStartY) / 50 ); if( prize->mFrameNumber > 4 ) { prize->mFrameNumber = 4; } } if( getPrizeFallingBelow( status ) ) { // another prize is already falling, and // it is ahead of us // slow our fall back to base velocity to give // other prize a chance to speed up and get out // of the way status->mDY = 1; } PrizeStatus *hitPrize = getPrizeBelow( status ); if( hitPrize != NULL ) { printf( "Hit prize.\n" ); // stop falling status->mFalling = false; status->mDY = 0; status->mFrozen = true; // back off int otherY = hitPrize->mAnimation->mY; prize->mY = otherY - prize->mFrameH; } if( status->mFalling && prize->mY > mapHeight - tileH - prize->mFrameH/2 - 1 ) { // hit bottom // stop falling status->mFalling = false; status->mDY = 0; status->mFrozen = true; prize->mY = mapHeight - tileH - prize->mFrameH/2 - 1; } } else if( status->mTouched ) { // check if still supported from underneath char supported = false; if( prize->mY >= mapHeight - tileH - prize->mFrameH/2 - 1 ) { // on bottom supported = true; } else if( getPrizeBelow( status ) != NULL ) { // on another prize supported = true; } if( !supported ) { // fall again status->mFalling = true; // start with some base velocity status->mDY = 1; // back to unpushable prize->mFrameNumber = 4; } else if( getPrizeLeft( status ) == NULL && isPushable( status ) ) { // show arrow prize->mFrameNumber = 5; } else if( !status->mMelting ) { // hide arrow prize->mFrameNumber = 4; } } if( status->mFrozen && ! status->mMelting ) { status->mScoreAnimation->mHide = false; status->mScoreAnimation->mX = prize->mX - 2; status->mScoreAnimation->mY = prize->mY - 2; status->mScoreTickTimer ++; if( status->mScoreTickTimer >= 75 ) { status->mScoreTickTimer = 0; status->mScore --; if( status->mScore < 1 ) { status->mScore = 1; } } status->mScoreAnimation->mFrameNumber = status->mScore; } if( status->mSlidingIntoFire ) { prize->mX += 2; status->mScoreAnimation->mX += 2; if( prize->mX >= kilnFireAnimations[0]->mX ) { // fully in fire, stop sliding, start melting prize->mX = kilnFireAnimations[0]->mX; status->mSlidingIntoFire = false; // only melt prizes if time still left (fire still burning) if( timeLeft > 0 ) { status->mMelting = true; } status->mScoreAnimation->mHide = true; } } if( status->mMelting ) { // change animation frame between 4 and 0 status->mMeltTimer ++; if( status->mMeltTimer == 5 ) { prize->mFrameNumber --; if( prize->mFrameNumber < 0 ) { prize->mFrameNumber = 0; if( ! status->mOrbSent ) { // start an orb at chimney top prizeOrbAnimation->mX = prize->mX; prizeOrbAnimation->mY = prize->mY - 36; prizeOrbAnimation->mTransparency = 1.0; prizeOrbAnimation->mHide = false; // hide prize prize->mHide = true; // move hidden prize out of the way so that it doesn't // interfere with collision detection prize->mX += tileW; status->mOrbSent = true; // show score rising with orb status->mScoreAnimation->mHide = false; status->mScoreAnimation->mX = prizeOrbAnimation->mX; status->mScoreAnimation->mY = prizeOrbAnimation->mY; } } // reset for next frame status->mMeltTimer = 0; } if( status->mOrbSent ) { // move orb upward prizeOrbAnimation->mY -= 2; prizeOrbAnimation->mTransparency -= 0.05; // move score along with it, but don't fade it status->mScoreAnimation->mY -= 2; if( prizeOrbAnimation->mTransparency <= 0 ) { // done dealing with this prize prizeOrbAnimation->mTransparency = 0; prizeOrbAnimation->mHide = true; status->mScoreAnimation->mHide = true; score += status->mScore; prizeList.deleteElement( i ); // back up in loop over prizeList i--; } } } else { // not melting yet if( kilnFireAnimations[0]->mX - status->mAnimation->mX < 11 && status->mAnimation->mY == kilnFireStartingY ) { // touching fire, start sliding in status->mSlidingIntoFire = true; } } } } gravitation-3+dfsg1.orig/game5/gameSource/kilnFire.png0000644000175000017500000000053110747757342021520 0ustar pabspabs‰PNG  IHDR /КѓЇQ IDAT8ЫЭ”1nУ0 EM…!Cv_!ZКAOр)^rOz‚ž AGŸС@с)—ˆ ” 4Ze›Љ…9‚I}|$ЅйћгЃљпЩiЛ[џA]§‹іЄ‘Ціaџf†:ъъCЕiф8H}q#Ч@@Ž!ХVilYРДѓЫѓъ‚›&рЬMРŽвВдеilѓзg[rZ– ИcЏ/{q к4ЇУ=/фиС>ЭШ Xэг)/›Ы‘3nжылнƒ8BЩЅ: вѓ"“"шєz{…‰PœЁaЅџцrнй0\4sУx]G.QuŒ=ІЛЕHk–‡;і" x§ї.чl„”— 4З‰їЄДo03Оp‚!–ПSМ&хIENDЎB`‚gravitation-3+dfsg1.orig/game5/gameSource/genColors.cpp0000644000175000017500000000220610761041043021663 0ustar pabspabs#include #include "minorGems/graphics/Image.h" #include "minorGems/graphics/converters/TGAImageConverter.h" #include "minorGems/io/file/File.h" #include "minorGems/io/file/FileOutputStream.h" #include "Gradient.h" int main() { double anchors[4] = { 0.0, 0.3333, 0.6666, 1.0 }; rgbColor colors[4] = { { 0.71, 0.28, 0.06 }, { 0.96, 0.55, 0.18 }, { 0.95, 0.84, 0.43 }, { 1.0, 0.98, 0.84 } }; Gradient grad( 4, anchors, colors ); int numSteps = 9; Image outImage( 1, numSteps + 1, 3 ); double *rChan = outImage.getChannel( 0 ); double *gChan = outImage.getChannel( 1 ); double *bChan = outImage.getChannel( 2 ); for( int i=0; i<=numSteps; i++ ) { rgbColor color = grad.sample( i / (double)numSteps ); rChan[i] = color.r; gChan[i] = color.g; bChan[i] = color.b; } File tgaFile( NULL, "genColors.tga" ); FileOutputStream tgaStream( &tgaFile ); TGAImageConverter converter; converter.formatImage( &outImage, &tgaStream ); } gravitation-3+dfsg1.orig/game5/documentation/0000755000175000017500000000000010762705354020020 5ustar pabspabsgravitation-3+dfsg1.orig/game5/documentation/toDo.txt0000644000175000017500000001454710762153353021475 0ustar pabspabsX-Hair on fire during mania ? x-Music idea: lots of tracks (6, maybe) where final, manic layers add melodies that are dissonant with base tracks. x-Make sure struct/union-based pixel color access works on little-endian machines. X-Game end when time runs out X-Better transition to title at end... instant, for now? X-Mez only throws ball when you are standing on the ground near him. X-Mez disappears toward end of game (leaves ball behind)... or maybe if ignored too long? Detect when Mez off screen for a chance for him to disappear. X-Pushing animation frames for main character X-Better fire (generated) in kiln (layered sprites look good enough) X-Additive blending for fires (lighten only) x-Fix bug with partial prize-kiln alignment x-How to blend tile sets when map is pre-rendered? X-Idea: time limit tied to fire dying down? Motivation for time limit. X-NO Idea: instant depression after a prize rises out of kiln? X-Update music player to allow selective muting and fade-in of tracks. x-Write music so that one track plays with depressed state, and all tracks play together with manic state. x-Fix bug that can trap you under a frozen block if you land first. (Is this still a problem? I can't reproduce it.) X-Better map: each section of map should highlight some problem/temptation associated with mechanics: x-Basics of a single prize (pushing it, etc.) x-Getting a chain of prizes allows you to keep jumping higher and higher. x-Long line of projects slower to push x-Projects get in the way of your walking during catch with mez x-You can get trapped down in a well after your mania wears off x-Projects on top of other projects must be pushed off first (handled by other sections.) X-These next two are in map, but won't work until falling column bug is fixed. x-Column of projects can block your access to mez until you can jump high enough to get over the column x-A column of 5 projects can completely seal you off from Mez for the rest of the game. x-Place where chain of prize-induced mania is necessary to keep jumping higher. X-Round off error during jump causes jitter at apex of jump. X-Fix arrow flicker right when block slides off top of another block. x-Clean out old code (spouse, chests, hash tables, etc.) X-If you're hitting keys right before gameEnd/title, then the title screen is only shown for a moment before the new game starts. (Changed to quick-fade instead of instant fade, seems to help). X-Emotion can get "stuck" at 1 if you get a chain of prizes right in a row X-Falling down through a column of prizes makes them fall on top of each other and land on top of each other. X-Optimize map loading? Startup is slow (11 second startup). Got down to 4 seconds. X-Add 1-pixel black bar between numbers and game image. X-Slow down base box-pushing rate X-Improve "mad" graphic to make it easier to see against sky. X-Make Mez more visible (flip background) Z-Fix lighting (due to sun in different position) x-Kiln x-Ash Pit x-Tiles x-Prize ice (and redo arrow) x-Base prize push rate even slower to make mania for prize pushing even more valuable? (And thus prizes that block you from mez even more of a problem?) No... seems slow enough as-is, especially with a train of prizes. X-Increase game length so that we have more time to experience loss of mez at end. Try: 6 minute game, Mez gone for last 2 minutes, fire fades during last 1 minute. An upcycle w/out mez takes 67 seconds... thus, current timing doesn't let us experience natural mania w/out Mez. Even this doesn't give you enough time post-Mez Fixes? 7-minute game, with 3-minutes post-Mez? Faster upswing? (33 sec?) One problem is that down-swing, even after getting a single prize, is slow (67 sec). Maybe base downswing rate should be faster? Mania short-lived? Okay, a faster base down-swing feels better. Tried faster upswing... no good, doesn't keep you "stuck" long enough to make you sweat. Want stuck to feel annoying. DO NOT PANDER TO PLAYER. Also, not enough time to explore all gameplay mechanics in a single game. How about: 8 minute game. Mez gone during last 3. Fire dies during last 1? Enough time for player to notice fire dying? Even better: fire visibly dies during last 4 minutes, but music fades during last minute. X-Title? Fire and Ashes? Something better? Look in DSM. Fire and Ashes Gravity Gravitation Pendulum Parabola The Law of Gravity The Simple Law of Gravity The Basic Law of Gravity Currently like the title "Gravitation". A simple word that everyone knows and everyone can pronounce/spell. Several layers of meaning (what goes up must come down, true of the character both physcially and emotionally, also the return back to home and the need for it, also the up-down-up-down motion through the level, also the motion of the ball, which is what the player experiences first upon starting the game). So the player is thinking about gravity when starting the game. The first thing they see is this ball-catching mini-game with the parabolic flight path of the ball... They might think, "Okay... so this gravity game is about the flight of a ball?" But after catching a few times, the view expands, and they jump upward to get a star. The star falls (again, through gavity), and then they start noticing the additional layers of meaning. Eventually, they notice that "mood" is directly linked to the strength of gravity as it affects their character... gravity is a metaphor for mood. X-Title screen graphic Fixed this stuff: X-General problem: various themes don't fit together. 365-day timer? So it's one year. But what about the fact that prizes freeze as they fall? Are we going to show seasonal changes in world graphics? How would prizes freeze, and then need to be thawed, in summer? X-Okay, so make it 3 months (90 days) in winter... Jan, Feb, March... that works, but then why would Mez leave at the end? Maybe he should leave only if you ignore him too much... like if you spend too much time up gathering prizes? X-Maybe he can leave at the end anyway... v1 release to do: x-Change name of target app x-Check last time for memory leaks. x-Create build directory tree x-Switch settings to fullscreen mode x-Readme x-Win32 build x-Source build x-Build mac Icon x-mac build x-Create a site meter x-Take a screen shot x-Post SF uploads x-Creator statementgravitation-3+dfsg1.orig/game5/documentation/Readme.txt0000644000175000017500000000010410762054651021746 0ustar pabspabsFor instructions, please see: http://hcsoftware.sf.net/gravitationgravitation-3+dfsg1.orig/game5/documentation/changeLog.txt0000644000175000017500000000114310762626267022454 0ustar pabspabsVersion 3 2008-March- (Thanks to Chris Hecker for pointing out that player-freeze during fade-out felt weird.) --Re-enabled player motion during game-end fade-out. --Added a 3-second title-screen freeze after fade-out to ensure that the player knows that the game is really over (so that key presses during the fade-out do not trigger a new game instantly). --Kiln now stops melting blocks (because fire is gone) during fade-out Version 2 2008-February-29 --Increased fade-out time at end of game. --Froze player during game-over fade-out. Version 1 2008-February-29 --Initial release.gravitation-3+dfsg1.orig/runToBuild0000755000175000017500000000075710762704566016203 0ustar pabspabs#!/bin/bash # # Modification History # # 2007-November-12 Jason Rohrer # Copied from Cultivation. # cd game5/gameSource chmod u+x ./configure ./configure echo "Building Gravitation..." make cd ../.. mkdir graphics mkdir music mkdir settings cp game5/gameSource/Gravitation ./Gravitation cp game5/documentation/Readme.txt . cp game5/gameSource/graphics/* ./graphics cp game5/gameSource/music/* ./music cp game5/gameSource/settings/* ./settings echo "Run Gravitation to play." gravitation-3+dfsg1.orig/minorGems/0000755000175000017500000000000010762704567016116 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/0000755000175000017500000000000010762704567016525 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/file/0000755000175000017500000000000010762704567017444 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/file/test/0000755000175000017500000000000010762704567020423 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/file/test/testChildFiles.cpp0000644000175000017500000000223110762704567024033 0ustar pabspabs/* * Modification History * * 2004-January-4 Jason Rohrer * Created. */ /** * A test program for the various child file functions in File.h * * @author Jason Rohrer. */ #include "minorGems/io/file/File.h" int main( int inNumArgs, char **inArgs ) { char *fileName = "linux"; if( inNumArgs > 1 ) { fileName = inArgs[1]; } File *testFile = new File( NULL, fileName ); int numChildren; File **childFiles = testFile->getChildFiles( &numChildren ); printf( "child files:\n" ); for( int i=0; igetFullFileName(); printf( " %s\n", fullName ); delete [] fullName; delete childFiles[i]; } delete [] childFiles; childFiles = testFile->getChildFilesRecursive( 10, &numChildren ); printf( "recursive child files:\n" ); for( int i=0; igetFullFileName(); printf( " %s\n", fullName ); delete [] fullName; delete childFiles[i]; } delete [] childFiles; delete testFile; return 0; } gravitation-3+dfsg1.orig/minorGems/io/file/test/testPath.cpp0000644000175000017500000000112210762704567022717 0ustar pabspabs/* * Modification History * * 2002-August-1 Jason Rohrer * Created. */ #include "Path.h" #include int main() { char *pathString = "/test/this/thing"; printf( "using path string = %s\n", pathString ); printf( "Constructing path.\n" ); Path *path = new Path( pathString ); printf( "Extracting path string.\n" ); char *extractedPathString = path->getPathStringTerminated(); printf( "extracted path string = %s\n", extractedPathString ); delete [] extractedPathString; delete path; return 1; } gravitation-3+dfsg1.orig/minorGems/io/file/unix/0000755000175000017500000000000010762704567020427 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/file/unix/DirectoryUnix.cpp0000644000175000017500000000141210762704567023741 0ustar pabspabs/* * Modification History * * 2003-January-23 Jason Rohrer * Created. * * 2003-November-10 Jason Rohrer * Added makeDirectory function. */ #include "minorGems/io/file/Directory.h" #include char Directory::removeDirectory( File *inFile ) { char *fileName = inFile->getFullFileName(); int result = rmdir( fileName ); delete [] fileName; if( result == 0 ) { return true; } else { return false; } } char Directory::makeDirectory( File *inFile ) { char *stringName = inFile->getFullFileName(); int result = mkdir( stringName, 0xFFFF ); delete [] stringName; if( 0 == result ) { return true; } else { return false; } } gravitation-3+dfsg1.orig/minorGems/io/file/File.h0000644000175000017500000005024110762704567020476 0ustar pabspabs/* * Modification History * * 2001-February-11 Jason Rohrer * Created. * * 2001-February-25 Jason Rohrer * Fixed file name bugs in length and existence functions. * * 2001-May-11 Jason Rohrer * Added a missing include. * * 2001-November-3 Jason Rohrer * Added a function for checking if a file is a directory. * Added a function for getting the child files of a directory. * Added a function for getting a pathless file name. * * 2001-November-13 Jason Rohrer * Made name length parameter optional in constructor. * Made return length parameter optional in name getting functions. * * 2001-November-17 Jason Rohrer * Added a functions for removing a file and for copying a file. * * 2002-March-11 Jason Rohrer * Added destruction comment to getFullFileName(). * * 2002-March-13 Jason Rohrer * Changed mName to be \0-terminated to fix interaction bugs with Path. * Fixed a missing delete. * Added a function for creating a directory. * * 2002-March-31 Jason Rohrer * Fixed some bad syntax. * * 2002-April-6 Jason Rohrer * Replaced use of strdup. * * 2002-April-8 Jason Rohrer * Fixed fopen bug. * * 2002-April-11 Jason Rohrer * Fixed a memory leak. * Fixed a casting error. * * 2002-June-28 Jason Rohrer * Added a function for copying a file class. * * 2002-August-3 Jason Rohrer * Added a function for getting the parent file. * * 2002-August-5 Jason Rohrer * Used an unused error variable. * * 2002-September-11 Jason Rohrer * Added return value to remove. * * 2003-January-27 Jason Rohrer * Added a function for reading file contents. * * 2003-February-3 Jason Rohrer * Added a function for writing a string to a file. * * 2003-March-13 Jason Rohrer * Added a function for getting a child file from a directory. * * 2003-June-2 Jason Rohrer * Fixed parent directory behavior when current file is root directory. * Fixed a bug in getting child files of root directory. * * 2003-November-6 Jason Rohrer * Added function for getting last modification time. * * 2003-November-10 Jason Rohrer * Changed to use platform-dependent makeDirectory function. * * 2004-January-4 Jason Rohrer * Added recursive child file functions. * * 2005-August-29 Jason Rohrer * Fixed an uninitialized variable warning. */ #include "minorGems/common.h" #ifndef FILE_CLASS_INCLUDED #define FILE_CLASS_INCLUDED #include #include #include #include #include "Path.h" #include "minorGems/util/SimpleVector.h" #include "minorGems/util/stringUtils.h" /** * File interface. Provides access to information about a * file. * * @author Jason Rohrer */ class File { public: /** * Constructs a file. * * @param inPath the path for this file. * Is destroyed when this class is destroyed. * Pass in NULL to specify * no path (the current working directory). * @param inName the name of the file to open. * Must be destroyed by caller if not const. * Copied internally. * @param inNameLength length of the name in chars, * or -1 to use the c-string length of inName * (assuming that inName is \0-terminated). * Defaults to -1. */ File( Path *inPath, char *inName, int inNameLength = -1 ); ~File(); /** * Gets whether this file is a directory. * * @return true iff this file is a directory. */ char isDirectory(); /** * Makes a directory in the location of this file. * * Can only succeed if exists() is false. * * @return true iff directory creation succeeded. */ char makeDirectory(); /** * Gets the files contained in this file if it is a directory. * * @param outNumFiles pointer to where the number of * files will be returned. * * @return an array of files, or NULL if this * file is not a directory, is an empty directory, or doesn't exist. * Must be destroyed by caller if non-NULL. */ File **getChildFiles( int *outNumFiles ); /** * Gets the files contained in this file if it is a directory and * recursively in subdirectories of this file. * * @param inDepthLimit the maximum subdirectory depth to recurse into. * If inDepthLimit is 0, then only child files in this directory * will be returned. * @param outNumFiles pointer to where the number of * files will be returned. * * @return an array of files, or NULL if this * file is not a directory, is an empty directory (or a directory * containing empty subdirectories), or doesn't exist. * Must be destroyed by caller if non-NULL. */ File **getChildFilesRecursive( int inDepthLimit, int *outNumFiles ); /** * Gets a child of this directory. * * @param inChildFileName the name of the child file. * Must be destroyed by caller if non-const. * * @return the child file (even if it does not exist), or NULL if * this file is not a directory. * Must be destroyed by caller if non-NULL. */ File *getChildFile( char *inChildFileName ); /** * Gets the parent directory of this file. * * @return the parent directory of this file. * Must be destroyed by caller. */ File *getParentDirectory(); /** * Gets the length of this file. * * @return the length of this file in bytes. Returns * 0 if the file does not exist. */ long getLength(); /** * Gets whether a file exists. * * @return true if the file exists. */ char exists(); /** * Gets the last modification time of this file. * * @return the modification time in seconds based on the * system clock. Returns 0 if the file does not exist. */ unsigned long getModificationTime(); /** * Removes this file from the disk, if it exists. * * @return true iff the remove succeeded, false if the removal * fails or the file does not exist. */ char remove(); /** * Copies this file object (does not copy the file described by * this object). * * @return a deep copy of this file object. */ File *copy(); /** * Copies the contents of this file into another file. * * @param inDestination the file to copy this file into. * If it exists, it will be overwritten. * If it does not exist, it will be created. * Must be destroyed by caller. * @param inBlockSize the block size to use when copying. * Defaults to blocks of 5000 bytes. */ void copy( File *inDestination, long inBlockSize = 5000 ); /** * Gets the full-path file name sufficient * to access this file from the current working * directory. * * @param outLength pointer to where the name length, in * characters, will be returned. Set to NULL to ignore * the output length. Defaults to NULL. * * @return the full path file name for this file, * in platform-specific form. Must be destroyed by caller. * The returned string is '\0' terminated, but this * extra character is not included in the length. * Must be destroyed by caller. */ char *getFullFileName( int *outLength = NULL ); /** * Gets the pathless name of this file. * * @param outLength pointer to where the name length, in * characters, will be returned. Set to NULL to ignore * the output length. Defaults to NULL. * * @return the name of this file. Must be destroyed by caller. */ char *getFileName( int *outLength = NULL ); /** * Reads the contents of this file. * * @return a \0-terminated string containing the file contents, * or NULL if reading the file into memory failed. * Must be destroyed by caller. */ char *readFileContents(); /** * Writes a string to this file. * * @param inString the \0-terminated string to write. * Must be destroyed by caller if non-const. * * @return true if the file was written to successfully, or * false otherwise. */ char writeToFile( char *inString ); private: Path *mPath; char *mName; int mNameLength; /** * Gets the files contained in this file if it is a directory and * recursively in subdirectories of this file. * * @param inDepthLimit the maximum subdirectory depth to recurse into. * If inDepthLimit is 0, then only child files in this directory * will be returned. * @param inResultVector vector to add the discovered files to. * Must be destroyed by caller. */ void getChildFilesRecursive( int inDepthLimit, SimpleVector *inResultVector ); }; inline File::File( Path *inPath, char *inName, int inNameLength ) : mPath( inPath ), mNameLength( inNameLength ) { if( inNameLength == -1 ) { inNameLength = strlen( inName ); mNameLength = inNameLength; } // copy name internally mName = stringDuplicate( inName ); } inline File::~File() { delete [] mName; if( mPath != NULL ) { delete mPath; } } inline long File::getLength() { struct stat fileInfo; // get full file name int length; char *stringName = getFullFileName( &length ); int statError = stat( stringName, &fileInfo ); delete [] stringName; if( statError == 0 ) { return fileInfo.st_size; } else { // file does not exist return 0; } } inline char File::isDirectory() { struct stat fileInfo; // get full file name int length; char *stringName = getFullFileName( &length ); int statError = stat( stringName, &fileInfo ); delete [] stringName; if( statError == -1 ) { return false; } else { return S_ISDIR( fileInfo.st_mode ); } } inline File **File::getChildFiles( int *outNumFiles ) { int length; char *stringName = getFullFileName( &length ); DIR *directory = opendir( stringName ); if( directory != NULL ) { SimpleVector< File* > *fileVector = new SimpleVector< File* >(); struct dirent *entry = readdir( directory ); if( entry == NULL ) { delete fileVector; closedir( directory ); delete [] stringName; *outNumFiles = 0; return NULL; } while( entry != NULL ) { // skip parentdir and thisdir files, if they occur if( strcmp( entry->d_name, "." ) && strcmp( entry->d_name, ".." ) ) { Path *newPath; if( mPath != NULL ) { newPath = mPath->append( mName ); } else { if( Path::isRoot( mName ) ) { // use name as a string path newPath = new Path( mName ); } else { char **folderPathArray = new char*[1]; folderPathArray[0] = mName; // a non-absolute path to this directory's contents int numSteps = 1; char absolute = false; newPath = new Path( folderPathArray, numSteps, absolute ); delete [] folderPathArray; } } // safe to pass d_name in directly because it is copied // internally by the constructor fileVector->push_back( new File( newPath, entry->d_name, strlen( entry->d_name ) ) ); } entry = readdir( directory ); } // now we have a vector full of this directory's files int vectorSize = fileVector->size(); *outNumFiles = vectorSize; if( vectorSize == 0 ) { delete fileVector; closedir( directory ); delete [] stringName; return NULL; } else { File **returnFiles = new File *[vectorSize]; for( int i=0; igetElement( i ) ); } delete fileVector; closedir( directory ); delete [] stringName; return returnFiles; } } else { delete [] stringName; *outNumFiles = 0; return NULL; } } inline File **File::getChildFilesRecursive( int inDepthLimit, int *outNumFiles ) { // create a vector for results SimpleVector *resultVector = new SimpleVector(); // call the recursive function getChildFilesRecursive( inDepthLimit, resultVector ); // extract results from vector File **resultArray = NULL; int numResults = resultVector->size(); if( numResults > 0 ) { resultArray = resultVector->getElementArray(); } delete resultVector; *outNumFiles = numResults; return resultArray; } inline void File::getChildFilesRecursive( int inDepthLimit, SimpleVector *inResultVector ) { // get our child files int numChildren; File **childFiles = getChildFiles( &numChildren ); if( childFiles != NULL ) { // for each child, add it to vector and // recurse into it if it is a directory for( int i=0; ipush_back( child ); if( child->isDirectory() ) { // skip recursion if we have hit our depth limit if( inDepthLimit > 0 ) { // recurse into this subdirectory child->getChildFilesRecursive( inDepthLimit - 1, inResultVector ); } } } delete [] childFiles; } } inline File *File::getChildFile( char *inChildFileName ) { // make sure we are a directory if( !isDirectory() ) { return NULL; } // get a path to this directory Path *newPath; if( mPath != NULL ) { newPath = mPath->append( mName ); } else { char **folderPathArray = new char*[1]; folderPathArray[0] = mName; // a non-absolute path to this directory's contents int numSteps = 1; char absolute = false; newPath = new Path( folderPathArray, numSteps, absolute ); delete [] folderPathArray; } return new File( newPath, inChildFileName ); } inline File *File::getParentDirectory() { if( mPath != NULL ) { char *parentName; Path *parentPath; if( strcmp( mName, ".." ) == 0 ) { // already a parent dir reference // append one more parent dir reference with parentName below parentPath = mPath->append( ".." ); parentName = stringDuplicate( ".." ); } else { // not a parent dir reference, so we can truncate parentPath = mPath->truncate(); parentName = mPath->getLastStep(); } File *parentFile = new File( parentPath, parentName ); delete [] parentName; return parentFile; } else { if( Path::isRoot( mName ) ) { // we are already at the root return new File( NULL, mName ); } else { // append parent dir symbol to path char **parentPathSteps = new char*[1]; parentPathSteps[0] = mName; Path *parentPath = new Path( parentPathSteps, 1, false ); char *parentName = ".."; File *parentFile = new File( parentPath, parentName ); delete [] parentPathSteps; return parentFile; } } } inline char File::exists() { struct stat fileInfo; // get full file name int length; char *stringName = getFullFileName( &length ); int statError = stat( stringName, &fileInfo ); delete [] stringName; if( statError == 0 ) { return true; } else { // file does not exist return false; } } inline unsigned long File::getModificationTime() { struct stat fileInfo; // get full file name int length; char *stringName = getFullFileName( &length ); int statError = stat( stringName, &fileInfo ); delete [] stringName; if( statError == 0 ) { return fileInfo.st_mtime; } else { // file does not exist return 0; } } inline char File::remove() { char returnVal = false; if( exists() ) { char *stringName = getFullFileName(); int error = ::remove( stringName ); if( error == 0 ) { returnVal = true; } delete [] stringName; } return returnVal; } inline File *File::copy() { Path *pathCopy = NULL; if( mPath != NULL ) { pathCopy = mPath->copy(); } return new File( pathCopy, mName ); } inline void File::copy( File *inDestination, long inBlockSize ) { char *thisFileName = getFullFileName(); char *destinationFileName = inDestination->getFullFileName(); FILE *thisFile = fopen( thisFileName, "rb" ); FILE *destinationFile = fopen( destinationFileName, "wb" ); long length = getLength(); long bytesCopied = 0; char *buffer = new char[ inBlockSize ]; while( bytesCopied < length ) { long bytesToCopy = inBlockSize; // end of file case if( length - bytesCopied < bytesToCopy ) { bytesToCopy = length - bytesCopied; } fread( buffer, 1, bytesToCopy, thisFile ); fwrite( buffer, 1, bytesToCopy, destinationFile ); bytesCopied += bytesToCopy; } fclose( thisFile ); fclose( destinationFile ); delete [] buffer; delete [] thisFileName; delete [] destinationFileName; } inline char *File::getFileName( int *outLength ) { char *returnName = stringDuplicate( mName ); if( outLength != NULL ) { *outLength = mNameLength; } return returnName; } inline char *File::getFullFileName( int *outLength ) { int length = mNameLength; int pathLength = 0; char *path = NULL; if( mPath != NULL ) { path = mPath->getPathString( &pathLength ); length += pathLength; } // extra character for '\0' termination char *returnString = new char[ length + 1 ]; if( path != NULL ) { memcpy( returnString, path, pathLength ); memcpy( &( returnString[pathLength] ), mName, mNameLength ); delete [] path; } else { // no path, so copy the name directly in memcpy( returnString, mName, mNameLength ); } // terminate the string returnString[ length ] = '\0'; if( outLength != NULL ) { *outLength = length; } return returnString; } #include "minorGems/io/file/FileInputStream.h" #include "minorGems/io/file/FileOutputStream.h" inline char *File::readFileContents() { if( exists() ) { int length = getLength(); char *returnString = new char[ length + 1 ]; if( returnString != NULL ) { FileInputStream *input = new FileInputStream( this ); int numRead = input->read( (unsigned char *)returnString, length ); delete input; if( numRead == length ) { returnString[ length ] = '\0'; return returnString; } else { delete [] returnString; return NULL; } } else { // failed to allocate this much memory return NULL; } } else { return NULL; } } inline char File::writeToFile( char *inString ) { long stringLength = strlen( inString ); FileOutputStream *output = new FileOutputStream( this ); long numWritten = output->writeString( inString ); delete output; if( stringLength == numWritten ) { return true; } else { return false; } } #include "Directory.h" inline char File::makeDirectory() { if( exists() ) { return false; } else { return Directory::makeDirectory( this ); } } #endif gravitation-3+dfsg1.orig/minorGems/io/file/linux/0000755000175000017500000000000010762704567020603 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/file/linux/PathLinux.cpp0000644000175000017500000000220610762704567023223 0ustar pabspabs/* * Modification History * * 2001-February-12 Jason Rohrer * Created. * * 2001-August-1 Jason Rohrer * Added missing length return value. * * 2003-June-2 Jason Rohrer * Added support for new path checking functions. */ #include "minorGems/io/file/Path.h" #include "minorGems/util/stringUtils.h" /* * Linux-specific path implementation. May be compatible * with other posix-complient systems. */ char Path::getDelimeter() { return '/'; } char *Path::getAbsoluteRoot( int *outLength ) { char *returnString = new char[1]; returnString[0] = '/'; *outLength = 1; return returnString; } char Path::isAbsolute( char *inPathString ) { if( inPathString[0] == '/' ) { return true; } else { return false; } } char *Path::extractRoot( char *inPathString ) { if( isAbsolute( inPathString ) ){ return stringDuplicate( "/" ); } else { return NULL; } } char Path::isRoot( char *inPathString ) { if( strcmp( inPathString, "/" ) == 0 ) { return true; } else { return false; } } gravitation-3+dfsg1.orig/minorGems/io/file/FileOutputStream.h0000644000175000017500000000653410762704567023101 0ustar pabspabs/* * Modification History * * 2001-February-11 Jason Rohrer * Created. * * 2001-April-12 Jason Rohrer * Changed so that File is not destroyed when this stream is destroyed. * * 2001-April-29 Jason Rohrer * Fixed a bug in the use of fwrite * (num elements and element size swapped). * Fixed a memory leak in the error message handling. * * 2006-August-22 Jason Rohrer * Fixed include order bug. */ #include "minorGems/common.h" #include "File.h" #ifndef FILE_OUTPUT_STREAM_CLASS_INCLUDED #define FILE_OUTPUT_STREAM_CLASS_INCLUDED #include "minorGems/io/OutputStream.h" #include /** * File implementation of an OutputStream. * * @author Jason Rohrer */ class FileOutputStream : public OutputStream { public: /** * Constructs an output stream. * * @param inFile the file to open for writing. * If the file does not exist, it will be created. * inFile is NOT destroyed when this class is destroyed. * @param inAppend set to true to append to file. If * file does not exist, file is still created. Defaults * to false. */ FileOutputStream( File *inFile, char inAppend = false ); /** * Destroys this stream and closes the file. */ ~FileOutputStream(); /** * Gets the file attached to this stream. * * @return the file used by this stream. * Should not be modified or destroyed by caller until after * this class is destroyed. */ File *getFile(); // implementst OutputStream interface virtual long write( unsigned char *inBuffer, long inNumBytes ); private: File *mFile; FILE *mUnderlyingFile; }; inline FileOutputStream::FileOutputStream( File *inFile, char inAppend ) : mFile( inFile ) { int fileNameLength; char *fileName = mFile->getFullFileName( &fileNameLength ); if( inAppend ) { mUnderlyingFile = fopen( fileName, "ab" ); } else { mUnderlyingFile = fopen( fileName, "wb" ); } if( mUnderlyingFile == NULL ) { // file open failed. char *stringBuffer = new char[ fileNameLength + 50 ]; sprintf( stringBuffer, "Opening file %s failed.", fileName ); setNewLastError( stringBuffer ); } delete [] fileName; } inline FileOutputStream::~FileOutputStream() { if( mUnderlyingFile != NULL ) { fclose( mUnderlyingFile ); } } inline File *FileOutputStream::getFile() { return mFile; } inline long FileOutputStream::write( unsigned char *inBuffer, long inNumBytes ) { if( mUnderlyingFile != NULL ) { long numWritten = fwrite( inBuffer, 1, inNumBytes, mUnderlyingFile ); if( numWritten < inNumBytes ) { int fileNameLength; char *fileName = mFile->getFullFileName( &fileNameLength ); // some other kind of error occured char *stringBuffer = new char[ fileNameLength + 50 ]; sprintf( stringBuffer, "Writing to file %s failed.", fileName ); setNewLastError( stringBuffer ); delete [] fileName; if( numWritten == 0 ) { // a complete write failure return -1; } } return numWritten; } else { // file was not opened properly int fileNameLength; char *fileName = mFile->getFullFileName( &fileNameLength ); char *stringBuffer = new char[ fileNameLength + 50 ]; sprintf( stringBuffer, "File %s was not opened properly before writing.", fileName ); setNewLastError( stringBuffer ); return -1; } } #endif gravitation-3+dfsg1.orig/minorGems/io/file/win32/0000755000175000017500000000000010762704567020406 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/file/win32/dirent.h0000644000175000017500000000327610762704567022054 0ustar pabspabs/* * Modification History * * 2002-April-7 Jason Rohrer * Added a mkdir wrapper for CodeWarrior. * * 2002-April-11 Jason Rohrer * Changed type of mode parameter to work with Visual C++. * Added missing macros. * * 2002-July-22 Jason Rohrer * Commented out mkdir replacement function to work with new MSL. * * 2002-October-13 Jason Rohrer * Re-added mkdir wrapper function, since both CW4 and VC++ need it. */ #include "minorGems/common.h" /* Declaration of POSIX directory browsing functions and types for Win32. Kevlin Henney (mailto:kevlin@acm.org), March 1997. Copyright Kevlin Henney, 1997. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose is hereby granted without fee, provided that this copyright and permissions notice appear in all copies and derivatives, and that no charge may be made for the software and its documentation except to cover cost of distribution. */ #ifndef DIRENT_INCLUDED #define DIRENT_INCLUDED typedef struct DIR DIR; struct dirent { char *d_name; }; DIR *opendir(const char *); int closedir(DIR *); struct dirent *readdir(DIR *); void rewinddir(DIR *); #include /** * The Metrowerks Standard Library seems * to have only a 1-parameter mkdir command in sys/stat.h. */ int mkdir( const char *pathname, unsigned int mode ); // make sure our needed macros are defined // S_IFMT and S_IFDIR seem to be defined everywhere #ifndef __S_ISTYPE #define __S_ISTYPE(mode, mask) (((mode) & S_IFMT) == (mask)) #endif #ifndef S_ISDIR #define S_ISDIR(mode) __S_ISTYPE((mode), S_IFDIR) #endif #endif gravitation-3+dfsg1.orig/minorGems/io/file/win32/DirectoryWin32.cpp0000644000175000017500000000140510762704567023701 0ustar pabspabs/* * Modification History * * 2003-January-23 Jason Rohrer * Created. * * 2003-November-10 Jason Rohrer * Added makeDirectory function. */ #include "minorGems/io/file/Directory.h" #include char Directory::removeDirectory( File *inFile ) { char *fileName = inFile->getFullFileName(); int result = _rmdir( fileName ); delete [] fileName; if( result == 0 ) { return true; } else { return false; } } char Directory::makeDirectory( File *inFile ) { char *stringName = inFile->getFullFileName(); int result = mkdir( stringName ); delete [] stringName; if( 0 == result ) { return true; } else { return false; } } gravitation-3+dfsg1.orig/minorGems/io/file/win32/dirent.cpp0000644000175000017500000000654310762704567022407 0ustar pabspabs/* * Modification History * * 2002-April-7 Jason Rohrer * Added a mkdir wrapper for CodeWarrior. * * 2002-April-11 Jason Rohrer * Changed type of mode parameter to work with Visual C++. * Added missing include. * * 2002-July-22 Jason Rohrer * Commented out mkdir replacement function to work with new MSL. * * 2002-October-13 Jason Rohrer * Re-added mkdir wrapper function, since both CW4 and VC++ need it. */ /* Implementation of POSIX directory browsing functions and types for Win32. Kevlin Henney (mailto:kevlin@acm.org), March 1997. Copyright Kevlin Henney, 1997. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose is hereby granted without fee, provided that this copyright and permissions notice appear in all copies and derivatives, and that no charge may be made for the software and its documentation except to cover cost of distribution. This software is supplied "as is" without express or implied warranty. But that said, if there are any problems please get in touch. */ #include #include #include #include #include #include struct DIR { long handle; /* -1 for failed rewind */ struct _finddata_t info; struct dirent result; /* d_name null iff first time */ char *name; /* NTBS */ }; DIR *opendir(const char *name) { DIR *dir = 0; if(name && name[0]) { size_t base_length = strlen(name); const char *all = /* the root directory is a special case... */ strchr("/\\", name[base_length - 1]) ? "*" : "/*"; if((dir = (DIR *) malloc(sizeof *dir)) != 0 && (dir->name = (char *) malloc(base_length + strlen(all) + 1)) != 0) { strcat(strcpy(dir->name, name), all); if((dir->handle = _findfirst(dir->name, &dir->info)) != -1) { dir->result.d_name = 0; } else /* rollback */ { free(dir->name); free(dir); dir = 0; } } else /* rollback */ { free(dir); dir = 0; errno = ENOMEM; } } else { errno = EINVAL; } return dir; } int closedir(DIR *dir) { int result = -1; if(dir) { if(dir->handle != -1) { result = _findclose(dir->handle); } free(dir->name); free(dir); } if(result == -1) /* map all errors to EBADF */ { errno = EBADF; } return result; } struct dirent *readdir(DIR *dir) { struct dirent *result = 0; if(dir && dir->handle != -1) { if(!dir->result.d_name || _findnext(dir->handle, &dir->info) != -1) { result = &dir->result; result->d_name = dir->info.name; } } else { errno = EBADF; } return result; } void rewinddir(DIR *dir) { if(dir && dir->handle != -1) { _findclose(dir->handle); dir->handle = _findfirst(dir->name, &dir->info); dir->result.d_name = 0; } else { errno = EBADF; } } int mkdir( const char *pathname, unsigned int mode ) { return mkdir( pathname ); } gravitation-3+dfsg1.orig/minorGems/io/file/win32/PathWin32.cpp0000644000175000017500000000321510762704567022632 0ustar pabspabs/* * Modification History * * 2001-February-12 Jason Rohrer * Created. * * 2001-March-4 Jason Rohrer * Fixed delimeter constants. * * 2001-August-1 Jason Rohrer * Added missing length return value. * * 2003-June-2 Jason Rohrer * Added support for new path checking functions. */ #include "minorGems/io/file/Path.h" #include "minorGems/util/stringUtils.h" /* * Windows-specific path implementation. */ char Path::getDelimeter() { return '\\'; } char *Path::getAbsoluteRoot( int *outLength) { // C:\ is the only root we can generically return char *returnString = new char[3]; returnString[0] = 'C'; returnString[1] = ':'; returnString[2] = '\\'; *outLength = 3; return returnString; } char Path::isAbsolute( char *inPathString ) { // ignore first character, which will be drive letter if( inPathString[1] == ':' && inPathString[2] == '\\' ) { return true; } else { return false; } } char *Path::extractRoot( char *inPathString ) { if( isAbsolute( inPathString ) ){ // copy path, then trim to only three characters char *pathCopy = stringDuplicate( inPathString ); pathCopy[ 3 ] = '\0'; char *trimmedCopy = stringDuplicate( pathCopy ); delete [] pathCopy; return trimmedCopy; } else { return NULL; } } char Path::isRoot( char *inPathString ) { // must be of form "c:\" if( strlen( inPathString ) == 3 && inPathString[1] == ':' && inPathString[2] == '\\' ) { return true; } else { return false; } } gravitation-3+dfsg1.orig/minorGems/io/file/Path.h0000644000175000017500000003536210762704567020522 0ustar pabspabs/* * Modification History * * 2001-February-12 Jason Rohrer * Created. * * 2001-May-11 Jason Rohrer * Added a version of getPathString that * returns a '\0' terminated string. * * 2001-September-21 Jason Rohrer * Added a missing include. * * 2001-September-23 Jason Rohrer * Added a copy function. * Made some comments more explicit. * Changed the constructor to allow for const path step strings. * * 2001-November-3 Jason Rohrer * Added a function for appending a string to a path. * Changed the interface to the main constructor. * * 2002-March-29 Jason Rohrer * Added Fortify inclusion. * * 2002-April-11 Jason Rohrer * Fixed a variable scoping bug. * * 2002-July-2 Jason Rohrer * Fixed a major memory leak in copy(). * * 2002-August-1 Jason Rohrer * Added support for path truncation. * Added support for parsing platform-dependent path strings. * * 2003-May-29 Jason Rohrer * Fixed a bug when an extra delimeters are at the end of the path. * Fixed a bug when string path consists only of root. * * 2003-June-2 Jason Rohrer * Fixed a bug in absolute path detection. * Added platform-specific functions for root and absolute path detection. * Fixed a memory bug when string path contains root only. * Fixed a path step bug when path is root. * Fixed bugs in truncate and append when non-default root string is used. * * 2005-August-29 Jason Rohrer * Fixed an uninitialized variable warning. */ #include "minorGems/common.h" #ifndef PATH_CLASS_INCLUDED #define PATH_CLASS_INCLUDED #include #include "minorGems/util/stringUtils.h" #ifdef FORTIFY #include "minorGems/util/development/fortify/fortify.h" #endif /** * Platform-independent file path interface. Contains * all of path except for file name. Thus, appending * a file name to the path will produce a complete file path. * * E.g., on Linux, file path: * temp/files/ * file name: * test.txt * full path: * temp/files/test.txt * * @author Jason Rohrer */ class Path { public: /** * Constructs a path. * * @param inPathSteps an array of c-strings representing * each step in the path, with no delimeters. * For example, { "temp", "files" } to represent * the linux path temp/files. * Must be destroyed by caller since copied internally. * @param inNumSteps the number of strings in the path. * @param inAbsolute set to true to make this an absolute * path. For example, in Linux, an absolute path * is one that starts with '/', as in /usr/include/. * The effects of inAbsolute vary by platform. * @param inRootString the root string for this path if it * is absolute, or NULL to specify a default root. * Defaults to NULL. * Must be destroyed by caller if non-NULL. */ Path( char **inPathSteps, int inNumSteps, char inAbsolute, char *inRootString = NULL ); /** * Constructs a path by parsing a platform-dependent path string. * * @param inPathSteps a \0-terminated string representing the path. * Must be destroyed by caller. */ Path( char *inPathString ); ~Path(); /** * Returns a complete, platform-dependent string path. * * @param outLength pointer to where the path length, in * characters, will be returned. * * @return a new char array containing the path. Note * that the string is not terminated by '\0'. Must * be destroyed by the caller. */ char *getPathString( int *outLength ); /** * Returns a complete, platform-dependent string path, terminated * bye '\0'. * * @return a new char array containing the path. Note * that the string IS terminated by '\0'. Must * be destroyed by the caller. */ char *getPathStringTerminated(); /** * Gets the platform-specific path delimeter. * * Note that this function is implemented separately for * each supported platform. * * @return the path delimeter. */ static char getDelimeter(); /** * Gets start characters for an absolute path. * * Note that this function is implemented separately for * each supported platform. * * @param outLength pointer to where the string length, in * characters, will be returned. * * @return the absolute path start string characters. For * example, on Linux, this would be the string "/". * Must be destroyed by the caller. */ static char *getAbsoluteRoot( int *outLength ); /** * Gets whether a path string is absolute. * * Note that this function is implemented separately for * each supported platform. * * @param inPathString the string to check. * Must be destroyed by caller if non-const. * * @return true if the string is absolute, or false otherwise. */ static char isAbsolute( char *inPathString ); /** * Extracts the root string from a path string. * * * @param inPathString the string to check. * Must be destroyed by caller if non-const. * * @return the root string, or NULL if inPathString is not * absolute. Must be destroyed by caller if non-NULL. */ static char *extractRoot( char *inPathString ); /** * Gets whether a path string is a root path. * * Note that this function is implemented separately for * each supported platform. For example, on Unix, only "/" * is the root path, while on Windows, both "c:\" and "d:\" might * be root paths. * * @param inPathString the string to check. * Must be destroyed by caller if non-const. * * @return true if the string is a root string, or false otherwise. */ static char isRoot( char *inPathString ); /** * Gets start string for an absolute path. * * @return the absolute path start string in \0-terminated form. * Must be destroyed by the caller. */ static char *getAbsoluteRootString(); /** * Copies this path. * * @return a new path that is a deep copy of this path. */ Path *copy(); /** * Constructs a new path by appending an additional * step onto this path. * * @param inStepString the step to add to this path. * Must be destroyed by caller if non-const. * * @return a new path with the extra step. * Must be destroyed by caller. */ Path *append( char *inStepString ); /** * Constructs a new path by removing the last step from this path. * * @return a new path, or NULL if there is only one step in this path. * Must be destroyed by caller. */ Path *truncate(); /** * Gets the last step in this path. * * @return the last step. Must be destroyed by caller. */ char *getLastStep(); private: char **mPathSteps; int mNumSteps; int *mStepLength; char mAbsolute; // the root string of this path, if it is absolute char *mRootString; }; inline Path::Path( char **inPathSteps, int inNumSteps, char inAbsolute, char *inRootString ) : mNumSteps( inNumSteps ), mAbsolute( inAbsolute ), mRootString( NULL ) { if( inRootString != NULL ) { mRootString = stringDuplicate( inRootString ); } // copy the path steps mPathSteps = new char*[ mNumSteps ]; mStepLength = new int[ mNumSteps ]; for( int i=0; i 1 ) { // don't count tail end delimeters delimCount++; } currentDelimPointer = strstr( &( currentDelimPointer[1] ), delimString ); } // no delimeter at end of path mNumSteps = delimCount + 1; mPathSteps = new char*[ mNumSteps ]; mStepLength = new int[ mNumSteps ]; // now extract the chars between delimeters as path steps currentDelimPointer = strstr( pathRootSkipped, delimString ); int stepIndex = 0; currentDelimPointer[0] = '\0'; mPathSteps[ stepIndex ] = stringDuplicate( pathRootSkipped ); mStepLength[ stepIndex ] = strlen( mPathSteps[ stepIndex ] ); stepIndex++; while( currentDelimPointer != NULL ) { char *nextDelimPointer = strstr( &( currentDelimPointer[1] ), delimString ); if( nextDelimPointer != NULL ) { nextDelimPointer[0] = '\0'; } mPathSteps[ stepIndex ] = stringDuplicate( &( currentDelimPointer[1] ) ); mStepLength[ stepIndex ] = strlen( mPathSteps[ stepIndex ] ); stepIndex++; currentDelimPointer = nextDelimPointer; } } else { // no delimeters if( strlen( pathRootSkipped ) > 0 ) { mNumSteps = 1; mPathSteps = new char*[1]; mPathSteps[0] = stringDuplicate( pathRootSkipped ); mStepLength = new int[1]; mStepLength[0] = strlen( mPathSteps[0] ); } else { // path with root only mNumSteps = 0; mPathSteps = new char*[0]; mStepLength = new int[0]; } } delete [] delimString; delete [] pathStringCopy; } inline Path::~Path() { // delete each step for( int i=0; i= 1 ) { return stringDuplicate( mPathSteps[ mNumSteps - 1 ] ); } else { if( mAbsolute ) { if( mRootString != NULL ) { return stringDuplicate( mRootString ); } else { return getAbsoluteRootString(); } } else { // no path steps and not absolute... return stringDuplicate( "" ); } } } inline char *Path::getAbsoluteRootString() { int rootLength; char *root = getAbsoluteRoot( &rootLength ); char *rootString = new char[ rootLength + 1 ]; strncpy( rootString, root, rootLength ); // strncopy won't add termination if length limit reached rootString[ rootLength ] = '\0'; delete [] root; return rootString; } #endif gravitation-3+dfsg1.orig/minorGems/io/file/Directory.h0000644000175000017500000000262210762704567021563 0ustar pabspabs/* * Modification History * * 2003-January-23 Jason Rohrer * Created. * * * 2003-November-10 Jason Rohrer * Added makeDirectory function. */ #include "minorGems/common.h" #include "minorGems/io/file/File.h" #ifndef DIRECTORY_INCLUDED #define DIRECTORY_INCLUDED /** * Class of static directory functions. * * This class exists because most directory operations are * platform-dependent, and a large body of existing code * depends on a platform-independent File.h. * * @author Jason Rohrer. */ class Directory { public: /** * Removes a directory. * * The directory must be empty for this call to succeed. * * @param inFile the file representing the directory. * Must be destroyed by caller. * * @return true if the directory is removed successfully, or * false otherwise (for example, if the directory is not empy). */ static char removeDirectory( File *inFile ); /** * Makes a directory. * * @param inFile the file representing the directory. * Must be destroyed by caller. * * @return true if the directory is removed successfully, or * false otherwise (for example, if the directory is not empy). */ static char makeDirectory( File *inFile ); }; #endif gravitation-3+dfsg1.orig/minorGems/io/file/testPath.cpp0000644000175000017500000000112210762704567021740 0ustar pabspabs/* * Modification History * * 2002-August-1 Jason Rohrer * Created. */ #include "Path.h" #include int main() { char *pathString = "/test/this/thing"; printf( "using path string = %s\n", pathString ); printf( "Constructing path.\n" ); Path *path = new Path( pathString ); printf( "Extracting path string.\n" ); char *extractedPathString = path->getPathStringTerminated(); printf( "extracted path string = %s\n", extractedPathString ); delete [] extractedPathString; delete path; return 1; } gravitation-3+dfsg1.orig/minorGems/io/file/UniversalFileIO.h0000644000175000017500000000572410762704567022625 0ustar pabspabs// Jason Rohrer // UniversalFileIO.h /** * * Object that handles universal file reading and writing * Writes files as big endian, even on little endian machines * * Assumes that longs and floats are 32-bits * * Created 1-12-99 * Mods: * Jason Rohrer 1-30-2000 Fixed fwrite functions to work on little endian machines */ #ifndef UNIVERSAL_FILE_IO_INCLUDED #define UNIVERSAL_FILE_IO_INCLUDED #include class UniversalFileIO { public: UniversalFileIO(); long freadLong( FILE *f ); float freadFloat( FILE *f ); void fwriteLong( FILE *f, long x ); void fwriteFloat( FILE *f, float x ); private: char machineBigEndian; char bytesInLong; char bytesInFloat; }; inline UniversalFileIO::UniversalFileIO() : machineBigEndian( true ), bytesInLong( 4 ), bytesInFloat( 4 ) { // test whether machine is big endian long test = 1; char testChopped = (*(char*)&test); if( testChopped == 1 ) machineBigEndian = false; } inline long UniversalFileIO::freadLong( FILE *f ) { if( machineBigEndian ) { long returnVal; fread((void *)&returnVal, sizeof(long), 1, f); return returnVal; } else { unsigned char *buffer = new unsigned char[bytesInLong]; fread((void *)buffer, sizeof(char), bytesInLong, f); // now put the bytes into a long long returnVal = (long)( buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3] ); delete [] buffer; return returnVal; } } inline float UniversalFileIO::freadFloat( FILE *f ) { if( machineBigEndian ) { float returnVal; fread( (void *)&returnVal, sizeof(float), 1, f ); return returnVal; } else { unsigned char *buffer = new unsigned char[bytesInFloat]; fread( (void *)buffer, sizeof(char), bytesInFloat, f ); // now put the bytes into a long long temp = (long)(buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]); delete [] buffer; return *((float *) &temp); // convert long into a float } } inline void UniversalFileIO::fwriteLong( FILE *f, long x ) { if( machineBigEndian ) { fwrite( (void *)&x, sizeof(long), 1, f ); } else { unsigned char *buffer = new unsigned char[bytesInLong]; buffer[0] = (unsigned char)(x >> 24); // put bytes from long into char buffer buffer[1] = (unsigned char)(x >> 16); buffer[2] = (unsigned char)(x >> 8); buffer[3] = (unsigned char)(x); fwrite( (void *)buffer, sizeof(char), bytesInLong, f ); } } inline void UniversalFileIO::fwriteFloat( FILE *f, float x ) { if( machineBigEndian ) { fwrite( (void *)&x, sizeof(float), 1, f ); } else { unsigned char *buffer = new unsigned char[bytesInFloat]; long temp = *((long*)&x); // convert float into long so that bit-wise ops can be performed buffer[0] = (unsigned char)(temp >> 24); // put bytes from float into char buffer buffer[1] = (unsigned char)(temp >> 16); buffer[2] = (unsigned char)(temp >> 8); buffer[3] = (unsigned char)(temp); fwrite( (void *)buffer, sizeof(char), bytesInFloat, f ); } } #endifgravitation-3+dfsg1.orig/minorGems/io/file/FileInputStream.h0000644000175000017500000000666410762704567022704 0ustar pabspabs/* * Modification History * * 2001-February-11 Jason Rohrer * Created. * * 2001-April-12 Jason Rohrer * Changed so that File is not destroyed when this stream is destroyed. * * 2001-April-29 Jason Rohrer * Fixed a bug in the use of fread * (num elements and element size swapped). * Fixed a memory leak in the error message handling. * * 2006-November-23 Jason Rohrer * Fixed a memory leak in error message handling. */ #include "minorGems/common.h" #ifndef FILE_INPUT_STREAM_CLASS_INCLUDED #define FILE_INPUT_STREAM_CLASS_INCLUDED #include "minorGems/io/InputStream.h" #include "File.h" #include /** * File implementation of an InputStream. * * @author Jason Rohrer */ class FileInputStream : public InputStream { public: /** * Constructs an input stream. * * @param inFile the file to open for reading. * If the file does not exist, all calls to read will fail. * inFile is NOT destroyed when this class is destroyed. */ FileInputStream( File *inFile ); /** * Destroys this stream and closes the file. */ ~FileInputStream(); /** * Gets the file attached to this stream. * * @return the file used by this stream. * Should not be modified or destroyed by caller until after * this class is destroyed. */ File *getFile(); // implementst InputStream interface virtual long read( unsigned char *inBuffer, long inNumBytes ); private: File *mFile; FILE *mUnderlyingFile; }; inline FileInputStream::FileInputStream( File *inFile ) : mFile( inFile ) { int fileNameLength; char *fileName = mFile->getFullFileName( &fileNameLength ); mUnderlyingFile = fopen( fileName, "rb" ); if( mUnderlyingFile == NULL ) { // file open failed. char *stringBuffer = new char[ fileNameLength + 50 ]; sprintf( stringBuffer, "Opening file %s failed.", fileName ); setNewLastError( stringBuffer ); } delete [] fileName; } inline FileInputStream::~FileInputStream() { if( mUnderlyingFile != NULL ) { fclose( mUnderlyingFile ); } } inline File *FileInputStream::getFile() { return mFile; } inline long FileInputStream::read( unsigned char *inBuffer, long inNumBytes ) { if( mUnderlyingFile != NULL ) { long numRead = fread( inBuffer, 1, inNumBytes, mUnderlyingFile ); if( numRead < inNumBytes ) { int fileNameLength; char *fileName = mFile->getFullFileName( &fileNameLength ); if( feof( mUnderlyingFile ) ) { // we reached the end of the file. char *stringBuffer = new char[ fileNameLength + 50 ]; sprintf( stringBuffer, "Reached end of file %s on read.", fileName ); setNewLastError( stringBuffer ); delete [] fileName; } else { // some other kind of error occured char *stringBuffer = new char[ fileNameLength + 50 ]; sprintf( stringBuffer, "Reading from file %s failed.", fileName ); setNewLastError( stringBuffer ); delete [] fileName; if( numRead == 0 ) { // a complete read failure return -1; } } } return numRead; } else { // file was not opened properly int fileNameLength; char *fileName = mFile->getFullFileName( &fileNameLength ); char *stringBuffer = new char[ fileNameLength + 50 ]; sprintf( stringBuffer, "File %s was not opened properly before reading.", fileName ); delete [] fileName; setNewLastError( stringBuffer ); return -1; } } #endif gravitation-3+dfsg1.orig/minorGems/io/linux/0000755000175000017500000000000010762704567017664 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/linux/TypeIOLinux.cpp0000644000175000017500000000524510762704567022567 0ustar pabspabs/* * Modification History * * 2001-February-3 Jason Rohrer * Created. * Fixed a bug in the big-endian code. * Fixed parameter names to match convention. * * 2001-February-26 Jason Rohrer * Fixed a bug in the little-endian implementation. * * 2001-August-28 Jason Rohrer * Changed to be FreeBSD compatible. * * 2002-March-13 Jason Rohrer * Started to change to work with solaris. * Finished changing to work with solaris. * * 2002-April-11 Jason Rohrer * Added a default BSD case to work with OSX. * * 2002-May-25 Jason Rohrer * Changed to use minorGems endian.h */ #include "minorGems/io/TypeIO.h" #include "minorGems/system/endian.h" /* * Linux-specific type input and output. * Note that all types are output in the order that * a big-endian linux machine outputs them with no conversion. */ #if __BYTE_ORDER == __LITTLE_ENDIAN void TypeIO::doubleToBytes( double inDouble, unsigned char *outBytes ) { unsigned char *doubleBuffer = (unsigned char*)( &inDouble ); // output second word first outBytes[0] = doubleBuffer[7]; outBytes[1] = doubleBuffer[6]; outBytes[2] = doubleBuffer[5]; outBytes[3] = doubleBuffer[4]; outBytes[4] = doubleBuffer[3]; outBytes[5] = doubleBuffer[2]; outBytes[6] = doubleBuffer[1]; outBytes[7] = doubleBuffer[0]; } double TypeIO::bytesToDouble( unsigned char *inBytes ) { double returnValue; unsigned char *doubleBuffer = (unsigned char*)( &returnValue ); // put first word at the end of this double doubleBuffer[7] = inBytes[0]; doubleBuffer[6] = inBytes[1]; doubleBuffer[5] = inBytes[2]; doubleBuffer[4] = inBytes[3]; doubleBuffer[3] = inBytes[4]; doubleBuffer[2] = inBytes[5]; doubleBuffer[1] = inBytes[6]; doubleBuffer[0] = inBytes[7]; return returnValue; } #endif #if __BYTE_ORDER == __BIG_ENDIAN void TypeIO::doubleToBytes( double inDouble, unsigned char *outBytes ) { unsigned char *doubleBuffer = (unsigned char*)( &inDouble ); // output in stored order outBytes[0] = doubleBuffer[0]; outBytes[1] = doubleBuffer[1]; outBytes[2] = doubleBuffer[2]; outBytes[3] = doubleBuffer[3]; outBytes[4] = doubleBuffer[4]; outBytes[5] = doubleBuffer[5]; outBytes[6] = doubleBuffer[6]; outBytes[7] = doubleBuffer[7]; } double TypeIO::bytesToDouble( unsigned char *inBytes ) { double returnValue; unsigned char *doubleBuffer = (unsigned char*)( &returnValue ); // store in input order doubleBuffer[0] = inBytes[0]; doubleBuffer[1] = inBytes[1]; doubleBuffer[2] = inBytes[2]; doubleBuffer[3] = inBytes[3]; doubleBuffer[4] = inBytes[4]; doubleBuffer[5] = inBytes[5]; doubleBuffer[6] = inBytes[6]; doubleBuffer[7] = inBytes[7]; return returnValue; } #endif gravitation-3+dfsg1.orig/minorGems/io/win32/0000755000175000017500000000000010762704567017467 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/win32/TypeIOWin32.cpp0000644000175000017500000000247110762704567022173 0ustar pabspabs/* * Modification History * * 2001-February-3 Jason Rohrer * Created. * Fixed parameter names to match convention. * * 2001-February-4 Jason Rohrer * Fixed a byte-order bug. */ #include "minorGems/io/TypeIO.h" /* * Win32-specific type input and output. * Note that all types are output in the order that * a big-endian linux machine outputs them with no conversion. */ // windows machines are all little-endian void TypeIO::doubleToBytes( double inDouble, unsigned char *outBytes ) { unsigned char *doubleBuffer = (unsigned char*)( &inDouble ); // output second word first outBytes[0] = doubleBuffer[7]; outBytes[1] = doubleBuffer[6]; outBytes[2] = doubleBuffer[5]; outBytes[3] = doubleBuffer[4]; outBytes[4] = doubleBuffer[3]; outBytes[5] = doubleBuffer[2]; outBytes[6] = doubleBuffer[1]; outBytes[7] = doubleBuffer[0]; } double TypeIO::bytesToDouble( unsigned char *inBytes ) { double returnValue; unsigned char *doubleBuffer = (unsigned char*)( &returnValue ); // put first word at the end of this double doubleBuffer[7] = inBytes[0]; doubleBuffer[6] = inBytes[1]; doubleBuffer[5] = inBytes[2]; doubleBuffer[4] = inBytes[3]; doubleBuffer[3] = inBytes[4]; doubleBuffer[2] = inBytes[5]; doubleBuffer[1] = inBytes[6]; doubleBuffer[0] = inBytes[7]; return returnValue; } gravitation-3+dfsg1.orig/minorGems/io/PipedStream.h0000644000175000017500000000765110762704567021124 0ustar pabspabs/* * Modification History * * 2001-February-19 Jason Rohrer * Created. * * 2001-February-20 Jason Rohrer * Added a missing return value. */ #include "minorGems/common.h" #ifndef PIPED_STREAM_CLASS_INCLUDED #define PIPED_STREAM_CLASS_INCLUDED #include "minorGems/io/InputStream.h" #include "minorGems/io/OutputStream.h" #include "minorGems/util/SimpleVector.h" #include /** * An input/output stream that can server as a pipe between * two components that read from and write to streams. * * Buffered internally to prevent blocking, so is compatible * with non-threaded components. Note, however, that * ever buffer written to the stream is copied internally, * so max memory usage is doubled. * * IS NOT THREAD-SAFE! * * @author Jason Rohrer */ class PipedStream : public InputStream, public OutputStream { public: /** * Constructs a PipedStream. */ PipedStream(); /** * Destroys any pending unread buffers. */ ~PipedStream(); // implements the InputStream interface long read( unsigned char *inBuffer, long inNumBytes ); // implements the OutputStream interface long write( unsigned char *inBuffer, long inNumBytes ); protected: SimpleVector *mBuffers; SimpleVector *mBufferSizes; long mCurrentBufferIndex; }; inline PipedStream::PipedStream() : mBuffers( new SimpleVector() ), mBufferSizes( new SimpleVector() ), mCurrentBufferIndex( 0 ) { } inline PipedStream::~PipedStream() { int numRemaining = mBuffers->size(); for( int i=0; igetElement( i ) ); delete [] buffer; } delete mBuffers; delete mBufferSizes; } inline long PipedStream::read( unsigned char *inBuffer, long inNumBytes ) { if( mBuffers->size() == 0 ) { // none read, since no buffers available InputStream:: setNewLastErrorConst( "No data available on piped stream read." ); return 0; } else { unsigned char *currentBuffer = *( mBuffers->getElement( 0 ) ); long currentBufferSize = *( mBufferSizes->getElement( 0 ) ); long outputIndex = 0; while( outputIndex < inNumBytes ) { long bytesRemaining = inNumBytes - outputIndex; long bytesRemainingInCurrent = currentBufferSize - mCurrentBufferIndex; // if current buffer isn't big enough to fill output if( bytesRemaining >= bytesRemainingInCurrent ) { // copy all of current buffer into inBuffer memcpy( &( inBuffer[outputIndex] ), &( currentBuffer[mCurrentBufferIndex] ), bytesRemainingInCurrent ); outputIndex += bytesRemainingInCurrent; // delete the current buffer mBuffers->deleteElement( 0 ); mBufferSizes->deleteElement( 0 ); delete [] currentBuffer; mCurrentBufferIndex = 0; if( outputIndex != inNumBytes && mBuffers->size() == 0 ) { // partial read, since no more buffers available InputStream::setNewLastErrorConst( "Partial data available on piped stream read." ); return outputIndex; } if( mBuffers->size() != 0 ) { // get the new current buffer currentBuffer = *( mBuffers->getElement( 0 ) ); currentBufferSize = *( mBufferSizes->getElement( 0 ) ); } } else { // current buffer is bigger memcpy( &( inBuffer[outputIndex] ), &( currentBuffer[mCurrentBufferIndex] ), bytesRemaining ); mCurrentBufferIndex += bytesRemaining; outputIndex += bytesRemaining; } } // end while // if we made it out of the while loop, we read all bytes return inNumBytes; } // end else } inline long PipedStream::write( unsigned char *inBuffer, long inNumBytes ) { // add a copy of the buffer to the vector of buffers unsigned char *copy = new unsigned char[ inNumBytes ]; memcpy( copy, inBuffer, inNumBytes ); mBuffers->push_back( copy ); mBufferSizes->push_back( inNumBytes ); return inNumBytes; } #endif gravitation-3+dfsg1.orig/minorGems/io/InputStream.h0000644000175000017500000000735010762704567021156 0ustar pabspabs/* * Modification History * * 2001-January-9 Jason Rohrer * Created. * * 2001-January-9 Jason Rohrer * Changed the "number of bytes read" parameter and return value * to longs. * * 2001-February-3 Jason Rohrer * Added a readDouble function to fix platform-specific double problems. * Also added a readLong function for completeness. Implemented * these functions, making use of the new TypeIO interface. * * 2001-February-12 Jason Rohrer * Changed to subclass Stream. * * 2002-March-9 Jason Rohrer * Added a readByte() function. * * 2002-March-31 Jason Rohrer * Made destructor virtual so it works with subclasses. * * 2004-May-9 Jason Rohrer * Added support for shorts. */ #include "minorGems/common.h" #ifndef INPUT_STREAM_CLASS_INCLUDED #define INPUT_STREAM_CLASS_INCLUDED #include "Stream.h" #include "TypeIO.h" /** * Interface for a byte input stream. * * @author Jason Rohrer */ class InputStream : public Stream { public: InputStream(); virtual ~InputStream(); /** * Reads bytes from this stream. * * @param inBuffer the buffer where read bytes will be put. * Must be pre-allocated memory space. * @param inNumBytes the number of bytes to read from the stream. * * @return the number of bytes read successfully, * or -1 for a stream error. */ virtual long read( unsigned char *inBuffer, long inNumBytes ) = 0; /** * Reads a byte from this stream. * * @param outByte pointer to where the byte should be stored. * * @return the number of bytes read successfully, or -1 for a * stream error. */ long readByte( unsigned char *outByte ); /** * Reads a double from the stream in a platform-independent way. * * @param outDouble pointer to where the double should be stored. * * @return the number of bytes read successfully, or -1 for a * stream error. */ long readDouble( double *outDouble ); /** * Reads a long from the stream in a platform-independent way. * * @param outLong pointer to where the long should be stored. * * @return the number of bytes read successfully, or -1 for a * stream error. */ long readLong( long *outLong ); /** * Reads a short from the stream in a platform-independent way. * * @param outShort pointer to where the short should be stored. * * @return the number of bytes read successfully, or -1 for a * stream error. */ long readShort( short *outShort ); private: unsigned char *mDoubleBuffer; unsigned char *mLongBuffer; unsigned char *mShortBuffer; unsigned char *mByteBuffer; }; inline InputStream::InputStream() : mDoubleBuffer( new unsigned char[8] ), mLongBuffer( new unsigned char[4] ), mShortBuffer( new unsigned char[2] ), mByteBuffer( new unsigned char[1] ) { } inline InputStream::~InputStream() { delete [] mDoubleBuffer; delete [] mShortBuffer; delete [] mLongBuffer; delete [] mByteBuffer; } inline long InputStream::readByte( unsigned char *outByte ) { int numBytes = read( mByteBuffer, 1 ); *outByte = mByteBuffer[0]; return numBytes; } inline long InputStream::readDouble( double *outDouble ) { int numBytes = read( mDoubleBuffer, 8 ); *outDouble = TypeIO::bytesToDouble( mDoubleBuffer ); return numBytes; } inline long InputStream::readLong( long *outLong ) { int numBytes = read( mLongBuffer, 4 ); *outLong = TypeIO::bytesToLong( mLongBuffer ); return numBytes; } inline long InputStream::readShort( short *outShort ) { int numBytes = read( mShortBuffer, 4 ); *outShort = TypeIO::bytesToShort( mShortBuffer ); return numBytes; } #endif gravitation-3+dfsg1.orig/minorGems/io/pipedStreamTest.cpp0000644000175000017500000000305610762704567022352 0ustar pabspabs/* * Modification History * * 2001-February-19 Jason Rohrer * Created. */ #include #include "PipedStream.h" #include "minorGems/util/random/StdRandomSource.h" // test function for piped streams int main() { PipedStream *stream = new PipedStream; InputStream *inStream = stream; OutputStream *outStream = stream; StdRandomSource *randSource = new StdRandomSource(); unsigned char *bufferA = new unsigned char[10]; unsigned char *bufferB = new unsigned char[15]; int i; printf( "bufferA = \n" ); for( i=0; i<10; i++ ) { bufferA[i] = (unsigned char)( randSource->getRandomBoundedInt(0, 255) ); printf( "%d\n", bufferA[i] ); } printf( "bufferB = \n" ); for( i=0; i<15; i++ ) { bufferB[i] = (unsigned char)( randSource->getRandomBoundedInt(0, 255) ); printf( "%d\n", bufferB[i] ); } unsigned char *bufferC = new unsigned char[ 10 + 15]; outStream->write( bufferA, 10 ); outStream->write( bufferB, 15 ); inStream->read( bufferC, 10 + 10 ); char *error = inStream->getLastError(); if( error != NULL ) { printf( "Stream error %s\n", error ); delete [] error; } printf( "bufferc = \n" ); for( i=0; i<10 + 15; i++ ) { printf( "%d\n", bufferC[i] ); } inStream->read( bufferC, 10 ); error = inStream->getLastError(); if( error != NULL ) { printf( "Stream error %s\n", error ); delete [] error; } printf( "bufferc = \n" ); for( i=0; i<10 + 15; i++ ) { printf( "%d\n", bufferC[i] ); } delete [] bufferA; delete [] bufferB; delete [] bufferC; delete randSource; delete stream; } gravitation-3+dfsg1.orig/minorGems/io/Stream.h0000644000175000017500000000513710762704567020137 0ustar pabspabs/* * Modification History * * 2001-February-12 Jason Rohrer * Created. * * 2002-March-29 Jason Rohrer * Added Fortify inclusion. * * 2002-March-31 Jason Rohrer * Made destructor virtual so it works with subclasses. * Fixed several bugs in deletion of mLastError. */ #include "minorGems/common.h" #ifndef STREAM_CLASS_INCLUDED #define STREAM_CLASS_INCLUDED #include #ifdef FORTIFY #include "minorGems/util/development/fortify/fortify.h" #endif /** * Base class for all streams. * * @author Jason Rohrer */ class Stream { public: /** * Constructs a stream. */ Stream(); virtual ~Stream(); /** * Gets the last error associated with this stream. * Calling this function clears the error until * another error occurs. * * @return the last stream error in human-readable form. * Must be destroyed by caller. Returns NULL if * there is no error. Note that this string is '\0' terminated. */ char *getLastError(); protected: /** * Called by subclasses to specify a new last error. Useful * when error doesn't contain information specifiable by * a constant string. * * @param inString human-readable string representing the error. * Note that this string must be '\0' terminated. * Will be destroyed by this class. */ void setNewLastError( char *inString ); /** * Called by subclasses to specify a new last error. Useful * when the error can be described by a constant string * * @param inString human-readable constant string representing * the error. * Note that this string must be '\0' terminated. */ void setNewLastErrorConst( const char *inString ); private: // set to NULL when there is no error char *mLastError; }; inline Stream::Stream() : mLastError( NULL ) { } inline Stream::~Stream() { if( mLastError != NULL ) { delete [] mLastError; } } inline char *Stream::getLastError() { char *returnString = mLastError; mLastError = NULL; return returnString; } inline void Stream::setNewLastError( char *inString ) { if( mLastError != NULL ) { delete [] mLastError; } mLastError = inString; } inline void Stream::setNewLastErrorConst( const char *inString ) { int length = 0; char lastChar = 'a'; while( lastChar != '\0' ) { lastChar = inString[length]; length++; } // add one more to length to accommodate '\0' terminination length++; if( mLastError != NULL ) { delete [] mLastError; } mLastError = new char[ length ]; memcpy( mLastError, inString, length ); } #endif gravitation-3+dfsg1.orig/minorGems/io/serialPort/0000755000175000017500000000000010762704567020651 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/serialPort/linux/0000755000175000017500000000000010762704567022010 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/serialPort/linux/SerialPortLinux.cpp0000644000175000017500000001477510762704567025636 0ustar pabspabs/* * Modification History * * 2003-February-17 Jason Rohrer * Created. * * 2003-April-4 Jason Rohrer * Added function for dumping the read buffer. */ #include "minorGems/io/serialPort/SerialPort.h" #include "minorGems/util/stringUtils.h" // Much of the code in this implementation was copied // from the Serial Programming FAQ, by Gary Frefking // http://en.tldp.org/HOWTO/Serial-Programming-HOWTO/ #include #include #include #include #include #include // baudrate settings are defined in , which is // included by class LinuxSerialPortObject { public: int mFileHandle; struct termios mOldTermIO; }; SerialPort::SerialPort( int inBaud, int inParity, int inDataBits, int inStopBits ) { int fileHandle = open( "/dev/ttyS0", O_RDWR | O_NOCTTY ); if( fileHandle < 0 ) { mNativeObjectPointer = NULL; } else { LinuxSerialPortObject *serialPortObject = new LinuxSerialPortObject(); serialPortObject->mFileHandle = fileHandle; mNativeObjectPointer = (void *)serialPortObject; struct termios newTermIO; //save current serial port settings tcgetattr( fileHandle, &( serialPortObject->mOldTermIO ) ); // clear struct for new port settings bzero( &newTermIO, sizeof( newTermIO ) ); unsigned int baudRate; switch( inBaud ) { case 1200: baudRate = B1200; break; case 2400: baudRate = B2400; break; case 4800: baudRate = B4800; break; case 9600: baudRate = B9600; break; case 19200: baudRate = B19200; break; case 38400: baudRate = B38400; break; case 57600: baudRate = B57600; break; default: break; } unsigned int parity = 0; switch( inParity ) { case SerialPort::PARITY_NONE: // disable parity parity = 0; break; case SerialPort::PARITY_EVEN: // enable parity, defaults to even parity = PARENB; break; case SerialPort::PARITY_ODD: // enable parity, and set to odd parity = PARENB | PARODD; break; default: break; } unsigned int dataBits = 0; switch( inDataBits ) { case 5: dataBits = CS5; break; case 6: dataBits = CS6; break; case 7: dataBits = CS7; break; case 8: dataBits = CS8; break; default: break; } unsigned int stopBits = 0; switch( inStopBits ) { case 1: stopBits = 0; break; case 2: stopBits = CSTOPB; break; default: break; } newTermIO.c_cflag = baudRate | parity | dataBits | stopBits | CLOCAL | CREAD; /* IGNPAR : ignore bytes with parity errors ICRNL : map CR to NL (otherwise a CR input on the other computer will not terminate input) IGNCR : ignore CR, so only one line is read when other machine sends CRLF otherwise make device raw (no other input processing) */ newTermIO.c_iflag = IGNPAR | ICRNL | IGNCR; /* Raw output. */ newTermIO.c_oflag = 0; /* ICANON : enable canonical input disable all echo functionality, and don't send signals to calling program */ newTermIO.c_lflag = ICANON; /* now clean the modem line and activate the settings for the port */ tcflush( fileHandle, TCIFLUSH ); tcsetattr( fileHandle, TCSANOW, &newTermIO ); } } SerialPort::~SerialPort() { if( mNativeObjectPointer != NULL ) { LinuxSerialPortObject *serialPortObject = (LinuxSerialPortObject *)mNativeObjectPointer; int fileHandle = serialPortObject->mFileHandle; tcsetattr( fileHandle, TCSANOW, &( serialPortObject->mOldTermIO ) ); delete serialPortObject; } } int SerialPort::sendLine( char *inLine ) { if( mNativeObjectPointer != NULL ) { LinuxSerialPortObject *serialPortObject = (LinuxSerialPortObject *)mNativeObjectPointer; int fileHandle = serialPortObject->mFileHandle; int stringLength = strlen( inLine ); int numWritten = write( fileHandle, inLine, stringLength ); char *endLineString = "\n"; int numWrittenEndLine = write( fileHandle, endLineString, 1 ); if( numWritten == stringLength && numWrittenEndLine == 1 ) { return 1; } else { return -1; } } else { return -1; } } char *SerialPort::receiveLine() { if( mNativeObjectPointer != NULL ) { LinuxSerialPortObject *serialPortObject = (LinuxSerialPortObject *)mNativeObjectPointer; int fileHandle = serialPortObject->mFileHandle; char *buffer = new char[500]; int numRead = read( fileHandle, buffer, 500 ); char *returnString; if( numRead != -1 ) { buffer[ numRead ] = '\0'; returnString = stringDuplicate( buffer ); } else { returnString = NULL; } delete [] buffer; return returnString; } else { return NULL; } } void SerialPort::dumpReceiveBuffer() { if( mNativeObjectPointer != NULL ) { LinuxSerialPortObject *serialPortObject = (LinuxSerialPortObject *)mNativeObjectPointer; int fileHandle = serialPortObject->mFileHandle; // from man page: // flushes data received but not read tcflush( fileHandle, TCIFLUSH ); } } gravitation-3+dfsg1.orig/minorGems/io/serialPort/win32/0000755000175000017500000000000010762704567021613 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/io/serialPort/win32/COMPort.cpp0000644000175000017500000002471110762704567023607 0ustar pabspabs/* * Modification History * * 2003-April-4 Jason Rohrer * Added function for dumping the read buffer. */ //============================================================================= // General component library for WIN32 // Copyright (C) 2000, UAB BBDSoft ( http://www.bbdsoft.com/ ) // // This material is provided "as is", with absolutely no warranty expressed // or implied. Any use is at your own risk. // // Permission to use or copy this software for any purpose is hereby granted // without fee, provided the above notices are retained on all copies. // Permission to modify the code and to distribute modified code is granted, // provided the above notices are retained, and a notice that the code was // modified is included with the above copyright notice. // // The author of this program may be contacted at developers@bbdsoft.com //============================================================================= #ifndef _COMPORT_ #include "ComPort.h" #endif #ifndef _WINDOWS_ #define WIN32_LEAN_AND_MEAN #include #endif #ifndef _STDEXCEPT_ #include #endif using namespace std; //---------------------------------------------------------------------------- COMPort::COMPort ( const char * const portName ) : theDCB (NULL) { thePortHandle = (unsigned ) CreateFile ( portName , GENERIC_READ | GENERIC_WRITE , 0 , NULL , OPEN_EXISTING , FILE_FLAG_NO_BUFFERING , NULL ); if (thePortHandle == HFILE_ERROR) { throw runtime_error ("COMPort: failed to open."); } // endif theDCB = new char [sizeof(DCB)]; getState(); setBlockingMode(); setHandshaking(); } // end constructor //---------------------------------------------------------------------------- COMPort::~COMPort() { delete [] theDCB; // close serial port device if (CloseHandle ((HANDLE)thePortHandle) == FALSE ) { throw runtime_error ("COMPort: failed to close."); } // endif } // end destructor //---------------------------------------------------------------------------- void COMPort::getState () const { if (!GetCommState ( (HANDLE) thePortHandle , (LPDCB) theDCB ) ) { throw runtime_error ("COMPort: could not retrieve serial port state."); } // endif } // end COMPort::getState () const //---------------------------------------------------------------------------- COMPort& COMPort::setState () { if (!SetCommState ( (HANDLE) thePortHandle , (LPDCB) theDCB ) ) { throw runtime_error ("COMPort: could not modify serial port state."); } // endif return *this; } // end COMPort::setState () //----------------------------------------------------------------------------- COMPort& COMPort::setBitRate ( unsigned long Param ) { DCB & aDCB = *((LPDCB)theDCB); aDCB.BaudRate = Param; return setState(); } // end COMPort::setBitRate (..) //----------------------------------------------------------------------------- unsigned long COMPort::bitRate() const { DCB & aDCB = *((LPDCB)theDCB); return aDCB.BaudRate; } // end COMPort::bitRate () const //----------------------------------------------------------------------------- COMPort& COMPort::setLineCharacteristics( char * inConfig ) { COMMTIMEOUTS aTimeout; if ( !BuildCommDCBAndTimeouts ( inConfig , (LPDCB)theDCB , &aTimeout ) ) { throw runtime_error ("COMPort: could not set line characteristics."); } // endif if ( ! SetCommTimeouts ( (HANDLE(thePortHandle)) , &aTimeout ) ) { throw runtime_error ("COMPort: could not set line characteristics."); } // endif return setState(); } //---------------------------------------------------------------------------- char COMPort::read () { char buffer; DWORD charsRead = 0; do { if (! ReadFile ( (HANDLE(thePortHandle)) , &buffer , sizeof(char) , &charsRead , NULL ) ) { throw runtime_error ("COMPort: read failed."); } // endif } while ( !charsRead ); return buffer; } // end COMPort::read() //---------------------------------------------------------------------------- void COMPort::dumpReceiveBuffer () { PurgeComm( (HANDLE(thePortHandle)) , PURGE_RXCLEAR ); } // end COMPort::dumpReceiveBuffer() //---------------------------------------------------------------------------- unsigned long COMPort::read ( void *inBuffer , const unsigned long inCharsReq ) { DWORD charsRead = 0; if ( !ReadFile ( (HANDLE(thePortHandle)) , inBuffer , inCharsReq , &charsRead , NULL ) ) { throw runtime_error ("COMPort: read failed."); } // endif return charsRead; } // end COMPort::read (..) //---------------------------------------------------------------------------- COMPort & COMPort::write ( const char inChar ) { char buffer = inChar; DWORD charsWritten = 0; if ( !WriteFile ( (HANDLE(thePortHandle)) , &buffer , sizeof(char) , &charsWritten , NULL ) ) { throw runtime_error ("COMPort: write failed."); } // endif return *this; } // end COMPort::write (..) //---------------------------------------------------------------------------- unsigned long COMPort::write ( const void *inBuffer , const unsigned long inBufSize ) { DWORD charsWritten = 0; if ( !WriteFile ( (HANDLE(thePortHandle)) , inBuffer , inBufSize , &charsWritten , NULL ) ) { throw runtime_error ("COMPort: write failed."); } // endif return charsWritten; } // end COMPort::write() //----------------------------------------------------------------------------- COMPort& COMPort::setxONxOFF ( bool Param ) { DCB & aDCB = *((LPDCB)theDCB); aDCB.fOutX = Param ? 1 : 0; aDCB.fInX = Param ? 1 : 0; return setState(); } // end COMPort::setxONxOFF (..) //----------------------------------------------------------------------------- bool COMPort::isxONxOFF () const { DCB & aDCB = *((LPDCB)theDCB); return (aDCB.fOutX && aDCB.fInX); } // end COMPort::isxONxOFF () const //---------------------------------------------------------------------------- COMPort& COMPort::setBlockingMode ( unsigned long inReadInterval , unsigned long inReadMultiplyer , unsigned long inReadConstant ) { COMMTIMEOUTS commTimeout; if ( !GetCommTimeouts ( (HANDLE(thePortHandle)) , &commTimeout ) ) { throw runtime_error ("COMPort: failed to retrieve timeouts."); } // endif commTimeout.ReadIntervalTimeout = inReadInterval; if ( inReadInterval==MAXDWORD ) { commTimeout.ReadTotalTimeoutMultiplier = 0; commTimeout.ReadTotalTimeoutConstant = 0; } else { commTimeout.ReadTotalTimeoutMultiplier = inReadMultiplyer; commTimeout.ReadTotalTimeoutConstant = inReadConstant; } // endifelse if ( !SetCommTimeouts ( (HANDLE(thePortHandle)) , &commTimeout ) ) { throw runtime_error ("COMPort: failed to modify timeouts."); } // endif return *this; } // end COMPort::setBlockingMode (..) //----------------------------------------------------------------------------- COMPort & COMPort::setHandshaking ( bool inHandshaking ) { DCB & aDCB = *((LPDCB)theDCB); if (inHandshaking) { aDCB.fOutxCtsFlow = TRUE; aDCB.fOutxDsrFlow = FALSE; aDCB.fRtsControl = RTS_CONTROL_HANDSHAKE; } else { aDCB.fOutxCtsFlow = FALSE; aDCB.fOutxDsrFlow = FALSE; aDCB.fRtsControl = RTS_CONTROL_ENABLE; } // endifelse return setState(); } // end COMPort::setHandshaking (..) //----------------------------------------------------------------------------- unsigned long COMPort::getMaximumBitRate() const { COMMPROP aProp; if ( !GetCommProperties ( (HANDLE)thePortHandle , &aProp ) ) { throw runtime_error ("COMPort: failed to retrieve port properties."); } // endif return aProp.dwMaxBaud; } // end COMPort::getMaximumBitRate () const //----------------------------------------------------------------------------- COMPort::MSPack COMPort::getModemSignals() const { MSPack aPack; // 1 bit - DTR, 2 - bit RTS (output signals) // 4 bit - CTS, 5 bit - DSR, 6 bit - RI, 7 bit - DCD (input signals) if ( !GetCommModemStatus ( (HANDLE)thePortHandle , (LPDWORD)&aPack ) ) { throw runtime_error ("COMPort: failed to retrieve modem signals."); } // endif return aPack; } // end COMPort::getModemSignals () const //----------------------------------------------------------------------------- COMPort& COMPort::setParity ( Parity Param ) { DCB & aDCB = *((LPDCB)theDCB); aDCB.Parity = Param; return setState(); } // end COMPort::setParity (..) //----------------------------------------------------------------------------- COMPort& COMPort::setDataBits ( DataBits Param ) { DCB & aDCB = *((LPDCB)theDCB); aDCB.ByteSize = Param; return setState(); } // end COMPort::setDataBits (..) //----------------------------------------------------------------------------- COMPort& COMPort::setStopBits ( StopBits Param ) { DCB & aDCB = *((LPDCB)theDCB); aDCB.StopBits = Param; return setState(); } // end COMPort::setStopBits (..) //----------------------------------------------------------------------------- COMPort::Parity COMPort::parity () const { DCB & aDCB = *((LPDCB)theDCB); return (COMPort::Parity)aDCB.Parity; } // end COMPort::parity () const //----------------------------------------------------------------------------- COMPort::DataBits COMPort::dataBits () const { DCB & aDCB = *((LPDCB)theDCB); return (COMPort::DataBits)aDCB.ByteSize; } // end COMPort::dataBits () const //----------------------------------------------------------------------------- COMPort::StopBits COMPort::stopBits () const { DCB & aDCB = *((LPDCB)theDCB); return (COMPort::StopBits)aDCB.StopBits; } // end COMPort::stopBits () cosnt gravitation-3+dfsg1.orig/minorGems/io/serialPort/win32/SerialPortWin32.cpp0000644000175000017500000001036510762704567025233 0ustar pabspabs/* * Modification History * * 2003-March-24 Jason Rohrer * Created. * * 2003-March-26 Jason Rohrer * Fixed a line parsing bug (lines end with newline, not CR). * * 2003-April-4 Jason Rohrer * Added function for dumping the read buffer. */ #include "minorGems/io/serialPort/SerialPort.h" #include "minorGems/util/stringUtils.h" // For now, we are using BBDSoft's COM port code #include "COMPort.h" SerialPort::SerialPort( int inBaud, int inParity, int inDataBits, int inStopBits ) { COMPort *port = new COMPort( "COM1" ); port->setHandshaking( false ); unsigned long baudRate = COMPort::br2400; switch( inBaud ) { case 1200: baudRate = COMPort::br1200; break; case 2400: baudRate = COMPort::br2400; break; case 4800: baudRate = COMPort::br4800; break; case 9600: baudRate = COMPort::br9600; break; case 19200: baudRate = COMPort::br19200; break; case 38400: baudRate = COMPort::br38400; break; case 57600: baudRate = COMPort::br57600; break; default: break; } port->setBitRate( baudRate ); switch( inParity ) { case SerialPort::PARITY_NONE: port->setParity( COMPort::None ); break; case SerialPort::PARITY_EVEN: port->setParity( COMPort::Even ); break; case SerialPort::PARITY_ODD: port->setParity( COMPort::Odd ); break; default: port->setParity( COMPort::None ); break; } switch( inDataBits ) { case 5: port->setDataBits( COMPort::db5 ); break; case 6: port->setDataBits( COMPort::db6 ); break; case 7: port->setDataBits( COMPort::db7 ); break; case 8: port->setDataBits( COMPort::db8 ); break; default: port->setDataBits( COMPort::db8 ); break; } switch( inStopBits ) { case 1: port->setStopBits( COMPort::sb1 ); break; case 2: port->setStopBits( COMPort::sb2 ); break; default: port->setStopBits( COMPort::sb1 ); break; } mNativeObjectPointer = (void *)port; } SerialPort::~SerialPort() { if( mNativeObjectPointer != NULL ) { COMPort *port = (COMPort *)mNativeObjectPointer; delete port; } } int SerialPort::sendLine( char *inLine ) { if( mNativeObjectPointer != NULL ) { COMPort *port = (COMPort *)mNativeObjectPointer; int stringLength = strlen( inLine ); int numWritten = port->write( (void *)inLine, stringLength ); char *endLineString = "\n"; int numWrittenEndLine = port->write( (void *)endLineString, 1 ); if( numWritten == stringLength && numWrittenEndLine == 1 ) { return 1; } else { return -1; } } else { return -1; } } char *SerialPort::receiveLine() { if( mNativeObjectPointer != NULL ) { COMPort *port = (COMPort *)mNativeObjectPointer; char *buffer = new char[500]; // read up to first newline int index = 0; char lastCharRead = port->read(); while( lastCharRead != '\n' && index < 499 ) { buffer[index] = lastCharRead; lastCharRead = port->read(); index++; } char *returnString; if( index > 0 ) { buffer[ index ] = '\0'; returnString = stringDuplicate( buffer ); } else { returnString = NULL; } delete [] buffer; return returnString; } else { return NULL; } } void SerialPort::dumpReceiveBuffer() { if( mNativeObjectPointer != NULL ) { COMPort *port = (COMPort *)mNativeObjectPointer; port->dumpReceiveBuffer(); } } gravitation-3+dfsg1.orig/minorGems/io/serialPort/win32/COMPort.h0000644000175000017500000000672310762704567023257 0ustar pabspabs/* * Modification History * * 2003-April-4 Jason Rohrer * Added function for dumping the read buffer. */ //============================================================================= // General component library for WIN32 // Copyright (C) 2000, UAB BBDSoft ( http://www.bbdsoft.com/ ) // // This material is provided "as is", with absolutely no warranty expressed // or implied. Any use is at your own risk. // // Permission to use or copy this software for any purpose is hereby granted // without fee, provided the above notices are retained on all copies. // Permission to modify the code and to distribute modified code is granted, // provided the above notices are retained, and a notice that the code was // modified is included with the above copyright notice. // // The author of this program may be contacted at developers@bbdsoft.com //============================================================================= #ifndef _COMPORT_ #define _COMPORT_ //----------------------------------------------------------------------------- class COMPort { public: enum Parity { None = 0 , Odd , Even , Mark , Space }; enum DataBits { db4 = 4 , db5 , db6 , db7 , db8 }; enum StopBits { sb1 = 0, sb15, sb2 }; enum BitRate { br110 = 110, br300 = 300, br600 = 600, br1200 = 1200, br2400 = 2400, br4800 = 4800, br9600 = 9600, br19200 = 19200, br38400 = 38400, br56000 = 56000, br57600 = 57600, br115200 = 115200, br256000 = 256000 }; // for function getModemSignals struct MSPack { unsigned char DTR : 1; unsigned char RTS : 1; unsigned char : 2; unsigned char CTS : 1; unsigned char DSR : 1; unsigned char RI : 1; unsigned char DCD : 1; }; COMPort ( const char * const portName ); ~COMPort (); // I/O operations char read (); COMPort & write (const char inChar); unsigned long read ( void * , const unsigned long count ); unsigned long write ( const void * , const unsigned long count ); // dumps unread characters in the receive buffer void dumpReceiveBuffer(); COMPort& setBitRate ( unsigned long Param ); unsigned long bitRate () const; COMPort& setParity ( Parity Param ); Parity parity () const; COMPort& setDataBits ( DataBits Param ); DataBits dataBits () const; COMPort& setStopBits ( StopBits Param ); StopBits stopBits () const; COMPort & setHandshaking ( bool inHandshaking = true ); COMPort& setLineCharacteristics ( char * Param ); unsigned long getMaximumBitRate () const; COMPort & setxONxOFF ( bool Param = true); bool isxONxOFF () const; MSPack getModemSignals () const; COMPort& setBlockingMode ( unsigned long inReadInterval = 0 , unsigned long inReadMultiplyer = 0 , unsigned long inReadConstant = 0 ); protected: private: // disable copy constructor and assignment operator COMPort (const COMPort &); COMPort& operator= (const COMPort &); void getState () const; COMPort& setState (); unsigned thePortHandle; char * theDCB; }; // End of COMPort class declaration #endif gravitation-3+dfsg1.orig/minorGems/io/serialPort/SerialPortFromFile.cpp0000644000175000017500000000266210762704567025073 0ustar pabspabs/* * Modification History * * 2003-March-28 Jason Rohrer * Created. */ #include "minorGems/io/serialPort/SerialPort.h" #include "minorGems/util/stringUtils.h" #include SerialPort::SerialPort( int inBaud, int inParity, int inDataBits, int inStopBits ) { FILE *file = fopen( "gpscap.txt", "r" ); mNativeObjectPointer = file; } SerialPort::~SerialPort() { if( mNativeObjectPointer != NULL ) { FILE *file = (FILE *)mNativeObjectPointer; fclose( file ); } } int SerialPort::sendLine( char *inLine ) { return 1; } char *SerialPort::receiveLine() { if( mNativeObjectPointer != NULL ) { FILE *file = (FILE *)mNativeObjectPointer; char *buffer = new char[500]; // read up to first newline int index = 0; char lastCharRead = (char)getc( file ); while( lastCharRead != '\n' && index < 499 ) { buffer[index] = lastCharRead; lastCharRead = (char)getc( file ); index++; } char *returnString; if( index > 0 ) { buffer[ index ] = '\0'; returnString = stringDuplicate( buffer ); } else { returnString = NULL; } delete [] buffer; return returnString; } else { return NULL; } } gravitation-3+dfsg1.orig/minorGems/io/serialPort/testSerialPortCompile0000755000175000017500000000011510762704567025071 0ustar pabspabsg++ -o testSerialPort -I../../.. linux/SerialPortLinux.cpp testSerialPort.cppgravitation-3+dfsg1.orig/minorGems/io/serialPort/testSerialPort.cpp0000644000175000017500000000101010762704567024331 0ustar pabspabs #include "SerialPort.h" #include int main() { printf( "Constructing serial port.\n" ); SerialPort *port = new SerialPort( 4800, SerialPort::PARITY_NONE, 8, 1 ); char *line = port->receiveLine(); // specific to GPS unit port->sendLine( "ASTRAL" ); while( line != NULL ) { printf( "received: %s\n", line ); delete [] line; line = port->receiveLine(); } printf( "Deleting serial port.\n" ); delete port; return 0; } gravitation-3+dfsg1.orig/minorGems/io/serialPort/SerialPort.h0000644000175000017500000000430610762704567023111 0ustar pabspabs/* * Modification History * * 2003-February-17 Jason Rohrer * Created. * * 2003-April-4 Jason Rohrer * Added function for dumping the read buffer. */ #ifndef SERIAL_PORT_INCLUDED #define SERIAL_PORT_INCLUDED /** * Serial port. * * Note: Implementation for the functions defined here is provided * separately for each platform (in the mac/ linux/ and win32/ * subdirectories). * * @author Jason Rohrer */ class SerialPort { public: static const int PARITY_NONE = 0; static const int PARITY_EVEN = 1; static const int PARITY_ODD = 2; /** * Constructs a serial port. * * @param inBaud the baud rate. * @param inParity the parity, one of SerialPort:: PARITY_NONE, * PARITY_EVEN, or PARITY_ODD. * @param inDataBits the number of data bits, 5, 6, 7, or 8. * @param inStopBits the number of stop bits, 1 or 2. */ SerialPort( int inBaud, int inParity, int inDataBits, int inStopBits ); ~SerialPort(); /** * Sends a line of text through this serial port. * * @param inLine the \0-terminated line of text to send. * Should not contain newline characters. * Must be destroyed by caller if non-const. * * @return 1 if the line was sent successfully, * or -1 for a port error. */ int sendLine( char *inLine ); /** * Receives a line of text from this serial port. * * @return the read line as a \0-terminated string with end of * line characters included, or NULL for a port error. * Must be destroyed by caller if non-NULL. */ char *receiveLine(); /** * Discards all characters in the receive buffer, including * unread characters. * * Can be used to recover from buffer overflow problems. */ void dumpReceiveBuffer(); private: /** * Used for platform-specific implementations. */ void *mNativeObjectPointer; }; #endif gravitation-3+dfsg1.orig/minorGems/io/Serializable.h0000644000175000017500000000345610762704567021314 0ustar pabspabs/* * Modification History * * 2001-January-10 Jason Rohrer * Created. * Added untility functions for converting integers to and from byte arrays. * * 2001-January-15 Jason Rohrer * Made utility functions static. * Fixed a major bug in the longToBytes function. * * 2001-February-3 Jason Rohrer * Removed the long io functions, which are now contained in the * input- and outputStream classes. * * 2005-November-21 Jason Rohrer * Fixed a warning by adding a virtual destructor. */ #include "minorGems/common.h" #ifndef SERIALIZABLE_CLASS_INCLUDED #define SERIALIZABLE_CLASS_INCLUDED #include "InputStream.h" #include "OutputStream.h" /** * Interface for an object that can be serialized to and deserialized * from a stream. * * Note that the deserialize function is meant to be called from an already * constructed object (to set object parameters using data read from the * stream), and is not a method of obtaining an object. * * All multi-byte data members should be encoded in using a big endian format. * * @author Jason Rohrer */ class Serializable { public: /** * Writes this object out to a stream. * * @param inOutputStream the stream to write to. * * @return the number of bytes written successfully, * or -1 for a stream error. */ virtual int serialize( OutputStream *inOutputStream ) = 0; /** * Reads this object in from a stream. * * @param inInputStream the stream to read from. * * @return the number of bytes read successfully, * or -1 for a stream error. */ virtual int deserialize( InputStream *inInputStream ) = 0; virtual ~Serializable(); }; inline Serializable::~Serializable() { // does nothing // exists to ensure that subclass destructors are called } #endif gravitation-3+dfsg1.orig/minorGems/io/TypeIO.h0000644000175000017500000000650610762704567020056 0ustar pabspabs/* * Modification History * * 2001-February-3 Jason Rohrer * Created. * Fixed parameter names to match convention. * * 2003-January-11 Jason Rohrer * Added missing casts. * * 2004-May-9 Jason Rohrer * Added support for shorts. */ #include "minorGems/common.h" #ifndef TYPE_IO_INCLUDED #define TYPE_IO_INCLUDED /** * Interfaces for platform-independent type input and output. * * The specification for the input/output format for types is as follows: * * Types should be output in the order and format that a big-endian Linux * outputs them by default. * * Note that minorGems/numtest.cpp can be used to test how doubles are * stored on a specific platform. * * @author Jason Rohrer */ class TypeIO { public: /** * Converts an 32-bit integer to a byte array in a * platform-independent fashion. * * @param inInt the integer to convert to a byte array. * @param outBytes preallocated array where bytes will be returned. */ static void longToBytes( long inInt, unsigned char *outBytes ); /** * Converts a 4-byte array to a 32-bit integer * platform-independent fashion. * * @param inBytes array of bytes to convert. * * @return the integer represented by the bytes. */ static long bytesToLong( unsigned char *inBytes ); /** * Converts an 16-bit integer to a byte array in a * platform-independent fashion. * * @param inInt the integer to convert to a byte array. * @param outBytes preallocated array where bytes will be returned. */ static void shortToBytes( short inInt, unsigned char *outBytes ); /** * Converts a 2-byte array to a 16-bit integer * platform-independent fashion. * * @param inBytes array of bytes to convert. * * @return the integer represented by the bytes. */ static short bytesToShort( unsigned char *inBytes ); /** * Converts an 64-bit float to a byte array in a * platform-independent fashion. * * @param inDouble the double to convert to a byte array. * @param outBytes preallocated array where bytes will be returned. */ static void doubleToBytes( double inDouble, unsigned char *outBytes ); /** * Converts a 8-byte array to a 64-bit float * platform-independent fashion. * * @param inBytes array of bytes to convert. * * @return the double represented by the bytes. */ static double bytesToDouble( unsigned char *inBytes ); }; // for now, these long IO functions can be implemented in the same way // on every platform. inline void TypeIO::longToBytes( long inInt, unsigned char *outBytes ) { // use a big-endian conversion outBytes[0] = (unsigned char)( inInt >> 24 & 0xFF ); outBytes[1] = (unsigned char)( inInt >> 16 & 0xFF ); outBytes[2] = (unsigned char)( inInt >> 8 & 0xFF ); outBytes[3] = (unsigned char)( inInt & 0xFF ); } inline long TypeIO::bytesToLong( unsigned char *inBytes ) { return (long)( inBytes[0] << 24 | inBytes[1] << 16 | inBytes[2] << 8 | inBytes[3] ); } inline void TypeIO::shortToBytes( short inInt, unsigned char *outBytes ) { // use a big-endian conversion outBytes[0] = (unsigned char)( inInt >> 8 & 0xFF ); outBytes[1] = (unsigned char)( inInt & 0xFF ); } inline short TypeIO::bytesToShort( unsigned char *inBytes ) { return (short)( inBytes[0] << 8 | inBytes[1] ); } #endif gravitation-3+dfsg1.orig/minorGems/io/OutputStream.h0000644000175000017500000000702310762704567021354 0ustar pabspabs/* * Modification History * * 2001-January-9 Jason Rohrer * Created. * * 2001-January-9 Jason Rohrer * Changed the "number of bytes written" parameter and return value * to longs. * * 2001-February-3 Jason Rohrer * Added a writeDouble function to fix platform-specific double problems. * Also added a writeLong function for completeness. Implemented * these functions, making use of the new TypeIO interface. * * 2001-February-12 Jason Rohrer * Changed to subclass Stream. * * 2002-February-25 Jason Rohrer * Added a function for writing a string. * * 2002-March-31 Jason Rohrer * Made destructor virtual so it works with subclasses. * * 2004-May-9 Jason Rohrer * Added support for shorts. */ #include "minorGems/common.h" #ifndef OUTPUT_STREAM_CLASS_INCLUDED #define OUTPUT_STREAM_CLASS_INCLUDED #include "Stream.h" #include "TypeIO.h" #include /** * Interface for a byte output stream. * * @author Jason Rohrer */ class OutputStream : public Stream { public: OutputStream(); virtual ~OutputStream(); /** * Writes bytes to this stream. * * @param inBuffer the buffer of bytes to send. * @param inNumBytes the number of bytes to send. * * @return the number of bytes written successfully, * or -1 for a stream error. */ virtual long write( unsigned char *inBuffer, long inNumBytes ) = 0; /** * Writes a string to this stream. * * @param inString a \0-terminated string. * Must be destroyed by caller. * @return the number of bytes written successfully, or -1 for a * stream error. */ long writeString( char *inString ); /** * Writes a double to the stream in a platform-independent way. * * @param inDouble the double to write * * @return the number of bytes written successfully, or -1 for a * stream error. */ long writeDouble( double inDouble ); /** * Writes a long to the stream in a platform-independent way. * * @param inLong the long to write * * @return the number of bytes written successfully, or -1 for a * stream error. */ long writeLong( long inLong ); /** * Writes a short to the stream in a platform-independent way. * * @param inShort the long to write * * @return the number of bytes written successfully, or -1 for a * stream error. */ long writeShort( short inShort ); private: unsigned char *mDoubleBuffer; unsigned char *mLongBuffer; unsigned char *mShortBuffer; }; inline OutputStream::OutputStream() : mDoubleBuffer( new unsigned char[8] ), mLongBuffer( new unsigned char[4] ), mShortBuffer( new unsigned char[2] ) { } inline OutputStream::~OutputStream() { delete [] mDoubleBuffer; delete [] mLongBuffer; delete [] mShortBuffer; } inline long OutputStream::writeString( char *inString ) { int numBytes = write( (unsigned char *)inString, strlen( inString ) ); return numBytes; } inline long OutputStream::writeDouble( double inDouble ) { TypeIO::doubleToBytes( inDouble, mDoubleBuffer ); int numBytes = write( mDoubleBuffer, 8 ); return numBytes; } inline long OutputStream::writeLong( long inLong ) { TypeIO::longToBytes( inLong, mLongBuffer ); int numBytes = write( mLongBuffer, 4 ); return numBytes; } inline long OutputStream::writeShort( short inShort ) { TypeIO::shortToBytes( inShort, mShortBuffer ); int numBytes = write( mShortBuffer, 2 ); return numBytes; } #endif gravitation-3+dfsg1.orig/minorGems/ui/0000755000175000017500000000000010762704567016533 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/ui/event/0000755000175000017500000000000010762704567017654 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/ui/event/ActionListenerList.h0000644000175000017500000000353210762704567023607 0ustar pabspabs/* * Modification History * * 2001-September-15 Jason Rohrer * Created. * * 2001-September-17 Jason Rohrer * Fixed a missing include. * * 2006-July-3 Jason Rohrer * Fixed warnings. */ #ifndef ACTION_LISTENER_LIST_INCLUDED #define ACTION_LISTENER_LIST_INCLUDED #include "ActionListener.h" #include "minorGems/ui/GUIComponent.h" #include "minorGems/util/SimpleVector.h" /** * A utility class to be subclassed by classes needing * to handle a list of action listeners. * * @author Jason Rohrer */ class ActionListenerList : protected SimpleVector { public: virtual ~ActionListenerList(); /** * Adds an action listener. * * @param inListener the listener to add. Must * be destroyed by caller after this class has been destroyed. */ virtual void addActionListener( ActionListener *inListener ); /** * Removes an action listener. * * @param inListener the listener to remove. Must * be destroyed by caller. */ virtual void removeActionListener( ActionListener *inListener ); /** * Tells all registered listeners that an action has been * performed. * * @param inTarget the GUI component on which the action * is being performed. */ virtual void fireActionPerformed( GUIComponent *inTarget ); }; inline ActionListenerList::~ActionListenerList() { } inline void ActionListenerList::addActionListener( ActionListener *inListener ) { push_back( inListener ); } inline void ActionListenerList::removeActionListener( ActionListener *inListener ) { deleteElement( inListener ); } inline void ActionListenerList::fireActionPerformed( GUIComponent *inTarget ) { for( int i=0; iactionPerformed( inTarget ); } } #endif gravitation-3+dfsg1.orig/minorGems/ui/event/ActionListener.h0000644000175000017500000000132310762704567022747 0ustar pabspabs/* * Modification History * * 2001-September-15 Jason Rohrer * Created. * * 2006-July-3 Jason Rohrer * Fixed warnings. */ #ifndef ACTION_LISTENER_INCLUDED #define ACTION_LISTENER_INCLUDED #include "minorGems/ui/GUIComponent.h" /** * An interface for a class that can handle a GUI action. * * @author Jason Rohrer */ class ActionListener { public: virtual ~ActionListener(); /** * Tells this class that an action has been performed. * * @param inTarget the GUI component on which the action * is being performed. */ virtual void actionPerformed( GUIComponent *inTarget ) = 0; }; inline ActionListener::~ActionListener() { } #endif gravitation-3+dfsg1.orig/minorGems/ui/linux/0000755000175000017500000000000010762704567017672 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/ui/linux/KeyboardLinux.cpp0000644000175000017500000000644610762704567023170 0ustar pabspabs/* * Modification History * * 2000-December-7 Jason Rohrer * Created. * * 2000-December-8 Jason Rohrer * Changed so that key state functions take a string instead of * an integer vkey code. * * 2001-May-2 Jason Rohrer * Changed to use more standard SDL include location. * * 2006-June-26 Jason Rohrer * Added function to get events that are waiting in the queue. */ #include "minorGems/ui/Keyboard.h" #include #include /** * Note: Linux implementation: * Requires that a ScreenGraphics be constructed before accessing the keyboard. */ // prototypes: /** * Maps an ascii string description of a key, such as "a", to an SDL keycode. * * @param inKeyDescription an ascii description of a key. * * @return the SDL keycode. */ int getKeyCode( const char *inKeyDescription ); /** * Maps a keycode to an ascii character. * * @param inSDLKeycode the keycode. * * @return the ascii character, or -1 if the keycode is not mappable to ascii. */ int getKeyASCII( int inSDLKeycode ); #define M_KEY SDLK_m #define N_KEY SDLK_n #define S_KEY SDLK_s #define Q_KEY SDLK_q #define L_KEY SDLK_l #define R_KEY SDLK_r #define T_KEY SDLK_t //char Keyboard::getKeyDown( int vKeyCode ) { char Keyboard::getKeyDown( const char *inKeyDescription ) { SDL_PumpEvents(); Uint8 *keys; keys = SDL_GetKeyState( NULL ); return keys[ getKeyCode( inKeyDescription ) ] == SDL_PRESSED; } //char Keyboard::getKeyUp( int vKeyCode ) { char Keyboard::getKeyUp( const char *inKeyDescription ) { SDL_PumpEvents(); Uint8 *keys; keys = SDL_GetKeyState( NULL ); return keys[ getKeyCode( inKeyDescription ) ] == SDL_RELEASED; } int Keyboard::getKeyPressedEvent() { SDL_Event event; if( SDL_PollEvent( &event ) ) { switch( event.type ) { case SDL_KEYDOWN: return getKeyASCII( event.key.keysym.sym ); break; } } else { return -1; } } int getKeyCode( const char *inKeyDescription ) { // note that strcmp functions return 0 if strings match if( !strcasecmp( inKeyDescription, "m" ) ) { return SDLK_m; } else if( !strcasecmp( inKeyDescription, "n" ) ) { return SDLK_n; } else if( !strcasecmp( inKeyDescription, "s" ) ) { return SDLK_s; } else if( !strcasecmp( inKeyDescription, "q" ) ) { return SDLK_q; } else if( !strcasecmp( inKeyDescription, "l" ) ) { return SDLK_l; } else if( !strcasecmp( inKeyDescription, "r" ) ) { return SDLK_r; } else if( !strcasecmp( inKeyDescription, "t" ) ) { return SDLK_t; } } int getKeyASCII( int inSDLKeycode ) { switch( inSDLKeycode ) { case SDLK_m: return 'm'; break; case SDLK_n: return 'n'; break; case SDLK_s: return 's'; break; case SDLK_q: return 'a'; break; case SDLK_l: return 'l'; break; case SDLK_r: return 'r'; break; case SDLK_t: return 't'; break; default: return -1; break; } } /* #define M_KEY SDLK_m #define N_KEY SDLK_n #define S_KEY SDLK_s #define Q_KEY SDLK_q #define L_KEY SDLK_l #define R_KEY SDLK_r #define T_KEY SDLK_t */ gravitation-3+dfsg1.orig/minorGems/ui/linux/MouseLinux.cpp0000644000175000017500000000270610762704567022513 0ustar pabspabs/* * Modification History * * 2000-November-28 Jason Rohrer * Created. * * 2001-May-2 Jason Rohrer * Changed to use more standard SDL include location. */ #include "minorGems/ui/Mouse.h" #include /** * Note: Linux implementation: * Requires that a ScreenGraphics be constructed before accessing the mouse. */ void Mouse::getLocation( int *outX, int *outY ) { SDL_PumpEvents(); SDL_GetMouseState( outX, outY ); /* SDL_PumpEvents( void ); int numEventsToGet = 99; SDL_Event *events = new SDL_Event[numEventsToGet]; // get events from the queue int numEventsRetrieved = SDL_PeepEvents( events, numEventsToGet, SDL_GETEVENT, SDL_MOUSEMOTIONMASK ); // for mouse motion, we only care about the last event SDL_Event lastEvent = events[ numEventsRetrieved - 1 ]; delete [] events; */ } char Mouse::isButtonDown( int inButtonNumber ) { SDL_PumpEvents(); int x, y; Uint8 buttonState = SDL_GetMouseState( &x, &y ); if( inButtonNumber == 0 ) { return( buttonState & SDL_BUTTON_LMASK ); } if( mNumButtons >=3 ) { // if we care about 3 buttons, then count the middle button // as button 1 if( inButtonNumber == 1 ) { return( buttonState & SDL_BUTTON_MMASK ); } if( inButtonNumber == 2 ) { return( buttonState & SDL_BUTTON_RMASK ); } } else { // we care about 2 or fewer buttons if( inButtonNumber == 1 ) { return( buttonState & SDL_BUTTON_RMASK ); } } return false; } gravitation-3+dfsg1.orig/minorGems/ui/Plot.h0000644000175000017500000000262510762704567017627 0ustar pabspabs// Jason Rohrer // Plot.h /** * * Scrolling Plot Gui element * * * Created 11-7-99 * Mods: * Jason Rohrer 11-8-99 Changed to use GraphicBuffer object as screen buffer * */ #ifndef PLOT_INCLUDED #define PLOT_INCLUDED #include #include "Color.h" #include "GraphicBuffer.h" class Plot { public: // construct a plot in a specific location with // specific border, background, and line colors Plot( int x, int y, int w, int h, Color bordC, Color bC, Color lnC ); ~Plot(); // add a point to the right of plot, cause plot to scroll left void addPoint( float p ); // draw plot into a graphic buffer void draw( GraphicBuffer &buff ); // erase plot from buffer void erase( GraphicBuffer &buff, Color &bgColor ); private: unsigned long *imageMap; int startX; int startY; int high; int wide; int innerHigh; // width and heigth of area inside borders int innerWide; int *mapYOffset; Color borderC; // color of border Color bgC; // color of progress bar max Color lineC; // color of plot line static const int borderWide = 2; float *plotVals; // values of plot line }; inline void Plot::draw( GraphicBuffer &buff ) { buff.drawImage(imageMap, mapYOffset, startX, startY, wide, high); } inline void Plot::erase( GraphicBuffer &buff, Color &bgColor ) { buff.eraseImage(startX, startY, wide, high, bgColor); } #endifgravitation-3+dfsg1.orig/minorGems/ui/ProgressBar.cpp0000644000175000017500000000500210762704567021465 0ustar pabspabs// Jason Rohrer // ProgressBar.cpp /** * * ProgressBar Gui element implementation * * * Created 11-6-99 * Mods: * Jason Rohrer 11-8-99 Changed to use GraphicBuffer object as screen buffer * */ #include "ProgressBar.h" ProgressBar::ProgressBar(int x, int y, int w, int h, Color bordC, Color hC, Color tipC) { startX = x; startY = y; wide = w; high = h; barWide = wide - 2*borderWide; barHigh = high - 2*borderWide; borderC = bordC; highC = hC; barTipC = tipC; imageMap = new unsigned long[high * wide]; mapYOffset = new int[high]; // precalc y offsets into 2d image map for( int y=0; yhigh-borderWide-1 || x>wide-borderWide-1 ) { imageMap[ yContrib + x ] = borderC.composite; // border } else { imageMap[ yContrib + x ] = 0xFF000000; // black inside } } } lastProgress = 0; } ProgressBar::~ProgressBar() { delete [] imageMap; delete [] mapYOffset; } void ProgressBar::setProgress(float fractionFull) { if( fractionFull < 0) fractionFull = 0; if( fractionFull > 1) fractionFull = 1; if( fractionFull < lastProgress ) { // decreasing proress, erase part of bar int deleteXStart = (int)((fractionFull) * barWide + borderWide); int deleteXEnd = (int)((lastProgress) * barWide + borderWide); for( int y=borderWide; y lastProgress) { //progress has increased int addXStart = (int)((lastProgress) * barWide + borderWide); int addXEnd = (int)((fractionFull) * barWide + borderWide); float weight = lastProgress; float deltaWeight = (fractionFull - lastProgress) / (addXEnd - addXStart); for( int x=addXStart; xhigh-borderWide-1 || x>wide-borderWide-1 ) { imageMap[ yContrib + x ] = borderC.composite; // border } else { imageMap[ yContrib + x ] = bgC.composite; // background } } } plotVals = new float[innerWide]; for( int i=0; i 0) { invLargest = 1/largest; } // fill plot with bg color for( int y=borderWide; y innerHigh + borderWide ) y = innerHigh + borderWide -1; if( y < borderWide ) y = borderWide; imageMap[ mapYOffset[y] + x ] = lineC.composite; // line } /* for( int x=0; x #include "SetMouse.h" void SetMouse (int x, int y) { Point base; // This routine donated to MacMAME by John Stiles // Picked up for RadiosGL from the Mac GLQuake site Point *RawMouse = (Point*) 0x82C; Point *MTemp = (Point*) 0x828; Ptr CrsrNew = (Ptr) 0x8CE; Ptr CrsrCouple = (Ptr) 0x8CF; base.v = y; base.h = x; LocalToGlobal(&base); *RawMouse = base; *MTemp = base; *CrsrNew = *CrsrCouple; } // do nothing, these are needed in windows only void CaptureMouse() { } void ReleaseMouse() { }gravitation-3+dfsg1.orig/minorGems/ui/Keyboard.h0000644000175000017500000000316110762704567020445 0ustar pabspabs/* * Modification History * * 2000-December-7 Jason Rohrer * Created. * * 2000-December-8 Jason Rohrer * Changed so that key state functions take a string instead of * an integer vkey code. * * 2006-June-26 Jason Rohrer * Added function to get events that are waiting in the queue. */ #ifndef KEYBOARD_INCLUDED #define KEYBOARD_INCLUDED /** * Interface for accessing keyboard input. * * Note: * Certain implementations may require a ScreenGraphics object to * be constructed before accessing the keyboard (i.e., to give the * keyboard input a context). */ class Keyboard { public: /* * Key descriptions: * * For the standard ascii characters, pass in the string containing * the lower case character, for example, "a" for the character A. * * For other keys, the descriptors have not been defined yet. */ /** * Gets whether a key is down. * * @param inKeyDescription string describing the queried key. * * @return true if key represented by given key code is down. */ //char getKeyDown( int vKeyCode ); char getKeyDown( const char *inKeyDescription ); /** * Gets whether a key is up. * * @param inKeyDescription string describing the queried key. * * @return true if key represented by given key code is up. */ //char getKeyUp( int vKeyCode ); char getKeyUp( const char *inKeyDescription ); /** * Gets the next keyboard event. * * @return the ASCII encoding of the pressed key, or -1 if no * keyboard events are waiting. */ int getKeyPressedEvent(); }; #endif gravitation-3+dfsg1.orig/minorGems/ui/SetMouse.h0000644000175000017500000000042410762704567020450 0ustar pabspabs// Jason Rohrer // SetMouse.h /** * * Interface for force-setting mouse cursor position * * Created 1-14-2000 * Mods: * Jason Rohrer 1-18-2000 Added capture and release mouse functions to help Win32 */ void SetMouse( int x, int y); void CaptureMouse(); void ReleaseMouse();gravitation-3+dfsg1.orig/minorGems/ui/Mouse.h0000644000175000017500000000327410762704567020002 0ustar pabspabs/* * Modification History * * 2000-November-28 Jason Rohrer * Created. */ #ifndef MOUSE_INCLUDED #define MOUSE_INCLUDED /** * Interface for accessing mouse input. * * Note: * Certain implementations may require a ScreenGraphics object to * be constructed before accessing the mouse (i.e., to give the * mouse coordinates a context). */ class Mouse { public: /** * Constructs a Mouse. * * @param inNumButtons the number of buttons on the mouse that should * be monitored. Default = 1. */ Mouse( int inNumButtons ); ~Mouse(); /** * Gets the location of the mouse. * * @param outX pointer to location where x component will be returned. * @param outY pointer to location where y component will be returned. */ void getLocation( int *outX, int *outY ); /** * Gets whether the main mouse button is down. * * @return true if the main mouse button is down. */ char isButtonDown(); /** * Gets whether a specified mouse button is down. * * @param inButtonNumber the number of the button to check for * (0 is the main mouse button). * * @return true if the specified mouse button is down. */ char isButtonDown( int inButtonNumber ); private: int mXLocation; int mYLocation; int mNumButtons; // array of booleans that represent the current // (or last known) state of each button char *mButtonDown; }; inline Mouse::Mouse( int inNumButtons = 1 ) : mNumButtons( inNumButtons ), mButtonDown( new char[inNumButtons] ) { } inline Mouse::~Mouse() { delete [] mButtonDown; } inline char Mouse::isButtonDown() { return isButtonDown( 0 ); } #endif gravitation-3+dfsg1.orig/minorGems/ui/SetMouseWin32.cpp0000644000175000017500000000154410762704567021632 0ustar pabspabs// Jason Rohrer // SetMouseWin32.cpp /** * * implementation of SetMouse on Win32 * This uses an "official" os feature (unlike the hacked mac version * * Created 1-16-2000 * Mods: * Jason Rohrer 1-18-2000 Added conversion from client to screen coords. * GLUT tracks mouse motion relative to window * Windows can only set the cursor position using * screen coordinates. */ #include #include "SetMouse.h" char captured = false; void SetMouse( int x, int y ) { POINT p; p.x = x; p.y = y; HWND window = GetActiveWindow(); ClientToScreen( window, &p ); SetCursorPos( p.x, p.y ); //SetCursorPos( x, y ); } // send all mouse movements to our window, even those outside the border void CaptureMouse() { HWND window = GetActiveWindow(); SetCapture( window ); } void ReleaseMouse() { ReleaseCapture(); }gravitation-3+dfsg1.orig/minorGems/util/0000755000175000017500000000000010762704570017065 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/util/log/0000755000175000017500000000000010762704570017646 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/util/log/AppLog.cpp0000644000175000017500000000553510762704570021544 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. * * 2002-March-30 Jason Rohrer * Wrapped our dynamically allocated static member in a statically * allocated class to avoid memory leaks at program termination. */ #include "AppLog.h" #include "Log.h" #include // wrap our static member in a statically allocated class LogPointerWrapper AppLog::mLogPointerWrapper( new PrintLog ); LogPointerWrapper::LogPointerWrapper( Log *inLog ) : mLog( inLog ) { } LogPointerWrapper::~LogPointerWrapper() { if( mLog != NULL ) { delete mLog; } } void AppLog::criticalError( char *inString ) { mLogPointerWrapper.mLog->logString( inString, Log::CRITICAL_ERROR_LEVEL ); } void AppLog::criticalError( char *inLoggerName, char *inString ) { mLogPointerWrapper.mLog->logString( inLoggerName, inString, Log::CRITICAL_ERROR_LEVEL ); } void AppLog::error( char *inString ) { mLogPointerWrapper.mLog->logString( inString, Log::ERROR_LEVEL ); } void AppLog::error( char *inLoggerName, char *inString ) { mLogPointerWrapper.mLog->logString( inLoggerName, inString, Log::ERROR_LEVEL ); } void AppLog::warning( char *inString ) { mLogPointerWrapper.mLog->logString( inString, Log::WARNING_LEVEL ); } void AppLog::warning( char *inLoggerName, char *inString ) { mLogPointerWrapper.mLog->logString( inLoggerName, inString, Log::WARNING_LEVEL ); } void AppLog::info( char *inString ) { mLogPointerWrapper.mLog->logString( inString, Log::INFO_LEVEL ); } void AppLog::info( char *inLoggerName, char *inString ) { mLogPointerWrapper.mLog->logString( inLoggerName, inString, Log::INFO_LEVEL ); } void AppLog::detail( char *inString ) { mLogPointerWrapper.mLog->logString( inString, Log::DETAIL_LEVEL ); } void AppLog::detail( char *inLoggerName, char *inString ) { mLogPointerWrapper.mLog->logString( inLoggerName, inString, Log::DETAIL_LEVEL ); } void AppLog::trace( char *inString ) { mLogPointerWrapper.mLog->logString( inString, Log::TRACE_LEVEL ); } void AppLog::trace( char *inLoggerName, char *inString ) { mLogPointerWrapper.mLog->logString( inLoggerName, inString, Log::TRACE_LEVEL ); } void AppLog::setLog( Log *inLog ) { int currentLoggingLevel = getLoggingLevel(); if( inLog != mLogPointerWrapper.mLog ) { delete mLogPointerWrapper.mLog; } mLogPointerWrapper.mLog = inLog; setLoggingLevel( currentLoggingLevel ); } Log *AppLog::getLog() { return mLogPointerWrapper.mLog; } void AppLog::setLoggingLevel( int inLevel ) { mLogPointerWrapper.mLog->setLoggingLevel( inLevel ); } int AppLog::getLoggingLevel() { return mLogPointerWrapper.mLog->getLoggingLevel(); } gravitation-3+dfsg1.orig/minorGems/util/log/Makefile0000644000175000017500000000235710762704570021315 0ustar pabspabs# # Modification History # # 2002-February-25 Jason Rohrer # Created. # Changed to be more succinct. # GXX=g++ ROOT_PATH = ../../.. DEBUG_ON_FLAG = -g DEBUG_OFF_FLAG = DEBUG_FLAG = ${DEBUG_OFF_FLAG} TIME_PLATFORM_PATH = unix TIME_PLATFORM = Unix TIME_O = ${ROOT_PATH}/minorGems/system/${TIME_PLATFORM_PATH}/Time${TIME_PLATFORM}.o TIME_H = ${ROOT_PATH}/minorGems/system/Time.h TIME_CPP = ${ROOT_PATH}/minorGems/system/${TIME_PLATFORM_PATH}/Time${TIME_PLATFORM}.cpp testLog: AppLog.o FileLog.o PrintLog.o Log.o testLog.o ${TIME_O} ${GXX} ${DEBUG_FLAG} -o testLog AppLog.o FileLog.o PrintLog.o Log.o testLog.o ${TIME_O} clean: rm -f *.o ${TIME_O} testLog.o: testLog.cpp AppLog.h FileLog.h Log.h ${GXX} ${DEBUG_FLAG} -o testLog.o -c testLog.cpp AppLog.o: AppLog.h AppLog.cpp Log.h PrintLog.h ${GXX} ${DEBUG_FLAG} -o AppLog.o -c AppLog.cpp PrintLog.o: PrintLog.h PrintLog.cpp Log.h PrintLog.h ${TIME_H} ${GXX} ${DEBUG_FLAG} -I${ROOT_PATH} -o PrintLog.o -c PrintLog.cpp FileLog.o: PrintLog.h FileLog.cpp FileLog.h Log.h ${GXX} ${DEBUG_FLAG} -o FileLog.o -c FileLog.cpp Log.o: Log.h Log.cpp ${GXX} ${DEBUG_FLAG} -o Log.o -c Log.cpp ${TIME_O}: ${TIME_H} ${TIME_CPP} ${GXX} ${DEBUG_FLAG} -I${ROOT_PATH} -o ${TIME_O} -c ${TIME_CPP} gravitation-3+dfsg1.orig/minorGems/util/log/Log.h0000644000175000017500000000457110762704570020547 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. * * 2002-March-29 Jason Rohrer * Added Fortify inclusion. */ #include "minorGems/common.h" #ifndef LOG_INCLUDED #define LOG_INCLUDED #ifdef FORTIFY #include "minorGems/util/development/fortify/fortify.h" #endif /** * An interface for a class that can perform logging functions. * * @author Jason Rohrer */ class Log { public: // These levels were copied from the JLog framework // by Todd Lauinger static const int DEACTIVATE_LEVEL; static const int CRITICAL_ERROR_LEVEL; static const int ERROR_LEVEL; static const int WARNING_LEVEL; static const int INFO_LEVEL; static const int DETAIL_LEVEL; static const int TRACE_LEVEL; // provided so that virtual deletes work properly virtual ~Log(); /** * Sets the logging level of the current log. * * Messages with levels above the current level will not be logged. * * @param inLevel one of the defined logging levels. */ virtual void setLoggingLevel( int inLevel ) = 0; /** * Gets the logging level of the current log. * * Messages with levels above the current level will not be logged. * * @return one of the defined logging levels. */ virtual int getLoggingLevel() = 0; /** * Logs a string in this log under the default logger name. * * @param inString the string to log as a \0-terminated string. * Must be destroyed by caller. * @param inLevel the level to log inString at. */ virtual void logString( char *inString, int inLevel ) = 0; /** * Logs a string in this log, specifying a logger name. * * @param inLoggerName the name of the logger * as a \0-terminated string. * Must be destroyed by caller. * @param inString the string to log as a \0-terminated string. * Must be destroyed by caller. * @param inLevel the level to log inString at. */ virtual void logString( char *inLoggerName, char *inString, int inLevel ) = 0; }; #endif gravitation-3+dfsg1.orig/minorGems/util/log/AppLog.h0000644000175000017500000000661010762704570021204 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. * * 2002-March-30 Jason Rohrer * Wrapped our dynamically allocated static member in a statically * allocated class to avoid memory leaks at program termination. */ #include "minorGems/common.h" #ifndef APP_LOG_INCLUDED #define APP_LOG_INCLUDED #include "Log.h" #include "PrintLog.h" // internally used class class LogPointerWrapper; /** * A singleton wrapper for implementations of the Log interface. * * This class should be the interface for log-access for applications. * * @author Jason Rohrer */ class AppLog { public: /** * These log errors at various levels. * * All char* parameters must be \0-terminated and destroyed by caller. */ static void criticalError( char *inString ); static void criticalError( char *inLoggerName, char *inString ); static void error( char *inString ); static void error( char *inLoggerName, char *inString ); static void warning( char *inString ); static void warning( char *inLoggerName, char *inString ); static void info( char *inString ); static void info( char *inLoggerName, char *inString ); static void detail( char *inString ); static void detail( char *inLoggerName, char *inString ); static void trace( char *inString ); static void trace( char *inLoggerName, char *inString ); /** * Sets the log to use. * Note that this call destroys the current log. * * @param inLog the log to use. * Will be destroyed by this class. */ static void setLog( Log *inLog ); /** * Gets the log being used. * * @return the log being used. * Will be destroyed by this class. */ static Log *getLog(); /** * Sets the logging level of the current log. * * Messages with levels above the current level will not be logged. * * @param inLevel one of the defined logging levels. */ static void setLoggingLevel( int inLevel ); /** * Gets the logging level of the current log. * * Messages with levels above the current level will not be logged. * * @return one of the defined logging levels. */ static int getLoggingLevel(); protected: // note that all static objects // are destroyed at program termination //static Log *mLog; static LogPointerWrapper mLogPointerWrapper; }; /** * Wrapper for static member pointer to ensure * deletion of static member object at program termination. */ class LogPointerWrapper { public: /** * Constructor allows specification of the object * to wrap and destroy at program termination. * * @param inLog the log object to wrap. * Will be destroyed at program termination if non-NULL. */ LogPointerWrapper( Log *inLog ); /** * Destructor will get called at program termination * if the object is statically allocated. */ ~LogPointerWrapper(); Log *mLog; }; #endif gravitation-3+dfsg1.orig/minorGems/util/log/FileLog.cpp0000644000175000017500000000576610762704570021711 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. * * 2002-March-13 Jason Rohrer * Added a flush after every write. * * 2002-April-8 Jason Rohrer * Changed to be thread-safe. * * 2002-November-5 Jason Rohrer * Added support for backing up logs and deleting old log data. */ #include "FileLog.h" #include "PrintLog.h" #include "minorGems/util/stringUtils.h" #include "minorGems/io/file/File.h" #include #include const char *FileLog::mDefaultLogFileName = "default.log"; FileLog::FileLog( char *inFileName, unsigned long inSecondsBetweenBackups ) : mLogFile( NULL ), mLogFileName( stringDuplicate( inFileName ) ), mSecondsBetweenBackups( inSecondsBetweenBackups ), mTimeOfLastBackup( time( NULL ) ) { mLogFile = fopen( mLogFileName, "a" ); if( mLogFile == NULL ) { printf( "Log file %s failed to open.\n", mLogFileName ); printf( "Writing log to default file: %s\n", mDefaultLogFileName ); // switch to default log file name delete [] mLogFileName; mLogFileName = stringDuplicate( mDefaultLogFileName ); mLogFile = fopen( mLogFileName, "a" ); if( mLogFile == NULL ) { printf( "Default log file %s failed to open.\n", mLogFileName ); } } } FileLog::~FileLog() { if( mLogFile != NULL ) { fclose( mLogFile ); } delete [] mLogFileName; } void FileLog::logString( char *inLoggerName, char *inString, int inLevel ) { if( mLogFile != NULL ) { if( inLevel <= mLoggingLevel ) { char *message = PrintLog::generateLogMessage( inLoggerName, inString, inLevel ); mLock->lock(); fprintf( mLogFile, "%s\n", message ); fflush( mLogFile ); if( time( NULL ) - mTimeOfLastBackup > mSecondsBetweenBackups ) { makeBackup(); } mLock->unlock(); delete [] message; } } } void FileLog::makeBackup() { fclose( mLogFile ); File *currentLogFile = new File( NULL, mLogFileName ); char *backupFileName = new char[ strlen( mLogFileName ) + 10 ]; sprintf( backupFileName, "%s.backup", mLogFileName ); File *backupLogFile = new File( NULL, backupFileName ); delete [] backupFileName; // copy into backup log file, which will overwrite it currentLogFile->copy( backupLogFile ); delete currentLogFile; delete backupLogFile; // clear main log file and start writing to it again mLogFile = fopen( mLogFileName, "w" ); if( mLogFile == NULL ) { printf( "Log file %s failed to open.\n", mLogFileName ); } mTimeOfLastBackup = time( NULL ); } gravitation-3+dfsg1.orig/minorGems/util/log/FileLog.h0000644000175000017500000000337710762704570021352 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. * * 2002-November-5 Jason Rohrer * Added support for backing up logs and deleting old log data. */ #include "minorGems/common.h" #ifndef FILE_LOG_INCLUDED #define FILE_LOG_INCLUDED #include "PrintLog.h" #include /** * A file-based implementation of the Log interface. * * @author Jason Rohrer */ class FileLog : public PrintLog { public: /** * Constructs a file log. * * @param inFileName the name of the file to write log messages to. * Must be destroyed by caller. * @param inSecondsBetweenBackups the number of seconds to wait * before making a backup of the current log file (deleting any * old backups), clearing the current log file, and starting * a fresh log in the current log file. Defaults to 3600 * seconds (one hour). Backup logs are saved to inFileName.bakup */ FileLog( char *inFileName, unsigned long inSecondsBetweenBackups = 3600 ); virtual ~FileLog(); /** * Makes a backup of the current log file, deletes old backups, * and clears the current log file. */ void makeBackup(); // overrides PrintLog::logString virtual void logString( char *inLoggerName, char *inString, int inLevel ); protected: FILE *mLogFile; char *mLogFileName; unsigned long mSecondsBetweenBackups; unsigned long mTimeOfLastBackup; static const char *mDefaultLogFileName; }; #endif gravitation-3+dfsg1.orig/minorGems/util/log/Log.cpp0000644000175000017500000000057110762704570021076 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. */ #include "Log.h" const int Log::DEACTIVATE_LEVEL = 0; const int Log::CRITICAL_ERROR_LEVEL = 1; const int Log::ERROR_LEVEL = 2; const int Log::WARNING_LEVEL = 3; const int Log::INFO_LEVEL = 4; const int Log::DETAIL_LEVEL = 5; const int Log::TRACE_LEVEL = 6; Log::~Log() { } gravitation-3+dfsg1.orig/minorGems/util/log/PrintLog.h0000644000175000017500000000326410762704570021562 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. * * 2002-April-8 Jason Rohrer * Changed to be thread-safe. */ #include "minorGems/common.h" #ifndef PRINT_LOG_INCLUDED #define PRINT_LOG_INCLUDED #include "Log.h" #include "minorGems/system/MutexLock.h" /** * A console-based implementation of the Log interface. * * @author Jason Rohrer */ class PrintLog : public Log { public: /** * Constructs a print log. */ PrintLog(); virtual ~PrintLog(); // implement the Log interface virtual void setLoggingLevel( int inLevel ); virtual int getLoggingLevel(); virtual void logString( char *inString, int inLevel ); virtual void logString( char *inLoggerName, char *inString, int inLevel ); protected: int mLoggingLevel; static const char *mDefaultLoggerName; MutexLock *mLock; /** * Generates a string representation of a log message. * * @param inLoggerName the name of the logger * as a \0-terminated string. * Must be destroyed by caller. * @param inString the string to log as a \0-terminated string. * Must be destroyed by caller. * @param inLevel the level to log inString at. * * @return the log message as a \0-terminated string. * Must be destroyed by caller. */ char *generateLogMessage( char *inLoggerName, char *inString, int inLevel ); }; #endif gravitation-3+dfsg1.orig/minorGems/util/log/PrintLog.cpp0000644000175000017500000000615010762704570022112 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. * * 2002-March-11 Jason Rohrer * Added a missing include. * * 2002-April-8 Jason Rohrer * Fixed a casting, dereferencing Win32 compile bug. * Changed to be thread-safe. * Changed to use thread-safe printing function. * * 2002-April-8 Jason Rohrer * Fixed a signed-unsigned mismatch. * * 2004-January-11 Jason Rohrer * Added lock around asctime call. * Increased scope of lock. * * 2004-January-29 Jason Rohrer * Changed to use ctime instead of localtime and asctime. * Improved locking scope. * Changed to use autoSprintf. */ #include "PrintLog.h" #include "minorGems/system/Time.h" #include "minorGems/util/printUtils.h" #include "minorGems/util/stringUtils.h" #include #include #include const char *PrintLog::mDefaultLoggerName = "general"; PrintLog::PrintLog() : mLoggingLevel( Log::TRACE_LEVEL ), mLock( new MutexLock() ) { } PrintLog::~PrintLog() { delete mLock; } void PrintLog::setLoggingLevel( int inLevel ) { mLock->lock(); mLoggingLevel = inLevel; mLock->unlock(); } int PrintLog::getLoggingLevel() { mLock->lock(); int level = mLoggingLevel; mLock->unlock(); return level; } void PrintLog::logString( char *inString, int inLevel ) { logString( (char *)mDefaultLoggerName, inString, inLevel ); } void PrintLog::logString( char *inLoggerName, char *inString, int inLevel ) { // not thread-safe to read mLoggingLevel here // without synchronization. // However, we want logging calls that are above // our level to execute with nearly no overhead. // mutex might be too much overhead.... // Besides, not being thread-safe in this case might // (worst case) result in a missed log entry or // an extra log entry... but setting the logging level should be rare. if( inLevel <= mLoggingLevel ) { char *message = generateLogMessage( inLoggerName, inString, inLevel ); threadPrintF( "%s\n", message ); delete [] message; } } char *PrintLog::generateLogMessage( char *inLoggerName, char *inString, int inLevel ) { unsigned long seconds, milliseconds; Time::getCurrentTime( &seconds, &milliseconds ); // lock around ctime call, since it returns a static buffer mLock->lock(); char *dateString = stringDuplicate( ctime( (time_t *)( &seconds ) ) ); // done with static buffer, since we made a copy mLock->unlock(); // this date string ends with a newline... // get rid of it dateString[ strlen(dateString) - 1 ] = '\0'; char *messageBuffer = autoSprintf( "L%d | %s (%ld ms) | %s | %s", inLevel, dateString, milliseconds, inLoggerName, inString ); delete [] dateString; return messageBuffer; } gravitation-3+dfsg1.orig/minorGems/util/log/testLog.cpp0000644000175000017500000000147210762704570021777 0ustar pabspabs/* * Modification History * * 2002-February-25 Jason Rohrer * Created. */ #include "AppLog.h" #include "FileLog.h" #include "Log.h" int main() { AppLog::warning( "A test warning" ); AppLog::warning( "Another test warning" ); AppLog::warning( "mainApp", "And Another test warning" ); AppLog::setLoggingLevel( Log::ERROR_LEVEL ); AppLog::warning( "Yet Another test warning" ); AppLog::error( "mainApp", "A test error" ); AppLog::setLog( new FileLog( "test.log" ) ); // this should be skipped AppLog::warning( "A second test warning" ); // this should not be AppLog::criticalError( "A critical error" ); AppLog::setLog( new FileLog( "test2.log" ) ); // this should be skipped AppLog::warning( "A third test warning" ); return 0; } gravitation-3+dfsg1.orig/minorGems/util/test/0000755000175000017500000000000010762704570020044 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/util/test/testSnprintf.cpp0000644000175000017500000000232410762704570023254 0ustar pabspabs/* * Modification History * * 2004-January-15 Jason Rohrer * Created. */ /** * A test program for snprintf behavior. */ #include #include #include int main() { int numStrings = 3; // test strings of length 3, 4, and 5 const char *testStrings[3] = { "tst", "test", "testt" }; int result; // a buffer of length 4, which IS NOT large // enough to hold the last two testStrings char *buffer = (char*)( malloc( 4 ) ); int i; for( i=0; i to explicitly specialized * getElementString. */ #include "minorGems/common.h" #ifndef SIMPLEVECTOR_INCLUDED #define SIMPLEVECTOR_INCLUDED #include // for memory moving functions const int defaultStartSize = 50; template class SimpleVector { public: SimpleVector(); // create an empty vector SimpleVector(int sizeEstimate); // create an empty vector with a size estimate ~SimpleVector(); void push_back(Type x); // add x to the end of the vector Type *getElement(int index); // get a ptr to element at index in vector int size(); // return the number of allocated elements in the vector bool deleteElement(int index); // delete element at an index in vector /** * Deletes a particular element. Deletes the first element * in vector == to inElement. * * @param inElement the element to delete. * * @return true iff an element was deleted. */ bool deleteElement( Type inElement ); /** * Gets the index of a particular element. Gets the index of the * first element in vector == to inElement. * * @param inElement the element to get the index of. * * @return the index if inElement, or -1 if inElement is not found. */ int getElementIndex( Type inElement ); void deleteAll(); // delete all elements from vector /** * Gets the elements as an array. * * @return the a new array containing all elements in this vector. * Must be destroyed by caller, though elements themselves are * not copied. */ Type *getElementArray(); /** * Gets the char elements as a \0-terminated string. * * @return a \0-terminated string containing all elements in this * vector. * Must be destroyed by caller. */ char *getElementString(); private: Type *elements; int numFilledElements; int maxSize; int minSize; // number of allocated elements when vector is empty }; template inline SimpleVector::SimpleVector() { elements = new Type[defaultStartSize]; numFilledElements = 0; maxSize = defaultStartSize; minSize = defaultStartSize; } template inline SimpleVector::SimpleVector(int sizeEstimate) { elements = new Type[sizeEstimate]; numFilledElements = 0; maxSize = sizeEstimate; minSize = sizeEstimate; } template inline SimpleVector::~SimpleVector() { delete [] elements; } template inline int SimpleVector::size() { return numFilledElements; } template inline Type *SimpleVector::getElement(int index) { if( index < numFilledElements && index >=0 ) { return &(elements[index]); } else return NULL; } template inline bool SimpleVector::deleteElement(int index) { if( index < numFilledElements) { // if index valid for this vector if( index != numFilledElements - 1) { // this spot somewhere in middle // move memory towards front by one spot int sizeOfElement = sizeof(Type); int numBytesToMove = sizeOfElement*(numFilledElements - (index+1)); Type *destPtr = &(elements[index]); Type *srcPtr = &(elements[index+1]); memmove((void *)destPtr, (void *)srcPtr, numBytesToMove); } numFilledElements--; // one less element in vector return true; } else { // index not valid for this vector return false; } } template inline bool SimpleVector::deleteElement( Type inElement ) { int index = getElementIndex( inElement ); if( index != -1 ) { return deleteElement( index ); } else { return false; } } template inline int SimpleVector::getElementIndex( Type inElement ) { // walk through vector, looking for first match. for( int i=0; i inline void SimpleVector::deleteAll() { numFilledElements = 0; if( maxSize > minSize ) { // free memory if vector has grown delete [] elements; elements = new Type[minSize]; // reallocate an empty vector maxSize = minSize; } } template inline void SimpleVector::push_back(Type x) { if( numFilledElements < maxSize) { // still room in vector elements[numFilledElements] = x; numFilledElements++; } else { // need to allocate more space for vector int newMaxSize = maxSize << 1; // double size Type *newAlloc = new Type[newMaxSize]; int sizeOfElement = sizeof(Type); int numBytesToMove = sizeOfElement*(numFilledElements); // move into new space memcpy((void *)newAlloc, (void *) elements, numBytesToMove); // delete old space delete [] elements; elements = newAlloc; maxSize = newMaxSize; elements[numFilledElements] = x; numFilledElements++; } } template inline Type *SimpleVector::getElementArray() { Type *newAlloc = new Type[ numFilledElements ]; int sizeOfElement = sizeof( Type ); int numBytesToCopy = sizeOfElement * numFilledElements; // copy into new space memcpy( (void *)newAlloc, (void *)elements, numBytesToCopy ); return newAlloc; } template <> inline char *SimpleVector::getElementString() { char *newAlloc = new char[ numFilledElements + 1 ]; int sizeOfElement = sizeof( char ); int numBytesToCopy = sizeOfElement * numFilledElements; // copy into new space memcpy( (void *)newAlloc, (void *)elements, numBytesToCopy ); newAlloc[ numFilledElements ] = '\0'; return newAlloc; } #endif gravitation-3+dfsg1.orig/minorGems/util/stringUtils.h0000644000175000017500000002125510762704570021572 0ustar pabspabs/* * Modification History * * 2002-April-6 Jason Rohrer * Created. * * 2002-April-8 Jason Rohrer * Fixed multiple inclusion bug * * 2002-May-7 Jason Rohrer * Added functions for case-insensitive substring finding and case * conversion. * * 2002-May-9 Jason Rohrer * Fixed a bug when string not found. * * 2002-May-26 Jason Rohrer * Added a function for string comparison ignoring cases. * * 2003-March-28 Jason Rohrer * Added split function. * * 2003-May-1 Jason Rohrer * Added replacement functions. * * 2003-May-4 Jason Rohrer * Added list replacement function. * * 2003-May-10 Jason Rohrer * Moved implementations into a .cpp file. This will break several * projects. * Added a tokenization function. * * 2003-June-14 Jason Rohrer * Added a join function. * * 2003-June-22 Jason Rohrer * Added an autoSprintf function. * * 2003-August-12 Jason Rohrer * Added a concatonate function. * * 2003-September-7 Jason Rohrer * Improved split comment. * * 2006-June-2 Jason Rohrer * Added a stringStartsWith function. */ #include "minorGems/common.h" #include "minorGems/util/SimpleVector.h" #ifndef STRING_UTILS_INCLUDED #define STRING_UTILS_INCLUDED // ANSI does not support strdup, strcasestr, or strcasecmp #include #include #include /** * Duplicates a string into a newly allocated string. * * @param inString the \0-terminated string to duplicate. * Must be destroyed by caller if non-const. * * @return a \0-terminated duplicate of inString. * Must be destroyed by caller. */ inline char *stringDuplicate( const char *inString ) { char *returnBuffer = new char[ strlen( inString ) + 1 ]; strcpy( returnBuffer, inString ); return returnBuffer; } /** * Converts a string to lower case. * * @param inString the \0-terminated string to convert. * Must be destroyed by caller if non-const. * * @return a newly allocated \0-terminated string * that is a lowercase version of inString. * Must be destroyed by caller. */ char *stringToLowerCase( const char *inString ); /** * Searches for the first occurrence of one string in another. * * @param inHaystack the \0-terminated string to search in. * Must be destroyed by caller if non-const. * @param inNeedle the \0-terminated string to search for. * Must be destroyed by caller if non-const. * * @return a string pointer into inHaystack where the * first occurrence of inNeedle starts, or NULL if inNeedle is not found. */ char *stringLocateIgnoreCase( const char *inHaystack, const char *inNeedle ); /** * Compares two strings, ignoring case. * * @param inStringA the first \0-terminated string. * Must be destroyed by caller if non-const. * @param inStringB the second \0-terminated string. * Must be destroyed by caller if non-const. * * @return an integer less than, equal to, or greater than zero if * inStringA is found, respectively, to be less than, to match, or be * greater than inStringB. */ int stringCompareIgnoreCase( const char *inStringA, const char *inStringB ); /** * Checks if a string starts with a given prefix string. * * @param inString a \0-terminated string. * Must be destroyed by caller if non-const. * @param inPrefix the prefix to look for as a \0-terminated string. * Must be destroyed by caller if non-const. * * @return true if inString begins with inPrefix, or false otherwise. */ char stringStartsWith( const char *inString, const char *inPrefix ); /** * Splits a string into parts around a separator string. * * Note that splitting strings that start and/or end with the separator * results in "empty" strings being returned at the start and/or end * of the parts array. * * For example, splitting "a#short#test" around the "#" separator will * result in the array { "a", "short", "test" }, but splitting * "#another#short#test#" will result in the array * { "", "another", "short", "test", "" }. * * This differs somewhat from the perl version of split, but it gives the * caller more information about the string being split. * * @param inString the string to split. * Must be destroyed by caller if non-const. * @param inSeparator the separator string. * Must be destroyed by caller if non-const. * @param outNumParts pointer to where the the number of parts (the length of * the returned array) should be returned. * * @return an array of split parts. * Must be destroyed by caller. */ char **split( char *inString, char *inSeparator, int *outNumParts ); /** * Joins a collection of strings using a separator string. * * @param inStrings the strings to join. * Array and strings must be destroyed by caller. * @param inNumParts the number of strings to join. * @param inSeparator the separator string. * Must be destroyed by caller if non-const. * * @return the joined string. * Must be destroyed by caller. */ char *join( char **inStrings, int inNumParts, char *inGlue ); /** * Concatonates two strings. * * @param inStringA the first string in the concatonation. * Must be destroyed by caller if non-const. * @param inStringB the second string in the concatonation. * Must be destroyed by caller if non-const. * * @return the concatonation. * Must be destroyed by caller. */ char *concatonate( char *inStringA, char *inStringB ); /** * Replaces the first occurrence of a target string with * a substitute string. * * All parameters and return value must be destroyed by caller. * * @param inHaystack the string to search for inTarget in. * @param inTarget the string to search for. * @param inSubstitute the string to replace the first occurrence * of the target with. * @param outFound a pre-allocated character which will be filled * with true if the target is found, and filled with false * otherwise. * * @return a newly allocated string with the substitution performed. */ char *replaceOnce( char *inHaystack, char *inTarget, char *inSubstitute, char *outFound ); /** * Replaces the all occurrences of a target string with * a substitute string. * * Note that this function is not self-insertion-safe: * If inSubstitute contains inTarget, this function will * enter an infinite loop. * * All parameters and return value must be destroyed by caller. * * @param inHaystack the string to search for inTarget in. * @param inTarget the string to search for. * @param inSubstitute the string to replace the all occurrences * of the target with. * @param outFound a pre-allocated character which will be filled * with true if the target is found at least once, * and filled with false otherwise. * * @return a newly allocated string with the substitutions performed. */ char *replaceAll( char *inHaystack, char *inTarget, char *inSubstitute, char *outFound ); /** * Replaces the all occurrences of each target string on a list with * a corresponding substitute string. * * Note that this function is not self-insertion-safe: * If inSubstituteVector contains elements from inTargetVector, * this function will enter an infinite loop. * * All parameters and return value must be destroyed by caller. * * @param inHaystack the string to search for targets in. * @param inTargetVector the list of strings to search for. * Vector and contained strings must be destroyed by caller. * @param inSubstituteVector the corresponding list of strings to * replace the all occurrences of the targets with. * Vector and contained strings must be destroyed by caller. * * @return a newly allocated string with the substitutions performed. */ char *replaceTargetListWithSubstituteList( char *inHaystack, SimpleVector *inTargetVector, SimpleVector *inSubstituteVector ); /** * Split a string into tokens using whitespace as separators. * * @param inString the string to tokenize. * Must be destroyed by caller. * * @return a vector of extracted strings. * Vector and strings must be destroyed by caller. */ SimpleVector *tokenizeString( char *inString ); /** * Prints formatted data elements into a newly allocated string buffer. * * Similar to sprintf, except that buffer sizing is automatic (and therefore * safer than manual sizing). * * @param inFormatString the format string to print from. * @param variable argument list data values to fill in the format string * with (uses same conventions as printf). * * @return a newly allocated buffer containing the \0-terminated printed * string. * Must be destroyed by caller. */ char *autoSprintf( const char* inFormatString, ... ); #endif gravitation-3+dfsg1.orig/minorGems/util/CircularBuffer.h0000644000175000017500000000614110762704570022136 0ustar pabspabs/* * Modification History * * 2001-Janary-11 Jason Rohrer * Created. * * 2001-Janary-12 Jason Rohrer * Added canRead and canWrite functions. * * 2001-February-24 Jason Rohrer * Fixed incorrect delete usage. */ #include "minorGems/common.h" #ifndef CIRCULAR_BUFFER_INCLUDED #define CIRCULAR_BUFFER_INCLUDED #include "minorGems/system/Semaphore.h" /** * Thread-safe circular buffer. * * @author Jason Rohrer */ class CircularBuffer { public: /** * Constructs a CircularBuffer. * * @param inSize the number of objects in this buffer. */ CircularBuffer( unsigned long inSize ); ~CircularBuffer(); /** * Writes an object into the next free position in the buffer. * Blocks if no free positions are available. * * @param inObject the object pointer to write. */ void writeObject( void *inObject ); /** * Reads the next available object from the buffer. * Blocks if now objects are available. * * @return the object pointer read. */ void *readNextObject(); /** * Returns true if an object can be read from this buffer * without blocking. */ char canRead(); /** * Returns true if an object can be written to this buffer * without blocking. */ char canWrite(); private: unsigned long mBufferSize; void **mObjects; unsigned long mReadIndex, mWriteIndex; // initialized to 0 Semaphore *mReadSemaphore; // initialized to mBufferSize; Semaphore *mWriteSemaphore; MutexLock *mLock; }; inline CircularBuffer::CircularBuffer( unsigned long inSize ) : mBufferSize( inSize ), mObjects( new void*[inSize] ), mReadIndex( 0 ), mWriteIndex( 0 ), mReadSemaphore( new Semaphore( 0 ) ), mWriteSemaphore( new Semaphore( inSize ) ), mLock( new MutexLock() ) { } inline CircularBuffer::~CircularBuffer() { delete [] mObjects; delete mReadSemaphore; delete mWriteSemaphore; delete mLock; } // note that in this implementation, no mutex is needed, since // reader and writer are never accessing the same data members // simultaneously inline void CircularBuffer::writeObject( void *inObject ) { // wait to for a space to write into mWriteSemaphore->wait(); // write, and increment our write location mObjects[ mWriteIndex ] = inObject; mWriteIndex++; mWriteIndex = mWriteIndex % mBufferSize; // signal the reader that an new object is ready mReadSemaphore->signal(); } inline void *CircularBuffer::readNextObject() { void *returnObject; // wait for an object to read mReadSemaphore->wait(); // read the object, and increment our read location returnObject = mObjects[ mReadIndex ]; mReadIndex++; mReadIndex = mReadIndex % mBufferSize; // signal the writer mWriteSemaphore->signal(); // now return the object that we retrieved from the buffer return returnObject; } inline char CircularBuffer::canRead() { // can read if the read semaphore won't block return ! mReadSemaphore->willBlock(); } inline char CircularBuffer::canWrite() { // can write if the write semaphore won't block return ! mWriteSemaphore->willBlock(); } #endif gravitation-3+dfsg1.orig/minorGems/util/printUtils.cpp0000644000175000017500000000107410762704570021750 0ustar pabspabs/* * Modification History * * 2002-April-8 Jason Rohrer * Created. * * 2002-April-11 Jason Rohrer * Added a missing return value. */ #include "printUtils.h" #include "minorGems/system/MutexLock.h" #include // for variable argument lists #include MutexLock threadPrintFLock; int threadPrintF( const char* inFormatString, ... ) { threadPrintFLock.lock(); va_list argList; va_start( argList, inFormatString ); int returnVal = vprintf( inFormatString, argList ); threadPrintFLock.unlock(); return returnVal; } gravitation-3+dfsg1.orig/minorGems/util/StringBufferOutputStream.cpp0000644000175000017500000000227410762704570024573 0ustar pabspabs/* * Modification History * * 2002-August-1 Jason Rohrer * Created. * * 2004-May-9 Jason Rohrer * Added function for getting data as a byte array. */ #include "minorGems/util/StringBufferOutputStream.h" StringBufferOutputStream::StringBufferOutputStream() : mCharacterVector( new SimpleVector() ) { } StringBufferOutputStream::~StringBufferOutputStream() { delete mCharacterVector; } char *StringBufferOutputStream::getString() { int numChars = mCharacterVector->size(); char *returnArray = new char[ numChars + 1 ]; for( int i=0; igetElement( i ) ) ); } returnArray[ numChars ] = '\0'; return returnArray; } unsigned char *StringBufferOutputStream::getBytes( int *outNumBytes ) { *outNumBytes = mCharacterVector->size(); return mCharacterVector->getElementArray(); } long StringBufferOutputStream::write( unsigned char *inBuffer, long inNumBytes ) { for( int i=0; ipush_back( inBuffer[ i ] ); } return inNumBytes; } gravitation-3+dfsg1.orig/minorGems/util/SettingsManager.cpp0000644000175000017500000001336510762704570022674 0ustar pabspabs/* * Modification History * * 2002-September-16 Jason Rohrer * Created. * Fixed a memory leak. * * 2002-September-25 Jason Rohrer * Added a setSetting function that takes a string value. * * 2002-September-26 Jason Rohrer * Added functions for integer values. * * 2003-January-11 Jason Rohrer * Added default values for float and int settings. * * 2003-August-24 Jason Rohrer * Fixed to remove 499-character limit for a setting value. */ #include "SettingsManager.h" #include "minorGems/util/stringUtils.h" #include "minorGems/io/file/File.h" #include "minorGems/io/file/Path.h" // will be destroyed automatically at program termination SettingsManagerStaticMembers SettingsManager::mStaticMembers; void SettingsManager::setDirectoryName( char *inName ) { delete [] mStaticMembers.mDirectoryName; mStaticMembers.mDirectoryName = stringDuplicate( inName ); } char *SettingsManager::getDirectoryName() { return stringDuplicate( mStaticMembers.mDirectoryName ); } SimpleVector *SettingsManager::getSetting( char *inSettingName ) { char *fileName = getSettingsFileName( inSettingName ); File *settingsFile = new File( NULL, fileName ); delete [] fileName; char *fileContents = settingsFile->readFileContents(); delete settingsFile; if( fileContents == NULL ) { // return empty vector return new SimpleVector(); } // else tokenize the file contents SimpleVector *returnVector = tokenizeString( fileContents ); delete [] fileContents; return returnVector; } char *SettingsManager::getStringSetting( char *inSettingName ) { char *value = NULL; SimpleVector *settingsVector = getSetting( inSettingName ); int numStrings = settingsVector->size(); if( numStrings >= 1 ) { char *firstString = *( settingsVector->getElement( 0 ) ); value = stringDuplicate( firstString ); } for( int i=0; igetElement( i ) ); delete [] nextString; } delete settingsVector; return value; } float SettingsManager::getFloatSetting( char *inSettingName, char *outValueFound ) { char valueFound = false; float value = 0; char *stringValue = getStringSetting( inSettingName ); if( stringValue != NULL ) { int numRead = sscanf( stringValue, "%f", &value ); if( numRead == 1 ) { valueFound = true; } delete [] stringValue; } *outValueFound = valueFound; return value; } int SettingsManager::getIntSetting( char *inSettingName, char *outValueFound ) { char valueFound = false; int value = 0; char *stringValue = getStringSetting( inSettingName ); if( stringValue != NULL ) { int numRead = sscanf( stringValue, "%d", &value ); if( numRead == 1 ) { valueFound = true; } delete [] stringValue; } *outValueFound = valueFound; return value; } void SettingsManager::setSetting( char *inSettingName, SimpleVector *inSettingVector ) { FILE *file = getSettingsFile( inSettingName, "w" ); if( file != NULL ) { int numSettings = inSettingVector->size(); for( int i=0; igetElement( i ) ); fprintf( file, "%s\n", setting ); } fclose( file ); } // else do nothing } void SettingsManager::setSetting( char *inSettingName, float inSettingValue ) { char *valueString = new char[ 15 ]; sprintf( valueString, "%f", inSettingValue ); setSetting( inSettingName, valueString ); delete [] valueString; } void SettingsManager::setSetting( char *inSettingName, int inSettingValue ) { char *valueString = new char[ 15 ]; sprintf( valueString, "%d", inSettingValue ); setSetting( inSettingName, valueString ); delete [] valueString; } void SettingsManager::setSetting( char *inSettingName, char *inSettingValue ) { SimpleVector *settingsVector = new SimpleVector( 1 ); settingsVector->push_back( inSettingValue ); setSetting( inSettingName, settingsVector ); delete settingsVector; } FILE *SettingsManager::getSettingsFile( char *inSettingName, const char *inReadWriteFlags ) { char *fullFileName = getSettingsFileName( inSettingName ); FILE *file = fopen( fullFileName, inReadWriteFlags ); delete [] fullFileName; return file; } char *SettingsManager::getSettingsFileName( char *inSettingName ) { char **pathSteps = new char*[1]; pathSteps[0] = mStaticMembers.mDirectoryName; char *fileName = new char[ strlen( inSettingName ) + 10 ]; sprintf( fileName, "%s.ini", inSettingName ); File *settingsFile = new File( new Path( pathSteps, 1, false ), fileName ); delete [] fileName; // pathSteps copied internally by Path constructor delete [] pathSteps; char *fullFileName = settingsFile->getFullFileName(); delete settingsFile; return fullFileName; } SettingsManagerStaticMembers::SettingsManagerStaticMembers() : mDirectoryName( stringDuplicate( "settings" ) ) { } SettingsManagerStaticMembers::~SettingsManagerStaticMembers() { delete [] mDirectoryName; } gravitation-3+dfsg1.orig/minorGems/util/TranslationManager.cpp0000644000175000017500000002126010762704570023363 0ustar pabspabs/* * Modification History * * 2004-October-7 Jason Rohrer * Created. * * 2006-February-19 Jason Rohrer * Fixed an inconsistency in memory management. */ #include "TranslationManager.h" #include #include "minorGems/io/file/File.h" // will be destroyed automatically at program termination TranslationManagerStaticMembers TranslationManager::mStaticMembers; void TranslationManager::setDirectoryName( char *inName ) { mStaticMembers.setDirectoryAndLanguage( inName, mStaticMembers.mLanguageName ); } char *TranslationManager::getDirectoryName() { return stringDuplicate( mStaticMembers.mDirectoryName ); } char **TranslationManager::getAvailableLanguages( int *outNumLanguages ) { File *languageDirectory = new File( NULL, mStaticMembers.mDirectoryName ); if( languageDirectory->exists() && languageDirectory->isDirectory() ) { int numChildFiles; File **childFiles = languageDirectory->getChildFiles( &numChildFiles ); if( childFiles != NULL ) { SimpleVector *languageNames = new SimpleVector(); for( int i=0; igetFileName(); char *extensionPointer = strstr( name, ".txt" ); if( extensionPointer != NULL ) { // terminate string, cutting off extension extensionPointer[0] = '\0'; languageNames->push_back( stringDuplicate( name ) ); } delete [] name; delete childFiles[i]; } delete [] childFiles; char **returnArray = languageNames->getElementArray(); *outNumLanguages = languageNames->size(); delete languageNames; delete languageDirectory; return returnArray; } } delete languageDirectory; // default, if we didn't return above *outNumLanguages = 0; return new char*[0]; } void TranslationManager::setLanguage( char *inLanguageName ) { mStaticMembers.setDirectoryAndLanguage( mStaticMembers.mDirectoryName, inLanguageName ); } const char *TranslationManager::translate( char *inTranslationKey ) { char *translatedString = NULL; SimpleVector *keys = mStaticMembers.mTranslationKeys; SimpleVector *naturalLanguageStrings = mStaticMembers.mNaturalLanguageStrings; if( keys != NULL ) { int numKeys = keys->size(); for( int i=0; igetElement( i ) ) ) == 0 ) { // keys match translatedString = *( naturalLanguageStrings->getElement( i ) ); } } } if( translatedString == NULL ) { // no translation exists // the translation for this key is the key itself // add it to our translation table char *key = stringDuplicate( inTranslationKey ); char *value = stringDuplicate( inTranslationKey ); keys->push_back( key ); naturalLanguageStrings->push_back( value ); // thus, we return a value from our table, just as if a translation // had existed for this string translatedString = value; } return translatedString; } TranslationManagerStaticMembers::TranslationManagerStaticMembers() : mDirectoryName( NULL ), mLanguageName( NULL ), mTranslationKeys( NULL ), mNaturalLanguageStrings( NULL ) { // default setDirectoryAndLanguage( "languages", "English" ); } TranslationManagerStaticMembers::~TranslationManagerStaticMembers() { if( mDirectoryName != NULL ) { delete [] mDirectoryName; } if( mLanguageName != NULL ) { delete [] mLanguageName; } if( mTranslationKeys != NULL ) { int numKeys = mTranslationKeys->size(); for( int i=0; igetElement( i ) ); } delete mTranslationKeys; } if( mNaturalLanguageStrings != NULL ) { int numKeys = mNaturalLanguageStrings->size(); for( int i=0; igetElement( i ) ); } delete mNaturalLanguageStrings; } } void TranslationManagerStaticMembers::setDirectoryAndLanguage( char *inDirectoryName, char *inLanguageName ) { // save temp copies first to allow caller to pass our own members in to us char *tempDirectoryName = stringDuplicate( inDirectoryName ); char *tempLanguageName = stringDuplicate( inLanguageName ); if( mDirectoryName != NULL ) { delete [] mDirectoryName; } if( mLanguageName != NULL ) { delete [] mLanguageName; } mDirectoryName = tempDirectoryName; mLanguageName = tempLanguageName; // clear the old translation table if( mTranslationKeys != NULL ) { int numKeys = mTranslationKeys->size(); for( int i=0; igetElement( i ) ); } delete mTranslationKeys; } if( mNaturalLanguageStrings != NULL ) { int numKeys = mNaturalLanguageStrings->size(); for( int i=0; igetElement( i ) ); } delete mNaturalLanguageStrings; } // now read in the translation table mTranslationKeys = new SimpleVector(); mNaturalLanguageStrings = new SimpleVector(); File *directoryFile = new File( NULL, mDirectoryName ); if( directoryFile->exists() && directoryFile->isDirectory() ) { char *languageFileName = autoSprintf( "%s.txt", mLanguageName ); File *languageFile = directoryFile->getChildFile( languageFileName ); delete [] languageFileName; if( languageFile != NULL ) { char *languageFileFullPath = languageFile->getFullFileName(); FILE *languageFILE = fopen( languageFileFullPath, "r" ); if( languageFILE != NULL ) { char readError = false; while( ! readError ) { char *key = new char[ 100 ]; int numRead = fscanf( languageFILE, "%99s", key ); if( numRead == 1 ) { // skip the first " int readChar = ' '; while( readChar != '"' && readChar != EOF ) { readChar = fgetc( languageFILE ); } if( readChar != EOF ) { char *naturalLanguageString = new char[1000]; // scan a string of up to 999 characters, stopping // at the first " character numRead = fscanf( languageFILE, "%999[^\"]", naturalLanguageString ); if( numRead == 1 ) { // trim the key and string and save them mTranslationKeys->push_back( stringDuplicate( key ) ); mNaturalLanguageStrings->push_back( stringDuplicate( naturalLanguageString ) ); } else { readError = true; } delete [] naturalLanguageString; // skip the trailing " readChar = ' '; while( readChar != '"' && readChar != EOF ) { readChar = fgetc( languageFILE ); } } else { readError = true; } } else { readError = true; } delete [] key; } fclose( languageFILE ); } delete [] languageFileFullPath; delete languageFile; } } delete directoryFile; } gravitation-3+dfsg1.orig/minorGems/util/SettingsManager.h0000644000175000017500000001456610762704570022345 0ustar pabspabs/* * Modification History * * 2002-September-16 Jason Rohrer * Created. * Fixed a memory leak. * * 2002-September-25 Jason Rohrer * Added a setSetting function that takes a string value. * * 2002-September-26 Jason Rohrer * Added functions for integer values. * * 2003-August-24 Jason Rohrer * Fixed to remove 499-character limit for a setting value. */ #include "minorGems/common.h" #ifndef SETTINGS_MANAGER_INCLUDED #define SETTINGS_MANAGER_INCLUDED #include "minorGems/util/SimpleVector.h" #include "minorGems/system/MutexLock.h" #include // utility class for dealing with static member dealocation class SettingsManagerStaticMembers; /** * Class that manages program settings. * * @author Jason Rohrer */ class SettingsManager { public: /** * Sets the directory name where settings are stored. * * @param inName the name of the directory (relative to the * program's working directory). * Must be destroyed by caller. */ static void setDirectoryName( char *inName ); /** * Gets the directory name where settings are stored. * * @return the name of the directory (relative to the * program's working directory). * Must be destroyed by caller if non-const. */ static char *getDirectoryName(); /** * Gets a setting. * * @param inSettingName the name of the setting to get. * Must be destroyed by caller if non-const. * * @return a vector of strings representing the setting value. * The vector and the strings it contains must be destroyed * by the caller. */ static SimpleVector *getSetting( char *inSettingName ); /** * Gets a string setting. * * @param inSettingName the name of the setting to get. * Must be destroyed by caller if non-const. * * @return the setting value string, or NULL if no setting * value can be read. * Must be destroyed by caller if non-NULL. */ static char *getStringSetting( char *inSettingName ); /** * Gets a float setting. * * @param inSettingName the name of the setting to get. * Must be destroyed by caller if non-const. * @param outValueFound pointer to where flag should be returned * indicating whether or not the value was found. * Set to true if the value was found, false otherwise. * * @return the setting value. */ static float getFloatSetting( char *inSettingName, char *outValueFound ); /** * Gets an integer setting. * * @param inSettingName the name of the setting to get. * Must be destroyed by caller if non-const. * @param outValueFound pointer to where flag should be returned * indicating whether or not the value was found. * Set to true if the value was found, false otherwise. * * @return the setting value. */ static int getIntSetting( char *inSettingName, char *outValueFound ); /** * Sets a setting. * * @param inSettingName the name of the setting to set. * Must be destroyed by caller if non-const. * @param inSettingVector a vector of strings representing the * setting value. * The vector and the strings it contains must be destroyed * by the caller. */ static void setSetting( char *inSettingName, SimpleVector *inSettingVector ); /** * Sets a setting to a single float value. * * @param inSettingName the name of the setting to set. * Must be destroyed by caller if non-const. * @param inSettingValue the value to set. */ static void setSetting( char *inSettingName, float inSettingValue ); /** * Sets a setting to a single int value. * * @param inSettingName the name of the setting to set. * Must be destroyed by caller if non-const. * @param inSettingValue the value to set. */ static void setSetting( char *inSettingName, int inSettingValue ); /** * Sets a setting to a single string value. * * @param inSettingName the name of the setting to set. * Must be destroyed by caller if non-const. * @param inSettingValue the value to set. * Must be destroyed by caller. */ static void setSetting( char *inSettingName, char *inSettingValue ); protected: static SettingsManagerStaticMembers mStaticMembers; /** * Gets the file for a setting name. * * @param inSettingName the name of the setting. * Must be destroyed by caller if non-const. * @param inReadWriteFlags the flags to pass into the * fopen call. For example, "r" or "w". * * @return the file descriptor, or NULL if the open failed. * Must be fclose()'d by caller if non-NULL. */ static FILE *getSettingsFile( char *inSettingName, const char *inReadWriteFlags ); /** * Gets the file name for a setting. * * @param inSettingName the name of the setting. * Must be destroyed by caller if non-const. * * @return the name of the settings file. * Must be destroyed by caller. */ static char *getSettingsFileName( char *inSettingName ); }; /** * Container for static members to allow for their proper destruction * on program termination. * * @author Jason Rohrer */ class SettingsManagerStaticMembers { public: SettingsManagerStaticMembers(); ~SettingsManagerStaticMembers(); char *mDirectoryName; }; #endif gravitation-3+dfsg1.orig/minorGems/util/development/0000755000175000017500000000000010770165273021407 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/util/development/memory/0000755000175000017500000000000010762704570022717 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/util/development/memory/testDebugMemory.cpp0000644000175000017500000000267710762704570026556 0ustar pabspabs/* * Modification History * * 2002-October-17 Jason Rohrer * Created. * * 2002-October-18 Jason Rohrer * Added static initialization counting class for MemoryTrack. * * 2002-October-19 Jason Rohrer * Removed call to debugMemoryPrintLeaksAndStopTracking. * Made test cases more interesting. * Added test cases for deleting NULL pointers. */ #include "minorGems/util/development/memory/debugMemory.h" #include class TestClass { public: TestClass() { mX = new int[5]; } ~TestClass() { delete [] mX; } int *mX; }; int main() { int *x = new int[5]; printf( "array contents before initializing elements:\n" "%d, %d, %d, %d, %d\n\n", x[0], x[1], x[2], x[3], x[4] ); x[0] = 1; x[1] = 2; x[2] = 3; x[3] = 4; x[4] = 5; printf( "array contents before deleting:\n" "%d, %d, %d, %d, %d\n\n", x[0], x[1], x[2], x[3], x[4] ); delete [] x; printf( "array contents after deleting:\n" "%d, %d, %d, %d, %d\n\n", x[0], x[1], x[2], x[3], x[4] ); int *y = new int[4]; y[0] = 1; TestClass *t = new TestClass(); delete t; int *z = new int[7]; delete z; //delete t; int *badPointer = NULL; delete badPointer; int *badPointer2 = NULL; delete [] badPointer2; return 0; } gravitation-3+dfsg1.orig/minorGems/util/development/memory/MemoryTrack.cpp0000644000175000017500000001620510762704570025664 0ustar pabspabs/* * Modification History * * 2002-October-17 Jason Rohrer * Created. * * 2002-October-18 Jason Rohrer * Changed to use custom list instead of SimpleVector because SimpleVector * uses debugMemory. * Added static initialization counting class. * Changed to use struct and malloc for AllocationList to avoid * circular new and delete calls. * * 2002-October-19 Jason Rohrer * Fixed a bug in adding to the alloc list. * Improved printing behavior. * Added support for clearing memory on allocation and deallocation. * Fixed to ignore deallocation of our own static lock. * Fixed bug in allocation count. * Added message for NULL pointer deallocation. * Put locks in place around print statements, which are not atomic on win32. * Changed to use hex notation when printing pointers. * * 2002-October-19 Jason Rohrer * Added ifdef for DEBUG_MEMORY. * * 2002-October-20 Jason Rohrer * Removed file and line arguments from deallocation calls. */ #ifdef DEBUG_MEMORY #include "minorGems/util/development/memory/MemoryTrack.h" #include #include #include int MemoryTrackStaticInitCounter::mCount = 0; MutexLock *MemoryTrack::mLock; AllocationList *MemoryTrack::mListHead; char MemoryTrack::mTracking = false; int MemoryTrack::mTotalAllocationSize = 0; int MemoryTrack::mTotalDeallocationSize = 0; int MemoryTrack::mNumberOfAllocations = 0; void MemoryTrack::addAllocation( void *inPointer, unsigned int inAllocationSize, int inAllocationType, const char *inFileName, int inLineNumber ) { mLock->lock(); if( !mTracking ) { printf( "Tracking off on allocation (0x%x) [%d bytes] %s:%d.\n", (unsigned int)inPointer, inAllocationSize, inFileName, inLineNumber ); mLock->unlock(); return; } // insert after head of list AllocationList *element = (AllocationList *)malloc( sizeof( AllocationList ) ); element->mPrevious = (void *)mListHead; element->mNext = mListHead->mNext; mListHead->mNext = (void *)element; AllocationList *nextElement = (AllocationList *)( element->mNext ); if( nextElement != NULL ) { nextElement->mPrevious = (void *)element; } element->mPointer = inPointer; element->mAllocationSize = inAllocationSize; element->mAllocationType = inAllocationType; element->mFileName = inFileName; element->mLineNumber = inLineNumber; mTotalAllocationSize += inAllocationSize; mNumberOfAllocations ++; // wipe this block of memory clearMemory( inPointer, inAllocationSize ); mLock->unlock(); } int MemoryTrack::addDeallocation( void *inPointer, int inDeallocationType ) { mLock->lock(); if( inPointer == NULL ) { printf( "NULL pointer (0x%x) deallocated\n", (unsigned int)inPointer ); } if( inPointer == (void *)mLock ) { // we're seeing the deallocation of our own static lock as // the system exits // ignore it mLock->unlock(); return 0; } if( !mTracking ) { printf( "Tracking off on deallocation (0x%x)\n", (unsigned int)inPointer ); mLock->unlock(); return 0; } AllocationList *element = (AllocationList *)( mListHead->mNext ); while( element != NULL ) { void *pointer = element->mPointer; if( pointer == inPointer ) { unsigned int allocationSize = element->mAllocationSize; int allocationType = element->mAllocationType; const char *allocFileName = element->mFileName; int allocLineNumber = element->mLineNumber; // remove from list, whether or not types match AllocationList *previousElement = (AllocationList *)( element->mPrevious ); AllocationList *nextElement = (AllocationList *)( element->mNext ); // patch list previousElement->mNext = (void *)( nextElement ); if( nextElement != NULL ) { nextElement->mPrevious = (void *)( previousElement ); } free( element ); mTotalDeallocationSize += allocationSize; if( allocationType == inDeallocationType ) { // found and types match mLock->unlock(); // wipe this block of memory clearMemory( inPointer, allocationSize ); return 0; } else { // allocation types don't match printf( "Attempt to deallocate (0x%x) [%d bytes] with wrong" " delete form\n" " %s:%d (location of original allocation)\n", (unsigned int)inPointer, allocationSize, allocFileName, allocLineNumber ); mLock->unlock(); return 2; } } element = (AllocationList *)( element->mNext ); } // not found (delete of unallocated memory) printf( "Attempt to deallocate (0x%x) unallocated memory\n", (unsigned int)inPointer ); mLock->unlock(); return 1; } void MemoryTrack::printLeaks() { mLock->lock(); printf( "\n\n---- debugMemory report ----\n" ); printf( "Number of Allocations: %d\n", mNumberOfAllocations ); printf( "Total allocations: %d bytes\n", mTotalAllocationSize ); printf( "Total deallocations: %d bytes\n", mTotalDeallocationSize ); int leakEstimate = mTotalAllocationSize - mTotalDeallocationSize; AllocationList *element = (AllocationList *)( mListHead->mNext ); if( element == NULL ) { printf( "No leaks detected.\n" ); } else { printf( "Leaks detected:\n" ); } int leakSum = 0; while( element != NULL ) { printf( "Not deallocated (0x%x) [%d bytes]\n" " %s:%d (location of original allocation)\n", (unsigned int)( element->mPointer ), element->mAllocationSize, element->mFileName, element->mLineNumber ); leakSum += element->mAllocationSize; element = (AllocationList *)( element->mNext ); } if( leakSum != leakEstimate ) { printf( "Warning: Leak sum does not equal leak estimate.\n" ); } printf( "Leaked memory: %d bytes\n", leakSum ); printf( "---- END debugMemory report ----\n\n" ); mLock->unlock(); } void MemoryTrack::clearMemory( void *inPointer, unsigned int inSize ) { unsigned char *charArray = (unsigned char *)inPointer; for( unsigned int i=0; i #include #define SINGLE_ALLOCATION 0 #define ARRAY_ALLOCATION 1 /** * Linked list of memory allocations. * * @author Jason Rohrer */ typedef struct { void *mPrevious; void *mNext; void *mPointer; unsigned int mAllocationSize; int mAllocationType; const char *mFileName; int mLineNumber; } AllocationList; /** * Class that tracks memory allocations and deallocations. * * @author Jason Rohrer */ class MemoryTrack { public: /** * Adds an allocation to this tracker and clears the allocated * memory block. * * @param inPointer a pointer to the allocated memory. * @param inAllocationType the type of allocation, * either SINGLE_ALLOCATION or ARRAY_ALLOCATION. * @param inAllocationSize the size of the allocation in bytes. * @param inFileName the name of the source file in which the * allocation took place. * @param inLineNumber the line number in the source file * on which the allocation took place. */ static void addAllocation( void *inPointer, unsigned int inAllocationSize, int inAllocationType, const char *inFileName, int inLineNumber ); /** * Adds a deallocation to this tracker and clears the block * to be deallocated. * Must be called *before* the memory is deallocated * * @param inPointer a pointer to the memory being deallocated. * @param inDeallocationType the type of deallocation, * either SINGLE_ALLOCATION or ARRAY_ALLOCATION. * @return 0 if the deallocation deallocates * an allocated block of memory, or 1 if it * deallocates a block of memory that is not currently allocated, * and 2 if it is the wrong deallocation type for the specified * block. */ static int addDeallocation( void *inPointer, int inDeallocationType ); /** * Prints a list of all memory leaks (allocations that have never * been deallocated). */ static void printLeaks(); // these are public so initializer can get to them static MutexLock *mLock; // dummy place holder for list head static AllocationList *mListHead; // true if we're tracking static char mTracking; static int mTotalAllocationSize; static int mTotalDeallocationSize; static int mNumberOfAllocations; protected: /** * Clears memory so that reading from it will not produce * anything useful. Good for checking for reads to memory that * has been deallocated. * * @param inPointer pointer to the memory to clear. * @Param inSize the number of bytes to clear starting at inPointer. */ static void clearMemory( void *inPointer, unsigned int inSize ); }; /** * Class that initializes MemoryTrack's static members. * * *All* files that use MemoryTrack will instantiate a static * instance of this class (see static instance below). * * This class counts how many static instantiations have happened so * far, making sure to init/destroy MemoryTrack's static members only once. * * Adapted from: * http://www.hlrs.de/organization/par/services/tools/docu/kcc/ * tutorials/static_initialization.html */ class MemoryTrackStaticInitCounter { public: MemoryTrackStaticInitCounter() { if( mCount == 0 ) { // allocate static members MemoryTrack::mLock = new MutexLock(); MemoryTrack::mListHead = (AllocationList *) malloc( sizeof( AllocationList ) ); MemoryTrack::mListHead->mPrevious = NULL; MemoryTrack::mListHead->mNext = NULL; MemoryTrack::mTotalAllocationSize = 0; MemoryTrack::mTotalDeallocationSize = 0; MemoryTrack::mNumberOfAllocations = 0; MemoryTrack::mTracking = true; } mCount++; } ~MemoryTrackStaticInitCounter() { mCount--; if( mCount == 0 ) { // print leaks... we should only get here after // all static members of classes that use MemoryTrack // have been destroyed. MemoryTrack::printLeaks(); MemoryTrack::mTracking = false; // deallocate static members free( MemoryTrack::mListHead ); delete MemoryTrack::mLock; } } private: // only allocate/deallocate when mCount == 0 static int mCount; }; // This will be included in *every* file that includes MemoryTrack.h static MemoryTrackStaticInitCounter memoryTrackInitializer; #endif gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/0000755000175000017500000000000010762704570023464 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/LeakTracer.cc0000644000175000017500000003331410762704570026014 0ustar pabspabs/* * Modification History * * 2002-March-31 Jason Rohrer * Added support for strdup. * Fixed bug in strdup. * * 2003-October-3 Jason Rohrer * Added printout of leak contents in report. * * 2004-January-16 Jason Rohrer * Switched to use minorGems platform-independed mutexes. * Changed to use simpler fopen call to open report. */ /* * Homepage: * * Authors: * Erwin S. Andreasen * Henner Zeller * * This program is Public Domain */ #ifdef THREAD_SAVE #define _THREAD_SAVE //#include #include "minorGems/system/MutexLock.h" #endif #include #include #include #include #include #include #include #include #include #include /* * underlying allocation, de-allocation used within * this tool */ #define LT_MALLOC malloc #define LT_FREE free #define LT_REALLOC realloc /* * prime number for the address lookup hash table. * if you have _really_ many memory allocations, use a * higher value, like 343051 for instance. */ #define SOME_PRIME 35323 #define ADDR_HASH(addr) ((unsigned long) addr % SOME_PRIME) /** * Filedescriptor to write to. This should not be a low number, * because these often have special meanings (stdin, out, err) * and may be closed by the program (daemons) * So choose an arbitrary higher FileDescriptor .. e.g. 42 */ #define FILEDESC 42 /** * allocate a bit more memory in order to check if there is a memory * overwrite. Either 0 or more than sizeof(unsigned int). Note, you can * only detect memory over_write_, not _reading_ beyond the boundaries. Better * use electric fence for these kind of bugs * */ typedef unsigned long magic_t; #define MAGIC ((magic_t) 0xAABBCCDDLu) /** * this may be more than sizeof(magic_t); if you want more, then * sepecify it like #define SAVESIZE (sizeof(magic_t) + 12) */ #define SAVESIZE (sizeof(magic_t) + 0) /** * on 'new', initialize the memory with this value. * if not defined - uninitialized. This is very helpful because * it detects if you initialize your classes correctly .. if not, * this helps you faster to get the segmentation fault you're * implicitly asking for :-). * * Set this to some value which is likely to produce a * segmentation fault on your platform. */ #define SAVEVALUE 0xAA /** * on 'delete', clean memory with this value. * if not defined - no memory clean. * * Set this to some value which is likely to produce a * segmentation fault on your platform. */ #define MEMCLEAN 0xEE /** * Initial Number of memory allocations in our list. * Doubles for each re-allocation. */ #define INITIALSIZE 32768 static class LeakTracer { struct Leak { const void *addr; size_t size; const void *allocAddr; bool type; int nextBucket; }; int newCount; // how many memory blocks do we have int leaksCount; // amount of entries in the leaks array int firstFreeSpot; // Where is the first free spot in the leaks array? int currentAllocated; // currentAllocatedMemory int maxAllocated; // maximum Allocated unsigned long totalAllocations; // total number of allocations. stats. unsigned int abortOn; // resons to abort program (see abortReason_t) /** * Have we been initialized yet? We depend on this being * false before constructor has been called! */ bool initialized; bool destroyed; // Has our destructor been called? FILE *report; // filedescriptor to write to /** * pre-allocated array of leak info structs. */ Leak *leaks; /** * fast hash to lookup the spot where an allocation is * stored in case of an delete. map */ int *leakHash; // fast lookup #ifdef THREAD_SAVE MutexLock mutex; #endif enum abortReason_t { OVERWRITE_MEMORY = 0x01, DELETE_NONEXISTENT = 0x02, NEW_DELETE_MISMATCH = 0x04 }; public: LeakTracer() { initialize(); } void initialize() { // Unfortunately we might be called before our constructor has actualy fired if (initialized) return; // fprintf(stderr, "LeakTracer::initialize()\n"); initialized = true; newCount = 0; leaksCount = 0; firstFreeSpot = 1; // index '0' is special currentAllocated = 0; maxAllocated = 0; totalAllocations = 0; abortOn = OVERWRITE_MEMORY; // only _severe_ reason report = 0; leaks = 0; leakHash = 0; char uniqFilename[256]; const char *filename = getenv("LEAKTRACE_FILE") ? : "leak.out"; struct stat dummy; if (stat(filename, &dummy) == 0) { sprintf(uniqFilename, "%s.%d", filename, getpid()); fprintf(stderr, "LeakTracer: file exists; using %s instead\n", uniqFilename); } else { sprintf(uniqFilename, "%s", filename); } // not sure why this "open" code is here // (it doesn't open the file properly in MinGW on win32) /* int reportfd = open(uniqFilename, O_WRONLY|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE); if (reportfd < 0) { fprintf(stderr, "LeakTracer: cannot open %s: %m\n", filename); report = stderr; } else { int dupfd = dup2(reportfd, FILEDESC); close(reportfd); report = fdopen(dupfd, "w"); if (report == NULL) { report = stderr; } } */ // simpler version using only fopen report = fopen( uniqFilename, "w" ); if( report == NULL ) { fprintf( stderr, "LeakTracer: cannot open %s\n", uniqFilename ); report = stderr; } time_t t = time(NULL); fprintf (report, "# starting %s", ctime(&t)); leakHash = (int*) LT_MALLOC(SOME_PRIME * sizeof(int)); memset ((void*) leakHash, 0x00, SOME_PRIME * sizeof(int)); #ifdef MAGIC fprintf (report, "# memory overrun protection of %d Bytes " "with magic 0x%4lX\n", SAVESIZE, MAGIC); #endif #ifdef SAVEVALUE fprintf (report, "# initializing new memory with 0x%2X\n", SAVEVALUE); #endif #ifdef MEMCLEAN fprintf (report, "# sweeping deleted memory with 0x%2X\n", MEMCLEAN); #endif if (getenv("LT_ABORTREASON")) { abortOn = atoi(getenv("LT_ABORTREASON")); } #define PRINTREASON(x) if (abortOn & x) fprintf(report, "%s ", #x); fprintf (report, "# aborts on "); PRINTREASON( OVERWRITE_MEMORY ); PRINTREASON( DELETE_NONEXISTENT ); PRINTREASON( NEW_DELETE_MISMATCH ); fprintf (report, "\n"); #undef PRINTREASON #ifdef THREAD_SAVE fprintf (report, "# thread save\n"); /* * create default, non-recursive ('fast') mutex * to lock our datastructure where we keep track of * the user's new/deletes */ /*if (pthread_mutex_init(&mutex, NULL) < 0) { fprintf(report, "# couldn't init mutex ..\n"); fclose(report); _exit(1); }*/ #else fprintf(report, "# not thread save; if you use threads, recompile with -DTHREAD_SAVE\n"); #endif fflush(report); } /* * the workhorses: */ void *registerAlloc(size_t size, bool type); void registerFree (void *p, bool type); /** * write a hexdump of the given area. */ void hexdump(const unsigned char* area, int size); /** * Terminate current running progam. */ void progAbort(abortReason_t reason) { if (abortOn & reason) { fprintf(report, "# abort; DUMP of current state\n"); writeLeakReport(); fclose(report); abort(); } else fflush(report); } /** * write a Report over leaks, e.g. still pending deletes */ void writeLeakReport(); ~LeakTracer() { // fprintf(stderr, "LeakTracer::destroy()\n"); time_t t = time(NULL); fprintf (report, "# finished %s", ctime(&t)); writeLeakReport(); fclose(report); free(leaks); #ifdef THREAD_SAVE //pthread_mutex_destroy(&mutex); #endif destroyed = true; } } leakTracer; void* LeakTracer::registerAlloc (size_t size, bool type) { initialize(); // fprintf(stderr, "LeakTracer::registerAlloc()\n"); if (destroyed) { fprintf(stderr, "Oops, registerAlloc called after destruction of LeakTracer (size=%d)\n", size); return LT_MALLOC(size); } void *p = LT_MALLOC(size + SAVESIZE); // Need to call the new-handler if (!p) { fprintf(report, "LeakTracer malloc %m\n"); _exit (1); } #ifdef SAVEVALUE /* initialize with some defined pattern */ memset(p, SAVEVALUE, size + SAVESIZE); #endif #ifdef MAGIC /* * the magic value is a special pattern which does not need * to be uniform. */ if (SAVESIZE >= sizeof(magic_t)) { magic_t *mag; mag = (magic_t*)((char*)p + size); *mag = MAGIC; } #endif #ifdef THREAD_SAVE //pthread_mutex_lock(&mutex); mutex.lock(); #endif ++newCount; ++totalAllocations; currentAllocated += size; if (currentAllocated > maxAllocated) maxAllocated = currentAllocated; for (;;) { for (int i = firstFreeSpot; i < leaksCount; i++) if (leaks[i].addr == NULL) { leaks[i].addr = p; leaks[i].size = size; leaks[i].type = type; leaks[i].allocAddr=__builtin_return_address(1); firstFreeSpot = i+1; // allow to lookup our index fast. int *hashPos = &leakHash[ ADDR_HASH(p) ]; leaks[i].nextBucket = *hashPos; *hashPos = i; #ifdef THREAD_SAVE //pthread_mutex_unlock(&mutex); mutex.unlock(); #endif return p; } // Allocate a bigger array // Note that leaksCount starts out at 0. int new_leaksCount = (leaksCount == 0) ? INITIALSIZE : leaksCount * 2; leaks = (Leak*)LT_REALLOC(leaks, sizeof(Leak) * new_leaksCount); if (!leaks) { fprintf(report, "# LeakTracer realloc failed: %m\n"); _exit(1); } else { fprintf(report, "# internal buffer now %d\n", new_leaksCount); fflush(report); } memset(leaks+leaksCount, 0x00, sizeof(Leak) * (new_leaksCount-leaksCount)); leaksCount = new_leaksCount; } } void LeakTracer::hexdump(const unsigned char* area, int size) { fprintf(report, "# "); for (int j=0; j < size ; ++j) { fprintf (report, "%02x ", *(area+j)); if (j % 16 == 15) { fprintf(report, " "); for (int k=-15; k < 0 ; k++) { char c = (char) *(area + j + k); fprintf (report, "%c", isprint(c) ? c : '.'); } fprintf(report, "\n# "); } } fprintf(report, "\n"); } void LeakTracer::registerFree (void *p, bool type) { initialize(); if (p == NULL) return; if (destroyed) { fprintf(stderr, "Oops, allocation destruction of LeakTracer (p=%p)\n", p); return; } #ifdef THREAD_SAVE //pthread_mutex_lock(&mutex); mutex.lock(); #endif int *lastPointer = &leakHash[ ADDR_HASH(p) ]; int i = *lastPointer; while (i != 0 && leaks[i].addr != p) { lastPointer = &leaks[i].nextBucket; i = *lastPointer; } if (leaks[i].addr == p) { *lastPointer = leaks[i].nextBucket; // detach. newCount--; leaks[i].addr = NULL; currentAllocated -= leaks[i].size; if (i < firstFreeSpot) firstFreeSpot = i; if (leaks[i].type != type) { fprintf(report, "S %10p %10p # new%s but delete%s " "; size %d\n", leaks[i].allocAddr, __builtin_return_address(1), ((!type) ? "[]" : " normal"), ((type) ? "[]" : " normal"), leaks[i].size); progAbort( NEW_DELETE_MISMATCH ); } #ifdef MAGIC if ((SAVESIZE >= sizeof(magic_t)) && *((magic_t*)((char*)p + leaks[i].size)) != MAGIC) { fprintf(report, "O %10p %10p " "# memory overwritten beyond allocated" " %d bytes\n", leaks[i].allocAddr, __builtin_return_address(1), leaks[i].size); fprintf(report, "# %d byte beyond area:\n", SAVESIZE); hexdump((unsigned char*)p+leaks[i].size, SAVESIZE); progAbort( OVERWRITE_MEMORY ); } #endif #ifdef THREAD_SAVE # ifdef MEMCLEAN int allocationSize = leaks[i].size; # endif //pthread_mutex_unlock(&mutex); mutex.unlock(); #else #define allocationSize leaks[i].size #endif #ifdef MEMCLEAN // set it to some garbage value. memset((unsigned char*)p, MEMCLEAN, allocationSize + SAVESIZE); #endif LT_FREE(p); return; } #ifdef THREAD_SAVE //pthread_mutex_unlock(&mutex); mutex.unlock(); #endif fprintf(report, "D %10p # delete non alloc or twice pointer %10p\n", __builtin_return_address(1), p); progAbort( DELETE_NONEXISTENT ); } void LeakTracer::writeLeakReport() { initialize(); if (newCount > 0) { fprintf(report, "# LeakReport\n"); fprintf(report, "# %10s | %9s # Pointer Addr\n", "from new @", "size"); } for (int i = 0; i < leaksCount; i++) if (leaks[i].addr != NULL) { // This ought to be 64-bit safe? char *memContents = (char *)LT_MALLOC( leaks[i].size + 1 ); memcpy( (void *)memContents, (void *)( leaks[i].addr ), leaks[i].size ); memContents[ leaks[i].size ] = '\0'; fprintf(report, "L %10p %9ld # %p %s\n", leaks[i].allocAddr, (long) leaks[i].size, leaks[i].addr, memContents ); LT_FREE( memContents ); } fprintf(report, "# total allocation requests: %6ld ; max. mem used" " %d kBytes\n", totalAllocations, maxAllocated / 1024); fprintf(report, "# leak %6d Bytes\t:-%c\n", currentAllocated, (currentAllocated == 0) ? ')' : '('); if (currentAllocated > 50 * 1024) { fprintf(report, "# .. that is %d kByte!! A lot ..\n", currentAllocated / 1024); } } /** -- The actual new/delete operators -- **/ void* operator new(size_t size) { return leakTracer.registerAlloc(size,false); } void* operator new[] (size_t size) { return leakTracer.registerAlloc(size,true); } void operator delete (void *p) { leakTracer.registerFree(p,false); } void operator delete[] (void *p) { leakTracer.registerFree(p,true); } // added by Jason Rohrer char *strdup( const char *inString ) { char *outString = (char*)leakTracer.registerAlloc( strlen( inString ) + 1, true ); strcpy( outString, inString ); return outString; } /* Emacs: * Local variables: * c-basic-offset: 8 * End: * vi:set tabstop=8 shiftwidth=8 nowrap: */ gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/Makefile0000644000175000017500000000262510762704570025131 0ustar pabspabs# # Modification History # # 2004-January-16 Jason Rohrer # Switched to use minorGems platform-independed mutexes. # CC = g++ # Source files SRC := LeakTracer.cc ROOT_PATH = ../../../.. # Switch comment to select a platform # PLATFORM_MUTEX = $(ROOT_PATH)/minorGems/system/win32/MutexLockWin32.cpp PLATFORM_MUTEX = $(ROOT_PATH)/minorGems/system/linux/MutexLockLinux.cpp -pthread # Comment both of these out to disable thread safetly C_THREAD=-DTHREAD_SAVE -D_REENTRANT -D_THREAD_SAFE O_THREAD = $(PLATFORM_MUTEX) # Common flags C_FLAGS = -g -pipe -Wall -W -I$(ROOT_PATH) $(C_THREAD) O_FLAGS = $(C_FLAGS) $(O_THREAD) # Object files OBJ_DIR = . OBJ := $(patsubst %.cc,$(OBJ_DIR)/%.o,$(SRC)) SHOBJ := $(patsubst %.o,$(OBJ_DIR)/%.so,$(OBJ)) .PHONY: all clean tidy distrib test all: $(OBJ) $(SHOBJ) clean: tidy rm -f $(OBJ) leak.out tidy: rm -f *~ *orig *bak *rej tags: $(SRC) $(INCL) ctags $(SRC) $(INCL) distrib: clean all README.html (cd .. && tar cvfz /root/drylock/LeakTracer/LeakTracer.tar.gz --exclude LeakTracer/CVS --exclude LeakTracer/old --exclude LeakTracer/test LeakTracer/) $(OBJ_DIR)/%.o: %.cc $(CC) -fPIC -c $(C_FLAGS) $< -o $@ $(OBJ_DIR)/%.so : $(OBJ_DIR)/%.o $(CC) $(O_FLAGS) -shared -o $@ $< README.html: README /root/ed/mcl/util/htmlize.pl README test: $(CC) $(C_FLAGS) test.cc -o test ./test ./LeakCheck ./test ./leak-analyze ./test # ./compare-test test.template test.result gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/LeakCheck0000755000175000017500000000064010762704570025224 0ustar pabspabs#!/bin/sh if [ $# -lt 1 ] ; then echo "Usage: $0 " exit 1 fi # this looks in the same directory, this # LeakCheck script resides; modify to your # needs: SHLIB=`dirname $0`/LeakTracer.so if [ ! -x $SHLIB ] ; then echo "$SHLIB not found" exit 1 fi if [ -z "$LEAKTRACE_FILE" ] ; then rm -f leak.out else rm -f "$LEAKTRACE_FILE" fi export LD_PRELOAD=$SHLIB exec $@ gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/README0000644000175000017500000002130110762704570024341 0ustar pabspabsIntroduction ------------ LeakTracer is a small tool I wrote when checking a C++ program for memory leaks. I couldn't get dmalloc to display what I wanted, and I just saw the __builtin_return_address gcc-extension mentioned. To use LeakTracer, run your program using the provided LeakCheck script. It uses the LD_PRELOAD feature to "overlay" some functions on top of your functions (no recompile needed). If your platform does not support LD_PRELOAD, you can add the LeakTracer.o object file to the objects in your Makefile and run your application. LeakTracer uses gdb to print out the exact line where the memory was allocated and not freed - this of course means you have to free all dynamically allocated data. LeakTracer also overrides the global operator new and operator delete - this will give problems if you override them as well. LeakTracer traces only new/new[] and delete calls - it does not look at malloc/free/realloc. Here is some example output: Gathered 8 (8 unique) points of data. (gdb) Allocations: 1 / Size: 36 0x80608e6 is in NullArcableInstance::NullArcableInstance(void) (Machine.cc:40). 39 public: 40 NullArcableInstance() : ArcableInstance(new NullArcable) {} Allocations: 1 / Size: 8 0x8055b02 is in init_types(void) (Type.cc:119). 118 void init_types() { 119 Type::Integer = new IntegerType; Allocations: 1 / Size: 132 (new[]) 0x805f4ab is in Hashtable::Hashtable(unsigned int) (ea/h/Hashtable.h:15). 14 Hashtable (uint _size = 32) : size(_size), count(0) { 15 table = new List [size]; [...] Requirements ------------ You need Perl5 and gdb installed to run the leak-analyzer. You need gcc -- I currently use 2.95 but have used it with previous older versions without problems. You also need to run this on an architecture which supports __builtin_return_address arguments that are greater than 0 - there may be some problems on MIPS there. So far this code has been tested under Linux 2.2, x86 system, Solaris and HP-UX. Installation ------------ Just type make. There is no install target; you should put LeakTracer some place you can remember. Since version 2.0, it is possible to preload the LeakTracer object on architectures that support LD_PRELOAD (this is at least Linux and probably others -- please report success/failure). This means it is much easier to use the program: you do not need to relink your program with LeakTracer.o. In case your platform does not support LD_PRELOAD, you can use LeakTracer in the old pre 2.0 way: add LeakTracer.o to your object files -- at the very end of them (also after -llibrary lines). In any case your application must also be compiled with debugging enabled (i.e. -g). Running with LeakTracer ----------------------- If you are using the shared object, run the LeakCheck script. This script should stay in the directory where you install LeakCheck -- it will search for LeakTracer.so file there and load it. E.g.: ~/src/LeakTracer/LeakCheck yourApplication (if you put LeakTracer in ~/src/LeakTracer/) Run your application as normal, performing tasks that you want to be traced for memory leaks. While the application runs, LeakTracer will write data about memory allocation to the file "leak.out" in the current directory. You can override the location of that file by setting the LEAKTRACE_FILE environment variable. If you cannot use LD_PRELOAD, just run your application as normal after relinking it. It will also produce a "leak.out" file when it finishes. Detectable errors ----------------- LeakTracer is capable to detect the following problems with your program 1) memory which is allocated but not freed 2) (limited support for) overwritten memory at the end of the allocated block ( reason = 1 ) 3) memory which is tried to be deleted but which is not allocated (either because of a garbage pointer or twice deletion) (reason = 2) 4) memory which is allocated with new[] but deleted with simple delete and vice versa (reason = 4) For the last three problems, LeakTracer can abort() your program if you tell it so; the resulting core-dump allows to debug the problem. By default, only the overwrite memory condition results in an abort of the program because it is inherently critical. The two other conditions are not critical. You can influence what LeakTracer does with the environment variable LT_ABORTREASON which you can set to some numeric value which is the result of the sum of the reasons you find in the parentesis in the enumeration above. To abort on any reason, for example, you would set LT_ABORTREASON to 7. Analyzing output ---------------- You should then run leak-analyze, since looking at the raw leak.out file will not help you much. To run leak-analyze, you need Perl as well as gdb installed (any version of gdb will do). For example: leak-analyze myprog leak.out You don't have to specify the leak.out filename if you just use the default one. leak-analyze will run gdb on the file, sending it a number of commands that will show the source lines with the memory leaks. leak-analyze should show you something like this: Gathered 2 (2 unique) points of data. #-- Alloc: Different allocation schemes alloc here :0x80485b7 is in main (test.cc:6). 5 6 int *wrong = new int[10]; ..free here :0x80485d9 is in main (test.cc:11). 11 delete wrong; #-- Leak: Allocations: 1 / Size: 168 0x8048593 is in main (test.cc:3). 2 int main() { 3 int *array = new int [42] ; #-- Leak: Allocations: 1 / Size: 4 0x80485a5 is in main (test.cc:4). 3 int *array = new int [42] ; 4 int *foo = new int; This means that total of two allocations happened, in two different places. First a delete error is shown: you allocated some memory using new[] but you freed it using delete. leak-analyze will show where you allocated the memory and where you freed it. Afterwards each allocation is shown in turn. There was 1 allocation from this line of code (test.cc:3), and it was 168 bytes in size. Note that of the two lines of code shown, it's the bottom one that created the allocation. That's all there is to it - now you should find those memory leaks, fix them and rerun Leak tracer. Shared libraries and objects ---------------------------- If you want to analyze the leaks in shared libraries in your file, it may be necessary to make leak-analyze run your program and thus load the shared libraries before searching for addresses. To do that, run leak-analyze with the program name, leak name AND another argument which is where to set the breakpoint, e.g.: leak-analyze myprog leak.out main This will make leak-analyze tell gdb to set a breakpoint on "main" and then run the program. After the analysis is complete, the program will be killed. If you want to load some shared libraries, you can set a breakpoint on a different location, e.g. main.cc:42 if you know that once line 42 is reached, all shared objects have been loaded. If your program needs some command line arguments, supply them after "main". Licensing --------- LeakTracer is public domain (i.e. do with it whatever you feel like). Credits ------- Initial version of LeakTracer was written by Erwin Andreasen. Henner Zeller (foobar@to.com) contributed a rewrite of the code which introduced dynamic loading of LeakTracer and more. Revision history ---------------- February 21, 1999 v1.0 - only tested internally February 23, 1999 v1.1 - added operator new[] / delete[] February 23, 1999 v1.2 - Oops, forgot to free() the memory.. February 26, 1999 v1.3 - allow delete 0 March 27, 1999 v1.4 - Allow %p format without leading 0x for non-GNU libc. Option to leak-analyze to run the program. July 21, 1999 v1.5 - Fix for the above suggested by Alan Gonzalez August 21, 2000 v1.6 - use a destructor instead of __attribute__(destructor) November 19, 2000 v2.0 - Rewrite by Henner Zeller introduces LD_PRELOAD and much more February 27, 2001 v2.1 - Further update by Henner: optional thread safety, choose what should make LeakTracer abort(), better tracing of delete on non-new'ed pointers March 2, 2001 v2.2 - Another updated by Henner: hash table to increase performance with many allocations June 13, 2001 v2.3 - Made LT more resistant to being called before init and after destruction Authors: Erwin Andreasen Henner Zeller Homepage: http://www.andreasen.org/LeakTracer/ gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/leak-analyze0000755000175000017500000000636410762704570026000 0ustar pabspabs#!/usr/bin/perl # # Modification History # # 2004-January-17 Jason Rohrer # Fixed regexps to match both A-F and a-f for hex address strings. # # Erwin S. Andreasen # Henner Zeller # # Homepage: http://www.andreasen.org/LeakTracer/ # This program is Public Domain use IO::Handle; die "You must supply at least one argument.\n" unless $#ARGV >= 0; $ExeFile = shift @ARGV; $LeaksFile = $#ARGV >= 0 ? shift @ARGV : "leak.out"; open (LEAKS, $LeaksFile) or die "Could not open leaks data file $LeaksFile: $!"; if ($#ARGV >= 0) { $BreakOn = shift @ARGV; # Rest in @ARGV are program arguments } $n = $u = 0; while () { chop; next if (m/^\s*#/); # 1 2 3 4 5 6 7 #if (/^\s*L\s+(0x)?([0-9a-fA-F]+)\s+(0x)?([0-9a-fA-F]+)\s+(0x)?([0-9a-fA-F]+)\s+(\d+)/) { # Allocations, which have not been freed or deallocations which have not # been allocated. # 1 2 3 if (/^\s*L\s+(0x)?([0-9a-fA-F]+)\s+(\d+)/) { $addr="$2"; # ",$4,$6"; $u++ if not exists $Type{$addr}; $Count{$addr}++; $Size{$addr} += $3; # $7; $Type{$addr} = "Leak"; $n++; } elsif (/^\s*D\s+(0x)?([0-9a-fA-F]+)/) { $addr="$2"; # ",$4,$6"; $u++ if not exists $Type{$addr}; $Count{$addr}++; $Type{$addr} = "delete on not allocated memory"; $n++; } # allocations/deallocations with other errornous conditions # 1 2 3 4 5 elsif (/^\s*([SO])\s+(0x)?([0-9a-fA-F]+)\s+(0x)?([0-9a-fA-F]+)/) { $addrs = "$3,$5,$1"; $AllocDealloc{$addrs} = ("$1" =~ m/S/) ? "Different allocation schemes" : "This Memory was overwritten"; } } print STDERR "Gathered $n ($u unique) points of data.\n"; close (LEAKS); # Instead of using -batch, we just run things as usual. with -batch, # we quit on the first error, which we don't want. open (PIPE, "|gdb -q $ExeFile") or die "Cannot start gdb"; #open (PIPE, "|cat"); # Change set listsize 2 to something else to show more lines print PIPE "set prompt\nset complaints 1000\nset height 0\n"; # Optionally, run the program if (defined($BreakOn)) { print PIPE "break $BreakOn\n"; print PIPE "run ", join(" ", @ARGV), " \n"; } print PIPE "set listsize 2\n"; foreach (sort keys %AllocDealloc) { print PIPE "echo \\n#-- Alloc: $AllocDealloc{$_}\\nalloc here :\n"; @addrs = split(/,/,$_); print PIPE "l *0x" . (shift @addrs) . "\necho ..free here :\n"; print PIPE "set listsize 1\n"; print PIPE "l *0x" . (shift @addrs) . "\n"; } foreach (sort keys %Type) { print PIPE "echo \\n#-- $Type{$_}: counted $Count{$_}x"; if ($Size{$_} > 0) { print PIPE " / total Size: $Size{$_}"; } print PIPE "\\n\n"; @addrs = split(/,/,$_); print PIPE "set listsize 2\n"; print PIPE "l *0x" . (shift @addrs) . "\n"; #print PIPE "echo ..called from :\n"; #print PIPE "set listsize 1\n"; # gdb bails out, if it cannot find an address. #print PIPE "l *0x" . (shift @addrs) . "\necho ..called from :\n"; #print PIPE "l *0x" . (shift @addrs) . "\n"; } if (defined($BreakOn)) { print PIPE "kill\n"; } print PIPE "quit\n"; PIPE->flush(); wait(); close (PIPE); gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/test.cc0000644000175000017500000000054110762704570024752 0ustar pabspabs/* * Modification History * * 2002-March-31 Jason Rohrer * Added test of strdup support. */ #include // Small leaky test program void foo() { int *x = new int; } int main() { char *str = strdup( "Test String" ); int *z = new int[10]; foo(); foo(); delete z; delete z; // delete value twice } gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/LeakCheckAnalyze0000755000175000017500000000033110762704570026545 0ustar pabspabs#!/bin/sh CHECKER=`dirname $0`/LeakCheck" $@" ANALYZER=`dirname $0`/leak-analyze" $1 leak.out" echo "Checking with: $CHECKER" echo "" $CHECKER echo "" echo "Analyzing with: $ANALYZER" echo "" $ANALYZER 2>&1 | more gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/VERSION0000644000175000017500000000000410762704570024526 0ustar pabspabs2.3 gravitation-3+dfsg1.orig/minorGems/util/development/leakTracer/README.html0000644000175000017500000002270510762704570025315 0ustar pabspabs

Table of contents

Introduction

LeakTracer is a small tool I wrote when checking a C++ program for memory
leaks. I couldn't get dmalloc to display what I wanted, and I just saw the
__builtin_return_address gcc-extension mentioned.

To use LeakTracer, run your program using the provided LeakCheck script. It
uses the LD_PRELOAD feature to "overlay" some functions on top of your
functions (no recompile needed). If your platform does not support LD_PRELOAD,
you can add the LeakTracer.o object file to the objects in your Makefile and
run your application. 

LeakTracer uses gdb to print out the exact line where the memory was allocated
and not freed - this of course means you have to free all dynamically
allocated data. LeakTracer also overrides the global operator new and operator
delete - this will give problems if you override them as well.

LeakTracer traces only new/new[] and delete calls - it does not look at
malloc/free/realloc.

Here is some example output:

Gathered 8 (8 unique) points of data.
(gdb)
Allocations: 1 / Size: 36
0x80608e6 is in NullArcableInstance::NullArcableInstance(void) (Machine.cc:40).
39      public:
40          NullArcableInstance() : ArcableInstance(new NullArcable) {}

Allocations: 1 / Size: 8
0x8055b02 is in init_types(void) (Type.cc:119).
118     void init_types() {
119         Type::Integer = new IntegerType;

Allocations: 1 / Size: 132 (new[])
0x805f4ab is in Hashtable::Hashtable(unsigned int) (ea/h/Hashtable.h:15).
14          Hashtable (uint _size = 32) : size(_size), count(0) {
15              table = new List [size];

[...]

Requirements

You need Perl5 and gdb installed to run the leak-analyzer. You need gcc -- I
currently use 2.95 but have used it with previous older versions without
problems.
You also need to run this on an architecture which supports
__builtin_return_address arguments that are greater than 0 - there may be
some problems on MIPS there. 

So far this code has been tested under Linux 2.2, x86 system, Solaris and
HP-UX.

Installation

Just type make. There is no install target; you should put LeakTracer
some place you can remember.

Since version 2.0, it is possible to preload the LeakTracer object on
architectures that support LD_PRELOAD (this is at least Linux and probably
others -- please report success/failure). This means it is much easier to use
the program: you do not need to relink your program with LeakTracer.o.

In case your platform does not support LD_PRELOAD, you can use LeakTracer in
the old pre 2.0 way: add LeakTracer.o to your object files -- at the very end
of them (also after -llibrary lines).

In any case your application must also be compiled with debugging enabled
(i.e. -g).

Running with LeakTracer

If you are using the shared object, run the LeakCheck script. This script
should stay in the directory where you install LeakCheck -- it will search for
LeakTracer.so file there and load it. E.g.:

~/src/LeakTracer/LeakCheck yourApplication

(if you put LeakTracer in ~/src/LeakTracer/)

Run your application as normal, performing tasks that you want to be traced
for memory leaks. While the application runs, LeakTracer will write data about
memory allocation to the file "leak.out" in the current directory. You can
override the location of that file by setting the LEAKTRACE_FILE environment
variable.

If you cannot use LD_PRELOAD, just run your application as normal after
relinking it. It will also produce a "leak.out" file when it finishes.

Detectable errors

LeakTracer is capable to detect the following problems with your program

  1) memory which is allocated but not freed
  2) (limited support for) overwritten memory at the end of the allocated
     block  ( reason = 1 )
  3) memory which is tried to be deleted but which is not allocated
     (either because of a garbage pointer or twice deletion)
     (reason = 2)
  4) memory which is allocated with new[] but deleted with simple delete
     and vice versa (reason = 4)

For the last three problems, LeakTracer can abort() your program if you
tell it so; the resulting core-dump allows to debug the problem. By default,
only the overwrite memory condition results in an abort of the program
because it is inherently critical. The two other conditions are not critical.
You can influence what LeakTracer does with the environment variable
   LT_ABORTREASON
which you can set to some numeric value which is the result of the
sum of the reasons you find in the parentesis in the enumeration above.
To abort on any reason, for example, you would set LT_ABORTREASON to 7.

Analyzing output

You should then run leak-analyze, since looking at the raw leak.out file will
not help you much. To run leak-analyze, you need Perl as well as gdb
installed (any version of gdb will do). For example:

leak-analyze myprog leak.out

You don't have to specify the leak.out filename if you just use the default
one. leak-analyze will run gdb on the file, sending it a number of commands
that will show the source lines with the memory leaks.

leak-analyze should show you something like this:

Gathered 2 (2 unique) points of data.

#-- Alloc: Different allocation schemes
alloc here :0x80485b7 is in main (test.cc:6).
5
6               int *wrong = new int[10];
..free here :0x80485d9 is in main (test.cc:11).
11              delete wrong;

#-- Leak: Allocations: 1 / Size: 168 
0x8048593 is in main (test.cc:3).
2       int main() {
3               int *array = new int [42] ;

#-- Leak: Allocations: 1 / Size: 4 
0x80485a5 is in main (test.cc:4).
3               int *array = new int [42] ;
4               int *foo = new int;
This means that total of two allocations happened, in two different places.

First a delete error is shown: you allocated some memory using new[] but you
freed it using delete. leak-analyze will show where you allocated the memory and where you freed it.

Afterwards each allocation is shown in turn. There was 1 allocation from this
line of code (test.cc:3), and it was 168 bytes in size. Note that of the two
lines of code shown, it's the bottom one that created the allocation.

That's all there is to it - now you should find those memory leaks, fix them
and rerun Leak tracer.

Shared libraries and objects

If you want to analyze the leaks in shared libraries in your file, it may be
necessary to make leak-analyze run your program and thus load the shared
libraries before searching for addresses.

To do that, run leak-analyze with the program name, leak name AND another
argument which is where to set the breakpoint, e.g.:

leak-analyze myprog leak.out main

This will make leak-analyze tell gdb to set a breakpoint on "main" and then
run the program. After the analysis is complete, the program will be killed.

If you want to load some shared libraries, you can set a breakpoint on a
different location, e.g. main.cc:42 if you know that once line 42 is reached,
all shared objects have been loaded.

If your program needs some command line arguments, supply them after "main".

Licensing

LeakTracer is public domain (i.e. do with it whatever you feel like).

Credits

Initial version of LeakTracer was written by Erwin Andreasen. Henner Zeller
(foobar@to.com) contributed a rewrite of the code which
introduced dynamic loading of LeakTracer and more.

Revision history

February 21, 1999       v1.0 - only tested internally
February 23, 1999       v1.1 - added operator new[] / delete[]
February 23, 1999           v1.2 - Oops, forgot to free() the memory..
February 26, 1999       v1.3 - allow delete 0
March 27, 1999          v1.4 - Allow %p format without leading 0x for non-GNU 
                                       libc. Option to leak-analyze to run the program.
July 21, 1999               v1.5 - Fix for the above suggested by Alan Gonzalez
August 21, 2000         v1.6 - use a destructor instead of 
                                       __attribute__(destructor)
November 19, 2000               v2.0 - Rewrite by Henner Zeller introduces LD_PRELOAD
                                       and much more
February 27, 2001               v2.1 - Further update by Henner: optional thread safety,
                                       choose what should make LeakTracer abort(), better
                                       tracing of delete on non-new'ed pointers
March 2, 2001                   v2.2 - Another updated by Henner: hash table to increase
                                       performance with many allocations
June 13, 2001                   v2.3 - Made LT more resistant to being called before init
                                       and after destruction

Authors:    Erwin Andreasen 
        Henner Zeller 
Homepage:   http://www.andreasen.org/LeakTracer/

gravitation-3+dfsg1.orig/minorGems/util/stringUtils.cpp0000644000175000017500000002544710762704570022134 0ustar pabspabs/* * Modification History * * 2003-May-10 Jason Rohrer * Created. * Added a tokenization function. * * 2003-June-14 Jason Rohrer * Added a join function. * * 2003-June-22 Jason Rohrer * Added an autoSprintf function. * * 2003-July-27 Jason Rohrer * Fixed bugs in autoSprintf return values for certain cases. * * 2003-August-12 Jason Rohrer * Added a concatonate function. * * 2003-September-7 Jason Rohrer * Changed so that split returns last part, even if it is empty. * * 2004-January-15 Jason Rohrer * Added work-around for MinGW vsnprintf bug. * * 2006-June-2 Jason Rohrer * Added a stringStartsWith function. */ #include "stringUtils.h" #include "StringBufferOutputStream.h" #include char *stringToLowerCase( const char *inString ) { int length = strlen( inString ); char *returnString = stringDuplicate( inString ); for( int i=0; i stringLength ) { return false; } else { for( int i=0; i *parts = new SimpleVector(); char *workingString = stringDuplicate( inString ); char *workingStart = workingString; int separatorLength = strlen( inSeparator ); char *foundSeparator = strstr( workingString, inSeparator ); while( foundSeparator != NULL ) { // terminate at separator foundSeparator[0] = '\0'; parts->push_back( stringDuplicate( workingString ) ); // skip separator workingString = &( foundSeparator[ separatorLength ] ); foundSeparator = strstr( workingString, inSeparator ); } // add the remaining part, even if it is the empty string parts->push_back( stringDuplicate( workingString ) ); delete [] workingStart; *outNumParts = parts->size(); char **returnArray = parts->getElementArray(); delete parts; return returnArray; } char *join( char **inStrings, int inNumParts, char *inGlue ) { StringBufferOutputStream *outStream = new StringBufferOutputStream(); for( int i=0; iwriteString( inStrings[i] ); outStream->writeString( inGlue ); } // no glue after last string outStream->writeString( inStrings[ inNumParts - 1 ] ); char *returnString = outStream->getString(); delete outStream; return returnString; } char *concatonate( char *inStringA, char *inStringB ) { char **tempArray = new char*[2]; tempArray[ 0 ] = inStringA; tempArray[ 1 ] = inStringB; char *glue = ""; char *result = join( tempArray, 2, glue ); delete [] tempArray; return result; } char *replaceOnce( char *inHaystack, char *inTarget, char *inSubstitute, char *outFound ) { char *haystackCopy = stringDuplicate( inHaystack ); char *fieldTargetPointer = strstr( haystackCopy, inTarget ); if( fieldTargetPointer == NULL ) { // target not found *outFound = false; return haystackCopy; } else { // target found // prematurely terminate haystack copy string at // start of target occurence // (okay, since we're working with a copy of the haystack argument) fieldTargetPointer[0] = '\0'; // pointer to first char after target occurrence char *fieldPostTargetPointer = &( fieldTargetPointer[ strlen( inTarget ) ] ); char *returnString = new char[ strlen( inHaystack ) - strlen( inTarget ) + strlen( inSubstitute ) + 1 ]; sprintf( returnString, "%s%s%s", haystackCopy, inSubstitute, fieldPostTargetPointer ); delete [] haystackCopy; *outFound = true; return returnString; } } char *replaceAll( char *inHaystack, char *inTarget, char *inSubstitute, char *outFound ) { // repeatedly replace once until replacing fails char lastFound = true; char atLeastOneFound = false; char *returnString = stringDuplicate( inHaystack ); while( lastFound ) { char *nextReturnString = replaceOnce( returnString, inTarget, inSubstitute, &lastFound ); delete [] returnString; returnString = nextReturnString; if( lastFound ) { atLeastOneFound = true; } } *outFound = atLeastOneFound; return returnString; } char *replaceTargetListWithSubstituteList( char *inHaystack, SimpleVector *inTargetVector, SimpleVector *inSubstituteVector ) { int numTargets = inTargetVector->size(); char *newHaystack = stringDuplicate( inHaystack ); char tagFound; for( int i=0; igetElement( i ) ), *( inSubstituteVector->getElement( i ) ), &tagFound ); delete [] newHaystack; newHaystack = newHaystackWithReplacements; } return newHaystack; } SimpleVector *tokenizeString( char *inString ) { char *tempString = stringDuplicate( inString ); char *restOfString = tempString; SimpleVector *foundTokens = new SimpleVector(); SimpleVector *currentToken = new SimpleVector(); while( restOfString[0] != '\0' ) { // characters remain // skip whitespace char nextChar = restOfString[0]; while( nextChar == ' ' || nextChar == '\n' || nextChar == '\r' || nextChar == '\t' ) { restOfString = &( restOfString[1] ); nextChar = restOfString[0]; } if( restOfString[0] != '\0' ) { // a token while( nextChar != ' ' && nextChar != '\n' && nextChar != '\r' && nextChar != '\t' && nextChar != '\0' ) { // still not whitespace currentToken->push_back( nextChar ); restOfString = &( restOfString[1] ); nextChar = restOfString[0]; } // reached end of token foundTokens->push_back( currentToken->getElementString() ); currentToken->deleteAll(); } } delete [] tempString; delete currentToken; return foundTokens; } char *autoSprintf( const char* inFormatString, ... ) { int bufferSize = 50; va_list argList; va_start( argList, inFormatString ); char *buffer = new char[ bufferSize ]; int stringLength = vsnprintf( buffer, bufferSize, inFormatString, argList ); va_end( argList ); if( stringLength != -1 ) { // follows C99 standard... // stringLength is the length of the string that would have been // written if the buffer was big enough // not room for string and terminating \0 in bufferSize bytes if( stringLength >= bufferSize ) { // need to reprint with a bigger buffer delete [] buffer; bufferSize = stringLength + 1; va_list argList; va_start( argList, inFormatString ); buffer = new char[ bufferSize ]; // can simply use vsprintf now vsprintf( buffer, inFormatString, argList ); va_end( argList ); return buffer; } else { // buffer was big enough // trim the buffer to fit the string char *returnString = stringDuplicate( buffer ); delete [] buffer; return returnString; } } else { // follows old ANSI standard // -1 means the buffer was too small // Note that some buggy non-C99 vsnprintf implementations // (notably MinGW) // do not return -1 if stringLength equals bufferSize (in other words, // if there is not enough room for the trailing \0). // Thus, we need to check for both // (A) stringLength == -1 // (B) stringLength == bufferSize // below. // keep doubling buffer size until it's big enough while( stringLength == -1 || stringLength == bufferSize) { delete [] buffer; if( stringLength == bufferSize ) { // only occurs if vsnprintf implementation is buggy // might as well use the information, though // (instead of doubling the buffer size again) bufferSize = bufferSize + 1; } else { // double buffer size again bufferSize = 2 * bufferSize; } va_list argList; va_start( argList, inFormatString ); buffer = new char[ bufferSize ]; stringLength = vsnprintf( buffer, bufferSize, inFormatString, argList ); va_end( argList ); } // trim the buffer to fit the string char *returnString = stringDuplicate( buffer ); delete [] buffer; return returnString; } } gravitation-3+dfsg1.orig/minorGems/util/printUtils.h0000644000175000017500000000102710762704570021413 0ustar pabspabs/* * Modification History * * 2002-April-8 Jason Rohrer * Created. */ #include "minorGems/common.h" #ifndef PRINT_UTILS_INCLUDED #define PRINT_UTILS_INCLUDED /** * A thread-safe version of printf. * * Note that printf is already thread-safe on certain platforms, * but does not seem to be thread-safe on Win32. * * @param inFormatString the format string to use. * @param ... a variable argument list, with the same usage * pattern as printf. */ int threadPrintF( const char* inFormatString, ... ); #endif gravitation-3+dfsg1.orig/minorGems/util/random/0000755000175000017500000000000010762704570020345 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/util/random/StdRandomSource.h0000644000175000017500000000636510762704570023604 0ustar pabspabs// Jason Rohrer // StdRandomSource.h /** * * Implementation of random number generation that uses stdlib calls * * * Created 12-7-99 * Mods: * Jason Rohrer 9-28-2000 Added a getRandomBoundedInt() * implementation * Jason Rohrer 12-7-2000 Overloaded constructor to support * specifying a seed. * Jason Rohrer 12-16-2000 Added a getRandomDouble() function. * Jason Rohrer 12-17-2000 Fixed bug in initialization of invDMAX * in default constructor. * Jason Rohrer 9-13-2001 Fixed a bug in getRandomBoundedInt() * as floats were being used, and they * don't provide enough resolution. * Jason Rohrer 10-11-2002 Fixed some type casting warnings. * Jason Rohrer 07-09-2006 Added getRandomBoundedDouble. * Jason Rohrer 07-27-2006 Added getRandomBoolean. */ #include "minorGems/common.h" #ifndef STD_RANDOM_SOURCE_INCLUDED #define STD_RANDOM_SOURCE_INCLUDED #include #include #include "RandomSource.h" class StdRandomSource : public RandomSource { public: StdRandomSource(); // needed to seed stdlib generator // specify the seed for the stdlib generator StdRandomSource( unsigned long inSeed ); // implements these functions float getRandomFloat(); // in interval [0,1.0] double getRandomDouble(); // in interval [0,1.0] long getRandomInt(); // in interval [0,MAX] long getIntMax(); // returns MAX long getRandomBoundedInt( long inRangeStart, long inRangeEnd ); double getRandomBoundedDouble( double inRangeStart, double inRangeEnd ); char getRandomBoolean(); private: double mInvMAXPlusOne; // 1 / ( MAX + 1 ) }; inline StdRandomSource::StdRandomSource() { MAX = RAND_MAX; srand( (unsigned)time(NULL) ); invMAX = (float)1.0 / ((float)MAX); invDMAX = 1.0 / ((double)MAX); mInvMAXPlusOne = 1.0 / ( ( (float)MAX ) + 1.0 ); } inline StdRandomSource::StdRandomSource( unsigned long inSeed ) { MAX = RAND_MAX; srand( inSeed ); invMAX = (float)1.0 / ((float)MAX); invDMAX = 1.0 / ((double)MAX); mInvMAXPlusOne = 1.0 / ( ( (double)MAX ) + 1.0 ); } inline float StdRandomSource::getRandomFloat() { return (float)(rand()) * invMAX; } inline double StdRandomSource::getRandomDouble() { return (double)(rand()) * invDMAX; } inline long StdRandomSource::getRandomInt() { return rand(); } inline long StdRandomSource::getIntMax() { return MAX; } inline long StdRandomSource::getRandomBoundedInt( long inRangeStart, long inRangeEnd ) { // float in range [0,1) double randFloat = (double)( rand() ) * mInvMAXPlusOne; long onePastRange = inRangeEnd + 1; long magnitude = (int)( randFloat * ( onePastRange - inRangeStart ) ); return magnitude + inRangeStart; } inline double StdRandomSource::getRandomBoundedDouble( double inRangeStart, double inRangeEnd ) { // double in range [0,1] double randDouble = getRandomDouble(); double magnitude = randDouble * ( inRangeEnd - inRangeStart ); return magnitude + inRangeStart; } inline char StdRandomSource::getRandomBoolean() { // float in range [0,1] double randFloat = getRandomFloat(); if( randFloat < 0.5 ) { return true; } else { return false; } } #endif gravitation-3+dfsg1.orig/minorGems/util/random/Noise.cpp0000644000175000017500000001625410762704570022136 0ustar pabspabs// Jason Rohrer // Noise.cpp /** * * Noise generation implementation * * * Created 11-3-99 * Mods: * Jason Rohrer 12-20-2000 Changed genFractalNoise2d function to make * it less blocky. * */ #include "Noise.h" // fills 2d image with ARGB noise void genRandNoise2d(unsigned long *buff, int buffHigh, int buffWide) { int *yOffset = new int[buffHigh]; // precalc y offsets for( int y=0; y> 24 & 0xFF) + alpha; int buffRed = (buffARGB >> 16 & 0xFF) + red; int buffGreen = (buffARGB >> 8 & 0xFF) + green; int buffBlue = (buffARGB & 0xFF) + blue; if( buffAlpha < 0) buffAlpha = 0; if( buffRed < 0) buffRed = 0; if( buffGreen < 0) buffGreen = 0; if( buffBlue < 0) buffBlue = 0; if( buffAlpha > 255) buffAlpha = 255; if( buffRed > 255) buffRed = 255; if( buffGreen > 255) buffGreen = 255; if( buffBlue > 255) buffBlue = 255; buff[ yOffset[buffY] + buffX] = buffBlue | buffGreen << 8 | buffRed << 16 | buffAlpha << 24; buffX++; blockX++; if( buffX >= buffWide ) blockX = blockWide; // if this block hangs outside buffer } buffY++; blockY++; if( buffY >= buffHigh ) blockY = blockHigh; // if this block hangs outside buffer } buffX = startX + blockWide; } buffY = startY + blockHigh; } } delete [] yOffset; } void genFractalNoise2d( double *inBuffer, int inWidth, int inMaxFrequency, double inFPower, char inInterpolate, RandomSource *inRandSource ) { RandomSource *r = inRandSource; int w = inWidth; int i, x, y, f; int numPoints = w * w; // first, fill surface with a uniform 0.5 value for( i=0; igetRandomDouble() - 1 ) * weight; } // now walk though 2d array and perform // bilinear interpolation between blocks for( y=0; y 1.0 ) { inBuffer[y * w + x] = 1.0; } else if( inBuffer[y * w + x] < 0.0 ) { inBuffer[y * w + x] = 0.0; } } } delete [] blockValues; } } void genFractalNoise( double *inBuffer, int inWidth, int inMaxFrequency, double inFPower, char inInterpolate, RandomSource *inRandSource ) { RandomSource *r = inRandSource; int w = inWidth; int i, x, f; // first, fill array with uniform 0.5 values for( i=0; igetRandomDouble() - 1 ) * weight; } // now walk though array and perform linear interpolation between blocks for( x=0; x 1.0 ) { inBuffer[x] = 1.0; } else if( inBuffer[x] < 0.0 ) { inBuffer[x] = 0.0; } } delete [] blockValues; } } gravitation-3+dfsg1.orig/minorGems/util/random/RandomSource.h0000644000175000017500000000376710762704570023134 0ustar pabspabs// Jason Rohrer // RandomSource.h /** * * abstract interface for random number generation * * Can be implemented by: * --stdlib rand() function calls * --seed file full of random numbers * * Created 12-7-99 * Mods: * Jason Rohrer 9-28-2000 Added a getRandomBoundedInt() * interface to faciliate retrieving * an integer in a given range [a,b] * where each integer in the range * has the same probability of being * returned. * Jason Rohrer 12-16-2000 Added a getRandomDouble() interface. * Jason Rohrer 11-21-2005 Added a virtual destructor. * Jason Rohrer 07-09-2006 Added a getRandomBoundedDouble interface. * Jason Rohrer 07-27-2006 Added a getRandomBoolean interface. */ #include "minorGems/common.h" #ifndef RANDOM_SOURCE_INCLUDED #define RANDOM_SOURCE_INCLUDED class RandomSource { public: // pure virtual functions implemented by inheriting classes virtual float getRandomFloat() = 0; // in interval [0,1.0] virtual double getRandomDouble() = 0; // in interval [0,1.0] virtual long getRandomInt() = 0; // in interval [0,MAX] virtual long getIntMax() = 0; // returns MAX /** * Returns a random integer in [rangeStart,rangeEnd] * where each integer in the range has an equal * probability of occuring. */ virtual long getRandomBoundedInt( long inRangeStart, long inRangeEnd ) = 0; /** * Returns a random double in [rangeStart,rangeEnd]. */ virtual double getRandomBoundedDouble( double inRangeStart, double inRangeEnd ) = 0; /** * Gets a random true/false value. */ virtual char getRandomBoolean() = 0; virtual ~RandomSource(); protected: long MAX; // maximum integer random number float invMAX; // floating point inverse of MAX double invDMAX; // double invers of MAX }; inline RandomSource::~RandomSource() { // does nothing // exists to ensure that subclass destructors are called } #endif gravitation-3+dfsg1.orig/minorGems/util/random/Noise.h0000644000175000017500000000473210762704570021601 0ustar pabspabs// Jason Rohrer // Noise.h /** * * Noise generation interface * * * Created 11-3-99 * Mods: * Jason Rohrer 12-20-2000 Added a fractal noise function * that fills a double array. * */ #include "minorGems/common.h" #ifndef NOISE_INCLUDED #define NOISE_INCLUDED #include #include #include "RandomSource.h" // fills 2d image with RGBA noise void genRandNoise2d(unsigned long *buff, int buffHigh, int buffWide); // returns a random floating point between 0 and 1 inline float floatRand() { float invRandMax = 1 / ((float)RAND_MAX); return (float)(rand()) * invRandMax; } // fills 2d image with ARGB fractal noise void genFractalNoise2d(unsigned long *buff, int buffHigh, int buffWide); /** * Fills a 2d array with 1/f fractal noise. * * @param inBuffer a pre-allocated buffer to fill. * @param inWidth the width and height of the 2d array * contained in the buffer. * Must be a power of 2. * @param inMaxFrequency the maximum frequency of noise modulation to * include, in [2,inWidth]. Lower values produce more "blurry" or * blocky noise. * @param inFPower power to raise F to whene generating noise. * Amplitude of modulation = 1 / (F^inFPower). * @param inInterpolate set to true to perform interpolation of * each frequency modulation. Setting to false produces a "blockier" * noise, while setting to true makes the noise more cloud-like. * @param inRandSource the source to use for random numbers. */ void genFractalNoise2d( double *inBuffer, int inWidth, int inMaxFrequency, double inFPower, char inInterpolate, RandomSource *inRandSource ); /** * Fills a 1d array with 1/f fractal noise. * * @param inBuffer a pre-allocated buffer to fill. * @param inWidth the width of the 2d array * contained in the buffer. * Must be a power of 2. * @param inMaxFrequency the maximum frequency of noise modulation to * include, in [2,inWidth]. Lower values produce more "blurry" or * blocky noise. * @param inFPower power to raise F to whene generating noise. * Amplitude of modulation = 1 / (F^inFPower). * @param inInterpolate set to true to perform interpolation of * each frequency modulation. Setting to false produces a "blockier" * noise, while setting to true makes the noise more cloud-like. * @param inRandSource the source to use for random numbers. */ void genFractalNoise( double *inBuffer, int inWidth, int inMaxFrequency, double inFPower, char inInterpolate, RandomSource *inRandSource ); #endif gravitation-3+dfsg1.orig/minorGems/util/StringBufferOutputStream.h0000644000175000017500000000277210762704570024243 0ustar pabspabs/* * Modification History * * 2002-August-1 Jason Rohrer * Created. * * 2004-May-9 Jason Rohrer * Added function for getting data as a byte array. */ #include "minorGems/common.h" #ifndef STRING_BUFFER_OUTPUT_STREAM_INCLUDED #define STRING_BUFFER_OUTPUT_STREAM_INCLUDED #include "minorGems/util/SimpleVector.h" #include "minorGems/io/OutputStream.h" /** * An output stream that fills a string buffer. * * @author Jason Rohrer */ class StringBufferOutputStream : public OutputStream { public: StringBufferOutputStream(); ~StringBufferOutputStream(); /** * Gets the data writen to this stream since construction as a * \0-terminated string. * * @return a string containing all data written to this stream. * Must be destroyed by caller. */ char *getString(); /** * Gets the data writen to this stream since construction as a * byte array. * * @param outNumBytes pointer to where the array length should be * returned. * * @return an array containingdata written to this stream. * Must be destroyed by caller. */ unsigned char *getBytes( int *outNumBytes ); // implements the OutputStream interface long write( unsigned char *inBuffer, long inNumBytes ); protected: SimpleVector *mCharacterVector; }; #endif gravitation-3+dfsg1.orig/minorGems/util/TranslationManager.h0000644000175000017500000001073410762704570023034 0ustar pabspabs/* * Modification History * * 2004-October-7 Jason Rohrer * Created. * Copied structure from SettingsManager. * * 2006-February-19 Jason Rohrer * Fixed an inconsistency in memory management. */ #include "minorGems/common.h" #ifndef TRANSLATION_MANAGER_INCLUDED #define TRANSLATION_MANAGER_INCLUDED #include "minorGems/util/SimpleVector.h" // utility class for dealing with static member dealocation class TranslationManagerStaticMembers; /** * Class that manages natural language translation of user interface strings. * * @author Jason Rohrer */ class TranslationManager { public: /** * Sets the directory name where translation files are stored. * Defaults to "languages". * * @param inName the name of the directory (relative to the * program's working directory). * Must be destroyed by caller. */ static void setDirectoryName( char *inName ); /** * Gets the directory name where translation files are stored. * * @return the name of the directory (relative to the * program's working directory). * Must be destroyed by caller. */ static char *getDirectoryName(); /** * Gets a list of available languages. * * @param outNumLanguages pointer to where the number of languages * should be returned. * * @return an array of language names. * Array and the strings it contains must be destroyed by caller. */ static char **getAvailableLanguages( int *outNumLanguages ); /** * Sets the natural language to translate keys into. * Defaults to "English". * * @param inLanguageName the name of the language. * This name, when .txt is appended, is the name of * the translation file. Thus, setLanguage( "English" ) would * select the English.txt language file. * Language names must not contain spaces. * Must be destroyed by caller. */ static void setLanguage( char *inLanguageName ); /** * Gets the natural language translation of a key. * * NOTE: if a translation does not exist for the key, the key * itself will be returned. (A copy of the key is returned, so * the original key passed in to translate can be destroyed by caller * if needed). * * @param inTranslationKey the translation key string. * Must be destroyed by caller if non-const. * * @return the translated natural language string. * The string MUST NOT be destroyed by the caller, as it will * be destroyed by this class upon program termination. * * This specification allows the translate function to be used * inline, whether or not a correct translation exists. Thus
         *
         * printf( "%s", translate( myKey ) );
         * delete [] myKey;
         * 
* * will always be correct, whether or not a translation exists, as * will
         *
         * printf( "%s", translate( "MY_KEY" ) );
         * 
*/ static const char *translate( char *inTranslationKey ); protected: static TranslationManagerStaticMembers mStaticMembers; }; /** * Container for static members to allow for their proper destruction * on program termination. * * @author Jason Rohrer */ class TranslationManagerStaticMembers { public: TranslationManagerStaticMembers(); ~TranslationManagerStaticMembers(); /** * Sets the directory name and language name to use, and reads * the translation table from file. * * @param inDirectoryName the directory name. * Must be destroyed by caller. * @param inLanguageName the language name. * Must be destroyed by caller. */ void setDirectoryAndLanguage( char *inDirectoryName, char *inLanguageName ); char *mDirectoryName; char *mLanguageName; // vectors mapping keys to strings SimpleVector *mTranslationKeys; SimpleVector *mNaturalLanguageStrings; }; #endif gravitation-3+dfsg1.orig/minorGems/build/0000755000175000017500000000000010762704566017214 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/build/Makefile.minorGems0000644000175000017500000002754610762704566022631 0ustar pabspabs# # Modification History # # 2004-November-19 Jason Rohrer # Copied from Primrose source. # # 2004-November-21 Jason Rohrer # Added multi-source downloader. # # 2004-December-13 Jason Rohrer # Added socket manager. # # 2005-February-4 Jason Rohrer # Added ScreenGL. # # 2005-February-21 Jason Rohrer # Added SingleTextureGL. # # 2006-November-21 Jason Rohrer # Added PNGImageConverter. # ## # The common portion of Makefiles for all targets that use minorGems, # supplying variable definitions for minorGems. # # Should not be made manually---used by project-specific configure scripts to # build Makefiles. ## # This file is intended to be included in another makefile. # The following variables need to be defined: # # ROOT_PATH the path to the directory containing the minorGems directory # PLATFORM_PATH # PLATFORM # DIRECTORY_PLATFORM_PATH # DIRECTORY_PLATFORM # TIME_PLATFORM_PATH # TIME_PLATFORM # SOCKET_UDP_PLATFORM_PATH # SOCKET_UDP_PLATFORM # Makefile Usage: # -- Include this file # -- Define your project-specific targets and rules # -- Include Makefile.minorGems_targets PLATFORM_DIRECTORY = ${ROOT_PATH}/minorGems/io/file/${DIRECTORY_PLATFORM_PATH}/Directory${DIRECTORY_PLATFORM} PLATFORM_TIME = ${ROOT_PATH}/minorGems/system/${TIME_PLATFORM_PATH}/Time${TIME_PLATFORM} PLATFORM_HOST_ADDRESS = ${ROOT_PATH}/minorGems/network/${PLATFORM_PATH}/HostAddress${PLATFORM} PLATFORM_SOCKET = ${ROOT_PATH}/minorGems/network/${PLATFORM_PATH}/Socket${PLATFORM} PLATFORM_SOCKET_CLIENT = ${ROOT_PATH}/minorGems/network/${PLATFORM_PATH}/SocketClient${PLATFORM} PLATFORM_SOCKET_SERVER = ${ROOT_PATH}/minorGems/network/${PLATFORM_PATH}/SocketServer${PLATFORM} PLATFORM_SOCKET_UDP = ${ROOT_PATH}/minorGems/network/${SOCKET_UDP_PLATFORM_PATH}/SocketUDP${SOCKET_UDP_PLATFORM} PLATFORM_TYPE_IO = ${ROOT_PATH}/minorGems/io/${PLATFORM_PATH}/TypeIO${PLATFORM} PLATFORM_THREAD = ${ROOT_PATH}/minorGems/system/${PLATFORM_PATH}/Thread${PLATFORM} PLATFORM_MUTEX_LOCK = ${ROOT_PATH}/minorGems/system/${PLATFORM_PATH}/MutexLock${PLATFORM} PLATFORM_BINARY_SEMAPHORE = ${ROOT_PATH}/minorGems/system/${PLATFORM_PATH}/BinarySemaphore${PLATFORM} ## # Header, source, and object files. ## SIMPLE_VECTOR_H = ${ROOT_PATH}/minorGems/util/SimpleVector.h OUTPUT_STREAM_H = ${ROOT_PATH}/minorGems/io/OutputStream.h INPUT_STREAM_H = ${ROOT_PATH}/minorGems/io/InputStream.h HOST_ADDRESS_H = ${ROOT_PATH}/minorGems/network/HostAddress.h HOST_ADDRESS_CPP = ${PLATFORM_HOST_ADDRESS}.cpp HOST_ADDRESS_O = ${PLATFORM_HOST_ADDRESS}.o SOCKET_H = ${ROOT_PATH}/minorGems/network/Socket.h SOCKET_CPP = ${PLATFORM_SOCKET}.cpp SOCKET_O = ${PLATFORM_SOCKET}.o SOCKET_CLIENT_H = ${ROOT_PATH}/minorGems/network/SocketClient.h SOCKET_CLIENT_CPP = ${PLATFORM_SOCKET_CLIENT}.cpp SOCKET_CLIENT_O = ${PLATFORM_SOCKET_CLIENT}.o SOCKET_SERVER_H = ${ROOT_PATH}/minorGems/network/SocketServer.h SOCKET_SERVER_CPP = ${PLATFORM_SOCKET_SERVER}.cpp SOCKET_SERVER_O = ${PLATFORM_SOCKET_SERVER}.o SOCKET_UDP_H = ${ROOT_PATH}/minorGems/network/SocketUDP.h SOCKET_UDP_CPP = ${PLATFORM_SOCKET_UDP}.cpp SOCKET_UDP_O = ${PLATFORM_SOCKET_UDP}.o SOCKET_STREAM_H = ${ROOT_PATH}/minorGems/network/SocketStream.h NETWORK_FUNCTION_LOCKS = ${ROOT_PATH}/minorGems/network/NetworkFunctionLocks NETWORK_FUNCTION_LOCKS_H = ${NETWORK_FUNCTION_LOCKS}.h NETWORK_FUNCTION_LOCKS_CPP = ${NETWORK_FUNCTION_LOCKS}.cpp NETWORK_FUNCTION_LOCKS_O = ${NETWORK_FUNCTION_LOCKS}.o SOCKET_MANAGER = ${ROOT_PATH}/minorGems/network/SocketManager SOCKET_MANAGER_H = ${SOCKET_MANAGER}.h SOCKET_MANAGER_CPP = ${SOCKET_MANAGER}.cpp SOCKET_MANAGER_O = ${SOCKET_MANAGER}.o PATH_H = ${ROOT_PATH}/minorGems/io/file/Path.h PATH_CPP = ${ROOT_PATH}/minorGems/io/file/${PLATFORM_PATH}/Path${PLATFORM}.cpp PATH_O = ${ROOT_PATH}/minorGems/io/file/${PLATFORM_PATH}/Path${PLATFORM}.o FILE_H = ${ROOT_PATH}/minorGems/io/file/File.h FILE_OUTPUT_STREAM_H = ${ROOT_PATH}/minorGems/io/file/FileOutputStream.h FILE_INPUT_STREAM_H = ${ROOT_PATH}/minorGems/io/file/FileInputStream.h DIRECTORY_H = ${ROOT_PATH}/minorGems/io/file/Directory.h DIRECTORY_CPP = ${PLATFORM_DIRECTORY}.cpp DIRECTORY_O = ${PLATFORM_DIRECTORY}.o TYPE_IO_H = ${ROOT_PATH}/minorGems/io/TypeIO.h TYPE_IO_CPP = ${PLATFORM_TYPE_IO}.cpp TYPE_IO_O = ${PLATFORM_TYPE_IO}.o TIME_H = ${ROOT_PATH}/minorGems/system/Time.h TIME_CPP = ${PLATFORM_TIME}.cpp TIME_O = ${PLATFORM_TIME}.o THREAD_H = ${ROOT_PATH}/minorGems/system/Thread.h THREAD_CPP = ${PLATFORM_THREAD}.cpp THREAD_O = ${PLATFORM_THREAD}.o MUTEX_LOCK_H = ${ROOT_PATH}/minorGems/system/MutexLock.h MUTEX_LOCK_CPP = ${PLATFORM_MUTEX_LOCK}.cpp MUTEX_LOCK_O = ${PLATFORM_MUTEX_LOCK}.o BINARY_SEMAPHORE_H = ${ROOT_PATH}/minorGems/system/BinarySemaphore.h BINARY_SEMAPHORE_CPP = ${PLATFORM_BINARY_SEMAPHORE}.cpp BINARY_SEMAPHORE_O = ${PLATFORM_BINARY_SEMAPHORE}.o SEMAPHORE_H = ${ROOT_PATH}/minorGems/system/Semaphore.h APP_LOG_H = ${ROOT_PATH}/minorGems/util/log/AppLog.h APP_LOG_CPP = ${ROOT_PATH}/minorGems/util/log/AppLog.cpp APP_LOG_O = ${ROOT_PATH}/minorGems/util/log/AppLog.o PRINT_LOG_H = ${ROOT_PATH}/minorGems/util/log/PrintLog.h PRINT_LOG_CPP = ${ROOT_PATH}/minorGems/util/log/PrintLog.cpp PRINT_LOG_O = ${ROOT_PATH}/minorGems/util/log/PrintLog.o FILE_LOG_H = ${ROOT_PATH}/minorGems/util/log/FileLog.h FILE_LOG_CPP = ${ROOT_PATH}/minorGems/util/log/FileLog.cpp FILE_LOG_O = ${ROOT_PATH}/minorGems/util/log/FileLog.o LOG_H = ${ROOT_PATH}/minorGems/util/log/Log.h LOG_CPP = ${ROOT_PATH}/minorGems/util/log/Log.cpp LOG_O = ${ROOT_PATH}/minorGems/util/log/Log.o PRINT_UTILS_H = ${ROOT_PATH}/minorGems/util/printUtils.h PRINT_UTILS_CPP = ${ROOT_PATH}/minorGems/util/printUtils.cpp PRINT_UTILS_O = ${ROOT_PATH}/minorGems/util/printUtils.o WEB_CLIENT_H = ${ROOT_PATH}/minorGems/network/web/WebClient.h WEB_CLIENT_CPP = ${ROOT_PATH}/minorGems/network/web/WebClient.cpp WEB_CLIENT_O = ${ROOT_PATH}/minorGems/network/web/WebClient.o URL_UTILS_H = ${ROOT_PATH}/minorGems/network/web/URLUtils.h URL_UTILS_CPP = ${ROOT_PATH}/minorGems/network/web/URLUtils.cpp URL_UTILS_O = ${ROOT_PATH}/minorGems/network/web/URLUtils.o MIME_TYPER = ${ROOT_PATH}/minorGems/network/web/MimeTyper MIME_TYPER_H = ${MIME_TYPER}.h MIME_TYPER_CPP = ${MIME_TYPER}.cpp MIME_TYPER_O = ${MIME_TYPER}.o WEB_SERVER_PATH = ${ROOT_PATH}/minorGems/network/web/server WEB_SERVER = ${WEB_SERVER_PATH}/WebServer WEB_SERVER_H = ${WEB_SERVER}.h WEB_SERVER_CPP = ${WEB_SERVER}.cpp WEB_SERVER_O = ${WEB_SERVER}.o REQUEST_HANDLING_THREAD = ${WEB_SERVER_PATH}/RequestHandlingThread REQUEST_HANDLING_THREAD_H = ${REQUEST_HANDLING_THREAD}.h REQUEST_HANDLING_THREAD_CPP = ${REQUEST_HANDLING_THREAD}.cpp REQUEST_HANDLING_THREAD_O = ${REQUEST_HANDLING_THREAD}.o THREAD_HANDLING_THREAD = ${WEB_SERVER_PATH}/ThreadHandlingThread THREAD_HANDLING_THREAD_H = ${THREAD_HANDLING_THREAD}.h THREAD_HANDLING_THREAD_CPP = ${THREAD_HANDLING_THREAD}.cpp THREAD_HANDLING_THREAD_O = ${THREAD_HANDLING_THREAD}.o CONNECTION_PERMISSION_HANDLER = ${WEB_SERVER_PATH}/ConnectionPermissionHandler CONNECTION_PERMISSION_HANDLER_H = ${CONNECTION_PERMISSION_HANDLER}.h CONNECTION_PERMISSION_HANDLER_CPP = ${CONNECTION_PERMISSION_HANDLER}.cpp CONNECTION_PERMISSION_HANDLER_O = ${CONNECTION_PERMISSION_HANDLER}.o STOP_SIGNAL_THREAD = ${ROOT_PATH}/minorGems/system/StopSignalThread STOP_SIGNAL_THREAD_H = ${STOP_SIGNAL_THREAD}.h STOP_SIGNAL_THREAD_CPP = ${STOP_SIGNAL_THREAD}.cpp STOP_SIGNAL_THREAD_O = ${STOP_SIGNAL_THREAD}.o FINISHED_SIGNAL_THREAD = ${ROOT_PATH}/minorGems/system/FinishedSignalThread FINISHED_SIGNAL_THREAD_H = ${FINISHED_SIGNAL_THREAD}.h FINISHED_SIGNAL_THREAD_CPP = ${FINISHED_SIGNAL_THREAD}.cpp FINISHED_SIGNAL_THREAD_O = ${FINISHED_SIGNAL_THREAD}.o FINISHED_SIGNAL_THREAD_MANAGER = ${ROOT_PATH}/minorGems/system/FinishedSignalThreadManager FINISHED_SIGNAL_THREAD_MANAGER_H = ${FINISHED_SIGNAL_THREAD_MANAGER}.h FINISHED_SIGNAL_THREAD_MANAGER_CPP = ${FINISHED_SIGNAL_THREAD_MANAGER}.cpp FINISHED_SIGNAL_THREAD_MANAGER_O = ${FINISHED_SIGNAL_THREAD_MANAGER}.o STRING_BUFFER_OUTPUT_STREAM_H = ${ROOT_PATH}/minorGems/util/StringBufferOutputStream.h STRING_BUFFER_OUTPUT_STREAM_CPP = ${ROOT_PATH}/minorGems/util/StringBufferOutputStream.cpp STRING_BUFFER_OUTPUT_STREAM_O = ${ROOT_PATH}/minorGems/util/StringBufferOutputStream.o XML_UTILS_H = ${ROOT_PATH}/minorGems/formats/xml/XMLUtils.h XML_UTILS_CPP = ${ROOT_PATH}/minorGems/formats/xml/XMLUtils.cpp XML_UTILS_O = ${ROOT_PATH}/minorGems/formats/xml/XMLUtils.o HTML_UTILS_H = ${ROOT_PATH}/minorGems/formats/html/HTMLUtils.h HTML_UTILS_CPP = ${ROOT_PATH}/minorGems/formats/html/HTMLUtils.cpp HTML_UTILS_O = ${ROOT_PATH}/minorGems/formats/html/HTMLUtils.o SETTINGS_MANAGER_H = ${ROOT_PATH}/minorGems/util/SettingsManager.h SETTINGS_MANAGER_CPP = ${ROOT_PATH}/minorGems/util/SettingsManager.cpp SETTINGS_MANAGER_O = ${ROOT_PATH}/minorGems/util/SettingsManager.o TRANSLATION_MANAGER_H = ${ROOT_PATH}/minorGems/util/TranslationManager.h TRANSLATION_MANAGER_CPP = ${ROOT_PATH}/minorGems/util/TranslationManager.cpp TRANSLATION_MANAGER_O = ${ROOT_PATH}/minorGems/util/TranslationManager.o STRING_UTILS = ${ROOT_PATH}/minorGems/util/stringUtils STRING_UTILS_H = ${STRING_UTILS}.h STRING_UTILS_CPP = ${STRING_UTILS}.cpp STRING_UTILS_O = ${STRING_UTILS}.o SHA1 = ${ROOT_PATH}/minorGems/crypto/hashes/sha1 SHA1_H = ${SHA1}.h SHA1_CPP = ${SHA1}.cpp SHA1_O = ${SHA1}.o MEMORY_TRACK_H = ${ROOT_PATH}/minorGems/util/development/memory/MemoryTrack.h MEMORY_TRACK_CPP = ${ROOT_PATH}/minorGems/util/development/memory/MemoryTrack.cpp MEMORY_TRACK_O = ${ROOT_PATH}/minorGems/util/development/memory/MemoryTrack.o DEBUG_MEMORY = ${ROOT_PATH}/minorGems/util/development/memory/debugMemory DEBUG_MEMORY_H = ${DEBUG_MEMORY}.h DEBUG_MEMORY_CPP = ${DEBUG_MEMORY}.cpp DEBUG_MEMORY_O = ${DEBUG_MEMORY}.o # variable pointing to both necessary .o files for memory tracking MEMORY_TRACKER_O = ${MEMORY_TRACK_O} ${DEBUG_MEMORY_O} # p2p parts HOST_CATCHER = ${ROOT_PATH}/minorGems/network/p2pParts/HostCatcher HOST_CATCHER_H = ${HOST_CATCHER}.h HOST_CATCHER_CPP = ${HOST_CATCHER}.cpp HOST_CATCHER_O = ${HOST_CATCHER}.o OUTBOUND_CHANNEL = ${ROOT_PATH}/minorGems/network/p2pParts/OutboundChannel OUTBOUND_CHANNEL_H = ${OUTBOUND_CHANNEL}.h OUTBOUND_CHANNEL_CPP = ${OUTBOUND_CHANNEL}.cpp OUTBOUND_CHANNEL_O = ${OUTBOUND_CHANNEL}.o DUPLICATE_MESSAGE_DETECTOR = ${ROOT_PATH}/minorGems/network/p2pParts/DuplicateMessageDetector DUPLICATE_MESSAGE_DETECTOR_H = ${DUPLICATE_MESSAGE_DETECTOR}.h DUPLICATE_MESSAGE_DETECTOR_CPP = ${DUPLICATE_MESSAGE_DETECTOR}.cpp DUPLICATE_MESSAGE_DETECTOR_O = ${DUPLICATE_MESSAGE_DETECTOR}.o PROTOCOL_UTILS = ${ROOT_PATH}/minorGems/network/p2pParts/protocolUtils PROTOCOL_UTILS_H = ${PROTOCOL_UTILS}.h PROTOCOL_UTILS_CPP = ${PROTOCOL_UTILS}.cpp PROTOCOL_UTILS_O = ${PROTOCOL_UTILS}.o MESSAGE_PER_SECOND_LIMITER = ${ROOT_PATH}/minorGems/network/p2pParts/MessagePerSecondLimiter MESSAGE_PER_SECOND_LIMITER_H = ${MESSAGE_PER_SECOND_LIMITER}.h MESSAGE_PER_SECOND_LIMITER_CPP = ${MESSAGE_PER_SECOND_LIMITER}.cpp MESSAGE_PER_SECOND_LIMITER_O = ${MESSAGE_PER_SECOND_LIMITER}.o MULTI_SOURCE_DOWNLOADER = ${ROOT_PATH}/minorGems/network/p2pParts/MultiSourceDownloader MULTI_SOURCE_DOWNLOADER_H = ${MULTI_SOURCE_DOWNLOADER}.h MULTI_SOURCE_DOWNLOADER_CPP = ${MULTI_SOURCE_DOWNLOADER}.cpp MULTI_SOURCE_DOWNLOADER_O = ${MULTI_SOURCE_DOWNLOADER}.o ENCODING_UTILS = ${ROOT_PATH}/minorGems/formats/encodingUtils ENCODING_UTILS_H = ${ENCODING_UTILS}.h ENCODING_UTILS_CPP = ${ENCODING_UTILS}.cpp ENCODING_UTILS_O = ${ENCODING_UTILS}.o SCREEN_GL = ${ROOT_PATH}/minorGems/graphics/openGL/ScreenGL SCREEN_GL_H = ${SCREEN_GL}.h SCREEN_GL_CPP = ${SCREEN_GL}.cpp SCREEN_GL_O = ${SCREEN_GL}.o SINGLE_TEXTURE_GL = ${ROOT_PATH}/minorGems/graphics/openGL/SingleTextureGL SINGLE_TEXTURE_GL_H = ${SINGLE_TEXTURE_GL}.h SINGLE_TEXTURE_GL_CPP = ${SINGLE_TEXTURE_GL}.cpp SINGLE_TEXTURE_GL_O = ${SINGLE_TEXTURE_GL}.o PNG_IMAGE_CONVERTER = ${ROOT_PATH}/minorGems/graphics/converters/PNGImageConverter PNG_IMAGE_CONVERTER_H = ${PNG_IMAGE_CONVERTER}.h PNG_IMAGE_CONVERTER_CPP = ${PNG_IMAGE_CONVERTER}.cpp PNG_IMAGE_CONVERTER_O = ${PNG_IMAGE_CONVERTER}.ogravitation-3+dfsg1.orig/minorGems/build/Makefile.minorGems_targets0000644000175000017500000001405510762704566024351 0ustar pabspabs# # Modification History # # 2004-November-19 Jason Rohrer # Copied from Primrose source. # # 2004-November-21 Jason Rohrer # Added multi-source downloader. # # 2004-December-13 Jason Rohrer # Added socket manager. # # 2005-February-4 Jason Rohrer # Added ScreenGL. # # 2005-February-21 Jason Rohrer # Added SingleTextureGL. # # 2006-April-24 Jason Rohrer # Added conditional compilation of files that depend on OpenGL/GLUT. # # 2006-November-21 Jason Rohrer # Added PNGImageConverter. # # 2007-April-23 Jason Rohrer # Changed to make compilation of all objects individually conditional using # NEEDED_MINOR_GEMS_OBJECTS variable. # ## # The common portion of Makefiles for all targets that use minorGems, # supplying target dependencies for minorGems targets. # # # Should not be made manually---used by project-specific configure scripts to # build Makefiles. ## # Makefile Usage (these must be in your Makefile in the following order): # -- Include Makefile.minorGems # -- List the desired minorGems objects in NEEDED_MINOR_GEMS_OBJECTS # Example: # NEEDED_MINOR_GEMS_OBJECTS = \ # ${SOCKET_O} \ # ${SOCKET_CLIENT_O} \ # ${SOCKET_SERVER_O} \ # ${HOST_ADDRESS_O} # -- Define your project-specific targets and rules # -- Include this file ## # Dependencies for minorGems objects. ## # first, take the object list and turn it into a source list MINOR_GEMS_SOURCE = ${NEEDED_MINOR_GEMS_OBJECTS:.o=.cpp} # Here is what the old, manual list looked like, for reference: # # MINOR_GEMS_SOURCE = \ # ${HOST_ADDRESS_CPP} \ # ${SOCKET_CPP} \ # ${SOCKET_SERVER_CPP} \ # ${SOCKET_CLIENT_CPP} \ # ${SOCKET_UDP_CPP} \ # ${NETWORK_FUNCTION_LOCKS_CPP} \ # ${SOCKET_MANAGER_CPP} \ # ${PATH_CPP} \ # ${DIRECTORY_CPP} \ # ${TYPE_IO_CPP} \ # ${TIME_CPP} \ # ${THREAD_CPP} \ # ${MUTEX_LOCK_CPP} \ # ${BINARY_SEMAPHORE_CPP} \ # ${APP_LOG_CPP} \ # ${PRINT_LOG_CPP} \ # ${FILE_LOG_CPP} \ # ${LOG_CPP} \ # ${PRINT_UTILS_CPP} \ # ${WEB_CLIENT_CPP} \ # ${URL_UTILS_CPP} \ # ${MIME_TYPER_CPP} \ # ${STRING_BUFFER_OUTPUT_STREAM_CPP} \ # ${XML_UTILS_CPP} \ # ${HTML_UTILS_CPP} \ # ${SETTINGS_MANAGER_CPP} \ # ${TRANSLATION_MANAGER_CPP} \ # ${STRING_UTILS_CPP} \ # ${SHA1_CPP} \ # ${MEMORY_TRACK_CPP} \ # ${DEBUG_MEMORY_CPP} \ # ${HOST_CATCHER_CPP} \ # ${OUTBOUND_CHANNEL_CPP} \ # ${DUPLICATE_MESSAGE_DETECTOR_CPP} \ # ${PROTOCOL_UTILS_CPP} \ # ${MESSAGE_PER_SECOND_LIMITER_CPP} \ # ${MULTI_SOURCE_DOWNLOADER_CPP} \ # ${ENCODING_UTILS_CPP} \ # ${WEB_SERVER_CPP} \ # ${REQUEST_HANDLING_THREAD_CPP} \ # ${THREAD_HANDLING_THREAD_CPP} \ # ${CONNECTION_PERMISSION_HANDLER_CPP} \ # ${STOP_SIGNAL_THREAD_CPP} \ # ${FINISHED_SIGNAL_THREAD_CPP} \ # ${FINISHED_SIGNAL_THREAD_MANAGER_CPP} \ # ${OPEN_GL_CPP_FILES} \ # ${PNG_IMAGE_CONVERTER_CPP} # next, generate dependencies using g++ # sed command for fixing up the dependencies generated by g++ # g++ (pre-3.0) leaves the path off of the .o target # look for a .o file at the beginning of a line (in other words, one # without a path), and replace it with the full-path version. # This should be compatible with g++ 3.0, since we only replace .o names # that occur at the beginning of a line (using the "^" modifier) # Split into two parts because sed (on certain platforms) cannot process # a string of commands as one long argument MINOR_GEMS_SED_FIX_COMMAND_A = sed ' \ s/^HostAddress.*\.o/$${HOST_ADDRESS_O}/; \ s/^SocketServer.*\.o/$${SOCKET_SERVER_O}/; \ s/^SocketClient.*\.o/$${SOCKET_CLIENT_O}/; \ s/^SocketUDP.*\.o/$${SOCKET_UDP_O}/; \ s/^SocketManager.*\.o/$${SOCKET_MANAGER_O}/; \ s/^Socket.*\.o/$${SOCKET_O}/; \ s/^NetworkFunctionLocks.*\.o/$${NETWORK_FUNCTION_LOCKS_O}/; \ s/^Path.*\.o/$${PATH_O}/; \ s/^Directory.*\.o/$${DIRECTORY_O}/; \ s/^TypeIO.*\.o/$${TYPE_IO_O}/; \ s/^Time.*\.o/$${TIME_O}/; \ s/^MutexLock.*\.o/$${MUTEX_LOCK_O}/; \ s/^BinarySemaphore.*\.o/$${BINARY_SEMAPHORE_O}/; \ s/^AppLog.*\.o/$${APP_LOG_O}/; \ s/^PrintLog.*\.o/$${PRINT_LOG_O}/; \ s/^FileLog.*\.o/$${FILE_LOG_O}/; \ s/^Log.*\.o/$${LOG_O}/; \ s/^PrintUtils.*\.o/$${PRINT_UTILS_O}/; \ s/^WebClient.*\.o/$${WEB_CLIENT_O}/; \ s/^URLUtils.*\.o/$${URL_UTILS_O}/; \ s/^MimeTyper.*\.o/$${MIME_TYPER_O}/; \ s/^StringBufferOutputStream.*\.o/$${STRING_BUFFER_OUTPUT_STREAM_O}/; \ s/^XMLUtils.*\.o/$${XML_UTILS_O}/; \ s/^HTMLUtils.*\.o/$${HTML_UTILS_O}/; \ s/^SettingsManager.*\.o/$${SETTINGS_MANAGER_O}/; \ s/^TranslationManager.*\.o/$${TRANSLATION_MANAGER_O}/; \ s/^stringUtils.*\.o/$${STRING_UTILS_O}/; \ s/^sha1.*\.o/$${SHA1_O}/; \ ' MINOR_GEMS_SED_FIX_COMMAND_B = sed ' \ s/^MemoryTrack.*\.o/$${MEMORY_TRACK_O}/; \ s/^DebugMemory.*\.o/$${DEBUG_MEMORY_O}/; \ s/^HostCatcher.*\.o/$${HOST_CATCHER_O}/; \ s/^OutboundChannel.*\.o/$${OUTBOUND_CHANNEL_O}/; \ s/^DuplicateMessageDetector.*\.o/$${DUPLICATE_MESSAGE_DETECTOR_O}/; \ s/^protocolUtils.*\.o/$${PROTOCOL_UTILS_O}/; \ s/^MessagePerSecondLimiter.*\.o/$${MESSAGE_PER_SECOND_LIMITER_O}/; \ s/^MultiSourceDownloader.*\.o/$${MULTI_SOURCE_DOWNLOADER_O}/; \ s/^encodingUtils.*\.o/$${ENCODING_UTILS_O}/; \ s/^WebServer.*\.o/$${WEB_SERVER_O }/; \ s/^RequestHandlingThread.*\.o/$${REQUEST_HANDLING_THREAD_O}/; \ s/^ThreadHandlingThread.*\.o/$${THREAD_HANDLING_THREAD_O}/; \ s/^Thread.*\.o/$${THREAD_O}/; \ s/^ConnectionPermissionHandler.*\.o/$${CONNECTION_PERMISSION_HANDLER_O}/; \ s/^StopSignalThread.*\.o/$${STOP_SIGNAL_THREAD_O}/; \ s/^FinishedSignalThreadManager.*\.o/$${FINISHED_SIGNAL_THREAD_MANAGER_O}/; \ s/^FinishedSignalThread.*\.o/$${FINISHED_SIGNAL_THREAD_O}/; \ s/^ScreenGL.*\.o/$${SCREEN_GL_O}/; \ s/^SingleTextureGL.*\.o/$${SINGLE_TEXTURE_GL_O}/; \ s/^PNGImageConverter.*\.o/$${PNG_IMAGE_CONVERTER_O}/; \ ' MINOR_GEMS_DEPENDENCY_FILE = Makefile.minorGems_dependencies # build the dependency file ${MINOR_GEMS_DEPENDENCY_FILE}: ${MINOR_GEMS_SOURCE} rm -f ${MINOR_GEMS_DEPENDENCY_FILE} ${COMPILE} -I${ROOT_PATH} -MM ${MINOR_GEMS_SOURCE} >> ${MINOR_GEMS_DEPENDENCY_FILE}.temp cat ${MINOR_GEMS_DEPENDENCY_FILE}.temp | ${MINOR_GEMS_SED_FIX_COMMAND_A} | ${MINOR_GEMS_SED_FIX_COMMAND_B} >> ${MINOR_GEMS_DEPENDENCY_FILE} rm -f ${MINOR_GEMS_DEPENDENCY_FILE}.temp include ${MINOR_GEMS_DEPENDENCY_FILE} gravitation-3+dfsg1.orig/minorGems/graphics/0000755000175000017500000000000010762704567017716 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/graphics/3d/0000755000175000017500000000000010762704567020224 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/graphics/3d/Object3DFactory.h0000644000175000017500000000645210762704567023331 0ustar pabspabs/* * Modification History * * 2001-March-14 Jason Rohrer * Created. * * 2001-March-17 Jason Rohrer * Finished implementation. * * 2001-April-1 Jason Rohrer * Fixed flag name. */ #ifndef OBJECT_3D_FACTORY_INCLUDED #define OBJECT_3D_FACTORY_INCLUDED #include "Object3D.h" // Run-time type identification interface (RTTI) #include // include these objects only if we are part of subreal #ifdef SUBREAL #include "subreal/entity/EntityObject3D.h" #define FACTORY_ENTITY_OBJECT_FLAG 1 #endif // the default flag #define FACTORY_DEFAULT_OBJECT_FLAG 0 /** * Class that maps Object3D integer subclass type flags to Object3D * subclass instances. * * Motivation for this class: * We have Object3D instances that exist simultaneously on opposite * sides of the network (at both the client and server ends). Initially, * we just let the objects get sent to the server via the base class * Object3D serialization function. At that time, subclasses of Object3D * did nothing more than init an Object3D in a particular way. This * worked fine when we didn't have animations associated with various * Object3D subclasses, but doesn't work now that we have animation * code in various subclasses. During serialization (if the object * is sent as a generic Object3D), the animation code is lost on * the client end. We need a way for the client to pick the correct * subclass to construct for deserialization. We can encode the * various subtypes by integers, and then this factory class can * be used to construct a class of appropriate subtype before * deserialization. * * @author Jason Rohrer */ class Object3DFactory { public: /** * Finds an integer subclass type flag for an object instance. * * @param inObject the object to determine a flag for. Must * be destroyed by the caller. * * @return a type flag for inObject. 0 (the defautl Object3D * baseclass flag) will be returned if subclass determination fails. */ static int object3DToInt( Object3D *inObject ); /** * Constructs a new, unitialized Object3D (in other words, * an Object3D ready for deserialization) of a subclass * type matching inTypeFlag. * * @param inTypeFlag the type flag specifying the class * of the returned object. * * @return an (unitialized) Object3D class instance with a * subclass type corresponding to inTypeFlag. If no * matching class is found, a default Object3D baseclass * instance is returned. Must be destroyed by the caller. */ static Object3D *intToObject3D( int inTypeFlag ); }; inline int Object3DFactory::object3DToInt( Object3D *inObject ) { // use RTTI to determine type of inObject #ifdef SUBREAL if( typeid( *inObject ) == typeid( EntityObject3D ) ) { return FACTORY_ENTITY_OBJECT_FLAG; } #endif // else return the default flag return FACTORY_DEFAULT_OBJECT_FLAG; } inline Object3D *Object3DFactory::intToObject3D( int inTypeFlag ) { switch( inTypeFlag ) { case FACTORY_DEFAULT_OBJECT_FLAG: return new Object3D(); break; /* these objects are only defined if * we are part of subreal */ #ifdef SUBREAL case FACTORY_ENTITY_OBJECT_FLAG: return new EntityObject3D(); break; #endif default: // unknown object flag type return new Object3D(); break; } } #endif gravitation-3+dfsg1.orig/minorGems/graphics/3d/LandscapePrimitive3D.h0000644000175000017500000000776710762704567024370 0ustar pabspabs/* * Modification History * * 2001-January-9 Jason Rohrer * Created. Copied from LandscapePrimitiveGL, which this class will replace * * 2001-January-15 Jason Rohrer * Fixed a bug in the constructor. * * 2001-January-17 Jason Rohrer * Fliped how x and y in height map correspond to x and z in the terrain. * * 2001-January-19 Jason Rohrer * Changed to support multi-texturing. * * 2001-January-30 Jason Rohrer * Fixed a bug that occurs when the class defaults to no detail texture. * * 2001-March-11 Jason Rohrer * Fixed a bug in the texture map anchor points. */ #ifndef LANDSCAPE_PRIMITIVE_3D_INCLUDED #define LANDSCAPE_PRIMITIVE_3D_INCLUDED #include "Primitive3D.h" /** * Primitive 3D lanscape object. * * Made from a height map. Mesh generated spans both x and z between -1 and * 1, and can vary in height (y) from 0 to 1. * * @author Jason Rohrer */ class LandscapePrimitive3D : public Primitive3D { public: /** * Constructs a LandscapePrimitive with a multi-layer texture. * * @param inWide width of mesh in number of vertices. * Must be even and at least 2. * @param inHigh height of mesh in number of vertices. * @param inHeights array of heights for each vertex, each in * [0,1]. Must be destroyed by caller. * @param inTexture the texture to map onto the lanscape. * Texture is anchored by its corners to the corners of the * lanscape. inTexture is destroyed when primitive is destroyed. * @param inDetailTexture the second layer in the multi-texture. * The alpha channel of inDetailTexture will be used as * the blending factor to mix the detail with the global texture. * Set to NULL to use only a single layer. * @param inDetailScale the scale factor of the detailed texture. * Setting to 1.0 will anchor the detail at the corners of the * mesh (just like inTexture). Setting to 0.25 will cause * the detail texture to cycle 4 times across the surface of the * mesh. */ LandscapePrimitive3D( int inWide, int inHigh, double *inHeights, RGBAImage *inTexture, RGBAImage *inDetailTexture = NULL, double inDetailScale = 1.0 ); }; inline LandscapePrimitive3D::LandscapePrimitive3D( int inWide, int inHigh, double *inHeights, RGBAImage *inTexture, RGBAImage *inDetailTexture, double inDetailScale ) { // first, set Primitve3D members mHigh = inHigh; mWide = inWide; mNumVertices = mHigh * mWide; if( inDetailTexture == NULL ) { mNumTextures = 1; mTexture = new RGBAImage*[1]; mTexture[0] = inTexture; mAnchorX = new double*[1]; mAnchorY = new double*[1]; mAnchorX[0] = new double[mNumVertices]; mAnchorY[0] = new double[mNumVertices]; } else { mNumTextures = 2; mTexture = new RGBAImage*[2]; mTexture[0] = inTexture; mTexture[1] = inDetailTexture; mAnchorX = new double*[2]; mAnchorY = new double*[2]; mAnchorX[0] = new double[mNumVertices]; mAnchorY[0] = new double[mNumVertices]; mAnchorX[1] = new double[mNumVertices]; mAnchorY[1] = new double[mNumVertices]; } mVertices = new Vector3D*[mNumVertices]; // anchor at texture corners, and step linearly through texture double anchorYStep = 1.0 / ( mHigh - 1 ); double anchorXStep = 1.0 / ( mWide - 1 ); double detailAnchorYStep = 1.0 / ( ( mHigh - 1 ) * inDetailScale ); double detailAnchorXStep = 1.0 / ( ( mWide - 1 ) * inDetailScale ); for( int y=0; ymNumPrimitives = mNumPrimitives; objCopy->mPrimitives = new Primitive3D*[ mNumPrimitives ]; objCopy->mTransform = new Transform3D*[ mNumPrimitives ]; int i; for( i=0; imPrimitives[i] = mPrimitives[i]->copy(); objCopy->mTransform[i] = new Transform3D( mTransform[i] ); } objCopy->mMembersAllocated = true; return objCopy; } inline int Object3D::getNumParameters() { return 0; } inline int Object3D::getNumAnimations() { return 0; } // the base class versions of these functions do nothing inline void Object3D::setParameter( int inParameterIndex, double inValue ) { } inline double Object3D::getParameter( int inParameterIndex ) { return 0; } inline void Object3D::step( double inStepSize ) { } inline void Object3D::startAnimation( int inAnimationIndex ) { } inline void Object3D::stopAnimation( int inAnimationIndex ) { } inline int Object3D::serialize( OutputStream *inOutputStream ) { int i; int numBytes = 0; numBytes += inOutputStream->writeLong( mNumPrimitives ); // write each primitive for( i=0; iwriteLong( typeFlag ); // write the primitive numBytes += mPrimitives[i]->serialize( inOutputStream ); } // write each primitive's transform for( i=0; iserialize( inOutputStream ); } return numBytes; } inline int Object3D::deserialize( InputStream *inInputStream ) { if( mMembersAllocated ) { // first, delete current contents of object for( int i=0; ireadLong( &mNumPrimitives ); printf( "receiving %d primitives\n", mNumPrimitives ); mPrimitives = new Primitive3D*[mNumPrimitives]; for( i=0; ireadLong( &typeFlag ); // construct a new object based on the type flag mPrimitives[i] = Primitive3DFactory::intToPrimitive3D( typeFlag ); // deserialize it numBytes += mPrimitives[i]->deserialize( inInputStream ); } mTransform = new Transform3D*[mNumPrimitives]; for( i=0; ideserialize( inInputStream ); } mMembersAllocated = true; return numBytes; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/3d/LathePrimitive3D.h0000644000175000017500000000650610762704567023521 0ustar pabspabs/* * Modification History * * 2001-January-9 Jason Rohrer * Created. Copied from LathePrimitiveGL, which this class will replace. * * 2001-January-19 Jason Rohrer * Changed to support multi-texturing internally, though this primitive * type doesn't use it. * * 2001-January-21 Jason Rohrer * Fixed a bug in the constructor. * * 2001-January-31 Jason Rohrer * Got rid of an unused variable. * * 2001-March-11 Jason Rohrer * Fixed a bug in the texture map anchor points. */ #ifndef LATHE_PRIMITIVE_3D_INCLUDED #define LATHE_PRIMITIVE_3D_INCLUDED #include "Primitive3D.h" /** * Primitive 3D lathe object. * * Made of a curve rotated around an axis. * * @author Jason Rohrer */ class LathePrimitive3D : public Primitive3D { public: /** * Constructs a LathePrimitive. The lathe curve is rotated * about the y axis. * * No parameters are copied, so they should not be destroyed * or re-accessed by caller. All are destroyed when the * primitive is destroyed. * * @param inNumCurvePoints number of points in curve to be lathed. * @param inCurvePoints points to be lathed. All z components * are set to 0 before lathing, so only x and y values matter. * @param inNumLatheSteps the number of quad segments around * the circumference of the lathed object. For example, * setting to 4 (with a lathe angle of 2pi) * will produce an extruded square object. * @param inNetLatheAngle total angle to sweep during lathing, * in (0,2pi]. * @param inTexture the texture to map onto the lathed object. * Texture is anchored by its corners to the ends of the lath * curve at the beginning and end of the lathe sweep */ LathePrimitive3D( int inNumCurvePoints, Vector3D **inCurvePoints, int inNumLatheSteps, double inNetLatheAngle, RGBAImage *inTexture ); }; inline LathePrimitive3D::LathePrimitive3D( int inNumCurvePoints, Vector3D **inCurvePoints, int inNumLatheSteps, double inNetLatheAngle, RGBAImage *inTexture ) { // first, set Primitve3D members mHigh = inNumCurvePoints; mWide = inNumLatheSteps + 1; mNumVertices = mHigh * mWide; mNumTextures = 1; mTexture = new RGBAImage*[1]; mTexture[0] = inTexture; double stepAngle = inNetLatheAngle / inNumLatheSteps; int i; // first, set all z values for control points to 0 for( i=0; imZ = 0; } mVertices = new Vector3D*[mNumVertices]; mAnchorX = new double*[1]; mAnchorY = new double*[1]; mAnchorX[0] = new double[mNumVertices]; mAnchorY[0] = new double[mNumVertices]; // anchor at texture corners, and step linearly through texture double anchorYStep = 1.0 / ( mHigh - 1 ); double anchorXStep = 1.0 / ( mWide - 1 ); for( int y=0; yreverseRotate( latheRotation ); delete latheRotation; } // cleanup as we go along delete inCurvePoints[y]; } delete [] inCurvePoints; generateNormals(); } #endif gravitation-3+dfsg1.orig/minorGems/graphics/3d/Primitive3DFactory.h0000644000175000017500000000646210762704567024074 0ustar pabspabs/* * Modification History * * 2001-March-14 Jason Rohrer * Created. * * 2001-April-1 Jason Rohrer * Added subreal entity vane class to factory. */ #ifndef PRIMITIVE_3D_FACTORY_INCLUDED #define PRIMITIVE_3D_FACTORY_INCLUDED #include "Primitive3D.h" // Run-time type identification interface (RTTI) #include // include these primitives only if we are part of subreal #ifdef SUBREAL #include "subreal/entity/EntityBodyPrimitive3D.h" #define FACTORY_ENTITY_BODY_PRIMITIVE_FLAG 1 #include "subreal/entity/EntityVanePrimitive3D.h" #define FACTORY_ENTITY_VANE_PRIMITIVE_FLAG 2 #endif // the default flag #define FACTORY_DEFAULT_PRIMITIVE_FLAG 0 /** * Class that maps Primitive3D integer subclass type flags to Primitive3D * subclass instances. * * Motivation for this class: * We want to extend Object3D to support subclass typed serialization * and deserialization without placing too much of a burden on * future Object3D subclasses. For instance, we don't want subclasses * to have to write their own de/serialization functions so that * particular Primitive3D subclasses are serialized correctly. * We can avoid this burden by writing the base Object3D serialization * code so that it uses this factory to transmit subclasses with * type informaton. * * @author Jason Rohrer */ class Primitive3DFactory { public: /** * Finds an integer subclass type flag for a primitive instance. * * @param inPrimitive the primitive to determine a flag for. Must * be destroyed by the caller. * * @return a type flag for inObject. 0 (the default Object3D * baseclass flag) will be returned if subclass determination fails. */ static int primitive3DToInt( Primitive3D *inPrimitive ); /** * Constructs a new, unitialized Primitive3D (in other words, * an Primitive3D ready for deserialization) of a subclass * type matching inTypeFlag. * * @param inTypeFlag the type flag specifying the class * of the returned primitive. * * @return an (unitialized) Primitive3D class instance with a * subclass type corresponding to inTypeFlag. If no * matching class is found, a default Primitive3D baseclass * instance is returned. Must be destroyed by the caller. */ static Primitive3D *intToPrimitive3D( int inTypeFlag ); }; inline int Primitive3DFactory::primitive3DToInt( Primitive3D *inPrimitive ) { // use RTTI to determine type of inPrimitive #ifdef SUBREAL if( typeid( *inPrimitive ) == typeid( EntityBodyPrimitive3D ) ) { return FACTORY_ENTITY_BODY_PRIMITIVE_FLAG; } else if( typeid( *inPrimitive ) == typeid( EntityVanePrimitive3D ) ) { return FACTORY_ENTITY_VANE_PRIMITIVE_FLAG; } #endif // else return the default flag return FACTORY_DEFAULT_PRIMITIVE_FLAG; } inline Primitive3D *Primitive3DFactory::intToPrimitive3D( int inTypeFlag ) { switch( inTypeFlag ) { case FACTORY_DEFAULT_PRIMITIVE_FLAG: return new Primitive3D(); break; /* these primitives are only defined if * we are part of subreal */ #ifdef SUBREAL case FACTORY_ENTITY_BODY_PRIMITIVE_FLAG: return new EntityBodyPrimitive3D(); break; case FACTORY_ENTITY_VANE_PRIMITIVE_FLAG: return new EntityVanePrimitive3D(); break; #endif default: // unknown primitive flag type return new Primitive3D(); break; } } #endif gravitation-3+dfsg1.orig/minorGems/graphics/3d/Primitive3D.h0000644000175000017500000003677310762704567022554 0ustar pabspabs/* * Modification History * * 2001-January-9 Jason Rohrer * Created. * * 2001-January-10 Jason Rohrer * Made class serializable. * Added a mMembersAllocated flag and made parameterless constructor * public to help with deserialization. * * 2001-January-15 Jason Rohrer * Fixed a bug in the deserialize() function. * * 2001-January-16 Jason Rohrer * Fixed a bug in the anchor serialization code. * * 2001-January-19 Jason Rohrer * Changed to support multi-texturing. * * 2001-January-24 Jason Rohrer * Added a copy() function. * Fixed a bug in deserialize(). * Made mMembersAllocated public for copy function. * * 2001-February-3 Jason Rohrer * Updated serialization code to use new interfaces. * * 2001-March-11 Jason Rohrer * Added support for paramatization and temporal animations. * * 2001-March-13 Jason Rohrer * Added interface for getting the number of parameters and animations. * * 2001-April-1 Jason Rohrer * Made copy function virtual. Added a getNewInstance function * to make derived-class-specific copying easier. */ #ifndef PRIMITIVE_3D_INCLUDED #define PRIMITIVE_3D_INCLUDED #include #include "minorGems/graphics/RGBAImage.h" #include "minorGems/math/geometry/Angle3D.h" #include "minorGems/math/geometry/Vector3D.h" #include "minorGems/math/geometry/Angle3D.h" #include "minorGems/io/Serializable.h" /** * 3D primitive object. * * Comprised of a triangle mesh, texture map, and anchor points. * * @author Jason Rohrer */ class Primitive3D : public Serializable { public: /** * Constructs a Primitive. * * No parameters are copied, so they should not be destroyed * or re-accessed by caller. All are destroyed when the * primitive is destroyed. * * @param inWide width of mesh in number of vertices. * Must be even and at least 2. * @param inHigh height of mesh in number of vertices. * @param inVertices vertices in row-major order. * @param inNumTextures number of multi-texture layers for * this primitive. * @param inTexture array of textures to map onto mesh. * Note that no RGBAImage in this array should have a * selection in it. * @param inAnchorX x texture anchors for each texture and * each vertex (indexed as inAnchorX[textNum][vertNum]), * in range [0,1] (outside this range, texture will wrap). * @param inAnchorY y texture anchors for each texture and * each vertex (indexed as inAnchorY[textNum][vertNum]), * in range [0,1] (outside this range, texture will wrap). */ Primitive3D( long inWide, long inHigh, Vector3D **inVertices, long inNumTextures, RGBAImage **inTexture, double **inAnchorX, double **inAnchorY ); // construct without initializing any members // for use by subclasses and for deserialization. Primitive3D(); char mMembersAllocated; ~Primitive3D(); /** * Sets whether this primitive is transparent or not. Default * is not transparent. * * @param inTransparent true if this primitive is transparent. */ void setTransparent( char inTransparent ); /** * Gets whether this primitive is transparent or not. * * @return true iff this primitive is transparent. */ char isTransparent(); /** * Sets whether this primitive's back face is visible. Default * is not visible. * * @param inIsVisible true if the back face is visible. */ void setBackVisible( char inIsVisible ); /** * Gets whether this primitive's back face is visible or not. * * @return true iff the back face is visible. */ char isBackVisible(); /** * Gets a new instance of the derived class type. * * Should be equivalent to calling the default constructor * for the derived class type. * * Should be overridden by all derived classes that * have data members beyond those provided by Primitive3D. * Note that if the extra data members require copying, * then the copy() function should be overridden instead * of simply overriding this function. * * Primitive3D::copy() will use this function to produce * a class instance before doing a copy. * * Note that this functionality SHOULD be provided by * the built-in RTTI, but it doesn't seem to be. * * @return an instance of the derived class. */ virtual Primitive3D *getNewInstance(); /** * Copies this primitive. * * @return a copy of this primitive, which must be destroyed * by the caller. */ virtual Primitive3D *copy(); /** * Gets the number of parameters associated with this object. * * @return the number of parameters. */ virtual int getNumParameters(); /** * Gets the number of animations associated with this object. * * @return the number of animations. */ virtual int getNumAnimations(); /* * Note that the default implementations for all the parameter * and temporal animation functions do nothing. */ /** * Sets a parameter for this primative. * * @param inParameterIndex the index of the parameter to set. * If an index for a non-existing parameter is specified, * this call has no effect. * @param inValue the value to set the parameter to, in [-1, 1]. * The default value for all parameters is 0. */ virtual void setParameter( int inParameterIndex, double inValue ); /** * Gets a parameter for this primative. * * @param inParameterIndex the index of the parameter to get. * If an index for a non-existing parameter is specified, * 0 is returned. * * @return the value of the parameter, in [-1, 1]. * The default value for all parameters is 0. */ virtual double getParameter( int inParameterIndex ); /** * Steps this primitive forward in time. * * @param inStepSize the size of the timestep to take. */ virtual void step( double inStepSize ); /** * Starts a temporal animation of this primitive. * The animation progresses as step() is called repeatedly. * If called for a non-existent animation or for one that is * already running, this function has no effect. */ virtual void startAnimation( int inAnimationIndex ); /** * Stops a temporal animation of this primitive. If called * for a non-existent animation or for one that is not currently * running, this function has no effect. */ virtual void stopAnimation( int inAnimationIndex ); long mHigh, mWide; long mNumVertices; Vector3D **mVertices; Vector3D **mNormals; long mNumTextures; // Note that no RGBAImage in this array should have a // selection in it. RGBAImage **mTexture; double **mAnchorX; double **mAnchorY; // implement the Serializable interface virtual int serialize( OutputStream *inOutputStream ); virtual int deserialize( InputStream *inInputStream ); protected: /** * Generates standard normals from the vertices. * * If subclass is not generating normals, this * must be called before primitive is drawn, but after * the vertices have been initialized. */ void generateNormals(); char mTransparent; char mBackVisible; }; inline Primitive3D::Primitive3D( long inWide, long inHigh, Vector3D **inVertices, long inNumTextures, RGBAImage **inTexture, double **inAnchorX, double **inAnchorY ) : mHigh( inHigh ), mWide( inWide ), mNumVertices( inHigh * inWide ), mNumTextures( inNumTextures ), mVertices( inVertices ), mTexture( inTexture ), mAnchorX( inAnchorX ), mAnchorY( inAnchorY ), mTransparent( false ), mBackVisible( false ), mMembersAllocated( true ) { generateNormals(); } inline Primitive3D::Primitive3D() : mTransparent( false ), mBackVisible( false ), mMembersAllocated( false ) { } inline Primitive3D::~Primitive3D() { if( mMembersAllocated ) { int i; for( i=0; isubtract( mVertices[ index ] ); } } // now cross and add into sum for( e=0; e<4; e++ ) { if( edges[e] != NULL && edges[ (e+1) % 4 ] != NULL ) { // not that this order of crossing works // because our cross product is right handed Vector3D *normal = edges[e]->cross( edges[ (e+1) % 4 ] ); normal->normalize(); // add this normal to our sum normalSum->add( normal ); delete normal; } } // now delete edges for( e=0; e<4; e++ ) { if( edges[e] != NULL ) { delete edges[e]; } } delete [] edges; // save summed normal as normal for this point normalSum->normalize(); mNormals[index] = normalSum; } } } inline void Primitive3D::setTransparent( char inTransparent ) { mTransparent = inTransparent; } inline char Primitive3D::isTransparent() { return mTransparent; } inline void Primitive3D::setBackVisible( char inIsVisible ) { mBackVisible = inIsVisible; } inline char Primitive3D::isBackVisible() { return mBackVisible; } inline Primitive3D *Primitive3D::getNewInstance() { return new Primitive3D(); } inline Primitive3D *Primitive3D::copy() { // get an instance of the derived class, if they've // overridden getNewInstance() Primitive3D *primCopy = getNewInstance(); primCopy->mHigh = mHigh; primCopy->mWide = mWide; primCopy->mNumVertices = mNumVertices; primCopy->mVertices = new Vector3D*[mNumVertices]; primCopy->mNormals = new Vector3D*[mNumVertices]; int i; for( i=0; imVertices[i] = new Vector3D( mVertices[i] ); primCopy->mNormals[i] = new Vector3D( mNormals[i] ); } primCopy->mNumTextures = mNumTextures; primCopy->mTexture = new RGBAImage*[mNumTextures]; primCopy->mAnchorX = new double*[mNumTextures]; primCopy->mAnchorY = new double*[mNumTextures]; for( i=0; imTexture[i] = mTexture[i]->copy(); primCopy->mAnchorX[i] = new double[mNumVertices]; primCopy->mAnchorY[i] = new double[mNumVertices]; memcpy( primCopy->mAnchorX[i], mAnchorX[i], sizeof( double ) * mNumVertices ); memcpy( primCopy->mAnchorY[i], mAnchorY[i], sizeof( double ) * mNumVertices ); } primCopy->mMembersAllocated = true; primCopy->setBackVisible( isBackVisible() ); primCopy->setTransparent( isTransparent() ); return primCopy; } inline int Primitive3D::getNumParameters() { return 0; } inline int Primitive3D::getNumAnimations() { return 0; } // the base class versions of these functions do nothing inline void Primitive3D::setParameter( int inParameterIndex, double inValue ) { } inline double Primitive3D::getParameter( int inParameterIndex ) { return 0; } inline void Primitive3D::step( double inStepSize ) { } inline void Primitive3D::startAnimation( int inAnimationIndex ) { } inline void Primitive3D::stopAnimation( int inAnimationIndex ) { } inline int Primitive3D::serialize( OutputStream *inOutputStream ) { int numBytes = 0; numBytes += inOutputStream->writeLong( mWide ); numBytes += inOutputStream->writeLong( mHigh ); int i; // output vertices and normals for( i=0; iserialize( inOutputStream ); } for( i=0; iserialize( inOutputStream ); } numBytes += inOutputStream->writeLong( mNumTextures ); // output textures for( i=0; iserialize( inOutputStream ); } // output anchor arrays for( i=0; iwriteDouble( mAnchorX[i][p] ); } } for( i=0; iwriteDouble( mAnchorY[i][p] ); } } numBytes += inOutputStream->write( (unsigned char *)&mTransparent, 1 ); numBytes += inOutputStream->write( (unsigned char *)&mBackVisible, 1 ); return numBytes; } inline int Primitive3D::deserialize( InputStream *inInputStream ) { int numBytes = 0; int i; if( mMembersAllocated ) { // delete the old vertices, normals, and anchors for( i=0; ireadLong( &mWide ); numBytes += inInputStream->readLong( &mHigh ); mNumVertices = mHigh * mWide; mVertices = new Vector3D*[mNumVertices]; mNormals = new Vector3D*[mNumVertices]; // input vertices and normals for( i=0; ideserialize( inInputStream ); } for( i=0; ideserialize( inInputStream ); } // input number of textures numBytes += inInputStream->readLong( &mNumTextures ); mAnchorX = new double*[mNumTextures]; mAnchorY = new double*[mNumTextures]; mTexture = new RGBAImage*[mNumTextures]; // input textures for( i=0; ideserialize( inInputStream ); } // input anchor arrays for( i=0; ireadDouble( &( mAnchorX[i][p] ) ); } } for( i=0; ireadDouble( &( mAnchorY[i][p] ) ); } } numBytes += inInputStream->read( (unsigned char *)&mTransparent, 1 ); numBytes += inInputStream->read( (unsigned char *)&mBackVisible, 1 ); mMembersAllocated = true; return numBytesRead; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/mac/0000755000175000017500000000000010762704567020456 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/graphics/mac/graphixCommonDefs.h0000644000175000017500000000012510762704567024242 0ustar pabspabs// ALifeGUICommonDefs.h // common definitions for ALifeGui #define MAC_KEY_CODESgravitation-3+dfsg1.orig/minorGems/graphics/mac/graphixFramework.cpp0000644000175000017500000001727510762704567024516 0ustar pabspabs/** 32 bit DrawSprockets pluggable framework * * Jason Rohrer, 4-28-99 * * Mods: * Jason Rohrer 11-8-99 Changed to use GraphicBuffer object as screen buffer * Jason Rohrer 12-15-99 Added support for keyboard querying * Jason Rohrer 3-21-2000 Added support for mouse querying * */ #include #include #include // for keyboard events #include #include #include "swapBuffers.h" // interface for swapping buffers #include "getKey.h" // interface for getting key states #include "getMouse.h" // interface for getting mouse state //#include "ALifeGuiRunner.h" #include "GoGUIRunner.h" #include "GraphicBuffer.h" // Constants #define BallWidth 20 #define BallHeight 20 #define BobSize 8 /* Size of text in each ball */ //MT Tutorial #define rWindow 128 // resource ID number for window // Globals Rect windRect; WindowPtr w; DSpContextReference theContext; unsigned long *double_buffer = NULL; // the double buffer unsigned long *screen_buffer = NULL; GraphicBuffer *graphicDoubleBuffer; short bufferHigh = 480; short bufferWide = 640; // prototypes void Initialize(void); void graphixPicker(void); // our mother function, picks effect order, etc. void initVideo(DSpContextReference *theContext); void MyInitAttributes(DSpContextAttributes*); void CleanUp(DSpContextReference theContext); int main() { Initialize(); // setup a window MaxApplZone(); initVideo( &theContext ); // set up and switch video graphixPicker(); CleanUp( theContext); } void graphixPicker() { // our "mother function" // selects which effect to run next // graphix plug-in format: // myGraphix( bufferPtr, bufferHigh, bufferWide, colorBits, numFrames) // function can cll "swapBuffer32" internally whenever it needs the back buffer // sent to the screen. // jcrTorus( double_buffer, 480, 640, 32, 100); // jcrVoxels( double_buffer, 480, 640, 32, 230); // jcrTorus( double_buffer, 480, 640, 32, 50); //jcrBloom( double_buffer, 480, 640, 32, 100); // GraphicBuffer passed in contains all needed info about screen // pass in number of frames to run for //ALifeGuiRunner( *graphicDoubleBuffer, 1000 ); GoGUIRunner( *graphicDoubleBuffer, 0 ); } // Initialize the draw sprockets // set up the video, fade out display, and switch video modes void initVideo(DSpContextReference *theContext) { CGrafPtr backBuffer; PixMapHandle bufferMap; DSpContextAttributes theDesiredAttributes; OSStatus theError; MyInitAttributes(&theDesiredAttributes); theDesiredAttributes.displayWidth = 640; theDesiredAttributes.displayHeight = 480; theDesiredAttributes.colorNeeds = kDSpColorNeeds_Require; theDesiredAttributes.backBufferDepthMask = kDSpDepthMask_32; theDesiredAttributes.displayDepthMask = kDSpDepthMask_32; theDesiredAttributes.backBufferBestDepth = 32; theDesiredAttributes.displayBestDepth = 32; theError = DSpFindBestContext(&theDesiredAttributes, theContext); // add page flipping by video card to request theDesiredAttributes.contextOptions |= kDSpContextOption_PageFlip; //theDesiredAttributes.contextOptions |= kDSpContextOption_DontSyncVBL; // Reserver a display theError = DSpContext_Reserve(*theContext, &theDesiredAttributes); // fade out theError = DSpContext_FadeGammaOut(NULL, NULL); theError = DSpContext_SetState(*theContext, kDSpContextState_Active); ShowCursor(); HideCursor(); // setup global pointers to screen and back buffer theError = DSpContext_GetBackBuffer(*theContext, kDSpBufferKind_Normal, &backBuffer); bufferMap = (PixMapHandle)GetGWorldPixMap(backBuffer); double_buffer = (unsigned long*)(**bufferMap).baseAddr; // create GraphicBuffer object graphicDoubleBuffer = new GraphicBuffer( double_buffer, 640, 480 ); theError = DSpContext_GetFrontBuffer(*theContext, &backBuffer); bufferMap = (PixMapHandle)GetGWorldPixMap(backBuffer); screen_buffer = (unsigned long*)(**bufferMap).baseAddr; theError = DSpContext_FadeGammaIn(NULL, NULL); } // initialize a set of Display attributes to zero void MyInitAttributes (DSpContextAttributes *inAttributes) { if (NULL == inAttributes) DebugStr("\pStimpy! You Idiot!"); inAttributes->frequency = 0; inAttributes->displayWidth = 0; inAttributes->displayHeight = 0; inAttributes->reserved1 = 0; inAttributes->reserved2 = 0; inAttributes->colorNeeds = 0; inAttributes->colorTable = NULL; inAttributes->contextOptions = 0; inAttributes->backBufferDepthMask = 0; inAttributes->displayDepthMask = 0; inAttributes->backBufferBestDepth = 0; inAttributes->displayBestDepth = 0; inAttributes->pageCount = 0; inAttributes->gameMustConfirmSwitch = false; inAttributes->reserved3[0] = 0; inAttributes->reserved3[1] = 0; inAttributes->reserved3[2] = 0; inAttributes->reserved3[3] = 0; } void CleanUp(DSpContextReference theContext) { OSStatus theError; theError = DSpContext_FadeGammaOut(NULL, NULL); /* put the context into the inactive state */ theError = DSpContext_SetState(theContext, kDSpContextState_Inactive); /* fade back in */ theError = DSpContext_FadeGammaIn(NULL, NULL); /* release the context */ theError = DSpContext_Release(theContext); ShowCursor(); } // swap bufferB to the screen (32 bit version) void swapBuffers32( GraphicBuffer &bufferB ) { OSStatus theError; // swap buffers theError = DSpContext_SwapBuffers(theContext, NULL, 0); // get pointer to new back buffer and return it CGrafPtr backBuffer; PixMapHandle bufferMap; theError = DSpContext_GetBackBuffer(theContext, kDSpBufferKind_Normal, &backBuffer); bufferMap = (PixMapHandle)GetGWorldPixMap(backBuffer); // replace the buffer in bufferB with the new double buffer bufferB.setBuffer( (unsigned long*)(**bufferMap).baseAddr ); // memcpy(screen_buffer, bufferPtrB, 4*bufferWide*bufferHigh); } // end of swapBuffers // returns true if key represented by given key code is down char getKeyDown( int vKeyCode ) { unsigned char keyArray [16]; GetKeys( (long *)keyArray ); return ((keyArray[vKeyCode>>3] >> (vKeyCode & 7)) & 1); } // returns true if key is up char getKeyUp( int vKeyCode ) { unsigned char keyArray [16]; GetKeys( (long *)keyArray ); return !((keyArray[vKeyCode>>3] >> (vKeyCode & 7)) & 1); } void getMouse( int *x, int *y ) { Point mousePoint; DSpGetMouse( &mousePoint ); *x = mousePoint.h; *y = mousePoint.v; } void Initialize(void) { WindowPtr mainPtr; OSErr error; SysEnvRec theWorld; // // Test the computer to be sure we can do color. // If not we would crash, which would be bad. // If we canЙt run, just beep and exit. // error = SysEnvirons(1, &theWorld); if (theWorld.hasColorQD == false) { // SysBeep(50); ExitToShell(); // If no color QD, we must leave. } // Initialize all the needed managers. InitGraf(&qd.thePort); // InitFonts(); InitWindows(); InitMenus(); TEInit(); InitDialogs(nil); InitCursor(); // // To make the Random sequences truly random, we need to make the seed start // at a different number. An easy way to do this is to put the current time // and date into the seed. Since it is always incrementing the starting seed // will always be different. DonЙt for each call of Random, or the sequence // will no longer be random. Only needed once, here in the init. // GetDateTime((unsigned long*) &qd.randSeed); // // Make a new window for drawing in, and it must be a color window. // The window is full screen size, made smaller to make it more visible. // mainPtr = GetNewCWindow(rWindow, nil, (WindowPtr) -1); // MW Tutorial windRect = mainPtr->portRect; SetPort(mainPtr); // set window to current graf port TextSize(BobSize); // smaller font for drawing. } gravitation-3+dfsg1.orig/minorGems/graphics/test/0000755000175000017500000000000010762704567020675 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/graphics/test/tgaConverterCompile0000755000175000017500000000014110762704567024573 0ustar pabspabsg++ -g -o tgaConverter -I../../.. tgaConverter.cpp ../../../minorGems/io/file/linux/PathLinux.cppgravitation-3+dfsg1.orig/minorGems/graphics/test/tgaConverter.cpp0000644000175000017500000001002010762704567024035 0ustar pabspabs/* * Modification History * * 2001-September-24 Jason Rohrer * Created. */ #include "minorGems/graphics/Image.h" #include "minorGems/graphics/ImageColorConverter.h" #include "minorGems/graphics/converters/TGAImageConverter.h" #include "minorGems/io/file/File.h" #include "minorGems/io/file/FileInputStream.h" #include "minorGems/io/file/FileOutputStream.h" #include #include #include void usage( char *inAppName ); Image *loadTGAImage( char *inFileName ); void writeTGAImage( char *inFileName, Image *inImage ); // normalizes an image into the pixel range [0,1] if some // pixels are out of range void normalizeImage( Image *inImage ); // a test program that converts a tga image between // parameterizable color formats int main( char inNumArgs, char **inArgs ) { if( inNumArgs != 5 ) { usage( inArgs[0] ); } Image *inImage = loadTGAImage( inArgs[1] ); Image *outImage; // convert inImage to outImage based on the color space strings if( !strcmp( inArgs[3], "rgb" ) ) { if( !strcmp( inArgs[4], "yiq" ) ) { outImage = ImageColorConverter::RGBToYIQ( inImage ); } if( !strcmp( inArgs[4], "ycbcr" ) ) { outImage = ImageColorConverter::RGBToYCbCr( inImage ); } } if( !strcmp( inArgs[3], "yiq" ) ) { if( !strcmp( inArgs[4], "rgb" ) ) { outImage = ImageColorConverter::YIQToRGB( inImage ); } if( !strcmp( inArgs[4], "ycbcr" ) ) { Image *tempImage = ImageColorConverter::YIQToRGB( inImage ); outImage = ImageColorConverter::RGBToYCbCr( tempImage ); delete tempImage; } } if( !strcmp( inArgs[3], "ycbcr" ) ) { if( !strcmp( inArgs[4], "rgb" ) ) { outImage = ImageColorConverter::YCbCrToRGB( inImage ); } if( !strcmp( inArgs[4], "yiq" ) ) { Image *tempImage = ImageColorConverter::YCbCrToRGB( inImage ); outImage = ImageColorConverter::RGBToYIQ( tempImage ); delete tempImage; } } writeTGAImage( inArgs[2], outImage ); delete inImage; delete outImage; return 0; } void usage( char *inAppName ) { printf( "Usage:\n" ); printf( "\t%s in_image_tga out_image_tga in_format out_format\n", inAppName ); printf( "Example:\n" ); printf( "\t%s testRGB.tga testYIQ.bmp rgb yiq\n", inAppName ); printf( "The following color formats are supported:\n" ); printf( "\trgb, yiq, ycbcr\n" ); exit( 1 ); } void normalizeImage( Image *inImage ) { // now normalize the image so that pixels are in the range [0,1] int numPixels = inImage->getWidth() * inImage->getHeight(); int numChannels = inImage->getNumChannels(); double minValue = 1000.0; double maxValue = -1000.0; int c; // search for min and max values for( c=0; cgetChannel( c ); for( int p=0; p maxValue ) { maxValue = channel[p]; } } } double diff = maxValue - minValue; if( minValue >= 0 && diff + minValue <= 1 ) { // no need to normalize, as values are already // in range return; } double scale = 1.0 / diff; // now normalize all pixels for( c=0; cgetChannel( c ); for( int p=0; pdeformatImage( imageStream ); delete imageFile; delete imageStream; delete converter; return returnImage; } void writeTGAImage( char *inFileName, Image *inImage ) { File *imageFile = new File( NULL, inFileName, strlen( inFileName ) ); FileOutputStream *imageStream = new FileOutputStream( imageFile ); TGAImageConverter *converter = new TGAImageConverter(); converter->formatImage( inImage, imageStream ); delete imageFile; delete imageStream; delete converter; } gravitation-3+dfsg1.orig/minorGems/graphics/test/yiq2rgbCompile0000755000175000017500000000012710762704567023513 0ustar pabspabsg++ -g -o yiq2rgb -I../../.. yiq2rgb.cpp ../../../minorGems/io/file/linux/PathLinux.cppgravitation-3+dfsg1.orig/minorGems/graphics/test/rgb2yiq.cpp0000644000175000017500000000615710762704567022771 0ustar pabspabs/* * Modification History * * 2001-September-19 Jason Rohrer * Created. * * 2001-September-20 Jason Rohrer * Finished initial implementation. * Changed so that images are normalized to [0,1] before * being output. */ #include "minorGems/graphics/Image.h" #include "minorGems/graphics/ImageColorConverter.h" #include "minorGems/graphics/converters/BMPImageConverter.h" #include "minorGems/io/file/File.h" #include "minorGems/io/file/FileInputStream.h" #include "minorGems/io/file/FileOutputStream.h" #include #include void usage( char *inAppName ); Image *loadBMPImage( char *inFileName ); void writeBMPImage( char *inFileName, Image *inImage ); // normalizes an image into the pixel range [0,1] if some // pixels are out of range void normalizeImage( Image *inImage ); // a test program that converts an rgb BMP to a yiq BMP int main( char inNumArgs, char **inArgs ) { if( inNumArgs != 3 ) { usage( inArgs[0] ); } Image *rgbImage = loadBMPImage( inArgs[1] ); Image *yiqImage = ImageColorConverter::RGBToYIQ( rgbImage ); normalizeImage( yiqImage ); writeBMPImage( inArgs[2], yiqImage ); delete rgbImage; delete yiqImage; return 0; } void usage( char *inAppName ) { printf( "Usage:\n" ); printf( "\t%s rgb_image_bmp yiq_image_bmp\n", inAppName ); printf( "Example:\n" ); printf( "\t%s testRGB.bmp testYIQ.bmp\n", inAppName ); exit( 1 ); } void normalizeImage( Image *inImage ) { // now normalize the image so that pixels are in the range [0,1] int numPixels = inImage->getWidth() * inImage->getHeight(); int numChannels = inImage->getNumChannels(); double minValue = 1000.0; double maxValue = -1000.0; int c; // search for min and max values for( c=0; cgetChannel( c ); for( int p=0; p maxValue ) { maxValue = channel[p]; } } } double diff = maxValue - minValue; if( minValue >= 0 && diff + minValue <= 1 ) { // no need to normalize, as values are already // in range return; } double scale = 1.0 / diff; // now normalize all pixels for( c=0; cgetChannel( c ); for( int p=0; pdeformatImage( imageStream ); delete imageFile; delete imageStream; delete converter; return returnImage; } void writeBMPImage( char *inFileName, Image *inImage ) { File *imageFile = new File( NULL, inFileName, strlen( inFileName ) ); FileOutputStream *imageStream = new FileOutputStream( imageFile ); BMPImageConverter *converter = new BMPImageConverter(); converter->formatImage( inImage, imageStream ); delete imageFile; delete imageStream; delete converter; } gravitation-3+dfsg1.orig/minorGems/graphics/test/rgb2yiqCompile0000755000175000017500000000012410762704567023510 0ustar pabspabsg++ -o rgb2yiq -I../../.. rgb2yiq.cpp ../../../minorGems/io/file/linux/PathLinux.cppgravitation-3+dfsg1.orig/minorGems/graphics/test/yiq2rgb.cpp0000644000175000017500000000622210762704567022762 0ustar pabspabs/* * Modification History * * 2001-September-20 Jason Rohrer * Created. * Changed so that images are normalized to [0,1] before * being output. */ #include "minorGems/graphics/Image.h" #include "minorGems/graphics/ImageColorConverter.h" #include "minorGems/graphics/converters/BMPImageConverter.h" #include "minorGems/io/file/File.h" #include "minorGems/io/file/FileInputStream.h" #include "minorGems/io/file/FileOutputStream.h" #include #include void usage( char *inAppName ); Image *loadBMPImage( char *inFileName ); void writeBMPImage( char *inFileName, Image *inImage ); // normalizes an image into the pixel range [0,1] if some // pixels are out of range void normalizeImage( Image *inImage ); // a test program that converts an rgb BMP to a yiq BMP int main( char inNumArgs, char **inArgs ) { if( inNumArgs != 3 ) { usage( inArgs[0] ); } Image *yiqImage = loadBMPImage( inArgs[1] ); if( yiqImage == NULL ) { printf( "Reading image from file %s failed\n", inArgs[1] ); usage( inArgs[0] ); } Image *rgbImage = ImageColorConverter::YIQToRGB( yiqImage ); normalizeImage( rgbImage ); writeBMPImage( inArgs[2], rgbImage ); delete rgbImage; delete yiqImage; return 0; } void usage( char *inAppName ) { printf( "Usage:\n" ); printf( "\t%s yiq_image_bmp rgb_image_bmp\n", inAppName ); printf( "Example:\n" ); printf( "\t%s testYIQ.bmp testRGB.bmp\n", inAppName ); exit( 1 ); } void normalizeImage( Image *inImage ) { // now normalize the image so that pixels are in the range [0,1] int numPixels = inImage->getWidth() * inImage->getHeight(); int numChannels = inImage->getNumChannels(); double minValue = 1000.0; double maxValue = -1000.0; int c; // search for min and max values for( c=0; cgetChannel( c ); for( int p=0; p maxValue ) { maxValue = channel[p]; } } } double diff = maxValue - minValue; if( minValue >= 0 && diff + minValue <= 1 ) { // no need to normalize, as values are already // in range return; } double scale = 1.0 / diff; // now normalize all pixels for( c=0; cgetChannel( c ); for( int p=0; pdeformatImage( imageStream ); delete imageFile; delete imageStream; delete converter; return returnImage; } void writeBMPImage( char *inFileName, Image *inImage ) { File *imageFile = new File( NULL, inFileName, strlen( inFileName ) ); FileOutputStream *imageStream = new FileOutputStream( imageFile ); BMPImageConverter *converter = new BMPImageConverter(); converter->formatImage( inImage, imageStream ); delete imageFile; delete imageStream; delete converter; } gravitation-3+dfsg1.orig/minorGems/graphics/loadFile.cpp0000644000175000017500000000335010762704567022142 0ustar pabspabs#include #include #include "loadFile.h" // loads any file into the dest ptr. void loadFile( const char* fileName, long sizeInBytes, unsigned char* byteDestPtr) { FILE *f; int numBytesRead; f = fopen( fileName, "rb"); // open the file // don't load if file failed to open if( f == NULL ) { return; } numBytesRead = fread( (void*)byteDestPtr, sizeof(char), sizeInBytes, f); fclose(f); } // loads a photoshop RAW image file, 32-bit // NOTE: // This function exists because photoshop swaps the red and blue channels when // it saves a file as raw. Thus, the file stream doesn't match the way a video // card deals with 32-bit color. // This function loads the file and then swaps the appropriate bytes void loadRawFile( const char* fileName, long sizeInBytes, unsigned char* byteDestPtr) { //unsigned char tempChannel; long byteCount; FILE *f; int numBytesRead; f = fopen( fileName, "rb"); // open the file // don't load if file failed to open if( f == NULL ) { return; } numBytesRead = fread( (void*)byteDestPtr, sizeof(char), sizeInBytes, f); // now that file read, swap the red and blue channels: for( byteCount = 0; byteCount< sizeInBytes; byteCount=byteCount+4) { unsigned char alpha = byteDestPtr[byteCount+3]; byteDestPtr[byteCount+3] = byteDestPtr[byteCount+2]; byteDestPtr[byteCount+2] = byteDestPtr[byteCount+1]; byteDestPtr[byteCount+1] = byteDestPtr[byteCount]; byteDestPtr[byteCount] = alpha; /* tempChannel = byteDestPtr[byteCount]; // currently in red position byteDestPtr[byteCount] = byteDestPtr[byteCount+3]; // currently set to what's in alpha position byteDestPtr[byteCount+2] = tempChannel; */ } fclose(f); }gravitation-3+dfsg1.orig/minorGems/graphics/RGBAImage.h0000644000175000017500000001107010762704567021544 0ustar pabspabs/* * Modification History * * 2000-December-21 Jason Rohrer * Created. * * 2001-January-15 Jason Rohrer * Added an overridden copy() method. * * 2001-January-19 Jason Rohrer * Fixed so that filter( filter, channelNum ) could be called on * this class type. * * 2001-January-31 Jason Rohrer * Fixed a bug in getRGBABytes(). * * 2001-September-15 Jason Rohrer * Added a constructor that copies data from an Image. * * 2006-September-7 Jason Rohrer * Optimized constructor. */ #ifndef RGBA_IMAGE_INCLUDED #define RGBA_IMAGE_INCLUDED #include #include #include "Image.h" /** * An RGBA extension of Image. * * @author Jason Rohrer */ class RGBAImage : public Image { public: /** * Constructs an RGBA image. All channels are initialized to 0. * * @param inWidth width of image in pixels. * @param inHeight height of image in pixels. */ RGBAImage( int inWidth, int inHeight ); /** * Constructs an RGBAImage by copying a given image. * The image data is truncated or expaned (with black channels) * to fit the 4 channel RGBA model, * and any selection in inImage is ignored. * * @param inImage the image to copy. Copied internally, so must be * destroyed by the caller. */ RGBAImage( Image *inImage ); /** * Gets the pixel data from this image as a byte array. * * @return a byte array containing pixel data for this image. * Stored in row-major order, with each pixel represented * by 4 bytes in the order RGBA. * Must be destroyed by caller. */ virtual unsigned char *getRGBABytes(); // overrides the Image::filter function virtual void filter( ChannelFilter *inFilter ); virtual void filter( ChannelFilter *inFilter, int inChannel ); // overrides the Image::copy function // since the function is non-virtual in the parent class, // the pointer type should determine which function gets called. RGBAImage *copy(); }; inline RGBAImage::RGBAImage( int inWidth, int inHeight ) : Image( inWidth, inHeight, 4 ) { } inline RGBAImage::RGBAImage( Image *inImage ) // Only init our image's channels to black of inImage doesn't have enough // channels. // This saves time if inImage has 4 or more channels. // Optimization found with profiler. : Image( inImage->getWidth(), inImage->getHeight(), 4, ( inImage->getNumChannels() < 4 ) ) { int minNumChannels = 4; if( inImage->getNumChannels() < minNumChannels ) { minNumChannels = inImage->getNumChannels(); } // if inImage does not have at least 4 channels, // leave our additional channels black // if inImage has extra channels, skip them // copy channels from inImage for( int c=0; cgetChannel( c ); memcpy( mChannels[c], inChannel, mNumPixels * sizeof( double ) ); } } /* inline unsigned char *RGBAImage::getRGBABytes() { int numBytes = mNumPixels * 4; unsigned char *bytes = new unsigned char[ numBytes ]; int pixel = 0; for( int i=0; ipaste( this ); return copiedImage; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/linux/0000755000175000017500000000000010762704567021055 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/graphics/linux/graphixCommonDefs.h0000644000175000017500000000013010762704567024635 0ustar pabspabs// ALifeGUICommonDefs.h // common definitions for ALifeGui #define LINUX_KEY_CODES gravitation-3+dfsg1.orig/minorGems/graphics/linux/ScreenGraphicsLinux.cpp0000644000175000017500000000660310762704567025506 0ustar pabspabs/* * Modification History * * 2000-November-18 Jason Rohrer * Created. * * 2000-November-19 Jason Rohrer * Change so that it doesn't use SDL's interrupt parachute, i.e., * so it will quit on ^c. * * 2001-May-1 Jason Rohrer * Changed to use more standard SDL include location. * * 2006-April-28 Jason Rohrer * Added functions for more direct access to screen pixels. * * 2006-June-26 Jason Rohrer * Added support for dirty rectangle. * Added resize support. */ #include "minorGems/graphics/ScreenGraphics.h" #include /** * Note: Linux implementation uses windowed mode. */ ScreenGraphics::ScreenGraphics( int inWidth, int inHeight ) : mWidth( inWidth ), mHeight( inHeight ) { if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 ) { printf( "Couldn't initialize SDL: %s\n", SDL_GetError() ); return; } SDL_Surface *screen = SDL_SetVideoMode( mWidth, mHeight, 32, SDL_SWSURFACE ); if ( screen == NULL ) { printf( "Couldn't set %dx%dx32 video mode: %s\n", mWidth, mHeight, SDL_GetError() ); return; } mNativeObjectPointer = (void*)screen; } ScreenGraphics::~ScreenGraphics() { SDL_Quit(); } void ScreenGraphics::resize( int inNewWidth, int inNewHeight ) { mWidth = inNewWidth; mHeight = inNewHeight; SDL_Surface *screen = SDL_SetVideoMode( mWidth, mHeight, 32, SDL_SWSURFACE ); if ( screen == NULL ) { printf( "Couldn't set %dx%dx32 video mode: %s\n", mWidth, mHeight, SDL_GetError() ); return; } mNativeObjectPointer = (void*)screen; } char ScreenGraphics::isResolutionAvailable( int inWidth, int inHeight ) { if( SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE ) < 0 ) { printf( "Couldn't initialize SDL: %s\n", SDL_GetError() ); return false; } // ask SDL if this screen size is supported char videoModeOk = (char)SDL_VideoModeOK( inWidth, inHeight, 32, SDL_SWSURFACE ); SDL_Quit(); return videoModeOk; } void ScreenGraphics::swapBuffers( GraphicBuffer *inOutBuffer ) { if( inOutBuffer->getHeight() != mHeight || inOutBuffer->getWidth() != mWidth ) { printf( "Buffer of incorrect size passed to screen.\n" ); return; } SDL_Surface *screen = (SDL_Surface*)mNativeObjectPointer; // check if we need to lock the screen if( SDL_MUSTLOCK( screen ) ) { if( SDL_LockSurface( screen ) < 0 ) { printf( "Couldn't lock screen: %s\n", SDL_GetError() ); return; } } Uint32 *buffer = (Uint32 *)( screen->pixels ); memcpy( (void*)buffer, (void*)( inOutBuffer->getBuffer() ), mWidth * mHeight * 4 ); // unlock the screen if necessary if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } SDL_Flip( screen ); } GraphicBuffer *ScreenGraphics::getScreenBuffer() { SDL_Surface *screen = (SDL_Surface*)mNativeObjectPointer; Uint32 *buffer = (Uint32 *)( screen->pixels ); return new GraphicBuffer( (unsigned long *)buffer, mWidth, mHeight ); } void ScreenGraphics::flipDirtyRectangle( int inTopLeftX, int inTopLeftY, int inWidth, int inHeight ) { SDL_Surface *screen = (SDL_Surface*)mNativeObjectPointer; SDL_UpdateRect( screen, inTopLeftX, inTopLeftY, inWidth, inHeight ); } void ScreenGraphics::flipScreen() { SDL_Surface *screen = (SDL_Surface*)mNativeObjectPointer; SDL_Flip( screen ); } gravitation-3+dfsg1.orig/minorGems/graphics/linux/SDLTest.cpp0000644000175000017500000001173010762704567023045 0ustar pabspabs //#include #include "minorGems/graphics/ScreenGraphics.h" #include "minorGems/graphics/GraphicBuffer.h" #include "minorGems/graphics/Color.h" #include "minorGems/ui/Mouse.h" #include #include #include int numIcons = 200; int currentStep = 0; int numSteps = 1000; void catch_int(int sig_num) { printf( "Quiting..." ); currentStep = numSteps; signal( SIGINT, catch_int); } int main() { int i, j; // let catch_int handle interrupt (^c) signal( SIGINT, catch_int); ScreenGraphics *graphics = new ScreenGraphics( 640, 480 ); Mouse *mouse = new Mouse(2); unsigned long *pixelBuff = new unsigned long[ 640 * 480 ]; GraphicBuffer *buffer = new GraphicBuffer( pixelBuff, 640, 480 ); IconMap **maps = new IconMap*[numIcons]; IconMap *mouseMap; IconMap *mouseMap1 = new IconMap( 10, 10 ); Color mouseColor1( 1.0, 0.0, 0.0, 1.0 ); for( int y=0; y<10; y++ ) { for( int x=0; x<10; x++ ) { mouseMap1->imageMap[ mouseMap1->yOffset[y] + x ] = mouseColor1.composite; } } IconMap *mouseMap2 = new IconMap( 10, 10 ); Color mouseColor2( 0.0, 1.0, 0.0, 1.0 ); for( int y=0; y<10; y++ ) { for( int x=0; x<10; x++ ) { mouseMap2->imageMap[ mouseMap2->yOffset[y] + x ] = mouseColor2.composite; } } IconMap *mouseMap3 = new IconMap( 10, 10 ); Color mouseColor3( 0.0, 0.0, 1.0, 1.0 ); for( int y=0; y<10; y++ ) { for( int x=0; x<10; x++ ) { mouseMap3->imageMap[ mouseMap3->yOffset[y] + x ] = mouseColor3.composite; } } mouseMap = mouseMap1; Color c( 0.0f, 0.0f, 0.0f, 1.0f ); buffer->fill( c ); float *xPos = new float[numIcons]; float *yPos = new float[numIcons]; float *xDelta = new float[numIcons]; float *yDelta = new float[numIcons]; for( i=0; iimageMap[ maps[i]->yOffset[y] + x ] = randColor.composite; } } } int mouseX = 0; int mouseY = 0; char buttonDown1 = false; char buttonDown2 = false; for( currentStep=0; currentSteperaseIconMap( mouseMap, mouseX, mouseY, c ); mouse->getLocation( &mouseX, &mouseY ); buffer->drawIconMap( mouseMap, mouseX, mouseY ); if( !buttonDown1 && mouse->isButtonDown(0) ) { buttonDown1 = true; mouseMap = mouseMap2; } else if( buttonDown1 && !mouse->isButtonDown(0) ) { buttonDown1 = false; mouseMap = mouseMap1; } else if( !buttonDown2 && mouse->isButtonDown(1) ) { buttonDown2 = true; mouseMap = mouseMap3; } else if( buttonDown2 && !mouse->isButtonDown(1) ) { buttonDown2 = false; mouseMap = mouseMap1; } for( i=0; ieraseIconMap( maps[i], (int)( xPos[i] - 5 ), (int)( yPos[i] - 5 ), c ); if( xPos[i] > 640 || xPos[i] < 0 ) { xDelta[i] = -xDelta[i]; } xPos[i] += xDelta[i]; if( yPos[i] > 480 || yPos[i] < 0 ) { yDelta[i] = -yDelta[i]; } yPos[i] += yDelta[i]; buffer->drawIconMap( maps[i], (int)( xPos[i] - 5 ), (int)( yPos[i] - 5 ) ); } graphics->swapBuffers( buffer ); } /* for( int i=0; i<100; i++ ) { if( i%2 == 0 ) { Color c( 1.0f, 0.0f, 0.0f, 1.0f ); buffer->fill( c ); } else { Color c( 0.0f, 1.0f, 0.0f, 1.0f ); buffer->fill( c ); } graphics->swapBuffers( buffer ); } */ printf( "Done.\n" ); return 0; /* if ( SDL_Init( SDL_INIT_VIDEO ) < 0 ) { printf( "Couldn't initialize SDL: %s\n", SDL_GetError() ); exit(1); } //atexit( SDL_Quit ); SDL_Surface *screen = SDL_SetVideoMode( 640, 480, 32, SDL_HWSURFACE | SDL_DOUBLEBUF );//| SDL_FULLSCREEN ); if ( screen == NULL ) { printf( "Couldn't set 640x480x32 video mode: %s\n", SDL_GetError() ); exit(1); } for( int i=0; i< 100; i++ ) { if ( SDL_MUSTLOCK(screen) ) { if ( SDL_LockSurface(screen) < 0 ) { printf( "Couldn't lock screen: %s\n", SDL_GetError()); exit(1); } } Uint32 value; if( i%2 == 0 ) { value = 0x0; } else { value = 0xFFFFFFFF; } Uint32 *buffer = (Uint32 *)( screen->pixels ); for ( int y=0; yh; y++ ) { for ( int x=0; xw; x++ ) { int r = ( ( ( x * 255 ) / screen->w ) + i ) % 255; int g = ( ( ( y * 255 ) / screen->h ) + i ) % 255; int b = 0; int a = 255; //buffer[ y * screen->w + x ] = (a << 24) | (r << 16) | (g << 8) | b; buffer[ y * screen->w + x ] = value; } } if ( SDL_MUSTLOCK(screen) ) { SDL_UnlockSurface(screen); } //SDL_UpdateRect( screen, 0, 0, screen->w, screen->h ); SDL_Flip( screen ); } SDL_Quit(); SDL_Delay(2000); exit(0); */ } gravitation-3+dfsg1.orig/minorGems/graphics/win32/0000755000175000017500000000000010762704567020660 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/graphics/win32/graphixCommonDefs.h0000644000175000017500000000013110762704567024441 0ustar pabspabs// ALifeGUICommonDefs.h // common definitions for ALifeGui #define WINDOWS_KEY_CODESgravitation-3+dfsg1.orig/minorGems/graphics/win32/graphixFramework.cpp0000644000175000017500000002651510762704567024715 0ustar pabspabs// 32 bit DDraw pluggable framework // Jason Rohrer, 4-28-99 /** * Mods: * Jason Rohrer 11-8-99 Changed to use GraphicBuffer object as screen buffer * Jason Rohrer 3-21-2000 Added support for mouse querying */ // based on the work of: /* * water ripples effect * -------------------- * anthony greene :: emit * april 1999 */ #define WIN32_LEAN_AND_MEAN // make sure certain headers are included correctly /* includes */ #include // include the standard windows stuff //#include // include the 32 bit stuff //#include // include the multi media stuff // need winmm.lib also #include // include direct draw components #include #include "swapBuffers.h" // interface for swapping buffers #include "getKey.h" // interface for handling keyboard input #include "getMouse.h" // interface for handling mouse input #include "GraphicBuffer.h" //#include "ALifeGuiRunner.h" #include "GoGUIRunner.h" /* defines */ #define WINDOW_CLASS_NAME "WINDOW_CLASS" // this is the name of the window class #define SCREEN_WIDTH 640 // the width of the viewing surface #define SCREEN_HEIGHT 480 // the height of the viewing surface #define SCREEN_BPP 32 // the bits per pixel #define MAX_COLORS 256 // the maximum number of colors /* types */ typedef unsigned char BYTE; typedef unsigned char UCHAR; typedef unsigned short WORD; /* macros */ // these query the keyboard in real-time #define KEY_DOWN(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 1 : 0) #define KEY_UP(vk_code) ((GetAsyncKeyState(vk_code) & 0x8000) ? 0 : 1) /* prototypes */ int DD_Init(HWND hwnd); int DD_Shutdown(void); void graphixPicker(void); // our mother function, picks effect order, etc. /* directdraw globals */ LPDIRECTDRAW lpdd = NULL; // dd object LPDIRECTDRAWSURFACE lpddsprimary = NULL; // dd primary surface LPDIRECTDRAWSURFACE lpddsback = NULL; // dd back surface LPDIRECTDRAWPALETTE lpddpal = NULL; // a pointer to the created dd palette PALETTEENTRY color_palette[256]; // holds the shadow palette entries DDSURFACEDESC ddsd; // a direct draw surface description struct DDSCAPS ddscaps; // a direct draw surface capabilities struct HRESULT ddrval; // result back from dd calls HWND main_window_handle = NULL; // used to store the window handle unsigned long *double_buffer = NULL; // the double buffer unsigned long *screen_buffer = NULL; GraphicBuffer *graphicDoubleBuffer; /* globals */ int Height[2][640*480]; int old; int nu; int running = 0; int cycle; /* direct x functions */ int DD_Init(HWND hwnd) { // this function is responsible for initializing direct draw, // it creates a primary surface int index; // looping index // now that the windows portion is complete, start up direct draw if (DirectDrawCreate(NULL,&lpdd,NULL)!=DD_OK) { // shutdown any other dd objects and kill window DD_Shutdown(); return(0); } // now set the coop level to exclusive and set for full screen and mode x if (lpdd->SetCooperativeLevel(hwnd, DDSCL_ALLOWREBOOT | DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN | DDSCL_ALLOWMODEX)!=DD_OK) { // shutdown any other dd objects and kill window DD_Shutdown(); return(0); } // now set the display mode if (lpdd->SetDisplayMode(SCREEN_WIDTH,SCREEN_HEIGHT,SCREEN_BPP)!=DD_OK) { // shutdown any other dd objects and kill window DD_Shutdown(); return(0); } // Create the primary surface memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE; if (lpdd->CreateSurface(&ddsd,&lpddsprimary,NULL)!=DD_OK) { // shutdown any other dd objects and kill window DD_Shutdown(); return(0); } // end if // allocate memory for the double buffer if ((double_buffer = (unsigned long *)malloc(SCREEN_WIDTH*SCREEN_HEIGHT*4))==NULL) return(0); // create GraphicBuffer object graphicDoubleBuffer = new GraphicBuffer( double_buffer, 640, 480 ); // create the palette and attach it to the primary surface // clear all the palette entries to RGB 0,0,0 memset(color_palette,0,256*sizeof(PALETTEENTRY)); // set all of the flags to the correct value int c=0; for (index=0; index<256; index++) { // create the GRAY/RED/GREEN/BLUE palette, 64 shades of each if (index < 64) { color_palette[index].peRed = index; color_palette[index].peGreen = 0; color_palette[index].peBlue = 0; } else if (index < 128) { color_palette[index].peRed = index; color_palette[index].peGreen = 0; color_palette[index].peBlue = 0; } else if (index < 192) { color_palette[index].peRed = index; color_palette[index].peGreen = c; color_palette[index].peBlue = c; c++; } else if (index < 256) { color_palette[index].peRed = index; color_palette[index].peGreen = c; color_palette[index].peBlue = c; c++; } // set the no collapse flag color_palette[index].peFlags = PC_NOCOLLAPSE; } // now create the palette object, note that it is a member of the dd object itself if (lpdd->CreatePalette((DDPCAPS_8BIT | DDPCAPS_INITIALIZE),color_palette,&lpddpal,NULL)!=DD_OK) { // shutdown any other dd objects and kill window DD_Shutdown(); return(0); } // now attach the palette to the primary surface lpddsprimary->SetPalette(lpddpal); // return success if we got this far return(1); } int DD_Shutdown(void) { // this function tests for dd components that have been created // and releases them back to the operating system // test if the dd object exists if (lpdd) { // test if there is a primary surface if(lpddsprimary) { // release the memory and set pointer to NULL lpddsprimary->Release(); lpddsprimary = NULL; } // now release the dd object itself lpdd->Release(); lpdd = NULL; // free double buffer if (double_buffer!=NULL) free(double_buffer); // return success return(1); } else return(0); } /* windows callback fucntion */ LRESULT CALLBACK WindowProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam) { // this is the main message handler of the system HDC hdc; // handle to graphics context PAINTSTRUCT ps; // used to hold the paint info // what is the message.. switch(msg) { case WM_CREATE: { // do windows inits here return(0); } break; case WM_PAINT: { // this message occurs when your window needs repainting hdc = BeginPaint(hwnd,&ps); EndPaint((struct HWND__ *)hdc,&ps); return(0); } break; case WM_DESTROY: { // this message is sent when your window is destroyed PostQuitMessage(0); return(0); } break; case WM_MOUSEMOVE: { // extract x,y /* int mouse_x = (int)LOWORD(lparam); int mouse_y = (int)HIWORD(lparam); Height[old][mouse_y*640+mouse_x] = 300; */ return(0); } break; default:break; } // let windows process any messages that we didn't take care of return (DefWindowProc(hwnd, msg, wparam, lparam)); } int WINAPI WinMain( HINSTANCE hinstance, HINSTANCE hprevinstance, LPSTR lpcmdline, int ncmdshow) { WNDCLASSEX winclass; // this holds the windows class info HWND hwnd; // this holds the handle of our new window MSG msg; // this holds a generic message // first fill in the window class stucture winclass.cbSize = sizeof(WNDCLASSEX); winclass.style = CS_DBLCLKS | CS_OWNDC | CS_HREDRAW | CS_VREDRAW; winclass.lpfnWndProc = WindowProc; winclass.cbClsExtra = 0; winclass.cbWndExtra = 0; winclass.hInstance = hinstance; winclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); winclass.hIconSm = LoadIcon(NULL, IDI_APPLICATION); winclass.hCursor = LoadCursor(NULL, IDC_ARROW); winclass.hbrBackground = (struct HBRUSH__ *)GetStockObject(BLACK_BRUSH); winclass.lpszMenuName = NULL; winclass.lpszClassName = WINDOW_CLASS_NAME; // register the window class if (!RegisterClassEx(&winclass)) return(0); // create the window if (!(hwnd = CreateWindowEx(WS_EX_TOPMOST, WINDOW_CLASS_NAME, // class "water", // title WS_VISIBLE | WS_POPUP, 0,0, // x,y GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN), NULL, // parent NULL, // menu hinstance, // instance NULL))) // creation parms return(0); // hide the mouse cursor ShowCursor(0); // save the window handle main_window_handle = hwnd; // initialize direct draw if (!DD_Init(hwnd)) { DestroyWindow(hwnd); return(0); } // peek at the message once just to make them happy PeekMessage(&msg,NULL,0,0,PM_REMOVE); // do it once, then leave graphixPicker(); // picks which effects to run. // afterwards, end!!! // shut down direct draw DD_Shutdown(); // return to Windows return(msg.wParam); } void graphixPicker() { // our "mother function" // selects which effect to run next // graphix plug-in format: // myGraphix( bufferPtr, bufferHigh, bufferWide, colorBits, numFrames) // function can cll "swapBuffer32" internally whenever it needs the back buffer // sent to the screen. // jcrTorus( double_buffer, 480, 640, 32, 100); // jcrVoxels( double_buffer, 480, 640, 32, 230); // jcrTorus( double_buffer, 480, 640, 32, 50); // jcrBloom( double_buffer, 480, 640, 32, 100); //ALifeGuiRunner( *graphicDoubleBuffer, 200 ); GoGUIRunner( *graphicDoubleBuffer, 0 ); } char getKeyDown( int vKeyCode ) { return ((GetAsyncKeyState(vKeyCode) & 0x8000) ? true : false); } char getKeyUp( int vKeyCode ) { return ((GetAsyncKeyState(vKeyCode) & 0x8000) ? false : true); } void getMouse( int *x, int *y ) { POINT p; GetCursorPos( &p ); *x = p.x; *y = p.y; } /// CODE FOR SWAPPING BUFFERES BELOW THIS POINT....... // swap bufferB to the screen (32 bit version) void swapBuffers32( GraphicBuffer &bufferB ) { unsigned long *primary_buffer = NULL, // used to draw *dest_ptr = NULL, // used in line by line copy *src_ptr = NULL; // " " short bufferHigh = 480; short bufferWide = 640; // copy the double buffer into the primary buffer memset(&ddsd,0,sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); // lock the primary surface lpddsprimary->Lock(NULL,&ddsd, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT,NULL); // get video pointer to primary surfce primary_buffer = (unsigned long *)ddsd.lpSurface; // test if memory is linear if (ddsd.lPitch == 640*4) { // copy memory from double buffer to primary buffer memcpy(primary_buffer, double_buffer, 640*480*4); } else { // non-linear // make copy of source and destination addresses dest_ptr = primary_buffer; src_ptr = double_buffer; // memory is non-linear, copy line by line for (int y=0; yUnlock(primary_buffer); } // end of swapBuffers gravitation-3+dfsg1.orig/minorGems/graphics/Image.h0000644000175000017500000003320010762704567021107 0ustar pabspabs/* * Modification History * * 2000-December-21 Jason Rohrer * Created. * * 2001-January-6 Jason Rohrer * Fixed a bug in filter( ChannelFilter * ). * Set mSelection to NULL by default. * * 2001-January-10 Jason Rohrer * Made class serializable. * * 2001-January-15 Jason Rohrer * Made copy() not-virtual, so it can be overridden by subclasses * while allowing pointer type to determine which function * implementation is invoked. * * 2001-January-31 Jason Rohrer * Fixed a bug in copy(). * * 2001-February-3 Jason Rohrer * Updated serialization code to use new interfaces. * * 2001-February-4 Jason Rohrer * Rewrote the serialization code to send the image across as a byte * array with one byte per channel. This will reduce the transfer size by * a factor of 8. Keeping images in double format is convennient for image * creation, but the added quality never affects the end user anyway, so * there's no point in sending the extra data to a stream. * Removed an unused array allocation. * * 2005-February-21 Jason Rohrer * Made destructor virtual to avoid compiler warnings. * * 2006-August-25 Jason Rohrer * Made zero init of pixels optional (for speed). */ #ifndef IMAGE_INCLUDED #define IMAGE_INCLUDED #include #include #include "ChannelFilter.h" #include "minorGems/io/Serializable.h" /** * A multi-channel, double-valued image. * * Is Serializable. Note that a serialized image doesn't have a selection. * * @author Jason Rohrer */ class Image : public Serializable { public: /** * Constructs an image. * * @param inWidth width of image in pixels. * @param inHeight height of image in pixels. * @param inNumChannels number of channels in image. * @param inStartPixelsAtZero true to initialize all pixels * to zero, or false to leave default memory values (garbage) * in place (pixels must be initialized by caller in this case). * Defaults to true. */ Image( int inWidth, int inHeight, int inNumChannels, char inStartPixelsAtZero = true ); virtual ~Image(); // gets the dimensions of this image. virtual long getWidth(); virtual long getHeight(); virtual long getNumChannels(); /** * Gets the values of a particular channel. * * Values are not copied. * * @param inChannel the channel to get. * * @return the values of the specified channel in row-major order. */ virtual double *getChannel( int inChannel ); /** * Selects a region of the image. Default is a clear selection, * which means all regions of image are affected by an applied * filter. * * @param inSelection the image to use as the selection mask. * Values of 0 indicate pixels that are not selection, and 1 * indicate pixels that are selected, with selection amount * varying linearly between 0 and 1. * If inSelection is a single channel, then that channel is * used as a selection mask for all channels in this image. * If inSelection contains the same number of channels as this * image, then the corresponding channels of inSelection are * are used to mask each channel of this image. * If inSelection contains a number of channels different * from the number in this image, the first channel of inSelection * is used to mask each channel in this image. * * Note that inSelection is not copied or destroyed by this class. * Thus, modifying inSelection after calling setSelection will * modify the selection in this image. */ virtual void setSelection( Image *inSelection ); /** * Gets the selection for this image. * * @return the selection for this image. Returns NULL * if there is no selection. Must not be destroyed * by caller before calling clearSelection. */ virtual Image *getSelection(); /** * Clears the selection. Effectively selects the entire image. */ virtual void clearSelection(); /** * Applies a filter to the selected region of * a specified channel of this image. * * @param inFilter the filter to apply. * @param inChannel the channel to filter. */ virtual void filter( ChannelFilter *inFilter, int inChannel ); /** * Applies a filter to the selected region of * all channels of this image. * * @param inFilter the filter to apply. */ virtual void filter( ChannelFilter *inFilter ); /** * Copies the selected region of this image. Not virtual, * so can be overridden by subclasses while allowing pointer * type to determine which function implementation is invoked. * * @return a new image with the same number of channels * as this image, each containing the selected region * from each corresponding channel of this image. Unselected * regions are set to black. Returned image has no selection. */ Image *copy(); /** * Pastes the selected region from another image into * the selected region of this image. * * @param inImage the image to paste. Let c be the number * of channels in this image, and cp be the number * of channels in the image being pasted. * If ccp, then only the first cp channels * of this image are pasted into. */ virtual void paste( Image *inImage ); /** * Copies the data from the selected region of a channel. * * @param inChannel the channel to copy. * * @return a copy of the channel data. Must be destroyed * by the caller. */ virtual double *copyChannel( int inChannel ); /** * Pastes channel data into the selected region of a specified channel. * * @param inChannelData an array containing the channel * data to be pasted. Must be destroyed by caller. * @param inChannel the channel to paste into. */ virtual void pasteChannel( double *inChannelData, int inChannel ); /** * Gets the mask for a specified channel. * * @param inChannel the channel to get a mask for. * * @return the mask data for the specified channel. * If selection has the same number of channels as this image * then a different mask is returned for each channel. Otherwise, * the first channel from the selection is returned as the * mask for every channel. Returns NULL if there is no selection. */ virtual double *getChannelSelection( int inChannel ); // implement the Serializable interface virtual int serialize( OutputStream *inOutputStream ); virtual int deserialize( InputStream *inInputStream ); protected: long mWide, mHigh, mNumPixels, mNumChannels; double **mChannels; // NULL if nothing selected. Image *mSelection; /** * Pastes masked channel data into the selected region of a * specified channel. * * @param inChannelData an array containing the channel * data to be pasted. Must be destroyed by caller. * @param inMask the selection mask to use for passed-in channel. * Set to NULL for no mask. * @param inChannel the channel to paste into. */ virtual void pasteChannel( double *inChannelData, double *inMask, int inChannel ); }; inline Image::Image( int inWidth, int inHeight, int inNumChannels, char inStartPixelsAtZero ) : mWide( inWidth ), mHigh( inHeight ), mNumPixels( inWidth * inHeight ), mNumChannels( inNumChannels ), mChannels( new double*[inNumChannels] ), mSelection( NULL ) { // initialize all channels for( int i=0; iapply( mChannels[ inChannel ], mWide, mHigh ); } else { // part of image selected // turn selection off and filter channel entirely Image *tempSelection = mSelection; mSelection = NULL; // filter a copy of the channel double *filteredChannel = copyChannel( inChannel ); inFilter->apply( filteredChannel, mWide, mHigh ); // now paste filtered channel back into selected region mSelection = tempSelection; pasteChannel( filteredChannel, inChannel ); } } inline void Image::filter( ChannelFilter *inFilter ) { for( int i=0; ipaste( this ); return copiedImage; } inline void Image::paste( Image *inImage ) { // copy paste in the min number of channels only int numChannelsToPaste = mNumChannels; if( numChannelsToPaste > inImage->getNumChannels() ) { numChannelsToPaste = inImage->getNumChannels(); } for( int i=0; igetChannel(i), inImage->getChannelSelection(i), i ); } } inline double *Image::copyChannel( int inChannel ) { // first, copy the channel double *copiedChannel = new double[mNumPixels]; memcpy( copiedChannel, mChannels[inChannel], sizeof( double ) * mNumPixels ); if( mSelection != NULL ) { // apply selection to copied channel double *selection = getChannelSelection( inChannel ); // scale copied channel with selection for( int i=0; igetNumChannels() == mNumChannels ) { // use separate selection for each channel return mSelection->getChannel( inChannel ); } else { // use first channel of selection for all channels return mSelection->getChannel( 0 ); } } } inline void Image::pasteChannel( double *inChannelData, int inChannel ) { pasteChannel( inChannelData, NULL, inChannel ); } // We've abstracted away the complexity in the other fuctions, // but it all seemed to filter down into this function, which // is very messy. inline void Image::pasteChannel( double *inChannelData, double *inMask, int inChannel ) { double *thisChannel = mChannels[inChannel]; if( mSelection != NULL ) { // scale incoming data with this selection double *selection = getChannelSelection(inChannel); if( inMask != NULL ) { // scale incoming data with both masks for( int i=0; iwriteLong( mWide ); numBytes += inOutputStream->writeLong( mHigh ); // then output number of channels numBytes += inOutputStream->writeLong( mNumChannels ); // now output each channel for( int i=0; iwriteDouble( mChannels[i][p] ); byteArray[p] = (unsigned char)( mChannels[i][p] * 255 ); } numBytes += inOutputStream->write( byteArray, mNumPixels ); delete [] byteArray; } return numBytes; } inline int Image::deserialize( InputStream *inInputStream ) { int i; // first delete old image channels for( i=0; ireadLong( &mWide ); numBytes += inInputStream->readLong( &mHigh ); mNumPixels = mWide * mHigh; // then input number of channels numBytes += inInputStream->readLong( &mNumChannels ); mChannels = new double*[mNumChannels]; // now input each channel for( i=0; iread( byteArray, mNumPixels ); // convert each byte to an 8-bit double pixel for( int p=0; preadDouble( &( mChannels[i][p] ) ); mChannels[i][p] = (double)( byteArray[p] ) / 255.0; } delete [] byteArray; } return numBytes; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/ChannelFilter.h0000644000175000017500000000103010762704567022577 0ustar pabspabs/* * Modification History * * 2000-December-21 Jason Rohrer * Created. * * 2006-October-14 Jason Rohrer * Added virtual destructor. */ #ifndef CHANNEL_FILTER_INCLUDED #define CHANNEL_FILTER_INCLUDED /** * Interface for a class that can filter a 2D channel. * * @author Jason Rohrer */ class ChannelFilter { public: virtual void apply( double *inChannel, int inWidth, int inHeight ) = 0; // ensure proper destruction of subclasses virtual ~ChannelFilter() { } }; #endif gravitation-3+dfsg1.orig/minorGems/graphics/IconMap.h0000644000175000017500000001003610762704567021415 0ustar pabspabs// Jason Rohrer // IconMap.h /** * * Simple 2d icon map * * * Created 12-12-99 * Mods: * Jason Rohrer 12-13-99 Added numPixels member * Jason Rohrer 3-22-2000 Added support for drawing icon maps into an icon map * Jason Rohrer 12-17-2000 Added include of Color.h */ #ifndef ICON_MAP_INCLUDED #define ICON_MAP_INCLUDED #include #include "Color.h" class IconMap { public: IconMap( int w, int h); // construct a map of a certain width and height IconMap( int w, int h, int *offset ); // pass in precomputed y offsets into image map ~IconMap(); int wide; int high; int numPixels; int *yOffset; unsigned long *imageMap; // draw a solid IconMap into this IconMap void drawIconMap( IconMap *icon, int xPos, int yPos ); // draw a transparent IconMap into this IconMap void drawIconMapAlpha( IconMap *icon, int xPos, int yPos ); void copy( IconMap *icon ); // copy contents of another icon map into this one // does nothing if icon maps aren't the same size private: char yOffsetExternal; // is the yOffset ptr external? float invChannelMax; Color utilColor; }; inline IconMap::IconMap( int w, int h ) { invChannelMax = 1 / 255.0; wide = w; high = h; numPixels = wide * high; imageMap = new unsigned long[ wide * high ]; yOffset = new int[high]; for( int y=0; yimageMap; int *imageYOffset = icon->yOffset; int imageWide = icon->wide; int imageHigh = icon->high; // watch for buffer bounds int minY = yPos; if( minY < 0 ) { minY = 0; } int maxY = yPos + imageHigh; if( maxY > high ) { maxY = high; } int minX = xPos; if( minX < 0 ) { minX = 0; } int maxX = xPos + imageWide; if( maxX > wide ) { maxX = wide; } for( int y=minY; yimageMap; int *imageYOffset = icon->yOffset; int imageWide = icon->wide; int imageHigh = icon->high; // watch for buffer bounds int minY = yPos; if( minY < 0 ) { minY = 0; } int maxY = yPos + imageHigh; if( maxY > high ) { maxY = high; } int minX = xPos; if( minX < 0 ) { minX = 0; } int maxX = xPos + imageWide; if( maxX > wide ) { maxX = wide; } for( int y=minY; y> 24) * invChannelMax; float oneMinusAlpha = 1-alpha; unsigned long buffARGB = imageMap[ buffYContrib + x ]; argb = utilColor.getWeightedComposite( argb, alpha ); buffARGB = utilColor.getWeightedComposite( buffARGB, oneMinusAlpha ); unsigned long sum = utilColor.sumComposite( argb, buffARGB ); imageMap[ buffYContrib + x ] = sum; } } } inline void IconMap::copy( IconMap *icon ) { // make sure they are the same size if( numPixels != icon->numPixels ) { return; } // void * memcpy (void * dst, const void * src, size_t len); // each pixel is 4 bytes, so shift numPixels by 2 memcpy( (void *)(imageMap), (void *)(icon->imageMap), numPixels << 2 ); } #endif gravitation-3+dfsg1.orig/minorGems/graphics/keyCodes.h0000644000175000017500000000104410762704567021634 0ustar pabspabs// Jason Rohrer // keyCodes.h /** * * Header for defining key codes for various platforms * * * Created 12-15-99 * Mods: * Jason Rohrer 3-23-2000 Added more key codes * */ #ifdef WINDOWS_KEY_CODES #define M_KEY 0x4D #define N_KEY 0x4E #define S_KEY 0x53 #define Q_KEY 0x51 #define L_KEY 0x4C #define R_KEY 0x52 #define T_KEY 0x54 #endif #ifdef MAC_KEY_CODES #define M_KEY 0x2E #define N_KEY 0x2D #define S_KEY 0x01 #define Q_KEY 0x0C #define L_KEY 0x25 #define R_KEY 0x0F #define T_KEY 0x11 #endifgravitation-3+dfsg1.orig/minorGems/graphics/Color.h0000644000175000017500000002565510762704567021162 0ustar pabspabs// Jason Rohrer // Color.h /** * * Color object for RadiosGL * * Float components in RGB (0..1) * Color of emitted energy can be greater than 1 * * * Created 9-5-99 * Mods: * Jason Rohrer 11-6-99 Added 32-bit composite member * Jason Rohrer 11-13-99 Added printing functionality * Jason Rohrer 11-15-99 Added rebuildComposite function * Added weightColor function * Added getMax function * Jason Rohrer 2004-June-12 Fixed a bug in copy function. * Jason Rohrer 2004-June-12 Added a linear sum function. * * Jason Rohrer 2004-August-12 Optimized Color constructor. * Jason Rohrer 2004-August-27 Added an equality test. * Jason Rohrer 2005-February-4 Added weighting and setValue functions. * Jason Rohrer 2005-February-10 Added invert and saturate functions. * Jason Rohrer 2005-February-11 Added HSV conversion function. * Jason Rohrer 2005-April-5 Disabled default building of composite. * Jason Rohrer 2006-August-29 Changed alpha default to 1. * Jason Rohrer 2006-October-3 Disabled building composite in * default Color() constuctor. */ #ifndef COLOR_INCLUDED #define COLOR_INCLUDED #include #include class Color { public : /** * Constructs a color. * * @param red, green, blue the components of the color, each in [0,1]. * @param alpha the alpha value in [0,1]. Defaults to 1. * @param inBuildComposite set to true to build the composite * upon construction, or false to skip building composite (faster). * Defaults to false. */ Color(float red, float green, float blue, float alpha=1, char inBuildComposite=false ); /** * Constructs a all-zero color with no composite built. */ Color(); /** * Constructs an rgb color from HSV components. * * @param inHue, inSaturation, inValue the HSV components of the * color, each in [0,1]. * @param alpha the alpha value in [0,1]. Defaults to 1. * @param inBuildComposite set to true to build the composite * upon construction, or false to skip building composite (faster). * Defaults to true. * * @return an RGBA color equivalent to the HSV color. * Must be destroyed by caller. */ static Color *makeColorFromHSV( float inHue, float inSaturation, float inValue, float inAlpha=1, char inBuildComposite=false ); float r, g, b, a; char mCompositeBuilt; unsigned long composite; // 32-bit composite color Color *copy(); // make a copy of this color /** * Sets the RGBA values of this color. * * @param red, green, blue, alpha the values to set. * Alpha defaults to 0. */ void setValues( float red, float green, float blue, float alpha=1 ); /** * Sets the RGBA values of this color using the values from * another color. * * @param inOtherColor the color to copy values from. * Must be destroyed by caller. */ void setValues( Color *inOtherColor ); /** * Tests whether this color is equal to another color. * * @param inOtherColor the other color. * Must be destroyed by caller. * * @return true if they are equal, or false otherwise. */ char equals( Color *inOtherColor ); void print(); /** * Computes the linear weighted sum of two colors. * * @param inFirst the first color. * @param inSecond the second color. * @param inFirstWeight the weight given to the first color in the * sum. The second color is weighted (1-inFirstWeight). * * @return the sum color. Must be destroyed by caller. */ static Color *linearSum( Color *inFirst, Color *inSecond, float inFirstWeight ); // after adjusting the r, g, b, a values exterally // call this to remake the composite unsigned long unsigned long rebuildComposite(); // get largest component of R,G,B float getMax(); // alter color data by multiplying by weight void weightColor( float weight ); /** * Alters color data by multiplying by a weight color. * * @param inWeightColor the color to multiply this color by. * Must be destroyed by caller. */ void weightColor( Color *inWeightColor ); /** * Inverts this color. * * Ignores alpha channel. */ void invert(); /** * Saturates this color, ensuring that at most 2 components are * non-zero. * * Ignores alpha channel. */ void saturate(); // get component by component weighted 32-bit composite // (returns alpha unweighted) unsigned long getWeightedComposite( float weight ); // from this color unsigned long getWeightedComposite(unsigned long c1, float weight ); // from composite unsigned long sumComposite(unsigned long c1, unsigned long c2); // access this color as a three vector float &operator[](int rgbIndex); }; inline Color::Color() { r = 0; g = 0; b = 0; a = 0; mCompositeBuilt = false; composite = 0; } inline Color::Color(float red, float green, float blue, float alpha, char inBuildComposite ) { r = red; g = green; b = blue; a = alpha; if( inBuildComposite ) { rebuildComposite(); } else { composite = 0; mCompositeBuilt = false; } } inline Color *Color::makeColorFromHSV( float inHue, float inSaturation, float inValue, float inAlpha, char inBuildComposite ) { // based on pseudocode from http://www.easyrgb.com/math.php float r, g, b; if ( inSaturation == 0 ) { r = inValue; g = inValue; b = inValue; } else { float var_h = inHue * 6; float var_i = int( var_h ); // Or var_i = floor( var_h ) float var_1 = inValue * ( 1 - inSaturation ); float var_2 = inValue * ( 1 - inSaturation * ( var_h - var_i ) ); float var_3 = inValue * ( 1 - inSaturation * ( 1 - ( var_h - var_i ) ) ); if( var_i == 0 ) { r = inValue; g = var_3; b = var_1; } else if( var_i == 1 ) { r = var_2; g = inValue; b = var_1; } else if( var_i == 2 ) { r = var_1; g = inValue; b = var_3; } else if( var_i == 3 ) { r = var_1; g = var_2; b = inValue; } else if( var_i == 4 ) { r = var_3; g = var_1; b = inValue; } else { r = inValue; g = var_1; b = var_2; } } return new Color( r, g, b, inAlpha, inBuildComposite ); } inline Color *Color::copy() { Color *copyColor = new Color(r,g,b,a, mCompositeBuilt ); return copyColor; } inline void Color::setValues( float red, float green, float blue, float alpha ) { r = red; g = green; b = blue; a = alpha; if( mCompositeBuilt ) { rebuildComposite(); } } inline void Color::setValues( Color *inOtherColor ) { setValues( inOtherColor->r, inOtherColor->g, inOtherColor->b, inOtherColor->a ); } inline char Color::equals( Color *inOtherColor ) { if( r == inOtherColor->r && g == inOtherColor->g && b == inOtherColor->b && a == inOtherColor->a ) { return true; } else { return false; } } inline void Color::print() { printf( "(%f, %f, %f)", r, g, b ); } inline Color *Color::linearSum( Color *inFirst, Color *inSecond, float inFirstWeight ) { float secondWeight = 1 - inFirstWeight; float r = inFirstWeight * inFirst->r + secondWeight * inSecond->r; float g = inFirstWeight * inFirst->g + secondWeight * inSecond->g; float b = inFirstWeight * inFirst->b + secondWeight * inSecond->b; float a = inFirstWeight * inFirst->a + secondWeight * inSecond->a; return new Color( r, g, b, a, inFirst->mCompositeBuilt || inSecond->mCompositeBuilt ); } inline unsigned long Color::rebuildComposite() { composite = ((int)(b*255)) | ((int)(g*255)) << 8 | ((int)(r*255)) << 16 | ((int)(a*255)) << 24; mCompositeBuilt = true; return composite; } inline float Color::getMax() { float max = -FLT_MAX; if( r > max ) max = r; if( g > max ) max = g; if( b > max ) max = b; return max; } inline void Color::weightColor( float weight ) { r = r * weight; g = g * weight; b = b * weight; // for now, don't touch alpha if( mCompositeBuilt ) { rebuildComposite(); } } inline void Color::invert() { r = 1 - r; g = 1 - g; b = 1 - b; } inline void Color::saturate() { if( r < g && r < b ) { r = 0; } else if( g < r && g < b ) { g = 0; } else if( b < r && b < g ) { b = 0; } else if( r != 0 ) { // they are all equal, but non-zero // default to dropping red r = 0; } //else // they are all 0 // leave as black } inline void Color::weightColor( Color *inWeightColor ) { r *= inWeightColor->r; g *= inWeightColor->g; b *= inWeightColor->b; a *= inWeightColor->a; if( mCompositeBuilt ) { rebuildComposite(); } } inline float &Color::operator[](int rgbIndex) { if( rgbIndex == 0) return r; else if( rgbIndex == 1) return g; else if( rgbIndex == 2) return b; else if( rgbIndex == 3) return a; return r; // default, return r reference } inline unsigned long Color::getWeightedComposite( float weight ) { return ((int)(b*255*weight)) | ((int)(g*255*weight)) << 8 | ((int)(r*255*weight)) << 16 | ((int)(a*255)) << 24; } inline unsigned long Color::getWeightedComposite( unsigned long c1, float weight ) { int b = c1 & 0xFF; int g = (c1 >> 8) & 0xFF; int r = (c1 >> 16) & 0xFF; int a = c1 >> 24; return ((int)(b*weight)) | (((int)(g*weight)) << 8) | (((int)(r*weight)) << 16) | (((int)(a*weight)) << 24); } inline unsigned long Color::sumComposite(unsigned long c1, unsigned long c2) { int b = (c1 & 0xFF) + (c2 & 0xFF); if( b > 255) b = 255; int g = ((c1 >> 8) & 0xFF) + ((c2 >> 8) & 0xFF); if( g > 255) g = 255; int r = ((c1 >> 16) & 0xFF) + ((c2 >> 16) & 0xFF); if( r > 255) r = 255; int a = (c1 >> 24) + (c2 >> 24); if( a > 255) a = 255; return b | (g << 8) | (r << 16) | (a << 24); } #endif gravitation-3+dfsg1.orig/minorGems/graphics/filters/0000755000175000017500000000000010762704567021366 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/graphics/filters/BoxBlurFilter.h0000644000175000017500000001367510762704567024276 0ustar pabspabs/* * Modification History * * 2000-December-21 Jason Rohrer * Created. * * 2001-January-6 Jason Rohrer * Added a getRadius function for completeness. * * 2006-August-22 Jason Rohrer * Fixed major bug: sum for box must start at zero. * * 2006-September-7 Jason Rohrer * Optimized inner loop. * Optimized more, avoiding summing over entire box for each pixel. */ #ifndef BOX_BLUR_FILTER_INCLUDED #define BOX_BLUR_FILTER_INCLUDED #include "minorGems/graphics/ChannelFilter.h" /** * Blur convolution filter that uses a box for averaging. * * @author Jason Rohrer */ class BoxBlurFilter : public ChannelFilter { public: /** * Constructs a box filter. * * @param inRadius the radius of the box in pixels. */ BoxBlurFilter( int inRadius ); /** * Sets the box radius. * * @param inRadius the radius of the box in pixels. */ void setRadius( int inRadius ); /** * Gets the box radius. * * @return the radius of the box in pixels. */ int getRadius(); // implements the ChannelFilter interface void apply( double *inChannel, int inWidth, int inHeight ); private: int mRadius; }; inline BoxBlurFilter::BoxBlurFilter( int inRadius ) : mRadius( inRadius ) { } inline void BoxBlurFilter::setRadius( int inRadius ) { mRadius = inRadius; } inline int BoxBlurFilter::getRadius() { return mRadius; } inline void BoxBlurFilter::apply( double *inChannel, int inWidth, int inHeight ) { double *blurredChannel = new double[ inWidth * inHeight ]; // optimization: // The sum for a given pixel's box in row N is the sum for the same pixel // in row (N-1) minus one box-row of pixels and plus a box-row of pixels // We don't have to loop over the entire box for each pixel (instead, // we just add the new pixels and subtract the old as the box moves along) char lastRowSumsSet = false; double *lastRowSums = new double[ inWidth ]; // track the sums from single rows of boxes that we have already seen // Thus, when we need to "subtract a row" from our box sum, we can use // the precomputed version double *singleRowBoxSums = new double[ inWidth * inHeight ]; for( int y=0; y= inHeight ) { endBoxY = inHeight - 1; // box hanging over bottom edge // no rows to add to sum addARow = false; } int boxSizeY = endBoxY - startBoxY + 1; for( int x=0; x= inWidth ) { endBoxX = inWidth - 1; } int boxSizeX = endBoxX - startBoxX + 1; // sum all pixels in the box around this pixel double sum = 0; if( ! lastRowSumsSet ) { // do the "slow way" for the first row for( int boxY = startBoxY; boxY<=endBoxY; boxY++ ) { int yBoxIndexContrib = boxY * inWidth; double rowSum = 0; for( int boxX = startBoxX; boxX<=endBoxX; boxX++ ) { rowSum += inChannel[ yBoxIndexContrib + boxX ]; } sum += rowSum; // store row sum for future use singleRowBoxSums[ yBoxIndexContrib + x ] = rowSum; } } else { // we have sum for this pixel from the previous row // use it to avoid looping over entire box again sum = lastRowSums[ x ]; if( addARow ) { // add pixels from row at endBoxY int yBoxIndexContrib = endBoxY * inWidth; double rowSum = 0; for( int boxX = startBoxX; boxX<=endBoxX; boxX++ ) { rowSum += inChannel[ yBoxIndexContrib + boxX ]; } sum += rowSum; // store it for later when we will need to subtract it singleRowBoxSums[ yBoxIndexContrib + x ] = rowSum; } if( subtractARow ) { // subtract pixels from startBoxY of previous row's box int yBoxIndexContrib = (startBoxY - 1) * inWidth; // use pre-computed sum for the row we're subtracting sum -= singleRowBoxSums[ yBoxIndexContrib + x ]; } } // divide by number of pixels to complete the average blurredChannel[ pixelIndex ] = sum / (boxSizeX * boxSizeY); // save to use when computing box sum for next row lastRowSums[ x ] = sum; } // we now have valid last row sums that we can use for // all the rest of the rows lastRowSumsSet = true; } // copy blurred image back into passed-in image memcpy( inChannel, blurredChannel, sizeof(double) * inWidth * inHeight ); delete [] blurredChannel; delete [] lastRowSums; delete [] singleRowBoxSums; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/filters/MedianFilter.h0000644000175000017500000000672410762704567024113 0ustar pabspabs/* * Modification History * * 2001-May-15 Jeremy Tavan * Created. * * 2001-May-16 Jeremy Tavan * Modified to use the much faster quick_select * median-finding algorithm. * * 2001-May-17 Jaosn Rohrer * Tried to optimize by moving stuff out of the inner-inner loop. * It helped a bit, but not much. * */ #ifndef MEDIAN_FILTER_INCLUDED #define MEDIAN_FILTER_INCLUDED #include "minorGems/graphics/ChannelFilter.h" #include "quickselect.h" int medianFilterCompareInt( const void *x, const void *y ); /** * Median convolution filter. * * @author Jeremy Tavan */ class MedianFilter : public ChannelFilter { public: /** * Constructs a median filter. * * @param inRadius the radius of the box in pixels. */ MedianFilter( int inRadius ); /** * Sets the box radius. * * @param inRadius the radius of the box in pixels. */ void setRadius( int inRadius ); /** * Gets the box radius. * * @return the radius of the box in pixels. */ int getRadius(); // implements the ChannelFilter interface void apply( double *inChannel, int inWidth, int inHeight ); private: int mRadius; }; inline MedianFilter::MedianFilter( int inRadius ) : mRadius( inRadius ) { } inline void MedianFilter::setRadius( int inRadius ) { mRadius = inRadius; } inline int MedianFilter::getRadius() { return mRadius; } inline void MedianFilter::apply( double *inChannel, int inWidth, int inHeight ) { // pre-compute an integer version of the channel for the // median alg to use int numPixels = inWidth * inHeight; int *intChannel = new int[ numPixels ]; for( int p=0; p= inHeight ) { endBoxY = inHeight - 1; } int boxSizeY = endBoxY - startBoxY + 1; for( int x=0; x= inWidth ) { endBoxX = inWidth - 1; } int boxSizeX = endBoxX - startBoxX + 1; int *buffer = new int[boxSizeX * boxSizeY]; // sum all pixels in the box around this pixel for( int boxY = startBoxY; boxY<=endBoxY; boxY++ ) { int yBoxIndexContrib = boxY * inWidth; int yBoxContrib = boxSizeX * ( boxY-startBoxY ); for( int boxX = startBoxX; boxX<=endBoxX; boxX++ ) { //buffer[boxSizeX*(boxY-startBoxY)+(boxX-startBoxX)] = (int)(1000.0 * inChannel[yBoxIndexContrib + boxX]); buffer[ yBoxContrib + ( boxX-startBoxX ) ] = intChannel[ yBoxIndexContrib + boxX ]; } } medianChannel[ yIndexContrib + x ] = (double)quick_select( buffer, boxSizeX*boxSizeY ) / 1000.0; delete [] buffer; } } // copy blurred image back into passed-in image memcpy( inChannel, medianChannel, sizeof(double) * inWidth * inHeight ); delete [] medianChannel; delete [] intChannel; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/filters/SeamlessFilter.h0000644000175000017500000000740510762704567024467 0ustar pabspabs/* * Modification History * * 2001-January-19 Jason Rohrer * Created. * * 2006-September-25 Jason Rohrer * Added control over blending curve. * Reorderd loop for efficiency. */ #ifndef SEAMLESS_FILTER_INCLUDED #define SEAMLESS_FILTER_INCLUDED #include "minorGems/graphics/ChannelFilter.h" #include /** * Filter that turns any image into a seamless tile. * * @author Jason Rohrer */ class SeamlessFilter : public ChannelFilter { public: /** * Constructs a filter. * * @param inBlendCurveExponent the exponent of the blending curve * as we near the edge of the image. Defaults to 1 for a linear * blending curve. Setting to 2 would result in a parabolic * curve which would push the blended area closer to the edge * and leave more high-contrast, unblended image data near * the middle. */ SeamlessFilter( double inBlendCurveExponent = 1 ); // implements the ChannelFilter interface virtual void apply( double *inChannel, int inWidth, int inHeight ); private: double mBlendingCurveExponent; }; inline SeamlessFilter::SeamlessFilter( double inBlendCurveExponent ) : mBlendingCurveExponent( inBlendCurveExponent ) { } inline void SeamlessFilter::apply( double *inChannel, int inWidth, int inHeight ) { int numPixels = inWidth * inHeight; int halfHigh = inHeight/2; int halfWide = inWidth/2; // mix the texture with itself. // as we move closer and closer to the texture edge, we should // start mixing in more and more of the center values double *channelCopy = new double[ numPixels ]; // first, create an image with no seams if tiled horizontally // (getting rid of vertical seams) for( int x=0; x arr[high]) ELEM_SWAP(arr[low], arr[high]) ; return arr[median] ; } /* Find median of low, middle and high items; swap into position low */ middle = (low + high) / 2; if (arr[middle] > arr[high]) ELEM_SWAP(arr[middle], arr[high]) ; if (arr[low] > arr[high]) ELEM_SWAP(arr[low], arr[high]) ; if (arr[middle] > arr[low]) ELEM_SWAP(arr[middle], arr[low]) ; /* Swap low item (now in position middle) into position (low+1) */ ELEM_SWAP(arr[middle], arr[low+1]) ; /* Nibble from each end towards middle, swapping items when stuck */ ll = low + 1; hh = high; for (;;) { do ll++; while (arr[low] > arr[ll]) ; do hh--; while (arr[hh] > arr[low]) ; if (hh < ll) break; ELEM_SWAP(arr[ll], arr[hh]) ; } /* Swap middle item (in position low) back into correct position */ ELEM_SWAP(arr[low], arr[hh]) ; /* Re-set active partition */ if (hh <= median) low = ll; if (hh >= median) high = hh - 1; } } #undef ELEM_SWAP gravitation-3+dfsg1.orig/minorGems/graphics/filters/MultiFilter.h0000644000175000017500000000276510762704567024011 0ustar pabspabs/* * Modification History * * 2000-December-21 Jason Rohrer * Created. */ #ifndef MULTI_FILTER_INCLUDED #define MULTI_FILTER_INCLUDED #include "minorGems/graphics/ChannelFilter.h" #include "minorGems/util/SimpleVector.h" /** * Filter that applies a collection of filters. * * @author Jason Rohrer */ class MultiFilter : public ChannelFilter { public: /** * Constructs a MultiFilter. */ MultiFilter(); ~MultiFilter(); /** * Adds a filter to end of this MultiFilter. Filters * are applied in the order in which they are added. * * @param inFilter filter to add. Is not * destroyed when the MultiFilter is destroyed. */ void addFilter( ChannelFilter *inFilter ); /** * Removes a filter. * * @param inFilter filter to remove. */ void removeFilter( ChannelFilter *inFilter ); // implements the ChannelFilter interface void apply( double *inChannel, int inWidth, int inHeight ); private: SimpleVector *mFilterVector; }; inline MultiFilter::MultiFilter() : mFilterVector( new SimpleVector() ) { } inline MultiFilter::~MultiFilter() { delete mFilterVector; } inline void MultiFilter::apply( double *inChannel, int inWidth, int inHeight ) { int numFilters = mFilterVector->size(); for( int i=0; igetElement( i ) ); thisFilter->apply( inChannel, inWidth, inHeight ); } } #endif gravitation-3+dfsg1.orig/minorGems/graphics/filters/InvertFilter.h0000644000175000017500000000123310762704567024153 0ustar pabspabs/* * Modification History * * 2000-December-21 Jason Rohrer * Created. */ #ifndef INVERT_FILTER_INCLUDED #define INVERT_FILTER_INCLUDED #include "minorGems/graphics/ChannelFilter.h" /** * Filter that inverts the values in a channel. * * @author Jason Rohrer */ class InvertFilter : public ChannelFilter { public: // implements the ChannelFilter interface void apply( double *inChannel, int inWidth, int inHeight ); }; inline void InvertFilter::apply( double *inChannel, int inWidth, int inHeight ) { int numPixels = inWidth * inHeight; for( int i=0; i= mThreshold ) { inChannel[i] = 1.0; } else { inChannel[i] = 0.0; } } } #endif gravitation-3+dfsg1.orig/minorGems/graphics/swapBuffers.h0000644000175000017500000000141610762704567022360 0ustar pabspabs#include "GraphicBuffer.h" // function that swaps bufferB to the screen (32 bit version) // returns new back buffer //unsigned long *swapBuffers32( unsigned long *bufferPtrB, short bufferHigh, short bufferWide); // now replaces "buffer" in bufferB with the new double buffer after swap // no need to pass back the new buffer void swapBuffers32( GraphicBuffer &bufferB ); // swap bufferB to the screen (8 bit version) // returns new back buffer unsigned char *swapBuffers8( unsigned char *bufferPtrB, short bufferHigh, short bufferWide ); // NOTE: the bodies of these functions must occur in the body of the main DDraw code file // i.e., in the file where all the directDraw objects are instantiated. // these functions assume the ddraw ojects are declared globallygravitation-3+dfsg1.orig/minorGems/graphics/getKey.h0000644000175000017500000000234510762704567021323 0ustar pabspabs// Jason Rohrer // getKey.h /** * * general interface for getting current key depressed * Implemented by a graphix framework on a particular platform * * * Created 12-15-99 * Mods: * */ // returns true if key represented by given key code is down char getKeyDown( int vKeyCode ); // returns true if key is up char getKeyUp( int vKeyCode ); /** Sample PC implementation #include getKeyDown( int vKeyCode ) { return ((GetAsyncKeyState(vKeyCode) & 0x8000) ? true : false); } getKeyUp( int vKeyCode ) { return ((GetAsyncKeyState(vKeyCode) & 0x8000) ? false : true); } Sample Mac implementation #include getKeyDown( int vKeyCode ) { KeyMapByteArray keyArray; GetKeys( keyArray ); int arrayInd = vKeyCode >> 3; // divide by 8 to get start array index of key code unsigned char neededByte = keyArray[ arrayInd ]; return (neededByte >> vKeyCode % 8) && 0x01; // trim off bit needed } getKeyUp( int vKeyCode ) { KeyMapByteArray keyArray; GetKeys( keyArray ); int arrayInd = vKeyCode >> 3; // divide by 8 to get start array index of key code unsigned char neededByte = keyArray[ arrayInd ]; return !((neededByte >> vKeyCode % 8) && 0x01); // trim off bit needed, and invert } */gravitation-3+dfsg1.orig/minorGems/graphics/GraphicBuffer.h0000644000175000017500000001327610762704567022607 0ustar pabspabs// Jason Rohrer // GraphicBufffer.h /** * * Graphic buffer, with functions for manipulation * * * Created 11-8-99 * Mods: * Jason Rohrer 12-12-99 Added support for drawing IconMap objects * Jason Rohrer 11-18-2000 Added a getBuffer function. */ #ifndef GRAPHIC_BUFFER_INCLUDED #define GRAPHIC_BUFFER_INCLUDED #include "Color.h" #include #include "IconMap.h" class GraphicBuffer { public: GraphicBuffer( unsigned long *buff, int buffW, int buffH ); ~GraphicBuffer(); // draw a solid image into the buffer void drawImage( unsigned long *image, int *imageYOffset, int xPos, int yPos, int wide, int high ); // draw a transparent image into the buffer void drawImageAlpha( unsigned long *image, int *imageYOffset, int xPos, int yPos, int wide, int high ); // replace a rectangle in the buffer with bgColor void eraseImage( int xPos, int yPos, int wide, int high, Color &bgColor ); // draw a solid IconMap into the buffer void drawIconMap( IconMap *icon, int xPos, int yPos ); // draw a transparent image into the buffer void drawIconMapAlpha( IconMap *icon, int xPos, int yPos ); // replace a rectangle (over icon) in the buffer with bgColor void eraseIconMap( IconMap *icon, int xPos, int yPos, Color &bgColor ); // set buffer to a new buffer of the same size void setBuffer( unsigned long *buff ); // get the pixel buffer unsigned long *getBuffer(); int getWidth(); int getHeight(); // fill buffer with a color void fill( Color &fillC ); // take a screen shot, save to disc void screenShot( FILE *f ); private: unsigned long *buffer; int bufferHigh; int bufferWide; int *buffYOffset; float invChannelMax; Color utilColor; // color for using composite functions }; inline GraphicBuffer::GraphicBuffer( unsigned long *buff, int buffW, int buffH) : utilColor(0,0,0,0) { invChannelMax = 1 / 255.0; bufferHigh = buffH; bufferWide = buffW; buffer = buff; // precalc'ed y contributions to linear indexing of buffer buffYOffset = new int[bufferHigh]; for( int y=0; y bufferHigh ) { maxY = bufferHigh; } int minX = xPos; if( minX < 0 ) { minX = 0; } int maxX = xPos + wide; if( maxX > bufferWide ) { maxX = bufferWide; } for( int y=minY; y bufferHigh ) { maxY = bufferHigh; } int minX = xPos; if( minX < 0 ) { minX = 0; } int maxX = xPos + wide; if( maxX > bufferWide ) { maxX = bufferWide; } unsigned long composite = bgColor.composite; for( int y=minY; y bufferHigh ) { maxY = bufferHigh; } int minX = xPos; if( minX < 0 ) { minX = 0; } int maxX = xPos + wide; if( maxX > bufferWide ) { maxX = bufferWide; } for( int y=minY; y> 24) * invChannelMax; float oneMinusAlpha = 1-alpha; unsigned long buffARGB = buffer[ buffYContrib + x ]; argb = utilColor.getWeightedComposite( argb, alpha ); buffARGB = utilColor.getWeightedComposite( buffARGB, oneMinusAlpha ); unsigned long sum = utilColor.sumComposite( argb, buffARGB ); buffer[ buffYContrib + x ] = sum; } } } inline void GraphicBuffer::drawIconMap( IconMap *icon, int xPos, int yPos ) { drawImage( icon->imageMap, icon->yOffset, xPos, yPos, icon->wide, icon->high ); } inline void GraphicBuffer::drawIconMapAlpha( IconMap *icon, int xPos, int yPos ) { drawImageAlpha( icon->imageMap, icon->yOffset, xPos, yPos, icon->wide, icon->high ); } inline void GraphicBuffer::eraseIconMap( IconMap *icon, int xPos, int yPos, Color &bgColor ) { eraseImage( xPos, yPos, icon->wide, icon->high, bgColor ); } inline void GraphicBuffer::fill( Color &fillC ) { unsigned long composite = fillC.composite; for( int y=0; y #include #include // include the jpeg library as a C file. // (yuk... spent way too much time trying to figure this one out!) extern "C" { #include } /* * is used for the decompression * error recovery mechanism. */ #include void JPEGImageConverter::formatImage( Image *inImage, OutputStream *inStream ) { if( inImage->getNumChannels() != 3 ) { printf( "JPEGImageConverter only works on 3-channel images.\n" ); return; } // most of this code was copied without modification from // IJG's example.c // This struct contains the JPEG compression parameters and pointers to // working space (which is allocated as needed by the JPEG library). // It is possible to have several such structures, representing multiple // compression/decompression processes, in existence at once. We refer // to any one struct (and its associated working data) as a "JPEG object". struct jpeg_compress_struct cinfo; // This struct represents a JPEG error handler. It is declared separately // because applications often want to supply a specialized error handler // (see the second half of this file for an example). But here we just // take the easy way out and use the standard error handler, which will // print a message on stderr and call exit() if compression fails. // Note that this struct must live as long as the main JPEG parameter // struct, to avoid dangling-pointer problems. struct jpeg_error_mgr jerr; // More stuff FILE * outfile; // target file JSAMPROW row_pointer[1]; // pointer to JSAMPLE row[s] int row_stride; // physical row width in image buffer // Step 1: allocate and initialize JPEG compression object // We have to set up the error handler first, in case the initialization // step fails. (Unlikely, but it could happen if you are out of memory.) // This routine fills in the contents of struct jerr, and returns jerr's // address which we place into the link field in cinfo. cinfo.err = jpeg_std_error( &jerr ); // Now we can initialize the JPEG compression object. jpeg_create_compress( &cinfo ); // Step 2: specify data destination (eg, a file) // Note: steps 2 and 3 can be done in either order. // use a temp file with a random name to make this more // thread-safe char *fileName = new char[99]; sprintf( fileName, "temp%d.dat", rand() ); // Here we use the library-supplied code to send compressed data to a // stdio stream. You can also write your own code to do something else. // VERY IMPORTANT: use "b" option to fopen() if you are on a machine that // requires it in order to write binary files. if( ( outfile = fopen( fileName, "wb" ) ) == NULL ) { printf( "can't open jpeg conversion temp file %s\n", fileName ); return; } jpeg_stdio_dest( &cinfo, outfile ); // Step 3: set parameters for compression // First we supply a description of the input image. // Four fields of the cinfo struct must be filled in: // image width and height, in pixels cinfo.image_width = inImage->getWidth(); cinfo.image_height = inImage->getHeight(); cinfo.input_components = 3; // # of color components per pixel cinfo.in_color_space = JCS_RGB; // colorspace of input image // Now use the library's routine to set default compression parameters. // (You must set at least cinfo.in_color_space before calling this, // since the defaults depend on the source color space.) jpeg_set_defaults( &cinfo ); // Now you can set any non-default parameters you wish to. // Here we just illustrate the use of // quality (quantization table) scaling: jpeg_set_quality( &cinfo, mQuality, TRUE ); // limit to baseline-JPEG values // Step 4: Start compressor // TRUE ensures that we will write a complete interchange-JPEG file. // Pass TRUE unless you are very sure of what you're doing. jpeg_start_compress( &cinfo, TRUE ); // Step 5: while (scan lines remain to be written) // jpeg_write_scanlines(...); // Here we use the library's state variable cinfo.next_scanline as the // loop counter, so that we don't have to keep track ourselves. // To keep things simple, we pass one scanline per call; you can pass // more if you wish, though. // JSAMPLEs per row in image_buffer row_stride = cinfo.image_width * 3; // channels of inImage, which we will need to pull pixel values out of double *redChannel = inImage->getChannel(0); double *greenChannel = inImage->getChannel(1); double *blueChannel = inImage->getChannel(2); // array that we will copy inImage pixels into // one scanline at a time row_pointer[0] = new JSAMPLE[ row_stride ]; //int rowNumber = 0; while( cinfo.next_scanline < cinfo.image_height ) { // jpeg_write_scanlines expects an array of pointers to scanlines. // Here the array is only one element long, but you could pass // more than one scanline at a time if that's more convenient. // make a scanline int yOffset = cinfo.next_scanline * cinfo.image_width; // for each pixel in the row for( int p=0; pgetLength(); unsigned char *fileBuffer = new unsigned char[ fileLength ]; fread( fileBuffer, 1, fileLength, inFile ); // now write the entire buffer to our output stream inStream->write( fileBuffer, fileLength ); delete [] fileBuffer; delete file; fclose( inFile ); // delete this temporary file remove( fileName ); delete [] fileName; // And we're done! } // copied this directly from IJG's example.c //extern "C" { /* * ERROR HANDLING: * * The JPEG library's standard error handler (jerror.c) is divided into * several "methods" which you can override individually. This lets you * adjust the behavior without duplicating a lot of code, which you might * have to update with each future release. * * Our example here shows how to override the "error_exit" method so that * control is returned to the library's caller when a fatal error occurs, * rather than calling exit() as the standard error_exit method does. * * We use C's setjmp/longjmp facility to return * control. This means that the * routine which calls the JPEG library must * first execute a setjmp() call to * establish the return point. We want the replacement error_exit to do a * longjmp(). But we need to make the setjmp buffer accessible to the * error_exit routine. To do this, we make a private extension of the * standard JPEG error handler object. (If we were using C++, we'd say we * were making a subclass of the regular error handler.) * * Here's the extended error handler struct: */ struct my_error_mgr { struct jpeg_error_mgr pub; /* "public" fields */ jmp_buf setjmp_buffer; /* for return to caller */ }; typedef struct my_error_mgr * my_error_ptr; /* * Here's the routine that will replace the standard error_exit method: */ METHODDEF(void) my_error_exit( j_common_ptr cinfo ) { /* cinfo->err really points to a my_error_mgr struct, so coerce pointer */ my_error_ptr myerr = (my_error_ptr)( cinfo->err ); /* Always display the message. */ /* We could postpone this until after returning, if we chose. */ (*cinfo->err->output_message)( cinfo ); /* Return control to the setjmp point */ longjmp( myerr->setjmp_buffer, 1 ); } // } Image *JPEGImageConverter::deformatImage( InputStream *inStream ) { // use a temp file with a random name to make this more // thread-safe char *fileName = new char[99]; sprintf( fileName, "temp%d.dat", rand() ); FILE *tempFile = fopen( fileName, "wb" ); if( tempFile == NULL ) { printf( "can't open jpeg conversion temp file %s\n", fileName ); return NULL; } // buffer for dumping stream to temp file unsigned char *tempBuffer = new unsigned char[1]; unsigned char previousByte = 0; // dump the JPEG stream from the input stream into tempFile // so that we can pass this file to libjpeg /* // optimization: use a buffer to prevent too many fwrite calls int bufferLength = 5000; unsigned char *fileBuffer = new unsigned char[ bufferLength ]; int currentBufferPosition = 0; while( !( tempBuffer[0] == 0xD9 && previousByte == 0xFF ) ) { previousByte = tempBuffer[0]; inStream->read( tempBuffer, 1 ); fileBuffer[currentBufferPosition] = tempBuffer[0]; if( currentBufferPosition == bufferLength - 1 ) { // at the end of the file buffer fwrite( fileBuffer, 1, bufferLength, tempFile ); currentBufferPosition = 0; } else { // keep filling the fileBuffer currentBufferPosition++; } } // now write remaining fileBuffer data to file fwrite( fileBuffer, 1, currentBufferPosition + 1, tempFile ); delete [] fileBuffer; */ // write until EOI sequence seen (0xFFD9) while( !( tempBuffer[0] == 0xD9 && previousByte == 0xFF ) ) { previousByte = tempBuffer[0]; inStream->read( tempBuffer, 1 ); fwrite( tempBuffer, 1, 1, tempFile ); } // end of jpeg stream reached. fclose( tempFile ); delete [] tempBuffer; // the remainder of this method was mostly copied from // IJG's example.c /* This struct contains the JPEG decompression parameters and pointers to * working space (which is allocated as needed by the JPEG library). */ struct jpeg_decompress_struct cinfo; /* We use our private extension JPEG error handler. * Note that this struct must live as long as the main JPEG parameter * struct, to avoid dangling-pointer problems. */ struct my_error_mgr jerr; /* More stuff */ FILE * infile; /* source file */ JSAMPARRAY buffer; /* Output row buffer */ int row_stride; /* physical row width in output buffer */ /* In this example we want to open the input * file before doing anything else, * so that the setjmp() error recovery below can assume the file is open. * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that * requires it in order to read binary files. */ if( ( infile = fopen( fileName, "rb" ) ) == NULL ) { printf( "can't open jpeg conversion temp file %s\n", fileName ); return NULL; } /* Step 1: allocate and initialize JPEG decompression object */ /* We set up the normal JPEG error routines, then override error_exit. */ cinfo.err = jpeg_std_error(&jerr.pub); jerr.pub.error_exit = my_error_exit; /* Establish the setjmp return context for my_error_exit to use. */ if( setjmp( jerr.setjmp_buffer ) ) { /* If we get here, the JPEG code has signaled an error. * We need to clean up the JPEG object, * close the input file, and return. */ jpeg_destroy_decompress( &cinfo ); fclose( infile ); printf( "error in decompressing jpeg from stream.\n" ); return NULL; } /* Now we can initialize the JPEG decompression object. */ jpeg_create_decompress( &cinfo ); /* Step 2: specify data source (eg, a file) */ jpeg_stdio_src( &cinfo, infile ); /* Step 3: read file parameters with jpeg_read_header() */ (void) jpeg_read_header( &cinfo, TRUE ); /* We can ignore the return value from jpeg_read_header since * (a) suspension is not possible with the stdio data source, and * (b) we passed TRUE to reject a tables-only JPEG file as an error. * See libjpeg.doc for more info. */ /* Step 4: set parameters for decompression */ /* In this example, we don't need to change any of the defaults set by * jpeg_read_header(), so we do nothing here. */ /* Step 5: Start decompressor */ (void) jpeg_start_decompress( &cinfo ); /* We can ignore the return value since suspension is not possible * with the stdio data source. */ /* We may need to do some setup of our own at this point before reading * the data. After jpeg_start_decompress() we have the correct scaled * output image dimensions available, as well as the output colormap * if we asked for color quantization. * In this example, we need to make an output work buffer of the right size. */ /* JSAMPLEs per row in output buffer */ int imageWidth = cinfo.output_width; int imageHeight = cinfo.output_height; // the return image with 3 channels Image *returnImage = new Image( imageWidth, imageHeight, 3, false ); // channels of returnImage, // which we will need to put pixel values into of double *redChannel = returnImage->getChannel(0); double *greenChannel = returnImage->getChannel(1); double *blueChannel = returnImage->getChannel(2); int currentIndex = 0; row_stride = cinfo.output_width * cinfo.output_components; /* Make a one-row-high sample array that * will go away when done with image */ buffer = ( *cinfo.mem->alloc_sarray ) ((j_common_ptr) &cinfo, JPOOL_IMAGE, row_stride, 1 ); /* Step 6: while (scan lines remain to be read) */ /* jpeg_read_scanlines(...); */ /* Here we use the library's state variable cinfo.output_scanline as the * loop counter, so that we don't have to keep track ourselves. */ int rowNumber = 0; double inv255 = 1.0 / 255.0; while( cinfo.output_scanline < cinfo.output_height ) { /* jpeg_read_scanlines expects an array of pointers to scanlines. * Here the array is only one element long, but you could ask for * more than one scanline at a time if that's more convenient. */ (void) jpeg_read_scanlines( &cinfo, buffer, 1 ); // write the scanline into returnImage int yOffset = rowNumber * cinfo.output_width; // for each pixel in the row // copy it into the return image channels for( int p=0; p> 8 ) & 0xFF ); buffer[2] = (unsigned char)( ( inLong >> 16 ) & 0xFF ); buffer[3] = (unsigned char)( ( inLong >> 24 ) & 0xFF ); inStream->write( buffer, 4 ); } inline long LittleEndianImageConverter::readLittleEndianLong( InputStream *inStream ) { unsigned char buffer[4]; inStream->read( buffer, 4 ); long outLong = buffer[0] | ( buffer[1] << 8 ) | ( buffer[2] << 16 ) | ( buffer[3] << 24 ); return outLong; } inline void LittleEndianImageConverter::writeLittleEndianShort( short inShort, OutputStream *inStream ) { unsigned char buffer[2]; buffer[0] = (unsigned char)( inShort & 0xFF ); buffer[1] = (unsigned char)( ( inShort >> 8 ) & 0xFF ); inStream->write( buffer, 2 ); } inline short LittleEndianImageConverter::readLittleEndianShort( InputStream *inStream ) { unsigned char buffer[2]; inStream->read( buffer, 2 ); long outShort = buffer[0] | ( buffer[1] << 8 ); return outShort; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/converters/jpegConverterTest.cpp0000644000175000017500000000366310762704567026301 0ustar pabspabs/* * Modification History * * 2001-April-27 Jason Rohrer * Created. * * 2001-April-29 Jason Rohrer * Completed initial version and used to test JPEGImageConverter * successfully. */ #include #include "minorGems/graphics/Image.h" #include "JPEGImageConverter.h" #include "minorGems/io/file/File.h" #include "minorGems/io/file/FileOutputStream.h" #include "minorGems/io/file/FileInputStream.h" // test function for the BMPImageConverter class int main( char inNumArgs, char**inArgs ) { if( inNumArgs != 2 ) { printf( "must pass in a file name to write to\n" ); return 1; } int length = 0; while( inArgs[1][length] != '\0' ) { length++; } File *file = new File( NULL, inArgs[1], length ); // read image in FileInputStream *stream = new FileInputStream( file ); JPEGImageConverter *converter = new JPEGImageConverter( 50 ); Image *image = converter->deformatImage( stream ); if( image != NULL ) { // write image back out File *fileOut = new File( NULL, "testOut.jpg", 11 ); FileOutputStream *outStream = new FileOutputStream( fileOut ); converter->formatImage( image, outStream ); delete outStream; delete fileOut; delete image; } delete stream; delete converter; delete file; /* FileOutputStream *stream = new FileOutputStream( file ); JPEGImageConverter *converter = new JPEGImageConverteonverter( 50 ); Image *image = new Image( 256, 256, 3 ); double *red = image->getChannel( 0 ); double *green = image->getChannel( 1 ); for( int y=0; ygetHeight(); y++ ) { for( int x=0; xgetWidth(); x++ ) { long index = y * image->getWidth() + x; red[index] = (double)y / (double)( image->getHeight() ); green[index] = (double)x / (double)( image->getWidth() ); //red[index] = 1.0; } } converter->formatImage( image, stream ); delete stream; // delete file explicitly delete file; delete converter; delete image; */ return 0; } gravitation-3+dfsg1.orig/minorGems/graphics/converters/bmpConverterTest.cpp0000644000175000017500000000376710762704567026137 0ustar pabspabs/* * Modification History * * 2001-February-19 Jason Rohrer * Created. * * 2001-February-24 Jason Rohrer * Fixed incorrect delete usage. * * 2001-April-12 Jason Rohrer * Changed to comply with new FileInput/OutputStream interface * (underlying File must be destroyed explicitly). */ #include #include "minorGems/graphics/Image.h" #include "BMPImageConverter.h" #include "minorGems/io/file/File.h" #include "minorGems/io/file/FileOutputStream.h" #include "minorGems/io/file/FileInputStream.h" // test function for the BMPImageConverter class int main( char inNumArgs, char**inArgs ) { if( inNumArgs != 2 ) { printf( "must pass in a file name to write to\n" ); return 1; } int length = 0; while( inArgs[1][length] != '\0' ) { length++; } File *file = new File( NULL, inArgs[1], length ); // read image in FileInputStream *stream = new FileInputStream( file ); BMPImageConverter *converter = new BMPImageConverter(); Image *image = converter->deformatImage( stream ); if( image != NULL ) { // write image back out File *fileOut = new File( NULL, "testOut.bmp", 11 ); FileOutputStream *outStream = new FileOutputStream( fileOut ); converter->formatImage( image, outStream ); delete outStream; delete image; } delete stream; delete file; delete converter; /* FileOutputStream *stream = new FileOutputStream( file ); BMPImageConverter *converter = new BMPImageConverter(); Image *image = new Image( 256, 256, 3 ); double *red = image->getChannel( 0 ); double *green = image->getChannel( 1 ); for( int y=0; ygetHeight(); y++ ) { for( int x=0; xgetWidth(); x++ ) { long index = y * image->getWidth() + x; red[index] = (double)y / (double)( image->getHeight() ); green[index] = (double)x / (double)( image->getWidth() ); //red[index] = 1.0; } } converter->formatImage( image, stream ); delete stream; // delete file explicitly delete file; delete converter; delete image; */ return 0; } gravitation-3+dfsg1.orig/minorGems/graphics/converters/JPEGImageConverter.h0000644000175000017500000000317410762704567025646 0ustar pabspabs/* * Modification History * * 2001-April-27 Jason Rohrer * Created. */ #ifndef JPEG_IMAGE_CONVERTER_INCLUDED #define JPEG_IMAGE_CONVERTER_INCLUDED #include "minorGems/graphics/ImageConverter.h" /** * JPEG implementation of the image conversion interface. * * Implementations are platform dependent. * * @author Jason Rohrer */ class JPEGImageConverter : public ImageConverter { public: /** * Constructs a JPEGImageConverter. * * @param inQuality a quality value in [0,100] for compression. * 100 specifies highest quality. */ JPEGImageConverter( int inQuality ); /** * Sets the compression quality. * * @param inQuality a quality value in [0,100]. 100 * specifies highest quality. */ void setQuality( int inQuality ); /** * Gets the compression quality. * * @return a quality value in [0,100]. 100 * indicates highest quality. */ int getQuality(); // implement the ImageConverter interface virtual void formatImage( Image *inImage, OutputStream *inStream ); virtual Image *deformatImage( InputStream *inStream ); private: int mQuality; }; inline JPEGImageConverter::JPEGImageConverter( int inQuality ) : mQuality( inQuality ) { if( mQuality > 100 || mQuality < 0 ) { printf( "JPEG quality must be in [0,100]\n" ); mQuality = 50; } } inline void JPEGImageConverter::setQuality( int inQuality ) { mQuality = inQuality; if( mQuality > 100 || mQuality < 0 ) { printf( "JPEG quality must be in [0,100]\n" ); mQuality = 50; } } inline int JPEGImageConverter::getQuality() { return mQuality; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/converters/BigEndianImageConverter.h0000644000175000017500000000524210762704567026737 0ustar pabspabs/* * Modification History * * 2006-November-21 Jason Rohrer * Created. Copied from LittleEndian version. */ #ifndef BIG_ENDIAN_IMAGE_CONVERTER_INCLUDED #define BIG_ENDIAN_IMAGE_CONVERTER_INCLUDED #include "minorGems/graphics/ImageConverter.h" /** * A base class for converters that have big endian file formats. * Basically includes big endian reading and writing functions. * * @author Jason Rohrer */ class BigEndianImageConverter : public ImageConverter { public: // does not implement the ImageConverter interface, // which makes this class abstract. protected: /** * Writes a long value in big endian format. * * @param inLong the long value to write. * @param inStream the stream to write inLong to. */ void writeBigEndianLong( long inLong, OutputStream *inStream ); /** * Writes a short value in big endian format. * * @param inShort the short value to write. * @param inStream the stream to write inShort to. */ void writeBigEndianShort( short inShort, OutputStream *inStream ); /** * Reads a long value in big endian format. * * @param inStream the stream to read the long value from. * * @return the long value. */ long readBigEndianLong( InputStream *inStream ); /** * Reads a short value in big endian format. * * @param inStream the stream to read the short value from. * * @return the short value. */ short readBigEndianShort( InputStream *inStream ); }; inline void BigEndianImageConverter::writeBigEndianLong( long inLong, OutputStream *inStream ) { unsigned char buffer[4]; buffer[0] = (unsigned char)( ( inLong >> 24 ) & 0xFF ); buffer[1] = (unsigned char)( ( inLong >> 16 ) & 0xFF ); buffer[2] = (unsigned char)( ( inLong >> 8 ) & 0xFF ); buffer[3] = (unsigned char)( inLong & 0xFF ); inStream->write( buffer, 4 ); } inline long BigEndianImageConverter::readBigEndianLong( InputStream *inStream ) { unsigned char buffer[4]; inStream->read( buffer, 4 ); long outLong = ( buffer[0] << 24 ) | ( buffer[1] << 16 ) | ( buffer[2] << 8 ) | buffer[3]; return outLong; } inline void BigEndianImageConverter::writeBigEndianShort( short inShort, OutputStream *inStream ) { unsigned char buffer[2]; buffer[0] = (unsigned char)( ( inShort >> 8 ) & 0xFF ); buffer[1] = (unsigned char)( inShort & 0xFF ); inStream->write( buffer, 2 ); } inline short BigEndianImageConverter::readBigEndianShort( InputStream *inStream ) { unsigned char buffer[2]; inStream->read( buffer, 2 ); long outShort = ( buffer[0] << 8 ) | buffer[1]; return outShort; } #endif gravitation-3+dfsg1.orig/minorGems/graphics/converters/PNGImageConverter.cpp0000644000175000017500000002570210762704567026101 0ustar pabspabs/* * Modification History * * 2006-November-21 Jason Rohrer * Created. */ #include "PNGImageConverter.h" #include "minorGems/util/SimpleVector.h" //#include PNGImageConverter::PNGImageConverter() { // set up the CRC table // code taken from the PNG spec: // http://www.w3.org/TR/2003/REC-PNG-20031110/#D-CRCAppendix unsigned long c; int n, k; for( n=0; n<256; n++ ) { c = (unsigned long)n; for( k=0; k<8; k++ ) { if( c & 1 ) { c = 0xedb88320L ^ (c >> 1); } else { c = c >> 1; } } mCRCTable[n] = c; } } unsigned long PNGImageConverter::updateCRC( unsigned long inCRC, unsigned char *inData, int inLength ) { // code taken from the PNG spec: // http://www.w3.org/TR/2003/REC-PNG-20031110/#D-CRCAppendix unsigned long c = inCRC; int n; for( n=0; n> 8); } return c; } #define ADLER_BASE 65521 /* largest prime smaller than 65536 */ /** * Updates an adler32 checksum. * code found here http://www.ietf.org/rfc/rfc1950.txt * * New adlers should start with inAdler set to 1. * * @param inAdler the current state of the checksum. * @param inData the data to add. Destroyed by caller. * @param inLength the length of the data in bytes. * * @return the new checksum. */ unsigned long updateAdler32( unsigned long inAdler, unsigned char *inData, int inLength ) { unsigned long s1 = inAdler & 0xffff; unsigned long s2 = (inAdler >> 16) & 0xffff; int n; for (n = 0; n < inLength; n++) { s1 = (s1 + inData[n]) % ADLER_BASE; s2 = (s2 + s1) % ADLER_BASE; } return (s2 << 16) + s1; } void PNGImageConverter::writeChunk( char inChunkType[4], unsigned char *inData, unsigned long inNumBytes, OutputStream *inStream ) { // chunk layout: // 4-byte length // 4-char type // data // 4-byte CRC (applied to type and data parts) // write the length writeBigEndianLong( inNumBytes, inStream ); inStream->write( (unsigned char *)inChunkType, 4 ); // start the crc unsigned long crc = updateCRC( mStartCRC, (unsigned char *)inChunkType, 4 ); if( inData != NULL ) { // chunk has data inStream->write( inData, inNumBytes ); crc = updateCRC( crc, inData, inNumBytes ); } // final step: invert the CRC crc = crc ^ 0xffffffffL; // now write the CRC writeBigEndianLong( crc, inStream ); } void PNGImageConverter::formatImage( Image *inImage, OutputStream *inStream ) { int numChannels = inImage->getNumChannels(); // make sure the image is in the right format if( numChannels != 3 && numChannels != 4 ) { printf( "Only 3- and 4-channel images can be converted to " ); printf( "the PNG format.\n" ); return; } long width = inImage->getWidth(); long height = inImage->getHeight(); // same for all PNG images // used to check for basic transmission errors, such as line-end flipping unsigned char pngSignature[8] = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; inStream->write( pngSignature, 8 ); // data for IHDR chunk unsigned char headerData[13]; // width headerData[0] = (width >> 24) & 0xff; headerData[1] = (width >> 16) & 0xff; headerData[2] = (width >> 8) & 0xff; headerData[3] = width & 0xff; // height headerData[4] = (height >> 24) & 0xff; headerData[5] = (height >> 16) & 0xff; headerData[6] = (height >> 8) & 0xff; headerData[7] = height & 0xff; // bit depth headerData[8] = 8; // color type // 2 = truecolor (RGB) headerData[9] = 2; // compression method // method 0 (deflate) headerData[10] = 0; // filter method // method 0 supports 5 filter types headerData[11] = 0; // no interlace headerData[12] = 0; writeChunk( "IHDR", headerData, 13, inStream ); int numRawBytes = width * height * 3; // extra byte per scanline for filter type numRawBytes += height; unsigned char *rawScanlineBytes = new unsigned char[ numRawBytes ]; // ignore alpha channel double *channels[3]; int i; for( i=0; i<3; i++ ) { channels[i] = inImage->getChannel( i ); } int pixelNumber = 0; for( int y=0; y zlibBlock; // compression method 8 (deflate) // with a LZ77 window size parameter of w=7 // LZ77 window size is then 2^( w + 8 ), or in this case 32768 zlibBlock.push_back( 0x78 ); // flags // compression level 0 (2 bytes = 00b) // no preset dictionary (1 byte = 0b) // check bits for compression method (5 bits) // Should be such that if the 8-bit compression method, followed // by the 8-bit flags field, is viewed as a 16-bit number, // it is an even multiple of 31 // For our settings, check bits of 00001 works //zlibBlock.push_back( 0x01 ); // hack: mimic zlib here zlibBlock.push_back( 0xda ); // now ready for compressed data blocks int rawDataIndex = 0; // length field is 16 bits int maxUncompressedBlockLength = 65535; while( rawDataIndex < numRawBytes ) { // push another deflate block // first bit BFINAL // only 1 for final block // next two bits BTYPE // BTYPE=00 is an uncompressed block // remaining 5 bits ignored // Thus, we put 0x00 for uncompressed blocks that are not final // and 0x80 for final uncompressed block int bytesLeft = numRawBytes - rawDataIndex; int bytesInBlock; if( bytesLeft <= maxUncompressedBlockLength ) { // final // hack: when comparing output with zlib, noticed that it doesn't // set 0x80 for the final block, instead it uses 0x01 // For some reason, this was making the PNG unreadable // zlibBlock.push_back( 0x80 ); zlibBlock.push_back( 0x01 ); bytesInBlock = bytesLeft; } else { // not final zlibBlock.push_back( 0x00 ); bytesInBlock = maxUncompressedBlockLength; } // length in least-significant-byte-first order unsigned char firstLengthByte = bytesInBlock & 0xff; unsigned char secondLengthByte = (bytesInBlock >> 8) & 0xff; zlibBlock.push_back( firstLengthByte ); zlibBlock.push_back( secondLengthByte ); // those same length bytes inverted // (called "one's compliment" in the spec zlibBlock.push_back( firstLengthByte ^ 0xff); zlibBlock.push_back( secondLengthByte ^ 0xff ); // now the uncompressed data for( int b=0; b< bytesInBlock; b++ ) { zlibBlock.push_back( rawScanlineBytes[ rawDataIndex ] ); rawDataIndex++; } } // finally, adler32 of original data unsigned long adler = updateAdler32( 1L, rawScanlineBytes, numRawBytes ); zlibBlock.push_back( (adler >> 24) & 0xff ); zlibBlock.push_back( (adler >> 16) & 0xff ); zlibBlock.push_back( (adler >> 8) & 0xff ); zlibBlock.push_back( adler & 0xff ); // the zlib block is now complete /* // check against real zlib implementation z_stream zStream; zStream.next_in = rawScanlineBytes; zStream.avail_in = numRawBytes; zStream.total_in = 0; int outSize = 2 * numRawBytes + 100; unsigned char *zlibOutBuffer = new unsigned char[ outSize ]; zStream.next_out = zlibOutBuffer; zStream.avail_out = outSize; zStream.total_out = 0; zStream.data_type = Z_BINARY; zStream.zalloc = Z_NULL; zStream.zfree = Z_NULL; // init the stream // no compression int result; //result = deflateInit( &zStream, Z_DEFAULT_COMPRESSION); result = deflateInit( &zStream, Z_NO_COMPRESSION); if( result != Z_OK ) { printf( "zlib deflateInit error: %s\n", zStream.msg ); } // deflate and flush result = deflate( &zStream, Z_FINISH ); if( result != Z_STREAM_END ) { printf( "zlib deflate error (%d): %s\n", result, zStream.msg ); } printf( "Total in = %d, total out = %d\n", zStream.total_in, zStream.total_out ); printf( "Our raw bytes (%d):\n", numRawBytes ); int b; for( b=0; b zlibBlock.size() ) { minBytes = zlibBlock.size(); } for( b=0; bgetNumChannels() != 3 ) { printf( "Only 3-channel images can be converted to the BMP format.\n" ); return; } long width = inImage->getWidth(); long height = inImage->getHeight(); long numPixels = width * height; // each line should be padded with zeros to // end on a 4-byte boundary int numZeroPaddingBytes = ( 4 - ( width * 3 ) % 4 ) % 4; short bitCount = 24; long rasterSize = numPixels * 3; // zero padding bytes for each row rasterSize += numZeroPaddingBytes * height; // offset past two headers long offsetToRaster = 14 + 40; long fileSize = offsetToRaster + rasterSize; long compressionType = 0; long pixelsPerMeter = 2834; // both are 0 since we have no color map long colorsUsed = 0; long colorsImportant = 0; // write the header unsigned char *signature = new unsigned char[2]; signature[0] = 'B'; signature[1] = 'M'; inStream->write( signature, 2 ); delete [] signature; writeLittleEndianLong( fileSize, inStream ); writeLittleEndianLong( 0, inStream ); writeLittleEndianLong( offsetToRaster, inStream ); // write the info header // header size writeLittleEndianLong( 40, inStream ); writeLittleEndianLong( width, inStream ); writeLittleEndianLong( height, inStream ); // numPlanes writeLittleEndianShort( 1, inStream ); writeLittleEndianShort( bitCount, inStream ); writeLittleEndianLong( compressionType, inStream ); writeLittleEndianLong( rasterSize, inStream ); writeLittleEndianLong( pixelsPerMeter, inStream ); writeLittleEndianLong( pixelsPerMeter, inStream ); writeLittleEndianLong( colorsUsed, inStream ); writeLittleEndianLong( colorsImportant, inStream ); // no color table... // now write the raster unsigned char *raster = new unsigned char[ rasterSize ]; double *red = inImage->getChannel( 0 ); double *green = inImage->getChannel( 1 ); double *blue = inImage->getChannel( 2 ); // pixels are stored bottom-up, left to right // (row major order) long rasterIndex = 0; for( int y=height-1; y>=0; y-- ) { for( int x=0; xwrite( raster, rasterSize ); delete [] raster; } inline Image *BMPImageConverter::deformatImage( InputStream *inStream ) { // temp buffer used to skip data in the stream unsigned char *temp = new unsigned char[ 100 ]; // skip signature inStream->read( temp, 2 ); long fileSize = readLittleEndianLong( inStream ); // skip unused inStream->read( temp, 4 ); long rasterOffset = readLittleEndianLong( inStream ); long rasterSize = fileSize - rasterOffset; // skip size of header inStream->read( temp, 4 ); long width = readLittleEndianLong( inStream ); long height = readLittleEndianLong( inStream ); // skip planes inStream->read( temp, 2 ); short bitCount = readLittleEndianShort( inStream ); char failing = false; if( bitCount != 24 ) { printf( "Only 24-bit BMP file formats supported.\n" ); failing = true; } long compression = readLittleEndianLong( inStream ); if( compression != 0 ) { printf( "Only uncompressed BMP file formats supported.\n" ); failing = true; } // skip imageSize, resolution, and color usage information inStream->read( temp, 20 ); // now we're at the raster. // each line should be padded with zeros to // end on a 4-byte boundary int numZeroPaddingBytes = ( 4 - ( width * 3 ) % 4 ) % 4; unsigned char *raster = new unsigned char[ rasterSize ]; inStream->read( raster, rasterSize ); Image *returnImage; if( failing ) { return NULL; } else { returnImage = new Image( width, height, 3 ); double *red = returnImage->getChannel( 0 ); double *green = returnImage->getChannel( 1 ); double *blue = returnImage->getChannel( 2 ); // pixels are stored bottom-up, left to right // (row major order) long rasterIndex = 0; for( int y=height-1; y>=0; y-- ) { for( int x=0; xgetNumChannels(); // make sure the image is in the right format if( numChannels != 3 && numChannels != 4 ) { printf( "Only 3- and 4-channel images can be converted to " ); printf( "the TGA format.\n" ); return; } long width = inImage->getWidth(); long height = inImage->getHeight(); long numPixels = width * height; // a buffer for writing single bytes unsigned char *byteBuffer = new unsigned char[1]; // write the identification field size // (an empty identification field) byteBuffer[0] = 0; inStream->write( byteBuffer, 1 ); // write the color map type // (no color map) byteBuffer[0] = 0; inStream->write( byteBuffer, 1 ); // write the image type code // (type 2: unmapped RGB image) byteBuffer[0] = 2; inStream->write( byteBuffer, 1 ); // no color map spec // (set to 0, though it will be ignored) unsigned char *colorMapSpec = new unsigned char[5]; int i; for( i=0; i<5; i++ ) { colorMapSpec[i] = 0; } inStream->write( colorMapSpec, 5 ); delete [] colorMapSpec; // now for the image specification // x origin coordinate writeLittleEndianShort( 0, inStream ); // y origin coordinate writeLittleEndianShort( 0, inStream ); writeLittleEndianShort( width, inStream ); writeLittleEndianShort( height, inStream ); // number of bits in pixels if( numChannels == 3 ) { byteBuffer[0] = 24; } else { byteBuffer[0] = 32; } inStream->write( byteBuffer, 1 ); // image descriptor byte if( numChannels == 3 ) { // setting to 0 specifies: // -- no attributes per pixel (for 24-bit) // -- screen origin in lower left corner // -- non-interleaved data storage byteBuffer[0] = 0; } else { // setting to 8 specifies: // -- 8 attributes per pixel (for 32-bit) (attributes are alpha bits) // -- screen origin in lower left corner // -- non-interleaved data storage byteBuffer[0] = 8; } // set bit 5 to 1 to specify screen origin in upper left corner byteBuffer[0] = byteBuffer[0] | ( 1 << 5 ); inStream->write( byteBuffer, 1 ); // We skip the image identification field, // since we set its length to 0 above. // We also skip the color map data, // since we have none (as specified above). // now we write the pixels, in BGR(A) order unsigned char *raster = new unsigned char[ numPixels * numChannels ]; double *red = inImage->getChannel( 0 ); double *green = inImage->getChannel( 1 ); double *blue = inImage->getChannel( 2 ); long rasterIndex = 0; if( numChannels == 3 ) { for( int i=0; iwrite( raster, numPixels * 3 ); } else { // numChannels == 4 double *alpha = inImage->getChannel( 3 ); for( int i=0; iwrite( raster, numPixels * numChannels ); delete [] raster; delete [] byteBuffer; } inline Image *TGAImageConverter::deformatImage( InputStream *inStream ) { // a buffer for reading single bytes unsigned char *byteBuffer = new unsigned char[1]; // read the identification field size inStream->read( byteBuffer, 1 ); int identificationFieldSize = byteBuffer[0]; // read the color map type // (only 0, or no color map, is supported) inStream->read( byteBuffer, 1 ); if( byteBuffer[0] != 0 ) { printf( "Only TGA files without colormaps can be read.\n" ); delete [] byteBuffer; return NULL; } // read the image type code // (only type 2, unmapped RGB image, is supported) inStream->read( byteBuffer, 1 ); if( byteBuffer[0] != 2 ) { printf( "Only TGA files containing unmapped RGB images can be read.\n" ); delete [] byteBuffer; return NULL; } // ignore color map spec // (skip all 5 bytes of it) unsigned char *colorMapSpec = new unsigned char[5]; inStream->read( colorMapSpec, 5 ); delete [] colorMapSpec; // now for the image specification // don't need either of these // don't set to a variable for now to avoid unused variable warnings // x origin coordinate readLittleEndianShort( inStream ); // y origin coordinate readLittleEndianShort( inStream ); long width = readLittleEndianShort( inStream ); long height = readLittleEndianShort( inStream ); long numPixels = width * height; // number of bits in pixels // only 24 bits per pixel supported inStream->read( byteBuffer, 1 ); if( byteBuffer[0] != 24 && byteBuffer[0] != 32 ) { printf( "Only 24- and 32-bit TGA files can be read.\n" ); delete [] byteBuffer; return NULL; } int numChannels = 0; if( byteBuffer[0] == 24 ) { numChannels = 3; } else { numChannels = 4; } // image descriptor byte // setting to 0 specifies: // -- no attributes per pixel (for 24-bit) // -- screen origin in lower left corner // -- non-interleaved data storage // set bit 5 to 1 to specify screen origin in upper left corner inStream->read( byteBuffer, 1 ); char originAtTop = byteBuffer[0] & ( 1 << 5 ); if( identificationFieldSize > 0 ) { // We skip the image identification field unsigned char *identificationField = new unsigned char[ identificationFieldSize ]; inStream->read( identificationField, identificationFieldSize ); delete [] identificationField; } // We also skip the color map data, // since we have none (as specified above). // now we read the pixels, in BGR(A) order unsigned char *raster = new unsigned char[ numPixels * numChannels ]; inStream->read( raster, numPixels * numChannels ); Image *image = new Image( width, height, numChannels ); double *red = image->getChannel( 0 ); double *green = image->getChannel( 1 ); double *blue = image->getChannel( 2 ); long rasterIndex = 0; double inv255 = 1.0 / 255.0; if( numChannels == 3 ) { if( originAtTop ) { for( int i=0; i=0; y-- ) { for( int x=0; xgetChannel( 3 ); if( originAtTop ) { for( int i=0; i=0; y-- ) { for( int x=0; xScreenGraphics. * Adjusts screen resolution and fills screen with black. * * @param inWidth width of desired full screen. * @param inHeight height of desired full screen. */ ScreenGraphics( int inWidth, int inHeight ); /** * Desctructor restores screen to original state. */ ~ScreenGraphics(); /** * Resizes the screen. * * @param inNewWidth the new width. * @param inNewHeight the new height. */ void resize( int inNewWidth, int inNewHeight ); /** * Gets the pixel buffer used by the screen. * * @return a graphics buffer containing a pointer to the screen * pixels. Must be destroyed by caller. */ GraphicBuffer *getScreenBuffer(); /** * Flips a dirty rectangle onto the screen. * * @param inTopLeftX the X coordinate, in pixels, of the top left * point on the rectangle. * @param inTopLeftY the Y coordinate, in pixels, of the top left * point on the rectangle. * @param inWidth the width of the rectangle. * @param inHeight the height of the rectangle. */ void flipDirtyRectangle( int inTopLeftX, int inTopLeftY, int inWidth, int inHeight ); /** * Flips all the pixels stored in the location pointed to by * getScreenBuffer() onto the screen. */ void flipScreen(); /** * Swaps a buffer to the screen. * The next buffer to be filled is returned in * inOutBuffer. * * No guarentee is made about what will be in the next buffer returned. * (On systems that support on-card double buffering, it may even * be a buffer pointing directly into video memory.) * * @param inOutBuffer pointer to the buffer to swap to the screen, * and pointer where the next buffer will be stored. */ void swapBuffers( GraphicBuffer *inOutBuffer ); /** * Determines whether a particular screen setting is available. * * NOTE: Do not call after constructing a ScreenGraphics instance. * * @param inWidth width of desired full screen. * @param inHeight height of desired full screen. * * @return true iff screen setting is available. */ static char isResolutionAvailable( int inWidth, int inHeight ); private: int mWidth; int mHeight; void *mNativeObjectPointer; }; #endif gravitation-3+dfsg1.orig/minorGems/graphics/ImageColorConverter.h0000644000175000017500000003377610762704567024020 0ustar pabspabs/* * Modification History * * 2001-February-26 Jason Rohrer * Created. * Added functions for converting to and from gray byte arrays. * * 2001-September-19 Jason Rohrer * Added an RGB->HSB conversion function, which was copied * from minorGems/ai/robotics/ImageStatistics. * Added RGB<->YIQ functions. * * 2001-September-20 Jason Rohrer * Fixed a bug in the YIQ conversion. * Got rid of this bug fix, as it distorts the YIQ space, * and there is no way to prevent colors from going out of the * [0,1] range all of the time anyway. * * 2001-September-24 Jason Rohrer * Added RGB<->YCbCr functions. * Abstracted out a common coefficient multiplying function. */ #ifndef IMAGE_COLOR_CONVERTER_INCLUDED #define IMAGE_COLOR_CONVERTER_INCLUDED #include "Image.h" /** * A container class for static functions that convert * images between various color spaces. * * @author Jason Rohrer */ class ImageColorConverter { public: /** * Converts a 3-channel RGB image to a 1-channel grayscale * image using an NTSC luminosity standard. * * @param inImage the RGB image to convert. Must be destroyed * by caller. * * @return a new, grayscale version of inImage. Must be * destroyed by the caller. Returns NULL if inImage * is not a 3-channel image. */ static Image *RGBToGrayscale( Image *inImage ); /** * Converts a 1-channel grayscae image to a 3-channel RGB * image. * * @param inImage the grayscale image to convert. Must be destroyed * by caller. * * @return a new, RGB version of inImage. Must be * destroyed by the caller. Returns NULL if inImage * is not a 1-channel image. */ static Image *grayscaleToRGB( Image *inImage ); /** * Converts a 1-channel grayscae image to a 1-channel byte array. * * @param inImage the grayscale image to convert. Must be destroyed * by caller. * @param inChannelNumber the channel number to use as the * gray channel. Defaults to 0; * * @return a new byte array with one byte per image pixel, * and image [0,1] values mapped to [0,255]. */ static unsigned char *grayscaleToByteArray( Image *inImage, int inChannelNumber = 0 ); /** * Converts a byte array to a 1-channel grayscale * image. * * @param inBytes the byte array to convert. Must be destroyed * by caller. * @param inWidth the width of the image contained in the byte array. * @param inHeight the height of the image contained in the byte array. * * @return a new, grayscale image version of the byte array. Must be * destroyed by the caller. */ static Image *byteArrayToGrayscale( unsigned char *inBytes, int inWidth, int inHeight ); /** * Converts an RGB image to HSB. * * @param inRGBImage the rgb image to convert. * Must be destroyed by caller. * * @return a new image that is the HSB conversion of the * RGB image. Must be destroyed by caller. */ static Image *RGBToHSB( Image *inRGBImage ); /** * Converts an RGB image to YIQ. * * Note that color values in the resulting YIQ * image may lie outside of the range [0,1]. * * @param inRGBImage the rgb image to convert. * Must be destroyed by caller. * * @return a new image that is the YIQ conversion of the * RGB image. Must be destroyed by caller. */ static Image *RGBToYIQ( Image *inRGBImage ); /** * Converts a YIQ image to RGB. * * * Note that color values in the resulting RGB * image may lie outside of the range [0,1]. * * @param inYIQImage the rgb image to convert. * Must be destroyed by caller. * * @return a new image that is the RGB conversion of the * YIQ image. Must be destroyed by caller. */ static Image *YIQToRGB( Image *inYIQImage ); /** * Converts an RGB image to YCbCr. * * Note that in the YCbCr standard, Y is in the range * [0,1], while Cb and Cr are both in the range [-0.5, 0.5]. * This function returns Cb and Cr components shifted * into the range [0,1]. * * @param inRGBImage the rgb image to convert. * Must be destroyed by caller. * * @return a new image that is the YCbCr conversion of the * RGB image. Must be destroyed by caller. */ static Image *RGBToYCbCr( Image *inRGBImage ); /** * Converts a YCbCr image to RGB. * * * Note that in the YCbCr standard, Y is in the range * [0,1], while Cb and Cr are both in the range [-0.5, 0.5]. * This function expects input Cb and Cr components to be shifted * into the range [0,1]. * * @param inYCbCrImage the rgb image to convert. * Must be destroyed by caller. * * @return a new image that is the RGB conversion of the * YCbCr image. Must be destroyed by caller. */ static Image *YCbCrToRGB( Image *inYCbCrImage ); protected: /** * Converts an 3-channel image to another 3-channel * image using a matrix of conversion coefficients. * * The following formulae are used; * outChan0 = inC00 * inChan0 + inC01 * inChan1 + inC02 * inChan2 * outChan1 = inC10 * inChan0 + inC11 * inChan1 + inC12 * inChan2 * outChan2 = inC20 * inChan0 + inC21 * inChan1 + inC22 * inChan2 * * @param inImage the image to convert. * Must be destroyed by caller. * * @return a new image that is inImage converted, or NULL if * conversion failed (usually because inImage does not * contain 3 channels). * Must be destroyed by caller. */ static Image *coefficientConvert( Image *inImage, double inC00, double inC01, double inC02, double inC10, double inC11, double inC12, double inC20, double inC21, double inC22 ); }; inline Image *ImageColorConverter::RGBToGrayscale( Image *inImage ) { int w = inImage->getWidth(); int h = inImage->getHeight(); int numPixels = w * h; Image *grayImage = new Image( w, h, 1 ); double *red = inImage->getChannel( 0 ); double *green = inImage->getChannel( 1 ); double *blue = inImage->getChannel( 2 ); double *gray = grayImage->getChannel( 0 ); for( int i=0; igetWidth(); int h = inImage->getHeight(); int numPixels = w * h; Image *rgbImage = new Image( w, h, 3 ); double *red = rgbImage->getChannel( 0 ); double *green = rgbImage->getChannel( 1 ); double *blue = rgbImage->getChannel( 2 ); double *gray = inImage->getChannel( 0 ); for( int i=0; igetWidth(); int h = inImage->getHeight(); int numPixels = w * h; unsigned char *bytes = new unsigned char[ numPixels ]; double *gray = inImage->getChannel( inChannelNumber ); for( int i=0; igetChannel( 0 ); for( int i=0; igetNumChannels() != 3 ) { printf( "RGBtoHSB requires a 3-channel image as input.\n" ); return NULL; } int w = inRGBImage->getWidth(); int h = inRGBImage->getHeight(); int numPixels = w * h; Image *hsbImage = new Image( w, h, 3 ); double *redChannel = inRGBImage->getChannel( 0 ); double *greenChannel = inRGBImage->getChannel( 1 ); double *blueChannel = inRGBImage->getChannel( 2 ); double *hueChannel = hsbImage->getChannel( 0 ); double *satChannel = hsbImage->getChannel( 1 ); double *brightChannel = hsbImage->getChannel( 2 ); for( int i=0; i g) ? r : g; if (b > cmax) { cmax = b; } int cmin = (r < g) ? r : g; if (b < cmin) { cmin = b; } bright = ( (double)cmax ) / 255.0; if( cmax != 0 ) { sat = ( (double)( cmax - cmin ) ) / ( (double) cmax ); } else { sat = 0; } if( sat == 0 ) { hue = 0; } else { double redc = ( (double)( cmax - r ) ) / ( (double)( cmax - cmin ) ); double greenc = ( (double) ( cmax - g ) ) / ( (double)( cmax - cmin ) ); double bluec = ( (double)( cmax - b ) ) / ( (double)( cmax - cmin ) ); if( r == cmax ) { hue = bluec - greenc; } else if( g == cmax ) { hue = 2.0 + redc - bluec; } else { hue = 4.0 + greenc - redc; } hue = hue / 6.0; if( hue < 0 ) { hue = hue + 1.0; } } hueChannel[i] = hue; satChannel[i] = sat; brightChannel[i] = bright; } return hsbImage; } inline Image *ImageColorConverter::RGBToYIQ( Image *inRGBImage ) { if( inRGBImage->getNumChannels() != 3 ) { printf( "RGBtoYIQ requires a 3-channel image as input.\n" ); return NULL; } Image *yiqImage = coefficientConvert( inRGBImage, 0.299, 0.587, 0.114, 0.596, -0.274, -0.322, 0.212, -0.523, 0.311 ); return yiqImage; } inline Image *ImageColorConverter::YIQToRGB( Image *inYIQImage ) { if( inYIQImage->getNumChannels() != 3 ) { printf( "YIQtoRGB requires a 3-channel image as input.\n" ); return NULL; } Image *rgbImage = coefficientConvert( inYIQImage, 1.0, 0.956, 0.621, 1.0, -0.272, -0.647, 1.0, -1.105, 1.702 ); return rgbImage; } inline Image *ImageColorConverter::RGBToYCbCr( Image *inRGBImage ) { if( inRGBImage->getNumChannels() != 3 ) { printf( "RGBtoYCbCr requires a 3-channel image as input.\n" ); return NULL; } // coefficients taken from the color space faq /* RGB -> YCbCr (with Rec 601-1 specs) Y = 0.2989 * Red + 0.5866 * Green + 0.1145 * Blue Cb = -0.1687 * Red - 0.3312 * Green + 0.5000 * Blue Cr = 0.5000 * Red - 0.4183 * Green - 0.0816 * Blue YCbCr (with Rec 601-1 specs) -> RGB Red = Y + 0.0000 * Cb + 1.4022 * Cr Green = Y - 0.3456 * Cb - 0.7145 * Cr Blue = Y + 1.7710 * Cb + 0.0000 * Cr */ Image *ycbcrImage = coefficientConvert( inRGBImage, 0.2989, 0.5866, 0.1145, -0.1687, -0.3312, 0.5000, 0.5000, -0.4183, -0.0816 ); // adjust the Cb and Cr channels so they are in the range [0,1] int numPixels = ycbcrImage->getWidth() * ycbcrImage->getHeight(); double *cbChannel = ycbcrImage->getChannel( 1 ); double *crChannel = ycbcrImage->getChannel( 2 ); for( int i=0; igetNumChannels() != 3 ) { printf( "YCbCrtoRGB requires a 3-channel image as input.\n" ); return NULL; } // adjust the normalized Cb and Cr channels // so they are in the range [-0.5,0.5] int numPixels = inYCbCrImage->getWidth() * inYCbCrImage->getHeight(); double *cbChannel = inYCbCrImage->getChannel( 1 ); double *crChannel = inYCbCrImage->getChannel( 2 ); for( int i=0; i YCbCr (with Rec 601-1 specs) Y = 0.2989 * Red + 0.5866 * Green + 0.1145 * Blue Cb = -0.1687 * Red - 0.3312 * Green + 0.5000 * Blue Cr = 0.5000 * Red - 0.4183 * Green - 0.0816 * Blue YCbCr (with Rec 601-1 specs) -> RGB Red = Y + 0.0000 * Cb + 1.4022 * Cr Green = Y - 0.3456 * Cb - 0.7145 * Cr Blue = Y + 1.7710 * Cb + 0.0000 * Cr */ Image *rgbImage = coefficientConvert( inYCbCrImage, 1.0, 0.0000, 1.4022, 1.0, -0.3456, -0.7145, 1.0, 1.7710, 0.0000 ); // clip r, g, and b channels to the range [0,1], since // some YCbCr pixel values might map out of this range // (in other words, some YCbCr values map outside of rgb space) for( int c=0; c<3; c++ ) { double *channel = rgbImage->getChannel( c ); for( int p=0; p 1 ) { channel[p] = 1.0; } } } return rgbImage; } inline Image *ImageColorConverter::coefficientConvert( Image *inImage, double inC00, double inC01, double inC02, double inC10, double inC11, double inC12, double inC20, double inC21, double inC22 ) { if( inImage->getNumChannels() != 3 ) { return NULL; } int w = inImage->getWidth(); int h = inImage->getHeight(); int numPixels = w * h; Image *outImage = new Image( w, h, 3 ); double *outChannel0 = outImage->getChannel( 0 ); double *outChannel1 = outImage->getChannel( 1 ); double *outChannel2 = outImage->getChannel( 2 ); double *inChannel0 = inImage->getChannel( 0 ); double *inChannel1 = inImage->getChannel( 1 ); double *inChannel2 = inImage->getChannel( 2 ); for( int i=0; i * * Modified by Aaron D. Gifford * * NO COPYRIGHT - THIS IS 100% IN THE PUBLIC DOMAIN * * The original unmodified version is available at: * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef __SHA1_H__ #define __SHA1_H__ #include "minorGems/system/endian.h" /* Make sure you define these types for your architecture: */ typedef unsigned int sha1_quadbyte; /* 4 byte type */ typedef unsigned char sha1_byte; /* single byte type */ /* * Be sure to get the above definitions right. For instance, on my * x86 based FreeBSD box, I define LITTLE_ENDIAN and use the type * "unsigned long" for the quadbyte. On FreeBSD on the Alpha, however, * while I still use LITTLE_ENDIAN, I must define the quadbyte type * as "unsigned int" instead. */ #define SHA1_BLOCK_LENGTH 64 #define SHA1_DIGEST_LENGTH 20 /* The SHA1 structure: */ typedef struct _SHA_CTX { sha1_quadbyte state[5]; sha1_quadbyte count[2]; sha1_byte buffer[SHA1_BLOCK_LENGTH]; } SHA_CTX; void SHA1_Init(SHA_CTX *context); void SHA1_Update(SHA_CTX *context, sha1_byte *data, unsigned int len); void SHA1_Final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX* context); /** * Computes a unencoded 20-byte digest from data. * * @param inData the data to hash. * Must be destroyed by caller. * @param inDataLength the length of the data to hash. * Must be destroyed by caller. * * @return the digest as a byte array of length 20. * Must be destroyed by caller. */ unsigned char *computeRawSHA1Digest( unsigned char *inData, int inDataLength ); /** * Computes a unencoded 20-byte digest from an arbitrary string message. * * @param inString the message as a \0-terminated string. * Must be destroyed by caller. * * @return the digest as a byte array of length 20. * Must be destroyed by caller. */ unsigned char *computeRawSHA1Digest( char *inString ); /** * Computes a hex-encoded string digest from data. * * @param inData the data to hash. * Must be destroyed by caller. * @param inDataLength the length of the data to hash. * Must be destroyed by caller. * * @return the digest as a \0-terminated string. * Must be destroyed by caller. */ char *computeSHA1Digest( unsigned char *inData, int inDataLength ); /** * Computes a hex-encoded string digest from an arbitrary string message. * * @param inString the message as a \0-terminated string. * Must be destroyed by caller. * * @return the digest as a \0-terminated string. * Must be destroyed by caller. */ char *computeSHA1Digest( char *inString ); #endif gravitation-3+dfsg1.orig/minorGems/crypto/hashes/sha1Test.cpp0000644000175000017500000000476710762704566023126 0ustar pabspabs/* * Modification History * * 2002-May-25 Jason Rohrer * Created. * * 2003-September-21 Jason Rohrer * Added test of long string. */ #include "sha1.h" #include #include /** * All parameters must be destroyed by caller. */ void checkHash( char *inString, char *inTestName, char *inCorrectHash ); int main() { /* * Test vectors: * * "abc" * A999 3E36 4706 816A BA3E 2571 7850 C26C 9CD0 D89D * * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" * 8498 3E44 1C3B D26E BAAE 4AA1 F951 29E5 E546 70F1 * * A million repetitions of "a" * 34AA 973C D4C4 DAA4 F61E EB2B DBAD 2731 6534 016F */ char *abc = "abc"; char *correctABCHash = "A9993E364706816ABA3E25717850C26C9CD0D89D"; char *mixedAlpha = "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"; char *correctMixedAlphaHash = "84983E441C3BD26EBAAE4AA1F95129E5E54670F1"; char *correctMillionHash = "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F"; int oneMillion = 1000000; char *millionAs = new char[ oneMillion + 1 ]; for( int i=0; i * * Modified by Aaron D. Gifford * * NO COPYRIGHT - THIS IS 100% IN THE PUBLIC DOMAIN * * The original unmodified version is available at: * ftp://ftp.funet.fi/pub/crypt/hash/sha/sha1.c * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR(S) OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "sha1.h" #include #include // for hex encoding #include "minorGems/formats/encodingUtils.h" #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ /* I got the idea of expanding during the round function from SSLeay */ #if __BYTE_ORDER == __LITTLE_ENDIAN #define blk0(i) (block->l[i] = (rol(block->l[i],24)&(sha1_quadbyte)0xFF00FF00) \ |(rol(block->l[i],8)&(sha1_quadbyte)0x00FF00FF)) #else #define blk0(i) block->l[i] #endif #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ ^block->l[(i+2)&15]^block->l[i&15],1)) /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); typedef union _BYTE64QUAD16 { sha1_byte c[64]; sha1_quadbyte l[16]; } BYTE64QUAD16; /* Hash a single 512-bit block. This is the core of the algorithm. */ void SHA1_Transform(sha1_quadbyte state[5], sha1_byte buffer[64]) { sha1_quadbyte a, b, c, d, e; BYTE64QUAD16 *block; block = (BYTE64QUAD16*)buffer; /* Copy context->state[] to working vars */ a = state[0]; b = state[1]; c = state[2]; d = state[3]; e = state[4]; /* 4 rounds of 20 operations each. Loop unrolled. */ R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); /* Add the working vars back into context.state[] */ state[0] += a; state[1] += b; state[2] += c; state[3] += d; state[4] += e; /* Wipe variables */ a = b = c = d = e = 0; } /* SHA1_Init - Initialize new context */ void SHA1_Init(SHA_CTX* context) { /* SHA1 initialization constants */ context->state[0] = 0x67452301; context->state[1] = 0xEFCDAB89; context->state[2] = 0x98BADCFE; context->state[3] = 0x10325476; context->state[4] = 0xC3D2E1F0; context->count[0] = context->count[1] = 0; } /* Run your data through this. */ void SHA1_Update(SHA_CTX *context, sha1_byte *data, unsigned int len) { unsigned int i, j; j = (context->count[0] >> 3) & 63; if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; context->count[1] += (len >> 29); if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64-j)); SHA1_Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) { SHA1_Transform(context->state, &data[i]); } j = 0; } else i = 0; memcpy(&context->buffer[j], &data[i], len - i); } /* Add padding and return the message digest. */ void SHA1_Final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX *context) { sha1_quadbyte i, j; sha1_byte finalcount[8]; for (i = 0; i < 8; i++) { finalcount[i] = (sha1_byte)((context->count[(i >= 4 ? 0 : 1)] >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ } SHA1_Update(context, (sha1_byte *)"\200", 1); while ((context->count[0] & 504) != 448) { SHA1_Update(context, (sha1_byte *)"\0", 1); } /* Should cause a SHA1_Transform() */ SHA1_Update(context, finalcount, 8); for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { digest[i] = (sha1_byte) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ i = j = 0; memset(context->buffer, 0, SHA1_BLOCK_LENGTH); memset(context->state, 0, SHA1_DIGEST_LENGTH); memset(context->count, 0, 8); memset(&finalcount, 0, 8); } unsigned char *computeRawSHA1Digest( unsigned char *inData, int inDataLength ) { SHA_CTX context; SHA1_Init( &context ); // copy into buffer, since this SHA1 implementation seems to overwrite // parts of the data buffer. unsigned char *buffer = new unsigned char[ inDataLength ]; memcpy( (void *)buffer, (void *)inData, inDataLength ); SHA1_Update( &context, buffer, inDataLength ); delete [] buffer; unsigned char *digest = new unsigned char[ SHA1_DIGEST_LENGTH ]; SHA1_Final( digest, &context ); return digest; } unsigned char *computeRawSHA1Digest( char *inString ) { SHA_CTX context; SHA1_Init( &context ); // copy into buffer, since this SHA1 implementation seems to overwrite // parts of the data buffer. int dataLength = strlen( inString ); unsigned char *buffer = new unsigned char[ dataLength ]; memcpy( (void *)buffer, (void *)inString, dataLength ); SHA1_Update( &context, buffer, strlen( inString ) ); delete [] buffer; unsigned char *digest = new unsigned char[ SHA1_DIGEST_LENGTH ]; SHA1_Final( digest, &context ); return digest; } char *computeSHA1Digest( char *inString ) { unsigned char *digest = computeRawSHA1Digest( inString ); char *digestHexString = hexEncode( digest, SHA1_DIGEST_LENGTH ); delete [] digest; return digestHexString; } char *computeSHA1Digest( unsigned char *inData, int inDataLength ) { unsigned char *digest = computeRawSHA1Digest( inData, inDataLength ); char *digestHexString = hexEncode( digest, SHA1_DIGEST_LENGTH ); delete [] digest; return digestHexString; } gravitation-3+dfsg1.orig/minorGems/crypto/hashes/sha1sum.cpp0000644000175000017500000000353610762704566023004 0ustar pabspabs/* * Modification History * * 2004-May-20 Jason Rohrer * Created. */ #include "sha1.h" #include "minorGems/formats/encodingUtils.h" #include /** * Prints usage message and exits. * * @param inAppName the name of the app. */ void usage( char *inAppName ); int main( int inNumArgs, char **inArgs ) { if( inNumArgs != 2 ) { usage( inArgs[0] ); } FILE *file = fopen( inArgs[1], "rb" ); if( file == NULL ) { printf( "Failed to open file %s for reading\n\n", inArgs[1] ); usage( inArgs[0] ); } SHA_CTX shaContext; SHA1_Init( &shaContext ); int bufferSize = 5000; unsigned char *buffer = new unsigned char[ bufferSize ]; int numRead = bufferSize; char error = false; // read bytes from file until we run out while( numRead == bufferSize && !error ) { numRead = fread( buffer, 1, bufferSize, file ); if( numRead > 0 ) { SHA1_Update( &shaContext, buffer, numRead ); } else{ error = true; } } fclose( file ); delete [] buffer; if( error ) { printf( "Error reading from file %s\n", inArgs[1] ); } else { unsigned char *rawDigest = new unsigned char[ SHA1_DIGEST_LENGTH ]; SHA1_Final( rawDigest, &shaContext ); // else hash is correct char *digestHexString = hexEncode( rawDigest, SHA1_DIGEST_LENGTH ); printf( "%s %s\n", digestHexString, inArgs[1] ); delete [] rawDigest; delete [] digestHexString; } return 0; } void usage( char *inAppName ) { printf( "Usage:\n\n" ); printf( "\t%s file_to_sum\n", inAppName ); printf( "example:\n" ); printf( "\t%s test.txt\n", inAppName ); exit( 1 ); } gravitation-3+dfsg1.orig/minorGems/crypto/hashes/sha1sumCompile0000755000175000017500000000011610762704566023526 0ustar pabspabsg++ -I../../.. -o sha1sum sha1sum.cpp sha1.cpp ../../formats/encodingUtils.cppgravitation-3+dfsg1.orig/minorGems/common.h0000644000175000017500000000033710762704566017561 0ustar pabspabs/* * Modification History * * 2002-October-18 Jason Rohrer * Created. */ #ifndef MINOR_GEMS_COMMON_INCLUDED #define MINOR_GEMS_COMMON_INCLUDED #include "minorGems/util/development/memory/debugMemory.h" #endif gravitation-3+dfsg1.orig/minorGems/formats/0000755000175000017500000000000010762704566017570 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/formats/xml/0000755000175000017500000000000010762704566020370 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/formats/xml/XMLUtils.h0000644000175000017500000000134110762704566022221 0ustar pabspabs/* * Modification History * * 2002-September-12 Jason Rohrer * Created. */ #ifndef XML_UTILS_INCLUDED #define XML_UTILS_INCLUDED /** * Utilities for processing XML. * * @author Jason Rohrer */ class XMLUtils { public: /** * Escapes characters disallowed in XML character data. * * @param the string to escape as a \0-terminated string. * Must be destroyed by caller if non-const. * * @return string with characters escaped as a newly allocated * \0-terminated string. * Must be destroyed by caller. */ static char *escapeDisallowedCharacters( char *inString ); }; #endif gravitation-3+dfsg1.orig/minorGems/formats/xml/XMLUtils.cpp0000644000175000017500000000470210762704566022560 0ustar pabspabs/* * Modification History * * 2002-September-12 Jason Rohrer * Created. */ #include "XMLUtils.h" #include "minorGems/util/stringUtils.h" #include "minorGems/util/SimpleVector.h" #include char *XMLUtils::escapeDisallowedCharacters( char *inString ) { SimpleVector *returnStringVector = new SimpleVector(); int stringLength = strlen( inString ); int i; for( i=0; ipush_back( '&' ); returnStringVector->push_back( 'a' ); returnStringVector->push_back( 'm' ); returnStringVector->push_back( 'p' ); returnStringVector->push_back( ';' ); break; case '<': returnStringVector->push_back( '&' ); returnStringVector->push_back( 'l' ); returnStringVector->push_back( 't' ); returnStringVector->push_back( ';' ); break; case '>': returnStringVector->push_back( '&' ); returnStringVector->push_back( 'g' ); returnStringVector->push_back( 't' ); returnStringVector->push_back( ';' ); break; case '\"': returnStringVector->push_back( '&' ); returnStringVector->push_back( 'q' ); returnStringVector->push_back( 'u' ); returnStringVector->push_back( 'o' ); returnStringVector->push_back( 't' ); returnStringVector->push_back( ';' ); break; case '\'': returnStringVector->push_back( '&' ); returnStringVector->push_back( 'a' ); returnStringVector->push_back( 'p' ); returnStringVector->push_back( 'o' ); returnStringVector->push_back( 's' ); returnStringVector->push_back( ';' ); break; default: returnStringVector->push_back( inString[i] ); break; } } int numChars = returnStringVector->size(); char *returnString = new char[ numChars + 1 ]; for( i=0; igetElement( i ) ); } returnString[ numChars ] = '\0'; delete returnStringVector; return returnString; } gravitation-3+dfsg1.orig/minorGems/formats/html/0000755000175000017500000000000010762704566020534 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/formats/html/HTMLUtils.cpp0000644000175000017500000000215710762704566023032 0ustar pabspabs/* * Modification History * * 2002-September-12 Jason Rohrer * Created. */ #include "HTMLUtils.h" #include "minorGems/util/stringUtils.h" #include "minorGems/util/SimpleVector.h" #include char *HTMLUtils::removeAllTags( char *inString ) { SimpleVector *returnStringVector = new SimpleVector(); int stringLength = strlen( inString ); int i = 0; while( i < stringLength ) { if( inString[i] == '<' ) { // the start of a tag // skip all until (and including) close of tag while( i < stringLength && inString[i] != '>' ) { // do nothing i++; } } else { returnStringVector->push_back( inString[i] ); } i++; } int numChars = returnStringVector->size(); char *returnString = new char[ numChars + 1 ]; for( i=0; igetElement( i ) ); } returnString[ numChars ] = '\0'; delete returnStringVector; return returnString; } gravitation-3+dfsg1.orig/minorGems/formats/html/HTMLUtils.h0000644000175000017500000000131010762704566022465 0ustar pabspabs/* * Modification History * * 2002-September-12 Jason Rohrer * Created. */ #ifndef HTML_UTILS_INCLUDED #define HTML_UTILS_INCLUDED /** * Utilities for processing HTML. * * @author Jason Rohrer */ class HTMLUtils { public: /** * Removes all HTML tags from an HTML string. * * @param the HTML data as a \0-terminated string. * Must be destroyed by caller if non-const. * * @return data with all HTML tags removed as a newly allocated * \0-terminated string. * Must be destroyed by caller. */ static char *removeAllTags( char *inString ); }; #endif gravitation-3+dfsg1.orig/minorGems/formats/encodingUtils.h0000644000175000017500000000423210762704566022551 0ustar pabspabs/* * Modification History * * 2003-August-22 Jason Rohrer * Created. * * 2003-September-22 Jason Rohrer * Added base64 encoding. */ #ifndef ENCODING_UTILS_INCLUDED #define ENCODING_UTILS_INCLUDED /** * A collection of functions for representing data in various encoding formats. * * @author Jason Rohrer */ /** * Encodes data as a ASCII hexidecimal string. * * @param inData the data to encode. * Must be destroyed by caller. * @param inDataLength the length of inData in bytes. * * @return a \0-terminated ASCII hexidecimal string containing * characters in the range [0-9] and [A-F]. * Will be twice as long as inData. * Must be destroyed by caller. */ char *hexEncode( unsigned char *inData, int inDataLength ); /** * Decodes raw data from an ASCII hexidecimal string. * * @param inHexString a \0-terminated hexidecimal string. * Must be destroyed by caller. * * @return an array of raw data, or NULL if decoding fails. * Will be half as long as inHexString. * Must be destroyed by caller if non-NULL. */ unsigned char *hexDecode( char *inHexString ); /** * Encodes data as a ASCII base64 string. * * @param inData the data to encode. * Must be destroyed by caller. * @param inDataLength the length of inData in bytes. * @param inBreakLines set to true to break lines every 76 characters, * or false to produce an unbroken base64 string. * * @return a \0-terminated ASCII base64 string containing * characters in the range [0-9], [A-Z], [a-z], and [+,/,=]. * Must be destroyed by caller. */ char *base64Encode( unsigned char *inData, int inDataLength, char inBreakLines = true ); /** * Decodes raw data from an ASCII base64 string. * * @param inBase64String a \0-terminated base64 string. Can optionally contain * linebreaks. * Must be destroyed by caller. * @param outDataLength pointer to where the length of the decoded data * should be returned. * * @return an array of raw data, or NULL if decoding fails. * Must be destroyed by caller if non-NULL. */ unsigned char *base64Decode( char *inBase64String, int *outDataLength ); #endif gravitation-3+dfsg1.orig/minorGems/formats/encodingUtilsTestCompile0000755000175000017500000000021010762704566024467 0ustar pabspabsg++ -g -I../.. -o encodingUtilsTest encodingUtilsTest.cpp encodingUtils.cpp ../util/stringUtils.cpp ../util/StringBufferOutputStream.cppgravitation-3+dfsg1.orig/minorGems/formats/encodingUtils.cpp0000644000175000017500000003143510762704566023111 0ustar pabspabs/* * Modification History * * 2003-August-22 Jason Rohrer * Created. * * 2003-September-22 Jason Rohrer * Added base64 encoding. * * 2004-March-21 Jason Rohrer * Fixed a variable scoping and redefinition bug pointed out by Benjamin Meyer. */ #include "encodingUtils.h" #include "minorGems/util/SimpleVector.h" #include #include char fourBitIntToHex( int inInt ) { char outChar[2]; if( inInt < 10 ) { sprintf( outChar, "%d", inInt ); } else { switch( inInt ) { case 10: outChar[0] = 'A'; break; case 11: outChar[0] = 'B'; break; case 12: outChar[0] = 'C'; break; case 13: outChar[0] = 'D'; break; case 14: outChar[0] = 'E'; break; case 15: outChar[0] = 'F'; break; default: outChar[0] = '0'; break; } } return outChar[0]; } // returns -1 if inHex is not a valid hex character int hexToFourBitInt( char inHex ) { int returnInt; switch( inHex ) { case '0': returnInt = 0; break; case '1': returnInt = 1; break; case '2': returnInt = 2; break; case '3': returnInt = 3; break; case '4': returnInt = 4; break; case '5': returnInt = 5; break; case '6': returnInt = 6; break; case '7': returnInt = 7; break; case '8': returnInt = 8; break; case '9': returnInt = 9; break; case 'A': case 'a': returnInt = 10; break; case 'B': case 'b': returnInt = 11; break; case 'C': case 'c': returnInt = 12; break; case 'D': case 'd': returnInt = 13; break; case 'E': case 'e': returnInt = 14; break; case 'F': case 'f': returnInt = 15; break; default: returnInt = -1; break; } return returnInt; } char *hexEncode( unsigned char *inData, int inDataLength ) { char *resultHexString = new char[ inDataLength * 2 + 1 ]; int hexStringIndex = 0; for( int i=0; i> 4 ); int lowBits = 0xF & ( currentByte ); resultHexString[ hexStringIndex ] = fourBitIntToHex( highBits ); hexStringIndex++; resultHexString[ hexStringIndex ] = fourBitIntToHex( lowBits ); hexStringIndex++; } resultHexString[ hexStringIndex ] = '\0'; return resultHexString; } unsigned char *hexDecode( char *inHexString ) { int hexLength = strlen( inHexString ); if( hexLength % 2 != 0 ) { // hex strings must be even in length return NULL; } int dataLength = hexLength / 2; unsigned char *rawData = new unsigned char[ dataLength ]; for( int i=0; i *encodingVector = new SimpleVector(); int numInLine = 0; // take groups of 3 data bytes and map them to 4 base64 digits for( int i=0; i> 18 ); unsigned int digitB = 0x3F & ( block >> 12 ); unsigned int digitC = 0x3F & ( block >> 6 ); unsigned int digitD = 0x3F & ( block ); encodingVector->push_back( binaryToAscii[ digitA ] ); encodingVector->push_back( binaryToAscii[ digitB ] ); encodingVector->push_back( binaryToAscii[ digitC ] ); encodingVector->push_back( binaryToAscii[ digitD ] ); numInLine += 4; if( inBreakLines && numInLine == 76 ) { // break the line encodingVector->push_back( '\r' ); encodingVector->push_back( '\n' ); numInLine = 0; } } else { // at end int numLeft = inDataLength - i; switch( numLeft ) { case 0: // no padding break; case 1: { // two digits, two pads unsigned int block = inData[i] << 16 | 0; unsigned int digitA = 0x3F & ( block >> 18 ); unsigned int digitB = 0x3F & ( block >> 12 ); encodingVector->push_back( binaryToAscii[ digitA ] ); encodingVector->push_back( binaryToAscii[ digitB ] ); encodingVector->push_back( '=' ); encodingVector->push_back( '=' ); break; } case 2: { // three digits, one pad unsigned int block = inData[i] << 16 | inData[i+1] << 8 | 0; // base64 digits, with digitA at left unsigned int digitA = 0x3F & ( block >> 18 ); unsigned int digitB = 0x3F & ( block >> 12 ); unsigned int digitC = 0x3F & ( block >> 6 ); encodingVector->push_back( binaryToAscii[ digitA ] ); encodingVector->push_back( binaryToAscii[ digitB ] ); encodingVector->push_back( binaryToAscii[ digitC ] ); encodingVector->push_back( '=' ); break; } default: break; } // done with all data i = inDataLength; } } char *returnString = encodingVector->getElementString(); delete encodingVector; return returnString; } unsigned char *base64Decode( char *inBase64String, int *outDataLength ) { SimpleVector *decodedVector = new SimpleVector(); int encodingLength = strlen( inBase64String ); SimpleVector *binaryEncodingVector = new SimpleVector(); int i; for( i=0; ipush_back( currentBinary ); } } int binaryEncodingLength = binaryEncodingVector->size(); unsigned char *binaryEncoding = binaryEncodingVector->getElementArray(); delete binaryEncodingVector; int blockCount = binaryEncodingLength / 4; if( binaryEncodingLength % 4 != 0 ) { // extra, 0-padded block blockCount += 1; } // take groups of 4 encoded digits and map them to 3 data bytes for( i=0; i> 16 ); unsigned int digitB = 0xFF & ( block >> 8 ); unsigned int digitC = 0xFF & ( block ); decodedVector->push_back( digitA ); decodedVector->push_back( digitB ); decodedVector->push_back( digitC ); } else { // at end int numLeft = binaryEncodingLength - i; switch( numLeft ) { case 0: // no padding break; case 1: { // impossible break; } case 2: { // two base64 digits, one data byte unsigned int block = binaryEncoding[i] << 18 | binaryEncoding[i+1] << 12 | 0; // data byte digits, with digitA at left unsigned int digitA = 0xFF & ( block >> 16 ); decodedVector->push_back( digitA ); break; } case 3: { // three base64 digits, two data bytes unsigned int block = binaryEncoding[i] << 18 | binaryEncoding[i+1] << 12 | binaryEncoding[i+2] << 6 | 0; // data byte digits, with digitA at left unsigned int digitA = 0xFF & ( block >> 16 ); unsigned int digitB = 0xFF & ( block >> 8 ); decodedVector->push_back( digitA ); decodedVector->push_back( digitB ); break; } default: break; } // done with all data i = binaryEncodingLength; } } delete [] binaryEncoding; *outDataLength = decodedVector->size(); unsigned char* returnData = decodedVector->getElementArray(); delete decodedVector; return returnData; } gravitation-3+dfsg1.orig/minorGems/formats/encodingUtilsTest.cpp0000644000175000017500000000232110762704566023741 0ustar pabspabs/* * Modification History * * 2003-September-22 Jason Rohrer * Created. */ #include "encodingUtils.h" #include #include int main() { const char *dataString = "*#$&$(@KFI#*$(SDBM@#*!(@%" "*#$&$(@KFI#*$(SDBM@#*!(@%" "*#$&$(@KFI#*$(SDBM@#*!(@F" "*#$&$(@KFI#*$(SDBM@#*!(@F" "*#$&$(@KFI#*$(SDBM@#*!(@F" "*#$&$(@KFI#*$(SDBM@#*!(@%a"; printf( "base64 encoding the string: %s\n", dataString ); char *encoding = base64Encode( (unsigned char *)dataString, strlen( dataString ), true ); printf( "Encoded as:\n%s\n", encoding ); int decodedLength; unsigned char *decoding = base64Decode( encoding, &decodedLength ); char *buffer = new char[ decodedLength + 1 ]; memcpy( (void *)buffer, (void *)decoding, decodedLength ); buffer[ decodedLength ] = '\0'; printf( "Decoded as: %s\n", buffer ); if( strcmp( buffer, dataString ) == 0 ) { printf( "Test passed\n" ); } else { printf( "Test failed\n" ); } delete [] buffer; delete [] decoding; delete [] encoding; return 0; } gravitation-3+dfsg1.orig/minorGems/system/0000755000175000017500000000000010762704567017442 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/system/unix/0000755000175000017500000000000010762704567020425 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/system/unix/LauncherUnix.cpp0000644000175000017500000000077310762704567023545 0ustar pabspabs/* * Modification History * * 2003-January-10 Jason Rohrer * Created. */ #include "minorGems/system/Launcher.h" #include #include void Launcher::launchCommand( char *inCommandName, char **inArguments ) { int forkValue = fork(); if( forkValue == 0 ) { // we're in child process, so exec command execvp( inCommandName, inArguments ); // we'll never return from this call } } gravitation-3+dfsg1.orig/minorGems/system/unix/TimeUnix.cpp0000644000175000017500000000123410762704567022673 0ustar pabspabs/* * Modification History * * 2001-October-29 Jason Rohrer * Created. * * 2002-March-13 Jason Rohrer * Added include of time.h so that FreeBSD compile will work. * Changed to use newer gettimeofday that should work on all unix platforms. * Fixed a conversion bug. */ #include "minorGems/system/Time.h" #include #include #include #include void Time::getCurrentTime( unsigned long *outSeconds, unsigned long *outMilliseconds ) { struct timeval currentTime; gettimeofday( ¤tTime, NULL ); *outMilliseconds = currentTime.tv_usec / 1000; *outSeconds = currentTime.tv_sec; } gravitation-3+dfsg1.orig/minorGems/system/MutexLock.h0000644000175000017500000000207310762704567021530 0ustar pabspabs/* * Modification History * * 2000-December-13 Jason Rohrer * Created. * * 2002-March-29 Jason Rohrer * Added Fortify inclusion. * * 2002-October-18 Jason Rohrer * Moved common include out of header and into platform-specific cpp files, * since MemoryTrack uses a mutex lock. */ #ifndef MUTEX_LOCK_CLASS_INCLUDED #define MUTEX_LOCK_CLASS_INCLUDED #ifdef FORTIFY #include "minorGems/util/development/fortify/fortify.h" #endif /** * Mutex lock class. * * Note: Implementation for the functions defined here is provided * separately for each platform (in the mac/ linux/ and win32/ * subdirectories). * * @author Jason Rohrer */ class MutexLock { public: /** * Constructs a mutex lock; */ MutexLock(); ~MutexLock(); /** * Locks the mutex. Blocks until mutex available if it's * already locked by another thread. */ void lock(); /** * Unlocks the mutex. */ void unlock(); private: /** * Used by platform-specific implementations. */ void *mNativeObjectPointer; }; #endif gravitation-3+dfsg1.orig/minorGems/system/semaphoreTest.cpp0000644000175000017500000000366410762704567023002 0ustar pabspabs/* * Modification History * * 2001-January-11 Jason Rohrer * Created. * * 2001-January-27 Jason Rohrer * Made printing in threads thread-safe. */ #include "BinarySemaphore.h" #include "Semaphore.h" #include "Thread.h" #include "ThreadSafePrinter.h" #include /** * Thread that waits on a semaphore. * * @author Jason Rohrer */ class WaitingThread : public Thread { public: WaitingThread( int inID, Semaphore *inSemaphore ); // override the run method from PThread void run(); private: Semaphore *mSemaphore; int mID; }; inline WaitingThread::WaitingThread( int inID, Semaphore *inSemaphore ) : mID( inID ), mSemaphore( inSemaphore ) { } inline void WaitingThread::run() { for( int i=0; i<10; i++ ) { ThreadSafePrinter::printf( "%d waiting for signal %d...\n", mID, i ); mSemaphore->wait(); ThreadSafePrinter::printf( "%d received signal %d.\n", mID, i ); } } /** * Thread that signals on a semaphore. * * @author Jason Rohrer */ class SignalingThread : public Thread { public: SignalingThread( Semaphore *inSemaphore ); // override the run method from PThread void run(); private: Semaphore *mSemaphore; }; inline SignalingThread::SignalingThread( Semaphore *inSemaphore ) : mSemaphore( inSemaphore ) { } inline void SignalingThread::run() { for( int i=0; i<5; i++ ) { sleep( 5000 ); ThreadSafePrinter::printf( "Signaling 20 times\n" ); for( int j=0; j<20; j++ ) { mSemaphore->signal(); } } } int main() { int i; Semaphore *semph = new Semaphore(); SignalingThread *threadS = new SignalingThread( semph ); WaitingThread **threadW = new WaitingThread*[10]; for( i=0; i<10; i++ ) { threadW[i] = new WaitingThread( i, semph ); threadW[i]->start(); } threadS->start(); for( i=0; i<10; i++ ) { threadW[i]->join(); delete threadW[i]; } threadS->join(); delete semph; delete threadS; delete [] threadW; return 0; } gravitation-3+dfsg1.orig/minorGems/system/BinarySemaphore.h0000644000175000017500000000331310762704567022703 0ustar pabspabs/* * Modification History * * 2001-January-11 Jason Rohrer * Created. * * 2001-January-27 Jason Rohrer * Fixed a bug in the precompiler directives. * * 2003-August-26 Jason Rohrer * Added support for timeouts on wait. */ #include "minorGems/common.h" #ifndef BINARY_SEMAPHORE_CLASS_INCLUDED #define BINARY_SEMAPHORE_CLASS_INCLUDED #include "MutexLock.h" /** * Binary semaphore class. Semaphore starts out with a value of 0. * * Note: Implementation for the functions defined here is provided * separately for each platform (in the mac/ linux/ and win32/ * subdirectories). * * @author Jason Rohrer */ class BinarySemaphore { public: /** * Constructs a binary semaphore. */ BinarySemaphore(); ~BinarySemaphore(); /** * Blocks on this semaphore until signal() is called by another thread. * Note that if signal() has already been called before wait() is * called, then this call will return immediately, though the semaphore * is reset to 0 by this call. * * @param inTimeoutInMilliseconds the maximum time to wait in * milliseconds, or -1 to wait forever. Defaults to -1. * * @return 1 if the semaphore was signaled, or 0 if it timed out. */ int wait( int inTimeoutInMilliseconds = -1 ); /** * Signals the semaphore, allowing a waiting thread to return from * its call to wait(). (The semaphore is set to 1 by this call if * no thread is waiting on the semaphore currently.) */ void signal(); private: // starts at 0 int mSemaphoreValue; /** * Used by platform-specific implementations. */ void *mNativeObjectPointerA; void *mNativeObjectPointerB; }; #endif gravitation-3+dfsg1.orig/minorGems/system/linux/0000755000175000017500000000000010762704567020601 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/system/linux/MutexLockLinux.cpp0000644000175000017500000000311310762704567024236 0ustar pabspabs/* * Modification History * * 2000-December-13 Jason Rohrer * Created. * * 2002-October-18 Jason Rohrer * Moved common include out of header and into platform-specific cpp files, * since MemoryTrack uses a mutex lock. * Changed to use malloc instead of new internally to work with debugMemory. * Made use of mNativeObjectPointer a bit cleaner. */ #include "minorGems/common.h" #include #include #include /** * Linux-specific implementation of the MutexLock class member functions. * * May also be compatible with other POSIX-like systems. * * To compile: * g++ -lpthread */ MutexLock::MutexLock() { // allocate a mutex structure on the heap mNativeObjectPointer = malloc( sizeof( pthread_mutex_t ) ); // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointer; // init the mutex pthread_mutex_init( mutexPointer, NULL ); } MutexLock::~MutexLock() { // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointer; // destroy the mutex pthread_mutex_destroy( mutexPointer ); // de-allocate the mutex structure from the heap free( mNativeObjectPointer ); } void MutexLock::lock() { // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointer; pthread_mutex_lock( mutexPointer ); } void MutexLock::unlock() { // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointer; pthread_mutex_unlock( mutexPointer ); } gravitation-3+dfsg1.orig/minorGems/system/linux/ThreadLinux.cpp0000644000175000017500000001335410762704567023542 0ustar pabspabs/* * Modification History * * 2000-December-13 Jason Rohrer * Created. * * 2001-January-11 Jason Rohrer * Added missing sleep() implementation. * * 2002-March-27 Jason Rohrer * Added support for gprof-friendly thread wrappers. * Fixed a compile bug when gprof threads disabled. * * 2002-August-5 Jason Rohrer * Removed an unused variable. * * 2003-February-3 Jason Rohrer * Fixed sleep to be thread safe (signals were interrupting thread sleeps). * * 2004-March-31 Jason Rohrer * Added support for detatched mode. * * 2005-January-22 Jason Rohrer * Added a static sleep function. */ #include #include #include #include #include /** * Linux-specific implementation of the Thread class member functions. * * May also be compatible with other POSIX-like systems. * * To compile: * g++ -lpthread * If thread profiling is desired for gprof on linux, compile * with -DUSE_GPROF_THREADS (otherwise, only main thread is profiled). */ #ifdef USE_GPROF_THREADS // prototype int gprof_pthread_create( pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg ); #endif // prototype /** * A wrapper for the run method, since pthreads won't take * a class's member function. Takes a pointer to the Thread to run, * cast as a void*; */ void *linuxThreadFunction( void * ); Thread::Thread() { // allocate a pthread structure on the heap mNativeObjectPointer = (void *)( new pthread_t[1] ); } Thread::~Thread() { // de-allocate the pthread structure from the heap pthread_t *threadPointer = (pthread_t *)mNativeObjectPointer; delete [] threadPointer; } void Thread::start( char inDetach ) { mIsDetached = inDetach; // get a pointer to the pthread pthread_t *threadPointer = (pthread_t *)mNativeObjectPointer; // create the pthread, which also sets it running #ifdef USE_GPROF_THREADS gprof_pthread_create( &( threadPointer[0] ), NULL, linuxThreadFunction, (void*)this ); #else pthread_create( &( threadPointer[0] ), NULL, linuxThreadFunction, (void*)this ); #endif if( mIsDetached ) { pthread_detach( threadPointer[0] ); } } void Thread::join() { void *joinStat; pthread_t *threadPointer = (pthread_t *)mNativeObjectPointer; pthread_join( threadPointer[0], &joinStat ); } void Thread::staticSleep( unsigned long inTimeInMilliseconds ) { unsigned long seconds = inTimeInMilliseconds / 1000; unsigned long milliseconds = inTimeInMilliseconds % 1000; struct timespec remainingSleepTimeStruct; remainingSleepTimeStruct.tv_sec = seconds; remainingSleepTimeStruct.tv_nsec = milliseconds * 1000000; struct timespec timeToSleepStruct; // sleep repeatedly, ignoring signals, untill we use up all of the time int sleepReturn = -1; while( sleepReturn == -1 ) { timeToSleepStruct.tv_sec = remainingSleepTimeStruct.tv_sec; timeToSleepStruct.tv_nsec = remainingSleepTimeStruct.tv_nsec; sleepReturn = nanosleep( &timeToSleepStruct, &remainingSleepTimeStruct ); } } // takes a pointer to a Thread object as the data value void *linuxThreadFunction( void *inPtrToThread ) { Thread *threadToRun = (Thread *)inPtrToThread; threadToRun->run(); if( threadToRun->isDetatched() ) { // thread detached, so we must destroy it delete threadToRun; } return inPtrToThread; } #ifdef USE_GPROF_THREADS // found at http://sam.zoy.org/doc/programming/gprof.html #include /* * pthread_create wrapper for gprof compatibility * * needed headers: * */ typedef struct wrapper_s { void * (*start_routine)(void *); void * arg; pthread_mutex_t lock; pthread_cond_t wait; struct itimerval itimer; } wrapper_t; static void * wrapper_routine(void *); /** * Same prototype as pthread_create; use some #define magic to * transparently replace it in other files */ int gprof_pthread_create( pthread_t * thread, pthread_attr_t * attr, void * (*start_routine)(void *), void * arg ) { wrapper_t wrapper_data; int i_return; /* Initialize the wrapper structure */ wrapper_data.start_routine = start_routine; wrapper_data.arg = arg; getitimer(ITIMER_PROF, &wrapper_data.itimer); pthread_cond_init(&wrapper_data.wait, NULL); pthread_mutex_init(&wrapper_data.lock, NULL); pthread_mutex_lock(&wrapper_data.lock); /* The real pthread_create call */ i_return = pthread_create(thread, attr, &wrapper_routine, &wrapper_data); /* If the thread was successfully spawned, wait for the data * to be released */ if( i_return == 0 ) { pthread_cond_wait(&wrapper_data.wait, &wrapper_data.lock); } pthread_mutex_unlock(&wrapper_data.lock); pthread_mutex_destroy(&wrapper_data.lock); pthread_cond_destroy(&wrapper_data.wait); return i_return; } /** * The wrapper function in charge for setting the itimer value */ static void * wrapper_routine( void * data ) { /* Put user data in thread-local variables */ void * (*start_routine)(void *) = ((wrapper_t*)data)->start_routine; void * arg = ((wrapper_t*)data)->arg; /* Set the profile timer value */ setitimer(ITIMER_PROF, &((wrapper_t*)data)->itimer, NULL); /* Tell the calling thread that we don't need its data anymore */ pthread_mutex_lock(&((wrapper_t*)data)->lock); pthread_cond_signal(&((wrapper_t*)data)->wait); pthread_mutex_unlock(&((wrapper_t*)data)->lock); /* Call the real function */ return start_routine(arg); } #endif gravitation-3+dfsg1.orig/minorGems/system/linux/BinarySemaphoreLinux.cpp0000644000175000017500000001103210762704567025412 0ustar pabspabs/* * Modification History * * 2001-January-11 Jason Rohrer * Created. * * 2003-August-26 Jason Rohrer * Added support for timeouts on wait. * * 2006-February-28 Jason Rohrer * Fixed bug in sub-second timeout computation. */ #include "minorGems/system/BinarySemaphore.h" #include "minorGems/system/Time.h" #include /** * Linux-specific implementation of the BinarySemaphore class member functions. * * May also be compatible with other POSIX-like systems. * * To compile: * g++ -lpthread */ /** * Native object pointer A is the condition variable. * Pointer B is the mutex that must go along with it. */ BinarySemaphore::BinarySemaphore() : mSemaphoreValue( 0 ) { // allocate a condition variable structure on the heap mNativeObjectPointerA = (void *)( new pthread_cond_t[1] ); // get a pointer to the cond pthread_cond_t *condPointer = (pthread_cond_t *)mNativeObjectPointerA; // init the cond pthread_cond_init( &( condPointer[0] ), NULL ); // allocate a mutex structure on the heap mNativeObjectPointerB = (void *)( new pthread_mutex_t[1] ); // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointerB; // init the mutex pthread_mutex_init( &( mutexPointer[0] ), NULL ); } BinarySemaphore::~BinarySemaphore() { // get a pointer to the cond pthread_cond_t *condPointer = (pthread_cond_t *)mNativeObjectPointerA; // destroy the cond pthread_cond_destroy( &( condPointer[0] ) ); // de-allocate the cond structure from the heap delete [] condPointer; // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointerB; // destroy the mutex pthread_mutex_destroy( &( mutexPointer[0] ) ); // de-allocate the mutex structure from the heap delete [] mutexPointer; } int BinarySemaphore::wait( int inTimeoutInMilliseconds ) { int returnValue = 1; // get a pointer to the cond pthread_cond_t *condPointer = (pthread_cond_t *)mNativeObjectPointerA; // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointerB; // lock the mutex pthread_mutex_lock( &( mutexPointer[0] ) ); if( mSemaphoreValue == 0 ) { // wait on condition variable, which automatically unlocks // the passed-in mutex if( inTimeoutInMilliseconds == -1 ) { // no timeout pthread_cond_wait( &( condPointer[0] ), &( mutexPointer[0] ) ); } else { // use timeout version unsigned long nsecPerSecond = 1000000000; unsigned long nsecPerMillisecond = 1000000; unsigned long currentSec; unsigned long currentMS; Time::getCurrentTime( ¤tSec, ¤tMS ); unsigned long currentNS = currentMS * nsecPerMillisecond; long timeoutSec = inTimeoutInMilliseconds / 1000; long extraMS = inTimeoutInMilliseconds % 1000; long extraNS = extraMS * nsecPerMillisecond; unsigned long absTimeoutSec = currentSec + timeoutSec; unsigned long absTimeoutNsec = currentNS + extraNS; // check for nsec overflow if( absTimeoutNsec > nsecPerSecond ) { absTimeoutSec += 1; absTimeoutNsec -= nsecPerSecond; } struct timespec abstime; abstime.tv_sec = absTimeoutSec; abstime.tv_nsec = absTimeoutNsec; int result = pthread_cond_timedwait( &( condPointer[0] ), &( mutexPointer[0] ), &abstime ); if( result != 0 ) { // timed out returnValue = 0; } } // mutex is apparently re-locked when we return from cond_wait } // decrement the semaphore value mSemaphoreValue = 0; // unlock the mutex again pthread_mutex_unlock( &( mutexPointer[0] ) ); return returnValue; } void BinarySemaphore::signal() { // get a pointer to the cond pthread_cond_t *condPointer = (pthread_cond_t *)mNativeObjectPointerA; // get a pointer to the mutex pthread_mutex_t *mutexPointer = (pthread_mutex_t *)mNativeObjectPointerB; // lock the mutex pthread_mutex_lock( &( mutexPointer[0] ) ); // increment the semaphore value mSemaphoreValue = 1; pthread_cond_signal( &( condPointer[0] ) ); // unlock the mutex pthread_mutex_unlock( &( mutexPointer[0] ) ); } gravitation-3+dfsg1.orig/minorGems/system/win32/0000755000175000017500000000000010762704567020404 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/system/win32/TimeWin32.cpp0000644000175000017500000000447010762704567022636 0ustar pabspabs/* * Modification History * * 2001-November-7 Jason Rohrer * Created. * * 2002-April-11 Jason Rohrer * Added missing include, and fixed a bug. * * 2004-January-29 Jason Rohrer * Fixed so that 0-point of time is the same as on other platforms. * * 2004-October-14 Jason Rohrer * Fixed bug in second/millisecond callibration. * Fixed bug in win32 time to ANSI time translation. * Fixed daylight savings time bug. */ #include "minorGems/system/Time.h" #include #include #include #include /** * Windows implementation of Time.h. * * The 0-point should match the ANSI standard. */ void Time::getCurrentTime( unsigned long *outSeconds, unsigned long *outMilliseconds ) { // convert from win32 broken-down time (which has msec resolution) // to an ANSI time struct and then convert to an absolute time in // seconds // This procedure ensures that the 0-point matches the ANSI standard. // note: // we cannot simply call ANSI time() to get the seconds and then rely // on GetLocalTime to get the milliseconds, since the seconds value // used by GetLocalTime is (strangely enough) not calibrated to the seconds // value of time(). // In other words, it is possible for the time() seconds to advance // at a different clock cycle than the GetLocalTime seconds. // get time using a win32 call SYSTEMTIME win32TimeStruct; GetLocalTime( &win32TimeStruct ); // convert this win32 structure to the ANSI standard structure struct tm ansiTimeStruct; ansiTimeStruct.tm_sec = win32TimeStruct.wSecond; ansiTimeStruct.tm_min = win32TimeStruct.wMinute; ansiTimeStruct.tm_hour = win32TimeStruct.wHour; ansiTimeStruct.tm_mday = win32TimeStruct.wDay; // ANSI time struct has month in range [0..11] ansiTimeStruct.tm_mon = win32TimeStruct.wMonth - 1; // ANSI time struct has year that is an offset from 1900 ansiTimeStruct.tm_year = win32TimeStruct.wYear - 1900; // unknown daylight savings time (dst) status // if we fail to init this value, we can get inconsistent results ansiTimeStruct.tm_isdst = -1; unsigned long secondsSinceEpoch = mktime( &ansiTimeStruct ); *outSeconds = secondsSinceEpoch; *outMilliseconds = (unsigned long)( win32TimeStruct.wMilliseconds ); } gravitation-3+dfsg1.orig/minorGems/system/win32/LauncherWin32.cpp0000644000175000017500000000065010762704567023475 0ustar pabspabs/* * Modification History * * 2003-January-10 Jason Rohrer * Created. * * 2003-March-24 Jason Rohrer * Fixed a syntax typo. */ #include "minorGems/system/Launcher.h" #include #include void Launcher::launchCommand( char *inCommandName, char **inArguments ) { _spawnvp( _P_NOWAIT, inCommandName, inArguments ); } gravitation-3+dfsg1.orig/minorGems/system/win32/BinarySemaphoreWin32.cpp0000644000175000017500000000401710762704567025025 0ustar pabspabs/* * Modification History * * 2001-January-27 Jason Rohrer * Created. * * 2001-March-4 Jason Rohrer * Replaced include of and with * to fix compile bugs encountered with newer windows compilers. * * 2003-August-26 Jason Rohrer * Added support for timeouts on wait. */ #include "minorGems/system/BinarySemaphore.h" #include /** * Win32-specific implementation of the BinarySemaphore class member functions. */ /** * Native object pointer A is the semaphore handle. * Pointer B is not used. */ BinarySemaphore::BinarySemaphore() : mSemaphoreValue( 0 ) { // allocate a handle on the heap mNativeObjectPointerA = (void *)( new HANDLE[1] ); // retrieve handle from the heap HANDLE *semaphorePointer = (HANDLE *)mNativeObjectPointerA; semaphorePointer[0] = CreateSemaphore( (LPSECURITY_ATTRIBUTES) NULL, // no attributes 0, // initial count 1, // maximum count (LPCTSTR) NULL ); // no name } BinarySemaphore::~BinarySemaphore() { // retrieve handle from the heap HANDLE *semaphorePointer = (HANDLE *)mNativeObjectPointerA; // destroy the semaphore CloseHandle( semaphorePointer[0] ); // de-allocate the handle from the heap delete [] semaphorePointer; } int BinarySemaphore::wait( int inTimeoutInMilliseconds ) { // retrieve handle from the heap HANDLE *semaphorePointer = (HANDLE *)mNativeObjectPointerA; if( inTimeoutInMilliseconds == -1 ) { WaitForSingleObject( semaphorePointer[0], INFINITE ); return 1; } else { // timeout int result = WaitForSingleObject( semaphorePointer[0], inTimeoutInMilliseconds ); if( result == WAIT_TIMEOUT ) { return 0; } else { return 1; } } } void BinarySemaphore::signal() { // retrieve handle from the heap HANDLE *semaphorePointer = (HANDLE *)mNativeObjectPointerA; ReleaseSemaphore( semaphorePointer[0], 1, (LPLONG) NULL ); } gravitation-3+dfsg1.orig/minorGems/system/win32/MutexLockWin32.cpp0000644000175000017500000000341110762704567023645 0ustar pabspabs/* * Modification History * * 2001-January-27 Jason Rohrer * Created. * * 2001-March-4 Jason Rohrer * Replaced include of and with * to fix compile bugs encountered with newer windows compilers. * * 2002-October-18 Jason Rohrer * Moved common include out of header and into platform-specific cpp files, * since MemoryTrack uses a mutex lock. * * 2002-October-19 Jason Rohrer * Changed to use malloc instead of new internally to work with debugMemory. * Made use of mNativeObjectPointer a bit cleaner. * Fixed a few bugs with new use of mNativeObjectPointer. */ #include "minorGems/common.h" #include "minorGems/system/MutexLock.h" #include #include /** * Win32-specific implementation of the MutexLock class member functions. */ MutexLock::MutexLock() { // allocate a handle on the heap mNativeObjectPointer = malloc( sizeof( HANDLE ) ); // retrieve handle from the heap HANDLE *mutexPointer = (HANDLE *)mNativeObjectPointer; // create the mutex *mutexPointer = CreateMutex( (LPSECURITY_ATTRIBUTES) NULL, // no attributes (BOOL) false, // not initially locked (LPCTSTR) NULL ); // no name } MutexLock::~MutexLock() { // retrieve handle from the heap HANDLE *mutexPointer = (HANDLE *)mNativeObjectPointer; // destroy the mutex CloseHandle( *mutexPointer ); // de-allocate the mutex structure from the heap free( mutexPointer ); } void MutexLock::lock() { // retrieve handle from the heap HANDLE *mutexPointer = (HANDLE *)mNativeObjectPointer; WaitForSingleObject( *mutexPointer, INFINITE ); } void MutexLock::unlock() { // retrieve handle from the heap HANDLE *mutexPointer = (HANDLE *)mNativeObjectPointer; ReleaseMutex( *mutexPointer ); } gravitation-3+dfsg1.orig/minorGems/system/win32/ThreadWin32.cpp0000644000175000017500000000456010762704567023147 0ustar pabspabs/* * Modification History * * 2001-January-27 Jason Rohrer * Created. * * 2001-March-4 Jason Rohrer * Replaced include of and with * to fix compile bugs encountered with newer windows compilers. * * 2004-March-31 Jason Rohrer * Added missing call to CloseHandle in destructor. * Added support for detatched mode. * * 2004-April-1 Jason Rohrer * Fixed a bug in CloseHandle call pointed out by Mycroftxxx. * * 2005-January-22 Jason Rohrer * Added a static sleep function. */ #include "minorGems/system/Thread.h" #include /** * Win32-specific implementation of the Thread class member functions. * */ // prototype /** * A wrapper for the run method, since windows thread (perhaps) won't take * a class's member function. Takes a pointer to the Thread to run, * cast as a void*; */ DWORD WINAPI win32ThreadFunction( void * ); Thread::Thread() { // allocate a handle on the heap mNativeObjectPointer = (void *)( new HANDLE[1] ); } Thread::~Thread() { // get a pointer to the allocated handle HANDLE *threadPointer = (HANDLE *)mNativeObjectPointer; // close the handle to ensure that the thread resources are freed CloseHandle( threadPointer[0] ); // de-allocate the thread handle from the heap delete [] threadPointer; } void Thread::start( char inDetach ) { mIsDetached = inDetach; // get a pointer to the allocated handle HANDLE *threadPointer = (HANDLE *)mNativeObjectPointer; DWORD threadID; threadPointer[0] = CreateThread( (LPSECURITY_ATTRIBUTES)NULL, // no attributes (DWORD)0, // default stack size win32ThreadFunction, // function (LPVOID)this, // function arg (DWORD)0, // no creation flags (start thread immediately) &threadID ); } void Thread::join() { HANDLE *threadPointer = (HANDLE *)mNativeObjectPointer; WaitForSingleObject( threadPointer[0], INFINITE ); } void Thread::staticSleep( unsigned long inTimeInMilliseconds ) { Sleep( inTimeInMilliseconds ); } // takes a pointer to a Thread object as the data value DWORD WINAPI win32ThreadFunction( void *inPtrToThread ) { Thread *threadToRun = (Thread *)inPtrToThread; threadToRun->run(); if( threadToRun->isDetatched() ) { // thread detached, so we must destroy it delete threadToRun; } return 0; } gravitation-3+dfsg1.orig/minorGems/system/Time.h0000644000175000017500000000444310762704567020516 0ustar pabspabs/* * Modification History * * 2001-October-29 Jason Rohrer * Created. * * 2004-October-14 Jason Rohrer * Fixed sign bug. * * 2005-February-10 Jason Rohrer * Added function to get time in floating point format. */ #include "minorGems/common.h" #ifndef TIME_INCLUDED #define TIME_INCLUDED /** * Interface for platform-independent, high-resolution time access. * * @author Jason Rohrer */ class Time { public: /** * Gets the current time in seconds and milliseconds. * * No guarentee about when absolute 0 of this time * scale is for particular systems. * * @param outSeconds pointer to where the time in seconds * will be returned. * @param outMilliseconds pointer to where the extra * milliseconds will be returned. Value returned is in [0,999]. */ static void getCurrentTime( unsigned long *outSeconds, unsigned long *outMilliseconds ); /** * Gets the current time in fractional (double) seconds. * * @return the current time in seconds. */ static double getCurrentTime(); /** * Gets the number of milliseconds that have passed * since a time in seconds and milliseconds. * * @param inSeconds the start time, in seconds. * @param inMilliseconds the start time's additional milliseconds. * * @return the number of milliseconds that have passed * since inSeconds:inMilliseconds. May overflow if * more than 49 days have passed (assuming 32-bit longs). */ static unsigned long getMillisecondsSince( unsigned long inSeconds, unsigned long inMilliseconds ); }; inline double Time::getCurrentTime() { unsigned long currentTimeS; unsigned long currentTimeMS; getCurrentTime( ¤tTimeS, ¤tTimeMS ); return currentTimeS + currentTimeMS / 1000.0; } inline unsigned long Time::getMillisecondsSince( unsigned long inSeconds, unsigned long inMilliseconds ) { unsigned long currentTimeS; unsigned long currentTimeMS; getCurrentTime( ¤tTimeS, ¤tTimeMS ); unsigned long deltaS = ( currentTimeS - inSeconds ); long deltaMS = ( (long)currentTimeMS - (long)inMilliseconds ); // carry, if needed if( deltaMS < 0 ) { deltaS--; deltaMS += 1000; } return 1000 * deltaS + deltaMS; } #endif gravitation-3+dfsg1.orig/minorGems/system/FinishedSignalThread.h0000644000175000017500000000326510762704567023640 0ustar pabspabs/* * Modification History * * 2002-March-9 Jason Rohrer * Created. * * 2002-March-10 Jason Rohrer * Made destructor public. * * 2002-March-11 Jason Rohrer * Changed so that destructor joins thread. * * 2002-April-4 Jason Rohrer * Changed name of lock to avoid confusion with subclass-provided locks. * * 2004-April-1 Jason Rohrer * Moved from konspire2b into minorGems. * Changed so that destructor does not join the thread. * * 2004-November-19 Jason Rohrer * Changed to virtual inheritance from Thread class. */ #ifndef FINISHED_SIGNAL_THREAD_INCLUDED #define FINISHED_SIGNAL_THREAD_INCLUDED #include "minorGems/system/Thread.h" #include "minorGems/system/MutexLock.h" /** * Abstract subclass if thread that has a * synchronized finished signal. * * @author Jason Rohrer */ class FinishedSignalThread : public virtual Thread { public: /** * Only destroys this thread. * Does not join. */ virtual ~FinishedSignalThread(); /** * Gets whether this thread is finished and * ready to be destroyed. * * @return true iff this thread is finished. */ char isFinished(); protected: FinishedSignalThread(); /** * Sets that this thread is finished and * ready to be destroyed. * * For this class to work properly, the subclass * MUST call this function at the end of its run method. */ void setFinished(); private: MutexLock *mFinishedLock; char mFinished; }; #endif gravitation-3+dfsg1.orig/minorGems/system/ThreadSafePrinter.h0000644000175000017500000000262710762704567023174 0ustar pabspabs/* * Modification History * * 2000-October-14 Jason Rohrer * Created. * * 2001-January-27 Jason Rohrer * Converted to use MutexLock and added to minorGems source tree. * Changed tprintf to be static (the mutexes don't work otherwise). * Now we're closing the argument list. * Fixed so that it works with any number of arguments. * Changed name of print function to printf. * * 2004-March-31 Jason Rohrer * Fixed static memory leak. */ #include "minorGems/common.h" #ifndef THREAD_SAFE_PRINTER_INCLUDED #define THREAD_SAFE_PRINTER_INCLUDED #include "MutexLock.h" #include // for variable argument lists #include /** * Thread safe printf function. Note that printf is actually thread safe * anyway, so this is just to demonstrate and test locks. It seems as * though printf _isn't_ thread safe on certain platforms, so this class * may be useful. * * @author Jason Rohrer */ class ThreadSafePrinter { public: static int printf( const char* inFormatString, ... ); private: static MutexLock sLock; }; // initialize static members MutexLock ThreadSafePrinter::sLock; inline int ThreadSafePrinter::printf( const char*inFormatString, ... ) { va_list argList; va_start( argList, inFormatString ); sLock.lock(); int returnVal = vprintf( inFormatString, argList ); fflush( stdout ); sLock.unlock(); va_end( argList ); return returnVal; } #endif gravitation-3+dfsg1.orig/minorGems/system/endian.h0000644000175000017500000000276110762704567021057 0ustar pabspabs/* * Modification History * * 2002-May-25 Jason Rohrer * Created. * * 2004-January-12 Jason Rohrer * Added support for metrowerks win32 compiler. */ #include "minorGems/common.h" /** * Include this file to define __BYTE_ORDER * * After this has been included, __BYTE_ORDER will be either * __LITTLE_ENDIAN or * --BIG_ENDIAN */ #ifdef __FreeBSD__ #include #elif defined(__NetBSD__) #include // default BSD case #elif defined(BSD) #include #elif defined(SOLARIS) // Code for Solaris defs adapted from: // MD5 message-digest algorithm. // by Colin Plumb in 1993, no copyright is claimed. //each solaris is different -- this won't work on 2.6 or 2.7 # include #define __LITTLE_ENDIAN 1234 #define __BIG_ENDIAN 4321 #ifdef _LITTLE_ENDIAN #define __BYTE_ORDER __LITTLE_ENDIAN #else // default to big endian #define __BYTE_ORDER __BIG_ENDIAN #endif // end solaris case #elif defined(WIN_32) || \ ( defined(__MWERKS__) && defined(__INTEL__) ) // windows case #define __LITTLE_ENDIAN 1234 #define __BYTE_ORDER __LITTLE_ENDIAN // end windows case #else // linux case #include // end linux case #endif // end of all system-specific cases // BSD calls it BYTE_ORDER, linux calls it __BYTE_ORDER #ifndef __BYTE_ORDER #define __BYTE_ORDER BYTE_ORDER #endif #ifndef __LITTLE_ENDIAN #define __LITTLE_ENDIAN LITTLE_ENDIAN #endif #ifndef __BIG_ENDIAN #define __BIG_ENDIAN BIG_ENDIAN #endif gravitation-3+dfsg1.orig/minorGems/system/StopSignalThread.cpp0000644000175000017500000000231510762704567023362 0ustar pabspabs/* * Modification History * * 2002-April-4 Jason Rohrer * Created. * Changed to reflect the fact that the base class * destructor is called *after* the derived class destructor. * * 2002-August-5 Jason Rohrer * Fixed member initialization order to match declaration order. * * 2003-September-5 Jason Rohrer * Moved into minorGems. * * 2005-January-9 Jason Rohrer * Changed to sleep on a semaphore to make sleep interruptable by stop. */ #include "StopSignalThread.h" StopSignalThread::StopSignalThread() : mStopLock( new MutexLock() ), mStopped( false ), mSleepSemaphore( new BinarySemaphore() ) { } StopSignalThread::~StopSignalThread() { delete mStopLock; delete mSleepSemaphore; } void StopSignalThread::sleep( unsigned long inTimeInMilliseconds ) { mSleepSemaphore->wait( inTimeInMilliseconds ); } char StopSignalThread::isStopped() { mStopLock->lock(); char stoped = mStopped; mStopLock->unlock(); return stoped; } void StopSignalThread::stop() { mStopLock->lock(); mStopped = true; mStopLock->unlock(); // signal the semaphore to wake up the thread, if it is sleeping mSleepSemaphore->signal(); } gravitation-3+dfsg1.orig/minorGems/system/TestThread.cpp0000644000175000017500000000231710762704567022220 0ustar pabspabs/* * Modification History * * 2000-December-13 Jason Rohrer * Created. * * 2002-November-14 Jason Rohrer * Added more verbose printouts. * * 2004-March-31 Jason Rohrer * Added test of detached threads. */ #include "TestThread.h" int numToCount = 1000; /** * Main method that spawns two TestThreads. * * @author Jason Rohrer */ int main() { TestThread *thread1 = new TestThread( 1, numToCount ); TestThread *thread2 = new TestThread( 2, numToCount ); TestThread *thread3 = new TestThread( 3, numToCount ); ThreadSafePrinter::printf( "Starting thread 1\n" ); thread1->start(); ThreadSafePrinter::printf( "Starting thread 2\n" ); thread2->start(); ThreadSafePrinter::printf( "Starting thread 3 in detached mode\n" ); thread3->start( true ); Thread::sleep( 5000 ); ThreadSafePrinter::printf( "Joining thread 1\n" ); thread1->join(); ThreadSafePrinter::printf( "Joining thread 2\n" ); thread2->join(); ThreadSafePrinter::printf( "Destroying thread 1\n" ); delete thread1; ThreadSafePrinter::printf( "Destroying thread 2\n" ); delete thread2; ThreadSafePrinter::printf( "Thread 3 should handle its own destruction.\n" ); return 0; } gravitation-3+dfsg1.orig/minorGems/system/FinishedSignalThreadManager.cpp0000644000175000017500000000461510762704567025466 0ustar pabspabs/* * Modification History * * 2004-November-9 Jason Rohrer * Created. * Modified from MUTE's ChannelReceivingThreadManager. * * 2005-January-9 Jason Rohrer * Changed to sleep on a semaphore to allow sleep to be interrupted. */ #include "minorGems/system/FinishedSignalThreadManager.h" FinishedSignalThreadManager::FinishedSignalThreadManager() : mLock( new MutexLock() ), mThreadVector( new SimpleVector() ), mStopSignal( false ), mSleepSemaphore( new BinarySemaphore() ) { this->start(); } FinishedSignalThreadManager::~FinishedSignalThreadManager() { mLock->lock(); mStopSignal = true; mLock->unlock(); // signal the sleeping semaphore to wake up the thread mSleepSemaphore->signal(); this->join(); mLock->lock(); // destroy all remaining threads int numThreads = mThreadVector->size(); for( int i=0; igetElement( i ) ); } delete mThreadVector; mLock->unlock(); delete mLock; delete mSleepSemaphore; } void FinishedSignalThreadManager::addThread( FinishedSignalThread *inThread ) { mLock->lock(); mThreadVector->push_back( inThread ); mLock->unlock(); } void FinishedSignalThreadManager::run() { char stopped; mLock->lock(); stopped = mStopSignal; mLock->unlock(); while( !stopped ) { // wait for 10 seconds int wasSignaled = mSleepSemaphore->wait( 10000 ); if( wasSignaled == 1 ) { // signaled... we should stop return; } char foundFinished = true; while( foundFinished ) { foundFinished = false; mLock->lock(); int numThreads = mThreadVector->size(); for( int i=0; igetElement( i ) ); if( currentThread->isFinished() ) { delete currentThread; mThreadVector->deleteElement( i ); foundFinished = true; } } mLock->unlock(); } mLock->lock(); stopped = mStopSignal; mLock->unlock(); } } gravitation-3+dfsg1.orig/minorGems/system/Thread.h0000644000175000017500000000560710762704567021032 0ustar pabspabs/* * Modification History * * 2000-December-13 Jason Rohrer * Created. * * 2001-March-4 Jason Rohrer * Made sleep() static so it can be called by non-Thread classes. * * 2001-May-12 Jason Rohrer * Added comments about joining before destroying. * * 2002-March-29 Jason Rohrer * Added Fortify inclusion. * * 2002-August-5 Jason Rohrer * Made destructor virtual. * * 2004-March-31 Jason Rohrer * Added support for detatched mode. * * 2005-January-9 Jason Rohrer * Made sleep function virtual to allow overrides. * * 2005-January-22 Jason Rohrer * Added a static sleep function. */ #include "minorGems/common.h" #ifndef THREAD_CLASS_INCLUDED #define THREAD_CLASS_INCLUDED #ifdef FORTIFY #include "minorGems/util/development/fortify/fortify.h" #endif /** * Base class to be subclassed by all threads. * * Note: Implementation for the functions defined here is provided * separately for each platform (in the mac/ linux/ and win32/ * subdirectories). * * @author Jason Rohrer */ class Thread { public: Thread(); virtual ~Thread(); /** * Starts this Thread. * * Note that after starting a non-detached thread, it _must_ be * joined before being destroyed to avoid memory leaks. * * Threads running in detatched mode handle their own destruction * as they terminate and do not need to be joined at all. * * @param inDetach true if this thread should run in detatched mode, * or false to run in non-detached mode. Defaults to false. */ void start( char inDetach = false ); /** * To be overriden by subclasses. * This method will be run by the Thread after start() has been called. */ virtual void run() = 0; /** * Blocks until this thread finishes executing its run() method. * * Must be called before destroying this thread, if this thread * has been started. */ void join(); /** * Puts the current thread to sleep for a specified amount of time. * * Note that given a thread instance threadA, calling threadA.sleep() * will put the calling thread to sleep. * * @param inTimeInMilliseconds the number of milliseconds to sleep. */ virtual void sleep( unsigned long inTimeInMilliseconds ) { staticSleep( inTimeInMilliseconds ); } /** * Same as sleep, but can be called without constructing a thread. */ static void staticSleep( unsigned long inTimeInMilliseconds ); /** * Gets whether this thread is detached. * * @return true if this thread is detached. */ char isDetatched() { return mIsDetached; } private: /** * Used by platform-specific implementations. */ void *mNativeObjectPointer; char mIsDetached; }; #endif gravitation-3+dfsg1.orig/minorGems/system/FinishedSignalThread.cpp0000644000175000017500000000203410762704567024164 0ustar pabspabs/* * Modification History * * 2002-March-9 Jason Rohrer * Created. * * 2002-March-11 Jason Rohrer * Changed so that destructor joins thread. * * 2002-April-4 Jason Rohrer * Changed name of lock to avoid confusion with subclass-provided locks. * * 2002-August-5 Jason Rohrer * Fixed member initialization order to match declaration order. * * 2004-April-1 Jason Rohrer * Moved from konspire2b into minorGems. * Changed so that destructor does not join the thread. */ #include "FinishedSignalThread.h" #include FinishedSignalThread::FinishedSignalThread() : mFinishedLock( new MutexLock() ), mFinished( false ) { } FinishedSignalThread::~FinishedSignalThread() { delete mFinishedLock; } char FinishedSignalThread::isFinished() { mFinishedLock->lock(); char finished = mFinished; mFinishedLock->unlock(); return finished; } void FinishedSignalThread::setFinished() { mFinishedLock->lock(); mFinished = true; mFinishedLock->unlock(); } gravitation-3+dfsg1.orig/minorGems/system/FinishedSignalThreadManager.h0000644000175000017500000000273610762704567025135 0ustar pabspabs/* * Modification History * * 2004-November-9 Jason Rohrer * Created. * Modified from MUTE's ChannelReceivingThreadManager. * * 2005-January-9 Jason Rohrer * Changed to sleep on a semaphore to allow sleep to be interrupted. */ #ifndef FINISHED_SIGNAL_THREAD_MANAGER_INCLUDED #define FINISHED_SIGNAL_THREAD_MANAGER_INCLUDED #include "minorGems/system/FinishedSignalThread.h" #include "minorGems/util/SimpleVector.h" #include "minorGems/system/Thread.h" #include "minorGems/system/MutexLock.h" #include "minorGems/system/BinarySemaphore.h" /** * A thread that manages the destruction of FinishedSignalThreads. * * @author Jason Rohrer. */ class FinishedSignalThreadManager : public Thread { public: /** * Constructs and starts this manager. */ FinishedSignalThreadManager(); /** * Stops and destroys this manager. */ ~FinishedSignalThreadManager(); /** * Adds a thread to this manager. * * @param inThread the thread to add. * Will be destroyed by this class. */ void addThread( FinishedSignalThread *inThread ); // implements the Thread interface void run(); protected: MutexLock *mLock; SimpleVector *mThreadVector; char mStopSignal; BinarySemaphore *mSleepSemaphore; }; #endif gravitation-3+dfsg1.orig/minorGems/system/TestThread.h0000644000175000017500000000252110762704567021662 0ustar pabspabs/* * Modification History * * 2000-December-13 Jason Rohrer * Created. * * 2001-January-27 Jason Rohrer * Switched to a ThreadSafePrinter in attempt to get it to work on Win32. * Changed print call to printf. * * 2002-November-14 Jason Rohrer * Added missing destructor. */ #include "minorGems/common.h" #ifndef TEST_THREAD_CLASS_INCLUDED #define TEST_THREAD_CLASS_INCLUDED #include "Thread.h" #include "ThreadSafePrinter.h" #include /** * Test subclass of Thread class. Useful for testing if platform-specific * thread implmentations are working. * * @author Jason Rohrer */ class TestThread : public Thread { public: /** * Constructs a test thread and tells it how high to count to. * * @param inID id number thread will print along with count. * @param inNumToCount thread will count from 0 to this number. */ TestThread( int inID, int inNumToCount ); ~TestThread(); // override the run method from PThread void run(); private: int mID; int mNumToCount; }; inline TestThread::TestThread( int inID, int inNumToCount ) : mID( inID ), mNumToCount( inNumToCount ) { } inline TestThread::~TestThread() { } inline void TestThread::run() { for( int i=0; i<=mNumToCount; i++ ) { ThreadSafePrinter::printf( "Thread %d counting %d.\n", mID, i ); } } #endif gravitation-3+dfsg1.orig/minorGems/system/StopSignalThread.h0000644000175000017500000000361610762704567023034 0ustar pabspabs/* * Modification History * * 2002-April-4 Jason Rohrer * Created. * Changed to reflect the fact that the base class * destructor is called *after* the derived class destructor. * * 2003-September-5 Jason Rohrer * Moved into minorGems. * * 2004-November-19 Jason Rohrer * Changed to virtual inheritance from Thread class. * * 2005-January-9 Jason Rohrer * Changed to sleep on a semaphore to make sleep interruptable by stop. */ #ifndef STOP_SIGNAL_THREAD_INCLUDED #define STOP_SIGNAL_THREAD_INCLUDED #include "minorGems/system/Thread.h" #include "minorGems/system/MutexLock.h" #include "minorGems/system/BinarySemaphore.h" /** * Abstract subclass of thread that has a stop signal. * * Note that subclasses MUST check the isStopped() function * periodically in their run() function for this class to work * properly. * * @author Jason Rohrer */ class StopSignalThread : public virtual Thread { public: /** * Only destroys this thread. * Does not stop or join. */ virtual ~StopSignalThread(); protected: StopSignalThread(); // overrides Thread::sleep to make it interruptable by our stop call virtual void sleep( unsigned long inTimeInMilliseconds ); /** * Signals this thread to stop, interrupting it if it is sleeping. * * Thread safe. * * Thread must be joined after this call returns. */ void stop(); /** * Gets whether this thread has been signaled to stop. * * Thread safe. * * @return true if this thread should stop. */ char isStopped(); private: MutexLock *mStopLock; char mStopped; BinarySemaphore *mSleepSemaphore; }; #endif gravitation-3+dfsg1.orig/minorGems/system/Launcher.h0000644000175000017500000000163010762704567021354 0ustar pabspabs/* * Modification History * * 2003-January-10 Jason Rohrer * Created. */ #include "minorGems/common.h" #ifndef LAUNCHER_INCLUDED #define LAUNCHER_INCLUDED /** * Interface for launching processes. * * @author Jason Rohrer */ class Launcher { public: /** * Launches a command in a new process. * * @param inCommandName the name of the command to launch. * Must be destroyed by caller if non-const. * @param inArguments an array of argument strings for the command. * This array must be terminated by a NULL pointer. * Note that by convention, the first argument should be the * command name. * Must be destroyed by caller. */ static void launchCommand( char *inCommandName, char **inArguments ); }; #endif gravitation-3+dfsg1.orig/minorGems/system/Semaphore.h0000644000175000017500000001023310762704567021535 0ustar pabspabs/* * Modification History * * 2001-January-11 Jason Rohrer * Created. * * 2001-January-11 Jason Rohrer * Added a willBlock() function. * * 2001-February-24 Jason Rohrer * Fixed incorrect delete usage. * * 2002-February-11 Jason Rohrer * Fixed a mistake in the signal() comment. * * 2003-August-26 Jason Rohrer * Added support for timeouts on wait. * * 2003-December-28 Jason Rohrer * Fixed a bug in semaphore value when we timeout on wait. * * 2004-January-9 Jason Rohrer * Fixed a preprocessor error. */ #include "minorGems/common.h" #ifndef SEMAPHORE_CLASS_INCLUDED #define SEMAPHORE_CLASS_INCLUDED #include "MutexLock.h" #include "BinarySemaphore.h" /** * General semaphore with an unbounded value. * * This class uses BinarySemaphores to implement general semaphores, * so it relies on platform-specific BinarySemaphore implementations, * but this class itself is platform-independent. * * @author Jason Rohrer */ class Semaphore { public: /** * Constructs a semaphore. * * @param inStartingValue the starting value for this semaphore. * Defaults to 0 if unspecified. */ Semaphore( int inStartingValue = 0 ); ~Semaphore(); /** * If this semaphore's current value is 0, then this call blocks * on this semaphore until signal() is called by another thread. * If this semaphore's value is >0, then it is decremented by this * call. * * @param inTimeoutInMilliseconds the maximum time to wait in * milliseconds, or -1 to wait forever. Defaults to -1. * * @return 1 if the semaphore was signaled, or 0 if it timed out. */ int wait( int inTimeoutInMilliseconds = -1 ); /** * If a thread is waiting on this semaphore, then the thread * becomes unblocked. * If no thread is waiting, then the semaphore is incremented. */ void signal(); /** * Returns true if a call to wait would have blocked. */ char willBlock(); private: // starts at 0 int mSemaphoreValue; // mutex semaphore starts at 1 BinarySemaphore *mMutexSemaphore; // blocking semaphore starts at 0 BinarySemaphore *mBlockingSemaphore; }; inline Semaphore::Semaphore( int inStartingValue ) : mSemaphoreValue( inStartingValue ), mMutexSemaphore( new BinarySemaphore() ), mBlockingSemaphore( new BinarySemaphore() ) { // increment the mutex semaphore to 1 mMutexSemaphore->signal(); } inline Semaphore::~Semaphore() { delete mMutexSemaphore; delete mBlockingSemaphore; } inline int Semaphore::wait( int inTimeoutInMilliseconds ) { int returnValue; // this implementation copied from _Operating System Concepts_, p. 172 // lock the mutex mMutexSemaphore->wait(); // decrement the semaphore mSemaphoreValue--; if( mSemaphoreValue < 0 ) { // we should block // release the mutex mMutexSemaphore->signal(); // block returnValue = mBlockingSemaphore->wait( inTimeoutInMilliseconds ); if( returnValue != 1 ) { // timed out // increment the semaphore, since we never got signaled // lock the mutex mMutexSemaphore->wait(); mSemaphoreValue++; // we will unlock the mutex below } } else { returnValue = 1; } // release the mutex // ( if we were signaled, then the signaller left the mutex locked ) // ( if we timed out, then we re-locked the mutex above ) mMutexSemaphore->signal(); return returnValue; } inline char Semaphore::willBlock() { char returnValue = false; // lock the mutex mMutexSemaphore->wait(); // check if we will block if( mSemaphoreValue <= 0 ) { returnValue = true; } // release the mutex mMutexSemaphore->signal(); return returnValue; } inline void Semaphore::signal() { // lock the mutex mMutexSemaphore->wait(); // increment the semaphore mSemaphoreValue++; if( mSemaphoreValue <= 0 ) { // we need to wake up a waiting thread mBlockingSemaphore->signal(); // let the waiting thread unlock the mutex } else { // no threads are waiting, so we need to unlock the mutex mMutexSemaphore->signal(); } } #endif gravitation-3+dfsg1.orig/minorGems/.emacs0000644000175000017500000001642210762704566017213 0ustar pabspabs; Modification History ;; ;; 2001-March-10 Jason Rohrer ;; Created. ;; Fixed so that c++ mode is used for .h files. ;; Fixed [C-backspace] mapping. ;; ;; 2001-May-21 Jason Rohrer ;; Changed so that Java inclass items are not doubly indented. ;; ;; 2002-January-21 Jason Rohrer ;; Gave in and set to use spaces instead of tabs. ;; This is primarily motivated by the fact that tabs look terrible ;; in CVS-web. ;; ;; 2005-January-16 Jason Rohrer ;; Added php mode. ;; (custom-set-variables ;; custom-set-variables was added by Custom -- don't edit or cut/paste it! ;; Your init file should contain only one such instance. '(case-fold-search t) '(current-language-environment "ASCII") '(global-font-lock-mode t nil (font-lock)) '(tab-stop-list (quote (4 8 12 16 20 24 28 32 36 40 44 48 52 56 60))) '(transient-mark-mode t)) (custom-set-faces ;; custom-set-faces was added by Custom -- don't edit or cut/paste it! ;; Your init file should contain only one such instance. ) ;(setq-default scroll-step 1) ; turn off jumpy scroll (setq-default visible-bell t) ; no beeps, flash on errors (display-time) ; display the time on modeline (column-number-mode t) ; display the column number on modeline (setq-default kill-whole-line t) ; ctrl-k kills whole line if at col 0 (setq-default fill-column 80) ; wrap at col 80 (setq-default tab-width 4) ; show tabs as 4 cols (setq font-lock-maximum-decoration t) ; use colours in font lock mode (setq font-lock-maximum-size nil) ; turn off limit on font lock mode ; turn on font-lock everywhere (if possible) (global-font-lock-mode 1 t) ; make sure C-backspace kills a word ( global-set-key `[C-backspace] `backward-kill-word ) ; background color, light yellow ( add-to-list 'default-frame-alist '( background-color . "#FFFFDC" ) ) ; auto fill mode ( add-hook 'c-mode-common-hook 'turn-on-auto-fill ) ; fix comment syntax highlighting problems ( setq font-lock-support-mode 'lazy-lock-mode ) ( setq lazy-lock-defer-time 0 ) ; delete highlighted text as we type ( delete-selection-mode t ) ; make sure c++ mode is used for .h files ( setq auto-mode-alist ( append '( ("\\.h$" . c++-mode) ) auto-mode-alist ) ) ; off for now, since it screws up indenting ; load the line numbers package ;( load "setnu" ); ; turn it on ;( add-hook 'c-mode-common-hook 'turn-on-setnu-mode ) ( copy-face 'italic 'font-lock-comment-face ) ( set-face-foreground 'font-lock-comment-face "#00AA00" ) ( setq font-lock-comment-face 'font-lock-comment-face ) ( copy-face 'default 'font-lock-string-face ) ( set-face-foreground 'font-lock-string-face "#FF00FF" ) ( setq font-lock-string-face 'font-lock-string-face ) ( copy-face 'bold 'font-lock-type-face ) ( set-face-foreground 'font-lock-type-face "#0000FF" ) ( setq font-lock-type-face 'font-lock-type-face ) ( copy-face 'bold 'font-lock-keyword-face ) ( set-face-foreground 'font-lock-keyword-face "#C88000" ) ( setq font-lock-keyword-face 'font-lock-keyword-face ) ( copy-face 'default 'font-lock-function-name-face ) ( set-face-foreground 'font-lock-function-name-face "#C80000" ) ( setq font-lock-function-name-face 'font-lock-function-name-face ) ( copy-face 'default 'font-lock-variable-name-face ) ( set-face-foreground 'font-lock-variable-name-face "#0000FF" ) ( setq font-lock-variable-name-face 'font-lock-variable-name-face ) ( copy-face 'bold 'font-lock-constant-face ) ( set-face-foreground 'font-lock-constant-face "#C800FF" ) ( setq font-lock-constant-face 'font-lock-constant-face ) ( copy-face 'bold 'font-lock-warning-face ) ( set-face-foreground 'font-lock-warning-face "#FF0000" ) ( setq font-lock-warning-face 'font-lock-warning-face ) ( copy-face 'default 'font-lock-reference-face ) ( set-face-foreground 'font-lock-reference-face "#00FFFF" ) ( setq font-lock-reference-face 'font-lock-reference-face ) (defconst my-c-style '((c-tab-always-indent . t) (c-comment-only-line-offset . 4) (c-hanging-braces-alist . ((substatement-open after) (defun-open after) (block-open after) (class-open after) (inline-open after) (brace-entry-open after) (brace-list-open))) (c-hanging-colons-alist . ((member-init-intro before) (inher-intro) (case-label after) (label after) (access-label after))) (c-cleanup-list . (scope-operator empty-defun-braces defun-close-semi)) (c-offsets-alist . ((arglist-close . c-lineup-arglist) (substatement-open . 0) (case-label . 4) (block-open . 0) (comment-intro . 0) (block-close . 4) (inclass . 8) (access-label . -4) (defun-close . 4) (inline-close . 4) (class-close . 4) (brace-list-close . 4) (knr-argdecl-intro . -))) (c-echo-syntactic-information-p . t) ) "My C Programming Style") ;; Customizations for all of c-mode, c++-mode, and objc-mode (defun my-c-mode-common-hook () ;; add my personal style and set it for the current buffer (c-add-style "PERSONAL" my-c-style t) ;; offset customizations not in my-c-style (c-set-offset 'member-init-intro '++) ;; other customizations (setq tab-width 4 ;; this will make sure spaces are used instead of tabs indent-tabs-mode nil) ;; we like auto-newline and hungry-delete (c-toggle-auto-hungry-state 1) ;; keybindings for C, C++, and Objective-C. We can put these in ;; c-mode-map because c++-mode-map and objc-mode-map inherit it (define-key c-mode-map "\C-m" 'newline-and-indent) ) ;; the following only works in Emacs 19 ;; Emacs 18ers can use (setq c-mode-common-hook 'my-c-mode-common-hook) (add-hook 'c-mode-common-hook 'my-c-mode-common-hook) (add-hook 'java-mode-hook 'my-c-mode-common-hook) ( add-hook 'perl-mode-hook 'my-perl-mode-hook ) (require 'php-mode) ; caml mode (Tuareg) (setq auto-mode-alist (cons '("\\.ml\\w?" . tuareg-mode) auto-mode-alist)) (autoload 'tuareg-mode "tuareg" "Major mode for editing Caml code" t) (autoload 'camldebug "camldebug" "Run the Caml debugger" t) ; old caml mode ;(setq auto-mode-alist ; (cons '("\\.ml[iylp]?$" . caml-mode) auto-mode-alist)) ;(autoload 'caml-mode "caml" "Major mode for editing Caml code." t) ;(autoload 'run-caml "inf-caml" "Run an inferior Caml process." t) ;(if window-system (require 'caml-font)) (put 'downcase-region 'disabled nil) ;; actionscript (for flash development) (autoload 'actionscript-mode "actionscript-mode" "Major mode for actionscript." t) ;; Activate actionscript-mode for any files ending in .as (add-to-list 'auto-mode-alist '("\\.as$" . actionscript-mode)) ;; Load our actionscript-mode extensions. ;;(eval-after-load "actionscript-mode" '(load "as-config"))gravitation-3+dfsg1.orig/minorGems/numtest.cpp0000644000175000017500000000135510762704566020324 0ustar pabspabs/* * Modification History * * 2001-February-3 Jason Rohrer * Created. * * 2001-February-4 Jason Rohrer * Fixed a bug that made this test not compatible with TypeIO. * Fixed comment. */ #include // function for testing how doubles are stored /* * The output from a big-endian linux is as follows: * * size of double = 8 * byte 0 = 63 * byte 1 = 255 * byte 2 = 189 * byte 3 = 137 * byte 4 = 176 * byte 5 = 126 * byte 6 = 158 * byte 7 = 168 * */ int main() { printf( "size of double = %d\n", sizeof( double ) ); double x = 1.983773889; unsigned char *doubleBuffer = (unsigned char*)( &x ); for( int i=0; i<8; i++ ) { printf( "byte %d = %d\n", i, doubleBuffer[i] ); } return 0; } gravitation-3+dfsg1.orig/minorGems/protocol/0000755000175000017500000000000010762704567017757 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/protocol/p2p/0000755000175000017500000000000010762704567020460 5ustar pabspabsgravitation-3+dfsg1.orig/minorGems/protocol/p2p/motivationEmail.txt0000644000175000017500000001267710762704567024377 0ustar pabspabsGreetings, I had a bit of correspondence with you about a year ago concerning "konspire", a distributed file sharing system that I was developing. As you may be aware, konspire never caught on. konspire failed to be popular for several reasons, but the major reason was that it was written using Java and had no natively compiled client or server available. Most people don't like to mess with getting a Java application up and running. Another problem was ease of use: konspire didn't work immediately "out of the box", as users had to enter the address of a live server the first time they ran konspire. Finally, there was a problem that never rose to the surface, which was scalability: had konspire become popular, the indexing scheme being used would have limited the network to about 100,000 files. When I was developing konspire, I was focusing on "complete searching" capabilities. When you got search results back using konspire, you could be certain that you were seeing a list of all files in the system that matched your search. With Gnutella, results trickled back over time, and you were never sure when they would stop arriving. With Napster, you could only search through files on one of their sub-servers. Of course, both Gnutella and Napster scale very well: in theory, the number of nodes in the network has no limit (though you can only search through a fraction of the available files). With konspire, each designated "server" node keeps a complete copy of the system-wide file index. The size of the index is bounded by the size of the memory available to the most memory-limited server. Thus, konspire does not scale well at all. Furthermore, even if the limit is not hit, who wants to donate their system's entire memory to the konspire file index? Add the 20MiB+ base memory requirements of Java to this, and konspire servers are major memory hogs. For a while, plans for konspire v1.2 were in place, and the new protocol would attempt to fix the scaling problems by splitting each copy of the index among a cluster of server nodes. Keeping things organized gets very messy, though. In the mean time, much simpler systems like Gnutella started to work well, once they had a larger consistent user base and a more connected network. In fact, you can find almost anything these days using a BearShare client... why bother with a smarter protocol? FastTrack improved the scalability with ideas similar to those of konspire v1.2, but they threw in a nice self-organization concept: self-organization frees novice users from making decisions (many users were endlessly confused about the difference between clients and servers in konspire). FastTrack has a huge problem, though: they are commercial and proprietary. You would think that these companies would learn their lesson from the Napster debacle. Do they think the RIAA will look the other way? Notice that the RIAA has not even touched Gnutella, since they have no one to point a suit at. The FastTrack protocol (supposedly) is also very specific to the way FastTrack organizes a network. Network organization and peer communication protocol seem like they could be completely separated. The kind of messages sent in a Napster network are pretty much the same as the kind of messages sent in a Gnutella network. The differences lie in how nodes behave and what they do upon receipt of a particular message. Think of a search request message: Gnutella nodes search themselves and pass the request on to other nodes; FastTrack nodes pass the request on to super-nodes, who pass the request among themselves. Why do the messages and protocols for a search request need to be different for Gnutella and FastTrack? In fact, Gnutella nodes and FastTrack nodes could be joined into one common network if they only used the same protocol. In fact, even a network that differs from Gnutella as much as Freenet could use the same communication protocol. Gnutella has download requests as well as search requests. Freenet in essence only has download requests. When a Gnutella node receives a DL request, it sends back the file, or sends a rejection if it doesn't have the file. A Freenet node differs in that it forwards download (key) requests (much like the way Gnutella forwards search requests). Again, another example of networks that differ in node behavior and not communication protocol. Freenet's communication protocol is a subset of the Gnutella communication protocol. I'm currently toying with a general purpose peer-to-peer protocol. When I say "general purpose", I mean that the protocol is extraordinarily general and abstract. Ideally, any kind of p2p network could make use of this protocol. However, the protocol itself is very simple, so simple that anyone could understand it. One could imagine p2p network developers "adding on" support for this protocol to existing p2p node software, allowing all networks supporting the protocol to be joined together. One upshot of such a protocol is that it could be used to design a non-proprietary replacement for FastTrack: nodes would decide to become servers and then simply behave differently than the nodes that are clients. I'm contacting you because I'm wondering if you've run into similar ideas or initiatives out there. If so, could you point me towards them? Anyway, I'll keep you posted with news as I work on this more... What will the protocol be called? Is the name "konspire" taken yet? ;) Thanks, Jason Rohrer HC software -- http://www.jasonrohrer.n3.net gravitation-3+dfsg1.orig/minorGems/protocol/p2p/notes.tex0000644000175000017500000001610710762704567022337 0ustar pabspabs% % Modification History % % 2001-October-8 Jason Rohrer % Created. % % 2001-December-2 Jason Rohrer % Fixed a few typos and mistakes. % \documentclass[12pt]{article} \usepackage{fullpage} \begin{document} \title{Generic peer-to-peer protocol notes} \date{Created: October 8, 2001; Last modified: December 1, 2001} \maketitle We can think of a peer-to-peer network as a group of hosts such that each host has a set of resources made available to the other hosts in the group. Peer $A$ can ask peer $B$ for a resource $r$ by sending $B$ a resource descriptor $D_r$, and peer $B$ can respond in one of \ref{response:count} ways: \begin{enumerate} \item Send a null response (equivalent to ``I know nothing about $r$''). \item Return the requested resource $r$. \item Return the address of a host that may know more about resource $r$ (referred to as informing $A$ of a more knowledgeable host). \label{response:inform} \item Forward the request for $r$ on to other hosts in the network and inform $A$ that it is doing so.\label{response:forward} \label{response:count} \end{enumerate} For response option \ref{response:forward} to make sense, we must assume that each resource descriptor $D_r$ contains a return address where the resource should be sent and a request identifier so that $A$ knows that a particular inbound transmission is a response to its request for $r$. To be compatible with request forwarding, all responses should be sent to the return address contained in the request. To make sense in this context, the null response should be embodied by no response at all. Because responses are not returned via the same two-way transmission channel on which the corresponding requests were sent, a responding host $B$ can in fact perform any subset of the response options simultaneously. Thus, the system can operate using only one-way transmissions. In this context, the null response corresponds to the empty response set. A network that avoids option \ref{response:forward} could still be a very usable network and in fact would require far fewer network transmissions to operate (as well as distributing the work load more heavily upon those hosts actually requesting resources). However, such a network would not take advantage of the work distribution possible with a forwarding network. Note that a non-forwarding network can be just as powerful as a forwarding network by clever use of response option \ref{response:inform} in place of \ref{response:forward}. We will deal only with forwarding networks throughout the rest of this document. As a simple example, consider the case where $r$ is file data. $A$ sends $D_r$ to $B$, and $B$ might execute a null response or return the requested resource by sending back the file data associated with $D_r$. We might assume that $D_r$ contains information that uniquely describes a file resource being offered by $B$, so neither response option \ref{response:inform} nor response option \ref{response:forward} would apply. For a more complex example, consider the case where $r$ is a search results set. Note that a search is itself a resource that might be offered by a host, and we might have specially-designated index nodes in the network that offer the resource of searching. Suppose $A$ sends $D_r$ to $B$. $D_r$ might contain information about the resource types to search for, as well as a set of resource descriptors. Suppose that $B$ does not have the capability to perform the requested search, but is aware of a super-node $B'$ that does have searching capabilities. $B$ has two options at this point: return a description of $B'$, or forward $D_r$ to $B'$. Since the method of executing the first option is obvious, consider the second option. $B$ forwards $D_r$ to $B'$, and $A$ waits for a response. $B'$ performs the search, constructing the set $R = \{D_{r'} \mid r'$ matches the search criteria of $r \}$. $B'$ attaches the identifier from $D_r$ to $R$ and then sends it to the return address found in $D_r$. $A$ receives $R$. By examining the identifier, $A$ knows $R$ is a response to $D_r$. In addition, $B'$ might forward $A$'s search request on to other indexing nodes. Thus, $A$ might receive multiple responses to $D_r$ and could track them all by their common identifier. As another example, we might think of an indexing node $B$ sending requests to non-indexing nodes to collect data about their resources. In this case, resource $r$ would be a resource list. $B$ might send $D_r$ to $A$, and $A$ might return its resource list as well as forward $D_r$ to the resource hosts that it knows about. In this case, $B$ might receive responses to $D_r$ from many different hosts, but all responses will contain an identifier that $B$ can recognize. Thus, $B$ can collect a substantial index of resources in the network simply by sending out a single request. $B$ might have a limit on its index size, so it might send out $D_r$ to various hosts until it builds a large enough index and then discard further responses. $B$ could update its index in the future by sending out a new $D_r$ with a different identifier. Because response option \ref{response:inform} and response option \ref{response:forward} are equally powerful, we can ignore option \ref{response:inform} in our further discussions. We choose to ignore \ref{response:inform} because we are primarily interested in the work distribution possible with forwarding networks. However, we should note that using option \ref{response:inform} wisely can result in drastic savings in terms of the number of network transmissions sent. For example, if only forwarding is used, the following situation might arise. Consider the host set $\{A, B, C, D\}$, and suppose that the only indexing node is $D$. Let $K$ be a binary knowledge relation such that $(X,Y)\in K \Rightarrow$ ``$X$ knows about $Y$''. In our system, assume $K=\{ (A,B), (B,C), (C,D) \}$. Suppose $A$ needs a search result set $r$. $A$ can only send $D_r$ to $B$. $B$ forwards the request to $C$, and $C$ forwards to $D$. $D$ fills the request and sends the results back to $A$ via the return address in $D_r$. When $A$ needs to search again, the same transmission process occurs, resulting in 4 transmissions for each search requested by $A$. By using response option \ref{response:inform}, $C$ might inform $A$ about $D$. Thus, $A$'s first search would require 5 transmissions, but each additional search would require only 2 transmissions. Even if response option \ref{response:inform} was used by $B$ during $A$'s first search to inform $A$ about $C$, $A$'s first search would only require 6 transmissions. For a set of hosts $S$ such that $|S|=n$ and for an arbitrary knowledge relation $K_s$, if $(X,Y)$ is in the transitive closure of $K$, then the worst case number of transmissions for each request fulfilled by $Y$ for $X$ is $O(n)$ if only forwarding is used. If the informing response option is always used along with forwarding, we have $2(n-1)$ transmissions in the worst case for the initial request, and $2$ transmissions for each subsequent request. For $O(n)$ requests, we execute $O(1)$ amortized transmissions per request. \end{document} gravitation-3+dfsg1.orig/minorGems/protocol/p2p/genericProtocol.txt0000644000175000017500000000403010762704567024354 0ustar pabspabsGeneric peer-to-peer protocol. White space: All white space is equivalent (tabs, line breaks, spaces, etc.) Two types of commands, GET and PUT. Command form: GET return_address id_number resource_descriptor PUT id_number resource return_address = {xxx.xxx.xxx.xxx | hostname}:port_number resource_descriptor = resource_type [description] description = resource specific description data may be optional for certain resource types resource = resource_type resource_data A PUT command corresponding to a GET command (in other words, a put command sharing the same ID as the GET command) can be of one of three types: 1. A resource matching the resource descriptor specified by the GET command. 2. A GET_REQUEST_FAILURE resource. 3. A MORE_KNOWLEDGEABLE_HOSTS resource. Examples: See resourceSpecifications.txt for information about the resource types used in these examples. A GET request for a server list: GET myhost.mydomain.com:5157 1 SERVER_LIST The corresponding PUT command: PUT 1 SERVER_LIST 3 server1.domain1.com:5157 server2.domain2.com:5157 server3.domain3.com:5157 A GET request for a search: GET myhost.mydomain.com:5157 2 SEARCH 1 FILE 3 termA termB termC A PUT command from a successful search: PUT 2 SEARCH 2 FILE filehost1.domain1.com:5157 c:/files/termAtermBtermC.txt FILE filehost2.domain2.com:5157 /home/john/myfiles/termAtermBtermC.txt A PUT command for a failed search: PUT 2 GET_REQUEST_FAILED SEARCH 1 FILE 3 termA termB termC A PUT command informing us of a more knowledgeable search host: PUT 2 MORE_KNOWLEDGEABLE_HOSTS 1 searchhost.domain.com:5157 We can request more knowlegeable hosts explicitly: GET myhost.mydomain.com:5157 3 MORE_KNOWLEDGEABLE_HOSTS SEARCH 1 FILE 3 termA termB termC The corresponding PUT command: PUT 3 MORE_KNOWLEDGEABLE_HOSTS 1 searchhost.domain.com:5157 A GET request for a file GET myhost.mydomain.com:5157 4 FILE filehost1.domain1.com:5157 c:/files/termAtermBtermC.txt The corresponding PUT command: PUT 4 FILE c:/files/termAtermBtermC.txt 19 ###this is a text file gravitation-3+dfsg1.orig/minorGems/protocol/p2p/resourceSpecifications.txt0000644000175000017500000000231510762704567025735 0ustar pabspabsThis file contains specifications for resource types. For each type, we give a specification for the resource descriptor and then the resource. Newlines in this specification can be replaced by any kind of white space. GET_REQUEST_FAILURE [no description] GET_REQUEST_FAILURE resource_descriptor (Note that a GET_REQUEST_FAILURE resource contains the descriptor from the failed request. The PUT request for a GET_REQUEST_FAILURE resource should use the ID number from the original resource request.) MORE_KNOWLEGEABLE_HOSTS resource_descriptor MORE_KNOWLEDGEABLE_HOSTS num_hosts address_1:port_1 address_2:port_2 ... address_N:port_N SERVER_LIST [no description] SERVER_LIST num_servers address_1:port_1 address_2:port_2 ... address_N:port_N SEARCH num_allowed_resource_types allowed_type_1 allowed_type_2 ... allowed_type_N num_search_terms search_term_1 search_term_2 ... search_term_N SEARCH num_results result_descriptor_1 result_descriptor_2 ... result_descriptor_N FILE host_address:host_port file_path FILE file_path file_length_bytes ###file_data (Note that for the FILE type, the ### must occur immediately before the file data (no whitespace must separate ### from the start of the file). gravitation-3+dfsg1.orig/minorGems/protocol/p2p/anonymousPublishing.txt0000644000175000017500000001457310762704567025310 0ustar pabspabsNovember 8, 2002 Ideas for low-overhead anonymous publishing. Freenet problem: In a system where a data retrieval can take up to 10 network hops, redirects are rediculous (10 hops to find the pointer file, 10 more hops to find the actual data). In Freenet, since SSKs are common, redirects are used for almost every piece of data in the system. From the start, the network should be designed to handle the most common usage scenareo (fetching the latest version of an anonymous author's content), not to handle all sorts of other possible scenareos. The goal of such a system should be usable anonymous publication and retrieval. We should not focus (as Freenet does) on side issues such as retrieval of past document versions or elimination of data redundancy. Simplest solution: Sign(K,D) signs data D with key K. Encr(K,D) encrypts data D with key K. Hash(D) produces a fixed-length hash of data D. A | B concatonates A and B. An anonymous author generates a private key R and a public key U. The author wants to post a subspace file "index.html", with content C and timestamp T. The author generates a random symmetric key K. The author generates the following pointer URL: K/U/index.html The author generates the following insertion data: T | Encr(K,C) | Sign( U, T | Encr(K,C) ) The author generates the following insertion URL: U/index.html Problems: U, the author's public key, is visible in the insertion URL. Thus, nodes can selectively block particular authors. The second problem is that the "file name" is visible in the insertion URL, allowing nodes to selectively block certain files. What if the insertion URL looks like this: Hash(U) + Hash("index.html") Problem: There is no way for storage nodes to verify that the inserted data actually matches the insertion URL. We have several reasons for assuming that we have one priv/pub key pair per author: 1. This allows authors to build an anonymous publishing identity and repuation, since all URLs that contain a particular U certainly correspond to data posted by a particular author. 2. Generating priv/pub key pairs is computationally expensive, so we want to do this as infrequently as possible. 3. Authors only need to manage one priv/pub key pair to publish in the network. Thus, given all of the assumptions and issues raised above, we can see why the Freenet paradigm uses redirects. However, we should note the following points about this paradigm: 1. Using redirects *doubles* data fetch time in the worst case. 2. Generating key pairs, though expensive, only takes a few seconds on modern computing hardware. 3. Freenet data fetch times, in practice, are take tens of seconds. 4. Each data post operation may be followed by many fetch operations for that data. 5. Readers, in general, do not compare the public keys in a URLs to judge whether or not two pieces of content were posted by the same author. They generally look at whether or not the two content "links" were grouped together on the same "homepage". I.e., they assume that all data grouped together into a "freesite" was posted by one author. (This is a fair assumption to make, since only one author posted the main page of the freesite, so it is safe to assume that the author chose to group the content links together.) Dropping the assumtions about keys stated earlier, we can devise a publishing mechanism with better properties: An anonymous author wants to post a new file "index.html", with content C and timestamp T. The author generates a new private key R and a public key U. The author generates a random symmetric key K. The author generates the following pointer URL: K/U The author generates the following insertion data: T | Encr(K,C) | Sign( U, T | Encr(K,C) ) The author generates the following insertion URL: U Whenever the author wants to post an updated version of this file, s/he uses the same R/U pair, inserting new content C' with a new timestamp T'. Storage nodes can check timestamps for key collisions and keep only the latest version of a content unit. This scheme has the following properties: 1. Storage nodes can verify that content matches a key by checking the signature included with the content. 2. Storage nodes can obtain a secure timestamp for each unit of content. 3. Storage nodes do not have access to unencrypted content. 4. Storage nodes cannot tie a piece of content to any particular author. 3. Readers, using the K/U URL form, can fetch the content (using U), verify its signature and timestamp, and decrypt it (using K). We might observe that, with this scheme, readers have lost the ability to associate a collection of content with a particular author, since each unit of content is signed with a different private key. However, we propose the following simple solution to this problem: Authors can insert a "collection" document with links to all of their work. This is similar to a homepage on the web. Since an author can securely update and maintain their collection document, readers can be sure that all of the work pointed to by the collection document was actually collected by the same author. Note that with *any* scheme, there is no way to guarentee authorship, so nothing really is lost here. With Freenet, all we can know for sure is that the same person *posted* each of a particular series of documents. In our system, we know for sure only that the same person *linked to* each of a particular series of documents. Since there is nothing all that sacred about posting a document, we claim that nothing sacred is lost. However, for each document posted, a new priv/pub key pair must be generated. This can be computationally expensive and time-consuming for a poster. To deal with this issue, each node can build a collection of fresh priv/pub key pairs using spare computation cycles (or a thread with low priority) so that fresh keys are ready whenever an author wishes to publish new content. We should note the following trade-offs: We gain: The ability to publish and retrieve content securely and anonymously without using redirects, while still allowing for reputation building and anonymous identity. We lose: The ability to factor redundant content out of the network. However, the only want to factor redundant content out of the network while still allowing for high-level pointers to content is by using redirects (a high-level pointer that redirects you to a low-level, content hash key).