From ea9021a414005534d971b3251395aa77ee9251fc Mon Sep 17 00:00:00 2001 From: Ardhya Novri Date: Sun, 18 Oct 2026 07:18:02 +0700 Subject: [PATCH] Add correctness-gated UART parser profiling with recorded timings --- .github/workflows/tests.yml | 4 +- CHANGELOG.md | 6 + MANIFEST.in | 2 +- README.md | 27 +- docs/PROFILING.md | 42 ++ docs/profile-preview.png | Bin 0 -> 155582 bytes docs/profile-sample.html | 26 + docs/profile-sample.json | 684 +++++++++++++++++++++++++ pyproject.toml | 2 +- src/uart_fixture_kit/__init__.py | 2 +- src/uart_fixture_kit/cli.py | 20 +- src/uart_fixture_kit/optimized.py | 58 +++ src/uart_fixture_kit/profile_report.py | 42 ++ src/uart_fixture_kit/profiler.py | 178 +++++++ tests/test_profiler.py | 114 +++++ 15 files changed, 1201 insertions(+), 6 deletions(-) create mode 100644 docs/PROFILING.md create mode 100644 docs/profile-preview.png create mode 100644 docs/profile-sample.html create mode 100644 docs/profile-sample.json create mode 100644 src/uart_fixture_kit/optimized.py create mode 100644 src/uart_fixture_kit/profile_report.py create mode 100644 src/uart_fixture_kit/profiler.py create mode 100644 tests/test_profiler.py diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index d8541c8..e970c8f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -30,6 +30,8 @@ jobs: - name: Build source and wheel distributions run: python -m build - name: Install wheel instead of editable source - run: python -m pip install --force-reinstall --no-deps dist/uart_fixture_kit-0.1.0-py3-none-any.whl + run: python -m pip install --force-reinstall --no-deps dist/uart_fixture_kit-0.2.0-py3-none-any.whl - name: Replay installed fixtures run: python -m uart_fixture_kit demo --json + - name: Profile installed parsers with a small synthetic corpus + run: python -m uart_fixture_kit profile --records 8 --repeats 3 --warmups 1 --output profile-smoke.json --html profile-smoke.html diff --git a/CHANGELOG.md b/CHANGELOG.md index fd0ef75..81145ad 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.2.0 + +- Chunk-scanning JSON alternative, preserving the byte-wise reference parser. +- Correctness-gated parser profiles with fixed synthetic workloads, raw paired timing samples, source/fixture hashes and cProfile hotspots. +- Standalone HTML profile reports and installed-wheel CLI verification in CI. + ## 0.1.0 - Protocol-independent JSON byte fixtures and virtual-time replay. diff --git a/MANIFEST.in b/MANIFEST.in index 435ac67..097e40b 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,2 @@ include CONTRIBUTING.md CHANGELOG.md -recursive-include docs *.md +recursive-include docs *.md *.json *.html *.png diff --git a/README.md b/README.md index bd025bb..f30ff05 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ A serial read can return half a message, several messages, or noise followed by Python 3.10 or newer. No runtime dependencies, API keys, GPU, or hardware. ```console -python -m pip install "git+https://github.com/vanovri/uart-fixture-kit.git@v0.1.0" +python -m pip install "git+https://github.com/vanovri/uart-fixture-kit.git@v0.2.0" uart-fixture-kit demo uart-fixture-kit demo --json ``` @@ -20,6 +20,29 @@ The demo runs bundled synthetic cases for newline JSON and a small binary protoc GitHub is the distribution source for this release. This package has not been published on PyPI. +## UART Parse Profiler + +Version 0.2 adds a chunk-scanning JSON alternative without changing the byte-wise reference parser or the default demo. Measure both against the same synthetic input and virtual timestamps: + +```console +uart-fixture-kit profile --records 2048 --repeats 9 --warmups 3 --output uart-profile.json --html uart-profile.html +``` + +Open the HTML file for the timing table and cProfile hotspots. JSON keeps every timing sample, environment details, source hashes and a manifest covering input bytes, timestamps and expected records. Seven saved JSON fixtures and four generated workloads must match their explicit record oracles on both parsers before timing. Each timed run is checked again outside the timer. No network connection or serial hardware is required. + +One Windows/CPython 3.14.7 run on 18 October 2026 measured the following medians over nine paired repeats: + +| Synthetic workload | Reference ms | Chunk scanning ms | Reference / candidate | +| --- | ---: | ---: | ---: | +| 76,739 bytes in 4,096-byte chunks | 18.368 | 8.669 | 2.12x | +| The same stream, repeating chunks 1/2/7/3 | 27.723 | 26.099 | 1.06x | +| The same stream, one byte per event | 44.280 | 56.507 | 0.78x | +| Malformed, oversized, stale and partial input recovery | 0.064 | 0.046 | 1.38x | + +The alternative was **slower for byte-by-byte arrival**. The smaller difference on fragmented input may be sensitive to measurement noise. These are parser/event-dispatch measurements on one machine, not UART link speed or a general performance guarantee. The original parser remains the default. See [methodology and exact replay](docs/PROFILING.md), [recorded JSON](docs/profile-sample.json) and [standalone HTML](docs/profile-sample.html). + +![Actual local profile report, including the slower byte-wise case](docs/profile-preview.png) + ## Catch a real class of bug This fixture delivers `OK\n` in two reads: @@ -150,6 +173,8 @@ python -m build Tests include a failing broken-parser regression, every two-chunk split of representative streams, byte-by-byte corruption recovery, timer boundary cases, CLI exit codes, fixture validation, and installed-package demo checks. CI runs on Windows and Linux across Python 3.10, 3.12, and 3.14. +Profiler tests also cover the 127/128/129-byte line boundary, mixed invalid input, empty-feed timeout behavior, bounded oversized partial input, rejection of an incorrect candidate before timing, raw-sample reports and the installed-wheel CLI. + ## Related tools [pySerial](https://pyserial.readthedocs.io/en/latest/) provides serial transport and loopback facilities. [Serial Studio](https://github.com/Serial-Studio/Serial-Studio) provides telemetry visualization and capture/replay. [WireDAQ](https://github.com/wuisabel-gif/WireDAQ) includes its own wire protocol and fault simulation. This project focuses on a small fixture contract for adapters to existing parsers. Replay and fault injection are established techniques. diff --git a/docs/PROFILING.md b/docs/PROFILING.md new file mode 100644 index 0000000..5262d75 --- /dev/null +++ b/docs/PROFILING.md @@ -0,0 +1,42 @@ +# UART Parse Profiler + +This extends the existing synthetic parser fixture kit. The reference `JsonLineParser` remains unchanged. `ChunkedJsonLineParser` scans for newlines using `bytes.find` and appends bounded slices instead of looping over every byte in Python. Both retain unfinished bytes, reject lines longer than 128 bytes, recover after newline or inactivity, validate fields and emit the same diagnostic records. The alternative inherits the reference's `advance` and `finish` methods. + +## Replay the comparison + +```console +python -m uart_fixture_kit profile --records 2048 --repeats 9 --warmups 3 --output uart-profile.json --html uart-profile.html +``` + +This runs two parsers over seven bundled JSON fixtures and four generated workloads, giving 22 correctness comparisons. A mismatch prevents timing entirely. Subsequent warm-ups, measured runs and cProfile runs must also preserve canonical JSON output exactly. Boolean and numeric validation, diagnostic order and unfinished-buffer behavior belong to the contract, not just decoded values. + +The three valid-data workloads use the same 2,048 records and 76,739 bytes. Only chunk boundaries and the resulting virtual event schedule differ: chunks of up to 4,096 bytes, a repeating 1/2/7/3 schedule, and individual bytes. The fourth workload has an explicit oracle for an expired partial record, invalid UTF-8, an oversized line, a bad unit, a valid message, and an EOF fragment. Workload creation is deterministic and uses no random state. Additional seeded differential tests explore mixed-stream chunk boundaries, alongside independent saved oracles and line-boundary cases. + +`fixture_manifest` and each workload hash cover canonical JSON containing the fixture name, exact event bytes, timestamps, end time and expected records. The report hashes both parser class definitions. Because the alternative inherits timer/EOF methods, keep the reference source hash with the alternative's hash. Reports record Python, OS, CPU information, repeat count and warm-up count. Source and fixture hashes identify what ran, not physical-device validity. + +## What the timer measures + +The `perf_counter_ns` interval includes constructing a fresh parser, dispatching virtual `advance`/`feed`/`finish` calls and collecting emitted records. It excludes fixture generation, JSON equivalence checks, hashing, report creation and cProfile. Virtual timestamps are inputs to parser logic, not wall-clock sleeps. + +Both parsers receive warm-ups before measurement. Each repeat is paired. The reference runs first on even-numbered iterations and second on odd-numbered iterations to reduce a fixed ordering bias. Garbage collection is disabled only during each timed run and restored to its previous state afterward. Raw nanosecond samples are retained, with median, minimum, maximum, population standard deviation and nearest-rank observed p95. With nine samples, p95 is the maximum observed sample, not a latency-distribution estimate. + +`speed_ratio` is reference median divided by alternative median. Above 1 means the alternative took less median time. `candidate_time_change_percent` is (alternative/reference - 1) times 100, so a positive number means a slowdown. These ratios use measured parser times, not a device's baud rate. Small recovery timings and small differences are especially sensitive to noise. + +A separate cProfile run uses the bulk workload. Its cumulative timings overlap and include instrumentation overhead. Do not add cumulative times or compare them directly with uninstrumented wall times. It helps locate Python-level work; it does not prove the entire application sped up. + +## Observed example + +The checked-in `profile-sample.json` and HTML came from one run on 18 October 2026 WIB, CPython 3.14.7, Windows 11, Intel64 Family 6 Model 165, with eight logical CPUs. With nine measured repeats and three warm-ups: + +- Bulk chunk median: 18.368 ms reference, 8.669 ms alternative, ratio 2.12x. +- Fragmented median: 27.723 ms reference, 26.099 ms alternative, ratio 1.06x. +- Byte-wise median: 44.280 ms reference, 56.507 ms alternative, ratio 0.78x. +- Fault-recovery median: 0.064 ms reference, 0.046 ms alternative, ratio 1.38x. + +The alternative was slower on one-byte events. It remains opt-in. Larger chunks allow the C-level search to avoid much of the Python byte loop, while tiny chunks still pay search and method-call overhead. On the bulk cProfile run, the reference made 74,691 `bytearray.append` calls. That observation supports the mechanism being explored; it does not establish the same ratio on another machine. + +There is no CPU-affinity setting, process isolation, thermal control or hardware I/O. Other applications may affect the results. The HTML and JSON deliberately preserve the slower case. Re-run on your target workload before choosing a parser. This synthetic comparison does not validate electrical UART behavior, sensor timing, production reliability or clinical use. + +## Provenance + +The source, workload definitions and record oracles are original synthetic additions for this project, developed with Codex assistance. They contain no shared thesis code, private captures or subject data. The broad theme of profiling before accepting an optimization was inspired by [Google's account of optimizing the ADK Python codebase](https://developers.googleblog.com/optimizing-a-200000-line-python-codebase-overnight-with-gemini-4-argon/). This project does not run or benchmark Gemini, and none of Google's performance figures are reused as local results. diff --git a/docs/profile-preview.png b/docs/profile-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..e877bc1acbb223a39f5c206b36c66bddc94921b0 GIT binary patch literal 155582 zcmeFZXH;9smME-l2ilRwn4H>x!DIs_hWM;9}v2aeXZ<$P;r@9epFv-zz!*jB@!Q0Px&55NfXb_!k>nyI+{T z|NV|X>z=v`+2w1lZUHWg2D^-}FqAPk1KGO__^!v_ z;Rk=h&VPs1{)9sUUj#DRJoyubTAFJyU{?nGz~dia=YN1*UO@kBpTKCN_S`4v&$0e2 ze`0*o%@=IJIRC`>@&W;Knl|4Ne=PoYo$*4<^s@ke)e0ARlq0Jvof0I&`K0N3sRR>wH}JGlMA zsN!Yd<;VDV0DJ&$fL{Rm0AGL$K$-!`0UiQm0g4w>04>1P%U7;mxqS8Nm8(olSAV+x z^Y!c3u3f)-oB8I?9CtZ6IqtHvbMxI7;N}tHWoQ3I@)scyQ895bE&-{BQV$;9e<1eY z&rW_|Vq&`f({moGB|e)#dyQ3Ki=EDbVru;SF@)d2K`?m zs=m%&7L?n2EF`aG?hLK|HngyRF$uVNiE$^(B^H1t;E)sWw;l8^^ZIY#zbWuvK>?^9 zL3laO1SkOEPr-s|mn*;12mH3Y3#QH^h(9hSEGzJg3hieZxp1fsdF*cdwn$MISzg)* zmEAD{^+=JQgUn$c?OZ0S1W^(NLgqlV+9qyn(Cm3Va$Op`Q9=B$8pP@t(>C_;B($k0 zRqmTos}_Pe+v0y(=1%jq%0{XzgjWx zec{61oM&2t<#rz4um8J0MEg**^4%I*QOrf)U3cR>FP`m`mXyL2^#BA~P{9Ee7Z;Ol zIa=Fjmc${ye0HSYhg7=&IPFr(l=CHq1i*(DmOI4Y*pC`1unZYe zVp7v>v5%U1sse&vt-4p@lijk0_IAxaH}1^|gXs4+S2keAtSvFY0H~i)*km2dg&E2T zy~gLTtgD`Cmd(^?fZnXr!8x8QdUK7`Q?qE-(uuk(Li=12x7%@;j3B#F8Mg2okz86S zu68JbMW55C^>l1%ZV=ifo4rpY*3@0fgxw~N;I9*Y6*ZegyFb{s0C89C12++vqsiPx zVg0E%(ZHP=w;0g6jQ*))>QvX;A2kctQKwSTNEHv!g~Wya9_WUXHBnEmZ{eIA$&^Er zaPe|ezkjF@27^mwb~N%_dZzI^?^2~4&P+fM*AX+b(SR&FY^63nJBekq-uACcNnpq4V2iz3jGD%?xDAa%VuFZ+iER#}ZI=;PFNIJ+%pf-kGlWDPX`9MhUH}XTT2ePbYJs8lS=}k) zdyrd(*thI0v7bio`Xw$r4?i06{@%!-3uP|cB3IY?1=FMT>Eh|JKXP&B7!8N#J47U_^~;P ziwpYAG##g&V;he*b1wjkju!xINb#>-6^C$pjcuV@<^?A0xt*ZF&*2of>kY87QGdirJ%V1jf_&B{*h19Jrg>%}>w&=yCmXw3{s|N` zDc#??y5=`@BsY~^+A>=u9g#NO0`_)Ctc_|u%bxaL-QAb(q`5rUWh@Z~>d46`9kXzK z=P{($O(lvq`Uxoct-Z19fUdDq*?4XnDqxvbiT+%dJr;Bzsol-h=4IFZpiBDi3e|rF zQ~K9FP(jl-^J{FcB$N*I$LS1Ubw=KyI*Vv72vkg^*WP4joyedZu-|`4^e$p;P|g#2>VpX=^xA`|cek5@hD4u-SonJ}^^($rTc$djrbPAScxr@D zt=HR#C>v75BiL44%*aZPt~fce5?a$+JhXKC`Ov9%^-|S@1J2N{yXo0F8kz!R=@`RT zRXQq)lwMUenaZmLIf`Q{Y$vu|8?;0vkX^r(#EJ1H+TPo9NOZ<}=&T|I&&|v_FV#Cq8ILuo!~by8*1wfkwI3cOesM0dNdqn`oBct_8tK^6Fp z_~vWFsK!ijjV(4qi2K`km}fW|yhf*jj%>=eM0ZE#?GG}~Ws@Q%cZy7xy{`Ods8|(D zU2W-^fc%&%uceM#8RuUyEcWJ{5fsVJ_6}|^-UowiRHAY!`cv9m1@eko(6=%-?7B?q zfTfB}mRTv{yCK!Nz$2?Io0*aW7481ttp^8R_P~OfjE4zaRt|4%qq5%AN%w5N-%bHN z4}!B3AYG5F#l?56XnA2`$3NA{X9@g)b=}t}2T2QwyqbR3t#oZjQDVufaJs^GFt`DF z96T~=v%jo-0x7j}(cI|WJzOLIQ5IM<5wT-1ntiy^$`|(nEd|#0*@lUqBsm#dA%QFn zL(dg=q`RKoTklwdsgfIx10IfaE{iEyOHX)PDHdAfqE@lBOOt}4LDu4a)#626;^)Mu zUhS#UA72i$x>0{0#K{yw!NvB<+Oc(`&777;fswQ6*nsdj~b*hdOjsPBOYlF7qp1G&=a@$I9dgC8`vkOvrXX-VQ3WNyL zc~iB?4y!_;>J5-;RBm?mc1`-qXKzwiZM`AWquNt)kbHwX@7rJf)1O;S%|LZ~Ssm~0 z1bWKnRto}u^E;}`9W%&F$W&u8>m2Na^q8{ormhdU*{3SDtXEZSITMm}3HH66^{RTY z_1K!u`+nr@fY2Rm&4){Q?*4gy>Cxa{0S(POzZpJu?rTrqmkSy)I0kG%7JiuU8_hD@ogTEL{6wt44oh)Td*%qDzj}b@ak7 z5hs|`oW=31FfFW&v_SVd^s9}ZV6}5vN_g(>Iry?q-F-Occ33?|aj^#dtG85ig#>ej zB)`C$CZ3^yWsLptMisS-c0bB!$W2aes4=EZ*ZF??M9Kqu`OnspaWnKPBHGIzCLSE( zyMO|g!XQhrpYblRo+zck!C$+JJ7x&6ok2X9X>8OR)S#AQI{$bm`d&ch8X^?$R83G^ zvKARO$kr;$kPL&B0Nd=o0OS}()PKBK-lsetGG8soj^dUnnsKXV4@}pFurZVZK~?>^ z2Bb(@#Gqj)i#+R#R2EtDGIK`bM*#u`md(0s7XY?{(8_e~l}0iCeEI zQP*I`DsJOPjXx!RPsbjs#MGLx3V8K7}DB<%XR46Avl0Px0V8iVsTBhp34;LLC?g>Utjn)6o=og;q}Y5 z_D6KYpmD(@Htrc*c<{dTm(Rls(DqmOxHU{ctLmLk=kQmbuv}vF2GH(j$cEZ<<1FoL ztWif^ojo!X#_eumt%V8{ZBu6 zgWh8os|j!IVuAS2uFhMSBd`+o)sX^Ng`-q#CXVC-YnN1mhOR{%UDtl7#lZa|ySff|t0;();8a=_ck{6hAHA56v>c~f$|+jSlzsMOZAo)Tvi3_KZnUTt7xfcz^caNeOne<_F@E*( z85l9tGLoW0z=TXfSonHFrozGdrmwu#uJo|o8NLAMRA~;v*LG0wO*j*Y25EsG!f)Fz zpNCXCBr)?LzG&Wn5@Qo0^e=r_S(;+CGtv7@=-g5KEmbLGR$Ch!A`xji$fruWOD6R# za(Qt_{y}pYUlG9-1%Ns1w6}=Rh?{XUVz1E}{C49f^HG9It%l73+3#@V(qPbV{hlM{ z>@??#ljk1L<*UPoL3Q=Vtzzqoh!pdPotIXgya~3%icO5ABVCp8^y@N^vx$WYr=Ih+ zH?Ugw!v<5k5(E7l@ny4iUcsi-vDo1FG7k0YukWIob#mFnYu&=Jgk$&?k|Ar|MC6#&+p*&sW)D%uFrvX%_eob?3x|=_1l7Tz(XgdzGtY@oOf#d zB1!#*&OVc`T4O|0Y;1X>Naf)BI?@vh_36b!D3rutH*R8II=xLRC34LXk>t@+$J^#w zQ75Wy?S;Oh|JBTTrXBKw+Cz4=bAr0(I3;d8S>@!Nj7%gXDk2e%$41hVDrI7 zvirtlt2W3(5y)FOfEa+ zT@?yPkvZ(a7Ct`?n<^PEEH_)UR@{-xd*p1TSDFI6w~%XBiNNS0H#`YjW?+t9y~@B6 z{$BAkh@H(s*_h(}S3MsIEOXDq6mzSl%*ApH))cgtMAXrw45;;E&kR%UVhynv5r5*Sl-VhT^QuZ;Nx1LlO_maZdfq6JWJQ0W_aje8D}1 znWd-sZr(+QK53bp%id+n+9km`gEJIt|--z}u6kW1>Tt+o?B3|%%; zl%|yTX+g6%n%3S5U%7SxFkU%Zsw>dc$oA+**jTSn2E4n($J+Q%sXY^N#2Fc4Q zOZMH1mDc4zAZLyu4(IOp9i#3&qj1sFRYDjnbB;0{?i}h|b@|aIZ_$z--HC1AM)6c%gtOqk$$7JAm*4=z;Q6v+v6u~XF_e4-8n0~Z&B=Go9-Q*)V zE-d>&g==SN3mO+op6G>46SF-{*{O!Dq;H2uAp*%>iWThnvQ&UN@dD|UI2>HO?1Vd?mqhN zCF6#ZC;`)NEn<6(d_2ha@{_(vTilATVj|$u^&C&}{iY|pjl47AKKzAOJpOa=P1ier`$!C9zwSt2wynqJQX9zXj9H8M>wR z`{trcv6QGR#%9^N&P1{B(vTac%ONmGp8_N@nSgIP>5j#%}w|%5S!h@ z+)wRR;#M49E>}d81xDm-!0k`>9{#%RN*BhM(uD&o=vNAma6QZYwsUZ0hkW;JC{^weFmMg<*PikxRczdHaa~9e6d5)d+JN(k zH5bzEhjolz0JIM~&6Fq^7k~!&BrdnXikfzQEa=kjR71)Eh2PErVq{+F3)^T5R|I!+ ztE)|p;>@g_>?cEx`FI9pEFCuZW6HBSK~6m8okF~mTTuB4DAJP+9686LYy|4k@t1#s z2Rx$^QU2;eF;Tiew_jdz#B;~ickN7gM{ZmIb{phbp7#ugGC%Sl>httv^^(u|o*_X; zkg#n;pJ^N}ZdS9=>**p~|K@oBa%uNdZtyeTeh^Qr-a5@a zb>AQ~JwtB?0{j`KghsYzDW7?d(tt)`7f1IZY&HHUXe#;b+-V+6_k~MdC7Dgfrcd7d z(=r#RnZm5nNj2C-^wMK@;!u8MnF~OmoeFW-ni9e^Y%B1Gx(7KM?a_SL$A25Qxzp_A z6a`}#;7&J#Kb?Gp)llBFIB$)Y#HfJ?|6&y>6l6+KDym$enT|y;$*Ku(G%t5{%;Ad13cf5y zDp4OtDvWSWLntm^4!c>tF3|3EM~e#jIo=P{q@!tGq$AJWZ|t^I+?MQ|gVsMs#Uxb(y+yok<(vV6Rd ziGD2zhBW3g!494Doi5M$~CCBq{ zeLrcE{!~)m9S85&Xr6bt0C;GKvKLYbrfYsfY*@XA?vmq$w;rInc?6S`&@-iisD0>0 zl+%({Vg4hEF4=T_KV647Z~@SxE+xQa>~=%_LB^5Mem#c*g}xQ^Y)W3lTsbTw;kf4O zUWBnfwB*!NL*PgMhq>-&8PU0JY_qj&0tPgYjA7tadoi$?l-#2vHpnJnJrP9bncJ0W zPov4gAaumSK23@ufDR4*tZ8@H6u!H3F#lEU3G0w9f*U3wU1$CcrXc~aYxq8W{@@WMjr*LLRc7ClE}$j@%)nuXJR zH>-j5Pcbn^z~G8WRH5~;AQFBl8B3Nawxq|N!fA#VfEhlo3xFN9wD9r<^OMyE|EWV$ z9*DP7zlO%v>DqE@Zi%1>pR!qkQIEj_v${D=IMQnib^#c4(vVE_kSPkO#MINwG>hP- zm=^a67Zs~SdvDtf-nvSO+;*VaV5JulC3tpxuD+rwi76k(wP9vXcnrv`3$S9VfYfF`QSWDYsmJB3eVMd-2a44=FSi$;$o9@wpst#^ zJN2mur7el$6<4Yc1>dQXT&VGS3~qhcZ+{};*u<+j-%<6gYu!Bb6RBB7hze@=xOc^= z;A`XSYS~zI@}qK`HiT4j0XR~>3|B2TU9a~ZU+n&dz%CN}3<>;&YY>wQz!0XQ{i$YQ zK6)eBDs+~x@M0Jo(%x)*8ex)a!Uj)}ZC;o=HLM3PtNw3!4gW=f`Y!-@btxY&0H02< z=U+9+pSRjsXp)-S8WIvN` zC2Q-TjwZ#!o0yO;G+wG11{9^MxO5U)C2|2c=UQ7ZVbPpeoo@>eAT1vro^LXIs{Z7lA_8_IrE=-~y>Tcg~@(80Vh};D^mb!Y0oSk(i>jp9z z2fm&Ay-k-bT9m^EVWkgNrw`W`L0)-kUdp2*oDe&dmY^4*Tk$VbinK$q2fls z+vT-$dvY7pn;YIg>plXDH2}Gjy{N;g$dUmXP3y4#SOvb4Y2+^G3zfsiC0HlxPMlWH z6_#2KRv$)WcI|&@1@FwGfeM<@fwYdWK{m7C_+qUgb@@RcCXS*tHn933PIRIIo7|ix zP^$yv=swPeVq$9A;&MPxc+cEzjA#D+5&MDsWEz0f9Y~AF0K3Y7+^6oi{|dGvC8B45 zz}{ezh2c{6xyjUkqXeW729;D$y)%xzn;b46E-D4=YH$pOXlk?_RSS8y#AItb3ySXE zSHpV%gJ4zPWY_qmD0?LNL(!rednc$`|NbDm%{kYFhHxSb&v7Cc!R#r}zg_9FxL(nH zAEeI{>>5m08zFy5bayy8DAKBgU8m@4p=Fc%4!OJ5`32jZYW?OH_RdV8rICKsg5C{c z&nVb6-76Nw+ioyBVEJV6ot`yzYrRgJyqTjkFdv3I=lGehJV$|Li$$_NP2uxZNK4j+ zY=tJxoez8pdc9{wmK+&I2^$s5=Mkk|n7g%f=lRbscI>w6d2CVI%?7&%!gHj;Sh`{e z`Tbi8@GHh2W{C!kEYoC6dd>B1v7!_mnO3$$Ms7jY%J6_d(IXk`+TtG{(iDXKg&Yd5 z=w$}?X*S6%zP18z z*;pFvqc8|=;=b}8!={^hNtaoDQ$SmQ9F5UE(7W`+j|?SYqfn%$7p7#{u7IG{CVGhj zS**jo&Y2(BSlTXGZpSS%5ZZ=l7p!%c{EaUR1uh!3Xg6nE6?AuY66~>ZlO(KHNu(=_ zMi^U%p%l7ei5)w$36a++V-^$*8CgV4nj6|EAb;H5#U>k8>S`r^)+EZb4nONmzW{_Y z3?IAvHp(q}?5@Cx-vyv-VGo+wCUToy7HDJ`AC<;7VNs?MTx+nL#2fOK6q1ivXLSDo z_F%1CWdpU?R)Kky>tkEdHCH<-i1cjQLZJksq82~U(+iHV*XT>c!@D$ktf_O5bWmLR zf=VG<`HrRT@dY6Jr>rEtud=Ky<$*@+f0!iI#H2K-+<1f)(zN!JRNv@!OzVZB!Ah$| zrp>x3`wI8lmn4U)b3L#UNCfNj3JQ4vXk}gt`|eAq;%ln!AAi}gRzy_IUOFyS*!KAS zeeaZmkF)sGS(OZ+(i3`oLZfHb*)6?45F0DYt{pR2MqH-!CgnN(9gH#Ghrcrjz~}Un z0P|XbYJOb46y`Z?_G9b?pktXoiH(PRsg$iNraw+f z>2Wb*5k!AVz72b38B(lKWQ7uk4VC&$M@uu=1}##eohd>?wJO~My%joEhAgBg{UHf7 zo_h<&Sw3TCL1*Hp5Qiu*)ymBUS*T4)g})9Za9dZ?*LSQzQ1qPnFH!NDYqRjZX_wRs zYaWh9R@}Z+B1bSZh=|8_x?!!lCD_$FMR60{@jH$o>ii7FZOD+ux&+_*gRx@Xh6c#K zw{XylZF{~%N3?5YuIK6~4(E?cO~zegSI~wk^l3YaBagRX%_X$kfvb8;8L|mgsgY$* z5tTmsRXs2zrlLyuVmu+H)h(i@VW~CebI#>6zBF;{i`!GWBk9nuyV+( z{!X7FhHV%zB(9YRd}$Yc5}h)4G;`K(=K-fy$zK3O84t8Yp>^Bk&D?I76si&`0XFMs z1erck=NZ&2oRRqSKsv}o=RBlBR(Mxjf*T=NGRTYZ#>=$ZorD~yoxRl#c8X^RzWhg) zkfV3>H-esz^0gN|lt~I-zscb<;?)(OauhejMVq#|d*3Y^Hnk2cFCJbBAM36=YMA@( z8wqG0sFQI@uAqVa#Oq0S4nBRU-0AM0SSCbb=XX@=i|2F{ROm%=?J5@Cqh579*Jq8x zBTm#cc=jP7a802eNBgyAG|aZT8_}vSrF?|;!frSZ!9BsMIL%3I&SkDeYm{5UeA;NT zxjn^nP{|GJ+r-aZqqEX|cVxDTY-VN_7~dK}SSuD7_CrpyzL?P^b!upl)rHU1tU?{? zMo;}`aVNR*e-M6IZ4lq|YqLjC@V<8Dcq=j1xv4V=dbKBf2^K$;Z*a5!!%d7q$@z^y zm%N+XJ!T1(sDbd1p;r`7h$~slstof*1Z6fGq0IpG%VPD?!UyD^AQl1|L(s) z2mViW@o$`#tG`_ z?Dj)a!8Y!|k&l+b+6&36)G;L4X-iO?%%K-MMa-In)A(Vkqvw7$J)sfx-(k(l-t$eo zxbt8~cS_JuYT$?s)BJ*w5mdPIhHyBWQ!K_Lz#$1rjv!fXs2Ry*3t2yyUv;QaQEUEp z^i+zH2~3uJJEt3z`fWkoj-t2ZnqMPNiOY8CgO#S7UxSqnwi^Ul8Ow2PT30&g4au;M z-uI}^8S=zvA7ek|RRkQ!xT)o0KvcogAf*ey)CJ&Ft3Ietr%j+Rz?R#@`#HE=co3cX zEXf;e;kk2!1ZEKFuJd)$7WZ~s@*qN_m7#7jcX;zuqK3)hD&aR9Z6>|Yw z>MB?m8?95AYiNEtLABgEv`pH&Ah-I-s zk{HQ*G|hdl6sDppUh)Yk>R!6%c(gw_AqOcu22Ew;!HXZ%A4yDrOfLXGjmezr%kuw~ zD*n3je#}1Ctq`5bs*(%9$s^wjK~Lz>2^;?$;9?(6RHCMp5zczB9e z)jKXpE8k-noM!{8v#BbItDqoILS*L5ItJQQG_3awThy?bnY=(40Nm0AX34amQje%gbH$w6aT`;VGx+|&2!(4q7WVH`hXjVqrKv|L!Gb#7v}wa^QDwN;N?N)ymm45~`9{#-7aueju7Q`**+ zyq($walO#zj2W}t4)b@1#s;>(VM%B{W$cWJjTza3(u`I@CC+v_JJ}f5QC{p-N?>Dq zvdPtN5=O6VkG%BPuhqq8!$!`aB0c^~ug-0$^1l@2``nE%;Wt=J|YBiwkN&HqHNJ z?K5{!p&l|hr7_;3QxSzCwi@k)B62MizRmZsLU-qirnOH@n)=K?wmKJ=3%d_*$*yC( zN_Q=#o01|GT~(Ayc-};b^S*w9PXC;gIi(#Jtwl5f|q-Ok_8o1iR9TM7Ab zZniADR+zpW?$x{kdYo)c30qr}RMhub@sZ{5zFWtc81ntIP5h}CW{ekE?NZ&%_1R&H z^2f)Gtfb5uK?MOt*=iuqQXB@%@XGfi8=@tK!ag0?xYFDL7ez(Tg#mn1@rT=x(>y~; z#aopb-QnHGv$CM%?`=CUZ5Z+%^BN(!JgqP2mSozqijnMBih9LyRNb!23YjFp08(Zg}CD$UDF?W*+qJB2WTQmP6^&81}5J9^nE zA>vKe^kbRGsB1;%3|GI4z$njVO&7ejR^4&%LDO3wN|S7pa2gqR&p0GSM_ls&illoa z+)MFF&yq9=w7LfaqL&yM*~2Hu541bLej6$;S-PBXe@daW7z$n%9x2ir1)ZS5Y>nqZ zIQiyNT?o6JB-iR;TMble@Up6DVDmWBsRU7I%z@XSI?r znceW3=;X?dXUMJ-UH2nQbzoIL5VzupwF@5;3VEypQ}Jk#U^1!H@^VPhE6JCU*q7nt zy=_6tkEf!1YssAQ7Nbe%l60LSBPgCb5sD0fC~WOMP8MC;8QjTpnhGmXu#V#KNREr* zTLd%s$}r5L)PF|m_3y0Fv3tXBz-Ii1FcfMF42}|a60vcs2r}UZE*4RIZ$qg1aAZU> z{gJ@o&+AvQ#$hoZij#LrO=txk@+{zuv91LR7b00PORo9Y~YXY3uQG3rH^>zziv0Q`R7Q z7A|~`o3yyr_c{>hbRhRKXtto(IO=-**}%7Ys-ANssN4Qh*ijmxFkMGcoi1&RA-)`J z7#oZ>3QBBu?6JrgBgG0-G|Ojhi!Ei(3G`kM(A0H$=M%F`$b|~-#Pzdh>~8UQvo=>g z6;aM8?Ed)GTPaKL+32e8(qz(4_EV`Dn>h8(=_4nPVo9Ze+8G7*;(B(edtORs<_cvE zrn5_mc>-$;b-Ur$ZV_fKUMq)OM`w`jeaqugQE`;uIjf#sY|Fxdky-ORv}Njav|ZyG zqIXI-amo~m{6L25I^|aL=@xwZUioyRI&9{fw{ezrdL{}r>RpX#5_fDM4vgs?s*|Pr z?OJ(K8sAqBBDfZ0TJ6dz=N4k(iXwT|T#Bg{3RkUi_7#2qf?CUS543bfiTfFOhfG-a zyYDYNeecz$rnZ--qP9$$ec#Y1HKO=jH=CIJrW!9;Y2~5aF&RI>#$DbSCElnmv!;ZC z^4SkOaq32CY+7hEF6$IVIH_0$r`Ay#93yVtE}`5T0-lfHfjqF>VIV{@=)SiLqN@>X z8DMRH{s=;a-$*8J8b`SE*GQPZeAF?8I|qZU8&Ft+(Q3YYqPD_YE*)#R@xR`d{_>wP zApXza%q;y6UX`d=_%T+AzEp7d^Wo1bM+L*_xs94Ty}tpL*8k6A@}C&N`yeYJiit<+ zy!8{xB6-VDoUF91eT<@Co4)l|ahli|L6(#*{QD0XZ%Hx3DJ>Ndeq*iN6p-clliF*s zN#(4Jmt3#>IrL>FJw`!#nfb{BfVh8(zBx5|C|Z}Y?G)keA+tXAVJwydZA5#{V$o<*zEr*= zsok%g6|>%O2{hzr`+9vnz>d7pgug5oY8vwTgt8^LVd^E5@_``S8f25R_D=`;zg)@B zOhMd4lP{H#gkZ=eQF<4BGJp5#N!UJc@8N3nLHQmbw!W&@wDnPhmqZ#%84A6vMH2Xj zM4nZaf6U2&RrTladt^vTNP~sGWNa7gmygP2O4b<;a2QXtkLANCn2E^DLN64Kt-BNz z!D=`+Q#0nqF*F9DL7tMGs7hpJ+k!9iizg0|X^uPb^-IvLQn8qr;LSqLtgJBf06VJ$ zf|4AIPk!r)Hh|n|eeG4qIU_xZUdA!p7y13l#KJif&EeaX#jokfu!4#MS_tMOH?+#} zDB{svM#~h{j#70PnO8R`&OZ0!Ae{gOv4mq(g~1F-$3?~FFDOJSs% zOO4sGN6(@Ki`DCEa-ADa^2K1N;NPPC)oFP&q5b|(JAb?wd5VfFiw}ZGOy@8EfARgE z_8Vf^C8hBRpsC@%F7n3_l&sf3=Y}R6>Q$X`Ssco>9PYY>Y?8xqQG8=?0jUl3U!vYA z?1fz`3oPcuHi=3&LYp(bS&J61*BdOI2N%2@#;dAf%EOJkwq_I5KC{}k%)COMtKRu? zq(j??Pea8JvsQ01kpYpJsoLR?l1gmdz0Vlt=l;Iy_CFg^8ES+H+q`*D*Slc@<1K8hUJ1Y zuN^aKNhUoX_eQEGIieL&Wh7chS;3dZ4XPm-tci?*TmZ~30LQv^#L=emwXZ78Bf#z4 zV46kS*yLDEe{y3KOvT?rEG9Nu`mPJB{GCs~_gfP61?(D~h!pGOcp=+vGT(+bLw;NO z5QJb6=+_I*F@LX>;QK$YWfBW2GegX_%@UM?T%ouJsgRAl2UFap-L0g8u>uQZrxLyr8OvlulR9>>)Ki05tywWSB1ULE#6?{HYcerCe-yp=Eeju-! zo1@1F=v4O**BPjw$9ooKAC0)Nve#bfo`4K#0q>_dm~e18F$efmq^cfxXBO-#@d;6N zgzE}_N9~z4vu2p!^c~9jTU~<3Ao!{CyJIe?e04I~udZADK``O5TyZ6pIP3E!IO2LO zC&k6IDXC=pD+7Ipwx_dQ=&<|BY%F&9%i$R{X7D)rRY4K=4@2&P(vCmz+Y+d{hdi6W zXU?)ef8BQN{Ff{*?4U=%-#KNtdp z9Wtb`KNFzh%?wVnYtWb356>^)mkbD{Z zVhfHn<>?my#sZ!Uk$?L?{Z8gMU!HnHe+am#_&FKs}GL3m~gC_M<^K6G|Ds=%UE~RaJgX3jr zAa#aE9m*?2A1TX^R=J-SL@IwgQVn|i(`dMKa!p!USwhvGKePGUHp+S7b zzGS1@gmkqC>)dn7BcYgE-)U_SJ69KXyv7Iw!Vciu`WFDR+hnpIjVnm$>@|^U9lVCYJ&QgoX4sL9I?|}7DvY$*%(<()Y z`(&vd93dXhigd{=Un(oh7UdCZ6TBCy+-4y!BS;OVJcoRMvPn4$NbD(vDO4cB7;oAI z`O?ub{a2ns7>YqaNCdSt5QJrR(noP;Jv=I2l4OMIU}*e#S!U4yfqX?aL|yG zcn&0zKUK-AslLyQS+G=3cXlgE;RR3pM#sM+^jrWuxf>Y1hx7<1aA4@P$f^VP z%lFx#kzB&ku6?$A$!XJU7^igvKHNKMd9+FNX5V*tN7=BCE6?oP$3au&AZBJ1)Lm zR)B^L3n9{VRW2i(D_Wg;Vi~zirgJOAxN?&ERjO(C9A3uAqoOmYPNL)era@y`vX1z! zbr_zFB@jKsvAh3W8l)?(+N;*t+~y*-;v{0G+%7?idPBJT+izrUTL-$z%_N<3eZ`8J z96^^xTp4ML;0ca6DwUuKs)+Ip@#z~l2s>d7@39tq7ep2Lc_CGkXx+7r;f-erH%&i8 zRdp?jyNZF!sC7u6L7)##aZF^mD(#SYOmmtM)yRG-SSXPji*GArBM!hJ`mZVWB&m-( zEaUD)B)bcM%;5KgkzOVmZ8a@ug29umV`FwGAHz;`d_ z`3%&M&s!ZGp`tg{4a!I`y~}?%&7#|j`1OW{(7=xIZ&b8E-q-sm3ri^W2NlOLGVa4XV&5MV%$nO&^Mxq=j64)mrzQ75Opr>o3eL)J!kfDR zY&u(pKDYP|AzY>Y(jFwuB2P13)VH$6<4|pf&g$F^)<6ql{vZpRTGIUtm&I;J*O;=S zzN0^V{Jf3oAJ*ial~62(yRX)cJG6U-Yza*>5}8;BTe6xtOADe|@-5_6qB03Lp8DrW z`6&$bWLMN?Eg0GkHR$MbM;3#iC?qoEV9ZY_CXmD2maKvPkX|m7jnIpgHw)LlgRLde z7>|Na=F?F@QS3tH03S$_x;yl`qw$#WhXe)L`M0#emfFUsq?>&FB&Mq%eG922U9I?Zy`XVNT;0+cy_Z(xhuhPA{q88F{x)Hj?1Z=Ic#j zGpYp(Kvoz`e8ccWkl)l8xuqBvO)-G43ts@-;7f2dh9KLya{;I$9*8oD<=_?o&x!;5+|kW9^5eJsZH^h?o4dyFJ$~rg=9Q$fb)P8i>_WGC(c4}*I!e8L z^q=BNEhv4-)Dnsh;RIHaF;BepHktA~g_9=nL?73=+cSQA=D=|QND+HM|77&dgH{uh z;pg{s)5joYj$efkls_;TRhT?X6?@N8?K?0S}r}T%TLijQzlp*C3}@jZbdyP z3*X#}CNn<@fZ24P`0Bp!F$yMhA?ly~5BA!Sk7j|aU8AnH7L_jGrhNje^1Ppal zdKE~4&_=2x6bYSB-fx8}on>v6;jNR|@1rW}9@hOmoLY6XtP&EsBmrC)JKz;a91DpEDxul3(z~ zOEX8i;s24gTAS2aYA!wsRk~>POB@&Zb)zM7*fY95K4Gj6ybamE73J_%2gn@$Ry%Zm z+OgnbSOB#nLswynTL$9qUeUH&TtFq?*hYQO_^(APCJ|xv(HL3jiSeP8g*<*n|h^ zQ^U#!r;p%$f1hg*Kb00s*yY7RM)uSD9lU7nNlf37{L<80h8>-~c~%|qrHC#=Fz#y<<1$Qe+4KbwwJIjm?t4BYWF%g#BRKqY*jEpQmcC8m;+4+)z;eRFT){@ni{Vnvg zA$n&xd-|-3H+JdY{yw+$%k0sO-Do`dQ_Puf3NM~?@ZwZiBxhOXXOzopK4hJdW_5I8 zS49#@4>&%87v35M~MfE$zAFa5zN0lcnZ@W z;(=5$6{k0MU)gw+(if_4*G7O5x>oktx%w6|o-}^C?#1zvMypE$Y76+mA)4i-k}czRA!L&T=&sgD+6Tfc=P~Q6uZoXqOEd!s%O&G4gLjYcJn%Y5Jy$+$LEbQd9P4n!Q0W_PSfY8>pWJb`>RmEJ-g7InfOd!L z>`x?02g?0yWU3KScO^*xfC*;A%N|mlm@%Q5?iz)~nMZbQf1jJ_;W0qk%6HQnV%uS# zcQd~K>DS~}_t^2`cbT1WLoVEOb$rulKdgH=Iw6aq81X1$TjN+Yc-6wq#gL=#Y}2%GB2 zJM!OsjeV`6So}q@1`t~CCNDf@leY`mJG&4%C{!jK<^QLrgjihaPd1+2_3{+lE_m9L ztU=P#ITO}whkX??a7s%L+rGbhnll_yc*Z9htz1~ld#Z!E`6(qE4eP7+`u=~P`wIy> zlL=$I;t#l{J=dC5nJIQE(&#tkFmNHV7=U`*E>V&JvGPhK!-vb~rei3-=#>@3k^4_w zylrHn1VW4~Y`|7trc`M3-Uj@@+sfm~7WlV1iDFFU1x@T});m`oS>a6X;IMK>74t6V zos=l~z9Kkn%|Mlpe$0!4Pa^5#F+5oMXt1jwktf-q`RJOU#GMpB%NIIt!I>?ok`Pwe zZpHk8jBlh_i0$qhtM7W+c4tev3K*-bad>kAe2R1OxPHFbXezPciTj^paCw)rE?O+! zb`hC*COKO8dz65oWeA|t9XLM@4JthQMHqpa>8-=2Tvw}~E6rCbiP1Md3h&-Ry*C{b z6H!Za_A|uWZVp5nz1FNPN9ic!*TyrxRNK8oE7Gz>*3q!3c=Wi)!!ngO;4Nkm9x6E} zYOO3hT>dQ%8Bt#PEFWS)u02@tGn{_E=u7fCR*Am2#LuuMG7Z%)b=}$Sm_vnnHaq@b19~R{K1Afdt z-{8@Rh`nRAOp;_IB)Iwg{B&w~mYDL=c*&8=-E2`oIi_E+pjz6nM@&tVce#%3+4*Ei zLs5d&KMQNk|6fq0S7gcCG78acO#>Su1eSgTIj&x0!jONT^Wj0Jia#UVdE7Pvzdu8#;jq1RoULc5ic6n5iL?zNUY5!~;x3278DG z2Qk}vZ|_${`9RglKl6n_VBCo>KeUA z_lXpD<>w5^pvrQs9F&pLhJnGE3^4-vHPrAMv1Z`2zm%MSXe&)thv2dYA1>lWingIc zw-Xw*Do}&&J2zwOs2aCX5#8NWSUxS_5@w8l!fy6SBIioqHSJ>iKvKVF3}i|7UH(nd zCV_Hd+rz@(ixU^3?s1c?emi;YMH(7ERQY*O^L|$D>eQvNnB@HpomT@yYV=*cG zx4pAtYi8ICzRN;IS4$|&sPB@x-20n8oCS0)lwp@UEVZQH|D#3wzcx_(@Bg>&=B$jxjE2PSaa<~;TBa$@8=);p^)`)a^KkQ}l*;OQ;?ZMMMsF8?~%(a);a`=Qx zwYCMeIkhM!>qw?lB0^U;`*SsCQk2C9;N6Ux&}2nm)qShWas$q?oTlvMt94zC+7L61 zD&y0hC&y4StdX*<yK!x(Dj&Bl4o)oijUhw zmFw@@jm{yw39jCJdgt{#RcCu6fUkc3ZRnin3<$d9in= z;q@k)xKQsIc3rlk&cMJ)qbAhy%!#`I*&faI*nOQ<0ZDG37nCQo15Ps^)vvhxNNt&3 zw{@rKy@sqX;T8BdemJ!6ssD1=2^#Gp#($>4-Xry#UiBdscWkMyaee%`^}2<&11)%I ztbE(-!B+b|S%Y{t5B?Dwx`z!a*nte323y=hTzyL?E1XIJpEg`C0#=+V6QKK z_2?%p3jv3USn5@+VVafLGPKxabVQ$Rh<1PsVg-a4o?^)vUDW>l$8HWLI?+?6W_(7o zs^hNRBN7cXnVJIb7%nb{m(ko#X%QXkzp($n@tIH5SjjrKP}%f zm@Q1G`@>@R!@*I#sQ9IVnop^vv4;CVN47rF)&dL$JMB#0*oMd*M(1`K3{evF44t~Z z(yJ426a)Ncc&{v7q^Dwm)X|ibGqW*!)OFyh?5GPwMA!pNq(y@rBr4PEb4Qr4Qs_Nu{kS+H~?|$zj&CAP8bDI^qjY)*mSA zO~6zmm}(hZA?s|%%5RO(&WhYs9ARzxTYM2PrJN;<$tCPpM#+u5Nlh3V0;!jhscH(S z){0@EB-jXX@5ZnNq+nxldI$l+ z+H+>9W9nN+Q&afs_;ZLj}BKdx=@bG87F zI@>|25!&9W*ph$#B$OhqKcGS9L|1*O(!mAJQ|>gq}xhiJIplu zE_)@VeA~l2G$`iaFoc!9GszV7+Pq@pO$R(zQMMNv>5IN@g8K1UcG7bL<4lLW{0<8X zG&6X8N1{F0lV9ewudK$n!YkC~;9snyGA<_%W;JQA*^^(Q-*kIHw}T6H4Kh3M*kz2sp$x|R4EX;x*Gdr zq^zkUOi;vPEjS&qKje$xpo@?_QJ*7N&x3u!fUyIhO?7bkAL(j~AikS~nK}zaCZohk zYW-;=x~zt*_coerEwbwfb@1mVx?FOe)S#m`Hpdz}ztTT*t`gy;;_y-hahvqD>?%80 z8=G#;AX`MLmu>%jPJ!2KwZ%j>J?2_lebuthqb(rHx1mwJ%=k{)mzX*(ip&pZg&J7k zo+k6^i=HSSid$1czf|{BSnY}6c0IBAcnMmrMSv`S~vdKFQE?^P#kRTF#L-U z;AE24$^I6985%GMnX&lwBWtVrL_ln|;prkzRwL9uRWU81yGK7#Vs*%T=)`Ni-eTw= zt|nlP<~`t)s@~oCF4hFn9h#Pw00ABx(-tmF;oHXB*$ydPCeEgbSgCrJjWMg&%L6hV zhAUs)Xr_8ni#I`{G1d?K*8HzZKasPA?I6i=FqXf^^w##T_(973qaSg~4D0J_D}wW} zdVGadMx+|*RGRme&7uImb4)~vg{^2!&WFuo7mioESM|Fj72&Js??j~2|0{}N}@BAQ<6!X%~TmmS}2+zE+qunrEO|ZPfuzIl=eJqgfDMfFCQH@} z*gFujf=q{%{edP-vOSc_*&7}o4HT5weJS>nPrbQg)|>ivvT(&>RilvvxtX`UKOWNY zF#B=n=BiUxIhr6bad_)S@@7B3cL@@fF;bt#=&^7y`2!WC`4^w(r2o~Mzwy~%rzBvB zox2b}YzU2Z=7Px|zMHNl*WJY) z5AD^|+%hKm*Ue8$ub{0$3*9tM{i6WUM?n5ep#MpkE>nT9Ue+>DYBRA9e?M*sIg!@n zQRSyt!$lNZ=O`+l6?63NUE2>UYmtKc-@>e$jOZjC32IdtO^`~U_wCBPynXMb zH2|sbBm@yu?{jx71b@3c8)nw={}eRH|Scz&VZBv9ES#L>X`wE2B z+`EZOu{<-W+dp|c%%%aJ;Qk=YS2XgZ6Miv#Z6>UjO3X~lCWN>k84a^9L;Mo@)C+A~ zBSR(#;ae`TLvfv~!~RZEQn!Dmf=rNw$kf}vKtrduGCLSAj?@QdTpxC@lJ&8jYd8Qo z2s5UJC+R&a$ZS??M{#Hyls`IxZ)@CfB}eR-tO(u-+Uk(JZis8A#*^xXMq*O34`RSG zV-NNP$1|w%nnn00*j{@F8d*4LzR7I9V3y{0Wqz`w6iYyX#{V@Z$9=-qw)z)3LU z#(VXnh#i*;RUg$Bz$uO7aFlCtny)i`-9Yse;GyWM>FeuOw&}%J7JzwCrbf5;5CyB3q$1obMeF zF{mhuSM5x^>*UgaRs{Tv-$}02!rvFk2eD-|-f_rC4!m5je5vBeSOzHr+DX6OB4L-8 zIQMyJL;ZNr;k5m#YMH8-lG_icQbUhP=wFpqm!*CDk{r(>=U^NGEqr8uP@FM`c*H{! z4y)L2%!mBuwg{0Kc-oV{N};p_!Ku;mly=wpk3{F&j(KrRX!%Az=Bgi3C(0(@!6H*Y zSIU?7RKVzu`uZp>hi#YSBt7e)`sH{zmKca|n!!@2Dec1jo{zH6J2A_!WJ z{3%u7d^u7Bad*Hs7QOC0DQv^7U_S+;6jD2`7>*Ta&L4F1+qq`c9VqY&IAKPnc1}~9gvy#+raG0 z3BnYN^w{Njgfh&S9mreyT;g#zRx{1#pY$zwL@TaCV@-s2xjscqL!7d36*iBRY}L{H zWaz`~xB2^9yUVOh{^ehuzj)?;{pKt<$(knLwk#*5A#Q)%ZWL6 z36oaWjR!nStegH>OGch6<{l7V7jjO#UcN~ij!JaJIk@~XjUNnGqBi@T)<53(Bk=uj z8}(Wu83w!{ys2>DZ#bF`k4tv%$C0GTq4NpN7)7gJh9Dz&gl$_#h&)5vc$K$b8`g1~ zUBEk1cPyti6mV!F+$sEw_7g)vQCoLvB`O);^4YaCbPPK<{-^xs8^LVswqcWL+%WD; zb7y#DLO$5OVN7U`O%?V0)awvEa=Ta1w)n0{daL%43vTyV`>-g=DZ9Ng}Hm z-9GjLA06Wsia3rVvflJ&G{m&@EQiiWSm`XTNKmwKhVZv~t=K-7DL4+DE=WvlHlL!t z`69_D2`p-}D^()|+I|U~L&9^WMw(6%_amG6^}sNZ5uqHh1KFa($j8K> zSC$SWU0Knl>nk1|Kw5soDnGGuxWRf+pFI9m>rO+Zg)K%P_=Ei>sH4MWJ2I^trp?9 zW9K>Fzm`QkgFTK^LK!m>j_Z$`bbF`LK|u9{()C<9^)37Rnz@xzAE5JF*%4c1rykg{ zF=4VBN_I^EMz^i;IoWL$GkcZrYgGq4=Pw)efsP592ph3sHH4`%1cU={Bv(UPq)up~ zJ>zcr0nZuff8!xM;mI$SKt}b*(!~<|7uDkTb^2VU*iJIRtNCf)eE$6(;{LgF7wgOT z#cbt}QWxCKhHVqmK$~c-9h|teM z#d~HJ{_sH~`tiEiW&i zu8w`b`cDfkQZHxzr8u5kMTe*RnpmF!0KThEvSsOLk$?TCfg>=+XE&YD>+Pl)h(|Xz zP({z6og~8|#r+QL7Ei^3NFyb*Q^F^lA=C78rAE(=TN8H!Oh)yKG_J$+-ILB9&H4Z8? z8B>NlxGeR2Iz;5NCsI(&*))zC>ap5r&8ONg?W)=EX~4a)P$;GG2u1fq2av@i)hc_u z`vHf6##!qk`>5gF#;KH^b;4&G&Qfi?%HuL=7_h3Y6-I_I+W5x|z#C(s?CA&rsg{T< za$}l7Hbt!Ln;8qfVFJQLBU&d8GbYq$Hi^FV&gb0FqH2JvN9p&_S`?cuCMvM9xp1Zc z1BL7ZE8;LsE64R0N5!x4I`&_V?_Tn9BzTu%7}J-rVu_A?TFe&Jc3_~iqPvt*Bf&lY z<-BuO97{*HK8%N!BPRu(7OM8g#j_2Ia4XSg9m_AvoQmNS#`DQx<8szhPm}e*({mG7 z{{0Jj8{3vz3k{QhBoM*z*q3xwZ%TKJpF%Wy-(Rzxh>yScNtm(|?AqnJR1R{%x~D#n zj0n76UBQMp9rxS9$Leli)z5wZ?-4K5<`YDV>!1``s`eLX$j=LcchRCmbw(pr8I}w35mc1%7is6 z!4}c{{N^aW(0C3p!9@Zi!v?IrABvPp@orM`r`S&Y+vDHo&LJEMi!!&FUNQJG1uWe) zoLPkt-osjK%99?<3#C17Xx*ypcn zF&yn6^;77i6@N@+gZL}CAY8#x*ly!gQOSh^;YnI{$O>I@+2ql(v@8H2s4s@8bU){~E2m5c+VOzm2~v=GAqbB_?_o z-$vbW0ua-_m3;coDgTo{eojx>#XsV~k%eb<26Zoyzt@j@|AFx#CkR`71{DifLq2}w z))|a^10Y8!prs&2*Y*LB(Twj#p;>K zculC&X+dvbWvxG+Kl`Z41IgFk-F?6|GG+3(!8iQ2_)`JijFLI_n&OdHg)Os$3qNX@ z`V!`SwBaGLwzo%nqrb6kaWh-7;0s%Vbld7$@`tXqxywFKcg*#W)ghE(T1|N5zlJX+!G z4NPMbWF;A0EjD=O3H8`Gd5(6>-O!YSCn0#R?vMpQCRMmGU+YD=$1o3idv6z1pu!M< z0=rH@AlV}SjJ)-;=z$Zkp>?3%HM4z_c7#M%6mqPm$l?8NWWGMdrz-nqpjEtD6kS^~ zVPsh8lH0V9Mm#ALK+*EH=HrtO`{35Yt_`W7AUEybz21}{UEs)dIIH92BeO;%T>2vG zcSHJFmh__OU5{&EctI(Q3AGYLO|}yN4?- zMijdng-)wEGfMigoXg6-PkPzPSIIxT-$)i>CA@86BsXsXUI*PMP#f@edfKv^E{E+D)WimIMWH4kag&@zNDtdW(`ixI) zkvgoHPYeL?=3{IO$gX%GE8nA7$)%=Iph0{2;II!Z7Y(3l#QD`cJ^=Rqib;v#ipv|! z`n1VulP{{OqwN!zTW3+E%>T3p zP!!_yFEUis++8^YM`)5GoKrP%1hWkJ8sVUvO4pY1NK?Gl2e}Cxd&gie9mYEF zzOEI7bf?L?4B6W5lh5_RN+xsBSFNN_B~Pc|tb<(T)h8vC)Fm_s z4^ncV`E?Hf8x|A3EM7@fSKmSf%;xy}Eyq>PJ06w)sEZ)Wn+Jdseok$ZB2dEd5-6Q& z6*Ye`S#kxQu9iEXL=8x5f7~@V+Mku}rT{vw@2y}~y2`a=ibl5Qr z{L72UZ*ndRDGRNea@a7V8_AJY2#P>Zr8rQ3I#rr_=c{DvTqyzZu})T()*!d4zXT^_ zGYI%WIBL(5XV13p`cg~DXspuNtHkf6n4~YNSd3_~Ug!~&Yb7-xh-zwzuGY&oZZD4- z6i+5XkWw+_&+HL3T6Y{O?vNlp7G8IcAx<~a!u+cFr|E8MbQsrnZhQ=N$7ksz1Sy{P zKGWm5c2GLj0fO3@cQ*mW*d=Et1;Q)qhMDS^5=-_gk>{;*vONwW3GXcHj<;M%PS_et z)*hCR4;``|)%rx)4%#)LtCFl!gOkTVsQ@EfxPQF#$5M6pK(4Y2XoeMD_((*;=A9Ce#*P(b`P2O|j$W+kBW~-T6tE9t3OWor+14B)w zrzyc;M}Iz{SP>pv7Js*la0RQs(4-FHS!HNYA^a1S>n_hQyuq@)n^pMvjd^QF(oyR% z#nZ&&(?UdGDFM_=5`>G~q!dtLBl;+LQ~bgbv$HS(f?v0p=4c{++if_Fo!DKBVqqn} zY9+9et3_ZgpJ6pTjc<3dDS;x_#C$3f6?*W#(YT)>!X;Wjww+}6tuRMq_~ih}khk$+ z{XG#Xh7xIM5CMGYeo>LE66JAVP_xJ}TC}kz3^qO4TMMbVw%mCXD$4OFb-A5UoE*u; z)pRZz@1jqjz-{BCLECr=A4tYytwOqWv^sC;S~sO3NYLDqjPtu7SifnCHW#EKN z-LiBx8?XLabKvOgd4DXceW0n6>DbQtGqo5JwUlhouk{p+U_zP11jzjnaFU))&Rki@ zo~;uV{ldd~@oXS~!h=|xdtLr=F6q|P?uOzYsJIVJ3Z_F@l`PSq%bydNQK4i<=Et zc{6ny$jqMehaX3<+2ehk-La)lZ^`{iy5gI?o~rN0$G0Auo9T>b;)=2&X*3!v)1|Pv zxj0YCd`~*VvxU&+obZ09b2K-%`gQsMna^HTOis8;-vI0^N5G@+NL_Sjomd+GZ5{=a zcVFpb_||%F*LX!V$0ZxeZn+j`<+CtjF!We(N6-TQtzWXLKlu0>S2es?eU6v#A#99w z#^t3o9-e@ExU$r$Cc?$#zt25x5{||pLm)q7-`RL+-`P{4V#TO`8;7*xw569h9rCX^uumNRPyPJbd)s ztB&a$?iEX2!dSzsU2N?wi9M>br9Nv7O*~~UBxFwngS?_n1$rCN(@ZfbgE1{N*@>Li zKuJMCfn2VGp|23na0)z_Hc>(Ak)5A>Xuc;XcT4-FRmmU41~xmXhTR7zMqgHBaeLKj zxgpHX!IbXd>u6luX>>s2Nah1StAEUKy=>^5fvJL2}`*XMWba~k#a14mK> zW|`|RXPYkbIX8}w65ieTc|pg`BLs+BKtAX2JNOH(%#@70rvBM7)%hrTUG`<}*R9Q} z9{ZG3UAekhwnbTHBXY{F3m?^giBWdq+lT7y^W34CcBunij*cj&mqa5XyzTM)&Z&)p z`U|GsBzDVJnq-vP=>WCqu+Eknu9bWy-y1YhScdZzO8!9du<#W! z!5f-=_o@pX-)qI6Lh+Q;Pj(Q<*c$b%MBtFFYBK%67lH!Qe#xUnLnSuYAQVJ=(nblXY(GI9bngd z!s5LVM(t&y0*Qj(Fb z!`B(Gj=zrR?a{bNCu4bva#1odQn$XgrLQQyC#CheBblXQ;S$fA9&iWF+l6qVUIA7% zUA&^00u~yBLOZ8g2DK66HIV9GXovx}d;7z7y;OCG9Tu_yPRU6BC|s~Rl`%h+QtDr^ z1LIkQ`aQgC^^%+GD%iD@jxBa<3=E3L70iXc{^D8#MUHmP-5sxX3cXT0;+~w)beaxk zh3apsMnI4Jmxc@*ny5#oPj4m&MWjgd-+SFTtJ!c1k!uNO1uMzWI#7t}PjWo@E z&5zFKWjk}2@w!tjLHW6>4K*RFg+JW(xp>jZk)tQ}wW~dzi3Pr^1+sDEa^)s8;IDbIEFn>l%#D zAW#KQjKKw{&*HU_Vs37(@9)yx_b$=g+;M$wi*I>Bd1fYcy0{DL(A2d(R4q3#p4w;x zXc5Lc04UBw+sCpw+ZKYve`mORh9uU@+r`IPnr`a05;OEu{<@t6qdM&{8Ld--}onG0%DsyCqF`3!R%v9enrqxjOQ7!vh@KV*f-aCDTJ$Gs8hgPYKe` zTX&rCw{MHA+7r#RUpKd6iBO$&7(fmlUr7sDBeKsjEobfy!*`z@u$aTp?&?R7L_{ak z0J)1H8dt<8Eaa#jhsv{oK+=2JdL#<#*ixsY%81p+S#rMT>j;2!Ho&482!H)1@@ zK5WeMirfvJpy+O?6 zJ@{qaiX>1#ka}Hu>!r0oMU@3w(*SINepCI%tt32Z!D~Z*PIaVj?e;L+IhkNb$@bHd za*d3-sW@5i!rFLgP(p@aN`mR&a*fYcrkl*_ETr}&WFGe=G4vN)w=C@>ea)&GIq4+l zouSh`k&4fSt5Xfh%!mgQ@Y9lZ@TuF?*b$j99 zD?=iWV6>9V6eh5gZh*&{`ySa|hHE?Bs}+);UsJicLRC_cyPX(#S~;<3!Y^i zZhpXht&u(GQr4%7sM?E#010So;SpYySrL#=sE3dLn~B@4hm7*zc!)=EtU4&eIA?>8 z0D+RnEtleP6$xyzXurc|O1DdQo)__``?Ty0H{M4EuAYuOyo8@ODl6FYu%wpnyKLyWHfY$M*fZa1_mzCgVjSk z`F%5mYN;?6Ew>;OiLCf}w{(FXgPj46dco-(F`r;rB8KTb{POFU^f|j(Bm^sy#&0r4 zOXJP;<|rbSS7{t}q-ZzItE)(UoD0@h@2yDfcF8Qy^AtpoY14^uli(&aH+YkYcmpdU}B$23vd}xerCS@CU=paa3W+G@plor)FK{jOl`}%`Ks30gLiBp{Gr|nh>7I z>b#-?^&m1Bk7&bq=HPF0U5knuQp>od;E~xfuZp3?CsX(zDHBnY$~FO(0ZXaPtd6GoXRgRqO&@7R^T?~PHhZRo zT`_6{F^n{(jWo*8%sZ=x-f^ui=082PP7sS$25Jl90CM)@V-^7Ev~SK&r~4+ezPQC) z+gk{~sbFR_@C%p09#aH(5iWK_Kve`h>L!V|u(HTx%6^NZOor1xZ6#zLNTgJ%sF9@Q{$WiCcs45V3k3;-FxcTbT||a`q-6 zef2HR=Jk~oc`}vUSUc*g_R)g-CxRxtyk$>{X&xU$J!t@kWHhGbTD^%PACVcPk&W_x z%Z|tK(T5E51BXymz;#q-g~r5uFQBqOINN? zM7p?7x-#O6PDki~; z>5mRUHijU%T9yiEp_pWP#H&00Wi|Id)$Py0{K{KC_BCP*y1XE z8VU3XdFMkgLOST9WO;MiiPgkS)^Ae!&(ojsDlF6cvHy&6Z|fW@54E_QM~?kY8l>?e zR1bH01BY=%e(eb?8H-@St6#gVj0UaS=bBn{ag8=IYiD|dm8hfYx>>SD$ajii#Qe$| zubTrbc`W{8Xwmj;W!(U&&|hjt-_|R+g%tyJ==Bh>PgTEWQ!aW9w)Lt|L#G$oz(Q^9 z**?vS9P!*^hWQR>&??+=F2So(LBh#M7A;*ssHXgz8HcvpoY*zuw86U5w=*!>?y&=| zoM>cmj}RtBMyymLb$#^inI#HGJ@s(f+xZPK=M~~rf};ZSf+LBVCL3gbIwfDk6^eJF zwN0)x|6)(`M*A#1dlC>lv-!4tAYSPL@|pV;WTX_t<(hG!7ow>zGw@CwLfv#*z3P%w zi2O5(gheZJn8n-&aI|DTpZ9R!Sxs$->*x7}{(Y{T6-@+Fv_EEbdjjOFax@l*Zo>|@ zF3Fk50Ro5b4z~y|7H67Fsx3YnJ|^yzIQFXNYdgD0vbc&14iFdTlX?%rXz-vR(5{-C_ho{`&7DMiR`4^j<_+It0BIb=ub*W)8N? zbe(Ot_EheyAd5I*eqIZqdVV_OgGZS1k&4^+#?YLDD?}3rIh1s>g4FN-o2X+^Q=uKrFWR< z>=6z%REvE~naG9@R9ff^UW1_In-Aj7M0r6Yl^dzqGgYQTP`O~D=Jqi4>4|!hA>G-K z`KKhYEm=s?`$JCSIJ{}zNyh!)PI!?@b`p0#h4-fEo9~{YLA{snq3-=Au`S2u8}-fqL|h?i|cKP8D0`huJSFlz<2cF`1|<*o5ieAJI){ONvwAE z;2yzZBif0n6!Po?6;SiK`@Q3BX-BgF)ZE?Xn?w4(Mljbe zIZkESMBS*9#Dme%(P6_OBu{i0X={wxd;oHU9z8S!YBbfHp1V^2KN&*)=W;ggE272Y zc?B8YrP;KMrHWkF-T1L<7yyDwZ#r8Jki6t<>3lF`2}1D`&VUJ39$!ng3#2}R$(`}gu;&DZfx&HVe%$RFJ^JSP`jg$!xq^4k1=rE9IE z;zFjg37?KkE8lc|t*A_Z&I|9ue6@?^`-I8yyC!pn<*~RS7a1KsTZjGB((rd*9~gfQ zE?wDu54!xpjx!f{UFB|x8B!7p>P9u>Mylx>fhvZ;sEt%#KD0P$673=`K#`37Xx(sU z*VmrlU<}AHYG+luVi*%9-@_)}9p>$Q&v1FqB z!UAuhS_-s{^W5$Q{SG@~RN{krga<~0-7|(b&f@U*>9g!o6n-A;te}q|?&9a;;&D%( zMi|8Q+*^~sQ9?2tmz$Tj{h0Ag^;;Ujwj_uP|XSvr#6p)qHt^%~wMDRN6P3 zVUr=tbd)PkkqbxI7`#smocp$@?geNVLu^7uf@dpeBV)P_D}_aJ?C~Kr*HZND*F2@V zx=2-ZFF7}GdXLwQg=8ZXB4GIVEjuko=<(y~rqsLL-9>QjtLFy_w z4dim`RHVZQ(bLsizsIWm*7kp~_uf%$W%-`3yQ^%M%c(KOnA{c^Y>`a1h+Q@!hXNr) zrc5-5U__P(Rd(4X3JXk5Wki%fGC^PgLJlM$f{_p+gUJFUj4g7gQTKhb=FPfy=Jvhs z&CFZt6@RcmXP>>#+0x$o=(m60@8{cxOa9R$;skzJ5M#Hq!?oE=7B%Y4{xTq?LxBm9 ztD-cev7^PDzq)+YQw#9CLY8_LE6)rVPmDc`cA`slyo%dfo$vgqWO<@_U2$ObMYAod zJB`;dnk_;j^rf^pfa8f=UcC|W@KEK{O5Uvb$jyemP3l$5L3xY#Mu>HbTX*-2O;8=& z_1%QW1PmasPo|@OU9&3I4^FELKPRORS8R>ib3B4eOoXKme-4zLriM=?)zlq!F5JPq zw6*4qzIFsgp0Sav)U8BazIe6wOK_~>)HYgOD`gvP?5L6Y221L4E9u+)GSenC$`0m_ zIOpG~L+c^5DdOCgKIdf^UPx*KpjK%8Wr8S0ltGYvmY>c^GP?bC^awo9datS^;PrE-B$nKe~2 zJJf)7#?Lxuyc-a8gQHKcI`b;g+uIPFT-&{uG0kY2u8fM=_}lI5eB;vRlyp z+{NdoL_2fHX-WQTdwfveVTVMymoZJmJM{DMGjB+Y*bE7Mdig(JBXNEB6sLWM-p{G`f0mB#!4+J(F( zs|AE&s)bd3pN{2+PSconyO>KUd z9rewEW43xTL90bjCl>d^Oj6ryFaSu)9+>tET`iI~lxPwAvvcuiP+d%!cTrs+!o&bN z=-6i7;}Xb)G_w>Rz5XUU;%Ncz$)EVo)aZc;uX^|Ns~97gYaax8eNBlz;gOW+**CB0 zqZ}9>|3IZH4PHCuvf(2pPY=|ZC%`M7Jbo02jT;_h%O9aUoLg-krc$+SL=M`Qn_`dXw3kPDfF0Rtimx!IVtcC0#iBBoYSoB5Y+bEPcz z&-M-xaeIQiUz9tkf)R@{vtW$M%Lj`71uDUEREMyhRMrnqXS#%WVsSaxw)pLwwhTVH`HE0qaSETB`}QMeUBYH%1f< zv!YImTd^UDHm}Ea?Ot7Uy}s{X|K};FBe}sCjR4)?31l3}O{Ssn9y9RMq5Jla9p64^ zN!YR92&!GTz~HgjGfG1kJ7~Ils2Pj5Xlxq`@*~DSEGk=%S57!>bb}?Pt6d+ne!V>c zgj!cUW1Z;;bMPtysC%AsTWQM#YCKlK%wF2TA*_|n=-^6rF5&> z{G|TIZ0%!)#tUhTQ+N_$|FAvXprqjSQAfxCYReR&>I^6mWy1`J zCW=DbL`{L}Ef~j|X=nQ8U5RuWc0Eb0dcqj4qf}mmB;rn}+n1g%Y#i4e9+CD+(M4~U z9;M+;^gD$g1ae=$KY*{FlSxo=jbBFkodTgK?WWX0c{y`mnPK;mzj0$ya~lv{ zn?uv?rDtFC&4+$mlPnT${vbX!ZGs#9ELi;ci~Az(9f~VNU%lA8mey$1oVOm`%U_{Y z5ySPb=^l?iyyHg8p$Z!GGPx4tA~oX)26aE@D$>8Fq+N1X5AzN1<-E&^^udP~iyF3b z;o1ENlT2*EA`GN6fC8an;oO;0nx3rf?F@R?B}d&E{DZF}&JSJ>e3^a5u6L>C;(&TI zsAz(3(fLd)>dV7c)6?>Q&hGVVUuTSym3u5!hf~R-fdyc;*BO58<+>48-QYfaMLr_K zMCVDF>Al{jRMNzu#0=%cJ@v0QkMT=Y^`5AG9u&8yR8bU}7H#K?_qk;aWx0(7C|xm- zEPxr%Wt+L78(2sno+xKl$c$CYE4*I26OjARu=Q=%v#MVVcZz&a`(zOgG2Eq)SHrXX zQK_Fs|GrDQltzEiGr1<&t}~rssvO0xBn|t7i=@gGqV@%_G6m^dMY#<-BTB2Am$45Y zc=vYbIrs!^6VwgDvWYM)Xd!Rrz;UxRv^BP(=~4jbfn924qmlJk|JWcq3e3Ou(nI9Z zUpm`|SNUGOOP(sLgiW5qjS8l-zSRzw(FoyODDIUB=C5hDE2pEOsCFIDS_4RA02U05 zD$a6M`8nL?L^~_Z=BTE6EzOAerW>+#bV>WC`l08lYfC`|qs$?6i@*0Y1 z%N-?g=%r7Ic712SOH{a<4(}^_-uazgrGBEvM|Pa;^UWEkDSyB(6vgS(2xd$en6HAJ@T9P%B zbFPBXTO2*#?=9p|K_AXR#GW5*eXcZ_Ku%B4+H$BRO>~2%$U31&EEP#?qxWX2pviB>^xyx}r6ymm|Ov#aPi?L||y z0XPNi!+*rK{STwhMcIghRxb(pLT;{Xv8pR4%q4C;gKz2HUoZ2PbWeOlq@74*1z_q_B zsD7KY9={eMTjrkOCneWsNZ;C*0G-BsF4OhRziFdb!2rgz3BHTO${%_yAg@eoesDbS zXk7?{IWFGmG5s}@D`z`On^#ppB?gF36LwNN*l$7QMPAWVQPKW#^#{M7D%+E;u1V0D z^?`1Medt?s^EU-$QVVd#gQ`%dV5U!|#UHDvlz#pqb>Dw9n&0R&V<@xj=KX1f3SZ#q z{AM+y-`G(?PjhtZi!{unCR@ej>9_yI<=L-y52YKe{Zc-7**-YBVxs6)7`>CN$pxxl z%w-tt8}D1BOmA2?Ek_Ks=j%#0(QPqPMN5GOMW{`4lC=tH(zoecAEIs3tXsAWYl>a$ zqB9%3zT9GUvLZ#1{nD!G=d)9)3&LacwgW17$)6!xGA09#?U#F&u3X55kA~cTu)W{Y z9V@xgxwj7>w>ns33)%uzLjm*WL00Qj;T#=4RKviifbK;xS%wLF-Ok&YKzHBtNj{94 zs0~d^VTH6IV7t8FJ2CjX6=sH*%t2k?M>g@>`j(==PKR(7XS#3Ge=4a66-O@%npCd4*y4I2UOfj>7_?&oaa|GR{xU>6Pdv$2P%oW zmrb`0XF?aFPkqDq`tyI}G39?r*|U7NlL(pN@PQ-r3U=>!?$lSxU;h&g{po1csBGoy zZ~R0V%JPZnqf-W|cQ4L@`AdY_H5VtBD<4EsEx3lh4sg3V7?6O0(XOtuD5oH;ha&aU z;TfbCzffz5Qc+|l>e)c3W7Pr{?lc^PrS{$qsRV znkP*}I51^oB5Jn^!&pb2s*2oE^ln{|f#3Kh(b+?ni>ObyG=i(M?YS48l$5{e^l3@M zVeaktw#ubV>lNjB1O}_jN<52&1$#__!2-=iS=FZ2)8ypTXMXbXgA_?9L)w&b`4BZ)SWNTbY-W^94L z*Qb3j_~L5bK$Y5h#v z{hTgtja+T&hj37QE<6k4(q=rNO3@QmS`b?*srv^$2=O-Z(o?=o@qOlnwF^D=f+}fl z%O?B7lDIkqDVjE5%qta9H@Il^+}BvVSYa4prA_;dGAl-aPzx;Q|q@XO*7L!RFO=l!Vp zTgkR_^>n>GQ(sSHF~VNsVY?fPQORuBz4vG1nb#5jg63&z~1gMECw1)L+?qps5-y=(gHUoIDIPKBDpVDqaCbIO#E-9k@ZFa{?ZA{e?7$z z)UrXjzuI;_ov-YQpCe(SEG$@+PNlNfqIS2}?zOK>zkr;(zi7P*YD8%h>5UK)4CkkG;}t$M;sPF+<0Z&m+4`%5s?_CF?qhjhN^m1HdJ z{`}1#|L6Zijc339c9L2;_+g_3hI|uGmP}^}cp!}H)a3+lG(kj@qoIquZ z*d?CU+g<(iG2bo94%u=C-LsJI&P{GqJ!^rs;W>B;oThd<;&bU_^J8gUWbTg#;N<*U zlbToO;+v9b&6EL0QgzLyF)VaX`We6YBMAM5_3)r(tpA>tjtwyG2)sv`0U&H2!_5y5 zi{6ZXaWG9BXFvV0GK#!EAf4Na)88yFDuJBW%Xb%21nb*4)~1;}LU0WRce1v?x<>!R zRV9DyNac7L=;)lwY?>;+di&r&@wd;Dvdu{&j@)UCJJl#`^jIO{k~cxi#Sj;z@t1UK zW=g4%P=ac-K(8}bz(_b*R=E4&yPivX>)RPo`wGcLOQq3KC$?$_{%b&rEl1#1*rVua zE%F)+P}olDE<>CsQWC^(pC&Rw%@Th&sI<}{B6q*bS52SWb6qTPi&Z@up#Db4J;^$_ zkCp6SvdBGdh_CWB!G(oxMaz5=#B_3V6f3#(RFDlsL!4J^i6gDjKc05eh?MrcQ*@JE zpldu;niVl{vM}Ipe+)Rl9{j-hbKnc3Y<+uVEz-S=ItV^GE$^Ya5E80D7D-eLA zTt4+g&r;es{qmvs2CXosyjr(R&G~M8w)Zb7I2;Z?o<4y)+1{&JO|;0t@fBW)QxyEB zq8bE1Mn4@C)EEKUWbB$$McB@{2sAnLFvFB;owJ$_Ut-1U8V-rS+;l)OAL6E~lB6S8J@@weRUpq~& z=nmN`NW7hIbcY}-Wko~^8#Ds0-db`rX1SA5J6@r!MDJlr@Xb(@lgDCA(0R;w-vnW8 zxEnot6P4{zT@vSlc2}J%z4C7Lex+CEfpU%Z&5!K9#kuY0lW`vMMcl2)s6vyQ`eyUUU+$Q)%kNtXgRpX z@Cvpg;&RzZUQdKDlFGQ+U|3r(*G~|jM7<@e(`GM%2BVl}shfAj)=Khng*lLqT_Jf- zWTmVsTt2_wo1X5EbD8HEO$3%HMC={?xZahYCLgw5#iR^96#|WrJ?%$URd5HgQmZR6 zA}H!E$g^K<^w>tq!)0xllP}DsT?FQ=0LQkh9j?kYk6o}|EWyaYt{y9nb@{it z>ijUQef2RIl|A5yfCb+z!+}656Rjs_LB+B;5tIaUUN<@1gjB`)8-Hl^gV0k>Uomv} zi$R$1qm}a|L=zHc!+_v%;6baHEs&BhT5TLA$Xv8l&aKT`yR#L?bA=Gon{fgs2G~IK z#xD2sxF>(Bv~ww8A%&mIY;Y9IvVb8zkhYBdgzv<$&SoV%R%{+NZo-25uQO~Y6!i-?sl+rPJbXZ`B zT{V14(N?W!)!ndFh(0h1+NA0;m`w$r*IBi5<~UZ_E(DuRfvc~r zq{|oWl?8IRN3g)8)RTs|s~g9jmUS9Y@V|pG5_CIMoF@A~H_#@D&9u7)?oI5F84rK0 zu1LyE9)Dz_ICSLB(qB``7~9J~NLoE*Ji0K#0RQ@Yrn2imY;~$O#;RHScybtPAM0HJi*dCsquK_BTBKH%?eAZs4lfUxTV4yf z^s*vQ;!ba}Unc?49Ho>QV=)2)Ru-;owCokwn$0{_iVSre7`g7ox@Ol=m+6}u@@bH8S3BCqn0z+JskN&37eRL(v#R6I=^*KDDmqQAvp8)bFPPIeheHAgficRGEy5#mNgiBM2>0!=kO0{9iw~k^P#szw8jkp1g-4 z0v{o81|piN+^S3><|(J;_fxfJ1ss&)+~eqLT4+h*?Tl~((6TqynG-r}?FMt_pJ-HI zw(b`q>R7%}F+72>+jf632NS(E* zc%*H*&=&2gAfkV`oH4gO(-wAQ&@HP(R-=jqhV_)H{tC(Ui9hS@#jnWdHVyf3M|+(f z`drT0&O6+0SeCTJZLw%`51pOrTkk05yEB+BJw8ads!izWxC<$D&tY*XEXOjv0&eum z#%eb;V_k__A%0!YAkxFCSvQODE(BO#UoWsKXuWB&jxq-GQYQ};oQMWTo~Db!jJm0- ztUWyRvn-~e(ZdFg5pu&Xrr!tkcgrj->~6Vviwy?qd`6UlOHy?Md$5(;I(Bw#`2`PW zH3FgG!!Dy_NUC^OAem0g__RmV;^U7mY^l`@$E?2@FUZv1woDd~1}G&G%PR`p*xRE9 zm*;dxORW|fq-00#($uu4IC4Ec-iT(I0J|7`R2!EPTr*34dH|h%Z+i{Uu3D#(021wT z$`muKqNg&Z7-foZFTDz4GA1sZDfaw4ZLx!r7}+|cY2h`cfTTn zuaAIXdLG9B;3_X3%1lT)maen%|8cn2SKZdjppRC*oDO9x$a-{_MS0L>>wAxdB5#Jg zTtD)#KVcNQtyUuBS#>CAJ4xUTcCx5fT44*e<)`N3N8&Z|f2+4XFPqhgAg7GXl=Ntc z#^=%^mzLqF8p7!joBmHl#bS2V1%RK@R~?z_MyoxluX08dU2~POF{+_(YRS<+v?V{I zY=$u4x1|;6-k4Lp+lsQcmP-KOvn5xDrFzVk*ilFNM*|tFTff>A^=_BkXdVv(x;!(I zN}td0_#R(AaTK}2yX}c39{8+z?xKvg$HJ4+-ee1)j}jfn0P*(=7rjp)yE&<^j<3jv zG91ItMfIn5J*aRfFbR+W0*Pm;$Rc*ycpjrzor+cYxqnghQy`!EY4F2 zm{A*o%EnPCt)5Z6t@m+Tc``Qfq3FIbU(fQ2=kIdBCXIy>J5U%6RvJ1@L`obDUS{|+ z9Tl)_r?oK!5JQc@NcKriX){^>z-%gRCRncy89ICa+RsrF{#v;p>8*s*n`#_pzcN{D z#p+$Q8%KI=U2|;RQ|t=TGh5s|&Jo}x4v&c%5;!hW(k;ZRSSsQ9!{$JR zhU69^RiNKGvTS*EsSS@IkL0OT^mVD&a9e0nxw3%Z^0~3x3@I&9E5Qm}au{l1k0gEs z&y;j8t2g@JR?#lHTp;scMyb^rE20Mg?gxt`3Y0q`vLFW5Q6R2bKRLKxWO7ypnW<=Z z1fgcaUH3RP=`wahjD(**i{bjsWgP2nM!=7o74z6SpC_THY@&_(4OrcQ3(+m2HRfw` ztD$4P-oTj_O2VWbSAV-{_eOqxa_OaD*!AS3t)*c_%C!iXc|@@5{*=6HbuCD2!7#Iz z07e8uulJCIlDFJz-W>yo)_OIPyi^~|yp*trn1Z2I0;Svo<++EGF5#noSx1+;#a)TK zrl`!km`>R+Sss$m8oyrCv|rR=dg)k}_aNlp9&E1E!&JM?HN@h;vDGKMg=EvWXmblM zn5cLti?-P~1=V9c9OsSqNyf2S(%N8CAK%=s%12FmbQ@H}RsJ#YuDgFw< zmGNcUQk?~p5XsvZ`g5?aPdyg){DWn=JFbiqM_I9v>kLy%E=Xao4GP79@=^=Kjm$bS zT2W=ka$W$MQ@yB#r>O;3u~^P*wrQXYhzoYD80Ax+(RZ!*Fl<6)%T4ikiIIqjdOWt* z**9rEF;tuEQA6FqXa_5AM_aEL=y}!944fCbnFV(h!ZA+GCCi7(p2}F48fwaVe-otJ zAAew-v*TKmcVx^({McoJV?h^Yvmz@@%7B~HNL$%oef2S7F}9rc`lLaB@pYM&tE;N;l$4oKSh zf+f?cX8dfM@Bjq9cYBl~I;XpG4*mWh*UqcKT}#fccQ3emG3N{rfcJLXq$91{%!#sF zCF?d>?~oy{fKE7?0`{if4%Xq51Z%_T$W$S?>NMChiW#5P63~Zo&d8vf^TK+rmt3{A zDb>8a${hY0UdP#7t@_c>*DqJ`{SY4eX0yHMP3YD_PdxRT(s_gPax*z0{B1l$@4Sut zr1NBXrrA`hx8Zk7?qvjOL)C+|TGMjH@oX}~-4|W=BwvUo$-*K!3v3%UFHQ}^;M0(P z?19$0|1h6Y+`a9G?6?<;^}VaEFZ)cVRR?5O5ZX|<%uTpW{AK8Q4n)_6q^r}}a~)ma z7C6S=HUh^`&9@)Daf!l5o(4f>UuX926$7m~KQ$7o zmY4rNR3L1}h6`Wc0^l@>wRe9zwcY;He$XKk`JRAbdhSc`+73`YFQvn*@;PJF3!TW2_g6?R9lbS%x^_DTRD_WY zRP_e{qrqSAm7Pd60BitVxDf#QxQYgtBF^?`2%dQ9>kdkXT9=Z7KDKQ}i>E`Va zQ{3{U7ibN65FQM=_JTnA0q|8hMj+v$2b%-jH0UuO!$LZJ|M ze(T;U>q_7M70Eld25AiM-nRH^JJ-#r_?$=hB)|l4W3>#{C_n#v1@_ogTlR62Z9%MC znok(XZG{XoOG=)G!luk$U_+%47Wv;dj*z6uAN1i8lT8!B_-Q?$>ee@s|8f<7|NZAg z2x;whG^=u3E9>3Xp6c@<*9AH~r)_=cZ+{cG3t~*N@n35-;kJH0fz)5s@Y7wwfvvU( zg~%V(-u(}cLH=I9x(b72Vq%JH+Ac>)$hv9>0Lr zJk)>4c-Zc!7-z<&ac2u*mK8SBNq;ZlV`?$-vVtrXFl(jA)8FG&InAt{SZJ5=}MUqqquwj7P#0T?7Kdg10Nf_x4m@}saW!Y=eSq$9uVL$ zv%1X)xa7}>2YXi%of}<9uI64%**8=AjGkbT0kjQ)5TN`kSX+6$JsWj5dLGa0cI>ih zR%F$(YZGL1C&F30@F`qLA9uz*%T&KUzi%Nvep;4AV*3sZH)3ra*HE1=|`xYm^9~)4=42!z=u-w@vR9X)qmo(^x zLYQEi3T8{T_Xw1}1;tOl5k+)73@@QzSs*5G3mJX5RjY-=w*K>cL;}=31l;#DKgcIA84!a z8uwp`FKSE8Smt6OQPxyag{fBBQB(n!s5Ki{VfeaKEcexmcMEEHWFTn$eVZK0&$LXo z5YV?v9&oURKTIY$FbFi&$RZ}6)h?oMq9~O?(o-^~iWl_oQO&)-?b~04UwYO-Mut5*LfI ztgwwrP_50qwib13?h(dk%^33`UN*NAjuE*64o&_(bu(63NoVVwn3 zM$ZRN`Kntyj_d9oXPHwhYtaE`oRO&w6Vk$rMJB0dFN9>0sDHL53s2Du83}sUn*tJ~ zjB>8#xq9VQNE$*`G>)0Vb)jG)a0R?V>&l(12v3(KrCngzU9J9 z_|ORz45U>xbF*2Xjn5E4TKU-*?}_(VJNnslB7r0~wrrNbsPa{K7+sz>D4RQcMfe}FNRC)DO2bbH+q_$;W@?Rh-|L8SmKDPLh`1O$9*HZ#;L zNu8od-y~LkQmK=vi=r)<}m$zVxoac*x7So#^sl`Y?UC_8jQ8z`X7VP!K8V_|Z z_tb(UG9y}1qS1t{n5I7Sgq$lImr44VTF6$QHrQ;qdiA*6#*ld!ySfrHSl#QbMg~S4 z$=~G6HS9;UFT~lv)STKF(a{u9+Qq334383irSamg&v+hT;Q+0cLSUR;pVE zysJ8e!n)eOkZl!Oo)FAddcAzoVU&LaQT(Wf*I_v7jXo$a*9WyLm;%+VFFrklf&(|3 znGKb>ma{Hy&h=6n=y%@XVz)G|bmioL@%EHA6KkKld6&YMoU)~tqO`Bw%g=>(Ftmm# zsa^C6N5U{vADwT~A}y1D9A8AV2x$2zfi!V4lvcr5_ z|HL4@BH_u~&Pm8jq5RtRK~%?sffPrrp&V<37qH$=V%B^ds(-jI@@#v?!hh)`ug+BU zn!VX_iDD4SB_mz4N8^3C2rhjGr9v9(?L(T-eJXlsT5jRjc0hSFiK{knS78wmks7)g zZ?^3-Xi4nLNTh&%PVA^NUZ~hS^qjPwgfOq09boZm0-56oej?kBkUyhXmM-Lm!zImF zq=R?m*>g_Vw-JN>70A>ZKWAuNZ1;Jse$BQ1YFd6nUm83&E!dIJva!n!Srhm_P4^kt zrPZfXJf3#jjGzaehoxwFOd>fEGY6hg**3ov^#5>QKnrA&Tq{>+`<k!+XF zG&GmY>`e>J)T*wTcCS1f7|i~3n9iFw-J#0tQr1O(jJR}G<^CKOlC#@GEiGO2&NXyqyKL7SF~jbLdq(q&t~EY5_~z2fN6Ez< zV>kO8x2s$aTq>d<-otSQ?-bT=ewoY`shKq=fg!M$oHTiz^4E@$S=2l_&FlKHy%F4F`hKT1rxwXnxuBWhlysEKPT9Wf#3HX| zu~n^*m46M&>GcW{BAhX$+nbPL6^jApEnKLmMRFY=N(Z7*yL$jX*!5b-9s2UduT@4k z|3N2LY6zWFzFV7Sk^wPw8;E}2%}7&$vGnmRng->lG{hB5BySCx0XB0A#ho7AA0 z1JBf_{$i>q@L>}ZC#U=9!J=V`l#}gYGkPQ|bx&Z)AZZ9lbJn{^3bg3Y?Tiy-+KXl_ zMr8?n7c!$6@*{$|#ra%gmak8b_q72Wp(-9n6UoIolBl)dMBg3pwv6Wy<4I{N#L@{P zHNyc9HM{MDLml+0+qXH26B%;L!>KY}JNJr2@zW(T=LU?ueN)GF_FF9K1Rz9}q^}uW z=BpO?*RQ7^-yG8GOquG>A4vR#hjN*&e6vpy0QbHsHX-}Eb#9B)Ix31-d`mcJV4@W| z6xAqDk8$W`_;knY1h;%NLl7vdq(zKezaAFTpP(&a8C+XE4pK^C1#*W_+0(f*I0{BT z3tWrqkU<^V8+Y0q8B7wgRtrE!CYJ=;HcpQf7UgSRBFQ+6N$-&lN)Kg(hchQ;BebKA zuftMhZ(f_uZ*c4Hxi2QmuZxWIPvR66?C^WKO9rz7sqb@tS?kZad^W$!{;{f`#hsR@4|U?$h7Y{%vYBZEie4K;u~4J{;oVuLZuk69awucLNsGVp@D9 zQ=?q0FfzJ;FAH2sZ#TXTrzSyBXsbUsDe*O`)IP|1Td_X+lgnntlXlI(PE4?H&Tf~^ z%F6!rB1B$Z>A8&JP^8w&g|NGOoks*wkEBj-WFkYNUPQj$|0YB#EdLxU@^bnoy`bcj zk*LBY8f?NH2T&*uR4L)~yXrhDx);@s}*U8uQ=9!a3*En%j!VHVR-#oW5G>qxWR0kJ4Eb8(rcRQ4VPnsb;XzxN8KvUvIBgsdpb$A5Bw1xXuj`e42-=-#uj{i$<1d1o z-95%ggD_BkLI=}Mf|wEheQvqrODiJ(sZx|9k}XH^K-FQ~uQmWdeMvneT*@L?U@q;y z971Ue%fF5on+h>0o+R`lNzeMy9{Y!8cGqGE#t!a4#cVx=c4PmF%_?r&r*%6@qRo?0 zcfHi1NUIK3TR80faO8y`N7*{Bc|{aw5I*cS3Lu^-!{K(mfV3^r9V4w?2EI!mc{-V8 zDpsf0%S3=p%K!k7Xu{@PNCPES+y91g`{3ELQKnrNtWA3~1H_F}lHYk_aD_|LIu(p4 zYjLISD4u6^<-kltXqzTYqiIHY0&ZTuD~~zB%dtQfasl&SIw)8TxIyX7Yd?ioj3Z*uPHE`nWe$k?=gTb61>9Z&nNlw}gvq#oBbnb3!CN?opmnf&lL5o<#vWpxesvHV9y z`b)G8syQM;vM}Q%|6I}vO|!VYuP)>_lIOX+u7#OPQcit{-wp@MMnby7{CZHD^Gs=9^Y^LV=UjlKiQ4G1&4w83aLcRG_ro0QxNT&XxTV9FI`O!mHGDR#lpP{iN@YR+iZ&mo(7%xoSt`q z(b&lWVq6FU3quPS7|SVvgzfEhBeQ{PdZG{o%=5S87ewJn%>f7FL||S3<2F%!N|R1Uy7h7axiiAKC~~GC zVYd1JRkii8{>`_v0fyr(*6aNng|d-i-jXvY zL`;IL2&ZXr6z>C`X>SwvXjzY5LP$Y8Wh57K!aPd_k++MhmFniRCdc2YzMuR)RW2Aq_3axmhJwMoq~az| z-N(5$iv*-mkDu`Eb=d2X^=6j_wKM`6riFGS6P&dL`w5B>$;)lr{)6WRaQ%&Ng6a8d z>9?wTJ^?DnrTK&jB5Agxsq~izsSM?AolCn9UT02s!h!=~a?ijya)AK^&(W}O0ccAe z2iP^fA1-6bXAR1$F0GfvRarhjI;LIOR&3B&At5@2y6!pt4b$^&s>IBSLB=9(abv`o z0pOx?bdR-uemmcKP&K?|s?h@QC?0AD`FbB{*xcJw z^47QTv}XNNqDWx>9Pd(4+?%g9uF#!aq=VssR@=oyvpvO@%4h8tTWNARrn1*NXIM~J zgTkin0})+;f>GX+5f`Y)A$}r}nb##okj1+3h&1x!k(5J3_l`@t%)7O8xJx|_SXR|^ zEXX#^&$oG8an@pqS1xuT{wU}#HuY0&?wk42)oes<=hk0&iw=tf?ig$Pvg_DZ_|@0^ zu$aBNsV)CT>kQcV+;+G&0acJbQ(P$vNqp|T^^*T2{02-%X81ai>4&L7cB;|m1-kBN zxg`J=7BDTIl-j{rA~=1uQ8RR%S)lUMmK7=vLO0pg(PZ=sj<^A`_->2(9qsFx0d+1d z7lJYL%SkUt(4fsU~}3BHoV{32tA8h^3L0t21vaT1u8&!lZiv16CKK3R0V*^NY8iXE~Sj zFuJMN53G9#YFm__KD)F9hL$EbA@G=~osutSC4I7 zsG8>L1H8kV+_63@ap_EU*QVvK7FFcC|1kp z@o15%!d8!`rxW?pdRIJ?-Mjj_J5%aGdU`gdl`WrjPO=`2xlY4bSiKYZdiH>%qjqzuyrcoVp?a1_N!lbi`j2w#o>iD;&zpuu2`>q~a=fA{tpa{NM< zDDf!eQr|{spEtY7?A3bisS^G0!8SjUSI==w&sem9V-n|JWpYavrN!l`FZ zNG{z0xr?CmwFx4JFu?%w{Bn;mE%$vpx148;nILtk_Bm2CX z!6bV!eq$;i(Wt89uoO+|vU|UM6X%5ATD;YgI-j4ZZZjCDmqJddgXzRU?ILi6+{Fkz z%6Z0LBF`lLC37WTUi=9{eX!v@Kf8L=V2e~FY*8l&#ljl)TUrvJSuN|k%MIDP^hH{p^Y{^u%e#vIMa#Fa1kb5=P9SVbaRvG54mdkEXdI7 z8sf`il)zYK;6cU5yX{>i1*G))kV?gyjstk1i2@zVD=_GCdX|+xX3v(ys~9CW84L&7;N)g<@xbXOy;<*tw#oyV&`s62aN;SSG3@uvhrboS_;+Q z*47s)f{LAUUTsJD((h~Q=p~cx3mYt@EN=CUOOK0>D#`@~n|4>@r-g@T4kJ`T$(z2I zZvM{cygnxF0dNljBBB-?ft0~)H%jiq_U4r23I;&t0sj{aQOj@iReGw#Y4hqzkeKXm z5%#!NV+45}z@2dax=~#)oSe3u&flGagx!ta^bCFC&vd_>-UnNaRk97k7qxj&N-hUJ z3JNg>`%ScZ9Pc)6r*V`nnKXOfgsQ|#-HU>xD2lnTJpG_B)#UlU&YCen*(pLts zV1%FgA|<3GQa=P(e)o2%me~!ojYL8-8fM_e6M%5z*<{@NNb4eZw_*?wLPhuD-3=_Q z6HlYun<=;+tpP+Zq_I7>W5A(5l)e?zxgZrsJxs`zFc4*o;I=QBSnjGadRR4Hw;oRY z!hYGa>%v7`s!Ny48Eo?b$p;o)ckeD8Iz2Kt_uS3#`#3J) zQeVAa1TCk=jsy^p!Ix4zLp&P@9{LdXEO?{1O#vs))Y_iryFy!(tIw=AH_RxxyATlu zs+lLb^@KL;*d{Pr;T`BwrvYgNsr#}?UB1{J5Z!Lq8Q3a^z-E_xn8*k@E6ldVBAZTEIRpF8otFLin4hks;R2n17` z0wKrGf8xZx{qIZsANcQ^e~8Og$pZORxIh;2`Bd!8Ka*|oudehTa7u`;{o4m)xLbM`O7zdZK6!N@aacU`)mG-mZp<`lC1g z_-y>kF#2Pp{NE>)KYHVj-uVB}>L6HJ6%U@ThVr6~2K3jSORIzxLx|_kz27(`S^V?= z_J#hB2LJ!t1K$iB`<;{x9VE0c@6O=p57zp+6%9OM@0#LPx0ym*o3+%<-3|UPOD7E< z+=fmvo43ZMC}{>YPF=x$hbz)}0HJA_7-1cIIPf`gKCS|-x@Sx0%|vLUaJsfkS)`&) zQ6b2}$6+f7NbbeUXp=?y2w-kS2urURxKcrQR`tRKvVAd8O6pyVsq9$l$)ro2fIx=j zgqn<<{Onc=UEG`+^81OXMECMxaKv%ETezjg>VgSek>PQx*v#WTUn%eM&qF~ey5F1R?LrejDS9i5fdI36);Y*0&wQzoV$sWjlZ8_c_i!G zu1`3&x2*BrbhL2VEA?)?sK_N8Xv%%w7>gR0kUC*vgdkhiWqIy;9K~|oRJpt(lMpe2 zUYu84XtL*?PNAJ7^>NTrVtMnm=5NZjL|$KCla)ma(8b7k8Roz@ykeFCopK|pRrvAHBfut&!=|L|#{^gSo0$m(^5Zp*9I zMgkK4U)X!^ptiC%Thzbqw!7U<4VYkJH_-+R4On3E&o&tYjX{Vc(I(j-f-SN{XeUgj zB`k7ilTkDhLMBMEP0l6=k!2eZ1c(eG`>E$ny_$FL)O%C6YHm%vn*XFzI?_2yd++mo z`}@{f<>e_Re+dks-JF6_Q_JC19jQVNeAnShtR~2T zx%O`NE#mFw96oX{QuBL>l%9?&C1zjd3}!!T$-dbR301Q_n?go)+kLu+n}Kz;^?xZC z-5vpYnZl&Q20@iKmM+$GIW8G8Kii5}UR3=7YAkdZHi+N?MV($wI6F*F@j!ttjC(dz zY>R(gP1|~JD?+y9bl|R2AET@X4wtQ4vV!%tk+y;@a_7gPLOhs>ne)q>a4+&W?I`V0 zsj~l(sTKoUCFZY{oGH36*aj(j%~ivN`W#e_S}ZqPPE;ucNT3Hv2oHE=`4?Ii#Ck&= zzfJwv-){KJ_K~$4DcaCg$x={}8&8?B$#>sqeWcpmC!M4j zjLzH2xc9xyQ}E8WP$&_XKzHJRhidf0+as_rhe$0G5>jWNM`r&n{7#cEO?f*+PsV1a zdB+zYfmsyOrCaI?g=5>Q33jTgQD&5&iJbAnawNLM5Kve9RyG`=7 zw5b#t+AzS0f$WHr2_Kc^{{_K!dv<_I6omUeyCRc_sn3JMqMQ0?Oc1sBumsr6D9xA0 zV3hAzGhoqe11}|dTchs6yYIK=C6!2&SVek*fZ+_Y?eFccAFYsPE1oD|VK$rCDl@ya z6abL%R1+1ct94+zxUbXOqGRX=y9BowRq$%_q}weJ4Eaz5J5=Y%fy>uZw;>q`V_wHU z1esbv@>;_A4%#5gWmLo%fT)pbDSUK_hwM@AOD;qOSp&R4Hau>DdlGi-<$U-_YgR;bXmqBp%#YD@; zYyIsbHS*@F24@`|yD>>gg}Q4b#sl~u+^A>q+bXRqGj&Vcu$xP)W4D9kY#(chnR}+t zHbm&S{mE>xM7xvT=a9U)n{6HGhD4{G0lV$yN2Z3^iJ1P8@SraXv_7wdGo?*l8FhZY zH)6jpYPEjV=DX~0TM?KY;(717GArNEW@h?uxpuy|)NOdU{c*!(ZapmpN0=$IJSeqD z554f1M>p}{EvyYTaZR$G6baS&s?m>caS;0O>|^z7!|J zK2(A+Y_v7dv*1O&-*#|sv6tYl4m{6sf@C}VsH>=523dP*?9rB>15I8&FXmAl`g<+E zIS79lHumg2viT+k5LXchKwx52i$l2QpMyo1H>J&&id05`6?JXTen|^cB#WTA6&q4j z!J>}QG{Y)iunJV=&b-#K@xkq#RC3PG9UTUDN3H$M(o?Vs(#c&2<>5xjm0FsS%1|E9 zpR$qZ5eb)h@JH|5X71f!0fFiHh44Kdgjiy?nJdD`M(GEJ#j^_S0HyfD3QqkJYo=WXqb) zg@uj5nAi(ZfMgNZl*UN3asQ$HIF!QmdA-CLeNMXt4l3Kz{DFheTc01rCVYW83^u?6 zj`i{~uPGa-4>$nO7TPyXR%vhCVz%ij64NpBvwb7>%MY)W!~!Uw#mb0j_9e`1qxh6g=}?N-MV+ z$@=rTH8pVg5cU6CJ?6h;1oR_+Tjw9g8jz};OUDg(_&~Z!&P6$&969o2=bI-Y?(enW zwwt?@l`z?nFzI|3Ot7fQX=P1w8KHB8MvW2zv!3bOh_dekuBPqMGEZb8c^t^8WJ0o5 z98hW|!@z~_@Z0-|w&>hO&9LS7%feOPYwR{7r*isYnRg2p?riTyj%xRV!LDQDKE2dHzBxQU3w!53bo5>p0fQ`GYVc?_7m`}%I+y3XS ziCJEGmZF9&}b~ zVZ8^Yq}1$bwCnr@_Yofvn%@}9UG^ZbLm<5|M>(kBeu#GV>mOqn$f+wp}^o zcU8^p$3r1YE)n0{pY?YmD?KmP_w|lWYMOg5oepG2@YpjRPvrfTKjkK;prN84j}4Q% zIh(FW2`{1)S@k2uMj0DItDM#DIf3J(&?TDbpp5bGSn61>i79h&X2LbK9eK1nqc+_S zw4ZKL75k?~U`i?_R9x_>6mC=Qj}l)`of8Qw$^1TDp<&YuN~?f1=q450+}TMOHXU?W zWDS-ainngWd5kI@dd%#@<`(v{|8nboP}3tch4G7%-KKk-O>gzpD%LfW&c}-5Y}l9T zn+H3wN5H#;n#HM0K<63{<2$3DFwL(+(-mVu?pshKh=l0*L3()fsNXeX;g{{{{KcaP zT(Ak1+Y}?P%JVv%KV2lbX4CJPTU~6s%Xo5oJK^O?KK!@V`9~6Ge?3-8gvN>@A_h_# zx~K^OOAEmWLRMeANx_*n16g0%V@=`=pVEenuRP(VM&W;7gyZ-?nfo(0GUux?bbDB7 z6m0+Dn`c6R!6EMhEEx208oY&ICB$_&)sM5tG24TAmtvwIlY@Kh+m~!-AL;!% z@@CyKy@BYOnpH?z?#V&}dx%l-ZGWB1Cvd8p)|?un21_irSIwy#5?0>z1GVZXYt`EL z>+^F%C)cJ5ss$KTIr`;g^?v?~9Mk9^>bbkg%25m~HT=wz-(7KkA5*zHoUK~p{vlk? z{`W0C*xN!V6!Mm(8zZHjk|7X@aFir`8JSQ)DJL7)mOV07kf}a^zr<({=X0~#QT8?k ztV!5%Uu>!X(7_m=_x7(Bhs(A0tLAF%dnaxUE)sl63O9DKo`w34%$$LC&>0_}W8rOG z)1P}Njq!|(4p?ZiI!a6Y_@%zUxaynj@BChczbbrO{N~gTAOA}(DgQsYsDNMHcKx*T z+|_<;0bF^jJY9#TduEXkgN{!0rl{4BZe!dTpfEG#hd-xL+bfpX;jgD63sTgw7zIGd zZ3oi_kj+`#GX42ByCCfOQsBN)kF|o7OU2pf=*`ZgaVh-P8sXZ)+U9Cd0lLFfmO2?< zR$W!}Di13e#hRFDJ``1dY3J#qL6(z7z8A%y-gOqqUAuBQIIt|Hl=`ryj*|}zjEO<% zh(zkX|1;PVombYWRI}_E=iepZHJIF8XDa+nOLSTxehMt>fa`=YiqrcvUMFsk-YdhH z{1DXk?E{Z%?al~EUah03=*%dRejM}qjldsktm(P|f5|rF`re<~{tYWb+{h7dRfKBo z7nsf%_5Roz(0X%+pct>9i=^Nz^(TP#9_ADB#DwenC53V4r>4!*$Z$&TEMb4t8A$k3 zr@%A$vx2E>H5R`GKHOPHiz2vksD*?p?n{0f)F3=O=Eq1Ci|ABoC%~%3?rvQwEz17u zsT4WvzJUZU?iV;7T&1`%2h}YwV@K>^R5sM2V`VU}8qHH3kzKdEmW_b)j;qC~9NO-j z-E!Pvf$dw?_)>m7=LyOsB`EQs-4l!<`2g~=<0eh;C24-{-9 zf|NhUW>N5HQzj5{5-_)+mM0Bv?c}J}qsOHWam95bb1xJ#e*>g&ti@BRCIZXohGzWS z?2RiqZW+u^I4m9ozQp>L~fTol&Nc4w{C-U+>@#hQ=2zszrS8dOOh(Nr0 zPxbhXK5tqq?GgQ`4M$3v1=f#KGl__t$XH#7+?&-C{nI9-RYQN$^CkXR9%cF7seL16Id*?}oFx;= ze%&MPl5>Mx=_N_^u+zSL9Nb+!W)!&vv@0#uL+~n&UbXb?h)R3ou6fr{QC7JWqsV$Y zV_v9+F^gmvZ}ECe&C6okCs1cpE+{$|hn{7d z{Ma}1SuVM}u&F8MM&JfZCK9Z=YwjZiKnN)MWF2vjWk&u?Z_)Q0xm!7bjawoi1Qf;B zY-@sw;J-ekA3kQy-TpzPAi+BzTY34o9GY`-+W#tSgj7G*;iG;%#HoK#C138MoA?S& z!yH8E_cDp^mM75KC@BjT%&_PNr=}>H=DXfD^P(l1eO29xu@U+}6go<|;i&V10;fpN znTJuO903dSO-C12+=9YK7dr9OdNwS- zdX#bq+#1^5`)U4-{#iUH2$*332xZl`zgt9ZmibsTc=U-jBN2yI1+()-ucj>+a-rkI zDh4;SB80NkS8LO%`*ZwW*SSF+SR==#sJS=N|1r#<#|>4!;BrC}j>NRFA*_T4jF5Rb z+aVMl3cEY?%%5z~y*urykJ*4m7GEMIRVVMQ`33By)$JK&8%T<@*)iYVai98=)(d9@ zj?J{K$x@FWBxtsx#m%|Uz=bzlNvnpSghW#G)ipQ&Y=^O#6IOzzHdNm;&I9R8jxX1( zV7)w_1t7+=tSd1*#ID+Y+PCvLHHvr}Kt!*P+U=S)ePdy>*}WL@fc4z^uLe1CMa@~G zi4=7Dy-OGFM}(&zMK|=Ql^pa7j00xNH`nIn<^56q_h~18emymL?7>Vp@e$ZWID9?j z^d)SRk;uq6Ztpj$H1R-b3+*N#Fx{{!owJlLJO&TxgE2 zAYoma(vLY|1;^wcX?$}WfpwpS5!|6VWk?w(=F|d!ODk2Rvow|X#0YRuK8zg~udvBF z!Zz_uQ@~d_*Vxc$i)qAl?^6ByNTLO%au^PoPLJ0#n500*(P}O!7X1r~**E6PL%(2> z2|OMJTv=a?Q0BrzJGSRF$_EwiwYcjVClmcTN7y-`#^}($v=b~`Qke|b?ih)}Vg-Z& zsIca^Lb-Jqu^7i>N2=NJ`%W>lWi15I0*>z*kpIn3RG^N8yw2#xvp9j_+CQS zC=9QM?9y%bCBUX5H^`!&J{vz=?UGAbN;U*5h6ioF#> z(F0EnqxigXB(3@DDd!TQn;qe62`D~o8|;zSZqWLZo`Us*HzToH<-9osP?vkbM3vv> zp72cPP)Dsy{9GX38EBsGQhOtxoquv||FuV^6f6U#>>V(00rDH^0d2#exwbZ`unzl0 z*K9P)y5nIAeG7_ut&~yTGHK<$7f6bC03$BK03uej!$a$_yOxhdj913Aa}UK(IB`sm zpDU{TZXO}ww3%}xG77I6b#ynp@8i=l3+h%xCX?y}R@Q&xj35gill+I1p* zpUdXp(J9r9W@f86zI;sVS*`EXKl*9yO8I?+U{zfv>~VR7bqZ~B=+MM=Vck?TOrqye zePDxRm>F02a%>o-&rQ6m!2HnbWnO9Ltmdr{&fCVv`l;zDbwLnGAauIE3>Z-txXUIp zzCeF(ovZYZP92k29mTERkbov2^D$vSCqHCP=5>(Tp`2Ck?`?5x=qNO?D(ztYCVL|*$mZPN>t z-k|Z^20Q5n7|h;GU{mC7HQkmGi4M>01aX?M$h$qj`_MuHVLL&|e!|>*lt0;af?s?p@81l$NPc zU4eC-=bV?K8E}R*6_4R8dIYW3MB;c)fJ&|v&}P7%q3vYPjLTN^wN(ZN#JnOuU3D42 z1U4b^Sv)=ZG?NZDmANy#yK4Q)?`nax({IGfv7V!4)6$tRvQ0|z3PzbJYIw5oo4TWa zZJ1;BikqrKmGA~CvcD}ob&}KscershK7SO8qC$W)Q}P>5Bj7w$-GzfK@Oo4v#t%Sk&xC-qWmj zJY)1L{MbR#*V0@rZRVbQDMrmHZZ`>&zbBf*>;s`<2Gj*~n_T-KrD)GiZhU=u(%8xV=xvnG za*Kt{s+(f6Cjn$pJ@RR87h&ktL5iH7ODb++YCz-db_&swqdr7`-oqg4a^HJ4qYaZY zbtz3?Zi13&P=gzffFqwneFzb?EZwWY^BA(zhlq4B^Zmj&J+!L|Jcu8;X_Eiqac}Ia zS#-U3Q2K+(7mIjK>T#87uu~k%f42M+1Dw?nq9!!rt%WWK_I4W-5`Tyl#sX_5J$C7% z$8EVuq&c!DL0|jatUv!$+%0MBD-Hp6;xm*&Cxa z#T)_@HEFN{*j7H^*ZI_9%)%&XV%-;&a35OFcwS%zPuRumnA@#cFYJkQrF5F7dDoX! zWJ|ZK?x`d6O#tYnloU+*Okrw;^HEQlMGpP>Os&-NfgAW$2WdOJ1da`{Da`w(cLd4Z zuviN$%Goq&K~@-3nNQ~eu4{>c&nX4cs#7a~ff~cMlYI2)_cI6XQ;{O-0u;U^SxVkaG!d;6K8;#N%fCmiQq;?UaNLXSEB(BR*5L$FLu>1CD z*-f@8?$@f#mvq&2>tOZmb3hl&=K9`p#$XgLSV*rdWWUt6wsqfi+?Rbu4JkUYHH6r9 zfdQ|3^tLG7)xmi9WruZ@BTG%rGzBtUnhKD8c8|isQ=0hldDCw9R<@VNT5D0hs&`SX z0ucklhd7uj@qhq4`EKcW>O&mpTM@#FiL-V{6#ZxRZjB|=gk^9pP`4TUAIngM>a$sSA^BK z@=F6e_JqEykE*g;8<6nk-@L*1ENeaLO&?>Fo7UW6`>OHY@+t{(p}>OlBjaN+YvmM` z)-FXKIkmU#EPWwJBXB4dWQ9HYLAlHEMP@8Z&7$4dC#*=#QIZp?6v$txPQnsjhS|Pq zXA|D`XxW8n9AqCo&^CX8QWMjwb!@cIBQ=OKX4z8@LqHAR4Ck+Effe_6$TC1=28{YH zvS}?-adr(HY_v0l6lXlq@z^`mNX=`jG}a{8pd5i;vW+755Hpk>_?Gske6^oCZU}3; z`UdJ}`XKvYnyAvM{L9=8s&8D{(^<_sMl9iIAM6cTjnl;AxPPptUK@$JHrCy!9;9=x{ZaVl^@Lf;;r(k4-TA~Sl>C#ySR(^Qt zEYXY_(m#v6j5&khr8s2U^DfXSOGLNm`jvRDRGK@}pLQ&U~^^nGENPLgtAard%a z2z9Mi2yj+M3!8As$%khf|D#JyW7{>4%jwxIuBnuesg%MTk0?3Kx_sVzkW!D&YkIei zSB(s7IX&v`2y$|BIEtbcBMrH2HULT~n91h754`5MVxf;;cl4N^LUz6HnZqOaV;M7Q zKi6&URn8X4v+KCyaU_d0Z~e~dg;Ju)T>-TPyX!G+Eby15em-=|V@8~jb+01&RN~vQ zM`mWsYNLlN`f+8j-u`PmcSU?qr$^;kVrD_~YN8>tkaoP>H|g-MS9pA^bBGvdFsk8_ z(wdUgS)%67S6y>A2NSj%kGp+(id)+!QyNr5B6P7hEiwfxmIE0IrN&Pm&+F6%6>8+TOTJFqA z<`k@|Sr_rw<{6tw?8pJ^io*@JJ7frM7uik62d4QS|UJHFX6_ zx21$`0VZk(H03Vpb&rJYhh}6Uz}$$9A@texaVzl)-pcH$o1??o2KG3j4-M_LjC99? z1HzjG#cm_A*0Jdgo!+s68;%;X2EPsH;c6jA*RJ`SfC9JKUV zLsHT$Xf7t|;HcS^rY>=CmzEHl7DuznEBbp@Uk!_{`CNPBih=eWujT>2L^W@L7?UF+ zMl%m>BcS*cc%zeo{&~EC5-*!*1Z$uTW6*bLo*5t+kN2(P9k%ul{njUyB4U$fAiW5X z&iI6Cm_Xs=l1}K*2nP$9%Bs9Yb}RCOga4m92HxHPjc`AWP+^o+Ti4)%h>XJI^7%70LJBXWYG6ofAb0)r&^`X+oD?F#FX58rJ7+V=zT3lIfE2P!vYPK=pG^2ve@2TmQYE3Tn%0~%@X6Lv z!Q!wYSPG59skNIWx-gy|iQA4NH1lrdoGoaQHTSOxgMIOGOd~Df1#u%#qBS`@ZHuMk zwGi@5M$!0QcIgvb&C&&8SECsxb3zXim$fJMIB9L>gd4`lVU+19BrsJfzLnqbr|2b) zZnDHm)e7g1J5vu?)@w?P_+o=gQojV!T!GPhS)FMiCsM#Iz$;VUv32AZeqvUfy(nv! zWseplWMiRUPyJX@*emwA|6>=c{BXnk{GW{yGwpN$jN-_f#|Ivx1Nr8w`Rp()89l}% z#E{M1WjOhi{8{S)jriGuuFFEK0E~SKBsrfMrgh1a@ehN&V7TBnT=fs5tdj=MZL`e! zW8zCc^R?A`6`|h;_UmB)85!3$MQ4MAVBUnuALaEBLyseOR{5{@`h7?$OJG59U&?O|EsY^PkT7DDV`xy)wfysYpSI12v_2o+`jx#*26GPDq9NM4} z$ol<0u*yiRBHJ^)Nr(}9A6=`Uutx75RbX6Pstm~f<3FoNa{eYPT!p4|HH3-cSU3Fa zi+7VKYM!K3<;VZ-|E-5?l#rr}Ql{FiK^Ioq?wEJE2UtakO=f?IXX&KcJf8GKYdUAe zDsN1_pP1R^aU&|&tB!Y!Bs6+vJ?srbI)`mYq0f5^qfI?#if9^j3{;};?3$|Nec>!w-$Wolx1xG27bK04tiCx&`&uIG5F)4(+~MomKi4a(5IonWkh-06YWFOwK27stb2del$p64} z&;Ql#Rdt$beqMxR+1N@dlajk=g5a@p+Ri7#-tIlr-KH*SXYI7NR0di!Z4OgkgJ*9@ zw)=g_(R3;Nq3eDva5wKhN}l2<5G4$tmA?<$#D@G7ZT3IqqmijeqTPxiVzZ2&T+PmEufn*}}6$tuKt zJ@uVK8&Jr2NyXgn*}1a_?p%)%QfWhn^mkpZ4xHS#Iz>M_#{x{j>Z$>GY44-JtCPY*R zsWQEyx!wRB{h;B`8pv77=Pva=AFnz#3DXE+f77pX_Obe>c*X3SrQswRE;${fzY3O@ zkHHY%jf^izLMlXY;X7-shmJtdEkn;y?9AwX55Pdbx9eW+ zQH2=Y&nz8#KZyu5b7sXKnwvY!JV*IG-th9f5<24duaPCYp=lxoHU8J2^HNaU_S>mA zOePA)duk?#N{g5^U84GtV6LGu6EHSW&jXoX#*@EkQ+sQ%jl98+6^dIPNBoEyKh=WG zdL1&t#7tuWxsj+gX?)o1(DH;JV@XI>qz2y3!qxwt{ETMb!2}2kNcBd zA1lYfAv{+pVSuljAJj2vZWtIzqgJpwEWZTxYy9ZwS)gQN03(zYZBZ29Cl`T3`14fRc&=?#Mt{}t^1@g)uQ_}%!v#-ndf^R)WHPrutmL6H(sj~|fZ(JUz ze_5E|jXdu_wHq zMnX=&e-ujCqC4tWoTuYUJSnh|`H>bW4x}lm~f-Vr3QvFm>p=f(f zIz1wa@ia94;uLNdC}MLQLkt#_QO?O{*Vw}AFr$9{Z|B}D0v9`OSF==g#^-u=ok;v6 z+cCfu;9A_3xm73Z?|3~G$4%!4*tVS7&_;^DRwcxuK_sD$!H656{7Uui8qH!3zUe@d z{le$D3bFQPk<>NVehgpZR8B<!K1R?tcdK}WG+nLpXnQkS#Sj3Ja zcuNJNyR=?|G_pXm+F};(J%k%6-c`pchFA-|F(!n^0>Nz{8w@8jBGiu`{_VGNFWY^5 zV{=y`3{b{57H)m(15$Yp6lsXr5y%$sm2Y_aYOU3d>=i)Id7XZ!4j71}y)@9t(w2ho{ta9&4E$zv_kf^q=BwsT)VmbhlG{4*ea|6Rop7wIm|D-AQBlt zkP}^7pX98&;DAdb!4@Xa^;)!GvlQteEU(O;w4b38lOKN*mPgXUY zmB~jXWo&q~iDzf6@PT%kE%BR8CKo3gX$0T9p6V#wBMiae_%q%`A$p&`E5}GZ_fTnM zhCkzirtz;jZ;ba`NpaC&lBMpawD>}^$-ny)&vXgvOuAsIc3JUW8I`XyyJr=uaqaXT zPU{_Op6?*_J-U!Sfu#>n=V$&7kG)sF>uU>TOvm!4R~GEJM-|anMI@(0dhG4BK2a5C zpm(jPbVqa-UQ<(-*bzS)Dr<6lmt$%~+_$o-+26OK@(UhRKxba%O6l zZ?;QQDoXQ#ZB^W>Ar+2)Un;pUujYZ+k>~l>*DV#;Qs@(TJ*yG#rtwf2UO3&|L3`$V zy~xAk?iv~&arLK9+FJwm%ub0(@u|@{Az7vcNl(jdZLQ9mYRy;{|Kz1?9{e zd!t?aP#_)p8Ow!}9l6b5kGr3Z0A(2#Jn>XybxMJKd*Vw6o6cWnjISQq?0blDR@r`p zjkk<}Mtq;7kBR>=Xyfg&`XYR9JU^}e zm2gx3f_$0R=ZzsuD0^M+onH=sov=35uJ5mG$bfVc6l4PSjQ|C&WX=W7mgCk$2OHd! zXYHpv=?_^^4pGI;>DPnKxMy9pLVB46>oH@Ui-2IcWoe%3-IN*CloG!LQW0I|C$X?R zcE_}WB>M&8M%XafsocXsN@TuRbtUEI%6b@6NJv!t@JC+gG5F*(j4q`KC?F4=A{43w{QbTOcb?cqN3sxU)J!PtoD`Y8`{^i0!SK~AhPP(2W5 z?=eh!acDP7i~9KTY+%f?TlV?XInOkw{=C!pI;a9nVepsTIG#hM@1FSY3fEHh;h(~D&@Q;HbMMZxEc*aN8Yv}tC6^LDaH9A; z*}GIKlj^hYa3vO~f};3!zt{kU-K5=ydjLy$UUcQ4Q+<8-DM)}CVy`YQpX|zAd|h0& zKw_Wm&&ZmTtmQdF9Jic9Nt_9VCJjNm#f{v;{#$6{0I_Sa=aA|I7lkpDykg+C_XcQp zt)({nJ31XI>Aa^Zx{(dL)OHIhyb^o)chnW2Z+ah+kooe5K@7H|E3RD7OU}OFWB~p3 zV5g#1M2vIL;o*!(;G0=gX__2ZaC-$3Tu;Yh zqOB_eDd0XMXO|7L-KcR9uWuhG;iJUempX1K<+odJs@=1oKBk);dlMOUYebU?^`8r; zCs%jf*{rEkLjU|f^Vt9IU-@qY{?ibU?5&TINovTzBHz3jKo-2i6-yPOtPc&%oXwAy z5-)8J{Nu}l!ojWP_4I{59nO9|Rb!`mGC<)l9{3@KpKD~6z3w#|aa+&9a@@Y2`mk-O z!kIhD03h3^Qq;|G8D<5vi@Nnm} znija~G^QVP%P1J7rv}8}ohSb8i^}P;+8mdBTj+;NyzO`pHCeldf&`hU-kR zKa58_C$?*`UDAT6&vdpRUbYACt2E67BO?p$^iZ{RSHdqjjt)$dddq+Fp*hKt8r14b zuDlDv1g3Yz?FwLOdo8 zDQr)>fphMea-rae{XMNraoeJu?P1=RZAU_nf9+m!wfUd5pSt2d0C9!Vg3Wlv}=Y_|kVvx)n#hyeRBF=di(~KB^s9e%CT;ZL+>A^IU%O^2VxPTXjzle`V*?DbC7& zYye*FT_``veD6Qk>PNnSk5>T@)0uP5fek`VAr{zJwBbra@#E#@_CpOTA}a*b{PT{<~HZ;B9z6lHgG;l7Z*^Y(FTyj#D&{O85anQ;kLJ10y!2_FV} zShI1*&KC2C+K8GzQ?zTBT|FQiEy2?KZbBsrnsHn%(2_g%3)4*s9ND=Tq4>7CIS~JW z6_-5j0`DOhCjUtz!Bz_kce#j!2X)2xZ0?kJxq8MWwY=C`e;NBI^`+IHc$ob|08o+T zhZF)zt@6lmMNmVo*O3v=xkNx!5eQ{6KR0*47M=_>V(xsax*LLAnvN5*%V=GNJiY#-EEnS-=C!hwnbLWcxMxgOXNUz*M z(HvaToba13NMVHJI(J3W=*ULO29KL=@M2!_pyA! z^{r({#In{N{JgZ~$BW+c4r&pm<)pd5ikoa>s7qC?x(?>JJp9l0QL1NFDsXzxkeFAq zj7yAEFM;^hM98{h?!zv-;2&0beLrbYhV1jw<+CpjsqUBNuT&M}#Ce-uleQ|1p$_B;cIYQH^4c2hpw<+F%-73nU2v0j zccgYfR;zQQeFyID_B_w9^~;PM3$}ISAJkZD%$g7~;lpvHBBx0qRgCBaK>VBN?6r zbBK67!0-?q8RT%SuV~4`wZFJ?h-{pOeH5jTJ<1%e7aMnJwBYX+r#Tpx9`ea`I~Eo{ z(9YY1eLn(YJ_*$NrN=ck%d{y!g%IXAz`F*BNu&YrFu>miL~_1wS*D#j|W4|0Wx*8y(x88bWeJuI-7vHk1h zM^^~1p^I(i_rv++uJ{j}2g^m5p0!1F33c-+Kv2(A;7uKU3ll?jHqJp(;Y!a3J%)^I z&iBP+y)C5clJtnNWlrW|f0du>wesap>LFo5?(@U~L}dY|=rHO^!G0$$;$om|Sx?9I z11A#h@=(OOn4bRMv!;(WY`1BD+?3aGF_1-E5VY2f07^u%x4C-)+pH~(x##_}EMvj6(JU)E@M(zA{TaDIwS5amQsx~M+$+byJ48q9#_<}ZGM0anL~n}Hnpw~;)hfXJ!AQJl@e5p^w(2W zoPn7K)($Ez3whgp%Wt{4lZF;%%y@J&GLB(v99c8z{*lAV`Me}(iDVVba^nXqpY>j$ zS9ag}DDgdbsrglC;@nutWtWOX=5G6mx>->z!=_*}9vQW#OjCG@sQBQ+R#0!}gVH^F z)EeBIoye?Rx@l6Onrz4yo#qC&ci&$4z-q>_!*tZlT zmQ@P&=%?OmGr6XNFYkRl)nJroXV%^7Ijm6LC@@AhXdGcSCaCsA{_-GcZ}gf%l+5zO z%)nqh{4#tZ_P5$83Iy#IG+nH^QyO|r3BA~^Wul55|7mO9q%9-6lT8`f4fTbQ!-q8F zr+xiGepAplQI-cpD2OwZIL%IQ{`Gh%*4DAi=*TdjfSQT7IsaT1Fs`n@OtGXu_R7M_ zwk95rPSydp3?H;4(IIPWa-y^?Aw&RL(-3lD10`q;$`~?KT%tE30U6G&F^}gnSaPP3 zyTJ}7K00|fT_VHdeXgN1G_pKI)vK6yy5=) zoikyk&pe^N3=O*hIEdOqmRJCY8itZ0`Mij6qwD?(jVD{Y9fj2LyZl2-#^B^XzgPMF z-@*95$f2Q#2ZA1Mt7=OSH;AtGJXs|@jr_@KwYv~F0jAP-Hq7*Xzo25Z&Aj-kg({P_ zQP>}nZC#b1?~h~$tVPkfL*9w#7<8MN1)Mr{^*{HH%mvPQ;f#FYKjZ~dyV0xfd%feK zlZQ5^QVUMF2{)wKeB1rkSHIB+J*+tT7?v=tIsg2x9~u~|Ia{~>`^5hjaQYn@z4Fff zQ|MnHd-g9_DxLaQtS|lxn6LgJ{x4AL{|)Bt-@fzw``iBdAAiDsy%Y6KxbeRKJsSS~ zsZv-H&d~lp|E~)F@xQ$^NEVkZNqgBbi9P@*^L26LX!?v)Nw;OF-LPW>hsLU{m-XYH z616t|dAl__)lHAHV}T#|E#C{2GhVU_=zuQFClg!E?sC8Di*SFxAs$dCXz<4@s46(> zV(3*smRY41LC#LAdJuvwRq1AuGt+IQ?#6IIzt*TV9Ynq50Jj!!$8dJ-2GE zme++TRRWM&^MFnPE1@|#37Wq+g?j?)e?Rrte*~59oW>FvFK7FtAqqpfVKBX{oUR%M z!0Qj;XI@!--nI8`$vUZ6yvicH4$d2w?4&gTq-z*AHuqlVc}HVG*$8ctgnS^~S`h}o z1uFlooh`4@98+xlk7vm}vthrQ1X1f z_AN69jrb+1<5|UHsRABPRI~H8Z3aFGuuXQwvQ```vda8G9D@gn&>OQ^ofC$ z0v;%-^yr_jB)R11YVF!t<*va@C3$&L*@~7@Ex_3F$-t&3|zLvxEF2tE^uOBvuP^mpa1@q z{+pxmO2|K3_mvQCQbGcw%J6i-=4>wfIS3VDUiPjk zuAD@d=8^05jQi{#rX*q8oZ`?3O`mTo56)E@Kw0sLE$_c4=(Uuf8X-Y^>LhR&B&a*) zCnvQ(-aBZu#A8rGg*$cEHu)oP4tXikjvL#<+I`rjjG~U;xsea>hJj zF%y%+2qD0Bzn=PRSgbbaW&VW#q-MVFxR6g)N~*A)0|B`BC{UFBjP2yQj^cLQu(0=a zAGx$?DUfmeLz=f&V8SH(dQ}cegYj*Zi59ve{b1HKIV??kuBLctyIXVg@=W@2bH#3i z+;0$nn`wjkp;t1-nblqDEHiKz@wAuIK@mp2*xM}9HrPRV2$NOEA-r6y4YJ;RwsAnEsmDaq&=$#^l z4-Q;QP8yC_BbGhRaD=bH;mvtTT|*6v1(oacH}vY6vJ9gvp!8_DLs;PmjDU1>6pcL$ zIA`HiG2gl4RZb{eWP@tlZ6Y9)(vipNo%pE4{9%tS{mSNg#)V~a+s9*lIoqz`nzZz> z0O^IsCJusD0mhV}ft^kK(p~;fgWHIq5qRYMkCpN_YjZ@!T7!{C6+=AT6VF3L)2@ME zYjR%h3{o!D`(~KbR^ITkz0Pn*_m?;oTHTw=k6bX@+jOeMtKK|)0Kvt?-21Vm{){9y zve9{h(Cc84ga2KAaRomm_RY$b$+c8gVMdN(mi`hG38CdDF~;q7XSOkzsD9Mq)b~~` zMquOgjC^}eIDx~JJ&uuY=*E`sg@OfUeqt(v1J>R;{k^kq(0_GeuqZQ-nk#l5=S>tN z9$wAYgo+b(@=EXrDt<;3sUd|ST73P-f4raikIagzMRCccd8>Kd2V@y!q)W4`A=-1k zR@nT@^zkbom_VUV&iqNsjX59T`IPB_j81il921B!%_=xLij(+Tke;!(eSRXJf6X(W z)tVK49U?OTNPy{c`K-p2$gL|+j zZHXhQix(MUkhk`ii~Gh%Lh6qsr7VXHQON~k>FpI!7>aP*Kn7#cZ?x zFFdv*l4((p>5*rmL%Bh~SH(q^WfL9dQhvqOZs%m?J9GJJK7m~0Y=Nq}NY_tftsX6b z#|W(QOVspAY4{w}m22=VS9KlK@s2fGVWid_kZlEY&C=^OreFwPxI&Pmra+nBKl&Kl zIhRg5-AJj}P%A?$mV}OlL|qW}4I^ zq~M6l03so{2NAm>`H#KeF{K)VdU-g}^WCh7#kmbA2ImB-RTL%%RLNUQ<#Wt=b^jN8 z=N;8#zV3U+v5bnkk=|!Q)6fPmAk}ds^ngGLoslXDMM5W(866cuGhpaN=}8DkARq|= z9Xg>%3muf+0@6EkbN0FG?0xQ@bN5;2oO{-}YwiECe#!f;_5+%#TzYdr z*%c)><-S3teSGz2SH&HCipQ4?xT7sP{~f!I2V!=U)XW#9qm$A(9TpT>fPc3n*YgUa z_`X8J+lVfA8EDeZfqtf=o1J&vYlGS0<$Y<$1HA@5gMu!6e?_czEEifUJf{sdDPm7| z@)VAp!0bI>+{Djr!unh*W}T5aAIo{5w|&$(qjj+S zW+&S|g=1aOQkNEGz0*ERzhERAFPPw{E3CmcDI494vK>HicCoVi>uIH;$AZTWAz4-_ z^_pu)*QG4`T4)=DFUG^j($zJkFkAu0W4Qgy;d6d+7oSL#Ew+OWJ4}?{(#D0yb7kWHDElRb$3mM zGt_AA_RlgpGbRl5hQ)VahP4p!!4d{;g37cT@?L`MIHt5BHmEX|?o6IH82LE`vu0GX z$!a|qvNA<}gIByFrg&NYHohi42G`OSO0TpoA)DDv`P^FH6L}XCldv8UyzA`jE_3wz z8B?D;=1_Ax*W>=csF>D?>EkIp=Onu^E>5 zr0W~o3|xB+T{R8@w>h}2m^&Lu zM~|{9I@V5q1ISV`IiODr6}IMODzB?jBq4T{E5HX^aFZa4+`Ie4Hw=s>=E)q%Cdsuu=Hjh^gvsZlm#>6bl0Rmfp^ZOa!T&abk`jSRb`oL)pZZWJPyHGnUl?gA=#sMBQK91pvyV=yH^ z7VC4tlx_0ouAt%mjnlD)^ZEoi%dwvkw1g^D>iZEVZa42HXW8hrn>nJfyTPqd2{mgY z`NsZz%VEZcqG+C3X$(blxLzj^H7K-;KSYJd;JHi45XC{YXo`Ey#;(&nc-K5-V?pBn z)kG8Ba~53ypz4@`T(Vt2>E~U^ox zK#rP_@;{J%+8EBT2~RO28{hsZ7Mix0?`lYcB8W>ov|0-Wr+sGw1QNLsD5qlX>W#IJ z`w}*)WmRjbuKpnmlMi+#Dh{=inzi0lr8GRrw33KRkV}n>PvBCBp2ljD<9S#UT`=)d zvyL(tQdV*0g#2A5*1Jwx;(|PgkS<@I{uUa3v!e^fmZ;t>PL1;Lq&f(^qQ2s@8+^!| zCFyb@KO|!f3v)U-wY5s&S*NSwgN|!@(CI-|7LhgzSn-P|pU*M_hpV|3*LtSP!1OTr zNaHfp(5@{x(QY;4M+?*^xtgC|96G(I5y{yz;cchlyM5l(*jt4`j<#d!$42toDb+G- zmiqVkHIiqF{oP)d?4)ydop@!=6c;OY(9Jy~DvTS>l6tAh5*SGc3Q-JDxddkzpr3JD zbj`;WIGRn#+<~T4s&v+_! zjMMiW?BvO)Q8Q5$O#?oF1&$<*n|f6?I~o-{!#1HweYat#@j;01Bz^Oq6Kij3H6X+8 zD<(hPeMvrWsbam>OkV5Zvz~!Sf{N@;Mp)k7ZooW%KEh_aX{fkJa(g@?RPugIMW-~W zD;O}G<8-O5LW7UTbTqPW1skNdo9zD#qKbMgCq$rVgxl{3{n~I*Q4tN1|0aoJbhp3T z4zsWyfbX%VXm1kxD&b}6X-?-tI>g_SpA*|!_K`S{tKKK#z+SBdk;XygRBcVk-cv;1rkYPyi>`)SI>{ks+Bm1bY5-CmxPFY-BUJJ5 z-PRkoJ_Gpq@67!Fink>*Zq7TaJQ|U-Xk+V?5UL#VPPd`p({qSNR*cVKY~$T_wir-z z|8GO2sG$B0tJ_zEhn2fc2S!AARE+qQ&hl65>WX4U*+F%9gu{`nD|?=_YcB(|U4LTl zCh-0M?xDZD3a5d$!iuWOj>Eg6`M>|E$ptm)R-(K;O=*$x#=oSN>*sk2V`CVo>bPiB zGgoE1NWei>A})wT)zdTI2L#ESZ9;=ZNy6JKNxdc>6X$*0@AR76!4L{+%rzhu6vm+_d^mBcwg8A zDCru-JJzdS0Ncy+j#BwaJ5lYtwwg+8NMEaE*`%iohiEc08W9`O?njL$*#`>2Vih!d z;3hMbuON;pk)uJY>#d#4vmMSZ8&!U#80CQ#sLN1t<~c~bXaiqgu$BDZnFHs1u6o-rZ%|*DKo11Nn%hTWvie}LF^sLk+5{na_ zJ!~B)x0DW+cIB>CBOV9DER1lyRc5-g*jIFPqekdn zwU@QGFu}Po1On8Xv{e5z#~Rd5AOLT1gPy`q{4HkgL*VM~XTIJMSNt{f;$%WR+%e3PC33~mKz5q#9saWOY!jSx z&xii0hRgr`cK-~nWWM$;uVcrL*B8ZJ zw9JU_x%dq%Yb+Hjgop^&-W3CQ9iccLaB$7)5@=2psvT!^#lEGyncK=}zUUGEU3rvs z3pHM!N+{5S0KPl?gP;5VVCbCV72PXaH*Y*qI-h&~;8lqHzEbCF<8SKt!v*FoK2?5d zQ2FI1;ET-{r*wlSJx`81&b^NP;PD~SP5d8+{Y^;DMR6i{>7Kx!1I6)36_|e@{lDY; z=Lr7riu=#;&Hr-*&prVEIlhU14*dV9!?=(Ck^KMTdids)bCvwJX7SeF+@}3MxcvVI zo|5-E#KCI~ySU_KnWE-aTK)_o74Mi;os~UDrV=?;gpAMwK{3#h?AO?(I9CQ_aJ9{* zRy4WQdwB1CBFesmtWTwl!T1QXWkarO-a4R9Xa|$U&0Ws)_b!DI1N&EMVl{YDs7^H zPNwt`qt8cJ|c51BEDA?D}dUMOS z_)Vxk{P2)wbs`mztUS!zbQcoSPU^tBg{y$dzYLjAj;$_5p`3nsy2JRGQ+&02iA$W9 zA`daY;2554H+E-JZ!M=UPj=eh@#m%RGOMB!-bu1Sb8!L{*<7r#>ifLaq*}`i3fr7= zwR-q+J0dr=h#`ZBYgY@qHQf|@+f!X(J+*QK7Qhb8WODhX$E>9vHANJin$G0d z=pmxkM|I2c2OWa@b%6N#9Oiu+ubM0f%0Vt`YP6pl;gpEGX3{5X>>>o&^M7C<*0EOe zb#J1-YrHzu008u@es@6J)thoj3v9?gB}6@#-V#hhtJ!Tsq3$ol@Cm)5E*%E}Ep*tCd39A>(dZmmVtEJ`ZN$m-i$?K_X1!wGLKtvV{1-@sYv6 z0<)2JSE7N|IH;RS3+C%B?U|l8CAs5&D!&riMA0E;;b1n^o}~Jvsp`6}g45(f{c>}c zEp=7yM&r%eZ(&$4W{_CIRu*9zmJk>y=JX4#%-*2~U5hJa%JTW5YU}P|L9a}1howki zV7E(XKD`2lwBvyA6(8J+_L@oYVN$)~j>$`CpvK04DmS9yTGok9j*gH^2NH%latTX^HuTUmkvRHj9T}BFQDSh%gM)pg*&`UmSLKIt zD_0y~0~0^x8mg?xlzusULQ$iNh~Sv>(b#&UUHThS(&F!DN**gL9&_$?Kx2X<@%QF*18xrmmsI`_m-8(c_>R5WNG7*1 zW1F#^vnA4-_+WIo>_v+^n)?GE$#4hrEm&VBXTAsrL$vcunp`wz#x0HwbM_)^jB?L) zxsHfjlJD`)pdlF+THXPnChTwT_@<5_ihb0K-Y62@nJG zYJtyc^LWfZSmJK8e71uUR1Mg>{i|TA*_?k-rp#V}DG~+IuN*}v9v>%T*SoGd}a8_(ow)t6%CrBDQt?<^~AS1Rabg=|9xO!_yx)0L#HJ#ma+q2w$wZc ztL3lkP!;bUSrto#sJ!u9Dc*LM`lSdbS~3S)tE29tD#+XM{h_rdqTv1rErrgw{&q18 zf0?y2^Amb(a`CJVT{PmZ-E>&sQucc(JH z+~X7MY4vAs$t>L5_t80p7!<6%=?*yND{iz|BI5TAmt4ELcS92Nz$kz|5lFXB-BcG( z+)6o2&aVg!kLSxr4%km!4=@Mmp?wARw?o0`;65;c5-W;hn98bQzi%7<(B8%EdF(HG4jd%mkU)?ULX{nxe~t`kUd>u_ZZ z-8MdGD@hoQ7<{qkg|Ts6jqjt^_&{U|lRNvCiD_|7!z*Mu+>X25tn!mJTwR$@e8}*G z8m`yJzD*!29z}+sbL_Z#gNh^cGE2Nd_FT)BM2fA$NSVU)us)3Zm_7>!!o#h} zrQ^meen}_mc88R50U&^=Kj7L8H>hu8)fh3#hJ5Tc))J$7KI@8YF^+9uDz!8R*nOVV zR3X0_5>rLtj>MIf{qV>>jrG~VxiZI|sNhIeUrbDkZ8Fi*sdammp` z$fBh5*_r`SBh)_aEOJ>KCSIYxdi}C=}$=}aJdd;bZ$upGECi_*DG6*3&YO+p#Cjaw| zyr7|-ByS6gpt^=%tWQ(ih9o2`ByY-^(UuX$ry?g0AKHXV>i1?T_9Gdv533SHJTOT+C@c%j)WmI0pn@lEn0g! zX1Hp3lH1CMSxMMTFYrcUo|th>9Tq7;s`(nA#qoy}ID^pbJ(!wr53 zE^1*sQ@b<9syWOsQNJR5pK8lqQX?>{(#7+;Olw!tTw4mcFqEz zCAYacR1#*z^kVK@qTAGzD zHMfto!Qb?=Y@Ej-WwqBG43`*nw-Yn?J7NJ;J`3(%dKl81hi14W4q7Q%DnBrPF%$8H zF~c?pdxm-pELD^ADutb-0)SB;OrJ_fz%_5nL7yHHH`HVz=kowjZEZ3ze+Mq#6b;(X zXK(+(%=wog?qN*+6N6TsB8+XBmp2p~mKO>jayEeY^rX)5<-~WpQg&4z%-@0+>WIic z`|gQbDpr&KE`5*(Ra2e>z|arM7jC^`+ARxxIniGJ-pI02ez*cH&^c+2kn+p7-BlcV zig%#)p(yJ$z?br{=Pq)o0j;&PGG+x=Or@3oX;$ zb}^eH6-iOcz{gR~=TD0K(F{Ja8Dtepnk%ey*#h+{Q+;NUBeg*S5U!m!{@-R3CSbAc zT}Qy!G9)n*%AT`m31F-cB802`^ zSlJtDp9&d#&pd09fZ<20j3z*#dFB3t_?bR7EOY~%=Qq>E9Z{f&ZxA|0EwL;W_dc%| zmm3&1%_8SYz`+s#Cfs2kEhjn<1|WK?#Z);2IY~o+-U99q$xE$ckvDStZi^&V5BDa) zT{7mC?Z!qp1U4UwLy<%Blw4drZW2mRLg}$D{|ky`FOpMMl|jRYJML(2rxkv&%OG7X zeXXc3a_h@O1}5T5pYq`o)gj{wlV9>sd;wG5HdOz*-ns}T1I36=Uo`C-hHA$4HW=-Q zdo0Jscp*L+o9O5mEf3F(K4j#VNF@Ih>l?t3r;mey&qy` zwBOUmGw+n-KY_-!_>zI`JOyZwFzd@MUM+L9=2NEN#JJQTw1)Z_TgCmsQ3lNAt*>%t zG#(`!Q=q4}8l8LgM~1+Iw&SO^Rm0={Y+9^*$mwXu#6e}E`zEp`yrv;2jy^IPa$HQD zl_`fSou^3kcgBIywN{ByQEpDkR(Dm4nI~%Rn^V6tzUh`?7dXOe{$&=!aqLN8uM*cO zduCHuL0($sb>BaAX1D?yExJFIr?`WJ*GFKJxQN4%TXruWp2*%Gaw%RJjPTLlaut^g zWzZ&j>7zwB%;{P7V7YsC$n=I=C7{Nh`XL%yhCW?uKN^4X{3no5X?7iI3}}h9y;**?p^-PiJv%53u5vH}?1u zdFN}%9#w(MeMTA}ibAF*4<1pU@4<(t<+gxn$p)-15I%QwDLU@(y^%sW@}{Wk>aTf| zk|}_)D=k!W5Z}KbwEJ{Y@V-`>ri|f*0*jjAiM-u$KaP(m;@5;#K1iGWfqdfWJ zIcG^LBkI;_Oci*ts;H$fO%dUSO>Wk{zBU2~(B;J3d}1FJABxR5DLZ>D|gxN{ta#A07=p zGHwu4+z}PKFP}ObYea5kx*PjhZ|v?FciWAD3Xmkx=sG+`)^!9KCSCe%FQQ|%AY;Nv zc`!3la0VaeO%3ot4YsrIHiD7GeC+0^t4EcOQ>So6OK#7;OVMzBt`9mMYfpfe3wWw! z*KOy%v+({IB&3a}383-`O@}u++W1|w!=e5|MkV`876NvThP2U@nh@oQA3C2SkuX;3 ziyI7LLUqntB1fC;JN@#?`Z0uTt1YXSN2*Kx{eWZpSTXL2hNoVYd-_{7_nyOUGst@5 zOqmwD-j2=Sj?mm4?ljO5`qoGHTsGe(2o5jTJ%r@RR*a$QPkJxe+V1s-Ts4QxIi z&R!OU1;m<7mDX@P*1M-CfWFMyYWb$7fdW%g`#-3vU3CoF>5TBOCYg!+sad2j-SusS zAId7sCxcy9vrxdEzaMp143(C#@%})nej5x9=6i<4mMnxG9RV;$$5*&jKW2-(_N2X# z#I^iz#Je~^{aQHFNI_GBBbO>^I}qPSB$mWXXc6KV_q5RMumP7Zc3Qx8fc4mzT>ipH z7N&yRLc?32E3kl@N9Trn%D0|3XDMj+2>mtP0*GO_hspUGlU7twUS89bj@Hx(UQI~I z2h0B#*iVQY~i_6VX0<0c|H>z+ui$GCV^PlysJs2bjw_OZzDIvlhs^>$03bol-65H!PVsib_mKA}*5Ws;cb^Z~RX zN=d!??hN)1=JtR2(EF}|lwC#STa9>|cNNP!Q1h$yS;vgyP}Bw}bR3kvuG_7tX&x{z zp|AIrI1rDe8>k!7w;XD!kAflm-(QH?UZ{=s(J9q$j;^_!1A!9dB5~as*3a<>veMm%SEiP)!Nbh#)NOztoo-y{BJ`{_v3)R5@O2@$qM}-G%s01r zMuNX4c4Q2@Vr~E+$_6;LW!mnzMf!A&U7cp>56k5dl`400)*Dd;zn}SZ-}RDe*sG6j zKsTArR_#DfyW$(5hY2X(*r&VnFe;}%IlPL6YRi2NvL$3XKD zn-(e)#c(W(&wWlE;h_Kk0O2sPoAdVRsjuCzW#MaHQ- z{?Wh|iqAqP$8gqx%?(;tPkU6>7$1{vG^SHErC#I2*XJ!f;2@J6ZWT89vYT_JWxWUg zw;J^M&}}q&K{}_)){2FA{M^7UO!J#TnxpbQa?*qyJV%|Zj<)`RPuuLe?EOLQ+pVgL zha@u!)xKU8whHs_H);;4Z0DO8#3X4I7bfebT3+7y{2XEJA!6B<)JBGat?}Hr@(5xL zvO#=>{)5u(9peNn*-K}U5vJENEt$~BozSY{p%99P!TNN9Mw>V+!PdurVI&lulO~F#ZTj&|G(}{Psvi zcg#Ary>o34A(`qqaoBgDSar|ot4M0vh{MflsvXaGIk0w8D#Ejj7 zep&rhm$Y2P0JF?n!H$$z!2=`ku*OE;f^4Jbyds73=;3ryO(CmS%|k6a+F$5Ouax-) z2`p;rKS=lI2k)ku6gYZLsIRYjpGl`=#3_haI5tEc$u;UUTqW@Zm&PNN`M6;nEMjd? z{p@OV&Wz7jGTuM@&59+g_@)?F>r6)t5s;U9QZX|dr?Ed9F z)6t4Zk={A^M%C3;=a3qn;U*O9P6bmyT5ohopeE44+vI_~o5Ky~(R9K@^=fdLg3tHX z0e#f0s#!Bf@tSoGn7U!sQfA7x;E}>20u@p^Q&SAW8UYZWbG~Aa9e@!9W=AviE6B4l zMW52%6%~nEwr?j*U~27hGc@aZV%kM4xZ`IB4P=wba1kpT-=nQfz8`Y6ewOs8Aab?U zU-oWw6S&`Y$B2(Wg{;`=^}3#;LRH?$$Ir#ITM6dwx<0=%p|x{wkwkb1b@mP*tT`9+ z>RCxD#k4yn@#V<-=zn8BUudV~FC+;g&qy*-WpAUkYQ#Jz@Vu2zwxn;rs(|MQi78rp zr}RA=pPYmF7eV!@?G3l}OJk@Gd-pG2OUo%k7q+2Uv(J)D&&aaM#DI@z<;Lc{uv_r z$ANzw9CSqAaT})s{TDRx^^GTgg(m)N{IAf&uWtS;rtyE=f$e)HTi^aO@b{1D@PA$_ zvqyyoFaJzW{ay$vm5H(Fjiv?#daRfiK%RD6f|Fm=x=o?Z` z@<^qW;xhD$2Gv+Al%;SwQn}7|W{F#O)eZ0FbloOxH@K4j*jCqX{ zj}Hr_!UQPAjB5hD8l|lTTnX1NDI(+y7UR5@Qd7t;4CIqHt#8Cko4NLyL># zcY@5X4Dv0xZC)!)>#@O_FYyXpQMPu$wHND^?1I<^>In_ePKLEFMhS!U4c_n6SceK< zlg;@SR?CT@71JhTSPD=du#o0h&`)ANySOG_L$Vp)rl6UFzP{)Z(MD(ZNHHek&U{Je3LlhcNm)8L0-A4p0g(rfOwPml7 zA7*)cJR|7!@0q5ck@4=k=fR3@rPYi;98Qw6eZXLHcC-ORHgq^Es_*G0>!%Le_D?ET zEDI`{6aA%2D*z#-bE-8;x;{rYvm#Q;54#6jlx{vpXSBGB-PcKb^K-L#5_7~G`2ZlF zRLd7g)iZ0u66w&@XxCBdRa>-e_VG{g*gXwlB1gnUi+Flze0CBq&76Ik-cE_oN=g)h zKV{{GQ0-gV7EcI;1LM^bBn#n$p{liILTjE@$)mm|T8k0W>=8;j9cehP8>AX;5u(4~ zi_Cxk*_hB2ztd{}DCATy%@koVqkVQ*K~hQ0K2_8lmg4rQ3YFAKIkFvcyDR8Z z(&X-~5FU{(25g?GkSdollE)0)8D#6>82zI@{j}hSXziCtf|UGs4~RqQQA>JWqh zM2z?lB`rE8_xe;7x2mdmRCyrBy?QXjD+OG|aV(rq&i!@ao}^^%lch=C1f&WCvrjzg zTI$L;+XT^GLuK=J8tZhDshr?cSc25eqvwp8s5Q&rsm(sQd3N{`2>q*UyA(u`gQ`kuF^`(9KM65NLB1=Z2L-WcK9 zJ)9T!M%pNM`jwD*v(E9f^iJ1OESwtDagc5UiN1w<-44eNb+5$fXQCe=E$bKsHS_RE^PZet#*zl$I0ac-zJCEm$+-YxOF zw3a!F->92OCjmao6!pzsix;l|f`kV#FqqCOvq?5biRV|9Z8ELq@j-g&hvZI4sn*V6 z2hoHKh|%ZTQiJ^TiHY&GPAGIQPdTPTvZcNfwrAAgB9wc*%C;4^+^MDoScbD1mCC)< z2(?QRyuh9Q8%Dx|u1GpW60hAGv1pLGd<_4NW%ccNfmbPZ$=wIoKaB)v+ zidgR#O_RTD$2j&;y=ikCFG45JZXEZwkVu7qM^lNe_oD_Bk|jNgHIXe7GkJFP(e-{m z#yiUGYl7nirlV)M;~?P-=aWkvw{5tX%at_+g6pc@KzZyM=MhNqklN74)`q)?$XC+=)*`riE={4&s*E_c2Joe%~R zEh~?!e3D)eZVY)`j|ea`3T*%;4)&36%>3MPC5 z6+f4_`1R*!XQ$&`GA`zwzG*ARv!TDA+3^laoi4FSz)!7z-|5EME2K=Yto2$x)-m~| zpC9oXcRtVRGm+%!TH>)TpU!3!`p}D;)!(%`kdyMycc`j_RaQtP=qvViIZ59dLH0$N zDOY{rL9{p!Vxxp)pSi_+ksBR|uK-YCwq)d{L9v7zpBR%0mnUZ#fIpQ5j1}cdpQ~P0 zd(urYh!9@VHnQL-ZVHn(xZ4KUtFog%4w%~e+Qe_0WD+KEifvcTjn$-2?Dt zBcMH}_XNTmMFekxVXFhHF(bF5yH|EEcFW!$9Y7yD4mMDMcvv@x%v1`h-|I4U{<)lgMoCqkWKVb zZ+P!=OpR~EUZwjLRZnh+qg?UhchB&Ccftet((7Dp2WqEw{AWRo~2&-}pzC>$3I`Kcn6e^UKQTrsDF>Rt}N zGg(sa+0HFcTXV+t=YLm7&#A54Ltnh-^G)%yQCI?8GK1z&)QbttyY>B9k-*orwzj*U zv0*<%??9`h zd%IU9KUp?9FHTgT6V&ji6c{}8^Dm`IFxcoOT4rLZ!C(7tL5@HF%C8+#e{-&c#MH*Q zi9U6PS@#VF8OOo4hNK*LtXq036ApEofqfr8;SQ^Cpk6-_ED#2w7IPv#0{B@?kkX@D5*~;9v2iF+=(*@AOsH-N@GC$@>ia8!*=OWTb%1QJj z_E?zA5Nctnw(9I0P>}!oVY<*AG+eo=ul>QKb)N7nL{U6%01{c{KfO`(TIf@S(Y>>tQwahm)rY!i(!6WSr(ywxzu+Jol)vP=lkIBq{MH_NXE?8bm0cA6QWPYQjd1+ znz=(H!?Vh!0+p`tqEy|jhbdGds{xDFa{%TkeF(@+60BB+7G+?>%Xx!kVjcz-=?~zA z31l?KYUvX`(t*wEjnri)w10)_6OTCp{dEWa)D)6hm=4=7}#Zy z@|O@^;0L%EsqT)8zB+2XFG$i|PQ3GJIpvxDWbo+QmsBao(KWVjTP41$04xVTB+hnn z^y@k^T`-tz(R%Cnoq54KyXe~M6T+{gi5U{a@eOYODF6Zou487%z7fBl3EdS9ERf>@HDDVBW;WlVYLx{Z z4UUEa@)YanLNHPz{K7rko1dTGo^G2#g2?7i073Uuc|JzxY`^{*_;0U$yxJ)c`M@IS zT|fg@AiKU!K2QT!Hg0ZU#7yJ^J8JgrB7tQ%1mZW1pRjJuUA$;HJ{WO6ZvzGfL-&JV z=Hq!XF|1p5@1ce8*#k}3=T_(0XSm9ayVj0&M)tW0z1$9L#i1}ZJ zUS^jXTceFsCBKhSYB9$X;+jUO`f}LeOpA|HTqGGgpQpnfsxDj2POfd>%-o@31>^lg zKWHXOO8yzyWjDit%40G%?FuEI*IX^P{O0v9*_ooI`qcW7G7^~&Cs z?fuxoHduvjLBfVOX<|Gr!8s4G#4SpP1^cu`eyP+IZ3-3Hn8`Upcq42iBu?@!R5m&6 zV;O1j&a%9Edb6?A(X}0UWlob?eB!5BOejde%v{>M=@-8$_y8*f?`xBtBTCtaEJ%jG zs|}=@wU0!eizCX-?Ayd|NuAXG%_N@Lr z;84lhgFK){U2i~a`#1ulw`qP?Wx#o6W4q!lO+HX_2jE{T_iaoC6){s_uG{9ub89|R z8H@efTEKY^vY!$9n{|eAU+a&zT&F``b&$kEju|p}+Zjz|a zFJ~Rzbu;~W=1`_3tZuO&#wl=ogb-8?IWnFb8zfCwsE<#%c@8fd`!(xaw=k6Ps#AH; z?5x2^mBHhfYokhm=2BbgP``nSQ>79sGNL*7mbPF{y)pvFwbTi*vdZ?_sa!@ZOo=f&J8 z#s~5P8>`@A&u}n8me)zGILfsmzG-grxH1K%d@b)XM9Iint}md`vwFOJ;EE(lqk?)v zU6ri{p+72N&;bYGTCb)|bV5=O1qeLF#qBO@pEoTmGlCj^g9Ym-T~r>Mra9?EPPg#* zi3hH5A81Uwlr4LFVV{{x+|CSAGR6foe6+cAb6){f=!Veb$XCV8_@>mI19R^59~G{Y zYGR9x1Lite`Wmw&m~gr4RdCoQ8gv_5lH+3@Dk~Hnv!UFf(kJrLf8h|`Sb3EnJlwe~ zot}ABc*V#P)iDd6yAsS+H(97UR<9Z-ESVQ)_OU91l6K7DZ>dsmoUidGMcqz(e%e0!#Q0Z+~wtKDfgjUrLDh}*?G#Ti|yJijbsG-P#)-~(LABA;4t_qo>eTR*f-@nnW7!(bh;>>#sI zX6Fv*K(qg%Ik%);w8>gwkmEP&;!c+hLcCz+GLOxSb9QFd(89Bs<*8$nJUPHqPP_RR z(fM^a*jEde;Kg3mzboMe^vRY=FN>;d@9$VFaD|M$%Tv16RtAGYhrrUFJkvF$txp&K zZX>9{LpMVyTeeG)e)$DP2a7}<;j`egP+#wRX?QvJzN;$#+Rjz4os7!iLZ3T!%Wq39 zsQlkdmJGlUO2JBjuv2lPt#U;LK}-0~{V%%?Jbi_5m5a0i!fbSFMGr2BY$o5g$1%~e z;%msz8y&qCmEAr2&@9&nC6lcTA5@1RXY9l?J%tAiHH;Hntms2D?~o+{%KF`}1``vn zJ_)vLmbMf4gkyTH8s;IC`6l~->;!+|ay=*uXBAOp(~`&0(ZRhk%Us*DzxVXlwi<=l z^2nR=_juV0BC<%(^2CuM6zl*f!gFJmtRBS?$KM5DPhj* z)&V-5YAUuHw&@$SWp5Wi(eYs#K_wh)^ov{sW^qq7cR5^Nzx16Qbh*zqfrL*ma(TvF zkoQ97JI;YmS;-^jx}(dlD^$5H7`J2q?hBt+d?XBdovfzciiy8t4!d=I^0LO+X|_>k zy~?ICKw?#WGF3T|5%lBQ#e9Oob`AVNMHG+paSJ3hT@J2qP=F>?XTfY4M*#H6g5QNB z`?5Wj>^hghb-}5YyDAGB^$FcteGb+v?hS!OwbptoMt9fuY_O+>yGA znlE~FWfY%xf2OHq39f|RekOjfYP_rT0-&KrEQ7L{?K%sP3mQeF2;a2<7jCt=$fO7% zo8_FGrFSS3Bj1NL-sG_|D-=m5 zn7G^az|}dVWXA%4jX=hHSuOUyKsU`>X*uy->+wj)v2c0;?AZ>s+2J#FH<87BebLfc zNjgKmbR;Ezq=-#H@9q*aM|~-tAV!h7`St}fmH`1hfkH{B-3M6>h+WVqHw46DWqO_1 zz_R2$R9Em=(OG|psjnj$y~5KV@axM`XfgLVfjqcOeGO6Nl`T{hsBytE6j%8Tq zKmR5pF5#~smaj%lyRCFQA~(LgTAeXWz%_UtNS_f5_@u`HHt%$ zOtcfd@ZuHK>a}tDM58LC2Dg3p(HfoYe+H`JpdQ&Ry-)1xFE_?QlX*{c`qT_zVuXl} zK{!<>=Mbh$agYrr*d=G`Qg4k^m<*6q3KHJ7S!Eba%Vn|9urSq;=?wkQvLnZ@LW@b- z70?3nzM-&;WB;93yh4t`XsGeFe8;*7M?+?OVZ$XO!x;clpQpp5-}EX!Sb3z%x9SjR zP0&2&dZ49xw+WHAXTY$qA@9Oi+q5b4?3FI%{@}<3c~j_m@!NmvpYLpKZnLX^R$|v@ z%hDRT`wBL4qxfDG>l||M7|NcE)`%vomi5B4LU9k@j+pvOnn9)Pb~$(l!vA!PPk1;| z8zwkGx6_050T-*j3WFavo9WEmR>SHhn^0FIW{xoY)0{ zSkNGrF;*-wHdJh}i@kT9m-GEy|MOq#taa8o>pY)f!REf%*S+_(uj}_C8(qQ8@be{3 z6A7w+{*_ULv5a?|+F$vfpOx}}PJB2CT-kd2$>&t5XL6(@I1p@oO_}e!$vb|bu~kzo zNH-yx6dv;p$G(&>>QLU*t_CwQ$yaF!(KzLGpOY8kx8=VE;dA>3?V;SgcKBsQfR6!p zLDE8a0-YHShYx_E5yqP31e1?K~*}JRn*lg1n&N?$9CmMX8!1sQi$VqzF@AraV3~CusLR;-jvaBV(wkx z8;fE_>A|{MX=6A?&h5?y|9$UnrGXbluHmb8g9W5|WG^YdLSVJIGYRVpV@-Efe3>Ty zc&E&_r~9XvQ1TEu-}NZXo!}n8Nisf4v~@?X1LPD)G-fwWyfNrqeXlv2Z|cey3%Qk< zh)Ph_A^-r6C6)0^VYMHB568Sp^T0vkg^%+qWH2`|@b<*Hw$rugXW5p(hKxF&uC6&n zdltJPiFw=meT*qgmRbew+(&IzaZ1Zt<~HSbChYbOJr(KZ6C2?DqTF=ow#m$TuUkfx z>_>k?2s0wpaXM;h;b;FznECM4Drvh}7g1BEA7PoB(Lz99iZRx906-;#Zdy!yDtqM~ z#u50-;}!YImHjx6M8~m0)P@2uUn)&tKr{5fXdrk;Nb9jrrF2R-f1#jkx}a0RoJl(z zlrus{=A;SWGzA)w<{*J#=4;I-xSt;*%{(LeYwXH@F+C_iGy<2T0(-ep10{r0)uzhT#w6#AY;Z1tL#2idb5=)gK5)3_!#Z`pbgiOaNn*FY`FjX<0EJ^6^JOT^)i*rhFjNDSc6RI?L{rqWSd7{|Vuso0 z!4w}0>Um1ZCJr+?d1p!;JBFy$DN1mfn#mod`*-|s6sFlWuf)SAO`Pi_3W%aqhGrSA zH&rc?>YxHs7AkV@iW0DD6Dd+@^}|xHcD69<+IS_w3s9k6q)PJEfKla;YtPE5t?dB^ zPa+~6QPeZ~bU3)dU{HAh3q=~w6&22hLP#%C`6nrw^X*%F>{AO zFaP&)I#a9=Ju&1~Xmqq?Oy@^1&&-OH!aY`eY<|u1mN&cW58|6r2$MqSPB@k(p+H&W zaqsFgQ`r@gnVRkg6OJgcVFd7Cwb?YS&P0xhif^30s91l7z|q9KT#c< zjFr0w8WRZFkS~gQdZn)cP_yck9QpPm{Y;{%4FbeP&^uD3=pDGj)e8Sr>Y-rjAY{W^ z5UmnUPx$lgxYMw5f_u6cNPLO670?teoj2w-9F(q;R%?=b@8$1LoUW?1D%-hlmb10W zlN^vkhzsWPc4~iQB9N=TxqezTSW_OF7-dEl_~?e;QHVx)puC;iOaRKxxfxYVw4+S? zrK6qO(UjWd1IHjX+%#}6t&=%^ILX9PKW?IzsBL(j!&O-O(082G{03idMNzS5|GlKE zK^EQEu!Yc~UqRfB#`=%#An+$d`hOE*`>MbPq;S*3O$QTeih- zc0NX~sTH}i?rzc7UForXQ3nkfO|!0jgZ}Kal)aU~R#x-2DPhRSjk6vyJB+Eu4-Fh1 zuHVhxJA|(|_Z;~1L`Z9RZ4o0^<0?Qy1)#kWNCM?43=XKjlX_TO zJKp(9%dhpJ_)z7o_@5|gReds1z65EkCI=%uS7bOh8JL@qkx5bF(R0}s&s|sCD{{;$ zoXWc@8Z~m|NGyQm5?wrtK>nn=V`ynkBA=M9ei(Z!TSLSh@_TIC`8xZSN3v}*p9O^p zY#o&@0`u4TQ@lHw1BaHY)z;U4R;kn~Gv0L#l2aenvDd6ola3JY0BDltk*f{)`Kw>; zNh6WbX1amXR^#9NbII0$GPvC<{f7QN6Z-O!mQg@xSTRAAIB*tn#JffO=Iwg+)1DkeW?g!>Tw3ftoIGr&)*wc;#OC8_ z{7TwP6gUBzXZf^SZ{)FnrdE?}%MBRkJTL07l6wfQUDXaZ7hbZsEPOmI{h~E_`W_}+ zSs-Y`D0t*h_y9aWEe}uZ00B$7{1eRL0atLUVJavfEcSuO`JlZY*LL7P5hm z9w@ z8I5r$2lvHD-tIG|2hNXY;AIcu8n`-d`n)Vo2FGQC=Qeu9>^t*Za$&COsQ4Ov)B=n{ z?bntis2VvHNq3Z6&po;^&c}K-{;^}swFZv09V|35f`B!pn1?W6Xb~+xisB zeVqjFJMLQWBabqAlWdLbc=W{wEv-;L6(PH~n81XWs)^#8;E|1;^Y&+t$XWK>(*LS~ z?Y|Cn|F67y#VPwh>Nw+=XYrbtu8{0$>h!~mCNH|o^YXy~QLWLB{<(CY(d4S18BKWb zjY97!-&yw=4+If=;c;R3*LSt*YbLu&J7WL&jQ?DZ|NKAxGhhCD@gwekvdsK{CHDU3 zcmC%J{I{+^n9U&kmwjC;v*V)|$31jZ_4}CUZ*E$vsg-=!ANdv$#zc?LhL`WIC%B8y z229Gf(^FqKwP^`me77tG$(rf)@}K0_H`d6TvspNN_0J{!5&xED?{gSpnNB4t3U6xO?S3r6xB^^sD4i*))_qc*$c7+5A_6SAnPQ#Tb2)m3gTng(}RaWOrY8B{+v0cX9u>3xvzCJD;C7`aB1oGb8auy|#ecjAu?(ux*IP?<2f-bqy!-_Z;2b(^y*j=A9!_4DF1VvN55ksDCag2)^?` z{=TOi4zg_7mvN4Pi6HK$n4v0qAq+${idi3JTIYg4G|1VSRbHhMsSSm@@ZiRz$-#@% zI_=U&K0IvTn{NN}OtHBXMf4V`p%mZrGUQPmnO5ggB>$)pr*zxtdrPw)m3MUcXDP10 z{HWa?2^RqrV{Y~2tOf*~%9O*X znGBS)m1E1Iot~5F_!>PWI2;JzF~F4~0qLQkZ4u`pN%FmC4VbZU#c%^IDpDP;?*<%d zbxduJX?aGN$eXUci(=??9hZFUUeT-iJ8)5!Xa$ZQE*-Zkd=&afKZ_hD=ShcY%bvbp z@?-Qg4~`on<%l{}^^|b&(}8yC)hF`YaL9KYLD;xxjbzX-;;W z3NvYC)1(N~H)MF0+!%r+`!=U+%9Ny6Q{K#C*dj77I4oCt&(Ep9QLFV)Yg%J`mZuY; zi!z&{j_3VhELXCPrUN41whi<|r74x9Q3UF!Xy;`QjI5>;Oh7Gu%;tIS+Yygsa75&f z8VuXM7B=Fw7+1ZZ(*Cp->C|^|M@j^uGwRHL5uFX9-6|VZA*R-;fBQCA zTQ2t{C=sdTCVZ@+)ZEoh0!Lr9am!n^B>w#jwXl<^G1tz)J`&?o9#k{3g+X2z9Rdz@ zN|ra6n6JA6#o6y&i6M+iiy}@ zA^zppg_t>iIvElD+n8Kj>`3=#fdB@xcd}ooiI96@Vq3oP2UjPB{Rj7Yy_yBO#fooz zE2Jp6rmXRVKSo*qR%w!~jihjG0MB#YwvQC4-D02n32J{LT<{kR#m17duySqsm*q+W zj;J{ul!=9-hjvB-dhihJnJCfErJ2w6(=z;5$-ymVQDefs%s|ufo~ughZ1#M@PB6XU za7QDrq!#XCF$w%!3NLwD_!J(tb&8%1i{8Q@_6t-JtoTz@Ybv_jUiE1WX{(zBO+)qr z*#PcZwl51&dMx&pB}x~nIj~iHb65S(h0mN<4fUffLkg1 zUVBz20z=&8-Q{TBNJ8TFtZpCaq-H36U$ft&x1_&(cQ23_qojyle)T!j=7^{->A0MrYJf$j+?H>wpluI_ct{w2Nc2K->VGUKUKG?)r`K+@2@!5-ebyj+(2Ygzay14 z{hpsU&}0aYG=>Zba8{rC5H6^ey&);gu>(ClHZw#+M*3r3!L`S}p~P<%vgnMk7vt(3 zTMKW%p-#8sLGXFxlb!bl-INLC?ON5`MJ@h-XCK)JOW zNaF>X27%nZ*$)~;ERW4*J3QLDVKTRxBL&rFz;s!3o!yhiLBTi4{^wwQD|fe#oxYu8 ze7s}_zO>hu%4>1nEEyH=Y?0|EHtB!Yjz3;a2|za?i6#Qe~+mZJFlG zUEFhZtq+8Uf0_&3nyJ}d=%`iLIg8Spi_jA{;TQSm(y)u!=F_884Xcasla7GW@F(wo ztKzy9`ncB-+4>K^F{E#=(WC|1Rk1Iss~-OzJZntHZG;%QfCuTAUZG1{IHj?qL0)|j*8pI z6r2Hx-;%bsK89|N+|i}e6oQr4izTAX#B2A?(cyUINcaf-Yh=vUw33%|SlGeztZ7G< za?<8H_ZThDz-De?Tm$%Y6A8oa8|6|1=j!(RUt_S3$+4#5n%UsNJ1&2C8 zy9AXX$(d1;77&ceDG|)C9Y^FJ_?^{Yd2MGF+1PDo34 zEkNn?wU!Xoy#_@6fUkc6)PEhX)t=#Hc1&k zSXesw1gck1-P7NPsE(|Pl>m6$Dj~ooO9<)M@jA)DHl!8a`)Jl9NkwH+1>^YJojYIu zTWh}m{crkL{_Dc6H~Y?$77_}c#mS!{^90Vv3;jOs%*_uS;u4qnz~%fx!^ookk2erD zUZpE@nfE+DfjmB>=!WnXE3jF7o#k@&*^pbE%H^aLT%>{J>(}q9lg!FP2b83-`Ls&v zEYWQK)t`ckdehRSc}=}mEBeN{_lLs1MfN=VDQmoOqMWb|8kya=V`*_j?cr*HN~F1e za+hX7iV{NJF6OcEr>5&W3l}wqN9jK)qL}#j#(jxKyp~KF_wSy&J|1Rv&qMown)m89 zmZWMnEAzbJj%yY}_Y%VOOR)p)J4c>Y;Rw)z*@Bk>0N^V+Z?qP-q4;Zn6&^b`kmX(H zc3s_)diAKT$$%VsLUw42o5n%H6i+w%BG0;(h9wOmMfRe<@X25VWNpnBOvnTQe#{aJ z$_KBcGLMD+)+}iYb8B|!*;BIg^l@Eexz&67`=U|W9fZao!B86(tErNRQ_s|i)F~42 zb|)L43d>5`RQP(aQ4flLk?#4NVrYoIVJXz_Wi*2&xciSjC}8k2+7ElBV>@tZqDw$P z3A5G>eSYijXp4-pa|2#GG#XhoXSUGtdUT;-hNdqFt9Tk8c)BOPTPhbCKWrzH(=F_H^AOZ1BzBCrWAfV+2nj zSRhvjG1S=`*e<62(o+)jL|bFIpW$LZLZmd+zhOLJ@DtFTvl2z&-*%CmD2*l80%c_7Fi%J^ zR)(L)FvR}3^v&MQUiILdkHa=*SzI4Q^rZ<|14*%M$Xt81`Eu5jz6bxy{Cv6Q@BH>W zuN_(#45pU`v^+^fgN_Dd3FMkn(+xyZ*t08)Gm6QKOH=>ot=Eu|zY*h$eL(G$)jEa*YYMrKz{P)&_jn6wEs+l_ z3Q_70z18sxw0Hh_=$QF~R+@UERH#3e(b%OaS_gw|;3HP1;!bG5$>2&Wl zqqK43sVySvo>9V&3n&5g6CG~IRLexLQm{W?hk)EkYZD1A04t+92B*Q-eY#f~;zuv)uDNWF9m9>B~MkBqQzh(SUx|I%0kaC>P|SAozo3@y2I+Qjv9X!A3@Y z4-@2?mC()Wv7iJF=*n)8=a+aUNSd$kx&CrTL0vSU`>0%;&&hQ?#Y{SdEHpcWOXG{a zyW#wILa~;aM(h4>|Lefs|NXJ{|Aue8t!GoF{Bb;rtds6pooG@g8YEkN#A!4?XdU4d z$#4-AZcxL+j}I@BJrb!aH>w!?@;!w+j&2#_c8t}pO~?p4X;;88PV4ZYtAZ>_-HneA?q!|IZ~eVb+JAf2m)ZS#lW}50syqGny11oo+l?r_CB%^*#|b7utbO z%4py8#y)7XYZf2S9Hg(g(%g+qs-n;=ro17x^(<;vGMU74CbWh{=EJ%2%>uD#md;b6 zpM|(zxKv(8A3ls)J8dj0sdUX@WPmAy8mK-=35|`brSrjT%o`dCkHonjH9b}=@pC zevr$LtfGA@r^`TQ2Xlz`=t~WDkJ=4Nse85#@@Yr2wefV_w-gXLd_?F;Lim=g-RAR6 zFN;YV7EI7sz3E|IbKi91W{9-un7={J^inacf$thLrmrx|hs#{?5u ze=4k(ESG!KlZY0S{qVNZ4%H^T=^$;-`R9^{_ySLTgYd<1`Eg+48<||G0xS-u@GLWx zG*oiaPIDUgln2$x$w{8QSQQ21>w{RTrKPbs`P#(|cAjCLxY=_dr<&DY%4Epw`xHm% z`Qzen*i;qo4#%mBXa9z`plzr$c)Kq^$PVSQC5qcRbgJ5ab z?bJ_cbpgS-M-1Hzxd!creJ9}&t$Ohl{d?yR*Eqzmf`~U-(vhL;Fiq1T!a6#a+KF#O z;hBa5UHur?ra)%LLUEIzR<~EA2%G*V3MeIQXk@o;V?ilN=dJ3LhL6e(%8MT}OvfAq z26`r7C9Ok-99rz?Fp1ZbiV(0eW|LW(E^T+y;cUECq`=bu5vUoEhCG?)?jcAilZT4inn<@b^I54Mp#coa!RUgD(a74n;3=xV4 zs3WxjAw(h#qh~Xr4*c(5Ik%q@NF*{%fmBAd&n(?MY}eaW-f<(kD&iW7qxz%OVPN*7 zt;fWYIGl`=+F$9xntU2kZgzlt>S2>FcziaXe)trj?nYAHtAx81h=(3qZ2$|VABcpCwKhj4w);h`m#-6Cy1H}&>Tl~H&}WFPb)0G-cE&d> z=7Wh@Cr0#u!6qw**N|_2ChgOH<0h=jZ#>zsl0sFsxZ6Q4-$S-PFm`N(a`yB!*Enmj7iw(+}Uj`+G&8ck#mCFuRGQL zK{HF%Ni#lK#(d&nWxUf0GX&_YE3dLeh58ph0^1-VsY#q+_#qb4@cJsD0bNp|rsY?l z2u;@|?~Hxh@r=l>CJ|V@Hg&#;ja`>VSegnZL?2(2UKU^VhT4-x9|DJMzz?vS_z+_* z^&q3x7vrXs*Y<3&?2graWc9(k4{U}fesKWh%%h~778@qAZ6UG;bq0^w;J@O_w9G^Q zic5v0PgH_qlTu-xhVzZ+!u5%83(7Zc%Z{c13(GFIg1`y>tO^BXC}~p{K%zDY2)90+ zn0p`Ro10m`tAu&djdh=!_>$XgHZmfMvD3;-AIwS(M!2IS*ur&`0VVBXd7@+Ihp zKcsfCRxa=#hG-B;$}gUZPv73ygSY)?CJDwx^w**5Prb=o*6r#pN-lnTIi#q@w8IVL zhg^fiUNhA|ne6sglz`a^N5>s0M5E%2l;Z-58(5mP*7S{dlkIGUprpXDPdlN&&cVsj z`+j^BQkvpgL3~bT@s_#dF^KV#;ZR-aHmt=DEp|jv7(+Eh%0X1mQ$8XMCwpXC*7PzZ z$nZcbnS1A53te=i?d!afDX}fsboxW<#RR^MBj=6+0%@r*xQ)cc?$!OcDT03bp>p>7 zSf8804w|1yZ`!UX5gk;sk;?5!*nGJlTZmkJM`w_lwxnbAfzumfE77i@WC>RjdKra0 z$_8aF=6Um9T(#@HskE2sTCV9`@rzN+>*2hcQh|7O=UzCVYeXF%MN7|as+i=jT>Dw% z>F4Nz2V=B19k5P4buDihYNd2VK@PiX$fWkAezG*oL@ruJy46^xzp=6P>7?ZeuC`Vy zS-?ij`gFaJP9a-YvfWAoPa!2S?EuC(0bZ#{5Qun_7+!Gao&8RkFT&D6N69n0-MgEa|_q$ z>{M_1#w*NstE{|LkUeU@ykMhQOicGxjJoNlaEg*_#cK6ho>#Ac_VeD(*-CYaHEWmw z7a2r8?wdv+aiujJlc#?Cr@gqsEBAEri4>0%{(zv`eQj$ zYWAhtFS$F6wQ1QSh--s@29wvcE}cwzG4QOoOQzR0#wfXFTC1fiB-p!C@&|WxKLb4pslq}@sncUpCed)wHqIbrw)CiuNWF`@F?`Lag#78 zKf|HT>Xt5USZ!JrYHeC(7m*weZmd{8)pl7&nWnm|-d8H5-5wSFqHCw=)#UKTsyqJI zj5c(pR1F>ne_|CXwM3uKJ|!XCZY1)$x1prAa57ri=Jc>6iAyPytO7 zDaUyZ@0g_|+W+LW(iO(3eN3fo6|z1UxnTH}f+G$YA~tcZo3(#a0!xy=MFidUdAl{i z(xW>RRyYvFAzrJZqi0|^NMh{s#v#@OQz@J1VmnPwSV7X5kEbNwy$Et1(+JoaY|F!p zG~s&J*?2YQd#J{lpODQ0G%j6oI(!hO?V(KVKBp)H5qIHGWSW# z8uD6EgQf>}l`h|ROu!mT;k&Z{yn_`NN`%HGuqTyLj{}vC~ zzu4G52@<2|#|M+h3vISJb%sYH9Jw7{LsiG7@{wa@W~g$_cG{9VHR?$R*|6Nu7X4B4 zGh^OdVw zZqKqI+s?5|tKswWoK?n)y*TNh@xcQ>nz*fq>HNnf#dqxmF3p=R0oE?JgL#~#BqT99 z>(J7#5qi+%`H5yX>%)@b!+a`#b)fDg;d-r34V^-FPvqlpf+3}?K~Z7~sD|*=F?Y6` z1Gy+Gz|L$m7Ec!KY%kcu$FFTxZg%F8isQ6GQ& z*crWeLr+b5Wv%S_^Drcz8+|!@#<%&~ zzfQ|kDQ@H;x}zN}TgF7UUO?yA7Yg3wM40Y=m}nm?3wS8|_y`|53doZ8Ga4=_kP}z{ z6`-@m92>j5yXt1^&^1K~u8Zo^CuUu)fGGXsuoJD=pD2FxlBXOtAoEL8OPW-;rdt#t zl!>$`G8#DhC8y=r|06b~|0?g^yAV@7ntsqfD2Ck?r%TAJ3W{d(*9bK4kG z_n2}%)-B`}KcDCL&QsiNmjIqaWPR+mK5S;)E6+GS+u>tOpG3B0z_5FC%!Y4b`5XmA zU}Bjp0r0fwj8`P2;E23ei>_@d3l$SAe=RY&Rx zEca?rK)G=R*y#~Nm9)psA;o5orGG=ue0oh%LH?14zs70hldQM{^dqC>^E9kt)9+a) zU-X88U9MPGi8;5MmmA?6*M0dS`i0D@&whA!)7-$ZS|G)ca^;u8WCxd-3NhB|;=)K4 zt+n}e$%hXfh}75LCnZZSfzro8%CazISAD-aowLb9qj9~jhNrFSg^av>kf(j-fDq#& zOYOz6IJ*dd?8w*GoV346F8^9~<(DUuWVg6jcJTjiZ2Arwo3 zZeov~K^1nz#^U!zs_P6b|G9KUcHi-$CcXZ<1`m-L=?VV4+ndQsx|qhe--K=bzu449 z^*E=aD{CBJ-Hprb6@2=)!TNYwYx*#-W}bQq`zv>UdiE1n%0wQ+W`NT?;&DW4ZEX*{5WBm`6yh=O0>Zq}cJ8Pg zdbcxF=cqRN-oq`mUmYO6Pw(6#n)@W`z`lFLkKLAULnNl1WuRHh*$7$?ClmA}zuVJ@ z{0+;alr=e1yny1BaAzO~0Knpm*<#bn@Q{)hwOn=??)#)F>q`HZB4p*YI4}iF%EI_f zCMG~Dg)_yUqNR9#5_U16lxP~aVQ_G@=svMpQ2Nzw^Ih8S7t)qEzHYJVG8U=PqR5tm zOEV&UadLA&eOK&;91|TAPBILD`(iOuJOxVQ!joU`-p{J$@4iy?_-@L-7b2{1e0J(U z5X_N0Uk8JfFl^ub>-Xr}@tsZ-)P-6a8J6*uA99&j`idKOE~_~-L{5JbZB3r*(9vFizW+Ldd#2{S-J~4XF&*)|w8OES1uJcQo!@xetjj5bdsoVv$lPp?^WwJwb8M$;CP7Yc3k7Lr+`9PcgsyGxLdZ!u0Q{_ zEPOu1EZL4T&IJww%FGMbD_}~M`Bm#V?Q<_oo3^jz-L|f zy|jrW$Lix-`j&2l8VA&5PdJ0EsHI-O8J>XHzhc<;o9=0inpztr-p4mFSLEh zy7{8pm^|~bzP#cK-ARkfkAdJ21pX$*4=o`UUnLU!G)HwD=f>sm9J00kb;$*m2nADj z*#Gg0-7Vn+pWAUC+_L8aQZ ztz4%;M@yALu$G;7a8`Knpv9zWap%pH_y1K){PXM8|05n}|CbNqhLO|Z!}4vnl%_Zmz-vNSpdEX&As9SZmW> z&YrTDW^+HK*FLFUfo|788jBf9H=T*TPH;>@ZEy2IRp-ZHa1`;mC#lYT~eQY85wZr=~xwru} z)mH>YPk?X(0rnY12XAn=I`I*sw*q+(6@UV5QYJnUpuJ3vCMZ1#RX3(?>qW#CmU}!)>m}(6=>}6X!6zZ=Gj)^ zKw$J`mp>vSTp(?(>Gy7dGukfy7>4GF!0lm%Q<<03HeJBR)U=S(Zk#vVPxFDAuB~bP z6)%}n(K*WT@ekvzgY+k&*!I1bcR)g~dEz?|FXeDR(iB3}R@uCL+H=&$R8BNBdCj#i z8p^b&7<_r9bliG6J$oUmx}rAT4PG!Hrzsv!!2z4@aT`*}Y0DIz*LQ_HnX z$`xh60o|$Y^PMchGGJ5DLfW+%SZCyg2L#i%SJH-RJy5oBTOEoSbV~722IEJEd!tgH z$8WMnwqe#SuX>x5!@;F&nY(4Y)P86EfXSh87*{ox3Bi3~J%ykWk{ku>YtTp3-z%Rk z*1nBrog&ZEqOXoHzVCQC8x`Bp$o`0H)2HRDp0vA;@ z#baa}jfslJV8Pb1kHUnCjX)?F#-l9ol9wUHJWHfE&%I6y+ykeWn9NO-w-OqCCn%7T zS)%8_!M76OoYAVwxl$i@jk^vik)WER1S8`nmsLP!hIezY#+XMAhb02CL1hKN#D~|n zY@awsy8v|})<2)r%IRT>BO#|rs0#VxYxKZGLh@I3)IvBYb<1nkL203qnyRd*J(TGr zSdS3jX7uHDwh}m4O}@Ai0DwDrP(0h{PUe2XnkPGm4yUb( zAsaD1sCv-_&U$BT!^mvOMDU#$y-!w%R4rStm=1`mS-sk6f6hd`O=U17Os@H6@AaSA z`+5oonC4*T2+eS)VR@toFCnvIv@JY>Qw*-jLIm%)V7V&`izNXvQE%6>zjYG0`VJ^< zW%6Pu2P)uPI(&em-QyMxpwVd7v$A=Wqi!~{n!vk9rB7uw<=iRd z33K1rZH+FesT;GWgMy{ME=feyD|VK$DDjcpm7Qww&q*Y1+%Iu_P0>a#$kG zN@H?1lBQ~FYrBK&^mJEo@Uii&*(~jq>)%EE(d?E*sMGaL8c#zK$0G~p<{MHc2?Xvt zc*%~cGA)-@g?Q%bP^(%|Tk9*8v+?ls&G|T&#EN4zKc-p)ujo~pxrWKi;)e}UptLUb zdPHjNSLb5w1Xn+$NYS$xCmFl)#4eMh3JDVb=gv(2j}<+xz>2e+Mk$yCh1-ZkoJPre z?kxAR;U8|mM}!&y2hD6r+4 zmz>hIi`xUiRxd@&V)GNKr!SAuZ~mI8$>g{}9pje9D`|ln4)55t!^#^Cd(YRsuy!J; zc_J%NgXG^Ub<^#a>frKGvNcJT-^G?@57th18!vUxFeM^xpc%F5;cV%%jCfUwkuCDV z<@MkF`$7QoKQuH7GFUiso`hfqyLj** zHCEHMemISU2rACo`NQ(k>;kIcM|Dk+>dg{h$WcBJ#~L3T%Br}i+~u$w)I~Nd9)Ysy znEj;S>N*~JHr8wYIlFTx5?!HYk0`RE4w~ooLv8ASN`bZ;FTI@X@%`3xoXDWfd}AVa zzX+=#O4*uqbIT(CHhZ@Bg*5vTBvdE`GJ?jvrg^ zRm9bApekhWa>``!uF}RXM&P_1&l(qE z*|7=ANM)}#%b+SdobFo+pP3GGwgvFi-BUAGVB=g+$jv9KYkEC5mOc{-CQ>xXCv>|*>T6d?rNq+z1DzMPI{ipr>Bug zPf@_yR)>Esk&#?FB-m(|BdDMM;OO4>zn{?T_ZxL4&oO!tyt8g}V}0z*C+nA|)PJV~ z()t|4+a1#?KpDMusv%clyU3}?v(~4)#mw3};`;tM@LU%M=<&NOnHXex?g@IN=fuZ2 z(=g2%g!WDy1JT~wyoA%nEuxDQfy)x}Y{2lbT`TzAaPJO{Nh3g<_gLtuw$WTun0Hxh z0dyFFymJ$l?5@Xa<d zZ87nz3%+%3g_8=eN~w;w>`C^Dd3So--ZAH6gO|%NLkRE7$M0M}f;gDG`Ol?*5C2@+ z==tXoAq{@roYLV?o({k=`s~M1w()*bBcB#p>PWPVyl9m}gWCp@^47M0v_$+OW2dC9 zSYX6auRDvpaGfPbEK+ zeTKQb-&nC4!C;fRad1@7Wa*?%>*O1L()BHEui@ZJ`=&2?yAGD9? zGEK0ya9{z>n~y)r)7bCeiF}P(3>a16s|MGzxD{~p!k7dE3#czGRG*($GyG>tO(ZnN zu4P)ot!@N_d^p5%jt@`$c8}g=)&o4SqvJm^tZ($DNzC*d6&hjH%|}$si589AF|#7F zl^aRPcoZn_U$ZkxyzYfBWV;#0BL|E`cQ#oKX_L%DL`YT)M)?gRi7XzpVkXaTpqOIl-<_)&LuO%_lwzV{gEYXE&nQhVe;1M)^I+A)| zMNwBOC)1hD%e%lw5uYCQ6mJas}a$>gZOVd1yEv@{f7_1SiK;rxt9_qMFrhm%emD2z{;% zCtEvRz3W9$5qVQdX#U)2Rz1o~Ke~3c`{Itd-Dim}_YRaX3iRJE09~o%AH51KQxDh* zTkv3`soH9zU46lDw1DUM8U(R{TkzRHSpk&Y{i-j%+t6uvyGeZ;u0&xA}cb_4lrE zd{QP6)K8jc=Oj*LZLrqCe8I6yK4q~ZoYl~~CR!60iTPz=qVuaeG;{}%#FX!Q628qy zc1wdvg%{Keqj)jTV!RGR|D?qCL0L9H5(w7ROthoJr%JOCax?UwpM4sLBY>@Y8t<~S z1##9rlyDxg5Hvxi01tNbU#{t_x4Y(uTqt(Mk;M#{TGgV`8 zV}Dcxy_LKMO)_q~d~c+EFA*8faxN_`9bPYF57w`~%%q}Y^Qvz0Ms^2sU zAl8MlGqQuTOllzr#e~Hf|8{_dx}|Y9gd-b*FD^O z(Bf70DLft!69xW^B}0Yk{A~vgcfl%&n;qj(k4mDyk38~@E_86Q4RE@Je&*MV)Lbgi zeLgiNWZoz?lFnfslET7#raYC#+Ff0-M=De4rmOS`7~v=x3l=Y<+oFJ*POw9tbRC{n zq%$Yo(@oYl=IEd(4Z6N#3unMxUT1vua4B)QZ|PVI@cCex6#&1u5x`==HS=9b@nao2Xr%jokJ+rYlaKnLq@21TpM9na;r}JBztYZ=p_N zqv)$Z65(+XMXD&V>k!0X2#7BMsS~6m1i5xm@kUzY@mb|B^UJFhTTWSYGITg4bTk1% zXYnKYEXL7vV{WiiL+S;=IkR>J0(tkbyhhDXB1d>!WzN_W>6#ybh4PjMwlw!gat{Iu`xW38oD9&T$)b}Yrm(bnh8s;+)CFJIp9+-yeN^P;U7K(xCJYea-H}9C z$7(yW2P5|<;!o7^=0PhR4qw_FHX}e+`r@|9X|M_8h!jBxJsy6R_;k*jPxmRX#^88c++{9A)oydmB&@I`nfDvbYaxb5sFdVCkT!O5qdb$W5jZP()@ zt|XYw_(l)gr|9{YxVs%OH1i`Qn!rb8il8X8<7PL43>4*!Q(Box1tw{Z5SA*5*f3Ks)q?xMGQukSQb`~&L-KrI=xVMjX*;KJ7=uaiq9sy zz>v+VjIVwYe-<*nMWF2QA-dAhf1vC~4|zrKJ-l5x0w5QN$PbZ?7qJ8#P&+PL_ZHKu zbYbu;fVZ}i`})@I0H!lTz^SUi<_}UOu>jSR#sK`1KCYfzarr*Zi6y+$R2|FQ#Yk2y zOjjRPW)`>jQR1FgI&7ynzqAL0%L6B+vY65IF;o28vcLGy=Pd{_x~?!t<}1Jh=9tfVQD~+5hwy$m5o3H zgs=k26v8NB6Gm&5$_j=UkX>0qLJ|`Q5JEsJE6g$ycA^kAgdIRe&$svgT<6I-=e{5O zpWJzrE7ujSBz(sE{eG?X1{%cqFMnALTGI*(79kw|@S$?>M?!V0&d-)K<94%4Y)^|z zy81e#0R7JNU>3V{AXyed|? z9CE9eh!yX^?oBXN`5pQJpr?zm`)2dNw3{j23R4Rv5v%l;_j*v5+a!`@NiiUxx4!LvroLcE`<-~nbJRtOB8KA#HGus1&_>*735d)O8EF|Q?%N8^6&Zj$!q?UlyW z7w@>w7jEwsz1tE&)@{ZA#67Q${j1m(^b0PaaeA=XkqJXoyZd^2665)`<;s2uiRG9< z?Rx`NVbWgmOS}@V*InNp+`X$7I~2FmthnzXu__3;?QG`0(4nQ9dBdHmS|+M#BSvBn z6kKEq>#${rdbzUe^80pBm$U&+)&8O}UJX=r|90WWPj@y9IfCIjQ$ImEu{UIV)#N_$1uABxd zyQ*q0-@4fFl&h|YWp5xZX*(>2z^q35_l!}PrV;Li?T*i!uF9;E6cf(=ncGckNjrS) zH9;~y>?p|S4CiTc5QzQ}Y|1Q4_Ex2bf<&{A(~iE|WKcw_eNTdNd8p7lc{L!&4@J*` zm?^0U6jNj8})&ykcUV;(z4o2w0J6kdBT_b(|iu{R#x3PEp)XV{w zR{r9ktu<(4>|KuUAEz=>nAZa@IMzmv3ijN08cZpE`iq1)u)iS(4N}Pz^KJ-{%FKBNmURBQUV5st99OMc9&`C zLXa{7kE`(KMLtlMNwE50{Od{PX$#ba24J@cW6l3Lc5;YH1u&2CH^T~U0Kz}dG!~k8 zl&?n!TZ3=-Sa@PLT2ejDwDb((@Kx~8;605@G%!TKiIY^{SPgrA`l8HkqR;ib%F^xF zMfB@N#~vJ_YA9Hn%!m&dt{2SQa69fkq8HwGHPEm^rTi9dUz?55%o^dB&7_lDoi zi5CKhC)8!gOr>zRVK46T!4}_+-|1GmfV{_1*X%O|F64Xg6?S8J;`=R!l^SDVCF$+s zl0QoBb0+OBo=1LM>_^+UYpzITMC=wvZQi?bprjVJbW4XSKQ`n}2e(X;htmRtrw_!b z#CD(HNUi9eyvpl3hZs4#IMb2pZ&yLz>rXrS{&2#{47mHY6Kx*G;7( zmTON_%wk@Ts!5cE>C6wy_B-Q+K_!q;Kd1x-O%uLkIvkE8 zVuIq@)sG5iR+pA(&)#w&Mo|^Fq4Dx&*O#3&$~N$E-WlY+<`E-cL&Am+&Gv(oA4 z-Tk#a1soGnV>3P`FP{j(E_6BH;ojg9Z~1$t-1|nDrDN<4rkEA0))cx}gZIeHa z6?bl#2mv2EaHN?sbMIY_9}o|fT%YXmjRm`&*V!Z~q1vYfMMqP8z0(7zKwslY zWEHOP@Oq`UzZO^hICAG%(jDbb58SNY#YYc9+m0-U9P8MPI5fAeJpnCKx3qAS$~#hj ze&)O6(lT|GQ^6*2c+`LH)?hZXn!|&S)C2Za52Sc5+VJI1!Ra!I&$=8rU$Y{KqtZ@! zfS@yFM))$hW{1MGoLPM~{);1bHaISIoj%*v?n#gA(OD($=$fGO(@d#yDMN!mv|-m| z#O@pD_DNUJ;-j{9OXlpK`yty&cWpF~*hYJs;C>jqd3{x2$vZmBI)wkn;l}n!>jgVx z=wP58bz?H=#+dMDqF73L7(RT3k@cXe9Z(OtGUnxDcwqhkb*C$URY-9No;YueHXx=F0YC02iJJ@kSH4dzi2 zThFz!a483Fi+|T)ang{NjW@FNf@I~dFc@9q!9rGDDdM`mU*bK_ovj_$`_SL-#ky=0 zTaENll0i!0@S&^*xb1oOCPkYlB?Kg5QY^A?dM0hw<#hagyVTXP`Nb-p^tkw&UCz89 zL=oXG{08mo&1qvGDRSyzAFX?#id(? zF^ox`(}z|cf-P>eUot*&i+`d3S7jjMU}$7t(_srSm)E@9km~xIV~?M3Fz=SE6VZr+ zfKnCnu`<>7QW;>4nbL!fDqro0(hmFZh`>?uy!`YqNg;QnRFE?BLXM20JF#+w`zAZ! zGrS`u(ubk@c+;(+9DSvfF_W`1VMMA^#x#8Z(n;W~l$jukSI&FRY;0xb=Ujy1v!7s> z1I3J*&W>N}cu9t9=nQ~^#F{L|oBcK60xBtn^b@K54f9F8uF2wh7q)b7V$O6e=z zLNn&QZ#rJ2j&h<@~;83e)967_Lf>-9#0ytQZHZTbJ*Uc1C|)E?d^Mt?;FP zc5WcroV?Sh6*|u8z&Q203CH(u5QyZ?yycmK16CKX;C6N5wQ+Tc+|fuqp;X=TB}*3) zo=`Yz!GBs&!QvP;-2o4KciuZ+=<4`q^_Q8q7)e!`UU24L6?t$2YheM_Aj%^l`O1>3 za7V)`{AYWO2staMTb*!e_tskWw@-3e{;-PCn5b}bGKv_jAD+su%g$je(VzP)aTLf|WdZ8W~J zc4dhaGHQ!DcvPv)XhoO3cr!z0sCebJYaU?rRqafoZbc%38dfPfeB>3r_12CulKd4o zW6N!ah8Kt9V{*=}*8Nb^_!QiwAa?1Vc+qnXoUp#qDm%xIz4!ARO$3*9x$*f~YpV87 z3sr-;x{NA69kgdyu7IC~kLyR{vSPDc)PLBWT(_}IX%JTA>Ni_JjY(aKGRd@NDxNh z;~|+PIE&dJ4L`~dHNWVE-_Na7@>-sBmNUM;gx(b!jE~!;grJZ}zpKxbx$o^t7US}v z-E89SfDy=B+d$s4Gzhz)@FTNj-#i~1nUZJhFmUyacLR^!QKxXrzs&MK{@c^xPf6=a zn*oe5#44{O%gW`x8xz~vhrTI!)89-^pCrgq2%FUA5LQV`6hu8>-<8^W7cQR*k z)W_3bX-nIs!4c9WVdb%R_3ou;C>jr6UM)N1Z8&DJw(5?jM$Vcx`JG0CzoJ_3%Oimi zC1Gwo#wnyRM$A9Q=*vgK!={fMXIm)U*Kz`T!zw7RedM=SERrBCj6Y_K*sIGJ-B=y# z)t27fSF|23{O6cz$8F7lv0zOVb{D+GaW{nu@$!-;Ex>vaOU?B0o$F>@ek;6Bv-4x& z_L?K@&fe64T$)NeSmha5Y9j)*Sjwvo%yq8tj zzPUP8w??<7PKe$Nzsr+;>*;s8O?E6pOOqGm39HNr?426A?2`_GHS_t;`jL4K!qie> z!u!Mfue;cPU{1U{K0;FC$|`EOuXk|4kVdRM+T-rR?tCM2&l$Zp@cE4LaiNuLa#HUC zQ)c<~t2=TR)?xBK-Ln}prGxo}eG4eZcwub zOgTp!9E+8+{e^Z=a!Lx^y7d~-0~ zD)A-?S5^i1)Yi8fU7Lu1dFWB6ypePCso%b~U%a8b_JyFp>!beLUryo_A`ciDC7~h2 z6KUiu#oTTiyo5w2mrg?Ft-)aY;K}TGI=A}ji&WJB!p}i*9@T1graO0|ATM{;qZCb* z3rfck>xw3HzSU#>!_iBDtjcRCFAr*sI#TB*)3k4H!^ZVb8sW<#q@3f?otepm^4#Gsw|8z8`evkZ7@phALNeOpsmN-Eu91I7XgqD3gY0me`JJaF%+=0B{MQ|Lr&IDOdQR_V!YM{}gRDYDjHYJCZk@Y{FpPen7CjsJBNa^}Gr)GfzGI$OD%wGxGZnYI4JHqf;zgU$eJYsQ6Shgte>jcy3!e zQuCnFA)wY`)g3<=o6p6j2X^MJO%1HT*po0ZKxZKBqF+@D-ChFXHKZ+Exhk#^0t7`* zQ>+TE*^%0cpbKACjx+SblQo=QR7oUc&=(6%xlfP;uRf`fky7Zvd_wa2ZFw&h^^kIs zM`mhCPPMhnFPc40oX4;!AU7p8%GO`(U+#u7_#ky*midfw>SveCKWuvEKhI%*8|Zw= z8H8Pj?;Gta5AvH@t{fCBsV(F=U!e|I#CM9Kf6A8oq+DAt?CQMWOY6)27V@H< z^r%{d)y%NC9?-HNrjK%n6fDvJ1b-2sOnK`>THE73BiM2$gwe)OUmnHHkmkx#e zbxWOtm?gZ--B~#wXQMzW$7suO@o8Gk#@%ZXkIGc z>QB}14Tc&kM_jUI>EXAa@MKRt^931^!d7lrbTJ6Hjm8L~6+SeXmDz5lxZ;9oXXoZJ zryLDh-NP7-{rdy{o&R;5Y-MK!m+9Bk^Riga>Nu1R+U)82rO;su^|jc$Dn_zj>j)vX z!Q-RoxbP<7u1(iOiu03p_}g>UzOvSC^Vyb#7a`b=l>CC4-STZR&mW|bcoF4Ww=QzK zZ$ruNrmtCq))<}?Bw+B=wj;Zs&LKR3JZK+K_*Y3|_Sow9x-Ee`+5uT6DOBF+`s|dK zL1m`}Fq%Mphb}w8oQCDpxf&VPKCf&iBv$>`Vs@AkHm@vXEMBoPcnsJCRJNk|`wo%` ziUB>$Zo)QrBscfCH%oe4eJHa?C6#y1u?>S0F9W(vkUo>QJ-54GQcb(vR?Z6@Hc z?h7o%G~cMTooD}kNBoCt=VR?8{tmQYJTtGo_6L(eQg4wxCt zWtmSZ`hT(bLeQ+3C9F*DGih;=K3kVMghi;HPpz(zj9p~yYJ0-=?wNrur(aL}{NL*3 z|Br9xT0CoKD`huHQK~xFJ|Ssao~)DZ2{T6KZmeT17_7*&|vbbY)O5^<6NT!rtR^24VWVQ5qlklM$|T5%`)v-Iv+5K_X^D8>ttkKc3K?qd^d> za?NZ*P?VHSJyCxSz2x{?RpFJT;#vsB*U9Z=18n?_0PvZTh$Pa1kMI-YW)3C-xx4uI_!1;};K_JU}cup48QpY_*Wt!);R&;mS!;xB}uM9T&H z==49Olx~MiReBWWbC+r@{Ml0<4hgEVq>#FUZ0c9`bbw$gJzF8HQ7c~e z%pl=}f^2rU?>Any_pGOt18>YPL;5wnEEMRfiea$GiaC169Eg(W4`*acs=wAYQ-h33 z7yr(AlQ!-$A_Ayp21we~Kb<&zFNlkw?JkPm_{Ant1f2N@nVU>$U#@FdL0^fs$u4>D z;^|znZvozpx!0qJEmnofr6IGeO@NbV&@k8hj+exlN6F_lqB)bWB}k=@ z$LY9{lsUi&b5%i$3&OusD1QNCe@g_FVggEo9bm=|9;x=txybIm<1^rE8S_HTfV<4M z_?5Wy9PjvKSqtSt-OY19l8D z8B%DInMs|>vW@=tCmajq@>>65kBw~@aAl=u!f_ot=JS*66ml3I22GSlsbC=!O42yC zVSneS;0ps(XkM_4GF@;HIP3>+Z1TgrzhgfNc#U)@9eZWW9X59O%#7Tbqq{E>=`h$B zfw26ked|c~d8Jacd@a?>(@J|L(Aqv{$fULLuaqWC0b9di=I#&PhWC! zqP9>90gOq#mRpivkq!iV)8t<)q{)3O|Q z`%G0wDk_8q1L|Xw1W*V<6!?L`RArDENpC|%@}3uL-vjiyj4=2J%n`6JrBx6JDYkzqR#i6%~Tut<)Op z1%rK&<%G3zb;`r#uYZjX>m|CfHa2(n8`D0ko7T2nl=svhRlIN*x8Ni6&OicoS;k>* zDJh&ms1e?FxAN=nVs=t6l;Xx+V*YLsBv~m8#x4`ifhj&ad(y|$W6uRR5c@4MtKu&C zBMb`%$h=jEFyVTe{U2BAML!jmSA|I`!5kc!Xq&_Rl}8^g>Sq4mQJ=m?K{jxS$4FMF zn2K2t8>A2oXq;mrwU6cGEE>a2i|-b;YvpgtbZI;0Q~)8Q6V)J4Oz7;)RHe{y0S%C! zL+f3B9M>8l$}~|`ud$V~VwBMR5->5h9Wc4Jc|-T7x|=_91h;=&evxhKd)3g4s(|}c zXg=UrzBOFp_Hs+eDgXfK9L;Hh86@ZGw_@BYBQqw#VMs+qa(kBxZ0G9Z>+xdKFM) z*LhDRmu~1Ct5X8SN0$;72Q+2B&G|x-Oz-=c|wJT5fO{jO>|cZjC(oRIoa zq8DboBGmge`?mdYHZdRep6&llrFnVxG{eb#P>Nk?rbO`rCmn zn`{kMkuV8n7)9?GZ}it4pS|>^%d%lIo}O{^_im=tz04g?Fqu9xO9*(kpr*5?s6hfh zc%@5g>(Zi9(km*4P>>GH0C*>Ii2sfFZBkr)tk!r|_bXy)uKaPwUCb8+15ub>D=#3= z0VecnAFR3Ryxkw7W;0zHu{TjQ#k2ua#uInLgO4#RlWGga}}N3dE$1R3PjjiX^30KNFif%-j}#U-2Or1z$~C8CK&mmP)tf?-}o zO5lCqMl2@{IuW=zhPTZz-sFO+h-BGo<})z(8a#AnMI%1&;b3&Vx>>-FO6wr(M%%Cx zw!du-RPsOJ8*kef#tDXtJvClaCni_7jOc=owLwp(s17=hF$la{$T4oqq(0o*=Bw>3 z>E(n=S$89{a-A|(0yJFkp25S&Hb~Toqthd!&wB0fKq-6CN=Xeh>RqW5BezJ#hDiBFWVx)4V@cSwTvIc!-tummnSw{@$_hxdA_)ElQqZ@i$VY^I+)>$W&Y(`~UjfhlasWO*U>zn^2kDkssPx4Ey8x)Y9> z_l8?9eP~Cycf(A85pACRhSsmZB50Vsmd;Sgd@8W;Gw)x;__eJ*fw`6i6qn<>W++;* zmyv%H7q?3sTj{6`6ss48ATWAiaPR>P_UKPTd^r)|4AlNfJs)$)QV9QmDKyiP0EqHl z5)&@DD3P)8#_sj?Sij4p7lkJ(FFy+OzvP6!GE0X+<#;Z!LGTsOUf!RsuPgljIaU(g zhX|sa3=yl2?Q&hx+6}^?XR#Yosgvkp^zc;N|NAnT_$}-^SNnUm)4u5>C+~DuH5`4d zPca0^BTyXBZWv=2Pzfi=$2rB`{`BC+XJZWJ5JA|{xai}$zB&psSf+S>^?X{b6J+5? z2XE!?DPVy0Eu1Ar(&E%RlwI^*Q>=oZP4Ek7Hhph>c{QeTH z_K0;mAT)x?w;F7JOAmXeStnNbzDwO9^#jZ*4C0;9Oxrd?`%flt4~D0Lzq#d-a|bQ0 zNVWLfB|Ys0I&|1D%|Iq}xu>HP`tNc1xd#?UFH1g0-#xX+^5X7pMr}9lZEPNrziw!M z1a@T!3|50@5V-^(VK&MF`-jAhyJ0NU~7YIafkq`>TdZ5z!0dD}R1$|-|C=87H{Uh6aa z2x6agjFEW7fI_1+5v`Rg8s5gX?DJ_gpR)v#rM`2&$&5_WMbI&Rh|Y$VlyN(w*cmHy6m=$i6^dA7!bbql3 zf!}W^`%@~ZL|ouaf7-^2&RzcHzT_2{iOJxb3RXY7wqySB`j%wF5V^`_0c1*4D4>XS z%+JzFGp4A@>F?j9$!HQ#)#ZwMkj zxSYgvn^O>jK_zP zQXkB7bHNX&ogxB=po#?|)QW*8259%ifN5r|J!G2Yl9u2Fp8X<3SlX1mMnPVElFl^O z*L3e;xm6so%LZL1qlC9}h8T{Y*N0UsyL2rbFv=fo{OwK{hvm;f$Z(6A5O141{M_Qe z_x%gYKGKg0Yc3*lx;}Z8qf1h=i;`MlNTY@2VqgvfGW(*r+V(KRNe2JKA>5oTH*8wL zG(q;qfR1i3h038qr{t##bF^&9vKv#Fv(*+_v8}nNcIlGzYmIs0c=BpbWm%MunfkD) z?ZYY_DQmkd+3!(W$9C#dj{CTSiLi*-)C3Mx`tWmZ&F#*tqR%Xk%j7z(?pB9^MR&JB z|8duTY-*cBD?IM9=UNGx3)rI}*j=-L`j80?C503_EHq05*Zs_+=3`#lbFx$)6@A3l z_#zb?qXKp@C|z&vPP=J#*%bRjf!c1+V0vAi+GYuuA?fou1?Xl9$D6qh%dBmodN^>?i96PtihT}wd?zU=+YHvf`hD)JF#0zicAh6CE6aK|p%C*UKz3pFK6Wm-OnJqSO{UzxjOKi~i z*sfcB6b!bp30PU+PGfN5a$1%>5t6Dfs%n12l+c2Y-n30tzlk1`f!iahWkM%01+Kre z8rHdj7*{XpWn9=_sX+r+t+&1SS9m5yCJ*8svqWor#oF?#7>>?Vm5|5;Ga|^nHvj6D zIOKdAkO{`3;V5|5D*4c(Jv#8=TSr^V~!& z>L5zcly?5CRSG|sOFD`C?qyL`sCu5%1Cv67i+B%2>Xg1%EXgv1#`*tvqN4@9iIh}Bc!p>rzh&ko82v4qJ-@RInDVd!b zN|(wj@hmBvff>VW6@{!*cMd6xd}*9Vi?Z^Td5}*KA+$@8SoraCH%OgB}v5)r)t| ztfU8+&cB@^yli8-;oJ|`ZI&k5v)@r^56>l>qn2u9n)A;mgV3-=azf#-LJfiGz-w&! z-ZlN;pJOJL%05*TbN1^@+Q%S#5%`m;%#ayfYG3u8Kg{SW;$~$qyrSsduc;|WL2-7D z$_o&^a3j1 zQhO0@B539u82)qY;ytZL+obJ-f%b^icT=24?Xa;w&U;+9;Ec^dgW9<+IH#z{Rm*wK zC1sI=nZZ-m(U~BkH_F-Y#q0Jv`4V6&89UwR{5^ou>AnI6Rx1)K{&a-`=xD>qpq5+7 z+cV~wCpnI0zK)P}h{Uyj`^1$Xpp@xO{^iF7_1b|}Rb?A#r+1mU&3}x}av5S@0Y|{g zoaw+J!l40LDWlS)lP-^;;tK1M(xOuG%W<}IteAJB(=)4Dp`(G%yD;z4Ql;&=hzK|0 zxA>~H@~MQg>5;<)@6Fg8L-7v!!&p#4!omD zT@OAQh=eQDzO1Y<&D*0olrwKJkaVunZ%Ctk_jSUG>p#cVCk{9*P{M1w#_wCouC<=3 znfc5yHnF|CKM;igtesX5*`(FP#mo7~4erfwZ%my#lD3Np9BA1#r9bhg$rtU!?2Je4 zN~bU;%IHK>oiaI-&5;!6N$G-1x)K9KXSM_^k~hJO5;o|CuQ`21x^lk6D)}+iO3Kl| zpgNiWk$_uJmiJT`|2gRUwXH|$)K8)#23KsoTVzBthyxOY0a@TM8wwd2ni1D^O!vKK z6#0nc7GJTn+e9^r;Y+){6rMwl&4LI^PXW_3GIQs4kT-3Z>?uhiY}+rmLfrVLfthDI zUYaeo(A2ZByAVI-dZNH6E#4fttEKtAgGMu-!)BHY#}!N|V1e=27-46pNP4io)-I(A z#=orjXi03>-U#D0jCMfj%j5}Ib>y!~tz(aXK>FsbgKgRU*V)pNMs%)gWM)G{IEr3T zh5nzW6X=85ys>~lKdryJ7Ue~!Jc4!?tB#}xAYRk(lKQYQaGZYBaBfKLc*WY%8#km( z1r}a|W3MnU1DY!$7^{CA1+XT&x^tT@%Ddn2!khw|+^Z@nQsr%DTju8jUAKBRf`dkW ze%{9Xf8>d# z!g9?q&=S~Q$$fDtqLP1c9T3F6nNEkTj5h@di`sZK`;w1i*&qn5L>YZmOC{4Bh+$a} zim>R&jeGFh;kPEN>{=E423=-SVn7yR#2T}Ihdwrkz|cnxU}?&oIg%%62s9kg0Ue83 zis(y6f} zV;uoMw1_o5`kI64SlpU!OTczmfq0PRD*`hv8_-=gapD?>6TH3X|RD{Js7q$S?f3fT)2*g@7g>;A181SdOY76PR!YFocLC zkYT_BK_IMHqk*Qm4{rJqZ1$~FTT7PG8s`c#L>V=;l30}j^4yul>u{R&UvE3psw@*t zO@ff5kn>&IZ$=FviFaL0c*7YI%enl75zfY?{;vpC+jH7hSy(Z7M=N!dVjyh#asb97 zayZsl?d;%4Yhx|<)NU%+rplrad&hR%sqQ0UR4SI&FV*b?oG+_klb8ED77%yXzD0zvZiXo9pwuK;@5*35BzfsHI$gDFoI& z$iryw>Xj<`xP@Jkx?22A?}$qGouB4Rxn^3`)}H#zFgz3%qtaX#76aI+dy*`_e;fxL zjAfttLwjr%Od#x=GaV4*ei$_26gw7ZP5;yS+2Yzm1wlH{;iEL&36#MxK_ng)nKzvM z@vOEaUT3g1zst2q-sa>$(h#Nke6n}?s^=Xk5XuYMK}cPLtu#Z1<7-ddyw!beyrE4u zxnoh#p?hh>ygwKbH}7OYJGc+e1zY?eXhrJ+B;kGK zZ0nE+etqA9YTZWk8;U>{b}6!?1oQm_?=;;;2v^@3jl;Pk4%kn(L|WuXl|bUH-E5KXjr^2CE`m>wo3#s-v2 zk-HS1G4MMt^=9j-rOA|upF1;K6=sqpTQJ_ik$b96@>~DwKQ86k5pl zxKzR5`kiDE9I;azS9phPbMg}kf_B-$VvrN-UW`Y7@!~UqelM+jpzN_V^$@_NJ$*#s7i-B~@?5}w1i^>+-rnvZvh^6b2y zR>Rh$FlGGD)kXmcRQG7&{c}`Uxb3cfIA^XDz^-^q zGQgf{1^fawz%IY%-im_l2itNOP#7!w&|!6MWDhBa9nHS};3N|?KcHiwcK1i#OBSOz zNWvajHboRF&Pco!GumI+fA~k2f$FRGz%ry#TQAjGqiwM(vw(8Xoa4vr;l-zWv+kn` zAO4VYBIyc}<_xN$^D=VMLKMT4XFhf|1q@ji$LvW5=d{$FPD;YT$g!$L3U6{v(0I27 z+oWNOU6A~fk6u&t`xfUi@SWS!YJJ#r_+c4RhQM7#vOqDE7HhYG_S~|N3T@r@IXc#V z&3To+XOCm5kHf?41A1*8%)rGIsqz{UUp|!fV(;~$o0^>fc}Jx`%fe}F)i|L@Za+G8 z1xRosve1a^_&Ug)M0v;4kCU@x-JPL1swgC4&2eYzmnL8XWF=6Ve6rcuqSj2GdO>^K7cmHe$XYqu_iGj?U1d1_ z>5q3BZJsFsNJ~3l@fxu@Dc-Q7vlm=sj49D{nwR~oxg3b;=z}ersdJd=1abf+!UPd1 zCB1i))v)?WG_qA|8b`js>atG884W08D!~Fm(Rt(Xhpl1iUH^$7Et3?(W=br-%aq(% ze;YP4J7ha1g0cZZ&u08!fsyNZ$8s#C?%dhqokNavm$^*`(^d2Q?7GHLTK+lKt+r}M zB`+_uh&9GR(IGR3?-D$HLBSWOcI8v3fy6P~e-<|^GP_u>`apn#XPhLI z99XSrUdr-Qd!_cCo8_nndovUDyoZI>TP_yCHU|P51nV5sFEj%zqoZA6WY!1(^=;8^ z0H_}~NZSLyP3p~U)heZr196mzN_dW~tC#GgUvTA_itMh7LwCdkpJ##a&tl>a=I7 z5t)p&JJr~I$Ett|0>@TE=fOnC7oo%I^m4xsEho-UVl>z?OQlZRGsSYt7iF@{=!KgO z>-R15#vC?ROCS0VI-k`)qjhLHIk9>=Z010W_|4q!hU4=gq97w_D=IT+1{MMP#58*d<+<9Pa*2PJ$5{Ml|>Y7XlNdy z+N4Kl+mlxapDjiqz`bCVG#s%DI$VYI_*d1Tk;m~^4IgMlH>L%BZHG7`&OrU6t9 zT?WiiUn-LrZ9p?<8q2d59lENu2}!kVe9h>D>Ia z3uQ_ccHMuo7F3p2{?(0bII?=-5c>&|!`ClGRV$^nC|{8&mR*lXs_X4K(@!+^jOcHxAE7T8vwaCMx)(v%NKRA7!LIIA^bj zPrY1)GEetpG-lbj*!nYv<=Cr$U4~pL(gg9t;UoL6UD7?1rL&Y7*3kfAspGdpgS7bM z+3<^pu`KUo6)a%Z0=UMscO`KoA{+SedpY$4K5A#R$EItJ1TdB>#(|FQM(rmhpPPht z;{)ZTu-QUOj1AAHi0sY0a9$om8yooAeI8DfnQ?G-$z7g3Kp)uquZ}(H&1#`n)Bo<% zNSFHcUwoP2#q0mKHr89ybw2a6H~22SR`p9l?aP^f6^Z}(5Q9RaMuximT{$2XS4XX@ z=;(#bv){#DWL~V)^jX6vYnLW|H&X^1KsRphVkdk3{Izc^G^L|8Gtvk2-?NOKWEjIt z-$B+mV(!PIeivx|btMcsPX#>OU+SCh7WL z?j0U%?*l)W54aZLoE8|oE?Z8I0sJHH4v2==A3lr~T1n#;iCdCIzrj3noo2oA7ogVz z09%5JwB^)E=s0Y{I*Q@&?mIIlm*vmZoz)hTa2!WW0=*Y${6mqrWu%Aq`;8#cIxT-9 ze=tKnBY2Ye6bsoBA)6h4*B^>}>iq^Uc;>R8qiJ#0zefR=mz&z@OG#>1QFK7!x;$$B z;PlQ&yBwBTT1l&u&h#q=o6OQmuI(_hGeekAgQXt5(lO_SDny=5;Zq;@T~o_hr5so3 z!pTq+RkjuOV_g%g&1!8+vBWoTiOyMO4Rp4m$h?`ce+ftYaBfYLi`t`*nSI}PiT4I7 zeT7yMMO`j+N;d@*OCoQ+7=7*i?m(D37!WdvXYLUqZ6|zNhqyBxeb85cd2^ji_yp4- zQ{BcwhIKIb7uMcG@}Fa}t?or_Tvr=!EhAC!ns3}7TeZ|Lp%VbO69zKxKX1Q(>oll} z+mvQ?K0-kJLWPRi1Ek+g1f{6eq-}?p=^4TM=h)zV*UBIR-Oes0w1l6xFuflTf6$#L z8}MC!IXLh*4Z;Tn7Ia3kG#+S1lxvZT16HrdN4G3;8gM z>D(*IGvaO?{URT<7ZPV<3V^`@U^G^oefPxX=k-l!CG>9=*1_0Z@@A3rv~h@BUqA`2 zF68dfdT4XeLd5>jy%3gBWL%Q+P2o?wYC+v-g!t49lQMB1pNN@w^v#ec6?NZbGbE_;7Ku$iAw(0=1L6c zYz=iSP&po2k-{@i{qxqJl}w||b}d#K(ZA<>ZYCfEc{AIfr^y2 z^n-gN2Mc=$A@BPf*WaYIkCL%$b_JGLnA#WDGzh)hDH0~VJKezBGVfG=*Bbks*4;9; z+2!@Fi>azb=U~hCdDREDvX7tTmRE@hoRRJjo>G7nGg#V@hOj#d zZtB|HBsyo^8F)0R;FTxMsUV7AF#E0s@QTz^i zDO@xFZ#*S$+J^WGn%L(HNlXKz@?H7!!nYFb!D%9FFIEcr?uF=X=e||*UG}Ios`n^i zAiMcpqx$D^zlQS3D_+$I1*Gdadu!{h@=VhW1kpnwd?ef54U0ZH>Bbq`0H1EUnP!`S}~R29G^82^Cdd_&yk1C7v$6zQc2F;3rbW#l`Nb z)`K0iV**R@i*U>t_@z@lI$4CScOdhskSm;Slmfl0;olAet@ZUAH{t6F$~4MJ^gK#MUkotZyYJMSivRZs-XalaruwMI$JN|a4u7!V7n~+ zNw~O6mJ_y!mKKI5*-j*v1fSJ^w1^dxy_WU)hLZkb$GG-KU50Ke!yT;BH;vkVC%{BVd?q*s8pWc}=eWb6Jat84mbdK8PiLkDQMEOPe;Tcu4; zJy{s7);M)MP>!6+P9*Ne9LXj4%CHR5(O^2Y?;`QRE7L`h&kOc7q&1*xAR7;};77_6 zXESq=huW#liW&5CtLrX+DI#6fRYhJY3<}r?tV}}Tw7Ap7AOFT|l1lCF03(@87J|4S zcs$T>&mduutbXyH1Tesqyjflb5QFT^)FcFRGQla3_+&XOm0gB}0;Cxruwc1x%6~0- zuVScT-o1kWQv4t7oo7^&=i~Qnf7;gBB1B}W2}1~@AOXYjS0zB0Wh7w*DpL|hWpApj zmKhAl9x8;D5HJY=83C2OH4yd?2w(_d2>}`QxqF^B&+Gp<&;R^SdBfpFILXCzU)=X~ zeZQa2S+Switzw-tAEr&uRQrwo4X&-}m(gJBMPGOn}u8|Hv`oTpCbihr?2Ia--^j6u)jcV+%!Ek=Oo7d*pEqJ2Wgi@>0 zPxX*!NX*&0i4d2+PQ2s<2$ME~qK`WhbJbpSF5O23+qzeoWMJNQjXX3xcJfSRgVmK} z7GO36%fqu1df@^aUcUIp`DW#r;5&`%#h1P;TX>0^DEidG@J0a=o;M(V9>Yd8?IE zN+*K-*P}WB$2$Z=$2XR7L~+hhP}q|`&7(+Vwg#uvxXbI_fMu2wb#_W@b{Hk@@48x8 z-*SNLEB$P;I1|aNf$!uB1Lqkhw}+%}bjUq{OF%F0pi+AiDhNi~SY@^B=?aUWorZ!J zSvwD+e^?8?TJBXRJ7r^NVnwA~q=+~z@5g2clyAi}XJFSvygx}yC-Zj>-j$vN-7Rvg ze*KvwJn_V-W~Nj~d5&d|JIr zb7aIaXkJP1Ndd*vM>_y!k1GyeXcCmp*sZFh9N*Q}94H7ds48>>Nufx7!Uf}vj>o7d zjbkBslsRpqwS-VttF=P0_SJq{-qmGP{B@$3wrlWeONl`6(Zmru6qEMTz0%tKl8#|^ z^i6bA)FHBEDp8YlC!Lm){q2q?OoQFnE${%^&EacE;Ft5yr0*R-Z~X|HTp340SaVmT--W2?AA50F)<~e^JI&=ml&d$ zZpY5itXm?U?Jc!L=SLM>sq1(dS^MAD;Foy1e|*7%7%&LR+&(H<0rY2x~1nEa%pqkNTGtoiC4+SUOpQ z?mrq_Q~OC{sMFO87k5&FrSQN_5+Y59zG}r44*wnsoa@bcNRMsrwtDqO;#YXC>nV3z z6>r0cSHdW0CC8HqbmmP{!F~6=wI%M1VxGWI-pPvGJex$#F{MQH*H56FJEm`{ww^)( zpaj`3aq&dE)%>3UC+1Y`7tn`Q7eBh5S+mnf6}b`U1D{QC;j`RtDZ%Ys0)bim@^=K= zQJUcXkh|V>Dhj=;dR;O<^CdYfB+Ueh8njf)OYDl8ti%k34gy9U@Ob4YEu%Ce=KDmE z?jrK|QD}zq?2+2k_R{*EXjWi$?CgpbY9mVbx{{7=9lx~uhWIJuB>&yw{cQu6l#uGQ zg0!gee92^P9tuqkY+*}}*{ns7Bnqrro%tJ7H%B*ehN($xF6#xahKck%FZm`}*{b z36eCqWeo$4i;T-4tZud95&|3jKkN(E%H5Be?B|PY?Ua4|pDk8C(`B@y{cVYI#7$jG&uUAgw>8f9 z)@1l!C*;_1rwY!ln-N~PQiso#r)PCYmzhxkBKpWva7^64NT{joCXm2H+23ibSeYzb zZ+iJa)TyfDK&33 zN>;%({taz?0LI$IeTQ6rCk4kYWaS|lcHiX z(Qt0CTTc;`Gdq%gx^TH_3f0Ia`*w5fQL_Ur3MsW$qZPYdy3O{s9jU)AaT7_#Fe*^S zFxn&MzRoTMQEQWjpN{Gu>YGarC{xpX4GP=GS%eu@R`K3ke0O_3$=z?$I;GchD+@yI z4ML*a-DI_63I6FiI_crVM3LB1OFqr}>)uB}U8e8DZb(?A2x@&VG= zGZYnGdXOQ4=5=QQ)gI9=6rtt2H|qYU4* zU^K9q-OxMd8&*8Vk99~P& zJFCAr$9>ihUyr@%yMNvKZtWU!fu2r5ORl>y=gVa+P1HjJINB7FC9$dO{>G}aL_MjR zX<%&^gWKRx!e^#Kg_&CUbLn8I*GLX3s!%kQ!v6V#1Z?cizmD!vb^XUZn>jr2EjM3K zbl7Nge3b#Az-R)zdEl>`OGo&vfip zkBP1}05`PE)UPAAf^0ia_4J(~$%q2y9IZ86&$bRtYgwg@R6MPF-O|Wa7R;2Hk*q-r zjYf$-5cY15)YX-^6xk|YQY~GvP23_OH4SPo;LYWV>HrRT$%;?1nyh~yVS#7yPA-aa z(A_&&=V0!rbe2`7OP+f5NYy?YUO-)_naZigXTn-81nlJRZNw*+%IZkird)_Frk=g# z&a!c#;%!8u_Jo=b)XkLDUZ41HDDVDfZr%TR?LQ;%Uoir09iEk5A3MUuaZ;h4mURxU zK%T@EK&tiY$A7$aYK+012q!IPTuH;kHFgvp)Fu@9zKNUs!WC@YiI^V{)$VlM?nfB> zcF$wA-@XBU@28zVhC6OiOh3}<+(hLBwT>5I?s#A3Y{qN=g+zU*^-_q`guxrNp^_9} z#{$KUlX9E2(FIF4F=R~Sokt*D3ITx^Pb;yun!Db21!2GQnDMka8r*A+ubpE@l{U6Wv+s2F$4IZM*)NaGg;m!jZ`_Xbdvoqxo7R?z$|^OH5CtLG z18O#d10$4R{Z8gURxgUTPmef62Q0rBaIJBcJ-lGwI3#K007OUcR`!Uy_TE5}?Dn*^ zi_FGK4y}8+fu#-J(E`n#tq4NMMT3YE*8)Ak&9Y39o1eiiJfxE6jD3`I)6z(dui%gI zIxshrLZ2Jkc6S1(hd-Er`>8QzHP+{;Sb-kA(P&Tk-jp_c{lK`d&OCdRB^`^Luav2T zqP2q_*4CYvb;TMY zz^iA*!!=P1_u8yHuF;27j~osH5bY8Ht-GI9q}3w}pVH=7r|bZ$);o^GcayIU)zX4* zCvZcOR*LnKgntX$3-_`)NqlVla86H97H^noJK1tZi2Zsz7%h(vx z276!F^rDIq57k!o3*JUwbvm{?e=^qZk1Ut&f>HQZ#JW-RVMC8VVYqMl;g2nayL?w3 ze8lDRfm?0URd~HECgb}IXY`tv-v=n^2aS>K?K+$-w5bsd9qz<8Fq#ThfZ8{?uwOcT z_YxjD!v2}zTDw1Gcs|l|z#5e)ISLa5^Xn8%AQ;>dhWvN@OVQIKdOx~q2^-!R8tj}q zVADo2WXToDtx}UNUyIr90iIe2T0oOm54bzp%d8T+q#nBWbIUHj+6zSafF|^(JR*eX zMQtLCf|L&nYxnrxa}_TEXV3ellpgKJxDweXl=1W~IV4k)PtAx!&-@FBcV=Q#IQjttldjl^F3B7~H&jsVKWx+{F73a_S3P*g#s8dc=}ePa zN-V%k;%}B@N3rqwF<%sK_AYHp>_=HS#M)-rN^?1`yZ9>17UXeQ!vLG+!eR3pl_S-O zwfQ_VZ0zIwTTi;i6LSuSOweTqMVC5{zRI94ARmnv@O z4tdop3dDwL9Q}#9&KzE^lrq5({zIkZLSFmWyF70+?Oxy&}^Jh}7rfde0^2 z{YJGL>faa(ZAmJbbdPesi3EIuxseDm8%0k;*OjTSQOL3Cs z@APr};|q^GMv2QZS$*|08JaPGN%tEZ#H_05ScYCSJg`k2Ag{h}%gWo?o#ok7$0tH1 zcYwNuCAMsGBMDgH6LPi>jlS3hQ5A;(?RDsH!7=UijUGA~$=`b)Gvm&5jJ5#;*?55n zT%;OjfO2lZ*VUUgT7u8Do)bqn49+vMtLL)P5;7)QKD!gEgW-e38igB4YR8X#0h)K& zlL6o8jkL~P=h6C^TiK?ku8=e)$Z&3KE}tO*L!hb~D!0|sje;Y3IeFR?=TaaA#ul)W zU-v5A&p+|sL6iBfxS=?4;s_xHP9?T?(zU@bD$Z9jk(==6+KFp5PG|a*0iAIcrivcn zXZ$JZb3^Ddg|x9Rdg8|y9UjkL_Wkg#QhIHfN_@hUp2hbZ*jtv%ueX9eU3>PgKWUaY zhxWy#3VId)EMKGF5rje=pXopd4qYO;7D?K~nxY3rL@8ef9e{5UGE; z`&~Y`udRf>_x=g9S>1f*DvVKrC6w>clUDi3>>YCZ?2~vEB z6FQ^^2hWJ+HKRZv(KfeRamhcb4oupkVC)aH8}7NuK-J9x59=(U(C!9g`9s_o0bv4H8|OzEIF}xGjY4BXDI1~0y1yj ze|Mar!wN zX_4ozLWd;~GLR&03!WsHZtMGSU!pWI_%d1IRC3%ED#o)}hssY^t0x_$J~`9wt(yU^ z6jd7a3)x}j5MdY3!<-64U5Du8LRMdipg$HmcPKCu-a_xUI*Yok-EzsF(a%QKZey=K zJ@MG-ow?1f*F!~4^d+6!%V3&AWht({&q+{XjW20*pXS4=3)-wTi@_~s8gM{7ojBtR zG}pg;vwwEOjF5^b%6&aabB%Ve@Ejh+JDyCpPaRC89$x3zPuUoB7a3bQi=_6y?he{t z4WIXDU}in{qvDy=Vz{_@sohNgO7l4t`115Ord1@2GPM$(orLxL)>h`mvu|Gk?Kz#?|MHC1Izc6mY0sOfJWW|s4_Rc6$-dkXO z%@{p4ThA>A{o$?Qz>Ol$b=MWcof0ZK{j0gV8zjKDLJot~AIy%pwi-xlI=r}DAiicU zUvvJ87@$~?Y{xekh>#mmMsAb0jV$|N+P0(|a)xZ2YOorVW=?Vw;{YU-DZRfHgozM0F3Q@A7+Q`op2nj~oU zzNYHo%l`eE)&_IF^$oE)Xv-Zo6$SghZ}X=<=)l?W>z5j9Zlw0?x{Uf_7=*66Z!t-F zx9*%Oe4#Wo3S2Q zfmSJOoe<@Jqhi-Dp--WT`;LrXLV?LvH>0OF>tW?GgWo(y`KxXpyvSs!l`wX8A?~HU)7&(Bb6yhd%q2x+L@=X znClvklX5?fmqcf3ji8pRgN~mD>@-Q!gN@XlFR$^9z1HVFlLoxC>ugQ^s|`1*-as!F z&=rbC0=2f+sFrZb6kT~87wWZ?L@gkIb!#{7$ki51#mNyCI*3xx2(Sh!fif{BreKg0XM=>8a%u`>iGboykKQjmfGL#GTJT}YgG(9A zkko0XU14+y$73veYVTu)B>NM>Y4U{syaErO--xy(ljTzs z__4FRAsMWgq--TCNPJOaf5Opq)GYkpS+4Ez4@Xirg7Y|Q)x%o(0_J3KvG0AVWB1Mx zYL!0nnLoB-O0HYz`W9qNc{XTTVq^?)q6k4#f;rzxb4|v>@?)jC<+_51?riJ)xql$AX-4sS>QQXrb+N2a_K>-Zd(n+iQN{0%|9tcZy6^6ljx8vWoN8p* zlo#laA9Edw-LPN2@<*rkq=G>O9U^_WmrhbaAlB(n>;^#J#0gOPO%*vgtF))q#$2(2 za2Gv!?F+h0CB)8CC3R@{kycm{HTWu;)^j7j1LHd6g*zOxaavt*>hO`zD>(l!B~kSG zpK|-_uo&0V3$Q9gauhd-fGuP7x;k1#tg;?v5?8DKXl0x2Pmb@ebiM&I8MEl|DH|BL zZ5}R?Jma)(&QkQ8qaI^Vp_hwpR-DQYW1@IUj>ZnndG+%wo6rh!VS{!7$dz&=K50A*x~oV zlVger%MC?+PCx*t%SroHH8a3XF}cQ=Wjf#Fq-Po0R3w%T>t3>dl!{MB`CP$ITKXIG z(YLMkxWR81&SVyqhwQ6_Y>hfR%OHd?oz){yMAPG9e(U&={(!o5=!MX1WfNG~Oqa>< z?s|iSW=nq!x|$Sc7KCEZ61yCft5 zv7On>AFOVO+8Rx}sJ~w3u$1j+R)PfguECTS+P9lgbjvK1=e^{&-jI0PT@yvm6)qPA zTq{rbzAtHx@jov@O36LA`m??ePXv*+MeH3V1(+aZ4;v~7C~l+5yaoqe68#DL)6nX{ zozV8AGh$m4XEz#qqe?RTIKu_j#G0)LFi#(5q9{`y3uywc{j%Cr=kb^tW8r4m(!M+A zWNtPtF^|tUvIksc70dYXNlFIY7p17O5$B^7xFUc?Kn2OC41CP( zz|~VD$L51hxs~gtFPk0XCZz4Im-Zr~D7ikJDDO!EemDu@QZNAsty}IyaI2aYu3V(Xz$o4rT$jIAlJ+_$?MB1oV`Kw z3NCbCXp=PVxg-}Zm&)%M^w^ofTTYVwMdI#ovNSQis7?_Nqs3*N+P z?haNs3FbwY`!5I7M86MEt7oA%gJQz%=6a%3ypjloj;@(#WJc(pa_QqslBT1=DWZ18 z3Z-Rq*u0cOJ4X2`UT zpDFHziMi6~QTwPkN|NcU>hLgr0uJ^MS=2}w-1{)HBqRQ#ePb78xU722^ZjDs$%GF3 zeDJs*vVP0{u{>@+X@p(PX}On3hwHX1YF@JWb?rd28ksZUcQD3>8#ts!d(6)?lW=O& zd7ms3I(^CxOt=Nbx*M&VuO22oSv^OmX@5xX6hAi=`l9pBQ{uLZDF+gtSO*gU{urBMSU|e$s~3o4p$mY0YFwR^do8SF zON&AG#F2_zd%+R;R>#HnBNce?l6cf}F+X*brT&QW&z%AA5}LQK-&}O_^~IO8CNpYq z0fki(4UR1=1}o(!ujXgTq~)zE>%LmcgWv0&a+M_yi8 z>qOe{yOK(~04sZohssg(?d@Z?$k;!lulUqYZO@jUPNZ%aEvFu_=3`HN59eLElHA{C z>6W(1k3im4ar4s_Z#S~ve1Wb>ENdXMrdCLk#V;~2RqB@hNozMGQp3z#oE&ypt?l@t z(bhI&{6mV3PTxJC;3SHNd#4y?nEwPpEFJwisvOkDPTxSD8x)r$I zm(!H-A2Kejj1Ok_zYjSV6G~;1$23dL;X1my1Hq_9T&ZVtEeBn$1Gf?DOfI>BbaGH( z)s3&kyy}dYuwH#01p`TSk`;!NeEXPgQ8oS{&+&Ot8&SQ+TE*N=>`wvxmvE&qp|76r zdKHx+Ba!0I#36imOYD0aksc4?^!}uAS zYNOe)*{0^N`h(skKYP9Vjr*cM3~H0lnL{HeM7PoQB?P)gcW^A^Qy}OlTA{=$uTNgO z(9N!7o~vYX8+Cv@^z-w`Nt!#nH94F;eJl{^=8T14tA!J50r483IMh9RhLe2}D{n%aM7(8|RN33ev~j9N zn1G9mKSzq6fTwFD1Wz2`E4aB?5c(765W^bpi0wE|9VD}7;1Zb$0u8chmn#TtH6rXr zBVHj>lj+{&@uKEQS?~8An${!tH3%LN0jJnJ{z|Ky`fttc9(K5I%*%o?Yo2m3FbHAC z#zbF(i}^hZhQJG%ncV_~CN<{zT<}&tFJ&FQOF8=il9^*xOWHsNt`TyyS^Mf?0OyV6ZQUOxT#|ZL}--O2VekPsLx+{;_Awr+yyE z5hb6IXH2QNn@k$En|_=o`u^R!q(3fcHt44+OB$~jzZ}cX+I1lbSkewr*!l^ zNcAf5##x*9q|OiGQcu!xkuJY08JhIJ+TASt8W6Dxl)DzdL8vg|0m4l+OvC--wBOCO zR8vxIdjozQb%gNl#Va{~U?x57{^D$fv$n%@t!_^Q$-0#AFPO%vyJ z4ep1;vNDCvtp>caH{}N=IrnO2d1m4g8Mq#Ibyvc7GxHR?x0@)mjs^(m2w?Xn!>lF^ zYs@*Z7FD87^*87NsY3Z6nsl|NpZBn(k!6VprarH_wlE_ONK48{POpQ{4HyI9jXQF- za_<}-9C7^8__g245bcn{N^ ziWP7%EsU_iQmFccsAb_)uZTp4IuNrrx`>3gQx?fsptcXV?NFd($zsODVjF>|1%y`b zh$F_TI}OY1lw3dgWOdcRwi;26Hu}b7cv1&GlZw5+R*^UQg!%P!!OLpTD62Z;`@Scv zsE!JE&tDyaI>!JF?3D$YWIJ$JPMv*kXKBO+lhwS#znf<8ET%?3PL=H$LP5>2pdcKx zr}Fah9^$z02&9+)t4alGxa5VIR)rcyVa?wM#z*yCtn<;f7LnfDkJ;-3uqE5pUHC$o zZ*DsWd2UBarCVQl*oFMSc%9ac=Tyy0g(Xn~!-HIBGPRp(zZy_fL1~HZjG(uJT)O9) z?o*^`2v_U#wAT|Nz=Gl-xwMuiEZ7)osG`05*&2!0)5*bml5#%JavsR&pYBU`X%T01 z$a1G{k`IM0e@Ap#6V7vQiu22S`!2ZanBSFp8ZDP^6);KlxLgn&w$}b>E|wUNfXe6R zHAQNS$v{^+x8278Sc(l_7+EHykfL;AcN`w5BqV%%hvM<(OXQJJzu$0|-(>5U?mO)h z0p_Oxk=e)cjf7^}?UD1LuRi+Ec1;r5a!*Mi#1fPic^RJEGWV@|TSMO2Ap6_Z>x75! zqnI!|`LtYm@BR$d-9C}73|%yC(b0Jb&>-!B-Hl99T6SQ0mVj)F?ekQ8NGTyg;n(nT z#KI{^Caq+TrIyD99txfBM4hzghzyLkEpda{UPz>fZNVp03Yh#xFRJ6V$^7edrXbiE z$d>u?tId`y!C?NqhMz;4VczAc(vMc@=;t{*!TO33M5b0pxPp2u2W3A>#0-G+F8!bu z{%J40Bwqa+fz;YsD=7)X;)=eF??#{2$$1O^kQer8a4XS$nKEvs<{2>#R2;7&m1! zz){r6>SR-OtpXbBvz7&KDe8UL9n~k@=4NBm4msXgl+1iX0j4drf;!BJsc(&I5^?64 zv3u*FSeDtUWBRblYZ_&|1_u)uMN4yV#fn~t^@Nstj}p$#emQ0QC2pH@_s3A$<(_-( zpQ{im^gc)xTzaL^1p16=WDN_-Yh+2FFJEk)IG0JL-I0%aGAM-NGz4h%Q^t^j3eG~( zZd7sH?hNT-FK+cN6va#{(&?`$wHYZfQTBBpcc5Hn<0*k{1JRc!470nq^t!;wtt@jb zY+AZjTn>#)-X3jX2iYU`l~||#Hdq+>N|ky=-TtnmWGBp8K8=B<+wbPcNIlbviz3Q) z!7y=SYS)`k>@v=|UIX~;M-^q23!OyU-Ag7z>2fg*{s6yEaL9?ye~!$bJ@QOQm_52? zUGwg8@A%5kRNN6vj(R?_*khv8D>+FU1Fo;l!@*FnTBAv|498?PDmDr!6?S;9&u2`o z3o`LRH^6i~-X|~Glz=XIPj2y@3HLm;oSP5#D6ah0h)w8|QRNGjOyssrj8SQCd{WYo zq70GsxrB|{CHwu)xt9q~lVymNK^A3JYfnGK;so@44y|)tFOc3zK7M>?g$nPmr#%P? zddtY?o%!rMTBT+JL1j%ysl36y-^_0V>PM6uph?Re1FN(2s<)pF+t0Xiq4EUnnl570 zwk0VgB*4gO&gZ^P{j<=G&DpO+HCX$gGYnl#it1}2HwbCPYQ;WGyLoiElv|Cm_Q)%y z6s}P+MYBCE73$zslAcs_{i(xOeCFh`b_XKWr7EmJV}O{3E1Tr3=L4wt!o632CooXF z)s4KP;R&YJSfz=vuXGgx&1e@AMJf`Owq#l+x7pV|2U@%jz+cH&(i|_vLTPYCaWJ^V zg*z4whJP#^7Btmo)&Ev+5Y9p-6gBY#=f8oJRxGS_XlXhSJs#pdP5^o*Kl*<4EKzTR z9(U!6rV7S%vGHoL$fItXQoYc>n72 zOM9AC-Xx~d*dkh*5C}`%BH_r*p?%2B(c@0UdUk0z@5&|T)BN$}MY)A#VIq7lFpzoB z6^J#nhx+&*&oG~FIuYpol+|XQ9J)9X*k%v`C{dki3{6Bh_@Xzc18G-+X5%~76iT?v9 C*Nhne literal 0 HcmV?d00001 diff --git a/docs/profile-sample.html b/docs/profile-sample.html new file mode 100644 index 0000000..eb6cfd5 --- /dev/null +++ b/docs/profile-sample.html @@ -0,0 +1,26 @@ + +UART Parse Profiler
uart-fixture-kit / Parse Profiler2026-10-18T00:14:59.200252+00:00
+

