From fa39d491f68405ac4111f298d92148f0e07cbb4a Mon Sep 17 00:00:00 2001 From: Jim Bowring Date: Wed, 17 Feb 2021 15:36:56 -0500 Subject: [PATCH 1/4] Added reports to SquidInkAPI --- .../java/org/cirdles/squid/Squid3API.java | 21 ++++-- .../java/org/cirdles/squid/Squid3Ink.java | 71 ++++++++++++++----- .../projects/Squid3ProjectReportingAPI.java | 58 +++++++++++++++ .../cirdles/squid/projects/SquidProject.java | 32 +++++---- 4 files changed, 145 insertions(+), 37 deletions(-) diff --git a/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java b/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java index 53b4b0690..e944b07f5 100644 --- a/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java +++ b/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java @@ -22,6 +22,7 @@ import javax.xml.bind.JAXBException; import org.cirdles.squid.exceptions.SquidException; import org.cirdles.squid.projects.Squid3ProjectBasicAPI; +import org.cirdles.squid.projects.Squid3ProjectReportingAPI; import org.xml.sax.SAXException; /** @@ -38,23 +39,23 @@ public interface Squid3API { public Squid3ProjectBasicAPI getSquid3Project(); /** - * + * * @param prawnXMLFileSourcePath * @throws IOException * @throws JAXBException * @throws SAXException - * @throws SquidException + * @throws SquidException */ public void newSquid3GeochronProjectFromPrawnXML(Path prawnXMLFileSourcePath) throws IOException, JAXBException, SAXException, SquidException; - + /** - * + * * @param prawnXMLFileSourcePath * @throws IOException * @throws JAXBException * @throws SAXException - * @throws SquidException + * @throws SquidException */ public void newSquid3GeochronProjectFromZippedPrawnXML(Path prawnXMLFileSourcePath) throws IOException, JAXBException, SAXException, SquidException; @@ -93,10 +94,18 @@ public void newSquid3GeochronProjectFromZippedPrawnXML(Path prawnXMLFileSourcePa public void saveAsSquid3Project(File squid3ProjectFileTarget) throws IOException, SquidException; // reports management ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + public Path generateReferenceMaterialSummaryExpressionsReport() throws IOException; + + public Path generateUnknownsSummaryExpressionsReport() throws IOException; + + public Path generateTaskSummaryReport() throws IOException; + + public Path generateProjectAuditReport() throws IOException; + /** * * @throws IOException */ - public void generateAllSquid3ProjectReports() throws IOException; + public Path generateAllSquid3ProjectReports() throws IOException; } diff --git a/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java b/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java index a4368488c..ff9ec3aac 100644 --- a/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java +++ b/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java @@ -19,9 +19,12 @@ import java.io.IOException; import java.nio.file.Path; import java.util.List; +import javafx.event.ActionEvent; +import javafx.fxml.FXML; import javax.xml.bind.JAXBException; import static org.cirdles.squid.constants.Squid3Constants.DEMO_SQUID_PROJECTS_FOLDER; import static org.cirdles.squid.constants.Squid3Constants.TaskTypeEnum.GEOCHRON; +import org.cirdles.squid.dialogs.SquidMessageDialog; import org.cirdles.squid.exceptions.SquidException; import org.cirdles.squid.parameters.ParametersModelComparator; import org.cirdles.squid.parameters.parameterModels.commonPbModels.CommonPbModel; @@ -264,15 +267,48 @@ public void saveAsSquid3Project(File squid3ProjectFileTarget) throws IOException // REPORTS +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /** - * This method first checks to see if reports folder is initialized * - * @throws IOException + * @return @throws IOException */ @Override - public void generateAllSquid3ProjectReports() throws IOException { - if (squid3Project.hasReportsFolder()) { - ((Squid3ProjectReportingAPI) squid3Project).generateAllReports(); - } + public Path generateReferenceMaterialSummaryExpressionsReport() throws IOException { + return ((Squid3ProjectReportingAPI) squid3Project).generateReferenceMaterialSummaryExpressionsReport(); + } + + /** + * + * @return @throws IOException + */ + @Override + public Path generateUnknownsSummaryExpressionsReport() throws IOException { + return ((Squid3ProjectReportingAPI) squid3Project).generateUnknownsSummaryExpressionsReport(); + } + + /** + * + * @return @throws IOException + */ + @Override + public Path generateTaskSummaryReport() throws IOException { + return ((Squid3ProjectReportingAPI) squid3Project).generateTaskSummaryReport(); + } + + /** + * + * @return @throws IOException + */ + @Override + public Path generateProjectAuditReport() throws IOException { + return ((Squid3ProjectReportingAPI) squid3Project).generateProjectAuditReport(); + } + + /** + * + * @return @throws IOException + */ + @Override + public Path generateAllSquid3ProjectReports() throws IOException { + return ((Squid3ProjectReportingAPI) squid3Project).generateAllReports(); } /** @@ -285,20 +321,23 @@ public void generateAllSquid3ProjectReports() throws IOException { public static void main(String[] args) throws IOException, SquidException, JAXBException, SAXException { Squid3API squid3Ink = Squid3Ink.spillSquid3Ink(); - //squid3Ink.openDemonstrationSquid3Project(); + squid3Ink.openDemonstrationSquid3Project(); // squid3Ink.newSquid3GeochronProjectFromPrawnXML( // (new File("Squid3_Resources/ExamplePrawnXMLFiles/836_1_2016_Nov_28_09.50.xml")).toPath()); - squid3Ink.newSquid3GeochronProjectFromZippedPrawnXML( - (new File("zippy/836_1_2016_Nov_28_09.50.xml.zip")).toPath()); - +// squid3Ink.newSquid3GeochronProjectFromZippedPrawnXML( +// (new File("zippy/836_1_2016_Nov_28_09.50.xml.zip")).toPath()); +// squid3Ink.generateAllSquid3ProjectReports(); System.out.println(squid3Ink.getSquid3Project().getProjectName() - + " " + squid3Ink.getSquid3Project().getPrawnFileHandler().getReportsEngine().makeReportFolderStructure()); - - squid3Ink.saveAsSquid3Project(new File("XXXXXX.squid")); - squid3Ink.generateAllSquid3ProjectReports(); - System.out.println(squid3Ink.getSquid3Project().getProjectName() - + " " + squid3Ink.getSquid3Project().getPrawnFileHandler().getReportsEngine().makeReportFolderStructure()); + + "\n" + squid3Ink.getSquid3Project().getPrawnFileHandler().getReportsEngine().makeReportFolderStructure()); + try { + System.out.println(squid3Ink.generateReferenceMaterialSummaryExpressionsReport().toString()); + } catch (IOException iOException) { + } +// squid3Ink.saveAsSquid3Project(new File("XXXXXX.squid")); +// squid3Ink.generateAllSquid3ProjectReports(); +// System.out.println(squid3Ink.getSquid3Project().getProjectName() +// + " " + squid3Ink.getSquid3Project().getPrawnFileHandler().getReportsEngine().makeReportFolderStructure()); System.out.println(squid3Ink.retrieveSquid3ProjectListMRU()); } diff --git a/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java b/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java index 71142a8c7..6f38296a9 100644 --- a/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java +++ b/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java @@ -5,6 +5,7 @@ */ package org.cirdles.squid.projects; +import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -15,4 +16,61 @@ public interface Squid3ProjectReportingAPI { public Path generateAllReports() throws IOException; + + public default boolean generateReportsValid() { + return (!((SquidProject) this).getTask().getNominalMasses().isEmpty()) + && ((SquidProject) this).hasReportsFolder() + && ((SquidProject) this).prawnFileExists(); + } + + public default Path generateReferenceMaterialSummaryExpressionsReport() throws IOException { + Path summaryFilePath = null; + if (generateReportsValid()) { + summaryFilePath + = ((SquidProject) this).getPrawnFileHandler().getReportsEngine().writeSummaryReportsForReferenceMaterials().toPath(); + } + if (summaryFilePath == null) { + throw new IOException("Squid3 unable to generateReferenceMaterialSummaryExpressionsReport"); + } else { + return summaryFilePath; + } + } + + public default Path generateUnknownsSummaryExpressionsReport() throws IOException { + Path summaryFilePath = null; + if (generateReportsValid()) { + summaryFilePath + = ((SquidProject) this).getPrawnFileHandler().getReportsEngine().writeSummaryReportsForUnknowns().toPath(); + } + if (summaryFilePath == null) { + throw new IOException("Squid3 unable to generateUnknownsSummaryExpressionsReport"); + } else { + return summaryFilePath; + } + } + + public default Path generateTaskSummaryReport() throws IOException { + Path taskAuditFilePath = null; + if (generateReportsValid()) { + taskAuditFilePath = ((SquidProject) this).getPrawnFileHandler().getReportsEngine().writeTaskAudit().toPath(); + } + if (taskAuditFilePath == null) { + throw new IOException("Squid3 unable to generateTaskSummaryReport"); + } else { + return taskAuditFilePath; + } + } + + public default Path generateProjectAuditReport() throws IOException { + Path projectAuditFilePath = null; + if (generateReportsValid()) { + projectAuditFilePath = ((SquidProject) this).getPrawnFileHandler().getReportsEngine().writeProjectAudit().toPath(); + } + if (projectAuditFilePath == null) { + throw new IOException("Squid3 unable to generateProjectAuditReport"); + } else { + return projectAuditFilePath; + } + } + } diff --git a/squidCore/src/main/java/org/cirdles/squid/projects/SquidProject.java b/squidCore/src/main/java/org/cirdles/squid/projects/SquidProject.java index eb56f8ed0..57d642008 100644 --- a/squidCore/src/main/java/org/cirdles/squid/projects/SquidProject.java +++ b/squidCore/src/main/java/org/cirdles/squid/projects/SquidProject.java @@ -873,27 +873,29 @@ public String[] splitPrawnFileAtRun(Run run, boolean useOriginalData) return retVal; } + @Override public Path generateAllReports() throws IOException { - if (prawnFileExists()) { - if (filterForConcRefMatSpotNames.length() > 0) { - prawnFileHandler.getReportsEngine().writeProjectAudit(); - prawnFileHandler.getReportsEngine().writeTaskAudit(); - - prawnFileHandler.getReportsEngine().writeSummaryReportsForReferenceMaterials(); - produceReferenceMaterialPerSquid25CSV(true); - produceSelectedReferenceMaterialReportCSV(); - - prawnFileHandler.getReportsEngine().writeSummaryReportsForUnknowns(); - produceUnknownsPerSquid25CSV(true); - produceUnknownsBySampleForETReduxCSV(true); - produceSelectedUnknownsReportCSV(); - produceUnknownsWeightedMeanSortingFieldsCSV(); - } + if (prawnFileExists()) { // these are raw data reports getTask().producePerScanReportsToFiles(); } + if (generateReportsValid()) { + prawnFileHandler.getReportsEngine().writeProjectAudit(); + prawnFileHandler.getReportsEngine().writeTaskAudit(); + + prawnFileHandler.getReportsEngine().writeSummaryReportsForReferenceMaterials(); + produceReferenceMaterialPerSquid25CSV(true); + produceSelectedReferenceMaterialReportCSV(); + + prawnFileHandler.getReportsEngine().writeSummaryReportsForUnknowns(); + produceUnknownsPerSquid25CSV(true); + produceUnknownsBySampleForETReduxCSV(true); + produceSelectedUnknownsReportCSV(); + produceUnknownsWeightedMeanSortingFieldsCSV(); + } + return (new File(prawnFileHandler.getReportsEngine().makeReportFolderStructure())).toPath(); } From e71612df0ddde1110cd937c225bb0cb8ccfc56eb Mon Sep 17 00:00:00 2001 From: Jim Bowring Date: Wed, 17 Feb 2021 16:24:32 -0500 Subject: [PATCH 2/4] Added more reports to SquidInkAPI --- .../java/org/cirdles/squid/Squid3API.java | 28 ++++++++++++++++++- .../java/org/cirdles/squid/Squid3Ink.java | 11 ++++++++ .../projects/Squid3ProjectReportingAPI.java | 17 +++++++++-- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java b/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java index e944b07f5..177b82f61 100644 --- a/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java +++ b/squidAPI/src/main/java/org/cirdles/squid/Squid3API.java @@ -22,7 +22,6 @@ import javax.xml.bind.JAXBException; import org.cirdles.squid.exceptions.SquidException; import org.cirdles.squid.projects.Squid3ProjectBasicAPI; -import org.cirdles.squid.projects.Squid3ProjectReportingAPI; import org.xml.sax.SAXException; /** @@ -94,14 +93,41 @@ public void newSquid3GeochronProjectFromZippedPrawnXML(Path prawnXMLFileSourcePa public void saveAsSquid3Project(File squid3ProjectFileTarget) throws IOException, SquidException; // reports management ++++++++++++++++++++++++++++++++++++++++++++++++++++++ + /** + * + * @return + * @throws IOException + */ public Path generateReferenceMaterialSummaryExpressionsReport() throws IOException; + /** + * + * @return + * @throws IOException + */ public Path generateUnknownsSummaryExpressionsReport() throws IOException; + /** + * + * @return + * @throws IOException + */ public Path generateTaskSummaryReport() throws IOException; + /** + * + * @return + * @throws IOException + */ public Path generateProjectAuditReport() throws IOException; + /** + * + * @return + * @throws IOException + */ + public Path generatePerScanReports() throws IOException; + /** * * @throws IOException diff --git a/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java b/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java index ff9ec3aac..02809bbc2 100644 --- a/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java +++ b/squidAPI/src/main/java/org/cirdles/squid/Squid3Ink.java @@ -311,6 +311,16 @@ public Path generateAllSquid3ProjectReports() throws IOException { return ((Squid3ProjectReportingAPI) squid3Project).generateAllReports(); } + /** + * + * @return + * @throws IOException + */ + @Override + public Path generatePerScanReports() throws IOException { + return ((Squid3ProjectReportingAPI) squid3Project).generatePerScanReports(); + } + /** * @param args the command line arguments * @throws java.io.IOException @@ -332,6 +342,7 @@ public static void main(String[] args) throws IOException, SquidException, JAXBE + "\n" + squid3Ink.getSquid3Project().getPrawnFileHandler().getReportsEngine().makeReportFolderStructure()); try { System.out.println(squid3Ink.generateReferenceMaterialSummaryExpressionsReport().toString()); + System.out.println(squid3Ink.generatePerScanReports().toString()); } catch (IOException iOException) { } // squid3Ink.saveAsSquid3Project(new File("XXXXXX.squid")); diff --git a/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java b/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java index 6f38296a9..a566fc6ee 100644 --- a/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java +++ b/squidCore/src/main/java/org/cirdles/squid/projects/Squid3ProjectReportingAPI.java @@ -5,7 +5,6 @@ */ package org.cirdles.squid.projects; -import java.io.File; import java.io.IOException; import java.nio.file.Path; @@ -15,8 +14,6 @@ */ public interface Squid3ProjectReportingAPI { - public Path generateAllReports() throws IOException; - public default boolean generateReportsValid() { return (!((SquidProject) this).getTask().getNominalMasses().isEmpty()) && ((SquidProject) this).hasReportsFolder() @@ -73,4 +70,18 @@ public default Path generateProjectAuditReport() throws IOException { } } + public default Path generatePerScanReports() throws IOException { + Path projectScanReportsPath = null; + if (generateReportsValid()) { + projectScanReportsPath = ((SquidProject) this).getTask().producePerScanReportsToFiles().toPath(); + } + if (projectScanReportsPath == null) { + throw new IOException("Squid3 unable to generatePerScanReports"); + } else { + return projectScanReportsPath; + } + } + + public Path generateAllReports() throws IOException; + } From d44a50f13b37b7408a6d5255b0e51e3622e8858c Mon Sep 17 00:00:00 2001 From: Jim Bowring Date: Fri, 26 Feb 2021 12:06:28 -0500 Subject: [PATCH 3/4] Fixed #589 --- common.gradle | 2 +- .../squidReportColumns/SquidReportColumn.java | 14 ++++++------- .../expressionTrees/ExpressionTree.java | 21 +++++++++++++------ 3 files changed, 22 insertions(+), 15 deletions(-) diff --git a/common.gradle b/common.gradle index 89029a4ae..0dcb336fd 100644 --- a/common.gradle +++ b/common.gradle @@ -6,7 +6,7 @@ apply plugin: 'java' apply plugin: 'maven' String mavenGroupId = 'org.cirdles' -String mavenVersion = '1.7.3' +String mavenVersion = '1.7.4' sourceCompatibility = '1.8' [compileJava, compileTestJava]*.options*.encoding = 'UTF-8' diff --git a/squidCore/src/main/java/org/cirdles/squid/squidReports/squidReportColumns/SquidReportColumn.java b/squidCore/src/main/java/org/cirdles/squid/squidReports/squidReportColumns/SquidReportColumn.java index 84e67c50f..ee62a0aca 100644 --- a/squidCore/src/main/java/org/cirdles/squid/squidReports/squidReportColumns/SquidReportColumn.java +++ b/squidCore/src/main/java/org/cirdles/squid/squidReports/squidReportColumns/SquidReportColumn.java @@ -23,7 +23,6 @@ import org.cirdles.squid.tasks.expressions.expressionTrees.ExpressionTree; import org.cirdles.squid.tasks.expressions.expressionTrees.ExpressionTreeInterface; import org.cirdles.squid.tasks.expressions.isotopes.ShrimpSpeciesNode; -import org.cirdles.squid.tasks.expressions.operations.Divide; import org.cirdles.squid.tasks.expressions.spots.SpotFieldNode; import org.cirdles.squid.tasks.expressions.variables.VariableNodeForSummary; @@ -37,7 +36,6 @@ import static org.cirdles.squid.squidReports.squidReportColumns.SquidReportColumnInterface.formatBigDecimalForPublicationSigDigMode; import static org.cirdles.squid.squidReports.squidReportTables.SquidReportTable.DEFAULT_COUNT_OF_SIGNIFICANT_DIGITS; import static org.cirdles.squid.squidReports.squidReportTables.SquidReportTable.HEADER_ROW_COUNT; -import static org.cirdles.squid.tasks.expressions.builtinExpressions.BuiltInExpressionsDataDictionary.R204PB_206PB; /** * @author James F. Bowring, CIRDLES.org, and Earth-Time.org @@ -121,11 +119,11 @@ public void initReportColumn(TaskInterface task) { expressionNameCustom = "total_" + expressionName + "_cts_/sec"; } - amIsotopicRatio = false; - if (((ExpressionTree) expTree).getLeftET() instanceof ShrimpSpeciesNode) { - // Check for isotopic ratios - amIsotopicRatio = (((ExpressionTree) expTree).getOperation() instanceof Divide); - } + amIsotopicRatio = ((ExpressionTree) expTree).amIsotopicRatio(); +// if (((ExpressionTree) expTree).getLeftET() instanceof ShrimpSpeciesNode) { +// // Check for isotopic ratios +// amIsotopicRatio = (((ExpressionTree) expTree).getOperation() instanceof Divide); +// } // propose column headers by splitting on underscores in name // row 0 is reserved for category displayname @@ -180,7 +178,7 @@ public void initReportColumn(TaskInterface task) { uncertaintyColumn = null; if ((uncertaintyDirective.length() == 0) - && expTree.builtAsValueModel() + && ( expTree.builtAsValueModel() || amIsotopicRatio) // && (!expressionName.toUpperCase().contains("PCT")) // && (!expressionName.toUpperCase().contains("ERR")) // && (!expressionName.toUpperCase().contains("CONCEN")) diff --git a/squidCore/src/main/java/org/cirdles/squid/tasks/expressions/expressionTrees/ExpressionTree.java b/squidCore/src/main/java/org/cirdles/squid/tasks/expressions/expressionTrees/ExpressionTree.java index a43324e32..45d9501bb 100644 --- a/squidCore/src/main/java/org/cirdles/squid/tasks/expressions/expressionTrees/ExpressionTree.java +++ b/squidCore/src/main/java/org/cirdles/squid/tasks/expressions/expressionTrees/ExpressionTree.java @@ -127,7 +127,7 @@ public class ExpressionTree protected String uncertaintyDirective; protected int index; - + protected transient boolean hasNoTargetSpots; public void setHasNoTargetSpots(boolean hasNoTargetSpots) { @@ -137,7 +137,6 @@ public void setHasNoTargetSpots(boolean hasNoTargetSpots) { public boolean doesHaveNoTargetSpots() { return hasNoTargetSpots; } - /** * @@ -468,6 +467,16 @@ public boolean amAnonymous() { return name.compareTo(ANONYMOUS_NAME) == 0; } + public boolean amIsotopicRatio() { + boolean retVal = false; + if (childrenET.size() > 1) { + retVal = (childrenET.get(0) instanceof ShrimpSpeciesNode) + && (childrenET.get(1) instanceof ShrimpSpeciesNode) + && (operation instanceof Divide); + } + return retVal; + } + /** * * @param xstream @@ -572,18 +581,18 @@ public boolean isTypeFunction() { public boolean isTypeFunctionOrOperation() { return (operation instanceof Function) || (operation instanceof Operation); } - + /** * * @return true if this expressionTree is built as a ValueModel */ @Override - public boolean builtAsValueModel(){ + public boolean builtAsValueModel() { boolean retVal = false; - if (isTypeFunction()){ + if (isTypeFunction()) { retVal = operation.getColCount() > 1; } - + return retVal; } From 9e1d01cae0a1c2e402436bec5b6b275d1c0aa94f Mon Sep 17 00:00:00 2001 From: Jim Bowring Date: Fri, 26 Feb 2021 12:45:14 -0500 Subject: [PATCH 4/4] Updated demo project --- .../squid/projects/SQUID3_demo_file.squid | Bin 9899313 -> 9899313 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/squidCore/src/main/resources/org/cirdles/squid/projects/SQUID3_demo_file.squid b/squidCore/src/main/resources/org/cirdles/squid/projects/SQUID3_demo_file.squid index 591a4568c0a73dc19f2bfdcfeab1f4193c02bf5f..3d67243f2d0d64d0adf270f877db49026b7e346e 100644 GIT binary patch delta 473 zcmWN=+cFdY0LS6kTD6h1ELxO}%3?*VN@-UVt3=Mrk{qH!QFL<7kCpSG!;HIbcDgaf zj2XAh^Z;huHM39P%J2gI-^{nQ9yD(0I0jB|5+fm;;xs1C5K0(l3FjOUoX1QgQCNs3 zhFC6OC60I!xX2|Ev2mFslDWcFu91SBRMJStK?c{!B#RqllY^67ZgPv;?)Q^8XzsiK-1YN?}s+iMQQZ$urqgBzZ~|As$*E%wdB z-=;nH{^Y+QpVjVn1iad?;|Me!{W3WHHkVJEv{|2Ni$2#@ZPRw`&==aNUHVdA>1*xQ z9_`gP`d0h2U*G9_9neAjpda;{ZH=Wfvo!13j V)FoZk6bP%D)krm1}TM30UOP&Jjg4 zF~oA7IO0j*0*NG%jENLdNh2LI7r8_Rm&qgx3)$q5%N4GYhn0K^D5QvDu5q0klu(Kd zJ7wIYoC+$bqM90NxkVkfspk%Nxrc)W8o5ss&9u<^$7%E={PHu~_qS`u4uTvzQ5nAv zw~l|>|IhEby8r!kTRcu}^I1IYM?VZ!x5?I_o!X_{`amD*Bkj@0`b3}VGwszreXjjF zpf7Y#hjdt9>MI@5QGKmrI<6Bssc&>jT{^9Abw+1(PT%Q!omcdOE~r~S>L>lIi~2>E WbXiyQtA5i}UDI{_?lajojC&`ajjF!@