一、模式解析
解释器模式是类的行为模式。给定一个语言之后,解释器模式可以定义出其文法的一种表示,并同时提供一个解释器。客户端可以使用这个解释器来解释这个语言中的句子。
以上是解释器模式的类图,事实上我很少附上类图,但解释器模式确实比较抽象,为了便于理解还是放了上来,此模式的要点是:
1、客户端提供一个文本、表达式或者其他,约定解析格式
2、针对文本中可以分为终结符表达式和非终结符表达式,
3、终结符表达式无需进一步解析,但仍需要转化为抽象接口的实例
4、针对非终结表达式,没一种标示需要定义一种解析类,如果后续有扩展,则进一步扩展一种解析类,并修改解析分支即可完成扩展
二、模式代码
1、定义整体环境类,保存除了解析器外,其他全局信息
package interpreter.patten; public class Context {
private String input;
private String output;
public String getInput() {
return input;
}
public void setInput(String input) {
this.input = input;
}
public String getOutput() {
return output;
}
public void setOutput(String output) {
this.output = output;
}
}
2、定义抽象解析器
package interpreter.patten; public abstract class AbstractExpression {
public abstract void interpret(Context context);
}
3、定义终结符解析器
package interpreter.patten; public class TerminalExpression extends AbstractExpression { @Override
public void interpret(Context context) {
System.out.println("终结符解析器");
}
}
4、定义非终结符表达式
package interpreter.patten; public class UnTerminalExpression extends AbstractExpression { @Override
public void interpret(Context context) {
System.out.println("非终结符解析器");
}
}
5、定义客户端类
package interpreter.patten; import java.util.ArrayList;
import java.util.List; public class Client {
public static void main(String[] args) {
Context context=new Context();
List<AbstractExpression> list=new ArrayList<AbstractExpression>();
list.add(new TerminalExpression());
list.add(new UnTerminalExpression());
list.add(new TerminalExpression());
list.add(new UnTerminalExpression());
list.add(new TerminalExpression());
list.add(new UnTerminalExpression());
for(AbstractExpression expression:list){
expression.interpret(context);
}
}
}
6、客户端执行结果
终结符解析器
非终结符解析器
终结符解析器
非终结符解析器
终结符解析器
非终结符解析器
三、应用场景
以上模式代码完整的实现了类图中的所有内容,并打印出了结果,但是又显得毫无意义,看起来比较蠢,这是因为在我们的实际使用中解释器模式使用非常稀少,他只有在做特定公式的解析或者语言解析才会用到,很不幸,目前我的工作中似乎没有可以完整的展示此模式的例子,但是为了加深印象,我们采用《java与模式》中的例子进行说明
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA2EAAAHeCAIAAACdbZThAAAgAElEQVR4nOy9L6zkSJa3fcGqtMMavGBXWlDSbEoNLyxg0LDhmA1ZbWtNBjYwaNbIatjE0mjRAIOFI6OBhkMsFRwZ9SIXLGBQ0B843z17KsLptNN22Ol8HpQ3rh0OR5yI+PnEv5ceAAAAAOBrXvZOAAAAAAAcDjQiAAAAALigEQEAAADABY0IAAAAAC5oRAAAAABwQSMCAAAAgAsaEQAAAABc0IgAAAAA4IJGBAAAAAAXNCLAUl5fX18gIK+vr3uXOQDA+UEjAizl5YV6FBQyHAAgADS1AEtBsgSGDAcACABNLcBSkCyBIcMBAAJAUwuwFCRLYMhwAIAA0NQCLAXJEhgyHAAgADS1AEtBsgSGDAcACABNLcBS9pIsdV23bbvLo/cFjQgAEIDhppb93kZgbzZweAkuWeq6juM4y7I0TS+XS9M0gROwL+EzHADgCRluammCRyBzwCG8SVhdmGVZURR3RJIkyZI0pGm65PYlUAcBAAKARpwNmQMOgU0iz/MoimxIVVVzI6nr2olkFl3XLbl9IdRBAIAAoBFnQ+aAQ2CTiKIoy7LBf8VvlGXZ931RFJfLJcuyOI6jKFLPn/x5uVzkYr1drozjWK9MkuRyuURRlOe5XC+BcRy/vLzIxeFHuqmDAAABQCPOhswBh4NoxCiK1KEYRZEsZ1Fp2HXd5XLRi30/YlEUOvqcJEme5/I7z/M4jtu2tWqy73sbW2CogwAAAUAjzobMAYcjaMS6rq1oS9NUpGEURXVdS+DlctHfvkYUZ2Fd13Vdp2lq/xtFkYpOBY0IAHBu0IizIXPAIbBJxHHsLDdpmsbRfFmWyZ+zNGKaptkb6kfs+15WT3ddZ69HIwIAnJtwGrEoCunbdKpTlmUy28m5Uka1nA7pONA/gUNgk5BZhvbPoijatrWBOlg8RSPKCHUcx1YX6rB10zRSbR1hqo+TuY8hoQ4CAAQgkEZUaSjLIW1H5WtECVwyEX7TTov+CRzCm0QURaLYqqrSaYJJkmig6r8oirQ6WI0omrJt2zzPRQ5WVXW5XOR3kiTyQyps27YyndHWrCiKiqKoquraAprtoA4CAAQghEaUvsf+qZ3KoEZcjjO5fl3on8BhF5OQpSTW89e/eeu1fkldkz+LotDfQlmWSZLYvRWrqhJ/oToR5ZaqqjQqdfCLf9FJQBiogwAAAQihEdW94eNrxDzPZQzaubJtW7tXsPRYTdNIz6ez6XX82ukOV4T+CRwwicCQ4QAAAQihEUe2c/M1osg+J7AsSxmh1t2DZQgsjuOiKOyWwnVdF0UhF+uw2rrQP4EDJhEYMhwAIACH04iDgVEU6fREmQXVexOt1JW48ACJm9A/gQMmERgyHAAgAI+hEfVAiDiOZRy5n7Opx7rQP4EDJhEYMhwAIAAhNKKzH68spZTf0zWivxUOGhEOAiYRGDIcACAAITSi7LKhGi5JEjsuPEUj2vWbslSlH9WIcrsVoytC/wQOmERgyHAAgAAE2h9RlqGkaSqrTCQwyzI5v8EuWC6KQgPtLr6yIZzusyj76cjyZ41cHycXb7QDDv0TOGASgSHDAQACEPQsviXbYvd97xwXu+LFs6B/AgdMIjBkOABAADiveTZkDji8e/fuBQLy7t27vcscAOD8oBFnQ+aAAyYRGDIcACAAaMTZkDnggEkEhgwHAAgAGnE2ZA44YBKBIcMBAAKARpwNmQMOmERgyHAAgACgEWdD5oDDYU1CDjqX37JNqW4y9dAcNsMBAM4EGnE2ZA44HNYk7Hb0sqWobjX/0Bw2wwEAzgQacTZkDjjsZRI3Nxyt6zqOY9GFWZbZo4keGuogAEAAhpta9nsbgb3ZwOHlumRJkiTP8zRN0zTN81zP/sne0POB5DChoigksCzL8YfWdf3y8jK+V3xd1/KU/muNqOF6xFHXdXLipYbPyYDQjGQ4AACsBX7E2ZA5T8uPP/74+fNnP1xMQrSdpW1bPVJS1GGWZXVdN02jIkxC5Lf18+k8whFuOgXruq6qSh4tcxPlFjnEUrCyVc83T9NUT8I8INRBAIAAoBFnQ+Y8LR8/fvzuu+98mThiEioBrUbs+77ruqIoiqKwutCeMG61493UdV3XdRRFVVWJn1LjbJpGzkZXMWqfKI7GhU/fDuogAEAA0IizIXOemUGZOFcjNk0Tx7EME1tltpFGTJJERrStH1FdhtaPiEYEAAAFjTgbMufJ8WXiXI2YJImqsWsaUUXkCF3XjV8gGlHnQYpGbNvWDmQPasQ8z4+8Sw51EAAgAGjE2ZA54MjEEZNI07Sua1kRon/KwpS+79u2TdO0KApZoRJFkfyoqkrXslyjLMvL5TIuE+s35HHqR4yiSG4syzKOY5GDuoCmbVs7YfGAUAcBAAKARpwNmQP91zJxxCTEb9e2rS4oFu+gTAeUzWusH7HrurIsb25qI9xc+yyPlt9d18kwt94rq1L0GvEjVlV15NUqAnUQACAAaMTZkDkgqExcyyTUvbcLUzbcOQjUQQCAAKARZ0PmgCIycRWTcPx84ZFR6b2ePgvqIABAANCIs7m2t/bPP/+s1/z8889c8yTX/Od//ucL9SUsZDgAQADQiLMhc0D5/PnzWn5EmA4ZDgAQADTibMgcEEQgfvz4EZMIDBkOABAANOJsyBzojUDsMYngkOEAAAFAI86GzAErEHtMIjhkOABAANCIsyFznhxHIPZ9/+7du8HlLLAR796929EAAACeBDTibMicZ8YXiD0mERwyHAAgAGjE2ZA5T8ugQOwxieCQ4QAAAUAjzobMeVr+8Ic/+AKxfyiTkHNcdtypexUeKMMBAB4XNOJsyBxweBSTyLJMfuR5/tAy8VEyHADgoUEjzobMAYetTaJt28vlslDVJUliD4NOkmRxuhaRpulgGpqmSZJk/FRA6iAAQADQiLMhc8DBMYmiKFZ/RJ7nS26vqkqdiBqyRTqn0zRNWZaD/8qyDI0IALA7aMTZkDng4JiEo8aOQJIkbds6gXEc75KYm6ARAQCOwHBTy35vI7A3Gzi8jGrEsizTNE3T1PoC27bNsixN0yzL7CByURQSqD62pmnyPI+iyHlonucSZ5ZlMr8wjuO6rrMsS5LEGZgelIPTNeLlcrnm87OvmWWZDGcXRaHXV1Ulr19Vlb04jmMno5qmkXdP0xSNCACwO/gRZ0PmgIOYRFEUWZZlWSbqRwST6B65zLrHdCqeqDq9QKcMOnP1LpeL/VMnFxZFURSF/I6iSIaPu65z9N+gHIyiaOIcxzzPfTfkYIT6IvKjaRr7dlYmShbpn23b6iujEQEAjgAacTZkDjiM+xG7rmvbtqoq8fNJYJIk6mlTXZjnufoa7fqS3tOIqvmsxLRCcIpGXH2sOY5jkZL6FhrS933btvaJjka0jkbGmgEAjgAacTZkDjiMa8Q4jsW950gfGUF2/IVFUcRxHMex4+FzNGKe5xJnmqYqwnbXiFVV5XleVZUmfiQZjkaMokgzB40IAHAE0IizIXPAYUQjpmmq/kIrfdRNWFWVykSVVo7LrR8aa26aZmTSoXO7SDcbYsd2VySKIh1b72f6EdGIAACHAo04GzIHHEZMIssy3WJGZJBoNdVnXdfpbyvaxjVilmVRFEVRpE7KflQj+iFZlk2ZYihYJ984SZJYjejMR7Si1tGIVivrxMprUAcBAAKARpwNmQMO4yYhS4/LsmzbVifq5XkuC4HtemFZDqwXS6DsIyiBorHatnV8deJT1EUhshui42Usy1KFV13XszZctCPa49R17Vwp67Kdk13KspRA+/qS7LIsq6rCjwgAsDtoxNmQOeAQ2CScYeLp0wqLohABd8AdHGdBHQQACAAacTZkDjiEN4m2bcXpaD2OzwN1EAAgAGjE2ZA54IBJBIYMBwAIABpxNmQOOGASgSHDAQACgEacDZkDDphEYMhwAIAAoBFnQ+aAwwOZhOzLOPEIvsPyQBkOAPC4oBFnQ+aAwxSTOMLKEl3O7OxEsxbO+YHbRUIdBAAIABpxNmQOOIybRFmWaZpGUXRHzE3T3HejT5IkVn6tfsiKsyf2XLquK8syjuMpkVAHAQACgEacDZkDDo5J+GeE1HV9t9Rb5VRl2Z7aCRk/y2QudV0v33ZxotCkDgIABACNOBsyBxxGzmsWdteISZL4g92rxKygEQEATgYacTZkDjjcoRHbts2yLE1Texhd3/d5nqdpaj18ouS6rpOT67qua5pG5Z0ecyyBdV2naeqfxTwoB6drxMvl4qTTRzRiURRpmtqD/qqqStM0TVM5J3AksEcjAgAcCTTibMgccBCTKIpCJI5MqsuyTOf/+RpRpwPaUWCdMth1nQo4/WHFk5V3+juKIhWXzuMG5WAURRNXruR5fnPNjbyjpF/EYt/3coq0pl8U4WCg/olGBAA4CGjE2ZA54DDXj5jnufUUyr+aprHrSJIkEQEXx7GVjMKgRrSBaZrWdT14/Xjg3dix5rquJfI4jlVctm07EiigEQEAjgMacTZkDjjM1YhZlvkCzpnPp9dEUZQkSZIk1t92UyMOPsJhU40o7zsobUf0LhoRAOA4oBFnQ+aAQwA/Yv/18PFNjai36xOdmX9t2667/Y2jESVy/IgAAI/LcFP7zTffvMAVvvnmm8CFBAfn5ZZkGZ+PqCs87HxEvUAllCwH0UBxE+Z5rrMAoyiSQH9suve8d/66lhE05vF31DRfm3oosnUwUP9EIwIAHIQHaGrpD+DgjJtoWZZlWWZZVpal6qGu64qikKXK9mJZ+KJeRpFTordkdYvKrCRJ0jRt27YoCtGIIhwdJ6VNhobLZdNfUB40fo0suJaXsj7LpmnyPHdOdvEDZQ9tCZTl2yPPok0AAAjAAzS19AdwcA5iojfnFxZFIVJv+UaG+3KQDAcAODcP0NTSH8DBOYKJisfx5i6G5+AIGQ4AcHoeoKmlP4CDg4kGhgwHAAjAAzS19AdwcDDRwJDhAAABeICmlv4ADg4mGhgyHAAgAA/Q1NIfwMHBRANDhgMABOABmtqff/557yQAjMF+ooFhj1IAgAA8gEYEAAAAgMCgEQEAAADABY0IAAAAAC4PoBGZjwgAAAAQmAfQiC+sYQQAAAAIywPILzQiAAAAQGAeQH6hEQEAAAAC8wDyC40IAAAAEJgHkF9oRAAAAIDAPID8QiMCAAAABOYB5BcaEQAAACAwDyC/2B8RAAAAIDAPoBEBAAAAIDBoRAAAAABwQSMCAAAAgMsDaETmIwIAAAAE5gE0IuuaAQAAAALzAPILjQgAAAAQmAeQX2hEAAAAgMA8gPxCIwIAAAAE5gHkFxoRAAAAIDAPIL/QiAAAAACBeQD5hUYEAAAACMwDyC/2RwQAAAAIzANoRAAAAAAIDBoRAAAAAFzQiAAAAADg8gAakfmIAAAAAIF5AI3IumYAAACAwDyA/EIjAgAAAATmAeQXGhEAAAAgMA8gv9CIAAAAAIF5APmFRgQAAAAIzAPILzQiAAAAQGAeQH6hEQEAAAAC8wDyi/0RAQAAAALzABoRAAAAAAKDRgQAAAAAlwNpxB9//PHz588TL/78+fOPP/64aXoAAAAAnpYDacSPHz9+9913vkz05yN+/vz5u++++/jxY6CUAQAAADwZB9KI/RWZ6KxrRiACAAAAbM2xNGI/JBOtRkQgAgAAAATgcBqx92SiakQEIgAAAEAYjqgR+69lomhEBCIAAABAMA6qEXsjE19eXhCIAAAAACE5rkbs32Tiy8sLAhEAAAAgJF9pxNfX1xcAAAAAODuvr68zNOLLy6HdigAAAACwCjdVHxoRAAAA4OlAIwIAAACACxoRAAAAAFzQiAAAAADggkYEAAAAABc0IgDA+rRtu3cSAAAWgUYEgEclTdPL5ZJlWZZlcRxHUbR3iv6PKIriON47FQAA94NGBIBHpa7ry+WifyZJchzvXVmWVVXtnQoAgPtBIwLAo2I14t3qcDtZ2XXdKtcAAOwCGhEAHhWrEXVgN0mSy+USRVGe55fLRcIlMEkSGZIuikICoyi6XC5VVcVxfLlcyrLs+75pmviNuq71cRpoB7X9QLldBsFtatM0lQFoDZe7NFXHcYICAPRoRAB4XOq6fnl58XVbnudxHLdta2cEXi4XkYZt214uFxFkEkOapn3fp2kqGjGKIpGGVoNmWSa390aPDgYKURRZjZimqf6ZJIncJfHLs+wFAABHAI0IAI+K1XBJkth/RVHkeObszEV1JTozGiVENKKgGi7Pc71LB4gHA/URVvNpPH3fV1UlilaeJYFZlh1qzQ0AABoRAB4VX+EpsuTZ6jZHI4qAG9SIulZa0Eh0SFr8jiOB/ZBG9JONRgSAI4NGBIBHxVF4RVGIr65pmiRJ0jS1zkV7pXr1fI3YNI0NkdHnvu9V8MlQtdw+GCiM+BGLopCBaTQiABwZNCIAPCplWaqeq6pKfnddJ6PMXdfpMpTezEeUAWIJHPRExnEs4lJ8hBIoi2D0t4xiDwbqn1YjFkURRVHXdW3bRlHUNI2kH40IAIcFjQgAj0r2NSLX5HdVVVVV2cFi0YhxHKuqK4pC73X2MpRVL3pl/7Y8RdyTevFgYNd1NlUaQ1VVcqUIRJtUvYUtFQHgOKARAeApcKYnAgDAOGhEADg/6jLcOyEAAA8DGhEAAAAAXNCIAAAAAOCCRgQAAAAAFzQiAAAAALigEQEAAADABY0IAAAAAC7zNOK7d+9eAAAAAODsvHv3boZGfMGPCAAAAPAE3FR9aEQAAACApwONCAAAAAAuaEQAAAAAcEEjAgAAAIALGhEAAAAAXNCIAAAAAOCCRgQAAAAAFzQiAAAAALigEQEAAADABY0IAAAAAC5oRAAAAABwQSMCAAAAgAsaEQAAAABc0IgAAAAA4IJGBAAAAAAXNCIAAAAAuKARAQAAAMAFjQgAAAAALmhEAAAAAHBBIwIAAACAyzyN+O7duxcAAAAAODvv3r2boRFf8CMCAAAAPAE3VR8aEQAAAODpQCMO03Xd3kkAAAAA2A004gBFUTRN0/d9lmV7pwUAAABgB1bWiE3TJEmyNFG7UlVVnufyu+u6NE3XjT/P84XSsyzLNE3jOF4rSQAAAAAOizRiVVXO1U3TTNcu+47niqfQx0l/URT+ay6hruvl7sm6rqMoWiU9AAAAAD6LNOISrdM0TV3Xd9++HHUWWqwTUVnXY4dGBAAAgOOzpkZs2zbPczs42zRNlmUSXhSFhldVFUWRTPuz3kS5Xv12XdeVZSlPqeta1FvXdVmWdV1n4xy80qaqLEsNqes6SZI0TZumadvWvoIEOlkwXSOmaWpfcxDRiE3T5HnuPKsoCsmum4FoRAAAANiUezSiuADruk7TVH7oBb52uVwuIpscmZhlmeNHLIpCLpCYNTyO4zzP27aN41ikXhRFogLrurYCzr+yaRqJqus6O1HymjNvUA5GUeRItGukaXrTRyhpFh2cJIkK4iRJ5ClW0Q4G9mhEAAAA2JjNNaKqLkeW+RrRUXv6+3K5OBLN/jdJEvXGjV9pPZQbacQpWAUsHs2+74uisL5PycPBQL0RjQgAAADbsfJ8xCUaMYqi8o04jlX5+brNUX4aj3+ljTNNU5Vc1zTiwrHmKdhHa3Y5uSFPHAx0bgQAAADYggNpxGtSbFwjii9zypVOOgc1YuA1KzpWbn2c/ZvLcDBQb0QjAgAAwHYs0oj+5jXTNWKe5yKAdJpdHMeq9uzMxUHlp4+2j/OvzLJMNV9VVTpkrPMU/WUrS/a+cVTdIHasWadgtm2r0yXbtpULBgM1EjQiAAAAbMeae2iLE07Wi4iGs6PGRVEkSWJlpQz+WlElaz70mJOmaSSGsiztEHAcx6KuZIHwyJV932dZJnHaNR/6dH8Z8pI9tOM4vrlmRVY0y1xD67OU5zo7bA8GlmWp+Xxtl0cAAACAJTzkWXxbHzGiInX1Q1YAAAAAHoLH04hylMvNbQgXsu8ZMAAAAAD78ngaEQAAAAC2Bo0IAAAAAC5oRAAAAABwOa1GlAmFLPsFAAAAuIPH0Ihzj8LTnWLyPN9CJq6yooVlMQAAAHBYjq4RZYPAy+Uy/RZnF0bdhnotZMPFu2/vuk62clwSCQAAAMCmLNKIW29Ao0zXiFVVOdqrqqp103ntHL9ZLBSaAAAAAJuy8nnNGzFdIyZJ4g9Mb3fg8t2gEQEAAODIrKwR8zyXM+40pG3bLMvSNK3rWk7Dk02w5b9VVelYcNM0cqW9XfA1YlEUcnCfc8LeoBycrhEvl4sToY9oREmAc5hemqZpmtrTBQcDezQiAAAAHJt7NKIclJxlmUyqy7JM5v+p2rMDvqrP7KHDVrTpb/3hO+ocjahP7L3phoNyMIqiiStX8jy/uT6mrusoiiQBIhb7N4GryRNFOBiof6IRAQAA4LCs5kd0hF0URf3XutBeMKgRRZzVdS0OQvsgRyPmea4OPGd18EI/4hTsi9R1LZHHcazism3bkUABjQgAAABHZk2NmCRJ+Yb8K8uyuq71gnGNqNLwph+x7/uiKOI4juPYcRCG14iihp1HqEa8lgw0IgAAAByZNTVimqb6p7j3rMNvXCPKvD3/SsHRiKoLHeecPNGZ+de27brb3zgaUSLHjwgAAABnYs39EeM4Fq9h13UyS88KI6uK9Mo8z2Vun128Im5Iu3bE0YhW8/k+Qicky7LpW3BHUaSOz2uoLuyvTz0UFTsYqH+iEQEAAOCwrLyHtkxAtPKuaRpZ/6sD0BKYJEmapm3bFkUhTkdZClOWZdu2ej5KVVUqGdVBWBSFBvr6ryxL3RCxrmt/lfQIkqTxa7qua5qmKArHZ9k0jfhNrRb0A2UPbQksy5LTVgAAAOCAhDtnZZVtBSdSFIVIPXx1AAAAAHcQSCPK6LPdswYAAAAADsvRz2sGAAAAgPCgEQEAAADABY0IAAAAAC5oxF73qdk7IQAAAABHYU2NeJz1KNNTogufnT1rAAAAAJ6Z1TRiWZZyKt19NE1z7fbsjYlH6pVlOfFKZ4PDdY9jUdI03ShmAAAAgI1YpBF1q2ph4bHIg7enaaruvaqqnHP2ZkV187Kqqpw3WoWmaeym4uNXrv50AAAAgDtY7bzmfgON6B/HvKJGLIrCV4QLX2Eh9sBrAAAAgB1ZWSOWZZmmqdU6GuKciVcURZqm9uA+OcQ5y7IkScSjJif7DSYrz/M0TR2Rl2VZmqbOWLMkwDkuue/7JEn8Y/ema8Q4jqdIOkmMfQvZS1xfXwLlyL7L5VKWJQf0AQAAwO7coxFF5cgEQfkhmuZyudR13fe9nEfcvx3WLPdmWSb/ld8qg3SuXhRFovm6rhOtJpH7aUqSRG7XKyVQ4reBmpLe03+DcjCKookDvvb86HGct6jrOo5jSb8dSb+WJAAAAIDwbDLWbI9m7rqubduqqsRNKIF5nqt0U7FoFdKIRmyaxi4BUaejXfKiUdk4xXvnXzP4Civia0T90+rmjZ4OAAAAcAeba8Q4jkWZOXqoKIo4juM4VkearxEHx5pt5BptXdeDGjGKovINZxWzkx4/DWuBRgQAAICHY1uNKLMD9WLVQ6oL7aoUXyP6G+KUZXnNj+jf3o+qLjsOronZYpOaOzQi8xEBAABgX9bcQ9vXiHZ4N03Tuq7Fk2el2IhGlCtVZerwtJ2PqFHpWHZRFFEUyQVlWeoFN1cxZ1nmr2IZedlr62kcpmtEXUYzca8cAAAAgI1YTSNWVaVrh8uy1FUpMl5clmXbtiryiqKQayS87/umabIsEwVpo+rflsg4sklXB9tAmeZY13VRFOqKk9iKovD1X9u26kqs69pZeT2OpnYcGePO81zTLynvuq7rujzP/VfYYo9GAAAAgFk8+3nN6tqc6BQEAAAAeAaeXSMCAAAAgA8aEQAAAABc0IgAAAAA4IJGBAAAAAAXNOL/v1njxCP4AAAAAJ6BZ9eIupw5z3NkIgAAAICwj0Ysy1K2CcyyzDnsZCJt214ul4Wqzjmdb4tDVpZTlqVz2AwAAADA1izSiP5uz1NEm3PknaPMpp90MmvL60Gcc1aqqgq2f/WU/beV5W8KAAAAMIs1z2vu+36KU9AeRtd/LSvLsrRn021KURQ3T+fbjmP6LAEAAACE1TRi0zR5nl8ul7Isy7LUo/DatpUBZXuYXhRFztl6XdfJOctybJ2uI8nzXHRbURRxHOvBfXme2xHYpmnkvOYsy5Iksbozz/M0TeVAPMd/6fssp2vEOI6nCOKqqtI0TdNU80pCJAc0EyRQDoyWV7DhNlVVVckZ1hKtzQHJZ3lN5lYCAADAEu7RiDqVMI5j+aGK0NdYVu6oTpLhZl8pZlnm+xFFOPZ9n6ap/e/lcnEuE79g13WaDDkYWp9oldOgHIyiaKK6Kstyynixyjg5SHrk6XVdi/hz/lvXtTMf8XK5SFRyGLQTYZIkwXyxAAAAcFZWHmt2pE+e53Y819E6bds63rhBjehowWvh9tH620bopG1QI64+1hzH8aDoHNSIg0/3NaJeZkftB18ZAAAA4D621YiOXrkmy3TMd1DfXNNtUzRi0zSiQdWheC1t48+6m7ZtZWTZyatBjejnZz9ZI4qTtes6ZjoCAADAcrbSiDL6POhHrOvaTgRM01Q9batrRNndxnmioPJRcRZcL0eH4HsvK5yM6hdrRBlJZxoiAAAArMLK+yPqQhB12tn5iDJ5bmTvG11rbH1+SzSiCKwoimTqpBOD7/WcvvPOYIQOdV3rfEHZEtJ5dNd1qokXasQ4juU14zietbEOAAAAgM/6e2g7DjNZsCyrlTVQRn6zLHPGf+V21WpN0+hl1kPmh8uqXtFGsjhGwq0KlDW/9lkyECy/rZ6bgj5uhK7rJDec19cE23XN+kbW++iH27eTf3VdZwVo27bsuQ0AAAALOflZfHEcq+QaVHV1XUvgTafgkbELnO2ybgAAAID7OLlG7N98liu8bxAAACAASURBVI4n8nyIx9HuuQgAAABwN+fXiAAAAAAwFzQiAAAAALigEQEAAADABY0IAAAAAC7zNOI333zzcmp+97vf7Z0EOAoYAygYw5GhdEDBGNblm2++maERz83PP//84cOHP/3pT3snBPYHYwBlL2P48uXLv//7v3/58iXwcx+Ln3766fX19ccffwzzuF9//fXl5eXXX38N8zjll19+eXl5CfaaD0rgqvrrr7/+0z/903/913+FeVy/n/mN8Cwa8R//+Mfr6+uXL18+fPjw97//fe/kwJ5gDKDsaAwiCw7VHxyNqqq+++67L1++fPvtt7/99tvWj/vy5cv79+9fXl7ev38fUrt/+vRJn/vp06dgz30sAldVMYZ/+7d/+/3vfx/A9vr9zG+cZ9GI3333nWym/fHjxw8fPhynACA8GAMoexmDlQVY4CBWGv71r3/9wx/+sPUTf/311x9//FH8eSG1+x/+8Ie//vWv8sGAK/EagauqlMX79+//+7//O4Dt9fuZ3zhPoRH/8pe//PDDD/rnTz/99Msvv+yYHtgRjAGUHY1BZcGh+oND8cMPP/zlL3/RP7f2HokX59OnTy8vL6Lgw2j3v/3tb99//33f9y8vL1++fHl9ff3HP/4R4LmPReCqqsbw/v373377LYDnci/zu8n5NeKnT59eX1+tAz/YyAUcDYwBlB2NwcqCQ/UHx0GzSPn48ePr6+t2T1Qf3svLS9/3YbS7FYXy3DAe08cifFVVY3h9ff348ePWttfvZH5TOL9GdD5GBb8BgmcAYwBlL2NQWfDbb7+9f/++P1J/cBB8TSD88Y9//J//+Z8tnqhenP6tkw6j3X/55ZeffvpJfr+87UIiumTT5z4WgauqNQYd4N7O9vr9zG8KJ9eIMuV58F+bFjkcEIwBlB2NQWWBasTj9AcH4VoRbJdRdiKgarWttbvzOvpcXImW8FXVGoNqxE0r6S7mN5Eza8TxuR2fPn369ttvP3/+HDhVsAsYAyg7GoPtaVQj9ofpD46AM/PMYYuJaNaL05tOemvtLnNS9c8Xs5vx999//7e//W2j5z4Q4auqYwyqEfvNJkHuZX4TObNG/Pnnn3/++eeRC/785z+zQ96TgDGAsqMxWFlgNeJB+oPdudnrOx3qKjiria1W2067+0Ol9rkBJsA9BOGrqmMMViNuYXv+E8OY33ROqxF1L6Xxy9gh7xnAGEDZ0RgcWeDogCP0B7tju+RrrCsL/I7fdtIbafdB99jL16eiOV7GJyR8VfWNwSmF1SXpLuY3i9NqxCltTc8Oec8BxgDKXsbgywJnotUR+oN9md4Br7iqw9+S0NFqW2h3u1Tl2nNxJYavqr4x+Mtl1l1RtIv5zeKcGnF8RosDO+SdG4wBlB2NwZcF/mT83fuDHZnoNBLWWtM6OHrodNKra/drETrP7Z/bHsJX1UFj8DXiiuupdzG/uZxQI17bN+Ea7JB3YjAGUHY0hsGG3teIu/cHOzJ3xHCVodjBc0221mrXUu4/92ntYZeqOmgMg9vurDUNYBfzm8sJNeJgoY7DDnlnBWMAZUdjGOxUBjf1eE7X0c2lCT7LRxivLUHYVKuNWJT/3P5Z7SF8Vb1mDIMpWWV0exfzu4OzacSRvZTGYYe884ExgLKjMVzrvQZH057QdXR3j7tQP107HHlTrfb9999f28ll8LmfPn368OHD8uc+ELtU1WvGcG0Ue7k97GJ+d3A2jfjhw4eXe/n222/3Tj6sCcYAyo7GcE0WXJtx9Wyuo72K5sOHD4OjmS87abXB5z4hu9jDNWO45uFebg9HM79rPJdRUglBkcPa904FHIJdjOGaRnxC19EI4RvtvboJuqcpBM6lO2ZBLORoZnCs1GzN0XIfdgSNCMqhNCJY0IhgQSMG5lip2Zqj5T7sCBoRlF2M4dqEJLCgEcGCRgzMsVKzNUfLfdgRNCIouxhD+O7nEUEjgiVwLoU/o/VoZnCs1GzN0XIfduTbb7+9tsAQno1djAGNOAU0IlgC51L4CSFHM4NjpWZrjpb7sCMTD3qCZ2AXY0AjTgGNCBY0YmCOlZqtOVruw46gEUFBIx4WNCJY0IiBOVZqtuZouQ87gkYEZRdjuOMwiScEjQgWNGJgjpWarTla7sOOoBFBQSMeFjQiWALn0t2HvtzN0czgWKnZmqPlPuwIGhEUNOJhQSOCBY0YmGOlZmuOlvuwI/TQoOxiDFjgFNCIYEEjBuZYqdmao+U+7Ag9NCi7GMMf/vCHv/71r4Ef+nCgEcGCRgzMsVKzNUfLfdgRNCIouxgDsx2mgEYECxoxMMdKzdYcLfdhR9CIoKARDwsaESyBc+m33357//59yCcezQyOlZqtOVruw46gEUFBIx4WNCJY0IiBOVZqtuZouQ87wg7GoOxiDGjEKaARwYJGDMyxUrM1R8t92BE0Iii7GMP79+9/++23wA99ONCIYEEjBuZYqdmao+U+7AgaERQ04mFBI4IlcC59+vTpX/7lX0I+8WhmcKzUbM3Rch92BI0IChrxsKARwXJ6eziaGRwrNVtztNyHHUEjgoJGPCyn1wS7P/exOL09HM0MjpWarTla7sOO/PnPf/7Tn/60dyrgEIQ3hi9fvvzrv/7r//7v/4Z86CNyek2w+3Mfi9Pbw9HM4Fip2Zqj5T7syF/+8pcffvhh71TAIQhvDL/88su33377448/hnzoI3J6TbD7cx+L09vD0czgWKnZmqPlPuwIGhGUwMbw6dOn9+/ff/ny5fX19ePHj8Ge+4gEbrS/fPny//7f//v8+XPIh8pzf/e734V/7sNxbnvYy/xGeC7NhEYEBY0ISmBj0JOa//73v3/48CHYcx+RwI32Xv7dX3755fe//z1+5Zuc2x5+/fXX19fXP/7xj2EeN4Xn0kxoRFDQiKCENIa//e1v33//vf7JeT/jhGy09/Lv4leezont4cuXL+/fv//06dOh2oTn0kxoRFCcrhqemWDGIP3NP/7xDw359OnTt99+e6jRpUMRstHey7+LX3k6J7aHX3/9VRyWnz9/fn19PcimB8+lmdCIoFRV9d133+2dCjgEwYzhl19++emnn5xA7RvAJ1ijvZd/F7/yLM5qD+pElD+P0z09l2ZCI4JynEoIuxPGGHToyv8Xg4zXCNNo7+Xfxa88l7Pag/+h+NNPP/3yyy8bPW46z6WZ0IigoBFBCWMMOnTlwyDjNcI02nv5d/Erz+WU9uA4ETXww4cPu386PpdmQiOCgkYEJYAx3JzyyCDjIAEa7b38u/iV7+CU9nBNff7jH/94fX0dTEkwnkszoRFB+fjx4+vr696pgEMQwBg+fPjw97//feSC33777f3795um4REJ0Gjv5d/Fr3wH57OHQSeisrtT+bk0ExoRFLpkUAIYw822fnB4C7ZutPfy7+JXvo/z2cPNluG7776rqmrFJ87iuTQTGhEUNCIoYYxhZKBqZHjrydm60d7Lv4tf+T7OZw/ffvutXRwT4ImzeC7NhEYEhSYYlDDGMDJQNTK89eRs3Wjv5d/Fr3wf57OHg1vCc2kmNCIoaERQghnD4EAV27mPEKDR3su/i1/5Dk5pD0e2hOfSTGhEUD5//vzNN9/snQo4BMGMwd9lzd+JDSwBGu29/Lv4le/glPZwZEt4Ls2ERgQL9gBKMGNwhpYYUhwnTLns5d/FrzyXs9rDYS3hufpINAFYsAdQQhqDDi3tPpB0fMKUy17+XfzKczmrPRzWEp6rj0QTgAV7ACWkMejQ0u4DScfn9P5d/MqzOLE9HNMSnquPRBOABXsAJbAx/PDDDz/88MPuA0nH5xn8u/iVp3NuezigJfxfdr++vr7A47PWcRHYwzlYxR4whi3453/+58BPfMSDhV6ewL+LX3k657aHA1rC/2V3yKyH7VirHLGHc7BKOWIM5+ARyzFwmvfy7/7www//8R//gV/5Jqe3h6ONMKARzwYaESxoRFCWl+MzeJTD+3fDP5fhpumEt4dDjTCgEc/GWuWIPZyDVcoRYzgHy8sRSzgHdBNgGSlHNOLZoPKDBY0IChoRBLoJsKARnwgqP1jQiKCgEUGgmwALGvGJoPKDBY0IChoRBLoJsDywRsyyLI7jNE2zLNs7LY/BKSt/13VZlmVZVlVV3/f29yzato3juOu6kWuqqorjuK5rJ7woijRNL5eL/68jg0YUiqKwNnO3CT00aEQQTtlNwN08qkaMoqgsy77v67q+XC4rxrywb5BUHZOzVv48z6Mokt9VVaVpekckYkhN04xfFkXRNSGIRnxcoihSE5KvjvHrz6cg0YgO45+LPm3bbpSSwJy1m4D7eEiNKB5E++dafXPTNAu9kjZhR+Oslb9pGv1OWNEYBkEjbhHJ7kRRdLlctO7fbASOXM3vA41oieN4ekdQlmUcx/qN8eictZtYTtM08Rs3vQmn4SE14uVyKYpi8F/OsFGe52madl2X53me54NXiudPnAdRFEnrYC+WK/WJcmVZllVVOUNUSZJIT3PM4e8TV37VZ7albttWykLrs/wpjsY8z7VM8zyX4nOilXDrNBKNKCbheA4GNaIY3jF9DGhEJY7joijsl4b8EBOyrYE0KVrN53qbDgsa0XK5XGZpPuk7tktPSE7cTSxEHQRVVZ2muG/yqBpx0GGTJIm4kZIkER0gA4hxHFdVlSSJioA0TfM8r+va1u26rtM0TdO0rmtVFVEUFUVR13We5+o8SNM0iiJRipfLRRSASAcxo2P6k05c+fW7X8uoLEsti8vlIjpPijiKoiRJ8jx/eXmRkmqaxkqEvu/bthUzE3NS0SCDkmVZ5nnuTHJwzLJtW7lSUnLA7040oiJmI5W6f9OIdV1L0yElKNW8aRqxqMNW8/tAIyoyX2XWFCY04nbxHATp3PXPKIrON+FkkPNoRKcIVbpdLhf51rczF20BWyeB7wKM41jicdwMOulNRKT8ruv6yC3FiSu/TEmsqkpLsyxLKSPRanYYUU3C6jZnYqssYZHfIivlty3uKIqs8ThmKTJUH+o7KXcHjahIWcsnn85HdFoJW4LrzoE+AmhERdwEtjrL8GJRFHEcWzPQwcckSY7c8s/ixN3EEqyPqe/7KIrSNE2SRKYZdF0nvw/oC1jIeTSi0w1r/62tuRUBIiidPr4f0oiylFUck1YjWseS/kYj7oVMSUySxFbRNE3Fv+hMNRssI3/xk3iOJRKrEdX2bNH3nlmKgUkXIj9WetfVQCMqWjp2qwT9zuw980AjbhHDQRBjsFMSpfSls9BvPx1qkMAjt/yzOHE3sQSntVfHgY5VijPCURQn4CE1olNaRVHIWhPbDau/Z1AjihtJ9J+t245GtK2AvR2NuEo863K5XGzPbT/7HD/iFI1o3dL2llka8ciL3Hs0okGbjqqq9IvCrnNHIwaI4SBIHbejB7Zh145G3EgaeOSWfxbn7ibuZlwjHnPG+So8pEZ0hpWlxtrFraLt5PegRrRq0jb36owU3WkfZKe1jWhEia1t2wN+T5y78sssQ/3zcrmoRJMy0rKbohF1SqveIrHZ8Ue1B/3TakTr2LaD4McBjajYBsHObdVSs3NSe+NivG+jpQOCRhRkMqJMLrd9h//FOOXL8xE5dzdxNzKUrH/KWHO/we57R+MhNWL/puJlHFA7ZpkvItVVAmVhgTT0MliszkW50kqB/k1cOi4oWcgia5Zlm2UZRuy6TtY32b2XRakccGCxP3vlt2vP+7cPCfnoj+NYJKP8KeF2Rapugq1SsmkauUyM4XK5iJ1IbI7lyDJnucYqCblYrDRMJswCjSioqcifsl+B/Jbic6Yi9W/TGGRFS+DUbgQaUUjTVJ3H6kge1IjSLziBJ+Dc3cTd+AsedB0kGvG4hT04P3T6pNFrVzp+47lu5MO6nZ+w8i+cQTzRQsY5tz08kDHcx7XiO2yx3gcaUXDWrop/YVAjyrQE+dRUr8EeSV6ZJ+wmJqKDSHbvGzTijYvggaDygwWNCAoasX/Tf+JFlp2xZS2CLEkpy1K2O4jjWGaeiG9JnM1pmp7DqUw3MYIuY5c/ZUBJBhsPPvv8btCITwSVHyxoRFDQiCDQTYAFjfhEUPnBgkYEBY0IAt0EWNCITwSVHyxoRFDQiCDQTYAFjfhEUPnBgkYEBY0IAt0EWNCITwSVHyxoRFDQiCDQTYAFjfhEUPnBgkYEBY0IAt0EWNCITwSVHyxoRFDQiCDQTYBlkkZ89+7dCzw+7969W8VosIdzsIo9YAznYLkxvKAJTsFa5Yg9nIORcsSPeDao/GBZpRwxhnOwvBz5WjgHuBLAMmIPaMSzsVY5Yg/nYJVyxBjOwfJyxBLOAd0EWEbKEY14Nqj8YEEjgoJGBIFuAixBNWLbtmVZ6lmHgamqauGJinVdZ1lWFMVaSQoMlX8Jclrr3qlYk3NrxK7r6rpuDHun6P9omuZoZ/uiEUGgmwDLDn7Ey+WyYmzTKctSDmtfQpZlyyPZCyq/T9d1E6+MoijP800TE5hza8S+76Mo0vJN03TfxFjSNI3jeO9UfAUaEQS6CbA8kUYUL+DCSNCIK8ZzBB7XK7yc02tER4edzA28LltrxKqq8jyPomhibDLss1317LpOBoXKslzFfbAiTdPsNdrWh+omyrKc9aX0zPZQFMWO6dlQI7ZtW9e1H+5oRHuNM/7SNM3EZn2Kg0c1op+qwaGowUA04s14pBD9smuaxsn5rus0h52sHrScQab79uq6dpKU57lfmmqEThqqqnKcjpLmQXOSB01/i10IphGn5INcs26V1x7opre4bduu69q2dezwmjEMpnN6M1LXtT/W7F95rSptQRg/4kQHgQjK3usdp3v9p5BlmRZrXdfH+VxsmmZHN3MwV0Jd1xO/GZ7cHoqi2HEYZKlG7LoujmOZ59e2bZIkUmxpmlZVVdd1nufOLEDbTHRdp1biWEySJNKSTsmdy+Vys0Truk6SJM/zuq7jONZmV5NqHzQY2KMRb8XTNE0URVLZJA8lXEpTikByvizLOI6rqoqiSOqAXCw3ShW9WaZN01wul5s9aNu2kiR5nN4rz7V9sKRfnp6mqZa+hmucRVFYc9Jwtds4jnd0BkwhgEaUQpQyFQHUdZ1mrBa6tANZlklncLPKTyz3OI7F6mydrapK7pVUSXuVJEmapuJF0NK8ZgyDTZMYrRiDSr3BwKZp0jR1mhG/wblWlTbiUBrR9taK/5G5EOcph5qxuiMH1IjYw47M0IhVVWVfI81WURSi8e1EbG3p/BFep5mw/av+ViUhUa1SWiJQ5Le27/oW+oLXAgU0osYjn3QW6W6t6Je8attW1Z7WQ/2vFLrzp7DWx3Rd1/qhYr9YBqcf2HmH9jvV0Yi2O/dfasXEb8eKGnHQGOSjUa+0GRJFkWh0+1/NbfsJtwTViP6XnuNCzrJMDSPPc02YbwzXmiZ9hHVGDgb2XjNyrcHxq9J27KURm6axr9+/aeiiKJqmUZPQj0kbOIIV5dewmkDLVD4exK+sIw8y0ClFo1dKochT8jy3r1CWZZ7n/qiFfFLaQBnWtIFt2w5+JkkVs1+z8qc111XYVyNKJtuyW24PbdtOaY0H7UGUqLRm8qPve3muKh9NkpSauCRs6U+3Bz/w2krZI9jDjLFmKQCbX5JN8v19h0aUxl0GX/wY7sO2s2qdjunIn4OBAhrxZjyaXTbDpeYXRSEl21/XiKIeBEeWLUG8eo4zZrDrvdaa+BpR79XGRcx1PJ7jsLUfUd2H0s7aim/ddYJTy1Yp95Gx5iiK7NeCM8w0IvSvNU0yucppnQcDe68ZuZYVg1VpI9bSiCKtLDbzncZfxwocHT9oALOsQsYoxq/JskxKUNy9Gp4kidiGJkkHPSRQLUfaNPGUq9zRwTTnc0L/q8/SK50hVF88aVR2XE5Hz9aVBet2E1L3LXqB/5paEM7w40J7mK4RfXuQIQ6ZFqUKR0YV5EPCftBKZXcGQ6bbw2BgP6Q6DmIPMzRikiQiY+VPKRLJl/v8iFv0r2jEvTSi3fBolh9xXdq2dWZJr64R+76XT948z48/VBFAI16rLEVRyMeAhmyqEQUrVpIksT7OWRpx5ImyLMN3GDiBaETh2qDBco04BdsWOZ68OI7zPNeU2/y3gkP0hI3TOhSt8LXGptGqeui/Htl0xJPjr9J/bWQee2lE+4Hdm9fs97YHWV7jOP71Als6zpdnP98e/MDeay6OYw8zNKI4ftXK7VeRJHdKM9G2rf0U05xt2/bmwNOUjQ8dt5bk8uAoz7Whnx6NOCEe31LtV5HULulIrvkR7YDCzcRMKXr7UTWoBqyNLfQjSu9Se+tjDsjWGtH5fNeSki9y57/OSPTN504pdxtn13V6i7TUtpFxVL6G+8Yw2DTZ4lbDGAzUx00Za35EjTiO0/hLnyrY0eHAmmDwX1avOPlvNaITQ5Zl4tqR4UXt9eUFnaEMaS58T7MjnpynbP0JsddYc13X4sFVe9B/7W4PuujCv3L8k3KWPQwG9kPNxUHsYd66ZqdZlxEZkWIytb9/m+pxuVxs65llWZIkkgtWhlu37fiju667XC43+wwxQX8lijTQvhb0A+VDZ635keEJUPml2usAilSJqqpEJsrkG+mDZR6CePLtFJy6rmVYR+rVeErKsrxcLjfno+jwQe1NTZOEaRstA9xVVfmLsmX6i4bbCp+mqVhp/TZ3JMuyOI4P/jkRZs2K5rDUGukXJRtlTYZcKdlb1/WUgZIp5S6mVVVV0zTS+MpDdZFgWZaq+9VC7BLCa8bgN01itGJg2dskocHA/koz4jc4g1VpO3bRiNe+x3bRBE5x2DHEWRpxJJGyqY2jAGRe1shYc/b1fM3H8iOO4GvEa2+xrz3IGOk1zTr4UTcxkYP24AeOfFL2j+JH7Idm/EwXUss9LrPWwB/fwbMR++6POEtYTy+j6UV/Lc4V7cFxXB18SmKwvW+m5LDk1RblPoW1+pvB9D9Eg7OXRrRjdho+WBw6bDfFhSzTxcavcZ6iil8GvuTLVkLst6Ud6fPTae+SSPqvtzqSryC9XW905sBY8WTXfsmEGeeWc2jE/mtP04r2YDNthGv2oMtbbcHpQ2Winfz2G/zp9nDNSHpPIx7HHrbaQxv2gj20t6Z+27inNmseD8tx9tBWn9/yqO5DxzqelgB7aIs3VxYIa7jM9FI3c/82fdl2w/ZiZwXxNW4ud+u6Tp8ia+l0mw6ZTC9eZO2/ZRjU9tY6Tc1Jp4Rbd7h4hmR1i6MLRXHa6cvin5aMsrNu5DL7dB2dFzfzWl9NwfbQ1te0HjupibYyLrcHX4z6DNqDbKytww464ixmIPYgITKVRUcYnDedYg/XjERutyul+sPYAxrxbKARwXIcjQi7w1l8IwSYD3oc6CZusvow95FBIz4RVH6woBFBQSOOIJPmDz4ssBZ0E+Oox3Hd6S6HBY34RFD5wYJGBAWNCALdBFjQiE8ElR8saERQ0Igg0E2ABY34RFD5wYJGBAWNCALdBFjQiE8ElR8saERQ0Igg0E2AZZJGfPfu3Qs8Pu/evVvFaLCHc7CKPWAM52C5MbygCU7BWuWIPZyDkXLEj3g2qPxgWaUcMYZzsLwc747h5l5ucjbPfZHPRXan08PTjrOWWfbPC/CgfbuJKa8ZzB5kf8SiKMQeDrX/0RHsAY14NtCIYEEjgrKjRrSn3o1cc+1f68o4uxWiSIQVI19CMGG0u0ac8poj12x3ApM9tXV3jmAPJ9eIsmv5lGOdTgMacYTpx3ydhsfSiHLIu5z5HuaJT8WOGnEKI93hugfkONtlH8ePGIyH6Cau2UPTNMEO9X4SVtOITdM8xLGkQpqm8rUx8STHc/AQlV+YYkvX2oK2bed+7akNyJjCrHsflwfSiE3T2MNSH6ipeRQ21YhyUploL3sWrYT7Q2ZVVclRlnpwn5yPJ+O/epkckZem6cTeRw8rG8FqRD1UTb5M2rbtuk5+9G+nC0pS9en2EE7nmDhJvJNOyRanKfMD27bN89zvqmRkXOMUx6efUbMI0E3I66ibRpvra6850R6qqoqiSM51vOlNbNt2ih/OFoTmsyjRruvEMORZ8lx7nHc/3x7khD3HHvzAifbQNI38aU8CnMsKGlFklpxIPWXUYHesUfZeyZ2YAJU/z3M9GVMmTNzh+W/b9uXl5eZxq4NHcEqlvVwu0x+Xpqk1Wr4Z1oqkKAotI+m97m4cnNY8zEScp2ItjSgqyqItQBzH0inqubeCU1u1V86yTBtn5+hkvXjWKXl6KPMIdV3HcZy9oeFyXnP/9fekRmiP05UZbEVR2GOCtSVMkkRrgQbaI3oHA/uhQ4c1KtVb/fWMms663YTIKYv8V462z/O867rL5aJG4r/mLHuYfkredI0op3KLyJFA6X3kUG9VhHKqsnxIWCE03R7UtJIk0WcNBg5m1KA9XC4XUTt3y8R7NKLTiYqil993uHBGWOjRuXa7bxnBJkTvy0Ya0Wmj1XDbtr1bfE9x6Y+U2nSN2Lat05LKt9fE2x+aLTSi36tpgzClOg+Wu7SwNuR5vuuCEUAjXi6XwY8Ep7Zqvbb6z1Z2+3v1k5Q1wq7rrNWJpBBN4z/aCg7REzZOa66ijeS3/YRWyx8M7D1N4Pir9F/XMmo6wTTi4Ee+Hz7LHlY/SVkjtInv+74sS9GOg4+2pTPLHvQatYHBwH6+PdxdU5ZqRH/i5FozRhdW/mu3N03jO4qslj8xwTSifs3cjOqatUwcObr2r+kacVBt8M1wdySORizLUlurmxrRH2QR/OLwlT0sJMB8xGvVyqmt6rCxdTO8Ruy91snp7J1HW43omLE4wHSttJqu9J5xHFsxOhjYe5rAeYo+/Wga8RrXCs7XiLPsYTuN6OO4w53VLfp20+1BPNNJkjhD0n5gP98edtOIjkNeESkmeSEfQ03TiFNBzkfXzBVvrcRj3fhpmsplVnHrEIDUoJdbGAAAIABJREFUHzldW24XT+/I7cKgJljdsI5JGI2YpqmUjvON5RSxlLvMEJIRaikC+dPpNsRsBP22lmZU4nTaU18jOpajDDajaMS7I3E0otRZ+VrQKi/TrWzTIVOLxE9TlqXjTXzmMgrGcTRi9rb1jG2od9GI/dcyMcsyO4Y4SyOO9C9t2/rdqB/oawKbP4f1I15jukacZQ9ba0RtmmS46dqjZQLltSSNJ1LmaDkqxQ+caw8hNKIIrzRNoyiSH9rW+zcPFqHqgP7rGqVXjnyl9V87Xe3t6q+a0nYMFs+1tzgZ61Z+1eVqDzqVW0pKy8WO3jr5r2ORZVla3+GU4acoirRWOM2K3+volY7PeLAZtYZ6YlbUiIPGoKMzUjqiEa0L0HEHXms6B8to1pRTuMlxNGKapnEci4tBq+o1TaDjQlOWrTgzjwdxOg7bcHVdp41b//UooTO26JixvUsicSLvr3SITo9mWzmnHmlKzqcRZ9mD+oBujlpMXK7qlKadfdh/LT9Ey8rvJElUTU60h7qurTtMZ1v6gfrnLHs4lh/RVp7e+IoHy1XWtfm+vcFXknVD0hVpAnzdee32Hj/iBvH4+Sway3qDZHKPLGJwNOLgI3wFUFVVURRJkujjbHE70V6TmP3Xtbq/0ow+iY8qjB+xf2slpAG99r3bz9SIT1JGwdhUI8qKVBmbs83CYLj0HdI7ysQVGX4V+5GVkTYSWfowZR78lG8/HeaSjknsuSgKmXYvo2F2tYTjKNFpao5GkXAnnTISIqtWneERJ7CqKhl1KctSXZsSKMNomp8jGTWRABpRUi65Zz21g695nz1MWZx0rfdRZKBSSlNsoKoqWX4nqVLr7U0rZ0t/uj2Ip1B6SVugfuC1jPLtQZInmSO95x1TAZdqRFFs9r8yZ9n5FBvRiP2bX91Ob++v+BF9l+Fcjch8xNXjGdSINlCqtORwdmXahIMv8vRj6z6NKJpV9yzQfzEfcd1IBjVibxzGIwYwXSMyH3F1DrI/otM+H7llXn2Y+yAcaou0B7KHs3qa7tGItmK0bes4POu6dlaVqz645kf0A3tv7rDzoFka0dHOfpeDJlgSj/8FL6MD+qddtH+HRrSfUFOWtvVDGtG2LNYeWNe8biTOZ54td6m/19bf9cY2HOcH65oDcBCN2L/tGyeemyNvVioex/Ntqnwojdg/iD2ox3HdU16OwAr7I2oXLls1SqCOKNnJm7KlkP6WH+Lj6d9y2cYsHb/d+UluFw+qdBt2Y6rY7MLj366wP+LW8YjTW/+0FiLrS2yZDsZgRZ795JCNQ6X41MnvzG3oPY1oHZn+amv2R9woEqsRe6PjNcOdqqdthV9nnW8AnIircxyNCPtyNI0I+7LOOStt2/qrEWXuoAbaHert7uQyAig7TPrROv4DXdwkp3L1ph+y8V+7XdFe6nmcRv2uld8ag5aXjPw6e+IPhktROk4m8S5bG5Mr9XZnVKKqqmsfA6o5iqJ4kg+GfnuNKFVb/7TFUde1s0pJbxl0Fdh6qockwYqgEUFAI4Ll2c9rPs4R3QGg8o/Aec07RjKFmvOatwSNCALdBFieVyM+IVR+sDyWRoRNQSOCQDcBFjTiE0HlBwsaEZTl5fju3bsXeHzevXu3ikVhD+dgxB7QiGdjrXLEHs7BKuWIMZyD5eWIJZwDugmwjJQjGvFsUPnBgkYEBY0IAt0EWNCIXyFLFs66cIHKP5dzL2RBI84CY9g6hono/hVnLYt9OXI3wcK18KymEQ+7+/l0dE+NiSc5zmX5pioju/lMIWTlP4c9yA85mGv1+Jfvvnttp5iJBNOIGMNNTmAMU2KY+5p+m9k0jW5xulFZPDkhu4lZUs8WvT27GTZlHY3Ytu3Ly8tDS/utN9aecjrkOPLx5B9kPJ1glb8oiiXpPAJbb6xtT9W8D9lycolRhdGIGMNNzmEMU7qJWZZQ1/XNM7GeZ8f7YITpJuTwpLqu8zyfqPbYSH8X7tGIg9Vy+gfivocXXfPDBTigb5UID6gRr52LPTG2fe1h0A8R4IC+VQ57XfjhsYVGxBju4BzGcLObKMvSHss5BafN9E9lfKpDEMIQoJtw6tSUnpEDOfdiNY048VMgz/Md3Y1d1w2ao3NwuDD9+PD7PoPu41E0opMn1w7GmG4P04/WmH7ltb55sPWZXnxT7OEcssCPBGNweB5juNlNyAGts97UyefBbF/9Y/7JCdBNZFlmBV8URVpNrlVYv5T9jzfYghU0oswSsNqlaZooiuSU3iRJ5Ou86zo5Z1nO57YOgzRNsyzLskxPaSvLUk5nzvM8jmM5Klvuzd64dqXEqZepLUrzFEWRP4tlsBvQ9NwkjuMpxirJc06CL8vSvtFIoHB8jVhVVZqmtruqqkrfXc9Nnm4PYmBxHMuPKIrkqD21MT2ze/BKTaRjD2VZpmkq9umU/sKuaIo9yBnTag8aPssedpcFfiQYg3/lkxjDFI1oz14f7Cb6t+ngUjpoxPAE6CZsZez7Po7juq6lrciyTCzcMWaKfi9maERpRqXFlx9WaTnaxRqBLUhfeMVxrJ8O9krpMPq+b5pGWu0sy3TKapqm2pQPXqn/ddyBg1Y1KAcHJdogbdtOcVdcLhddEyPJsF9C+nsw0EYyJUmDrFv5pT+29qD57HdX+qfjMpluD9Kd9H2v5/xaG7OP86+8Zg/X/DeDRuK0ayNMsQc716ooCjHgufawuyzoMYZbPI8xjHcTbdtKtjul43cT1wrd/9OPBJYToJtwikwrvlQE+a19vTBY9I8+0fkhWG2s2SktR+3p78FuQH9HUaQuBOt/9u+1Dbp/pfNEa22DprbQjzgR+2jJLttd9W+t52Cgc+N9BBtr9rsrffcpskB/O/bgPOWaXd28Uu1hlixY95vVPlqza6497C4L/Egwhjs4hzGMdxMyn0yGfQbdB/rZbN8CP2J49vIj9n1f1/U1pztFvxf7a0Rp+gXHbpxHXNOIg8tNZARK4rTf8VvMR5zIoEb0X3kw0LnxPh5CI063h2t2Nd0eNpqCNoVrsmCWPewuC/xIMIY7OIcxjHcT+qddxO13E85boBHDs8t8RPn8G5mYy3zEvbhHIw6W4lyNOOgSsPOQxjVinudqZIPdgJV3gxrRWUE53uusguMU6c240s1A5YAa0V8qfocsuMMeHBvTEp9uDzYx1kgCL2WV6Wj9fHvYXRb4kWAMd3AOYxjvJvTPpmnssLJeoL9HNCLrmgMQoJtw6tS1ySfO7axr3oXV9tD25yNqO+vMWBcj0LmMRVFIm9i2rTMo7MzjkZkN/dDKeedKaYakJ/CnNXRdV7/t1K8s2R9RZlpMuUyTpK+vM7fsEwcDhQNqRB+nu+q6zrYCNq+m24Pf/8nyo/5tYcTIleP20A9terJkS7wp9mBHVeyzZtnD7rJgSiQYw5MYw0gMTqHozOzBbiJNU2mKZaXR+BIi9kdcnTDdRJqm8kHoDA+OFKhT9DgRw7CCRuy6TkZtmqaRCm9FmOz8bDWcfx5A27bOYkaN0DbNYkxVVdlWY/BKwblS0dnrDtr4zv029RXnNWSrW+fiuq79JPmBbduOvOwUwlR+m04NURtwBg37CfbgG5ggcn/KlcKgPYwcXaNtUFEUsz5Yp9tDVVW+IploDzpaOviyUwigETGG5zGGkRjqutaCFgOQpTzXugk1Az/rbOM8tyxgCsFcCVLKWsR+W+Ffr0Wvh6LB1jzSec3OSuotkPiXnHd3ZI58EOcdWCfERnBEb5hIloMxLITzmkE4cjdRc15zcB5JI9qPUbiDI1f+uYgTYt9jOR6d02hEjGE5D6QRYVPO1E3Ach5JI8JCqPxgOY1GhOWgEUGgmwALGvGJoPKDBY0IChoRBLoJsKARnwgqP1jQiKCgEUGgmwDLqTSirHruvS0tQHi2yq+L5rCHQZ5KI2IM46ARpyNrZc66YubZuonlPO1qtj01Ytd1sqXW9HnobdvabVpX31h1cGeKWTRNk+f5jht6PW7llw1QZm2IVZalltcx7UE2jN1xEf2DakSMYQvCaMR1T67aBd11pW3bLRrz5bv5jGzhNIWQ3cQ57EF+2EZmRZYvxfM3FJvFPRoxWLnOOqzd2WAzy7J101mW5fKuZeE+twvZqPIH26dq1v7hD2EPWZbteErEFhoRY7ibRzeGmzG0bfvy8vLQe1MsOWphCss7CNkX5iGOWiiKYkk6j8CS3fWnYA+uvA/Zknmj3fWvasRgnrDpGtE/cHn1wxxHjgmaFcn5NGKwjm16g+K33ce0h0eXBX4kGMPdPLoxTOkmpjtF9t3J6JofLvCRrXdzQI04aNuPYg+DfrjAp3QuieQQGnFQzEmgPRFV/2Vb7WtbYg5qxMFzC5yj7oXplc055WUQLS3/QXLIgRM4+FLPoxH9d5dt9PsF9jDY8A1eOVj00+1hypS1ufYwGPjossCPBGNw/vU8xjClm5jovs3zfEd3Y9d1g+bheyL6vk+SZOJLTbzsqTSikyfXRiGm28P0cYzpV14TaoNe5OnFN8UeTqIR5YzFuq7tqdvyu67rPM8l15xzWu3pnFVVyZWOWnc0osw4lIUpzjsv7AbiOL7pV5AzVcVY9bxXm36bLTK1SArYdgbPoBG16O10Us0l7QjvsAen4ZNxHzE8p6wX2sPlcrk5oWeWPQwG9o8vC/xIMIanNYbxbkJmY9tSa5omiqKiKLIsS5JEylcOVIzjWErcNp5pmkoWqeuhLEs5X0d6mSzLRN7JCJ21Lv9KiVMv0yKWQ8Pl+G/H5AY1waB7YpApvYxcJklKkkRfXyYzOBYyGCgcXyPKegPbG1ZVpe+ulWi6PYiBxXEsP0Q8WBvTc9oGr9REOvZQlmWapmKf40eHjwQOMlF16Gvai2fZQziNKJVH6o/8kCyzmaK/pwdqU+JLZkcjyiml8tupvYMFE0XRig5q6Qbktx5Rr5nQv+VP7x1gb9N2Jo0oFU/qs/zous5xv8u72wyxpTzXHpyGT54ov51e/FD2MBior/DQsqDHGN6ShzFIDNKnSvcvP2xb7ZSabeFtMfnCS87j9q8U9dD3fdM0krFZlqnrV+T4yJX6X8cdOGgzg3JweqnJEdU3L7tcLromRpJh65H+Hgy0kUxJ0iDrdhMizqw9aD77vaH9UHSqxkR7EEXYm30MrI3Zx/lXXrOHa868aw3LxG+GKfYg35zyuygKMeC59rC/H1FaW0EyyLaY/S2NKN7BoihELzsx+5aRJIn/MTfo8F93pog1FM30QY+FY9Bn1YiKLTX1GMnp7NJU2c+ym7JgxB6chq9pmjiOBxe/L/zCm8J0exhxaz26LPAjwRie1himjDU7pTZY6P0VTaC/rb6Poshp+e29tlz8K50n2kkFg+ax0I84EftorTL2uWJdg4HOjfcRbKzZ7w313adoRP3t2IPzlGt2dfNKtYdZGjFAwzLXHvbXiH6mOMMoIxpRPpVETd/0Iwqy44DzUDvMPZKwJaARr8XjyAK/OlnzHZcF4/Yw2PBVVZUkiWOTh/pmOLEs8CPBGJ7WGDbViNYTca119e+9ZmAaIsOREqd16gyax8L5iBMZ1Ij+K4/0Mv0TaMTp9nDNrqbbw0bzEadwTSPOsocdNKI/a1BzU7PMpsnXiG3bygUyRCWBkh22ojoa0arA8Q8LScn0PaLqoXUw/jWa1Kqq5CNjcOToScaaFWeFgX1fMRWbIXZ8ba49OA3fyHe/M4rXz7SHKbtJTbeHEw8v+pFgDE9rDFPWKMzViIP+IesqHteIeZ5rQQ9qAtvsD2pExy09LkFWwfGQ9WaQ8WagckCN6Ne4OzTiHfbg2JiW+HR7sImxRhJ4XbO63ubaww4a0UGGzGUXWW1PpX135qVmWZYkiTSFMim4fxPv0rDKvO++77uu09mmagEys0HGsv3vOUfUz9rbQqZKjF8jA+iDy1OqqnKae2mbpIDV7HSnoqZpgm0jZwmz8VVRFEmS1HVtyy5NU/H1igFI4HR70E2/rJqP41gy2RcBfd8nSWIzebo9dF13uVxuKoNZ9jAYKG6JWRvFr0uAPbQxhucxhikx+PMRtVyc5QuSObZDkYxt29b5HnDaUukmeq8L96+U+QmDp+/Ixb7vYMn+iFN6md6Midt1WjqNzz5xMFA4oEb0cbSLs3DN5tV0e/DFkDYmju/Gv3LcHvqhz8Ul+yNOVx3+s2bZw/4aURj0w0mgFeyDl81qFkccfroDfrb2HrkTE3D3lWHYdwN9CXE+EJfbw8jFWgPn2sMsBX+0Up5OsHNWMIbjs7VGlM9+GcuTLLUiTHS/zWr/cAg5X8cWsUZosz172/vCdpODVwrOlYouZXDQnniu02jKaJWmtigK5+K6rv0k+YGyq9S1l51CmG7CplND1AacEeR+gj34BiaI3J9ypTBoDyNH16iGK4pi+gdDP8ceqqFjnCbagw6d3+2Z2vwsvqqq7Mfi1ogd7PUtfnCOcBafOIRWScYUtMUJ9sQHYvez+DCG43Ca85qdldRbIPHveHDiphyhm1iRAPKj4rzmgxQ2LORklR8WsrtGhONwGo0ok5H2TsUDc6ZuQnzVfBYuAY34RJyp8sNy0IignEYjwkLoJsCCRnwiqPxgQSOCgkYEgW4CLGjEJ4LKDxY0IihoRBDoJsDyvBpRZhyfdd7xIFT+a8hCyN7b8uDcoBEHwRj2iiEMz1m+03m2bkIXAmMPgyzViF3XLdk0cvz2sizzPJ84AVmO7Zr4XLuacruVlUcToAEq/8JNREfsQfbBKstyoj1c2xx/MGa9cvVNUBU9JfY4bK0RMYZrnNIYwmuCrutk07vpixK2Lt/BbUpm0TRNnuezdtpbl8fViLIbzqwO3W7qfEx7kLZrRy1xj0Z0tuRZeHDI4O1d12lJ53k+UeBP3PI++/pkw1mHLkynLMslG5luwUaV3+4s0HXdwoMHBu3BbjicJMnELmFiSpzLNtpc0z9Acne20IgYwxROaQzj3cR2DB7Zeo2ty7csy+U645THcQXb/25Wt/sQ9nDYE5iuasSb5zXP4trB2HdsX35fNzD9xo0Itq9SmIM4t7AHp8WcqOmnpMQ/g9U/YSkwj2UPGMOmPJAxTDmveQuma8QA5TvdYz0eyfk0YjCVM10j+ufTHNMeTqIRZdt0Gy7bpvvxDp6z7Nw+UkMGdyeXOJ1uYHCj+cEymz5a4Wz0P4K/L7yYo5MqPZ02ACE1op/5/tb5wk17qKpqpN6OxDnFHvyDv/0bR5huDzoLyqan99L/cPaAMShPbgxTNOJIAdnjcfVfzvHfg7cPasTBbiJA+Wr/4j9ITrxwAgdf6nk0ov/uWtnvtodBjTh45TX/lB84yJThzbn2MBh4Bo0oo7d5nuubpGkqp5faQyflsEs5vFVLwr/9Wg1p21bOa7YHL4rwlyNo7F0S6BzR2F9pJpzR5xHiOJ7ynSFH9zjnjkdRJE+XzOnfdviUNi7APp9hKr//mv1bccjpk9p2T7SHazVEp6vK4b8SKCU+3R4WNhMT7UEcGPYt5LRiSb8+7hHtAWOwVz6zMYx3E2IDTgHJb+km5MWdQ3v192CHIjgaUWYcSvk6/UiA8hWr1qK0B+wOHuctr59lmS3iZ9CIWvTWQaO5pNX8DntwNOJgwyIstIfL5XJzEGOWPQwG9g+kEWUaUJZl0u6rrrJnpWv+6ktav12WZXqlZq5/+7UaYgtPuxw7IUkvsH2P4yO8phFXX9Pkv4W1dVvkwUa61638RVGIGUhHroXrv6Y97NLm/0R7uFZDbL7pb5vnU+zh2mjm6r2y8xa2IXBs8rHsAWO4g1Maw81uQq+03wATAwc7FMHRiPJJIL8d9RCgfEUTyG/9CLE+CJ1N63yi2LSdSSMOtgzOkK68u80QW8pz7cHRiIMNix+zspc9DAbqKzyGRlRGPr71t3zMFUVhv5ibponjeKRdnq4R1TKsQdhWRj6+Bz/Zfe0/KBwX4r+FJu8cGlFxzHfwNcXo5UtOs3qiPQzWECcPpQTFWetHNWIPVjEMpmEtfFlgv50eVBb4kWAMUzilMYx3E9L1CqLqbPfZ39KIgx2KxuxPUUiSxB8aClC+tii1Cxh0X40U9Jk0ouJ/FIkx1HUtnXhmVu/e1Igj9uBoxMGGxY95PPBuptvDiI/zhBqxbVt1APgyX2YUaSQ3HQD92+fgLI147a0GJ6Vu0RCjEfU17X4Evhy/aQ/+FDTpYGbJgmvvMvjNgCy4OxKMYQqnNIa5SxudMbURjTjeoQzOR5SJSc5DA5QvGvFaPNcM3l6gsn5cI47bw+B8RKdhEQ71zXAqjTjiwJff4l6WEMkjKU47nntzuEHNpes6XyPqWHNsxvi1XtmPyLZtHTvwjWD6UqZ6aCr0tSvnasSt1zBuVPmd73X/NWX6lwRKyzjXHmxOVlUlRTB+pZ3vP8seZu2FNN0e7pAFD2EPGIPy5MYw3k1EUaRDfpr/4yJeS+1ah6KR2Byz5eV/hGxdvo6/XKx6cBjxScaaFWe5iX1fMRWbIXawda49OBpxsGHxn6Ih0+1hSpWcbg+nGmu2yJRSqYfy4S6lJQM6kikyZ1MCZfaoZsG12/u+T5KkKArN1t5MRi6KQgObppFeJ89zmQEj4fIse7vibJWZzdkSKYqiKXs66JoV9W9LtZe3kynqerFMt5++IfDdBNgcdfA15RtO5gllWWb1/UR7kGGpqqrslqdSuFL0Wrtk9EHtQS8esQdnB4RZex9MtAcZ1rTjHVIv5HeapjZVj2UPGIPy5MYwHkNd1/Llb0tNOnsRB6qKsixLkkT6RS21wQ6l6zoxjKIoNDPFqMS77BfH1uWrxll7y1OqqnL6/jzPdc2K9kFN02jfEWxPQUuYPbSlQZDe3K5ZEV+vGIAETrcHWel8uVysmvcbFkuSJDaTp9tD13WXy+WmTJxlD4OBfnMRmA3P4rv2SgtfdVDPzd33UnqI/utt1k/PvhvoL7eH6UU/1x7SNJWWYtYHw6Oz41l8GMPRCHPOykgBWR/P4GWzOo6RggtTvtNjPpqNhewm/HeXEGeobbk9jFxsl4vNKotZCv5opTyd5z2vWb7Lt/46PxSPe8hSAKQR2etbbRc4r/kaGEPgGKqqsoNIW/OE5TudI3QT1rMeADE87GGQ59WIT8gRKj8cBzQiKI94XjNsAd0EWNCITwSVHyxoRFDQiCDQTYAFjfhEUPnBgkYEBY0IAt0EWNCITwSVHyxoRFDQiCDQTYDleTWibIM0fTOkE0Dlv4bsjNBPO6b9NKARB8EY9orhgNBN7B7PcaBlcP815aK5yN4/TdPcvRS8LMvly8jtmqmQ66dmsXrDdMDKv9welueS7Lspv529Mw/FMe0BY9iFAxrD+Da6S3Jy/HbZQnLiDhW2fG8Spps4mgAN0E0srFkj9tC27az9RAdPfLkWc4CWoWka/wzJfblHI97dgut+lbLTwX2RRFG0UMXbDc37mVurB6Msy8EzhZawUeW/e8eK5fbQtu3lclm4Z4Gz+X7IXfGmZ91h7QFjWItHN4bxbmLhwSGDt3ddp9Itz/OJ/cLEw9bCdBNbFOVCAnQTXdctPPJu0B7s7tNJkkxsCiamJEzL4B8guTsrnNfcv+1vPv4kR7Db+jzl9hXxyyBYqey7X3eY85r7+YcU9fvZg+xib0MGT/TeiH3HLAKc19xjDJN5dGOYe17zLAZvtwex+k+cFdWUy/btvIP1HWG6iS3swRGOEzX9lJTs2zIMcgR7mKER7RmsFhsoh+YNPmnwdnu8txNuv0jattUTuq493X5PDPqWpx90U5blxCv9vs0eGqs0TSMROkfHNk3jGIHE1ratnwD917grIkzlH3zN3suQWfbQtq3ag319OfPQXnkzl5wY/BNd+znt13R70IJWqqryHzTdHiRD/JFZffebCQugETGGQU5pDFM0ol8W174BBs9Zdm4f8U0Onq0scTr5PDi3IVg3MbEor9WjLQipEf3Mb5rmPnuQQz6vJWYkzin2EKxl0CmPNj29l/6D2MNUjSgSW05dVI2ic0Tk+EW9MYoiPwv82+UUTrldDit0wm1i5PayLO3h33pOa5qm1nQGC9sZVhghjuMpXw8SoRzRqEeLyvG1dV2ruUivlmWZTKG4XC6SA3rcs0YoZ9dKtHmea30ry1IOo5QTLcddEQEq/+BryjV6Mqk9nXOKPUiccRzLwYl6ZKeE25Gaa7k0Yg/X/BMTs2KiPegBsnEca68vGWXlwnR7kIogxqxHHsuDxPDiOL7ZpW2tETGGQc5qDDc1ol8WmkJ5RwnUNq0oCs18/3bJMT8ZWr5yDLQG6inh9i4JtFcKYbqJiUV5rR5tRBiNOGixUhzSnalQm2gPcqCzn4xBKSIlPt0ewrQM0tzZt5CjqyX9+rjj2IOrEWWwX87Vlh9atH6NstnnHMSZJIm0hho4WCHtvEPrHnM0YpZl2rjog2yE/jSCwcq/7kCPNQj7mehblRS2fxaQ3wLGcaz5YKuKXn9zFu26lV86sCzLpLpmWeYnT3Cq3H32cLlcxN6cjzxnNs9gLo3Yw7Uxi3Xrnu2rbMxL7EH/tEU/+MrXWFEjYgzTOasxjHcTg2WhWWGTbY1HO3X/9msa0Waj6g87O00vsELE0dBhuol+clH2cxTJQsJ0E/5r2nEAm/8T7eGaRhyUIjbPp9hDmJah995CNLT+y9rkEexhxlizk3rHuP365kxLn+XI9TWi3+LrV6md1CzYj4nxBCxBvnjyPHf6sMFuYHAazaBG9H9rVZGPrfFUBZuPOK7L/UyYYg/XXOu+LPB/j9iDbRdGUrgQmYnsF9Aq9jAoC9I0vTmlOsx8RIzB4azGMH0+oh3wEaeydZ80TeM7Pv3bp2hEzQ1rGLbxFE/MoP8mQDfRTy7K/hiaYEk82dBYc//1a8oHhvSedjbIFHsY1IiDUkSctX5UI/YQpmXohzSi/XY6uUZ0slg8vYO3C0vQjSj2AAAJHElEQVQ0opRxWZa+0QxONd0ou8XWb/oRB79+JmpE+UoTd/rN9BxKI65lD1NkwYg9DHYGG9lDnudRFNkXX8UenHYkz3OZenEzPcfRiBjD4IMeyxjmasS2bfUT139TmV6mkdz0BvVvIzazNOK1dwnWTaAR9TXLstQ8H/QrjduDPx9Rhq1nacRr7xKsZTiJRvRbHE29jj4PfvbZXB6cI2hneyz0I8o0psHPPj/m6QuUfLE7iH3TwdZN83ChRpRpiDKn52aqNqr8/hwd5zUHhxfXsoeJrqPp9jBrk4sp9mCvudbu2xVaS2SBDOhMnKeyhUbEGKZfczJjGO8m/LKQ71ubbNGL9nN3sP+2gZpXXdf5GlHHmmOzAlqzLkkSvd1ZFdQH6Sb6uzTi1gtaw3QT/mva1Wlit3PtweZkVVVSBONX2sUfs+xh9ZZBuEMj7mgPM/bQlmnCVVVpcmUyaV3XeZ5rvkdRpJNPbf76t4vS12JWJLwoCg2XGZ392xR1yUSJX2azDk6Ed74tpm90FEXRlB0W5KHyprYIxeGnO3zKDAx/Jyedy6zh9u0kE6T+iBMxyzKZ8j+eqmB7aDuv2fe9+DPE4m1jPcUe7BRdZ5Otuq4vl4uGX8ulcXuwJtrP3Cx3ij3UdS2jGM7r9299mL77dHuozUw1uUUjFHtIkuTmh2aYPbQxBsuJjWF8D+3BspCskM5CW3IZiJdwaaiv3d73fZIkRVFIDBIi49diSBooC+elP5KJkhIuz7K3KwG6ielF2Q/Vo40I0E0MvqY4Auu61h5N9f1Ee6jrWnSeLGiTZw1KEZneoPZglzRcs4etW4b+bYjDjqpLvZDfuv5VOII9zD5nxa9Cg5XqWk2bXgNvYhtE21LYQClva0yrs/Wao/rr6Uo3dw3d/ZyVw9pDmqaquVd8rsOs178D50MzzDcDxnAf5zOG+2K41mQtbDxXyd4w3cTR2LebWG4P04t+rj2EaRmOxjnPa5amv2kafxG7Ig3o1hp8a2SGr2yydfNLZXeNuBdT7GHiNnIHRz6+m6YZnEDjcLSz+MKAMQzCec2DnKObmMXTdhNTOEfLMItzakQYhMoPlufUiDAIGhEEugmwoBGfCCo/WNCIoKARQaCbAAsa8Ymg8oMFjQgKGhEEugmwoBGfCCo/WNCIoKARQaCbAMskjfjNN9+8wOPzzTffrGI02MM5WMUeMIZzsNwYXs6oCWStz/Sd8E7AWuV4PnuQ/Xf6r7dsPD0j5Xi2AgYAgI1YURPITnhN09y9w0hZlst3J7F74M3aDy8kq+vXA2rE5fawPJdk30357eydeShC2gMaEQAAJuH0JXd350mSyC50zsnds4iiaKGzR86v0j9nnasRjLIsnbOFlrORRrQ73s9iuT20bXu5XBZuWOOfKRpsi8TpWRfYHtCIAAAwCacv8feebNv25kaDzgF0VudNuX1F/JNpgp2Qu+9+3RtpRN/xNuU1D2IPcgKKDRk80Xsj9h3aRiMCAMBSbmpEeyCvxQbKoXmD8Q/ebs+2dsKt96VtWz2u7drTrZ9p8KRse0jaOGVZTrzSFzr2BGGlaRqJ0DlHWE5PsFfqKa9+AvRf436pMBpx8DV7L0Nm2UPbtmoP9vXlzEN75c1ccmJwTi0Spn8zTLcHLWilqir/QdPtQTLEH6bXd7+ZMDQiAAAsZVwjiidGDoVSjSJnzjqHdMvR88452oO3y1m9crscdOuE28TI7WVZao8rR4HLob1pmlotMqgJnNHnEeI4nuJkkgjlSFXxFdnjyLXzFomTZZmcz3u5XCQH9LhnjVAOMpZo5URyCS/LUo48TpJE4hlJVQCNOPia/duxYSLQNXyiPUiccRzLwYl6CrOe5G6fPphLI/YwKAena8SJ9iBPl7dQCSgZZbXjdHuQiiDGrOdf928nMMmDbn75oBEBAGAp0pfI8oIsy6RzsrrKF162l7W/ZSBPukYNHNRtdt6hdY85GjHLMvWv6INshP5ss0GNuO6on9UN1v3jiw8RCvKCjr/T8cbFcaz5oPHoj0H/qMO6GlHUTJZlcRzLDz95gnM25n32cLlcxN4ct5kzS28wl0bsYVAOOulZjr6+4+BcYg/6py36wVe+BhoRAACWcnOs2emQHL3id1fOGoVZ432+Rvz/2rvbG0dhKArDWwIF0QQ1uAVaSAd04AqogDqoIwWwP450ZV074KwhX/s+v0YoyQBzJZ8xvk4+/GsaZtu2+/3upnmK33BdM6A+JcY4DMM0TS7QFDNB8bvFixkx/9kikSYU98/qZesR93N5fhNq6uFRU0ueEfOfd+ohhJB3qJy+PnUcx2EY8j/QKfVQzIjjOB523pARAQCtTsmIbsTS07fi26UlI+p55TzPeXwpdiRc1LOipHg4j1ic/6vMiJrM05P9w/P5qIx4Vj3UZMSdeij+z3BRPUzT1Pd9euGn1EP6Fs2Ia+nF4fmQEQEArdxYkg8/Nqjb0+d8qNbiQjtYXCOYLk1rnEfUmrbi7GD+yfV9rHnYLUqvtJha7B42ZkQtQ9QStMOzuigj5ks53WUWnzWfVQ+V84j19fDUXkg19ZC+xv257VenHVotGVHP/d1i0EfIiACAVofZQj0By7JY9FHTgLoEbPzr+17jtJu8yd+uJfnLsrgBWMdjjHY8hGBNIRYf9fnqWih2Rbhpzvr98Pq+Lz4KzF+m3OZmdDThN8+ztd/GGEMIbkS3HgU7nl6dboIeMWsS8Xa7qf9j/6xetoe2u8xt2zS5pTRjd7uyHtI+mHRlqvWs2PFHd2m/HtIS3Z7cU72mHtRBop4VV2y6TLv2+npIly3qLfaBqocQwuFsKBkRANCqMlvkSauYvR4FshM3Lk5HR4UD94IYo2KBWmXP+r3OuX0PObd2Lc8Wztu/Z+Vj62EcR8vc122g/dTl/wP3jL7lfwYyIgCgytd9P69ywLqu7ilnSqPpK/fuvoL2lNHmeYcTWm/PiO9SUw+Vewp+OE1MrutaXGfpkBEBAK2+LhOg6L/NiCgiIwIAWpEJfgMZESkyIgCgFZngN5ARkSIjAgBakQl+AxkRKTIiAKBV13V/8P26rqMeYHbqgYwIAAAAj4wIAAAAj4wIAAAAj4wIAAAA7y/moDNo0soBOAAAAABJRU5ErkJggg==" alt="" width="865" height="478" />
此为java与模式中提供的相关例子,主要用于解析条件判断语句,例如:A and B,A or B ,not A等条件语句,表达式分为几类
1、终结符表达式-常量表达式,主要显示true或者false
2、终结符表达式=-变量表达式,主要是需要判断的条件
3、非终结符表达式-各种运算符,包括:与或非
四、场景代码
1、环境(Context)类定义出从变量到布尔值的一个映射
package interpreter.example; import java.util.HashMap;
import java.util.Map; public class Context { private Map<Variable,Boolean> map = new HashMap<Variable,Boolean>(); public void assign(Variable var , boolean value){
map.put(var, new Boolean(value));
} public boolean lookup(Variable var) throws IllegalArgumentException{
Boolean value = map.get(var);
if(value == null){
throw new IllegalArgumentException();
}
return value.booleanValue();
}
}
2、定义抽象表达式
package interpreter.example;
public abstract class Expression {
/**
* 以环境为准,本方法解释给定的任何一个表达式
*/
public abstract boolean interpret(Context ctx);
/**
* 检验两个表达式在结构上是否相同
*/
public abstract boolean equals(Object obj);
/**
* 返回表达式的hash code
*/
public abstract int hashCode();
/**
* 将表达式转换成字符串
*/
public abstract String toString();
}
3、定义常量表达式
package interpreter.example;
public class Constant extends Expression{ private boolean value; public Constant(boolean value){
this.value = value;
} @Override
public boolean equals(Object obj) { if(obj != null && obj instanceof Constant){
return this.value == ((Constant)obj).value;
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) { return value;
} @Override
public String toString() {
return new Boolean(value).toString();
} }
4、定义变量表达式
package interpreter.example;
public class Variable extends Expression { private String name; public Variable(String name){
this.name = name;
}
@Override
public boolean equals(Object obj) { if(obj != null && obj instanceof Variable)
{
return this.name.equals(
((Variable)obj).name);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public String toString() {
return name;
} @Override
public boolean interpret(Context ctx) {
return ctx.lookup(this);
} }
5、定义逻辑与
package interpreter.example;
public class And extends Expression { private Expression left,right; public And(Expression left , Expression right){
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof And)
{
return left.equals(((And)obj).left) &&
right.equals(((And)obj).right);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) { return left.interpret(ctx) && right.interpret(ctx);
} @Override
public String toString() {
return "(" + left.toString() + " AND " + right.toString() + ")";
} }
6、定义逻辑或
package interpreter.example;
public class Or extends Expression {
private Expression left,right; public Or(Expression left , Expression right){
this.left = left;
this.right = right;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof Or)
{
return this.left.equals(((Or)obj).left) && this.right.equals(((Or)obj).right);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) {
return left.interpret(ctx) || right.interpret(ctx);
} @Override
public String toString() {
return "(" + left.toString() + " OR " + right.toString() + ")";
} }
7、定义逻辑非
package interpreter.example;
public class Not extends Expression { private Expression exp; public Not(Expression exp){
this.exp = exp;
}
@Override
public boolean equals(Object obj) {
if(obj != null && obj instanceof Not)
{
return exp.equals(
((Not)obj).exp);
}
return false;
} @Override
public int hashCode() {
return this.toString().hashCode();
} @Override
public boolean interpret(Context ctx) {
return !exp.interpret(ctx);
} @Override
public String toString() {
return "(Not " + exp.toString() + ")";
} }
8、定义客户端代码
package interpreter.example;
public class Client { public static void main(String[] args) {
Context ctx = new Context();
Variable x = new Variable("x");
Variable y = new Variable("y");
Constant c = new Constant(true);
ctx.assign(x, false);
ctx.assign(y, true); Expression exp = new Or(new And(c,x) , new And(y,new Not(x)));
System.out.println("x=" + x.interpret(ctx));
System.out.println("y=" + y.interpret(ctx));
System.out.println(exp.toString() + "=" + exp.interpret(ctx));
} }
五、总结
解释器模式可以很容易改变和扩展解释方法,但是由于每个文本都需要定义一个类,会导致后期很难管理,因此不太常用。
注:此文代码和案例都是一些经典实现,并无工作体验,以后如果有具体案例再替换