From 1e59282298df2f3ce09a3376674e9ba55eac0e78 Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Tue, 21 Mar 2023 15:14:41 -0300 Subject: [PATCH 1/8] Brach teste --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d85267..fc8b529 100644 --- a/README.md +++ b/README.md @@ -10,5 +10,5 @@ Atividade 01: - [ ] Dotenv - [ ] RestClient - Dio - senha: cddbdabqeujfjluo - lembrar do delay na requisição de 2s. \ No newline at end of file + - [ ] senha: cddbdabqeujfjluo + - [ ] lembrar do delay na requisição de 2s. \ No newline at end of file From dabe5dc6cbeaba968632c6f2a1ef6a1a9263388d Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Mon, 27 Mar 2023 18:26:41 -0300 Subject: [PATCH 2/8] dias da semana --- lib/app/pages/schedule/schedule_page.dart | 11 ++++++++++- lib/app/pages/schedule/widgets/line_days.dart | 4 +++- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/lib/app/pages/schedule/schedule_page.dart b/lib/app/pages/schedule/schedule_page.dart index d3174cb..05a87b8 100644 --- a/lib/app/pages/schedule/schedule_page.dart +++ b/lib/app/pages/schedule/schedule_page.dart @@ -63,16 +63,25 @@ class _SchedulePageState extends BaseState { ), SizedBox(height: context.percentWidth(0.05)), SizedBox( - height: 80, + height: 90, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: state.schedule.length, itemBuilder: (context, index) { + final now = DateTime.now(); + final startOfWeek = + now.subtract(Duration(days: now.weekday)); + final List daysOfWeek = []; + for (int i = 0; i < 7; i++) { + daysOfWeek.add(startOfWeek.add(Duration(days: i))); + } + list = state.schedule[state.selectedDay!].horarios; return Padding( padding: const EdgeInsets.only(right: 10), child: LineDays( day: state.schedule[index], + hoje: daysOfWeek[index].day, color: state.selectedDay == index ? ColorsApp.instance.cardwhite : ColorsApp.instance.cardnoselected, diff --git a/lib/app/pages/schedule/widgets/line_days.dart b/lib/app/pages/schedule/widgets/line_days.dart index 5492206..0de7217 100644 --- a/lib/app/pages/schedule/widgets/line_days.dart +++ b/lib/app/pages/schedule/widgets/line_days.dart @@ -6,6 +6,7 @@ import '../../../core/ui/styles/text_styles.dart'; // ignore: must_be_immutable class LineDays extends StatefulWidget { + final int hoje; final Horario day; final VoidCallback onPressed; Color? color; @@ -15,6 +16,7 @@ class LineDays extends StatefulWidget { required this.day, required this.onPressed, this.color = const Color(0xFF1E1E1E), + required this.hoje, }); @override @@ -60,7 +62,7 @@ class _LineDaysState extends State { ), ), Text( - widget.day.id.toString(), + widget.hoje.toString(), style: TextStyles.instance.texLabelH4.copyWith( color: ColorsApp.instance.labelblack4, fontWeight: TextStyles.instance.textExtraBold.fontWeight, From dda303cb3a545fbad7a75d836e118fcaa06e4486 Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Wed, 5 Apr 2023 11:26:16 -0300 Subject: [PATCH 3/8] pegando dia atual da semana --- lib/app/pages/schedule/schedule_state.dart | 2 +- lib/app/pages/schedule/widgets/my_card.dart | 43 +++++++++++++++++---- 2 files changed, 36 insertions(+), 9 deletions(-) diff --git a/lib/app/pages/schedule/schedule_state.dart b/lib/app/pages/schedule/schedule_state.dart index 2787ff2..41569a4 100644 --- a/lib/app/pages/schedule/schedule_state.dart +++ b/lib/app/pages/schedule/schedule_state.dart @@ -32,7 +32,7 @@ class ScheduleState extends Equatable { : status = ScheduleStatus.initial, schedule = [], errorMessage = null, - selectedDay = 1; + selectedDay = DateTime.now().weekday; @override List get props => [status, schedule, errorMessage, selectedDay]; diff --git a/lib/app/pages/schedule/widgets/my_card.dart b/lib/app/pages/schedule/widgets/my_card.dart index 3cadfd0..b9091ee 100644 --- a/lib/app/pages/schedule/widgets/my_card.dart +++ b/lib/app/pages/schedule/widgets/my_card.dart @@ -12,13 +12,31 @@ class MyCard extends StatelessWidget { required this.horarioDetalhado, }); + colorBody() { + if (horarioDetalhado.horario == '18:30 ~ 19:19') { + return ColorsApp.instance.cardwhite; + } else if (horarioDetalhado.horario == '20:20 ~ 21:09') { + return ColorsApp.instance.primary; + } else { + return ColorsApp.instance.cardnoselected; + } + } + + colorLabel() { + if (horarioDetalhado.horario == '18:30 ~ 19:19') { + return ColorsApp.instance.cardnoselected; + } else { + return ColorsApp.instance.cardwhite; + } + } + @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.all(10), margin: const EdgeInsets.only(bottom: 15, top: 0), decoration: BoxDecoration( - color: ColorsApp.instance.cardnoselected, + color: colorBody(), borderRadius: BorderRadius.circular(5), ), child: Column( @@ -26,16 +44,25 @@ class MyCard extends StatelessWidget { Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Text( - horarioDetalhado.horario, - style: TextStyles.instance.texLabelH4.copyWith( + Container( + padding: EdgeInsets.all(context.screenHeight * 0.005), + decoration: BoxDecoration( + color: ColorsApp.instance.cardred, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + horarioDetalhado.horario, + style: TextStyles.instance.texLabelH4.copyWith( color: ColorsApp.instance.cardwhite, - fontWeight: TextStyles.instance.textExtraBold.fontWeight), + fontWeight: TextStyles.instance.textBold.fontWeight, + fontSize: context.screenHeight * 0.017, + ), + ), ), Text( horarioDetalhado.sala, style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.cardwhite, + color: colorLabel(), fontWeight: TextStyles.instance.textExtraBold.fontWeight), ), ], @@ -48,7 +75,7 @@ class MyCard extends StatelessWidget { child: Text( horarioDetalhado.disciplina, style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.cardwhite, + color: colorLabel(), fontWeight: TextStyles.instance.textSemiBold.fontWeight), ), ), @@ -62,7 +89,7 @@ class MyCard extends StatelessWidget { child: Text( horarioDetalhado.professor, style: TextStyles.instance.texLabelH5.copyWith( - color: ColorsApp.instance.cardwhite, + color: colorLabel(), fontWeight: TextStyles.instance.textSemiBold.fontWeight), ), ), From 629d5f3c04dc8580549671fe2327e303bee55bed Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Mon, 24 Apr 2023 18:37:18 -0300 Subject: [PATCH 4/8] assets --- assets/images/images_cards/report-card.png | Bin 0 -> 22708 bytes assets/images/images_cards/timetable.png | Bin 0 -> 27089 bytes assets/images/logos/logo_academico.png | Bin 0 -> 21555 bytes lib/app/pages/daily/daily_controller.dart | 9 +++++++-- lib/app/pages/daily/daily_state.dart | 1 + lib/app/pages/splash/splash_page.dart | 5 +++-- 6 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 assets/images/images_cards/report-card.png create mode 100644 assets/images/images_cards/timetable.png create mode 100644 assets/images/logos/logo_academico.png diff --git a/assets/images/images_cards/report-card.png b/assets/images/images_cards/report-card.png new file mode 100644 index 0000000000000000000000000000000000000000..2f0fc3f18f6b6adae489a83dcb9084745919b548 GIT binary patch literal 22708 zcmdSBg%<`5D<`-Zt0TlMx;ZLZUmI>PHB)5>F(~9IN$I*@B97@ zzmMzUI{VC-Ju`b|&06=m*P0!s^iCQJoeUj}fB z%c`M*KX23zq2N2(M;R?A2*U1q{D=F-giQ_#Nu8xMomK74oZXBZO(8coH&#nKYbO(< zkEX2lj^?R{ugM^Y29lK&Q*%$-UvTrMF!vEYHXpd0YthdWyjZjy?3p%Hl|KrGXoHDR zz8J{J_$x`EqM>y;&_p4ARubo}=-`rQ=V7hy@2T_@**SD>*MlTF+&d>R7 zl`-)YJ&-m$kWnHjfqsW$Y*e@|J9n)&gHUY?u?&NzP(8#*MnrH-L_mYFPRNb^R%8N2 zYKlXTnO1|gFD9+t`-hXh_4Tdh(mX152uD41 zC^N8-AMa%78`KF^zP))8qbT3fyQghMi2x}hP2auTp3PO3H0|Ge1*KuYC0BZ$?fm>% z1O}790pYL&3}tT5ANXHd{O0BC<(44kEWD&F+xuaP2}wp6p1t@NRsJle<3$}jl=Z`E zFgi-1ZG2C_iVy)BgP*<&W1YYYyWV7kp!mqs7cHgP??H=0K|`4qzLgCB%vd3afV-u} z&-Id2e@Z!m1PW#SwW(NL@7^a;2M1++k6$`)!Kw*`^WTQId61NgkbP(Xa+s1YGQLM< zg$ueUtGK~ef6n}`$R!>tw-Xe`wfTliQW>4SC`_Y4#qs7MR6@C{P&0}$g0k98&R)D4 zQ6z@L>^xTHt_iXyLn2ERQKmc|=?+c#1&Ic9Zz@WP^?-}6$BSNY(FrcPAW^u-PiJfd z2njh=1b57y9a5qxzrn{90`oT^#N$VoBgX+L>4Em?Qm8=@%VW`}$0B1;q)h>eC?AXR z9*e-(=n5nEUEn0&flJQH#*nXXkuXkHFz z656$2gt;~sR*-W9P-m*mU6aeZfMp?4{liV6@@m>3sXO2g^E(Fq$aswW;kYsNeWv`1 zvZNl3ar0vh%2WsS=I*@kuzB!A+%ZF$o8x8c$A-S>Pqqq1 zI@@(P;ZsJZC;mtwfqvvy+>C#E$H+hbjk0s3YK??>OOH~H6Vu!Hj(zfq$FPCI&4rnc z7tF@cD@=*zt-tL!sea`f&RDQS(r(IRBMKJNLIGFVsgHwdBEn-0d4+3u`~h(OR$q)r zRy$6@3^vqj2KTi4$R(_(mQqN6#Z*33RQP-LtEB;L9Sh4r?6eq}jtPunGtK@1Nqug` zg+xzWg`Kd>f?yZZ%{PazI3vT-`Df<9tPFI zoX1mCYAOaAqmvzR`4uE|_`<(a6wXeo8Gzbmp!RrL>1tcSt;5_r4p*mr2`o*LkQGMV zpMSE^@zmYWlf*;8XBSqc$hESe$8^$o$c-A&j3xHX1jVzeyiByoMTquS@` z9@B=$M0Y5Jltqp#?6wKDzII3a_Zn_nlQk+;@vs|)o!MnxryoIB@!h&c$!A5Secj9E zp~Fd~f8|LCb+3pb)s@eg0pYv)e$^#{InQjLaF7kALFwp z2?m?_$D19}Cz2coE-wk2gvSD6+-yRY|J=lE{Nejn=SsLYyyC5|2yxtV;@w#Szi^7g{kEuUcM4vSa^g#nUx^{!8~W1#ZT-)3~->rekKsn7tLR(nMn@f|%=X(ibTN&uF;# z>dt5<*pQ)9Bp%o@*lNx8>#`K3r#(VCxl!(Kijg$BQY+~HY!{g+t|Nh36kvQ{OSzBq zeI@zmQM7m_u)&}|IvS8z;5kaZn$RLiYz)yTR@|WUer)h}!-ApX7dBlLNTIsB=3tfC z?{-I9d@aJi2(=~i%uLP&;XNjaJD1PS`an5D_EQQ8#cG~KYDZ$wOdx3HG$cfXdS-9d)DNyb;;Wv! z*BK)-Mz=0$r{yhJtxo|G?$3lmDi801TPjP}^llIJjz^Yo-{edYdlTws{U>AG(G)}eRX z(%Wp0Ta!}JL;HzG5EGn=I(Ycc*a+0rg2B>fwPP$xs9;tJW-@z?&7G#_^ z-xyewCv_YhwU7t#*zqbI7(-cwMnJY;DTloa4Gz5{O&njkVCM%t=mSd`t^bj%;;eVwGBsSaZ8yXZ)5o z{+=W)|D~L9F;wp-Pq3sDxA)<1xJ1V4qp$|F*RMH4%(5^i&*C+p2637H6B_jFh!cbvwH$ zuuaq22v@(uQYk(_s3gdcBOy?H79jyKG1TJkrzix?Qz<&ko7{{Q2&oTl$EHc|hE963 zn2)cLR0pp|I8lxxe$w8}O`7M@Q|O(0OIJNCZ5(T2{goMBrGOl+Soe%&IF@HyX^|sW-C*6h^}N>vjO8 z)cdVC_v)TkO7(iaa&YV=+rz=Etdv5x0rechLf4zu(p8psSIa9>2II`14-z&TH|Q7$R6Fu(8gB(^K@ESYWBR-;?C7COIU>sueUVrtcayrNT<4RVQIq89XW zj+y;i`Y>MJYIi+&bs*#X;X@)xt^9(ax!5e1Rg7uvLkog9C5DdaUooM&3?ZYP>9qXS z>}0vbMWHewiq6uWT?NDH)lZazE&m-nMdv29Jg`J;BjMZtqne0w(l<9P9*27SrRezgMHm z@ZkMpTx@#6mF9hwi6Xz9*1K7CP4d6nG~;OLx(guJu<6MxS%mu;jzP*|=2S^)Fncmj zPi^x3UzZEiN5lg&Y%={v;Ea-Rcaxqktozl%DT~h9j+`H9sJxCT6K?rr25o+Hv1xm6 zvDq6TV_`N3sQDfr)y|}n(=|7Ef0m!`oAaFr^(SlaDiwdBssl8k)w4-$a~o0R&Msnl z`#LrEWpkBj4FaK7E}6g~iHjL_XU5D4Jpu$3hti)+k(UOWktDGabL7RddYm8M=HAy& ztlEafGOWr8X1MjkVg_FcbaHgnBe4TR%xrvCz$UNp)>kBw~}5FyKw$V}6Np*v#Q<$GIl8ni`WQrJP&3yOsr98FIlh_1~L z$_g*P8TW8Ady_q##sNE3IB3Wz#0JfZoQ(DWlfoIU$}N*i1wK z5E2V0rFHLAw#eGCDY$yo&MtkjBX_VnUFuG&$0~n1VRbWo@X~HyLJj}|B!HH>eKTsN zrk{zmr>6X)DC}wMHScwx|s45j9}8yisl?b}KFy5}pu2hEj-AMfBu92Q)cd z!nb2#QEp#YG%R5(>@Mf}oq7Dt4)gb`v})SH3NE$UZJ!v@i;h&hh=TKH?buX2vcww@aiXl!)(uR;FjLZ-!Ku)ioDe+w>PWTb5SGZLaaz& zCWNq3MOfB50$WV|G(O=^lgJ9FMY+^Pr3G4@y$pHFTq9_hx7c8evDjqx;#W@f_FiqC z_Q|*O5eX*V%WQOqmxi8TFhfyV6KX*g8J*LXKS zLv=TjCH+y+iX~8*bdXzc=%c!Ys${+-WBdl3akxcR#Sa};02$he=udu82OUs+f-@zB= zv+1vt`uKPR+f;OklI|kmXxgXmeyX5^gLT;8II7EUak>7!w)eoc!2w_Z2eQ9E*eY*H zq3F4K*b+lX`SY}or8F4fDdE)77aBhEz2o?!kygFfIRoqvB2KDEGRJ#Xx?CLtPS~j? zr{wtH4BuYw8Uj%M>eReN-yFCERWBUE7&{;wcAJL}ld|25Jv>dT3fSt#>8YU4yxBAC zP{wWuhX(xG9cy(|!C%G(6X6#O>!k9<*pd`IWdZ{No>$SEK`EWyGE@(8sMX|buI*W9 z=-bIe`58gpu*$=SfgnjU2ihzMR1|!pwg;Cb7C%b&iL$sS&AA~sQxSVcp!cF=P-%3~ z{iEmKKPN~E-5vV`Kt-`oxfIGWYH@-t-) zTTq~!UieVvA+kBzBl<2`P0qb{rkB<7fjCu#@a|^&Yklt~&*-`$Cgc)6l$rKrl5ns$ zzbiKAThdwkIqERcfl$YBqp3A5G(9>R8EM`%zU+`Wk9@7%Gpifo<+N5y6if$OdDbof{NQ(0w+_@-7RWcYoiDQI zbOYV$lRB5E{PussGL-g(uy1lt;N%n8(v?W@CAK3aD~c*8Q@^s5mL=Dh86M8TJPM7L zWh}9qOww>P*}!@sriwIV+e~};3O!d7ffyP?j$&rpbnnZDm{5tyUv7T9?OXkdr_ufO zx@tnu!B(y=*Cexmq_M>Q1i$d&hGt!)8A%Cc`mUcP$MER(hZU!&=E-=N*mvt{<%=!O z>v4puwKH?`w+1w*C&L6brTBd)Ax}XRS{3RLP{BqO@!O_$DTC9b7r{ zIC&<|>=VT2$?Au}(?L9brz(jbgrIG9_8*OYgjpHSVR{yIQTHgDoQ6*!=g-Y^Gja1B z(6SSduNu?r`jWK~hD+CVodFAu7?gZzUCK@jcz+GIQpbI7dcDr;*K)WTg}t36>HU0IgE!o!=XrHXqBno;C8xS7cQ%p(%Ny9?$e^PPt zH8U6q*N4XrA&p@pc5(pw{W-at0+#XYCaaGx9U8p;R0~m^O&gW+=gbB_W_w%W_A_wn z6AhPRQt7HeMi+^tg3v!iAr6>%(3x;cd+)YRCgV!t)irEkZbHAN@^c|@1JWUA~>>ZgF z=$&BE+m4uNnzy^+zwb5gv86N!3(Q_6Zjja4s*i-rV&#C`BZo4r0#M;bLhC^NbRIie z-Tmka-*s*;^0_{fHjP2-8yC6M)j%Q0JYRRrVut1k&DJ;|?c?1pu zM~mXJ5>{|+jI&;MM=6r25)-jY?2x-Z7>Tka0$s3u6Uyzb1*t>%nQ=^u9*A6uw zyja`QtbByLAb0(_SJlCEwZjgyP55xsPL_1bN!r!-`Ud3o67tLAs~6#LS>e-n3rc?0 z?YA>k_y?iW^LUpR?Xvx73C z7CKYE%eywkOwq~JTuUYs*#yl&q-0!mBkOc?6=;FZ{AJ#=Y-KlzE=Cf($%`f)euUeopc*nn+* zj25NhN?tk>b4)`LQ_B8O6klAb(+|Am6LB(;Du+)F-uD9X?m;j?44npu|`+YyoIE8;kO` z$%i-i4H+=aD=Jh-3Q~Zpy!`0GW+c+)!~bx9?mIrki3p8Y z*0{9^0mf^3T8x2*`WC_8t-83<2fGlf8Ge}t^fii!uoKvlzZN{{j`*|ug7VZ#PZQ_F zYv}UDge71oq9`S`tK8&XFu&C#l`~eAaGFRJfzG?XxQjL2$Zbv4uvGbYt*Wj`b8NTg z!HU*Oru)-j@Ii3xv^EbDMo?1UhMpE*cVzi9Bd65c#BcY9-} ziBM02+BBOm^u`93VroAUP-}TLlyKOmQ+AD1Ub<<=Bf|MjH}+h5{BUK5`22_3JpX*6 zJEdB>B}Rms6V$OC`d3O!E7p}+El^dtC~@<0p3CEJoRdc$KS9SoRfGI@n!*p_Wil7jzRh2)FcAC|z-T!&RM^)}^8A!>%4=GXhH$qg zzm&O5J)ixUH&hZh(qv*c9T#S!zZ=D~tdqFl4}2w3g|mJBQHt>81E196gF$^IWhKqN zMPo8*N|Eh8^{?L<)_Tmgcw};B+f6fU4A08&I@{H$}?<6nqF2q-7^!RR@%OeO~fEQ$G?)K!mGgpriUSh8LB?lq?#Wnyn^}hv=Q-gt7SQ znBg?!o{0z9AC@E>CR-AGRb3K9a?EofYKI4wz{2ZmCPqtvOZrnq2PIo$s66W_(cF#; zmZWdBZuE-c?Bt3nzBGm4mYdmU05`5>Zr@0D847zm68plO9`j?p&&upAczu>KcQM+2 z;l<_ZC+~L1ebI}~I5VH&Xg0NY0s@e{nGe0EzXY6rA|67qX3Ozg^vK? z@*lFz@)$~V{d;P6#;-cOb|B$(d@v&hZqm4ai`^!2p7b>0PM3i>^!j$#*238Wfv!*w z1j*LxLm5`=n`#9XKM+Xtn!kuyTQfo7Fmc*3Z2No+Cqaj@^#@A&PGH64RTUM`t&du9#)i?x;%{l*Kn2L2SUO7-;vbJKo zB`t}Z+X^`@Ifp8-g%{l_idI>!4R3q=MPy`&O+ff_>i)eIzglNIh-tWO+#&k|ck*O# z{#mVb>hUAxEjYP9p!qIojKG^y$X{n`Sm2*7%)2y{dyTrWw#ktx#EKjt8)W(?`>S>Auc)|S@MuspzRI&JWa-ZhG^pvk~Lg0f~yZXud<{#Pk8r?c^1VwHus@$0S zYG}5&0Vt%ka7_$XNpi}2*W%9h3KgOlVzXmSBQmdus_27QiyjPefs?W5q1c9a zZkE6{N}^+QD9$Hlv*2W<;=a#glx743h8I)_T2}bp2jgkth8t<|MSo|=75joi{Gm${ zmqRSXc$7H6SZ$ zu(g5g4fFk6KMol4;nQJt*LypJfk7uc+B$Y(nnVl$)9rN#Zk+jKF#h$xDU*X<&cdFG zm39F|x8J$$`+%AdF~9U+e)=;rh$GQ0O;aeW47N0#?Dm+ZWmSjT#=Y_O zxUp+)tw=n=*Xrqo!umAuax_j7XZ|-AAh^w9&YzgedG)9_#xN`Gs`1%UCUKNtztUg!c?nfFU!S@o`G-ol$HjJaF|cPG_M zdvcfuCR7sx*A5Rhp@@`|vWPbTednK>yuY&8GIj9UL{GLZOL({Y+)lXcT&!zZ|`OAbi09THtPFqP=d zy&;`X&1~ea+|HnsFvtO7fb|bKl&GAI;j%Ts)%rcf+C6FdA#hoSKNw*D-d^3vT{emE-o$-4$#85$`HsQ`2X#f*vH8Kg(NQ~ zLke~$do$}N?{^83!IHixPmh3D&3q>nKsKu)8Qh3d9?(ye;FcsptnN11wwBM~z`Jau zKnKAlI`Thxco`I_fjO4?iQ?Qc+?bJ@rzArg6|X1!u~-yvkUI7%8ED+^!}@ZZe+KtT zKL>s$u7s1;er6K9J(Y3|=te7x4EeEzVXyo3tP@?hpeoX`!7P76h^BH`UZB(dVLe=R zhu~OZrXR!WsnsD6`Mhd1Kj}YDF5%YrlgK5E7ILpB0Yv z6N%#GFl~XL)6N__=7+zpkR7WSlIzp#Lj8qD>`OnOY7)I$cGG$Pl(y-rsARj)dh0oS z`<$E_AtqG)ouekSEt4-$`gFWBZHXOodj|e*LmpdE?=K_WiX4 zh)XV7L@N^lRn1~0&$4&KgNb33FC5`PoM1P{{RI-R|nQOZf>w9zb?Lz5*$beJM;XC)%;6R9i;4F2xt$e`KZ65JwLa6`92l!baHJg%38lR zCyCtNy$kq;`MErwe*;WBP8y;N2BUj9N!Z7ZI;*B3*y4PP4$6|x)b;;Yd)cim^P$MTN_<;NG9osWB zIm(D4X7hM76H;Qb`NA2h2DJzanHxxoktFMoeU(} z(7`}lUgJO2$w63>b$iHw7qd)`hV%L?$A8t%fBgpykKe@TNoNJ;b^kSlZC((kJQx~A zYhz>a>uff0rAE&hC+?Ya52F?1A<16v!dD5tZzG2Jx`kHDv52@OE2unNTx&?SE$&9r zY#*{~TcuI0;8t=)0$yL^bR~1*{H2Thh){ir#ZcCay`eq=Pw`I>Ew91JBz*yaLl8Zi zZ>!IP>G`Lu-jwVbTS{l(&kpTfRogsQKU2@G{;bPaY0>2_AknHNZivqK$N(0rS|AtE!J3oe2x`>UJ68-(_scNB}2SF98R*M4)R9?M2uM-N>&L)1`L^0>_WjjxQ8 zIZF&7zq_FElZUFZ6cI=!_ZGM9%m?R873ef!VB=~*IE|Q_@JQ%fZk?+pXNsvY%Dj1=i`lQzw* zT-Z#i@N$wYQR6wGpMoa>WE3Xr7x9NXG;e@<0Uw=nvbXS+7)w$si}=MSIDdJEmYdsC zy3_IQuGo?_{O6O1p%KHy)JiN4GmBnp==@fDA3J}aIR2j0RHqMR{~kJ}9{c&fLEJ5_ z&vY^}lar$$emrQ51%@v5+SHPQEm#U|A+CPPRQK2L*_~%|w;D96DwNP$$ip&oFdZnZ zmU=y207AR4kY}j%wcWEQ_m>~Y$u>TAml+T$8cQ)-S{7S175+rvi0J53@RUF~-~5&k zt)6ILd3YhzWY|}8QlfppedU(>uM-lLGd^qkJNJ)AoZvUx_nXUBh5Q%~=_RxAUiTGS zq6fPPmDzv5JcPZ9AKH8$$F)upAH~Kk^8OpCBjQFB+Zo6=Apyo9e8|ri(01;Fr&#&X z9$H)Iy5oOLJ&O~a&sQ4X`x$6IENqb5u(|B#pAMLd9kdMm<;bJ756s|#wKC25&Yco| zwt9Kcit9PwCc;*T4J?IHhth)OgOx2W?CfD_!1lT%gPXAB(!+M}WXwfFlT4Zb@opi% z=(w23%X++Nqt0`3Sy99Gsxgutl|lE`T*-^IXnP`$rA*9nuZSh;Lm$U_<}JrIOA!m@ z5u=#o&S{;5mRHc!x7a5iIcYEgD@jK+%oNuQXJ&d+7;iQW1O#`c-RNn>~OC8Fj+ubKlt8$hmkvU1ys-m8Uj5 ziYxr@spO>}iulQ&8jACLVFI@nq+LgAqXY3kZSm{TD;!~O6vXcN!Z^E8f!eJ4y`fQo zvA=4$hgL9#!KMgofp&XribC0)o=6Nt ziZZCTqQ*acw)6AA{~`oiT5$+?Id{CKiMuK#OJ@e*kfBp0(qoV;h8`WhHeb7fdt&#W zri)yBmWyrBWK9XWN&f_SL?7bw=Z<G&aJ|=OVzF36MLi%L0*p#8FPSKZa z^MJjD7{`>3i#rsN8C{*V7<*x=$HMIgh3xLPUa{bM?X~0MPB1;f15OiL2A!l0>zW$` z|MyDr)Ky7|)mQwU!gM*08N3)@XqIO!KL70fz0c(*F_C4OK9^C=9oHTuwE2GTDIGdG zXyUK6>R<)`U(5x~#_Tz(2UEh0pZr;Y4vb@yqyF|be!|3!G<4dK2sI1pfVe2}F5A{e z9W$IYZHGm6Lx@4A-lxoh(d^Vi-i(vo*^3)J&_6*2k!^6c($2LyVp!KzVLM`XRssH>G2xQco5E8Et0V}76;^6u69V0<|0H$^e7(dXrWF| z{k1pf(~x%Nmr87(R@c@ny9qY}Tp!1R{7c#|vai)%j6r`kGD-<^U~?*~`hxqCJmUSE z_2mOp>N{4%iG~Ke_ma?dg&D)#5@dRhq0AH|HA)bCwG@85awMT7mw4AeWgk$vrl2$_ zy!4>?mME^pK>GR`2G>}nSf`ntmyqo|qmzB9zvJ?99lz$JY|=c?9m9V!yC`(Qk5e4s z3G0nYi8cA@lpo@ozS#*VJ6`NALs2}1&t}J+_uFko*smHtY#G`zIjwl50UF<{7c>e~ zI;S-o+#^yeyKV?XQ*p7I!*s4wOQOG{H3b$G9(U_bW!<#!6MH~Lv>HhgNnOpWC<9<> z=`3RWWFAwFiE@W=^~!f35g13%Kiy^DRx_)KL!;}VP;u4`g6Q`8!lV642*Halwg-w_ z5_>VauVW5iaPLP94sW@N^Q+g_YL~>r;)%Gqucc@4@kypQnV{jndMotwX7bZx{jxz# zrR%N{`L@q-5=%jRJ_F~PaW7go=QjQHKO9Zbn%(I=ZHNJF1@>hNGE))@p9_7JCLxMG z0kdwapIDwXnthZi(#MX&e~O^`8TBpp3cd)Z$orZd#$TWPwp|F7nl{40#WBdf{ zZ_gD)8HV5Ac{*%jcJ0>#)22WsvVODPbrYIwB$HePY}JUc+2KWJ%&qY+1N!wUFOa$R z8YEqR_@bGX?1t=NiWxdn5pKX@8p0C22B-IFxwD+kjM1-+?K#1g{3kMpQdicZh=!9C zG^TZ+Qt7JBD_hpM@oyl+(@M)z>tMa9#_itn?W((g^QW?XbwRZo#zRng>;H2Qwq*&LZ{F2Q zh%P}csUZGj-ZBCb=TPo$$akIQG5m+|tJXq=juj(V$BTF`Xko=ysjbEz`!&a3;Cd}{ z#+sqnruWKf_Yx75dOSG~!7h{g8OrAZe{yRdQs1}sO?%3fp!D8p+x7XA)%k&#G3f^c zW8Z;EkF=**&8yl3We-o~#LkW9G5(kPP&5~%^2E#@zY<5Fb6-9u$j06%a3skeyVzTQwg-fNVUZq%$e1=YaJ$Lr2VsDzENHfBydoR1CRhp95<7Ajz|IR_k%Wx7P;tiA9h=L(S~5DzlLeLz z%s7Q0@Bi^Pp@GqWojJjJN=JuI1H_Up2Ldk0|Lb37_TWQz#k8h4GMH#oRkF4l3u=H1 z*#8lgGK}Qcm-Xu#^@VoHR{w@CfnW0ZeSIC@OMV$8!OCW#`pk?9$O+-cT@qwRvYnaU zxiiD;977K4j(%70$V0d&MBzx?QUmTcUq@LY;f`4RR^))1f z9}lp^Kn{mnz%heYbQPPh6qZCUuy^qB2?l2=0Yi5 zFrM_1ae8qKK0pHjKE??OWftJ$Ujw=<8w}HD?Q8j2`u((8%23<8$gMLz9-%!K(shvI zDM=*183AaO7S>$j@lSYfswQ{SSzeO-{yqAs8RjFi-W%8qui~Ste#*g^h@E`9arp@?hz|eQSTb=$ek4X-$7lYsb&}vy8Q}Yu)|9=&@Qr|A%W<@NAZ0vc z7~46YZ1bK|N|m+DwOl; zyA1lQ8gdUF{#PDXH$x96s}7MTvPLwR-kw$>`d_!Zom3XEi7|ue(Q;`1uGba(usO_Z zW(Y?OqZ<&`S@Yk=kjr_xC!ut($^rmJojJ;a^#d^;VzACv93riTL)|m`;%(;&CDb}o zlvw5T%pGQQ_>>%@-jTgpHNN2T4-c8%){z=2yUNzgyDn&tCO|vZc>8+Q+3y0G08ys@ zMkM|>7wl|xgD2Qb9*ESN!G~nh((n0=zgs;M0{AhjowPZ?>4x(bYL%LpP5nl9VsN4{Y^g zcUYb6qnKAh;209X8?jsSRu78UQ8Z<0Zj=ZB%XTn9>o0jzVIQ7vZF_`;?xOwYSVCrK zA8>}((H?mddvHK$0vxHr^#FLF5Tw(E_E7_u&gwrjOAsgud@KS-XZl0;%n%AESLPaLyW$zK ztTdPNdBQL*F>8Ia8Yc{z$xUgQ_e^U6J4R^(rtBK;M=7EWy$T66xLj$T3EZ|=fCR3U zWZblVbLG*ZCf-jBs1|5aAQd+RgwIjcDbw#td0-b`?2*cD$Wf{9ap@F&$;B-X|A>4u zQL1f5&MPUaSYSp{5W8M>!xg^PL$&IdY)H$JPR-hPM~J^*gSYx#0|M|m$k;37<}tZH z^kyUHektF9+z5B|DaJXIJar`4j2~1NlM!gOT{~hv6|RW~(gXxc?R7T)4^rk=HE{XA zDck!vr&wijeLdX~ZgAAQNgX43+^$~cT%BLA4ItnB)Af$e3En>^8whWKo_xYDHACIlK-ZuAkGJ!QQeVm^# z7k!p}F$rJSi&q6N>9oQfX|;4-db~4#HR{|M5WbHu)luKv6j4{LuuA?W`q<>mP3L@U zL<8`YqGW>p(+Io><;MX(i$YnK-YXQLn!=&uiK#uX$L%x9!pc$gBO|~d%Nr1GI1>R8228|}8$j1;0Kj6!( zeKQC<5eG0f_Vbk|;8G4r4tm$B*7BooW@k+J($YDECjHK-k8RIHj+PXUdJQ?&z}5u% zq>?@qKw`SjZT36$$Jv7NR7N!3$6g6Ng|z_wHnSRu8BhwC{UcdmKQ5{2RiNZ7NH|#- zQ_Tl#0$}!rvhnp3#i&3qa!}Xu;n?r&bEz1a@2@}Ef7a1ZyJx};*oM;rl2XgL-q*;k zq4;p{pBN*2!bC=&Y&{TW7c$_F^4KF(wc3`@o}&3Mq-RzZQYE$5rpUR0=Xmy-r98Hyxy{dwjZ0-9nw};2o^|*f5dE34PA5d!vbKPVD2Ts)9}X{NL@E!sBrv z^~fO@g+#Qty`IUArqCk1(2U;Ap3YQ9Yzc3<)t|3It(eSvo&2sp-4ScUrfv<$AwOy(Ts*r6K_oiTX$_n7MCLE$w@FoAelT`tudP z{#2B)H_#axFo&i8KMVRE5T-#iE!eYs}!oe7Hd~=qPzRCf4>u0Ul-+_GAXNN z-reiG&3M(m*+!%M=7FC&gvz>fd*cm5$lV2X2yS>P)!Udl8rc4m_Sp1$e!lKdo}BBn znD$u4HVu7SmK6rOS#Rzf71LV|XQ{P%%W+Nxy$2C{xk@BzEw_d|lOiL9*Pj&ayh8w~ z_kUa@{v8Ua6YD&T-XUiY@Zrq-?rT(4!;xN$uCNU)B6tu z=KL=Njt#+;1*#LtWn+TjN)LnY!gh2Nm&_gYbh$J34+0K4rzl}v68Cp@9Q%OTN;0dZ z8YM5+_qH|#KSH82qo1rE{-jOo8>Y=o7{!Y=)+r=pJKXO4hW&1x$%@hUm9YP<*&Ftx z5yL{=K>cp>qg)l#^f;2*7bEuzJTKByzxV$iv9p=nux}6n=g(k40)o#=?2dYR^N$Bz zIe}?md^9b7g*I=Qk-jY4N(lH%G%%a}9XL`Z|9JT&XL&q%T2fMfjS%o-UoCv{j~g~K zIVSGlpp+^&8b;aZjF`|L`i~1y8eOOTPuQ;E27#Tx+@8?p?Tx*yCmo##I1hqUBZvFU z&<@K*aEKZ?%Pe9uM#rB4-F+$C7UXV({>T8g=PXWD;#z%*`8RF#0R3%9Gtqz$#oDRM z7CyCp{1tbGi#tIMFpOFd!>u0` z4+#I_1+OwIb$^3srHAjEuemUXfE{Ke!jrTK{a)VD|8=tG{Z#~BJjJiiN1{JqzM;u0 z1rKc*7SatzWbt*)g{uld33NneI0ENF!N}ABNu&@-c>C=DJkN4t`qWZF={&(h9<_sa!m#t(qB~~P>JW}Bq9WnkUqW_VBy_g zZXA!(xloFF!clJWEr)~z?U2cB}0-_*4ThnLHSOg5I8E=(~3A=$C<>oz~*fh;J|JS#8Y0I zc@%Hw8i;;a;`N!h3vkkSwkmQ1eV+l04=wd$coZy6=+f1b=Z9_Np~C0(IKYtg;uYND zE}S8a_o_#g(z?PFwhrxYxm=XkC{I5-~B((9&<{0mo$lm>Jx7ikzzl zAD6A@Shhz89Y^?12sN*}?Z!Y}NiK9BmatQiqv$(yMLik#MPj`j_GmbByxNTZ2@yQ5 zRMYspXh=X`S*z6{$rG6>3DnHy$FpoEkA6<@Kk9PlH1ADX)hHPTQ>)ce0jTf(3NGR` z<1V2Xizt=v?>`l0_H!~{rD@DsQqnBn{ebEJH}rs${EVTYVCa(9#fJZhL+PnW-cS72 zrkG|N;ASUr`bBiwuF8vKY3UfgO%pcVy-$1|qeIqkyoBB5@ z_?Y)^7^c1K=V=IRnm>oYjdhh!iHro*CuJqj#HVX|M?AhCAWqh^zGL#lj0pABF9#hH zb-gYSRzUW`c!jnZU6z+uAVnIYi-O@0`}m@P=cI82kro599XXg!XY@`6FY<-0*WBA< zO-AvsnRm9?a~=4LSv_)I2pY+JvyUj@o&-70_PWD_@Cea>*kTqFZMb5T`&_snC|{CR z!0Rk-uVn&)395;Da59?-L8Zt-lb9twxp^i-fQ~slIAnu6h;>}z1m_a}Lrn!#UbrMA zsIl03rSF)8&n+4LODe>djIV{&PN_5Zy|oRY5c3#k`c3)t(<4>0Q&BjC$}2i^{px?| zmn>fA9QPX?1xi&Ab+9-{m5<50)JHSDkC3OGwZU+VmGNS@t0Cm*9e zd-v9lEs7Zs|7RH~4Ju-XAd#k0X6D*4-t}Hz>PlHIRX^;{Fs}|(QT^>3zYs`F)N(3S zdG?O6j7dwy;VMdLa-sYjLkg|CXwk!Nje<#%^kz>4v&KBJW=-!yA1*=0h5nC0H}JNK z8_3*Wvwg^aTl`O#vgDO7;h*UMIig=8dAZsNb$Sr)>^M#!swWl{6^N#dTJ=M#>S&nFYIZ5Gh}PUpUe zY*anh#0RD9Hp19D+#G`N4rVxkUq0d522a*vzv)^Xr<9BOM*1mudD9E*)Pw$^dRLHcFe4-Z^|kz zBq381e}xf5CGl{v`eQ+Mhhyk2co#*Sf|R-hY@ed1(j(qwVb5_lng-P(I;5ho0+*#C zbZP@<0_!nXq{q>NA}uYTr{{>Qlbv0U!KjfvIs?2mL_3xCG#rYvO+ygzBf4>G! zd8l)x^&7#itEWtHCcpuBIt&7Z&VaC&$M5|vqPEURhS!@}gMMs2Dy&hF)PSC3-wgh^ zj15USx>S(s!%Q*)=oQ-0|F4%Te}w9b+hgCeG|Cz?h*Gv8B$UQZwy8-PL)K(BmJ&m@ zk)14wWGNxp(pYD*D@75b>{50!L-t|btMB{%3-7Pz-gEA`=brmnp7T5(ptuR9Y%Wk3 zt_FmDy(P78i(h-#XY+>$>rQs}V z$6p6Eg-pjsy%P0n?&`(=C}0cypsk8lUjG?{Fi+XS-vf?x~R@A0(?HMPnysl8Yod)uM!4ZZbHXgRZPoBNg0+k_Qe z32M>Dupr=cd?8(nHz5wrKX&m}o8a9FA6u2kwOHUFm2dbG5VTl+qc~)3vWTk*COEiF zsq}rJk1vkz3;HDK*VGk@*Y<)f&&yjIdwK+tIe3dCXUtBozeJpSgbM59Pp9Qujm=u! zu4`c{b(>ep>I(=1ox~O4-rr=F7qxMp3&TQt0BC{y-DE>o@m&1Psln*Y^X8VSJTm6! zbw7i0Gb1p6n#|gv;T*trThC-QZXXfxI6TQ^D$xE=Cm-hlWQMy2QPPffP>!clTR7Zp zK&eegO_%ocE8Lwoy{-5h=dM$KKRc1I{&A zUofkNa0+lM5K98$ASe`IN~OvkfebAGE_S`=i29+;3M&6E&IH0ipt=BXV#fijLsSzAWTr`M z6hfxq(|tr^Vtzxlc(x7X_t{y5uackjULQw%p>^A}vpJT`miejtocxl^S<#b&`D+;7 ziHXV8wa@)#^SqGDdDrkmb)t3 z7W(*tH!EBQ*%w8WbB3&Eq*5>T!mr-nUl+rTYe*i{ZUwLmJu2{IP28mp1DE+?&N-KJ z44P!(71epu3P8>*^zce%n)7kVkV-??mlSLlSh!wehs#Zbil#HxWQ006_hTtj2Tef@ zrtjNqx9uo4=VccAdXphr%V^0USBb>3!t^|wn5pq7y@B(-BM*+lX+Wh{!*>PXhZSL_Kmx1=_4Cff2OaL?4OFMhSi;tssyi( z9Wuu}x4XJ2s6|ytuR36EufLjK`oy`G|Hmqpvnrr?&HAx`?v}363f++1XUnVT03+{@ z596}$S>n?+mOiEv(>X?G-Lc1QJjo(e3+-y1iX~xC3jz6`oTqocvCqXq=8{nPd4Je( z5<;19FdN+;#>QK;)&&*G?w*)+s6@i|Y2MqpdR3v+{c6@@ z3kojRsKxZ8xr!8Y0EJEAOKk~yCm^T8@X5Z(+Eh%ZorS&!g$)E7O8FarWeu2pvt}*F zC#2MeNYs5!8X>LsT3b0i#v~iz};V|ef0boa2ikNYUE-g8ZdK+{gBc2)7|0P zmQ?tP{)9`aD>ta*&Fv`qSLb(ZSP(A%XT|saiw9??1t06!j|$(MpF%8E4Bjc-JG&np znil;mYM72S@p3BNV!k*jrpfKJL>p%_xV-XY@BEou04+2!Ze*pWJ&L+IU!;As0}Wg+ zS5`g)^v#itImJCt>?ZbUuZ4RU%<)2ZS4N~BDbve>IajmVAo=WOag_4j^ECk@7%PbL zOmW)iaLFjl(wjM8%n(d@*@zDn?R3 zw-Q!P z-k{gH_?A=0BhQ7id%nc`@waqEjO1CWyd&3CTvN>_EK%#7J~!F#b|>ge-dnR;GGrr` ziONxlF69b9F)#43LkS2oCu!o%_wTDe!S25=5yK(0_sf}k<*N8ld53OHwsI68Z?pd{ zyFmW2JkICeUFgqg`hHO%QWdBgpy@{`_-ISCxm#UFB6E+QCQ|z%#}Ii+4nFLMb=M!a zQVActN;2V&tMgIy%D;R^!XUor%+tqtd~eWS0q+bfRnzHXhsb%7BK$Cxjj_Ilgk_j~ zq!zjF-;8fxY?b$IHmUV_C^?9iAJ?~I#Kvxouw`!fR+A=qssgS8drykle~fTL4JL>H z%&Tg}nMHpJk=1SU*r?qpxh0+Q)<364pJ5Fft7s!ta2PW?LuemUHEF!KIbHKNKAffh z)4=Dj7mg6@26E=j4o`hD_wgTNM4n)3lE-SF(JhX-_t=fWRgv=h4;kTCDm_{M4#nGq zl=}LuF)_)xQt z$7HdQ=7nU(_SK(>v{(Bx_{y)yIL76baA{s07N?b+O!`$J-;-Wf!Z*n6KByA}sWbdq zjiT|v&m)z?Pt$hWpWKm|R@h};N!sr4SvdDmvr*V`(+Onx0rcY4s65?+3zRLq>nBv) z16eWd4bi4$y`(H({4|7IgLXRWCYlg~6`5%W812>b@&dgJDp5+O`}H(zQa_#!@sfue z=lQ*O&x76I&!uP>Dr;lFfb+P@FgMXfxFl0T!?A7_Sp>5{U^zy z9#nP$(IXQ1ZB8ANwc-)dPgpwHUWLAyM!-Gp>V&%>xsJR;JrL>C&Q4pv!9W!a)e3lT zDLs>wE}%Q=Doi^r3vCh!*BX3tqf;=uIc6`Dh?ZMLttLBDE7kxo1K@+^4x4{G0S3SA z?J(Ql*R(4fULlNL7w=mT;J+@y1VRl>EOt?t#3WoP+1D5*G4_SOhc{L09o#}WCg)E> za{(&XLauj}9nL~VYvzRValWNby5tv17j1LhK+M(U^-Q{BlrqXZ6q;Mwz?b^ymM!~2 z@vDa?2b}w75ROabcouGk5@*U6zxB5XZHwFnwKFG;l%p@Z)gD7H-A?x6`8Jl7<*qZM zcX>F4i^0ljiHD0wdWQ%WPE(tmqYf@;wrFX_`jM^_3wC^JI`Ob6O!)2c3io zrvr`rFAm?&tip~507KfHi=5nZeOT+opX>Azg?ek9_!)Gkbh|A_gJ;I9!{S1l4?3nj zupq*$T$lD>n9w~SIYPe}9h(Vq%%NnQr)b@1Lp@|F>599vcr}l~(lP-C!UQIhXX0(* zD1SdFYaD)77czrX7Y7IvY97LtKKtGeZ4ac3#^WjItEJP6<80Gm97CPiCo4OVp(7CQ zoTk1rkE>xu1Oiu0Mi{bnLb{SUuYUW(q^|_ux|@nh)X|lZMiSuJ5Y9ymTiyGUQ>+>^ zq^=vVPnaTrFp4qa&HQZ2)LMsKMgSS*8`i{6ucijQ>&h?*havc+<$6He$&N_SE_Zt3aYuobb00PDd}T0;0uC*3WspcJp;Dt z&=OtCXLwmdszj75)Ar_EW3h$~Y6eAT+#4R1v=@aE2reO)zbG zdtFhqIsq&AMi)Ip>ei#Y?A&D^xo1`pqXy!O@qB^YPF#fiCY=4!YadM!1DvbDQP(ow zgX~^VO5bi;_&e`caxKp_qS~XfKdlz;Yz&y(ux&+n9NiVznW1#mGqXkMxx(QnoZ4e> z1*!62b8j)|_xnMU%cqwTbaf^Q$B{2TI!l#Y&*###x(iVGS-|RMo*oEM#9Px5wp+r0 z_CsDo>M;DkrDFNnH-WZHh6BKs*_=1=YJF?YUVHnoC?zC+{O$QBQ^_w!%Q{}s@P*Qv z@Tk5nI&@=eV11q*mEEodUhdpikO+1$D%h5ua;PMtA7 z@%O5%&(=^`-XF40ut-SL9X{T|WQOQQTH8&H#){{g24*YEyG^uGmZQA*eg{o4YRa7(PcDS3E})x9_?2UjPE<LQGfkZ1`84e%B`-@JcdcT0=fI$61Zi)%i6si2@6P1wG;g-YzM zaE;|_sBq#S)X&EDl9_y;DhD!@p%2*qd@ZbykYvtVCP%k!UNJKDnu_J!6VZ~)V`WbnBnM<8DWN_O7=fp@H9u801BkK#Wx8JlOJ+cVKINfi0XE%T2u_lJS2Da~D ze~H7Yw+%3A%L_4Mb>j9m!HXBu1x9x94*6reP9A&);VqbXg;$|c$8;w+iB5u?+W6=P zQnSB={?EEV%LBPV!zmI%fR2XeA4R473b6O!a5bRHCJy(S^`Ew8_&*Md$Ul$-5d~}% z9M0oE@y-8hCrhcolK@OZ{-s_EI5aie2^K#7#ku_^`JGfgsNOIFNb%IJHgQQp2lY)j zgbVw;nW_UxmOxSE?ER~AeGFcrap2C zfxzs2AtxTLMB_XV?=8Qg+6B2Id;S{-{I0~hRJzl&X;~6lu1eZY3oeE+r7C^-Ho3J$ z!jPP^>;w*ZAyu8AnxV2QMlLRB~Kbs2No56F}>moM?nwuCjt>L)(E~^)@4JK zuKBiL%Xs(aqW$xZhI5ldzRO{ksGBb4=KC0uHSj0vd3c$TS>~cZMKDDJI708FmzIhR zT@SRWye!+gdLCQaoaG^lIjMwBH2>qB8A~TK-h9z~0$OC9YJEqeAm#J44?9HEsmABc ziu=CZMEz$rZjg-X^S<*N+H^xu(8AjooLpkdvZHiCoOqf(Ha$yID8*I_S^u6;)SR{Z zh~Wjdf~!B?ct)EMx7u_M0_AL{h9&;?G;99Wuw;?*2mYy+P*>Z!$pMTE2uNI1FFhrz zaRu{-1$QZaGt|Cz6y6TP+=HktbYyuR?p$l{{SPMwXpyI literal 0 HcmV?d00001 diff --git a/assets/images/images_cards/timetable.png b/assets/images/images_cards/timetable.png new file mode 100644 index 0000000000000000000000000000000000000000..1fad96e71f0b7fb8cd79cb8aba190982b0391dcb GIT binary patch literal 27089 zcmcG#byQqI6E8SOAS6g|hXi+bPjCp30KwgZyUP#(f(CaBL6RULxVy{XE`vjmVQ`(< zOTO>zzW2`AJ@2383?sMit*-8_s{YllyT80qSHyWj@dN|{;V3J~X@Wqgz*iLHV+`Qq zg|_uC-~-*`m9q9@;4kp8RRr)G%T-C=1GsW&r{3A#?!~#-5TWM zLhyk9F4X(jHxl}M?_c}ks z?O~;3dV~7hLR6TwGbXs?=@hPewd#NXwk%be)Sj^PaNEO!Ls z^Yo0Tb(c6DXka9?RTPv<9XTq|H7H|&H&er)*wE&nHg(1j_G88$guWQQ=)RvCZ`5%6 z=o9#pKuXRIk5fR!r$>3xL*u^P?w#rY}XQ;*@59;b|y-A(HBYc{iza^oiNM z~&6GLKX2uS0NF0Gdc4Zb2P%GZM= z4yZVFJ$601Q!V|rJ<1UVLc#rq%;!&Pv8*k3lG3hNn5r8TcWPc}FJwgh$58x`&TYM&FuziG30IY4YBjUR% z7C7zK3txd_R;Z=S=dSUHx%{VBPhFpSo&U}^H5trRfNtIq z@AzrL5SkO9lsn)z35{V;PpCiCK5uHxPR?DK+m+Il-|IXx8&?4x=u0+=4}B=6jMvz0 zeGkR@*!7rKQeNj3BGl1DLX053>M$rORJ=jZKa6mwM@LSZc-)x01NzgcQ zOcr3C9AC{P1~>yMP+Rd{^YG`?i;IRrV-<%Tg)Ad&eSz0JXRy8bTbi%^O59-P2&@IbJO&pKhzpp995j!n!^tlK-a)<#!%;B&uLA7A7prvNN$CX z>n02{tK3kq?ysmHj`p$cEn4d6Mk>NtX!7jx3b~I?q-fYE&Zo0(?pVRT?(qcRml914 zvrq4&6NurVFHA`2u1l8UNHn-(Y@8%;It-wg?ZjzkN~WD#HnZQW=B2h!*N-|JFqYvg z;Z6Y&3)yjND%~TyI)M0|syKH1sN2qEX>81&t?ARb(vO~LaGfssZp5hfef6rXQ*=f_ zB(AZqx3ufGf9m>qe`#wB)L@~r?1SdY>`KKX1!;Rfqc|^mO+`?ipG)+*e#uiC!n9st zroAXu)uE)h2OcrR$r4ckkfUCh~ zRZyQ0GE)q@=Q_q1Fuqe6jxKKT=L%rrP`N$_-oLf@m#4n~v@Yi1@5lC1pP(s8d_!JKWYgSW65!7J}4! za=0?%bSS=mtj;g`Jqsx@e4Ozi4;>167&h#*jE+LBOJj$huQ$k9DAZWqIC+bFLY>AY zic!B611cwqVfb2U=(jNjQ~?uiBFg0{qr zv4ebOWM890nVm<3LreQCcv=8G)oRRfC6I=qS;&PI*MXWu{0+41B_pnjM$iDJLB%L<@}*yIVxoO~hxbLcFs3e4=0$uYp{!4Nd= z$!8K1duH9DDxg1aWyj=YkDpp*m^RGpy^&*Z8DUOG4>Vs@&et?c0$F8-L4Bd-P#ax3 zb6vP~~W!YmoGn~AZU-I4RJE#s9K^V%RV^#6HOSRBn5DemMM!~>t`=?jcyAUeFqO2bnxACCJDfV3CvzWq*sxEzzFQ#Du?(2Q$uxeA1?h=-t^+e9OGoKD36; z1>NWGnveT-p3OfEQ58?uX}R)ol*SP`9IIgdhJ`WXWjkeK^;afrT*j&o6a=ZW4ZP2D zV#`@u)RyR~`{5hr!XLLz{`Yk3F*5d0pig4p}0 zFHciO$9^6m`nA~~+8i$s^Qas&BM31(d0YHZSyvtVJ0wnY`!MBbtgUYyi(2mm9o@W* zz;P-d&e=oktEW{E>TmahPQ%6;v`WMil`ITDDEo-|B#T(D?@s%eZ zjhv=f9bPq>&R~d)i*I-OO00R30b{qv#)ygQH?)BMoWLun9WYfnIX=%1lPJ*)4uoJk z3GdQLUH}VP?Xnc3ktxqGff$D8S9Im%x=~ObE?h7@Ktv1j|5K#+{{bTZ_ae;59=_Ho zYp4PH|LUV!a6O+gVkZN94XHP%uHdU8PIA-z)ym~=rD$Nh{->x>v|f1xJX}qe6ZjCH zD$iZ40-eUgaF`S zeGa_mpH1s>L=^+?L~(#LAk15tOEipnY{UqQQFrBeBaZ8GapWxp)z2gyPW_F>S?(2w z(JrB)3G5Ws!^q{ABe{Rw7zt8(wQdGg{%@7YAUr0l_m0OX#bO$t+1Hk&M}O-?OL+&` zhFm>nzL9cXU;(|FESmI&Ghz>CDc5@wfDp#wtPAz=Z!eeB%!X_XH#8qK0bDCF8;-qR zC%B&)GPw6VtN`8Y*)1U$tp^PSw3PpKc@0|yj;-hh{*Omp8>jEb2Jfv!=R$=%qSKpWkA$d za&}kC73$d|Q&{&B1N#V|tAbaLkPh>YcAyzowez*Xg(gq@Dy1Mj{`hWElUGL z@nHv*RE#OGLHvpr~C!GV;Mm`I&7& zt!Ucfb8WzL9qvrPbEBB$9^YN?@$uapF`zawO^3i!BHf5=5akD2^wB>prpl_QzBL|r zaY8OkIZ8aerk&LZDx);~ICVo?p1y$0uPs(>0r4Ns5rK1#P6N|vGPO1A5+`gX2B zfyknL!3e^6iRXX7{p)^bU*mXkguCc$!LY7kyY}!GXRMN(T&cwlc6)OBn$QLF`}&|A zvA;gwh4VrVM~df`X3gKq0eUe85P&yR+E)J*aw{(m#wxTXbR-1};O`(>C^;e?B-qSi z%REbS)-p{9D|*B2^^4{?Rh+fwJsOZ1%DE?;KeP%ju+3Q1Gvj^S8>9#D^mlm+2<_l6b(;JBZ>h^2NuwQnHW8AWI~F8z7A$I zMC((^yQHor1EkVQTz~vApp)%#QMX?O7^4t50)=IGv6COE>F65z8_}QpT_TBx7E+@R z1oh5*@)o|imuCp9ekuVv##v_+Wb`Py>UWT`mIw{K-S1tPjA^zXUvS;1CjtI|{0sxo zZ=}bJstYO6>2J^KR{QLC;FSi4e>vz9ewB)0@7}jlMJ?2-F~sKy668x#Fe-HJxnld7 zK{AVo?oo!he!UPmXP7xZU+d)h`s9W~lx2vRvVCzi!Zwfmtcph@HB)a~?;9hb zQazfwV&ZwJ3JB5l&D*KU&kUT})byCy9l7Cb=<>8}?y8j4DcLXTYIjP$6t*wDyKj;j zWjQpMX6(44g+e{f0`c;iAc@JCv1!eGt3BL#;y#&BsYKT?c;qaEdlq+Rfs(hdzm*iJ zqTn}j>x)xe_N^X{Wd#5I-f6q)Q*lHqmMwm{)WqJKKN;7mfV+Qge_vGRP@sl(FEKlv zPWmxK_j~RQC*&FbT5QLm`&(fr-gm8+xF_RsA5t5e^jBvc>S@6%deMptivm~0?Tp>6TyN8ePtf~tcNQby=D9@%PS0cv^olxV2xU) zS8stI|M8vWj!NxWZQ8^PRzZ=6{YXFLu8#ogLM|GI0*hx!A%Bq=m)zO14$Fz?Pp?v1 zS_g!{1%_+nHuAxGkQi_6a1lTV`a=ig;Qi37V6M`|Pdgh`9g#CJ603j4lWLh#qu1#Z z<20_%6^aj=zP;_D&H6kVU6_c=*+xd7!LTbJLb*+DC&Zf3xpnB`F7~O^+5~m%St)8t z#!Qavy5F0P=9;?CO+KZ7`SZEp>uQ*O5RTco-@w3x-6?fsSu3CxUUrBSNIxzAl)%$< z<|4wtpNm?L%fesTl0_7&sK0VY;^KK&B+e(JA<*5u&PJlGwq5dbKpR(6#+Iom5+NtY zP?w$vMDgWzTebJ>;gYL=Lc=L%CkUxUcK0*=Gv=lyyFWJRdTb>nivF?x!*~zlzS;j% zxvK&Af1 zaPzyGq}o!=##WL^CWvOPC6d%YIGy5SqI?J)T|z)KGhlA;_Rqbt1IBnqCdn5Wx5nZo zHkryk`|70kUn2TDjN)5MxpVj|G4gQtYl%kvjpKuBZFs)+5xD)WlaTeX+GYHxeXBd3 z8=>S4_dFQB5!ANCk~x`b3*l!@S~~NeJ&LBKI*2~gYP0t1{dkFBc=b^6e9!VCpY1AH zdQJ2wC<}L3;6-d!GEcord&&w4qLROA@3zUOeAw>7oQDl)3vV1dNjZb4f(>T@mds01 zBuY|16m}gva7aO?x=6RZ?wd6|yY?9~UBbv8|L9=}z|>+6IM2F%^Lsd`>r>E>Y)HjMn}zflYl=8Rjcr!&q|X7E#KQe%yCib2>$NTZ!!;R zS(V|zD7C0l|6;c*%goTcPkVa6_C))^=yWLM-Cuhd{lsd&PEmOKyp-!dm(}|tc?GBA zcO_H{Sf1;UJo@>dCbLyfnwUGFCKV=?Wf05fuE_sL-;B1rh$)LzvBrQJJ>OU79rUvK z?-RxK;7d_zIW|Dc*Y7qdt0Ga~J=j?yRRtQE6p9j!5!5#&p(6UfciXl=_PRn9{sz9_ zS%{T+k{thE@ulMoeR_S-Kqf0C|Msyuh2%$hOPfNkkuL?dB@cSliHh~cCV}kkSD8{@ zOXWOeqWbLc$zPS!_2`Pe;qEu#A=YaE7Od}*iF-aM|0v7Ml;!itqb&Yln%QBI7`W)7iot0`pD`*ALt(bY2 z9oSnKNSqA>TOu8+QKd}HyOVjg`&R@(JQreQhMDoQgoyeldu zdrY^#2tD#Oxd=%L@j+dld5^QOViKA3b9)nItR4)^->;JLc3tpMqMrNQ>X;RB{Tm=eVYg+C`IL6?YA)IOlclTQ@@>)!#bmct)p| z5(s*4?;Xj>@+2u?1auP$0@!{P{yUtc(=lv zjI;xSUbC}(Tj*vi1@K7D`_v7XUR<3IX3m?Z4C_TTxw=L)7NO&ELq!DTSsR`Ldj{Bd zgQK{Zw_Kc8eBLCUX$Q1ur;_KYjL28YeXw1qJ#Al!kyvO>_eJf!ib~hf z?6EDT>FfN7RolJh(~zdS-fubR4tAZE=zMpYg)3XSaf~e^>x#-VfAm~#(`lZWp8*5j>!KGT0OzjIBqrgRf2`CbMiSrQ z1cR+NlOk_&I*@OG1Yx_NVnx+Qz){1D&O*?z4=PItTKx4)e$!ZToF}!-9na;wy6Eht z&fh@4@#dw)&$wp;n6nri47L=M@oF zj~06^fZK2fs&`#@w4&H!Fd69P0o<Sj`iLg0G# z?y_dRDYUedKl$Wj>Ba|4jyn0AV0lM#h4IzkLK<2m|Be8m0YN+muit8#W5Yc^$p22G z8^eb9{_rx29%Ai1Z>P0D5MOFOl-7*&lcg4td`yig!N(qlhG7?{aJnr5MRz?7V}8wg zgH~_19)ERL;8))=@@E5#()s06ESh@gyFQe*$>2W!K*>c{Jb?|B-5|2pom($-1XAp- ztBoXZuVf}c9y5=_^MQOGK(srJV)HalM5$HO?IPvo=2juSp}{HI+61n&jU84tE4%v} z(wRI_!KMCOB9UWz4LotR8*JA3^9T$i_En>>*2GoXq`B4L z47%A*>g=r#E56Y<_xI}I@m00quLNLC?1C27K5Q|AHLVqK!Gr`~UY)CG)U63M2Q|TcTCIUNHL%)BqEXVb$HT`v9jh*Y z<{B~TJGJ-BJ!c&Kd4kdy@lf2Q`E!!BnUNv#2y%@`kd)9C0~1k<(Q`)yf*A@y=IvM0 z#8KoqU*KoL8ANJpCl`kRSbjYxfCkL;d5WOb@#1xgu0|Z(6-ht7tt=3t+3ArQ+BQd2 zmZUR{;ydb;35S?g%&*e0kBN;q2ulA>Y9@Kj`lWpDV%h%g%^=IF!e$vxGxeUY5m>_p z=Ne!01gBJeJi#lwAi~I>WYjGDKhEPN8*MrF#e6a*X0jr&jCgp@aXN>ugooq)Mi~|R zA`bq#*v^)F3tbAG!daO&d@_;EwaWl%N=Pk2(J-73 zrIbW@?nn3X!(yG3@Fp}QPmo&tswb@PanA^+r^f@hI2qOcCGJ{44jLegJJN^Tj83r! z`&`tx_0147%}|Nx0s`(2}3rrSfH=1$bcxS`F0)d(UX*@)(}VY zv;G13S`_f=2$ciU2b%{CMzhUE4Q}$~Lmv=h=6eho25K0kbnbO>;_LVO?f=10BM%Gc zU5|`J&#iii(@)Vy{`A%?HSNE90Ef#DW$e%kxAQYbBEM)Ck9bgyv%l6uHNw-N2rCQ6 zybtWfSqbkh=YbmH1(FQr>wyJS2LR+zJYY`cL^!895PoD%a?<5P(=`EDY1KYa14QJ6 z%VDl3uTvjvMiyvCG#`L#TY?|@njBbvh#=2m`G+>i^2kB>Rdf3Px|R1~PeS^^e@fD1 zR6%q$e;QfdJZM8O0*Xi*`T3s~eF3!A>-aAM{Zfto+=3VY!4I;TCb7X0$;1DVpw~VT zqY5m`cJLegXVjFs2YZu25nuh@<^g(jzcOd1)J1*%2Qnw~$ZL{>(6u-P{c71nir1;~ zp_uIjJLM(NUZwJMW2sQ?QK{5LA?{+$snwaC^n~P^=|T@d=W`BEPu@P zGwklYz17QGnZVUq0^kP<3%9qH!Ddluzr6l9Lb_@7+QY9h)1ob9NYiQ$8%zL-myKrs z35}|PY?%hkR8|&$F}^(-dVWK%@deU<~+{42%B$a z?ktiVSiSU?`@%eY2-yg8duLJa+hb}F^wiz6O@d_Ze~1qPjv(MD~PRQWpd0w4Uff1ZbN1A`i&WWNw#A%WD9 zh8$9!2_IH^VpopDraTS_V(K)_Ri4=%&Vbs&@q0Kj3_Dq?qJD6U40!=`J{=ujwQj&|5p`Mj_1H?r%Ec|ugcPf1hYYl%bYZ?c7DGXb3+kkP#x zjnRCUF?*xmS{dR4*;zP&Mtertiy228_E9yLZMHR4MlBpvNJ9BqL3FoL|tg1VLLSjZE!6) z<{LCeygkYODfHaclO&x6BaTPVEc2)4T-X;b_-3>%!S}qSCm3$Jj=k=YRv5TDt-0Y%H<z*Aj^KAeg=otX-=EMPEKMJHvbcj;6Z_zW5YtZmV%khM%1||pw|`FJ6l5C`8gHa2ovc_y z5fR_h_6BC0jE>i{yKoVpku|9gzi6O`D?*ucgah1*-UnM5kozR=)nh{(gudNkY)jx8 z@;(D%gyb(?rB!tRC4nA;C<7K7{HM{*dgxeNTG=VqBXwZ~!acK5k3V(d2VXA+G+dpy zRIT^SX5%U<{Jv|b2|WJe;x8|Jj4I{mvi}RZ%hw)m{o=KNapogFLBrc%O%C)xdsERV4dfQ zOYSw6^!2sz*`bSiA8%$-QtBbYIEHoO&`>Xef4pNtd1_t6I_A?Kd%(1eOaDe7t zy43Ui`ZZTMPa$W#(fRPHL&Ihyay@zWOzw4l0DMdM;ipB9YLNt&-2)V>HCX;)g~=a@ zxX1)j+d5oRM-@Z51{RX2(@E2%9@}!H=pnVFdN{rQx0n+-P$(dP15LY!0h>=A$AE*@0zbkyA4jaagh%sDlRpzi!uS)Ksv zm0LE32pQ>{1MiL6E3!#nx|bmmCdb7n-d^V?TinQm8V6x<>PV}GaN+v;buM8X(mqxV zWbi-=x*6%f2sljYpapc^x6wQ?sb(oMEQ5URZ8M*;PrpIcvpBgBB_y^+Iz62ZghNjDs~g$Bsh`tVQt-ka#11UIPZ;h}*1 zaC!|3gJN<@WuCyfM#fs{{{B`CO_>W?^^x7S%W7%yulZ^=SQejKr=5*@X8Z2jE$w&7 zTJQ8#tmRp^tb3ADiM4bn%vAO;Ze$;DlILab?r!YZ47r7iDy@st!q7hD;@tAo{uwfo z9{1NLK=5Vt!B;nnNO_u_tCs*5jApjr4vxR_9I~**V&kmZ*5JG zy*C`hkFP}5=H@vhyh%Lpa)&nuEXnyB6V})1$kuEZk|Q*0c3zV4U2?#ch>sq3>(UxhVmIR^Srb3*J!F@O;!dDVd zW!@bh=9?eK7h1d+HnE`|vFKdosIx5o1@D?$mwRL(HOI5zLgUkkrot$kLC5jp%S$); zB2jph7sU?0sNqy1XwPMIB`)Lks3PR+y-wXREVcv9f*c2xU$guKHk)ydN93dD36l&( zk&`jkWPI(e-Rn1)k#2|#cW%t|<&bWrMGNL8HLZ>~h3NM$iE6R1s=2Vk?mxEpthR?d zE10*SQ~yyMvr*gupEL@*{WTiwiPjtl>uG}tOuzY5*e``X(V#B)`P5UlO4=gBTQD;oRZ1jaD;7WaO--Q=? z#f*1|YePTV*zgp%3MTc(z2w$%k#5Vu3~|>rIXJk44~;?xhagrb<{Rc|*3BIUv}gA; zu71e9kSJ&fSPv^$8M`@4VZ$j`kFN##-$pSB43d^sE*h0w8ZdI{l z%J-trPAeq$ee=BtD`ll5mbpk3wWm(TyVR=%@O?cY1~Xn69&)gMiMLxQtJ9awghPkA zV+bvRvltVZ7@OO*Q{EEsNO80~dwWup#>c(AE@+H4j2(adIOCag^Gu&lg?K#aDzF%O zNa<&OZc;2eq$GelyA0bN9a`tey2^p^8xn$r4|X|n1;ZN~uFI^?dN53@BAE$Ffy8*k z#pk!@&0aJ+U&vGArYMBm$=k_o1q3{M@yiyJKnZZl)jLR>+f70ND;t-}t$!P4Wb**} z^UQ04WezDS66B>_V?mYgRS(Z9V)|#+FLJVoPG-c~c1~Pxy5x2qLwgFZ=(W)7v=2!9 zV3&vXysz^vcv4Fi7lCPyb$(n`M_b5hHA)1aI3UH`OpKLux;r!sVVEKXR!gg+X$?o5 z+HU9|lHU9~*#VjcAKQkKsm|D=@}_d{KO*x7Tbzt)OTy1XL=&WgU_|x`#NyPN24a}d z$fl(Oe;=i}N|)EQOQ9|`qII#4c5|{T#;8>8uOJA$G(%x-W+LHYCCJ`4>G;60#qqA} z)so^mNuSu0Y#}cyq|d&t??DHxdneYZLZCKG#+j7pHUTZ9k~^U2hJQ=_%wy&b*W`AC z3W1pHd7blS+f#{kaS}~;X)9my`Z&?a5)P1yLN%i@0{FISiZ>2NYG}qwm0q9Wo%&ha zH-rOTYlvqd$Qjx_JAvTWwbZd`9%RU?Q{e_AY}LBsgZ_7|xg9YxDECQ`Awk-`(U)h% z!;Y3cFq>m&g}SwRq&Q5($&%9O9No3ma=o8yxE*yj(+VwM*1 zEXXUE_*~Qby2hC$)6T)dwW`y6hA9^KrIWekq5+qKQP<7raBZN;Y{Nt5k0I$fx$J0| zeUEv|alhG6>bq{sA>r)2FnhD~1|LjdYVZsF`UU=0H2s3#2JGo|o$9s-^+<%bw;R#1 zq4P@vZ2teYHE2Tu&UIc)@p^dQ+dt$cJdwn*{7KnuLfo!Gg9& zbA}V~5a503OMHpuoTkp`FAp@W z5_p}zJrglo7!2Bzw)ZIUjJg6A#w?5g8_&7A|EM0$%aA)e#2s?>9ueGE_k&zq>~Q}+ zXVbV1(u^i{+L`pzCg-Y0AoxCp5MI<6Qpq3uPCR4}U&q_kPCae;hbu{jfq`tYbjzUt z=A^*a1?m=n4Tyev8D0;&4Pm4h9kspRfn*P!#;tbm71O3()NtvZxV37Apr~IK_a{Gw zcMvw}pVsvZXY&s3xrS+?-j#VHG&j(OpCy6Ffc!_)=PtgeI+^1MRj`^V(A~Y9w_8Eg zhxTq_(JzC%_deg9$C(z_Gu-dY2i+ds+&AuPC>K^FE4t+L7E5IW8-G^YMro`536~wB zO9oj%KfRswYur=2z$TMs4%FW;0Jta%6YIkOMCOCihWGtL&4?-c;x6Af@aj-*@MZ3B zW-4OffGZ*HV%~Ung%HCu<((2eLGD>q=>JhkdQEGQ-*F`{p@sveJRUh z-GU1lw-eF($N6^0?C`Eoa%$qUl?ttblccC&n5#f$GD}5~z;vYoqU}&H>z4tA+DGE~I z<#EDKljAUyOc{;NJYqMr%^12mHEJrhc%Xo%4*L6-ay+G-oSd=*I>=g_<}Mv%7oYpk z(kSdt4X_a8D*?w*NW6YZ@X1ni@tveI3m&$+Kt+$UeoG|YvJakkQ}~LYn<1^y)rZWR z!-fR(<|c+`%~!6)vZC6o$CrR(s4egK{&vaS89vDSI{d42YYA(+^aqUlNi;J7K!EXf z6tuPG&Sa0Mhr4}sLG1L^BRpsaN(>+{Wn6@}%i67i1N&+)V*X*jfU|Gc2!`ci;oM;M z?oLQK?(w-p91s9ysj-%2C*czM#XAB@8~(@nO~&3XkK2x}Y_i=Xz9Nq5y_&5+0&8QK*ADkM%yl;)ZUw3S~Nw)9vJv3zx;rgJ2$c#V!z<)fI&Lo4+84OPzB9^8a$|UNS@RO z0Swp|R{2nyH{-cPe@I~lIf8L_*Ucs=%eRu-klgt3bH?DuB6|8r1Ff5n$Y6&?_tWi- zq;w|h*M*HmFV9Y z2oF|rI-DCW_whZ()LTsO!|B-<4K(!gReQ?4Qu*oI!MxepBG70G69*c5bA=%g6AwT& zYCW{}qGEL^m-rphq#_d&c7ywFI-L{8rVENUMmrF=(~X!K!uT_BH30;JE{i2^U1QvG z?D}~-dRayg8@j+3fY00m_)MZdIP502lS3||)EFS2Rk)hHJzqepgds+Vat^&KlKW2) z6Ep!Z90>nJ`x~tGC>d|(glx+P?lT!^%U5}fPW`Gijr)qW?r8Evt>7RQd>cbMQm1iT zl|YKSs*&+T!ym|8V0*P?o9WD`X$Jg@=SN+Fnd!@kXGV`WhO5o}W)a`oGgl037Hp)t zE{nfOvpPbMTgr_Y;#s&KVXI`DR~w2_W1Q+Awv4$?EMN`-@&?KWi>Fn?TEkfhKa6xd zgaoCg;Z{+XoV%L=v$TD)&cQu_xwpVjmE3M+gaUSHJduY_-6hQNa;43Eqe(+_ofxt~jLgOnhF(M)HPrDh^$)I`X_)B} zd^NuFbVEWk+{L0n$6LVD?>}xU@w)jcoflxEvC2CifWs=`IOz0UfR#Ql+s7x85CRBIDHr2zh0#qTV3vRz!R;r z5Vi4qw2Fi|Of(h=&)C+l+KTJC-I^>HTYr}Ow7SeQzvmBzOplrxr2mZy*8nB#pi0;a z(2-~SXO{&-Su@O!4$Zvp26w{= zuRNIhIHLn>gE?KTOesdKCHeV*!siX;d*G%lzM%i237)S!3c2Xg*f_Vo z5YQ-;mT|r7&wNy9Z`iN*Hb1SndwCS%BGNJNtXy?V{>Lx~oPy%G<`d9h|Cg>j+fB?i zR{X>JLO~+Gz}M_$Yr}4eu0Zzuu#S1P{E>F;xu%_WYirDC%VF$U&?df?e)Dcgbh%ek zUO(oks;#TeIlQR5%1Z`IM(Dczi@6O=io0aa{Px2{w=S&nlYXG9eKxv>{zrx(Z+rvs zdzZfqnyxdFM@yTV+`$R%Wzzvfx4y;xI~$e|MxwZ5#~n6VI8j3lLz)@@EJN;K1^QyajhgokCpazbC*eg?-Qkz=;)8~KF|){vNBq}1pZ${GGaZo}l zSKt2yLdItDPzujC{Ax-t0ezSwr`v7IgD+CK^xc{hy)S%C-793;70H{84pq(@(Bq(^ z>pl0n__LK^$J-dT)^Ij;84QI~NB-9AMoL(LO=zQ&j?{6+`3uKv@Nfi4ThqCcl9>G+kq zW;=2;=t zOm`ly)!d%Kq@AANNwtg|m6Of_cIGwPDD5bDCjI@AGhKpe7sm7`Ihk!)>Sv1zD&M

MGu7bHKV^}hi>m{>v(gXd!F_X|2q2Xh0^~$IBSq?y<7_n@e z8vsd%vF`Q?YZ@K9SN`O7IyybIyNR~!vexBi4qzhTB$Xeth+(uD2$}PB3gRWPj^eKioRF zg#bj}T{(&2x+pE^X#jW@X3Vt$0eBJRmUKhz`|~oBrY~<;EF5xYjf14D^bGU&LdYYT z$A>0Vour%cDMakz_J#?;jWGjcvXRhR23f6s0d@ci*E+8{1mrSv3^ywc{o-V2 zc%&NZW@QMSzeSqeEmoHY;~j(7yyfJ=etRv_EZ$NHJ8SpOvY~v{eqBcH`fbsN08~|b zej|DOB5{ELU$lS5=>piQ+j^yBR6eZWR`-jC26>8UK}2w#5&l2+0wl{F`>)rxU^VB6 zd_nKFpjqc79WRLr4W?cDIwKpluIlM_fN$w{e$FJ`Bq)jE`)L#9WultBhTJCgqN54w zRr@1m>p&-|)%(ld+aDCm8p_H#>J!eJZW+=iTT%vl_IKOdSiK)FKE7bVqW9@ihoD!j>gPX^bLf0zZa8bvM(S$C*^y zuO<2dI6V-DYQsDlqFA|@FF zI?L17jkgcjX2{P<9>qk^yfE2icpp?$o%#hJ)VrM!q8ywfcef(BGe~4JkkR}OCU+xr z0gHXZDxY6~%rc?Zmx@(sk(?^Ot2`9{ONtVXVmLDT&IQAQsqTFfCmI?D>|hF-8wQ+b zh%Dz?IpDX=+l}h;t1mPD7?QDa1l##BiaWUw&{)+q-a(req#IRs|L$GN`k*UQk350_ z)aHN7itt&cFTzFK%7?-P!mfg%S^~ta=-YmUgYOp=Mlq`FK^MP%tzs-$+h+!w$|#l$|J|7=K-?N(mu?^%)z_g^gp*58J-RK>fLwn9=`3EFjiaE>oz z%tN+w>dmT`jdeZ}14DJM0)0QZSfgBrRP;8sfL4|KxL#c)T>IIRC}B% z+(xApFkK`Wt&FBVp${VbksY6J52&e_Vj*|V9J96{n&o@3eKGIF71*yJ-W0DMk+R{R zFZNmj%jISm9JP8EO|bP*W*9+us4nj9VQ6%8>AwRo@=8R`aU2%DQJ3xpC1>YL9z-7G zGtY=0?Eh-sdW{urYd?-YT56#5xo*m?zUT`x!P4FKM(jEAn$!H^=#NWP9++}FnOUTW zKuX|6$B%++RbN%qS|5GfnJLhLG~;n`N;N0lBgQ2c7tRl>sSC?5_~?$W zgV|&Rka{UrXHK_J)>n9mny%hZn*23!5ipu;UTDpx4mylIhy7obeRWh+-xu#4Iwb|9 zQ$zs~kdARcL{g+gS{S;KZUq4;=@teQ5a}*SVQ7S*yQGF8q#5Gf@9+Kp)_Q;4b=RrA z_u26|=bnA;QTGAiuHgsr?v)7*`g$j?!w~v~E2OXZ^_^0H{=z|1j$aK(a3b85?^IR% z_ZiIGl3VJf$v^Xw>B)Aap!{t8HS75I<;Bom&;b-(eXriU0LirUUJCECYL?HgIONJa zGwR6Hg~rv4vweT4{y(SFc5dzREv|-hs)9rN9YQ^Jz>2_@H+k9#k&ThVY-|f%fzS{uJVnveso;`rsESHyCms>tSXi= zzQyW{I@mt#_06OW;Skl4`2AU#ip<3{F6%DbKh!&}CHo3KyE%8{l|><%^|M&-U?dzn z_yYfpJT7qHXVy%99ihxxUhmlk9p&07zBMX4JHCk;F{tW%#G(ntV8ONF>`1R)>`Wr zQCil(hn^+Q(eQw{v$>C{VZtgtHZP--iItAo>`^WC$l-g z`;W%N&@qkCzl4C9{;^11KP8pr@H}soCYJ#M@rk3(+4L6 z;TQIjKiw*AuZ@K_)a-CKMjn1cmkef|>3geQ_+#K%;yd4>=Y&u*YuTE>B{u6N zFfT}-BYXK~ukHMGixW1L-Iuu-QnA0=eZ8}@4_PiNQ?!E z?sl^r(J%z^TA`9I{Ri2!yFO$v3TDV9((p>?hZ;zLvvJb?u)U!Et)g4*a|gnaEfz_S~MUZOJ#-#>x_*8`h( za_Hi-%+AQ#4VgTx{2lp`G(fO3%SGU4+0)YQRNrg=fSZfDlhhb7#~BN+)H}R@$4Ti{ zC6wykGp+Pr==Jil*`&i-*UkD$aR<+CiJP-DiuCi`wLhS6<)u!kt&*f~X+smm9BZ#7 zwme-t34rCPcBVT>c20v5-@IRj>t)`OM{(bbOmU|7cMsh!uChb~_BRLIN6h=C4N}e$ zhw?@lq&>yv7BB=ZQV?Y)s;lQOEGXkk#OxA0u=^AR&CPM%GS$_D)a#nmE<=Oe^9{?e z7Qv%%;fh~e^k9N?9H8<}_ewvZyXv~CPr*uaK$ zwI8_-d{Y$%aM?CT{tHhm%bPWQ_cqf42R`rlkN14}TfUmTNUCJT%@Tz}xPvl~(294; z7QxRsGqQH_N^*Fy)F3lMq+GM^)@t}I=?l#jgoqq+LPUdOdHCuc@?BgU+A6yr*V;cN z|0i!IgSpdO%g`y_GR7Ev^Cj5fC8)yU0C=|GQ-o#VXyUE_wclKOA}|U9A^=Qd^0(ca zk$JzddA@#}SS0XLmLv1E)aUOa^oIxOx5I5Cavz1ue`$JHHj6JU!o5IUq)Udf6W-1lRL1?M`Da6aJd)irYY@tLkx@B3#%rP8UlwRULF zh1_3xlang7`0w9ue1>V!Y2nRNJ|T)IiQQFw^9hgJa>=?eh&c~}n=V;>H9Y8VIwGP; zG$^@g|ISTrvp!=hDdRb>{eArH#;m0aZjJt(k|qZQtZ#S0=@P980T~b$E0tAuOCYCZ z{F$=zjg(R&zFA+@$$5aBu?2;HAO;@WBO?`d3ExCLmNxac_rwu79Iz`O%YYfUVF02> z@&DxgIpjMCDjuMOF{mOxYz^Z94+JLKIL&10aUu>3s{Hdm4={=XHmo>#t%7-!oeffS ziuI&`*$l~bTNV!x0i}HjNWc(l><5Gsa3YRqu1AkEE$!c*;dwiszFR>09t&`>Q%5ZA zZ=#*^SOJxJK|hZH-X2l_r2F=KsBZ$(rbQG_sdoP#_I=b2&s2bE^wiINjlC1(lrO+} zCFbO+t;c#YH{U;*!yp0xeCiWtJr@j&9Ey~_WIHS;_Ioq=K{2ORw)m9DS2ad`56?*r zgWgR8e;Usso#ErDC3?o;l${K|WS?(5E7^t(3$WAoiGfuHI{&iu)6?f@O)@3`czssF zkg;liP*kQsgfOX3jN_Gj>N_`%GrjaSc&Xf3F$c-J0OUC~FA%EMD(+; z;F$*tjHuT4Ap_w-U+09V`1agSwI;~#c)hZPp4jY5!qiXfVz>ZQY37p3YMu9Ggknn2 zJMofxlSQUp+yC}G*dBr8*WP1$;B)!dqj^_8)00vJ!tT60vt+63=%@N$=N@YJX^=UL z*VmmUH)jqDNU?q)D_3Rr>Tn9Wl2@+Vk7q9j(ue`zBH(f%WzvZ1B%3CbvS)Pdc*_gd zVR5Hm7ur~65fBK@LI#EWP0Hu~w|7%x!GqmjUTX{Ya{jV|ahEJATs~~vQ!O7H4{#_- zOlJxha`>?{RP~U)ndxi=CHeFT)y0*Z=hKv`lK$?=OIgv2<}Abgjd^^D1yD#81soTuwLMeeAZl?78A6H7uF2MC&J|Yq|GZDKF{+k=0(Py&@B@ z;TE{eC6cLkc$n<+O}S~-^3Y)5ZHQ(@! zH93p^O$vM5@|F}YDp%hY;#u`5wjHz1X9YwLFZjs@Cv&7$*kepQ=BVHD@m$5-&M6?>cY{jT;X!bgpJzo#~~ zOXKi`D@eu_Yl=?kS|kgNfkD3I3rPiR!KL5V=_m1jb<4V( zZgK-0#mDa+sU6z;ztIboSNS-=tM-*C8C|ndWU={97yvBAlgO$rcQQKz7Ma}#pMGZ0 zC|v)eXRj)j-h1bXB6pKUA7Vc%HI;Tj_w0k~zl*|mFFyxD(}k}|chEZ?Ea*d90SM-B z1!*E2E(wo1tV4~P{w;;CE~f9=Cb5hg(uyYu`RqH`wIFZge6CEaSk6C)t8OaE;PD$> zv6PWJ%7wmoD=V~SbIVW-Vb9-BU);U^IZ{u#*jhnW9Y%xt_ENokO&dHJ0RRfZADyl4 zGX9(yg5;pkXNOkX z;qvx8%8I_NbkCFRIazT`^v;guk(erd77Sa=1&SqiUVFswtKkMC(_U*o0{n>f?c1k| zlEZR$H(_fyJp8ZGg0{9Kmk6rj`i~O)X{O|3X4=WZ;wHW5<2!z-N{S}; zgZdH}CumPEPD2}!3W=IZa`oMK-wgTJd3aEd1!Bg97AvHAdEMbi8L^2e?G4+4Vf52M z_l-Z*ga@vAQXUf?T5YH6;&SV)eq|FL4#pyuY={0-{X=ctb(gYa15(e=4iC)?uUQw6 zbh>4bUu2fnJa3^DTPc7ac|ZX)zO*yjEW#tHCgpAL~;Y*5S&1}oCXmOs<_%UFPs-}vYb?SEwF zy$6SD-u}@zlK-s*YzeI=1kA|$i_co75vXt|ej}Hv6_<@2(Rag~FnLvaAKDosFR$Jb zz0q$@et!37=W9((`>Bd7-jov})YNkIKj-OJ`pjdJJ+~J3|K5FS{^LdX{=6VI<8+Z$ z90DviK&*!c%cggAz;MFp8|c1(-(Pke{(=|1$X8MPBeMQ9%o#304E%ZYRK^rnewjb} zr{6@ou6@0Tqn_3qyHVSB?9QLT>odOujq%kD&dO%$OmT!p#G=b3bM7?S6~u`7$;jNE z**3*4OjpEIZS+@+$ERj>1;NRQ1{&YZ9Au$-)%!^X8c)Sj(RTO;m;N$0ZO&`@;w~+C zE_nZX8o+3}Ko=v+Q`!jYizS6cY^kWK{@q{-MC@LotOcy5%9aUpFm@zMRTW_uZQK*g zm#dnUfRO$D2taj($BT2nwJIJB#;`s8WzXVd>GxW4aZ|#4v(fKHXb$hmV&s=h9_|sVK zVp|}}spnSVwm{3=g))tHD{~DD;Rc&AGuej!h8{${B)})3+OMh_YdpM+N-}P1$@?TP z$9k}D3o?GUi z0YODO7sZ+w7+e`d-v#b|>?Sk_Za$e|D-G{ zT^6I>B+Q!Hc+7TCywR!_D>`D@-Y{MHu`(>F#XZAA%Y%w=%>G9NO_`vbJJPBA`K01mfKQ*~{1nDFK@AzmP*V0|v!~f)6*{9OJ|C6x(kb=2Xzqqp9k#GN z=1J$Fc``{LDhnf`%G~2`$y&Fpoy+pCvmvM9ZCl#Ijt%JrE?wyPerIj|(Fpg=)N;D1 zrr=+#O*s2;!g@Vr8&e+}>1QomueSX`0;=lOo;*Je3IxTYsj=U|geUoCgyCscWkwB+hMIDWp^G=2XMU8_w*zf8e-KeTP&%G zz57!P^<7)+8ha+QffeT8CL55+R#PRI_{wN^?IG`^I>*5m)scSPP`>PYS$HP=dnm}S z%VhCEI?X{IIuq^X>T6}{mN3pgIo^qPtnp~MWH&^|*Y3y31Zo-e)+9lVPNTweWv7K| zK1n`7O?CFk$ls%ji|hRIql;A!t)dp=HPAH~$r9clWC)(TQ)c3=^t?lI$ye>Az?FCoWM5ZK0IfWuxcp%eVx_2r_*0cHFwi~FBY^D zNY!nbWBR9Ay_AYLuOG@h)$y_4N*VjHuyHf_)%%ns3)LE728Ya%W$k#*;Gz|zU@*BI zPiFto;yZhJ_WZq4&tSjv$H!^EdV5Fj2m=k+5dGXdAqoB_bed_(|q2q$j7Op@bW1o~M-!ALxeDft20_1irM{TaBl%1Cv zcv8@E3T6lG*&6wGm`%U|q073%BmxQ917!~a5{NY8@nciw-C|!QQI8G%tCQqYq^DwE z5GbNeL>9X_2#gnhbYU9d=&z!%whT(nD^~1U%(w49Ou3dej}8aWU-NdMuTV8XmPwQq zg|2OT7AG~#41K$CDM!-{e8mGcTKF=wJ1?n0=+5l*@7~CUo|CUGESU1J&^|SGJ^-0q zJOJcY_H}jZ%c;0lwieoOg$7%--Qd6^^=hXI{rdyrW)3gOP>xqMb8w2l!aOc+e*oBe zzsh&^cYN1d6GYz;2hErQ)os+zOi*?Q-u}@|H@14Evqflcuq#E88#a-9*v|LKb68ee z@&h{w4Q|Ntm*HO;%-P!Yyx(qUIYJM)c?`UFDl>IbUDFJ2vCjPG-sxo)=#1Lb2>!S! zldg5Cp<_oWpLq_`c-yBb>ZL4+&MXF ziYt`pBl7k=F7FB7E8`w>ldDZKlk++0EuSr$Q@ARPd+66%!<;dvobp>J|xCkt=!;8Br zCW(6d*~rKZBcWHiPzDmD3u$w0-i=w2`GFUlugv83mwfVsO{0T8rHqav6mq;bk<821 zXy9>AzS`$!rn{iemx-U^_yHwL6caJR5<;{lIdPl3gR3b^>dR(6F*|OvZmDzdCC0r( z6+q%s4MKm(ZsA~5(f?l}k77%M@3>1D>r*4Jv$ezXhQDR>7uZlQ4-ew;rwZy8md$tx z>X%bIcm7T*KU^>!_6U3YuOEFBEjrd#+Xt={e7QCFA-OEJ3gu16CfA#&`{jERbYYYP zN8|b8sAhfr33yH4;VJKx@8BD|;*a~(HmA16IO zE9j8@h@PKky7DGaeq7A9+(rJ+Y1NLYCL+96mEjSwx`EGA3c2m&NxvK0@%ur+jAo$L z#!b_mQUf?iVwU3#;{rLd4*wK){XqPZN8{(U*7qX1Rt{<}mlGGBY)tUS^d>qCs@oMWrM<(l~We}C`r~<>-*g!zsOC!9Yal*m`>QV1l4$LwM9?S!KnYlYyS4} zVtQp-k5X6pH_<*!l|21+lrkyw%NT*F+!GJ%Dooow8&}Hp*2^K>bk?~H(%B9y(314K)r(b*c$isONF#?J` zQat@?;)?qUcCRa5usVV3o|ft$NbO=>^K%h_Z4k3ac2#K*uROeD;V)k~;mcV~Yx=U2 z;mh-M>lL06XqWk~EAWC}NjS=e_&|ed!-zOwx+WC*n$;DU+#MAh@I=GjsR()oX2iv+~}Z;t7p+=Q3Iao|c(72MahTdpIO7y%buis%p20PJtg zU!3X?Qd)h^P@?!|lClgt#CQd6*IY_scE@?4^V-#sCeo6m%z6s%8+XW4J{b!<9oJOm z^(E(F>)DdLH(P7+V;W`+bMUEp{TdBwptHkP6|x9K*Z)qVN~R6G4CL+PptFhX=i~+yKZ9R6X30YK zidCs#TlzHvzghM(e?)d+pe2*EWxsZq1+m?)F3+SxYL07iV>N}@ZpNfDfn3nxPoV3x zYy7#M4~SJv*5byA-^nlyEW>H&$5aJJjhk{4h$68x}>At zvS~Z!|8ivn5pT6N*Z;nwGTz%aoU6HC#ys^T>Q1A<``#gLao&$5CGV?*QGJ6IIIpw~ zH9gd2b#*;-bS7V!7<6@foN!oZO-%^+TPgAUu~A*Fz(4JhrZ05VKwh_PGwC_+m*OTc z!pdRoR|@V~P2QTdBMv)zTk*?Wz>Tyb!EaBAfzkCEas?)4@0R}wLPz`qCO|~hOO=Qc zazWP6gQ;S2^7+AFu*ac6E7kgpiQ=H~fAuWCcaEd|jRF&7WFkG)2?K3^XUZ!B5v?#J zMLWEm^nZ*cz6+Tu`**lJbCYHwr>_`I@2J(lv>@1Qz8R-XAFQG=R}SI*^1XqYBUD4x zGri%AO9X4LtItW+NgfTx!zf+)F;-%rSkm!2*dRDVRwRs)1BHLQ03`Mb^A_Xy^v|f`Qj2*Qi>FoqTB)k0b8~AGZbE{%<={rVSI(M!p zgk~^R$X#_EoZxs{CK7dgf?`21w2j=nJwM_UsTNnZhh}+`dQW4j_VtaGi?{)X?7Gx; z()IvF&ogxnMLdBS_-c@xNcGeEOi}m;vM!qZYWt)~c)@R0YGM?b*r(M!_+Uf<8NY-M z4QXgnGHk(JU?sdFItIe4E^yolFLfL!zw4}9a2rnB^S8L65eChVR(^z8$t~QM?;#K; z^==0T)-zV-2Iua%#@t0a8fyAKJH}dOMq0NeIYDsUAaM=Grx(Sfk=(>Ur3w?%0qp_N zmv0S>;Izrf4=%lX*C|Z1w4X``>DB|*LL@6?n&e+m1Mjj?o{Y28!HECl9J+CYc}w}G zQU3!pDS$ZI>p#~a$eqCr{KhRD!nuN+lYS`!J5-ElU4*axh2Kx_2&}~>x*0<7g1!INe1`$T2s-q=xM>d z4fA#Zn}tBSTKK(Bgy#&Hg4>WexbrKcIP;f)GOfnkO#48)(0@{Wk0tO9h9So$gA9ZY zh6QanZl#vhsGaRxL@JomAZk(J9+&ygaG;!{p7&bty;--4|C7nG%AcmAf>&D-8;>y` zLcFYSHX-y7dYq3C_ur4A1s_+Coa4M9qHQ!jeOt@Z4H`^juk8RHD*O`FlJ-i z1L_0juvkV}-Ukfc)`CJf0+dF0WbCI+xYzAcflVuqJ)3uv?NmPpPy^KIs7V%YoCaKF zJ);=PRWMq-tvxlNW3luE15m|9NhNm#l^TUtLqHHaP{3=s`j?+#ap1>Aa>iuDfI{C>+aLUpU*L&j4vINs-*- z0H(?>-=NJV6Aw6a*DwsKxh^l~I=v(bi{J^YiARsT+M3R7Vu*jk4MgOl#27C{Txvmm zh){43F64V(qHP?ZtVRteVzcTvY_z|WJ)>iy;-ob(6FZOzi%l+$qKZ_<2`0)yO)_}{ z4J^H{Kv7hFqw}WmPKO~qC%TCs)Icb!hT)54r)9a^s8zdAp{m!*cg?87Vn2e7^FWsh zlP?sw+d%C23;_Y>pi{Z^g<<<93kgfif8_$;&|5V;pI+o)ozoAZHXolh7&Aw zzi^1mC|E3U`R%gA_mc>3cOZ?pg_J+<&x*ED9Hka71j>+uN(rrN|5H9n$DHs47Z#V@ zj$=kw@dXzC!c`XbfCmEo&01J0|CW-0I2w38LB~y2Om$9;DQE+2ilF<1$ov5)S_k*p zvC$@yw>TXyRnSz$j)=dX%AaDU_{v@ob%83n8YT9tf`=@NaJ@)CS@8|e!CiUTzXR`O zIdHha?jJj{uRxcXYrtEf+1Ci)Eohh#zk0uwuS#%0jEKVn;@@P|;RKT4ZsHU|=)OOV z%s<3IpKn{4Dk8c{>$o{q!@(-kS#|u&{ALnD3=(&@!uYkB9Rtk>4_GP~&l%q+A@bka z>cW0M0cFYDXFH%sic`pP_(UIW;Q9>*qtv!n5eFLTcU|ImGj4#0>Omm}?+yhXZ(c23 zFXwYd>EKhHwq($1nv?W+LV^EkNR@Wy^1fvNQ}8cG4y9-i)EEL&|1Ar&JpBO8FUp?# z5NL$5`>a%MSV);oDZWps$&0|Rgm03^iOFrS3-y64Hfu-JHBA1Ec~W7N=IjtC5g7G^ z|9pTF*67~R4oT8ui#xFnE>I}%@w}P$-qO93q_tHPa}|_D+4%q*o+Ff!xVNMU0G}|$ t9K8RYoRF6QC5(uJ`pf^%>z`ZPwX%HadD_`s@b^o=%jX)3WiYc3{|Dpw?VbPt literal 0 HcmV?d00001 diff --git a/assets/images/logos/logo_academico.png b/assets/images/logos/logo_academico.png new file mode 100644 index 0000000000000000000000000000000000000000..a1dbdca7ae34eb81603843603bc34eac788aa3ef GIT binary patch literal 21555 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 e`2Vd2)<~xkSM { state.copyWith(status: DailyStateSatus.loaded, semestres: semestres)); } catch (e, s) { log('Erro ao buscar semestres', error: e, stackTrace: s); - emit(state.copyWith( + + emit( + state.copyWith( status: DailyStateSatus.error, - errorMessage: 'Erro ao buscar semestres')); + errorMessage: 'Erro ao buscar semestres', + ), + ); } } diff --git a/lib/app/pages/daily/daily_state.dart b/lib/app/pages/daily/daily_state.dart index 7c4f14f..db9b3f6 100644 --- a/lib/app/pages/daily/daily_state.dart +++ b/lib/app/pages/daily/daily_state.dart @@ -22,6 +22,7 @@ class DailyState extends Equatable { final String? errorMessage; final bool isNow; final int selected; + const DailyState({ required this.status, diff --git a/lib/app/pages/splash/splash_page.dart b/lib/app/pages/splash/splash_page.dart index f21fa5a..26e7bc3 100644 --- a/lib/app/pages/splash/splash_page.dart +++ b/lib/app/pages/splash/splash_page.dart @@ -16,7 +16,7 @@ class SplashPage extends StatelessWidget { children: [ Image.asset( 'assets/images/logos/logo_ifce.png', - height: context.percentHeight(.25), + height: context.percentWidth(.5), fit: BoxFit.cover, ), SizedBox( @@ -26,7 +26,8 @@ class SplashPage extends StatelessWidget { width: context.percentWidth(.6), height: context.percentHeight(.07), label: 'Acessar', - onPressed: () => Navigator.of(context).popAndPushNamed('/login'), + onPressed: () => + Navigator.of(context).popAndPushNamed('/login'), ), ], ), From 864cb05407bbe87159aefa5b20dac2421d2df2f5 Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Tue, 9 May 2023 12:47:15 -0300 Subject: [PATCH 5/8] lista de disciplinas --- .env | 4 +- lib/academico_mobile.dart | 4 +- .../exceptions/unauthorized_exception.dart | 1 + .../core/provider/application_binding.dart | 9 +- lib/app/core/rest_client/custom_dio.dart | 2 +- lib/app/core/ui/widgets/my_appbar.dart | 11 +- lib/app/models/auth_model.dart | 25 ++ lib/app/models/daily_model.dart | 15 +- lib/app/pages/daily/daily_controller.dart | 14 +- lib/app/pages/daily/daily_page.dart | 53 ++-- lib/app/pages/daily/daily_state.dart | 2 +- lib/app/pages/daily/daily_state.g.dart | 20 ++ .../daily/widgets/lista_card_disciplina.dart | 19 +- lib/app/pages/daily/widgets/my_switch.dart | 4 +- .../pages/dashbord_daily/dashboard_page.dart | 50 ++-- .../widgets/card_aulas_futuras.dart | 12 - lib/app/pages/home/widgets/card_home.dart | 71 +++--- lib/app/pages/login/login_controller.dart | 36 +++ lib/app/pages/login/login_page.dart | 239 ++++++++++-------- lib/app/pages/login/login_router.dart | 28 +- lib/app/pages/login/login_state.dart | 41 +++ lib/app/pages/login/login_state.g.dart | 70 +++++ lib/app/pages/schedule/schedule_page.dart | 29 ++- lib/app/pages/schedule/schedule_state.dart | 2 +- lib/app/pages/schedule/schedule_state.g.dart | 10 + lib/app/pages/schedule/widgets/my_card.dart | 76 +++--- .../repositories/auth/auth_repository.dart | 5 + .../auth/auth_repository_impl.dart | 40 +++ .../daily/daily_repository_impl.dart | 9 +- .../schedule/schedule_repository_impl.dart | 7 +- lib/main.dart | 54 +--- pubspec.lock | 233 +++++++++++++---- pubspec.yaml | 2 + 33 files changed, 798 insertions(+), 399 deletions(-) create mode 100644 lib/app/core/exceptions/unauthorized_exception.dart create mode 100644 lib/app/models/auth_model.dart create mode 100644 lib/app/pages/login/login_controller.dart create mode 100644 lib/app/pages/login/login_state.dart create mode 100644 lib/app/pages/login/login_state.g.dart create mode 100644 lib/app/repositories/auth/auth_repository.dart create mode 100644 lib/app/repositories/auth/auth_repository_impl.dart diff --git a/.env b/.env index 2ff9338..57c6b36 100644 --- a/.env +++ b/.env @@ -1,3 +1 @@ -base_url=http://192.168.0.123:8080/ -URL_LOGIN=https://qacademico.ifce.edu.br/qacademico/index.asp?t=1001 -URL_SCHEDULE=https://qacademico.ifce.edu.br/qacademico/index.asp?t=2010 \ No newline at end of file +base_url=http://192.168.0.123:3000/ \ No newline at end of file diff --git a/lib/academico_mobile.dart b/lib/academico_mobile.dart index 3cf409e..c481b34 100644 --- a/lib/academico_mobile.dart +++ b/lib/academico_mobile.dart @@ -2,7 +2,7 @@ import 'package:academico_mobile/app/core/provider/application_binding.dart'; import 'package:academico_mobile/app/core/ui/theme/theme_config.dart'; import 'package:academico_mobile/app/pages/daily/daily_router.dart'; import 'package:academico_mobile/app/pages/home/home_router.dart'; -import 'package:academico_mobile/app/pages/login/login_page.dart'; +import 'package:academico_mobile/app/pages/login/login_router.dart'; import 'package:academico_mobile/app/pages/recover_password/recover_password_page.dart'; import 'package:academico_mobile/app/pages/schedule/schedule_router.dart'; import 'package:academico_mobile/app/pages/splash/splash_page.dart'; @@ -20,7 +20,7 @@ class AcademicoMobile extends StatelessWidget { debugShowCheckedModeBanner: false, routes: { '/': (context) => const SplashPage(), - '/login': (context) => const LoginPage(), + '/login': (context) => LoginRouter.page, '/schedule': (context) => ScheduleRouter.page, '/daily': (context) => DailyRouter.page, '/home': (context) => HomeRouter.page, diff --git a/lib/app/core/exceptions/unauthorized_exception.dart b/lib/app/core/exceptions/unauthorized_exception.dart new file mode 100644 index 0000000..1ee5470 --- /dev/null +++ b/lib/app/core/exceptions/unauthorized_exception.dart @@ -0,0 +1 @@ +class UnauthorizedException implements Exception {} diff --git a/lib/app/core/provider/application_binding.dart b/lib/app/core/provider/application_binding.dart index d86bbee..6fc352d 100644 --- a/lib/app/core/provider/application_binding.dart +++ b/lib/app/core/provider/application_binding.dart @@ -1,4 +1,6 @@ import 'package:academico_mobile/app/core/rest_client/custom_dio.dart'; +import 'package:academico_mobile/app/repositories/auth/auth_repository.dart'; +import 'package:academico_mobile/app/repositories/auth/auth_repository_impl.dart'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; @@ -16,7 +18,12 @@ class ApplicationBinding extends StatelessWidget { providers: [ Provider( create: (context) => CustomDio(), - ) + ), + Provider( + create: (context) => AuthRepositoryImpl( + dio: context.read(), + ), + ), ], child: child, ); diff --git a/lib/app/core/rest_client/custom_dio.dart b/lib/app/core/rest_client/custom_dio.dart index aa6332a..8ce9cf8 100644 --- a/lib/app/core/rest_client/custom_dio.dart +++ b/lib/app/core/rest_client/custom_dio.dart @@ -8,7 +8,7 @@ class CustomDio extends DioForNative { BaseOptions( baseUrl: Env.instance['base_url'] ?? '', connectTimeout: const Duration(milliseconds: 5000), - receiveTimeout: const Duration(milliseconds: 60000), + receiveTimeout: const Duration(milliseconds: 180000), ), ) { interceptors.add(LogInterceptor( diff --git a/lib/app/core/ui/widgets/my_appbar.dart b/lib/app/core/ui/widgets/my_appbar.dart index 51cf578..ff0a1cd 100644 --- a/lib/app/core/ui/widgets/my_appbar.dart +++ b/lib/app/core/ui/widgets/my_appbar.dart @@ -15,7 +15,12 @@ class MyAppbar extends AppBar { required final VoidCallback onPressed, }) : super( elevation: elevation, - title: Text(title, style: TextStyles.instance.labelPage), + title: Text( + title, + style: TextStyles.instance.labelPage.copyWith( + fontSize: 15, + ), + ), centerTitle: true, backgroundColor: ColorsApp.instance.background, leading: IconButton( @@ -43,7 +48,7 @@ class MyAppbar extends AppBar { return Container( alignment: Alignment.center, padding: - const EdgeInsets.symmetric(vertical: 10, horizontal: 10), + const EdgeInsets.symmetric(vertical: 10, horizontal: 15), margin: const EdgeInsets.symmetric(horizontal: 10, vertical: 10), decoration: BoxDecoration( @@ -58,7 +63,7 @@ class MyAppbar extends AppBar { color: state.isOn ? ColorsApp.instance.cardwhite : ColorsApp.instance.cardwhite, - fontSize: 15, + fontSize: 12, fontWeight: TextStyles.instance.textButtonLabel.fontWeight, ), diff --git a/lib/app/models/auth_model.dart b/lib/app/models/auth_model.dart new file mode 100644 index 0000000..f9fc34a --- /dev/null +++ b/lib/app/models/auth_model.dart @@ -0,0 +1,25 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'dart:convert'; + +class AuthModel { + final String accessToken; + + AuthModel({required this.accessToken}); + + Map toMap() { + return { + 'access_token': accessToken, + }; + } + + factory AuthModel.fromMap(Map map) { + return AuthModel( + accessToken: map['access_token'] ?? '', + ); + } + + String toJson() => json.encode(toMap()); + + factory AuthModel.fromJson(String source) => + AuthModel.fromMap(json.decode(source) as Map); +} diff --git a/lib/app/models/daily_model.dart b/lib/app/models/daily_model.dart index 36a5ceb..692782b 100644 --- a/lib/app/models/daily_model.dart +++ b/lib/app/models/daily_model.dart @@ -19,7 +19,7 @@ class SemestreModel { } class DisciplinaModel { - int id; + String id; String nome; String professor; Resumo resumo; @@ -37,8 +37,8 @@ class DisciplinaModel { List avaliacoes = List.from(json["avaliacoes"].map((x) => x.toString())); return DisciplinaModel( - id: json["id"], - nome: json["nome"], + id: json["id"] ?? '0', + nome: json["nome"] ?? '', professor: json["professor"], resumo: Resumo.fromJson(json["resumo"]), avaliacoes: avaliacoes); @@ -56,7 +56,7 @@ class DisciplinaModel { class Resumo { String cargaHoraria; String faltas; - List aulasFuturas; + String aulasFuturas; List presencas; List ausencias; List pendentes; @@ -80,13 +80,10 @@ class Resumo { List pendentes = List.from( json["pendentes"].map((x) => x.toString()), ); - List aulasFuturas = List.from( - json["aulas_futuras"].map((x) => x.toString()), - ); return Resumo( cargaHoraria: json["carga_horaria"], faltas: json["faltas"], - aulasFuturas: aulasFuturas, + aulasFuturas: json["aulas_futuras"], presencas: presencas, ausencias: ausencias, pendentes: pendentes); @@ -95,7 +92,7 @@ class Resumo { Map toJson() => { "carga_horaria": cargaHoraria, "faltas": faltas, - "aulas_futuras": List.from(aulasFuturas.map((x) => x)), + "aulas_futuras": aulasFuturas, "presencas": List.from(presencas.map((x) => x)), "ausencias": List.from(ausencias.map((x) => x)), "pendentes": List.from(pendentes.map((x) => x)), diff --git a/lib/app/pages/daily/daily_controller.dart b/lib/app/pages/daily/daily_controller.dart index b353d53..6ebf245 100644 --- a/lib/app/pages/daily/daily_controller.dart +++ b/lib/app/pages/daily/daily_controller.dart @@ -1,7 +1,6 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first import 'dart:developer'; - import 'package:bloc/bloc.dart'; import 'package:academico_mobile/app/pages/daily/daily_state.dart'; import 'package:academico_mobile/app/repositories/daily/daily_repository.dart'; @@ -16,13 +15,12 @@ class DailyController extends Cubit { Future loadSemestre() async { emit(state.copyWith(status: DailyStateSatus.loading)); try { - await Future.delayed(const Duration(seconds: 2)); final semestres = await _dailyRepository.findDaily(); emit( - state.copyWith(status: DailyStateSatus.loaded, semestres: semestres)); + state.copyWith(status: DailyStateSatus.loaded, semestres: semestres), + ); } catch (e, s) { log('Erro ao buscar semestres', error: e, stackTrace: s); - emit( state.copyWith( status: DailyStateSatus.error, @@ -37,7 +35,13 @@ class DailyController extends Cubit { await Future.delayed( const Duration(seconds: 2), ); - emit(state.copyWith(status: DailyStateSatus.loaded, isNow: !state.isNow)); + emit( + state.copyWith( + status: DailyStateSatus.loaded, + isNow: !state.isNow, + + ), + ); } Future selectedDay(int index) async { diff --git a/lib/app/pages/daily/daily_page.dart b/lib/app/pages/daily/daily_page.dart index c595b83..a14b2d4 100644 --- a/lib/app/pages/daily/daily_page.dart +++ b/lib/app/pages/daily/daily_page.dart @@ -20,15 +20,13 @@ class DailyPage extends StatefulWidget { } class _DailyPageState extends BaseState { + late List list = []; @override - void onReady() { - super.onReady(); - controller.loadSemestre(); + void onReady() async { + await controller.loadSemestre(); list = controller.state.semestres[0].disciplinas; } - List list = []; - @override Widget build(BuildContext context) { return Scaffold( @@ -79,7 +77,12 @@ class _DailyPageState extends BaseState { borderRadius: BorderRadius.circular(5), ), child: TextButton( - onPressed: () => controller.selectedDay(index), + onPressed: () { + setState(() { + controller.selectedDay(index); + list = state.semestres[index].disciplinas; + }); + }, child: Text( state.semestres[index].semestre, style: TextStyles.instance.texLabelH2.copyWith( @@ -102,20 +105,36 @@ class _DailyPageState extends BaseState { padding: EdgeInsets.only(left: context.percentWidth(0.03)), child: const LabelSubtitle(title: 'Disciplinas'), ), - BlocListener( + BlocConsumer( listener: (context, state) { - list = state.semestres[state.selected].disciplinas; - }, - child: Expanded( - child: ListView.builder( - itemCount: list.length, - itemBuilder: (context, index) { - return ListaCardDisciplina( - disciplina: list[index], - ); + state.status.matchAny( + any: () => hideLoader(), + loading: () => showLoader(), + error: () { + hideLoader(); + showError(state.errorMessage ?? + 'Erro ao carregar o cronograma'); }, - ), + ); + }, + buildWhen: (previous, current) => current.status.matchAny( + any: () => false, + initial: () => true, + loaded: () => true, ), + builder: (context, state) { + return Expanded( + child: ListView.builder( + shrinkWrap: true, + itemCount: list.length, + itemBuilder: (BuildContext context, int index) { + return ListaCardDisciplina( + disciplina: list[index], + ); + }, + ), + ); + }, ), SizedBox(height: context.percentHeight(0.02)) ], diff --git a/lib/app/pages/daily/daily_state.dart b/lib/app/pages/daily/daily_state.dart index db9b3f6..3844ea1 100644 --- a/lib/app/pages/daily/daily_state.dart +++ b/lib/app/pages/daily/daily_state.dart @@ -34,7 +34,7 @@ class DailyState extends Equatable { DailyState.initial() : status = DailyStateSatus.initial, - semestres = [], + semestres = [], errorMessage = null, isNow = true, selected = 0; diff --git a/lib/app/pages/daily/daily_state.g.dart b/lib/app/pages/daily/daily_state.g.dart index bd2259f..58a637a 100644 --- a/lib/app/pages/daily/daily_state.g.dart +++ b/lib/app/pages/daily/daily_state.g.dart @@ -11,6 +11,8 @@ extension DailyStateSatusMatch on DailyStateSatus { {required T Function() initial, required T Function() loading, required T Function() loaded, + required T Function() isNow, + required T Function() selected, required T Function() error}) { final v = this; if (v == DailyStateSatus.initial) { @@ -25,6 +27,14 @@ extension DailyStateSatusMatch on DailyStateSatus { return loaded(); } + if (v == DailyStateSatus.isNow) { + return isNow(); + } + + if (v == DailyStateSatus.selected) { + return selected(); + } + if (v == DailyStateSatus.error) { return error(); } @@ -37,6 +47,8 @@ extension DailyStateSatusMatch on DailyStateSatus { T Function()? initial, T Function()? loading, T Function()? loaded, + T Function()? isNow, + T Function()? selected, T Function()? error}) { final v = this; if (v == DailyStateSatus.initial && initial != null) { @@ -51,6 +63,14 @@ extension DailyStateSatusMatch on DailyStateSatus { return loaded(); } + if (v == DailyStateSatus.isNow && isNow != null) { + return isNow(); + } + + if (v == DailyStateSatus.selected && selected != null) { + return selected(); + } + if (v == DailyStateSatus.error && error != null) { return error(); } diff --git a/lib/app/pages/daily/widgets/lista_card_disciplina.dart b/lib/app/pages/daily/widgets/lista_card_disciplina.dart index 3a66116..73d1789 100644 --- a/lib/app/pages/daily/widgets/lista_card_disciplina.dart +++ b/lib/app/pages/daily/widgets/lista_card_disciplina.dart @@ -43,7 +43,7 @@ class ListaCardDisciplina extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - disciplina.id.toString(), + disciplina.id.trim(), style: TextStyles.instance.texLabelH5.copyWith( color: ColorsApp.instance.labelblack1, fontSize: 14, @@ -53,20 +53,21 @@ class ListaCardDisciplina extends StatelessWidget { ), SizedBox(height: context.screenHeight * 0.005), Text( - disciplina.nome, - style: TextStyles.instance.texLabelH4.copyWith( + disciplina.nome.trim(), + style: TextStyles.instance.texLabelH4.copyWith( color: ColorsApp.instance.labelblack1, - fontSize: 17, + fontSize: 15, fontWeight: TextStyles.instance.textSemiBold.fontWeight), ), - SizedBox(height: context.screenHeight * 0.002), + SizedBox(height: context.screenHeight * 0.005), Text( - disciplina.professor, + disciplina.professor.trim(), style: TextStyles.instance.texLabelH5.copyWith( - color: ColorsApp.instance.labelblack1, - fontWeight: - TextStyles.instance.textSemiBold.fontWeight), + color: ColorsApp.instance.labelblack1, + fontWeight: + TextStyles.instance.textSemiBold.fontWeight, + ), ), ], ), diff --git a/lib/app/pages/daily/widgets/my_switch.dart b/lib/app/pages/daily/widgets/my_switch.dart index b5df70d..b21287a 100644 --- a/lib/app/pages/daily/widgets/my_switch.dart +++ b/lib/app/pages/daily/widgets/my_switch.dart @@ -31,7 +31,9 @@ class _MySwitchState extends State { borderRadius: BorderRadius.circular(5), ), child: TextButton( - onPressed: () => context.read().changeIsNow(), + onPressed: () { + context.read().changeIsNow(); + }, child: Text( 'Diário atual', style: TextStyles.instance.texLabelH2.copyWith( diff --git a/lib/app/pages/dashbord_daily/dashboard_page.dart b/lib/app/pages/dashbord_daily/dashboard_page.dart index 1e316ba..ac92a84 100644 --- a/lib/app/pages/dashbord_daily/dashboard_page.dart +++ b/lib/app/pages/dashbord_daily/dashboard_page.dart @@ -68,18 +68,17 @@ class _DashboardPageState extends State { label: 'Carga Horária Total', value: '${widget.disciplina.resumo.cargaHoraria}H', ), - Row( - children: [ - Text( - 'Existem 6 aulas planejadas a mais que as necessárias.', - style: TextStyles.instance.texLabelH5.copyWith( - color: ColorsApp.instance.cardgrey, - fontWeight: TextStyles.instance.textSemiBold.fontWeight, - ), - ), - ], - ), - SizedBox(height: context.screenHeight * 0.01), + // Row( + // children: [ + // Text( + // 'Existem 6 aulas planejadas a mais que as necessárias.', + // style: TextStyles.instance.texLabelH5.copyWith( + // color: ColorsApp.instance.cardgrey, + // fontWeight: TextStyles.instance.textSemiBold.fontWeight, + // ), + // ), + // ], + // ), CardHorario( label: 'Você ainda pode ter', value: '${widget.disciplina.resumo.faltas} falta(s)', @@ -87,8 +86,7 @@ class _DashboardPageState extends State { ), CardFaltasFuturas( label: 'Horas aula futuras', - value: '${widget.disciplina.resumo.aulasFuturas[0]}H', - percent: '${widget.disciplina.resumo.aulasFuturas[1]}%', + value: '${widget.disciplina.resumo.aulasFuturas}H', ), SizedBox(height: context.screenHeight * 0.02), Row( @@ -139,10 +137,26 @@ class _DashboardPageState extends State { color: ColorsApp.instance.cardnoselected, thickness: 1, ), - LineNotas(label: 'N1', value: 7.0.toString()), - LineNotas(label: 'N2', value: 7.0.toString()), - LineNotas(label: 'Media Parcial', value: 7.0.toString()), - LineNotas(label: 'Prova Final', value: 7.0.toString()), + LineNotas( + label: 'N1', + value: widget.disciplina.avaliacoes[0].toString() == '' + ? '0' + : widget.disciplina.avaliacoes[0].toString()), + LineNotas( + label: 'N2', + value: widget.disciplina.avaliacoes[1].toString() == '' + ? '0' + : widget.disciplina.avaliacoes[1].toString()), + LineNotas( + label: 'Media Parcial', + value: widget.disciplina.avaliacoes[2].toString() == '' + ? '0' + : widget.disciplina.avaliacoes[2].toString()), + LineNotas( + label: 'Prova Final', + value: widget.disciplina.avaliacoes[3].toString() == '' + ? '0' + : widget.disciplina.avaliacoes[3].toString()), ], ), ), diff --git a/lib/app/pages/dashbord_daily/widgets/card_aulas_futuras.dart b/lib/app/pages/dashbord_daily/widgets/card_aulas_futuras.dart index a3fa35d..9a61cc5 100644 --- a/lib/app/pages/dashbord_daily/widgets/card_aulas_futuras.dart +++ b/lib/app/pages/dashbord_daily/widgets/card_aulas_futuras.dart @@ -6,13 +6,11 @@ import 'package:flutter/material.dart'; class CardFaltasFuturas extends StatelessWidget { final String label; final String value; - final String percent; const CardFaltasFuturas({ super.key, required this.label, required this.value, - required this.percent, }); @override @@ -43,16 +41,6 @@ class CardFaltasFuturas extends StatelessWidget { ), ), ), - Padding( - padding: const EdgeInsets.all(10), - child: Text( - percent, - style: TextStyles.instance.texLabelH3.copyWith( - color: ColorsApp.instance.cardwhite, - fontWeight: TextStyles.instance.textSemiBold.fontWeight, - ), - ), - ), ], ), ); diff --git a/lib/app/pages/home/widgets/card_home.dart b/lib/app/pages/home/widgets/card_home.dart index 2c12bef..f694913 100644 --- a/lib/app/pages/home/widgets/card_home.dart +++ b/lib/app/pages/home/widgets/card_home.dart @@ -1,57 +1,56 @@ +import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; import 'package:academico_mobile/app/core/ui/styles/text_styles.dart'; import 'package:flutter/material.dart'; - import 'package:academico_mobile/app/models/home_model.dart'; -import 'package:loading_gifs/loading_gifs.dart'; - class CardHome extends StatelessWidget { final HomePageModel listaCards; - const CardHome({ + const CardHome({ Key? key, required this.listaCards, }) : super(key: key); @override Widget build(BuildContext context) { - return ElevatedButton( - style: ButtonStyle( - backgroundColor: - MaterialStateProperty.all(ColorsApp.instance.cardwhite), - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(5), + return Padding( + padding: const EdgeInsets.only(bottom: 10), + child: ElevatedButton( + style: ButtonStyle( + backgroundColor: + MaterialStateProperty.all(ColorsApp.instance.cardnoselected), + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(5), + ), ), ), - ), - onPressed: () => Navigator.pushNamed(context, listaCards.url), - child: Container( - decoration: BoxDecoration( - borderRadius: BorderRadius.circular(5), - ), - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Padding( - padding: const EdgeInsets.all(5.0), - child: - FadeInImage.assetNetwork( - placeholder: cupertinoActivityIndicator, - image: listaCards.image, - height: 100, - width: 110, + onPressed: () => Navigator.pushNamed(context, listaCards.url), + child: Container( + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(5), + ), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Image.asset( + listaCards.image, + height: context.percentWidth(.15), fit: BoxFit.cover, ), - ), - Text( - listaCards.name, - style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.background, - fontWeight: TextStyles.instance.textSemiBold.fontWeight, + SizedBox( + height: context.screenWidth * 0.035, ), - ), - ], + Text( + listaCards.name, + style: TextStyles.instance.texLabelH4.copyWith( + fontSize: context.screenWidth * 0.045, + color: ColorsApp.instance.cardwhite, + fontWeight: TextStyles.instance.textSemiBold.fontWeight, + ), + ), + ], + ), ), ), ); diff --git a/lib/app/pages/login/login_controller.dart b/lib/app/pages/login/login_controller.dart new file mode 100644 index 0000000..71e0cd6 --- /dev/null +++ b/lib/app/pages/login/login_controller.dart @@ -0,0 +1,36 @@ +import 'dart:developer'; +import 'package:academico_mobile/app/core/exceptions/unauthorized_exception.dart'; +import 'package:academico_mobile/app/pages/login/login_state.dart'; +import 'package:academico_mobile/app/repositories/auth/auth_repository.dart'; +import 'package:bloc/bloc.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +class LoginController extends Cubit { + final AuthRepository _authRepository; + + LoginController(this._authRepository) : super(const LoginState.initial()); + + Future login(String matricula, String password) async { + try { + emit(state.copyWith(status: LoginStatus.login)); + final authModel = await _authRepository.login(matricula, password); + final prefs = await SharedPreferences.getInstance(); + await prefs.setString('access_token', authModel.accessToken); + emit(state.copyWith(status: LoginStatus.sucess)); + } on UnauthorizedException catch (e, s) { + log('Permissão Negada Controller 1', error: e, stackTrace: s); + emit( + state.copyWith( + status: LoginStatus.loginError, + errorMessage: 'Permissão Negada Controller 2'), + ); + } catch (e, s) { + log('Erro ao realizar Login Controller 1', error: e, stackTrace: s); + emit( + state.copyWith( + status: LoginStatus.error, + errorMessage: 'Erro ao realizar Login Controller 2'), + ); + } + } +} diff --git a/lib/app/pages/login/login_page.dart b/lib/app/pages/login/login_page.dart index 7783ca1..60ff3c2 100644 --- a/lib/app/pages/login/login_page.dart +++ b/lib/app/pages/login/login_page.dart @@ -1,11 +1,15 @@ // ignore_for_file: unnecessary_string_interpolations, avoid_print +import 'package:academico_mobile/app/core/ui/base_state/base_state.dart'; import 'package:academico_mobile/app/core/ui/helpers/size_extensions.dart'; import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; import 'package:academico_mobile/app/core/ui/styles/text_styles.dart'; import 'package:academico_mobile/app/core/ui/widgets/my_input_button.dart'; +import 'package:academico_mobile/app/pages/login/login_controller.dart'; +import 'package:academico_mobile/app/pages/login/login_state.dart'; import 'package:academico_mobile/app/pages/login/widgets/my_sliverfillremaining.dart'; import 'package:flutter/material.dart'; -import 'package:webview_flutter/webview_flutter.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:validatorless/validatorless.dart'; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @@ -14,136 +18,153 @@ class LoginPage extends StatefulWidget { State createState() => _LoginPageState(); } -class _LoginPageState extends State { +class _LoginPageState extends BaseState { final formKey = GlobalKey(); TextEditingController matriculaEC = TextEditingController(); - TextEditingController senhaEC = TextEditingController(); + TextEditingController passwordEC = TextEditingController(); bool _obscuredText = true; - late WebViewController controller; - @override - void initState() { - controller = WebViewController() - ..setJavaScriptMode(JavaScriptMode.unrestricted) - ..setBackgroundColor(const Color(0x00000000)) - ..loadRequest(Uri.parse( - 'https://qacademico.ifce.edu.br/qacademico/index.asp?t=1001')); - super.initState(); - } @override void dispose() { matriculaEC.dispose(); - senhaEC.dispose(); + passwordEC.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - return Scaffold( - body: CustomScrollView( - slivers: [ - SliverToBoxAdapter( - child: Padding( - padding: EdgeInsets.all(context.screenWidth * .03), - child: Form( - key: formKey, - child: Column( - children: [ - SizedBox( - height: context.percentHeight(.15), - ), - Image.asset( - 'assets/images/logos/logo_ifce.png', - height: context.percentHeight(.2), - fit: BoxFit.cover, - ), - SizedBox( - height: context.percentHeight(.05), - ), - TextFormField( - controller: matriculaEC, - keyboardType: TextInputType.number, - style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack1, - fontSize: 20, - fontWeight: - TextStyles.instance.textButtonLabel.fontWeight, - ), - decoration: const InputDecoration( - hintText: 'matricula', - ), - ), - const SizedBox( - height: 20, - ), - TextFormField( - controller: senhaEC, - obscureText: _obscuredText, - style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack1, - fontSize: 20, - fontWeight: - TextStyles.instance.textButtonLabel.fontWeight, - ), - decoration: InputDecoration( - hintText: 'senha', - suffixIcon: IconButton( - onPressed: () { - setState(() { - _obscuredText = !_obscuredText; - }); - }, - icon: Icon( - _obscuredText - ? Icons.visibility - : Icons.visibility_off, - color: ColorsApp.instance.labelblack1, - size: 25), + return BlocListener( + listener: (context, state) { + state.status.matchAny( + any: () => hideLoader(), + login: () => showLoader(), + loginError: () { + hideLoader(); + showError('Login ou Senha inválidos'); + }, + error: () { + hideLoader(); + showError('Error ao realizar login'); + }, + sucess: () { + hideLoader(); + Navigator.of(context).pushReplacementNamed('/home'); + }, + ); + }, + child: GestureDetector( + onTap: () => FocusScope.of(context).unfocus(), + child: Scaffold( + body: CustomScrollView( + slivers: [ + SliverToBoxAdapter( + child: Padding( + padding: EdgeInsets.all(context.screenWidth * .03), + child: Form( + key: formKey, + child: Column( + children: [ + SizedBox( + height: context.percentHeight(.15), ), - ), - ), - const SizedBox( - height: 30, - ), - Center( - child: Row( - children: [ - Expanded( - child: MyInputButton( - height: context.screenHeight * .07, - label: 'Acessar', + Image.asset( + 'assets/images/logos/logo_ifce.png', + height: context.percentHeight(.2), + fit: BoxFit.cover, + ), + SizedBox( + height: context.percentHeight(.05), + ), + TextFormField( + controller: matriculaEC, + validator: + Validatorless.required('Matricula Obrigatória'), + keyboardType: TextInputType.number, + style: TextStyles.instance.texLabelH4.copyWith( + color: ColorsApp.instance.labelblack1, + fontSize: 20, + fontWeight: + TextStyles.instance.textButtonLabel.fontWeight, + ), + decoration: const InputDecoration( + hintText: 'matricula', + ), + ), + const SizedBox( + height: 20, + ), + TextFormField( + controller: passwordEC, + validator: Validatorless.multiple([ + Validatorless.required('Senha Obrigatória'), + Validatorless.min( + 6, + 'Senha deve ter no mínimo 6 caracteres', + ) + ]), + obscureText: _obscuredText, + style: TextStyles.instance.texLabelH4.copyWith( + color: ColorsApp.instance.labelblack1, + fontSize: 20, + fontWeight: + TextStyles.instance.textButtonLabel.fontWeight, + ), + decoration: InputDecoration( + hintText: 'senha', + suffixIcon: IconButton( onPressed: () { - print('${matriculaEC.text}'); - print('${senhaEC.text}'); - Navigator.of(context) - .pushReplacementNamed('/home'); + setState(() { + _obscuredText = !_obscuredText; + }); }, + icon: Icon( + _obscuredText + ? Icons.visibility + : Icons.visibility_off, + color: ColorsApp.instance.labelblack1, + size: 25), ), ), - ], - ), - ), - SizedBox( - height: context.screenHeight * .07, + ), + const SizedBox( + height: 30, + ), + Center( + child: Row( + children: [ + Expanded( + child: MyInputButton( + height: context.screenHeight * .07, + label: 'Acessar', + onPressed: () async { + final formValid = + formKey.currentState?.validate() ?? + false; + if (formValid) { + await controller.login( + matriculaEC.text, + passwordEC.text, + ); + } + }, + ), + ), + ], + ), + ), + SizedBox( + height: context.screenHeight * .07, + ), + ], ), - ], + ), ), ), - ), + const MySliverfillremaining() + ], ), - const MySliverfillremaining() - ], + ), ), ); } } - - -// controller -// ..runJavaScript( -// "javascript:document.getElementById('txtLogin').value = '${matriculaEC.text}'") -// ..runJavaScript( -// "javascript:document.getElementById('txtSenha').value = '${senhaEC.text}'") -// ..runJavaScript( -// "javascript:document.forms['frmLogin'].submit()"); -// print('foi'); \ No newline at end of file diff --git a/lib/app/pages/login/login_router.dart b/lib/app/pages/login/login_router.dart index 669b95a..8df745d 100644 --- a/lib/app/pages/login/login_router.dart +++ b/lib/app/pages/login/login_router.dart @@ -1,12 +1,18 @@ -// import 'package:academico_mobile/app/pages/login/login_page.dart'; -// import 'package:flutter/material.dart'; -// import 'package:provider/provider.dart'; +import 'package:academico_mobile/app/pages/login/login_controller.dart'; +import 'package:academico_mobile/app/pages/login/login_page.dart'; +import 'package:flutter/material.dart'; +import 'package:provider/provider.dart'; -// class LoginRouter { -// LoginRouter._(); -// static Widget get page => MultiProvider( -// providers: [ -// ], -// child: const LoginPage(), -// ); -// } +class LoginRouter { + LoginRouter._(); + static Widget get page => MultiProvider( + providers: [ + Provider( + create: (context) => LoginController( + context.read(), + ), + ), + ], + child: const LoginPage(), + ); +} diff --git a/lib/app/pages/login/login_state.dart b/lib/app/pages/login/login_state.dart new file mode 100644 index 0000000..3d01d5b --- /dev/null +++ b/lib/app/pages/login/login_state.dart @@ -0,0 +1,41 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'package:equatable/equatable.dart'; +import 'package:match/match.dart'; + +part 'login_state.g.dart'; + +@match +enum LoginStatus { + initial, + login, + sucess, + loginError, + error, +} + +class LoginState extends Equatable { + final LoginStatus status; + final String? errorMessage; + + const LoginState({ + required this.status, + this.errorMessage, + }); + + const LoginState.initial() + : status = LoginStatus.initial, + errorMessage = null; + + @override + List get props => [status, errorMessage]; + + LoginState copyWith({ + LoginStatus? status, + String? errorMessage, + }) { + return LoginState( + status: status ?? this.status, + errorMessage: errorMessage ?? this.errorMessage, + ); + } +} diff --git a/lib/app/pages/login/login_state.g.dart b/lib/app/pages/login/login_state.g.dart new file mode 100644 index 0000000..9d7bcb3 --- /dev/null +++ b/lib/app/pages/login/login_state.g.dart @@ -0,0 +1,70 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'login_state.dart'; + +// ************************************************************************** +// MatchExtensionGenerator +// ************************************************************************** + +extension LoginStatusMatch on LoginStatus { + T match( + {required T Function() initial, + required T Function() login, + required T Function() sucess, + required T Function() loginError, + required T Function() error}) { + final v = this; + if (v == LoginStatus.initial) { + return initial(); + } + + if (v == LoginStatus.login) { + return login(); + } + + if (v == LoginStatus.sucess) { + return sucess(); + } + + if (v == LoginStatus.loginError) { + return loginError(); + } + + if (v == LoginStatus.error) { + return error(); + } + + throw Exception('LoginStatus.match failed, found no match for: $this'); + } + + T matchAny( + {required T Function() any, + T Function()? initial, + T Function()? login, + T Function()? sucess, + T Function()? loginError, + T Function()? error}) { + final v = this; + if (v == LoginStatus.initial && initial != null) { + return initial(); + } + + if (v == LoginStatus.login && login != null) { + return login(); + } + + if (v == LoginStatus.sucess && sucess != null) { + return sucess(); + } + + if (v == LoginStatus.loginError && loginError != null) { + return loginError(); + } + + if (v == LoginStatus.error && error != null) { + return error(); + } + + return any(); + } +} diff --git a/lib/app/pages/schedule/schedule_page.dart b/lib/app/pages/schedule/schedule_page.dart index 05a87b8..429cab5 100644 --- a/lib/app/pages/schedule/schedule_page.dart +++ b/lib/app/pages/schedule/schedule_page.dart @@ -20,8 +20,8 @@ class SchedulePage extends StatefulWidget { class _SchedulePageState extends BaseState { @override - void onReady() { - controller.loadSchedule(); + void onReady() async { + await controller.loadSchedule(); } List list = []; @@ -75,20 +75,23 @@ class _SchedulePageState extends BaseState { for (int i = 0; i < 7; i++) { daysOfWeek.add(startOfWeek.add(Duration(days: i))); } - - list = state.schedule[state.selectedDay!].horarios; + list = state + .schedule[ + state.selectedDay ?? DateTime.now().weekday] + .horarios; return Padding( padding: const EdgeInsets.only(right: 10), child: LineDays( - day: state.schedule[index], - hoje: daysOfWeek[index].day, - color: state.selectedDay == index - ? ColorsApp.instance.cardwhite - : ColorsApp.instance.cardnoselected, - onPressed: () async { - await controller.selectedDay(index); - list = state.schedule[index].horarios; - }), + day: state.schedule[index], + hoje: daysOfWeek[index].day, + color: state.selectedDay == index + ? ColorsApp.instance.cardwhite + : ColorsApp.instance.cardnoselected, + onPressed: () async { + await controller.selectedDay(index); + list = state.schedule[index].horarios; + }, + ), ); }, ), diff --git a/lib/app/pages/schedule/schedule_state.dart b/lib/app/pages/schedule/schedule_state.dart index 41569a4..b188e2b 100644 --- a/lib/app/pages/schedule/schedule_state.dart +++ b/lib/app/pages/schedule/schedule_state.dart @@ -32,7 +32,7 @@ class ScheduleState extends Equatable { : status = ScheduleStatus.initial, schedule = [], errorMessage = null, - selectedDay = DateTime.now().weekday; + selectedDay = DateTime.now().weekday - 1; @override List get props => [status, schedule, errorMessage, selectedDay]; diff --git a/lib/app/pages/schedule/schedule_state.g.dart b/lib/app/pages/schedule/schedule_state.g.dart index 862bed0..745072f 100644 --- a/lib/app/pages/schedule/schedule_state.g.dart +++ b/lib/app/pages/schedule/schedule_state.g.dart @@ -11,6 +11,7 @@ extension ScheduleStatusMatch on ScheduleStatus { {required T Function() initial, required T Function() loading, required T Function() loaded, + required T Function() selectedDay, required T Function() error}) { final v = this; if (v == ScheduleStatus.initial) { @@ -25,6 +26,10 @@ extension ScheduleStatusMatch on ScheduleStatus { return loaded(); } + if (v == ScheduleStatus.selectedDay) { + return selectedDay(); + } + if (v == ScheduleStatus.error) { return error(); } @@ -37,6 +42,7 @@ extension ScheduleStatusMatch on ScheduleStatus { T Function()? initial, T Function()? loading, T Function()? loaded, + T Function()? selectedDay, T Function()? error}) { final v = this; if (v == ScheduleStatus.initial && initial != null) { @@ -51,6 +57,10 @@ extension ScheduleStatusMatch on ScheduleStatus { return loaded(); } + if (v == ScheduleStatus.selectedDay && selectedDay != null) { + return selectedDay(); + } + if (v == ScheduleStatus.error && error != null) { return error(); } diff --git a/lib/app/pages/schedule/widgets/my_card.dart b/lib/app/pages/schedule/widgets/my_card.dart index b9091ee..2a2885d 100644 --- a/lib/app/pages/schedule/widgets/my_card.dart +++ b/lib/app/pages/schedule/widgets/my_card.dart @@ -40,32 +40,22 @@ class MyCard extends StatelessWidget { borderRadius: BorderRadius.circular(5), ), child: Column( + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Container( - padding: EdgeInsets.all(context.screenHeight * 0.005), - decoration: BoxDecoration( - color: ColorsApp.instance.cardred, - borderRadius: BorderRadius.circular(5), - ), - child: Text( - horarioDetalhado.horario, - style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.cardwhite, - fontWeight: TextStyles.instance.textBold.fontWeight, - fontSize: context.screenHeight * 0.017, - ), - ), + Container( + padding: EdgeInsets.all(context.screenHeight * 0.005), + decoration: BoxDecoration( + color: ColorsApp.instance.cardred, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + horarioDetalhado.horario, + style: TextStyles.instance.texLabelH4.copyWith( + color: ColorsApp.instance.cardwhite, + fontWeight: TextStyles.instance.textBold.fontWeight, + fontSize: context.screenHeight * 0.017, ), - Text( - horarioDetalhado.sala, - style: TextStyles.instance.texLabelH4.copyWith( - color: colorLabel(), - fontWeight: TextStyles.instance.textExtraBold.fontWeight), - ), - ], + ), ), SizedBox(height: context.screenHeight * 0.015), Row( @@ -75,26 +65,36 @@ class MyCard extends StatelessWidget { child: Text( horarioDetalhado.disciplina, style: TextStyles.instance.texLabelH4.copyWith( - color: colorLabel(), - fontWeight: TextStyles.instance.textSemiBold.fontWeight), + color: colorLabel(), + fontWeight: TextStyles.instance.textSemiBold.fontWeight, + ), ), ), ], ), SizedBox(height: context.screenHeight * 0.015), - Row( - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Expanded( - child: Text( - horarioDetalhado.professor, - style: TextStyles.instance.texLabelH5.copyWith( - color: colorLabel(), - fontWeight: TextStyles.instance.textSemiBold.fontWeight), - ), - ), - ], + Text( + horarioDetalhado.sala, + style: TextStyles.instance.texLabelH4.copyWith( + color: colorLabel(), + fontWeight: TextStyles.instance.texLabelH4.fontWeight, + ), ), + // SizedBox(height: context.screenHeight * 0.015), + // Row( + // mainAxisAlignment: MainAxisAlignment.start, + // children: [ + // Expanded( + // child: Text( + // 'Nome do Professor', + // style: TextStyles.instance.texLabelH4.copyWith( + // color: colorLabel(), + // fontWeight: TextStyles.instance.texLabelH4.fontWeight, + // ), + // ), + // ), + // ], + // ), ], ), ); diff --git a/lib/app/repositories/auth/auth_repository.dart b/lib/app/repositories/auth/auth_repository.dart new file mode 100644 index 0000000..335e9f3 --- /dev/null +++ b/lib/app/repositories/auth/auth_repository.dart @@ -0,0 +1,5 @@ +import 'package:academico_mobile/app/models/auth_model.dart'; + +abstract class AuthRepository { + Future login(String matricula, String password); +} diff --git a/lib/app/repositories/auth/auth_repository_impl.dart b/lib/app/repositories/auth/auth_repository_impl.dart new file mode 100644 index 0000000..9ea0fa1 --- /dev/null +++ b/lib/app/repositories/auth/auth_repository_impl.dart @@ -0,0 +1,40 @@ +// ignore_for_file: public_member_api_docs, sort_constructors_first +import 'dart:developer'; +import 'package:academico_mobile/app/core/exceptions/repository_exceptions.dart'; +import 'package:academico_mobile/app/core/exceptions/unauthorized_exception.dart'; +import 'package:academico_mobile/app/core/rest_client/custom_dio.dart'; +import 'package:academico_mobile/app/models/auth_model.dart'; +import 'package:dio/dio.dart'; + +import './auth_repository.dart'; + +class AuthRepositoryImpl implements AuthRepository { + final CustomDio dio; + + AuthRepositoryImpl({ + required this.dio, + }); + + @override + Future login(String matricula, String password) async { + try { + final response = await dio.unauth().post( + '/login', + data: {'matricula': matricula, 'password': password}, + ); + final Map jsonData = + response.data as Map; + final String accessToken = jsonData['access_token'] as String; + return accessToken.isNotEmpty + ? AuthModel(accessToken: accessToken) + : throw UnauthorizedException(); + } on DioError catch (e, s) { + if (e.response?.statusCode == 403) { + log('Permissão Negada Repository 1', error: e, stackTrace: s); + throw UnauthorizedException(); + } + log('Erro ao realizar Login Repository', error: e, stackTrace: s); + throw RepositoryExceptions(message: 'Erro ao realizar Login Repository'); + } + } +} diff --git a/lib/app/repositories/daily/daily_repository_impl.dart b/lib/app/repositories/daily/daily_repository_impl.dart index 53892fd..91916e9 100644 --- a/lib/app/repositories/daily/daily_repository_impl.dart +++ b/lib/app/repositories/daily/daily_repository_impl.dart @@ -18,10 +18,11 @@ class DailyRepositoryImpl implements DailyRepository { @override Future> findDaily() async { try { - final result = await dio.unauth().get('/semestres'); - return (result.data as List) - .map((e) => SemestreModel.fromJson(e as Map)) - .toList(); + final result = await dio.unauth().get('/lista-disciplinas'); + + final list = result.data as List; + final semestres = list.map((e) => SemestreModel.fromJson(e)).toList(); + return semestres; } on DioError catch (e, s) { log('Erro ao nuscar semestres', error: e, stackTrace: s); throw RepositoryExceptions(message: 'Erro ao buscar semestres'); diff --git a/lib/app/repositories/schedule/schedule_repository_impl.dart b/lib/app/repositories/schedule/schedule_repository_impl.dart index 191c438..c814178 100644 --- a/lib/app/repositories/schedule/schedule_repository_impl.dart +++ b/lib/app/repositories/schedule/schedule_repository_impl.dart @@ -1,4 +1,5 @@ // ignore_for_file: public_member_api_docs, sort_constructors_first +import 'dart:convert'; import 'dart:developer'; import 'package:academico_mobile/app/core/exceptions/repository_exceptions.dart'; @@ -19,9 +20,9 @@ class ScheduleRepositoryImpl implements ScheduleRepository { Future> findSchedule() async { try { final result = await dio.unauth().get('/horarios'); - return (result.data as List) - .map((e) => Horario.fromJson(e as Map)) - .toList(); + final data = json.decode(result.data); + final retorno = (data as List).map((e) => Horario.fromJson(e)).toList(); + return retorno; } on DioError catch (e, s) { log('Erro ao buscar horários', error: e, stackTrace: s); throw RepositoryExceptions(message: 'Erro ao buscar horários'); diff --git a/lib/main.dart b/lib/main.dart index 4f019ff..a440e85 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -7,27 +7,15 @@ Future main() async { runApp(const AcademicoMobile()); } - -//! Código para testes!!!! Apenas para testes!!!! - +//! Teste de código class MyApp extends StatelessWidget { const MyApp({super.key}); - // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', theme: ThemeData( - // This is the theme of your application. - // - // Try running your application with "flutter run". You'll see the - // application has a blue toolbar. Then, without quitting the app, try - // changing the primarySwatch below to Colors.green and then invoke - // "hot reload" (press "r" in the console where you ran "flutter run", - // or simply save your changes to "hot reload" in a Flutter IDE). - // Notice that the counter didn't reset back to zero; the application - // is not restarted. primarySwatch: Colors.blue, ), home: const MyHomePage(title: 'Flutter Demo Home Page'), @@ -38,15 +26,6 @@ class MyApp extends StatelessWidget { class MyHomePage extends StatefulWidget { const MyHomePage({super.key, required this.title}); - // This widget is the home page of your application. It is stateful, meaning - // that it has a State object (defined below) that contains fields that affect - // how it looks. - - // This class is the configuration for the state. It holds the values (in this - // case the title) provided by the parent (in this case the App widget) and - // used by the build method of the State. Fields in a Widget subclass are - // always marked "final". - final String title; @override @@ -58,47 +37,18 @@ class _MyHomePageState extends State { void _incrementCounter() { setState(() { - // This call to setState tells the Flutter framework that something has - // changed in this State, which causes it to rerun the build method below - // so that the display can reflect the updated values. If we changed - // _counter without calling setState(), then the build method would not be - // called again, and so nothing would appear to happen. _counter++; }); } @override Widget build(BuildContext context) { - // This method is rerun every time setState is called, for instance as done - // by the _incrementCounter method above. - // - // The Flutter framework has been optimized to make rerunning build methods - // fast, so that you can just rebuild anything that needs updating rather - // than having to individually change instances of widgets. return Scaffold( appBar: AppBar( - // Here we take the value from the MyHomePage object that was created by - // the App.build method, and use it to set our appbar title. title: Text(widget.title), ), body: Center( - // Center is a layout widget. It takes a single child and positions it - // in the middle of the parent. child: Column( - // Column is also a layout widget. It takes a list of children and - // arranges them vertically. By default, it sizes itself to fit its - // children horizontally, and tries to be as tall as its parent. - // - // Invoke "debug painting" (press "p" in the console, choose the - // "Toggle Debug Paint" action from the Flutter Inspector in Android - // Studio, or the "Toggle Debug Paint" command in Visual Studio Code) - // to see the wireframe for each widget. - // - // Column has various properties to control how it sizes itself and - // how it positions its children. Here we use mainAxisAlignment to - // center the children vertically; the main axis here is the vertical - // axis because Columns are vertical (the cross axis would be - // horizontal). mainAxisAlignment: MainAxisAlignment.center, children: [ const Text( @@ -115,7 +65,7 @@ class _MyHomePageState extends State { onPressed: _incrementCounter, tooltip: 'Increment', child: const Icon(Icons.add), - ), // This trailing comma makes auto-formatting nicer for build methods. + ), ); } } diff --git a/pubspec.lock b/pubspec.lock index 5117324..d9177ff 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -5,26 +5,26 @@ packages: dependency: transitive description: name: _fe_analyzer_shared - sha256: "503361166f4a100e0d7eb7fb5a62c6f0322512f2bcb48d6922caf98f24b0ab90" + sha256: "8880b4cfe7b5b17d57c052a5a3a8cc1d4f546261c7cc8fbd717bd53f48db0568" url: "https://pub.dev" source: hosted - version: "56.0.0" + version: "59.0.0" analyzer: dependency: transitive description: name: analyzer - sha256: "93fcd81a6716e69864516750590cf1e699420615046bda19100238aa7b429785" + sha256: a89627f49b0e70e068130a36571409726b04dab12da7e5625941d2c8ec278b96 url: "https://pub.dev" source: hosted - version: "5.8.0" + version: "5.11.1" args: dependency: transitive description: name: args - sha256: "4cab82a83ffef80b262ddedf47a0a8e56ee6fbf7fe21e6e768b02792034dd440" + sha256: c372bb384f273f0c2a8aaaa226dad84dc27c8519a691b888725dec59518ad53a url: "https://pub.dev" source: hosted - version: "2.4.0" + version: "2.4.1" async: dependency: transitive description: @@ -109,10 +109,10 @@ packages: dependency: transitive description: name: built_value - sha256: "31b7c748fd4b9adf8d25d72a4c4a59ef119f12876cf414f94f8af5131d5fa2b0" + sha256: "2f17434bd5d52a26762043d6b43bb53b3acd029b4d9071a329f46d67ef297e6d" url: "https://pub.dev" source: hosted - version: "8.4.4" + version: "8.5.0" characters: dependency: transitive description: @@ -125,10 +125,10 @@ packages: dependency: transitive description: name: checked_yaml - sha256: "3d1505d91afa809d177efd4eed5bb0eb65805097a1463abdd2add076effae311" + sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" clock: dependency: transitive description: @@ -165,10 +165,10 @@ packages: dependency: transitive description: name: crypto - sha256: aa274aa7774f8964e4f4f38cc994db7b6158dd36e9187aaceaddc994b35c6c67 + sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.3" cupertino_icons: dependency: "direct main" description: @@ -181,18 +181,18 @@ packages: dependency: transitive description: name: dart_style - sha256: "6d691edde054969f0e0f26abb1b30834b5138b963793e56f69d3a9a4435e6352" + sha256: f4f1f73ab3fd2afcbcca165ee601fe980d966af6a21b5970c6c9376955c528ad url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.3.1" dio: dependency: "direct main" description: name: dio - sha256: "3e5c4a94d112540d0c9a6b7f3969832e1604eb8cde0f88d0808382f9f632100b" + sha256: "0894a098594263fe1caaba3520e3016d8a855caeb010a882273189cca10f11e9" url: "https://pub.dev" source: hosted - version: "5.0.3" + version: "5.1.1" equatable: dependency: "direct main" description: @@ -209,6 +209,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + ffi: + dependency: transitive + description: + name: ffi + sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + url: "https://pub.dev" + source: hosted + version: "2.0.1" file: dependency: transitive description: @@ -258,15 +266,20 @@ packages: dependency: "direct main" description: name: flutter_svg - sha256: "12006889e2987c549c4c1ec1a5ba4ec4b24d34d2469ee5f9476c926dcecff266" + sha256: f991fdb1533c3caeee0cdc14b04f50f0c3916f0dbcbc05237ccbe4e3c6b93f3f url: "https://pub.dev" source: hosted - version: "2.0.4" + version: "2.0.5" flutter_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" frontend_server_client: dependency: transitive description: @@ -327,10 +340,10 @@ packages: dependency: transitive description: name: json_annotation - sha256: c33da08e136c3df0190bd5bbe51ae1df4a7d96e7954d1d7249fea2968a72d317 + sha256: b10a7b2ff83d83c777edba3c6a0f97045ddadd56c944e1a23a3fdf43a1bf4467 url: "https://pub.dev" source: hosted - version: "4.8.0" + version: "4.8.1" lints: dependency: transitive description: @@ -443,6 +456,30 @@ packages: url: "https://pub.dev" source: hosted version: "1.0.1" + path_provider_linux: + dependency: transitive + description: + name: path_provider_linux + sha256: "2ae08f2216225427e64ad224a24354221c2c7907e448e6e0e8b57b1eb9f10ad1" + url: "https://pub.dev" + source: hosted + version: "2.1.10" + path_provider_platform_interface: + dependency: transitive + description: + name: path_provider_platform_interface + sha256: "57585299a729335f1298b43245842678cb9f43a6310351b18fb577d6e33165ec" + url: "https://pub.dev" + source: hosted + version: "2.0.6" + path_provider_windows: + dependency: transitive + description: + name: path_provider_windows + sha256: d3f80b32e83ec208ac95253e0cd4d298e104fbc63cb29c5c69edaed43b0c69d6 + url: "https://pub.dev" + source: hosted + version: "2.1.6" petitparser: dependency: transitive description: @@ -451,6 +488,14 @@ packages: url: "https://pub.dev" source: hosted version: "5.1.0" + platform: + dependency: transitive + description: + name: platform + sha256: "4a451831508d7d6ca779f7ac6e212b4023dd5a7d08a27a63da33756410e32b76" + url: "https://pub.dev" + source: hosted + version: "3.1.0" plugin_platform_interface: dependency: transitive description: @@ -467,6 +512,14 @@ packages: url: "https://pub.dev" source: hosted version: "1.5.1" + process: + dependency: transitive + description: + name: process + sha256: "53fd8db9cec1d37b0574e12f07520d582019cb6c44abf5479a01505099a34a09" + url: "https://pub.dev" + source: hosted + version: "4.2.4" provider: dependency: "direct main" description: @@ -479,34 +532,90 @@ packages: dependency: transitive description: name: pub_semver - sha256: "307de764d305289ff24ad257ad5c5793ce56d04947599ad68b3baa124105fc17" + sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" url: "https://pub.dev" source: hosted - version: "2.1.3" + version: "2.1.4" pubspec_parse: dependency: transitive description: name: pubspec_parse - sha256: ec85d7d55339d85f44ec2b682a82fea340071e8978257e5a43e69f79e98ef50c + sha256: c63b2876e58e194e4b0828fcb080ad0e06d051cb607a6be51a9e084f47cb9367 url: "https://pub.dev" source: hosted - version: "1.2.2" + version: "1.2.3" + shared_preferences: + dependency: "direct main" + description: + name: shared_preferences + sha256: "858aaa72d8f61637d64e776aca82e1c67e6d9ee07979123c5d17115031c1b13b" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + shared_preferences_android: + dependency: transitive + description: + name: shared_preferences_android + sha256: "6478c6bbbecfe9aced34c483171e90d7c078f5883558b30ec3163cf18402c749" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + shared_preferences_foundation: + dependency: transitive + description: + name: shared_preferences_foundation + sha256: "0c1c16c56c9708aa9c361541a6f0e5cc6fc12a3232d866a687a7b7db30032b07" + url: "https://pub.dev" + source: hosted + version: "2.2.1" + shared_preferences_linux: + dependency: transitive + description: + name: shared_preferences_linux + sha256: "9d387433ca65717bbf1be88f4d5bb18f10508917a8fa2fb02e0fd0d7479a9afa" + url: "https://pub.dev" + source: hosted + version: "2.2.0" + shared_preferences_platform_interface: + dependency: transitive + description: + name: shared_preferences_platform_interface + sha256: fb5cf25c0235df2d0640ac1b1174f6466bd311f621574997ac59018a6664548d + url: "https://pub.dev" + source: hosted + version: "2.2.0" + shared_preferences_web: + dependency: transitive + description: + name: shared_preferences_web + sha256: "74083203a8eae241e0de4a0d597dbedab3b8fef5563f33cf3c12d7e93c655ca5" + url: "https://pub.dev" + source: hosted + version: "2.1.0" + shared_preferences_windows: + dependency: transitive + description: + name: shared_preferences_windows + sha256: "5e588e2efef56916a3b229c3bfe81e6a525665a454519ca51dbcc4236a274173" + url: "https://pub.dev" + source: hosted + version: "2.2.0" shelf: dependency: transitive description: name: shelf - sha256: c24a96135a2ccd62c64b69315a14adc5c3419df63b4d7c05832a346fdb73682c + sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 url: "https://pub.dev" source: hosted - version: "1.4.0" + version: "1.4.1" shelf_web_socket: dependency: transitive description: name: shelf_web_socket - sha256: a988c0e8d8ffbdb8a28aa7ec8e449c260f3deb808781fe1284d22c5bba7156e8 + sha256: "9ca081be41c60190ebcb4766b2486a7d50261db7bd0f5d9615f2d653637a84c1" url: "https://pub.dev" source: hosted - version: "1.0.3" + version: "1.0.4" sky_engine: dependency: transitive description: flutter @@ -516,10 +625,10 @@ packages: dependency: transitive description: name: source_gen - sha256: c2bea18c95cfa0276a366270afaa2850b09b4a76db95d546f3d003dcc7011298 + sha256: b20e191de6964e98032573cecb1d2b169d96ba63fdb586d24dcd1003ba7e94f6 url: "https://pub.dev" source: hosted - version: "1.2.7" + version: "1.3.0" source_span: dependency: transitive description: @@ -588,10 +697,10 @@ packages: dependency: "direct main" description: name: toggle_switch - sha256: "82c778c4bfe93af154a41e346ccd1d5b0cb6a50f8f187941412edd0a9bbf51ee" + sha256: "9e6af1f0c5a97d9de41109dc7b9e1b3bbe73417f89b10e0e44dc834fb493d4cb" url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.1.0" top_snackbar_flutter: dependency: "direct main" description: @@ -608,30 +717,38 @@ packages: url: "https://pub.dev" source: hosted version: "1.3.1" + validatorless: + dependency: "direct main" + description: + name: validatorless + sha256: ddb46df636114b3322d289489164cac309767b157191ba43c7ad49b28c2b57c7 + url: "https://pub.dev" + source: hosted + version: "1.2.3" vector_graphics: dependency: transitive description: name: vector_graphics - sha256: "4cf8e60dbe4d3a693d37dff11255a172594c0793da542183cbfe7fe978ae4aaa" + sha256: ea8d3fc7b2e0f35de38a7465063ecfcf03d8217f7962aa2a6717132cb5d43a79 url: "https://pub.dev" source: hosted - version: "1.1.4" + version: "1.1.5" vector_graphics_codec: dependency: transitive description: name: vector_graphics_codec - sha256: "278ad5f816f58b1967396d1f78ced470e3e58c9fe4b27010102c0a595c764468" + sha256: a5eaa5d19e123ad4f61c3718ca1ed921c4e6254238d9145f82aa214955d9aced url: "https://pub.dev" source: hosted - version: "1.1.4" + version: "1.1.5" vector_graphics_compiler: dependency: transitive description: name: vector_graphics_compiler - sha256: "0bf61ad56e6fd6688a2865d3ceaea396bc6a0a90ea0d7ad5049b1b76c09d6163" + sha256: "15edc42f7eaa478ce854eaf1fbb9062a899c0e4e56e775dd73b7f4709c97c4ca" url: "https://pub.dev" source: hosted - version: "1.1.4" + version: "1.1.5" vector_math: dependency: transitive description: @@ -652,42 +769,58 @@ packages: dependency: transitive description: name: web_socket_channel - sha256: ca49c0bc209c687b887f30527fb6a9d80040b072cc2990f34b9bec3e7663101b + sha256: d88238e5eac9a42bb43ca4e721edba3c08c6354d4a53063afaa568516217621b url: "https://pub.dev" source: hosted - version: "2.3.0" + version: "2.4.0" webview_flutter: dependency: "direct main" description: name: webview_flutter - sha256: "47663d51a9061451aa3880a214ee9a65dcbb933b77bc44388e194279ab3ccaf6" + sha256: "1a37bdbaaf5fbe09ad8579ab09ecfd473284ce482f900b5aea27cf834386a567" url: "https://pub.dev" source: hosted - version: "4.0.7" + version: "4.2.0" webview_flutter_android: dependency: transitive description: name: webview_flutter_android - sha256: "34f83c2f0f64c75ad75c77a2ccfc8d2e531afbe8ad41af1fd787d6d33336aa90" + sha256: "1acea8def62592123e2fbbca164ed8681a98a890bdcbb88f916d5b4a22687759" url: "https://pub.dev" source: hosted - version: "3.4.3" + version: "3.7.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface - sha256: "1939c39e2150fb4d30fd3cc59a891a49fed9935db53007df633ed83581b6117b" + sha256: "78715dc442b7849dbde74e92bb67de1cecf5addf95531c5fb474e72f5fe9a507" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.3.0" webview_flutter_wkwebview: dependency: transitive description: name: webview_flutter_wkwebview - sha256: ab12479f7a0cf112b9420c36aaf206a1ca47cd60cd42de74a4be2e97a697587b + sha256: "61f33512810bf1ee9ac89761a4b02663ff64e8227b7dc80654642acd660fd49d" url: "https://pub.dev" source: hosted - version: "3.2.1" + version: "3.4.2" + win32: + dependency: transitive + description: + name: win32 + sha256: "5a751eddf9db89b3e5f9d50c20ab8612296e4e8db69009788d6c8b060a84191c" + url: "https://pub.dev" + source: hosted + version: "4.1.4" + xdg_directories: + dependency: transitive + description: + name: xdg_directories + sha256: ee1505df1426458f7f60aac270645098d318a8b4766d85fde75f76f2e21807d1 + url: "https://pub.dev" + source: hosted + version: "1.0.0" xml: dependency: transitive description: @@ -700,10 +833,10 @@ packages: dependency: transitive description: name: yaml - sha256: "23812a9b125b48d4007117254bca50abb6c712352927eece9e155207b1db2370" + sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" url: "https://pub.dev" source: hosted - version: "3.1.1" + version: "3.1.2" sdks: dart: ">=2.19.0 <4.0.0" flutter: ">=3.7.0-0" diff --git a/pubspec.yaml b/pubspec.yaml index 7b9ad98..f800b7f 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,8 @@ dependencies: equatable: ^2.0.5 match: ^0.4.1 toggle_switch: ^2.0.1 + validatorless: ^1.2.3 + shared_preferences: ^2.1.0 dev_dependencies: flutter_test: From e698e78d6cb4c4f1856d0c9a153a6c8e87b96318 Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Tue, 9 May 2023 13:44:22 -0300 Subject: [PATCH 6/8] lista de disciplinas --- assets/images/images_cards/schedule.png | Bin 0 -> 28360 bytes lib/app/core/rest_client/custom_dio.dart | 2 +- lib/app/core/ui/widgets/my_appbar.dart | 21 +++++++++ lib/app/pages/daily/daily_page.dart | 2 +- .../daily/widgets/lista_card_disciplina.dart | 41 +++++++++++------- .../pages/dashbord_daily/dashboard_page.dart | 15 ++++--- lib/app/pages/schedule/schedule_page.dart | 2 +- lib/app/pages/schedule/widgets/line_days.dart | 1 + pubspec.lock | 16 +++---- 9 files changed, 68 insertions(+), 32 deletions(-) create mode 100644 assets/images/images_cards/schedule.png diff --git a/assets/images/images_cards/schedule.png b/assets/images/images_cards/schedule.png new file mode 100644 index 0000000000000000000000000000000000000000..9697a390894c7cfd7badbb1dffea3890ef4f4e58 GIT binary patch literal 28360 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 jlL7A)`xG~aV7cLP$$@c#2`Zd0|Q3rGHt=* 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 literal 0 HcmV?d00001 diff --git a/lib/app/core/rest_client/custom_dio.dart b/lib/app/core/rest_client/custom_dio.dart index 8ce9cf8..5890948 100644 --- a/lib/app/core/rest_client/custom_dio.dart +++ b/lib/app/core/rest_client/custom_dio.dart @@ -7,7 +7,7 @@ class CustomDio extends DioForNative { : super( BaseOptions( baseUrl: Env.instance['base_url'] ?? '', - connectTimeout: const Duration(milliseconds: 5000), + connectTimeout: const Duration(milliseconds: 10000), receiveTimeout: const Duration(milliseconds: 180000), ), ) { diff --git a/lib/app/core/ui/widgets/my_appbar.dart b/lib/app/core/ui/widgets/my_appbar.dart index ff0a1cd..4750e07 100644 --- a/lib/app/core/ui/widgets/my_appbar.dart +++ b/lib/app/core/ui/widgets/my_appbar.dart @@ -29,6 +29,27 @@ class MyAppbar extends AppBar { ), ); + MyAppbar.normal({ + super.key, + double elevation = 0, + required String title, + String subtitle = '', + IconData icon = Icons.arrow_back_ios, + required final VoidCallback onPressed, + }) : super( + elevation: elevation, + title: Text( + title, + style: TextStyles.instance.labelPage, + ), + centerTitle: true, + backgroundColor: ColorsApp.instance.background, + leading: IconButton( + icon: Icon(icon), + onPressed: onPressed, + ), + ); + MyAppbar.home({ super.key, double elevation = 0, diff --git a/lib/app/pages/daily/daily_page.dart b/lib/app/pages/daily/daily_page.dart index a14b2d4..d6eeccd 100644 --- a/lib/app/pages/daily/daily_page.dart +++ b/lib/app/pages/daily/daily_page.dart @@ -30,7 +30,7 @@ class _DailyPageState extends BaseState { @override Widget build(BuildContext context) { return Scaffold( - appBar: MyAppbar( + appBar: MyAppbar.normal( title: 'Meus Diários', onPressed: () => Navigator.pop(context), ), diff --git a/lib/app/pages/daily/widgets/lista_card_disciplina.dart b/lib/app/pages/daily/widgets/lista_card_disciplina.dart index 73d1789..ba34d4e 100644 --- a/lib/app/pages/daily/widgets/lista_card_disciplina.dart +++ b/lib/app/pages/daily/widgets/lista_card_disciplina.dart @@ -19,13 +19,16 @@ class ListaCardDisciplina extends StatelessWidget { Widget build(BuildContext context) { return InkWell( splashColor: ColorsApp.instance.background, - onTap: () => Navigator.of(context).push( - MaterialPageRoute( - builder: (context) => DashboardPage( - disciplina: disciplina, + onTap: () { + print('Disciplina: ${disciplina.nome}'); + Navigator.of(context).push( + MaterialPageRoute( + builder: (context) => DashboardPage( + disciplina: disciplina, + ), ), - ), - ), + ); + }, child: Container( padding: const EdgeInsets.all(10), margin: const EdgeInsets.only(bottom: 15, left: 10, right: 10, top: 0), @@ -42,25 +45,31 @@ class ListaCardDisciplina extends StatelessWidget { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Text( - disciplina.id.trim(), - style: TextStyles.instance.texLabelH5.copyWith( - color: ColorsApp.instance.labelblack1, - fontSize: 14, - fontWeight: - TextStyles.instance.textExtraBold.fontWeight, + Container( + padding: EdgeInsets.all(context.screenHeight * 0.005), + decoration: BoxDecoration( + color: ColorsApp.instance.cardblue, + borderRadius: BorderRadius.circular(5), + ), + child: Text( + disciplina.id.trim(), + style: TextStyles.instance.texLabelH4.copyWith( + color: ColorsApp.instance.cardwhite, + fontWeight: TextStyles.instance.textBold.fontWeight, + fontSize: context.screenHeight * 0.017, + ), ), ), - SizedBox(height: context.screenHeight * 0.005), + SizedBox(height: context.screenHeight * 0.007), Text( disciplina.nome.trim(), style: TextStyles.instance.texLabelH4.copyWith( color: ColorsApp.instance.labelblack1, fontSize: 15, fontWeight: - TextStyles.instance.textSemiBold.fontWeight), + TextStyles.instance.textBold.fontWeight), ), - SizedBox(height: context.screenHeight * 0.005), + SizedBox(height: context.screenHeight * 0.007), Text( disciplina.professor.trim(), style: TextStyles.instance.texLabelH5.copyWith( diff --git a/lib/app/pages/dashbord_daily/dashboard_page.dart b/lib/app/pages/dashbord_daily/dashboard_page.dart index ac92a84..c81188f 100644 --- a/lib/app/pages/dashbord_daily/dashboard_page.dart +++ b/lib/app/pages/dashbord_daily/dashboard_page.dart @@ -140,23 +140,28 @@ class _DashboardPageState extends State { LineNotas( label: 'N1', value: widget.disciplina.avaliacoes[0].toString() == '' - ? '0' + ? ' ' : widget.disciplina.avaliacoes[0].toString()), LineNotas( label: 'N2', value: widget.disciplina.avaliacoes[1].toString() == '' - ? '0' + ? ' ' : widget.disciplina.avaliacoes[1].toString()), LineNotas( - label: 'Media Parcial', + label: 'Média Parcial', value: widget.disciplina.avaliacoes[2].toString() == '' - ? '0' + ? ' ' : widget.disciplina.avaliacoes[2].toString()), LineNotas( label: 'Prova Final', value: widget.disciplina.avaliacoes[3].toString() == '' - ? '0' + ? ' ' : widget.disciplina.avaliacoes[3].toString()), + LineNotas( + label: 'Média Final', + value: widget.disciplina.avaliacoes[4].toString() == '' + ? ' ' + : widget.disciplina.avaliacoes[4].toString()), ], ), ), diff --git a/lib/app/pages/schedule/schedule_page.dart b/lib/app/pages/schedule/schedule_page.dart index 429cab5..e9dc59e 100644 --- a/lib/app/pages/schedule/schedule_page.dart +++ b/lib/app/pages/schedule/schedule_page.dart @@ -29,7 +29,7 @@ class _SchedulePageState extends BaseState { @override Widget build(BuildContext context) { return Scaffold( - appBar: MyAppbar( + appBar: MyAppbar.normal( title: 'Cronograma de Aulas', onPressed: () => Navigator.pop(context), ), diff --git a/lib/app/pages/schedule/widgets/line_days.dart b/lib/app/pages/schedule/widgets/line_days.dart index 0de7217..e535fda 100644 --- a/lib/app/pages/schedule/widgets/line_days.dart +++ b/lib/app/pages/schedule/widgets/line_days.dart @@ -64,6 +64,7 @@ class _LineDaysState extends State { Text( widget.hoje.toString(), style: TextStyles.instance.texLabelH4.copyWith( + fontSize: context.screenHeight * 0.025, color: ColorsApp.instance.labelblack4, fontWeight: TextStyles.instance.textExtraBold.fontWeight, ), diff --git a/pubspec.lock b/pubspec.lock index d9177ff..fd4ddcd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -189,10 +189,10 @@ packages: dependency: "direct main" description: name: dio - sha256: "0894a098594263fe1caaba3520e3016d8a855caeb010a882273189cca10f11e9" + sha256: "347d56c26d63519552ef9a569f2a593dda99a81fdbdff13c584b7197cfe05059" url: "https://pub.dev" source: hosted - version: "5.1.1" + version: "5.1.2" equatable: dependency: "direct main" description: @@ -213,10 +213,10 @@ packages: dependency: transitive description: name: ffi - sha256: a38574032c5f1dd06c4aee541789906c12ccaab8ba01446e800d9c5b79c4a978 + sha256: ed5337a5660c506388a9f012be0288fb38b49020ce2b45fe1f8b8323fe429f99 url: "https://pub.dev" source: hosted - version: "2.0.1" + version: "2.0.2" file: dependency: transitive description: @@ -548,10 +548,10 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "858aaa72d8f61637d64e776aca82e1c67e6d9ee07979123c5d17115031c1b13b" + sha256: "16d3fb6b3692ad244a695c0183fca18cf81fd4b821664394a781de42386bf022" url: "https://pub.dev" source: hosted - version: "2.1.0" + version: "2.1.1" shared_preferences_android: dependency: transitive description: @@ -564,10 +564,10 @@ packages: dependency: transitive description: name: shared_preferences_foundation - sha256: "0c1c16c56c9708aa9c361541a6f0e5cc6fc12a3232d866a687a7b7db30032b07" + sha256: e014107bb79d6d3297196f4f2d0db54b5d1f85b8ea8ff63b8e8b391a02700feb url: "https://pub.dev" source: hosted - version: "2.2.1" + version: "2.2.2" shared_preferences_linux: dependency: transitive description: From 687b264386a62bcbb1f98d84917a05fce6380bc4 Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Tue, 9 May 2023 18:29:41 -0300 Subject: [PATCH 7/8] lista de disciplinas --- lib/app/core/ui/widgets/my_appbar.dart | 2 +- lib/app/core/ui/widgets/my_input_button.dart | 7 ++++++- lib/app/pages/daily/daily_controller.dart | 1 + lib/app/pages/daily/widgets/lista_card_disciplina.dart | 1 - lib/app/pages/dashbord_daily/dashboard_page.dart | 4 ++-- lib/app/pages/dashbord_daily/widgets/line_dashboard.dart | 6 +++--- lib/app/pages/dashbord_daily/widgets/line_notas.dart | 4 ++-- lib/app/pages/home/home_controller.dart | 1 + lib/app/pages/home/widgets/card_home.dart | 5 +++-- lib/app/pages/schedule/schedule_page.dart | 3 +-- lib/app/repositories/daily/daily_repository_impl.dart | 1 - 11 files changed, 20 insertions(+), 15 deletions(-) diff --git a/lib/app/core/ui/widgets/my_appbar.dart b/lib/app/core/ui/widgets/my_appbar.dart index 4750e07..d900ed4 100644 --- a/lib/app/core/ui/widgets/my_appbar.dart +++ b/lib/app/core/ui/widgets/my_appbar.dart @@ -40,7 +40,7 @@ class MyAppbar extends AppBar { elevation: elevation, title: Text( title, - style: TextStyles.instance.labelPage, + style: TextStyles.instance.labelPage ), centerTitle: true, backgroundColor: ColorsApp.instance.background, diff --git a/lib/app/core/ui/widgets/my_input_button.dart b/lib/app/core/ui/widgets/my_input_button.dart index 09f2b4f..ce8330f 100644 --- a/lib/app/core/ui/widgets/my_input_button.dart +++ b/lib/app/core/ui/widgets/my_input_button.dart @@ -1,4 +1,5 @@ import 'package:academico_mobile/app/core/ui/styles/app_styles.dart'; +import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; import 'package:flutter/material.dart'; class MyInputButton extends StatelessWidget { @@ -21,7 +22,11 @@ class MyInputButton extends StatelessWidget { width: width, height: height, child: ElevatedButton( - style: context.appStyles.buttonStyle, + style: context.appStyles.buttonStyle.copyWith( + backgroundColor: MaterialStateProperty.all( + ColorsApp.instance.cardblue, + ), + ), onPressed: onPressed, child: Text(label), ), diff --git a/lib/app/pages/daily/daily_controller.dart b/lib/app/pages/daily/daily_controller.dart index 6ebf245..c30ac86 100644 --- a/lib/app/pages/daily/daily_controller.dart +++ b/lib/app/pages/daily/daily_controller.dart @@ -49,4 +49,5 @@ class DailyController extends Cubit { await Future.delayed(const Duration(seconds: 1)); emit(state.copyWith(status: DailyStateSatus.loaded, selected: index)); } + } diff --git a/lib/app/pages/daily/widgets/lista_card_disciplina.dart b/lib/app/pages/daily/widgets/lista_card_disciplina.dart index ba34d4e..042bc83 100644 --- a/lib/app/pages/daily/widgets/lista_card_disciplina.dart +++ b/lib/app/pages/daily/widgets/lista_card_disciplina.dart @@ -20,7 +20,6 @@ class ListaCardDisciplina extends StatelessWidget { return InkWell( splashColor: ColorsApp.instance.background, onTap: () { - print('Disciplina: ${disciplina.nome}'); Navigator.of(context).push( MaterialPageRoute( builder: (context) => DashboardPage( diff --git a/lib/app/pages/dashbord_daily/dashboard_page.dart b/lib/app/pages/dashbord_daily/dashboard_page.dart index c81188f..892a810 100644 --- a/lib/app/pages/dashbord_daily/dashboard_page.dart +++ b/lib/app/pages/dashbord_daily/dashboard_page.dart @@ -102,7 +102,7 @@ class _DashboardPageState extends State { ], ), Divider( - color: ColorsApp.instance.cardnoselected, + color: ColorsApp.instance.background, thickness: 1, ), LineDashboard( @@ -134,7 +134,7 @@ class _DashboardPageState extends State { ], ), Divider( - color: ColorsApp.instance.cardnoselected, + color: ColorsApp.instance.background, thickness: 1, ), LineNotas( diff --git a/lib/app/pages/dashbord_daily/widgets/line_dashboard.dart b/lib/app/pages/dashbord_daily/widgets/line_dashboard.dart index b0571cd..1033539 100644 --- a/lib/app/pages/dashbord_daily/widgets/line_dashboard.dart +++ b/lib/app/pages/dashbord_daily/widgets/line_dashboard.dart @@ -29,7 +29,7 @@ class LineDashboard extends StatelessWidget { child: Text( label, style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack4, + color: ColorsApp.instance.cardwhite, fontWeight: TextStyles.instance.textSemiBold.fontWeight, ), ), @@ -39,7 +39,7 @@ class LineDashboard extends StatelessWidget { child: Text( value, style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack4, + color: ColorsApp.instance.cardwhite, fontWeight: TextStyles.instance.textSemiBold.fontWeight, ), ), @@ -49,7 +49,7 @@ class LineDashboard extends StatelessWidget { child: Text( '$percent%', style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack4, + color: ColorsApp.instance.cardwhite, fontWeight: TextStyles.instance.textSemiBold.fontWeight, ), ), diff --git a/lib/app/pages/dashbord_daily/widgets/line_notas.dart b/lib/app/pages/dashbord_daily/widgets/line_notas.dart index f9d2b0f..c563f48 100644 --- a/lib/app/pages/dashbord_daily/widgets/line_notas.dart +++ b/lib/app/pages/dashbord_daily/widgets/line_notas.dart @@ -24,7 +24,7 @@ class LineNotas extends StatelessWidget { child: Text( label, style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack4, + color: ColorsApp.instance.cardwhite, fontWeight: TextStyles.instance.textSemiBold.fontWeight, ), ), @@ -34,7 +34,7 @@ class LineNotas extends StatelessWidget { child: Text( value, style: TextStyles.instance.texLabelH4.copyWith( - color: ColorsApp.instance.labelblack4, + color: ColorsApp.instance.cardwhite, fontWeight: TextStyles.instance.textSemiBold.fontWeight, ), ), diff --git a/lib/app/pages/home/home_controller.dart b/lib/app/pages/home/home_controller.dart index d2056b9..f1f6714 100644 --- a/lib/app/pages/home/home_controller.dart +++ b/lib/app/pages/home/home_controller.dart @@ -24,4 +24,5 @@ class HomeController extends Cubit { errorMessage: 'Error ao carregar home page')); } } + } diff --git a/lib/app/pages/home/widgets/card_home.dart b/lib/app/pages/home/widgets/card_home.dart index f694913..8f18b5e 100644 --- a/lib/app/pages/home/widgets/card_home.dart +++ b/lib/app/pages/home/widgets/card_home.dart @@ -3,10 +3,11 @@ import 'package:academico_mobile/app/core/ui/styles/colors_app.dart'; import 'package:academico_mobile/app/core/ui/styles/text_styles.dart'; import 'package:flutter/material.dart'; import 'package:academico_mobile/app/models/home_model.dart'; + class CardHome extends StatelessWidget { final HomePageModel listaCards; - const CardHome({ + const CardHome({ Key? key, required this.listaCards, }) : super(key: key); @@ -18,7 +19,7 @@ class CardHome extends StatelessWidget { child: ElevatedButton( style: ButtonStyle( backgroundColor: - MaterialStateProperty.all(ColorsApp.instance.cardnoselected), + MaterialStateProperty.all(ColorsApp.instance.primary), shape: MaterialStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(5), diff --git a/lib/app/pages/schedule/schedule_page.dart b/lib/app/pages/schedule/schedule_page.dart index e9dc59e..b40a110 100644 --- a/lib/app/pages/schedule/schedule_page.dart +++ b/lib/app/pages/schedule/schedule_page.dart @@ -76,8 +76,7 @@ class _SchedulePageState extends BaseState { daysOfWeek.add(startOfWeek.add(Duration(days: i))); } list = state - .schedule[ - state.selectedDay ?? DateTime.now().weekday] + .schedule[state.selectedDay ?? DateTime.now().weekday] .horarios; return Padding( padding: const EdgeInsets.only(right: 10), diff --git a/lib/app/repositories/daily/daily_repository_impl.dart b/lib/app/repositories/daily/daily_repository_impl.dart index 91916e9..6ee4801 100644 --- a/lib/app/repositories/daily/daily_repository_impl.dart +++ b/lib/app/repositories/daily/daily_repository_impl.dart @@ -19,7 +19,6 @@ class DailyRepositoryImpl implements DailyRepository { Future> findDaily() async { try { final result = await dio.unauth().get('/lista-disciplinas'); - final list = result.data as List; final semestres = list.map((e) => SemestreModel.fromJson(e)).toList(); return semestres; From c7d44f4af5ea76bbe4e54c70275cf641eaef9ce0 Mon Sep 17 00:00:00 2001 From: ErnestoMoraes Date: Wed, 10 May 2023 14:32:09 -0300 Subject: [PATCH 8/8] lista de disciplinas --- lib/app/pages/daily/daily_page.dart | 9 ++++++++- lib/app/pages/daily/widgets/my_switch.dart | 8 ++++---- lib/app/pages/schedule/schedule_state.dart | 2 +- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/lib/app/pages/daily/daily_page.dart b/lib/app/pages/daily/daily_page.dart index d6eeccd..2907298 100644 --- a/lib/app/pages/daily/daily_page.dart +++ b/lib/app/pages/daily/daily_page.dart @@ -24,7 +24,9 @@ class _DailyPageState extends BaseState { @override void onReady() async { await controller.loadSemestre(); - list = controller.state.semestres[0].disciplinas; + if (controller.state.isNow) { + list = controller.state.semestres[0].disciplinas; + } } @override @@ -123,6 +125,11 @@ class _DailyPageState extends BaseState { loaded: () => true, ), builder: (context, state) { + if (state.isNow) { + list = state.semestres[0].disciplinas; + } else { + list = state.semestres[state.selected].disciplinas; + } return Expanded( child: ListView.builder( shrinkWrap: true, diff --git a/lib/app/pages/daily/widgets/my_switch.dart b/lib/app/pages/daily/widgets/my_switch.dart index b21287a..faa0fb0 100644 --- a/lib/app/pages/daily/widgets/my_switch.dart +++ b/lib/app/pages/daily/widgets/my_switch.dart @@ -7,7 +7,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; class MySwitch extends StatefulWidget { - const MySwitch({super.key}); + const MySwitch({ + super.key, + }); @override State createState() => _MySwitchState(); @@ -31,9 +33,7 @@ class _MySwitchState extends State { borderRadius: BorderRadius.circular(5), ), child: TextButton( - onPressed: () { - context.read().changeIsNow(); - }, + onPressed: () => context.read().changeIsNow(), child: Text( 'Diário atual', style: TextStyles.instance.texLabelH2.copyWith( diff --git a/lib/app/pages/schedule/schedule_state.dart b/lib/app/pages/schedule/schedule_state.dart index b188e2b..41569a4 100644 --- a/lib/app/pages/schedule/schedule_state.dart +++ b/lib/app/pages/schedule/schedule_state.dart @@ -32,7 +32,7 @@ class ScheduleState extends Equatable { : status = ScheduleStatus.initial, schedule = [], errorMessage = null, - selectedDay = DateTime.now().weekday - 1; + selectedDay = DateTime.now().weekday; @override List get props => [status, schedule, errorMessage, selectedDay];