Parser output first.
Timing second.

Synthetic byte streams. Virtual arrival times. Actual local measurements.

+

The unchanged byte-wise JSON reference parser is compared with a chunk-scanning alternative. Every timed run must preserve the expected records, including diagnostics.

+
22 / 22 correctness checks passed

Bundled JSON fixtures and four generated workloads run through both parsers before measurement.

+

Paired timing results

Median milliseconds. The smaller line shows min–max over 9 measured runs after 3 warm-ups. Ratio = reference median / chunk-scanning median. Values below 1 mean the alternative was slower.

+
+ + + + + + + + + + + +
WorkloadReference msChunk scanning msRatio
bulk-409676,739 bytes / 19 events18.36817.822–20.1388.6698.493–9.2182.12x
fragmented-1-2-7-376,739 bytes / 23,612 events27.72326.933–36.21526.09924.787–28.8741.06x
bytewise76,739 bytes / 76,739 events44.28042.690–46.38856.50754.889–59.5710.78x
fault-recovery206 bytes / 32 events0.0640.061–0.0660.0460.041–0.0481.38x
+

Measurement conditions

CPython 3.14.7, Windows-11-10.0.26300-SP0, 8 logical CPUs.

+

Intel64 Family 6 Model 165 Stepping 2, GenuineIntel. Timer: perf_counter_ns. Parser construction, event dispatch and record creation are timed. Exact JSON comparison runs outside the timer. Paired order alternates. Garbage collection is disabled during each timed run and restored afterward. This is one machine, without process isolation or a CPU-affinity setting. No serial device, electrical timing or hardware speed is measured.

