From db36ce0c3c4a325339a1fdaf2dde223b5d0d76f3 Mon Sep 17 00:00:00 2001 From: Looly Date: Mon, 19 Aug 2024 12:04:49 +0800 Subject: [PATCH] add test --- .../dromara/hutool/poi/excel/ExcelConfig.java | 11 +++++------ .../hutool/poi/excel/reader/ExcelReader.java | 4 ++-- .../poi/excel/reader/sheet/BeanSheetReader.java | 4 ++-- .../poi/excel/reader/sheet/ListSheetReader.java | 2 +- .../poi/excel/reader/sheet/MapSheetReader.java | 8 ++++---- .../dromara/hutool/poi/excel/ExcelUtilTest.java | 2 +- .../hutool/poi/excel/reader/ExcelReadTest.java | 16 ++++++++-------- .../poi/excel/reader/IssueI8PT9ZTest.java | 4 ++-- .../poi/excel/writer/TemplateContextTest.java | 7 ++++--- hutool-poi/src/test/resources/template.xlsx | Bin 0 -> 8905 bytes 10 files changed, 29 insertions(+), 29 deletions(-) create mode 100644 hutool-poi/src/test/resources/template.xlsx diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelConfig.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelConfig.java index d5889fc68..47d8d902e 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelConfig.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/ExcelConfig.java @@ -105,13 +105,13 @@ public class ExcelConfig { * @param headerList 原标题列表 * @return 转换别名列表 */ - public List aliasHeader(final List headerList) { + public List aliasHeader(final List headerList) { if (CollUtil.isEmpty(headerList)) { return new ArrayList<>(0); } final int size = headerList.size(); - final List result = new ArrayList<>(size); + final List result = new ArrayList<>(size); for (int i = 0; i < size; i++) { result.add(aliasHeader(headerList.get(i), i)); } @@ -125,16 +125,15 @@ public class ExcelConfig { * @param index 标题所在列号,当标题为空时,列号对应的字母便是header * @return 转换别名列表 */ - public String aliasHeader(final Object headerObj, final int index) { + public Object aliasHeader(final Object headerObj, final int index) { if (null == headerObj) { return CellReferenceUtil.indexToColName(index); } - final String header = headerObj.toString(); if (null != this.headerAlias) { - return ObjUtil.defaultIfNull(this.headerAlias.get(header), header); + return ObjUtil.defaultIfNull(this.headerAlias.get(headerObj.toString()), headerObj); } - return header; + return headerObj; } /** diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/ExcelReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/ExcelReader.java index 8d61a9af5..6b6ae9aac 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/ExcelReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/ExcelReader.java @@ -246,7 +246,7 @@ public class ExcelReader extends ExcelBase { * * @return Map的列表 */ - public List> readAll() { + public List> readAll() { return read(0, 1, Integer.MAX_VALUE); } @@ -259,7 +259,7 @@ public class ExcelReader extends ExcelBase { * @param endRowIndex 读取结束行(包含,从0开始计数) * @return Map的列表 */ - public List> read(final int headerRowIndex, final int startRowIndex, final int endRowIndex) { + public List> read(final int headerRowIndex, final int startRowIndex, final int endRowIndex) { final MapSheetReader reader = new MapSheetReader(headerRowIndex, startRowIndex, endRowIndex); reader.setExcelConfig(this.config); return read(reader); diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/BeanSheetReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/BeanSheetReader.java index d2151b222..b989ee733 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/BeanSheetReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/BeanSheetReader.java @@ -53,14 +53,14 @@ public class BeanSheetReader implements SheetReader> { @Override @SuppressWarnings("unchecked") public List read(final Sheet sheet) { - final List> mapList = mapSheetReader.read(sheet); + final List> mapList = mapSheetReader.read(sheet); if (Map.class.isAssignableFrom(this.beanClass)) { return (List) mapList; } final List beanList = new ArrayList<>(mapList.size()); final CopyOptions copyOptions = CopyOptions.of().setIgnoreError(true); - for (final Map map : mapList) { + for (final Map map : mapList) { beanList.add(BeanUtil.toBean(map, this.beanClass, copyOptions)); } return beanList; diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/ListSheetReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/ListSheetReader.java index b58ffb021..6451827a6 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/ListSheetReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/ListSheetReader.java @@ -63,7 +63,7 @@ public class ListSheetReader extends AbstractSheetReader>> { if (CollUtil.isNotEmpty(rowList) || !ignoreEmptyRow) { if (aliasFirstLine && i == startRowIndex) { // 第一行作为标题行,替换别名 - rowList = Convert.toList(Object.class, this.config.aliasHeader(rowList)); + rowList = this.config.aliasHeader(rowList); } resultList.add(rowList); } diff --git a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/MapSheetReader.java b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/MapSheetReader.java index 95ea384b5..a73648a91 100644 --- a/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/MapSheetReader.java +++ b/hutool-poi/src/main/java/org/dromara/hutool/poi/excel/reader/sheet/MapSheetReader.java @@ -33,7 +33,7 @@ import java.util.Map; * @author looly * @since 5.4.4 */ -public class MapSheetReader extends AbstractSheetReader>> { +public class MapSheetReader extends AbstractSheetReader>> { private final int headerRowIndex; @@ -50,7 +50,7 @@ public class MapSheetReader extends AbstractSheetReader } @Override - public List> read(final Sheet sheet) { + public List> read(final Sheet sheet) { // 边界判断 final int firstRowNum = sheet.getFirstRowNum(); final int lastRowNum = sheet.getLastRowNum(); @@ -73,9 +73,9 @@ public class MapSheetReader extends AbstractSheetReader final int endRowIndex = Math.min(this.cellRangeAddress.getLastRow(), lastRowNum);// 读取结束行(包含) // 读取header - final List headerList = this.config.aliasHeader(readRow(sheet, headerRowIndex)); + final List headerList = this.config.aliasHeader(readRow(sheet, headerRowIndex)); - final List> result = new ArrayList<>(endRowIndex - startRowIndex + 1); + final List> result = new ArrayList<>(endRowIndex - startRowIndex + 1); final boolean ignoreEmptyRow = this.config.isIgnoreEmptyRow(); List rowList; for (int i = startRowIndex; i <= endRowIndex; i++) { diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java index 0d6648b91..6ae2cc156 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/ExcelUtilTest.java @@ -72,7 +72,7 @@ public class ExcelUtilTest { @Test public void getReaderByBookFilePathAndSheetNameTest() { final ExcelReader reader = ExcelUtil.getReader("aaa.xlsx", "12"); - final List> list = reader.readAll(); + final List> list = reader.readAll(); reader.close(); Assertions.assertEquals(1L, list.get(1).get("鞋码")); } diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/ExcelReadTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/ExcelReadTest.java index 627965f6c..a3c33dca5 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/ExcelReadTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/ExcelReadTest.java @@ -58,8 +58,8 @@ public class ExcelReadTest { Assertions.assertEquals("checkPerm", read.get(0).get(2)); Assertions.assertEquals("allotAuditPerm", read.get(0).get(3)); - final List> readAll = reader.readAll(); - for (final Map map : readAll) { + final List> readAll = reader.readAll(); + for (final Map map : readAll) { Assertions.assertTrue(map.containsKey("userName")); Assertions.assertTrue(map.containsKey("storageName")); Assertions.assertTrue(map.containsKey("checkPerm")); @@ -70,7 +70,7 @@ public class ExcelReadTest { @Test public void excelReadTestOfEmptyLine() { final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("priceIndex.xls")); - final List> readAll = reader.readAll(); + final List> readAll = reader.readAll(); Assertions.assertEquals(4, readAll.size()); } @@ -137,7 +137,7 @@ public class ExcelReadTest { @Test public void excelReadToMapListTest() { final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("aaa.xlsx")); - final List> readAll = reader.readAll(); + final List> readAll = reader.readAll(); Assertions.assertEquals("张三", readAll.get(0).get("姓名")); Assertions.assertEquals("男", readAll.get(0).get("性别")); @@ -241,7 +241,7 @@ public class ExcelReadTest { @Disabled public void readEmptyTest(){ final ExcelReader reader = ExcelUtil.getReader("d:/test/issue.xlsx"); - final List> maps = reader.readAll(); + final List> maps = reader.readAll(); Console.log(maps); } @@ -274,14 +274,14 @@ public class ExcelReadTest { public void readIssueTest() { //https://gitee.com/dromara/hutool/issues/I5OSFC final ExcelReader reader = ExcelUtil.getReader(ResourceUtil.getStream("read.xlsx")); - final List> read = reader.read(1,2,2); - for (final Map map : read) { + final List> read = reader.read(1,2,2); + for (final Map map : read) { Console.log(map); } //超出lastIndex 抛出相应提示:startRowIndex row index 4 is greater than last row index 2. //而非:Illegal Capacity: -1 try { - final List> readGreaterIndex = reader.read(1,4,4); + final List> readGreaterIndex = reader.read(1,4,4); } catch (final Exception e) { Console.log(e.toString()); } diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/IssueI8PT9ZTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/IssueI8PT9ZTest.java index 297213e3f..37ddcb1e7 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/IssueI8PT9ZTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/reader/IssueI8PT9ZTest.java @@ -16,8 +16,8 @@ public class IssueI8PT9ZTest { @Disabled void readTest() { final ExcelReader reader = ExcelUtil.getReader("d:/test/test.xlsx"); - final List> read = reader.read(2, 4, Integer.MAX_VALUE); - for (final Map stringObjectMap : read) { + final List> read = reader.read(2, 4, Integer.MAX_VALUE); + for (final Map stringObjectMap : read) { Console.log(stringObjectMap); } diff --git a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/TemplateContextTest.java b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/TemplateContextTest.java index b22b36806..def486b64 100644 --- a/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/TemplateContextTest.java +++ b/hutool-poi/src/test/java/org/dromara/hutool/poi/excel/writer/TemplateContextTest.java @@ -12,15 +12,16 @@ package org.dromara.hutool.poi.excel.writer; -import org.dromara.hutool.core.lang.Console; import org.dromara.hutool.poi.excel.ExcelUtil; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; public class TemplateContextTest { @Test void readTemplate() { - final ExcelWriter writer = ExcelUtil.getWriter("d:/test/template.xlsx"); + final ExcelWriter writer = ExcelUtil.getWriter("template.xlsx"); final TemplateContext templateContext = new TemplateContext(writer.getSheet()); - Console.log(templateContext); + Assertions.assertNotNull(templateContext.getCell("date")); + Assertions.assertNotNull(templateContext.getCell(".month")); } } diff --git a/hutool-poi/src/test/resources/template.xlsx b/hutool-poi/src/test/resources/template.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..b78abfddc6d6ae89cd6d97ec3694994173e9d805 GIT binary patch literal 8905 zcmeHN1y>x|)@|IOaZPa70Kq*t!QF#2PNPAByC%2=2@(h%AUFX6B)Ai_AwYslM zlbN?>CNtkJc&~b`y49;|pVf8m+2@?QPid$iArk>m0q6h#fEHj0&9yT_000t^0RTb( zI->Ct7qBM?>}js!>k9HP0U3&oo!Yn;l9 zbyDb$_e1*#*fb?ReNO2uw=&MNx4+MexdzG<5IYFg5{xbS@g9xX)q$NGL!*1!w6Nns z`akKKQ3`T@>Dy!MBqdLFH!?iPC!&;kL~d^W(k2^_>DJVv#V@-mtz1cAM@%9S{3Cav zPY-{&w*|Z0s8qNg(zT+d_YGfYuxtwWV}kIjgFUOC*~t%1CFD3dzeN%+vtkWe18r7I ztrmA!hDwJAOEcf}Gb_YzJdug*xJ#qUsBImB4^{ao>dInI%Z+*y9oakmP5fVUvb>5r z)qu4M5Zjq^8s|xc(1uRV0W=)r>Pf12!D9iRC5elk4jp#WEL}6M5>kC$rnGL&OGva< zBcpTXSSjwylT{ZMWD5;^*FVrK^htf+ipn2cGJ&>+EO&WNbdJB>dh$sIIPi&lqO+jBHFCiirCx60Me_+Haz)8|Wp@{TF=G3K8I8P)S24dwcN7R2bO=sz3?jiWC82G3CcBuV%^!{q{;AoXwx z;lXFd$BEn9#of`;#l`Wryj7`d>XOYv6!510KKMqh79#{XO=m=*K@mc9cEYH&9!yvX zuxYf{(!D)si%jGnQJKYM6xirK625rIwMhyQ`;eEZV?u;aXG>;S873t;F3uOhg}U6C>k@9l9d2L@&?rSOHp(dYQ7Qxy*0n9PMv+aI+0g0Hs;1Ia zmM2W(Ejbx>dvuHz2F8t(tyi%xRuD(Pug*s-iL$fX8t$N+@g~1&{{0eswevRIK8Zh}nsUDh_9f!K9l2?1( z+e*SYw9GGES_IScVK%iY(vWzE)y(BKFu+<1Q6ZJCi$wJK#Be2Rz@Q54M0ETEwP zHDAL_VNPf5L-DgK$;^aa`8K2%lxibae*03YkyTwbMn%XUwhgopg6;GKy#_+Q$MNZ^eAQF+I&T zSg)rlV%6O6^W?5C1@lkT2(?IS12{?y#ZuCc1Hs%>3K(O!J+$v}Ym z3FLXUHqP$0d5!HhpZ8O?rGRv*|h@?kxZ zjYo$b{W6r=ct-8|>k2pA$^S`%5Q)@`6ZkK!a4Jv$&=KG?_&r_xl??w$9SHDB4o;^3 z?xRvmRpm1eupR3zipM+Kix_|2lbdc&cNY(Rpq>@NM9UX=x=hK|YHBc}!j0q->3cBJ z=XLQI_d62dSr>b0ECKQhLZ<^!6qk{c5hQfW{i=td3MhmGdpo-o`&hWIJqTMQlKVOG zh=evSSs2Nqic08YPg^D<`5i`ip7T0*j6WEJht8q;wP0Ad_Fh$JeNz+7YgU`}`<5q= zbJRDXzSI*Z{ZE&nxb;m|L;?V&&;S53_#J;l zP7gZ}$kT)S=kVya5So*sngF2zMjoWWsDT$`5Vu8B_ECpv&*^sErNA7FhkY#1OlZu@ zVauYuF(0(ffmNU$vdqog5Q{t4@z}jjBK8Z(Oqx$I>brI7Ofyb56W$FxU>rSZ{61K( zF-b23tGT?i=n(Y!K><)t9B)k)_~wmbrN*D%68991bM$Mk1N3ONI%}8XkWI+`%cRg~ z)<#`1QbA1<&r?$s1Qq&53L{A=4i@O6z}f!MTzjL%(5Xdm^xBSWmY#yavjy>z3 zU{W1eM`H4PzcP2twy4Dw`fk$@iLqhYsf+&$ra9&SLi5)ri;}IG`UL9DW3dLMDzHo< zbKXIc6Aj5uhP@^BY@d!72q@i14h*TM>n*%CQ{4W&1!OT?99uCaJ}qHm`8rA&e3gfi z(nzXA&x*PouPe`qFk#t@#9#d@ZoEI-W4bT-q~^-|7|X~JO}k;JJ&P&yOhv8c!K9rd z;Jj{&WbDOzQd4(~W2BV2X_)iFovv||^7fj4BI>cocN*VK==LP zg2UuSQ1HyC)|k=Z_8mvbD;}-psE4_dxyD)_4T?stVCggDqN5L3y>(TP1q=Kz)?ewo zJ^Xa#iO;M?+Er#q8Q?Vjn9P;NEniBiU5EF?>P`@Az2<2SW zC3-HJC+nvsc9wYLL(ZuEY}S~DxqK*w*#;ZSPDdB(Ye7lFE>546c>rOv*SqoqjWVh!x?w}jZ17DXYyE}%MP2tF-vu44aLBa{di(n zvc42f9>p=<+E)L&o^f(9Z>O9DhiSaIJ<&#+#F||^UNIo@#1vkf8vDvQea8)IdgXRl` z9_69u%~IP$n(5zPwRJDH*WO>*&Q9b-yM;ceQNMb)(_9OTYj;Rf&nG`}bPCb-5wJ20 zMP9Ty+2Mb(xguCF-MSeujhyuLxmId0MDzoB)-ziM)7ERpO(e{wvXwdunGb~96qF>G zqT*Fb$mU1UHlyT)4@hBIbtm|N941k8Tr1LjXJ6kKFLj#9`9G_BrMvc5!{U|H_*r{B_>ycI2oUS9ri_dkm0ER?5X)T3H5}!yWjW76x z);ai_(Zg0OA5oOaqio(oaoSODG9=AS%cAqebmKTnfNu=!6{wd?qx=2;O%jOr1|E&Qo{;~waxsc1nmOcWq*AbErZCz|1#o|BW(7^8CtVRP0 zJ@E01D8-rWu|cP{&gT|b={ip8I%6134>fqvLClPLnE7bID(f+z$=ci~Tw%x)d?04L z)9ib6jU(%rwjRUP@_gC~E2u7Hxb0)7e zWX^)AY4IV7d6jiBuP9v+vhu73bGnE;z#m#tx_lbmE+abEzPrt=CLqkhaCbQI4JVsQ z3h<)%!eVG3oWeg-YksKBqPeyR>PD5c*`TC5pv7ZZ%7UUHQ*L*dphLqdcTxutlho6* z7&Fi^vkrd5jso@Akjh=6ePt$9(r!ab(5Q{3_ILbI9KhZ;5+dJ5qR*T~KIVUGbG?@y zffj*YkoGv%iQ5Jw@2My6-yJae&9?cU$(TCu^?S8Q=vSOsZ(0V(vxwuf$0jrzz4ypW zDtTh3Ly6Ilz3B9fhnHF#L07KMZ4TA z1_}~_k>~W*tIrv}_E(3?LAnbWm)>hPjDBY#l5$QVHsBSm8Q*CRd2?`UK^ei4Hz>B= z2iV;kTr;sR@kUA6AqMP5Jx58+0;^PuMlma7WGqlxFVGaEWh=?B_mHW&Y39N#26Q)C zO-sJ!Ge4;fq*SIDnThIeAWFhokkU3~wcE+@UaZ0YxYG-=Ln}VJkZAt(#GM}r6_Ek-l0LK=4=t@AMBII zO$IZOkJY@=jiHviMgM&%7JFS?Zch=A>O>J~~|_p8|Q|Nyng!yvANhbrm`; zTc5}w5b9Y(H#7_)Wh#;JI(s6k`@~nYFpi9vFP3XV*d%5v@>MJ3vs4>Y(3DGfsyOjfU8~s*(S0Y8zP7X3*dsYVe+2ceNtn0qg=@ zAQ1WcL{!Q$Be6*_L5F}fI!VCQyc-wgVXPR*7Yh999FV*Sl#qK1rYRoHX2wpYa}#-> zYb4#Ixs57aB!KQ<)~O$aNf;NMVw4zUN8XK3WJ>(TSm%0%Im0?&(95|ynN9nRPI+uI zY)z};;BM_Z5SYts5ikd?_p>No+QMZI?3^vHFRIbsj?(-fxu+mqA@08;VvD)wO_@ZE zYm`<)B1bHF%5baKHhH>xR=vE}h#GidUmG8iw0W%g8L_*t5y?g)5F3fMt^gj>9kE3Wz1s&!#<9zP??MC*M&CG;7r_h3i=_5v~y*EB&nptHz z1EBb2(|4m}MT5XB!fJ+>N9lT({JvLo<-_Sy6~x7;2;r5MA9+i1TES^mr8LtqY-Pym z1@$zjjW4$Kic1*Y?=f~QeL9h^rg{3E#Dc9Z2mxPqxl)B$yO1H0lg!oz^2~yvZhKve zO_hYIbmlJ6y7XK@M5^H%ihX6mcl307-Lmc+Ky^iIDCqRjQjDmZl9v?X+K>sE)p#Tt2Nj<7q@A#*Rait&HAcLB*A|TjK=QL}py$q-)X+skQ4Bq3#?N}z<$3vo18JF|i8dF0T zIvP+I+Bl6^N5HglkaF@%dx+)pBaXp7G-o!9hFy$Psl0%KBrzmiip^ z27KVmn=t<1tXZ^LafoAY2S}B2uPAs!n6v+N_HH|0Z`2v(>kkdV+XrgxAW9HLG#T~G zduMeRJ!RO;#&Z-Ttb4mE!+1%vVKdbYQu~$o_W3z-T)VBO-SdkWQJWvG#BzN?yzj~` z3MGDsJ4*oaizRdPsLV{47$HfWB6F6DkowbXd*p=xXv(v-+=!0Nw@72&k@UP?y+zVn zZwsi06?*37G9$&It4Rmdo3Oy^P~+p(uRPMiDWX+gm}gZq1WxzK;ceR8;{K*7|GvB0 z-aKD3fN!#I;B+DSgDQ3w?jUPzPj`E;?N7#3ri>`}ND)O`gdXq=cVxi@a)#|fnr4rJ zHgKf%0ycxUrHvML0hTl}DT-Vdb$D_F3ky*}Hc60KN!jytcA<#xNJ2{^xvTycIjd%E zZbT8KLj(gTLd`b1k1SU(-aP5+Lc11CxH6>y@Nn&A05|VCHl||Qb1I^tDSv^4 zD{?=>PfL#`-^yrIq$~H#@{Eorln)^1DJe|+S~0CkpovT7ONUZ?J@ZI8gu0~i%6oMo zxvkNCsBh@_qYL5sf?K{g3v{2clv8RSW)zb&Xz7eCtNn==ovB)tWQWm040b2ybs=F0gZ&CxNusQd3lqK%dBHi z_$@0|#$S=!h-9Ub3Qmn#dWq$bs>^@S7t46p^uovHBJ535+u}Qi$M|P5(>s*+H=Kn{ zv$rV!7PQL0wfn2VSHd1Hjo`zj5o;GK4R;q;4{j?LchDcbt^X+^a2NGY)>IGUA&OX5 zy}^5XFy0+GPw_0~^;I1slO=!06WL!bf=1tk}I?B!a z!TMAh>F8=Ls5WV%0?KJs7x~Hvyj_F^#+C!|ORWJ1n82oe?t@}zbHGak+-{GqEsY;XbI= z7#){X^Q7>Z{HNF=VtR`I8t#NZcsKz5)d?+JUH|8U@G1M_$Vu)3Lw;*$pulh=p)Yg5 zERj-rns3=(%+&ytUg(2FNZ3?DKT{0kfifPT?%{YXKs-M^EUJH5q6X1+VF>y@tDyDW zA2L@Nks0relC9>R9x~Oz57w?Z+u2zo93o)TXWM;1X?DDnpLRY;>uQeWEkC&VJzLT0p)$x>=KEt?!$DHlZ z%gGT3QgnmZIAG-jroHmj^ww6&d!Fl$)6Y<-<3hL6^AC!;a)(i<-&vNWMF^7*DbFK^ zN|JtlTne_w0$C;(elf(N2pCSjQgajq%~vUpuM$=2POwCUPdDHwQ9}}W27`hE#cytp z?l)b!l&Bp7guoB_Hi~l2afqk{yik$QFrvcQ!$>BZ917?<5X2rJU0@?YgFjRvxcYbu z&#FJ=Za>VsW@2fgx1bJq1m&vg88l}Lf9L#=?27lWEq>t