From f33c4f367679ccef3997f54067caf07f9cf79afa Mon Sep 17 00:00:00 2001 From: Paul Snow Date: Sun, 14 Sep 2008 17:06:58 -0500 Subject: [PATCH] initial load --- DSLCompiler/.classpath | 11 + DSLCompiler/.project | 17 + DSLCompiler/.settings/org.eclipse.jdt.core.prefs | 5 + .../src/main/java/com/dtrules/compiler/RType.java | 144 + .../java/com/dtrules/compiler/cup/Compiler.java | 265 + .../java/com/dtrules/compiler/cup/TokenFilter.java | 231 + .../dtrules/compiler/decisiontables/Changed.java | 30 + .../compiler/decisiontables/CompileError.java | 54 + .../compiler/decisiontables/DTCompiler.java | 325 + DTParser/.classpath | 7 + DTParser/.project | 17 + DTParser/.settings/org.eclipse.jdt.core.prefs | 5 + DTParser/lib/java-cup-11a.jar | Bin 0 -> 96121 bytes DTParser/parser.bat | 43 + .../com/dtrules/compiler/cup/DTRulesParser.java | 8371 ++++++++++++++++++++ .../java/com/dtrules/compiler/cup/RLocalType.java | 14 + .../java/com/dtrules/compiler/cup/RSymbol.java | 33 + .../src/main/java/com/dtrules/compiler/cup/bnf.txt | 573 ++ .../java/com/dtrules/compiler/cup/copyright.txt | 16 + .../main/java/com/dtrules/compiler/cup/parser.cup | 1158 +++ .../main/java/com/dtrules/compiler/cup/sym.java | 192 + DTRules/.classpath | 6 + DTRules/.project | 13 + DTRules/.settings/org.eclipse.jdt.core.prefs | 5 + DTRules/docs/DTRules.doc | Bin 0 -> 25600 bytes DTRules/docs/OperatorList.doc | Bin 0 -> 59904 bytes DTRules/src/main/java/com/dtrules/App.java | 13 + .../java/com/dtrules/admin/IRulesAdminService.java | 74 + .../java/com/dtrules/admin/RulesAdminService.java | 411 + .../java/com/dtrules/decisiontables/ANode.java | 188 + .../com/dtrules/decisiontables/BalanceTable.java | 123 + .../java/com/dtrules/decisiontables/CNode.java | 139 + .../com/dtrules/decisiontables/CompilerError.java | 115 + .../java/com/dtrules/decisiontables/DTLoader.java | 420 + .../java/com/dtrules/decisiontables/DTNode.java | 75 + .../decisiontables/DecisionTableTypeTest.java | 176 + .../com/dtrules/decisiontables/RDecisionTable.java | 1092 +++ .../src/main/java/com/dtrules/entity/IREntity.java | 158 + .../src/main/java/com/dtrules/entity/REntity.java | 357 + .../main/java/com/dtrules/entity/REntityEntry.java | 195 + .../com/dtrules/infrastructure/RulesException.java | 115 + .../java/com/dtrules/interpreter/ARObject.java | 169 + .../java/com/dtrules/interpreter/IRObject.java | 128 + .../main/java/com/dtrules/interpreter/RArray.java | 271 + .../java/com/dtrules/interpreter/RBoolean.java | 121 + .../main/java/com/dtrules/interpreter/RDouble.java | 127 + .../java/com/dtrules/interpreter/RInteger.java | 121 + .../main/java/com/dtrules/interpreter/RMark.java | 44 + .../main/java/com/dtrules/interpreter/RName.java | 259 + .../main/java/com/dtrules/interpreter/RNull.java | 85 + .../main/java/com/dtrules/interpreter/RString.java | 312 + .../main/java/com/dtrules/interpreter/RTable.java | 237 + .../main/java/com/dtrules/interpreter/RTime.java | 147 + .../java/com/dtrules/interpreter/RXmlValue.java | 154 + .../com/dtrules/interpreter/SimpleTokenizer.java | 136 + .../main/java/com/dtrules/interpreter/Token.java | 99 + .../dtrules/interpreter/operators/RArrayOps.java | 480 ++ .../dtrules/interpreter/operators/RBooleanOps.java | 407 + .../dtrules/interpreter/operators/RControl.java | 432 + .../interpreter/operators/RDateTimeOps.java | 457 ++ .../com/dtrules/interpreter/operators/RMath.java | 301 + .../dtrules/interpreter/operators/RMiscOps.java | 742 ++ .../dtrules/interpreter/operators/ROperator.java | 124 + .../dtrules/interpreter/operators/RTableOps.java | 166 + .../interpreter/operators/RXmlValueOps.java | 81 + .../java/com/dtrules/mapping/AttributeInfo.java | 186 + .../src/main/java/com/dtrules/mapping/DataMap.java | 541 ++ .../java/com/dtrules/mapping/DataObjectMap.java | 161 + .../main/java/com/dtrules/mapping/EntityInfo.java | 57 + .../java/com/dtrules/mapping/LoadDatamapData.java | 229 + .../src/main/java/com/dtrules/mapping/LoadMap.java | 321 + .../main/java/com/dtrules/mapping/LoadMapping.java | 368 + .../main/java/com/dtrules/mapping/LoadXMLData.java | 368 + .../java/com/dtrules/mapping/MapGenerator.java | 217 + .../src/main/java/com/dtrules/mapping/Mapping.java | 287 + .../src/main/java/com/dtrules/mapping/XMLTag.java | 115 + .../src/main/java/com/dtrules/session/DTState.java | 704 ++ .../main/java/com/dtrules/session/EDDLoader.java | 146 + .../java/com/dtrules/session/EntityFactory.java | 322 + .../main/java/com/dtrules/session/ICompiler.java | 90 + .../java/com/dtrules/session/ICompilerError.java | 90 + .../main/java/com/dtrules/session/IRSession.java | 100 + .../main/java/com/dtrules/session/RSession.java | 449 ++ .../src/main/java/com/dtrules/session/RuleSet.java | 387 + .../java/com/dtrules/session/RulesDirectory.java | 242 + .../java/com/dtrules/trace/DecisionTableNode.java | 79 + .../src/main/java/com/dtrules/trace/TraceNode.java | 94 + .../com/dtrules/xmlparser/GenericXMLParser.flex | 311 + .../com/dtrules/xmlparser/GenericXMLParser.java | 874 ++ .../com/dtrules/xmlparser/IGenericXMLParser.java | 98 + .../java/com/dtrules/xmlparser/IXMLPrinter.java | 171 + .../java/com/dtrules/xmlparser/XMLPrinter.java | 535 ++ .../dtrules/xmlparser/compileGenericXMLParser.bat | 6 + .../com/dtrules/admin/RulesAdminServiceTest.java | 55 + .../test/com/dtrules/decisiontables/ANodeTest.java | 67 + .../test/com/dtrules/decisiontables/CNodeTest.java | 78 + .../com/dtrules/decisiontables/DTLoaderTest.java | 211 + .../decisiontables/DecisionTableTypeTest.java | 187 + .../dtrules/decisiontables/RDecisionTableTest.java | 113 + .../test/com/dtrules/entity/REntityEntryTest.java | 62 + .../src/test/com/dtrules/entity/REntityTest.java | 340 + .../interpreter/operators/OperatorTest.java | 139 + DTRules/src/test/com/dtrules/test/AllUnitTest.java | 37 + DTRules/src/test/com/dtrules/test/BaseTest.java | 49 + DTScanner/.classpath | 10 + DTScanner/.project | 16 + DTScanner/.settings/org.eclipse.jdt.core.prefs | 5 + DTScanner/lib/JFlex.jar | Bin 0 -> 169635 bytes .../com/dtrules/compiler/cup/DTRulesscanner.java | 1824 +++++ .../java/com/dtrules/compiler/cup/scanner.flex | 240 + ExcelUtil/.classpath | 13 + ExcelUtil/.project | 18 + ExcelUtil/.settings/org.eclipse.jdt.core.prefs | 5 + ExcelUtil/src/main/java/excel/util/Excel2XML.java | 212 + .../src/main/java/excel/util/ImportRuleSets.java | 608 ++ authors.txt | 2 + 116 files changed, 32625 insertions(+) create mode 100644 DSLCompiler/.classpath create mode 100644 DSLCompiler/.project create mode 100644 DSLCompiler/.settings/org.eclipse.jdt.core.prefs create mode 100644 DSLCompiler/src/main/java/com/dtrules/compiler/RType.java create mode 100644 DSLCompiler/src/main/java/com/dtrules/compiler/cup/Compiler.java create mode 100644 DSLCompiler/src/main/java/com/dtrules/compiler/cup/TokenFilter.java create mode 100644 DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/Changed.java create mode 100644 DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/CompileError.java create mode 100644 DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/DTCompiler.java create mode 100644 DTParser/.classpath create mode 100644 DTParser/.project create mode 100644 DTParser/.settings/org.eclipse.jdt.core.prefs create mode 100644 DTParser/lib/java-cup-11a.jar create mode 100644 DTParser/parser.bat create mode 100644 DTParser/src/main/java/com/dtrules/compiler/cup/DTRulesParser.java create mode 100644 DTParser/src/main/java/com/dtrules/compiler/cup/RLocalType.java create mode 100644 DTParser/src/main/java/com/dtrules/compiler/cup/RSymbol.java create mode 100644 DTParser/src/main/java/com/dtrules/compiler/cup/bnf.txt create mode 100644 DTParser/src/main/java/com/dtrules/compiler/cup/copyright.txt create mode 100644 DTParser/src/main/java/com/dtrules/compiler/cup/parser.cup create mode 100644 DTParser/src/main/java/com/dtrules/compiler/cup/sym.java create mode 100644 DTRules/.classpath create mode 100644 DTRules/.project create mode 100644 DTRules/.settings/org.eclipse.jdt.core.prefs create mode 100644 DTRules/docs/DTRules.doc create mode 100644 DTRules/docs/OperatorList.doc create mode 100644 DTRules/src/main/java/com/dtrules/App.java create mode 100644 DTRules/src/main/java/com/dtrules/admin/IRulesAdminService.java create mode 100644 DTRules/src/main/java/com/dtrules/admin/RulesAdminService.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/ANode.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/BalanceTable.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/CNode.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/CompilerError.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/DTLoader.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/DTNode.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/DecisionTableTypeTest.java create mode 100644 DTRules/src/main/java/com/dtrules/decisiontables/RDecisionTable.java create mode 100644 DTRules/src/main/java/com/dtrules/entity/IREntity.java create mode 100644 DTRules/src/main/java/com/dtrules/entity/REntity.java create mode 100644 DTRules/src/main/java/com/dtrules/entity/REntityEntry.java create mode 100644 DTRules/src/main/java/com/dtrules/infrastructure/RulesException.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/ARObject.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/IRObject.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RArray.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RBoolean.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RDouble.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RInteger.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RMark.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RName.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RNull.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RString.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RTable.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RTime.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/RXmlValue.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/SimpleTokenizer.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/Token.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RArrayOps.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RBooleanOps.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RControl.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RDateTimeOps.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RMath.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RMiscOps.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/ROperator.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RTableOps.java create mode 100644 DTRules/src/main/java/com/dtrules/interpreter/operators/RXmlValueOps.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/AttributeInfo.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/DataMap.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/DataObjectMap.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/EntityInfo.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/LoadDatamapData.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/LoadMap.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/LoadMapping.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/LoadXMLData.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/MapGenerator.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/Mapping.java create mode 100644 DTRules/src/main/java/com/dtrules/mapping/XMLTag.java create mode 100644 DTRules/src/main/java/com/dtrules/session/DTState.java create mode 100644 DTRules/src/main/java/com/dtrules/session/EDDLoader.java create mode 100644 DTRules/src/main/java/com/dtrules/session/EntityFactory.java create mode 100644 DTRules/src/main/java/com/dtrules/session/ICompiler.java create mode 100644 DTRules/src/main/java/com/dtrules/session/ICompilerError.java create mode 100644 DTRules/src/main/java/com/dtrules/session/IRSession.java create mode 100644 DTRules/src/main/java/com/dtrules/session/RSession.java create mode 100644 DTRules/src/main/java/com/dtrules/session/RuleSet.java create mode 100644 DTRules/src/main/java/com/dtrules/session/RulesDirectory.java create mode 100644 DTRules/src/main/java/com/dtrules/trace/DecisionTableNode.java create mode 100644 DTRules/src/main/java/com/dtrules/trace/TraceNode.java create mode 100644 DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.flex create mode 100644 DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.java create mode 100644 DTRules/src/main/java/com/dtrules/xmlparser/IGenericXMLParser.java create mode 100644 DTRules/src/main/java/com/dtrules/xmlparser/IXMLPrinter.java create mode 100644 DTRules/src/main/java/com/dtrules/xmlparser/XMLPrinter.java create mode 100644 DTRules/src/main/java/com/dtrules/xmlparser/compileGenericXMLParser.bat create mode 100644 DTRules/src/test/com/dtrules/admin/RulesAdminServiceTest.java create mode 100644 DTRules/src/test/com/dtrules/decisiontables/ANodeTest.java create mode 100644 DTRules/src/test/com/dtrules/decisiontables/CNodeTest.java create mode 100644 DTRules/src/test/com/dtrules/decisiontables/DTLoaderTest.java create mode 100644 DTRules/src/test/com/dtrules/decisiontables/DecisionTableTypeTest.java create mode 100644 DTRules/src/test/com/dtrules/decisiontables/RDecisionTableTest.java create mode 100644 DTRules/src/test/com/dtrules/entity/REntityEntryTest.java create mode 100644 DTRules/src/test/com/dtrules/entity/REntityTest.java create mode 100644 DTRules/src/test/com/dtrules/interpreter/operators/OperatorTest.java create mode 100644 DTRules/src/test/com/dtrules/test/AllUnitTest.java create mode 100644 DTRules/src/test/com/dtrules/test/BaseTest.java create mode 100644 DTScanner/.classpath create mode 100644 DTScanner/.project create mode 100644 DTScanner/.settings/org.eclipse.jdt.core.prefs create mode 100644 DTScanner/lib/JFlex.jar create mode 100644 DTScanner/src/main/java/com/dtrules/compiler/cup/DTRulesscanner.java create mode 100644 DTScanner/src/main/java/com/dtrules/compiler/cup/scanner.flex create mode 100644 ExcelUtil/.classpath create mode 100644 ExcelUtil/.project create mode 100644 ExcelUtil/.settings/org.eclipse.jdt.core.prefs create mode 100644 ExcelUtil/src/main/java/excel/util/Excel2XML.java create mode 100644 ExcelUtil/src/main/java/excel/util/ImportRuleSets.java create mode 100644 authors.txt diff --git a/DSLCompiler/.classpath b/DSLCompiler/.classpath new file mode 100644 index 0000000..66fa0e8 --- /dev/null +++ b/DSLCompiler/.classpath @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/DSLCompiler/.project b/DSLCompiler/.project new file mode 100644 index 0000000..4bcdf05 --- /dev/null +++ b/DSLCompiler/.project @@ -0,0 +1,17 @@ + + DSLCompiler + SDC Parent POM + + DTParser + DTRules + DTScanner + + + + org.eclipse.jdt.core.javabuilder + + + + org.eclipse.jdt.core.javanature + + \ No newline at end of file diff --git a/DSLCompiler/.settings/org.eclipse.jdt.core.prefs b/DSLCompiler/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..6481952 --- /dev/null +++ b/DSLCompiler/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Thu May 15 12:54:27 CDT 2008 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 diff --git a/DSLCompiler/src/main/java/com/dtrules/compiler/RType.java b/DSLCompiler/src/main/java/com/dtrules/compiler/RType.java new file mode 100644 index 0000000..54674cd --- /dev/null +++ b/DSLCompiler/src/main/java/com/dtrules/compiler/RType.java @@ -0,0 +1,144 @@ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.compiler; + +import java.util.ArrayList; + +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.interpreter.RName; +import com.dtrules.session.RSession; + +public class RType { + RName name; + int type; + ArrayList entities = new ArrayList(); + ArrayList refs = new ArrayList(); + + public RName getRName(){return name;} + public int getType() {return type;} + public ArrayList getEntities(){return entities;} + + public static final String REF = "ref"; + public static final String NOT_REF = "not ref"; + public static final String POSSIBLE_REF = "possible ref"; + + public String toString() { + try{ + String s = name + +"\n type: "+RSession.typeInt2Str(type) + +"\n Entities: "; + for(int i=0;i getUnReferenced(){ + + ArrayList unreferenced = new ArrayList(); + + //Ignore the mapping "key" attribute. + if(name.equals(IREntity.mappingKey))return unreferenced; + + for(int i=0; i< refs.size(); i++){ + if(refs.get(i).equals(NOT_REF)){ + RName entityName = entities.get(i).getName(); + // Ignore self references. + if(!entityName.equals(name)){ + unreferenced.add(entityName.stringValue()+"."+name.stringValue()); + } + } + } + return unreferenced; + } + + /** + * Possible Referenced attributes + * @return + */ + public ArrayList getPossibleReferenced(){ + ArrayList attribs = new ArrayList(); + +// Ignore the mapping "key" attribute. + if(name.equals(IREntity.mappingKey))return attribs; + + for(int i=0; i< refs.size(); i++){ + if(refs.get(i).equals(POSSIBLE_REF)){ + RName entityName = entities.get(i).getName(); + // Ignore self references. + if(!entityName.equals(name)){ + attribs.add(entityName.stringValue()+"."+name.stringValue()); + } + } + } + return attribs; + } + + + public RType(RName _name,int _type, REntity _entity){ + name = _name; + type = _type; + addEntityAttribute(_entity); + } +} diff --git a/DSLCompiler/src/main/java/com/dtrules/compiler/cup/Compiler.java b/DSLCompiler/src/main/java/com/dtrules/compiler/cup/Compiler.java new file mode 100644 index 0000000..85083aa --- /dev/null +++ b/DSLCompiler/src/main/java/com/dtrules/compiler/cup/Compiler.java @@ -0,0 +1,265 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.compiler.cup; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Set; + +import javax.swing.JComboBox.KeySelectionManager; + +import java_cup.runtime.Scanner; +import java_cup.runtime.lr_parser; + +import com.dtrules.compiler.RType; +import com.dtrules.decisiontables.RDecisionTable; +import com.dtrules.entity.REntity; +import com.dtrules.entity.REntityEntry; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.session.EntityFactory; +import com.dtrules.session.ICompiler; +import com.dtrules.session.IRSession; +import com.dtrules.session.RSession; + +public class Compiler implements ICompiler { + + private HashMap types = null; + private final EntityFactory ef; + private final IRSession session; + private RDecisionTable currentTable; + private int localcnt = 0; // Count of local variables + HashMap localtypes = new HashMap(); + + public void setTableName(String tablename) { + try{ + currentTable = ef.getDecisionTable(RName.getRName(tablename)); + }catch (RulesException e) { + /** Just ignore this if the name isn't found **/ + } + } + + + /** + * Add a identifier and type to the types HashMap. + * @param entity + * @param name + * @param itype + * @throws Exception + */ + private void addType( REntity entity, RName name, int itype) throws Exception { + RType type = (RType) types.get(name); + if(type==null){ + type = new RType(name,itype,entity); + types.put(name,type); + }else{ + if(type.getType()!=itype){ + String entitylist = entity.getName().stringValue(); + for(int i=0; i(); + Iterator entities = ef.getEntityRNameIterator(); + while(entities.hasNext()){ + RName name = (RName) entities.next(); + REntity entity = ef.findRefEntity(name); + Iterator attribs = entity.getAttributeIterator(); + addType(entity,entity.getName(),IRObject.iEntity); + while(attribs.hasNext()){ + RName attribname = (RName) attribs.next(); + REntityEntry entry = entity.getEntry(attribname); + addType(entity,attribname,entry.type); + } + } + + Iterator tables = ef.getDecisionTableRNameIterator(); + while(tables.hasNext()){ + RName tablename = (RName) tables.next(); + RType type = new RType(tablename,IRObject.iDecisiontable,(REntity) ef.getDecisiontables()); + if(types.containsKey(tablename)){ + System.out.println("Multiple Decision Tables found with the name '"+types.get(tablename)+"'"); + } + types.put(tablename, type); + } + + return types; + } + + /** + * Prints all the types known to the compiler + */ + public void printTypes(PrintStream out) throws RulesException { + Object typenames[] = (Object []) types.keySet().toArray(); + for(int i=0;i0){ + Object hold = typenames[j]; + typenames[j]=typenames[j+1]; + typenames[j+1]=hold; + } + } + } + for(int i=0;i types.get(two).getType()){ + Object hold = typenames[j]; + typenames[j]=typenames[j+1]; + typenames[j+1]=hold; + } + } + } + for(int i=0;i getParsedTokens(){ + return tfilter.getParsedTokens(); + } + + public void newDecisionTable () { + localcnt = 0; + localtypes.clear(); + } + + /** + * The actual routine to compile either an action or condition. The code + * is all the same, only a flag is needed to decide to compile an action vs + * condition. + * @param action Flag + * @param s String to compile + * @return Postfix + * @throws Exception Throws an Exception on any error. + */ + private String compile (boolean action, String s)throws Exception { + + + InputStream stream = new ByteArrayInputStream(s.getBytes()); + DataInputStream input = new DataInputStream(stream); + DTRulesscanner lexer = new DTRulesscanner (input); + tfilter = new TokenFilter(session, lexer,types, localtypes); + DTRulesParser parser = new DTRulesParser(tfilter); + Object result = null; + + parser.localCnt = localcnt; + try { + result = parser.parse().value; + }catch(Exception e){ + throw new Exception( "Error found at Line:Char ="+lexer.linenumber()+":"+lexer.charnumber()+" "+ + e.toString()); + } + localcnt = parser.localCnt; + localtypes.putAll(parser.localtypes); + return result.toString(); + } + + /* (non-Javadoc) + * @see com.dtrules.compiler.ICompiler#getLastPreFixExp() + */ + public String getLastPreFixExp(){ + return ""; + } + + /** + * Build a compiler instance. This compiler compiles either a condition or + * an action. Use the compiler access methods to compile each. + * + * @param entityfactory Needed to generate the symbol table used by the compiler. + * @throws Exception Throws an exception of a compiler error is encountered. + */ + public Compiler(IRSession session) throws Exception { + this.session = session; + ef = session.getEntityFactory(); + getTypes(ef); + } + + + /* (non-Javadoc) + * @see com.dtrules.compiler.ICompiler#compileContext(java.lang.String) + */ + public String compileContext(String context) throws Exception { + return compile(true,"context "+context); + } + + /* (non-Javadoc) + * @see com.dtrules.compiler.ICompiler#compileAction(java.lang.String) + */ + public String compileAction(String action) throws Exception { + return compile(true,"action "+action); + } + /* (non-Javadoc) + * @see com.dtrules.compiler.ICompiler#compileCondition(java.lang.String) + */ + public String compileCondition(String condition) throws Exception { + return compile(false,"condition "+ condition); + } + /* (non-Javadoc) + * @see com.dtrules.compiler.ICompiler#getTypes() + */ + public HashMap getTypes() { + return types; + } + /** + * Return the list of Possibly (but we can't tell for sure) referenced attributes + * so far by this compiler. + */ + public ArrayList getPossibleReferenced() { + ArrayList v = new ArrayList(); + for(RType type :types.values()){ + v.addAll(type.getPossibleReferenced()); + } + return v; + } + /** + * Return the list of UnReferenced attributes so far by this compiler + */ + public ArrayList getUnReferenced() { + ArrayList v = new ArrayList(); + for(RType type :types.values()){ + v.addAll(type.getUnReferenced()); + } + return v; + } +} diff --git a/DSLCompiler/src/main/java/com/dtrules/compiler/cup/TokenFilter.java b/DSLCompiler/src/main/java/com/dtrules/compiler/cup/TokenFilter.java new file mode 100644 index 0000000..d6aff64 --- /dev/null +++ b/DSLCompiler/src/main/java/com/dtrules/compiler/cup/TokenFilter.java @@ -0,0 +1,231 @@ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.compiler.cup; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; + +import com.dtrules.compiler.RType; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.session.IRSession; + +import java_cup.runtime.*; + +public class TokenFilter implements Scanner{ + + Scanner scanner; + HashMap types; + IRSession session; + + boolean EOF = false; + RSymbol lastToken = null; + RSymbol unget = null; + ArrayList tokens = new ArrayList(); + HashMap localtypes = null; + + public ArrayList getParsedTokens(){ + return tokens; + } + + TokenFilter(IRSession session, Scanner scanner, HashMap types, HashMap localtypes){ + this.types = types; + this.scanner = scanner; + this.session = session; + this.localtypes = localtypes; + } + /** + * Look up an Identifier in the symbol table and return its type. + * @param ident + * @return + */ + int identType(String ident,String entity){ + + RType type = (RType) types.get(RName.getRName(ident,true)); + boolean defined = true; + if(entity != null && entity.length()!=0 && type!=null){ + defined = false; + for(REntity rEntity : type.getEntities()){ + if(entity.equalsIgnoreCase(rEntity.getName().stringValue())){ + defined = true; + break; + } + } + } + if(type==null || defined==false){ + RName rname = RName.getRName( + (entity==null||entity.length()==0?"":entity+".")+ident); + try { + IRObject o = session.getState().find(rname); + if(o==null)return -1; + return o.type(); + } catch (RulesException e) { + return -1; + } + } + + type.addRef(entity); + + return type.getType(); + + } + /** + * Looks at the sym.class with reflection and looks up the type + * associated with the given code. + * + * @param type integer code associated with a symbol. + */ + private String type2str(int type){ + try{ + Class tokentypes = sym.class; + Field[] types = tokentypes.getDeclaredFields(); + for(int i=0;i=0){ + entity=ident.substring(0,ident.indexOf('.')); + ident =ident.substring(ident.indexOf('.')+1); + } + int theType = identType(ident,entity); + + if(theType!= IRObject.iEntity && theType != -1 ){ + throw new RuntimeException("Invalid Possessive. "+ident+" is not an Entity"); + } + if(theType == -1){ + if(localtypes.containsKey(ident.toLowerCase())){ + RLocalType t = localtypes.get(ident.toLowerCase()); + theType = t.type; + next.local = true; + next.value = t.index +" local@"; + }else{ + throw new RuntimeException("Undefined attribute '"+next.value+"'"); + } + }else{ + next.value = (entity.length()>0?entity+".":"")+ident; + } + unget = new RSymbol(false, new Symbol(sym.COMMA)); // Inject a comma after every possessive + unget.value = ","; + + } + + if(next.sym==sym.IDENT){ + String entity = ""; + String ident = next.value.toString(); + if(ident.indexOf('.')>=0){ + entity=ident.substring(0,ident.indexOf('.')); + ident =ident.substring(ident.indexOf('.')+1); + } + int theType = identType(ident,entity); + + if(theType == -1 ){ + if(localtypes.containsKey(next.value.toString().toLowerCase())){ + RLocalType t = localtypes.get(next.value.toString().toLowerCase()); + theType = t.type; + next = new RSymbol(true, next); + next.value = t.index +" local@"; + ((RSymbol)next).leftvalue = t.index +" local!"; + } + } + + switch(theType){ + case IRObject.iEntity : next.sym=(sym.RENTITY); break; + case IRObject.iName : next.sym=(sym.RNAME); break; + case IRObject.iInteger : next.sym=(sym.RLONG); break; + case IRObject.iDouble : next.sym=(sym.RDOUBLE); break; + case IRObject.iString : next.sym=(sym.RSTRING); break; + case IRObject.iBoolean : next.sym=(sym.RBOOLEAN); break; + case IRObject.iDecisiontable : next.sym=(sym.RDECISIONTABLE); break; + case IRObject.iArray : next.sym=(sym.RARRAY); break; + case IRObject.iTime : next.sym=(sym.RDATE); break; + case IRObject.iTable : next.sym=(sym.RTABLE); break; + case IRObject.iOperator : next.sym=(sym.ROPERATOR); break; + case IRObject.iXmlValue : next.sym=(sym.RXMLVALUE); break; + case -1 : next.sym=(sym.UNDEFINED); break; + default: + System.out.println("Unhandled Type"); + tokens.add(next.sym+" "+type2str(next.sym)+" "+next.value.toString()); + throw new RuntimeException("Unhandled Type: "+next.value); + } + } + + tokens.add(next.sym+" "+type2str(next.sym)+" "+next.value.toString()); + lastToken = next; + return next; + + } + +} diff --git a/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/Changed.java b/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/Changed.java new file mode 100644 index 0000000..72c9d55 --- /dev/null +++ b/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/Changed.java @@ -0,0 +1,30 @@ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.compiler.decisiontables; + +public class Changed { + public String tablename; + public String source; + public String newPostfix; + public String oldPostfix; + + Changed(String dtname, String src,String newPS, String oldPS){ + tablename = dtname; + source = src; + newPostfix = newPS; + oldPostfix = oldPS; + } +} diff --git a/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/CompileError.java b/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/CompileError.java new file mode 100644 index 0000000..5cd634f --- /dev/null +++ b/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/CompileError.java @@ -0,0 +1,54 @@ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.compiler.decisiontables; + +import java.util.ArrayList; + +/** + * A simple class, really just a structure, for collecting + * information about reported errors as we compile a set of + * decision tables. + * + * @author Paul Snow + * + */ +public class CompileError { + + public String tablename; // Name of the decision table with the error + public String filename; // Name of a Excel file if that was the source + public String source; // The text we were trying to compile + public String message; // Error message generated + public int lineNumber; // Line number in the XML file + public String info; // Any other information we might have. + public ArrayList tokens; // List of parsed Tokens + /** + * Store all the info when we create an instance of a CompileError + * @param dtname String decision table name + * @param src String the code being compiled + * @param msg String the error message generated + * @param line int the line in the XML where the error was detected. + * @param info String any other information we might have. + */ + CompileError(String dtname, String filename,String src, String msg, int line, String info, ArrayList _tokens){ + tablename = dtname==null?"":dtname; + this.filename = filename; + source = src==null?"":src; + message = msg==null?"":msg; + lineNumber = line; + this.info = info==null?"":info; + tokens = _tokens; + } +} diff --git a/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/DTCompiler.java b/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/DTCompiler.java new file mode 100644 index 0000000..6e68950 --- /dev/null +++ b/DSLCompiler/src/main/java/com/dtrules/compiler/decisiontables/DTCompiler.java @@ -0,0 +1,325 @@ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.compiler.decisiontables; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import sun.misc.Sort; + +import com.dtrules.compiler.cup.Compiler; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.RName; +import com.dtrules.session.ICompiler; +import com.dtrules.session.RSession; +import com.dtrules.session.RuleSet; +import com.dtrules.session.RulesDirectory; +import com.dtrules.xmlparser.GenericXMLParser; +import com.dtrules.xmlparser.IGenericXMLParser; + +public class DTCompiler implements IGenericXMLParser{ + + private ArrayList errors = new ArrayList(); + private ArrayList changes = new ArrayList(); + + Compiler compiler = null; + int conditionsCompiled = 0; + int actionsCompiled = 0; + int contextsCompiled = 0; + int initialActionsCompiled = 0; + String message = null; + + boolean newstatement = true; //Set to true at start of condition or action + + String tablename; //Keep the Decision Table name too. + String filename; //Filename (if source was Excel) + String source; //Keep the source after we parse it. + String oldpostfix ="None in XML"; //Keep the old postfix after we parse it. + //(I set the oldpostfix to an impossible value to + // pick up cases were we have no description to compile) + String newpostfix; //Keep the new postfix after we generate it. + + PrintStream out; + // Indicates that the "printer" is on a newline or not + boolean newline = true; + + public ArrayList getErrors() { return errors; } + public ArrayList getChanges() { return changes; } + + void printStartTag(String tag, HashMap attribs){ + if(!newline)out.println(); + out.print("<"); out.print(tag); + if(attribs!=null){ + Object [] keys = attribs.keySet().toArray(); + for(int i=0;i"); + newline = false; + } + + void printEndTag(String tag, String body){ + if(body!=null) out.print(GenericXMLParser.encode(body)); + out.print(""); + } + + public void beginTag(String[] tagstk, int tagstkptr, String tag, HashMap attribs) throws IOException, Exception { + if(!tag.equals("condition_postfix") && + !tag.equals("action_postfix")){ + printStartTag(tag, attribs); + } + } + + public void logError(String decisionTableName, String filename,String source, String message, int line, String info){ + errors.add(new CompileError(decisionTableName,filename,source,message,line,info,new ArrayList())); + } + /** + * Used to compile a Context, Initial_Action, Condition, or Action + * @param prefix + * @param body + */ + private void compileone(String prefix, String body){ + source = GenericXMLParser.unencode(body).trim(); + try{ + if(prefix.equals("action")){ + newpostfix = compiler.compileAction(source); + }else if(prefix.equals("condition")){ + newpostfix = compiler.compileCondition(source); + }else if(prefix.equals("context")){ + newpostfix = compiler.compileContext(source); + }else if(prefix.equals("initial_action")){ + newpostfix = compiler.compileAction(source); + } + }catch(Exception e){ + message = e.toString(); + if(message==null)message = "unknown"; + newpostfix = ""; + } + printStartTag(prefix+"_postfix", null); + out.print(GenericXMLParser.encode(newpostfix)); + printEndTag(prefix+"_postfix",null); + } + + /** + * Log the result of the compile, after comparing if the new result + * matches the old result. Note, we can't do this until we reach + * the end of the description. + * @param prefix + */ + private void logResult(String prefix){ + if (message!=null){ + String info=""; + if(oldpostfix!=null)info="Old Postfix: "+oldpostfix; + errors.add(new CompileError(tablename,filename,source,message,-1,info,compiler.getParsedTokens())); + printStartTag("compile_error",null); + printEndTag("compile_error",message); + message = null; + oldpostfix = null; + }else if (!oldpostfix.equals(newpostfix)){ + if(prefix.equals("action")){ + actionsCompiled++; + }else if(prefix.equals("condition")){ + conditionsCompiled++; + }else if(prefix.equals("context")){ + contextsCompiled++; + }else if(prefix.equals("initial_action")){ + initialActionsCompiled++; + } + conditionsCompiled++; + changes.add(new Changed(tablename,source,GenericXMLParser.unencode(newpostfix),oldpostfix)); + } + oldpostfix="None in XML"; + } + public void endTag(String[] tagstk, int tagstkptr, String tag, String body, HashMap attribs) throws Exception, IOException { + if(!tag.equals("condition_postfix") && + !tag.equals("action_postfix")){ + printEndTag(tag, body); + }else{ + oldpostfix = GenericXMLParser.unencode(body); + } + if(tag.equals("action_description")){ + compileone("action",body); + }else if(tag.equals("condition_description")){ + compileone("condition",body); + }else if(tag.equals("context_description")){ + compileone("context",body); + }else if(tag.equals("initial_action_description")){ + compileone("initial_action",body); + }else if(tag.equals("condition_details" )){ + logResult("condition"); + }else if (tag.equals("action_details")){ + logResult("action"); + }else if (tag.equals("initial_action_details")){ + logResult("initial_action"); + }else if (tag.equals("context_details")){ + logResult("context"); + } else if(tag.equals("table_name")){ + tablename = body; + } else if(tag.equals("xls_file")){ + filename = body; + } else if(tag.equals("decision_table")){ + tablename = ""; + filename = ""; + compiler.newDecisionTable(); + } + + } + + public boolean error(String v) throws Exception { + return true; + } + + InputStream dtinput; + OutputStream dtoutput; + + /** + * Compiles the XML stream, writing the "compiled" XML to result. + * Note that it is the caller's responsiblity to ask the compiler + * for a list of errors and to report these errors.... + * + * @param source InputStream + * @param result OutputStream + * + */ + public DTCompiler(Compiler compiler){ + this.compiler = compiler; + } + + + + public void compile( String decisionTable,String resultDecisionTable){ + try { + + InputStream in = new FileInputStream(decisionTable); + FileOutputStream out = new FileOutputStream(resultDecisionTable); + + compile(in,out); + }catch(Exception e){ + System.out.println("Error openning files: \n"+e); + } + } + + public void compile(InputStream in, OutputStream out) { + this.out = new PrintStream(out); + try { + GenericXMLParser.load(in, this); + } catch (Exception e) { + errors.add(new CompileError( + tablename,filename,"Error occurred in the XML parsing", e.toString(), -1,null + ,compiler.getParsedTokens()) + ); + } + } + + public void printErrors(PrintStream eOut){ + printErrors(eOut,0x7fffffff); + } + + public void printTypes(PrintStream eOut){ + try { + compiler.printTypes(eOut); + } catch (Exception e) { + eOut.println(e); + } + } + + public void printErrors(PrintStream eOut, int count){ + Iterator err = errors.iterator(); + while (err.hasNext()&&count>0) { + count--; + CompileError error = err.next(); + eOut.println("\nError:"); + eOut.println("Decision Table: " + error.tablename); + eOut.println("Filename: " + error.filename); + eOut.println(); + eOut.println("Source: " + error.source); + eOut.println("Error: " + error.message); + eOut.println("Info: " + error.info); + Iterator tokens = error.tokens.iterator(); + while(tokens.hasNext())eOut.println(tokens.next()); + if(error.lineNumber>=0){ + eOut.println("Line: " + error.lineNumber); + } + eOut.println(); + } + } + + public void printUnreferenced(PrintStream eOut){ + ArrayList unreferenced = compiler.getUnReferenced(); + for(int i=0;i0){ + String t = unreferenced.get(j); + unreferenced.set(j, unreferenced.get(j+1)); + unreferenced.set(j+1, t); + } + } + } + + eOut.println("Found "+ unreferenced.size()+" Unreferenced attributes: "); + for (String unref : unreferenced){ + eOut.println(" "+unref); + } + ArrayList attriblist = compiler.getPossibleReferenced(); + for(int i=0;i0){ + String t = attriblist.get(j); + attriblist.set(j, attriblist.get(j+1)); + attriblist.set(j+1, t); + } + } + } + + eOut.println("Found "+ attriblist.size()+" Ambiguous attributes: "); + for (String attrib : attriblist){ + eOut.println(" "+attrib); + } + + } + + public void printChanges(PrintStream eOut){ + Iterator chg = changes.iterator(); + while (chg.hasNext()) { + Changed change = chg.next(); + eOut.println("Change:"); + eOut.println("Decision Table: " + change.tablename); + eOut.println("Source: " + change.source); + eOut.println("Old: " + change.oldPostfix); + eOut.println("New: " + change.newPostfix); + + } + + eOut.println("Conditions compiled: " + conditionsCompiled); + eOut.println("Actions compiled: " + actionsCompiled); + eOut.println("Changes: " + changes.size()); + eOut.println("Errors: " + errors.size()); + eOut.println(); + } +} diff --git a/DTParser/.classpath b/DTParser/.classpath new file mode 100644 index 0000000..e46fa5a --- /dev/null +++ b/DTParser/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/DTParser/.project b/DTParser/.project new file mode 100644 index 0000000..30bbbba --- /dev/null +++ b/DTParser/.project @@ -0,0 +1,17 @@ + + + DTParser + SDC Parent POM + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/DTParser/.settings/org.eclipse.jdt.core.prefs b/DTParser/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..b08576a --- /dev/null +++ b/DTParser/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Thu May 15 12:54:26 CDT 2008 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 diff --git a/DTParser/lib/java-cup-11a.jar b/DTParser/lib/java-cup-11a.jar new file mode 100644 index 0000000000000000000000000000000000000000..73ffa0b336a562c41321d51063b4b1dc7e6fde1e GIT binary patch literal 96121 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 DrQc(I literal 0 HcwPel00001 diff --git a/DTParser/parser.bat b/DTParser/parser.bat new file mode 100644 index 0000000..814bb34 --- /dev/null +++ b/DTParser/parser.bat @@ -0,0 +1,43 @@ +@echo off +rem * Copyright 2004-2008 MTBJ, Inc. +rem * +rem * Licensed under the Apache License, Version 2.0 (the "License"); +rem * you may not use this file except in compliance with the License. +rem * You may obtain a copy of the License at +rem * +rem * http://www.apache.org/licenses/LICENSE-2.0 +rem * +rem * Unless required by applicable law or agreed to in writing, software +rem * distributed under the License is distributed on an "AS IS" BASIS, +rem * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +rem * See the License for the specific language governing permissions and +rem * limitations under the License. +rem * +set projectDirectory=%cd% +set cupDir=%projectDirectory%\src\main\java\com\dtrules\compiler\cup +set libDir=%projectDirectory%\lib + +rem dir %projectDirectory% +rem dir %libDir% + +cd %cupDir% +rem echo create BNF + +java -cp %libDir%\java-cup-11a.jar java_cup.Main -parser nul: -symbols nul: -dump_grammar < parser.cup 2> bnf.txt +rem echo create Java file +java -cp %libDir%\java-cup-11a.jar java_cup.Main -compact_red -nopositions -parser DTRulesParser < parser.cup + + +copy /y copyright.txt+DTRulesParser.java xxx.tmp > nul +copy /y xxx.tmp DTRulesParser.java > nul + +copy /y copyright.txt+sym.java xxx.tmp > nul +copy /y xxx.tmp sym.java > nul + +copy /y copyright.txt+bnf.txt xxx.tmp > nul +copy /y xxx.tmp bnf.txt > nul + +del xxx.tmp > nul + + +cd %projectDirectory% \ No newline at end of file diff --git a/DTParser/src/main/java/com/dtrules/compiler/cup/DTRulesParser.java b/DTParser/src/main/java/com/dtrules/compiler/cup/DTRulesParser.java new file mode 100644 index 0000000..dfe307a --- /dev/null +++ b/DTParser/src/main/java/com/dtrules/compiler/cup/DTRulesParser.java @@ -0,0 +1,8371 @@ +/** + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//---------------------------------------------------- +// The following code was generated by CUP v0.11a beta 20060608 +// Mon Sep 08 16:23:44 CDT 2008 +//---------------------------------------------------- + +package com.dtrules.compiler.cup; + +import java.util.*; +import java.io.*; +import java_cup.runtime.*; + +/** CUP v0.11a beta 20060608 generated parser. + * @version Mon Sep 08 16:23:44 CDT 2008 + */ +public class DTRulesParser extends java_cup.runtime.lr_parser { + + /** Default constructor. */ + public DTRulesParser() {super();} + + /** Constructor which sets the default scanner. */ + public DTRulesParser(java_cup.runtime.Scanner s) {super(s);} + + /** Constructor which sets the default scanner. */ + public DTRulesParser(java_cup.runtime.Scanner s, java_cup.runtime.SymbolFactory sf) {super(s,sf);} + + /** Production table. */ + protected static final short _production_table[][] = + unpackFromStrings(new String[] { + "\000\u01ec\000\002\010\004\000\002\002\004\000\002\010" + + "\005\000\002\010\007\000\002\010\007\000\002\010\005" + + "\000\002\011\004\000\002\011\003\000\002\066\003\000" + + "\002\066\003\000\002\012\004\000\002\012\004\000\002" + + "\012\004\000\002\012\004\000\002\012\004\000\002\012" + + "\004\000\002\012\004\000\002\012\004\000\002\012\004" + + "\000\002\012\004\000\002\012\004\000\002\012\004\000" + + "\002\012\004\000\002\012\004\000\002\012\003\000\002" + + "\107\004\000\002\107\005\000\002\107\005\000\002\107" + + "\005\000\002\107\005\000\002\107\003\000\002\107\003" + + "\000\002\107\003\000\002\107\003\000\002\106\004\000" + + "\002\106\005\000\002\106\007\000\002\106\007\000\002" + + "\037\004\000\002\037\005\000\002\037\003\000\002\103" + + "\005\000\002\103\004\000\002\103\005\000\002\103\004" + + "\000\002\103\006\000\002\103\005\000\002\102\003\000" + + "\002\033\004\000\002\063\003\000\002\063\003\000\002" + + "\063\003\000\002\063\003\000\002\062\005\000\002\062" + + "\007\000\002\062\005\000\002\062\005\000\002\062\007" + + "\000\002\062\005\000\002\062\005\000\002\062\007\000" + + "\002\062\005\000\002\062\005\000\002\062\007\000\002" + + "\062\005\000\002\062\005\000\002\062\007\000\002\062" + + "\005\000\002\062\005\000\002\062\007\000\002\062\005" + + "\000\002\062\005\000\002\062\007\000\002\062\005\000" + + "\002\047\007\000\002\047\011\000\002\034\011\000\002" + + "\034\014\000\002\034\013\000\002\034\016\000\002\034" + + "\004\000\002\034\007\000\002\034\006\000\002\034\011" + + "\000\002\034\010\000\002\034\006\000\002\034\011\000" + + "\002\032\004\000\002\032\006\000\002\032\010\000\002" + + "\032\006\000\002\032\011\000\002\032\013\000\002\035" + + "\010\000\002\035\013\000\002\035\010\000\002\040\014" + + "\000\002\040\017\000\002\040\005\000\002\041\005\000" + + "\002\041\004\000\002\041\003\000\002\041\004\000\002" + + "\041\003\000\002\041\004\000\002\041\004\000\002\041" + + "\003\000\002\044\005\000\002\071\003\000\002\071\004" + + "\000\002\072\003\000\002\072\004\000\002\073\003\000" + + "\002\073\004\000\002\074\003\000\002\074\004\000\002" + + "\075\003\000\002\075\004\000\002\076\003\000\002\076" + + "\004\000\002\100\003\000\002\100\004\000\002\077\003" + + "\000\002\077\004\000\002\043\006\000\002\043\006\000" + + "\002\043\006\000\002\043\006\000\002\043\006\000\002" + + "\043\006\000\002\043\006\000\002\043\006\000\002\043" + + "\006\000\002\043\006\000\002\043\006\000\002\043\006" + + "\000\002\043\006\000\002\043\006\000\002\043\004\000" + + "\002\043\004\000\002\043\004\000\002\043\004\000\002" + + "\045\003\000\002\045\004\000\002\045\004\000\002\046" + + "\004\000\002\046\004\000\002\046\004\000\002\046\004" + + "\000\002\046\004\000\002\046\004\000\002\046\004\000" + + "\002\036\006\000\002\070\003\000\002\070\005\000\002" + + "\070\004\000\002\013\003\000\002\013\003\000\002\051" + + "\003\000\002\051\003\000\002\051\003\000\002\052\003" + + "\000\002\052\003\000\002\050\006\000\002\050\006\000" + + "\002\050\011\000\002\050\006\000\002\050\011\000\002" + + "\050\006\000\002\050\011\000\002\050\006\000\002\050" + + "\011\000\002\050\006\000\002\050\011\000\002\050\014" + + "\000\002\050\011\000\002\050\014\000\002\061\011\000" + + "\002\061\011\000\002\054\010\000\002\054\011\000\002" + + "\054\007\000\002\054\007\000\002\054\004\000\002\054" + + "\004\000\002\054\006\000\002\054\010\000\002\054\010" + + "\000\002\057\005\000\002\057\005\000\002\057\005\000" + + "\002\057\005\000\002\057\003\000\002\057\003\000\002" + + "\057\003\000\002\057\003\000\002\060\006\000\002\065" + + "\011\000\002\026\006\000\002\026\005\000\002\026\003" + + "\000\002\026\006\000\002\026\004\000\002\026\006\000" + + "\002\026\005\000\002\026\005\000\002\026\005\000\002" + + "\026\003\000\002\026\006\000\002\026\006\000\002\104" + + "\005\000\002\105\005\000\002\105\005\000\002\105\005" + + "\000\002\105\005\000\002\105\005\000\002\105\003\000" + + "\002\105\003\000\002\105\003\000\002\105\003\000\002" + + "\105\003\000\002\024\006\000\002\020\003\000\002\020" + + "\005\000\002\020\003\000\002\020\005\000\002\020\005" + + "\000\002\020\005\000\002\020\004\000\002\020\011\000" + + "\002\020\010\000\002\020\006\000\002\020\005\000\002" + + "\064\007\000\002\064\007\000\002\064\007\000\002\064" + + "\007\000\002\064\007\000\002\064\007\000\002\025\005" + + "\000\002\025\003\000\002\025\006\000\002\025\006\000" + + "\002\025\006\000\002\025\011\000\002\025\007\000\002" + + "\025\004\000\002\025\006\000\002\025\005\000\002\025" + + "\005\000\002\025\011\000\002\025\007\000\002\025\007" + + "\000\002\025\007\000\002\025\007\000\002\025\007\000" + + "\002\025\007\000\002\025\007\000\002\025\007\000\002" + + "\025\007\000\002\025\007\000\002\021\003\000\002\021" + + "\004\000\002\021\004\000\002\021\007\000\002\021\003" + + "\000\002\021\007\000\002\021\004\000\002\021\006\000" + + "\002\056\005\000\002\056\003\000\002\022\003\000\002" + + "\022\007\000\002\023\003\000\002\023\007\000\002\023" + + "\011\000\002\023\003\000\002\023\006\000\002\023\011" + + "\000\002\023\003\000\002\023\004\000\002\023\003\000" + + "\002\023\005\000\002\023\006\000\002\023\006\000\002" + + "\023\006\000\002\023\005\000\002\023\005\000\002\023" + + "\005\000\002\023\005\000\002\023\005\000\002\023\005" + + "\000\002\023\005\000\002\023\005\000\002\023\005\000" + + "\002\023\005\000\002\023\006\000\002\023\006\000\002" + + "\023\006\000\002\110\002\000\002\023\011\000\002\023" + + "\004\000\002\023\007\000\002\023\006\000\002\016\003" + + "\000\002\016\004\000\002\016\003\000\002\016\006\000" + + "\002\016\011\000\002\016\005\000\002\016\005\000\002" + + "\016\005\000\002\016\005\000\002\016\005\000\002\016" + + "\005\000\002\016\005\000\002\016\005\000\002\016\005" + + "\000\002\016\005\000\002\016\005\000\002\016\005\000" + + "\002\016\004\000\002\016\005\000\002\016\006\000\002" + + "\016\006\000\002\016\006\000\002\016\006\000\002\016" + + "\006\000\002\016\005\000\002\016\007\000\002\016\006" + + "\000\002\016\004\000\002\016\007\000\002\016\011\000" + + "\002\016\006\000\002\015\005\000\002\015\005\000\002" + + "\015\005\000\002\015\005\000\002\015\003\000\002\015" + + "\004\000\002\015\005\000\002\015\003\000\002\015\007" + + "\000\002\015\010\000\002\015\010\000\002\015\004\000" + + "\002\015\006\000\002\015\006\000\002\015\006\000\002" + + "\015\011\000\002\015\004\000\002\015\006\000\002\015" + + "\005\000\002\015\005\000\002\015\005\000\002\015\006" + + "\000\002\015\006\000\002\015\006\000\002\015\006\000" + + "\002\015\005\000\002\015\007\000\002\015\007\000\002" + + "\015\007\000\002\015\007\000\002\015\005\000\002\015" + + "\006\000\002\015\006\000\002\031\004\000\002\031\004" + + "\000\002\031\003\000\002\031\004\000\002\014\003\000" + + "\002\014\003\000\002\014\003\000\002\042\004\000\002" + + "\042\004\000\002\067\005\000\002\067\004\000\002\017" + + "\007\000\002\017\006\000\002\017\005\000\002\017\012" + + "\000\002\017\006\000\002\017\010\000\002\017\010\000" + + "\002\017\006\000\002\017\010\000\002\017\012\000\002" + + "\017\012\000\002\017\006\000\002\017\007\000\002\017" + + "\007\000\002\017\005\000\002\017\007\000\002\017\007" + + "\000\002\017\005\000\002\017\005\000\002\017\005\000" + + "\002\017\005\000\002\017\005\000\002\017\005\000\002" + + "\017\005\000\002\017\005\000\002\017\005\000\002\017" + + "\005\000\002\017\005\000\002\017\005\000\002\017\005" + + "\000\002\017\005\000\002\017\005\000\002\017\005\000" + + "\002\017\005\000\002\017\005\000\002\017\005\000\002" + + "\017\005\000\002\017\005\000\002\017\005\000\002\017" + + "\005\000\002\017\005\000\002\017\003\000\002\017\004" + + "\000\002\017\005\000\002\017\005\000\002\017\005\000" + + "\002\017\005\000\002\017\005\000\002\017\005\000\002" + + "\017\005\000\002\017\007\000\002\017\005\000\002\017" + + "\007\000\002\017\010\000\002\017\005\000\002\017\005" + + "\000\002\017\005\000\002\017\005\000\002\017\005\000" + + "\002\017\005\000\002\017\005\000\002\017\005\000\002" + + "\017\005\000\002\017\005\000\002\017\005\000\002\017" + + "\005\000\002\017\004\000\002\017\004\000\002\017\004" + + "\000\002\017\004\000\002\017\004\000\002\017\004\000" + + "\002\017\004\000\002\017\004\000\002\017\004\000\002" + + "\017\007\000\002\017\005\000\002\017\006\000\002\017" + + "\007\000\002\017\005\000\002\017\005\000\002\017\006" + + "\000\002\017\005\000\002\017\006\000\002\017\005\000" + + "\002\017\005\000\002\017\010\000\002\017\005\000\002" + + "\017\005\000\002\017\006\000\002\017\003\000\002\002" + + "\003\000\002\002\005\000\002\002\004\000\002\003\003" + + "\000\002\003\006\000\002\003\005\000\002\004\003\000" + + "\002\004\005\000\002\004\004\000\002\005\003\000\002" + + "\005\010\000\002\005\007\000\002\006\003\000\002\006" + + "\005\000\002\006\004\000\002\007\003\000\002\007\010" + + "\000\002\007\007\000\002\027\003\000\002\027\004\000" + + "\002\030\003\000\002\030\005" }); + + /** Access to production table. */ + public short[][] production_table() {return _production_table;} + + /** Parse-action table. */ + protected static final short[][] _action_table = + unpackFromStrings(new String[] { + "\000\u04de\000\010\005\005\034\007\036\006\001\002\000" + + "\004\002\u04e0\001\002\000\056\006\u03ae\031\u03b4\035\u03a4" + + "\044\u0388\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397\115" + + "\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201\u039a" + + "\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af\001" + + "\002\000\174\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\044\u0388\050\106\051\346\052\115\054\157\061\175" + + "\067\332\070\140\074\123\100\324\107\116\110\350\114" + + "\032\116\144\121\142\123\334\126\021\132\121\133\107" + + "\134\126\135\133\136\132\140\046\142\336\144\122\147" + + "\342\153\034\156\050\157\353\162\174\164\124\165\045" + + "\167\027\171\125\172\120\177\025\201\051\207\041\210" + + "\043\211\163\212\134\214\024\217\111\220\330\226\044" + + "\227\023\233\352\235\335\241\141\001\002\000\012\006" + + "\016\071\011\072\014\120\015\001\002\000\002\001\uffcf" + + "\000\004\067\u0378\001\002\000\002\001\uffce\000\004\202" + + "\u0377\001\002\000\060\014\054\030\042\032\036\033\035" + + "\037\022\067\053\074\055\114\032\123\033\126\021\140" + + "\046\153\034\156\050\165\045\167\027\177\025\201\051" + + "\207\041\210\043\214\024\226\044\227\023\233\026\001" + + "\002\000\020\013\u033b\025\u033a\042\u0339\052\u0336\063\u033c" + + "\121\u0338\207\u0337\001\002\000\060\014\054\030\042\032" + + "\036\033\035\037\022\067\053\074\055\114\032\123\033" + + "\126\021\140\046\153\034\156\050\165\045\167\027\177" + + "\025\201\051\207\041\210\043\214\024\226\044\227\023" + + "\233\026\001\002\000\002\001\uffd0\000\002\001\uffcd\000" + + "\032\014\054\033\035\037\022\074\066\114\032\123\067" + + "\126\021\140\063\153\034\156\050\167\065\226\044\001" + + "\002\000\004\145\u0330\001\002\000\004\123\u032d\001\002" + + "\000\002\001\ufeed\000\002\001\ufeea\000\060\014\054\030" + + "\042\032\036\033\035\037\022\067\053\074\055\114\032" + + "\123\033\126\021\140\046\153\034\156\050\165\045\167" + + "\027\177\025\201\051\207\041\210\043\214\024\226\044" + + "\227\023\233\026\001\002\000\004\015\075\001\uff23\000" + + "\006\145\322\152\321\001\002\000\002\001\uff32\000\134" + + "\004\130\006\131\014\054\030\042\032\036\033\035\037" + + "\022\043\127\050\106\052\115\067\053\070\140\074\123" + + "\107\116\114\032\116\144\121\142\123\117\126\021\132" + + "\121\133\107\134\126\135\133\136\132\140\046\144\122" + + "\153\034\156\050\164\124\165\045\167\027\171\125\172" + + "\120\177\025\201\051\207\041\210\043\211\113\212\134" + + "\214\024\217\111\226\044\227\023\233\112\241\141\001" + + "\002\000\066\013\071\014\054\030\042\032\036\033\035" + + "\037\022\063\u0240\067\053\074\055\114\032\123\033\126" + + "\021\140\046\153\034\156\050\165\045\167\027\177\025" + + "\201\051\206\154\207\041\210\043\214\024\226\044\227" + + "\023\233\026\001\002\000\004\035\u0327\001\002\000\004" + + "\167\u0324\001\002\000\004\145\u0322\001\002\000\004\224" + + "\u031a\001\002\000\010\156\077\167\u01fd\177\152\001\002" + + "\000\004\234\u016d\001\ufee8\000\036\030\042\033\035\074" + + "\u0171\123\u016f\153\034\165\045\167\065\177\025\201\051" + + "\207\041\210\043\214\024\227\023\233\026\001\002\000" + + "\004\145\u030d\001\002\000\036\030\042\033\035\074\u0171" + + "\123\u016f\153\034\165\045\167\065\177\025\201\051\207" + + "\041\210\043\214\024\227\023\233\026\001\002\000\060" + + "\014\054\030\042\032\036\033\035\037\022\067\053\074" + + "\055\114\032\123\033\126\021\140\046\153\034\156\050" + + "\165\045\167\027\177\025\201\051\207\041\210\043\214" + + "\024\226\044\227\023\233\026\001\002\000\030\033\035" + + "\063\101\123\u021b\135\133\136\132\153\034\167\u0304\172" + + "\120\206\100\217\111\233\u021a\001\002\000\004\114\u0128" + + "\001\002\000\002\001\uff39\000\004\033\u02ff\001\ufef0\000" + + "\002\001\uffd2\000\060\014\054\030\042\032\036\033\035" + + "\037\022\067\053\074\055\114\032\123\033\126\021\140" + + "\046\153\034\156\050\165\045\167\027\177\025\201\051" + + "\207\041\210\043\214\024\226\044\227\023\233\026\001" + + "\002\000\004\114\104\001\002\000\006\037\057\041\060" + + "\001\002\000\002\001\uff21\000\004\145\061\001\002\000" + + "\002\001\ufed4\000\032\014\054\033\035\037\022\074\066" + + "\114\032\123\067\126\021\140\063\153\034\156\050\167" + + "\065\226\044\001\002\000\002\001\uff36\000\006\063\101" + + "\206\100\001\002\000\004\156\077\001\002\000\004\015" + + "\075\001\002\000\004\037\057\001\002\000\034\013\071" + + "\014\054\033\035\037\022\074\066\114\032\123\067\126" + + "\021\140\063\153\034\156\050\167\065\226\044\001\002" + + "\000\004\176\074\001\002\000\004\176\072\001\002\000" + + "\004\135\073\001\002\000\002\001\uff38\000\002\001\uff3a" + + "\000\002\001\uffd5\000\002\001\uffd6\000\002\001\uff37\000" + + "\004\013\103\001\002\000\004\013\102\001\002\000\002" + + "\001\uff34\000\002\001\uff33\000\134\004\130\006\131\014" + + "\054\030\042\032\036\033\035\037\022\043\127\050\106" + + "\052\115\067\053\070\140\074\123\107\116\114\032\116" + + "\144\121\142\123\117\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\144\122\153\034\156\050\164" + + "\124\165\045\167\027\171\125\172\120\177\025\201\051" + + "\207\041\210\043\211\113\212\134\214\024\217\111\226" + + "\044\227\023\233\112\241\141\001\002\000\016\156\077" + + "\164\271\167\u01fd\171\273\172\u018f\177\152\001\002\000" + + "\006\164\u02fc\171\u0144\001\002\000\004\073\u02f8\001\002" + + "\000\012\050\234\132\233\152\232\222\235\001\uff26\000" + + "\036\030\042\033\035\074\u0171\123\u016f\153\034\165\045" + + "\167\065\177\025\201\051\207\041\210\043\214\024\227" + + "\023\233\026\001\002\000\060\014\054\030\042\032\036" + + "\033\035\037\022\067\053\074\055\114\032\123\033\126" + + "\021\140\046\153\034\156\050\165\045\167\027\177\025" + + "\201\051\207\041\210\043\214\024\226\044\227\023\233" + + "\026\001\002\000\004\073\u02c8\001\002\000\002\001\uff27" + + "\000\004\234\301\001\002\000\002\001\ufeae\000\134\004" + + "\130\006\131\013\071\014\054\030\042\032\036\033\035" + + "\037\022\043\127\050\106\052\277\063\u0240\067\053\070" + + "\140\074\123\107\116\114\032\116\144\121\275\123\312" + + "\126\021\132\121\133\107\134\126\135\u0190\140\046\144" + + "\122\153\034\156\050\164\124\165\045\167\027\171\125" + + "\177\025\201\051\206\154\207\041\210\043\211\113\212" + + "\134\214\024\226\044\227\023\233\310\241\141\001\002" + + "\000\002\001\ufefc\000\062\004\130\006\131\033\035\043" + + "\127\050\106\052\115\070\140\074\212\107\116\116\144" + + "\121\142\123\207\132\121\133\107\134\126\144\122\153" + + "\034\164\124\167\065\171\125\211\113\212\134\233\206" + + "\241\141\001\002\000\032\014\054\033\035\037\022\074" + + "\066\114\032\123\067\126\021\140\063\153\034\156\050" + + "\167\065\226\044\001\002\000\012\037\057\041\060\043" + + "\214\242\213\001\002\000\002\001\ufecf\000\002\001\ufeab" + + "\000\006\164\u02eb\171\u0152\001\002\000\004\073\u02e7\001" + + "\002\000\004\145\u02e4\001\002\000\004\224\u02c1\001\002" + + "\000\060\014\054\030\042\032\036\033\035\037\022\067" + + "\053\074\055\114\032\123\033\126\021\140\046\153\034" + + "\156\050\165\045\167\027\177\025\201\051\207\041\210" + + "\043\214\024\226\044\227\023\233\026\001\002\000\004" + + "\156\u024d\001\ufef8\000\062\004\130\006\131\033\035\043" + + "\127\050\106\052\115\070\140\074\212\107\116\116\144" + + "\121\142\123\207\132\121\133\107\134\126\144\122\153" + + "\034\164\124\167\065\171\125\211\113\212\134\233\206" + + "\241\141\001\002\000\002\001\uff29\000\006\035\u02d8\160" + + "\u02d9\001\002\000\006\145\322\152\321\001\uff25\000\002" + + "\001\ufed1\000\004\073\u02d4\001\002\000\004\234\u0280\001" + + "\002\000\014\050\203\132\201\152\200\175\202\222\204" + + "\001\uff28\000\004\145\145\001\002\000\054\014\054\030" + + "\042\033\035\037\022\074\055\114\032\123\147\126\021" + + "\140\063\153\034\156\050\165\045\167\065\177\025\201" + + "\051\207\041\210\043\214\024\226\044\227\023\233\026" + + "\001\002\000\004\152\321\001\ufe9f\000\060\013\071\014" + + "\054\030\042\033\035\037\022\074\055\114\032\123\147" + + "\126\021\140\063\153\034\156\050\165\045\167\065\177" + + "\025\201\051\206\154\207\041\210\043\214\024\226\044" + + "\227\023\233\026\001\002\000\006\156\077\177\152\001" + + "\002\000\002\001\ufea0\000\002\001\ufee9\000\006\152\321" + + "\176\u0251\001\002\000\004\176\155\001\002\000\114\004" + + "\130\006\173\014\054\033\035\037\022\042\165\043\127" + + "\050\106\052\115\054\157\061\175\067\167\070\140\074" + + "\170\107\116\114\032\116\144\121\142\123\164\126\021" + + "\132\121\133\107\134\126\140\172\144\122\153\034\156" + + "\050\162\174\164\124\167\065\171\125\200\176\211\163" + + "\212\134\226\044\233\162\241\141\001\002\000\012\156" + + "\077\162\272\164\271\171\273\001\002\000\004\145\u02d0" + + "\001\002\000\004\123\u02cd\001\002\000\002\001\ufee5\000" + + "\060\014\054\030\042\032\036\033\035\037\022\067\053" + + "\074\055\114\032\123\033\126\021\140\046\153\034\156" + + "\050\165\045\167\027\177\025\201\051\207\041\210\043" + + "\214\024\226\044\227\023\233\026\001\002\000\064\004" + + "\130\006\131\033\035\043\127\050\106\052\115\070\140" + + "\073\u02c8\074\212\107\116\116\144\121\142\123\207\132" + + "\121\133\107\134\126\144\122\153\034\164\124\167\065" + + "\171\125\211\113\212\134\233\206\241\141\001\002\000" + + "\114\004\130\006\173\013\071\014\054\033\035\037\022" + + "\042\264\043\127\050\106\052\277\054\157\061\175\067" + + "\167\070\140\074\170\107\116\114\032\116\144\121\275" + + "\123\164\126\021\132\121\133\107\134\126\140\063\144" + + "\122\153\034\156\050\162\174\164\124\167\065\171\125" + + "\211\163\212\134\226\044\233\162\241\141\001\002\000" + + "\004\123\u028d\001\002\000\002\001\ufed8\000\004\145\u0253" + + "\001\002\000\010\037\057\043\214\242\213\001\002\000" + + "\002\001\ufee4\000\042\030\042\033\035\063\101\074\u0171" + + "\123\u016f\153\034\165\045\167\065\177\025\201\051\206" + + "\100\207\041\210\043\214\024\227\023\233\026\001\002" + + "\000\064\004\130\006\131\033\035\043\127\050\106\052" + + "\115\070\140\074\212\107\116\116\144\121\142\123\207" + + "\132\121\133\107\134\126\144\122\153\034\164\124\167" + + "\065\171\125\211\113\212\134\224\u02c1\233\206\241\141" + + "\001\002\000\002\001\uff11\000\004\145\u02bd\001\002\000" + + "\002\001\ufef2\000\002\001\ufee6\000\062\004\130\006\131" + + "\033\035\043\127\050\106\052\115\070\140\074\212\107" + + "\116\116\144\121\142\123\207\132\121\133\107\134\126" + + "\144\122\153\034\164\124\167\065\171\125\211\113\212" + + "\134\233\206\241\141\001\002\000\062\004\130\006\131" + + "\033\035\043\127\050\106\052\115\070\140\074\212\107" + + "\116\116\144\121\142\123\207\132\121\133\107\134\126" + + "\144\122\153\034\164\124\167\065\171\125\211\113\212" + + "\134\233\206\241\141\001\002\000\004\224\u02b3\001\ufeb6" + + "\000\062\004\130\006\131\033\035\043\127\050\106\052" + + "\115\070\140\074\212\107\116\116\144\121\142\123\207" + + "\132\121\133\107\134\126\144\122\153\034\164\124\167" + + "\065\171\125\211\113\212\134\233\206\241\141\001\002" + + "\000\062\004\130\006\131\033\035\043\127\050\106\052" + + "\115\070\140\074\212\107\116\116\144\121\142\123\207" + + "\132\121\133\107\134\126\144\122\153\034\164\124\167" + + "\065\171\125\211\113\212\134\233\206\241\141\001\002" + + "\000\002\001\ufec4\000\060\014\054\030\042\032\036\033" + + "\035\037\022\067\053\074\055\114\032\123\033\126\021" + + "\140\046\153\034\156\050\165\045\167\027\177\025\201" + + "\051\207\041\210\043\214\024\226\044\227\023\233\026" + + "\001\002\000\062\004\130\006\131\033\035\043\127\050" + + "\106\052\277\070\140\074\212\107\116\116\144\121\275" + + "\123\207\132\121\133\107\134\126\144\122\153\034\164" + + "\124\167\065\171\125\211\113\212\134\233\206\241\141" + + "\001\002\000\006\164\271\171\273\001\002\000\002\001" + + "\ufec6\000\006\043\214\242\213\001\002\000\032\006\223" + + "\033\035\042\165\054\157\061\175\067\167\123\225\153" + + "\034\162\174\167\065\211\226\233\224\001\002\000\006" + + "\103\215\145\216\001\002\000\006\133\u02aa\242\u02a9\001" + + "\002\000\004\133\217\001\002\000\004\071\220\001\002" + + "\000\032\006\223\033\035\042\165\054\157\061\175\067" + + "\167\123\225\153\034\162\174\167\065\211\226\233\224" + + "\001\002\000\006\132\256\152\255\001\ufea8\000\004\162" + + "\272\001\002\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\060\014\054\030\042\032\036\033\035" + + "\037\022\067\053\074\055\114\032\123\033\126\021\140" + + "\046\153\034\156\050\165\045\167\027\177\025\201\051" + + "\207\041\210\043\214\024\226\044\227\023\233\026\001" + + "\002\000\074\004\130\006\173\033\035\042\264\043\127" + + "\050\106\052\115\054\157\061\175\067\167\070\140\074" + + "\212\107\116\116\144\121\142\123\265\132\121\133\107" + + "\134\126\144\122\153\034\162\174\164\124\167\065\171" + + "\125\211\163\212\134\233\162\241\141\001\002\000\062" + + "\004\130\006\131\033\035\043\127\050\106\052\115\070" + + "\140\074\212\107\116\116\144\121\142\123\207\132\121" + + "\133\107\134\126\144\122\153\034\164\124\167\065\171" + + "\125\211\113\212\134\233\206\241\141\001\002\000\014" + + "\050\203\132\201\152\200\175\202\222\204\001\uff64\000" + + "\010\043\246\133\250\241\247\001\002\000\012\050\234" + + "\132\233\152\232\222\235\001\uff65\000\062\004\130\006" + + "\131\033\035\043\127\050\106\052\115\070\140\074\212" + + "\107\116\116\144\121\142\123\207\132\121\133\107\134" + + "\126\144\122\153\034\164\124\167\065\171\125\211\113" + + "\212\134\233\206\241\141\001\002\000\062\004\130\006" + + "\131\033\035\043\127\050\106\052\115\070\140\074\212" + + "\107\116\116\144\121\142\123\207\132\121\133\107\134" + + "\126\144\122\153\034\164\124\167\065\171\125\211\113" + + "\212\134\233\206\241\141\001\002\000\062\004\130\006" + + "\131\033\035\043\127\050\106\052\115\070\140\074\212" + + "\107\116\116\144\121\142\123\207\132\121\133\107\134" + + "\126\144\122\153\034\164\124\167\065\171\125\211\113" + + "\212\134\233\206\241\141\001\002\000\062\004\130\006" + + "\131\033\035\043\127\050\106\052\115\070\140\074\212" + + "\107\116\116\144\121\142\123\207\132\121\133\107\134" + + "\126\144\122\153\034\164\124\167\065\171\125\211\113" + + "\212\134\233\206\241\141\001\002\000\002\001\ufec5\000" + + "\002\001\ufeb0\000\002\001\ufec2\000\002\001\ufeaf\000\006" + + "\050\203\222\204\001\ufec8\000\006\050\234\222\235\001" + + "\ufeb1\000\006\050\203\222\204\001\ufeca\000\006\050\234" + + "\222\235\001\ufeb2\000\004\073\261\001\002\000\004\073" + + "\253\001\002\000\004\073\251\001\002\000\004\162\252" + + "\001\002\000\002\001\uff05\000\032\006\223\033\035\042" + + "\165\054\157\061\175\067\167\123\225\153\034\162\174" + + "\167\065\211\226\233\224\001\002\000\006\132\256\152" + + "\255\001\uff06\000\032\006\223\033\035\042\165\054\157" + + "\061\175\067\167\123\225\153\034\162\174\167\065\211" + + "\226\233\224\001\002\000\032\006\223\033\035\042\165" + + "\054\157\061\175\067\167\123\225\153\034\162\174\167" + + "\065\211\226\233\224\001\002\000\002\001\uff08\000\002" + + "\001\uff09\000\004\162\262\001\002\000\002\001\uff04\000" + + "\004\043\u029a\001\002\000\006\123\u028d\176\u028c\001\002" + + "\000\074\004\130\006\173\033\035\042\264\043\127\050" + + "\106\052\277\054\157\061\175\067\167\070\140\074\212" + + "\107\116\116\144\121\275\123\265\132\121\133\107\134" + + "\126\144\122\153\034\162\174\164\124\167\065\171\125" + + "\211\163\212\134\233\162\241\141\001\002\000\010\162" + + "\272\164\271\171\273\001\002\000\010\132\256\152\255" + + "\176\270\001\002\000\002\001\uff12\000\002\001\ufed0\000" + + "\002\001\uff0b\000\002\001\ufea7\000\016\050\203\132\201" + + "\152\200\175\202\176\u0249\222\204\001\uff64\000\006\176" + + "\u027f\234\u0280\001\002\000\014\050\234\132\233\152\232" + + "\176\u0148\222\235\001\uff65\000\006\176\300\234\301\001" + + "\002\000\056\014\054\030\042\033\035\037\022\074\055" + + "\114\032\123\147\126\021\140\063\153\034\156\050\165" + + "\045\167\065\177\025\200\u027a\201\051\207\041\210\043" + + "\214\024\226\044\227\023\233\026\001\002\000\004\145" + + "\302\001\002\000\004\174\304\001\002\000\002\001\ufeb7" + + "\000\004\123\305\001\002\000\124\004\130\006\131\014" + + "\054\030\042\032\036\033\035\037\022\043\127\050\106" + + "\052\115\067\053\070\140\074\123\107\116\114\032\116" + + "\144\121\142\123\312\126\021\132\121\133\107\134\126" + + "\140\046\144\122\153\034\156\050\164\124\165\045\167" + + "\027\171\125\177\025\201\051\207\041\210\043\211\113" + + "\212\134\214\024\226\044\227\023\233\310\241\141\001" + + "\002\000\014\156\077\164\271\167\u01fd\171\273\177\152" + + "\001\002\000\014\035\u0277\050\234\132\233\152\232\222" + + "\235\001\uff40\000\060\014\054\030\042\032\036\033\035" + + "\037\022\067\053\074\055\114\032\123\033\126\021\140" + + "\046\153\034\156\050\165\045\167\027\177\025\201\051" + + "\207\041\210\043\214\024\226\044\227\023\233\026\001" + + "\002\000\004\035\u026e\001\uff3e\000\132\004\130\006\131" + + "\013\071\014\054\030\042\032\036\033\035\037\022\043" + + "\127\050\106\052\277\063\u0240\067\053\070\140\074\123" + + "\107\116\114\032\116\144\121\275\123\312\126\021\132" + + "\121\133\107\134\126\140\046\144\122\153\034\156\050" + + "\164\124\165\045\167\027\171\125\177\025\201\051\206" + + "\154\207\041\210\043\211\113\212\134\214\024\226\044" + + "\227\023\233\310\241\141\001\002\000\004\176\u0268\001" + + "\002\000\010\035\320\145\322\152\321\001\uff41\000\016" + + "\035\316\050\203\132\201\152\200\175\202\222\204\001" + + "\uff3f\000\124\004\130\006\131\014\054\030\042\032\036" + + "\033\035\037\022\043\127\050\106\052\115\067\053\070" + + "\140\074\123\107\116\114\032\116\144\121\142\123\312" + + "\126\021\132\121\133\107\134\126\140\046\144\122\153" + + "\034\156\050\164\124\165\045\167\027\171\125\177\025" + + "\201\051\207\041\210\043\211\113\212\134\214\024\226" + + "\044\227\023\233\310\241\141\001\002\000\002\001\uff43" + + "\000\124\004\130\006\131\014\054\030\042\032\036\033" + + "\035\037\022\043\127\050\106\052\115\067\053\070\140" + + "\074\123\107\116\114\032\116\144\121\142\123\312\126" + + "\021\132\121\133\107\134\126\140\046\144\122\153\034" + + "\156\050\164\124\165\045\167\027\171\125\177\025\201" + + "\051\207\041\210\043\211\113\212\134\214\024\226\044" + + "\227\023\233\310\241\141\001\002\000\176\004\130\006" + + "\173\010\331\014\054\024\354\025\343\030\042\032\036" + + "\033\035\037\022\042\165\043\127\050\106\051\346\052" + + "\115\054\157\061\175\067\332\070\140\074\123\100\324" + + "\107\116\110\350\114\032\116\144\121\142\123\334\126" + + "\021\132\121\133\107\134\126\135\133\136\132\140\046" + + "\142\336\144\122\147\342\153\034\156\050\157\353\162" + + "\174\164\124\165\045\167\027\170\340\171\125\172\120" + + "\173\327\177\025\201\051\207\041\210\043\211\163\212" + + "\134\214\024\217\111\220\330\226\044\227\023\233\352" + + "\235\335\241\141\001\002\000\060\014\054\030\042\032" + + "\036\033\035\037\022\067\053\074\055\114\032\123\033" + + "\126\021\140\046\153\034\156\050\165\045\167\027\177" + + "\025\201\051\207\041\210\043\214\024\226\044\227\023" + + "\233\026\001\002\000\002\001\uff19\000\060\014\054\030" + + "\042\032\036\033\035\037\022\067\053\074\055\114\032" + + "\123\033\126\021\140\046\153\034\156\050\165\045\167" + + "\027\177\025\201\051\207\041\210\043\214\024\226\044" + + "\227\023\233\026\001\002\000\010\065\361\110\u01f0\142" + + "\363\001\ufede\000\010\065\361\110\u01c2\142\363\001\ufee7" + + "\000\002\001\ufedb\000\004\110\u0202\001\002\000\032\014" + + "\054\033\035\037\022\074\066\114\032\123\067\126\021" + + "\140\063\153\034\156\050\167\065\226\044\001\002\000" + + "\062\014\054\030\042\032\036\033\035\037\022\067\053" + + "\074\055\114\032\123\033\126\021\140\046\145\u0253\153" + + "\034\156\050\165\045\167\027\177\025\201\051\207\041" + + "\210\043\214\024\226\044\227\023\233\026\001\002\000" + + "\006\065\361\110\u01ad\001\ufedd\000\200\004\130\006\173" + + "\010\331\013\071\014\054\024\354\025\u023c\030\042\032" + + "\036\033\035\037\022\042\264\043\127\050\106\051\346" + + "\052\277\054\157\061\175\063\u0240\067\332\070\140\074" + + "\123\100\324\107\116\110\350\114\032\116\144\121\275" + + "\123\334\126\021\132\121\133\107\134\126\135\u0239\136" + + "\132\140\046\142\336\144\122\147\342\153\034\156\050" + + "\157\353\162\174\164\124\165\045\167\027\171\125\172" + + "\120\177\025\201\051\206\154\207\041\210\043\211\163" + + "\212\134\214\024\217\111\220\330\226\044\227\023\233" + + "\352\235\335\241\141\001\002\000\172\004\130\006\173" + + "\010\331\014\054\024\354\025\343\030\042\032\036\033" + + "\035\037\022\042\165\043\127\050\106\051\346\052\115" + + "\054\157\061\175\067\332\070\140\074\123\100\324\107" + + "\116\110\350\114\032\116\144\121\142\123\334\126\021" + + "\132\121\133\107\134\126\135\133\136\132\140\046\142" + + "\336\144\122\147\342\153\034\156\050\157\353\162\174" + + "\164\124\165\045\167\027\171\125\172\120\177\025\201" + + "\051\207\041\210\043\211\163\212\134\214\024\217\111" + + "\220\330\226\044\227\023\233\352\235\335\241\141\001" + + "\002\000\172\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\051\346\052\115\054\157\061\175\067\332" + + "\070\140\074\123\100\324\107\116\110\350\114\032\116" + + "\144\121\142\123\334\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\142\336\144\122\147\342\153" + + "\034\156\050\157\353\162\174\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\217\111\220\330\226\044\227\023" + + "\233\352\235\335\241\141\001\002\000\014\050\234\065" + + "\361\110\356\142\363\222\235\001\ufee2\000\002\001\ufeda" + + "\000\010\065\361\110\u0181\142\363\001\ufedf\000\004\145" + + "\u0230\001\002\000\006\156\u0229\234\u022a\001\002\000\010" + + "\065\361\110\u0181\142\363\001\ufee0\000\062\014\054\030" + + "\042\032\036\033\035\037\022\067\053\074\055\114\032" + + "\123\033\126\021\127\u0214\140\046\153\034\156\050\165" + + "\045\167\027\177\025\201\051\207\041\210\043\214\024" + + "\226\044\227\023\233\026\001\002\000\172\004\130\006" + + "\173\010\331\014\054\024\354\025\343\030\042\032\036" + + "\033\035\037\022\042\165\043\127\050\106\051\346\052" + + "\115\054\157\061\175\067\332\070\140\074\123\100\324" + + "\107\116\110\350\114\032\116\144\121\142\123\334\126" + + "\021\132\121\133\107\134\126\135\133\136\132\140\046" + + "\142\336\144\122\147\342\153\034\156\050\157\353\162" + + "\174\164\124\165\045\167\027\171\125\172\120\177\025" + + "\201\051\207\041\210\043\211\163\212\134\214\024\217" + + "\111\220\330\226\044\227\023\233\352\235\335\241\141" + + "\001\002\000\004\110\u0164\001\ufedc\000\172\004\130\006" + + "\173\010\331\014\054\024\354\025\343\030\042\032\036" + + "\033\035\037\022\042\165\043\127\050\106\051\346\052" + + "\115\054\157\061\175\067\332\070\140\074\123\100\324" + + "\107\116\110\350\114\032\116\144\121\142\123\334\126" + + "\021\132\121\133\107\134\126\135\133\136\132\140\046" + + "\142\336\144\122\147\342\153\034\156\050\157\353\162" + + "\174\164\124\165\045\167\027\171\125\172\120\177\025" + + "\201\051\207\041\210\043\211\163\212\134\214\024\217" + + "\111\220\u01ff\226\044\227\023\233\352\235\335\241\141" + + "\001\002\000\022\156\077\157\u01fe\162\272\164\271\167" + + "\u01fd\171\273\172\u018f\177\152\001\002\000\060\014\054" + + "\030\042\032\036\033\035\037\022\067\053\074\055\114" + + "\032\123\033\126\021\140\046\153\034\156\050\165\045" + + "\167\027\177\025\201\051\207\041\210\043\214\024\226" + + "\044\227\023\233\026\001\002\000\002\001\ufe5d\000\002" + + "\001\ufe2c\000\014\050\203\065\361\110\356\142\363\222" + + "\204\001\ufee1\000\012\065\u0118\075\u0117\117\u0119\142\u0116" + + "\001\002\000\002\001\ufe1f\000\062\004\130\006\131\033" + + "\035\043\127\050\106\052\115\070\140\074\212\107\116" + + "\116\144\121\142\123\207\132\121\133\107\134\126\144" + + "\122\153\034\164\124\167\065\171\125\211\113\212\134" + + "\233\206\241\141\001\002\000\004\224\u0113\001\002\000" + + "\002\001\ufe1c\000\004\065\u0111\001\002\000\062\004\130" + + "\006\131\033\035\043\127\050\106\052\115\070\140\074" + + "\212\107\116\116\144\121\142\123\207\132\121\133\107" + + "\134\126\144\122\153\034\164\124\167\065\171\125\211" + + "\113\212\134\233\206\241\141\001\002\000\062\004\130" + + "\006\131\033\035\043\127\050\106\052\115\070\140\074" + + "\212\107\116\116\144\121\142\123\207\132\121\133\107" + + "\134\126\144\122\153\034\164\124\167\065\171\125\211" + + "\113\212\134\233\206\241\141\001\002\000\004\215\u0109" + + "\001\002\000\002\001\ufe25\000\002\001\ufe22\000\062\004" + + "\130\006\131\033\035\043\127\050\106\052\115\070\140" + + "\074\212\107\116\116\144\121\142\123\207\132\121\133" + + "\107\134\126\144\122\153\034\164\124\167\065\171\125" + + "\211\113\212\134\233\206\241\141\001\002\000\002\001" + + "\ufe2b\000\062\004\130\006\131\033\035\043\127\050\106" + + "\052\115\070\140\074\212\107\116\116\144\121\142\123" + + "\207\132\121\133\107\134\126\144\122\153\034\164\124" + + "\167\065\171\125\211\113\212\134\233\206\241\141\001" + + "\002\000\002\001\ufe28\000\004\215\u0101\001\002\000\062" + + "\004\130\006\131\033\035\043\127\050\106\052\115\070" + + "\140\074\212\107\116\116\144\121\142\123\207\132\121" + + "\133\107\134\126\144\122\153\034\164\124\167\065\171" + + "\125\211\113\212\134\233\206\241\141\001\002\000\014" + + "\050\203\132\201\152\200\175\202\222\204\001\ufe72\000" + + "\012\050\234\132\233\152\232\222\235\001\ufe74\000\004" + + "\150\u0102\001\ufe1d\000\004\065\u0103\001\002\000\004\224" + + "\u0104\001\002\000\002\001\ufe1a\000\014\050\203\132\201" + + "\152\200\175\202\222\204\001\ufe6e\000\012\050\234\132" + + "\233\152\232\222\235\001\ufe70\000\014\050\203\132\201" + + "\152\200\175\202\222\204\001\ufe6a\000\012\050\234\132" + + "\233\152\232\222\235\001\ufe6c\000\004\150\u010a\001\ufe23" + + "\000\004\065\u010b\001\002\000\004\224\u010c\001\002\000" + + "\002\001\ufe20\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe66\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe68\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe62\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe64\000\004\224\u0112\001\002\000\002\001\ufe26" + + "\000\002\001\ufe29\000\014\050\203\132\201\152\200\175" + + "\202\222\204\001\ufe5e\000\012\050\234\132\233\152\232" + + "\222\235\001\ufe60\000\004\065\u0123\001\002\000\004\215" + + "\u011f\001\002\000\004\224\u011e\001\002\000\004\215\u011a" + + "\001\002\000\004\150\u011b\001\ufe1e\000\004\065\u011c\001" + + "\002\000\004\224\u011d\001\002\000\002\001\ufe1b\000\002" + + "\001\ufe2a\000\004\150\u0120\001\ufe24\000\004\065\u0121\001" + + "\002\000\004\224\u0122\001\002\000\002\001\ufe21\000\004" + + "\224\u0124\001\002\000\002\001\ufe27\000\004\123\u0155\001" + + "\002\000\064\004\130\006\131\033\035\043\127\050\106" + + "\052\115\070\140\074\212\107\116\114\u0128\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\002\001\ufe9e\000\054\004\u012a\006\u0130" + + "\033\035\043\127\050\u012f\074\212\107\116\116\144\121" + + "\142\123\u012d\132\u0131\133\107\134\u0129\144\122\153\034" + + "\167\065\171\125\211\u012c\212\u0133\233\u012b\241\141\001" + + "\002\000\004\171\u0152\001\002\000\004\145\u0150\001\002" + + "\000\060\014\054\030\042\032\036\033\035\037\022\067" + + "\053\074\055\114\032\123\033\126\021\140\046\153\034" + + "\156\050\165\045\167\027\177\025\201\051\207\041\210" + + "\043\214\024\226\044\227\023\233\026\001\002\000\004" + + "\073\u0149\001\002\000\054\004\u012a\006\u0130\033\035\043" + + "\127\050\u012f\074\212\107\116\116\144\121\275\123\u012d" + + "\132\u0131\133\107\134\u0129\144\122\153\034\167\065\171" + + "\125\211\u012c\212\u0133\233\u012b\241\141\001\002\000\004" + + "\171\273\001\002\000\004\171\u0144\001\002\000\004\224" + + "\u0141\001\002\000\054\004\u012a\006\u0130\033\035\043\127" + + "\050\u012f\074\212\107\116\116\144\121\142\123\u012d\132" + + "\u0131\133\107\134\u0129\144\122\153\034\167\065\171\125" + + "\211\u012c\212\u0133\233\u012b\241\141\001\002\000\014\050" + + "\u0138\132\u0137\152\u0136\160\u013f\222\u0139\001\002\000\054" + + "\004\u012a\006\u0130\033\035\043\127\050\u012f\074\212\107" + + "\116\116\144\121\142\123\u012d\132\u0131\133\107\134\u0129" + + "\144\122\153\034\167\065\171\125\211\u012c\212\u0133\233" + + "\u012b\241\141\001\002\000\014\050\u0138\103\u0135\132\u0137" + + "\152\u0136\222\u0139\001\002\000\032\014\054\033\035\037" + + "\022\074\066\114\032\123\067\126\021\140\063\153\034" + + "\156\050\167\065\226\044\001\002\000\054\004\u012a\006" + + "\u0130\033\035\043\127\050\u012f\074\212\107\116\116\144" + + "\121\142\123\u012d\132\u0131\133\107\134\u0129\144\122\153" + + "\034\167\065\171\125\211\u012c\212\u0133\233\u012b\241\141" + + "\001\002\000\054\004\u012a\006\u0130\033\035\043\127\050" + + "\u012f\074\212\107\116\116\144\121\142\123\u012d\132\u0131" + + "\133\107\134\u0129\144\122\153\034\167\065\171\125\211" + + "\u012c\212\u0133\233\u012b\241\141\001\002\000\054\004\u012a" + + "\006\u0130\033\035\043\127\050\u012f\074\212\107\116\116" + + "\144\121\142\123\u012d\132\u0131\133\107\134\u0129\144\122" + + "\153\034\167\065\171\125\211\u012c\212\u0133\233\u012b\241" + + "\141\001\002\000\054\004\u012a\006\u0130\033\035\043\127" + + "\050\u012f\074\212\107\116\116\144\121\142\123\u012d\132" + + "\u0131\133\107\134\u0129\144\122\153\034\167\065\171\125" + + "\211\u012c\212\u0133\233\u012b\241\141\001\002\000\002\001" + + "\ufeb0\000\002\001\ufeaf\000\006\050\u0138\222\u0139\001\ufeb1" + + "\000\006\050\u0138\222\u0139\001\ufeb2\000\002\001\ufe92\000" + + "\002\001\uff24\000\002\001\ufead\000\004\171\u0142\001\002" + + "\000\062\004\130\006\131\033\035\043\127\050\106\052" + + "\115\070\140\074\212\107\116\116\144\121\142\123\207" + + "\132\121\133\107\134\126\144\122\153\034\164\124\167" + + "\065\171\125\211\113\212\134\233\206\241\141\001\002" + + "\000\002\001\ufe9d\000\004\026\u0145\001\002\000\062\004" + + "\130\006\131\033\035\043\127\050\106\052\115\070\140" + + "\074\212\107\116\116\144\121\142\123\207\132\121\133" + + "\107\134\126\144\122\153\034\164\124\167\065\171\125" + + "\211\113\212\134\233\206\241\141\001\002\000\002\001" + + "\ufe9a\000\014\050\u0138\132\u0137\152\u0136\176\u0148\222\u0139" + + "\001\002\000\002\001\ufeac\000\004\171\u014a\001\002\000" + + "\062\004\130\006\131\033\035\043\127\050\106\052\115" + + "\070\140\074\212\107\116\116\144\121\142\123\207\132" + + "\121\133\107\134\126\144\122\153\034\164\124\167\065" + + "\171\125\211\113\212\134\233\206\241\141\001\002\000" + + "\002\001\ufe9c\000\004\123\u014d\001\002\000\054\004\u012a" + + "\006\u0130\033\035\043\127\050\u012f\074\212\107\116\116" + + "\144\121\142\123\u012d\132\u0131\133\107\134\u0129\144\122" + + "\153\034\167\065\171\125\211\u012c\212\u0133\233\u012b\241" + + "\141\001\002\000\014\050\u0138\132\u0137\152\u0136\176\u014f" + + "\222\u0139\001\002\000\002\001\ufe98\000\054\004\u012a\006" + + "\u0130\033\035\043\127\050\u012f\074\212\107\116\116\144" + + "\121\142\123\u012d\132\u0131\133\107\134\u0129\144\122\153" + + "\034\167\065\171\125\211\u012c\212\u0133\233\u012b\241\141" + + "\001\002\000\012\050\u0138\132\u0137\152\u0136\222\u0139\001" + + "\ufe99\000\004\026\u0153\001\002\000\062\004\130\006\131" + + "\033\035\043\127\050\106\052\115\070\140\074\212\107" + + "\116\116\144\121\142\123\207\132\121\133\107\134\126" + + "\144\122\153\034\164\124\167\065\171\125\211\113\212" + + "\134\233\206\241\141\001\002\000\002\001\ufe9b\000\172" + + "\004\130\006\173\010\331\014\054\024\354\025\343\030" + + "\042\032\036\033\035\037\022\042\165\043\127\050\106" + + "\051\346\052\115\054\157\061\175\067\332\070\140\074" + + "\123\100\324\107\116\110\350\114\032\116\144\121\142" + + "\123\334\126\021\132\121\133\107\134\126\135\133\136" + + "\132\140\046\142\336\144\122\147\342\153\034\156\050" + + "\157\353\162\174\164\124\165\045\167\027\171\125\172" + + "\120\177\025\201\051\207\041\210\043\211\163\212\134" + + "\214\024\217\111\220\330\226\044\227\023\233\352\235" + + "\335\241\141\001\002\000\024\051\u01ed\064\372\065\361" + + "\100\u01ea\110\u01f0\111\u0160\112\u0162\137\374\142\363\001" + + "\002\000\050\021\u01c6\064\372\065\361\075\366\076\367" + + "\077\370\110\u01c2\111\u0160\112\u0162\117\375\124\357\125" + + "\362\130\u01ca\137\374\142\363\145\322\152\321\176\u0198" + + "\205\u01cc\001\002\000\036\064\372\065\361\075\366\076" + + "\367\077\370\110\u01ad\111\u0160\112\u0162\117\375\124\357" + + "\125\362\132\256\152\255\176\u01e9\001\002\000\042\050" + + "\234\064\372\065\361\075\366\076\367\077\370\110\356" + + "\117\375\124\357\125\362\132\233\137\374\142\363\152" + + "\232\176\u014f\222\235\001\002\000\016\064\372\065\361" + + "\110\u0181\137\374\142\363\176\u0197\001\002\000\022\012" + + "\u017c\064\372\065\361\110\u0181\137\374\142\363\150\u017f" + + "\176\u017d\001\002\000\016\051\u0165\105\u015f\110\u0164\111" + + "\u0160\112\u0162\114\u0128\001\002\000\044\050\203\064\372" + + "\065\361\075\366\076\367\077\370\110\356\117\375\124" + + "\357\125\362\132\201\137\374\142\363\152\200\175\202" + + "\176\u015e\222\204\001\002\000\002\001\ufeb8\000\064\014" + + "\054\030\042\032\036\033\035\037\022\042\u0168\067\053" + + "\074\055\114\032\123\033\126\021\140\046\153\034\156" + + "\050\165\045\167\027\177\025\201\051\207\u016c\210\043" + + "\214\024\226\044\227\023\233\026\234\u0169\001\002\000" + + "\002\001\ufe17\000\002\001\ufe3e\000\002\001\ufe19\000\002" + + "\001\ufe42\000\006\142\u0178\143\u0179\001\002\000\006\104" + + "\u0167\142\u0166\001\002\000\004\104\u0176\001\002\000\064" + + "\014\054\030\042\032\036\033\035\037\022\042\u0168\067" + + "\053\074\055\114\032\123\033\126\021\140\046\153\034" + + "\156\050\165\045\167\027\177\025\201\051\207\u016c\210" + + "\043\214\024\226\044\227\023\233\026\234\u0169\001\002" + + "\000\032\006\223\033\035\042\165\054\157\061\175\067" + + "\167\123\225\153\034\162\174\167\065\211\226\233\224" + + "\001\002\000\062\004\130\006\131\033\035\043\127\050" + + "\106\052\115\070\140\074\212\107\116\116\144\121\142" + + "\123\207\132\121\133\107\134\126\144\122\153\034\164" + + "\124\167\065\171\125\211\113\212\134\233\206\241\141" + + "\001\002\000\002\001\ufe85\000\002\001\ufe8f\000\040\030" + + "\042\033\035\074\u0171\123\u016f\153\034\165\045\167\065" + + "\177\025\201\051\207\041\210\043\214\024\227\023\233" + + "\026\234\u016d\001\ufee8\000\004\145\u0172\001\002\000\002" + + "\001\ufe8e\000\040\030\042\033\035\074\u0171\123\u016f\153" + + "\034\165\045\167\065\177\025\201\051\206\154\207\041" + + "\210\043\214\024\227\023\233\026\001\002\000\004\177" + + "\152\001\002\000\004\041\060\001\002\000\004\174\304" + + "\001\002\000\002\001\ufeec\000\002\001\ufe91\000\006\132" + + "\256\152\255\001\ufe90\000\064\014\054\030\042\032\036" + + "\033\035\037\022\042\u0168\067\053\074\055\114\032\123" + + "\033\126\021\140\046\153\034\156\050\165\045\167\027" + + "\177\025\201\051\207\u016c\210\043\214\024\226\044\227" + + "\023\233\026\234\u0169\001\002\000\002\001\ufe86\000\004" + + "\143\u017a\001\002\000\002\001\ufe18\000\002\001\ufe16\000" + + "\002\001\ufe84\000\172\004\130\006\173\010\331\014\054" + + "\024\354\025\343\030\042\032\036\033\035\037\022\042" + + "\165\043\127\050\106\051\346\052\115\054\157\061\175" + + "\067\332\070\140\074\123\100\324\107\116\110\350\114" + + "\032\116\144\121\142\123\334\126\021\132\121\133\107" + + "\134\126\135\133\136\132\140\046\142\336\144\122\147" + + "\342\153\034\156\050\157\353\162\174\164\124\165\045" + + "\167\027\171\125\172\120\177\025\201\051\207\041\210" + + "\043\211\163\212\134\214\024\217\111\220\330\226\044" + + "\227\023\233\352\235\335\241\141\001\002\000\002\001" + + "\ufe3b\000\172\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\051\346\052\115\054\157\061\175\067\332" + + "\070\140\074\123\100\324\107\116\110\350\114\032\116" + + "\144\121\142\123\334\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\142\336\144\122\147\342\153" + + "\034\156\050\157\353\162\174\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\217\111\220\330\226\044\227\023" + + "\233\352\235\335\241\141\001\002\000\172\004\130\006" + + "\173\010\331\014\054\024\354\025\343\030\042\032\036" + + "\033\035\037\022\042\165\043\127\050\106\051\346\052" + + "\115\054\157\061\175\067\332\070\140\074\123\100\324" + + "\107\116\110\350\114\032\116\144\121\142\123\334\126" + + "\021\132\121\133\107\134\126\135\133\136\132\140\046" + + "\142\336\144\122\147\342\153\034\156\050\157\353\162" + + "\174\164\124\165\045\167\027\171\125\172\120\177\025" + + "\201\051\207\041\210\043\211\163\212\134\214\024\217" + + "\111\220\330\226\044\227\023\233\352\235\335\241\141" + + "\001\002\000\172\004\130\006\173\010\331\014\054\024" + + "\354\025\343\030\042\032\036\033\035\037\022\042\165" + + "\043\127\050\106\051\346\052\115\054\157\061\175\067" + + "\332\070\140\074\123\100\324\107\116\110\350\114\032" + + "\116\144\121\142\123\334\126\021\132\121\133\107\134" + + "\126\135\133\136\132\140\046\142\336\144\122\147\342" + + "\153\034\156\050\157\353\162\174\164\124\165\045\167" + + "\027\171\125\172\120\177\025\201\051\207\041\210\043" + + "\211\163\212\134\214\024\217\111\220\330\226\044\227" + + "\023\233\352\235\335\241\141\001\002\000\006\065\u0118" + + "\142\u0116\001\002\000\046\021\u01c6\064\372\065\361\075" + + "\366\076\367\077\370\110\u01c2\111\u0160\112\u0162\117\375" + + "\124\357\125\362\130\u01ca\137\374\142\363\145\322\152" + + "\321\205\u01cc\001\002\000\034\064\372\065\361\075\366" + + "\076\367\077\370\110\u01ad\111\u0160\112\u0162\117\375\124" + + "\357\125\362\132\256\152\255\001\002\000\040\050\234" + + "\064\372\065\361\075\366\076\367\077\370\110\356\117" + + "\375\124\357\125\362\132\233\137\374\142\363\152\232" + + "\222\235\001\002\000\014\064\372\065\361\110\u0181\137" + + "\374\142\363\001\002\000\020\012\u017c\064\372\065\361" + + "\110\u0181\137\374\142\363\150\u017f\001\ufe48\000\042\050" + + "\203\064\372\065\361\075\366\076\367\077\370\110\356" + + "\117\375\124\357\125\362\132\201\137\374\142\363\152" + + "\200\175\202\222\204\001\002\000\046\030\042\033\035" + + "\074\u0171\123\u018c\135\133\136\132\153\034\165\045\167" + + "\065\172\120\177\025\201\051\207\041\210\043\214\024" + + "\217\111\227\023\233\u018a\001\002\000\046\030\042\033" + + "\035\074\u0171\123\u018c\135\133\136\132\153\034\165\045" + + "\167\065\172\120\177\025\201\051\207\041\210\043\214" + + "\024\217\111\227\023\233\u018a\001\002\000\060\014\054" + + "\030\042\032\036\033\035\037\022\067\053\074\055\114" + + "\032\123\033\126\021\140\046\153\034\156\050\165\045" + + "\167\027\177\025\201\051\207\041\210\043\214\024\226" + + "\044\227\023\233\026\001\002\000\004\152\321\001\ufe58" + + "\000\042\030\042\033\035\074\u0171\123\u016f\135\u0190\153" + + "\034\165\045\167\065\177\025\201\051\206\154\207\041" + + "\210\043\214\024\227\023\233\026\001\002\000\006\172" + + "\u018f\177\152\001\002\000\002\001\ufe59\000\002\001\ufef6" + + "\000\004\176\u0191\001\002\000\036\030\042\033\035\074" + + "\u0171\123\u016f\153\034\165\045\167\065\177\025\201\051" + + "\207\041\210\043\214\024\227\023\233\026\001\002\000" + + "\002\001\ufef5\000\004\123\u0194\001\002\000\046\030\042" + + "\033\035\074\u0171\123\u018c\135\133\136\132\153\034\165" + + "\045\167\065\172\120\177\025\201\051\207\041\210\043" + + "\214\024\217\111\227\023\233\u018a\001\002\000\006\152" + + "\321\176\u0198\001\002\000\004\176\u0197\001\002\000\002" + + "\001\ufef7\000\002\001\ufed3\000\004\152\321\001\ufe5a\000" + + "\002\001\ufe5b\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe73\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe75\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe6f\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe71\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe6b\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe6d\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe67\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe69\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe63\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe65\000\014\050\203\132\201\152\200\175\202" + + "\222\204\001\ufe5f\000\012\050\234\132\233\152\232\222" + + "\235\001\ufe61\000\022\007\u01bc\022\u01bb\023\u01ba\065\u0118" + + "\075\u0117\117\u0119\142\u0178\143\u0179\001\002\000\032\006" + + "\223\033\035\042\165\054\157\061\175\067\167\123\225" + + "\153\034\162\174\167\065\211\226\233\224\001\002\000" + + "\032\006\223\033\035\042\165\054\157\061\175\067\167" + + "\123\225\153\034\162\174\167\065\211\226\233\224\001" + + "\002\000\032\006\223\033\035\042\165\054\157\061\175" + + "\067\167\123\225\153\034\162\174\167\065\211\226\233" + + "\224\001\002\000\002\001\ufe43\000\032\006\223\033\035" + + "\042\165\054\157\061\175\067\167\123\225\153\034\162" + + "\174\167\065\211\226\233\224\001\002\000\002\001\ufe3f" + + "\000\032\006\223\033\035\042\165\054\157\061\175\067" + + "\167\123\225\153\034\162\174\167\065\211\226\233\224" + + "\001\002\000\006\132\256\152\255\001\ufe37\000\006\132" + + "\256\152\255\001\ufe34\000\006\132\256\152\255\001\ufe32" + + "\000\006\132\256\152\255\001\ufe36\000\006\132\256\152" + + "\255\001\ufe31\000\032\006\223\033\035\042\165\054\157" + + "\061\175\067\167\123\225\153\034\162\174\167\065\211" + + "\226\233\224\001\002\000\032\006\223\033\035\042\165" + + "\054\157\061\175\067\167\123\225\153\034\162\174\167" + + "\065\211\226\233\224\001\002\000\032\006\223\033\035" + + "\042\165\054\157\061\175\067\167\123\225\153\034\162" + + "\174\167\065\211\226\233\224\001\002\000\006\132\256" + + "\152\255\001\ufe33\000\006\132\256\152\255\001\ufe35\000" + + "\010\012\u01c0\132\256\152\255\001\002\000\032\006\223" + + "\033\035\042\165\054\157\061\175\067\167\123\225\153" + + "\034\162\174\167\065\211\226\233\224\001\002\000\006" + + "\132\256\152\255\001\ufe30\000\016\065\u0118\075\u0117\117" + + "\u0119\142\u01e0\143\u0179\147\u01df\001\002\000\036\030\042" + + "\033\035\074\u0171\123\u016f\153\034\165\045\167\065\177" + + "\025\201\051\207\041\210\043\214\024\227\023\233\026" + + "\001\002\000\036\030\042\033\035\074\u0171\123\u016f\153" + + "\034\165\045\167\065\177\025\201\051\207\041\210\043" + + "\214\024\227\023\233\026\001\002\000\036\030\042\033" + + "\035\074\u0171\123\u016f\153\034\165\045\167\065\177\025" + + "\201\051\207\041\210\043\214\024\227\023\233\026\001" + + "\002\000\054\004\u012a\006\u0130\033\035\043\127\050\u012f" + + "\074\212\107\116\116\144\121\142\123\u012d\132\u0131\133" + + "\107\134\u0129\144\122\153\034\167\065\171\125\211\u012c" + + "\212\u0133\233\u012b\241\141\001\002\000\002\001\ufe41\000" + + "\036\030\042\033\035\074\u0171\123\u016f\153\034\165\045" + + "\167\065\177\025\201\051\207\041\210\043\214\024\227" + + "\023\233\026\001\002\000\002\001\ufe3d\000\036\030\042" + + "\033\035\074\u0171\123\u016f\153\034\165\045\167\065\177" + + "\025\201\051\207\041\210\043\214\024\227\023\233\026" + + "\001\002\000\036\030\042\033\035\074\u0171\123\u016f\153" + + "\034\165\045\167\065\177\025\201\051\207\041\210\043" + + "\214\024\227\023\233\026\001\002\000\036\030\042\033" + + "\035\074\u0171\123\u016f\153\034\165\045\167\065\177\025" + + "\201\051\207\041\210\043\214\024\227\023\233\026\001" + + "\002\000\040\030\042\033\035\074\u0171\123\u016f\150\u01ce" + + "\153\034\165\045\167\065\177\025\201\051\207\041\210" + + "\043\214\024\227\023\233\026\001\002\000\036\030\042" + + "\033\035\074\u0171\123\u016f\153\034\165\045\167\065\177" + + "\025\201\051\207\041\210\043\214\024\227\023\233\026" + + "\001\002\000\006\035\u01d1\152\321\001\ufe56\000\002\001" + + "\ufe57\000\040\030\042\033\035\074\u0171\123\u016f\150\u01ce" + + "\153\034\165\045\167\065\177\025\201\051\207\041\210" + + "\043\214\024\227\023\233\026\001\002\000\006\035\u01d1" + + "\152\321\001\002\000\002\001\ufe88\000\004\152\321\001" + + "\ufe87\000\004\152\321\001\ufe53\000\004\152\321\001\ufe55" + + "\000\004\152\321\001\ufe49\000\004\152\321\001\ufe4d\000" + + "\014\050\u0138\132\u0137\152\u0136\205\u01da\222\u0139\001\002" + + "\000\036\030\042\033\035\074\u0171\123\u016f\153\034\165" + + "\045\167\065\177\025\201\051\207\041\210\043\214\024" + + "\227\023\233\026\001\002\000\004\152\321\001\ufe54\000" + + "\004\152\321\001\ufe4b\000\004\152\321\001\ufe4c\000\004" + + "\152\321\001\ufe4a\000\004\145\u01e4\001\002\000\010\065" + + "\u0123\143\u017a\147\u01e1\001\002\000\004\145\u01e2\001\002" + + "\000\032\014\054\033\035\037\022\074\066\114\032\123" + + "\067\126\021\140\063\153\034\156\050\167\065\226\044" + + "\001\002\000\002\001\ufe51\000\032\014\054\033\035\037" + + "\022\074\066\114\032\123\067\126\021\140\063\153\034" + + "\156\050\167\065\226\044\001\002\000\002\001\ufe52\000" + + "\016\012\u017c\064\372\065\361\110\u0181\137\374\142\363" + + "\001\ufe45\000\020\012\u017c\064\372\065\361\110\u0181\137" + + "\374\142\363\150\u017f\001\ufe47\000\014\064\372\065\361" + + "\110\u0181\137\374\142\363\001\ufe46\000\002\001\uff0c\000" + + "\036\030\042\033\035\074\u0171\123\u016f\153\034\165\045" + + "\167\065\177\025\201\051\207\041\210\043\214\024\227" + + "\023\233\026\001\002\000\002\001\ufe40\000\002\001\ufe3c" + + "\000\004\142\u01f7\001\002\000\060\014\054\030\042\032" + + "\036\033\035\037\022\067\053\074\055\114\032\123\033" + + "\126\021\140\046\153\034\156\050\165\045\167\027\177" + + "\025\201\051\207\041\210\043\214\024\226\044\227\023" + + "\233\026\001\002\000\060\014\054\030\042\032\036\033" + + "\035\037\022\067\053\074\055\114\032\123\033\126\021" + + "\140\046\153\034\156\050\165\045\167\027\177\025\201" + + "\051\207\041\210\043\214\024\226\044\227\023\233\026" + + "\001\002\000\044\030\042\033\035\065\u0118\074\u0171\123" + + "\u016f\142\u01f1\143\u0179\153\034\165\045\167\065\177\025" + + "\201\051\207\041\210\043\214\024\227\023\233\026\001" + + "\002\000\006\065\u0123\143\u017a\001\002\000\006\145\u01f3" + + "\152\321\001\002\000\060\014\054\030\042\032\036\033" + + "\035\037\022\067\053\074\055\114\032\123\033\126\021" + + "\140\046\153\034\156\050\165\045\167\027\177\025\201" + + "\051\207\041\210\043\214\024\226\044\227\023\233\026" + + "\001\002\000\002\001\ufe76\000\002\001\ufe2f\000\002\001" + + "\ufe2e\000\004\101\u01f8\001\002\000\036\030\042\033\035" + + "\074\u0171\123\u016f\153\034\165\045\167\065\177\025\201" + + "\051\207\041\210\043\214\024\227\023\233\026\001\002" + + "\000\004\152\321\001\ufe79\000\006\152\321\236\u01fb\001" + + "\ufe78\000\172\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\051\346\052\115\054\157\061\175\067\332" + + "\070\140\074\123\100\324\107\116\110\350\114\032\116" + + "\144\121\142\123\334\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\142\336\144\122\147\342\153" + + "\034\156\050\157\353\162\174\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\217\111\220\330\226\044\227\023" + + "\233\352\235\335\241\141\001\002\000\020\012\u017c\064" + + "\372\065\361\110\u0181\137\374\142\363\150\u017f\001\ufe77" + + "\000\002\001\uff1d\000\002\001\ufe5c\000\004\110\u0202\001" + + "\ufe89\000\022\012\u017c\064\372\065\361\110\u0181\137\374" + + "\142\363\150\u017f\154\u0201\001\002\000\002\001\ufe4f\000" + + "\004\141\u0203\001\ufe8a\000\060\014\054\030\042\032\036" + + "\033\035\037\022\067\053\074\055\114\032\123\033\126" + + "\021\140\046\153\034\156\050\165\045\167\027\177\025" + + "\201\051\207\041\210\043\214\024\226\044\227\023\233" + + "\026\001\002\000\012\071\u0208\103\u0205\146\u0206\236\u0207" + + "\001\002\000\002\001\ufe8d\000\002\001\ufe8b\000\172\004" + + "\130\006\173\010\331\014\054\024\354\025\343\030\042" + + "\032\036\033\035\037\022\042\165\043\127\050\106\051" + + "\346\052\115\054\157\061\175\067\332\070\140\074\123" + + "\100\324\107\116\110\350\114\032\116\144\121\142\123" + + "\334\126\021\132\121\133\107\134\126\135\133\136\132" + + "\140\046\142\336\144\122\147\342\153\034\156\050\157" + + "\353\162\174\164\124\165\045\167\027\171\125\172\120" + + "\177\025\201\051\207\041\210\043\211\163\212\134\214" + + "\024\217\111\220\330\226\044\227\023\233\352\235\335" + + "\241\141\001\002\000\002\001\ufe8c\000\060\014\054\030" + + "\042\032\036\033\035\037\022\067\053\074\055\114\032" + + "\123\033\126\021\140\046\153\034\156\050\165\045\167" + + "\027\177\025\201\051\207\041\210\043\214\024\226\044" + + "\227\023\233\026\001\002\000\004\236\u020e\001\002\000" + + "\006\114\u0128\236\u020c\001\002\000\172\004\130\006\173" + + "\010\331\014\054\024\354\025\343\030\042\032\036\033" + + "\035\037\022\042\165\043\127\050\106\051\346\052\115" + + "\054\157\061\175\067\332\070\140\074\123\100\324\107" + + "\116\110\350\114\032\116\144\121\142\123\334\126\021" + + "\132\121\133\107\134\126\135\133\136\132\140\046\142" + + "\336\144\122\147\342\153\034\156\050\157\353\162\174" + + "\164\124\165\045\167\027\171\125\172\120\177\025\201" + + "\051\207\041\210\043\211\163\212\134\214\024\217\111" + + "\220\330\226\044\227\023\233\352\235\335\241\141\001" + + "\002\000\020\012\u017c\064\372\065\361\110\u0181\137\374" + + "\142\363\150\u017f\001\ufe7c\000\172\004\130\006\173\010" + + "\331\014\054\024\354\025\343\030\042\032\036\033\035" + + "\037\022\042\165\043\127\050\106\051\346\052\115\054" + + "\157\061\175\067\332\070\140\074\123\100\324\107\116" + + "\110\350\114\032\116\144\121\142\123\334\126\021\132" + + "\121\133\107\134\126\135\133\136\132\140\046\142\336" + + "\144\122\147\342\153\034\156\050\157\353\162\174\164" + + "\124\165\045\167\027\171\125\172\120\177\025\201\051" + + "\207\041\210\043\211\163\212\134\214\024\217\111\220" + + "\330\226\044\227\023\233\352\235\335\241\141\001\002" + + "\000\020\012\u017c\064\372\065\361\110\u0181\137\374\142" + + "\363\150\u017f\001\ufe7d\000\020\012\u017c\064\372\065\361" + + "\110\u0181\137\374\142\363\150\u017f\001\ufe7e\000\022\012" + + "\u017c\064\372\065\361\110\u0181\137\374\142\363\150\u017f" + + "\154\u0212\001\002\000\002\001\ufe50\000\012\071\u0208\103" + + "\u0205\146\u0206\236\u0220\001\002\000\004\072\u0215\001\002" + + "\000\032\014\054\033\035\037\022\074\066\114\032\123" + + "\067\126\021\140\063\153\034\156\050\167\065\226\044" + + "\001\002\000\004\224\u0217\001\002\000\024\033\035\123" + + "\u021b\135\133\136\132\153\034\167\065\172\120\217\111" + + "\233\u021a\001\002\000\004\103\u021e\001\002\000\004\172" + + "\u018f\001\002\000\060\014\054\030\042\032\036\033\035" + + "\037\022\067\053\074\055\114\032\123\033\126\021\140" + + "\046\153\034\156\050\165\045\167\027\177\025\201\051" + + "\207\041\210\043\214\024\226\044\227\023\233\026\001" + + "\002\000\004\135\u0190\001\002\000\004\123\u021d\001\002" + + "\000\024\033\035\123\u021b\135\133\136\132\153\034\167" + + "\065\172\120\217\111\233\u021a\001\002\000\032\014\054" + + "\033\035\037\022\074\066\114\032\123\067\126\021\140" + + "\063\153\034\156\050\167\065\226\044\001\002\000\002" + + "\001\ufe83\000\172\004\130\006\173\010\331\014\054\024" + + "\354\025\343\030\042\032\036\033\035\037\022\042\165" + + "\043\127\050\106\051\346\052\115\054\157\061\175\067" + + "\332\070\140\074\123\100\324\107\116\110\350\114\032" + + "\116\144\121\142\123\334\126\021\132\121\133\107\134" + + "\126\135\133\136\132\140\046\142\336\144\122\147\342" + + "\153\034\156\050\157\353\162\174\164\124\165\045\167" + + "\027\171\125\172\120\177\025\201\051\207\041\210\043" + + "\211\163\212\134\214\024\217\111\220\330\226\044\227" + + "\023\233\352\235\335\241\141\001\002\000\060\014\054" + + "\030\042\032\036\033\035\037\022\067\053\074\055\114" + + "\032\123\033\126\021\140\046\153\034\156\050\165\045" + + "\167\027\177\025\201\051\207\041\210\043\214\024\226" + + "\044\227\023\233\026\001\002\000\004\236\u0226\001\002" + + "\000\006\114\u0128\236\u0224\001\002\000\172\004\130\006" + + "\173\010\331\014\054\024\354\025\343\030\042\032\036" + + "\033\035\037\022\042\165\043\127\050\106\051\346\052" + + "\115\054\157\061\175\067\332\070\140\074\123\100\324" + + "\107\116\110\350\114\032\116\144\121\142\123\334\126" + + "\021\132\121\133\107\134\126\135\133\136\132\140\046" + + "\142\336\144\122\147\342\153\034\156\050\157\353\162" + + "\174\164\124\165\045\167\027\171\125\172\120\177\025" + + "\201\051\207\041\210\043\211\163\212\134\214\024\217" + + "\111\220\330\226\044\227\023\233\352\235\335\241\141" + + "\001\002\000\020\012\u017c\064\372\065\361\110\u0181\137" + + "\374\142\363\150\u017f\001\ufe80\000\172\004\130\006\173" + + "\010\331\014\054\024\354\025\343\030\042\032\036\033" + + "\035\037\022\042\165\043\127\050\106\051\346\052\115" + + "\054\157\061\175\067\332\070\140\074\123\100\324\107" + + "\116\110\350\114\032\116\144\121\142\123\334\126\021" + + "\132\121\133\107\134\126\135\133\136\132\140\046\142" + + "\336\144\122\147\342\153\034\156\050\157\353\162\174" + + "\164\124\165\045\167\027\171\125\172\120\177\025\201" + + "\051\207\041\210\043\211\163\212\134\214\024\217\111" + + "\220\330\226\044\227\023\233\352\235\335\241\141\001" + + "\002\000\020\012\u017c\064\372\065\361\110\u0181\137\374" + + "\142\363\150\u017f\001\ufe81\000\020\012\u017c\064\372\065" + + "\361\110\u0181\137\374\142\363\150\u017f\001\ufe82\000\004" + + "\114\u022d\001\002\000\004\145\u022b\001\002\000\004\174" + + "\304\001\002\000\002\001\ufe2d\000\054\004\u012a\006\u0130" + + "\033\035\043\127\050\u012f\074\212\107\116\116\144\121" + + "\142\123\u012d\132\u0131\133\107\134\u0129\144\122\153\034" + + "\167\065\171\125\211\u012c\212\u0133\233\u012b\241\141\001" + + "\002\000\014\050\u0138\132\u0137\152\u0136\160\u022f\222\u0139" + + "\001\002\000\002\001\ufe38\000\032\014\054\033\035\037" + + "\022\074\066\114\032\123\067\126\021\140\063\153\034" + + "\156\050\167\065\226\044\001\002\000\004\100\u0232\001" + + "\002\000\172\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\051\346\052\115\054\157\061\175\067\332" + + "\070\140\074\123\100\324\107\116\110\350\114\032\116" + + "\144\121\142\123\334\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\142\336\144\122\147\342\153" + + "\034\156\050\157\353\162\174\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\217\111\220\330\226\044\227\023" + + "\233\352\235\335\241\141\001\002\000\020\012\u017c\064" + + "\372\065\361\110\u0181\137\374\142\363\150\u017f\001\ufe7a" + + "\000\002\001\ufe44\000\022\012\u017c\064\372\065\361\110" + + "\u0181\137\374\142\363\150\u017f\154\u0236\001\002\000\002" + + "\001\ufe4e\000\026\051\u01ed\064\372\065\361\100\u01ea\110" + + "\u01f0\111\u0160\112\u0162\137\374\142\363\176\u0252\001\002" + + "\000\050\021\u01c6\064\372\065\361\075\366\076\367\077" + + "\370\110\u01c2\111\u0160\112\u0162\117\375\124\357\125\362" + + "\130\u01ca\137\374\142\363\145\322\152\321\176\u0251\205" + + "\u01cc\001\002\000\006\156\u024d\176\u0191\001\ufef8\000\036" + + "\064\372\065\361\075\366\076\367\077\370\110\u01ad\111" + + "\u0160\112\u0162\117\375\124\357\125\362\132\256\152\255" + + "\176\270\001\002\000\042\050\234\064\372\065\361\075" + + "\366\076\367\077\370\110\356\117\375\124\357\125\362" + + "\132\233\137\374\142\363\152\232\176\u0148\222\235\001" + + "\uff65\000\010\156\u0229\176\u024b\234\u022a\001\002\000\022" + + "\012\u017c\064\372\065\361\110\u0181\137\374\142\363\150" + + "\u017f\176\u024a\001\002\000\020\051\u0165\105\u015f\110\u0164" + + "\111\u0160\112\u0162\114\u0128\176\074\001\002\000\044\050" + + "\203\064\372\065\361\075\366\076\367\077\370\110\356" + + "\117\375\124\357\125\362\132\201\137\374\142\363\152" + + "\200\175\202\176\u0249\222\204\001\uff64\000\004\176\u0241" + + "\001\002\000\004\200\u0242\001\002\000\004\123\u0243\001" + + "\002\000\036\030\042\033\035\074\u0171\123\u016f\153\034" + + "\165\045\167\065\177\025\201\051\207\041\210\043\214" + + "\024\227\023\233\026\001\002\000\006\035\u0247\152\321" + + "\001\ufef3\000\004\176\u0246\001\002\000\002\001\uff1c\000" + + "\036\030\042\033\035\074\u0171\123\u016f\153\034\165\045" + + "\167\065\177\025\201\051\207\041\210\043\214\024\227" + + "\023\233\026\001\002\000\002\001\ufef4\000\002\001\ufebf" + + "\000\002\001\ufe3a\000\032\014\054\033\035\037\022\074" + + "\066\114\032\123\067\126\021\140\063\153\034\156\050" + + "\167\065\226\044\001\002\000\002\001\ufe39\000\004\114" + + "\u024e\001\002\000\054\004\u012a\006\u0130\033\035\043\127" + + "\050\u012f\074\212\107\116\116\144\121\142\123\u012d\132" + + "\u0131\133\107\134\u0129\144\122\153\034\167\065\171\125" + + "\211\u012c\212\u0133\233\u012b\241\141\001\002\000\014\050" + + "\u0138\132\u0137\152\u0136\160\u0250\222\u0139\001\002\000\002" + + "\001\ufef9\000\002\001\ufee3\000\002\001\uff22\000\006\133" + + "\u025c\241\u025b\001\002\000\006\103\u0255\236\u0256\001\002" + + "\000\032\014\054\033\035\037\022\074\066\114\032\123" + + "\067\126\021\140\063\153\034\156\050\167\065\226\044" + + "\001\002\000\172\004\130\006\173\010\331\014\054\024" + + "\354\025\343\030\042\032\036\033\035\037\022\042\165" + + "\043\127\050\106\051\346\052\115\054\157\061\175\067" + + "\332\070\140\074\123\100\324\107\116\110\350\114\032" + + "\116\144\121\142\123\334\126\021\132\121\133\107\134" + + "\126\135\133\136\132\140\046\142\336\144\122\147\342" + + "\153\034\156\050\157\353\162\174\164\124\165\045\167" + + "\027\171\125\172\120\177\025\201\051\207\041\210\043" + + "\211\163\212\134\214\024\217\111\220\330\226\044\227" + + "\023\233\352\235\335\241\141\001\002\000\020\012\u017c" + + "\064\372\065\361\110\u0181\137\374\142\363\150\u017f\001" + + "\uff1a\000\004\236\u0259\001\002\000\172\004\130\006\173" + + "\010\331\014\054\024\354\025\343\030\042\032\036\033" + + "\035\037\022\042\165\043\127\050\106\051\346\052\115" + + "\054\157\061\175\067\332\070\140\074\123\100\324\107" + + "\116\110\350\114\032\116\144\121\142\123\334\126\021" + + "\132\121\133\107\134\126\135\133\136\132\140\046\142" + + "\336\144\122\147\342\153\034\156\050\157\353\162\174" + + "\164\124\165\045\167\027\171\125\172\120\177\025\201" + + "\051\207\041\210\043\211\163\212\134\214\024\217\111" + + "\220\330\226\044\227\023\233\352\235\335\241\141\001" + + "\002\000\020\012\u017c\064\372\065\361\110\u0181\137\374" + + "\142\363\150\u017f\001\uff1b\000\004\145\u025f\001\002\000" + + "\004\145\u025d\001\002\000\032\006\223\033\035\042\165" + + "\054\157\061\175\067\167\123\225\153\034\162\174\167" + + "\065\211\226\233\224\001\002\000\006\132\256\152\255" + + "\001\ufeff\000\032\006\223\033\035\042\165\054\157\061" + + "\175\067\167\123\225\153\034\162\174\167\065\211\226" + + "\233\224\001\002\000\006\132\256\152\255\001\uff00\000" + + "\004\101\u0262\001\002\000\172\004\130\006\173\010\331" + + "\014\054\024\354\025\343\030\042\032\036\033\035\037" + + "\022\042\165\043\127\050\106\051\346\052\115\054\157" + + "\061\175\067\332\070\140\074\123\100\324\107\116\110" + + "\350\114\032\116\144\121\142\123\334\126\021\132\121" + + "\133\107\134\126\135\133\136\132\140\046\142\336\144" + + "\122\147\342\153\034\156\050\157\353\162\174\164\124" + + "\165\045\167\027\171\125\172\120\177\025\201\051\207" + + "\041\210\043\211\163\212\134\214\024\217\111\220\330" + + "\226\044\227\023\233\352\235\335\241\141\001\002\000" + + "\020\012\u017c\064\372\065\361\110\u0181\137\374\142\363" + + "\150\u017f\001\ufe7b\000\004\236\u0265\001\002\000\172\004" + + "\130\006\173\010\331\014\054\024\354\025\343\030\042" + + "\032\036\033\035\037\022\042\165\043\127\050\106\051" + + "\346\052\115\054\157\061\175\067\332\070\140\074\123" + + "\100\324\107\116\110\350\114\032\116\144\121\142\123" + + "\334\126\021\132\121\133\107\134\126\135\133\136\132" + + "\140\046\142\336\144\122\147\342\153\034\156\050\157" + + "\353\162\174\164\124\165\045\167\027\171\125\172\120" + + "\177\025\201\051\207\041\210\043\211\163\212\134\214" + + "\024\217\111\220\330\226\044\227\023\233\352\235\335" + + "\241\141\001\002\000\020\012\u017c\064\372\065\361\110" + + "\u0181\137\374\142\363\150\u017f\001\ufe7f\000\002\001\uff45" + + "\000\002\001\uff3d\000\014\050\234\132\233\152\232\176" + + "\u0148\222\235\001\002\000\006\114\u0128\176\074\001\002" + + "\000\004\176\u0252\001\002\000\010\145\322\152\321\176" + + "\u0251\001\002\000\016\050\203\132\201\152\200\175\202" + + "\176\u0249\222\204\001\002\000\124\004\130\006\131\014" + + "\054\030\042\032\036\033\035\037\022\043\127\050\106" + + "\052\115\067\053\070\140\074\123\107\116\114\032\116" + + "\144\121\142\123\312\126\021\132\121\133\107\134\126" + + "\140\046\144\122\153\034\156\050\164\124\165\045\167" + + "\027\171\125\177\025\201\051\207\041\210\043\211\113" + + "\212\134\214\024\226\044\227\023\233\310\241\141\001" + + "\002\000\002\001\uff42\000\004\123\u0271\001\002\000\102" + + "\004\130\006\131\030\042\033\035\043\127\050\106\052" + + "\115\070\140\074\u0275\107\116\116\144\121\142\123\u0274" + + "\132\121\133\107\134\126\144\122\153\034\164\124\165" + + "\045\167\065\171\125\177\025\201\051\207\041\210\043" + + "\211\113\212\134\214\024\227\023\233\310\241\141\001" + + "\002\000\010\164\271\171\273\177\152\001\002\000\014" + + "\050\234\132\233\152\232\176\u014f\222\235\001\002\000" + + "\104\004\130\006\131\030\042\033\035\043\127\050\106" + + "\052\277\070\140\074\u0275\107\116\116\144\121\275\123" + + "\u0274\132\121\133\107\134\126\144\122\153\034\164\124" + + "\165\045\167\065\171\125\177\025\201\051\206\154\207" + + "\041\210\043\211\113\212\134\214\024\227\023\233\310" + + "\241\141\001\002\000\010\041\060\043\214\242\213\001" + + "\002\000\016\050\203\132\201\152\200\175\202\176\u015e" + + "\222\204\001\002\000\124\004\130\006\131\014\054\030" + + "\042\032\036\033\035\037\022\043\127\050\106\052\115" + + "\067\053\070\140\074\123\107\116\114\032\116\144\121" + + "\142\123\312\126\021\132\121\133\107\134\126\140\046" + + "\144\122\153\034\156\050\164\124\165\045\167\027\171" + + "\125\177\025\201\051\207\041\210\043\211\113\212\134" + + "\214\024\226\044\227\023\233\310\241\141\001\002\000" + + "\002\001\uff44\000\002\001\ufece\000\004\123\u027c\001\002" + + "\000\002\001\ufebe\000\036\030\042\033\035\074\u0171\123" + + "\u016f\153\034\165\045\167\065\177\025\201\051\207\041" + + "\210\043\214\024\227\023\233\026\001\002\000\004\176" + + "\u027e\001\002\000\002\001\ufecd\000\122\004\130\006\131" + + "\014\054\030\042\033\035\037\022\043\127\050\106\052" + + "\115\070\140\074\123\107\116\114\032\116\144\121\142" + + "\123\u0284\126\021\132\121\133\107\134\126\140\063\144" + + "\122\153\034\156\050\164\124\165\045\167\065\171\125" + + "\177\025\200\u0287\201\051\207\041\210\043\211\113\212" + + "\134\214\024\226\044\227\023\233\310\241\141\001\002" + + "\000\004\145\u0281\001\002\000\004\174\304\001\002\000" + + "\002\001\ufe93\000\012\156\077\164\271\171\273\177\152" + + "\001\002\000\124\004\130\006\131\013\071\014\054\030" + + "\042\033\035\037\022\043\127\050\106\052\277\070\140" + + "\074\123\107\116\114\032\116\144\121\275\123\u0284\126" + + "\021\132\121\133\107\134\126\140\063\144\122\153\034" + + "\156\050\164\124\165\045\167\065\171\125\177\025\201" + + "\051\206\154\207\041\210\043\211\113\212\134\214\024" + + "\226\044\227\023\233\310\241\141\001\002\000\002\001" + + "\ufea6\000\002\001\ufea5\000\004\123\u0289\001\002\000\002" + + "\001\ufea4\000\036\030\042\033\035\074\u0171\123\u016f\153" + + "\034\165\045\167\065\177\025\201\051\207\041\210\043" + + "\214\024\227\023\233\026\001\002\000\004\176\u028b\001" + + "\002\000\002\001\ufea3\000\056\014\054\030\042\033\035" + + "\037\022\074\055\114\032\123\147\126\021\140\063\153" + + "\034\156\u0292\165\045\167\065\177\025\200\u0291\201\051" + + "\207\041\210\043\214\024\226\044\227\023\233\026\001" + + "\002\000\036\030\042\033\035\074\u0171\123\u016f\153\034" + + "\165\045\167\065\177\025\201\051\207\041\210\043\214" + + "\024\227\023\233\026\001\002\000\006\152\321\176\u028f" + + "\001\002\000\002\001\uff0f\000\002\001\uff10\000\004\123" + + "\u0297\001\002\000\004\114\u0294\001\002\000\002\001\uff0e" + + "\000\054\004\u012a\006\u0130\033\035\043\127\050\u012f\074" + + "\212\107\116\116\144\121\142\123\u012d\132\u0131\133\107" + + "\134\u0129\144\122\153\034\167\065\171\125\211\u012c\212" + + "\u0133\233\u012b\241\141\001\002\000\014\050\u0138\132\u0137" + + "\152\u0136\160\u0296\222\u0139\001\002\000\002\001\uff0d\000" + + "\036\030\042\033\035\074\u0171\123\u016f\153\034\165\045" + + "\167\065\177\025\201\051\207\041\210\043\214\024\227" + + "\023\233\026\001\002\000\004\176\u0299\001\002\000\002" + + "\001\uff07\000\004\176\u029b\001\002\000\002\001\uff0a\000" + + "\004\123\u029d\001\002\000\032\006\223\033\035\042\165" + + "\054\157\061\175\067\167\123\225\153\034\162\174\167" + + "\065\211\226\233\224\001\002\000\010\132\256\152\255" + + "\176\u01e9\001\002\000\010\043\u02a0\133\u02a2\241\u02a1\001" + + "\002\000\004\224\u02a7\001\002\000\004\224\u02a5\001\002" + + "\000\004\224\u02a3\001\002\000\004\162\u02a4\001\002\000" + + "\002\001\uff02\000\004\162\u02a6\001\002\000\002\001\uff03" + + "\000\004\162\u02a8\001\002\000\002\001\uff01\000\032\006" + + "\223\033\035\042\165\054\157\061\175\067\167\123\225" + + "\153\034\162\174\167\065\211\226\233\224\001\002\000" + + "\004\071\u02ab\001\002\000\032\006\223\033\035\042\165" + + "\054\157\061\175\067\167\123\225\153\034\162\174\167" + + "\065\211\226\233\224\001\002\000\006\132\256\152\255" + + "\001\ufea9\000\006\132\256\152\255\001\ufeaa\000\006\132" + + "\256\152\255\001\ufe94\000\004\123\u02b0\001\002\000\062" + + "\004\130\006\131\033\035\043\127\050\106\052\115\070" + + "\140\074\212\107\116\116\144\121\142\123\207\132\121" + + "\133\107\134\126\144\122\153\034\164\124\167\065\171" + + "\125\211\113\212\134\233\206\241\141\001\002\000\002" + + "\001\ufec1\000\002\001\ufec3\000\054\004\u012a\006\u0130\033" + + "\035\043\127\050\u012f\074\212\107\116\116\144\121\142" + + "\123\u012d\132\u0131\133\107\134\u0129\144\122\153\034\167" + + "\065\171\125\211\u012c\212\u0133\233\u012b\241\141\001\002" + + "\000\014\045\u02b5\050\u0138\132\u0137\152\u0136\222\u0139\001" + + "\002\000\004\240\u02b6\001\ufeb5\000\062\004\130\006\131" + + "\033\035\043\127\050\106\052\115\070\140\074\212\107" + + "\116\116\144\121\142\123\207\132\121\133\107\134\126" + + "\144\122\153\034\164\124\167\065\171\125\211\113\212" + + "\134\233\206\241\141\001\002\000\014\050\203\132\201" + + "\152\200\175\202\222\204\001\ufeb4\000\012\050\234\132" + + "\233\152\232\222\235\001\002\000\006\050\203\222\204" + + "\001\ufec7\000\006\050\234\222\235\001\ufec9\000\006\050" + + "\203\222\204\001\ufecb\000\006\050\234\222\235\001\ufecc" + + "\000\004\133\u02be\001\002\000\004\145\u02bf\001\002\000" + + "\032\006\223\033\035\042\165\054\157\061\175\067\167" + + "\123\225\153\034\162\174\167\065\211\226\233\224\001" + + "\002\000\006\132\256\152\255\001\ufefe\000\006\164\u02c2" + + "\171\u0142\001\002\000\062\004\130\006\131\033\035\043" + + "\127\050\106\052\115\070\140\074\212\107\116\116\144" + + "\121\142\123\207\132\121\133\107\134\126\144\122\153" + + "\034\164\124\167\065\171\125\211\113\212\134\233\206" + + "\241\141\001\002\000\002\001\ufebd\000\006\152\321\213" + + "\u02c5\001\002\000\004\145\u02c6\001\002\000\036\030\042" + + "\033\035\074\u0171\123\u016f\153\034\165\045\167\065\177" + + "\025\201\051\207\041\210\043\214\024\227\023\233\026" + + "\001\002\000\004\152\321\001\ufef1\000\006\164\u02c9\171" + + "\u014a\001\002\000\062\004\130\006\131\033\035\043\127" + + "\050\106\052\115\070\140\074\212\107\116\116\144\121" + + "\142\123\207\132\121\133\107\134\126\144\122\153\034" + + "\164\124\167\065\171\125\211\113\212\134\233\206\241" + + "\141\001\002\000\002\001\ufebc\000\004\123\u02cc\001\002" + + "\000\074\004\130\006\173\033\035\042\165\043\127\050" + + "\106\052\115\054\157\061\175\067\167\070\140\074\212" + + "\107\116\116\144\121\142\123\265\132\121\133\107\134" + + "\126\144\122\153\034\162\174\164\124\167\065\171\125" + + "\211\163\212\134\233\162\241\141\001\002\000\036\030" + + "\042\033\035\074\u0171\123\u016f\153\034\165\045\167\065" + + "\177\025\201\051\207\041\210\043\214\024\227\023\233" + + "\026\001\002\000\004\176\u02cf\001\002\000\002\001\ufeeb" + + "\000\032\014\054\033\035\037\022\074\066\114\032\123" + + "\067\126\021\140\063\153\034\156\050\167\065\226\044" + + "\001\002\000\004\007\u02d2\001\002\000\032\006\223\033" + + "\035\042\165\054\157\061\175\067\167\123\225\153\034" + + "\162\174\167\065\211\226\233\224\001\002\000\006\132" + + "\256\152\255\001\ufefd\000\032\006\223\033\035\042\165" + + "\054\157\061\175\067\167\123\225\153\034\162\174\167" + + "\065\211\226\233\224\001\002\000\010\132\256\152\255" + + "\224\u02d6\001\002\000\032\006\223\033\035\042\165\054" + + "\157\061\175\067\167\123\225\153\034\162\174\167\065" + + "\211\226\233\224\001\002\000\006\132\256\152\255\001" + + "\ufe95\000\134\004\130\006\131\014\054\030\042\032\036" + + "\033\035\037\022\043\127\050\106\052\115\067\053\070" + + "\140\074\123\107\116\114\032\116\144\121\142\123\117" + + "\126\021\132\121\133\107\134\126\135\133\136\132\140" + + "\046\144\122\153\034\156\050\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\113\212\134\214\024\217\111\226\044\227\023\233\112" + + "\241\141\001\002\000\002\001\uff31\000\012\050\234\132" + + "\233\152\232\222\235\001\uff2d\000\002\001\uff2c\000\002" + + "\001\uff2a\000\006\145\322\152\321\001\uff2e\000\014\050" + + "\203\132\201\152\200\175\202\222\204\001\uff2b\000\016" + + "\050\203\103\u02e1\132\201\152\200\175\202\222\204\001" + + "\002\000\014\050\234\103\u0135\132\233\152\232\222\235" + + "\001\002\000\032\014\054\033\035\037\022\074\066\114" + + "\032\123\067\126\021\140\063\153\034\156\050\167\065" + + "\226\044\001\002\000\002\001\ufeb3\000\002\001\ufefb\000" + + "\062\004\130\006\131\033\035\043\127\050\106\052\115" + + "\070\140\074\212\107\116\116\144\121\142\123\207\132" + + "\121\133\107\134\126\144\122\153\034\164\124\167\065" + + "\171\125\211\113\212\134\233\206\241\141\001\002\000" + + "\014\050\203\132\201\152\200\175\202\222\204\001\ufeb9" + + "\000\012\050\234\132\233\152\232\222\235\001\ufe99\000" + + "\032\006\223\033\035\042\165\054\157\061\175\067\167" + + "\123\225\153\034\162\174\167\065\211\226\233\224\001" + + "\002\000\010\132\256\152\255\224\u02e9\001\002\000\032" + + "\006\223\033\035\042\165\054\157\061\175\067\167\123" + + "\225\153\034\162\174\167\065\211\226\233\224\001\002" + + "\000\006\132\256\152\255\001\ufe97\000\004\026\u02ec\001" + + "\002\000\062\004\130\006\131\033\035\043\127\050\106" + + "\052\115\070\140\074\212\107\116\116\144\121\142\123" + + "\207\132\121\133\107\134\126\144\122\153\034\164\124" + + "\167\065\171\125\211\113\212\134\233\206\241\141\001" + + "\002\000\002\001\ufebb\000\004\236\u02ef\001\ufea2\000\172" + + "\004\130\006\173\010\331\014\054\024\354\025\343\030" + + "\042\032\036\033\035\037\022\042\165\043\127\050\106" + + "\051\346\052\115\054\157\061\175\067\332\070\140\074" + + "\123\100\324\107\116\110\350\114\032\116\144\121\142" + + "\123\334\126\021\132\121\133\107\134\126\135\133\136" + + "\132\140\046\142\336\144\122\147\342\153\034\156\050" + + "\157\353\162\174\164\124\165\045\167\027\171\125\172" + + "\120\177\025\201\051\207\041\210\043\211\163\212\134" + + "\214\024\217\111\220\330\226\044\227\023\233\352\235" + + "\335\241\141\001\002\000\020\012\u017c\064\372\065\361" + + "\110\u0181\137\374\142\363\150\u017f\001\ufea1\000\002\001" + + "\ufec0\000\002\001\ufead\000\004\123\u02f4\001\002\000\112" + + "\004\130\006\131\030\042\033\035\043\127\050\106\052" + + "\115\070\140\074\u0275\107\116\116\144\121\142\123\u02f6" + + "\132\121\133\107\134\126\135\133\136\132\144\122\153" + + "\034\164\124\165\045\167\065\171\125\172\120\177\025" + + "\201\051\207\041\210\043\211\113\212\134\214\024\217" + + "\111\227\023\233\112\241\141\001\002\000\012\164\271" + + "\171\273\172\u018f\177\152\001\002\000\106\004\130\006" + + "\131\030\042\033\035\043\127\050\106\052\277\070\140" + + "\074\u0275\107\116\116\144\121\275\123\u0274\132\121\133" + + "\107\134\126\135\u0190\144\122\153\034\164\124\165\045" + + "\167\065\171\125\177\025\201\051\206\154\207\041\210" + + "\043\211\113\212\134\214\024\227\023\233\310\241\141" + + "\001\002\000\004\152\321\001\ufefa\000\032\006\223\033" + + "\035\042\165\054\157\061\175\067\167\123\225\153\034" + + "\162\174\167\065\211\226\233\224\001\002\000\010\132" + + "\256\152\255\224\u02fa\001\002\000\032\006\223\033\035" + + "\042\165\054\157\061\175\067\167\123\225\153\034\162" + + "\174\167\065\211\226\233\224\001\002\000\006\132\256" + + "\152\255\001\ufe96\000\004\026\u02fd\001\002\000\062\004" + + "\130\006\131\033\035\043\127\050\106\052\115\070\140" + + "\074\212\107\116\116\144\121\142\123\207\132\121\133" + + "\107\134\126\144\122\153\034\164\124\167\065\171\125" + + "\211\113\212\134\233\206\241\141\001\002\000\002\001" + + "\ufeba\000\004\074\u0300\001\002\000\004\020\u0301\001\002" + + "\000\036\030\042\033\035\074\u0171\123\u016f\153\034\165" + + "\045\167\065\177\025\201\051\207\041\210\043\214\024" + + "\227\023\233\026\001\002\000\004\152\321\001\ufeef\000" + + "\004\063\u0306\001\002\000\006\015\075\063\u0305\001\002" + + "\000\002\001\uff1f\000\002\001\uff20\000\004\012\u0308\001" + + "\002\000\060\014\054\030\042\032\036\033\035\037\022" + + "\067\053\074\055\114\032\123\033\126\021\140\046\153" + + "\034\156\050\165\045\167\027\177\025\201\051\207\041" + + "\210\043\214\024\226\044\227\023\233\026\001\002\000" + + "\002\001\ufed2\000\006\026\u030b\152\321\001\002\000\036" + + "\030\042\033\035\074\u0171\123\u016f\153\034\165\045\167" + + "\065\177\025\201\051\207\041\210\043\214\024\227\023" + + "\233\026\001\002\000\004\152\321\001\uff30\000\036\030" + + "\042\033\035\074\u0171\123\u016f\153\034\165\045\167\065" + + "\177\025\201\051\207\041\210\043\214\024\227\023\233" + + "\026\001\002\000\006\073\u030f\152\321\001\002\000\054" + + "\004\u012a\006\u0130\033\035\043\127\050\u012f\074\212\107" + + "\116\116\144\121\142\123\u012d\132\u0131\133\107\134\u0129" + + "\144\122\153\034\167\065\171\125\211\u012c\212\u0133\233" + + "\u012b\241\141\001\002\000\014\050\u0138\132\u0137\152\u0136" + + "\222\u0139\224\u0311\001\002\000\054\004\u012a\006\u0130\033" + + "\035\043\127\050\u012f\074\212\107\116\116\144\121\142" + + "\123\u012d\132\u0131\133\107\134\u0129\144\122\153\034\167" + + "\065\171\125\211\u012c\212\u0133\233\u012b\241\141\001\002" + + "\000\012\050\u0138\132\u0137\152\u0136\222\u0139\001\ufeee\000" + + "\006\152\321\224\u0314\001\002\000\006\122\u0316\232\u0315" + + "\001\002\000\002\001\ufed6\000\002\001\ufed7\000\004\074" + + "\u0318\001\002\000\004\040\u0319\001\002\000\002\001\ufed5" + + "\000\004\034\u031b\001\002\000\006\071\u031c\145\u031d\001" + + "\002\000\004\221\u0320\001\002\000\004\221\u031e\001\002" + + "\000\004\213\u031f\001\002\000\002\001\uff50\000\004\213" + + "\u0321\001\002\000\002\001\uff4f\000\060\014\054\030\042" + + "\032\036\033\035\037\022\067\053\074\055\114\032\123" + + "\033\126\021\140\046\153\034\156\050\165\045\167\027" + + "\177\025\201\051\207\041\210\043\214\024\226\044\227" + + "\023\233\026\001\002\000\002\001\uff1e\000\004\033\u0325" + + "\001\002\000\002\001\uffd3\000\002\001\uffd4\000\006\033" + + "\035\153\034\001\uffd7\000\002\001\uffd8\000\006\035\u02d8" + + "\160\u032a\001\002\000\002\001\uff2f\000\004\123\u032c\001" + + "\002\000\036\030\042\033\035\074\u0171\123\u016f\153\034" + + "\165\045\167\065\177\025\201\051\207\041\210\043\214" + + "\024\227\023\233\026\001\002\000\036\030\042\033\035" + + "\074\u0171\123\u016f\153\034\165\045\167\065\177\025\201" + + "\051\207\041\210\043\214\024\227\023\233\026\001\002" + + "\000\006\152\321\176\u032f\001\002\000\002\001\ufed9\000" + + "\032\014\054\033\035\037\022\074\066\114\032\123\067" + + "\126\021\140\063\153\034\156\050\167\065\226\044\001" + + "\002\000\002\001\uff35\000\004\223\u0333\001\002\000\006" + + "\140\u0335\200\176\001\002\000\002\001\uff3b\000\036\030" + + "\042\033\035\074\u0171\123\u016f\153\034\165\045\167\065" + + "\177\025\201\051\207\041\210\043\214\024\227\023\233" + + "\026\001\002\000\006\164\u0355\231\u0356\001\002\000\006" + + "\177\u0351\231\u0352\001\002\000\006\171\u034e\231\u034d\001" + + "\002\000\006\162\u0349\231\u034a\001\002\000\006\157\u0346" + + "\231\u0345\001\002\000\006\156\u0342\231\u0341\001\002\000" + + "\006\167\u033d\231\u033e\001\002\000\002\001\uffca\000\004" + + "\017\u033f\001\uffcc\000\060\014\054\030\042\032\036\033" + + "\035\037\022\067\053\074\055\114\032\123\033\126\021" + + "\140\046\153\034\156\050\165\045\167\027\177\025\201" + + "\051\207\041\210\043\214\024\226\044\227\023\233\026" + + "\001\002\000\002\001\uffcb\000\004\017\u0343\001\uffbd\000" + + "\002\001\uffbb\000\032\014\054\033\035\037\022\074\066" + + "\114\032\123\067\126\021\140\063\153\034\156\050\167" + + "\065\226\044\001\002\000\002\001\uffbc\000\004\017\u0347" + + "\001\uffc3\000\002\001\uffc1\000\172\004\130\006\173\010" + + "\331\014\054\024\354\025\343\030\042\032\036\033\035" + + "\037\022\042\165\043\127\050\106\051\346\052\115\054" + + "\157\061\175\067\332\070\140\074\123\100\324\107\116" + + "\110\350\114\032\116\144\121\142\123\334\126\021\132" + + "\121\133\107\134\126\135\133\136\132\140\046\142\336" + + "\144\122\147\342\153\034\156\050\157\353\162\174\164" + + "\124\165\045\167\027\171\125\172\120\177\025\201\051" + + "\207\041\210\043\211\163\212\134\214\024\217\111\220" + + "\330\226\044\227\023\233\352\235\335\241\141\001\002" + + "\000\020\012\u017c\064\372\065\361\110\u0181\137\374\142" + + "\363\150\u017f\001\uffc2\000\002\001\uffbe\000\004\017\u034b" + + "\001\uffc0\000\032\006\223\033\035\042\165\054\157\061" + + "\175\067\167\123\225\153\034\162\174\167\065\211\226" + + "\233\224\001\002\000\006\132\256\152\255\001\uffbf\000" + + "\004\017\u034f\001\uffc9\000\002\001\uffc7\000\062\004\130" + + "\006\131\033\035\043\127\050\106\052\115\070\140\074" + + "\212\107\116\116\144\121\142\123\207\132\121\133\107" + + "\134\126\144\122\153\034\164\124\167\065\171\125\211" + + "\113\212\134\233\206\241\141\001\002\000\002\001\uffc8" + + "\000\002\001\uffb8\000\004\017\u0353\001\uffba\000\036\030" + + "\042\033\035\074\u0171\123\u016f\153\034\165\045\167\065" + + "\177\025\201\051\207\041\210\043\214\024\227\023\233" + + "\026\001\002\000\004\152\321\001\uffb9\000\002\001\uffc4" + + "\000\004\017\u0357\001\uffc6\000\062\004\130\006\131\033" + + "\035\043\127\050\106\052\115\070\140\074\212\107\116" + + "\116\144\121\142\123\207\132\121\133\107\134\126\144" + + "\122\153\034\164\124\167\065\171\125\211\113\212\134" + + "\233\206\241\141\001\002\000\002\001\uffc5\000\004\012" + + "\u036a\001\002\000\012\011\u035b\103\u035c\114\u0128\236\u035d" + + "\001\uffb1\000\032\014\054\033\035\037\022\074\066\114" + + "\032\123\067\126\021\140\063\153\034\156\050\167\065" + + "\226\044\001\002\000\060\014\054\030\042\032\036\033" + + "\035\037\022\067\053\074\055\114\032\123\033\126\021" + + "\140\046\153\034\156\050\165\045\167\027\177\025\201" + + "\051\207\041\210\043\214\024\226\044\227\023\233\026" + + "\001\002\000\172\004\130\006\173\010\331\014\054\024" + + "\354\025\343\030\042\032\036\033\035\037\022\042\165" + + "\043\127\050\106\051\346\052\115\054\157\061\175\067" + + "\332\070\140\074\123\100\324\107\116\110\350\114\032" + + "\116\144\121\142\123\334\126\021\132\121\133\107\134" + + "\126\135\133\136\132\140\046\142\336\144\122\147\342" + + "\153\034\156\050\157\353\162\174\164\124\165\045\167" + + "\027\171\125\172\120\177\025\201\051\207\041\210\043" + + "\211\163\212\134\214\024\217\111\220\330\226\044\227" + + "\023\233\352\235\335\241\141\001\002\000\022\011\u035f" + + "\012\u017c\064\372\065\361\110\u0181\137\374\142\363\150" + + "\u017f\001\uffac\000\032\014\054\033\035\037\022\074\066" + + "\114\032\123\067\126\021\140\063\153\034\156\050\167" + + "\065\226\044\001\002\000\004\225\u0361\001\002\000\002" + + "\001\uffab\000\006\011\u0363\236\u0364\001\uffaf\000\032\014" + + "\054\033\035\037\022\074\066\114\032\123\067\126\021" + + "\140\063\153\034\156\050\167\065\226\044\001\002\000" + + "\172\004\130\006\173\010\331\014\054\024\354\025\343" + + "\030\042\032\036\033\035\037\022\042\165\043\127\050" + + "\106\051\346\052\115\054\157\061\175\067\332\070\140" + + "\074\123\100\324\107\116\110\350\114\032\116\144\121" + + "\142\123\334\126\021\132\121\133\107\134\126\135\133" + + "\136\132\140\046\142\336\144\122\147\342\153\034\156" + + "\050\157\353\162\174\164\124\165\045\167\027\171\125" + + "\172\120\177\025\201\051\207\041\210\043\211\163\212" + + "\134\214\024\217\111\220\330\226\044\227\023\233\352" + + "\235\335\241\141\001\002\000\020\012\u017c\064\372\065" + + "\361\110\u0181\137\374\142\363\150\u017f\001\uffad\000\004" + + "\225\u0367\001\002\000\002\001\uffae\000\004\225\u0369\001" + + "\002\000\002\001\uffb0\000\004\113\u036b\001\002\000\060" + + "\014\054\030\042\032\036\033\035\037\022\067\053\074" + + "\055\114\032\123\033\126\021\140\046\153\034\156\050" + + "\165\045\167\027\177\025\201\051\207\041\210\043\214" + + "\024\226\044\227\023\233\026\001\002\000\004\103\u036d" + + "\001\002\000\032\014\054\033\035\037\022\074\066\114" + + "\032\123\067\126\021\140\063\153\034\156\050\167\065" + + "\226\044\001\002\000\006\011\u036f\236\u0370\001\uffb5\000" + + "\032\014\054\033\035\037\022\074\066\114\032\123\067" + + "\126\021\140\063\153\034\156\050\167\065\226\044\001" + + "\002\000\172\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\051\346\052\115\054\157\061\175\067\332" + + "\070\140\074\123\100\324\107\116\110\350\114\032\116" + + "\144\121\142\123\334\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\142\336\144\122\147\342\153" + + "\034\156\050\157\353\162\174\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\217\111\220\330\226\044\227\023" + + "\233\352\235\335\241\141\001\002\000\022\011\u0372\012" + + "\u017c\064\372\065\361\110\u0181\137\374\142\363\150\u017f" + + "\001\uffb3\000\032\014\054\033\035\037\022\074\066\114" + + "\032\123\067\126\021\140\063\153\034\156\050\167\065" + + "\226\044\001\002\000\004\225\u0374\001\002\000\002\001" + + "\uffb2\000\004\225\u0376\001\002\000\002\001\uffb4\000\002" + + "\001\ufffc\000\006\103\u0379\145\u037a\001\002\000\032\014" + + "\054\033\035\037\022\074\066\114\032\123\067\126\021" + + "\140\063\153\034\156\050\167\065\226\044\001\002\000" + + "\032\014\054\033\035\037\022\074\066\114\032\123\067" + + "\126\021\140\063\153\034\156\050\167\065\226\044\001" + + "\002\000\006\012\u037d\236\u037c\001\002\000\172\004\130" + + "\006\173\010\331\014\054\024\354\025\343\030\042\032" + + "\036\033\035\037\022\042\165\043\127\050\106\051\346" + + "\052\115\054\157\061\175\067\332\070\140\074\123\100" + + "\324\107\116\110\350\114\032\116\144\121\142\123\334" + + "\126\021\132\121\133\107\134\126\135\133\136\132\140" + + "\046\142\336\144\122\147\342\153\034\156\050\157\353" + + "\162\174\164\124\165\045\167\027\171\125\172\120\177" + + "\025\201\051\207\041\210\043\211\163\212\134\214\024" + + "\217\111\220\330\226\044\227\023\233\352\235\335\241" + + "\141\001\002\000\004\113\u037e\001\002\000\060\014\054" + + "\030\042\032\036\033\035\037\022\067\053\074\055\114" + + "\032\123\033\126\021\140\046\153\034\156\050\165\045" + + "\167\027\177\025\201\051\207\041\210\043\214\024\226" + + "\044\227\023\233\026\001\002\000\004\236\u0380\001\002" + + "\000\172\004\130\006\173\010\331\014\054\024\354\025" + + "\343\030\042\032\036\033\035\037\022\042\165\043\127" + + "\050\106\051\346\052\115\054\157\061\175\067\332\070" + + "\140\074\123\100\324\107\116\110\350\114\032\116\144" + + "\121\142\123\334\126\021\132\121\133\107\134\126\135" + + "\133\136\132\140\046\142\336\144\122\147\342\153\034" + + "\156\050\157\353\162\174\164\124\165\045\167\027\171" + + "\125\172\120\177\025\201\051\207\041\210\043\211\163" + + "\212\134\214\024\217\111\220\330\226\044\227\023\233" + + "\352\235\335\241\141\001\002\000\020\012\u017c\064\372" + + "\065\361\110\u0181\137\374\142\363\150\u017f\001\uffa3\000" + + "\020\012\u017c\064\372\065\361\110\u0181\137\374\142\363" + + "\150\u017f\001\uffa4\000\004\236\u0384\001\002\000\172\004" + + "\130\006\173\010\331\014\054\024\354\025\343\030\042" + + "\032\036\033\035\037\022\042\165\043\127\050\106\051" + + "\346\052\115\054\157\061\175\067\332\070\140\074\123" + + "\100\324\107\116\110\350\114\032\116\144\121\142\123" + + "\334\126\021\132\121\133\107\134\126\135\133\136\132" + + "\140\046\142\336\144\122\147\342\153\034\156\050\157" + + "\353\162\174\164\124\165\045\167\027\171\125\172\120" + + "\177\025\201\051\207\041\210\043\211\163\212\134\214" + + "\024\217\111\220\330\226\044\227\023\233\352\235\335" + + "\241\141\001\002\000\020\012\u017c\064\372\065\361\110" + + "\u0181\137\374\142\363\150\u017f\001\uffa2\000\004\202\u0393" + + "\001\002\000\022\012\u017c\064\372\065\361\110\u0181\137" + + "\374\142\363\150\u017f\202\u0390\001\002\000\172\004\130" + + "\006\173\010\331\014\054\024\354\025\343\030\042\032" + + "\036\033\035\037\022\042\165\043\127\050\106\051\346" + + "\052\115\054\157\061\175\067\332\070\140\074\123\100" + + "\324\107\116\110\350\114\032\116\144\121\142\123\334" + + "\126\021\132\121\133\107\134\126\135\133\136\132\140" + + "\046\142\336\144\122\147\342\153\034\156\050\157\353" + + "\162\174\164\124\165\045\167\027\171\125\172\120\177" + + "\025\201\051\207\041\210\043\211\163\212\134\214\024" + + "\217\111\220\330\226\044\227\023\233\352\235\335\241" + + "\141\001\002\000\024\051\u01ed\064\372\065\361\100\u01ea" + + "\110\u01f0\111\u0160\112\u0162\137\374\142\363\001\uff6c\000" + + "\046\021\u01c6\064\372\065\361\075\366\076\367\077\370" + + "\110\u01c2\111\u0160\112\u0162\117\375\124\357\125\362\130" + + "\u01ca\137\374\142\363\145\322\152\321\205\u01cc\001\uff70" + + "\000\034\064\372\065\361\075\366\076\367\077\370\110" + + "\u01ad\111\u0160\112\u0162\117\375\124\357\125\362\132\256" + + "\152\255\001\uff6b\000\040\050\234\064\372\065\361\075" + + "\366\076\367\077\370\110\356\117\375\124\357\125\362" + + "\132\233\137\374\142\363\152\232\222\235\001\uff6e\000" + + "\020\012\u017c\064\372\065\361\110\u0181\137\374\142\363" + + "\150\u017f\001\uff6f\000\016\051\u0165\105\u015f\110\u0164\111" + + "\u0160\112\u0162\114\u0128\001\uff6a\000\042\050\203\064\372" + + "\065\361\075\366\076\367\077\370\110\356\117\375\124" + + "\357\125\362\132\201\137\374\142\363\152\200\175\202" + + "\222\204\001\uff6d\000\004\044\u0388\001\uffff\000\004\202" + + "\u0392\001\002\000\002\001\ufffd\000\172\004\130\006\173" + + "\010\331\014\054\024\354\025\343\030\042\032\036\033" + + "\035\037\022\042\165\043\127\050\106\051\346\052\115" + + "\054\157\061\175\067\332\070\140\074\123\100\324\107" + + "\116\110\350\114\032\116\144\121\142\123\334\126\021" + + "\132\121\133\107\134\126\135\133\136\132\140\046\142" + + "\336\144\122\147\342\153\034\156\050\157\353\162\174" + + "\164\124\165\045\167\027\171\125\172\120\177\025\201" + + "\051\207\041\210\043\211\163\212\134\214\024\217\111" + + "\220\330\226\044\227\023\233\352\235\335\241\141\001" + + "\002\000\022\012\u017c\064\372\065\361\110\u0181\137\374" + + "\142\363\150\u017f\202\u0395\001\002\000\002\001\ufffe\000" + + "\060\014\054\030\042\032\036\033\035\037\022\067\053" + + "\074\055\114\032\123\033\126\021\140\046\153\034\156" + + "\050\165\045\167\027\177\025\201\051\207\041\210\043" + + "\214\024\226\044\227\023\233\026\001\002\000\006\164" + + "\u04c8\171\u04c9\001\002\000\002\001\uff73\000\130\004\u012a" + + "\006\u0130\014\054\030\042\032\036\033\035\037\022\043" + + "\127\050\u012f\053\u04a9\067\053\074\123\107\116\114\032" + + "\116\144\121\142\123\u04ab\126\021\132\u0131\133\107\134" + + "\u0129\135\133\136\132\140\046\144\122\153\034\156\050" + + "\165\045\167\027\171\125\172\120\177\025\201\051\207" + + "\041\210\043\211\u012c\212\u0133\214\024\217\111\226\044" + + "\227\023\233\u04a8\241\141\001\002\000\004\033\u04a0\001" + + "\002\000\006\035\u03a4\202\u039e\001\002\000\056\006\u03ae" + + "\031\u03b4\035\u03a4\044\u0388\046\u03a2\071\u03a1\072\u0396\102" + + "\u03a7\106\u0397\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399" + + "\174\304\201\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233" + + "\u039c\244\u03af\001\002\000\062\004\130\006\131\033\035" + + "\043\127\050\106\052\115\070\140\074\212\107\116\116" + + "\144\121\142\123\207\132\121\133\107\134\126\144\122" + + "\153\034\164\124\167\065\171\125\211\113\212\134\233" + + "\206\241\141\001\002\000\002\001\ufff9\000\002\001\uff9a" + + "\000\010\035\u03a4\072\014\202\u039e\001\ufffa\000\004\067" + + "\u0478\001\002\000\006\164\u0476\171\u0477\001\002\000\032" + + "\014\054\033\035\037\022\074\066\114\032\123\067\126" + + "\021\140\063\153\034\156\050\167\065\226\044\001\002" + + "\000\002\001\ufff8\000\006\135\u046d\163\u046c\001\002\000" + + "\006\035\u03a4\202\u039e\001\002\000\172\004\130\006\173" + + "\010\331\014\054\024\354\025\343\030\042\032\036\033" + + "\035\037\022\042\165\043\127\050\106\051\346\052\115" + + "\054\157\061\175\067\332\070\140\074\123\100\324\107" + + "\116\110\350\114\032\116\144\121\142\123\334\126\021" + + "\132\121\133\107\134\126\135\133\136\132\140\046\142" + + "\336\144\122\147\342\153\034\156\050\157\353\162\174" + + "\164\124\165\045\167\027\171\125\172\120\177\025\201" + + "\051\207\041\210\043\211\163\212\134\214\024\217\111" + + "\220\330\226\044\227\023\233\352\235\335\241\141\001" + + "\002\000\006\035\u03a4\202\u039e\001\002\000\006\035\u03a4" + + "\202\u039e\001\002\000\002\001\uff97\000\006\035\u03a4\202" + + "\u039e\001\002\000\006\035\u03a4\202\u039e\001\002\000\056" + + "\006\u03ae\031\u03b4\035\u03a4\044\u0388\046\u03a2\071\u03a1\072" + + "\u0396\102\u03a7\106\u0397\115\u03ad\151\u03a5\155\u03b2\163\u0398" + + "\166\u0399\174\304\201\u039a\202\u039e\203\u03bb\204\u03a3\211" + + "\u039d\233\u039c\244\u03af\001\002\000\134\004\130\006\173" + + "\014\054\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\052\115\054\157\061\175\067\332\070\140" + + "\074\123\107\116\114\032\116\144\121\142\123\u03dc\126" + + "\021\132\121\133\107\134\126\140\046\144\122\153\034" + + "\156\050\162\174\164\124\165\045\167\027\171\125\177" + + "\025\201\051\207\041\210\043\211\163\212\134\214\024" + + "\226\044\227\023\233\u03da\241\141\001\002\000\126\004" + + "\130\006\131\012\u040f\014\054\030\042\032\036\033\035" + + "\037\022\043\127\050\106\052\115\067\053\070\140\074" + + "\123\107\116\114\032\116\144\121\142\123\312\126\021" + + "\132\121\133\107\134\126\140\046\144\122\153\034\156" + + "\050\164\124\165\045\167\027\171\125\177\025\201\051" + + "\207\041\210\043\211\113\212\134\214\024\226\044\227" + + "\023\233\310\241\141\001\002\000\006\035\u03a4\202\u039e" + + "\001\002\000\006\035\u03a4\202\u039e\001\002\000\032\014" + + "\054\033\035\037\022\074\066\114\032\123\067\126\021" + + "\140\063\153\034\156\050\167\065\226\044\001\002\000" + + "\006\035\u03a4\202\u039e\001\002\000\032\014\054\033\035" + + "\037\022\074\066\114\032\123\067\126\021\140\063\153" + + "\034\156\050\167\065\226\044\001\002\000\006\035\u03a4" + + "\202\u039e\001\002\000\006\035\u03a4\202\u039e\001\002\000" + + "\006\035\u03a4\202\u039e\001\002\000\006\035\u03a4\202\u039e" + + "\001\002\000\004\216\u0402\001\002\000\006\035\u03a4\202" + + "\u039e\001\002\000\030\033\035\066\u03d0\153\034\156\u03cf" + + "\157\u03c8\162\u03ce\164\u03cb\167\u03c5\171\u03ca\177\u03c4\200" + + "\u03c6\001\002\000\056\006\u03ae\031\u03b4\035\u03a4\044\u0388" + + "\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397\115\u03ad\151" + + "\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201\u039a\202\u039e" + + "\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af\001\001\000" + + "\002\001\uffe9\000\002\001\uff9c\000\010\035\u03a4\072\014" + + "\202\u039e\001\ufffb\000\002\001\uffd1\000\002\001\uff98\000" + + "\004\017\u03ff\001\002\000\004\017\u03fd\001\002\000\002" + + "\001\uff8d\000\004\015\075\001\uff8f\000\002\001\uff89\000" + + "\004\017\u03fb\001\002\000\002\001\uff91\000\026\033\035" + + "\153\034\156\u03cf\157\u03c8\162\u03ce\164\u03cb\167\u03c5\171" + + "\u03ca\177\u03c4\200\u03c6\001\002\000\002\001\uff95\000\002" + + "\001\uff93\000\004\017\u03f1\001\002\000\004\017\u03ef\001" + + "\002\000\002\001\uff8b\000\002\001\uff87\000\044\014\054" + + "\033\035\037\022\074\066\114\032\123\u03e7\126\021\135" + + "\133\136\132\140\063\153\034\156\050\167\065\172\120" + + "\217\111\226\044\233\u021a\001\002\000\004\017\u03e4\001" + + "\002\000\004\017\u03d6\001\002\000\004\017\u03d4\001\002" + + "\000\006\140\u0335\200\176\001\002\000\002\001\uff7e\000" + + "\134\004\130\006\173\014\054\030\042\032\036\033\035" + + "\037\022\042\165\043\127\050\106\052\115\054\157\061" + + "\175\067\332\070\140\074\123\107\116\114\032\116\144" + + "\121\142\123\u03dc\126\021\132\121\133\107\134\126\140" + + "\046\144\122\153\034\156\050\162\174\164\124\165\045" + + "\167\027\171\125\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\226\044\227\023\233\u03da\241\141" + + "\001\002\000\016\156\077\162\272\164\271\167\u01fd\171" + + "\273\177\152\001\002\000\012\050\234\132\233\152\232" + + "\222\235\001\uff7a\000\004\114\u0128\001\uff78\000\060\014" + + "\054\030\042\032\036\033\035\037\022\067\053\074\055" + + "\114\032\123\033\126\021\140\046\153\034\156\050\165" + + "\045\167\027\177\025\201\051\207\041\210\043\214\024" + + "\226\044\227\023\233\026\001\002\000\002\001\uff7d\000" + + "\142\004\130\006\173\013\071\014\054\030\042\032\036" + + "\033\035\037\022\042\264\043\127\050\106\052\277\054" + + "\157\061\175\063\u0240\067\332\070\140\074\123\107\116" + + "\114\032\116\144\121\275\123\u03dc\126\021\132\121\133" + + "\107\134\126\140\046\144\122\153\034\156\050\162\174" + + "\164\124\165\045\167\027\171\125\177\025\201\051\206" + + "\154\207\041\210\043\211\163\212\134\214\024\226\044" + + "\227\023\233\u03da\241\141\001\002\000\006\132\256\152" + + "\255\001\uff79\000\006\145\322\152\321\001\uff7c\000\014" + + "\050\203\132\201\152\200\175\202\222\204\001\uff7b\000" + + "\004\123\u03e1\001\002\000\114\004\130\006\173\030\042" + + "\033\035\042\165\043\127\050\106\052\115\054\157\061" + + "\175\067\167\070\140\074\u0275\107\116\116\144\121\142" + + "\123\u03e3\132\121\133\107\134\126\144\122\153\034\162" + + "\174\164\124\165\045\167\065\171\125\177\025\201\051" + + "\207\041\210\043\211\163\212\134\214\024\227\023\233" + + "\u03da\241\141\001\002\000\012\162\272\164\271\171\273" + + "\177\152\001\002\000\116\004\130\006\173\030\042\033" + + "\035\042\264\043\127\050\106\052\277\054\157\061\175" + + "\067\167\070\140\074\u0275\107\116\116\144\121\275\123" + + "\u03e3\132\121\133\107\134\126\144\122\153\034\162\174" + + "\164\124\165\045\167\065\171\125\177\025\201\051\206" + + "\154\207\041\210\043\211\163\212\134\214\024\227\023" + + "\233\u03da\241\141\001\002\000\172\004\130\006\173\010" + + "\331\014\054\024\354\025\343\030\042\032\036\033\035" + + "\037\022\042\165\043\127\050\106\051\346\052\115\054" + + "\157\061\175\067\332\070\140\074\123\100\324\107\116" + + "\110\350\114\032\116\144\121\142\123\334\126\021\132" + + "\121\133\107\134\126\135\133\136\132\140\046\142\336" + + "\144\122\147\342\153\034\156\050\157\353\162\174\164" + + "\124\165\045\167\027\171\125\172\120\177\025\201\051" + + "\207\041\210\043\211\163\212\134\214\024\217\111\220" + + "\330\226\044\227\023\233\352\235\335\241\141\001\002" + + "\000\014\064\372\065\361\110\u0181\137\374\142\363\001" + + "\uff80\000\020\012\u017c\064\372\065\361\110\u0181\137\374" + + "\142\363\150\u017f\001\uff83\000\036\013\071\014\054\033" + + "\035\037\022\074\066\114\032\123\067\126\021\135\u0190" + + "\140\063\153\034\156\050\167\065\226\044\001\002\000" + + "\006\156\077\172\u018f\001\002\000\004\237\u03ed\001\002" + + "\000\004\237\u03eb\001\uffde\000\036\030\042\033\035\074" + + "\u0171\123\u016f\153\034\165\045\167\065\177\025\201\051" + + "\207\041\210\043\214\024\227\023\233\026\001\002\000" + + "\004\152\321\001\uffdd\000\036\030\042\033\035\074\u0171" + + "\123\u016f\153\034\165\045\167\065\177\025\201\051\207" + + "\041\210\043\214\024\227\023\233\026\001\002\000\004" + + "\152\321\001\uffdc\000\036\030\042\033\035\074\u0171\123" + + "\u016f\153\034\165\045\167\065\177\025\201\051\207\041" + + "\210\043\214\024\227\023\233\026\001\002\000\004\152" + + "\321\001\uff81\000\060\014\054\030\042\032\036\033\035" + + "\037\022\067\053\074\055\114\032\123\033\126\021\140" + + "\046\153\034\156\050\165\045\167\027\177\025\201\051" + + "\207\041\210\043\214\024\226\044\227\023\233\026\001" + + "\002\000\002\001\uff82\000\002\001\uff8a\000\002\001\uff94" + + "\000\002\001\uff92\000\002\001\uff8e\000\002\001\uff8c\000" + + "\002\001\uff90\000\002\001\uff86\000\002\001\uff88\000\062" + + "\004\130\006\131\033\035\043\127\050\106\052\115\070" + + "\140\074\212\107\116\116\144\121\142\123\207\132\121" + + "\133\107\134\126\144\122\153\034\164\124\167\065\171" + + "\125\211\113\212\134\233\206\241\141\001\002\000\002" + + "\001\uff84\000\062\004\130\006\131\033\035\043\127\050" + + "\106\052\115\070\140\074\212\107\116\116\144\121\142" + + "\123\207\132\121\133\107\134\126\144\122\153\034\164" + + "\124\167\065\171\125\211\113\212\134\233\206\241\141" + + "\001\002\000\002\001\uff85\000\032\006\223\033\035\042" + + "\165\054\157\061\175\067\167\123\225\153\034\162\174" + + "\167\065\211\226\233\224\001\002\000\006\132\256\152" + + "\255\001\uff7f\000\002\001\uffec\000\056\006\u03ae\031\u03b4" + + "\035\u03a4\044\u0388\046\u03a2\071\u03a1\072\u0396\102\u03a7\106" + + "\u0397\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304" + + "\201\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244" + + "\u03af\001\002\000\004\035\u03a4\001\uff9f\000\002\001\ufff3" + + "\000\002\001\uffee\000\002\001\uffef\000\002\001\ufff2\000" + + "\002\001\uff49\000\002\001\ufff6\000\002\001\uff4a\000\002" + + "\001\ufff0\000\002\001\ufff7\000\014\035\u041a\050\234\132" + + "\233\152\232\222\235\001\uffe2\000\004\035\u0418\001\uffe0" + + "\000\126\004\130\006\131\012\u040f\014\054\030\042\032" + + "\036\033\035\037\022\043\127\050\106\052\115\067\053" + + "\070\140\074\123\107\116\114\032\116\144\121\142\123" + + "\312\126\021\132\121\133\107\134\126\140\046\144\122" + + "\153\034\156\050\164\124\165\045\167\027\171\125\177" + + "\025\201\051\207\041\210\043\211\113\212\134\214\024" + + "\226\044\227\023\233\310\241\141\001\002\000\002\001" + + "\uffdf\000\010\035\u0415\145\322\152\321\001\uffe3\000\016" + + "\035\u0413\050\203\132\201\152\200\175\202\222\204\001" + + "\uffe1\000\126\004\130\006\131\012\u040f\014\054\030\042" + + "\032\036\033\035\037\022\043\127\050\106\052\115\067" + + "\053\070\140\074\123\107\116\114\032\116\144\121\142" + + "\123\312\126\021\132\121\133\107\134\126\140\046\144" + + "\122\153\034\156\050\164\124\165\045\167\027\171\125" + + "\177\025\201\051\207\041\210\043\211\113\212\134\214" + + "\024\226\044\227\023\233\310\241\141\001\002\000\002" + + "\001\uffe5\000\126\004\130\006\131\012\u040f\014\054\030" + + "\042\032\036\033\035\037\022\043\127\050\106\052\115" + + "\067\053\070\140\074\123\107\116\114\032\116\144\121" + + "\142\123\312\126\021\132\121\133\107\134\126\140\046" + + "\144\122\153\034\156\050\164\124\165\045\167\027\171" + + "\125\177\025\201\051\207\041\210\043\211\113\212\134" + + "\214\024\226\044\227\023\233\310\241\141\001\002\000" + + "\002\001\uffe7\000\002\001\uffe8\000\126\004\130\006\131" + + "\012\u040f\014\054\030\042\032\036\033\035\037\022\043" + + "\127\050\106\052\115\067\053\070\140\074\123\107\116" + + "\114\032\116\144\121\142\123\312\126\021\132\121\133" + + "\107\134\126\140\046\144\122\153\034\156\050\164\124" + + "\165\045\167\027\171\125\177\025\201\051\207\041\210" + + "\043\211\113\212\134\214\024\226\044\227\023\233\310" + + "\241\141\001\002\000\002\001\uffe4\000\126\004\130\006" + + "\131\012\u040f\014\054\030\042\032\036\033\035\037\022" + + "\043\127\050\106\052\115\067\053\070\140\074\123\107" + + "\116\114\032\116\144\121\142\123\312\126\021\132\121" + + "\133\107\134\126\140\046\144\122\153\034\156\050\164" + + "\124\165\045\167\027\171\125\177\025\201\051\207\041" + + "\210\043\211\113\212\134\214\024\226\044\227\023\233" + + "\310\241\141\001\002\000\002\001\uffe6\000\006\114\u0128" + + "\224\u0451\001\002\000\006\102\u0445\224\u0444\001\002\000" + + "\010\132\256\152\255\224\u043f\001\002\000\012\102\u0433" + + "\145\322\152\321\224\u0432\001\002\000\012\043\u0423\133" + + "\u0424\224\u0421\241\u0422\001\002\000\036\014\054\033\035" + + "\037\022\074\066\114\032\123\067\126\021\140\063\153" + + "\034\156\050\164\u042d\167\065\171\u042c\226\044\001\002" + + "\000\004\224\u0429\001\002\000\004\224\u0427\001\002\000" + + "\004\224\u0425\001\002\000\004\162\u0426\001\002\000\002" + + "\001\uff14\000\004\162\u0428\001\002\000\002\001\uff13\000" + + "\004\162\u042a\001\002\000\002\001\uff15\000\004\012\u042f" + + "\001\uff57\000\002\001\uff62\000\002\001\uff61\000\002\001" + + "\uff63\000\004\224\u0430\001\002\000\036\014\054\033\035" + + "\037\022\074\066\114\032\123\067\126\021\140\063\153" + + "\034\156\050\164\u042d\167\065\171\u042c\226\044\001\002" + + "\000\002\001\uff56\000\036\014\054\033\035\037\022\074" + + "\066\114\032\123\067\126\021\140\063\153\034\156\050" + + "\164\u042d\167\065\171\u042c\226\044\001\002\000\004\142" + + "\u0434\001\002\000\004\131\u0435\001\002\000\004\224\u0436" + + "\001\002\000\032\014\054\033\035\037\022\074\066\114" + + "\032\123\067\126\021\140\063\153\034\156\050\167\065" + + "\226\044\001\002\000\004\012\u0438\001\uff52\000\004\224" + + "\u0439\001\002\000\032\014\054\033\035\037\022\074\066" + + "\114\032\123\067\126\021\140\063\153\034\156\050\167" + + "\065\226\044\001\002\000\002\001\uff51\000\004\012\u043c" + + "\001\uff5b\000\004\224\u043d\001\002\000\036\014\054\033" + + "\035\037\022\074\066\114\032\123\067\126\021\140\063" + + "\153\034\156\050\164\u042d\167\065\171\u042c\226\044\001" + + "\002\000\002\001\uff5a\000\036\014\054\033\035\037\022" + + "\074\066\114\032\123\067\126\021\140\063\153\034\156" + + "\050\164\u042d\167\065\171\u042c\226\044\001\002\000\004" + + "\012\u0441\001\uff59\000\004\224\u0442\001\002\000\036\014" + + "\054\033\035\037\022\074\066\114\032\123\067\126\021" + + "\140\063\153\034\156\050\164\u042d\167\065\171\u042c\226" + + "\044\001\002\000\002\001\uff58\000\040\014\054\033\035" + + "\034\u031b\037\022\074\066\114\032\123\067\126\021\140" + + "\063\153\034\156\050\164\u042d\167\065\171\u042c\226\044" + + "\001\002\000\004\142\u0446\001\002\000\004\131\u0447\001" + + "\002\000\004\224\u0448\001\002\000\032\014\054\033\035" + + "\037\022\074\066\114\032\123\067\126\021\140\063\153" + + "\034\156\050\167\065\226\044\001\002\000\004\012\u044a" + + "\001\uff54\000\004\224\u044b\001\002\000\032\014\054\033" + + "\035\037\022\074\066\114\032\123\067\126\021\140\063" + + "\153\034\156\050\167\065\226\044\001\002\000\002\001" + + "\uff53\000\004\012\u044e\001\uff5d\000\004\224\u044f\001\002" + + "\000\036\014\054\033\035\037\022\074\066\114\032\123" + + "\067\126\021\140\063\153\034\156\050\164\u042d\167\065" + + "\171\u042c\226\044\001\002\000\002\001\uff5c\000\032\014" + + "\054\033\035\037\022\074\066\114\032\123\067\126\021" + + "\140\063\153\034\156\050\167\065\226\044\001\002\000" + + "\002\001\uff5e\000\060\006\u03ae\031\u03b4\035\u03a4\044\u0388" + + "\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397\115\u03ad\151" + + "\u03a5\155\u03b2\161\u0454\163\u0398\166\u0399\174\304\201\u039a" + + "\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af\001" + + "\002\000\002\001\uff9e\000\002\001\ufff5\000\002\001\ufff4" + + "\000\002\001\uffed\000\002\001\uffeb\000\002\001\uff99\000" + + "\022\012\u017c\064\372\065\361\110\u0181\137\374\142\363" + + "\150\u017f\216\u045b\001\002\000\056\006\u03ae\031\u03b4\035" + + "\u03a4\044\u0388\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397" + + "\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201" + + "\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af" + + "\001\002\000\014\035\u03a4\056\u0467\062\u0468\072\014\202" + + "\u039e\001\ufffa\000\064\006\u03ae\031\u03b4\035\u03a4\044\u0388" + + "\046\u03a2\056\u0461\057\u045e\062\u0460\071\u03a1\072\u0396\102" + + "\u03a7\106\u0397\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399" + + "\174\304\201\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233" + + "\u039c\244\u03af\001\002\000\172\004\130\006\173\010\331" + + "\014\054\024\354\025\343\030\042\032\036\033\035\037" + + "\022\042\165\043\127\050\106\051\346\052\115\054\157" + + "\061\175\067\332\070\140\074\123\100\324\107\116\110" + + "\350\114\032\116\144\121\142\123\334\126\021\132\121" + + "\133\107\134\126\135\133\136\132\140\046\142\336\144" + + "\122\147\342\153\034\156\050\157\353\162\174\164\124" + + "\165\045\167\027\171\125\172\120\177\025\201\051\207" + + "\041\210\043\211\163\212\134\214\024\217\111\220\330" + + "\226\044\227\023\233\352\235\335\241\141\001\002\000" + + "\002\001\uff69\000\002\001\uff68\000\056\006\u03ae\031\u03b4" + + "\035\u03a4\044\u0388\046\u03a2\071\u03a1\072\u0396\102\u03a7\106" + + "\u0397\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304" + + "\201\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244" + + "\u03af\001\002\000\060\006\u03ae\031\u03b4\035\u03a4\044\u0388" + + "\046\u03a2\062\u0463\071\u03a1\072\u0396\102\u03a7\106\u0397\115" + + "\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201\u039a" + + "\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af\001" + + "\002\000\002\001\uff67\000\002\001\uff66\000\022\012\u017c" + + "\064\372\065\361\110\u0181\137\374\142\363\150\u017f\216" + + "\u0466\001\002\000\056\006\u03ae\031\u03b4\035\u03a4\044\u0388" + + "\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397\115\u03ad\151" + + "\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201\u039a\202\u039e" + + "\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af\001\002\000" + + "\056\006\u03ae\031\u03b4\035\u03a4\044\u0388\046\u03a2\071\u03a1" + + "\072\u0396\102\u03a7\106\u0397\115\u03ad\151\u03a5\155\u03b2\163" + + "\u0398\166\u0399\174\304\201\u039a\202\u039e\203\u03bb\204\u03a3" + + "\211\u039d\233\u039c\244\u03af\001\002\000\002\001\uffb7\000" + + "\012\035\u03a4\062\u046a\072\014\202\u039e\001\002\000\002" + + "\001\uffb6\000\002\001\ufff1\000\002\001\uff72\000\002\001" + + "\uff71\000\004\103\u046f\001\002\000\006\016\u0471\047\u0470" + + "\001\002\000\004\026\u0474\001\002\000\004\026\u0472\001" + + "\002\000\024\033\035\123\u021b\135\133\136\132\153\034" + + "\167\065\172\120\217\111\233\u021a\001\002\000\002\001" + + "\uff47\000\024\033\035\123\u021b\135\133\136\132\153\034" + + "\167\065\172\120\217\111\233\u021a\001\002\000\002\001" + + "\uff46\000\002\001\uff74\000\002\001\uff75\000\006\103\u0379" + + "\145\u0479\001\002\000\032\014\054\033\035\037\022\074" + + "\066\114\032\123\067\126\021\140\063\153\034\156\050" + + "\167\065\226\044\001\002\000\006\012\u047c\236\u047b\001" + + "\002\000\172\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\051\346\052\115\054\157\061\175\067\332" + + "\070\140\074\123\100\324\107\116\110\350\114\032\116" + + "\144\121\142\123\334\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\142\336\144\122\147\342\153" + + "\034\156\050\157\353\162\174\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\217\111\220\330\226\044\227\023" + + "\233\352\235\335\241\141\001\002\000\004\113\u047d\001" + + "\002\000\060\014\054\030\042\032\036\033\035\037\022" + + "\067\053\074\055\114\032\123\033\126\021\140\046\153" + + "\034\156\050\165\045\167\027\177\025\201\051\207\041" + + "\210\043\214\024\226\044\227\023\233\026\001\002\000" + + "\004\236\u047f\001\002\000\172\004\130\006\173\010\331" + + "\014\054\024\354\025\343\030\042\032\036\033\035\037" + + "\022\042\165\043\127\050\106\051\346\052\115\054\157" + + "\061\175\067\332\070\140\074\123\100\324\107\116\110" + + "\350\114\032\116\144\121\142\123\334\126\021\132\121" + + "\133\107\134\126\135\133\136\132\140\046\142\336\144" + + "\122\147\342\153\034\156\050\157\353\162\174\164\124" + + "\165\045\167\027\171\125\172\120\177\025\201\051\207" + + "\041\210\043\211\163\212\134\214\024\217\111\220\330" + + "\226\044\227\023\233\352\235\335\241\141\001\002\000" + + "\022\012\u017c\064\372\065\361\110\u0181\137\374\142\363" + + "\150\u017f\216\u0481\001\002\000\056\006\u03ae\031\u03b4\035" + + "\u03a4\044\u0388\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397" + + "\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201" + + "\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af" + + "\001\002\000\012\035\u03a4\060\u0483\072\014\202\u039e\001" + + "\002\000\056\006\u03ae\031\u03b4\035\u03a4\044\u0388\046\u03a2" + + "\071\u03a1\072\u0396\102\u03a7\106\u0397\115\u03ad\151\u03a5\155" + + "\u03b2\163\u0398\166\u0399\174\304\201\u039a\202\u039e\203\u03bb" + + "\204\u03a3\211\u039d\233\u039c\244\u03af\001\002\000\010\035" + + "\u03a4\072\014\202\u039e\001\uffa0\000\022\012\u017c\064\372" + + "\065\361\110\u0181\137\374\142\363\150\u017f\216\u0486\001" + + "\002\000\056\006\u03ae\031\u03b4\035\u03a4\044\u0388\046\u03a2" + + "\071\u03a1\072\u0396\102\u03a7\106\u0397\115\u03ad\151\u03a5\155" + + "\u03b2\163\u0398\166\u0399\174\304\201\u039a\202\u039e\203\u03bb" + + "\204\u03a3\211\u039d\233\u039c\244\u03af\001\002\000\012\035" + + "\u03a4\060\u0488\072\014\202\u039e\001\002\000\056\006\u03ae" + + "\031\u03b4\035\u03a4\044\u0388\046\u03a2\071\u03a1\072\u0396\102" + + "\u03a7\106\u0397\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399" + + "\174\304\201\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233" + + "\u039c\244\u03af\001\002\000\010\035\u03a4\072\014\202\u039e" + + "\001\uffa1\000\012\043\u048b\073\u048c\133\u048e\241\u048d\001" + + "\002\000\004\073\u0496\001\002\000\006\164\u0493\171\u0495" + + "\001\002\000\004\073\u0491\001\002\000\004\073\u048f\001" + + "\002\000\004\162\u0490\001\002\000\002\001\uff17\000\004" + + "\162\u0492\001\002\000\002\001\uff18\000\002\001\uff5f\000" + + "\002\001\uff55\000\002\001\uff60\000\004\162\u0497\001\002" + + "\000\002\001\uff16\000\002\001\uff9d\000\010\035\u03a4\072" + + "\014\202\u039e\001\uffd9\000\056\006\u03ae\031\u03b4\035\u049c" + + "\044\u0388\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397\115" + + "\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201\u039a" + + "\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af\001" + + "\002\000\002\001\uffdb\000\004\233\u039c\001\ufff8\000\002" + + "\001\uffda\000\002\001\uff96\000\002\001\uffea\000\004\203" + + "\u04a1\001\002\000\004\020\u04a2\001\002\000\036\030\042" + + "\033\035\074\u0171\123\u016f\153\034\165\045\167\065\177" + + "\025\201\051\207\041\210\043\214\024\227\023\233\026" + + "\001\002\000\006\017\u04a4\152\321\001\002\000\036\030" + + "\042\033\035\074\u0171\123\u016f\153\034\165\045\167\065" + + "\177\025\201\051\207\041\210\043\214\024\227\023\233" + + "\026\001\002\000\004\152\321\001\uff3c\000\014\156\077" + + "\167\u01fd\171\273\172\u018f\177\152\001\002\000\014\050" + + "\u0138\055\u04c4\132\u0137\152\u0136\222\u0139\001\002\000\060" + + "\014\054\030\042\032\036\033\035\037\022\067\053\074" + + "\055\114\032\123\033\126\021\140\046\153\034\156\050" + + "\165\045\167\027\177\025\201\051\207\041\210\043\214" + + "\024\226\044\227\023\233\026\001\002\000\060\014\054" + + "\030\042\032\036\033\035\037\022\067\053\074\055\114" + + "\032\123\033\126\021\140\046\153\034\156\050\165\045" + + "\167\027\177\025\201\051\207\041\210\043\214\024\226" + + "\044\227\023\233\026\001\002\000\004\073\u04b7\001\002" + + "\000\126\004\u012a\006\u0130\013\071\014\054\030\042\032" + + "\036\033\035\037\022\043\127\050\u012f\063\u0240\067\053" + + "\074\123\107\116\114\032\116\144\121\275\123\u04b2\126" + + "\021\132\u0131\133\107\134\u0129\135\u0190\140\046\144\122" + + "\153\034\156\050\165\045\167\027\171\125\177\025\201" + + "\051\206\154\207\041\210\043\211\u012c\212\u0133\214\024" + + "\226\044\227\023\233\u04b1\241\141\001\002\000\004\073" + + "\u04ad\001\002\000\032\014\054\033\035\037\022\074\066" + + "\114\032\123\067\126\021\140\063\153\034\156\050\167" + + "\065\226\044\001\002\000\004\013\u04af\001\002\000\002" + + "\001\uff4c\000\012\156\077\167\u01fd\171\273\177\152\001" + + "\002\000\060\014\054\030\042\032\036\033\035\037\022" + + "\067\053\074\055\114\032\123\033\126\021\140\046\153" + + "\034\156\050\165\045\167\027\177\025\201\051\207\041" + + "\210\043\214\024\226\044\227\023\233\026\001\002\000" + + "\124\004\u012a\006\u0130\013\071\014\054\030\042\032\036" + + "\033\035\037\022\043\127\050\u012f\063\u0240\067\053\074" + + "\123\107\116\114\032\116\144\121\275\123\u04b2\126\021" + + "\132\u0131\133\107\134\u0129\140\046\144\122\153\034\156" + + "\050\165\045\167\027\171\125\177\025\201\051\206\154" + + "\207\041\210\043\211\u012c\212\u0133\214\024\226\044\227" + + "\023\233\u04b1\241\141\001\002\000\004\123\u04b4\001\002" + + "\000\074\004\u012a\006\u0130\030\042\033\035\043\127\050" + + "\u012f\074\u0275\107\116\116\144\121\142\123\u04b5\132\u0131" + + "\133\107\134\u0129\144\122\153\034\165\045\167\065\171" + + "\125\177\025\201\051\207\041\210\043\211\u012c\212\u0133" + + "\214\024\227\023\233\u04b1\241\141\001\002\000\076\004" + + "\u012a\006\u0130\030\042\033\035\043\127\050\u012f\074\u0275" + + "\107\116\116\144\121\275\123\u04b5\132\u0131\133\107\134" + + "\u0129\144\122\153\034\165\045\167\065\171\125\177\025" + + "\201\051\206\154\207\041\210\043\211\u012c\212\u0133\214" + + "\024\227\023\233\u04b1\241\141\001\002\000\006\171\273" + + "\177\152\001\002\000\034\014\054\027\u04b9\033\035\037" + + "\022\074\066\114\032\123\067\126\021\140\063\153\034" + + "\156\050\167\065\226\044\001\002\000\004\013\u04ba\001" + + "\002\000\002\001\uff48\000\002\001\uff4b\000\004\073\u04bc" + + "\001\002\000\032\014\054\033\035\037\022\074\066\114" + + "\032\123\067\126\021\140\063\153\034\156\050\167\065" + + "\226\044\001\002\000\004\236\u04be\001\002\000\172\004" + + "\130\006\173\010\331\014\054\024\354\025\343\030\042" + + "\032\036\033\035\037\022\042\165\043\127\050\106\051" + + "\346\052\115\054\157\061\175\067\332\070\140\074\123" + + "\100\324\107\116\110\350\114\032\116\144\121\142\123" + + "\334\126\021\132\121\133\107\134\126\135\133\136\132" + + "\140\046\142\336\144\122\147\342\153\034\156\050\157" + + "\353\162\174\164\124\165\045\167\027\171\125\172\120" + + "\177\025\201\051\207\041\210\043\211\163\212\134\214" + + "\024\217\111\220\330\226\044\227\023\233\352\235\335" + + "\241\141\001\002\000\020\012\u017c\064\372\065\361\110" + + "\u0181\137\374\142\363\150\u017f\001\uff4d\000\004\123\u04c1" + + "\001\002\000\104\004\u012a\006\u0130\030\042\033\035\043" + + "\127\050\u012f\074\u0275\107\116\116\144\121\142\123\u04c3" + + "\132\u0131\133\107\134\u0129\135\133\136\132\144\122\153" + + "\034\165\045\167\065\171\125\172\120\177\025\201\051" + + "\207\041\210\043\211\u012c\212\u0133\214\024\217\111\227" + + "\023\233\u04a8\241\141\001\002\000\010\171\273\172\u018f" + + "\177\152\001\002\000\100\004\u012a\006\u0130\030\042\033" + + "\035\043\127\050\u012f\074\u0275\107\116\116\144\121\275" + + "\123\u04b5\132\u0131\133\107\134\u0129\135\u0190\144\122\153" + + "\034\165\045\167\065\171\125\177\025\201\051\206\154" + + "\207\041\210\043\211\u012c\212\u0133\214\024\227\023\233" + + "\u04b1\241\141\001\002\000\004\073\u04c5\001\002\000\032" + + "\014\054\033\035\037\022\074\066\114\032\123\067\126" + + "\021\140\063\153\034\156\050\167\065\226\044\001\002" + + "\000\004\013\u04c7\001\002\000\002\001\uff4e\000\002\001" + + "\uff76\000\002\001\uff77\000\006\012\u04d2\103\u04d1\001\002" + + "\000\002\001\uff9b\000\062\006\u03ae\031\u03b4\035\u03a4\044" + + "\u0388\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397\114\u0128" + + "\115\u03ad\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201" + + "\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\236\u04ce" + + "\244\u03af\001\002\000\010\035\u03a4\072\014\202\u039e\001" + + "\uffaa\000\172\004\130\006\173\010\331\014\054\024\354" + + "\025\343\030\042\032\036\033\035\037\022\042\165\043" + + "\127\050\106\051\346\052\115\054\157\061\175\067\332" + + "\070\140\074\123\100\324\107\116\110\350\114\032\116" + + "\144\121\142\123\334\126\021\132\121\133\107\134\126" + + "\135\133\136\132\140\046\142\336\144\122\147\342\153" + + "\034\156\050\157\353\162\174\164\124\165\045\167\027" + + "\171\125\172\120\177\025\201\051\207\041\210\043\211" + + "\163\212\134\214\024\217\111\220\330\226\044\227\023" + + "\233\352\235\335\241\141\001\002\000\074\006\u03ae\012" + + "\u017c\031\u03b4\035\u03a4\044\u0388\046\u03a2\064\372\065\361" + + "\071\u03a1\072\u0396\102\u03a7\106\u0397\110\u0181\115\u03ad\137" + + "\374\142\363\150\u017f\151\u03a5\155\u03b2\163\u0398\166\u0399" + + "\174\304\201\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233" + + "\u039c\244\u03af\001\002\000\010\035\u03a4\072\014\202\u039e" + + "\001\uffa7\000\032\014\054\033\035\037\022\074\066\114" + + "\032\123\067\126\021\140\063\153\034\156\050\167\065" + + "\226\044\001\002\000\004\113\u04d3\001\002\000\060\014" + + "\054\030\042\032\036\033\035\037\022\067\053\074\055" + + "\114\032\123\033\126\021\140\046\153\034\156\050\165" + + "\045\167\027\177\025\201\051\207\041\210\043\214\024" + + "\226\044\227\023\233\026\001\002\000\004\103\u04d5\001" + + "\002\000\032\014\054\033\035\037\022\074\066\114\032" + + "\123\067\126\021\140\063\153\034\156\050\167\065\226" + + "\044\001\002\000\060\006\u03ae\031\u03b4\035\u03a4\044\u0388" + + "\046\u03a2\071\u03a1\072\u0396\102\u03a7\106\u0397\115\u03ad\151" + + "\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201\u039a\202\u039e" + + "\203\u03bb\204\u03a3\211\u039d\233\u039c\236\u04d8\244\u03af\001" + + "\002\000\010\035\u03a4\072\014\202\u039e\001\uffa6\000\172" + + "\004\130\006\173\010\331\014\054\024\354\025\343\030" + + "\042\032\036\033\035\037\022\042\165\043\127\050\106" + + "\051\346\052\115\054\157\061\175\067\332\070\140\074" + + "\123\100\324\107\116\110\350\114\032\116\144\121\142" + + "\123\334\126\021\132\121\133\107\134\126\135\133\136" + + "\132\140\046\142\336\144\122\147\342\153\034\156\050" + + "\157\353\162\174\164\124\165\045\167\027\171\125\172" + + "\120\177\025\201\051\207\041\210\043\211\163\212\134" + + "\214\024\217\111\220\330\226\044\227\023\233\352\235" + + "\335\241\141\001\002\000\074\006\u03ae\012\u017c\031\u03b4" + + "\035\u03a4\044\u0388\046\u03a2\064\372\065\361\071\u03a1\072" + + "\u0396\102\u03a7\106\u0397\110\u0181\115\u03ad\137\374\142\363" + + "\150\u017f\151\u03a5\155\u03b2\163\u0398\166\u0399\174\304\201" + + "\u039a\202\u039e\203\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af" + + "\001\002\000\010\035\u03a4\072\014\202\u039e\001\uffa5\000" + + "\060\006\u03ae\031\u03b4\035\u03a4\044\u0388\046\u03a2\071\u03a1" + + "\072\u0396\102\u03a7\106\u0397\115\u03ad\151\u03a5\155\u03b2\163" + + "\u0398\166\u0399\174\304\201\u039a\202\u039e\203\u03bb\204\u03a3" + + "\211\u039d\233\u039c\236\u04dd\244\u03af\001\002\000\010\035" + + "\u03a4\072\014\202\u039e\001\uffa9\000\172\004\130\006\173" + + "\010\331\014\054\024\354\025\343\030\042\032\036\033" + + "\035\037\022\042\165\043\127\050\106\051\346\052\115" + + "\054\157\061\175\067\332\070\140\074\123\100\324\107" + + "\116\110\350\114\032\116\144\121\142\123\334\126\021" + + "\132\121\133\107\134\126\135\133\136\132\140\046\142" + + "\336\144\122\147\342\153\034\156\050\157\353\162\174" + + "\164\124\165\045\167\027\171\125\172\120\177\025\201" + + "\051\207\041\210\043\211\163\212\134\214\024\217\111" + + "\220\330\226\044\227\023\233\352\235\335\241\141\001" + + "\002\000\074\006\u03ae\012\u017c\031\u03b4\035\u03a4\044\u0388" + + "\046\u03a2\064\372\065\361\071\u03a1\072\u0396\102\u03a7\106" + + "\u0397\110\u0181\115\u03ad\137\374\142\363\150\u017f\151\u03a5" + + "\155\u03b2\163\u0398\166\u0399\174\304\201\u039a\202\u039e\203" + + "\u03bb\204\u03a3\211\u039d\233\u039c\244\u03af\001\002\000\010" + + "\035\u03a4\072\014\202\u039e\001\uffa8\000\002\001\000" }); + + /** Access to parse-action table. */ + public short[][] action_table() {return _action_table;} + + /** reduce_goto table. */ + protected static final short[][] _reduce_table = + unpackFromStrings(new String[] { + "\000\u04de\000\004\010\003\001\001\000\002\001\001\000" + + "\054\011\u03bb\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u039f" + + "\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053" + + "\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a" + + "\066\u03bc\106\u03b6\001\001\000\036\015\u0183\016\u0186\017" + + "\u0386\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b" + + "\042\344\046\u0385\102\350\103\051\104\030\001\001\000" + + "\014\034\016\035\007\061\011\062\017\063\012\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\020\020\u0358\023\027\024\055\026\u0359" + + "\102\037\103\051\104\030\001\001\000\002\001\001\000" + + "\020\020\036\023\027\024\055\026\046\102\037\103\051" + + "\104\030\001\001\000\002\001\001\000\002\001\001\000" + + "\012\026\u0331\102\063\103\051\104\030\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\020\020\u032a\023\027\024\055\026\046\102\037" + + "\103\051\104\030\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\030\015\107\016\142\020\113" + + "\021\134\023\136\024\055\026\046\102\104\103\051\104" + + "\030\105\u0328\001\001\000\020\020\u026a\023\u026b\024\055" + + "\026\u0269\102\037\103\051\104\030\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\010\023\u0312\102" + + "\u016f\103\051\001\001\000\002\001\001\000\010\023\u0309" + + "\102\u016f\103\051\001\001\000\020\020\u0306\023\027\024" + + "\055\026\046\102\037\103\051\104\030\001\001\000\010" + + "\021\u0302\102\u0218\103\051\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\020" + + "\020\u0253\023\027\024\055\026\046\102\037\103\051\104" + + "\030\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\012\026" + + "\061\102\063\103\051\104\030\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\012\026\067\102\063\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\004\103\075" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\030\015\107\016\142\020\113\021\134\023\136\024" + + "\055\026\046\102\104\103\051\104\030\105\135\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\010\023\u02f6\102\u016f\103\051\001\001" + + "\000\020\020\u02f2\023\027\024\055\026\u0125\102\037\103" + + "\051\104\030\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\024\015\u0268\016" + + "\u026c\020\u026a\023\u026b\024\055\026\u0269\102\305\103\051" + + "\104\030\001\001\000\002\001\001\000\012\015\u02f1\016" + + "\u02f0\102\207\103\051\001\001\000\012\026\u02ed\102\063" + + "\103\051\104\030\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\020\020\u02e2\023" + + "\027\024\055\026\046\102\037\103\051\104\030\001\001" + + "\000\002\001\001\000\012\015\u02df\016\u02de\102\207\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\014\023\145" + + "\026\150\102\147\103\051\104\030\001\001\000\002\001" + + "\001\000\014\023\152\026\067\102\147\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\024\015\160" + + "\016\176\022\157\024\165\025\170\026\046\102\155\103" + + "\051\104\030\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\020\020\u02ca\023" + + "\027\024\055\026\u0125\102\037\103\051\104\030\001\001" + + "\000\014\013\227\015\230\016\226\102\207\103\051\001" + + "\001\000\022\013\262\015\275\016\273\025\266\026\067" + + "\102\155\103\051\104\030\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\010\023\u02c3\102\u016f\103\051\001\001\000" + + "\014\013\u029e\015\230\016\226\102\207\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\012\015\u02bb\016\u02ba\102\207\103\051" + + "\001\001\000\012\015\u02b9\016\u02b8\102\207\103\051\001" + + "\001\000\002\001\001\000\012\015\u02b1\016\u02b0\102\207" + + "\103\051\001\001\000\012\015\210\016\204\102\207\103" + + "\051\001\001\000\002\001\001\000\020\020\u02ae\023\027" + + "\024\055\026\u0125\102\037\103\051\104\030\001\001\000" + + "\012\015\u0268\016\u026c\102\207\103\051\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\010\025" + + "\u02ad\102\221\103\051\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\010\025" + + "\220\102\221\103\051\001\001\000\002\001\001\000\002" + + "\001\001\000\014\013\u029e\015\230\016\226\102\207\103" + + "\051\001\001\000\020\020\u029b\023\027\024\055\026\046" + + "\102\037\103\051\104\030\001\001\000\016\013\262\015" + + "\230\016\226\025\266\102\265\103\051\001\001\000\014" + + "\013\227\015\230\016\226\102\207\103\051\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\012" + + "\015\244\016\243\102\207\103\051\001\001\000\012\015" + + "\242\016\241\102\207\103\051\001\001\000\012\015\240" + + "\016\237\102\207\103\051\001\001\000\012\015\236\016" + + "\235\102\207\103\051\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\010\025\253\102\221" + + "\103\051\001\001\000\002\001\001\000\010\025\257\102" + + "\221\103\051\001\001\000\010\025\256\102\221\103\051" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\016\013\262\015\275\016\273\025\266\102\265\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\016\023\u0278\024\u027a\026\046\102" + + "\147\103\051\104\030\001\001\000\002\001\001\000\004" + + "\060\302\001\001\000\002\001\001\000\002\001\001\000" + + "\026\015\306\016\314\020\310\023\313\024\055\026\046" + + "\057\312\102\305\103\051\104\030\001\001\000\002\001" + + "\001\000\002\001\001\000\020\020\u026f\023\027\024\055" + + "\026\u0125\102\037\103\051\104\030\001\001\000\002\001" + + "\001\000\024\015\u0268\016\u026c\020\u026a\023\u026b\024\055" + + "\026\u0269\102\305\103\051\104\030\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\026\015\306" + + "\016\314\020\310\023\313\024\055\026\046\057\316\102" + + "\305\103\051\104\030\001\001\000\002\001\001\000\026" + + "\015\306\016\314\020\310\023\313\024\055\026\046\057" + + "\u0266\102\305\103\051\104\030\001\001\000\034\015\336" + + "\016\354\017\343\020\324\021\340\023\325\024\055\025" + + "\332\026\346\042\344\102\350\103\051\104\030\001\001" + + "\000\020\020\322\023\027\024\055\026\046\102\037\103" + + "\051\104\030\001\001\000\002\001\001\000\020\020\u0263" + + "\023\027\024\055\026\046\102\037\103\051\104\030\001" + + "\001\000\012\002\u01ee\003\u01ed\027\u01ea\030\u01eb\001\001" + + "\000\022\002\u01cc\003\u01ca\004\u01c7\005\u01c4\006\u01c3\007" + + "\u01c2\027\u01c6\030\u01c8\001\001\000\002\001\001\000\002" + + "\001\001\000\012\026\u0260\102\063\103\051\104\030\001" + + "\001\000\020\020\u0253\023\027\024\055\026\046\102\037" + + "\103\051\104\030\001\001\000\020\002\u01b3\004\u01b1\005" + + "\u01af\006\u01ae\007\u01ad\027\u01b0\030\u01b2\001\001\000\036" + + "\013\262\015\u023a\016\u023e\017\u023c\020\u0236\021\u0184\023" + + "\u0237\024\055\025\u0239\026\u023d\042\344\102\350\103\051" + + "\104\030\001\001\000\034\015\u0183\016\u0186\017\u0234\020" + + "\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344" + + "\102\350\103\051\104\030\001\001\000\034\015\u0183\016" + + "\u0186\017\u0233\020\u0155\021\u0184\023\u0181\024\055\025\u0182" + + "\026\u015b\042\344\102\350\103\051\104\030\001\001\000" + + "\016\002\u019f\003\u019e\004\u019d\005\u019c\006\u019b\007\u019a" + + "\001\001\000\002\001\001\000\006\002\u0187\003\u0188\001" + + "\001\000\002\001\001\000\002\001\001\000\006\002\u017f" + + "\003\u017d\001\001\000\020\020\u0212\023\027\024\055\026" + + "\046\102\037\103\051\104\030\001\001\000\034\015\u0183" + + "\016\u0186\017\u0210\020\u0155\021\u0184\023\u0181\024\055\025" + + "\u0182\026\u015b\042\344\102\350\103\051\104\030\001\001" + + "\000\006\027\u0162\030\u0160\001\001\000\034\015\u0183\016" + + "\u0186\017\u01ff\020\u0155\021\u0184\023\u0181\024\055\025\u0182" + + "\026\u015b\042\344\102\350\103\051\104\030\001\001\000" + + "\002\001\001\000\020\020\u0124\023\027\024\055\026\u0125" + + "\102\037\103\051\104\030\001\001\000\002\001\001\000" + + "\002\001\001\000\016\002\375\003\372\004\370\005\364" + + "\006\363\007\357\001\001\000\002\001\001\000\002\001" + + "\001\000\012\015\u0114\016\u0113\102\207\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\012\015\u010f\016\u010e\102\207\103\051\001\001\000\012" + + "\015\u010d\016\u010c\102\207\103\051\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\012\015\u0107" + + "\016\u0106\102\207\103\051\001\001\000\002\001\001\000" + + "\012\015\u0105\016\u0104\102\207\103\051\001\001\000\002" + + "\001\001\000\002\001\001\000\012\015\377\016\376\102" + + "\207\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\014\013\u0126\015\230\016\226" + + "\102\207\103\051\001\001\000\002\001\001\000\010\015" + + "\u0131\102\u012d\103\051\001\001\000\002\001\001\000\002" + + "\001\001\000\020\020\u014b\023\027\024\055\026\u0125\102" + + "\037\103\051\104\030\001\001\000\002\001\001\000\010" + + "\015\u0146\102\u012d\103\051\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\010\015\u013f\102\u012d" + + "\103\051\001\001\000\002\001\001\000\010\015\u0133\102" + + "\u012d\103\051\001\001\000\002\001\001\000\012\026\u013d" + + "\102\063\103\051\104\030\001\001\000\010\015\u013c\102" + + "\u012d\103\051\001\001\000\010\015\u013b\102\u012d\103\051" + + "\001\001\000\010\015\u013a\102\u012d\103\051\001\001\000" + + "\010\015\u0139\102\u012d\103\051\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\014\013\u0142\015\230\016\226\102\207\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\014" + + "\013\u0145\015\230\016\226\102\207\103\051\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\014\013\u014a\015\230\016\226\102\207\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\010" + + "\015\u014d\102\u012d\103\051\001\001\000\002\001\001\000" + + "\002\001\001\000\010\015\u0150\102\u012d\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\014\013\u0153\015" + + "\230\016\226\102\207\103\051\001\001\000\002\001\001" + + "\000\034\015\u0158\016\u015c\017\u015a\020\u0155\021\u0159\023" + + "\u0156\024\055\025\u0157\026\u015b\042\344\102\350\103\051" + + "\104\030\001\001\000\012\002\u01ee\003\u01ed\027\u01ea\030" + + "\u01eb\001\001\000\022\002\u01cc\003\u01ca\004\u01c7\005\u01c4" + + "\006\u01c3\007\u01c2\027\u01c6\030\u01c8\001\001\000\020\002" + + "\u01b3\004\u01b1\005\u01af\006\u01ae\007\u01ad\027\u01b0\030\u01b2" + + "\001\001\000\016\002\u019f\003\u019e\004\u019d\005\u019c\006" + + "\u019b\007\u019a\001\001\000\006\002\u0187\003\u0188\001\001" + + "\000\006\002\u017f\003\u017d\001\001\000\006\027\u0162\030" + + "\u0160\001\001\000\016\002\375\003\372\004\370\005\364" + + "\006\363\007\357\001\001\000\002\001\001\000\022\020" + + "\u016a\023\027\024\055\026\046\031\u017a\102\037\103\051" + + "\104\030\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\022\020\u016a\023\027\024" + + "\055\026\046\031\u0169\102\037\103\051\104\030\001\001" + + "\000\010\025\u0174\102\221\103\051\001\001\000\014\013" + + "\u0173\015\230\016\226\102\207\103\051\001\001\000\002" + + "\001\001\000\002\001\001\000\010\023\u016d\102\u016f\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\010" + + "\023\152\102\u016f\103\051\001\001\000\002\001\001\000" + + "\002\001\001\000\004\060\u0172\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\022\020\u016a\023" + + "\027\024\055\026\046\031\u0176\102\037\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\034\015\u0183" + + "\016\u0186\017\u01e7\020\u0155\021\u0184\023\u0181\024\055\025" + + "\u0182\026\u015b\042\344\102\350\103\051\104\030\001\001" + + "\000\002\001\001\000\034\015\u0183\016\u0186\017\u01e6\020" + + "\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344" + + "\102\350\103\051\104\030\001\001\000\034\015\u0183\016" + + "\u0186\017\u01e5\020\u0155\021\u0184\023\u0181\024\055\025\u0182" + + "\026\u015b\042\344\102\350\103\051\104\030\001\001\000" + + "\034\015\u0183\016\u0186\017\u0185\020\u0155\021\u0184\023\u0181" + + "\024\055\025\u0182\026\u015b\042\344\102\350\103\051\104" + + "\030\001\001\000\002\001\001\000\022\002\u01cc\003\u01ca" + + "\004\u01c7\005\u01c4\006\u01c3\007\u01c2\027\u01c6\030\u01c8\001" + + "\001\000\020\002\u01b3\004\u01b1\005\u01af\006\u01ae\007\u01ad" + + "\027\u01b0\030\u01b2\001\001\000\016\002\u019f\003\u019e\004" + + "\u019d\005\u019c\006\u019b\007\u019a\001\001\000\006\002\u0187" + + "\003\u0188\001\001\000\006\002\u017f\003\u017d\001\001\000" + + "\016\002\375\003\372\004\370\005\364\006\363\007\357" + + "\001\001\000\012\021\u0199\023\u0198\102\u018c\103\051\001" + + "\001\000\012\021\u018d\023\u018a\102\u018c\103\051\001\001" + + "\000\020\020\u0192\023\027\024\055\026\046\102\037\103" + + "\051\104\030\001\001\000\002\001\001\000\010\023\152" + + "\102\u016f\103\051\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\010\023\u0191" + + "\102\u016f\103\051\001\001\000\002\001\001\000\002\001" + + "\001\000\012\021\u0195\023\u0194\102\u018c\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\012" + + "\015\u01ab\016\u01aa\102\207\103\051\001\001\000\012\015" + + "\u01a9\016\u01a8\102\207\103\051\001\001\000\012\015\u01a7" + + "\016\u01a6\102\207\103\051\001\001\000\012\015\u01a5\016" + + "\u01a4\102\207\103\051\001\001\000\012\015\u01a3\016\u01a2" + + "\102\207\103\051\001\001\000\012\015\u01a1\016\u01a0\102" + + "\207\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\010\025\u01b8\102\221\103\051" + + "\001\001\000\010\025\u01b7\102\221\103\051\001\001\000" + + "\010\025\u01b6\102\221\103\051\001\001\000\002\001\001" + + "\000\010\025\u01b5\102\221\103\051\001\001\000\002\001" + + "\001\000\010\025\u01b4\102\221\103\051\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\010\025\u01be\102\221\103\051" + + "\001\001\000\010\025\u01bd\102\221\103\051\001\001\000" + + "\010\025\u01bc\102\221\103\051\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\010\025\u01c0\102" + + "\221\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\010\023\u01dd\102\u016f\103\051\001\001\000\010\023" + + "\u01dc\102\u016f\103\051\001\001\000\010\023\u01db\102\u016f" + + "\103\051\001\001\000\010\015\u01d8\102\u012d\103\051\001" + + "\001\000\002\001\001\000\010\023\u01d7\102\u016f\103\051" + + "\001\001\000\002\001\001\000\010\023\u01d6\102\u016f\103" + + "\051\001\001\000\010\023\u01d5\102\u016f\103\051\001\001" + + "\000\010\023\u01d4\102\u016f\103\051\001\001\000\012\023" + + "\u01ce\067\u01cf\102\u016f\103\051\001\001\000\010\023\u01d3" + + "\102\u016f\103\051\001\001\000\002\001\001\000\002\001" + + "\001\000\012\023\u01d1\067\u01d2\102\u016f\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\010\023\u01da\102\u016f\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\012\026\u01e2\102\063\103\051" + + "\104\030\001\001\000\002\001\001\000\012\026\u01e4\102" + + "\063\103\051\104\030\001\001\000\002\001\001\000\006" + + "\002\u017f\003\u017d\001\001\000\006\002\u017f\003\u017d\001" + + "\001\000\006\002\u017f\003\u017d\001\001\000\002\001\001" + + "\000\010\023\u01f9\102\u016f\103\051\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\020\020\u01f5" + + "\023\027\024\055\026\046\102\037\103\051\104\030\001" + + "\001\000\020\020\u01f4\023\027\024\055\026\046\102\037" + + "\103\051\104\030\001\001\000\010\023\u01f1\102\u016f\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\020" + + "\020\u01f3\023\027\024\055\026\046\102\037\103\051\104" + + "\030\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\010\023\u01f8\102\u016f\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\034" + + "\015\u0183\016\u0186\017\u01fb\020\u0155\021\u0184\023\u0181\024" + + "\055\025\u0182\026\u015b\042\344\102\350\103\051\104\030" + + "\001\001\000\006\002\u017f\003\u017d\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\006\002\u017f" + + "\003\u017d\001\001\000\002\001\001\000\002\001\001\000" + + "\020\020\u0203\023\027\024\055\026\046\102\037\103\051" + + "\104\030\001\001\000\004\014\u0208\001\001\000\002\001" + + "\001\000\002\001\001\000\034\015\u0183\016\u0186\017\u020f" + + "\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042" + + "\344\102\350\103\051\104\030\001\001\000\002\001\001" + + "\000\020\020\u0209\023\027\024\055\026\u020a\102\037\103" + + "\051\104\030\001\001\000\002\001\001\000\002\001\001" + + "\000\034\015\u0183\016\u0186\017\u020c\020\u0155\021\u0184\023" + + "\u0181\024\055\025\u0182\026\u015b\042\344\102\350\103\051" + + "\104\030\001\001\000\006\002\u017f\003\u017d\001\001\000" + + "\034\015\u0183\016\u0186\017\u020e\020\u0155\021\u0184\023\u0181" + + "\024\055\025\u0182\026\u015b\042\344\102\350\103\051\104" + + "\030\001\001\000\006\002\u017f\003\u017d\001\001\000\006" + + "\002\u017f\003\u017d\001\001\000\006\002\u017f\003\u017d\001" + + "\001\000\002\001\001\000\004\014\u0220\001\001\000\002" + + "\001\001\000\012\026\u0215\102\063\103\051\104\030\001" + + "\001\000\002\001\001\000\010\021\u0217\102\u0218\103\051" + + "\001\001\000\002\001\001\000\002\001\001\000\020\020" + + "\u021b\023\027\024\055\026\046\102\037\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\010\021" + + "\u0195\102\u0218\103\051\001\001\000\012\026\u021e\102\063" + + "\103\051\104\030\001\001\000\002\001\001\000\034\015" + + "\u0183\016\u0186\017\u0227\020\u0155\021\u0184\023\u0181\024\055" + + "\025\u0182\026\u015b\042\344\102\350\103\051\104\030\001" + + "\001\000\020\020\u0221\023\027\024\055\026\u0222\102\037" + + "\103\051\104\030\001\001\000\002\001\001\000\002\001" + + "\001\000\034\015\u0183\016\u0186\017\u0224\020\u0155\021\u0184" + + "\023\u0181\024\055\025\u0182\026\u015b\042\344\102\350\103" + + "\051\104\030\001\001\000\006\002\u017f\003\u017d\001\001" + + "\000\034\015\u0183\016\u0186\017\u0226\020\u0155\021\u0184\023" + + "\u0181\024\055\025\u0182\026\u015b\042\344\102\350\103\051" + + "\104\030\001\001\000\006\002\u017f\003\u017d\001\001\000" + + "\006\002\u017f\003\u017d\001\001\000\002\001\001\000\002" + + "\001\001\000\004\060\u022b\001\001\000\002\001\001\000" + + "\010\015\u022d\102\u012d\103\051\001\001\000\002\001\001" + + "\000\002\001\001\000\012\026\u0230\102\063\103\051\104" + + "\030\001\001\000\002\001\001\000\034\015\u0183\016\u0186" + + "\017\u0232\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026" + + "\u015b\042\344\102\350\103\051\104\030\001\001\000\006" + + "\002\u017f\003\u017d\001\001\000\006\002\u017f\003\u017d\001" + + "\001\000\006\002\u017f\003\u017d\001\001\000\002\001\001" + + "\000\012\002\u01ee\003\u01ed\027\u01ea\030\u01eb\001\001\000" + + "\022\002\u01cc\003\u01ca\004\u01c7\005\u01c4\006\u01c3\007\u01c2" + + "\027\u01c6\030\u01c8\001\001\000\002\001\001\000\020\002" + + "\u01b3\004\u01b1\005\u01af\006\u01ae\007\u01ad\027\u01b0\030\u01b2" + + "\001\001\000\016\002\u019f\003\u019e\004\u019d\005\u019c\006" + + "\u019b\007\u019a\001\001\000\002\001\001\000\006\002\u017f" + + "\003\u017d\001\001\000\006\027\u0162\030\u0160\001\001\000" + + "\016\002\375\003\372\004\370\005\364\006\363\007\357" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\012\023\u0243\056\u0244\102\u016f\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\012\023\u0243\056\u0247\102\u016f\103\051\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\014\024" + + "\u024b\026\046\102\063\103\051\104\030\001\001\000\002" + + "\001\001\000\002\001\001\000\010\015\u024e\102\u012d\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\012\026\u0257\102\063\103\051\104\030\001\001" + + "\000\034\015\u0183\016\u0186\017\u0256\020\u0155\021\u0184\023" + + "\u0181\024\055\025\u0182\026\u015b\042\344\102\350\103\051" + + "\104\030\001\001\000\006\002\u017f\003\u017d\001\001\000" + + "\002\001\001\000\034\015\u0183\016\u0186\017\u0259\020\u0155" + + "\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344\102" + + "\350\103\051\104\030\001\001\000\006\002\u017f\003\u017d" + + "\001\001\000\002\001\001\000\002\001\001\000\010\025" + + "\u025d\102\221\103\051\001\001\000\002\001\001\000\010" + + "\025\u025f\102\221\103\051\001\001\000\002\001\001\000" + + "\002\001\001\000\034\015\u0183\016\u0186\017\u0262\020\u0155" + + "\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344\102" + + "\350\103\051\104\030\001\001\000\006\002\u017f\003\u017d" + + "\001\001\000\002\001\001\000\034\015\u0183\016\u0186\017" + + "\u0265\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b" + + "\042\344\102\350\103\051\104\030\001\001\000\006\002" + + "\u017f\003\u017d\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\026\015\306\016\314" + + "\020\310\023\313\024\055\026\046\057\u026e\102\305\103" + + "\051\104\030\001\001\000\002\001\001\000\002\001\001" + + "\000\014\015\u0272\016\u0275\023\u0194\102\u0271\103\051\001" + + "\001\000\002\001\001\000\002\001\001\000\014\015\u0268" + + "\016\u026c\023\152\102\u0271\103\051\001\001\000\002\001" + + "\001\000\002\001\001\000\026\015\306\016\314\020\310" + + "\023\313\024\055\026\046\057\u0277\102\305\103\051\104" + + "\030\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\012\023\u0243\056\u027c\102" + + "\u016f\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\024\013\u0287\015\230\016\226\023\u0285\024\u0284\026" + + "\046\102\u0282\103\051\104\030\001\001\000\002\001\001" + + "\000\004\060\u0281\001\001\000\002\001\001\000\002\001" + + "\001\000\020\015\u0268\016\u026c\023\152\026\067\102\u0282" + + "\103\051\104\030\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\012\023\u0243" + + "\056\u0289\102\u016f\103\051\001\001\000\002\001\001\000" + + "\002\001\001\000\016\023\u028f\024\u0292\026\046\102\147" + + "\103\051\104\030\001\001\000\010\023\u028d\102\u016f\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\010\015\u0294\102\u012d\103\051\001\001\000\002" + + "\001\001\000\002\001\001\000\012\023\u0243\056\u0297\102" + + "\u016f\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\010\025\u029d\102\221\103\051\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\010\025\u02ac\102\221\103\051\001\001\000\002" + + "\001\001\000\010\025\u02ab\102\221\103\051\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\012\015\u0272\016\u0275\102\207\103\051\001" + + "\001\000\002\001\001\000\002\001\001\000\010\015\u02b3" + + "\102\u012d\103\051\001\001\000\002\001\001\000\002\001" + + "\001\000\012\015\u02b7\016\u02b6\102\207\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\010\025\u02bf\102\221\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\014" + + "\013\u02c2\015\230\016\226\102\207\103\051\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\010" + + "\023\u02c6\102\u016f\103\051\001\001\000\002\001\001\000" + + "\002\001\001\000\014\013\u02c9\015\230\016\226\102\207" + + "\103\051\001\001\000\002\001\001\000\002\001\001\000" + + "\014\015\u0272\016\u0275\025\u029d\102\265\103\051\001\001" + + "\000\012\023\u0243\056\u02cd\102\u016f\103\051\001\001\000" + + "\002\001\001\000\002\001\001\000\012\026\u02d0\102\063" + + "\103\051\104\030\001\001\000\002\001\001\000\010\025" + + "\u02d2\102\221\103\051\001\001\000\002\001\001\000\010" + + "\025\u02d4\102\221\103\051\001\001\000\002\001\001\000" + + "\010\025\u02d6\102\221\103\051\001\001\000\002\001\001" + + "\000\026\015\u02d9\016\u02dd\020\u02da\021\u02db\023\u02dc\024" + + "\055\026\046\102\104\103\051\104\030\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\012\026\u02e1\102\063\103\051\104" + + "\030\001\001\000\002\001\001\000\002\001\001\000\012" + + "\015\u02e5\016\u02e4\102\207\103\051\001\001\000\002\001" + + "\001\000\002\001\001\000\010\025\u02e7\102\221\103\051" + + "\001\001\000\002\001\001\000\010\025\u02e9\102\221\103" + + "\051\001\001\000\002\001\001\000\002\001\001\000\014" + + "\013\u02ec\015\230\016\226\102\207\103\051\001\001\000" + + "\002\001\001\000\002\001\001\000\034\015\u0183\016\u0186" + + "\017\u02ef\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026" + + "\u015b\042\344\102\350\103\051\104\030\001\001\000\006" + + "\002\u017f\003\u017d\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\016\015\u0272\016\u0275\021\u0195" + + "\023\u0194\102\u02f4\103\051\001\001\000\002\001\001\000" + + "\014\015\u0268\016\u026c\023\152\102\u0271\103\051\001\001" + + "\000\002\001\001\000\010\025\u02f8\102\221\103\051\001" + + "\001\000\002\001\001\000\010\025\u02fa\102\221\103\051" + + "\001\001\000\002\001\001\000\002\001\001\000\014\013" + + "\u02fd\015\230\016\226\102\207\103\051\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\010\023" + + "\u0301\102\u016f\103\051\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\020\020\u0308\023\027\024\055" + + "\026\046\102\037\103\051\104\030\001\001\000\002\001" + + "\001\000\002\001\001\000\010\023\u030b\102\u016f\103\051" + + "\001\001\000\002\001\001\000\010\023\u030d\102\u016f\103" + + "\051\001\001\000\002\001\001\000\010\015\u030f\102\u012d" + + "\103\051\001\001\000\002\001\001\000\010\015\u0311\102" + + "\u012d\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\004\110\u0316\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\020\020\u0322\023\027\024" + + "\055\026\046\102\037\103\051\104\030\001\001\000\002" + + "\001\001\000\002\001\001\000\004\103\u0325\001\001\000" + + "\002\001\001\000\004\103\u0327\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\010\023\u0194\102\u016f\103\051\001\001\000\010\023\u032d" + + "\102\u016f\103\051\001\001\000\002\001\001\000\002\001" + + "\001\000\012\026\u0330\102\063\103\051\104\030\001\001" + + "\000\002\001\001\000\002\001\001\000\004\022\u0333\001" + + "\001\000\002\001\001\000\010\023\u02c3\102\u016f\103\051" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\020\020\u033f\023\027\024\055\026\046\102\037\103\051" + + "\104\030\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\012\026\u0343\102\063\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\034\015\u0183\016\u0186\017\u0347\020\u0155\021\u0184" + + "\023\u0181\024\055\025\u0182\026\u015b\042\344\102\350\103" + + "\051\104\030\001\001\000\006\002\u017f\003\u017d\001\001" + + "\000\002\001\001\000\002\001\001\000\010\025\u034b\102" + + "\221\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\014\013\u034f\015\230\016\226\102" + + "\207\103\051\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\010\023\u0353\102\u016f\103\051\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\014\013\u0357\015\230\016\226\102\207\103\051\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\012\026\u0367\102\063\103\051\104\030\001\001\000" + + "\020\020\u0361\023\027\024\055\026\046\102\037\103\051" + + "\104\030\001\001\000\034\015\u0183\016\u0186\017\u035d\020" + + "\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344" + + "\102\350\103\051\104\030\001\001\000\006\002\u017f\003" + + "\u017d\001\001\000\012\026\u035f\102\063\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\012\026\u0365\102\063\103\051\104\030\001\001" + + "\000\034\015\u0183\016\u0186\017\u0364\020\u0155\021\u0184\023" + + "\u0181\024\055\025\u0182\026\u015b\042\344\102\350\103\051" + + "\104\030\001\001\000\006\002\u017f\003\u017d\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\020\020\u036b\023\027\024" + + "\055\026\046\102\037\103\051\104\030\001\001\000\002" + + "\001\001\000\012\026\u036d\102\063\103\051\104\030\001" + + "\001\000\002\001\001\000\012\026\u0374\102\063\103\051" + + "\104\030\001\001\000\034\015\u0183\016\u0186\017\u0370\020" + + "\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344" + + "\102\350\103\051\104\030\001\001\000\006\002\u017f\003" + + "\u017d\001\001\000\012\026\u0372\102\063\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\012\026\u0382\102\063\103\051\104\030\001\001\000" + + "\012\026\u037a\102\063\103\051\104\030\001\001\000\002" + + "\001\001\000\034\015\u0183\016\u0186\017\u0381\020\u0155\021" + + "\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344\102\350" + + "\103\051\104\030\001\001\000\002\001\001\000\020\020" + + "\u037e\023\027\024\055\026\046\102\037\103\051\104\030" + + "\001\001\000\002\001\001\000\034\015\u0183\016\u0186\017" + + "\u0380\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b" + + "\042\344\102\350\103\051\104\030\001\001\000\006\002" + + "\u017f\003\u017d\001\001\000\006\002\u017f\003\u017d\001\001" + + "\000\002\001\001\000\034\015\u0183\016\u0186\017\u0384\020" + + "\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344" + + "\102\350\103\051\104\030\001\001\000\006\002\u017f\003" + + "\u017d\001\001\000\002\001\001\000\006\002\u017f\003\u017d" + + "\001\001\000\034\015\u038b\016\u038e\017\u038c\020\u0388\021" + + "\u0184\023\u0389\024\055\025\u038a\026\u038d\042\344\102\350" + + "\103\051\104\030\001\001\000\012\002\u01ee\003\u01ed\027" + + "\u01ea\030\u01eb\001\001\000\022\002\u01cc\003\u01ca\004\u01c7" + + "\005\u01c4\006\u01c3\007\u01c2\027\u01c6\030\u01c8\001\001\000" + + "\020\002\u01b3\004\u01b1\005\u01af\006\u01ae\007\u01ad\027\u01b0" + + "\030\u01b2\001\001\000\016\002\u019f\003\u019e\004\u019d\005" + + "\u019c\006\u019b\007\u019a\001\001\000\006\002\u017f\003\u017d" + + "\001\001\000\006\027\u0162\030\u0160\001\001\000\016\002" + + "\375\003\372\004\370\005\364\006\363\007\357\001\001" + + "\000\004\046\u0390\001\001\000\002\001\001\000\002\001" + + "\001\000\034\015\u0183\016\u0186\017\u0393\020\u0155\021\u0184" + + "\023\u0181\024\055\025\u0182\026\u015b\042\344\102\350\103" + + "\051\104\030\001\001\000\006\002\u017f\003\u017d\001\001" + + "\000\002\001\001\000\022\020\u04c9\023\027\024\055\026" + + "\u04cb\032\u04ca\102\037\103\051\104\030\001\001\000\002" + + "\001\001\000\002\001\001\000\024\015\u04a6\020\u04a9\021" + + "\u04ab\023\027\024\055\026\046\102\u04a5\103\051\104\030" + + "\001\001\000\002\001\001\000\004\066\u049e\001\001\000" + + "\056\012\u03a9\033\u03bd\035\u03b8\037\u0497\040\u039e\041\u0498" + + "\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053" + + "\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a" + + "\066\u03bc\101\u0499\106\u03b6\001\001\000\014\013\u0489\015" + + "\230\016\226\102\207\103\051\001\001\000\002\001\001" + + "\000\002\001\001\000\006\034\u03bf\066\u03c0\001\001\000" + + "\002\001\001\000\002\001\001\000\012\026\u046d\102\063" + + "\103\051\104\030\001\001\000\002\001\001\000\002\001" + + "\001\000\004\066\u046a\001\001\000\036\015\u0183\016\u0186" + + "\017\u0459\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026" + + "\u015b\036\u0458\042\344\102\350\103\051\104\030\001\001" + + "\000\004\066\u0457\001\001\000\004\066\u0456\001\001\000" + + "\002\001\001\000\004\066\u0455\001\001\000\004\066\u0454" + + "\001\001\000\054\011\u0452\012\u03a9\033\u03bd\035\u03b8\040" + + "\u039e\041\u039f\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa" + + "\050\u03b7\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064" + + "\u03a7\065\u039a\066\u03bc\106\u03b6\001\001\000\030\013\u041f" + + "\015\230\016\226\020\u041c\023\u041e\024\055\025\u041d\026" + + "\u041b\102\u03d6\103\051\104\030\001\001\000\026\015\u040c" + + "\016\u0411\020\u040d\023\u0410\024\055\026\046\102\305\103" + + "\051\104\030\107\u040f\001\001\000\004\066\u040b\001\001" + + "\000\004\066\u040a\001\001\000\012\026\u0409\102\063\103" + + "\051\104\030\001\001\000\004\066\u0408\001\001\000\012" + + "\026\u0407\102\063\103\051\104\030\001\001\000\004\066" + + "\u0406\001\001\000\004\066\u0405\001\001\000\004\066\u0404" + + "\001\001\000\004\066\u0403\001\001\000\002\001\001\000" + + "\004\066\u0400\001\001\000\026\071\u03c2\072\u03c6\073\u03d0" + + "\074\u03cb\075\u03cc\076\u03c1\077\u03d1\100\u03d2\102\u03c8\103" + + "\051\001\001\000\052\012\u03a9\033\u03bd\035\u03b8\040\u039e" + + "\041\u03be\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050" + + "\u03b7\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7" + + "\065\u039a\066\u03bc\106\u03b6\001\001\000\002\001\001\000" + + "\002\001\001\000\006\034\u03bf\066\u03c0\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\026\071\u03f3\072" + + "\u03f4\073\u03f7\074\u03f5\075\u03f6\076\u03f2\077\u03f8\100\u03f9" + + "\102\u03c8\103\051\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\014\021\u03e9\026\u03e8\102\u03e7\103" + + "\051\104\030\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\004\022\u03d4\001\001\000\002\001" + + "\001\000\026\015\u03d7\016\u03de\020\u03da\023\u03dd\024\055" + + "\025\u03dc\026\u03d8\102\u03d6\103\051\104\030\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\020" + + "\020\u03df\023\027\024\055\026\u0125\102\037\103\051\104" + + "\030\001\001\000\002\001\001\000\030\013\262\015\275" + + "\016\273\020\u026a\023\u026b\024\055\025\266\026\u0269\102" + + "\u03d6\103\051\104\030\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\016\015" + + "\u0272\016\u0275\023\u0194\025\u029d\102\u03e1\103\051\001\001" + + "\000\002\001\001\000\020\013\262\015\275\016\273\023" + + "\152\025\266\102\u03e1\103\051\001\001\000\034\015\u0183" + + "\016\u0186\017\u03e5\020\u0155\021\u03e4\023\u0181\024\055\025" + + "\u0182\026\u015b\042\344\102\350\103\051\104\030\001\001" + + "\000\006\002\u0187\003\u0188\001\001\000\006\002\u017f\003" + + "\u017d\001\001\000\012\026\067\102\063\103\051\104\030" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\010\023\u03eb\102\u016f\103\051\001\001\000\002" + + "\001\001\000\010\023\u03ed\102\u016f\103\051\001\001\000" + + "\002\001\001\000\010\023\u03ef\102\u016f\103\051\001\001" + + "\000\002\001\001\000\020\020\u03f1\023\027\024\055\026" + + "\046\102\037\103\051\104\030\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\014\013\u03fb\015\230\016" + + "\226\102\207\103\051\001\001\000\002\001\001\000\014" + + "\013\u03fd\015\230\016\226\102\207\103\051\001\001\000" + + "\002\001\001\000\010\025\u03ff\102\221\103\051\001\001" + + "\000\002\001\001\000\002\001\001\000\052\012\u03a9\033" + + "\u03bd\035\u03b8\040\u039e\041\u0402\043\u03af\044\u03a5\045\u03b2" + + "\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055\u03b5\060" + + "\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106\u03b6\001\001" + + "\000\006\034\u03bf\066\u03c0\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\026\015\u040c\016\u0411\020\u040d\023\u0410\024\055\026" + + "\046\102\305\103\051\104\030\107\u0416\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\026\015" + + "\u040c\016\u0411\020\u040d\023\u0410\024\055\026\046\102\305" + + "\103\051\104\030\107\u0413\001\001\000\002\001\001\000" + + "\026\015\u040c\016\u0411\020\u040d\023\u0410\024\055\026\046" + + "\102\305\103\051\104\030\107\u0415\001\001\000\002\001" + + "\001\000\002\001\001\000\026\015\u040c\016\u0411\020\u040d" + + "\023\u0410\024\055\026\046\102\305\103\051\104\030\107" + + "\u0418\001\001\000\002\001\001\000\026\015\u040c\016\u0411" + + "\020\u040d\023\u0410\024\055\026\046\102\305\103\051\104" + + "\030\107\u041a\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\014\026\u042d\051\u042a\102\063\103\051" + + "\104\030\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\014\026\u042d\051" + + "\u0430\102\063\103\051\104\030\001\001\000\002\001\001" + + "\000\014\026\u042d\051\u043a\102\063\103\051\104\030\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\012\026\u0436\102\063\103\051\104\030\001\001\000" + + "\002\001\001\000\002\001\001\000\012\026\u0439\102\063" + + "\103\051\104\030\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\014\026\u042d\051\u043d\102\063" + + "\103\051\104\030\001\001\000\002\001\001\000\014\026" + + "\u042d\051\u043f\102\063\103\051\104\030\001\001\000\002" + + "\001\001\000\002\001\001\000\014\026\u042d\051\u0442\102" + + "\063\103\051\104\030\001\001\000\002\001\001\000\014" + + "\026\u042d\051\u044c\102\063\103\051\104\030\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\012" + + "\026\u0448\102\063\103\051\104\030\001\001\000\002\001" + + "\001\000\002\001\001\000\012\026\u044b\102\063\103\051" + + "\104\030\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\014\026\u042d\051\u044f\102\063\103\051" + + "\104\030\001\001\000\002\001\001\000\012\026\u0451\102" + + "\063\103\051\104\030\001\001\000\002\001\001\000\052" + + "\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u03be\043\u03af\044" + + "\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0" + + "\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106" + + "\u03b6\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\006\002\u017f\003\u017d\001\001\000\054\011\u045c" + + "\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u045b\043\u03af\044" + + "\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0" + + "\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106" + + "\u03b6\001\001\000\006\034\u03bf\066\u03c0\001\001\000\054" + + "\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u03be\043\u03af\044" + + "\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0" + + "\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\070" + + "\u045e\106\u03b6\001\001\000\036\015\u0183\016\u0186\017\u0464" + + "\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026\u015b\036" + + "\u0463\042\344\102\350\103\051\104\030\001\001\000\002" + + "\001\001\000\002\001\001\000\054\011\u0461\012\u03a9\033" + + "\u03bd\035\u03b8\040\u039e\041\u039f\043\u03af\044\u03a5\045\u03b2" + + "\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055\u03b5\060" + + "\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106\u03b6\001\001" + + "\000\052\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u03be\043" + + "\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4" + + "\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066" + + "\u03bc\106\u03b6\001\001\000\002\001\001\000\002\001\001" + + "\000\006\002\u017f\003\u017d\001\001\000\054\011\u045c\012" + + "\u03a9\033\u03bd\035\u03b8\040\u039e\041\u039f\043\u03af\044\u03a5" + + "\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055" + + "\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106\u03b6" + + "\001\001\000\052\012\u03a9\033\u03bd\035\u03b8\040\u039e\041" + + "\u0468\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7" + + "\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065" + + "\u039a\066\u03bc\106\u03b6\001\001\000\002\001\001\000\006" + + "\034\u03bf\066\u03c0\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\010\021\u0472\102\u0218\103\051\001\001\000\002\001\001" + + "\000\010\021\u0474\102\u0218\103\051\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\012\026\u0479\102\063\103\051\104\030\001\001\000" + + "\002\001\001\000\034\015\u0183\016\u0186\017\u0484\020\u0155" + + "\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344\102" + + "\350\103\051\104\030\001\001\000\002\001\001\000\020" + + "\020\u047d\023\027\024\055\026\046\102\037\103\051\104" + + "\030\001\001\000\002\001\001\000\034\015\u0183\016\u0186" + + "\017\u047f\020\u0155\021\u0184\023\u0181\024\055\025\u0182\026" + + "\u015b\042\344\102\350\103\051\104\030\001\001\000\006" + + "\002\u017f\003\u017d\001\001\000\052\012\u03a9\033\u03bd\035" + + "\u03b8\040\u039e\041\u0481\043\u03af\044\u03a5\045\u03b2\046\u03ab" + + "\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061" + + "\u03b9\064\u03a7\065\u039a\066\u03bc\106\u03b6\001\001\000\006" + + "\034\u03bf\066\u03c0\001\001\000\052\012\u03a9\033\u03bd\035" + + "\u03b8\040\u039e\041\u0483\043\u03af\044\u03a5\045\u03b2\046\u03ab" + + "\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061" + + "\u03b9\064\u03a7\065\u039a\066\u03bc\106\u03b6\001\001\000\006" + + "\034\u03bf\066\u03c0\001\001\000\006\002\u017f\003\u017d\001" + + "\001\000\052\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u0486" + + "\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053" + + "\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a" + + "\066\u03bc\106\u03b6\001\001\000\006\034\u03bf\066\u03c0\001" + + "\001\000\052\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u0488" + + "\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053" + + "\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a" + + "\066\u03bc\106\u03b6\001\001\000\006\034\u03bf\066\u03c0\001" + + "\001\000\002\001\001\000\002\001\001\000\004\052\u0493" + + "\001\001\000\002\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\002\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\004\066\u049d\001\001" + + "\000\006\034\u03bf\066\u03c0\001\001\000\056\012\u03a9\033" + + "\u03bd\035\u03b8\037\u049a\040\u039e\041\u0498\043\u03af\044\u03a5" + + "\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055" + + "\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\101\u0499" + + "\106\u03b6\001\001\000\002\001\001\000\056\012\u03a9\033" + + "\u03bd\035\u03b8\037\u049c\040\u039e\041\u0498\043\u03af\044\u03a5" + + "\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055" + + "\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\101\u0499" + + "\106\u03b6\001\001\000\002\001\001\000\002\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\010" + + "\023\u04a2\102\u016f\103\051\001\001\000\002\001\001\000" + + "\010\023\u04a4\102\u016f\103\051\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\020\020\u04bf\023" + + "\027\024\055\026\u0125\102\037\103\051\104\030\001\001" + + "\000\020\020\u04ba\023\027\024\055\026\046\102\037\103" + + "\051\104\030\001\001\000\002\001\001\000\022\015\u0146" + + "\020\u026a\023\u026b\024\055\026\u0269\102\u04af\103\051\104" + + "\030\001\001\000\002\001\001\000\012\026\u04ad\102\063" + + "\103\051\104\030\001\001\000\002\001\001\000\002\001" + + "\001\000\002\001\001\000\020\020\u04b2\023\027\024\055" + + "\026\u0125\102\037\103\051\104\030\001\001\000\022\015" + + "\u0146\020\u026a\023\u026b\024\055\026\u0269\102\u04af\103\051" + + "\104\030\001\001\000\002\001\001\000\012\015\u014d\023" + + "\u0194\102\u04b5\103\051\001\001\000\012\015\u0146\023\152" + + "\102\u04b5\103\051\001\001\000\002\001\001\000\012\026" + + "\u04b7\102\063\103\051\104\030\001\001\000\002\001\001" + + "\000\002\001\001\000\002\001\001\000\002\001\001\000" + + "\012\026\u04bc\102\063\103\051\104\030\001\001\000\002" + + "\001\001\000\034\015\u0183\016\u0186\017\u04be\020\u0155\021" + + "\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344\102\350" + + "\103\051\104\030\001\001\000\006\002\u017f\003\u017d\001" + + "\001\000\002\001\001\000\014\015\u014d\021\u0195\023\u0194" + + "\102\u04c1\103\051\001\001\000\002\001\001\000\012\015" + + "\u0146\023\152\102\u04b5\103\051\001\001\000\002\001\001" + + "\000\012\026\u04c5\102\063\103\051\104\030\001\001\000" + + "\002\001\001\000\002\001\001\000\002\001\001\000\002" + + "\001\001\000\002\001\001\000\002\001\001\000\052\012" + + "\u03a9\033\u03bd\035\u03b8\040\u039e\041\u04cc\043\u03af\044\u03a5" + + "\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055" + + "\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106\u03b6" + + "\001\001\000\006\034\u03bf\066\u03c0\001\001\000\034\015" + + "\u0183\016\u0186\017\u04ce\020\u0155\021\u0184\023\u0181\024\055" + + "\025\u0182\026\u015b\042\344\102\350\103\051\104\030\001" + + "\001\000\056\002\u017f\003\u017d\012\u03a9\033\u03bd\035\u03b8" + + "\040\u039e\041\u04cf\043\u03af\044\u03a5\045\u03b2\046\u03ab\047" + + "\u03aa\050\u03b7\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9" + + "\064\u03a7\065\u039a\066\u03bc\106\u03b6\001\001\000\006\034" + + "\u03bf\066\u03c0\001\001\000\012\026\u04da\102\063\103\051" + + "\104\030\001\001\000\002\001\001\000\020\020\u04d3\023" + + "\027\024\055\026\046\102\037\103\051\104\030\001\001" + + "\000\002\001\001\000\012\026\u04d5\102\063\103\051\104" + + "\030\001\001\000\052\012\u03a9\033\u03bd\035\u03b8\040\u039e" + + "\041\u04d6\043\u03af\044\u03a5\045\u03b2\046\u03ab\047\u03aa\050" + + "\u03b7\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061\u03b9\064\u03a7" + + "\065\u039a\066\u03bc\106\u03b6\001\001\000\006\034\u03bf\066" + + "\u03c0\001\001\000\034\015\u0183\016\u0186\017\u04d8\020\u0155" + + "\021\u0184\023\u0181\024\055\025\u0182\026\u015b\042\344\102" + + "\350\103\051\104\030\001\001\000\056\002\u017f\003\u017d" + + "\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u04d9\043\u03af\044" + + "\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0" + + "\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106" + + "\u03b6\001\001\000\006\034\u03bf\066\u03c0\001\001\000\052" + + "\012\u03a9\033\u03bd\035\u03b8\040\u039e\041\u04db\043\u03af\044" + + "\u03a5\045\u03b2\046\u03ab\047\u03aa\050\u03b7\053\u03b4\054\u03b0" + + "\055\u03b5\060\u03a8\061\u03b9\064\u03a7\065\u039a\066\u03bc\106" + + "\u03b6\001\001\000\006\034\u03bf\066\u03c0\001\001\000\034" + + "\015\u0183\016\u0186\017\u04dd\020\u0155\021\u0184\023\u0181\024" + + "\055\025\u0182\026\u015b\042\344\102\350\103\051\104\030" + + "\001\001\000\056\002\u017f\003\u017d\012\u03a9\033\u03bd\035" + + "\u03b8\040\u039e\041\u04de\043\u03af\044\u03a5\045\u03b2\046\u03ab" + + "\047\u03aa\050\u03b7\053\u03b4\054\u03b0\055\u03b5\060\u03a8\061" + + "\u03b9\064\u03a7\065\u039a\066\u03bc\106\u03b6\001\001\000\006" + + "\034\u03bf\066\u03c0\001\001\000\002\001\001" }); + + /** Access to reduce_goto table. */ + public short[][] reduce_table() {return _reduce_table;} + + /** Instance of action encapsulation class. */ + protected CUP$DTRulesParser$actions action_obj; + + /** Action encapsulation object initializer. */ + protected void init_actions() + { + action_obj = new CUP$DTRulesParser$actions(this); + } + + /** Invoke a user supplied parse action. */ + public java_cup.runtime.Symbol do_action( + int act_num, + java_cup.runtime.lr_parser parser, + java.util.Stack stack, + int top) + throws java.lang.Exception + { + /* call code in generated class */ + return action_obj.CUP$DTRulesParser$do_action(act_num, parser, stack, top); + } + + /** Indicates start state. */ + public int start_state() {return 0;} + /** Indicates start production. */ + public int start_production() {return 1;} + + /** EOF Symbol index. */ + public int EOF_sym() {return 0;} + + /** error Symbol index. */ + public int error_sym() {return 1;} + + + + + public int localCnt = 0; + + public HashMap localtypes = new HashMap(); + + public void report_error(String message, Object info){} + + public final int + iBoolean = 0, + iString = 1, + iInteger = 2, + iDouble = 3, + iEntity = 4, + iName = 5, + iArray = 6, + iDecisiontable = 7, + iNull = 8, + iMark = 9, + iOperator = 10, + iTime = 11, + iTable = 12, + iXmlValue = 13; + /** + * Adds a symbol to the local variable hash, and + * returns allocation code for the local variable. + **/ + public String newLocal(String v, int type, String initialValue){ + v = v.toLowerCase(); + RLocalType t = new RLocalType(); + t.name = v; + t.index = localCnt++; + t.type = type; + localtypes.put(v,t); + if(initialValue != null){ + return initialValue + "allocate execute deallocate pop "; + }else{ + return "null allocate execute "; + } + } + + +} + +/** Cup generated class to encapsulate user supplied action code.*/ +class CUP$DTRulesParser$actions { + + + + public String left (java.util.Stack stack) { + return ((RSymbol)stack.peek()).leftvalue; + } + + public void notlocal(java.util.Stack stack){ + Symbol v = (Symbol) stack.peek(); + if(v instanceof RSymbol && ((RSymbol)v).local){ + throw new RuntimeException("The Local Variable "+((RSymbol)v).rightvalue+" is being referenced improperly"); + } + } + /** + * Provides the original text for the right side. + **/ + public String rv(java.util.Stack stack){ + return ((RSymbol)stack.peek()).rightvalue; + } + + private final DTRulesParser parser; + + /** Constructor */ + CUP$DTRulesParser$actions(DTRulesParser parser) { + this.parser = parser; + } + + /** Method with the actual generated action code. */ + public final java_cup.runtime.Symbol CUP$DTRulesParser$do_action( + int CUP$DTRulesParser$act_num, + java_cup.runtime.lr_parser CUP$DTRulesParser$parser, + java.util.Stack CUP$DTRulesParser$stack, + int CUP$DTRulesParser$top) + throws java.lang.Exception + { + /* Symbol object for return from actions */ + java_cup.runtime.Symbol CUP$DTRulesParser$result; + + /* select the action based on the action number */ + switch (CUP$DTRulesParser$act_num) + { + /*. . . . . . . . . . . . . . . . . . . .*/ + case 491: // isnotnull ::= IS NOT NULL + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("isnotnull",22, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 490: // isnotnull ::= ISNOTNULL + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("isnotnull",22, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 489: // isnull ::= IS NULL + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("isnull",21, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 488: // isnull ::= ISNULL + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("isnull",21, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 487: // lte ::= LESS THAN OR EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("lte",5, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 486: // lte ::= IS LESS THAN OR EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("lte",5, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 485: // lte ::= LTE + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("lte",5, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 484: // lt ::= LESS THAN + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("lt",4, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 483: // lt ::= IS LESS THAN + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("lt",4, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 482: // lt ::= LT + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("lt",4, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 481: // gte ::= GREATER THAN OR EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("gte",3, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 480: // gte ::= IS GREATER THAN OR EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("gte",3, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 479: // gte ::= GTE + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("gte",3, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 478: // gt ::= GREATER THAN + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("gt",2, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 477: // gt ::= IS GREATER THAN + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("gt",2, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 476: // gt ::= GT + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("gt",2, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 475: // neq ::= NOT EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("neq",1, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 474: // neq ::= IS NOT EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("neq",1, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 473: // neq ::= NEQ + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("neq",1, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 472: // eq ::= EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eq",0, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 471: // eq ::= IS EQUAL TO + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eq",0, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 470: // eq ::= EQ + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eq",0, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 469: // bexpr ::= BOOL_FUNCTION + { + String RESULT =null; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = b+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 468: // bexpr ::= BOOLEAN VALUE OF operatorstatements + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 467: // bexpr ::= eexpr neq eexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"req not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 466: // bexpr ::= eexpr eq eexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"req "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 465: // bexpr ::= dexpr IS BETWEEN dexpr AND dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d3 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d2+d1+"d> not "+d1+d3+" d> not and "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 464: // bexpr ::= dexpr lte dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"d> not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 463: // bexpr ::= dexpr gte dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"d< not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 462: // bexpr ::= dexpr IS AFTER dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"d> "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 461: // bexpr ::= dexpr gt dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"d> "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 460: // bexpr ::= dexpr IS BEFORE dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"d< "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 459: // bexpr ::= dexpr lt dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"d< "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 458: // bexpr ::= dexpr eq dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"d== "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 457: // bexpr ::= BOOLEAN RARRAY LBRACE iexpr RBRACE + { + String RESULT =null; + String ra = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String ie1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ra+" "+ie1+"getat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 456: // bexpr ::= LPAREN BOOLEAN RPAREN indx_expr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 455: // bexpr ::= LPAREN bexpr RPAREN + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 454: // bexpr ::= USING eexpr LPAREN bexpr RPAREN + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 453: // bexpr ::= eexpr isnotnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 452: // bexpr ::= strexpr isnotnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 451: // bexpr ::= array_expr isnotnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 450: // bexpr ::= dexpr isnotnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 449: // bexpr ::= eexpr isnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 448: // bexpr ::= strexpr isnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 447: // bexpr ::= array_expr isnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 446: // bexpr ::= dexpr isnull + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+" isnull "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 445: // bexpr ::= NOT bexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 444: // bexpr ::= bexpr OR bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+"{ pop "+e2+"} over not if\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 443: // bexpr ::= bexpr AND bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+"{ pop "+e2+"} over if\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 442: // bexpr ::= bexpr neq bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"beq "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 441: // bexpr ::= bexpr eq bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"beq "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 440: // bexpr ::= strexpr MATCHES strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+s1+"regexmatch "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 439: // bexpr ::= strexpr lte strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"s<= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 438: // bexpr ::= strexpr gte strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"s>= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 437: // bexpr ::= strexpr lt strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"s< "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 436: // bexpr ::= strexpr gt strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"s> "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 435: // bexpr ::= WAS bexpr QUESTIONMARK + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 434: // bexpr ::= IS bexpr QUESTIONMARK + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 433: // bexpr ::= DOES bexpr QUESTIONMARK + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 432: // bexpr ::= strexpr IS NOT ONE OF array_expr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+s1+"memberof not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 431: // bexpr ::= strexpr IS ONE OF array_expr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+s1+"memberof "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 430: // bexpr ::= strexpr STARTS_WITH strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "0 "+s1+s2+"startswith "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 429: // bexpr ::= strexpr AT iexpr STARTS_WITH strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+s1+s2+"startswith "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 428: // bexpr ::= strexpr neq strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"streq not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 427: // bexpr ::= strexpr eq strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"streq "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 426: // bexpr ::= strexpr eq blist + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String bl = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+bl+"swap drop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 425: // bexpr ::= nexpr neq strexpr + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+s+"streq not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 424: // bexpr ::= nexpr neq nexpr + { + String RESULT =null; + String n1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String n2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n1+n2+"nameeq not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 423: // bexpr ::= nexpr eq strexpr + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+s+"streq "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 422: // bexpr ::= nexpr eq nexpr + { + String RESULT =null; + String n1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String n2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n1+n2+"nameeq "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 421: // bexpr ::= colonRef RBOOLEAN + { + String RESULT =null; + String re = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = re+ "entitypush "+b+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 420: // bexpr ::= RBOOLEAN + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 419: // bexpr ::= fexpr lte fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f<= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 418: // bexpr ::= iexpr lte fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f<= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 417: // bexpr ::= fexpr lte iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f<= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 416: // bexpr ::= iexpr lte iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"<= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 415: // bexpr ::= fexpr lt fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f< "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 414: // bexpr ::= iexpr lt fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f< "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 413: // bexpr ::= fexpr lt iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f< "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 412: // bexpr ::= iexpr lt iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"< "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 411: // bexpr ::= fexpr gte fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f>= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 410: // bexpr ::= iexpr gte fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f>= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 409: // bexpr ::= fexpr gte iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f>= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 408: // bexpr ::= iexpr gte iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+">= "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 407: // bexpr ::= fexpr gt fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f> "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 406: // bexpr ::= iexpr gt fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f> "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 405: // bexpr ::= fexpr gt iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f> "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 404: // bexpr ::= iexpr gt iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"> "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 403: // bexpr ::= fexpr neq fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f== not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 402: // bexpr ::= iexpr neq fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f== not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 401: // bexpr ::= fexpr neq iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f== not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 400: // bexpr ::= iexpr neq iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"== not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 399: // bexpr ::= fexpr eq fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f== "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 398: // bexpr ::= iexpr eq fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f== "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 397: // bexpr ::= fexpr eq iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"f== "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 396: // bexpr ::= iexpr eq iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"== "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 395: // bexpr ::= eexpr IS strexpr OF eexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s + "{ pop true } { pop false } "+ + "{ dup type streq source "+e1+" req and target "+e2+" req and } "+ + " relationships forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 394: // bexpr ::= eexpr HASA strexpr WHERE bexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s + e +"{ pop pop true } { pop pop false } "+ + "{ over type streq over target req and "+ + "source entitypush "+b+"entitypop and } relationships forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 393: // bexpr ::= eexpr HASA strexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s + e +"{ pop pop true } { pop pop false } "+ + "{ over type streq over target req and } relationships forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 392: // bexpr ::= eexpr DOES NOT HAVE strexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s + e +"{ pop pop false } { pop pop true } "+ + "{ over type streq over target req and } relationships forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 391: // bexpr ::= ONE OF array_expr HASA bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ true } { false } { " + b +"} "+a+"forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 390: // bexpr ::= ALL array_expr HAVE bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ false } { true } { " + b +"not } "+a+"forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 389: // bexpr ::= THERE IS NO eexpr inthe array_expr WHERE bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ false } { true } { " + b +"} "+a+"forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 388: // bexpr ::= THERE IS NO eexpr inthe eexpr WHERE bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ false } { true } { " + b +"} "+e1.trim()+"s "+e2+"entitypush forfirstelse entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 387: // bexpr ::= THERE IS NO eexpr WHERE bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ false } { true } { " + b +"} "+e1.trim()+"s forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 386: // bexpr ::= HASA eexpr WHERE bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ true } { false } { " + b +"} "+e1.trim()+"s forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 385: // bexpr ::= thereis eexpr inthe array_expr WHERE bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ true } { false } { " + b +"} "+a+ " forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 384: // bexpr ::= thereis eexpr inthe eexpr WHERE bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ true } { false } { " + b +"} "+e1.trim()+"s "+e2+"entitypush forfirstelse entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 383: // bexpr ::= thereis eexpr WHERE bexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ true } { false } { " + b +"} "+e1.trim()+"s forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 382: // bexpr ::= thereis MATCH FORALL array_expr TO nexpr IN array_expr + { + String RESULT =null; + String a1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "true { { { pop true } { pop false } { dup "+n+"execute streq } "+a2+"forfirstelse } { pop false } swap ifelse } "+a1+"for "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 381: // bexpr ::= array_expr INCLUDES includeSearch + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+e+"memberof "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 380: // bexpr ::= array_expr DOES INCLUDE includeSearch + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+e+"memberof "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 379: // bexpr ::= array_expr DOES NOT INCLUDE includeSearch + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+e+"memberof not "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("bexpr",13, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 378: // blist ::= OR strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "dup "+s+"streq "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("blist",53, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 377: // blist ::= strexpr COMMA blist + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String bl = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "dup "+s+"streq { pop "+bl+"} over not if "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("blist",53, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 376: // thereis ::= IS THERE + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("thereis",32, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 375: // thereis ::= THERE IS + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("thereis",32, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 374: // inthe ::= ON + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("inthe",10, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 373: // inthe ::= FOR + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("inthe",10, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 372: // inthe ::= IN + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("inthe",10, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 371: // includeSearch ::= STRING strexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("includeSearch",23, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 370: // includeSearch ::= eexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("includeSearch",23, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 369: // includeSearch ::= DATE dexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("includeSearch",23, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 368: // includeSearch ::= VALUE number + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("includeSearch",23, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 367: // iexpr ::= SUM_OF iexpr IN array_expr + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "0 { "+i+"ladd } "+a+"forall "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 366: // iexpr ::= LONG VALUE OF operatorstatements + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 365: // iexpr ::= GET YEAROF dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+"yearof "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 364: // iexpr ::= YEARS FROM dexpr TO dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d2+d1+"yearsbetween "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 363: // iexpr ::= MONTHS FROM dexpr TO dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"monthsbetween "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 362: // iexpr ::= DAYS FROM dexpr TO dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1+d2+"daysbetween "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 361: // iexpr ::= USING eexpr LPAREN iexpr RPAREN + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 360: // iexpr ::= ABSOLUTEVALUE OF iexpr + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+"labs "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 359: // iexpr ::= DIVIDE RLONG BY number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+v+n+" ldiv def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 358: // iexpr ::= MULTIPLY RLONG BY number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+v+n+" lmul def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 357: // iexpr ::= SUBTRACT FROM RLONG number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+v+n+" lsub def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 356: // iexpr ::= ADD TO RLONG number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+v+n+" ladd def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 355: // iexpr ::= USING array_expr number + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ee+"entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 354: // iexpr ::= LENGTH OF strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"strlength "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 353: // iexpr ::= LENGTH OF array_expr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+"length "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 352: // iexpr ::= NUMBEROF array_expr WHERE bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "0 { { 1 ladd } "+b+"if }"+a+"forall "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 351: // iexpr ::= NUMBEROF array_expr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+"length "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 350: // iexpr ::= LPAREN LONG RPAREN RTABLE LPAREN tablelist RPAREN + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String keys = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = t + " " + keys + "lookup "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 349: // iexpr ::= LPAREN LONG RPAREN number + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie + "cvi "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 348: // iexpr ::= LPAREN LONG RPAREN strexpr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie + "cvi "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 347: // iexpr ::= LPAREN LONG RPAREN indx_expr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie + "cvi "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 346: // iexpr ::= colonRef RLONG + { + String RESULT =null; + String re = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = re+ "entitypush "+n+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 345: // iexpr ::= GET DAYS OF MONTHS FOR dexpr + { + String RESULT =null; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d + "getdayofmonth "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 344: // iexpr ::= GET DAYS IN MONTHS FOR dexpr + { + String RESULT =null; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d + "getdaysinmonth "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 343: // iexpr ::= GET DAYS IN YEAROF dexpr + { + String RESULT =null; + String de = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = de + "getdaysinyear "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 342: // iexpr ::= RLONG + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 341: // iexpr ::= LPAREN iexpr RPAREN + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 340: // iexpr ::= MINUS iexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"negate "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 339: // iexpr ::= INTEGER + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 338: // iexpr ::= iexpr DIVIDE iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"div "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 337: // iexpr ::= iexpr TIMES iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"* "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 336: // iexpr ::= iexpr MINUS iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"- "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 335: // iexpr ::= iexpr PLUS iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"+ "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("iexpr",11, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 334: // fexpr ::= SUM_OF fexpr IN array_expr + { + String RESULT =null; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "0 { "+f+"ladd } "+a+"forall "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 333: // fexpr ::= fexpr ROUNDED TO iexpr DECIMAL_PLACES WITH_BOUNDRY fexpr + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-6)).value; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+i+b+" roundto "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 332: // fexpr ::= fexpr ROUNDED TO iexpr DECIMAL_PLACES + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = n+i+"0.5 roundto "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 331: // fexpr ::= fexpr ROUNDED + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = n+"0 0.5 roundto "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 330: // fexpr ::= DOUBLE VALUE OF operatorstatements + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 329: // fexpr ::= USING eexpr LPAREN fexpr RPAREN + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 328: // fexpr ::= ABSOLUTEVALUE OF fexpr + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+"fabs "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 327: // fexpr ::= DIVIDE RDOUBLE BY number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+" "+v+n+" fdiv def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 326: // fexpr ::= MULTIPLY RDOUBLE BY number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+" "+v+n+" fmul def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 325: // fexpr ::= SUBTRACT FROM RDOUBLE number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+" "+v+n+" fsub def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 324: // fexpr ::= ADD TO RDOUBLE number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+" "+v+n+" fadd def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 323: // fexpr ::= LPAREN DOUBLE RPAREN indx_expr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 322: // fexpr ::= LPAREN fexpr RPAREN + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 321: // fexpr ::= MINUS fexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"fnegate "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 320: // fexpr ::= fexpr DIVIDE fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fdiv "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 319: // fexpr ::= iexpr DIVIDE fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fdiv "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 318: // fexpr ::= fexpr DIVIDE iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fdiv "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 317: // fexpr ::= fexpr TIMES fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fmul "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 316: // fexpr ::= iexpr TIMES fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fmul "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 315: // fexpr ::= fexpr TIMES iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fmul "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 314: // fexpr ::= fexpr MINUS fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fsub "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 313: // fexpr ::= iexpr MINUS fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fsub "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 312: // fexpr ::= fexpr MINUS iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fsub "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 311: // fexpr ::= iexpr PLUS fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fadd "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 310: // fexpr ::= fexpr PLUS fexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fadd "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 309: // fexpr ::= fexpr PLUS iexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+"fadd "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 308: // fexpr ::= LPAREN DOUBLE RPAREN RTABLE LPAREN tablelist RPAREN + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String keys = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = t + " " + keys + "lookup "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 307: // fexpr ::= LPAREN DOUBLE RPAREN strexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 306: // fexpr ::= RDOUBLE + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 305: // fexpr ::= colonRef RDOUBLE + { + String RESULT =null; + String re = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = re+ "entitypush "+f+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 304: // fexpr ::= FLOAT + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("fexpr",12, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 303: // strexpr ::= RELATIONSHIP_BETWEEN eexpr AND eexpr + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2+ + "{ type } { '' } "+ + "{ over source req { pop dup target req } over if } "+ + "relationships forfirstelse swap pop swap pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 302: // strexpr ::= USING eexpr LPAREN strexpr RPAREN + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 301: // strexpr ::= GET CURRENT_TIMESTAMP + { + String RESULT =null; + RESULT = "gettimestamp "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 300: // strexpr ::= CHANGE strexpr TO UPPER_CASE NT$0 GET CURRENT_DATE + { + String RESULT =null; + // propagate RESULT from NT$0 + RESULT = (String) ((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String se = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + RESULT = "getdate "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 299: // NT$0 ::= + { + String RESULT =null; + String se = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + RESULT = se +"touppercase "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("NT$0",70, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 298: // strexpr ::= CHANGE strexpr TO LOWER_CASE + { + String RESULT =null; + String se = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + RESULT = se +"tolowercase "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 297: // strexpr ::= LPAREN STR RPAREN indx_expr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie +"tostring "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 296: // strexpr ::= TRIM LPAREN strexpr RPAREN + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+"strtrim "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 295: // strexpr ::= strexpr PLUS RINVALID + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+" strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 294: // strexpr ::= strexpr PLUS RNULL + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+" strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 293: // strexpr ::= strexpr PLUS array_expr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 292: // strexpr ::= strexpr PLUS dexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 291: // strexpr ::= strexpr PLUS eexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 290: // strexpr ::= strexpr PLUS nexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 289: // strexpr ::= strexpr PLUS bexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 288: // strexpr ::= strexpr PLUS fexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 287: // strexpr ::= strexpr PLUS iexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+e+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 286: // strexpr ::= LPAREN strexpr RPAREN + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 285: // strexpr ::= LPAREN STR RPAREN dexpr + { + String RESULT =null; + String de = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = de+"tostring "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 284: // strexpr ::= LPAREN STR RPAREN iexpr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie+"tostring "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 283: // strexpr ::= LPAREN STR RPAREN fexpr + { + String RESULT =null; + String fe = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = fe+"tostring "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 282: // strexpr ::= strexpr PLUS strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 281: // strexpr ::= STRING + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 280: // strexpr ::= colonRef RSTRING + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1 +"entitypush "+s+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 279: // strexpr ::= RSTRING + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 278: // strexpr ::= LPAREN STR RPAREN texpr LPAREN tablelist RPAREN + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String keys = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = t + " " + keys + "lookup "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 277: // strexpr ::= STRING VALUE OF operatorstatements + { + String RESULT =null; + String o = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = o +"cvs "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 276: // strexpr ::= TABLEINFORMATION + { + String RESULT =null; + RESULT = "actionstring "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 275: // strexpr ::= SUBSTRING OF strexpr FROM iexpr TO iexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String start = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String end = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = end+start+s+"substring "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 274: // strexpr ::= RXMLVALUE COLON GET ATTRIBUTE strexpr + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = t+s+"getXmlAttributeValue "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 273: // strexpr ::= RXMLVALUE + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+" cvs "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("strexpr",17, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 272: // texpr ::= NEW strexpr TABLE OF strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + /**c**/ + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("texpr",16, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 271: // texpr ::= RTABLE + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = t+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("texpr",16, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 270: // tablelist ::= strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("tablelist",44, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 269: // tablelist ::= strexpr COMMA tablelist + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+t; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("tablelist",44, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 268: // nexpr ::= LPAREN NAME RPAREN strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"cvn "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 267: // nexpr ::= colonRef RNAME + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1 +"entitypush "+n+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 266: // nexpr ::= USING eexpr LPAREN nexpr RPAREN + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 265: // nexpr ::= NAME + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+n+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 264: // nexpr ::= NAME RARRAY LBRACE iexpr RBRACE + { + String RESULT =null; + String ra = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String ie1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ra+" "+ie1+"getat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 263: // nexpr ::= THENAME strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"cvn "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 262: // nexpr ::= NAMEOF eexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"getname "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 261: // nexpr ::= RNAME + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("nexpr",15, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 260: // dexpr ::= EARLIEST OF array_expr AFTER dexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d + "dup >r { { pop pop i i } over i > if pop } "+a+"dup false sortarray for r> pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 259: // dexpr ::= END OF MONTHS OF dexpr + { + String RESULT =null; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d + "endofmonth "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 258: // dexpr ::= FIRST OF MONTHS OF dexpr + { + String RESULT =null; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d + "firstofmonth "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 257: // dexpr ::= FIRST OF YEARS OF dexpr + { + String RESULT =null; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d + "firstofyear "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 256: // dexpr ::= ADD number DAYS TO RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"adddays "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 255: // dexpr ::= ADD number MONTHS TO RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"addmonths "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 254: // dexpr ::= ADD number YEARS TO RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"addyears "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 253: // dexpr ::= SUBTRACT number DAYS FROM RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"negate adddays "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 252: // dexpr ::= SUBTRACT number MONTHS FROM RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"negate addmonths "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 251: // dexpr ::= SUBTRACT number YEARS FROM dexpr + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+i +"negate addyears "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 250: // dexpr ::= LPAREN DATE RPAREN RTABLE LPAREN tablelist RPAREN + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String keys = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = t + " " + keys + "lookup "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 249: // dexpr ::= dexpr MINUS dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1 +d2+"d- "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 248: // dexpr ::= dexpr PLUS dexpr + { + String RESULT =null; + String d1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String d2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = d1 +d2+"d+ "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 247: // dexpr ::= LPAREN number DAYS RPAREN + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + RESULT = n +"days "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 246: // dexpr ::= colonRef RDATE + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1 +"entitypush "+d+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 245: // dexpr ::= USING eexpr LPAREN dexpr RPAREN + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 244: // dexpr ::= LPAREN DATE RPAREN RARRAY LBRACE iexpr RBRACE + { + String RESULT =null; + String ra = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String ie1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ra+" "+ie1+"getat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 243: // dexpr ::= LPAREN DATE RPAREN indx_expr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 242: // dexpr ::= DATE LPAREN strexpr RPAREN + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = s+"newdate "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 241: // dexpr ::= LPAREN DATE RPAREN strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"newdate "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 240: // dexpr ::= RDATE + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 239: // dexpr ::= LPAREN dexpr RPAREN + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("dexpr",19, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 238: // datestatement ::= ADD number DAYS TO RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"adddays /"+v+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("datestatement",50, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 237: // datestatement ::= ADD number MONTHS TO RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"addmonths /"+v+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("datestatement",50, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 236: // datestatement ::= ADD number YEARS TO RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"addyears /"+v+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("datestatement",50, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 235: // datestatement ::= SUBTRACT number DAYS FROM RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"negate adddays /"+v+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("datestatement",50, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 234: // datestatement ::= SUBTRACT number MONTHS FROM RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"negate addmonths /"+v+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("datestatement",50, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 233: // datestatement ::= SUBTRACT number YEARS FROM RDATE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v +" "+ i +"negate addyears /"+v+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("datestatement",50, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 232: // eexpr ::= strexpr OF eexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ source } { null } { "+s+"type == } forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 231: // eexpr ::= FIRST eexpr WHERE bexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e+"} { null } { "+b+"} "+e.trim()+"s forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 230: // eexpr ::= FIRST eexpr IN array_expr WHERE bexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e+"} { null } { "+b+"} "+a+"forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 229: // eexpr ::= LPAREN ENTITY RPAREN RTABLE LPAREN tablelist RPAREN + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String keys = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = t + " " + keys + "lookup "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 228: // eexpr ::= colonRef RENTITY + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1 +"entitypush "+e2+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 227: // eexpr ::= CLONE OF eexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+ "clone "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 226: // eexpr ::= NEW RENTITY ENTITY + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "/"+n + " createentity "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 225: // eexpr ::= NEW nexpr ENTITY + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = n+ " createentity "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 224: // eexpr ::= indx_expr + { + String RESULT =null; + String ie = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ie; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 223: // eexpr ::= LPAREN eexpr RPAREN + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 222: // eexpr ::= RENTITY + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("eexpr",14, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 221: // indx_expr ::= array_expr LBRACE iexpr RBRACE + { + String RESULT =null; + String ra = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String ie1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ra + ie1 + "getat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("indx_expr",18, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 220: // array_list ::= strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 219: // array_list ::= iexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 218: // array_list ::= eexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 217: // array_list ::= fexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 216: // array_list ::= nexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 215: // array_list ::= array_list COMMA nexpr + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 214: // array_list ::= array_list COMMA fexpr + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 213: // array_list ::= array_list COMMA eexpr + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 212: // array_list ::= array_list COMMA iexpr + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 211: // array_list ::= array_list COMMA strexpr + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_list",67, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 210: // array_lit ::= LBRACE array_list RBRACE + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "{ "+l+"} "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_lit",66, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 209: // array_expr ::= TOKENIZE strexpr BY strexpr + { + String RESULT =null; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s1+s2+"tokenize "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 208: // array_expr ::= ARRAY_OF_VALUES LBRACE array_list RBRACE + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "mark "+e+" arraytomark "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 207: // array_expr ::= array_lit + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 206: // array_expr ::= NEW STR ARRAY + { + String RESULT =null; + RESULT = "/string newtypedarray "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 205: // array_expr ::= NEW ENTITY ARRAY + { + String RESULT =null; + RESULT = "/entity newtypedarray "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 204: // array_expr ::= COPY OF array_expr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"copyelements "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 203: // array_expr ::= GET COPY OF array_expr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"copyelements "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 202: // array_expr ::= colonRef RARRAY + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"entitypush "+v+" entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 201: // array_expr ::= LPAREN ARRAY RPAREN NAME + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = n+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 200: // array_expr ::= RARRAY + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 199: // array_expr ::= LPAREN array_expr RPAREN + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = a; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 198: // array_expr ::= MAP array_expr THROUGH texpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = t+a+"false translate "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("array_expr",20, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 197: // xmlvaluestatements ::= RXMLVALUE COLON SET ATTRIBUTE strexpr ASSIGN strexpr + { + String RESULT =null; + String t = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-6)).value; + String s1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = t+" "+s1+s2+"setXmlAttribute "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("xmlvaluestatements",51, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 196: // operatorstatements ::= ROPERATOR LPAREN operatorlist RPAREN + { + String RESULT =null; + String op = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = l+" "+op+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorstatements",46, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 195: // operatorlist ::= eexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 194: // operatorlist ::= fexpr + { + String RESULT =null; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = f; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 193: // operatorlist ::= iexpr + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = i; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 192: // operatorlist ::= strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 191: // operatorlist ::= eexpr COMMA operatorlist + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 190: // operatorlist ::= fexpr COMMA operatorlist + { + String RESULT =null; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+f; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 189: // operatorlist ::= iexpr COMMA operatorlist + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+i; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 188: // operatorlist ::= strexpr COMMA operatorlist + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("operatorlist",45, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 187: // randomstatements ::= SORT array_expr IN DESCENDINGORDER BY nexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+f+"false sortentities "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 186: // randomstatements ::= SORT array_expr IN ASCENDINGORDER BY nexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+f+"true sortentities "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 185: // randomstatements ::= REMOVE eexpr FROM CACHE + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + RESULT = i+"flushbyid "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 184: // randomstatements ::= CLEAR array_expr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+"clear "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 183: // randomstatements ::= RANDOMIZE array_expr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+"randomize "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 182: // randomstatements ::= REMOVE eexpr FROM array_expr ARRAY + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = a+i+"remove pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 181: // randomstatements ::= REMOVE nexpr FROM array_expr ARRAY + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = a+i+"remove pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 180: // randomstatements ::= REMOVE EACH eexpr FROM array_expr WHERE bexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+"{ { dup 0 entityfetch remove pop } "+b+"if } over forallr pop"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 179: // randomstatements ::= REMOVE iexpr ELEMENT FROM array_expr ARRAY + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = a+i+"removeat pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("randomstatements",42, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 178: // contextstatement ::= ADD eexpr TO CONTEXT FOR THIS TABLE + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + RESULT =e+"entitypush "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("contextstatement",47, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 177: // contextstatement ::= ADD eexpr TO CONTEXT OF THIS TABLE + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + RESULT =e+"entitypush "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("contextstatement",47, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 176: // addtostatement ::= ADD strexpr IF NOT MEMBER TO array_expr AND TO array_expr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-8)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+a+"over add_no_dups "+a2+"swap add_no_dups "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 175: // addtostatement ::= ADD strexpr IF NOT MEMBER TO array_expr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =a+" "+e+"add_no_dups "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 174: // addtostatement ::= ADD eexpr IF NOT MEMBER TO array_expr AND TO array_expr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-8)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+a+"over add_no_dups "+a2+"swap add_no_dups "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 173: // addtostatement ::= ADD eexpr IF NOT MEMBER TO array_expr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =a+" "+e+"add_no_dups "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 172: // addtostatement ::= SUBTRACT number FROM subtodest + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =v+a ; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 171: // addtostatement ::= ADD number TO addtodest AND TO addtodest + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =v+"dup "+a+a2; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 170: // addtostatement ::= ADD number TO addtodest + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =v+a ; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 169: // addtostatement ::= ADD dexpr TO addtodest AND TO addtodest + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+"dup "+a+a2; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 168: // addtostatement ::= ADD dexpr TO addtodest + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+a; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 167: // addtostatement ::= ADD strexpr TO addtodest AND TO addtodest + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+"dup "+a+a2; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 166: // addtostatement ::= ADD strexpr TO addtodest + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+a; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 165: // addtostatement ::= ADD eexpr TO addtodest AND TO addtodest + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+"dup "+a+a2; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 164: // addtostatement ::= ADD eexpr TO addtodest + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =e+a; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 163: // addtostatement ::= ADD array_expr TO array_expr + { + String RESULT =null; + String a1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT =a1+a2+"false addarray "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtostatement",38, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 162: // subtodest ::= RDOUBLE + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+" swap f- /" +a+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("subtodest",40, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 161: // subtodest ::= RLONG + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+" swap - /" +a+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("subtodest",40, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 160: // addtodest ::= RDOUBLE + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+" fadd /" +a+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtodest",39, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 159: // addtodest ::= RLONG + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+" + /" +a+" xdef "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtodest",39, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 158: // addtodest ::= array_expr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = a+"swap addto "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("addtodest",39, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 157: // number ::= fexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("number",9, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 156: // number ::= iexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("number",9, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 155: // ifcontinue ::= ELSEIF ifblock + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT=e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("ifcontinue",54, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 154: // ifcontinue ::= ELSE statement_list ENDIF + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT=e1; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("ifcontinue",54, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 153: // ifcontinue ::= ENDIF + { + String RESULT =null; + RESULT=""; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("ifcontinue",54, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 152: // ifblock ::= bexpr THEN statement_list ifcontinue + { + String RESULT =null; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(e2.trim().length()>0) { + RESULT= "{ "+e1+"} {"+e2+"} "+b+"ifelse "; + }else{ + RESULT= "{ "+e1+"} "+b+"if "; + } + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("ifblock",28, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 151: // debugstatement ::= DEBUG array_expr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"debug "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("debugstatement",36, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 150: // debugstatement ::= DEBUG dexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"debug "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("debugstatement",36, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 149: // debugstatement ::= DEBUG eexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"debug "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("debugstatement",36, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 148: // debugstatement ::= DEBUG fexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"debug "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("debugstatement",36, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 147: // debugstatement ::= DEBUG iexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"debug "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("debugstatement",36, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 146: // debugstatement ::= DEBUG bexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"debug "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("debugstatement",36, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 145: // debugstatement ::= DEBUG strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+"debug "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("debugstatement",36, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 144: // performstatement ::= PERFORM NAME + { + String RESULT =null; + String dt = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = dt; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("performstatement",35, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 143: // performstatement ::= PERFORM RDECISIONTABLE + { + String RESULT =null; + String dt = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = dt; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("performstatement",35, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 142: // performstatement ::= RDECISIONTABLE + { + String RESULT =null; + String dt = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = dt; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("performstatement",35, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 141: // setstatement ::= DECREMENT RDOUBLE + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+v+" "+v+" 1 dsub def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 140: // setstatement ::= DECREMENT RLONG + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+v+" "+v+" 1 lsub def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 139: // setstatement ::= INCREMENT RDOUBLE + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+v+" "+v+" 1 dadd def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 138: // setstatement ::= INCREMENT RLONG + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/"+v+" "+v+" 1 ladd def "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 137: // setstatement ::= SET left_ArrayRef ASSIGN array_expr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 136: // setstatement ::= SET left_ArrayRef ASSIGN dexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 135: // setstatement ::= SET left_ArrayRef ASSIGN iexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 134: // setstatement ::= SET left_ArrayRef ASSIGN fexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 133: // setstatement ::= SET left_ArrayRef ASSIGN strexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 132: // setstatement ::= SET left_ArrayRef ASSIGN eexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 131: // setstatement ::= SET left_texpr ASSIGN texpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cvd "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 130: // setstatement ::= SET left_dexpr ASSIGN dexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cvd "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 129: // setstatement ::= SET left_bexpr ASSIGN nexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cvb "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 128: // setstatement ::= SET left_strexpr ASSIGN strexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cvs "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 127: // setstatement ::= SET left_eexpr ASSIGN eexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cve "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 126: // setstatement ::= SET left_bexpr ASSIGN bexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cvb "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 125: // setstatement ::= SET left_fexpr ASSIGN number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cvr "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 124: // setstatement ::= SET left_iexpr ASSIGN number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"cvi "+v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("setstatement",33, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 123: // left_ArrayRef ::= colonRef left_ArrayRef + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_ArrayRef",61, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 122: // left_ArrayRef ::= RARRAY + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_ArrayRef",61, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 121: // left_texpr ::= colonRef left_texpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_texpr",62, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 120: // left_texpr ::= RTABLE + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_texpr",62, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 119: // left_dexpr ::= colonRef left_dexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_dexpr",60, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 118: // left_dexpr ::= RDATE + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_dexpr",60, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 117: // left_strexpr ::= colonRef left_strexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_strexpr",59, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 116: // left_strexpr ::= RSTRING + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_strexpr",59, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 115: // left_eexpr ::= colonRef left_eexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_eexpr",58, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 114: // left_eexpr ::= RENTITY + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_eexpr",58, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 113: // left_bexpr ::= colonRef left_bexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_bexpr",57, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 112: // left_bexpr ::= RBOOLEAN + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_bexpr",57, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 111: // left_fexpr ::= colonRef left_fexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_fexpr",56, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 110: // left_fexpr ::= RDOUBLE + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_fexpr",56, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 109: // left_iexpr ::= colonRef left_iexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_iexpr",55, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 108: // left_iexpr ::= RLONG + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = left(CUP$DTRulesParser$stack); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("left_iexpr",55, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 107: // usingstatement ::= USING usingblock separator + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = ee ; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("usingstatement",34, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 106: // block ::= statement + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 105: // block ::= block separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 104: // block ::= IF ifblock + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 103: // block ::= firstblock + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 102: // block ::= FORALL forblock + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 101: // block ::= forallblock + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 100: // block ::= USING usingblock + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 99: // block ::= LCURLY statement_list RCURLY + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e+"\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("block",31, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 98: // firstblock ::= forfirstctl THEN block + { + String RESULT =null; + String ctl = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String body = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+body+" } "+ctl+ "pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("firstblock",30, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 97: // firstblock ::= FOR FIRST OF array_expr AND ITS eexpr WHERE bexpr THEN block ELSEIFNONEAREFOUND block + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-9)).value; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-6)).value; + String test = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String body1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String body2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e1+" entitypush "+body1+"entitypop } { "+body2+" } { "+e1+" entitypush "+test+"entitypop } "+a+" forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("firstblock",30, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 96: // firstblock ::= FOR FIRST OF array_expr WHERE bexpr THEN block ELSEIFNONEAREFOUND block + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-6)).value; + String test = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String body1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String body2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+body1+" } { "+body2+" } { "+test+" } "+a+" forfirstelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("firstblock",30, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 95: // forfirstctl ::= FOR FIRST IN array_expr WHERE bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String test = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "dup { "+test+" } "+a+" forfirst "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forfirstctl",27, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 94: // forfirstctl ::= FOR FIRST OF array_expr AND ITS eexpr WHERE bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String test = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e1+" entitypush dup execute entitypop } { "+e1+" entitypush "+test+" entitypop } "+a+" forfirst "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forfirstctl",27, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 93: // forfirstctl ::= FOR FIRST OF array_expr WHERE bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String test = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "dup { "+test+" } "+a+" forfirst "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forfirstctl",27, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 92: // forblock ::= eexpr AND ITS eexpr IN array_expr WHERE bexpr block + { + String RESULT =null; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String blk = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e2+"entitypush { "+blk+" } "+b+"if entitypop } "+a+"forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forblock",24, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 91: // forblock ::= eexpr AND ITS eexpr IN array_expr block + { + String RESULT =null; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String blk = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e2+"entitypush "+blk+" entitypop } "+a+" forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forblock",24, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 90: // forblock ::= array_expr WHERE bexpr block + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String blk = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ { "+blk+" } "+b+"if } "+a+"forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forblock",24, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 89: // forblock ::= eexpr IN array_expr WHERE bexpr block + { + String RESULT =null; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String blk = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ { "+blk+" } "+b+"if } "+a+"forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forblock",24, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 88: // forblock ::= eexpr IN array_expr block + { + String RESULT =null; + String ev = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String blk = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+blk+"} "+a+" forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forblock",24, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 87: // forblock ::= array_expr block + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String blk = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+blk+"} "+a+"forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forblock",24, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 86: // forallctl ::= FORALL array_expr WHERE bexpr ALLOWING array_expr TOBEREMOVED + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + RESULT = "{ dup "+b+"if } "+a+"forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 85: // forallctl ::= FORALL array_expr WHERE bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ dup "+b+"if } "+a+"forall "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 84: // forallctl ::= FORALL array_expr IN eexpr WHERE bexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ dup "+b+"if } "+e2+" entitypush "+a+"forall entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 83: // forallctl ::= FORALL array_expr IN eexpr ALLOWING array_expr TOBEREMOVED + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String ev = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + RESULT = "dup "+ev+" entitypush "+a+"forallr entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 82: // forallctl ::= FORALL array_expr IN eexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String ev = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "dup "+ev+" entitypush "+a+"forall entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 81: // forallctl ::= FORALL array_expr ALLOWING array_expr TOBEREMOVED + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + RESULT = "dup "+a+"forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 80: // forallctl ::= FORALL array_expr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "dup "+a+"forall "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 79: // forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr WHERE bexpr ALLOWING array_expr TOBEREMOVED + { + String RESULT =null; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-7)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + RESULT = "{ "+e2+"entitypush dup "+b+"if entitypop } "+a+"forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 78: // forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr WHERE bexpr + { + String RESULT =null; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-4)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e2+"entitypush dup "+b+"if entitypop } "+a+"forall "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 77: // forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr ALLOWING array_expr TOBEREMOVED + { + String RESULT =null; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + RESULT = "{ "+e2+"entitypush dup execute entitypop } "+a+" forallr "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 76: // forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr + { + String RESULT =null; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+e2+"entitypush dup execute entitypop } "+a+" forall "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallctl",26, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 75: // ifstatement ::= IF bexpr THEN block ELSE block ENDIF + { + String RESULT =null; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-5)).value; + String blk1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String blk2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "{ "+blk1+"} { "+blk2+"} }" +b+ "ifelse "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("ifstatement",37, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 74: // ifstatement ::= IF bexpr THEN block ENDIF + { + String RESULT =null; + String b = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String blk1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "{ "+blk1+"} " +b+ "if " ; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("ifstatement",37, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 73: // localvariables ::= LOCAL STRING RSTRING + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 72: // localvariables ::= LOCAL STRING UNDEFINED ASSIGN strexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iString, e); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 71: // localvariables ::= LOCAL STRING UNDEFINED + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iString, null); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 70: // localvariables ::= LOCAL ARRAY RARRAY + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 69: // localvariables ::= LOCAL ARRAY UNDEFINED ASSIGN array_expr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iArray, e); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 68: // localvariables ::= LOCAL ARRAY UNDEFINED + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iArray, null); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 67: // localvariables ::= LOCAL DATE RDATE + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 66: // localvariables ::= LOCAL DATE UNDEFINED ASSIGN dexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iTime, e); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 65: // localvariables ::= LOCAL DATE UNDEFINED + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iTime, null); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 64: // localvariables ::= LOCAL BOOLEAN RBOOLEAN + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 63: // localvariables ::= LOCAL BOOLEAN UNDEFINED ASSIGN bexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iBoolean, e); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 62: // localvariables ::= LOCAL BOOLEAN UNDEFINED + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iBoolean, null); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 61: // localvariables ::= LOCAL DOUBLE RDOUBLE + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 60: // localvariables ::= LOCAL DOUBLE UNDEFINED ASSIGN number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iDouble, e); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 59: // localvariables ::= LOCAL DOUBLE UNDEFINED + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iDouble, null); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 58: // localvariables ::= LOCAL LONG RLONG + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 57: // localvariables ::= LOCAL LONG UNDEFINED ASSIGN number + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iInteger, e); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 56: // localvariables ::= LOCAL LONG UNDEFINED + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iInteger, null); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 55: // localvariables ::= LOCAL ENTITY RENTITY + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 54: // localvariables ::= LOCAL ENTITY UNDEFINED ASSIGN eexpr + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iEntity, e); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 53: // localvariables ::= LOCAL ENTITY UNDEFINED + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = parser.newLocal(v, parser.iEntity, null); + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("localvariables",48, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 52: // context_for_table ::= localvariables + { + String RESULT =null; + String v = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = v; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("context_for_table",49, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 51: // context_for_table ::= contextstatement + { + String RESULT =null; + String c = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = c +"execute entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("context_for_table",49, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 50: // context_for_table ::= forfirstctl + { + String RESULT =null; + String ctl = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ctl+"pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("context_for_table",49, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 49: // context_for_table ::= forallctl + { + String RESULT =null; + String ctl = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ctl+"pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("context_for_table",49, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 48: // forallblock ::= block forallctl + { + String RESULT =null; + String blk = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String ctl = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ "+blk+"} "+ctl+"pop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("forallblock",25, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 47: // colonRef ::= possessiveRef + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("colonRef",64, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 46: // possessiveRef ::= COLON RENTITY COLON + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e1 +" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("possessiveRef",65, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 45: // possessiveRef ::= COLON RENTITY COLON possessiveRef + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1 +" entitypush "+e2+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("possessiveRef",65, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 44: // possessiveRef ::= RENTITY ARROW + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("possessiveRef",65, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 43: // possessiveRef ::= RENTITY ARROW possessiveRef + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1 +" entitypush "+e2+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("possessiveRef",65, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 42: // possessiveRef ::= POSSESSIVE COMMA + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e+" "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("possessiveRef",65, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 41: // possessiveRef ::= POSSESSIVE COMMA possessiveRef + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1 +" entitypush "+e2+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("possessiveRef",65, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 40: // usingblock ::= block + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("usingblock",29, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 39: // usingblock ::= usingEntityRef COMMA usingblock + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("usingblock",29, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 38: // usingblock ::= usingEntityRef usingblock + { + String RESULT =null; + String ee = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = ee + "entitypush "+e+"entitypop "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("usingblock",29, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 37: // maximusstatements ::= SET ERRORCODE array_expr WITH strexpr + { + String RESULT =null; + String a = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "{ /errorcode xdef "+ + "/actioncomment getdescription def " + + "/errormsg " +s+"def set_error_code "+ + "} "+a+"for "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("maximusstatements",68, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 36: // maximusstatements ::= SET ERRORCODE nexpr WITH strexpr + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/actioncomment getdescription def " + + "/errorcode "+n+"def " + + "/errormsg " +s+"def set_error_code "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("maximusstatements",68, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 35: // maximusstatements ::= SET ERRORCODE nexpr + { + String RESULT =null; + String n = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "/actioncomment getdescription def " + + "/errorcode "+n+"def set_error_code "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("maximusstatements",68, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 34: // maximusstatements ::= MAXPRINT parameterlist + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l+"printmessage "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("maximusstatements",68, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 33: // parameterlist ::= eexpr + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"entityname "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 32: // parameterlist ::= fexpr + { + String RESULT =null; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = f; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 31: // parameterlist ::= iexpr + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = i; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 30: // parameterlist ::= strexpr + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 29: // parameterlist ::= eexpr COMMA parameterlist + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e+"entityname "+l+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 28: // parameterlist ::= fexpr COMMA parameterlist + { + String RESULT =null; + String f = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = f+l+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 27: // parameterlist ::= iexpr COMMA parameterlist + { + String RESULT =null; + String i = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = i+l+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 26: // parameterlist ::= strexpr COMMA parameterlist + { + String RESULT =null; + String s = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-2)).value; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = s+l+"strconcat "; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 25: // parameterlist ::= AND parameterlist + { + String RESULT =null; + String l = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = l; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("parameterlist",69, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 24: // statement ::= separator + { + String RESULT =null; + RESULT = ""; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 23: // statement ::= xmlvaluestatements separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 22: // statement ::= datestatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 21: // statement ::= contextstatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 20: // statement ::= operatorstatements separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 19: // statement ::= maximusstatements separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 18: // statement ::= commonerror separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 17: // statement ::= randomstatements separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 16: // statement ::= usingstatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 15: // statement ::= clearstatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 14: // statement ::= addtostatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 13: // statement ::= ifstatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 12: // statement ::= debugstatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 11: // statement ::= performstatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 10: // statement ::= setstatement separator + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement",8, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 9: // separator ::= COMMA + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("separator",52, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 8: // separator ::= SEMI + { + String RESULT =null; + + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("separator",52, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 7: // statement_list ::= block + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement_list",7, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 6: // statement_list ::= statement_list block + { + String RESULT =null; + String e1 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + String e2 = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = e1+e2; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("statement_list",7, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 5: // done ::= CONTEXT context_for_table SEMI + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "\n"+e+"\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("done",6, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 4: // done ::= CONDITION bexpr SEMI debugstatement SEMI + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "\n"+e+d+"\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("done",6, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 3: // done ::= CONDITION debugstatement SEMI bexpr SEMI + { + String RESULT =null; + String d = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-3)).value; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "\n"+d+e+"\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("done",6, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 2: // done ::= CONDITION bexpr SEMI + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = "\n"+e+"\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("done",6, RESULT); + } + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 1: // $START ::= done EOF + { + Object RESULT =null; + String start_val = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.elementAt(CUP$DTRulesParser$top-1)).value; + RESULT = start_val; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("$START",0, RESULT); + } + /* ACCEPT */ + CUP$DTRulesParser$parser.done_parsing(); + return CUP$DTRulesParser$result; + + /*. . . . . . . . . . . . . . . . . . . .*/ + case 0: // done ::= ACTION statement_list + { + String RESULT =null; + String e = (String)((java_cup.runtime.Symbol) CUP$DTRulesParser$stack.peek()).value; + RESULT = "\n"+e+"\n"; + CUP$DTRulesParser$result = parser.getSymbolFactory().newSymbol("done",6, RESULT); + } + return CUP$DTRulesParser$result; + + /* . . . . . .*/ + default: + throw new Exception( + "Invalid action number found in internal parse table"); + + } + } +} + + \ No newline at end of file diff --git a/DTParser/src/main/java/com/dtrules/compiler/cup/RLocalType.java b/DTParser/src/main/java/com/dtrules/compiler/cup/RLocalType.java new file mode 100644 index 0000000..f9ce9df --- /dev/null +++ b/DTParser/src/main/java/com/dtrules/compiler/cup/RLocalType.java @@ -0,0 +1,14 @@ +/** + * + */ +package com.dtrules.compiler.cup; + +/** + * @author paul snow + * + */ +public class RLocalType { + String name; + int type; + int index; +} diff --git a/DTParser/src/main/java/com/dtrules/compiler/cup/RSymbol.java b/DTParser/src/main/java/com/dtrules/compiler/cup/RSymbol.java new file mode 100644 index 0000000..1ce7328 --- /dev/null +++ b/DTParser/src/main/java/com/dtrules/compiler/cup/RSymbol.java @@ -0,0 +1,33 @@ +/** + * + */ +package com.dtrules.compiler.cup; + +import java_cup.runtime.Symbol; + +/** + * @author ps24876 + * + * We return this symbol only if the identifier is local. + */ +public class RSymbol extends Symbol { + boolean local = false; + String leftvalue; + String rightvalue; + /** + * @param id + * @param l + * @param r + * @param o + */ + public RSymbol(boolean local, Symbol s) { + super(s.sym); + this.local = local; + this.left = s.left; + this.parse_state = s.parse_state; + this.right = s.right; + this.sym = s.sym; + this.value = s.value; + if(s.value != null) this.rightvalue = s.value.toString(); + } +} diff --git a/DTParser/src/main/java/com/dtrules/compiler/cup/bnf.txt b/DTParser/src/main/java/com/dtrules/compiler/cup/bnf.txt new file mode 100644 index 0000000..e6be539 --- /dev/null +++ b/DTParser/src/main/java/com/dtrules/compiler/cup/bnf.txt @@ -0,0 +1,573 @@ +/** + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + Warning : Terminal "IDENT" was declared but never used +===== Terminals ===== +[0]EOF [1]error [2]ABSOLUTEVALUE [3]ACTION [4]ADD +[5]AFTER [6]ALL [7]ALLOWING [8]AND [9]ARRAY +[10]ARRAY_OF_VALUES [11]ARROW [12]ASCENDINGORDER [13]ASSIGN [14]ATTRIBUTE +[15]AT [16]BEFORE [17]BETWEEN [18]BOOL_FUNCTION [19]BOOLEAN +[20]BY [21]CACHE [22]CHANGE [23]CLEAR [24]CLONE +[25]COLON [26]CONTEXT [27]COMMA [28]CONDITION [29]COPY +[30]CURRENT_DATE [31]CURRENT_TIMESTAMP [32]DATE [33]DAYS [34]DEBUG +[35]DECIMAL_PLACES [36]DECREMENT [37]DESCENDINGORDER [38]DIVIDE [39]DOES +[40]DOUBLE [41]EACH [42]EARLIEST [43]ELEMENT [44]ELSE +[45]ELSEIF [46]ELSEIFNONEAREFOUND [47]END [48]ENDIF [49]ENTITY +[50]EQ [51]EQUAL [52]ERRORCODE [53]FIRST [54]FLOAT +[55]FOR [56]FORALL [57]FROM [58]GET [59]GREATER +[60]GT [61]GTE [62]HASA [63]HAVE [64]IF +[65]IN [66]INCLUDE [67]INCLUDES [68]INCREMENT [69]INTEGER +[70]IS [71]ISNOTNULL [72]ISNULL [73]ITS [74]LBRACE +[75]LCURLY [76]LENGTH [77]LESS [78]LOCAL [79]LONG +[80]LOWER_CASE [81]LPAREN [82]LT [83]LTE [84]MAP +[85]MATCH [86]MATCHES [87]MEMBER [88]MINUS [89]MONTHS +[90]MULTIPLY [91]NAME [92]NAMEOF [93]NEQ [94]NEW +[95]NO [96]NOT [97]NULL [98]NUMBEROF [99]OF +[100]ON [101]ONE [102]OR [103]PERFORM [104]PLUS +[105]POSSESSIVE [106]QUESTIONMARK [107]RANDOMIZE [108]RARRAY [109]RBOOLEAN +[110]RBRACE [111]RCURLY [112]RDATE [113]RDECISIONTABLE [114]RDOUBLE +[115]RELATIONSHIP_BETWEEN [116]REMOVE [117]RENTITY [118]RINVALID [119]RLONG +[120]RNAME [121]RNULL [122]ROPERATOR [123]ROUNDED [124]RPAREN +[125]RSTRING [126]RTABLE [127]RXMLVALUE [128]SEMI [129]SET +[130]SORT [131]STARTS_WITH [132]STR [133]STRING [134]SUBSTRING +[135]SUBTRACT [136]SUM_OF [137]TABLE [138]TABLEINFORMATION [139]THAN +[140]THEN [141]THENAME [142]THERE [143]THIS [144]TIMES +[145]THROUGH [146]TO [147]TOBEREMOVED [148]TOKENIZE [149]TRIM +[150]UMINUS [151]UNDEFINED [152]UPPER_CASE [153]USING [154]VALUE +[155]WAS [156]WHERE [157]WITH [158]WITH_BOUNDRY [159]YEARS +[160]YEAROF [161]IDENT [162]MAXPRINT + +===== Non terminals ===== +[0]eq [1]neq [2]gt [3]gte [4]lt +[5]lte [6]done [7]statement_list [8]statement [9]number +[10]inthe [11]iexpr [12]fexpr [13]bexpr [14]eexpr +[15]nexpr [16]texpr [17]strexpr [18]indx_expr [19]dexpr +[20]array_expr [21]isnull [22]isnotnull [23]includeSearch [24]forblock +[25]forallblock [26]forallctl [27]forfirstctl [28]ifblock [29]usingblock +[30]firstblock [31]block [32]thereis [33]setstatement [34]usingstatement +[35]performstatement [36]debugstatement [37]ifstatement [38]addtostatement [39]addtodest +[40]subtodest [41]clearstatement [42]randomstatements [43]commonerror [44]tablelist +[45]operatorlist [46]operatorstatements [47]contextstatement [48]localvariables [49]context_for_table +[50]datestatement [51]xmlvaluestatements [52]separator [53]blist [54]ifcontinue +[55]left_iexpr [56]left_fexpr [57]left_bexpr [58]left_eexpr [59]left_strexpr +[60]left_dexpr [61]left_ArrayRef [62]left_texpr [63]usingEntityRef [64]colonRef +[65]possessiveRef [66]array_lit [67]array_list [68]maximusstatements [69]parameterlist +[70]NT$0 + +===== Productions ===== +[0] done ::= ACTION statement_list +[1] $START ::= done EOF +[2] done ::= CONDITION bexpr SEMI +[3] done ::= CONDITION debugstatement SEMI bexpr SEMI +[4] done ::= CONDITION bexpr SEMI debugstatement SEMI +[5] done ::= CONTEXT context_for_table SEMI +[6] statement_list ::= statement_list block +[7] statement_list ::= block +[8] separator ::= SEMI +[9] separator ::= COMMA +[10] statement ::= setstatement separator +[11] statement ::= performstatement separator +[12] statement ::= debugstatement separator +[13] statement ::= ifstatement separator +[14] statement ::= addtostatement separator +[15] statement ::= clearstatement separator +[16] statement ::= usingstatement separator +[17] statement ::= randomstatements separator +[18] statement ::= commonerror separator +[19] statement ::= maximusstatements separator +[20] statement ::= operatorstatements separator +[21] statement ::= contextstatement separator +[22] statement ::= datestatement separator +[23] statement ::= xmlvaluestatements separator +[24] statement ::= separator +[25] parameterlist ::= AND parameterlist +[26] parameterlist ::= strexpr COMMA parameterlist +[27] parameterlist ::= iexpr COMMA parameterlist +[28] parameterlist ::= fexpr COMMA parameterlist +[29] parameterlist ::= eexpr COMMA parameterlist +[30] parameterlist ::= strexpr +[31] parameterlist ::= iexpr +[32] parameterlist ::= fexpr +[33] parameterlist ::= eexpr +[34] maximusstatements ::= MAXPRINT parameterlist +[35] maximusstatements ::= SET ERRORCODE nexpr +[36] maximusstatements ::= SET ERRORCODE nexpr WITH strexpr +[37] maximusstatements ::= SET ERRORCODE array_expr WITH strexpr +[38] usingblock ::= usingEntityRef usingblock +[39] usingblock ::= usingEntityRef COMMA usingblock +[40] usingblock ::= block +[41] possessiveRef ::= POSSESSIVE COMMA possessiveRef +[42] possessiveRef ::= POSSESSIVE COMMA +[43] possessiveRef ::= RENTITY ARROW possessiveRef +[44] possessiveRef ::= RENTITY ARROW +[45] possessiveRef ::= COLON RENTITY COLON possessiveRef +[46] possessiveRef ::= COLON RENTITY COLON +[47] colonRef ::= possessiveRef +[48] forallblock ::= block forallctl +[49] context_for_table ::= forallctl +[50] context_for_table ::= forfirstctl +[51] context_for_table ::= contextstatement +[52] context_for_table ::= localvariables +[53] localvariables ::= LOCAL ENTITY UNDEFINED +[54] localvariables ::= LOCAL ENTITY UNDEFINED ASSIGN eexpr +[55] localvariables ::= LOCAL ENTITY RENTITY +[56] localvariables ::= LOCAL LONG UNDEFINED +[57] localvariables ::= LOCAL LONG UNDEFINED ASSIGN number +[58] localvariables ::= LOCAL LONG RLONG +[59] localvariables ::= LOCAL DOUBLE UNDEFINED +[60] localvariables ::= LOCAL DOUBLE UNDEFINED ASSIGN number +[61] localvariables ::= LOCAL DOUBLE RDOUBLE +[62] localvariables ::= LOCAL BOOLEAN UNDEFINED +[63] localvariables ::= LOCAL BOOLEAN UNDEFINED ASSIGN bexpr +[64] localvariables ::= LOCAL BOOLEAN RBOOLEAN +[65] localvariables ::= LOCAL DATE UNDEFINED +[66] localvariables ::= LOCAL DATE UNDEFINED ASSIGN dexpr +[67] localvariables ::= LOCAL DATE RDATE +[68] localvariables ::= LOCAL ARRAY UNDEFINED +[69] localvariables ::= LOCAL ARRAY UNDEFINED ASSIGN array_expr +[70] localvariables ::= LOCAL ARRAY RARRAY +[71] localvariables ::= LOCAL STRING UNDEFINED +[72] localvariables ::= LOCAL STRING UNDEFINED ASSIGN strexpr +[73] localvariables ::= LOCAL STRING RSTRING +[74] ifstatement ::= IF bexpr THEN block ENDIF +[75] ifstatement ::= IF bexpr THEN block ELSE block ENDIF +[76] forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr +[77] forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr ALLOWING array_expr TOBEREMOVED +[78] forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr WHERE bexpr +[79] forallctl ::= FORALL eexpr AND ITS eexpr IN array_expr WHERE bexpr ALLOWING array_expr TOBEREMOVED +[80] forallctl ::= FORALL array_expr +[81] forallctl ::= FORALL array_expr ALLOWING array_expr TOBEREMOVED +[82] forallctl ::= FORALL array_expr IN eexpr +[83] forallctl ::= FORALL array_expr IN eexpr ALLOWING array_expr TOBEREMOVED +[84] forallctl ::= FORALL array_expr IN eexpr WHERE bexpr +[85] forallctl ::= FORALL array_expr WHERE bexpr +[86] forallctl ::= FORALL array_expr WHERE bexpr ALLOWING array_expr TOBEREMOVED +[87] forblock ::= array_expr block +[88] forblock ::= eexpr IN array_expr block +[89] forblock ::= eexpr IN array_expr WHERE bexpr block +[90] forblock ::= array_expr WHERE bexpr block +[91] forblock ::= eexpr AND ITS eexpr IN array_expr block +[92] forblock ::= eexpr AND ITS eexpr IN array_expr WHERE bexpr block +[93] forfirstctl ::= FOR FIRST OF array_expr WHERE bexpr +[94] forfirstctl ::= FOR FIRST OF array_expr AND ITS eexpr WHERE bexpr +[95] forfirstctl ::= FOR FIRST IN array_expr WHERE bexpr +[96] firstblock ::= FOR FIRST OF array_expr WHERE bexpr THEN block ELSEIFNONEAREFOUND block +[97] firstblock ::= FOR FIRST OF array_expr AND ITS eexpr WHERE bexpr THEN block ELSEIFNONEAREFOUND block +[98] firstblock ::= forfirstctl THEN block +[99] block ::= LCURLY statement_list RCURLY +[100] block ::= USING usingblock +[101] block ::= forallblock +[102] block ::= FORALL forblock +[103] block ::= firstblock +[104] block ::= IF ifblock +[105] block ::= block separator +[106] block ::= statement +[107] usingstatement ::= USING usingblock separator +[108] left_iexpr ::= RLONG +[109] left_iexpr ::= colonRef left_iexpr +[110] left_fexpr ::= RDOUBLE +[111] left_fexpr ::= colonRef left_fexpr +[112] left_bexpr ::= RBOOLEAN +[113] left_bexpr ::= colonRef left_bexpr +[114] left_eexpr ::= RENTITY +[115] left_eexpr ::= colonRef left_eexpr +[116] left_strexpr ::= RSTRING +[117] left_strexpr ::= colonRef left_strexpr +[118] left_dexpr ::= RDATE +[119] left_dexpr ::= colonRef left_dexpr +[120] left_texpr ::= RTABLE +[121] left_texpr ::= colonRef left_texpr +[122] left_ArrayRef ::= RARRAY +[123] left_ArrayRef ::= colonRef left_ArrayRef +[124] setstatement ::= SET left_iexpr ASSIGN number +[125] setstatement ::= SET left_fexpr ASSIGN number +[126] setstatement ::= SET left_bexpr ASSIGN bexpr +[127] setstatement ::= SET left_eexpr ASSIGN eexpr +[128] setstatement ::= SET left_strexpr ASSIGN strexpr +[129] setstatement ::= SET left_bexpr ASSIGN nexpr +[130] setstatement ::= SET left_dexpr ASSIGN dexpr +[131] setstatement ::= SET left_texpr ASSIGN texpr +[132] setstatement ::= SET left_ArrayRef ASSIGN eexpr +[133] setstatement ::= SET left_ArrayRef ASSIGN strexpr +[134] setstatement ::= SET left_ArrayRef ASSIGN fexpr +[135] setstatement ::= SET left_ArrayRef ASSIGN iexpr +[136] setstatement ::= SET left_ArrayRef ASSIGN dexpr +[137] setstatement ::= SET left_ArrayRef ASSIGN array_expr +[138] setstatement ::= INCREMENT RLONG +[139] setstatement ::= INCREMENT RDOUBLE +[140] setstatement ::= DECREMENT RLONG +[141] setstatement ::= DECREMENT RDOUBLE +[142] performstatement ::= RDECISIONTABLE +[143] performstatement ::= PERFORM RDECISIONTABLE +[144] performstatement ::= PERFORM NAME +[145] debugstatement ::= DEBUG strexpr +[146] debugstatement ::= DEBUG bexpr +[147] debugstatement ::= DEBUG iexpr +[148] debugstatement ::= DEBUG fexpr +[149] debugstatement ::= DEBUG eexpr +[150] debugstatement ::= DEBUG dexpr +[151] debugstatement ::= DEBUG array_expr +[152] ifblock ::= bexpr THEN statement_list ifcontinue +[153] ifcontinue ::= ENDIF +[154] ifcontinue ::= ELSE statement_list ENDIF +[155] ifcontinue ::= ELSEIF ifblock +[156] number ::= iexpr +[157] number ::= fexpr +[158] addtodest ::= array_expr +[159] addtodest ::= RLONG +[160] addtodest ::= RDOUBLE +[161] subtodest ::= RLONG +[162] subtodest ::= RDOUBLE +[163] addtostatement ::= ADD array_expr TO array_expr +[164] addtostatement ::= ADD eexpr TO addtodest +[165] addtostatement ::= ADD eexpr TO addtodest AND TO addtodest +[166] addtostatement ::= ADD strexpr TO addtodest +[167] addtostatement ::= ADD strexpr TO addtodest AND TO addtodest +[168] addtostatement ::= ADD dexpr TO addtodest +[169] addtostatement ::= ADD dexpr TO addtodest AND TO addtodest +[170] addtostatement ::= ADD number TO addtodest +[171] addtostatement ::= ADD number TO addtodest AND TO addtodest +[172] addtostatement ::= SUBTRACT number FROM subtodest +[173] addtostatement ::= ADD eexpr IF NOT MEMBER TO array_expr +[174] addtostatement ::= ADD eexpr IF NOT MEMBER TO array_expr AND TO array_expr +[175] addtostatement ::= ADD strexpr IF NOT MEMBER TO array_expr +[176] addtostatement ::= ADD strexpr IF NOT MEMBER TO array_expr AND TO array_expr +[177] contextstatement ::= ADD eexpr TO CONTEXT OF THIS TABLE +[178] contextstatement ::= ADD eexpr TO CONTEXT FOR THIS TABLE +[179] randomstatements ::= REMOVE iexpr ELEMENT FROM array_expr ARRAY +[180] randomstatements ::= REMOVE EACH eexpr FROM array_expr WHERE bexpr +[181] randomstatements ::= REMOVE nexpr FROM array_expr ARRAY +[182] randomstatements ::= REMOVE eexpr FROM array_expr ARRAY +[183] randomstatements ::= RANDOMIZE array_expr +[184] randomstatements ::= CLEAR array_expr +[185] randomstatements ::= REMOVE eexpr FROM CACHE +[186] randomstatements ::= SORT array_expr IN ASCENDINGORDER BY nexpr +[187] randomstatements ::= SORT array_expr IN DESCENDINGORDER BY nexpr +[188] operatorlist ::= strexpr COMMA operatorlist +[189] operatorlist ::= iexpr COMMA operatorlist +[190] operatorlist ::= fexpr COMMA operatorlist +[191] operatorlist ::= eexpr COMMA operatorlist +[192] operatorlist ::= strexpr +[193] operatorlist ::= iexpr +[194] operatorlist ::= fexpr +[195] operatorlist ::= eexpr +[196] operatorstatements ::= ROPERATOR LPAREN operatorlist RPAREN +[197] xmlvaluestatements ::= RXMLVALUE COLON SET ATTRIBUTE strexpr ASSIGN strexpr +[198] array_expr ::= MAP array_expr THROUGH texpr +[199] array_expr ::= LPAREN array_expr RPAREN +[200] array_expr ::= RARRAY +[201] array_expr ::= LPAREN ARRAY RPAREN NAME +[202] array_expr ::= colonRef RARRAY +[203] array_expr ::= GET COPY OF array_expr +[204] array_expr ::= COPY OF array_expr +[205] array_expr ::= NEW ENTITY ARRAY +[206] array_expr ::= NEW STR ARRAY +[207] array_expr ::= array_lit +[208] array_expr ::= ARRAY_OF_VALUES LBRACE array_list RBRACE +[209] array_expr ::= TOKENIZE strexpr BY strexpr +[210] array_lit ::= LBRACE array_list RBRACE +[211] array_list ::= array_list COMMA strexpr +[212] array_list ::= array_list COMMA iexpr +[213] array_list ::= array_list COMMA eexpr +[214] array_list ::= array_list COMMA fexpr +[215] array_list ::= array_list COMMA nexpr +[216] array_list ::= nexpr +[217] array_list ::= fexpr +[218] array_list ::= eexpr +[219] array_list ::= iexpr +[220] array_list ::= strexpr +[221] indx_expr ::= array_expr LBRACE iexpr RBRACE +[222] eexpr ::= RENTITY +[223] eexpr ::= LPAREN eexpr RPAREN +[224] eexpr ::= indx_expr +[225] eexpr ::= NEW nexpr ENTITY +[226] eexpr ::= NEW RENTITY ENTITY +[227] eexpr ::= CLONE OF eexpr +[228] eexpr ::= colonRef RENTITY +[229] eexpr ::= LPAREN ENTITY RPAREN RTABLE LPAREN tablelist RPAREN +[230] eexpr ::= FIRST eexpr IN array_expr WHERE bexpr +[231] eexpr ::= FIRST eexpr WHERE bexpr +[232] eexpr ::= strexpr OF eexpr +[233] datestatement ::= SUBTRACT number YEARS FROM RDATE +[234] datestatement ::= SUBTRACT number MONTHS FROM RDATE +[235] datestatement ::= SUBTRACT number DAYS FROM RDATE +[236] datestatement ::= ADD number YEARS TO RDATE +[237] datestatement ::= ADD number MONTHS TO RDATE +[238] datestatement ::= ADD number DAYS TO RDATE +[239] dexpr ::= LPAREN dexpr RPAREN +[240] dexpr ::= RDATE +[241] dexpr ::= LPAREN DATE RPAREN strexpr +[242] dexpr ::= DATE LPAREN strexpr RPAREN +[243] dexpr ::= LPAREN DATE RPAREN indx_expr +[244] dexpr ::= LPAREN DATE RPAREN RARRAY LBRACE iexpr RBRACE +[245] dexpr ::= USING eexpr LPAREN dexpr RPAREN +[246] dexpr ::= colonRef RDATE +[247] dexpr ::= LPAREN number DAYS RPAREN +[248] dexpr ::= dexpr PLUS dexpr +[249] dexpr ::= dexpr MINUS dexpr +[250] dexpr ::= LPAREN DATE RPAREN RTABLE LPAREN tablelist RPAREN +[251] dexpr ::= SUBTRACT number YEARS FROM dexpr +[252] dexpr ::= SUBTRACT number MONTHS FROM RDATE +[253] dexpr ::= SUBTRACT number DAYS FROM RDATE +[254] dexpr ::= ADD number YEARS TO RDATE +[255] dexpr ::= ADD number MONTHS TO RDATE +[256] dexpr ::= ADD number DAYS TO RDATE +[257] dexpr ::= FIRST OF YEARS OF dexpr +[258] dexpr ::= FIRST OF MONTHS OF dexpr +[259] dexpr ::= END OF MONTHS OF dexpr +[260] dexpr ::= EARLIEST OF array_expr AFTER dexpr +[261] nexpr ::= RNAME +[262] nexpr ::= NAMEOF eexpr +[263] nexpr ::= THENAME strexpr +[264] nexpr ::= NAME RARRAY LBRACE iexpr RBRACE +[265] nexpr ::= NAME +[266] nexpr ::= USING eexpr LPAREN nexpr RPAREN +[267] nexpr ::= colonRef RNAME +[268] nexpr ::= LPAREN NAME RPAREN strexpr +[269] tablelist ::= strexpr COMMA tablelist +[270] tablelist ::= strexpr +[271] texpr ::= RTABLE +[272] texpr ::= NEW strexpr TABLE OF strexpr +[273] strexpr ::= RXMLVALUE +[274] strexpr ::= RXMLVALUE COLON GET ATTRIBUTE strexpr +[275] strexpr ::= SUBSTRING OF strexpr FROM iexpr TO iexpr +[276] strexpr ::= TABLEINFORMATION +[277] strexpr ::= STRING VALUE OF operatorstatements +[278] strexpr ::= LPAREN STR RPAREN texpr LPAREN tablelist RPAREN +[279] strexpr ::= RSTRING +[280] strexpr ::= colonRef RSTRING +[281] strexpr ::= STRING +[282] strexpr ::= strexpr PLUS strexpr +[283] strexpr ::= LPAREN STR RPAREN fexpr +[284] strexpr ::= LPAREN STR RPAREN iexpr +[285] strexpr ::= LPAREN STR RPAREN dexpr +[286] strexpr ::= LPAREN strexpr RPAREN +[287] strexpr ::= strexpr PLUS iexpr +[288] strexpr ::= strexpr PLUS fexpr +[289] strexpr ::= strexpr PLUS bexpr +[290] strexpr ::= strexpr PLUS nexpr +[291] strexpr ::= strexpr PLUS eexpr +[292] strexpr ::= strexpr PLUS dexpr +[293] strexpr ::= strexpr PLUS array_expr +[294] strexpr ::= strexpr PLUS RNULL +[295] strexpr ::= strexpr PLUS RINVALID +[296] strexpr ::= TRIM LPAREN strexpr RPAREN +[297] strexpr ::= LPAREN STR RPAREN indx_expr +[298] strexpr ::= CHANGE strexpr TO LOWER_CASE +[299] NT$0 ::= +[300] strexpr ::= CHANGE strexpr TO UPPER_CASE NT$0 GET CURRENT_DATE +[301] strexpr ::= GET CURRENT_TIMESTAMP +[302] strexpr ::= USING eexpr LPAREN strexpr RPAREN +[303] strexpr ::= RELATIONSHIP_BETWEEN eexpr AND eexpr +[304] fexpr ::= FLOAT +[305] fexpr ::= colonRef RDOUBLE +[306] fexpr ::= RDOUBLE +[307] fexpr ::= LPAREN DOUBLE RPAREN strexpr +[308] fexpr ::= LPAREN DOUBLE RPAREN RTABLE LPAREN tablelist RPAREN +[309] fexpr ::= fexpr PLUS iexpr +[310] fexpr ::= fexpr PLUS fexpr +[311] fexpr ::= iexpr PLUS fexpr +[312] fexpr ::= fexpr MINUS iexpr +[313] fexpr ::= iexpr MINUS fexpr +[314] fexpr ::= fexpr MINUS fexpr +[315] fexpr ::= fexpr TIMES iexpr +[316] fexpr ::= iexpr TIMES fexpr +[317] fexpr ::= fexpr TIMES fexpr +[318] fexpr ::= fexpr DIVIDE iexpr +[319] fexpr ::= iexpr DIVIDE fexpr +[320] fexpr ::= fexpr DIVIDE fexpr +[321] fexpr ::= MINUS fexpr +[322] fexpr ::= LPAREN fexpr RPAREN +[323] fexpr ::= LPAREN DOUBLE RPAREN indx_expr +[324] fexpr ::= ADD TO RDOUBLE number +[325] fexpr ::= SUBTRACT FROM RDOUBLE number +[326] fexpr ::= MULTIPLY RDOUBLE BY number +[327] fexpr ::= DIVIDE RDOUBLE BY number +[328] fexpr ::= ABSOLUTEVALUE OF fexpr +[329] fexpr ::= USING eexpr LPAREN fexpr RPAREN +[330] fexpr ::= DOUBLE VALUE OF operatorstatements +[331] fexpr ::= fexpr ROUNDED +[332] fexpr ::= fexpr ROUNDED TO iexpr DECIMAL_PLACES +[333] fexpr ::= fexpr ROUNDED TO iexpr DECIMAL_PLACES WITH_BOUNDRY fexpr +[334] fexpr ::= SUM_OF fexpr IN array_expr +[335] iexpr ::= iexpr PLUS iexpr +[336] iexpr ::= iexpr MINUS iexpr +[337] iexpr ::= iexpr TIMES iexpr +[338] iexpr ::= iexpr DIVIDE iexpr +[339] iexpr ::= INTEGER +[340] iexpr ::= MINUS iexpr +[341] iexpr ::= LPAREN iexpr RPAREN +[342] iexpr ::= RLONG +[343] iexpr ::= GET DAYS IN YEAROF dexpr +[344] iexpr ::= GET DAYS IN MONTHS FOR dexpr +[345] iexpr ::= GET DAYS OF MONTHS FOR dexpr +[346] iexpr ::= colonRef RLONG +[347] iexpr ::= LPAREN LONG RPAREN indx_expr +[348] iexpr ::= LPAREN LONG RPAREN strexpr +[349] iexpr ::= LPAREN LONG RPAREN number +[350] iexpr ::= LPAREN LONG RPAREN RTABLE LPAREN tablelist RPAREN +[351] iexpr ::= NUMBEROF array_expr +[352] iexpr ::= NUMBEROF array_expr WHERE bexpr +[353] iexpr ::= LENGTH OF array_expr +[354] iexpr ::= LENGTH OF strexpr +[355] iexpr ::= USING array_expr number +[356] iexpr ::= ADD TO RLONG number +[357] iexpr ::= SUBTRACT FROM RLONG number +[358] iexpr ::= MULTIPLY RLONG BY number +[359] iexpr ::= DIVIDE RLONG BY number +[360] iexpr ::= ABSOLUTEVALUE OF iexpr +[361] iexpr ::= USING eexpr LPAREN iexpr RPAREN +[362] iexpr ::= DAYS FROM dexpr TO dexpr +[363] iexpr ::= MONTHS FROM dexpr TO dexpr +[364] iexpr ::= YEARS FROM dexpr TO dexpr +[365] iexpr ::= GET YEAROF dexpr +[366] iexpr ::= LONG VALUE OF operatorstatements +[367] iexpr ::= SUM_OF iexpr IN array_expr +[368] includeSearch ::= VALUE number +[369] includeSearch ::= DATE dexpr +[370] includeSearch ::= eexpr +[371] includeSearch ::= STRING strexpr +[372] inthe ::= IN +[373] inthe ::= FOR +[374] inthe ::= ON +[375] thereis ::= THERE IS +[376] thereis ::= IS THERE +[377] blist ::= strexpr COMMA blist +[378] blist ::= OR strexpr +[379] bexpr ::= array_expr DOES NOT INCLUDE includeSearch +[380] bexpr ::= array_expr DOES INCLUDE includeSearch +[381] bexpr ::= array_expr INCLUDES includeSearch +[382] bexpr ::= thereis MATCH FORALL array_expr TO nexpr IN array_expr +[383] bexpr ::= thereis eexpr WHERE bexpr +[384] bexpr ::= thereis eexpr inthe eexpr WHERE bexpr +[385] bexpr ::= thereis eexpr inthe array_expr WHERE bexpr +[386] bexpr ::= HASA eexpr WHERE bexpr +[387] bexpr ::= THERE IS NO eexpr WHERE bexpr +[388] bexpr ::= THERE IS NO eexpr inthe eexpr WHERE bexpr +[389] bexpr ::= THERE IS NO eexpr inthe array_expr WHERE bexpr +[390] bexpr ::= ALL array_expr HAVE bexpr +[391] bexpr ::= ONE OF array_expr HASA bexpr +[392] bexpr ::= eexpr DOES NOT HAVE strexpr +[393] bexpr ::= eexpr HASA strexpr +[394] bexpr ::= eexpr HASA strexpr WHERE bexpr +[395] bexpr ::= eexpr IS strexpr OF eexpr +[396] bexpr ::= iexpr eq iexpr +[397] bexpr ::= fexpr eq iexpr +[398] bexpr ::= iexpr eq fexpr +[399] bexpr ::= fexpr eq fexpr +[400] bexpr ::= iexpr neq iexpr +[401] bexpr ::= fexpr neq iexpr +[402] bexpr ::= iexpr neq fexpr +[403] bexpr ::= fexpr neq fexpr +[404] bexpr ::= iexpr gt iexpr +[405] bexpr ::= fexpr gt iexpr +[406] bexpr ::= iexpr gt fexpr +[407] bexpr ::= fexpr gt fexpr +[408] bexpr ::= iexpr gte iexpr +[409] bexpr ::= fexpr gte iexpr +[410] bexpr ::= iexpr gte fexpr +[411] bexpr ::= fexpr gte fexpr +[412] bexpr ::= iexpr lt iexpr +[413] bexpr ::= fexpr lt iexpr +[414] bexpr ::= iexpr lt fexpr +[415] bexpr ::= fexpr lt fexpr +[416] bexpr ::= iexpr lte iexpr +[417] bexpr ::= fexpr lte iexpr +[418] bexpr ::= iexpr lte fexpr +[419] bexpr ::= fexpr lte fexpr +[420] bexpr ::= RBOOLEAN +[421] bexpr ::= colonRef RBOOLEAN +[422] bexpr ::= nexpr eq nexpr +[423] bexpr ::= nexpr eq strexpr +[424] bexpr ::= nexpr neq nexpr +[425] bexpr ::= nexpr neq strexpr +[426] bexpr ::= strexpr eq blist +[427] bexpr ::= strexpr eq strexpr +[428] bexpr ::= strexpr neq strexpr +[429] bexpr ::= strexpr AT iexpr STARTS_WITH strexpr +[430] bexpr ::= strexpr STARTS_WITH strexpr +[431] bexpr ::= strexpr IS ONE OF array_expr +[432] bexpr ::= strexpr IS NOT ONE OF array_expr +[433] bexpr ::= DOES bexpr QUESTIONMARK +[434] bexpr ::= IS bexpr QUESTIONMARK +[435] bexpr ::= WAS bexpr QUESTIONMARK +[436] bexpr ::= strexpr gt strexpr +[437] bexpr ::= strexpr lt strexpr +[438] bexpr ::= strexpr gte strexpr +[439] bexpr ::= strexpr lte strexpr +[440] bexpr ::= strexpr MATCHES strexpr +[441] bexpr ::= bexpr eq bexpr +[442] bexpr ::= bexpr neq bexpr +[443] bexpr ::= bexpr AND bexpr +[444] bexpr ::= bexpr OR bexpr +[445] bexpr ::= NOT bexpr +[446] bexpr ::= dexpr isnull +[447] bexpr ::= array_expr isnull +[448] bexpr ::= strexpr isnull +[449] bexpr ::= eexpr isnull +[450] bexpr ::= dexpr isnotnull +[451] bexpr ::= array_expr isnotnull +[452] bexpr ::= strexpr isnotnull +[453] bexpr ::= eexpr isnotnull +[454] bexpr ::= USING eexpr LPAREN bexpr RPAREN +[455] bexpr ::= LPAREN bexpr RPAREN +[456] bexpr ::= LPAREN BOOLEAN RPAREN indx_expr +[457] bexpr ::= BOOLEAN RARRAY LBRACE iexpr RBRACE +[458] bexpr ::= dexpr eq dexpr +[459] bexpr ::= dexpr lt dexpr +[460] bexpr ::= dexpr IS BEFORE dexpr +[461] bexpr ::= dexpr gt dexpr +[462] bexpr ::= dexpr IS AFTER dexpr +[463] bexpr ::= dexpr gte dexpr +[464] bexpr ::= dexpr lte dexpr +[465] bexpr ::= dexpr IS BETWEEN dexpr AND dexpr +[466] bexpr ::= eexpr eq eexpr +[467] bexpr ::= eexpr neq eexpr +[468] bexpr ::= BOOLEAN VALUE OF operatorstatements +[469] bexpr ::= BOOL_FUNCTION +[470] eq ::= EQ +[471] eq ::= IS EQUAL TO +[472] eq ::= EQUAL TO +[473] neq ::= NEQ +[474] neq ::= IS NOT EQUAL TO +[475] neq ::= NOT EQUAL TO +[476] gt ::= GT +[477] gt ::= IS GREATER THAN +[478] gt ::= GREATER THAN +[479] gte ::= GTE +[480] gte ::= IS GREATER THAN OR EQUAL TO +[481] gte ::= GREATER THAN OR EQUAL TO +[482] lt ::= LT +[483] lt ::= IS LESS THAN +[484] lt ::= LESS THAN +[485] lte ::= LTE +[486] lte ::= IS LESS THAN OR EQUAL TO +[487] lte ::= LESS THAN OR EQUAL TO +[488] isnull ::= ISNULL +[489] isnull ::= IS NULL +[490] isnotnull ::= ISNOTNULL +[491] isnotnull ::= IS NOT NULL + +------- CUP v0.11a beta 20060608 Parser Generation Summary ------- + 0 errors and 1 warning + 163 terminals, 71 non-terminals, and 492 productions declared, + producing 1246 unique parse states. + 1 terminal declared but not used. + 0 non-terminal declared but not used. + 0 productions never reduced. + 0 conflicts detected (0 expected). + Code written to "nul:.java", and "nul:.java". +---------------------------------------------------- (v0.11a beta 20060608) + \ No newline at end of file diff --git a/DTParser/src/main/java/com/dtrules/compiler/cup/copyright.txt b/DTParser/src/main/java/com/dtrules/compiler/cup/copyright.txt new file mode 100644 index 0000000..44bed3d --- /dev/null +++ b/DTParser/src/main/java/com/dtrules/compiler/cup/copyright.txt @@ -0,0 +1,16 @@ +/** + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + \ No newline at end of file diff --git a/DTParser/src/main/java/com/dtrules/compiler/cup/parser.cup b/DTParser/src/main/java/com/dtrules/compiler/cup/parser.cup new file mode 100644 index 0000000..ecb30be --- /dev/null +++ b/DTParser/src/main/java/com/dtrules/compiler/cup/parser.cup @@ -0,0 +1,1158 @@ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.compiler.cup; + +import java.util.*; +import java.io.*; +import java_cup.runtime.*; + +action code {: + + public String left (java.util.Stack stack) { + return ((RSymbol)stack.peek()).leftvalue; + } + + public void notlocal(java.util.Stack stack){ + Symbol v = (Symbol) stack.peek(); + if(v instanceof RSymbol && ((RSymbol)v).local){ + throw new RuntimeException("The Local Variable "+((RSymbol)v).rightvalue+" is being referenced improperly"); + } + } + /** + * Provides the original text for the right side. + **/ + public String rv(java.util.Stack stack){ + return ((RSymbol)stack.peek()).rightvalue; + } +:}; + +parser code {: + + public int localCnt = 0; + + public HashMap localtypes = new HashMap(); + + public void report_error(String message, Object info){} + + public final int + iBoolean = 0, + iString = 1, + iInteger = 2, + iDouble = 3, + iEntity = 4, + iName = 5, + iArray = 6, + iDecisiontable = 7, + iNull = 8, + iMark = 9, + iOperator = 10, + iTime = 11, + iTable = 12, + iXmlValue = 13; + /** + * Adds a symbol to the local variable hash, and + * returns allocation code for the local variable. + **/ + public String newLocal(String v, int type, String initialValue){ + v = v.toLowerCase(); + RLocalType t = new RLocalType(); + t.name = v; + t.index = localCnt++; + t.type = type; + localtypes.put(v,t); + if(initialValue != null){ + return initialValue + "allocate execute deallocate pop "; + }else{ + return "null allocate execute "; + } + } + +:}; + + +/* Terminals (tokens returned by the scanner). */ +terminal String ABSOLUTEVALUE, ACTION, ADD, AFTER, ALL, ALLOWING, AND, ARRAY, + ARRAY_OF_VALUES, ARROW, ASCENDINGORDER, ASSIGN, ATTRIBUTE, + AT, BEFORE, + BETWEEN, BOOL_FUNCTION, BOOLEAN, BY, CACHE, CHANGE, CLEAR, + CLONE, COLON, CONTEXT, COMMA, CONDITION, COPY, CURRENT_DATE, + CURRENT_TIMESTAMP, DATE, DAYS, DEBUG, DECIMAL_PLACES, + DECREMENT, DESCENDINGORDER, DIVIDE, DOES, DOUBLE, EACH, + EARLIEST, ELEMENT, ELSE, ELSEIF, ELSEIFNONEAREFOUND, END, + ENDIF, ENTITY, EQ, EQUAL, ERRORCODE, FIRST, FLOAT, FOR, + FORALL, FROM, GET, GREATER, GT, GTE, HASA, HAVE, IF, IN, + INCLUDE, INCLUDES, INCREMENT, INTEGER, IS, ISNOTNULL, + ISNULL, ITS, LBRACE, LCURLY, LENGTH, LESS, LOCAL, LONG, + LOWER_CASE, LPAREN, LT, LTE, MAP, MATCH, MATCHES, MEMBER, + MINUS, MONTHS, + MULTIPLY, NAME, NAMEOF, NEQ, NEW, NO, NOT, NULL, NUMBEROF, + OF, ON, ONE, OR, PERFORM, PLUS, POSSESSIVE, QUESTIONMARK, + RANDOMIZE, RARRAY, RBOOLEAN, RBRACE, RCURLY, RDATE, + RDECISIONTABLE, RDOUBLE, RELATIONSHIP_BETWEEN, + REMOVE, RENTITY, + RINVALID, RLONG, RNAME, RNULL, ROPERATOR, ROUNDED, RPAREN, + RSTRING, RTABLE, RXMLVALUE, SEMI, SET, SORT, STARTS_WITH, STR, + STRING, SUBSTRING, SUBTRACT, SUM_OF, TABLE, TABLEINFORMATION, + THAN, THEN, THENAME, THERE, THIS, TIMES, THROUGH, TO, + TOBEREMOVED, + TOKENIZE, TRIM, UMINUS, UNDEFINED, UPPER_CASE, USING, VALUE, + WAS, WHERE, WITH, WITH_BOUNDRY, YEARS, YEAROF; + +terminal String IDENT; // This one is used by the Lexical Analyzer, so it is + // unreferrenced in the parser. We still need it. + +/* Non terminals */ +non terminal String eq, neq, gt,gte,lt,lte; + +non terminal String done, statement_list, statement; +non terminal String number; +non terminal String inthe; +non terminal String iexpr, fexpr, bexpr, eexpr, nexpr, texpr, strexpr, indx_expr; +non terminal String dexpr; +non terminal String array_expr, + isnull, + isnotnull; +non terminal String includeSearch; + + +non terminal String forblock; +non terminal String forallblock; + +non terminal String forallctl, forfirstctl; +non terminal String ifblock; +non terminal String usingblock; +non terminal String firstblock; +non terminal String block; +non terminal String thereis; + + +non terminal String setstatement; +non terminal String usingstatement; +non terminal String performstatement; +non terminal String debugstatement; +non terminal String ifstatement; +non terminal String addtostatement, addtodest, subtodest; +non terminal String clearstatement; +non terminal String randomstatements; +non terminal String commonerror; +non terminal String tablelist; +non terminal String operatorlist; +non terminal String operatorstatements; +non terminal String contextstatement; +non terminal String localvariables; +non terminal String context_for_table; +non terminal String datestatement; +non terminal String xmlvaluestatements; +non terminal String separator; + + +non terminal String blist; + +non terminal String ifcontinue, + left_iexpr, + left_fexpr, + left_bexpr, + left_eexpr, + left_strexpr, + left_dexpr, + left_ArrayRef, + left_texpr, + usingEntityRef, + colonRef, + possessiveRef, + array_lit, + array_list; + + +/** + ** Maximus Example Terminal and non terminal Declarations + ** + **/ +terminal String MAXPRINT; +non terminal String maximusstatements, + parameterlist; + + +/* Precedences */ + +precedence left RARRAY,RLONG,RBOOLEAN,RENTITY,RSTRING; +precedence right SEMI, ACTION, WHERE, OF; +precedence left ASSIGN,RCURLY,LCURLY; +precedence left LBRACE, RBRACE, FORALL; +precedence left IF, THEN, ELSE, ENDIF; +precedence left OR, COMMA, DEBUG; +precedence left AND; +precedence left EQ,NEQ,GT,LT,GTE,LTE,ISNULL,ISNOTNULL; +precedence right ROUNDED, TO; +precedence left PLUS, MINUS; +precedence left TIMES, DIVIDE; +precedence left IS, NOT, EQUAL, UMINUS, LPAREN, RPAREN, TRIM, STRING; +precedence left USING, POSSESSIVE, COLON, ARROW; + + + + +/* The grammar */ + + + + +done ::= ACTION statement_list:e {: RESULT = "\n"+e+"\n"; :} + | + CONDITION bexpr:e SEMI {: RESULT = "\n"+e+"\n"; :} + | + CONDITION debugstatement:d SEMI bexpr:e SEMI {: RESULT = "\n"+d+e+"\n"; :} + | + CONDITION bexpr:e SEMI debugstatement:d SEMI {: RESULT = "\n"+e+d+"\n"; :} + | + CONTEXT context_for_table:e SEMI {: RESULT = "\n"+e+"\n"; :} + ; + +statement_list ::= statement_list:e1 block:e2 {: RESULT = e1+e2; :} | + block:e {: RESULT = e; :} ; + +separator ::= SEMI | COMMA ; + +statement ::= setstatement:e separator {: RESULT = e; :} | + performstatement:e separator {: RESULT = e; :} | + debugstatement:e separator {: RESULT = e; :} | + ifstatement:e separator {: RESULT = e; :} | + addtostatement:e separator {: RESULT = e; :} | + clearstatement:e separator {: RESULT = e; :} | + usingstatement:e separator {: RESULT = e; :} | + randomstatements:e separator {: RESULT = e; :} | + commonerror:e separator {: RESULT = e; :} | + maximusstatements:e separator {: RESULT = e; :} | + operatorstatements:e separator {: RESULT = e; :} | + contextstatement:e separator {: RESULT = e; :} | + datestatement:e separator {: RESULT = e; :} | + xmlvaluestatements:e separator {: RESULT = e; :} | + separator {: RESULT = ""; :} ; // Allow the null statement + +parameterlist ::= + AND parameterlist:l {: RESULT = l; :} | + strexpr:s COMMA parameterlist:l {: RESULT = s+l+"strconcat "; :} | + iexpr:i COMMA parameterlist:l {: RESULT = i+l+"strconcat "; :} | + fexpr:f COMMA parameterlist:l {: RESULT = f+l+"strconcat "; :} | + eexpr:e COMMA parameterlist:l {: RESULT = e+"entityname "+l+"strconcat "; :} | + strexpr:s {: RESULT = s; :} | + iexpr:i {: RESULT = i; :} | + fexpr:f {: RESULT = f; :} | + eexpr:e {: RESULT = e+"entityname "; :} ; + +maximusstatements ::= + MAXPRINT parameterlist:l {: RESULT = l+"printmessage "; :} | + SET ERRORCODE nexpr:n {: RESULT = "/actioncomment getdescription def " + + "/errorcode "+n+"def set_error_code "; :} | + SET ERRORCODE nexpr:n WITH strexpr:s + {: RESULT = "/actioncomment getdescription def " + + "/errorcode "+n+"def " + + "/errormsg " +s+"def set_error_code "; :} | + SET ERRORCODE array_expr:a WITH strexpr:s + {: RESULT = "{ /errorcode xdef "+ + "/actioncomment getdescription def " + + "/errormsg " +s+"def set_error_code "+ + "} "+a+"for "; :} ; + + + +usingblock ::= usingEntityRef:ee usingblock:e {: RESULT = ee + "entitypush "+e+"entitypop "; :} | + usingEntityRef:ee COMMA usingblock:e {: RESULT = ee + "entitypush "+e+"entitypop "; :} | + block:e {: RESULT = e; :} ; + +// To make this work, the token filter has to inject a token after every possessive parsed, and +// I chose a COMMA for that token +possessiveRef ::= POSSESSIVE:e1 COMMA possessiveRef:e2 {: RESULT = e1 +" entitypush "+e2+"entitypop "; :} | + POSSESSIVE:e COMMA {: RESULT = e+" "; :} | + RENTITY:e1 ARROW possessiveRef:e2 {: RESULT = e1 +" entitypush "+e2+"entitypop "; :} | + RENTITY:e ARROW {: RESULT = e; :} | + COLON RENTITY:e1 COLON possessiveRef:e2 {: RESULT = e1 +" entitypush "+e2+"entitypop "; :} | + COLON RENTITY:e1 COLON {: RESULT = e1 +" "; :} ; + +colonRef ::= possessiveRef:e {: RESULT = e; :} ; + +forallblock ::= block:blk forallctl:ctl + {: RESULT = "{ "+blk+"} "+ctl+"pop "; :}; + +context_for_table ::= forallctl:ctl {: RESULT = ctl+"pop "; :} | + forfirstctl:ctl {: RESULT = ctl+"pop "; :} | + contextstatement:c {: RESULT = c +"execute entitypop "; :} | + localvariables:v {: RESULT = v; :} ; + +localvariables ::= + LOCAL ENTITY UNDEFINED:v {: RESULT = parser.newLocal(v, parser.iEntity, null); :} | + LOCAL ENTITY UNDEFINED:v ASSIGN eexpr:e {: RESULT = parser.newLocal(v, parser.iEntity, e); :} | + LOCAL ENTITY RENTITY:v {: if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); :} | + + LOCAL LONG UNDEFINED:v {: RESULT = parser.newLocal(v, parser.iInteger, null); :} | + LOCAL LONG UNDEFINED:v ASSIGN number:e {: RESULT = parser.newLocal(v, parser.iInteger, e); :} | + LOCAL LONG RLONG:v {: if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); :} | + + LOCAL DOUBLE UNDEFINED:v {: RESULT = parser.newLocal(v, parser.iDouble, null); :} | + LOCAL DOUBLE UNDEFINED:v ASSIGN number:e {: RESULT = parser.newLocal(v, parser.iDouble, e); :} | + LOCAL DOUBLE RDOUBLE:v {: if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); :} | + + LOCAL BOOLEAN UNDEFINED:v {: RESULT = parser.newLocal(v, parser.iBoolean, null); :} | + LOCAL BOOLEAN UNDEFINED:v ASSIGN bexpr:e {: RESULT = parser.newLocal(v, parser.iBoolean, e); :} | + LOCAL BOOLEAN RBOOLEAN:v {: if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); :} | + + LOCAL DATE UNDEFINED:v {: RESULT = parser.newLocal(v, parser.iTime, null); :} | + LOCAL DATE UNDEFINED:v ASSIGN dexpr:e {: RESULT = parser.newLocal(v, parser.iTime, e); :} | + LOCAL DATE RDATE:v {: if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); :} | + + LOCAL ARRAY UNDEFINED:v {: RESULT = parser.newLocal(v, parser.iArray, null); :} | + LOCAL ARRAY UNDEFINED:v ASSIGN array_expr:e {: RESULT = parser.newLocal(v, parser.iArray, e); :} | + LOCAL ARRAY RARRAY:v {: if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); :} | + + LOCAL STRING UNDEFINED:v {: RESULT = parser.newLocal(v, parser.iString, null); :} | + LOCAL STRING UNDEFINED:v ASSIGN strexpr:e {: RESULT = parser.newLocal(v, parser.iString, e); :} | + LOCAL STRING RSTRING:v {: if(true)throw new RuntimeException( + "The variable '"+rv(CUP$DTRulesParser$stack)+"' is already defined"); :} ; + + +// Only use the IF statement in extreme circumstances. +ifstatement ::= + IF bexpr:b THEN block:blk1 ENDIF {: RESULT = "{ "+blk1+"} " +b+ "if " ; :} | + IF bexpr:b THEN block:blk1 ELSE block:blk2 ENDIF {: RESULT = "{ "+blk1+"} { "+blk2+"} }" +b+ "ifelse "; :} ; + +// The Control statements assume the object that should be executed as +// described by the following statements, and that object should be left on the stack +forallctl ::= + FORALL eexpr AND ITS eexpr:e2 IN array_expr:a + {: RESULT = "{ "+e2+"entitypush dup execute entitypop } "+a+" forall "; :} + | + FORALL eexpr AND ITS eexpr:e2 IN array_expr:a ALLOWING array_expr TOBEREMOVED + {: RESULT = "{ "+e2+"entitypush dup execute entitypop } "+a+" forallr "; :} + | + FORALL eexpr AND ITS eexpr:e2 IN array_expr:a WHERE bexpr:b + {: RESULT = "{ "+e2+"entitypush dup "+b+"if entitypop } "+a+"forall "; :} + | + FORALL eexpr AND ITS eexpr:e2 IN array_expr:a WHERE bexpr:b ALLOWING array_expr TOBEREMOVED + {: RESULT = "{ "+e2+"entitypush dup "+b+"if entitypop } "+a+"forallr "; :} + | + FORALL array_expr:a + {: RESULT = "dup "+a+"forall "; :} + | + FORALL array_expr:a ALLOWING array_expr TOBEREMOVED + {: RESULT = "dup "+a+"forallr "; :} + | + FORALL array_expr:a IN eexpr:ev + {: RESULT = "dup "+ev+" entitypush "+a+"forall entitypop "; :} + | + FORALL array_expr:a IN eexpr:ev ALLOWING array_expr TOBEREMOVED + {: RESULT = "dup "+ev+" entitypush "+a+"forallr entitypop "; :} + | + FORALL array_expr:a IN eexpr:e2 WHERE bexpr:b + {: RESULT = "{ dup "+b+"if } "+e2+" entitypush "+a+"forall entitypop "; :} + | + FORALL array_expr:a WHERE bexpr:b + {: RESULT = "{ dup "+b+"if } "+a+"forall "; :} + | + FORALL array_expr:a WHERE bexpr:b ALLOWING array_expr TOBEREMOVED + {: RESULT = "{ dup "+b+"if } "+a+"forallr "; :} + ; + +forblock ::= + + array_expr:a block:blk + {: RESULT = "{ "+blk+"} "+a+"forallr "; :} + | + eexpr:ev IN array_expr:a block:blk + {: RESULT = "{ "+blk+"} "+a+" forallr "; :} + | + eexpr:e2 IN array_expr:a WHERE bexpr:b block:blk + {: RESULT = "{ { "+blk+" } "+b+"if } "+a+"forallr "; :} + | + array_expr:a WHERE bexpr:b block:blk + {: RESULT = "{ { "+blk+" } "+b+"if } "+a+"forallr "; :} + | + eexpr AND ITS eexpr:e2 IN array_expr:a block:blk + {: RESULT = "{ "+e2+"entitypush "+blk+" entitypop } "+a+" forallr "; :} + | + eexpr AND ITS eexpr:e2 IN array_expr:a WHERE bexpr:b block:blk + {: RESULT = "{ "+e2+"entitypush { "+blk+" } "+b+"if entitypop } "+a+"forallr "; :} + ; + + + +// Takes the "Then" clause on the data stack. +forfirstctl ::= FOR FIRST OF array_expr:a WHERE bexpr:test + {: RESULT = "dup { "+test+" } "+a+" forfirst "; :} + | + FOR FIRST OF array_expr:a AND ITS eexpr:e1 WHERE bexpr:test + {: RESULT = "{ "+e1+" entitypush dup execute entitypop } { "+e1+" entitypush "+test+" entitypop } "+a+" forfirst "; :} + | + FOR FIRST IN array_expr:a WHERE bexpr:test + {: RESULT = "dup { "+test+" } "+a+" forfirst "; :} ; + + +firstblock ::= FOR FIRST OF array_expr:a WHERE bexpr:test THEN block:body1 ELSEIFNONEAREFOUND block:body2 + {: RESULT = "{ "+body1+" } { "+body2+" } { "+test+" } "+a+" forfirstelse "; :} + | + FOR FIRST OF array_expr:a AND ITS eexpr:e1 WHERE bexpr:test THEN block:body1 ELSEIFNONEAREFOUND block:body2 + {: RESULT = "{ "+e1+" entitypush "+body1+"entitypop } { "+body2+" } { "+e1+" entitypush "+test+"entitypop } "+a+" forfirstelse "; :} + | + forfirstctl:ctl THEN block:body + {: RESULT = "{ "+body+" } "+ctl+ "pop "; :} + ; + + + +block ::= LCURLY statement_list:e RCURLY {: RESULT = e+"\n"; :} | + USING usingblock:e {: RESULT = e; :} | + forallblock:e {: RESULT = e; :} | + FORALL forblock:e {: RESULT = e; :} | + firstblock:e {: RESULT = e; :} | + IF ifblock:e {: RESULT = e; :} | + block:e separator {: RESULT = e; :} | + statement:e {: RESULT = e; :} ; + + + +usingstatement ::= USING usingblock:ee separator {: RESULT = ee ; :} ; + +/** + * Because we also have local variables, we let the tokenizer pick the code used to + * popluate the value of a left side expression. + **/ +left_iexpr ::= RLONG:v {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_iexpr:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; +left_fexpr ::= RDOUBLE:v {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_fexpr:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; +left_bexpr ::= RBOOLEAN:v {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_bexpr:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; +left_eexpr ::= RENTITY:v {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_eexpr:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; +left_strexpr ::= RSTRING:v {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_strexpr:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; +left_dexpr ::= RDATE:v {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_dexpr:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; +left_texpr ::= RTABLE:v {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_texpr:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; + +// +// Punt on type checking on values assigned to typed arrays. +// +left_ArrayRef ::= RARRAY:a {: RESULT = left(CUP$DTRulesParser$stack); :} | + colonRef:e left_ArrayRef:v {: notlocal(CUP$DTRulesParser$stack); RESULT = e+"entitypush "+v+"entitypop "; :} ; + +setstatement ::= SET left_iexpr:v ASSIGN number:e {: RESULT = e+"cvi "+v; :} | + SET left_fexpr:v ASSIGN number:e {: RESULT = e+"cvr "+v; :} | + SET left_bexpr:v ASSIGN bexpr:e {: RESULT = e+"cvb "+v; :} | + SET left_eexpr:v ASSIGN eexpr:e {: RESULT = e+"cve "+v; :} | + SET left_strexpr:v ASSIGN strexpr:e {: RESULT = e+"cvs "+v; :} | + SET left_bexpr:v ASSIGN nexpr:e {: RESULT = e+"cvb "+v; :} | + SET left_dexpr:v ASSIGN dexpr:e {: RESULT = e+"cvd "+v; :} | + SET left_texpr:v ASSIGN texpr:e {: RESULT = e+"cvd "+v; :} | + + SET left_ArrayRef:v ASSIGN eexpr:e {: RESULT = e+v; :} | + SET left_ArrayRef:v ASSIGN strexpr:e {: RESULT = e+v; :} | + SET left_ArrayRef:v ASSIGN fexpr:e {: RESULT = e+v; :} | + SET left_ArrayRef:v ASSIGN iexpr:e {: RESULT = e+v; :} | + SET left_ArrayRef:v ASSIGN dexpr:e {: RESULT = e+v; :} | + SET left_ArrayRef:v ASSIGN array_expr:e {: RESULT = e+v; :} | + + INCREMENT RLONG:v {: RESULT = "/"+v+" "+v+" 1 ladd def "; :} | + INCREMENT RDOUBLE:v {: RESULT = "/"+v+" "+v+" 1 dadd def "; :} | + DECREMENT RLONG:v {: RESULT = "/"+v+" "+v+" 1 lsub def "; :} | + DECREMENT RDOUBLE:v {: RESULT = "/"+v+" "+v+" 1 dsub def "; :} + ; + + + + +performstatement ::= + RDECISIONTABLE:dt {: RESULT = dt; :} | + PERFORM RDECISIONTABLE:dt {: RESULT = dt; :} | + PERFORM NAME:dt {: RESULT = dt; :} ; + + + +debugstatement ::= + DEBUG strexpr:s {: RESULT = s+"debug "; :} | + DEBUG bexpr:s {: RESULT = s+"debug "; :} | + DEBUG iexpr:s {: RESULT = s+"debug "; :} | + DEBUG fexpr:s {: RESULT = s+"debug "; :} | + DEBUG eexpr:s {: RESULT = s+"debug "; :} | + DEBUG dexpr:s {: RESULT = s+"debug "; :} | + DEBUG array_expr:s {: RESULT = s+"debug "; :} ; + + +ifblock ::= bexpr:b THEN statement_list:e1 ifcontinue:e2 + {: if(e2.trim().length()>0) { + RESULT= "{ "+e1+"} {"+e2+"} "+b+"ifelse "; + }else{ + RESULT= "{ "+e1+"} "+b+"if "; + } + :}; + +ifcontinue ::= ENDIF {: RESULT=""; :} | + ELSE statement_list:e1 ENDIF {: RESULT=e1; :} | + ELSEIF ifblock:e {: RESULT=e; :} ; + + + +/* +basictype ::= + LONG:v {: RESULT = v+" "; :} | + DOUBLE:v {: RESULT = v+" "; :} | + STRING:v {: RESULT = v+" "; :} | + NAME:v {: RESULT = v+" "; :} | + RLONG:v {: RESULT = v+" "; :} | + RNULL:v {: RESULT = v+" "; :} | + RDOUBLE:v {: RESULT = v+" "; :} | + RSTRING:v {: RESULT = v+" "; :} | + RDATE:v {: RESULT = v+" "; :} | + RBOOLEAN:v {: RESULT = v+" "; :} | + RENTITY:v {: RESULT = v+" "; :} | + RDECISIONTABLE:v {: RESULT = v+" "; :} | + RNAME:v {: RESULT = v+" "; :} + ; +*/ +number ::= iexpr:v {: RESULT = v+" "; :} | + fexpr:v {: RESULT = v+" "; :} + ; + + + + +/** Array types **/ + +addtodest ::= array_expr:a {: RESULT = a+"swap addto "; :} | + RLONG:a {: RESULT = a+" + /" +a+" xdef "; :} | + RDOUBLE:a {: RESULT = a+" fadd /" +a+" xdef "; :} ; + +subtodest ::= RLONG:a {: RESULT = a+" swap - /" +a+" xdef "; :} | + RDOUBLE:a {: RESULT = a+" swap f- /" +a+" xdef "; :} ; + + +addtostatement ::= + ADD array_expr:a1 TO array_expr:a2 {: RESULT =a1+a2+"false addarray "; :} | + + ADD eexpr:e TO addtodest:a {: RESULT =e+a; :} | + ADD eexpr:e TO addtodest:a AND TO addtodest:a2 + {: RESULT =e+"dup "+a+a2; :} | + ADD strexpr:e TO addtodest:a {: RESULT =e+a; :} | + ADD strexpr:e TO addtodest:a AND TO addtodest:a2 + {: RESULT =e+"dup "+a+a2; :} | + ADD dexpr:e TO addtodest:a {: RESULT =e+a; :} | + ADD dexpr:e TO addtodest:a AND TO addtodest:a2 + {: RESULT =e+"dup "+a+a2; :} | + ADD number:v TO addtodest:a {: RESULT =v+a ; :} | + ADD number:v TO addtodest:a AND TO addtodest:a2 + {: RESULT =v+"dup "+a+a2; :} | + + SUBTRACT number:v FROM subtodest:a {: RESULT =v+a ; :} | + + ADD eexpr:e IF NOT MEMBER TO array_expr:a {: RESULT =a+" "+e+"add_no_dups "; :} | + ADD eexpr:e IF NOT MEMBER TO array_expr:a AND TO array_expr:a2 + {: RESULT =e+a+"over add_no_dups "+a2+"swap add_no_dups "; :} | + ADD strexpr:e IF NOT MEMBER TO array_expr:a {: RESULT =a+" "+e+"add_no_dups "; :} | + ADD strexpr:e IF NOT MEMBER TO array_expr:a AND TO array_expr:a2 + {: RESULT =e+a+"over add_no_dups "+a2+"swap add_no_dups "; :} ; + +contextstatement ::= + ADD eexpr:e TO CONTEXT OF THIS TABLE {: RESULT =e+"entitypush "; :} | + ADD eexpr:e TO CONTEXT FOR THIS TABLE {: RESULT =e+"entitypush "; :} ; + + + //"sortentities" Signature: + // ( array field boolean -- ) +randomstatements ::= + REMOVE iexpr:i ELEMENT FROM array_expr:a ARRAY {: RESULT = a+i+"removeat pop "; :} | + REMOVE EACH eexpr:e FROM array_expr:a WHERE bexpr:b {: RESULT = a+"{ { dup 0 entityfetch remove pop } "+b+"if } over forallr pop"; :} | + REMOVE nexpr:i FROM array_expr:a ARRAY {: RESULT = a+i+"remove pop "; :} | + REMOVE eexpr:i FROM array_expr:a ARRAY {: RESULT = a+i+"remove pop "; :} | + RANDOMIZE array_expr:a {: RESULT = a+"randomize "; :} | + CLEAR array_expr:a {: RESULT = a+"clear "; :} | + REMOVE eexpr:i FROM CACHE {: RESULT = i+"flushbyid "; :} | + SORT array_expr:a IN ASCENDINGORDER BY nexpr:f {: RESULT = a+f+"true sortentities "; :} | + SORT array_expr:a IN DESCENDINGORDER BY nexpr:f {: RESULT = a+f+"false sortentities "; :} ; + + +operatorlist ::= strexpr:s COMMA operatorlist:l {: RESULT = l+s; :} | + iexpr:i COMMA operatorlist:l {: RESULT = l+i; :} | + fexpr:f COMMA operatorlist:l {: RESULT = l+f; :} | + eexpr:e COMMA operatorlist:l {: RESULT = l+e; :} | + strexpr:s {: RESULT = s; :} | + iexpr:i {: RESULT = i; :} | + fexpr:f {: RESULT = f; :} | + eexpr:e {: RESULT = e; :} ; + +operatorstatements ::= + ROPERATOR:op LPAREN operatorlist:l RPAREN {: RESULT = l+" "+op+" "; :} ; + + // start_date: set the attribute "error" = "Invalid blah blah" +xmlvaluestatements ::= + RXMLVALUE:t COLON SET ATTRIBUTE strexpr:s1 ASSIGN strexpr:s2 {: RESULT = t+" "+s1+s2+"setXmlAttribute "; :} ; + +// Array expressions + +array_expr ::= + MAP array_expr:a THROUGH texpr:t {: RESULT = t+a+"false translate "; :} | + LPAREN array_expr:a RPAREN {: RESULT = a; :} | + RARRAY:e {: RESULT = e+" "; :} | + LPAREN ARRAY RPAREN NAME:n {: RESULT = n+" "; :} | + colonRef:e RARRAY:v {: RESULT = e+"entitypush "+v+" entitypop "; :} | + GET COPY OF array_expr:e {: RESULT = e+"copyelements "; :} | + COPY OF array_expr:e {: RESULT = e+"copyelements "; :} | + NEW ENTITY ARRAY {: RESULT = "/entity newtypedarray "; :} | + NEW STR ARRAY {: RESULT = "/string newtypedarray "; :} | + array_lit:l {: RESULT = l; :} | + ARRAY_OF_VALUES LBRACE array_list:e RBRACE {: RESULT = "mark "+e+" arraytomark "; :} | + TOKENIZE strexpr:s1 BY strexpr:s2 {: RESULT = s1+s2+"tokenize "; :} ; + +array_lit ::= LBRACE array_list:l RBRACE {: RESULT = "{ "+l+"} "; :} ; + +array_list ::= array_list:l COMMA strexpr:s {: RESULT = l+s; :} | + array_list:l COMMA iexpr:s {: RESULT = l+s; :} | + array_list:l COMMA eexpr:s {: RESULT = l+s; :} | + array_list:l COMMA fexpr:s {: RESULT = l+s; :} | + array_list:l COMMA nexpr:s {: RESULT = l+s; :} | + nexpr:s {: RESULT = s; :} | + fexpr:s {: RESULT = s; :} | + eexpr:s {: RESULT = s; :} | + iexpr:s {: RESULT = s; :} | + strexpr:s {: RESULT = s; :} ; + + +indx_expr ::= + array_expr:ra LBRACE iexpr:ie1 RBRACE {: RESULT = ra + ie1 + "getat "; :} ; + + + + +// Entity expressions +eexpr ::= RENTITY:e {: RESULT = e+" "; :} | + LPAREN eexpr:e RPAREN {: RESULT = e; :} | + indx_expr:ie {: RESULT = ie; :} | + NEW nexpr:n ENTITY {: RESULT = n+ " createentity "; :} | + NEW RENTITY:n ENTITY {: RESULT = "/"+n + " createentity "; :} | + CLONE OF eexpr:e {: RESULT = e+ "clone "; :} | + colonRef:e1 RENTITY:e2 {: RESULT = e1 +"entitypush "+e2+" entitypop "; :} | + LPAREN ENTITY RPAREN RTABLE:t LPAREN tablelist:keys RPAREN + {: RESULT = t + " " + keys + "lookup "; :} | + + FIRST eexpr:e IN array_expr:a WHERE bexpr:b {: RESULT = "{ "+e+"} { null } { "+b+"} "+a+"forfirstelse "; :} | + FIRST eexpr:e WHERE bexpr:b {: RESULT = "{ "+e+"} { null } { "+b+"} "+e.trim()+"s forfirstelse "; :} | + + // relationship Relationship Syntax + strexpr:s OF eexpr:e {: RESULT = "{ source } { null } { "+s+"type == } forfirstelse "; :} ; + + +datestatement ::= + SUBTRACT number:i YEARS FROM RDATE:v {: RESULT = v +" "+ i +"negate addyears /"+v+" xdef "; :} | + SUBTRACT number:i MONTHS FROM RDATE:v {: RESULT = v +" "+ i +"negate addmonths /"+v+" xdef "; :} | + SUBTRACT number:i DAYS FROM RDATE:v {: RESULT = v +" "+ i +"negate adddays /"+v+" xdef "; :} | + ADD number:i YEARS TO RDATE:v {: RESULT = v +" "+ i +"addyears /"+v+" xdef "; :} | + ADD number:i MONTHS TO RDATE:v {: RESULT = v +" "+ i +"addmonths /"+v+" xdef "; :} | + ADD number:i DAYS TO RDATE:v {: RESULT = v +" "+ i +"adddays /"+v+" xdef "; :} ; + +// Date expressions + +dexpr ::= LPAREN dexpr:e RPAREN {: RESULT = e+" "; :} | + RDATE:e {: RESULT = e+" "; :} | + LPAREN DATE RPAREN strexpr:s {: RESULT = s+"newdate "; :} | + DATE LPAREN strexpr:s RPAREN {: RESULT = s+"newdate "; :} | + LPAREN DATE RPAREN indx_expr:ie {: RESULT = ie; :} | + LPAREN DATE RPAREN RARRAY:ra LBRACE iexpr:ie1 RBRACE {: RESULT = ra+" "+ie1+"getat "; :} | + USING eexpr:ee LPAREN dexpr:e RPAREN {: RESULT = ee + "entitypush "+e+"entitypop "; :} | + colonRef:e1 RDATE:d {: RESULT = e1 +"entitypush "+d+" entitypop "; :} | + LPAREN number:n DAYS RPAREN {: RESULT = n +"days "; :} | + dexpr:d1 PLUS dexpr:d2 {: RESULT = d1 +d2+"d+ "; :} | + dexpr:d1 MINUS dexpr:d2 {: RESULT = d1 +d2+"d- "; :} | + LPAREN DATE RPAREN RTABLE:t LPAREN tablelist:keys RPAREN + {: RESULT = t + " " + keys + "lookup "; :} | + SUBTRACT number:i YEARS FROM dexpr:v {: RESULT = v +" "+i +"negate addyears "; :} | + SUBTRACT number:i MONTHS FROM RDATE:v {: RESULT = v +" "+ i +"negate addmonths "; :} | + SUBTRACT number:i DAYS FROM RDATE:v {: RESULT = v +" "+ i +"negate adddays "; :} | + ADD number:i YEARS TO RDATE:v {: RESULT = v +" "+ i +"addyears "; :} | + ADD number:i MONTHS TO RDATE:v {: RESULT = v +" "+ i +"addmonths "; :} | + ADD number:i DAYS TO RDATE:v {: RESULT = v +" "+ i +"adddays "; :} | + + +//We match MONTHS and YEARS to both plural and singular + FIRST OF YEARS OF dexpr:d {: RESULT = d + "firstofyear "; :} | + FIRST OF MONTHS OF dexpr:d {: RESULT = d + "firstofmonth "; :} | + END OF MONTHS OF dexpr:d {: RESULT = d + "endofmonth "; :} | + + // the earliest cutoffdate after the currentdate; + // The postfix is a bit complicated. I sort the array in decending order, then (starting with + // the given date) I run through all the dates in the list, and keeping only the dates after + // the given date. The one remaining is the last one, the earliest greater than the given date. + // I use the control stack to make the logic a bit easier to follow. + EARLIEST OF array_expr:a AFTER dexpr:d {: RESULT = d + "dup >r { { pop pop i i } over i > if pop } "+a+"dup false sortarray for r> pop "; :} ; + +// Name expressions +nexpr ::= RNAME:n {: RESULT = n+" "; :} | + NAMEOF eexpr:e {: RESULT = e+"getname "; :} | + THENAME strexpr:s {: RESULT = s+"cvn "; :} | + NAME RARRAY:ra LBRACE iexpr:ie1 RBRACE {: RESULT = ra+" "+ie1+"getat "; :} | + NAME:n {: RESULT = "/"+n+" "; :} | + + USING eexpr:ee LPAREN nexpr:e RPAREN {: RESULT = ee + "entitypush "+e+"entitypop "; :} | + colonRef:e1 RNAME:n {: RESULT = e1 +"entitypush "+n+" entitypop "; :} | + LPAREN NAME RPAREN strexpr:s {: RESULT = s+"cvn "; :} ; + + + +tablelist ::= strexpr:s COMMA tablelist:t {: RESULT = s+t; :} + | + strexpr:s {: RESULT = s; :} ; + +texpr ::= RTABLE:t {: RESULT = t+" "; :} | + NEW strexpr TABLE OF strexpr:s + {: /**c**/ :}; + +strexpr ::= + RXMLVALUE:s {: RESULT = s+" cvs "; :} + | + RXMLVALUE:t COLON GET ATTRIBUTE strexpr:s + {: RESULT = t+s+"getXmlAttributeValue "; :} + | + SUBSTRING OF strexpr:s FROM iexpr:start TO iexpr:end + {: RESULT = end+start+s+"substring "; :} + | + TABLEINFORMATION {: RESULT = "actionstring "; :} + | + STRING VALUE OF operatorstatements:o + {: RESULT = o +"cvs "; :} + | + LPAREN STR RPAREN texpr:t LPAREN tablelist:keys RPAREN + {: RESULT = t + " " + keys + "lookup "; :} + | + RSTRING:s {: RESULT = s+" "; :} + | + colonRef:e1 RSTRING:s {: RESULT = e1 +"entitypush "+s+" entitypop "; :} + | + STRING:s {: RESULT = s+" "; :} + | + strexpr:s1 PLUS strexpr:s2 {: RESULT = s1+s2+"strconcat "; :} + | + LPAREN STR RPAREN fexpr:fe {: RESULT = fe+"tostring "; :} + | + LPAREN STR RPAREN iexpr:ie {: RESULT = ie+"tostring "; :} + | + LPAREN STR RPAREN dexpr:de {: RESULT = de+"tostring "; :} + | + LPAREN strexpr:s RPAREN {: RESULT = s; :} + | + strexpr:s PLUS iexpr:e {: RESULT = s+e+"strconcat "; :} + | + strexpr:s PLUS fexpr:e {: RESULT = s+e+"strconcat "; :} + | + strexpr:s PLUS bexpr:e {: RESULT = s+e+"strconcat "; :} + | + strexpr:s PLUS nexpr:e {: RESULT = s+e+"strconcat "; :} + | + strexpr:s PLUS eexpr:e {: RESULT = s+e+"strconcat "; :} + | + strexpr:s PLUS dexpr:e {: RESULT = s+e+"strconcat "; :} + | + strexpr:s PLUS array_expr:e {: RESULT = s+e+"strconcat "; :} + | + strexpr:s PLUS RNULL:e {: RESULT = s+e+" strconcat "; :} + | + strexpr:s PLUS RINVALID:e {: RESULT = s+e+" strconcat "; :} + | + TRIM LPAREN strexpr:s RPAREN {: RESULT = s+"strtrim "; :} + | + LPAREN STR RPAREN indx_expr:ie {: RESULT = ie +"tostring "; :} + | + CHANGE strexpr:se TO LOWER_CASE {: RESULT = se +"tolowercase "; :} + | + CHANGE strexpr:se TO UPPER_CASE {: RESULT = se +"touppercase "; :} + GET CURRENT_DATE {: RESULT = "getdate "; :} | + GET CURRENT_TIMESTAMP {: RESULT = "gettimestamp "; :} | + USING eexpr:ee LPAREN strexpr:e RPAREN {: RESULT = ee + "entitypush "+e+"entitypop "; :} | + + // relationship Syntax + RELATIONSHIP_BETWEEN eexpr:e1 AND eexpr:e2 {: RESULT = e1+e2+ + "{ type } { '' } "+ + "{ over source req { pop dup target req } over if } "+ + "relationships forfirstelse swap pop swap pop "; :} ; + + +fexpr ::= FLOAT:n {: RESULT = n+" "; :} + | + colonRef:re RDOUBLE:f {: RESULT = re+ "entitypush "+f+" entitypop "; :} + | + RDOUBLE:e1 {: RESULT = e1+" "; :} + | + LPAREN DOUBLE RPAREN strexpr:e1 {: RESULT = e1+" "; :} + | + LPAREN DOUBLE RPAREN RTABLE:t LPAREN tablelist:keys RPAREN {: RESULT = t + " " + keys + "lookup "; :} + | + fexpr:e1 PLUS iexpr:e2 {: RESULT = e1+e2+"fadd "; :} + | + fexpr:e1 PLUS fexpr:e2 {: RESULT = e1+e2+"fadd "; :} + | + iexpr:e1 PLUS fexpr:e2 {: RESULT = e1+e2+"fadd "; :} + | + fexpr:e1 MINUS iexpr:e2 {: RESULT = e1+e2+"fsub "; :} + | + iexpr:e1 MINUS fexpr:e2 {: RESULT = e1+e2+"fsub "; :} + | + fexpr:e1 MINUS fexpr:e2 {: RESULT = e1+e2+"fsub "; :} + | + fexpr:e1 TIMES iexpr:e2 {: RESULT = e1+e2+"fmul "; :} + | + iexpr:e1 TIMES fexpr:e2 {: RESULT = e1+e2+"fmul "; :} + | + fexpr:e1 TIMES fexpr:e2 {: RESULT = e1+e2+"fmul "; :} + | + fexpr:e1 DIVIDE iexpr:e2 {: RESULT = e1+e2+"fdiv "; :} + | + iexpr:e1 DIVIDE fexpr:e2 {: RESULT = e1+e2+"fdiv "; :} + | + fexpr:e1 DIVIDE fexpr:e2 {: RESULT = e1+e2+"fdiv "; :} + | + MINUS fexpr:e {: RESULT = e+"fnegate "; :} + %prec UMINUS + | + LPAREN fexpr:e RPAREN {: RESULT = e; :} + | + LPAREN DOUBLE RPAREN indx_expr:ie {: RESULT = ie; :} + | + ADD TO RDOUBLE:v number:n {: RESULT = "/"+n+" "+v+n+" fadd def "; :} | + SUBTRACT FROM RDOUBLE:v number:n {: RESULT = "/"+n+" "+v+n+" fsub def "; :} | + MULTIPLY RDOUBLE:v BY number:n {: RESULT = "/"+n+" "+v+n+" fmul def "; :} | + DIVIDE RDOUBLE:v BY number:n {: RESULT = "/"+n+" "+v+n+" fdiv def "; :} | + + + ABSOLUTEVALUE OF fexpr:n {: RESULT = n+"fabs "; :} | + USING eexpr:ee LPAREN fexpr:e RPAREN {: RESULT = ee + "entitypush "+e+"entitypop "; :} | + DOUBLE VALUE OF operatorstatements:e {: RESULT = e; :} | + + fexpr:n ROUNDED {: RESULT = n+"0 0.5 roundto "; :} | + fexpr:n ROUNDED TO iexpr:i DECIMAL_PLACES {: RESULT = n+i+"0.5 roundto "; :} | + fexpr:n ROUNDED TO iexpr:i DECIMAL_PLACES WITH_BOUNDRY fexpr:b + {: RESULT = n+i+b+" roundto "; :} | + SUM_OF fexpr:f IN array_expr:a {: RESULT = "0 { "+f+"ladd } "+a+"forall "; :} ; + + + + +iexpr ::= iexpr:e1 PLUS iexpr:e2 {: RESULT = e1+e2+"+ "; :} + | + iexpr:e1 MINUS iexpr:e2 {: RESULT = e1+e2+"- "; :} + | + iexpr:e1 TIMES iexpr:e2 {: RESULT = e1+e2+"* "; :} + | + iexpr:e1 DIVIDE iexpr:e2 {: RESULT = e1+e2+"div "; :} + | + INTEGER:n {: RESULT = n+" "; :} + | + MINUS iexpr:e {: RESULT = e+"negate "; :} + %prec UMINUS + | + LPAREN iexpr:e RPAREN {: RESULT = e+" "; :} + | + RLONG:e1 {: RESULT = e1+" "; :} + | + GET DAYS IN YEAROF dexpr:de {: RESULT = de + "getdaysinyear "; :} + | + GET DAYS IN MONTHS FOR dexpr:d {: RESULT = d + "getdaysinmonth "; :} + | + GET DAYS OF MONTHS FOR dexpr:d {: RESULT = d + "getdayofmonth "; :} + | + colonRef:re RLONG:n {: RESULT = re+ "entitypush "+n+" entitypop "; :} + | + LPAREN LONG RPAREN indx_expr:ie {: RESULT = ie + "cvi "; :} + | + LPAREN LONG RPAREN strexpr:ie {: RESULT = ie + "cvi "; :} + | + LPAREN LONG RPAREN number:ie {: RESULT = ie + "cvi "; :} + | + LPAREN LONG RPAREN RTABLE:t LPAREN tablelist:keys RPAREN {: RESULT = t + " " + keys + "lookup "; :} + | + NUMBEROF array_expr:a {: RESULT = a+"length "; :} | + NUMBEROF array_expr:a WHERE bexpr:b {: RESULT = "0 { { 1 ladd } "+b+"if }"+a+"forall "; :} | + LENGTH OF array_expr:a {: RESULT = a+"length "; :} | + LENGTH OF strexpr:s {: RESULT = s+"strlength "; :} | + + USING array_expr:ee number:e {: RESULT = ee+"entitypush "+e+"entitypop "; :} | + + ADD TO RLONG:v number:n {: RESULT = "/"+n+v+n+" ladd def "; :} | + SUBTRACT FROM RLONG:v number:n {: RESULT = "/"+n+v+n+" lsub def "; :} | + MULTIPLY RLONG:v BY number:n {: RESULT = "/"+n+v+n+" lmul def "; :} | + DIVIDE RLONG:v BY number:n {: RESULT = "/"+n+v+n+" ldiv def "; :} | + + ABSOLUTEVALUE OF iexpr:n {: RESULT = n+"labs "; :} | + USING eexpr:ee LPAREN iexpr:e RPAREN {: RESULT = ee + "entitypush "+e+"entitypop "; :} | + DAYS FROM dexpr:d1 TO dexpr:d2 {: RESULT = d1+d2+"daysbetween "; :} | + MONTHS FROM dexpr:d1 TO dexpr:d2 {: RESULT = d1+d2+"monthsbetween "; :} | + YEARS FROM dexpr:d1 TO dexpr:d2 {: RESULT = d2+d1+"yearsbetween "; :} | + GET YEAROF dexpr:d1 {: RESULT = d1+"yearof "; :} | + LONG VALUE OF operatorstatements:e {: RESULT = e; :} | + SUM_OF iexpr:i IN array_expr:a {: RESULT = "0 { "+i+"ladd } "+a+"forall "; :} ; + + +includeSearch ::= VALUE number:e {: RESULT = e; :} | + DATE dexpr:e {: RESULT = e; :} | + eexpr:e {: RESULT = e; :} | + STRING strexpr:e {: RESULT = e; :} ; + +inthe ::= IN | FOR | ON; + + +thereis ::= THERE IS | + IS THERE; + +blist ::= strexpr:s COMMA blist:bl {: RESULT = "dup "+s+"streq { pop "+bl+"} over not if "; :} | + OR strexpr:s {: RESULT = "dup "+s+"streq "; :} ; + +bexpr ::= + // Complicated Tests + // array does not include integer/string/float/entity + array_expr:a DOES NOT INCLUDE includeSearch:e {: RESULT = a+e+"memberof not "; :} | + array_expr:a DOES INCLUDE includeSearch:e {: RESULT = a+e+"memberof "; :} | + array_expr:a INCLUDES includeSearch:e {: RESULT = a+e+"memberof "; :} | + + // This syntax looks for a match for each string in a1 to an + // attribute n on some entity in an array of entities a2 + thereis MATCH FORALL array_expr:a1 TO nexpr:n IN array_expr:a2 + {: RESULT = "true { { { pop true } { pop false } { dup "+n+"execute streq } "+a2+"forfirstelse } { pop false } swap ifelse } "+a1+"for "; :} | + // Is there a case_indvidual [ in the case ] Where case_indvidual.current_plan_available == false + thereis eexpr:e1 WHERE bexpr:b + {: RESULT = "{ true } { false } { " + b +"} "+e1.trim()+"s forfirstelse "; :} | + thereis eexpr:e1 inthe eexpr:e2 WHERE bexpr:b + {: RESULT = "{ true } { false } { " + b +"} "+e1.trim()+"s "+e2+"entitypush forfirstelse entitypop "; :} | + thereis eexpr:e1 inthe array_expr:a WHERE bexpr:b + {: RESULT = "{ true } { false } { " + b +"} "+a+ " forfirstelse "; :} | + + HASA eexpr:e1 WHERE bexpr:b + {: RESULT = "{ true } { false } { " + b +"} "+e1.trim()+"s forfirstelse "; :} | + THERE IS NO eexpr:e1 WHERE bexpr:b + {: RESULT = "{ false } { true } { " + b +"} "+e1.trim()+"s forfirstelse "; :} | + THERE IS NO eexpr:e1 inthe eexpr:e2 WHERE bexpr:b + {: RESULT = "{ false } { true } { " + b +"} "+e1.trim()+"s "+e2+"entitypush forfirstelse entitypop "; :} | + THERE IS NO eexpr:e1 inthe array_expr:a WHERE bexpr:b + {: RESULT = "{ false } { true } { " + b +"} "+a+"forfirstelse "; :} | + // all initialdeterminations have an eligibility == Denied_Out_of_Age_Limit + ALL array_expr:a HAVE bexpr:b + {: RESULT = "{ false } { true } { " + b +"not } "+a+"forfirstelse "; :} | + ONE OF array_expr:a HASA bexpr:b + {: RESULT = "{ true } { false } { " + b +"} "+a+"forfirstelse "; :} | + + // relationship Syntax + // + // Relationship tests. These tests assume that a relationships list exists within the context, + // and that a Relationship entity is defined. This relationship entity must have the following + // attributes: + // entity source -- This is the source entity + // entity target -- This is the target entity + // String type -- This is the type, like child. source is a child of target + + eexpr:e DOES NOT HAVE strexpr:s {: RESULT = s + e +"{ pop pop false } { pop pop true } "+ + "{ over type streq over target req and } relationships forfirstelse "; :} | + + eexpr:e HASA strexpr:s {: RESULT = s + e +"{ pop pop true } { pop pop false } "+ + "{ over type streq over target req and } relationships forfirstelse "; :} | + + eexpr:e HASA strexpr:s WHERE bexpr:b {: RESULT = s + e +"{ pop pop true } { pop pop false } "+ + "{ over type streq over target req and "+ + "source entitypush "+b+"entitypop and } relationships forfirstelse "; :} | + + eexpr:e1 IS strexpr:s OF eexpr:e2 {: RESULT = s + "{ pop true } { pop false } "+ + "{ dup type streq source "+e1+" req and target "+e2+" req and } "+ + " relationships forfirstelse "; :} | + + + +// Numbers + iexpr:e1 eq iexpr:e2 {: RESULT = e1+e2+"== "; :} + | + fexpr:e1 eq iexpr:e2 {: RESULT = e1+e2+"f== "; :} + | + iexpr:e1 eq fexpr:e2 {: RESULT = e1+e2+"f== "; :} + | + fexpr:e1 eq fexpr:e2 {: RESULT = e1+e2+"f== "; :} + | + + iexpr:e1 neq iexpr:e2 {: RESULT = e1+e2+"== not "; :} + | + fexpr:e1 neq iexpr:e2 {: RESULT = e1+e2+"f== not "; :} + | + iexpr:e1 neq fexpr:e2 {: RESULT = e1+e2+"f== not "; :} + | + fexpr:e1 neq fexpr:e2 {: RESULT = e1+e2+"f== not "; :} + | + + iexpr:e1 gt iexpr:e2 {: RESULT = e1+e2+"> "; :} + | + fexpr:e1 gt iexpr:e2 {: RESULT = e1+e2+"f> "; :} + | + iexpr:e1 gt fexpr:e2 {: RESULT = e1+e2+"f> "; :} + | + fexpr:e1 gt fexpr:e2 {: RESULT = e1+e2+"f> "; :} + | + + iexpr:e1 gte iexpr:e2 {: RESULT = e1+e2+">= "; :} + | + fexpr:e1 gte iexpr:e2 {: RESULT = e1+e2+"f>= "; :} + | + iexpr:e1 gte fexpr:e2 {: RESULT = e1+e2+"f>= "; :} + | + fexpr:e1 gte fexpr:e2 {: RESULT = e1+e2+"f>= "; :} + | + + iexpr:e1 lt iexpr:e2 {: RESULT = e1+e2+"< "; :} + | + fexpr:e1 lt iexpr:e2 {: RESULT = e1+e2+"f< "; :} + | + iexpr:e1 lt fexpr:e2 {: RESULT = e1+e2+"f< "; :} + | + fexpr:e1 lt fexpr:e2 {: RESULT = e1+e2+"f< "; :} + | + + iexpr:e1 lte iexpr:e2 {: RESULT = e1+e2+"<= "; :} + | + fexpr:e1 lte iexpr:e2 {: RESULT = e1+e2+"f<= "; :} + | + iexpr:e1 lte fexpr:e2 {: RESULT = e1+e2+"f<= "; :} + | + fexpr:e1 lte fexpr:e2 {: RESULT = e1+e2+"f<= "; :} + | + + RBOOLEAN:e1 {: RESULT = e1+" "; :} + | + colonRef:re RBOOLEAN:b {: RESULT = re+ "entitypush "+b+" entitypop "; :} + +// Names + | + nexpr:n1 eq nexpr:n2 {: RESULT = n1+n2+"nameeq "; :} + | + nexpr:n eq strexpr:s {: RESULT = n+s+"streq "; :} + | + + nexpr:n1 neq nexpr:n2 {: RESULT = n1+n2+"nameeq not "; :} + | + nexpr:n neq strexpr:s {: RESULT = n+s+"streq not "; :} + | + +// Strings + strexpr:s eq blist:bl {: RESULT = s+bl+"swap drop "; :} + | + strexpr:s1 eq strexpr:s2 {: RESULT = s1+s2+"streq "; :} + | + strexpr:s1 neq strexpr:s2 {: RESULT = s1+s2+"streq not "; :} + | + strexpr:s1 AT iexpr:e1 STARTS_WITH strexpr:s2 + {: RESULT = e1+s1+s2+"startswith "; :} + | + strexpr:s1 STARTS_WITH strexpr:s2 + {: RESULT = "0 "+s1+s2+"startswith "; :} + | + strexpr:s1 IS ONE OF array_expr:a + {: RESULT = a+s1+"memberof "; :} + | + strexpr:s1 IS NOT ONE OF array_expr:a + {: RESULT = a+s1+"memberof not "; :} + | + DOES bexpr:e QUESTIONMARK {: RESULT = e; :} + | + IS bexpr:e QUESTIONMARK {: RESULT = e; :} + | + WAS bexpr:e QUESTIONMARK {: RESULT = e; :} + | +// String Compares + strexpr:s1 gt strexpr:s2 {: RESULT = s1+s2+"s> "; :} | + strexpr:s1 lt strexpr:s2 {: RESULT = s1+s2+"s< "; :} | + strexpr:s1 gte strexpr:s2 {: RESULT = s1+s2+"s>= "; :} | + strexpr:s1 lte strexpr:s2 {: RESULT = s1+s2+"s<= "; :} | + +// Regex Compare + strexpr:s1 MATCHES strexpr:e1 {: RESULT = e1+s1+"regexmatch "; :} + | + +// Boolean tests + bexpr:e1 eq bexpr:e2 {: RESULT = e1+e2+"beq "; :} + | + bexpr:e1 neq bexpr:e2 {: RESULT = e1+e2+"beq "; :} + | + bexpr:e1 AND bexpr:e2 {: RESULT = e1+"{ pop "+e2+"} over if\n"; :} + | + bexpr:e1 OR bexpr:e2 {: RESULT = e1+"{ pop "+e2+"} over not if\n"; :} + | + NOT bexpr:e {: RESULT = e+"not "; :} + | + +// Null Tests + dexpr:s isnull {: RESULT = s+" isnull "; :} + | + array_expr:s isnull {: RESULT = s+" isnull "; :} + | + strexpr:s isnull {: RESULT = s+" isnull "; :} + | + eexpr:s isnull {: RESULT = s+" isnull "; :} + | + dexpr:s isnotnull {: RESULT = s+" isnull not "; :} + | + array_expr:s isnotnull {: RESULT = s+" isnull not "; :} + | + strexpr:s isnotnull {: RESULT = s+" isnull not "; :} + | + eexpr:s isnotnull {: RESULT = s+" isnull not "; :} + | + USING eexpr:ee LPAREN bexpr:e RPAREN {: RESULT = ee + "entitypush "+e+"entitypop "; :} + | + LPAREN bexpr:e RPAREN {: RESULT = e; :} + | + LPAREN BOOLEAN RPAREN indx_expr:ie {: RESULT = ie; :} +// | +// LPAREN BOOLEAN RPAREN anytype:ie {: RESULT = ie; :} + | + + BOOLEAN RARRAY:ra LBRACE iexpr:ie1 RBRACE {: RESULT = ra+" "+ie1+"getat "; :} + | + +// Date Compares + dexpr:d1 eq dexpr:d2 {: RESULT = d1+d2+"d== "; :} | + dexpr:d1 lt dexpr:d2 {: RESULT = d1+d2+"d< "; :} | + dexpr:d1 IS BEFORE dexpr:d2 {: RESULT = d1+d2+"d< "; :} | + dexpr:d1 gt dexpr:d2 {: RESULT = d1+d2+"d> "; :} | + dexpr:d1 IS AFTER dexpr:d2 {: RESULT = d1+d2+"d> "; :} | + dexpr:d1 gte dexpr:d2 {: RESULT = d1+d2+"d< not "; :} | + dexpr:d1 lte dexpr:d2 {: RESULT = d1+d2+"d> not "; :} | + dexpr:d1 IS BETWEEN dexpr:d2 AND dexpr:d3 {: RESULT = d2+d1+"d> not "+d1+d3+" d> not and "; :} | + +// Entity Compares + eexpr:e1 eq eexpr:e2 {: RESULT = e1+e2+"req "; :} | + eexpr:e1 neq eexpr:e2 {: RESULT = e1+e2+"req not "; :} | + + BOOLEAN VALUE OF operatorstatements:e {: RESULT = e; :} | + +// Rather random tests + BOOL_FUNCTION:b {: RESULT = b+" "; :} ; + + +eq ::= EQ | IS EQUAL TO | EQUAL TO ; +neq ::= NEQ | IS NOT EQUAL TO | NOT EQUAL TO ; +gt ::= GT | IS GREATER THAN | GREATER THAN ; +gte ::= GTE | IS GREATER THAN OR EQUAL TO | GREATER THAN OR EQUAL TO ; +lt ::= LT | IS LESS THAN | LESS THAN ; +lte ::= LTE | IS LESS THAN OR EQUAL TO | LESS THAN OR EQUAL TO ; + +isnull ::= ISNULL | IS NULL ; +isnotnull ::= ISNOTNULL | IS NOT NULL ; \ No newline at end of file diff --git a/DTParser/src/main/java/com/dtrules/compiler/cup/sym.java b/DTParser/src/main/java/com/dtrules/compiler/cup/sym.java new file mode 100644 index 0000000..9df3b1e --- /dev/null +++ b/DTParser/src/main/java/com/dtrules/compiler/cup/sym.java @@ -0,0 +1,192 @@ +/** + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//---------------------------------------------------- +// The following code was generated by CUP v0.11a beta 20060608 +// Mon Sep 08 16:23:44 CDT 2008 +//---------------------------------------------------- + +package com.dtrules.compiler.cup; + +/** CUP generated class containing symbol constants. */ +public class sym { + /* terminals */ + public static final int STARTS_WITH = 131; + public static final int LBRACE = 74; + public static final int ROPERATOR = 122; + public static final int FLOAT = 54; + public static final int GT = 60; + public static final int INCLUDES = 67; + public static final int GET = 58; + public static final int UNDEFINED = 151; + public static final int INCLUDE = 66; + public static final int ARROW = 11; + public static final int CACHE = 21; + public static final int VALUE = 154; + public static final int THAN = 139; + public static final int ARRAY_OF_VALUES = 10; + public static final int RPAREN = 124; + public static final int DEBUG = 34; + public static final int RXMLVALUE = 127; + public static final int ROUNDED = 123; + public static final int DECREMENT = 36; + public static final int LOCAL = 78; + public static final int WHERE = 156; + public static final int TIMES = 144; + public static final int ATTRIBUTE = 14; + public static final int SUM_OF = 136; + public static final int FORALL = 56; + public static final int ERRORCODE = 52; + public static final int RNULL = 121; + public static final int ELSEIF = 45; + public static final int UMINUS = 150; + public static final int RBOOLEAN = 109; + public static final int ARRAY = 9; + public static final int EQ = 50; + public static final int RINVALID = 118; + public static final int DESCENDINGORDER = 37; + public static final int YEAROF = 160; + public static final int DAYS = 33; + public static final int ADD = 4; + public static final int WAS = 155; + public static final int EACH = 41; + public static final int CONDITION = 28; + public static final int ASSIGN = 13; + public static final int RNAME = 120; + public static final int AFTER = 5; + public static final int NULL = 97; + public static final int ONE = 101; + public static final int EOF = 0; + public static final int MINUS = 88; + public static final int CURRENT_TIMESTAMP = 31; + public static final int RARRAY = 108; + public static final int ALLOWING = 7; + public static final int LTE = 83; + public static final int MAP = 84; + public static final int TRIM = 149; + public static final int ACTION = 3; + public static final int USING = 153; + public static final int ELSEIFNONEAREFOUND = 46; + public static final int ELSE = 44; + public static final int EQUAL = 51; + public static final int HAVE = 63; + public static final int END = 47; + public static final int OR = 102; + public static final int FIRST = 53; + public static final int NAME = 91; + public static final int ON = 100; + public static final int LESS = 77; + public static final int QUESTIONMARK = 106; + public static final int AND = 8; + public static final int SUBTRACT = 135; + public static final int DECIMAL_PLACES = 35; + public static final int NUMBEROF = 98; + public static final int THIS = 143; + public static final int OF = 99; + public static final int MATCHES = 86; + public static final int TOBEREMOVED = 147; + public static final int BY = 20; + public static final int SEMI = 128; + public static final int INCREMENT = 68; + public static final int CHANGE = 22; + public static final int TABLE = 137; + public static final int BOOLEAN = 19; + public static final int NEW = 94; + public static final int THROUGH = 145; + public static final int NO = 95; + public static final int IDENT = 161; + public static final int NEQ = 93; + public static final int RCURLY = 111; + public static final int ABSOLUTEVALUE = 2; + public static final int AT = 15; + public static final int BETWEEN = 17; + public static final int RDATE = 112; + public static final int PLUS = 104; + public static final int LPAREN = 81; + public static final int ALL = 6; + public static final int RELATIONSHIP_BETWEEN = 115; + public static final int CURRENT_DATE = 30; + public static final int RBRACE = 110; + public static final int RTABLE = 126; + public static final int COPY = 29; + public static final int GREATER = 59; + public static final int RDECISIONTABLE = 113; + public static final int ELEMENT = 43; + public static final int CONTEXT = 26; + public static final int COMMA = 27; + public static final int HASA = 62; + public static final int RLONG = 119; + public static final int LT = 82; + public static final int THENAME = 141; + public static final int MONTHS = 89; + public static final int ASCENDINGORDER = 12; + public static final int MEMBER = 87; + public static final int ISNULL = 72; + public static final int DATE = 32; + public static final int TOKENIZE = 148; + public static final int NOT = 96; + public static final int WITH = 157; + public static final int DOES = 39; + public static final int NAMEOF = 92; + public static final int STR = 132; + public static final int ENDIF = 48; + public static final int BEFORE = 16; + public static final int LONG = 79; + public static final int FOR = 55; + public static final int THEN = 140; + public static final int INTEGER = 69; + public static final int DIVIDE = 38; + public static final int STRING = 133; + public static final int DOUBLE = 40; + public static final int EARLIEST = 42; + public static final int TABLEINFORMATION = 138; + public static final int LOWER_CASE = 80; + public static final int ITS = 73; + public static final int FROM = 57; + public static final int ENTITY = 49; + public static final int BOOL_FUNCTION = 18; + public static final int WITH_BOUNDRY = 158; + public static final int CLONE = 24; + public static final int RANDOMIZE = 107; + public static final int LENGTH = 76; + public static final int POSSESSIVE = 105; + public static final int GTE = 61; + public static final int IS = 70; + public static final int MULTIPLY = 90; + public static final int UPPER_CASE = 152; + public static final int IN = 65; + public static final int MAXPRINT = 162; + public static final int error = 1; + public static final int YEARS = 159; + public static final int SORT = 130; + public static final int IF = 64; + public static final int RDOUBLE = 114; + public static final int RSTRING = 125; + public static final int ISNOTNULL = 71; + public static final int COLON = 25; + public static final int SET = 129; + public static final int PERFORM = 103; + public static final int SUBSTRING = 134; + public static final int LCURLY = 75; + public static final int THERE = 142; + public static final int CLEAR = 23; + public static final int REMOVE = 116; + public static final int RENTITY = 117; + public static final int TO = 146; + public static final int MATCH = 85; +} + + \ No newline at end of file diff --git a/DTRules/.classpath b/DTRules/.classpath new file mode 100644 index 0000000..f82b51e --- /dev/null +++ b/DTRules/.classpath @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/DTRules/.project b/DTRules/.project new file mode 100644 index 0000000..8ab58a1 --- /dev/null +++ b/DTRules/.project @@ -0,0 +1,13 @@ + + DTRules + SDC Parent POM + + + + org.eclipse.jdt.core.javabuilder + + + + org.eclipse.jdt.core.javanature + + \ No newline at end of file diff --git a/DTRules/.settings/org.eclipse.jdt.core.prefs b/DTRules/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..31e06fb --- /dev/null +++ b/DTRules/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Thu May 15 12:54:22 CDT 2008 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 diff --git a/DTRules/docs/DTRules.doc b/DTRules/docs/DTRules.doc new file mode 100644 index 0000000000000000000000000000000000000000..13f7e45aca7bc0497ead50961264a28d97da0fb6 GIT binary patch literal 25600 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 literal 0 HcwPel00001 diff --git a/DTRules/docs/OperatorList.doc b/DTRules/docs/OperatorList.doc new file mode 100644 index 0000000000000000000000000000000000000000..867e0abd11580e54518814b9cad2939f26b77948 GIT binary patch literal 59904 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ϖ+yq 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 my^zB-EWssGXKDUbWJ getRulesets(); // List of Ruleset Names + public RuleSet getRuleset(String RulesetName); + public void updateRuleset(RuleSet ruleset); + public void createRuleset(RuleSet ruleset) throws RulesException; + + public List getDecisionTables(String rulesetname); + public RDecisionTable getDecisionTable(String rulesetname, String DecisionTableName); + public void saveDecisionTables(RSession session, String rulesetname) throws RulesException; + public RDecisionTable createDecisionTable(String rulesetname, String decisiontablename) throws RulesException; + //public Node getDecisionTableTree(String rulesetname) --- not needed now + + public List getEntities(String rulesetname); + public List getAttributes(String rulesetname, String entityName); + public IREntity createEntity(String rulesetname, boolean readonly, String EntityName); + public boolean createAttribute(String rulesetname, REntityEntry attribute); + public void saveEDD(RSession session, String rulesetname)throws RulesException; + public void updateAttribute(REntity entity, String rulesetname,REntityEntry attribute)throws RulesException; + + /** + * Given an incomplete table, this method returns a balanced table. + * Entries in the table provided can be 'y', 'n', '-', or ' '. If + * blank, then it is assumed that the caller assumes this should be + * flushed out. If the result will be larger than 16 columns, an + * null is returned. (You can't have a table larger than 16 columns). + * @param table -- A partial truth table. + * @return + */ + public String[][] balanceTable(String [] [] table); + /** + * Given a Rule Set and an Entity, returns the list of EntityEntry objects + * that define the meta information about each attribute of the entity. + * @param rulesetname The Rule Set in which the entity is defined + * @param entityname The entity name of intrest. + * @return The list of Entity Entries that define the attributes of the Entity + */ + public List getEntityEntries(String rulesetname, String entityname); + +} diff --git a/DTRules/src/main/java/com/dtrules/admin/RulesAdminService.java b/DTRules/src/main/java/com/dtrules/admin/RulesAdminService.java new file mode 100644 index 0000000..379c824 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/admin/RulesAdminService.java @@ -0,0 +1,411 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.admin; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +import com.dtrules.decisiontables.RDecisionTable; +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.entity.REntityEntry; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.session.EntityFactory; +import com.dtrules.session.RSession; +import com.dtrules.session.RuleSet; +import com.dtrules.session.RulesDirectory; + +/** + * @author Prasath Ramachandran + * Feb 1, 2007 + * + * The RulesAdminService provides all the methods for adding to and maintaining a + * Rules in DTRules. This is the interface to be used by editors and other tools + * to add/remove decision tables, modify the Entity Description Dictionary, and + * create and modify Rule Sets. + */ +@SuppressWarnings("unchecked") +public class RulesAdminService implements IRulesAdminService{ + final private RSession session; + private RulesDirectory rd; // The Rules Directory provides a place where Rule + // sets are defined. + + /** + * The RulesAdminService needs a session for specifing the output of debugging + * and trace information. It needs a Rules Directory to administer. + */ + public RulesAdminService(final RSession session, final RulesDirectory rd) { + super(); + this.session = session; + this.rd = rd; + } + + /** + * Create a new Attribute; The Entity modified is specified by the attribute. + * @param rulesetname The name of the RuleSet where the attribute should be created. + * @param attribute The REntityEntry defines the Entity to be modified. It is + * assumed that this Entity already exists. + * @return true if the attribute was successfully added. + */ + public boolean createAttribute(final String rulesetname, final REntityEntry attribute) { + try { + RuleSet rs = getRuleset(rulesetname); + IREntity entity = rs.getEntityFactory(session).findRefEntity(attribute.attribute); + entity.addAttribute(attribute); + return true; + } catch (RulesException e) { + return false; + } + + } + + /** + * Given a Rule Set and an Entity, returns the list of EntityEntry objects + * that define the meta information about each attribute of the entity. If an + * error occurs while building the list, an empty list is returned. + * + * @param rulesetname The Rule Set in which the entity is defined + * @param entityname The entity name of intrest. + * @return The list of Entity Entries that define the attributes of the Entity + */ + public List getEntityEntries(String rulesetname, String entityname){ + ArrayList entries = new ArrayList(); + RuleSet rs = getRuleset(rulesetname); + IREntity entity; + try { + entity = rs.getEntityFactory(session).findRefEntity(RName.getRName(entityname)); + Iterator attribs = entity.getAttributeIterator(); + + while(attribs.hasNext()){ + entries.add(entity.getEntry(attribs.next())); + } + } catch (RulesException e) { } + + return entries; + } + + /** + * Create a new Decision Table + */ + public RDecisionTable createDecisionTable(String rulesetname, String decisiontablename) + throws RulesException{ + RuleSet rs = getRuleset(rulesetname); + return rs.getEntityFactory(session).newDecisionTable(decisiontablename,session); + } + + /** + * Creates a new Entity of the given name within the RuleSet. If + * the Entity already exists or the name is invalid, or this operation + * fails in any other way, a null is returned. + * @see com.dtrules.admin.IRulesAdminService#createEntity(java.lang.String, java.lang.String) + * @param rulesetname The name of the RuleSet in which to create this entity + * @param EntityName The name of the new Entity + */ + public IREntity createEntity(String rulesetname, boolean readonly, String entityName) { + RName name = RName.getRName(entityName); + IREntity e = session.getEntityFactory().findRefEntity(name); + if(e!=null)return null; + try { + return session.getEntityFactory().findcreateRefEntity(readonly, name); + } catch (RulesException e1) { + return null; + } + } + + /** + * Create a new Rule Set + * @see com.dtrules.admin.IRulesAdminService#createRuleset(com.dtrules.session.RuleSet) + */ + public void createRuleset(RuleSet ruleset) throws RulesException{ + rd.addRuleSet(ruleset); + } + + /* (non-Javadoc) + * @see com.dtrules.admin.IRulesAdminService#getAttributes(java.lang.String, java.lang.String) + */ + @SuppressWarnings("unchecked") + public List getAttributes(String rulesetname, String entityName) { + if(rd==null)return null; + try { + RuleSet rs = rd.getRuleSet(RName.getRName(rulesetname)); + Iterator it = rs.getEntityFactory(session) + .findRefEntity(RName.getRName(entityName)).getAttributeIterator(); + return getList(it); + } catch (RulesException e) { + return null; + } + } + + /* (non-Javadoc) + * @see com.dtrules.admin.IRulesAdminService#getDecisionTable(java.lang.String, java.lang.String) + */ + public RDecisionTable getDecisionTable(String rulesetname, String DecisionTableName) { + try { + RuleSet rs = rd.getRuleSet(RName.getRName(rulesetname)); + return rs.getEntityFactory(session) + .findTable(RName.getRName(DecisionTableName)); + } catch (RulesException e) { + return null; + } + } + + /* (non-Javadoc) + * @see com.dtrules.admin.IRulesAdminService#getDecisionTables(java.lang.String) + */ + public List getDecisionTables(String rulesetname) { + if(rd==null)return null; + try { + RuleSet rs = rd.getRuleSet(RName.getRName(rulesetname)); + Iterator it = rs.getEntityFactory(session).getDecisionTableRNameIterator(); + return getList(it); + } catch (RulesException e) { + return null; + } + } + + @SuppressWarnings("unchecked") + private List getList(Iterator iterator){ + List list = new ArrayList(); + while(iterator.hasNext()){ + list.add(((IRObject)iterator.next()).stringValue()); + } + return list; + + } + + /** + * Return the list of Entities known to the given ruleset + * @return List of Entity RName objects + * @see com.dtrules.admin.IRulesAdminService#getEntities(java.lang.String) + */ + public List getEntities(String rulesetname) { + if(rd==null)return null; + try { + Iterator e = rd.getRuleSet(RName.getRName(rulesetname)).getEntityFactory(session) + .getEntityRNameIterator(); + return getList(e); + } catch (RulesException e) {} + return null; + } + + /** + * Return the RuleSet associated with the given RuleSet Name + * @return RuleSet A set of Decision Tables and Entities which define a RuleSet + * @see com.dtrules.admin.IRulesAdminService#getRuleset(java.lang.String) + */ + public RuleSet getRuleset(String RulesetName) { + if(rd==null)return null; + return rd.getRuleSet(RName.getRName(RulesetName)); + } + + /** + * Returns the list of RuleSets known to this Rules Directory + * @return A List of RName objects giving the list Rule Sets + * @see com.dtrules.admin.IRulesAdminService#getRulesets() + */ + public List getRulesets() { + List rulesets = new ArrayList(); + for(Iterator it = rd.getRulesets().keySet().iterator(); it.hasNext();){ + RName name = (RName)it.next(); + rulesets.add(name.stringValue()); + } + return rulesets; + } + + /** + * Loads the XML defining the RulesDirectory. The given path must be a + * path and filename which is valid in the file system, or a valid Java + * resource, or a valid URL. + * @param pathtoDT + * @see com.dtrules.admin.IRulesAdminService#initialize(java.lang.String) + */ + public void initialize(String pathtoDTrules) { + String path = "C:\\eclipse\\workspace\\EB_POC\\CA HCO Plan\\xml\\"; + String file = path + "DTRules.xml"; + if(pathtoDTrules != null){ + file = pathtoDTrules; + } + + try { + rd = new RulesDirectory("",file); + + } catch (Exception e) { + e.printStackTrace(); + } + + } + + /** + * This method changes (potentially) the attributes of an attribute of an + * Entity. The REntityEntry attribute must be populated correctly. + * + * @param rulesetname The Ruleset which holds the Entity for which the + * attribute applies. + * @param attribute Contains the Entity Name and all the other meta data + * for the attribute to be changed. + * + * @see com.dtrules.admin.IRulesAdminService#updateAttribute(java.lang.String, com.dtrules.entity.REntityEntry) + */ + public void updateAttribute(REntity entity, String rulesetname, REntityEntry attribute) throws RulesException { + entity.addAttribute(attribute); + + } + /** + * Updates the Decision Table XML specified in the RuleSet with the Decision Tables as + * currently held in memory. + */ + public void saveDecisionTables(RSession session, String rulesetname) throws RulesException { + RuleSet rs = rd.getRuleSet(RName.getRName(rulesetname)); + String filepath = rs.getFilepath(); + String filename = rs.getDT_XMLName(); + + OutputStream out; + try { + out = new FileOutputStream(filepath+filename); + } catch (FileNotFoundException e) { + throw new RulesException( + "OutputFileCreationError", + "saveDecisionTables", + "An error occured openning the file: "+filepath+filename+"\n"+e + ); + } + saveDecisionTables(out,session,rulesetname); + } + + /** + * Writes out the Decision Tables to the given output stream as the currently exist in + * Memory. + * + * @param out outputstream to write the decision tables to. + * @param session The session which gives us the outputstreams for debug statements and trace statements + * @param rulesetname The Rule Set to be written out to the output stream + * @throws RulesException + */ + public void saveDecisionTables(OutputStream out, RSession session, String rulesetname) throws RulesException { + RuleSet rs = rd.getRuleSet(RName.getRName(rulesetname)); + EntityFactory ef = rs.getEntityFactory(session); + + PrintStream ps = new PrintStream(out); + Iterator tables = ef.getDecisionTableRNameIterator(); + ps.println(""); + while(tables.hasNext()){ + RName dtname = tables.next(); + ef.getDecisionTable(dtname).writeXML(ps); + } + ps.println("\n"); + + } + + /** + * Test function. + * @param args ignored. + */ + public static void main(String args[]){ + String path = "C:\\eclipse\\workspace\\EB_POC\\new_york_EB\\xml\\"; + String file = path + "DTRules.xml"; + + RulesDirectory rd = new RulesDirectory("",file); + RuleSet rs = rd.getRuleSet(RName.getRName("ebdemo")); + RSession session; + try { + OutputStream out = new FileOutputStream("c:\\temp\\dt.xml"); + session = new RSession(rs); + RulesAdminService admin = new RulesAdminService(session, rd); + + admin.saveDecisionTables(out, session, "ebdemo"); + } catch (Exception e1) { + System.out.println(e1.toString()); + } + } + /* (non-Javadoc) + * @see com.dtrules.admin.IRulesAdminService#updateEntity(java.lang.String, com.dtrules.entity.REntity) + */ + public void saveEDD(RSession session, String rulesetname) throws RulesException { + RuleSet rs = rd.getRuleSet(RName.getRName(rulesetname)); + EntityFactory ef = rs.getEntityFactory(session); + String filepath = rs.getFilepath(); + String filename = rs.getEDD_XMLName(); + + OutputStream out; + try { + out = new FileOutputStream(filepath+filename); + } catch (FileNotFoundException e) { + throw new RulesException( + "OutputFileCreationError", + "saveDecisionTables", + "An error occured openning the file: "+filepath+filename+"\n"+e + ); + } + PrintStream ps = new PrintStream(out); + Iterator entities = ef.getEntityRNameIterator(); + ps.println(""); + while(entities.hasNext()){ + RName ename = entities.next(); + ef.findRefEntity(ename).writeXML(ps); + } + ps.println("\n"); + } + + /* (non-Javadoc) + * @see com.dtrules.admin.IRulesAdminService#updateRuleset(com.dtrules.session.RuleSet) + */ + public void updateRuleset(RuleSet ruleset) { + // TODO Auto-generated method stub + + } + + + /** + * Given an incomplete table, this method returns a balanced table. + * Entries in the table provided can be 'y', 'n', '-', or ' '. If + * blank, then it is assumed that the caller assumes this should be + * flushed out. If the result will be larger than 16 columns, an + * null is returned. (You can't have a table larger than 16 columns). + * @param table -- A partial truth table. + * @return + */ + public String[][] balanceTable(String [] [] table){ + int rows = table.length; + if(rows>4||rows<=0)return null; + int cols = 1<<(rows); + + String newTable[][] = new String [rows][cols]; + + for(int i=0; i< cols; i++){ + for(int j=0;j>(rows-1-j))&1)==1?"n":"y"; + } + } + + return newTable; + } + + public final RulesDirectory getRd() { + return rd; + } + + public final RSession getSession() { + return session; + } + +} diff --git a/DTRules/src/main/java/com/dtrules/decisiontables/ANode.java b/DTRules/src/main/java/com/dtrules/decisiontables/ANode.java new file mode 100644 index 0000000..9a48def --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/decisiontables/ANode.java @@ -0,0 +1,188 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.decisiontables; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.session.DTState; + +/** + * ANodes execute a list of actions. + * @author ps24876 + * + */ +public class ANode implements DTNode { + RDecisionTable dtable; // The Decision Table to which this ANode belongs + ArrayList action = new ArrayList(); // The action postfix + ArrayList anumbers = new ArrayList(); // The action numbers (for tracing purposes) + ArrayList columns = new ArrayList(); // Keep track of the columns that send us here, for tracing + String section; // What section we are being called from. + + + public DTNode cloneDTNode(){ + ANode newANode = new ANode(dtable); + newANode.action.addAll(this.action); + newANode.anumbers.addAll(this.anumbers); + newANode.columns.addAll(this.columns); + newANode.section = this.section; + return newANode; + } + + public int getRow(){ return -1; } + + /** + * Create and return an new ANode instance that holds all of the + * actions whose supposed to execute if this column executes. + * @param col (the zero based column number) + */ + public static ANode newANode(RDecisionTable dt, int col){ + //int cnt = 0; + ArrayList list = new ArrayList (); + ArrayList numbers = new ArrayList(); + for(int i=0; i< dt.actiontable.length; i++){ + if(dt.actiontable[i][col].equalsIgnoreCase("x")){ + if(dt.ractions!=null && dt.ractions.length>=i){ + list.add(dt.ractions[i]); + numbers.add(Integer.valueOf(i)); + } + } + } + return new ANode(dt,col+1, list, numbers); + } + + public void addNode(ANode node){ + columns.addAll(node.columns); + for(int i=0;i objects, ArrayList numbers){ + dtable = dt; + columns.add(new Integer(column)); + action = objects; + anumbers = numbers; + } + + public ANode(RDecisionTable dt){ + dtable = dt; + } + + /** Give the list of columns that got us to this ANode. Unbalanced tables + * can give us multiple columns in a single ANode + * @param columns + * @return + */ + public String prtColumns(ArrayList columns){ + String s=""; + for(Integer column : columns){ + s += column.toString()+" "; + } + return s; + } + + public void execute(DTState state) throws RulesException { + Iterator inum = anumbers.iterator(); + if(state.testState(DTState.TRACE)){ + state.traceTagBegin("Column", "n='"+prtColumns(columns)+"'"); + } + for(IRObject v : action){ + int num = inum.next().intValue(); + if(state.testState(DTState.TRACE)){ + state.traceTagBegin("action","n='"+(num+1)+"'"); + state.traceTagBegin("formal",null); + state.traceTagEnd("formal",dtable.getActions()[num]); + int d = state.ddepth(); + + try { + String section = state.getCurrentTableSection(); + int numhld = state.getNumberInSection(); + state.setCurrentTableSection("Action",num); + state.evaluate(v); + state.setCurrentTableSection(section, numhld); + } catch (RulesException e) { + e.setSection("Action",num+1); + throw e; + } + if(d!=state.ddepth()){ + throw new RulesException("data stack unbalanced","ANode Execute","Action "+(num+1)+" in table "+dtable.getDtname()); + } + state.traceTagEnd("action",null); + }else{ + try { + String section = state.getCurrentTableSection(); + int numhld = state.getNumberInSection(); + state.setCurrentTableSection("Action",num); + state.evaluate(v); + state.setCurrentTableSection(section, numhld); + } catch (RulesException e) { + e.setSection("Action",num+1); + throw e; + } + } + } + if(state.testState(DTState.TRACE)){ + state.traceTagEnd("Column", null); + } + } + + public Coordinate validate() { + return null; + } + + public String toString(){ + return "Action Node for columns "+(prtColumns(columns)); + } + /** + * An Action Node is equal to another DTNode if 1) it has one and + * only one set of actions it executes regardless of the path taken, and + * 2) if the actions this node takes are exactly the as the node provided. + */ + public boolean equalsNode(DTNode node) { + ANode other = node.getCommonANode(); // Get the common path + if(other==null)return false; // No common path? Not Equal then! + if(other.anumbers.size()!=anumbers.size()) return false;// Must be the same length. + Iterator iother = other.anumbers.iterator(); // Iterate through the other node's actions. + Iterator ithis = anumbers.iterator(); // Also Iterate through this nodee's actions. + while(iother.hasNext()){ // The other node still has actions? loop! + if(!iother.next().equals(ithis.next()))return false;// Make sure each action is the same action. + } // If a mismatch is found, Not Equal!!! + return true; + } + + public ANode getCommonANode() { + return this; + } + + +} diff --git a/DTRules/src/main/java/com/dtrules/decisiontables/BalanceTable.java b/DTRules/src/main/java/com/dtrules/decisiontables/BalanceTable.java new file mode 100644 index 0000000..01ae6fc --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/decisiontables/BalanceTable.java @@ -0,0 +1,123 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.decisiontables; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.session.IRSession; + +/** + * Builds a balanced decision table from the given decision table. + * @author paul snow + * Mar 5, 2007 + * + */ +public class BalanceTable { + + private int maxRow=0,maxCol=0; + private int maxARow=0; + private String ctable[][] = new String[32][10240]; + private String atable[][] = new String[32][10240]; + + final RDecisionTable dt; + public BalanceTable(RDecisionTable dt) throws RulesException{ + this.dt = dt; + } + + RDecisionTable balancedTable (IRSession s) throws RulesException{ + if(!dt.isCompiled())dt.build(); + if(!dt.isCompiled()){ + throw new RulesException("DecisionTableError","balancedTable()","Malformed Decision Table"); + } + RDecisionTable btable = (RDecisionTable) dt.clone(s); + ctable = btable.conditiontable; + atable = btable.actiontable; + filltable(0,0,btable.decisiontree); + btable.setType(RDecisionTable.Type.BALANCED); + btable.build(); + return btable; + } + + public String getPrintableTable(){ + if(dt.decisiontree==null)return "empty table"; + filltable(0, 0, dt.decisiontree); + StringBuffer buff = new StringBuffer(); + buff.append("Number of Columns: "+maxCol+"\r\n\r\n"); + String spacer = " "; + if(maxCol < 25) spacer = " "; + + + for(int i=0;i tag. + // Any tag within this tag is interpreted as an attribute of + // the decision table. The Table_type tag is treated special. + /** + * The limit here is many times too large for actual decision tables. + * In fact, one should throw an error if a table has more than 16 columns, + * or more than 16 actions. Tables larger than that are too hard to + * understand to be useful. + **/ + static final int LIMIT = 100; + + // Temp Space for collecting data for the decision tables + String context_formal [] = new String[LIMIT]; + String context_postfix [] = new String[LIMIT]; + String ia_formal [] = new String[LIMIT]; + String ia_postfix [] = new String[LIMIT]; + String ia_comment [] = new String[LIMIT]; + String c_formal[] = new String[LIMIT]; + String c_comment[] = new String[LIMIT]; + String c_postfix[] = new String[LIMIT]; + String c_table[][] = new String[LIMIT][LIMIT]; + String a_formal[] = new String[LIMIT]; + String a_comment[] = new String[LIMIT]; + String a_postfix[] = new String[LIMIT]; + String a_table[][] = new String[LIMIT][LIMIT]; + + RDecisionTable dt = null; + + /** + * In order to load decision tables into an EntityFactory, we create + * a loader. The tables are loaded into the entityfactory, and warning + * messages will be routed through the session. + * + * @param _session + * @param _ef + */ + public DTLoader(IRSession _session, EntityFactory _ef){ + session = _session; + state = _session.getState(); + ef = _ef; + } + + + public void end_decision_tables()throws Exception { + /** + * Now we build all the decision tables. + */ + Iterator it = ef.getDecisionTableRNameIterator(); + while(it.hasNext()){ + try { + RDecisionTable dt = ef.getDecisionTable(it.next()); + dt.build(); + + } catch (RulesException e) { + state.traceInfo("error", null,"Error building Decision Table "+dt+"\r\n"+e); + } + } + } + + + /** + * Handle the Decision Table setup and initialization. + */ + + /** + * Decision Table Name + * @throws RulesException + */ + public void end_table_name() throws RulesException { + dt = ef.newDecisionTable(_body, session); + + c_cnt = 0; + a_cnt = 0; + col_cnt = 1; + col = 0; + ia_cnt = 0; + context_cnt = 0; + + c_table = new String[LIMIT][LIMIT]; + a_table = new String[LIMIT][LIMIT]; + + } + + /** + * All done gathering the info for the table. Now we need to + * pack it away into the actual decision table. + * + */ + public void end_decision_table(){ + /** Contexts do not have comments **/ + dt.contexts = new String[context_cnt]; + dt.contextsPostfix = new String[context_cnt]; + + /** Initial Actions have Comments, descriptions, and postfix **/ + dt.initialActionsComment = new String[ia_cnt]; + dt.initialActions = new String[ia_cnt]; + dt.initialActionsPostfix = new String[ia_cnt]; + + /** The count of columns for Conditions and actions have to match **/ + dt.maxcol = col_cnt; + + /** Conditions have a comment, description, Postfix, and a truth table **/ + dt.conditionsComment = new String[c_cnt]; + dt.conditions = new String[c_cnt]; + dt.conditionsPostfix = new String[c_cnt]; + dt.conditiontable = new String[c_cnt][col_cnt]; + + /** Actions have a comment, description, Postfix, and a action table **/ + dt.actionsComment = new String[a_cnt]; + dt.actions = new String[a_cnt]; + dt.actionsPostfix = new String[a_cnt]; + dt.actiontable = new String[a_cnt][col_cnt]; + + //Move over the information for the contexts + for(int i=0;i tag is encountered + * + */ + public void begin_attribute_fields() { + processing_fields = true; + } + /** + * Turn off attribute field processing outside the tag + */ + public void end_attribute_fields() { + processing_fields = false; + } + + /** + * Mostly we just collect attribute fields. But if the attribute field is the + * table_type tag, then it has to have a value of FIRST, ALL, or BALANCED. + */ + public void process_field() throws RulesException { + dt.fields.put(RName.getRName(_tag),_body); + if(_tag.equalsIgnoreCase("type")){ + if(_body.equalsIgnoreCase("first")){ + dt.setType(RDecisionTable.Type.FIRST); + }else if (_body.equalsIgnoreCase("all")){ + dt.setType(RDecisionTable.Type.ALL); + }else if (_body.equalsIgnoreCase("balanced")){ + dt.setType(RDecisionTable.Type.BALANCED); + }else { + throw new RulesException("Invalid","Decision Table Load","Bad Decision Table type Encountered: '"+_body+"'"); + } + } + } + + + /* + * Handle each condition in turn. + * + */ + + public void begin_condition_details(){ + col=0; // Start at the begining of the columns again. + } + + public void end_context_description(){ + context_formal[context_cnt] = _body; + } + + public void end_context_postfix (){ + context_postfix[context_cnt] = _body; + } + + public void end_context_details (){ + context_cnt++; + } + + public void end_initial_action_description(){ + ia_formal[ia_cnt] = _body; + } + + public void end_initial_action_comment(){ + ia_comment[ia_cnt] = _body; + } + + public void end_initial_action_postfix () { + ia_postfix[ia_cnt] = _body; + } + + public void end_initial_action_details () { + ia_cnt++; + } + + + public void end_condition_description(){ + c_formal[c_cnt]=_body; + } + + public void end_condition_postfix(){ + c_postfix[c_cnt]=_body; + } + + public void end_condition_comment(){ + c_comment[c_cnt]=_body; + } + + public void begin_condition_column() throws RulesException { + if(col>=col_cnt){ + col_cnt++; + } + int theCol = Integer.parseInt((String)_attribs.get("column_number"))-1; + c_table[c_cnt][theCol]= (String) _attribs.get("column_value"); + col++; + } + + public void end_condition_details(){ + c_cnt++; + } + + /* + * Load Actions + */ + + + public void begin_action_details(){ + for(int i=0;i=col_cnt){ + throw new RuntimeException("Decision Table Loader: Too many columns found in "+dt.toString()); + } + String a_v = (String)_attribs.get("column_value"); + + a_table[a_cnt][a_col]= a_v; + } + + public void end_action_details() { + a_cnt++; + } + + public void beginTag(String[] tagstk, int tagstkptr, String tag, HashMap attribs) throws IOException, Exception { + + _tag = tag; + _attribs = attribs; + _body = null; + String tagname = "begin_"+tag; + try { + Method m = methodCache.get(tagname); + if(m==null){ + m = this.getClass().getMethod(tagname,(Class [])null); + methodCache.put(tagname,m); + } + m.invoke(this,(Object [])null); + } catch (NoSuchMethodException e){ // Ignore undefined tags + } catch (InvocationTargetException e){ // Ignore errors thrown by Decision Table parsing + throw new RuntimeException("An Invocation Target Exception was thrown processing the Begin XML tag "+tag+ + "\nError states: "+e.getCause()); + } catch (Exception e) { + state.traceInfo("error", null,e.getCause().getMessage()); + throw new RuntimeException("Error Parsing Decision Tables: "+e.getMessage()); + } + } + + HashMap methodCache = new HashMap(); + + public void endTag(String[] tagstk, int tagstkptr, String tag, String body, HashMap attribs) throws Exception, IOException { + + _tag = tag; + _attribs = attribs; + body = body.trim().replaceAll("[\\n\\r]"," "); + _body = body; + String tagname = "end_"+tag; + try { + Class[] classArr = null; + Object[] objArr = null; + Method m = methodCache.get(tagname); + if(m==null){ + m = this.getClass().getMethod(tagname,classArr); + methodCache.put(tagname, m); + } + m.invoke(this, objArr); + } catch (NoSuchMethodException e){ // Ignore undefined tags + if(processing_fields){ // Unless we are in the attribute files section. + process_field(); + } + } catch (InvocationTargetException e){ // Ignore errors thrown by Decision Table parsing + state.traceInfo("error", null,"An Invocation Target Exception was thrown processing the End XML tag "+tag+ + "\nError states "+e.getCause()); + } catch (Exception e) { + state.traceInfo("error", null,e.getCause().getMessage()); + throw new RuntimeException("Error Parsing Decision Tables: "+e.getMessage()); + } + + } + + /** + * Skip DTD stuff and other parsing things the Rules Engine doesn't + * care about. + */ + public boolean error(String v) throws Exception { + return true; + } + + +} diff --git a/DTRules/src/main/java/com/dtrules/decisiontables/DTNode.java b/DTRules/src/main/java/com/dtrules/decisiontables/DTNode.java new file mode 100644 index 0000000..f18eb93 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/decisiontables/DTNode.java @@ -0,0 +1,75 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.decisiontables; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.session.DTState; + +public interface DTNode { + static class Coordinate { + int row; + int col; + Coordinate(int row, int col){ + this.row = row; + this.col = col; + } + public int getCol() { + return col; + } + public void setCol(int col) { + this.col = col; + } + public int getRow() { + return row; + } + public void setRow(int row) { + this.row = row; + } + } + + public int getRow(); + + /** + * Returns a clone of this node, and all nodes below (if it + * has subnodes). + * @return + */ + public DTNode cloneDTNode(); + + public int countColumns(); + + void execute(DTState state) throws RulesException; + Coordinate validate(); + + /** + * For two DTNodes are equal if every path through both nodes + * execute exactly the same set of Actions. + * @param node + * @return + */ + boolean equalsNode(DTNode node); + /** + * Returns an ANode which represents the execution of every + * path through the given DTNode. If different paths through + * the DTNode execute different actions, this method returns + * a null. Note that ANodes always return themselves (i.e. + * there is only one execution path through an ANode). + */ + ANode getCommonANode(); +} diff --git a/DTRules/src/main/java/com/dtrules/decisiontables/DecisionTableTypeTest.java b/DTRules/src/main/java/com/dtrules/decisiontables/DecisionTableTypeTest.java new file mode 100644 index 0000000..7351417 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/decisiontables/DecisionTableTypeTest.java @@ -0,0 +1,176 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.decisiontables; + +import java.util.Iterator; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.session.ICompilerError; +import com.dtrules.session.IRSession; +import com.dtrules.session.RuleSet; +import com.dtrules.session.RulesDirectory; + +public class DecisionTableTypeTest { + + int maxRow=0,maxCol=0; + String ctable [][] = new String[128][128]; + String atable [][] = new String[128][128]; + RDecisionTable dt; + + public DecisionTableTypeTest(IRSession session, RuleSet rs) throws RulesException{ + + dt = new RDecisionTable(session, rs, "test"); + + String ctable[][] = { + { "y", "n", "n", "y", "d", "a" }, + { "n", "n", "y", " ", " ", " " }, + { "y", "y", "y", "n", " ", " " }, + { "y", "y", " ", " ", " ", " " }, + { " ", " ", "y", " ", " ", " " }, + { "y", " ", " ", " ", " ", " " }, + + }; + dt.conditiontable = ctable; + + String atable[][] = { + { "x", " ", " ", " ", " ", " " }, + { " ", "x", "x", " ", " ", " " }, + { " ", "x", "x", " ", " ", " " }, + { " ", " ", " ", "x", "x", " " }, + { " ", " ", " ", " ", "x", " " }, + { " ", " ", " ", "x", " ", "x" }, + }; + dt.maxcol = ctable[0].length; + dt.actiontable = atable; + dt.rconditions = new IRObject[ctable.length]; + dt.ractions = new IRObject[atable.length]; + + String cps[] = new String[ctable.length]; + for (int i = 0; i < cps.length; i++) + cps[i] = "{ 'Condition " + i + "' }"; + + String aps[] = new String[atable.length]; + for (int i = 0; i < aps.length; i++) + aps[i] = "{ 'Action " + i + "' }"; + + dt.conditions = cps; + dt.conditionsPostfix = cps; + dt.actions = aps; + dt.actionsPostfix = aps; + dt.setType(RDecisionTable.Type.FIRST); + } + + public static void main(String[] args) { + String path = "C:\\eclipse\\workspace\\EB_POC\\CA HCO Plan\\xml\\"; + String file = "DTRules.xml"; + if(args.length>0){ + file = args[0]; + } + + try { + RulesDirectory rd = new RulesDirectory(path,file); + RuleSet rs = rd.getRuleSet(RName.getRName("ebdemo")); + IRSession session = rs.newSession(); + DecisionTableTypeTest test; + + test = new DecisionTableTypeTest(session,rs); + test.dt.setType(RDecisionTable.Type.FIRST); + test.dt.build(); + test.printtable (); + + test = new DecisionTableTypeTest(session,rs); + test.dt.setType(RDecisionTable.Type.ALL); + test.dt.build(); + test.printtable (); + + + } catch (Exception e) { + e.printStackTrace(System.out); + } + + } + + void printtable(){ + maxRow = maxCol = 0; + filltable(0,0,dt.decisiontree); + + System.out.print(" "); + for(int i=0;i errors = dt.getErrorList().iterator(); + while(errors.hasNext()){ + ICompilerError error = errors.next(); + System.out.println(error.getMessage()+ + " on "+"Row " + error.getRow()+" Column "+error.getCol()); + + + } + } + + + private int filltable(int row, int col, DTNode node){ + if(node.getClass()==CNode.class){ + int ncol; + CNode cnode = (CNode) node; + + if(cnode.conditionNumber!=row){ + ncol = filltable(row+1,col, node); + for(int i=col;i
+ * + * BALANCED -- These decision tables expect all branches to be defined in the condition table
+ * ALL -- Evaluates all the columns, then executes all the actions, in the order they + * are specified, for all columns whose conditions are met.
+ * FIRST -- Effectively evaluates each column, and executes only the first Column whose + * conditions are met.
+ * @author paul snow + * Mar 1, 2007 + * + */ +public class RDecisionTable extends ARObject { + + private final RName dtname; // The decision table's name. + + private String filename = null; // Filename of Excel file where the table is defined, + // if this decision table is defined in Excel. + + enum UnbalancedType { FIRST, ALL }; // Unbalanced Table Types. + public static enum Type { + BALANCED { void build(RDecisionTable dt) {dt.buildBalanced(); }}, + FIRST { void build(RDecisionTable dt) {dt.buildUnbalanced(UnbalancedType.FIRST); }}, + ALL { void build(RDecisionTable dt) {dt.buildUnbalanced(UnbalancedType.ALL); }}; + abstract void build(RDecisionTable dt); + } + + public Type type = Type.BALANCED; // By default, all decision tables are balanced. + + public static final int MAXCOL = 16; // The Maximum number of columns in a decision table. + + int maxcol = 1; // The number of columns in this decision table. + + private final RuleSet ruleset; // A decision table must belong to a particular ruleset + + public final Map fields = new HashMap(); // Holds meta information about this decision table. + + private boolean compiled=false; // The decision table isn't compiled + // until fully constructed. And + // it won't be if compilation fails. + String [][] conditiontable; + String [] conditions; // The conditions in formal. The formal langauge is compiled to get the postfix + String [] conditionsPostfix; // The conditions in postfix. derived from the formal + String [] conditionsComment; // A comment per condition. + IRObject [] rconditions; // Each compiled condition + + String [][] actiontable; + String [] actions; + String [] actionsComment; + String [] actionsPostfix; + IRObject [] ractions; // Each compiled action + + + String [] initialActions; // A list of actions to be executed each time the + // decision table is executed before the conditions + // are evaluated. + IRObject [] rinitialActions; + String [] initialActionsPostfix; // Compiled Initial Actions + String [] initialActionsComment; // Comment for Initial Actions + String [] contexts; // Contexts in which to execute this table. + String [] contextsPostfix; // The Postfix for each context statement. + String contextsrc; // For Tracing... + IRObject rcontext; // lists of entities. It is best if this is done within the table than + // by the calling table. + + List errorlist = new ArrayList(); + DTNode decisiontree=null; + + private int numberOfRealColumns = 0; // Number of real columns (as unbalanced tables can have + // far more columns than they appear to have). + + public int getNumberOfRealColumns() { + if(decisiontree==null)return 0; + return decisiontree.countColumns(); + } + + /** + * Check for errors in the decision table. Returns the column + * and row of a problem if one is found. If nothing is wrong, + * a null is returned. + * @return + */ + public Coordinate validate(){ + if(decisiontree==null){ + if(actions !=null && actions.length==0)return null; + return new Coordinate(0,0); + } + return decisiontree.validate(); + } + + BalanceTable balanceTable = null; // Helper class to build a balanced or optimized version + // of this decision table. + + public boolean isCompiled(){return compiled;} + + + + public String getFilename() { + return filename; + } + + public void setFilename(String filename) { + this.filename = filename; + } + + @Override + public IRObject clone(IRSession s) throws RulesException { + RDecisionTable dt = new RDecisionTable(s,ruleset, dtname.stringValue()); + dt.numberOfRealColumns = numberOfRealColumns; + dt.conditiontable = conditiontable.clone(); + dt.conditions = conditions.clone(); + dt.conditionsPostfix = conditionsPostfix.clone(); + dt.conditionsComment = conditionsComment.clone(); + dt.rconditions = rconditions.clone(); + dt.actiontable = actiontable.clone(); + dt.actions = actions.clone(); + dt.actionsComment = actionsComment.clone(); + dt.actionsPostfix = actionsPostfix.clone(); + dt.ractions = ractions.clone(); + dt.rinitialActions = rinitialActions.clone(); + dt.initialActions = initialActions.clone(); + dt.initialActionsComment = initialActionsComment.clone(); + dt.initialActionsPostfix = initialActionsPostfix.clone(); + dt.contexts = contexts.clone(); + dt.contextsPostfix = contextsPostfix.clone(); + dt.contextsrc = contextsrc; + dt.rcontext = rcontext.clone(s); + return dt; + } + /** + * Changes the type of the given decision table. The table is rebuilt. + * @param type + * @return Returns a list of errors which occurred when the type was changed. + */ + public void setType(Type type) { + this.type = type; + } + /** + * This routine compiles the Context statements for the + * decision table into a single executable array. + * It must embed into this array a call to executeTable + * (which avoids this context building for the table). + */ + private void buildContexts(){ + // Nothing to do if no extra contexts are specfied. + if(contextsPostfix==null || contextsPostfix.length==0) return; + + // This is the call to executeTable against this decisiontable + // that we are going to embed into our executable array. + contextsrc = "/"+getName().stringValue()+" executeTable "; + + boolean keep = false; + for(int i=contextsPostfix.length-1;i>=0;i--){ + if(contextsPostfix[i]!=null){ + contextsrc = "{ "+contextsrc+" } "+contextsPostfix[i]; + keep = true; + } + } + if(keep == true){ + try { + rcontext = RString.compile(ruleset, contextsrc, true); + } catch (RulesException e) { + errorlist.add( + new CompilerError ( + ICompilerError.Type.CONTEXT, + "Formal Compiler Error: "+e, + contextsrc,0)); + } + } + } + + /** + * Build this decision table according to its type. + * + */ + public void build(){ + errorlist.clear(); + decisiontree = null; + buildContexts(); + /** + * If a context or contexts are specified for this decision table, + * compile the context formal into postfix. + */ + type.build(this); + } + + /** + * Return the name of this decision table. + * @return + */ + public RName getName(){ + return dtname; + } + + /** + * Renames this decision table. + * @param session + * @param newname + * @throws RulesException + */ + public void rename(IRSession session, RName newname)throws RulesException{ + ruleset.getEntityFactory(session).deleteDecisionTable(dtname); + ruleset.getEntityFactory(session).newDecisionTable(newname, session); + } + + /** + * Create a Decision Table + * @param tables + * @param name + * @throws RulesException + */ + + public RDecisionTable(IRSession session, RuleSet _ruleset, String name) throws RulesException{ + ruleset = _ruleset; + dtname = RName.getRName(name,true); + EntityFactory ef = ruleset.getEntityFactory(session); + RDecisionTable dttable =ef.findDecisionTable(RName.getRName(name)); + if(dttable != null){ + new CompilerError(CompilerError.Type.TABLE,"Duplicate Decision Tables Found",0,0); + } + } + + /** + * Compile each condition and action. We mark the decision table as + * uncompiled if any error is detected. However, we still attempt to + * compile all conditions and all actions. + */ + public List compile(){ + compiled = true; // Assume the compile will work. + rconditions = new IRObject[conditionsPostfix.length]; + ractions = new IRObject[actionsPostfix.length]; + rinitialActions = new IRObject[initialActionsPostfix.length]; + + for(int i=0; i< initialActions.length; i++){ + try { + rinitialActions[i] = RString.compile(ruleset, initialActionsPostfix[i],true); + } catch (Exception e) { + errorlist.add( + new CompilerError( + ICompilerError.Type.INITIALACTION, + "Postfix Interpretation Error: "+e, + initialActionsPostfix[i], + i + ) + ); + compiled = false; + rinitialActions[i]=RNull.getRNull(); + } + } + + for(int i=0;i edepth)state.entitypop(); // Pop off extra entities. + } + + /** + * Builds (if necessary) the internal representation of the decision table, + * then validates that structure. + * @return true if the structure builds and is valid; false otherwise. + */ + public List getErrorList() { + if(decisiontree==null){ + errorlist.clear(); + build(); + } + return errorlist; + } + + + + + /** + * Builds the decision tree, which is a binary tree of "DTNode"'s which can be executed + * directly. This defines the execution of a Decision Table. + *

+ * The way we build this binary tree is we walk down each column, tracing + * that column's path through the decision tree. Once we are at the end of the column, + * we add on the actions. This algorithm assumes that a decision table describes + * a complete decision tree, i.e. there is no set of posible condition states which + * are not explicitly handled by the decision table. + * + */ + void buildBalanced() { + compile(); + if(conditiontable[0].length == 0 || // If we have no conditions, or + conditiontable[0][0].equals("*")){ // If *, we just execute all actions + decisiontree = ANode.newANode(this,0); // checked in the first column + return; + } + + decisiontree = new CNode(this,0,0, rconditions[0]); // Allocate a root node. + + for(int col=0;col"); + p.print(body); + p.print(""); + newline = false; + } + + private void openTag(PrintStream p,String tag){ + if(!newline){p.println();} + p.print("<"); p.print(tag); p.print(">"); + newline=false; + } + + /** + * Write the XML representation of this decision table to the given outputstream. + * @param o Output stream where the XML for this decision table will be written. + */ + public void writeXML(PrintStream p){ + p.println(""); + newline = true; + printattrib(p,"table_name",dtname.stringValue()); + Iterator ifields = fields.keySet().iterator(); + while(ifields.hasNext()){ + RName name = ifields.next(); + printattrib(p,name.stringValue(),fields.get(name)); + } + openTag(p, "conditions"); + for(int i=0; i< conditions.length; i++){ + openTag(p, "condition_details"); + printattrib(p,"condition_number",(i+1)+""); + printattrib(p,"condition_description",GenericXMLParser.encode(conditions[i])); + printattrib(p,"condition_postfix",GenericXMLParser.encode(conditionsPostfix[i])); + printattrib(p,"condition_comment",GenericXMLParser.encode(conditionsComment[i])); + p.println(); + newline=true; + for(int j=0; j"); + } + p.println(""); + } + p.println(""); + openTag(p, "actions"); + for(int i=0; i< actions.length; i++){ + openTag(p, "action_details"); + printattrib(p,"action_number",(i+1)+""); + printattrib(p,"action_description",GenericXMLParser.encode(actions[i])); + printattrib(p,"action_postfix",GenericXMLParser.encode(actionsPostfix[i])); + printattrib(p,"action_comment",GenericXMLParser.encode(actionsComment[i])); + p.println(); + newline=true; + for(int j=0; j0){ + p.println(""); + } + } + p.println(""); + } + p.println(""); + p.println(""); + } + + + /** + * All Decision Tables are executable. + */ + public boolean isExecutable() { + return true; + } + + /** + * The string value of the decision table is simply its name. + */ + public String stringValue() { + String number = fields.get("ipad_id"); + if(number==null)number = ""; + return number+" "+dtname.stringValue(); + } + + /** + * The string value of the decision table is simply its name. + */ + public String toString() { + return stringValue(); + } + + /** + * Return the postFix value + */ + public String postFix() { + return dtname.stringValue(); + } + + /** + * The type is Decision Table. + */ + public int type() { + return iDecisiontable; + } + + /** + * @return the actions + */ + public String[] getActions() { + return actions; + } + + /** + * @return the actiontable + */ + public String[][] getActiontable() { + return actiontable; + } + + /** + * @return the conditions + */ + public String[] getConditions() { + return conditions; + } + + /** + * @return the conditiontable + */ + public String[][] getConditiontable() { + return conditiontable; + } + + public String getDecisionTableId(){ + return fields.get(RName.getRName("table_number")); + } + + public void setDecisionTableId(String decisionTableId){ + fields.put(RName.getRName("table_number"),decisionTableId); + } + + public String getPurpose(){ + return fields.get(RName.getRName("purpose")); + } + + public void setPurpose(String purpose){ + fields.put(RName.getRName("purpose"),purpose); + } + + public String getComments(){ + return fields.get(RName.getRName("comments")); + } + + public void setComments(String comments){ + fields.put(RName.getRName("comments"),comments); + } + + public String getReference(){ + return fields.get(RName.getRName("policy_reference")); + } + + public void setReference(String reference){ + fields.put(RName.getRName("policy_reference"),reference); + } + + /** + * @return the dtname + */ + public String getDtname() { + return dtname.stringValue(); + } + + + /** + * @return the ractions + */ + public IRObject[] getRactions() { + return ractions; +} + /** + * @param ractions the ractions to set + */ + public void setRactions(IRObject[] ractions) { + this.ractions = ractions; + } + + /** + * @return the rconditions + */ + public IRObject[] getRconditions() { + return rconditions; + } + + /** + * @param rconditions the rconditions to set + */ + public void setRconditions(IRObject[] rconditions) { + this.rconditions = rconditions; + } + + /** + * @param actions the actions to set + */ + public void setActions(String[] actions) { + this.actions = actions; + } + + /** + * @param actiontable the actiontable to set + */ + public void setActiontable(String[][] actiontable) { + this.actiontable = actiontable; + } + + /** + * @param conditions the conditions to set + */ + public void setConditions(String[] conditions) { + this.conditions = conditions; + } + + /** + * @param conditiontable the conditiontable to set + */ + public void setConditiontable(String[][] conditiontable) { + this.conditiontable = conditiontable; + } + + + /** + * @return the actionsComment + */ + public final String[] getActionsComment() { + return actionsComment; + } + + + /** + * @param actionsComment the actionsComment to set + */ + public final void setActionsComment(String[] actionsComment) { + this.actionsComment = actionsComment; + } + + + /** + * @return the actionsPostfix + */ + public final String[] getActionsPostfix() { + return actionsPostfix; + } + + + /** + * @param actionsPostfix the actionsPostfix to set + */ + public final void setActionsPostfix(String[] actionsPostfix) { + this.actionsPostfix = actionsPostfix; + } + + + /** + * @return the conditionsComment + */ + public final String[] getConditionsComment() { + return conditionsComment; + } + + + /** + * @param conditionsComment the conditionsComment to set + */ + public final void setConditionsComment(String[] conditionsComment) { + this.conditionsComment = conditionsComment; + } + + + /** + * @return the conditionsPostfix + */ + public final String[] getConditionsPostfix() { + return conditionsPostfix; + } + + + /** + * @param conditionsPostfix the conditionsPostfix to set + */ + public final void setConditionsPostfix(String[] conditionsPostfix) { + this.conditionsPostfix = conditionsPostfix; + } + + /** + * A little helpper function that inserts a new column in a table + * of strings organized as String table [row][column]; Inserts blanks + * in all new entries, so this works for both conditions and actions. + * @param table + * @param col + */ + private static void insert(String[][]table, int maxcol, final int col){ + for(int i=0; i col; j--){ + table[i][j]=table[i][j-1]; + } + table[i][col]=" "; + } + } + /** + * Insert a new column at the given column number (Zero based) + * @param col The zero based column number for the new column + * @throws RulesException + */ + public void insert(int col) throws RulesException { + if(maxcol>=16){ + throw new RulesException("TableTooBig","insert","Attempt to insert more than 16 columns in a Decision Table"); + } + insert(conditiontable,maxcol,col); + insert(actiontable,maxcol,col); + } + + /** + * Balances an unbalanced decision table. The additional columns have + * no actions added. There are two approaches to balancing tables. One + * is to have executed all columns whose conditions are met. The other is + * to execute only the first column whose conditions are met. This + * routine executes all columns whose conditions are met. + */ + public void buildUnbalanced(UnbalancedType type) { + + compile(); + + if( + conditiontable.length == 0 || + conditiontable[0].length == 0 || // If we have no conditions, or + conditiontable[0][0].equals("*")){ // If *, we just execute all actions + decisiontree = ANode.newANode(this,0); // checked in the first column + return; + } + + if(conditions.length<1){ + errorlist.add( + new CompilerError( + ICompilerError.Type.CONDITION, + "You have to have at least one condition in a decision table", + 0,0) + ); + } + if( conditiontable[0].length==0 || conditiontable[0][0].trim().equals("*"))return; + /** + * + */ + CNode top = new CNode(this,1,0,this.rconditions[0]); + int defaultCol = -1; // The Index of the Default Column + int allCol = -1; // The Index of the "All" Column (executed on all conditions) + for(int col=0;col= 0){ + defaults = ANode.newANode(this,defaultCol); + }else{ + defaults = new ANode(this); + } + addDefaults(top,defaults); // Add defaults to all unmapped branches + if(allCol >= 0) addAll(top, ANode.newANode(this,allCol)); // Add to all branches the All actions + decisiontree = optimize(top); // Optimize the given tree. + } + + /** + * Replace any untouched branches in the tree with a pointer + * to the defaults for this table. We only replace nulls. + * @param node + * @param defaults + * @return + */ + private DTNode addDefaults(DTNode node, ANode defaults){ + if(node == null ) return defaults; + if(node instanceof ANode)return node; + CNode cnode = (CNode)node; + cnode.iffalse = addDefaults(cnode.iffalse,defaults); + cnode.iftrue = addDefaults(cnode.iftrue, defaults); + return node; + } + + private void addAll(DTNode node, ANode all){ + if(node.getClass()==ANode.class){ + ((ANode)node).addNode(all); + }else{ + addAll( ((CNode)node).iffalse ,all); + addAll( ((CNode)node).iftrue ,all); + } + } + + /** + * Replaces the given DTNode with the optimized DTNode. + * @param node + * @return + */ + private DTNode optimize(DTNode node){ + ANode opt = node.getCommonANode(); + if(opt!=null){ + return opt; + } + CNode cnode = (CNode) node; + cnode.iftrue = optimize(cnode.iftrue); + cnode.iffalse = optimize(cnode.iffalse); + if(cnode.iftrue.equalsNode(cnode.iffalse)){ + return cnode.iftrue; + } + return cnode; + } + + /** + * Build a path through the decision tables for a particular column. + * This routine throws an exception, but the calling routine just ignores it. + * That way we don't flood the error list with lots of duplicate errors. + * @param here + * @param row + * @param col + * @return + */ + private DTNode processCol(UnbalancedType code, DTNode here, int row, int col) throws Exception{ + if(row >= conditions.length){ // Ah, end of the column! + ANode thisCol = ANode.newANode(this, col); // Get a new ANode for the column + + if(here!=null && code == UnbalancedType.FIRST){ // If we execute only the First, we are done! + thisCol = (ANode) here; + } + if(here!=null && code == UnbalancedType.ALL){ // If Some path lead here, fold the + thisCol.addNode((ANode)here); // old stuff in with this column. + } + return thisCol; // Return the mix! + } + + String v = conditiontable[row][col]; // Get the value from the condition table + boolean dcare = v.equals("-") || v.equals(" "); // Standardize Don't cares. + + if(!v.equalsIgnoreCase("y") && !v.equalsIgnoreCase("n") && !dcare){ + errorlist.add( + new CompilerError ( + ICompilerError.Type.CONTEXT, + "Bad value in Condition Table '"+v+"' at row "+(row+1)+" column "+(col+1), + v,0)); + } + if((here==null || here.getRow()!= row ) && dcare){ // If we are a don't care, but not on a row + return processCol(code,here,row+1,col); // that matches us, we skip this row for now. + } + + if(here==null){ // If this node is null, and I need + here = new CNode(this,col,row,rconditions[row]); // a condition node, create it! + }else if (here!=null && here.getRow()!= row ){ // If this is the wrong node, and I need + CNode t = new CNode(this,col,row,rconditions[row]); // a condition node, create a new one and insert it. + t.iffalse = here; // Put the node I have on the false tree + t.iftrue = here.cloneDTNode(); // and its clone on the true path. + here = t; // Continue with the new node. + } + + if(v.equalsIgnoreCase("y") || dcare){ // If 'y' or a don't care, + DTNode next = ((CNode) here).iftrue; // Recurse on the True Branch. + ((CNode) here).iftrue = processCol(code,next,row+1,col); + } + if (v.equalsIgnoreCase("n")|| dcare){ // If 'n' or a don't care, + DTNode next = ((CNode) here).iffalse; // Recurse on the False branch. Note that + ((CNode) here).iffalse = processCol(code,next,row+1,col); // Don't care branches both ways. + } + return here; // Return the Condition node. + } + + /** + * In the case of an unbalanced decision table, this method returns a balanced + * decision table using one of the two unbalanced rules: FIRST (which executes only + * the first column whose conditions are matched) and ALL (which executes all columns + * whose conditions are matched). If the decision table is balanced, this method returns + * an "optimized" decision table where all possible additional "don't cares" are inserted. + * + * @return + */ + RDecisionTable balancedTable(IRSession session) throws RulesException{ + if(balanceTable==null)balanceTable = new BalanceTable(this); + return balanceTable.balancedTable(session); + } + + public BalanceTable getBalancedTable() throws RulesException { + return new BalanceTable(this); + } + + public Iterator DecisionTablesCalled(){ + ArrayList tables = new ArrayList(); + ArrayList stack = new ArrayList(); + for(int i=0;i stack, List tables){ + if(action==null)return; + if(action.type()==iArray){ + RArray array = (RArray)action; + if(stack.contains(array))return; // We have already been here. + stack.add(array); + try { // As this is an array, arrayValue() will not ever throw an exception + @SuppressWarnings({"unchecked"}) + Iterator objects = array.arrayValue().iterator(); + while(objects.hasNext()){ + addTables((IRObject) objects.next(),stack,tables); + } + } catch (RulesException e) { } + } + if(action.type()==iDecisiontable && !tables.contains(action)){ + tables.add((RDecisionTable)action); + } + } + /** + * Returns the list of Decision Tables called by this Decision Table + * @return + */ + ArrayList decisionTablesCalled(){ + ArrayList calledTables = new ArrayList(); + + addlist(calledTables, rinitialActions); + addlist(calledTables, rconditions); + addlist(calledTables, ractions); + + return calledTables; + } + /** + * We do a recursive search down each IRObject in these lists, looking for + * references to Decision Tables. We only add references to Decision Tables + * to the list of called tables if the list of called tables doesn't yet have + * that reference. + * + * @param calledTables + * @param list + */ + private void addlist(ArrayList calledTables, IRObject [] list){ + for(int i=0; i tables = new ArrayList(); + ArrayList stack = new ArrayList(); + getTables(stack, tables, list[i]); + for(RDecisionTable table : tables){ + if(!calledTables.contains(table))calledTables.add(table); + } + } + } + /** + * Here we do a recursive search of all the constructs in an IROBject. This + * is because some IRObjects are arrays, so we search them as well. + * @param obj + * @return + */ + private ArrayList getTables(ArrayListstack, ArrayList tables, IRObject obj){ + + if(obj instanceof RDecisionTable) tables.add((RDecisionTable) obj); + if(obj instanceof RArray && !stack.contains(obj)){ + stack.add((RArray) obj); + for(IRObject obj2 : (RArray) obj){ + getTables(stack,tables,obj2); + } + } + return tables; + } +} diff --git a/DTRules/src/main/java/com/dtrules/entity/IREntity.java b/DTRules/src/main/java/com/dtrules/entity/IREntity.java new file mode 100644 index 0000000..e039e17 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/entity/IREntity.java @@ -0,0 +1,158 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.entity; + +import java.io.PrintStream; +import java.util.Iterator; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; + +public interface IREntity extends IRObject{ + + /** + * This is the attribute name used by DTRules to map data from + * XML files into Rules Engine Entitites. + * + */ + public final RName mappingKey = RName.getRName("mapping*key"); + /** + * Returns if the Entity is read only or not + */ + public boolean isReadOnly(); + /** + * Returns an iterator for the attributes of an REntity. Each Key + * is itself an RName. + */ + public abstract Iterator getAttributeIterator(); + + /** + * Remove the attribute of the given name from this Entity. Should only be + * used by Rules Maintanence code, not by runtime code. + * @param attrib attribute name to be removed. + */ + public abstract void removeAttribute(RName attrib); + + /** + * Add the attribute defined by this REntityEntry to this Entity. The assumption + * is that everything in the entry is set up correctly, and only the index to the + * value needs to be adjusted (and then only if the attribute isn't defined already). + * + * @param entry Entry providing the meta data for a new attribute. + */ + public void addAttribute(REntityEntry entry); + + /** + * This adds an attribute into the REntity. This is called by the Entity + * construction during the loading of the Entity Description Dictionary. + * + * @param defaultvalue + * @param writable + * @param type + * @return Error string if the add failed, or a null on success. + */ + public String addAttribute( RName attributeName, String defaulttxt, IRObject defaultvalue,boolean writable, boolean readable, int type, String subtype); + + /** + * Returns the name of this entity. + */ + public abstract RName getName(); + + /** + * Here is where we set a value of an attribute within an Entity. We take the + * attribute name, look up that attribute and insure that the value type matches + * the type expected by the attribute entry. All types accept a RNull value. + * + * @param attrib + * @param value + * @throws RulesException + */ + public abstract void put(RName attrib, IRObject value) + throws RulesException; + + /** + * Returns an IRObject if this Entity defines an attribute of the given name. + * Otherwise it returns a null. This method should be avoided if a RName is + * easily available. + * @param attrib + * @return + */ + public IRObject get(String attribName); + + /** + * Returns an IRObject if this Entity defines an attribute of the given name. + * Otherwise it returns a null. + * @param attrib + * @return + */ + public abstract IRObject get(RName attrib); + + /** + * Returns the indexed value of a key/value pair. Sometimes we look at the + * EntityEntry before we grab the object. This avoids an extra hash lookup. + * @param i + * @return + */ + public abstract IRObject get(int i); + + /** + * This method returns the Entry for an attribute. An Entry allows the caller + * to see the type and other information about the attribute in addition to its + * value. If the attribute is undefined, a null is returned. + * @param attrib + * @return + */ + public abstract REntityEntry getEntry(RName attrib); + + /** + * Then sometimes they change their mind and want the value from an REntityEntry + * @param index + * @return + */ + public abstract IRObject getValue(int index); + + /** + * Returns the ID number for this instance of the entity. Entities with + * an ID of zero are reference entities. + * @return + */ + public int getID(); + + /** + * Checks to see if the given attribute is defined by this entity. + * @param attName + * @return + */ + public boolean containsAttribute(RName attName); + + /** + * Sets a value into the values array. Should not be called directly, + * but only through DTState. We should refactor to enforce this. + */ + public void set(int i, IRObject v); + + /** + * Writes the XML representation of this Entity to the given printstream. + * All the attributes are written along with their default values. The self + * referential attribute is not written. + * @param p printstream to which the XML representation of this Entity is written. + */ + public void writeXML(PrintStream p) throws RulesException; +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/entity/REntity.java b/DTRules/src/main/java/com/dtrules/entity/REntity.java new file mode 100644 index 0000000..ea6d041 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/entity/REntity.java @@ -0,0 +1,357 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.entity; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.ARObject; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RNull; +import com.dtrules.session.IRSession; +import com.dtrules.session.RSession; + +/** + * Entities serve as the dictionaries of the Rules Engine. These + * Dictionaries are typed Hashtables. In other words, you can't + * just put any old object into an Entity. There has to be an + * attribute with the appropriate name and type in order to put + * a particular object with that name into an Entity. + *

+ * This structure catches many data entry and program structure + * errors, as well as provides for a number of convienent automatic + * data conversions (if the compiler writer cares to provide such + * facilities). + * + * @author Paul Snow + * + */ +public class REntity extends ARObject implements IREntity { + + public void removeAttribute(RName attrib) { + attributes.remove(attrib); + } + + /** This attribute's name */ + final RName name; + boolean readonly; + + HashMap attributes; + ArrayList values = new ArrayList(); + + /** + * A readonly entity cannot be modified at run time. + */ + public boolean isReadOnly(){ return readonly; } + + /** + * All reference Entities (i.e. those from which we clone instances) have + * an id of zero. Clones have an id that is non zero, and unique. + */ + final int id; + + /** + * Returns the ID number for this instance of the entity. Entities with + * an ID of zero are reference entities. + * @return + */ + public int getID(){ return id;} + + /** + * Returns an interator that provides all the names of all the attributes for this entity. + */ + public Iterator getAttributeIterator(){ + return attributes.keySet().iterator(); + } + /** + * Checks to see if the given attribute is defined by this entity. + * @param attName + * @return + */ + public boolean containsAttribute(RName attName){ + return attributes.containsKey(attName); + } + + /** + * Create a clone of an Entity. + * + */ + public REntity( boolean _readonly, REntity entity, IRSession s) throws RulesException{ + id = s.getUniqueID(); + readonly = _readonly; + name = entity.name; + attributes = entity.attributes; + values = new ArrayList(entity.values); + for(int i=0;i(); + this.addAttribute(_name, "", this, false, true, type(),null); // Add a reference to self! + this.addAttribute(mappingKey,"",RNull.getRNull(),false, true, iString,null); + } + + /* (non-Javadoc) + * @see com.dtrules.entity.IREntity#getName() + */ + public RName getName(){ + return name; + } + + /** + * Adds this REntityEntry to this Entity. If an EntityEntry already exists, it will + * be replaced by this new one, no questions asked. The assumption is that one is + * editing the Attributes of the Entity, and the latest is the the right one to keep. + * + * @param entry The new Attribute meta data. + * + */ + public void addAttribute(REntityEntry entry){ + REntityEntry oldentry = getEntry(entry.attribute); + if(oldentry!=null){ // If the attribute already exists + entry.index = oldentry.index; // replace the old one (keep their index) + }else{ + entry.index = values.size(); // If the attribute is new, make a new + values.add(RNull.getRNull()); // value index. + } + if(entry.defaultvalue==null){ // Update with the default value. + values.set(entry.index, RNull.getRNull()); + }else{ + values.set(entry.index, entry.defaultvalue); + } + + attributes.put(entry.attribute,entry); // Put the new Entity Entry into this Entity. + + } + + /** + * This adds an attribute into the REntity. This is called by the Entity + * construction during the loading of the Entity Description Dictionary. + * + * @param defaultvalue Default value for this tag + * @param writable If true, the attribute is writable by decision tables + * @param readable If true, the attribute is readable by decision tables + * @param type + * @return null if successful, and an Error string if it failed. + */ + public String addAttribute(RName attributeName, + String defaulttxt, + IRObject defaultvalue, + boolean writable, + boolean readable, + int type, + String subtype ){ + REntityEntry entry = getEntry(attributeName); + if(entry==null){ + int index = values.size(); + if(defaultvalue==null){ + values.add(RNull.getRNull()); + }else{ + values.add(defaultvalue); + } + REntityEntry newEntry = new REntityEntry(this,attributeName,defaulttxt, defaultvalue,writable,readable,type,subtype,index); + + attributes.put(attributeName,newEntry); + return null; + } + if(entry.type!=type){ + String type1 =""; + String type2 =""; + try{ + type1="("+ RSession.typeInt2Str(entry.type)+") "; + }catch(RulesException e){} + try{ + type2="("+ RSession.typeInt2Str(type)+")"; + }catch(RulesException e){} + + return "The entity '"+name.stringValue()+ + "' has an attribute '"+attributeName.stringValue()+ + "' with two types: "+type1+" and "+ type2+ "\n"; + } + return null; // Entry already matches what we already have. + } + /* (non-Javadoc) + * @see com.dtrules.entity.IREntity#put(com.dtrules.interpreter.RName, com.dtrules.interpreter.IRObject) + */ + public void put(RName attrib, IRObject value) throws RulesException { + REntityEntry entry = (REntityEntry)attributes.get(attrib); + if(entry==null)throw new RulesException("Undefined", "REntity.put()", "Undefined Attribute "+attrib+" in Entity: "+name); + if(value.type()!= iNull && entry.type != value.type()){ + switch(entry.type) { + case iInteger : value = value.rIntegerValue(); break; + case iDouble : value = value.rDoubleValue(); break; + case iBoolean : value = value.rBooleanValue(); break; + //case iDecisiontable : value = value.rDecisiontableValue(); break; + case iEntity : value = value.rEntityValue(); break; + //case iMark : value = value.rMarkValue(); break; + case iName : value = value.rNameValue(); break; + //case iOperator : value = value.rOperatorValue(); break; + case iString : value = value.rStringValue(); break; + case iTime : value = value.rTimeValue(); break; + } + } + values.set(entry.index,value); + } + + /** + * Looks up the name of an attribute, + * and returns the associated value. + * If no value is defined, returns a null. + */ + public IRObject get(String attribName) + { + return get(RName.getRName(attribName)); + } + + /** + * Looks up the given name, and returns the associated value. If + * no value is defined, returns a null. + */ + public IRObject get(RName attrib) { + REntityEntry entry = (REntityEntry)attributes.get(attrib); + if(entry==null)return null; + return (IRObject) values.get(entry.index); + } + + /* (non-Javadoc) + * @see com.dtrules.entity.IREntity#get(int) + */ + public IRObject get(int i) { + return (IRObject) values.get(i); + } + + /** + * Sets a value in the values array. Should only be used + * RARELY outside of REntity. + * @param i + * @param v + */ + public void set(int i, IRObject v){ + values.set(i, v); + } + /** + * Returns an object that describes all the information we track about an + * Entity Attribute (the key to get its value). If the attribute is undefined, + * then a null is returned. + */ + public REntityEntry getEntry(RName attrib) { + REntityEntry entry = (REntityEntry)attributes.get(attrib); + return entry; + } + /* (non-Javadoc) + * @see com.dtrules.entity.IREntity#getValue(int) + */ + public IRObject getValue(int index) { + return (IRObject) values.get(index); + } + + + /* (non-Javadoc) + * @see com.dtrules.entity.IREntity#postFix() + */ + public String postFix() { + return "/"+name.stringValue()+" "+id+" createEntity "; + } + + /* (non-Javadoc) + * @see com.dtrules.entity.IREntity#stringValue() + */ + public String stringValue() { + return name.stringValue(); + } + + /* (non-Javadoc) + * @see com.dtrules.entity.IREntity#type() + */ + public int type() { + return iEntity; + } + + public String toString(){ + String v = name.stringValue()+" = {"; + Iterator ia = getAttributeIterator(); + while(ia.hasNext()){ + RName n = ia.next(); + IRObject o = get(n); + if(o==null){ // Protect ourselves from nulls. + o = RNull.getRNull(); + } + v +=n.stringValue()+" = "+get(n).stringValue()+" "; + } + v +="}"; + return v; + + } + + public IRObject clone(IRSession s) throws RulesException { + if(readonly)return this; + return new REntity(false,this,s); + } + + /** + * Returns itself + */ + public IREntity rEntityValue() throws RulesException { + return this; + } + + public void writeXML(PrintStream p) throws RulesException { + Iterator attribs = getAttributeIterator(); + p.println(); + while(attribs.hasNext()){ + RName attrib = attribs.next(); + if(attrib.equals(name))continue; // Skip the self reference. + REntityEntry entry = attributes.get(attrib); + p.print(""); + p.print(name.stringValue()); + p.println(""); + } + } +} diff --git a/DTRules/src/main/java/com/dtrules/entity/REntityEntry.java b/DTRules/src/main/java/com/dtrules/entity/REntityEntry.java new file mode 100644 index 0000000..707412a --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/entity/REntityEntry.java @@ -0,0 +1,195 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.entity; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.session.RSession; + +/** + * + * A Entry holds the attribute type and attribute value as held in an + * Entity. Past implementations of the Rules Engine used a separate + * Attribute and Value hashmaps. However, too many operations require + * both an inspection of the attribute as well as the value. So now + * I have one hashmap for the attribute, which provides an index into + * an ArrayList to get the value. + * + * @author Paul Snow + * + */ +public class REntityEntry { + public REntity entity; // The entity involved. + public RName attribute; // The name of this attribute. + public String defaulttxt; // Text for the default value. + public IRObject defaultvalue; // Every Entry has default value, which may be null. + public boolean writable; // We allow Entries to be locked. + public boolean readable; // We allow some Entries to be write only. + public int type; // The type value, i.e. integer, float, etc. as defined + // by IRObject + public String subtype; // The Subtype (for some kinds of attributes)... + public int index; // Index into the values array to get the current + // value for this attribute. + public String typeValue; + + /** + * Allows the insertion of the REntityEntry into an Entity after the + * fact. + * @param newIndex The index into the values array where the value of this attribute can be found. + */ + void updateIndex(int newIndex){ + index = newIndex; + } + + REntityEntry( + REntity _entity, + RName _attribute, + String _defaulttxt, + IRObject _defaultvalue, + boolean _writable, + boolean _readable, + int _type, + String _subtype, + int _index){ + attribute = _attribute; + defaulttxt = _defaulttxt; + defaultvalue = _defaultvalue; + writable = _writable; + readable = _readable; + type = _type; + subtype = _subtype; + index = _index; + } + + @Override + public String toString() { + String thetype=""; + try{ + thetype = "("+RSession.typeInt2Str(type)+")"; + }catch(Exception e){} + return thetype +" default: "+defaulttxt; + } + + /** + * @return the attribute + */ + public RName getAttribute() { + return attribute; + } + + /** + * @param attribute the attribute to set + */ + public void setAttribute(RName attribute) { + this.attribute = attribute; + } + + /** + * @return the defaulttxt + */ + public String getDefaulttxt() { + return defaulttxt; + } + + /** + * @param defaulttxt the defaulttxt to set + */ + public void setDefaulttxt(String defaulttxt) { + this.defaulttxt = defaulttxt; + } + + /** + * @return the defaultvalue + */ + public IRObject getDefaultvalue() { + return defaultvalue; + } + + /** + * @param defaultvalue the defaultvalue to set + */ + public void setDefaultvalue(IRObject defaultvalue) { + this.defaultvalue = defaultvalue; + } + + /** + * @return the type + */ + public int getType() { + return type; + } + + /** + * @param type the type to set + */ + public void setType(int type) throws RulesException { + this.type = type; + setTypeValue(RSession.typeInt2Str(type)); + } + + /** + * @return the writable + */ + public boolean isWritable() { + return writable; + } + + /** + * @param writable the writable to set + */ + public void setWritable(boolean writable) { + this.writable = writable; + } + + public String getTypeValue() throws RulesException { + if(typeValue==null)typeValue=RSession.typeInt2Str(type); + return typeValue; + } + + public void setTypeValue(String typeValue) throws RulesException{ + this.typeValue = typeValue; + setType(RSession.typeStr2Int(typeValue,entity.getName().stringValue(),attribute.stringValue())); + } + + public String getAttributeStrValue() { + return attribute.stringValue(); + } + + public void setAttributeStrValue(String attributeStrValue) { + setAttribute(RName.getRName(attributeStrValue)); + } + + public final int getIndex() { + return index; + } + + public final void setIndex(int index) { + this.index = index; + } + + /** + * @return the subtype + */ + public String getSubtype() { + return subtype; + } + + +} diff --git a/DTRules/src/main/java/com/dtrules/infrastructure/RulesException.java b/DTRules/src/main/java/com/dtrules/infrastructure/RulesException.java new file mode 100644 index 0000000..781d4a4 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/infrastructure/RulesException.java @@ -0,0 +1,115 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.infrastructure; + +import javax.rules.RuleException; + +public class RulesException extends RuleException { + String errortype; + String location; + String message; + String decisionTable=""; + String postfix = null; + String filename = null; + String section = null; + int number; + + public void setPostfix(String s){ + if(postfix == null){ + postfix = s; + } + } + + public String getPostfix(){ + return postfix; + } + + /** + * Get the DecisionTable under execution at the time the error + * occurred. Returns a null if unknown. + * @return + */ + public String getDecisionTable() { + return decisionTable; + } + + /** + * Set the decisionTable under execution when the error occurred. + * @param decisionTable + */ + public void addDecisionTable(String decisionTable, String filename) { + if(filename==null)filename=""; + if(this.decisionTable.length()==0){ + this.decisionTable = decisionTable+" \n"; + }else { + this.decisionTable = this.decisionTable+" called by: "+decisionTable+" \t("+filename+")\n"; + } + if(this.filename == null) this.filename = filename; + } + + public RulesException(String type, String _location, String _message ){ + super("Location :"+_location+" type: "+type+" error: "+_message); + location = _location; + errortype = type; + message = _message; + } + + static final long serialVersionUID = 0; + + /** + * Provide my view of a Rules Exception; + */ + public String toString() { + + return + (decisionTable!="" ? "\nDecision Table: "+decisionTable:"\n") + + "File name: "+filename+"\n"+ + ((section!= null) ? ("Section: "+section + " " + number +"\n"):"")+ + ((postfix!= null) ? ("Postfix: "+postfix+"\n"):"")+ + "Location: '"+location+"'\n" + + "Type: '"+errortype+"'\n" + + "Error: '"+message+"'\n" ; + } + + /** + * @return the section + */ + public String getSection() { + return section; + } + + /** + * @param section the section to set + */ + public void setSection(String section, int number) { + if(this.section == null){ + this.section = section; + this.number = number; + } + } + + /** + * @return the number + */ + public int getNumber() { + return number; + } + + +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/ARObject.java b/DTRules/src/main/java/com/dtrules/interpreter/ARObject.java new file mode 100644 index 0000000..ab3fe7f --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/ARObject.java @@ -0,0 +1,169 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; + +import com.dtrules.entity.IREntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.mapping.XMLTag; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; + +public abstract class ARObject implements IRObject { + + /** + * No point in implementing this here. Every Object that has + * an array representation needs to implement it themselves. + */ + public RArray rArrayValue() throws RulesException { + throw new RulesException("Conversion Error","ARObject","No Time value exists for "+this.stringValue()); + } + + public RBoolean rBooleanValue() throws RulesException { + return RBoolean.getRBoolean(booleanValue()); + } + + public RDouble rDoubleValue() throws RulesException { + return RDouble.getRDoubleValue(doubleValue()); + } + + public RTime rTimeValue() throws RulesException { + return RTime.getRTime(timeValue()); + } + + public Date timeValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Time value exists for: "+this); + } + + public void execute(DTState state) throws RulesException { + state.datapush(this); + } + + public IRObject getExecutable(){ + return this; + } + + public IRObject getNonExecutable() { + return this; + } + + public boolean equals(IRObject o) throws RulesException { + return o==this; + } + + public boolean isExecutable() { + return false; + } + + public String postFix() { + return toString(); + } + + public RString rStringValue() { + return RString.newRString(stringValue()); + } + + public IRObject rclone() { + return (IRObject) this; + } + + /** Conversion Methods. Default is to throw a RulesException **/ + + public int intValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Integer value exists for "+this); + } + + public ArrayList arrayValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Array value exists for "+this); + } + + public boolean booleanValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Boolean value exists for "+this); + } + + public double doubleValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No double value exists for "+this); + } + + public IREntity rEntityValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Entity value exists for "+this); + } + @SuppressWarnings({"unchecked"}) + public HashMap hashMapValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Integer value exists for "+this); + } + + public long longValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Long value exists for "+this); + } + + public RName rNameValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Integer value exists for "+this); + } + + public RInteger rIntegerValue() throws RulesException { + throw new RulesException("Undefined","Conversion Error","No Integer value exists for "+this); + } + + public int compare(IRObject irObject) throws RulesException { + throw new RulesException("Undefined","No Supported","Compared Not suppoted for this object"+this); + } + + /** + * By default, objects clone themselves by simply returnning themselves. + * This is because the clone of a number or boolean etc. is itself. + */ + public IRObject clone(IRSession s) throws RulesException { + return this; + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.IRObject#rTableValue() + */ + public RTable rTableValue() throws RulesException { + throw new RulesException("Undefined","Not Supported","No Table value exists for "+this); + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.IRObject#tableValue() + */ + @SuppressWarnings({"unchecked"}) + public HashMap tableValue() throws RulesException { + throw new RulesException("Undefined","Not Supported","No Table value exists for "+this); + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.IRObject#rXmlValue() + */ + public RXmlValue rXmlValue() throws RulesException { + throw new RulesException("Conversion Error","","No XmlValue value exists for "+this); + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.IRObject#xmlTagValue() + */ + public XMLTag xmlTagValue() throws RulesException { + throw new RulesException("Conversion Error","","No XmlValue value exists for "+this); + } + +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/IRObject.java b/DTRules/src/main/java/com/dtrules/interpreter/IRObject.java new file mode 100644 index 0000000..e8ae333 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/IRObject.java @@ -0,0 +1,128 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + + +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; + +import com.dtrules.entity.IREntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.mapping.XMLTag; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; + +@SuppressWarnings({"unchecked"}) +public interface IRObject { + + public IRObject clone(IRSession s) throws RulesException; + + // *************** NOTE !!!!!! + // You can't put static methods on an interface. So the String to integer conversion + // for types is a static method on the RSession class. + + final String rBoolean = "boolean", + rString = "string", + rInteger = "integer", + rFloat = "float", + rEntity = "entity", + rName = "name", + rArray = "array", + rDecisiontable = "decisiontable", + rNull = "null", + rMark = "mark", + rOperator = "operator", + rTime = "time", + rTable = "table", + rXmlValue = "xmlvalue"; + + final String types[] = { rBoolean, rString, rInteger, rFloat, + rEntity, rName, rArray, rDecisiontable, + rNull, rMark, rOperator, rTime, + rTable, rXmlValue}; + + final int iBoolean = 0, + iString = 1, + iInteger = 2, + iDouble = 3, + iEntity = 4, + iName = 5, + iArray = 6, + iDecisiontable = 7, + iNull = 8, + iMark = 9, + iOperator = 10, + iTime = 11, + iTable = 12, + iXmlValue = 13; + + + void execute(DTState state) throws RulesException; + + public IRObject getExecutable(); + + public IRObject getNonExecutable(); + + public boolean equals(IRObject o) throws RulesException; + + public boolean isExecutable(); + + /** + * By default, the toString() method for most Objects should provide + * a representation of the object that can be used as the postFix value. + * The stringValue should provide simply the data for the object. Thus + * If I want to append the a String and a Date to create a new string, + * I should append the results from their stringValue() implementation. + *

+ * If I needed the postfix (and thus the quotes and maybe other ) then + * call postFix(). But if the postFix is going to match either stringValue() + * or toString, it is going to match toString(). + *

+ * @return + */ + public String stringValue(); + public RString rStringValue(); + + public String postFix(); + + public int type(); + + public IRObject rclone(); + + public XMLTag xmlTagValue() throws RulesException; + public long longValue () throws RulesException; + public int intValue () throws RulesException; + public RInteger rIntegerValue() throws RulesException; + public double doubleValue () throws RulesException; + public RDouble rDoubleValue() throws RulesException; + public ArrayList arrayValue () throws RulesException; + public RArray rArrayValue() throws RulesException; + public boolean booleanValue () throws RulesException; + public RBoolean rBooleanValue() throws RulesException; + public HashMap hashMapValue () throws RulesException; + public RXmlValue rXmlValue () throws RulesException; + public IREntity rEntityValue () throws RulesException; + public RName rNameValue () throws RulesException; + public RTime rTimeValue () throws RulesException; + public Date timeValue () throws RulesException; + public RTable rTableValue() throws RulesException; + public HashMap tableValue() throws RulesException; + public int compare(IRObject irObject) throws RulesException; +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/RArray.java b/DTRules/src/main/java/com/dtrules/interpreter/RArray.java new file mode 100644 index 0000000..232fdfe --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/RArray.java @@ -0,0 +1,271 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; +/** + * Immplements Arrays for Decision Tables. Because we can't tag references, + * we do the same trick here that we do for RNames, i.e. we create an executable + * and a non-executable version of each array. However, we only create one + * ArrayList. + *

+ * If dups is true, we allow duplicate references in the array. Sometimes it + * is pleasent to have an array whose values are all unique. In that case, create + * an array with dups set to false.
+ *
+ * @author ps24876 + * + */ +@SuppressWarnings("unchecked") +public class RArray extends ARObject implements Collection { + final ArrayList array; + final RArray pair; + final boolean executable; + final boolean dups; + final int id; + + + + + + /* (non-Javadoc) + * @see java.util.Collection#addAll(java.util.Collection) + */ + public boolean addAll(Collection arg0) { + return array.addAll(arg0); + } + /* (non-Javadoc) + * @see java.util.Collection#clear() + */ + public void clear() { + array.clear(); + + } + /* (non-Javadoc) + * @see java.util.Collection#contains(java.lang.Object) + */ + public boolean contains(Object arg0) { + if(arg0 instanceof IRObject) { + for(IRObject o: array){ + try{ // Really this isn't possible. + if (o.equals((IRObject)arg0))return true; + }catch(RulesException e){} + } + } + return false; + } + /* (non-Javadoc) + * @see java.util.Collection#containsAll(java.util.Collection) + */ + public boolean containsAll(Collection arg0) { + return array.containsAll(arg0); + } + /* (non-Javadoc) + * @see java.util.Collection#isEmpty() + */ + public boolean isEmpty() { + return array.isEmpty(); + } + /* (non-Javadoc) + * @see java.util.Collection#iterator() + */ + public Iterator iterator() { + return array.iterator(); + } + /* (non-Javadoc) + * @see java.util.Collection#remove(java.lang.Object) + */ + public boolean remove(Object arg0) { + return array.remove(arg0); + } + /* (non-Javadoc) + * @see java.util.Collection#removeAll(java.util.Collection) + */ + public boolean removeAll(Collection arg0) { + return array.removeAll(arg0); + } + /* (non-Javadoc) + * @see java.util.Collection#retainAll(java.util.Collection) + */ + public boolean retainAll(Collection arg0) { + return retainAll(arg0); + } + /* (non-Javadoc) + * @see java.util.Collection#toArray() + */ + public Object[] toArray() { + return array.toArray(); + } + /* (non-Javadoc) + * @see java.util.Collection#toArray(T[]) + */ + public T[] toArray(T[] arg0) { + return array.toArray( arg0); + } + /** + * Returns the id of this array. Used by debuggers to analyze trace files + * @return ID of the array + */ + public int getID(){ return id; } + /** + * Constructor to create the core structure for an RArray. + * @param bogus + * @param exectuable + */ + protected RArray(int id, boolean duplicates, ArrayList thearray, RArray otherpair, boolean executable){ + this.id = id; + this.array = thearray; + this.executable = executable; + this.pair = otherpair; + this.dups = duplicates; + } + + public RArray(int id, boolean duplicates, boolean executable){ + this.id = id; + array = new ArrayList(); + this.executable = executable; + dups = duplicates; + pair = new RArray(id,dups, array, this, !executable); + } + + public RArray(int id, boolean duplicates, ArrayList thearray, boolean executable){ + this.id = id; + this.array = thearray; + this.executable = executable; + dups = duplicates; + pair = new RArray(id,dups,thearray,this,!executable); + } + + public Iterator getIterator(){ return array.iterator(); } + + public int type() { + return iArray; + } + public boolean add(IRObject v){ + if(!dups && array.contains(v))return false; + return array.add(v); + } + public void add(int index,IRObject v){ + array.add(index,v); + } + public void delete(int index){ + array.remove(index); + } + public void remove(IRObject v){ + array.remove(v); + } + public IRObject get(int index) throws RulesException{ + if(index<0 || index>= array.size()){ + throw new RulesException("Undefined","RArray","Index out of bounds"); + } + return (IRObject) array.get(index); + } + public ArrayList arrayValue() throws RulesException { + return array; + } + + public boolean equals(IRObject o) throws RulesException { + if(o.type() != iArray) return false; + return ((RArray)o).array == array; + } + + public void execute(DTState state) throws RulesException { + int cnt = 0; // A debugging aid. + for(IRObject obj : this){ + if(obj.type()==iArray || !obj.isExecutable()){ + state.datapush(obj); + }else{ + try{ + obj.execute(state); + }catch(RulesException e){ + e.setPostfix(this.postFix()); + throw e; + } + } + cnt++; + } + + } + + public IRObject getExecutable() { + if(executable)return this; + return pair; + } + + public IRObject getNonExecutable() { + if(!executable)return this; + return pair; + } + + public boolean isExecutable() { + return executable; + } + + public String postFix() { + StringBuffer result = new StringBuffer(); + result.append(executable?"{":"["); + for (IRObject obj : array){ + result.append(obj.postFix()); + result.append(" "); + } + result.append(executable?"}":"]"); + return result.toString(); + } + + public String stringValue() { + StringBuffer result = new StringBuffer(); + result.append(isExecutable()?"{ ":"[ "); + for(IRObject obj : array){ + result.append(obj.stringValue()); + result.append(" "); + } + result.append(isExecutable()?"}":"]"); + return result.toString(); + } + public String toString() { + return stringValue(); + } + + /** + * returns the clone of this object + */ + public IRObject clone(IRSession session) { + ArrayList newArray = new ArrayList(); + newArray.addAll(array); + return new RArray(session.getUniqueID(), dups, newArray, executable); + } + + public RArray rArrayValue() throws RulesException { + return this; + } + + /* + * Returns the size of the array. + */ + public int size() + { + return this.array.size(); + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/RBoolean.java b/DTRules/src/main/java/com/dtrules/interpreter/RBoolean.java new file mode 100644 index 0000000..5332ea2 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/RBoolean.java @@ -0,0 +1,121 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + +import com.dtrules.infrastructure.RulesException; + +public class RBoolean extends ARObject { + + /** + * Provides all the supported conversions of a String to a boolean value. + * @param value + * @return + * @throws RulesException + */ + public static boolean booleanValue(String value)throws RulesException { + String v = value.trim(); + if(v.equalsIgnoreCase("true") || + v.equalsIgnoreCase("y") || + v.equalsIgnoreCase("t") || + v.equalsIgnoreCase("yes")){ + return true; + }else if(v.equalsIgnoreCase("false") || + v.equalsIgnoreCase("n") || + v.equalsIgnoreCase("f") || + v.equalsIgnoreCase("no")){ + return false; + } + throw new RulesException("typecheck","String Conversion to Boolean","No boolean value for this string: "+value); + } + /** + * Really, there is no reason for more that two instances of Boolean objects + * in the Rules Engine world. + */ + private static RBoolean trueValue = new RBoolean(true); + private static RBoolean falseValue = new RBoolean(false); + /** + * The value of this boolean object. + */ + public final boolean value; + /** + * A private constructor to avoid any creation of boolean values besides + * the two (true and false) + * @param _value + */ + private RBoolean(boolean _value){ + value = _value; + } + /** + * Report that this is indeed a boolean object. + */ + public int type() { + return iBoolean; + } + /** + * Return the proper boolean object for the given boolean value. + * @param value + * @return + */ + public static RBoolean getRBoolean(boolean value){ + if(value)return trueValue; + return falseValue; + } + + /** + * Attempt to convert the string, and return the proper boolean object. + * @param value + * @return + * @throws RulesException + */ + public static RBoolean getRBoolean(String value) throws RulesException { + return getRBoolean(booleanValue(value)); + } + /** + * Return my value. + */ + public boolean booleanValue() throws RulesException { + return value; + } + /** + * We *COULD* simply do an object equality test... + */ + public boolean equals(IRObject o) throws RulesException { + return value == o.booleanValue(); + } + /** + * Return the string value for this boolean. + */ + public String stringValue() { + if(value)return "true"; + return "false"; + } + /** + * Return the string value for this boolean + */ + public String toString() { + return stringValue(); + } + /** + * The postfix is nothing more than the string value for this boolean. + */ + public String postFix() { + return stringValue(); + } + +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/RDouble.java b/DTRules/src/main/java/com/dtrules/interpreter/RDouble.java new file mode 100644 index 0000000..ee8ef3c --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/RDouble.java @@ -0,0 +1,127 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + +import com.dtrules.infrastructure.RulesException; + +/** + * @author Paul Snow + * + */ +public class RDouble extends ARObject { + final double value; + + static RDouble mone = new RDouble(-1.0); + static RDouble zero = new RDouble(0.0); + static RDouble one = new RDouble(1.0); + + private RDouble(double v){ + value = v; + } + + static public double getDoubleValue(String s) throws RulesException { + if(s==null || s.trim().length()==0){ + return 0.0D; + } + try { + double v = Double.parseDouble(s); + return v; + } catch (NumberFormatException e) { + throw new RulesException("Conversion Error","RDouble.getDoubleValue()","Could not covert the string '"+s+"' to a double: "+e.getMessage()); + } + } + /** + * Parses the given string, and returns an RDouble Object + * @param s String to parse + * @return RDouble value for the given string + * @throws RulesException + */ + static public RDouble getRDoubleValue(String s) throws RulesException { + return getRDoubleValue(getDoubleValue(s)); + } + + + + static public RDouble getRDoubleValue(double v){ + if(v == -1.0) return mone; + if(v == 0.0) return zero; + if(v == 1.0) return one; + + return new RDouble(v); + } + + static public RDouble getRDoubleValue(int v){ + return getRDoubleValue((double) v); + } + + static public RDouble getRDoubleValue(long v){ + return getRDoubleValue((double) v); + } + + public RDouble rDoubleValue() { + return this; + } + + public double doubleValue() { + return value; + } + + public int intValue() { + return (int) value; + } + + + public long longValue() { + return (long) value; + } + + public RInteger rIntegerValue() { + return RInteger.getRIntegerValue((long)value); + } + + /** + * Returns the type for this object. + */ + public int type() { + return iDouble; + } + + public String stringValue() { + return Double.toString(value); + } + + /** + * returns 0 if both are equal. -1 if this object is less than the argument. + * 1 if this object is greater than the argument + */ + public int compare(IRObject irObject) throws RulesException { + return (this.value==irObject.doubleValue())?0:((this.value=0){ + String entity = _name.substring(0,dot); + if(dot == 0 || dot+1 == _name.length() || _name.indexOf(dot+1,'.')>=0){ + throw new RuntimeException("Invalid Name Syntax: ("+_name+")"); + } + String name = _name.substring(dot+1); + return getRName(RName.getRName(entity),name,executable); + } + return getRName(null, _name, executable); + } + /** + * We cache the creation of RNames so as to not create new copies + * of RNames that we don't have to create. (RNames are reusable) + *

+ * Thus one calls one of the getRName functions, and one cannot call our + * constructors directly. + *

+ * Returns a null if a RName cannot be found/created. + * + * @param _name + * @return + */ + static public RName getRName(String _name, boolean _executable) { + // Fix the name; trim and then replace internal spaces with '_'. + _name = _name.trim().replaceAll(" ","_"); + return getRName(null,_name,_executable); + } + + static Pattern space = Pattern.compile(" "); + /** + * We cache the creation of RNames so as to not create new copies + * of RNames that we don't have to create. (RNames are reusable) + *

+ * Thus one calls one of the getRName functions, and one cannot call our + * constructors directly. + * + * @param _name + * @return + */ + static public RName getRName(RName _entity, String _name, boolean _executable) { + // Fix the name; trim and then replace internal spaces with '_'. + _name = space.matcher(_name).replaceAll("_"); + // If we already have the RName, we are done. + String lname = _name.toLowerCase(); + String cname = _name; + if(_entity!=null){ + cname = _entity.stringValue().toLowerCase()+"."+lname; + } + RName rn = (RName) names.get(cname); + if(rn == null ) { + rn = new RName(_entity ,_name,_executable, lname.hashCode()); + names.put(cname,rn); + } + if(_executable) return (RName) rn.getExecutable(); + return (RName) rn.getNonExecutable(); + } + /** + * Returns the entity component of the name, which is null if none + * was specfied when the name was created. + * + * @return + */ + public RName getEntityName(){ + return entity; + } + + public boolean equals(Object arg0) { + if(arg0.getClass()!=RName.class)return false; + boolean f = name.equalsIgnoreCase(((RName)arg0).name); + return f; + } + + public int hashCode() { + return hashcode; + } + + /** + * Compare this RName with another Rules Engine Object. RNames + * are only equal to other RNames. + */ + public boolean equals(IRObject o) { + if(o.type()!=IRObject.iName)return false; + return equals((Object)o); + } + static int cnt= 0; + /** + * The execution of an RName looks up that RName in the Entity + * Stack. If the object found there is an Array, it is pushed + * to the Entity Stack. If the object found there is not an + * array, and it is not executable, then it is pushed. Otherwise + * (not an array, and executable) the object is executed. + */ + public void execute(DTState state) throws RulesException { + cnt++; + IRObject o = state.find(this); // Does a lookup of the name on the Entity Stack + if(o==null){ + throw new RulesException("Undefined","RName","The Name '"+name+"' was not defined by any Entity on the Entity Stack"); + } + if(o.isExecutable()){ + o.execute(state); + }else{ + state.datapush(o); + } + } + + public IRObject getExecutable() { + return executable ? this : partner ; + } + + public IRObject getNonExecutable() { + return executable ? partner : this ; + } + + public boolean isExecutable() { + return executable; + } + + + /** + * Returns the postfix version of the name. + */ + public String postFix() { + return executable ? stringValue() : "/"+stringValue(); + } + + /** + * Returns the value of the name unadorned by the leading slash, even + * if the name is a literal. + */ + public String stringValue() { + if(entity!=null){ + return entity.stringValue()+"."+name; + } + return name; + } + + /** + * Returns the nicest format for debugging, i.e. the Postfix version which + * has the slash if the name is a literal name. + */ + public String toString(){ + return postFix(); + } + + public int type() { + return iName; + } + + @Override + public int compare(IRObject obj) throws RulesException { + String v = obj.stringValue(); + return name.compareToIgnoreCase(v); + } + /** + * Returns myself + */ + public RName rNameValue() throws RulesException { + return this; + } + /* (non-Javadoc) + * @see com.dtrules.interpreter.ARObject#rStringValue() + */ + @Override + public RString rStringValue() { + return RString.newRString(name); + } + +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/RNull.java b/DTRules/src/main/java/com/dtrules/interpreter/RNull.java new file mode 100644 index 0000000..ff95d94 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/RNull.java @@ -0,0 +1,85 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + +import com.dtrules.infrastructure.RulesException; + +public class RNull extends ARObject { + + /** + * returns 0 if both are equal. -1 Otherwise. A Null is considered + * less than anything else. We do this just so sorting arrays were + * some values are null doesn't blow up. + */ + public int compare(IRObject irObject) throws RulesException { + if(irObject.equals(this))return 0; // A Null is equal to other nulls. + return -1; // A Null is less than anything else. + } + + + + static RNull theNullObject = new RNull(); + /** + * Nobody needs the constructor. + * + */ + private RNull(){} + + /** + * Returns the RNull object. There is no need for more than + * one of these objects. + * @return + */ + public static RNull getRNull(){ return theNullObject; } + + /** + * A Null is only equal to the null object + */ + public boolean equals(IRObject o) { + return o.type()==iNull; + } + + public String stringValue() { + return "null"; + } + + /** + * A Null is only equal to the null object, i.e. any + * Null object. They are all equal. + */ + public boolean equals(Object arg0) { + return arg0.getClass().equals(this.getClass()); + } + + /** + * We override toString() to simply return "null". + * Because we do this, we override hashcode() as well. + */ + public String toString() { + return "null"; + } + + public int hashCode() { + return 0; + } + + public int type() { + return iNull; + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/RString.java b/DTRules/src/main/java/com/dtrules/interpreter/RString.java new file mode 100644 index 0000000..debdb8e --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/RString.java @@ -0,0 +1,312 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.operators.ROperator; +import com.dtrules.session.DTState; +import com.dtrules.session.RuleSet; + +/** + * @author Paul Snow + * + */ +public class RString extends ARObject { + + RString pair; + String value; + boolean executable = false; + + public double doubleValue() throws RulesException { + double d; + try { + d = Double.parseDouble(value); + } catch (NumberFormatException e) { + return super.doubleValue(); + } + return d; + } + + @Override + public int intValue() throws RulesException { + int i; + try { + i = Integer.parseInt(value); + } catch (NumberFormatException e) { + return super.intValue(); + } + return i; + } + + @Override + public long longValue() throws RulesException { + long l; + try { + l = Long.parseLong(value); + } catch (NumberFormatException e) { + return super.longValue(); + } + return l; + } + + @Override + public RDouble rDoubleValue() throws RulesException { + return RDouble.getRDoubleValue(doubleValue()); + } + + @Override + public RInteger rIntegerValue() throws RulesException { + return RInteger.getRIntegerValue(longValue()); + } + + @Override + public RName rNameValue() throws RulesException { + return RName.getRName(value); + } + + @Override + public RString rStringValue() { + return this; + } + + private RString(String v,boolean executable,RString pair){ + value = v; + this.pair = pair; + this.executable = executable; + } + /** + * Return a non Executable string + * @param v + * @return + */ + static public RString newRString(String v){ + return newRString(v,false); + } + /** + * Return an RString of the given executable nature. + * @param v + * @param executable + * @return + */ + static public RString newRString(String v, boolean executable){ + RString s = new RString(v,executable,null); + s.pair = new RString(v,!executable,s); + return s; + } + + @Override + public IRObject getExecutable() { + if(isExecutable()){ + return this; + }else{ + return pair; + } + } + + @Override + public IRObject getNonExecutable() { + if(isExecutable()){ + return pair; + }else{ + return this; + } + } + + /** + * Returns a boolean value if the String can be reasonably + * interpreted as a boolean. + * + * @Override + */ + public boolean booleanValue() throws RulesException { + return RBoolean.booleanValue(value); + } + + /** + * + */ + public RBoolean rBooleanValue() throws RulesException { + return RBoolean.getRBoolean(booleanValue()); + } + + /** + * Returns String type. + * @see com.dtrules.interpreter.IRObject#type() + */ + public int type() { + return iString; + } + + /** + * Here we look to see if we can do a compile time lookup of + * an object. If we can't, we just return the object unchanged. + * But if we can, then we return the value we looked up. That + * saves many, many runtime lookups. + */ + static IRObject lookup(RuleSet ruleset, RName name){ + IRObject v = ROperator.getPrimitives().get(name); // First check if it is an operator + if(v==null){ // No? Then + try { // look for a decision table. + v = ruleset.getEntityFactory(null).getDecisionTable(name); + } catch (RulesException e) { } // Any error just means the name isn't + } // a decision table. Not a problem. + if(v==null || v.type()== iArray) return name; + return v; + } + + /** + * Compiles the String and returns the executable Array Object + * that results. Unless the compilation fails, at which time + * we throw an exception. + * + * @return + * @throws RulesException + */ + static public IRObject compile(RuleSet rs, String v, boolean executable) throws RulesException{ + + if(v==null)v=""; // Allow the compiling of null strings (we just don't do anything). + + SimpleTokenizer tokenizer = new SimpleTokenizer(v); + + IRObject result = compile(rs, tokenizer, v, executable, 0); + return result; + } + + /** + * The compiles of Strings are recursive. When we see a [ or {, + * we recurse. Then on a close bracket ] or } we return the + * non-executable or executable array. The RString checks to make + * sure it is the right type, and throws an error if it isn't. + * The recursive depth is checked by compile(); + * @param tokenizer + * @return + * @throws RulesException + */ + static private IRObject compile(RuleSet ruleset, SimpleTokenizer tokenizer, String v, boolean executable, int depth) throws RulesException { + try{ + RArray result = new RArray(0,true,executable); + Token token; + while((token=tokenizer.nextToken())!=null){ + if(token.getType()== Token.Type.STRING) { + IRObject rs = RString.newRString(token.strValue); + result.add(rs); + }else if(token.getType()== Token.Type.LSQUARE) { + IRObject o = compile(ruleset,tokenizer, v, false, depth+1); + result.add(o); + }else if(token.getType()== Token.Type.RSQUARE) { + if(depth==0 || executable){ + throw new RulesException("Parsing Error", + "String Compile", + "\nError parsing <<"+v+">> \nThe token ']' was unexpected."); + + } + return result; + }else if(token.getType()== Token.Type.LCURLY) { + IRObject o = compile(ruleset,tokenizer,v,true, depth+1); + result.add(o); + }else if(token.getType()== Token.Type.RCURLY) { + if(depth==0 || !executable){ + throw new RulesException("Parsing Error", + "String Compile", + "\nError parsing <<"+v+">> \nThe token '}' was unexpected."); + + } + return result; + }else if(token.getType()== Token.Type.NAME) { + if(token.nameValue.isExecutable()){ // All executable names are checked for compile time lookup. + IRObject prim = lookup(ruleset,token.nameValue); + if(prim == null){ // If this name is not a primitive, then + result.add(token.nameValue); // then add the name as it is to the array. + }else{ + result.add(prim); // Otherwise, compile the reference to the operator. + } + }else{ + result.add(token.nameValue); + } + + }else if (token.getType() == Token.Type.DATE){ + result.add(token.datevalue); + + }else if (token.getType()== Token.Type.INT) { + RInteger i = RInteger.getRIntegerValue(token.longValue); + result.add(i); + }else if (token.getType()== Token.Type.REAL) { + RDouble d = RDouble.getRDoubleValue(token.doubleValue); + result.add(d); + } + } + if(depth!=0){ + throw new RulesException("Parsing Error", + "String Compile", + "\nError parsing << " + v + " >>\n missing a " + (executable ? "}" : "]")); + + } + return (IRObject) result; + } catch (RuntimeException e) { + throw new RulesException("Undefined","String Compile","Error compiling string: '"+v+"'\n"+e); + } + + } + /** + * Compiles this String and returns the object. + * @param executable + * @return + * @throws RulesException + */ + public IRObject compile(RuleSet ruleset, boolean executable) throws RulesException{ + return compile(ruleset, value,executable); + } + + @Override + public boolean isExecutable() { + return executable; + } + + public void execute(DTState state) throws RulesException { + if(isExecutable()){ + IRObject o = compile(state.getSession().getRuleSet(),value,true); + o.execute(state); + }else{ + state.datapush(this); + } + } + + public String stringValue() { + return value; + } + public String toString(){ + return "\""+value+"\""; + } + + + /** + * returns 0 if both are equal. -1 if this object is less than the argument. + * 1 if this object is greater than the argument + */ + public int compare(IRObject irObject) throws RulesException { + int f = this.value.compareTo(irObject.stringValue()); + if(f<0)return -1; + if(f>0)return 1; + return f; + } + + public boolean equals(IRObject o) throws RulesException { + return value.equals(o.stringValue()); + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/RTable.java b/DTRules/src/main/java/com/dtrules/interpreter/RTable.java new file mode 100644 index 0000000..b3cd468 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/RTable.java @@ -0,0 +1,237 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.interpreter; + +import java.util.ArrayList; +import java.util.HashMap; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.session.DTState; +import com.dtrules.session.EntityFactory; +import com.dtrules.session.RuleSet; + +public class RTable extends ARObject { + private final int resultType; + private final int id; + private RName tablename; + private RString description; + + private final HashMap table = new HashMap(); + + /** + * Get the description of this table + * @return the description + */ + public RString getDescription() { + return description; + } + + /** + * Set the description of this table + */ + public void setDescription(RString description){ + this.description = description; + } + + /** + * Return the Unique ID for this table. + * @return the id + */ + public int getId() { + return id; + } + + /** + * Return the type of result found in this table. + * @return the resultType + */ + public int getResultType() { + return resultType; + } + + /** + * Return the HashMap for primary dimension of this table + * @return the table + */ + public HashMap getTable() { + return table; + } + + /** + * @return the tablename + */ + public RName getTablename() { + return tablename; + } + + public boolean containsKey (RName key){ + return table.containsKey(key); + } + + public boolean containsValue (IRObject value){ + return table.containsValue(value); + } + + private RTable(EntityFactory ef, + RName tablename, + String description, + int resultType) throws RulesException { + this.tablename = tablename; + this.resultType = resultType; + this.id = ef.getUniqueID(); + this.description = RString.newRString(description); + } + /** + * Factory method for creating an RTable + * @param state + * @param tablename + * @param description + * @param resultType + * @return + */ + static public RTable newRTable(EntityFactory ef, RName tablename, String description, int resultType) throws RulesException{ + return new RTable(ef,tablename,description,resultType); + } + /** + * This routine assumes that the string defines an Array of the + * form: + * { + * { key1 value1 } + * { key2 value2 } + * ... + * { keyn valuen } + * } + * This routine compiles the given string, then calls the + * set routine that takes an array of key value pairs and sets + * them into the RTable + * + * @param values + */ + public void setValues(RuleSet rs, String values)throws RulesException{ + RArray array = RString.compile(rs, values, false).rArrayValue(); + setValues(array); + } + /** + * This routine assumes that an Array of the + * form: + * { + * { key1 value1 } + * { key2 value2 } + * ... + * { keyn valuen } + * } + * This routine takes an array of key value pairs and sets + * them into the RTable + * + * @param values + */ + public void setValues(RArray values) throws RulesException{ + for(IRObject irpair : values){ + RArray pair = irpair.rArrayValue(); + if(pair.size()!=2){ + throw new RulesException( + "Invalid_Table_Value", + "RTable.setValues", + "setValues expected an array of arrays giving pairs of values to assert into the Table"); + } + RName key = pair.get(0).rNameValue(); + IRObject value = pair.get(1); + setValue(key, value); + } + } + + /** + * Set a value with the given set of keys into the given table. + * @param keys + * @param value + * @throws RulesException + */ + @SuppressWarnings("unchecked") + public void setValue(DTState state, RName[]keys, IRObject value) throws RulesException{ + IRObject v = this; + for(int i=0;i keys = new ArrayList(table.keySet()); + int id = state.getSession().getUniqueID(); + return new RArray(id, true, keys,false); + } + + public String stringValue() { + return tablename.stringValue(); + } + + public int type() { + return iTable; + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.ARObject#rTableValue() + */ + @Override + public RTable rTableValue() throws RulesException { + return this; + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.ARObject#tableValue() + */ + @SuppressWarnings({"unchecked"}) + public HashMap tableValue() throws RulesException { + return table; + } + + +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/RTime.java b/DTRules/src/main/java/com/dtrules/interpreter/RTime.java new file mode 100644 index 0000000..5952863 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/RTime.java @@ -0,0 +1,147 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.session.DTState; + +public class RTime extends ARObject { + final Date time; + public int type() { + return iTime; + } + + @Override + public double doubleValue() throws RulesException { + return time.getTime(); + } + + @Override + public long longValue() throws RulesException { + return time.getTime(); + } + + @Override + public RDouble rDoubleValue() throws RulesException { + return RDouble.getRDoubleValue(time.getTime()); + } + + + @Override + public RInteger rIntegerValue() throws RulesException { + return RInteger.getRIntegerValue(time.getTime()); + } + + @Override + public RString rStringValue() { + return RString.newRString(stringValue()); + } + + + + private RTime(Date t){ + time = t; + } + + public static SimpleDateFormat [] formats ={ + new SimpleDateFormat("MM/dd/yyyy"), + new SimpleDateFormat("MM-dd-yyyy"), + }; + + public static Date getDate(String s){ + for(int i=0;i arrayValue() throws RulesException { + ArrayList a = new ArrayList(); + if(tag.getTags().size()>0){ + for(XMLTag t : tag.getTags()){ + a.add(new RXmlValue(state,t)); + } + } + return a; + } + + @Override + public boolean booleanValue() throws RulesException { + return RBoolean.booleanValue(tag.getBody().toString()); + } + + @Override + public double doubleValue() throws RulesException { + return RDouble.getDoubleValue(tag.getBody().toString()); + } + + @Override + public boolean equals(IRObject o) throws RulesException { + return rStringValue().equals(o); + } + + @Override + public int intValue() throws RulesException { + return (int)RInteger.getIntegerValue(tag.getBody().toString()); + } + + + @Override + public long longValue() throws RulesException { + return RInteger.getIntegerValue(tag.getBody().toString()); + } + + @Override + public RBoolean rBooleanValue() throws RulesException { + return RBoolean.getRBoolean(booleanValue()); + } + + @Override + public RDouble rDoubleValue() throws RulesException { + return RDouble.getRDoubleValue(doubleValue()); + } + + @Override + public RInteger rIntegerValue() throws RulesException { + return RInteger.getRIntegerValue(longValue()); + } + + @Override + public RName rNameValue() throws RulesException { + return RName.getRName(stringValue(),false); + } + + public RString rStringValue() { + return RString.newRString(stringValue()); + } + + public RTime rTimeValue() throws RulesException { + return RTime.getRTime(timeValue()); + } + + public Date timeValue() throws RulesException { + return RTime.getDate(tag.getBody().toString()); + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.ARObject#rXmlValue() + */ + @Override + public RXmlValue rXmlValue() throws RulesException { + return this; + } + + /* (non-Javadoc) + * @see com.dtrules.interpreter.ARObject#xmlTagValue() + */ + @Override + public XMLTag xmlTagValue() throws RulesException { + return tag; + } + + + +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/SimpleTokenizer.java b/DTRules/src/main/java/com/dtrules/interpreter/SimpleTokenizer.java new file mode 100644 index 0000000..164b31a --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/SimpleTokenizer.java @@ -0,0 +1,136 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.interpreter; + +import java.util.Date; + +import com.dtrules.infrastructure.RulesException; + +public class SimpleTokenizer { + private StringBuffer buff; + private int index; + + static RTime t; + static { + try{ + t = RTime.getRDate("12/31/2000"); + }catch(RulesException e){} + } + + public SimpleTokenizer (String input){ + buff = new StringBuffer(input); + index = 0; + } + /** + * Tosses whitespace (anything less than 32). Returns true if any + * whitespace was found, and false otherwise. The end of string counts + * as whitespace. + * @return + */ + private boolean tossWhite(){ + if(index>=buff.length())return true; + char c = buff.charAt(index); + if(c>' ')return false; + while(hasChar() && buff.charAt(index)<=32)index++; + return true; + } + /** + * Returns true if any characters remain in the buffer. + * @return + */ + private boolean hasChar(){ + return index < buff.length(); + } + /** + * Returns the next character in the buffer. Returns a space on end + * of string. + * @return + */ + char getChar(){ + if(index>=buff.length())return ' '; + char c = buff.charAt(index++); + return c; + } + + /** + * Parses out a token at a time, and returns null on the end of input. + * @return + */ + public Token nextToken() throws RulesException { + tossWhite(); + if(!hasChar())return null; + int start = index; + char c = getChar(); + switch(c){ + case '"': case '\'': return parseString(c); + case '[': + case ']': + case '{': + case '}': + case '(': + case ')': return new Token(c); + } + while(getChar()>32); + return buildToken(buff.substring(start, index)); + } + /** + * We assume the first quote has been + * parsed already. We parse till we find the delim char. + * We then build + * @param delim + * @return + */ + Token parseString(char delim){ + char c = ' '; + int start = index; + while(hasChar()){ + if(getChar()==delim){ + if(start>index-1){ + return new Token("",Token.Type.STRING); + } + return new Token(buff.substring(start,index-1),Token.Type.STRING); + } + } + throw new RuntimeException("String is missing the closing quote: ("+c+")"); + } + /** + * We attempt to convert v to a long. + * Then we attempt to convert v to a float. + * Then we try parsing it as a date. + * Then we build a name. + * @param v + * @return + */ + Token buildToken(String v){ + try { + Long longValue = Long.parseLong(v.replaceAll(",", "")); + return new Token(longValue); + } catch (NumberFormatException e) {} + try { + Double doubleValue = Double.parseDouble(v.replaceAll(",","")); + return new Token(doubleValue); + } catch (NumberFormatException e) {} + Date t = RTime.getDate(v); + if(t!=null){ + return new Token(RTime.getRTime(t)); + } + + return new Token(RName.getRName(v)); + } + +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/Token.java b/DTRules/src/main/java/com/dtrules/interpreter/Token.java new file mode 100644 index 0000000..520e846 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/Token.java @@ -0,0 +1,99 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.interpreter; + +class Token { + + public enum Type { + INT, + REAL, + DATE, + LPAREN, + RPAREN, + LCURLY, + RCURLY, + LSQUARE, + RSQUARE, + NAME, + STRING, + }; + + Type type; + String strValue; + Long longValue; + Double doubleValue; + RTime datevalue; + RName nameValue; + + public Type getType(){ + return type; + } + + Token(char c) { + strValue = String.valueOf(c); + switch(c){ + case '[': type = Type.LSQUARE; break; + case ']': type = Type.RSQUARE; break; + case '{': type = Type.LCURLY; break; + case '}': type = Type.RCURLY; break; + case '(': type = Type.LPAREN; break; + case ')': type = Type.RPAREN; break; + default : + nameValue = RName.getRName(String.valueOf(c)); + type = Type.NAME; + } + } + + Object getValue(){ + if(type == Type.INT)return longValue; + if(type == Type.REAL)return doubleValue; + if(type == Type.STRING)return strValue; + if(type == Type.LSQUARE)return "["; + if(type == Type.RSQUARE)return "]"; + if(type == Type.LCURLY)return "{"; + if(type == Type.RCURLY)return "}"; + if(type == Type.LPAREN)return "("; + if(type == Type.RPAREN)return ")"; + if(type == Type.NAME)return "/"+nameValue.stringValue(); + return "?"; + } + + Token(RTime t){ + datevalue = t; + type = Type.DATE; + } + + Token(String s,Type t){ + strValue = s; + type = t; + } + Token(long v){ + longValue = v; + type = Type.INT; + } + + Token(Double v){ + doubleValue = v; + type = Type.REAL; + } + + Token(RName n){ + nameValue = n; + type = Type.NAME; + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/operators/RArrayOps.java b/DTRules/src/main/java/com/dtrules/interpreter/operators/RArrayOps.java new file mode 100644 index 0000000..c0d88dd --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/operators/RArrayOps.java @@ -0,0 +1,480 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter.operators; + +import java.util.ArrayList; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RBoolean; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RMark; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RString; +import com.dtrules.session.DTState; + +@SuppressWarnings("unchecked") +public class RArrayOps { + static { + new Addto(); + new Addat(); + new Remove(); + new Removeat(); + new Getat(); + new Newarray(); + new Length(); + new Memberof(); + new Mark(); + new Arraytomark(); + new Copyelements(); + new Sortarray(); + new Sortentities(); + new Add_no_dups(); + new Clear(); + new Merge(); + new Randomize(); + new AddArray(); + new Tokenize(); + } + /** + * tokenize ( String1 String2 --> array ) + * String1 is a string to tokenize + * String2 is a regular expression defining these tokens + * array is an array of strings that results when String1 is tokenized. + * @author ps24876 + * + */ + static class Tokenize extends ROperator { + Tokenize(){super("tokenize");} + + public void execute(DTState state) throws RulesException { + + String pattern = state.datapop().stringValue(); + IRObject obj1 = state.datapop(); + String v = ""; + if(obj1.type() != IRObject.iNull){ + v = obj1.stringValue().trim(); + } + String [] results = v.split(pattern); + + RArray r = new RArray(state.getSession().getUniqueID(),false,false); + for(String t : results){ + r.add(RString.newRString(t)); + if(state.testState(DTState.TRACE)){ + state.traceInfo("addto", "arrayID='"+r.getID()+"'","'"+t+"'"); + } + } + state.datapush(r); + } + } + + + /** + * addto( Array Value --> ) + * Addto Operator, adds an element to an array + * @author Paul Snow + * + */ + static class Addto extends ROperator { + Addto(){super("addto");} + + public void execute(DTState state) throws RulesException { + IRObject value = state.datapop(); + RArray rarray = state.datapop().rArrayValue(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("addto", "arrayID='"+rarray.getID()+"'",value.postFix()); + } + rarray.add(value); + } + } + + /** + * addat( Array int Value --> ) + * Addat Operator, adds an element to an array at the given location + */ + static class Addat extends ROperator { + Addat() {super("addat");} + + public void execute(DTState state) throws RulesException { + IRObject value = state.datapop(); + int position = state.datapop().intValue(); + RArray rarray = state.datapop().rArrayValue(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("addat", "arrayID='"+rarray.getID()+"' index="+position+"'",value.postFix()); + } + rarray.add(position, value); + + } + } + + /** + * remove( Array Value --> boolean ) + * Remove Operator, removes all elements from an array that match the value. Returns a + * true if at least one element was removed, and a false otherwise. + */ + static class Remove extends ROperator { + Remove() {super("remove");} + + public void execute(DTState state) throws RulesException { + IRObject value = state.datapop(); + RArray rarray = (RArray)state.datapop(); + ArrayList array = rarray.arrayValue(); + boolean removed = false; + if(value!=null){ + for(int i=0; i boolean ) + * Removeat Operator, removes an element from an + * array at the given location. Returns true upon + * success + */ + static class Removeat extends ROperator { + Removeat() {super("removeat");} + + public void execute(DTState state) throws RulesException { + int position = state.datapop().intValue(); + RArray rarray = (RArray)state.datapop(); + if(position >= rarray.size()){ + state.datapush(RBoolean.getRBoolean(false)); + } + + ArrayList array = rarray.arrayValue(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("removed", "arrayID='"+rarray.getID()+"' position='"+position+"'"); + } + + array.remove(position); + state.datapush(RBoolean.getRBoolean(true)); + } + } + + /** + * getat( Array int --> value) + * Getat Operator, gets an element from an array at the given location + */ + static class Getat extends ROperator { + Getat() {super("getat");} + + public void execute(DTState state) throws RulesException { + int position = state.datapop().intValue(); + ArrayList array = state.datapop().arrayValue(); + state.datapush((IRObject)array.get(position)); + } + } + + /** + * newarray( --> Array) + * Newarray Operator, returns a new empty array + */ + static class Newarray extends ROperator { + Newarray() {super("newarray");} + + public void execute(DTState state) throws RulesException { + IRObject irobject = new RArray(state.getSession().getUniqueID(),true, false); + state.datapush(irobject); + } + } + + /** + * length( Array --> int) + * Length Operator, returns the size of the array + */ + static class Length extends ROperator { + Length() {super("length");} + + public void execute(DTState state) throws RulesException { + ArrayList array = state.datapop().arrayValue(); + state.datapush(RInteger.getRIntegerValue(array.size())); + } + } + + /** + * memberof( Array Value --> boolean) + * Memberof Operator, returns true if the element found in the array + */ + static class Memberof extends ROperator { + Memberof() {super("memberof");} + + public void execute(DTState state) throws RulesException { + IRObject value = state.datapop(); + ArrayList array = state.datapop().arrayValue(); + boolean found = false; + if(value!=null){ + for(int i=0; i newarray) + * Copyelements Operator, returns the copy of the array + */ + static class Copyelements extends ROperator { + Copyelements() {super("copyelements");} + + public void execute(DTState state) throws RulesException { + RArray rarray = state.datapop().rArrayValue(); + RArray newRArray = rarray.clone(state.getSession()).rArrayValue(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("copyelements", "id='"+rarray.getID()+"' newarrayid='"+newRArray.getID()+"'"); + for(IRObject v : newRArray){ + state.traceInfo("addto", "arrayID='"+rarray.getID()+"'",v.postFix()); + } + } + + state.datapush(newRArray); + + } + } + + /** + * sortarray( Array boolean --> ) + * Sortarray Operator, sorts the array elements (asc is boolean is true) + */ + static class Sortarray extends ROperator { + Sortarray() {super("sortarray");} + + public void execute(DTState state) throws RulesException { + boolean asc = state.datapop().booleanValue(); + int direction = asc ? 1 : -1; + + RArray rarray = state.datapop().rArrayValue(); + ArrayList array = rarray.arrayValue(); + + if(state.testState(DTState.TRACE)){ + state.traceInfo("sort", "length='"+array.size()+"' arrayID='"+rarray.getID()+"'",asc ? "true" : "false"); + } + + IRObject temp = null; + int size = array.size(); + for(int i=0; i ) + * Randomizes the order in the given array. + */ + static class Randomize extends ROperator { + Randomize() { + super("randomize"); + } + + public void execute(DTState state) throws RulesException { + ArrayList array = state.datapop().arrayValue(); + IRObject temp = null; + int size = array.size(); + for(int i=0; i<10; i++){ + for(int j=0; j ) + * Sortentities Operator, + */ + static class Sortentities extends ROperator { + Sortentities() {super("sortentities");} + + public void execute(DTState state) throws RulesException { + boolean asc = state.datapop().booleanValue(); + RName rname = state.datapop().rNameValue(); + RArray rarray = state.datapop().rArrayValue(); + ArrayList array = rarray.arrayValue(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("sortentities", + "length='"+array.size()+ + "' by='"+rname.stringValue()+ + "' arrayID='"+rarray.getID()+"'", + asc ? "true" : "false"); + } + REntity temp = null; + int size = array.size(); + int greaterthan = asc ? 1 : -1; + for(int i=0; i ) + * Add_no_dups Operator, adds an element to an array if it is not present + */ + static class Add_no_dups extends ROperator { + Add_no_dups(){super("add_no_dups");} + + public void execute(DTState state) throws RulesException { + + IRObject value = state.datapop(); + RArray rArray = (RArray) state.datapop(); + ArrayList array = rArray.arrayValue(); + for(int i=0; i ) + * Clear Operator, removes all elements from the array + */ + static class Clear extends ROperator { + Clear(){super("clear");} + + public void execute(DTState state) throws RulesException { + IRObject rarray = state.datapop(); + ArrayList array = rarray.arrayValue(); + array.clear(); + if (state.testState(DTState.TRACE)){ + state.traceInfo("clear", "array='"+rarray.stringValue()+"'"); + } + } + } + + /** + * merge( Array Array--> Array) + * Merge Operator, merges two array to one (Array1 elements followed by Array2 elements) + */ + static class Merge extends ROperator { + Merge(){super("merge");} + + public void execute(DTState state) throws RulesException { + ArrayList array2 = state.datapop().arrayValue(); + ArrayList array1 = state.datapop().arrayValue(); + ArrayList newarray = new ArrayList(); + newarray.addAll(array1); + newarray.addAll(array2); + state.datapush(new RArray(state.getSession().getUniqueID(),false,newarray, false)); + } + } + + /** + * Mark ( -- mark ) pushes a mark object onto the data stack. + * + */ + static class Mark extends ROperator { + Mark(){super("mark");} + + public void execute(DTState state) throws RulesException { + state.datapush(RMark.getMark()); + } + } + + /** + * arraytomark ( mark obj obj ... -- array ) creates an array out + * of the elements on the data stack down to the first mark. + * + */ + static class Arraytomark extends ROperator { + Arraytomark(){super("arraytomark");} + + public void execute(DTState state) throws RulesException { + int im = state.ddepth()-1; // Index of top of stack + while(im>=0 && state.getds(im).type()!=iMark)im--; // Index of mark + RArray newarray = new RArray(state.getSession().getUniqueID(),true,false); // Create a new array + int newdepth = im++; // skip the mark (remember its index) + while(im");} + + public void execute(DTState state) throws RulesException { + IRObject o2 = state.datapop(); + IRObject o1 = state.datapop(); + long number2 = o2.longValue(); + long number1 = o1.longValue(); + state.datapush(RBoolean.getRBoolean(number1 > number2)); + } + } + + /** + * Lessthan( Number Number -- Boolean ) + * Lessthan Operator, returns the boolean value for condition with the given parameters + */ + static class Lessthan extends ROperator { + Lessthan(){super("<");} + + public void execute(DTState state) throws RulesException { + long number2 = state.datapop().longValue(); + long number1 = state.datapop().longValue(); + state.datapush(RBoolean.getRBoolean(number1 < number2)); + } + } + + /** + * Greaterthanequal( Number Number -- Boolean ) + * Greaterthanequal Operator, returns the boolean value for condition with the given parameters + */ + static class Greaterthanequal extends ROperator { + Greaterthanequal(){super(">=");} + + public void execute(DTState state) throws RulesException { + long number2 = state.datapop().longValue(); + long number1 = state.datapop().longValue(); + state.datapush(RBoolean.getRBoolean(number1 >= number2)); + } + } + + /** + * Lessthanequal( Number Number -- Boolean ) + * Lessthanequal Operator, returns the boolean value for condition with the given parameters + */ + static class Lessthanequal extends ROperator { + Lessthanequal(){super("<=");} + + public void execute(DTState state) throws RulesException { + long number2 = state.datapop().longValue(); + long number1 = state.datapop().longValue(); + state.datapush(RBoolean.getRBoolean(number1 <= number2)); + } + } + + /** + * Equal( Number Number -- Boolean ) + * Lessthanequal Operator, returns the boolean value for condition with the given parameters + */ + static class Equal extends ROperator { + Equal(){super("==");} + + public void execute(DTState state) throws RulesException { + state.datapush(RBoolean.getRBoolean(state.datapop().longValue() == state.datapop().longValue())); + } + } + + /** + * FGreaterthan( Number Number -- Boolean ) + * FGreaterthan Operator, returns the boolean value for condition with the given parameters + */ + static class FGreaterthan extends ROperator { + FGreaterthan(){super("f>");} + + public void execute(DTState state) throws RulesException { + double number2 = state.datapop().doubleValue(); + double number1 = state.datapop().doubleValue(); + state.datapush(RBoolean.getRBoolean(number1 > number2)); + } + } + + /** + * FLessthan( Number Number -- Boolean ) + * FLessthan Operator, returns the boolean value for condition with the given parameters + */ + static class FLessthan extends ROperator { + FLessthan(){super("f<");} + + public void execute(DTState state) throws RulesException { + double number2 = state.datapop().doubleValue(); + double number1 = state.datapop().doubleValue(); + state.datapush(RBoolean.getRBoolean(number1 < number2)); + } + } + + /** + * FGreaterthanequal( Number Number -- Boolean ) + * FGreaterthanequal Operator, returns the boolean value for condition with the given parameters + */ + static class FGreaterthanequal extends ROperator { + FGreaterthanequal(){super("f>=");} + + public void execute(DTState state) throws RulesException { + double number2 = state.datapop().doubleValue(); + double number1 = state.datapop().doubleValue(); + state.datapush(RBoolean.getRBoolean(number1 >= number2)); + } + } + + /** + * FLessthanequal( Number Number -- Boolean ) + * FLessthanequal Operator, returns the boolean value for condition with the given parameters + */ + static class FLessthanequal extends ROperator { + FLessthanequal(){super("f<=");} + + public void execute(DTState state) throws RulesException { + double number2 = state.datapop().doubleValue(); + double number1 = state.datapop().doubleValue(); + state.datapush(RBoolean.getRBoolean(number1 <= number2)); + } + } + + /** + * FEqual( Number Number -- Boolean ) + * FEqual Operator, returns the boolean value for condition with the given parameters + */ + static class FEqual extends ROperator { + FEqual(){super("f==");} + + public void execute(DTState state) throws RulesException { + state.datapush(RBoolean.getRBoolean(state.datapop().doubleValue() == state.datapop().doubleValue())); + } + } + + /** + * Isnull(object -- Boolean ) + * Isnull Operator, returns true if the object is null + */ + static class Isnull extends ROperator { + Isnull(){super("isnull");} + + public void execute(DTState state) throws RulesException + { + state.datapush(RBoolean.getRBoolean(state.datapop().type()==IRObject.iNull)); + } + } + + /** + * Booleanequal(boolean1 boolean2 -- Boolean ) + * Booleanequal Operator, returns true if both are equal + */ + static class Booleanequal extends ROperator { + Booleanequal(){super("b="); alias("beq");} + + public void execute(DTState state) throws RulesException { + state.datapush(RBoolean.getRBoolean(state.datapop().booleanValue()==state.datapop().booleanValue())); + } + } + + /** + * Booleannotequal(boolean1 boolean2 -- Boolean ) + * Booleannotequal Operator, returns true if both are not equal + */ + static class Booleannotequal extends ROperator { + Booleannotequal(){super("b!=");} + + public void execute(DTState state) throws RulesException { + state.datapush(RBoolean.getRBoolean(state.datapop().booleanValue()!=state.datapop().booleanValue())); + } + } + + /** + * SGreaterthan( String String -- Boolean ) + * SGreaterthan Operator, returns the boolean value for condition with the given parameters + */ + static class SGreaterthan extends ROperator { + SGreaterthan(){super("s>");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RBoolean.getRBoolean(value1.compareTo(value2)>0)); + } + } + + /** + * SLessthan( String String -- Boolean ) + * SLessthan Operator, returns the boolean value for condition with the given parameters + */ + static class SLessthan extends ROperator { + SLessthan(){super("s<");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RBoolean.getRBoolean(value1.compareTo(value2)< 0)); + } + } + + /** + * SGreaterthanequal( String String -- Boolean ) + * SGreaterthanequal Operator, returns the boolean value for condition with the given parameters + */ + static class SGreaterthanequal extends ROperator { + SGreaterthanequal(){super("s>=");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RBoolean.getRBoolean(value1.compareTo(value2)>=0)); + } + } + + /** + * SLessthanequal( String String -- Boolean ) + * SLessthanequal Operator, returns the boolean value for condition with the given parameters + */ + static class SLessthanequal extends ROperator { + SLessthanequal(){super("s<=");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RBoolean.getRBoolean(value1.compareTo(value2)<=0)); + } + } + + /** + * SEqual( String String -- Boolean ) + * SEqual Operator, returns the boolean value for condition with the given parameters + */ + static class SEqual extends ROperator { + SEqual(){super("s=="); alias("streq");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RBoolean.getRBoolean(value1.equals(value2))); + } + } + + /** + * SEqualIgnoreCase( String String -- Boolean ) + * Same as SEqual Operator, only ignores the case. + * Returns the boolean value for condition with the given parameters + */ + static class SEqualIgnoreCase extends ROperator { + SEqualIgnoreCase(){super("sic=="); alias("streqignorecase");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RBoolean.getRBoolean(value1.equalsIgnoreCase(value2))); + } + } + + + + /** + * StrConcat( String String -- String ) + * StrConcat Operator, add the given two strings and returns a string value + */ + static class SConcat extends ROperator { + SConcat(){super("s+"); alias("strconcat");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RString.newRString(value1+value2)); + } + } + + /** + * Strremove( String1 String2 -- String3 ) + * Strremove Operator, removes string2 from string1 and returns string3 + */ + static class Strremove extends ROperator { + Strremove(){super("strremove");} + + public void execute(DTState state) throws RulesException { + String value2 = state.datapop().stringValue(); + String value1 = state.datapop().stringValue(); + state.datapush(RString.newRString(value1.replaceAll(value2, ""))); + } + } + + /** + * Req( object1 object2 -- Boolean ) + * Req Operator, compares the two objects using equals and returns the boolean value + */ + static class Req extends ROperator { + Req(){super("req");} + + public void execute(DTState state) throws RulesException { + IRObject value2 = state.datapop(); + IRObject value1 = state.datapop(); + state.datapush(RBoolean.getRBoolean(value1.equals(value2))); + } + } +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/interpreter/operators/RControl.java b/DTRules/src/main/java/com/dtrules/interpreter/operators/RControl.java new file mode 100644 index 0000000..2affe69 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/operators/RControl.java @@ -0,0 +1,432 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter.operators; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; +import com.dtrules.session.DTState; +/** + * Defines math operators. + * @author paul snow + * + */ +@SuppressWarnings("unchecked") +public class RControl { + static { + new If(); new Ifelse(); new While(); + new Forallr(); new Forall(); new For(); + new Forr(); new Entityforall(); new Forfirst(); + new Doloop(); new ForFirstElse(); new ExecuteTable(); + new Execute(); new Deallocate(); new Allocate(); + new Localfetch(); new Localstore(); + } + + /** + * ( body boolean -- ) executes the body if the boolean is true. + * @author paul snow + * + */ + static class If extends ROperator { + If(){super("if");} + + public void execute(DTState state) throws RulesException { + boolean test = state.datapop().booleanValue(); + IRObject body = state.datapop(); + if(test)body.execute(state); + } + } + /** + * ( truebody falsebody test -- ) Executes truebody if the boolean test is true, otherwise + * executes falsebody. + * @author paul snow + * + */ + static class Ifelse extends ROperator { + Ifelse(){super("ifelse");} + + public void execute(DTState state) throws RulesException { + boolean test = state.datapop().booleanValue(); + IRObject falsebody = state.datapop(); + IRObject truebody = state.datapop(); + if(test){ + truebody.execute(state); + }else{ + falsebody.execute(state); + } + } + } + + /** + * This is an internal operator which doesn't have any use outside of the + * Rules Engine itself. It is used to execute the conditions and actions + * for a table within the context as defined in the table. + * + * ( DecisionTableName -- ) Takes the DecisionTable name and looks it up + * in the decisiontable entity. It then executes the table within that + * decision table. Because of this extra lookup, this path shouldn't be + * used unless there actually is a context to be executed. + * + * @author paul snow + * + */ + static class ExecuteTable extends ROperator { + ExecuteTable(){super("executetable");} + + public void execute(DTState state) throws RulesException { + RName dtname = state.datapop().rNameValue(); + state.getSession().getEntityFactory().getDecisionTable(dtname).executeTable(state); + } + } + /** + * ( RObject -- ? ) Executes the object on the top of the data stack. + * The behavior of this operator is defined by the object executed. Usually + * the data stack will be left clean. + * @author paul snow + * + */ + static class Execute extends ROperator { + Execute(){super("execute"); } + + public void execute(DTState state) throws RulesException { + state.datapop().getExecutable().execute(state); + } + } + + /** + * ( body test -- ) executes test. If test returns true, executes body. + * Repeats until the test returns false. + * + * @author paul snow + * + */ + static class While extends ROperator { + While(){super("while");} + + public void execute(DTState state) throws RulesException { + IRObject test = state.datapop(); // Get the test + IRObject body = state.datapop(); // Get the body + + test.execute(state); // evaluate the test + while(state.datapop().booleanValue()){ // If true, keep looping + body.execute(state); // execute the body. + test.execute(state); // check the test again. + } + + + } + } + /** + * ( body array -- ) Execute the body for each entity in the array. + * executes backwards through the array, and the entity can be removed + * from the array by the body. + * + * @author paul snow + * + */ + static class Forallr extends ROperator { + Forallr(){super("forallr");} + + public void execute(DTState state) throws RulesException { + + ArrayList array = state.datapop().arrayValue(); // Get the array + int length = array.size(); // get Array length. + IRObject body = state.datapop(); // Get the body + for(int i=length - 1;i>=0;i--){ // For each element in array, + IRObject o = (IRObject) array.get(i); + int t = o.type(); + if(t== iNull)continue; + if(t!=iEntity){ + throw new RulesException("Type Check", "Forallr", "Encountered a non-Entity entry in array: "+o); + } + state.entitypush((IREntity) o); + body.execute(state); + state.entitypop(); + } + } + } + + /** + * ( body array -- ) executes the body for each entity in the array. Uses an + * Iterator and executes forward in the array. The entity cannot be removed from + * the array by the body. + * + * @author paul snow + * + */ + static class Forall extends ROperator { + Forall(){super("forall");} + + public void execute(DTState state) throws RulesException { + + RArray array = state.datapop().rArrayValue(); + IRObject body = state.datapop(); // Get the body + + for(IRObject o : array){ + int t = o.type(); + if(t== iNull)continue; + if(t!=iEntity){ + throw new RulesException("Type Check", "Forallr", "Encountered a non-Entity entry in array: "+o); + } + state.entitypush((IREntity) o); + body.execute(state); + state.entitypop(); + } + } + } + + /** + * ( body array -- ) Pushes each element on to the data stack, then executes the body. + * @author paul snow + * + */ + static class For extends ROperator { + For(){super("for");} + + public void execute(DTState state) throws RulesException { + RArray list = state.datapop().rArrayValue(); + IRObject body = state.datapop(); // Get the body + for(IRObject o : list){ + state.datapush(o); + body.execute(state); + } + } + } + /** + * ( body array -- ) pushes each element on to the data stack, then executes the body. + * Because the array is evaluated in reverse order, the element can be removed from the + * array if you care to. + * + * @author paul snow + * + */ + static class Forr extends ROperator { + Forr(){super("forr");} + + public void execute(DTState state) throws RulesException { + ArrayList array = state.datapop().arrayValue(); // Get the array + int length = array.size(); // get Array length. + IRObject body = state.datapop(); // Get the body + for(int i=length-1;i>=0;i++){ // For each element in array, + IRObject o = (IRObject) array.get(i); + state.datapush((IRObject) o); + body.execute(state); + } + } + } + /** + * ( body entity -- ) Executes the body for each key value pair in the Entity. + * + * @author paul snow + * + */ + static class Entityforall extends ROperator { + Entityforall(){super("entityforall");} + + public void execute(DTState state) throws RulesException { + IREntity entity = state.datapop().rEntityValue(); // Get the entity + IRObject body = state.datapop(); // Get the body + Iterator keys = entity.getAttributeIterator(); // Get the Attribute Iterator + while(keys.hasNext()){ // For each attribute + RName n = (RName) keys.next(); + IRObject v = entity.get(n); + if(v!=null){ + state.datapush(n); + state.datapush(v); + body.execute(state); + } + } + } + } + /** + * ( body test array -- ) + * Each entity within the array is placed on the entity stack. The test is evaluated, which should + * return the boolean. If true, the body is executed, and the loop stops. + * @author paul snow + * Jan 10, 2007 + * + */ + static class Forfirst extends ROperator { + Forfirst(){super("forfirst");} + + public void execute(DTState state) throws RulesException { + RArray array = state.datapop().rArrayValue(); + IRObject test = state.datapop(); + IRObject body = state.datapop(); + Iterator ie = array.getIterator(); + while(ie.hasNext()){ + state.entitypush(ie.next()); + test.execute(state); + if(state.datapop().booleanValue()){ + body.execute(state); + state.entitypop(); + return; + } + state.entitypop(); + } + } + } + + /** + * ( body1 body2 test array -- ) + * Each entity within the array is placed on the entity stack. The test is + * evaluated, which should return the boolean. If true, the body1 is executed, + * and the loop stops. If no match is found, body2 is executed. Kinda a + * default operation. + * @author paul snow + * Jan 10, 2007 + * + */ + static class ForFirstElse extends ROperator { + ForFirstElse(){super("forfirstelse");} + + public void execute(DTState state) throws RulesException { + RArray array = state.datapop().rArrayValue(); + IRObject test = state.datapop(); + IRObject body2 = state.datapop(); + IRObject body1 = state.datapop(); + for(IRObject obj : array) { + IREntity e = obj.rEntityValue(); + state.entitypush(e); + test.execute(state); + if(state.datapop().booleanValue()){ + body1.execute(state); + state.entitypop(); + return; + } + state.entitypop(); + } + body2.execute(state); + } + } + + /** + * ( body start increment limit -- ) Starts the index with the value "start". If the + * increment is positive and start is below the limit, the index + * is pushed and body is executed, then the index is incremented + * by increment. If the increment is negative and stat is above + * the limit, then the index is pushed and the body is executed, + * then the index is decremented by the increment. This continues + * until the limit is reached. + * + * @author paul snow + * Jan 10, 2007 + * + */ + static class Doloop extends ROperator { + Doloop(){super("doloop");} + + public void execute(DTState state) throws RulesException { + int limit = state.datapop().intValue(); + int increment = state.datapop().intValue(); + int start = state.datapop().intValue(); + IRObject body = state.datapop(); + if(increment>0){ + for(int i = start;ilimit;i+=increment){ + state.cpush(RInteger.getRIntegerValue(i)); + body.execute(state); + state.cpop(); + } + } + } + } + /** + * ( value -- ) + * Allocates storage for a local variable. The value is the initial + * value for that variable. In all reality, this is just a push of + * a value to the control stack. + * @author paul snow + * + */ + static class Allocate extends ROperator { + Allocate(){super("allocate"); alias("cpush");} + + public void execute(DTState state) throws RulesException { + IRObject v = state.datapop(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("allocate", "value='"+v.stringValue()+"'"); + } + state.cpush(v); + } + } + + /** + * ( -- value ) + * Deallocates storage for a local variable. In all reality, this is + * just a pop of a value from the control stack. + * + * @author paul snow + * + */ + static class Deallocate extends ROperator { + Deallocate(){super("deallocate"); alias("cpop");} + public void execute(DTState state) throws RulesException { + state.datapush(state.cpop()); + } + } + /** + * ( index -- IRObject ) fetches the value from the local variable + * specified by the given index. This is an offset from the currentframe. + * @author paul snow + * + */ + static class Localfetch extends ROperator { + Localfetch(){super("local@");} + + public void execute(DTState state) throws RulesException { + int index = state.datapop().intValue(); + IRObject value = state.getFrameValue(index); + if(state.testState(DTState.TRACE)){ + state.traceInfo("local_fetch", "index='"+index+"' value='"+value.stringValue()+"'"); + } + state.datapush(value); + } + } + /** + * (value index -- ) stores the value into the local variable specified + * by the given index. The index is an offset from the currentframe. + * @author paul snow + * + */ + static class Localstore extends ROperator { + Localstore(){super("local!");} + + public void execute(DTState state) throws RulesException { + int index = state.datapop().intValue(); + IRObject value = state.datapop(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("local_store", "index='"+index+"' value='"+value.stringValue()+"'"); + } + state.setFrameValue(index, value); + } + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/operators/RDateTimeOps.java b/DTRules/src/main/java/com/dtrules/interpreter/operators/RDateTimeOps.java new file mode 100644 index 0000000..fa0f5d0 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/operators/RDateTimeOps.java @@ -0,0 +1,457 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter.operators; + +import java.sql.Timestamp; +import java.util.Date; +import java.util.Calendar; +import java.util.GregorianCalendar; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.RBoolean; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RString; +import com.dtrules.interpreter.RTime; +import com.dtrules.session.DTState; + +/** + * Boolean Operators + * @author anand b + */ +public class RDateTimeOps { + + static { + new Newdate(); + new SetCalendar(); + new Yearof(); + new Getdaysinyear(); + new Getdaysinmonth(); + new Getdayofmonth(); + new Datelt(); + new Dategt(); + new Dateeq(); + new Gettimestamp(); + new Days(); + new DatePlus(); + new DateMinus(); + new FirstOfMonth(); + new FirstOfYear(); + new AddYears(); + new AddMonths(); + new AddDays(); + new EndOfMonth(); + new YearsBetween(); + new DaysBetween(); + new MonthsBetween(); + } + + /** + * Newdate( String -- Date ) + * Newdate Operator, returns the Date object for the String value + * + */ + static class Newdate extends ROperator { + Newdate(){super("newdate");} + + public void execute(DTState state) throws RulesException { + state.datapush(RTime.getRTime(java.sql.Date.valueOf(state.datapop().stringValue()))); + } + } + + /** + * Days( number -- Date ) + * Returns a Date object holding this number of days. + * + */ + static class Days extends ROperator { + Days(){super("days");} + + public void execute(DTState state) throws RulesException { + int days = state.datapop().intValue(); + long time = days * 24* 60 * 60 * 1000; + state.datapush(RTime.getRTime(new Date(time))); + } + } + + /** + * FirstOfMonth ( date -- date2) + * Given a date, returns date2 pointing to the first of the month. + * So given 2/23/07 would return 2/1/07 + */ + static class FirstOfMonth extends ROperator { + FirstOfMonth(){super("firstofmonth");} + + public void execute(DTState state) throws RulesException { + Date date = state.datapop().timeValue(); + state.calendar.setTime(date); + state.calendar.set(Calendar.DAY_OF_MONTH, 1); + state.calendar.set(Calendar.HOUR, 0); + state.calendar.set(Calendar.MINUTE, 0); + state.calendar.set(Calendar.MILLISECOND, 0); + state.datapush(RTime.getRTime(state.calendar.getTime())); + } + } + /** + * FirstOfYear ( date -- date2) + * Given a date, returns date2 pointing to the first of the year. + * So given 2/23/07 would return 2/1/07 + */ + static class FirstOfYear extends ROperator { + FirstOfYear(){super("firstofyear");} + + public void execute(DTState state) throws RulesException { + Date date = state.datapop().timeValue(); + state.calendar.setTime(date); + state.calendar.set(Calendar.DAY_OF_MONTH, 1); + state.calendar.set(Calendar.MONTH, 0); + state.calendar.set(Calendar.HOUR, 0); + state.calendar.set(Calendar.MINUTE, 0); + state.calendar.set(Calendar.MILLISECOND, 0); + state.datapush(RTime.getRTime(state.calendar.getTime())); + } + } + /** + * EndOfMonth ( date -- date2) + * Given a date, returns date2 pointing to the first of the month. + * So given 2/23/07 would return 2/1/07 + */ + static class EndOfMonth extends ROperator { + EndOfMonth(){super("endofmonth");} + + public void execute(DTState state) throws RulesException { + Date date = state.datapop().timeValue(); + state.calendar.setTime(date); + state.calendar.set( + Calendar.DAY_OF_MONTH, + state.calendar.getActualMaximum(Calendar.MONTH)); + state.calendar.set(Calendar.HOUR, 0); + state.calendar.set(Calendar.MINUTE, 0); + state.calendar.set(Calendar.MILLISECOND, 0); + state.datapush(RTime.getRTime(state.calendar.getTime())); + } + } + /** + * AddYears ( date int -- date2) + * Adds the given number of years to the given date. Care has to be + * taken where leap years are in effect. The month can change. + * So given 2/23/07 3 addYears would return 2/23/10 + */ + static class AddYears extends ROperator { + AddYears(){super("addyears");} + + public void execute(DTState state) throws RulesException { + int years = state.datapop().intValue(); + Date date = state.datapop().timeValue(); + state.calendar.setTime(date); + state.calendar.add(Calendar.YEAR, years); + state.datapush(RTime.getRTime(state.calendar.getTime())); + } + } + + /** + * AddMonths ( date int -- date2) + * Adds the given number of months to the given date. Care has to be + * taken where the current day (31) may not be present in the new + * month (a month with 30 days). + * The behavior in this case is defined by the behavior of the Java + * Calendar. + * So given 2/23/07 3 addMonths would return 5/23/07 + */ + static class AddMonths extends ROperator { + AddMonths(){super("addmonths");} + + public void execute(DTState state) throws RulesException { + int months = state.datapop().intValue(); + Date date = state.datapop().timeValue(); + state.calendar.setTime(date); + state.calendar.add(Calendar.MONTH, months); + state.datapush(RTime.getRTime(state.calendar.getTime())); + } + } + + /** + * AddDays ( date int -- date2) + * Adds the given number of days to the given date. You might + * move over to the next month! + */ + static class AddDays extends ROperator { + AddDays(){super("adddays");} + + public void execute(DTState state) throws RulesException { + int days = state.datapop().intValue(); + Date date = state.datapop().timeValue(); + state.calendar.setTime(date); + state.calendar.add(Calendar.DATE, days); + state.datapush(RTime.getRTime(state.calendar.getTime())); + } + } + + /** + * SetCalendar( String -- ) + * SetCalendar Operator, + */ + @SuppressWarnings({"unchecked"}) + static class SetCalendar extends ROperator { + SetCalendar(){super("setCalendar");} + + public void execute(DTState state) throws RulesException { + try { + Class clazz = Class.forName(state.datapop().stringValue()); + Object obj = clazz.newInstance(); + if(obj instanceof Calendar){ + state.calendar=(Calendar)obj; + } else { + throw new RulesException("Date Time Exception","Set Calendar","Not a Calendar Object"); + } + } catch(Exception e){ + throw new RulesException("Date Time Exception","/","Error while creating object: "+e); + } + } + } + + /** + * Yearof( date -- int ) + * Yearof Operator, returns the year value for the given date + */ + static class Yearof extends ROperator { + Yearof(){super("yearof");} + + public void execute(DTState state) throws RulesException { + Calendar calendar = Calendar.getInstance(); + calendar.setTime(state.datapop().timeValue()); + state.datapush(RInteger.getRIntegerValue(calendar.get(Calendar.YEAR))); + } + } + + /** + * Getdaysinyear( date -- long ) + * Getdaysinyear Operator, returns the number of days in a year from the given date + */ + static class Getdaysinyear extends ROperator { + Getdaysinyear(){super("getdaysinyear");} + + public void execute(DTState state) throws RulesException { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(state.datapop().timeValue()); + if(calendar.isLeapYear(calendar.get(Calendar.YEAR))){ + state.datapush(RInteger.getRIntegerValue(366)); + } else { + state.datapush(RInteger.getRIntegerValue(365)); + } + } + } + /** + * Getdayofmonth( date -- long ) + * Returns the day of the month in the given date + */ + static class Getdayofmonth extends ROperator { + Getdayofmonth(){super("getdayofmonth");} + + public void execute(DTState state) throws RulesException { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(state.datapop().timeValue()); + int day = calendar.get(Calendar.DAY_OF_MONTH); + state.datapush(RInteger.getRIntegerValue(day)); + } + } + /** + * GetdaysinMonth( date -- long ) + * Getdaysinyear Operator, returns the number of days in a year from the given date + */ + static class Getdaysinmonth extends ROperator { + Getdaysinmonth(){super("getdaysinmonth");} + + public void execute(DTState state) throws RulesException { + GregorianCalendar calendar = new GregorianCalendar(); + calendar.setTime(state.datapop().timeValue()); + int daysinmonth = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); + state.datapush(RInteger.getRIntegerValue(daysinmonth)); + } + } + + /** + * Datelt( date1 date2 -- boolean ) + * Datelt Operator, returns true if date1 is less than date2 + */ + static class Datelt extends ROperator { + Datelt(){super("d<");} + + public void execute(DTState state) throws RulesException { + Date date2 = state.datapop().timeValue(); + Date date1 = state.datapop().timeValue(); + boolean test =date1.before(date2); + state.datapush(RBoolean.getRBoolean(test)); + } + } + + /** + * Dategt( date1 date2 -- boolean ) + * Dategt Operator, returns true if date1 is greater than date2 + */ + static class Dategt extends ROperator { + Dategt(){super("d>");} + + public void execute(DTState state) throws RulesException { + Date date2 = state.datapop().timeValue(); + Date date1 = state.datapop().timeValue(); + boolean test = date1.after(date2); + state.datapush(RBoolean.getRBoolean(test)); + } + } + + /** + * Dateeq (date1 date2 -- boolean ) + * Dateeq Operator, returns true if date1 is equals to date2 + */ + static class Dateeq extends ROperator { + Dateeq(){super("d==");} + + public void execute(DTState state) throws RulesException { + Date date2 = state.datapop().timeValue(); + Date date1 = state.datapop().timeValue(); + state.datapush(RBoolean.getRBoolean(date1.compareTo(date2)==0)); + } + } + + /** + * Gettimestamp( date -- String ) + * Gettimestamp Operator, creates a string timestamp from s date + */ + static class Gettimestamp extends ROperator { + Gettimestamp(){super("gettimestamp");} + + public void execute(DTState state) throws RulesException { + Date date = state.datapop().timeValue(); + state.datapush(RString.newRString((new Timestamp(date.getTime())).toString())); + } + } + + /** + * d+ ( date1 date2 -- ) + * Add two dates together. This doesn't make all that much sense unless + * one or both of the dates is just a count of days. + */ + static class DatePlus extends ROperator { + DatePlus() {super("d+"); } + public void execute(DTState state) throws RulesException { + long date2 = state.datapop().timeValue().getTime(); + long date1 = state.datapop().timeValue().getTime(); + state.datapush(RTime.getRTime(new Date(date1+date2))); + } + + } + + /** + * d- ( date1 date2 -- ) + * Subtract date2 from date1 This doesn't make all that much sense unless + * one or both of the dates is just a count of days. + */ + static class DateMinus extends ROperator { + DateMinus() {super("d-"); } + public void execute(DTState state) throws RulesException { + long date2 = state.datapop().timeValue().getTime(); + long date1 = state.datapop().timeValue().getTime(); + state.datapush(RTime.getRTime(new Date(date1-date2))); + } + + } + /** + * ( date1 date2 -- int ) + * Returns the number of years between date1 and date2. It is always + * the difference, i.e. positive, even if date1 is after date2 + */ + static class YearsBetween extends ROperator { + YearsBetween() {super("yearsbetween"); } + public void execute(DTState state) throws RulesException { + Date date2 = state.datapop().timeValue(); + Date date1 = state.datapop().timeValue(); + if(date1.after(date2)){ + Date hold = date1; + date1 = date2; + date2 = hold; + } + state.calendar.setTime(date1); + int y1 = state.calendar.get(Calendar.YEAR); + int m1 = state.calendar.get(Calendar.MONTH); + int d1 = state.calendar.get(Calendar.DAY_OF_MONTH); + state.calendar.setTime(date2); + int y2 = state.calendar.get(Calendar.YEAR); + int m2 = state.calendar.get(Calendar.MONTH); + int d2 = state.calendar.get(Calendar.DAY_OF_MONTH); + int diff = y2-y1; + if(m2
+ * + * 1.3 0 .7 roundto

+ * + * would result in 1, while

+ * + * 1.7 0 .7 roundto
+ * + * would reslut in 2.


+ * + * Note: if the boundary is zero, than any fractional amount will round up. + * If the boundary is 1, the number is simply truncated. + * + * Limitation: We always towards zero. Lots of other rounding ideas are + * possible. We need to come back here and rework and add to our options + * if the need for more complexity comes our way. + * + * @author paul snow + * + */ + static class Roundto extends ROperator { + Roundto(){super("roundto"); } + + double round(double number,double boundary){ + double v = (int)number; // Get the integer porition of number + if (boundary>=1) return v; // If boundary is 1 or greater we are done + double r = Math.abs(number - v); // Get the fractional portion of number + if (boundary<=0) return r>0 ? v++ : v; // If boundary is 0 or less, inc on any fraction + if(r>=boundary)return v++; // Otherwise test the boundary. Inc if fraction + return v; // is greater or equal to the boundary. + } + public void execute(DTState state)throws RulesException { + double boundary = state.datapop().doubleValue(); + int places = state.datapop().intValue(); + double number = state.datapop().doubleValue(); + if(places >0){ // We put the boundary across zero. shift left if + number *= 10*places; // places is positive (okay, its a decimal shift) + number = round(number,boundary); // Do the round thing. + number /= 10*places; // Fix it back when done. + }else{ + number /= -10*places; // We decimal shift right if places is negative + number = round(number,boundary); // Do the round thing + number *= -10*places; // Fix it back. + } + + } + } + + + /** + * Negate a double + * @author paul snow + * + */ + static class FNegate extends ROperator { + FNegate(){super("fnegate"); } + + public void execute(DTState state)throws RulesException { + state.datapush( + RDouble.getRDoubleValue( + -state.datapop().doubleValue() + ) + ); + } + } + + + /** + * Absolute value of a double. + * @author paul snow + * + */ + static class FAbs extends ROperator { + FAbs(){super("fabs"); } + + public void execute(DTState state)throws RulesException { + state.datapush( + RDouble.getRDoubleValue( + Math.abs(state.datapop().doubleValue()) + ) + ); + } + } + /** + * Absolute value of an integer + * @author paul snow + * + */ + static class Abs extends ROperator { + Abs(){super("abs"); } + + public void execute(DTState state)throws RulesException { + state.datapush( + RInteger.getRIntegerValue( + Math.abs(state.datapop().intValue()) + ) + ); + } + } + + /** + * Negate an integer + * @author paul snow + * + */ + static class Negate extends ROperator { + Negate(){super("negate"); } + + public void execute(DTState state)throws RulesException { + state.datapush( + RInteger.getRIntegerValue( + -state.datapop().intValue() + ) + ); + } + } + + /** + * Add Operator, adds two integers + * @author Paul Snow + * + */ + static class Add extends ROperator { + Add(){ + super("+"); alias("ladd"); + } + + public void execute(DTState state) throws RulesException { + state.datapush(RInteger.getRIntegerValue(state.datapop().longValue()+state.datapop().longValue())); + } + } + + + + + /** + * Sub Operator, subracts two integers + * @author Paul Snow + * + */ + static class Sub extends ROperator { + Sub(){super("-"); alias("lsub");} + + public void execute(DTState state) throws RulesException { + long b = state.datapop().longValue(); + long a = state.datapop().longValue(); + long result = a-b; + state.datapush(RInteger.getRIntegerValue(result)); + } + } + + /** + * Mul Operator, multiply two integers + * @author Paul Snow + * + */ + static class Mul extends ROperator { + Mul(){super("*"); alias("lmul");} + + public void execute(DTState state) throws RulesException { + state.datapush(RInteger.getRIntegerValue(state.datapop().longValue()*state.datapop().longValue())); + } + } + + /** + * Divide Operator, divides one integer by another + * @author Paul Snow + * + */ + static class Div extends ROperator { + Div(){super("/"); alias("div"); alias("ldiv");} + + public void execute(DTState state) throws RulesException { + long result; + long a=0; long b=0; + try { + b = state.datapop().longValue(); + a = state.datapop().longValue(); + result = a/b; + } catch (ArithmeticException e) { + throw new RulesException("Math Exception","/","Error in Divide: "+a+"/"+b+"\n"+e); + } + state.datapush(RInteger.getRIntegerValue(result)); + } + } + + /** + * FAdd (f+) Operator, adds two doubles + * @author Paul Snow + * + */ + static class FAdd extends ROperator { + FAdd(){ + super("f+");alias("fadd"); + } + + public void execute(DTState state) throws RulesException { + IRObject b = state.datapop(); + IRObject a = state.datapop(); + state.datapush(RDouble.getRDoubleValue(a.doubleValue()+b.doubleValue())); + } + } + + + + + /** + * FSub (f-) Operator, subracts two doubles + * @author Paul Snow + * + */ + static class FSub extends ROperator { + FSub(){super("f-");alias("fsub");} + + public void execute(DTState state) throws RulesException { + double b = state.datapop().doubleValue(); + double a = state.datapop().doubleValue(); + double result = a-b; + state.datapush(RDouble.getRDoubleValue(result)); + } + } + + /** + * FMul Operator, multiply two doubles + * @author Paul Snow + * + */ + static class FMul extends ROperator { + FMul(){super("f*");alias("fmul");} + + public void execute(DTState state) throws RulesException { + state.datapush(RDouble.getRDoubleValue(state.datapop().doubleValue()*state.datapop().doubleValue())); + } + } + + /** + * FDiv Operator, divides one double by another double. + * @author Paul Snow + * + */ + static class FDiv extends ROperator { + FDiv(){super("fdiv"); alias("f/");} + + public void execute(DTState state) throws RulesException { + double result; + double a=0; double b=0; + try { + b = state.datapop().doubleValue(); + a = state.datapop().doubleValue(); + result = a/b; + } catch (ArithmeticException e) { + throw new RulesException("Math Exception","f/","Error in Divide: "+a+"/"+b+"\n"+e); + } + state.datapush(RDouble.getRDoubleValue(result)); + } + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/operators/RMiscOps.java b/DTRules/src/main/java/com/dtrules/interpreter/operators/RMiscOps.java new file mode 100644 index 0000000..4d9e84a --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/operators/RMiscOps.java @@ -0,0 +1,742 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter.operators; + +import com.dtrules.decisiontables.RDecisionTable; +import com.dtrules.entity.IREntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RBoolean; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RNull; +import com.dtrules.interpreter.RString; +import com.dtrules.session.DTState; +import com.dtrules.session.RSession; + +public class RMiscOps { + static { + new RError(); + new Debug(); + new Traceon(); + new Traceoff(); + new Ignore(); + new Stringlength(); + new Touppercase(); + new Tolowercase(); + new Trim(); + new substring(); + new Swap(); + new Dup(); + new Pop(); + new Over(); + new EntityName(); + new Entitypush(); + new Entitypop(); + new Entityfetch(); + new I(); new J(); new K(); + new ToR(); + new FromR(); + new Def(); + new Find(); + new Print(); + new Clone(); + new Xdef(); + new PStack(); + new Null(); + new Createentity(); + new Cvi(); + new Cvr(); + new Cvb(); + new Cve(); + new Cvs(); + new Cvn(); + new Cvd(); + new ActionString(); + new GetDescription(); + new RegexMatch(); + } + + /** + * ( -- RNull ) Return the Null object + */ + static class Null extends ROperator { + Null() { + super("null"); + } + public void execute(DTState state) throws RulesException { + state.datapush(RNull.getRNull()); + } + } + + + /** + * ( entity -- RName ) Get the name of the given entity. + */ + static class EntityName extends ROperator { + EntityName() { + super("entityname"); + } + public void execute(DTState state) throws RulesException { + IREntity entity = state.datapop().rEntityValue(); + state.datapush(entity.getName()); + } + } + /** + * ( Exception message -- ) Throws a RulesException with the given message. + * @author paul snow + * + * + */ + static class RError extends ROperator { + RError(){super("error");} + + public void execute(DTState state) throws RulesException { + String message = state.datapop().stringValue(); + String exception = state.datapop().stringValue(); + try { + throw new RulesException( + "exception", + "User Exception", + message); + } catch (Exception e) { + throw new RulesException("Type Check", + "User Exception", + exception+":"+message); + } + } + } + + /** + * ( string -- ) Prints a debug message only if debug output is enabled. + * @author paul snow + * + */ + static class Debug extends ROperator { + Debug(){super("debug");} + + public void execute(DTState state) throws RulesException { + String msg = state.datapop().stringValue(); + if(state.testState(DTState.DEBUG)){ + state.debug(msg); + } + } + } + + /** + * ( -- ) Turn on the trace flag. + * @author paul snow + * + */ + static class Traceon extends ROperator { + Traceon(){super("traceon");} + + public void execute(DTState state) throws RulesException { + state.setState(DTState.TRACE); + } + } + + /** + * ( -- ) Turn off the trace flag + * @author paul snow + * + */ + static class Traceoff extends ROperator { + Traceoff(){super("traceoff");} + + public void execute(DTState state) throws RulesException { + state.clearState(DTState.TRACE); + } + } + + /** + * ( flag -- ) Set the debug state + * + * @author paul snow + * + */ + static class SetDebug extends ROperator { + SetDebug(){super("setdebug");} + + public void execute(DTState state) throws RulesException { + boolean flg = state.datapop().booleanValue(); + if(flg){ + state.setState(DTState.DEBUG); + }else{ + state.clearState(DTState.DEBUG); + } + } + } + + /** + * A Noop -- Does nothing. + * @author paul snow + * + */ + static class Ignore extends ROperator { + Ignore(){super("ignore"); alias("nop");} + + public void execute(DTState state) throws RulesException { + } + } + + /** + * ( string -- length ) returns the length of the given string + * @author paul snow + * + */ + static class Stringlength extends ROperator { + Stringlength(){super("strlength");} + + public void execute(DTState state) throws RulesException { + String str = state.datapop().stringValue(); + RInteger len = RInteger.getRIntegerValue(str.length()); + state.datapush(len); + } + } + + /** + * ( String -- String ) converts the string to uppercase. + * @author paul snow + * + */ + static class Touppercase extends ROperator { + Touppercase(){super("touppercase");} + + public void execute(DTState state) throws RulesException { + String str = state.datapop().stringValue(); + String str2 = str.toUpperCase(); + state.datapush(RString.newRString(str2)); + } + } + + /** + * ( String -- String ) converts the string to lowercase + * @author paul snow + * + */ + static class Tolowercase extends ROperator { + Tolowercase(){super("tolowercase");} + + public void execute(DTState state) throws RulesException { + String str = state.datapop().stringValue(); + String str2 = str.toLowerCase(); + state.datapush(RString.newRString(str2)); + } + } + + /** + * ( string -- string ) Trims the string, per trim in Java + * @author paul snow + * + */ + static class Trim extends ROperator { + Trim(){super("trim");} + + public void execute(DTState state) throws RulesException { + String str = state.datapop().stringValue(); + String str2 = str.trim(); + state.datapush(RString.newRString(str2)); + } + } + + /** + * (endindex beginindex string -- substring ) Returns the substring + * @author paul snow + * + */ + static class substring extends ROperator { + substring(){super("substring");} + + public void execute(DTState state) throws RulesException { + String str = state.datapop().stringValue(); + int b = state.datapop().intValue(); + int e = state.datapop().intValue(); + String str2 = str.substring(b,e); + state.datapush(RString.newRString(str2)); + } + } + + /** + * ( obj1 obj2 -- obj2 obj1 ) swaps the top two elements on the data stack + * @author paul snow + * + */ + static class Swap extends ROperator { + Swap(){super("swap"); alias("exch");} + + public void execute(DTState state) throws RulesException { + IRObject obj1 = state.datapop(); + IRObject obj2 = state.datapop(); + state.datapush(obj1); + state.datapush(obj2); + } + } + + /** + * ( obj1 -- obj1 obj2 ) + * @author paul snow + * + */ + static class Dup extends ROperator { + Dup(){super("dup");} + + public void execute(DTState state) throws RulesException { + IRObject obj1 = state.datapop(); + state.datapush(obj1); + state.datapush(obj1); + } + } + + static class Pop extends ROperator { + Pop(){ + super("pop"); + alias("drop"); + } + + public void execute(DTState state) throws RulesException { + state.datapop(); + } + } + + /** + * (obj1 obj2 -- obj1 obj2 obj1 ) copies the element below the top. + * @author paul snow + * + */ + static class Over extends ROperator { + Over(){super("over");} + + public void execute(DTState state) throws RulesException { + IRObject obj1 = state.getds(state.ddepth()-2); + state.datapush(obj1); + } + } + + /** + * ( entity -- ) push the given entity onto the entity stack + * @author paul snow + * + */ + static class Entitypush extends ROperator { + Entitypush(){super("entitypush");} + + public void execute(DTState state) throws RulesException { + IREntity e = state.datapop().rEntityValue(); + if(state.testState(DTState.TRACE)){ + state.traceInfo("entitypush", "value='"+e.stringValue()+"' id='"+e.getID()+"'"); + } + state.entitypush(e); + } + } + + /** + * ( -- ) pops the top element from the entity stack and tosses + * it into the bit bucket + * @author paul snow + * + */ + static class Entitypop extends ROperator { + Entitypop(){super("entitypop");} + + public void execute(DTState state) throws RulesException { + if(state.testState(DTState.TRACE)){ + state.traceInfo("entitypop",""); + } + state.entitypop(); + } + } + + /** + * Pushes a copy of the top entity on the entity stack on to the + * data stack. + * ( index -- element ) + * @author paul snow + * + */ + static class Entityfetch extends ROperator { + Entityfetch(){super("entityfetch");} + public void execute(DTState state) throws RulesException { + int i = state.datapop().intValue(); + state.datapush(state.entityfetch(i)); + } + } + + /** + * Returns the top element from the control stack. + * @author paul snow + * + */ + static class I extends ROperator { + I(){super("i"); alias("r@");} + + public void execute(DTState state) throws RulesException { + state.datapush( state.getcs(state.cdepth()-1)); + } + } + + /** + * Returns the second element from the control stack. + * @author paul snow + * + */ + static class J extends ROperator { + J(){super("j");} + + public void execute(DTState state) throws RulesException { + state.datapush( state.getcs(state.cdepth()-2)); + } + } + + /** + * Returns the third element from the control stack. + * @author paul snow + * + */ + static class K extends ROperator { + K(){super("k");} + + public void execute(DTState state) throws RulesException { + state.datapush( state.getcs(state.cdepth()-3)); + } + } + + /** + * ( obj -- ) Pops the top element from the data stack, and pushes + * it to the Control stack. + * @author paul snow + * + */ + static class ToR extends ROperator { + ToR(){super(">r");} + + public void execute(DTState state) throws RulesException { + state.cpush(state.datapop()); + } + } + + /** + * ( -- obj ) pops the top element from the control stack, and pushes + * it to the data stack. + * @author paul snow + * + */ + static class FromR extends ROperator { + FromR(){super("r>");} + + public void execute(DTState state) throws RulesException { + state.datapush(state.cpop()); + } + } + + /** + * ( name value -- ) + * Binds the name with the value in the highest entity on the + * entity stack which is both writable, and has an entry with + * a writiable name that matches. + * + * @author paul snow + * + */ + static class Def extends ROperator { + Def(){super("def");} + + public void execute(DTState state) throws RulesException { + IRObject value = state.datapop(); + RName name = state.datapop().rNameValue(); + boolean f = state.def(name, value, true); + if(!f)throw new RulesException("Undefined", + "def", + name+" is undefined"); + } + } + /** + * ( name -- obj ) + * Looks up the name, and returns the value associated with + * the name in the top most entity that defines the name. + * Returns RNull if the name isn't found. + * @author paul snow + * + */ + static class Find extends ROperator { + Find(){super("find");} + + public void execute(DTState state) throws RulesException { + RName name = state.datapop().rNameValue(); + IRObject v = state.find(name); + if(v==null)throw new RulesException("Undefined", + "find", + name+" is undefined"); + } + } + /** + * ( obj -- ) Prints the top element of on the data stack to + * Standard Out. + * @author paul snow + * + */ + static class Print extends ROperator { + Print(){super("print"); alias("debug"); } + + public void execute(DTState state) throws RulesException { + state.debug(state.datapop().toString()); + } + } + + /** + * ( obj1 -- obj2 ) Creates a clone of the given object. + * @author paul snow + * + */ + static class Clone extends ROperator { + Clone(){super("clone");} + + public void execute(DTState state) throws RulesException { + state.datapush(state.datapop().clone(state.getSession())); + } + } + + /** + * ( value name -- ) + * Binds the name with the value in the highest entity on the + * entity stack which is both writable, and has an entry with + * a writiable name that matches. + * + * @author paul snow + * + */ + static class Xdef extends ROperator { + Xdef(){super("xdef");} + + public void execute(DTState state) throws RulesException { + RName name = state.datapop().rNameValue(); + IRObject value = state.datapop(); + boolean f = state.def(name, value, true); + if(!f) + if(state.find(name)==null){ + throw new RulesException("Undefined", + "xdef", + name+" is undefined"); + }else{ + throw new RulesException("Write Protection", + "xdef", + name+" is Input only, and xdef attempted to write to it"); + } + } + } + + /** + * ( -- ) Prints all the elements on all the stacks non-distructively. + * This is purely a debugging aid. + * @author paul snow + * + */ + static class PStack extends ROperator { + PStack(){super("pstack");} + + public void execute(DTState state) throws RulesException { + state.pstack(); + } + } + + /** + * ( RName -- ) Creates an instance of the entity with the given name. + * + * @author paul snow + * + */ + static class Createentity extends ROperator { + Createentity(){super("createentity");} + + public void execute(DTState state) throws RulesException { + RName ename = state.datapop().rNameValue(); + IREntity entity = ((RSession) state.getSession()).createEntity(null, ename); + state.datapush(entity); + } + } + + /** + * ( Object -- Integer ) Converts to an Integer. + * + * @author paul snow + * + */ + static class Cvi extends ROperator { + Cvi(){super("cvi");} + + public void execute(DTState state) throws RulesException { + IRObject v = state.datapop(); + IRObject obj = v.rIntegerValue(); + if(state.testState(DTState.TRACE)){ + if(v.type()!= IRObject.iInteger){ + state.traceInfo("cvi", "value='"+v+"'",obj.stringValue()); + } + } + state.datapush(obj); + } + } + /** + * ( Object -- Double ) Converts to an Double. + * + * @author paul snow + * + */ + static class Cvr extends ROperator { + Cvr(){super("cvr"); alias("cvd");} + + public void execute(DTState state) throws RulesException { + IRObject v = state.datapop(); + IRObject obj = v.rDoubleValue(); + if(state.testState(DTState.TRACE)){ + if(v.type()!= IRObject.iDouble){ + state.traceInfo("cvr", "value='"+v+"'",obj.stringValue()); + } + } + state.datapush(obj); + } + } + /** + * ( Object -- Boolean ) Converts to an Boolean. + * + * @author paul snow + * + */ + static class Cvb extends ROperator { + Cvb(){super("cvb");} + + public void execute(DTState state) throws RulesException { + state.datapush(state.datapop().rBooleanValue()); + } + } + /** + * ( Object -- Entity ) Converts to an Entity. + * + * @author paul snow + * + */ + static class Cve extends ROperator { + Cve(){super("cve");} + + public void execute(DTState state) throws RulesException { + IRObject v = state.datapop(); + if(v.type()==IRObject.iNull){ + state.datapush(v); + }else{ + state.datapush(v.rEntityValue()); + } + } + } + /** + * ( Object -- String ) Converts to a String. + * + * @author paul snow + * + */ + static class Cvs extends ROperator { + Cvs(){super("cvs");} + + public void execute(DTState state) throws RulesException { + state.datapush(state.datapop().rStringValue()); + } + } + /** + * ( Object -- String ) Converts to a Name. + * + * @author paul snow + * + */ + static class Cvn extends ROperator { + Cvn(){super("cvn");} + + public void execute(DTState state) throws RulesException { + IRObject obj = state.datapop(); + state.datapush(obj.rNameValue().getNonExecutable()); + } + } + /** + * ( Object -- Date ) Converts to an Date. + * + * @author paul snow + * + */ + static class Cvd extends ROperator { + Cvd(){super("cvd");} + + public void execute(DTState state) throws RulesException { + IRObject datevalue = state.datapop(); + state.datapush(datevalue.rTimeValue()); + } + } + + /** + * ( -- String ) Returns the Decision Table and Action number + * + * @author paul snow + * + */ + static class ActionString extends ROperator { + ActionString(){super("actionstring");} + + public void execute(DTState state) throws RulesException { + state.datapush( RString.newRString( + state.getCurrentTable().getName().stringValue()+" "+ + state.getCurrentTableSection()+" "+ + (state.getNumberInSection()+1))); + } + } + /** + * ( -- String ) Returns the Decision Table and Action number + * + * @author paul snow + * + */ + static class GetDescription extends ROperator { + GetDescription(){super("getdescription");} + + public void execute(DTState state) throws RulesException { + String section = state.getCurrentTableSection(); + String description = ""; + if(section.equalsIgnoreCase("action")){ + RDecisionTable table = state.getCurrentTable(); + description = table.getActionsComment()[state.getNumberInSection()]; + }else if(section.equalsIgnoreCase("condition")){ + RDecisionTable table = state.getCurrentTable(); + description = table.getConditionsComment()[state.getNumberInSection()]; + } + state.datapush( RString.newRString(description)); + } + } + /** + * ( regex String -- boolean ) Returns true if the given string is matched + * by the given regular expression. + * + * @author Paul Snow + * + */ + static class RegexMatch extends ROperator { + RegexMatch(){super("regexmatch");} + + public void execute(DTState state) throws RulesException { + String string = state.datapop().stringValue(); + String regex = state.datapop().stringValue(); + boolean b = string.matches(regex); + state.datapush( RBoolean.getRBoolean(b)); + } + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/operators/ROperator.java b/DTRules/src/main/java/com/dtrules/interpreter/operators/ROperator.java new file mode 100644 index 0000000..618c467 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/operators/ROperator.java @@ -0,0 +1,124 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter.operators; + +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.ARObject; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; + +/** + * This Class creates the primities entity in a rather cute way. The actual operators + * are for the most part extend ROperator and only supply a new execute() method. Each + * of these classes are defined as subclasses of the classes listed in the static + * section. They in turn have a static section that lists all of classes that implement + * the operators in their section. + *

+ * Each operator calls the super constructor with their name, and the super constructor + * (defined here) creates the entry in the primitives entity for the operator. + * + * @author paul snow + * + */ +public class ROperator extends ARObject { + + static final REntity primitives = new REntity(1,true,RName.getRName("primities",false)); + + static { + new RMath(); + new RArrayOps(); + new RControl(); + new RBooleanOps(); + new RMiscOps(); + new RDateTimeOps(); + new RTableOps(); + new RXmlValueOps(); + } + + static public IREntity getPrimitives() { + return primitives; + } + + final RName name; + public int type() { return iOperator; } + + /** + * Puts another entry into the primitives entity under a different name. This is + * useful for operators that we would like to define under two names (such as "pop" and + * "drop".) + * + * This function also allows us to define constants such as "true" and "false" as objects + * rather than defining operators that return "true" and "false". + * + * @param o + * @param n + */ + protected static void alias (IRObject o ,String n) { + try { + RName rn = RName.getRName(n); + primitives.addAttribute(rn, "", o, false, true, o.type(),null); + primitives.put(rn,o); + } catch (RulesException e) { + throw new RuntimeException("An Error occured in alias building the primitives Entity: "+n); + } + } + + /** + * A method that makes it a bit easier to call the other alias function when I am + * creating an alias for an operator in its own constructor. + * + * @param n + */ + protected void alias (String n){ + alias(this,n); + } + + /** + * All of the operators extend ROperator. They call the super constructor with their + * name as a string. Here we convert the name to an RName, set the name as a final + * field in the Operator, and create an entry in the primities entity for the + * operator. + * @param _name + */ + public ROperator(String _name){ + name = RName.getRName(_name,true); + try { + primitives.addAttribute(name, "", this,false, true,iOperator,null); + primitives.put(name,this); + } catch (RulesException e) { + throw new RuntimeException("An Error occured building the primitives Entity: "+name); + } + } + + public boolean isExecutable() { return true; } + + public String stringValue() { + return name.stringValue(); + } + + public String toString(){ + return name.stringValue(); + } + + public String postFix(){ + return name.stringValue(); + } +} diff --git a/DTRules/src/main/java/com/dtrules/interpreter/operators/RTableOps.java b/DTRules/src/main/java/com/dtrules/interpreter/operators/RTableOps.java new file mode 100644 index 0000000..6c2cbfd --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/interpreter/operators/RTableOps.java @@ -0,0 +1,166 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.interpreter.operators; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RString; +import com.dtrules.interpreter.RTable; +import com.dtrules.session.DTState; +import com.dtrules.session.RSession; + +public class RTableOps { + static { + new Lookup(); new Set(); new GetKeys (); + new NewTable(); new SetDescription(); new Translate (); + } + /** + * ( table, index1, index2, ... lookup -- result ) + * Does a lookup (of however many keys) and returns the result. An + * Error will be thrown if any index but the last fails to return + * an RTable object + * + * @author paul snow + * Aug 14, 2007 + * + */ + static class Lookup extends ROperator { + Lookup(){ super("lookup");} + + public void execute(DTState state) throws RulesException { + int cnt = 0; + int d = state.ddepth(); + while(state.getds(--d).type()!=iTable)cnt++; + RName []keys = new RName[cnt]; + for(int i=0;i ) + * Addto Operator, adds an element to an array + * @author Paul Snow + * + */ + static class SetXmlAttribute extends ROperator { + SetXmlAttribute(){super("setxmlattribute");} + + @Override + public void execute(DTState state) throws RulesException { + String value = state.datapop().stringValue(); + String attribute = state.datapop().stringValue(); + XMLTag xmlTag = state.datapop().xmlTagValue(); + + state.traceInfo("SetXmlAttribute","tag='"+xmlTag.getTag()+"' attribute='"+attribute+"' value='"+value+"'"); + + xmlTag.getAttribs().put(attribute, value); + } + } + /** + * GetXmlAttribute ( XmlValue Attribute --> Value ) + * Get the value of the given attribute from this XmlValue. + * If the attribute is not defined, a null is returned. + * @author Paul Snow + * + */ + static class GetXmlAttribute extends ROperator { + GetXmlAttribute(){super("getxmlattribute");} + + @Override + public void execute(DTState state) throws RulesException { + String attribute = state.datapop().stringValue(); + XMLTag xmlTag = state.datapop().xmlTagValue(); + + String value = (String) xmlTag.getAttribs().get(attribute); + if(value != null ){ + state.datapush(RString.newRString(value)); + state.traceInfo("GetXmlAttribute","tag='"+xmlTag.getTag()+"' attribute='"+attribute+"' value='"+value+"'"); + }else{ + state.datapush(RNull.getRNull()); + state.traceInfo("GetXmlAttribute","tag='"+xmlTag.getTag()+"' attribute='"+attribute+"' null='true'"); + } + } + } + + +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/mapping/AttributeInfo.java b/DTRules/src/main/java/com/dtrules/mapping/AttributeInfo.java new file mode 100644 index 0000000..bc9a75c --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/AttributeInfo.java @@ -0,0 +1,186 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.mapping; + +import java.util.ArrayList; +import java.util.Iterator; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.session.DTState; + +/** + * A structure for holding information about Attributes. Instances of AttributeInfo are stored in the setAttributes HashMap. + * Note that Attributes are a bit more complex than Entities. We allow not only the tag to be specfied, but the enclosing tag + * for the identification of an Attribute. To further complicate things, we can specify different target attributes... + * @author ps24876 + * + */ +@SuppressWarnings({"unchecked"}) +class AttributeInfo { + + public static final String DATE_STRING_TYPE = "DateString"; //Strings + public static final String STRING_TYPE = "String"; + public static final String INTEGER_TYPE = "Integer"; + public static final String NONE_TYPE = "None"; + public static final String FLOAT_TYPE = "Float"; + public static final String BOOLEAN_TYPE = "Boolean"; + public static final String ARRAY_TYPE = "list"; + public static final String ENTITY_TYPE = "entity"; + public static final String XMLVALUE_TYPE = "XmlValue"; + + public static final int DATE_STRING_CODE = 0; //Codes + public static final int STRING_CODE = 1; + public static final int NONE_CODE = 2; + public static final int INTEGER_CODE = 3; + public static final int FLOAT_CODE = 4; + public static final int BOOLEAN_CODE = 5; + public static final int ARRAY_CODE = 6; + public static final int ENTITY_CODE = 7; + public static final int XMLVALUE_CODE = 8; + + public static final String int2str[] = {DATE_STRING_TYPE, + STRING_TYPE, + NONE_TYPE, + INTEGER_TYPE, + FLOAT_TYPE, + BOOLEAN_TYPE, + ARRAY_TYPE, + ENTITY_TYPE, + XMLVALUE_TYPE, + }; + + /** + * This is the information we collect for an attribute + */ + public class Attrib { + String enclosure; // This is the XML Tag that must enclose this attribute. + String rAttribute; // This is the Rules Engine attribute to assign the value to + String rEntity; // If an Entity type, this is the Entity to create. + int type; // This is the type for this attribute. + } + /** + * A list of Attrib values for a given attribute mapping. + */ + ArrayList tag_instances = new ArrayList(); + + public ArrayList getTag_instances() { + return tag_instances; + } + + /** + * We add an enclosure attribute pair to these arraylists. An + * exception is thrown if we get two of the same enclosures. + * @param _enclosure + * @param _attribute + * @param _type + */ + public void add(DTState state, + final String tag, + final String _enclosure, + final String _attribute, + String _type)throws RulesException { + + final Iterator iattribs = tag_instances.iterator(); + int attribType = -1; + if(_type.equalsIgnoreCase("date"))_type = "datestring"; + if(_type.equalsIgnoreCase("time"))_type = "datestring"; + for(int i=0;i and enclosure <"+_enclosure+"> "+ + "have been encountered more than once in this mapping file\n"+ + "For "+ (_enclosure==""?"":"<"+_enclosure+"> ") +tag+"> \n"+ + " Existing: RAttribute '"+attrib.rAttribute+"'\n"+ + " type '"+int2str[attrib.type]+"'\n"+ + " New: RAttribute '"+_attribute+"'\n"+ + " type '"+_type+"'\n"); + if(thisisanerror) throw new RuntimeException("Duplicate Enclosures encountered"); + } + } + final Attrib attrib = new Attrib(); + attrib.enclosure = _enclosure==null?"":_enclosure; + attrib.rAttribute = _attribute; + attrib.type = attribType; + tag_instances.add(attrib); + } + + /** + * Looks up the given enclosure, and returns the attribute + * associated with that enclosure, or a null if not found. + * @param _enclosure + * @return + */ + public Attrib lookup(String _enclosure){ + if(_enclosure==null) _enclosure=""; + Iterator iattribs = tag_instances.iterator(); + while(iattribs.hasNext()){ + Attrib attrib = (Attrib) iattribs.next(); + if(attrib.enclosure.equals(_enclosure)){ + return attrib; + } + } + return null; + } + + public boolean elementExists(String tag, String _enclosure) + { + if(_enclosure==null) _enclosure=""; + Iterator iattribs = tag_instances.iterator(); + while(iattribs.hasNext()){ + Attrib attrib = (Attrib)iattribs.next(); + if(attrib.enclosure.equals(_enclosure)) + { + return true; + } + } + return false; + } + +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/mapping/DataMap.java b/DTRules/src/main/java/com/dtrules/mapping/DataMap.java new file mode 100644 index 0000000..b283b60 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/DataMap.java @@ -0,0 +1,541 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * The Data Map class holds data for later mapping into the Rules Engine + * using the same mapping definition that can be used to upload XML to + * an EDD. This interface can also be used to write out XML to a file. + * + * This isn't a complex implementation. The idea is to collect all the + * data we would have written to an XML file, then map it in the same + * way with the same tag structure into the EDD. And as a bonus, we + * allow for the writing of the data out as XML for debugging or playback + * purposes. + */ +package com.dtrules.mapping; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.HashMap; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.xmlparser.GenericXMLParser; +import com.dtrules.xmlparser.IGenericXMLParser; +import com.dtrules.xmlparser.IXMLPrinter; +import com.dtrules.xmlparser.XMLPrinter; + + +public class DataMap implements IXMLPrinter{ + Mapping map; + OutputStream out = null; + ArrayList tagStack = new ArrayList(); + XMLTag rootTag; + + /** + * Write out this DataMap as an XML file. I do not write out + * tags with no body (body == null) and no internal structure + * (no tag.tags....). This is because the load treats attributes + * with null values as having not responded at all. Such + * attributes default to the default value specified in the EDD. + * When we load the text version however, we can't have a tag + * or we will not behave in the same way. A null for a string + * will become a zero length string (for example). + * @param out + */ + static public void print(XMLPrinter xout, XMLTag tag){ + if(tag.body == null && tag.tags.size()>0){ + xout.opentag(tag.tag,tag.attribs); + for(XMLTag t : tag.tags){ + print(xout,t); + } + xout.closetag(); + }else{ + xout.opentag(tag.tag,tag.attribs); + xout.printdata(tag.body); + xout.closetag(); + } + } + + /** + * If created without an output stream, no XML is written. + * @param tag + */ + public DataMap(String tag){ + opentag(tag); + rootTag = top(); + } + /** + * Constructor you have to use if you wish to use Data Objects to + * provide attributes. + * @param map - Provides info on the DO's + * @param tag + * @param xmlOutputStream - Writes an XML file out if specified (not null). + */ + public DataMap(Mapping map, String tag, OutputStream xmlOutputStream){ + this(tag); + this.map = map; + this.out = xmlOutputStream; + } + /** + * If created with an output stream, XML is generated and written + * to the output stream. + * @param tag + * @param xmlOutputStream + */ + public DataMap(String tag, OutputStream xmlOutputStream){ + this(tag); + this.out = xmlOutputStream; + } + + /** + * Write out this DataMap as an XML file + * @param out + */ + public void print(OutputStream out){ + XMLPrinter xout= new XMLPrinter(out); + DataMap.print(xout,rootTag); + } + + /** + * Returns the number of tags on the tag stack. + */ + public int depth() { + return tagStack.size(); + } + + /** + * Returns the tag with the given index. Returns null if out + * of range. + */ + public String getTag(int i){ + if(i<0 || i>=tagStack.size())return null; + return tagStack.get(i).tag; + } + + public boolean isInContext(String tag, String key_attribute, Object value){ + XMLTag t = top(); + while(t!=null && t!=rootTag){ + if( t.tag.equals(tag) && + (key_attribute == null || + t.attribs.containsKey(key_attribute) && + (value==null || t.attribs.get(key_attribute).equals(value)))){ + return true; + } + t = t.parent; + } + return false; + } + + /** + * If we close, then we close all our tags. If an output file has been specified, + * we write that out. + */ + public void close() { + if(out!=null){ + print(out); + } + } + + /** + * close the last tag. + */ + public void closetag() { + tagStack.remove(tagStack.size()-1); + } + + private void newtag(String tag ){ + XMLTag t = top(); + if(t!=null && top().body!=null){ + throw new RuntimeException("You can't have tags and body text within the same XML tag!"); + } + XMLTag newtag = new XMLTag(tag,t); + if(t!=null){ + t.tags.add(newtag); + } + tagStack.add(newtag); + } + + private XMLTag top(){ + if(tagStack.size()==0)return null; + return tagStack.get(tagStack.size()-1); + } + + private void addValue(String key, Object value){ + top().attribs.put(key, value); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7, + String name8, Object value8, + String name9, Object value9) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + addValue(name4, value4); + addValue(name5, value5); + addValue(name6, value6); + addValue(name7, value7); + addValue(name8, value8); + addValue(name9, value9); + } + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7, + String name8, Object value8, + String name9, Object value9, + String name10,Object value10) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + addValue(name4, value4); + addValue(name5, value5); + addValue(name6, value6); + addValue(name7, value7); + addValue(name8, value8); + addValue(name9, value9); + addValue(name10,value10); + } + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7, + String name8, Object value8) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + addValue(name4, value4); + addValue(name5, value5); + addValue(name6, value6); + addValue(name7, value7); + addValue(name8, value8); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + addValue(name4, value4); + addValue(name5, value5); + addValue(name6, value6); + addValue(name7, value7); + } + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4, String name5, Object value5, String name6, Object value6) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + addValue(name4, value4); + addValue(name5, value5); + addValue(name6, value6); + + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4, String name5, Object value5) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + addValue(name4, value4); + addValue(name5, value5); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, String name1, Object value1, String name2, Object value2, String name3, Object value3, String name4, Object value4) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + addValue(name4, value4); + + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, String name1, Object value1, String name2, Object value2, String name3, Object value3) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + addValue(name3, value3); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, String name1, Object value1, String name2, Object value2) { + newtag(tag); + addValue(name1, value1); + addValue(name2, value2); + + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String, java.lang.String, java.lang.Object) + */ + public void opentag(String tag, String name1, Object value1) { + newtag(tag); + addValue(name1, value1); + } + + + /* + * Open a tag with the given hashmap of values + */ + @SuppressWarnings("unchecked") + public void opentag(String tag, HashMap attribs){ + newtag(tag); + for(Object key : attribs.keySet()){ + addValue((String)key,attribs.get(key)); + } + } + + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#opentag(java.lang.String) + */ + public void opentag(String tag) { + newtag(tag); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#print_error(java.lang.String) + */ + public void print_error(String errorMsg) { + opentag("error","msg",errorMsg); + closetag(); + + } + + /* + * We write the data to the body of the top tag. If multiple printdata() calls + * are made, then everything is converted to a String and added together. + */ + public void printdata(Object bodyvalue) { + XMLTag t = top(); + if(t.body==null){ + t.body = bodyvalue; + return; + } + t.body = t.body.toString() + bodyvalue.toString(); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#printdata(java.lang.String, java.lang.Object) + */ + public void printdata(String tag, Object bodyvalue) { + opentag(tag); + printdata(bodyvalue); + closetag(); + + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#printdata(java.lang.String, java.lang.String, java.lang.Object, java.lang.Object) + */ + public void printdata(String tag, String name1, Object value1, Object body) { + opentag(tag,name1,value1); + printdata(body); + closetag(); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#printdata(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.Object) + */ + public void printdata(String tag, String name1, Object value1, + String name2, Object value2, Object bodyvalue) { + opentag(tag,name1,value1, name2, value2); + printdata(bodyvalue); + closetag(); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#printdata(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.Object) + */ + public void printdata(String tag, String name1, Object value1, + String name2, Object value2, String name3, Object value3, + Object bodyvalue) { + opentag(tag,name1,value1, name2, value2, name3, value3); + printdata(bodyvalue); + closetag(); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#printdata(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.Object) + */ + public void printdata(String tag, String name1, Object value1, + String name2, Object value2, String name3, Object value3, + String name4, Object value4, Object bodyvalue) { + opentag(tag,name1,value1, name2, value2, name3, value3, name4, value4); + printdata(bodyvalue); + closetag(); + } + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IXMLPrinter#printdata(java.lang.String, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.String, java.lang.Object, java.lang.Object) + */ + public void printdata(String tag, String name1, Object value1, + String name2, Object value2, String name3, Object value3, + String name4, Object value4, String name5, Object value5, + Object bodyvalue) { + opentag(tag,name1,value1, name2, value2, name3, value3, name4, value4, name5, value5); + printdata(bodyvalue); + closetag(); + + } + + /** + * Return the Root XMLTag of the data structures + * @return + */ + public XMLTag getRootTag(){ return rootTag; } + /** + * Read the attributes of a Data Object and populate an EDD with + * those values. This assumes that the class for the Data Object has + * been mapped to an Entity in the Map file for a Rule Set + * @param obj + * @param tag + */ + public void readDO(Object obj, String tag){ + String do_name = obj.getClass().getName(); + ArrayList doMaps = map.dataObjects.get(do_name); + DataObjectMap doMap = null; + for(DataObjectMap DO : doMaps){ + if(DO.tag.equals(tag)){ + doMap = DO; + break; + } + } + if(doMap==null){ + throw new RuntimeException("Unknown Data Object: "+do_name); + } + try { + doMap.mapDO(this, obj); + } catch (RulesException e) { + throw new RuntimeException("Unknown Data Object: "+do_name); + } + } + /** + * Looks up the Key from the Data Object and generates the approprate + * open tag structure. + * @param obj + * @param tag + */ + public void opentag(Object obj, String tag){ + String do_name = obj.getClass().getName(); + ArrayList doMaps = map.dataObjects.get(do_name); + DataObjectMap doMap = null; + if(doMaps != null)for(DataObjectMap DO : doMaps){ + if(DO.tag.equals(tag)){ + doMap = DO; + break; + } + } + if(doMap==null){ + throw new RuntimeException("Attempt to map data into the EDD using an Unknown Data Object: "+do_name); + } + doMap.OpenEntityTag(this, obj); + } + + private class XmlLoader implements IGenericXMLParser { + DataMap datamap; + + XmlLoader(DataMap datamap){ + this.datamap = datamap; + } + public void beginTag(String[] tagstk, int tagstkptr, String tag, + HashMap attribs) throws IOException, Exception { + datamap.opentag(tag,attribs); + } + + public void endTag(String[] tagstk, int tagstkptr, String tag, + String body, HashMap attribs) throws Exception, + IOException { + if(body!=null && body.length()>0){ + datamap.printdata(body); + } + datamap.closetag(); + } + + public boolean error(String v) throws Exception { + return true; + } + + } + + /** + * Loads an XML File into a DataMap + * @param xml + */ + public void loadXML(InputStream xml) throws RulesException { + XmlLoader xmlLoader = new XmlLoader(this); + try{ + GenericXMLParser.load(xml, xmlLoader); + }catch(Exception e){ + throw new RulesException("Bad XML","loadXML",e.toString()); + } + } + +} diff --git a/DTRules/src/main/java/com/dtrules/mapping/DataObjectMap.java b/DTRules/src/main/java/com/dtrules/mapping/DataObjectMap.java new file mode 100644 index 0000000..130b638 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/DataObjectMap.java @@ -0,0 +1,161 @@ +package com.dtrules.mapping; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.HashMap; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.mapping.AttributeInfo.Attrib; + +/** + * Defines the DO accesser to Entity Object Attribute Mapping. Each + * instance of a DataObjectMap maps a DO to an Entity. If you need + * to be able to map the DO to several Entities, then you will need + * several DataObjectMaps, one for each Entity. + * @author Paul Snow + * May 8, 2008 + * + */ +@SuppressWarnings({"unchecked"}) +class DataObjectMap { + String tag; // Entity Tag to look for + boolean loaded = false; // Have I initialized this object yet? + String dataObjName; // Name for this DO + Class dataObj; // This is the Data Object Mapped by this Map + // Getter to Attribute Map for this DO + String entityName = null; // Names of Entities which receive attributes + // from this Data Object + String key = null; // The Key identifying this DO + String keyAccessor = null; // The name of the Accessor to get the Key + String key_attribute = null; // The Attribute identifying the Entity in the XML + + // We figure out what accessors in the DO provide values we can + // use populate attributes on the Entity, and we store the accessor to tag + // mapping here. + HashMap tagMap= new HashMap(); + + + DataObjectMap(String dataObjName,String entity, String tag, String key,String key_attribute) throws Exception { + this.dataObjName = dataObjName; + this.entityName = entity; + this.tag = tag; + this.dataObj = Class.forName(dataObjName); + this.key = key; + this.key_attribute = key_attribute==null?key:key_attribute; + if(key!=null){ + keyAccessor = "get"+key.substring(0,1).toUpperCase(); + if(key.length()>1){ + keyAccessor = keyAccessor+key.substring(1); + } + } + } + + /** + * Returns true if an Entity tag has been openned. + * @param datamap + * @param idataObj + * @return + * @throws Exception + */ + public boolean OpenEntityTag(DataMap datamap, Object idataObj){ + try{ + Class params[] = {}; + Object paramsObj[] = {}; + Object keyValue = null; + if(keyAccessor!=null){ + keyValue = dataObj.getMethod(keyAccessor,params).invoke(idataObj,paramsObj); + } + if(!datamap.isInContext(tag, key_attribute, keyValue)){ + if(key_attribute!=null){ + datamap.opentag(tag,key_attribute,keyValue); + }else{ + datamap.opentag(tag); + } + return true; + } + return false; + }catch(Exception e){ + return false; + } + } + + public void mapDO(DataMap datamap, Object idataObj)throws RulesException { + if(loaded==false){ + String err = init(datamap); + if(err!=null)throw new RulesException("Undefined","DataObjectMap",err); + } + Class params[] = {}; + Object paramsObj[] = {}; + + try { + boolean needToClose = OpenEntityTag(datamap, idataObj); + for(String getter : tagMap.keySet()){ + String tag = tagMap.get(getter); + Method getV = dataObj.getMethod(getter, params); + Object v = getV.invoke(idataObj, paramsObj); + datamap.printdata(tag, v); + } + if(needToClose){ + datamap.closetag(); + } + } catch (SecurityException e) { + throw new RulesException("invalidAccess","DataObjectMap",e.toString()); + } catch (IllegalArgumentException e) { + throw new RulesException("invalidAccess","DataObjectMap",e.toString()); + } catch (NoSuchMethodException e) { + throw new RulesException("undefined","DataObjectMap",e.toString()); + } catch (IllegalAccessException e) { + throw new RulesException("invalidAccess","DataObjectMap",e.toString()); + } catch (InvocationTargetException e) { + throw new RulesException("unknown","DataObjectMap",e.toString()); + } + } + /** + * Returns null if the prefix isn't found. + * @param prefix + * @param n + * @return + */ + private String removePrefix(String prefix, Method method){ + if(method.getParameterTypes().length!=0) return null; + String mName = method.getName(); + int l = prefix.length(); + if(mName.length() < l) return null; + if(!mName.startsWith(prefix))return null; + String first = mName.substring(l,l+1); + if(mName.length()>l+1){ + mName = first.toLowerCase()+mName.substring(l+1); + } + return mName; + } + /** + * Returns an array of error messages if the initialization fails. This + * routine looks through all the getters in the DO and looks for matches + * with the tags defined in the mapping file. + * @return + */ + public String init(DataMap datamap){ + loaded = true; + try { + Class c = Class.forName(dataObjName); + Method [] methods = c.getMethods(); + for(Method method : methods){ + String tag = removePrefix("is", method); + if(tag==null) tag = removePrefix("get",method); + if(tag!=null){ + AttributeInfo info = datamap.map.setattributes.get(tag); + if(info!= null) for(Attrib attrib : info.getTag_instances() ){ + if( entityName.equalsIgnoreCase(attrib.enclosure)){ + tagMap.put(method.getName(), tag); + } + + } + } + } + } catch (ClassNotFoundException e) { + return "Could not find the DO: "+dataObjName; + } + return null; + } + +} diff --git a/DTRules/src/main/java/com/dtrules/mapping/EntityInfo.java b/DTRules/src/main/java/com/dtrules/mapping/EntityInfo.java new file mode 100644 index 0000000..cafd54e --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/EntityInfo.java @@ -0,0 +1,57 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.mapping; + +import com.dtrules.entity.IREntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RName; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; + +/** + * Holds information about each entity expected in the XML input data. + * @author paul snow + * + */ +class EntityInfo { + String id; + String name; + IREntity entity; + String number; + String list; + /** + * Get a new instance of an Entity upon a reference in the data file. + * If only one instance of an Entity is to be created, then return + * that one. If the Entity is a constant Entity, return the constant + * Entity. Otherwise create a new clone and return that. + * @return + */ + IREntity getInstance(IRSession s)throws RulesException{ + if(number.equals("1"))return entity; + DTState state = s.getState(); + IRObject rarray = state.find(RName.getRName(name+"s")); + + IREntity newentity = (IREntity) entity.clone(s); + if(rarray!=null && rarray.type() ==IRObject.iArray){ + ((RArray)rarray).add(newentity); + } + return newentity; + } +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/mapping/LoadDatamapData.java b/DTRules/src/main/java/com/dtrules/mapping/LoadDatamapData.java new file mode 100644 index 0000000..9816a13 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/LoadDatamapData.java @@ -0,0 +1,229 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.mapping; + +import java.io.IOException; +import java.math.BigDecimal; +import java.text.ParseException; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RBoolean; +import com.dtrules.interpreter.RDouble; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RString; +import com.dtrules.interpreter.RTime; +import com.dtrules.interpreter.RXmlValue; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; +import com.dtrules.session.RSession; + +@SuppressWarnings({"unchecked"}) +public class LoadDatamapData extends LoadXMLData { + + public LoadDatamapData(Mapping _map){ + super(_map); + } + + public LoadDatamapData(Mapping _map, IRSession session, String _ruleSetName){ + super(_map, session, _ruleSetName); + } + + XMLTag xmltag = null; + + public void endTag(String[] tagstk, int tagstkptr, XMLTag tag, Object body, + HashMap attribs) throws Exception, IOException { + this.xmltag = tag; + endTag(tagstk,tagstkptr,tag.tag,body,attribs); + } + + + public void endTag(String[] tagstk, int tagstkptr, String tag, Object body, + HashMap attribs) throws Exception, IOException + { + String attr; + REntity entity = null; + + if(attribs.containsKey("create entity")){ // For create Entity Tags, we pop the Entity from the Entity Stack on the End Tag. + attribs.remove("create entity"); + entity = (REntity) state.entitypop(); + Iterator pairs = map.attribute2listPairs.iterator(); + body = ""; // Don't care about the Body if creating an Entity, but it can't be null either. + while(pairs.hasNext()){ + Object [] pair = (Object []) pairs.next(); + if(entity.containsAttribute(RName.getRName((String)pair[0]))){ + RName.getRName((String) pair[1],true).execute(state); + state.entitypush(entity); + RName.getRName("addto",true).execute(state); + + } + } + if(state.testState(DTState.TRACE)){ + state.traceTagEnd("createEntity", null); + } + } + + // If this is a Date format, we are going to reformat it, and let it feed into + // the regular set attribute code. + if ((attr = (String) attribs.get("set attribute date"))!=null){ // Look and see if we have an attribute name defined. + attribs.remove("set attribute date"); + if(body instanceof String){ + String sbody = body.toString(); + if (sbody.trim().length() > 0) + { + Date date; + try { + if(false && sbody.indexOf("7777")>=0){ + date = new Date(0x7FFFFFFFFFFFL); + }else{ + date = df_in.parse(sbody); + } + } catch (ParseException e) { + try{ + date = df_out.parse(sbody); + }catch (ParseException e2){ + date = df_out.parse("01/05/2008"); + //throw new RuntimeException("Bad Date encountered: ("+tag+")="+body); + } + } + body = df_out.format(date); + attribs.put("set attribute",attr); + } + } + }else { + attr = (String) attribs.get("set attribute"); + } + if (attr != null){ + attribs.remove("set attribute"); + // Look and see if we have an attribute name defined. + if(body!=null){ + RName a = RName.getRName(attr); + IRObject value; + + IREntity enclosingEntity = session.getState().findEntity(a); + if(enclosingEntity==null){ + throw new Exception ("No Entity is in the context that defines "+ a.stringValue()); + } + int type = enclosingEntity.getEntry(a).type; + + if(type == IRObject.iInteger){ + value = RInteger.getRIntegerValue(getLong(body)); + } else if (type == IRObject.iDouble) { + value = RDouble.getRDoubleValue(getDouble(body)); + } else if (type == IRObject.iBoolean){ + value = RBoolean.getRBoolean(body.toString()); + } else if (type == IRObject.iTime){ + value = RTime.getRTime((Date)body); + } else if (type == IRObject.iEntity) { + if(entity!=null){ + value = entity; + }else{ + throw new RulesException("MappingError","LoadDatamapData","Entity Tags have to create some Entity Reference"); + } + } else if (type == IRObject.iString) { + value = RString.newRString(body.toString()); + } else if (type == IRObject.iXmlValue){ + if(xmltag != null){ + value = new RXmlValue(state,xmltag); + }else{ + throw new RulesException("MappingError","LoadDatamapData","Somehow we are missing the XML Tag for the attribute: "+a); + } + } else { + throw new RulesException("MappingError","LoadDatamapData","Unsupported type encountered: "+RSession.typeInt2Str(type)); + } + // conversion in the Rules Engine to do the proper thing. + state.def(a,value,false); + state.traceInfo("message",null," /"+a+" \""+body+"\" def"); + } + } + + return; + } + + long getLong(Object num){ + if(num.getClass()==BigDecimal.class)return ((BigDecimal)num).longValue(); + if(num.getClass()==Long.class)return ((Long)num).longValue(); + if(num.getClass()==Double.class)return ((Double)num).longValue(); + if(num.getClass()==Integer.class)return((Integer)num).longValue(); + if(num.getClass()==String.class)return Long.parseLong(num.toString()); + throw new RuntimeException("Can't figure out the value "+num.toString()+" "+num.getClass().getName()); + } + + double getDouble(Object num){ + if(num.getClass()==BigDecimal.class)return ((BigDecimal)num).doubleValue(); + if(num.getClass()==Long.class)return ((Long)num).doubleValue(); + if(num.getClass()==Double.class)return ((Double)num).doubleValue(); + if(num.getClass()==Integer.class)return((Integer)num).doubleValue(); + if(num.getClass()==String.class)return Double.parseDouble(num.toString()); + throw new RuntimeException("Can't figure out the value "+num.toString()+" "+num.getClass().getName()); + } + + + @Override + public boolean error(String v) throws Exception { + return true; + } + + + /** + * We collect all the Entities we create as we go. These + * are stored as a value, and their id as the key. Then if + * we encounter the same key in the XML, we return the same + * Entity. + */ + HashMap entities = new HashMap(); + + IREntity UpdateReferences(IREntity e)throws RulesException { + RName listname = RName.getRName(e.getName().stringValue()+"s"); + + // First add this entity to any list found on the entity stack. + for(int i=0; i< state.edepth(); i++){ + // Look for all Array Lists on the Entity Stack that look like lists of this Entity + IRObject elist = state.getes(i).get(listname); + if(elist!=null && elist.type()==IRObject.iArray){ + // If not a member of this list, then add it. + if(!((RArray)elist).contains(e)){ + ((RArray)elist).add(e); + } + } + } + // Then update any reference to this entity that might be on the Entity Stack. + // DON'T mess with any entity's self reference though! That is BAD. + for(int i=0;i< state.edepth(); i++){ + if((state.getes(i)).get(e.getName())!=null){ + IREntity refto = state.getes(i); + + if(! refto.getName().equals(e.getName())) // Update a reference to an Entity of the same name, + (state.getes(i)).put(e.getName(), e); // but only if it isn't a self reference. + + } + } + + return e; + } + + + } diff --git a/DTRules/src/main/java/com/dtrules/mapping/LoadMap.java b/DTRules/src/main/java/com/dtrules/mapping/LoadMap.java new file mode 100644 index 0000000..f4c51d7 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/LoadMap.java @@ -0,0 +1,321 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.mapping; + +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import com.dtrules.entity.IREntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.RName; +import com.dtrules.session.DTState; +import com.dtrules.session.EntityFactory; +import com.dtrules.xmlparser.IGenericXMLParser; + + +/** + * LoadMap class is used by the GenerixXMLParser to load the Map defining + * the XML to EDD transformation. + * + * @author Paul Snow + * + */ +class LoadMap implements IGenericXMLParser { + /** + * We track if we encountered any errors, but we print as many messages as we can. + * Then we report if we failed to load, assuming anyone cares. + */ + private boolean loadSuccessful = true; + private HashMap undefinedEntities; + private HashMap definedAttributes; + + private final DTState state; + private final EntityFactory ef; + private final Mapping map; + + private HashMap _attribs; + + /** + * @param map + */ + LoadMap(DTState state, Mapping map) { + this.map = map; + this.state = state; + this.ef = state.getSession().getEntityFactory(); + } + + /** + * This boolean is set at the end of loading a file. + * @return the loadSuccessful + */ + public boolean isLoadSuccessful() { + return loadSuccessful; + } + /** + * + */ + + public void begin_dataobjects(){} + + public void begin_do2entitymap(){ + + String doClass = _attribs.get("class"); + String key = _attribs.get("key"); + String key_attribute = _attribs.get("key_attribute"); + String entity = _attribs.get("entity"); + String entity_tag = _attribs.get("entity_tag"); + ArrayList dataobjmaps = map.dataObjects.get(doClass); + + if(dataobjmaps==null){ + dataobjmaps = new ArrayList(); + map.dataObjects.put(doClass, dataobjmaps); + } + + for(DataObjectMap dataobjmap : dataobjmaps){ + if(dataobjmap.entityName.equals(entity) && + dataobjmap.tag.equals(entity_tag)){ + throw new RuntimeException("Duplicate DO to Entity mappings for: "+entity); + } + } + + try { + DataObjectMap dataobjmap = new DataObjectMap(doClass,entity,entity_tag,key,key_attribute); + dataobjmaps.add(dataobjmap); + } catch (Exception e) { + // System.out.println("Undefined Data Object: '"+doClass+"'\n"); + } + } + + /** + * Mapping tag. + * used simply to organize the mapping xml under a single tag. + * This does any initialization of the mapping state + * + */ + public void begin_mapping () { + undefinedEntities = new HashMap(); + definedAttributes = new HashMap(); + loadSuccessful = true; + } + + /** + * Contains the tags that define the XML to EDD mapping. Right + * now that is all we implement. In the future we will add an + * EDD to XML mapping set of tags, maybe. + * + */ + public void begin_XMLtoEDD () {} + + /** + * Tag groups all the entity tags. + */ + public void begin_entities () {} + + + /** + * Process an Entity tag. Example: + * + * Valid number specifications are: + * "*" (0 or more) + * "+" (1 or more) + * "1" (1) + */ + public void begin_entity () { + String entity = ((String) _attribs.get("name")).toLowerCase(); + String number = (String) _attribs.get("number"); + + IREntity rEntity = map.getSession().getEntityFactory().findRefEntity(RName.getRName(entity)); + if(rEntity==null){ + System.out.println("The Entity specified, '"+entity+"' is not defined"); + loadSuccessful = false; + } + if(number.equals("1") || number.equals("+") || number.equals("*")){ + this.map.entityinfo.put(entity,number); + }else{ + + try { + state.traceInfo("error", null, + "Number value must be '1', '*', or '+'. Encounterd: "+number); + } catch (RulesException e) {} // Ignore because we are going to throw an exception anyway. + throw new RuntimeException("Number value must be '1', '*', or '+'. Encounterd: "+number); + } + } + + /** + * Every entity that defines the given attribute gets its instances logged + * in to the given list. + */ + public void addalltolist () { + String withAttribute = (String) _attribs.get("withAttribute"); + String toList = (String) _attribs.get("toList"); + String pair[] = {withAttribute.toLowerCase(),toList.toLowerCase()}; + map.attribute2listPairs.add(pair); + + } + + /** + * Groups initalentity tags. + * + */ + public void begin_initialization(){} + + /** + * Defines an entity to be placed on the Entity Stack at initialization. + * + */ + public void begin_initialentity(){ + String entity = (String) _attribs.get("entity"); + this.map.entitystack.add(entity.toLowerCase()); + } + + /** + * Groups all of the mapping tags. + * + */ + public void begin_map(){} + + + /** + * Saves away the information required to create an entity. + * + */ + public void begin_createentity(){ + final String entity = (String) _attribs.get("entity"); + final String tag = (String) _attribs.get("tag"); + final String attribute = (String) _attribs.get("attribute"); + final String value = (String) _attribs.get("value"); + final String id = (String) _attribs.get("id"); + String list = (String) _attribs.get("list"); + list = list==null?"":list; + + try { + IREntity theentity = ef.findRefEntity(RName.getRName(entity)); + if(theentity==null)throw new Exception(); + } catch (Exception e) { + System.out.println("\nThe Entity "+entity+" isn't defined by the EDD"); + loadSuccessful = false; + } + + EntityInfo info = new EntityInfo(); + info.id = id; + info.name = entity.toLowerCase(); + info.list = list.toLowerCase().trim(); + if(attribute== null || value==null ){ + this.map.requests.put(tag,info); + }else{ + this.map.multiple.put(tag,attribute); + this.map.requests.put(value,info); + } + } + + + + /** + * The Rules Engine expects everything to be lowercase!! + * Be careful how you use attributes! + */ + public void begin_setattribute(){ + String tag = (String) _attribs.get("tag"); + String type = (String) _attribs.get("type"); + String enclosure = (String) _attribs.get("enclosure"); // This is an optional tag enclosure.... + String rattribute = (String) _attribs.get("RAttribute"); // This is the Entity Attribute name + + if(rattribute == null)rattribute = tag; // If no rattribute name is specified, default to the tag. + + AttributeInfo info = (AttributeInfo) this.map.setattributes.get(tag); + if(info==null){ + info = new AttributeInfo(); + } + try { + IREntity e = ef.findRefEntity(RName.getRName(enclosure)); + if(e==null){ + if(!undefinedEntities.containsKey(enclosure)){ + System.out.println("The entity "+enclosure+" isn't defined in the EDD"); + loadSuccessful = false; + undefinedEntities.put(enclosure, enclosure); + } + }else{ + if(definedAttributes.containsKey(enclosure+"*"+rattribute)){ + System.out.println("The Entity "+enclosure+" and Attribute "+rattribute +" have multiple definitions"); + loadSuccessful = false; + } + if(e.getEntry(RName.getRName(rattribute))==null){ + System.out.println("The Attribute "+rattribute+" isn't defined by "+enclosure); + loadSuccessful = false; + } + info.add(state,tag, enclosure,rattribute.toLowerCase(),type); + } + } catch (RulesException e) {} + + this.map.setattributes.put(tag,info); + } + + + /** + * Because all of the tags possible within a Mapping XML are defined, and because we only have to load the Mapping + * File once at initialization, all we do here is take our parameters and store them away within our class, then + * by intraspection load the proper method for this tag, and execute it. + */ + @SuppressWarnings({"unchecked"}) + public void beginTag(String[] tagstk, int tagstkptr, String tag, HashMap attribs) throws IOException, Exception { + + _attribs = (HashMap)attribs; + + if(state.testState(DTState.VERBOSE)){ + String data = "<"+tag+" "; + for(Object v : attribs.keySet()){ + data += v+" = '"+attribs.get(v)+"'"; + } + state.traceInfo("Load",null,data+">\n"); + } + + try { + this.getClass().getMethod("begin_"+tag, (Class[])null).invoke(this,(Object [])null); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + System.out.println( e.getCause().getMessage()); + loadSuccessful = false; + } catch (NoSuchMethodException e) { + System.out.println("No implmentation for "+tag+"()"); + throw new RuntimeException("Undefined tag found in mapping file: "+tag); + } + } + + /** + * We are not doing anything on an end tag right now. + */ + @SuppressWarnings({"unchecked"}) + public void endTag(String[] tagstk, int tagstkptr, String tag, String body, HashMap attribs) throws Exception, IOException { + + + } + /** + * All errors throw an Exception. If we run into problems, there is no + * recovery, no fix. + */ + public boolean error(String v) throws Exception { + return true; + } + +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/mapping/LoadMapping.java b/DTRules/src/main/java/com/dtrules/mapping/LoadMapping.java new file mode 100644 index 0000000..66176d3 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/LoadMapping.java @@ -0,0 +1,368 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.mapping; +/** + * Loads the mapping file (the description of how data should be moved + * from XML to the EDD) + * + */ +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RBoolean; +import com.dtrules.interpreter.RDouble; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RNull; +import com.dtrules.interpreter.RString; +import com.dtrules.interpreter.RTime; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; +import com.dtrules.session.RSession; +import com.dtrules.xmlparser.IGenericXMLParser; + +@SuppressWarnings({"unchecked"}) +public class LoadMapping implements IGenericXMLParser { + Mapping map; + int codeCnt = 0; + IRSession session; + IRObject def; + DTState state; + String ruleSetName; + static DateFormat df_in = new SimpleDateFormat ("yyyy-MM-dd"); + + static DateFormat df_out = new SimpleDateFormat ("MM/dd/yyyy"); + + + public LoadMapping(Mapping _map){ + map = _map; + } + + public LoadMapping(Mapping _map, IRSession session, String _ruleSetName){ + map = _map; + this.session = session; + this.state = session.getState(); + this.ruleSetName = _ruleSetName; + + try{ // Cache the def operator. + def = session.getState().find(RName.getRName("def")); + }catch(Exception e){ + try { + state.traceInfo("error", null,"General Rules Engine Failure"); + } catch (RulesException e1) { } // Ignore since we are going to throw anyway... + throw new RuntimeException(e); + } + + Iterator es = this.map.entities.keySet().iterator(); + while(es.hasNext()){ + RName ename = (RName) es.next(); + try { + IREntity e = findEntity(ename.stringValue().toLowerCase(),null,null); + state.entitypush(e); + } catch (RulesException e) { + try { + state.traceInfo("error", null,"Failed to initialize the Entity Stack (Failed on "+ename+")\n"+e); + } catch (RulesException e1) { } // Ignore since we are going to throw anyway... + throw new RuntimeException(e); + } + } + } + + /** + * Looks to make sure that we have not yet created an Entity + * of this name with the given code. If we have, we return the + * earlier created Entity. Otherwise, we create a new instance. + * @param entity -- We assume this is a valid Entity name (no dot syntax) + * @param code + * @return + * @throws RulesException + */ + IREntity findEntity( String entity, String code, EntityInfo info) throws RulesException{ + String number = (String) this.map.entityinfo.get(entity); + IREntity e; + if(number==null){ + number = "*"; + } + if(number.equals("1")){ + e = (IREntity)entities.get(entity); + if(e==null){ + e = session.getState().findEntity(RName.getRName(entity+"."+entity)); + if(e==null){ + e = ((RSession)session).createEntity(null,entity); + } + entities.put(entity,e); + } + }else { // We assume number.equals("*") || number.equals("+") + e = null; + String key = ""; + if(code!=null && code.length()!=0) { + key = entity+"$"+code; + e = (IREntity)entities.get(key); + } + if(e==null) { + e = ((RSession)session).createEntity(null,entity); + } + if(code!=null) entities.put(key,e); + } + if(e==null)throw new RulesException("undefined","LoadMapping.findEntity()","Failed to create the entity "+entity); + UpdateReferences(e,info); + return e; + } + + public void beginTag(String[] tagstk, int tagstkptr, String tag, + HashMap attribs) throws IOException, Exception { + String name = tag; // We assume the tag might create an entity + @SuppressWarnings("unused") + boolean traceopen = false; + EntityInfo info = (EntityInfo) this.map.requests.get(name); + AttributeInfo aInfo = (AttributeInfo) this.map.setattributes.get(tag); + + + // If I get info, then create an entity. + // Get the code from this tag. + // If a fixed entity name is specified, + // or the tag name, use it. Otherwise use the multiple name + if(info!=null){ + Object objCode = attribs.get(info.id); + String code = objCode==null?"":objCode.toString(); + String eName = info.name; + if (eName == null || eName.length() <= 0) + { + eName = (String) attribs.get("name"); + } + IREntity e = findEntity(eName, code, info); // Look up the entity I should create. + if(e!=null){ // I hope to goodness I can find it! + attribs.put("create entity","true"); + if(code.length()!=0) { + e.put(IREntity.mappingKey,RString.newRString(code)); + }else{ + e.put(IREntity.mappingKey,RString.newRString("v"+ (++codeCnt))); + } + + state.entitypush(e); + if(state.testState(DTState.TRACE)){ + state.traceTagBegin("createEntity", "name='"+info.name+"' id='"+code+"'"); + traceopen = true; + } + }else{ + + state.traceInfo("error", null, "The Mapping defines '"+info.entity+"', but this entity isn't defined in the EDD"); + throw new Exception("The Mapping defines '"+info.entity+"', but this entity isn't defined in the EDD"); + } + } + + if(aInfo!=null){ // If we are supposed to set an attribute, then we set ourselves up + // to define the entity attribute on the end tag. We may be setting this + // Attribute to the value of the Entity we just created/looked up. + /** + * First check enclosures, then check the blank case. This allows + * the user to specify a default mapping, yet still direct some attributes to + * specific destinations based on the enclosure. + */ + AttributeInfo.Attrib attrib; + { // Not only do you have to match the attribute name, + int i=tagstkptr-2; // But you must match the immediately enclosing tag + attrib = aInfo.lookup(tagstk[i]); + if(attrib!=null){ + queueSetAttribute(attrib, attribs); + } + } + attrib = aInfo.lookup(""); // If I don't find the enclosure defined, look to see + queueSetAttribute(attrib,attribs); // if a general default is defined. + } + } + + public void endTag(String[] tagstk, int tagstkptr, String tag, String body, + HashMap attribs) throws Exception, IOException + { + String attr; + REntity entity = null; + + if(attribs.containsKey("create entity")){ // For create Entity Tags, we pop the Entity from the Entity Stack on the End Tag. + entity = (REntity) state.entitypop(); + Iterator pairs = map.attribute2listPairs.iterator(); + body = ""; // Don't care about the Body if we created an Entity. + while(pairs.hasNext()){ + Object [] pair = (Object []) pairs.next(); + if(entity.containsAttribute(RName.getRName((String)pair[0]))){ + RName.getRName((String) pair[1],true).execute(state); + state.entitypush(entity); + RName.getRName("addto",true).execute(state); + + } + } + if(state.testState(DTState.TRACE)){ + state.traceTagEnd("createEntity", null); + } + } + + // If this is a Date format, we are going to reformat it, and let it feed into + // the regular set attribute code. + if ((attr = (String) attribs.get("set attribute date"))!=null){ // Look and see if we have an attribute name defined. + if (body.trim().length() > 0) + { + Date date; + try { + if(false && body.indexOf("7777")>=0){ + date = new Date(0x7FFFFFFFFFFFL); + }else{ + date = df_in.parse(body); + } + } catch (ParseException e) { + try{ + date = df_out.parse(body); + }catch (ParseException e2){ + date = df_out.parse("01/05/2008"); + //throw new RuntimeException("Bad Date encountered: ("+tag+")="+body); + } + } + body = df_out.format(date); + attribs.put("set attribute",attr); + } + } + + if ((attr = (String) attribs.get("set attribute"))!=null){ + // Look and see if we have an attribute name defined. + { + RName a = RName.getRName(attr); + IRObject value; + + IREntity enclosingEntity = session.getState().findEntity(a); + if(enclosingEntity!=null){ + + + int type = enclosingEntity.getEntry(a).type; + + if(type == IRObject.iInteger){ + value = RInteger.getRIntegerValue(body.length()==0? "0" : body); + } else if (type == IRObject.iDouble) { + value = RDouble.getRDoubleValue(body.length()==0? "0" : body); + } else if (type == IRObject.iBoolean){ + value = RBoolean.getRBoolean(body.length()==0? "false" : body); + } else if (type == IRObject.iTime){ + if(body.trim().length()>0){ + value = RTime.getRDate(body); + if(value == null){ + throw new RulesException("MappingError","LoadMapping","Bad Date... Could not parse '"+body+"'"); + } + }else{ + value = RNull.getRNull(); + } + } else if (type == IRObject.iEntity){ + if(entity!=null){ + value = entity; + }else{ + throw new RulesException("MappingError","LoadMapping","Entity Tags have to create some Entity Reference"); + } + }else { + value = RString.newRString(body); + } + // conversion in the Rules Engine to do the proper thing. + state.def(a,value,false); + } + } + } + + return; + } + + public boolean error(String v) throws Exception { + return true; + } + + /** + * Does nothing if the info is null... Just means we are not mapping this attribute. + * Otherwise it updates the attribs hashmap. + * + * @param info + */ + private void queueSetAttribute( AttributeInfo.Attrib attrib, HashMap attribs){ + if(attrib==null)return; + switch (attrib.type ){ + case AttributeInfo.DATE_STRING_CODE : + attribs.put("set attribute date",attrib.rAttribute); + break; + case AttributeInfo.STRING_CODE : + case AttributeInfo.NONE_CODE : + case AttributeInfo.INTEGER_CODE : + case AttributeInfo.BOOLEAN_CODE : + case AttributeInfo.FLOAT_CODE : + case AttributeInfo.ENTITY_CODE : + case AttributeInfo.XMLVALUE_CODE : + attribs.put("set attribute",attrib.rAttribute); + break; + default: + throw new RuntimeException("Bad Type Code "+attrib.type+" in com.dtrules.mapping.AttributeInfo: "+attrib.rAttribute); + } + } + + /** + * We collect all the Entities we create as we go. These + * are stored as a value, and their id as the key. Then if + * we encounter the same key in the XML, we return the same + * Entity. + */ + HashMap entities = new HashMap(); + + IREntity UpdateReferences(IREntity e, EntityInfo info)throws RulesException { + RName listname; + if(info!=null && info.list.length()==0){ + listname = RName.getRName(e.getName().stringValue()+"s"); + }else{ + listname = RName.getRName(info.list); + } + // First add this entity to any list found on the entity stack. + for(int i=0; i< state.edepth(); i++){ + // Look for all Array Lists on the Entity Stack that look like lists of this Entity + IREntity entity = state.getes(i); + IRObject elist = entity.get(listname); + if(elist!=null && elist.type()==IRObject.iArray){ + // If not a member of this list, then add it. + if(!((RArray)elist).contains(e)){ + ((RArray)elist).add(e); + } + } + } + // Then update the reference to this entity that might be on the Entity Stack. + // DON'T go wild. Only look at the top entity (or you may overwrite a reference + // you'd rather leave alone. + // DON'T mess with any entity's self reference though! That is BAD. + int i=state.edepth()-1; + if(((IREntity)state.getes(i)).get(e.getName())!=null){ + IREntity refto = state.getes(i); + if(! refto.getName().equals(e.getName())) // Update a reference to an Entity of the same name, + ((IREntity)state.getes(i)).put(e.getName(), e); // but only if it isn't a self reference. + + } + + return e; + } + + + } diff --git a/DTRules/src/main/java/com/dtrules/mapping/LoadXMLData.java b/DTRules/src/main/java/com/dtrules/mapping/LoadXMLData.java new file mode 100644 index 0000000..9710d3c --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/LoadXMLData.java @@ -0,0 +1,368 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.mapping; +/** + * Loads the mapping file (the description of how data should be moved + * from XML to the EDD) + * + */ +import java.io.IOException; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RBoolean; +import com.dtrules.interpreter.RDouble; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RNull; +import com.dtrules.interpreter.RString; +import com.dtrules.interpreter.RTime; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; +import com.dtrules.session.RSession; +import com.dtrules.xmlparser.IGenericXMLParser; + +@SuppressWarnings({"unchecked"}) +public class LoadXMLData implements IGenericXMLParser { + Mapping map; + int codeCnt = 0; + IRSession session; + IRObject def; + DTState state; + String ruleSetName; + static DateFormat df_in = new SimpleDateFormat ("yyyy-MM-dd"); + + static DateFormat df_out = new SimpleDateFormat ("MM/dd/yyyy"); + + + public LoadXMLData(Mapping _map){ + map = _map; + } + + public LoadXMLData(Mapping _map, IRSession session, String _ruleSetName){ + map = _map; + this.session = session; + this.state = session.getState(); + this.ruleSetName = _ruleSetName; + + try{ // Cache the def operator. + def = session.getState().find(RName.getRName("def")); + }catch(Exception e){ + try { + state.traceInfo("error", null,"General Rules Engine Failure"); + } catch (RulesException e1) { } // Ignore since we are going to throw anyway... + throw new RuntimeException(e); + } + + for(RName ename : this.map.entities.keySet()){ + try { + IREntity e = findEntity(ename.stringValue().toLowerCase(),null,null); + state.entitypush(e); + } catch (RulesException e) { + try { + state.traceInfo("error", null,"Failed to initialize the Entity Stack (Failed on "+ename+")\n"+e); + } catch (RulesException e1) { } // Ignore since we are going to throw anyway... + throw new RuntimeException(e); + } + } + } + + /** + * Looks to make sure that we have not yet created an Entity + * of this name with the given code. If we have, we return the + * earlier created Entity. Otherwise, we create a new instance. + * @param entity -- We assume this is a valid Entity name (no dot syntax) + * @param code + * @return + * @throws RulesException + */ + IREntity findEntity( String entity, String code, EntityInfo info) throws RulesException{ + String number = (String) this.map.entityinfo.get(entity); + IREntity e; + if(number==null){ + number = "*"; + } + if(number.equals("1")){ + e = (IREntity)entities.get(entity); + if(e==null){ + e = session.getState().findEntity(RName.getRName(entity+"."+entity)); + if(e==null){ + e = ((RSession)session).createEntity(null,entity); + } + entities.put(entity,e); + } + }else { // We assume number.equals("*") || number.equals("+") + e = null; + String key = ""; + if(code!=null && code.length()!=0) { + key = entity+"$"+code; + e = (IREntity)entities.get(key); + } + if(e==null) { + e = ((RSession)session).createEntity(null,entity); + } + if(code!=null) entities.put(key,e); + } + if(e==null)throw new RulesException("undefined","LoadXMLData.findEntity()","Failed to create the entity "+entity); + UpdateReferences(e,info); + return e; + } + + public void beginTag(String[] tagstk, int tagstkptr, String tag, + HashMap attribs) throws IOException, Exception { + String name = tag; // We assume the tag might create an entity + @SuppressWarnings("unused") + boolean traceopen = false; + EntityInfo info = (EntityInfo) this.map.requests.get(name); + AttributeInfo aInfo = (AttributeInfo) this.map.setattributes.get(tag); + + + // If I get info, then create an entity. + // Get the code from this tag. + // If a fixed entity name is specified, + // or the tag name, use it. Otherwise use the multiple name + if(info!=null){ + Object objCode = attribs.get(info.id); + String code = objCode==null?"":objCode.toString(); + String eName = info.name; + if (eName == null || eName.length() <= 0) + { + eName = (String) attribs.get("name"); + } + IREntity e = findEntity(eName, code, info); // Look up the entity I should create. + if(e!=null){ // I hope to goodness I can find it! + attribs.put("create entity","true"); + if(code.length()!=0) { + e.put(IREntity.mappingKey,RString.newRString(code)); + }else{ + e.put(IREntity.mappingKey,RString.newRString("v"+ (++codeCnt))); + } + + state.entitypush(e); + if(state.testState(DTState.TRACE)){ + state.traceTagBegin("createEntity", "name='"+info.name+"' id='"+code+"'"); + traceopen = true; + } + }else{ + + state.traceInfo("error", null, "The Mapping defines '"+info.entity+"', but this entity isn't defined in the EDD"); + throw new Exception("The Mapping defines '"+info.entity+"', but this entity isn't defined in the EDD"); + } + } + + if(aInfo!=null){ // If we are supposed to set an attribute, then we set ourselves up + // to define the entity attribute on the end tag. We may be setting this + // Attribute to the value of the Entity we just created/looked up. + /** + * First check enclosures, then check the blank case. This allows + * the user to specify a default mapping, yet still direct some attributes to + * specific destinations based on the enclosure. + */ + AttributeInfo.Attrib attrib; + { // Not only do you have to match the attribute name, + int i=tagstkptr-2; // But you must match the immediately enclosing tag + if(i>=0){ + attrib = aInfo.lookup(tagstk[i]); + if(attrib!=null){ + queueSetAttribute(attrib, attribs); + } + } + } + attrib = aInfo.lookup(""); // If I don't find the enclosure defined, look to see + queueSetAttribute(attrib,attribs); // if a general default is defined. + } + } + + public void endTag(String[] tagstk, int tagstkptr, String tag, String body, + HashMap attribs) throws Exception, IOException + { + String attr; + REntity entity = null; + + if(attribs.containsKey("create entity")){ // For create Entity Tags, we pop the Entity from the Entity Stack on the End Tag. + entity = (REntity) state.entitypop(); + Iterator pairs = map.attribute2listPairs.iterator(); + body = ""; // Don't care about the Body if we created an Entity. + while(pairs.hasNext()){ + Object [] pair = (Object []) pairs.next(); + if(entity.containsAttribute(RName.getRName((String)pair[0]))){ + RName.getRName((String) pair[1],true).execute(state); + state.entitypush(entity); + RName.getRName("addto",true).execute(state); + + } + } + if(state.testState(DTState.TRACE)){ + state.traceTagEnd("createEntity", null); + } + } + + // If this is a Date format, we are going to reformat it, and let it feed into + // the regular set attribute code. + if ((attr = (String) attribs.get("set attribute date"))!=null){ // Look and see if we have an attribute name defined. + if (body.trim().length() > 0) + { + Date date; + try { + if(false && body.indexOf("7777")>=0){ + date = new Date(0x7FFFFFFFFFFFL); + }else{ + date = df_in.parse(body); + } + } catch (ParseException e) { + try{ + date = df_out.parse(body); + }catch (ParseException e2){ + date = df_out.parse("01/05/2008"); + //throw new RuntimeException("Bad Date encountered: ("+tag+")="+body); + } + } + body = df_out.format(date); + attribs.put("set attribute",attr); + } + } + + if ((attr = (String) attribs.get("set attribute"))!=null){ + // Look and see if we have an attribute name defined. + { + RName a = RName.getRName(attr); + IRObject value; + + IREntity enclosingEntity = session.getState().findEntity(a); + if(enclosingEntity!=null){ + + + int type = enclosingEntity.getEntry(a).type; + + if(type == IRObject.iInteger){ + value = RInteger.getRIntegerValue(body.length()==0? "0" : body); + } else if (type == IRObject.iDouble) { + value = RDouble.getRDoubleValue(body.length()==0? "0" : body); + } else if (type == IRObject.iBoolean){ + value = RBoolean.getRBoolean(body.length()==0? "false" : body); + } else if (type == IRObject.iTime){ + if(body.trim().length()>0){ + value = RTime.getRDate(body); + if(value == null){ + throw new RulesException("MappingError","LoadXMLData","Bad Date... Could not parse '"+body+"'"); + } + }else{ + value = RNull.getRNull(); + } + } else if (type == IRObject.iEntity){ + if(entity!=null){ + value = entity; + }else{ + throw new RulesException("MappingError","LoadXMLData","Entity Tags have to create some Entity Reference"); + } + }else { + value = RString.newRString(body); + } + // conversion in the Rules Engine to do the proper thing. + state.def(a,value,false); + } + } + } + + return; + } + + public boolean error(String v) throws Exception { + return true; + } + + /** + * Does nothing if the info is null... Just means we are not mapping this attribute. + * Otherwise it updates the attribs hashmap. + * + * @param info + */ + private void queueSetAttribute( AttributeInfo.Attrib attrib, HashMap attribs){ + if(attrib==null)return; + switch (attrib.type ){ + case AttributeInfo.DATE_STRING_CODE : + attribs.put("set attribute date",attrib.rAttribute); + break; + case AttributeInfo.STRING_CODE : + case AttributeInfo.NONE_CODE : + case AttributeInfo.INTEGER_CODE : + case AttributeInfo.BOOLEAN_CODE : + case AttributeInfo.FLOAT_CODE : + case AttributeInfo.ENTITY_CODE : + case AttributeInfo.XMLVALUE_CODE : + attribs.put("set attribute",attrib.rAttribute); + break; + default: + throw new RuntimeException("Bad Type Code "+attrib.type+" in com.dtrules.mapping.AttributeInfo: "+attrib.rAttribute); + } + } + + /** + * We collect all the Entities we create as we go. These + * are stored as a value, and their id as the key. Then if + * we encounter the same key in the XML, we return the same + * Entity. + */ + HashMap entities = new HashMap(); + + IREntity UpdateReferences(IREntity e, EntityInfo info)throws RulesException { + RName listname; + if(info!=null && info.list.length()==0){ + listname = RName.getRName(e.getName().stringValue()+"s"); + }else{ + listname = RName.getRName(info.list); + } + // First add this entity to any list found on the entity stack. + for(int i=0; i< state.edepth(); i++){ + // Look for all Array Lists on the Entity Stack that look like lists of this Entity + IREntity entity = state.getes(i); + IRObject elist = entity.get(listname); + if(elist!=null && elist.type()==IRObject.iArray){ + // If not a member of this list, then add it. + if(!((RArray)elist).contains(e)){ + ((RArray)elist).add(e); + } + } + } + // Then update the reference to this entity that might be on the Entity Stack. + // DON'T go wild. Only look at the top entity (or you may overwrite a reference + // you'd rather leave alone. + // DON'T mess with any entity's self reference though! That is BAD. + int i=state.edepth()-1; + if(((IREntity)state.getes(i)).get(e.getName())!=null){ + IREntity refto = state.getes(i); + if(! refto.getName().equals(e.getName())) // Update a reference to an Entity of the same name, + ((IREntity)state.getes(i)).put(e.getName(), e); // but only if it isn't a self reference. + + } + + return e; + } + + + } diff --git a/DTRules/src/main/java/com/dtrules/mapping/MapGenerator.java b/DTRules/src/main/java/com/dtrules/mapping/MapGenerator.java new file mode 100644 index 0000000..c278f64 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/MapGenerator.java @@ -0,0 +1,217 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.mapping; + +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.StringTokenizer; + +import com.dtrules.xmlparser.GenericXMLParser; +import com.dtrules.xmlparser.IGenericXMLParser; +import com.dtrules.xmlparser.XMLPrinter; + +@SuppressWarnings({"unchecked"}) +public class MapGenerator implements IGenericXMLParser { + String[] tagstk; + int tagstkptr; + String tag; + HashMap attribs; + String body; + + XMLPrinter out = null; + String mapping = null; + + /** + * These are the list of entities for which at least one + * Attribute will be set by this mapping file. + */ + ArrayList entities = new ArrayList(); + ArrayList unreferenced = new ArrayList(); + /** + * Returns true if the particular mapping here is one of the + * input sources for this attribute. + */ + boolean inputMatch(String inputs){ + /** Deal quickly with the trival case **/ + if(inputs.trim().length()==0) return false; + StringTokenizer tokenizer = new StringTokenizer(inputs," \t\r\n,"); + while(tokenizer.hasMoreTokens()){ + if(tokenizer.nextToken().equalsIgnoreCase(mapping))return true; + } + return false; + } + + public void end_entity(){ + String attribute = (String) attribs.get("attribute"); + String type = (String) attribs.get("type"); + String input = (String) attribs.get("input"); + String entity = attribs.get("entityname").toLowerCase().trim(); + + if(inputMatch(input)){ + out.printdata("setattribute", + "tag" ,attribute, + "RAttribute" ,attribute, + "enclosure" ,entity, + "type" ,type, + null); + if(!entities.contains(entity)){ + entities.add(entity); + }else{ + if(unreferenced.contains(entity)){ + unreferenced.remove(entity); + } + } + }else{ + if(!entities.contains(entity)){ + entities.add(entity); + if(!unreferenced.contains(entity)){ + unreferenced.add(entity); + } + } + } + } + + public void beginTag(String[] tagstk, int tagstkptr, String tag, HashMap attribs) throws IOException, Exception { + this.tagstk = tagstk; + this.tagstkptr = tagstkptr; + this.tag = tag.toLowerCase(); + this.attribs = attribs; + this.body = null; + + try { + this.getClass().getMethod("begin_"+tag, (Class[])null).invoke(this,(Object [])null); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + System.out.println(e.getCause().getMessage()); + } catch (NoSuchMethodException e) { + //Ignore tags we don't know. + } + } + + + /* (non-Javadoc) + * @see com.dtrules.xmlparser.IGenericXMLParser#endTag(java.lang.String[], int, java.lang.String, java.lang.String, java.util.HashMap) + */ + public void endTag(String[] tagstk, int tagstkptr, String tag, String body, HashMap attribs) throws Exception, IOException { + this.tagstk = tagstk; + this.tagstkptr = tagstkptr; + this.tag = tag; + this.attribs = attribs; + this.body = body; + + try { + this.getClass().getMethod("end_"+tag, (Class[])null).invoke(this,(Object [])null); + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (SecurityException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + System.out.println(e.getCause().getMessage()); + } catch (NoSuchMethodException e) { + //System.out.println("Unknown: end_"+tag); + } + } + + /* Something required of the XML parser. + * @see com.dtrules.xmlparser.IGenericXMLParser#error(java.lang.String) + */ + public boolean error(String v) throws Exception { + return true; + } + + public void generateMapping(String mapping, String inputfile, String outputfile) throws Exception { + FileInputStream input = new FileInputStream(inputfile); + XMLPrinter out = new XMLPrinter(new FileOutputStream(outputfile)); + generateMapping(mapping,input,out); + } + /** + * Given an EDD XML, makes a good stab at generating a Mapping file for a given + * mapping source. The mapping source is specified as an input in the input column + * in the EDD. + * @param mapping + * @param input + * @param out + * @throws Exception + */ + public void generateMapping(String mapping, InputStream input, XMLPrinter out)throws Exception { + this.out = out; + this.mapping = mapping; + out.opentag("mapping"); + out.opentag("XMLtoEDD"); + + out.opentag("map"); + GenericXMLParser.load(input,this); + + for(String entity : entities){ + out.printdata("createentity", + "entity", entity, + "tag" , entity, + "id" , "id", + null); + } + out.closetag(); + + out.opentag("entities"); + for(String entity : entities) { + out.printdata("entity","name",entity,"number","*",null); + } + out.closetag(); + + out.opentag("initialization"); + for(String entity : unreferenced){ + out.printdata("initialentity","entity",entity,"epush","true",null); + } + out.closetag(); + + out.close(); + } + + + public static void main(String args[])throws Exception{ + String path = "C:/eb/workspace/AutoAssignmentDevelopment/"; + String mapping = "main"; + InputStream input = new FileInputStream(path+"xml/ny_eb_edd.xml"); + MapGenerator mg = new MapGenerator(); + FileOutputStream os = new FileOutputStream(path+"temp/gen_map.xml"); + XMLPrinter out = new XMLPrinter(os); + + mg.generateMapping(mapping, input, out); + + } + + + /** + * @return the entities + */ + public ArrayList getEntities() { + return entities; + } +} diff --git a/DTRules/src/main/java/com/dtrules/mapping/Mapping.java b/DTRules/src/main/java/com/dtrules/mapping/Mapping.java new file mode 100644 index 0000000..0f81b97 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/Mapping.java @@ -0,0 +1,287 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.mapping; + +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; + +import com.dtrules.entity.IREntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.RName; +import com.dtrules.session.DTState; +import com.dtrules.session.IRSession; +import com.dtrules.session.RSession; +import com.dtrules.session.RuleSet; +import com.dtrules.session.RulesDirectory; +import com.dtrules.xmlparser.GenericXMLParser; + +/** + * The Mapping class is used to load XML formated data into an instance of + * an EntityFactory. + * @author Paul Snow + * + */ +public class Mapping { + + private final DTState state; + + private final IRSession session; + + HashMap entities = new HashMap(); + HashMap multiple = new HashMap(); // Specifies a tag that uses an attribute to specify what entity to create. + HashMap requests = new HashMap(); + HashMap entityinfo = new HashMap(); + HashMap>dataObjects = new HashMap>(); + /** + * List of attribute/list pairs. Every entity that defines the given attribute has every instance saved in the given list. + * Each entry is an array of two strings, the attribute and the list name. + */ + ArrayList attribute2listPairs = new ArrayList(); + + /** + * A List of entities that should be created at intialization and put on the Entity Stack. + */ + ArrayList entitystack = new ArrayList(); // Specifies what Entities should be on the Entity Stack to begin with. + + + /** + * This is the set of Attribute objects used to map XML tags to Attributes on Entities. + */ + HashMap setattributes = new HashMap(); // Sets an attribute. + + + private Mapping(IRSession session){ + this.session = session; + this.state = session.getState(); + } + + private void initialize(){ + for(String entity : entitystack){ + try { + IREntity newEntity = ((RSession)session).createEntity(null,entity); + session.getState().entitypush(newEntity); + } catch (RulesException e) { + throw new RuntimeException("Failed to initialize the Entity Stack: "+e); + } + } + } + + /** + * For internal use only. If you need a Mapping object, get it from the appropriate + * RuleSet object. + * @param rd + * @param session + * @param filename + * @return + */ + public static Mapping newMapping(RulesDirectory rd, IRSession session, String filename){ + Mapping mapping = new Mapping(session); + try { + InputStream s = session.getRuleSet().openfile(filename); + session.getState().traceTagBegin("loadMapping", "file='"+filename+"'"); + mapping.loadMap(s); + session.getState().traceTagEnd("loadMapping",null); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + return mapping; + } + + + /** + * Clones the mapping structures for use by a given session + * @param session + * @param amapping + * @return + */ + public Mapping clone(IRSession session){ + Mapping mapping = new Mapping(session); + mapping.entities = entities; + mapping.multiple = multiple; + mapping.requests = requests; + mapping.entityinfo = entityinfo; + mapping.entitystack = entitystack; + mapping.setattributes = setattributes; + mapping.attribute2listPairs = attribute2listPairs; + mapping.dataObjects = dataObjects; + mapping.initialize(); + return mapping; + } + + + /** + * Constructor for creating a Mapping. This has been deprecated because + * building a map this way reloads the mapping file over and over. Instead + * you should use: + * + * Mapping map = session.getMapping(); + * + * @param rd + * @param session + * @param rs + * @deprecated + */ + public Mapping(RulesDirectory rd,IRSession session, RuleSet rs){ + this.session = session; + this.state = session.getState(); + String filename = rs.getMapPath().get(0); + try { + InputStream s = session.getRuleSet().openfile(filename); + session.getState().traceTagBegin("loadMapping", "file='"+filename+"'"); + this.loadMap(s); + session.getState().traceTagEnd("loadMapping",null); + } catch (FileNotFoundException e) { + throw new RuntimeException(e); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * Load parses XML to EDD Map file into a set of actions + * which can be used to build an EDD file. + *

+ * + * @param file + */ + protected void loadMap(InputStream xmlStream) throws Exception { + LoadMap map = new LoadMap(state,this); + GenericXMLParser.load(xmlStream,map); + if(!map.isLoadSuccessful()){ + + throw new Exception("Map failed to load due to errors!"); + } + } + + public void loadData(IRSession session, String dataSource )throws RulesException { + loadData(session, dataSource, dataSource); + } + + public void loadData(IRSession session, String dataSource, String source )throws RulesException { + InputStream input = session.getRuleSet().openfile(dataSource); + if(input == null){ + throw new RulesException("File Not Found","Mapping.loadData()","Could not open "+dataSource); + } + loadData(session,input,source); + } + + /** + * This is the state for dataloading... So that data can be split over multiple files, we + * cache our LoadXMLData object between calls to loadData(). + */ + LoadXMLData dataloader = null; + + /** + * Loads data using this mapping from an XML data Source into the given session. + * @param session + * @param dataSource + * @throws RulesException + */ + public void loadData (IRSession session, InputStream dataSource, String source) throws RulesException { + if(dataloader ==null) { + dataloader = new LoadXMLData(this,session,session.getRuleSet().getName()); + } + if(source==null){ + source = "XML file"; + } + try { + if(session.getState().testState(DTState.TRACE)){ + session.getState().traceTagBegin("dataLoad","source='"+source+"'"); + } + + GenericXMLParser.load(dataSource, dataloader); + + if(session.getState().testState(DTState.TRACE)){ + session.getState().traceTagEnd("dataLoad",null); + } + } catch (Exception e) { + if(session.getState().testState(DTState.TRACE)){ + session.getState().traceTagEnd("dataLoad",null); + } + throw new RulesException("Parse Error","LoadMap.loadData()",e.getMessage()); + } + } + + /** + * Load an in Memory data structure into the given session. + * @param session + * @param datasrc + * @throws RulesException + */ + public void loadData(IRSession session, DataMap datasrc)throws RulesException { + if(dataloader ==null) { + dataloader = new LoadDatamapData(this,session,session.getRuleSet().getName()); + } + try { + if(session.getState().testState(DTState.TRACE)){ + session.getState().traceTagBegin("loadData",""); + } + XMLTag tag = datasrc.getRootTag(); + processTag(tag); + if(session.getState().testState(DTState.TRACE)){ + session.getState().traceTagEnd("loadData",null); + } + }catch(Exception e){ + if(session.getState().testState(DTState.TRACE)){ + session.getState().traceTagEnd("loadData",null); + } + throw new RulesException("Parse Error","LoadMap.loadData()",e.getMessage()); + } + + } + String tagstk[] = new String[1000]; + int tagstkptr = 0; + /** + * Load a tag into a session. + */ + void processTag(XMLTag tag) throws Exception { + tagstk[tagstkptr++] = tag.tag; + dataloader.beginTag(tagstk, tagstkptr, tag.tag, tag.attribs); + for(XMLTag nextTag : tag.tags){ + state.traceTagBegin("process", null); + processTag(nextTag); + state.traceTagEnd("process", null); + } + ((LoadDatamapData)dataloader).endTag(tagstk, tagstkptr, tag, tag.body, tag.attribs); + tagstkptr--; + tagstk[tagstkptr]= null; + } + + + /** + * @return the state + */ + public DTState getState() { + return state; + } + + + /** + * @return the session + */ + public IRSession getSession() { + return session; + } + + +} diff --git a/DTRules/src/main/java/com/dtrules/mapping/XMLTag.java b/DTRules/src/main/java/com/dtrules/mapping/XMLTag.java new file mode 100644 index 0000000..b36af14 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/mapping/XMLTag.java @@ -0,0 +1,115 @@ +/** + * + */ +package com.dtrules.mapping; + +import java.util.ArrayList; +import java.util.HashMap; + +/** + * This object represents an XML tag, but I avoid serializaiton under + * the assumption that any conversion to a string would have been + * undone by a conversion from a string back to the object anyway. I + * also use the same structure for both tagged data and a tag holding + * tags. + * + * @author Paul Snow + * Sep 24, 2007 + * + */ +public class XMLTag { + String tag; + HashMap attribs = new HashMap(); + ArrayList tags = new ArrayList(); + Object body = null; + XMLTag parent; + + public XMLTag(String tag, XMLTag parent){ + this.tag = tag; + this.parent = parent; + } + + public String toString(){ + String r = "<"+tag; + for(String key : attribs.keySet()){ + r +=" "+key +"='"+attribs.get(key).toString()+"'"; + } + if(body != null){ + String b = body.toString(); + if(b.length()>20){ + b = b.substring(0,18)+"..."; + } + r +=">"+b+""; + }else if( tags.size()==0 ){ + r += "/>"; + }else{ + r += ">"; + } + return r; + } + + /** + * @return the tag + */ + public String getTag() { + return tag; + } + + /** + * @param tag the tag to set + */ + public void setTag(String tag) { + this.tag = tag; + } + + /** + * @return the tags + */ + public ArrayList getTags() { + return tags; + } + + /** + * @param tags the tags to set + */ + public void setTags(ArrayList tags) { + this.tags = tags; + } + + /** + * @return the body + */ + public Object getBody() { + return body; + } + + /** + * @param body the body to set + */ + public void setBody(Object body) { + this.body = body; + } + + /** + * @return the parent + */ + public XMLTag getParent() { + return parent; + } + + /** + * @param parent the parent to set + */ + public void setParent(XMLTag parent) { + this.parent = parent; + } + + /** + * @return the attribs + */ + public HashMap getAttribs() { + return attribs; + } + + +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/session/DTState.java b/DTRules/src/main/java/com/dtrules/session/DTState.java new file mode 100644 index 0000000..7150912 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/DTState.java @@ -0,0 +1,704 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.session; + + +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.GregorianCalendar; +import java.util.Random; + +import com.dtrules.decisiontables.RDecisionTable; +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntityEntry; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.xmlparser.GenericXMLParser; + +public class DTState { + + public Calendar calendar; + { // Work around for a Java Bug + // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5045774 + // + try{ + calendar = new GregorianCalendar(); + }catch(Throwable t){} + } + + private RDecisionTable currentTable; + private String currentTableSection; + private int numberInSection; + + /** + * The interpreter is a stack based interpreter. The implementation + * is much like a Postscript Interpreter. + * + * The control stack is used to implement a stack frame for + * decision tables. The control stack has no analog in a PostScript + * interpreter. + * + * The Entity stack is used to define the context for associating + * attributes with values. This is much like the PostScript Dictionary + * Stack. + * + * The Data stack is used to pass data to operators and to return + * results from operators. + */ + + private final int stklimit = 1000; + + IRObject ctrlstk[] = new IRObject[stklimit]; + IRObject datastk[] = new IRObject[stklimit]; + IREntity entitystk[] = new IREntity[stklimit]; + + int ctrlstkptr = 0; + int datastkptr = 0; + int entitystkptr = 0; + + int frames[] = new int[stklimit]; + int framestkptr = 0; + int currentframe = 0; + + final IRSession session; + + ArrayList tagstk = new ArrayList(); + int tracePoint = 0; + boolean newline = true; + + + public long seed = 0x711083186866559L; + public Random rand = new Random(seed); + /** + * The default debugging printstream is Standard Out. + * The default error printstream is Standard Out. + */ + private PrintStream out = System.out; + private PrintStream err = System.out; + + public PrintStream getErrorOut() { return err; } + public PrintStream getDebugOut() { return out; } + public PrintStream getTraceOut() { return out; } + + public static final int DEBUG = 0x00000001; + public static final int TRACE = 0x00000002; + public static final int ECHO = 0x00000004; + public static final int VERBOSE = 0x00000008; + + private int state = 0; + + + /** + * Set the output streams for debug and trace. + */ + public void setOutput(OutputStream debugtrace, OutputStream error){ + out = new PrintStream(debugtrace); + err = new PrintStream(error); + } + + /** + * Set the output streams for debug and trace. + */ + public void setOutput(PrintStream debugtrace, PrintStream error){ + out = debugtrace; + err = error; + } + + /** + * We always print the error stream. But this may not + * be true forever. + * @param s + * @return + */ + public boolean error(String s){ + err.print(s); + return true; + } + + public void traceStart(){ + setState(TRACE); + tracePoint = 0; + traceTagBegin("DTRulesTrace",null); + } + public void traceEnd() throws RulesException { + traceTagEnd("DTRulesTrace",null); + clearState(TRACE); + } + + + /** + * Returns a trace point. The trace Point is incremented each time a + * point is generated. The idea is that the RulesEngine state can be + * reset to the state represented by one of these trace points. + * @return + */ + public int tracePt(){ return tracePoint++; } + + /** + * Begins an execution tag. The execution (of something) is + * contained between the traceStart and traceEnd tags. If any + * attributes should be included, pass them as a string, i.e. + * " dt='Compute Policy" col='5' " + * If ECHO is set, then the output is also echoed to + * Standard out. + */ + public void traceTagBegin(String tag, String attribs){ + if(testState(TRACE)){ + if(!newline)out.println(); + if(testState(ECHO) && out != System.out){ + System.out.print(tag + " "+attribs); + } + out.print("<"+tag+ (attribs!=null ?" "+attribs+">":">")); + newline = false; + tagstk.add(tag); + } + } + /** + * Prints a single tag, i.e. "" + * @param tag + * @param attribs + */ + public void traceInfo(String tag, String attribs){ + if(testState(TRACE)){ + if(!newline)out.println(); + if(testState(ECHO) && out != System.out){ + System.out.print(tag + " "+attribs); + } + out.println("<"+tag+ (attribs!=null ?" "+attribs+"/>":"/>")); + newline = true; + } + } + /** + * Prints a tag, attributes, body, and the end tag. + * @param info The tag to use in the XML + * @param attribs Any attibutes you want + * @param body The body of the tag. + */ + public void traceInfo(String info, String attribs, String body)throws RulesException{ + traceTagBegin(info, attribs); + traceTagEnd(info,body); + } + + /** + * Ends an execution tag. The execution (of something) is + * contained between the traceTagBegin and traceTagEnd calls. + * Tags are checked for balance (if the tag is supplied.) + * If ECHO is on, the body is written to standard.out. + * Standard out. + * Returns true if it printed something. + */ + public void traceTagEnd(String tag, String body) throws RulesException { + if(testState(TRACE)){ + if(testState(ECHO) && out != System.out && body!=null){ + System.out.print(body); + System.out.print("\n"); + } + int index = tagstk.size()-1; + if(index<0){ + System.out.println("tag underflow"); + } + String btag = tagstk.get(index); + tagstk.remove(index); + if(tag!=null && !btag.equals(tag)){ + System.out.println("tag_error tag1='"+GenericXMLParser.encode(btag)+"' "+ + "expectedtag='"+GenericXMLParser.encode(tag)+"'"); + } + if(body!=null) out.print(GenericXMLParser.encode(body)); + out.println(""); + newline=true; + } + } + + /** + * Prints a string to the output file if DEBUG is on. + * If ECHO is set, then the output is also echoed to + * Standard out. + * Returns true if it printed something. + */ + public boolean debug(String s){ + if(testState(DEBUG)){ + if(!newline)out.println(); + if(testState(ECHO) && out != System.out){ + System.out.print(s); + } + s = GenericXMLParser.encode(s); + out.print(""+s+""); + newline=false; + return true; + } + return false; + } + + /** + * Prints the Data Stack, Entity Stack, and Control Stack to + * the debugging output stream. + */ + public void pstack() { + try{ + traceTagBegin("pstack", null); + + traceTagBegin("datastk", null); + for (int i = 0; i < ddepth(); i++) { + traceTagBegin("e",null); + traceTagEnd ("e",getds(i).stringValue()); + } + traceTagEnd("datastk",null); + + traceTagBegin("entitystk", null); + for (int i = 0; i < edepth(); i++) { + traceTagBegin("e",null); + traceTagEnd ("e",getes(i).stringValue()); + } + traceTagEnd("entitystk",null); + + traceTagEnd("pstack", null); + }catch(RulesException e){ + err.print("ERROR printing the stacks!\n"); + err.print(e.toString()+"\n"); + } + } + /** + * Returns the count of the number of elements on the data + * stack. + * @return data stack depth + */ + public int ddepth(){ + return datastkptr; + } + /** + * Returns the element on the data stack at the given depth + * If there are 3 elements on the data stack, getds(2) will + * return the top element. A stack underflow or overflow will + * be thrown if the index is out of range. + */ + public IRObject getds(int i) throws RulesException{ + if(i>=datastkptr){ + throw new RulesException( + "Data Stack Overflow", + "getds", + "index out of range: "+i); + } + if(i<0){ + throw new RulesException( + "Data Stack Underflow", + "getds", + "index out of range: "+i); + } + return datastk[i]; + } + + /** + * Returns the element on the entity stack at the given depth + * If there are 3 entities on the entity stack, getes(2) will + * return the top entity. A stack underflow or overflow will + * be thrown if the index is out of range. + */ + public IREntity getes(int i) throws RulesException{ + if(i>=entitystkptr){ + throw new RulesException( + "Entity Stack Overflow", "getes", + "index out of range: "+i); + } + if(i<0){ + throw new RulesException( + "Entity Stack Underflow", "getes", + "index out of range: "+i); + } + return entitystk[i]; + } + + /** + * While the state holds the stacks, the Session holds changes + * to Entities and other Rules Engine objects. On rare occasions + * we need to get our session, so we save it in the DTState. + * @param rs + */ + DTState(IRSession rs){ + session = rs; + } + + /** + * Get Session + * @return the session assocaited with this state + */ + public IRSession getSession(){ return session; } + + /** + * Returns the index of the Entity Stack. + * @return + */ + public int edepth () { return entitystkptr; } + /** + * Pushes an IRObject onto the data stack. + * @param o + * @throws RulesException + */ + public void datapush(IRObject o) throws RulesException { + if(datastkptr>=1000) { + throw new RulesException( + "Data Stack Overflow", + o.stringValue(), + "Data Stack overflow."); + } + datastk[datastkptr++]=o; + } + /** + * Pops an IRObject off the data stack and returns that object. + * @return + * @throws RulesException + */ + public IRObject datapop() throws RulesException { + if(datastkptr<=0) { + throw new RulesException( "Data Stack Underflow", "datapop()", "Data Stack underflow."); + } + IRObject rval = datastk[--datastkptr]; + datastk[datastkptr]=null; + return(rval); + } + + /** + * Pushes an entity on the entity stack. + * @param o + * @throws RulesException + */ + public void entitypush(IREntity o) throws RulesException { + if(entitystkptr>=1000) { + throw new RulesException("Entity Stack Overflow", + o.stringValue(), + "Entity Stack overflow."); + } + entitystk[entitystkptr++]=o; + } + /** + * Pops an Entity off of the Entity stack. + * @return + * @throws RulesException + */ + public IREntity entitypop() throws RulesException { + if(entitystkptr<=0) { + throw new RulesException("Entity Stack Underflow", + "entitypop", "Entity Stack underflow."); + } + IREntity rval = entitystk[--entitystkptr]; + entitystk[entitystkptr] = null; + return(rval); + } + /** + * Returns the nth element from the top of the entity stack + * (0 returns the top element, 1 returns the 1 from the top, 2 + * the 2 from the top, etc.) + * @return + * @throws RulesException + */ + public IREntity entityfetch(int i) throws RulesException { + if(entitystkptr<=i) { + throw new RulesException("Entity Stack Underflow", + "entityfetch", "Entity Stack underflow."); + } + IREntity rval = entitystk[entitystkptr-1-i]; + return(rval); + } + + /** + * Test to see if the given flag is set. + * @param flag + * @return + */ + public boolean testState(int flag){ + return (state&flag)!=0; + } + + /** + * Clear the given flag (By and'ing the not of the flag + * into the state) + */ + public void clearState(int flag){ + state &= flag^0xFFFFFFFF; + } + + /** + * Set the given flag by or'ing the flag into the state + * @param flag + */ + public void setState(int flag){ + state |= flag; + } + + + /** + * Returns the current depth of the control stack. + * @return + */ + public int cdepth(){ return ctrlstkptr; } + + public void pushframe() throws RulesException{ + if(framestkptr>=stklimit){ + throw new RulesException("Control Stack Overflow", + "pushframe", "Control Stack Overflow."); + + } + frames[framestkptr++] = currentframe; + currentframe = ctrlstkptr; + } + + public void popframe() throws RulesException{ + if(framestkptr<=0){ + throw new RulesException("Control Stack Underflow", + "popframe", "Control Stack underflow."); + } + ctrlstkptr = currentframe; // Pop off this frame, + currentframe = frames[--framestkptr]; // Then set the currentframe back to its previous value. + } + + public IRObject getFrameValue(int i) throws RulesException{ + if(currentframe+i >= ctrlstkptr){ + throw new RulesException("OutOfRange","getFrameValue",""); + } + return getcs(currentframe+i); + } + + public void setFrameValue(int i, IRObject value) throws RulesException{ + if(currentframe+i >= ctrlstkptr){ + throw new RulesException("OutOfRange","getFrameValue",""); + } + setcs(currentframe+i, value); + } + + /** + * Push an Object onto the control stack. + * @param o + */ + public void cpush(IRObject o){ + ctrlstk[ctrlstkptr++]= o; + } + + /** + * Pop the top element from the control stack and return it. + * @return + */ + public IRObject cpop(){ + IRObject r = ctrlstk[--ctrlstkptr]; + ctrlstk[ctrlstkptr]= null; + return r; + } + + public IRObject getcs(int i) throws RulesException{ + if(i>=ctrlstkptr){ + throw new RulesException("Control Stack Overflow","getcs", + "index out of range: "+i); + } + if(i<0){ + throw new RulesException("Control Stack Underflow","getcs", + "index out of range: "+i); + } + return ctrlstk[i]; + } + + public void setcs(int i, IRObject v) throws RulesException{ + if(i>=ctrlstkptr){ + throw new RulesException("Control Stack Overflow","setcs", + "index out of range: "+i); + } + if(i<0){ + throw new RulesException("Control Stack Underflow","getcs", + "index out of range: "+i); + } + ctrlstk[i] = v; + } + + /** + * This method evalates a condition, or any other set of PostFix code that produces + * a boolean value. The code must only add one element to the data stack, and that + * element must have a valid boolean value. + * @param c -- Condition to execute + * @return -- Returns the boolean value of c + * @throws RulesException + */ + public boolean evaluateCondition(IRObject c) throws RulesException { + int stackindex = datastkptr; // We make sure the object only produces one boolean. + c.execute(this); // Execute the condition. + if(datastkptr-1 != stackindex){ + throw new RulesException("Stack Check Exception","Evaluation of Condition","Stack not balanced"); + } + return datapop().booleanValue(); + } + /** + * This method executes an action, or any other set of Postfix code. This code can + * have side effects, but it cannot change the depth of the data stack. + * @param c -- Object to execute + * @throws RulesException + */ + public void evaluate(IRObject c) throws RulesException { + int stackindex = datastkptr; + c.execute(this); + if(datastkptr != stackindex){ + throw new RulesException("Stack Check Exception","Evaluation of Action","Stack not balanced"); + } + } + + /** + * Looks up the entity stack for an Entity that defines an + * attribute that matches the name provided. When such an Entity + * with an attribute that matches the name is found, that Entity + * is returned. A null is returned if no match is found, which + * means no Entity on the entity Stack defines an attribute with + * a name that mathches the name provided. + * @param name + */ + public IREntity findEntity(RName name) throws RulesException{ + RName entityname = name.getEntityName(); // If the RName does not spec an Enttiy Name + if(entityname == null){ // then we simply look for the RName in each + for(int i=entitystkptr-1;i>=0;i--){ // entity on the Entity Stack. + IREntity e = entitystk[i]; + if(e.containsAttribute(name)) return e; + } + }else{ // Otherwise, we insist that the Entity name + for(int i=entitystkptr-1;i>=0;i--){ // match as well as insist that the Entity + IREntity e = entitystk[i]; // have an attribute that matches this name. + if(e.getName().equals(entityname)){ + if(e.containsAttribute(name)){ + return e; + } + } + } + } + + return null; // No matach found? return a null. + } + + /** + * Looks up the Entity Stack and returns the value for the + * given named attribute. + * + * When getting data out of the rules Engine, it is useful to + * take string values rather than RNames. This should never be + * done within the Rules Engine where RNames should be the + * coin of the realm. + * + * This routine simply returns a null if an error occurs or if + * the name is undefined. + */ + public IRObject find(String name){ + try { + return find(RName.getRName(name)); + } catch (RulesException e) { + return null; + } + } + + /** + * Looks up the entity stack and returns the entity which + * defines the value of the given attribute. + * + * When getting data out of the rules Engine, it is useful to + * take string values rather than RNames. This should never be + * done within the Rules Engine where RNames should be the + * coin of the realm. + * + * This routine simply returns a null if an error occurs or if + * the name is undefined. + */ + public IREntity findEntity(String name){ + try { + return findEntity(RName.getRName(name)); + } catch (RulesException e) { + return null; + } + } + + /** + * Looks up the entity stack for a match for the RName. When a match is found, the + * value is returned. A null is returned if no match is found. + * @param name + */ + public IRObject find(RName name) throws RulesException{ + IREntity entity = findEntity(name); + if(entity == null) return null; + return entity.get(name); + } + + /** + * Looks up the entity stack for a match for the RName. When a match is found, the + * value is placed there and a true is returned. + * If no match is found, def returns false. + * @param name + * @param value + */ + public boolean def(RName name, IRObject value, boolean protect) throws RulesException{ + + RName entityname = name.getEntityName(); + + + for(int i=entitystkptr-1;i>=0;i--){ + IREntity e = entitystk[i]; + if(!e.isReadOnly() && (entityname == null || e.getName().equals(entityname) )){ + REntityEntry entry = e.getEntry(name); + if(entry!=null &&(!protect || entry.writable)){ + if(testState(TRACE)){ + traceTagBegin("def", "entity='"+e.postFix()+"' name='"+name.stringValue()+"'"); + traceTagEnd("def",value.postFix()); + } + + e.put(name, value); + return true; + } + } + } + return false; + } + public RDecisionTable getCurrentTable() { + return currentTable; + } + public void setCurrentTable(RDecisionTable currentTable) { + this.currentTable = currentTable; + } + /** + * Condition, Action, Context, etc. + * @return the currentTableSection + */ + public String getCurrentTableSection() { + return currentTableSection; + } + /** + * Condition, Action, Context, etc. + * @param currentTableSection the currentTableSection to set + */ + public void setCurrentTableSection(String currentTableSection,int number) { + this.currentTableSection = currentTableSection; + this.numberInSection = number; + } + /** + * Condition number, context number, initial Action number, etc. -1 means not set + * @return the numberInSection + */ + public int getNumberInSection() { + return numberInSection; + } + /** + * Condition number, context number, initial Action number, etc. -1 means not set + * @param numberInSection the numberInSection to set + */ + public void setNumberInSection(int numberInSection) { + this.numberInSection = numberInSection; + } + +} diff --git a/DTRules/src/main/java/com/dtrules/session/EDDLoader.java b/DTRules/src/main/java/com/dtrules/session/EDDLoader.java new file mode 100644 index 0000000..51df3ea --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/EDDLoader.java @@ -0,0 +1,146 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.session; + +import java.io.IOException; +import java.util.HashMap; + +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.xmlparser.IGenericXMLParser; + +@SuppressWarnings({"unchecked"}) +public class EDDLoader implements IGenericXMLParser { + + final EntityFactory ef; + final String filename; + boolean succeeded = true; + String errorMsgs = ""; + + EDDLoader(String _filename, EntityFactory _ef){ + ef = _ef; + filename = _filename; + } + + /** + * If this string has a non-zero length, the EDD did not load + * properly. The caller is responsible for checking this. Otherwise + * the loader can only report a single error. + * + * @return + */ + + + public String getErrorMsgs() { + return errorMsgs; + } + + + + + public void beginTag(String[] tagstk, int tagstkptr, String tag, + HashMap attribs) throws IOException, Exception { + } + + public void endTag(String[] tagstk, + int tagstkptr, + String tag, + String body, + HashMap attribs) throws Exception, IOException { + + if(tag.equals("entity")){ + String entityname = (String) attribs.get("entityname"); + String attribute = (String) attribs.get("attribute"); + String type = (String) attribs.get("type"); + String subtype = (String) attribs.get("subtype"); + String access = (String) attribs.get("access"); + String defaultv = (String) attribs.get("default"); + + boolean writeable = true; // We need to convert access to a boolean + boolean readable = true; // Make an assumption of r/w + int itype = -1; // We need to convert the type to an int. + IRObject defaultO = null; // We need to convert the default into a Rules Engine Object. + + //First deal with the access thing... Compute the boolean we need. + if(access==null){ // Check to see if we need to handle TIERS EDD files. + access = (String) attribs.get("cdd_i_c_flag"); + if(access!=null){ + writeable = access.toLowerCase().indexOf("i")<0; + } + }else{ // Nope? Then handle the more rational DTRules EDD files + writeable = access.toLowerCase().indexOf("w")>=0; + readable = access.toLowerCase().indexOf("r")>=0; + if(!writeable && !readable){ + errorMsgs +="\nThe attribute "+attribute+" has to be either readable or writable\r\n"; + succeeded=false; + } + } + + // Now the type. An easy thing. + try { + itype = RSession.typeStr2Int(type,entityname,attribute); + } catch (RulesException e1) { + errorMsgs+= e1.getMessage()+"\n"; + succeeded = false; + } + + // Now deal with the default specified. + if (defaultv==null){ // Do we need to handle TIERS EDD files? + defaultv = (String) attribs.get("cdd_default_value"); + } + + defaultO = EntityFactory.computeDefaultValue(ef, ef.ruleset, defaultv, itype) ; + + RName entityRName = RName.getRName(entityname.trim(),false); + RName attributeRName = RName.getRName(attribute.trim(),false); + REntity entity = ef.findcreateRefEntity(false,entityRName); + int intType = -1; + try { + intType = RSession.typeStr2Int(type,entityname,attribute); + } catch (RulesException e) { + errorMsgs += "Bad Type: '"+type+"' encountered on entity: '"+entityname+"' attribute: '"+attribute+"' \n"; + succeeded = false; + } + String errstr = entity.addAttribute(attributeRName, + defaultv, + defaultO, + writeable, + readable, + intType, + subtype); + if(errstr!=null){ + succeeded = false; + errorMsgs += errstr; + } + } + //else if(tag.equals("obj")){ + // String javaclass = (String)attribs.get("class"); + // Class javaobj = getClass().getClassLoader().loadClass(javaclass); + //new REntityWrapper(ef,javaobj,false,RName.getRName(body)); + //} + + } + + public boolean error(String v) throws Exception { + return true; + } + +} diff --git a/DTRules/src/main/java/com/dtrules/session/EntityFactory.java b/DTRules/src/main/java/com/dtrules/session/EntityFactory.java new file mode 100644 index 0000000..deb11e8 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/EntityFactory.java @@ -0,0 +1,322 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.session; + +import java.io.InputStream; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; + +import com.dtrules.decisiontables.DTLoader; +import com.dtrules.decisiontables.RDecisionTable; +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.entity.REntityEntry; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RBoolean; +import com.dtrules.interpreter.RDouble; +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RNull; +import com.dtrules.interpreter.RString; +import com.dtrules.interpreter.RTable; +import com.dtrules.interpreter.RTime; +import com.dtrules.xmlparser.GenericXMLParser; + +@SuppressWarnings({"unchecked"}) +public class EntityFactory { + + String create_stamp; + int uniqueID = 10; // Leave room for some fixed IDs. Primitives have an ID = 1, decisiontables have an ID=2; + boolean frozen = false; + RuleSet ruleset; + HashMap javaObjectEntityMap = new HashMap(); + HashMap entityJavaObjectMap = new HashMap(); + HashMap referenceEntities = new HashMap(); + + ArrayList decisiontablelist = new ArrayList(); + + IREntity decisiontables = new REntity(2,true,RName.getRName("decisiontables")); + + /** + * Provides a HashMap that provides a mapping of Java Objects (as a key) + * to Rules Entity objects. + * @return + */ + public HashMap getJavaObjectEntityMap(){ + return javaObjectEntityMap; + } + + /** + * Provides a HashMap that provides a mapping of Rules Entities (as a key) + * to Java Objects. + * @return + */ + public HashMap getEntityJavaObjectMap(){ + return entityJavaObjectMap; + } + + /** + * Map the given Java Object and Entity to each other + */ + public void map(Object obj, IREntity entity){ + javaObjectEntityMap.put(obj, entity); + entityJavaObjectMap.put(entity,obj); + } + + /** + * Creates and returns a new Decision Table object. + * @param name -- The name of the new decision table. + * @return -- The new decision table + */ + public RDecisionTable newDecisionTable(String name, IRSession session)throws RulesException{ + RName rname = RName.getRName(name); + return newDecisionTable(rname, session); + } + + /** + * Creates and returns a new Decision Table object. + * @param name -- The name of the new decision table. + * @return -- The new decision table + */ + public RDecisionTable newDecisionTable(RName name, IRSession session)throws RulesException{ + IRObject table = decisiontables.get(name); + if(table !=null && table.type() != IRObject.iDecisiontable){ + throw new RulesException("ParsingError","New Decision Table","For some reason, "+name.stringValue()+" isn't a decision table"); + } + if(table != null){ + session.getState().debug("Overwritting the Decision Table: "+name.stringValue()); + } + RDecisionTable dtTable = new RDecisionTable(session,ruleset,name.stringValue()); + decisiontablelist.add(name); + decisiontables.addAttribute(name, "", dtTable, false, true, IRObject.iDecisiontable,null); + decisiontables.put(name, dtTable); + return dtTable; + } + /** + * Delete Decision Table doesn't really delete the decision table, but removes it + * from the structures in the entityfactory. + */ + public void deleteDecisionTable(RName name)throws RulesException { + IRObject table = getDecisionTable(name); + if(table==null)return; + decisiontables.removeAttribute(name); + decisiontablelist.remove(name); + } + /** + * Returns an Iterator which provides each Entity name. + * @return + */ + public Iterator getEntityRNameIterator (){ + return referenceEntities.keySet().iterator(); + } + /** + * Provides an Iterator that provides each decision table name. + * @return + */ + public Iterator getDecisionTableRNameIterator () { + return decisiontablelist.iterator(); + } + + /** + * Look up a Decision Table in the decision tables held in this Rule Set. + * @param name + * @return + * @throws RulesException + */ + public RDecisionTable getDecisionTable(RName name)throws RulesException{ + IRObject dt = decisiontables.get(name); + if(dt==null || dt.type()!=IRObject.iDecisiontable){ + return null; + } + return (RDecisionTable) dt; + } + + public EntityFactory(RuleSet rs) { + ruleset = rs; + ((REntity)decisiontables).removeAttribute(RName.getRName("decisiontables")); + } + + + public RDecisionTable findTable(RName tablename){ + return (RDecisionTable) decisiontables.get(tablename); + } + + /** + * Looks up the reference Entity given by name. Returns + * a null if it isn't defined. + * @param name + * @return + */ + public REntity findRefEntity(RName name){ + return (REntity) referenceEntities.get(name); + } + /** + * Looks up the reference Entity given by name. Creates a new + * reference entity if it doesn't yet exist. Otherwise it returns + * the existing reference entity. + * + * @param name + */ + public REntity findcreateRefEntity(boolean readonly, RName name)throws RulesException { + if(!referenceEntities.containsKey(name)){ + IREntity entity = new REntity(getUniqueID(), readonly, name); + referenceEntities.put(name,entity); + } + return (REntity) referenceEntities.get(name); + } + + public void loadedd(String filename, InputStream edd) throws RulesException { + EDDLoader loader = new EDDLoader(filename, this); + try { + GenericXMLParser.load(edd,loader); + if(loader.succeeded==false){ + throw new RulesException("Parsing Error(s)","EDD Loader",loader.errorMsgs); + } + } catch(Exception e){ + throw new RulesException("Parsing Error","EDD Loader",e.toString()); + } + } + + /** + * Looks up the given Decision Table in the list of tables and returns + * it. + * @param dt + * @return + */ + public RDecisionTable findDecisionTable(RName dt){ + IRObject dttable = decisiontables.get(dt); + if(dttable==null || dttable.type()!=IRObject.iDecisiontable){ + return null; + } + return (RDecisionTable) dttable; + } + /** + * Loads a set of decision tables from the given input stream. + * @param dt Source of Decision Tables in XML. + * @throws RulesException + */ + public void loaddt(IRSession session, InputStream dt) throws RulesException { + DTLoader loader = new DTLoader(session, this); + try { + GenericXMLParser.load(dt, loader); + }catch (Exception e) { + throw new RulesException("Parsing Error","Decision Table Loader",e.toString()); + } + } + + @Override + public String toString() { + Iterator ikeys = referenceEntities.keySet().iterator(); + StringBuffer buff = new StringBuffer(); + while(ikeys.hasNext()){ + IREntity e = referenceEntities.get(ikeys.next()); + buff.append(e.getName().toString()); + buff.append("\r\n"); + Iterator iattribs = e.getAttributeIterator(); + while(iattribs.hasNext()){ + RName entryname = (RName)iattribs.next(); + REntityEntry entry = e.getEntry(entryname); + buff.append(" "); + buff.append(entryname); + if(entry.defaultvalue!=null){ + buff.append(" -- default value: "); + buff.append(entry.defaultvalue.toString()); + } + buff.append("\r\n"); + } + } + return buff.toString(); + } + public static IRObject computeDefaultValue(EntityFactory ef, RuleSet ruleset, String defaultstr, int type) throws RulesException { + + if(defaultstr==null ) defaultstr=""; + defaultstr = defaultstr.trim(); + if(defaultstr.equalsIgnoreCase("null")) defaultstr=""; + + switch(type){ + case IRObject.iArray : + if(defaultstr.length()==0) return new RArray(ef.getUniqueID(), true,false); + RArray v = (RArray) RString.compile(ruleset, defaultstr, false); // We assume any values are + // surrounded by brackets, and regardless make + RArray rval = v.get(0).getNonExecutable().rArrayValue(); // sure they are non-executable. + return rval; + case IRObject.iString : + if(defaultstr.length()==0)return RNull.getRNull(); + return RString.newRString(defaultstr); + case IRObject.iName : + if(defaultstr.length()==0)return RNull.getRNull(); + return RName.getRName(defaultstr.trim(),false); + case IRObject.iBoolean : { + if(defaultstr.length()==0)return RNull.getRNull(); + return RBoolean.getRBoolean(defaultstr); + } + case IRObject.iDouble : { + if(defaultstr.length()==0)return RNull.getRNull(); + double value = Double.parseDouble(defaultstr); + return RDouble.getRDoubleValue(value); + } + case IRObject.iInteger : { + if(defaultstr.length()==0)return RNull.getRNull(); + long value = Long.parseLong(defaultstr); + return RInteger.getRIntegerValue(value); + } + case IRObject.iTime : { + if(defaultstr.length()==0) return RNull.getRNull(); + SimpleDateFormat fmt = new SimpleDateFormat("MM/dd/yyyy"); + try { + Date date = fmt.parse(defaultstr); + return RTime.getRTime(date); + } catch (ParseException e) { + throw new RulesException("Invalid Date Format","EntityFactory.computeDefaultValue","Only support dates in 'MM/dd/yyyy' form."); + } + } + case IRObject.iTable : { + if(defaultstr.length()==0) return RNull.getRNull(); + RTable table = RTable.newRTable(ef, null, defaultstr, -1); + table.setValues(ruleset, defaultstr); + return table; + } + default: return RNull.getRNull(); + } + } + /** + * EntityFactories create things that need IDs. The EntityFactory + * has to be created prior to any sessions that are going to + * execute against the entityfactory. + * @return uniqueID (a long) + */ + public int getUniqueID() throws RulesException{ + if(frozen)throw new RulesException("No UniqueID","EntityFactory.getUniqueID()","Once a session has been created, you can't modify the EntityFactory"); + return uniqueID++; + + } + + /** + * @return the decisiontables + */ + public IREntity getDecisiontables() { + return decisiontables; + } +} diff --git a/DTRules/src/main/java/com/dtrules/session/ICompiler.java b/DTRules/src/main/java/com/dtrules/session/ICompiler.java new file mode 100644 index 0000000..3fc1943 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/ICompiler.java @@ -0,0 +1,90 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.session; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; + +import com.dtrules.infrastructure.RulesException; + +@SuppressWarnings({"unchecked"}) +public interface ICompiler { + + /** + * Return the list of unreferenced attributes so far in the use + * of this compiler. + * @return + */ + public ArrayList getUnReferenced(); + /** + * Return the list of possible referenced attributes so far in the + * use of this compiler. + * @return + */ + public ArrayList getPossibleReferenced(); + /** + * Last set of tokens parsed prior to the error. + * @return + */ + public ArrayList getParsedTokens(); + + /** + * Returns the last Prefix (Lisp style) string representation of the AST + * tree generated by this compiler instance. + * @return + */ + public abstract String getLastPreFixExp(); + + /** + * Compiles a single Action. Returns the postfix string needed by the Rules Engine. + * @param action The String in "Formal" to be compiled. + * @return The postfix string representing the action. + * @throws Exception Throws an exception if the compile fails for any reason. + */ + public abstract String compileAction(String action) throws Exception; + + /** + * Compiles a Context Wrapper Returns the postfix string needed by the Rules Engine. + * @param context The String in "Formal" to be compiled. + * @return The postfix string representing the action. + * @throws Exception Throws an exception if the compile fails for any reason. + */ + public abstract String compileContext(String context) throws Exception; + + /** + * Compiles a single Condition. Returns the postfix string needed by the Rules Engine. + * @param condition The String in "Formal" to be compiled. + * @return The postfix string representing the condition + * @throws Exception Throws an exception if the compile fails for any reason. + */ + public abstract String compileCondition(String condition) throws Exception; + + /** + * Returns the types HashMap. + * @return + */ + public abstract HashMap getTypes(); + + /** + * Prints all of the types known by the compiler. + * @throws RulesException + */ + public void printTypes(PrintStream out) throws RulesException; + +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/session/ICompilerError.java b/DTRules/src/main/java/com/dtrules/session/ICompilerError.java new file mode 100644 index 0000000..b445e1c --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/ICompilerError.java @@ -0,0 +1,90 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.session; + +/** + * ICompilerError defines a linked list of errors generated when compiling + * a decision table. The error types are: + *

+ * 1 -- Condition
+ * 2 -- Action
+ * 3 -- Table
+ * 4 -- InitialAction
+ * 5 -- Context
+ *

+ * @author paul snow + * Feb 20, 2007 + * + */ +public interface ICompilerError { + + enum Type { CONDITION, ACTION, TABLE, INITIALACTION, CONTEXT}; + + /** + * Returns the Error type, which will be a 1 if the error was in the + * compilation of a Condition, a 2 if the error was in the compliation + * of an Action, or a 3 if it was in building the Table. + * @return ErrorTypeNumber + */ + Type getErrorType(); + /** + * Returns the text provided the compiler which generated the error. If + * the error type is a 3, this function returns null. + * @return Source code of error + */ + String getSource(); + /** + * Returns an error message explaining the error. + * @return message explaining the error + */ + String getMessage(); + /** + * Returns the index (1 based) of the condition that triggered the error. + * Returns a value > 0 if compling a condition caused the error, and a + * zero otherwise. Error types 2 and 3 will always return zero. + * @return index of condition + */ + int getConditionIndex(); + /** + * Returns the index (1 based) of the action that triggered the error. + * Returns a value > 0 if compling an action caused the error, and a zero + * otherwise. Error types 1 and 3 will always return zero. + * @return index of action + */ + int getActionIndex(); + /** + * Really, we should toss the getConditionIndex and getActionIndex in + * favor of a getIndex which returns a 1 or greater for valid indexes, + * and a zero otherwise. Use the errorType to decide if this is an + * index into InitialActions, Conditions, or Actions. + */ + int getIndex(); + /** + * If the error was due to an unbalanced decision table, this funciton + * returns the row in the condition table where the error was detected. + * @return row index of error + */ + int getRow(); + /** + * If the error was due to an unbalanced decision table, this funciton + * returns the column in the condition table where the error was detected. + * @return column index of error + */ + int getCol(); + +} diff --git a/DTRules/src/main/java/com/dtrules/session/IRSession.java b/DTRules/src/main/java/com/dtrules/session/IRSession.java new file mode 100644 index 0000000..729a18a --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/IRSession.java @@ -0,0 +1,100 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.session; + +import java.io.PrintStream; +import java.rmi.RemoteException; + +import javax.rules.InvalidRuleSessionException; +import javax.rules.RuleExecutionSetMetadata; + +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.mapping.Mapping; +import com.dtrules.xmlparser.IXMLPrinter; + +public interface IRSession { + + /** + * Returns the RulesDirectory used to create this session. + * @return RulesDirectory + */ + public abstract RulesDirectory getRulesDirectory(); + /** + * Returns the RuleSet associated with this Session. + * @return + */ + public abstract RuleSet getRuleSet(); + + /** + * Creates a new uniqueID. This ID is unique within the RSession, but + * not across all RSessions. Unique IDs are used to relate references + * between objects when writing out trace files, or to reconstruct a RSession + * when reading in a trace file. + * + * @return A unique integer. + */ + public abstract int getUniqueID(); + + public abstract RuleExecutionSetMetadata getRuleExecutionSetMetadata(); + + public abstract void release() throws RemoteException, + InvalidRuleSessionException; + + public abstract int getType() throws RemoteException, + InvalidRuleSessionException; + + public abstract void execute(String s) throws RulesException; + + /** + * Returns the Rules Engine State for this Session. + * @return + */ + public abstract DTState getState(); + + public abstract EntityFactory getEntityFactory() ; + + /** + * Debugging aid that allows you to dump an Entity and its attributes. + * @param e + */ + public void dump(REntity e) throws RulesException; + + public void printEntity(IXMLPrinter rpt, String tag, IREntity e) throws Exception ; + + public void printEntityReport(IXMLPrinter rpt, DTState state, String iRObjname ); + + public void printEntityReport(IXMLPrinter rpt, boolean verbose, DTState state, String iRObjname ); + + public void printBalancedTables(PrintStream out)throws RulesException; + + /** + * Get the default mapping + * @return + */ + public Mapping getMapping (); + + /** + * Get a named mapping file + * @param filename + * @return + */ + public Mapping getMapping (String filename); +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/session/RSession.java b/DTRules/src/main/java/com/dtrules/session/RSession.java new file mode 100644 index 0000000..a869846 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/RSession.java @@ -0,0 +1,449 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.session; + + +import java.io.PrintStream; +import java.rmi.RemoteException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; + +import javax.rules.InvalidRuleSessionException; +import javax.rules.RuleExecutionSetMetadata; +import javax.rules.RuleSession; + +import com.dtrules.decisiontables.RDecisionTable; +import com.dtrules.entity.IREntity; +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RArray; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RString; +import com.dtrules.interpreter.operators.ROperator; +import com.dtrules.xmlparser.IXMLPrinter; +import com.dtrules.mapping.Mapping; + +@SuppressWarnings("unchecked") +public class RSession implements RuleSession, IRSession { + + final RuleSet rs; + final DTState dtstate; + final EntityFactory ef; + int uniqueID = 1; + HashMap entityInstances = new HashMap(); + ICompiler compiler = null; + + /** + * Get the default mapping + * @return + */ + public Mapping getMapping () { + return rs.getMapping(this); + } + + /** + * Get a named mapping file + * @param filename + * @return + */ + public Mapping getMapping (String filename){ + return rs.getMapping(filename, this); + } + + /** + * Gets the Rules Directory used to create this session + * @return The Rules Directory used to create this session + */ + public RulesDirectory getRulesDirectory() { + return rs.getRulesDirectory(); + } + /** + * If the session is provided a compiler object, then it can compile + * the Formal syntax into posfix using this compiler. A Compiler is + * really specific to the RuleSet. However, in the future we may + * wish that a compiler be specific to the decision table. + * + * @param _compiler + */ + public void setCompiler(ICompiler _compiler){ + compiler = _compiler; + } + + /** + * Each RSession is associated with a particular RuleSet + * @param _ef + * @throws RulesException + */ + public RSession(RuleSet _rs) throws RulesException { + rs = _rs; + dtstate = new DTState(this); + ef = _rs.getEntityFactory(this); + if(ef.getUniqueID()<100000){ + uniqueID = 100000; + }else{ + uniqueID = ef.getUniqueID()+100000; + } + /** + * Add all the reference entities to the session list + * of entities. + */ + Iterator ie = ef.referenceEntities.keySet().iterator(); + while(ie.hasNext()){ + IREntity e = ef.findRefEntity(ie.next()); + String id = e.getID()+""; + if(entityInstances.containsKey(id)){ + throw new RulesException("duplicate","new RSession()","Duplicate id "+id+" found between:\n" + +e.getName()+" and "+entityInstances.get(id).getName()); + } + entityInstances.put(id,e); + } + try { + dtstate.entitypush(ROperator.getPrimitives()); + dtstate.entitypush(ef.decisiontables); + } catch (RulesException e) { + throw new RulesException("Initialization Error", + "RSession", + "Failed to initialize dtstate in init()"); + } + } + + /** + * Does a recursive dump of the given entity to standard out. + * This is a debugging thing. If DEBUG isn't set in the State of the Session, + * calling this routine does nothing at all. + * @param e + */ + public void dump(REntity e) throws RulesException { + + if(!dtstate.testState(DTState.DEBUG))return; // Leave if nothing to do. + dtstate.traceTagBegin("entity", "name='"+e.getName().stringValue()+"' id='"+e.getID()+"'"); + dump(e,1); + dtstate.traceTagEnd("entity", null); + } + + private HashMap boundries = new HashMap(); // Track printing Entity from Entity boundries to stop recursive printing. + + private String getType(REntity e, RName n) throws RulesException{ + int type = e.getEntry(n).type; + return RSession.typeInt2Str(type); + } + + /** + * Dumps the Entity and its attributes to the debug output source. However, + * if debug isn't enabled, the routine does absolutely nothing. + * @param e The Entity to be dumped. + * @param depth Dumping is a private, recursive thing. depth helps us track its recursive nature. + */ + private void dump(REntity e,int depth){ + Iterator anames = e.getAttributeIterator(); + while(anames.hasNext()){ + try { + RName aname = anames.next(); + IRObject value = e.get(aname); + + dtstate.traceTagBegin("attribute", "name='"+aname.stringValue()+"' type='"+getType(e,aname)+"'"); + switch(e.getEntry(aname).type){ + case IRObject.iEntity: { + if(value.type()==IRObject.iNull){ + dtstate.traceInfo("value","type ='null' value='null'"); + break; + } + dtstate.traceTagBegin("entity", + "name='"+((REntity)value).getName().stringValue()+ + "' id='"+((REntity)value).getID()+"'"); + + if(!(boundries.get(e)!= null && boundries.get(e).contains(value))){ + dtstate.debug(" recurse\n"); + }else{ + if(boundries.get(e)==null)boundries.put(e, new ArrayList()); + boundries.get(e).add(value); + dump((REntity)value, depth+1); + } + dtstate.traceTagEnd("entity", null); + break; + } + case IRObject.iArray: { + ArrayList values = value.arrayValue(); + Iterator iv = values.iterator(); + while(iv.hasNext()){ + IRObject v = (IRObject) iv.next(); + if(v.type()==IRObject.iEntity){ + dump((REntity)v,depth+2); + }else{ + dtstate.traceInfo("value","v='"+v.stringValue()+"'"); + } + } + break; + } + default : { + dtstate.traceInfo("value","v='"+value.stringValue()+"'"); + } + } + dtstate.traceTagEnd("attribute",null); + } catch (RulesException e1) { + dtstate.debug("Rules Engine Exception\n"); + e1.printStackTrace(dtstate.getErrorOut()); + } + } + } + + + /** + * Return an ID that is unique for this session. The ID is generated using a simple + * counter. This ID will not be unique across all sessions, nor is it very likely to + * be unique when compared to IDs generated with by methods. + *

+ * Unique IDs are used to distinguish various instances of entities apart during + * exectuion and/or during the generation or loading of a Trace file. They can be + * used for other purposes as well, under the assumption that the number of unique IDs + * are less than or equal to 0x7FFFFFFF hex or 2147483647 decimal. + * + * @return a Unique ID generated by a simple counter. + */ + public int getUniqueID(){ + return uniqueID++; + } + + /* (non-Javadoc) + * @see com.dtrules.session.IRSession#getRuleExecutionSetMetadata() + */ + public RuleExecutionSetMetadata getRuleExecutionSetMetadata(){ + return null; + } + + /* (non-Javadoc) + * @see com.dtrules.session.IRSession#release() + */ + public void release() throws RemoteException, InvalidRuleSessionException { + } + + /* (non-Javadoc) + * @see com.dtrules.session.IRSession#getType() + */ + public int getType() throws RemoteException, InvalidRuleSessionException { + return 1; + } + + /** + * Compiles the given string into an executable array, per the Rules Engine's interpreter. + * Assuming this compile completes, the given array is executed. A RulesException can be + * thrown either by the compile of the string, or the execution of the resulting array. + * @param s String to be compiled. + * @exception RulesException thrown if any problem occurs compiling or executing the string. + * @see com.dtrules.session.IRSession#execute(java.lang.String) + */ + public void execute(String s) throws RulesException { + RString.newRString(s,true).execute(dtstate); + return; + } + /** + * Converts the string representation of a type into an index. + * @param type + * @return + * @throws RulesException + */ + static public int typeStr2Int(String type, String entity, String attribute)throws RulesException{ + type = type.trim(); + if(type.equalsIgnoreCase("list"))type = IRObject.rArray; + if(type.equalsIgnoreCase("date"))type = IRObject.rTime; + if(type.equalsIgnoreCase("double"))type = IRObject.rFloat; + for(int i=0;i IRObject.types.length){ + throw new RulesException("Undefined","typeInt2Str","Bad Type Index Encountered: "+type); + } + return IRObject.types[type]; + } + + /** + * Returns the state object for this Session. The state is used by the Rules Engine in + * the interpretation of the decision tables. + * @return DTState The object holds the Data Stack, Entity Stack, and other state of the Rules Engine. + */ + public DTState getState(){return dtstate; } + + /** + * @return the ef + */ + public EntityFactory getEntityFactory() { + return ef; + } + /** + * Create an Instance of an Entity of the given name. + * @param name The name of the Entity to create + * @return The entity created. + * @throws RulesException Thrown if any problem occurs (such as an undefined Entity name) + */ + public IREntity createEntity(Object id, String name) throws RulesException{ + RName entity = RName.getRName(name); + return createEntity(id, entity); + } + + /** + * Create an Instance of an Entity of the given name. + * @param name The name of the Entity to create + * @return The entity created. + * @throws RulesException Thrown if any problem occurs (such as an undefined Entity name) + */ + public IREntity createEntity(Object id, RName name) throws RulesException{ + if(id==null){ + id = getUniqueID()+""; + } + REntity ref = ef.findRefEntity(name); + if(ref==null){ + throw new RulesException("undefined","session.createEntity","An attempt ws made to create the entity "+name.stringValue()+"\n" + + "This entity isn't defined in the EDD"); + } + if(!ref.isReadOnly()){ + REntity e = (REntity) ref.clone(this); + entityInstances.put(e.getID(),e); + return e; + } + return ref; + } + + + /** + * @return the rs + */ + public RuleSet getRuleSet() { + return rs; + } + + + public void printEntity(IXMLPrinter rpt, String tag, IREntity e) throws Exception { + if(tag==null)tag = e.getName().stringValue(); + IRObject id = e.get(RName.getRName("mapping*key")); + String idString = id!=null?id.stringValue():"--none--"; + rpt.opentag(tag,"DTRulesId",e.getID()+"","id",idString); + Iterator names = e.getAttributeIterator(); + while(names.hasNext()){ + RName name = names.next(); + IRObject v = e.get(name); + if(v.type()==IRObject.iArray && v.rArrayValue().size()==0) continue; + String vstr = v==null?"":v.stringValue(); + rpt.printdata("attribute","name",name.stringValue(), vstr); + } + } + + + public void printArray(IXMLPrinter rpt, ArrayList entitypath, ArrayList printed, DTState state, String name, RArray rarray)throws RulesException{ + if(name!=null && name.length()>0){ + rpt.opentag("array","name",name, "id", rarray.getID()); + }else{ + rpt.opentag("array"); + } + for(IRObject element : rarray){ + printIRObject(rpt, entitypath, printed, state,"",element); + } + rpt.closetag(); + } + + public void printEntityReport(IXMLPrinter rpt, DTState state, String objname ) { + printEntityReport(rpt,false,state,objname); + } + + public void printEntityReport(IXMLPrinter rpt, boolean verbose, DTState state, String name ) { + ArrayList entitypath = new ArrayList(); + ArrayList printed = null; + if (!verbose) printed = new ArrayList(); + try { + IRObject obj = state.find(name); + if(obj==null){ + rpt.printdata("unknown", "object", name,null); + }else{ + printIRObject(rpt,entitypath, printed,state,name,obj); + } + } catch (RulesException e) { + rpt.print_error(e.toString()); + } + } + + public void printIRObject(IXMLPrinter rpt, ArrayList entitypath, ArrayList printed, DTState state, String name, IRObject v) throws RulesException { + switch(v.type()){ + case IRObject.iEntity : + if(name.length()!=0)rpt.opentag(name); + printAllEntities(rpt, entitypath, printed, state, v.rEntityValue()); + if(name.length()!=0)rpt.closetag(); + break; + case IRObject.iArray : + if(name.length()!=0)rpt.opentag(name); + printArray(rpt, entitypath, printed, state, name, v.rArrayValue()); + if(name.length()!=0)rpt.closetag(); + break; + default: + String vstr = v==null?"":v.stringValue(); + rpt.printdata("attribute","name",name, vstr); + } + } + + public void printAllEntities(IXMLPrinter rpt, ArrayList entitypath, ArrayList printed, DTState state, IREntity e) throws RulesException { + String entityName = e.getName().stringValue(); + if(entitypath.contains(e) && entitypath.get(entitypath.size()-1)==e){ + rpt.printdata("entity","name",entityName, "self reference"); + }else if (printed!= null && printed.contains(e)){ + rpt.printdata("entity","name",entityName,"DTRulesId",e.getID(),"id",e.get("mapping*key").stringValue(),"multiple reference"); + }else{ + entitypath.add(e); + if(printed!=null) printed.add(e); + IRObject id = e.get(RName.getRName("mapping*key")); + String idString = id!=null?id.stringValue():"--none--"; + rpt.opentag("entity","name",entityName,"DTRulesId",e.getID()+"","id",idString); + Iterator names = e.getAttributeIterator(); + while(names.hasNext()){ + RName name = names.next(); + IRObject v = e.get(name); + printIRObject(rpt, entitypath, printed, state, name.stringValue(), v); + } + rpt.closetag(); + entitypath.remove(entitypath.size()-1); + } + } + /** + * Prints all the balanced form of all the decision tables in this session to + * the given output stream + * @throws RulesException + */ + public void printBalancedTables(PrintStream out)throws RulesException { + Iterator dts = this.getEntityFactory().getDecisionTableRNameIterator(); + while(dts.hasNext()){ + RName dtname = dts.next(); + RDecisionTable dt = this.getEntityFactory().findDecisionTable(dtname); + String t = dt.getBalancedTable().getPrintableTable(); + + out.println(); + out.println(dtname.stringValue()); + out.println(); + out.println(t); + } + } + +} diff --git a/DTRules/src/main/java/com/dtrules/session/RuleSet.java b/DTRules/src/main/java/com/dtrules/session/RuleSet.java new file mode 100644 index 0000000..9c24c9b --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/RuleSet.java @@ -0,0 +1,387 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.session; + +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; +import java.util.HashMap; +import com.dtrules.mapping.Mapping; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.RName; +/** + * Defines the set of artifacts which make up a logical set of + * rules. These include the schema for the rules (The Entity + * Description Dictionary or EDD) as well as the entityfactory + * created from the EDD. A Rule Set also includes the decision + * tables, and a set of mappings to map XML data into the + * Schema defined by the EDD. + *

+ * This implementation is really just a place holder. We need + * to explore how to define sets of Rules, their schemas, their + * decision tables and the entry points into these tables, the + * connections between rules and databases, and rules and + * perhaps several UI implementations. This is a much more + * complex problem than it first appears. + * + * @author paul snow + * Jan 17, 2007 + * + */ +public class RuleSet { + protected RName name; + protected boolean resource = false; + protected ArrayList edd_names = new ArrayList(); + protected ArrayList dt_names = new ArrayList(); + protected ArrayList map_paths = new ArrayList(); + protected String excel_edd = null; + protected String excel_dtfolder = null; + + protected HashMap mappings = new HashMap(); + protected EntityFactory ef = null; + protected RulesDirectory rd; + protected String firstDecisionTableName; + + protected String resourcepath =null; + protected String filepath =null; + protected String workingdirectory =null; + + /** + * Get the default mapping (the first mapping file) + * @param session + * @return + */ + public Mapping getMapping(IRSession session){ + String filename = map_paths.get(0); + return getMapping(filename,session); + } + + /** + * get Mapping. + * We create an instance that has a reference to this + * session, but is otherwise identical to the reference + * mapping. + */ + public synchronized Mapping getMapping(String filename,IRSession session){ + Mapping map = mappings.get(filename); + if(map != null)return map.clone(session); + if(map_paths.indexOf(filename)<0){ + throw new RuntimeException("Bad Mapping File: "+filename+" For the rule set: "+name.stringValue()); + } + map = Mapping.newMapping(rd, session, filename); + mappings.put(filename, map); + return map.clone(session); + } + + /** + * Tries openning the filename as it is. Then attempts to open + * the file with the resource path. Then the file path. If everything + * fails, returns a null. + * @param filename + * @return InputStream + */ + public InputStream openfile(String filename){ + InputStream s = null; + s = RulesDirectory.openstream(this,filename); + if(s!=null)return s; + s = RulesDirectory.openstream(this,getFilepath()+"/"+filename); + if(s!=null)return s; + s = RulesDirectory.openstream(this,getResourcepath()+filename); + return s; + } + + /** + * @return the excel_dtfolder + */ + public String getExcel_dtfolder() { + return excel_dtfolder; + } + + /** + * @param excel_dtfolder the excel_dtfolder to set + */ + public void setExcel_dtfolder(String excel_dtfolder) { + if(excel_dtfolder.startsWith("/") || excel_dtfolder.startsWith("\\")){ + excel_dtfolder = excel_dtfolder.substring(1); + } + this.excel_dtfolder = excel_dtfolder; + } + + /** + * @return the excel_edd + */ + public String getExcel_edd() { + return excel_edd; + } + + /** + * @param excel_edd the excel_edd to set + */ + public void setExcel_edd(String excel_edd) { + if(excel_edd.startsWith("/") || excel_edd.startsWith("\\")){ + excel_edd = excel_edd.substring(1); + } + this.excel_edd = excel_edd; + } + + /** + * Appends the directory specified in the RulesDirectory (if present) to the + * filepath for the Rule Set. + * @return the filepath + */ + public String getFilepath() { + return rd.getFilepath()+"/"+filepath; + } + + /** + * @param filepath the filepath to set + */ + public void setFilepath(String filepath) { + filepath = filepath.trim(); + if( !filepath.endsWith("/") && !filepath.endsWith("\\")){ + filepath = filepath + "/"; + } + //Remove any leading slash. + if(filepath.startsWith("/")||filepath.startsWith("\\")){ + filepath = filepath.substring(1); + } + this.filepath = filepath; + } + + /** + * @return the resourcepath + */ + public String getResourcepath() { + return resourcepath; + } + + /** + * @param resourcepath the resourcepath to set + */ + public void setResourcepath(String resourcepath) { + this.resourcepath = resourcepath; + } + + /** + * @return the workingdirectory + */ + public String getWorkingdirectory() { + return rd.getFilepath()+"/"+workingdirectory; + } + + /** + * @param workingdirectory the workingdirectory to set + */ + public void setWorkingdirectory(String workingdirectory) { + workingdirectory = workingdirectory.trim(); + if( !workingdirectory.endsWith("/") && !workingdirectory.endsWith("\\")){ + workingdirectory = workingdirectory + "/"; + } + //Remove any leading slash. + if(workingdirectory.startsWith("/")||workingdirectory.startsWith("\\")){ + workingdirectory = workingdirectory.substring(1); + } + + this.workingdirectory = workingdirectory; + } + + /** + * Accessor for getting the Rules Directory used to create this Rule Set + * @return + */ + RulesDirectory getRulesDirectory(){ + return rd; + } + + RuleSet(RulesDirectory _rd){ + rd = _rd; + } + /** + * Returns an interator for the paths used to define the + * decision tables. These paths may point to XML files on + * the file system, or to resources within a jar. + * @return + */ + public Iterator DTPathIterator(){ + return dt_names.iterator(); + } + + /** + * Returns an iterator for the paths used to define the + * EDD for this rule set. These paths may point to XML files + * on the file system, or to resources within a jar. + * @return + */ + public Iterator eDDPathIterator(){ + return edd_names.iterator(); + } + + /** + * Creates a new Session set up to execute rules within this + * Rule Set. Note that a RuleSet is stateless, so a Session + * can point to a RuleSet, but a RuleSet can belong to many + * sessions. + * @return + * @throws RulesException + */ + public IRSession newSession () throws RulesException{ + return new RSession(this); + } + + /** + * Get the EntityFactory associated with this ruleset. + * An EntityFactory is stateless, so many sessions can use + * the reference to a single EntityFactory. + * @return + * @throws RulesException + */ + public EntityFactory getEntityFactory(IRSession session) throws RulesException{ + if(ef==null){ + ef = new EntityFactory(this); + Iterator iedds = edd_names.iterator(); + while(iedds.hasNext()){ + String filename = iedds.next(); + String filenameused = ""; + InputStream s= openfile(filename); + if(s==null){ + if(s==null){ + System.out.println("No EDD XML found"); + } + } + if(s!=null) ef.loadedd(filenameused,s); + } + Iterator idts = dt_names.iterator(); + while(idts.hasNext()){ + String filename = idts.next(); + InputStream s = openfile(filename); + if(s==null){ + if(s==null){ + System.out.println("No Decision Table XML found"); + } + } + if(s!=null) ef.loaddt(session, s); + } + + } + return ef; + } + + /** + * Returns the path to load the mapping file. Ultimately, we + * should support multiple mappings into the same EDD. + * @return the map_path + */ + public ArrayList getMapPath() { + return map_paths; + } + + /** + * Sets the path to the mapping file. + * @param map_path the map_path to set + */ + public void setMapPath(ArrayList map_path) { + this.map_paths = map_path; + } + /** + * @return the name + */ + public String getName() { + return name.stringValue(); + } + + /** + * Get the name as a RName + */ + public RName getRName(){ + return name; + } + + /** + * @param name the name to set + */ + public void setName(String name) { + this.name = RName.getRName(name); + } + /** + * @return the dt_paths + */ + public ArrayList getDt_paths() { + return dt_names; + } + /** + * @param dt_paths the dt_paths to set + */ + public void setDt_paths(ArrayList dt_paths) { + this.dt_names = dt_paths; + } + + /** + * Returns the single DecisionTable XML. If there are more, or none, an + * error is thrown. + * @return filename + * @throws RulesException + */ + public String getDT_XMLName() throws RulesException{ + if(dt_names.size()!=1){ + throw new RulesException("UnsupportedConfiguration","RuleSet","We can only have one DecisionTable XML file"); + } + return dt_names.get(0); + } + /** + * Returns the single EDD XML. If there are more, or none, an error is + * thrown. + * @return filename + * @throws RulesException + */ + public String getEDD_XMLName() throws RulesException{ + if(edd_names.size()!=1){ + throw new RulesException("UnsupportedConfiguration","RuleSet","We can only have one EDD XML file"); + } + return edd_names.get(0); + } + /** + * @return the edd_paths + */ + public ArrayList getEdd_paths() { + return edd_names; + } + /** + * @param edd_paths the edd_paths to set + */ + public void setEdd_paths(ArrayList edd_paths) { + this.edd_names = edd_paths; + } + /** + * @return the firstDecisionTableName + */ + public String getFirstDecisionTableName() { + return firstDecisionTableName; + } + /** + * @param firstDecisionTableName the firstDecisionTableName to set + */ + public void setFirstDecisionTableName(String firstDecisionTableName) { + this.firstDecisionTableName = firstDecisionTableName; + } + + public String getSystemPath () { + return rd.getSystemPath(); + } + +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/session/RulesDirectory.java b/DTRules/src/main/java/com/dtrules/session/RulesDirectory.java new file mode 100644 index 0000000..3ee92a9 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/session/RulesDirectory.java @@ -0,0 +1,242 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.session; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; +import java.util.HashMap; + +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.RName; +import com.dtrules.xmlparser.GenericXMLParser; +import com.dtrules.xmlparser.IGenericXMLParser; + +@SuppressWarnings({"unchecked"}) +public class RulesDirectory { + + boolean loaded; + HashMap rulesets; + String systemPath=""; // Path to the directory on the File System + // where files can be read and written. If + // present, it is appended to paths used by + // rule sets. + + public void addRuleSet(RuleSet ruleset) throws RulesException { + + } + + /** + * Returns the ruleset associated with the given name. The conversion + * of the String to an RName is done by this routine. + * All hash tables in DTRules should use RNames as keys. + * + * Returns true if the RulesDirectory has been successfully loaded. + * @return + */ + public boolean isLoaded(){return loaded;} + + public RuleSet getRuleSet(String setname){ + return getRuleSet(RName.getRName(setname)); + } + + /** + * Returns the ruleset associated with the given name. Note that the + * key is an RName. All hash tables in DTRules should use RNames as keys. + * + * @param setname + * @return + */ + public RuleSet getRuleSet(RName setname){ + return (RuleSet) rulesets.get(setname); + } + + + /** + * We attempt to open the streamname as a resource in our jar. + * Then failing that, we attempt to open it as a URL. + * Then failing that, we attempt to open it as a file. + * + * @param streamname + * @return + */ + public static InputStream openstream(Object object, String streamname){ + // First try and open the stream as a resource + // InputStream s = System.class.getResourceAsStream(streamname); + + InputStream s = object.getClass().getResourceAsStream(streamname); + + if(s!=null)return s; + + // If that fails, try and open it as a URL + try { + URL url = new URL(streamname); + URLConnection urlc = url.openConnection(); + s = urlc.getInputStream(); + if(s!=null)return s; + } catch (MalformedURLException e) { + } catch (Exception e){} + + // If that fails, try and open it as a file. + try { + s = new FileInputStream(streamname); + return s; + } catch (FileNotFoundException e) {} + + // If all these fail, return a null. + return null; + + } + + + String propertyfile; + + /** + * The RulesDirectory manages the various RuleSets and the versions of + * RuleSets. We need to do a good bit of work to make all of this + * managable. For right now, I am loading the property list from the + * path provided this class. It first attempts to use this path as a + * jar resource, then an URL, then a file. + * + * The systemPath is assumed to be the name of a directory, either with + * or without a ending '/' or '\'. + * + * @param propertyfile + */ + public RulesDirectory(String systemPath, String propertyfile) { + if(systemPath.endsWith("/")||systemPath.endsWith("\\")){ + // If it has an ending slash, chop it off. + systemPath = systemPath.substring(0,systemPath.length()-1); + } + if(propertyfile.startsWith("/")||propertyfile.startsWith("\\")){ + // If the propertyfile has a leading slash, chop that off. + propertyfile = propertyfile.substring(1); + } + this.propertyfile = propertyfile; + this.systemPath = systemPath.trim(); + + InputStream s = openstream(this,systemPath +"/"+ propertyfile); + loadRulesDirectory(s); + } + + public RulesDirectory(String systemPath, InputStream s) { + if(systemPath.endsWith("/")||systemPath.endsWith("\\")){ + systemPath = systemPath+"/"; + } + this.systemPath = systemPath.trim(); + propertyfile = s.toString(); + + loadRulesDirectory(s); + } + + public void loadRulesDirectory(InputStream s){ + LoadDirectory parser = new LoadDirectory(this); + + if(s==null){ + throw new RuntimeException("Could not find the file/inputstream :"+propertyfile); + } + try { + GenericXMLParser.load(s,parser); + } catch (Exception e) { + throw new RuntimeException("Error parsing property file/inputstream: "+propertyfile+"\n"+e); + } + loaded = true; + } + + static class LoadDirectory implements IGenericXMLParser { + + final RulesDirectory rd; + LoadDirectory(RulesDirectory _rd){ + rd=_rd; + rd.rulesets = new HashMap(); + } + RuleSet currentset=null; + + public void beginTag(String[] tagstk, int tagstkptr, String tag, HashMap attribs) throws IOException, Exception { + if (tag.equals("RuleSet")){ + currentset = new RuleSet(rd); + currentset.setName((String) attribs.get("name")); + if(currentset.name==null){ + throw new RuntimeException("Missing name in RuleSet"); + } + rd.rulesets.put(currentset.name, currentset); + } + } + + public void endTag(String[] tagstk, int tagstkptr, String tag, String body, HashMap attribs) throws Exception, IOException { + if(tag.equals("RuleSetResourcePath")){ + currentset.setResourcepath(body.trim()); + }else if (tag.equals("RuleSetFilePath")){ + currentset.setFilepath(body.trim()); + }else if (tag.equals("WorkingDirectory")){ + currentset.setWorkingdirectory(body.trim()); + }else if (tag.equals("Entities")){ + currentset.edd_names.add((String) attribs.get("name")); + }else if (tag.equals("Decisiontables")){ + currentset.dt_names.add((String) attribs.get("name")); + }else if (tag.equals("Map")){ + currentset.map_paths.add((String) attribs.get("name")); + }else if (tag.equals("DTExcelFolder")){ + currentset.setExcel_dtfolder(body.trim()); + }else if (tag.equals("EDDExcelFile")){ + currentset.setExcel_edd(body.trim()); + } + } + public boolean error(String v) throws Exception { + return true; + } + + } + + /** + * @return the rulesets + */ + public HashMap getRulesets() { + return rulesets; + } + /** + * @return the filepath + */ + public String getFilepath() { + return systemPath; + } + /** + * @param filepath the filepath to set + */ + public void setFilepath(String filepath) { + this.systemPath = filepath; + } + /** + * @return the systemPath + */ + public String getSystemPath() { + return systemPath; + } + /** + * @param systemPath the systemPath to set + */ + public void setSystemPath(String systemPath) { + this.systemPath = systemPath; + } + +} diff --git a/DTRules/src/main/java/com/dtrules/trace/DecisionTableNode.java b/DTRules/src/main/java/com/dtrules/trace/DecisionTableNode.java new file mode 100644 index 0000000..443b9ef --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/trace/DecisionTableNode.java @@ -0,0 +1,79 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.trace; + +import java.util.ArrayList; + +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; + +public class DecisionTableNode implements TraceNode { + + ArrayList children = new ArrayList(); + TraceNode parent; + TraceNode previous; + + public RName getAttribute() { + return null; + } + /** + * Get first child, and return null if no children. + */ + public TraceNode getFirstChild() { + if(children.size()==0)return null; + return children.get(0); + } + + public RInteger getIndex() { + return null; + } + + public TraceNode getNext() { + // TODO Auto-generated method stub + return null; + } + + public TraceNode getNextChange() { + // TODO Auto-generated method stub + return null; + } + + public TraceNode getParent() { + // TODO Auto-generated method stub + return null; + } + + public TraceNode getPrevious() { + // TODO Auto-generated method stub + return null; + } + + public TraceNode getPreviousChange() { + // TODO Auto-generated method stub + return null; + } + + public void setNewValues() { + // TODO Auto-generated method stub + + } + + public void setOldValues() { + // TODO Auto-generated method stub + + } + +} diff --git a/DTRules/src/main/java/com/dtrules/trace/TraceNode.java b/DTRules/src/main/java/com/dtrules/trace/TraceNode.java new file mode 100644 index 0000000..826ce5d --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/trace/TraceNode.java @@ -0,0 +1,94 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.trace; + +import com.dtrules.interpreter.RInteger; +import com.dtrules.interpreter.RName; + +/** + * A trace node allows two kinds of navigation acorss changes recorded in + * a DTRules Trace file. One mode is a tree, and one mode is linear. In + * fact, all changes occur serially within a decision table thread. Yet all + * changes occur with in a hierarchy of Decision Table execution. + * + * The parent of all nodes is a root node. The initialization node holds the + * initial values (includeing data inserted into a ruleset) + * + * The changes are kept as nodes + */ +public interface TraceNode { + + /** + * These are the hierarchy operators. + */ + + /** getParent() -- return the parent node, usually a decisiontable. But it + * could be the root node, or the initialization node. + * @return + */ + TraceNode getParent(); + /** + * Get the firstChild() + * @return + */ + TraceNode getFirstChild(); + /** + * Get the next(); + * Returns a null if no more children; + * @return + */ + TraceNode getNext(); + /** + * Get the perivious node, + * @return + */ + TraceNode getPrevious(); + + /** + * These are the linear access methods. All the changes are organized + * in a linear list. + */ + /** + * Get the next Change Node + * @return + */ + TraceNode getNextChange(); + /** + * Get the previous Change Node + * @return + */ + TraceNode getPreviousChange(); + + + /** + * Change Operators + */ + void setOldValues(); + void setNewValues(); + /** + * Returns the Name for the Attribute that changed (or a null if + * this isn't a change to an Entity). + */ + RName getAttribute(); + /** + * Returns the index for the Attribute that changed (or a null if + * this isn't a change to an Element of an Array). + */ + RInteger getIndex(); +} diff --git a/DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.flex b/DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.flex new file mode 100644 index 0000000..657458f --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.flex @@ -0,0 +1,311 @@ +package com.dtrules.xmlparser; +import java.util.*; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.regex.Pattern; +@SuppressWarnings({"unchecked","unused"}) +%% +%public +%class GenericXMLParser +%yylexthrow Exception +%unicode +%line +%column +%int + +%{ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + private String sourcename = "unknown name"; + String tagstk [] = new String[1000]; + int tagstkptr = 0; + int statestk [] = new int[1000]; + int statestkptr = 0; + ArrayList attribstk = new ArrayList(); + HashMap attribs = new HashMap(); + boolean printflg = true; + IGenericXMLParser parser = null; + + String body = ""; + String currenttag = ""; + String Source; + + public GenericXMLParser(String filename) throws FileNotFoundException { + this(new FileInputStream(filename)); + sourcename = filename; + } + + void pushTag(String tag){ + tagstk[tagstkptr++] = tag; + currenttag = tag; + attribstk.add(attribs); // We save and restore the attribs hashmap + attribs = new HashMap(); + } + + String popTag(String endtag) { + attribs = (HashMap) attribstk.remove(attribstk.size()-1); + if(endtag.indexOf("=0){ + endtag=endtag.substring(2,endtag.length()-1).trim(); + } + if(tagstkptr<=0){ + System.err.print("Stack Underflow\n"); + } + String tag = tagstk[--tagstkptr]; + if(!tag.equals(endtag)){ + System.err.print("Begin and End tags do not match:\n"+ + "Begin tag: "+tag+"\n"+ + "End tag: "+endtag+"\n"); + } + + if(tagstkptr<=0){ + currenttag = ""; + }else{ + currenttag = tagstk[tagstkptr-1]; + } + + return tag; + } + + public void setSource(String source){ + this.sourcename=source; + } + + public void setParser (IGenericXMLParser p_parser){ + parser = p_parser; + } + + void pushstate(int state) { + statestk[statestkptr++]=yystate(); + yybegin(state); + } + + int popstate (){ + int newstate = statestk[--statestkptr]; + statestk[statestkptr]=0; + yybegin(newstate); + return newstate; + } + + void error(String v)throws Exception{ + if(!parser.error(v)){ + throw new Exception("Unmatched characters, parsing cannot continue at" + where()); + } + } + + static private Pattern xamp = Pattern.compile("&"); + static private Pattern xlt = Pattern.compile("<"); + static private Pattern xgt = Pattern.compile(">"); + static private Pattern xsqu = Pattern.compile("'"); + static private Pattern xdqu = Pattern.compile("""); + + static public String unencode (String s){ + if(s.indexOf("&")>=0){ + s= xlt.matcher(s).replaceAll("<"); + s= xgt.matcher(s).replaceAll(">"); + s= xsqu.matcher(s).replaceAll("'"); + s= xdqu.matcher(s).replaceAll("\""); + s= xamp.matcher(s).replaceAll("&"); + } + return s; + } + static private Pattern tst = Pattern.compile("[&<>'\"]+"); + static private Pattern amp = Pattern.compile("&"); + static private Pattern lt = Pattern.compile("<"); + static private Pattern gt = Pattern.compile(">"); + static private Pattern squ = Pattern.compile("'"); + static private Pattern dqu = Pattern.compile("\""); + + static public String encode (String s) { + if(tst.matcher(s).find()){ + s= amp.matcher(s).replaceAll("&"); + s= lt.matcher(s).replaceAll("<"); + s= gt.matcher(s).replaceAll(">"); + s= squ.matcher(s).replaceAll("'"); + s= dqu.matcher(s).replaceAll("""); + } + return s; + } + + + static public StringBuffer encode (StringBuffer sb) { + + return new StringBuffer(encode(sb.toString())); + + } + + + public String where() { + return sourcename + ":" + (yyline+1) + "." + (yycolumn+1) ; + } + + public int getYYLine() { return yyline+1;} + public int getYYColumn() { return yycolumn+1;} + + /** + * Loads an XML file with the given Generic Parser. + *

+ * @param file An inputStream providing the XML + * @param gp A parser implementing the IGenericXMLParser interface. + */ + static public void load(java.io.InputStream xmlStream, IGenericXMLParser gp) throws Exception{ + GenericXMLParser parser = new GenericXMLParser(xmlStream); + parser.setParser(gp); + while(true){ + if(GenericXMLParser.YYEOF == parser.yylex()) break; + } + } + + /** + * Loads an XML file with the given Generic Parser. + * @param xmlStream + * @param gp + * @throws Exception + */ + static public void load(java.io.Reader xmlStream, IGenericXMLParser gp) throws Exception{ + GenericXMLParser parser = new GenericXMLParser(xmlStream); + parser.setParser(gp); + while(true){ + if(GenericXMLParser.YYEOF == parser.yylex()) break; + } + } + + +%} + +Char = [a-z]|[A-Z]|"_" +Digit = [0-9] +namestart = {Char} +namechar = {namestart} | "-" | "." | {Digit} +Identifier = {namestart}{namechar}*(":"{namestart}{namechar}*)? +EOL = \r|\n|\r\n +ws = {EOL}|[ \t\f] +string1 = "'"[^']*"'" +string2 = "\""[^\"]*"\"" +string = {string1}|{string2} +body = ({ws}|[^<>])* +any = Char|ws|Digit|">"|"<"|"&"|. +comment = "" + +%xstate Attributes +%xstate Tag +%xstate EndTag +%xstate NestedTag +%% + + { + + "<" {pushstate(Tag); } + "" {} + {ws} { } + {comment} {} + {any} { error(yytext()); } + +} + + { + {Identifier}{ws}*"="{ws}*{string} { + String text = yytext(); + String key = text.substring (0,text.indexOf('=')).trim(); + String value = text.substring (text.indexOf('=')+1).trim(); + char delimiter = value.charAt(0); + value = value.substring(1,value.lastIndexOf(delimiter)); + + attribs.put(key,unencode(value)); + } + + "/"?">" { + yypushback(1); + if(yytext().indexOf("/")>=0) yypushback(1); + popstate(); + } + + {ws} { } + {any} { error(yytext()); } +} + + { + {Identifier} { + pushTag(yytext()); + body=""; + pushstate(Attributes); + } + + ">" { + parser.beginTag(tagstk,tagstkptr,currenttag,attribs); + popstate(); + pushstate(EndTag); + } + + "/>" { + parser.beginTag(tagstk,tagstkptr,currenttag,attribs); + parser.endTag(tagstk,tagstkptr,currenttag,"",attribs); + attribs.clear(); + popTag(currenttag); + popstate(); + return 1; + } + + {comment} {} + {ws} { } + {any} { error(yytext()); } + +} + + { + + {body} { + String text = yytext(); + body += text; + } + + "" { + String endTag = yytext(); + parser.endTag(tagstk,tagstkptr,currenttag,unencode(body),attribs); + attribs.clear(); + popTag(endTag); + popstate(); + } + + "<" { + popstate(); + pushstate(NestedTag); + pushstate(Tag); + } + + {comment} {} + {any} { body += yytext(); error(yytext()); } +} + + { + "<" {pushstate(Tag); } + + "" { + String endTag = yytext(); + parser.endTag(tagstk,tagstkptr,currenttag,"",attribs); + attribs.clear(); + popTag(endTag); + popstate(); + return 1; + } + + {ws} {} + {comment} {} + {any} { error(yytext()); } + +} + diff --git a/DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.java b/DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.java new file mode 100644 index 0000000..b2d9e57 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.java @@ -0,0 +1,874 @@ +/* The following code was generated by JFlex 1.4.1 on 9/3/08 9:55 PM */ + +package com.dtrules.xmlparser; +import java.util.*; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.util.regex.Pattern; +@SuppressWarnings({"unchecked","unused"}) + +/** + * This class is a scanner generated by + *
JFlex 1.4.1 + * on 9/3/08 9:55 PM from the specification file + * C:/eb/eb_dev2/RulesEngine/DTRules/src/main/java/com/dtrules/xmlparser/GenericXMLParser.flex + */ +public class GenericXMLParser { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int EndTag = 3; + public static final int NestedTag = 4; + public static final int YYINITIAL = 0; + public static final int Tag = 2; + public static final int Attributes = 1; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\1\7\1\6\1\0\1\7\1\5\22\0\1\7\1\26\1\11"+ + "\3\0\1\0\1\10\5\0\1\3\1\2\1\31\12\2\1\4\1\0"+ + "\1\12\1\30\1\25\1\27\1\0\2\1\1\13\1\21\26\1\4\0"+ + "\1\1\1\0\1\15\5\1\1\23\1\14\1\22\10\1\1\16\1\20"+ + "\1\24\2\1\1\17\3\1\uff85\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\3\0\1\1\1\0\1\2\2\3\1\4\7\2\1\5"+ + "\1\2\1\6\1\2\1\7\1\2\1\1\1\10\1\11"+ + "\1\4\13\0\1\12\13\0\1\6\4\0\1\13\3\0"+ + "\1\14\2\0\1\15\4\0"; + + private static int [] zzUnpackAction() { + int [] result = new int[66]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\32\0\64\0\116\0\150\0\202\0\234\0\202"+ + "\0\266\0\320\0\352\0\u0104\0\u011e\0\u0138\0\u0152\0\u016c"+ + "\0\202\0\u0186\0\u01a0\0\u01ba\0\202\0\u01d4\0\u01ee\0\u0208"+ + "\0\202\0\u0222\0\u023c\0\u0256\0\u0270\0\u028a\0\u011e\0\u02a4"+ + "\0\u02be\0\u02d8\0\u02f2\0\u030c\0\u0326\0\202\0\u0340\0\u035a"+ + "\0\u0374\0\u038e\0\u03a8\0\u03c2\0\u03dc\0\u03f6\0\u0410\0\u042a"+ + "\0\u0444\0\u045e\0\u0478\0\u0492\0\u04ac\0\u04c6\0\202\0\u04e0"+ + "\0\u04fa\0\u0514\0\202\0\u052e\0\u0548\0\202\0\u0562\0\u057c"+ + "\0\u0596\0\u05b0"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[66]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\5\6\1\7\2\10\2\6\1\11\1\12\3\6\1\13"+ + "\1\6\1\14\11\6\1\15\3\6\1\7\2\10\3\6"+ + "\1\16\3\15\1\17\1\15\1\20\3\15\1\21\3\6"+ + "\1\22\1\6\1\23\3\6\1\7\2\10\2\6\1\24"+ + "\12\23\1\25\3\6\1\26\12\27\1\30\12\27\1\31"+ + "\4\27\5\6\1\7\2\10\2\6\1\32\1\12\3\6"+ + "\1\13\1\6\1\14\10\6\40\0\1\10\51\0\1\33"+ + "\1\34\16\0\1\35\35\0\1\6\33\0\1\36\10\0"+ + "\3\37\1\40\3\41\3\0\12\37\3\0\1\42\2\0"+ + "\3\37\1\40\3\41\3\0\1\37\1\43\10\37\3\0"+ + "\1\42\2\0\3\37\1\40\3\41\3\0\5\37\1\15"+ + "\4\37\3\0\1\42\2\0\3\37\1\40\3\41\3\0"+ + "\7\37\1\44\2\37\3\0\1\42\26\0\1\21\5\0"+ + "\3\23\1\45\6\0\12\23\33\0\1\33\30\0\1\46"+ + "\4\0\12\27\1\0\12\27\1\0\4\27\26\0\1\33"+ + "\2\0\1\47\26\0\1\33\2\0\1\50\3\0\1\51"+ + "\26\0\12\34\1\0\12\34\1\0\1\34\1\52\2\34"+ + "\15\0\1\53\37\0\1\54\7\0\1\55\11\0\12\55"+ + "\12\0\3\41\20\0\1\42\6\0\3\42\1\56\1\57"+ + "\21\0\3\37\1\40\3\41\3\0\2\37\1\60\7\37"+ + "\3\0\1\42\2\0\3\37\1\40\3\41\3\0\10\37"+ + "\1\61\1\37\3\0\1\42\2\0\1\62\11\0\12\62"+ + "\6\0\1\63\11\0\12\63\6\0\1\64\11\0\12\64"+ + "\10\0\1\65\26\0\12\34\1\0\12\34\1\10\1\34"+ + "\1\52\2\34\16\0\1\6\35\0\1\66\10\0\3\55"+ + "\1\0\3\41\3\0\12\55\3\0\1\42\1\0\10\56"+ + "\1\67\21\56\11\57\1\67\20\57\1\0\3\37\1\40"+ + "\3\41\3\0\3\37\1\15\6\37\3\0\1\42\2\0"+ + "\3\37\1\40\3\41\3\0\7\37\1\70\2\37\3\0"+ + "\1\42\2\0\3\62\7\0\12\62\6\0\3\63\1\71"+ + "\3\72\3\0\12\63\1\73\5\0\3\64\1\74\3\75"+ + "\3\0\12\64\1\76\4\0\3\65\1\77\26\65\24\0"+ + "\1\6\6\0\3\37\1\40\3\41\3\0\11\37\1\15"+ + "\3\0\1\42\2\0\1\100\11\0\12\100\12\0\3\72"+ + "\15\0\1\73\5\0\1\101\11\0\12\101\12\0\3\75"+ + "\15\0\1\76\4\0\3\65\1\102\26\65\1\0\3\100"+ + "\1\0\3\72\3\0\12\100\1\73\5\0\3\101\1\0"+ + "\3\75\3\0\12\101\1\76\4\0\3\65\1\102\21\65"+ + "\1\10\4\65"; + + private static int [] zzUnpackTrans() { + int [] result = new int[1482]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\3\0\1\1\1\0\1\11\1\1\1\11\10\1\1\11"+ + "\3\1\1\11\3\1\1\11\1\1\13\0\1\11\13\0"+ + "\1\1\4\0\1\11\3\0\1\11\2\0\1\11\4\0"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[66]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /* user code: */ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + private String sourcename = "unknown name"; + String tagstk [] = new String[1000]; + int tagstkptr = 0; + int statestk [] = new int[1000]; + int statestkptr = 0; + ArrayList attribstk = new ArrayList(); + HashMap attribs = new HashMap(); + boolean printflg = true; + IGenericXMLParser parser = null; + + String body = ""; + String currenttag = ""; + String Source; + + public GenericXMLParser(String filename) throws FileNotFoundException { + this(new FileInputStream(filename)); + sourcename = filename; + } + + void pushTag(String tag){ + tagstk[tagstkptr++] = tag; + currenttag = tag; + attribstk.add(attribs); // We save and restore the attribs hashmap + attribs = new HashMap(); + } + + String popTag(String endtag) { + attribs = (HashMap) attribstk.remove(attribstk.size()-1); + if(endtag.indexOf("=0){ + endtag=endtag.substring(2,endtag.length()-1).trim(); + } + if(tagstkptr<=0){ + System.err.print("Stack Underflow\n"); + } + String tag = tagstk[--tagstkptr]; + if(!tag.equals(endtag)){ + System.err.print("Begin and End tags do not match:\n"+ + "Begin tag: "+tag+"\n"+ + "End tag: "+endtag+"\n"); + } + + if(tagstkptr<=0){ + currenttag = ""; + }else{ + currenttag = tagstk[tagstkptr-1]; + } + + return tag; + } + + public void setSource(String source){ + this.sourcename=source; + } + + public void setParser (IGenericXMLParser p_parser){ + parser = p_parser; + } + + void pushstate(int state) { + statestk[statestkptr++]=yystate(); + yybegin(state); + } + + int popstate (){ + int newstate = statestk[--statestkptr]; + statestk[statestkptr]=0; + yybegin(newstate); + return newstate; + } + + void error(String v)throws Exception{ + if(!parser.error(v)){ + throw new Exception("Unmatched characters, parsing cannot continue at" + where()); + } + } + + static private Pattern xamp = Pattern.compile("&"); + static private Pattern xlt = Pattern.compile("<"); + static private Pattern xgt = Pattern.compile(">"); + static private Pattern xsqu = Pattern.compile("'"); + static private Pattern xdqu = Pattern.compile("""); + + static public String unencode (String s){ + if(s.indexOf("&")>=0){ + s= xlt.matcher(s).replaceAll("<"); + s= xgt.matcher(s).replaceAll(">"); + s= xsqu.matcher(s).replaceAll("'"); + s= xdqu.matcher(s).replaceAll("\""); + s= xamp.matcher(s).replaceAll("&"); + } + return s; + } + static private Pattern tst = Pattern.compile("[&<>'\"]+"); + static private Pattern amp = Pattern.compile("&"); + static private Pattern lt = Pattern.compile("<"); + static private Pattern gt = Pattern.compile(">"); + static private Pattern squ = Pattern.compile("'"); + static private Pattern dqu = Pattern.compile("\""); + + static public String encode (String s) { + if(tst.matcher(s).find()){ + s= amp.matcher(s).replaceAll("&"); + s= lt.matcher(s).replaceAll("<"); + s= gt.matcher(s).replaceAll(">"); + s= squ.matcher(s).replaceAll("'"); + s= dqu.matcher(s).replaceAll("""); + } + return s; + } + + + static public StringBuffer encode (StringBuffer sb) { + + return new StringBuffer(encode(sb.toString())); + + } + + + public String where() { + return sourcename + ":" + (yyline+1) + "." + (yycolumn+1) ; + } + + public int getYYLine() { return yyline+1;} + public int getYYColumn() { return yycolumn+1;} + + /** + * Loads an XML file with the given Generic Parser. + *

+ * @param file An inputStream providing the XML + * @param gp A parser implementing the IGenericXMLParser interface. + */ + static public void load(java.io.InputStream xmlStream, IGenericXMLParser gp) throws Exception{ + GenericXMLParser parser = new GenericXMLParser(xmlStream); + parser.setParser(gp); + while(true){ + if(GenericXMLParser.YYEOF == parser.yylex()) break; + } + } + + /** + * Loads an XML file with the given Generic Parser. + * @param xmlStream + * @param gp + * @throws Exception + */ + static public void load(java.io.Reader xmlStream, IGenericXMLParser gp) throws Exception{ + GenericXMLParser parser = new GenericXMLParser(xmlStream); + parser.setParser(gp); + while(true){ + if(GenericXMLParser.YYEOF == parser.yylex()) break; + } + } + + + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + public GenericXMLParser(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + public GenericXMLParser(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 90) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public int yylex() throws java.io.IOException, Exception { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + boolean zzR = false; + for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL; + zzCurrentPosL++) { + switch (zzBufferL[zzCurrentPosL]) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn++; + } + } + + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + } + if (zzPeek) yyline--; + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = zzLexicalState; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 11: + { String text = yytext(); + String key = text.substring (0,text.indexOf('=')).trim(); + String value = text.substring (text.indexOf('=')+1).trim(); + char delimiter = value.charAt(0); + value = value.substring(1,value.lastIndexOf(delimiter)); + + attribs.put(key,unencode(value)); + } + case 14: break; + case 9: + { body += yytext(); error(yytext()); + } + case 15: break; + case 6: + { pushTag(yytext()); + body=""; + pushstate(Attributes); + } + case 16: break; + case 5: + { yypushback(1); + if(yytext().indexOf("/")>=0) yypushback(1); + popstate(); + } + case 17: break; + case 12: + { String endTag = yytext(); + parser.endTag(tagstk,tagstkptr,currenttag,unencode(body),attribs); + attribs.clear(); + popTag(endTag); + popstate(); + } + case 18: break; + case 8: + { popstate(); + pushstate(NestedTag); + pushstate(Tag); + } + case 19: break; + case 7: + { parser.beginTag(tagstk,tagstkptr,currenttag,attribs); + popstate(); + pushstate(EndTag); + } + case 20: break; + case 13: + { String endTag = yytext(); + parser.endTag(tagstk,tagstkptr,currenttag,"",attribs); + attribs.clear(); + popTag(endTag); + popstate(); + return 1; + } + case 21: break; + case 10: + { parser.beginTag(tagstk,tagstkptr,currenttag,attribs); + parser.endTag(tagstk,tagstkptr,currenttag,"",attribs); + attribs.clear(); + popTag(currenttag); + popstate(); + return 1; + } + case 22: break; + case 1: + { String text = yytext(); + body += text; + } + case 23: break; + case 2: + { error(yytext()); + } + case 24: break; + case 4: + { pushstate(Tag); + } + case 25: break; + case 3: + { + } + case 26: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + return YYEOF; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/DTRules/src/main/java/com/dtrules/xmlparser/IGenericXMLParser.java b/DTRules/src/main/java/com/dtrules/xmlparser/IGenericXMLParser.java new file mode 100644 index 0000000..a57d880 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/xmlparser/IGenericXMLParser.java @@ -0,0 +1,98 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.dtrules.xmlparser; + +import java.io.IOException; +import java.util.HashMap; + +/** + * This is a simple interface for handling parsing events + * from the generic parser. At this time, only two events + * are generated, the beginTag and the endTag events. The + * endTag() provides the body, if present. + * Creation date: (9/15/2003 8:35:17 AM) + * @author: Paul Snow, MTBJ, Inc. + */ +public interface IGenericXMLParser { + + /** + * The beginTag method is called when the parser detects the + * each begin tag in the XML file being parsed. When one uses + * a SAX parser, the class implementing the interface is responsible + * for keeping up with the context of the tags as they are + * encountered and closed. The GenericXMLParser provides a + * stack of all the tags currently open when the begin tag + * is encountered. This is the actual stack maintained by the + * GenericXMLParser, which is maintained as an array of tags. + * The tagstkptr provides an index into this array.

+ * The attributes associated with the tag are provided as a + * hashmap of key/Value pairs.

+ * + * @param tagstk A stack of tags active at the time the tag was encountered. + * @param tagstkptr A pointer into the tag stack to the top of stack. + * @param tag The tag encountered. + * @param attribs A hash map of attributes as a set of key/Value pairs. + * @throws IOException If an error occurs while parsing the XML, this exception will be thrown. + * @throws Exception If the tags are not matched, or an unexpected character is encountered, an + * exception will be thrown. + */ + public void beginTag( + String tagstk[], + int tagstkptr, + String tag, + HashMap attribs) + throws IOException, Exception; + + /** + * The endTag method is called when the parser detects the + * each end tag in the XML file being parsed. When one uses + * a SAX parser, the class implementing the interface is responsible + * for keeping up with the context of the tags as they are + * encountered and closed. The GenericXMLParser provides a + * stack of all the tags currently open when the end tag + * is encountered. The GenericXMLParser also provides the + * attributes of the begin tag to the end tag as well. + *

+ * + * @param tagstk A stack of tags active at the time the tag was encountered. + * @param tagstkptr A pointer into the tag stack to the top of stack. + * @param tag The tag encountered. + * @param body the body (if any) of the data between the begin and end tags. + * @param attribs A hash map of attributes as a set of key/Value pairs. + * @throws IOException If an error occurs while parsing the XML, this exception will be thrown. + * @throws Exception If the tags are not matched, or an unexpected character is encountered, an + * exception will be thrown. + **/ + public void endTag( + java.lang.String[] tagstk, + int tagstkptr, + String tag, + String body, + HashMap attribs) + throws Exception, IOException; + + /** + * When an error is encountered by the parser, the error method + * is called on the class implementing the IGenericXMLParser + * interface. This method returns true if parsing should continue. + * @param v This is the error string from the GenericXMLParser + */ + public boolean error(String v) + throws Exception; // Returns true if parsing should continue. +} diff --git a/DTRules/src/main/java/com/dtrules/xmlparser/IXMLPrinter.java b/DTRules/src/main/java/com/dtrules/xmlparser/IXMLPrinter.java new file mode 100644 index 0000000..07ee9db --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/xmlparser/IXMLPrinter.java @@ -0,0 +1,171 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.xmlparser; + +public interface IXMLPrinter { + + /** + * Returns the number of tags on the tag stack. + */ + public int depth(); + + /** + * Returns the tag with the given index. Returns null if out + * of range. + */ + public String getTag(int i); + + /** + * Prints a simple open tag with no attributes. + * @param tag + */ + public abstract void opentag(String tag); + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + */ + public abstract void opentag(String tag, String name1, Object value1); + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + */ + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2); + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param name3 + * @param value3 + */ + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3); + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param name3 + * @param value3 + * @param name4 + * @param value4 + */ + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3, String name4, Object value4); + + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3, String name4, Object value4, String name5, + Object value5); + + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3, String name4, Object value4, String name5, + Object value5, String name6, Object value6); + + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3, String name4, Object value4, String name5, + Object value5, String name6, Object value6, String name7, Object value7); + + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3, String name4, Object value4, String name5, + Object value5, String name6, Object value6, String name7, Object value7, String name8, + Object value8); + + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3, String name4, Object value4, String name5, + Object value5, String name6, Object value6, String name7, Object value7, String name8, + Object value8, String name9, Object value9); + + public abstract void opentag(String tag, String name1, Object value1, String name2, + Object value2, String name3, Object value3, String name4, Object value4, String name5, + Object value5, String name6, Object value6, String name7, Object value7, String name8, + Object value8, String name9, Object value9, String name10,Object value10); + /** + * Closes the currently open tag. Assumes no body text. Throws a + * runtime exception if no open tag exists. + */ + public abstract void closetag(); + + /** + * Print data within a data tag. The text is encoded. + * @param text + */ + public abstract void printdata(Object bodyvalue); + + /** + * Print data within a given tag. + */ + public abstract void printdata(String tag, Object bodyvalue); + + /** + * Print the tag, one attribute, and the body. + * @param tag + * @param name1 + * @param value + * @param body + */ + public abstract void printdata(String tag, String name1, Object value, Object body); + public void printdata(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + Object bodyvalue); + public void printdata(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + Object bodyvalue); + public void printdata(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + Object bodyvalue); + public void printdata(String tag, + String name1, Object value1, + String name2, Object value2, + Object bodyvalue); + /** + * Closes all open tags, close the file. + * + */ + public abstract void close(); + + /** + * Just a helper to print an error during the generation of an XML file + * @param errorMsg The error message to be printed. Put into an tag in the XML. + */ + public abstract void print_error(String errorMsg); + +} \ No newline at end of file diff --git a/DTRules/src/main/java/com/dtrules/xmlparser/XMLPrinter.java b/DTRules/src/main/java/com/dtrules/xmlparser/XMLPrinter.java new file mode 100644 index 0000000..5b223e9 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/xmlparser/XMLPrinter.java @@ -0,0 +1,535 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.xmlparser; + +import java.io.OutputStream; +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; + +import com.dtrules.interpreter.RTime; + +/** + * A simple class for the support of printing XML files. Start and end tags + * are tracked and printed. An enclosing tag is printed. Strings are encoded + * automatically. Tags are specified by their name, i.e. "Document" and not + * using any XML syntax, i.e. "". + * + * @author paul snow + * Jul 9, 2007 + * + */ +public class XMLPrinter implements IXMLPrinter { + ArrayList tagStack = new ArrayList(); + final PrintStream out; + boolean newline = true; + boolean intextbody = false; + boolean intagbody = false; + /** + * Returns the number of tags on the tag stack. + */ + public int depth() { + return tagStack.size(); + } + + /** + * Returns the tag with the given index. Returns null if out + * of range. + */ + public String getTag(int i){ + if(i<0 || i>=tagStack.size())return null; + return tagStack.get(i); + } + + /** + * This function puts the output on a newline, but not if we + * are already on a newline. + */ + private void newline(){ + if(!newline)out.println(); + newline = true; + } + /** + * A helper function just to print text, and sets the state of the + * newline function. Note that we are never going to print a newline + * on a non-XML syntax boundry. + * @param text + */ + private void print(String text){ + out.print(text); + newline = false; + } + + /** + * Prints a simple open tag with no attributes. + * @param tag + */ + private void halfopentag(String tag){ + if(intextbody)throw new RuntimeException("Can't open a tag within a data body"); + newline(); + int indent = tagStack.size(); + for(int i=0;i"); + } + /** + * Prints an attribute. The value is encoded. + */ + private void printAttribute(String name, Object value){ + name = name.replaceAll(" ", "_"); + print(" "); + print(name); + print("='"); + print(GenericXMLParser.encode(value.toString())); + print("'"); + } + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + */ + public void opentag(String tag, String name1, Object value1){ + halfopentag(tag); + printAttribute(name1, value1); + print(">"); + } + /** + * Open a tag with a given set of attributes + */ + public void opentag(String tag, HashMap attribs){ + halfopentag(tag); + for(String key : attribs.keySet()){ + Object o = attribs.get(key); + if(o!=null){ + printAttribute(key, o); + }else{ + printAttribute(key,""); + } + } + print(">"); + } + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + */ + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + print(">"); + } + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param name3 + * @param value3 + */ + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + print(">"); + } + + /** + * Open a tag with one named attribute + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param name3 + * @param value3 + * @param name4 + * @param value4 + */ + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + printAttribute(name4, value4); + print(">"); + } + + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + printAttribute(name4, value4); + printAttribute(name5, value5); + print(">"); + } + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + printAttribute(name4, value4); + printAttribute(name5, value5); + printAttribute(name6, value6); + print(">"); + } + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + printAttribute(name4, value4); + printAttribute(name5, value5); + printAttribute(name6, value6); + printAttribute(name7, value7); + print(">"); + } + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7, + String name8, Object value8 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + printAttribute(name4, value4); + printAttribute(name5, value5); + printAttribute(name6, value6); + printAttribute(name7, value7); + printAttribute(name8, value8); + print(">"); + } + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7, + String name8, Object value8, + String name9, Object value9 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + printAttribute(name4, value4); + printAttribute(name5, value5); + printAttribute(name6, value6); + printAttribute(name7, value7); + printAttribute(name8, value8); + printAttribute(name9, value9); + print(">"); + } + + public void opentag(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + String name6, Object value6, + String name7, Object value7, + String name8, Object value8, + String name9, Object value9, + String name10,Object value10 + ){ + halfopentag(tag); + printAttribute(name1, value1); + printAttribute(name2, value2); + printAttribute(name3, value3); + printAttribute(name4, value4); + printAttribute(name5, value5); + printAttribute(name6, value6); + printAttribute(name7, value7); + printAttribute(name8, value8); + printAttribute(name9, value9); + printAttribute(name10,value10); + print(">"); + } + + + /** + * Closes the currently open tag. Assumes no body text. Throws a + * runtime exception if no open tag exists. + */ + public void closetag(){ + int lastIndex = tagStack.size()-1; + if(!intextbody){ + newline(); + for(int i=0;i"); + newline(); + tagStack.remove(lastIndex); + intextbody = false; + intagbody = true; + } + /** + * Print data within a data tag. The text is encoded. + * @param text + */ + public void printdata(Object bodyvalue){ + if(intagbody){ + throw new RuntimeException("You can't mix data and tags"); + } + if(bodyvalue != null){ + if(bodyvalue instanceof Date) { + bodyvalue = RTime.getRTime((Date)bodyvalue); + } + String v = GenericXMLParser.encode(bodyvalue.toString()); + out.print(v); + } + intextbody = true; + } + + /** + * Print data within a given tag. + */ + public void printdata(String tag, Object bodyvalue){ + opentag(tag); + printdata(bodyvalue); + closetag(); + } + /** + * Open a tag with a given set of attributes + */ + public void printdata(String tag, HashMap attribs, Object bodyvalue){ + halfopentag(tag); + for(String key : attribs.keySet()){ + String v = GenericXMLParser.encode(attribs.get(key).toString()); + printAttribute(key, v); + } + print(">"); + printdata(bodyvalue); + closetag(); + } + /** + * Print the tag, attributes, and the body. + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param body + */ + public void printdata(String tag, String name1, Object value1,String name2, Object value2, Object bodyvalue){ + opentag(tag,name1,value1,name2,value2); + printdata(bodyvalue); + closetag(); + } + /** + * Print the tag, attributes, and the body. + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param name3 + * @param value3 + * @param body + */ + public void printdata(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + Object bodyvalue){ + opentag(tag,name1,value1,name2,value2,name3,value3); + printdata(bodyvalue); + closetag(); + } + + /** + * Print the tag, attributes, and the body. + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param name3 + * @param value3 + * @param name4 + * @param value4 + * @param body + */ + public void printdata(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + Object bodyvalue){ + opentag(tag, + name1,value1, + name2,value2, + name3,value3, + name4,value4 + ); + printdata(bodyvalue); + closetag(); + } + + /** + * Print the tag, attributes, and the body. + * @param tag + * @param name1 + * @param value1 + * @param name2 + * @param value2 + * @param name3 + * @param value3 + * @param name4 + * @param value4 + * @param name5 + * @param value5 + * @param body + */ + public void printdata(String tag, + String name1, Object value1, + String name2, Object value2, + String name3, Object value3, + String name4, Object value4, + String name5, Object value5, + Object bodyvalue){ + opentag(tag, + name1,value1, + name2,value2, + name3,value3, + name4,value4, + name5,value5 + ); + printdata(bodyvalue); + closetag(); + } + + /** + * Print the tag, attributes, no + * @param tag + * @param name1 + * @param value + * @param body + */ + public void printdata(String tag, String name1, Object value, Object bodyvalue){ + opentag(tag,name1,value); + printdata(bodyvalue); + closetag(); + } + public XMLPrinter(OutputStream stream ){ + out = new PrintStream(stream); + } + /** + * Opens an output stream, and puts out the surrounding root tag. + * @param tag The surrounding tag. No XML syntax should be specified. + * @param stream + */ + public XMLPrinter(String tag, OutputStream stream){ + out = new PrintStream(stream); + opentag(tag); + } + + /** + * Closes all open tags, close the file. + * + */ + public void close(){ + for(int i = tagStack.size()-1; i>=0;i--){ + closetag(); + } + out.close(); + } + + /** + * Just a helper to print an error during the generation of an XML file + * @param errorMsg The error message to be printed. Put into an tag in the XML. + */ + public void print_error(String errorMsg){ + if(intextbody)closetag(); + opentag("error"); + print(GenericXMLParser.encode(errorMsg)); + closetag(); + } + +} diff --git a/DTRules/src/main/java/com/dtrules/xmlparser/compileGenericXMLParser.bat b/DTRules/src/main/java/com/dtrules/xmlparser/compileGenericXMLParser.bat new file mode 100644 index 0000000..5f60cb3 --- /dev/null +++ b/DTRules/src/main/java/com/dtrules/xmlparser/compileGenericXMLParser.bat @@ -0,0 +1,6 @@ +dir +set pdir=C:\eb\eb_dev2\RulesEngine\DTRules\src\main\java\com\dtrules +set pdir2=C:\jflex-1.4.1 +set xmldir=%pdir%\xmlparser +java -classpath %pdir2%\lib\JFlex.jar JFlex.Main -d %xmldir% %xmldir%\GenericXMLParser.flex +pause \ No newline at end of file diff --git a/DTRules/src/test/com/dtrules/admin/RulesAdminServiceTest.java b/DTRules/src/test/com/dtrules/admin/RulesAdminServiceTest.java new file mode 100644 index 0000000..0bf4be8 --- /dev/null +++ b/DTRules/src/test/com/dtrules/admin/RulesAdminServiceTest.java @@ -0,0 +1,55 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.admin; + +import static org.junit.Assert.*; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class RulesAdminServiceTest { + + @Before + public void setUp() throws Exception { + } + + @After + public void tearDown() throws Exception { + } + + @Test + public final void testGetRulesets() { + RulesAdminService ras = new RulesAdminService(null,null); + ras.initialize(null); + assertNotNull("Ruleset null", ras.getRulesets()); + assertNotNull("Ruleset null", ras.getRulesets().get(0)); + assertEquals("Ruleset name is the same","ebdemo", ras.getRulesets().get(0)); + // fail("Not yet implemented"); // TODO + } + + @Test + public final void testGetRuleset() { + RulesAdminService ras = new RulesAdminService(null,null); + ras.initialize(null); + assertNotNull("Ruleset name null", ras.getRuleset("ebdemo")); + assertNull("Ruleset null", ras.getRuleset("/ebdemo")); + // fail("Not yet implemented"); // TODO + } + +} diff --git a/DTRules/src/test/com/dtrules/decisiontables/ANodeTest.java b/DTRules/src/test/com/dtrules/decisiontables/ANodeTest.java new file mode 100644 index 0000000..1da33d9 --- /dev/null +++ b/DTRules/src/test/com/dtrules/decisiontables/ANodeTest.java @@ -0,0 +1,67 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.decisiontables; + +import com.dtrules.test.BaseTest; + +/** + * @author prasath ramachandran + * Jan 23, 2007 + * + */ +public class ANodeTest extends BaseTest { + + public ANodeTest(String arg) { + super(arg); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Test method for {@link com.dtrules.decisiontables.ANode#execute(com.dtrules.session.DTState)}. + */ + public final void testExecute() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.ANode#validate()}. + */ + public final void testValidate() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.ANode#toString()}. + */ + public final void testToString() { + fail("Not yet implemented"); // TODO + } + +} diff --git a/DTRules/src/test/com/dtrules/decisiontables/CNodeTest.java b/DTRules/src/test/com/dtrules/decisiontables/CNodeTest.java new file mode 100644 index 0000000..8bb2133 --- /dev/null +++ b/DTRules/src/test/com/dtrules/decisiontables/CNodeTest.java @@ -0,0 +1,78 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.decisiontables; + +import junit.framework.TestCase; + +/** + * @author prasath ramachandran + * Jan 23, 2007 + * + */ +public class CNodeTest extends TestCase { + + /** + * + */ + public CNodeTest() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @param arg0 + */ + public CNodeTest(String arg0) { + super(arg0); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Test method for {@link com.dtrules.decisiontables.CNode#execute(com.dtrules.session.DTState)}. + */ + public final void testExecute() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.CNode#validate()}. + */ + public final void testValidate() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.CNode#toString()}. + */ + public final void testToString() { + fail("Not yet implemented"); // TODO + } + +} diff --git a/DTRules/src/test/com/dtrules/decisiontables/DTLoaderTest.java b/DTRules/src/test/com/dtrules/decisiontables/DTLoaderTest.java new file mode 100644 index 0000000..23a2933 --- /dev/null +++ b/DTRules/src/test/com/dtrules/decisiontables/DTLoaderTest.java @@ -0,0 +1,211 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.decisiontables; + +import com.dtrules.test.BaseTest; + + +/** + * @author prasath ramachandran + * Jan 23, 2007 + * + */ +public class DTLoaderTest extends BaseTest { + + /** + * @param arg + */ + public DTLoaderTest(String arg) { + super(arg); + // TODO Auto-generated constructor stub + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#setUp() + */ + protected void setUp() throws Exception { + super.setUp(); + } + + /* (non-Javadoc) + * @see junit.framework.TestCase#tearDown() + */ + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_decision_tables()}. + */ + public final void testEnd_decision_tables() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_table_name()}. + */ + public final void testEnd_table_name() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_decision_table()}. + */ + public final void testEnd_decision_table() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_table_number()}. + */ + public final void testEnd_table_number() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_ipad_id()}. + */ + public final void testEnd_ipad_id() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_purpose()}. + */ + public final void testEnd_purpose() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_comments()}. + */ + public final void testEnd_comments() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_policy_reference()}. + */ + public final void testEnd_policy_reference() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#begin_condition_details()}. + */ + public final void testBegin_condition_details() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_condition_description()}. + */ + public final void testEnd_condition_description() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_condition_postfix()}. + */ + public final void testEnd_condition_postfix() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_condition_comment()}. + */ + public final void testEnd_condition_comment() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#begin_condition_column()}. + */ + public final void testBegin_condition_column() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_condition_details()}. + */ + public final void testEnd_condition_details() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#begin_action_details()}. + */ + public final void testBegin_action_details() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_action_description()}. + */ + public final void testEnd_action_description() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_action_postfix()}. + */ + public final void testEnd_action_postfix() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_action_comment()}. + */ + public final void testEnd_action_comment() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#begin_action_column()}. + */ + public final void testBegin_action_column() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#end_action_details()}. + */ + public final void testEnd_action_details() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#beginTag(java.lang.String[], int, java.lang.String, java.util.HashMap)}. + */ + public final void testBeginTag() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#endTag(java.lang.String[], int, java.lang.String, java.lang.String, java.util.HashMap)}. + */ + public final void testEndTag() { + fail("Not yet implemented"); // TODO + } + + /** + * Test method for {@link com.dtrules.decisiontables.DTLoader#error(java.lang.String)}. + */ + public final void testError() { + fail("Not yet implemented"); // TODO + } + +} diff --git a/DTRules/src/test/com/dtrules/decisiontables/DecisionTableTypeTest.java b/DTRules/src/test/com/dtrules/decisiontables/DecisionTableTypeTest.java new file mode 100644 index 0000000..ed2826a --- /dev/null +++ b/DTRules/src/test/com/dtrules/decisiontables/DecisionTableTypeTest.java @@ -0,0 +1,187 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.decisiontables; + +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.Iterator; + +import com.dtrules.entity.REntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.IRObject; +import com.dtrules.interpreter.RName; +import com.dtrules.interpreter.RNull; +import com.dtrules.mapping.LoadMapping; +import com.dtrules.mapping.Mapping; +import com.dtrules.session.DTState; +import com.dtrules.session.ICompilerError; +import com.dtrules.session.IRSession; +import com.dtrules.session.RuleSet; +import com.dtrules.session.RulesDirectory; +import com.dtrules.xmlparser.GenericXMLParser; + +public class DecisionTableTypeTest { + + int maxRow=0,maxCol=0; + String ctable [][] = new String[128][128]; + String atable [][] = new String[128][128]; + RDecisionTable dt; + + public DecisionTableTypeTest(IRSession session, RuleSet rs) throws RulesException{ + + dt = new RDecisionTable(session, rs, "test"); + + String ctable[][] = { + { "y", "n", "n", "y", "d", "a" }, + { "n", "n", "y", " ", " ", " " }, + { "y", "y", "y", "n", " ", " " }, + { "y", "y", " ", " ", " ", " " }, + { " ", " ", "y", " ", " ", " " }, + { "y", " ", " ", " ", " ", " " }, + + }; + dt.conditiontable = ctable; + + String atable[][] = { + { "x", " ", " ", " ", " ", " " }, + { " ", "x", "x", " ", " ", " " }, + { " ", "x", "x", " ", " ", " " }, + { " ", " ", " ", "x", "x", " " }, + { " ", " ", " ", " ", "x", " " }, + { " ", " ", " ", "x", " ", "x" }, + }; + dt.maxcol = ctable[0].length; + dt.actiontable = atable; + dt.rconditions = new IRObject[ctable.length]; + dt.ractions = new IRObject[atable.length]; + + String cps[] = new String[ctable.length]; + for (int i = 0; i < cps.length; i++) + cps[i] = "{ 'Condition " + i + "' }"; + + String aps[] = new String[atable.length]; + for (int i = 0; i < aps.length; i++) + aps[i] = "{ 'Action " + i + "' }"; + + dt.conditions = cps; + dt.conditionsPostfix = cps; + dt.actions = aps; + dt.actionsPostfix = aps; + dt.setType(RDecisionTable.Type.FIRST); + } + + public static void main(String[] args) { + String path = "C:\\eclipse\\workspace\\EB_POC\\CA HCO Plan\\xml\\"; + String file = "DTRules.xml"; + if(args.length>0){ + file = args[0]; + } + + try { + RulesDirectory rd = new RulesDirectory(path,file); + RuleSet rs = rd.getRuleSet(RName.getRName("ebdemo")); + IRSession session = rs.newSession(); + DTState state = session.getState(); + DecisionTableTypeTest test; + + test = new DecisionTableTypeTest(session,rs); + test.dt.setType(RDecisionTable.Type.FIRST); + test.dt.build(); + test.printtable (); + + test = new DecisionTableTypeTest(session,rs); + test.dt.setType(RDecisionTable.Type.ALL); + test.dt.build(); + test.printtable (); + + + } catch (Exception e) { + e.printStackTrace(System.out); + } + + } + + void printtable(){ + maxRow = maxCol = 0; + filltable(0,0,dt.decisiontree); + + System.out.print(" "); + for(int i=0;i errors = dt.getErrorList().iterator(); + while(errors.hasNext()){ + ICompilerError error = errors.next(); + System.out.println(error.getMessage()+ + " on "+"Row " + error.getRow()+" Column "+error.getCol()); + + + } + } + + + private int filltable(int row, int col, DTNode node){ + if(node.getClass()==CNode.class){ + int ncol; + CNode cnode = (CNode) node; + + if(cnode.conditionNumber!=row){ + ncol = filltable(row+1,col, node); + for(int i=col;i ", "true", + " 5 3 < ", "false", + " 3 3 >= ", "true", + " 3 8 <= ", "true", + " 1 1 == ", "true", + " 5.1 3.2 > ", "true", + " 5.5 3.4 < ", "false", + " 3.1 3.0 >= ", "true", + " 3.9 4.0 <= ", "true", + " 1.5 1.5 == ", "true", + " true true b= ", "true", + " true true b!= ", "false", + " 'austin' 'austin' s== ", "true", + " 'madison' 'austin' s> ", "true", + " 'dallas' 'austin' s< ", "false", + " 3 3 >= ", "true", + " 3 8 <= ", "true", + " 1 1 == ", "true", + " 'austin ' 'downtown' s+ ", "austin downtown", + " 'austin downtown ' 'downtown' strremove ", "austin", + " 'abc' 'abc' req ", "true", + " 5 5 req ", "true", + + " '2007-12-12' newdate ", "2007-12-12", + " '2007-12-12' newdate yearof ", "2007", + " '2007-12-12' newdate getdaysinyear ", "365", + " '2008-12-12' newdate getdaysinyear ", "366", + " '2008-12-12' newdate '2007-12-12' newdate d< ", "false", + " '2008-12-12' newdate '2007-12-12' newdate d> ", "true", + " '2008-12-12' newdate '2008-12-11' newdate d== ", "false", + " '2008-12-12' newdate '2008-12-12' newdate d== ", "true", + " '2008-12-12' newdate gettimestamp", "2008-12-12 00:00:00.0", + + }; + + static int testcnt = 0; + static int testcntfailed = 0; + + public static void main(String args[]){ + + String file = "c:\\eclipse\\workspace\\DTRules\\com.dtrules.testfiles\\DTRules.xml"; + IRSession session; + DTState state; + RulesDirectory rd; + RuleSet rs; + + try { + rd = new RulesDirectory("",file); + rs = rd.getRuleSet(RName.getRName("test",true)); + session = rs.newSession(); + state = session.getState(); + } catch (RulesException e1) { + System.out.println("Failed to initialize the Rules Engine"); + return; + } + + for(int i=0;i> expected: "+tests[i+1]+" --passed\n"); + }else{ + state.debug("test: << "+tests[i]+" >> expected: "+tests[i+1]+" result:"+result+" --FAILED\n"); + } + state.debug("\n"); + }catch(Exception e){ + state.error(" Exception Thrown:\n"); + state.error("test: "+tests[i]+"expected: "+tests[i+1]+" result: Exception thrown --FAILED\n"); + state.error(e+"\n"); + } + } + } +} diff --git a/DTRules/src/test/com/dtrules/test/AllUnitTest.java b/DTRules/src/test/com/dtrules/test/AllUnitTest.java new file mode 100644 index 0000000..838ecac --- /dev/null +++ b/DTRules/src/test/com/dtrules/test/AllUnitTest.java @@ -0,0 +1,37 @@ +/* + * $Id$ + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.test; + +import junit.framework.Test; +import junit.framework.TestSuite; + +/** + *

Title : DTRules

+ *

Description : The Rules Engine

+ *

Date : Jan 26, 2005 , 4:41:14 PM

+ * + * @author Prasath Ramachandran + * @version $Revision: 1.0 $ + */ + +public class AllUnitTest { + public static Test suite() { + TestSuite suite = new TestSuite(); + return suite; + } +} diff --git a/DTRules/src/test/com/dtrules/test/BaseTest.java b/DTRules/src/test/com/dtrules/test/BaseTest.java new file mode 100644 index 0000000..a2bd1fb --- /dev/null +++ b/DTRules/src/test/com/dtrules/test/BaseTest.java @@ -0,0 +1,49 @@ +/* + * + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.test; + +import junit.framework.TestCase; + +/** + *

Title : DTRules

+ *

Description : The Rules Engine

+ *

Date : Jan 26, 2005 , 4:41:14 PM

+ * + * @author Prasath Ramachandran + * @version $Revision: 1.0 $ + */ + +public class BaseTest extends TestCase { + + public BaseTest(String arg) { + super(arg); + } + + public void assertNotEqual(String message, Object expected, Object actual) { + if (expected == null) { + if (actual == null) { + fail("They are equal"); + } + } else { + if (actual != null) { + if (actual.equals(expected)) { + fail("They are equal"); + } + } + } + } +} diff --git a/DTScanner/.classpath b/DTScanner/.classpath new file mode 100644 index 0000000..f6b6d82 --- /dev/null +++ b/DTScanner/.classpath @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/DTScanner/.project b/DTScanner/.project new file mode 100644 index 0000000..fd223d3 --- /dev/null +++ b/DTScanner/.project @@ -0,0 +1,16 @@ + + DTScanner + SDC Parent POM + + DTParser + DTRules + + + + org.eclipse.jdt.core.javabuilder + + + + org.eclipse.jdt.core.javanature + + \ No newline at end of file diff --git a/DTScanner/.settings/org.eclipse.jdt.core.prefs b/DTScanner/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..6481952 --- /dev/null +++ b/DTScanner/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Thu May 15 12:54:27 CDT 2008 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 diff --git a/DTScanner/lib/JFlex.jar b/DTScanner/lib/JFlex.jar new file mode 100644 index 0000000000000000000000000000000000000000..d82e9d6c81146bfbf63355965493994650462eb2 GIT binary patch literal 169635 zcwU@&1C%8RvUYdbwr#u1t}ffQZFkwW?JnD0wr$&X)!#j{Z+B+T+xd6ijmq!DiHvhk zRz}>2FTa!#2Lyun^y~9xV@&_)40xq+;&Sp185DdN61U;o(BY18P~k{SzT!7X9*l8e*I|@l;&S$3$ecH^cTBF$9*B%L z4jJ|cVPWM+ZL4;2l()PDZ5nMFpJc>A!IY*X$Q*xOl;6)o=AZxFzh5@U&qGYu!qA2G zUpX)TmILw69AigQ+W-7rQ2)$xFtm5D|BFnRe`e}hIXLLroBu`bulsMN>!ho#?`ZQE zY4Cqcvvag^Fts%N|CHA=Qe_Nzg z=FRs3`Oa7AHJ-4`2NtSz1pBsywdOv-eNp?+TIs(#;{EPSK}peP->pgr6H;dPjM?s@ z=0Q*-y?5KFcGZd@OTD}|v@w(i0xwG(?(&EW5B?y=SKBo)yEZf7Mo4wd#HbDTKxLF}`HAqg*8AZF6+!x}%)L z{`?#va`XAkGIa9Z+3EHc?FFg29PaC+VMVplo13!q!VgTHG<9wT|9yuGV`21#IsG;| zmz&h;3$e_`9S>_`k%u5`PtEH#8(GFnSLIHE2J7Nd6N4->?hl~>T=r!SQ0t6i%v1Ek z7E?~gFIhrqyJQwC4~K9}xGaUG%|iA4RdeV)O8QVWnZB;Pw^?^6Qb<=)H_bsYYo2F~ z2GgFF$IB&MJ{9NkNuccPofaGmawI*K)>x?dOYU8^4S^^E*^gw2ZNyAL< z_-NQ@hwVc86CQJ>Z3RY^$leNq)Ev(s%PFAYW=YwW6WS|P!4BgZoGa@e%twb2o}TTV z0XuwEXVdWPiyG4&OF_?={XR2U&bJxo=Z6=p+Y96SiQ8j!wkf;EU_e(!QwxQ6O%Y|5 zW{g&Mv8kzk1d#{Ue)4PBT&%^lm1PIQD}|J(m7cn%STcx9FKlJj7%wjzR>jU+0(Pqb znp_L+jTOlL%_@TjZUej`&h(UPCmCx2tsVPz7dqNSR~AXnIF#!@Cd7&TOyJAy+`8~! z!i=G|gVQ5JjhpOo-<;ww-@EWKkq4l*ar?|cY&DoLdwD{C4ergTd)bkmW(>sU<*kQS?D{;VnUQ6K4FY(ET;T$@QeU6B;AhEZITaUgj@w z&ST{&k@iM#gS>8bWP}0&OIp;VkR=k1i7FM97))76&~sxTIc7y^Ni))S%@UNP6zyV* zKpbOjK}w9HAtkTtL}@JIidJ^{+c`^<7LNDK@;J@nA=R3*%c-Q;n@i(F+#IKoic(`m zt;$NYcuGB16)2r&mCB{(PU5JHS~b?Ro=~HXch}inXD<(j@QnNgmhQB9U_7sOWE}ha zG|r=ibEE_c8t(aMTK%R5T~hIB%_&N6XhS_p@QDPz21Y~Sr@RWiMYag{%+z1!H(zUx z`K@M^qO%LXxpSmA(>pQV)7>-N)88{jGDOlxGNz(ahb#4i3&T6(u6o)$bge1N)6b$V z$bBzR5wA|9(2}sHAM0a6oiP(jeQP14TGijefqZacIbW`IU&-uohdo^ppKQ+yie$#( zS!~NQbU!&ql(ZWeNd;YcQG}uv7?@;CMdLtkMQcTOM{`GiK?6mTriWq7)Wy=pGUOa# z>t`D`F{-0eLnlQ;xJ57;Q=qSdf=V;h(^-N_9Qzkw>2UV3jk*Nd`uhYhPB2v2f?yi| z3qs*Q|CR;$W5v^0J2j*iec>G2GKG=0cS-G;!OGmfWD5E(L(O{4IKy``6+w1f@h3SN zuzPM~3j+UDh!B5H@*pykd|G4jZ<$aq;@`5`#cV3*;pzV?Sir{v{5{L}!m2a7*I&k# zXwBpBHFRd#$Xav&O*_{a%b0e*lQ|mGcqb%~gf|WSDleEyFpU&b7|bM;PySzqG*8>p z7*^xA3LmT>Y-ikA+nxUf^6_c8tGDZt7i&Mk$I9*EXVM?RE7#eYQk5#Y58y9=SL<8L zC&$mn0JFfwkTR(GCS1Oa@NE%`mMm*VGe3a_BfV=A3dER>&94g`YFx(##E%i}zYLLM za7vTh7%)hi-WV|cgm{)eK;n(T7w^XiV=bO*NV^R0`=od_>5!X$ft-i-ovo++SoPR^ zL%N0K7h8Us^J$(zN#4|NOrK2wrh)Rozao-JW;6Lr3(~uUZj$>Jfn^f>$w6OLz-bcs z5E~oWOUj3I(x}?;#YR1C(g8L8mkj`O&@48Oovs==Sut{G{c@Xh2cS8u7DY#-)SRYk zP|eW<9H6G?1qa};e{*~Xz;Fm%sBmBPL`!Ki9#v%xffC>qgk{kA{^-Pb48ht7Fi*g9 z3qHba3HZbQ!O8b(HF50-Ml+hAa}Qi%9L?0dhpIJB=IS{`H=3}acZuB;^(6(*B>JN> zq<6{GH3KA#$SL_Jr>}6)BsAh5uxO!Q8!^Vhvhthr$1{Hf=-^*go;<~tyAvEq$R2t4 zn}f(Hb;;JX)3+(>D*}!~>=OSc2iG2Txb(Y%VF3lDqH4)-Xd$vBWvUWWxry3Tom@h~ zA5MuWDwWp!7OE=$Wlw_I)ZPzYTY&$T5lefYO*tU`EtAh&zc*Gv;OxI;p>RBZ%Q~N*<}a0E_Wb^qQF<9C12TXbzzkwVf5Efo-TyZF zIpv=L{{y%T0SB0=FM_{0QfH!bORuOGosS7Z^M}9}|GO0k(=xl2Oo>xyncc=lCONd_ z?+|0t9=V7Pv|b_K&;++0E04AkYtvs4xS{5>?sdpe*Eq(MhZ!^u?hDnZ6Se*U{88Z5 z1WjTrP=<{D1=Wu)51?NA?>{D1aUV@z1Y(#VO;M()@>RdqMjPRe@uvp-#{juo%{HG^ zd92SPM(6zkoK~4J6CIqkfCuyybML}0Ct~B(9IO(*E$|Yf`yWm!5_jmPoFk~6_#hR2 zt^X(j!*5PqCw2_6U?Q9ymhQc92u#sRBk%a2GJAAlyq*E zAWw)F!W+@E=xy8~>7N3M-YY@J?nURr4WP}|vjQ;h%+hl>a=`@=gGp?@_>6%2BZ85_ zN#UjQviaBmYyoxuDL`PoOA5R4c=Vx<>HQ#Y8LqF7^>dWi3hpeT4fL~h+xqW-4Zued zVu`Rt+F)({DNwQOQuPAv?S~7{4&{Wt%FtwJGqRc3MeU~!QV(T@KFd&SC^M3s$VXk~ zeLIWsME4pA+kTOGJo-`l^C9fG5EHcG02XJr!}#Vwh)3y4KOz4Y^!@~79wkwm1R&*q z!Os&!%A$6Ef*UUfk*TO$Tp^xNFQhlJXW85T98g1oA;c193%5brqU+Z6?*R*f z|IdM{=gOFSaj0iTkhd=v<+ms5Qk~R#ggXDFi3P}A;T~r-FwbEKZ57B-YEv{wVMJ(k z9G0%H+@D868UoCgXszV0l<}z8H{J90j5C}tKifxXP_oV)Zmb7aE@XPeyF|Q~51bqy zM_O5%vRz;HEnK7SZBZ7S%sCceWO{c?G?sR>h?oVKIZscRV1J{(&|d?qX&&Cbu#nYs zPWI4NFXuVBqM{NL#kw)VLun}R28ufF;c+y2L}~1`HcldR%Bf8P1Mm5M-PiS5NC7!B z=G>G9lS;gFGC`v3|G@+0+J$Ex9UJid%h_g@KrKbu#wk=;=-gTo!Z5-Q z!Zx;9t$h(MQ=erQu=fTC((wi|V2p>fgT9hMe(qq2OBvMFWjL*?*UImOz`3xhlJ_MGF+GFzOvW4WoU zC-Os`ZO%$nws2y(2Q}0%E-Uz4IqB8HHZwuK49C1u2|s<#iuZMMMymg0k`ZG?Xj?k0 z#zRdcOdYbnHfpC#Mg^jEuy&}}-J!BsqIGEsD3AUJ1JznvO=J^%1jzUg^Kj! zDB>wo(wgf%xYP3RxyQ>^M(T7%WDSS6Ko-UPg>17?^gV;wc5XwRq?c?N5bF^d1bbSB zIs5@cbDL($DN?YtOeM-_(_70Y{4oD^Kgcwwa@Zh!(8cwpz0*Y_L}dZcmRN5 zXiG9({Q9SnwCS1hBv-9AWiM~dqj#Q!HE%u*s#93mV&V09(htp9&|XMVZ=^fa%&-tk zKHcEpvj@Q*R=ub?S`sHgK|)H&@QjDv3TuCE0w=^O-EO`dp*Qs$#f}~5%XX99xV>)( z$h4H;SN6muh0_pH@5-^LeZ+TGmgukk5Zhp zjf1JRmA#;;u7$Pn@A_4OGPsL|BJ%r%#l_xTy<{BA+7Xi2*IFj=v<6WDa?w;KX3MGg z#P|X!Bds_Q5=Pzq0#SH!^O0PFTmrJ-+*~|yz!dUulqF!GFfg)gDu5c=8nV`dwwG9m zK_c9thrRTdEc^53hgJ9SW^0_s(*{7BJi+fH-BP!V%_&3F5+KP$$wVoq3&E?yyDTK+ z$elBjVH>sQpTw;eE(an5 zxCr)WUl#jzmbysv0IXJS+agOBKc|?ilj$10#f$FjI+oKx(VZLBF7X{5Ir`{3_iSgb~^G7S5x0T^%Z|;8D88 z=pkiHoDG%(krb%3RVa^ygX4<4CGVfB%K^inWJ*+%Y=R+0V67KBY1(U3k^DWF9LXnH zOa#Bil_^5xi-cW@gfWAkC{A1o2DWOb=ct@5DlNM@ygd@V@(;|j2sC=1)BQL=4!{B* zt+G0NltTt3aFZ)3LJiEY`+jI2)1K#LoRLuBL0&^Y5JrjPqn_h2;jB3wj4e3TrrZnz z6b2_Cw{9hkABe|C$0&o?4HYMJz8RKN+zd)i7}X7AwEJJaSloh3gbFq~r@+^aa3=Vx z`Y!`?jpNvDR*%vkGz-Xz|1bt#?iMEe68w;=ROKhUZpA=!UY2t-Z>Cng8Fodz&Tn;` zi*LtRzZ8y!>E5y&zG&n`96f^t4brU+Kp$64c&ma<(nr_o>IrCBS=T;5wKi*+GWE4> z9m+rN49S<(N~Mj*`E%<7$Pm|=-u$5rrv6msx#GPrp|FaMaOzBdGCF%;Up{KxIhM$R z$)qIkcM}Us?a3-s5AU(&yu}k@x=Q2MS z)TjvjzpC;$=&tK5cED4^L1A1y=GN3O__zY=<9rS}J0?u~o~Q|5)>AdQdAVzs$q7a= z-6aPi-fx>muM1*KEAFhA0+U$ehkT@C$X;B-CtgR2!eqdG5U%14URj|JJ3d>TG}J6H zu4~5<$C#Ynw=1TRyQ4s&yoE6Qbs!=VvX2wnbFpB@y-5)M#?clGa})=aZKfEL~MTzeiU7^;xzN# z6QiRfSisRXSw&Eh=XjBv__Zcj@k6G4|9OEG)AL=Yu8cz`#nNc8&S?tc-KA*h%$b7i z$JA8+TTHQbVzqaW=j@Ufjgfcy^hCIPN3W`2z?pRva0`b8A;O*^4L*f!r{;Son+EFB zHW;@b0QSL_M5HPU5cUD%?Q=8bVbiy+WKiv#u)bUyEWd)C!^DWZvRR=RGMoXOC$<*k zokOL_yt3STdZW;Uh$1RnX;nVw%pBdTt)zTXV|o7;Q4Lga!4jHbpr>?(d~=w(rHnAl zWIl3>4F~2lMLN~v+X=IlZFWLEbb28weW8NLEW4v!BNMCHj$`)R__zkf^>I7R@7Z-I zl)%^lnd?NL_7qsbbx92>^o-M5E4BJT@H0a7#nXKhvUy>ILJ0&)C);Gz!l)u)0kfk6 zX8kS2$d0p+g6%Z(p+d88CjPZ4={>s|B<{(lhH)V4iiDsH_TlSJHYmc?O#NqH0<@Q`A2jY?U1yk1}>?afZ}YiY1eb=}itqg@Ny;4|_g)p(is zX?6u_SPaz0cT}q)%1K95GT2Iv8ZcwdG{*&qQcp#6W*Juc-FTJ=K^+{T*CJ3Sze2hS zGF1;Tv;-DCiAahsti;9pl05Ioq6Co6q;+^rlZd5Qo)#h(vzUsheewe}P#>*bizvxd zr^{p^mBgtAD8v?!47?dR#EX-``w-tv!tNkl?@}$O!%VyZR;hBSBTv9WpG~7D{93?o z?MpkkW+`~65Xx9ELl#5z^?kN3SB@WApim}khQ%Z#86K=2$}?1o677lFKpS%nyomHm z?i-sn`)y1^M64C2_aF>7X*J`)Sw0!ZXtYnjZEY^<4~3>j@S>P7ZP~OLd()d4?6#Gy zTTz{xS}d=Io(bE>W|)ng%XS!^iLC>USAaC>JZm4wE9%@05`%653>{rv+3|d$+wR=Y z5;PJz5O31d68Nq4bRnkTyQj699zlm#kHPbNU22CW`P!x@bQxahkJaF)F(lILz0S7u zI#Fyg?AY%bF(WM#f+%k~{^qpQF)OKzTp{RygK;{A&_<$kD!0>f*L|PP zfne~beCM&e5g3f}6Zb&!q`C7x^s1_qfRney*N+1UV0AC`@7` z^6&bKf^-3Q9)<$85M$*_sih37(Leh2veI_G>d045^x$6(p543En0gP? z?RzkXR1#0ho!+~sa`E_#^=ZMr*?KhiM(ewuW|vPWB~_KHR}U22tJDwdao&H$%;HL9 z3H^C=Yl$qooL1M_-Yk;tX}MGF(O{tNTaZiXoG699Hf`;8AQ}p))1jx4Pet{?FZx1Q z2r)j=-fb(b;+=O(Zrh$BPULB~1*mJ#Ks6QOZKe9< zQ{pzZP}roIGs{)nv28Bt}=CR{Y$bn!|)Vt9X)ux;WK6Yp$#hNvYYCX% zVuqs8k!&|B;VJGEC8%~7s-(#=8#X|Q9C**zL-}OiBGUw8I?M?@?#v#1m(Rd1@O>`e z#4bzgMKsFx_q*G$V#cIVlO3v!X^f4yq@sxUJfHM zWw=FyvZ8L3vANT?I7C8wrei@wJvr1}M7fo+CYAC7UVh!Kaow(A2(Om2o7ha7nqpTE zaQ!d0V4l$^>*qO_6&MiKg!uE48&Qj1y-(NnR4vajzzHHHz!adY+_}y>`t0MWeTqpd12o}nwm)RARP&4ydpNj?f6RUXMi*`(xw8e31})t4!b$vQ9H*DyBXn8 z7mOXYGK0e~8Cq;4d;22LHG^p{x`9nwVVx1J3DYbFJ0XIU**yY!%CNL{F6UshcP`a} z7C73vwoZs%cz*HbWvlhpGl);05>fw(H{wJ9GAwTM`4LN8&Oqn~9ujshn%M z%~5iocq|Ow1{luv-F9b>urx@INvS(F1`pl#!`&1KVXbcZ#vHx7KgxBGxjMS?GC~=v z((fBVBViETogYEIOD&s059UN(qH{zSTi%mEk7OKCmDb$k#^Mj61)8&QRp+ zV+KadMPM<=TPhjoQ9`JHm5yJJI1eN+p5Vh~rllz4&|k)l?`L&r`;jgpm$jlJwxaV% z;2sZ5ux{su4aHx=kwQ*`Q2)!h>7k$?s;&dE8B{>5`;hwT7V9uPH9VQ|O8)85BAUJe z&4)IEpC<+jq4cTv&V%w2vgBxYzXb})G|GNWvIy*5WuA1Pm;BfP-`bZ7EeL6Pi4W5s z3DpP=o`D9U?${@IVkpfAA#5}iN)*WjL1(%1jx$)Z6($qBQ9zQITrK5DmeWgkd!$v@ z(}V~QBt=O|W57tyCfJrYcKINPo@NYCx=rQvLapOsNx0E2!q@6UEG}_u<+x@?wDnBF zU^A!mJ?I19bf=_sI(7hm6}Ba*sw@2Sr%#Ole^pq_KNVI|*VIbbPS?`#pGB1&lIo#@ z^R$9A705Y#k%BD%n+9Zs1Hh;7=_c@LYVG<~Hp>?>a;^Fm4-S<3TNHn|Brp~M!4eM7 zg!>J{&DGO=B$ZP2ZZ0Gu@Gjkv9>ffc5!NVsvi{-x0t5L1n((Wi8`*h#S;H+%v%+0+ zV=sun)-B(Wd5$6PP@0@*dmo*a=$IC_@!**-s&CG&IC121d0_B_3n7ugWE22S=8a0K zJLqW2HIxq7IVJJ-S~O`0o&i-kuWJTWf=jkxzLcN`dLOlI7oGA|+H0cwtCah;64}|= zVmue3x_r2pA)Nly>(eIP@!u5aDm>k|?YyYa}o7Qw`(9e2i{bfB-|5VSfx>g1jhW5YLQgdoW z%8wTgWHW{TOP!GV#GQgRuPZ2K6&jK}>w0RvRVs@=2}=0HegN#I0J`zFI?PSqC!@tI zV6Tr3?;qdHn`*YE1L1wqg>A#X!TYjm8J=huJ%vd?8h*kC3;dedBnT8Vyubzq%pWvj zdr9U?4yz7E<6JnkCTP>cd#JQy_qkC5$ht>85t%`N->ZhPPZGj232Gj2>2 zCifI){*A(o>QmUn$n!StuUmU|?CF5=^VVYh<*mj0^q*%SJ>CBd!4)Y)KD773a?KW+ zz0J=)xnx4(F;?x@{5_KO;6{X~#2PmGMoBzpKWfBVvLzeH7T$n>Ht(_m34%LtG4L0Gjk1dw{ zJDfj=3~zAFQApO1iuId*#PAk8P)q?%Q*8SVP{_KeXU`9oFD{~zIZg{8B!esPPl%A> zLq8ax)f#huB}Bg%$zizfRb^lR!rMF}0*B_P9%ayzrjE*g&mJ2#N+^uWOiX15Ou0Rh z(J6q(8e%*eNm?#q6szm(`64|w1c4~g7@tM3c|Scxms?R|_JL=a!T^hN?pFN6(Plyb z5ECX9hsAcID=`SggJe*7ESK7K)a`BUGMIq6>J^sDXPC*B7AO>&&;uVd4tazum#U1% zg3;}S=fckRZ2Vj94jtFQ%lO+KQu1+JgJu0LD8P*VC^(LH2$3iJ@S%&tFgDi@iVub$ zZR^m3HdE+}Bwb;jq9D_TGLL1W6_?e0$5v28{babtebilTLs>+1{)#M(jDI%e@Ey|Txs6*ez` zU)^G5dwsw8vs=Uf|F0X9`S)gVl>NuXG%vy~bKE#t4pN&U_mvI>Q{+Rx&H1@8p?_^m zspEHf-`vMd&_~&ANh+F6pxD*)Rr~Xyv6q1p%vhDa*a#d6qnPga2-8s&GL__dx`AjV zYII~usJLGXvm(Ptgna<@=fbS}xiDE+(QE3{cuy}jkFYfFN9cYSaq0+il=DI~^A)cnA??M#A;Ydi~mZw6l=4Q=T)6hzr(M=_h^w0^n zsBzSte3y8F4?!jJj<@jJfIoOoQrlOj_LJ>qa$mI}p)*mr{n*FJ`c>Bve!qpVpLMPI z%PD~M>3?6C|C|8w=GHTGNL*IpJ^b^L)d_Me{dv3#HN<<6UxngigotHazh(>@vodEC z{al1|tuT>-LcuCs~~xAG|o~CM#@V^}s4Bjkds; zEEU_Ss+z1b(2$OhtkkP|WXD|S3tWM7?{QjqFl$2+Ez->j?ZMJQLAtt^N=IBd1=2&X z`LS+6Im?5i>sSm(En6yd@h@^A#Sa61X7?%hMYzn%q7-eRh7rJPQTPse7Rlbv2j|p%hj#FCwO2 z^s_;E$|a4coDSJOc(iPV)0qxuAS7C5tz zL*NQxPEhBAri5W?x$T@ySVEG~e8_b{BS5NtyU`+FvYaX6X)0SLmo}xsf@-1md4FU| zMKENWq1=g#C3x)>WZuG)?_55%R?t4i?wd24wEZ4iSd$VW3ddf4-j3cdvqZDm*u-Fp zt^cbsQl!oPo~=Ti+n%gOdMpGW;jX#r!{%YelSw4(+{0vUTo=Gi%~pPpVGfQVd=Qi|p=G=!0qm#*v&! zZAla{S?I6DLHr&f&`yRD`}%Z~k?P^m(M}kqNY#AUE%^D1L`!maogX@AEzCYz%Uy)T zFmoXMM-@(}`$Y?JJ0XoC*S=)+kPMr<%(JiwI-H9*MM)!iKV`|`9%SIEmIFDOSck%P z)0{={V>&DUG1Rl{j~+-I@!AU}`~J+&PXum!Iim9 zlFc~Y0H6n2F!1`!ChQoYPNXC)4j(p)&It~COr%G^$#0q z@Rb+VMR$~dQgun@{>it7e(|m9pL~mmymG-Txd`+$x9qr(-eh`G?I+=4`boIV^Uc!k z8{|DdmsM~Q-k8w0GhxzXPl?=^1Su0RFCMGM)#xHb9YZ5<_1pa>+7v878pat~*LkrZU5&4k*K?}BleR7L|#bT^n z8K*AgEPa;-1;An3BpXS8vI6rKd4C?icizB< z_V91KfbKV5&_@rg9wQ;ICruod-%{K2ix?s|?xo!BnV-#|_bqSi zBp>V>1b`Q+55vIQa15EC$*HT>dq=ZKq=Lep;E35^TeuYK&hV}Epx}I2yr29w0kl-A zT1OnEQrWq|RVV{V^&udgEhnh~>Ekg5rakz>ppOBHT(T@GZFR8U``Pa9bpBg+oR!`9 zMaIhrIo%wo<%ro(6j0$nG9u^wJwhUNWYzG;$X18sRXVHC)*Jii;MFbNm{W>$s|9A1 z`UjNk#&hs02PR{Wd5r!y@zHBHcdURft94}OK=PX?8xhsZZE3}JZ-92%(I5WZ?i#J# z_Gf39`(7`YMo*|l=#WkN^eC3&2v&&nkY5&X;FJ>j1kMa0h3 zKt|Wf&_dv6yExeWoB|I2=#}U$sTE$hz>f&*p!`4?JYKQsXr}xS%1gkyZG;dMq|XS7 z=a|L`RCX2y=>XQV=CDcyIM1Irk@Sqrt%@nfSZni^-agg_ig>(rx8OjLfMAl92~ z(96P^g%heH8v({X%)q~=B?T~~KB2~$Bg>2&!}goZbS8dgL(2c8WtFLX)0TK(mMI$j zbwj$JB}BdMB?Le$-hJH~%$io9%iN%<%?MR2jpnl_axTlh4Zdomyb z@Op}{Jj%fs*AZ&cS7c3ku`tB?!)gG=DIzG-mQte63$jpeAhBez){??WlL`67=}=;= zxYHfvw-OT!O2z&xvHM@n0`&jA#Q!L)(waQx0`iAu-E^*D7YPd)8XdR}s=sADxNQhF zV6_jLz$?5)ReF>fKcpG~5dl!32TMa)e$JCgdLg6fz?cDvZlR~C5mf$NUEGlX`UHTpeu1m>?VsGMCnwQ;oQ?9GGgg8 zmwtYrB*Pnhd}aT9|NH<6wZR`DxybUe%aV{o!}G{i!h^Nj)T9RUg505QNdBYXu2R92 z24Y`j+s4w!R2ONN461Z=;guz+RBxN9M7gcEfZI%_o{6uXYC@DHUVD4XAo>mPSu3*x zhfpAuhcK3oX0eil+7%>Gu5SwThR2eMTa6t^>XXH&;#W2FR#T{uLkExvti0CYEz64} zHK~aM>%YcFHMus$|AY12u( zEPB&vEy|dF%4OU`3X?LDSebWrILB%ysHO5>&$C#q+L&y|-Z(0bM-ekr5dk#cP{^Vf z9Y?-~i9-r&=O9PA7i~RvB8ipUW1PMbUYl)AVKzO}oSRqC&0#x&YThm(G1-QvZ=8zQ z;g_oVvf^W~^YZxFwz^yg6LymiQFuxX} z9Y*EKBl^0G$$Mv#xxUP3kpJt~L5O~faGm%;C_6XblEUkmF9ZD(SA`*s7HtvE4QfD1 z6pq{mI{+jSul)1QLJYb)B?GIO655z5+ptw#?xl{IvFCADnB? zu?F6-oHMfZrKTW!pnu#|b>dtt_;(`Mxe@m_3A;un3A@F&!ux-rB#&Ta3E;<+$ugV4 zjaAd&D@t%!6gcOefP>vZ%l-oXoryGuvTkRmV<$>ynt2j?gIDMkhJOee%^WN)f=B>A z#IPcVVZEt;QPR9>d(6BzbYZH0eKaRwstW)ru{CV(+?d>wD&MaF%cu@iHF$UatPjHO z1jg><-X2j3193XNu0Q)7KK=5#{1Nu19AI{1`=l7>Ol)0P@|A_cT0g1rv?EqkAY#y* ztBY&BMr5~MGm|Zq64uF;v|PiL%we{eaWH71`hidpu3}t8WbL4s2gS-7Y(w}v=Z-sN z(U3xb{hovL?ziIeH{p7bGK+Esp_$9iFb!dju3`-@!;D-BpuN2-taiAXLbaEYCnnrR z%qkLK4ycDzo7C8pYhh;lbvmT)G4&txuTa^5N3NjcgNp%MYIbioZ zatL2Zb4JqIqG)gVwxH^lLZi;{g_i-5%mRKbMQr;1d=-z;HDiV~QA|`(3?*lVV#*v8 zt`?Z5)m!HVt$GKe;fOd#{4f(m59(@eH=(VsUu zw*4eNYW)pa!+4g@jIgOd?MvSa*fQ;v^~b65W0Lp%cQrj`09$}%ZzSD2WhLiWn+s#9 zp1QIhV2qpsG=k*bKy5|Yk=Gi6nKpC0b2`P1PnbYE`8H$R-y%SI29iMc)Rrzr5_o#v z{45EI;ra4VpjN?3=04u104?3BB>kAV@Lo(@g)hpl!`H1nRXdL6MF!=aCsQr7O?Mm{ z-|(CEv?4)ud|HK!I{nqC>{Z%+@LeICc&8}RY;kH4f3MtvaL?SEIK=Yis6^bn*n##$ zZ2#`Y(@N6L;!>mdz$0;lzBU$(W3I(Yd5M2DH4up|IIg-T8DJm271616zNad*t(k7O z5_GJ7``i$zdZ7yJN10p1^x<~ZcniL<0A!uQI&`$SXn>Z}b7Hb_eyLf(THn)TjKTIj zR@;LMylmH4TV1)jm)`RT)n*Dd_Wq#0+>ePBjYH5ii`2W`aDAB%i6dAKRQ8q!YK=*K zfYG7NmS>%62Yj#;y|Q^6jM?8A?D2EdJ9`r*2I%K9zi)GVKg`zsP^(g%^QNSw_=6k| z!Fg`eJn%^t5?urg06|HB=A31+W$1UiX%xo5#M?lpkG>;L$7 zSmDo1S|a4K9~&9}`kQL^RiK+y0`$`-2k8H+4#V<4>|ES>h8OOg1>9DD^|mYT7B~Rp zt2~AX|2DueFCEu;bXoe8;*_>c!K=Vz-s`d7fd1moDY9~4sp(-hm^L?~q4ly%Bg(W)KsWR40&i0Dv@{WBw^1coz5=#0knqJ9+i%#L9U8L|m|?u=}x2Bwo}>!tO@ z>N*FwrAJ4u5z;LS7KMJC73ERoX4V*d3@)+g;&85B$@raYRs@kWVAXM2>}2|3!&*MB zj`B~BF6~FARCMCv$mcf?dQXBYRD^Kg%UEHoivveXs0hRFx$bxc4J^J-D2$h#!;rIs z&oI(BZ_yU~82wgvRx0U5M#s^Wz75W%Kith^+{)Gq@TbsKOIMpxFm(nB@k z=yg_O!DMy9C}{pdD0cCE0xL`L{9 zBE^O67S=@lJZt(dz3xss*^z21wNIsip0ddx@6lVG<9EGI;F;U+7dsdJOLqPrb)A1a z!a2&VSArCHF9yNU~F=0hc_y$G8o?y;euO?l>NPNzs1?&P& zPwjtoGQ@=cGgAu&SIz6$72YmQgza$^j|XJ@jxz|`Xo zQ9+1PIJV44fPsz+JlmwJJ4MTgr2M8A(QLG%RM35cW_M-~erpjVws`E*{;91@tIWhO zSeyyomtDsuJP5e?GB0xCFMDPbV_o zk`cfH#1PdROSY8vBcsxBEJdzv~e>H6V2+QAg3$X8aRaoe*siCHOfT=LnXPXCdl zZo^gn1R(pSjQQ^fzO$vt=R2^!xFL^Cr# zcnHD_sanu}{F{^ma+e}e3LO~Qxd7FteNji*zM)ZSG|HhDku&*Rbel5CfOpxVAZJY% zz92UxJ^}?^)98)i{H41#cZRi+-2)Eogu<(P+bZKb#8?EwoiE#D!y5l%SX~ z(MU$KfY%Vm1ieH6{v%{Nl1(?c?CGFwfXgd~YYI`!T^*%H-wZP}X71J)52O*DTjTz5eDsKna46G2g*Y{FDw zIBS_Zz`x4MPhYSb`Tx~&{=6(i46O|9bRDei6in<4bq)S82jorV5&7Ue<0NZ_Y6c^) za>+vRv1G4+1mO{YV!w&@`qqT1b;Bh>v^FiNJj&m~KB~s&)rob! zoO{j8+`LRYWXaG4vtp!9q6!gici%!X;*IJc34Aqa@@vI7*HyVZ7rEr^5#XG@M3Yts zH!1Eb4y5Nq?zKgpP~cRi@5*LZ9APL&08}>$PMvp}lT0xjpG;n7TE`5j(M>>bUBDkF zgFh`54=10|1+&J4Y19ZzytODDbw(&CO<hOt1^5mfF2cHcdHa>rpw?=wAXbj_D8z z+{|wm_C201?5mwCS3E}wSCr1xWEu_&)DLZk1zCfx?Vfb~zRT3uq~Fvazi87`Ej*3H z&a#yJb%Lz8#~7DBjzg&9EVV&scTlDJG)r(~MX_kG9fmn;n1g8cP4au1p`s6r_0Ya8OUH&o@$ekp8d+voHg0PjEdwv@H@q z>qJEmR$xUa7k!zQlS|<3gXY68mD6q7)`GN$5;?E8B*+o*NW)Ig%#`?nJuPEM>Z9`* zQIH-Lhf}-27R>f4X0~sfI4qGhgAv9dgIJmz8&Bx1!oo%lC7e1eI2FPf6>G*x;=%8e zF_4P4n}*5$V{54_$r*LEeh*V;%TU<432uZ-d8NXAh>NZm)xeYBkLshDwof^6!d*#U z%`iPWym@dMw_{&J%~2?uq@rrUdEsiepYgqz;HDd&G7J5`17Ij?;I9a^G5{a}G7Z4~ z*nV>d>jk~f?gf2-d*yfeq-jNgxLMf{-a!Z>vGbbl#Vj#>878h)tr*&&ONg z4n;?_1Sk=M?@@m9*<(a@Re7>PS?&Dp+tP^1bCq}+DDX{DJubq*xx9cgj zHCdwmM^A^zByY8|jbB2Cb-s1L=zm7MbtsI^;}ow`FO&ej(zy)O8imjm>Yg96-YP#; zq}-#)24S@ocN)BIMd7>X?3m0N;turJu?3bG1{ZHiI<+LHzeoM`V@x5(mFE39U(132 z&%!FhAB9yku9adDY<-gPeu%_Qb{^YSF$ai#-r;3?8WocbEM0U;){NB zk4wYTnfx@aT zeV=AJG$|>WOR|lM1XeQd3gL|F;9TI&kp2F~HSTI8rIf7GvUiH~xiKz05WhY_@debh zC*JkaWhwGb+dcZ1!1!G z*{`=jTqx@bNB(-zI^wZxxZ<+fHzzq(I8m|@P%l?EuU}p+ol`2GS1Z3yf6y|* z8OqN>>R7!QZ$Ef_Sgl>-i1PNjc)Qdi$w&yQ+}1_MiP=hGI8}CK!|Tao;3VnUVc^{A ziK7_r;=|2EcsB*^l%q$OD0V^VjM@5vo;lG2=_1=F{#fq2@pM@eTFpi_*!i%9oKyLH z37S*+blEb=^L$B~V@>v08%q8dMrTdoBHriFMm?&n*yiU9d}9sqe%|9wA$HXPg*$i& ztNJ9OfaBB_5x3!GJ)9AS*~s@|uOlU15bddr9m>HjVw6frrWNQF{Bo_iY* zTF~7lAQP-GTLa{(@Ez$`u{zZbX;@KK$t4t$c}Eb~1>M=Qu8+Y+g9}sK6!2;k&!2G%B13WL+k^INFb~mi$8M%PR5kE=_yf$4)bc0wd@IXmnDmA7{dm=rEm^zW^sB^4 zA5WyA&%u-e{bC}A3ti%c%oc<23C(B^ETqwF`F*I7SJ5jqGJ^-kg27VOYpHqyNDacS=<8ZiTK09 zgWq|eC`)^Vdv_2}tio}8Sf zyoQ^7EMKY=HQQ@?6J2xMK0X((SBT`f6%VmxSW;1ukC~LywcLIkt=bmJ5!l|;!hoOI zp(M2HpRBP-rlwsY7?;gpQ+M6HFdiMGaMJxQZ_G)YXkxx|IHbx@v}+*#q7JPFFjH1q z3brF&<0f@~eY$5bux}V_G-yw zH3oHoAqKUvPHCT3fRagFtP**hS{}2)z!%PJY?~?eyP`0zjotXA9}xnh+tz(U($J`C z;*zU`y-x2q4V-4@;YW5P`>%eQqys9HMSFX`d}F*yQ8Sm89wIqz5g0aM!Vz_mjE~V6 z`lPJM@Qm}=7Bd1EZ^2OwEr436Tl;V`hX%`qQ{+gy>5`Rm zpz4lRr~!A+G=8my)lBYr89c=u`mtSF?TWnf$GF7h)qH{*cfN|^;Ag( z2iFBU+8yZHVPmaK$M`f*V{-Ho;sSXyh7*hi6I+o=t#e6%z!b|%fEZ_m#26Xmsd=^e zF&x3;f_%ajl5_|VBlX-3MB)o;yW{_lv~LWvY}=Mh+qP{Rm9}lW(zb2ewyjFrc2*jd zW+l6-&b_B!-+u3P_w8T%+duajW3Gr8BVz7`DNz#ROXCZD3S-|D?D{r0e}-m~1;Yni zoP%*8QkpWHnumph?m0>Zqj@M9UYbP}s}LDc#q~B$VHs+ZMv28XEye1!C2P^DOzq2& z!>AoZR%ArkfjPR!uObsc30#Ejq|RuxJVl=Evmq1K*i3tmnS$S`H!n3nFEcmXsjii% zw^6PT1$^oj*Y+Mo_~{~*F0zx=`HOmu0Sai2*AVw2l0q}_^t$V7`aD2UQ;gkx!b5~j zG%}0!KO@HTkzD*V6ylgHhXNNj&r=fm;hNwRMwZv!Lxs*1n~rG==&!y#j8i=X5}Qd# zqqOCtMOJl(=vKQva9N1L_Cd7bZpgY;2=8elIrNBV6eOVXZ5-sMC%faAoE7yBzt>YfOK{`mq*@yb>=f4 zzl=%Pv|q@HKQZ+V9;0N#WE`kKNyT)Tau~ZA8c?0YIB2FRCM2J0^H9BS6?vp?oX|8f zMZ`RXI;2;=yV`X8!jbB$NS_)Bfx_{|3@<5)9Wpnvc%y z6e~n;PtkivSwe8?<%!w;ZT^c<4qLlF!ZRQ2Z%*alUeLLsXOBEJ5nP_yf8~ zs%fu{v@K3`mwLO|0fJ%u%v5*bqGSzWuGm|K^j1UdyD@B;k!ef|rcg8{NisS64aqhp zaqcEK|zmaT^NPbRSIHJX{6*(ft%<_adaRdI!DOv*|cwA49%buol;4CWm+B`;-= zTm8w#O&bi_PuH}zhhiC|W8Aonf(G455^iMeQeHQapgv7gEKmId$}@Q_xxZ#_2}QN_ z8HJB7*GERk9m?6uC0A~>Spr9`#%-v9fnomt!xcN-8oy5mfiwQy|&noXP$99?4$)>VacyiMQhVXQrWk)hr2Z!1LlqxY$wmh&A#}8Hm;*7cR z!f+W5XmY#sX1mj`-s2dfidWkFw4XjLEUVb9AOhJ6CLDNMg_>Ve!k3*NRQ)HbE$x51le zS8B#}d7DIhS}vNaf(gj|nmxWcz`@_QM6kUNP}A3ZUFX7DGa&cfWX$`tVQV+Z8u9g{ z2pD7NXO~KWw*$RwLODr`3C=;Pj2%5UMetl3JhFXnB~4`3ltfOQg&X`Q_%PD}<%5X} zL4a$1GkUd2Yq7srgUUCd(V+pDw=hsmb84=<_R*2(wr~U9+YFc8EBjqoiK+sUb&~gp zN5QeRP@LMSSp0A3@VgcO{MG;Xcm93z&^W2|dBw zQl{MCh_8W;e?)#Am#V2tDj9IFTDMJY>>a9tRRu-S@ki=J#?%%r-S%HdfOze6tK&}$ zBQdxfPzVg}0Ed8O`C)>mCxEAWDCiMAaq65Z$5!Os0NBdO*UoW~NOm;%2I+9{o|U#d z)(S4(^({XPZu1OQcA}Ldar+3yBUI?NW&#{}o_!ef6c&vWyDR|hZadlyY;Jnw3FFC| z?E@G+Aw#r-B-)8?V$A;t)WHK$l5h^``bvM~vg+8hH~Q1%;+T8%tcaJk|MB}h$+Wnk z>$eH0bZhcEM88;!OCywBWZ4fnM#x>MZ)|aDPo9iybZoaeFllLsH143rYHyne zIBlLE9l_xK(42z#YmMhW`wZwpeP3KAd)4vSe zJFuM0Udy`>El+|=P!tk#DvRb&K!=0?fONfclo&84SV&fBOi3!bPY#+Umk4M{$xQV` zc`l-=*MgDXYQNkjKb~e8UR*WKINmjMftYEHxggqY{5B*>X*BpARAn;2mnQBQe7eQJe(T1;+d#Q; zUqI=p9jL;wgRgV1~tJKEjI$Lxi+2HrMElgmD$n>JAJM?15x{?g7j z)?MSxe{1IpsK1vUhk9uyG~ZMHEIrig6yDmaasSfJIp8c@zn30D|JE4$pFN@=BSp-J z;q&(x`_<|q-^IQZyf2U_LS5cerOZukq)M~|Gfm?BQs!MOpx{Rz{%$PN&R_u^78Q0Bc|iUTDbmNz?3S=tH}0b8GJH@To}+q} zS084xADG|dH&rADHwfjB1hVT{0?(*GsqVf^h~q{)%b~aqLJnw8@gMVE-auc3=g6;b zG{oU5ZOBJemGA>IwpEv5gBMWBRLy4|(hE`b4|yTN-NKEPo15LJW5U|ImrNaTRw zQXeQ0O%kmH1L`zb`bZ69_`O?`!lqkP$wO?VJW9EN)*XX&86#rEm8u(|944%eE?Jr# zL-H^tDp)B*o3#QuL|2c>ezl7W{RWaBzMOei3=m$e1YZOvB77Vk=XTpwMY^$Q&CPcD_8CYH66B!zD37IX;UABCAm@p330v$o1vEhVb>U#+a? zD->J~0n^Eidy{b%p2F>~g{D3f8ySNP2JjfO6z(z6x*LDS{@E|}isuJ7{VHJUzZJ{+ zyLei1{R}7{P^0>AR}tu4q8H_?7qD-@qw@ezv9&3~|yp zPM0N60=aZ2D$r1_Jc!S?KQ&9A?`b;D>qU8YUsaBsKlQWRs;8#cPp&pA!h;>oXO+Up z3jwNj+@Xjvm@iuulBwq7UF0g#DRf9CFVc#$$A1Cv z@L)-D$$m>pMg}jY>+hrx*8O4l{UP_o0_4#8j!ACnk%>FxbW7R=(QZrPcY>mn-?jq{ zb^|;fo=5qB^WE@Js%6|op0B&*fim#U&zqCde{2V7HN7jRN@ai94l2UA3FB(9w(l_G zq}4+Ri!Dql{{~=B6g=kyB|6umUjQte`Uijs7&!ZJ_HWu=XdLL_>&AB`zSqlK=dj9r zejKWILh}8T>8%4>>wC(vxVXkLrFiznz#yW zXShyVOQ=FhEPm+QNX;iyN`Mdi*&8g}%)>@{b zkKe>Gfql8#F7PwOV3idsfi&%frK!tNR%7G-pC}1p=4y*QS|xK`o#{T)vbA=fijfZU zhV$KB5#Purvy7n=%qQ)R;hM{&E!bI6vKjN<$ca9Q{Dl%qD1#V-Tdg( z_6c(m*PJ|qvUmAl-bCDYZfH}@+~%J578sn9>7B$q)v5+EWecMxY!67tF5 znxbdHVR|Ar>M)qg*dKiSyL7&VI`#xfF8C#su~FF(hQiGrnn;0Lk!1D+9rL3VS@JgN zMBt5Whu?-dp<%(X%{9$A+oEN_wd`=+%H+WvQJE);y9m{YpML7=fn*raszuNv)0RQP z4239o6N1MD-4Y;3DE1!DRW^UzAuM!WMhI;s6XDF`rhY`Y6x^JPBk~5aBCQ8upkZlP zSG1NIm5W|bp6Xn|332ECj*{fJ@Wz(R7YGy+7P8vDSb+f^QO{35W*UMh0 zRIyVr(tfw=82K|@VGoLCsI+Tc5lMW6imCLd3nRfA+$Ylfy-IPP>?lvBpL8CC#F0KY zVb|&;<5{Kp)2jr2@*g-NOctR;GNi=kjS(!5Yw98(U@v5e`1VXG-h$Pqv4iE;gXxb4 zEH;LrNn#7ZhUP zp1;N~vz9gAA*V}a-bJYmfQGnDpN}W08L+ON=qA<$p(|AjZOf?EI|onF8{;QwM^Ya} z;gzF)R-o2TrWw>~PD|0KqkZ;vkNmN%rTwgji2gsu%>Jua1Jl2-xBn0lTF??fvCmrs zrr0*qSrktd%yf675m4y52K1u1k;6F?sgFCD$-P=U*uT5L)u=KY6G8tMLOxqvYob`g z81)?bAiwFUW_^llUw+1D8!i*lzZN*ZA~@mqP3zYiV2VLkLWEwA;oz~LM4#fPV)(vG zCE=dqHbgn|$*(s6y&KI`&%z|8Cl~_?d=k=)?r5U0ycx|@UYCHsB+o39VkuEi)Lx1? z)1=B9w$B8wPbsfGb<(2?t?|wx8wzpd>E{=iOO3@CV1-mN)t%VG3_{fJhCLAA?%>cO zGzFoT)U5bIz0Q#B9k;Sr>_oFL%;m#9(oK1KrlYFT!}!+TITftnXYE+ zo2f6xd2fAMk7|6Px#b3jXtg86go zat!VxBLN*6)}gQvfs1h-1gs|}Y#D3@@?6k(fn5`aso>lK{-h9=*&rgo&^#-y(ChY4 z*+S><$t8}ZWzptPr^*jAL8opz++$OfY76XyTgFkwse(q4kt0nG`6hVXg*sQhgG=T6 z)T~f1n?r>;v^4@${Fu(h%S3hHM=nX-NL!~p74TyI7f zCWLu0;V*en-xxQJ;OEy`$O@YgFO6h4qo|rNPK?G@2=lNZie>p&bUB~@O_G%(VPrm) ze7MwTet5@Vvhm*7`8OYc{Uyk6>=1ql^7>zby!5vX@$NSt=n17_!}-Mr_WT2B|KbC4 zRloRvdQI;JXThvp{AV0;*&u?eAc3BY^Ng8%gFa?R5=n9>tk3X^ukK;PnQ3glTK03& zME3gxCBq!4QKw}hK7@2M$A}kDBA3tFvG1&!Ee0`M-FWZh_m#|D&eX?{Cy65Bk%a-2 z4HG`=#%zzxb+xedBeMfO^+}dmkzoK^#)0!_M5x9#Q;ki=(r?Z^*!InCatep*l?0FukW^5hk98illvuy>UE5fZI*@4u^XOmAivusH>TWj@Bf$`{;v){ z=YM8J9AW!oMbvCj7AMFr*iu#oVrn~4uGw0& zcrc*66OE z)RM$c^(G9ettZLYpcKUTTuIUgzJZL~iS1Lyr1h~c43nXX;cAKYdPSjK_{a??WQehz zJjtefpi;jxgWHb9!s{{aDUgDycQBT66te+nJrNPp+c2fUx*TzD4euCD<)ogCUFD9c!* zD2=W=d`XC=>f#d#lhVOI=PZ9S2NQ2EcuMh4>LdXQi+3UJ%Zu3ZcQwuj%ZGOL64~A z@9dI~99h;&+XXgXTE$<8###h@Ne>A#<~+o4vf6ZZktY-BhK>Q|4u;QId28jF~$KYv>hZU1c! z!2F+H&Ek9|RDFWtr7Ua@Xd*9g!;5PaEzQi7*x{9uN5S_D=#%7z90{!sEMYVKCuiQ( z-P=VJO*+|m@=YBMGpaM~%UoYkASL($O!kW)Suxc>T5m6QgjVf#()Rb{lz7P&Qux9b zDxu3~*;D9zlP^K6Tog^AaUei|6ca9S|Ylw9DrYvc?)2v){_Trd{#jCm|5(y1DIGjZ5wU9pL=hT_eV~Y| zQw-~I7Gmb|2{TB#-G5xRQwAUStEM*7Y-1zG8{7@*Lj{p^(kO8QMUj-!+-dd<=lU`E zTI|LRP16i}_{)O!S30f5u7kxDLtUh7m{4Z$lI*`na;-%P9+?JR2@$$I`lA;jsefI| zvQga;Hsj7)G@XYJ%G0%5&+;n!*GP^>UUJa$pCh?qSSaN^|CD$x)EgC))yrZ~bNf$f5sa0Gt0{0M!2_1HkwX3;_KP z14tdT_)wVmEIVWr3k%(913N9*q39r+{5vI__rH|$U;i)Xf7;8Hj0|jS zOdLeqj7jlrO%L;0b6w|`JOXMGxI{#>D7a&kj_LnCDEha!zo|9sC z4vaS<9uaVd&<%+!3xme<3l*HK$!1}pJDa+ky!_!h9rgY?Gou$*AKDQ?)Dqbi4DRJV znkweyUS$a0NhM+mxCBH4HuMCP>felUyETjd2pl4~gA0>|hl_o|F0+HXgsp%gDmHey z>!+LT$)|IEF*B`JdKvsccIcGj`yEu*YxH{a?TKp4i~MAX+x`HwJ5bu8QiYf7<@`G8 zB+|O!(Pfq2xe$Juaz)D~RA+?Wg(&v;G#|hYX3C z#5x&Yb3{L&VQ;0uHs^XJX2a5H^BJK%Z}}dD);X&5)Fx7fd6g+$WhOjmz5#dd% z7^+lpV*6zTS^tEgANZpi2~Pg~#i%OUe8r(NK~9{MIg+VCFvz3PC_iK38osQv3NACn z(?kB0Bxp_8!#pU;1fhd;Gl9!_t~T!50O9Wd%XvOT#Fqlvk^W8&qGp<9Yud+;^d|hR zy6BmInw+U2u03@;D_%Or#hb{80+Wlbn-`r+F5#>^hHq)El*^-HfLO-MHsm#+?cq@?@gMnQXB8baY!#F(c4opcClIJ0OChT2 zW;h`T6sl&}63`?z7D8o;mZM@Jrr^G~pg1T0nGeXF3VOcI6ws9Up3}hIe!YTA<}s-G z`6|}q^PG0qE63^Vw}%@>PVcNM? zks{$qjAtARU{^c#pf!Xe6lEDg`O(=`g;}a8Yt8!()2@gWac1M_D$0|)rG(1a#0RQN zMMuxA>RPUI6VaE3r2-{g$FrR0i@fdCdl%G#wV~jKPWGO8JFLrw{iVij8{%RF2T4+U z)Bsg7;*CmPKD=Do8XN8hTeAt1;5HSCtag$7>uC52X|eD9+zoBroeTFliNJdD4Be9T zmt38f5l`8EO>c#r<2ELR^~o<$$iPGe z7%YrH8-rqPSp8k$^w-7xc_gu^+2dgGOWotc+IMTrsZE8}Brve8G59vhp)xePIbpA4 zOzJS-{ljS-2x-zsjWqHt%Yriwqv{Q>bYa;ms>AyI9$fI4iD=(`k`aPQU3w&z&ovTMWg9j(^lsR3rXZH; zx;{oOt@i}Hf39dYDWx+Der2q=)6D{R^CaL6d;?q0$Sz#WFDg#LpVboaL$jOX3u^Ej z7#WrVS=VfAPM!7rZV7-+365Cw7R0R{hlt@f#Vd+vwD|QRfN-!JmG1k%Bjm_nffE1n zy#1@%3IBH_6@r|o?l0`Lv^h8)eMUVii!+}ew3rQVFJf7ZL!83$UW`WW66jVGw*2|? zxjFr=!KrxS{ogp`+oCnACZZ^JIs~OG z2Pkcse+I7UET+RHuAwDbbPpMErG=d(&h0M3w{12wEh*^9eT3(ILdpD9%F=ZvyOoN6ERWp=3qY9$n-iKsW|mSGkLg*C)qi8xxvpX&&w!s znS6PdO1}B$o~!obZJO>;xT6>|kw+G|Lci!WMV2lq$9NVVBWI;U!-0el`*_B7QxUpn zbN$!G=k?fXiGydnft9pwpJ;Y^I`y?>*v{`?X(I(M4faZm!u2KA4;0O(W^cCJT(fvX1F@kbgy$S7dt9>~NEc^o=+EehS zbWPQl$m>pAIm%q8Ol62*wIAxUj+n3cyHKq z$A?kljWzB1bg`^#f!6i-O!5l2(=?i;SmCBqNGY~9RV}fL4^_68PHsW!tIU07 zU@mrpZ_m-Ht#UV(&&q16uG=UoshTRG0N{i|v>o7~BgFkCRF2pL*r7KoD}8)}Wv4cL zkAS1G@a^SLJt}J2bWhU&qmm1!p;m(~hM=_I_>1q5ip-fyYhrRmZn~e{p~x~gs?cgU zS-VkJ1&Q_vcs(wN&n)_LzTdGJBZB?u`Aec7CZ43<8zAabN+D{dHbjQ63gk9??=kU< zxkGTka4MGK0uOR2tky9|W|2f|kyGGT8}~xd?Hjzfp}D+=u7+vGgZA%`DdSPtL*e|n zMou~M(k2oFY?3A4`PJsLS-C36zbkPSTdsEFPc9{LW#C10@eP(9A5nInbt-U`(5Ahl ze`usTVQewgh6}A-x1tNN@r=yq34wiu>xG*sPt|Yc2oeDf5f{k0Q#8ttXZeIQFEQhC z12QQNKU-MSR2UwE6exWvs@61c+HpW2jaS~$CJ{CFFh5PR4*7%uues`NtodqXnFo_Z zYB)f>wpJk8RyHFB?29?{WpXp;DL-ay1Jfh_xxuoYaU(=oQkUo& zQEQfKw@Lu1UA%9-;z{|EseNLi#n^Ud22-+i!1R3*+?Ng)-OZ`sgzCDM75jk5Hp80q zN!l)F4vFj_A+@o0qbM&pIUAq0R#OWQCmOM#|M0~ZL!;VnWE&>R3D@D>*3{e{FPb!6 zV+;)>`c*KmN4agrFCK5)V{qH?%#B*O)X%;>Yw8Dp*tnQ?PS$4A`GbMb3RVY2Hlc`7 zD|(>w*IFFvJlirN?W&z}XLr9D;TDmS*%*^b1qLjHuDvnKc`3?vI@;UCSpm(aX0C#y z1Ls}grv$cm?hQ5f!k6mrEfWQ8g%_jZwSik zmuEFzRPNO%TFhB8#^1#ow<{jgnIA%op4&aR>a@@9so+v_R`78U85+Kqxe2m^21r3g znJmxU&pY7e@q!UW(3f4ABYqQb*s&YBo|vc=;_9p_U$~33fDI}Ki5;i@aCm!d1o(P@ z?74-~rR>wA^e#%7v(9XFDjI8L>XqFja#tP9H(4JpBVvT~h~B~u*B7?MT*pd9B|8Nx z;OLCg!`^5}jy$aF_10@NvT(XYE z_ii4{=~g?*PYxfH?y+rU4(UI4>AVDEd2v2)@}Nt^-@t${y@~glhROvAt8#BA?{k~b zt9V;7Yb3>R9Q>&**Cf4w7FvfEUXz7jKWJ-4FjlX*_`Lk;my@|4M@Kf1*%4zFo1Csz zh1wdxNB$71tEc82O+Afy&YY!qsYVVf1_iVy3I`E(EGv$`Gt9gOWyo;Ga{R?}$-RwFV>gX#r!s{mp~7F5ZkBQUUgrLnscCzs=-lQPVAaF@ zcc6v*H)tuEn2EUA{bLj!tz>08uaDxhjdn6*L$Hw+kviS3!G#gPMgLXSOgn&(+1@l9 zAKIx3%zx4FsPvuG)+n6p3OS4`)Eub%5WyKJ{iyi@gt-MVMY zRXsnU0v6O;|vQk6|uiq(pP4_L@if2Cs& zvoDsj(bGVU%jt&Rts76+mn|a~m;)iI>E`-)sKAYB%yE5LUyho*DtmjcUM98J>i{*= z`i;`COZ?B<`s!sss4K@a zQ)ycuOIIAZW&GcKtEny1kERt9?i6S%o-5?81lG$9{Cl!60g$$u5U!IUbD18vW2KDg z6IVz?qjD&@J%J34V+q%SjYjnZFHjp!5%h$!hF9u?NK)d9!*EaSP*?hYP;L{L93rbF z^&_twL^L%U4A~YL{Wu{vw3S29!z74T9bMhYhs*O0mX*cm{zB#enK=9tEFG`}EDcYg z-_1drFt;*q;CRk2yzW$+Lz&Fdnq?8uX8zYj^Kdc!(h$Q6VJ! zWCuc{^{<}u_}T}-{7VVpgZy_rhxd2S37H!>2>tH2e-ZA^aTAgQUr<6mEf$20nl!5; zxCQc6zoOAmZ-I2i?e~nu+9h?3k*}h$;)qb=n1pc7U7KJnB*vzM zrfEEeRO7LEHV*?co@QP24Mxmor~l>aA%9XwT==uaUJ~DMfIBQhAo01pi%d?u?L(@* zt%_%0l@uOFVZ7s4#e-^LD+Z8N>hmjAcay{t?^Kg!EEgTH-(MS-T4$VfYpYLPSK87(}Y? zR|jbTO#%og@P$N(Db9SfC^2ZNd(WntLQ?<=%6t1fKhUawcqxBaQBGsnAq;KmluI{=1CF&fY#2>tccfKMrdbe`tnR%4$2?$+T{ zP291Cg}Qr@?wu1*cWB8c=K2g^#m*YQNFiOFcuLdatf)NoNIRXE{u^wUY@VovA)gHs z9iRQ4uwU03E+;MBz!Xq3h&f(s$&JT0L8vW?d15L%xH&~GJv80*LbF%?7j#Ic`Y)-Y z0;yonon9J#t=EUTJw#uK-Rfg&lRl^{Y94P``Fd2poddn`_V9hN`RHN6dcp>3%59Zw z6v)8#_DZDLA|v0SfwqY+=8rp4wP=xQ6w25rTB8Jclh4!9-Nwyx*gien2u8bi1u07? zGUtpr1-r*_SHaQ)x6&_V)fAHJ{Cu8pPyy$dr|Yc z-&$barSn{YoX~rzr)Ij}A^`?bliQz)eim>3>>+rk#`h%v_o4Xu(aeG`affZ;Lp^n6 zd^$4!wk-#LO|JW~DA#&p#&iqr|8a6S^WK#CNkXhAepj6ONrUkw!uN4@*bDkh{jomb z`*g$a^)>^rHT4O#TjlHd6I%mF#Y;V2tscU+UcYg*GD!_n`Z8toEQCVoC;}DL(Tr7? zJw|&G$s(LCqD9*HRx~r?9NREj8k2WwnSG|hHj0Iz9Cacc=wS+4GxJ{ zgIwj}PJpnCP*J;v>QjB`_!-d+la>5YrWH|i^c)96{qZ4C)R;C;hs)7$$QYTO z3B*(t2YUk_Q$urckHJBLd9-uOjxORzUyj5>^aHIDK~2}~?HegaF^wuVYS%e-p-T0y zAGRN9&8a$QNdzlJbmQ@}1zd;L`Js($O0?E;nI%gvMQuBnSSM{ZeTmmj4Ph*7aT#cA zcpc)Nq@zxyhWXYQ>?67jkAhu`1tY_Te_0D1pqfV}Qmzq88KTv&{w`sU!uG2MLOHtW zH(c%pIm-l6{_X{H?Lg9xkfO(XIRi^U^W`4hx#6Q_wE&1d{N#Cmc z7NYgGmSVUv{c$Y0sAmSl^KN|o_GJ&~98>CUntBa<01jpYky8R6d!Bg+mDzKixDr$U z&TS?DHCko7t&Y)Q5oz!G&F##NiElL172&Kc!e`jXY^&t8mA8ij6w#*Dso~8Mzz?<2 zEhMv37d_3?l?zsy`#0u=jYIG_NDR^pWN#=q<9D5zep(agRkIOwqaWr`%^Ylu2U>{Y zoMg1^xJh83md4O~zP-qr%*nDa2JFT`_ zHb3yj-iw=z!g$V%H>0hLjRuJiZ+WN*&7{$UPt zE-VOZPU#|@jmy$pk9vg@Z{T)>tq11{3oeq}(y`IYrFPmg4a}9Zm^*{6?PyL_4dyIU zObU3Ey}YCk&dOh;e%VdNDP#bYzN)dX}Oyye%R2fVA0c~PV@v*c=PE6)Kvd4On z*-4rNe+u`fIKF$bMTL{b3#zyEeD4WuNtH-u2I8C8pr)26OZern_4*bNQ=nKuB+A_0yt zK9FHCSSFQP_74>y>6ccnp~{eqGiBDOa=n=r7)rUy>LD|mNMr$rJ84$!Q!@Mlipk*F zI~l(8P&buTWzdRQWs!TtHevb<%OEVuw30r($uPmh6#-+8>G3NEBP$0f$HO9p60GV7 z8IN#Xwk3=(nP^llIbc$rWC2;oX~0T;rnLdx@3Z2&%Ypd9O=p%8@>(OXK+z5A`yMBC z`hYTH*5QYS+J%g8WsdaiUR@db6^g8L%89}qJF}2VGO9|_rv4>RMXL-;rhxP4OQKjnj(^~7u%`Pvf9n3 z?=4L3u7|#qB#amd*j$FZq;S=(CTs14(JkQB6{fJRmV(nq6qm!zV}a~ED;wx0j|KA# zD&L)^Qf?^WRIAZ4EMZ#ak1e1oh6ADjn~7mpZ!T$smZ@p=vf)`&EKKs?r+|oX*0%8F zaC5dA67pzWMjUmBE1~2z*Q-L5mGJ24oXC)>HY~rFYRby6wRS;H#zQEoWKxj}r$h5i%!7Q#v;r%K+>~oW zxtXVS;@(_IWC<&g+^&2~sg0%2%GxXeY5-EHq1dPcjd*Nz+N}Ad@R!7xZ>`| z>per1-+WmmnhuRP#}8GVU7!P#(edmnANMVxdN_@Q2{OxwC}XIzAc}NX2m17@{PkOr z>Ti*x`CV_ew73DhvR_)9$@3uS;Dq=$dm;pA>K zCWPoirU_?h5-sL3&*AIsuSm5k31_C3Czq*QP~Z#RGw#^_N?)(!q_*u~pj>;vn~Yd) z;>4-3tzqS?ohV3)7yI=W7Uc6m9XpTIb%her!pebgrYCs>^Nv<}5}h4nX~YJ0CPHNy-qUDTIAJtbyUCmuJDSi|vV@Z%UrLEw`YlXkEi>NGH`9 z)l8Ic@EJ*yr9+W1(NwSoXWkQIq+eP~iKm6VBI2jzD3_yCaI;iz>JAh?51~+2AxJGm zWVntRSwmSA70vY_*?A(Fg{DExhMlIO%jmc?AAA^TMy8`v%8JYi%PZqVpVx5Lv0RXy zlN`XC9+32nwjPSoYn&*fsH@?PX#&?A-+~u%%)DLKqhwKZSrJ8ec|W)m3{TaVsHbT1 zwto5u1wZo)=dM`yly;h9*`m6)XH9`RHHfy3oo>v#OC1k1@6v;+k(}@a6n>+-Pbr1- zrfS~j1bNU@ctzYhFZru@>~v9NpHYoW`hQK#?tr2_p49%Oz7DB@5r7u`kTVWbp3q`ZYud)wqj0q4D!|FTzrma2L6? z-NKmqMM5cno#4haqjc;*B?^3c*36UL|I6ULWI2@$EVtM-WXHidh@nvHEL z<{e~^L|1w=Fp`4H@3@@xf(Mx#8n-U^(So&RKQCrLcAP)XN_@|%a)CO%;n$x{^$zNq zU;;Nab(Vi5f_ZM#iR>IN1zf2mPBcU*AiL%V>)%(Fo{E#g32GK}I48`9&6urM---mA zeI=O5<2e)Soky5$4tEvmz&GEMiF?YYZPZ&3Lv!zf9fWM;g8|N$-pyQ)4WzPmv*SKg zMSTyGHC-3zW=P8qW*x-akVOW_>fgPbb>V6rG_l2Q0dDFHtl=7U;o!(KP-}i)a@n)+ z)Y)d#OlxCycM#U5`*nTYn>xVk7o_< z_E=v}I=C0SK%gse>Oj%%fm!bjjyQoTn@eU1tN{zH^)Ju?*VqK$vn`%DCF_W{Dam$% zzR1@)^^y0%z~L0-2Z49>?`^fRm?Wfs%$4i~Ox0Os4fc`h1#U_VSs1zZ90l@nNxBt! z5uPB$MZ2e5rrf>d@fP*`9VafN;;AiF;%) zZ1J}nC6*;WKt@Nob#Y)(Sp>h}D_hc$@96CN;VH20%>ogHEeSs>?hz+j_^!VM*p?kw zw-b8GeZ7$SO-K*$(+fAvllbkf`Z}$1H#fN1OpC@Ytu>QxW%BL|itoJSR%%T#eba5I z-FWKid4F{3d@f+S{ngKVbT>D68{2~3Ju-Sbj?|BkPA`sQ>X-GFr`UQ?kmjEd(dx?r z#LQyN3+82t_D2{1YmfwDe)RzBr%eOO3CX|~Z50MU0_ZsE^3r|H@S9K_gBpSH8bfPC zBfGC(5ne}{6?|XsAlg#_l{s-)d=wHAh5Rywi-^?KA#pBAp3B|kJ4vq%6(}ai-0Fg` z0fymR**3`NXLnd#L0&?SWFenFQVZICKGZ7-ZAV4i3LV)+D=LCFXhZ3;mYSNX5*IFqNPJ_>axPy=G zh$WlvWj&L`bNL#iwl6h`|y$Cv(6^W?t- z9_EAJ-|16ie`1z>u*(3l(i`QO#Do8i{sj85@148fLvOc}+IB_%IpG}v``R<0PTWcT ze z%56=S(_G@EYU`SNg3s7`Dyy;!PzI{|0Ma|M1GCA=ZBWh7P#qB)7NXo!(mqpPxo>0@ zkbJXYt{EI|?8bM!pd8Y`90&vE#j&P`l>3d$!D3ybj5tiaHBbE`17B$#t#pJ$K|1t? z*D#&1IBptFGI$8rl(lV2jf{{`oMx-W1B_UjBI)jFVYHA=^472pcS`HL@`5ySB+29o zw|TN(95D}XVX&qel@zNP;T((z0#cn<@up9)I7w}@*(A+?EffmA8Y!meH-V=osT*QU zW_O!I6CXa4ScGXJwg&)dL#nFCqs_RYDD+R)eodTcu~oa>HQl*~xkhTK4uT+Tq$3Gs zpyHcc?)oaFj1O7Jupr=A!BFVRr4^uA@d(!awr`W5BZ4>B?W8O7-WCGIDY@@Pn?3EU zJpIrVuu}XSlMFYZ+Fzr$98^`*>j)-`BR0Ttr>~L)sk2OiX)+t;w0Zl6NY#4C*}4ZY z)%YFC-13l#8Z_B%T|h-eG<<@>-fWs*8agg9*C6RRfX`|OFB{V%pl46fR$$aKD1KyY+JKx*B>0*J3NJB4)j@S@2uGP3oVpvzlJo7|3& zLybyR=S)taThSH)a!I$OKd&=;nlFOkicu1%&yS!p)Cc!gK$g&V6u2bxE#nwiFaaX% zmbIJ%qi*$MBTg-)W>8Vj!Ghrc)uXC71q~XtZcYjcgadp`*Fuxx0^@-a2+v<0OR?8Q zb4hdwyxfEPClhg~1?veyRB#n%v8ll5kA8HeJJ5|_=1LauNtEd{$}C3OX%OI=Gi)g! zYjQ9fd&doSayZ3kZB^*-qOuwLqVYj&eG_a80NWA8cc@K% zwFQNU~xA8}WrtbQPTmbL(r}6+a?%C(GP7NH4a1H_+00BP(nB~7H?@rrHAL0Bw zcI-+7w*cpiXuZ?_Vl$g*u;YoITX3#{|I8q+*5-quT(ci7IUBk5v;P8xSK2Behnzq+ zf?qK2XLQL()AAZe{Tq}?X*=U4?a`YV_p}N|Vk7O$qmRIm=3rNGhapyDHV|mK^P}sx zkDAo00O25>71>3&d3V(SvPM+{uvc}86h9D{^2tSzvIoy5$1g%eeOllI?WU5Yz>ayb zO6#(l^vgu$I`yFH-zPaM=C}mpoVI&K`li7L(sNRjcNCQ!2l0iz<;s)!N)moV-Ts7^ z-{7BD{6H3YhAulxbzcI+&f zeCy9KV3$>ls0O5%DC0uDQ%QXL;FwfhSro2ysVh6IZkRep(U!kV{%kUy+Ul1 z>Z=S_g*KSvZp>!CbOPOi$yd5(;2n6p+qf${o~3g-088YG^>Z2H#c>c7g*J%G&(R#HY-{r6xq zTYVwJCp(?Gl34Phv%}SJ-qm>EmAfqyFXWrlAaaUWDwLlKqSbzNpqq561$5}b=Lge> z#a9Ko>X|KG(uD6Q2cJ1uGvyURIQH;_MlUPn7AqXHu*Xa;JK8IMc{R}-*;$9Ek}4Ef z>mKh0<}oh#UvbHa_@=_Toeg&oumJGRYo|IqQDRq{AfnzpP)|T+9kO5@TBgOv5&c`+ z`NErun=`UnawsCul-Ts=6*N-;*YQP|))Vsnt&X!$X z0+p~b53I?wBN?kf*lgvo-JCd75~jLppE1vhuU&y5vCaD3mvxu30;^-x-*m)7#MTej zqe=5_JcsYhPh8>UK8EfZKZbmA(!kGGz|R4D{C@Jdsaviw z3W+z+wE1S|qh6Xhe`g$3VY=w?WaB%j*7lY3Mo&qBPj`7fkr)Fioa zzmT5M!j~8MH24S0sw})xd1hdjVY~FY2W*zAwyF&dVS#^zv1?XwdX;%c-)cBKl3wWh zt9@n1SN^(Vz2Fz96 zr7vu96JrtoLFE9G$_>MQth-~g6a9LZ&KbpJLt_s=x@XYZ5asdlAT8?sWpPUYXyj^^5MxYX+G;}bIw5soAIj!(QR6vKkCn@frpHy(LpAhjb!ryGATQ&ab z19~$rM_(Z3ztyoV;SF0Fh=iO$*kJIIVCki9c+AS@wc&(^jV{@u*$lSN&a)?6Dy>Tf z^;F)BJarwI$7nUcb22tFV(}YqTS&`?9fe<-tzB`dWtQ&RQ0Pi|GOn@$>JwBZdX>cj2?_~VZf{!tq9jM?6fxGT+oj&g zt8d`H;&+&e8J#VARNER+nVZj0*Hbg+`GnSvX%L7Z%$=Xe9bZ(_NrAi_2v^)l9N7uo z*UgF$w|q$M&umb@&rTz^)@2-*aip%Vjbh$j@qDg9Oyd%_Es0YI9kehE1UvWaqc4Q90V&ZS08g$M%vHnTy zqn~%HM*TEVy_0rYFWZql>XS>T2wp_0Uz@o?oj~g7=Ty1}i90n3uH^m=uoL-VN29D2 zLL&QxU`x>R4*dGJ&58;5&dqqlor#%`zinxnk*Vc~61&*Y$!)|=V3I~Dklugr-goiI zC&Mr=q%M$D(us;6HxRtYJ`~9P*8*W) z6$P@yxJd~cyEe{?nIzoEbLfi4{1IY0C7DWwH9W+dGaQ-h)nhee1{kW7F!dlvDbW?fY@0k_Xijg%vG#TZu71F zQ{2xtoI{45dCNom5&o`OKpG+2&8cK8u38Q(#!A}Qv?clxTI=}xOdiXw zf?SpzjXK=h%J|sVq2YQ+FMkM_X~gC##CfV~v90F#N`T7G%O}zF9*qzLN~H8l2jyO7 zwHxml-E}TswbIKuzO71Y_n{4r*=*b(^~%-K5H%FW3$-u2e4~ZKP&#|(U@i96Uy7N< zCTp~u!oeg$@eg~StJEPonrMH+Yjttg_7=^Y7;CGZB^7Hf{YluPNR=(4fdm|@R?_Et z?3to{%WH+mAW2I>wDZ0}HsRbD-m|?y*A6i|g&v{>zNfp^E~TX?%&&hXXw(8iZ?K7g zfS!5(-`qmd_OAbQu>aT2P5FQBdho;LZ9v6K%=8DMp1ZBhX)bu06GevnLjxX)sH|3z zy;f|0NW<0dr1S&RwgWf8xp#nFF!F?N(ml~q3GJlIDe+JPC#WNgR|F%27s#e(?N7f+xZy=pxJ z9QR^w;lIa!+iT;wZ!>SX7^i>BCjKcD((_k=wWO=|1jSfxOaO{UP)yO^j#_8v6tq9@}#ii5Jc2TulPawH4S;YwqqS8FPXc7k3jrGw(Dh=VS4pE9F!X70r(wlxl&cG zA7T)`5&^nkUdNHKe`^6;<>oJVGvmb>o0%@YR!LVF-AZJPNtipvfl2ysHVI=nvz)rK zQq)BjASGsbcDOGjeV;=HS~}U%ZL&8%U`Xbj^2s8x zTEq!K*IBh9XK+qXcoky9a7qFlVml_3o~41m(a0!whucl_X6#QiFF-aajY+PZn1=12LgZQC|h8S)z+qe1e#yEb=DqFbX07%TwrKZKkTo}gslA#5{h=N z-OKEXS+S0_XPTftp^HMD3&>_7$-xw! zk-l_|o7@~7Ve^ELr!qJEVXE7M&g}psy*g4d8VUEa($Q#%$n~>mP&xT1?6AS0hO%jowE>msL7!??-(l3-cdNlmq z*{5Ldzblav58b4-sKRBcSf=uDm?gcn9zIK#XelSOO=dVVx=1qQOG4(0DtRm%i(e(p z?bKw@jN0NGOg)AozvrywYnZlS-5Nmeh&;dqLZufs5!8OXn+FY%7>(=enVSf&Vw+&# zi6YwW0M-%DGQb*Q=ahk3bqY3S+7g?JW|!2=oySx5tNaDehNLD6FI6LqdNve-t7g^V zBa9u%hoJso3eS%8QU=*ucztT|G|!fm}m1y6txRuN;Gfw}`9Ff3ykxza1sQ|6gq)ZfE7{YUccZ zyTnap+Wue5ccicPI-0>OaY3$Adnpvgf`;gkplQ6z=@@Es<~K*yn-LoD-yuCA2m&$p zrb0D{?*F;+a0MDEVI};2=E|3K*Pm4|!0$7Vgg{tJOKf`Rn&n1|D&O1)Gz){PbplXD z`Z@t{I0%dkhZ|uPd|G4}obKRFzAeTYzZ1JEYaq;Z#R-Qi$tkbHO4S!st825-SX=#O(~?pA3Msg_xsF?cOsFK2AFAq8R2@iIEJ#*@;P$P>A1s8pQtl%3 zf*bCjP?|wO_u-Cw=AN3gWl~}$uKA*h=5M*Q!JuWu-^4K<96=ep7B&LhoyCHLXirCGQmq7_`a_^c%lT8`tr2#f2?C zfyvRJ)CPpf7!3EhZRO)Mhq-cAJSVhjTe$TW-Ic2FiH_Uln(U)aEm$N+oib&jKhjP} z@?`pGetWWV|8Uv%k!_MO(5qR=;Mp0IjR}mn@MY{T=R7ptq1kB7dZ|D1wE2Vn%PSZV zS_t-!ax(w7sQbUm=|7yn|E#9}TypQGCa=1vgvMVd|0zR-Bm|?b43?7IiUt#bCRU&_ zOw9x;mvcZvj~w*nn244TD(eyFqZx-Q>0w`PV(}OFn`-nkkp|o?A?tCb^R?^qK9Nwc z*DoB?se0l}BE&>43{p7`OHwZk@sNd#jElk)j0syvZW78^VuXHb0uaj`hc?PL z3KAU9Uyk)cBAS=UKZnpFCS7$!-fFv8el;!W45!l3QN`+N78})LK#S?>qDz|`aXzjQ ztwUXw5vIi{J-)+97v}h)Tv|*>ZoA!BGgR8s=KSQVyXWOxVQEJBx9$*&M@-237waPV zGzoqkjf$aJ*i7j`rUqM;$Vic5ZsQF!LKd2NR1j76@)_7ZEDl(Lnyh29a8 z7$XA{m@XpH7SZt{4daZB51HEuu^EmdUcx#X>h? zx0aGw+)&VN%T5#Z9KT-W2G>P%toPBkSq{#|K_)S0i!m35c0oH=>@fF1>kNxFZ}%7x zR@a_F@=1B=6})=8m7!r34-#&@U=hwd21FswtjPX^>!M|n8vdu3c=1caU)f(s+UrK@ zA6z77lxWV~Ouw1-@}mJ_IB;pqXVwjFjvxNNXW=~`+&r7$rM%3lfqxmyCm-_sb-QB^ z$Fn2)qv?KONow6a>>!fi@};8EEQugXX&G>3i#QB+?&4T1i2)k`+TX>3hnN%~88uo+ zdGPhyuZAS{{Cu$$0UcdUqB+-sx#K$dhjR_p;L*fmC1eA1fSKwuc zZ*gx7ZphymYEEdUC<3S)8Wb92Q;ROHJ+>dHdJ&6z|1HK!`OdE)|0nHIp36^mV&JOw#xU=Z#N?M)ELLC>xF zCe6*~3+Ma&R>nA)Jj8Q&SNm-I~0Z|`3Sb}rli@%cF1l6LB-EM~M3dgYM( z<$Vyi@PsHLd~q%FkbGHIl4(mY6J;!{v>7q545&urbmXHUX6k8%bp}Qo`V6b+I;8#^ zo{rZD3mHD2l6A@+-Qf=T%*_&?aJhEXj?a>I+00H-fMn0>%D%uBVLzxcUqra+%isbZ ziAlVSi%>^=tKKa#%taKoNHVSZ{}Y+(lXbx1)0D@oVOP1_`o0_2N&a3e%AIl5Ej zRBA{+-=ZrJm|rlv$<-l$_s=F2?@;zNcPGrc^z7C^ba9ty?H|Q+5{>?a2i(|6VKv)< zVVaIP{E{I4ECyIV~*ZYUXC76q3=Dc6H#MJH1{n6<|nzH zpHjRqJ3|CsBbhqiyk)Ei&1WamQs37Z9IBj#m=@6$!>l+eF?W$syUq0HaP2D5c8#>X zb2F-}e*_)QD-492=zlQo-Ps z)72Ry1pl7euAfc1shhLH6uUqdpgeu9IpoHDR!NT!~3gv38?=vL-@oWQCsuz;MswrvK z{#r8_*eQ8p+-qxXvBQ|4Y{r;_6vKDGgH7l&YtG!#2H@fUHqj4MxIs=NnP6V83jdLy z`peNeW89BttrJho#uXi!SJc|<6eIilaV>W?0E)q|cN@6;Mg_4xqZf%^^T8tp5zE83 z?_*_F$p>z~U&|E3jWt3h03v!T9!Hli+(>?;h6^coJ}G?S1^49Q=|N z?dh&MNS1-JnSSW`)e65Q1Yy)6z^1LY4Cl4A?w9?+^R84pceUjwey z>x9%MoI*O~`4BhTcyjC7fi_*%;6q|DdQ31_UErxLg*Cc&1A?v>s$X(rH{DCQ$Pp_rS}1+`;9;&pdf%8-`9Tf_V_6tHylbr39cs$ z5q1|Y@%jSn(Mf}2mwDxQcwS~sKw?G79Wv~E7HlSR@GJ8NH#gboAV3jw6mRgPo4F69!Z{x zL{8y~cn>q3rBc}=+RK=aQ*(e3BNrrzqy>z?{og+vB-ebx8NZ{ zl5g&VJj!oJqVJFVt!=GX!L*&V1w zs+p1HxwtR$hL8E|cQ5}2Y46Wxyx>11d-dpC^gPu_AprkyDhG=MKpW_r74Hu|O0!^tNiL-AWm`p3JfP(`twL zxw|&)lKvutB0{zF*%S}C=s;+;74CcYw%wrqavS~3kc)zH+luQdT94qmc3nC<^r~~T zOX|Hu6>f{S{G^5}r_Fgwrn2tw5ZRz>8y|@ZUQ#kqw0wq&m70j843g_oOh<%Wv0nWp z$*=zMaN|*(6FcbBkak;u8EM%n;JLb&?BzXB`*b;eh{_vrJUPF00r$pc+t_&+cF88p zY)MPCdhe=T+++sL&A_(mJe5jJn2>>0owq#XQ8FpIPn?;Kddx^#ID}TdmqbN<*pTxvRAV|x1C=YnYf!V`Sca5unU0e7VQNv!YDFDQA~bAq?1>$w_#@svVXm`j6l2+- zRI_)w!o{ij>%OvbFKP~2PPx^C76uUie}cGKz!V^_y|uQ*P&8P=5QMn!v`-{j?! zf7=+6Oc6lx<7}lukUGa(U{hpPl*_pjQHlV`_E|evA4zYv4uG@eAQBiJ{fiNi2Pf@{ zGfMkZ>Xk$4>yB88Nc<&18&rj7vSSOQkJZPn6DfgKdx**?%lVO!BmxM`@~{2HMO%om zOWgR4fPYz8tAQ}@6;Z3V@rdu1_YK^EYcH`4)rr1r1-Q5T0D8FPT0Cf<+Ui5{e$(y@ z)Wr%7!;Ucw)QEPNKfUY+6Bs-t*u^A_nN_=1eY;V5XLuixW*6@9IqD36`SlQde_r+= zulx@DUON8z$CveJGJ7Bm=FQ;USCqJ?auzfGJ<)2Jr*9qL97EJ^07Ag}O83RB!ndDh zC{QebR{jcp0UG%6tEb~jP(iX~{EtRe(2*XHIn1l?-VM~N$l^1L)Ab%h$vP&pRICa_esO zH4q`aOT=mT@`Ucw5aWlXlUsStJx?LtYDHuJW{>ojLwUn+(pReAd(J59ni7ns{Rdxn zw)A2YQ)N7F*n1vh!vICmVO}qWF&zQ-&&pS~*pL{n-WKXksc8bFmhnYe0q6oqepNrP z)y_`Be`Ik*+A(rG{zID1LH++h5G5lMoBz*^ho8EgCayS|f0&RvY8#SB0ab}DvK;Mcfi{MRTQE4iaVp* z#pC9Y&*gMyeD|lvI~eF@Uunb@i!mZuU+x=04SKmvZI0<731cJ}IfR9J&F(48WyAtOK#C3{?{S&UgNnc}+8 zM-!z`2C7U^x+py=ckF6m#KOr`Su=}69j6;Ji+W#obI!vmADJ4{CJg&I+$=qg`>e>GqfdVeO1eSr^) z)_^ZGrd*rf-R#Q^;i7j5PAv~ZJN5%EbGh;uk7?^#%zJ#f9D?Rq3Dmts0ZX4&e4aCH zK%7(!heO@@ncG?Dsn^_3o1+42`@)lmY-R;la_h1jfH z96IyuY=y)IAli=qfBrCzFCn`i>Buu-v|AWAX@#+#V_6%^`-^N;ufZ zK^^j1q-5vp+#_WWWjFDsv6Ne;{gWK7SF1RIO@af*_$Zi~n1Hw%);usv;VN&xFpHD)8 z-J8$T6Uf`0clr(1dZ`~3+2pfufba_yO!9?U$E${4hGF!K#+6*y~u!4Q@EIZWtSmbOOpIomyF7_5ZJ%R!Shgd!oaJJ^u zJ2ED`vG`%hc#-8BrfVLxJOX*^iIOah4tlru&UD2``}Dx{VYavAe@GcZB}Gq3kRF2e zt6N5K^Tz6|KzdR@91rQVp57TXw(|*@p60mo&^BSm610kY$>m!f(W! zw8jiq2VhiOb!A(yVIDu~U_{$n&jgeTPMPxk>&pS-Wd#DU3J}^8@=+bhmq#woMgPoW zgx|2)N+zue1H#2vpXh?G(u%fnhOUT$AuCYsic=BUj0ioaqi8xA4v`b(Zp9r-;)Gr` zf&Tk1w9mF3R!{>50y6rynQl1$>n91@+WwELmQZy&2UJNUe-0<#w8@0u%yBtD@R6Xc zRwie#e$XW)6b0}jLfNHYAMOpDGvqV)JbBTdm>-ff&$V&Whbzi0}+ODkD@6t1HY zms8z6UcB7RZ!*?9SAYKgLxX!l!h_}=WQNVM`P%RC^e|a=n(o2b#~iSwy3*mY?XumG z_bk*G9;OB|Cu7lF0;VNG!+E=0G)MV!HQm&_3>NR%XD@kr_TPKr;NcP3_|VcT*=sat zI~%u>bE+A2{b_x=*YyrV`ywCWo|DvVbrg!UjCTtAET1h#cT;=xQMquP*6vrUSL|2& z+l57}HXo81*NqeVGK6Oqa<4xZd`Np}aAk8Ox3Q3=)jZ5pKWb6ABBTy#)i>e6BY(Bv zZ}w6!Wlz?@4$0W-!^kDuNos8PWQjF#WHl#Ib+T8r+k0_rZcnH8+NqLMG{PvW5l4m7 zB$_txPr5_R@?R}BUHG&vYN^fB)d`;}O7ww{*0f%${&8jawPU54I7~mgkrc1*&^87f z!GaI1_KsI@zjqIQ;)1+SO2fC*PRHbfRu1@X+;qQ?&B^pV+N>=~Pt!__sE)1Ne6e<3 zH}{Lfw{GZ@gWt`3L(l{>|7HY3ZF@fm68Zs936}7Jv8FxZN`l+OKR};&eHQ8_bMTGZw$5NWbij z!%P{6CMC4#+zoRs zzP&NH(#rqp;0|dv_9!cpjFo0*Zbv6@T+l81GxA8=DR9AZ;6E-3UP#I<~z#shn`BJZk#dDXoCU= zMw<*OJRv^n-oCq$;nRp~lcSUcdWjGC&Ocg5%oQsUqO?k4m+WLuXKFgy#=3*&>et^g;($(z$< z&@OMK0eeon7b&H!KlA+qwQ#OQ;gISgjM1N-XK6^zs53x_!F(Z$3DLyRIy^8)`$k#= zJFax$Hxe9$D8}azCV5$5U-s2QP!5t_pGdm_S_7o^)xzPh@ehBo5aT=Vz-A%I_^9`( zflvP|)JPVBcm)ER<*8uDhYqA{rdS5Zox@bMfW&#KT@!c564Rq?lKs)q*il&Mkcy}I zgAHY6t?FAYyX?`}BcwpIP!qC=&OhWMdlvB=J~njF7Z+B~qk_#QhtkSgEUwN^p`>H3 zgGj6M%gja&(aNtS)j4|Oln}d?epj3+lf^V$E1!1nM%ib5P)RI{)pQ%(5uW zH8QMZRZM@WY~&*8K+Ej(^6y&q#aMk|f^u6xu`d2emMPg_GL9N-^=E)TW}kZ~n>gVy z9%Y`I3z1W25)Ds61UIX+!imx~d7TcaQ@5@iloPROdd08FnX&Sb>7ioz_3`o{9&B|! zzF2SU**$G+NUvu+1ZY!6qF*DATy%ff^W3o|l_>YYu^A8QW76&(s#Q?XSq%D>u}76C zi73O#Okg=CEr$@Wh1tfr;xwsce-1=PY}UvQ!8oRQD-!Q{MohDZa6#IoQ}U#eLO9L3 zLfg12J<{V;S$5dlZpQ(rS>O++pB?Nwn^hMelLs6580&Q@O1W>7hq-K7utD4G0iU{H>qXg zzi@1BWaf6%ux72LTQZ7@B9yZ;!WW(l?7$a>h2UaELQw|8qUJP}=EilMqoWPT}V^$&oiDOlT53)^k&Wi{+uyW}PnvZr0fb)f!Zy;V*teger1 zhu!KYt~(^It}bp?D>PW$>Vn&bJI&xA4JTusT~$+^e}|^p${S%>t=3TTlwv!$Tuw<) z&q4mI6HFV9iMrVo1JsQyTW#4k|I;`o8>Uw&F(0ecdA7ubHrGk2Raxw0+gv&*WNZps zttdr5I?7xPS%N&&Rv0`R>{c8OtUqFZ*@E6xhFIn+T(;^T9?R>y4@)=bL=(KYrCAh= zw^vXl$%tnN=SZ(jkrQ=#4xE)JCrFNj);$hm?M;OZU%}PJ6B1lZ%r!@x*DUzIzN&(O zc{cm7H_;f@Il?4=tnw9zzd*KB$I=l2w9rhf!08!4TQWivdzi&Z5={XREKXfieSNB0 zcu#(@a)HdAmI>sJ!0Yn9YDOE?PH0?XH`0JEvT^KQ?~H71mITKlERBKLiFG4vTNb}VmSSriPJ5O2) zWhvks@q%`077p3@%3ERX$pJsiH+()UqmGs150S)E?-S^nM(gu`K6_Ql*)Bh5jT_Zic*| z_*=5_9pM_FH#`p$5Ie3|hHPQ5U&f3xMuO&!P`i6fGm8#kw~jEos>46Ot@Oyw$^Qls z-sAd@ZAQuf-g3ziu2ThSWsHN_v(=D!7D8)@06QiZ-hnk_ftzP?>dAnj1HO zYo^?p(nN$Kt{grE|H)U^$JIBE5I{idaQ}|4F#nsc{)ejg&oirru8XQV+P6X`McICH zai9Sa6mem5U@H_xf(k7>yJ7tqC-r_q!6uj+g*9g8lZ z%P}Y(9)Y)7){njD4^rO-f1gt}c$JYE)4Z0|olo7}kChFdk43>>yF$npcZrBCXRpS6 zkeDB`O2NX+cq;dRJGgg8EXfe|>VxulTE%j%(gOgK8*>aAFf6RWkXp=#5`rk#D42wv z*5LrlaBi=9wvv;IxX5q_jI6jybqUy863qg6dPogPk?}-$*&p@$<~Ic&r-|rAn5|R+ zBPuA@yt%Tcun_xU+>fhftKlrPH;9i-4>w$mEdtGaSDHHtxk)K<%67H_i%mLvHZJN| ziW+I%wku)&1m-aqe{k{fn40_#j;)ocwe$pv4oZ&P289PenwH-Qo3^K%%~HMRRMTj) z+$S+OI(r*x6+YRurE@Z*hI^8dqPg*q)axZFbcPg5DJ8^nGxbT_qFsCzTyte-6~B=w zF2Y4ak{xQPoh$)4bAONIM14o8J2$Z!Z$^_94&R!z^HjYA(>>IvP_nQ!&#)fzd-T0z zngyBN8Hsq_mT3uAIxsz{jimSkjGjgiNO8oqp_rNbU!|J^>Vne)?*WqXz6)9N1?Hk{ zw2XIH=L*azcD~;l;3<=nwMM+|mJx=q=Y#^ja)a1>hr`Ah&S2q%!5}(WmTPL_?1777;De(JnYMhalHR@Qg4; ze_L}4E@aQ2QC?TOz<1Uh_9sk(5ogR{NyLTVd zwtII-w+VSoavTIP0Q1INk@yZf{|=#PN$O_SRXoDGiS-q?_DWF)i1*GpM;ebgbpNdt z2knJvmEQH+8a*kz#vqw|9tnE3p7B7ja3Tni$O=7qBjN}3<=LsZFJmGFmskS3MzL zWgR)@?a94CmS_~)SU$kEvX55foO$gekqC7Ra%{5_!LiPy&bJ-+rIHobrNJ7f(LL2m zqQoC;O+Az;LR@PInWOIi14rWQX6LUy73B54B3*TcG4ZU`e~%~Q2wdg)UUkP3*%dYI z8N2<(bKWgHykokkFNV0oFxSAD7NoncQ#EusvG^S)9mRjo7u}gk|M(Ha;*c&%b-Mi) z@R!yUr4R&H44i|mqzSbIZ`Xv|LMiNZy*I5MI?d}#VDBT`Hk4NFm6R_m-U%wt5Ua^H zSrK+2iZ{h6I&E9pqD>WCe(nv#sNaOTRB>m3k@{#E1aG?EDUx!#-z%E6p^a24E_AXy zNqd`qF6h|5kv=6(J{lUbcYuGOCy3p7e|EBe7^fWr@(=LQeplbAt3z^0b})_v37o%|4Lx{$s0G_nLI*v z9KaCrf-;7JQx;l^u$&?Zq>~asYI9|IOoYpb&ES+O*WLEGRIzJjC}+3UO(`E=0_b|! z>R*JlT2{4Ql&#clDB4u*a^Fs;VrB0-%yhqIyUg;xZZ&nE_W11?q4miUb~;hIcitoH zsNZ379=gN6*&y!>e%d!5f);$q_wQ~~4TQr8I2U0N!oCrL=K++16w!Stu6~eaX3_uF z;g*mb=e-p|{W|ys^Q}nr3w___uWmo5{Zya*`W+!>@Xy4tx zmX?A7XQ?u=1BoW`ESixLxaQDCqAt{M(Bc+bpo}TEa*1>!6j0dS>+;S^~Fv zADgfOrc&u#3<;hDEBF*jecNw8u`An9SI+4IKQm^{0YLyZu{Jj%e{PG2ql++3D3=znNSgZCuM2&N#6oeFA%?j6a8Co?S zJq=oLyn=-U8ucpIWEpmv#~_=@Nt#|Kdc&xg47JV;o@aL8Q=5 zFxN-)3dxdunJl#n^akRT0UB|&s7f?dt0ozz6cm~a8gliG!i8}fJM{|15<8kNtrAr= z9(6Wed9fUZJvi-eu>#g@fO_^B0*@?M-gT+VnO^9O>X~m)<8TCJ&^%QCB4E62SQGm} zyn|ME+LLL)56ehIo-L8d54mX@Qw9fYHOi38vX%@jnbDGx%cc-`M8OtLBId*tuo%(y z&LbKI75(8?;Qot`>XL22>IDoHtj5XBZ){Cx{Rmd#4XR}`0?R3H9L^_YlLxFQ<+=Zl zQ#zh-OddbXHXi$B(YRE;ebsJ6Ml~-ib%g6X)Ueg~^z(8M?9rh${npS^B?BItJn2mO zxs_biE~XLxL#VoLHvX=>%v1^DtF}=QqbLL|6oXkLv*3C`qh(;o(yU#vztoB* z&tX!3{9Gc_iTz8J?V0oKe@zyoa=AJU`fYh`fGZewEJSZ)@{}mAiE2wC^L5 z{F(FH=1kiC>0ZR3pp4C1hu{^bBbeVU`)u_Lo7-_D7xlNq?1tjAp2WbJ*6Nv;Q=PQQ zSN7f=1lmT$JnWN?LYjdCn-xS5-7O-?t@!-d@iT>YEK+zhyY*8dRnc*099G1y3$y!X zkz0zM;ud)doNkia(>rH046klIWS$~u(Ks1J_776K)id=h8&<)V)lP0~HaX;k98b`3 zN4bzqQqn6pHOttCjZM~v>!>30Qk-sz4-5i;=lTKYI+%%xs;OsSZ%c$?S!G5Z85$Ao>u-(S$dQZ-~(aaM5HMT!!zy(2LlL1|qJxBAZZoy*^U_ z<|%$}McoPCSmyxq$t_%1kU8OM+LP!B^DBf2k4ez}9*3^u0Gn~D)}_32c3^q>CL!nB zh&Lr|X3Y8dhKf2?<+bl6c27_V6QtT$ogAfdq6!Cu%b9K}?=An}D+5L?qEP18yXOGw1>dqds%!rpz+ z@Q0~UJ7d8@+<2FZ9dx9Ce`S4-(l7l^3CuXpwS_>Y)lJqDkqp*gZCJ-tt>aDOGXZ{- zCtUBoRZhu4!n;C=fRa}>?>vDy$KIn372XV2%3zH_ZNgV+h7Q6`wvQ~eo?e?LV!xqb z!PR8*#QK~OUQQ<|Q&|cNHwON{7-8CjDe1w1v1(%&(OK(F)vmkA{?rO+mlu^bxS8>( z1P*u*R)N#y`gZN#$&6Ta@G5k$AzCd_4^E*myVuDlI2W$76k4GvZCQAV@9DWpW5evr z)6?{J`1CfHneXAU;JUcs~z?vx-U)qWs9{Ou6Uvu1sJoAd$ou+b|Hw5b~COjpZCtstITMHw=M5q9<(@uR{*(N=IM*NY> zH8?8KrR|v|ZFJpq^{XP}!*sc8hlwXgIOT$=_Kg?s%TP8m@>qT*$1|9UY%NkW@$Km8 zZ2;d_{iu(EqGG1X8gOl7E4mt=i}7u@T0gj-_{J4#S^gUAIcFs#oa}66%Z`(5gN>F` zm`7S(UYddtL0BPA7EePB6pyQoR^?JUpBb=zvq@HczS_`?nTBvtiQCp%)dwr~5h zwC}`dx$iDNd^QgRdYNeg%uu2y*Rr2NQB1ZN4{PxFbzEd6?FKtKGC3~!FexK947Wzw zYAbB6${j3CqtRG<*!4fx@!Ux(j=V?YDh_a)YpgAgHP5y5ceOlhHRNfpIkoh4oX9p3 zd{kS-ib)qS9kE>3)H9(qyyb17GWmTX2sCXw&Oi z^@ZD+sIN>Cp|ndGk;-AQjc%A;4N;upLrSo2k7t)i2F>eQIoRm17}eV!Wi7r*wbC#G znmV*89UMmSwgP#99fb}w-`L}O_ftTL0iH9v*>JZ;a^&$_c!l-GSj~gR$Y+gz9+}3J zny?)iZw?!zX!5$($JdUa*I3!^~=l&t6=iTvXOPkX$~MRZbqJiqKwg2mT6Q{W|GD zJf^188iJV!i=qiFgN1CcREF7M8K$LVpqMvXl1?d7P#F=FzQ;4nbIm8uZBJbrNQ-im zJ?N?)GTTk!l2{S;YLuw=H4)EflEWV9SGUgK2@$m&50Cmke7$3ECeOeB9XlJ_wr$(C zoosB|wvCOmv2EM7wQ)AMukR1%)c<~PuIhJHzhMAZm$K#6MUh%vYv#nde9#&yVJnHXI3^Lkr60k-GW~H(nAcyBag=!LBULT;fCaun(zCX z0jaWlK^77RlqdG0eEFKeCYtZ}<-r8-5k~OHmIHE{(VH0!pfw(dm-mz#_pI!Dp19HJ zj<|07U?0#Fi8%aOA@W&~K+|DD4|8J2XNA%~i-PB5t|R84Ba}JVRTz+$Ad}?>(YaA{ z&Ov?_%Q(R3fw$jVEyXXMX+3hzoMh+A@Hpc8v*gXT_9pBMi)|6>PocM^ z@Q<4P44gd2(cK5Cbt!M#fa%I!j~eX@HY(vHG^t*+zXzJl8-c~#-=wS_mM!B4OP$S` zZVcZ)K%uz5Ldv@~y@Y>=)$`GYp2a_0KUMU6=A7;62g~E@|HBz@&%--Tfxg)45q0c5 zQtZEvmB+;x+SAwQ5och^ed~wMvp*#Jp5pr2jrO&L!IEAQTp{b&&=f8)H+D0(r0MWl z9Tjfxwx!2p6Zy*%if*+?w9LkHBfi~&Ct`fFew8q8+?oDF(r7z?gs8fvUC(xpyt;Go2cf+BoB?m=rkCvzDzwEev%{GwxpKZ&TA<&2=KFk^ z#F8pp=|G>jOskHvdhu^PH z?)gts5zYi&=l1(0;woO(l)@D7QeUU)QNJB%M+NX=UkB>Z4Y;-MQx8dfuFpn#@v`q? zN#bsCfBm5t6BCW2spxaW;KCDWo4F^fP`9fLSahWRF)ZU#1=5BWoFivo)am$m81IqF zrF!BIU*}Bk8LT0XKbS+eGv$JxbDo*)f9gdqwXZyD22#DQ0Io~F2Lo&Y#VOa93Q~)F z#{#SY+a}&O3!Xz+U?BJ_zy@5GVh;nP7UQ>8AADvo^ZappA_h;jzLa5zGqoiM%$wX6 zD-udOy=+;x;>c|yLaH&noH$o+a{8wUwA^4nD;`Zb+%hZZldizZ9Bp-JcYWS-zoV`U zx8!LSGo;W)y3LqwE#5<$`PJx?5&ul#XHA%OdajToa6C9KeU0RPnK=E)rhOmoOc8S@ zRx-v6_Q14mzjB*c&QoVRgd%T{&bqgMJJD+A^`IE$m1yWusCYC}YOd9fc(f};8OzKk zA8rDbff}Rt`L>*mc=d?kL*5OY>Vj?hyvgD_1q*O{96>7+7|%EKSg7pCyi zHS>diZEH?seo0C=Ew)9$t}5v^ShsC0HF#?Di#+K%#Er08k6Hg}fTL2?jnbT9+-d2U zJGbJCjBeR_nf?CPvhtUeLG>F%ARr=w|La`|=Ks7ak+hPvcmIFhp1Z2@IN*q3eyuc= zHYcD+NKJ`IbwS5(<)YF+%M1U$8cI7}i(`ZkKpw?BrOho#o~4*QH-&t_j7m{eRYkQb z&jdDuFwc-0hGS9v_fOI2t9uc4llA-N>-)w3+s57h{j`$+v5!pCNOuTILb|qCIVRMB zCI)}&1T+0ol!0myH~CM(e#XVHO&bZqA}$MVe?7WB#E>wn^S0UYt7@Iwv|; z8fO~UjpNp-=DtT?{ltAXijeg|HgjS*d2n?VQkC-`XA`JZIJbS67YCY(jquhV3W z`BQUq8)78Jtypx{r+;SF+HjJXHb2qLJ}8n-OcAanb=RD-V}V4$P0KnZT5G3ZRX|^z zp$lP9vr$;cW-=c{&R~ipae}}*hSkE7Ae}`>{0=k<3k+tWunrB{mt@omMcj;QFYXL0 z@93~O39;%lc9pxje&Z5L5aAD^X`@b78V*Ooq-4w?nk8Rhs$`o)D;{8XE45<-0k3?d zRpz!)JsKzPP^MIchwhe@N-I$QF0ClF3o9k3M9N@BHpnMX*qxTGRRKkTH!VU^A-gFj zb%1Lx0 z#)t!0cAF3jr_c3y*!zTM(a&>XR)o#wpB)(N+h+wm-L`9OSy% zT*r)Yh)iCb-?s!)sn*Zrd}}+p!?hjGI}dPnoMH5-Lbp<7j(L8i(Lj`1o`qHz1$=zW zNzmM}i9OLP1?c`T&urHnXMaHl^3)4&Wrq>3A$(Ai+Tc8RyyS=a@3_N!>7S__WtMie zo2udh)FoP<`MlKgh%w=p`w5_9Yv891_CrXw_>`<$7ZZj!lN~F0wvDWbqE6w6o4^OU zuj<>Rc6G0RU7SXf=Hs%0r7Z=Y;2;D#<-Qp1AaZWHOT{Q_2j3e2L%zo%BJJX=27{)@6Jeb_Lu-ep6d}v((gmi$J9{Ef2REJ_TVlM7M}v#?T`OwdyxPCM!5gGSDmbx zhn0!Z&wuSn`9I5jbrev9P`}Ey-8Rk8D1)4ox`cIT!BN4Y1BfLHh2SAVF?1(NXzg0d zI?3)hd=3R(387O&kq;XMCOpjDsj?fMjm&4J-sn$retv&^zQG!qDk>)QmB%oF6UB_o z$5AlnQAf1(x3%RZ+{=O`!yIHFbIghf%jc90{}B#hVKz6LViKj(X>1>!(^^}6ZvHvF z5_^?oe!a2L((erCxJ`@ACbN4A2W>FJ&9ISLDamMa%oZPV9O%A4_$6i-s$&Km6YBx9_@tIzsAs0d>P3dKHo0l=GQLaLNE4pEy+>JC6Dk;L@ zGvzbhS6^U^WUop~RA-EZg+?=$pxb9i zpMu-ay6IgqJf~cp(IWn!y&ul1=>K;sMOXS!AQM9c*1rbHl$nqU$n7aAtMvMc7PD(g z?yrEcaOlPqBjO|W5S8zKxT;P}XBYa-yhSR|nM#Ny<4`>I#nlqGcCn!`bWQ@GZ1aaSq_$j>I0EixSX zPmUy%jL1jml0t4{iG;XWq+Ln-9KrPz{(NCBk;%%3oC=Z8HTMwoC{vhPJ?a-k1V%Aw zu7wP77?wu^mT1Q*t{)4vQKy1AH-~|T)*uM?5t{E6AHZCb^jqiP(?5QKoqes)%FN`O27e?=m3cplMv2*f(E~ z21l`9_XWFjC3IN)Xb|&V8^pietN|wk8B6?9U2Iz27Tlg@l&NX0kA`AkwYr#ESEl?wu3bdLQ4(CZzc)Z)${oI^AeE6krSCrsRnz^HlGxTQBWL1QiRx z87g{(p$-MFg_*#_X&7-vn8#3h$oHiiOk98%YZ5y2F~)unZ4?dSspLQ~JG(4Xz^M?> z}-TN91H`e2KaMZ9mCjRDDx^_8B-W^%3J|*b^+4hf1va z$CRFo*fmEfW(M01BVJGKd@_G~)n^sKNpn|c`GQM<<{*)LDmyctuf|oAr-?#)=SfbE zm-N?|j;AWQ^EV-1efEw-Ch!fKu!ho5P^)d(V~n5p)i%zhEGm|VEH=P|l(du*0#E9^ zWA{Y02X}X%LG^4AnwKwkKBK9SJX|aHWWnHfg&51UOM|+hx!VzlSS{pAZ>sZg61r1J z7%V=ZJLhb#+#37wHN<^ZXcMhu9|3sF`^;Mo&>S&(9!n!;@$GFAZ4!BFHwR&rq<1j9 zRpqrnK2s3txg_+z6LQZ6K1a6sXC{#kvV3XuiU^Q>qZs{`w5B*@BHe zR~Lk(EGr-tX>1lO$%6CM0X z#pN#{rCinBrJG<_vf=!mY0p!>gmPI`SDEq3b+Q~0P^rFhNZLCpaO|}Yzlu-z_Rplj z&UM`1^$C>IM=u!XPM5%{|LdWtj8VK z!)K^vpGFaqK{UE9nv%Nsb6q{_-wVv*2e=?ozX}{BD_Tj6r zO|~ud>+s_~`)$ivK`od2sYd13OojKN2hO+SK6CPV@t;k4sZ>_A1-0?xq^+dUVN)vM zWMaK52IZ9KQYn4n`7BfsHaydjxZBl|IMs;d63!0y1tD&f^CD@z^PTBoZprP)N5a6o zk|K;m4-9ungmPtjj7xGp$r6M_NY-;AYtIC30of9UL@>3BQ)Ay4Yl6ftQGB95l!?Hi z5Xe|1Qt|V?jESR>yoE9f(jpPwQDci)k8s=J)(ed;1ZC2LdRJB=FV2;ZUD13tsQQYf zq8Q#YlreK2ypd!|MkUl_ookX-sB#x#nT{jn?_|VO^yg;hXb0jbSR$s?GSaCdNH5fm zhiXhTl*VM_GOV$HwVCHn)Ns8F$MLHf-#ep({T}=#ERbdOC*j(a}OI_n$f4u;~JRx4W zBWlVrZtp0iQ);WaC2tCu2y)SstPNYy7CmN1>>Y7M))24#lDq{>jZf+nF=j;UXU!)( zqa-?9EE-jDgXuUL$s@ESCC4rHvWWd%L!N56fF;K*^Q9^6Ojlgygv>8-#G44Ksv)!` z#ym%MKwq_hhEYWVx-6Bd`oQOuMSW1Ic3v6nYfwp4-khZ>aZ<5b0+HobOwFeBi9!12 zd*CN{6t4P#lt_T`2A!CX{DuYpm`zGXT3lt*CFTU7`}1aQR1y!OunsADu5`xpZr}U^<63Lzf>ZiblGdQ zkS}%IYqMZb{!}OW6+GsT{FY7rnNI$xm;9A2{aq~mT_yefOZt0nipT7$ygDYH;%ItY zGCMVik0hK$LE6o2B&VdhX=^J+cLq0^g5p=)LCh})^u(0p-0bwU+!t-_l`Xh8oDYOl zl`>g8Cab0Lqk9zPGE$O~?tmIxE~A6jlzIkvIcYo|CeJI;C1wVToBMGF@?IvpfuW)M zBI&~^E^;O-p9?T*F0RFSRwhrE39$KUhcYq>c^}__w)*0VEi4cz2C_H>>|9Qv#|WX} z$;dh~2+UIfy^X?%7zkF)m1>L=Ij1+jxxjJ+qM#KY5x$KohWoG6UCs@_; zS3{Z3PW&KUF*#UeK%9-rgS8x56xQ{H`#;+k7aNjKr^YjrKkgr6*1>WhGI+cPy0jLZ z2=|!HS(pwFd0i&aBqc$_kE=7>M6DB@=_+0s*u zP05YVOnRiRZ0#B3C$r=9u{clf6`P+P$xY0BWSnI1*xfW$Pn{Qes+zL{yPKVm%Y)+f z4GL;;aotkP3@s>3OiTV+9v^4s#2Bu9Y@)5Vym7(iUCttl;p0CoW@4>&W>3pFYCgAW z$I^tQ4dY<(_FCE6nnGYHJ4wnv!5+!UOHG!sftqVHw=kPqfK6^=aZVPPnH-bnfETr4 zWw%8a($;iy+qGO?9vCsQm%OrbsmQE#%0JlZf-V_?s zJk}f>=Ps;`D~+8ZdBVKZSzi2Ri`J<;2aCmtrO!p)63;_#nI^yXZg5{vG+B1h1K%9Dk~*$Vp^M7HmX za1r#Fvfi^8CCJ^rch&NEYMYsmh|CbbVsU41gLhLwRW9@aAtyMq?-?|9`-v8w@`JF< zm0_lXq9o)J+XRkVEyH5r%BB7W*Jdcuv4oa!;qja`Xssi$abaf`Q$#*7DNpF+Dr1hp z^du`ajl-AR7TnBBp8Z`QcMe-e$N6Vr^soIah};tBd+;!9@vm20WI5qUI3c$b=EiJ2 zU^%Mw#?uolCatE?u%Aet{hB+Z`(TblITZxQMxN+w(Y&D%*<|XzQEQw8TF{cyc|4P2 zMD#qw10<>?2quTcun8W3TqAbMlo0WUEh#_8g|oTNGA`d?uy2LJ3)ERUB;jrjsy3PJ235A zs%L=F2q(@DMyMB04@%%a#lmr4#Gn)ED@@{9WG_G1iSLLu6eNln*X+$1&$f$65~OA( zrv5l|f#;o_9?wV&?dDcw<+r&dpGUU@32#@_Po)0^QJc$56RXQePc+0;KMWxUuUfId zM3S8&ES3Fm6Rs&o^5F2SSl*3I3@t?c7m^UK*8Ikn%2&n;7spH{UBs! zY!=GXrlQ=QY?G8sqkBq!$L${catB3)T%)u#S?mdS+sE@q6My{BgJLJseP7R$V<-1z zkI$3gEb@^zR?Ao%p|fPp9z(=yV@Sx}XLA1#p}Y|9WHbq4ZBfD4y6C%{!c>Ir|8L;7^QCa3GqGIU4st z^-t^-y->y_WJtafoKi~HKbJ3-EbfnE68DT6(?pg@74#A!Sqg|btdl-81GW>E$W>T! zT^FT}4aF*Tr1Wy-ms)wVshlxzzxaSJ&oP}2k9SQ*w_FiZI!(soj(f2ezxd$!pp()d zT7z9HZ8aleL0jdSOM|f5D!V^Vx)B|9S<6TWOlOAL(V1flRtT8tT#)5YRk5c+Nxe1F zzCFx4WdL``UiomA$Td8(2sOa za{a@^Dvv3C!Y7>Gm+&~T`vkUFinMwS*Yz(wSfkXJ34gr*z^Rn+mV(k>tZ&`QiBp0E zpJk8;N>%}(lFHDf4`WGj}!gf_U6c?oLAx(T_-5=D6 zS1|g`%6-TXDV6Gp#=p5B=E;!ttbr*am(S<|YVPmUe2O7=x+h6^UgJHFPE+3=zm-zo z)T(G6syNh747T+%4H`R{d!G%>{I=&OKHgPQ-{8$s-(oRn9(px3GrvENQ{MzMbuzyP zr$?TOgC;%*ZfmB#$M+{b^6{&tzO^EiULKrN-+J4A-t}thW`19$0zk_k^ZR&Z;$s(G z{lveym-*XWg8ISVzliz!vfD!FSr3Q{h}D2V*ZT4A`d2Gi2m zC(BmR2Sr!Y1_0^@XpnbRy^nQOeE^_-fCgDtSAZs(n;FNOT^UE4p8$#lNG{{1c^V)( zfNDxyaLPPwdCEL&!?{kHLEt=WDat%*?wtC(bT?zQ^fnt8Xs?GuYOe=PYp+K|Yw^~0 z!(xY%<~wwGJch2kBFa2ptJQ9M5r6BiM*Y#L8E-CT-8Ig-Wy-pB%({)-HV;o`Jyl^n zU1U8?YG8!5V_0rx!I-Aj&af#p&0}U(;L1G3%{=v)BTl>rcQ&fC@>Z%OoYV_BuGJ&1 z(j%|Z>nB{r=+j)q7y!s9;4<2%{8Fai>RlQ0;+;9;;N2->{~ZP(Y0BOnY?R&}2$t?1 z^o_c@LD{;xQQ12CK7fX3>+C`PTxK&(Ug|Ic#1wwH3HbEX{%tMx~L;2ARXn-8SH}>xQ=iS1NxN=#4j_zAn-2M2dK9m zsL!4j><%Xy=wrkffM5Uwy~CLVejkAe=&468u&)L=!>IxwHUQB92)c)J3H&-D4%AZ* z9bo?xVh=|L=ygOLfbfR)KOxs}cmi(4f$z50pnW)C0&hp`_B!h!U+u2IdvN{++>ZDS zxc9}tar{6Y5ed0xGPs8HGA@9PkKY%p;BY1$Ah(_?tr->J)20OPX^M z%7Sa3SAugEWd=5+F~~umG$$SE)NH^LoYS5jXeJvr@Zp4bud5vsfPp93G5~BCG@om0 z#}%}%1)9sInbmTw3V1%jF6eGYx3sSX-N?QSd_I8ypkpstD|CXr9mG+#4$#YqdS7>Y zF18zOvnb3Ioue~_!!9k@O?GF%-;&>u`7{-;fD+yJQ{efNpAh;9P9_g=of*+nW(H?CC&GbfN>_R*(&Qn&AKld7?uT@U|ii zK$r~s8i*4e8vttebvOTTu&-(TDc9284BTdK3v#2A9r$+zeXpk(4S=9GI-3CevDc#p zwAJbc@=_xVIFns)1$?994g9vkFWA$ZPe?#G1_^+|;^>C~2kiC>u0_ z-rj*`-J7t$Z_mVnJ>8fI_6+OzmYbV0?%7D^&&*SM&rSfr0QGhw_u1Eh+-=$beLQOe z@CN`P?>2D&C=NjAK6`tJyGhTkXSumRUcV4uZ>~UkcmO6p12FkU1ONg|9!9Qsn@f@q z0cmUyY(arA9&xNVt>zY0hv$BVDabo#FORT|0{Vt3$UAE<4RMPF*zp+Uh4OptG)p#kw)I`lJIUr#o|nmY!_^R`%kulv21^PiH38|1y-PSn?1deFzt zN#M^L7{T67z^C)64pbo_bJR%wO z$zwDE?)CZawsnAfUeG~yyT$t4?U?`w;`5TG|6_~uB@Ohv8%@y5o-AQU2fXA(9e`{A ztnqyAZ2e(*TLZb_jT7*^Lw?bLWqE50yy2}A_`Jhj(A|n>d3z1C;SDb6ZBH?`Lj$(q z-3j<#Ug$|k$V_*DuRVd`?xw0`fJ#Am0!}4B+Q(V-W9{K75Mb6i`=E zAl^}Zc@S&fWMGeQzgh!ZxWxdu`_u#S@#g@Xah}7~e%ydPdU?r2 zPsL_W6jq@mZZ8h$%19s}IU0q2gBJE%@cF}%l2b;NGKV?? zC=004!}S}3tq-vu%eR+GN$C<*N?Vr^2TbvzuBZ$a5UvRa9u!pa7ej|r8mxMKt}ND` z7;N+{$;2M*$zh!&aqi(R?qiP$-bG>#T@;oKTydihZEH70&%pQ;?h^4gzSIsNk5MTzY*B$2WviRpD+i>3La@(en!j)FTE*S=>>nx$Ztt3e@Xp9& zD1@3Od`gqGGk2SlP0>9myrLH~^<`XSK+c(i+D_*-a=l!B;cr(+xR28gJQDJ`5DzM@ zqSSOz6wK+A_CLx?Av2^gOA_af!F|!^kF%t@eBt}&Tik0|PM>i3u-^bO=0RtnhqG-& zj=z)VtjgT6k3bb3ds+!QLr-NI3Iy=KN8Z+O!-r0rnHE0mIgmdpmW%=+uxOgbGmv znrXb3pvVepQUYHqu$sjDuCj{=#+GmBgXl9f6SYKo4~+Fn$@+`qN@Am`BFrL*a6<+S zv}j31wJ8dIoIV;twNcWd(Ogjlhaw6BpwgaSaMULre)0d$Jo)@0M7)J(p%9p9L*9y_a^d0ejk}v3`!~`JV%*Z#F$^ z3vbXtQIr|Gnc6Q;q#gMOR!_i0{=XZMs=?8^S4ii+3>JmJ%r>~p-hp=_Qr)ve zj}4R*dleL|q<6F9P}jRaRSywfI9_wB*M*J;?|+~MQRmUDrH6_a3mzLddnWgFMH;7z zv(~Va@;D?U*VB_OPiwBT_ViGLO4QKs7_e#YVD54zj4{wdqGD;PiLUhf>g96Y&W^YOs4>S z0!X7(1--k&1bIGar)j+PJcxhZTpZp%g(Q6ot4-<5K}U};1s#kUUcO~NH7OAWG*)!h zNyA;N$Vbg|tE!VqQRlxchVbNQ< zgvwGvxK=dChxkv*hk{ws^+1}mC3>s`jX{u#;|HmG>KCfMswMTs&kkdaDSzXX%i6qT zBM4B!nE&TlC&ou-9TwG%KLAl{bs=wEK>KA8IXw*>0<$TpIyd+W%CRozL}6$#3_)<= z`2{DOriCEf%SYtwYs`*>q!!&NWAk?}1gGN8DVeRvs;TmKo12GW=gas&089=N+lW3SX&s*SZq z4{t?^q=jY(l3JyOzcrF{V4K|F<63S?p0_GM+lM5kquJ!cSgIyItafX0hpN&-xj+;* zss3!qlP<1-&6gh^x*W{LoKb5e@);rP-B{}}u!XtR&?9W%dQ52z$z$$jsN$A+YcZ$k zrl?t85h!W3vp>ZYo1C?A1EarXRMrrjZ!xDBp3BNbwWZ7ZPcuqev4sZRNRxK_H7oKS zLD|lhb|D~c7}Lgx_KegbKzHV%HMjl48z7Bd2i6+Z#d-_LG#x2C)?fe zv}O?t#V@ev$TB%jbl;#RDa~xZSyafhy{h|4ZF7c&RlVHJtTViPLv6o4K~Fur6}Csv&YSLulCoHYGB24sWl7MG&U zd(-mOt8{DkyA2RD=+KPZ_~onB;D+(Ns;|BD@P-1=$`%#s3c91_PEMvy&ue`A6zdM0 zYtfg0NMO*E<^wXT8joD-`~Ng_OT-K6s?7^@2Z5tr9aWMw!rex&wH#6%A7fh?rQ({H zaX19{l1o9>AnKRRr<364o+5N$%VZ*8ls3Fk*bKm-G>cLP(=T7Y~IX~z|*R7Oltq_f?N4}K7D{5?`K$8}u>#dE_MJ&u$BH2lL z<0iqAtvLI*f+w<8Rpz^TLX35Y1$GE@MHS!R9&l{L{3~E(X39PG=+`)b(0)Z>aBa5xr`U+E#Bmn zI;eii^N3p2&FP32X-(ObmuX=m3xD`<+10ii`sBp+yX@NI&tPEoU1Nfi>*_}w5RN;lg+;ZFhcjNOxX8Y@ofmL!c@J<_QvfpjD zcL~q>yvmIu?B@f*=8a{`@T!tJL_mu2EXYcE>u8> z_-eKJui@H_PFe@bb-Yu(q61;hIc!`f&qw)!{&dKoMCzkEe!_h674zpG z_CeLv_`y$T&=v5QU0jhE)*>AqbkQbS1MUC(`5v`WT$+Z z^!$WTQ~?r0)}#uoSQjYpYtIzC&}fzml@2Ds3-71 zNU?V$-A{Ra11Rcc45vHS$4O2xRctX!#Y^{*6%6XM5?zCGX#J%toVe;5zyI(;~^c?#P*e_o)!q)%N!5xNd^~~8ffgtOAe!1xX2&2k$4-8u2gPpa^~LyM1RV-y-DmOCCv%rpf3HUB(AVKS^-Cb|}{?s#>8A zD`O0=5U9~gwSSe9dnl>Uk_y4Y5BFn7#o`)LQ`!{@)-qUMf8YiF(VTQICVoe$5s(+J z;gO*EpgZvRj70AhI((w={G3y6fB!z& zrN(|{K0%97gU0kUDZGc^6|jGjzi$Hzp=P@nyf~Ch%UR>X0v16Jfuhno^9~Nw>Oz<>2`@ug&OvLH3-{kn zu|bTbcxJDOjrmSeZmyMIY257>z4SYWqgwH@^)Bo<__DQWiWr`T;72L~Vhy&sE0mk5 zJ0IUF99omBpp_;be}SP5Yqize!<5(iBI*D$DFFs>CQg$P9e7j+Ns^W>WM*wmQ4j4w zx0Kj#3Vyw@8{~%0kSltYzSUc|wZd*cj_c^KCzmrDO$8zYQD?jRf2wtw%ua(|a(5$z z2+9X@6#sZ*lz(~Sny&fZ{jBTa_&21pIP95D*@L+s*ew~#I=y1(!h&{|B(spU$Ioux zC0ldyNx$AOhFWxQi0ik+jN7RworBpUdKHOdvWJDoTx`+a%#a@Bs6qJe&xKnw$IxNd zjmwcHeRVM&9kJg^Faf1qjn{6?Y~(OZ?|R6D$O=%|wjDJQyW1)&Lb+cmwy9dn6{K$n zH+CP~k%+h{#yExld!DbsI#=h02DTIyTp+$C2<=|ULt6f7hLlnD_4Ra`3L#+631U6Q zKG*5`BkK2>qG+!`C70xIR`4gz2Q#t7r&I7Bc4JqI&SpPP+}E&TRC}DLQuZTA;ua2E zl3e)FjfHbz-+&mof2D@SP$HpyT1e=>EXB$KASQrEh0NA2VL+Ht6`;J5zL=mhD(OBi z>nPzJ0u~DrKzVY4Rc%k;$sT9rDq%$H3k0&L=IU6=DF8!%bT+65kERIFU57AXzrpng zpv*u?BKXp!)cEmVU1%{QQqaWOFX>ITi5=TGB=A= zB1M*7&7&(|!5@ogmlZoBfSaT3IPAdDVho6P_30|j-!OhP8hir*7ZA~QQ3D$Cu8 zbBClzh9B6uH>n^$$=Yw%KP47BYIPz=#!hbfa;>!$#d7S$(oC<{S*KEkzM!s0juCn6 z^Bs5=7S5H#R!J2&#%dM{?<0l|5Wx&{qr&h}=#Zw2f+h<^z%6hSJeCQqDDzwDzTnP3 zJqG8Fz&|4N3LgWBeh1((GO9N8&2POn{~(JX-f2Txl0_7IRLO%Nk$8nH<~a>f+wrG!bhgb0^oLi#p! z3hdfy%eBUC4PQZ@vsU?6=8S-!qD_uhk{wXO^4rXO;1IHm--nQ_7=S$$dZ9ATN3%bFe;m z^bZav)jMa+nUpby@14uW@DeMdh*2i0vs_rL^b;vwCxc;uF7(><7#m9F%P4b9};NOD=G zLMUg@TnLWB!w9ls1yU#Yhje`&AZCS1sLaf$V@B>Fe=nOUYqJ&5a$~>t;IM;{5UBN z{&?Xa3yH{7 z%vnm^|9fzWE#{K^bFpQf7&h@nj%iK_SBt&oyG3BeRmej`HTrShL-?O~ z;Z0({0Y=Scd$5NyYy+)ig*r}^#XiDrs|^>jq)|&U2pgLn(q@fTxT@698Sr!$ z#qod@h7{|WQ9s&*vRfj4w<@zo>kutAtA(VB{bZ|vsvi0UyUrr~9FxEY%JyiVoz#YrZK;0}c`;u0rXVYv%K3-{csyIky#Rj~baEg_$Fsi%@ynac7_Y2 zy658-14XfjbY-`ye}^2ZA1WWz{f-*UnJeKtGwQH2JC1wVZYpy&16obZSAt7y*KEs3 zi`qlrVshSQRoi852xM(+FsSW)ic+$cAw^=swE;mZQUz}UsmR38tQ>xuq=>*|f6LqI z;K{^ES|d#zqz!|^zc7g*dqtuVZ>LQ!@v{DNVIGEnP9n4KnnheepEF?A0O zFopY7PBV@gW~)UZB!2{@53xH5R$FbdNOG7oxhhI+Z6(;Fm+adsqiqLmjv_eXk zZ$;UZrTS0AMcO>8@2n_s{ps12n{n_(0V)l4&SP@UgQC5QwQk*1L01db>Q$b+<&x(1 zyv}|QI6r1fjFp4DwueQZGrW~xZE(gEj32LOr)U_?MJ63oF**F zneM-LM7L^3WBY^Hzxww_J#mwO`j~pLoUJ2S+w$FLnu3hbmnFMXwj{(aF!qcuOZslj zYNz_@VPmaf0g<2F6lu#x!wu+wf%-N6WB$2y2PYWnQq@cc0MIjf3}F0@@JFkjdI$JaSUR|4?*emdopQ@fqo?bNoWwr$(Cv1{A5ZMVC& zv1{A+JNKS-)_poJ$!k`!R`Sn7e(|?ERBReL%|yvMho$fEvUg~lnudF92*r^|GHz70 zRbV3>PXoD81REZ*SD+deEVof@5*1ZRqQtvHxS5MpDtRXhyFr9wy>uj&C2En_%Mx>a zsz%YcX8)>V`UVRao!_k=^$ce}IM}o~n=4<{fEQr^w3(hHh?3FHoIbPsq;?pPOn$Ys zjD)&wI?tCYTt|eE2xRMsm$Zeibg(+(O0|ADbT&kU62ETyCz4-aD<_+Oiw+)KX0O;O zw$C&z2->twkdPi``c)lDRt5RPVYLu@1YOwuMYd;dP;cKBDR)Tkph^js5dH2ZRiZ@M z6-9yfBkUtsd^!B2VUnct_1Db4kY5K9uY0rj(-?A=1YpR^owyvQAKLSU#+$`VfsT*! zWY5T>BCJ;Lv`u$CaH?rB4KXA&XX1Sj1#chwFFg!E?9JfVNL|nyxa+@ zWyAb|NORAfCC9&v#&1cT`$+f&z`X^Bmkvt01T|qQq2dt*&t2l(ZzNzzJl`LtWQZA*#Znkc@+Fhs5{03!B93M63yW`7 z4XbWtS2n~-;fIRn%n;U;)k|8+&&W%>QoNww?9pw{7CKy73i|%okWgu$ryIHPtZdEJ zOv0buvnEZ6kVF?t+>Mcp zujlk3rF$G2zoha+dUjFv9>y#EBPEwF@_@d&zp3nk&*TW{v6INHjJ}qcd|)!eo1$r$ z(g4)uO5EQtSa^t|7C<>(Xi~@K&yAu;kTJ!MRgyMj)#d@7<`a;9&z<2$cpTo|L8#=M z#8V(|uZ+=f1;5~>i~H*M4wA^Fl-gq$`0la!8lKUN8}WX$e$W6uN|2!WQ01sI0J9;mADz9`i`xJAS*ZX0SE)nd75+8Nak*W{)%g28e z<%@1_dhcuXWgA4jU1fDY;2WUO9$NlF`(4BPCMMu8@BuIxdc4HQ$)|4zx`H^PvXioJ zZ>>cZqaR-2D{*h+#L^bfVtT+z9N1;iYR1ebF zpMaLCAiW0 zp~9j!BbuIx9UsFnnHaaPl3(pmOHmcNly5?)tN2P4 zySS&~u75DQ<`2aJB2Xa89RGUK{DsBPoOuN!DZcO2RaqfHK_;F|2?yjJ=IS_2K{ z-)>177sVg-&RoGL!W5q*I8G(WuLM(5Mutk4&A%(>g$f5Va!qm7*i3OuIz(PHA`4ih zY7?uBe$Izma0AQeunFNdgC5^`I?MVv12g;5@uP(ph=;`sj^J zVKuThwocNdeTwyIcY10qgWya1q^e~Hp{DJdRksYy1GCG+Y^C)s7}lH-N-sefb0h^! ze!n-B14(FDO4J$Dob@(575{`4|NRt1*al2HM$Up*+)z}wt*J`);)RlYuMaLogk&q6 zGV7#?@#NL>*b&y|0R*C6K$EK%szWc5h-ivo zLmc475A;Dz!Qr0%VO@g|l?}FOqFT|)*_8mcVuF}irU+N%K}O4Em|_^#TKCEpWf1>f z411O^?F~2!gYC>Y0)uJ~q4ei{HH>!%DPsr-^%(tKn~5ZQL4Ko465~`9K@JKUeT`Cc zPgEodh6Exql=A0ndJYJ0PM67zUsItz_h6h~kXR%zGPc#I*VwZMt4|O{>xY6hzhXC% zkxsXsp1J_K&X`{aW`sPk(n^Fb4SmGT4cii#{MJU&UoJ1)l!cY`i7o~;(2l0(Dt9r{ zH-%M~UUvCZukU`In)kxR*)Ikk9(l4%ZgWet0?0m?jTm=(^{Kmo8`fd8IlVlEFn847 zFx@_5SPG;IYr!;6V)wCSnx-NQ!_xZnniDmlDjW{ZZVL`prx=A)p$m zORV`NiJAc3^l*xiPZQUE0F|(Sy$9;blbysa`VoJBRemR^Sk79D@UQDUW-RJ3#h{X+ zkdIAfaCrn4B)q{shN@DR5>?_V^;+wMQ2B#r?a=$5y(z z2PY=oL@qlyo}C%GBP)Ha9oy+n$S=neHXp%TIy*HpRd8(KB;MI`=E5WERmeMnI~XiF zT^!0!7q=vhq{p(FyemD)&{u8iCC>$*n!7KX|J|L=GTcPe4rhiGhSjZiPJKImx<<#( zV9Q>S-ag)Fy0CI3^M^%12xaSGGrDUIL`t`$gvHb27@Y-DLK{#I zvN%!OMv5ck3BM?$@c{k*2|X)=!{IDk*|Qa0f43+VW$t2ZTB>ksS4Ng>A$+}PE&`Rj z4{JahiuPr|3#&1vPk+NzNO6Dl@b*B-LR-NAhf4_UCdnqbU)G1$#nLdrU^T3FT4({H zFt}hmQJkXJph6M(Hkx7B%e>?u5mlT#77M}68Dv^CozB;Y5Cz^~r95$RST2#6`0p*= z^+_eFxulhL%|l}iq^!?@#cgsCHGRYwA#tEY!IC;k(F?P{o?2Zlo^e#P$Y_)>Dhsb1 zE*kt3-(l@7&iy&qcaM*3yF7**3tVytB;SvvAt2TQ`=R{8kr97OfK*XniYt0p8sRiw zVkV!5L?u~Cd>j|$3in9oykUqh6bR8M?DPHaQ)Juu93oiQkr}4Ai-<4t_X!>mw z{7i?E-(Z;^TVBo;4<)#h#*aGhgJl8;v3DhDXB?7aP|~vp_Ezxc9?wsAtjFKiS&rqJ z1j06An=tDA-+hktws`t8=JdN1h{@f1w6u$q8_xN7z0y1CU z%Y5vxUgxGg%T2$Vfj*t?bAXuP??OHQR{iQNcF0P4ioLOIak{mF{i=$%mQ&kL`l9b} zl17-Z`3BXcn;v>Gb!x{34YRhqkJGrO+$7DlrEH|ZKIwSgX-evM7#ZGq^};eZ_AUu} zblvlzx^c(kLcU^3zC2G>>TSJIZ#d>qrrCp(enBq_tRiLwq;O;e1b-tPX~|OvKP!3Da6ppqjI;(g>8oxGs!xlm zI<+?7_+@jx;;ILXPr+Ry+BILcEX^452yqt`FA+3YA3gf=3|VAMvg!L)d}lI%UoIs! z-LxuXOyGUsgFqH_!z{~*a%KP{wck0Ze-;vlZ}10Hu@+ipe{Tp0Tf^}hXq_-_2z}bX zp|4_iE;Y$JN00uMhrp(6NDjc0V+=d6DB;R6P>9WM3BYR!So{Hwz6$l0f2s;>WtsJt zw{2GcBo8+GB%M`6V#e3cF-kb__~9AQjvqn0&KT(8L|Pw)N1_o(l8)fig|(~0Yjb^O z?zM8?a+%X=^W0_Axz}=zVGi7?JTZx&K@z+ji=erj~bxTp50vu&WCSpcofM<98YWU~sp8XQCR=GDAQUgYaOZ z_$N1K3~1M1@y<`Za~@sD8%U2~*k(8ry04^7m9h#~xo6PW@GsM6=31g2L(cK`MD43$ ztrP6=VJ&x>5pHxgI(AsA&-DrK3I~Qat=Skb=rN|Z4@P&BoL_in2r8aQ-8;@N?ZD)0V->tkFTVO$*QKZQmr5%wL0_t$%w(CCt* zH$i$S(9_4nFRp5pqcTByqgE%>cP~rgm9F-QApLzR?pQpvLOZ)-wohjQcrhfP6Ai4R zfnsY6@+P~e$De|%xGeWsdR*t67>Thrx_r1GE?zDeteP&|GL&e2^yo`;1PHH%E;w~|L_zdyP0Kk>S zR;fwy?z+b4G2KJT?^rMZEt|}Y47$$IDPfa97l14MCP4JGM;(Pqw4PJkPm;MlRw63d z&M;YL=L536*sl>OVsT&FU%f7_d`48-jowuE7-e~>J?YVb-bjv94MrU}CyYrD#1_%L z0WDrV9sUFHr$Gq@G|Hu@ER~Q+kf?H8+zoU@@K3!$!W{pEYcc^$nLCK(>*6hI6x;5I z;!gMkp^yis3zHq=O8H1`*xIxZwX(nKw9zF4SdD)}y^~nt&95ilcQ<$OnGGoNdwOZl zBs{(q8LbmIy(7*4K-HUG)Y*ni<>R5kbaV&p9f7>re~vnVHle(1%x-6NE)8r*CAug2-T<^QlI^lMH~DBI$uMES>K`6 zk7mmouh&z@A8@!AA2iy>{Hrj>euj#EMhDs7Ax-aYY}2nhV2K&Fvecp76X)(eaHHmZ zBTOllWgdL@IQJQr!%G??c27AaOL?d z>H{ssLGniFQZYsfmK4jPms2Q<^cPgkG`J9)5HTgW zmCam%u5dpo4eQ=ue(1MAx&vozk>@uDto5u ztkW=$Vm4Hm`Pc3Pp&a2G{zCo40ru9**Zki@4Hw@8;cPOOl+DVQqw zc5VdNj#W8dZu!|ykOHP*WE8kH_7-)9<6A&le$Tt6vA8iHmPB&(z0Pb|zBqUq=j=wJ zDf31;d>np`ssk}U`J8uAXW-;nU6|M$Afvs=T#V*Ky4&qi9$BQ>pYE#a#FXVU@@7a9P!uKHgcuPSPI^nX zWXP3F7@Vsa74v8Yc4f>SJow!wfibHNPry|bc49I$bHghSfSd{KlTuizQ6acv+)QX4 zF;X0eQeMN!}^a8GfPLg2Ke~m%aw{7>$?+9*T?oJW~@m30^Qh>7-4@^V%C`YKY%SQ?h=X=LVsDej4B%|@AB;f2xFvZQMJ>7GkK>JHWK@Ix+uk_$ zg!2FoEyos?om|=G&wK}KY`{*3(7@Xd0OLpE`o?W=b_tUvefz*%58clJ=R9#85g>;= z$_*IhbD4(R!NderT_3^~nwUPD*G`Y$5JjJ`9j1gD2z>u7?hL?iR)!M#(bi1PsGLty*1)no& zvtWQOgY`J)fbFO&$lB;_IQ9lU+0Trw-?lgj_N+`ncob$q`uM;7V{AJiQBDV#6x z@n0UM+jjZ6WMR0LCBkY?zM*gnbI-xFPtHAYRw%XWLaY$!S64#nwXr7uW7r+ybNzx? zF9PA7oWM(QpPY>J+MOKwpKQn6{~{qRuLXUc=CcxnMSU3K&>#Lqda5^Lr8ibUTHY4s z`!>?X8oVb|m)ec=&nBtkL%!L7c@cnkG8j4*qYW3>fw|MUSPN%v>jA)h;W~h?=HaS5$_B_M#tY=kHxh8h9=$DqQo@tU~SkkKFlUTa+3KUM2H zQFuK%J{fSn!^jZ+DMCn^Tpi`BEsdVO_vpNFWb-pGs+Bs_c+!!K`Rou8qAw2g5jq}D zLwTa&rAlrD*1Yfn68C|hIbS7)p6|uGw_B=&!arY6>hcid8BGnSv;*;kb@wB?cwCJ{xS)tRL3RQesCiM?G|&^Oi6k%vXDHRCW{lltk51( zvO9rH?TOp4;2oSnE=^8rqV-v$oFT`#K@NW@3IDeQuWp|HHpM1>N0fp7?aEXKf%X(5 zMJ~jbZT2|i@>r$rk|j65q>94!b7CzvKWQb*ErQkvlF#m$K3=H&O9?#Iwtww(g(il2 zx&p`FH-tkuxlYG8!^yf;kKw`NU?^dY4{Q#@Hs4R=oD$EyPR|c`>?1%M^M$x{aeHnD z(#(zaQ-qKNz*X(#ZHLM9Uu1kB>ctu*MsJ%P`j%zgdZ#S7CA=jeN?6hd$;2Y);tJ+A_eoxX&wzii}ttl(KHjnGz0 zV?^>XbGdjQ4Abj-Tww~}!ah`x)%?bsuwQ2j#2Z4Uw@~6U{Nu5tX$@%Rm^p?Sw(x>2 zt)}9!?nK!Sydf}yR#e}2>&P7CM`h_b0IpUTI>vH~wLK1m4%l{=uft&S*{KPaWISZE z#vD-EENfbdD~u8(P~CI4UXzXO_?@?zf5d~IRtM`)_c_I{#>FD`>0Rwg#m|Iu0Gju(xeZ^HyYd(LQ@1Fevgd3zRRX z_|DgMA$6|e3V2j<273ewr6m~CN9lQtV4j5jP1f^RJ&r*edBl>?h>GsQh38 z5!z6GOdVeu*?SOYSq`WjxzXuGvEb;j4~PjoFb{<35!gmkMj=CMxWBO>Z7C=Zv8oNR z7{&Kka7Q~MlSt{spEYCPZIxAxay+3(VA6`aVpnr~w;|Zp%CV){OxxNwXDw;pO6}W= z1{rqDkAj6kGVA?2oz}6m0mhH0)^&^rc(i3LA;lCaZ^`%VXLPb?>eye)P0MtGXZF@* z(yTsHD209tV!soOD|WgcZ9@VN7?+>k;_JI-?+(&(u{O@}-pg}c2yoC1rTL%VU;Az6 zb#-@{^=__@&ZB!-k{WXttilZ6+SA;T#P~yvx@z4QhF5Ec&jm&zr`>43!{C69AK0GL z(N-8fOiJ_Q74Gb$)R__&|{(WoaZ^UlG~fjKZOBE z{n@@h9#F0j-z>E5oqdTgB0n*fzm5=>)4dCO-RJb62lMXKd>a5{pH{+eB9$2fpo|?X zR+>z!o+8xL1p4R^P*Z|;X*;M@Y&&V{00JhJjIfWxTZ{w5+u?jIy|Op}=E;sQ6sJcLvs?PG@L! zJJc>gXR5ViWF6)ih%YbKKypTocG6 z!mlW_;xC1>vM-HDrElU#g>T`r+OJX;=}(4Jvd7+HwMDz4Tb#u0<+h}JiTTb9+V0Zw zd25+OzD4I#)M+xhMV@&_Iw8$UQOV3^%5s5wNv~$}(>M&0*Ji|d1v*)-LYMf8=9+m- zP4-g?O{7z)>QZOnbF!^Dg1E1u$CR&pUdl;LLX9PY1a1q!7;lsK(f0ZePC?uvf(58b zvnGl~CYx~0eBNr^<}D6QvpVCu{nOT zT9fQL)};cS3T{z%1#fxGN~i^D6Y{#qzpj$*s_y)lg_1lF_wM%c_Tu)OsntT0Hl2=E z`Sk3vIde1Jy4SiZofLPqiIv&ho0LuL6E24{=C`nQ+(awvvghJljgGNtJziTo4s23J4&_Y zTbTQLUo)gK(RF-DrE~wR*ax_zRq6V;P}4!MVyVqw{#c`+8Dtf?e3DVa+TPGa*yh+o z*v_}&yRTXHIn}K2-hS@?B(-92xl-eKDW#V9lze`?ey!6xU(@beyJfGlV%vUY?xy|R z>{Zii>1Y2b^RC9e@^z@%#NXMyuD6Nb^lkq<{{_0L{@nVEe&W9}SpRMpH{WSXbh*kY znY@DE+WQhw+sZxf@Cvzdtz9PB%zU7HR^?sqR=VEZt{&}(dX&9F^~8L}?#}F#zTT^u z^=fB0M{4uS<3IVT|B8DDc&u73Rdg3CK}=GRhHtI>_mLN&ubSlyXEq zvE@3xs*ZJh+9;&_wi62}Jo!HSY_x6c(U-7&fuH~GdOE%MTrvN_n3uaO+LPc|WTU|s z|HFnB%77|XGsa3FHZg~t_zPc*fv$**!-vCfD39~glS&z`eUDsd&R|v%O@6L`Zb1O$ zCl~}g=^rR*;8l0g>m1?n+Hn@I+cU4%%(jPHjv3}?dXz)gt5=pj9{?$RiDOP15Mqjt zkzQ+5-wrM{1?9cU=`cIbJdOHeqpH30S;z+6Oq5z-P-h^x!otXg{kd#c40i<$+Q9N z`k!CfHi1a{U|-0-WBh|bU64q(h&)payW(BA{2<cUYK$kIkjNOLW)KUQZ?)8x6gH&BNIw$#F+BD%C{iUC(Sp3OS-IzLu(;2wD zzNBnYTbg=_@bI5`wY2J>X~#ZaIfJ&oo1{>E&#}aL)HJRkl$mWt1*$6K=Vq8?Gehk@ z?Gp5Jah*pjjo6Y2O)L~p;Z7Nig=8S9=?x%V;d^JILRL@I#E|wdRivC>`aTAwwkGE zmeI21T%;?)nAw#M8^_T!`1we8vp!84K;%}(-I{mU3q8BHdkFUR$UPkzE2qvsx!yG@ z+ESYpF@wu-eZ|z?sDMg}b0PU-dX%3&cw;>Vyi`ux&e>vKseVQ?+^l^rSx;m>kyy%* z;%3Jul|7N@SD}*%44=U98LQwLu@?!0BCtryzHrh!FUzV{8YpJ+XWTt>hPw+Mh7%GW z!BKtXZ$7>6UOrDh+n+VV0-idTcFu`4&$MQqDVUyOP5pmiVVx1rY@{9qx@=5#AmpH+ z`(OlDVS-qg{wxS!S!4ZXl*TeK77FM$h$hkx1r>(|G7W~Bgo4w!bkAe`sEi4?NnnJr ze6X{Mx!_}1$Kw6m_CXJ3Y7=fe&!~o4(1X#HmTSa)Q-prFAF=f7cc1tWd#e6clnZ^{ zN?lAy^Im|-S%9#9FWUMYeb%I9wz^l;O?0Sb@b*f6BI1YY?hl#Z3da5WLEF9@Q-J9w zQ450$!`4kH%5EIq2YVz`kmy_-{hqu6i%jZ+y#k9cW_n5q5wDK0SSZwkf6arB zn8Df%tRVy2b%Hc(1g_|05n)8QB#}WxxRjy%s)&$%`74R@3%_grz94zX+Ck4%Slm67 zp;c{nW^H&sB!1Wce=`(#h8^uH0O(f)@x ztz=>&Y;Iy?_20jXRkiF;)qa01x5l()#zElakq#HLkAiKs{e}h2??S+E6uJDNYtm+$ z8PV9k=)i?e*luqsQzXmzUBIs56ELr=0*0+z6sTN|xeQi@7M5s8#b;?=t zjOBk=Ob)fpGzFDRuWJH1GqE0?s36ah7&CMJYC}q9cxusYP}`{O0$gG#VT!UDmHHE+ zO)}rjO2lNI{TVg?l(HTiMh}GVX*Sd{ffxUZqR*(L51lT52u{x|O4OIdfJLdVptSU$uge;uuhcJr2-v6BufZ$eEbcRKfTz4^U-((KOe?C?1ztO{)TUm> zC>_r$972wyI^sa?MImh@-G8R(UB0e!Y~Zj$M>;N#F3qi%AwR3=R;DD6E>ay=6_%0| zevH>?yiOKT09~oS`Z{Dk-hAOL8O@xuUdMa@k`}DYyA>o|iRy^OyeWt^s}~z}a@Q3V z97VInM~vj!MsI+mLa&LnNOGRqEs9j)GG#0^;&v@_mm7Wm(=>u(%+*4iZ-k5Dl3@?3YkFt?~N z7jy9rTo9V6%P2^>WSlwU2$MTn&t)`eZdM7hH2+V=XqNKLT!QaREqV_#MW;7|+pEV& z-N3USmx`6X{>ji*hj-H;pj5@PcSqvltgm#I_O@QD`>}B+sr(+NEucKbaPsEwLe7r( zj@+Jw&#x$jUoq838!~KW?I>#w0P{e7EA&5FV{~pFR*n!k%Rke9d}K$F%H^cD%VJck zBY$#-@cxeN0;)iEr@-lr` zVf&zEw&B$>cyMRHDDRT~>Fv|^YwY1g?*!gOx&0Btxl2=UPB=q{9GV;EjBdVoNFMZC zPzOKW(qZ4V>IL)biWZRT+d++nAPKmh!v{c2!r1=ua59hTU}{qAMtGEJs_Kk|0^mMv zg}Tz0X}><#LOwebKL0Zf zUp_~oGt)j?L1>XO?oFBoYivH{7fQNdw5VW*(%cHVKdGlgYWhs?0Uq*q;lufXIiR%!=_d z9>XN_m9!}=Z(Z=)X8UA8uy8VU*I)nlahVw{YvDP>j~{3ME1v)VYnE0f)+Ww&|IO!* zQSD9Y~wDz2pS(G0P_=z9*Sw ze?WyGcTg1PBR1SfoujlH4cVFriVN9}N$@_bLV*Py(;EZJVhgaY)MGk0@X*yJu%>8cDqVTWtCqw%Lu_ku z;Q{V;Vc0f|TtX!`r1KWRnla|`T@;wv%Oij0K<{Kpk!Wb^E}7keH2O~qaN_myJoziD z*7NHagD6#y=qCybCn(})fkG=ujPizp1>@+%rb*!oUTVXgozrD&OQde*5{%3dcdW}# zZW%tR@&&U-5+W@T5@uR|CeR=t8>4_`LO&cL;)dsMqqX|wMJv}VL?M2%j%dh>=#OwB zH@hfMQVjXfA;fkpmaSnjaYa=2ylhIlQ_#RQki{9^tn}-Z9x`AcF+xp{iwSUaZeFk* zPFyff4EQ)ijmi|dMJqEg`FL}^l8oz!^WaD}VzX68vdZ|%Q@@+zF>Me0U`r|OSQ2z|^ zvbI8Q_OU3}n?1e`UgJJo$P@vIGX7=6bA|y8s^mmefvu;?A}&BfbT3?G(EualAU`hh z`t*fQ_S_w^ROLfp6zR4imT)gAlJMLef#2Y5&7^GrK2ss6J$_yXc!lEmaXD`EB)F3XTQIXU^%9kqAymgYlq z)b2(LzjyH3r7BQwl<-CzpJwQWqANo&H(zQr_ZAZ@uJkLi_wtRAyYn zBU&8`*!9H!9_WpjB&S&-n&`ZkkiR9w{~rE!?joa|;jv3D<0x#DN7GbuG?#D=ze`&) z`*)@?oKGV=Tx>+MTxzcz{dfj1hr`VlPyMv%a5{lFhaUkIt;;;zxoNeA6=U7JQM+uU ziC{`=`fy{S>9Fj&JFXg4jU7ML2DW*SMZE zKKwnegzLAtwS`?pweI$ISH&^|motXMTtIa=LZpe26iZ|#&;*tfa(ln(xS_KM&a0;{ zvPeSZjd=ZPv3@&eZh-=}-c`@Y%SK7bD6tE@aSf&5F6U-aOY14Q=&kYAF1{Fv^V{ z9_;#BNbg~lT*F^JA*&K-`#~-&;+e4DID5 zCCIaMb%u&2)`zNoy8&uA8EzVN70Oqk=k4KnIM1*rnU7F=5Cpj9Zyu( zWyXazT{LDCQGmx3U7B)sxY04qr4xLjFP(j) z3G+8cnP6egn)gh9Xj3wtcC@R6B7s^=QF7{DLil<&#a{=A#C2G5BqG1X%)TTYW6FTQ zts8hlYO{sVJ#0aPjo&2zM8nW-CMSr-b+NylF~+)ogW*2O2HVX2bHjotaYnL|K8P~3 zr1@}v4TNfjMBoKMbVXE!*@Jm95*j2Oa7k)H;FNy2=B!HgykmFUIG+j6XA_HAkjc5` zC3>pedt*vVsB(AAk?0)K$w)aXv?nFd*KBbHwnN<0f5U)oJtV++({?c2QA|uAQ_1DK z;FP2!QPt!8TNmR6#{1G&q$W`)b+ou(Uhz2Ye?Ct>8wg3(kOoA01AV2jhX&y7?s)-* za|UhrDzX6P9j716Sd4(ip#$l>I}QxiYkMYJyV&9CoOp0s&f#-5_ouyRo zc*Sz_QD&hI;{L>ge6i%NrBYxGveRN(Ihn$A&nyqy@UH24jh za9xA)hz%%sKii#PY81vZm0G}YGq-%j7I^=rs@wI6A6bGeh}+vftFiOtfa=w+8jsMl zS)(%sDRD;}<4+{T-nGV1RkUA&qd#K5!T(FJfn_7)+5P(QBMA9_6KqKTBiKa51pl8_ ztM-I*S6*6r(tOWiKAtlENqR_{J_P~AfaQoyx?6@UANONUAPz$Q_aJF{TmUI5dBiS0 zYs=$u(uMMm!)4V>zUQ-*OlJa+s9L+0S~Xe$9}%< z9Pcep>*se@%`4l3z+T^diTSd?+y@2B;|!i{@j$2Uq(h$9dY>#HB)LsOj8GzY18qWX z-be6Zsk$%u7*K>T%p(EN^}REZuP8z;)$-j!<~4K^)E=bRQQj(emGH`4KK?K9Kn z7~N_|0h`=&0F@p+shBrHgex~18s2Ox6F_3BO~Z2gY(VM_XM%CLvDS6S2|~g%Q&j4t zW5@-c+Vaf(ousbG?P~*aGFMH@%g-oWI$a|N>4`PcunaoedJbEM%3&)y+eQw9Tdt@T ztxa2pu;FYB3c9NX_n={_#BOpOYsc1cUW{i+D9kr=1iPeM?bkKqTTu)>>svAmJ$FB^ zL6;y`EWfnq9CanHED5bDTdPRc+R;T3Hyft*o{mOH zxZw;hlyTXT`btY+#ty*_i%aYoN6ffTWe>$NYAR3P{Kncw{`wY{aCb>#WosB!Wh?jg zzVv{k{#wT$x!=Cdoy zuo6P-M|<-)Nd5gzotkLFmZEmBm-&_`t{O z#^?c^Ls{k${&o3u*^z}C&32Bm-DWia;O6>VlC_*(U!(3+a7;|ASy1%kHo{I%z!b#3 zwylVJt-Y~8K8?DQR-;wc2?7eaj6Lv4B(-#BF^;nKX6>Dwg+!lTZ6;*I+r|rFZN(O8 zR7fYra!&Z|9>9VX)++CJmf5R7ekF^B9^!Hbqo$H`FVD}%MY_0BWSQ`gv6?Lx760r1 z78~df*haY)%Xb-KGq}t#_K~BWYfqu7HI595cv3%JFPE)_5TV}Q+KBxXA|5kyX=4*p zS_Flw6p{1NMOx-4iPs?Fc=iGDn~dzHY)=`=8A~hhm6t}D9pvQwqAsKJSORiSwZiXa zC5quSCDl^zC0k?WPd^JcQ1Elo>hkb`+89l0BTs>`jCILjThvC8a^V&_&Ayf4MHv>> zTw<+`Vt@8;U5nAkR@|=_w-02}Nq`I;!5>F2i=fbARy^!DSaP}F;wz`h(*A3Gt^)pj zt4tdcjA-2xJ2cG1mGqAY+gtt3)}}#$D>;+M-AnonkU6`RaiP*rG`EJb!-CWZV*80V zvN#6o?jUZz!^}l&er*TwKkN zwuvsT%c?C`_zARdFXnKvBDTDY7^d=wicke4RHi6lc?&2NBjag_2ue-q)Bu5}}2NV+9m z1{*X`^c}CrP*4Dt$Ip(z8@osxQv38ThrQm_qEc-j6BGTQE$)#)p-sTS(IUfULNZh^ zLftHArWtS*Jy{jY_)X#~!4wQxXgopf!SQ#W)J}lAC!gIRpG#1+!ld{MvT`0e2o^@l zFhZFQ>W^a!Nl|m0ic#|Ez>dVnNdX@wJyfBbPdNXw_Y0@?3ciH<8?S)+~@YY@TBD^qAI_1ZLJyrIb} znO@2H?eZBu9$+p9+&Q`!=N6zOd9zO7OI>iVQ+B`ikVj9G*j9s(b}mZ6n6#?_ee!+*GGcL|^&2 zIeDMH+f?WtX^OtS!3M+obxy`%nft5Pw{=l!=#vu$?_2XM{EkU}i-)|v+fqT{_k*Vc zTj!`cI=3m|xr7Hkb@CY$n+YR+|A&uvS`r0Xwr$I{ZQHhO+qON+wr$(CZQHh8cda z92SyfM-!BlsW5_KC6+VZ8s^TThZ<9^Frk7ejaA8S7$lXw70DfB@pQ2=H?0u%%0+)N zS)*AVOAhPWO6<9zWyro{uu_z`k=j3B;4~un+q1oUC~`4Q0n2_|r>TYT^AqYc=EuK( z68r?~4)Z`5t3Z`&4fSTS6xOgcwYElZZB>CDL{piXeF|JVTv?)Mo zbSWmS01sO3uJI-0li(Ns9b_Y%lGc7wVi%zzk|M#c5&qlgHoM2oMhnRLt?zn4Qd_&m7(i|3T0QavK{-L3{{aKMImr(hdu&Vi;!1FD>uKC@+ zH>@#x@D638WB|CAm!%YiX4Fb?XEh4ETqO#tm5>ugfe>nHmD*N#c_Xy<^t7DOU+Mw?nJ&I66t{C43T@}G)?lH=3Y3spa1HW{P!nxb4{WcR z+#FOGxcCkV)3zxphS;jr-}%$wm!72n zAc29zA2`qA51=v;u>l~t@TetdDk&B(L)|pn*g!sEv`k| zCRHu>qM5hh*BAoc>%bQHImo-xB*V}_MnVBduIqoK8njj&DXkxF@k&qQ(-0L#L$7dq zh6BvvP*cjctXeLaV%y!wFngT7Du2Akm1^{!kATSJeL%0&N5$8v;`P8PaCR z1JetC0;3E`JNlfQ;bRWrGH+nj8_n^FlPe{+4E5PLav^Ft_NEc`1#o^_ypC!pMd;$G zTx>)VwzfxmU<)wTSOz+NU6wyE17piR?rN0V(Ba}0`Azw~`-kPCyK(G1ee8T)^rXc5 zqP@q32Y}x*ew2PwmelmiV$zQ)q|j9UMoA8G0F=Bv5kCkue0Q+bCkyHVHyU^FybiF+ zUGND{w&aaDF*YdG`@ke*7`60c>y2J`VkJi`#AaTX{y{1;g7lh@}Z4E(~$-Zv27 z0~};E&Odw3zmgx2`rl~jH}p^F?0e?zlyp9?|QfC2)9tP82&bf_}+*tmr8K7D|&G zvIfDjhOo7%2(xU_J9Yj>nZbs3yk$U&Jxfi==C_M zD#kTxJ(H3jq6LB+kIXw<<=Vlrrv&!Ei_laJX`fmPYD7WgWDs2d12`)=;*a(t{qa{{6t}G`vC@u@62`O$Q+WIF^{)|t8 z3$5mPx^1bkAi)6zb%Lqciz!3yKDziQ(!vi3w{1T4fZtvopBtzxU|g4vnt2=e%17;5 zzE<%tGX@Cx4*w`zOoFA> zBG1S-alj=pGA(jtd6fPA4LINm%b@(H@{L?H@Wu}$pwCPfZ~w^?o^*5_sA6JS1PZhJ z<{{?3T6+Ae?)~w49jQ%u*1vxqRIs;cSRyv|ee0E0R)y+vvHqL5$vRNYTwBJ{Bp5f= z{t~KJkzmc|92^8lw2e{MgMO7D@ljMa0wh=;NR?h$90dq7X^o@P8__?>p0h@HjpB!9x7H z^e4(!wnaz=V{CW^q+LQ^;aP2lICG#JT+T!)qmMq9jPclbbYy4_@4fYV{D z_PAoQ8qShJo1(0~rj0vgzM_ z23zVdvRKJ{3j_aHr;LFdy983aR13D?%4Nv}!+aam1|Tbk5Cyx+^Puuo@9}K<^IgDU z5Jh&NcfPC zQ8E-J1Rp_x5=)Lk-~~!0C2=P4DJN~8gAC=`1qv86ET>#9Ou!Q@K%hcDiCr^ppNInl zN)aQP`{O|~Ugu%PoPMa>LYLV&dIUkQ<3G7-Y_=e`<)+HC_!!FXpc|0>s+G8l^~7*= z$9Ome5H&XiN%5q_*;I4}RMMaa)MF(e&`Oa5KQc^2yRacK9z3AxWesP`CUgW4=?XD% zij_Gs4tB5Wd9vNr+dPFag2Iy4wcck@!XL5hw;O$R&#@FqKc`)CdQhVa- zkAMrlAoqsqA6tL0_QviVUwyErzYy9Zg8DQ;JkS;f+oMi>uqEu<7AD;x@%ps2C->3U zo&q}3-XZKAcn`n5gCElM>R<1JkNAFvuTOLh>-nkR?DHOycdK{z$3>`rI6i>s6Z?(G zM+tu`KS2J;_=G$%@RxbMd(vjmpw{9b8AHVRPLeGQ=r@USLb`v2h({M;V!EWsgIQ(<-n_#X+OnY&=)_okM#)|ibURY|W{M^J zYK(IEaQ*=67qcf&E4Mu}@*KS!^)amdv$xo+dlV?md*V)(OQz1yj*oxH)5&$MkT=3Q_mWwrGjTWGR}43&@)Yf=uOR349K5}A zs<+-;rxZERSNd^D51oB}OKOo` zl)8twW!O(cwoi!GA9o?2g=!ElU7$~l7Mt6YwI^zmV-D7(77NzPZV>dEcVfdCv_{>H z^6@((R@n_M6LDQdl7L?C_QW>!0}@xMP8@oAZ|SQUlhG~VgU{DLQw;WWt9{dM^u#vg zgX{;*1+0cee+ZN_1X`!+1Lg;=h^%CK%+YW++WKkalujq>BO$KMv(&KIjznS^W8Ak?zUp6Q$+h zFunmpBA(+trvX9T{#~bPzHby12jh|CoxDBNz7%K<%rEd)3SGJ2jA&Q(pRj)a6Xjg# zTnXzmkik%c7~&bla>(-3`rgjftL?m2Z#3NG&!~ug^<(?somj&a^!v znq`yCHRWyFtxUl!Ly$|awM6hxIK(-?3@Y@|1PHbGU~2Et1{? z-NNZD6?{bDBmONG9rm4*KI}bLzN7b$_Ld4CGW@{GuQt&FD`kD`nq5{W3P1s7;w0?H{0asWSON3348vnpD`@0 zUJSsmnr2(<1|l{q{i#X|8f^VMA+9{Ce){8;Kgk`2;1j;Zbc*((TkRg7@;zQ@jL-V4 zP?#!}+{ED0#+G*7 z{hdDDftRLsE*g#PP(-$Rx_rjq1uwhUZ_i>K+pcapNZ0Pdw@ug1{{6ehNv+8pdLL{4 zM3i)irz>B~kupvxm~*j5d;^U(xF@KofIlDD2kgo@ z8+G^8(upnY!4Coryiiy!E}Tafo`jkv@3*i^O5nkT4!w}P$LGcAAA#5z*}3Kh|A`obPL zxftZcj>Q82ig>YvNp`DmMsi-!_v^a}vfzyHD`k31U z8_<$^Z?QvM_7aU~Rm(1)L07b`O|N*VxLFt9kg&2-4Qmw$Zd4IzZcoizCvKylFLT~V z)=uW1jqVkk+FlTLY31gE-Fid)z($ZCOnKls!_~{awL2;Ku81s^hW^ z&_~%+5p$kYc&-+@6xwVtu~<`#b>lT~0amqSCo=NOQnTJGXm>-_EwL3m?he6QwJR}a z{6(_RU$axT(}qB%ErPwAXR=@=O*THJpLH+ys5Jf-b&a3MTi+cYUSd~y{f~PlM3zk( zdsJtY{RonZi(osg2|Mxrcq>ia>&I^5&Y)3yhk;qBX+n_o^T}ch{63~^9Vo#n4cy<# zwP|CXl%X#2Fe%t#Gs%ej{sX&#!#I`0p>$tp*xXU6eOZ#+bgNtevw+>K+2n18JJQ|k z$=C}bJ8E>yQTo;}@mZun5{;O)Przm(ThE^#Q}D^wNpb!K|L;aP2E$Bm1s4Fom*s!j z2xI)e3ZILKysL}4lckHP)BjoxyC&N^Bdel}=4BOckkK^*B9T~D6$&&eB8fmYv_LGR z3SIRdF0N#vu5!>Auo96@Kyj&ahAuhFy8Otx7weMog*9qz;z zAPud(i*62-m@DspIgoAI$jpXMrS91XtYn$A)OXW?oKs$#aTF?T_YQRTSp zF>cLvTEbT|_;(7q6s*{BM#0RTu3~Ck*l0s3x2SDZ!n?Iq?`C$GI-iKtEV10UHmxOg z^kF#WwthmDS+%9wT!|JO*wn#ggZHEwzd$&UT{*UJfzr8y%MB53+;$&Bx`Tnp$G|Iu zztNh1__>aRNScmi%Zre`lAtm+s%BJ{2Bz+mtL$icSl1UJY?ezj;&vKtSy5-dj@UH) z1o!u-eNA+?3BH^p6XREGlpL*ZjFG5S1JuF>%cv1r9zhm^3ny<8y8g=swV0wueQBhQ_j@NOEXdvGp5b-a%X( zT-JZX`;Kj@O051OV=i<5@T4YE=zYUEtb?H|1&}NCXh1*o~ zuU~d4cNpysaGXTode8rxG`L%@T4XKoiV>B$C-je_CUGrAPrO_#b<9*d&~?9oVfnN) z;h1$O8ODudGwTkF#36XD!e*Odl!Mk8CCR(Q;oX5A_V&nA6XClTt?jS`oEeWxYLBGQ zZ(@c9N?xcH<`XL>E@87@xX>_6VBraT2smGnybRK+MS@J}HO zG!jq{S*>YCIQ9v|pFmCE@&@r_{73Lg!O!gN|4uk+#bcRtOJr{<9BP2n8 zHm{$z>Zr=Ipmdp8>+sg~>W$Q~}iHQfR=>l9smxXVATyUdRpwj@2r%A-cMpO4x=4!I5QN_#pj zy-j-c>`q-s`D%5rh8Q3dD)Ir=rYtuWg0=|fQ_lfDKu*dyhn)*OTHY7DDTH1CS@Z9bt>W~Sglxu zH8jXooh6)DEm6{^=BgywT*83M;@GJDz-A_~;%4s*dndNwgwhR8kme1f)FNsVU&Cwu z`Qo4}TmLw2b5EG-Xo@c*c|3x3k?`NRyKj;JhkLdruTGxLP{C}}N zq5&is7YKWfoQ9EQho zpAuL;D%c!`huS=s`Q8?IkMVwoAs77>-NbXD{|&}xuOI&SDh$leWPi-?nI5=6k1~ALe_hzYpeHTjX!7zYDQD>5N)K+Sf zh!M9f(VB*waPQZQVktA2o{L#S zeX@lKU)Htk1{!Cgt#uh74DS$BeNRWffp}o2S4D+qy|T#p0siq3PBDYn&Z^7UV{;b5fy_wI z^`orBeH3(c*W>ABYG`mLqdWM4x$t2m3Tu;&fazjR#r&l!S7 zrX1J9S0Y^4pn*!%R|>6ptdN*f3Z?vRjlEPN9y<+8MH@xnK`JCwU{#iCFj3VED)_1a z#q1E~BCBvL0`3Ni*;De_6Y@-ivIo3lN4H70YMIRm?CD21xz+MYg|Kv)@*|#&&ldX&J`22aq*dVirT@IMjdeoTrkCg@oJ;Ot2v5RV{k$F6MRZkz>Bme z={y%h52&Wutzz?K2u(36f=aOp3zZl#>Lg1@&l%ckSEJP|6ttA3mR~syRk0Ne*3@X~ zb)@zC>EsnN>rukYg@;ya(<~k9Yn7z*qd#Nz#{(1Xb6C*9V7=RgEhi*r9$toPXx{(4 zy?A`mEMtjFMFD`;a^MUkE)&W0+MWnP95<(MNoJf6tGg^44;DSJ;qj|QUxO+KtZzlhdWwH8*ZN#_XP)wxvf8)kFQOnNvxvC!3|x zU$Rp!E(uu|X3Ag<83nwqO`H(h9c8S@-K`V3##+ZR#fK9%NwRcXHge=i7jTm9j{Zw# zl1MA!4a$xAWqr$GEA14{w+bO%`sFDuOP&-{E)_&a&h9%>vY%kMHv~IOU+RPcRpO#BpTwGSp zr|FQ4DV%mlqfE+fVK>J*7EHAf#qNxlRV8dCw(P8w#;sb~Hu6qgNn|VOta*SqcJq{vaP4Ac$0eejrwPk zB)ws!HysV`>LAiJaE`JGpqls|a|jVQ*ML)}>hHZ+p3?cYlHG3n>`8v2DXMyMGRhb_ zsr(85xu;{fz+dM1I`KF0NCfH4>w)k=cuA=4HRv;({d7=uh05sL>!b}QZL)$kyoS;o zO@`CBFW$5!ZIs$$;gdsn*{fD1-QFiI=j~xq_j;xnkJ$QFK|-Lv47vOYtpnVL^-ExC z`9zJYEX|SqO>|73VNhT$=^%e+j*@fpN>#oI-keG!${lG{vX>b!ua%GalWe}@5G3vJ z>xkPGV0tU4?1UWVJ|Xf2bU+yE0fq*+W!Ey|wDXM${j#8FjrawxDn=ysP!MHbf~t#= z88CtwK^k!s05k$&ny?q(jq(ALZk|3)v9V3&+dWPg?{|1NGX^=2=Afg{+Zx zx})GIe*~X{RWejiAmBl@D}l-Zq!Ky)#n2)1WpHC&d3~lz%4Rz|yK;#<1(|%yzXpTZ zj(c?dVt6mu(fYtE|ElN*=J62x-TzOL0NQTE5ndhJ=YdpLL!&kbcQQ0X54{?`LvBOv zgiE;EfV{1$efcybd~XIR4)SaoqcOQdWf-S?3L3GGKCiQ-ssYB;@9{|8;G3WD4Lo`! z>RwX57L+}`#uA=Dw<~OUE9%`$Xj$H(-ic!ViM?oCo-98#Ux9XBisE%~++DWxR*^@> zVtdlqKWI>4Vvm(lVJC^VY2BIHe_8tLL}A6kGyh+$D*H20NvnRYx=oIn$(UIcm_SO6pLxNH$dBDAR{N za0Q6WCkuUXAy&|1VjgPGh6LkrnQ<4cq!@Q9?m!lGHexHgDZjy1Pe7-`=ki}_*!OqY z4Br*t-5Cc_9mWkQ>EsKwE2QizneJPm4zySi)T%3PS57*FVO9UIhP~=b{L>p8CDhv) zId$xK-KM({F4-Fn6aBn_>P1yvT-nSb^m>}~DXh6io=Ki805t9C-n5UcNMKl|h(5Bf z%*A1T;&dbJJwB>?d#D0>aNT@PV$97RqBKV$tEdFxRP`$j&))X0{~_c106z9WF2WaN zrZ}fispt&c<>SmtOnP!YlJeO=zlaxazvNqP)`%gAEjCc?dpuM8^}#7YLm97|nyOnO zd_DdrLAd`diO(9HcB@u}dbJ29U)nZ-cIu3Wn0af5tQ z{3NAv_El#I??SZPzSW0~6GiONl2w+M+q07GpkSF?=_ay#L7_}XrIPw;KVZ{>`n0Uc zp_UU6a@n*wdc^4`X2{bkv?E>a&04$AnP!C6JK1Km%OeP{QMA*-@mJCBE8 zUH4Su`cq{Z(%Ncx2^d`FRmpz+diEFJJ=y7A6;=K?qVmQBqnJieO1E~YYOM-WBZUb2 zs)Be#{aC5;UMX_S?K*3{5W$HKz$X_nj&%(vm8 z7oO`IRwur;z2r?%b%Rk|TlQurQnDE#{E=O3H;CdIrDh8T3R8r6$k~Cvc8ps2fQmI; z;LB@AUlCeU3ZlqIn%p6n z>?xFiFQQ41Y#c-Z9nwe5#+%NOYM zLV^6rxVnFYQI*>d;_9EYFS%S^<`C?K#k|5?J!7t!HHR8q@FDY(MYy)D4doZ=wYC+x zUUrezgF)Q~_I7~si^20AsXZ0M-0|dEvs&{9`d>>z%cX<5fB^u|!}*^q3Hkq8lCXuL zld|dmHYHybZFOu_j2+?I2?Yi;Ev(2ERY*$!Xf+kO76pqSoyvmdXCur+U`!ZfH71R6 zY29BSeV+>W+7f!-iy+;q5W1}u^R&K!y~102Gl{{OH0HgJS-!8WJ=0nJzwZYuK9`}$ zLRfWTjtFZ-I!sM6)2|E-WknfdvPexG_=6`3qIaSHDBtN|J7P$zr{gZll@&(YaTh`E zmeEeai5C=x9TtY6I+4E_)>QBsf9&06VX@=(Kb&U51;e z@KBB3-9Hz9W*P(JrwqiE> zWa%|;*&baws-V0a%8J>Y#sGzR3U4`K{Ip3h9occI;&diFWZW?XgHtONb9Ta962V1( zVe0u+6$ixwV~PKX6^4q4Z9&=6iCW$F4nq!2?nqI_F zbpRE%TZK%+Oh=+AcByKGYRCvd+8*pQ>`U;C(kflnYGmk9u{LWjn^#n5%i@*SL{Y}D z8cIv^k37qSd6C5Y1Tan!_SBRV!-9=vQMNL2DT?Nsh8IZf5zg*{BbfbFb~_%fZ)3Ko zkU0G=e1JdcvC#OHg2t-DAq3%IQ{fS@Pj$hI1Fp4 zvnL7~`ukhk!`t(dHx#6W#aS(2S;t-ZR^LdKZ{-!nZ|aK)?byH&O0 zBcNsNj)fS!7Kd+6tlU}a7|p6DIda2dvk2wbYSb%$p_hMviV^tlGBbmN!KWYR55zvv6q7$Z=X#EuLRc@Ac|YPnMoQiYGUIqo zzK~t3d}Xnq_?rT*V!0HG(VI?TuN50VQ#Y}2BP3i~)c#uEz~3?>P{=DfL{H?*`0Uz^ zb2dGKoa>$C8f7Rboinbn;TR_bGR-<`=mdw5l3r<-&?hgUVBu#Dkb6BQzJrd>vz`g5 zjw2f4VrH?)h2* zDD^a+?@whW@&2RwbMLG+-#*#1O8;QK|`qP~Jqn zI1w<)`oG7X&Z&S)(_Z`C6aI`q6u!JoF`G-$=Max0xLDb|J+UQXm*SD8pwoBkt?;F{ zQ?^+9qL8dCy2ES^@ydF&-0WIIyuUAZE_o4MR<6nTcWA z-l4aR)tv&2)2atbY5JH6Z%mNz_Grb^`Cx3Ea%wr_QQY5%KY;%ZHuqvGk#rCMfVThf z48#8$Y)Yo)q8<*;|N9DqsvSN2c{@x8z-%?42DdD zN0UI&QbYl;P;@Ap?&G;q9RM;}%abq$V?ATamLz**-y3hqcb#Xy)#UTE?rkcRe z)?v-3?hSpa)5jl6YGs%094w%aLd|2{offjArZWv@=8r?KgX?h(W6=nVNRyVx_U1@-Jn)b-DKh26{>ej;PX z?`++A9ifa!IR0q+08dXeEx7**c9&wTVtv=RmYy^%Oc?hmD|FRE-U-t>2^6m z5^3j%_2_hUsiId(BSDqQVsBf?9oWt@Wi!KJ$C~!Dkj#WmhT`qf z$Q4=D7(wAA+Zi<8Y}|!TvC&`|i_Ph@^7(;mT@|Y?8If&QT=!urlxfM^{nLfx3lSPt zH?CHD8xBsX1!ULj_L38)#$oufkt~%+3*Dn#7FJpGo;v}5zh#>Jz7;E-qES26TGb;i zMmFIiKavlW8M}osp`r(YJzNW4_XP$&@EHDnb;Tc4Rt3eENUZAe0{aP7;6fsg_+zy9 zdm62JRO)-2ke$%723+n2U||dadQA)_p3nMRF<9*LEz*J?F>_a}w>Mw-y-?3!%V+y! zV}iq^NW2GWQVd85QWtdDqa1gGamo$aN7KGnhni$QNL`#LNYP*;_ag#Pd@_+R(9)nu zF(V^e zaNhOO$MfOEu1_TgdF>cPaW#8}7jYVH=u;Prk>6Tdg=_P2dmRvV3R^qXR)uzT5l9${ zij7ci&B`I~P`K3-fg!clo7+KsQ_yeqg^BrQju*ScbazY8zEzRx%SWg$9x+4}M7w3q z-wxSU+cOb$y+KvSBSl;=??kX z^T&p(vlvOo30p7-=^kOhC?qW@G9^k*Z8mR2(z|x72BnXCZ#v6X6_!KGwfOyZ(r2GJ zRp3I`y*`wDv{6zf(wdXg6-vjG8f8=msZtb4(A?-xLevjV?gYb~xfevpDM@g@Gtk5> z6w%1~z1h0CQNj&RUjG;j8bc^`0QJ>Jf`o`9wzF4may`7>mIfNO4}U@-ehHc00zBX1?PEZ~Gwfs$oz^Co);s4|E1vl5{cYi%PyK*NVEBoj3&zb25m#%w5 zUPPy&G7&o72@ZeWjixDkL;EH8c&(OZ8t5Wves53z@Ar&7{}){c;c&#<+4v47GGB^E z&vX&v9{9nB@l@FS-4GsQl?xpJtRaz3d$7dyhRb}_wIzGvT5MZNm)emWkbM=3b}GaR zko=#&(s@cD7x{yWBIh07a)boXp~6Q}{;2Oi$LtOK8BF`YE%D2Y5f zg15I{wvv!DKab8)#_krR-e;}eJzya~>i47Rr{Slimk*+15Wu7VY_($}gX-X5h4;Jh zh)e^eDjkW4nqmSiXikldu9;xe4A>ovI05PhGa@u1tWyqx_+zc2`}6Z0iC!=1C(%Gl z4FN?B;-VwZZAaOaemOl6>DdZLnspa zC!58!`;=KwFw(zfn?RwJKPenamSM#+a*lY~K-!+rt#_uHbZ*`Y#QsY!(?CC;yMu%E z938#zA>jil2}|%W@##Txsp^zyx*kh`ynP8Mlv~89j211)rA6|`08YMAq|Tfg^U$(Z zrBHg`(HiP$F@w5DDsiJTWq-_68OeyDru{lTT0r_?S#>lx7Eg~zf#Ac!W2x;xX$F{y zT?=??0=>)W4JRR$^ksYN`#q>#phL+=IXUn>!foEsg%Mxt~ zLF>Y*@>B;6QlsR_m6C&eE&*+v89`3hdg;5d!gORiDLQ=%M4}NE9x6ZOw`3C9MM$;| z9_u``ea|MurJX6<%9uej|D;PuocjBCo9)JCcUAh0KCooieCl*`)00<#Rd%Ulv_V4% z9QIbU{T{?70>V&5B_#2~mGLw`!dmte<*Eo8X~=nf`%qa(%&`cYYk7XJmNI=_$I-Kr zobW@7fBSPmShdNei`%Ul(=xJ3by&DYRAH8pw!L;sU#-Xm2DaP?sM)sSTFjrb@S7R? zv4xS;L)97roh>g$AJ&(VYD$hS7&06SlQi3nuCPei##JrkW}83&xMXbx2vqL?)4h@S zPaYqqTfa}Ueynzu3uUz$HIVO|O-FCK+zM+I?A{#2=j$ZyA=<42DAhm_=uF*hR!b|g z4Dcil&j9OC&E$xeFYAydSRjS+ShwJg7Vjtnm>Hf5tUij%RAAA=#ERzVWxxCVX)2#&mo)_|vfpR9A3r=Hlx!sZf_za2;(0 z=d?f<1oQ$yOm98B5+`DMt5GI{{zd(0D?ARj5Lj;fayZw6W4WIbRFHH9y4K<33Bpit z+@@(4F+gVDN5X$2e*Q>qlm)U851{bG<@N(|Su9C39vI~2pD3n>uW)U-_ZeFve!@3e zGVWg{tH3NU3obO$WPP;%5jdh83^ul>gWSiv15dMZPg5B3X*_St*m|s(H2l21Q`1Yn zuw+f%gw+mQXjbrCMg-SuSzz8R5;5wP!ca4r@-NnY=&yd-)TgX)1|`x~Vc3s;h37Ux zNyIqEl{_(`yHH7KF=FCTET4P=>#>NjqCt^i+r4GO_R7EI`7X;$VOs@@!06Z=g!0(Y zc<}s?kb~j3g$Vlt5J%|2cfpbrl<`?qhy{l@y)nNQA*Mbf!1i8PaqhY=teqP%fA*i= zLX0DYq}cpmE!TtFt+;W_zWxULx%Z%u8(b(r>8*z&a)ml8^;A8ZXQ{?kQWcEzcF#Jo zC$^VUf{`7hC<0YHe5)q?mb&MOV_Gq_kN`70?V!DVo>7q zbZvfyqw?`GBx2PbV^Un65KOt?AB!NS&q;d)Mw5KDx|VH`Bhq{@lOsu5JbFYEKIe}w z9UGkv$Q%RVcLv=iFwfo*UK6pdr2|H`L*=BZuc=MlS$P}V$4cA%<#W!<9ak3vq09GO zglGR>kRpL%Lx0g#_S_XM(~<6eKGTq|g4xQDXt?$k?M{`_H_HmPXl1KNg8zgZ$eCk9 z|2N!0OuRME;&8gSi9FzO&)h36LLIWUUXpkPlK!)CXkTBYqb3M1(YE&dWYFNAh~-Hc z1d{DG645ZjwUcpuuxLNUb02J95r=+@tV28ZwcSrv2Z>#T8ys&3Sq7ulp4NFcSB^8R zf+Z|;ElsmM{_WQ#3s|>&pK&ST&+t$z-C_-4IrQpfElVq%I*`4&eewhN@7xF^HyE-a zyObxqly}9?`G8|6dAFgvJ7BPiJ-|Iz-D_cxt+E&59(=Au?kCz?AlGWWcgg$cA|$b= zGTw&-4^11n+}_j+DERBe*HN6GavANbXMz_h^xTML_|F?frjRz^lGk!tz0Izo)F zP2mSR!@G40!CLFMiFOPB*2B^`!*Ib;&ls-Xnhq~gxi_A7zCyGX-dU^3skdO0UPuIi zVI%+-njUeLChe-lwP9En>7~o)0XTUEXg^Dx#NBLo8?#Ap+jD9mlf2m4mu zKRMq_DxS#gBU|)3jPRC5XDdZx;$fQ~v=AOkPGHj4$iJ^1$Xs2)OWgmDv3G2)1p3;% z)3I%%Pi)(^ZQEwYIk9b<9XmPcI33%zt$zOZ%ri4p^Wv`g2D@rsSM7!0+6yrd@f+d4 z;!Rutya+u!7+5*+{~M0t=Hu``YY_&EE2;!6n9#;>5alo1elQg;ls6O4Aw9ZnU{#<* zB#b}7co12KORh;UV`3Kfc3j+4oeLGNk8-*nCk;13+7S-TDfBTdmlRfYZR(0^aAkk- zytprZ&-`U%q_fKKOFP%dHHmF?O;79Em6FAecU?vg>pQ?kAv#c)!LLicRq)Gdv6Smh zhmGT8ZlR|)k`iflO>5ySdnt3GL4z!}f_yk~{Hb2dS=yA$qD2L@%yKEGRDM*>V+T)U zLDiZ*rMSv5-58E2l4+T_N1vjU<95m@E}P|v5=~d0JnplH zt>A~Ir_-g64SkjS zo}&#`wtQ-90%7ygf&~ zMro$_WCtXsT{Pt=^M_F%$P{xwkmBeH2soV;4hUqkx+)Kav=;_f;tp zeDu`nX)32jm)0kp;xp&_%aQskHCD6Hl`DDhDfk#o=$>EI50_2<>t)RBn4&VFevdCs z|KuIYw~3#-znW+?TxkiHj;SwTo43xtYBzBs-1d_r5_!f~UaMZ0hj09>Wa0G{-RijZ z2b8Nlrcj#Xga7enE#3@z`#>GY!I{qmW>aPp$_wLVpcfS2EOZCPFU=2$f{`##0y3NB zzJuhK;fGSf_&d-7a=Ycf1MiXUfn>sH7^nf+-SXZ+_sH}>okTeeZ~>hL+krO&Ucj5d z7a++13Xo(l0a!4g1S}Z*3p5%C;YQH|anb`3oRc~r`9K@D$W0-WAjVptfOp1fB*Z>y zeALTsz&^w);EwK<|+Za{ONfICVWWJq^rnPuJvuJ>j8N)zY@~e?X^i@VkwZpOL8hu}pq9tuMMe@5}GY zJVDumm#GCu5^OGSlRmk=!yfCPl$wXm`>}hr4M-rK^;i z=qVO{)Q$ycFv@gJLEjpJ-5@|dI!w|Z%7OP*QN82%7Tafaf$CNsR${%mKL=|Q`Iihl*oPvtD9{^BBBLsh=UVT}-Gwm6P+ z_wkyfu9tHTu2(nF`|EHjp|-vxH?qzmcRxLzqMzlanwCkY&071I3Qhu8ZsU?tt z)`4G7XED6m20sF9DYXdeSC{BeKFRwTtFl;=){5<#rMo7$VNkenH*@x8Z_46?r&A)W zWHP_;ES&|AOBNdah4)0etlR-N<`dyyInI#(z6euiFF=3*i^Z>T5>Z;Xr-9fkqaZ0GM#5;_ z5fu!!%wB7zIt;T4yBi!4xw?1@OOkxp`Nz5=9u29X&}i7q|0f%w%`0w!^Zogn?JK6e zM5T+Z_tI+ax<(#9VQKOk7M(4N>!13hcHEV}fuAeZkDLLcq> zbqwvuF%9gbNWo8}NZFd*ET;P*gyn+QXILxDsX3!aB#;&V-CN_2c!8Zz@&wuGAN_;v zK!noj1kXPBE8pODauQ31GimnmUIHO?%RwHtCkB!{b?d2yy?2kBdX;ca-F9vik9zy` z-$>{c=hqDW=cj*wEsgRo1UvX<7UQT&V;5@C8_EHODu~FK0YBjzu`cA9!g{+(1iz2O z`Gse3deF>0maa$nJqKU)Xx{MEgt7v{h^NZI_^doBQqScZA9^()ay_b7*V- zczpbh8W7uSs#sQE zNd1wwMu#!IBf`t&q0`Z<->R?`a3NU~=Y#DRdxgnTx!c+g4;k^*xAv^&7>vM_^q(#< z@Z3L-WegRy+vOQXND5yS*#g}c-mdVMFQA(@!f!0&W`wtka*?fv+J5lR=u%7#cQFm0 z1ma<2)7x|48%gz96QTn=v54b}c94bDL>SE&jK2IlnN_5_H){;y`|{|$rZ zsc$G^s9+jYu>JPLE!>3aDXJ_Z9g&NL55|SWLPIC}d5*B)nmFj0Ef1q=7MtO83uP3W z5tjKXDhjv@Mqy^T8y6S)(>3D`UUwQ})Ad*IgbHE8KA0l) zLdn!Pwc_6I`+aByCrBXdJEX0>l?pZ_NFmtS(T0Xe;D>1Vq}i;?1kPAlOd0BR6tmNG^@}*@_1-pkwBoJIHF*uU6Lv5v zJhM|4}{*^3v%iOv<+NiBzj9U#9bkBFE}ikHP< zc%jz+v9t)wx5`-3pNP0pwvsOp7S+>cfz;ZvIo*TMt$b)yz<5RBqYb5tUg;ulwPyCL zU}u)aH>S3f`oX=ERwJZwCBo1HB&>l9r=PZZm1{mR*8>`J=8s2oAat*@a|DS~g0h>m zai>D3d6ZGf9h1i9SjtEBCC}>h#BXVlIfNRyUV0E{e-yioLmgC=jQk zs8W@>Ma(9aC!T?>)g+0#ngEA;Em#thc^rdT*}+ z`Ik-g%N1q11yAz{0m;_zvy}tyMlOu^yuos*r>rkp&cwr?vBuyf+Cv((CWr|xNPlsC z;x1l)5xk18r7BzMga}gyGZMn*4^ns6v@F}2q6I*7J-guWUs5S(vD0osU-{J_r24mwTs+=|H`tJf zDA0bxIS@#SaWnYRhq006BJJtJ9++}B9E8Nj!0$C%b!~HWThmnj7OlKY!?rEx(sLo) z$SN_DEpi$2w0F`bOFYd}hs~!s!d=L1BD#<*JymD$>PeG8Vos`LRzk!a-?4m z51ECY)YMd;^Q^?bhMmcpR8In`j!f$wwDFVgXAq%MLUcFkNv#h65OGf>HwTa}*=H%N zNuV)J`?Uyb4jDX=``?g8reSonsdiHLo|w^;?v8O>NC6F)6Ticd!+XIMmHROG~& z0!Xj*07O+OoOMba!H&DIDDTuVs&-@9n&a>PB+CI17l}xd{h>cgE|OhtJem=^QH`|j zc|uT35|gQo1YKvWdcN4wuXO5Zj4aLyJ zG3$o%nqZhbn9|Cxs>(~4&E1Ad;rfKO5irdW$7nWHacD|N(bHF|B{EvKkSZwSs3iPi zfYh)Lz(+tBNy3W$C%p)0asu2H>}7|&)P^;XsK0!h>JeQqXVWx1AXj)Ra-j{gGd*H+ z1rkIuhhi`{h0$M=MN*BGMDz4S#wBEG{lNU>(BD<%K7Yq&Uz)%g?To5qb^b;DD^rzQ zx-{v7z~^A68_->;)ZGFJ(`P}N$%@^bd$6Ga9yH9fPwWu{da~!|KEoCpTX?^ zPsyn1DPgFfek*ogr8kos{HXJ;dhtY9{6GTnfom#@6oWwY7DY84I2(0yFmVli=P5V% zM*hka9CM)46rj)qx0@%890%uF?qqJ(&4;CB(AW1plFFkQFOZQ?VIMcXU1SuFlS%`T z5^Z=6GQwM6#F9IB;gWwivIQ>JZrDeEcUU5x*u+g{#5#F9wh9+VS+4#-C!VSh=O!Cv zT6Dx68$r!*$rBp}3SCZPqi%iM><0^F;aY3)#WtVbz5Pm2jZW}u;??SQqp;HR4WwBo z-jAamJ}0Bjf&~c=#ePL@!F|Ojhw%OW&3GY*}_sT{-ve@w6DsbpRLwD zCC{d7)rJnL>*)p`v@7_SZUXS6c=;D>=%*9M-vISiI~{N016xY;g-L(w# z>ElXVmkW`tTGW;6#{2QkZq4zBlFe2PBz@NW%?sOfoci+Qydzg2Pw-)?UPF26R>)x`byGU9uGdgKd(aY@tx>kq7^;P+8ufk0=BT7qsH zse_SeMAB<%>D@6ckYj+Pz7~NrvowT*@BB_XSK--(^*=PCZ-vx!=;a30sL7vPfZAg! zL}RGGl3<>I*%Z!ur^J1JpRAe(EcGLX)YI`tv+{U$*I;D)5z;3SpFi;3>UNY= z;tX@8k`II+CCJ6cPn6S!LcF(|S%TGDMo^U)=M9`XzXVl&ctpN5R1yM?Q#iT(dV)C~S>`H;X$_xG4(N{5^&sV71>csv&w5~MX* z7-mK)Bn~P~5zV8?0e$1xWyBM{%2O~Gq`EL#RCU0f+HEpSqO2-b6>Y;OexS(6)Yb?q za0}*duh;Pm51ZBX`*cvyKL{uY?$W^lX9D$0;}$lcfsB9BPzL_~YF&~Y%1wkC?w$uz zjtb|;YHZo92K>jHE(@>$YJX|q9^!`zrn0@4A}Py$ha$6Vk$=-F7egU-FOObf&0)v$ z-uj!)#=n{Dy2MdxAB!4Rhd1N`iVFN(k81F<`9trKK6dUs=(eD_>Ps~3G^1;?#}1s_ z)_`F3H8+S!7aFZ;oR7f5v7VC-kp=!}%1Z=}8qs#Y`!cs>3A;wqPAlkysr;77;2u)` zdS{6!)*4UeUwjtC)ua+9Rm$O>6~2p9^Nm<4<;J@TP=~w}vw1gmzYuy6Pd1ix!;@EP zqplnB1RXxyr5OAkgj9IK8bz@kCTiX+{5DM{;$MR6V#_E(A$T>5^rTR_pm>F*u*cXd zO4pTK?>pkbmltee;+>omr^Dg{5pNxnKOr7JlAP+xlNeT_4aM`J-i7xnot~*`-+bQ8 z-*XJC>m<|N|Mj1WPf|ym?%{)(qS7N=LDGrUNb=c+UgGmk&mx5{*AJnKlYO8!iCzOz zaacVVbV7d#?^iOE) zs}Y1_d3?@bMKj!=Ez~{YIA^!m$uyye!C8HOy2o+oM|~mztp;BT!I;^g_(u{}1SK>r zoT(M%f5Q4Y%>TmQ9famst{`xKYh*qT!cQpwK9DxWxA9lnpJJD{u2d8XQ&^=h5YdKJ zvPQU9AuCbIfeVC0qL?dfmk$EEAt?aPE8%z?9IG36H0^noeTH21jKiIz4-#00@RK}L zGkVWFlxF90`aUbePcwd&6K|KV;0yY`M^Kcum%==31%$uGCTWW{gVw*p7jIVWo890X zBHE%nJ()x^J|x@|1?~{L@VfYvFo&wBUsx>h4G53a+z88f;)l4)lPoi2icX#k+luop zvF3MaJ)DucZxQ}DLqs}bjNZ~I?r}06AWPirVF%jH-Z_?*L|lZiQd`~gC5C0%s(Eto9*82!tob@e-A=J*}QE7dnA#B1|&OZ;?lr)25__zCfCLXNmg z()l)u86-Mbf$1+fcmfA|3ssh{@hKPGU%YEK@~`HVD>|s=)rpCRJuzw5>&GGS^r8B{ZB@MX+i&6_0wqth5CmqGk|*tRwTG|KzXPvOb z6;Mv6QZF8k&X&rp3e1w7QZ;QucT3Hz0r3Nl>6(Or;j;9qrcLN_soJt^y5%5Oz^81j zaOg#0S`>X_tX)0q3ceTE#!c8AD{*RVPal^TaWdMZ(aHf5B1>(G}|e zIb>@!O!Lq$(pC#WbFzeDvjl0}>HGgVUj9BtDz^$Sg}PG)m_j2c0aU9>SxDv1+h?QZ zP6?repD8wG`;nhVJ%e`QiFyKjpy?Q3U@T3JL0?nYHwEty2g;?biehY5gDl|oU0uS_ zwP>3ZfHkQdy1*-0eKEEE^wm>8_(0`-Uhp16Ad&3mE;bjfiyFDVg#1@p2an1o`M20p zJ36wb>N%(EmSU@yvNKgkVyyt9Cm?#OSOTaCc&2vAK=-0+(gOOWc4z@VDwn=w`3pgz zvizl>VOjoSP|2cY0s2RpH@yfyV}9YT3?}#;CWm)+^WWLn0*!qhKz_v`f^1JENKUq= z7DOl8BYP2~09>I76a#W??K1$j70m-)sTN21FneNj?uenhXz%*aNoHjQOLr;Y1t~L? zU?U4?@3PPf)b0@ged_ykvVjVNL20j&K&P}rQBVDGfN^3)XraE6&s>&)dE)L+MK2vEfNzO~XtTo30bkk;) znl~qJrOK-`cP9&^URIei0sQE)s?D>L&t#ufnj4Z00UtD3Mdm>O7-}BnaS>T$O;)vW zdO(1zC0$mDd3~~vEV7DgW%6(;Vf`U2K#G<}c6?5jxcm?oFiM-%U>=+tE{jd0Q+vn_ zK+$RzAHS1Lr{xhD2g)j{-opZ@=y)W?tE6#x6vkNr6?8iF=Hba~m6y^0D_S18@io~Q z71#RYht%ALL-0e@PE;Q~Mpf6QWVuxR>O)pQhFZAMIF_s?xs5s2c>tdCr0q{8j$PNX zWDd*~)y4@1EjpbF^WJ16S?Dx-^?PbS4*IGCYpHqWzGe0}K468mQ*r!htkyL&S&C}H z>`)SrQ1;3VNYJ{61So+VMDt4zDFI5F_m}`BjeB;05>+8vD!bh*zB>LLRy(^$WI#p}J0T=7+R^YZy-o*m(~-Bzg=?}klJ4m0z>Vc7!pbCoe4%A-9ILn#YWag1`mQWTx4|KSd9A83HI;P3I_}%7&El(pIn`k(Tr5Z5`L>)#+u4Z z&L)3w3jlSQ8>g(7JmAZxr6 z;Dak5^6I5o1behJB3|gneV3zZcmOr03(4^ts@MM(hH9{wsKTY=nf!y#)?bl`slA`a z4_c@d#=YQgEm~9fj!<^!;9MQ}#iSdRX#+d+%vFcD3+n#uu;*x9Ux24iFyzAywW9dK zrAjC63VvL^w7djWEuT4WOf;wteZejdPD#E*^qI!KY44_s?V3H@>LEt?A;#g`#;r_l zN;~`ekCD{Zqo-o&?->$!g(h1#R|SVkPYDMD2XBFRZS4(Z0!GWk6g;_DZ*v~!R1O>) z75rLw)Gj*$@T2J`I&g*M&*X`awC}FY?{eJM22HG*h#E7JgnRdSoqe&P#^q-##C zpNjfgc-EzW$jy5Pkc3!c)wYpV_m7JR%eJGcRUfO7hg7@pepe5+{l(eb$WzCk_0?kU zKzUtRS-yaC!1CTY^F*#Fk7kU(X*#Zz;+zF}Bk~89G9_G8L0ET{k*scs1`3b1+6w)yaa3!kC}uc$5J(zD zKCOG%Ropk##(>bpHapxMeSJBH4V&XQtT!}>`L6O#eV@z#LuEFQE_Z6>f<4ED!|Tmp|fv?V9-$(;p&9V$|X2Qmd~L5uoDD{X=O?Wy$;^v(U=BGpm*}bT({V)T zBL%m1l#vpUk=F_`G-u(7XRDkTiSTY;C8S#438$W>n|l0m*K~tmWse_DY%j}7U8E9$ zskxd-COwP%i07WV3+OIB~{eep~0R8&5W^dOE+kzktBtY z)^P{Fx4bLPfgCoP(qHkWi||#|#tb@=enUve!g|H!o6y!s2CPQx!^5<(%VwOfN6@+j zpy6Fdx!cqu?lLauH;h0;vVu!-V5nlaS9tiQ11WPm&3r_Io!ux*|C;N{u#E)6(_PdG zP`GF|c2=<(S34vC5PZb_P?%2SlF-)IYWV%(3uHH3AELX~Wl;)dBAHLO`!roAz4-mv zg{ByGp2l8YQ4{=)0)Me_jV6*zB=GzHkYYTQl?3N}NKSu<2;D{m|H8$|-b*j=ens!2 zXU)-WA!lVz&lZEOCdZPQi38DtEXI{+UZ;j5AJB*eBNCo&i~KVqPux_&o6_M#08iift4ovU zI(Ha?p2v({9SP?rNhdEPpgN#=hPo-W^^Ue02e(&Q(cHGd%A#nR`R}#J3+^NAW((m= z^sWWgDS{~WEBx-1GW=BTdoA5Ic}2g|g6Tyy?FH)p>P+?;o{J{*2L_Y?NPSJT+j%BYW_v-+)MY|*J>OoR3nil(CeDki=T*Y zlY@L*^BKp7e@xBGlaETbkf;k73g|KnAu|kA&aR0V8WfsXbU;tGv^=Rxde`-@+d7p) zIICQtN8(GXHgf{3>2J$# z6hA^gfjpeoqVj?e|kcFzPL@eQHf9a%*XQ~O-^_UuVdU19N z;~h#_H^yh5w?vgCZWF(8t)z-2`+a#76>6bi&*z%6;<1wP=xThI(>6T&CwriT9aaxS zAE(hJ&H51gfMFH<0PTYF-Qvb3JKC9zEQUOF@#*$CMpQEju+fnxXFs+M_RwH)V)H{+ zRNWE&Y@a5cOzeKho<**yLphvg?c6+sExOxG0b}^wHGiO|<6XF5fmEoJf?k_^!`rrZ zI(~mjogq#S$4elq>e7Oi6*egCQgsri1PfKc+uq!awNHIucFfFD&kTmb9dY)dMhRz9 zl~FrCC56Abg5Y?!?~67YY2j>W7(BTVr`1ArXLzdE5ivz+U*gYkSDFQ;XeF;J;p(|Nb16?E~+rmMYh*Ps2p(w2NVt%?ML@uXuEI>iJ50oE+|<+x$@nR7X~oFa8cj^auvi>*(nC8e3)US(B6b=F*#{@F zM}E)D819390aA`hDf>~O=htuC2Eiet3@TQ-!Lep-A+s^XdTPrqSaNm zXxuYOBV&Z=1GR=R#)xwWIXb*`6*MLJR!*u&BH=Rw{Tm)0IefU;`zN`(7ZrOG@xD@v z0isdssCU!TRkNWK6&R~gG8>6WKU&k*r(6}DK-eYt`rXBOh@AsW)@M>$Ff?x^b1&Le zyKm%C+!TT2adPBIQZV)G%PlVB_94q=#QiO)(<3h2r)ffxwflhWmA%D!KJwaWx`>5? zDT`U+=0{I>pcB$NsRSO!p0n9^BAMMv{j^><<2di8d4xIU1rQVY4kstYWOs;@n*#mz zyxh3groE7{rmnt@y)M}{;B&XUZ`hsI1QU61)y(^Mmc0%-aS4S5#wVTV*g~2K{i!%q z{rNg{P+ms-_S2()q?N7@`1v?WsM!hf?2Ic8V>B$2;7Bxp1x?Nufo$yAwiUis9267HCr6xM238(x^Ez z#aMeJa&feGj2nW`Ss^B8f=~fT%7THyMLBF7+WltWgVi)+mVk@OR&vx*1qxVG=Zt)& zx+y_`$MIP`l=7&t>4sr*t^zHeSpI4vQ$!DfVg5hPW{{yQzLz{mag|P@Xe32VG^p@JhqF8stn{*K z;&>ZulQFqE+KQ4Tf?Lno#35-s;%?9qmUffj(Vr?8#}Ppbf$jvfsN8w9_N&H>74BXA zET*kF0+K|xu=c(EbF5xf=5wTTst7&xukG^l(b2ODox#u;cMY^4+lA+Sg1s`C3i5mOXQ zaL)1UCWby*x`Z#SHRA!w7AO^GVUXW90mH*e2Z4*tcx#xL)-Vr7igXblrZBTsF)=wR zNytyQP?BVn*nY9(vY4Y36HYW-pyVC7lT=Qo@Qpc)Hdp6u#G(imCp-Qg%()>dG~Me8 zk2I-8$MMTGwu;z-(20qLgo_MNKHTbxw60V(25qT9&nhGnVKG~W)mppK@AkL{+!4%J zirx~n$OS>pnME&+AMRm|qq=IXb6>`c>vWy#ypd?^%TTmWoq%z9 z-BfrqGxV$KXc>$Uq#x|ca@MIo8GIIN+PLmLhRrv!Sc$YjX6d82N|AbHidRe7lF0kF_Bl zPL&*MK*J@IL#~2-{Cccfj22F%4)&n#vj)Nt&_eJe#o0S36z-u)F};tGUB?>j@LQ70 zP@;0E{=OEIYcEhRsKfFTzf`J0wF%4oIia)&ogUzMz(T1avJ-{8loNu@$l6Fz4Ue^&ddg$S^2o{y`7&hCl zymR^KLT1=}^xd@c6e03U!DKS;)FDK&I|n$dPQf&f5eBp@6XcKfh^hQ*&9&WT*fRWP zraZUY^-l6R(g~BD-G+myt5<`9jl8drY30y{qkbk;VSc-BxmiAnGUL=={78yrCfTaT z;(vO}0#k!4hc!Nzrad~j2F1yzYd&8w;d_zbvSwPfcYD>!rMY|CQ7e*TJ&^i}%wEtA z}5IvO=D^LQeg9tN&>N(kb^ ztLy5RpO7(dGdOX$lY?ONt#vM4?$kcR`5L5=15t#_zb+u@yhBq?R9qf}`HFf%@s(?^ zPKD4^0S}SK9RKu(#QM==NFtuiRFReN(y@R`yJ8E*K>Nfx&k#RU?+*r-;j1k_(i8Fks-wq!>yUKjgg zZh(hp5VQMZ%iNx@A74-Ua$q}JH7HMpD1`2PRFpVu^nFCMby9%kd}L6_A--mxYGX;q zfn_c;l;hnB^dz{bEu&a{HbMV@IT*5XT-Q0h@%ZbXgjsWI`&cU+Xx+N zgxZ^4I#^)`7h|v~mIhhg?jV%d@+?r^&PrvmTE{%D8I+^2(WFs2JqR$&md`I?iobOl)(GX2OedO^)V zHY?4k(z@Sz^xhyuH^MNd(op9})1|{$a>knJBQyRSai9vSm$#$Gk+|c>r}E4fu~{=q zI5Hx%TB69HDg4msnYsA_mbMP300&!nb|{FDWY(tYdF6>G=B=1T6!0~Zv`yYIwa4!t z!!m7_inpKw)9xd1#xfBHzp(Jc>!sSl;OHjSd(h*_X~ZX4)>5IK$`p+`e|^qkIm_~p zB*_br@NiWQ@!)GWf_3a?R=>I4sV@Go?0>g6Jr*zcIyQ4V@1xLw=zD3hyy_%S+qH=J z6;E!|{}#pnHWuG=hU-2i!bVTec#q5WCJgNg$J#fVITGpp8vaSn%e!9LeJ9>sbYPU` z#F90d=`aQC{@Y}*1K!TEVm8I5zFDS&xi^z1V&>l0^sA5FIX^tICmeBe&458x-1(=TkDOEeeC?k|=e-6+v*o54eb8cRgEf$>Y5^ zgA$v@;c`#y(e1Vy>5RE~z7;h*+-tw5MG?x)@O~w7_w8TQ#M1^0j$F$@$sa8?z=#j?_JR1DO=fh+JoJ^$Jv>1FKNkbwEg3%*UIf3lvFm7_y^S z_$@^!%Q;B~n9;l7)S4w8R+2u$eNfI`q$_rV>J=qYk{V5O-`}4Lv^QWDPe9?9OhaqT zziRUt)O3L4{}fzrLQ)qD_8<<#>9yVZk1FBMsVk{|U5b%pB^0pP%!9I8%IR~Z+wK3z z&eJV?-%WMp!dlB!nzn-UtYuq;Pruop(cSw5aSA>V#;DTXyd-f!wWUUX_U`GgE2{Uos31 z1Vf4w{F6&8mNTr?*V$UO5*8~bbUh?Wp0Gg@O7C`XNm&kpin653cPa3~ZpVc?oFhS5 zi$dReb)H4~9W>!XWM6@9Mc=WuI)`f1T37M_Mo>ht!p2&$c-dpJZLztv*j+Xg?uYPG`hHr^oV%eLS*59~gR&IZc|#4l)|>SOzo znwsy(9pD;hD37%wu3}^~yGaPEbT0@r_1Rss#(z|0T@?Zh@lI<3O_?tah?=7M)-Lhk zm4jMJUUs!DISX$l?8B=7gP*qyKX6C}bH0Phnj`BH%aB3R8FI+k`=I)wr}9rAi=2W&dXHd(%6 zcp9W-E^?MfD0}ee7x@b|J-4oMeCMo}+hZ^FG7#jI^zUiNJe-lBHOj}6-q3Fov!*qT z)4z>>enWgS@gs1>P1EofW(jfL656QNDJ&jN3d~{Fwe|OdvWOQMBy+0Csx-?T?lm5&;$O+LgtW0 zy+VQ+_J+Pe0TU?XA{l@IKL|aQ^A*H>$cp#JJ`RZY=R9^JeAAygxg+BhNJUw=a~2dG zrFf$zN;r-@^F}18Iq)|uG<&pi*Pj|a!|lZU3l`3*d?6wfjYJVYcwew2rtw6&<%cj1~;08H|3HxN^T<1_Zy7!Nozqs_Y^Tj zaF@O}o&_g*uwcsSh2cFSz?N3Esy(&%Eu2wWPdP>`J@lQ7a~baVDyK6$X&ruDH(P?` zdmUlem%BB)Aw_f(p2z_cfg_)vrq zAr%s4GmA${3S~K{oC#rOOgt3h@pp_gK*sP zY7dr24$hKCuIijeZVG$(LM;e0N7?kED~Pj)D46ig042WfFJ0Jx&ms|(`^y5|?s^RZ z?_)5d7X`gVukc^sX%7xGz3?S+ZXd+EYIZb>5bQ%2GJ&z@?PD(X*d{o^&9Be3x@YzL8WAi>o(EUvsV(q6Sh9Om`p8peNQ}-V$h98<1EExf}L` zC@?4yA|Q1N_wW)@BGE*IX=d!@p`Y3?8jU~f;s+NcSD{A-x15XPHnvIG%eh}K)v>0I zVwffV-Gc=1OA6IuIF3h$WUvV<5{MOIhpcPKs;NywuyKixeu*oTs0|=hoT~^>=1QoX zn`JFY!94+8z@LI)3DI`O@y7mHohx?b{NmL6d3(gIP~QE}zG7gD5F2}QZGU;48|vO3 zvIrrnMeOcbvfs@|(%rpFVyWdbyA~IJb8UKgog9>FkhZkNS&HrQ*tj?;GQLl=d!DSF z+a|1uHE!4RPrzCG-II{cMxHKK;U-yIt><7ss&7$qECD$u7y?{BeoOxc+-ea_y`;+) z^4A{zSj2@&kLT%GEF=V;)Ge4|h_-pAK$FQbh*~3#CO!c1_b#{3R{E=jNq%AeBLHjH zUp`#51Er@;ACs&=Zv;&Q|3Z$|G2BIay#Wfjo%SVkG($aPgwMEe%iCZ6pmbgu#d8C8 z7ZPJuLK&mvfV+z^{({%jP-et)Tt|1vG`-JGsGr}(f|bVoA-QrLN@HWJ|l($>uBy^Y2ECCJW&%CZ&uZ~p2)T%p#4_d zXdYA7b6y>u!Y@tMrVQe#Iml+3NIG+G-(-MIptKXZ`Q;9wE`p(jGt2%*q}( z5#!<>IT7RX9y$@DN2*6uF6QJDoH9{owT%UBs-elz4L-rN(`U92=XuhAHLchf6%X zW0ARti#wUlw26pM^v~~}Ra>iEL(HluLvt&KQ*s?RN7{JS=8iF`HmjPPD|oPe0i)yz zo*zSt{9)9kAjf|M{uvxZc>v^{<&Nky73L7N2y6`AmS^Uc47(8lPR?%qi41qC`;{Yc z&TjWPL)xh0AKMH~8I%*wB8!;#;dL5O6ehoz;fX`DZn>wVu39kjL3#gZw4szrT5k~@ zt^N*`-4g1<{T*(-1-Jc;v&ZQT*Sa!U*=iUZxvOFSg)iC{U*@zMKROdZvKoGi(TyHx zxiZ9LPxU!-9U`>)bxY+3j@)>HYqrBS6KD}aN9m(vc`GjMp!ZH%sjLcu)^SW0{ zQ2^q-V_nYrYi{uBznsQoA=48Lc+jXNKxrcO7q}QtFzbCCujLX-DZ78r#_ta+d!W-M z2}HV>bTT*WOL;o!UIXjPKst145&0D3%nX`gedD5+bGHzj3$=)8qSs1o=2sbxh^FL} z*B_FMrdy?U5h7q9wul5$>GXN$V?}A{6nW=h0a0|CUUTCxb{dCAlxoF42mi?ZkuA$n zNF-Vl&zhnfH@t*h%TP#%Si{VkE|+|P%rd)yYi--&falU#XWHy5l{0N4a}XyTGN|2b zs_VF7)LiSnW3P$X2$0FJ?OQ7zuH)^IkIcBZg(ots8g}6Ak&V>aNNzQ#DYkPzYvt`x zj9j^Jjzo5v-HUT^aGWpWy12zA`j(1pKX}-2>WSX-u~J)cuPxEt03=URdHu}HmNRH zy={5UD|^eUcN&i>X)D5_U%U4zIK2)PB+u*1W8o!imqE5sXx66qdmx|HXx_kA!0W=f zK@D#k!{DuVE=|hzW|;gwGx^%f_((BFf_RqxzOeT|p!5M{<4wx_TcsD`I>xaP$T<+$ z`yz;4x9+4RP+yZDr77U(G^z5NA)GiW9x1A=gba#9la~)0x&?zYBM+7WRl#hHGILZh z0+kPHxn*I`-ILPZBxg_36Zz8oWN7Qs-#g3zOsO!!FUue#`%ZN+OmA1ulgGB3&Yn&P zs@gl$6ASeWTLk?SLnLOkqS!@|@>LL!3 z`IK{{fYxxOdL!;3z-FjG(ZwKr&SyBbcN6^wqc?C6do>!EfyWQlAm45~7Z=b9Wk|=_ z(%>}M`rE3d*TlDnD0v$+Al+aS+@8GcY2P;TZxbHj<1)mn(Zx{z0wV4CG{@|6rqs*h zH6M9rWe*0K?N|&^qKWB@!W>N{)e_0MpmseTx-3m@l1+EdY+-ier?zhfqn4PJ5uLv& z2i-PkEgs^dc(?Ahis`Jyb8(IF^jD52*K&0BE~9yCuQP5p%=ub?Gn*f(XG^3plOHaz zdBQ;8Gd2J8^I(j@HhXsvyY}>2Fj}e$-7qn zJWtt`jdzM)%6Rt04HLZbKBXjzHqmfghf-Y25tNNqidVDfU@WmZGS$OdObVteTIp5LD)MPsPWCdm z(D+d1d9ebt>fW^i`tYPYEa9US33UH&inkjGD-vOT@yie;ZU9S+kSC(u^Psa^CnDlP=B!{bGb%Po*Rze0*MOfnCuX+sghndQtt^t!CI?TJD z)JNk{)sD)8YQ~H=$OPUf+`%tl3*JoJkuMQ3-n9BN3&wm(UWEDjW@M^^7N6dMA;$|C z4y6ih$V!f+d+{d~r=J@HvN!tJx#YcvsfBYWY zz<|I~Ivo!zciAL#NS{%D*GHIYqUBXNb2M@gU63&SE@^f^itJc&c7udt=yE?C7lttDJjr z7ev)6IfegldJeRHaBp6+vTe%TjkJ)zE6)Z40e}_^`uS#lx1T1=4gvFM%3tSy;lH#RXxueo9g)L<{8n=)BM!55#jp8E{{3 zC}aDI`V@dbpciKp5Ou7DY0u7zC3jX}JtvyVnXcj7%V-&VECv>+(E}CVfnjqbDMvmP zg4P3i4FqxXQyt{(`J1!HlJO@IDO(?-78)3U#h%cESZuw;ORI2OH@q{bA4vusNDN zGvtNKhZF2|_1p6A^kUw>(bC87p3C(oUK;L;X9S9a=h}2KAntpOpJt(tnw-gF`#-72 zO})1;0_;y)TV{l%x0tZUcL21AgHai1E4r4`i1D_N1P>$Dr|%6xyC8Hvl6WR3m|BQlKGK`SvjVKje-JxHzUFzUhK%#Ro;Ph{9)TJP0OcBI{pk=q8#9_h|s z4KNKUs{aeojaYrb0H#is17eKKC>HX?+7(I$KE!#)%O%in|OPG-x zvi^yw)}I?#`15X=H!08&<4Rw8m zyaoAzIyyGgR2gU!&n_k<`9-)H^1eW%gnt=$Ng6`3S!*0INZ_V4i84N6l8G)`r*#f` zMOt_1JqHGzX1Kt>=HXOo`SAP?1`RPEw2}k@^Iav_7a{x;79|dlPyPcFe+PfR(MliW z8yavQI0y@<>%MKY*6A3_m_h6*f^OM7w+qLev0=o<^4A+|GSoB@tka+2LYYEb{e@ic zYjB!QL@4%8^L`VCTM=e-L`L+uRnwrs=Se&6bM0};)JT&d5gx2J!yD}Vl5JU{ujs)s zq7YEGEb>PL-u;&Zcqpa70F8bhC@_F3{#T_iB)f!Lp1M;=p)fkTyi@R^@ZT)r1fan@ zJRSPBe&;EOYgmq5?J0O{n39`FQNJV+?hdNXtJ-5=tq_D4;GIkCF;Kd|(JF>RFZ(ge z)PBmx+FCOV+fw9hCVI5z*&z6?jKZm)U@Xdj4w^S2i@NbLmw=$z1-oy7z~)gVR{ObK_Cvrv!Z_{SMn93RQ$(Z0%WgAf{8S>GX%Ng@jOd8fA z&L&E>BJlI+B#nAb0`Y}KCv|P}RXkJ>Tt8wpMk^?Rk#U&8(`D;XD{1o^6fx7p&qggX zQ7f7A5KNpKQ85gK(I!rp{YbuA+&S4Vmu(&Ypd7oPJpwSZ%|yu6g$N0yOfn6`nzoC8 z6wug}D1*C$B7~oOmFsJ?;)yXO4nR=5fg|FACOa(_9@Me*r z4Xhh5Xi=r~B^yv~QGD8!s)4wMODydy-v*WWpA1vEDOQCb3gLRuozE+9!}y>}M}_}U zG=RULS*h1C;CYCEw~AXEyC1Hv62ciJi#$*dX7`^)C2t_zCs83~tzX_ZS|O3qzZfpR zB(cZh63m*RLouzJ97?z9WRKjYU~SwSTEDchNAQ%(n#@5tsYf4ryL7e(@s!mX<3&ZU z|A~lPm)-yS9NLzIZ2F#R}{t{08MqeKti==vYw{O8KY;}UVkHssh zHHjW};a1Gk=6Z9n$L^Kinz2Q8y;ZR% z@0GpWkB!*=q?{knMXCODt`F@czuwOc^L%UF|8J#o3;UtPLkn>eavLfnQols*9`>1+ z|ZQro!?YCoY1YpQ? zpX;vpRoRR58)a84^;N|MWp~nMKp$fq#j}uOcE>rl5w1{q%%C)F%B=!38x1&MYI;rvG$(5p$tLj%v_(#*q^8Xmn=}nawTN_f(%=cFj^>?4 zJj*G;cgNXj^G}eR5+vp~O8M(FaJd=FV$gX0%ejOfG{%Zb_SQ?dj66L9gEi*6orEik z|01M-?8D;t!#eTLE?_EXu?TS{b-hmbctF_!>N0L{PlaR4g#mU>ytmK8w`o!2H29O~ zBT3fc#2r7K;N7FBBw3q78>Ljyglj7yduN~}p3S+@MG?@4|7HjMstM;*2vgLMNBpf~ zF^Q+G{s~XkxgEg4NS>}8yfW2=OOKeSnmNuWWy6+8n$|TU6(f^6X?|!u$AO*5?vgrW zy(jEvDeaeJ#>hY}+){UOd`29X&S6F)ocj}9f;nD4CyvH1s}ALDj6{<%T&EBdNaoJI zU;Eph4bLVCSuZsU$`k4OAIGrI)5T9R%B8rpjVQ;` zVIw(iO;Th_Rkfb?m2X^LLh*fFRG&+yDhoj?g&0;fkKCKY?NCZAr7MFsNY{;MZ=sHo> z{%*$KA4Y14g;?oUWKnyXuPSzf4j5yAgVaJWcSb0mVBRM#t;A=F=(5PAS=w5)S+0i4$IsHXC z#yx%1hPt#uE0HnC6|);XkJ{!?x#Mpe@%1)*Mh~@p99K3VT`cv|f!DYoV7sJuZU5FI zL7logZhQFowB{zl1CE!bt26nEWpfL8@mQyEdK-c7ECS;gu|hT(#>eT1RqGa57E+iqMWX^fIAnaOmb=8`n^({SPlg3y_1_* z4oK|e^ldyhc2C?%oyoFPkFw!jn^uF*1vXTUYVS@YZL9C2W^`$_4g0t;FotqGbV9!PI^uwVol#? z<6XhS){hO#>|(Q^%7$2ts$RiCtVX@~!X*7d9#lBh7ZmokUOh>uY`Jdz}=T8^i9SFDpMU zKjTTrb&9t?)Jceq3U5&V-JzbiHM%l6x+Z*Y?~?8nz(bI$|8ewiN%=)}!JfrsUQPPr zSAWbJ8ep<0KTKZ8Ah-n*F%#_4EVOd3pzW~nSYta0!ah_l0nY|s2ssoNHP<&c)ZD3~ zZ39WFJjs`l$@rgV&N*uU;aUpa`e&HFabD9%Nseg^3 z=x}DnqIg@O8w*G9&I?b8x=tkhpgfqDtD397OHC@cBw6JW*Do-y_t-%ZuzWB=jBc>9 z{q3jcLV%SO2X#R>zT(+!6=urEc#bC4;jPo zJ|Hf_$38md7a0vwH;n%J)mlst_70k59)t$fp`4KQ-a1t>>0BdCclF-q2q2sSJfZwT0naLMH1pfi)ET-65wU z+7*&uXvd9mddPUrG1Cm(HIVp2wrCS>U3L_aaaYiEy2zapN*D@WN#3$75=drcJ`>o>0ue9O#R&YzFXLbEFi+155U*54KXb@=71A!|h@K%X7!8L&VXxl_QA==mcT-eXU3VBl`8%D45 zr~ibiCR-j&(BZJ~gB39=-f!*kTX^l5!$+g^2PB)siZ zdQ6;LFvA`OjzuOoJuTNZ%O+A6D{5tOk77pg5|ECzcJGin4UnuRN2Xml^lc-zXM2~8 zhugsAgLw?E`m{;WuZ2~$`zue$!Xm7qOz=`<6Uy0yHb%SyN_^Iz7wz|Ng=#Uh^mu)| zsjHIcxyj$MSS4^SZ^>IBE=BZsJ+|DT#kQX=g|O1@5w`^3)yMs$jy^mkbsCbk9+k#{ z&ESYvgpDpxV$Tr8NGE*Ni`x8yO26Lrcij-XVMN(3pdMF-p~inP+7d`~z-bhFA%Ah> zhmGVy-m+=EWu-eJ6O#OCLmRr77jYx(In3XTx&nYaQ>z>vs6?D;u**i!oReY5E#2~z z)AAK!VSCF4!ht9yXZt(eIcyD7t-PjYV*Oc|AN~0z~A@a+ka;mdO8TZApf%} zOH^|ssCDyCi|@r3di7;pK;2T?FovG?Ew^>gCX8~jP|BqDQor}wB&K1&=y?m{`lqWb{)>- z&%o~PE7zXokssf2YF;SEe!Yl8<6rk!=_G|c_Y(L=Wvrwkwo!%BgXHJ_3U|m%47cRt45WHr?8e& zOzGzcGEdRO@_EW<3!u4tLl z>PD~T4vdD)XQ+A)y{XPOkn8|a&G0kW^9p1wXuvHaa!{QP8od*)ZQv-RQaju(a1zY5 zjZ+}9l4Ekf(6Cb4lxL# zO6J(^MKhl~*wOBwF1z|?WtAoB$u(M!ca7LiqT{o(Wwre-rZuBYxF?MORYbcW=%~Ou}GXLj) zLlpe5b6bA@`}M0m^#2c{AZz!3fj7OCtQE19QGCz@T-00m<5eok7|fv6#AvOn{hI&i zz(mWz7cXoKkhKQ|Pup|=l2m@ezCe6h7zHuY&3iuzadJD=k#%rfk9kjW9A|lMTz}p_ zW?RjMp>)n)QQlmNZnGmuvm1=Fr@Y%gbcPW*l@3`@NVMZ``3EbC5S>56SWsh~oCpES z_>!;UgUIl*#r@9E*ng#)JG8kMnK?z#C6S~21-*Zt!xtLs%L&4Q?K=P zhWh06jCxC2Ubwa9CFQBz)>Flin({^Q9=wBaV-xZU$|)+aN>#Y-Cpp!HlG)ETJ)J!(W1<;!e#WZrE=v!6aCjbiBo=+;N{moHAe`??!DhUs6PVlOpB0 z{75rCIv`YM{HEY(AJcD~YUw|Gh-uY86o5IYIG2sdnJu;uJ4w5)-f1YKeEpmqimMel0m)U!09Of+k=#l zmV$nNOte@ZOc$8qPmKZWx0k)wo9M%x!YB(+0p!HkaBgj(Oi5)vaj#;_7Q?rdiMx$B zEmBU(a@fQ%Dn^UMV%_dlLcs;4Da@(X9(LIUnJVbJ)RGje!CeO2YQ0O39!uJorDpdN zDBlNRhLtQUWsv4S$ircbNwiS`CE>8z$XpHo)=0Jy0?8nhE-~E*6*C8EW$wab8e*rF zQX@AX2Y5Anx;?URX1o`wmV*X)wccu5a*&oKS?ndcZ9aaMn)|9HQ65cZ&gBbv5O|ED ztOZme7WLkkrdyM%uIrShDjI7xvXBFVX(UxlM);&7U{8lgix~P`KhwR+Ub8-p;d1tv zMqdf<2S;B4d6V}0J=!fK1?y=#(UhLZ^Og*JXp0vN-AId>NXq7!iV~k0S}96|*4RE^ zN6v>1S!q#0lv019J3z_qq>YYQd!hj^qU8Mhh)th(UsV~d=;iK^iuK3rKdA~9IQh=e zHGf0REIk&*{XseF9Ht8W%@2uUy;$qBcgrYeSwj%xK2cL+^J=>NR~CJKWf#QY1!jU} zaS5Fub+|2k#q2-S(hDp+RJa4XeF2X--F2}kCRXNVL*z7@ir1^_SwxYl22IA?BEbpO zh77iPtTroJg+nS@#e~5jnlJYL7euQcTHfK_TKn&QABgSm?Yth_6h{=2pzLC|Y&03e;!*VV^R(CZu-kRF{l#n6VV37* z3w?ja*LD*G&SM?~OG_4_;*bQM0`qVrRUsOVOpxTwh^-~W!U%&yI8cjGYey!zmC>C` zdS~LuI!HpqVvlWIc9kGED&ewF*&zf%pHbvF+BwnQsH;m_Zaf`JXj~{+$t+HsOgyCV z(7HjQM69ckrOh8sVO&YPN@<(}3ngRkq~Z`A%ZW*MMo~N&V)%ISjjDVlFZGR4ddH#& zp_wXN@@{c^E_EudH63f`+{iK|iA9stu}H;{1w-iksQO<_?g=4!Tu>KFhd8o%N=_PJ zxm}JF_V6_rZf}loU4vvCeSF1$(mq^*E~O9<@A0ibnmUm)$&4XMr#g;`B}E{4R7Xwv zMwP5p-A~dW#i&&nZ#iCDbi6v=bD``Ih~rks{7p8lN~t+{bY&9m9hu}=iSusBam^ZT z-}5+n@xfYt=(GOd2Z0_BS-gQLzG|D|-J9APdSo40)I3I5t=J8n$j~528rwOBjHM-+qcpBa<(}cUp{A&;_$g9Ry9zDG~T5c@|c(a(Eg>pVjU%;l}BrhcST$i}L| zCL-1{hf7*Q29v4M!^ioCWBG~6BeudeVm6H24(|PT7urElM>~XcB%2hz&Z5$)Tx=O( zWuw<8R3w@4Or;F7#2kMn2QrDcgKVu$MUG;Q7_*+QNc=S2?&t_McBN^aaG{8Eu9ROY z%hE`(xbss=N@7LnbhuE^0eraCIm~++d`7lSp-E1-7ImB1JzK38gU>)%4VuQ$QHYJNyziEpbWP z`k&ADKG0EgSjGe@%gnPE*=9Ai17TM@LcT$Z&~7c!@VDgz5{u)ZQsPX7#Ij6=MYBf+N(*WHNFmF2F%R9$ zoz?up!foef_6L(xlcs7N{VsNSJ@!UWt_#yVwN$6x@xv79%+mRVl6j&(QJeuF=_@m$ zM^DpjdzHnONaH-U@DiD;c$PUF!!@s2uUe8xRvOz{E%wFaiDhB|+n711ZC!b>Ukop$3V`9-Ajm-Z%+Y*B+bO1v>_n zty$#%y8!V`c#7+Kbv;=V zS>}1O7d5=wGyrSDn@Q~1rjOJvg5ezXK!)>hj=ie)lUC$$iZoY*5%#tMb}pSF*!vL9 zfi1BbaWgB7MDrHA&5+&MDa5^Pe%dZmn^6=upkj>_bdko1jdk`zo1l{+vaiOq(S6Y$Cc+gCaQ~A=RlN@^WPy z|LDrteUsR>c5JiKh^->E>*}-)$7W^R^3WL<&ku6G822F$aKItb!wKScRQyZAdSsj*7<=|i)c;bodB^2kIpI2F8tX{XwcL3YckzuwM zD5TRprTg}?VdqeF;%t#6@2EJTZXCe*9+e|6q1O2xo}( zUjL~;CLFGCR4-JfJZoi7pAylXa#1|UAsHr{N@*GBqL#0iic{Mv>%qwlHhaD#&Eo!W zs#L18et)(kyR&M}Z{a|0wPgN>I6dT$7Tla!ikMS+Sal&AhhH(F+tcFV@ysE)VkBzx z-Z?{L@rYI;kARQ0v4eq?7OysTdBpNqiG07g-h5iR{{8jSjfiY<6q<87FP(F`V4Z5Z zpTD%7Gg|!2{ggLDG$-C14&GS9{q^Qe7Zc!TUY4wzlR#;}da4qvY%giVswX z(F31ISL4n1dM&D$xDP*&k9lHsAljKEHxScwzScKmxIC5fbM;CT+-gv3oxv;@4$Z}( ziawB#Prpk-V8RR0jBY@v#@t!@4qK?FI5^g!s-k7?hMGkYT~XF!XB{=Z3;oWtYWXrQ zMa)%WHE|ObUS0zlFSr=Xboq!ZN~xnC)B&YS7>!lh!zY+00##pfX*7vNFZspWrbbyw z_Ky%?Wbj5pN_l(o#?zba=8>YC1U$RC5g*iFBdC^@CaF|BR9w5bYx2h%Dhs?6ly@s4 z>IX;n z=(cZ7m(>qsr~%l-hTT2m&u>Hb@kgezWdoI6Rtj(C3xgqtVw>xg2(z20BL3`a(CY|B zSt43+&#gf=q6+(AyXc>W6SFmGLGo8-B}>bO$w9o->;iT!RT0Jz<#nk8NFmNzU}%d- z6Sqae0cAE?9WDChq6q|Figv%L6Z5EymD7_*xDQ5D^Ou!TPi-EZ3*}ebqi(=N(BkHq zKnlT6IxH4m?@Y&H!JQjkuN)3w>3C|05hB|Bhb)uOvcf9o;oP$Fgn2BR)oi5UiML+erj3q< zvubbR^{f!)y$MY{iY<#GtpCXl>{r|EKp@x{pV}?9Y*kS-xytMaawO+LcyZ(1kOJln zp*rosVjy}Bt6v|MRW=yT57;gG%h-esNCWQal8Rm|arnTt+v+X!VQgMPDiF^Lz#2N( zeai*5g=ndd8!*1&U8fT>vI1enAUG!?Ij44*=pDb0H;f2o3-V8s{|(x{)<3n&CQOng z9mgI?bc+nqBMKZhr4KRi9BK`wCNv>#HvonEqlqvS_t1{(@PqacI*exec704;bifO} zdD~KNWNIFvWVZj2V`lyEwP)ep8{6X{$FaL# zHAWRi=giG{u##NI`v+;_$Wa+7r_3XM zHXrZ?1Cd~>2la*)a`0yM8_##+)1jmA?dGG_@HT zx0E9sVh*egJIK2rY*PT0_rYt!@O?3Cp$j#4Km&^w=0YW07Y6!f-7v$(P0-ca-?+dx zpuCX09$F0!a_mH4;n7!kn2}L>mGYk%9dQ5s={PhXlK;9tcUrP{>_2ha!YT;gScNAT zk5d>IGuogQK_`p6JW*;Rf_Pj5QVF4P4KVXfLPv`{Q>Eb?noIey4Z&O!(`5t}2%}p6 zG@d;8JnO@rvW??adqxj)koV?43TEhGb3|i#+xf6LYaKx7YRId=o-0_evtJa2r1Sv@ z0e4L(KK`>x=m@$$0+j?4jvsm*SKiX0KJnDfWy|kRlJf%j6ek?LV~$-%Vr# z;eIvOL;_U-#1+u>2Bf*VWW%Pe24lBcH4ocMmoecjm9S_gjWB%bqma}G&x{#X2-ipl z9BWq3be+*&>ucVBHkgmhPOcn9^GI?+q5}k+STe=PX{&JX?=MV&G&;=dqz#(|R?P3Ks z|Em4NKf>E}ydNx&>5W?p(FI{}9|Kmz6SA7__9kb1DR~u%eMr}3VbA3WS}P&-xVzts z0$5^cLaR;u6#)44yJvvf&y(dG_;N5}kFQf!*oq0jsa)Mt4muj(XhX`!d0BPK-=W(g zUD7>31*5sV9Y`je(~0>$Y9qpUmLDpCz2ig$#MbA6^{C%~)vW?IO>;=%4Nat@)MAgA){xP!X}L%tuF3JgltZ4Gm%Ou{9^^>zr}a3S4kB z_Rnv5Z=uI%ohP0CI=A+TkH9NNkS;A^<`apRiT$NY2qHTxCp|mk(30(zmi?mV8Me2d z$x~pnu`Whp*=Ll{M>)QTQgln8&moCwML)jjQiMo85Ao3$TGZk5>B`c-k}HOxo+rx4 zitM+{BdADYLY~*q3wxqxE1_oIs@Q$6eZ;1|6X{}%gM*!7$rJ5b0DaI`-%Cal+EyvU z<+~|B#Vz_=eVx#)kYvl&I*<0i_s{=5n~-0o*%FFWg{HWQ_kPK@mt&`SYc5ZGuTZ$* zTi7{pO4sV7c3$s(^m8A*A} zOg^k9zeaqXGTddJrNsaBv(R=)jHQ}om36;su=O)6h1<-Kt(JwWQu4?Lo80QyYtp%4 zXl80#98%dFvw{0W_WiT8EQ-k{Y8o{z$=QIHixMH6YA89?^kUJik}IH$>+C2>HqVH*D(j-fIkDRtRnkvJ$O`G$ormxR-7VXw|I{!4)7)`7?5MQ|)tTq&1 zsVBMEFuh}4Jfz*1X1#j7WGy^$q3Bg56Fs;q|7C6O{-bVRZ-}d%&2i`@HGIjrYyUd!*E~S@}ckX;d17BZ$C5 z7JK4)`#OIza7AxUWf|O9l@8;A^Uf4?HQ6by_$K=gC-%SLvRRz&lLcBin95MSRwY9= z8DKnt#*VE!`wjM5m|-&ue-*N^1mxySSR0+aUI%OS`bC?$m^2;;qO0 z+9issmo2S&)!X78tHEVp9~7f`TxM0Odir|3Z*oj)6YRL*P`hHTYL=Z|V7SxTROk}i zbP`ta<+b#by-{9WuUL7F!AqnvA;j~KuDr$s-qVKqvp{;butsZ{gy(-W_@tEZ_@6HA zB+`{KnwliL#CL9Sd#v9Q2Uy}zYWfEUSyw4CxgS7IAH2+DQv1jo_$G2QJ$5oaNUI;AZZrf;*k=G0ZzbPh0 z8H4ZN0VHlM7c^y@(ZOrmLQN5f2lB9wsl+DG>dO| z<>r)30yWgzPw8l|DuVR4oJp27oQVQMU7y%rB9&IS3ca5ON)8=QkSNE6Rc(6ui({= z3eP4edTSqP)ex?|sFvj(iD6@((aR)ioFzQd4xkx3wYl%e@?Rv?{ZRzc&x z$eL}rW1T~tlbv728z|N4n!k+kTFHkKBW6pvKe+Mv(|Z(rMR#G1ccOP2%3VtV@hR;(Pqn<%temTbfl4-{=LWcfL52TC2*ZDKIHWv zbr05&)+t?$XFGc`!teI)IFnW??Je=~z?Lp-T~s`k&=B#J6rJNbWA{Msj@yw&pLceG z?vB+FU0qam0`rcuDUw~3euRDh#lw$Z0(pieVh#&Cud)(sV+?jmT$N>GXu5c1#p<23 zE#O+WdAevt>K#&DI@@6Vh-iiGozpGu>L8%IpLGqS@(wPYS9NE5#{v}BKFmMD>xlmh zoh-Dzg1#g4M)pkJx+@g$t*s@}i#&PuvajOsWWgw{iwSS|88p^<}Z*g_ggUuN->#k zsyJ(CYvNA{rF{uCle%2`w7`Tgjc|KPaPl%u!PcxoGA@nu`e4Dt2aVuch%uF~;kpIF zr1FDWzQ$Nb*_XQN6Z496_CQDFNuz-?#6|v$N%xYbn(Y(oimvuJMA?OUct(p{CyeqsBu~xBFktH+Nw(_`0`*Fj34e2G^sPXj!~jk=ep49WYxeE0@vgdbml%nL-{p5*KGDk#n$%P+qHky22X~xqiO@z3ysQ! z&X7r4tv=KC#Tw2F1nXpX__T|yvE%k^1H_B!CFl#ARnLc}Oa90@DD4!Q#r7JJH9@Bs z_BfiQ;u@(2Q>T_@AKfxq{bW<|C5$ykr^4n;&5BFiMHBh@(*~YPU`y_HnfG9dC0|`8 zkBv(ud2sb@QNt$p*`PmCcm9oW?b*lL#rw&nv~61Vm9*iFJJXtv zEr{ptW~}!qPrCOZ?lkW+YlCd}!@BBD@TH$C=Ep{7fcL@nSkF^SU9Wqtp6^S~)Hl#O z^K0)b4foz>#OKkc|NH7IMo~A)Q5VGZqr+iZb%3V_N$W-W2t*ei@uTD+&X!E}PP>n| zC(=E`mNxc%AYSgRKEyosr_QiV)_ETqP7=Lg08)auux6kwa<4)%rsjJl& zlyBab?&d)D_WN7XE!-EEZ@kw(_p&z^@#$u7@U!!c^83rH?T6UMqHk0d_V-&Ee_AX8 z$~_b4*IQbj7%wY*a4hW9-T_$TYfvA{=Tx5rFGF3p>hGN6L{Qz^aeuJStiFFfHgWg5 zzXdEc-INeV>14d;8l0R%5z7v>;*jLo=usUC@X zIh#@eu--GZ;?NJe#YK0S3XHG!Nd`WS5|q89#x%Vw#R)&0M-D!o6Uko66O28a#^68J z6W*UQNuqDslz>|nO2{`JO5cN*Vz1fNP;D@EHhUHSHhRVUR(fUmc6t^3mU`v-wh}t>4J*1kAsYUC8zcA@ zFv9X>_y8&TDSFYMBxdRP=HY~vwySezO*@Tf4)(k+5gEQ{W~a4`gZ z1}l8?XuLo4$R(8f7+qldURa>}jz8@8_#!0!t~=EC7-%53L>eOG%)rdapY@kVJV_KX z5@~*MXzWyrfr?W$Dv~wgZhmq&=yZC2>hxx4=+r|V$y+%K)mu7M zxYV-o+pvu&DWus`!V*(BR3=6lR3;{qNOjDo0>T4O2Ec)W{l5`uqImmQv#B+r494e( zH_VS=VNCppVNCo;(sU4eag&HPA|_>;=}W4bDHb|ky&iA^ zf9Er^xj(2y_MK1}HtV>(AGrm0XKaIbr+iIsPvF}1%GoO6m6-Vl(h-2{JFQLEGu^HF z$>Uo1O4lmvmHUzODtbM+AG*~#-0ScX;XA4YGsGPc_J%^5Qdm}xjG}7QwjYySZdPwG zjBKg!xJDYm)*^E^%1QxT`;s7O5fqQUQduzYOnzJ|m0$*x865{FtLbDUq^?Sj&tjLM z97e0aJWwUmxi==&xJxG4xKAb(bcH7EcZDYJxK~evyUS8|-}B19A9>egCA}mwQrvhJ zGxL?ejRWLDPF$5I?nfz)-b|?qAIK>U@6o9b?g8>t_W;G23Ef($@!g`V%%4059iK`E zpKs5Jrq7pT%r|^W=Qqft^*6}m_O~AeESNOLT7FeJ3Nhus;KdS-|AHO#{}ngX>4iAR z_v09g|0{H`?>9I~1$U)LMYmE&L2IH?MdPm4QohY;sM-U(eh1%I2KZ8~qADDP2q?GL z)0b^&v5U1g+l4hW*rnZP4%|)P1}jfg3 zeB~ithKTYLHuvqt-ZDZlPUe4&DZguZZMy>m@nPT$=I6_<7@;YSVJ=tSR*df z1X8(yuLMe{_Pe>EYSO(E!1+(#g0`KZBaHr2GjyPbnFO+o_Y2rzcF}RDp$~ZqI@E!L zy^t4~SK-|445fr-N4weT*Us3~->pfc>01o145GMg_H9BC198D@(H}$k20QnThmQBC zs+c+4u(ZHDNg;0_BKLU4`z4WNzv%)qV_R;Sbc!eUxN54u2mR?~>XE@5qFJV6T6=Cahk& zhdq&UeoO6G0!<=aSw0u`yYY|vMHSGEAtgQ{mxR~B41tE1%gZ>}>a;`l5IGz8quxY! zON(-qvZOhj;4&ez^h8_dZ>QSfRpm3E71USj3aguq#WszmlH10!DerVMDMBkt0Q(k_ zhEY;qSz)4!ns3&e3*+0o!OH;4w-zyB4jVU{w+He9gR6Kx1Ro5+DKuNILIrwX+)=rlqn2cZde2%c~1egXQw}YOuKj({tOWb{Z(_ zuPKe-3qr%vnA3~ToT)y`2U?P@KHED3Y}-u%?)o$Ku&}!nM)hLie8`7lG{=OHbgIyl6DQ;6<$!o?$_}eeo>Pi$MKr4 zgn56X{i>Ue1nkVv>1S#ZnwDSZNUVa!twqwaZ4|ZdEr+It9r}{`!p?9QeX%!mp_DnH z-(N+IvY}%r_<9ZjL#vp%b_CJDLHpXl`hMWrwO!Y#-DNX}Le{C&cpZmAgmp}kLME|s z)u4U*VEq(O4QRJ@V#j@MhvUTF(|SN~*>FIRWi$G(Efg0L*k~Pd>y9AWJ!oG)XrDM( zKL~V#P|?Jx?SHZx+k5>(N2X`z1=$E4kAs9dL#Q-kOaebcAT?uLgdszOmZDN;VUG>pmilSfj*-*&ppI&HTCO0kRF;|jHFhrywkLa(* zrz5WDzoTXTldAP$&PUV`U%qH*we!g7Hhw6r3l*EubvCJ2IG*VPSw-)@$Tq-8>}Y-# zJ0L*p=)Uk{20WVwVbyV>e`L8UaKzOp)OHsFv{J{OPP-f-eP#c5!qpYt9e7)l-pVtA z%1i;qQ$Wxnll_q{FnaV;3==Idf(zCW8r5+fu?jr^tqP68oN7by(O1#MWYcFcP}0SG z;ip^?V-Lji#En5L)*6q;tTRt9cWE+pX)fex9Ey3K`tSX2I^)WYCTJUJ7%1oo6%p40 zYHrKX^b+Ns*aVg~2=~Q^sE@$(I0>VV;HmpgN{wFu=hqM@J%v?d0DwIv7HXSv-8sSTg)`}n&<>Jufzb0NBBtadj2JYX1- z+;fSsQ=I&LiL6h$Ulq##Olb!XZ9tu-4T7HV=Q*UoQZFRmT*8G|ih&v4R2RAwGee}o zbtA*17tV1iY-|VeB!hSQ8*3zucUqqws<`@>>&%}_;uG~-{i7C8FOJfEUW40Xsi07? zh{Nf02-o`re|+uxa;SWbtKH){g14#4nU# z7>oh!Hd;3!QCo1Y5k_K|?L2dW=?Ws(^ltt};+X9RKqNsh+E$orCg$5ivc1(12#;%H zJJRu#oGERD2l1Fkqw8)tL5KR)+)kt!7G|g+triG|T_XS# zXE%Y74HXag*>SZ^iCUmJrlsZ?3(xW8UHwNixBIU<7k=A$S-P(f`HRTgFt{Y-_tT4vo9hxVwAf?kkg;uCjw zcXt|hcXw%MVA8mrckR8;+UMj;R=%Wu)cEr}$;h2iSE`2WSTE(PoP>1CW$!Ypg>>t( zCc38(95Drb6lYEOc%$+GYDVx?5Bv}2df8o}7jAQG>H4Y~gee`e#j}p)a0Hqsi8g$~ zAMy>His5ap*P9`|7m`nDy*{MP6W8_glMIUmd<>X$km3?dZBz@~Zt00EFVP|lcuBN% zQEj|Uu#qT)VqFlm<^CC$H@Y*w?4wa18`#q#&4+1^~+h=w1GK9`u;LT&mzeE zS|XRn#Ud!jyubCnng4vF@=&`K`B&l}h5mzb6%7Og2Cu4M!h92H8Ak+fbb{N^3dpoTev5WVv$8xM{@yCK2B_Cc|MaKA?A@`QWw%#3fmSmRo!J=G-1S{ug*>Wo%P13xZavOazRkunt zFQ3^&a_0tN%H8B0`W*#k!A=Ptq`x@2j%!!6D6qEZc7$GEA4q}jP9I9kcS546ocu#A z8ME|H)G`-%FNj72l5iNFd7qe$i%d8+Khzg#JG6S3U#i2j!&G8zr1!2yDqcd4oH(&b z>i(=;61T0j92SfJJNcxVW0_!Omz_<8AsF5uBeHHb4m7KzRIOg49$-E(oAK?coYEPo z?O?4pEnAdK*zC;vYLoa#X1FI2zJu$w0yeT@kVTqh#<}4Er_|@m{<{U|?Q!g@xj%_q zsZLm`4a6U`u|pDmq{=m61uvp^OqfdTRq}YR4JZ7ER{aPX+v6>kIo61FI$&7I(T|%u zne@zDDC^pMfg;B(1!}5JG9|^;=!1=JUhE_#QjZw;&+X7L+;{q#E6OB0i86AaE#jh$ z@{A_iH=8V~&`h_+0w)1ZWNaj9!Fo(%e;N6oiuXc$u-@4FcqD#U9Ui>pU(2w38I+0CcZR z7c&cy)4s#^nzL36{6PyOpW;j00aYx*xx!!cna%W>Eu?6A-chNvb%mO~F|0y`G-Dd* z31lsYNjon3*ky$*#6;4YkJ%! zU2u=9#%dL^LIZGUd*Xq1v+B}r0?}et?iDYn)Cv6`HgEO~{ks6>^7*}VD)<}XyrLmj z`ysfoZWV@DV@E3HlIrErGlO14X1Y6=5P<83H$oh<_thsL((Vbd=n2*g5P={#NEtAI z6;M+8AvND;Mi6KW8)%9XNEY3P@Q&)($k9IR`Ud{o2@rCL^f9;a=4n|#XKExhVh|WB_txA=_ku0 zGD%|aVmf%nv4V1D=nqYi+9b-YR(Vy#Ygk}FcyFmBPq!r$DDkf9UVn%FmuvmEL`X2d zKtMEp`A@DT{#tf=gB^=hae9fx&_;#&nYU4lT=C z`Zdd1b}h@luTL)oIFb|%Jf}&0Pj=j9->>*~`5w29-umKlzcbek?fRFGwn8rLW0GHC zfMrRC%MfpD{G>|rG#j>~yZmoV!%>TF_^|UHMF+WAt`e@5(2dYs>g>Cfhj2Bwu7{b~ zc9{<3g#~{KK|ULQ>5U2Reu^q5eb}#h%8aV>oxd35ajuJU@&QLg_0W^t@4NaxuFHYWqHNs>KSCwV>e}}ulFg>nSoyKF#3vUV`_QpJ+rbv=d-95ahcQnMBAxxvE?%N?OiR2NbQH7-QBjh#SjSERa|t9K%d;;O)HHW_!f3yd z9|)B3NI*kkK66{<&6L$Y=Zd5La+~CqJ9;ccq71smX|h(D`jm27H&+nKq_8;Z+=n)N zk=A%~(h7TnB)B6@Cw0LrRy(ghvGJM+LQKOg5;j#eYLN0g^};jpt*s^#jMd5{D_S<) z$nY1Dr9(;wTdQ27_k>);4Ap5$RWo7W-UB~W$(Cz=NX^xgn^>~s5>#G6j<-o$HfL~Q zvGc5BQ(u7OxbatRWn_SI`k&2;*REm?+tzv?O45IDlD~hgijf*iw3g7!gO|)vHA|vg zTqTeldIS0jsU35R<1NpHS|YFRzY`Eh7{pl+FotRx%-vuW5~P}D1Xm>JNXO1ZFW4;U zB*?HbAL}uo{tY$NWT3R}C=RqBW}T%?aOl2~+nuo9=8kLgk?2 zkPs;;)!J$=-w%IE2wu3`&`Gp*N+Tyy9~DBcGKgy2BI1=DTm(oB#c{ns1A$x^i6G0B zrM*fM?=sT>twFb^il{sr07(u3Mnok*bZ{2@^`x=S81gUt2RRZpi_H@iGkZ9`V?l7C zXp{FbeL#t^eJjH_tTD?p!?p8DIfK*cxsfq@n?;w^C0&S_OEQLRSwtFFH)I8TTS~=K z3vhQ&6TNTwh9ID9|IsvFWcmtN=#%4DeN{k1KtOfww1-OY5y8XtCM&}U^UQ?qMP9u> ztA^M%W*u_om@;o9@z@&SRj)N@WO2uXejNwmVy?d%AP`%T}UsVHBL`-4GMS5VE~%2x&03L~Df88JRc#nsCkx zAA3kpGH@z*|HFgO$HI!Sao&cS0?yP~pzG-}Wpc$_1a|mb6n!y(S#P81NQxvm3JCj* zGlc2j;-y`2#@+)#f+7~2;@v^(DBT_C<5PpAwXQ^;y1e^L;Y@UI(qAt zuuY$Q>h{#v!2}PoGGaHaeqBNq6>{4?oqZ3o!QU}5m5>jU==FqERzjG-@wba&lJ6w0 z#p15X6hD?exZ8K7v;%wIiN8u_G9A0ltf5TSRF3#N3)9vzcNd<6LV zem$lvPuBhwB8QcaILP{y!Ub8>%8dNP7)F~54vn-Q`HkNC*o4nDeZi&+!Ju3a`kp8X z^sB40I3Kk)sZgfS8J9Zx3a@$DpOzj!b;#MOgf|ks^#=ykTdW{ZwW{O5g^6#fz+v1P zakH^`e4VE>sxQY^g=vuj&llp*bH5P^Z#QrV`YL}~!paQ8q9=WUb1i(5DC9Q4e0SXN z!@NGuFW`n^|e3bn*&sz2!h26tAbwbX>~NJ6xMcfmh2PGP(v*0pKU);l70sOblc|L3VEI{wd<^&S{v4~ zpc&IA=El?zUr~m{D|`|aRre}YC(`Em=yY*M-mUE0dBv*-u+tzwTc#y9%u1w>W43Ul zpi#wAv1g_kF!E(e?x1Jd(Pg$emH$dIQoxGOXgRzpi#{XK4i?Z6jEmkLU9kh&kEz5G zI2#l?vZRT=7Eaw~-uTmM)}48&m@nesiJ(~!(Jd?Jrq1v4TWUo{m?%fg5}7BLz;`Bq zg5+ABFTsg{l*Ik>ui9gu(BVn;-E^Gg*48ft{wzBirm0iy##T#|q3foW*LJJESe4&8 z9q{b7?nSKXI>^jg3C7-(T+*z*5U%MtjpCt#3gL+%#?fl^l8mr$tqe`kww=*&=-1Xb zxFO71@cZ)hYlSDpX2dirk&HU%I9Ey)OO1pbG&DqK`qa&3;IWpaex{9VWD+}>&If9-NCYe#6RGnFiUmHh2fSpt;PN}%iESk|6#(@L#(jWW++r^a1cLs1mEKo0-$=7J_KMFt1;O_)D65o2=6F+6g0+B^;N7==g zltN6q?r0~_RP_HbWW#UK=$+upYaVjrK5_p=br;;mLD2{h5Hwi-iR!TaO?B$-ChivM z7ViHIbFtbEDjKW!0Vt1GGz{eR&=%;)<@Jo~Pm=GD*b^R~Wn6yJ)R3 zY=<%fif#1lXvXtaW|A|2ts7ePT;i{Fq@D{lfmRzzn@gUF+_Ggk=W*P3e5Zz2%n=S5 z>u$5&vwYXDg4eIPk3<0v^Qe~j1thE8Hzsq@nlgYj`HB7b%bbLsWLz6_bEmcFCf?KZ zmJb8GgoVP$y1ol%GLPP9e)x3XN1eLkMt$3kc`wI_si`F0o80HgRs`9>b*tVu_| zg;<7#%V=glx&DT-mgh0yFD?qkvhwT+GZGjXMF~&!1+wx6a~t#P+Y~Bm0me>ScnDq= z>ggn0YcTl88SY$#sXKoZ_+saBI z2bKJ32z9Xr)UV2TNc$WnW3|w{l7ov9G!#Hg1-bYUstJaRr4OZMr*!U1%@qX{O!M$q ztBevfRxQm5=+4rG^UQ7;|9p~w0@AR;LVO^Uma7fje1g?O027GLRR~!d>M~<+a28FN zfR!=w6#W%odcM-mW=+X{;`vhBzB_iQBtgmpn`DLTn;2T5NBK;6bp4Z^LK{uo$ko}} zar^fxc=y^d(wUdJB@tcJg3;OL?}dg@;pDYEHG6^%`8L%#%K^c_GOQVbBijs;^ug9e zos9@FA0fghMdZiL{?4LQUWdZnMEMraaQn#Wq$Sk00GcdnIyyF#gqtZ!Ea#|Fz9m`8 z%Fs=ILX>$T9X)+El-)C9O}5mckCCf&^2+t*jN+9-BSTUY)eDRqZ{Dz#T!-m!V3V%r zF6d-my$p%(cxN8BEpd4>g-Gch-`9-&YuXf@kA&krSe3=}Q=J!Noh(ntmHx^!`ruXnITkTzoREeBirIXjt=PlUa!JE`jG!Fvx z9`{C)wAQrm(tkW$JwN(ZOw-^w8`Z7>gkpp@?Oj+q?>=H&=|f(jVZMYU>YQ+7tuIlm zWGS~b2fzn_xx1OptVsG4)TLe49 zM&JyWhM*w6rBTIGe}DV+%FSh0YV2o)$69fjKM*4yiHMGmzJns zEICwpXiGFtT=i{wOEex@>(k1XoLZJd2754uIvGPcuYa)>;f>|uB*!Lh0~zc(v2HUr zOf$x}8t| z7U2ru^1GrcwiV*}W}yDz%dT<=S&pK^Bw%O|cbQ2l+hyLvnDUQd08MOi{Fj6 z-9CkRGS<7%P$!Cc;U~04Rq#$ZZ#yhx+rBr)XZ)>xk89qYL4AOsT>6!OSdx(YHXFI{ z3}b*^21=%!!(vOS4UP66HG8>q`mT&cf|6-ZDd~3QmjZ+JtpYCCiMk>czQskpTpDUi z5rcGoboxKTh zRF&M>NY!W8#)j^AX~HQS73J&xD7UX>U5G0sZs`mUu7~<1p{y$L(jv z10*r8dBz6^nQUIkMF3KGy9-=zt_|Zkyv1ynm>KbXFzgSz%A1Q-RqVoIu^G)!sz&~0 z!V99+vxQyDM}tws=lct?t{m`%>Pf&EP?2hkAEsM^mW2b^&;+?pZr9KZB`{;ZN2nEwYWiHlAS6ZW{1_2emo^;=<_-t5|8*&F=%Ao>8oYHRzZMaS}No~9+M&78r zD}<16?xQ#79e0Z7ti=24(M*vq6>#ysp>$MI9(fU=uD%lQN9P=(Ue(v!xLRJHuR}Fujw8J#<6Sk1y=4QgFb?$vA^VIc`Xod9ruZ1Qx$_*O zmC352bnOszG(nZ$5Cwy16mbd@U(L^Itz$hzf}OH5@)akEZx{191p0tXiK_kP#ndM* z-ZbAr+IF+^CDbzBtGFwMP`B>kDw=rHyH24T*uw!F1yD|IcXpk7UZJ19T6bP({iOJX zzLYOCYJO?UFG8@F{%S7}WnePkjn_(Y;LX#AI$!B{v6a9HqEm?3@5By!0ZS}py3yoY z1tRSrPcsF+xnC*Dn^fS774VLJa7h=Xrw7#Z**xraT_32>r_WJS#^2NQ!Jm$yrnp|Z z7XI~qvO&HpeI+GK6PKQ)C;hlH5drZn+VgYzV*8%iAGe7&WAURE|+ctV3kRP z5c|q7R&Hri3xR0xd%)mHbJuXBDGbZ2c%=M6N_??zl<5jskN#~n4i0wu zn;R=I*eOEj(5f!t8e6I^(vn>^c3yU`{=3wG5wW^^_T(^Tx3Yw*c+47G$eS(j8I!MiX_^VRWsVF^nQ@Vrkd%RG{{mu(r!YB5%yP@Yyl$N%m{Uod zx#qdmU@SM_h|-BdY*|K`^`&WUB^c>1XRK95nVsP1o$aNimW|--olSRt^$H-t#;$wl z&aQhZy9A8bBz351`P~fFt#!n1ijSaNvo3@qxI-QzlE2sa+_hPG2Q?+7?cXyozDra| ziRTY1j+~i$e&-}CbAkv7P8cI{iv3e_mGd(^Qv<<#TIHf5EeNRgb11Bo8X(x%?9f(UK$-Xj`BEm6_E8n1w7@)~Z%+f}4_p?bK4}JvLO>&`2sxuRXsMBpJe}i-G z?l#lSab@SPqi)WQQFg>(i6nfebB5FVHE%)_F;D&E3t^52m2l6MNU(yxe3 zEXlgBzt$--#n`bThRtts^?Zf_59_Y{e#Y4x`Wt%eWebSO{{CH=tjc7wt2@ajaE&EQ z#8-Md@mJ1j$Tc=QI~#=RHGkEJnf&aPPApQJ-4|fjvS(-&XeT=~6~|gw=sN*^eL1X4 z3+u9dca9Mc6C-y~3i7^$Tpmo<_FCx)U4My^#x$Ah=u%|S)rhA#x5&P}v_x_;D)LyC zE1qp?J*9HNIZsyr7qKSX9!bY~guiq;a1iQGZ@Z>|dt64%UEY{nMNocQvOn(sx<1=E z)Oy^XY6)T@LUpx2UK;_Uje3H@ z`AGHw$!2h)W<+srg1^9&qv}Kge7PrU!(gP*CZbuF%M(EEAq)tY&+q_{afl7l=6i7N z9s%=@5)%3H?HmE34;?^WygSE$xI=%CKM|?3-xwHuGyoLGC;aOVB1P}{HCkBEov>Bj zm#`u?2doZ~^|z%c>~n6P?^0>cy*uAtSyh{&oR*D@+;VKLiO1&}vprA~+%oPa6iU1U z-u@6zsyCAzvv9krfin3Xes1YY>;BvoGECe#&Ul+vAG^0A9x1>IgRnIQPs(yf?J6I9 z4;Tsa!rQTFpSWQj>_Wa~GjIUZ?fU~C32WI5?Am9Xd-h=mV}V&nUC6#jq^w)^?ZY>s zgEhcSBvSS*$EW&z3Sb<;6|3LWjmsbnQXZ$@gmc;cBCrc7kIir8hHr2iI7`@T{8YFv z4`d$We9`f%FMusT`sZPe{B&ykK;$uXPIIYN9YewbT!XZ%+cXizAXf?+cXC2{l3 zy%Quczl?4=npp;orn`j)cNHwcM<%pWPaGso2DsR8=&ysy3gIN}UM!DO8**e;71IJn zE$di&8s4|3tiOE(1*+NA-ms__1koRXtzpvtbq{oL{*+B=wL&B#Zf)*vWLB zl|B+^1Fc4Tt!9I~y0wrd3439>WQUx?Wu^m_(U=B?V(?n@UC}ZR?8qx_%`c*!0g3X5GFhvaCpuw2K zWzl(*0gX>c;EaQ^h&=j$%%}4MLomHd9-yV2=?XWG%8-HtEssf9T9B3m12tND$Zq&F zN_yDr00c1b%LU{BdH`a6y-$$fumh`zJi1&gBg$M1Cp0H4Ck*9i791xWBk~>cUJbtt zK-H5gm>cW~#y+r$^osC`vKs0dn#B>3_A7bnI5>^WV+ja)3Om4!G-3>hd@4Cei!@>m z2zyF7(2g`>3W$AbIarM}VhIR&@*3)6_z(gU4)?KqK!Hi4b}2t7z@*Wi5^t8^yr@rw zx6^~Rh)=P%w1d8bcMb5@N|ZsyTeGv4zh<=0Ixm^p-@d=j*=v}g*rE@Kh1Nrxn4|ro zazBBc8lH|=;1QPEH4E>}aCxbnE^<;P_9y*qL#jMCDQI+T5=8$?j0@JPoISe&B(9bN zlBADFu9Ob36)VyUqW1W*@SA{9i>E+$JBrGdOHTtewUSt;)U!zQ&#-F?sl#u#=0(TG zf!jSsJ81rD@L6-|H?wJpG|iAECb(0b==ufQ;f@u#Y^xtZe`^R`f;_%5H*4*a+d(n6 zwjN^G;WD>8?6KRCGPem2W3S-0FO;~X*wNN{#tw7UA{ty|f-Ve}+ezfW0oHUEf&ao( zW6fu5V?+puZ0!GpsW|_}R9Q!NacdLT|IhWKud~K7@yE>7_N8SL8=E;486k9Z`??|m z?MQmM4#F4mU$}Ab!ei7O{R5UfmyWClU(t6pFQBmf!k`sNr!+J$7*-Z+{%A-GEaIOl zyebQrwJd`C`OG$Lau%+=uC}|f&@3|*W`yE)|Go;%jKh8Uzy4?kd-!d}v8ov&z3hus z;%TlOOKzZ|vIj6XvKJrO%K*38x9A7!iMFWSeWUocm>XG6AU`0}rdoy8@q8p;=c#Bfj;6`d$BQvxj8?<_PsAS(7m~$cBrw*}h&#nm z)fu%EP|S}V#T-X-xX$eucEL@L_opI2y`Y*Qm$Qz9;EZeW!mI~DeW>`wG%~iq-C*UR zG+~=$mA+OlgEgFxKWY8pPs1HQhdj1a`w!?!;g1%EDa6yrW(Ou$y-S@+72%xkWO%}h z047c)te5hriC6_cR7LPe()-B`mp;>Q&db*2<~Yl~tkrp5#^ovA#c4aOU+J(12jBio zy1C|HvMu%07Z@WW`i$7&Bz$>PioMyPq)m*{8#G0?RTTx5S>4;s|ha^CBWO3S6h{X*OuuoL=i#^wyk#FBc&zaK;|1UzX!#1@vi|;pidP zJLbz0I1A30vUIPf@=g?o%7LjE_yKvkZE0D@9bQpPZs299AP3kYnM4C2>Cz8!9F(3# zvt;R|DPj^u(_c5W$XD`N*)x-FbS@`DbG@jA+^u5oDu%9>02lmECfbV)bPZ=s_fd@L zm2!s9z4h^TrQ? zWp5b55ToVpRwmNn(xN-=B16+&NA%;w98 zj0WMQ?_iDfOQzWqGAQXrA>X}EKQ`|}uns`dO~g_XPmQ(s`&&wAIrY@FX=TUIhy!c!0q}4E6U%^NzanBH- zg?KVOfevv=mB{tt>$z#c- zEOsB}75H@(WAws>Szwf?y3Csp|HYBNJ@Uk1#C9u!t38ZHzkM+zYi@L1>yIO0Z0_Jn zV=xN-QFjcejh*T&;t()}(hzMxya9&bW_3wD(=d>H#(|ctg=q}CT2WaVFvfBtXGcCZ zJ1|ucj_f`Gs1}%YhM@0`8(;Q6%UDmIsHa9BV(U?q@INq`2mh#aGt*=~UMfl^zsYO- z<EYBVRO7U#xI-Gj%*6N53HPR9E@J9PhLrmEc;vG`YtTW*MmZSBv+&2Z~p0zD-;0i zxC1UhV4IG{^#Q_L#O==D;u9WRb~6ALcaJ^?iEM}0j+bK%S&28rWddQ0u1m-NX{;6r zA$HqDgOp0fnz{^lGN({bG4Ik*vr&&Y2$GNei8B>c=$i~ee7t{#e>*ak0G%s)*UV$` zD_GY2I?KR-zKt~)umBx zWZ`aPyU6{Q;-RwZP)?(q*O_vdq4UC5jeT8CU!@XykplcuJp)>{XP!wKj(f!Zs1*^< zCzb2jNjL1gbR)&R(n1l8FTVyG=v@4{hPEWdAdkIris{DJ;t9x83h1x?h+ls|pM1u3 ze-&@7G2-9Wxf&&cCI%G{hraj_oSA5+dVXX6yRYF4h2Sr%XpOW(@Isn-^+{JY89#-t zKY(Goa!M8B)r7Mtl(aTzh5mZ+sa`#R+%Zz|fEH<*+v5hQ**)WLx9#9~G4QQ8mZU3< z8)q3-s0hGp4IM27mN0n+6osWl*KIK5jF)X{HjKQVHqxj0_gFYz0D5xH(0gjeY1V6r zPi|#3^r_-^`D4i01qSZ)j-2XddG4y#7J_y;_(aTJK7wN3;}n`i_67ZBR>$%(Is;9- zo(M(X1q$ASahKB8fPwY*pO{cjJh_^PhZA9K|NQ8d+SCpIY5``S>hv2+gO(hPAxiJ{ zns#uUMXRn=NM4wgg(6+_k(7UrX2Vgjfnf8oDF&3j13lMU1|DAx6c37{ zqX(-NQ8TQ*=p&Y9OX6$;yeN0|3g$-D)T}EZ-IPt-F6`*ln#p__o?34d`Dgf<7AkGq z&hW42m6bx7V`tup{z`e*wB|LfGm|kNG{-2ebc&7it5dgyGX42#!^K>%nZJ|~Km5DY=KM1Pu;%@?xk6g28gdhpCT zY7NdTvL>5T)l?S z(cL4&1;rz;L-U`%O@j`WG)Y@)=bq6|}S%8{;SaYY?V2!|j1 zTuFQ*{TC%`O(|6z{6on{|M7|be-khNg~;On!sCB%*}~P+#QuL0`Bfd17gewVt~MOD zt5GJ1_P!e~*Rq!)>|*)p23P1FL4}5*$y|-V$k|GFf}WZV!KOXE@`lr6uwWcl zkUdL+3;8#{FXECkkYO_&F(r zG5j2^1zHO%udes@qE;xa>KL2qzu1HpOAZRg3&26vFj=_|qd)$icN)W-e+ptfIPnbQ zwac1hPsgON-5?jeni*KZ$}VO81^mr?gU3BbN5>_GyO{#QgHJj(6r2Xj_t$UHR6bJ} z-%*iCkl*+y1WFuWo4ExktK)GKof4URSJ4bTe#Y?d{M?^LH4a!@Ukt_e2{cY(Z&T?f ztOTbn?U(=y4Sh(P0L4|w9zP23wP&nHT9Bg_8l_U=JZSnym>S_$$M~Mf7_SA`#j&zY zCy-Ab)g0N|B2isFFLq~K^$tU>hLrB5a^R;fsz>|&>yAGj-B)1h3k1Y7GVJC;?*|Q{!zz|vOhK(iLR*duIi#>@Gwq--OV% z(`(EW!Hz1~r3N1JFVa^e?m_ZFkAI|M0Yn@`9IOn=f^|f|I(Vum(o>?HGZIl_(Husm zFB9;BiE`=QZ{x*6;|j{<-HFt|%ehK-G58Z&a45Ygs^8~VJz!Q=QsheHRDnY29rC}fExaH>0qlcTGEplBwG8^Dg zr=`D!J*F9gLv>Z9{y~$I1jH0pM~?G^y%1IR?xJ_+Q{r)(FOUy-c|1^@^=`oo1Mycp z!+p6||Ladv?Nhn!c{Zf*j-FS(bgrTP+;qw^=O-s1N@LHT#Z1G!7&2+UG6e0Ibtah? z8Gw|IXO3rzXIYQOY&zbMH-7}X)RoD%a z;jUy7LauoX;fahR6Hc8(&YRbQ;W!~#TAjKsbDX&#pDRfAfKDwiUKADF`3^f^s1V;k zgJJ$>9GY))f-1h13iHT;A+NuFGzJ=Glb(`xLyJvxyj2dt$50)JREppf?=*%wHXcVi zp?sE-$41#_tPn8V{08KECXT*^(>hkJ9ye-d2{Z#<_3(NG$)_(Hu6nGBFc8B&B96&;LP^ldQ4H#8B=o>wM-#;2VsD|VWD<|I5NUri z+~zXMcy2v!zRimLQFWdQO+MLb)>Q?GP~_U2yN&_x;NHp1exf!gNNA>_Gw$yVX!QuCd_Z;G? zQOrko#vo^GL)wX z@?PNFYU_^u=HaNr;3j7SbA)_l`>9f#N-)((WLsT(7Dc44Nb z$mF)#`VKA88=9MXRquqhFFCI}3e$OH{WrlrjvxbUwK_bzUIX@5G6T^F&(L`6CMvtZbO zqvlVojHGEH*U(_-UWQ4UN#0jO2xS;&-Uy1P00?P|&vS?o3n8+D*(Wg6vwv$$uEK;f zW5h9FChjmmux{_iYOm*H38HP4n4~^^Mnj=&6;0+?W(;cn9%%$h%b%!Hx`h!!4YE(fj!&ly8aAcGLb42528!DPGXH+suvS z*hvwM(9W*jOdN4shTSbj9=mXK_-sad11EhiK8U%>Z} zNV+o^<}0#b!<|k?P)~kVkLlb*3qwb0gyYGuBEXuO`7Km`L73wB8R6!YE^E^ zjV8S#dLR`M-%D_=@7g=np(Xs_>u*U&#OQ6#7^jA}nvpHDYZCCvOcZb`R_wx=a^^AF z;Io2IQY$Oj!e_`~3C%MA;ze%#Cx@o@i8$kAnv18M5zfQu50-iP*|Ev-1N< zCX>H)w5}(}Kj?SKWv#Tu0ul?hF%>D>t5m2ml&9-2WB;(5@t_?Ueq5gfPD!mMbjf7A zj2$=(AEyhH9p4`EWhn9ThBDm)J^K~({)n@={S(g~K^X`J3OVunFiuMlQK?7eqS2I&@dd=hIEN8*f&aQZk3k(J|8E7|HScO zYK+E103f`k&0fz{DqE;Q9@l6rV98z2F%{*6$L8dXS?R~HHvY@~1lEQM#GI?u((A=p zoxk;l{a~KE`py%5hh@WY!~9{gCsfULql~`+?j5L3dSXaJAqK??cyf?+zHb!E+L8~a z6lJk*tghy=Qnd^~s;00GDta`oxa%5ZS!gg6$m51sRtvWE z)I!Y5M=${Va`xxfwE`tYmZYQV(^>GtzgKfnwLUixBx{n74=iz9!CPgDXKUhW zX@Tmy{rHN#&sKgtO7ahJ&m8%h!|bAyObyFbANZPbX)_y4dCgGiBpFSTBFN6l>b%vQ z=nAa3bthM$KY2qMEbxB84uG)Ow_Pow%?s`Fg3LW79E8gQwz*&kGrucS%mJ{1WRvfe z$k#4vJr(o)AV+xVQS82^xnwKH_J>J$qSHsZa)XyKr^!vb(%1L_{F|+jlVAjIB$t&) zWQpRruvnBv%O2Po(y+(KZlAoJZjCB7`!CY51Et;iJsU3H-09Ow!CIJf^% zC_ad+z*{`=_JLpR8HueKB`8wFsV*8ggWatVmfuj5pzU_GYm!r~W0&H{=Qw9@vx}@- zx`x$HGrZta?U%eqR6QUqYIfq&)S9IB`Kqm!YkK3Ih`5S$NN*=%q@|J+Y)9*>$JZ-b zW^E-?6zEYl$%i)wNw~PV*oiZkmz;_AC{_m;&2?>j(SD)z?2LBr40Lv;cyG=Ewxr@v z_V~9@k`!`>wq^E7cJK<8dfJnke4X<^!xncu1MPQv^whN}=pC6Hq_!@YNv)!%rj(?A z(d~~b7MdKYU2$EuV(e&7Pni3@DUl=!CS?8nQ8kohl2+M9vC={*2I|1sRmUZ45+p2EE3?nO)1v1 z>_&rjWzP>OWxk_%rFpLuMm$hS&6n5z_L~DRbO`*-!Ph_~S!oERYwQ$r$f(*s2T~-q zI?v&Xbz(+`96h^s@ti}*4#Hg{qrt06<2->ate`qwYoK6;^N-J|$9yLc%ELo>QABx} zklN3%{S4(MU}oi4Stuz*U}QdCcy&JyQEyMC z44ZYQyAQPeGW@ z-)R0a-NETqKf>qcWHd?p=na;603s6=MLy@esq^6>45Otxj@6#y=kA!* z77O{@^?**5I&ShpZj+AAV96$Yw&hrXt>K@n3uG;FML(7kF zFRl>cUo<&&L$0YK)7j%`hhza4+-E0zgBwa=YV*bG0XyzobDS5Hg92kXV4$CSyDx-vBk^A3Hqw_>$5z~4@jrF zC{R$Ie|?fe_Iqh6XXR++3UGIF1>2$Qq26(^LpeibyrB1YpKEc#PV694%-Xcb-aycpCg*eY~wg)g95#R z0Y#gwwY&nkq8Kt1X&kNDgx(U)tslmMevd~I4)svD5vw^S-}1HG~nKsVuQk4C@AIBys3ms7ql>{82X>%IT%SUFyQ5OxZ3k;VVrhinV*1ejWQIJ3KYIJyHJtk|_4IG8(K zJ`U3cs^Mth-f?QGr#53%VohJ&aA?s!n2Qf zk{@&2`T)OEvh%_5hx-eH$5{_HvfIQSQil*sD=dpzW5d;;RS>QV9H%X*U;~HTc38V$ zy3Em(6bd-V`?xBY(Mr+mI9s9t#uO7m703~J;w8XF*5-)=mJ$3<`-Wcu#l9v9cb_U^ zz;)`J_2Wb|yxB*tu+e>2H1lPr*uxsHME85cUX`z{UJGsDr)sVHEjode`T8vLW&OK2 z3)U--caC?2JkEkmnP+$COO29ZVxx3E)Ek8#GZB4N%}5s4bxmUOuUY)&F;e_K^wpt3 zqXw6ek){BQ^{!Ug$rNn0I{m12Au-uWF+nZqGstx3<>Z9OR062tE&JY}|* zNY;MhgTC-$S{UPgDoR@Fy3p;e{!KzjS-IpTO4ke$fY+PKTnngRA+kN77}vzUMwLq}2D$Bul&Q zc>rZs*LMs{gb9Rl>>i_W$WZ}}0fAgNiVqWTLu1Ia3I;wQ%TN;CDHQFjjXD?9W|iIaK@#)jhToP^72CMZfV&P?N&*gw|Ei*s z@lIfesl4BYxY|Oqc-$#$BN#LUmXi#Whh1Y0NlS7tK}_&G^19+BeVFP1fWFic&zcBl$zcwH#_Py3kNbEIdBZh!B1f zdmCGBd2MGd)n`}GZRf-3S@yzDaWp-RcbviL$Sn!or9xqQ1}HXFiS5;o1RNDVCi7Hm zS~_le!8$3r(FfLJH>7tW%};Vh;Ss%J8WvV)VQzzO{BDB1t5lTIj)**GF$(M0T=%GQ zGmdbqC;aQPOw7=gbtPB3RLVjakstaTl`vAi+$fJ0Tt(#OtW$4-+NK>&OAl%k@k%3 zi!(Mn^7R)lr#0_l_M^1Dm~=nWH!QF7oPM99_RLvbXD^LFQ|HxcxI|`!(1EHAqIw&h z2Ko@?YiEOj^%)cHg_SpzMtg9WBD1_Y24)8od%?8h_>yB>p-z(6UaqFb{Y)Bc=HeoFHGsDjVEF6 z89`IqkH=HM$`NVmGCn1$oGMLjk@=}gc@#ilPvgmHBB|7l0HppYPqlw3b(Fv?c&)HupAS}e&x{4jM$bu8z0;@o1T$sX^QT~NYJ%MWGqGf&e($q$l4M~upH6a z7BomrX{S|Q;o4?jgtv?j4*kezZc84l$_{H=CvHU8BX1I;$}8w!n~>p8qt;ttFbmfZ zyTqpY9c8=NNVa_Pu}v&nj13{9fsSh}yQj9hD`x(?Ilf*`&Uu-pF&p7fK(!sAROl#~ z8CEs`KAYUUftYjXu`Yg9(Ui&?mu@?aQwmz7!sy5a@1zymwqhotGfoZKFuQ&^gNpdc z1AEcIpR}51wVH<8DxzKY2yDJ3$uT1C<>tpKxMNTb$szfn6RG&}b-GfO&0&=li%z;1 z-cLSpG8}mu8sLQV1v$`P3HHlv-YuVm)o>{|S6Cz?Jt_s5(C3jG!O25po8jd!{+$B; zq7%XHPKsj<5;e5E4;9v0&e<<2gc}cR*dQzv6z2au`|*zoVek5@IQ-iRD)a8e*^lqU zKE4v>W`8o!DIV~cQWQJHGNBSKf|rspnnHpPohm&{!CDf5jvK&*gOn2?S*7~|Un89h2%5qy8rYVtdWavr+jB+l<1F0wH9;mQ zoI7$YjWJv^(st$yjE*!?UVcBITGq`tmpQ1cvZAED-;L+{gPzo@FzlV`^KL8=t*+ql z#^-CS9!9@xM7E4_IcC-laBy3n@eTt*q zBRb5k(Qz#uj@PJY$$KZ9$9_dC#%}ry?k&3r_hm^gKca|F>c*J@bx(tmMa1vA|`;dn8p8c_m zaL`g+tut*9akM*yB~M>|Y*qg^aYD+69YUr>6;*=sqMXE-eL)U^k?6(_D)H**L9zGv zD&z>Mrj%p)f^s9#MWo%{Z@-NYnyxSrab+AZtC3z!O~rBOAm6Nho~R$HLWgZ9Hz?CxUxOI zwJ*grr~)5@S(lWkIBL|I2$+JhpBtuOl(vY~?tT8$?h8T$rNBB%meR*MEYHZA;%&vG z)*9+tcJfH=jeNx`jEt`eM9$-7vmcC|CwxhZ!&fe=ttY@j~bpnpMx zjZR3H&6A9ipTDLz8u_aPzxC!F$h9cS6r1rg)B*gYN7FpsI?;p^}Bk898Hn-}b6N-3@+_a%NFXv&+lE$gs~L94z!4d+WpC=`tIS{cqW%`4w-3)KQB1e6JL7)BBTei54A}e4 zd;W7P?TAJv6d7(yQqKIHdmTsd<;7>_-fpGriukgL#tj6`jb15-}f$!Q6VB>V}AoA*g_gSJOaCh5( zAg~;S*m#6ipS8A(8@xwFz~1qiZ5sVp7-SIbjvV@PGLI!n-y!(y;AZ2KlK>X97Bo*L zG%upE^7UKBI>(6StE900uL@`z6n3d7H?2|Bg*rmj7N4+fQ3g4uMOSoevV96>Z`fl@ z3)pozW_F&0-|gHr-qR6?RyQb9YTVq?{gi?3QXLb}X5G$SjOJ2J65>kC57BJrdq@H zD*U|zQG*_?!xQa7x|!YNr|aggvX<|S5}-I*0|{km`)vC1---)7OUI@jjWXWDkP>k> z(`=&2vZ$lseSkXu%>HeY9uFCnzInXoosP&FBYJvE*Odw8&t<7w=HEZd9~h%V9i>+3 z=fn=h2t4_g!BNddaE|4#maJ7aqChld=-Z(lj`{;8F2RLhQz_rLCAEJrePhh8adEed z?aWM!)-G7ftSdi6A@2>)ttECKMg11WLyK=~Jz-7S@+IDuevPesottU;KA(o1X=c_@ zY0I`OPM)GZs)31RocyR6uvj=*)mujmkdiY#LEAh#+e3uQe8hQ+rbNZKmQLM~ZQ&Dj z@vW~T2TghAei}5HW=bIwJyc5bsa6&OC9CkXA^gcyxM_;LWpC+Vzd+|!68Ox*tJQRn zn@#b4{fR9xElBFI#5sRN`2f=uC;Lf1eLlSfFdUvU^p3030R2zAAB#a2Xr?BgRZY2@ zmoW~ISrT7s(Z?$1X{EuwTgd4uXmKn2a2&+53Y9N&B}qX4?r z4850q!Ul}Zj6^gK$yu03p6P|QRTaNZ2)Ty|H(7LO#X3^UV@Nl$9q;My*U!U4ZN|aP z-Fw&Rd(Q0Zp9C+*oT~?D;%&bM8xKvu@6xw&-+3R2F8mS2SAe_Jj`VN}QlUm)P9bIHY1$R|> zvx}zV^lP_VE$?IVM@dLg(92c(_m*Yz+9?KE`VEz3b8oH~;lzGq^?HWQ`wV!DO*Yt$ zo{=!S5ExsX8u(-zAA_ESv_ypzDfmgwou`BR7-~(;A3*9SX_eSOyBAtP5Kw5kI#i7annfe(u6Foa>X*xrqaE&qS0$r z$gL;fGJ&G+463dO$S*^zR+CsqA@(?un1njSmN8OBeM+;WelP1Y4Xdz9NtQS9TH891 zd4p#%A0W*?Yp6SqDp*8uKh#H_ykVr^Gcg|y8LPXhdR9Kk8B0reN9mr-gB8FYtyiok zUAFuPvKB)4FwRr5@Z5s8U4y2fL$5gU&++<2pdSoE?~Qdc5~{9qciyQcI2cYfAzWk2 zab)-M2DoFQ6rg$egOKDx{qle|ek z1zXrp7%MhG9klcE7R19_l<4eC&&xblg;hUd2*csoCfylP&6KL7U5K|?0Q3Pp^6wyu zle{1eK_g4^3_e0R~`1XTXN#ZqYsFF<#+3K?ZC7HA^Bp?a(3p6OMN4^4!?8uKz zrSN|sxbEHOKv@Vj_a$fAgH4hA&b%-6;JuL0%ju@F*%lVlqTVLeSdUENLm^`2_@`!> zr~aL@3=%VPPutNOMwQsiwiFsNHeKj*BR2Qxb5lyNza_aY_+SryYIxdJBd~q;l;D=!8nWl0)`N`=a^2An*_*r#89O>Y zxi3lPtlJ*lu^TxR!&En(cKeZe0FCG$QH`t)$Dl|jfJe}f#6noODw)fL8(H=5X?d>Q0bEn`l1jx8 z)3RMMwn8|UNrfk8uF+uN9xXPC4IT7l(Jk-5wt`mG#W&BahO=Qr7cjjWHpR&7Tv$!) zH>g6Wk;YQzlTEsbSy257b*c-q5atJ(?;f=+vZCaCI5~-JIEk{3HV2FtWq1-XhCj+j zmU`O|&tW9Q{BhD;Y=m&^#t3R(ttLAf4D8}wC3lz#TdUd;&H2?Imh3}bZ#J_Ol7v1a zo|Z{*%%&r8)-XQXird1-`rcM3Np z&HULo{25KEHD-)@R*?A`P``{c%zEvxGE2lOqqm+xj@2uANoY`Hw@A2wf=XtHf8KV@ zLgNJeTzCHDJ~De5K9Pz3Kx+trCp#@4`(97vrm54XQbw#5)t{mH{)=rM6R#0nCc@eb zJ%Qm4F22D7F6=D))7u-nGi9@&5h!!en|SBW$7a-~5izq+Bu@Q^=@e|LAO*^0o>xZVf>M;ruM5IWb8opMOLk9* z>$O5#Bsob%9vG(-_>$u@i3Jr7#^vgqBG)oHNj^Q`3q|5`S>xX;IA9~yoe#$uBwwUm zi`z>(fDR28>rhL=TzWcanrnKBq_bu*r1c|MX7E9VIN742PS4#E^pB;UMvB`>B{*HS zbfV?!%j2JK`RaODWDDV%>KyK62w^YiqVCn(Qu^mS>WG`D@-n$y)S&G|<-7Pr`lKEC zOIG3%Y%~K0;nIqNw{gmn)PQOTCQ8J{lGNUmQ2ts zceV)_QGqRvY-p5cS(vIGSPk!J7d0wEC6BxrH1#AJn~0y4@OR+Z;uyX7wq(Eyg>Fme zs7^gv{IYA<7R|GmWQongEn&B%?;!KI-N)HtgkAvFor0+&Q9rksJa9KM_PUq|oF9vSeD72M_4OXb zdh%9v$&2A+EE1gfSKs?$gJ;pJFg)vo3|x{tCc`?Eg>6F>?Tit_HJ0iHI2UF%4?e+9 zAXbI0mCAl-FrQa$Y53$Q`4Kzn zVRoq=F^H6r1;c)J5h%?H$SySv5G!VHm-`&O=X8WSGx3x|?vBHn8Jxc){Bx`4?b&8% zz7)f&fKQ3C1(KrY!M&$FT9OEdHmP;UKjZ>W;XYXReqr27TVa=4R~U0tjDK!%q9I0L zg^oPJdYE-z;GX-lS2gc;#h-oi>(_dS^t4zkXn&$yeMF-0+q1&@yI*Eh3xu`C+9K3X zDSJ96Dr8jG1N<|SfaJClrZgMR$H(5b8Kjvy+4@6A7d`12A8?O}E-ZbetUhrpZ}3o= z%FrzSdwS>;+xWYQ2sn9a8u?E4(m@2|Q77729@cQgQ4-wxhhtUbUGgQU@RFhGW@(iY zb(Mw1t^UG9vbT=J#I|k=TF68u3qw zcRH+Wb)s}5iWoF}Z-iYc*XXpa%{{<$?{o6b51Vc*OvDY7Y3s%zL!d6{(x)v>Nsr8T z__#0EK8B09AXTU4ZXYOhWdlE2Zm!OjIs5of<$sVsA87ONZ+$?SRvuq=9H$W3P+aQs zO$T*v^V2p4XnBsD+0GVLWlowHp;l($pB?bRTxgEc77&*Ljo7X1 zmGQaDoKJ+gJcz$X#7k|W3(>q4cT5E4JEeEXPjP=niWAn^AuflS$1I0^T<9&Zo}F?B z!?lQf8p*>F?9nu5m?!k_t*iCL!XBn#enA9=^)z7;DBw{IeSWo*IZ(d&4L7y$v`)=< za7uIi{t>+B#8~3@(O%=Y_%)4aKl04%0ijod@f!oyiYVPeFz>?*ww9-$B7q~cjoTY> zK4gIwCTa$s>lqZXOY9j@WLDi)y*)>{pn34@E72a;ZR-JvD0uB`nMK^|qC(UvVnC&w>?)L+);;b6whZn!u)Q2x7P)qs8=LW9468*TFfC!`xxVH#XQ4A~u zB!J*)$(<$qX}XskY%a`O__GSbj=@DessePL9ns4s0<@l8L@r`2tYjhgrTNcQwxndX z`bb@FvE#%6ioIayqv@-{X1IF*EhZwt%sn;J43Er91;R93NO$r4yxP2=$?@5jsh5={ zjTu*(hSc?j0=KzPaT4V|P}gvf*tc_O87pkCSk2oo)dXR__ElEV)FU`2`C+k+STnR6 zcg*EzQkP(=9Yp3-gxT?!tD-1j0dNp{6lh>5D?cBf-dsFH&7jo0GTC%HitC%ziF=*A z<>BG@Q|G1D;0f7&X>`VqIcUpOYXlt`LOJR z-Sh4X-4Io{dCShEroFHlD#puTSsjDOK>cUuP7+hGCf6V(1W-jvY-)=!|OI-X^k|0VXHmvrAMGkAdh zLon2@CX<(c3Ige`im6DbD#*%cX|t)wUcE55pAmllc5&f(sLSstuF9N&$)H@5fq}l1 zvGD-1|Lt06*W{Rf%eh;*xx4*U662br_HW6{hUtHkz3$oo=qq{kH!-YhVnxsp(h)o| zHE|uN9@tP&ne^b1nf$G>vXz(m#rvUOIee9H;pG{}`Q~kqKFI{XKF9cv5Q}@&%WD68 z+2SS*1lT*-Kt?q^t?Y;aUA7(u3X1$1s)zhW6b%n#*msk$l5h|#8w4Y{2Fs$n3R3|9 z9c5hs4pujTwm3ElEG8a7ft&AaMUr~%`{%fFd`3rpA!%)1*973HP{FPWJlekmND%KT^K}{ zV=+S}-JlZCIOBX41d{&4TZ=4z@fPO|G^&2p1Q5*!q!#rx8Z!G;nw%@pQXSxEWiJI{ zy1RmubcYO-m+ItKMudWLNB`Ab?LXia2SgxbjMO*L;0r5dVZo#LP~c`O`5?nIRQfSj zK`@s;qF5w!Llkdtmn3K5>LZ9zd?x~#bc0H%jO1$KAa!2AgWFdodd*Fj-@j?!bF~6k zLWXtmzIpK;q?ODcDIqBNmz3awOlvgdl^F)rc3~3m2%1Slv=K5U3z0|YB7#zXM9^L1 zW~KNc!#D;JfpHN1o}mTV?>B(j3HhYQU7LcyjZ2vLOrj!AU7#Qbi;>Fny{ zY~|_>wE6?%ZQp^!ec@@iU%My&!zg%OVt(zVgpfoRfFIGw6@(xUw?hBAHTe(l%IgyF zdsp25aZPzc=nfGD6x5M06cpw)7Nz$kOI20^vT!<23@16rk}_CuOYWy#3M)9eUw9QV zApRs`YZe4xg$K7}D&rFHYeBAMXJv2Y?&PR#byIYHJPgf)1F@`O!I!H)vahrLJs34+q>%_1BfHN<_TxW0p7q@M%mF+l#Lhv56EWp0TS!(({ zY%k6cyFuRPNBh|jC_$4^z;6@cJ1*s~m;@PeJlUnYa|`5X@{4=8tB}0D|C9jUFiMYU zx^qcE$tZ;Q>#)cFq~AKKw3&Kzl1kcNs6> z4J%|H*d@v(P=wpy!E2!S{3S!#$_r=#u>Yr`-r!TeAfJA5kU`=|;4!(kbiD@NFcj`g zNpTuLK{a-RSDsI6SJb$e9v}m3Sa|a{K?;0E0>3>r5Qo0>g_VQUJ*&&Fs=*1+ndmuA zp!@k?EO0`&%x}WKRSPm9meAVd9jLze@qpJ}0kunl^i8!F&=9j70va7j2;eE9=AW{-gXlGDODF!{OI*9x@9*iw$K1G{#Iw!Og++ zxMYFUfh>H#fJr(96pwl&@PP6LT?$|89S9DvRp}>R03~HE8aMzW{1Wghqi#q^LRu6F z7SIrXMg~4Q*kUgMZkO@2w6X?x*t>%>`ffY6R)IzbBLcV!vY!5CJaB-l056r&b4`#7 zoRGj3h)KH?mQj9UC*>+ic8K7 zM@WLBu6Db>9%_50OVssqi@*t28`t&Iyf;OY*@>uVuV zjX$ir$<0@H0A8PT-Wy&*ZrVBt&bqpP>bkqhjA8!1gAg2bb)yB-H57{(1k{b&ufVxi z-!V~K@)GB|^Gban8GQ9EmAVrAKd)F!K!1-w<0QowJFlex 1.4.1 + * on 9/8/08 4:23 PM from the specification file + * C:/eb/eb_dev2/RulesEngine/DTScanner/src/main/java/com/dtrules/compiler/cup/scanner.flex + */ +public class DTRulesscanner implements java_cup.runtime.Scanner { + + /** This character denotes the end of file */ + public static final int YYEOF = -1; + + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int YYINITIAL = 0; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 2, 0, 3, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 3, 47, 7, 0, 54, 0, 49, 8, 37, 38, 36, 33, 31, 27, 6, 34, + 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 30, 29, 50, 46, 28, 32, + 0, 9, 26, 10, 15, 18, 19, 44, 25, 12, 4, 53, 20, 23, 14, 13, + 22, 48, 16, 21, 11, 17, 35, 24, 45, 43, 52, 39, 0, 40, 0, 4, + 0, 9, 26, 10, 15, 18, 19, 44, 25, 12, 4, 53, 20, 23, 14, 13, + 22, 48, 16, 21, 11, 17, 35, 24, 45, 43, 52, 41, 51, 42, 0, 0 + }; + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\1\0\2\1\1\2\1\3\3\0\1\1\21\2\1\4"+ + "\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\2"+ + "\1\14\1\15\1\16\1\17\1\20\1\21\1\22\2\2"+ + "\1\23\2\0\1\24\4\0\1\25\1\26\2\2\1\1"+ + "\12\2\1\27\3\2\1\30\1\31\1\32\1\33\1\34"+ + "\1\35\1\2\1\36\43\2\1\37\1\40\1\41\1\1"+ + "\1\0\4\2\1\42\1\43\2\0\1\44\1\45\1\34"+ + "\1\46\1\2\1\47\2\2\1\44\1\50\2\2\1\51"+ + "\7\2\1\0\5\2\1\1\1\52\1\2\1\53\1\54"+ + "\1\2\1\55\2\2\1\56\1\57\1\13\13\2\1\60"+ + "\5\2\1\61\10\2\1\62\3\2\1\63\2\2\1\64"+ + "\11\2\2\0\3\2\1\65\1\0\11\2\1\66\2\2"+ + "\1\67\1\0\1\2\1\70\1\71\1\72\1\2\1\0"+ + "\1\73\2\2\1\46\1\74\1\2\1\57\1\2\1\75"+ + "\6\2\1\76\4\2\1\77\2\2\1\0\2\2\1\100"+ + "\2\2\1\101\1\2\1\102\7\2\1\103\2\2\1\0"+ + "\1\104\3\2\1\1\1\2\1\105\1\2\1\46\2\2"+ + "\1\106\1\107\5\2\1\110\1\111\1\0\2\2\1\0"+ + "\1\112\4\2\1\113\3\2\1\114\2\2\1\115\1\2"+ + "\1\0\1\116\1\117\2\0\2\2\1\120\4\2\1\121"+ + "\1\2\1\122\1\123\1\2\1\124\1\125\3\2\1\126"+ + "\1\105\1\2\1\127\6\2\2\0\2\2\1\0\2\2"+ + "\1\130\3\2\1\131\1\2\1\132\4\0\1\133\1\2"+ + "\1\134\1\26\4\2\1\123\1\135\1\125\2\2\1\136"+ + "\5\2\1\137\1\2\2\0\1\2\1\140\1\0\1\141"+ + "\1\0\4\2\1\0\1\142\1\133\1\0\2\2\1\143"+ + "\1\144\1\145\1\146\1\147\1\2\1\150\3\2\2\0"+ + "\1\151\1\152\1\153\1\0\3\2\1\154\2\0\1\155"+ + "\1\2\1\0\1\156\1\2\1\0\1\157\2\0\1\160"+ + "\1\2\1\161\1\2\2\0\1\162\1\0\1\163\3\0"+ + "\2\2\1\164\6\0\1\165\1\2\1\164\7\0\1\2"+ + "\5\0\1\166\5\0\1\167\5\0\1\163\6\0\1\165"+ + "\3\0\1\170\10\0\1\70\1\171\2\0\1\172"; + + private static int [] zzUnpackAction() { + int [] result = new int[509]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\67\0\156\0\245\0\334\0\u0113\0\u014a\0\u0181"+ + "\0\u01b8\0\u01ef\0\u0226\0\u025d\0\u0294\0\u02cb\0\u0302\0\u0339"+ + "\0\u0370\0\u03a7\0\u03de\0\u0415\0\u044c\0\u0483\0\u04ba\0\u04f1"+ + "\0\u0528\0\u055f\0\u0596\0\u05cd\0\156\0\156\0\156\0\156"+ + "\0\156\0\u0604\0\u063b\0\156\0\156\0\156\0\156\0\156"+ + "\0\156\0\156\0\u0672\0\u06a9\0\u06e0\0\u0717\0\u074e\0\u0785"+ + "\0\u07bc\0\u07f3\0\u082a\0\u0861\0\u0113\0\156\0\u0898\0\u08cf"+ + "\0\u0906\0\u093d\0\u0974\0\u09ab\0\u09e2\0\u0a19\0\u0a50\0\u0a87"+ + "\0\u0abe\0\u0af5\0\u0b2c\0\u0b63\0\u0b9a\0\u0bd1\0\u0c08\0\u0c3f"+ + "\0\245\0\245\0\u0c76\0\245\0\245\0\u0cad\0\u0ce4\0\u0d1b"+ + "\0\u0d52\0\u0d89\0\u0dc0\0\u0df7\0\u0e2e\0\u0e65\0\u0e9c\0\u0ed3"+ + "\0\u0f0a\0\u0f41\0\u0f78\0\u0faf\0\u0fe6\0\u101d\0\u1054\0\u108b"+ + "\0\u10c2\0\u10f9\0\u1130\0\u1167\0\u119e\0\u11d5\0\u120c\0\u1243"+ + "\0\u127a\0\u12b1\0\u12e8\0\u131f\0\u1356\0\u138d\0\u13c4\0\u13fb"+ + "\0\u1432\0\u1469\0\245\0\156\0\156\0\u14a0\0\u14d7\0\u150e"+ + "\0\u1545\0\u157c\0\u15b3\0\156\0\156\0\u15ea\0\u1621\0\156"+ + "\0\156\0\156\0\u1658\0\u168f\0\156\0\u16c6\0\u16fd\0\245"+ + "\0\245\0\u1734\0\u176b\0\u17a2\0\u17d9\0\u1810\0\u1847\0\u187e"+ + "\0\u18b5\0\u18ec\0\u1923\0\u195a\0\u1991\0\u19c8\0\u19ff\0\u1a36"+ + "\0\u1a6d\0\u1aa4\0\245\0\u1adb\0\245\0\245\0\u1b12\0\245"+ + "\0\u1b49\0\u1b80\0\245\0\u1bb7\0\245\0\u1bee\0\u1c25\0\u1c5c"+ + "\0\u1c93\0\u1cca\0\u1d01\0\u1d38\0\u1d6f\0\u1da6\0\u1ddd\0\u1e14"+ + "\0\u1e4b\0\u1e82\0\u1eb9\0\u1ef0\0\u1f27\0\u1f5e\0\u1f95\0\u1fcc"+ + "\0\u2003\0\u203a\0\u2071\0\u20a8\0\u20df\0\u2116\0\u214d\0\245"+ + "\0\u2184\0\u21bb\0\u21f2\0\245\0\u2229\0\u2260\0\245\0\u2297"+ + "\0\u22ce\0\u2305\0\u233c\0\u2373\0\u23aa\0\u23e1\0\u2418\0\u244f"+ + "\0\u2486\0\u24bd\0\u24f4\0\u252b\0\u2562\0\245\0\u2599\0\u25d0"+ + "\0\u2607\0\u263e\0\u2675\0\u26ac\0\u26e3\0\u271a\0\u2751\0\u2788"+ + "\0\245\0\u27bf\0\u27f6\0\245\0\u282d\0\u2864\0\245\0\245"+ + "\0\245\0\u289b\0\u28d2\0\245\0\u2909\0\u2940\0\245\0\245"+ + "\0\u2977\0\245\0\u29ae\0\245\0\u29e5\0\u2a1c\0\u2a53\0\u2a8a"+ + "\0\u2ac1\0\u2af8\0\245\0\u2b2f\0\u2b66\0\u2b9d\0\u2bd4\0\u2c0b"+ + "\0\u2c42\0\u2c79\0\u2cb0\0\u2ce7\0\u2d1e\0\245\0\u2d55\0\u2d8c"+ + "\0\245\0\u2dc3\0\245\0\u2dfa\0\u2e31\0\u2e68\0\u2e9f\0\u2ed6"+ + "\0\u2f0d\0\u2f44\0\245\0\u2f7b\0\u2fb2\0\u2fe9\0\245\0\u3020"+ + "\0\u3057\0\u308e\0\u2486\0\u30c5\0\u30fc\0\u3133\0\u316a\0\u31a1"+ + "\0\u31d8\0\245\0\245\0\u320f\0\u3246\0\u327d\0\u32b4\0\u32eb"+ + "\0\245\0\u3322\0\u3359\0\u3390\0\u33c7\0\u33fe\0\245\0\u3435"+ + "\0\u346c\0\u34a3\0\u34da\0\245\0\u3511\0\u3548\0\u357f\0\245"+ + "\0\u35b6\0\u35ed\0\245\0\u3624\0\u365b\0\245\0\245\0\u3692"+ + "\0\u36c9\0\u3700\0\u3737\0\245\0\u376e\0\u37a5\0\u37dc\0\u3813"+ + "\0\245\0\u384a\0\u3881\0\u38b8\0\u38ef\0\245\0\u3926\0\u395d"+ + "\0\u3994\0\u39cb\0\245\0\245\0\u3a02\0\245\0\u3a39\0\u3a70"+ + "\0\u3aa7\0\u3ade\0\u3b15\0\u3b4c\0\u3b83\0\u3bba\0\u3bf1\0\u3c28"+ + "\0\u3c5f\0\u3c96\0\u3ccd\0\245\0\u3d04\0\u3d3b\0\u3d72\0\245"+ + "\0\u3da9\0\245\0\u3de0\0\u3e17\0\u3e4e\0\u3e85\0\245\0\u3ebc"+ + "\0\245\0\245\0\u3ef3\0\u3f2a\0\u3f61\0\u3f98\0\245\0\245"+ + "\0\156\0\u3fcf\0\u4006\0\245\0\u403d\0\u4074\0\u40ab\0\u40e2"+ + "\0\u4119\0\245\0\u4150\0\u4187\0\u41be\0\u41f5\0\245\0\u422c"+ + "\0\u4263\0\u429a\0\u42d1\0\u4308\0\u433f\0\u4376\0\u43ad\0\u43e4"+ + "\0\156\0\u441b\0\u4452\0\u4489\0\u44c0\0\245\0\245\0\245"+ + "\0\245\0\u44f7\0\245\0\u452e\0\u4565\0\u459c\0\u45d3\0\u460a"+ + "\0\245\0\156\0\245\0\u4641\0\u4678\0\u46af\0\u46e6\0\245"+ + "\0\u471d\0\u4754\0\245\0\u478b\0\u47c2\0\245\0\u47f9\0\u4830"+ + "\0\245\0\u4867\0\u489e\0\156\0\u48d5\0\245\0\u490c\0\u4943"+ + "\0\u497a\0\245\0\u49b1\0\u49e8\0\u4a1f\0\u4a56\0\u4a8d\0\u4ac4"+ + "\0\u4afb\0\u4b32\0\u4b69\0\u4ba0\0\u4bd7\0\u4c0e\0\u4c45\0\u4c7c"+ + "\0\u4cb3\0\u4cea\0\156\0\u4d21\0\u4d58\0\u4d8f\0\u4dc6\0\u4dfd"+ + "\0\u4e34\0\u4e6b\0\u4ea2\0\u4ed9\0\u4f10\0\u4f47\0\u4f7e\0\u4fb5"+ + "\0\156\0\u4fec\0\u5023\0\u505a\0\u5091\0\u50c8\0\156\0\u50ff"+ + "\0\u5136\0\u516d\0\u51a4\0\u51db\0\156\0\u5212\0\u5249\0\u5280"+ + "\0\u52b7\0\u52ee\0\u5325\0\156\0\u535c\0\u5393\0\u53ca\0\156"+ + "\0\u5401\0\u5438\0\u546f\0\u54a6\0\u54dd\0\u5514\0\u554b\0\u5582"+ + "\0\156\0\156\0\u55b9\0\u55f0\0\156"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[509]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\1\0\1\2\2\3\1\4\1\5\1\6\1\7\1\10"+ + "\1\11\1\12\1\13\1\14\1\15\1\16\1\17\1\20"+ + "\1\21\1\22\1\23\1\24\1\25\1\26\1\27\1\30"+ + "\1\31\1\32\1\33\1\34\1\35\1\36\1\37\1\40"+ + "\1\41\1\42\1\43\1\44\1\45\1\46\1\47\1\50"+ + "\1\51\1\52\1\53\1\54\1\4\1\55\1\56\1\4"+ + "\1\57\1\60\1\61\2\4\1\62\2\0\1\3\157\0"+ + "\2\4\1\63\1\0\1\64\22\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\6\0\1\5\1\65"+ + "\65\0\1\65\61\0\7\7\1\66\57\7\10\10\1\66"+ + "\56\10\4\0\2\4\1\63\1\0\1\64\1\4\1\67"+ + "\1\70\2\4\1\71\1\72\1\73\2\4\1\74\1\75"+ + "\1\76\4\4\1\77\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\4\4\1\100\6\4\1\101\6\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\1\102\2\4\1\103\1\104\2\4\1\105"+ + "\10\4\1\106\1\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\2\4\1\107\2\4\1\110\4\4\1\111\1\4\1\112"+ + "\5\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\5\4\1\113"+ + "\1\4\1\114\2\4\1\115\7\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\1\116\3\4\1\117\3\4\1\120\1\121"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\1\122\2\4"+ + "\1\123\1\124\4\4\1\125\10\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\1\126\10\4\1\127\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\14\4\1\130\5\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\1\131\4\4\1\132\1\4\1\133"+ + "\3\4\1\134\6\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\135\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\136\2\4\1\137\1\140\2\4\1\141\12\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\4\4\1\142\4\4\1\143"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\2\4\1\144"+ + "\1\4\1\145\3\4\1\146\1\147\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\7\4\1\150\1\4\1\151\10\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\1\152\3\4\1\153"+ + "\4\4\1\154\10\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\155\2\4\1\156\14\4\1\157\1\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\1\160\21\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\4\4\1\161\4\4\1\162\10\4\10\0"+ + "\1\4\7\0\1\163\2\4\2\0\1\4\3\0\2\4"+ + "\35\0\1\164\110\0\1\165\52\0\1\166\1\0\1\167"+ + "\26\0\2\4\1\63\1\0\1\64\1\170\21\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\11\4\1\171\10\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\7\4\1\172\1\4\1\173"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\57\0\1\174\66\0\1\175\34\0\1\176\27\0"+ + "\1\177\4\0\1\200\63\0\1\201\73\0\1\202\7\0"+ + "\1\203\4\0\22\203\10\0\1\203\7\0\3\203\2\0"+ + "\1\203\3\0\2\203\5\0\1\204\4\0\22\204\10\0"+ + "\1\204\7\0\3\204\2\0\1\204\3\0\2\204\26\0"+ + "\1\205\45\0\2\4\1\63\1\0\1\64\2\4\1\206"+ + "\17\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\2\4\1\207"+ + "\17\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\6\4\1\210"+ + "\13\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\6\4\1\211"+ + "\13\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\7\4\1\212"+ + "\1\4\1\112\10\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\2\4\1\213\17\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\13\4\1\214\6\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\4\1\215\20\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\14\4\1\216\5\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\5\4\1\217\7\4\1\220\4\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\11\4\1\221\10\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\21\4\1\222\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\16\4\1\223\3\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\2\0\3\224\2\4\1\63"+ + "\1\0\1\64\22\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\1\4\1\225\5\0\2\4\1\63\1\0"+ + "\1\64\10\4\1\226\11\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\1\227\2\4\1\230\3\4\1\231\1\4\1\232"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\14\4\1\233"+ + "\5\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\1\4\1\234"+ + "\1\235\17\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\236\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\16\4"+ + "\1\237\3\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\2\4"+ + "\1\240\17\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\13\4"+ + "\1\241\2\4\1\242\3\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\17\4\1\243\2\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\2\4\1\223\17\4\10\0\1\4\7\0\1\244"+ + "\2\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\22\4\10\0\1\245\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\10\4\1\246\1\247\10\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\14\4\1\250\4\4\1\251\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\5\4\1\252\14\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\13\4\1\253\2\4\1\254\3\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\3\4\1\255\16\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\1\4\1\256\5\4\1\257"+ + "\12\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\2\4\1\260"+ + "\3\4\1\261\13\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\7\4\1\262\12\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\14\4\1\263\5\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\10\4\1\264\11\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\13\4\1\265\6\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\7\4\1\266\12\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\7\4\1\267\12\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\4\4\1\270\15\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\4\1\271\3\4\1\272\14\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\5\4\1\273\6\4\1\274\5\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\7\4\1\275\12\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\7\4\1\276\12\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\21\4\1\277\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\2\4\1\300\17\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\3\4\1\301\16\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\7\4\1\302\12\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\2\4\1\303\12\4\1\304\4\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\5\4\1\305\14\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\16\4\1\306\3\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\14\4\1\307\5\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\2\4\1\310\17\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\3\4\1\311\1\312"+ + "\4\4\1\313\10\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\14\4\1\314\5\4\10\0\1\315\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\4\4\1\316\15\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\2\4\1\317\7\4\1\320\7\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\1\0\1\166\2\0"+ + "\64\166\42\167\1\321\1\167\1\322\22\167\4\0\2\4"+ + "\1\63\1\0\1\64\13\4\1\323\6\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\1\324\21\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\11\4\1\325\10\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\2\4\1\326\17\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\14\0\1\60\66\0"+ + "\1\34\57\0\2\203\1\327\2\0\22\203\10\0\1\203"+ + "\7\0\3\203\2\0\1\203\3\0\2\203\5\0\2\204"+ + "\2\0\1\64\22\204\10\0\1\204\7\0\3\204\2\0"+ + "\1\204\3\0\2\204\5\0\2\4\1\63\1\0\1\64"+ + "\3\4\1\330\16\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\7\4\1\331\12\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\332\21\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\333\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\4\4"+ + "\1\334\15\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\335\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\4\4"+ + "\1\336\15\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\2\4"+ + "\1\337\3\4\1\340\13\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\22\4\10\0\1\4\7\0\1\341\2\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\342\21\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\13\4"+ + "\1\343\6\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\344\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\2\0\3\224\26\0\1\345\40\0\2\4"+ + "\1\63\1\0\1\64\11\4\1\346\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\11\4\1\347\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\5\4\1\350\14\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\14\4\1\351\5\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\4\4\1\352\15\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\2\0\3\353"+ + "\2\4\1\63\1\0\1\64\5\4\1\354\1\4\1\355"+ + "\12\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\13\4\1\356"+ + "\6\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\11\4\1\357"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\13\4\1\360"+ + "\6\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\21\4\1\361"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\14\4\1\362\5\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\21\4\1\363\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\14\4\1\364\5\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\1\4\1\365\20\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\10\4\1\366\11\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\6\4\1\367\13\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\1\370\21\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\4\4\1\371\15\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\5\4\1\372\14\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\20\4\1\373\1\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\13\4\1\374\6\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\3\4\1\375\16\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\3\4\1\376\16\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\4\4\1\377\15\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\11\4\1\u0100\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\1\u0101\21\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\14\4\1\226\5\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\14\4\1\u0102\5\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\2\0\3\u0103\2\4"+ + "\1\63\1\0\1\64\1\u0104\10\4\1\u0105\10\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\16\4\1\u0106\3\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\1\u0107\21\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\22\4\10\0\1\4\7\0\1\4"+ + "\1\235\1\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\22\4\10\0\1\4\7\0\1\4"+ + "\1\u0108\1\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\14\4\1\u0109\5\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\3\4\1\u010a\16\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\2\4\1\u010b\17\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\2\4\1\u010c\11\4\1\u010d\5\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\5\4\1\u010e\14\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\12\4\1\u010f\7\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\1\4\1\u0110\20\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\2\4\1\u0111\17\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\21\4\1\u0112\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\20\4\1\u0113\1\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\1\4\1\u0114\11\4\1\u0115"+ + "\6\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\14\4\1\u0115"+ + "\5\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\7\4\1\u0115"+ + "\12\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\2\0\3\u0116\2\4\1\63\1\0\1\64\22\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\11\4\1\u0117\10\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\13\4\1\u0118\6\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\17\4\1\u0119\2\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\4\4\1\u011a\15\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\1\0\44\167\1\0\64\167\1\u011b\1\167\1\322\22\167"+ + "\4\0\2\4\1\63\1\0\1\64\10\4\1\u011c\11\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\7\4\1\u011d\12\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\1\u011e\21\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\5\0"+ + "\1\u011f\4\0\22\u011f\10\0\1\u011f\7\0\3\u011f\2\0"+ + "\1\u011f\3\0\2\u011f\5\0\2\4\1\63\1\0\1\64"+ + "\4\4\1\u0120\15\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\3\4\1\u0121\16\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\22\4\10\0\1\4\7\0\1\u0122\2\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\7\4"+ + "\1\u0123\12\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\17\4"+ + "\1\u0124\2\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\5\4"+ + "\1\u0125\14\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\13\4"+ + "\1\u0126\6\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\u0127\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\3\4"+ + "\1\u0128\16\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\7\4"+ + "\1\u0129\12\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\u012a\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\23\0\1\u012b\50\0\2\4\1\63\1\0"+ + "\1\64\5\4\1\u012c\14\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\10\4\1\u012d\11\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\2\0\3\353\12\0\1\u012e"+ + "\54\0\2\4\1\63\1\0\1\64\11\4\1\u012f\10\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\10\4\1\u0130\11\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\11\4\1\u0131\10\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\13\4\1\u0132\6\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\11\4\1\u0133\10\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\22\4\10\0\1\4"+ + "\7\0\1\4\1\u0134\1\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\4\4\1\u0135\15\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\2\4\1\u0136\17\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\22\4\10\0\1\u0137"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\22\4\10\0\1\4\7\0\1\4"+ + "\1\u0138\1\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\3\4\1\u0139\16\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\2\4\1\u013a\17\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\12\4\1\u013b\7\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\7\4\1\u013c\12\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\2\0\3\u013d"+ + "\2\4\1\63\1\0\1\64\22\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\13\4\1\u013e\6\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\2\4\1\u013f\17\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\2\0\3\u0103\5\0"+ + "\1\u0140\10\0\1\u0141\50\0\2\4\1\63\1\0\1\64"+ + "\13\4\1\u0142\6\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\u0143\21\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\13\4"+ + "\1\u0144\6\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\2\4"+ + "\1\u0145\17\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\5\4"+ + "\1\u0146\14\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\7\4"+ + "\1\u0147\12\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\2\4"+ + "\1\u0148\17\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\2\4"+ + "\1\u0149\17\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\4\4"+ + "\1\u014a\15\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\20\4"+ + "\1\u014b\1\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\20\4"+ + "\1\u014c\1\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\u014d\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\20\4"+ + "\1\u014e\1\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\u014e\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\2\0\3\u0116\5\0\1\u014f\61\0\2\4"+ + "\1\63\1\0\1\64\11\4\1\u0150\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\11\4\1\u0151\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\7\4\1\u0152\12\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\11\4\1\u0153\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\14\4\1\u0154\5\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\2\4\1\u0155\17\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\u011f"+ + "\3\0\22\u011f\10\0\1\u011f\7\0\3\u011f\2\0\1\u011f"+ + "\3\0\2\u011f\5\0\2\4\1\63\1\0\1\64\5\4"+ + "\1\u0156\14\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\21\4"+ + "\1\u0157\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\3\4\1\u0158"+ + "\16\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\6\4\1\u0159"+ + "\13\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\10\4\1\u015a"+ + "\11\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\22\4\10\0"+ + "\1\4\7\0\2\4\1\u015b\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\2\4\1\u015c\17\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\2\0\3\u015d\2\4\1\63\1\0\1\64\22\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\2\0"+ + "\3\u015e\67\0\2\4\1\63\1\0\1\64\3\4\1\u015f"+ + "\16\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\22\4\10\0"+ + "\1\4\7\0\1\4\1\u0160\1\4\2\0\1\4\3\0"+ + "\2\4\12\0\1\u0161\61\0\2\4\1\63\1\0\1\64"+ + "\6\4\1\u0162\13\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\7\4\1\u0163\12\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\11\4\1\u0164\10\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\5\4\1\u0165\14\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\16\4\1\u0166\3\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\3\4\1\u0167\16\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\11\4\1\u0168\10\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\11\4\1\u0169\10\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\22\4\10\0\1\4\7\0\1\u016a\2\4\2\0\1\4"+ + "\3\0\2\4\2\0\3\u016b\2\4\1\63\1\0\1\64"+ + "\22\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\2\0\3\u013d\10\0\1\u016c\76\0\1\u016d\53\0"+ + "\1\u016e\61\0\2\4\1\63\1\0\1\64\13\4\1\u016f"+ + "\6\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\1\4\1\u0170"+ + "\20\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\20\4\1\u0171"+ + "\1\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\22\4\10\0"+ + "\1\4\7\0\1\4\1\u0172\1\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\1\u0173\21\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\7\4\1\u0174\12\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\7\4\1\u0175\12\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\11\4\1\u0176\10\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\14\4\1\u0177\5\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\7\4\1\u0178\12\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\17\0\1\u0179\54\0\2\4\1\63\1\0\1\64\1\u017a"+ + "\21\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\11\4\1\u017b"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\11\4\1\u017c"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\11\4\1\u017d"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\10\4\1\u017e"+ + "\11\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\5\4\1\u017f"+ + "\14\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\3\4\1\u0180"+ + "\16\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\2\4\1\u0181"+ + "\17\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\2\4\1\u0182"+ + "\17\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\3\4\1\u0183"+ + "\16\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\2\0\3\u015d\10\0\1\u0184\53\0\3\u015e\14\0"+ + "\1\u0185\52\0\2\4\1\63\1\0\1\64\22\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\1\u0186\1\4"+ + "\5\0\2\4\1\63\1\0\1\64\20\4\1\u0187\1\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\30\0\1\u0188\43\0\2\4\1\63\1\0\1\64\11\4"+ + "\1\u0189\10\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\2\0\3\u018a\2\4\1\63\1\0\1\64"+ + "\22\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\6\4\1\u018b"+ + "\13\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\3\4\1\u018c"+ + "\16\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\4\4\1\u018d"+ + "\15\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\14\4\1\u018e"+ + "\5\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\2\0\3\u016b\6\0\1\u018f\77\0\1\u0190\67\0"+ + "\1\u0191\54\0\1\u0192\60\0\2\4\1\63\1\0\1\64"+ + "\20\4\1\u016f\1\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\1\4\1\u0193\20\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\3\4\1\u0194\16\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\16\4\1\u0195\3\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\14\4\1\u0196\5\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\5\4\1\u0197\14\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\5\4\1\u0198\14\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\7\4\1\u0199\12\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\2\4\1\u019a\17\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\22\4\10\0\1\4\7\0\1\4\1\u019b\1\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\5\4\1\u019c\14\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\11\4\1\u019d\10\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\5\0\2\4\1\63\1\0\1\64"+ + "\4\4\1\u019e\15\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\2\4\17\0\1\u019f\72\0\1\u01a0\50\0"+ + "\2\4\1\63\1\0\1\64\11\4\1\u01a1\10\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\23\0"+ + "\1\u01a2\50\0\2\4\1\63\1\0\1\64\14\4\1\u01a3"+ + "\5\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\2\0\3\u018a\11\0\1\u01a4\55\0\2\4\1\63"+ + "\1\0\1\64\3\4\1\u01a5\16\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\5\0\2\4\1\63"+ + "\1\0\1\64\22\4\10\0\1\4\7\0\3\4\2\0"+ + "\1\4\3\0\1\u01a6\1\4\5\0\2\4\1\63\1\0"+ + "\1\64\5\4\1\u01a7\14\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\5\0\2\4\1\63\1\0"+ + "\1\64\2\4\1\u01a8\17\4\10\0\1\4\7\0\3\4"+ + "\2\0\1\4\3\0\2\4\16\0\1\u01a9\52\0\3\u01aa"+ + "\114\0\1\u0191\41\0\2\4\1\63\1\0\1\64\2\4"+ + "\1\u01ab\17\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\5\0\2\4\1\63\1\0\1\64\5\4"+ + "\1\u01ac\14\4\10\0\1\4\7\0\3\4\2\0\1\4"+ + "\3\0\2\4\2\0\3\u01ad\2\4\1\63\1\0\1\64"+ + "\22\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\11\4\1\u01ae"+ + "\10\4\10\0\1\4\7\0\3\4\2\0\1\4\3\0"+ + "\2\4\5\0\2\4\1\63\1\0\1\64\22\4\10\0"+ + "\1\4\7\0\1\4\1\u01af\1\4\2\0\1\4\3\0"+ + "\2\4\2\0\3\u01b0\2\4\1\63\1\0\1\64\22\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\5\0\2\4\1\63\1\0\1\64\5\4\1\u01b1\14\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\24\0\1\u01b2\72\0\1\u01b3\62\0\1\u01b4\47\0\2\4"+ + "\1\63\1\0\1\64\5\4\1\u01b5\14\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\11\4\1\u01b6\10\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\14\4\1\u01b7\5\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\20\0\1\u01b8"+ + "\50\0\3\u01aa\12\0\1\u01b9\54\0\2\4\1\63\1\0"+ + "\1\64\22\4\10\0\1\4\7\0\1\4\1\u01ba\1\4"+ + "\2\0\1\4\3\0\2\4\2\0\3\u01ad\24\0\1\u01bb"+ + "\37\0\3\u01bc\2\4\1\63\1\0\1\64\22\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\2\0"+ + "\3\u01b0\37\0\1\u01bd\40\0\1\u01be\66\0\1\u01bf\55\0"+ + "\2\4\1\63\1\0\1\64\22\4\10\0\1\4\7\0"+ + "\1\4\1\u01c0\1\4\2\0\1\4\3\0\2\4\5\0"+ + "\2\4\1\63\1\0\1\64\20\4\1\u01c1\1\4\10\0"+ + "\1\4\7\0\3\4\2\0\1\4\3\0\2\4\23\0"+ + "\1\u01c2\61\0\1\u01c3\102\0\1\u01c4\36\0\3\u01bc\11\0"+ + "\1\u01c5\62\0\1\u01c6\75\0\1\u01c7\111\0\1\u01c8\24\0"+ + "\3\u01c9\2\4\1\63\1\0\1\64\22\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\5\0\2\4"+ + "\1\63\1\0\1\64\3\4\1\u01ca\16\4\10\0\1\4"+ + "\7\0\3\4\2\0\1\4\3\0\2\4\26\0\1\u01cb"+ + "\57\0\1\u01cc\72\0\1\u01cd\64\0\1\u01ce\72\0\1\u01cf"+ + "\71\0\1\u01d0\61\0\1\u01d1\45\0\3\u01c9\11\0\1\u01d2"+ + "\55\0\2\4\1\63\1\0\1\64\15\4\1\u01d3\4\4"+ + "\10\0\1\4\7\0\3\4\2\0\1\4\3\0\2\4"+ + "\23\0\1\u01d4\62\0\1\u01d5\67\0\1\u01d6\70\0\1\u01d7"+ + "\56\0\1\u01d8\74\0\1\u01d9\67\0\1\u01da\47\0\3\u01db"+ + "\2\4\1\63\1\0\1\64\22\4\10\0\1\4\7\0"+ + "\3\4\2\0\1\4\3\0\2\4\2\0\3\u01dc\64\0"+ + "\3\u01dd\105\0\1\u01de\66\0\1\u01df\57\0\1\u01e0\72\0"+ + "\1\u01e1\50\0\3\u01db\26\0\1\u01e2\35\0\3\u01dc\5\0"+ + "\1\u01e3\56\0\3\u01dd\6\0\1\u01e4\74\0\1\u01e5\62\0"+ + "\1\u01e6\74\0\1\u01e7\66\0\1\u01e8\64\0\1\u01e9\57\0"+ + "\1\u01ea\72\0\1\u01eb\71\0\1\u01ec\61\0\1\u01ed\75\0"+ + "\1\u01ee\70\0\1\u01ef\60\0\1\u01f0\100\0\1\u01f1\37\0"+ + "\3\u01f2\107\0\1\u01f3\64\0\1\u01f4\45\0\3\u01f2\17\0"+ + "\1\u01f5\65\0\1\u01f6\66\0\1\u01f7\61\0\1\u01f8\70\0"+ + "\1\u01f9\65\0\1\u01fa\71\0\1\u01fb\63\0\1\u01fc\67\0"+ + "\1\u01fd\47\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[22055]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\1\0\1\1\1\11\2\1\3\0\24\1\5\11\2\1"+ + "\7\11\3\1\2\0\1\1\4\0\1\1\1\11\75\1"+ + "\2\11\1\1\1\0\4\1\2\11\2\0\3\11\2\1"+ + "\1\11\16\1\1\0\74\1\2\0\4\1\1\0\15\1"+ + "\1\0\5\1\1\0\27\1\1\0\22\1\1\0\24\1"+ + "\1\0\2\1\1\0\16\1\1\0\2\1\2\0\33\1"+ + "\2\0\2\1\1\0\11\1\4\0\12\1\1\11\12\1"+ + "\2\0\2\1\1\0\1\1\1\0\4\1\1\0\1\1"+ + "\1\11\1\0\14\1\2\0\1\1\1\11\1\1\1\0"+ + "\4\1\2\0\2\1\1\0\2\1\1\0\1\1\2\0"+ + "\1\11\3\1\2\0\1\1\1\0\1\1\3\0\3\1"+ + "\6\0\2\1\1\11\7\0\1\1\5\0\1\11\5\0"+ + "\1\11\5\0\1\11\6\0\1\11\3\0\1\11\10\0"+ + "\2\11\2\0\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[509]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the input device */ + private java.io.Reader zzReader; + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** number of newlines encountered up to the start of the matched text */ + private int yyline; + + /** the number of characters up to the start of the matched text */ + private int yychar; + + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /* user code: */ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + Symbol build(int code) { + return new Symbol(code,yytext()); + } + + /** Accessor for yyline **/ + int linenumber () { return yyline; } + + /** Accessor for yychar **/ + int charnumber () { return yychar; } + + + + /** + * Creates a new scanner + * There is also a java.io.InputStream version of this constructor. + * + * @param in the java.io.Reader to read input from. + */ + public DTRulesscanner(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + public DTRulesscanner(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzPushbackPos-= zzStartRead; + zzStartRead = 0; + } + + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length) { + /* if not: blow it up */ + char newBuffer[] = new char[zzCurrentPos*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + } + + /* finally: fill the buffer with new input */ + int numRead = zzReader.read(zzBuffer, zzEndRead, + zzBuffer.length-zzEndRead); + + if (numRead < 0) { + return true; + } + else { + zzEndRead+= numRead; + return false; + } + } + + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ + + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = zzPushbackPos = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() throws java.io.IOException { + if (!zzEOFDone) { + zzEOFDone = true; + yyclose(); + } + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public java_cup.runtime.Symbol next_token() throws java.io.IOException, RulesException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + yychar+= zzMarkedPosL-zzStartRead; + + boolean zzR = false; + for (zzCurrentPosL = zzStartRead; zzCurrentPosL < zzMarkedPosL; + zzCurrentPosL++) { + switch (zzBufferL[zzCurrentPosL]) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + zzR = false; + break; + case '\r': + yyline++; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + } + break; + default: + zzR = false; + } + } + + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + } + if (zzPeek) yyline--; + } + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = zzLexicalState; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = zzBufferL[zzCurrentPosL++]; + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = zzBufferL[zzCurrentPosL++]; + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 97: + { return build(sym.INCLUDE); + } + case 123: break; + case 55: + { return build(sym.DATE); + } + case 124: break; + case 7: + { return build(sym.COLON); + } + case 125: break; + case 92: + { return build(sym.LENGTH); + } + case 126: break; + case 30: + { return build(sym.NO); + } + case 127: break; + case 70: + { return build(sym.ARRAY); + } + case 128: break; + case 110: + { return build(sym.ATTRIBUTE); + } + case 129: break; + case 11: + { return build(sym.DIVIDE); + } + case 130: break; + case 44: + { return build(sym.ONE); + } + case 131: break; + case 109: + { return build(sym.SUBTRACT); + } + case 132: break; + case 65: + { return build(sym.LESS); + } + case 133: break; + case 84: + { return build(sym.WHERE); + } + case 134: break; + case 39: + { return build(sym.POSSESSIVE); + } + case 135: break; + case 63: + { return build(sym.ELSE); + } + case 136: break; + case 56: + { return build(sym.RBOOLEAN); + } + case 137: break; + case 27: + { return build(sym.ON); + } + case 138: break; + case 77: + { return build(sym.ENDIF); + } + case 139: break; + case 71: + { return build(sym.AFTER); + } + case 140: break; + case 14: + { return build(sym.RPAREN); + } + case 141: break; + case 76: + { return build(sym.USING); + } + case 142: break; + case 3: + { return build(sym.INTEGER); + } + case 143: break; + case 96: + { return build(sym.THROUGH); + } + case 144: break; + case 25: + { return build(sym.IF); + } + case 145: break; + case 23: + { return build(sym.TO); + } + case 146: break; + case 90: + { return build(sym.ENTITY); + } + case 147: break; + case 8: + { return build(sym.COMMA); + } + case 148: break; + case 66: + { return build(sym.SORT); + } + case 149: break; + case 114: + { return build(sym.SUBSTRING); + } + case 150: break; + case 120: + { return build(sym.TABLEINFORMATION); + } + case 151: break; + case 19: + { return build(sym.ASSIGN); + } + case 152: break; + case 106: + { return build(sym.THENAME); + } + case 153: break; + case 89: + { return build(sym.REMOVE); + } + case 154: break; + case 6: + { return build(sym.SEMI); + } + case 155: break; + case 13: + { return build(sym.LPAREN); + } + case 156: break; + case 118: + { return build(sym.TOBEREMOVED); + } + case 157: break; + case 81: + { return build(sym.MAXPRINT); + } + case 158: break; + case 29: + { return build(sym.OF); + } + case 159: break; + case 9: + { return build(sym.QUESTIONMARK); + } + case 160: break; + case 98: + { return build(sym.ELSEIF); + } + case 161: break; + case 79: + { return build(sym.FIRST); + } + case 162: break; + case 49: + { return build(sym.FOR); + } + case 163: break; + case 112: + { return build(sym.NUMBEROF); + } + case 164: break; + case 121: + { return build(sym.RELATIONSHIP_BETWEEN); + } + case 165: break; + case 72: + { return build(sym.CLEAR); + } + case 166: break; + case 2: + { return build(sym.IDENT); + } + case 167: break; + case 60: + { return build(sym.NULL); + } + case 168: break; + case 113: + { return build(sym.RANDOMIZE); + } + case 169: break; + case 88: + { return build(sym.DOUBLE); + } + case 170: break; + case 67: + { return build(sym.WITH); + } + case 171: break; + case 31: + { return build(sym.BY); + } + case 172: break; + case 107: + { return build(sym.INCLUDES); + } + case 173: break; + case 38: + { return build(sym.NAME); + } + case 174: break; + case 87: + { return build(sym.ACTION); + } + case 175: break; + case 41: + { return build(sym.ALL); + } + case 176: break; + case 100: + { return build(sym.MATCHES); + } + case 177: break; + case 10: + { return build(sym.PLUS); + } + case 178: break; + case 43: + { return build(sym.LONG); + } + case 179: break; + case 82: + { return build(sym.MATCH); + } + case 180: break; + case 46: + { return build(sym.NEW); + } + case 181: break; + case 57: + { return build(sym.THAN); + } + case 182: break; + case 122: + { return build(sym.ELSEIFNONEAREFOUND); + } + case 183: break; + case 12: + { return build(sym.TIMES); + } + case 184: break; + case 111: + { return build(sym.CONDITION); + } + case 185: break; + case 40: + { return build(sym.ADD); + } + case 186: break; + case 32: + { return build(sym.ARROW); + } + case 187: break; + case 116: + { return build(sym.ERRORCODE); + } + case 188: break; + case 18: + { return build(sym.RCURLY); + } + case 189: break; + case 58: + { return build(sym.THIS); + } + case 190: break; + case 54: + { return build(sym.COPY); + } + case 191: break; + case 108: + { return build(sym.EARLIEST); + } + case 192: break; + case 69: + { return build(sym.YEARS); + } + case 193: break; + case 59: + { return build(sym.THEN); + } + case 194: break; + case 61: + { return build(sym.DOES); + } + case 195: break; + case 117: + { return build(sym.DESCENDINGORDER); + } + case 196: break; + case 93: + { return build(sym.MEMBER); + } + case 197: break; + case 115: + { return build(sym.ASCENDINGORDER); + } + case 198: break; + case 119: + { return build(sym.ABSOLUTEVALUE); + } + case 199: break; + case 74: + { return build(sym.THERE); + } + case 200: break; + case 17: + { return build(sym.LCURLY); + } + case 201: break; + case 75: + { return build(sym.DEBUG); + } + case 202: break; + case 50: + { return build(sym.SET); + } + case 203: break; + case 105: + { return build(sym.TOKENIZE); + } + case 204: break; + case 83: + { return build(sym.MONTHS); + } + case 205: break; + case 35: + { return build(sym.NEQ); + } + case 206: break; + case 94: + { return build(sym.BEFORE); + } + case 207: break; + case 103: + { return build(sym.GREATER); + } + case 208: break; + case 62: + { return build(sym.EACH); + } + case 209: break; + case 101: + { return build(sym.BOOLEAN); + } + case 210: break; + case 5: + { return build(sym.GT); + } + case 211: break; + case 68: + { return build(sym.HAVE); + } + case 212: break; + case 33: + { return build(sym.GTE); + } + case 213: break; + case 47: + { return build(sym.DAYS); + } + case 214: break; + case 99: + { return build(sym.PERFORM); + } + case 215: break; + case 36: + { return build(sym.AND); + } + case 216: break; + case 22: + { return build(sym.STRING); + } + case 217: break; + case 34: + { return build(sym.EQ); + } + case 218: break; + case 16: + { return build(sym.RBRACE); + } + case 219: break; + case 51: + { return build(sym.MAP); + } + case 220: break; + case 85: + { return build(sym.HASA); + } + case 221: break; + case 64: + { return build(sym.FROM); + } + case 222: break; + case 52: + { return build(sym.WAS); + } + case 223: break; + case 37: + { return build(sym.LTE); + } + case 224: break; + case 26: + { return build(sym.IS); + } + case 225: break; + case 80: + { return build(sym.LOCAL); + } + case 226: break; + case 91: + { return build(sym.FORALL); + } + case 227: break; + case 45: + { return build(sym.NOT); + } + case 228: break; + case 20: + { return build(sym.LT); + } + case 229: break; + case 53: + { return build(sym.GET); + } + case 230: break; + case 86: + { return build(sym.VALUE); + } + case 231: break; + case 104: + { return build(sym.ALLOWING); + } + case 232: break; + case 73: + { return build(sym.TABLE); + } + case 233: break; + case 42: + { return build(sym.ITS); + } + case 234: break; + case 21: + { return build(sym.FLOAT); + } + case 235: break; + case 24: + { return build(sym.IN); + } + case 236: break; + case 102: + { return build(sym.BETWEEN); + } + case 237: break; + case 4: + { return build(sym.MINUS); + } + case 238: break; + case 15: + { return build(sym.LBRACE); + } + case 239: break; + case 95: + { return build(sym.CONTEXT); + } + case 240: break; + case 78: + { return build(sym.EQUAL); + } + case 241: break; + case 28: + { return build(sym.OR); + } + case 242: break; + case 48: + { return build(sym.END); + } + case 243: break; + case 1: + { + } + case 244: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + { return new java_cup.runtime.Symbol(sym.EOF); } + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/DTScanner/src/main/java/com/dtrules/compiler/cup/scanner.flex b/DTScanner/src/main/java/com/dtrules/compiler/cup/scanner.flex new file mode 100644 index 0000000..5421a60 --- /dev/null +++ b/DTScanner/src/main/java/com/dtrules/compiler/cup/scanner.flex @@ -0,0 +1,240 @@ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.dtrules.compiler.cup; +import java.util.*; +import java.io.*; +import java_cup.runtime.*; +import com.dtrules.infrastructure.RulesException; +@SuppressWarnings({"unchecked","unused"}) +%% +%public +%class DTRulesscanner +%yylexthrow RulesException +%line +%char +%cup +%ignorecase + +%{ +/* + * Copyright 2004-2008 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + Symbol build(int code) { + return new Symbol(code,yytext()); + } + + /** Accessor for yyline **/ + int linenumber () { return yyline; } + + /** Accessor for yychar **/ + int charnumber () { return yychar; } + +%} + +EOL = \r|\n|\r\n +Whitespace = {EOL}|[ \t\f] +ws = {Whitespace} +Char = [a-z]|[A-Z] +digit = [0-9] +integer = {digit}+ +float = ({digit}+"."{digit}*)|({digit}*"."{digit}+) +Ident = ({Char}|"_")({Char}|{digit}|"_")* +Identifier = ({Ident}".")?{Ident} +stringdbl = ("\""[^\"]*"\"") +stringsgl = ("'"[^']*"'") +string = {stringdbl}|{stringsgl} + +%% + + { + + + "action" {return build(sym.ACTION); } + "condition" {return build(sym.CONDITION); } + + "true" {return build(sym.RBOOLEAN); } + "false" {return build(sym.RBOOLEAN); } + + "perform"{ws}+"when"{ws}+"called" + {return build(sym.RBOOLEAN); } + + {integer} {return build(sym.INTEGER); } + {float} {return build(sym.FLOAT); } + {string} {return build(sym.STRING); } + {Whitespace} {} + + "date" {return build(sym.DATE); } + "time" {return build(sym.DATE); } + "boolean" {return build(sym.BOOLEAN);} + "double" {return build(sym.DOUBLE); } + "->" {return build(sym.ARROW); } + ";" {return build(sym.SEMI); } + ":" {return build(sym.COLON); } + "," {return build(sym.COMMA); } + "?" {return build(sym.QUESTIONMARK); } + "+" {return build(sym.PLUS); } + "-" {return build(sym.MINUS); } + "/" {return build(sym.DIVIDE); } + "div" {return build(sym.DIVIDE); } + "*" {return build(sym.TIMES); } + "(" {return build(sym.LPAREN); } + ")" {return build(sym.RPAREN); } + "[" {return build(sym.LBRACE); } + "]" {return build(sym.RBRACE); } + "{" {return build(sym.LCURLY); } + "}" {return build(sym.RCURLY); } + "set" {return build(sym.SET); } + "end" {return build(sym.END); } + "add" {return build(sym.ADD); } + "subtract" {return build(sym.SUBTRACT); } + "remove" {return build(sym.REMOVE); } + "from" {return build(sym.FROM); } + "array" {return build(sym.ARRAY); } + "include" {return build(sym.INCLUDE); } + "includes" {return build(sym.INCLUDES); } + "attribute" {return build(sym.ATTRIBUTE); } + "value" {return build(sym.VALUE); } + "string" {return build(sym.STRING); } + "name" {return build(sym.NAME); } + "local" {return build(sym.LOCAL); } + "substring" {return build(sym.SUBSTRING); } + "member" {return build(sym.MEMBER); } + "this" {return build(sym.THIS); } + "context" {return build(sym.CONTEXT); } + "for"{ws}*"all" {return build(sym.FORALL); } + "for"{ws}*"each" {return build(sym.FORALL); } + "each" {return build(sym.EACH); } + "int" {return build(sym.LONG); } + "long" {return build(sym.LONG); } + "all" {return build(sym.ALL); } + "perform" {return build(sym.PERFORM); } + "in" {return build(sym.IN); } + "==" {return build(sym.EQ); } + "!=" {return build(sym.NEQ); } + "=" {return build(sym.ASSIGN); } + "equal" {return build(sym.EQUAL); } + "to" {return build(sym.TO); } + "is" {return build(sym.IS); } + "are" {return build(sym.IS); } + "its" {return build(sym.ITS); } + "greater" {return build(sym.GREATER); } + "less" {return build(sym.LESS); } + "than" {return build(sym.THAN); } + ">"|">" {return build(sym.GT); } + "<"|"<" {return build(sym.LT); } + ">="|">=" {return build(sym.GTE); } + "<="|"<=" {return build(sym.LTE); } + "and" {return build(sym.AND); } + "&&" {return build(sym.AND); } + "or" {return build(sym.OR); } + "||" {return build(sym.OR); } + "not" {return build(sym.NOT); } + "no" {return build(sym.NO); } + "if" {return build(sym.IF); } + "then" {return build(sym.THEN); } + "endif" {return build(sym.ENDIF); } + "else" {return build(sym.ELSE); } + "first" {return build(sym.FIRST); } + "of" {return build(sym.OF); } + "on" {return build(sym.ON); } + "using" {return build(sym.USING); } + "copy" {return build(sym.COPY); } + "get" {return build(sym.GET); } + "sort" {return build(sym.SORT); } + "by" {return build(sym.BY); } + "new" {return build(sym.NEW); } + "earliest" {return build(sym.EARLIEST); } + "entity" {return build(sym.ENTITY); } + "debug" {return build(sym.DEBUG); } + "clear" {return build(sym.CLEAR); } + "for" {return build(sym.FOR); } + "randomize" {return build(sym.RANDOMIZE); } + "was" {return build(sym.WAS); } + "one" {return build(sym.ONE); } + "does" {return build(sym.DOES); } + "day"("s")? {return build(sym.DAYS); } + "null" {return build(sym.NULL); } + "between" {return build(sym.BETWEEN); } + "before" {return build(sym.BEFORE); } + "after" {return build(sym.AFTER); } + "length" {return build(sym.LENGTH); } + "there" {return build(sym.THERE); } + "number"{ws}+"of" {return build(sym.NUMBEROF); } + "the"{ws}+"name" {return build(sym.THENAME); } + "relationship"{ws}+"between" + {return build(sym.RELATIONSHIP_BETWEEN); } + "allowing" {return build(sym.ALLOWING); } + "table" {return build(sym.TABLE); } + "have" {return build(sym.HAVE); } + "year"("s")? {return build(sym.YEARS); } + "month"("s")? {return build(sym.MONTHS); } + "tokenize" {return build(sym.TOKENIZE); } + "to"{ws}+"be"{ws}+"removed" + {return build(sym.TOBEREMOVED); } + "table"{ws}+"information" + {return build(sym.TABLEINFORMATION); } + "with" {return build(sym.WITH); } + "match" {return build(sym.MATCH); } + "matches" {return build(sym.MATCHES); } + + "error"{ws}+"code"("s")? {return build(sym.ERRORCODE); } + "absolute"{ws}+"value" {return build(sym.ABSOLUTEVALUE); } + "else"{ws}+"if"{ws}+"none"{ws}+"are"{ws}+"found" + {return build(sym.ELSEIFNONEAREFOUND); } + "has"{ws}+("a"|"an") {return build(sym.HASA); } + "descending"{ws}+"order"? {return build(sym.DESCENDINGORDER); } + "ascending"{ws}+"order"? {return build(sym.ASCENDINGORDER); } + "else"{ws}+"if" {return build(sym.ELSEIF); } + "where"|"whose"|"which"|"while" {return build(sym.WHERE); } + "map" {return build(sym.MAP); } + "through" {return build(sym.THROUGH); } + + /*** + *** MAXIMUS example tokens + *** + ***/ + + "print" {return build(sym.MAXPRINT); } + + + + "//"[^\r\n]* { } // // comments + "/*"([^/]|("/"[^*]))*"*/" { } // /* ... */ comments + + "a"|"an"|"the" { } /* Just ignore articles so you can put them anywhere you like */ + {Identifier}"'s" { return build(sym.POSSESSIVE); } + "$"{Identifier} { return build(sym.NAME); } + {Identifier} { return build(sym.IDENT); } + +} + + + + + \ No newline at end of file diff --git a/ExcelUtil/.classpath b/ExcelUtil/.classpath new file mode 100644 index 0000000..55c5dbb --- /dev/null +++ b/ExcelUtil/.classpath @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/ExcelUtil/.project b/ExcelUtil/.project new file mode 100644 index 0000000..948a68c --- /dev/null +++ b/ExcelUtil/.project @@ -0,0 +1,18 @@ + + ExcelUtil + SDC Parent POM + + DSLCompiler + DTRules + DTParser + DTScanner + + + + org.eclipse.jdt.core.javabuilder + + + + org.eclipse.jdt.core.javanature + + \ No newline at end of file diff --git a/ExcelUtil/.settings/org.eclipse.jdt.core.prefs b/ExcelUtil/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..6481952 --- /dev/null +++ b/ExcelUtil/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,5 @@ +#Thu May 15 12:54:27 CDT 2008 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.source=1.5 +org.eclipse.jdt.core.compiler.compliance=1.5 diff --git a/ExcelUtil/src/main/java/excel/util/Excel2XML.java b/ExcelUtil/src/main/java/excel/util/Excel2XML.java new file mode 100644 index 0000000..d97127a --- /dev/null +++ b/ExcelUtil/src/main/java/excel/util/Excel2XML.java @@ -0,0 +1,212 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package excel.util; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.nio.channels.FileChannel; +import java.util.Iterator; +import java.util.List; + +import com.dtrules.compiler.cup.Compiler; +import com.dtrules.compiler.decisiontables.DTCompiler; +import com.dtrules.decisiontables.RDecisionTable; +import com.dtrules.decisiontables.DTNode.Coordinate; +import com.dtrules.entity.IREntity; +import com.dtrules.infrastructure.RulesException; +import com.dtrules.interpreter.RName; +import com.dtrules.mapping.MapGenerator; +import com.dtrules.session.EntityFactory; +import com.dtrules.session.ICompiler; +import com.dtrules.session.ICompilerError; +import com.dtrules.session.IRSession; +import com.dtrules.session.RSession; +import com.dtrules.session.RuleSet; +import com.dtrules.session.RulesDirectory; + +public class Excel2XML { + + private RuleSet ruleSet; + private final String UDTFilename = "Uncompiled_DecisionTables.xml"; + String path; + String rulesDirectoryXML; + String ruleset; + DTCompiler dtcompiler = null; + + /** + * Returns the ruleSet being used by this compiler + * @return + */ + public RuleSet getRuleSet() { + return ruleSet; + } + + /** + * We assume that the Rule Set provided gives us all the parameters needed + * to open a set of Excel Files and convert them into XML files. + * @param propertyfile + */ + public Excel2XML(RuleSet ruleSet) { + this.ruleSet = ruleSet; + } + + /** + * Opens the RulesDirectory for the caller. + * @param rulesDirectoryXML + * @param ruleset + */ + public Excel2XML(String path, String rulesDirectoryXML, String ruleset){ + this.path = path; + this.rulesDirectoryXML = rulesDirectoryXML; + this.ruleset = ruleset; + reset(); + } + + /** + * We reset the Rules Directory after we have modified the XML used to + * define the Rules Directory. + */ + public void reset (){ + RulesDirectory rd = new RulesDirectory(path,rulesDirectoryXML); + this.ruleSet = rd.getRuleSet(ruleset); + } + + /** + * Return the Last DecisionTable Compiler used. Null if none exists. + * + * @return Return the Last DecisionTable Compiler used. + */ + public DTCompiler getDTCompiler(){ + return dtcompiler; + } + /** + * Converts the RuleSet + * @throws Exception + */ + public void convertRuleset() throws Exception { + ImportRuleSets dt = new ImportRuleSets(); + dt.convertEDD (ruleSet.getSystemPath()+"/"+ruleSet.getExcel_edd(), ruleSet.getFilepath()+ruleSet.getEDD_XMLName()); + dt.convertDecisionTables(ruleSet.getSystemPath()+"/"+ruleSet.getExcel_dtfolder(),ruleSet.getFilepath()+UDTFilename); + copyFile(ruleSet.getFilepath()+UDTFilename,ruleSet.getFilepath()+ruleSet.getDT_XMLName()); + reset(); + } + + /** + * Copy a file + * Throws a runtime exception if anything goes wrong. + */ + public static void copyFile(String file1, String file2) { + FileChannel inChannel = null; + FileChannel outChannel = null; + try{ + inChannel = new FileInputStream(file1).getChannel(); + outChannel = new FileOutputStream(file2).getChannel(); + try { + // Stupid fix for Windows -- 64Mb - 1024 bytes to avoid a bug. + int blksize = (64 * 1024 * 1024)-1024; + long size = inChannel.size(); + long position = 0; + while (position < size) { + position += inChannel.transferTo(position, blksize, outChannel); + } + inChannel.close(); + outChannel.close(); + } catch (IOException e) { + throw new RuntimeException(e.getMessage()); + } + }catch(FileNotFoundException e) { + throw new RuntimeException(e); + } + } + + /** + * Compiles the RuleSet + * @param NumErrorsToReport How many errors to print + * @param err The output stream which to print the errors + */ + public void compile(int NumErrorsToReport, PrintStream err) { + + try { + IRSession session = new RSession(ruleSet); + Compiler compiler = new Compiler(session); + dtcompiler = new DTCompiler(compiler); + + InputStream inDTStream = new FileInputStream(ruleSet.getFilepath()+"/"+UDTFilename); + OutputStream outDTStream = new FileOutputStream(ruleSet.getFilepath()+"/"+ruleSet.getDT_XMLName()); + + dtcompiler.compile(inDTStream, outDTStream); + + RulesDirectory rd = new RulesDirectory(path, rulesDirectoryXML); + RuleSet rs = rd.getRuleSet(RName.getRName(ruleset)); + EntityFactory ef = rs.newSession().getEntityFactory(); + IREntity dt = ef.getDecisiontables(); + Iterator idt = ef.getDecisionTableRNameIterator(); + + while(idt.hasNext()){ + RDecisionTable t = (RDecisionTable) dt.get(idt.next()); + List errs = t.compile(); + Coordinate err_RowCol = t.validate(); + if(!t.isCompiled() || err_RowCol!=null){ + int column = 0; + int row = 0; + if(err_RowCol!=null){ + row = err_RowCol.getRow(); + column = err_RowCol.getCol(); + } + dtcompiler.logError( + t.getName().stringValue(), + t.getFilename(), + "validity check", + "Decision Table did not compile", + 0, + "A problem may have been found on row "+row+" and column "+column); + } + } + + dtcompiler.printErrors(err, NumErrorsToReport); + err.println("Total Errors Found: "+dtcompiler.getErrors().size()); + + } catch (Exception e) { + err.print(e); + } + + } + /** + * Generates a default Mapping File. This file is not complete, but + * requires adjustments to match XML tags if they differ from the + * Attribute names used in the EDD. Also, the initial Entity Stack and + * frequence of Entity types must be examined and updated. + * + * @param mapping Tag for the mapping file. Attributes with this tag in the + * EDD will be mapped in the generated mapping + * @param filename File name for the mapping file generated + * @throws Exception + */ + public void generateMap(String mapping, String filename) throws Exception { + RuleSet rs = getRuleSet(); + MapGenerator mgen = new MapGenerator(); + mgen.generateMapping( + mapping, + rs.getFilepath()+rs.getEDD_XMLName(), + rs.getWorkingdirectory()+"map.xml"); + } +} diff --git a/ExcelUtil/src/main/java/excel/util/ImportRuleSets.java b/ExcelUtil/src/main/java/excel/util/ImportRuleSets.java new file mode 100644 index 0000000..d2f4508 --- /dev/null +++ b/ExcelUtil/src/main/java/excel/util/ImportRuleSets.java @@ -0,0 +1,608 @@ +/* + * Copyright 2004-2007 MTBJ, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package excel.util; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.Writer; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; + +import org.apache.poi.hssf.usermodel.HSSFCell; +import org.apache.poi.hssf.usermodel.HSSFRow; +import org.apache.poi.hssf.usermodel.HSSFSheet; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.poifs.filesystem.POIFSFileSystem; + +import com.dtrules.xmlparser.XMLPrinter; + +public class ImportRuleSets { + + String defaultColumns[]={"number","comments","dsl","table"}; + + // These are the default columns for the decision tables. + String columns[] = defaultColumns; + + /** + * Return the column number for the given column name. + * @param s + * @return + */ + int getColumn(String s){ + for(int i=0; i< columns.length && columns[i]!= null; i++){ + if(columns[i].equalsIgnoreCase(s)) return i; + } + return -1; + } + + /** + * Convert all the Excel files in the given directory, and all sub + * directories + * @param directory + * @param sb + * @return true if some file to convert was found. + * @throws Exception + */ + private boolean convertFiles(File directory,XMLPrinter out, int depth) throws Exception{ + boolean xlsFound = false; + File[] files = directory.listFiles(); + for(int i=0; i < files.length; i++){ + if(files[i].isDirectory()){ + if(convertFiles(files[i],out,depth+1)){ + for(int j=0;j sheet.getLastRowNum()) return ""; + HSSFRow theRow = sheet.getRow(row); + if(theRow==null)return ""; + HSSFCell cell = theRow.getCell((short)column); + if(cell==null)return ""; + switch(cell.getCellType()){ + case HSSFCell.CELL_TYPE_BLANK : return ""; + case HSSFCell.CELL_TYPE_BOOLEAN : return cell.getBooleanCellValue()? "true": "false"; + case HSSFCell.CELL_TYPE_NUMERIC :{ + Double v = cell.getNumericCellValue(); + if(v.doubleValue() == (v.longValue())){ + return Long.toString(v.longValue()); + } + return Double.toString(v); + } + case HSSFCell.CELL_TYPE_STRING : + String v = cell.getRichStringCellValue().getString().trim(); + return v; + + default : return ""; + } + } + /** + * Looks for the value in some column, and returns that index. This way we can be a bit more + * flexible in our format of the EDD. + * @param value + * @param sheet + * @param row + * @return the Index of the value, or -1 if not found. + */ + private int findvalue(String value, HSSFSheet sheet, int row){ + HSSFRow theRow = sheet.getRow(row); + if(theRow==null)return -1; + for(int i=0;i0){ + String src = sourceIndex>=0 ? getCellValue(sheet,row,sourceIndex):""; + String comment = commentIndex>=0 ? getCellValue(sheet,row,commentIndex):""; + xout.opentag("entry"); + xout.opentag("entity", + "entityname" , entityname, + "attribute" , getCellValue(sheet,row,attributeIndex), + "type" , getCellValue(sheet,row,typeIndex), + "subtype" , getCellValue(sheet,row,subtypeIndex), + "default" , getCellValue(sheet,row,defaultIndex), + "access" , getCellValue(sheet,row,accessIndex), + "input" , getCellValue(sheet,row,inputIndex) + ); + xout.closetag(); + if(comment.length()>0)xout.printdata("comment",getCellValue(sheet,row,commentIndex)); + if(src .length()>0 )xout.printdata("source", getCellValue(sheet,row,sourceIndex)); + xout.closetag(); + } + } + xout.closetag(); + xout.close(); + } + /** + * Pulls the ATTRIBUTE name out of the next cell. The assumption is that + * all ATTRIBUTES (Including the main sections of the decision table) are + * all in the first column of a row, followed by a colon. + * + * We ignore numeric Attribute names. + * @param sheet + * @param row + * @return + */ + private String getNextAttrib(HSSFSheet sheet, int row){ + String value = getCellValue(sheet, row, 0).trim(); + int colonIndex = value.indexOf(":"); + if(colonIndex>1){ + String attrib = value.substring(0,colonIndex); + attrib = attrib.replaceAll(" ", "_").toLowerCase(); + try { + Integer.parseInt(attrib); + attrib = ""; + } catch (NumberFormatException e) { } + return attrib; + } + return ""; + } + /** + * Pulls the ATTRIBUTE Value out of the next cell. If no attribute value + * is found, then the value of column 0 is returned, whitespace trimmed off. + * + * Ah, but we add a wrinkle. If the value + * we find in column 0 is a number, then we return the value from column + * column 3. + * + * @param sheet + * @param row + * @return + */ + private String getNextAttribValue(HSSFSheet sheet, int row){ + String value = getCellValue(sheet, row, 0).trim(); + int colonIndex = value.indexOf(":"); + if(colonIndex>1){ + value = value.substring(colonIndex+1).trim(); + } + try{ + Integer.parseInt(value); + value = getCellValue(sheet,row,2).trim(); + }catch(NumberFormatException e){}; + return value; + } + /** + * Returns the value of the number column. You don't have to have one + * of these. + * + * @param sheet + * @param row + * @return + */ + private String getNumber(HSSFSheet sheet, int row){ + int field = getColumn("number"); + if(field==-1)return ""; + String value = getCellValue(sheet,row, field); + return value.trim(); + } + /** + * Any Section can get the DSL specified in the section from this call. + * + * @param sheet + * @param row + * @return + */ + private String getDSL(HSSFSheet sheet, int row){ + int field = getColumn("dsl"); + if(field==-1)throw new RuntimeException("No DSL Column"); + String value = getCellValue(sheet,row, field); + return value.trim(); + } + /** + * Returns the contents of the Comment column... You don't have to have one + * of these. + * + * @param sheet + * @param row + * @return + */ + private String getComments(HSSFSheet sheet, int row){ + int field = getColumn("comments"); + if(field==-1)return ""; + String value = getCellValue(sheet,row, field); + return value.trim(); + } + + /** + * Returns the Table value + * of these. + * + * @param sheet + * @param row + * @return + */ + private String getTableValue(HSSFSheet sheet, int row, int tableIndex){ + int field = getColumn("table"); + if(field==-1)return ""; + String value = getCellValue(sheet,row, field+tableIndex); + return value.trim(); + } + + /** + * Returns the value of the Requirement Reference column... You don't have to have one + * of these. + * + * @param sheet + * @param row + * @return + */ + private String getRequirement(HSSFSheet sheet, int row){ + int field = getColumn("requirement"); + if(field==-1)return ""; + String value = getCellValue(sheet,row, field); + return value.trim(); + } + + + /** + * Returns the index of the heading of the next block. + * @param sheet + * @param row + * @return + */ + int nextBlock(HSSFSheet sheet, int row){ + String attrib = getNextAttribValue(sheet, row); + while(attrib == ""){ + row++; + attrib = getNextAttribValue(sheet, row); + if(row > sheet.getLastRowNum()) return row-1; + } + return row; + } + + /** + * Reads the decision table out of an Excel spreadsheet and generates the + * approriate XML. + * @param file + * @param sb + * @return true if at least one decision table was found in this file + * @throws Exception + */ + public boolean convertDecisionTable(File file,XMLPrinter out) throws Exception{ + if(! (file.getName().endsWith(".xls"))) return false; + + InputStream input = new FileInputStream(file.getAbsolutePath()); + POIFSFileSystem fs = new POIFSFileSystem( input ); + HSSFWorkbook wb = new HSSFWorkbook(fs); + boolean tablefound = false; + for(int i=0; i< wb.getNumberOfSheets(); i++){ + tablefound |= convertOneSheet(file.getName(),wb.getSheetAt(i),out); + } + return tablefound; + + } + /** + * Returns true if the given sheet describes a valid DecisionTable. + * + * @param filename + * @param sheet + * @param sb + * @return + */ + private boolean convertOneSheet(String filename, HSSFSheet sheet,XMLPrinter out){ + + columns = defaultColumns; + + // The first row of a decision table has to provide the decision table name. This is required! + // Must be the first row, must have a NAME: tag, followed by a decision table name! + String attrib = getNextAttrib(sheet, 0); + String value = getNextAttribValue(sheet, 0); + if(!attrib.equalsIgnoreCase("name") || value.length()==0){ + return false; + } + out.opentag("decision_table"); + + String dtName = value.replaceAll("[\\s]+", "_"); + + ArrayList attributes = new ArrayList(); + + int rowIndex = 1; + // Go through the attribute rows, identified by some tag followed by a colon. When we reach a heading + // tag of CONDITIONS: then we stop! These headers we preserve in the resulting XML. + for(rowIndex=1;true;rowIndex++){ + + attrib = getNextAttrib(sheet, rowIndex); + value = getNextAttribValue(sheet, rowIndex); + + // Once we transitioned to the table upon seeing the CONDITIONS: tag. We are + // grandfathering that into our parsing. Any other segment (Context or Initial Actions) + // requires a blank line to step the processing on. First optional segment is Contexts:, + // followed by Initial_Actions:, followed by the Condition table. + if( attrib.equalsIgnoreCase("conditions") || (attrib.length()==0 && value.length()==0)){ + break; + } + String v = value.trim(); + attributes.add(attrib); + attributes.add(v); + + // If we have a columns attribute, then the column numbers and order are specfied there. + // COLUMNS: number, comment, requirements, dsl, table + if(attrib.equalsIgnoreCase("columns")){ + v = v.substring(2).trim(); + columns = v.split("[,\\s]+"); + } + + } + out.printdata("table_name",dtName); + out.printdata("xls_file",filename); + out.opentag("attribute_fields"); + for(int i=0; i< attributes.size(); i+=2){ + out.printdata(attributes.get(i),attributes.get(i+1)); + } + out.closetag(); + + rowIndex = nextBlock(sheet, rowIndex); + attrib = getNextAttrib(sheet, rowIndex); + + if(attrib.equalsIgnoreCase("contexts")){ + rowIndex++; + out.opentag("contexts"); + while(true){ + attrib = getNextAttrib(sheet, rowIndex); + if(attrib.length()>0)break; + String context = getDSL(sheet, rowIndex); + if(context != "") + { + out.opentag("context_details"); + out.printdata("context_description",context); + out.closetag(); + } + rowIndex++; + } + out.closetag(); + } + + rowIndex = nextBlock(sheet, rowIndex); + attrib = getNextAttrib(sheet, rowIndex); + + if(attrib.equalsIgnoreCase("initial_actions")){ + rowIndex++; + out.opentag("initial_actions"); + while(isAction(sheet,rowIndex)){ + String initialActionDescription = getDSL(sheet, rowIndex); + + if(initialActionDescription != "") + { + out.opentag("initial_action_details"); + String actionNumber = getNumber(sheet, rowIndex); + out.printdata("initial_action_number",actionNumber); + + String initialActionComment = getComments(sheet, rowIndex); + out.printdata("initial_action_comment",initialActionComment); + + out.printdata("initial_action_description",initialActionDescription); + out.closetag(); + } + rowIndex++; + } + out.closetag(); + } + + rowIndex = nextBlock(sheet, rowIndex); + attrib = getNextAttrib(sheet, rowIndex); + rowIndex++; + + out.opentag("conditions"); + while(isCondition(sheet, rowIndex)){ + + String conditionDescription = getDSL(sheet, rowIndex); + + if(conditionDescription != "") { + out.opentag("condition_details"); + String conditionNumber = getNumber(sheet, rowIndex); + out.printdata("condition_number",conditionNumber); + + String conditionComment = getNumber(sheet, rowIndex); + out.printdata("condition_comment",conditionComment); + + out.printdata("condition_description",conditionDescription); + + for(int j=0; j<16;j++){ + String columnValue =getTableValue(sheet, rowIndex, j); + if(columnValue.equals(""))columnValue = "-"; + if ((columnValue.equalsIgnoreCase("*")) || + (columnValue.equalsIgnoreCase("-")) || + (columnValue.equalsIgnoreCase("y")) || + (columnValue.equalsIgnoreCase("n"))) { + out.printdata("condition_column","column_number",""+(j+1),"column_value",columnValue,null); + }else{ + // if(columnValue != "") + // throw new Exception("Undesired value in the condition matrix"); + } + } + out.closetag(); + } + rowIndex++; + } + out.closetag(); + + rowIndex = nextBlock(sheet, rowIndex); + attrib = getNextAttrib(sheet, rowIndex); + rowIndex++; + + out.opentag("actions"); + while(isAction(sheet,rowIndex)){ + String actionDescription = getDSL(sheet, rowIndex); + if(actionDescription.length()>0){ + out.opentag("action_details"); + String actionNumber = getNumber(sheet, rowIndex); + out.printdata("action_number",actionNumber); + + String actionComment = getComments(sheet, rowIndex); + out.printdata("action_comment",actionComment); + + out.printdata("action_description",actionDescription); + + for(int j=0; j<16;j++){ + String columnValue = getTableValue(sheet, rowIndex, j); + if (columnValue.equalsIgnoreCase("x") || + columnValue.equalsIgnoreCase("s") ) { + out.printdata("action_column","column_number",""+(j+1),"column_value",columnValue,null); + }else{ + if(columnValue.length() != 0){ + System.out.println(dtName+": Undesired value '"+columnValue+"' in the action matrix ("+j+","+rowIndex+")"); + } + } + } + out.closetag(); + } + rowIndex++; + + } + out.closetag(); + out.closetag(); + return true; + } + + /** + * We used to do something really smart. Now we just return false at the end of the spread + * sheet or if we encounter another block. + * @param sheet + * @param rowIndex + * @return + */ + private boolean isAction(HSSFSheet sheet, int rowIndex){ + String attrib = getNextAttrib(sheet, rowIndex); + if (attrib.length()>0) return false; + if(rowIndex > sheet.getLastRowNum()) return false; + return true; + } + + /** + * We used to do something really smart. Now we just return false at the end of the spread + * sheet or if we encounter another block. + * @param sheet + * @param rowIndex + * @return + */ + private boolean isCondition(HSSFSheet sheet, int rowIndex){ + String attrib = getNextAttrib(sheet, rowIndex); + if (attrib.length()>0) return false; + if(rowIndex > sheet.getLastRowNum()) return false; + return true; + } + + public void setContents(File aFile, String aContents) + throws FileNotFoundException, IOException { + if (aFile == null) { + throw new IllegalArgumentException("File should not be null."); + } + + //declared here only to make visible to finally clause; generic reference + Writer output = null; + try { + //use buffering + //FileWriter always assumes default encoding is OK! + output = new BufferedWriter( new FileWriter(aFile) ); + output.write( aContents ); + } + finally { + //flush and close both "output" and its underlying FileWriter + if (output != null) output.close(); + } + } + + +} diff --git a/authors.txt b/authors.txt new file mode 100644 index 0000000..0df90a2 --- /dev/null +++ b/authors.txt @@ -0,0 +1,2 @@ +paulsnow = Paul Snow +subversion = Subversion \ No newline at end of file -- 2.11.4.GIT