+
cProfile hotspots, bulk workload

A separate instrumented run. Cumulative times overlap and must not be added or compared directly with the uninstrumented timing table.

bytewise_reference

FunctionCallsCumulative ms
profiler.py:73 run_once184.303
examples.py:25 feed1984.164
__init__.py:304 loads2,04818.016
~:0 <method 'append' of 'bytearray' objects>74,69112.599
~:0 <built-in method builtins.len>78,7879.845
decoder.py:340 decode2,0489.016
__init__.py:248 detect_encoding2,0484.146

chunk_scanning

FunctionCallsCumulative ms
profiler.py:73 run_once132.613
optimized.py:16 feed1932.504
__init__.py:304 loads2,04817.401
decoder.py:340 decode2,0488.779
__init__.py:248 detect_encoding2,0483.973
decoder.py:351 raw_decode2,0482.623
~:0 <method 'match' of 're.Pattern' objects>4,0961.709
+
Fixture and parser SHA256 evidence

Fixture digests cover canonical event bytes, virtual timestamps, expected records and name. Source digests cover the two class definitions; the alternative inherits timer and EOF handling from the reference.

Parser sources

c9562cf89b2049d0b7299cf7ab857b008e0efb6de0fc4fa1dfdecf4abfda73e7da86bce5a1d40f33b62efb4b8c088be1122c49934bd3ff718d8bbb504113a7ac
  • bulk-4096cc202aae41aa6da835ca9f34f99acee02936d6e0afdaa376ecff663a94b890f8
  • fragmented-1-2-7-3579d413e5b2fb5a10c22ca452acb358f6728251da0a368b4a4267de214513694
  • bytewise33172f6e1f12446c27e1ff3e3e03a833fc3bf28c4aff577ffef7913f881d2d92
  • fault-recovery03df6f9982da793b55f4d70c410c5afb95372f1b3fdd42d5857be84082f5d0e1
