From b9df1006cc17c79b970f8891c977a9518157d107 Mon Sep 17 00:00:00 2001 From: Rui Miguel Alonso Date: Mon, 2 May 2022 14:47:46 +0200 Subject: [PATCH] feat: add score assets (#276) * feat: added assets for scores * refactor: modified scoretext component to show sprite with the score * refactor: changed all ocurrences of scoretext to use score enum as value * feat: extension to get value * test: refactor score texts * refactor: refactored sandbox for scoretexts * refactor: moved score_text to score_component * refactor: score enum to Points * test: golden tests for points * chore: unused imports * chore: unused imports * test: coverage for points extension * refactor: removed unused points and changed enum names * test: golden test for kept scores * Update test/game/components/scoring_behavior_test.dart Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> * refactor: score priority over sparky animatronic * test: reorder tests * chore: removed empty test group * fix: missed dino desert points Co-authored-by: Allison Ryan <77211884+allisonryan0002@users.noreply.github.com> --- lib/game/components/android_acres.dart | 6 +- lib/game/components/bottom_group.dart | 2 +- lib/game/components/dino_desert.dart | 3 +- .../flutter_forest/flutter_forest.dart | 8 +- .../components/google_word/google_word.dart | 12 +- lib/game/components/scoring_behavior.dart | 10 +- lib/game/components/sparky_scorch.dart | 8 +- lib/game/game_assets.dart | 4 + .../assets/images/score/five-thousand.png | Bin 0 -> 16291 bytes .../assets/images/score/one-million.png | Bin 0 -> 18689 bytes .../assets/images/score/twenty-thousand.png | Bin 0 -> 18361 bytes .../images/score/two-hundred-thousand.png | Bin 0 -> 19284 bytes .../lib/gen/assets.gen.dart | 21 ++ .../lib/src/components/components.dart | 2 +- .../lib/src/components/score_component.dart | 92 ++++++++ .../lib/src/components/score_text.dart | 57 ----- .../lib/src/components/z_indexes.dart | 6 +- packages/pinball_components/pubspec.yaml | 1 + .../pinball_components/sandbox/lib/main.dart | 2 +- .../backboard/backboard_game_over_game.dart | 21 +- .../lib/stories/backboard/stories.dart | 7 +- .../sandbox/lib/stories/score/score_game.dart | 44 ++++ .../sandbox/lib/stories/score/stories.dart | 11 + .../stories/score_text/score_text_game.dart | 32 --- .../lib/stories/score_text/stories.dart | 11 - .../sandbox/lib/stories/stories.dart | 2 +- .../test/src/components/golden/score/1m.png | Bin 0 -> 28600 bytes .../test/src/components/golden/score/200k.png | Bin 0 -> 28647 bytes .../test/src/components/golden/score/20k.png | Bin 0 -> 28593 bytes .../test/src/components/golden/score/5k.png | Bin 0 -> 27555 bytes .../src/components/score_component_test.dart | 202 ++++++++++++++++++ .../components/score_text_effects_test.dart | 75 ------- .../components/scoring_behavior_test.dart | 26 ++- 33 files changed, 443 insertions(+), 222 deletions(-) create mode 100644 packages/pinball_components/assets/images/score/five-thousand.png create mode 100644 packages/pinball_components/assets/images/score/one-million.png create mode 100644 packages/pinball_components/assets/images/score/twenty-thousand.png create mode 100644 packages/pinball_components/assets/images/score/two-hundred-thousand.png create mode 100644 packages/pinball_components/lib/src/components/score_component.dart delete mode 100644 packages/pinball_components/lib/src/components/score_text.dart create mode 100644 packages/pinball_components/sandbox/lib/stories/score/score_game.dart create mode 100644 packages/pinball_components/sandbox/lib/stories/score/stories.dart delete mode 100644 packages/pinball_components/sandbox/lib/stories/score_text/score_text_game.dart delete mode 100644 packages/pinball_components/sandbox/lib/stories/score_text/stories.dart create mode 100644 packages/pinball_components/test/src/components/golden/score/1m.png create mode 100644 packages/pinball_components/test/src/components/golden/score/200k.png create mode 100644 packages/pinball_components/test/src/components/golden/score/20k.png create mode 100644 packages/pinball_components/test/src/components/golden/score/5k.png create mode 100644 packages/pinball_components/test/src/components/score_component_test.dart delete mode 100644 packages/pinball_components/test/src/components/score_text_effects_test.dart diff --git a/lib/game/components/android_acres.dart b/lib/game/components/android_acres.dart index 489dc2e5..e7330c1f 100644 --- a/lib/game/components/android_acres.dart +++ b/lib/game/components/android_acres.dart @@ -18,17 +18,17 @@ class AndroidAcres extends Component { AndroidSpaceship(position: Vector2(-26.5, -28.5)), AndroidBumper.a( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-25, 1.3), AndroidBumper.b( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-32.8, -9.2), AndroidBumper.cow( children: [ - ScoringBehavior(points: 20), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-20.5, -13.8), ], diff --git a/lib/game/components/bottom_group.dart b/lib/game/components/bottom_group.dart index b4a888f4..c13f21be 100644 --- a/lib/game/components/bottom_group.dart +++ b/lib/game/components/bottom_group.dart @@ -51,7 +51,7 @@ class _BottomGroupSide extends Component { final kicker = Kicker( side: _side, children: [ - ScoringBehavior(points: 5000)..applyTo(['bouncy_edge']), + ScoringBehavior(points: Points.fiveThousand)..applyTo(['bouncy_edge']), ], )..initialPosition = Vector2( (22.64 * direction) + centerXAdjustment, diff --git a/lib/game/components/dino_desert.dart b/lib/game/components/dino_desert.dart index fc601791..b3ae4ab9 100644 --- a/lib/game/components/dino_desert.dart +++ b/lib/game/components/dino_desert.dart @@ -14,7 +14,8 @@ class DinoDesert extends Component { children: [ ChromeDino( children: [ - ScoringBehavior(points: 200000)..applyTo(['inside_mouth']), + ScoringBehavior(points: Points.twoHundredThousand) + ..applyTo(['inside_mouth']), ], )..initialPosition = Vector2(12.6, -6.9), _BarrierBehindDino(), diff --git a/lib/game/components/flutter_forest/flutter_forest.dart b/lib/game/components/flutter_forest/flutter_forest.dart index 42e5415d..1fb8907b 100644 --- a/lib/game/components/flutter_forest/flutter_forest.dart +++ b/lib/game/components/flutter_forest/flutter_forest.dart @@ -18,22 +18,22 @@ class FlutterForest extends Component with ZIndex { children: [ Signpost( children: [ - ScoringBehavior(points: 20), + ScoringBehavior(points: Points.fiveThousand), ], )..initialPosition = Vector2(8.35, -58.3), DashNestBumper.main( children: [ - ScoringBehavior(points: 200000), + ScoringBehavior(points: Points.twoHundredThousand), ], )..initialPosition = Vector2(18.55, -59.35), DashNestBumper.a( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(8.95, -51.95), DashNestBumper.b( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(22.3, -46.75), DashAnimatronic()..position = Vector2(20, -66), diff --git a/lib/game/components/google_word/google_word.dart b/lib/game/components/google_word/google_word.dart index 2ce68263..af1faea9 100644 --- a/lib/game/components/google_word/google_word.dart +++ b/lib/game/components/google_word/google_word.dart @@ -16,27 +16,27 @@ class GoogleWord extends Component with ZIndex { children: [ GoogleLetter( 0, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(-13.1, 1.72), GoogleLetter( 1, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(-8.33, -0.75), GoogleLetter( 2, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(-2.88, -1.85), GoogleLetter( 3, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(2.88, -1.85), GoogleLetter( 4, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(8.33, -0.75), GoogleLetter( 5, - children: [ScoringBehavior(points: 5000)], + children: [ScoringBehavior(points: Points.fiveThousand)], )..initialPosition = position + Vector2(13.1, 1.72), GoogleWordBonusBehavior(), ], diff --git a/lib/game/components/scoring_behavior.dart b/lib/game/components/scoring_behavior.dart index 3e757eab..e8f51e90 100644 --- a/lib/game/components/scoring_behavior.dart +++ b/lib/game/components/scoring_behavior.dart @@ -12,21 +12,21 @@ import 'package:pinball_flame/pinball_flame.dart'; class ScoringBehavior extends ContactBehavior with HasGameRef { /// {@macro scoring_behavior} ScoringBehavior({ - required int points, + required Points points, }) : _points = points; - final int _points; + final Points _points; @override void beginContact(Object other, Contact contact) { super.beginContact(other, contact); if (other is! Ball) return; - gameRef.read().add(Scored(points: _points)); + gameRef.read().add(Scored(points: _points.value)); gameRef.audio.score(); gameRef.firstChild()!.add( - ScoreText( - text: _points.toString(), + ScoreComponent( + points: _points, position: other.body.position, ), ); diff --git a/lib/game/components/sparky_scorch.dart b/lib/game/components/sparky_scorch.dart index d461f95f..434e9479 100644 --- a/lib/game/components/sparky_scorch.dart +++ b/lib/game/components/sparky_scorch.dart @@ -16,17 +16,17 @@ class SparkyScorch extends Component { children: [ SparkyBumper.a( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-22.9, -41.65), SparkyBumper.b( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-21.25, -57.9), SparkyBumper.c( children: [ - ScoringBehavior(points: 20000), + ScoringBehavior(points: Points.twentyThousand), ], )..initialPosition = Vector2(-3.3, -52.55), SparkyComputerSensor()..initialPosition = Vector2(-13, -49.9), @@ -47,7 +47,7 @@ class SparkyComputerSensor extends BodyComponent : super( renderBody: false, children: [ - ScoringBehavior(points: 200000), + ScoringBehavior(points: Points.twentyThousand), ], ); diff --git a/lib/game/game_assets.dart b/lib/game/game_assets.dart index 1b8ae0f6..d8532c50 100644 --- a/lib/game/game_assets.dart +++ b/lib/game/game_assets.dart @@ -124,6 +124,10 @@ extension PinballGameAssetsX on PinballGame { images.load(components.Assets.images.multiplier.x5.dimmed.keyName), images.load(components.Assets.images.multiplier.x6.lit.keyName), images.load(components.Assets.images.multiplier.x6.dimmed.keyName), + images.load(components.Assets.images.score.fiveThousand.keyName), + images.load(components.Assets.images.score.twentyThousand.keyName), + images.load(components.Assets.images.score.twoHundredThousand.keyName), + images.load(components.Assets.images.score.oneMillion.keyName), images.load(dashTheme.leaderboardIcon.keyName), images.load(sparkyTheme.leaderboardIcon.keyName), images.load(androidTheme.leaderboardIcon.keyName), diff --git a/packages/pinball_components/assets/images/score/five-thousand.png b/packages/pinball_components/assets/images/score/five-thousand.png new file mode 100644 index 0000000000000000000000000000000000000000..d373e2e1ef08c58bdf3533ece59a0fb8f8683e10 GIT binary patch literal 16291 zcmb8WWmFwa@HdDA_uvizg1f`Tg9Ud8&V}Hv7f-O@4#9&55AN<4cXxNVT-=uD|GxX~ ze%TLO=X9T6S9R4?*K}9UnVAk(RhGp-B|(LOfx(cM`=Sm50|$D?TgdS5b&#J%5)2GH zjH;rhw5*fjJLmrw;p5|z5fPCP5>kh zN=8gT@Qy!XV-w*MP>_(45)=O~MaEB5pC~8^@$vtU9c*mu|9A79|G(^z68&$L|I_mw zkQ0+?Ns+}kkhG=aulHad&tN_5puIwnUk{NFM=^8#2rX3p^WmL}f(TyrkzX&7U(b;* z<}rHnab0zZndm;hi*B|trt5KR)JWcOeG&l=GbOkj_dgvNnAcNe3Euz4_)_=|0Wzy7BiuDCZ-C@;%Mlq96*-N>KFDTwh2D9OpOF){IQagmXb;Naje(a~QP{xkm0 zgoTBD2mh;n2mfF6Jcsx$dY(mm@A*7~_&oJL%?ZTGB8=xTL`Wa9zAW+c2%;bx`7;>t zc?j`&0P(30;i(tlsR!Yy8^PxrUZDrp(O;xE>yOvU zKMR=rU#Cm#Eg|9Zkm{(2VFuTozcsw1Z9o&EA9D9sQeyAJNdngi12?xrr=69IvoU@@ zGg9K^jrv^nnb3lb)>=odPvIO>lH{_(@FLVhz;l;RpzL8^g#J(tOoUc5|42 z2wC%KlRc}lj&(^vIvwvy;W$O@Q+BK|Z2SBq;Zdw38aaprJLN)B`OMcvhc0!gDPf*? z7nQ&p>#j0s^?0fz8jKnusaB#YU;q~E2&T>c!DjmVb<0h{!y@TSUB40&H4AtV&6UnK zv-44No=F0l8H%fRI=<)8!+{vvyrP8xTdBsiub9&zTUkAA>&r>9`7ez^=g)EIr4%&N z9~aw8GL@X&R5z$tEv@B7jcqTE#MSU~^Ps=dqV=>-PU`1{;~SZoGNY=-WuvUZJ+Pxv zYVILQFD*GB`m1)Adh%)l=Ye3Uf{=G7x7T(ZKgr^pLzNg&%R*-5721)ZKAmWN zt`my4TFOMXn~bwk*2uF*Zp+Of8>fw#771+KM6S@f8Hx?UOc_topd+iu?=KH#u!BeZ zFyVtX|Bi?wvN_O~k=LiL)W>$dqu=J@I83c;)$5*(oY~=a5zA8>BvPyyo)xkteuq) z1Wgy)eynZtiETCIIr0meF4AN1!rGaV@PZa1Lt2Y;O`x+r8T?-A&i)DGTXj4y`?ufj z7crXJ&!Xjt_J=jPnWN2Y0&OR0!`B_w@3aH{PT_a9@=uOcQaJS4i*l($|MN~16hqj3 zGN80hlkOG+6#A7dEKN6o4M-_6uqGn(dH&K!50jLKG)fQ=Y?=drz%^3vgC-`huttEi z-U89Uw(#7W78h4rGG|;XID8p+|JmJT)$z{%?JelzH*mT|z;3Td|H$Yj2lqQYuO@!mVQkOMigy?ANATP_I4}NO|Ey1XE$t&~ zspF~Q2)okqB=m#?=Q0{vWH2vus2u|fTw$1^!Xt$U0NL7VcmpaSh+%Tx&xya(V}DW< z>5FXn86TzUFNZzJ$OwAN+C!(`Vxv_QxhS6vCKA!-KH#PK`5EO&Fnk5!K{~1!R7$~R z*<7%y>vgOm;7092LOqa`jVRjGkCO?WSnTvo_8Ry{? zNu#_7#zQjhAA(w-Yjtn8&@YoaIdIeVZd-n5D+KOt3UK-UqkVcgdb-dyLC3mp)U9n2 zK-)>GXIbk*kA_ShF&4mXGM$EEcLHdS^&kXFa$@nn3@jRu4$Ss)Q$N@nFK=0#N{XaA z5oJhSd4(f7GcYarUsoW5I=K-129g&VT+?LR2`Hd7N18vUS=}2=lPy=iao%7V6`fNl zg!LX)hD)me7p}wM#wgl-m07;>Kno7OHVkXBGB`G(1VV0k*e5Rb9<&ifzBa0%iuBJ* z6ggbP3{_j^gjEYFFgdOce8!Ia7%ev~#h-vH9iTRzc=ox-q!s5~lhVqF;6Yo{`&mlW z6Ac{s31BlQ^4Nrck>YnwTl)>Kz{-v!@8_Tb4^J}vZ;hJ5*H2n^BRS=5K?dH}Ga-Lu zkNE6z!+M@(7iQ0PgjhUp+&Jj@)JZEz^v5rzcB%^{8i}!?ZeRfO(!9Nv`~?@B7U%@) z?BGFL+dIj@J?XC6WhvD?T2a{BEqt7d-lkD^pn?5qXz_!YT3&9vqXa0gmX*EitL3co z`l=}n%pSQQ)6aDy=Czb$ja))?(3|H5S8D6LJ$;19a{FQC27gfXSv%Xx4jsw2r{r-i zb~UY3!>a65dl?w8u*V@4Li_wc5evTeteLngDGQ*@;x&yrW`aQ4{rQ7bCRtrn7G8AI znJWs!Yt-5om0xu#S=J(3u0fAM>FvW_mXM3n+xXs0kpADvd;%$ZhkQFXXAK>$KC_L6 z-hNe))tPZ@eL;;Iu(X5h&%vFqQos=mk&+Zp8diu9I?cf%SLYR;uaWwY z=>(&>9#g}UP-))cRI6uE(Du^)Df3dWQGeBXGbO_)sGFT*dI^JLT-f%*pElRxFD+vu zk}7WQ+k)kFl)L5Y#gS13czT+rpj9%w&CYRqf^0dn3JO6#k4xEp-;ZlHw8nb=;;3Dl01Q+JGKJK(Q1U%HwRXJpejh3UVTms?xy z>f3QN(U)`&N%VDCA^vF_(L7X(?9N!Z1ZzAlOIE&wz}_121T*`^#GLc+djNAQKj#E6 zlCh0E>drXr>95W6CF&0%2mdJh9talp{HkVz&lF3uyDVBP+=m>x^ihb|(!awaV~~^(AEdFbz7+;4ZrA&b``b-nUzm}lmHPy0BFaR%%7csNHNur zo<+@7UD1R46aa+=iQ9#8wNCypm8^b=9Z4BpQYvyWATMHM#`a%% zvjtvbE79g`o8fBQL_eXLKRqD(3(3n>F7me*!0hU!9g7= zLPLhXx})V>M15^v(8!~^KP50hQo4yhpuv6$e4Nyw5RG@8=Y>~+ckVsW8!^ziq)hLE zwc(~~@jgKy$YqHyf2o@EB8VQSNp|Es%te!mx!zSp7z9m-aCY(J=Gd=Mvxir#-d|I( zuyUy=BED7QPEL}4YY0Pu*zSSB3B#Jc)XBN5VN6AcHlN`+TQa#iY zt`n)Q`(x}$43(9dqMo+4u}?TT%QPq~-Q8<{QCfIDi@o%xeX@j--j&(ByH ztl^k-AqMR_L7@Rhy7}z;XEcYG9QqtaifiDmi$ameu6dEtt>c(|v*lf9EzFdHyvcnRP?^K8%im~dOw~6=nSD3m-xq<)bwYkUB9`0s zyIwer%O7FKApdcFQht8t;)C>_>87`wf@({81QFY!16@7FcOye+<+^*_$}XFHfJ@Ds z{3=V-&lC@vehZYRe%7j5It_0DUhJ-lrCDKTaUUej@}%>SBjOe|gqDrBYtbjO z`l+O-5h%UjZ_>TLY0HNs#mnoX=l`@{;p8+wmdHRi6Hl=EmLnggh-v@tz`3IKq9b#o z-O_NJ{NriI^YgLD!QgUd?YxogMSFuw*x;LNPc1mcW?Sip1982Gp@iHoXA-A$8RW(- z`~>oi*USiXCrn^?0f4%*X%5`YxkvyjA})?#I?)yy8VZ%!i!JVx?eey$Y2+T{if{|g zTr8Rj4%4}!()kjy8y&;G@uvqVTZB7Nqkyb!DqR$h42j!jN_j*3*T8;CN_&*w(JRir z-VrfJnes#-a$@daCdb)DIAR!>VP+E$Zv#Z3c4zF)i%^w&?Z90vY>37P6hf;Hz8A!Q zKmZ=t-wb}rf)YT`449WM{a_~?Gy@U&cz|!~FG?$To2?tEFwA^=*<_e*Jo`~CM8#^| z%2=q(|6*{AsP(js+Fe5WF_bDQSPAZ{RsuF38g668D;-Kp#AAP4wd&s=5cc8neV`V3 zAT62mxHV%ZX+6|CV#GH2=29Up3+(W?Ij*l(rWsF!r@xf~@JEO2_U|wSw7Nt>KUWB| zwgsJqd3$3mXdau`#;kzJ{en$K9{TN&*|%klf;XC~p|BV{4bN#(fh8l?s((fbIO$g@ zuX&t0*f7iwLv}A-yHKRTBGY&A(7MZPN8ui}s&thVNHLecI_(F2A(jO6nJr4>E|5}n z0~FS5Te@t+5>t%eb#nkPvSOZ8xlv=GU{*e}IAH&k%1fdNqa-d9HJ~4h{IVPs!N-g5 z2b&6#{$GDrYUFvt;N@79236_%++Y@}>Fru*Hy``)zt&tR+22e`x?7(8w8FxZ1;Rl< zG+X;CTky&y+Ayg<-Y-H)C40ipB&iFovo4^|wR0<|@l}5T$PEf68cVSs0DJrurV6#W zD=RCpx>k!CMbb#vvL=e;4m%+Ob|`t45UVg~tjT@!CfsCGrM?}`rsJFFYh z3vyE>_6(-n1+mbE*#)ShDlS)U)yff4Eq~fu%>Z!iihqO{IU$at+El1yvaC%_&4B6_ zBrR32K9oKZelR!1Y5-uxf{u&KdF6ZUJaHeVLiFUuU3{-R@P%$^mkqP&k?t<@A?7I^ zf)ZJmAeijH*i0p*ocrAD?EJx&mKIFhmX??sKE|yJgs$1pgA$&>Jc%4(d8s3J)rB%O z7iwY>bi05l6k)tgiIp2oEG8WH2~lCXJ=W4E=bD z=<1qb{*+%+84g+KCCj46q_&zI@H|(7{Wa9u_d=#1x0kgUr&*l9n;Mk06S<{am-Tiv z8%l_gy>v-=BmAn>Vp&zZQ2I$38n*3w%u%$a$7JI3Yh`NBRc3GvKae~MD^5bkJ&?JOfC zo)D=X(euR^RFs##uvK&t5bh!B?4_h7+K}-cnlXuIJ9eX>QP9y!PEAea1T!<2tt4HR zbW;}DS?!lF#XihBrVm_^#tryh?8hd35J?x9LTikB&f3AeWP0s3R3Z25i)5z=cnI%6 z$|{iUZh-q~-^CM4t#YlXWWm=LyfYs7d$L?<&HXonW{Q?(65hwJUzxxoWv8%3hfRSj zt=B~pgCwqO?aI>(yJj_YTdb>+5C!Ebzvbz*PJk!bk7ePGEqSCfUd`m|@34tW%gQ#W zVBBdcIeR*SR;tfrbp)!I3!3qT)?GXhwBhA?2Sf*9hkf>1if#p@M4l#1(_^N8?PLXn zX4DUKM~;UpPQGOSZZ%={r+H#^{5I#gn%hcjh zb#$juyT5u7X(p61k5pWhW)w(V@)hW_Dnbni6HKQsAWe#UdkQsVw zY$k|l9{s5oT6Ns%{j!cH;2P}gIqd^Vg~&!0woP|o>Uw!FAz&gm(NK>|HkKl;#`Nwd*@9eCs zV?(sAiPff|ujw!XAEuNvT$!X5r%gtk13Z@fs2^?^HunbcKE-=2?}N-Vd<47i3CtyW ze9nIOQ;*p~2f6?wv&1JLot4L%!Zf>60l9R^oC&iy>pLCmumf-{>;`>&I#IVVAM@aK{>`1%|dfJDgSmG_4SM3hZmW z95X^V>Cz@4Cs0(Nv8|d|O@cShxD;ruh>Uf2_tep8RG#Lr)aC3C+~sSNgpf`p7!m9@ zf=Y-b)T5l`$DM(;i}X@+%&yNtSS1O$Iv>@iQ!3VK{56=$n_7uojI1sy9kL5d$IoUG zcXze5vvuYCX};ZGaeG<)RSwfP#i8-47be@IyFIK;p_oA)JVuF+6CW_Dr323J5jOZw zi|%I4ujk#%lY9exZZ>43ZOmDM7@YS~?Jz^NFn@75B|E$bO-ub*5i-~v=Lv;Q{~p{R;<2HR zLS$f{SvWLiI~-nXz5>_ciiLmjkMKL)zrOn(F)Z1Hzn~|nW2DpAyqFa99ID2jc?aQsc#hr&6!S69~cby@e2=A2QI2EoG2J$f?*G0W?@51efZ? z@s%gyuopTnZS0&IhYt3+VWnL6AH)>XuLS`zl=uT|?38pRa~{5;a(L+Hcn=a6n+#b~ zK5!C2Dtab*3OO%RLS{U0I-mA495Ew!cxZRRG+v`Qlr6NK zA0z6jw?K_OijGNz5c(&Hg+av#&?@@?Tys+8y{S5><$yvJ#NdC6z4)<<3ix;+6LLk( zp!p*Y#hU*H&uG{f1L65@;LT6zgt~&cce4PyxQaVN3(CD&5U>&>F(GG<8pWTBOxjj= zY3$4}(dYh$Yr^$-*thm+0TD-2=^;)YdEG5EL(o`Cg;J_Si%^)Nl9$&JO>Cu{yngLs ze;n3Uoaf}#;c|c*Ne$#rc5%*UcC#jRqf8gc`L5Qtrw)V!f**74rcEjcCTsn%>nK0{ z7Y%?XpZj^KtRz3s(&!l3H&)koBzZ9!XS%Zc9pIT*+2k9bKcJAg#JJYuDhK8HA1o;D zv>}K*0%6;*k`KIbq&hS~F)lJ{FKMv>)`R_nS#KL%A;#eQ56c-xAjG=G5GQ6Pc340y zv__|U{_`i@J!N}aK0X!u$$6Td9h0Gz3a1qkSDy9U067}BJ(O1QedZ7MwJLt-qNI%K zaLRuqaVE3=1dFxIDYt78N${cnfrz^J&mEj>Hd!Q}A!1^(yQyR~+(3fso{}(fkY~4? z=i?~tqkj*;s}*03^Q+{Kd#U<=gC-9il8U}Ghp-1Gt z`Z-G?^a3dZXg6Jv8?PqK2wl-bw}}3>g>?z^jGQt#o;J*7)>S;%jQd!tD;<$3I?$an zISt*dBlCC*(Fe;wlT&M0_>B-Gv|kEqUzh|u;)M{*O@V$TI$Tt$AZu{wNKYAJ5{87m z2)(90z0KauIt-7%sxn7((O(8f{5jXJu8D-q#L_3TUPSkbaK8xjPbKBCx==#P0b3T1 z#-YG(-F6sjwI8;1Ooqvm_~UtWLAXl!bl%{VB#r6izn{dXwB$htNf;uN*H}HQ$XGrH z)sX!q!f$K3#q!xpn=_%o#eUlbZ39ErEce2NIDUH-iuvTnHgBh?5tHy zcaB%!OtQ^vzG6Ep9pMZFBP}f3?DenUk{oHRoFyJp;g^?isC=a0!xq?WZ^y`;VR#zM zcNSRnrpPomOzr|J-0be_XwJKl%c<`GjS_m3?SmZ9Ra3*ZZk5R$^t@s6{yv2q6MT<- z9Qzr<|AM-obY?au3d>bG5nQ}P-`LvR%27V2f`?($``e17e@#t|qW_`3pv_L(=w>}s z#0J2_bF@tb^1^>Y#huKAXAj10)>U<`jti-w~#w639YvGLJ z{)BL8)b1Q7q4Asp*NE+c3io5PI0Lg5{{1e`qENWVv8%a8z0l5pnAl(K4#JsKRF?G| zmy$Hmuo4d_dCl@(5_O~;C@SvEzS|gD|j`odbI90nF}&H#*1VV!v!$&M*K{9`wx$-#t;-`aWe)mg4v#%NF{QNE(Y4oEj5?gcTT%!zE-_Cx za?T||n|~|BC~w2oLBjH}bx2JiZn8bCi9cCg&G#f+e5Ab=RwhdX#~$~3|1>A0O~Zbg+x{ur|E+Oj-Jo%EjTc7{NQV;P z;@gx{HI5RCIM~cdGO{*(4~|C!!daiv?4==kOUAZu+lTDg}YEWZ;f->v^9U>aHSn(G>xKF>7I=0Kn;BbkQ47J0!rKjYvt`a zba3F-<72nTBF(g`M|aZleR}%wF$iad>dV*sqVI6lWSey8{7O=Lt-_WcTtO=ne%)PJ zprgkK%^r!4%sVP`B4Yvgq(R&dE0C>rwD13*MT%43YMoLEJvT&L5t{+EK%Ws`-Q5St zE*PVLen;-L#E&08Y8L?tPQ7k`M}k$7gJUriYklFWgqRqPp3l5x`I7nH&8(rzsKe7W z6$YA9;7GzX!x#7KX&glddC;S>RY$fbJ4;UU!wIueX#MDMp{2az{+egvO#W%zNzbaCXc*=T+}SmonFm$7x*B$leTk>l8NWYn-G;|H6yL&s==R2^n88;QF=4e zXEE;Mz-J9A#>Nm8+G51}-NbMF_&$6r1PT!c=@N04M z$r6ijUt0;v9i-(`>JnwHi7g}6^rfvO!lWhU-?Bd|ujS)iwhQA%)M$9}@e5HtZ)_;LmQ`D=db9)0XFMy}n`{JQJ0(*9N}nwOqgJ%dXHbKE-d& zf*N1xi)E)GB4 zzD6N8m{d$iaGrP)eoayHwKL^%T3bVG<0CSLrL-M}sMQ^GxcYT%iL0In{iY>qCPV=e55)* z{=L-tNJ`UpM?kQ6I{yCRxzeUH#=QTr|C)iwt=P&gWDL5@u^{IZ-p}MsAXH9z^;$ zaJN|8x3SHJln+p@68D1Jo|#Tz)jw(Hq@^bpO~U%pHdj2*|LfV+z|A|GU4E8uWdGm* z2SV7-5gqhB9SJ3LWp=({$y3yqe|u%3WRoZ%+;Yi~*T+Vg)60-rxmjZS+er$opOj8n z%}&en^vRC*Q6l9~U=q_>3*o#$k)ildqy>p@YFv^@a2}uy9jNN>*Nz(6(bz{B)AJpz z3bJ^#mcP37%InKd)(U9Bapm;i=c=^B*qA-s$`BG-T3B@G86Sx>C26pxAbV>ToRuOf zQB8QNkLv!@gBx%Q`^+}gg7t;DO1HUp`}D?*-gMxzx={l?h1fNf@5VB*oi;b*geuUO zt>8p3%{_#7n?lCH=ydu}z$RmVs~?<8@%Cf5XO9Yf96vnw);BJv8ww3nGrHY3-y^sp zCMHh9v(-3)J9Zc?4$?bieb5J;e)~shq@gQ4!~ZdMty>vLQOlF=ASlhKZ08x~QbXs1 z*u?gq!?8N>p_Z3rB7o|Jj!;=ZSez2i{s2>SHrr_*z4EpBUfMhX7WIRIgwvxzN>K09 zr8>BPWD&>eD3`fAAb404 z{vo~h)b{@NjqKv=Z7Ex~(DWxOMf!kHjs9MtsRKpkVCsQKUOq`1(KFIQGCAuvP)Gs5 z4J0hnS@(8);QyJa5k0FH_A{0zp+N@^rc7wWY3R8y$UT!XGhi-YtLv_Q*G{><3rLaA z<88;ATtEK<@lc2?9a7ZI@AT5Rv+3CzME^*%@}v^|`r5c-f?QPGA@AZqhI%pTh-0bh z?W*WSz4!0}d3GG^eXxa>qR;k)4CB%x%2d937(kg8#*v?|4gEVFiTs+%+u)EJiU(dYm;vY&Z2|~HF{LG9 zeQ9=CSG+CQNqRQaL1+LCU;<)lJm(@RFTReF7Gx3_KrHgdciOs2x>4H*E7S2Qs8{6; zCNkPtQ{aY)y$X9~MMvzJD?;FhJ`UEusw=~{9QhRmB`x7WZhk)N-&|b(`I4-%lFo}h zqlpmaa(Oq^L&*`lQCxPJXql>}|20t+z8Vt8ad_ z94K3O!^THv?&^@zwiy8jS>&*69mGmqbJMiLxp>b-qdJ{qO?4lZ`9}@1?G-v3Z%wU~9 zyOOx~6XW?lG(mqvTufMu-K)lV6Bf%T4$nDX=C?n3Uc=LF7&nmVf%aV`T7twP(^#CF zLvRuN(mdEgJE0SpWek6J|WJi(Y z6N$(+GYaGU`ZKx>D>)^QXK^nr=#de!=Pr?q#5jR&0W?flRGU-o$SkBSwA6i-Vb#4;EhF`j~%;?$Dw?sMtYPW*p>8B zWNYRM0>#;Ya7@$6Lh(kyC#$F_27We`7V*?cNRPK(Pz;UtgR+ zaVrEU6N@%F6#a+K0D|oJ_2)ox?#{>$gfB|%751kz6MTkFiZncaul$Ln*5PVJSBn@* zLA7M>ipE3WMB8C~E{*F(#xEO%mube{2Gj)gOO_xIX!zgw**&_hmn|DRa4(HD9x$h% z?oafqYc`)0-)!R5V;$R46ryhBIfUWp{%2%7i&TT>D?>Fx>cOW@>~wUernyFyF>QY@ zcjya;v$HLg>ls8&Jd+8}#Fb(&EHhZ|{j>Y<lGwME)50jl8Jr*9 ztn7whLoBz}XeGhyh{b$ZHWe`Yu9NLb<#v1WAFT)A=7cHrCF;KRqq%qe$o2kTY!VrA z3KvGSTdpU*9j-d)G69lZWj|7L{}J_G?03hwTK+GaIL410Ql8#=-^b2HL^$Pu#H-P) zyM%0*uyh5N0Nz23;^(W~{?6d2nHS8_SdMFwnELf?Iia?F^)8KdO3g{6q2e|&nFcBm z-uu)^&QTIs96>M@|}Q|iT9Y>=(}-7 zKaaV`H>CIz@7kl9MI&DP4AaYwGj3{1=@MwKS!06HJ9s65V>_OO`!{6fpl#Q#Cy8)A zTq$;TN98+iQ~_8=%C@1V4=dEki;gC0A%feuL*y%kDWIgK^qc)cc+O>gawEIxkl+>{ z%s*-212KylIL5nUQ^9N;II5^0O1;pIx4PJ7!~bRfv|_K1fU20FS_~r`wk1!m*82W1 zNIx&@Y;y3KW!Pt^pw(|@ zp0@k2AWKDeRFbR4zcIWiLzk9b%uBRur9DC8&u>~p;i~^pY&@eum4 zZTGq~A^5evc)X1eJ^w}TD>el;zka;PXK9n-Frs=944^&d%ht2)Bdg$N!V;*Dm-ou6kXvM8!L9>u2** zSV)zHn@RD5sOYsfE_6|bmD8)xoP zYcIW|D(mrA3Il%&RWZjf z+nn_ED3!}`+GsM$5FZ!RFtey1TT-lR&C6LZFsU;wX=Q@(aPUG|h<^)tML5Ca(^kOR zi6e&>`qXM2P4X_?wciE!-x**w8e_-a75S5~+r75CzP-6#cy_vWj`WlJOGM4<@=e7z zWX+qXdhsr3(^W0xd1BlHHbhO}NWYYq(`{Ypw*H|3GkLuRJ9TFR^cpK-tN7~H&5|Wc-Pum%=*GkJ@RsjI2#qJ2QCUQN-`Tl_6SU(`kNb= zKq3SpqU0omXq0T{vFJaa9|v5u+86+C^hYmw-#)w@=)dVq)Z4C?ZecVZ51lDb;R`Y! zv9kHjHR}AG>}Oh| zQpM5ukB@4uyx5*T2 zf&6Y9mw&8^fblORKpa}LB9p!&VSo3(k+ZEcT4JBB)0))?Co6YRwKs>T$ml%6cii!? z+Q1k=G@njNGq(6N&)3KkOh|ITm#<4so3WpBpR^&fDE?B;vKAAV#_^}U^e^SsqucE0zcn>X zM{2$=ItFT6jk;e~Iu>*8S9FWNiHI6CL3&p7<=I&XVhTN*+FXnV%WGv8m-m4LY;6U? z!t~y6cCM^CC_3#V#~(T~ety4XXjfT~9oPS}aQZD@DOm@p=Ikntj;LqJIP3aGB2-;7ric#bEZos1X*uU3b6EfXX8dmoM?a3)gMGEC(&1XDO2F$Qc+ zD{m4OY^QMBH~p$Nr$;)LK-IVXg2!vF%wDo_Gyr@+087@}R`cz~oPmOmG6N{<>OC_0 z@h#oWBvwLn`oenGXbL%J(S!ZZhz|is6g^`7c*AJfTbCwoD#QlNSw-YRc{ko+iH8P*+iLMj)D6c(C zp9}7q`3OV`4o)-+4z&8V8gru8^#vnOv+anQ+`@o7GZC47P1U~Q&HfcH3m2VFd~Z*( z|FcLlE)HosVb z%8CR16mPi+`c+ha$Gb9mF|j!|ni1<11cR0lgoz=ovSx5&zSm1Y71rZ|=NFNMdAh1q zg;KBLx*(Ok==QKBW)v@5zq6?lhll%NhPHIQA)e^6*Q12CQpSly(QW5ZXFH1PVFJ@H zTQ`3JIgam3LqKlAcjt0?{dRr+e1BlMijr3~;MEInu4I+2SI#q&>q(;;{a}0MVVCrg zz>oZ*sAhp<;kaEW{%Kyn#be3ar9XqxxmM@zjBHqI>q))}1@Gd^wa-Y|wo-V? z`!A8|MHWd0xvX;lSg_qOSGwHWZ*4 z?3mg1c6NYq&X$(Py=%OWhTAEpADh-*6uN;$THURQ=AJs7KOpH~Bawwrc$Hj*PdqY3 z?(Xupbw2$yti>ZNDECJL12ynfm6f8gT^Xel+19lJ_(E5F(E{)k1DQ$~1HNq`L~33K z2FF^{!l40FUUMSMzG3?6#tD?vW+7kb&nrZJ7=vUYc4@YE)H zS%Bdtf%t8VZ`;`0ogefog9V)G5*n2W6+zcO=Y@qK zA^p;BvfWP=_<*yJ)sEzz%Fu(W+a#09z34Nt7eQ}JB2t>8D7-56+g<#c=oySfh@aaB zN0@bwP0gG=Ckt;rcKLpvjJHzLK6(9279)#M$9nYMkcAv5*yDaUx2~|%`a-JD^8LJ3 z9E`{-R%vH>sSF@S@Iraz*OhtzxU4YD5e_hb)80q#JFL># zC6$ibP@1JwE8z+Jq|%ajDv+5;*c|{kTjt(hKK4QF2vP=`M^Lx8{C5$!@Q?RueV=0)V({DT>v;)(j!u(=)SQ z+!xri6t#a%1iX(q$C`rz)n(n1g&{=9*4Wc!VF|XYmS3)QlT%2;z(;dZZU;S)ucn=yIDLXftOrubR9gqM--rA-A z=~{Hxl^FNilgyS}D=Wg-Frm2o% zzEI+t8<*mI)=*(<6GCw)g>nmTs>u4nadU&OWC^q<`&0$DD&frNN~i*@OTH0O5!|~1 z1F-FagcDlj=o_`G$KD?SUu{M>9(9b8)~g*+eREUqKXzOx1X6!toug|#^e5@cKi|eQ z060J|`IRgj_ez2fECD0UiIbmA{UlQ-vr|Qsc4v=<8CCeZFxuc!+ONXXiIc4H4>M}K z()82cf0o#{?=1b8F9>YaDeoHKt{a(6-_TT25Lw3eNAnGOQhAQGXy z@uAJPCNr_iA>7%ZO4b)^EA|wTIqS4S;P-CU?JOswPnYA0ow41+JTf3DR|UP<*%Ake zYi%Huy`6;OEX}p%KH;%%g8dS^j{I!6hP0K&X=Y97NV&d+ObN3X`d#3V?^|lSEc^3j zctE8Sm#+#nwAeIx8-MO7(_XK=%q>#K!y1O~Jsdy0U&&)$PrV|#e-BD07 zO8{CY)5;RgHH1IIuL`#7v}}j$rwnCGpLbn?H}1a}24o*`G-{SOD6hnRi{->V5(Er5 zpUL~8P`)w>E5=KW=4rQ9H__aarU6bnokf!@qtaGIo`%C~8f9FKAL3-QZ6C6Kx?rya zGgZaek8(LUbhBM*cMYr@MQzM^hB@{t0-afHN;Ub5##o*W*^ydeb(s3U=+P_)i+2F zs^@Rnu@6U%b@ZHbt&q!ywkgZj!k|~7Yrr#);rw?0;iWe-OCToVNJtdK>|=HDo5J@h zzZ1JLTF6v(34gHQTLm(G;)w4EKipw&&D{F0N6fZp|GdZS9#w3LCXD4?mZrk(iXZ(M z&xQ}XdlW3^)~#JcCQDL2A^rk83jU7>5&Dd$u^Flg?oL3Wqw%4Wom_yqTbz-DpYrkw z*~8wC`qm_Pn7KQ=(%0=I&i@wH48>0!n@6>BQ z8i{q=Xi0K1X=VtC;8}gtd?wK-Z}b)$hgqSif4W0`{s!i^Hr>gP>iL;>ZG2~ja#|>7 zJM9nN#g+B;M=!h9qIaKkU49(bhbZQqDCP*xy@!g;$ExaA)n65{&Ev~|{z1}@*QGp` zi$iRIk(nm3?V=Ui?X_*A{=a)xp0L-ke0fgX&ZLd#00?coPW?XPipD1BMn1~#8Pd2~ z#_b6s_%&re7=wRP+Ozss=)9#^E4PJ+d7U~#`HeURt_B+*$CgxR_E?B~%%%A~)>XRM z@@`O+v~$M)9GNrvL-?MW-XmR?FU4Z@cdODumPhWw4Ki=H1y})rZv>yW&~2>_mf|1e8^{q%e20uWjXPib+q_-Y{CR9YK?|KAbkO9> zRj29sLlf{$q8O4K?bsYb#!>_LU`3=r72*Z7 zr8B~2dT8VHCR&1Hue^SKBp{PqQSun%ouli@wPPv^>z{ksiw}e8c(Ec)+K~!wd?=`x zvQy#Xr}s#j026lZkn-IR^IX~TwhZY*`CE(Yj!%m zN$Bs;zWJeS0)PvdE)L_wEAx#mODe9Z(o-_W%b|3 zb$t=c&C~0JZ|``~1p;J~T!l!f5x7vl-~~31tFJ=rF6{w8+vfn+u`9*_SzY~VB|D;Q zPHDHQpQqz_b?+y}f{ry1%$eg)7?jC8R>tphMEZ+q2g50{i3vqJ@vi#%d%1y)jq3Bb zf*-kygnd7wd&p>256r@*X&1b3IFNTJ0YS|n(p#oZ}V+}+(>id&Ha#a)U!#ogU0?ojMY-}m18 z|J&!uoH=u5XLn?Gv$Go}FZ&S#l@t{L0RclwQcMv60SJTR8xSNod|_s#MLr~LmG5<)^UVq$VqQc5y13KCK%IVA-t86h6tf8~%86GJH|sb4{#;ANJum=JP4!WD)zD{XaRAP55`)XwUnQk}yId{C{$uPaw}n zknIuNr(MW@1^y!*{=`cJnunz@^Ij#Ar#wg_2V|ZGy2eG2z6~Ld>Ui zaJJV!t)JGwH}j~DYD7<~|M zH6`U`E$F-wbWjBT;fnRpft=-teOvEfjq>2QnUqwvvRh znF-m=g>3wUEGD2xe;{iJ!dOi~IrsrSECSCYqK?L+O{btPC!+8$Q4B<(ZD&JPlTkL( zQI^tCcD_SC@{#Z5LH6?@TnrTZKOn2$A!lXagJMYe3VSkK^EyXGStSGjA`%c81csoX zqM>78VqxP7$XbM_^%i;HGiYtSTnZ6VHgFP?CCreFI?$0;@+eZUL4VV{_S2`OW_|ba z^1}4?4IKWbu>6B1-2dQv0ge~pe~36g97uis$oKLh`|{E%|04R2`l15=?Y{)G!yjt@ z-ZlP#m)!rrmlqSm+s+s7=$F+Ow&Kj9zA#>-|NMNk^`TBq`EZY61X-phVjqA|BCCcmQWCh>NjCkBW(?ZJ|7Kl z*&DF{bcVtCRgZQCQOq&C;;_je*40*fK0V%Es~h;-fmIDNCo-a4388 ziLx#vCSUIKZPn?TjY1X+qZ@r(BF1QT*CLeJzJR+{+)APR&Iz4)D_wnqyW`$L9^K8& z#9UNsns8`z>!axqdtY#TUNFj+X9Jam*e8NeBEO-`pBPpOTHp2*a&p|6M&7VEPFN?d-x0$I6{qn^7iTo&og(A)!?It;nd8~1LgH=tZCCOi zA>i%9fn7G<$ew_&i>-Kj0n)s~Q4$H$gEKT-q|r@Cl+}c%GFGM$i@A)@U7W+vKvhqo z1y(AhD}RW5K<(BMaYNaA>8qLm>#%O}bHa61GI;|g^9XyZ(GWeXQtDltF6ImA`@nCQ z$}kK%D8{(OfR17X^a0JlI?iLA;Dm{?VbNF78m>#bH~wB+64K$mxZj0jO6;cp(Krf+ z2s6aNhm|}^V(YgNd!3$1KqooXwpfO50^h|OS5ZYWd69o@J@GBY{y-J+YVLw? zdznHzP$XS`MeLYXv#&9vM}~Mjs6tl{cvsJE_}nXJKx*OeY8U;;Xp)zvb4W`QS{9?z zTXCiYaRYk`Kk#A&)nx_tDyzE}CfIyGI0$u8=!;tAFXq;(Z`#Fy`S~&}RbIu>D{T8i zGO!Oea>6DS_VbX3#hS2sQ9!5@~VEblF979sRy zaMtrJ#6lue-T~>1lkzbuXggFgfbqvGZIS75Q#&7fnZ{#-t*l@S=g@jM|4+iY-isJC zvPutggSvbeXPC3FHtBEQ4pbq@3FU?lPhoKk&HM-_n*uT^aCWsM$%sXR`+nrrieFeJ zZ#0Mc13cVO4(^e27(=NlyOJVD6^PlZvi^3+^!IsIMubSz;nZ&=D#OF*@dh98VMX6~ zv(D4I%FR@mUPk8%Rncgq!2RpsJCCQqRTbNYGR}#Z!7mJ7X;pZGcxl1Ml_FLtd~Z28 zI2>Ni8@~T>+YZYQdt9~q(HbNgbm-xAGCFLo=AWfP&E{XdEjpvhX*>2ULf@Iq)!X-( zkx(v)44?B&n&NNvB>PLbmFMO6~|lWrLmf&G+DB&(Q*$NqJ6a*S~6a zSIVG#3E6?Zo37|l9|g!$!&=JP(F< zB6K!m&>2ZwZESvU->^LzE4^`%K=sSvFD0uxOf+$%2AQT5A5L68XSR+j$Apxu+?ZXL z7!!R&;K0U&qlZH-^V?6@H^MNitpu#;_rVrc&T`Q)QBfZH-w6ah$?MCQiw!QAFWHUw zsBuDeY+SXKnL##scUQFt9(Q?P4fxRvp|IjYOtt)_5AWSjau2IRHnI^xl4mx$LmiEJ z(zOQWG0wAL@hpd_4KI?Qa8QmPW=_Ol@0Y150aG_F-e?5Sz}56d>a$2QP+tIDAA)E+ z!>pOU;u}`D%#^a&GVwmVcm!F269RrMy7M1TaE8gqjreKcv%+=@3SIHKKgWKuc-8j- zhVa^^Y>&t|Y@fS^XAJE=m_yzpN;&;$Tb>iL)@s{Sq@BO_vG0mAnljTuOS=nzWYo01 zy@9IWf5!IiRR0l6*iw*cM0IkJzfP=Q#CgO;(wbLICF%Y2uF<_sIB27p=nYX~1Yj{) zU3D*$YbTrdb7X)$ zG$%H<3M3TrU3>Tysg)xU5>m8KOY~@6laGkHAE&lp1Ao6eF&l70Nx2bYtL7@P`%M{r zp{9d27qt8b$26g6;q`@zpG7{SLSYpqlTY_iu6(>XwSN$?l7yF_%Ic2dzqk@NWa>^-wjV#LgA+qkq>7Dtvn zER-BzYgYhhAZ}>SMpo|&SrZk^@sscTj|y^bvmMzo8(@gi@utIL)55nFA78zF8kT;& zp^mS=sY#ok-AJ#{a%_n%)dhE`C|HHI?+h)_h2FbZoY&K30PJT;{qqOeZ|!J3d_E^z z5=LZbu8pFc5F>yYCW9zuH-sL}Tb(?AuX|YgkVP@vOKp*U7jDExbz$qe*x;<+YmK;i zjNQU|++R*@UTp*;Z9nfgIQuG3AOe%xuA^axP3dI(wnaKRaY_9lWjRxQQHOIwJOGEG zJZYqF?Y8HN%)t}A2y|r=%`%#ltCs*1U+pnS>?dp}x!~uulmb57bhV*s}An@1$dvoR8 zKL*JeArH9WKq&$d0H2fTy_^OPMgxfWdOjnq5A2_!L5y^5R(r^aPP@a{F`6HHiCA_F zh_&;P_{^eY`cr0ENq7@-5_NephNqPgOBz5YR zXbxVNgrg!hk*raq9>Fmzx`VxEO_Ib3FM>-o1YT7mtbR=#Fy;ub@Daj-KNyl^9uJpt z-3ol~$j^yD+Dq`}ZGrQT#&1cj$DTu~)^29_X5?|4M)#i^zbQ7+?>r>vX@HV=6~#@)B$2by!l zEB^ex@}F%^;jl&e24-PgqPP3M%GvgR{Fo@{eD#%v5pEOKM#*n#waFv(cpSX*n<^M%cD= z_^Jahkanv2WII{&6?W3AqHtD>HY^r8+q=yl+UR)^S9!7@$d89^SsWib5Vu8CeIJRi zuq_XY1N5K1ia#E)VW@f9-Z$HxFDg(mC&&%lBC(Sfy@SVxnFJEE?%9suV6SbXBo_9* zy+8(fgXc>V>f@l4?^*G{pUj4UO6QG03yf*!4UEmd>&sU!3lEszc_$CY(3(+IZ$4?} z;K<-3vW0d+jDi26w7x|+y^hbUb%Sw%jIqL@)Z_G;N2a|%$Z2Zo`$6jSQ-GmMyIXtzsmH0;Pt_xR z#8bl)rHKJl+li#gYla zax5%<$Rs=$_RQT-?sXML;=91QLflNe%qYIsa*mCx2M~>Udl5RsiSunoT@**5cAJpX zOZFjliI?SPu-qm3+zGwqKGV3rELG!rSDt5zJb8Hd`SWL?)H!3*faFJS;p|>*Lj}wQ zRs}^o`fZ)q7Y-X!#qnOw{1VR^4+K!0XmQ;JjVn>Aa8?_Zz2s28@6Fx-0Nzy+FksyAlY z4bP>>&k4)+NzBo`W;aZv=-ga^-5bG=+=l$jns*0=J4rR5j9ZN>jp3q@cbZTYf*%_S zqBztwM;y2%FKWAp{!J{ZD&O!4YU<0El^o(*^Md-LDN6WxZ`HXD7*bXnCWD)YULc$NYg{_&_hZVbokk3?A$sCKDD*-wz7*ABZ%O8R19E1H$g=E3(7!=}S6 zTRgjW7#ZkMG>`bx!qWUFH$IylYo|b?@)=rzt!9^`{aV_mBrGpse-HGPKZad1x0LO- zt4g5W)k|cO`S?tfmTxs)^uhTJVxAnfuk(moT#-gi*gmQ|3PzNmNWO(gI<|M6^|Fj~ znhX@Pq*6Noa4tor6H%%yPd~F0_qd1rG4tC3@3e>NSLAlrZzBx1CGzy=PQbpioQ`}y zB5Dwu4Fi#ndAE+`ju}WG`tv9FiskmUgf^XeQ}@uW-==pr`JOGS9S>H@M0lJgcR*(! zrpmoxL7ht;Miu(^tD{-K(Y8daUf=6KEj&o4yv%dE2wxW}{&~kyzRMPHP|WRUiY{~{ z__Y%lxYuTilYaL16+4Svl{dCF6Tg>cZ&+S9GC#=ix||5Bx-7a+)UO)l5{E?HT)66{o%4wjR1A63 zQg~*I?+VIQo4(qeYGj(&y@|F8=16R(Ium~yzET_BkcQDTof29H149;!h@`k0Ny!C% zZUlB+Nc@gC(O03Jf^|n#KKn9aB??TU+#VvlWw1J!nKCoaXp0E-uSid&W@3zej4NA_h5oPH<~dKp@!_ zbH9pK&ZB}ce6WN(Zz)jwyLazAcM+-BsaOl;*TUV@5qERAuecQ5t#zu9$VR)M@Ft(|m-Rp)HDutKNt6-+iFjSEm zi#DJ}4hb!FEvNtLWt>{0q3@)9&GnAU)!oR5m<_w(| zyHQtB&?DpD=u3yHcf;_2<|%i9UA{u5IqcYO=Pf~Bg`LTjrP?HZW+BL7VPXa&1O%*~ zI)qc~%sH$EXHXx^+*^YT5*pX(Ca39B5wHIF2NT#+8|;T~lwjajkw#?*5Vq(cEPcOw z)ZA_!?bBZ)aKUBdzHWZzAOv_4P&EC@zbQ1L=$&JaEqN+M1LEFpCJ7zaiCgM}>Z^TS}j5T~r#el67Q7I<+W3AI?KNQQebXd;7*p z(sV9`V?NNZJYczxj=kQ4x$lf{89wf&`=#VuXp{yNT$29A3{!MwOiJvilCDF6Bf1JQw^w5%ZsYCtl;O|0p^Ti~34>M!- z0x9CEPeRQ;+wDE$V(^Cf+g0SMcLr@{(UCwP8GG&nD2cN=A)RK;@UQ#k^7i~)&#-MM z;dAc?{T0mb%{9cWt$IQwG;T{Pq&vQ%RA$2-9FS(?A(Q$zf3(oTf78~Y#LipDNl|wl z^fv`2a9b-C0y%A~8h^;x_9*T8zyROB&B)SO3z*telpXKy2kO=Q9&``Px}@L;fIj@x zl}l$!s3JkMdaW+n@nG|qG?`&!_vV$xFe7qK9kj~+C=ZiTdHb%OPa7MX6WDBXbhcn4 z)pqOh*Behcf@%Rt&n2K_sQK5g!J#FKiKQ9K)3|M?37_!inV90+X%ms$o@ySvO+&Mk|x zhs1l-0Wf#r)pTLgsg(p>HCnUv2S)eoUUVhwvY5f}6l9`UpHY#q?fA6Q`Lj{BfgAbK zjr9FP<}*hqcBn*p$l$~hqX(zYlFN05O~{}FFaEm$Esps^=U}lH8Li#{vOB>Do~1~e zucNtWJeD>Eg2iSyO3F>Fh*YUBC2I!Pe1YC^ULute z|4N$lj{nM&5Iz8F@B@k1=093RjY|*1*qKN_ejLj(M!XPE@?1j(;Pgv!TG#v~_ory_ zKYnwCtxFr)7F+@(BTdr`h=Xxho-LHS)b~8L)?~b_3om>5X6*eS32kM(s`Oi9BE6&S z1GSB9%CKz-lQB}Jb{m9bi0{1}Sf&c*o(V%zM8lHF64El>n)^V6-R9dNwV#=i>x}n_ zQO9^0l_#!Crw>D>QxYHd-9v^Rc81d8LQ;@1e4F@Dh>(>nuRoZC$j34|;_o<_EYDd0 z#*ZG_Y{0Mrp+}1q$e;o~3&;qYp2*;{HCDV@f;LZovh*~+;Kz$SP2Z%$L=L1dq9w$( z{HGS5mXQY%%`8p}dMoAl{P?23{Xhm2+gb--G^rJuX&-gWvwBEBrQBA05Q&^5>s+Mn z2V?%XZYv4=S3T^e2k76qB4Rka(o{N1zgEpX7=MpmFk$0B)_4<6T$Leh6>y{+ju|y9 z9pKLjxDSKJdTgR`&Mh8FV~u$IT$BNYCF9ML$`*A)L4jW0C~xI0F+S-hUn^won@{_UsWE zI4C~xl`>pHlZ^E9=R<^btHHvn(Y7(>Jr3#?XVi?Edz956LIm$B}R|Xk)KJCgfHR*oS*~v4dOVe*_XvpQlwsl7D2;SzZF9x z=%DEoXb|t%U&FR2ZeC`{x#hKS-Vr})UL%}NItU6TU+&S`n)W5c&k3Yb7~2AJcxOdy zI8L^|p+QX8hL#)7Is;wxZMai9k%1aVRbM9TPz@LjCZm*Pgy*ZPiKNe;B7uQS`rA3T z{=nr04&}|94v;@|)`@^ig^P>8>3TzTel5@CMu(-?t><&#UVaYG#x~2`BKmJVm}*)l za(*6#i~XNjs2w1#CPn7ND-F&e}OncAtwu-Bgm3eomeM!wRm5RJ72X&>R7_ zTGD)Sd?OfrXreDv8#lHL6B+m*qs}Z+PgMR<&!()n7)K~5XtiYbOHN4t012;;ia$A5 zK!~o8UO*4l^tbALjN8^gxWa;$Px z_2v9e)U6;$j`sDUik=B$TbywrWXPD{v^}MUlE^t2)A}ShpU1rx(VpixEu%8l+IE zhZoe20#}K-+Ax2Mj3F84v$KjaLpv+$d~FFGmb`3)ZJ+UjYl-Y^6Cex}*QNhaeYi2Svq^hGGE*g1P&rndFt(9m zl;v#=uRFC#LnVWk_Zz=1zW!g=87?E(Awu$%ygbw#fUv#hhizki@tOgLshuI_sxZ+{a7 znEiIS)kr_T97<++*?hWvB{TF}(8Rcfs*_*C@h67A5?h)-FjusZsjo|WnecBL9w2AA zpX!QPO42>u>r^7AL8+ZU;-VhwDkB>^!($e`Dx!v;g9A9K9+VZ?`{OW?s+J%q9nCAL~UHTlHB8q^U-0xnfEwj<=Q z$sJsRY76(QK4ZRto<8DwA8XGOV&ga>YVL2i%%wpFHuOGy->=M+bE|sx3N>rr{yKM+ zA%{B3;LsKMzR(yVoj%&dNQ*3dW1rFci;+jP4SgGDG?W^fT{7-+$=FPE#T|B$OC#R6EznZ$!S1CsveI9p2`mr% z2KJcP#f{8=F~K#?j_mD2#=$O!F51UJPmW!rU>(b3Xal6^0x8c6#@7Nsym|jxkM)3B zbDNTSbDQ?eWQy5rgD|yR>OCtrYtTlgSvRQ!O#)gdd@1DGTDV=~$(&wbGMNwuY=}pC zv#TwoE@_Vfw<#RdQ6Z^lH|!mBL6#%Ix=Lu-mdT!HYDcT&#b-Tz)bov@51?Z60dKD+ z*J}!t@;|&4U(YXs0N$}thGx6m`B~kL*|%P#WRwBX2e9|yUs=ms|`bs;Iq@{mJaiU6b!SPci)YJ z63oU{osw2V=JK-{(I2&o&Y|~QWP}85V7GSFuM=_?-NEFm_4=YGOoDdWJ7RJ3Ku|p7 z@{fMn&d5Ox-ugaJ9fQdF>qnf&!7kU$M|{%?283j~aL&OUUhh-S7SgflSKOj0+riVP3;>&N`L9bqd*4P~JYmCPS zZzcc(@z9q^ZTv{++`1L)t&ztLDxT2q66OQGb~P)HD0D2f-FOnGOYVTPjzHd_cLL6d zrFq?@NzB6Bey#laRilTD!OMbi(z(z_+t{>U62zZUd>@y|*#W{1Qm`WH0#`iYkLvz* z4T1JqiH=z~s$+f>s;|T*kY!5CB~$O0+RZI-D1TMxiM9PJF1oVs(gaQ8;H}4$ z6UAPx4dyqj=-mbqNDGnFhiEm(z@iERTQ(3w__?JEz9DH{N6h2cForX z{Vy9_|lVyIo{TxGoKWO<8UZ18&Z{CU{+BU znOO*#qi`%Ib|k+(TRa+L!LnZHyEWCqW-3Vagz87cNl`>xh{2*(b@ZezLZo_j>8e7? z?EMnYa=ixBYnQX!%gQ)t^}2t@ex#McKL@u(V46HaJa2eTyOi(dfUiGMh}Rfl>*?v~ z-V*Lz=Br%c*HGFbd`g1}6NSt`93HJdr-}9|Fl=d9B?`M5%-az2K9!N!G3BPbSDB|W zM}C8T@$M(C7(ujlqipcaX(C(ZQxv)y#_3`rJ;EL6DCt+7QH^ z_36jWUKL3wn-ignZy)m@%sjS4&Mgd{VtHGJ*Y;%y=8D=?E>+F}8Th<=H||=m9OGP% z52Pq)g}(Na2`AxBoP)An{OOj#cW+j2>lf;6A5>`4$8K%)R*LI7=Q{Xs74MT1Up%`Z zoZrHexR^9&OrNN9fDH6X@e38u$-W?lPkxIu!}6T_7wp(lsJRr!@`}ipjU=cLU}oBl zHN7Iu{JbK#!-*ZkHdMi~NFZnbykJ_%r*OUpT(4`Vk56|}Wh(Q-9nkG&70mw0P>tny zK%Pi>Zf53=(YT#N&yX=XV&oC+14=jYb`tI9-cidu-xdo@2Ef~e$Dg0Xqq~58I)>Ef zI!u1V*OZ{#~s^^P$dfe)#LR87m zN_Atox5KQ*Ig>PzU?2^tf(wj!P=aV=pv#xu zT&B)o+f)OL_k#M636<4Va85(q&~;RcS66-CfMwK7p5eVLkk4b}>l>xc%1eBWDJ39YxI zZiyBWEPBBEoJuX;_l8Rb0;r>^39`iOzUQN(n|H7Q4`a{$B)H_-ycR6r_SAjXW(eQc zzLfd|*-1nVOTc|5-!5vXdOI&|Fs9Hst}n7EL2T)_%n7*v$u|tlCvJG% zFVf=kn6uFtQ+_CV3J!Vy;q^lI_-7iryM*?qpIpp7ceA|_MA?sLdD)8{ncAh|qtVBD zl`Zx46uw>^ah^O#4fa;&|2&&e>hC9|U7v7L02%PuWkr>gB*2ywmLL!)A9hph$%3>l z<*WdGv$*tJ1O7f_H8&cObJ(s-e?fI{=J(4%dj=chevf7uQsbDmgGL)$Ui=fuo5=6c zt&@<_^R)z4tq2?6r!+;7J8k-VG>sd9!JvWk)l^KwOw9xzBc@|Ma8*m>0R~^_~bll4Lwb}Aw-^1mPXa(u) zQSTO~Mb^pXFrtx=9nflCYbxsUme32oP_vh>APJjiyJ>V>OPgk-9CqkLW;NSn2)Q z!m&l3ChP+cjL70fGK#$E4CNy(^KWuPyeQ?{g@pd{uc}C5YI`U1Dwbes6C6^ zEH%sMH(qKq*vjbh{v_jA$0|U>tcsGLs--J!t>EycKOH8XQWX|Po|-$U+1KC@SrjDB z2#8Z=ji876aE3Jbc04u+UOgKP9WPl;CzfJ?2pWM zj`YTcHBT;m2nSybM>-_@5yXu1ovw##JQayDAu@B*IiBgL-uW+nYW^9KY@A~0+JM3B z&WX_7;H+!@@F0^}k(lznhU{)%4z(N8YPcf<&m~%1)8DlcIZk(p;?-{s4#$Mp6yMq< z{qxYVTn-LqrhJl|X-hN}E%9K2;StEev~@AzkhBaEU28~BaU zpshs~_K=A=x-oNc241oTgh}x)j(F;@kqKEoEh2nEbQZ=jo!OE8N@ zX|f6iY@vnYZYI+hZEGC(q|=R~C7k}7yLob6?Zg(g7S zvZ)Ce!4>TJVZx5|H!bHl1KYxBIHi@85)%TN%p2h~53HV!v_LZmRu9I&dz=4C=YxG> zuLYlV@V@UjIkQd9DkH$Hn_SKg&?)Y!4kIG6sXadfh$D!y(1^(O=-L#+*uIRBrLKoh z%q_ioA9J}wGuyQw;~J^?7C{P2EX4dnI3AjH-vT2WQV6pZfd>yK>jO_CzNbSs%;C=3n)?&*6;#rP=Piibd!ea<1^#SN)8a}b zhnk2s&8zEu^wmO5)BG}BbR0={*&DeaUWD|AeXzXz0z)ujl`{aI@T(&%rUTN1Mc|Yy zkeW`JR2+!f;LGL6$nU={@?EVUt|T*@N6{_dPbZ4docgR|8-Ta#81E?~qk^oBM^W&3 z_RF;7ZUD*cCgdF%@h?Y-nO{qz!^35fd)ZzyL9eX3!Oqxi3A%d>+_&`e? zzqo(F|Cg-nVQ~C1Fu)k_r-R}G%)a2By5G zZY!||N#jGFKzPqwg3_;y8ir2|erSU@DXtg}HL&X^rVn;|s3t!IGyQG`Ou*qHbU|dH zruX5yq^Hct8>WSBhW)pDVuN#~IyKHr@w!S1LQDLoBZM5`gv03C{NJarT1+v`Q?8qO z4HQ;WaJqp&m(DYw(K&LDATv24-~bH3K~?-|tL^4U$dB^DHA@ES?1bSYeCFh+bTpEo zENyqUXc)7Kpmt+AF=AVL%*mN9R#n6`5_W+re^_UsTA|TO8XPr3%fb^)PzTO=kX zVW5?$&-lLqpsavc?av}IVhrd+M@0_AH=2(9D=2^#kVKhg0PcjlMGXDI^=uA$TKP1FH%+SoJ)`>_trUB_P*WC*T_k*mDyP_FknNe#1q+$$7?k97;O)l_Q?h?{mK? z7bh1dXKj54D4MBWgYi;hn2JMQs20(90r3#rMGvJNMFxsM2zs0W4)WT0Kcakb2ES`j z0U`yY@7xu0#%X*KR*eYyPy}})*Ck;r+5vhXF1F#HhdB*m z#WkfxF3sBT7>NL>JrKME3NE?+g|2#lfP*c!Vzhc2c?&|m z1>W6`mzXz1&FJm6CmhPC*;l!B z>p-8zDhv2kgjhYA>f1pRY3gUGb|*O6Zhlww`dYxn+Zic`uq(z1ai+6-}O&AJoM!(~=Hhhv8gC+@{V2LFX?ghq{V+I_OLR7-n_~drz zqq6WlO4~z=L7%Y~pr#T9f`|R>Gj?q8dpg8;Sr~eZ?zh4=x-%L*rrTrx$tEuH0^&Yl zR)_~N+l!2chw)@sb3?X>no@BHLw)C`jYD{@p=#Nf&)B13)gA5eRU_chH{a&RDiQU{ zPZGKmk{m`3(Z_}4qyo84v-x%SLh6#;FuaaDYyg1_?4U|F6u=DD`7g)R?FaUKjbBFQGWpb~f^RPN~QY@1rpc}YN zh>cy9)H)sJE01Wf{P8wq+|W9_r#h*xv2a+~nHii*k%44Wrdi|uB7sgVvX zT*CJDDmAm7_Q7cBe5z|kNwfH4n>C$Y$Y=4IuwZm@HiUJMG=K8XOB(|g+W3=jk|_-{ z(7{K%On;@I(U6$q|3O%E#;QVJ*)$hx_F*9Bt zZ``zwScx!xR2Jk7Wb}>bLYkiy#J_5(eX| zF~K{>xvuB+7r!h`^S?1`3YxFHL-f~~M%Cn@Q*AY6mm+14V3Wt16rRRDihBH_ zQs_FhNc6c`J&IJa2Awq-k`+~fCtbO5j0bbeQO^aD`*&~sLLer9eN$yD`)l-Hnvz^x z=uH*kH7LELD^V|4QhK@ZZG?Do!`(U@)TzVoIbcF(*n-D4ZOdMSt*3%9X;o)`;TP=E zpq2-1^4O9h62``FU}BuozNlSTBz<}!Pgwl2JZ{Yf!4*#Mr7hXo^$USZpgLB3b~k`gYBTBm90S znJ)?m+N{tI=NhIQdv)s;)k&-WdiS+473Ra;Rp5J67nh#4g_d{}|7YY{r zJlR^yy0UT7QpT1&6G8LGfNfl2ynBoD{S+6lxn;N%G7l=k}$sY||O+a}m zO`i8t-~DJjAk}QEP3qSE4LBD9%b(KLLbf>_sEg%YXSn&E#ej$XIMiu}o2sB#%R zw5FVMt?4$NUS?A$Oh`-G&1eREF+C>M%rV$Md9`HmIM*)63XhhCM@~hO&{7+N*r*FP^~lDE$rKg>9oFvYGx0GK=aG3BT+=G$eID}P#?%Rd!%)?5rMl~ zuyFbAU{cFp)E;bCXL%OAZ0;Sn6%^HtN}8O>Xa>7g#e*Ot+4uPL z34VWt8)qE<`zka&KAr`S&p=v3@&x zHnNfD9>28{tqd8b9o`~Ba$wzn?ti*5n@xyad)|3_^#|$bb)}=c*xUK-spG>S^ao=5 z2=qsEYr;>tTHPzeHyc@1h{iUyJX&-j=1YZphhEGCO>+gMPHy8wd9M?C?FkNN9!<|i z>t+z@?;x2uNvEY0d0a{lO8yGNI&C|JakdzFc|ykqIl=P8+8YZqD&Q4=Ds9sD`#t0> zTgzvYZ3GIx_&x8hly;^cK7JE99pTKShD9o}T3V*1A~Vw<36WhzVU%RtilTT&;oqSI zE<$elWG~ybCI4&&FBMOx86<;O80#o89xOQp!}|uz$iGSiB-)7LWI2BmCPR71A(+(v z-=5S0&qI23nqlgaLcB<7^mz;hVi}p8?`?ff+o|)B8)BB9G*tpy6i_X-|K9KqqHx%( z_!>sOyEmG@s?pUqr6v&9)a>;g#ZNoY2WVKosx>dEY$&c{#(2*|#Ug9SNfjlW#W`T; zfJBmoQKr{?v^SVJaO;91!RB(Glr1rdD~8$iE`reh{dX<|qJ&BYKer63p$E>U zm4J>GY4GNv%rsx4+ZKl!oFm>Pa)hc+MJM?fGfpjgq$%>P-~h&Q-M!S{jDC7QB6grP z%wM-*cravgYu;T*ihfPmI8do^sbJl+B7drcirHJ&h)>?W(3WIsM$QCAS=nhDO0z z65-*k(MwL)96*w*vyE=_<4m5d_&uSqVw3i4?M95 zsWFP#$hV@AY!TxQf}PDg;cYop-7Y;MM%Vt=JwOhgeS`Uo$#AqU2SH0Rw(+yrw()L) z56{mY<7npymEt(jhEFQsiyOAlAs=@%3EsoA7dB%g>_1MqsG`u3(v;e*dVZpg@M`lB)^X!Dd{BX>8QrjBxr5#kJY;_ZJ>djvDhUmxWz>az ze7#k#5%p=1#Wal_AMt!>kO(b=T?n`hXxs>i4w7IL6Ueusk<3B7$dZQud$XZ`W*#0L z1nofH(?M>TCc;jBuXvb{K`3g&$NZUc8$RjahAp{iX=J0ah(!?^5k%mE%3NAP%cv=} z+s9n3B}r`>TGvg}*v^s$nEbA&t@#QrYGcB+X#G*lLB17@1c)E>xI@Asn+SGjwTTy# zXvd(3$U)Fsl{JV0Qx3oE{_PLDIEt(swvTGVSKUXPU!?Z5+^+XtsELsO?cjpSbe7OE z>MfW0Ypt4^)TVJTgT|(hcs?}rfBV6{6Io3NNb2tS#DNElVy=Yw5G8qp^c=Bx+wI%P3!*? z8l<8d2X`WS0Pss@!mLJdxoIRo=~1yRj~-$`wu8W9n-2U7{t*ha_)IyRG-P0kr-|Gt z1%OcoH#YP1=&fA(0uh}mOH*0Ix~Cd#3Jsz(>Po5SYyCf@(a4#Geys0AZpRMNNid2D z72nB4j5i@jFp3G}ThU1CAhHmd2yJ90HaDbz zIY?WlXxI*fMTpWw03Hd#VdN2W9GQQo(^sW7d?mTv)97doDz4>~qY1Dug3wetmbylz zw-}8^OhYU*;u+D1;ycv`DRPhmqnJRx6^%p=;x(4u?a@Vm?@Qoc@(UdXSFckvOpYxA ziNZ-`B4inyU1;WU>0B;-D+xItuZtQ0v-1kr2UbNCTD6BuT~F&pXplvj##&x9;`q)e zIg1XGU=$O`x1y2ULDUx~V0{+cU-ahJ1E?5C#B~g2AEDF8%z@?1t1f-#dzws(l9#Xn z(BRf%rR!UDeHvs@qOq18jd&+=>>vq7F@bz58mS#5_7Gm;Y^?JOO{9pA!6_jg62k2Z zlMiPM2_7iCU@vFPJT9H*^bs!;lA}p+iXK6=k%Xqw^`%~%#(GTSyKHF`KeUwInQjyl z$hV@A-a>eR)o^o(mU5ePkf;bz*a4zMcuE!%Z}6Y?&OkGQ7zo3c?3NzY)0Zf4C=`AF z2dn0GZl<}6lNHR$_n|0iI{%0`H(%}^>5IN2?po-RcQLXTAZ7dIs)xt^R?kz0Z|@|< zBb5<=WXMmb|9O$Nz2B8fx~N>Z$qZEFSSIi3JK}Xc^}XoDunJ4n>AqHvDq}fD8BK$D zfD}90M~Y!c|9O6blpngPtjZ;8Br24BWFvBXtKSjdb1_;ii;_1|f2#+Ukwcf^pCAEJ z>}Ve;h9dQlt8d2WXQ}t$`~E4$GTE`;9wWItPG0K07%eTblG4~#4=CdlvW(jQ8#cw0 zg%rcG?*tKZY`Fl-@O^&Cg5hmX_FA5THn+ZFGODXDq{>Afz}?83E1^IXElj zlDZDI1w&bs-9)f`ljl_Ac6n^4Cn!Vz#8fF#Mu1Z!=LhA|S-g+dNOaw{3O~GeEJoBb zpwn}fk7FXWmJuMu8118sFncssNmLn$%G{}5 zuzT{9AdNnL8Kg)Vv5t_XX*ClrVncZy@eW^rHpef66e;6)myp%!Qgpdc9372!a85vq zbHnWURx@2KG%_V7j}!rX@1v>?gtN+&m^@Mh@O>$2I{3pZ+FLrs6ajo&N?aidkRtp7eomMdQOdmx00000NkvXXu0mjfII{dX literal 0 HcmV?d00001 diff --git a/packages/pinball_components/assets/images/score/twenty-thousand.png b/packages/pinball_components/assets/images/score/twenty-thousand.png new file mode 100644 index 0000000000000000000000000000000000000000..2f9bfd574a87f327be9ad2f27b9f3863a0c49215 GIT binary patch literal 18361 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 VinJ^J!Fd1x002ovPDHLkV1gxL5d#1K literal 0 HcmV?d00001 diff --git a/packages/pinball_components/lib/gen/assets.gen.dart b/packages/pinball_components/lib/gen/assets.gen.dart index 4388ced6..d526909e 100644 --- a/packages/pinball_components/lib/gen/assets.gen.dart +++ b/packages/pinball_components/lib/gen/assets.gen.dart @@ -31,6 +31,7 @@ class $AssetsImagesGen { $AssetsImagesMultiplierGen get multiplier => const $AssetsImagesMultiplierGen(); $AssetsImagesPlungerGen get plunger => const $AssetsImagesPlungerGen(); + $AssetsImagesScoreGen get score => const $AssetsImagesScoreGen(); $AssetsImagesSignpostGen get signpost => const $AssetsImagesSignpostGen(); $AssetsImagesSlingshotGen get slingshot => const $AssetsImagesSlingshotGen(); $AssetsImagesSparkyGen get sparky => const $AssetsImagesSparkyGen(); @@ -201,6 +202,26 @@ class $AssetsImagesPlungerGen { const AssetGenImage('assets/images/plunger/rocket.png'); } +class $AssetsImagesScoreGen { + const $AssetsImagesScoreGen(); + + /// File path: assets/images/score/five-thousand.png + AssetGenImage get fiveThousand => + const AssetGenImage('assets/images/score/five-thousand.png'); + + /// File path: assets/images/score/one-million.png + AssetGenImage get oneMillion => + const AssetGenImage('assets/images/score/one-million.png'); + + /// File path: assets/images/score/twenty-thousand.png + AssetGenImage get twentyThousand => + const AssetGenImage('assets/images/score/twenty-thousand.png'); + + /// File path: assets/images/score/two-hundred-thousand.png + AssetGenImage get twoHundredThousand => + const AssetGenImage('assets/images/score/two-hundred-thousand.png'); +} + class $AssetsImagesSignpostGen { const $AssetsImagesSignpostGen(); diff --git a/packages/pinball_components/lib/src/components/components.dart b/packages/pinball_components/lib/src/components/components.dart index 43ba302f..394f32ed 100644 --- a/packages/pinball_components/lib/src/components/components.dart +++ b/packages/pinball_components/lib/src/components/components.dart @@ -24,7 +24,7 @@ export 'layer_sensor.dart'; export 'multiplier/multiplier.dart'; export 'plunger.dart'; export 'rocket.dart'; -export 'score_text.dart'; +export 'score_component.dart'; export 'shapes/shapes.dart'; export 'signpost.dart'; export 'slingshot.dart'; diff --git a/packages/pinball_components/lib/src/components/score_component.dart b/packages/pinball_components/lib/src/components/score_component.dart new file mode 100644 index 00000000..12d198cb --- /dev/null +++ b/packages/pinball_components/lib/src/components/score_component.dart @@ -0,0 +1,92 @@ +// ignore_for_file: public_member_api_docs + +import 'dart:async'; + +import 'package:flame/components.dart'; +import 'package:flame/effects.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:pinball_flame/pinball_flame.dart'; + +enum Points { + fiveThousand, + twentyThousand, + twoHundredThousand, + oneMillion, +} + +/// {@template score_component} +/// A [ScoreComponent] that spawns at a given [position] with a moving +/// animation. +/// {@endtemplate} +class ScoreComponent extends SpriteComponent with HasGameRef, ZIndex { + /// {@macro score_component} + ScoreComponent({ + required this.points, + required Vector2 position, + }) : super( + position: position, + anchor: Anchor.center, + ) { + zIndex = ZIndexes.score; + } + + late final Effect _effect; + + late Points points; + + @override + Future onLoad() async { + await super.onLoad(); + final sprite = Sprite( + gameRef.images.fromCache(points.asset), + ); + this.sprite = sprite; + size = sprite.originalSize / 55; + + await add( + _effect = MoveEffect.by( + Vector2(0, -5), + EffectController(duration: 1), + ), + ); + } + + @override + void update(double dt) { + super.update(dt); + + if (_effect.controller.completed) { + removeFromParent(); + } + } +} + +extension PointsX on Points { + int get value { + switch (this) { + case Points.fiveThousand: + return 5000; + case Points.twentyThousand: + return 20000; + case Points.twoHundredThousand: + return 200000; + case Points.oneMillion: + return 1000000; + } + } +} + +extension on Points { + String get asset { + switch (this) { + case Points.fiveThousand: + return Assets.images.score.fiveThousand.keyName; + case Points.twentyThousand: + return Assets.images.score.twentyThousand.keyName; + case Points.twoHundredThousand: + return Assets.images.score.twoHundredThousand.keyName; + case Points.oneMillion: + return Assets.images.score.oneMillion.keyName; + } + } +} diff --git a/packages/pinball_components/lib/src/components/score_text.dart b/packages/pinball_components/lib/src/components/score_text.dart deleted file mode 100644 index 6dcba4b1..00000000 --- a/packages/pinball_components/lib/src/components/score_text.dart +++ /dev/null @@ -1,57 +0,0 @@ -import 'dart:async'; - -import 'package:flame/components.dart'; -import 'package:flame/effects.dart'; -import 'package:flutter/material.dart'; -import 'package:pinball_components/pinball_components.dart'; -import 'package:pinball_flame/pinball_flame.dart'; - -/// {@template score_text} -/// A [TextComponent] that spawns at a given [position] with a moving animation. -/// {@endtemplate} -class ScoreText extends TextComponent with ZIndex { - /// {@macro score_text} - ScoreText({ - required String text, - required Vector2 position, - this.color = Colors.black, - }) : super( - text: text, - position: position, - anchor: Anchor.center, - ) { - zIndex = ZIndexes.scoreText; - } - - late final Effect _effect; - - /// The [text]'s [Color]. - final Color color; - - @override - Future onLoad() async { - textRenderer = TextPaint( - style: TextStyle( - fontFamily: PinballFonts.pixeloidMono, - color: color, - fontSize: 4, - ), - ); - - await add( - _effect = MoveEffect.by( - Vector2(0, -5), - EffectController(duration: 1), - ), - ); - } - - @override - void update(double dt) { - super.update(dt); - - if (_effect.controller.completed) { - removeFromParent(); - } - } -} diff --git a/packages/pinball_components/lib/src/components/z_indexes.dart b/packages/pinball_components/lib/src/components/z_indexes.dart index 04dd02c7..440bd1fe 100644 --- a/packages/pinball_components/lib/src/components/z_indexes.dart +++ b/packages/pinball_components/lib/src/components/z_indexes.dart @@ -101,10 +101,10 @@ abstract class ZIndexes { static const androidBumper = _above + ballOnBoard; - // Score Text + // Score - static const scoreText = _above + spaceshipRampForegroundRailing; + static const score = _above + spaceshipRampForegroundRailing; // Debug information - static const debugInfo = _above + scoreText; + static const debugInfo = _above + score; } diff --git a/packages/pinball_components/pubspec.yaml b/packages/pinball_components/pubspec.yaml index 4ca7f28e..1d2232e0 100644 --- a/packages/pinball_components/pubspec.yaml +++ b/packages/pinball_components/pubspec.yaml @@ -86,6 +86,7 @@ flutter: - assets/images/multiplier/x4/ - assets/images/multiplier/x5/ - assets/images/multiplier/x6/ + - assets/images/score/ flutter_gen: line_length: 80 diff --git a/packages/pinball_components/sandbox/lib/main.dart b/packages/pinball_components/sandbox/lib/main.dart index c123c2d9..25473f02 100644 --- a/packages/pinball_components/sandbox/lib/main.dart +++ b/packages/pinball_components/sandbox/lib/main.dart @@ -24,7 +24,7 @@ void main() { addBoundariesStories(dashbook); addGoogleWordStories(dashbook); addLaunchRampStories(dashbook); - addScoreTextStories(dashbook); + addScoreStories(dashbook); addBackboardStories(dashbook); addDinoWallStories(dashbook); addMultipliersStories(dashbook); diff --git a/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart b/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart index 639a4b57..ce14d7b6 100644 --- a/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart +++ b/packages/pinball_components/sandbox/lib/stories/backboard/backboard_game_over_game.dart @@ -1,6 +1,5 @@ import 'package:flame/input.dart'; -import 'package:flutter/material.dart'; -import 'package:pinball_components/pinball_components.dart' hide Assets; +import 'package:pinball_components/pinball_components.dart' as components; import 'package:pinball_theme/pinball_theme.dart'; import 'package:sandbox/common/common.dart'; @@ -8,7 +7,13 @@ class BackboardGameOverGame extends AssetsGame with HasKeyboardHandlerComponents { BackboardGameOverGame(this.score, this.character) : super( - imagesFileNames: characterIconPaths.values.toList(), + imagesFileNames: [ + components.Assets.images.score.fiveThousand.keyName, + components.Assets.images.score.twentyThousand.keyName, + components.Assets.images.score.twoHundredThousand.keyName, + components.Assets.images.score.oneMillion.keyName, + ...characterIconPaths.values.toList(), + ], ); static const description = ''' @@ -30,21 +35,23 @@ class BackboardGameOverGame extends AssetsGame @override Future onLoad() async { + await super.onLoad(); + camera ..followVector2(Vector2.zero()) ..zoom = 5; await add( - Backboard.gameOver( + components.Backboard.gameOver( position: Vector2(0, 20), score: score, characterIconPath: characterIconPaths[character]!, onSubmit: (initials) { add( - ScoreText( - text: 'User $initials made $score', + components.ScoreComponent( + points: components.Points.values + .firstWhere((element) => element.value == score), position: Vector2(0, 50), - color: Colors.pink, ), ); }, diff --git a/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart b/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart index b8c85d10..9e83c7c4 100644 --- a/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/backboard/stories.dart @@ -1,4 +1,5 @@ import 'package:dashbook/dashbook.dart'; +import 'package:pinball_components/pinball_components.dart'; import 'package:sandbox/common/common.dart'; import 'package:sandbox/stories/backboard/backboard_game_over_game.dart'; import 'package:sandbox/stories/backboard/backboard_waiting_game.dart'; @@ -14,7 +15,11 @@ void addBackboardStories(Dashbook dashbook) { title: 'Game over', description: BackboardGameOverGame.description, gameBuilder: (context) => BackboardGameOverGame( - context.numberProperty('Score', 9000000000).toInt(), + context.listProperty( + 'Score', + Points.values.first.value, + Points.values.map((score) => score.value).toList(), + ), context.listProperty( 'Character', BackboardGameOverGame.characterIconPaths.keys.first, diff --git a/packages/pinball_components/sandbox/lib/stories/score/score_game.dart b/packages/pinball_components/sandbox/lib/stories/score/score_game.dart new file mode 100644 index 00000000..4bde5018 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/score/score_game.dart @@ -0,0 +1,44 @@ +import 'dart:math'; + +import 'package:flame/input.dart'; +import 'package:pinball_components/pinball_components.dart'; +import 'package:sandbox/common/common.dart'; + +class ScoreGame extends AssetsGame with TapDetector { + ScoreGame() + : super( + imagesFileNames: [ + Assets.images.score.fiveThousand.keyName, + Assets.images.score.twentyThousand.keyName, + Assets.images.score.twoHundredThousand.keyName, + Assets.images.score.oneMillion.keyName, + ], + ); + + static const description = ''' + Simple game to show how score component works, + + - Tap anywhere on the screen to spawn an image on the given location. +'''; + + final random = Random(); + + @override + Future onLoad() async { + await super.onLoad(); + camera.followVector2(Vector2.zero()); + } + + @override + void onTapUp(TapUpInfo info) { + final index = random.nextInt(Points.values.length); + final score = Points.values[index]; + + add( + ScoreComponent( + points: score, + position: info.eventPosition.game..multiply(Vector2(1, -1)), + ), + ); + } +} diff --git a/packages/pinball_components/sandbox/lib/stories/score/stories.dart b/packages/pinball_components/sandbox/lib/stories/score/stories.dart new file mode 100644 index 00000000..9c1d3c62 --- /dev/null +++ b/packages/pinball_components/sandbox/lib/stories/score/stories.dart @@ -0,0 +1,11 @@ +import 'package:dashbook/dashbook.dart'; +import 'package:sandbox/common/common.dart'; +import 'package:sandbox/stories/score/score_game.dart'; + +void addScoreStories(Dashbook dashbook) { + dashbook.storiesOf('Score').addGame( + title: 'Basic', + description: ScoreGame.description, + gameBuilder: (_) => ScoreGame(), + ); +} diff --git a/packages/pinball_components/sandbox/lib/stories/score_text/score_text_game.dart b/packages/pinball_components/sandbox/lib/stories/score_text/score_text_game.dart deleted file mode 100644 index aa776405..00000000 --- a/packages/pinball_components/sandbox/lib/stories/score_text/score_text_game.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'dart:math'; - -import 'package:flame/input.dart'; -import 'package:flutter/material.dart'; -import 'package:pinball_components/pinball_components.dart'; -import 'package:sandbox/common/common.dart'; - -class ScoreTextGame extends AssetsGame with TapDetector { - static const description = ''' - Simple game to show how score text works, - - - Tap anywhere on the screen to spawn an text on the given location. -'''; - - final random = Random(); - - @override - Future onLoad() async { - camera.followVector2(Vector2.zero()); - } - - @override - void onTapUp(TapUpInfo info) { - add( - ScoreText( - text: random.nextInt(100000).toString(), - color: Colors.white, - position: info.eventPosition.game..multiply(Vector2(1, -1)), - ), - ); - } -} diff --git a/packages/pinball_components/sandbox/lib/stories/score_text/stories.dart b/packages/pinball_components/sandbox/lib/stories/score_text/stories.dart deleted file mode 100644 index c4899a27..00000000 --- a/packages/pinball_components/sandbox/lib/stories/score_text/stories.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:dashbook/dashbook.dart'; -import 'package:sandbox/common/common.dart'; -import 'package:sandbox/stories/score_text/score_text_game.dart'; - -void addScoreTextStories(Dashbook dashbook) { - dashbook.storiesOf('ScoreText').addGame( - title: 'Basic', - description: ScoreTextGame.description, - gameBuilder: (_) => ScoreTextGame(), - ); -} diff --git a/packages/pinball_components/sandbox/lib/stories/stories.dart b/packages/pinball_components/sandbox/lib/stories/stories.dart index d8641b9c..89bf5d96 100644 --- a/packages/pinball_components/sandbox/lib/stories/stories.dart +++ b/packages/pinball_components/sandbox/lib/stories/stories.dart @@ -12,6 +12,6 @@ export 'launch_ramp/stories.dart'; export 'layer/stories.dart'; export 'multipliers/stories.dart'; export 'plunger/stories.dart'; -export 'score_text/stories.dart'; +export 'score/stories.dart'; export 'slingshot/stories.dart'; export 'sparky_scorch/stories.dart'; diff --git a/packages/pinball_components/test/src/components/golden/score/1m.png b/packages/pinball_components/test/src/components/golden/score/1m.png new file mode 100644 index 0000000000000000000000000000000000000000..bb2f563115b8c0ecb3996bd03cb327b396dd537f GIT binary patch literal 28600 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 literal 0 HcmV?d00001 diff --git a/packages/pinball_components/test/src/components/golden/score/20k.png b/packages/pinball_components/test/src/components/golden/score/20k.png new file mode 100644 index 0000000000000000000000000000000000000000..2a4446c33d430b3b568ddbf73b7db7e9fe0f48ca GIT binary patch literal 28593 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 G|N1YI-HlNI literal 0 HcmV?d00001 diff --git a/packages/pinball_components/test/src/components/golden/score/5k.png b/packages/pinball_components/test/src/components/golden/score/5k.png new file mode 100644 index 0000000000000000000000000000000000000000..8f2a7973aaf3308fe21df957c0a4c2bd318ae07a GIT binary patch literal 27555 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 TestGame(assets)); + + group('ScoreComponent', () { + flameTester.testGameWidget( + 'loads correctly', + setUp: (game, tester) async { + await game.images.loadAll(assets); + game.camera.followVector2(Vector2.zero()); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + }, + verify: (game, tester) async { + final texts = game.descendants().whereType().length; + expect(texts, equals(1)); + }, + ); + + flameTester.testGameWidget( + 'has a movement effect', + setUp: (game, tester) async { + await game.images.loadAll(assets); + game.camera.followVector2(Vector2.zero()); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + + game.update(0.5); + await tester.pump(); + }, + verify: (game, tester) async { + final text = game.descendants().whereType().first; + expect(text.firstChild(), isNotNull); + }, + ); + + flameTester.testGameWidget( + 'is removed once finished', + setUp: (game, tester) async { + await game.images.loadAll(assets); + game.camera.followVector2(Vector2.zero()); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + + game.update(1); + game.update(0); // Ensure all component removals + await tester.pump(); + }, + verify: (game, tester) async { + expect(game.children.length, equals(0)); + }, + ); + + group('renders correctly', () { + flameTester.testGameWidget( + '5000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.fiveThousand, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/5k.png'), + ); + }, + ); + + flameTester.testGameWidget( + '20000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.twentyThousand, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/20k.png'), + ); + }, + ); + + flameTester.testGameWidget( + '200000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.twoHundredThousand, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/200k.png'), + ); + }, + ); + + flameTester.testGameWidget( + '1000000 points', + setUp: (game, tester) async { + await game.images.loadAll(assets); + await game.ensureAdd( + ScoreComponent( + points: Points.oneMillion, + position: Vector2.zero(), + ), + ); + + game.camera + ..followVector2(Vector2.zero()) + ..zoom = 8; + + await tester.pump(); + }, + verify: (game, tester) async { + await expectLater( + find.byGame(), + matchesGoldenFile('golden/score/1m.png'), + ); + }, + ); + }); + }); + + group('PointsX', () { + test('5k value return 5000', () { + expect(Points.fiveThousand.value, 5000); + }); + + test('20k value return 20000', () { + expect(Points.twentyThousand.value, 20000); + }); + + test('200k value return 200000', () { + expect(Points.twoHundredThousand.value, 200000); + }); + + test('1m value return 1000000', () { + expect(Points.oneMillion.value, 1000000); + }); + }); +} diff --git a/packages/pinball_components/test/src/components/score_text_effects_test.dart b/packages/pinball_components/test/src/components/score_text_effects_test.dart deleted file mode 100644 index 7f828f1d..00000000 --- a/packages/pinball_components/test/src/components/score_text_effects_test.dart +++ /dev/null @@ -1,75 +0,0 @@ -// ignore_for_file: cascade_invocations - -import 'package:flame/components.dart'; -import 'package:flame/effects.dart'; -import 'package:flame_test/flame_test.dart'; -import 'package:flutter/material.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:pinball_components/pinball_components.dart'; - -import '../../helpers/helpers.dart'; - -void main() { - group('ScoreText', () { - final flameTester = FlameTester(TestGame.new); - - flameTester.testGameWidget( - 'renders correctly', - setUp: (game, tester) async { - game.camera.followVector2(Vector2.zero()); - await game.ensureAdd( - ScoreText( - text: '123', - position: Vector2.zero(), - color: Colors.white, - ), - ); - }, - verify: (game, tester) async { - final texts = game.descendants().whereType().length; - expect(texts, equals(1)); - }, - ); - - flameTester.testGameWidget( - 'has a movement effect', - setUp: (game, tester) async { - game.camera.followVector2(Vector2.zero()); - await game.ensureAdd( - ScoreText( - text: '123', - position: Vector2.zero(), - color: Colors.white, - ), - ); - - game.update(0.5); - await tester.pump(); - }, - verify: (game, tester) async { - final text = game.descendants().whereType().first; - expect(text.firstChild(), isNotNull); - }, - ); - - flameTester.testGameWidget( - 'is removed once finished', - setUp: (game, tester) async { - game.camera.followVector2(Vector2.zero()); - await game.ensureAdd( - ScoreText( - text: '123', - position: Vector2.zero(), - color: Colors.white, - ), - ); - - game.update(1); - game.update(0); // Ensure all component removals - }, - verify: (game, tester) async { - expect(game.children.length, equals(0)); - }, - ); - }); -} diff --git a/test/game/components/scoring_behavior_test.dart b/test/game/components/scoring_behavior_test.dart index 731bb481..2afa862d 100644 --- a/test/game/components/scoring_behavior_test.dart +++ b/test/game/components/scoring_behavior_test.dart @@ -18,6 +18,14 @@ class _TestBodyComponent extends BodyComponent { } void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + final assets = [ + Assets.images.score.fiveThousand.keyName, + Assets.images.score.twentyThousand.keyName, + Assets.images.score.twoHundredThousand.keyName, + Assets.images.score.oneMillion.keyName, + ]; + group('ScoringBehavior', () { group('beginContact', () { late GameBloc bloc; @@ -51,12 +59,13 @@ void main() { whenListen(bloc, Stream.value(state), initialState: state); return bloc; }, + assets: assets, ); flameBlocTester.testGameWidget( 'emits Scored event with points', setUp: (game, tester) async { - const points = 20; + const points = Points.oneMillion; final scoringBehavior = ScoringBehavior(points: points); await parent.add(scoringBehavior); final canvas = ZCanvasComponent(children: [parent]); @@ -66,7 +75,7 @@ void main() { verify( () => bloc.add( - const Scored(points: points), + Scored(points: points.value), ), ).called(1); }, @@ -75,8 +84,7 @@ void main() { flameBlocTester.testGameWidget( 'plays score sound', setUp: (game, tester) async { - const points = 20; - final scoringBehavior = ScoringBehavior(points: points); + final scoringBehavior = ScoringBehavior(points: Points.oneMillion); await parent.add(scoringBehavior); final canvas = ZCanvasComponent(children: [parent]); await game.ensureAdd(canvas); @@ -88,9 +96,9 @@ void main() { ); flameBlocTester.testGameWidget( - "adds a ScoreText component at Ball's position with points", + "adds a ScoreComponent at Ball's position with points", setUp: (game, tester) async { - const points = 20; + const points = Points.oneMillion; final scoringBehavior = ScoringBehavior(points: points); await parent.add(scoringBehavior); final canvas = ZCanvasComponent(children: [parent]); @@ -99,11 +107,11 @@ void main() { scoringBehavior.beginContact(ball, MockContact()); await game.ready(); - final scoreText = game.descendants().whereType(); + final scoreText = game.descendants().whereType(); expect(scoreText.length, equals(1)); expect( - scoreText.first.text, - equals(points.toString()), + scoreText.first.points, + equals(points), ); expect( scoreText.first.position,