From c38584d8a805e6bf7eeb983bcbed7dd173074fc9 Mon Sep 17 00:00:00 2001 From: xile611 Date: Sun, 20 Sep 2026 11:27:34 +0800 Subject: [PATCH 1/2] docs: plan waterfall leader line direction fix --- .../plans/2026-09-20-waterfall-leader-line.md | 34 +++++++++++++++++++ ...2026-09-20-waterfall-leader-line-design.md | 25 ++++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 docs/superpowers/plans/2026-09-20-waterfall-leader-line.md create mode 100644 docs/superpowers/specs/2026-09-20-waterfall-leader-line-design.md diff --git a/docs/superpowers/plans/2026-09-20-waterfall-leader-line.md b/docs/superpowers/plans/2026-09-20-waterfall-leader-line.md new file mode 100644 index 0000000000..c5c0cc01f0 --- /dev/null +++ b/docs/superpowers/plans/2026-09-20-waterfall-leader-line.md @@ -0,0 +1,34 @@ +# 瀑布图连接线方向修复计划 + +**目标:** 修复横向瀑布图连接线延伸到柱外侧的回归,保留显式反向轴的正确行为。 + +**方案:** 在 WaterfallSeries 现有方向判断中归一化 Y 轴 inverse;使用真实 VChart 渲染验证连接线端点与柱边界,不再用 mock 的布尔返回值固化错误行为。 + +**技术栈:** TypeScript、现有 Jest/Electron 测试环境。 + +**约束:** 不改变公共 API、依赖、图像基准或柱样式;不新增每图元分配。单任务在当前会话内执行。 + +## 实施步骤 + +- [ ] 替换 `packages/vchart/__tests__/unit/series/waterfall.test.ts` 中直接断言私有方向方法的测试:渲染正负变化与总计柱,读取 bar 图元和 leaderLine 图元,检查连接线在累计顺序中的上一柱与下一柱相邻边缘之间。覆盖两种方向、三种 inverse 配置、两种 calculationMode,以及 inverse 更新。 +- [ ] 在未修复源码上运行测试,确认横向配置在端点几何断言处失败。 +- [ ] 修改 `packages/vchart/src/series/waterfall/waterfall.ts`:横向方向判断返回 `!this._yAxisHelper?.isInverse?.()`,纵向保持现有逻辑,并解释 Y 轴屏幕方向。 +- [ ] 运行瀑布图、柱图和瀑布图数据转换测试;运行 TypeScript、定向 ESLint、Prettier、`git diff --check`。 +- [ ] 使用原始 case 在浏览器核对修复后的连接线,并记录验证结果。 +- [ ] 添加中文 patch 变更说明,提交并推送 `codex/fix-horizontal-waterfall-leader-line`,创建目标为 develop 的 PR。 + +## 验证命令 + +在 `packages/vchart` 执行: + +```sh +./node_modules/.bin/jest --runInBand --runTestsByPath __tests__/unit/series/waterfall.test.ts +./node_modules/.bin/jest --runInBand --runTestsByPath __tests__/unit/series/waterfall.test.ts __tests__/unit/chart/bar.test.ts __tests__/unit/data/waterfall-transform-options.test.ts +./node_modules/.bin/tsc --noEmit --project tsconfig.json +./node_modules/.bin/eslint src/series/waterfall/waterfall.ts __tests__/unit/series/waterfall.test.ts --quiet +./node_modules/.bin/prettier --check src/series/waterfall/waterfall.ts __tests__/unit/series/waterfall.test.ts +``` + +## 完成标准 + +新增回归先失败、修复后通过;所有方向组合连接相邻柱边界,显式 inverse 更新有效;PR 说明包含原因、修复前后行为、Bugserver case 和实际验证结果。 diff --git a/docs/superpowers/specs/2026-09-20-waterfall-leader-line-design.md b/docs/superpowers/specs/2026-09-20-waterfall-leader-line-design.md new file mode 100644 index 0000000000..418d6d3bd6 --- /dev/null +++ b/docs/superpowers/specs/2026-09-20-waterfall-leader-line-design.md @@ -0,0 +1,25 @@ +# 瀑布图连接线方向修复 + +## 问题与目标 + +Bugserver 用例 `649d7f2452a1e9eec95f9f1c` 是横向瀑布图。提交 `14c5e3e6f` 根据轴的 `inverse` 翻转连接线端点,但横向 Y 轴默认 `inverse=true`,屏幕上的分类仍然从上往下排列。因此连接线从柱间空隙延伸到两根柱的外侧;复现中线长由 10px 变为 40px。 + +用户已确认修复端点方向判断,并要求从当前 develop 创建分支、提交 PR。 + +## 方案 + +保留既有的累计模式与端点选择算法,在方向判断处将 Y 轴的 inverse 转换成屏幕分类方向:横向使用 `!yAxisHelper.isInverse()`,纵向保留 `xAxisHelper.isInverse()`。这样默认横向分类不再额外翻转,显式反向横轴/纵轴仍连接相邻柱边界。 + +不整体回退原提交,因为纵向反向轴需要原来的修复。也不逐图元读取 scale.range() 或比较柱位置,因为既有 axis helper 已提供所需方向信息,无须增加数组分配和几何计算。 + +## 验收 + +- 真实图表的连接线只跨越相邻柱之间的空隙,连接对应累计值。 +- 覆盖 horizontal/vertical、未指定 inverse/false/true、increase/decrease。 +- 配置更新切换 inverse 后,连接线仍在相邻柱边界。 +- 不改变柱的几何、虚线样式、公共 API、依赖和图像基准。 +- 运行时只修改方向判断,不新增缓存、兜底或每图元分配。 + +## 自查 + +需求、实现范围与验证入口一致;无待定配置或额外兼容承诺。沿用本任务已批准的修复目标,直接执行并提交 PR。 From ca396ae89f70ddc67dc143ab1d13b6fc00f22380 Mon Sep 17 00:00:00 2001 From: xile611 Date: Sun, 20 Sep 2026 11:33:33 +0800 Subject: [PATCH 2/2] fix(waterfall): connect horizontal leader lines at facing bar edges --- ...ntal-waterfall-leader-line_2026-09-20.json | 10 ++ .../plans/2026-09-20-waterfall-leader-line.md | 21 ++- .../2026-09-20-waterfall-leader-line.png | Bin 0 -> 62746 bytes .../__tests__/unit/series/waterfall.test.ts | 139 +++++++++++++----- .../vchart/src/series/waterfall/waterfall.ts | 11 +- 5 files changed, 133 insertions(+), 48 deletions(-) create mode 100644 common/changes/@visactor/vchart/fix-horizontal-waterfall-leader-line_2026-09-20.json create mode 100644 docs/superpowers/validation/2026-09-20-waterfall-leader-line.png diff --git a/common/changes/@visactor/vchart/fix-horizontal-waterfall-leader-line_2026-09-20.json b/common/changes/@visactor/vchart/fix-horizontal-waterfall-leader-line_2026-09-20.json new file mode 100644 index 0000000000..af241423a4 --- /dev/null +++ b/common/changes/@visactor/vchart/fix-horizontal-waterfall-leader-line_2026-09-20.json @@ -0,0 +1,10 @@ +{ + "changes": [ + { + "packageName": "@visactor/vchart", + "comment": "fix: 修复横向瀑布图连接线端点方向错误,避免连接线覆盖相邻柱体边缘,并保持反向轴和反向累计模式的正确连接。", + "type": "patch" + } + ], + "packageName": "@visactor/vchart" +} diff --git a/docs/superpowers/plans/2026-09-20-waterfall-leader-line.md b/docs/superpowers/plans/2026-09-20-waterfall-leader-line.md index c5c0cc01f0..121cd931a7 100644 --- a/docs/superpowers/plans/2026-09-20-waterfall-leader-line.md +++ b/docs/superpowers/plans/2026-09-20-waterfall-leader-line.md @@ -10,11 +10,11 @@ ## 实施步骤 -- [ ] 替换 `packages/vchart/__tests__/unit/series/waterfall.test.ts` 中直接断言私有方向方法的测试:渲染正负变化与总计柱,读取 bar 图元和 leaderLine 图元,检查连接线在累计顺序中的上一柱与下一柱相邻边缘之间。覆盖两种方向、三种 inverse 配置、两种 calculationMode,以及 inverse 更新。 -- [ ] 在未修复源码上运行测试,确认横向配置在端点几何断言处失败。 -- [ ] 修改 `packages/vchart/src/series/waterfall/waterfall.ts`:横向方向判断返回 `!this._yAxisHelper?.isInverse?.()`,纵向保持现有逻辑,并解释 Y 轴屏幕方向。 -- [ ] 运行瀑布图、柱图和瀑布图数据转换测试;运行 TypeScript、定向 ESLint、Prettier、`git diff --check`。 -- [ ] 使用原始 case 在浏览器核对修复后的连接线,并记录验证结果。 +- [x] 替换 `packages/vchart/__tests__/unit/series/waterfall.test.ts` 中直接断言私有方向方法的测试:渲染正负变化与总计柱,读取 bar 图元和 leaderLine 图元,检查连接线在累计顺序中的上一柱与下一柱相邻边缘之间。覆盖两种方向、三种 inverse 配置、两种 calculationMode,以及 inverse 更新。 +- [x] 在未修复源码上运行测试,确认横向配置在端点几何断言处失败。 +- [x] 修改 `packages/vchart/src/series/waterfall/waterfall.ts`:横向方向判断返回 `!this._yAxisHelper?.isInverse?.()`,纵向保持现有逻辑,并解释 Y 轴屏幕方向。 +- [x] 运行瀑布图、柱图和瀑布图数据转换测试;运行 TypeScript、定向 ESLint、Prettier、`git diff --check`。 +- [x] 使用原始 case 在浏览器核对修复后的连接线,并记录验证结果。 - [ ] 添加中文 patch 变更说明,提交并推送 `codex/fix-horizontal-waterfall-leader-line`,创建目标为 develop 的 PR。 ## 验证命令 @@ -32,3 +32,14 @@ ## 完成标准 新增回归先失败、修复后通过;所有方向组合连接相邻柱边界,显式 inverse 更新有效;PR 说明包含原因、修复前后行为、Bugserver case 和实际验证结果。 + +## 验证结果 + +- 修复前,6 组横向配置和 1 项横向轴更新用例均在连接线端点几何断言处失败;6 组纵向配置未出现该问题。 +- 修复后,瀑布图 13 项、柱图 8 项、瀑布图数据转换 2 项,共 3 个套件、23 项测试通过。 +- `tsc --noEmit`、定向 ESLint 和 Prettier 均通过。 +- 本地源码通过 esbuild 生成浏览器验证构建,用原始 Bugserver spec 复现:14 条可见连接线均从 40px 恢复为 10px,所有柱的几何属性前后一致。 +- 仅将旧方向判断代入同一本地构建作为修复前对照;右侧使用本次实际源码。对照图见下。 +- 原私有方法重命名为 `_isCategoryAxisReversed`,明确表达归一化后的屏幕分类方向,避免与 axis helper 原始 inverse 混淆。 + +![原始用例连接线修复前后](../validation/2026-09-20-waterfall-leader-line.png) diff --git a/docs/superpowers/validation/2026-09-20-waterfall-leader-line.png b/docs/superpowers/validation/2026-09-20-waterfall-leader-line.png new file mode 100644 index 0000000000000000000000000000000000000000..a5a5e9015a0dcf3ad94cc1cfb2603c506797bb95 GIT binary patch literal 62746 zcmZ_01yodR_dZOFw8Ve{f-rQqARr(qT_P`*9mSBU|?WeS5}gLh=Bni#lXN~#lr#r z@*~CfIR*wPhO)fOBOlDIEL`(P9b;dwGD1UJIys!y#l{+Qr+GAxU9GNnQeb>=1HH; zPQ9(|>T|2z`%oC>|6clR=H6EltyfBL$p2m*8oA4(`Pg~OU*Wfq82JCX>clZA*XeKL z@$yG*Vg36iQu-Uzd>i97-Z{m;9s_@ZCyxd&A?wnv81i~DSj^J@eQ6~@3~K4{1`)Xt z+PTF4zB}IynYfz@lg15JC1SewKTj(t!i5vzq`BBK?EL@k8NLZMA5dy#K=+LIKu`9+ zyOqXLP=FsMz@^YV$Ghd;{8!H(RNxnkn3N2;T)6E8s;RE)gA9-B-8&S1RnRc!YGQr+ z_D$6DN0LdmwUyO`?reH{+~9D!7rPu5vz8#lXO55hr_*RN9)$;AUvIDc!-qpWh+o+x zGf?O?rB-#kiDhY@c?7Ojqt~{?!sXe{*9iK+$j$LGN&;gQ6@qZ$+tFk1jq~-(Onug} zya{wk2q!hApOW6cIu}}8T-++_?Q^gjF1-G;XJfq_enmTtkOsv49bz_OItbNTRN4R zwa|I~7->`GYYsj8**K80nB)mVXiA+xu1*GmxM!7UCt_6fk~1?)&jO=%fA971<-09) zu8)_Q(FF_-4-44zQYC-5Xf7dKlIfNL9lW|@4^6-8633R~54C(nL@fx}9D6UMB6>OZ zndE*95=q*0`lAHZ-RFO0ZXSygg<#qk$ zG0x-d^PeZ~@mF(Kml4!LHU^K(x_@kDyJ)MkCSc$vVPM9$SDkDW?@JdJ(Wj=NDd|2xo4e{9*1Z2d6UvE*uw*mu!Zz7bDQ{zBf;~6` z3%}dVRn|H@ETnlaC+Jd)`MzejfXwCW)#aIsuHGl?<-EYzCf`n4^UPgJA_0++Fl>?n zmE>Tm`;OxuI)03n+%^y@VZ?;86JQC3*bf(~|G>R=|Ni~+-%Ii32j9&%J`J2{YR4$` zi+72#k?6N{?_~1{;o=fe!H?&H?wdh~Th`X5hx&+S_gyN?V;~1=xmv`bGq?8+4}~QU zdY(Vn_fO0E)hje0UFfZftb1cGs41}{d~c(_fQs45^!Uk;QYg9HBWZS1Tf>ys$<>8s?Q(%x{gO8=*+2bWd=Z^-a5(F?(=k%4!*eUy z$j`l|Fq8ijtPDeo558Qn*;GPC{)h$L@&nG{J?nG%pV@vtwS{bZV~vXk(mx86-Ss|? zzkjLK@>7+j;?CCu-gcc%r4$L&9W(06yL0~JySuxEKb9>_rLKBXcyzYp&C-VWgl=0o zRaFRfn03!O?2v90#i-Z2uMB=LxuAqD=l_6yD4f6T2&=V;~W!h^Ayg{}PQz3>= z8AupkH$D~uW^O&Tb*BDVvO9R?!g@6ln)O7U&b%F}3YjVD_y`-H3b=~BJ1ZS{Okbbc zbzI=DsRH&<*_Q|99aV5fva@^juu?vZd}kNleEb{O6mq_%U%?f3SF*Wl^8LeCgg9cV z&EGd$#9ln4IQDnz%@K9O+G#${PFFA8a1QJb7)X_v-4DaU#z(^CXz}(~m^W9i6-i`v z83s#;c75&x288U^t#@?6%)Iu-wNG!5CGnZjS@)#qy7`tDYvo}{NJzlk7uAr|*DI`K zQ&i3m$Ia@1DPSPceh1$z_uaRtW;Les|5C~8E4VV5UK88lcC=-9n9D>`;+|zj`ZbLE zJu(6&U~Y9$D~drEbnb>qZA_}vv-R~k-3huP6!2l5t*};=S5PQ!rhgMytQx#*$Ykqm z<}w=5+A0l!K$M1&9|t=-rUDIb5fBJ?zt~336HfmYUe*dQVZ?DF28%vr7gdaa(tCR zupEsFsS@Qszqt68uSkL#qWz{2L#+O&a}$9}rC(K_%!Av=o<`Xw{LY+UW^&}!G8P{bS(`3&b*R3>4fG@^Dki zPqEHVx1X-@lv0AKUWY$MyHmae@}yd0>`^BUCkP;hK-HrmD1KGBB}mP}ZMh#{5(ZOV^SDm8jF&c{-ycC|Foo zr%EgR5j|x!b3s>g7ImoLvfn?CeezLCO#5 z_>QGHn2t*oUfkp`e&F=*glxm+y;erlw1W$URZCiI7O=?S;TiFZAE%4qk}US^~`?kT&d55gaxs;SQ8AL{PjA~o!XJzt6_2U0!Huj-V@N%(?{-0pR!aETRm3L2*iB((P1zb@z{uH56MgY(6rx( zl*ta*0S6ql_eRxK%e1xv%Pe^w8$<5hWLEfz%x?+`y1FPH#M51OadGkF(U9DTcpNDt z-=EB>8!SR-J>QBz7I!XsAUFCFTH0~tarOnox%|?!MWA5&nW8EoVBu%AWv@55u zI2^qOC$ES4PV;hRS+g6VpIo;}`N-XR+k1Q2eA_dezp{h4WP8~#k6D4e2$sO>9+AP1 zAfXR0bxFb%Q4RuYazpzhS({OC+n|s(9oO)R$M-~xv9jee!NulO&+6Gy)5hKqNMR32^n#3?9HZ(8s6Oads7Qf zCdUF-=m_h-b;sPOKj{joK2MNvn&1}>Fq7C^bx!;0%)zF?X+Pf7B%&8VeET8E$Hn)l z87)3L1p$WPj6!yAV&3-_s0GSoVpw-4b-jEqIpX+)CC6eT=X{S>O+FrlQmTFBJq9xU-n^|4J<?r#JWF_HMSzb)Ie{ z{EUn}3A>Fpu{0~e4A+{RS~<1Yq@qbW&>mPyOJQ$1rN>W2pvyLVg7qOHVa8|ICM3*M zhx-$3FQxz9DCcM5+v6iMC+^NA{q^)UZ-`YF^xVgeM$@GX9OnMmm0}&bDQh!KUxOrp z)Yv^MqeiE4eWZ-NvzTg2v?EF0A}w;m7gz^TVyhhtH%?S3`HAj>gPz+@J0xnGPO5u@ z1zJ+-PHc5QSg*n*?(|g9rtNXHoc2@&^nHT~uF4z{@VBIx9a!1J&!LROtS1U)rhP1) z=`_z*t(kd+B9@)_sg~aat8FKvJ_Ve?GP1jtIX6_Y?wA@`$D$Nxf;)V%Dyq?+(X&;CD_=92Oqr%RojPB ztF~p=@QfC1B>IuF`jRG?87${LO5`Z*PnoJ_?VI}KaC&0|S9RNdguZ;6mSjDgXVU0p=%DAU26k(|y4uKkYE3>+JD~tt!BioU+arawH^|%Q*@In+ z>JjapBx_6Hosw%lf5=2kZMezj+%<$bxvm|Umbj6&xP|l(kY0A;i2U#{r&KlR`Enor zVpSqFWREcSVECb!@^FfaofEVA7~Tt0ORXpbpNvP61it(G4Hi|YWz74vYFZA;69{e zHJH|SJcVsLw%oBJd3kiCDl(90_HhMaQeqZ(k*dGn<@xjQGJ&-%#l1p8_UIAP9lEUh zde4_4LT{xzIq&-~>xLGan5fJei-IFKxBU^$H-(e~yF(P+wTdHsi4%9Bv6ySV6Dg9C zMB!UzV;$>*F{CFF4lB=ctog24u$@67GuzDJ638ApEJnx6W5)4SnK7)M>Kbl^#XXzo z(GvY9)rQFH>C9z1MH-wYBJzoj@2~Hh-Lf7ab~8fF<=4o|Sh1k8$=y?64c&9mU#zZKd5W&E%%MYfJiIW6kp^H z_sPA~l^2Ut{hEg}$MlXnE+?aG8%;<32UV6Ayi+}Hnn)fT91L^OMG{VK>(Z@%VSo*PSYc3{O~{oTjEwO`MnHUDA+6qC&C7udb= z7p45=`nJVI{B2X8jD~UT&6bzBmzZ4e%4^Nsml88RQ1Q2`&Z@vjBKLfe9+NMmr+RKX z@f=S)iI;i0C0K1{O3!{6HQa8_p9?4_cYHUgE}Lk<0zI3!NV)_DVq5`1mY`y=WsE4q~E>T2Vr)$#}Jm?#6>Ei)%NaC9Xic z?iD2y8NzjAM}632@?{0=i7(ck7vneCpX2WR zx4)$2ZhvH)GXzd^^Utj{@>R8+T{6=*_@ePr>1pTK%o1Tmty8o93u34fkN(iHkKt>! znz9MRUVh{ZZU;`vO2`mB4@KuJ`&$?H7GOm4dxU^JFhw(cgJXeRrC0*LSWwTsHew{| zP##vk1^JIvk$n0m3CU*Lb3RMgtI5kHL{Z`VB=^tDBj4tZmSnMLTP^3A&?PN%ljKxj zH%oY=rQVpFA>mE1ah_)6YBNV&vKTC;1UJ1?JcXU2o_qS*k&F3iQ7|bk)~s{y#S#4B z4N2ARyS^LZ}1C2v-QDip5wsA~}^`bri(?zygQx}D~i)l|g>-rPMcuDc#5 zPNhwbQB&kr)bZyk3_;ixH9AtY zir59nzILtlWiXg} zsLvW@tzc^W80@xRo7t!@+fO9_Ub?{TUi%|N?f#AL%j1>+-&WO_oy3Nzji!!6R00I` z{EmNy^~xhN%13g{%4;4gDdAZKT}ykwm2=}n*Gx#Sx?$xR6EWfBm9$jE>lY~0EUn<> zR3L2v@5MOiN0@}skn|^#?=lttW?S*3|?Sz zHW1NEJ?>JGbmt-I=UnKN2^2`6#(fyrmB50uZyVxsTl`M?(I>$SbH&2c>rSfR&9IoL z#bu=r*1lmady222;OJ zH_KLrD87&}Z0s2h5eZr__v9}7wVR{t=U)*Bg6x16BV-xV=+cJ8uHQp78ugIt*hf&p_w7m7cP$7bf1@5z12aIf7yKlW)g!eRXCcaC#t!(Xo`wnxWD_)XW(v8n<%go4_aAq zgY{5jmB7t470U#_w_XWnAO2(=UHRTxVb+}8fBK=6H)+5!C3Mn9X|aBP#b{{zo8b?3 zHGZnn&60KR5~)ZA_6OPZbPqq2UkFkWA#pA0sSO*H(`uj4-K8q!VHe)xFncTQ9VbF$L~M=}CzzcP-&|_O;?Ye2)Z)7k@P-JIS0p zj5xne!OY~l7=ygHE3aSAt43;KZ66|Xt%2XOoCpkmpS0ZLN`R`gv1M{vwSM6Hk4ttz z_p*=OydU)$D)(?gJc;C6j1SwOPdM}^0;!3{=1Te+AR%q1?(PE=7ri}eag?KyrYU0G zBpY37Z7H^gu1d|Z4u(*VY=0!oMh9kQ&Lmo8+ySi z9js2`oJ6^M$P_eO5Xb(_v3Q3JnB(XqlVeQ&^pPbB$>6h|7comA5#SV1X8$UY5o# z^pQbfarY&GWfMi%Ei}jLWV5le$`Tlans@&NLTeM!NnWzVM=~qvc^Yj zO)?y_Onz0G)nm!PpzQR8Eg3xySduieLlefL380g>H(d??Wc@1ee<}T)5Sw>Lr^xCV ztRw!q-5Q8h3M}Z~NkVt>Tx^EBWTuIKCI#X9YwSiBQkUQ|J;Qknn2sAo=}cI@Aj+1 zr~VqmA48$Q1Z_uSaF#Itk?Smvz~}*q8Zh5Kul1K;*3W5g{E$b_v|kP0@P8k!V+IdD zb~l*hKzGP4ftm7WD}U!rRYBL~@?rMquIHN|Z^i!8Fle3vAKf*Ci;D$xjcA9Oi~XNr zV?qbn(6bif9f<}zY>2Pr@?Updwb8R)Z>=x}jfXL{KKyff|NKnBA4Hg^5$b?bo|%YI z4dBY(gZg8rjNoYsG6OwTV6&*OxIxbG|E5%P^}+3RPph|-_@YdhKh*yF?tBG$w;y}doMQY^Z(l-qz{Rd8ctLrG;ZkaAUxitVq>(}%&lFt@QI;;o|e zm2hRFNHA~wv9D_^$jryZ0LNR zKVKbO0LemhI-QtaDw7E?`rXWTL5k=6*JqN**w~JDx+UeFn|eARtJqwWNl?EjjL-j% zk|5U@i`S8UJ;i62;{mSh?nmCelIFo>VZ=Y7hlah?tbc%O8*NHZceRXTLu@@^UTeA~ z*T?@Rz&t8u|BbI`{5yp*`-elGTQmD4uQju}$QH|(Z%+K4d`9WEC9j4MOc4YbdL+^( zHY3z9`12jm+;=FF1!rm~Y^Xrhc%%{}0Dbnl*gk@srCRzOe44vY<*zO;c0ua=)pDc9 zM)2FW?2qeQF_*r^>sOLO$;p$MEP7uFAXkWigrf8OWMAEyiUE-TlRnF3ep{)IZl0_z zOty;TDJDvxVndpr1|_GMzq|G>*5Gvfly)IU?rZOxy$A6MU#V`B;O^PXFj|jgvb@^+ z&P^*B_~T|mFWO5WUNi8&Q59|f{Mq^4IZ!HuOPsSYGn=36t#H06D&oS0ixR!5z$a&& zzc`+YXfsEu9*W@jmIR9uSzTc#+j$|sr(16XCmA+Bubz6mJKq+9G~<6GDWv^CId=jd zY?9Zq6B0N9JUj}|WcQZB0IiWE)lY%qr0%gYlNk3UgttD?=9z3p(mpgaG!*+l`0QhV zEyV{Gmi(%CZ;R+k02Kie32jAwSd@Nip<}YhE&6Pg$f_7|bJ_C+KuB#sQc?2bmZ)p) z)RnZ!jA*8)o2>IIgF>}58jib~F3pEGO?_8xpl0#Tj&~xQ-cjAU6+PSRCpVSALUy-+ znhCMU2G;U-TBQP52U>_nkj$C%vD`B0wGHWV%%!=;qbGYKX}=Hl?SDV*q_1<`O(^zA z-yN@=TjkaFHM`iMq!sfTN=m&44PwD`6me4Aq03rWNZTK^t+)17N1L?gOfVe^YgUBs zuiahke(XMkR*jRP1W=(&lv`k1$+7sVFVVO(Ar$F+A#`+NE|M7{&cVIXNHd-{Wx|eQ zk1DCH!b7+NNQ-1$UCXTmkZ@kGqJt~tS{%?pYRqx{h$F;i{Ko_Sq8n@+Pw9YSsNABb zpLU_Wqok%>l+Tgtt z2i{tlBXNEg#ZPiY>KTP8_v|+IP9IG2#lghWIj4aAdS3uPz6sv=Q=+@oQ^ zydceG4PykWt~KFd5=k8T_%lY9uU=7R{Cn{kRc4+;oYTrZvrYGlUf zI{F91bUMo?o^tZ`BU&piMLm{7Df-B~wr0yxcs({oI2FbD&=vrI{qu6pTi?FXwji*XNkqr5osz+@Jpuv(1`BjHY4c=H%$cdP zu5D~kJ5+wj@*_6a9FZA$r+p)vZW8a}-2d4K#r#ghK}-y-y`ZZ3VT1EqqXOvbOEHJi zCDNhc;bghRt&q9@hD+wn5$b%;&IMNu?p~vtqt3 zvTCAoZQtZ4Y=!C{w|<}uKSD@-4Kvz^#Q@O{)b$1cIR;`072Gm5_}oS{H-mPj;wSf0 zm==BrCtd%gFN~7Ht6aN?y4^@JUt8a!)meMz)@a%Ly=C3lp!c&xL05uQBV~SZ^Gi#y zan4NNa-XWR^Z@7dcgR4R8!#{NL_vKU*7_RlgIz-aXu2zn;;6Fpt$OGalP(!N#oS{%cUUGN7 z_5K4J4zYZOHbh)~LY4b%jj z|9}QG&Uy}+U_$#R*V|}Z+HbJ<{KYst?&_;nD3RcFOH`G}6~hvvRcS!Dj#0Ble@ClW z^CdR#0T1c}Xwd+?aIG5CsOTNbDO`ntS4T3t0yoEouW(-HYZ{!YSfpowaIGy&3PX8O zdi~eURxK-{im8_5ZE4sN6HLK~{kstZpy>Zo+`63YqyX#U8ig zGlkn>8#E-vPB%8}O%-z_Q&mt#QCKgANpg4Re&e6uPThR9m--Ir%qe+meb-J{RdpqD#Ja2=%bDW0VI%+g@uKu zlipqp=4ia#8&QvbZhi;?#(40n;u$jrBN`kc+DUzuUn<5Dhu#X~=ob6~U{lhYd&Q$$ zC18}s&Vz~fG9jRB(%1ePhO|C__k*LZTGUYXKrG;!lvGvaY;0_@JNX{h!C6#O%z>Wk z<~~pu0)vuNL`(kXbDi*zwHsDG=ZXgPZ-1Uq38R;in>E#SyaUZJl;$iJh#p zm9t@>mGY-5(#+{x|CX;V$fOwe1wc#q#Dqa9Ff;%e39mFC&-!&2&u?tlt2~j<0c*Pc z?D5;=CwS#I(Mw8}8=xin^ur?uu(1HjR&jYo1-Oxdkct+PFp7j%l8O56F{9nDTDF9t z7^#HB)4iWHBz|GwT)*|ELAOZb_W9cVt2Q9)iw63dc_37beDOlg%8L2?{Cu#< z_u1A|wQAQ-ApKkG&ypL+mK^o8AfXTZCB^y$o)<~&e{lPHXnWuT!w)F@a`Y}kVY%LC z=9|KrQ#cAvG?5o8(~j)FZ-zsEV|xU%x=0C#A}SuCHJt(wD~H$I0_(HQ_vrk8$> z;07;uIR%?GKQH#!9xOAv|F|Xa_Sw;PNK4CoPW=xtzWb{TtgJZGwJwSwIMCtFy zAAQjIN4?U)H4-Twk|j+97*VE%Fvas210;liwe>ML-?mIJ5%}zOi1WCF9Sy}tXV{T` z4K~8X!nLMlVR0~(ICL?$S42tL7J^p2ZcSF=3My#psAnKtH-=bN@ZK6#ze_3T2U;e1 zD~^y%+x|@av|?B#X*dae+|%z37Bh8j4ry`#xkjRO%%Vb=KQzGE_X5_W?mM#bGqbr6 zCP{{BojDMy#4n&eCPqqmc2Zbc4&0a+t~&5=n!9mrcjP9!U5c;3Pr*grj*J3~lp%M# zU%?PswRwP%eNI+VcTd)G@@2yad>zJ*c#wCwU)eg)FrJ>CzFX!sX@GHZs%*dH2OPFA zA%lQ`wivWChB^d@=0-l4(Cn`b=p+e zv9ht16cFyTTuFid{9Z&~!sizZ&5B7}fUIuss_R!mmx;&W*PPh2yy2y8%M=RJT{nF3 zMRKvhFg^J39_3BoiM|NXa+01P1)+%our)KSg1>(L^l_L7DC9qX>GyQmD#t0!9%-_; z>b5jyBI=qN*Y3~8op&q*6+{amBvP$FtqpO; z4}spH6LFq`q#*_iR4JEkXjR&%S7$OXFkphn=MfDr4lZtq1f5c=J)V{}wC)-(o3$8U zoQjx$v)TxcAxM;t0xJCloTKJ55}6bVJBzEfCrFcxpsYrsWH~O&gJ*L5Z-Yom=bFeP z;xe^-AKp2A#GOqiMHMf32jgqLrp0j0mj0x2_RV*px}in3A`X2m<{avYwMVqxVq`{j z*_oEk0^KjA>9Df1v&Dwc<`*cdsex^VJ7u$%dC&@gkU#ErhMdObgF^KT9K(iOYt$wU z2qfZxDAVHCeA^G(U02GjJ8NZ1(kk?Z)Uw?j-0O`fsnr$|2mTcq3U%Ug%rB0cB(j-I>o1vD0AqaPm z6$ixqI@&MOqyid@YFt;kZxGRl^d{M=T6HXYJCPMRG2qjt9fy2FkeZ-|6!c76s&Hq^;irOt zryQD?(DGz>o4GVlgw3z4SUYMb@tRC6+f~+=e*~`b0iMQLd~_mw6Ak^upLAu5#=+aP z+>a1T&)d?`u3D}&pFeD-KrL)E zBP%=GBHED*oI)=iTUGmn{yzW(i!3}Auz3_pfa5{;c=#ogfyttLLmCvSM)p{*?ZOv5DI~$24Ta`|h-!}8#PmIo>=k60J zPqHx$cSA#(@-R40h36@WjE_$pj{>_Y)>BP@nx}&xc))Q3Ml1!)vomjJutuymm60k@ z?F#3pkzAc-{B!+2<>-URc%q*#231xTOx{t5*SwIQYkc~(;5V0&hDHZK@~`z`-@S8c zo?2KR`4ATE81c)&;;nIGxL0w1%FrVm66X0;$jooyxDN3>Ph28l5M&4P-6+9wih+2j zficA4M!W;S3G8bU9@^$k+^dO|hqvSiq#WlsLC3`_@J|n#ZhwF3_+l`6B^l|I$-eSV z7hmD{!|lO*W89IqriLqB4BS;%MhYS+Z#hsUG@GMcC#pFGcXTixD7D7oiNhvnK||Jt3$%B#z{xzc**I%_&>xs9?Ce~r>u6{)Qrlsie&E$BA7)C3B&>I z9LTr6>FMs;F;~;&rw|BfTM<<6r3P`zAN*i5IVmpIcF616csu&_3%HoTWU#D>c5B?VmlN zf4W+u?PCL%cYFX7=63+eWRB(JuYHfiXmof0#|fq;dhicVPJz%jJF6An2L}<<0Rd7O zT?fR1U#=6!EREgv@{S?pfAu+`2_W$qbp?(-Lu(+q5C;XSg^Y}DRa8{$RVBT875U_A z9D}5!q-HiVGaDO|u(0lHqCdej_{l2|&H>@|LK=@SV#r-8EAI`)Gi9vjtggF@3XeWK zrUv$GqS3odc@!YgCxf{%?8Y_R4&xtU=jYA+4@dP2{i9-N#h^DhA89RsT9ssG9nrvZ z(aVdSASNcJ&qNpW3_kHFH8Xlar7K9J;h|A#y8xvLPcqFJKNE2gyuz|%; z319(7Aa=@5IUuo5bhI@Y^1acU2@r@&ow1)Q2c%wr$|0G{Y2X9VAQqrgb5Q8vv)^}D zU5IR%^2Ns|Ul+qDP2ojFMUm)i75aj!lDk%qOAJf7Zp4?Udc_e#QfbE$)+wf$F~34d zu@{D~!A;wz>D6TY{r&UA#cca&0W*mKs$qJxO;ZH90ZX{^>5MmB*s;)tErwbMN4G=| zT|1NP|m@jOr$%fkx((~NM@n#$mP` zX@nZvvkO79gD!nTBO>y>cV<-{)8dn}X~@rg3SjUB>ZmY)flZ%pu=s;Y9hGq0e~$PX zI;O1ed@(f(Feh>7tBGf#uD_`MU`6+)Paey8{ua^b zz_5B?xb;1VO23R%Sqg;v(!5xL3Ih5G!zQ52NuS5$H(=*2_^F;2UzL=7iUy&Ubm5)T zlasV%Yx0g)uc%PrQSnlz>_Ckjic9B%0m__Y%S@XAhY;emJ+<&_;d7y23^)xF55P%x zZej;KoR$x8!UO|xEUMY?X))5VrxS7a^_{;AwT!Ld?dn4bX=9!5<-2ZuDfYK=XMOQ( zzT~Q}ou2TrJ-+hhe1zF5lNig{q2r>#D`8uXRc-?Wpm^p>c5D`MK7W0t*UAMJ1Vy1B zX<;|+M*&1vrFzPyjqIwF%a~V#d2#@gis^lLT-;q|(x~U0{+9PC?QGzgGb$Sg;A2I3 z`7f~}O>D)EU*m2gtw{j%(4yh&o+Wzt;0MY$7@fcz1CG%AI!iZtLaJaw%@D&+Z}97~ zuw~%2Prp%UUT@s7;qUB8B~0PgL3Il%ILC26uDKaYGuHM@Q|hg3^f%w~C;Cb6)^<$J z+&1=ZNC3C@00n2|A#hPrJNgMsq=ITDTve2mRzce|s^<5AC)HJlhuUw;TY(vkGr!GqB%eu7 zMK*d|yE=0tmP$L9EWElylDb6BET(BUR!28g<4`!H>g$W<+J=cBhEm^3l_isQdEW0S z)FgRx&`NlynV{z}e+%+OG%`9m*w>&Xu=z)3ldnt$53GmGY9m;b^xdQ4U{GxEjue#J zS@n?!E}5?n<^kN@q;k`DQb{{Sp{q0;AiH7@I^arZ(X0K$w?YK!Y70)!jPHR-{?2n( z7{$G=M1hYJ<<>=_!C*ywWme}AJEVD}B6O3``?D|LYU2W}{co#)MaqxvdqPA8rGfwCFJ8xjppb z+20K8=nA_MR=>3Qip!2@NV>?z`o>0@qG?7lKM?nzY+e|FsyZKH5X}#~s}&-m6&*~v z1O<>x0AM2!ojdt+fjVU&cdXGu6%Y$f;fgRlK|4cSG`hlwEPV}vnpT9CQ-gSE-a(8S z5btNmK7Stm?yR*fAMd?^DUU#;SO9S{XVT}7uAY9Fl#GPBQE2n zdhnL8dAvB#dFsru^`%=6XeBg!Fl~M}wCvX@f#RZJF(b^&%R^G*O;u-d>AnjE2^{H6 zLQp>x(*F3C_%VO@hs%I-3L7%UBC)YQHXon<&7i+ z;Pq!V=8D`+x=zeTm4yv>LD*sEC1iHCASshp(hUx$Y;->T<5cEzZgH=a7$6A^x30d;+bl|iXlHI2}Egx8bA zq4P+$(iG~-g;fnA@KK-2O6K_==wSR5kFp}j>t@f1PF+^AnBVSvuJoN!eZoJWYetIt z!qWD2dU}`9YG5CKa7XM@@)nz2?~s9wgXAX=>Wipn3ftm$ryPEj4A{}KpUNxz#=vj} zvm5_tJHWK-0Ck`muDhbot@3@alr&Ic3h(jEa1=ne6w}7$KgS}P`fUHeX%HV_d@Tpqv^o2{E z+s>pX*dIwi6y+9u%jNw8YL7rNO?_*h!R|OeCK-MAs6y2BaB~c>)Qxf}f{$YwW2VKc zM?8(mx?g!TRBa4L45$&NNME3xm9RT4m)VQ7*! zugyvyjX!}#q1^KL8I0;Srfx~->b*VTclvEvCR2I($Ni*F+Fd{6!iYoD7j(Y?T6f0T zgBGyQ^4kd5jg#bEg|A*Oe|`F>7~B*lLrbul2MA)ucfngBgOdjFTd}Y*w?|PDU@O+s zrO%|8Hlzm+@c>U!9uJ>cv!|cfqaU9)eE{^kOtu{ukTkdoSry+ zzXqfj^H?D$UL>3gYG-^8n{W2|_fYIRq>p!>bV~gh8;DY4Hc#T7>2Dkh55&%L}{kWJIBA%%K1PW{nT96~e zk9w{t+(cG&fJ~cy(1SRR7{mdt5!yEN$}oB?berY7`2V7g$R1!;a&jnY5^+S3!4B$)fBrSAt|YD-%po^nBQVjy7+UM zN?Cxs7R9R!%1uH}+(50K2kaHL#moxeistv^fHD?tjm4&!{e`QnDYz?xCTBzpa2jpBNNlY+FAtAkvsL@nGrzMF56Gz}pg2A^Fsli+y+Jz5ww@=?$)flMs^G&%bpB z)s>X^JoEv3i#7>x$QGm4B)!d#b7o^Of+-8~E4~9~^mKMhE|J&7LbL=_@ zb98!Wv9Pe@L;r^EN*J!UZ~$Fo17raBNmQ8eP{;bvTX9j65rDvDI2}o&mGMgCQz{6+ zjhk0#9}SjwUk18IxvA)ugjY-^fh)~k+v2@)?(QnY)TT&jZ7BHI1chnfiM9Xb$=X}3 zJlX8RssKXwD|Nd+DO^ENDl7BoQPLEX#rf}DhnupNmapBJ(SZ*Ffp}}uD6%?`Q?{IS zF&HRX#4dhD^)Lv^9toeR1PUQ}RM!4X{tm!JPckP}q2;OngRAT551xf2yB7^)_GCHj zp8on~=f8WXX;5w@{3$~Kx24a-=J~bR%b>W$maDUCI-jmaDOP!n>_5`6CP-_OB4bHQ z^vgbsZSt6XqJ=KEnThBm^^t$N9Z~$1LCgHMmQ!Q@GXY~Kl_@|GZqv!J_Q+Onlem==o$~IA~cMUGX01b zjh&xkhtv~P+Vsf+g@tzQQ#wI-Qh76ciS&7&KNQ{!^6X0gFp-@9b%>)Y2#11 z4rXAt;f!*q0D$`j0E+cz^KW%`NlB-rgKcO~hJdcy9W>_xKH!ARRTWn@kpJOB9Rb@m zGXSygsQq>q|3U^M##EOAVVBy;Pkn#!6TkEGGt0+!#j&d-wlmXH!oA)zqJdrVvVJG! z_i5E>F_{yrohL_%8FBrPARtz?|k2C{s(b47+?RKaDSYMgM)fN z;u7QXa3Y|NHV3Y|S@TZ9_t*XB5;!5avteYK_pwMqa94Ty8xL};;z`7-oQXr)a=W93 zWoWMnJ6gFYc^^7JUu$++F6!U6>?|YPJsB5rTb@v6aolA1>CRZ?nsvrL5gos01E~ri zsd|I9>Of1@8H!I1%V6u~x~&*Pg#ZkM1LF^F;u`Qh4Ve_)w~!?n(>cJ|2R$m$yN)hu zE{i%iIucnGJ#JB-`@^z7^A1K!QPJEZf<;2@*|AF&zmA! zc5%hH2l*h{$&~aaTkHQyy~HpP^y^jkKCdnT;0hI7wG4mzq{^-l^SBAFa#vNTu#d~o z;y%0iq1E}pWb}&Mqo)rZ;9&LO%wNkVw|pZ|1Q%hewe8 z8hW33%r6}s#p8Fnov_jn$Y~_P~IFzxd7e^`A3ja;x>j13^rO5`MWX=zmUsfuX!WWgqto4A65R?&2=1UW1 z-K*l4YPE$4aS<*`Ow_MoFh6cg3FWl7p&sJIZ#BS)3~hyP;TE0;p2W8#zzu`A6_#*3 zVH#K*OnI6E(*oslS-IpW+oN9Iza^jYwPO@w^*GNlrFRb-&!>A zOiK!t@=G-G^y$YB=LMdAW^a17v%6jLY-1x`2%nO&Vm|evnpUmeokJ-7I^<1pIbONLa~OE&o7_GLD<5s1WXio!<5C)w*& z!FTF>Id~|F%53$v<9K6C9{+%?|KRiWdGe(@)~8KW8VJ)A2kN^VA{y32a9%SG|F~jl zX$9gHu^POfWd}Bz&`>>e*YgB!R?3jFKHdwC28`z(iYD@E$Gg3-8814IJMDYgQoBfJ#I=tD)rSje2Dd z?^LPD%o=-e9%efD0z_<$M|H^d#Fv35AvoNnd$<}|tFDt(s+`0)FL-DWZ>BdYnBvR*pn z_87aRSXxGh7K0tZ#{h8=${L%F$>8qmTL=ohAg`#X()+f|y zl@SYA-HVap>#@FjmJl`iFJVXNd=XKOOvYEq!_~moCY1%r@$bAiSI6xtzG%srYRKFoF;`ngHxApyJC@uY9%zK~E4;b+b1QC_sEt(oTJI-IGE^Ugj#MQ9h!r9){MMwBC$nw-1jY1mU~KPK1!?kEUP zN_&{eZ`DVyQ*J~9ut~29h!T7vB6(m&K?WQN8DXUbq=~>*o6mzHS<%L($VBk?#^VEe zsg~{@GQNCD(ynCK_;|G&uw53jS_%`iV^rg$j6ok-hZCsr3EPXn$)A7F2v07~tfQl2 z4kAg~Kzvh_!u`OSff%=&G7NB6dLp0c%MdU==YSfSryLXt!D0N;={XS;Q4<=2;z5-R-6 z_wg541VEM}Y&N`k3hvIaQdzknDoMcF(PU97Q`(gU$i{W6(S*dTtiX_VyUD#i(lFky zFHx3J*K@rd=gYZ%exs{K*LZl~O-~$VY`Y0bD%TOO*_l{BKfhC+V+sPG52?B~kEB4T zB%PXr0tsDwwP2uBpKohxD+m1PVm@1y#l#%&*~hWR13@alW=I6@cqGOOHWi^#Mm*fF zD6YfI0ms(jZ!R$wW>=2IPhUXF`C$8--14aJtW_TN_3BT&Ey+MVFRf{l7RBnu2iTDh zc(H3!*VM7RS@F6j2etA066pGr8sag#)Ix;dadzN(fImdh@dB6zm5t6KRAi+hmv!hw zNu8SZMJzRfA!mx?D1EG#VOo+##UA}EAsIEpY!QX2*- zAWam7XZa#>b$kqVrFgscgXtO>eZop#eVwce-c-+j#I)8tvP|AwdtS?vavBIAXG7ER z-zRQWW6Ls;f~=+uq#3#%`@cqLvY|R9YdSorkLsO+M;C;0VR8FDX_&|x76XDwH9E^q zSqQ=yZp8Q9*$5P)<)yWR7Gb~?>Y&iqLR4N4)(=JmcHkza3;|emNKw^;XXz+I76u<9 zWViO$UmvLzn8kvkXynvy=~r;cT9Nq(ZhHgkEN=DII4*hk!hIQsPbLVeUx@vZt&v$g zbek0v-4^{}D@#-PLXwi(Uu!0PJWLZ&qtEm4BV5R7XmEa3`t5t^zWV>eEN@t!v|EyaO)!~ z%$i7EpDFhEwASLW8HpGFz=LGsVEU|K-9tC#t}E?1<`w7ZhnvDxdwmTWe3%~sT~>1c z?BbiMFX9N8Ws4(CC)6GlCaBY_&^y?SBl>l!{%jU4Q`mS}2nB}{TEuv`71}1%L{nl} zQr>#6GOs~Si|EyWRCB)*1Ox>5#Ki5ePQpM+Ka$*qDDxK(>WoS415`}$sldZFs6WU< zTs$8c(rGDTD@DInKGb4s`nob&!+I`Vw1@r92y>>hMz)0WcONEF=13)U0IOv->N0ng zp**5Y?#ZQj#`(^(>-)a#7rE3c-tv=OfC;^GYDMr+<3sBk#p`C-M9 z;`V%nb4(o``vXn>c@zS?SUIuD&CU_a%HDix_f}@~@U2#jt5@4jO91^!+t)eo8DsR)Bs`Ok_s0TG*=wtO0y)zdT-?MzXboBF6poEsJAo%On5Bgz|+VW1;LJ_2&;Ua7?412RY+hd{8L_+uapJdq73TqI=xI zcSiJHjssxW2d9LJ&(dCJs-U=D1cw8 zgZcZ{kHAh6+tP;T=hE}8ZOz`Z7 zP$DU6gvn?#3Pp%$#?g{}$57f?2!UK<0iS0~KmBtO{remA0bEIUcC727rZJ_n0G7j7 z%lQJofy+xQbJqjLm=OpCU(Rw^Ue#oq6;+4AZ?A|E>x{($Lzk1(@|Xdh?nQ!U<(YwW zKf)YafdjpW7oqzbpUshq?OgYrxwUGP!-`%$fLjiOi9IuIJ5V^fDHl^HO0rc24H! zt=UGq?j3RL&1VSUV9bZi34B80=Ddz*-p#q)A5E8#LmI#v(>9>POQD1`NSD8Ri1eqr z=l%CWZzZ*Jv|CNGj)XnPCt-yJEN#%_ZpI6;PcPp|^FPjg=Rr`ah$lxthLH}J?R+e5 zU=+O~_0ikQ%ZMoe@X%}row>sP&M()G(Fq$6<7u%nUL)o_ivj7AMD6YE4=f+`xxSUc zBO{wOQ`e+F)~h%hVm;Y>Xbo!ZL#;cTv^H}WckzLM1GbT!4Y#$cdSUGg*3!wCT}$yR z8Dd&RjZPEKNm%{1*b6nXN%{Er=y`|NKPGA90Sk;!)5Kxvl=B8)3`7I%NI^>*wz}%P zJW;Fhp5JL&5>abjet1D^7+q0UI^pBP^LGXl&$8ea%-88=#e)agt@A^sIezX#E z#`kyTZ5GR$Q^`e;p6KK2`_%F^WL9Zz(9Og`RPT+g)j8UqTrQv^ z6!Y5PzJBAzd-br3uAg$iBUWTseTv2NBgNMCcJWQ(bkPZcdsi8*gT5K@&4e^p8zNd~ zcFl~k z`tubLnwn&*9?Os;RBaiRm&Jr1DS3 zH@;84Ajb<#L11J}{j-ly11#S9KHm{-%NHteqjMIB^bmUXc>|Bt7Q8j+Kz~lK#v%~I zMgTXz>M$a?)lT|Y6i_F_LL@~0UGIQ6?cdU2wD)&1C$mI)?u5ohLf`S#HCpAqyRqx zu_P<#eB62#r9T2H*?9+T_wq=g=B|3`&F?ag+>*xdpd+jFB0gP+ytOoRZu>NANcZa) zYes!&c@E3cDMZ?L=i~WKJ4$CBM89iWSHw#| zEsR-PlD!#dOj3I}^VO~GF`d3&A;uz3F)I@JF{FWR%hTTcUCY>CRu;EV>btjCQYt1R zMuk2n#K&{L?(XZ!s+s*}%#g)W+gZF4m_s-tW}sT1pgUXqM^W$?ZD<8#R~>C&(VchX z%*+n%kBP%t!G%2YtfHb~uQD!nM@LeE$s=!TOpIWXvl+}u0q3FMbG|{}@JcP$ zaKTH=YmXY#pp6M$KRu#+G`p`0T<$Dy|nEDg9LNl5}8v!<#a-nCI(%Uv9-+U_Tz zD{%g!l2y1YyQx)VEb-ZHgts7#5HVusFk+eF#SGua&UN|R#l}ec6_=cb9o7ph$57lP zQx|H?4@dl2RDiJrIdZ4@gR&r2F1A3WkaWA4iZrvXOehpdj&YZnegh)&9f_$#tyYCc za#dCq3+QH8`qM=;Z;vBN+1qa|^!O87|BtOX9{U%>)WyavvSrIdlOuNe~sqS^SA zl(4?OKFOK_=n4ZuP*zp#Njgn%^%F=xDQ_NK-UwT>89aDy*bAs}p%K;&_*-*c{>UtL z0qZ)`q)QhwLPye>tA9vj|AN?#p|Pt8_9i&N=ZYU^!44axVg-69Xv1Qa=vTx|IM$Ou zZCxlCDY?5`?fK8?kcjaOmPloGz$oT3va$s+-yJuwG`EUhQ%yj#!OG7Y>wM`EX0aBAMAN@o;r0My5WTl zhoIVxh=@RsRo(oLG9WVq<2`(m1DNnqejsaw7&>G#^2Jn542VTJ8ZC*?J`zI~p;%%w zNCJ>hdW-dsuX_S#=dSVVHu-GdhFB&hY+Pc5{Bnjs)dkSDwt!;xvS8J-T*&l>6k$0y z<&rt%1aDlwUI`cw34%}Tl?#7+>PqWlym>?yfd50iAW(Cu#Zp!jG}o{#ib-I;n!u~C z_}X@UU^ywL(T6Cw+W*t9Co;fxv$B7^gyo1v7oL&^d&*x=*ZYOOK4`wT0c*MnoUeXf zVWt1!0aL{pSSu8t-eg7t;JgMn9F)An5^zQdYqwa`eTnDSy)JLL{wQ*5BikcJ2FEny zL3*jE{Spqa?yvDRO<}3lo?`p$0vEIUHE6Lf(~ScG#9!ym-~H6y=d7VQK{@+vakpPh^(l9o$I$*zfH=TxD;;op|Zl z(?$@NXtS>sW;HnzxTMZsMu?R9|B(UMQneeq#J?g@ilNWVAVG+fNYPtEC~*6AEcT|d z?_y_2xRd(t|DyYt8jZ|YpgF6j0N2F6d*%V*MVCjf(O0zG=I2~#-%nl9fL&Yk<8oyj z;z?hd)fBEh>eZf`_-)ZyhEwOZt(w&$<8y(bsn0N|2>a6d$FYatzGd}GyJy(BLrGc9 zObLC>xo@|c<{pnlujXro7tb6jT?#6Ew3L=Edr!&Z@sZnF!&_VV=+-lT%<2Y-44D4oSd(1PZNEy>l0A2GHjm z;`Px=ii(EZy3SW?Pb;ci zxi{)*>*(p6h*K}$hD9Yo0rL@L*vK|MdOYpIL zi#_B0kpVUNAyBhil{+XVF38mTKp^(xrm2>VX6>oHo~?&NDNjZ*%x8u?4$R4}ZE^gb z{a9?UJngQzXny%++>O)M2P*XGh`-Lr7uKH z5t{EzSfuJpG0fUKY#6xDqU>XuVy|Eu@|~;3-eeUEO6g~8*=yRx-Dm~{A|jS&x+hHn zJeM#H^OyGa(z8TnJ!C!QOK<&UJ8j#kF{v8K{r(QymQZa27+?CuyD$V7H zRgCeilxXX)wP$SpUZxS@DfSzWbc(Oi%lJvk$;-#;iyrzy%@%)|W|8I|*l>6Hi5ah- zZORNOE8Q8}a+}Gx6%iNrJQwf#sh)#G^fdx{0H3tXy$K*mghsz+yQ$SL&KwD>&eQr+ zUv$(7Z|17Bi7UVDZk7qZccUu{yGWBARV5Sn0*g`fN2|NgK{M2Q!-CilAM!jz_T%1u zPxqIUmL&;I!CH6wP-!Vgc`K#DhhwYFIc9*E<&>RsdTJLn&x>Igt)5%Cp{CW77%)Kr z2W=Q+-{kJTTAzsQ9!|i{9bk4z2^vm9sm1^qO)392OeF_}KWfLC9MEH*h*C`sV3Z)o zFtlP5!hilF0`#l9Kl`NPzYG|=FLwkqPQgOacdIXFwiKfKNpV)Y@Yy!k&^xEbCxeo0 zOB|Z1M5#}-R_?wkCmDZcA9Z8!F~zJoF1ze=338p#Bfcbnlt7aUA%>t%@Z2bpIARz< zeC2G17Zl(C=Ks%cdb3ct7fQ1CJ5egBY)yJzsXU<|8+z(=cx_L_-7xMlonogXNYaX9 zX=_(Tt-%2b60)2e3{djpmX0{ImE19YdUs#MZDkVIsFCv1Q5oqdoAbIE0ZD#D#d6lw zYy@>u2#Wqg&A>55gzRIQkFD+u6IYZtgJ(kO$8yN@lmsK|JPA*^VbV^K5toiB8H)#< z>aNEE)P)y{^r^6S+=Nof^FEG0w~sdMRw?*joj@RjKrD zwj)^XQ-iOUB9ueRJ~z%7_=9x#J}=VM+u<5miPTzMB^!zjx{OPr7|S5MJ{bNQ{!b{J zWjXxA24P1ausIXI?lE?*-ksr+gcWpri{p5aW1QU>qpWwZoPiC_7Si{6V9~u+$lG z`qs@CRcXN0Z<1FUJTI2vfBw*~b!w5fc@O361QHLln zSTTFtO-Greq6atZ?+>Eszq8&G(9MnJFOnPFNUAy3HXuJ%!(tJVqj#IV%#z*w;3poZ zPR$yj+{V)*sZO7imNt7lu66G3k2^xl++OgF5RCL3(E++&Q$R{EMM^^B%7NG^Y%0fek8j76av&2M8k#n|=1*xWVtr}LPo|$_Yi2!U z*ko%wToZlt=+RfollMl3JE0uVlOKzW9lz>{P+gQE+5GFOK<*|$>z|g z2R)#YEl-o0FpH!F8A3k^=?#P0JI4}QR^Y4q{-NYM6Mk1*w!$~Peyw^vF$;e5f!&lK z7R}k@wiiTni;01#s3;6*%uG?$d90lT?>`b@12pBxqaUDq9Vjyt0$C9bGI~m<0RUys zU=G1+-Y7yE9(3#DY`+q&(w{JsXbtAdFhZ)>*N1qN1B`GPeKij(r>UHwf7850t4Kx)2F+=3jpxw)D?S+X-~VO~t^Hsz zN=w>SIB(WKl{OD7wtkf$$F-j1GZ3(auUBRe2)xp}3skaxPw6G@@|t!zr}Au!xBt~#|KbNi)}*w&1_2<2TV#L#?3Q*6 zs|<^u-&ouSPyi#GyO_&-NMdYUoE~YI>U|z|K|xAHpbHW@ooQ$@MnX^;9dz)Ho)-u5 zyp97H2YzK~ZQV7EHw6}&mgwNTq}s8a?l~1aIN8F*M!`=fF4&Ee-*4k7{_;%fM*}lQ z7K@el4}&}df=U5O=Q~(4Wf;2v)bPP_Thr}?AL9nP|NEwOWT!R(v+Kpeh`BL?OB?^6SJnw5R3MY_eu`W;!h#!j<#Fq?{()CxE|IL_gXMIMYkgYPZaJwDjBy8I!8%as%mRb>aZ#J_q`Rsf<9Y{<(Cho&(d5?x~E zv!)0Gy+%2C(z!d^+tDKGJ{yCV*muQ=89ew9U(vBn0?kAYa(0pX*FsPmhzQh7DaZ>p z$R)@*z4P~Es zL(g?)BxLBdhRWsY2Tp49z=Cegf6K14cx~$=dV>^Hal}$_$DM3JQuqh%K8iNe1kz z1-qdtwG1Qljt0)ahbGQUFRG~~N*WSH(=#W-*A!6iJrilGdv>9QE?X#6)SNNWea2^y zy^X?q6YC9qu;)#|v$8BZ{qM>md;9P&Uy-o3vbx?f^nPimSUAhmhd+zqZj-H(lg=ie zm+|3r{u3^zkMHi~d~a&Q;dHS)9?kYm8w4#hQnf?!XM(!VZhJ>Y_EI?o9)mhp5 zPndc1$|68WVv|}}&5P&#r66?`6i~$%JcWXJ@5K93fMyiig|~5Aux z5BQD`4Y;%3L7Rc!!#WpfhGMa0mGw&*!s1qp^8B;E7iqmJITIn@($*$Wl0rn#3Kf`| zYhfkC!SN)MiI}Qcj!gTnZbKZK$B;Wj*i|5{dX>&ELZA76?V1aCPv1tg9c42au3bsP z&n`T(qY3=f&%o{3B-pt6`?vgU)#sR%?+l#kKlE$%^b&nO-;VH?9^YSwLrGBn(evoM zcg32Q{Kq{=Y53ee?cq5@QEJlQK>;K^3R-QsBH8y13C;cYYm6S|g!GgC$3<9v^@X5_ z({x#i^S?$yG#|3z-sCL8gBQjO4xxcw<+^N^I8PpTw%YYYIn5^~{8oog>1X!0O3(N> z#q?4e_g*&49zU7KPRb;XJN6T;T2KIoT%&x1{RhqSx`^0$@vP|lW?cE&d_>nk?qyeA zv&IiL$<}h4B6W$*G-+vu9+uAL05@GlH-@C8!EShw7&o}&EYuP0rcsyr8Fb(OdS9v% zztgn0Y2Ej*nwqLfs=~e;`7u)A(5bvwM zhj$qg)sensaRIT4iV8A$Qmat?L{f|b6jtxE@L)r*DbTbZtHPN#iPx8UZu?%fcRmf} zhN!3klK+=K zvu$c26RRUQI9LlNfqHm*({Wk}@YPngjF^T9kbl@Hq&0?oQ3nN>Dy~ZtOz39rhcbSs z2rl>k(OGy-0^GMWeQ8Z73HM9vJ0EXtrJUc=_cu0j8f&14%Z!lyS@`RH8OF~lzneby zZ@{A4A8iyObfw)Z{y>}F`=INlNSpQHzSeyesCN09_!Nz78G7iyjaA+}&Dq^ZbhXg# z^Yc;0JNVIuCgJ@PcNad7MI%&(rD5pDqiKvu=n-$F7K#d&Ve217Gz3f8uoCv~Q3wO~ z3R@93DHhj67(i7(Hgm79k)4!g$8^8@B_d{n*hk=wxKXWr*nld{a^Cx=4xG=-cMyYQ z+{($pD$mVzoUuL4CyOiiu?)kV%(b<_4KA`NCyAF_@x*KF0x=E+@dnNO`KseDSvOL*5N(VtC#LtO|wm#^R8PkNVId6 zJ$OY=cRFqsLI-mn)ViPfHNZOi*Zu{`ZVLA4bZ-3kI1(5%W-UE9>kUJMh9hETp?r z414vTl_UT%DNW+|F%E!&k6gy0BSVO^;q29L;^Dh4=Kvh*@`Mh<=4>+xRbI z=dW&MYpGs0P8}j%N;Cnv4J~QI@Y{oddPM^6x2IH^Ba!WHz9s)F=PWLY=_V_aq4l9% z))a;)#%9$cf~C&DfqH8Qr!tpu`#Qi-6*C*`QZYM-hd2Mai=};c!A!}1`C>kHp!UAn z4tCq7O0y|}0zET6m^eoneV``b9FSJsb|9V_hN*MEZ; z;pd7_(hJ)r(>UF#dU`b~2~C02PO>{&-Ppfpr$o&avg=>Y9R&LF&$Wp^QpE zE0-Z_MVpNEKHoJ2XL(?ZO2P{DMGsIpJ&@?>_lJ0k-TaP`V+2L~y}WDKf9I0;Sb(Cq-(^ZTY@r7yq0yQqR8h{nl+)D>VsY($a_1w&kq#N4#hx$ z%YM)0nt~#UOA2epDVr4aXGd{n$MO;&NAjy#)*%_@+>jK6=pvAO7^3bjHPVa1kR8Gg zPfVk+@knPOycw;o9;2evBl&yMb#--ir2`fEr%x9^OvuUaGOu8YggQ`*srOx=%n7v) zX+~Z-PE8Y3J9^9Gt|SQ8>s#wI3KyVW3BBqK!+*DcK^1^r7FcsyEOJwj*~^e-+8WO; zZ^1vAOx`62ZY2g$$C%1We(?3(fasBuFv#4?1v$UX(4)wg$E24sSaB;)E2`yu_RU{i zdC67}mdtZjPUjo4ka&+bnW{s9vsd!_8-Z9^3ThTT8=&!Nf^PcIo*^$k-{JecWn;v| zBwU{ZJ(m)n6!B@vzKn}hj3V~UP^CQ1z%w)y<${a|EXY;?TN?@{nRGybn*44SvYWS{ zhZGK`wl7wSG03ZZRFnJ~xEPrAJFZ>SE_nGl*(V1+lS`nVk4u+G$-{18zLe<;pS`p3 zKiVXQko2EK0U#uoou+2rWs0aqTOztFXo`g{$MS=HcVl^sD%)qB0CM1t@@+s6eN~9z z5%F<5K7fM&$$T}!x=z>K8F~AI(M!+Ykl7_LcLEwv!mL3blXVob#e+c%Vb|`E_=4X3 z1hjx0c;v6a;`_`6Im9H>vRp%f%o2AWq?|`mxAI6eWcDu@)jGyPBf_{ZwH-A43(x?C z2yythYJy}jJtH&mbYq?o1?6dr&WD5VWA5ZMJ>eF=8~q*G z9eiQxV7>FlB^4x<0ry+9RwBYrQU`WshUdW};Bj1$&A_Q5$U|(8_7UK!)$xJOrma$7 zA7}hc0;7XG#pq#aysFw3=!pKjz;*j1pOY)OwLA#jDFFZ0|7c`{f#0t=-lCAeTtrU7 zS~t9tt*$-#QF-IHA5>-k2#&@v|D@S#K0;aEMeFEL_XXd(cQjai z5$!P_dHVLp$P6)jqh~ggwN;6Kxq#duh;VXU61Drlt8Dbj>z9rfj1ql%>)k0}rb|X7 zKNM-n7eKVb6C^mzC5~qTnI^6ZcN3NPO-$D9ry4{Np znF~jyNRoEhSp^uk5lG2ZX}`&7S@6|*h6=Ps)Ems46`slFMy~Qnu_*}Y1*~RTmE{b| zv-}2(9h&y~c24~Pe+wd6uVaAqDH6l22-|i>9ITATj8)gQ#dZmvk3MvL686MQtrZeZ zY=&U4a|0xpMC^RV9};qOEFArlcEXoWF%6zElSW7#pyNC1d2!>b3uCL?S+?dGjq@j9 ztxRS#SIwLfZx1A|aYO`}*F^h&(#<=&&(!}czmx)VqN!fs0PhtF9To-_7EvdTD$l%z z>9y8SqWD)xy_{4}U!l^>g9c9r_ z55N+h>vxrFS9!XF3dz!GZUPH?e6Ry45H%t_ARAtc^#^B7g1@Vkg#3j@mqt6fko!5% z{DArj2VN@PXouLS=+yaygoH?ruDqw$`>pm~*~xr5XBLWk$F5|b^7hE-5lCL|qMO;{ z9As))J9x$P{wH+cK_BNeElL>Y5t|?PQbAW4T4AHe%mC-ow|EjqgF>Fbkc|)@rO~!` z*bo$g{$7B&F5WdEQKO`)$|D&o2oZmZC(Oiq$cZ7%pXw zyRu?rllqkjyaRXaTp!=Y3C5#z#>SHR!Tg0BPj2DOJy{W6H*Cx0lZfDHGWMNx_vMg3 zGUe|IM?c!wteSrCQDevCbEU_D4T`dYNWc+TBPV_J>ALN4f?L>LBPl!=sfRma<)I-0 zjY6LVo?XtB;ZmwB-xiSQKuaaG&@LQ zn6Ve3?+HY>t8x43}cntl$$T>=K0PRV!w4v3SdT%Ea!6ek;*QYAUYA<0`ea2 z2V}1Bz9~27q8J$dfYc|{I{@e6=MrNcUMWYUjt)bZtqBjF#pVumOFEFm!}iN8jX&gi4z)$T}Ra zImk)f{X1x-Lw)vX7mK`y*vzV4-{@4yMRD>;+qyB3)Pi>tf}oc!C7y!^i+n+Z@n3b3 zy{)$S>67p%sYqybkJLr6(9eifXtcKa^UX(pMeG4cv;MeDl$)pU{}>)`i~R7`)1&3Z zaZQ7ImXnJs?etW{&m*xH0-R?1Q0?a-lBtiw#?T#d5M8hF9RGY8)E{UF1^A7**3d#q znZrG>B}uM_AOs?(5NNAILPFShd5M3|_&42_vq`(|ED0(YPS zW3}--JN8Hfc-LD0C?SqTg~MgAZ(L&T)u} zGieg+lxr|+oJ~Z8wp6dY6(lT|Js}?~>o(8FCnKEAf5ZRcAyO4W^$@{W*2er5sGug> zqbsCf^wB+GV>mV-mW2Y+`0}&!K*Mf8sQ38Q?ig`?u2!8n&)@kb^L?Nb>KUv>te&9z zD1vK=11_oPBcwz{)zyhX3}5Tpw`Be4qFrDx)R~TB26NHmMF3FRM>$|epqSHwIq;3U zRM^aBh_M6SN9#*_RZmy%MS`x1@vQZIp1sp;hTiJ0kR=Lk-ZE|H4@$F1+nb?l<`LK} zo8~-MuUKpFtjoK2B(po%EbyMX8hyG zaAkA_Y7$-HKJ9sF#gNTfZHfl36$yL+RRzxrz>2w`I54Pn%v3SiL_ZL}Q}XbiL=nM7 z7szeH$H(V?eO$#Itt}>4Tk*azAMI6cjN_#giRnKKcP%z<81FQV>U#0hMRBNTn32l+ z&6b_9QNr+BRd^hP8qFtEd#Dxf1*}qP>88-zsL`pWo_Ej+2P`!A`gC?X^mGJn4RP8} z)=}*5{_X;o#Erxs0N?WR@|@>daiI5O)-R{5uC5ao0^)FVio~BhXwf5H9}VZ)pC}-( zD+8||t30?Qk0*y|;-6NHl6hkkkeob>^~k{B?wg~Y+{ z=Cp?g5W*|I6dy2Iaf@}y*@CHzk{N#+L+bYOqle7o1|L|xf3v>1)U)}qf8sX)0CGsEAZR>eNa$stzCL5Lg-nFXVigx!P^RHl4Wo(HUv`|)E}Vr} zcHKK9Ok$cV{yC5m__5|{)wSzsf;Sx>O-jCIAwViL&?Uq3mKV__CLvM$G5w0&;dOFX z`cO;)`ZbcpetUUL5H_twsMiO6Z;7c&h?B3gzj(WJ!Dcdt^yI_guJ5l7A3Sh= zw2$*mWIs02d_UrC;~r+Oo;_Mm?|JvLG*=J@*~T1R7njZ!7m^rU=B_>wgoPc`)Oque zhmMIlfOp|AElre%KMBtBj6{t4cReAyQOk<*0Uk__Uz8kR!iOc=0aFz3kuZv&MRXEJ zE;O!nG9nd3%#8nkC!CfehF4HR^v`a})=Cq)}B)o_h_)D#jW8o{o6!*6;X|A=O_?q@8GsW** zmEBZ91cykPJxoH;7l-*(u=8p6GCyCT5YOPdcp;R$E(}(l3PM`apdi zmPG;xOAP7wToHH1DY}dogd^s?$qYn{ArRJxu&KzjnqgCcxrcqMK-(@~)|hZn4r}nZ zFW}g7&;A4X9lP+-^}=?>gkB|Ug}wVIdP!pN6ofqv$2;F{+L+KwMKF3ffToTh@Q&JJ zb|HcB@6#+}lFWmHn-V8s(+u<5-$~m@C?H%ak} zFXh5%E*XoWk4Tk;Hy0jIG^8)0tA5J=b5S-0VlN5Tjk~#Q60k z`TeKfKV*gNWRsq5n*7!MKuY(QhZy%^SPz%8TQ3d3wnptMR5=-MDlxy3x3! zMbon9>2=D=1lUm+1GO>`*s>1o1~yjyEAi@ha!+KVq-mnT+3m5_DDAPFi^)UmZ;1h& zN7zy*lHAmn4Yeh|58V`|l2zl@KK0qIf9RdiGhUOXtUN0g8v^O+Y1`D>X|%-!Ys>AZ zBJtznSq;STvx#jzSB@EhQDuO2Ce52l%zA3HP#vH}B$COQsEan`;?uCI=5nbGYaAI7 z>b{1t_QvNdY@2sg#hjlBii>aAo@#r}ysMMN>yAY6eQ=r%ylm{g&;`+>%}vBmg{=tN zmI$&iT?wE`gwTa0pOG7@__M#ms$=MWfnEeEN`K-p>|g|EipmzW2w&bW{K&VQy1HRi=Vd|`d=db(*DKo|$!r3G< z;_%h%A1GmgiI4TcJBy!0WBf_qMZ?HpgKmr1}c9(Om)aNSU z1?|U0%zsE7)x-H=NC9j1#2+rhK=@n!ocH~g%`zYV1~JJ7 zB2YZ&3}HwJkf3x<_Ko)$6{zsM+a=)qOZpuI#c}jy!Ff?f5%}_2bF}*e>(ISHv~&JF zl6o*1Az*JFLCcSrC}8rM+0W(qw%MVnd~8|KHZ?^AtmbSH04s$(ICz0PDqGU{xE*kW zX<@b^UQm8#%&-3f&Og5oAcA<`xz5@3e=y}S0)k&LB==T1X6>@JRVo#lb(!!}b~=yp z_1FT9$#Y;P0QzVM7$zmD1?Qu`Tma1G<6Q0LxCgM^r@xw!bpKp^85NZHzaAX}V_;uF z7KG9?{7>{q9XDo|7`X{GX}#j{efs<>u2)Z5zwK}arirCnawf*dvzL-}U46zp{U<1H0 z{CR?greLV14a{Co!I{63_%~Y*<~Isi?L{mtQJsHxX&moj_)ykaaq{KduBxMt;UmhV zAN@e^CgJAysc5Lp5iRB58Pk`~2JxdhL3E{#LiX=ZD>d|JsJOHcYZ$&aLCnJ5Y zfv`W>i_{W<=AsO%uYHzIHvI081cB&;6|SH#f>kg5{yw!f8%$QR{>huID1DyRK##87BruW7%!~Zr%_W)pxx)0P}xysM&t+O(LOAyPff*A&h%4%4A`3yN*#m zP9k#T8;DjwLRO->NQXS|Hc1dY6iFh1w2)^;00I_3x$}-6a#vojW4mDdP09vq0MLPjBY?OP5LFE^*W0 zfdmX5(Y7$OdPxg7|jKI$vq~C$l>7&kb%`Ty&oQXCT?4_ zZ7IHp$q3WT%&d?QWI_4B^&vy%v^^{|`Lv}uj+WyalpG@&8p2*29#b0 ziLj@pAtUFJeLI?z7ujGS())_eReNlLhYoCDlHMd^gW(ZjyD?XSJ4wDGS+vX3yY~dR zc4zJ^v>p84aQE&(29E!=>Ad?qKi<7^$D)_KUDmCl;szQPNeRWpL%&`4Wg5-K^9D**TL@0p_~w!tNdNws3$R>nE z$|@0gD)wt$v4BaG26{Q|XVi1aN%Q|3;6@3!@H0u%#(p=QxUt%7w#xsp-4IfxOS<-) zk0b7Q9=FAq)6M^^u$J?i<4=7m!g4hIuu0{gfWa%OfkeQ3kFh9=@iRgL} zk49n@u*2ih*P)kZ z0SVENBQ^N=>EWyvgvq8a;htdKs)>dUQQKZQf#1y@8$-R!-Hirj?APf3?dTnl1Oh{Y zpQ@V_P)(UL%^4pZ&@$@>##0IMJdF;J>M^i1R*)fc?+DviPvnS5#q4~J__9Dj<^6&B zUcH-Pzrp~eq?GGPb&am{cBDNpdNp=Ei?io;`2S|mG2O8XE#2hGKDI$8p;OK7wQ{gEh^1Q^ zbLM!%MYzc*=nO~^R3a>?I2(8%L)I6A*wyfF-wR&0(|mmQj^$0OCdXVzeRH`eP4W75 zab2yy1|n~dLL}n4Jo;B%Rt9n%I2ndZi%m&Z`b46^EeF$o7 zbrkQxB$aw^>+Vtx5?qyIYau1RgCqv zS>WiO%1A}ukLQh9Ne@lkk)^xlq5t`&O8-E2hnCYk)PkBeghO_dGn@9GPFX~0;2v@fLG9PB)w3Jx;%S?bzaC& z{OSKYGh)s7A4(xTAn@{kT>1$;L(NxScc9x{>RMy_eigRVhnCR)9C+bsecv1oJ{ZE+ zlYBY>)N>^Mdu!neCzPAbu>K6n*06v)1{ejR|I{VNH(tgTh#u=UrlT7OynaeE1Gg38 zr&qzElm|urMK4dVeZp`6ayWcs;NV5ZWV6eM&E|%)$U$sJVkS(AQl%S1;+|kYTBB-e z@S}Z*SNnf#eFr?2?fbsHcZBQ^*+ll9AtT8i2_>5lvPqFqWMoHHGPCyF30@zLVD00fHft%%PZEG7#Uz_+3O?x(cyx?g*5{PGa1|pdf&#pt6Bxr*M!X@{XM)*66&I7JN+UE#B6U8Frc|W%M z@8<+MZ^zwl`yF};wD63{*o7CxP1bNi@!wiuG22|~{b^#JjNKYd%^fxEeI;+*FU97@ z>;F~d#|CqiO&h~(FE&R#CwPbP-7aVdf2y!I zLhM&eHnlb|a#4TB{hMd1mOr3E9>TSDIjHEED*=v{=-YRKU@&u=GloJnF{3vFbb^)++yuttg}qLCZvsFPI+20Ua5)9(vragq zkW&}&3eMM{r!%L8P1LtSdbjlb?tN0b{!$(<T?#EDJ#) ziBA0PDIq0<>D2wH^1=_;!$H3Z5wz2St2yxEPegarL0-Dt79`Z}Nr(IzRx2T~Jp6T{Aw8&>L+TnQX9v zEa>@4kll5;d z0Gz^A=gex|=|CUvv0~5gG=OD27mk?@CP2r_hKlK)WlMzR(2?0PIZ6Dk!>mjp%SB)D z-p_F?)6`U#$KWK!R7N&{`6p0SRGoUvmI|DN>yeC*W#u-^ecRQgf;7Z}_4TzP>pD<% z^Lh@MQ?R*2>f*|cP}RTL5{!HIlF~b9BE5hFpwQ)PH&H_Y+D6Z3TQK4-q5^nOMG-?3 z2mr(YQLAYm)yW9Eg+8;DvDgk}HlV>^W`Cr9mGSKf6m^`ZKJg3MXkp({mH^@Fq?ss8 zzi+B?=LG~VIZKLS0%vA@s=mIj;cD;=^%S*(-E{e}?-%3+fIiJ?RHjscI$Gc?2^rdS zORJM0@FmRDc(btZWk?<|Y>~ZJS}rk%oNv%)GjuFO`O~>JOqbh}B6Ft#(`FaxgdaBZ zivX4gGb5u+FUu(_%I0&H#KDEb?P0U3#ll)f8g5ks+%%t^L=FZjDjdzsGX0_Js$xN| zh-C}yi~=|E?&-M*E>$0amfvZtk3mcrA zdzb|vB$#_!wVIl`w$W|+AzFF&wU@s3Hzf!~Svem%{-qDZLW5 z<11AqW#_$(?nFDzdI2k!ugZ4ZntRj#v4aQ1a~W;LfdTphK{R|YKX`gw8GE`U6f4*1 zcD%cY)4a$vo&JH_`f;3(bYyufZ?%O}&X7+1V2kJI!d6yvp#9vNjF0Rh zNjZu=LsKB?dEZIP5&VmME(P)b#vP~KZA*aW$i-bQ|ISoS{Z^wVLUSfZqNDUC6djmP zl2@vpHzxyHWzIr3{pjX#8~CxTjg8MCIxpug=UO@6M?!X7vtxfKheW474S?iAm|!OJ zOLb~9yOB~IP>7DqD}6oeC_f;r%tZ9Wf*pX*Ql@-m{4AANuO+?R5Phd>~mrLqia_BZu#mjk{;6Uw%~8E7)MrHV#@ zxcA`0#~a@<7}BnRl*{LNb3Qz#gU0`uxI{ls4Cx@W%~ae}8ch_Ae8!_adP%nX;NVB{ zm;7FL66(_|A-gjgYgUuJ2a&&C^>_D5`fH8S=g-eSDyGSz(S>nEU?rLSIrarn!B!^r zlGJQZYeTbBKWcj4Yv`0FTo@eSVRBTT_a0uJA85cl1ZoO?2Q7o6;~W>5jK#%EIO9PK zdaaBq>v%jvJLpTtXPKCXZrAt5_eymt$)-*ZbXu9FiPt!J(g;%b@E}-fBt*hnaAEzu znLDU8Ez{x*J$YMK+S=LKc}}|STMWF}-?`u4 zKcVXxBnVq&GgMio#xZgw|L5v_l+4L7B#!Gd<^Cwe7)PKS$fNPd02>#d;C$`hk0H9i zXO3dFX~%mF60@vb8!YLU(5{DKsGy_=G->_@Tc;lU=gN+3)kVnpLzOs{(3v72$|0ikgWQyhzmE$v2H}gaN1?1+{GZjrz{84mS0$#GN zwVlyKytrYX>h1dkO`Cl+Znm+UdPG8Z2efX2D9VLI#5o(1kGZ<9&jMn62z9We4VDd1 zmzaUn@E>UyWc4};zyVZ1Q(W!3_u}@V${a7~0Up~W%tT_0+y-uB0OA%78Wmuv;ZDR2 zMsN=i^_S-6=5AaP28Jl{l`8a7;wC`su}i=e43`bU0;&f-4l!{j!b|-;w>BKsI2&B! zwwPbWN&8m-=kyl-c87aqN8RvUG$}|@`FDD|hFK;=rAZgJ>vK>}suvze;}HS3HaRm% z`fv>$@IN2mO2D+(;PSBxjjG|prrw0{yk<8_OAC<3Oh`n)Q?3lgAgY?`>TN$_*k;~T ze!VsvA_+~+Vp3n-(au;v2K!iZ6HEkFTHHesH8A8)(?y*52`Q17eBxS}GR+SaV3o3T zWDe$2ys~i~ET}^e+eH%xP?|j;1y>x;IG#tl`MR$^F?lZvvZsL=omDQ@QE+)lmF z=IpdJuMOdccCU!a)vLN1!JzP+bXn(cJ~N7hk}?#=`VyLXNP^^dRM;u6(La64y)p0( z8tC`y33$!$5@-73|!pVSn|*)M78+Lv zf~iPLYb!d~7K@sCZtKn^lXM2!HHiR;hjn!+bi+hMv2V1qm}MJ+wP#zSa18nj!M>$0 z|5!lrRAUR63mpZbYQ>&o^r58_AUP~`0?6F3;;c^N2_eWzIOd-KN%Mi^vhbmxH>q!O zxy+n+_fzw`!KCnoZ+Xr0-+%bf zh{-_W{2T~qSgc38_uhak$7wVBlqyDYyOa~__a(KjP+|LBZNLugwyBk|Gs*SdiF2}VUq!0*ZM*-tKSrY=r8NE$iq-y=|{fZ_tk zHfDcG=akr{D1&_O!89qC~Vm4N@C_81#WB#{UfR z&)}f%=Q(QMpx=a6M(Fg!Lqj|Kl%-7vy22xZS*3o>APn*;OP1~l-8vQEib(0RhasG} zk3rT*IJM|}|NOn*O^s$_*EP-~8gLc5mmcRALlQRA?!w(*y@04FVF?KW5!aQM-7)f@ zcU{NDsu8*pmCX>93L%wYXqKiv;kgeTk|+| zbYfy&GIr^`3{Xf3lW}t5yP&>H0DhRdj@F1slci{I_q}QP@q8rr5`X5Ge}4S$KI_zF zXgT=n&-wKn8qbVOadz1Ybh!wVZpnnx0lr`!UZpY5Ho7Ctn61eTjNqVy2x-Zo*^gq59t{)->$LOFL&S^DxA!=zDPyztmil2 zf`sQ>?N(@=RST(G3DGY`MBfRTv~CrEg%<*2ywTiIoW!vMMQ|;tWg*mZG3Q*KnN|)% z{hJF2qBjwL85>V&{ve^~1}ixjHzL)kT(TRa#9zl~Al_FBl{Wy39@Nc~e7)CCBJG*K z8Py01lnFp*BD3IKtubQ-?x)egz?_~c6c=M+71Dh*A-%?POI(OG{1j&=$H^3h(g)qX zQ{}M5JM4z?LfEm8#wYjDF@%brPN=lyk#Qo5(yX5MpbgC`^HS3xH}3Z}tNymNh38kV z^qw1*2gh_hD1<7ZJ~??;5aM1ue*PA zHZS^}Syz$K#E3f-?46f+2P)~S)SUxOzmKR;Pu1#`8$UuK=eoO1;z^B5i{7=JUu|NQETY-ewo!%gAA$ZD$XYvr_Iy#WufC;kX87Ly} zf2Z7wBY|1HD58C;eh0*T+~Q4^sVyXPzt3ce4fi=Y0LY4GKY#uVmF1`MCRZxS--obB zGch$wJa#^PK2B$eZE6>5j$ZSiY2Dc1Rv+-eGv-H1t&!_|q(~DCV&MqwT`xXE0v4T^ zI7;GMVeN{*J4BHh1n=abJq;0i0V%gHkcEe|4IKzm#IgUb|H91y{^`Ah9}7Fpz(oOt zO`yT zj36vRK>L&f7ZebMY<{7GNl?wbo&~aM3&zi|`x3F_u0*1YopuopvrXNVyoY^Y4jD|4 z<#I32a9unGHOryaj~`&dK%myZYi&SB^IM9?S6LAHb`|v4Su%hVniQPAWq_}!&Lk)} zz``ax0Xa92PJ*%st+uu{2QNQADWsgJk(L=ZlabaZ)Y8-a%Y6wX=(R24IyQ{t?gaX$ z!lL8BD77|9GOIhyKd+-piQ5RAfB_^p^9+z-CPpx>!wp6pM+DxfO7QRyK`v1dVm>CUPH+(dt3=GV zclugb5Vwodg#eaqi8a6`lo6JfRm78RTBgG(-L%=tyHpi-Z{mCdAQcg}{epH0Z?eBS zDLGkRbO?KpPQ+OM_f$wFgvpz#iwslkE@UvNCB3$qz-wb|P|xfeRAo9r#wQZs6vdZg z9Nqlu&7el(45?o(<0>utDs};A77}4=D*>$tQK6vbYc%c8Z`?x3VLwZ0TcIO?95BSU zD=Z{YRco+NJ<5oUZw-v#yP`R)%2WZp1aXYXFE{F~PMG!s?{c#rTtX&eH1FQOZy8tQ zT%Qw`o{0+KT$>w~z6lW8`?ZxP+~gF}=z3hplnyjtZ>R+YgH!qIlt+}jrUafMPgCM= z_r3^eYLbcBX$>XTTZfo7&vm6$jki7+(F#EdJo`U$_yJ>dkv&2f*UC}!z1+S%i#)%i z@jiZ9GwPmDP5+LfpDXu+{=Apa zE#EZ*rH~DDS3Iu@!V>5py38{DNkvME`n1;fNUX+v zISc}Q4&`>pZ@$lZ6YgH`ha=H?SD#J&BAJss1o`7mpSaxoUz0mlh9RO)h%@d9ZGV6j>iJ*c{G<-+uBZ!{WUN6MLGKI(y_hNR1;`OTE~WP zMB7=E%dp`rWa47(L>9ZQO5Yi-p;q6PrwK&v&6Cjk?%osxNzZ8(J~kx10IF5_bA-=$ z9PdW^P(Xi2uIc*jN9hyxAAz%o{hA2U4%b=2)%OCVnCFAxKT-%V2H6D>kB;Dw zgp86>w(1qIOM(VPU?4xOiEDivQ!-NJM!B*wNO3F8k6?RopsB^mmIWVFx-WApLj2qs z5Y!1Ij@<4`(#G{Kf*}yu-55*bxBYNU{cu5fFcRo?lw}-$xG2;FH~2G2aAR3eJ*R{n z&Ehz_=y92qp2z_GU8~X8r(ApbaBovP|N6z4JJ#0OF7#cXyeKImLKOp!xiG(jNz@Ms zr~{#Do!Cw8F}pkd6Xd28oP~RKz}Oj(1G`Jx4IvpOqz|;vj-hI!s@irE+ynSGrhzcc z6Hc ztdwMzUksWbn*p`i@E4aFbE@YdYTepE>pa+^$GsWx=fu_PRis87A!N~@<+mMrZ(O(3 zFRRB^asl~D-9DC`=0f)~3|FSaH;hI0V3L{VDF6imQRA9>S5A3}s*w`5yf=>a(FHz? zoJ{#ytOzP7D;te*&8akj6`Yh)msSZGpb<2j`93Lj858SjQJAv#QYhR>!W}y)+Tcb5 ze1B}$_fjPMiK2YVIiC6rF3c7mla=M;yeTWujvn}&6f^-upf)wqXjP(ZO`wa z*Iw04&Hc=a!W@EOvUR?isqgdHxJ`6+Z5NbTa|W07@5fhgl)7heiw{K3^0)UjfZEG9l&MckU! zV?y^JR!^wBPXXd(5#yI|fbbremd5)~T8sqg$}7*mY5gjL7QOb@ai;0Vk&*WS(9&`9 z89x4Nl+6h0A{OJ2_v$!Yi;mAgFzOEilaai=o@z-qt>#>@vkg3>WQk6H;P)$a4ZjFd*hY{AHfAA24-EVUM{l=?sIsce`mO zv&DMaBBV+j4kf&we&Nheom1sVLs}}yoRrXnup}O?IUSf`|9s+;^Px~PJ!=_#nC(41 z90157!$*a3?e2Z=OvIDW(=(6XcH(78jl)n?Lk$tA*AUq=>(;qho_T9OO5T_AVam%z z0E@Uz?VXp`{rtnvQeR8C(OwAVzb>4cvcIQ#PhiL_(~F{7;ZD2D{iSc-Q()Q(qQEaB zN~H3Xtu{`fe!F^l&rwv%rGaDYlNaa@kuK);0?8z1(36{*5jj8s#*ag?{-x8?O=caC zKXzc{I%?yo&iV6Y3>+>Rl+8r|%RrcsiwLu`94d6fz}oux5Q4T`J&CY_oZFX`Mrrvu z@uB^*@YyiYH6>H@S0?eqxGl?cMj68?DFagYr*a&h7C`a_W@d@$)Aljb8o^9Zqa=aB zkPz!y;E>-=)?*kZql1rn~y;V7o z!48t4_&wK96(_<7HGf~2Wt(%kDrc2$lu`n@;r?exa<6gVXTG+)X(u#7L7zX5k@6}` z<4O}nY_`u7US^k6w7)m0{`Mjp+o zC>I9(*NL@>jJ1EFxL}MMC;ORw0g%(d4K3`_%|_4YA}vEAaI#Ol0g%XL6caOS#Jg5T zcA@F}A5acB7*yF|Q!O=z2Kdv2sc|@p_ivxZ(>WtzfrLBy%~Fn2m=kbvdsS*GlYK|T z|77Jeen9ZqyNtm^pT$+4@?6y-wZS`|F45jyrfrwI`csFT^DId*BZuxqyhmGK)p9?J zU(AYbNjhQiFji?C58;%SUiuoBI6Aso5I=enmx+SOE`y4v<&XA(htFw>5$emL2M)!@ z?j+_Y%|y9e&(O%z{mXDH7Z^p<+6^?37m}x=U@l#N)(?#3Z7cauHvRJxu=7`3toY4&k z<7}Y0k(841cJ-rv?qNI|k!VE4$E)`HZH70{#Fyf0+S6^QO zG}23mXaja;UxE!HzuRjAG6f+(LyiTqC7_N*BDsVcs-cL-iprHM{M^%Qf4_7H3joVX z5#PgvL8DtIO?SmYKX#!6whEJSs-WVLzwoDV$W5mU1}Tl7;>6HsDKMWR;*17ukc!~S z@$lx-NXhqmpo`67{XQW8QpdO2!zf0ooHIQqXdLS@g77NiY&Dv2|LdOF4yjYfh&Z_I zEivd{{jo+(E#tI%q1zkts8R!KNMqVu8NIdU%G#G*v54h6c47~GE;lAR-qtbo{eI+a zzQa~zG$A|k*5=G@tu%rq*%bnlf-qA4)#1%*$qaw2N zaAMj`HkcHR)wpp2KRuMkq-NeTl3gYs5VzPb`q!$0?TK%(pSj;Hov~s+Es-I4ny>!l zjV(>bvds-;bdtj8IFVoF_HxtGFi3{fF+@gso2pg@-=d&JEa%g{a`>AIxS5=xp4RJV znef9|vX6)U;hn`o9?+Jb2K)IAa9#|Dq_6dU_A?ZjJ9pSY8Zx~fn(M{d@%OnRomNLy(oc~-jXeP+h6CfxAW^^!on^vsXYrtr49h5y+6mwZ9^r!ccvivyZ>v#W7`CWpPyeWdJXtF z^7I~vNfP+4JAP=z#j6TOIlx}|{CQjxuPPG$S=b*Zx{QmCBl=Un;J~xlMM1gKkn5fA z#^<@$3F3YRJGfj!kYyu%J!Ds*-*N>{pRLK5yjaOx#T%D#cJ*vKFe+pW@Iln|#2OIXM?}m>-BiFnfgUmC>&9b%-m9Mo)BXE#REnqGCtiwHCR7hP9G`~n%`lJ<{dojE7Dc`%0jXCQ zK(0i+k*{xZQrhQTZxmR^n8WT7?ZJ%1=^NMDflqaB^($Q|clF%5^<53^CVmXqKAyOn zbHns?l9-<~@qcOlT5gWQMET86Bei*ex1m2T`(tV-t6xE1KbvMs`&(+)^|Xs%a`(~t z=4OSY*Iu@LZONUVW-2NwZOR;zA11K3Hz3>k?I`N@{MNJ8k#!v}QRTw(O-HcD;dF6_ zxj-rgBm^^qu(MG>6N>~9qX#CLjA<^5bpI~mj{yAWeFqG+H$b||TYZn=qZhseqn}Ufd zI?3Ad&P%uG<+dNG>Q`Al=P6^%RMWFCKR2!0^per4+Q$@4tLZAHb%97E7@<+zUzLQ- zFBU01y>*x{B;H632IgaiS)=d133eQ=j*iZHukhr2C!KoF+z*;LA6yEK>rnJP;IX)kdySEys>BeF&hyz;Mhw6gfjF1_sAqUG^Y;W~`>pF??@gS}X!ANYyI1 zxZv%k*<yBVUJ#?W6GUR!|;# z$#9d8?b;coOzji0pe((z{j__R5!WQIc5g#5lbF_6KG$ zF{L8a`lpp19P@1kPr|S%18mkdx8I!)>F2Uggp-nzBD#|p>UVEyf@D^VqfvswKRZ<# zYxy6cQ`%i$A%ibP2}^6K#gIKjz~3CxwdAF2)dN<%$B&15t2L9w!pYjpe3d+Yqy{bI zCow!ETnYaGOdh#Cf$t9r`J3zioT$j#(W9T9uTu+X1dOv8A%s}y4+bfY%V{d)(J%+k zw~!bYu>0=LdDwkzz{dA8d$r1S=Xzrt&s7Jj*r}EUHzQ{u4lG|^spwjgiskXp?Id?O z)7;!MV%?9n;WNf>n5)$C0f?wxK6dTAs6_&rAxA-hyZpSTC$2~u3ObIbU72saSYEnp zw1zz&72o_ZeeO9^(j3h+<)<=!5`x9Va)IFs+hj7)lsxAmu(~uQgn*vadv36O{mgBW zv}pfhpW2tYn^S(ubbb5f6 z`AwDjk>SOhOvDn?64`g_{_g)J~}HWGFiIqpuhZq`3=@t?1k?vDnOih02j^`HOs z8zUmy7G<&QHkC{<>iO`09>9Oze?+H=wA&h`nba`A?f+cWJL~k==N3vc>x-x2uwne? zCL;d?r}B5_n@|GTtD3YVs&Fiw0!*CeP1e@N*k3G ztiOQs&pkT8DZY-Eh0Et3{k@6*U)P4or%bh*lwfs^;5=*p-)~M{9E#GD<)4WIaGIUF z+3SC=7P2?_y!7uuE(%r&LbfK!mnfKa7vQG$ zvfG{I`URyg;US8|KVoCaH^X*!g9%_JC*vNj z<34^={mNcFk-I-Ju6i@)0d{!WocT|t#XUOvi!C-rxKKVe=j=A_xp~5u>cDzThiHe z9o)mcVXXJ5WjM-_DQz3i7uUB7%$y`IUU`FhY*=d`>KCQic-$vpH`<_F6m#ay#{n0c z_>YZ==!wIe19#dNB1C+40$)rw8ez_=>5NMqEnvG&DQYbv6>>1Mc^Z!Im z^1+TW|FV_FcaWo~zwzUo&e@}hjk5g}6oM%~m=TUo0^8xM=0A5wg{8CKT)*Y3%!zSa zh5$|Xo4uu4JH(}yCDu1nHy~nQyO6{J8`6a*24|;&f2bV# zHM~Jme7f0twF5c?nam3F7V>`uPU>aomSIutn>$MEulei;dn|V>*GwM_UXfY+PPo=J zUJl59d56rP1OXc^Mq!ZjXI2Kp!2B|(i zp}tH1LO3tSMQ-wq*5$Y44~ga@EZPIN>IxwHP74WZ?Lzg7iE~cjP0yr<;Ha1)PE7 z?kWxX4EC2RN`3q#Ya3hdr*^ky;bN@*v6BM%Ew3O%@>p5 zoNRHnK51(Bu<}V7w%dlz=)qTd;km)Gzqb8DLqmC5@2D?U(-2_!ypj+VrM`OZRf@@SG4IyXzm)$Y5zQPrf6pR6{i=NdZ=^%kdEZ0PtE+dC!EAjNGk0HOuqPtlhpfnKxW7lQP`-BPsyQFkmV~k} zW}%Yet-%+)^Ixk8pU~S(GL_yq&VA<*mLs+v5f=H*Y4}M&d~M9N>uWvGYR#x0M#M;a z@PqvDdTs1Q6S-$jDwK~RtFiVRqDMLPGPh1n1h|97dt=|P-pQCU$3~7t{}+l+c?PAs zEKX?cNe{3?`p+X_;V9icHf)?HBBginUCvWb%@cd__>G2@?|zG)>^uIDy^oHhZy>q^Mau3l*nm z->5dTg<#t+PtvqX($UERtgO!K>hoh^fSKsoJNpBL*_4s0`{i{w zs?XUABY$}6SK44N3>4(A?y!@RCI8fTNPtwR7&xb9KO_GyC}zqlCr(^AE#!PZM&G(+fpgb z)rOt+p$+idwwSN7Emq_b3v81q=8hMKp6+8;Uhkc=9+hUVyI=)?Vd(b*dEBWT0KGah z=+X>kv{Ei;pEESI^>8F51umx;>$W|4!zaL#FU$;Xiim*8*6N^b9WuV*p zqGgJ)4{ctucy3eV16BIWzDJA{<9iV1zCXN)N~AB*$?G}psbBhlaCYPgPEo>Rrm^uy^xEfU zGk;Cct+jOp+`n(mpg=DgnbNI8Hk?PD!4O`P(`ho_SI&K`Urp~(VHX?}8aXqzN;x$g z;>UR5@=OmeYnnLGhTN4s2YRve_=*SVX2Jz}s65rTn8#*B=~R!Ur#$Y7VM*h$Fm^H? zU}K(tuk#&khxlGv;8D<0-l%lf*N!;b5$WPr);m_!@+XWl26uMO8oMT8%yL-J3}TM%MSPx}ov+{MbCGGp!?dEP>No+Dd<7gHK5g4R6f8^RsN=AiWNFES##s@{G2h=^q^UzL!Urza=mc!>${K4g5I zX_ELba)^a?)BwUBar7KYh8wWU-ovYX0NXF+ka|d|U-aWP2mJ92KL9=xL}`H(Tx`2> zj_2N1^3>`_TQL|*nZCWT)1~ZQ`FgH`X-?O|x23CHff8<{X%soD zM`C7hrHwj5X_J{a?&pNFVPx%@1s1bNBhd_spjKr~Io~fzgs8&}YBC;umkF+LJjzDuW3cF3NH@HvPB6=TX5-qYu!UM> z`mqxA#ln6vmBf=V)yncD1L8h% zeWo-&VNAPoO$BKEdBFBth&-kyu5<8L-Ryj z*A{`l_Ruq2Z)zZMlh5R$@Zi-Up?ouZkl4|pbYjvY(|a=-yq)AB<15(|`yoY|`8uDX zuftqz+Syw(aVGoJKGiPX%FFp2R8s-n6g@Xr4z2cA&^#|rbT5*+bH`&Q;lQBIuac z&~nrhD6Lhb;f7&UN6925g<88quh6gL=4M)*BpXPy(SzElnT!=>!^rn((r%o0!bsze zk&vzbxdm~>FS2O3uD&KOqdY__iWC&(3xw|O-`NY>zB86zvj3HDo^y#lm44wQfG%2G zvO73VU32a$1F0^@^rvq#`nv}l_Im(F*S6LaQVdC_Jl=XU(CmEm_E=;X8M{=w0b7Pf zM@7%v>a(A#&mREVH8Rt&Sz<_FSvvW73dolHXbs9St4qc1$v94sKA(~?7_?!yT*W)P zV{x(AE&L&HKv`#5{hHeY8ExithTbtsZ?o&&ZRK83t;$ixJ~|WG9u%H&d${7+`(=a@9+Z90*>e$0vw@q@Tugw5su0a z)70%1R}XBJ+k#D#yz(W`yDb}EYxpyUy=Mw_z)vZYRJZlgvE?nTr!qbk7uXy&LbX|E zq*)pD@aMA3lIP-iy7do@Q<}|X>T3p_J${Jym6*78T?y=d_ALzqU*d_=)5s}!4D+8bX5^Q6_{aQZx01ob-0b3#K+ zJ4oN!)?U7FZ=@Tq- zhVnYK?&k;C!XLesZg)NVr?7*9iD%?L_NRz6q7Tt7O;D-G?+6&8Pjh_KxIfXmlOQS< z3GEw2eTKhRjb;50{uGFuMB$=w;gxFnzc~bQV}I7a!L8G4h*>McoKpX$4t`Kh(f_?@ z?h3zZr_qh}cTDWLD4R$f3W?UiVwiwY#5Ac`>CgM#rZhkL`$8vKD`!Q@74afNUIIELD`OC=<(?w zk`4Ubpz4LBr(n!H7vVS6E^~T>p;eqwQLl^4?9`arN_4H@9O!lnFBC49_%DB<_`Yg+}Kcd^6F4auV!-te{0 zSts*0)Nc$LsX6tEVy+OKW)V&YT#E;rAI+mi^YD=$q1z7 zMBERG-N}n{U}AR$tVYS5ECMvMd)sPt8vMtPPg;U2`3^cgy&TW-ngsBFe9~Fm_wnX* z((0lz-t^3wwZonmrYNd;g}Ynda)eh6M@nqd8e(KOo_JdcRM<_vxt4Vl^WakB2_|#L zAx+HWkv{MHyEI-Q=U7=;XEHx#FK(UCpPY4H{#q25ePmSb734d9-hSn~$VL}`fkCAK z@BK|_of6-f%UnmULaE+A328<5iA|GtiJ(ZJT<--p0M$5cz$%5=fUwe%dN$JIvrh< zrh9?D>z}QbCK&Q6`L~*VM;*`?8V6#pFO8H_5-tw+S-}=S%8*-HWc>J=ZGc*Q(bSi6 z5lMT|u!#DH5TY$8X3|qXswuZk*WK*6f1KBsYn+D$ZPF!HMuu9q`r}fn3IlQHx*slV ztq4!k|5-_;aJIwKwiHEF=!}h;DZa$=>nW6a8)d+=JC>c4fEN_FiE)+u8yU{Gw61;g zWBcjf3<%p?@EkN%>iWdXZC)TOcHSha&xqiN)+%{m5KG7%a@EK^-B7{m?RB=L)cgWK zqu(OMgo?GfhaV5-+An_3HGDFo%8DNHCddA-wX0VZ!GOkj?k>4TvRDv!wPb{dy^DYDyuL1m z!qlHFt1->JN}fx8{5nq^6R}I8ER&GIsHaNe)QYY zQn#K9V)xgM2a1XpR=0PjW{RFBBs{8klk{#uJ!rPah9)oX;_h0EW3l1jx1gv-IT?TH zb3(aEdCAFVRkY-N$z1lrguYvDh_oe^{Xpp8n*thtcl79583*JZbxlNHWS`N~eh@3R404Yha*49?}oIJgpxYSiQ4>n0& zX6Wivf3SYB>lPmN`Ka>+at7)Te%c(-V;b=8g`chW#Fo<-%cUoc?295$O8GMA%(sEl z!l~Pa|4{ZIw9C9O7KY#C<*=sAc@qLw%$dw&Y{p5EiJ0{vgwww_ zDSJXRk;U$(V=p7fX*|11?4l>HACiO`?B!2wnYw3I#$?h~8 z8o-ES?gR1loC)k3$$yXFG3014(v16l4(6vyN!*2(-5eeD7k7&}pLu2HNXXw@z($sH zuAj2~FU6_UzlU&EOEO4-Eh#CKoKr6WT z?~5b4aCX;jl&;m`@zMSJqDTe2Z{&p3hil?PF@JBwKWN4nN%cEU)h*NOX#Y=g9r<7v zI6s+gGyKr+G5pszfs0E3H3CxtHm^za|6K!r?g3n+HGzUsU?qv#pD*`cuc)en@i^^W z{!a9N-xH5(>JSQ1XNpgYUw^;*pI>$X#S+xuagMI-e_cS%vvJ>mKr9l66Z>|IgJC zBNRxlr6kb&-{Fiq1Oz&!!C+}hG5+3_Kd1*7Kt7nX>GxpH(n<9(|9#cT9#wBd9Kcux zMK$riKh#_kHSW#d=j30%S;*DoQx*bup+d`&dXG#+1Jj-U<5;v8vzcP;gJ}_~%Efch zW5vuva~JU%g8112T#Z~9cvg6JEA-J$CwG}ahdd7&bH+iQ zub0&0ugTuMlgSx&W$>y;ry?93Gp>2Sdhnd5=DQ2oC%4-xtzAKT==zn;oE8@2TnkQK z+cc`xoJf5nYJbI$7 z+3-kPv+fbG^bwW|XSHRt(c#IjzWDpI>&{e1vueBZWk0{W)&8Pyy004-%RHuE@1AMd z*P1`LxIR#&=hmP%xsP)DL+Wsk|LRf++lqneB1Y7K2#xSW=sP=I( z7-*kJSeW|FckyrfhV8}K*KXBF-zaQW?pBp(_gpo{WuXm)t=_|d??+nBY<_&1+D;vdba-8~46q>bkit%%Uj>dItRK55?M zZOp3_`xf!*ePn19eP^5SaZXfT&dJe>z58Qt-PlZ1BouSvAE?C@eeMsBFKnW+VmuIE z@BLM>+Qd|!%zU~`x*7rY>htk)phi?7uiwy8Um;~{~_hLd#R`eo17Xj+yrS2x_>=O{n2+}Fb-vAWoLO=3 z_%?CTjB&@17DTkx8}QP>&zz?8`5VhWgvw3Ph@tbZJu5y{?p5(dG)j0; z5pj0IuX7jb_|DQ?wr@>)J+x5&{4yx$H-)ZhwAjw1wF8B^#QMluH%gxl=iE^j-^@;ov9CrVja#ZMJi zT?rVzFr=o^e#`*wHN|CUJP|`fKP=HT>E$)5c>5(zHjV2>zCOLS zHor)g2JK+W*oNcShx$8%b^Q6)iGo5yvG;dY@)vJz@mZABsIIK8hNhnn036F67)}uq zTKXk>=T>K7J$O8{NY>Z9OxUOg?6cKanL|{ng6iAQFh7x5R-vw;(RZLP`BESo$og{R{v^N{#N{0c**k;hViHl{0&Swom51yw($>+c!DgvMb;$KWM~+4y7kXnEtzdS#*Vijc`ZkvbM-1FTc{kiXZ=leP5^Euyh&gcF4oO7c5 z_>;X36CS!)u@1PAde>33*>_ayA7LUPpFEN3r)iKAecX!GLse*{D__JiF`5csSPA+w z+XOhv3@vJo?WNmjr)Q)LDKSN-9@ z^Ve}1Q(7gKbfFT^EyJid6E08%PF`t)q41s}R^LayXV1Q|l-sz#fvc6X1BG`YpgEYeO5ubkUy@Yz?@$>_PWjy+fV8-O_@>AD^g@4om zswNg^B(7l8k(a;)!@A=);xo9fHrler@&4}+3QA0$Lp{*bK27upi?B-Eco}~vhzS-ugo*UtRZghR2H~4 zA+e~@U7_J9Ck$LL=pO?TLHwnox5m$LMf+(1;Lf1NcYQm%c zQP_cf8D4Bps&XHXT@wAkqS?bx$OfLU9H|&me%C&2@EZz>_e=8c` z=6rw9F=(`cQ-;$wJsK!9jsg3WK8=}ZWNpb43i)i=c|q#%L9iP(?ZRZ}*{5^CTVp>I zjlL`_-AQ*_YWghP7O*(40`^Al%AktrxXTM|5A;wm*jMhDRFEu3=s&fRc&O_pfiSg0 zO^y2gsz#b6tFi?g5xiKl_s!VH6tJ+RJGaE`;J2b)Rr_t0*~gqItN8QIvHKB8I^%Le zi~L?!))}|cd4VmlSH3?B`ztF_3vL%>c&5ry$t6|JKG^`AM&q%P&Y#q8rZG+B3k?dm$abYUxPY|tK|4)Wmt26M_4s$^xvL$Sq= z>E1uxy&_bYIk|$0N}`BlE2%ywe-DS~p+-?jtw4-scNa!!ZEvQDcQpb`vRNBe~er?Z6WOF*|m3O0CYd(N( z^|vdl>D7^KZL|8%hR$awZ~~CzTtOkX9K-A1(q|Hk!tAQw9d+H(YwwF?W{ogODrBae)u3NtVsvU%;Py738cBn!VpN0ub&6hG~*vMxTR+ zg!-m@A<%)3{vaJT|0Um$6AB4Eb}=$(RVXtJ*1qbUbGCz)hReJ$T;(#VQS5|OklhQ4 z_8+^Niqei%mcXv(je)`lTBaH5*#^x4g3g!ai`m$tU*YwDwe#s#=_YC2M9II zA<0OEvIh{pNfOmUg7NVHBu2DBxroq1gbF@<4djramg4D57pX#r;Z=uLYpzOi1SS1z zyy}liK#*Jf?uJx4)B#%U08e7*{y;i3e;agxvL->G!9BQGQWD<;i(1E+m|q8=(tu%= zDkKVw-yLf$fg$`oA@7{%!$U$~7@~+OwTZOyeqdV@O;=G3dK<}GruUoVS;1B?6QHXN z^P&D24S(UdW_a)>1!$VU>`dRP}BHCj}|D}4(F0>6*cUmo~WpK}ggwMPC)b=?5MG4zd~z>YoGMBm|=52${c5?GlsPfEs-wwC5VoY-GyUw*-{rupyI@#+ad< zy6nMqYKM$Q3Z|^c!eA>a8rM%$!C)|XXqb?N4eQ0;|3zb<0X%^@JGwbk+u@V{1(|l; Av;Y7A literal 0 HcmV?d00001 diff --git a/packages/vchart/__tests__/unit/series/waterfall.test.ts b/packages/vchart/__tests__/unit/series/waterfall.test.ts index 45090e3aeb..83c256f31b 100644 --- a/packages/vchart/__tests__/unit/series/waterfall.test.ts +++ b/packages/vchart/__tests__/unit/series/waterfall.test.ts @@ -1,48 +1,111 @@ -import { DataSet } from '@visactor/vdataset'; -import type { ISeriesOption } from '../../../src/series/interface'; -import { WaterfallSeries } from '../../../src/series/waterfall/waterfall'; -import { initChartDataSet, seriesOption } from '../../util/context'; -import { Direction } from '../../../src/typings/space'; +import type { ILineGraphicAttribute, IRectGraphicAttribute } from '@visactor/vrender-core'; +import VChart from '../../../src'; +import type { IWaterfallChartSpec } from '../../../src/chart/waterfall/interface'; +import type { WaterfallSeries } from '../../../src/series/waterfall/waterfall'; +import { createDiv, removeDom } from '../../util/dom'; -describe('[Domain-Series-Waterfall] Waterfall Series', () => { - let ctx: ISeriesOption; +type Direction = 'horizontal' | 'vertical'; +type CalculationMode = 'increase' | 'decrease'; + +const createSpec = (direction: Direction, calculationMode: CalculationMode, inverse?: boolean): IWaterfallChartSpec => { + const horizontal = direction === 'horizontal'; + return { + type: 'waterfall', + direction, + calculationMode, + width: 500, + height: 500, + animation: false, + data: { + values: [ + { category: 'Feb.4', total: true, value: 45 }, + { category: 'Feb.11', value: -5 }, + { category: 'Feb.20', value: 2 }, + { category: 'Feb.25', value: -2 }, + { category: 'total', total: true, value: 40 } + ] + }, + xField: horizontal ? 'value' : 'category', + yField: horizontal ? 'category' : 'value', + total: { type: 'field', tagField: 'total', valueField: 'value' }, + axes: horizontal + ? [ + { orient: 'bottom', type: 'linear' }, + { orient: 'left', type: 'band', paddingInner: 0.4, inverse } + ] + : [ + { orient: 'left', type: 'linear' }, + { orient: 'bottom', type: 'band', paddingInner: 0.4, inverse } + ] + }; +}; + +describe('Waterfall leader line geometry', () => { + let chart: VChart; + let dom: HTMLElement; beforeEach(() => { - const dataSet = new DataSet(); - initChartDataSet(dataSet); - ctx = seriesOption({ dataSet }); + dom = createDiv(); + }); + + afterEach(() => { + chart?.release(); + removeDom(dom); }); - test('leader line category positions should respect inverse axis in vertical mode', () => { - const series = new WaterfallSeries({}, ctx); - (series as any)._direction = Direction.vertical; - (series as any)._xAxisHelper = { - isInverse: () => false - }; - - expect((series as any)._getLeaderLineCategoryPos(true, false)).toBe(1); - expect((series as any)._getLeaderLineCategoryPos(false, false)).toBe(0); - expect((series as any)._getLeaderLineCategoryPos(true, true)).toBe(0); - expect((series as any)._getLeaderLineCategoryPos(false, true)).toBe(1); - - (series as any)._xAxisHelper = { - isInverse: () => true - }; - - expect((series as any)._getLeaderLineCategoryPos(true, false)).toBe(0); - expect((series as any)._getLeaderLineCategoryPos(false, false)).toBe(1); - expect((series as any)._getLeaderLineCategoryPos(true, true)).toBe(1); - expect((series as any)._getLeaderLineCategoryPos(false, true)).toBe(0); + const expectLinesBetweenBars = (direction: Direction) => { + const series = chart.getChart().getAllSeries()[0] as WaterfallSeries; + const bars = new Map(); + series + .getMarkInName('bar') + .getGraphics() + .forEach(graphic => { + bars.set(graphic.context.data[0].category, graphic.attribute as IRectGraphicAttribute); + }); + const lines = series + .getMarkInName('leaderLine') + .getGraphics() + .filter(graphic => graphic.attribute.visible !== false); + expect(lines).toHaveLength(bars.size - 1); + + const position = direction === 'horizontal' ? 'y' : 'x'; + const size = direction === 'horizontal' ? 'height' : 'width'; + lines.forEach(graphic => { + const { lastIndex, index } = graphic.context.data[0]; + const previous = bars.get(lastIndex); + const next = bars.get(index); + const points = (graphic.attribute as ILineGraphicAttribute).points; + // Derive facing edges from rendered bars, independently of axis inverse and calculation mode. + const forward = previous[position] < next[position]; + const start = previous[position] + (forward ? previous[size] : 0); + const end = next[position] + (forward ? 0 : next[size]); + + expect(points).toHaveLength(2); + expect(points[0][position]).toBeCloseTo(start); + expect(points[1][position]).toBeCloseTo(end); + expect(Math.abs(points[1][position] - points[0][position])).toBeCloseTo(Math.abs(end - start)); + }); + }; + + describe.each(['horizontal', 'vertical'])('%s', direction => { + describe.each(['increase', 'decrease'])('%s', calculationMode => { + test.each([undefined, false, true])('connects facing bar edges with inverse=%s', inverse => { + chart = new VChart(createSpec(direction, calculationMode, inverse), { dom, animation: false }); + chart.renderSync(); + + expectLinesBetweenBars(direction); + }); + }); }); - test('leader line category positions should respect inverse axis in horizontal mode', () => { - const series = new WaterfallSeries({}, ctx); - (series as any)._direction = Direction.horizontal; - (series as any)._yAxisHelper = { - isInverse: () => true - }; + test('updates facing edges when the horizontal category axis is reversed', () => { + chart = new VChart(createSpec('horizontal', 'increase'), { dom, animation: false }); + chart.renderSync(); + expectLinesBetweenBars('horizontal'); - expect((series as any)._getLeaderLineCategoryPos(true, false)).toBe(0); - expect((series as any)._getLeaderLineCategoryPos(false, false)).toBe(1); + for (const inverse of [true, false]) { + chart.updateSpecSync(createSpec('horizontal', 'increase', inverse)); + expectLinesBetweenBars('horizontal'); + } }); }); diff --git a/packages/vchart/src/series/waterfall/waterfall.ts b/packages/vchart/src/series/waterfall/waterfall.ts index 09b6c51864..85bb6bb882 100644 --- a/packages/vchart/src/series/waterfall/waterfall.ts +++ b/packages/vchart/src/series/waterfall/waterfall.ts @@ -58,7 +58,7 @@ export class WaterfallSeries