From 41113d8b41a27ee1620ca53b77ac16ae3dcd2c4a Mon Sep 17 00:00:00 2001 From: ALeBD Date: Fri, 6 Dec 2024 02:30:27 -0800 Subject: [PATCH 01/11] Alvin: UI design imported from repo made by Zain --- android/app/build.gradle | 3 +- lib/assets/Login-Setup.png | Bin 0 -> 67653 bytes lib/assets/background_for_Fictus.png | Bin 0 -> 65670 bytes lib/componets/Account_Card.dart | 35 +++++++ lib/componets/BudgetItemCard.dart | 29 +++++ lib/componets/Stock_Item.dart | 74 +++++++++++++ lib/componets/setting_tiles.dart | 33 ++++++ lib/main.dart | 7 +- lib/screens/budget_page.dart | 143 +++++++++++++++++++++++++ lib/screens/camera_page.dart | 15 +++ lib/screens/home_page.dart | 101 ++++++++++++++++++ lib/screens/home_screen.dart | 63 ++++++++--- lib/screens/setting_page.dart | 151 +++++++++++++++++++++++++++ lib/screens/stocks_page.dart | 114 ++++++++++++++++++++ pubspec.lock | 16 +++ pubspec.yaml | 3 + 16 files changed, 768 insertions(+), 19 deletions(-) create mode 100644 lib/assets/Login-Setup.png create mode 100644 lib/assets/background_for_Fictus.png create mode 100644 lib/componets/Account_Card.dart create mode 100644 lib/componets/BudgetItemCard.dart create mode 100644 lib/componets/Stock_Item.dart create mode 100644 lib/componets/setting_tiles.dart create mode 100644 lib/screens/budget_page.dart create mode 100644 lib/screens/camera_page.dart create mode 100644 lib/screens/home_page.dart create mode 100644 lib/screens/setting_page.dart create mode 100644 lib/screens/stocks_page.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index d8b02cd..7951124 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -24,7 +24,8 @@ android { applicationId = "com.example.fiscus" // You can update the following values to match your application needs. // For more information, see: https://flutter.dev/to/review-gradle-config. - minSdk = flutter.minSdkVersion + //minSdk = flutter.minSdkVersion + minSdkVersion 23 targetSdk = flutter.targetSdkVersion versionCode = flutter.versionCode versionName = flutter.versionName diff --git a/lib/assets/Login-Setup.png b/lib/assets/Login-Setup.png new file mode 100644 index 0000000000000000000000000000000000000000..ad89e46f8cfa0ae481b72bddb7ee717ad8e54cc9 GIT binary patch literal 67653 zcmX_{Wmr>x-2V|#QbIap0@4lAF;b9jknRpaYBZ7p0!oZ-5Tv`iySuv?FgmvX{N4Zi z-jiM1gI#CmobUJZj@S92q9pSMgA4-+3F*yeSt&Inq!(pKNH6oyUL(GNT};d(-d=oD zlaW9w8>2Wxd_ego@mT{6@$x}44@W|JkMvneT*K4wq!r|;q5YeltjO2s7m5VhXS7q~ zN*Z@85{TX6scv)A-{K~#$AWb}Cs@*9@?kRH@Nu%=H1{<3s-}T~_u{Tgf(O`vJYxl`Ko;BVV~Klt%3BGJa%AC`@L(T~nO zk=ka;k%aHU*cJUZKm|C^usS_Y|6qC1k|e!1G3?35H2zpa%y5h6XW4O&+nY|Dwbc^% zNiG8b(}inO*>K_gRlp}FQbQ5TUJKuIpHTv1431aSih)kTl^9GBm^9DT;_$WgwpR4A z)fU35{gsBmBQvh;bHdGyH4{vA)s5AWbl%j}Xq`Xw6lKFn|) z1N*T0dI)&zEqcG`pn`m$KkP`|g|W>4*`s{Bb*eyR#W?iswp{@#^d$t9Rv(w~o8<)6-RlFM#_E{5!k$K`DsKf6QxUZdy0mYO1~WGYj^Ya=@XV=oTixnFp= zu&3K9S0N+oZ(YWxo$k^J=TbiED_kJ;kEi>kZD!-SD`W!@>6WUqnatIL5&qwa^Oq!2 zQ{lbk5fhez9Pg5Fy4rAHi_FSh@g-O`N;g`=`Nt1$?j}()!_u+2hEfG~xi=dVF!T8} z7>I~*3Xs$T7;!ByaNh?7kaESuxC26Itn|zcO&8`8aRI3C+xd(TlImM3`*z+N;@m9> z4XP{%VEqpT!z9xGKRsb+!$Dg`>Kj7i!Uggy>%yFNhBoHqVKSdK%MJYj2X0kE!(coz zBc5+fo}VUtL^FW&8dR*`^^2Z{T#ZFHd~s<7Dk=&nG7Ncva#nX2{x>KR8|(0`j=a4X zf$E5mW{xGv28>gxb}fQLLh5non&{Vp7!QmWP*iA`0NnoM`Qk$kI(TL*x=x|y`FWlX z5*(SX-5-7-{O}0m6g6zXJXML*3JAUSRT}k%J)s6OMNQ#F`hyh>c&`^{vxfq;Db;a9 zxT3Q+P40$`TKXReZ;x*?jc`C{SwHr0%OtpMm8N6e3yCtcvom=aBnxn+WyFG#floOq z{Y!xL?i9~ym+B|ok4ot?lC=b59{PcN^(UNJ8*z8{qSZd4BhtYpAEA7Pc9QyznUEU;*S$Ifmnz{ z-XFSdpfAYmqon@(4pO~;x8eB1ZTgsy`=EPC>0hB0z$$LF&CJ%z_;@14 z@lwA@kI2mO3m^DwyjVt$P!tkiYs;AU*EvdX=qd4fA10a2Uu5LedF8^~F z+ASyMH>2b*d5r&8{5>( zEXTm)CkPRcCQN>)iY>)!#E= zZLsr=RT_^ZA>Ma(w$dL{23=j|tkjejiEnBv5`h(-?u0b-_f?!5e`IXt897=C`al{F zv@UL+mH{xbn1qv-T?MwWoh@Hn5dn^Gwv=?WWf4B~t4M;kZLJOfU43nSw34GAIZqUK zf|Oi20x0}Jmkk>5thJcP@{soU!|WR?Ge2WLw0%E@fx%#i$;I4PU5sp91;B|g${$@p z9m>MX3KMs9;Y#zeEor)Y+R&1Od#NTZ-wiA)!2Fpp3)r zr_M)7Nc>rrPgdPI{PK8Q-p2W~cdKbRCQS_>4D^q1vM|HeE+i_!&xAfLxA&8Pi`+wB zTU-w=tIU2FXD&ik07MRF-b<;>WSW?9&+kXk0rv+u2Z-v#!+VmpaAg)tr|N63s?` z4vBw2QZVhz`01L0At?{PEmGcX3-?S_o%`t|d z@r0?PhhskA_eY#i`e#2Kp>`r7tpw?3(jrc_F|(A|#lP7&_dG}RoPN<~qcYw$qi+k@ zlFOJ-ooZ6>U-&{jP%ugEPUn2TUR=(89$$x(U{d{|qyJ>&{M_8`KTQ`S&$qzZiN(4e zwoiz$unXk$O%fdebe_c2V%la`mQf!`Os*qi^BM(@S7KH<1LK_h)nRkmv_+28`XNi* z6Avzj^M7A;LL*#EAFM4ZG!WZP;puQPFl_+{t6nRDn7@0%4HF{ zYQ=4-4!>>v@79RkXZ4w{z$ulna?tt2)Fi%BjEAwXkt*|36n}Lp`F{VytS|e-XlVC= z*vMBa0>8EW8Y1ZY+C7t>`ShWy5h7Qh6j)wjz@!*84kZS9sf!cZ{$f!d=#v%Q0~N&R z4#wO|vfB(ib`R)%v-N+%KY_;o`hAj1aTWgi4HDB^Xg%s#7tY$Fy_zUo8y6Xfp8#f& z>}eoSbjZXTgDL>_aMl3sgxqQIIP5f4vASu&rj;SnTN888Vnw0N%WLvDIm0~*iw-~z zrgmbB;0q9Sq&z#e6QHUxl;dtmD6jL%*egj=cm#*)vb*X*PG?qyb+~iQ>fNXVc(Xe_ zjD8mC`}PGlk8R3#7MwmPG0GT+ZlW#Y#?#R*Y7SXQ(`VbunDg~ywh>~bA)JW(mO7J0 zmdipn{F-`(IkCxVS7S=Dtz(}UKaf-wp(c2ru*nv<%vSNW!CuNWRtv59& z%#}u6ZR-0b{gswQ^9M6qb0fu}uM#H9<4sxt*$p*MA2PMoflQb5mo2~h^QHq2b8nf= zU>nby@jiFkR`Z?lC9YJ(X-DfHDQ85I?te|H-Yt9Zc2ArS(2T+vtsR~(xb5DHvMDts zl;$Bh`&Kg-)9zh$T!zacT0L0^+ z?C-=96XC5js?Ve~!3D^~+4-l)p%Ot=&RduN)B9>rpG8v=qXgJ-GEU$))%2N zr=r&7KQOO=LnzYw)bU8=a=BqguGJBR&?O>N9uS-t34vswy9w6;xArH6zJ)oD%z_22 z5_J-s{`UTg28oeo4gt{5UK@HDb^4YEr`9`liGZ+)aynoc3GVN7%1`(0BVHA8Txe)3FU z8%3v<=^Zd2QPsq-cg-*`xiaEOZCV)iI1|w1)wBerqlgE7n1V5)jNPHYf=GTE3VFd{o?{}0H4#CRvGpD)} zPS#n2OD-xlO3cGDBsoFe{&UyE0=}P`9^N(OAzNMqY1I^YTki>>7c|5rFl;8ah~@>& ziP$cOe2fbm_jjR~>8oWcVa0nIT`duB+4C(F2`iW?t;f7!-7)JD-JNBL#x+B8h&4V}NQ(eZKly9;mfcDakL=AcQg!aq{} zbU>M&K8=1eeJFhYWe;bv{O4`h^rM+T&KlV<(-X#*I-w!H1k!A?p7mHk!WOPN(UgAM`=>R{(T&O-yiyw!O$FPT;Txl@Q z^RDGEL^BW&=ho5zbcajnSq*P@q`_?gB2AWx>?F!%pLyWbF^HQ|C`j!Kue_~g=ho2| zwMoXL-jB7e-}iyAoq7h$DB+i_3K3+Vd4>uYk~f6Q83b5uQV(;dBuAlUFk=|nJS-^# z{HEN5RfO;7*_!BGZDAo**i)WhFk+k_bADJi5FB_lOaxZkloef6UW*g)e!p`qrlMcK zuwJhWrVBc~arn4jZ|XSz1M^f>M*3~Ud99l~6+SbhS+mVezxf5=Ou$x0ANISY1Shqe z5Tk+ib4(^Nuw3S+k$k~!XXF8wYg`MN7Y7y)ZjOp&x;?suTtG)cP-7AzDy*5vx~0gYkbHf0m~btx7hy^WpCB8n#=`-8*4h_GOjXiN751zx{G@nXB}-;H&zr9Py}KIjFnLNXm&u`=HYlX8Oeq7Pq^ z6VEp%V z@vmubI*4zE6#r@)^A{_Tx}sTEm$- z3mciyxVup=*4OM-nXZDI@FS(qSA1{je$rIcKsqL#Yb*aVGSSOA- zC~d*tf*;U}=4~@xjC1?`6NdvV01TI^3M8joW-~#Ek25Zt+4P|7G#@H!HHC&{UXKf2 zx&SMm{CnKeGeMzO1Y_|*k2-Y6Z|wW-kxE(pANrx0lUrPBQ3xEvz31LjkBgBbcYWgw?pc6ALiy4$VOdk_A zrniF&#@^{3L>j%RAeyL;uCZ%|cow;%fF&gBlJm!2bJOvB;W>#;p<4 zgG>VksbV2TGAXO|GzzDbEBkMM^s2>IWOeOV#ARnV@`EXp6@WB!p^_MA6jvWb7Bt3;aO;0Vx}+$SZjHH7%VJ zaH#~Uj-llWALBlL->vb2Mn6$Wex8Sab?L?aa(Q7$z;l9z+Fj}j7?a5|hxr#a+E_2a z`XY$L%W0L=1Bf2UtkxzEdsnu)e}(?Def*gRwVR5#5Dg-z(B-y$XFQKrVzH2`7xgOq z=8;I(@M0n3gW8i{b~SklTV3~J-LP3-9Tx|7U11ZJW%euH$^C_?)t87Q2IIh67`|)e zbX+LG&d{P#LT4>(#4VBpc#`<`T!3-z_v69uerTx|?PAP5{Vb8~-tI5%=5zKi=HTv2&1m>T=yr_btIOzjjPo&%Hqq!CD2jn!{!^^~KvvV*) z#!kjQk^UC|z888`NH8ukZw8HPNn8?g8^1jTsx{h!D0_5chp z17OChY6=CTU(^-Za5+&!H63mHc* zvcw?Wy%4{++QB?G18t|Z@AdV7tKZ5YjRNPRf3)OP@!Aj7gzS5x$58T#yQ_d|oX((k zS|5`mI63@>j$QSLPed$Sd9gpnDC_8d+QoWvUBKwsrWHPVrGn+Mhq{OAaTbv!Iyq)e20we>{$Ca7IJZ72gz$mYfV|Pb=Jzh@=F5=KE;OWHS#K%7w zM0xxqmW;>~ZWQ4_`xgXh7cR8|TGi4rU&dq~$Nt@n+rmf~MHtmz0rd2u8IEs<;-CR5-w-@+}^*5&7*rBay3ey_u5=NeVkni8yi%9F&3VO z^HC#{&VLM)2?TmX=PQQ#Cd5>h9_zTRj6l8(N1A|qEe1Fft*1_@wPx?Is1EiXi_!$% zW#~1^4m~!md64^6Tht#|o)D}G``<@;p!`)KcUPnZ8D=9*_s18PWgjN_d%_C|VjcVm z_AJZ-muk<8l|91!H1@7rYrHBQ{C=H;2{NJ1&aD=&*B)@Oq#Px=e3cuVxYciU z#$1z-clL~r2bWX4(QU`&4-$I+NZhADT!86;Tn{W6Yy%cv_W?v(i3)jSJ)8hfmvN_t z5^-Mgs+vD#wG2GuNL8rT*6mm61p#*Bf%;kN{+rG=%)$DHt&H*W2i;-#XGyFqY}lJ$ zWtEl7HgKbtCHY(YgeUvWT3eii8_6!Ke@47Xy#)kqqmgh7H|v%(wb?o*5P(!H=e6I1 zzRY-;4{xd)-bzY)YLApAGLG!lCeEE5pR;v6v<~rvAW@w^(ROYsdU`7o9$DjG4-C%B zMg2H5%Sui{WTsVTVcvVZvd%18ON`ZNSyj@Y$ZrzjXy0iVa z_2P9atf4}PXuZ-$ua7HEw)Bpx>Ex@&>S)JsSI8v#pn6TinkKa2B)+Dox_G_*yv1e5 z3r_;JdYQ$pX6cA<8(v|OZG|7uXx8M)% zKy@G>RtVIdX9qtRA~LC$kIL!V1_qtbuq`GHXoC+TPP33C*zATTwpl0us3;Iu)_;H+ zz+^?#1uX_gp{v~8L+ZP)+w|yevrw5V2|Aiyt-XswD4b%tSc?qZOnczm32kPkK_f0A zD$XBMfAoal*{gsAKHO*P>8Ge&5=kuOa>Wykr-l$r%VZ;t9s<}^Ay&MPO-w=Ye_DBM zBJeX`11;mZ7-5!F-zk-zL%4_c#Z?WXXA&b;w?up9-W#C#O&nw+_{~|K#-7jVloQFw0AWP<9%rjJKfEJ1OAbzg-ItZPuf9wOFIaU!n<1X)2Q)70+v9VmE zqD6x<{Tc`z-(Y)%y#J##`27!MWUg zW<32mcDqU%Fb`a1d>jArtUv#YeoBH<7Aj$JTshB2s{h=0P}HR{lkS&wFWaA6HFXX7 zeN6=|IrE&HU&M*Y9-GOQol1DccY-QWa%?7JM4#TSiDkV`2$?$jQ)mBLxY9Kv{_~(^ zQwF2~8E`5}QPIZ9!d8vRg`zLA{~~$JO98mMllQ2oF)xJJdW>OTqkyKB@>H~>`_yS7 z@s-E?Im;W6owOSp0}ktB)HO!+HZsG_KgtX3MvGLbf=r?1lb{!Htq?U2}tD4;tw#TFH?-13m5O=a=a=W(IKbP+#|Tn&lhYP5u<9#Zg9X&~b?*_o zRsX9Iv)J?ursr1I^@AWj;Ihb>V93_x;CNRq0Tu66T#&niFVD5vTgW~r#8Cmb2Ur7| zfB^*aIlq;Zbojkf$GX<=_kC_4^2J0Ef5|?YqwwA_<4Yeup%Km#Y8ZE=hr^3mnZNgg zKgt4*bFR<$m#}2U>!SvN8Su~u`3np(LhQQ~ghB3j6c1V+WWXWP1a}|Z*FFpi$1eG8 z&muqZG-07vn6#}^*z?~{9Z8Gj$FF>JTq6xeXaHRKg2x{hJ?{f7cqX1vUK-8v+ z&9@u$Xuq`og2~5CR5eLQ${C#F*52B!`V^w;WnLX5$`kfAW!R_fhld<}SbZLRz9|+t zKO;u9&n(|>e?AgXrv%S2NGBPu-M>#c;}(}u{Be0CxjW8`XIKFEFFqR#`vYbTUMRPX4N%bB)dNNdFlwaU>*@;)n6C9!Yh ziNRB5K2;T>AMfx|5m>yRo+7Tcaw|BM_5ie3$AblQaj&cg2OK-W1{p zqIvI?7mL=#A2-L+RygNd-+i-y90)DW%ba!o0kemPx8(QiNRAS>?1+miy%r9;S8-4HwwV>FTh#1_!llMWaZ`RCl3A{&#s1|if224QMXF=BaB~*sk#7l?f+3}nH|Y|z zC2KO21-L$^7lfN1GIQ4zk>YUNDX&7Y5eb_yQ|WpiB zqsYTGJ|mjCy{*kTpW!8;qidG>I=tE8aYGJgFTd!Rm-B1)Wmcf3uudS(WX5{P;OxF& z^R>lDZ%~J=x+d;oAQ{5tbu};F9v^EH%$s{;K%bd=iIcGvP|@$R+I$Ks>iVi#x;Xt& z%_MiYC_3|W9Q^aBSYWmNi4P?*aeukA78<;uL|W5gu|W?$_!WzLx0&lmoSaEZ$G?Tw z>P6Qv=g&nC1Uz9!*SC`omwyY7{h?%pJfOApJA^(;h;Darhq@7nvgSWX8 zAFtq`InsU9S0e|p9?Nt*{qFmR{b0zSY_F&FQYUvCgD%ZTR=}OFlA&rJE*UA${k{e; zlN_wX-}R@2BJV%NCqw8p0%!qtu>cJ9+9_l^K6z6Jtw;14DSMy7`<7hrj$MYcg4g)! zP6%mBgYg0|;gTgrNy#Z&iFyH%;PNhd5)bpp;rL&pMDO%mCxsWe;UK7yyBC?yV{)x1 zA!Ugg?_06(f0YfVt^uO4I6NK{yWM5BBWkAmB;~pkoiMM5Ygl%1zm?*mqb4Num&l>Q z2QH{<(6#0AvuQVk>s1nRTqtt!{%lvvkebce?Z6^YmM0iglCJ#|WN_~{Poh|#wa9I5 zsNa80E=T*uE%uVu+DG5M#4dh5xvtEa08C_EZ}u)jTaRiPH~e26GxYl23~vud50(|Y zjQ|N~dUD0`@f&%m(L?Gn{D;CG!f@(3CW1^X1RBcHt_VDxcO~Z0d~?>zMVDXB2ui(F z8%;6XNcnrQ1htBkPk~af2P4X^2?nvOs6UB=^NxP-BB&UAWIH4Q^S$=zxBO>=y_Q1u ziZspP1j=%6ortrpklE_1cImEX!E9lE7sA)aW;?gvSi;T3&%|~cuLVS!O{wCuY2PnD zKyquZr(^1nU%dM$pc58***j}d_QS2#;55X6Mgg)QlALi|gA&F#`-ZUBZb z{P_)`X1M<~)3zC_@Gzoc*nBq`Uq_oBgMcEssbE<{yZ+yObHnG&g+Dk6t)M7^m)vUH zkhSy?p53C16O68TH$2+hYKOgXw9UbIKkGL9UPwgq!5gtjlO{{n#SxW z>7$?K(bWeqByhLj*CGa_Nm>&kbpuL$1-7)fGZK6*Ls{!=0vYH4l@rcX3_lWTjTObN zsZA1jKAECYG*6V3ud~33H4{2bqdYx0PU~_@0F1G2gh#uN9BhEZwKjT{1Mila^>7g;(ZpSm0~j0z zKvPUg!ewury%emAqmK>c4F|YzO>Z<>K&hA5qx^s~c_)aa-?fOHF9QbpDJjVXJBe0K z{fVu>!jWNMGYYRJyd0Uw_-4&!@~@4%?>v0w;Ng?+s2uHDAk&))E_gS@_ZB)@3f_cD z();ebAdG+?HGO*T*+Q-|urF9{T6-7ir>2i}Kc}Pp;?07qTHWUT@js}mhNYFgwSxS) z*c7^c8l5o*;RGn&L0=mr`@v$)Mu2gSa2}2LE;(1_L19^{=dEq_jj>j5zs&KbSG6kf z;L~lx>E2Am=|1Zbd4 zM*I<+5uD8>9A(oV^nX+7zqPF-^H$ZR*zbxP9J=a+hXk$~JFk+Hh1S;rNVMBjONxn# zg9fhju_EPnYzqHsM+!r0T?UN33PB1Z0K^Y1})k;%$`t|NT-_4Q@+ZUMn7TfWnP zWsi!;ik~ekJ!>Z96GtxHSr}yHX8vUtJ9?kwFtlQgve(rLIeCtusT0>m-n|Xfair{V zd+yzX;fK9G_k~a!IW=UT{Y5u5J*HCavhIHG=qMY|hb;M1L`Tzll{j)RFb`bD#8IV+ z={HiQItV@@iN0-X%5KN7h!FaJ;{XP-w&Y`@H_6=;k>H!jyRS9DGH8HO#TH1lsrXY%g*beEybG&$ctLD8CSPEFt#Tp4~#SH$2%fHA;E~uZdx)Q!-f+M<*t`rcDU*@mbs+zXJ zL(n+f6Dm2jy(P>WG|nG0E(8pNo>2d`x}|4#4B%(cVBVfs2{v_jaTWvCVhzwJ5#Gen zvCt8Q>AjM+Z6hBRaS(73+}KY|NJRDzU{y9JL7Zk0tW~QbQHnOL33~-VFL3Co;|VwV zIW{8&W!=l==T;~_p>0%02-ZA3yBi|0_W)qQwX>Jwny6(kEQp67X*Q71?tR^$-%jg( zwuB#g`emNmTqEU$3Dnn!{!4J9T6os}-KqCqlFu;`<*Ibas`UM(thD&4c~Yd(M@B+}`IQ;s z@yVfYpg-|_xDjZUaH~(7Mgr-`t@NqnuRt{hL{=fBKph zRe;6(2jc>r^p=8Nu>DlPW~EwZf_1ECo8|vNq4C0nEE%tliAH}kaa_^sBjWC01Zs%= zMYPPO@H?q>_5g2+E?c*=YoHp2JjZ2Qnd@to;uya_R+~&$;Qsujm;yiUH4urg)8Ey7 zdYtHg^V&{`%l~c%J^5Cq`$UZj%c4eM%)>Bn9EbO3Bdl_VUUSOxHMyCZ1@3XUmh{if zNmWm$eLT;Aa)~dfoteF_8pSF+{m=Sk*D`IL2i++*t~ve*iV$RZTdQs#76m)X$+t&y zBqN=BkzaT0hl44l9Y2u?H|F_CtZ(jw#TcCgsFxa0`C1ri3AR+&s>)`%T}l=vki_vwl8C`PLlEJuz8qQ6G%gXV@VtI2^362*D}C7N`wq^_PUE!5ySZ9$dSSX>98i#xEw0 z1z|46R(|LGI6q0&rb-Fmd}F5ciK(T=%lV463?4!RwtPjNqUOMt3k%#&rYuNPS+(mz@TdW|{XIAR zTV(4b+A0N7Bk_Ov$$J7k)`hccF=t@>6K^Mi`$(;}q)dHO`we~8DhT5}76%{%#(?>T=7;_x|r z7jNRlArkD7K2}n|Eo!73Pl<`E+E7@q((i~dSIVbapVdAN-->(p72X+CAp$v6cQJ;Y zn40(s2s}X6!tlc>Pfj|ANU$%NX#wnI(S~VC;I18}n#d&by)1aR;CONEu{|!T0-zw~ zyqnvmB>2zm)54Lp@9ZG7+H#eNEt`wCGNOH2ry8VI>QeM z(OQ`*T>8u~kMiuP?-5ok!JQ6o3r>13pu+2bfg4W4OGo#fChGlJdbp4M;aQ-!WVgxg zxK-k45VF2r4Js2`w6nnGPlc{f>Z2NVOTzKca?9-Z#&&GXfy)!yoDF)}IsvA@GPIC} zJWopZhmFenS`PfpM=q@Kb;SRDHY(6H-y@4Uft$j$!(r?9%znIjtr)?yE2)B)-DT^zQV<-EK! zr=(ptiF+GkK`P;Vf80-Gx23E{v$mB}@6cAG`k;X;xgCtmX(ZFtfzcoI4GI z1y{XDZ+O$8r+Pd;cD7SMvnpJy%KoA$$dOvv2CG|D>V`|mptXbWVz*Ep@T}DXhwq3_ z_QgvGAOv~)G$ur|`YJn3E{V*M8UoMV%KW-6Rro#95am7o7XI^7k$gHb5s>t8 z(4pt$E6q#X#A;fL4l-!OOv~GCH6ik8$;nZ%1kk>@3dG+8-$NzE zo+=1J@)|E2W?QZ3MQC<2n%tqhJ~fZwzDvh6H)(Niw>A*fm26zIg&!;f9>iJ3&`|Sc z^fLotpx~w7n`-%Vf1`Y)u$m;e`Jz9qj=je_tsh`eOZ|2hgS`;x4t|1XO3WKk3yLmH zYczJuyf5SG6TE!m-r^a_q7mapKvxcg`oRSj`rz)sWR;crQbI7qB+1pp$`y|rXWZVj z@h_E#Z3ndgGvkp4fp8{Wz0ZCRL4yJAykGQh()APYNynGn-da3xAgJ@NpG2QJA1oGz zx)&WglytH3Wc`~R09Y%tDe`1t4>F%cXW|u5j}#o-=5-UaX7&a(WtH?^vi{-Uzt@!< z=lpN6Ny$;Nl$QtmO`gt|CVu;F%+0;~4Btw#<|3CKQ4ely>dvw7?~lpfp|$KmmI@0rKY>Ox?*x1vHWTB+IWi=%_KxAF4k^k2!o z=Syx8TG9+XPJk)3N~%i^QRTkV;QyJ>Y@}?ABFAj};XjWcpY|S0hZZDmo8!jc-3k1a{q5ste-BGWqyY4$mEkBuXI)XsA<*=E60V z=T7_^^-xf2`tErxm#n)v5pK1!-*FUbYoi*hh53`U%z2#Z=`|u>e?LWFog{+4r%3{m z`UQJ7_H#m@y7{5m@-p@cQD5;2KF}R_yw_8hv=TwgGResM52;@!LWLo#>_ZWv=KnSo zdg(nJC)XpLM;Z}YbVI}Ho_^$s55)>9_Xx&3@WJh;a8F?*y6>#S@At?m5;3u$H2}6wC?9rxrR0G$rVBg~rY->*Zl< zdf3KIhrxUa_@K$wk(OY0_drm>QtUOW8YJM!!`ivgqEd_R1)>_+*#DEbuSWX)@WOf` zNDjL-v=(#qQn>u;rqc>lxyiEi)gr0RPopBWt-4O4c@j~Z`m`(0^tH;51^u~_I1)_> zrp@^EI%~_(X`#_}tyAS-m)eXkyf|ucZ}lyx-U6abStcckz{@qPhM1kZCe|5dep0UdaD;)j1WmBfE>&oD8dPdbNjXoe}`CHix8PAIEVFAIx zIluT{4z7zHXsFwYf@WcD_1TV0BJsW;QHkHHOtZX@D%B_bcQQ6P(Oi?7%`edVU+wgi#Y3=&_q*GT=r2 znXVBu4;@-3_d-G-cMK|DClk3Z7OakKT=D2~u8)WwCTVzq>ud^q3!tqu9iXm$YWxuC zcT$b_um5vao&N9&YEjPkT%Sa#fWz7` z_Jlk7%t6ciE<=9__c}?ng0nbIC-}A}vbj7ig4Zc6a+ihk{w&^-@ zA#aL%`+FUc-dE#!vMt&aRZwO_EKy7rKFX7{ds=&v__ae&qKwg5xmSgOK46uQ0;8Lv z<2=fuT0}XXe}<2^x@o#bY%fz=c0)AXJt!OAp#x!?5`z4348t<9ydek?nK9_gd7S<7Zd6bHk$3CsIKg|7vcvfGvHLd&SSP0f>%zKu$jJ;;IJb=TOV{`4`0|rv$^*f~gZ|NkO=&&T0u!l{W~4OCO}aDb03k}T| zNm82%P@5Lz>uJf)xyFccG}Z%%i?*3;0S!J@DML=s(&1Eb4H2i)yZRhB4d6AMUcMYDCWR9Bqt^st}DJJicRIf1r;Np4zLWa zro(tXAoxy~s-VyL-(zUdp!i1<_el*M4NaooyZEO#4uYOXX=_9U}({6H2uFm5?i!B-Jq z4Y-Oib#4^O44NMwAOBoK42^5PKm3vZjf#Et1XtT|2Lpm%A5t=99X)acNjBaY2Re&E#tH7&W5sE=;xhqpTI=$lL*T3QNPYVyR} zwBiM(B?s9}5ZC7Gv|m!tZkDZlB(i9y@{H-%OQ;cr&`a&fEzW6gT}L9}YL{Q@kClBR zX$t5Kd>>Kh$Li5(Kh?fG-7&$Y;~Vc*Q%^1$G;HF=?dV&Z25*od%Y5HtkL^ z!{SlvjNQ>y)@v$RR3mnML)p3>(bjS1Os}5~e50I`FBv{EoTdc!mPzbrruh>$zmC6wwQSCfi{z+VtiU-Q}CuP&X4d`rd2y);_{ew^!oZZ-JTjeU|E8(Xc8v1%>486y9j`h8# zbtR_}ce)|2{hp>A^~K@@DQ>B|(wwv|q-tq{EWmHLCU;MNd#R}ebmV&vZ}Fr2oTk5! zGzjfzV_TRYUspA`$absagSab(dTwv0CQPv;! zp|0G?@%U0zjU3NMEk2VuP8*$#g$> zj+Lb>HskRqAhEdc$s zA!@qsY358c<)*}0?$rXwE4QefuROlvRSbVWTlgtON>x1-@roNHAc2J2VoEBd-C47J&8HCjyA zvz=GwhYzHupHN`&9b8>XjhUpFyp+|_7cL3Mz)lN33Gd19$&Y5tgtXdAONBh%T1hCLAg{#v4K8@oN@PIZm$J>M>5*MbjFCKguscg*Xr7r$b}BM26Vz>DHHykRNJW(<-SE|xh$nz=zYzXlfsbdS#L?_Yw)UVT!WOw|a-E-|C1ckezwN zMvrguI#nJUG$}A-elX8y z^Ii+!fIoMwvx8Z|19hZ_=GZ-=Z>it%6{p@0qT1+P*eE*FjfnF$Eg|eU*$6GXbuHnj zv4nD~!~-SpKJ8kO$iYTTEP9FacgU6{3R<3q^i#rKVb`)XHNC4Olok)i-$h= zBQ5DPG5*#$kCslBBccg+Bb?y=+2a)o$2ZnbCakgp8yr=+?{;%#7*$*skezTz_~$qK z=CL^n0br0_OU-y?@3_m;V_NE$*p>uvDl5lQR)+h+y0-2Z<@78-!9Z?69}ub_Cr67r zCU5iYS!irgeBk~_`NNkn*iC#ifMDt3 zwuvcuz_Va4upMMK``nWcJsNT)TF|HLwo;3KufIi06!i7gUpj^V zq*>j{eD=huiM4zlMm*sQ;KPq~KiyKRo4a)bheA$IKW7hqZUHgS_i`fB_t(~FD6VNeLn8s*k>0AW)|Zhttzhi@$~nddgGs3XHYK2s>42( z04G;ZcvM&bt{O{V@0}aV!yv&g{!n2|hmD6Vnw3qAxIkrPcaDGd0Ey85D44UbGq~Mv zriB3w7oSv_JAA&=%RZYLP)Z-JnBrd6Xlc&jDb?h;APCN%z>aQ(+&3jWBz22-6n8W*y!FK~=(w#S0E4dVMx_t^a`aemp7c1LAZpJ*6 zY$XN{upmUI`&?i}18w#8F-nR(vOzT&G~+$8rGFLe)%~+p<>`VGY-7*jI6gpd)(Jq51dVy>vPw0%1;{ZGow877TKO;yyz)a)A;;EShoof6F+g=SQ(sY-nc|E*&GpFIy)R3%5Tj)-;-rLv@~)S+B@H3Yh#hkj z$p#QpOBF_c;(j@?{#iX;O~8YDRaY>ryTdFH0jp%zY2TFqTfGr`S^lYCVtg^zQ*?Fh z0f`J9Cfc6j`8CMYd-+>4;2;l$AE=cVT^^(qtcQlK?EQsm*ht*)yWUD6BP*i+^waR& zhY=&fm#0e-i4O6Qbw>+-_>Qk4d2mTNYSfhaL}4A4eZKqg&CfLub?`05VjLrHeIwp= zUt$nHW7ObXIz6kUil{1j`VELONOw*wnQ?xl&AS@5Z+T860DggSx8h2;X?sU{RVe)U&#t26yYPwjpJZ<0 z^nd?ht-oEjhf+E{n6}2=zOAgB8P1ZZFOl5LUCkF|;eA{42%?{SjfWR$E>%ETv;jx6 zotm}wc^!Ru3Q6v_cmKK(3ajYLpnzbAc0=_lcm2**Cf9k%wCYNU?Yxw4f7va#rTCQ< zn&EyT9(oSdKg22~M$sEglihMD;e?B^-^+A68E9I5lhK~7q4S;9**yYS1)bZuouz>U zw3&Pop=lpgR{8b+A}YP *Df=G}45nQ$G>eh8Q;8x~L-tMJWz(rH-s4dzmMF9rZg zUkwgjb4?vWexqtR8(voli~}7Qg=I5IjpN=hS9MnwyCnFald`M))i%A@do;nozWQvGW1aA!^V8z_d@)Y3Z6 z@3#(iF3A~~RQY5K_Rh`r#a+{Gyhzj3BLpjB^R)Z z753(uhu)1}lE}0+D{PH5^9B%tx(NFo1*Xb@+yIIQxy`k$Jwho?qRXY;I~$?Q=Q5c> z8AATWaMSGX%ZIpHsTeV&`o*;ZHHkj4=c#0{ERx=4C}bihBssp-{+y@{3u`5=yhJ!t z-z&UW^hhzLsx2xKXlMlenK6MNF@P1uD^zA-IFWdR;t5|FM1I!H2I9+ujeu&(YT z)}Y44*czT22+~__?pZedsYWU59~Sa2Qvl-^cQLoCd7Wu30o`n%LMLZ`G?X^u`=+x< z=3TzikaZeh`1Vuu4tp6Zsg*Q}Y0~w>!Up5jW!_2o{3 z5@+tsDv7Yh6ZP!og}0FXg5zIg0fGE=Z>h3Yr!Z7lfW~W-7ky8z3zgo@|4lKX9J%l* zuOJ#>N-gGRSZ?L<3kMig^;!AfNwc7ma_c6%;Vm=Rwis>&{I6Xw~kplrTFY@cGqM@rx`cGX~=Y^eAtKf)h zY$OzgavaV6o*@0uXC1Mgo>e1E`4@SGW6^Ms#G(z(&}qg|D++E)8i;aBuUj>qcj`}a5<7xtPqp8y`= zOB+OXu+CV0PuWIY<*K&LYZ&OcUWXkz_fgB}CG90;WdkxoeD!VttM{N15Aja&S~3X^ zoD!mlf-yeKV|Shg#1x zlQT@D@TXMP2^azP=JqKcfzB&BF&3$eRc zy2vUj_%4k-YFxJLrstmQGL-dSuNu!48eJ!$mQYaSU!Y#f1BQHG2uycud1!~c9x?^=F-c*uYm7UKQFBv{M*VOXgct3ZOx3H4WIGT zpqaWgXi8|wD%(NA6qc*+a5Ph?=N9KBBp`xl;Sh3D(fR$R}c~ z5s=*38&!&Vdb2OD>u?lYO(#4e)2)4ElB!Y^oKtf)U+&{tSl=As4EcBeq94Re;@cRC zSW1)|Furu86Do2qZZ&CS89&ORC{?&b(W(${zqxt%w+uv+OZ1F(5kKGMSec=Z(6L0` zkgwj{f|s4~PQY&KN7S|M&rKRsZuY7rvCCy2G$-5^JzR|BD@Dpx_pz}Fg0iNSV-4SY zq?EC5RA6KtdyHA389j1T*TVo;b!N@ChAJgT)R5!vOdR{P2op#7d1sErd_n62+ zy>S(Ff9Y%^Uzl|wr}6+d7zy?E{g#BaPi!vcT@7vGgUhL}+jWpa~!%;`b_P8Cy`CIG4R^rQJ3-L?HR~%edB6c~+WqUdS;v`NK z4)2uqz*fyD)mb|EFTax~B8^Awh~uKfy!9N}>|M1g1q3U`YF))1uL;T5NhQKAuyzp#wXico4_BeAL=InrW-en7*@;byNmm$Q zeH5?V8Utq8KV)_d-C%Zd#*-64#>zK~#bAQA2I0fQ_eDDtOZfc)RoO$yLeCjA|CkJs zlPDU(JrS#)>8c#7e;}`lw`$tg#MVz68#Od^G~o`AVxs2USlQt`e>T>NqAi9*R3$ud156>iInWJ98i$beB_w{^7W^aC_eFh%%<7pUkpkCZc_Iod`k##Zi7T2Lc5Pu z%qbtRB_t1hZwk;6t)j~&idBn|4JrM!Y}t2B^)Fi0*nS*Pu1i>{F<(ag291!0Y9O0H z6`E)q@+1~9@K0~Q8-AFd6O)a+bcMJe%p_om3N)kjSmrEuc~uzW@~uCg1sgxcE&Hn+ zP^BM{oHk9g8rh%!3xZ9CQ_SrQlyD@&)b1VT{%-KA@A$KPkg29hc_PXMPBw-kf$S&$ z&`^gu=G&`J?Kjj&L0PGBJ9oDTj{$&!P8{*XjXmv4XnbY8G0yN=rZ6k3-DCvpk>kBiPLgqryzaAKQ)2=g1)LJ73nKTjofg9s7zO5U~Ayu>=D}vZjHuuAO3AZ&X|8R zaC1_L`TXIuBf*iuCzQgvCp55@KHF~e2q)=AfwMK;zJf7eFG05d>RfHAIVz3&U)YXV z-x@q6IB~qBSBGZpW31YSg|mEs=kr`AnU`E;H_`yO)RtF}2el$4+#mw9-)xWC>}lI0 zt7F@^Gd&&gK6hKWHb_Bd%hDlp@2S}0vG)FUB`FKLcsYCMOv3#WW<4()tW9{$6%;lB z`FW}#J}>cG_k$K^iU#1v)4j&n+9LZz{u*P`c%$pASQz1EtqlaKhC^t(S-}rqcqpEk zP7OQ^hOKIh4_+S0^0yi5kY7!oPqja}pP2W-%Kw7$Tfts8pWoCEktNrC^ZOukdd$1s zRxb7Q6pHGQV|X)C{Dz~KTJ%YF-98t*>I#-h*wke8D%H`m}a19kEgUab=`giAHn z;DPn!teuU%>}>~Wp%MC`>2(78ArtTP9K88b%SRYQK0K=bW2`fZLSK~WA!k0c^;G%) z6j?H9tnBQUhk$FvhwB<>qC=Al5twpkk)nwNrw)%B$ zT(N0!Q)h}004_%v+#;$*yP4g4vDBu1Bs-qSk4b+4VnikNW~f$P00mF{S&gc60a5A0 z@a0D>olu#zAH!!{K;`Rm>xb|X<}cuef_kjPg-q}h>9g!75{q^ub#ZKzzE9Z59s{*6 zu^5;JFkdZgV+I|m-*Y`7?ytL5@htS-bVOY?@n#)PjuwUPKI^HelQ)wM59lY=5cK76 zB;^n2haz~J87u0Ro}kMZtXk-f#G-J6Jd(W3sy8z%fow~%Z;e?6(sEqP#A zI*R+=8=~Kc()7#Pjjx3s=T9$R(Zya0B+d{zCF$89nPie3G zVEn05mDGuh?)^P?+c&W%>ZFxMBH`&BoZ z%oMkN1cpZj4vGf!H+fo0%FNfY|I)K?S@aV;BIFn&OHD@7`6Q4JN`$eFJqsFfLc_vF z?Q5Dsu+ofyO3nTU)TqYy_p}UQzJITEw+9kKA2hJ0G6+P9pdUX;{pep_!S!Ah4M3h=9y(ye@$IK*a9U}2Npv@^&-)O|)y#|u1J$D91D-yIk6 z9*vZc!MQxFnZj1k3kAvYu6Q6~CSP2`CkSDvAP(-wMnB#}d{wZlXWq)cE{uZHFa$1kg4A7WKmLNTIM2lkdiV*=-0U z|KId2e@!8*>=rw=W&rj34rn7QG~;v^Q>GVe_;C^HBO=1THBKPNq`m+-B|swS%vO4$ zC=$|iFSNhjYCot`zG|?IIp_uMXQ_STEbWr^lpGe|g!+?%N=4R~W$Tz4C2 zW_(_U!mD5-2i)4l(!ZpT`m=l#eaxvWN0Khwl>&`^H026^6=CyPo>G8BMnoc52y>?& zus}6}zlidD*r4Cm3Md@i7arv*q?w+c2|kXgu*Cf?Brh);sJZ}>Hj^3tX82FgoL;!0 zT6VHOd>oYcQYqRnp{~96Mu6)7$C#6m!za#;-jwRnax6x?Js1OUm_OUz$aDv7`9Ce) z0VZSISvo8e$}ks#g_C4}K%6ZC%l|sBWs01s{^sI;B$GJ@vyE8N>FU`*FDLURY8NNq z_`k_$HW*Mw-l0()un=FD3Gba<>-SiFl+$NtWFGaaIxuZl6Bzgkj8gykbCU}or((U1 zY8;Hsa3ab-qbXas{Oc&Mxu_CI!^)(A){g`c!r#EzpLOjlT9+`_(;k343*B^(O2aGC zX?YSP^4&y>5AAml`_kZHMjmgN83PGcxuiA4ZU$9*Jlz-rs5X~Lo~C-ikwEp=fBn9sFHLM8@BfL zjMFOnKNi4dMQ~zyZl`6JR_H~%JbY3^`y@1!>Y0Qan{##6>9r(!Q;C+&Z*-k;1@$Nt zuZnsvLl2}{tbYf&#RldEY~n`(CrXh?3mid}CVh+Izzs-AB4S{Ac>wGKnOh6zvH0VJKSsk0(}aa++? z*@4<*LY0b8nS-QH*}l2%-^^*;4In61M1F(bi7+y2ei&PB*_VCGnNK~$)KC?F+q9qs zrQ7>L3DN2LN&*`@1#n(uN@a8UHK0_T4>?^f({hvzEa*?^?hA-2Y#i z99fXSfRubd0bZW{wBe6e1pKTG)<~}jP3Xn7GJDrqm_@M+J)~pH_RYBDA}N%9fviQX zt~eN(F%_?+l#Dz`d_|lx)%}~Y-%Nl0G|2XXmnJRv#0KT<023Syp$}yo(vyFMbA?{^ z6`y^U5@A-jcIBb-ESqW$JL&QsO>Qw=R4?r-Sitr8Ave0T0T_OZ?s5Mae!(Y@fu6u1 zRC<|wTXxG)N4}_R-$aIaN_zPLiN?m#-dTGlEiVqy^{Um@e*l zwDS^$53sWT#q*|K$kv<$?Xxcjsi_0kz2Jd)Jo$HweT`}ua}-XOjV}gx zH-_D8ljDrgfW94PW5p2;w4?Pk5Z`z}R#phy2sldM#iXDxSR-la_d1MR9G~9(OFbYz zXZR&t7nu|`MTiR>2`<@VS1vc2KIs-j0OlUqA4oAv#%qcD zPkN?dCd{1-W81mH-$3cdjTmYWdgcKiO`uSf#VP5)BU1HQ3v)(>=N;;XW;QhBY)%bz zB>VEFs(*DHx~MxK8@^H+GGpu57XcT3Hn}IKBbTcc$PumiPWZ@58iEnmQv-G2m@<$% zaGL*!ABOjnpq?+xUc}JmKCS`C0MO;QeE3uaWO>u=u1(xE{B$GWPEFtB8}{AgZjsBx zd|Qf99yDzuj;*UlQv3z#;Pf{$C1-f$)<%c%X^Y$Vi}? z$cKP#p|HosFI6sfIGSu#?qdEMqhxyECv8rniTA?m;r@*p4Kaw8j@ZqQ-foWDMX64XW+D&{vneQ*EJFol5C5N(9iG3eIEOm#Upmx#81CCzTsz;V>Vf`*2s{>IRP+;D=mT@ET{ zoa_aa)&(WG5Q)Q-ayA*im`V%}$a>bTED#vA6G)KsT*z%5lg@6kGxg*Mz-iBpuDuNG z{juw)XZuh&@?y9FrEllAz4=PV7-)biLfgYnTiqx8{6+4IunaA-0A7!b)K`D1TL0K{ z(!R1y+4EBL5kx{DVhEZiJjzg_KReK)h)42U{ppnat4P<@Q`|H==T7mR0R1`DNV_%QgeD=BEIh$`)4yeYK-f!O6UEchF>ucZ%_P()K z(_+WkHA9xz75_GV(sZ@HSlp^i_AqdHa^u~sYIf%}d&7T7TAQ}*9su_h1f=X%hTjIM zJo@lGF^k2MYodN91cZk5?j37BL5@k)1~U=jUZc!Z%%S0Bf!Ok2gfQ1^L`6@YYTaNs zH2kbAIs|Uau$x^&i4R2}cq(O3x=jG0g$M$bK6V&GtpLh1(KJ&!4eKt;Zk55k^+P;k zFx%FRgW0+Q;hJqTQDo2r+s#FYw z_&d_0t~j5I-cbNIqpY*7g~eBlSa@#W1V$V{XIv>!|C8fr6I}UD2itwM;H^oUY)j0$ zA|Ao%WA40^boDriOrAO}^9Oucz`r*g(O>oIdilZ`TRvzS~Mv~$$$Rjt!<+_ z%+(@tPQY2_yCiR8ijWK%8;~QqWPh8Ufsx-4ckws7ITVOvZ(n>nUHsz&_T(_>tO1C5 zzS6A>liD3?fMb8pk^F7h@$rKkA~Se$bFoT&j1`sm#T{O4rvR*%MY=QoI6Q3d;LbsF z872C9O^p0BE95v!GXP#8aPEhuyJkX6`FuZ1z2^>F-)|2CSZ))XCf>pM*+x<~9RJ#% z_kOq4)L}^uY&R@*iYY?Wn4vXiY<)X$#BZTsNC}4pj9e#xNM>C_G`rmtlJ$bgH!Z>3 z9KHUncaCOz%puK-P{cY2BQ6Mis`4D$*;`MrgImEHE%8?Opbfc***P2a+^2$CW~aca zI*^K*8&UMOXK!hPr1^^Rf_;iW266vMw{8!*D4ur%C0S8%3mY3uW`=DQ-iVm8mVWn6hsJ zEmp0ZB~tnffqFKlE)r|wF!j^;#R%O&UrBeU`hXdiVI=wBAZTa$vc}g-Z-VB*fa!-_ z>kDJ^9y8_CSnC?l?C_=29Lu>E)#dTwmD92Cv*xjNuNc1*LQ_+p4Tm$l)`A8B)YZ=# z1qk^7=D4T6L3o%9revN0u5p)F;VUi)~+1`FTq8XRNZLAJz1}VONAMx&Sr>JoOuQ-!UHCtfx%GRm{t^twG z%*;U-pZu5oj*lJo;$z$IV8W%oxcgJ%JM@&ydfvCYgu8^=FOR)9vN&^V+6syo3M14i zs8l*xEfK2BA1GCxWZp_yI5fX1(_jn{hNzRV(Kp-Df136G5j!l%^RyXW?4(Mq)vl5l zwhARi_uu2M5!!m2+3^2cSW&F-^yf4B{>W|Li7FOa%63ptJf@TRTi%-GqN)^%AdmF3 z7+j;i&blSWy3M_z->Viyn$=7nK*LGufUs_ZXD%4sRxRj@0aLf^eOtZsJs1Nr?pNf+&jP? zx{s4|hfW^OWi8({hw#65hel1I`~s@(+##h6cBdt>fa;eKYCH)UiStrVGJZ;IH6Z8j zLM>IBrKfLrWn-FjoBrKQ(%|WqSC!rU#l7dwke`Q279w^?M!@m$iW_u=$F>LGKR0d1 z?tS-`xonn|b}&!stH_Td_f|*kB#8^TdoY#{Zt7!bc=`;jJy@Ui{$sqFMV`o{-JoB7 zfs64NRh=3gZ!4=6#qp_~YM9Dtv1@RS?1n0EI=Gwz6V=AMQ7BMxSqH5vA!>tH=Z zYy3|=^X$bGf#s(>ePF} z>OING65y)SF^e^5>fP2@!PmXu^_3D3fOpLb|2_6#c^dSCdX$Mc@`QB!k$(cXIOW=3 zBJ}!AwiHO7?}z_??Mqo^$KcG5=gp`eB=W#`vxj!?DMiC--*D zMen*f3n6?ZMKR9j72Sxt>IMXgIL9v#6762J9bkuzFlEo49GUXuy{wpWFHuI-RTYzn zcv({+r3k6~?(@zlA*cdT{=sQZ*I!LNo9o)-*GQzUMUeKwAB`pRb9?)Jq{ab-1` z3ph2n90x_YGrzqzwLs+oIivwi`z$^QWvbH}B#HgYSYm~WL!j}vvH_`6_(I(+O?8;Y zOzPJ#>G8mLoSb(nyd(xwr>|M!$%WZ=ooC1C6CYgU^nk`+xje7py@iI3DAJ>kSDx1N z=IFoKj!!QKU_vTv9Zx2L;Qwe=H-4{Q>#posz)qB*|FouP}8bZT8U@!=G#Q~O%`8NZ#l^JW zq&X&UpFKYnsuj$}Ac$RzRyE@H0o_wB-LLEMwvS!x4=LaWi^-%6K_4aj&RX?IG7h#7 zZTkOhY#+=tCX?kZ5a~)1-g60ydbVoJJQq6J!EoTXzKSeRmFu;OOW-ded*L(TY8~l{ z>JXi9d)yR7M&7|16ZzM~hU7!dZnYO=>Ck?OA@(RL~UQimr-25oA*L z$bPew75pgjKy9>hS7+g^q)Ce(AHQPgtCdS6G`-101LyVJ+$Yhk##1#5x~z-c%gG>0 z0eq%i#HJgukM+Z3*280h`=E=JP_ZnR~W`?Ko$kD+R*$A(>IiDG` z^j;-!6h&G4M4IOWdS+t8v*(sk zVa_17rfK3^_U?p`lQOz+=g1lx9;vqfvHXA$+dM~YGqP#xNtdUkWOkqnxF-IGU=>1a zH8kn3vHrBX{|yL%#+L5)PCX_<)x04|I3~zD@ptK8Rwu-dO>Di0$J27!fD_Tb_bDgq?>YFL z11r=&3_NGRLSOm`Zy$N(#5+h)L$7VJh=X;oLE|l#f)RVupN|i)nCBOvagqw$wG-I8D{&!J4{+mC= z9Pg6*acarOJ^NG3_y0X_*3YPt0*+^XQ-4zTYFmcjBSBoBKKtspKls->rZ$|KoDW+^=2i8WNSlGONPT$W8BHg8G-w=XH%vL~RjcTkc%) zVFz1DaR2&Q6j5vfkH+|F0RzA95@GXYbcFTbQ)oLp`5*IY>#9u7h%EWe?z)+0|BIYu z&Xc@Z38}%|8Wi+EI=rJ;x{rI##mcxcM|lW91TNwAySDG*{L9Hq%#ufJTH}LpjF*^~ zadA&7$w_Z6tLgo@)3Lfiq(c5}NHHA&b4mA}MSErCWUf5ZH;+(EIm+EyaVhUih3xfK(CgXKHX> zd>bcwU2mOQ8R#YLzv%H+aP8N+FM~l=-`;7mGXYO?X&CdV$=Fg{`m^U}D(*hY^rzPZ zUf@>-qo*Vs0r0HdX;&~A;tFWT30rQ^e$+d?b%7ZzcJYDh9}w6WW%mU8A0RM08E1z) z#W;D6<=5~0^yH#;T`Y4p(9qG)@Kk%eRz$e#WTP6N=>6 z!m8TE?!P&OHuAeH=G>M(vXWBbeZ3I?t?Eo+29 z0Z-;vAT*@FS8yLL+@aSsF=UiP2#y>)m*(T0#XhqBEfD$_{Nirb_xp_O3EW@z2}~k5 zPL+jbqQZ3N8-=cRnch5RkJUq{&Do7=LV2|x&PSEbU}X)?M?_>1nwZXY#F8%epbqag ztnxPmRTO<>ufA;gc{Vf)gxz#}P@D&QKkM>B3-tLmDF{kuGu}b7EWTEzc^xAt_(y$T zqwTdc^xo>|fL#IbDK;?d$$UEWLoATS^<^VL5-Y1x4XJ<56W2ABaur>GK5a-;H`ftL zt|q)ZMfuX#RxY@RZ`7@(Dv)@jiF;=YIk^j7;Zu=E+ew*A?MX40Lh6x!Z!4_(sRu*$Ol;CA2^(iBrv7!e38M^9+PtWvZ{! zl5ZVkh*-9*KWiZj7Cm-6?rK&uy{9=Rq1t?CQ|?z?tEJ-GK`Dx2EZNGxe~d@GCf7pK z0clnQb=+@L&erz^)l@edY7ph#K2EmXzd~yJ8IEb0eBW}a=YP{8-z@loXgDQ|d+;-S zC*pYBv8OPHf;r(R{w0L8<&NXq(%54>=z6Q0Z{uOYoEm>IDkLUmy$bT|GiKGdzrQJ2 zPk4Kt0e$?FBvSE_*kjZ&@|~)mJV{bnsnj6c2x1+!*G@mI$uSmlDJ;6jMz*8MP+kF#G68yZW9OZnt#lPNzOF)&Q^cVhbLrn@_IBPcWY`TXxE=ff=MTDd1gR#&%aQ&i-xv? zGz5~jR(y)jlMJTM=z48flg0zC_4q4UpCi=eFPhs^V=uA=mJhWK#pWK)%um5cyF1H$ z{d`iLgD)q)sxmHrNT1#9hWq|*xr``U+Kf?*x%FZ8dQZ=wy=he1cRDuumUNZnv*Jan zlT_tX5)`AqkB@lnz^O?t$l0MBGkji(LKptV;hp}th7jh5p1RSD3B7O-2p*j9tMcbN zaqZyd*txZ=HYhkbh4!;eQfQ;rXu`$qrRlqDFFJiv%E;F1i^!SpFqI$p?ofG}td8a; z;wO>Dm*rbO$vC@aQ+(dN?i5{}4~MNs=BH&hZ0$$-I~~u{MPxiuf!&vDbV>Ob$cOOP z6o_qi@KgTO2KlczpRcY2{C|VRo9(Px86ga>TsP)c4ULd{Mh^zpX{NsY#N1oOF2a@6 z!JjjnndPq;qrT+B1s-G~%!TOU!yY;y*N(6G#ACv$4!UjM=AV0*%G&CQzZCXM`hp6` zG({eboy~>xSfolX`z}0qU)+dSS^O1^)szB-_*t;+bxj6>ZAmu6U$yG9ydEmbWb=6t zffe_>*_M;S` zJ#Vm>sO5DM*t=t+jFy0yE)umEnA!Z^*Ra|^K24h|rVF5p2kqq5ug*mE!nJQ-pKqVY z&bkiYp7$I{&~3s~wLilkc6))LtV8gCxyk#<&?71_-|{nT2ynR zj~_Q3W&)gf%X<#8KhQ8%eEB6j!*ZzZ3xVy7XTCM|ow#(*zPly`zi{(n_K=eDZUJoJ zv9rghb7|J|nKZVtKAxHPhcA1U;<}cKCX=U9pDM4$%FpEnTIX266>$tZV)qJQEnQOK zZCJnl^NeTS%hjmEnUOuUJq)B;*2O}yMkmo55PVREYwOpRhsm*K;(6o4Ioc}7pD^HS zORTPF?w0WKp#5pUm6J+y!! znCsyTqa@i~CR+YVcPR?x`hTVy%DNsZYmqF^gvv0SVYBk9RgOA`^MYhT+~~MRW<$|w zH~7H6Swrd6@^F7Q=5@BoV5lqQwZ3YO#Q&tjSh}q=h_j2tv?Km={^04Lo_1lZ!3@$t-S_8pBB@R z3zj+%FFCrrq?%D!%5C6LyKzX*)u}ti=|Tdb=b7JA4-zh?%yrN;JD4Qv(e7y(XQFLa z=ld4pqb7q`ZG?e8YcVeL^ay_8Exx(FHz$gy(ZhK2GJ83nwAewo=|zen+(WFFKZ{}T zV5fy@y(G8D;thk#XQQ526W!YnywK`AXM_G;28pwXk=B=6%*wpfL9Lzs-vInf9r$2UjKY`L+3@QELYZW`4`C$jv%P zNPN&Lz7lCM=ucJ9?OVmW^<5ncG;hCd=)-Z;Yueb<*%#yxvaZ|>&)(~%TJBGYzK3SV zgu$*|`uoF>x(@O38nER@-^EA4Xar>lJom;PH*u?R2iZ!8}eIL*%)-dJ*Fd8pWV|{$##7 zdQwyi@mL5(_S?$#x6cpKo;4KXadgJ?d+j_p}4K z@&;K5_fLTh#$GVEa1cDYGf)5W9)6%Oa`+}`qpor~SHNjo3aCrA>qwp-a7htV*+Sd@ zZm+mMDdNrWxZW&Iy*#&PuJ3_t=M{zTqnY1|oMmNpydN7Yc=PjsX72C9b6OTu!_{AD z`?8pW`4}TFcTqtK6Q46(V&rk`yYEHVL$d^N9p!69q4=l@+|a8nFmhAnPa!sDLDEY5 z_5jC9m*cIw0fRGft86cV;uVjU8e*5T@21|*eTX2xjjmGMs63*iD8uF`e%7IoYsk#- zUtWB4OIY1v-(!(_{}k;-gFa-EfjE8IIhbdp_t@ z#1Qml4@~wHnApsNZ5MlM9m|~>RsJXJZrJd?7L7n7JSJ| zld#1HHhyrK>&dh#;nAH?W?^hPSWz=0@p?Ai&qucjUCm&#+omwUy&_=sGk5 zI{ciM@gxDm+dl<8XKXckeF149JvOJ?yjD!s+nZT@fZ7@JB@?q$ie32TBPDUW5{PR7 z!H7}tyI>BXLkWMK`_q>T#M!7Y6^BU2B7tI1{z*8FxZKg}ukXHKKkz1U*ZbP)w^zsu z{t2n41F`n6Wn}#IAjTrXA({_RDC^t1zu#){ji1piMO`x?Q^gAl+Twk$H@}5K3mT%N zi;`=zP-J=NwTDGyqj>Xjgy7CHmw$f?{sOA>zl@Dsy}X++_%UNxbw=Q__01M|8{LQP zr(2{xh;9?Dy;(~=ELz#+a>Hsz1!(9*=_B+2GJGf4(6PX z0=Srz&vS0^;m4L}Z$i@f$+qK0Vdc-?@Nh`FLO}`lQHXaSILLYvmb_70GlfR z7aK)|qrINy*h^J_#XPaZ&pUPC+0DlCsXt@wt#iQTZK8|!+UFs9-sA2TTIgv{jlXe* z^s%5$HuH9^(gs03hW@Yb^SE3%0#DIz-{%jxDT@c1)y&^cUnLL?zl=Y4zyEhMfzOKS zLZq=>esT;t6m`1asgHNxrs=L=TtDVQUJ?|9?g!F+D(A*~5C4w^=wCzLQRcZO_4=_j z74Go0I2WNnh0I1nP?QgCi87%-dr62p(BNhuD{v_6X za$_&OUn+#rOp`Tc!SEtR!JH|Ml`yz_dqH*Pk>$VIg6=$bJ?fbgi5f64zak`r6ZlA& z>0F|=9vr%=C^NDfvxIO=UUJalgN?xGZt}l)#+oO z=iT*Z5TLDnPC`ijwV1mW724>vbYLe0EOR?SD%Ow7t`^9rxr3YXBs_^LtuIR~?Ma1U zd-GeSR02EO#d4Sr+_hWMB3S^YdLIKEs?BJG7P z>uuVOr3oRnr=N-Dv)+CC{V-FjjJP@voOQAC00=!3bu-sr1z*EWJMyj_|MQ5svo+7% zNrGWWhuM+7+Yi4EG@})gKRS1BM-)7KgNIwB+!xSi`z88rB@1K9vXg%F=KZRSdhl{_ zA$eNj0V5Pm2`=>C@7zD{6*yjsk-xb)Z(?}aTBF+h*%vbzl9tI>Rri*b^zhBR*!P=t zAH4p@%U{iAL*bS4@F}AXQ@43-gD9!2dK{j2gPym(J_s|)5}BTCo6_WGBaSp%TOR_) zW#qbZuP_F>qezx-9L%GfYgiZwpm)y!4VS}PZL-L;TZ1e26yC}`rQ zXurU%Z#|CopJHDfk9r^Pb!#^=h}X}XKB-7!Ng^P&dM~qXI^-I_=Y~~Y%f;XJl#~Bg zLa|~rYRu<}G*&D|>3iSN;zhTsoGVgckvP_@bu`yudcAniy~VA6@G||GWl;2T_bgjQ z`BhS9^@NU>O?v&|%eq(zw&>8r{A$g0#~#%K6W-sWjEmE)D0+;Q84SvY^*`)v#$u+@Hxm9_C6bri4PST z1BNCjDYS{4LFH6HkE>U?49G(|4j>`i2i~YAKY=BUQi^&`t=7jzFGqL1F0~X3jSkIjMk|;XtyebHbG3%Peeo|c)1el`8=Oy10}Dlt3tj<^%Om~< zsd+T4uOl#naYJIG&coLBu z<}&vNd7Uo(RZNyw$en9{QPZ38(zn&j*hj%jk}H)w3$os2Y4xCk%4;O>3!eg!G2JCw zAX#;+b;k=dmA5H)Up?tB+rwA0>TV3+Yrp2wH@2IDoY#99^3=!{37))}oM8qhNfmn< zZevIr!?5hxaVhp}c*R0*fkAzDOljmar=}mZl@WA+u}Bvi)Y;h+@523iVr2Y>Upu%y zfcUAUB`gAhQTto|*xaVV{mE-M`Vntap_TGd7n?RXxO)QWWRLqf(QX!g_WtsLtgtF` zhFx@F2o%%>+eZa36N`MhYcNB>Vfo6;U39CuFu)-l3D z{hHs8Lmsxu5Nt~x2&t+qkMGXKz+V_I*nZeripaTwUXEk1>R+^Js`yC57H$qWhl4Mj zr(9>lPY)1n+bCDlS;zP>14#pZByAop0Vy6Ai9p@**s39j&mdzWuXZs^=w&U5?)nmj zaizWOK&WP(NL!uNyUi)33X!0@oAJ0y`6}4K#;T%qCV+s8ojjIUk8qC4k3WQ1yfIDK zgM~#L8KX=9&4v3*N@hb$ib!NRF#W3&+}Ufso2uETl@1Hb6wp->78DS$9mi3wzSxiO zbS1gZ!v~U5zLnAgtaF%*rM%m8IpMkAn^R{}J82mOehI;v*^lmMvi|U&lTZy277M6S zSpx$|E4bj$HX6iGwL&_0+UnPgs?J8Cd5XV{XD;At`J47$_LC71WhpH7Om zTKwdD!s?~*W|pd){r@kVTd)`I@Pf#2(lWJh#q2AVcOT7H)pq?^t~bD|O<}Y3SifoI z+pacdN3q)9&lA$>)0)p@+#gf!AInWBVceZhG&>xPZX&briG#ECqh{_+=d>l@cgjVZ zqN*E(e04ih6(b>o#XL`EDqw;D%iQy)QtI<0#9cArb6W~O=eu7=;~6_hTQ)^43G7EN z%eRi_hEW#Lb&P}hAU`jWgH(6BgzzFnJD@%zb40AyHK$I}5a zEEA53Wa!-Pp3tlDp)JD~HFVZvH7o0lWq+9BNrNYL>^Cb#2+>Y4O;vP9|HAvoamlVP ziRVe8yX$>v3^^}su4;oUR`-bscj?Cb>Qw$-Q5YZjMBzAjU^rGa=KJG>-+Yg z07Q3)29Pz)`WRMSB(tt1iW?A^UIce1!mJH>Q{fLfi8GiE46okoPLn8FRDrQ0XqR z?TfKAQ+MlJGLvM8S0KH)qMS!!n5*Fp*~=Dd$BP>cUk5L?4uUT!oQpB~BuYRY0IvBlET;a@K7piVeJKB#Az^_* zph(D_jrK;;inRpW_@LLwhS#LOjgF6vuexJ?rbQ|r+wpU1)8L|vwzHg5;fA+Hex)X~ zfVRqY0qFeV7XUl^G{`aC!ybg*YV?7XcGT@dwwa{`#X7Az-aN53}>^ z?5yqqe(-WNBROm$kEY5HKl#ZSwx{PJai#q3;7RLX1r-hR*$;D$wBDiPUZ6@qkR-k& zOK=ywKT!1Qs@@giJh5ke5+-vAjl>}vNbi$tNc<3qx3&P38kVIWF99^g2rh(wd+#+R zB9xH7^8udPuqpWNP_$F{otF1sjzNhe984`JfsR?+VpWUKmU7h~RF)FP4A0qc25y@!|a&1nlN;@gm5YG+x&!Sqe*`4i|H3{CgKmsYc8^c zqLQQAFL{#!!Up12ke)6EaE-CrzYd%&xVW6L{@&)mi zz6tj&l=)&P)906$8&}&d20Q+bS3o%6_c%-x4VnpR7t2+0QT8fU*|kxjtcVdprU8hb zw~>jLI8c?+k%HhR&l*&s;IN<)GBAmN?%@O8g&|h%g6V0r9VASPjbjf`ZuRSDOCWSs6J;uQ{j#c%8?T z4sK#@zi0)%+A#Qlb(jBQ z5hB}I4^Wt)0^JSp-xS9v!{MX4c3EaE?u}0%uq+7ZC`6MwC{f+j;I zr=BI&%_u+nEx(hXPGu-%|1AQ*8tNULb0HMy1p3sU5#VsMLGDlzYpCRdg#@MbvY zQl~%RF;$-8@4=+$d6(EuJ8tRMx0<{Vw(aBHHhXSN*f!%2Rh48lq!` zkhhRLBXNURDN=LToRFO7PZq($qEDL;q`mLX)%mx}M66uiCW?XINoKLDumLBC-k4T9 zMWWAqZ$0N~WUZm!*7U*ggXL2|9o7Wpa&UWNJK#NNsg7IMW8epQGegGnc+9{J>aT&*7*< zwMJU10#!cs0_eBCtSZQQU?rIh%e<%jdDSMOS}f$6j4D7c+QnZ!q3SAtKm7Q8$bYRW zkOvk9&kv!-VqjGq)HZaHbP(A7!ioI3CCU&Iv^~GGi2MN7UBir3Rw)>;?tLxMGy|c2 zHK-lUNs6A4n*Nlyqq3^`!<8wN{8Z8W4|A#DFc-}*4aMT9AK^}gosw;4MHjWt(;q1I zH)?oEo~t|HIKGD|2VrXP+}LWE59j;R-u8NYv(<&RLR6hyu<}A&?Em*#E#L6OmX8X2 zuYPdZzrENCW`a{hm7;`05tP~KfF$1C0ClFuG1lY0>=iquXo|Zn!}VNcCoyjTvoW4l zPl)ELG7BOUEqp6Dk6l=+8(mc?1=5Q}Q~|@yl<{>w*6Lv=q{I0ySP@;t7_56d64jyv zjG{O)ekPej<2%l`jg7vhnKm!Cb(e8?E{zFajzb=!WF>^~@?ZE;;vpQbw0pii=6q~S zy9)^FrKPJNG~F=!5yIXe6nkD^%Uz1hlb z2*z^(&Ez7wYGkQNIX(${eqqVS$G?g7S?E~H)7yf2IVOELP~SJ?J5xXWVD7Y!RD1U# z{Mtg|vUc+)u6pM$#`n81aE|sy&(zBWR6b4#qH46A*)C8covP4)VoSSx>;Z!AY^fIo`G)`aYrkBm;JJkMwe7h` zDnA_P&d|h=pD@U9c)5{ z)$RLp*SGo!pN1VaW;P^u*_8s9hCcLJ&Qb!9h7MWS&*fv770A1w{y8rSJ(bn6+NoM! z=@Elx@8!ZO#7v#sTU)df>Qw=(<16=ybC5`Ed<6qra~}gNn*8C$BaV{DW#Axv$GF(l zjg!pS#Z@tvxgtMlF;$Kwo#G0|MZ8OvS63)r_D+q@$D%{qZZPQmX)rGxp^02m64Vyn zCAuq(Pu;&RqVG;wMakprqm-Stpb4Lz9v{eNoJNU*7q~m97n1>x&vTl7e_83(tnSO^=Bim-f@NFGfoM5o@dNKiTp_~Tun9z*hw48- zdN;yPRaj( zYv#3C;7C~relAEnzo3rJK_BKkC178y{yB4S`%DBgDQ_kdPVQk9?86zF!IFGKJL2a0 zg|M-#aJ#4|* z&P#R&6{QU;JKSH`VR~E@K|~JjKzx>?Q9xDa`e7!u4Y`v$-d4)Y)hUkW{GxDOtNu!t z;Pze#^&@&89gP~V#%x(;+XeI>|EY-TZ4jTmg{HrqTBuqk@pR-O=kj#)Prmd!rRDg` zDVujkvPm+Yhrdez4~MdGe5ooSM?43s zU8_jUz0=$z&A5DI|D3FkF4hn*#PK#i-yJm1hYmRFMg2Ir!rZD*+zFj>{Avr}I0LT} z#iNw8reDemY<=leB8(1nEu>V7yOj1?!&4}LN;o7HWfCp$2J0x=5z({^G+PG4o8?*W zW3r7c?!RqBW!#u)wu>U0TrNQ6wJJhg@*cpo(?Ta$^)F5VP>SPI*0O$V>%}On_(V*4a9j!`s`uzree!wKNdL7DUwX zos@HpBXo{w(o=T+a^&c0V=;(p)}9LGJlixttBf<*mm?-I?lpUKPPSE*U3tL1iglG= zkd;4INx1EKul7n*Y8Zz}GE(#J!&+7v&h%QhB5mM%+TY4KXP@<3nGlQzD24I#%eiJf z#AC%s^22p#|JA92#jztN=Xj37SiDSK+#otZys9Si>F+(natF^4wiU>sU=%NTnw;HL7BuCr*=xM&{c-QD5qg9}qza zs?0AYT75-_Ds<;RUZve-I)1^LBtz_!wQ^nG^TYu!ods0IAqiXeikOPS z$HSY-6kCaoy*w+%gWuGR&28I!c;sb}QS_K^WV4da{Z==ThaP#B9EJ?AJBYTbCXi6C zWRwkHc~$r7pG#JH3l4#KRi>a{bk35Gio!Ui;=BV(ORck>ofX>?!BYWeo}k&eG5*FY zBPOXAwcLw)n*k$n`SBv2l~GoQrJ?=&=b?<`=wk*JEn*r_R+KlHz~UQwV~Fav%SkHD ze*&EhvPmRCAgFqB=2KW7=C6i;&|F_-l83D6G=T=`2-z*;edKv)ajqPjo-@c1)1e@V7S zez9r_a(&j7#50%IkluWY8+WgZ<_-1nT}BUl^FYSA0XD?N65D@iRwFQ38vxG-0TBEGd3@9fWl;` z+qhn8V{N6_+y(FI6NrzUj}uB>5{j51lagRGpO6m)%6a%dY}wTpvz3P;bhFvt5EaySokdCj6A!{`a;9s^cvTL zBdTr`w?S+{(NAbF_$(Mg%L<+3I1~@$@*`0pqB~Om8{l(2OtRqH^9xs`+T~Wn1dPiN z(`#-tgAD!1&ZGS)pDp?dA)`OV9jJXvwDFxY+%7AztXF>U&sEpF66|8$?i-hjV`f^Y zvn(n9T4wh3A17pM5CYzsvl|2Cb$(WtlL6E{?E0&P8707jjCo?vUl?9alGKvWBW&^L z?sUZ0`_WQw$>g02uz)%f?OhyMHL^VT!8Om4my2J`$ewOX$k80j-TcTzDqUU(N? zGmw*40u4+SH7KhNM-aFShBg!Uc2FED@y5VF)1bLZ@aySZK1w>%fW?ukL|)iJI(*Qb zho91ewWdWOHq4U6*`FW|x~~)YFs{?28I^`2sP@hU6k@lrv zDzt+cz4qt02|iY9cM%~EVMrirJuFoBxh#z%n*I2cZ&%8#4vSkh++qDaIq+YPOHqYA z>!5_*iT7QvL^(T?8U#B=y|DcFQTD@SA>VQx=JmmHe3IE;f2CN=h3;*TKP7TZ0E3Nz zlwqZ}(7LBYCN|_-30S9~tA^+;cBmpYrvqT&X7AMh{OLr2I1TgdHR{2FR!WdHhMLZ_ zPb>XI5c`k?v6D9Mw_z~oCb$p#@u#8{GOh9d3J1rfaONN@qM@Xz@AXex13KM@ByCr= zr9yaA@@YSL{FB_Oyv_>sEJxRR(}WWUPI4#h9z@_$B5A60SHnEaH(>&*O#p3J*2%5} zF!Wqj0;q(bjyLrenIui%@}w($<6rAq=a(l^mQzY~vKec5fFlfWcO@NPHv;#%uHAI; zpV{_D5czK>KDdJy?-6j9G!o5!jIN;tCpBjVRALia~1ZqzfEGE#r?t?$Zg+CsCZ>g6-PwM zdeOC9Ds|AKyUjct4kH^H8buiBrhV+0vg=Hxosy{wlGk4^m+WkSG-}a{^6?D9nK|05 z;6b#)B{Un^dm<*o#Ya3 z#5N5RY!aMzy-Z$n?T#{&th^m!eZ2o+8+?qpo}JDh;>Y^&c~ltska}irZpGmZ!w^V8 ziuwYJ>wv#$BzN(4SETW$_20% zz5&JQc7Yz6s;ZMiQQ&kh5Bdx5u9`1Fon82uv&s}`l9y1BN`94DUQ>@;Gywz-AKhIQ zxC+B@&IBpOes*6*ArX#3VgF+RcsBnT7*`v%8~VQ)Sp?%?*Xw2CPt0Irn@lU`hBo8;Cu$@qF2)>~Kek88D(H_Yk6_QwlIMxc6Kb2*-9T@6pMj zt#S&Xcq#NG%)7{J(_S2Th{TodFbJz{Xe1&>s{p6nAyf92HKbi^+KUo^BDZk;Xr0Y|VZVb-@0M1y=tjxGnjF}0Jijs}zUEN;jBWY-lJFv=y^f1s z&@|G17p!S^F!VcQV>Zul5&l91rl{oNFk3|QjRAa;;wDV%p4X>-#_uapRwR_knqpM= zMo5xMkc8X({ITpNi0HS}E5)}a5^}+vuKss<4I=RO-Ng|tm(c1Qfh>~GzP5~Obs#;wj=7>m=;CSr;F)5Xehc?Ax+Bg915g!7^J`fi0*c_R;wXPDDio?>BX z3HXgd(Z4GkCKAm`HLh%6d5}tW1EwJ1FvPYd;YyhBmC|YKb6CaBT2VnCNu|9bYBa<^ zNm`w^4?Paeyko-0!~ccdyLJBW)#855p+q(L!WkG?_UJ;duJcC{L-490KKKsSj_2&e zC&6~#h{`xwgjSic`0DM$9#>~)CgGMJCC^_V9m@-3e-o+(MVz|gLix>I%$tjD_^CWR z&sJME=UCNCdvL6`jeuY+IUhlQB zs-;$MpX^nsY9IQ4sr(LAw?hp-Rw5<9O)Z1dS?XzcQRq;CVV5l;b&c51ouF=6Y{v(4 zOmn98e-LJmXI1HtQC_d&HDT%TjESIg243g_;8-CTL#q}GaSyL@qu zDYB%*6)_>3!s^6Gf>WxTh zm7B4QVPJOv?cb1-Bi>kU_}POK7d47Mtse?eiFogp=O?JmJ^@V+a;B$4&EgYP_fz^V zDPJ?SU%D<2c|~P-y5F)S=?moT?3eV}jWFgWk?nfMTw6-$2L&1~P*9xpaYrHD#>EEj zJLw2a54@~Jxyw>wsBUXr>n<;2$J#YEG6ZsS6oM2=7OF6>)&(sF91d1QcSh0xiBB$=p z{&bk6U4<^JIsU9L%CsfDYzA#r7}B6$hM4D{7E`4~brd(9lXfu$hdd|}Yq5D{koc#BU!)dn-zq+Hws|cQ)-}KY=8OMuX>tETj_$;F<$gz)J zvD%u`-^k?4*0#&EgoqKHfkrCMd$vu+QH9qHUdy6>yBct_9WFy4G1*o_UEP^upB7)) zId^1>F844#bN1kcRNacFsjWR-i?HCX`R^hD3fj(;n>JzqDH=mKs;ieV6W7|if#kU- zcrKucu5yPwBn&ro*pe@c6Q~4K1$@?LG~VxlJht`U?tBmq)7%UZk^EGUVbdUE)4m^F z-VL9-9o1dXxvyAXJlBVCe~#G|fXMf@@0uflQof~bfptrPxh6I9usq!LkA z=+9@ZSQVEtKhSp|=Pawg=9}p6sv0`%B0o{)cyJfUSF;KKP_6&&KxkBv%MR?}cq@|6 zl4(v6F@sP|LsQXlJX10$3=e-af-`V4I_nbp#pRaRaXtgKf=t)-!^mvOXKM@4_hH~f za7O)FVa`#8Y?XYOs_tg*&05yY>iSCgWcWSyz5-QKvMcAuxO4((47)@rt>Vk|R#)xS zbihyUy^!0XR9qQD$8be5wU9r73_Tl-Yv^hsZLskJG0?$R;qREX1H0yZ$j<%Qg=+%9 zuJQ&EM|6zA#mQXWjPJu%>+*dTG4US7d1`f7tHjLzAxGb9^ZXCq@-KulIKtr28#Rwd zp$8ec_LeRR`#0U}>(%p4HI`J5GkX&Ro8i^%fp(cL4=vj^L=HXRXd3FSg)PA+b->IG zE{}xD>9{Y6OWwV=hwnlLT7jH!56X7;Q-jV~=_RVv|Az$$sDk1Ef7v$-I9`X1N;hpA zi57Nq^vBnU6YB>bn87~ZOS#zr5T^VJNqDo8a1Z*V@UdxiK-IJl$V9(~_ELdV8t*he zYiK6aLUj5I@=5{h1!f2tS}%5Iht-&l-}vklHWcLGHok8Lm8DKx_GawDohVg7z3EOq z`@EgV=crSSWgScOoaUfsX0!veEeRm|2RxI!-7SW}9X3_t#h4J(Q4)OGUgK=~%0d2x zu%kfx$pTAwW5#E)B+DGHLjMsAu`qlf*Vd&4MmG@F_^Tq6yiI>sX9Pf*~i&7W5x^cMA?bRFJ>pk*A#Pdtb!+*j{>aT|(Ana|a82Ch4|wzl4@a{l!@ z&qF3T#q?t~S5!s4d0+CgWoV8ZEZ$<1Gxht*B&I*S0Iz*(<)j13GTyuTCh6mBuApBb z^;U%Y^#_)yD(w3V&)cf%^VE1GPq||T9LcH+eyWPYI!1g{6D9}@n=m(X;9f*Ec=|Z` zihejQbRzXzI{U+~EH>>IB+Wb}-=8_!L0hksXN5!1q1A9EQCM|`dP7_4Yc%}`cavxV zxSI;1kk=SW9f85e7aD+LuaQk^la1FOm+sFN9<=12wy=GgSQnab?oQXrQnFMDs zjH9N|cO${Wal-TMHQP@?92QQ=7xT_WD_?I-jgic4_3gWF=4E;uiWuoYo^@D+yE~WA zs}n*_mx`lWlEOWX8od84-uZ1ZRpF-<;be)^ccn;z{+u?)fDygaQoD{fk3s2d*MBcR zDv_c3X^NyqL?3YEgVUu0TESk)Q(8I{!h73SZxu|c+UsBHKI(!*Q#3ar@1%@$5QQ=D zRt2Yx``61Vqxm$FS!O*9EyHcb(+Zqd=RIIf#Y|0P&w9d@OkK3azpfq-=Q#FDqP8~} zI0Gmj^f!+tGw7x~YU`oxx?CQ}m~Q);3vMQ`GN9I>rhzRL41A3LT!}xPScW$MD*9)= z?{KNL3}P!4sTtPHOGnq{h7iDkNYyJ)>4u~?>|&JL=S-CynMBf&^Cq&W1CL3&gkv_9 zQ)^09bW&lvDUtp9VbsE?jn?V(I8}e$NhJoIilK9HQ8pJ7jw^X0Cu*C9_^2!>2mihR}q_P6FxOl(FPZVD=7$NMUy8Xf;;pp)+D7IyofZ?$PG52Xu zNW62jDu--3)YO@&w{2Na=uHZ*S7+Ec;}9-Vo0p|~;vm=Ciuz`NwxrB7TiQATpa}Peinbp-vfl zu!n9%FN<5&RA*~xE=$FQMZ{M-gjuoSn)jD7GvlonC9irUGzR6U5JA*#`0*AT7wJ)w zi(w?=1sz)$CyPoKKhGHSn2_xM`8y^mH{QEG>hmsRCp1-ayR*s96DH4Mhy7ziYFe&1 zw&iBPyJu3XC?{UeYs)vW zxue4Oh{!{*DrHT%nWg5A3}1~PgJ+75)$hqGssqeYggWqXiFi;owp=7If}5s~7pJ4z z#CW+s>ObZ~uL3)e$5Aokt;tNVe5EMdEF8Ti;Y3d6qRm7XTy-1)wSG#He0I}sGUWA< z6<@PL-G?n%{%zOq&O$4_kjG=}U2&jur&LB$$3ia!vkWCpyo{dA$@S+V%o$~q%M_jE zeU%t26xtqSz4=;@Gr=)scF2t@!`2rHWfHe83kgKEuBADCqvAV}_x+y6ixhsAlY!jM z`_0tIbq214+ataRQO=(BCF53qc1gUfyH;gS2&p)zbv9G~$I6~-B6t=3!f24PAQ1z1 zCX_%v!;wj26Oc}f=$XYO(!BRkuJnI>xsb1E4A8u@f&l~6T?xf=@yf=KEUsP2e*s)S zWuQCJq_+vpPs_d90Hj_V<|pSK>(E%`uY>3_0Z~i(O?}>SC-R`2nyg zpyEUaqbzlaVuQ8nGe3oYfDEJIktF*gC%*u}=UB{S_HT;>A)8Hs7(L2M{1DWiANoLk-))>TV1I=U zo$E_tGGWJjDuT86e)`ym>Z$G;i#&$rR;z(${f{SYg_xmU9Ckn~E#G(7t2*wctXIqY zW%49JnGR`fm2}W;DZ?9YP7Dw@Vt?|r2ihjdzKc(JlP*bhgt{R6a%<-4$3u(@C$ZE& zbXZ!5>BZHYW9pwnPKg%SrTJ*3px!g5_ruPkiGFIn=;c4`q&Bv4#e*SIumb{Q^L?Cj;y%N$;Z&p!e$-8#=$S|$iVp?LyyLN@{5E20F$jPZYvlD{2TgM5e@@I zpNe6iXp}CXzQ+u$&}=D_$j6gSac1cJbCnnrV_)l?EQ+!ur=zu_cKrhnCev!m8Xnzd z!XUkk8*Vd4a&?YkpLEnG6Xs<;4s|9%X%C&KGwE4p4b?CU^VvWb8MDhOf~B_G=H_bI zOgWQDjvHN2MC^{JlzgZ1S0t{qChhptGwd>3mG%mv!n1ae3x% z`;*zJ9<*49rWS}(+KCXOqBq-06W0I(mcVGG?f*2JGsv1HV(X;$K=tEKQVRA}JtA_1 zK+?c~-oHInYgrlS{UH=|(P((F#~b&2d?`L9h-SIJUjrCl=PRC38vNy6$Z#0b|M-y> z*=#o0S|j44sKqR#{*N$0}SMrffq8 zkfRirX$|fcs7yx`aOIRq1p_m2X@py1PW#!uGi|A3t!HoQ4h-0J&g2SR%S6Cj&AFR! z?(PtqJV_fZ7JA%@w8<%=Ma2BICn%`tFo=(%5FIwxqTFX@e|n1A4n>7WbKo#om(#;i z>?Do?*QYPE`knQ^xHzK-u6zTP`qAR1#*FtM@=-K~1>eCaYgmnWb_-vra&EGOlKFf1 z)>t+100Z&X^Q$ve3$G}dh{BqOo~-(LJFVJcY-YO+V@lN-p9(oe658msEJSL}ce?s` z1Lvqxvwx)Kk6`! zyR3zqvD`a$jB*rfZwD%bU(vG7PDsKIzjo3+R8ybV!uaNHDALGGA-G>E$3?y!dlfD( z)I^X>v;dv+)e}yZHQu=-pX|DJ9b!@f&(IzohDNEAqD@@kdAcgxRU>5Py>20yr!|2e zPuG4jKOLWH=8I0cgt(r_~DOiPkjGy9NhK~A-~O4OGH6>>wE{Ygs3{1@0=noDUfPime` z4f^SdfU^J5Ix6)<5RS@R!?sDlcpbLPOMy;gTx`_nMC0^6SuQ<|*BO=G&9H_!IDVm% z>fC+HJaKvTQHt_6TF|cy0d)e#b)pENs6>uvxi%L7?!?hvlLR#bjxm$3C|#_bu6j6e z)ZXx{ebKXjeK8ly7Rz>Qh}$nD*i6j^7kaL)r%wg6q+?`nZWL5wTOmI@Nnx$z`np#k zaHcL6nKU)FbtG8|Z=k=fV6jCU-*8gm49GV^pAON(JZahb8p>SK&57F$jVzHE9-xE! zH;9BZYpMn@w{@5Mkdx|ijP}(}g36HN@0lg!xqS(NrSqt-g9x17~*!eemaPfCou`*+=b z8oDozoW-SM-TzG4fNnyAo_kucbGM!mNSb}xYU(Jd9CnwRUF1n(<%VlC3Jm+!gCo3j zXh`mWdkh2baGh|kZ2I+jft}LJoV%YZvTjBq$|<}iz_3UF{){g0Mayv+6Tc!W8)ag> zYIf|MBc<3|XOa{bdnyZSA1||)GEO~m&-N4PHtJyENdMGO8`|zERZDV@K{P4)oyK50!Y?pFQbNFNE|3ye?h{4mdQXE!U?2u>D zAtn)%q`Pv{1O`^G;J07bOUl&xhK4KZMQ^f3>o1>KXI)AwqapCrrP3JwUdbR~h1uEh?mYSGL)1eE1pOENp92J>^oREVe^g~VN!=YIs1U2Bs<}GW zB-Tcr!8qCXODCiXmoT?Brht|7SMf3&8Row>KMR?wZ^ow?5}2`J<0BgjK0kA^G5h}< z@(BJe4qs+Jeq6l~qEcJwI~SA16;n&NzkN}2ro;N}54MO8KRlw#AA$m7m2IPpwzF&* zmfBun07|7>pG7IR#JZibgLfsp*uw!E-anx6*hkDvo!><@KzQ%yqPO^fh_K#}LiUKLS9XB|2Y>CRF{Qn}0hhXQOYG{cIuUTvg=ezb7Vj zQFAW?oX2BhN=gwPcFc`snaVDYhxhBhU=Q;AD!QN(!?GYF^OeQ($P!db&GbN*lq2b1 zp0DCFHd;^qWcaLBD&bbRn=81ZGNvu%`>)s*Xvh_D7ACO3w){P0l?&06=Hf`5FXYr) z9umBD%mwrQjPKduDuPWXsEm&Xvx$=|-)Z2U_6yc07Mb>nCbn{*4daMrOjQqKS0if? z-)??$sZ)*;WhVNkjsTu;q5TJscCy;a$PN-E-5^5lq+8EK>5A{Nq(EftLqH|Jz8RCOzc9hl{(OEsx(F^!fWKMQ%PRHQc8j&M>aG%stArrX&pYr# zSTHK*_D+LT-6(h(z{$mUE=$rjCQs7-Xq62xC_?O^?}7W@c)-JAcx1w+sZYM(jU3bG ze*Wn8F4RZ5BhvSPg8r~fkEJF+&6ykic6SZW#QR=2dLmMl{C>ri6(lHvvkV%WG(Ern zQ2xOG|FGWFp$aEwZ>&9iUZ9~Qe$-*LV`)=QNT?0a=nXDA{7Q)PVo_L>rb-D8F?AlihHFS`53{VOWbAo{oePI zNM{B>T^@q}LhQjA5#5w4nQ@wGG_?0vvV62$nEW*X=07YYmuqI^@-qVBWD*&Rad{|r z+RgEV_vo7|MDN7b;01ITA999gc(+=fknnML{@l5ev_#xhGZ7Oc5Mnya_t&INNIIlS zH1R_wV%pkB;5{#mHop87t_q!)VlCAPCkiVEx%<5 z!W%ZTA83Kwo(tjEjQLeDSkzxtI!1dK{1R2;g`F+o!QJsGVg93W9HIPA8I9S>K~u#=o~AgSnI3=OvAT?V;hg|)62n516o0zI+)GYH7n>uiqoYsl0(cAH<&u zhHbKflCuCfKNKM=@c!u}s9P<8EbbfJL(U&o16jU#ox@l_*lKiu{j9ZCc#591Ch!#vgK|TYMi{$eTpc=Y=28^a|gvKwWr9OjePf>bc6GK^p&)i z6&2=*DsF0a$10y54}SHH4D6UI7)#*ZD-wwI=`8|4#qLjxclKR3IT+TLH=>q&kQ8^- z`!2HAO1p1p_2bh0WNCJ>#@&y7!mR=$TC|OR8^|(2h@^EO1vNA9S;@{8r6{JfkY-}c z63!!M3a^0Ob>PDV_c6f<4t^GwO(9Y8jvs~~=Uv!{{os_~Y|xW70w_{*;e=h>2=MZ= zm?pYjQwYY_x53P8*&Up-OoLlZH0P0fxd~zQ&6j+?e^4fH5s|ZI9k;=t{jjFv)lvGW zEmm3i`&Aj5ml+jROj+|)%m^a$1jSr&xpBY+`+iY9&vZi<_9(@qcjjDa#K;}GoBuy? z*+>sZ=ndmol)w~Fz-{bNj8evF8IN36B4}=}r4LE3D zWPHy?LG0yxas6fO4!cN&$j5_zsX8)2Jaq3^N@R7>{kM(7DMcG@s*zvb;@Fp+|Ax0? zxc?zQCq4&6Noz{{>#nlRF+SYN=CT49h$#;1qSK+~h`XhSW$=U?`-bw57{Cenb#9)l z>yz(OS=cYHKMEaS6z+A>G5F7m!GAxDPQjrB)as!ZazzH1Bx79eaD}yWR`07i$;pm2 z4tsda*OjgdVxMm0qB3h9)(8V7(>qb+5DmjtBQgadkDIRT z@&XhBS<^=YA(>7wk$KnrU&OC#TbkaL^pm1PaQ+NhY_dzq?nv@j+MB9OqB_iHdOQ$5 zgze|DY;D0XS$Kt9IP_8Z3)Z6uL$M&Iepj9RN(XqP!Wi+OzSP}J44a;3d>6yi@A6Bk zfu-vUxYCBUl4qP>`4+;aa$v@*p1X=m7Twi;b4;|=Y%v{2y|T}Qbcf!^*z5fw^d6ev|Jqc(0boE8?!2N z4EH);sKGQRNj0jwpr?WDeF{4gmH8PCsOA4P_0|DVwO_O_C7sepcSuMm-AH%CPy!+) z-7VcE0!oMUfaK6fhcpaGcMaVz0^ia1cfWi2mzi^(*-!0QYi+Kk#L#x)*&Rk4D%<#= z$s5hYMm$0PR2VsM7!ogOFSK1w#+V24ZOOTPE{?Vjcy>k3ZMJrkLmJ4Vj25wP{ITGl)$d1<*YIms7Jiz((M3_&B{%peS^8BO=s~kVG44JyY5RF>$v{ zJ_;C%f>#M+G0ZsIWV=`v6pz`w@!>1hx&^jl4;=7*{~Syj0Gt^##^B58%6yV@$2W<0 z!EBZ%r?*I7Ymy&v6=uSHxmM%aL~;p3u5tnBU?Dl&DmFPFh7q8kQOz;US(H){{*(Fa z6$XmI&?968j}kF3q0#RJoH0h>$^Mq+-Bcy8d1${=N63)wsWW7GcaBNc%y)mcc&g40Lxofp%r?W=3pe z2R#PFwpm39xH_-0+ao-T<5zZ_gVYf+BHr}1pyFWi&?$HtH{5vZ_iR97qAI88^`aqq zs#N+$(A4ap-*-(pe8B*wzQ82V?;5eUg(qtCwM*Q|<%K(DaMuYnndOw6yDHLyCu}o&Do@u7 z?6Hn!aTmo!0ryTroZ?>ful!uUxC$nZ=Aifp?lVQ6N=0ha3Av29=1?NPQ`j0OrAbos&7oT>f2jCLtQg zFl!i2I6y<=AuW!-zTJs$LwKQHlpG=BHO9XvNa?F^bI{mKNEK4$QD*IAjYwVYKKE>a z{^r{bl)83x)@!wU(zai8+3M>$pPQSE*WqH)Vowmf7g&Qtp#3?BaG=x|ljVJGm!+v4 z`{_n?cLJ-*3=rD^vQd23h^Ka!es&%u%kisb%PV|+jd$}B!BqDsyos+_4aM>Dj`Q5R z)lFVzjs97$_eY-M*%-Dn?jHY(*!a$5PL+;lTLQTl?a4?XG?D_+x=V zgYYF4v26R?mUUpe@Z74IaQ(u%wXRT+Ht<6T2wsLdnN{A$p#& zTg=lsLn9`P%A##0Cc(a^Awkzzi8pq~OPBAPwx;&{*Z~rftlq~uN#pNnP|^4s5Aqk= zsY`JQe>n;M0ko=nwXe2(cC>Rl5=t((O_6c&oMi~^anM3S_~~giU;mDLD%oK~20E}D zs>?C+TjZU--mpVmE7-Al%hfp^Rq=3-O5;iGb0~NRiYq;bRv-$U<|Y+D+d50K$K`i7 zH;rClvEUOsv|z_b)nDVfje8x!?0~ zIdb~bMZp8sCjz0^!_=J&yY_E&{BY`+w)ef;i+Y~`#0)qZWrz7~yZ@B7?Zb~|ueI%^ z79qAnb(fCqO#ok%aE<4Jrb(%%?q!9Hx1#<%q`=?ZTnSjC^Mgwdwoo*BuDvL~@0Rga z3zQ{uC_awe%)@qc|7GM8YvrA!Za;5Lp%xZ-fyd-vOuvaImWmdG}8?fEOc zhuB@@g0OR!L&fq_4Xuc>Z`JmB;~&3HGek(U&ATF>Pdq6wx5*qSY!LPlxf_5(y`bA`krJ>v!&j!rI!ks z&q$^DO11CFa^I`kn9wkAkqxvLrmm6Ict<+qrS5W0@5bR?K9dZ*hm`RU%n2*?`V4zi z)&2H=63vD^+T#BCdAV2PG{Ca%Z)alz+ycU*}<)nI*(P+&h_)Vg%z5 z{}Gtfp4h;NqK7@bgLw8LdEgFaCLR>h14C zR_Uw=H-LhKcO@gg2BO(1Wd>Se(Xz4CkDhw0#n~uBu%w**s8*ixf_d-5*?Q*cI7O<5 zKSe|Qbt%VU|AT@{vhZ`&c;^m;1oJ1LPzTMT6;u(hEDVRwiZMXFsa%AT)Wr-_S+HTP z-i}QR{}ED*{do9D5c&Q2zeLqGUE^kV=>Hb)%V&plpV8bPDDJrnU6W_zk7XpYzYLAM65AcV`%z6k zr|B2)E28}2XCC0}z3k+pTUl1Lp89ao9N@cR=Oh-Baw)wIoH|{{VMCK#?p|2Mo3$-RFegy1ZN5way9R5U zsF7a=_j;)WB`Vvo>{>s`K3kS3zCyv_I?-geaWXH06vl7UNBYqEwQ_FZgW(hIEL8Zw0(OVc?@KuFc$z;w2XF1u}Pu%Q?BPmSg zp#`Ds<>uBUXbggqWicIO1o;}P=3|=rdh3BzI{%+8!|%mNQz1)o!X(tU1lZ(X3~p*q z22PGBsnB+7k2*20T{O(Y%!f|JRAFN$3S%z-VH^_m5g#o;-D)xjv~{9n+nT zzPc8#2o0^*C2h!7Y6neV8-jvcJ)g*lQTrg#1}&NZRCoYV?2Bs)1HtpI1$>F=(=&># zRzYdDih$B6!x!aBgzCCY#yL?i*@7yHg5@Ur=Pp9o>{$-^!f{(38Dho%=y{X2(mOCj ztJcEM$0>ZirUk8f{b|6x{?Wss@qXOWtzlDdjkcG5543P(F#O2{jqn0?ZaS8#}^q445TKe|ko(}dw zh^%S8rhtum$M4AUU^8D7H3O37mJ8V!4Wz}1{jX6K4!_mL(*JJJS`>sS)@in1KhMg@ z^sEirDb3x>g*la{m<@>-6pa`ipB`>i2I|&N5VP`GUd%e4{g>gG7w)G&42f?UPT`V` z+zPM_c%D6aS15t-E_imRKwwjio;u{tlLi+nVPtk-c<4 zl@$WZ_ZH!K>9_^o0)1DpJW(j%>MPZ3`(r+^R-Huu5*AFUjzAMPq%8-s4qzSo_TLeN z?}4M7I>d{EAb>l`_B&M5v*Z~8rsiAcuWR}2%E3L~M3df$cy56HdWw;(Cp}ja4_A4< za^xTU4JVxCQ+QD{3O@vBChHAB&^NFASP-lkZ&_G2Y9qcJm4bb|mruYzn9L&0ByOGJCD+^#;e^89Ig(TEx>tX~!C;w)6~F=CvLm3fu3s zCWc<>1Ay-h5#r^v9J6Z51#C=Wo!|YLTXhM+JbT^uWrJRH3+(VN!YtHJFKyS-0mP?a zDT!e2&W!h}C+hbq5rNHl`9;)5K4zUVpa@5Gs2hwkYEk ziow5-sJ=ug_lssPRfW<}{ja*X){KH63;_P(HZ^F^^TLPiS$WeBfDV zk=0<|h@t#8%4Q@#VE^FChSz?U55R$9Oz<93cn|ffgf36pe-~xbNKy>!EvAKv?LQ-v z8EXV1=^@$}^FY#nf8*IuQvPZ5Z2e)YH0^xyUtuGqR@kr_uO@4=a-<42%n>tm?}nHt zZ&Axp@^Z@(k=&Y&QSX}G;o;q3B%QBBD!+yHxm0a%pfEt6{avV zmU)AfjF-V*zVUOI%z~0txYPl*loy$o?{W2thkz{5NY8t9+rxBU*Q#Z7MoLfbb)%HU zy!rUjGePXm-18IE!x&#r>q`g80xnrIKz-}>4}!4ZmyIoO7dBOZ{;nCbD#oRSScN?F zhqXwqJ_f#{00(IryN*TEIxDtYe;c$}FLWy3pC2>koX2szSsZf~t+!idim5q{Rd{xk z)Nv2XR6PbsLo0nAffcT|mPwZsc5-T#dfixC%SNC-NbV$NOpA!p1yj84I{g_q%t07wq$tVKNGQ>8{szCtM?IGi#q`*WQMZ%< z(5nCmI(57`sLE9#UH0YHbpidw2rVNi6f%p6fP}7we=kc)c$0G+fH3E7pS(MKQ!G#v zD7IXTj{trrp0xxWt)v<~JqYUHr!O~Y@1s(!f{9f`G(`jwClATWPvN}2rZ zwB`lmFu&83!Va|21g?6#-s1ea9z+mWs$Acik2;Wo+7-MC|;wYz0e$TBEjhW7S#gX26STtJ%bN+@lmc&v_MSSO32GQ$I^Sy~eA zCZu!nuV97rhXfx1dC;9Gs6y+7NUGAp*ZmBKE3_&Qv%LIF^_v%p9`}CE@8ky>)=KsG zSbJDQ^gBDOwQQc36>As>yx8vmj&7aBNxdU92C(On*i!^>__n1=c9Qv#{ozfpjBeQo z%wu@j5DR;)y8|GPa0uR?+= zB>H^9EBLInO)np`iI^)k3-47Ydk1Si^^*!zB8ziSE&Gy$s8%IS z8B94lKmdYAlrO4Y0;{Wyh>8sbti>9_!H8IdJtD03T+%Oe_R(D7p!EPN8Rx;Eus+Kz z!QGZ|M&+xz_=!Q+3p9Ba;i^pjH3)uyP;%A1Ky)p8z(Z!+m(w^7YUYatls?rCmEqWP zEk){sSkivo5^RsHck-r5=amvPfyw~Wv zavh}T2C)x3E?j`s#-nQg_|5kQgpB8wnp$F96O_r6ObBAZhoU$tI1wZw|1Bs4t%v~Y zOOUhPM!OxxfI{$KXxv;AB5DG%B8{izUQ~tLwfUpCrk~;Qe5v|OiRjgkD*2ZqY%TOH z-9iF=@w`vnKKhCHGxyh`>>jLLI8DbKiB~3ut1GVroW5rksRjw1Wff=PeTy%1o_L*G zFUERz^Eq*aIs&am$pt80N+h(iDoE%!rei$w=etfHMGGHVzY9w?>vRvMCT8}bK`Sks zX(lxSZ#6uUyQI~vFpN{#QHwB+rTaoT+dpZ_^MB$?pI{q2MjWe%^F=Rt2Ecq*PuCUwOks4xg0_6OUh}6)+;ST zdBoc8S$j|W)HhrIQzu9hleA3L42ebdK@<6oY0YH4z3|4?xO5@h-R^Vjt=}ahs$V!< zbZ=3Bo~?&|XF9G)%@VMSjs9?KO6?>n0r;1?xt-%GaoY0&pE;JM!}iwKt2X}3?cVzn1-5XkH; zY0>l29CL)_)5$iS%W$L<2%Xf%5s3?1pT3}`J$H3x&Te}ejt~Uje~C(7O?dJ%ibx4E za|+vF2?M;8O)jki`G;uv5?EnpH8&Ztx3^J?gFaB)7vz}>q&r}T3G(^Vf|t6i1!*V0 zj~9CSe*aKVI}wz|j-7n8uEy|*$KHCaA)FuZ9nrvOL5IN1c4Z|bd+vM^Xl)M)Uga6X zDNFQ9;cd(K6)!Wrna~vpr>&41=J7Rs5by8vF%}9N`^k5#;`}1VoG?G(px|cmz{A>7 zUL!oZP3?6xF?^pnHdUGzh*T6}LxErru*C2C;Ay0k(^|w2qFTD^Nmsv-3s+8y?rYUK zj~|s8uq#i zbJI+J`iPZu`-fixdGftgi67HFB}tMJ8Kie2c~tnW?TPx)?g>3F^ZL?M4s>9V)xz}8 zA1?(b!+us@O)#(mK>Wq^17w1iV}=J;#*HPr&wbKrIKUbvS5E+~ApkaYZfxLhRnk_NbibOQjpQSH) zetO&?`&av{uf1QqMmD*TK{WPy9Xh(vU z32DvYGGI*%Abf-o^zzvAHwOYKVR(5xze5>sk$5L5|ARPd{n5bgo zrC|*pLRw*6#*ZY1abfRby^ZI^&Jv@Jxv;bTFfhAvN9Ka{*_dN@e}?oxS^l1vHLAH> z_PL>)><8ac&4|-a%;U^Fj#$Yz&j#_;^_fjND-_&|$-+k62Gxm}LUkE9e75g|1{BDL zg)HlCtA=;Lf?QA+x#1Uf;f23|T|&sBZ<%c>?;%(P6{43zH!6G|Cm2{_SYm1H6n61* zH3vp=Sxlke)a@g5ja4SowQ1tBweK&ix=L?ds<1K}_F@qb^tij{$JY!b_x+S_7YLwHg9^T?wY&)6 z5&4{;E2Bqe)FL=O$xzypZwE*J^%4GYLTYxxpSPZc?Vj*0Ahj}8O6ixU3{WFx(72&J z83?>xc)uO)tFztdY0ohUXpn?^y_IIt%)8BzbBZYB6n+;Ccrb4-;2{HFR9&;=Q4J|)?ajh0ZF5{+p z1_^CU2IYO;>MS~opPph`kX7NCzebp09YIL6IGV9O=`39Zs#lSTOujE4JdBW{ZUp4X zwo|icivR!^uK^9Qq8sAW(OcGas4$w1>&t!V%M;9I?EK}D(d_1WD!OgWH&B~w9jiIC zd%tHEtjPw{tLZY!i*)mT9s7pGP0WKG&;8#DxYTM8(Q z>@@~RzD8zjSx&&mccD9X&3%KfRPb@UaQXzx7p}TidPItpP8ZVeb>F=F2ToY_BNSP= zRwAuR3{dVaA->!2Ze(eD-PsMl`b|4LFbD*Lj9pigzwgP2BoT#QR9I=^+Df(7so(o& zd4zl#d@r(!XkozX?JqZfp}S>W8$Ka_36qwpg{tGo#>&Ttn}mkl^j;pdn41CjOt(>$ z!*zN=?wMNJ+3IFMJA_r@0B=scBZkAiw zV1+Dlg0hd94K~?;?w0{Uk)V=Rrhy0~o4p#t!Z!sqS#$r=8b7m=-6zH8QIn4jC+dVl zfAm%#!zD<=) I(~;srk^66#_4o+T=J^YjI~+E~>NnY^_x79O814gT z-%5?7^5V#LlsxxohA9hiU2ndV;JvoAln`#pOhi3R2_kEoh4jORA{vCY{MH}p$P>4FmCC<5yS7*J*BP&$*boxEDYzc}mfKc=BeNL$DlY9T zvZoyL$aik+jCB*I_`RbkRm13JyS$zsDot0)7tyL79I|7wY^hUz} zc~6E2@SCn=8^KrvbIpJBzo^8kk}}U`UdQf!(&h*y6i>Zz_Wh2?Oe_m3c5cdI{L67N z#K`j;*?oP1fM&3nzz42Nz5HagYWkeg!AanN`e+O(-^{5d(D`Gm0=6w1FsMf3@O5G!3M-$S`6v$JJ%seV9svxhK)Z!qoi*@Jn$by1Y$6t3&db2 zw$grIwrkUnO}v@^gv&`Ur;g26TDEA6Gc|w$kft$XF4yO5vA-%o5k30 zf%71;|E*hqU?j6+6&}&g4T)8GBF8dq+U>CM$-Ps4CDQ(B_YM=|;E3#? zlt<|*KQX+Zw8Uir0)2zVoE*W)g6f30;1=lu2*RyY(I=%8}i-WtJXN1Fc{F3n!12%{3;%I`Br-a(-c& ziHNh~So(9bHcS-4QbK}9Zc3GlF&&{Yb4+BBm9>#-HkRL1w;p(uWdWs>OT%C>@b0~B zU*M&JiDsvPLM{Vmn^_))0OjTeyegX#wHc!mXH{C_ zNl7gWL3#k2g&MSt@$Y#gZZXRFH^=TE7R=Vu$iuc!S`r{(7lH5CJRlAh6C@1oFLPJs z>e)*c1_vsVzP21+gSP~l)%x?7;VPF6>Sp=rGTRwYd<5t69om?ne$4hawSGEfl_icyQs3R`w{@qKlJ;4( zICRUK_>8svP7NROk)j%_J^`(KV$Q{mQoruxZ0l5VFRyp7#QE;-^h9v=AkD4s%b{q& zKntIW#EJoti(#RCCXcsCC%{r;#bd!Cn!O@B7Cw+yz7HXxa0Z1-mJyESZCnT+SZMibNiYAA4@o*A905R`EeMb&jaKG1iyN{qF;1;gS2x0vNJ90e_o<47QBGd{4 z^p1rSRA<6FW0A=>a%Yd=3Iuv+A*>FTS-C#XercS~CUBsJG=cQi`OX8W7{8pC$%JYK z0fI~>G@d&4Bn>A2e8n%>>9FZo4X9osBgMiX| zJP!KPUpYkK)Lbu!!96gOrM#Oj} z3mTPuAHNbSeDdky`Oa;@O0KI>s0^YYrid@KA|c5grQ&%7B_$O+t?k#4%!MTzqEZ(P z#_iIH;w0gFp0$?=cmzKCjV#O5QS};4v-^@E0+`7nu7QS5&?EA6PEwT;j>*BG74=Q} z!haRT(FHUZ#J@=1^;?GQg?&)KTtZ^#*WlMJDyAZBB9;a06J zQ+|q66@Ae2TzB_0Fs>uwU#GgFX+MD<;=www_b5~TUzMT0gcnW&;_PZNE~bLqc7fuf zBV}fG4HK-j@~={?Y&tg+Mk4u!hVuov-V}f9A0_rRIwaGXs(EAqGJyZlV@HmV0X>E3 zF!N?KK?ZfWr>`%2gXsWL=J?JbmWCIA$L=5OdCVKBbCLm0OgfKxWL^S&@4SBdhR}Rb zKtcwn9S9rab-V?Yu70{W=!eT~c_5)NC#X338t*whV+lvE(4Xh&M(1FGyB`CvqSr6j zH+Z$MegOH1AGob26Je(vdc4B}(X(YhhKbp0Ixaw?_tf-t^5>`#!Q_usPJ+l?yX#$J zIQZR<-{ReM5PyJz-SAI6L0*=D833Zf`sCMXw-4LEwj}YW9s}lP4^@=Z^x4AUAZy}; zk9H8m)ZwC+`3O15ZpD>Y&-Ye*6fTO!Bco|95CnzB*NqIXpJ5CiQDlwrFD6HH$_r^F zQcy;hWZ{~PdlX)uW_GmbeirkQ~oD9gbdz!g|}ZF=K0+U}chCu;BWS z?i1yi1ER_PjmEN}6l&1qx-)%1uGzCH-`jUnvBE9MxEz&d6u+m^>yiITu5A*ddNfcd zA!o}&>|Zlpkh^1xIIAhsYL}gzxMW3{YAau>!RA+c3p`yjUbd`jm#9r?DpJ#w=$e_I zMIq(T2aywF>+irKw2K_PTAz=9eHgk4*+6@AvHU#?w}>>K<7zzfXPU#yqdv<`EOadz zgIw0I5ZMv}1=CDGy!v0o#>j{!r(w8s+D?(w)H!E<#;owF8Xj{;PF$grFVyWi;R=m4 zJQgsuuU7Nf%jW)z+WqN!8V{M38;~B7abLfh_M*j*(w;r|t=$wT5d#5RKEG*U`EmDW z@-g$?th4zzLR6)bo%`U^hKG{YnlY)FhYU4!l{|lUy{$C&DxOw2o$mlq^7(?4w(u3! z&M9}fb4l9_qR3VF{qurE<4LqT6L;tpLBsdB1|qnr{(~Al%JsgOF2G!3^8k7BeMN&4 z|0dx6cy(bV&){d;ap?Bh$@u)4po~!UAT<$c$Q!Jwheyl;E)S?j`wDkVLNfEE4*-et zHN*k5PW}o97R?E{2Glo;_tNAI6{w5cweV4-a7)^%$n94pG$?7Q{jDy*Uu?b_imDO@?}A1zR0m)#Y!1x!3uAQ z{Dkmx46lj5GT{a^2Q%$L*L_|C;ciDcIV<-!-r+|K^9L_n2qV7T5gm7b{3{^1+L2aQ z2xP%4*h9Q(dlJ3ou3(0JE*LN19%Rl2&LC^D4M-7!Vg4q4KlXp9KC}`1)Dp3p<={;b zk6f^yjxxbrt_9JsHZ_589sEABjYqHZPvnqAF@&} zs>97LVH>_Qh&%>k@09q=L`g#xo|wf_gJd>!w#%TKacr@f{gKm6wwG3OmF@EljAMXJ z;vjO7Ed$128&H~~o^$0FGhRZ!3)&O**PXjLJ4;RvXqvh#aMeOCPg=H_4~Sguh2X~g zK(?WE6}SS4mz22=pB_{ZUM{*8a;}a;YC<&1x?y@HUAvBT$IQhvq}z%`uR~?8!k$*;b@9*Kr#4h_7sdSqyx`Qk%M?-6x)o7kVZUI}30AiPuFOdXo~WMWabs6 zw^FxsHgZ$1RvD(K$SAdvKNfoq^MQE}PX*ez}f3!`GUZ1um!#aV^y@OQiL>Sy|ci%wo7BLLQlO+Nag@i~r2 zFAVimzcYzmR5E5_Uod;CawFMbDU;ZRX7XrlLgRK8koMUdNQ25pKjkc$MZ4yMQts6> zxdFL$#;C?|kGHc2!RN*ui<7CFmeGxBN_A|`Z@3i*_23ox;<{?;lty_^o$Ym+2`}D!stHi^|H3(R4VNf#eCSnUYQd5Kzkeo0OG=CATC-T`%G9!* zVva29gy)Oun;Wyjavs}%AD&GahW$jWQck@)*_oqZoM@6l(zAAf&+LD-X|4kz1QR^m zK)yCTUjG@<-@Fp-XCWj$$Rmw?ebh&-J~#n`pWU8L=!VDP%VU#UPPss6NMlC)$uaNH zB+lx$N|+>$a<9&%9sY>dlv${cy;%wmt2HID`17*tUH|R)sZ8G7=E1>qhA;m4G#R^S z<))GJrz*Y!r^S7p+YkPG5A&Yld4IGsXcv2mVnc#cWOH_~q{9*u@x;2)9T?bQ_d7c{ z675f`({&pM*ON2ObhIdA1c=??76tZrq@VxgPKJZE8wR{ITzfShyK#A21jfVEz2HyrfJuVm1 zg$6!TRv|xm62#XKe4-|v>!&+Zt5Y%cHuJW{P*FBNT1E5RxymBKLUMt#BEb_ark36O zMRAJj`m?HJ;l4i!wIjAawr4tF5D&M!gw@JpRreS7ZwLM8$4jlzZ!#@6DLkOJf@o9I z#NC}buU5rQEQQX^z3Ex831W2df4bzKX$m4~yk8CNBE{{N+Uy$lJN26nWYEDCOCn>A z$D_d|-fGHG55)N<^Zeb>-R-W166|7EJ@qy|zuV>2*>7F%&&l_GmC;P1rG2Gm`8S(u z>`R*gk}m5!hn(tov*Gs(=MRV_K@#HB(6Ai%2zq5nrvzRrW$KGJ0xPCObAm!t>7u#z zm#`CLq!40*AS}H2NY!05yTjzjnQuM#1-BRK&u!#MY{fet#ZbnNPfl8T*z_V8U1?sP zPXFP#CD9iE!e`P|yWR`loBh3*f6{n!_mGI1>8HClg68O2*IF_`(kO! zA$l)zduEk~S&fX;y_u2vQj|RrEvjNb37>@5;VjVq=`kRsK4I9JzU^?|tvj@|s`75r z7M=Jw%_$Ggt}cIP`5ALoaF7a3JxHt_D>bFbK%~6b>X8x@;UH?*+8Kls-S2=bBVu@a z=Qkfm=vqB{Tm^P>a}!zPt8}z(!zTyS#cHs<k)$YvjqrUo31JODa)>%T}alo#=JCEfP5b|23936E@$!}laS1*j$>;y0t zMTPP${i^HxN{{jwJ+V(VFccKjF91Fxjg5vzx1k4o^!d2oMzGG{kL!~}K~vUNu6Ke~ z)Q2LXuW4zAV{>v!&n4rjsy5o$JZ!n|6ESoKC%ot+n4jtRpnNiZqmgCS;V;BGF8%0J z46)=8+M@Y4+o}JKqp|Z68>TZ(-lcR$!H#~Ru63^ndS!jzumVJ_VxI5hm zQ)HAqhTT1oVMhYv=ehQR2v#z%H~LSmgo>>5Yl(cSH2InAgPOB3LM&nojjM8Z-#gmx z(`^{VWOe*~(F+uG@&a^U(O=dX^wU+jEN=#|ktlwFj*dPAnfXRRzR;JPU?9@1 zVIne5li0sv8n!Nz?k)FMAyY0k!+u z#R0=oCa8&?8K(N};mSPSj&)@;$fGCfwmx1gm=<{Q8B^wHWp&l2S)>`-LCs4*=O zz}PYq;5h1U^s5b*5G<4(C zh>|x>#JU=jww{5@WY)DS3Sv}HVULAKS0jStl6JBDLT4iQv)oGIL9P5kOq(p|S*St@ zCL-Mg4U)xR%{9e1$(&^XD>Dj1HRrL}*C*W(A;C9OvY?0dNV^|^vBJ?cmJtgj_Zbh@ z{S~lc{kI7Y1@#pk8P0JYC$Fv;0Mh1OJogWq9>nVTTJ`bNF#uPyLHv>A!aaMLZS zMVM1FC`mW6wM@c!UW>JR&TI6}*0;L50C%|&y>m?c_wEQ1UhKsk)v{iQA^cr>KDmJ4 zs#}hcD)2)Z{43lYfe(JAPtqo4ApXvqZZX|2&~jUrl&^nYKx5a8BL|8{P3Pi336nHN ziL3t(O*%Z*hH*f!F9>*o1o>&F6Sc3kB&0c;b3ioV5KC5WA2 zhx&r%JLcKz53aMy(g-f=MtpWfONp<_B8qb8e|*WEbEb%al;g6Pr~u!AqK6T>DLQt1 zK7Uu+gt=qP{+%KQE%j~NHy*~N9=A#+ZUTK+lgb>hVe%-Dij_DzTw>bh8`3#7-tqo8 z$*Em9x$|+D362t*hQl=#mn1%`hK>_mJ2psL+J};pCWoyQ%C9S4OzVE)A#~Ee4 zpQ3ARl>HT~2n*OF6BLLHRYoza0)}5lc(84X<8W8R%$nT z2!n^7B+!ww{U|KI#nmK&9*p%B<+4;dj|Ii3g0qKSz)(vpX9=7ndgwoH|MtzBH`UBR zMEZC>CJ~MX{dONKV<5i1sk3@?&Qib}egw}3VCFQR6hgG#;vAl-{Arkj8kyqF%2D+s zS@kr4GyL0`OfDGc2TB2^WnQ#oB0Gw&lsQKOam3`ibNXLz-?=(6NW);uD=QuJ?-;uj1&*#eh6uT6BDk%o#*Q)0k4m+}}vRCtnhWJt>+g0F05KtWa z6290=X%90utjJw?GY6_0hZZTYI+!`cze#Rw3*j=SpJ2cYF~v83=ja$B zQ7rmywy!8rv#^ArvH#*%zCcH$O{O+5U}|3tM_|C8g3(CL?5bI{OAZi-}Qc~Kf0aDJ>wSD zFlhjH_IaR__D7Jjfn#&HE>ESq(2z{$OyAAQZF}31HI7-9dprn&K3D~?S69g0dZ;ms zhI`RfK_c>_Mh5&U^w2|M<$^Ir?QhvV$qE`ZOpICMjWBV%EGiAWaq9-==oMddae_&| z@ymipMNIa7h6m%Js5tsCg&KHdD)ylHmKgukW3j+sg-29*Wp{Kx+T>C81me3Kt+LpK z;6py3&~jB5SvOpCH*i6tcx>x6NJ>%))BO{gLzF1WdZ4X`eCqab>lBOzk<2&*b8_nB zzTR{-+(==Sx4W4r=yl=wubFRXBmxhyKtGp%Uc=_9hn!Ad9$t&;lTO4MKi{bJjDcXH z2CESR=MxvwN>A8p+gwai-^`^FUqHE7r_bX)FY*sRwE2)+7UZ!iW1#FiLFq)_LTgtaf^7J7#OFfA*~pk?!<1gLPZcZ@9t% zfm!J_e**NmrtgEyrhGBu_78V63wrY$Wc+Q_ScZPTHyFWp=@b@%%reCLj-zV%-51%U zmsZkU0!Spxm1RkG)vvZy&ciS@S=Ti!C2ESF+1d`wJe1`mvp*2w5k<{kbeNRBW#gKw zZlYj886!lDvj6D10x!cL$T7kzh<`sZ-`Xy8GtR^XmLvABe&8b!|02XtGUD;q-E6=& zmkxup?KqxgZC2m^M0Y-r%*<;!JSEY?TGW;XeMvf;^`_qt7T~>V20pDzU>-1X(Sjf5 zG2Dy)oESBpIspjC^uz6T7aRb~k27tYFYwu=|229Wq5j8=iIzy&Eo!@mAKdy}bjD;e z6)8k6+52001J99632J&RtB*!-2#w%|cm*HxZ3;2iQ&6_DPD{i{kEH{xyhUX})P8b~ z&yj56BtQH*eIJf?P5H)RUaWBx;|Z45#>21T=*TNDqmgWyRulz`V?h`Dihmjv>_~p{ z3fqHy-y2h1hxD8B!uqJU^wjap`xNc*Fy6NwE-J+oz2h%(=MLSPF~vF->{9!qF5jf({ zUSjrbjt!O$YCrQVL5-Oc8;}KYnK=q5p=Yrmed(D!NWWcxeE~c5wG%~Pw})Z<__?d| zOCes6V9uu_(w7}LelYQa4K@V8pQ_)85f>OLgZPuetc+jSEdZ5Y!uyv3)?w-4QDVYa z#SmU$vl8H1)<8oXkBLn(Qp}mAq;Fhl&_e{@iI1mh69gU$#X+F;g?$v6Q59qG(hA_i zNg=^DeY&X-?=d(WZZf<56+hp@x)cH`<{H$^IBVP|0tQe{i%+NzTIB8+`jShi_iZuA z9s|K(tIFIFYx|WPv%%_*u4*w>`omWesxkJC;|FlyvbSPbGjwU7xrplbYeQE(K7 zW>2P4xr~2Ir0Dp?K{Vt22K$v3h{H@a;IEhEkFrBF_r>C;POLE-_|#NyuI9To9#V5l z3&j)XsFd=$RL~%9u0*59cVJc8#B>$2gKI>7A|S=~I2RA2hTpFDM7nTt*i4U1(LHOH z2GNoCOK@G^8^=`Czwzk!>j>eSkJ{V_q{!ZueXrmlr7e#NMx*P^5*z+dn5@eQd(<(u zO-=W&hs4u^mk7RJ0I^)@Cxp}npkJeOc-4?Ot|ZS7PBRS=61Dp7PWuB^u6;oT<=ORg z+LFKFg|jC*nTwAf4|>7(A3ql_(i#V@$u4dgWd5JGuj#ib$6n!!Gh&x)E|*4$IVG@d zOtAvztGPBx9OQMo?anAI`0H5Puf-OT_$y9qMpHb3^tl|(*08Qj`XpZZL&xwYc+;=# zgEA31&if%4-T&QqJha}~L=9seWbQhU8~;Bv&IOF=b~}`52*97BoSH0H+Wgc12aS)o A$^ZZW literal 0 HcmV?d00001 diff --git a/lib/assets/background_for_Fictus.png b/lib/assets/background_for_Fictus.png new file mode 100644 index 0000000000000000000000000000000000000000..146957e8de68457d159b540e3ddef92abbf5d194 GIT binary patch literal 65670 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 T`TBn7x7|B*wllW=ec}HA(m6FJ literal 0 HcmV?d00001 diff --git a/lib/componets/Account_Card.dart b/lib/componets/Account_Card.dart new file mode 100644 index 0000000..234342e --- /dev/null +++ b/lib/componets/Account_Card.dart @@ -0,0 +1,35 @@ +import 'package:flutter/material.dart'; + +class AccountCard extends StatelessWidget { + final String title; + final String amount; + + AccountCard({required this.title, required this.amount}); + + @override + Widget build(BuildContext context) { + return Card( + margin: EdgeInsets.symmetric(vertical: 8.0), + color: Colors.white + .withOpacity(0.9), // Slightly transparent to blend with background + child: Padding( + padding: const EdgeInsets.only( + left: 20, right: 250, bottom: 16.0, top: 16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle(fontSize: 18, color: Colors.grey.shade700), + ), + SizedBox(height: 8), + Text( + amount, + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + ], + ), + ), + ); + } +} diff --git a/lib/componets/BudgetItemCard.dart b/lib/componets/BudgetItemCard.dart new file mode 100644 index 0000000..8d53754 --- /dev/null +++ b/lib/componets/BudgetItemCard.dart @@ -0,0 +1,29 @@ +import 'package:flutter/material.dart'; + +class BudgetItemCard extends StatelessWidget { + final String label; + final String percentage; + final Color color; + + BudgetItemCard( + {required this.label, required this.percentage, required this.color}); + + @override + Widget build(BuildContext context) { + return Card( + color: color.withOpacity(0.9), + margin: EdgeInsets.symmetric(vertical: 8.0), + child: ListTile( + title: Text( + percentage, + style: TextStyle(color: Colors.white, fontSize: 18), + ), + subtitle: Text( + label, + style: TextStyle(color: Colors.white, fontSize: 14), + ), + trailing: Icon(Icons.more_vert, color: Colors.white), + ), + ); + } +} diff --git a/lib/componets/Stock_Item.dart b/lib/componets/Stock_Item.dart new file mode 100644 index 0000000..6e7d0f2 --- /dev/null +++ b/lib/componets/Stock_Item.dart @@ -0,0 +1,74 @@ +import 'package:flutter/material.dart'; + +class StockItem extends StatelessWidget { + final String name; + final String symbol; + final String price; + final String change; + final bool isPositive; + + StockItem({ + required this.name, + required this.symbol, + required this.price, + required this.change, + required this.isPositive, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + name, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 16), + ), + Text( + symbol, + style: TextStyle(color: Colors.grey.shade500, fontSize: 12), + ), + ], + ), + // Small placeholder for the line chart + Container( + width: 50, + height: 20, + color: Colors.green.shade300, + ), + Column( + crossAxisAlignment: CrossAxisAlignment.end, + children: [ + Text( + price, + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 16), + ), + Container( + decoration: BoxDecoration( + color: isPositive ? Colors.green : Colors.red, + borderRadius: BorderRadius.circular(4), + ), + padding: EdgeInsets.symmetric(horizontal: 6, vertical: 2), + child: Text( + change, + style: TextStyle(color: Colors.white, fontSize: 12), + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/componets/setting_tiles.dart b/lib/componets/setting_tiles.dart new file mode 100644 index 0000000..d515c9c --- /dev/null +++ b/lib/componets/setting_tiles.dart @@ -0,0 +1,33 @@ +import 'package:flutter/material.dart'; + +class SettingsTile extends StatelessWidget { + final IconData icon; + final String title; + final String? subtitle; + final Widget? trailing; + final Color? titleColor; + final Function? onTap; + + SettingsTile({ + required this.icon, + required this.title, + this.subtitle, + this.trailing, + this.titleColor, + this.onTap, + }); + + @override + Widget build(BuildContext context) { + return ListTile( + leading: Icon(icon, color: Colors.blueGrey), + title: Text( + title, + style: TextStyle(color: titleColor ?? Colors.black), + ), + subtitle: subtitle != null ? Text(subtitle!) : null, + trailing: trailing, + onTap: onTap != null ? () => onTap!() : null, + ); + } +} diff --git a/lib/main.dart b/lib/main.dart index fc25988..536254b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -5,8 +5,8 @@ import 'screens/auth_screen.dart'; import 'screens/home_screen.dart'; void main() async { - WidgetsFlutterBinding.ensureInitialized(); - await Firebase.initializeApp(); + //WidgetsFlutterBinding.ensureInitialized(); + //await Firebase.initializeApp(); runApp(const MainApp()); } @@ -21,6 +21,8 @@ class MainApp extends StatelessWidget { primarySwatch: Colors.blue, brightness: Brightness.light, ), + home: HomeScreen(), + /* home: StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { @@ -33,6 +35,7 @@ class MainApp extends StatelessWidget { return const AuthScreen(); }, ), + */ ); } } diff --git a/lib/screens/budget_page.dart b/lib/screens/budget_page.dart new file mode 100644 index 0000000..baeace1 --- /dev/null +++ b/lib/screens/budget_page.dart @@ -0,0 +1,143 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:fiscus/componets/BudgetItemCard.dart'; +import 'package:flutter/material.dart'; +import 'package:fl_chart/fl_chart.dart'; + +class BudgetPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // Background Image + Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("lib/assets/Login-Setup.png"), + fit: BoxFit.cover, + ), + ), + ), + // Overlay Content + Column( + children: [ + SizedBox(height: 50), // Adjust for spacing + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( + children: [ + CircleAvatar( + radius: 24, + backgroundColor: Colors.grey, + ), + SizedBox(width: 16), + Text( + 'Budget Report', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + Spacer(), + Icon(Icons.notifications, color: Colors.black), + SizedBox(width: 16), + Icon(Icons.more_vert, color: Colors.black), + ], + ), + ), + SizedBox(height: 30), + // Circular Progress (Budget Pie Chart) + SizedBox( + height: 200, + child: PieChart( + PieChartData( + sections: [ + PieChartSectionData( + color: Colors.blue.shade800, + value: 65, + title: '65%', + radius: 50, + titleStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + PieChartSectionData( + color: Colors.lightBlue.shade300, + value: 20, + title: '20%', + radius: 50, + titleStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + PieChartSectionData( + color: Colors.lightBlueAccent, + value: 2.5, + title: '2.5%', + radius: 50, + titleStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ], + ), + ), + ), + SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.circle, size: 8, color: Colors.grey), + SizedBox(width: 8), + Icon(Icons.circle, size: 8, color: Colors.grey.shade300), + SizedBox(width: 8), + Icon(Icons.circle, size: 8, color: Colors.grey.shade300), + ], + ), + SizedBox(height: 20), + // Scrollable Budget Items + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + children: [ + BudgetItemCard( + label: 'Taxes', + percentage: '65%', + color: Colors.blue.shade800, + ), + SizedBox(height: 10), + BudgetItemCard( + label: 'Food', + percentage: '20%', + color: Colors.lightBlue.shade300, + ), + SizedBox(height: 10), + BudgetItemCard( + label: 'Entertainment', + percentage: '2.5%', + color: Colors.lightBlueAccent, + ), + // Add more BudgetItemCards here as needed + ], + ), + ), + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/screens/camera_page.dart b/lib/screens/camera_page.dart new file mode 100644 index 0000000..779151a --- /dev/null +++ b/lib/screens/camera_page.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; + +class CameraPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Camera Page'), + ), + body: Center( + child: Text('This is the camera page'), + ), + ); + } +} diff --git a/lib/screens/home_page.dart b/lib/screens/home_page.dart new file mode 100644 index 0000000..45c4689 --- /dev/null +++ b/lib/screens/home_page.dart @@ -0,0 +1,101 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:fiscus/componets/Account_Card.dart'; +import 'package:flutter/material.dart'; + +class HomePage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // Background Image + Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("lib/assets/Login-Setup.png"), + fit: BoxFit.cover, + ), + ), + ), + // Overlay Content + Column( + children: [ + SizedBox(height: 50), // Adjust as needed for spacing + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( + children: [ + CircleAvatar( + radius: 24, + backgroundColor: Colors.grey, + ), + SizedBox(width: 16), + Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + 'Welcome,', + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + Text( + '[Name]', + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + ], + ), + ], + ), + ), + Expanded( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 30.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + Padding( + padding: const EdgeInsets.only(right: 175.0), + child: Text( + '[Bank Name]:', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + ), + AccountCard(title: 'Debit', amount: '\$0.00'), + AccountCard(title: 'Credit', amount: '\$0.00'), + AccountCard(title: 'Savings', amount: '\$0.00'), + ], + ), + ), + ), + ), + Padding( + padding: const EdgeInsets.only(bottom: 16.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Icon(Icons.circle, size: 20, color: Colors.grey), + SizedBox(width: 8), + Icon(Icons.circle, size: 16, color: Colors.grey.shade300), + SizedBox(width: 8), + Icon(Icons.circle, size: 16, color: Colors.grey.shade300), + ], + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 3021413..23b1de5 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -1,9 +1,10 @@ import 'package:flutter/material.dart'; -import 'dashboard_screen.dart'; -import 'budget_screen.dart'; -import 'charts_screen.dart'; -import 'profile_screen.dart'; +import 'home_page.dart'; +import 'camera_page.dart'; +import 'setting_page.dart'; +import 'stocks_page.dart'; +import 'budget_page.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @@ -15,26 +16,56 @@ class HomeScreen extends StatefulWidget { class _HomeScreenState extends State { int _selectedIndex = 0; - final List _screens = [ - const DashboardScreen(), - const BudgetScreen(), - const ChartsScreen(), - const ProfileScreen(), + // List of pages to navigate to + final List _pages = [ + HomePage(), // Home page + BudgetPage(), // Reports page + CameraPage(), // Camera page + StocksPage(), // Stocks page + SettingsPage(), // Settings page ]; + // Function to handle navigation item selection + void _onItemTapped(int index) { + setState(() { + _selectedIndex = index; + }); + } + @override Widget build(BuildContext context) { return Scaffold( - body: _screens[_selectedIndex], + body: IndexedStack( + index: _selectedIndex, + children: _pages, + ), bottomNavigationBar: BottomNavigationBar( currentIndex: _selectedIndex, - onTap: (index) => setState(() => _selectedIndex = index), - items: const [ - BottomNavigationBarItem(icon: Icon(Icons.dashboard), label: 'Dashboard'), - BottomNavigationBarItem(icon: Icon(Icons.account_balance_wallet), label: 'Budget'), - BottomNavigationBarItem(icon: Icon(Icons.pie_chart), label: 'Analytics'), - BottomNavigationBarItem(icon: Icon(Icons.person), label: 'Profile'), + onTap: _onItemTapped, + items: [ + BottomNavigationBarItem( + icon: Icon(Icons.home), + label: 'Accounts', + ), + BottomNavigationBarItem( + icon: Icon(Icons.bar_chart), + label: 'Reports', + ), + BottomNavigationBarItem( + icon: Icon(Icons.camera_alt), + label: 'Camera', + ), + BottomNavigationBarItem( + icon: Icon(Icons.attach_money), + label: 'Stocks', + ), + BottomNavigationBarItem( + icon: Icon(Icons.settings), + label: 'Settings', + ), ], + selectedItemColor: Colors.blue, // Selected icon color + unselectedItemColor: Colors.grey, // Unselected icon color ), ); } diff --git a/lib/screens/setting_page.dart b/lib/screens/setting_page.dart new file mode 100644 index 0000000..427a261 --- /dev/null +++ b/lib/screens/setting_page.dart @@ -0,0 +1,151 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:fiscus/componets/setting_tiles.dart'; +import 'package:flutter/material.dart'; + +class SettingsPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text("Settings"), + backgroundColor: Colors.blueGrey, + ), + body: ListView( + children: [ + // Account Settings Section + SettingsSection( + title: "Account", + tiles: [ + SettingsTile( + icon: Icons.person, + title: "Profile", + subtitle: "Edit your profile details", + onTap: () { + // Handle profile tap + }, + ), + SettingsTile( + icon: Icons.lock, + title: "Password", + subtitle: "Change your password", + onTap: () { + // Handle password tap + }, + ), + SettingsTile( + icon: Icons.security, + title: "Privacy", + subtitle: "Manage your privacy settings", + onTap: () { + // Handle privacy tap + }, + ), + ], + ), + // Notifications Section + SettingsSection( + title: "Notifications", + tiles: [ + SettingsTile( + icon: Icons.notifications, + title: "Push Notifications", + trailing: Switch(value: true, onChanged: (val) {}), + ), + SettingsTile( + icon: Icons.email, + title: "Email Notifications", + trailing: Switch(value: false, onChanged: (val) {}), + ), + SettingsTile( + icon: Icons.sms, + title: "SMS Notifications", + trailing: Switch(value: false, onChanged: (val) {}), + ), + ], + ), + // General Settings Section + SettingsSection( + title: "General", + tiles: [ + SettingsTile( + icon: Icons.language, + title: "Language", + subtitle: "English", + onTap: () { + // Handle language tap + }, + ), + SettingsTile( + icon: Icons.palette, + title: "Theme", + subtitle: "Light", + onTap: () { + // Handle theme tap + }, + ), + ], + ), + // About Section + SettingsSection( + title: "About", + tiles: [ + SettingsTile( + icon: Icons.info, + title: "About Us", + onTap: () { + // Handle About Us tap + }, + ), + SettingsTile( + icon: Icons.help, + title: "Help", + onTap: () { + // Handle Help tap + }, + ), + SettingsTile( + icon: Icons.logout, + title: "Logout", + titleColor: Colors.red, + onTap: () { + // Handle logout + }, + ), + ], + ), + ], + ), + ); + } +} + +class SettingsSection extends StatelessWidget { + final String title; + final List tiles; + + SettingsSection({required this.title, required this.tiles}); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + color: Colors.grey.shade700, + ), + ), + SizedBox(height: 8), + Column(children: tiles), + Divider(thickness: 1), + ], + ), + ); + } +} diff --git a/lib/screens/stocks_page.dart b/lib/screens/stocks_page.dart new file mode 100644 index 0000000..f98d487 --- /dev/null +++ b/lib/screens/stocks_page.dart @@ -0,0 +1,114 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:fiscus/componets/Stock_Item.dart'; +import 'package:flutter/material.dart'; + +class StocksPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // Background Image + Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("lib/assets/Login-Setup.png"), + fit: BoxFit.cover, + ), + ), + ), + // Overlay Content + Column( + children: [ + SizedBox(height: 50), // Adjust for spacing + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( + children: [ + CircleAvatar( + radius: 24, + backgroundColor: Colors.grey, + ), + SizedBox(width: 16), + Text( + 'Stocks', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + Spacer(), + Icon(Icons.notifications, color: Colors.white), + SizedBox(width: 16), + Icon(Icons.more_vert, color: Colors.white), + ], + ), + ), + SizedBox(height: 30), + // Stocks List Container + Center( + child: Container( + width: 350, + decoration: BoxDecoration( + color: Colors.black.withOpacity(0.8), + borderRadius: BorderRadius.circular(16), + ), + child: ListView( + shrinkWrap: true, + children: [ + StockItem( + name: "Dow Jones", + symbol: "Dow Jones Industrial Average", + price: "40,696.21", + change: "+1.91%", + isPositive: true, + ), + StockItem( + name: "S&P 500", + symbol: "Standard & Poor's 500", + price: "5,480.03", + change: "+1.50%", + isPositive: true, + ), + StockItem( + name: "^FTSE", + symbol: "FTSE 100", + price: "8,285.71", + change: "+1.21%", + isPositive: true, + ), + StockItem( + name: "GE", + symbol: "GE Aerospace", + price: "171.01", + change: "+3.85%", + isPositive: true, + ), + StockItem( + name: "AAPL", + symbol: "Apple Inc.", + price: "219.37", + change: "+0.86%", + isPositive: true, + ), + StockItem( + name: "NKE", + symbol: "NIKE, Inc.", + price: "72.44", + change: "+1.45%", + isPositive: true, + ), + ], + ), + ), + ), + ], + ), + ], + ), + ); + } +} diff --git a/pubspec.lock b/pubspec.lock index 0b1330f..861e853 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + equatable: + dependency: transitive + description: + name: equatable + sha256: "567c64b3cb4cf82397aac55f4f0cbd3ca20d77c6c03bedbc4ceaddc08904aef7" + url: "https://pub.dev" + source: hosted + version: "2.0.7" fake_async: dependency: transitive description: @@ -105,6 +113,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.18.1" + fl_chart: + dependency: "direct main" + description: + name: fl_chart + sha256: "74959b99b92b9eebeed1a4049426fd67c4abc3c5a0f4d12e2877097d6a11ae08" + url: "https://pub.dev" + source: hosted + version: "0.69.2" flutter: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index da685c8..8a818db 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -11,6 +11,7 @@ dependencies: sdk: flutter firebase_core: ^3.8.0 firebase_auth: ^5.3.3 + fl_chart: ^0.69.2 dev_dependencies: flutter_test: @@ -19,3 +20,5 @@ dev_dependencies: flutter: uses-material-design: true + assets: + - lib/assets/ From 42e683305f36f403d0857c17b4b7e7fac27e945d Mon Sep 17 00:00:00 2001 From: ALeBD Date: Fri, 6 Dec 2024 02:41:32 -0800 Subject: [PATCH 02/11] login page import --- lib/screens/login_page.dart | 105 ++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) create mode 100644 lib/screens/login_page.dart diff --git a/lib/screens/login_page.dart b/lib/screens/login_page.dart new file mode 100644 index 0000000..beefcef --- /dev/null +++ b/lib/screens/login_page.dart @@ -0,0 +1,105 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter/material.dart'; + +class LoginPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("lib/assets/Login-Setup – 1.png"), + fit: BoxFit.cover, + ), + ), + child: Center( + child: Padding( + padding: const EdgeInsets.all(16.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Align( + alignment: Alignment.centerLeft, + child: Text( + 'Login', + style: TextStyle( + fontSize: 32, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + ), + SizedBox(height: 20), + TextField( + style: TextStyle(color: Colors.white), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Username', + labelStyle: TextStyle(color: Colors.white), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + ), + ), + ), + SizedBox(height: 20), + TextField( + obscureText: true, + style: TextStyle(color: Colors.white), + decoration: InputDecoration( + border: OutlineInputBorder(), + labelText: 'Password', + labelStyle: TextStyle(color: Colors.white), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide(color: Colors.white), + ), + ), + ), + TextButton( + onPressed: () { + // Handle forgot password logic + }, + child: Text('Forgot Password?', + style: TextStyle(color: Colors.black)), + ), + SizedBox(height: 20), + TextButton( + onPressed: () { + // Handle sign up logic + }, + child: Text( + "Don't have an account? Sign up now", + selectionColor: Colors.white, + style: TextStyle(color: Colors.black), + ), + ), + SizedBox(height: 80), + ElevatedButton( + onPressed: () { + // Handle login logic + }, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + padding: EdgeInsets.symmetric(horizontal: 50, vertical: 15), + textStyle: TextStyle(fontSize: 20), + ), + child: Text('Sign in', + style: TextStyle( + color: Colors.black, + fontSize: 20, + fontWeight: FontWeight.bold)), + ), + ], + ), + ), + ), + ), + ); + } +} From d240f56b5808978f2b0ba57b1ee39db15db39716 Mon Sep 17 00:00:00 2001 From: ALeBD Date: Fri, 6 Dec 2024 11:27:07 -0800 Subject: [PATCH 03/11] Added Swiping between budget and spending page and other changes --- lib/screens/budget_page.dart | 308 ++++++++++++++++++++++++++------- lib/screens/home_screen.dart | 4 +- lib/screens/report_page.dart | 20 +++ lib/screens/spending_page.dart | 214 +++++++++++++++++++++++ 4 files changed, 480 insertions(+), 66 deletions(-) create mode 100644 lib/screens/report_page.dart create mode 100644 lib/screens/spending_page.dart diff --git a/lib/screens/budget_page.dart b/lib/screens/budget_page.dart index baeace1..37771cc 100644 --- a/lib/screens/budget_page.dart +++ b/lib/screens/budget_page.dart @@ -1,10 +1,115 @@ -// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables - -import 'package:fiscus/componets/BudgetItemCard.dart'; import 'package:flutter/material.dart'; import 'package:fl_chart/fl_chart.dart'; -class BudgetPage extends StatelessWidget { +class BudgetPage extends StatefulWidget { + @override + _BudgetPageState createState() => _BudgetPageState(); +} + +class _BudgetPageState extends State { + // List to store budget items + List budgetItems = [ + BudgetItem(label: 'Taxes', percentage: 65, color: Colors.blue.shade800), + BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300), + BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.lightBlueAccent), + ]; + + // Method to calculate the total percentage + double getTotalPercentage() { + return budgetItems.fold(0, (sum, item) => sum + item.percentage); + } + + // Method to calculate the sections of the pie chart + List getPieChartSections() { + double totalPercentage = getTotalPercentage(); + + // If the total is 0, return a faint outline of the pie chart + if (totalPercentage == 0) { + return [ + PieChartSectionData( + color: Colors.grey.shade300, + value: 1, + radius: 60, + showTitle: false, + ), + ]; + } + + // Create sections for each budget item + List sections = budgetItems.map((item) { + double adjustedPercentage = (item.percentage / 100) * 100; + return PieChartSectionData( + color: item.color, + value: adjustedPercentage, + title: '${adjustedPercentage.toStringAsFixed(1)}%', + radius: 60, + titleStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ); + }).toList(); + + // Add a greyed-out section for the remaining percentage + double remainingPercentage = 100 - totalPercentage; + if (remainingPercentage > 0) { + sections.add( + PieChartSectionData( + color: Colors.grey.shade300, + value: remainingPercentage, + title: '${remainingPercentage.toStringAsFixed(1)}%', + radius: 60, + titleStyle: TextStyle( + fontSize: 16, + fontWeight: FontWeight.bold, + color: Colors.grey.shade700, + ), + ), + ); + } + + return sections; + } + + // Method to add a new budget item + void addBudgetItem(String label, double percentage, Color color) { + setState(() { + budgetItems.add(BudgetItem(label: label, percentage: percentage, color: color)); + }); + checkTotalPercentage(); + } + + // Method to remove a budget item + void removeBudgetItem(int index) { + setState(() { + budgetItems.removeAt(index); + }); + checkTotalPercentage(); + } + + // Warn if total percentage exceeds 100% + void checkTotalPercentage() { + double total = getTotalPercentage(); + if (total > 100) { + WidgetsBinding.instance.addPostFrameCallback((_) { + showDialog( + context: context, + builder: (context) => AlertDialog( + title: Text('Warning'), + content: Text('The total budget exceeds 100%. Adjust your values.'), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), + child: Text('OK'), + ), + ], + ), + ); + }); + } + } + @override Widget build(BuildContext context) { return Scaffold( @@ -24,8 +129,7 @@ class BudgetPage extends StatelessWidget { children: [ SizedBox(height: 50), // Adjust for spacing Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 5.0), child: Row( children: [ CircleAvatar( @@ -51,44 +155,11 @@ class BudgetPage extends StatelessWidget { SizedBox(height: 30), // Circular Progress (Budget Pie Chart) SizedBox( - height: 200, + height: 210, child: PieChart( PieChartData( - sections: [ - PieChartSectionData( - color: Colors.blue.shade800, - value: 65, - title: '65%', - radius: 50, - titleStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), - PieChartSectionData( - color: Colors.lightBlue.shade300, - value: 20, - title: '20%', - radius: 50, - titleStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), - PieChartSectionData( - color: Colors.lightBlueAccent, - value: 2.5, - title: '2.5%', - radius: 50, - titleStyle: TextStyle( - fontSize: 16, - fontWeight: FontWeight.bold, - color: Colors.white, - ), - ), - ], + sections: getPieChartSections(), + centerSpaceRadius: 40, ), ), ), @@ -96,11 +167,11 @@ class BudgetPage extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.circle, size: 8, color: Colors.grey), + _buildCircleWithShadow(Icons.circle, Colors.grey), SizedBox(width: 8), - Icon(Icons.circle, size: 8, color: Colors.grey.shade300), + _buildCircleWithShadow(Icons.circle, Colors.grey.shade300), SizedBox(width: 8), - Icon(Icons.circle, size: 8, color: Colors.grey.shade300), + _buildCircleWithShadow(Icons.circle, Colors.grey.shade300), ], ), SizedBox(height: 20), @@ -110,34 +181,141 @@ class BudgetPage extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0), child: Column( - children: [ - BudgetItemCard( - label: 'Taxes', - percentage: '65%', - color: Colors.blue.shade800, - ), - SizedBox(height: 10), - BudgetItemCard( - label: 'Food', - percentage: '20%', - color: Colors.lightBlue.shade300, - ), - SizedBox(height: 10), - BudgetItemCard( - label: 'Entertainment', - percentage: '2.5%', - color: Colors.lightBlueAccent, - ), - // Add more BudgetItemCards here as needed - ], + children: budgetItems + .asMap() + .entries + .map( + (entry) => Column( + children: [ + BudgetItemCard( + label: entry.value.label, + percentage: '${entry.value.percentage}%', + color: entry.value.color, + onDelete: () => removeBudgetItem(entry.key), + ), + SizedBox(height: 10), + ], + ), + ) + .toList(), ), ), ), ), + // Add Budget Item Button + Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: () { + _showAddBudgetItemDialog(context); + }, + child: Text('Add Budget Item'), + ), + ), ], ), ], ), ); } + + // Dialog to add a new budget item + void _showAddBudgetItemDialog(BuildContext context) { + final TextEditingController labelController = TextEditingController(); + final TextEditingController percentageController = TextEditingController(); + + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Add Budget Item'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: labelController, + decoration: InputDecoration(labelText: 'Label'), + ), + TextField( + controller: percentageController, + decoration: InputDecoration(labelText: 'Percentage'), + keyboardType: TextInputType.number, + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + final label = labelController.text; + final percentage = double.tryParse(percentageController.text) ?? 0; + if (label.isNotEmpty && percentage > 0) { + addBudgetItem(label, percentage, Colors.primaries[budgetItems.length % Colors.primaries.length]); + } + Navigator.of(context).pop(); + }, + child: Text('Add'), + ), + ], + ); + }, + ); + } +} +// Helper to create a circle with shadow + Widget _buildCircleWithShadow(IconData icon, Color color) { + return Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 6, + spreadRadius: 2, + offset: Offset(0, 3), + ), + ], + ), + child: Icon(icon, size: 12, color: color), + ); + } + +// Model for a budget item +class BudgetItem { + final String label; + final double percentage; + final Color color; + + BudgetItem({required this.label, required this.percentage, required this.color}); +} + +// Widget for Budget Item Card +class BudgetItemCard extends StatelessWidget { + final String label; + final String percentage; + final Color color; + final VoidCallback? onDelete; + + BudgetItemCard({required this.label, required this.percentage, required this.color, this.onDelete}); + + @override + Widget build(BuildContext context) { + return Card( + color: color.withOpacity(0.8), + child: ListTile( + title: Text(label, style: TextStyle(color: Colors.white)), + subtitle: Text(percentage, style: TextStyle(color: Colors.white70)), + trailing: IconButton( + icon: Icon(Icons.delete, color: Colors.white), + onPressed: onDelete, + ), + ), + ); + } + } diff --git a/lib/screens/home_screen.dart b/lib/screens/home_screen.dart index 23b1de5..b488b43 100644 --- a/lib/screens/home_screen.dart +++ b/lib/screens/home_screen.dart @@ -1,10 +1,12 @@ +import 'package:fiscus/screens/report_page.dart'; import 'package:flutter/material.dart'; import 'home_page.dart'; import 'camera_page.dart'; import 'setting_page.dart'; import 'stocks_page.dart'; import 'budget_page.dart'; +import 'spending_page.dart'; class HomeScreen extends StatefulWidget { const HomeScreen({super.key}); @@ -19,7 +21,7 @@ class _HomeScreenState extends State { // List of pages to navigate to final List _pages = [ HomePage(), // Home page - BudgetPage(), // Reports page + ReportPage(), // Reports page CameraPage(), // Camera page StocksPage(), // Stocks page SettingsPage(), // Settings page diff --git a/lib/screens/report_page.dart b/lib/screens/report_page.dart new file mode 100644 index 0000000..30e85fd --- /dev/null +++ b/lib/screens/report_page.dart @@ -0,0 +1,20 @@ + +import 'package:fiscus/screens/budget_page.dart'; +import 'package:fiscus/screens/spending_page.dart'; +import 'package:flutter/material.dart'; + +class ReportPage extends StatelessWidget { + const ReportPage({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + body: PageView( + children: [ + BudgetPage(), + SpendingReportPage(), + ], + ) + ); + } +} \ No newline at end of file diff --git a/lib/screens/spending_page.dart b/lib/screens/spending_page.dart new file mode 100644 index 0000000..2f2d8f9 --- /dev/null +++ b/lib/screens/spending_page.dart @@ -0,0 +1,214 @@ +// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables + +import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/material.dart'; + +class SpendingReportPage extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + body: Stack( + children: [ + // Background Image + Container( + decoration: BoxDecoration( + image: DecorationImage( + image: AssetImage("lib/assets/Login-Setup.png"), + fit: BoxFit.cover, + ), + ), + ), + // Overlay Content + Column( + children: [ + SizedBox(height: 50), // Adjust for spacing + Padding( + padding: + const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + child: Row( + children: [ + CircleAvatar( + radius: 24, + backgroundColor: Colors.grey, + ), + SizedBox(width: 16), + Text( + 'Spending Report', + style: TextStyle( + fontSize: 20, + fontWeight: FontWeight.bold, + color: Colors.white, + ), + ), + Spacer(), + Icon(Icons.notifications, color: Colors.white), + SizedBox(width: 16), + Icon(Icons.more_vert, color: Colors.white), + ], + ), + ), + SizedBox(height: 30), + // Bar Chart Container + Center( + child: Container( + height: 350, + width: 350, + decoration: BoxDecoration( + color: Colors.white.withOpacity(0.8), + borderRadius: BorderRadius.circular(16), + ), + padding: EdgeInsets.all(16), + child: BarChart( + BarChartData( + maxY: 400, + gridData: FlGridData( + show: true, + drawVerticalLine: false, + drawHorizontalLine: true, + ), + borderData: FlBorderData(show: false), + titlesData: FlTitlesData( + leftTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + interval: 100, + reservedSize: 40, + getTitlesWidget: (value, meta) { + return Text( + '\$${value.toInt()}', + style: TextStyle(color: Colors.black), + ); + }, + ), + ), + bottomTitles: AxisTitles( + sideTitles: SideTitles( + showTitles: true, + getTitlesWidget: (value, meta) { + const days = [ + 'M', + 'T', + 'W', + 'Th', + 'F', + 'Sa', + 'Su' + ]; + return Text( + days[value.toInt() % days.length], + style: TextStyle(color: Colors.black), + ); + }, + ), + ), + ), + barGroups: [ + BarChartGroupData( + x: 0, + barRods: [ + BarChartRodData(toY: 250, color: Colors.lightBlue) + ], + ), + BarChartGroupData( + x: 1, + barRods: [ + BarChartRodData(toY: 200, color: Colors.lightBlue) + ], + ), + BarChartGroupData( + x: 2, + barRods: [ + BarChartRodData(toY: 280, color: Colors.lightBlue) + ], + ), + BarChartGroupData( + x: 3, + barRods: [ + BarChartRodData(toY: 220, color: Colors.lightBlue) + ], + ), + BarChartGroupData( + x: 4, + barRods: [ + BarChartRodData(toY: 300, color: Colors.lightBlue) + ], + ), + BarChartGroupData( + x: 5, + barRods: [ + BarChartRodData(toY: 180, color: Colors.lightBlue) + ], + ), + BarChartGroupData( + x: 6, + barRods: [ + BarChartRodData(toY: 350, color: Colors.lightBlue) + ], + ), + ], + ), + ), + ), + ), + SizedBox(height: 20), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _buildCircleWithShadow(Icons.circle, Colors.grey.shade300), + SizedBox(width: 8), + _buildCircleWithShadow(Icons.circle, Colors.grey), + SizedBox(width: 8), + _buildCircleWithShadow(Icons.circle, Colors.grey.shade300), + ], + ), + SizedBox(height: 20), + // Scrollable Content + Expanded( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Container( + decoration: BoxDecoration( + color: Colors.grey.shade300.withOpacity(0.8), + borderRadius: BorderRadius.circular(16), + ), + child: Column( + children: [ + SizedBox(height: 20), + Text( + 'Additional content goes here', + style: TextStyle(fontSize: 16), + ), + SizedBox(height: 300), // Example content height + ], + ), + ), + ), + ), + ), + ], + ), + ], + ), + + ); + } + // Helper to create a circle with shadow + Widget _buildCircleWithShadow(IconData icon, Color color) { + return Container( + decoration: BoxDecoration( + shape: BoxShape.circle, + boxShadow: [ + BoxShadow( + color: Colors.black.withOpacity(0.2), + blurRadius: 6, + spreadRadius: 2, + offset: Offset(0, 3), + ), + ], + ), + child: Icon(icon, size: 12, color: color), + ); + } +} + From 2d62f66ccd93580d6a989813f4e2cbc1e3a21da4 Mon Sep 17 00:00:00 2001 From: ALeBD Date: Fri, 6 Dec 2024 18:41:02 -0800 Subject: [PATCH 04/11] amount and edit label --- lib/screens/budget_page.dart | 177 +++++++++++++++++++++++++-------- lib/screens/spending_page.dart | 4 +- 2 files changed, 137 insertions(+), 44 deletions(-) diff --git a/lib/screens/budget_page.dart b/lib/screens/budget_page.dart index 37771cc..3f0e298 100644 --- a/lib/screens/budget_page.dart +++ b/lib/screens/budget_page.dart @@ -9,10 +9,67 @@ class BudgetPage extends StatefulWidget { class _BudgetPageState extends State { // List to store budget items List budgetItems = [ - BudgetItem(label: 'Taxes', percentage: 65, color: Colors.blue.shade800), - BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300), - BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.lightBlueAccent), + BudgetItem(label: 'Taxes', percentage: 65, color: Colors.blue.shade800, amount: 100), + BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300, amount: 100), + BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.red, amount: 100), ]; + // Method edit + void _showEditBudgetItemDialog(BuildContext context, int index) { + final TextEditingController labelController = + TextEditingController(text: budgetItems[index].label); + final TextEditingController percentageController = + TextEditingController(text: budgetItems[index].percentage.toString()); + + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Edit Budget Item'), + content: Column( + mainAxisSize: MainAxisSize.min, + children: [ + TextField( + controller: labelController, + decoration: InputDecoration(labelText: 'Label'), + ), + TextField( + controller: percentageController, + decoration: InputDecoration(labelText: 'Percentage'), + keyboardType: TextInputType.number, + ), + ], + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(); + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + final label = labelController.text; + final percentage = double.tryParse(percentageController.text) ?? 0; + if (label.isNotEmpty && percentage > 0) { + setState(() { + budgetItems[index] = BudgetItem( + label: label, + percentage: percentage, + color: budgetItems[index].color, + amount: budgetItems[index].amount, + ); + }); + checkTotalPercentage(); + } + Navigator.of(context).pop(); + }, + child: Text('Save'), + ), + ], + ); + }, + ); +} // Method to calculate the total percentage double getTotalPercentage() { @@ -29,7 +86,7 @@ class _BudgetPageState extends State { PieChartSectionData( color: Colors.grey.shade300, value: 1, - radius: 60, + radius: 70, showTitle: false, ), ]; @@ -42,7 +99,7 @@ class _BudgetPageState extends State { color: item.color, value: adjustedPercentage, title: '${adjustedPercentage.toStringAsFixed(1)}%', - radius: 60, + radius: 70, titleStyle: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, @@ -75,7 +132,7 @@ class _BudgetPageState extends State { // Method to add a new budget item void addBudgetItem(String label, double percentage, Color color) { setState(() { - budgetItems.add(BudgetItem(label: label, percentage: percentage, color: color)); + budgetItems.add(BudgetItem(label: label, percentage: percentage, color: color, amount: 100)); }); checkTotalPercentage(); } @@ -177,31 +234,33 @@ class _BudgetPageState extends State { SizedBox(height: 20), // Scrollable Budget Items Expanded( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Column( - children: budgetItems - .asMap() - .entries - .map( - (entry) => Column( - children: [ - BudgetItemCard( - label: entry.value.label, - percentage: '${entry.value.percentage}%', - color: entry.value.color, - onDelete: () => removeBudgetItem(entry.key), - ), - SizedBox(height: 10), - ], - ), - ) - .toList(), - ), + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + children: budgetItems + .asMap() + .entries + .map( + (entry) => Column( + children: [ + BudgetItemCard( + label: entry.value.label, + percentage: '${entry.value.percentage}%', + color: entry.value.color, + amount: entry.value.amount, + onDelete: () => removeBudgetItem(entry.key), + onEdit: () => _showEditBudgetItemDialog(context, entry.key), ), - ), + SizedBox(height: 10), + ], ), + ) + .toList(), + ), + ), + ), +), // Add Budget Item Button Padding( padding: const EdgeInsets.all(16.0), @@ -275,8 +334,8 @@ class _BudgetPageState extends State { boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), - blurRadius: 6, - spreadRadius: 2, + blurRadius: 1, + spreadRadius: 1, offset: Offset(0, 3), ), ], @@ -290,32 +349,66 @@ class BudgetItem { final String label; final double percentage; final Color color; + final double amount; - BudgetItem({required this.label, required this.percentage, required this.color}); + BudgetItem({required this.label, required this.percentage, required this.color, required this.amount}); } // Widget for Budget Item Card class BudgetItemCard extends StatelessWidget { final String label; final String percentage; + final double amount; final Color color; final VoidCallback? onDelete; + final VoidCallback? onEdit; - BudgetItemCard({required this.label, required this.percentage, required this.color, this.onDelete}); + BudgetItemCard({ + required this.label, + required this.percentage, + required this.color, + this.onDelete, + this.onEdit, + required this.amount, + }); @override Widget build(BuildContext context) { - return Card( - color: color.withOpacity(0.8), - child: ListTile( - title: Text(label, style: TextStyle(color: Colors.white)), - subtitle: Text(percentage, style: TextStyle(color: Colors.white70)), - trailing: IconButton( - icon: Icon(Icons.delete, color: Colors.white), - onPressed: onDelete, + return GestureDetector( + onTap: onEdit, // Trigger edit dialog when tapped + child: Card( + color: color.withOpacity(0.8), + child: ListTile( + title: Text( + label, + style: TextStyle(color: Colors.white), + ), + subtitle: Text( + percentage, + style: TextStyle(color: Colors.white70), + ), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Text( + '\$${amount.toStringAsFixed(2)}', // Format the amount + style: TextStyle( + color: Colors.white, + fontSize: 18, // Larger font size + ), + ), + SizedBox(width: 8), // Spacing + IconButton( + icon: Icon(Icons.delete, color: Colors.white), + onPressed: onDelete, + ), + ], + ), ), ), ); } - + } + + diff --git a/lib/screens/spending_page.dart b/lib/screens/spending_page.dart index 2f2d8f9..53e1145 100644 --- a/lib/screens/spending_page.dart +++ b/lib/screens/spending_page.dart @@ -201,8 +201,8 @@ class SpendingReportPage extends StatelessWidget { boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), - blurRadius: 6, - spreadRadius: 2, + blurRadius: 1, + spreadRadius: 1, offset: Offset(0, 3), ), ], From 12c9a871d0b4d417728191c3a525c64570a0bc07 Mon Sep 17 00:00:00 2001 From: ALeBD Date: Sun, 8 Dec 2024 04:57:06 -0800 Subject: [PATCH 05/11] Added Blur to Scroll and Wallet Section / Ability AddMoney --- lib/componets/Account_Card.dart | 69 ++++++++++++----- lib/main.dart | 4 +- lib/screens/budget_page.dart | 66 ++++++++++------ lib/screens/home_page.dart | 132 ++++++++++++++++++++++++++------ 4 files changed, 203 insertions(+), 68 deletions(-) diff --git a/lib/componets/Account_Card.dart b/lib/componets/Account_Card.dart index 234342e..3d3c1b2 100644 --- a/lib/componets/Account_Card.dart +++ b/lib/componets/Account_Card.dart @@ -2,33 +2,66 @@ import 'package:flutter/material.dart'; class AccountCard extends StatelessWidget { final String title; - final String amount; + final double amount; + final VoidCallback? onAddMoney; // Nullable callback - AccountCard({required this.title, required this.amount}); + AccountCard({ + required this.title, + required this.amount, + this.onAddMoney, // Optional parameter + }); @override Widget build(BuildContext context) { return Card( margin: EdgeInsets.symmetric(vertical: 8.0), - color: Colors.white - .withOpacity(0.9), // Slightly transparent to blend with background - child: Padding( - padding: const EdgeInsets.only( + color: Colors.white.withOpacity(0.9), // Slightly transparent + child: Stack( + children: [ + Padding( + padding: const EdgeInsets.only( left: 20, right: 250, bottom: 16.0, top: 16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: TextStyle(fontSize: 18, color: Colors.grey.shade700), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle(fontSize: 18, color: Colors.grey.shade700), + ), + SizedBox(height: 8), + Text( + '\$${amount.toStringAsFixed(2)}', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + ], ), - SizedBox(height: 8), - Text( - amount, - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + ), + // Positioned "Add" button at the top right + if (onAddMoney != null) // Only show button if onAddMoney is provided + Positioned( + top: 8.0, + right: 8.0, + child: IconButton( + icon: Icon( + Icons.add, + color: Colors.black, // Color of the icon + ), + onPressed: onAddMoney, // Callback when pressed + ), ), - ], - ), + if (onAddMoney == null) // Grey out button if onAddMoney is null + Positioned( + top: 8.0, + right: 8.0, + child: IconButton( + icon: Icon( + Icons.add, + color: Colors.grey, // Grey out the icon + ), + onPressed: null, // Disable the button + ), + ), + ], ), ); } diff --git a/lib/main.dart b/lib/main.dart index 536254b..9d484e4 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -22,7 +22,7 @@ class MainApp extends StatelessWidget { brightness: Brightness.light, ), home: HomeScreen(), - /* +/* home: StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), builder: (context, snapshot) { @@ -35,7 +35,7 @@ class MainApp extends StatelessWidget { return const AuthScreen(); }, ), - */ +*/ ); } } diff --git a/lib/screens/budget_page.dart b/lib/screens/budget_page.dart index 3f0e298..8d5a3e7 100644 --- a/lib/screens/budget_page.dart +++ b/lib/screens/budget_page.dart @@ -234,33 +234,49 @@ class _BudgetPageState extends State { SizedBox(height: 20), // Scrollable Budget Items Expanded( - child: SingleChildScrollView( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 16.0), - child: Column( - children: budgetItems - .asMap() - .entries - .map( - (entry) => Column( - children: [ - BudgetItemCard( - label: entry.value.label, - percentage: '${entry.value.percentage}%', - color: entry.value.color, - amount: entry.value.amount, - onDelete: () => removeBudgetItem(entry.key), - onEdit: () => _showEditBudgetItemDialog(context, entry.key), - ), - SizedBox(height: 10), - ], - ), - ) - .toList(), + child: ShaderMask( + shaderCallback: (Rect bounds) { + return LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.transparent, // Top fade + Colors.black, // Fully visible content + Colors.black, // Fully visible content + Colors.transparent, // Bottom fade + ], + stops: [0.0, 0.02, 0.98, 1.0], // Control the fade range + ).createShader(bounds); + }, + blendMode: BlendMode.dstIn, // Blend mode for fading + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 16.0), + child: Column( + children: budgetItems + .asMap() + .entries + .map( + (entry) => Column( + children: [ + BudgetItemCard( + label: entry.value.label, + percentage: '${entry.value.percentage}%', + color: entry.value.color, + amount: entry.value.amount*(entry.value.percentage/100), + onDelete: () => removeBudgetItem(entry.key), + onEdit: () => _showEditBudgetItemDialog(context, entry.key), + ), + SizedBox(height: 10), + ], + ), + ) + .toList(), + ), + ), + ), ), ), - ), -), // Add Budget Item Button Padding( padding: const EdgeInsets.all(16.0), diff --git a/lib/screens/home_page.dart b/lib/screens/home_page.dart index 45c4689..b833edb 100644 --- a/lib/screens/home_page.dart +++ b/lib/screens/home_page.dart @@ -3,7 +3,55 @@ import 'package:fiscus/componets/Account_Card.dart'; import 'package:flutter/material.dart'; -class HomePage extends StatelessWidget { +class HomePage extends StatefulWidget { + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { + // Initialize account balances + double debitBalance = 0.0; + double creditBalance = 0.0; + double savingsBalance = 0.0; + double walletBalance = 0.0; + + // Function to update account balances + void _showAddMoneyDialog(BuildContext context) { + final TextEditingController amountController = TextEditingController(); + + showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Add Money to Wallet'), + content: TextField( + controller: amountController, + keyboardType: TextInputType.number, + decoration: InputDecoration(hintText: 'Enter amount'), + ), + actions: [ + TextButton( + onPressed: () => Navigator.of(context).pop(), // Close dialog + child: Text('Cancel'), + ), + TextButton( + onPressed: () { + final enteredAmount = double.tryParse(amountController.text); + if (enteredAmount != null) { + setState(() { + walletBalance += enteredAmount; // Update balance using setState + }); + } + Navigator.of(context).pop(); // Close dialog + }, + child: Text('Add'), + ), + ], + ); + }, + ); + } + @override Widget build(BuildContext context) { return Scaffold( @@ -23,8 +71,7 @@ class HomePage extends StatelessWidget { children: [ SizedBox(height: 50), // Adjust as needed for spacing Padding( - padding: - const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), + padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), child: Row( children: [ CircleAvatar( @@ -54,33 +101,71 @@ class HomePage extends StatelessWidget { ], ), ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 30.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '[Bank Name]:', + style: TextStyle( + fontSize: 24, + fontWeight: FontWeight.bold, + color: Colors.white), + ), + ], + ), + ), + // Scrollable Area with Edge Fading Expanded( - child: Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.only(right: 175.0), - child: Text( - '[Bank Name]:', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.white), - ), - ), - AccountCard(title: 'Debit', amount: '\$0.00'), - AccountCard(title: 'Credit', amount: '\$0.00'), - AccountCard(title: 'Savings', amount: '\$0.00'), + child: ShaderMask( + shaderCallback: (Rect bounds) { + return LinearGradient( + begin: Alignment.topCenter, + end: Alignment.bottomCenter, + colors: [ + Colors.transparent, // Top fade + Colors.black, // Fully visible content + Colors.black, // Fully visible content + Colors.transparent, // Bottom fade ], + stops: [0.0, 0.01, 0.99, 1.0], // Control the fade range + ).createShader(bounds); + }, + blendMode: BlendMode.dstIn, // Blend mode for fading + child: SingleChildScrollView( + child: Center( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 30.0), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + AccountCard( + title: 'Debit', + amount: debitBalance, + ), + AccountCard( + title: 'Credit', + amount: creditBalance, + ), + AccountCard( + title: 'Savings', + amount: savingsBalance, + ), + AccountCard( + title: 'Wallet', + amount: walletBalance, + onAddMoney: () => _showAddMoneyDialog(context), + ), + ], + ), + ), ), ), ), ), Padding( - padding: const EdgeInsets.only(bottom: 16.0), + padding: const EdgeInsets.symmetric(vertical: 10), child: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ @@ -99,3 +184,4 @@ class HomePage extends StatelessWidget { ); } } + From 20a63b43664b23b138ba695c492f96ffb15a06e2 Mon Sep 17 00:00:00 2001 From: ALeBD Date: Sun, 8 Dec 2024 17:39:50 -0800 Subject: [PATCH 06/11] Home Page Budget progress --- lib/componets/Account_Card.dart | 75 +++++++++++++++------------------ lib/screens/budget_page.dart | 8 ++-- lib/screens/home_page.dart | 37 +++++++++++++++- 3 files changed, 74 insertions(+), 46 deletions(-) diff --git a/lib/componets/Account_Card.dart b/lib/componets/Account_Card.dart index 3d3c1b2..2eafb39 100644 --- a/lib/componets/Account_Card.dart +++ b/lib/componets/Account_Card.dart @@ -3,12 +3,12 @@ import 'package:flutter/material.dart'; class AccountCard extends StatelessWidget { final String title; final double amount; - final VoidCallback? onAddMoney; // Nullable callback + final VoidCallback? onAddMoney; AccountCard({ required this.title, required this.amount, - this.onAddMoney, // Optional parameter + this.onAddMoney, }); @override @@ -16,53 +16,46 @@ class AccountCard extends StatelessWidget { return Card( margin: EdgeInsets.symmetric(vertical: 8.0), color: Colors.white.withOpacity(0.9), // Slightly transparent - child: Stack( + child: Row( children: [ - Padding( - padding: const EdgeInsets.only( - left: 20, right: 250, bottom: 16.0, top: 16.0), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - title, - style: TextStyle(fontSize: 18, color: Colors.grey.shade700), - ), - SizedBox(height: 8), - Text( - '\$${amount.toStringAsFixed(2)}', - style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), - ), - ], + Expanded( + child: Padding( + padding: const EdgeInsets.symmetric(vertical: 16.0, horizontal: 20.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + title, + style: TextStyle(fontSize: 18, color: Colors.grey.shade700), + ), + SizedBox(height: 8), + Text( + '\$${amount.toStringAsFixed(2)}', + style: TextStyle(fontSize: 24, fontWeight: FontWeight.bold), + overflow: TextOverflow.ellipsis, // Prevent overflow issues + ), + ], + ), ), ), - // Positioned "Add" button at the top right if (onAddMoney != null) // Only show button if onAddMoney is provided - Positioned( - top: 8.0, - right: 8.0, - child: IconButton( - icon: Icon( - Icons.add, - color: Colors.black, // Color of the icon - ), - onPressed: onAddMoney, // Callback when pressed + IconButton( + icon: Icon( + Icons.add, + color: Colors.black, // Color of the icon ), - ), - if (onAddMoney == null) // Grey out button if onAddMoney is null - Positioned( - top: 8.0, - right: 8.0, - child: IconButton( - icon: Icon( - Icons.add, - color: Colors.grey, // Grey out the icon - ), - onPressed: null, // Disable the button + onPressed: onAddMoney, // Callback when pressed + ) + else + IconButton( + icon: Icon( + Icons.add, + color: Colors.grey, // Grey out the icon ), + onPressed: null, // Disable the button ), ], ), ); } -} +} \ No newline at end of file diff --git a/lib/screens/budget_page.dart b/lib/screens/budget_page.dart index 8d5a3e7..9dea220 100644 --- a/lib/screens/budget_page.dart +++ b/lib/screens/budget_page.dart @@ -9,9 +9,9 @@ class BudgetPage extends StatefulWidget { class _BudgetPageState extends State { // List to store budget items List budgetItems = [ - BudgetItem(label: 'Taxes', percentage: 65, color: Colors.blue.shade800, amount: 100), - BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300, amount: 100), - BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.red, amount: 100), + BudgetItem(label: 'Taxes', percentage: 65, color: Colors.blue.shade800, amount: 10000), + BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300, amount: 10000), + BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.red, amount: 10000), ]; // Method edit void _showEditBudgetItemDialog(BuildContext context, int index) { @@ -132,7 +132,7 @@ class _BudgetPageState extends State { // Method to add a new budget item void addBudgetItem(String label, double percentage, Color color) { setState(() { - budgetItems.add(BudgetItem(label: label, percentage: percentage, color: color, amount: 100)); + budgetItems.add(BudgetItem(label: label, percentage: percentage, color: color, amount: 10000)); }); checkTotalPercentage(); } diff --git a/lib/screens/home_page.dart b/lib/screens/home_page.dart index b833edb..c470a33 100644 --- a/lib/screens/home_page.dart +++ b/lib/screens/home_page.dart @@ -10,11 +10,15 @@ class HomePage extends StatefulWidget { class _HomePageState extends State { // Initialize account balances - double debitBalance = 0.0; + double debitBalance = 14000.0; double creditBalance = 0.0; double savingsBalance = 0.0; double walletBalance = 0.0; + double balance = 14000.0; + void totalBalanceCal(BuildContext context){ + balance = debitBalance + walletBalance; + } // Function to update account balances void _showAddMoneyDialog(BuildContext context) { final TextEditingController amountController = TextEditingController(); @@ -41,6 +45,7 @@ class _HomePageState extends State { setState(() { walletBalance += enteredAmount; // Update balance using setState }); + totalBalanceCal(context); } Navigator.of(context).pop(); // Close dialog }, @@ -101,6 +106,36 @@ class _HomePageState extends State { ], ), ), + Padding( + padding: const EdgeInsets.symmetric(horizontal: 30.0), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Stack( + children: [ + // Shadow text + Text( + 'Total Balance: \$${balance.toStringAsFixed(2)}', + style: TextStyle( + fontSize: 23.2, + + color: Colors.black.withOpacity(0.5), // Shadow color + ), + ), + // Foreground text + Text( + 'Total Balance: \$${balance.toStringAsFixed(2)}', + style: TextStyle( + fontSize: 23, + + color: Colors.white, + ), + ), + ], + ), + ], + ), + ), Padding( padding: const EdgeInsets.symmetric(horizontal: 30.0), child: Row( From 5f4d16e2dbd11cf5764960f43586a9ec779865c0 Mon Sep 17 00:00:00 2001 From: ALeBD Date: Sun, 8 Dec 2024 19:57:38 -0800 Subject: [PATCH 07/11] Periodical Budget functionality --- lib/screens/budget_page.dart | 110 ++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 21 deletions(-) diff --git a/lib/screens/budget_page.dart b/lib/screens/budget_page.dart index 9dea220..bfc0785 100644 --- a/lib/screens/budget_page.dart +++ b/lib/screens/budget_page.dart @@ -1,6 +1,9 @@ import 'package:flutter/material.dart'; import 'package:fl_chart/fl_chart.dart'; +import 'package:flutter/src/rendering/box.dart'; +double balance = 14000; +double currAmount = 14000; class BudgetPage extends StatefulWidget { @override _BudgetPageState createState() => _BudgetPageState(); @@ -9,10 +12,40 @@ class BudgetPage extends StatefulWidget { class _BudgetPageState extends State { // List to store budget items List budgetItems = [ - BudgetItem(label: 'Taxes', percentage: 65, color: Colors.blue.shade800, amount: 10000), - BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300, amount: 10000), - BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.red, amount: 10000), + BudgetItem(label: 'Taxes', percentage: 65, color: Colors.blue.shade800, amount: 9100), + BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300, amount: 2800), + BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.red, amount: 2100), ]; + int selectedPeriod = 0; // 0: Year, 1: Week, 2: Month, 3: Day + + // Function to update the amount for all budget items + void updateAmountsForAll(int periodic) { + setState(() { + if(periodic == 0) { + for (var item in budgetItems) { + item.amount = balance * (item.percentage / 100); + currAmount = balance; + } + }else if (periodic == 1) { + for (var item in budgetItems) { + item.amount = (balance/12) * (item.percentage / 100); + currAmount = balance/12; + } + }else if (periodic == 2) { + for (var item in budgetItems) { + item.amount = (balance/52) * (item.percentage / 100); + currAmount = balance/52; + } + }else { + for (var item in budgetItems) { + item.amount = (balance/365) * (item.percentage / 100); + currAmount = balance/365; + } + } + }); +} + + // Method edit void _showEditBudgetItemDialog(BuildContext context, int index) { final TextEditingController labelController = @@ -132,7 +165,7 @@ class _BudgetPageState extends State { // Method to add a new budget item void addBudgetItem(String label, double percentage, Color color) { setState(() { - budgetItems.add(BudgetItem(label: label, percentage: percentage, color: color, amount: 10000)); + budgetItems.add(BudgetItem(label: label, percentage: percentage, color: color, amount: currAmount*(percentage/100))); }); checkTotalPercentage(); } @@ -142,7 +175,6 @@ class _BudgetPageState extends State { setState(() { budgetItems.removeAt(index); }); - checkTotalPercentage(); } // Warn if total percentage exceeds 100% @@ -220,18 +252,54 @@ class _BudgetPageState extends State { ), ), ), - SizedBox(height: 20), - Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - _buildCircleWithShadow(Icons.circle, Colors.grey), - SizedBox(width: 8), - _buildCircleWithShadow(Icons.circle, Colors.grey.shade300), - SizedBox(width: 8), - _buildCircleWithShadow(Icons.circle, Colors.grey.shade300), - ], + SizedBox(height: 10), + // Dropdown menu for selecting time period (Day, Month, Week, Year) + // Row with Dropdown and Current Amount + Padding( + padding: const EdgeInsets.symmetric(horizontal: 20.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + // Current Amount Display + Text( + 'Budget: \$${currAmount.toStringAsFixed(2)}', + style: TextStyle(color: const Color.fromARGB(255, 0, 0, 0), fontSize: 16), + ), + // Dropdown menu for selecting time period (Day, Month, Week, Year) + DropdownButton( + value: selectedPeriod, + + dropdownColor: Colors.white, + borderRadius: BorderRadius.circular(15), + items: [ + DropdownMenuItem( + value: 0, + child: Text('Year'), + ), + DropdownMenuItem( + value: 1, + child: Text('Month'), + ), + DropdownMenuItem( + value: 2, + child: Text('Week'), + ), + DropdownMenuItem( + value: 3, + child: Text('Day'), + ), + ], + onChanged: (value) { + setState(() { + selectedPeriod = value!; + updateAmountsForAll(selectedPeriod); + }); + }, + ), + ], + ), ), - SizedBox(height: 20), + SizedBox(height: 10), // Scrollable Budget Items Expanded( child: ShaderMask( @@ -263,11 +331,11 @@ class _BudgetPageState extends State { label: entry.value.label, percentage: '${entry.value.percentage}%', color: entry.value.color, - amount: entry.value.amount*(entry.value.percentage/100), + amount: entry.value.amount, onDelete: () => removeBudgetItem(entry.key), onEdit: () => _showEditBudgetItemDialog(context, entry.key), ), - SizedBox(height: 10), + SizedBox(height: 5), ], ), ) @@ -279,7 +347,7 @@ class _BudgetPageState extends State { ), // Add Budget Item Button Padding( - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.all(10.0), child: ElevatedButton( onPressed: () { _showAddBudgetItemDialog(context); @@ -365,7 +433,7 @@ class BudgetItem { final String label; final double percentage; final Color color; - final double amount; + double amount; BudgetItem({required this.label, required this.percentage, required this.color, required this.amount}); } @@ -374,7 +442,7 @@ class BudgetItem { class BudgetItemCard extends StatelessWidget { final String label; final String percentage; - final double amount; + double amount; final Color color; final VoidCallback? onDelete; final VoidCallback? onEdit; From f06c77621994289d160d82b8fcd597b44fcb9b11 Mon Sep 17 00:00:00 2001 From: ALeBD Date: Sun, 8 Dec 2024 20:00:02 -0800 Subject: [PATCH 08/11] cleanup --- lib/screens/budget_screen.dart | 11 ----------- lib/screens/charts_screen.dart | 11 ----------- lib/screens/dashboard_screen.dart | 11 ----------- lib/screens/profile_screen.dart | 11 ----------- 4 files changed, 44 deletions(-) delete mode 100644 lib/screens/budget_screen.dart delete mode 100644 lib/screens/charts_screen.dart delete mode 100644 lib/screens/dashboard_screen.dart delete mode 100644 lib/screens/profile_screen.dart diff --git a/lib/screens/budget_screen.dart b/lib/screens/budget_screen.dart deleted file mode 100644 index 24ad0aa..0000000 --- a/lib/screens/budget_screen.dart +++ /dev/null @@ -1,11 +0,0 @@ - -import 'package:flutter/material.dart'; - -class BudgetScreen extends StatelessWidget { - const BudgetScreen({super.key}); - - @override - Widget build(BuildContext context) { - return const Center(child: Text('Budget')); - } -} \ No newline at end of file diff --git a/lib/screens/charts_screen.dart b/lib/screens/charts_screen.dart deleted file mode 100644 index a4da46d..0000000 --- a/lib/screens/charts_screen.dart +++ /dev/null @@ -1,11 +0,0 @@ - -import 'package:flutter/material.dart'; - -class ChartsScreen extends StatelessWidget { - const ChartsScreen({super.key}); - - @override - Widget build(BuildContext context) { - return const Center(child: Text('Charts')); - } -} \ No newline at end of file diff --git a/lib/screens/dashboard_screen.dart b/lib/screens/dashboard_screen.dart deleted file mode 100644 index 7d02d38..0000000 --- a/lib/screens/dashboard_screen.dart +++ /dev/null @@ -1,11 +0,0 @@ - -import 'package:flutter/material.dart'; - -class DashboardScreen extends StatelessWidget { - const DashboardScreen({super.key}); - - @override - Widget build(BuildContext context) { - return const Center(child: Text('Dashboard')); - } -} \ No newline at end of file diff --git a/lib/screens/profile_screen.dart b/lib/screens/profile_screen.dart deleted file mode 100644 index 3da8dcd..0000000 --- a/lib/screens/profile_screen.dart +++ /dev/null @@ -1,11 +0,0 @@ - -import 'package:flutter/material.dart'; - -class ProfileScreen extends StatelessWidget { - const ProfileScreen({super.key}); - - @override - Widget build(BuildContext context) { - return const Center(child: Text('Profile')); - } -} \ No newline at end of file From 1bcd348387ccea8f1a3e1525c7e41d9637b8317f Mon Sep 17 00:00:00 2001 From: ALeBD Date: Sun, 8 Dec 2024 21:27:53 -0800 Subject: [PATCH 09/11] Custom Budget implemented --- lib/screens/budget_page.dart | 100 ++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 18 deletions(-) diff --git a/lib/screens/budget_page.dart b/lib/screens/budget_page.dart index bfc0785..a1427c4 100644 --- a/lib/screens/budget_page.dart +++ b/lib/screens/budget_page.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:fl_chart/fl_chart.dart'; -import 'package:flutter/src/rendering/box.dart'; double balance = 14000; double currAmount = 14000; @@ -16,33 +15,94 @@ class _BudgetPageState extends State { BudgetItem(label: 'Food', percentage: 20, color: Colors.lightBlue.shade300, amount: 2800), BudgetItem(label: 'Entertainment', percentage: 15, color: Colors.red, amount: 2100), ]; + + Future setCurrentAmount(BuildContext context) async { + final TextEditingController budgetController = TextEditingController(); + + final result = await showDialog( + context: context, + builder: (context) { + return AlertDialog( + title: Text('Custom Budget'), + content: TextField( + controller: budgetController, + decoration: InputDecoration(labelText: 'Amount'), + keyboardType: TextInputType.number, + ), + actions: [ + TextButton( + onPressed: () { + Navigator.of(context).pop(null); // Return null if canceled + }, + child: Text('Cancel'), + ), + ElevatedButton( + onPressed: () { + final budget = double.tryParse(budgetController.text) ?? 0; + Navigator.of(context).pop(budget); // Return the entered value + }, + child: Text('Confirm'), + ), + ], + ); + }, + ); + + // Ensure a non-null value is always returned + return result ?? 0.0; +} + int selectedPeriod = 0; // 0: Year, 1: Week, 2: Month, 3: Day - // Function to update the amount for all budget items - void updateAmountsForAll(int periodic) { +void update() { setState(() { - if(periodic == 0) { + currAmount = currAmount + 1; + currAmount = currAmount - 1; + }); +} + + // Function to update the amount for all budget items +Future updateAmountsForAll(int periodic) async { + if (periodic == 0) { + setState(() { + currAmount = balance; for (var item in budgetItems) { - item.amount = balance * (item.percentage / 100); - currAmount = balance; + item.amount = currAmount * (item.percentage / 100); } - }else if (periodic == 1) { + }); + } else if (periodic == 1) { + setState(() { + currAmount = balance / 12; for (var item in budgetItems) { - item.amount = (balance/12) * (item.percentage / 100); - currAmount = balance/12; + item.amount = currAmount * (item.percentage / 100); } - }else if (periodic == 2) { + }); + } else if (periodic == 2) { + setState(() { + currAmount = balance / 52; for (var item in budgetItems) { - item.amount = (balance/52) * (item.percentage / 100); - currAmount = balance/52; + item.amount = currAmount * (item.percentage / 100); } - }else { + }); + } else if (periodic == 3) { + setState(() { + currAmount = balance / 365; for (var item in budgetItems) { - item.amount = (balance/365) * (item.percentage / 100); - currAmount = balance/365; + item.amount = currAmount * (item.percentage / 100); } + }); + } else if (periodic == 4) { + // Custom budget logic + final budget = await setCurrentAmount(context); // Wait for dialog result + if (budget > 0) { + setState(() { + currAmount = budget; + for (var item in budgetItems) { + item.amount = currAmount * (item.percentage / 100); + } + }); } - }); + } } @@ -89,9 +149,10 @@ class _BudgetPageState extends State { label: label, percentage: percentage, color: budgetItems[index].color, - amount: budgetItems[index].amount, + amount: currAmount * (percentage/100), ); }); + //update(); checkTotalPercentage(); } Navigator.of(context).pop(); @@ -288,6 +349,10 @@ class _BudgetPageState extends State { value: 3, child: Text('Day'), ), + DropdownMenuItem( + value: 4, + child: Text('Custom Budget'), + ), ], onChanged: (value) { setState(() { @@ -492,7 +557,6 @@ class BudgetItemCard extends StatelessWidget { ), ); } - } From e6eaf3da938f59ec460a744c7f37df7797550a52 Mon Sep 17 00:00:00 2001 From: unknown Date: Mon, 9 Dec 2024 16:28:58 -0800 Subject: [PATCH 10/11] Updated main.dart, modified build files, added firebase support, and removed auth_screen --- android/app/build.gradle | 3 + android/app/google-services.json | 29 ++ android/settings.gradle | 3 + firebase.json | 1 + lib/firebase_options.dart | 86 +++++ lib/main.dart | 67 ++-- lib/screens/auth_screen.dart | 33 -- lib/screens/camera_page.dart | 78 ++++- lib/screens/home_page.dart | 88 +++-- lib/screens/login_page.dart | 312 +++++++++++++----- lib/screens/signup_page.dart | 127 +++++++ macos/Flutter/GeneratedPluginRegistrant.swift | 4 + pubspec.lock | 218 +++++++++++- pubspec.yaml | 11 +- .../flutter/generated_plugin_registrant.cc | 3 + windows/flutter/generated_plugins.cmake | 1 + 16 files changed, 859 insertions(+), 205 deletions(-) create mode 100644 android/app/google-services.json create mode 100644 firebase.json create mode 100644 lib/firebase_options.dart delete mode 100644 lib/screens/auth_screen.dart create mode 100644 lib/screens/signup_page.dart diff --git a/android/app/build.gradle b/android/app/build.gradle index 7951124..1404d30 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,5 +1,8 @@ plugins { id "com.android.application" + // START: FlutterFire Configuration + id 'com.google.gms.google-services' + // END: FlutterFire Configuration id "kotlin-android" // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. id "dev.flutter.flutter-gradle-plugin" diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 0000000..68c93d5 --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,29 @@ +{ + "project_info": { + "project_number": "1054264689837", + "project_id": "fiscus-fa2ab", + "storage_bucket": "fiscus-fa2ab.firebasestorage.app" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1054264689837:android:f6ac64bc93a8f266503224", + "android_client_info": { + "package_name": "com.example.fiscus" + } + }, + "oauth_client": [], + "api_key": [ + { + "current_key": "AIzaSyCPegnFSkjByLr3Dd7ww1XGssveLeV5wMs" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/settings.gradle b/android/settings.gradle index b9e43bd..9759a22 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -19,6 +19,9 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "com.android.application" version "8.1.0" apply false + // START: FlutterFire Configuration + id "com.google.gms.google-services" version "4.3.15" apply false + // END: FlutterFire Configuration id "org.jetbrains.kotlin.android" version "1.8.22" apply false } diff --git a/firebase.json b/firebase.json new file mode 100644 index 0000000..0fa10f5 --- /dev/null +++ b/firebase.json @@ -0,0 +1 @@ +{"flutter":{"platforms":{"android":{"default":{"projectId":"fiscus-fa2ab","appId":"1:1054264689837:android:f6ac64bc93a8f266503224","fileOutput":"android/app/google-services.json"}},"dart":{"lib/firebase_options.dart":{"projectId":"fiscus-fa2ab","configurations":{"android":"1:1054264689837:android:f6ac64bc93a8f266503224","ios":"1:1054264689837:ios:336b2dceab0181ae503224","macos":"1:1054264689837:ios:336b2dceab0181ae503224","web":"1:1054264689837:web:7dd99b49fab8870c503224","windows":"1:1054264689837:web:5571e664c9dc6e01503224"}}}}}} \ No newline at end of file diff --git a/lib/firebase_options.dart b/lib/firebase_options.dart new file mode 100644 index 0000000..e636810 --- /dev/null +++ b/lib/firebase_options.dart @@ -0,0 +1,86 @@ +// File generated by FlutterFire CLI. +// ignore_for_file: type=lint +import 'package:firebase_core/firebase_core.dart' show FirebaseOptions; +import 'package:flutter/foundation.dart' + show defaultTargetPlatform, kIsWeb, TargetPlatform; + +/// Default [FirebaseOptions] for use with your Firebase apps. +/// +/// Example: +/// ```dart +/// import 'firebase_options.dart'; +/// // ... +/// await Firebase.initializeApp( +/// options: DefaultFirebaseOptions.currentPlatform, +/// ); +/// ``` +class DefaultFirebaseOptions { + static FirebaseOptions get currentPlatform { + if (kIsWeb) { + return web; + } + switch (defaultTargetPlatform) { + case TargetPlatform.android: + return android; + case TargetPlatform.iOS: + return ios; + case TargetPlatform.macOS: + return macos; + case TargetPlatform.windows: + return windows; + case TargetPlatform.linux: + throw UnsupportedError( + 'DefaultFirebaseOptions have not been configured for linux - ' + 'you can reconfigure this by running the FlutterFire CLI again.', + ); + default: + throw UnsupportedError( + 'DefaultFirebaseOptions are not supported for this platform.', + ); + } + } + + static const FirebaseOptions web = FirebaseOptions( + apiKey: 'AIzaSyDaO0-5DaCwK4U9pEIp2F7E9h6PLK1r_NU', + appId: '1:1054264689837:web:7dd99b49fab8870c503224', + messagingSenderId: '1054264689837', + projectId: 'fiscus-fa2ab', + authDomain: 'fiscus-fa2ab.firebaseapp.com', + storageBucket: 'fiscus-fa2ab.firebasestorage.app', + ); + + static const FirebaseOptions android = FirebaseOptions( + apiKey: 'AIzaSyCPegnFSkjByLr3Dd7ww1XGssveLeV5wMs', + appId: '1:1054264689837:android:f6ac64bc93a8f266503224', + messagingSenderId: '1054264689837', + projectId: 'fiscus-fa2ab', + storageBucket: 'fiscus-fa2ab.firebasestorage.app', + ); + + static const FirebaseOptions ios = FirebaseOptions( + apiKey: 'AIzaSyBRHW3G_1atFY-toQA3tODyrOfzTZ4xjkM', + appId: '1:1054264689837:ios:336b2dceab0181ae503224', + messagingSenderId: '1054264689837', + projectId: 'fiscus-fa2ab', + storageBucket: 'fiscus-fa2ab.firebasestorage.app', + iosBundleId: 'com.example.fiscus', + ); + + static const FirebaseOptions macos = FirebaseOptions( + apiKey: 'AIzaSyBRHW3G_1atFY-toQA3tODyrOfzTZ4xjkM', + appId: '1:1054264689837:ios:336b2dceab0181ae503224', + messagingSenderId: '1054264689837', + projectId: 'fiscus-fa2ab', + storageBucket: 'fiscus-fa2ab.firebasestorage.app', + iosBundleId: 'com.example.fiscus', + ); + + static const FirebaseOptions windows = FirebaseOptions( + apiKey: 'AIzaSyDaO0-5DaCwK4U9pEIp2F7E9h6PLK1r_NU', + appId: '1:1054264689837:web:5571e664c9dc6e01503224', + messagingSenderId: '1054264689837', + projectId: 'fiscus-fa2ab', + authDomain: 'fiscus-fa2ab.firebaseapp.com', + storageBucket: 'fiscus-fa2ab.firebasestorage.app', + ); +} diff --git a/lib/main.dart b/lib/main.dart index 536254b..a826ea0 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,12 +1,17 @@ +import 'package:fiscus/screens/home_page.dart'; +import 'package:fiscus/screens/login_page.dart'; import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_auth/firebase_auth.dart'; -import 'screens/auth_screen.dart'; -import 'screens/home_screen.dart'; +import 'screens/signup_page.dart'; void main() async { - //WidgetsFlutterBinding.ensureInitialized(); - //await Firebase.initializeApp(); + WidgetsFlutterBinding.ensureInitialized(); + await Firebase.initializeApp(); + + // FOR TESTING: Force sign out any currently logged-in user + await FirebaseAuth.instance.signOut(); + runApp(const MainApp()); } @@ -20,22 +25,46 @@ class MainApp extends StatelessWidget { theme: ThemeData( primarySwatch: Colors.blue, brightness: Brightness.light, + scaffoldBackgroundColor: Colors.white, + visualDensity: VisualDensity.adaptivePlatformDensity, ), - home: HomeScreen(), - /* - home: StreamBuilder( - stream: FirebaseAuth.instance.authStateChanges(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return const CircularProgressIndicator(); - } - if (snapshot.hasData) { - return const HomeScreen(); - } - return const AuthScreen(); - }, - ), - */ + home: const AuthWrapper(), + routes: { + '/signup': (context) => SignUpPage(), + }, + ); + } +} + +class AuthWrapper extends StatelessWidget { + const AuthWrapper({super.key}); + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: FirebaseAuth.instance.authStateChanges(), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Scaffold( + body: Center( + child: CircularProgressIndicator( + color: Colors.blue, + ), + ), + ); + } + + // If the user is logged in, show HomePage + if (snapshot.hasData && snapshot.data != null) { + print('User is logged in: ${snapshot.data!.email}'); + return HomePage(); + } + // Otherwise, show LoginPage + else { + print('User is not logged in'); + return LoginPage(); + } + }, ); } } diff --git a/lib/screens/auth_screen.dart b/lib/screens/auth_screen.dart deleted file mode 100644 index 4cb957e..0000000 --- a/lib/screens/auth_screen.dart +++ /dev/null @@ -1,33 +0,0 @@ - -import 'package:flutter/material.dart'; - -class AuthScreen extends StatefulWidget { - const AuthScreen({super.key}); - - @override - State createState() => _AuthScreenState(); -} - -class _AuthScreenState extends State { - bool isLogin = true; - - @override - Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text(isLogin ? 'Login' : 'Sign Up'), - ), - body: Center( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - ElevatedButton( - onPressed: () => setState(() => isLogin = !isLogin), - child: Text(isLogin ? 'Need an account? Sign up' : 'Have an account? Login'), - ), - ], - ), - ), - ); - } -} \ No newline at end of file diff --git a/lib/screens/camera_page.dart b/lib/screens/camera_page.dart index 779151a..2d47335 100644 --- a/lib/screens/camera_page.dart +++ b/lib/screens/camera_page.dart @@ -1,15 +1,85 @@ import 'package:flutter/material.dart'; +import 'package:camera/camera.dart'; + +class CameraPage extends StatefulWidget { + @override + _CameraPageState createState() => _CameraPageState(); +} + +class _CameraPageState extends State { + late List cameras; + CameraController? controller; + bool isCameraInitialized = false; + + @override + void initState() { + super.initState(); + initializeCamera(); + } + + Future initializeCamera() async { + try { + // Retrieve available cameras + cameras = await availableCameras(); + // Initialize the first camera (back camera) + controller = CameraController( + cameras.first, + ResolutionPreset.high, + ); + await controller?.initialize(); + setState(() { + isCameraInitialized = true; + }); + } catch (e) { + print("Error initializing camera: $e"); + } + } + + @override + void dispose() { + controller?.dispose(); + super.dispose(); + } + + Future captureImage() async { + if (!controller!.value.isInitialized) { + return; + } + try { + final image = await controller?.takePicture(); + if (image != null) { + // Process the captured image (e.g., send it to an OCR library) + print('Image saved to: ${image.path}'); + // Add receipt-reading logic here + } + } catch (e) { + print("Error capturing image: $e"); + } + } -class CameraPage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Camera Page'), ), - body: Center( - child: Text('This is the camera page'), - ), + body: isCameraInitialized + ? Stack( + children: [ + CameraPreview(controller!), + Align( + alignment: Alignment.bottomCenter, + child: Padding( + padding: const EdgeInsets.all(16.0), + child: ElevatedButton( + onPressed: captureImage, + child: Text('Capture Receipt'), + ), + ), + ), + ], + ) + : Center(child: CircularProgressIndicator()), ); } } diff --git a/lib/screens/home_page.dart b/lib/screens/home_page.dart index 45c4689..5d07d52 100644 --- a/lib/screens/home_page.dart +++ b/lib/screens/home_page.dart @@ -1,15 +1,39 @@ -// ignore_for_file: prefer_const_constructors, prefer_const_literals_to_create_immutables - -import 'package:fiscus/componets/Account_Card.dart'; import 'package:flutter/material.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:fiscus/componets/Account_Card.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class HomePage extends StatefulWidget { + @override + _HomePageState createState() => _HomePageState(); +} + +class _HomePageState extends State { + String _userName = 'Loading...'; + + @override + void initState() { + super.initState(); + _getUserName(); + } + + Future _getUserName() async { + try { + SharedPreferences prefs = await SharedPreferences.getInstance(); + setState(() { + _userName = prefs.getString('first_name') ?? 'User'; + }); + } catch (e) { + print('Error fetching user name: $e'); + } + } -class HomePage extends StatelessWidget { @override Widget build(BuildContext context) { return Scaffold( body: Stack( children: [ - // Background Image Container( decoration: BoxDecoration( image: DecorationImage( @@ -18,10 +42,9 @@ class HomePage extends StatelessWidget { ), ), ), - // Overlay Content Column( children: [ - SizedBox(height: 50), // Adjust as needed for spacing + SizedBox(height: 50), Padding( padding: const EdgeInsets.symmetric(horizontal: 16.0, vertical: 8.0), @@ -37,17 +60,11 @@ class HomePage extends StatelessWidget { children: [ Text( 'Welcome,', - style: TextStyle( - fontSize: 30, - fontWeight: FontWeight.bold, - color: Colors.white), + style: TextStyle(fontSize: 30, color: Colors.white), ), Text( - '[Name]', - style: TextStyle( - fontSize: 30, - fontWeight: FontWeight.bold, - color: Colors.white), + _userName, + style: TextStyle(fontSize: 30, color: Colors.white), ), ], ), @@ -56,42 +73,15 @@ class HomePage extends StatelessWidget { ), Expanded( child: Center( - child: Padding( - padding: const EdgeInsets.symmetric(horizontal: 30.0), - child: Column( - mainAxisSize: MainAxisSize.min, - children: [ - Padding( - padding: const EdgeInsets.only(right: 175.0), - child: Text( - '[Bank Name]:', - style: TextStyle( - fontSize: 24, - fontWeight: FontWeight.bold, - color: Colors.white), - ), - ), - AccountCard(title: 'Debit', amount: '\$0.00'), - AccountCard(title: 'Credit', amount: '\$0.00'), - AccountCard(title: 'Savings', amount: '\$0.00'), - ], - ), + child: Column( + children: [ + AccountCard(title: 'Debit', amount: '\$0.00'), + AccountCard(title: 'Credit', amount: '\$0.00'), + AccountCard(title: 'Savings', amount: '\$0.00'), + ], ), ), ), - Padding( - padding: const EdgeInsets.only(bottom: 16.0), - child: Row( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Icon(Icons.circle, size: 20, color: Colors.grey), - SizedBox(width: 8), - Icon(Icons.circle, size: 16, color: Colors.grey.shade300), - SizedBox(width: 8), - Icon(Icons.circle, size: 16, color: Colors.grey.shade300), - ], - ), - ), ], ), ], diff --git a/lib/screens/login_page.dart b/lib/screens/login_page.dart index beefcef..c331357 100644 --- a/lib/screens/login_page.dart +++ b/lib/screens/login_page.dart @@ -1,104 +1,242 @@ -// ignore_for_file: prefer_const_constructors - +import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; -class LoginPage extends StatelessWidget { +class LoginPage extends StatefulWidget { + @override + _LoginPageState createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + final _emailController = TextEditingController(); + final _passwordController = TextEditingController(); + bool _isLoading = false; + + Future _loginUser() async { + if (_emailController.text.isEmpty || _passwordController.text.isEmpty) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Please fill in both email and password.')), + ); + return; + } + + setState(() { + _isLoading = true; + }); + + try { + UserCredential userCredential = + await FirebaseAuth.instance.signInWithEmailAndPassword( + email: _emailController.text.trim(), + password: _passwordController.text.trim(), + ); + if (mounted) { + Navigator.pushReplacementNamed(context, '/home'); + } + } on FirebaseAuthException catch (e) { + String errorMessage = 'An unknown error occurred'; + if (e.code == 'user-not-found') { + errorMessage = 'No user found with that email.'; + } else if (e.code == 'wrong-password') { + errorMessage = 'Incorrect password.'; + } else if (e.code == 'network-request-failed') { + errorMessage = 'No internet connection.'; + } else if (e.code == 'too-many-requests') { + errorMessage = 'Too many requests. Please try again later.'; + } else if (e.code == 'invalid-email') { + errorMessage = 'Invalid email address.'; + } + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text(errorMessage)), + ); + } + } catch (e) { + if (mounted) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Error: ${e.toString()}')), + ); + } + } finally { + if (mounted) { + setState(() { + _isLoading = false; + }); + } + } + } + @override Widget build(BuildContext context) { return Scaffold( - body: Container( - decoration: BoxDecoration( - image: DecorationImage( - image: AssetImage("lib/assets/Login-Setup – 1.png"), - fit: BoxFit.cover, + body: Stack( + children: [ + // Background Image + Container( + decoration: const BoxDecoration( + image: DecorationImage( + image: AssetImage( + 'lib/assets/Login-Setup.png'), // Background image path + fit: BoxFit.cover, + ), + ), + ), + Container( + decoration: BoxDecoration( + color: const Color.fromARGB(255, 0, 0, 0) + .withOpacity(0.1), // Darken the background slightly + ), ), - ), - child: Center( - child: Padding( - padding: const EdgeInsets.all(16.0), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Align( - alignment: Alignment.centerLeft, - child: Text( - 'Login', - style: TextStyle( - fontSize: 32, - fontWeight: FontWeight.bold, - color: Colors.white, + Center( + child: SingleChildScrollView( + child: Padding( + padding: const EdgeInsets.symmetric(horizontal: 30.0), + child: Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + // Welcome Text + Text( + 'Welcome Back!', + style: TextStyle( + color: Colors.white, + fontSize: 32, + fontWeight: FontWeight.bold, + ), ), - ), - ), - SizedBox(height: 20), - TextField( - style: TextStyle(color: Colors.white), - decoration: InputDecoration( - border: OutlineInputBorder(), - labelText: 'Username', - labelStyle: TextStyle(color: Colors.white), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.white), + SizedBox(height: 10), + Text( + 'Please login to your account', + style: TextStyle( + color: Colors.white.withOpacity(0.9), + fontSize: 16, + ), + ), + SizedBox(height: 30), + + // Email Input + TextField( + controller: _emailController, + style: TextStyle(color: Colors.white), + decoration: InputDecoration( + filled: true, + fillColor: Colors.white.withOpacity(0.2), + hintText: 'Email', + hintStyle: TextStyle(color: Colors.white70), + contentPadding: + EdgeInsets.symmetric(vertical: 18, horizontal: 20), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide.none, + ), + ), ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.white), + SizedBox(height: 20), + + // Password Input + TextField( + controller: _passwordController, + obscureText: true, + style: TextStyle(color: Colors.white), + decoration: InputDecoration( + filled: true, + fillColor: Colors.white.withOpacity(0.2), + hintText: 'Password', + hintStyle: TextStyle(color: Colors.white70), + contentPadding: + EdgeInsets.symmetric(vertical: 18, horizontal: 20), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(30.0), + borderSide: BorderSide.none, + ), + ), ), - ), - ), - SizedBox(height: 20), - TextField( - obscureText: true, - style: TextStyle(color: Colors.white), - decoration: InputDecoration( - border: OutlineInputBorder(), - labelText: 'Password', - labelStyle: TextStyle(color: Colors.white), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.white), + + SizedBox(height: 10), + + // Forgot Password Button + Align( + alignment: Alignment.centerRight, + child: TextButton( + onPressed: () { + // Handle forgot password logic + }, + child: Text( + 'Forgot Password?', + style: TextStyle( + color: Colors.white, + fontSize: 14, + ), + ), + ), + ), + + SizedBox(height: 30), + + // Login Button + _isLoading + ? CircularProgressIndicator(color: Colors.white) + : ElevatedButton( + onPressed: _loginUser, + style: ElevatedButton.styleFrom( + backgroundColor: Colors.blueAccent, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30.0), + ), + padding: EdgeInsets.symmetric(vertical: 20), + textStyle: TextStyle(fontSize: 18), + ), + child: Text('Login', + style: TextStyle(color: Colors.white)), + ), + + SizedBox(height: 20), + + // OR Divider + Row( + children: [ + Expanded( + child: Divider( + color: Colors.white.withOpacity(0.5), + thickness: 1, + ), + ), + Padding( + padding: EdgeInsets.symmetric(horizontal: 10), + child: Text( + 'OR', + style: TextStyle(color: Colors.white70), + ), + ), + Expanded( + child: Divider( + color: Colors.white.withOpacity(0.5), + thickness: 1, + ), + ), + ], ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide(color: Colors.white), + + SizedBox(height: 20), + + // Sign Up Option + TextButton( + onPressed: () { + Navigator.pushNamed(context, '/signup'); + }, + child: Text( + "Don't have an account? Sign up now", + style: TextStyle( + color: Colors.white, + fontSize: 16, + fontWeight: FontWeight.bold, + ), + ), ), - ), - ), - TextButton( - onPressed: () { - // Handle forgot password logic - }, - child: Text('Forgot Password?', - style: TextStyle(color: Colors.black)), - ), - SizedBox(height: 20), - TextButton( - onPressed: () { - // Handle sign up logic - }, - child: Text( - "Don't have an account? Sign up now", - selectionColor: Colors.white, - style: TextStyle(color: Colors.black), - ), - ), - SizedBox(height: 80), - ElevatedButton( - onPressed: () { - // Handle login logic - }, - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - padding: EdgeInsets.symmetric(horizontal: 50, vertical: 15), - textStyle: TextStyle(fontSize: 20), - ), - child: Text('Sign in', - style: TextStyle( - color: Colors.black, - fontSize: 20, - fontWeight: FontWeight.bold)), + ], ), - ], + ), ), ), - ), + ], ), ); } diff --git a/lib/screens/signup_page.dart b/lib/screens/signup_page.dart new file mode 100644 index 0000000..df7ed2f --- /dev/null +++ b/lib/screens/signup_page.dart @@ -0,0 +1,127 @@ +import 'package:flutter/material.dart'; +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class SignUpPage extends StatefulWidget { + @override + _SignUpPage createState() => _SignUpPage(); +} + +class _SignUpPage extends State { + final _firstNameController = TextEditingController(); + final _emailController = TextEditingController(); + final _passwordController = TextEditingController(); + final _confirmPasswordController = TextEditingController(); + final _formKey = GlobalKey(); + + bool _isLoading = false; + + Future _createAccount() async { + if (_formKey.currentState!.validate()) { + setState(() { + _isLoading = true; + }); + + try { + UserCredential userCredential = + await FirebaseAuth.instance.createUserWithEmailAndPassword( + email: _emailController.text.trim(), + password: _passwordController.text.trim(), + ); + + // Store user info in SharedPreferences + SharedPreferences prefs = await SharedPreferences.getInstance(); + await prefs.setString('first_name', _firstNameController.text.trim()); + await prefs.setString('email', _emailController.text.trim()); + + // Show success message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Account created successfully!')), + ); + + // Navigate back to login screen or home screen + Navigator.of(context).pop(); // Use pop() to return to login page + } catch (e) { + // Show error message + ScaffoldMessenger.of(context).showSnackBar( + SnackBar(content: Text('Failed to create account: $e')), + ); + } finally { + setState(() { + _isLoading = false; + }); + } + } + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('Sign Up'), + ), + body: Padding( + padding: const EdgeInsets.all(16.0), + child: Form( + key: _formKey, + child: Column( + children: [ + TextFormField( + controller: _firstNameController, + decoration: InputDecoration(labelText: 'First Name'), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your first name'; + } + return null; + }, + ), + TextFormField( + controller: _emailController, + decoration: InputDecoration(labelText: 'Email'), + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your email'; + } + return null; + }, + ), + TextFormField( + controller: _passwordController, + decoration: InputDecoration(labelText: 'Password'), + obscureText: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please enter your password'; + } + return null; + }, + ), + TextFormField( + controller: _confirmPasswordController, + decoration: InputDecoration(labelText: 'Confirm Password'), + obscureText: true, + validator: (value) { + if (value == null || value.isEmpty) { + return 'Please confirm your password'; + } + if (value != _passwordController.text) { + return 'Passwords do not match'; + } + return null; + }, + ), + SizedBox(height: 20), + _isLoading + ? CircularProgressIndicator() + : ElevatedButton( + onPressed: _createAccount, + child: Text('Create Account'), + ), + ], + ), + ), + ), + ); + } +} diff --git a/macos/Flutter/GeneratedPluginRegistrant.swift b/macos/Flutter/GeneratedPluginRegistrant.swift index 7b9be20..3ba4b5e 100644 --- a/macos/Flutter/GeneratedPluginRegistrant.swift +++ b/macos/Flutter/GeneratedPluginRegistrant.swift @@ -5,10 +5,14 @@ import FlutterMacOS import Foundation +import cloud_firestore import firebase_auth import firebase_core +import shared_preferences_foundation func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) { + FLTFirebaseFirestorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseFirestorePlugin")) FLTFirebaseAuthPlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseAuthPlugin")) FLTFirebaseCorePlugin.register(with: registry.registrar(forPlugin: "FLTFirebaseCorePlugin")) + SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin")) } diff --git a/pubspec.lock b/pubspec.lock index 861e853..a376d62 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,10 +5,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "71c01c1998c40b3af1944ad0a5f374b4e6fef7f3d2df487f3970dbeadaeb25a1" + sha256: eae3133cbb06de9205899b822e3897fc6a8bc278ad4c944b4ce612689369694b url: "https://pub.dev" source: hosted - version: "1.3.46" + version: "1.3.47" async: dependency: transitive description: @@ -25,6 +25,46 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.1" + camera: + dependency: "direct main" + description: + name: camera + sha256: "26ff41045772153f222ffffecba711a206f670f5834d40ebf5eed3811692f167" + url: "https://pub.dev" + source: hosted + version: "0.11.0+2" + camera_android_camerax: + dependency: transitive + description: + name: camera_android_camerax + sha256: e3627fdc2132d89212b8a8676679f5b07008c7e3d8ae00cea775c3397f9e742b + url: "https://pub.dev" + source: hosted + version: "0.6.10" + camera_avfoundation: + dependency: transitive + description: + name: camera_avfoundation + sha256: "2e4c568f70e406ccb87376bc06b53d2f5bebaab71e2fbcc1a950e31449381bcf" + url: "https://pub.dev" + source: hosted + version: "0.9.17+5" + camera_platform_interface: + dependency: transitive + description: + name: camera_platform_interface + sha256: b3ede1f171532e0d83111fe0980b46d17f1aa9788a07a2fbed07366bbdbb9061 + url: "https://pub.dev" + source: hosted + version: "2.8.0" + camera_web: + dependency: transitive + description: + name: camera_web + sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f" + url: "https://pub.dev" + source: hosted + version: "0.3.5" characters: dependency: transitive description: @@ -41,6 +81,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: "852c1a14399be76c71a881d2475392393f2ceef77c0859405a6bcac5ec8c0221" + url: "https://pub.dev" + source: hosted + version: "5.5.1" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: "69f0baeb7ac0577946f82991075b18133fd81441aeda487e41fb5692958117cd" + url: "https://pub.dev" + source: hosted + version: "6.5.1" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: ff65ee2f8caafb1bcba3133666d5ee00848f94c677900a368cad593982ef8ba8 + url: "https://pub.dev" + source: hosted + version: "4.3.5" collection: dependency: transitive description: @@ -49,6 +113,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.18.0" + cross_file: + dependency: transitive + description: + name: cross_file + sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670" + url: "https://pub.dev" + source: hosted + version: "0.3.4+2" equatable: dependency: transitive description: @@ -65,6 +137,22 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6" + url: "https://pub.dev" + source: hosted + version: "2.1.3" + file: + dependency: transitive + description: + name: file + sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4 + url: "https://pub.dev" + source: hosted + version: "7.0.1" firebase_auth: dependency: "direct main" description: @@ -93,26 +181,26 @@ packages: dependency: "direct main" description: name: firebase_core - sha256: "2438a75ad803e818ad3bd5df49137ee619c46b6fc7101f4dbc23da07305ce553" + sha256: fef81a53ba1ca618def1f8bef4361df07968434e62cb204c1fb90bb880a03da2 url: "https://pub.dev" source: hosted - version: "3.8.0" + version: "3.8.1" firebase_core_platform_interface: dependency: transitive description: name: firebase_core_platform_interface - sha256: e30da58198a6d4b49d5bce4e852f985c32cb10db329ebef9473db2b9f09ce810 + sha256: b94b217e3ad745e784960603d33d99471621ecca151c99c670869b76e50ad2a6 url: "https://pub.dev" source: hosted - version: "5.3.0" + version: "5.3.1" firebase_core_web: dependency: transitive description: name: firebase_core_web - sha256: f967a7138f5d2ffb1ce15950e2a382924239eaa521150a8f144af34e68b3b3e5 + sha256: "9e69806bb3d905aeec3c1242e0e1475de6ea6d48f456af29d598fb229a2b4e5e" url: "https://pub.dev" source: hosted - version: "2.18.1" + version: "2.18.2" fl_chart: dependency: "direct main" description: @@ -134,6 +222,14 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + flutter_plugin_android_lifecycle: + dependency: transitive + description: + name: flutter_plugin_android_lifecycle + sha256: "9b78450b89f059e96c9ebb355fa6b3df1d6b330436e0b885fb49594c41721398" + url: "https://pub.dev" + source: hosted + version: "2.0.23" flutter_test: dependency: "direct dev" description: flutter @@ -216,6 +312,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.9.0" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279 + url: "https://pub.dev" + source: hosted + version: "2.2.1" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334" + url: "https://pub.dev" + source: hosted + version: "2.1.2" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7 + url: "https://pub.dev" + source: hosted + version: "2.3.0" + platform: + dependency: transitive + description: + name: platform + sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984" + url: "https://pub.dev" + source: hosted + version: "3.1.6" plugin_platform_interface: dependency: transitive description: @@ -224,6 +352,62 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.8" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "95f9997ca1fb9799d494d0cb2a780fd7be075818d59f00c43832ed112b158a82" + url: "https://pub.dev" + source: hosted + version: "2.3.3" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "7f172d1b06de5da47b6264c2692ee2ead20bbbc246690427cdb4fc301cd0c549" + url: "https://pub.dev" + source: hosted + version: "2.3.4" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "07e050c7cd39bad516f8d64c455f04508d09df104be326d8c02551590a0d513d" + url: "https://pub.dev" + source: hosted + version: "2.5.3" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80" + url: "https://pub.dev" + source: hosted + version: "2.4.1" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e + url: "https://pub.dev" + source: hosted + version: "2.4.2" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1" + url: "https://pub.dev" + source: hosted + version: "2.4.1" sky_engine: dependency: transitive description: flutter @@ -253,6 +437,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.2" + stream_transform: + dependency: transitive + description: + name: stream_transform + sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" + url: "https://pub.dev" + source: hosted + version: "2.1.0" string_scanner: dependency: transitive description: @@ -309,6 +501,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.1.0" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15" + url: "https://pub.dev" + source: hosted + version: "1.1.0" sdks: dart: ">=3.5.3 <4.0.0" - flutter: ">=3.22.0" + flutter: ">=3.24.0" diff --git a/pubspec.yaml b/pubspec.yaml index 8a818db..bd9f4dc 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,16 +7,19 @@ environment: sdk: ^3.5.3 dependencies: - flutter: - sdk: flutter - firebase_core: ^3.8.0 + camera: ^0.11.0+2 + cloud_firestore: ^5.5.1 firebase_auth: ^5.3.3 + firebase_core: ^3.8.0 fl_chart: ^0.69.2 + flutter: + sdk: flutter + shared_preferences: ^2.3.3 dev_dependencies: + flutter_lints: ^4.0.0 flutter_test: sdk: flutter - flutter_lints: ^4.0.0 flutter: uses-material-design: true diff --git a/windows/flutter/generated_plugin_registrant.cc b/windows/flutter/generated_plugin_registrant.cc index d141b74..bf6d21a 100644 --- a/windows/flutter/generated_plugin_registrant.cc +++ b/windows/flutter/generated_plugin_registrant.cc @@ -6,10 +6,13 @@ #include "generated_plugin_registrant.h" +#include #include #include void RegisterPlugins(flutter::PluginRegistry* registry) { + CloudFirestorePluginCApiRegisterWithRegistrar( + registry->GetRegistrarForPlugin("CloudFirestorePluginCApi")); FirebaseAuthPluginCApiRegisterWithRegistrar( registry->GetRegistrarForPlugin("FirebaseAuthPluginCApi")); FirebaseCorePluginCApiRegisterWithRegistrar( diff --git a/windows/flutter/generated_plugins.cmake b/windows/flutter/generated_plugins.cmake index 29944d5..b83b40a 100644 --- a/windows/flutter/generated_plugins.cmake +++ b/windows/flutter/generated_plugins.cmake @@ -3,6 +3,7 @@ # list(APPEND FLUTTER_PLUGIN_LIST + cloud_firestore firebase_auth firebase_core ) From 5d740ba07317a246202ad64f3dcc197ef2dd6e6f Mon Sep 17 00:00:00 2001 From: ALeBD Date: Mon, 9 Dec 2024 17:33:10 -0800 Subject: [PATCH 11/11] home_screen --- android/app/build.gradle | 12 ++++++--- .../gradle/wrapper/gradle-wrapper.properties | 3 ++- android/settings.gradle | 6 +++-- lib/main.dart | 8 +++--- lib/screens/home_page.dart | 26 ++----------------- 5 files changed, 19 insertions(+), 36 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 1404d30..724a882 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -11,15 +11,19 @@ plugins { android { namespace = "com.example.fiscus" compileSdk = flutter.compileSdkVersion - ndkVersion = flutter.ndkVersion + //ndkVersion = flutter.ndkVersion + ndkVersion "25.1.8937393" compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + //sourceCompatibility = JavaVersion.VERSION_1_8 + //targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility JavaVersion.VERSION_17 + targetCompatibility JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = JavaVersion.VERSION_1_8 + //jvmTarget = JavaVersion.VERSION_1_8 + jvmTarget = 17 } defaultConfig { diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties index 7bb2df6..f5f1a53 100644 --- a/android/gradle/wrapper/gradle-wrapper.properties +++ b/android/gradle/wrapper/gradle-wrapper.properties @@ -2,4 +2,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +#distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.10.2-all.zip diff --git a/android/settings.gradle b/android/settings.gradle index 9759a22..8e8a18b 100644 --- a/android/settings.gradle +++ b/android/settings.gradle @@ -18,11 +18,13 @@ pluginManagement { plugins { id "dev.flutter.flutter-plugin-loader" version "1.0.0" - id "com.android.application" version "8.1.0" apply false + //id "com.android.application" version "8.1.0" apply false // START: FlutterFire Configuration id "com.google.gms.google-services" version "4.3.15" apply false // END: FlutterFire Configuration - id "org.jetbrains.kotlin.android" version "1.8.22" apply false + //id "org.jetbrains.kotlin.android" version "1.8.22" apply false + id "com.android.application" version "8.3.2" apply false + id "org.jetbrains.kotlin.android" version "2.0.20" apply false } include ":app" diff --git a/lib/main.dart b/lib/main.dart index 178fbaf..61b09e3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,4 +1,5 @@ import 'package:fiscus/screens/home_page.dart'; +import 'package:fiscus/screens/home_screen.dart'; import 'package:fiscus/screens/login_page.dart'; import 'package:flutter/material.dart'; import 'package:firebase_core/firebase_core.dart'; @@ -28,7 +29,6 @@ class MainApp extends StatelessWidget { scaffoldBackgroundColor: Colors.white, visualDensity: VisualDensity.adaptivePlatformDensity, ), -<<<<<<< HEAD home: const AuthWrapper(), routes: { '/signup': (context) => SignUpPage(), @@ -58,7 +58,7 @@ class AuthWrapper extends StatelessWidget { // If the user is logged in, show HomePage if (snapshot.hasData && snapshot.data != null) { print('User is logged in: ${snapshot.data!.email}'); - return HomePage(); + return HomeScreen(); } // Otherwise, show LoginPage else { @@ -66,8 +66,7 @@ class AuthWrapper extends StatelessWidget { return LoginPage(); } }, -======= - home: HomeScreen(), + /* home: StreamBuilder( stream: FirebaseAuth.instance.authStateChanges(), @@ -82,7 +81,6 @@ class AuthWrapper extends StatelessWidget { }, ), */ ->>>>>>> 1bcd348387ccea8f1a3e1525c7e41d9637b8317f ); } } diff --git a/lib/screens/home_page.dart b/lib/screens/home_page.dart index dc560cb..c1aefc7 100644 --- a/lib/screens/home_page.dart +++ b/lib/screens/home_page.dart @@ -29,14 +29,6 @@ class _HomePageState extends State { } } -<<<<<<< HEAD -======= -class HomePage extends StatefulWidget { - @override - _HomePageState createState() => _HomePageState(); -} - -class _HomePageState extends State { // Initialize account balances double debitBalance = 14000.0; double creditBalance = 0.0; @@ -85,7 +77,6 @@ class _HomePageState extends State { ); } ->>>>>>> 1bcd348387ccea8f1a3e1525c7e41d9637b8317f @override Widget build(BuildContext context) { return Scaffold( @@ -127,19 +118,7 @@ class _HomePageState extends State { ], ), ), -<<<<<<< HEAD - Expanded( - child: Center( - child: Column( - children: [ - AccountCard(title: 'Debit', amount: '\$0.00'), - AccountCard(title: 'Credit', amount: '\$0.00'), - AccountCard(title: 'Savings', amount: '\$0.00'), - ], - ), - ), - ), -======= + Padding( padding: const EdgeInsets.symmetric(horizontal: 30.0), child: Row( @@ -176,7 +155,7 @@ class _HomePageState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - '[Bank Name]:', + 'Wells Fargo:', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, @@ -246,7 +225,6 @@ class _HomePageState extends State { ], ), ), ->>>>>>> 1bcd348387ccea8f1a3e1525c7e41d9637b8317f ], ), ],