From 38b865b8460fe0b8543bab3fa8245750ac2d3d6d Mon Sep 17 00:00:00 2001 From: mikecoomber <58986130+mikecoomber@users.noreply.github.com> Date: Mon, 14 Oct 2024 16:15:12 +0100 Subject: [PATCH] fix(UX-1105): Updated search bar to use internal text field (#186) fix: Components using the internal text input are now sized correctly --- .../pages/components/search_bar_example.dart | 1 + .../components/search_bar_widgetbook.dart | 2 +- lib/src/components/date_input/date_input.dart | 1 + .../components/password/password_input.dart | 1 + lib/src/components/search_bar/search_bar.dart | 167 ++++++------------ .../components/select_input/select_input.dart | 1 + .../text_input/internal_text_input.dart | 33 +++- lib/src/components/time_input/time_input.dart | 1 + .../search_bar/golden/search_bar_default.png | Bin 3971 -> 3721 bytes .../search_bar/golden/search_bar_full.png | Bin 5058 -> 4780 bytes .../search_bar/golden/search_bar_medium.png | Bin 3971 -> 3721 bytes .../search_bar/golden/search_bar_sharp.png | Bin 3779 -> 3518 bytes .../search_bar/golden/search_bar_small.png | Bin 3903 -> 3658 bytes .../search_bar/search_bar_test.dart | 12 +- 14 files changed, 92 insertions(+), 127 deletions(-) diff --git a/example/lib/pages/components/search_bar_example.dart b/example/lib/pages/components/search_bar_example.dart index b44ee768..5395fa47 100644 --- a/example/lib/pages/components/search_bar_example.dart +++ b/example/lib/pages/components/search_bar_example.dart @@ -27,6 +27,7 @@ class _SearchBarExampleState extends State { padding: const EdgeInsets.all(20), child: ZetaSearchBar( onChange: (value) {}, + showSpeechToText: false, textInputAction: TextInputAction.search, onFieldSubmitted: (text) { print(text); diff --git a/example/widgetbook/pages/components/search_bar_widgetbook.dart b/example/widgetbook/pages/components/search_bar_widgetbook.dart index 9072142b..fc767a8d 100644 --- a/example/widgetbook/pages/components/search_bar_widgetbook.dart +++ b/example/widgetbook/pages/components/search_bar_widgetbook.dart @@ -49,7 +49,7 @@ Widget searchBarUseCase(BuildContext context) { size: size, shape: shape, disabled: disabled, - hintText: hint, + placeholder: hint, showSpeechToText: showSpeechToText, onChange: (value) { if (value == null) return; diff --git a/lib/src/components/date_input/date_input.dart b/lib/src/components/date_input/date_input.dart index 20905696..88f45768 100644 --- a/lib/src/components/date_input/date_input.dart +++ b/lib/src/components/date_input/date_input.dart @@ -47,6 +47,7 @@ class ZetaDateInput extends ZetaFormField { return InternalTextInput( label: label, + constrained: true, hintText: hintText, errorText: field.errorText ?? errorText, size: size, diff --git a/lib/src/components/password/password_input.dart b/lib/src/components/password/password_input.dart index cb3c01d8..152de9f8 100644 --- a/lib/src/components/password/password_input.dart +++ b/lib/src/components/password/password_input.dart @@ -50,6 +50,7 @@ class ZetaPasswordInput extends ZetaTextFormField { requirementLevel: requirementLevel, errorText: field.errorText ?? errorText, onSubmit: onSubmit, + constrained: true, disabled: disabled, obscureText: state._obscureText, semanticLabel: semanticLabel, diff --git a/lib/src/components/search_bar/search_bar.dart b/lib/src/components/search_bar/search_bar.dart index 57b1a9e2..fc536ede 100644 --- a/lib/src/components/search_bar/search_bar.dart +++ b/lib/src/components/search_bar/search_bar.dart @@ -3,6 +3,7 @@ import 'package:flutter/material.dart'; import '../../../zeta_flutter.dart'; import '../../interfaces/form_field.dart'; import '../buttons/input_icon_button.dart'; +import '../text_input/internal_text_input.dart'; /// ZetaSearchBar provides input field for searching. /// {@category Components} @@ -25,8 +26,9 @@ class ZetaSearchBar extends ZetaTextFormField { super.initialValue, this.size = ZetaWidgetSize.medium, this.shape = ZetaWidgetBorder.rounded, - @Deprecated('Use hintText instead. ' 'deprecated as of 0.15.0') String? hint, - this.hintText, + @Deprecated('hint has been removed. ' 'deprecated as of 0.15.0') String? hint, + @Deprecated('Use placeholder instead. ' 'deprecated as of 0.16.0') String? hintText, + this.placeholder, this.onSpeechToText, this.showSpeechToText = true, @Deprecated('Use disabled instead. ' 'enabled is deprecated as of 0.11.0') bool enabled = true, @@ -49,130 +51,74 @@ class ZetaSearchBar extends ZetaTextFormField { _ => zeta.radius.none, }; - final defaultInputBorder = OutlineInputBorder( - borderRadius: borderRadius, - borderSide: BorderSide(color: zeta.colors.cool.shade40), - ); - - final focusedBorder = defaultInputBorder.copyWith( - borderSide: BorderSide( - color: zeta.colors.blue.shade50, - width: zeta.spacing.minimum, - ), - ); - - final disabledborder = defaultInputBorder.copyWith( - borderSide: BorderSide(color: zeta.colors.borderDisabled), - ); - late final double iconSize; - late final double padding; switch (size) { case ZetaWidgetSize.large: iconSize = zeta.spacing.xl_2; - padding = zeta.spacing.medium; case ZetaWidgetSize.medium: iconSize = zeta.spacing.xl; - padding = zeta.spacing.small; case ZetaWidgetSize.small: iconSize = zeta.spacing.large; - padding = zeta.spacing.minimum; } return ZetaRoundedScope( rounded: shape != ZetaWidgetBorder.sharp, child: Semantics( excludeSemantics: disabled, - label: disabled ? hintText ?? 'Search' : null, // TODO(UX-1003): Localize + label: disabled ? placeholder ?? 'Search' : null, // TODO(UX-1003): Localize enabled: disabled ? false : null, - child: TextFormField( + child: InternalTextInput( focusNode: focusNode, - enabled: !disabled, + size: size, + disabled: disabled, + constrained: true, + borderRadius: borderRadius, controller: state.effectiveController, keyboardType: TextInputType.text, textInputAction: textInputAction, - onFieldSubmitted: onFieldSubmitted, - onChanged: state.onChange, - style: ZetaTextStyles.bodyMedium, - decoration: InputDecoration( - isDense: true, - contentPadding: EdgeInsets.symmetric( - horizontal: 10, - vertical: padding, - ), - hintText: hintText ?? 'Search', // TODO(UX-1003): Localize - hintStyle: ZetaTextStyles.bodyMedium.copyWith( - color: !disabled ? zeta.colors.textSubtle : zeta.colors.textDisabled, - ), - prefixIcon: Padding( - padding: EdgeInsets.only(left: zeta.spacing.medium, right: zeta.spacing.small), - child: ZetaIcon( - ZetaIcons.search, - color: !disabled ? zeta.colors.cool.shade70 : zeta.colors.cool.shade50, - size: iconSize, - ), - ), - prefixIconConstraints: BoxConstraints( - minHeight: zeta.spacing.xl_2, - minWidth: zeta.spacing.xl_2, - ), - suffixIcon: IntrinsicHeight( - child: Row( - mainAxisSize: MainAxisSize.min, - children: [ - if (state.effectiveController.text.isNotEmpty && !disabled) ...[ - Semantics( - container: true, - button: true, - excludeSemantics: true, - label: clearSemanticLabel, - child: InputIconButton( - icon: ZetaIcons.cancel, - onTap: () => state.onChange(''), - disabled: disabled, - size: size, - color: zeta.colors.iconSubtle, - key: const ValueKey('search-clear-btn'), - ), - ), - if (showSpeechToText) - SizedBox( - height: iconSize, - child: VerticalDivider( - color: zeta.colors.cool.shade40, - width: 5, - thickness: 1, - ), - ), - ], - if (showSpeechToText) - Semantics( - label: microphoneSemanticLabel, - container: true, - button: true, - excludeSemantics: true, - child: InputIconButton( - icon: ZetaIcons.microphone, - onTap: state.onSpeechToText, - key: const ValueKey('speech-to-text-btn'), - disabled: disabled, - size: size, - color: zeta.colors.iconDefault, - ), + placeholder: placeholder ?? 'Search', // TODO(UX-1003): Localize + onSubmit: onFieldSubmitted, + onChange: state.onChange, + prefix: ZetaIcon( + ZetaIcons.search, + color: !disabled ? zeta.colors.iconSubtle : zeta.colors.iconDisabled, + size: iconSize, + ), + suffix: Row( + mainAxisSize: MainAxisSize.min, + children: [ + if (state.effectiveController.text.isNotEmpty && !disabled) ...[ + InputIconButton( + icon: ZetaIcons.cancel, + onTap: () => state.onChange(''), + disabled: disabled, + size: size, + semanticLabel: clearSemanticLabel, + color: zeta.colors.iconSubtle, + key: const ValueKey('search-clear-btn'), + ), + if (showSpeechToText) + SizedBox( + height: iconSize, + child: VerticalDivider( + color: zeta.colors.cool.shade40, + width: 5, + thickness: 1, ), - ], - ), - ), - suffixIconConstraints: BoxConstraints( - minHeight: zeta.spacing.xl_2, - minWidth: zeta.spacing.xl_2, - ), - filled: !disabled ? null : true, - fillColor: !disabled ? null : zeta.colors.cool.shade30, - enabledBorder: defaultInputBorder, - focusedBorder: focusedBorder, - disabledBorder: disabledborder, + ), + ], + if (showSpeechToText) + InputIconButton( + icon: ZetaIcons.microphone, + onTap: state.onSpeechToText, + key: const ValueKey('speech-to-text-btn'), + disabled: disabled, + semanticLabel: microphoneSemanticLabel, + size: size, + color: zeta.colors.iconDefault, + ), + ], ), ), ), @@ -184,14 +130,13 @@ class ZetaSearchBar extends ZetaTextFormField { /// Default is [ZetaWidgetSize.medium] final ZetaWidgetSize size; + /// Placeholder text for the search field. + final String? placeholder; + /// Determines the shape of the input field. /// Default is [ZetaWidgetBorder.rounded] final ZetaWidgetBorder shape; - /// If provided, displays a hint inside the input field. - /// Default is `Search`. - final String? hintText; - /// The type of action button to use for the keyboard. final TextInputAction? textInputAction; @@ -224,14 +169,14 @@ class ZetaSearchBar extends ZetaTextFormField { properties ..add(EnumProperty('size', size)) ..add(EnumProperty('shape', shape)) - ..add(StringProperty('hintText', hintText)) ..add(StringProperty('initialValue', initialValue)) ..add(ObjectFlagProperty.has('onSpeechToText', onSpeechToText)) ..add(DiagnosticsProperty('showSpeechToText', showSpeechToText)) ..add(DiagnosticsProperty('focusNode', focusNode)) ..add(EnumProperty('textInputAction', textInputAction)) ..add(StringProperty('microphoneSemanticLabel', microphoneSemanticLabel)) - ..add(StringProperty('clearSemanticLabel', clearSemanticLabel)); + ..add(StringProperty('clearSemanticLabel', clearSemanticLabel)) + ..add(StringProperty('placeholder', placeholder)); } } diff --git a/lib/src/components/select_input/select_input.dart b/lib/src/components/select_input/select_input.dart index d530feb2..f2c18f3c 100644 --- a/lib/src/components/select_input/select_input.dart +++ b/lib/src/components/select_input/select_input.dart @@ -54,6 +54,7 @@ class ZetaSelectInput extends ZetaFormField { builder: (context, _, controller) { return InternalTextInput( size: size, + constrained: true, requirementLevel: requirementLevel, disabled: disabled, controller: state.inputController, diff --git a/lib/src/components/text_input/internal_text_input.dart b/lib/src/components/text_input/internal_text_input.dart index 05d7a9c1..2c20bba0 100644 --- a/lib/src/components/text_input/internal_text_input.dart +++ b/lib/src/components/text_input/internal_text_input.dart @@ -36,6 +36,8 @@ class InternalTextInput extends ZetaStatefulWidget { this.externalPrefix, this.semanticLabel, this.borderRadius, + this.textInputAction, + this.constrained = false, }) : requirementLevel = requirementLevel ?? ZetaFormFieldRequirement.none, assert(prefix == null || prefixText == null, 'Only one of prefix or prefixText can be accepted.'), assert(suffix == null || suffixText == null, 'Only one of suffix or suffixText can be accepted.'); @@ -130,6 +132,12 @@ class InternalTextInput extends ZetaStatefulWidget { /// The widget displayed before the input. final Widget? externalPrefix; + /// The action to take when the user submits the input. + final TextInputAction? textInputAction; + + /// Determines if the prefix and suffix should be constrained. + final bool constrained; + @override State createState() => InternalTextInputState(); @override @@ -156,7 +164,9 @@ class InternalTextInput extends ZetaStatefulWidget { ..add(DiagnosticsProperty('keyboardType', keyboardType)) ..add(DiagnosticsProperty('focusNode', focusNode)) ..add(DiagnosticsProperty('borderRadius', borderRadius)) - ..add(StringProperty('semanticLabel', semanticLabel)); + ..add(StringProperty('semanticLabel', semanticLabel)) + ..add(EnumProperty('textInputAction', textInputAction)) + ..add(DiagnosticsProperty('constrained', constrained)); } } @@ -197,7 +207,7 @@ class InternalTextInputState extends State { case ZetaWidgetSize.medium: return EdgeInsets.symmetric( horizontal: Zeta.of(context).spacing.medium, - vertical: Zeta.of(context).spacing.small, + vertical: Zeta.of(context).spacing.medium, ); } } @@ -221,7 +231,7 @@ class InternalTextInputState extends State { width = Zeta.of(context).spacing.xl_6; height = Zeta.of(context).spacing.xl_6; case ZetaWidgetSize.small: - width = Zeta.of(context).spacing.xl_6; + width = Zeta.of(context).spacing.xl_4; height = Zeta.of(context).spacing.xl_4; } return BoxConstraints( @@ -277,11 +287,11 @@ class InternalTextInputState extends State { ); OutlineInputBorder _focusedBorder(bool rounded) => _baseBorder(rounded).copyWith( - borderSide: BorderSide(color: _colors.primary.shade50, width: ZetaBorders.medium), - ); // TODO(mikecoomber): change to colors.borderPrimary when added + borderSide: BorderSide(color: _colors.borderPrimary, width: ZetaBorders.medium), + ); OutlineInputBorder _errorBorder(bool rounded) => _baseBorder(rounded).copyWith( - borderSide: BorderSide(color: _colors.error, width: ZetaBorders.medium), + borderSide: BorderSide(color: _colors.borderNegative, width: ZetaBorders.medium), ); @override @@ -337,6 +347,7 @@ class InternalTextInputState extends State { onChanged: widget.onChange, onSubmitted: widget.onSubmit, style: _baseTextStyle, + textInputAction: widget.textInputAction, cursorErrorColor: _colors.error, obscureText: widget.obscureText, focusNode: widget.focusNode, @@ -345,9 +356,11 @@ class InternalTextInputState extends State { contentPadding: _contentPadding, filled: true, prefixIcon: _prefix, - prefixIconConstraints: widget.prefixText != null ? _affixConstraints : null, + prefixIconConstraints: + widget.prefixText != null || widget.constrained ? _affixConstraints : null, suffixIcon: _suffix, - suffixIconConstraints: widget.suffixText != null ? _affixConstraints : null, + suffixIconConstraints: + widget.suffixText != null || widget.constrained ? _affixConstraints : null, focusColor: _backgroundColor, hoverColor: _backgroundColor, fillColor: _backgroundColor, @@ -358,7 +371,9 @@ class InternalTextInputState extends State { errorBorder: widget.disabled ? _baseBorder(rounded) : _errorBorder(rounded), hintText: widget.placeholder, errorText: widget.errorText, - hintStyle: _baseTextStyle, + hintStyle: _baseTextStyle.copyWith( + color: widget.disabled ? _colors.textDisabled : _colors.textSubtle, + ), errorStyle: const TextStyle(height: 0.001, color: Colors.transparent), ), ), diff --git a/lib/src/components/time_input/time_input.dart b/lib/src/components/time_input/time_input.dart index 3d3d0467..ee7e49df 100644 --- a/lib/src/components/time_input/time_input.dart +++ b/lib/src/components/time_input/time_input.dart @@ -49,6 +49,7 @@ class ZetaTimeInput extends ZetaFormField { return InternalTextInput( label: label, hintText: hintText, + constrained: true, errorText: field.errorText ?? errorText, size: size, placeholder: state.timeFormat, diff --git a/test/src/components/search_bar/golden/search_bar_default.png b/test/src/components/search_bar/golden/search_bar_default.png index 3926f59791cc35deb2fc037a86e9248f31803186..614622dbf0597acefab2dda9bd7c29c71c2b4c21 100644 GIT binary patch delta 688 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 GxBmqJ`Cs?| diff --git a/test/src/components/search_bar/golden/search_bar_medium.png b/test/src/components/search_bar/golden/search_bar_medium.png index 3926f59791cc35deb2fc037a86e9248f31803186..614622dbf0597acefab2dda9bd7c29c71c2b4c21 100644 GIT binary patch delta 688 zcmV;h0#E&eABi21Kz|N1Nkl>3`UmOvdE!aIyO1ufNC6 z&ek|L+aA;D=DKGD007R2mCFE0Jwh$ z5C8xmBR~KEfRlOyAb;HT6X>6Q_QiPT-S>~R*~>4zFs@v_bgZ=i0Kmz8_|eDX#*NpH zwf3#I-W=DjT|LqMPCx(vfXrQ=fYhFU@s$&;zj)#4@#Rx^nr_ zxN`Z@y_p680Jx{FU%NW4U%R@t{hfdS000>Q0ssJHCO`i2+v>4L9$xnx006)l_tUSx zI{^Uz06LR^10<7=0}y|+F`aIXsmke|9)W3<~QfenWeqGy~hU!hvVM;?XkJFGiI~>0RRAS6n`d@wXr@uHO`$qJyus& z#?tQYgU9c^e|MZd_0m|Mo*I+M+Hv0z004MF%x3#zb8Ba8?>rozf9=9p`q%BdkH>gC zE}lPo+;;;20A5gcHa5o?kH_-n*3MX;o;vRP0000lu=VN5vAMN7mS?klAG-no0G_GI zWNpl5`(ydIF9iYs0DO9rfC43dt4}-d;hnqVv4wzhZ1AOG~{r+V%uTifG@ zKl9Mu7J@@>VzWDlh_iz80d;Y@tSH|6qkLKV1h1bWsf1iKz9u^VX5=Tqr=k{jG0~^RJwH;+c() z?mcyY0002b-sQ{R9j{)z_{1|G-nnz60peS*lRE(;e+Uo&03fr_KO+3e&)yo7$!DH; zW;WYfWCZ{K@Ql3q<`2fnlP8{dW_S0&k?ve5KyH8V@1wd0000ns`|Wq~oj!sE003m3 z`W=vKSFem~SFb#ay8r+H&)AI{*T;<;*N<(#cR&CDfXs6lAWKK^jOC@pp0eQhSXy3i z|AIf6C8Y%)u)O?SzBB*;_&>MMAE7@h>+5I6Z-4poDl|*3NO?2LJ$gfo*Q>j`iuuv3&0A>9M`@ zaNOD0^iBu>0C1#cv;A>rV{>fpJQ(NBPRG*T-rnPbgTry}{?^#s+7%%H0Kk!%OxDKw z^yD~qb~;v9SNi1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9ji|s42tK#WAE}&fB{Sv!*3VG(0TdlpG-x&ZDH3`i4PFhWVx#j}*(n6v;)) z6E|=-IW{}GN=Vr-2>L3q9bTsWP9QAJH1EItd-=PiPv1YRe0}!!A@l8@KVN?cw20$O zzu~b*H(Mj;Gcz#!IREzD+kWHCb}S4G1yvjZ3=9g&4h#$pJq(Nt3`R^q(Gx@oem*XH zqwaT|P35neMXB5K?@DB^))qd?#K3U5`sb^!H*W2+zxZacJOA-#$9{$UzS{tF#?0jV z4OiCP-(!6B&!zky!KdSMH;qPnVv4 zd~ok>;q%N42j(y1njn5&PX6WYOl6=I7M1p8`+=O|?&tnF%he+o7#!R{Hb^o8B~w^9 z7#Jo9DqsXbKrkA-F2n(cCebJ4SQI jXzn1gEk0nyMIEzEisKrki=q0!Mj?ZztDnm{r-UW|i=!SM literal 3779 zcmeAS@N?(olHy`uVBq!ia0y~yU{+vYV2a>i1B%QlYbpRzjKx9jP7LeL$-D$|Sc;uI zLpXq-h9jkefq^gA)5S5QV$R#U`}^+~%N+RlJ$Aju--pLFvkZO+Hv1|GF>iKFa$WAF z;ybHkgU4etLAPeLUPeX1$^RQ1n_3)s9vyGcxTXEedG%H8{|zxk_s`$`>?Pm-^Y5=c z_fFpZwC8>Q?B8!bum3Lxw7Id>@Ys&`_pHr+19=Dj-w}_mGk<3OTL{RR>f8WSAj!zY zz>vbi!N4#9b;EVq~hn-7(AjKa2Uv-17U<^0l8{`ka=ldGN0=;s3swX^adFFZ*OFbN76F7Hxd? zUG1yRjay1GF8woQ_jq_|srTdG@^y2*^t9?mA3HjA>dfcc^>ljn>&4Bf{CDZpsTub- zrC$CP9}_9b9sDi-u2tUs;@4+BGcbI}S7SY)%x`Z}ma{+as`2vke+=*ae{k5;_WPBW z#*cSCkDpPrbz}1JZ-u|U%$)iB{m$R#K3=_k|C~+z=SRMee|+k^`Tc(B^B=Ef-~66` zyX>q*`MdKopO?S8W5~Dv(w(Gmf8k`imVJR`Z*N)NtNVNP z>^`8_hI4;rO5<`gR-fP&+-z`6BEIJ5-L(763=BJ%&cyC0c=-P8K46#>q<$bisBl|A zR7j6%Cni0PhSF##;V-d9Q^;rv8BHNnsv1XYE&}bN(b8tLv>7dJh%IgYGu+H+(s%MY QsKo#Tp00i_>zopr0Haj%6aWAK diff --git a/test/src/components/search_bar/golden/search_bar_small.png b/test/src/components/search_bar/golden/search_bar_small.png index 835f47d2f0f62de0aeba4eafd0f6c1ea37f95a20..0f23bf32428461673e989cf7a66f613be843fd81 100644 GIT binary patch delta 629 zcmdllcS>f0Lp|>oPZ!6KiaBrZZp>PeD$?*Uzs+aT$u1qSut#QMN@3cMR5_ZK_HLaz z_rcSM+Yww%(>Lfubw)(&$XeVwD|PbBGxB9Rdm2(ye)px#U;gh$@vZ5`PtKUlKKt!u znRVFf%sK1zj+w;rF)%dD-Vh)$`GzUT4d!-eUUCSu*q zwdXk)814vNF0nipCZ4?aUeEM*`wY_R=h@xtGdy-z{QaA1GX{nS)2wQ1%(mTrJ7Yf3 z?72@b?t9M2z>v2QXtYIq{;`@_dVk+=F)&mt0~%=PJ3V>ddq<${&)XS*s*IRe7#L1) z2rw`xC_4Z}dl(q&VWKg=8BVav*KN7nzW>Lc&Gp9o3=9GlU+-mG@BRPtV!!#P@?4OP zGw0MVtiP4>W|!v8uYaxc@5}Sc)m6X!{(k@WcRxO@USIy>U-aXHhx6y%{C>aY@z;-c zzuUhtIRE$KOLh79-?j`4Zyv2Wdu-k8Nvm%(FfcGkGBPnt)?|@!yZMvv#JX~8p!xsT z&EEI9P*fV^#NxNSCql(9FakyUSL-dX*EUmNU~owLc3FRa?)$x;KJ9xBG$U`P`~H7< z%uEanC6gIhwCbOAA3Zo@+3DKzK=0m30tO{080;hEdN*G^3Js~xSC3j)+R1#L{P^(3 zxcp-;9~;jGTKB-s_wrKb}Oj4nNUmySR zqDqTrn{V1PZhF5E6tvC%n^+kbQdoeIH(~QkmI+*w9a!#&J}9KRlrKz|PDNklIwaba&Hx1ONc8h~@HR%oj)F@aWli!1I6a5l!-_~L8(o8B7$ z0B}X!e>fjwoQ=tRaWwX3*EhW%007_$+nZe*^Tm@fSuRgpy8-|JK2g)@?pQ8Q#$?kQ z0RR9#KLiK>0Fy-nD}UKJ&o4iJ{(Ri~;KOqbc;hQ~#$@vH&ROSmKW=Axdz`LTYp>tk z*%>FNr)#f&zFLjR_V&i+pRQJ8=OXiWcgLMCe`)RY004Y;tX8Y>{`-GF*P1uq{OZ`g zz~{~XIah!jEDpy{fA;fp4fyS^-X8mVH!uBlKW;X=F&2x%wSU)tqSk z%b))=Zr!?d;n}WW0RRA*bDeYY0AvIR0F#&l7k^p%F}(k{_rZ94^Tm(hogW;my&(VqpmX=`-^Q(5`!D?2qeqV~ zecsvu^7b!(bD8@9001`N`#<<$I`3Rpu(sA1u+AC)0N|6ewRQea>Fca{k#n7Z?Csqg zfBeJmE@dzP0I(VR`}^a)yMNutY+phL001%q1ONcYd@2IuGB<9MO)hvR?V?xOwk8*x zf5CTR>w+&ZnS3h#6aWCY;?{l&)@AbD5&!`BeDH5?001B(KmY)MjFTq;AAblC001B( zKmY)Mi~s=u05X&5bayP5C!5{}003}>Ete-_I^7+Uz1j6KUmR_EKL7y06*gZy8GEy9 zV{&`{#yC8BHts*1I|%^*04~*Xc{1)loR7n!r{nhiY-}ALAD^9`uEs}?7h}G7B0>NF zfJ-x-?vB0LwQ+lYHg