+
\ No newline at end of file diff --git a/docs/profile-sample.json b/docs/profile-sample.json new file mode 100644 index 0000000..b84c26f --- /dev/null +++ b/docs/profile-sample.json @@ -0,0 +1,684 @@ +{ + "schema_version": 1, + "created_utc": "2026-10-18T00:14:59.200252+00:00", + "data": "synthetic; no hardware or private captures", + "passed": true, + "parameters": { + "records": 2048, + "repeats": 9, + "warmups": 3 + }, + "environment": { + "python": "3.14.7", + "implementation": "CPython", + "platform": "Windows-11-10.0.26300-SP0", + "machine": "AMD64", + "processor": "Intel64 Family 6 Model 165 Stepping 2, GenuineIntel", + "logical_cpus": 8 + }, + "method": { + "timer": "perf_counter_ns", + "gc": "disabled only during timed runs, restored afterward", + "order": "alternating baseline/candidate order per paired repeat", + "scope": "fresh parser construction, virtual-event dispatch, emitted records; validation outside timer", + "p95": "nearest-rank observed sample", + "speed_ratio": "reference median / chunk-scanning median" + }, + "sources": { + "reference_sha256": "c9562cf89b2049d0b7299cf7ab857b008e0efb6de0fc4fa1dfdecf4abfda73e7", + "candidate_sha256": "da86bce5a1d40f33b62efb4b8c088be1122c49934bd3ff718d8bbb504113a7ac" + }, + "fixture_manifest": [ + { + "name": "json_complete", + "sha256": "869943d07227dc653d576ea4e71d7635c2315facab757792d8591dd93b214f4f" + }, + { + "name": "json_fragmented", + "sha256": "54479abe2c31e8770e82b4e78c9152efb59ad5e913d83df65da884246fe2173b" + }, + { + "name": "json_invalid_fields", + "sha256": "53616cf53881a9767cddd663544a2eaeb8b11a790f0cf213de1a73591dfb9c80" + }, + { + "name": "json_malformed_recovery", + "sha256": "b77fa97a74bb5f8c7b3e1e1478b8f25bf82fba5728a7578cc1188f69c0d15c65" + }, + { + "name": "json_oversize_recovery", + "sha256": "7b0e203e4d1eb0ed854aea21f7755e2a2b1528cab777c637e8d06423b0005d31" + }, + { + "name": "json_stale_recovery", + "sha256": "d323ea55c6af98adc7fc4a7d552bc7282ab8d83c1c993397c79b950002b20dac" + }, + { + "name": "json_truncated", + "sha256": "2f15653fd96506df7414d79d9fa0f2d95a62ba95ffbcc5fc8975a58391cbc1cb" + }, + { + "name": "bulk-4096", + "sha256": "cc202aae41aa6da835ca9f34f99acee02936d6e0afdaa376ecff663a94b890f8" + }, + { + "name": "fragmented-1-2-7-3", + "sha256": "579d413e5b2fb5a10c22ca452acb358f6728251da0a368b4a4267de214513694" + }, + { + "name": "bytewise", + "sha256": "33172f6e1f12446c27e1ff3e3e03a833fc3bf28c4aff577ffef7913f881d2d92" + }, + { + "name": "fault-recovery", + "sha256": "03df6f9982da793b55f4d70c410c5afb95372f1b3fdd42d5857be84082f5d0e1" + } + ], + "gate": { + "passed": true, + "checks": [ + { + "fixture": "json_complete", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "json_complete", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "json_fragmented", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "json_fragmented", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "json_invalid_fields", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "json_invalid_fields", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "json_malformed_recovery", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "json_malformed_recovery", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "json_oversize_recovery", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "json_oversize_recovery", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "json_stale_recovery", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "json_stale_recovery", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "json_truncated", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "json_truncated", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "bulk-4096", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "bulk-4096", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "fragmented-1-2-7-3", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "fragmented-1-2-7-3", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "bytewise", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "bytewise", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + }, + { + "fixture": "fault-recovery", + "parser": "bytewise_reference", + "passed": true, + "diff": "" + }, + { + "fixture": "fault-recovery", + "parser": "chunk_scanning", + "passed": true, + "diff": "" + } + ] + }, + "workloads": [ + { + "name": "bulk-4096", + "fixture_sha256": "cc202aae41aa6da835ca9f34f99acee02936d6e0afdaa376ecff663a94b890f8", + "expected_sha256": "b4725047461702fba1aae180f909476e478d821671bf672a707732bd897932c6", + "bytes": 76739, + "events": 19, + "emitted_records": 2048, + "timings": { + "bytewise_reference": { + "samples_ns": [ + 18294200, + 18034900, + 18064000, + 20137600, + 19678700, + 18367800, + 18521100, + 18556100, + 17822400 + ], + "median_ns": 18367800, + "min_ns": 17822400, + "max_ns": 20137600, + "p95_ns": 20137600, + "population_stdev_ns": 737415.2124519506 + }, + "chunk_scanning": { + "samples_ns": [ + 8669000, + 8492700, + 8734400, + 8600900, + 9218000, + 9006300, + 8605400, + 8906100, + 8585900 + ], + "median_ns": 8669000, + "min_ns": 8492700, + "max_ns": 9218000, + "p95_ns": 9218000, + "population_stdev_ns": 224012.1326079361 + } + }, + "speed_ratio": 2.1187910947052715, + "candidate_time_change_percent": -52.80327529698712 + }, + { + "name": "fragmented-1-2-7-3", + "fixture_sha256": "579d413e5b2fb5a10c22ca452acb358f6728251da0a368b4a4267de214513694", + "expected_sha256": "b4725047461702fba1aae180f909476e478d821671bf672a707732bd897932c6", + "bytes": 76739, + "events": 23612, + "emitted_records": 2048, + "timings": { + "bytewise_reference": { + "samples_ns": [ + 36215500, + 27723400, + 29831300, + 28045400, + 27448500, + 27378500, + 26932600, + 27197800, + 28638900 + ], + "median_ns": 27723400, + "min_ns": 26932600, + "max_ns": 36215500, + "p95_ns": 36215500, + "population_stdev_ns": 2742750.3410956394 + }, + "chunk_scanning": { + "samples_ns": [ + 26152000, + 26170200, + 26486300, + 28874000, + 24787100, + 25049300, + 25889200, + 25281300, + 26099500 + ], + "median_ns": 26099500, + "min_ns": 24787100, + "max_ns": 28874000, + "p95_ns": 28874000, + "population_stdev_ns": 1125114.6974727225 + } + }, + "speed_ratio": 1.0622195827506273, + "candidate_time_change_percent": -5.857506655027878 + }, + { + "name": "bytewise", + "fixture_sha256": "33172f6e1f12446c27e1ff3e3e03a833fc3bf28c4aff577ffef7913f881d2d92", + "expected_sha256": "b4725047461702fba1aae180f909476e478d821671bf672a707732bd897932c6", + "bytes": 76739, + "events": 76739, + "emitted_records": 2048, + "timings": { + "bytewise_reference": { + "samples_ns": [ + 43900300, + 44104200, + 45308500, + 44199300, + 44661900, + 46101700, + 46388400, + 42690300, + 44280200 + ], + "median_ns": 44280200, + "min_ns": 42690300, + "max_ns": 46388400, + "p95_ns": 46388400, + "population_stdev_ns": 1085169.7250194394 + }, + "chunk_scanning": { + "samples_ns": [ + 56236900, + 58603100, + 56507000, + 56455700, + 59571400, + 58213400, + 57146000, + 54888700, + 55601800 + ], + "median_ns": 56507000, + "min_ns": 54888700, + "max_ns": 59571400, + "p95_ns": 59571400, + "population_stdev_ns": 1422216.2692583748 + } + }, + "speed_ratio": 0.7836232679137098, + "candidate_time_change_percent": 27.61234140767206 + }, + { + "name": "fault-recovery", + "fixture_sha256": "03df6f9982da793b55f4d70c410c5afb95372f1b3fdd42d5857be84082f5d0e1", + "expected_sha256": "b981a97015f69f10fcf1e8b6c7eb46ca8d17a82593f2e20190b7526dd340cfed", + "bytes": 206, + "events": 32, + "emitted_records": 6, + "timings": { + "bytewise_reference": { + "samples_ns": [ + 66400, + 66200, + 60700, + 65500, + 63500, + 65100, + 63700, + 63400, + 61500 + ], + "median_ns": 63700, + "min_ns": 60700, + "max_ns": 66400, + "p95_ns": 66400, + "population_stdev_ns": 1882.669499525725 + }, + "chunk_scanning": { + "samples_ns": [ + 46300, + 41200, + 47700, + 45800, + 47300, + 45700, + 46800, + 45900, + 46800 + ], + "median_ns": 46300, + "min_ns": 41200, + "max_ns": 47700, + "p95_ns": 47700, + "population_stdev_ns": 1798.215851035014 + } + }, + "speed_ratio": 1.3758099352051836, + "candidate_time_change_percent": -27.315541601255887 + } + ], + "hotspots": { + "bytewise_reference": [ + { + "file": "profiler.py", + "line": 73, + "function": "run_once", + "calls": 1, + "primitive_calls": 1, + "self_seconds": 6.88e-05, + "cumulative_seconds": 0.08430270000000001 + }, + { + "file": "examples.py", + "line": 25, + "function": "feed", + "calls": 19, + "primitive_calls": 19, + "self_seconds": 0.0411076, + "cumulative_seconds": 0.0841639 + }, + { + "file": "__init__.py", + "line": 304, + "function": "loads", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0034336, + "cumulative_seconds": 0.018015700000000003 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 74691, + "primitive_calls": 74691, + "self_seconds": 0.012598600000000001, + "cumulative_seconds": 0.012598600000000001 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 78787, + "primitive_calls": 78787, + "self_seconds": 0.0098448, + "cumulative_seconds": 0.0098448 + }, + { + "file": "decoder.py", + "line": 340, + "function": "decode", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0035480000000000004, + "cumulative_seconds": 0.0090159 + }, + { + "file": "__init__.py", + "line": 248, + "function": "detect_encoding", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0026084000000000003, + "cumulative_seconds": 0.004146100000000001 + }, + { + "file": "decoder.py", + "line": 351, + "function": "raw_decode", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0026341000000000003, + "cumulative_seconds": 0.0026341000000000003 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 4096, + "primitive_calls": 4096, + "self_seconds": 0.0017776, + "cumulative_seconds": 0.0017776 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 6144, + "primitive_calls": 6144, + "self_seconds": 0.001487, + "cumulative_seconds": 0.001487 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 6144, + "primitive_calls": 6144, + "self_seconds": 0.0012211000000000001, + "cumulative_seconds": 0.0012211000000000001 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 6144, + "primitive_calls": 6144, + "self_seconds": 0.0011408, + "cumulative_seconds": 0.0011408 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 4096, + "primitive_calls": 4096, + "self_seconds": 0.0007267, + "cumulative_seconds": 0.0007267 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0006525000000000001, + "cumulative_seconds": 0.0006525000000000001 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0005408, + "cumulative_seconds": 0.0005408 + } + ], + "chunk_scanning": [ + { + "file": "profiler.py", + "line": 73, + "function": "run_once", + "calls": 1, + "primitive_calls": 1, + "self_seconds": 6.36e-05, + "cumulative_seconds": 0.0326127 + }, + { + "file": "optimized.py", + "line": 16, + "function": "feed", + "calls": 19, + "primitive_calls": 19, + "self_seconds": 0.010183900000000001, + "cumulative_seconds": 0.0325039 + }, + { + "file": "__init__.py", + "line": 304, + "function": "loads", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0032354000000000003, + "cumulative_seconds": 0.017401 + }, + { + "file": "decoder.py", + "line": 340, + "function": "decode", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0033580000000000003, + "cumulative_seconds": 0.0087788 + }, + { + "file": "__init__.py", + "line": 248, + "function": "detect_encoding", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0025133, + "cumulative_seconds": 0.003973 + }, + { + "file": "decoder.py", + "line": 351, + "function": "raw_decode", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0026225000000000003, + "cumulative_seconds": 0.0026225000000000003 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 4096, + "primitive_calls": 4096, + "self_seconds": 0.0017089000000000002, + "cumulative_seconds": 0.0017089000000000002 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 8245, + "primitive_calls": 8245, + "self_seconds": 0.0013545, + "cumulative_seconds": 0.0013545 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 6144, + "primitive_calls": 6144, + "self_seconds": 0.001347, + "cumulative_seconds": 0.001347 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 6144, + "primitive_calls": 6144, + "self_seconds": 0.0011575000000000001, + "cumulative_seconds": 0.0011575000000000001 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 6144, + "primitive_calls": 6144, + "self_seconds": 0.0011376000000000001, + "cumulative_seconds": 0.0011376000000000001 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 4096, + "primitive_calls": 4096, + "self_seconds": 0.0007279000000000001, + "cumulative_seconds": 0.0007279000000000001 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 2048, + "primitive_calls": 2048, + "self_seconds": 0.0006188000000000001, + "cumulative_seconds": 0.0006188000000000001 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 2065, + "primitive_calls": 2065, + "self_seconds": 0.0006151, + "cumulative_seconds": 0.0006151 + }, + { + "file": "~", + "line": 0, + "function": "", + "calls": 2065, + "primitive_calls": 2065, + "self_seconds": 0.0005754, + "cumulative_seconds": 0.0005754 + } + ] + } +} \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 2154d7c..0faa34a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "uart-fixture-kit" -version = "0.1.0" +version = "0.2.0" description = "Deterministic byte-stream fixtures for testing your own UART parser" readme = "README.md" requires-python = ">=3.10" diff --git a/src/uart_fixture_kit/__init__.py b/src/uart_fixture_kit/__init__.py index 2015ec0..a1e2a1e 100644 --- a/src/uart_fixture_kit/__init__.py +++ b/src/uart_fixture_kit/__init__.py @@ -7,4 +7,4 @@ "Event", "Fixture", "Parser", "ReplayResult", "load_fixture", "replay", "chunk_bytes", "drop_bytes", "flip_byte", "schedule", ] -__version__ = "0.1.0" +__version__ = "0.2.0" diff --git a/src/uart_fixture_kit/cli.py b/src/uart_fixture_kit/cli.py index 5dd628f..2eaf528 100644 --- a/src/uart_fixture_kit/cli.py +++ b/src/uart_fixture_kit/cli.py @@ -19,10 +19,28 @@ def main(argv=None) -> int: run.add_argument("fixture", type=Path) run.add_argument("--parser", required=True, metavar="MODULE:FACTORY") run.add_argument("--json", action="store_true") + profile = subcommands.add_parser("profile", help="compare fixed synthetic JSON parser workloads") + profile.add_argument("--records", type=int, default=2048) + profile.add_argument("--repeats", type=int, default=7) + profile.add_argument("--warmups", type=int, default=2) + profile.add_argument("--output", type=Path, default=Path("uart-profile.json")) + profile.add_argument("--html", type=Path, help="also write a standalone HTML report") + profile.set_defaults(json=True) args = parser.parse_args(argv) reports = [] try: - if args.command == "demo": + if args.command == "profile": + from .profiler import run_profile + from .profile_report import render_profile_html + report = run_profile(args.records, args.repeats, args.warmups) + args.output.write_text(json.dumps(report, indent=2, allow_nan=False), encoding="utf-8") + if args.html: + args.html.write_text(render_profile_html(report), encoding="utf-8") + print(json.dumps({"passed": report["passed"], "checks": len(report["gate"]["checks"]), + "workloads": len(report["workloads"]), "report": str(args.output), + "html": str(args.html) if args.html else None})) + return 0 if report["passed"] else 1 + elif args.command == "demo": folder = resources.files("uart_fixture_kit").joinpath("fixtures") for resource in sorted(folder.iterdir(), key=lambda item: item.name): if not resource.name.endswith(".json"): diff --git a/src/uart_fixture_kit/optimized.py b/src/uart_fixture_kit/optimized.py new file mode 100644 index 0000000..9aba3e6 --- /dev/null +++ b/src/uart_fixture_kit/optimized.py @@ -0,0 +1,58 @@ +"""Chunk-scanning alternative to the unchanged byte-wise JSON reference parser.""" + +import json +import math + +from .examples import JsonLineParser, diagnostic + + +class ChunkedJsonLineParser(JsonLineParser): + """Same 128-byte line and inactivity contract, scanning chunks with bytes.find. + + advance() and finish() intentionally use the original implementation. + This is a synthetic reference example, not a serial transport or standard. + """ + + def feed(self, data: bytes, now_ms: int): + output = [] + if data: + self.last_byte_ms = now_ms + offset = 0 + while offset < len(data): + newline = data.find(b"\n", offset) + if self.discarding: + if newline < 0: + break + self.discarding = False + offset = newline + 1 + continue + end = len(data) if newline < 0 else newline + # Check size before slicing so a huge unfinished line cannot grow + # the bounded buffer or allocate a second copy of the input. + if len(self.buffer) + end - offset > 128: + self.buffer.clear() + output.append(diagnostic("oversize")) + self.discarding = newline < 0 + if newline < 0: + break + offset = newline + 1 + continue + self.buffer.extend(data[offset:end]) + if newline < 0: + break + line = bytes(self.buffer) + self.buffer.clear() + offset = newline + 1 + try: + value = json.loads(line) + except (ValueError, UnicodeDecodeError): + output.append(diagnostic("invalid_json")) + continue + if (not isinstance(value, dict) + or type(value.get("seq")) is not int or not 0 <= value["seq"] <= 255 + or type(value.get("value")) not in (int, float) + or not math.isfinite(value["value"]) or value.get("unit") != "C"): + output.append(diagnostic("invalid_record")) + continue + output.append({"kind": "message", "seq": value["seq"], "value": value["value"], "unit": "C"}) + return output diff --git a/src/uart_fixture_kit/profile_report.py b/src/uart_fixture_kit/profile_report.py new file mode 100644 index 0000000..f1e0b0a --- /dev/null +++ b/src/uart_fixture_kit/profile_report.py @@ -0,0 +1,42 @@ +"""Standalone HTML view of measured profile JSON. No scripts or network calls.""" + +from html import escape + + +def render_profile_html(report: dict) -> str: + rows = [] + for workload in report["workloads"]: + reference = workload["timings"]["bytewise_reference"] + candidate = workload["timings"]["chunk_scanning"] + ratio = workload["speed_ratio"] + def milliseconds(value): + return f"{value / 1_000_000:.3f}" + rows.append(f'''{escape(workload['name'])}{workload['bytes']:,} bytes / {workload['events']:,} events +{milliseconds(reference['median_ns'])}{milliseconds(reference['min_ns'])}–{milliseconds(reference['max_ns'])} +{milliseconds(candidate['median_ns'])}{milliseconds(candidate['min_ns'])}–{milliseconds(candidate['max_ns'])} +{f'{ratio:.2f}x' if ratio is not None else 'N/A'}''') + environment = report["environment"] + params = report["parameters"] + passed = sum(check["passed"] for check in report["gate"]["checks"]) + hashes = "".join(f"
  • {escape(w['name'])}{escape(w['fixture_sha256'])}
  • " + for w in report["workloads"]) + hotspots = [] + for name, values in report["hotspots"].items(): + entries = "".join(f"{escape(item['file'])}:{item['line']} {escape(item['function'])}" + f"{item['calls']:,}{item['cumulative_seconds'] * 1000:.3f}" + for item in values[:7]) + hotspots.append(f"

    {escape(name)}

    {entries}
    FunctionCallsCumulative ms
    ") + return f''' +UART Parse Profiler
    uart-fixture-kit / Parse Profiler{escape(report['created_utc'])}
    +

    Parser output first.
    Timing second.

    Synthetic byte streams. Virtual arrival times. Actual local measurements.

    +

    The unchanged byte-wise JSON reference parser is compared with a chunk-scanning alternative. Every timed run must preserve the expected records, including diagnostics.

    +
    {passed} / {len(report['gate']['checks'])} correctness checks {'passed' if report['passed'] else 'passed; timing withheld'}

    Bundled JSON fixtures and four generated workloads run through both parsers before measurement.

    +

    Paired timing results

    Median milliseconds. The smaller line shows min–max over {params['repeats']} measured runs after {params['warmups']} warm-ups. Ratio = reference median / chunk-scanning median. Values below 1 mean the alternative was slower.

    +
    {''.join(rows)}
    WorkloadReference msChunk scanning msRatio
    +

    Measurement conditions

    {escape(environment['implementation'])} {escape(environment['python'])}, {escape(environment['platform'])}, {environment['logical_cpus']} logical CPUs.

    +

    {escape(environment['processor'])}. Timer: perf_counter_ns. Parser construction, event dispatch and record creation are timed. Exact JSON comparison runs outside the timer. Paired order alternates. Garbage collection is disabled during each timed run and restored afterward. This is one machine, without process isolation or a CPU-affinity setting. No serial device, electrical timing or hardware speed is measured.

    +
    cProfile hotspots, bulk workload

    A separate instrumented run. Cumulative times overlap and must not be added or compared directly with the uninstrumented timing table.

    {''.join(hotspots)}
    +
    Fixture and parser SHA256 evidence

    Fixture digests cover canonical event bytes, virtual timestamps, expected records and name. Source digests cover the two class definitions; the alternative inherits timer and EOF handling from the reference.

    Parser sources

    {escape(report['sources']['reference_sha256'])}{escape(report['sources']['candidate_sha256'])}
      {hashes}
    +
    ''' diff --git a/src/uart_fixture_kit/profiler.py b/src/uart_fixture_kit/profiler.py new file mode 100644 index 0000000..6997e48 --- /dev/null +++ b/src/uart_fixture_kit/profiler.py @@ -0,0 +1,178 @@ +"""Measured parser comparison on fixed synthetic inputs, gated by exact records.""" + +import cProfile +from datetime import datetime, timezone +import gc +import hashlib +from importlib import resources +import inspect +import json +import math +import os +from pathlib import Path +import platform +import pstats +import statistics +from time import perf_counter_ns + +from .core import Event, Fixture, load_fixture, replay +from .examples import JsonLineParser +from .faults import schedule +from .optimized import ChunkedJsonLineParser + + +def canonical(value) -> bytes: + return json.dumps(value, sort_keys=True, separators=(",", ":"), allow_nan=False).encode("utf-8") + + +def sha(value: bytes) -> str: + return hashlib.sha256(value).hexdigest() + + +def fixture_digest(fixture: Fixture) -> str: + return sha(canonical({"name": fixture.name, "events": [ + {"at_ms": event.at_ms, "hex": event.data.hex()} for event in fixture.events + ], "end_ms": fixture.end_ms, "expected": fixture.expected})) + + +def build_workloads(records: int = 2048) -> tuple[Fixture, ...]: + if type(records) is not int or not 1 <= records <= 10000: + raise ValueError("records must be an integer from 1 to 10000") + expected = [{"kind": "message", "seq": i % 256, + "value": ((i % 7001) - 3500) / 100, "unit": "C"} for i in range(records)] + stream = b"".join(canonical({k: value[k] for k in ("seq", "value", "unit")}) + b"\n" + for value in expected) + workloads = [] + for name, sizes in (("bulk-4096", [4096]), ("fragmented-1-2-7-3", [1, 2, 7, 3]), ("bytewise", [1])): + events = schedule(stream, sizes) + workloads.append(Fixture(name, events, events[-1].at_ms + 1, expected)) + # Explicit fault oracle: a partial record expires, then malformed bytes, + # an oversized line and a bad unit precede a valid record and EOF fragment. + good = b'{"seq":7,"value":12.5,"unit":"C"}\n' + recovery = b'\xff\n' + b'x' * 129 + b'\n' + b'{"seq":1,"value":2,"unit":"mV"}\n' + good + tail = schedule(recovery, [2, 17, 1], start_ms=51) + events = (Event(0, b'{"seq":'), Event(50, b'')) + tail + (Event(tail[-1].at_ms + 1, b'{'),) + expected_faults = [{"kind": "diagnostic", "code": code} for code in + ("stale_partial", "invalid_json", "oversize", "invalid_record")] + expected_faults += [{"kind": "message", "seq": 7, "value": 12.5, "unit": "C"}, + {"kind": "diagnostic", "code": "truncated"}] + workloads.append(Fixture("fault-recovery", events, events[-1].at_ms + 1, expected_faults)) + return tuple(workloads) + + +def bundled_json_fixtures() -> tuple[Fixture, ...]: + folder = resources.files("uart_fixture_kit").joinpath("fixtures") + fixtures = [] + for resource in sorted(folder.iterdir(), key=lambda item: item.name): + if resource.name.startswith("json_") and resource.name.endswith(".json"): + with resources.as_file(resource) as path: + fixtures.append(load_fixture(path)) + return tuple(fixtures) + + +def run_once(fixture: Fixture, factory) -> list[dict]: + """Time construction, dispatch and emitted records, without JSON comparison.""" + parser = factory() + records = [] + for event in fixture.events: + records.extend(parser.advance(event.at_ms)) + records.extend(parser.feed(event.data, event.at_ms)) + records.extend(parser.advance(fixture.end_ms)) + records.extend(parser.finish(fixture.end_ms)) + return records + + +def validate_parsers(fixtures, factories) -> dict: + checks = [] + for fixture in fixtures: + for name, factory in factories.items(): + result = replay(fixture, factory()) + checks.append({"fixture": fixture.name, "parser": name, "passed": result.passed, + "diff": result.diff if not result.passed else ""}) + return {"passed": all(item["passed"] for item in checks), "checks": checks} + + +def _measure(fixture, factory) -> tuple[int, list[dict]]: + enabled = gc.isenabled() + gc.disable() + try: + started = perf_counter_ns() + records = run_once(fixture, factory) + elapsed = perf_counter_ns() - started + finally: + if enabled: + gc.enable() + return elapsed, records + + +def summarize(samples: list[int]) -> dict: + ordered = sorted(samples) + return {"samples_ns": samples, "median_ns": statistics.median(samples), + "min_ns": min(samples), "max_ns": max(samples), + "p95_ns": ordered[math.ceil(0.95 * len(samples)) - 1], + "population_stdev_ns": statistics.pstdev(samples)} + + +def hotspots(fixture, factory) -> list[dict]: + profile = cProfile.Profile() + records = profile.runcall(run_once, fixture, factory) + if canonical(records) != canonical(fixture.expected): + raise ValueError("Profiled run changed parser output") + stats = pstats.Stats(profile) + rows = [] + for (filename, line, function), (primitive, calls, total, cumulative, _) in stats.stats.items(): + rows.append({"file": Path(filename).name, "line": line, "function": function, + "calls": calls, "primitive_calls": primitive, + "self_seconds": total, "cumulative_seconds": cumulative}) + return sorted(rows, key=lambda row: row["cumulative_seconds"], reverse=True)[:15] + + +def run_profile(records: int = 2048, repeats: int = 7, warmups: int = 2) -> dict: + if type(repeats) is not int or not 3 <= repeats <= 31: + raise ValueError("repeats must be an integer from 3 to 31") + if type(warmups) is not int or not 1 <= warmups <= 10: + raise ValueError("warmups must be an integer from 1 to 10") + workloads = build_workloads(records) + factories = {"bytewise_reference": JsonLineParser, "chunk_scanning": ChunkedJsonLineParser} + fixtures = bundled_json_fixtures() + workloads + gate = validate_parsers(fixtures, factories) + report = {"schema_version": 1, "created_utc": datetime.now(timezone.utc).isoformat(), + "data": "synthetic; no hardware or private captures", "passed": gate["passed"], + "parameters": {"records": records, "repeats": repeats, "warmups": warmups}, + "environment": {"python": platform.python_version(), "implementation": platform.python_implementation(), + "platform": platform.platform(), "machine": platform.machine(), + "processor": platform.processor(), "logical_cpus": os.cpu_count()}, + "method": {"timer": "perf_counter_ns", "gc": "disabled only during timed runs, restored afterward", + "order": "alternating baseline/candidate order per paired repeat", + "scope": "fresh parser construction, virtual-event dispatch, emitted records; validation outside timer", + "p95": "nearest-rank observed sample", "speed_ratio": "reference median / chunk-scanning median"}, + "sources": {"reference_sha256": sha(inspect.getsource(JsonLineParser).encode("utf-8")), + "candidate_sha256": sha(inspect.getsource(ChunkedJsonLineParser).encode("utf-8"))}, + "fixture_manifest": [{"name": fixture.name, "sha256": fixture_digest(fixture)} for fixture in fixtures], + "gate": gate, "workloads": [], "hotspots": {}} + if not gate["passed"]: + return report + for fixture in workloads: + expected = canonical(fixture.expected) + for _ in range(warmups): + for factory in factories.values(): + if canonical(run_once(fixture, factory)) != expected: + raise ValueError("Warm-up output changed after the correctness gate") + samples = {name: [] for name in factories} + for repeat in range(repeats): + order = list(factories) if repeat % 2 == 0 else list(reversed(factories)) + for name in order: + elapsed, result = _measure(fixture, factories[name]) + if canonical(result) != expected: + raise ValueError("Timed output changed after the correctness gate") + samples[name].append(elapsed) + timings = {name: summarize(values) for name, values in samples.items()} + reference = timings["bytewise_reference"]["median_ns"] + candidate = timings["chunk_scanning"]["median_ns"] + report["workloads"].append({"name": fixture.name, "fixture_sha256": fixture_digest(fixture), + "expected_sha256": sha(expected), "bytes": sum(len(event.data) for event in fixture.events), + "events": len(fixture.events), "emitted_records": len(fixture.expected), "timings": timings, + "speed_ratio": reference / candidate if candidate else None, + "candidate_time_change_percent": (candidate / reference - 1) * 100 if reference else None}) + report["hotspots"] = {name: hotspots(workloads[0], factory) for name, factory in factories.items()} + return report diff --git a/tests/test_profiler.py b/tests/test_profiler.py new file mode 100644 index 0000000..7ce34e0 --- /dev/null +++ b/tests/test_profiler.py @@ -0,0 +1,114 @@ +import gc +import json +import random +import subprocess +import sys + +import pytest + +from uart_fixture_kit import Event, Fixture, replay, schedule +from uart_fixture_kit.examples import JsonLineParser +from uart_fixture_kit.optimized import ChunkedJsonLineParser +from uart_fixture_kit.profiler import (build_workloads, bundled_json_fixtures, + canonical, fixture_digest, run_profile, validate_parsers) + + +@pytest.mark.parametrize("fixture", bundled_json_fixtures(), ids=lambda fixture: fixture.name) +def test_chunk_parser_matches_saved_oracles(fixture): + replay(fixture, ChunkedJsonLineParser()).assert_matches() + + +LINE = b'{"seq":1,"value":25.0,"unit":"C"}' + + +@pytest.mark.parametrize("split", range(len(LINE) + 2)) +def test_every_split_preserves_complete_and_empty_lines(split): + stream = LINE + b"\n\n" + LINE + b"\n" + expected = [{"kind": "message", "seq": 1, "value": 25.0, "unit": "C"}, + {"kind": "diagnostic", "code": "invalid_json"}, + {"kind": "message", "seq": 1, "value": 25.0, "unit": "C"}] + fixture = Fixture("split", (Event(0, stream[:split]), Event(1, stream[split:])), 2, expected) + replay(fixture, ChunkedJsonLineParser()).assert_matches() + + +@pytest.mark.parametrize("length", [127, 128, 129]) +@pytest.mark.parametrize("sizes", [[1], [17, 2, 3], [10000]]) +def test_line_limit_and_recovery(length, sizes): + line = LINE + b" " * (length - len(LINE)) + message = {"kind": "message", "seq": 1, "value": 25.0, "unit": "C"} + expected = [message if length <= 128 else {"kind": "diagnostic", "code": "oversize"}, message] + events = schedule(line + b"\n" + LINE + b"\n", sizes) + fixture = Fixture("limit", events, events[-1].at_ms + 1, expected) + replay(fixture, ChunkedJsonLineParser()).assert_matches() + + +def test_huge_partial_is_bounded_and_empty_feed_does_not_reset_timeout(): + parser = ChunkedJsonLineParser() + assert parser.feed(b"x" * 1000000, 0) == [{"kind": "diagnostic", "code": "oversize"}] + assert not parser.buffer and parser.discarding + assert parser.feed(b"", 49) == [] + assert parser.advance(50) == [{"kind": "diagnostic", "code": "stale_partial"}] + assert not parser.discarding + assert parser.feed(LINE + b"\n", 51) == [{"kind": "message", "seq": 1, "value": 25.0, "unit": "C"}] + + +def test_seeded_mixed_stream_matches_reference_for_many_chunk_boundaries(): + rng = random.Random(1751) + stream = (LINE + b"\n" + b"x" * 129 + b"\n\xff\n{broken}\n\n") * 20 + b'{' + for _ in range(25): + events = schedule(stream, [rng.randint(1, 40) for _ in range(7)]) + fixture = Fixture("mixed", events, events[-1].at_ms + 1, []) + reference = replay(fixture, JsonLineParser()).records + assert canonical(replay(fixture, ChunkedJsonLineParser()).records) == canonical(reference) + + +def test_workloads_are_reproducible_and_match_explicit_expected_records(): + first, second = build_workloads(7), build_workloads(7) + assert [fixture_digest(item) for item in first] == [fixture_digest(item) for item in second] + assert fixture_digest(first[0]) != fixture_digest(build_workloads(8)[0]) + for fixture in first: + replay(fixture, JsonLineParser()).assert_matches() + replay(fixture, ChunkedJsonLineParser()).assert_matches() + + +def test_broken_candidate_prevents_any_timing(monkeypatch): + import uart_fixture_kit.profiler as profiler + class Broken(JsonLineParser): + def feed(self, data, now_ms): + return [] + monkeypatch.setattr(profiler, "ChunkedJsonLineParser", Broken) + monkeypatch.setattr(profiler, "_measure", lambda *args: pytest.fail("Timed a rejected parser")) + report = run_profile(records=2, repeats=3, warmups=1) + assert not report["passed"] and not report["workloads"] + assert any(not check["passed"] for check in report["gate"]["checks"]) + + +def test_small_profile_has_raw_samples_and_restores_gc(): + enabled = gc.isenabled() + report = run_profile(records=3, repeats=3, warmups=1) + assert gc.isenabled() == enabled + assert report["passed"] and len(report["gate"]["checks"]) == 22 + assert len(report["workloads"]) == 4 and len(report["hotspots"]) == 2 + for workload in report["workloads"]: + assert len(workload["fixture_sha256"]) == 64 + for timing in workload["timings"].values(): + assert len(timing["samples_ns"]) == 3 + assert timing["min_ns"] <= timing["median_ns"] <= timing["p95_ns"] <= timing["max_ns"] + + +@pytest.mark.parametrize("kwargs", [{"records": True}, {"records": 0}, {"records": 10001}, + {"repeats": 2}, {"repeats": True}, {"warmups": 0}]) +def test_profile_bounds(kwargs): + with pytest.raises(ValueError): + run_profile(**kwargs) + + +def test_profile_cli_writes_json_and_html(tmp_path): + target, html = tmp_path / "result.json", tmp_path / "result.html" + result = subprocess.run([sys.executable, "-m", "uart_fixture_kit", "profile", "--records", "3", + "--repeats", "3", "--warmups", "1", "--output", str(target), "--html", str(html)], + capture_output=True, text=True) + assert result.returncode == 0, result.stderr + assert json.loads(result.stdout)["passed"] + assert json.loads(target.read_text(encoding="utf-8"))["passed"] + assert "fault-recovery" in html.read_text(encoding="utf-8")