0  0 H@@HHam;]o66o;]yy8@a4
P         2TvͫgE#2Tv2Tv        ͛F#  2d                                   /./"ݼݽ>3##>,3"333#32=32"3323"#<uvgweuvgwfgvv#bsr<s-33""23#=""D4L4DD4K4KDCCDCDLDDCD4DCKDCL4ݾͽ=뾾===33$##C4##2##3B##"C32#B4"#3$#"3##2CVuFWfvwedgUuwffuVeWfWwuGegfUvUfVݽ|7>srg->L>=~<<=#޻2"";#>;<̻Mݻ۽K˼K̽̚Ϋ̼ڭȭވ̜ͪ޵wg}^gVDDD4D4DDC33333344DDDDD4D34333334333#3#32"""""!##33313#3"#"""""#3D4333"3"D433333"""3#""""3#"""""[flw[lf}w}w~}~w7s3#CDD#C3##C3$sCC$sC""s737s"www<ܼܼܼ<"KDDKLKKLLKMLLKDLLKDDDɩfkwVWvugUk[[[elUvWg[uew[f""""2!2!".""2"""!"Vu6WfvwecgUuwffuVeWfWwu7egfUvUfV"!!411CC==>=>433CCDD3-=.>    #-C;      321#3!,A3#1#2
 
                             P ```       
  J
   
p p`WPwv      D  @C  @    g eP v     "   B    `p   v` Vp Pp u                        PP pp                          p  `                           e                  P` `` `` pp                         pvg `                  `   ` V ee         P T P` P` `` `gwg            ` ```f``pvg `              `  p `vfV`e`eV @ @@ DD@T@PdUP`Vee egwg` ```f``gp `  P @@4343          pf pv  ` fpgV`e`eV `````'U "#        0# PPvPvPWPPWPpWPpvPvPPe   Vf`w `@t7C"##CC##CC##022!22#"(!""*2#2!3#9""                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                "##2D$$B""##22"#DD+"2#""$22;"#        ""##22"#DD+"2#""$22;"#                #DD+"2#""$22;"#                        "$22;"#432CCBC2#A#1CDC$3C3#CBC"#A#1>4   C         $   #   "   1   4                0  0  @  0       @          0            @     "   1  3             @    "     3                     <    L   ˬ   <  < ""*""+"̻         4 @+";"#"##22"##""        @3 " 2""##22"""!                                                                                                                >34332$#324#4B4CDC3C4CC34"C3$#3   4   $   4   4   3         30  0  0$""@33$@30C0 30 3 $"""@423   4   @   3   C  2  """B3#CC      3   4  0#    0   4D0   DC   04D0  0DC    @   4  D  @"""@"""0$2C@   @  C C 4""3C4  @#2"20"2"0"#" #"" 0"!  !  "   """!  !"   "        DD4343""443###3""""33#######DݚݚKݚKݪ̚DDĚĚ̚̚ܚ """!233!333!233"""     """"333333333333""""     """33#33333#"""          뺪                      ˼̼        

        

            
	           
                      ߰#""222233#"""22""""!LݙLݙLݩLݩL̩ܩ܊۩ۉۉۉݙ                     "!"!!"""  !         !"!"                  LD<< ܍                      ̼K44;4444L<<      ,     DD  DD www}w     ff    vw  vv  `e  df ffV                  Pe  [U ef PfQ Vfe VUU Vff pwwf  Uu  ff e fVv UUv ffv ww                       ϻ                            ˻         $"B03# # 03#  3""                                                                                                                                                                                                                             wwwwDwwDDwwDDD        F"ff U  U 'b  ebPPw  VW  f                  @          0           w  @w          0     2#  2# ""+"+"               ˻ ˻        ""  ""  " " +"      "" """"+ 3                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      3"0!!" / #  !  !  23/!/                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       2B  #$ @" "        @#$! B  1 0   3 4  s 2     0   !`#PG1$ 3 0  $           u# @  # 00  $             0    2  #  2    4     2   B   2     0 -    #@#               # @ #                 *   !    *    !  1  !          0            !   0            L  L  B  &   !   D L    !  1  @!       @  L D0          d  !   0              DD3A4#sA3#4#r$" 1r    . .    KKLAM A       	ɫ   `  [u evPV\V[fveUv`Wf fv             eP    e  `p P f ` `ff 3f 4"w@3" 03 #"  "       P   C P T       4Pd `  @@  D0 40DPCCP05DPE eF e     @433#4Sw#3w6#033 #"  w   @3"@42 42  @  `# `7B  # @     4  $  2        e  p  r"  +" "" ""    "  ++"+"""" ""                 ; @;43+433#333"0""     "b  Cv243#$CC!"""B   03  >>3.333 3  ?               D @KD@DD@DD 44                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              #"  C#  @           """"233# @     22            0   0 L#"<$"=  @ #2  11  1!  C#  /  ?#  D2  #D                                                                                                      ""  !"!""""            ̻̻ݻ         K4 D304;044044 CC  0 ޼  ؼ  K34ҼB"                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            ""                3  0  $      3      3   3 @ $      3     2  03 @# $      3   3  "3                 ;        4  @3            ;                      ;                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   .""                        "                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              ~kZZmUZJJ	$$ۺOZ(    @  	) $   B  A                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    QRSRQRQRS                                                                                                                                                                                                                                    PPPPPP                                                                                                                                                                                                                                  PPPP                                                                                                                                                                                                                                 PP                                                                                                                                                                                   PP                                                                                                                                                                                                             PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                                                            PP                                                                                                                                                                                                            				                            PP                                                                                                                                                                                                           						                           PP                                                                                                                                                                                                           							                          PP                    000                                                                                                                                                                    			             							                          PP                   00000                                                                                                                                                                  					             					                          PP                   00000                                                                                                                                                                  					               		                          KPP   			            0000000                                                                                                                                                                							                                       JHPP   				           000000                                                                                                                                                                							            L                        HIPP  					 			        0000                                                                                                                                                                 						            L                       K PPI 				 			                                                                                                                                                                               		     L        LL HK                HHJ   PP  	  				 			                                                                                                                                                                                  L        LL /JHJ               SRQPPHH   							                                                                                                                                                                                  L        KHJ         SRQPPPPK     					                                                                                                                                                                           HK H HQRPQRPRQHJJIJ     !!/IH   				                                                                                                                                                                      KJ K H/PPPPPJ   !!!!   	                                                                                                                                                                        PPP!!!!!!!!!

/J                                                                                                                                                                          !!!!!!!


IH      	                                                                                                                                                                 !!!!!!

/IK   			                                                                                                                                                        !!!   


J 					  	                                                                                                                                                    














!     

  		  			                                                                                                                                                   







     H     			                                                                                                                                                   

    

     

IIHI I                                                                                                                                                    

              




/                                                                                                                                                                      




/JIIHK                                                                                                                                                                  


!!!                                                                                                                                          no                     


!!!!!!                                                                                                                                         ~                                



!!!!!!                                                                                                                                                                     

