From bc13f67a294ed54ffeb41354ccfd3e7a9d128dc9 Mon Sep 17 00:00:00 2001 From: winter <2436197699@qq.com> Date: Mon, 26 Feb 2024 14:18:56 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=AD=A6=E7=94=9F=E8=AF=84=E4=BB=B7?= =?UTF-8?q?=E7=9A=84=20pdf=20=E7=94=9F=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TeamModelExtensionApplication.java | 2 + .../controller/frontend/HelloController.java | 43 ++++- .../model/vo/appraise/StudentReportVo.java | 3 + .../service/impl/EvaluationServiceImpl.java | 64 ++++++- .../java/cn/teammodel/utils/ChartUtil.java | 181 ++++++++++++++++++ src/main/java/cn/teammodel/utils/PdfUtil.java | 42 ++-- .../pdf_templates/student_report.pdf | Bin 0 -> 27332 bytes 7 files changed, 306 insertions(+), 29 deletions(-) create mode 100644 src/main/java/cn/teammodel/utils/ChartUtil.java create mode 100644 src/main/resources/templates/pdf_templates/student_report.pdf diff --git a/src/main/java/cn/teammodel/TeamModelExtensionApplication.java b/src/main/java/cn/teammodel/TeamModelExtensionApplication.java index b25bb74..2ee5074 100644 --- a/src/main/java/cn/teammodel/TeamModelExtensionApplication.java +++ b/src/main/java/cn/teammodel/TeamModelExtensionApplication.java @@ -10,4 +10,6 @@ public class TeamModelExtensionApplication { SpringApplication.run(TeamModelExtensionApplication.class, args); } + + } diff --git a/src/main/java/cn/teammodel/controller/frontend/HelloController.java b/src/main/java/cn/teammodel/controller/frontend/HelloController.java index 126e3ec..a237804 100644 --- a/src/main/java/cn/teammodel/controller/frontend/HelloController.java +++ b/src/main/java/cn/teammodel/controller/frontend/HelloController.java @@ -1,12 +1,18 @@ package cn.teammodel.controller.frontend; -import cn.hutool.core.map.MapUtil; import cn.teammodel.common.R; import cn.teammodel.repository.AppraiseRepository; import cn.teammodel.service.EvaluationService; +import cn.teammodel.utils.ChartUtil; import cn.teammodel.utils.PdfUtil; import com.itextpdf.text.DocumentException; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import io.swagger.annotations.Api; +import org.jfree.chart.ChartUtils; +import org.jfree.chart.JFreeChart; +import org.jfree.data.general.DefaultPieDataset; +import org.springframework.core.io.ClassPathResource; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.web.bind.annotation.GetMapping; @@ -14,8 +20,11 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; +import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.util.Map; @RestController @@ -43,8 +52,36 @@ public class HelloController { @GetMapping("public/pdf") public void freepdf(HttpServletResponse response) throws DocumentException, IOException { - Map data = MapUtil.ofEntries(MapUtil.entry("Text1", "1000"), MapUtil.entry("Text2", "2000"), MapUtil.entry("Text3", "3000")); - PdfUtil.fillStudentPdfForm(data, response); + // 设置response参数 + response.reset(); + response.setContentType("application/pdf"); + response.setHeader("Content-disposition", + "attachment;filename=report_student_" + System.currentTimeMillis() + ".pdf"); + ClassPathResource resource = new ClassPathResource("templates/pdf_templates/student_report.pdf"); + InputStream in = resource.getInputStream(); + ServletOutputStream os = response.getOutputStream(); + // 处理 stampter + PdfReader pdfReader = new PdfReader(in); + PdfStamper stamper = new PdfStamper(pdfReader, os); + + Map data = PdfUtil.data(); + DefaultPieDataset dataset = new DefaultPieDataset( ); + dataset.setValue( "IPhone 5s" , new Double( 20 ) ); + dataset.setValue( "SamSung Grand" , new Double( 20 ) ); + dataset.setValue( "MotoG" , new Double( 40 ) ); + dataset.setValue( "Nokia Lumia" , new Double( 10 ) ); + + JFreeChart pieChart = ChartUtil.pieChart("手机销量统计", dataset); + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + ChartUtils.writeChartAsJPEG(bos, pieChart, 850, 440); + // 填充表单 + PdfUtil.fillPdfForm(stamper, data); + PdfUtil.fillImage(stamper, "praiseDistribution", bos.toByteArray()); + PdfUtil.fillImage(stamper, "criticalDistribution", bos.toByteArray()); + // 关闭流 + stamper.setFormFlattening(true); + stamper.close(); + os.close(); } diff --git a/src/main/java/cn/teammodel/model/vo/appraise/StudentReportVo.java b/src/main/java/cn/teammodel/model/vo/appraise/StudentReportVo.java index 24a3df8..b39dc18 100644 --- a/src/main/java/cn/teammodel/model/vo/appraise/StudentReportVo.java +++ b/src/main/java/cn/teammodel/model/vo/appraise/StudentReportVo.java @@ -20,6 +20,9 @@ import java.util.Map; @Data @Builder public class StudentReportVo { + @ApiModelProperty("学生名字") + private String name; + @ApiModelProperty("学生表扬总数") private Integer praiseCount; diff --git a/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java b/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java index 964069c..5824ff9 100644 --- a/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java +++ b/src/main/java/cn/teammodel/service/impl/EvaluationServiceImpl.java @@ -18,13 +18,21 @@ import cn.teammodel.model.vo.appraise.StudentReportVo; import cn.teammodel.repository.*; import cn.teammodel.security.utils.SecurityUtil; import cn.teammodel.service.EvaluationService; +import cn.teammodel.utils.ChartUtil; +import cn.teammodel.utils.PdfUtil; import cn.teammodel.utils.RepositoryUtil; import cn.teammodel.utils.SchoolDateUtil; import com.azure.cosmos.models.CosmosPatchOperations; import com.azure.spring.data.cosmos.core.query.CosmosPageRequest; import com.itextpdf.text.DocumentException; +import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfStamper; import org.apache.commons.lang3.ObjectUtils; import org.apache.commons.lang3.StringUtils; +import org.jfree.chart.ChartUtils; +import org.jfree.chart.JFreeChart; +import org.jfree.data.general.DefaultPieDataset; +import org.springframework.core.io.ClassPathResource; import org.springframework.data.domain.Page; import org.springframework.data.domain.Sort; import org.springframework.stereotype.Service; @@ -32,7 +40,9 @@ import org.springframework.stereotype.Service; import javax.annotation.Resource; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; +import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.io.InputStream; import java.time.Instant; import java.time.LocalDate; import java.util.*; @@ -591,6 +601,7 @@ public class EvaluationServiceImpl implements EvaluationService { String topCriticalNode = criticalNodeMap.entrySet().stream().max(Map.Entry.comparingByValue()).map(Map.Entry::getKey).orElse(null); return StudentReportVo.builder() + .name(student.getName()) .praiseCount(praiseCount) .score(appraiseRecord.getScore()) .beyondPercent(beyondPercent) @@ -608,10 +619,59 @@ public class EvaluationServiceImpl implements EvaluationService { @Override public void exportStuReportPdf(IdRequest idRequest, HttpServletResponse response) throws IOException, DocumentException{ - - + // 设置response参数 + response.reset(); + response.setContentType("application/pdf"); + response.setHeader("Content-disposition", + "attachment;filename=report_student_" + System.currentTimeMillis() + ".pdf"); + ClassPathResource resource = new ClassPathResource("templates/pdf_templates/student_report.pdf"); + InputStream in = resource.getInputStream(); ServletOutputStream os = response.getOutputStream(); + // 获取报告数据 + StudentReportVo reportVo = this.studentReport(idRequest); + // 处理 stampter + PdfReader pdfReader = new PdfReader(in); + PdfStamper stamper = new PdfStamper(pdfReader, os); + + Map data = new HashMap<>(); + data.put("name", reportVo.getName()); + data.put("praiseCount", String.valueOf(reportVo.getPraiseCount())); + data.put("beyondPercent", String.valueOf(reportVo.getBeyondPercent())); + data.put("topPraiseTeacher", reportVo.getTopPraiseTeacher().getName()); + data.put("topCriticalTeacher", reportVo.getTopCriticalTeacher().getName()); + data.put("topPraiseNode", reportVo.getTopPraiseNode()); + data.put("topCriticalNode", reportVo.getTopCriticalNode()); + + DefaultPieDataset praiseDistributionDataset = new DefaultPieDataset( ); + praiseDistributionDataset.setValue(FiveEducations.VIRTUE.getName(), reportVo.getPraiseDistribution().get(FiveEducations.VIRTUE.getCode())); + praiseDistributionDataset.setValue(FiveEducations.INTELLIGENCE.getName(), reportVo.getPraiseDistribution().get(FiveEducations.INTELLIGENCE.getCode())); + praiseDistributionDataset.setValue(FiveEducations.SPORTS.getName(), reportVo.getPraiseDistribution().get(FiveEducations.SPORTS.getCode())); + praiseDistributionDataset.setValue(FiveEducations.ART.getName(), reportVo.getPraiseDistribution().get(FiveEducations.ART.getCode())); + praiseDistributionDataset.setValue(FiveEducations.LABOUR.getName(), reportVo.getPraiseDistribution().get(FiveEducations.LABOUR.getCode())); + JFreeChart praisePieChart = ChartUtil.pieChart("五育表扬指标分布", praiseDistributionDataset); + ByteArrayOutputStream praiseBos = new ByteArrayOutputStream(); + ChartUtils.writeChartAsJPEG(praiseBos, praisePieChart, 340, 330); + + DefaultPieDataset criticalDistributionDataset = new DefaultPieDataset( ); + criticalDistributionDataset.setValue(FiveEducations.VIRTUE.getName(), reportVo.getCriticalDistribution().get(FiveEducations.VIRTUE.getCode())); + criticalDistributionDataset.setValue(FiveEducations.INTELLIGENCE.getName(), reportVo.getCriticalDistribution().get(FiveEducations.INTELLIGENCE.getCode())); + criticalDistributionDataset.setValue(FiveEducations.SPORTS.getName(), reportVo.getCriticalDistribution().get(FiveEducations.SPORTS.getCode())); + criticalDistributionDataset.setValue(FiveEducations.ART.getName(), reportVo.getCriticalDistribution().get(FiveEducations.ART.getCode())); + criticalDistributionDataset.setValue(FiveEducations.LABOUR.getName(), reportVo.getCriticalDistribution().get(FiveEducations.LABOUR.getCode())); + JFreeChart criticalPieChart = ChartUtil.pieChart("五育待改进指标分布", criticalDistributionDataset); + ByteArrayOutputStream criticalBos = new ByteArrayOutputStream(); + ChartUtils.writeChartAsJPEG(criticalBos, criticalPieChart, 340, 330); + + // 填充表单 + PdfUtil.fillPdfForm(stamper, data); + PdfUtil.fillImage(stamper, "praiseDistribution", praiseBos.toByteArray()); + PdfUtil.fillImage(stamper, "criticalDistribution", criticalBos.toByteArray()); + // 关闭流 + stamper.setFormFlattening(true); + stamper.close(); + os.close(); + } /** diff --git a/src/main/java/cn/teammodel/utils/ChartUtil.java b/src/main/java/cn/teammodel/utils/ChartUtil.java new file mode 100644 index 0000000..fc7796a --- /dev/null +++ b/src/main/java/cn/teammodel/utils/ChartUtil.java @@ -0,0 +1,181 @@ +package cn.teammodel.utils; + +import org.jfree.chart.ChartFactory; +import org.jfree.chart.JFreeChart; +import org.jfree.chart.StandardChartTheme; +import org.jfree.chart.labels.StandardCategoryItemLabelGenerator; +import org.jfree.chart.labels.StandardPieSectionLabelGenerator; +import org.jfree.chart.plot.CategoryPlot; +import org.jfree.chart.plot.PiePlot; +import org.jfree.chart.plot.PlotOrientation; +import org.jfree.chart.renderer.category.BarRenderer; +import org.jfree.chart.renderer.category.LineAndShapeRenderer; +import org.jfree.chart.renderer.category.StandardBarPainter; +import org.jfree.data.category.DefaultCategoryDataset; +import org.jfree.data.general.DefaultPieDataset; + +import java.awt.*; +import java.text.DecimalFormat; +import java.text.NumberFormat; + +/** + * 生成图表工具类 + * @author winter + * @create 2023-10-30 11:12 + */ +public class ChartUtil { + private static final Color[] BAR_COLORS = new Color[]{ + new Color(79,129,189), + new Color(192, 80, 77), + new Color(155, 187, 89), + }; + + private static final Color[] LINE_COLORS = new Color[]{ + new Color(237, 123, 46), + new Color(90, 154, 213), + new Color(164, 164, 164), + }; + + private static final Color[] PIE_COLORS = new Color[]{ + new Color(75, 172, 198), + new Color(128, 100, 162), + new Color(155, 187, 89), + new Color(192, 80, 77), + new Color(79, 129, 189), + new Color(44, 77, 117), + new Color(247, 150, 70), + new Color(165, 165, 165), + }; + + + private static StandardChartTheme initChartTheme(){ + StandardChartTheme currentTheme = new StandardChartTheme("JFree"); + // 横轴纵轴标题文字大小 + currentTheme.setLargeFont(new Font("宋体", Font.BOLD, 15)); + // 横轴纵轴数值文字大小 + currentTheme.setRegularFont(new Font("宋体", Font.PLAIN, 13)); + currentTheme.setExtraLargeFont(new Font("宋体", Font.BOLD, 20)); + // 背景颜色 + currentTheme.setPlotBackgroundPaint(new Color(255, 255, 204, 0)); + // 边框线条 + currentTheme.setPlotOutlinePaint(new Color(0, 0, 0, 0)); + // 网格线条 + currentTheme.setRangeGridlinePaint(new Color(78, 74, 74)); + return currentTheme; + } + + /** + * 线图 + * + * @param title 标题 + * @param categoryAxisLabel 分类标签 + * @param valueAxisLabel 数值标签 + * @param dataset 数据集 + * @return org.jfree.chart.JFreeChart + */ + public static JFreeChart lineChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset){ + ChartFactory.setChartTheme(initChartTheme()); + + JFreeChart chart = ChartFactory.createLineChart( + title, + categoryAxisLabel, + valueAxisLabel, + dataset, + PlotOrientation.VERTICAL, + true, + true, + false + ); + + CategoryPlot plot = chart.getCategoryPlot(); + LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer(); + // 折现点显示数值 + renderer.setDefaultItemLabelsVisible(true); + renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator()); + // 更改线条颜色 + for (int i = 0; i < dataset.getRowKeys().size(); i++) { + renderer.setSeriesPaint(i, LINE_COLORS[i]); + } + return chart; + } + + /** + * 柱状图 + * + * @param title + * @param categoryAxisLabel + * @param valueAxisLabel + * @param dataset 数据集 + * @return org.jfree.chart.JFreeChart + */ + public static JFreeChart barChart(String title, String categoryAxisLabel, String valueAxisLabel, DefaultCategoryDataset dataset){ + ChartFactory.setChartTheme(initChartTheme()); + + JFreeChart chart = ChartFactory.createBarChart( + title, + categoryAxisLabel, + valueAxisLabel, + dataset, + PlotOrientation.VERTICAL, + true, + true, + false + ); + + CategoryPlot plot = chart.getCategoryPlot(); + BarRenderer renderer = (BarRenderer) plot.getRenderer(); + // 纯色显示 + renderer.setBarPainter(new StandardBarPainter()); + // 柱子上显示小数字 + renderer.setDefaultItemLabelsVisible(true); + renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator()); + // 设置柱子间隔 + renderer.setItemMargin(0.0); + // 设置柱子颜色 + for (int i = 0; i < dataset.getRowKeys().size(); i++) { + renderer.setSeriesPaint(i, BAR_COLORS[i]); + } + return chart; + } + + /** + * 饼图 + * @param title + * @param dataset + * @return org.jfree.chart.JFreeChart + */ + public static JFreeChart pieChart(String title, DefaultPieDataset dataset){ + ChartFactory.setChartTheme(initChartTheme()); + + JFreeChart chart = ChartFactory.createPieChart( + title, + dataset, + true, + true, + false + ); + PiePlot plot = (PiePlot) chart.getPlot(); + // 设置扇区颜色 + for (int i = 0; i < dataset.getKeys().size(); i++) { + plot.setSectionPaint(dataset.getKey(i), PIE_COLORS[i]); + } + // 设置扇区的线条颜色 + plot.setDefaultSectionOutlinePaint(new Color(255, 255, 255)); + // 设置扇区的线条大小 + plot.setDefaultSectionOutlineStroke(new BasicStroke(3)); + // 设置标签颜色 + plot.setLabelLinkPaint(new Color(255,255,255, 0)); + // 设置标签背景色 + plot.setLabelBackgroundPaint(new Color(255, 255, 255,0)); + // 设置标签线条颜色 + plot.setLabelOutlinePaint(new Color(255, 255, 255, 0)); + // 设置标签阴影颜色 + plot.setLabelShadowPaint(new Color(255, 255, 255, 0)); + // 设置饼图阴影颜色 + plot.setShadowPaint(new Color(255, 255, 255, 0)); + // 添加标签数字百分比显示 + plot.setLabelGenerator(new StandardPieSectionLabelGenerator(("{0}{2}"), NumberFormat.getNumberInstance(),new DecimalFormat("0.00%"))); + return chart; + } +} + diff --git a/src/main/java/cn/teammodel/utils/PdfUtil.java b/src/main/java/cn/teammodel/utils/PdfUtil.java index 5f67ba3..6a95419 100644 --- a/src/main/java/cn/teammodel/utils/PdfUtil.java +++ b/src/main/java/cn/teammodel/utils/PdfUtil.java @@ -1,16 +1,13 @@ package cn.teammodel.utils; import com.itextpdf.text.DocumentException; +import com.itextpdf.text.Image; +import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.AcroFields; -import com.itextpdf.text.pdf.PdfReader; +import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfStamper; -import org.springframework.core.io.ClassPathResource; -import javax.servlet.ServletOutputStream; -import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; import java.util.Map; /** @@ -18,27 +15,24 @@ import java.util.Map; * @create 2024-01-24 16:02 */ public class PdfUtil { - - public static void fillStudentPdfForm(Map data, HttpServletResponse response) throws IOException, DocumentException { - response.reset(); - response.setContentType("application/pdf"); - response.setHeader("Content-disposition", - "attachment;filename=report_student_" + System.currentTimeMillis() + ".pdf"); - - ClassPathResource resource = new ClassPathResource("templates/pdf_templates/template.pdf"); - InputStream in = resource.getInputStream(); - ServletOutputStream os = response.getOutputStream(); - fillPdfForm(in, os, data); - } - public static void fillPdfForm(InputStream in, OutputStream os, Map data) throws IOException, DocumentException { - PdfReader pdfReader = new PdfReader(in); - PdfStamper stamper = new PdfStamper(pdfReader, os); + public static void fillPdfForm(PdfStamper stamper, Map data) throws IOException, DocumentException { AcroFields fields = stamper.getAcroFields(); for (Map.Entry entry : data.entrySet()) { fields.setField(entry.getKey(), entry.getValue()); } - stamper.setFormFlattening(true); - stamper.close(); - os.close(); } + + public static void fillImage(PdfStamper stamper, String imgFieldName, byte[] data) throws DocumentException, IOException { + AcroFields acroFields = stamper.getAcroFields(); + Image image = Image.getInstance(data); + int pageNo = acroFields.getFieldPositions(imgFieldName).get(0).page; + Rectangle rectangle = acroFields.getFieldPositions(imgFieldName).get(0).position; + float x = rectangle.getLeft(); + float y = rectangle.getBottom(); + PdfContentByte content = stamper.getOverContent(pageNo); + image.scaleToFit(rectangle.getWidth(), rectangle.getHeight()); + image.setAbsolutePosition(x, y); + content.addImage(image); + } + } \ No newline at end of file diff --git a/src/main/resources/templates/pdf_templates/student_report.pdf b/src/main/resources/templates/pdf_templates/student_report.pdf new file mode 100644 index 0000000000000000000000000000000000000000..6191a2b0d1ead5389046b692f891cb472c09687a GIT binary patch literal 27332 zcmeFYWmH|u(k_f!@Zc^9E{lb`ySuv+oP|rU;KAM9ArL&cySuv+EVzE`ea_iupZo3e zj(x|tKi~DMXV0qYdY-PX*)@C3j|w7U^h^wFNFTSh$ET4HnAia%01`VRDj4JN-ri}7NR>~k7 zK0YUqqp6_{5`x9riKednvJ~nw?IYZeuC+51cv5g`=p`j72uZv6;ArcB0t4|-Pt})a z-kPABQg)$28u_{&!>!fD4Cb0`++j68heGK0oy_zpN@12yoWr$dY6yi$PHX@hO;prK zcw1KHba-kgW)14E=3+oYfE|X@5~mqUKKsaoRiyhnYC7gf&Z6vn(&`lW5%>O--4DDq z{_bPYba99yG<#oS5h+?HCYVR05w+eOX74AfgUj&#N)=`V*nNm_l(_reo^^}tdO6+r z1nYy`wz2O2bFY<={47oMA4mzAQ`6kBB&c?=M zxDCrro^ta&{Pg`G39;8Of6MZE@Ut{U+~^a{*ikhGLyg>)hD@OYdWaDWf5vRetYPeJ z``R2zSu#raJ=xs7K~efz|EiaOaj>c8Y zmx4%LfB4~cTCvMK_E@BU8;3nJ4sh3p_ms!bx_0}Z7KS4uHr+Nn+8hyzeEIUg z85uI8rSN@C)|el~d*5Q0c;bRe%?4Ns>QPdJHfzKTR``euE8_Vo_Z`0a*Z#VZIO!V5 zU6?rz&ggN(Uan9Zc8g*$p(r7?rJ~f_py1~_zBV2;DW$r<06F8uv8ye$VB@#)MvuxT zPWJ{asvJf}mfCIe=73U#LId6}SjSSx7vA<>PO{~pGWA$Aq|hWPcCMO)!!RgtU5?v{ z%?C{CzoJ+w9nK$XjGtbHTY2;A7UmcVD>`Im%}$##anoTB54f#;+kQrxZi7cDiG6o$ zq^f@Gb#;JirG?Nn33@NNi~ER?9*o4sOWUq8GZf-#CxQGctG)QkSOMHsoXp zk0HP2iE9o{yIn%_Cg$%hgtPNm`L&H*p!%IK$5w6<=5ryq%jl} z8b4HgG41_pofWtt>0%wNNyr5{n8* zK6x#f-&QVcue|~?~SyO--h&vT~b~fFhj1yTY-g;X>m5i;d(1P@Z zy<5JB-A-H4p0S8zN#XA4)ClA?6DH)w3BAaGu>YJl%!X0^b}<{&b#S$pd)tKhC8;QH z%7#j3Ege}~Y!iEGvNp%w=lW)Qwnz=bhm_C;9|1e>S6N!k?^mni7%!LxU|O4Xen<$W zwkH3~T5ql2G9VK>)8EL2tpCo09B+w`>A&ScV66&3p{jb)l|f3DZg6DWNs>--*1j4D z1OS-;Kp+bXfE5UwWUEqO2Pn)377sB_*~<*dOR3t+Fbv5{(J8`F4XN8Zr~!Zz%q&yP zKmee6V&-;KUXXQY0CfPs>WdFO6R(t-E)}Th;sOQ^1Evv02mY6!fd4n3SONbtCWU`s z8e<%#RRql3j>%9*vH>9wV0w>&Rj~4pU_TTVVJ$C$L*an!AG}-tOMjUEZ~S56_#Yht z$qgd}2p~QscnRJrveOI*eY#LXJ(d;8M=D6touprAw<|rU2>uWU&-}hZP$)4p&WTSZ z8?f7o-sI}H5(RMlD8`@uyfOfJrc=yv%dxu_M$4=By#8r1${LzRGlC}d$+Km;CkMLd ze87~lQ{+?R2?owe6-=D<9UK)q0r(LTeur+jZ!;UrN*#Pp_?(tv1{5m{|S@JRs}aBr*Tjz*B#lBLzUU3YZW% zG(Nuf{?k+oI<&BN!$|HHdUm{@P;{F-SvszgW_0P9zE*5pN|KhfIqb{^+zdi2yab&T z^bt!i)iB+l7jQnGq#-1{=(^0Q3hSUYoA zR0A*^FY4UC1jqU}z_I;-jg{$t3P6mZP6U4d4%mkJeUyjA=QJl~97w?y6;!SRR6^kV zlIi;l1-q<__9!5NrvgG6SGPw*z)xd)Z#-AZvo&}s$X`oA!`0A{6@tGye<@N|TtGzF z%ov(y9jXE3kaYw|p*M5=zZ>PpLr7_&$?Xz8I!mk%Zp}uGQLrqs@IM*hx92aSe7a=X zv3SWtCZ(wO41oyNZ9v!cm#EqP25MH0KVUO){Dzz3zs+f&nvLBu2jUCuL!-}uV*L)g z0abM6A)bMTZ$Z;4)=q#CZ6siE$fT*^WS;orN83~TW=O4JvaH~Is#F;v_>Yo8u`K=|M1Ej(ar`c8I+u6_=&HV~_L+MkmI zYu$W3$Ph6_kueH5hm!F^F{^xryjEpCC+A@cIIdS;$yX;N)wUyP? zx?9Q;{e0!R zHi_adth_TrbH)wxm#{2-p?K4q8-SaND&wNwgO1w5r1g#mFOC9yNe$?A@$DU7GJ44b z;ZMEcJ!RB}>{j%IEV(uXyo{rA0W(^Ju&ll(cuWKx=7dSDY!)~-YBO?%96yUefU@1S z)>G>Nr=kZ3-@MvWgFeA4SwzUuGXUo_g#u&R0AjQHeF7jE1!OKt&TZJXXo)Az1Y8y2&q2RrlbGUmy^IZ_Pv9h#zTkLn`p zZYK&{6Gt&8^^sOZs8PTHgs+*Y_p-e!2-Kh6J*ZJIsNrmBZp;$DW(NI;}A#LA%;bFv~?CL|ihFKhoJ5-`^E!!YglbPXCKm7ZeSh*SXj^n|!8MVD+~ z8f_ydB!ya@UOaZshlm&su`M@I0?IyW8eNI5L$bBLM9`tPt1G_s;=*(N>vYaKJ&_t^ z`K9gT*|RGK*Iu`Itb&wqz%Tlh(mdulcJFVkAfbGZ4*nlNueFJ<=G(p2h%_O|CO z9k1~is)Auq&gDy6AVE{V?vIP-@iFOURE&xsJ>2yN&Nx`JFgw%eB1}U`ff`UZ2PHJ4 zq@H8!Zv2j_7=qd+H#u%(EySc~Z?qqbL;bG19FRp*jg$I&EQY8Q&<=8*fbg70cpAr~ z4=@p^qBr(#W|HLg0@&A;s$47DZ3x#d!8`=l&rvgTc7e)CNnm4sz`YBer6?1bm@>hJrdWfa3%w2bGyBEfv$rE;me6=j5qpk`?RjOCI6e1? zP9W^v2ntA?Cbg5>!7H{c1i*RkKEv&pW=23%X93%Cr+{{QyVt+R)~S!Cw@*uZ@noaG z7bbUD!@VUPXJE4iHT%s6*===5^U&&q8z#*cId_~1E6BOoUZ~6itB~>wrrPaUVA40% z2d(Mz{(Cr{!L!pBbOW#(ri-b+%zo^DBm4d7fyVLM0}c4!lHZ4M>39ALsL&hjz+tT& zj`>FgRKaLA%s@R0QijVIUAV8Q*)QI^y58YVW*gCwq)=1v(Fmln)dT9uw@%zDzgW~( z>~3sZfYD%{_pJS_wt`!8x!&7`Nrjq0;;38L2^z?R^NKhM$pR)S25^Csero9Pp^&nY z0kdVh}&-3t(ex3mH7t;vZf$I6GM>Uzw2rq zem8qV<4>j_5+hS{OIu#Dv*va(5=#?aGIds2fULc+sfDG4hoh;ohn$MB$0uV>6Ec22 z1RggoHyeAKH)|wrHrBRITyDH%hHraaQ?9r6Z{3V!B)^M*KJk(X{&s^zLso%A*v`?E zgq4Af-Wb5dPQuB=z{JMF!p1^J^0s#cFap>ZnONzW09-%-7l4)IpFc7_gtr!tqlp=p zl8D$phkLu?C9?p5?70{jU0q!nT$vf{9L*V-I5{~P0YF9|kp4}A-pSn-Wavh3>qPz! zBmc4^V(Mh_1-9zmHk8YFNd?S`AbdvKk@M& zdT%%0hGYIqB|{SnJ7d>>6Zs#Cg2s+^Mus54-(=M796y;^+qwP&@bB~S51M%1Jm!+M zGqE&t7kPWN!}m6gEc5^%JrJnE1mpq$xmW?T01hqyfQRw_ko-5*zuORgd&%?mYUn>~ zFsZzS0xOUU$ns|!f0Fz^Z2T*>|I^BU@#LTD;CI>o!_My`*g2}$*;(`bBXs}C1&M;A z9f^qWTd*=P0U6#3Cl-!>;QF)1pNyFpbD7yW+8BcP4DIc$EsYI-3pmEN8R234_pLw4 z|33X(B6h~kzlDjU2%odFr3u&D0$~HZE#@~;+1cq?jLZP^96%rwJqLh;)5wg|kj=!{ zjW~iH8%a1T>t>U#tZ;3)3dXfaMH7wvUAcKG6R|EO<9eZfGlPv z#>UKVj{d`^Kk5F-?i&)WH%d&LjZGc@22=kb{wFj43`4Fr_ufK?iHGq&JN`n_#njR1 zjY__^b@XrPe|7#-o`>5kO25Um$rYLlCu1}c9RI@>gXWp0E1#f zY3^jv^#dc1w)Zt6g{?x>nF5z(68QlxQI#zPAj1tI3$lWEAEMB4gbYh!(q%>{=WBut ztM`Sfo;;nV!*|Qp-}g%nWS50OmnHGLAjCpAwh3R|WJunsXn(@)Lu5pV-_8Nn=;7%9 zij?0#{r7X;fBDVI{B{EHuXNbpqG`RwHR`Y`5t%DcbvsEgH;0$r^^=ar;?75Q`0HVyrwXHQIQZN7y2 zR#@~-e(NRfjj@(QbNmwel@}IolJNU_oB-zCZ>-<;okDReGD`*%L1=*s40NTLD43s6 zE;q8))pI6RkG%*I8jh}yZg#t${ zVVJ**Q1!{ab%(=-n>`t)V!CcR&sfrm&5AWcug!K05AGS+88`v7Iq4axo&=7g^UVf# zB-;y{R2pg8qYM5|h@V0yRL$tkQa%LyF|W+839U8H^pBspdpOhIyTSV}qCQr<(hX!n zy9=+);kMTC4LBN@Rt1^eeqqHQ;hO`K|3D%ywH)T z_eGL9K}j;Nw63B$XEoMYLX-j@)8O6DEN8iYf98Ju&aNi9mR_)DKBkFE`Ggn%4>pi z*QlikivJ{JGHKPLACrn66^wk^;_$uwQG-!2(Qu?vC8isObLuTmS9-$6gUv$qxZ_Xp+Ls7os`#3f?+&ZFJ zCe+I?b~CtQnl;4P;MIJ9zFo#0vY)qY1}N%3;LwrXHK3$f$ngVcHBo|n4MSEruzQl- zUc_uxoe2guZcd$K13nJa-00FunDG&0E5l-;;-T93cSpoqLcksyf{7z~28*9yenj1X zPnQ!d+x}Hfye}rFDG0~cih^7)V+akE723d6q3A!m4o|cOk1Lb~8i8(>X~|Zy`AKEV zOQlw*Kt>n~`8kK49co*KtVK5My*0^%{^ykM{qZyjGLzAZGdk-FE9JI{aZitGoTr?5 zO6SX{1NcH`TDw~>*iU%Kz>Tr7cl~4Uh|>bdCCmt0KB~V5#CZn8N3tB1w)F_oJ&hJ& z&q?O1BnApRDq|`o0I~0h zc~HYFsAIK_!*#oq>!RMlamYn_T_=}Ycg_JB{30m3JsL4M_+f8ceenfWGMOM^&!jXh zy2x;Fp~@HvQYQ4}!70l>6tI-@;47w$6*C~5tsTAIoH6nGhz~+J$qc(cfj-T9Uve1HTDlGHeksTYQ6UIXHxdO5gRIyD5byHMwzROB7;yi?k*W5i94_Xx}<)ic%g zds7d{5J<%e&LlTtQi%@w4yTSFGjXT@Ty!90d@wpTBRrxFBKD9C(8FL zM6D$qG;zq`BGp4sh9=g_9|jq}DNPVjV7WoxS#y2W3t;lWTPu0;XeC&0@LO!z7bd&+ zM5|KO5xY!9uqr$6<1&`#G&J&OIake4^kiwYGvx2)?X^c`w!>(Y^L5Y2Tb&=GWmG47 z%J0U)t5%r(DkTUzD*VZA5*&vslTr=#aB2i*KW%@cVjceTc7wnF+o;!E!* z4s$-;#ljNM8b(R19V#%Ar*<3M-UE4}zauAm3761(rlqGVT`2&5b6%_CED`G+K#K(n z9F71gXS4yfvrn*}JANAo*D5!8diBmaW-ISXg-p0~{@~?9%}79QV+}_o^`nH&fR>DU zwt2&{?02z23Wu-iEz!jxOj{l#R5S?SP|%7U8{m#eBLc5JtGvvJ-S&|r0U>VW!4R6; z)kI9TO~E9#*yE--xwJ{pro# z)18=SN|}$iUIPKI-3i4@2SypOYfYn6t;wvp8(2f_Fd|m$FIleITWU2Y#mZUF&y+|S zW9^dY?>dla(xwxz2Quo;pHrI+qQnS&~+oqSvJdfCa6ILEbe}b7Idn z>ygefC;hDq-k<;v)@8f!;SDmHw(xS4^QB+1BWeDXg@3 zLii%^isTcTp4Mx2rgA<;Y=b>W4ty@s^uV3llkeJ!+6c!z!isk@RgFK;)?`V!iiMIK z4|c#dpx~JX$0e!O;S+=t*ez zN1Lb}t21t(ET#IZMgXv8fpt*QPLaUr5n3s|7zsY@QE6&dXvE5+ll(L-i2eV|ww zu0bAcJ-`Qk-+efxBa5vqC(`neeGqm^~U6rVbXjheqhk01*Rw0srbp@cprI$n1&+0Ng6FK-S zc7-NsBH1%igOBr0X(%SaHc;$=0ALLw9^q{iia$COP1~cTEk~d?J=nZm$u! zP?-PjX(8S%v4~qwXPJJ2N=yM z1C*k_rKVYhvV4n1X!KGsnl0C;k#=^`{f4GG=GgZ1V1ssa>hM*>!uywy#!9oaTHv?3 zUD)-XZA;Icsy@b)JluIhA(kQ^=2<p#6;$~UKT(u8e$E8iGygE)f7Y;WSe-&JguTbuV&sn*l;}?o71k^9lfO^~lWIuKe zOCBumK#NPBSDZZ%69rH5+>^79exGPjq+zTCB!oeS@S#*_xJrCQE>{ax8=KN|*lvR( zTxsg*lhI~t7ym|Ag;z%Ce4SCIjZF~W30Bi6m6~eQXcVdiC5joXazgQ!9q zx1t`t4u^E5A!3w$7i5&Xc#2cj&K+0oQVUG4SdwjKQ)^N!*CLe+(K7XOh95j__S=-0zB{mpsG zGmC^uE9|`rI9dr6x{xsXs>Y#VRzY8U#M;d)5ahJ+-OYuED#x@f2w^8@Ym&2y1 z!-XQetIv)$-8qG0W^UWV2Fk3G=|ci&?DmC4W!qQOv0!X>+!$M4fD@AZ7nWFQ+q3OErn3 zHtG{dDY{r*KuP9IzVS?z^y}O`MOl3=*3Ks3&4U%cz9Mz(UY3Fpy`t#_smax}V!@Om zp@MdV>!KHsJT!uWSptj@Q{<%?yN@7n*Gu6=_s8U3%11j)`rY|Nj9pu{Q<-`$wc)+i zEYs#2EoNZ^CWh(YUrM{n;u+WV+L7&t#M{I4vz;ug<;eQfvIy2hfy=fFa?YomkPf_6 zCCeM0BS@I<9ENf9akN*rE*rI+Va0-VTl7b}zk#P-F9*Ad?w1dSA(8gJQZ_?9v}r$~ zrwH}MUL-ue3cIAhiaP8%=twcQ*B{%?Zhu{Sy1nkX&SyBAA*fdO7S4wRc8Qd_V1dVh5Qaf(R};b)Y!#!gltA z8sm_JD;$WQk&P-zw-MjH{v1zAj~1exz;g?rTUV;DFo7l1RdR9r_Fxce5H(}*E5z;s zOgTkKF8n%YKjNgqERUqC8f$W#Wejp5$gTcWGZBbiG9mpXd`6o|(G$&A62tq?fVI}+5n7>JkjxIBZ$i8b9GV6xO)IMl0- z$-)I&t^5a*nJ0bbnRP`Htw8tWZM_XcXvB`LYD*I(WhK`w^FlUZ*!kVk6aythg}a^C z8HwzlhapG;%9@^=yNn*EbI;<}^jh}@x9s;<)!J2+U`8`)kdy`n{F=tN=!b`Ej|{|c z9EaEV$%uS;rbAAXl-*wkuYA^&=t^mAPCaVolx*iPX3h>iHzyI%izz2G1DJS8qHgCr zb$E@K`|B1cEzER$%9@QPV;iDh(Q7qK8IRflcXj)b2x5bEA!y+tS+*HA2P)w@(3!|V z7^4eC9aNKZOdn%X<1(7ny*~tC$FlA=LCK7=nfEaV4+F!L7h*v_bF3-GV)j95Kjc&s zxTSTiC3P1swq^3FCw*eSd|jJ`63JE_$}=w0(~SgKg!wvOh@r?l*lrl!Rs;phxwV2f zjg|ZNTCja(7NB$r0XO$;U0cejUv$sG}apH;=nALy}TX?;TWI)VAj zUfyZTzwA)Z&;=>YJ4gg~GeW1LP?(Na$3{;NPyxEOlR1i6}2a4#yTqD@i(O1WvR4^ zWmctmmSwcA+3@3}_bT~gQ|*1nIMuw$qX!!>Rnq9wCx_U=B9W(&v@WcXbwpn*;sPfg zK+mTbFfl6Ww({{;X5&u92`S*hhr?~e z)nOmvy!qK#s{zsL%g;l~4_AeKi}ZsaD}?4fWdTX^?0<_&c7IdH;bRnP`)F4=QlIjkgq z7s))t%skIvuj0?%JYRF)Cfi{}-z zVN9cxhXdN1Z}!(RA-hf3?=$^~Q-M~_cB^lx>MnG|h_E7&SB;+KM0=9|!k=87sjxed zIc9H+?tLTfyfx4_u-+`#yv=!oR~50zGI~SlTD*bTn6_9#*VpA;Vs^UN zrHR!DfmwxkH2RYeUK2eJqg2F9+4Jyxge%tUUg`$DBn`(`m}pV>FVX%8)bajY@f#iO z+*HtR#;vXikH&EE0$~-iMOI@A^2wuYk@cHx;qdwKjDYW(vKJEX{kzz5EornJUM2by zGR0{I$fXq}!IxC;Jh@tGsd%+Ai0mp?awkncXK5xGODkdGo{!9UG>NR8Rn#xEP7n2*5;KvpSI%dC zZp$`qaPusM5zH$=)+u9kVsB8|RlLci5a;PRk4 z^73mhTOvQ&Wg21UI_s>Mr@HR!r#bLWDR}y@^bEPFu{pE?^OLAKCQ{VkIp%RQP2>tUFCQu}WPJQ|hY=zS@O#VIp_xTc%@~vs%Le{3}AWz=#(^ zkOXxOuzm|znQS~i`#wxmm};9W*AO@L%O~)nS@{`=$wedXqTO;I3vXhjt|3GX(LB5; zAYz4}RV`BUHmw;?bZ?X)a3qMjs*^@7byaL>pNxbIeN9bNMWi&B z#6Ti>#0344j0e4ooGQ0ODLQ-MQo(h3wUU6|MZ3AOKX1QWcm8LI>v^B)8I;BNWE?-U z`JU_9^V-{{C8Ls?2K@T9>ADAgEG#-UTcxfM)I`?SQVdXRqtvyFETRbmuO5B~Ris{# zzGl3g`pNUDh5S3uUK@Dhi41w6F{SDl4TKcEmk=Z>HxY}B`x5k)2gFamYA+5d@|<^V zp?+Bc1Tm@wz?K>LwU4Qv0w23%G7k$gbq^%iWf=@(=R3GGz{$^%umLmdY#)b6gip9Z z=K|GRLcl_y!93BzF?+h%leQh0x4#bdXd8mV7uB^fqy8FyA?Aau(GtvslX&~IY=< zq#kOY<|Il?+!8nfA;|=|l44L5FG)3a;57`NCtCm`$+Qu`4Kv?gyHOAo&x+iGX72|O zE8u>Euw^jFp}0^6Pooik+RTzX;d|7ET-ThnC6Jrr{V++n&?U||Dr-duM_J$tyuHP*ZBc+dZSxf{b*g7va07)p8@Fqsu9ltl=06$Re>~{;1 z8GL$8S})KR{0!;#?n2R#IBO67Df|vOnQci3+1gsNbPRnLZvi2%WpQq4CT0=oxjk1* z6Gz}Qq*q7~XN_Y`Sw)7kOd~*nIy_Q!Xs@%3ku++Vn;2VaGRJzXRxgLfr*_^2YE}hP zHfoqau``Qn;pi8T54{K7toFJXF0;6>g+U_vxs0CrhmIoOC#t%EPc~z0x|l_iiZtdP zxZM1C|z)OK?pE|4V(6)gz!%a{MGQG9q=0r#@>bayMt@~^l1xMdy;-ODZkMAs|RyFe| zs^JiPcZr{S!KaSH@iVi%y}aO)Js`e?D!W^Q*qWGmMNALbZ&Mf~)2x{M(CQ#`$hsp> zdV1VTZThjWNA=XGIWzOA6S9WtaCJPm>08U`Q|pMg9)*5i0w?{hb(yhEWz z8u=WZHuO)Uv>gdka>?S_R!G?AQni|=$LX&XwzxCiV8&V!ZNLNhZgVg?HCbZ`V| zp!>kvJGIN(_#=sW9<_920O(dncipT6xf2k{~*P61EYawE}E^Tsl>>* zGLDv2>kx(Az(4%ugcpyre5`Bm;}_+lu%bXh%D9yU;jc8cE%rUvf}U}vxCR&KzA$mI zvtJBAer#>ub!f#sil9RP`Ab$vkCa#pPkh|hPQ#Y$5HpuoE))FIuWQKWo!tOkMQ;KY ze-Z3~8OYWdWOmn%Z2Wfp9~-T80F!`?1;N#gy3Mrp@VT3S5@`@$#Z-LnoUP-hTC>40 ztq_zVFQ1=hr=FEX9+VZISm0gPu>-om1O;Tr0!o%Ic?UHLZ(jntfxT8cPi@#EECO6mj-+BN-tj(B;<^zBwnX zm8q3@RcD1CeEE-X@I7_5g5dz8-H-YRIwX9sSP_|&u-o`9n#v-J6l$i4^E1oxuIA2A zx;bLM3~*EG!2>=CBKa)wrI^zQ7D;n4ReZO)b;Mmkj0c4y7L^X_95zB(K!}~g3$45vBl%Tk5IgR?)#dIekJW$)p-!1%Q&|f%srI9x zqX}+27fn?nKS)V{w*}H30NEoQyz!Vt;j3wn;QzkQoZrHubZ*V+WHuzz4t#u21E(EK zj4|*mRZgN3`F8E}MQ=w}?t|5o0$x0-kfF&n1ob?g#@vz0>q+!QXW%gBq@-oms7q?gN+^WUcXtU8H@TdE%X)Lj2${1H`l_st?oo6*D}s@M%c5zaXDRP#0Q? zdqJgt9viY*k8xRt_FW0rk1$LZ9Ls&-c!B0R>dEiU0D=~&Mk|d9xxQR`BMh{Cz)wCd zIqL9~U%AGs{`V8FqD9TYW&ZW8NCjv33Mq*9M-(I+s8kTNuOY#fbEOGkc|A-v&_&bC z5|I)g;MNL1iDe zufStWQ#l~TZ~D7=zY{vrf(3J`3{xM7fM6m*Q4ksvS}-OYVKbKs0cPh%gVQ2+^E8JF^+%rZGt!YN zAEALfQJ0@hkhrvTqb!S3<~e1kY825SG%r+v|dUH*1%zS{z*~5RSMD-|$n3 z4RxJyLg)K1WM_#%W^RabU{w--@@PwBgF^5IgjACpRrx7HiE6;sIStRvHXiM?i3ot1 z)_eS>JYroO9+or+xvk#Jhaj_Q=~53P)%kuCHcnloF~XxvHMrjAvcv$-&`wLIe(ab= z571TLT!)C@e*l=$+zXroSOlbJ|QV)?of5-l*iGNx#@aIKKtge|k&j$*!H5;0SJpowMYpE0# zA(OR3R(51&N66V-aEs4Bpu$ckltB64oK=hiqnbJC01Aa%@_FgagnDEXSc8xocow9jV6xtj%X`jwU;!h(4cx#Uphj%rvfO zciTQO=qPuAqku+mskr&XUVJ~{_&dVn?@{L z;*K{(RQ0Eb5k<;nxZd;jhR9l%*MghywqI7wvMYC?E6|6;B=TeG_vYG}FJXp`Dd;FVKm}kB1zG*l78pS# z(~Qfps+hS2eTAHxe4Fi|=43~+%LF$+4!xe9AX-R0gDbd>`iQ@MzIbWR;PW(&6E%I; z*|xPlQM+}PZAMIUo_n7ikwQ*o4M&I2n?Ckayy5-H&wVNR?>KS zA=0ymur84X`>4XDy*0r*q-&~JOYalbsF#Jr#&QI7P(E=}2MNmTkxI}N2Il7YMd^l@ zR%UpYzZ3N$nfY|U;}VeYODV8yVPl3vmq`CLvhvOrnI3K}uWY*vz0AqgGwyVUmk5`i z_odk(ZQ1H3$cmO2&n6>f6^n$7=2fA^O#Z1pu(bL}{QAJ01{8=$j~ybiRUf&ZkA}A1 zyO|`>joW<(UD&_S?OJVCl1H8I3Rs!-?jl2rGm60L&vqTS!Dm>bTM(v(2QLIeP2!D? z&rk{J2F@6ne&d~3I8)hfP*a)?8%R^@;b4&=Xx)@SHr#-Q{Kmo=H<0pEuD?HkW<`Y1 zvUtg}QQ&()z}x3+%``b&Grzi66v9@5TVoFkjbf-yq=dKq5g|;fqk-G=>C$O&%*sj) z)@z2mM9$6@)(0n52>p7({QBq<8g88?WxwW{I4VSs2@QXI@jdirdt%SRKpgnkwrt=3 zvD@M&oD@;$m57Q@GhD$Grkmz-j`uaq^Mz8k;ph)5by&*rq6xYlBo~l{FDFR`M)UB= z_(~%eDXa8X2E|qSSOYZ>BsB)R0NmrV=;Ai)D>Uu8UyKpM z3q771Jn3@V2RK4<0!$dm5g)z)KYFvUe|3Z99AIMycR;~KUeh)<+I~zZqTB<@bCl-a zEOc&L8}!$}p+b*MFMmcJy_fldbdbf8nIw?S!4d_5&n{RjG``AL&z-Q~w>20yO7@}X zJ0*G=m^rdTr++dr<-WcHP3U|pR~7z5qI#7m>Im7sMfGx9Q;xrqb2wLN1)sg!x84l6 z1iSBzc_X#Nr#~%sl`*)NPH$F>CcF_^y|UoM=e;eOP)s4ftck@I=Ud?Uei*045AD(_MY5(?4Dpk=Uv$qpHp4SMQ8#?Ejz3M9@~ ze^sBHaoEVpbjd}+fr(A;=ItYRZ_8>v`RQldxDw41j9J%;x=ziY4;gG_8iWfX2f{Rd z+|UVkV9O!aJpUWTj0`TT)IJvWRqUtIWR!<7JKD|an2F#+?@&U z^L{|AUz?cdP=QCH@TuzUmWsDsu|Fb?Xo2Y65}y(DR=tSvsxf|7_AQ;tk+5c`?AS*^ zvE-#V-beeli40fndI4;4^@T%jDqmyc~XIg4#ou)OE{=Z7r@z&<-49ZFn+Q#TQ`^P-+pgTLCkP1%n z-_G|#iLI}{E9l7KKD>+!3>RnCzn%#VTrb(pn%>eHKBAd$ zg3fgObox5LaGPB?#uA~t?BsZ31oF*ml5w({O{uJyHJxi#GpiGt^;Z(dd^e1-t`r`kYJg%T`pn5@Rqtvj6oZkK+tvC%DSUS&MQ?thk>Sj7GK3gArH z;U0Hi-@oVePa>NVD6GgU!Efbyh#g@^zzVx7(H0NF8VJnUvG?arSr#?1mx)tdGdnxM zljXy5k32flI5@Pj(RZ+3#rU&KOkPEl%X**83vKOpjcWUpYO+0f@eCu}6Z*xo8w zf2efBoS*Xe%CzvxMtmg5@nO;{?=+tFf2dFtLx-L>6JAkrE3b;EsCj*bXGR< z>QT%7gL;EB*+B4#EG-C|BU;+*tP5S>!>LU_j`4Z=z@36CPl#2Rk8zOosVC#{EoLU{ zx{N>bd`Huq*kIG(^u{$Qs!&H+uG`NnmMjwF%1L(e`#^!@($I1V?#45&SUVw5ZATt3 z37rOi+8|cDywXK(xXxb1M!cT=d)giR2zoUOp3he_dV_`hanHaJ*)A79jg@0mE{re$ zOO4`lGM_kc5@|qtl-oV%z2CN*tW!WKM?jq@b*-xFt=q7S`;=Mj&jD~G2u@i71A1fN zIxaxiM2J6#1FV<$2|6eSb{d(E9Rsz%qjK$o>!Jr&idx>B#O#eZ;X0pGNT;E^Gxx%o zBDvfVK7t*J^b>2}E%V^J5t;+Z-i$H1&JFX%U&)?5ykoAD5ouyzVLEIaNe4Rt(DrgH zGCD~7(W!VS8Aq)Xo}yMkIo|ejF{a0R-G`rjYm6*rj@I}+AE(F#P|x(-2s+_%isqFW zin{@Ag9d|!y%!BiNs2?p2{N%W~vQk`L_GP`K18>exPYz<1 zA(L(_7~%TGp&b8O`N17t@}Rei#rb}=$_hm}wEL=v8+!^OR#cL{z7A&WY%z$XNH0Uuw8zwVd9ItNu{U3`8cQ zYp5BYTXhYsa*_)cwFMj?{xHZ0Oql(k(GzdSxT=^;Fy6fpaaR<%QlooqsTW(Ic-j5gy&D{|^T6NV3QF+ZI$4dPb!dl2%P>W) z$n(2*s6v7z%0FW|znmxFzQDY?twr92n0f{53|>27Q^ZVF=a$d$R7g#dDIIGo*d8La zbamob#GRN=mgJ5zFTV?I#mbwDu$|lEfbB-!O)mDS`a}b$4Kbp+cpw(Yh5hjVHFg$m zQLbAXCx(y^kPcx;L271b9F(CHq&tW1?nYq9p+iy{q>&m@kdp2cBt!(1ZV?bZ_CEWZ zZ+l&y{eAz!?^*A<@8`XqbuaG@JEF9>F5@%Yv=;;i-9{6K2MeM%1Ua$8O7D%p^nB6Z zG+K~M)X|jW^?S1^>={xqR@PQB>~TDBN4KHJI9GR75Q<)Ej{KZ-6`fXfHe+cdnvriE zf>a4$v}Chh_a4f|1H95$M7Q;xTlAV9%yPmXGYBc9gY%c4<^~Qc^%YDMaUw;^qkki@dR)b} z{d`N#qbi72An|yvk4JHFZTvPmk1A9FPofw`!lz0`PS_1;c&5=hJ;I@Y)9_691ePlP zg5SMksW(U@`|XGGnNX1*>Ex$!?l0&rLKwd?m*^=g;@hHS@S-&DnBnE1nKktZ8>K+*KKF$GPc5*KqJFiE*iZw)^{A$GS@YemRuo+0DX|G zz+BuW!QPHyDt3U{O=DD&km#dAht!ErGo(Dn{nz3U7*9o1_00)9SJlc?4TCG*5r z_l(>=YGuaNmgYMR_JYz z%OLq$nszmVv?YmpGyAE+0WGs*)8sge@6!DqfOXyI={_wrLDTU#*T!$hVXYxb(FL|v zh>#S@pXOVdTu#_x20^RWIU`u-_eNS?qws{!2U%%jckJ&FghKt2r1$u-Ef&$Aw*AKGHoJ*1NjF?sldtDaPwAHSFCXt8`|@BsU}FvaAd@YOUw5r|=3y7?v%bpT z|1gW{>ii`w{$c$mC;`PgKT|&{PdvtitqOvjAA~!7j?a!k$-c~5v9h)qolJ)~j>5v^ z@zvQPTmr$L_6PpO}&{u=q>_Qq9Vlg#m9Kt3oL zUr?4N2Zl679uum&$au7K@VHz?!?mVk>0!>mqO-%3z=d3vaN*;e*4{{dUS8#-Wu-qPyP__&?2m zA~z3_bNnhRws5Za2Gz@{nk6HV<@xAC#s&$))XK+!6kPh@hG@=IP2qaxqJ+|A3e3JL z52O9f*(^Te7}MQO(m-EqT`76-NTJ=7r#|6b>a$-gJk71B?UXqU1`zB7-SJw%QJSJW(M~FDSdat=13xnIdoQn==j6gvC}yFq6VT$wYb=LUUbDVd;C{0~R8>L;KNu1G zJRk~P+^uo2>U~%u&P7p-B$jWgrg5)YvHbf%{HJtpqmFCAadg_C;Qm>gy1S*=lVHqn zZ0ti!%eC~Bj?Dn^pR~>&GMR8mVIf}oqT0cJ4K0Sc^KZ^6n=mfei5V+HNJ0oJiek-7 zVc07k5;Ob476}IKykLlMv?HR`KkW(X4V~Hq(8_T%-06yVLih z{LCAI)9NaqU)WzUNjABU>UySP!}4dMmJwNU$|X$XM=8df?O}tkkNfBm-D8b|I?q!OL1IIt zkJDn+52%Nk1n-(|blV{_!VG#=7w{z82h|PA-{hepvXsreA7p^|%61e663+SF3#;cN zHW%x~sU9ipF7Y1_XMN_i2v%d&f0P#1S@0>kp1@OQ_=stGAuaN>^8p#vOFF0I2>qWZ zMJX3R&1cV4^f0q@TD0_^Sm;hgFA8DK58-*=r8V|w-*Ix3GUGPr9>z49lYe2zUFG3N zo3}zMihu}w25T#;Q}U&FlLEJAY58GxI5{oMLf=F1j3X6s>Dh`pAKfp3#(Beit1derhEwU~V1 z>So&b2Uf3_nmXDt-W)qkc-?|+saP+m!A8^*%OQt5ZW-(9hiz28!>_{Sa-P3cv&C2n zYS(qmEX%R4_5?iRkv3@DLhQH3^AopAuAw>(W>VHcE4Y65cenMt}dnhlK$k!2l@cr=~@(FD#mWWL18<0?s=Sv z%=Ed}xAWlf$&4sWx?xJL`tDz4SUP1L7$vA&27^}FZ?snCpr~vfaRWb+;PzEJG#ZSr4w@&LZT;k zWwvGaqxRW4DI=$?F4h50>2(}xG-f%MVn*ySBPBss4@s|No@&6Lrk1cfI;G{J1qGZ2 z@_&nitCWOPQJ=%{B?+PN0i`myvTCqy#aN_PDnhzcvun9Hv9_Ze7d}`J&j`FI$rX47 zzg8-=oY1sAn~WG8w6(36vS|Q1f*GUBo2~A(ezTOaBn_jtS0%%Z4vwjrX6E?j&y)sm z-YQK#;W;F(DnK5A(|)*;Y=vTvcHc@rH*J;uz+$`m_Z9*@jgu9OZmlcKFDb^v4f8bl zj46jdpdRlgcV2DkOeOh=ZA=>VWw{#8XYSrj4Xt-!B!KjnTKS7;w6w5u2-(lYUj*Fx zAv0|$uk+y&k$Zf$0aLF|yX%TRjK80&D{8bD*-x*#p113t8ST7hbJ&@Vc#~<_cKEs8 zJOtbFMVtKiC(A#qG6&L zB&{KTH>_O!facQ_KhA`}^#$e!@p20z@3P?~iP@D?VeMq#AOj@u%1WjT0Y0b^>u)pJ zL-qA9?rw*PflE!=(UmEOto&SU=l}@Vht!tce=;(VPyVLb3^jcg66D(35P7+?Nhix zRjCo+^Uukx*&33`aJi?>_BT<&yo=Rwr8^&zd7ykGLZ<9@8!=K53P!5ui-~al_#ybd zRvOo;3}89LZZwX{tm&bk^` z=;SB`<2(AE+_3N^RqtiO6>0HSPP=%k^PCeUx?2_naNI&avLGUW;KNdEHw6BKZd{T3a|4@w8nf?D2sUEI!oJ z+aOH5tleq+0;P`uknDF6V+QCj} zzp^rGqQQ9@oO-<2(kmuvrf0<#lYPAESvg|0=;_2)GnK{yeG#oo2H|N%7~am?e~&KG z{oOJBErj4Vx$1u%6GR03>$fpv(+wh){(gbfVT%F|IIH7CcX|g=`YRVRe0sK~t~?~+ zL2-Q>mJ?SqIcwex#ao|?iKS%OD~D;wtPq4JFFO|&T@BoHlqr92L5*~w$L@R zs$%1wDi`~)Bf9ekk=;~m+R3lqeM&t1ZUoZy41GV>4##-oxO`(2?f^iSM#t8ZJ6Sky zd@cE@&R&Cha#y&r|CrJ_8!7>*dn;7ni$FN?hxHmHtOqNi|Ap3uPA% zkDwV9MX@UC7j^e4C$+Twvlavn&MbzBVoUBzDW?FPb0v7Qymw^)^mdsts_CYMlCGE#PuMXo31?3T?x;) z$9_5Wie5ah#fqXI-J{)~0?djIe{fqs#CcwPcyrtFOHRUG{|@%w5)A))Rr7%$zry}| zRT~XBlVL?ODjnn#ZJlA#S-+yO(di%TdSNIgfk*z#smb+eLHUk$j?L1e{^ebETDS32 zU7c6GtuJx4-kxSu)2Z_=AwF}2&&CgDW_r5_Pq)y@>PVcez8{#UrtlSjJImGzm5-lY zU`M?%tqZAWraeYr+Tf6t;gNZ?PdvAUe?(`DYS5^ByWHx%F7|>vrw-Q7T*n_xN3Qt# zrInt)q^jz>hwQuo8UWNqab5WC!odD)VxkJ0pUBvc8axY+1F3I5`;qJ02IF5Zh*1(! zF^;4L_p+Gnt@5AenskfZ>6D&S9kc%`tHh*EVL3{g)lC>&^Q@I=+~WD#*Es5KX2013 z`De?Or>nOE52YbcpO~>HdjT&=wF2Hm-B!73C&}k7HhW|U* z|D0C+7i>Q8FYzw=2}^%;lhD5`O|;;3ATG+FGwP@D?&Cm(-m2HyPUBEb_j@|0+tp?A*aG)3h{p+x6-o8=5aOg*OxRagR6D(=; zovFxU6Ri()({7#i9m|yxkG^u+wa4yKX#4VQ;5?ni4^d9Zt@fmB^Vq1QB}t3hrCC2Q z*74*y-V}a=&3H7t-`y{}Y9|`mFr`I+9M8IkT*!imS6+W}AYo`dIclw29?cRXD5z%n z{Id95Jo#WDpD2OQT+^bESzj%daO z{F^^KWhVw++`jjhgD{3|HTw~QtEITIPHG=hRG;-*pV0Bu_u6cv<1!ioh7MiOj;rv<+Qh#B{^Il=w=XA+O^BJQn z%~;}&cH*nOh9H-kcPcW;n>zIDAH(fZBe*QQ3+3!03!yuR#+YofVt%jiEwWNMj7Z6Q zZ;_8DSt1igjUkoUlTADR<<){H{5Zww8Q(HyIBbWJ--zq6!$8d4emtVf+pP!v!I3_{ zBmVyiG=c~T{z5$duZlk=bDf7Lm*`buk(B*e@k{<_nbAufG?MbXewSH2f4X?^rr8F; zn~$#LFEOtj9!%sRVAj^o*$$dO{e!>s^HHc)bla_dF5T*<-e3CZe5;=$vWk?8kZTK8 z-J&O75xBw>&1foFp#gz1Bj7Y@flhF!tv; z!H_p`Qr@mrU4ZZK0191dXfQGpl?>hy2sy4v?(N$eF$>hc{?nPL5CvBJhAdd%|7X?t zfAN6HNn>)D;9F~QN#-5&nlJr{tTG6c#W{`B5ai;l~0m`qk&9vhyBh-IJTv%+dv zwoD7N=&%RH2&2%UiI51(^A1n3Nehyy5L!B3v)9hX=gQ4gaG%6mZ#*j$2>eDgZ7=Qmt zZid(0*UEE8$k|SEOr%)RVs6=vzBtPtAB3i*F?RQNXCw5tJgk51I#M=vv3I@Qf+Xo^ z=Wg%d3gqWib}=`zHg$7!0fKK0&F|JD$x7)#r9gtx!e9vj0gwzx8pbaval1!E7z}|) zN%Hf71%;&_Lxp6(f`USP0uU((pP&H0h={bHh_IA|FbFIHkr5VtNvs1ph0e z?5`#V7Ut(wb#%PlzVydcLX}s|+Q%FS7W!-PlD4Y31+SJK7zhD^4gUAjv|2VXLBn7J zboLweb)4LolGaj@c8h|dNMt}iC09SQTwek1-2@F%O9ZhELDBCiDF!!n_V-HeymSZD zc%a?+NDS=M#$!oKL1?D~HF+X5Ff0WEwWY;VM}2TyRvyOZ85>bBYN5~k4Dq%l$8o;S zjYre{0a$v+j4(3MCPJonz}A4hCv-;n=^~*N@Fm<4mK*BNH+