!!!!!!                                                                                                                                   

                               !!!!!!                                                                                                                              

                             





                                                                                                                              
                        



                                                                                                                              
            



                                                                                                                                
                                                                                                                                                              

                                                                                                                                                                    


                                                                                                                                                                                                                                                                                                                                               TTTTTTTTTTTT                                                                                                                                                       TTTTTTTTT                                                                                                                                                       TTT                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                ǲ                                                                                                                                                                                                                  ȸ                                                                                                                                                                                                                  ᱱ                                                                                                                                                                                                                  񱱱                                                                                                                                                                                                                                                                                                                                                                                                                                    ˣ                                                                                                                                                                                                                  񣤥                                                                                                                                                                                                                  ᳴                                                                                                                                                                                                                  ų                                                                                                                                                                                                                  ᣤ                                                                                                                                                                                                                  񳴵                                                                                                                                                                                                                  ų                                                                                                                                                                                                                  񣤥                                                                                                                                                                                                                  ᳴                                                                                                                                                                                                                 Ų                                                                                                                                                                                                                	| ^\_U[Y_bX U@_p\0X@_[@T _ ZPV_0ZTP_[W`_YT _ ZU _ ?p   $68F	Xfdbd    PPcPcQbCVEEDCDVXZ\]\\[Z]]]\Z\_____     NJFA@EHLNNOO N KJIILLNNNOOO O O O O O |    PQS	X,YZ\\\\O\?]/^/___ _ _ _ _ _ _ _ _ _ _ _ _ _ _      PUZ	],______O_?_/_/___ _ _ _ _ _ _ _ _ _ _ _ _ _ _         @p                       =                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     @PA`CwFwHJA0B@CWFWI_K_BB E7G7I?J?K KL'LL/LLMMM MM k6   @       @	 @    @          @    @   	 @ @   `3                                                 /                                                                                                                                                                              ? ꪪWffwwfvVWffwWffwwfvVVeWfwfvVWffwfuVgVeWfꪪWUvFުeguWWUvFWUv1#"3#12323#3#1!3#12323#3#113VwgfevUvVwgfVwg!//!!//!!"2udWeڪud/v!_/!oeV!o/!"VA^u6򯪪/"""a"""""""]UUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUv7񪪯!"!!"!!"!a!"!!"!!"!!"!!"!!"!!"!ffffffffffffffffffffffffffffffffffffffg5򪪪!""!""!""q!""!""!""!""!""!""!""mfffffffffffffffffffffffffffffffffffff򯪪"""V"""""""}wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww^e"j/!!!Ww!A!!ᩪ!!!!Ww!ffegUeg6񪪪jjfffީvUfVޭvU򪪪jfffjfj/efUgVuFWVuFWޭewFUVgGfef%ffffffjfUfvVfvwefvweުWUvegUgVUf6ffffffjfDD433"""GDD33#""RDD433"""IDD33#""DD433"""NDD33#""rGDD33#""DD433"""tW7򪪪fffcffff/43"""33#F3#""233b43"""33#J3#""23343"""33#N3#""233rG3#""23343"""33#fu6!ffjcffff4#F=R4#I=4#N=r̚E=4#Wf!jjjffffcff4    #F     =r4    #J     =4  #N=b   G=4#WU6񪪪jfffjfc3#7@DK=b3DDD4#9332=3w#>=b`#7   =3#Vw򪪪jfjfczj/# 4#7@CDD=b#D4DD#: <=#  #>=b`7B4pP=##ud'ff7s#  #6°DD=R#C333#90#23=##>=RK #< g =##>jfffz33# 2#604D4>r#3334#: =3<>##>>bK@ ܚ< '>##>򪪪jfffJD7#3srzwwb/# 5@LD>q#4DDD903->#@3">>qL ܊9">#>!jffff$"zw3#233"33s'" B 2'@S"DD4?*0=#/"@42?..c 4 *"""2!ffffJ,"LJww733,33"333"  &0a"343)03#" 42..a$)""">wjcfc,""w3s3"3<3"23322  %@q2333* 22@..a2 ݿ* !2w3#*jc," w333#"3"""""/2 % a2   -    2  ..Q )  2.?33#rCq73333#""""""2ffffff/&R2/.2/..Rݿ)2">/23#"wwrJ7w3333<,","""g233#"""&33A233#".333"233#".333""""ᩪ)333"233#""">"3#"zw3'swz3"233"./U"""2!&""a"""2.""""""2."""ᙙ)""""""2!>!/<3#"""3s2373""WvVuWvVteufdgUuuWvVteuf!33"2333333"""gfwegfwveWfwffuegfwveWf>,333,2333"""uVgfuVgwfvVVeWffuVgwfvV,,2/WVGfWVGeguWWwuGfWVGeguW.,,gUuVgUuevUvegfUVgUuevUvޙ>dwVUdwVftvevUfVUdwVftve>/gGfefUgefUgefUgewFUVuFWDDD4DDD4DDD4>!UgVUfvVUfvVUfvVWUvefvweD4DDD4DDD4DD.WvVtWwutWwutWwuteufdgUuC333C333C333.!"gfwfuVefuVefuVeveWfwffu333433343334.!/uVgWffwWffwWffwwfvVVeWf4DDD4DDD4DDD>/WVGWUvFWUvFWUvFeguWWwuGDD4DDD4DDD4D>gUuVwgfVwgfVwgfevUvegfU343334333433ޘ/dwVudWeudWeudWeftvevUfV333433343334"/"/!/"/!!fUgefUgVuFWewFUVgGfewFUefUgDDD4333#333#333#DDD4#"!//!!//!!1ufvVUfvVfvweWUvegUgVWUveUfvVD4DD3#33#33#3D4DD3231!3#1!323231!3#1!323"2aeWwutWwudgUuteufuWvVteuftWwuC3332"""2"""2"""C333ޙJ##3BwfgvwfgvwuVefuVewffuveWfegfwveWffuVe3334""!#""!#""!#3334##"Cv#bsv#bsvffwWffwVeWfwfvVfuVgwfvVWffw4DDD#333#333#3334DDD~32#Bޙr<s-r<s-rUvFWUvFWwuGeguWfWVGeguWWUvFDD4D13#313#313#3DD4D~n4"#3Y33""33""3wgfVwgfegfUevUvVgUuevUvVwgf3433"#"""#"""#""3433ޘW$#"323#23#2dWeudWevUfVftveUdwVftveudWe3334"""#"""#"""#3334^wv##2Cnnm=""=""=wFUefUgVgGfVuFWewFUVuFWDDD4333#333#333#DDD4uvgwuvgw!uvgwuvgwuvgw>3#-2">UveUfvVgUgVfvweWUvefvweD4DD3#33#33#3D4DDޘDeuvgeuvg22#euvgeuvgeuvg#>,3#33euftWwuuWvVdgUuteufdgUuC3332"""2"""2"""C333JNCwfgvwfgv"(wfgvwfgvwfgv3"33"#3=3eWffuVeegfwwffuveWfwffu3334""!#""!#""!#3334Nv#bsv#bs!"v#bsv#bsv#bs3##=3fvVWffwfuVgVeWfwfvVVeWf4DDD#333#333#3334DDD~r<s-r<s-"*2r<s-r<s-r<s-32=2<3-3guWWUvFfWVGWwuGeguWWwuGDD4D13#313#313#3DD4D~ng33""33""#2!33""33""33""32"33"3vUvVwgfVgUuegfUevUvegfU3433"#"""#"""#""3433ޘWe23#23#3#23#23#23#33232,3tveudWeUdwVvUfVftvevUfV3334"""#"""#"""#3334^wv^v=""=""9""=""=""="""#<=23"wFUVgGfefUg$##CefUgefUg333#333#333#333#uvgwuvgw>3#-##-2"uvgw-2"232"">3#>UvegUgVUfvV4##2UfvVUfvV3#33#33#33#3,""euvgeuvg#>,3-#3#33euvg3#332==</""/""#>,eufuWvVtWwu##3BtWwutWwu2"""2"""2"""2"""᎙BBwfgvwfgv3"33233"#3=wfgv"#3=33#3"#""#"3"333eWfegfwfuVe##"CfuVefuVe""!#""!#""!#""!#ވ..v#bsv#bs3#3"#=3v#bs#=32#2/"/"3#fvVfuVgWffw32#BWffwWffw#333#333#333#333DDn~n~r<s-r<s-32=#2=#2<3-r<s-2<3-,"3>"!#"!#32=3guWfWVGWUvF4"#3WUvFWUvF13#313#313#313#3DDvnvn33""33""32"323333"333""33"333<##"#"32"vUvVgUuVwgf$#"3VwgfVwgfn"#"""#"""#"""#""wwV~V~23#23#3323#2,23#2,23<!!"!!"33233tveUdwVudWe##2CudWeudWenv"""#"""#"""#"""#w}w^~u^~u=""="""#<.#3#=23=""=23=22."">."">"#<"gGf$##Cnvw333#333#333#333#wwwwuvgwuvgw>3#-2"-##>3#232232-2"22"">3#-UgV4##2vww3#33#33#33#3DwwD"euvgeuvg#>,3#333-##>,2==<2==<3#33"""#>,WvV##3Bfwww2"""2"""2"""2"""DwwDBwfgvwfgv3"33"#3=2333"3333#333#3"#3=!""!"""2!3"332gfw##"Cnwwww""!#""!#""!#""!#DD-v#bsv#bs3##=33"3#2#22#2#=3!!!!!!2!"3#uVg32#Bvwwww#333#333#333#333n~r<s-r<s-32=2<3-#2=#32=,"3>,"3>2<3-./!"./!"."32=#WVG4"#3nwwwww13#313#313#313#3nvn33""33""32"33"3323332"33<#33<#33"3!/2!!/2!"2"32"3gUu$#"3vwwwww"#"""#"""#"""#""V~23#23#33232,#332323<23<2,""!""!""3323dwV##2Cnwwwwww"""#"""#"""#"""#u^~u=""="""#<=23.#3#"#<=22=22=23""!""#<.$##C~wwwwwwμ߽/.uvgwuvgw>3#232-##-##-2"232232-2">3#-##"//""2D4##2vwwwwww/euvgeuvg#>,2==<3-#3-#3#332==<2==<3#33#>,3-#!""/""/"""NC##3Bwwwwwwwwfgvwfgv3"3333#3233233"#3=33#333#3"#3=3"33233#"#""#"!""N##"Cwwwwwwwv#bsv#bs3#2#23"3"#=32#22#2#=33#3""/"/"!!!32#Bnwwwwwwwμ߽r3#r3#32=,"3>#2=##2=#2<3-,"3>,"3>2<3-32=#2=#1"!#"!#./!"fgf4"#3~wwwwwww332#332#32"33<#3233323333"333<#33<#33"332"3233""!#"#"!/2!ewugf$#"3vwwwwwww̽ݾ23#-23#-332323<##2,23<23<2,3323#.1"!!!"!!"""!wwvwwgf##2Cwwwwwwww̽"=2#=2#"#<=22.#3#.#3#=23=22=22=23"#<.#3##!.."">."">"vgwwwwwgf$##Cwwwwwwwwuvgw-##uvgwuvgw-##>3#>3#232-##232232>3#232""//"//uvgwwDwww4##2DnwwwwwwDweuvg3-#euvgeuvg3-##>,#>,2==<3-#2==<2==<#>,μ2==</""!""!""̼fgvwGCwwwg##3BJNC~wwwwwGCwwfgv233wfgvwfgv2333"333"3333#323333#333#33"3333#3"#"###bswGtwwww##"CN~wwwwwGtwv#bs3"v#bsv#bs3"3#3#2#23"2#22#23#2#2/"""<s-wwwvwww32#B~vwwwwwwwvr<s-#2=#r<s-r<s-#2=#32=32=,"3>#2=#,"3>,"3>32=,"3>"!#113""wvgwwwwg4"#3~ngwwwwwwvgw33""323333""33""323332"32"33<#323333<#33<#32"˾˾33<##"""!""!ݼ3#vewuwwww$#"3Wewwwwwvewu23##23#23##3323332323<#23<23<332323<!!".1"!.1"!""Wwwvwwww##2C^wv^vnwwwwwWwwv="".#3#=""="".#3#"#<"#<=22.#3#=22=22"#<ܼܼ=22ܼܼ."">#!.#!.ݽ##uvgwwwww$##Cuvgwuvgwuvgwwwwwuvgw>3#232""""//-##-##-2">3#>3#"//"3-#euvgw"ww4##2euvgeuvgeuvgwwzeuvg#>,2==<"/""!""3-#3-#3#33#>,#>,μܼ!""/""33wfgvwBrw##3BwfgvwfgvwfgvwwJzwfgv3"3333#3"2!"#"#233233"#3=3"333"33#"#"3"v#bsw'rw##"Cv#bsv#bsv#bswwwv#bs3#2#22!"/""3"3"#=33#3#޽"/"2=#r<s-gwww32#Br<s-r<s-r<s-zwwr<s-32=,"3>.""!#1#2=##2=#2<3-32=32=1"!#23333""wvgw4"#333""33""33""wg33""32"33<#"2"#"""!3233323333"332"32"˾˾ݼݼݼ˾""!#"˾#23#Vwvw$#"323#23#23#vWu23#332323<""!!".1"!##2,33233323ܼܼ.1"!!!"#3#=""Wwwu##2C=""=""=""Wvwv="""#<=22!"."">#!..#3#.#3#=23"#<"#<ݽݽݽܼܼܼܼ#!.."">2"-2"uvgw!232-2"232uvgw-##-2"-2"22""2μμ#333#33euvg22#2==<3#332==<euvg3-#3#333#33""/""/"""̼̼ܼ#3="#3=wfgv"(33#3"#3=33#3wfgv233"#3="#3=!""!"""#""#"!""#=3#=3v#bs!"2#2#=32#2v#bs3"#=3#=3!!!!!!/"/"!!!̽޽<3-2<3-r<s-"*2,"3>2<3-,"3>r<s-#2=#2<3-2<3-./!"./!""!#"!#./!"μμ3"333"333""#2!33<#33"333<#33""323333"333"3!/2!!/2!#"#"!/2!ݼ˾ݼݼ˾ݼݼ˾ݼ2,2,23#3#23<2,23<23##2,2,""!""!!!"!!"""!˼̽˼ܼ̽޼23=23=""9""=22=23=22="".#3#=23=23""."">."">"ܼܼݽݽܼܼݽݽݽܼܼݽ32>3#232-##>3#>3#-##-2"-2"2322"""222μμμμμμ==<#>,2==<3-##>,#>,3-#3#333#332==<"/""""""ܼ3#33"3333#32333"333"33233"#3="#3=33#3!"""#""2!!""!""!""#23#2#23"3#3#3"#=3#=32#2!!!/"2!"!!!!!!!!!̽޽޽̽"3>32=,"3>#2=#32=32=#2=#2<3-2<3-,"3>./!""!#."./!"./!"./!"μμμμμμ3<#32"33<#323332"32"323333"333"333<#ݼ!/2!#""2"!/2!!/2!!/2!ݼݼݼ3<332323<#33233323#2,2,23<""!!!"""""!""!""!̽޼̽̽̽̽޼˼̽22"#<=22.#3#"#<"#<.#3#=23=23=22ݽ"."">!""""ݽ̼̼ܼܼݽܼܼܼܼݽܼܼ""232232-2"232-##232-##μμμ"""//""//"//μμ"""2==<2==<3#332==<3-#2==<3-#/""/""!""/""!""!""̼̼#""2!33#333#3"#3=33#323333#3233"#""#"#"#"##"2!"2#22#2#=32#23"2#23"̽>3/""/"""!#.","3>,"3>2<3-,"3>#2=#,"3>#2=#μμμ#32#"!#1"!#11μμ#""2"33<#33<#33"333<#323333<#323332##"""!#"""!""!ݼݼ˾ݼݼݼݼ˾!!"""23<23<2,23<#23<#̽̽̽32##!!".1"!!!".1"!.1"!ܼ̽޼̽޼ܼ"">!"=22=22=23=22.#3#=22.#3#̼ܼܼ."">."">#!.."">#!.#!.ݽݽݽݽݽݽ2"-##-##˼ܽۻ-##μμμμμμμ"/""3-#3-#߿3-#̼̼"""#"233233233!!/"3"3"3"ݽ̽/!""!##2=##2=##2=#μμμμμμμ/2!#"323332333233ݼݼ˾ݼ˾ݼ"!!!"##ܿݽ#̽̽̽޼ܼݽ˼̽̽̽޼̽޼"."">.#3#.#3#˼̼.#3#̼̼ݽݽܼܼݽ̼̼ܼܼݽ"//"μμܽμμ˼μμ!""/""ܼܼμ߿˼#"#"/"̽޽̽6 -- 0.0.08
-- title:  BitMiner
-- author: JKBYKM
-- desc:   A wip sandbox
-- script: lua

-- DEBUG
 DEBUG=false
 fpsNow=60
 fpsTick=0
 fpsFrms=0
 function updFps()
  fpsFrms=fpsFrms+1
  local t=time()
  if t-fpsTick>=1000 then
   fpsNow=fpsFrms
   fpsFrms=0
   fpsTick=t
  end
 end
 function dbgCtx(ctx,x,y)
  print("t"..ctx.tile.." w"..ctx.wall,x,y,12,true,1,true)
  print("tu"..ctx.tileAdj.up.." td"..ctx.tileAdj.down,x,y+8,12,true,1,true)
  print("tl"..ctx.tileAdj.left.." tr"..ctx.tileAdj.right,x,y+16,12,true,1,true)
  print("wu"..ctx.wallAdj.up.." wd"..ctx.wallAdj.down,x,y+24,12,true,1,true)
  print("wl"..ctx.wallAdj.left.." wr"..ctx.wallAdj.right,x,y+32,12,true,1,true)
 end
 function mouseTileCtx()
  local mt = cam:mouseTarget()
  return mt.tx,mt.ty,mt.ctx
 end
 function drawDbg()
  local stk = plr.invt[plr.selectedSlot]
  local mineProg = 0
  if not stk:isEmpty() then
    mineProg = stk.itm.progress
  end
  local tx,ty,ctx = mouseTileCtx()
  print("tx:"..tx.." ty:"..ty,140,80,12,true,1,true)
  dbgCtx(ctx,140,88)
  print("mine progress:"..mineProg,2,80,12,true,1,true)
  print("x:"..plr.x.." y:"..plr.y,2,88,12,true,1,true)
  print("vx:"..fmt(plr.vx).." vy:"..fmt(plr.vy),2,96,12,true,1,true)
  print("g:"..tostring(plr.on_ground).." j:"..tostring(plr.jumping),2,104,12,true,1,true)
  print("m:"..plr.medium.." ff:"..tostring(plr.feet_fluid).." ef:"..tostring(plr.eyes_fluid),2,112,12,true,1,true)
  print("hp:"..plr.hp.." st:"..flr(plr.stamina).." o2:"..plr.o2,2,120,12,true,1,true)
  print("fps:"..fpsNow,2,128,11,true,1,true)
 end
--

-- Math
 max=math.max
 min=math.min
 rnd=math.random
 flr=math.floor
 function round(n)return flr(n+.5)end
 function snap(a,b,c)if math.abs(a-b)<c then return b else return a end end
 function fmt(n)return string.format("%8.4f",n)end
 function clamp(v,a,b) return min(max(v,a),b) end
 function lerp(a,b,t)return a+(b-a)*t end
 function wrap(v,m)local r=v%m if r<0 then r=r+m end return r end
--

-- BACKGROUND
 farBase=45
 farAmp=85
 farSmth=7
 nearBase=88
 nearAmp=53
 nearSmth=13
 cldCnt=6
 mtnW=512
 cldW=480
 farPar=.18
 nearPar=.45
 farMtn={}
 nearMtn={}
 clouds={}
 function drawSky()
  for y=0,scrH-1 do
   local t=y/(scrH-1)
   local a,b,k
   if t<.25 then
    a,b,k=10,9,t/.25
   elseif t<.65 then
    a,b,k=9,8,(t-.25)/.40
   else
    a,b,k=8,15,(t-.65)/.35
   end
   line(0,y,scrW-1,y,a)
   local off=(y%2)*2
   if k>.15 then
    for x=off,scrW-1,4 do pix(x,y,b) end
   end
   if k>.45 then
    for x=off+1,scrW-1,4 do pix(x,y,b) end
   end
   if k>.75 then
    for x=off+2,scrW-1,4 do pix(x,y,b) end
   end
  end
 end
 function mkMtn(base,amp,smth)
  local arr={}
  local y=base
  local targ=base
  for x=0,mtnW-1 do
   if x%smth==0 then targ=base+rnd(-amp,amp) end
   y=lerp(y,targ,.06)
   arr[x]=y
  end
  for x=0,mtnW-1 do
   arr[x]=arr[x]+math.sin(x*.015)*10+math.sin(x*.037+1.7)*6
  end
  local blend=64
  local startY=arr[0]
  for i=0,blend-1 do
   local x=mtnW-blend+i
   local t=i/(blend-1)
   local s=t*t*(3-2*t)
   arr[x]=lerp(arr[x],startY,s)
  end
  for x=1,mtnW-2 do
   local a,b,c=arr[x-1],arr[x],arr[x+1]
   if b<a and b<c then arr[x]=b-2 end
  end
  for x=0,mtnW-1 do arr[x]=flr(arr[x]) end
  return arr
 end
 function initCld()
  clouds={}
  for i=1,cldCnt do
   local dep=rnd()
   clouds[i]={
    x=rnd()*cldW,
    y=flr(6+(1-dep)*18+rnd(0,16)),
    s=(10+rnd()*12)*(.72+dep*.58),
    spd=.03+dep*.18,
    dep=dep,
    wob=rnd()*6.28318
   }
  end
 end
 function initBg()
  farMtn=mkMtn(farBase,farAmp,farSmth)
  nearMtn=mkMtn(nearBase,nearAmp,nearSmth)
  initCld()
 end
 function drawMtn(arr,edgeCol,fillCol,camX,par)
  for x=0,scrW-1 do
   local sx=wrap(x+flr(camX*par),mtnW)
   local y=arr[sx]
   pix(x,y,edgeCol)
   line(x,y+1,x,scrH-1,fillCol)
  end
 end
 function drawCld(cld,drawX,t)
  local y=cld.y
  local s=cld.s
  local puffCol,shadeCol=11,12
  if cld.dep<.33 then puffCol,shadeCol=12,11 end
  circ(drawX-s*.28,y,s*.20,puffCol)
  circ(drawX,y-1,s*.28,puffCol)
  circ(drawX+s*.30,y,s*.18,puffCol)
  elli(drawX,y+s*.10,s*.72,s*.14,shadeCol)
 end
 function drawClds(camX,t,minDep,maxDep)
  for i=1,#clouds do
   local cld=clouds[i]
   if cld.dep>=minDep and cld.dep<maxDep then
    local par=.10+cld.dep*.35
    local x=wrap(cld.x-camX*par+t*cld.spd,cldW)-40
    drawCld(cld,x,t)
    drawCld(cld,x-cldW,t)
    drawCld(cld,x+cldW,t)
   end
  end
 end
 function drawBg(camX)
  local t=time()/16
  drawSky()
  drawClds(camX,t,0,.20)
  drawMtn(farMtn,13,14,camX,farPar)
  drawClds(camX,t,.20,.70)
  drawMtn(nearMtn,6,7,camX,nearPar)
  drawClds(camX,t,.70,1.01)
 end
--

-- NOISE
 Noise={}
 function Noise.lerp(a,b,t)return a+(b-a)*t end
 function Noise.smooth(t)return t*t*(3-2*t)end
 function Noise.newBuff(w,h,fill)
  local b={}
  fill=fill or 0
  for x=0,w do
   b[x]={}
   for y=0,h do
    b[x][y]=fill
   end
  end
  return{w=w,h=h,b=b}
 end
 function Noise.newRandBuff(w,h,amp)
  local b={}
  amp=amp or 1
  for x=0,w do
   b[x]={}
   for y=0,h do
    b[x][y]=rnd()*amp
   end
  end
  return{w=w,h=h,b=b}
 end
 function Noise.get(n,x,y)
  if x<0 then x=0 elseif x>n.w then x=n.w end
  if y<0 then y=0 elseif y>n.h then y=n.h end
  return n.b[x][y]
 end
 function Noise.sampleLayer(n,x,y,outW,outH)
  local fx=x*n.w/outW
  local fy=y*n.h/outH
  local x0=flr(fx)
  local y0=flr(fy)
  local x1=x0+1
  local y1=y0+1
  local tx=Noise.smooth(fx-x0)
  local ty=Noise.smooth(fy-y0)
  local v00=Noise.get(n,x0,y0)
  local v10=Noise.get(n,x1,y0)
  local v01=Noise.get(n,x0,y1)
  local v11=Noise.get(n,x1,y1)
  local a=Noise.lerp(v00,v10,tx)
  local b=Noise.lerp(v01,v11,tx)
  return Noise.lerp(a,b,ty)
 end
 function Noise.new(w,h,scale,octaves,persistence,lacunarity)
  local n={}
  n.w=w
  n.h=h
  n.scale=scale or 8
  n.octaves=octaves or 4
  n.persistence=persistence or .5
  n.lacunarity=lacunarity or 2
  n.layers={}
  n.maxVal=0
  local amp=1
  local freq=1
  local m=max(w,h)
  local nw=w/m
  local nh=h/m
  for i=1,n.octaves do
   local lw=max(2,flr(nw*n.scale*freq))
   local lh=max(2,flr(nh*n.scale*freq))
   n.layers[i]=Noise.newRandBuff(lw,lh,amp)
   n.maxVal=n.maxVal+amp
   amp=amp*n.persistence
   freq=freq*n.lacunarity
  end
  function n:sample(x,y)
   local v=0
   for i=1,#self.layers do
    v=v+Noise.sampleLayer(self.layers[i],x,y,self.w,self.h)
   end
   return v/self.maxVal
  end
  return n
 end
--

-- WORLD GEN
 function fillWorldWalls(surface)
  for x=0,WORLD_W do for y=0,WORLD_H do
    if y>=surface[x] + 7 then
     setLyrId(wallLyr,x,y,32)
    elseif y>=surface[x] + 1 then
     setLyrId(wallLyr,x,y,33)
    else
     setLyrId(wallLyr,x,y,0)
    end
  end end
 end
 function clearWorldTiles()
  for x=0,WORLD_W do for y=0,WORLD_H do
    setLyrId(tileLyr,x,y,0)
  end end
 end
 function genSurface(heightNoise)
  local surf={}
  for x=0,WORLD_W do
   local n=heightNoise:sample(x,0)
   surf[x]=flr(38+n*22)
  end
  return surf
 end
 function genTerrain(surface)
  for x=0,WORLD_W do
   local sy=surface[x]
   for y=0,WORLD_H do
    if y<sy then
     setLyrId(tileLyr,x,y,0)
    elseif y==sy then
     setLyrId(tileLyr,x,y,4)   -- grass
    elseif y<sy+4 then
     setLyrId(tileLyr,x,y,3)   -- dirt
    else
     setLyrId(tileLyr,x,y,2)   -- stone
    end
   end
  end
 end
 function genCaves(caveNoise,surface)
  for x=0,WORLD_W do
   for y=0,WORLD_H do
    local n=caveNoise:sample(x,y)
    local thresh = .7-.2*(y-surface[x])/(WORLD_H - surface[x])
    if n>thresh then
     setLyrId(tileLyr,x,y,0)
    end
   end
  end
 end
 function genOre(oreNoise,tileId,replaceId,threshold,minDepth)
  for x=0,WORLD_W do
   for y=minDepth,WORLD_H do
    if getLyrId(tileLyr,x,y)==replaceId then
     if oreNoise:sample(x,y)>threshold then
      setLyrId(tileLyr,x,y,tileId)
     end
    end
   end
  end
 end
 function blobFunc(x, y) return (y+2-2*math.sqrt(y*y+1))*(math.sqrt((y-1)*(y-1)+1)-y/2)-x*x end
 function leafBlob(cx, cy, k)
  local radius = math.ceil(3*k)
  for dx = -radius, radius do
   for dy = -radius, radius do
    local sx = flr(dx+0.5)/k
    local sy = flr(dy+0.5)/k
    if blobFunc(sx, -sy)+.1*rnd() > 0 then
     local tx = cx+dx
     local ty = cy+dy
     if getLyrId(tileLyr,tx,ty) == 0 then
      setLyrId(tileLyr,tx,ty,9)
     end
    end
   end
  end
 end
 function genTree(tx, ty)
  local height = rnd(3, 5)
  local topY = ty - height
  setLyrId(tileLyr,tx,ty,60)
  -- trunk
  for i = 1, height do
   setLyrId(tileLyr,tx,ty-i,8)
  end
  leafBlob(tx,topY+1,height+1)
  return true
 end
 function genTallGrass(tx, ty)
  for x=-5,5 do for y=-2,2 do 
   if getLyrId(tileLyr,tx+x,ty+y)==0 and getLyrId(tileLyr,tx+x,ty+y+1)==4 and rnd()<.7 then setLyrId(tileLyr,tx+x,ty+y,40 + rnd(4)) end
  end end
 end
 function genSurfObj(surface, obj, tile,  space, p)
  for x=4,WORLD_W-4 do
   local y=surface[x]
   if getLyrId(tileLyr,x,y)==tile and rnd()<p and x%space == 0 then
    if getLyrId(tileLyr,x,y-1)==0 then
     obj(x,y)
    end
   end
  end
 end
 function findSpawn(surface)
  local x=WORLD_W//2
  local y=surface[x]
  for _=1,20 do
   if getLyrId(tileLyr, x, y) == 4 then
    return x*8,y*8-16
   end
   x=x+rnd(-10,10)
   y=surface[x]
  end
 end
 function genWorld()
  clearWorldTiles()
  local heightNoise=Noise.new(WORLD_W,WORLD_H,12,4,.5,2)
  local caveNoise  =Noise.new(WORLD_W,WORLD_H,70,2,.3,1.3)
  local coalNoise  =Noise.new(WORLD_W,WORLD_H,100,1,.5,2)
  local ironNoise=Noise.new(WORLD_W,WORLD_H,100,3,.9,2)
  local gemNoise   =Noise.new(WORLD_W,WORLD_H,10,2,.5,2)
  local surface=genSurface(heightNoise)
  genTerrain(surface)
  genCaves(caveNoise,surface)
  fillWorldWalls(surface)
  genOre(coalNoise,10,2,.8,50)   -- coal in stone
  genOre(ironNoise,12,2,.75,70) -- iron
  genOre(gemNoise,14,2,.9,60)    -- sapphire-ish
  genSurfObj(surface,genTree,4,4,.3)
  genSurfObj(surface,genTallGrass,4,15,1)
  local sx,sy=findSpawn(surface)
  plr.x=sx
  plr.y=sy
 end
--

-- WORLD
 WORLD_H=135
 WORLD_W=239

 mineCrkTx=nil
 mineCrkTy=nil
 mineCrkLvl=0

 function newWorldLyr(defaultId, boundsId)
  return {
   defaultId=defaultId or 0,
   boundsId=boundsId or 1,
   ids={},
   data={},
   states={}
  }
 end

 function initWorldLyr(lyr)
  for x=0,WORLD_W do
   lyr.ids[x]={}
   lyr.data[x]={}
   lyr.states[x]={}
   for y=0,WORLD_H do
    local id=lyr.defaultId
    lyr.ids[x][y]=id
    lyr.data[x][y]={rot=rnd(0,3)}
    lyr.states[x][y]=nil
   end
  end
 end

 function lyrInBounds(tx,ty)
  return tx>=0 and ty>=0 and tx<=WORLD_W and ty<=WORLD_H
 end

 function getLyrId(lyr,tx,ty)
  if not lyrInBounds(tx,ty) then return lyr.boundsId end
  if not lyr.ids[tx] then return lyr.defaultId end
  return lyr.ids[tx][ty] or lyr.defaultId
 end

 function setLyrId(lyr,tx,ty,id)
  if not lyrInBounds(tx,ty) then return end
  if not lyr.ids[tx] then
   lyr.ids[tx]={}
   lyr.data[tx]={}
   lyr.states[tx]={}
  end
  lyr.ids[tx][ty]=id or lyr.defaultId
  lyr.data[tx][ty]={rot=rnd(0,3)}
  lyr.states[tx][ty]=nil
  if lyr.writeFn then lyr.writeFn(tx,ty,lyr.ids[tx][ty]) end
 end

 function getLyrData(lyr,tx,ty)
  if not lyrInBounds(tx,ty) then return nil end
  if not lyr.data[tx] then return nil end
  return lyr.data[tx][ty]
 end

 function setLyrData(lyr,tx,ty,data)
  if not lyrInBounds(tx,ty) then return end
  if not lyr.data[tx] then lyr.data[tx]={} end
  lyr.data[tx][ty]=data
 end

 function getLyrState(lyr,tx,ty)
  if not lyrInBounds(tx,ty) then return nil end
  if not lyr.states[tx] then return nil end
  return lyr.states[tx][ty]
 end

 function setLyrState(lyr,tx,ty,state)
  if not lyrInBounds(tx,ty) then return end
  if not lyr.states[tx] then lyr.states[tx]={} end
  lyr.states[tx][ty]=state
 end
 
 function getLyrAdj(lyr, tx, ty)
   return {
     up    = getLyrId(lyr, tx, ty-1),
     down  = getLyrId(lyr, tx, ty+1),
     left  = getLyrId(lyr, tx-1, ty),
     right = getLyrId(lyr, tx+1, ty)
   }
 end

 function getTileCtx(tx, ty)
   return {
     tile = getLyrId(tileLyr, tx, ty),
     wall = getLyrId(wallLyr, tx, ty),
     tileAdj = getLyrAdj(tileLyr, tx, ty),
     wallAdj = getLyrAdj(wallLyr, tx, ty)
   }
 end

 function hasAnySide(adj)
   return adj.up ~= 0 or adj.down ~= 0 or adj.left ~= 0 or adj.right ~= 0
 end

 wallLyr=nil
 tileLyr=nil

 function initWalls()
  wallLyr=newWorldLyr(0,1)
  initWorldLyr(wallLyr)
 end

 function initTiles()
  tileLyr=newWorldLyr(0,1)
  initWorldLyr(tileLyr)
 end

 function tileAt(px,py)
  return getLyrId(tileLyr,px//8,py//8)
 end
--

-- CAMERA
 Cam={}
 Cam.__index=Cam
 cam=nil
 function Cam:new()
  local c=setmetatable({},self)
  c.x=0
  c.y=0
  return c
 end
 function Cam:update()
  self.x=flr(plr.x-(scrW//2-plr.w//2))
  self.y=flr(plr.y-(scrH//2-plr.h//2))
 end
 function Cam:screenToWorld(sx,sy)
  return sx+self.x,sy+self.y
 end
 function Cam:worldToScreen(wx,wy)
  return wx-self.x,wy-self.y
 end
 function Cam:tileAtScreen(sx,sy)
  local wx,wy=self:screenToWorld(sx,sy)
  return wx//8,wy//8
 end
 function Cam:mouseTarget()
  local mx,my=mouse()
  local wx,wy=self:screenToWorld(mx,my)
  local tx=wx//8
  local ty=wy//8
  local ctx=getTileCtx(tx,ty)
  local id=ctx.tile
  local isWall=false
  if id==0 and ctx.wall~=0 then
   id=ctx.wall
   isWall=true
  end
  return {
   mx=mx,my=my,
   worldx=wx,worldy=wy,
   tx=tx,ty=ty,
   ctx=ctx,
   tile=ctx.tile,
   wall=ctx.wall,
   id=id,
   isWall=isWall
  }
 end
 function Cam:drawMineCrack()
  if mineCrkTx==nil or mineCrkLvl<=0 then return end
  local sx=mineCrkTx*8-self.x
  local sy=mineCrkTy*8-self.y
  spr(236+mineCrkLvl,sx,sy,0)
 end
 function Cam:drawLyr(lyr)
  local tileX=self.x//8
  local tileY=self.y//8
  local offX=-(self.x%8)
  local offY=-(self.y%8)
  for sx=0,30 do
   for sy=0,17 do
    local tx=tileX+sx
    local ty=tileY+sy
    local id=getLyrId(lyr,tx,ty)
    local data=getLyrData(lyr,tx,ty)
    if id~=0 then
     local rot = fget(id,7) and data.rot or 0
     spr(id,offX+sx*8,offY+sy*8,0,1,0,rot)
    end
   end
  end
 end
 function Cam:drawPlayer()
  if plr.vx<0 then
   plr.flip=1
  elseif plr.vx>0 then
   plr.flip=0
  end
  if plr.ifrms%2==0 then
   spr(plr.sprite,scrW//2-4,scrH//2-8,0,1,plr.flip,0,1,2)
  end
 end
 function Cam:drawDrops()
  for i=1,#drops do
   drops[i]:draw(self.x, self.y)
  end
 end
 function Cam:draw()
  drawBg(self.x)
  self:drawLyr(wallLyr)
  self:drawLyr(tileLyr)
  self:drawMineCrack()
  self:drawPlayer()
  self:drawDrops()
  if DEBUG then drawDbg() end
 end
--

-- UI
 scrW=240
 scrH=136
 invt_open=false
 invtScrlRow=0
 inv_cursor_stk=nil
 miniMapBig = false
 miniMapCache={}
 function drawSprBox(sprId,x1,y1,x2,y2)
  spr(sprId,x1,y1,0,1,0,0)
  spr(sprId,x2,y1,0,1,0,1)
  spr(sprId,x2,y2,0,1,0,2)
  spr(sprId,x1,y2,0,1,0,3)
  local left,right,xspan = x1+8,x2-8,x2-x1-16
  if xspan >= 0 then
   local nx = max(1, math.ceil(xspan/8) + 1)
   for i=0,nx-1 do
    local t = (nx==1) and 0 or i/(nx-1)
    local x = flr(left + t*xspan + 0.5)
    spr(sprId+1,x,y1,0,1,0,0)
    spr(sprId+1,x,y2,0,1,0,2)
   end
  end

  -- left / right
  local top,bot,yspan = y1+8,y2-8,y2-y1-16
  if yspan >= 0 then
   local ny = max(1, math.ceil(yspan/8) + 1)
   for i=0,ny-1 do
    local t = (ny==1) and 0 or i/(ny-1)
    local y = flr(top + t*yspan + 0.5)
    spr(sprId+1,x1,y,0,1,0,3)
    spr(sprId+1,x2,y,0,1,0,1)
   end
  end
 end
 function initMiniMap()
  miniMapCache={}
  vbank(1)
  cls(0)
  for tile=0,255 do
   cls(0)
   spr(tile,0,0,0)
   local cnts={}
   local bestColor=10
   local bestCnt=-1
   for px=0,7 do
    for py=0,7 do
     local c=pix(px,py)
     if c~=0 and (tile == 2 or c~=13)then
      cnts[c]=(cnts[c] or 0)+1
      if cnts[c]>bestCnt then
       bestCnt=cnts[c]
       bestColor=c
      end
     end
    end
   end
   miniMapCache[tile]=bestColor
  end
  cls()
  vbank(0)
 end
 function drawMiniMap()
  local DX,DY,color=35,20,0
  if miniMapBig then 
   DX,DY,color=scrW//2-4,scrH//2-4,0
  end
  for x=-DX,DX do
   for y=-DY,DY do
    local tile=tileAt(plr.x+x*8,plr.y+y*8)
    if tile== 0 then tile = getLyrId(wallLyr,(plr.x+x*8)//8,(plr.y+y*8)//8) end
    if x==0 and (y==0 or y==1) then color=0 else color=miniMapCache[tile] end
    pix(scrW+x-DX-5,y+DY+4,color)
   end
  end
  drawSprBox(304,scrW-2*DX-7,1,scrW-9,2*DY-2)
 end
 function drawHart(i,health,sprShift)
  local x=8*(i-1)
  local flash=(time()//100)%2
  if health<1 then
   spr(249+sprShift,x,3,0)
  elseif health==1 then
   spr(248+flash+sprShift,x,3,0)
  elseif health==2 then
   spr(248+sprShift,x,3,0)
  elseif health==3 then
   spr(247+flash+sprShift,x,3,0)
  else
   spr(247+sprShift,x,3,0)
  end
 end
 function drawOxy()
  local oxy=plr.o2//15
  for i=-2,2 do
   local x=116+9*i
   local sprId=234
   if oxy<=0 then sprId=236
   elseif oxy<=8 and oxy%2==1 then sprId=235 end
   spr(sprId,x,50,0)
   oxy=oxy-7
  end
 end
 function outlineSpr(id,x,y)
  vbank(1)
  cls()
  spr(id,0,0,0)
  local mask={}
  for px=0,7 do
   mask[px]={}
   for py=0,7 do
    mask[px][py]=pix(px,py)
   end
  end
  cls()
  vbank(0)
  for i=-1,1 do for j=-1,1 do
   for px=0,7 do for py=0,7 do
    if mask[px][py] ~= 0 then
     pix(x+px+i,y+py+j,0)
    end end
   end
  end end
 end
 function outlinePrint(txt, x, y)
  txt = tostring(txt)
  for i=-1,1 do for j=-1,1 do
    print(txt, x+i, y+j, 15, true, 1, true)
  end end
  print(txt, x, y, 11, true, 1, true)
 end
 function drawStkIcon(stk,x,y)
  if stk:isEmpty() then return end
  local itm = stk.itm
  local cnt = stk.cnt or 0
  outlineSpr(itm.id, x+4, y+4)
  spr(itm.id, x+4, y+4, 0)
  if itm.dur and itm.maxDur then
   if itm.dur < itm.maxDur then
    local durBar = (12 * itm.dur) // itm.maxDur
    line(x+2, y+13, x+14, y+13, 15)
    line(x+2, y+13, x+2+durBar, y+13, 6)
   end
  elseif cnt > 1 then
   local t_X = x + 15 - 4*#tostring(cnt)
   local t_Y = y + 10
   outlinePrint(cnt, t_X, t_Y)
  end
 end
 function drawSlotFrm(x,y,selected)
  local sprShift = selected and 2 or 0
  spr(224+sprShift, x, y, -1, 1, 0, 0, 2, 2)
 end
 function drawInvtSlot(slotIdx,x,y)
  drawSlotFrm(x,y,slotIdx == plr.selectedSlot)
  drawStkIcon(plr.invt[slotIdx],x,y)
 end

 function invtLayout()
  local cols = 9
  local rows = 5
  local slotSize = 17
  local x = (scrW - cols*slotSize + 1)//2
  local y = 28
  return x,y,cols,rows,slotSize
 end

 function visibleInvtRows()
  local _,_,_,rows = invtLayout()
  return rows
 end

 function maxInvtScrl()
  local cols,rows = 9,visibleInvtRows()
  local totalRows = max(1, math.ceil(#plr.invt / cols))
  return max(0, totalRows - rows)
 end

 function clampInvtScrl()
  invtScrlRow = clamp(invtScrlRow, 0, maxInvtScrl())
 end

 function invtSlotAt(mx,my)
  local startX,startY,cols,rows,slotSize = invtLayout()
  if mx < startX or my < startY then return nil end

  local col = (mx - startX) // slotSize
  local row = (my - startY) // slotSize
  if col < 0 or col >= cols or row < 0 or row >= rows then return nil end

  local slot = invtScrlRow*cols + row*cols + col + 1
  if slot > #plr.invt then return nil end
  return slot
 end

 function swapInvtSlot(slot)
  if inv_cursor_stk == nil then
   inv_cursor_stk = emptyStk()
  end

  local held = inv_cursor_stk
  inv_cursor_stk = plr.invt[slot]
  plr.invt[slot] = held

  if slot <= 9 then
   plr.selectedSlot = slot
  end
 end

 function drawInvtCursor(mx,my)
  if inv_cursor_stk == nil or inv_cursor_stk:isEmpty() then return end
  drawStkIcon(inv_cursor_stk,mx-8,my-8)
 end

 function drawInvtScreen()
  local x,y,cols,rows,slotSize = invtLayout()
  local boxPad = 10
  local boxX1 = x - boxPad
  local boxY1 = y - 16
  local boxX2 = x + cols*slotSize - 1 + boxPad - 1
  local boxY2 = y + rows*slotSize - 1 + 18

  rect(0,0,scrW,scrH,0)
  rect(0,0,scrW,scrH,1)
  drawSprBox(304,boxX1,boxY1,boxX2,boxY2)
  outlinePrint("Invt",x + 46,boxY1 + 4)
  print("[B] close  click to swap",x+8,boxY2-10,12,true,1,true)

  local topSlot = invtScrlRow*cols + 1
  for row=0,rows-1 do
   for col=0,cols-1 do
    local slot = topSlot + row*cols + col
    if slot <= #plr.invt then
     drawInvtSlot(slot, x + col*slotSize, y + row*slotSize)
    end
   end
  end

  local maxScrl = maxInvtScrl()
  if maxScrl > 0 then
   outlinePrint((invtScrlRow+1).."/"..(maxScrl+1), boxX2-24, boxY1+4)
  end

  local mx,my = mouse()
  drawInvtCursor(mx,my)
 end

 function drawHotbar()
  for i=1,9 do
   drawInvtSlot(i, 2 + (i-1)*17, 14)
  end
 end

 function drawUi()
  if invt_open then
   drawInvtScreen()
   return
  end

  local hpShift=((plr.ifrms//5)%2==1) and -16 or 0
  local hp=plr.hp
  for i=1,10 do
   drawHart(i,hp,hpShift)
   hp=hp-4
  end

  local sprShift=plr.winded and -16 or 0
  spr(244+sprShift,80,3,0)
  for i=1,8 do spr(245+sprShift,80+8*i,3,0) end
  spr(246+sprShift,152,3,0)

  local fill=plr.stamina/1000
  if fill>0 then
   local x2=83+fill*73
   line(83,5,x2,5,5)
   line(82,6,x2+1,6,6)
   line(83,7,x2,7,6)
   line(83,8,x2,8,7)
  end

  if plr.o2<plr.max_o2 then drawOxy() end

  drawHotbar()
  drawMiniMap()
 end

 function death_screen()
  death_frm = death_frm or frm
  cam:update()
  cam:draw()
  plr.ifrms=plr.ifrms-1

  if death_frm==frm-1 then sfx(63) end
  if frm-death_frm>40 then
   cls(2)
   if (frm//30)%2==1 then
    print("Press [B] to respawn",65,70,14,false,1)
   end
   if btnp(5) then
    plr=makePlr(WORLD_W*4,165)
    death_frm=nil
   end
  end
  print("You Died!",32,35,12,false,4)
 end
--

-- TILES
 Tile={}
 Tile.__index=Tile
 function Tile:new(id, props)
  props=props or {}
  local t=setmetatable({}, self)
  t.id=id
  t.hardness=props.hardness or 5
  t.tool=props.tool
  t.drop=props.drop
  t.upd=props.upd
  return t
 end
 function Tile:brake(tx,ty)
  if self.drop then
   drops[#drops+1]=Drop:new(self.drop(),tx*8+2,ty*8+2)
  else
   drops[#drops+1]=Drop:new(ItmStk:new(makeItm(self.id),1),tx*8+2,ty*8+2)
  end
 end
 tiles={}
 function defTile(id, props)
  tiles[id]=Tile:new(id, props)
  return tiles[id]
 end
 function getTile(id) return tiles[id] or tiles[0] end
 function isSolid(tile) return fget(tile,0) end
 function isReplaceable(tile) return fget(tile,1) end
 --loot tables
 function ltTbl(list)
  return function()
   if #list==0 then return emptyStk() end
   local totalWeight=0
   for i=1,#list do
    totalWeight=totalWeight+(list[i][4] or 1)
   end
   local r=rnd()*totalWeight
   local acc=0
   for i=1,#list do
    local e=list[i]
    acc=acc+(e[4] or 1)
    if r<=acc then
     local id=e[1]
     local minCnt=e[2] or 1
     local maxCnt=e[3] or minCnt
     local cnt=max(0,rnd(minCnt,maxCnt))
     return ItmStk:new(makeItm(id),cnt)
    end
   end
   return emptyStk()
  end
 end
 -- tile updates
 function Tile:fallingBlock()
  return function(self,tx,ty,ctx)
   if not isSolid(ctx.tileAdj.down) then
    queueTileSet(tx,ty,0)
    queueTileSet(tx,ty+1,self.id)
    if isReplaceable(ctx.tileAdj.down,1) then tiles[ctx.tileAdj.down]:brake(tx,ty) end
    sfx(5)
   end
  end
 end
 function Tile:supportDown(list)
  if list then 
   return function(self,tx,ty,ctx)
    local supported = false
    for _,id in pairs(list) do supported = supported or ctx.tileAdj.down == id end
    if not supported then 
     queueTileSet(tx,ty,0)
     self:brake(tx,ty)
    end
   end
  else
   return function(self,tx,ty,ctx)
    if not isSolid(ctx.tileAdj.down) then
     queueTileSet(tx,ty,0)
     self:brake(tx,ty)
    end
   end
  end
 end
 function Tile:grow(speed, list)
  return function(self,tx,ty,ctx)
   if rnd() < (1/speed) then
    queueTileSet(tx,ty,self.id + 3)
   end
   self:supportDown(list)(self,tx,ty,ctx)
  end
 end
 function Tile:growTree(speed,list)
  return function(self,tx,ty,ctx)
   if rnd() < (1/speed) then
    genTree(tx,ty+1)
   end
   self:supportDown(list)(self,tx,ty,ctx)
  end
 end
 function Tile:leafDecay(maxDist)
  local dist = function(x,y) return getLyrData(tileLyr,x,y).logDist end
  return function(self,tx,ty,ctx)
   local minDist=nil
   for x=-1,1 do for y=-1,1 do 
    if dist(tx+x,ty+y) then
     minDist=min(dist(tx+x,ty+y),minDist or dist(tx+x,ty+y))
    end
    if getLyrId(tileLyr,tx+x,ty+y) == 8 then minDist=0 end
   end end
  
   getLyrData(tileLyr,tx,ty).logDist = (minDist or maxDist) + 1
   if getLyrData(tileLyr,tx,ty).logDist > maxDist and rnd()<.001 then 
    queueTileSet(tx,ty,0)
    tiles[self.id]:brake(tx,ty)
   end
  end
 end


 -- air and void
  for id=0,1 do defTile(id,{hardness=-id,drop=ltTbl({{1,0,0}})}) end 
 -- mined with pick
  defTile(2,{hardness=100,tool=1,drop= ltTbl({{18}}),tier=0})
  for id=10,15 do defTile(id,{hardness=150+30*(id-10),tool=1,tier=clamp(id-11,0,3)})end
  for id=18,32 do defTile(id,{hardness=100,tool=1,tier=0})end
  tiles[18].drop = ltTbl({{368,2,3}})
 -- mined with axe
  defTile(8,{hardness=100,tool=2,drop=ltTbl({{16}})})
  defTile(9,{hardness=100,tool=2,drop=ltTbl({{381,0,1},{379},{380},{381}}),upd=Tile:leafDecay(10)})
  for id=16,17 do defTile(id,{hardness=50,tool=2})end
 -- mined with shovle
  for id=3,7 do defTile(id,{hardness=100,tool=3})end
  defTile(33,{hardness=100,tool=3})
  defTile(60,{hardness=100,tool=3})
  tiles[4].drop = ltTbl({{3}})
  tiles[60].drop = ltTbl({{3}})
 --plants
  for id=41,44 do defTile(id,{drop=ltTbl({{374,0,2},{375,0,1},{376,0,1}}),upd=Tile:supportDown({3,4,60})})end
  for id=45,53 do defTile(id,{drop=ltTbl({{374+id%3}}),upd=Tile:grow(100,{3,4,60})})end
  cropDrops= {{{377,1,3},{374,2,3}},{{375,2,5}},{{376,1,3}}}
  for id=54,56 do defTile(id,{drop=ltTbl(cropDrops[id%3]),upd=Tile:supportDown({3,4,60})})end
  defTile(58,{upd=Tile:supportDown({3,4,5,6,7,60})})
  defTile(57,{upd=Tile:growTree(100,{3,4})})
 -- def updates
  for id=5,6 do tiles[id].upd=Tile:fallingBlock()end
--

--TILE UPDATES
 BG_PHASES = 60
 bgPhase = 0
 pendingTileChanges={}
 function getMiniMapTileBounds()
  local DX,DY = 35,20
  if miniMapBig then
   DX,DY = scrW//2-4, scrH//2-4
  end
  local cx = plr.x // 8
  local cy = plr.y // 8
  local x1 = max(0, cx - DX)
  local y1 = max(0, cy - DY)
  local x2 = min(WORLD_W, cx + DX)
  local y2 = min(WORLD_H, cy + DY)
  return x1,y1,x2,y2
 end
 function updTilesRegion(x1,y1,x2,y2)
  for y=y1,y2 do for x=x1,x2 do
   local id = getLyrId(tileLyr,x,y)
   local tile = getTile(id)
   if tile.upd then
    local ctx = getTileCtx(x,y)
    tile.upd(tile,x,y,ctx)
   end 
  end end
 end
 function updTilesBgStag()
  local mx1,my1,mx2,my2 = getMiniMapTileBounds()
  for y=0,WORLD_H do for x=0,WORLD_W do
   local inMini = x>=mx1 and x<=mx2 and y>=my1 and y<=my2
   if not inMini and ((x + y) % BG_PHASES) == bgPhase then
    local id = getLyrId(tileLyr,x,y)
    local tile = getTile(id)
    if tile.upd then
     local ctx = getTileCtx(x,y)
     tile.upd(tile,x,y,ctx)
    end
   end
  end end
  bgPhase = (bgPhase + 1) % BG_PHASES
 end
 function queueTileSet(tx,ty,id) pendingTileChanges[#pendingTileChanges+1]={tx=tx,ty=ty,id=id}end
 function applyTileChanges()
  for i=1,#pendingTileChanges do
   local c=pendingTileChanges[i]
   setLyrId(tileLyr,c.tx,c.ty,c.id)
  end
  pendingTileChanges={}
 end
 function updTilesCmbd()
  pendingTileChanges = {}
  if frm % 5 == 0 then
   local x1,y1,x2,y2 = getMiniMapTileBounds()
   updTilesRegion(x1,y1,x2,y2)
  end
  updTilesBgStag()
  applyTileChanges()
 end
--

-- ITEMS
 ItmStk={}
 ItmStk.__index=ItmStk
 Itm={}
 Itm.__index=Itm
 itmDefs={}
 function ItmStk:new(itm,cnt)
  local s=setmetatable({}, self)
  if itm==nil then
   s.itm=nil
   s.cnt=0
  else
   s.itm=itm
   s.cnt=cnt or 1
  end
  return s
 end
 function ItmStk:clear()
  self.itm=nil
  self.cnt=0
 end
 function ItmStk:isEmpty() return self.itm==nil or self.cnt<=0 end
 function ItmStk:addStk(other)
  if not itmsStkable(self.itm,other.itm) then return other end
  if self.cnt+other.cnt<=self.itm.maxStk then
   self.cnt=self.cnt+other.cnt
   other:clear()
  else
   other.cnt=(self.cnt+other.cnt)-self.itm.maxStk
   self.cnt=self.itm.maxStk
  end
 end
 function emptyStk() return ItmStk:new(nil,0) end
 function Itm:new(id,props)
  props=props or {}

  local itm=setmetatable({}, self)
  itm.id=id
  itm.name=props.name or ("itm_"..id)
  itm.type=props.type or "material"
  itm.useTime=props.useTime or 20
  itm.useType=props.useType
  itm.maxStk=props.maxStk or 99
  itm.maxDur=props.maxDur
  itm.dur=props.maxDur
  itm.progress=0
  itm.targetTx=nil
  itm.targetTy=nil
  itm.cooldown=0

  return itm
 end
 function Itm:clone()
  local c=Itm:new(self.id,{
   name=self.name,
   type=self.type,
   useTime=self.useTime,
   useType=self.useType,
   maxStk=self.maxStk,
   maxDur=self.maxDur
  })
  return c
 end
 function Itm:use(mt)
  if self.useType==nil then return false end
  return self.useType(self,mt)
 end
 function Itm:placeBlock(tID)
  return function(itm,mt)
   local tx,ty,ctx = mt.tx,mt.ty,mt.ctx
   if not fget(ctx.tile,1) then return false end --replaceable spr flag
   local nearBlock = hasAnySide(ctx.tileAdj)
   local anchoredByWall = ctx.wall~=0
   if nearBlock or anchoredByWall then
    setLyrId(tileLyr,tx,ty,tID)
    return true
   end 
   return false
  end
 end
 function Itm:placeWall(tID)
  return function(itm,mt)
   local tx,ty,ctx = mt.tx,mt.ty,mt.ctx
   if ctx.wall~=0 then return false end
   local nearWall = hasAnySide(ctx.wallAdj)
   local anchoredByBlock = ctx.tile~=0 or hasAnySide(ctx.tileAdj)
   if nearWall or anchoredByBlock then
    setLyrId(wallLyr,tx,ty,tID)
    return true
   end
   return false
  end
 end
 
 function Itm:plant(tID,plantOn)
  return function(itm,mt)
   local tx,ty,ctx = mt.tx,mt.ty,mt.ctx
   if ctx.tile~=0 then return false end
   if ctx.tileAdj.down == plantOn then
    setLyrId(tileLyr,tx,ty,tID)
    return true
   end
   return false
  end
 end

 function Itm:fert()
  return function(itm,mt)
   local tx,ty,ctx = mt.tx,mt.ty,mt.ctx
   if ctx.tile == 0 and ctx.tileAdj.down == 4 then 
    genTallGrass(tx, ty)
    return true 
   end
   return false
  end
 end

 function Itm:mine(power,toolType)
  return function(itm,mt)
   local tx,ty = mt.tx,mt.ty
   local targetId = mt.id
   local miningWall = mt.isWall
   local tile = getTile(targetId)
   if tile.hardness<=0 then
    resetMine(itm)
    return false
   end
   if itm.targetTx~=tx or itm.targetTy~=ty then
    itm.progress=0
    itm.targetTx=tx
    itm.targetTy=ty
   end
   local minePower=power
   if tile.tool~=nil and toolType~=tile.tool then
    minePower=1
   end
   itm.progress=itm.progress+minePower
   local crkLvl=(4*itm.progress)//tile.hardness
   crkLvl=clamp(crkLvl,0,3)
   mineCrkTx=tx
   mineCrkTy=ty
   mineCrkLvl=crkLvl
   if itm.progress>=tile.hardness then
    if miningWall then
     setLyrId(wallLyr,tx,ty,0)
    else
     setLyrId(tileLyr,tx,ty,0)
    end
    resetMine(itm)
    tile:brake(tx,ty)
    return true
   end
   return false
  end
 end
 function Itm:eat(hp) return function(itm,mt) return healPlr(hp) end end
 function defItm(id,props)
  local def=Itm:new(id,props)
  itmDefs[id]=def
  return def
 end
 function makeItm(id)
  local def=itmDefs[id]
  if not def then error("missing itm def: "..tostring(id)) end
  return def:clone()
 end
 function itmsStkable(a,b)
  if a==nil or b==nil then return false end
  if a.id~=b.id then return false end
  if a.maxDur~=nil or b.maxDur~=nil then return false end
  return true
 end

 -- wals and blocks
 wallItmIds={17,19,21,23,25,32,33}
 for id=1,55 do defItm(id,{useTime=30,useType=Itm:placeBlock(id)})end
 for _,id in pairs(wallItmIds)do defItm(id,{useTime=10,useType=Itm:placeWall(id)}) end
 -- tools
 for t=0,3 do for k=1,3 do defItm(352+4*t+k,{useType=Itm:mine(t,k),maxDur=flr(100*(2.5)^t),maxStk=1}) end end
 -- gems & ingots
 for id=368,373 do defItm(id,{useType=Itm:placeBlock(id-342)})end
 -- crop seeds
 for id=374,376 do defItm(id,{useType=Itm:plant(id-329,60)})end
 defItm(377,{})
 -- fertalizer
 defItm(378,{useType=Itm:fert()})
 -- acorn
 defItm(379,{useType=Itm:plant(57,4)})
 -- stick
 defItm(380,{})
 -- food
 for id=381,386 do defItm(id,{useType=Itm:eat(3*(id-380))}) end
 -- hand
 defItm(999,{useType=Itm:mine(1,nil),maxStk=1})
--

--INVENTORY
 function makeInv()
  local inv={}

  inv[1]=ItmStk:new(makeItm(357),1)
  inv[2]=ItmStk:new(makeItm(5),25)

  for i=3,45 do
   inv[i]=emptyStk()
  end

  return inv
 end

 function makeDbgInv()
  local inv={}
  local ids={}

  for id,_ in pairs(itmDefs) do
   if id ~= 999 then
    ids[#ids+1]=id
   end
  end

  table.sort(ids)

  for i=1,#ids do
   local itm = makeItm(ids[i])
   local cnt = itm.maxDur and 1 or itm.maxStk
   inv[i]=ItmStk:new(itm,cnt)
  end

  local totalSlots = max(45,#ids)
  for i=#ids+1,totalSlots do
   inv[i]=emptyStk()
  end

  return inv
 end

 function setDbgMode(enabled)
  DEBUG = enabled
  if plr == nil then return end

  invt_open = false
  inv_cursor_stk = emptyStk()

  if enabled then
   if plr.saved_invt == nil then
    plr.saved_invt = plr.invt
   end
   plr.invt = makeDbgInv()
   plr.selectedSlot = 1
   invtScrlRow = 0
  else
   if plr.saved_invt ~= nil then
    plr.invt = plr.saved_invt
    plr.saved_invt = nil
   end
  end

  clampInvtScrl()
 end

 function updItmCooldowns()
  for i=1,#plr.invt do
   local stk=plr.invt[i]
   if not stk:isEmpty() and stk.itm.cooldown and stk.itm.cooldown>0 then
    stk.itm.cooldown=stk.itm.cooldown-1
   end
  end
 
  if plr.hand_itm and plr.hand_itm.cooldown>0 then
   plr.hand_itm.cooldown=plr.hand_itm.cooldown-1
  end
 end
--

-- DROPS
 Drop = {}
 Drop.__index = Drop

 function Drop:new(stk,x,y)
  local d = setmetatable({}, self)

  d.stk = stk

  d.x = x or 0
  d.y = y or 0
  d.vx = rnd(-10,10) / 10
  d.vy = -1.2

  d.w = 4
  d.h = 4

  d.fricx = 0.85
  d.gravity = 0.12
  d.max_fall = 2.5

  d.age = 0
  d.pickup_delay = 20
  d.dead = false
  return d
 end

 function Drop:upd()
  if self.stk.cnt <=0 then 
   self.dead = true
   return
  end

  self.age = self.age + 1
  self.h = 4+math.sin(self.age / 20)
 
  self.vy = math.min(self.vy + self.gravity, self.max_fall)
 
  -- move x
  local newX = self.x + self.vx
  if self.vx > 0 then
   if isSolid(tileAt(newX + self.w, self.y))
   or isSolid(tileAt(newX + self.w, self.y + self.h - 1)) then
    self.vx = 0
   else
    self.x = newX
   end
  elseif self.vx < 0 then
   if isSolid(tileAt(newX, self.y))
   or isSolid(tileAt(newX, self.y + self.h - 1)) then
    self.vx = 0
   else
    self.x = newX
   end
  end
 
  -- move y
  local newY = self.y + self.vy
  if self.vy > 0 then
   if isSolid(tileAt(self.x, newY + self.h))
   or isSolid(tileAt(self.x + self.w - 1, newY + self.h)) then
    self.vy = 0
    self.y = flr((newY + self.h)//8)*8 - self.h
   else
    self.y = newY
   end
  elseif self.vy < 0 then
   if isSolid(tileAt(self.x, newY))
   or isSolid(tileAt(self.x + self.w - 1, newY)) then
    self.vy = 0
   else
    self.y = newY
   end
  end
 
  self.vx = self.vx * self.fricx
  if math.abs(self.vx) < 0.02 then self.vx = 0 end
 end

 function Drop:draw(camX, camY)
  local sx = flr(self.x - camX)
  local sy = flr(self.y - camY)

  smlSpr(self.stk.itm.id, sx, sy)
 end
 
 function giveStk(stk)
  if stk:isEmpty() then return true end

  for i=1,#plr.invt do
   local slot = plr.invt[i]
   if not slot:isEmpty() then
    slot:addStk(stk)
    if stk:isEmpty() then return true end
   end
  end

  for i=1,#plr.invt do
   if plr.invt[i]:isEmpty() then
    plr.invt[i] = stk
    return true
   end
  end

  return false
 end

 function Drop:tryPickup()
  if self.age < self.pickup_delay then return end
 
  local px1 = plr.x - 4
  local py1 = plr.y
  local px2 = plr.x + plr.w+4
  local py2 = plr.y + plr.h
 
  local dx1 = self.x
  local dy1 = self.y
  local dx2 = self.x + self.w
  local dy2 = self.y + self.h
 
  local overlap = dx1 < px2 and dx2 > px1 and dy1 < py2 and dy2 > py1
  if overlap then
   if giveStk(self.stk) then
    self.dead = true
    sfx(6)
   end
  end
 end

 drops = {}
 function updDrops()
  for i = #drops, 1, -1 do
   local drop = drops[i]
   drop:upd()
   drop:tryPickup()

   if drop.dead then
    drops[i] = drops[#drops]
    drops[#drops] = nil
   end
  end
 end
 
 function smlSpr(id, x, y)
  vbank(1)
  cls()
  spr(id,0,0,0)
 
  local stamp={}
  for px=0,3 do
   stamp[px]={}
   for py=0,3 do
    stamp[px][py]=pix(px*2,py*2)
   end
  end
  cls()
  vbank(0)
  
  for px=0,3 do for py=0,3 do
   if stamp[px][py] ~= 0 then
    pix(x+px,y+py,stamp[px][py])
  end end end
 end
--

-- PLAYER
 function makePlr(x,y)
  return{
   x=x,y=y,vx=0,vy=0,ax=0,ay=0.5,
   fricx=.7,fricy=.95,
   w=4,h=15,sprite=256,flip=0,
   on_ground=false,jumping=false,
   hp=40,max_hp=40,stamina=1000,max_stam=1000,o2=600,max_o2=600,
   invt=makeInv(),selectedSlot=1,hand_itm=makeItm(999),usingHand = false,
   saved_invt=nil,
   regen_timer=0,regen_speed=120,
   winded=false,working=false,
   ifrms=60,maxv=0,last_dx=1,
   medium="air",last_medium="air",
   feet_fluid=false,eyes_fluid=false,
   sound_timer=0
  }
 end
 function inpPlr()
  plr.ax=0
  plr.working=false
  if btnp(5) then
   if invt_open then
    if inv_cursor_stk ~= nil and not inv_cursor_stk:isEmpty() then
     if giveStk(inv_cursor_stk) then
      inv_cursor_stk = emptyStk()
     else
      clampInvtScrl()
      return
     end
    end
    invt_open = false
   else
    invt_open = true
    invtScrlRow = 0
   end
   clampInvtScrl()
  end
  if invt_open then return end
  if btn(2) then plr.ax=plr.ax-.5 end
  if btn(3) then plr.ax=plr.ax+.5 end
  if plr.medium=="air" then
   plr.fricx=.7
   plr.fricy=.95
   if btnp(4) and plr.on_ground then
    local pct=plr.stamina/plr.max_stam
    local vol=1+flr(14*pct)
    if not plr.winded then
     sfx(1,"D-4",20,0,vol)
     plr.vy=-5
     plr.stamina=plr.stamina-100
    else
     sfx(1,"D-3",20,0,vol)
     plr.vy=-2
     plr.stamina=plr.stamina-50
    end
    plr.on_ground=false
    plr.jumping=true
    plr.maxv=0
   end
   if btn(4) and plr.jumping then
    if plr.vy<0 then plr.ay=.05 else plr.ay=.167 end
   else
    plr.ay=.5
   end
  elseif plr.medium=="submerged" then
   plr.jumping=false
   plr.ay=.1
   plr.fricx=.5
   plr.fricy=.8
   plr.working=true
   if btnp(4) and plr.on_ground then
    sfx(1,"D-3",20,0,5)
    plr.vy=-3
    if plr.winded then plr.stamina=max(0,plr.stamina-20) end
    plr.on_ground=false
   end
   if btn(4) and not plr.winded then
    plr.fricy=.9
    plr.vy=plr.vy-.7
    plr.vy=max(plr.vy,-2.5)
    plr.stamina=plr.stamina-2
    if frm-plr.sound_timer>60 then
     sfx(3,"E-5",-1,0,5)
     plr.sound_timer=frm
    end
   end
   if plr.last_medium=="air" then
    local note=55+rnd(3)
    sfx(2,note,20,0,5)
   end
  elseif plr.medium=="wading" then
   plr.ay=.15
   plr.fricx=.5
   plr.fricy=.9
   if plr.last_medium=="air" then
    local note=55+rnd(3)
    sfx(2,note,20,0,5)
    plr.vy=1
    plr.jumping=false
   end
   if btnp(4) and plr.on_ground then
    sfx(1,"D-3",20,0,5)
    if not plr.winded then
     plr.vy=-3
     plr.stamina=plr.stamina-100
    else
     plr.vy=-1
     plr.stamina=plr.stamina-50
    end
    plr.on_ground=false
    plr.jumping=true
    plr.maxv=0
   end
   if btn(4) and not (plr.on_ground or plr.winded) then
    if frm-plr.sound_timer>60 then
     sfx(3,"E-5",-1,0,5)
     plr.sound_timer=frm
    end
    plr.ay=0
    plr.working=true
    plr.jumping=true
    local amp=(math.abs(3*plr.vx)+1)/10
    plr.y=plr.y+amp*math.sin(6.283*time()/1000)
    plr.stamina=plr.stamina-amp
   end
  end
 end
 function moveX()
  local oldVx=plr.vx
  local newX=plr.x+plr.vx
  if plr.vx>0 then
   plr.last_dx=1
   local right=newX+plr.w
   if isSolid(tileAt(right,plr.y))
   or isSolid(tileAt(right,plr.y+plr.h//2))
   or isSolid(tileAt(right,plr.y+plr.h-1)) then
    plr.x=(right//8)*8-plr.w
    plr.vx=0
   else
    plr.x=newX
   end
  elseif plr.vx<0 then
   plr.last_dx=-1
   local left=newX
   if isSolid(tileAt(left,plr.y))
   or isSolid(tileAt(left,plr.y+plr.h//2))
   or isSolid(tileAt(left,plr.y+plr.h-1)) then
    plr.x=(left//8+1)*8
    plr.vx=0
   else
    plr.x=newX
   end
  end
  if math.abs(plr.vx)<1/60 then plr.vx=0 end
  if plr.vx==0 then
   if oldVx>0 then
    plr.x=math.ceil(plr.x)
   elseif oldVx<0 then
    plr.x=flr(plr.x)
   end
  end
 end
 function moveY()
  local newY=plr.y+plr.vy
  if plr.vy>0 then
   local botProbe=newY+plr.h+1/2
   local left=plr.x
   local mid=plr.x+plr.w//2
   local right=plr.x+plr.w-1
   if isSolid(tileAt(left,botProbe))
   or isSolid(tileAt(mid,botProbe))
   or isSolid(tileAt(right,botProbe)) then
    plr.y=(botProbe//8)*8-plr.h
    if plr.vy>6.25 then hurtPlr((plr.vy-6)*4) end
    plr.vy=0
    plr.on_ground=true
    plr.jumping=false
   else
    plr.y=newY
    plr.on_ground=false
    if plr.medium=="air" then plr.jumping=false end
   end
  elseif plr.vy<0 then
   local top=newY
   local left=plr.x
   local mid=plr.x+plr.w//2
   local right=plr.x+plr.w-1
   if isSolid(tileAt(left,top))
   or isSolid(tileAt(mid,top))
   or isSolid(tileAt(right,top)) then
    plr.y=(top//8+1)*8
    plr.vy=0
   else
    plr.y=newY
   end
  end
 end
 function hurtPlr(dmg,kbx,kby,numFrms)
  kbx=kbx or 0
  kby=kby or -3
  numFrms=numFrms or 10
  dmg=max(0,flr(dmg))
  if plr.ifrms==0 then
   plr.ifrms=numFrms
   plr.vx=plr.vx+kbx
   plr.vy=plr.vy+kby
   plr.hp=plr.hp-dmg
   sfx(4)
  end
  if plr.hp<=0 then
   death_frm=frm
   plr.dead=true
  end
  plr.regen_timer=plr.regen_speed
 end
 function healPlr(hp)
  if plr.hp<40 then
   if hp then plr.hp=plr.hp+hp end
   if plr.regen_timer<0 then
    plr.hp=plr.hp+1
    plr.regen_timer=plr.regen_speed
   end
   return true
  end
  plr.regen_timer=plr.regen_timer-1
  return false
 end
 function recStam()
  if plr.stamina<=0 then plr.winded=true end
  if plr.working then return end

  local regen=2
  if plr.winded then regen=3 end

  if plr.stamina<plr.max_stam then
   plr.stamina=plr.stamina+regen
  end

  if plr.stamina>=plr.max_stam then
   plr.stamina=plr.max_stam
   plr.winded=false
  end
 end
 function breathe()
  if plr.eyes_fluid then
   plr.o2=max(0,plr.o2-1)
  else
   plr.o2=math.min(plr.max_o2,plr.o2+1)
  end
  if plr.o2<=0 then hurtPlr(2,0,-1,30) end
 end
 function updPlr()
  inpPlr()
  updItmCooldowns()
  plrMouse()
  plr.vx=plr.vx*plr.fricx+plr.ax
  plr.vy=plr.vy*plr.fricy+plr.ay
  moveX()
  moveY()
  healPlr()
  recStam()
  breathe()
  plr.ifrms=max(plr.ifrms-1,0)
 end
--

-- MOUSE
 MB_LEFT  = 1
 MB_MID   = 2
 MB_RIGHT = 4
 prevMouseBits = 0

 function mouseBits()
  local _,_,lmb,mmb,rmb = mouse()
  local bits=0
  if lmb then bits=bits|MB_LEFT end
  if mmb then bits=bits|MB_MID end
  if rmb then bits=bits|MB_RIGHT end
  return bits
 end

 function isDown(bits, button)
  return (bits & button)~=0
 end

 function mouseTarget()
  return cam:mouseTarget()
 end

 function resetMine(itm)
  if itm==nil then return end
  itm.progress=0
  itm.targetTx=nil
  itm.targetTy=nil
  mineCrkTx=nil
  mineCrkTy=nil
  mineCrkLvl=0
 end

 function mouseInvt(mx,my,mb,pressed,scrl)
  if not invt_open then return false end

  if scrl ~= 0 then
   invtScrlRow = invtScrlRow - scrl
   clampInvtScrl()
  end

  if isDown(pressed, MB_LEFT) then
   local slot = invtSlotAt(mx,my)
   if slot ~= nil then
    swapInvtSlot(slot)
   end
  end

  return true
 end

 function mouseHotbar(mx,my,pressed,scrl)
  if scrl ~= 0 then
   plr.selectedSlot = (plr.selectedSlot - 1 - scrl) % 9 + 1
  end

  if isDown(pressed, MB_LEFT) then
   if my <= 32 and my > 13 then
    local slot = (mx-2)//17 + 1
    if slot >= 1 and slot <= 9 then
     plr.selectedSlot = slot
    end
   end
  end

  return plr.invt[plr.selectedSlot]
 end

 function mouseActiveItm(stk,pressed)
  local itm=nil

  if isDown(pressed, MB_LEFT) then
   if stk:isEmpty() then
    plr.usingHand=true
    itm=plr.hand_itm
   else
    plr.usingHand=false
    itm=stk.itm
   end
  else
   if plr.usingHand then
    itm=plr.hand_itm
   elseif not stk:isEmpty() then
    itm=stk.itm
   end
  end

  return itm
 end

 function mouseResetMine(itm,stk,mb,mt)
  if not isDown(mb, MB_LEFT) then
   resetMine(plr.hand_itm)
   if not stk:isEmpty() then resetMine(stk.itm) end
  end

  if itm and itm.targetTx ~= nil then
   if itm.targetTx ~= mt.tx or itm.targetTy ~= mt.ty then
    resetMine(itm)
   end
  end
 end

 function mouseUseItm(itm,stk,mt,mb)
  if not isDown(mb, MB_LEFT) then return end
  if itm==nil then return end
  if mt.my <= 32 then return end
  if itm.use == nil then return end
  if itm.cooldown > 0 then return end

  if itm:use(mt) then
   itm.cooldown = itm.useTime

   if not plr.usingHand then
    if itm.maxDur ~= nil then
     itm.dur = itm.dur - 1
     if itm.dur <= 0 then
      plr.invt[plr.selectedSlot] = emptyStk()
     end
    else
     stk.cnt = stk.cnt - 1
     if stk.cnt <= 0 then
      plr.invt[plr.selectedSlot] = emptyStk()
     end
    end
   end
  end
 end

 function plrMouse()
  local mt = mouseTarget()
  local mx,my = mt.mx,mt.my
  local _,_,_,_,_,_,scrl = mouse()
  scrl = scrl or 0
  local mb = mouseBits()
  local pressed = mb & (~prevMouseBits)
  if mouseInvt(mx,my,mb,pressed,scrl) then
   prevMouseBits = mb
   return
  end
  local stk = mouseHotbar(mx,my,pressed,scrl)
  local itm = mouseActiveItm(stk,pressed)
  mouseResetMine(itm,stk,mb,mt)
  mouseUseItm(itm,stk,mt,mb)
  prevMouseBits = mb
 end
--
function BOOT()
 initBg()
 initTiles()
 initWalls()
 initMiniMap()

 plr = makePlr(WORLD_W*4,WORLD_H*4)
 lastx,lasty = plr.x,plr.y
 cam=Cam:new()
 cam:update()

 inv_cursor_stk = emptyStk()
 invt_open=false
 invtScrlRow=0
 if DEBUG then setDbgMode(true) end
 npcs={}
 frm=0

 genWorld()
end
function TIC()
 frm=frm+1
 updFps()

 if not plr.dead then
  if miniMapBig then
   drawUi()
   if keyp(13) then
    miniMapBig = not miniMapBig
    if DEBUG then plr.x,plr.y = lastx,lasty end
   end
  else
   if keyp(13) then 
    miniMapBig = not miniMapBig 
    if DEBUG then 
     lastx,lasty = plr.x,plr.y
     plr.x,plr.y = WORLD_W*4,WORLD_H*4
    end
   end
   if keyp(11) then setDbgMode(not DEBUG) end
   if keyp(12) then hurtPlr(20) end
   updTilesCmbd()
   updPlr()
   updDrops()
   if keyp(2) then genTallGrass(plr.x//8, 2 + plr.y//8) end
   cam:update()
   cam:draw()
   drawUi()
  end
 else
  death_screen()
 end
end

