From 6caa741f202c9302f323270f95ab0a143c4a587b Mon Sep 17 00:00:00 2001 From: Caroline DE POURTALES <cdepourt@montana.irit.fr> Date: Mon, 16 May 2022 16:24:12 +0200 Subject: [PATCH] update --- data_retriever.json | 2 +- .../DecisionTree/DecisionTreeComponent.py | 10 +- .../NaiveBayes/NaiveBayesComponent.py | 2 +- .../RandomForest/RandomForestComponent.py | 110 +-- pages/application/RandomForest/utils/data.py | 41 +- .../RandomForest/utils/xgbooster/encode.py | 20 +- .../RandomForest/utils/xgbooster/explain.py | 73 +- .../RandomForest/utils/xgbooster/xgbooster.py | 379 +------- .../RandomForest/utils/xgbrf/encode.py | 21 +- .../RandomForest/utils/xgbrf/tree.py | 90 +- .../RandomForest/utils/xgbrf/xgb_rf.py | 530 +---------- pages/application/RandomForest/utils/xprf.py | 176 ++-- .../pysortn.cpython-38-darwin.so | Bin 23084 -> 0 bytes .../pysortnetwrk.cpython-38-darwin.so | Bin 23116 -> 0 bytes .../temp.macosx-10.9-x86_64-3.8/pysortn.o | Bin 252064 -> 0 bytes .../pysortnetwrk.o | Bin 252080 -> 0 bytes .../RandomForest/utils/xrf/archive/encode.py | 276 ------ .../utils/xrf/archive/pysortnetwrk.cc | 248 ----- .../utils/xrf/archive/pysortnetwrk.so | Bin 23116 -> 0 bytes .../RandomForest/utils/xrf/archive/rfc.py | 636 ------------- .../RandomForest/utils/xrf/archive/setup.py | 14 - .../utils/xrf/archive/sortcard.hh | 298 ------ .../utils/xrf/archive/sortnetwrk.py | 74 -- .../RandomForest/utils/xrf/archive/tree.py | 154 ---- .../RandomForest/utils/xrf/rndmforest.py | 860 +++++++----------- .../RandomForest/utils/xrf/tree.py | 105 +-- utils.py | 17 +- 27 files changed, 698 insertions(+), 3438 deletions(-) delete mode 100755 pages/application/RandomForest/utils/xrf/archive/build/lib.macosx-10.9-x86_64-3.8/pysortn.cpython-38-darwin.so delete mode 100755 pages/application/RandomForest/utils/xrf/archive/build/lib.macosx-10.9-x86_64-3.8/pysortnetwrk.cpython-38-darwin.so delete mode 100644 pages/application/RandomForest/utils/xrf/archive/build/temp.macosx-10.9-x86_64-3.8/pysortn.o delete mode 100644 pages/application/RandomForest/utils/xrf/archive/build/temp.macosx-10.9-x86_64-3.8/pysortnetwrk.o delete mode 100644 pages/application/RandomForest/utils/xrf/archive/encode.py delete mode 100644 pages/application/RandomForest/utils/xrf/archive/pysortnetwrk.cc delete mode 100755 pages/application/RandomForest/utils/xrf/archive/pysortnetwrk.so delete mode 100644 pages/application/RandomForest/utils/xrf/archive/rfc.py delete mode 100644 pages/application/RandomForest/utils/xrf/archive/setup.py delete mode 100644 pages/application/RandomForest/utils/xrf/archive/sortcard.hh delete mode 100644 pages/application/RandomForest/utils/xrf/archive/sortnetwrk.py delete mode 100644 pages/application/RandomForest/utils/xrf/archive/tree.py diff --git a/data_retriever.json b/data_retriever.json index 5ef4f56..c85d663 100644 --- a/data_retriever.json +++ b/data_retriever.json @@ -22,7 +22,7 @@ "ml_type" : "RandomForest", "component" : "RandomForestComponent", "solvers" : ["LIME", "ANCHOR", "SHAP"], - "xtypes" : {"H": "Heuristic", "HV": "Heuristic and validation", "G": "Global"} + "xtypes" : {"S": "Smallest", "NS": "Not smallest"} } ] diff --git a/pages/application/DecisionTree/DecisionTreeComponent.py b/pages/application/DecisionTree/DecisionTreeComponent.py index edb89a4..23dc317 100644 --- a/pages/application/DecisionTree/DecisionTreeComponent.py +++ b/pages/application/DecisionTree/DecisionTreeComponent.py @@ -11,16 +11,16 @@ from pages.application.DecisionTree.utils.dtviz import (visualize, from pages.application.DecisionTree.utils.upload_tree import UploadedDecisionTree -class DecisionTreeComponent(): +class DecisionTreeComponent: - def __init__(self, tree, type_tree='SKL', info=None, type_info=''): + def __init__(self, tree, info=None, type_info=''): if info is not None and '.csv' in type_info: self.categorical = True data = Data(info) fvmap = data.mapping_features() feature_names = data.names[:-1] - self.uploaded_dt = UploadedDecisionTree(tree, type_tree, maxdepth=tree.get_depth(), + self.uploaded_dt = UploadedDecisionTree(tree, "SKL", maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_) self.dt_format, self.map, features_names_mapping = self.uploaded_dt.dump(fvmap, feat_names=feature_names) @@ -38,7 +38,7 @@ class DecisionTreeComponent(): dom = sorted(dom) for j, v in enumerate(dom): fvmap[f'f{i}'][j] = (fid, True, v) - self.uploaded_dt = UploadedDecisionTree(tree, type_tree, maxdepth=tree.get_depth(), + self.uploaded_dt = UploadedDecisionTree(tree, "SKL", maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_) self.dt_format, self.map, features_names_mapping = self.uploaded_dt.dump(fvmap, feat_names=feature_names) @@ -48,7 +48,7 @@ class DecisionTreeComponent(): feature_names = tree.feature_names_in_ except: feature_names = [f'f{i}' for i in range(tree.n_features_in_)] - self.uploaded_dt = UploadedDecisionTree(tree, type_tree, maxdepth=tree.get_depth(), + self.uploaded_dt = UploadedDecisionTree(tree, "SKL", maxdepth=tree.get_depth(), feature_names=feature_names, nb_classes=tree.n_classes_) self.dt_format, self.map, features_names_mapping = self.uploaded_dt.convert_dt(feat_names=feature_names) diff --git a/pages/application/NaiveBayes/NaiveBayesComponent.py b/pages/application/NaiveBayes/NaiveBayesComponent.py index 98c7848..1d0d2ef 100644 --- a/pages/application/NaiveBayes/NaiveBayesComponent.py +++ b/pages/application/NaiveBayes/NaiveBayesComponent.py @@ -11,7 +11,7 @@ import shlex class NaiveBayesComponent(): - def __init__(self, model, type_model='SKL', info=None, type_info=''): + def __init__(self, model, info=None, type_info=''): #Conversion model p=subprocess.Popen(['perl','pages/application/NaiveBayes/utils/cnbc2xlc.pl', model],stdout=subprocess.PIPE) diff --git a/pages/application/RandomForest/RandomForestComponent.py b/pages/application/RandomForest/RandomForestComponent.py index 50dd5d3..25f27d5 100644 --- a/pages/application/RandomForest/RandomForestComponent.py +++ b/pages/application/RandomForest/RandomForestComponent.py @@ -1,83 +1,83 @@ -import base64 +from dash import html +from io import StringIO +import pandas as pd -import dash_bootstrap_components as dbc -import numpy as np -from dash import dcc, html +from sklearn.ensemble import RandomForestClassifier +from sklearn.ensemble._voting import VotingClassifier +from pages.application.RandomForest.utils import xrf +from pages.application.RandomForest.utils.xrf.rndmforest import XRF, RF2001, VotingRF, Dataset +from xgboost import XGBClassifier, XGBRFClassifier -from pages.application.RandomForest.utils.data import Data from pages.application.RandomForest.utils.anchor_wrap import anchor_call from pages.application.RandomForest.utils.lime_wrap import lime_call from pages.application.RandomForest.utils.shap_wrap import shap_call -from pages.application.RandomForest.utils.xgbooster import XGBooster, preprocess_dataset -from pages.application.RandomForest.utils.xgbrf import XGBRandomForest +from pages.application.RandomForest.utils.xgbooster import XGBooster +from pages.application.RandomForest.utils.xgbrf import XGBRandomForest -class RandomForestComponent: - def __init__(self, model, type_model='SKL', info=None, type_info=''): +################################################################# +##################### Questions ################################# +##### Can upload sklearn model or need to translate to xrf ###### +# separate XGBRandomForest and XGBooster # +# data format : avoir un fichier chelou de données là # +# pas adapté, get_dump ? beaucoup de classe, besoin de diagramme de classe # - if info is not None and '.csv' in type_info: - self.data = Data(info) - # Conversion model - if type_model == "RF": - self.random_forest = XGBRandomForest(info, from_model=model) - else: - self.random_forest = XGBooster(info, from_model=model) +class RandomForestComponent: - # self.random_forest.encode(test_on=info) + def __init__(self, model, info=None, type_info=''): - self.map_file = "" + # Conversion model + options = {} + if info is not None and '.csv' in type_info: + self.data = Dataset(info) + self.data.mapping_features() + options["n_classes"] = self.data.num_class + options["feature_names"] = self.data.feature_names + options["n_features"] = self.data.nb_features + if isinstance(model, RandomForestClassifier) or isinstance(model, VotingClassifier) or isinstance(model, + xrf.rndmforest.RF2001): + self.random_forest = XRF(model, self.data) + elif isinstance(model, XGBRFClassifier): + self.random_forest = XGBRandomForest(options, from_model=model) + elif isinstance(model, XGBClassifier): + self.random_forest = XGBooster(options, from_model=model) self.network = html.Div([]) self.explanation = [] - def update_with_explicability(self, instance, enum_feats=None, validation=None, xtype=None, solver=None, ): + def update_with_explicability(self, instance, enum_feats=None, xtype=None, solver=None, ): # Call explanation if not enum_feats and self.data is not None: - enum_feats = len(self.data.names) - 1 + enum_feats = len(self.data.nb_features) - 1 - expl = self.random_forest.explain(instance, - use_lime=lime_call if solver == "lime" else None, - use_anchor=anchor_call if solver == "anchor" else None, - use_shap=shap_call if solver == "shap" else None, - nof_feats=enum_feats) - - if validation: - coex = self.random_forest.validate(instance, expl) - if coex: - # repairing the local explanation - gexpl = self.random_forest.explain(instance, expl_ext=expl, prefer_ext=True) - else: - # an attempt to refine the local explanation further - gexpl = self.random_forest.explain(instance, expl_ext=expl) - - print(expl) + smallest = True if xtype == "S" else False + if isinstance(self.random_forest, XRF): + explanation_result = self.random_forest.explain(instance) + else: + explanation_result = self.random_forest.explain(instance, smallest, solver, + use_lime=lime_call if solver == "LIME" else None, + use_anchor=anchor_call if solver == "ANCHOR" else None, + use_shap=shap_call if solver == "SHAP" else None, + nof_feats=enum_feats) self.explanation = [] list_explanations_path = [] - explanation = {} self.network = html.Div([]) # Creating a clean and nice text component - # instance plotting - self.explanation.append(html.H4("Instance : \n")) - self.explanation.append(html.P(str([str(instance[i]) for i in range(len(instance))]))) - for k in explanation.keys(): - if k != "List of path explanation(s)" and k != "List of path contrastive explanation(s)": - if k in ["List of abductive explanation(s)", "List of contrastive explanation(s)"]: - self.explanation.append(html.H4(k)) - for expl in explanation[k]: - self.explanation.append(html.Hr()) - self.explanation.append(html.P(expl)) - self.explanation.append(html.Hr()) - else: - self.explanation.append(html.P(k + explanation[k])) - else: - list_explanations_path = explanation["List of path explanation(s)"] - list_contrastive_explanations_path = explanation["List of path contrastive explanation(s)"] - - return list_explanations_path, list_contrastive_explanations_path + compt=0 + for sample_expl in explanation_result: + compt+=1 + self.explanation.append(html.H4("Sample{0} : \n".format(compt))) + for k in sample_expl.keys(): + self.explanation.append(html.H5(k)) + self.explanation.append(html.Hr()) + self.explanation.append(html.P(sample_expl[k])) + self.explanation.append(html.Hr()) + + return list_explanations_path, [] diff --git a/pages/application/RandomForest/utils/data.py b/pages/application/RandomForest/utils/data.py index 6c94e3d..d86e8ec 100644 --- a/pages/application/RandomForest/utils/data.py +++ b/pages/application/RandomForest/utils/data.py @@ -26,8 +26,7 @@ class Data(object): Class for representing data (transactions). """ - def __init__(self, filename=None, fpointer=None, mapfile=None, - separator=' ', use_categorical = False): + def __init__(self, file=None, mapfile=None, separator=',', use_categorical = False): """ Constructor and parser. """ @@ -40,55 +39,21 @@ class Data(object): self.fvmap = None self.ovmap = {} self.fvars = None - self.fname = filename self.mname = mapfile self.deleted = set([]) - if filename: - with open(filename, 'r') as fp: - self.parse(fp, separator) - elif fpointer: - self.parse(fpointer, separator) + self.parse(file, separator) if self.mname: self.read_orig_values() - # check if we have extra info about categorical_features - - if (use_categorical): - extra_file = filename+".pkl" - try: - f = open(extra_file, "rb") - print("Attempt: loading extra data from ", extra_file) - extra_info = pickle.load(f) - print("loaded") - f.close() - self.categorical_features = extra_info["categorical_features"] - self.categorical_names = extra_info["categorical_names"] - self.class_names = extra_info["class_names"] - self.categorical_onehot_names = extra_info["categorical_names"].copy() - - for i, name in enumerate(self.class_names): - self.class_names[i] = str(name).replace("b'","'") - for c in self.categorical_names.items(): - clean_feature_names = [] - for i, name in enumerate(c[1]): - name = str(name).replace("b'","'") - clean_feature_names.append(name) - self.categorical_names[c[0]] = clean_feature_names - - except Exception as e: - f.close() - print("Please provide info about categorical features or omit option -c", e) - exit() - def parse(self, fp, separator): """ Parse input file. """ # reading data set from file - lines = fp.readlines() + lines = fp.split('\n') # reading preamble self.names = lines[0].strip().split(separator) diff --git a/pages/application/RandomForest/utils/xgbooster/encode.py b/pages/application/RandomForest/utils/xgbooster/encode.py index 6a77fb3..bf98a6b 100644 --- a/pages/application/RandomForest/utils/xgbooster/encode.py +++ b/pages/application/RandomForest/utils/xgbooster/encode.py @@ -42,7 +42,6 @@ class SMTEncoder(object): self.feats = {f: i for i, f in enumerate(feats)} self.nofcl = nof_classes self.idmgr = IDPool() - self.optns = xgb.options # xgbooster will also be needed self.xgb = xgb @@ -165,8 +164,8 @@ class SMTEncoder(object): # if targeting interval-based encoding, # traverse all trees and extract all possible intervals # for each feature - if self.optns.encode == 'smtbool': - self.compute_intervals() + # if self.optns.encode == 'smtbool': + self.compute_intervals() # traversing and encoding each tree for i, tree in enumerate(self.ensemble.trees): @@ -203,13 +202,9 @@ class SMTEncoder(object): # number of variables nof_vars = len(self.enc.get_free_variables()) - if self.optns.verb: - print('encoding vars:', nof_vars) - print('encoding asserts:', nof_asserts) - return self.enc, self.intvs, self.imaps, self.ivars - def test_sample(self, sample): + def test_sample(self, sample, solver=None): """ Check whether or not the encoding "predicts" the same class as the classifier given an input sample. @@ -221,9 +216,6 @@ class SMTEncoder(object): # score arrays computed for each class csum = [[] for c in range(self.nofcl)] - if self.optns.verb: - print('testing sample:', list(sample)) - sample_internal = list(self.xgb.transform(sample)[0]) # traversing all trees @@ -274,7 +266,7 @@ class SMTEncoder(object): # now, getting the model escores = [] - model = get_model(And(self.enc, *hypos), solver_name=self.optns.solver) + model = get_model(And(self.enc, *hypos), solver_name=solver) for c in range(self.nofcl): v = Symbol('class{0}_score'.format(c), typename=REAL) escores.append(float(model.get_py_value(v))) @@ -282,10 +274,6 @@ class SMTEncoder(object): assert all(map(lambda c, e: abs(c - e) <= 0.001, cscores, escores)), \ 'wrong prediction: {0} vs {1}'.format(cscores, escores) - if self.optns.verb: - print('xgb scores:', cscores) - print('enc scores:', escores) - def save_to(self, outfile): """ Save the encoding into a file with a given name. diff --git a/pages/application/RandomForest/utils/xgbooster/explain.py b/pages/application/RandomForest/utils/xgbooster/explain.py index ca07874..a4e5f8b 100644 --- a/pages/application/RandomForest/utils/xgbooster/explain.py +++ b/pages/application/RandomForest/utils/xgbooster/explain.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -#-*- coding:utf-8 -*- +# -*- coding:utf-8 -*- ## ## explain.py ## @@ -9,7 +9,7 @@ ## # -#============================================================================== +# ============================================================================== from __future__ import print_function import numpy as np import os @@ -23,6 +23,7 @@ from six.moves import range import sys + # #============================================================================== class SMTExplainer(object): @@ -31,7 +32,7 @@ class SMTExplainer(object): """ def __init__(self, formula, intvs, imaps, ivars, feats, nof_classes, - options, xgb): + solver, xgb): """ Constructor. """ @@ -41,14 +42,12 @@ class SMTExplainer(object): self.imaps = imaps self.ivars = ivars self.nofcl = nof_classes - self.optns = options self.idmgr = IDPool() # saving XGBooster self.xgb = xgb - self.verbose = self.optns.verb - self.oracle = Solver(name=options.solver) + self.oracle = Solver(name=solver) self.inps = [] # input (feature value) variables for f in self.xgb.extended_feature_names_as_array_strings: @@ -150,28 +149,26 @@ class SMTExplainer(object): disj.append(GT(self.outs[i], self.outs[self.out_id])) self.oracle.add_assertion(Implies(self.selv, Or(disj))) - if self.verbose: - inpvals = self.xgb.readable_sample(sample) + inpvals = self.xgb.readable_sample(sample) - self.preamble = [] - for f, v in zip(self.xgb.feature_names, inpvals): - if f not in str(v): - self.preamble.append('{0} = {1}'.format(f, v)) - else: - self.preamble.append(v) + self.preamble = [] + for f, v in zip(self.xgb.feature_names, inpvals): + if f not in str(v): + self.preamble.append('{0} = {1}'.format(f, v)) + else: + self.preamble.append(v) - print(' explaining: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.output)) + explanation_dic = {} + explanation_dic["explaning instance"] = ' explaining: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.output) + return explanation_dic def explain(self, sample, smallest, expl_ext=None, prefer_ext=False): """ Hypotheses minimization. """ - self.time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - # adapt the solver to deal with the current sample - self.prepare(sample) + explanation_dic = self.prepare(sample) # saving external explanation to be minimized further if expl_ext == None or prefer_ext: @@ -182,27 +179,20 @@ class SMTExplainer(object): # if satisfiable, then the observation is not implied by the hypotheses if self.oracle.solve([self.selv] + [h for h, c in zip(self.rhypos, self.to_consider) if c]): - print(' no implication!') - print(self.oracle.get_model()) - sys.exit(1) - - if not smallest: - self.compute_minimal(prefer_ext=prefer_ext) - else: - self.compute_smallest() - - self.time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - self.time - - expl = sorted([self.sel2fid[h] for h in self.rhypos]) + explanation_dic["no implication"] = self.oracle.get_model() + else : + if not smallest: + self.compute_minimal(prefer_ext=prefer_ext) + else: + self.compute_smallest() - if self.verbose: + expl = sorted([self.sel2fid[h] for h in self.rhypos]) + explanation_dic["explanation brute "] = expl self.preamble = [self.preamble[i] for i in expl] - print(' explanation: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.xgb.target_name[self.out_id])) - print(' # hypos left:', len(self.rhypos)) - print(' time: {0:.2f}'.format(self.time)) + explanation_dic["explanation"] = ' explanation: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.xgb.target_name[self.out_id]) + explanation_dic["Hyphothesis left"] = ' # hypos left:' + str(len(self.rhypos)) - return expl + return explanation_dic def compute_minimal(self, prefer_ext=False): """ @@ -258,10 +248,6 @@ class SMTExplainer(object): hset = hitman.get() iters += 1 - if self.verbose > 1: - print('iter:', iters) - print('cand:', hset) - if self.oracle.solve([self.selv] + [self.rhypos[i] for i in hset]): to_hit = [] satisfied, unsatisfied = [], [] @@ -302,10 +288,7 @@ class SMTExplainer(object): else: to_hit.append(h) - if self.verbose > 1: - print('coex:', to_hit) - hitman.hit(to_hit) else: self.rhypos = [self.rhypos[i] for i in hset] - break + break \ No newline at end of file diff --git a/pages/application/RandomForest/utils/xgbooster/xgbooster.py b/pages/application/RandomForest/utils/xgbooster/xgbooster.py index 25cd86c..b7e62b4 100644 --- a/pages/application/RandomForest/utils/xgbooster/xgbooster.py +++ b/pages/application/RandomForest/utils/xgbooster/xgbooster.py @@ -11,24 +11,16 @@ # # ============================================================================== from __future__ import print_function -from .validate import SMTValidator -from .encode import SMTEncoder -from .explain import SMTExplainer -import numpy as np -import os -import resource -from sklearn.model_selection import train_test_split -from sklearn.metrics import accuracy_score -import sklearn -# print('The scikit-learn version is {}.'.format(sklearn.__version__)) -from sklearn.preprocessing import OneHotEncoder, LabelEncoder -import sys +import random + +import numpy as np from six.moves import range -from .tree import TreeEnsemble -import xgboost as xgb -from xgboost import XGBClassifier, Booster -import pickle +from xgboost import XGBClassifier + +from .encode import SMTEncoder +from .explain import SMTExplainer +from .validate import SMTValidator # @@ -38,164 +30,20 @@ class XGBooster(object): The main class to train/encode/explain XGBoost models. """ - def __init__(self, options, from_data=None, from_model=None, - from_encoding=None): + def __init__(self, options, from_model=None): """ Constructor. """ + np.random.seed(random.randint(1, 100)) - assert from_data or from_model or from_encoding, \ - 'At least one input file should be specified' - - self.init_stime = resource.getrusage(resource.RUSAGE_SELF).ru_utime - self.init_ctime = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime - - # saving command-line options - self.options = options - self.seed = self.options.seed - np.random.seed(self.seed) - - if from_data: - self.use_categorical = self.options.use_categorical - # saving data - self.data = from_data - ## - samps = np.asarray(self.data.samps) - if not all(c.isnumeric() for c in samps[:, -1]): - le = LabelEncoder() - le.fit(samps[:, -1]) - samps[:, -1] = le.transform(samps[:, -1]) - # self.class_names = le.classes_ - # print(le.classes_) - ## - dataset = np.asarray(samps, dtype=np.float32) - # dataset = np.asarray(self.data.samps, dtype=np.float32) - - # split data into X and y - self.feature_names = self.data.names[:-1] - self.nb_features = len(self.feature_names) - - self.X = dataset[:, 0:self.nb_features] - self.Y = dataset[:, self.nb_features] - self.num_class = len(set(self.Y)) - self.target_name = list(range(self.num_class)) - - param_dist = {'n_estimators': self.options.n_estimators, - 'max_depth': self.options.maxdepth} - - if (self.num_class == 2): - param_dist['objective'] = 'binary:logistic' - - self.model = XGBClassifier(**param_dist) - - # split data into train and test sets - self.test_size = self.options.testsplit - if (self.test_size > 0): - self.X_train, self.X_test, self.Y_train, self.Y_test = \ - train_test_split(self.X, self.Y, test_size=self.test_size, - random_state=self.seed) - else: - self.X_train = self.X - self.X_test = [] # need a fix - self.Y_train = self.Y - self.Y_test = [] # need a fix - - # check if we have info about categorical features - if (self.use_categorical): - self.categorical_features = from_data.categorical_features - self.categorical_names = from_data.categorical_names - self.target_name = from_data.class_names - - #################################### - # this is a set of checks to make sure that we use the same as anchor encoding - cat_names = sorted(self.categorical_names.keys()) - assert (cat_names == self.categorical_features) - self.encoder = {} - for i in self.categorical_features: - self.encoder.update({i: OneHotEncoder(categories='auto', sparse=False)}) # , - self.encoder[i].fit(self.X[:, [i]]) - - else: - self.categorical_features = [] - self.categorical_names = [] - self.encoder = [] - - fname = from_data - - elif from_model: - fname = from_model - self.load_datainfo(from_model) - if (self.use_categorical is False) and (self.options.use_categorical is True): - print( - "Error: Note that the model is trained without categorical features info. Please do not use -c option for predictions") - exit() - # load model - - elif from_encoding: - fname = from_encoding - - # encoding, feature names, and number of classes - # are read from an input file - enc = SMTEncoder(None, None, None, self, from_encoding) - self.enc, self.intvs, self.imaps, self.ivars, self.feature_names, \ - self.num_class = enc.access() - - # create extra file names - try: - os.stat(options.output) - except: - os.mkdir(options.output) - - self.mapping_features() - ################# - self.test_encoding_transformes() - - bench_name = os.path.splitext(os.path.basename(options.files[0]))[0] - bench_dir_name = options.output + "/bt/" + bench_name - try: - os.stat(bench_dir_name) - except: - os.mkdir(bench_dir_name) - - self.basename = (os.path.join(bench_dir_name, bench_name + - "_nbestim_" + str(options.n_estimators) + - "_maxdepth_" + str(options.maxdepth) + - "_testsplit_" + str(options.testsplit))) - - data_suffix = '.splitdata.pkl' - self.modfile = self.basename + '.mod.pkl' - - self.mod_plainfile = self.basename + '.mod.txt' - - self.resfile = self.basename + '.res.txt' - self.encfile = self.basename + '.enc.txt' - self.expfile = self.basename + '.exp.txt' - - def load_datainfo(self, model_from_pkl, data_from_pkl): self.model = XGBClassifier() - self.model = model_from_pkl - loaded_data = data_from_pkl - self.X = loaded_data["X"] - self.Y = loaded_data["Y"] - self.X_train = loaded_data["X_train"] - self.X_test = loaded_data["X_test"] - self.Y_train = loaded_data["Y_train"] - self.Y_test = loaded_data["Y_test"] - self.feature_names = loaded_data["feature_names"] - self.target_name = loaded_data["target_name"] - self.num_class = loaded_data["num_class"] - self.nb_features = len(self.feature_names) - self.categorical_features = loaded_data["categorical_features"] - self.categorical_names = loaded_data["categorical_names"] - self.encoder = loaded_data["encoder"] - self.use_categorical = loaded_data["use_categorical"] + self.model = from_model - def train(self, outfile=None): - """ - Train a tree ensemble using XGBoost. - """ + self.feature_names = options["feature_names"] + self.num_class = options["n_classes"] + self.nb_features = options["n_features"] - return self.build_xgbtree(outfile) + self.mapping_features() def encode(self, test_on=None): """ @@ -208,9 +56,7 @@ class XGBooster(object): if test_on: encoder.test_sample(np.array(test_on)) - # encoder.save_to(self.encfile) - - def explain(self, sample, use_lime=None, use_anchor=None, use_shap=None, + def explain(self, sample, smallest, solver, use_lime=None, use_anchor=None, use_shap=None, expl_ext=None, prefer_ext=False, nof_feats=5): """ Explain a prediction made for a given sample with a previously @@ -229,12 +75,10 @@ class XGBooster(object): if 'x' not in dir(self): self.x = SMTExplainer(self.enc, self.intvs, self.imaps, self.ivars, self.feature_names, self.num_class, - self.options, self) + solver, self) - expl = self.x.explain(np.array(sample), self.options.smallest, - expl_ext, prefer_ext) + expl = self.x.explain(np.array(sample), smallest, expl_ext, prefer_ext) - # returning the explanation return expl def validate(self, sample, expl): @@ -255,191 +99,12 @@ class XGBooster(object): # try to compute a counterexample return self.v.validate(np.array(sample), expl) - def transform(self, x): - if (len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert (self.encoder != []) - tx = [] - for i in range(self.nb_features): - self.encoder[i].drop = None - if (i in self.categorical_features): - tx_aux = self.encoder[i].transform(x[:, [i]]) - tx_aux = np.vstack(tx_aux) - tx.append(tx_aux) - else: - tx.append(x[:, [i]]) - tx = np.hstack(tx) - return tx - else: - return x - - def transform_inverse(self, x): - if (len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert (self.encoder != []) - inverse_x = [] - for i, xi in enumerate(x): - inverse_xi = np.zeros(self.nb_features) - for f in range(self.nb_features): - if f in self.categorical_features: - nb_values = len(self.categorical_names[f]) - v = xi[:nb_values] - v = np.expand_dims(v, axis=0) - iv = self.encoder[f].inverse_transform(v) - inverse_xi[f] = iv - xi = xi[nb_values:] - - else: - inverse_xi[f] = xi[0] - xi = xi[1:] - inverse_x.append(inverse_xi) - return inverse_x - else: - return x - - def transform_inverse_by_index(self, idx): - if (idx in self.extended_feature_names): - return self.extended_feature_names[idx] - else: - print("Warning there is no feature {} in the internal mapping".format(idx)) - return None - - def transform_by_value(self, feat_value_pair): - if (feat_value_pair in self.extended_feature_names.values()): - keys = ( - list(self.extended_feature_names.keys())[list(self.extended_feature_names.values()).index(feat_value_pair)]) - return keys - else: - print("Warning there is no value {} in the internal mapping".format(feat_value_pair)) - return None - def mapping_features(self): self.extended_feature_names = {} self.extended_feature_names_as_array_strings = [] counter = 0 - if (self.use_categorical): - for i in range(self.nb_features): - if (i in self.categorical_features): - for j, _ in enumerate(self.encoder[i].categories_[0]): - self.extended_feature_names.update({counter: (self.feature_names[i], j)}) - self.extended_feature_names_as_array_strings.append( - "f{}_{}".format(i, j)) # str(self.feature_names[i]), j)) - counter = counter + 1 - else: - self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i)) # (self.feature_names[i]) - counter = counter + 1 - else: - for i in range(self.nb_features): - self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i)) # (self.feature_names[i]) - counter = counter + 1 - - def readable_sample(self, x): - readable_x = [] - for i, v in enumerate(x): - if (i in self.categorical_features): - readable_x.append(self.categorical_names[i][int(v)]) - else: - readable_x.append(v) - return np.asarray(readable_x) - - def test_encoding_transformes(self): - # test encoding - - X = self.X_train[[0], :] - - print("Sample of length", len(X[0]), " : ", X) - enc_X = self.transform(X) - print("Encoded sample of length", len(enc_X[0]), " : ", enc_X) - inv_X = self.transform_inverse(enc_X) - print("Back to sample", inv_X) - print("Readable sample", self.readable_sample(inv_X[0])) - assert ((inv_X == X).all()) - - if (self.options.verb > 1): - for i in range(len(self.extended_feature_names)): - print(i, self.transform_inverse_by_index(i)) - for key, value in self.extended_feature_names.items(): - print(value, self.transform_by_value(value)) - - def transfomed_sample_info(self, i): - print(enc.categories_) - - def build_xgbtree(self, outfile=None): - """ - Build an ensemble of trees. - """ - - if (outfile is None): - outfile = self.modfile - else: - self.datafile = sefl.form_datefile_name(outfile) - - # fit model no training data - - if (len(self.X_test) > 0): - eval_set = [(self.transform(self.X_train), self.Y_train), (self.transform(self.X_test), self.Y_test)] - else: - eval_set = [(self.transform(self.X_train), self.Y_train)] - - print("start xgb") - self.model.fit(self.transform(self.X_train), self.Y_train, - eval_set=eval_set, - verbose=self.options.verb) # eval_set=[(X_test, Y_test)], - print("end xgb") - - evals_result = self.model.evals_result() - ########## saving model - self.save_datainfo(outfile) - print("saving plain model to ", self.mod_plainfile) - self.model._Booster.dump_model(self.mod_plainfile) - - ensemble = TreeEnsemble(self.model, self.extended_feature_names_as_array_strings, nb_classes=self.num_class) - - y_pred_prob = self.model.predict_proba(self.transform(self.X_train[:10])) - y_pred_prob_compute = ensemble.predict(self.transform(self.X_train[:10]), self.num_class) - - assert (np.absolute(y_pred_prob_compute - y_pred_prob).sum() < 0.01 * len(y_pred_prob)) - - ### accuracy - try: - train_accuracy = round(1 - evals_result['validation_0']['merror'][-1], 2) - except: - try: - train_accuracy = round(1 - evals_result['validation_0']['error'][-1], 2) - except: - assert (False) - - try: - test_accuracy = round(1 - evals_result['validation_1']['merror'][-1], 2) - except: - try: - test_accuracy = round(1 - evals_result['validation_1']['error'][-1], 2) - except: - print("no results test data") - test_accuracy = 0 - - #### saving - print("saving results to ", self.resfile) - with open(self.resfile, 'w') as f: - f.write("{} & {} & {} &{} &{} & {} \\\\ \n \hline \n".format( - os.path.basename(self.options.files[0]).replace("_", "-"), - train_accuracy, - test_accuracy, - self.options.n_estimators, - self.options.maxdepth, - self.options.testsplit)) - f.close() - - print("c BT sz:", ensemble.sz) - print("Train accuracy: %.2f%%" % (train_accuracy * 100.0)) - print("Test accuracy: %.2f%%" % (test_accuracy * 100.0)) - return train_accuracy, test_accuracy, self.model + for i in range(self.nb_features): + self.extended_feature_names.update({counter: (self.feature_names[i], None)}) + self.extended_feature_names_as_array_strings.append("f{}".format(i)) # (self.feature_names[i]) + counter = counter + 1 diff --git a/pages/application/RandomForest/utils/xgbrf/encode.py b/pages/application/RandomForest/utils/xgbrf/encode.py index 6a77fb3..78816a8 100644 --- a/pages/application/RandomForest/utils/xgbrf/encode.py +++ b/pages/application/RandomForest/utils/xgbrf/encode.py @@ -39,10 +39,10 @@ class SMTEncoder(object): """ self.model = model + self.features_names = feats self.feats = {f: i for i, f in enumerate(feats)} self.nofcl = nof_classes self.idmgr = IDPool() - self.optns = xgb.options # xgbooster will also be needed self.xgb = xgb @@ -165,8 +165,8 @@ class SMTEncoder(object): # if targeting interval-based encoding, # traverse all trees and extract all possible intervals # for each feature - if self.optns.encode == 'smtbool': - self.compute_intervals() + # if self.optns.encode == 'smtbool': + self.compute_intervals() # traversing and encoding each tree for i, tree in enumerate(self.ensemble.trees): @@ -203,13 +203,9 @@ class SMTEncoder(object): # number of variables nof_vars = len(self.enc.get_free_variables()) - if self.optns.verb: - print('encoding vars:', nof_vars) - print('encoding asserts:', nof_asserts) - return self.enc, self.intvs, self.imaps, self.ivars - def test_sample(self, sample): + def test_sample(self, sample, solver): """ Check whether or not the encoding "predicts" the same class as the classifier given an input sample. @@ -221,9 +217,6 @@ class SMTEncoder(object): # score arrays computed for each class csum = [[] for c in range(self.nofcl)] - if self.optns.verb: - print('testing sample:', list(sample)) - sample_internal = list(self.xgb.transform(sample)[0]) # traversing all trees @@ -274,7 +267,7 @@ class SMTEncoder(object): # now, getting the model escores = [] - model = get_model(And(self.enc, *hypos), solver_name=self.optns.solver) + model = get_model(And(self.enc, *hypos), solver_name=solver) for c in range(self.nofcl): v = Symbol('class{0}_score'.format(c), typename=REAL) escores.append(float(model.get_py_value(v))) @@ -282,10 +275,6 @@ class SMTEncoder(object): assert all(map(lambda c, e: abs(c - e) <= 0.001, cscores, escores)), \ 'wrong prediction: {0} vs {1}'.format(cscores, escores) - if self.optns.verb: - print('xgb scores:', cscores) - print('enc scores:', escores) - def save_to(self, outfile): """ Save the encoding into a file with a given name. diff --git a/pages/application/RandomForest/utils/xgbrf/tree.py b/pages/application/RandomForest/utils/xgbrf/tree.py index afe34d9..6c7f753 100644 --- a/pages/application/RandomForest/utils/xgbrf/tree.py +++ b/pages/application/RandomForest/utils/xgbrf/tree.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -#-*- coding:utf-8 -*- +# -*- coding:utf-8 -*- ## ## tree.py (reuses parts of the code of SHAP) ## @@ -9,8 +9,8 @@ ## # -#============================================================================== -from anytree import Node, RenderTree,AsciiStyle +# ============================================================================== +from anytree import Node, RenderTree, AsciiStyle import json import numpy as np import xgboost as xgb @@ -18,13 +18,13 @@ import math # -#============================================================================== +# ============================================================================== class xgnode(Node): - def __init__(self, id, parent = None): + def __init__(self, id, parent=None): Node.__init__(self, id, parent) self.id = id # The node value self.name = None - self.left_node_id = -1 # Left child + self.left_node_id = -1 # Left child self.right_node_id = -1 # Right child self.missing_node_id = -1 @@ -37,29 +37,31 @@ class xgnode(Node): def __str__(self): pref = ' ' * self.depth if (len(self.children) == 0): - return (pref+ "leaf: {} {}".format(self.id, self.values)) + return (pref + "leaf: {} {}".format(self.id, self.values)) else: - if(self.name is None): - return (pref+ "{} f{}<{}".format(self.id, self.feature, self.threshold)) + if (self.name is None): + return (pref + "{} f{}<{}".format(self.id, self.feature, self.threshold)) else: - return (pref+ "{} \"{}\"<{}".format(self.id, self.name, self.threshold)) + return (pref + "{} \"{}\"<{}".format(self.id, self.name, self.threshold)) # -#============================================================================== -def build_tree(json_tree, node = None, feature_names = None, inverse = False): +# ============================================================================== +def build_tree(json_tree, node=None, feature_names=None, inverse=False): def max_id(node): if "children" in node: return max(node["nodeid"], *[max_id(n) for n in node["children"]]) else: return node["nodeid"] + m = max_id(json_tree) + 1 - def extract_data(json_node, root = None, feature_names = None): + + def extract_data(json_node, root=None, feature_names=None): i = json_node["nodeid"] if (root is None): node = xgnode(i) else: - node = xgnode(i, parent = root) + node = xgnode(i, parent=root) node.cover = json_node["cover"] if "children" in json_node: @@ -73,8 +75,8 @@ def build_tree(json_tree, node = None, feature_names = None, inverse = False): for c, n in enumerate(json_node["children"]): child = extract_data(n, node, feature_names) elif "leaf" in json_node: - node.values = json_node["leaf"] - if(inverse): + node.values = json_node["leaf"] + if (inverse): node.values = -node.values return node @@ -83,7 +85,7 @@ def build_tree(json_tree, node = None, feature_names = None, inverse = False): # -#============================================================================== +# ============================================================================== def walk_tree(node): if (len(node.children) == 0): # leaf @@ -95,7 +97,7 @@ def walk_tree(node): # -#============================================================================== +# ============================================================================== def scores_tree(node, sample): if (len(node.children) == 0): # leaf @@ -103,41 +105,43 @@ def scores_tree(node, sample): else: feature_branch = node.feature sample_value = sample[feature_branch] - assert(sample_value is not None) - if(sample_value < node.threshold): + assert (sample_value is not None) + if (sample_value < node.threshold): return scores_tree(node.children[0], sample) else: return scores_tree(node.children[1], sample) # -#============================================================================== +# ============================================================================== class TreeEnsemble: """ An ensemble of decision trees. This object provides a common interface to many different types of models. """ - def __init__(self, model, feature_names = None, nb_classes = 0): + + def __init__(self, model, feature_names=None, nb_classes=0): self.model_type = "xgboost" - #self.original_model = model.get_booster() + # self.original_model = model.get_booster() self.original_model = model #### self.base_offset = None - json_trees = get_xgboost_json(self.original_model) + json_trees = get_xgboost_json(self.original_model, feature_names) self.trees = [build_tree(json.loads(t), None, feature_names) for t in json_trees] - if(nb_classes == 2): + if (nb_classes == 2): # NASTY trick for binary # We change signs of values in leaves so that we can just sum all the values in leaves for class X # and take max to get the right class - self.otrees = [build_tree(json.loads(t), None, feature_names, inverse = True) for t in json_trees] + self.otrees = [build_tree(json.loads(t), None, feature_names, inverse=True) for t in json_trees] self.itrees = [build_tree(json.loads(t), None, feature_names) for t in json_trees] self.trees = [] - for i,_ in enumerate(self.otrees): + for i, _ in enumerate(self.otrees): self.trees.append(self.otrees[i]) self.trees.append(self.itrees[i]) self.feature_names = feature_names + def print_tree(self): - for i,t in enumerate(self.trees): + for i, t in enumerate(self.trees): print("tree number: ", i) walk_tree(t) @@ -149,13 +153,14 @@ class TreeEnsemble: self.invert_tree_prob(node.children[0]) self.invert_tree_prob(node.children[1]) return node + def predict(self, samples, nb_classes): # https://github.com/dmlc/xgboost/issues/1746#issuecomment-290130695 prob = [] - nb_estimators = int(len(self.trees)/nb_classes) + nb_estimators = int(len(self.trees) / nb_classes) for sample in np.asarray(samples): scores = [] - for i,t in enumerate(self.trees): + for i, t in enumerate(self.trees): s = scores_tree(t, sample) scores.append((s)) scores = np.asarray(scores) @@ -163,30 +168,31 @@ class TreeEnsemble: if (nb_classes == 2): for i in range(nb_classes): - class_scores.append(math.exp(-(scores[i::nb_classes]).sum())) # swap signs back as we had to use this trick in the contractor - s0 = class_scores[0] - s1 = class_scores[1] - v0 = 1/(1 + s0) - v1 = 1/(1 + s1) + class_scores.append(math.exp(-( + scores[i::nb_classes]).sum())) # swap signs back as we had to use this trick in the contractor + s0 = class_scores[0] + s1 = class_scores[1] + v0 = 1 / (1 + s0) + v1 = 1 / (1 + s1) class_scores[0] = v0 class_scores[1] = v1 else: - for i in range(0,nb_classes*nb_estimators,nb_estimators): - class_scores.append(math.exp((scores[i:i+nb_estimators]).sum())) - #for i in range(nb_classes): + for i in range(0, nb_classes * nb_estimators, nb_estimators): + class_scores.append(math.exp((scores[i:i + nb_estimators]).sum())) + # for i in range(nb_classes): # class_scores.append(math.exp((scores[i::nb_classes]).sum())) class_scores = np.asarray(class_scores) - prob.append(class_scores/class_scores.sum()) + prob.append(class_scores / class_scores.sum()) return np.asarray(prob).reshape((-1, nb_classes)) # -#============================================================================== -def get_xgboost_json(model): +# ============================================================================== +def get_xgboost_json(model, feature_names): """ REUSED FROM SHAP This gets a JSON dump of an XGBoost model while ensuring the feature names are their indexes. """ - fnames = model.feature_names + fnames = feature_names model.feature_names = None json_trees = model.get_dump(with_stats=True, dump_format="json") model.feature_names = fnames diff --git a/pages/application/RandomForest/utils/xgbrf/xgb_rf.py b/pages/application/RandomForest/utils/xgbrf/xgb_rf.py index 024225f..840def7 100644 --- a/pages/application/RandomForest/utils/xgbrf/xgb_rf.py +++ b/pages/application/RandomForest/utils/xgbrf/xgb_rf.py @@ -10,6 +10,10 @@ # #============================================================================== +from __future__ import print_function + +import random + from .validate import SMTValidator from .pi_checker import SMTChecker from .encode import SMTEncoder @@ -39,222 +43,22 @@ class XGBRandomForest(object): The main class to train/encode/explain Random Forest models. """ - def __init__(self, options, from_data=None, from_model=None, - from_encoding=None): + def __init__(self, options, from_model=None): """ Constructor. """ + self.extended_feature_names = None + self.extended_feature_names_as_array_strings = None + np.random.seed(random.randint(1, 100)) - assert from_data or from_model or from_encoding, \ - 'At least one input file should be specified' - - self.init_stime = resource.getrusage(resource.RUSAGE_SELF).ru_utime - self.init_ctime = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime - - # saving command-line options - self.options = options - self.seed = 42 - np.random.seed(self.seed) - - if from_data: - self.use_categorical = self.options.use_categorical - # saving data - self.data = from_data - dataset = np.asarray(self.data.samps, dtype=np.float32) - - - # split data into X and y - self.feature_names = self.data.names[:-1] - self.nb_features = len(self.feature_names) - - self.X = dataset[:, 0:self.nb_features] - self.Y = dataset[:, self.nb_features] - self.num_class = len(set(self.Y)) - self.target_name = list(range(self.num_class)) - - param_dist = {'n_estimators':self.options.n_estimators, - 'max_depth':self.options.maxdepth} - - self.params = { 'num_parallel_tree': self.options.n_estimators, - 'max_depth': self.options.maxdepth, - 'colsample_bynode': 0.8, 'subsample': 0.8, - 'learning_rate': 1, 'random_state': self.seed, - 'verbosity' : self.options.verb - } - - if(self.num_class == 2): - self.params['eval_metric'] = 'error' - self.params['objective'] = 'binary:logistic' - else: - self.params['eval_metric'] = 'merror' - self.params['num_class'] = self.num_class - self.params['objective'] = 'multi:softprob' - - if(self.num_class == 2): - param_dist['objective'] = 'binary:logistic' - - #self.model = XGBRFClassifier(**param_dist) - self.model = None - - # split data into train and test sets - self.test_size = self.options.testsplit - if (self.test_size > 0): - self.X_train, self.X_test, self.Y_train, self.Y_test = \ - train_test_split(self.X, self.Y, test_size=self.test_size, - random_state=self.seed) - else: - self.X_train = self.X - self.X_test = [] # need a fix - self.Y_train = self.Y - self.Y_test = []# need a fix - - # check if we have info about categorical features - if (self.use_categorical): - self.categorical_features = from_data.categorical_features - self.categorical_names = from_data.categorical_names - self.target_name = from_data.class_names - - #################################### - # this is a set of checks to make sure that we use the same as anchor encoding - cat_names = sorted(self.categorical_names.keys()) - assert(cat_names == self.categorical_features) - self.encoder = {} - for i in self.categorical_features: - self.encoder.update({i: OneHotEncoder(categories='auto', sparse=False)})#, - self.encoder[i].fit(self.X[:,[i]]) - - else: - self.categorical_features = [] - self.categorical_names = [] - self.encoder = [] - - fname = from_data - - elif from_model: - fname = from_model - self.load_datainfo(from_model) - if (self.use_categorical is False) and (self.options.use_categorical is True): - print("Error: Note that the model is trained without categorical features info. Please do not use -c option for predictions") - exit() - # load model - - elif from_encoding: - fname = from_encoding - - # encoding, feature names, and number of classes - # are read from an input file - enc = SMTEncoder(None, None, None, self, from_encoding) - self.enc, self.intvs, self.imaps, self.ivars, self.feature_names, \ - self.num_class = enc.access() - - # create extra file names - try: - os.stat(options.output) - except: - os.mkdir(options.output) - - self.mapping_features() - ################# - self.test_encoding_transformes() - - bench_name = os.path.splitext(os.path.basename(options.files[0]))[0] - bench_dir_name = options.output + "/" + bench_name - try: - os.stat(bench_dir_name) - except: - os.mkdir(bench_dir_name) - - self.basename = (os.path.join(bench_dir_name, bench_name + - "_nbestim_" + str(options.n_estimators) + - "_maxdepth_" + str(options.maxdepth) + - "_testsplit_" + str(options.testsplit))) - - data_suffix = '.splitdata.pkl' - self.modfile = self.basename + '.mod.pkl' - - self.mod_plainfile = self.basename + '.mod.txt' - - self.resfile = self.basename + '.res.txt' - self.encfile = self.basename + '.enc.txt' - self.expfile = self.basename + '.exp.txt' - - def form_datefile_name(self, modfile): - data_suffix = '.splitdata.pkl' - return modfile + data_suffix - - def pickle_save_file(self, filename, data): - try: - f = open(filename, "wb") - pickle.dump(data, f) - f.close() - except: - print("Cannot save to file", filename) - exit() - - def pickle_load_file(self, filename): - try: - f = open(filename, "rb") - data = pickle.load(f) - f.close() - return data - except: - print("Cannot load from file", filename) - exit() - - def save_datainfo(self, filename): - - print("saving model to ", filename) - self.pickle_save_file(filename, self.model) - - filename_data = self.form_datefile_name(filename) - print("saving data to ", filename_data) - samples = {} - samples["X"] = self.X - samples["Y"] = self.Y - samples["X_train"] = self.X_train - samples["Y_train"] = self.Y_train - samples["X_test"] = self.X_test - samples["Y_test"] = self.Y_test - samples["feature_names"] = self.feature_names - samples["target_name"] = self.target_name - samples["num_class"] = self.num_class - samples["categorical_features"] = self.categorical_features - samples["categorical_names"] = self.categorical_names - samples["encoder"] = self.encoder - samples["use_categorical"] = self.use_categorical - - - self.pickle_save_file(filename_data, samples) - - def load_datainfo(self, filename): - print("loading model from ", filename) self.model = XGBRFClassifier() - self.model = self.pickle_load_file(filename) - - datafile = self.form_datefile_name(filename) - print("loading data from ", datafile) - loaded_data = self.pickle_load_file(datafile) - self.X = loaded_data["X"] - self.Y = loaded_data["Y"] - self.X_train = loaded_data["X_train"] - self.X_test = loaded_data["X_test"] - self.Y_train = loaded_data["Y_train"] - self.Y_test = loaded_data["Y_test"] - self.feature_names = loaded_data["feature_names"] - self.target_name = loaded_data["target_name"] - self.num_class = loaded_data["num_class"] - self.nb_features = len(self.feature_names) - self.categorical_features = loaded_data["categorical_features"] - self.categorical_names = loaded_data["categorical_names"] - self.encoder = loaded_data["encoder"] - self.use_categorical = loaded_data["use_categorical"] + self.model = from_model - def train(self, outfile=None): - """ - Train a random forest using XGBoost. - """ + self.feature_names = options["feature_names"] + self.num_class = options["n_classes"] + self.nb_features = options["n_features"] - return self.build_xgbtree(outfile) + self.mapping_features() def encode(self, test_on=None): """ @@ -266,32 +70,27 @@ class XGBRandomForest(object): if test_on: encoder.test_sample(np.array(test_on)) - encoder.save_to(self.encfile) - - def explain(self, sample, use_lime=None, use_anchor=None, use_shap=None, - expl_ext=None, prefer_ext=False, nof_feats=5): + def explain(self, sample, smallest, solver, use_lime=None, use_anchor=None, use_shap=None, + expl_ext=None, prefer_ext=False, nof_feats=5): """ Explain a prediction made for a given sample with a previously trained tree ensemble. """ if use_lime: - expl = use_lime(self, sample=sample, nb_samples=5, nb_features_in_exp=nof_feats) + expl = use_lime(self, sample=sample, nb_samples=5, + nb_features_in_exp=nof_feats) elif use_anchor: expl = use_anchor(self, sample=sample, nb_samples=5, - nb_features_in_exp=nof_feats, threshold=0.95) + nb_features_in_exp=nof_feats, threshold=0.95) elif use_shap: expl = use_shap(self, sample=sample, nb_features_in_exp=nof_feats) else: - if 'x' not in dir(self): - self.x = SMTExplainer(self.enc, self.intvs, self.imaps, - self.ivars, self.feature_names, self.num_class, - self.options, self) - - expl = self.x.explain(np.array(sample), self.options.smallest, - expl_ext, prefer_ext) + self.x = SMTExplainer(self.enc, self.intvs, self.imaps, + self.ivars, self.feature_names, self.num_class, + solver, self) + expl = self.x.explain(np.array(sample), smallest, expl_ext, prefer_ext) - # returning the explanation return expl def validate(self, sample, expl): @@ -312,289 +111,12 @@ class XGBRandomForest(object): # try to compute a counterexample return self.v.validate(np.array(sample), expl) - - def isPrimeImplicant(self, sample, expl): - """ - Check the explnation if it is a prime implicant. - """ - - # there must exist an encoding - if 'enc' not in dir(self): - encoder = SMTEncoder(self.model, self.feature_names, self.num_class, - self) - self.enc, _, _, _ = encoder.encode() - - if 'checker' not in dir(self): - self.checker = SMTChecker(self.enc, self.feature_names, self.num_class, - self) - - # check the explanation - return self.checker.check(np.array(sample), expl) - - def repair(self, sample, expl): - """ - Make an attempt to repair that a given pessimistic (incorrect) explanation. - """ - #encode without sample - self.encode() - gexpl = self.explain(sample, expl_ext=expl, prefer_ext=True) - - #global explanation - return gexpl - - def refine(self, sample, expl): - """ - Make an attempt to refine that a given optimistic explanation. - """ - #encode without sample - self.encode() - gexpl = self.explain(sample, expl_ext=expl) - - #global explanation - return gexpl - - def transform(self, x): - if(len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert(self.encoder != []) - tx = [] - for i in range(self.nb_features): - #self.encoder[i].drop = None - if (i in self.categorical_features): - self.encoder[i].drop = None - tx_aux = self.encoder[i].transform(x[:,[i]]) - tx_aux = np.vstack(tx_aux) - tx.append(tx_aux) - else: - tx.append(x[:,[i]]) - tx = np.hstack(tx) - return tx - else: - return x - - def transform_inverse(self, x): - if(len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert(self.encoder != []) - inverse_x = [] - for i, xi in enumerate(x): - inverse_xi = np.zeros(self.nb_features) - for f in range(self.nb_features): - if f in self.categorical_features: - nb_values = len(self.categorical_names[f]) - v = xi[:nb_values] - v = np.expand_dims(v, axis=0) - iv = self.encoder[f].inverse_transform(v) - inverse_xi[f] =iv - xi = xi[nb_values:] - - else: - inverse_xi[f] = xi[0] - xi = xi[1:] - inverse_x.append(inverse_xi) - return inverse_x - else: - return x - - def transform_inverse_by_index(self, idx): - if (idx in self.extended_feature_names): - return self.extended_feature_names[idx] - else: - print("Warning there is no feature {} in the internal mapping".format(idx)) - return None - - def transform_by_value(self, feat_value_pair): - if (feat_value_pair in self.extended_feature_names.values()): - keys = (list(self.extended_feature_names.keys())[list( self.extended_feature_names.values()).index(feat_value_pair)]) - return keys - else: - print("Warning there is no value {} in the internal mapping".format(feat_value_pair)) - return None - def mapping_features(self): self.extended_feature_names = {} self.extended_feature_names_as_array_strings = [] counter = 0 - if (self.use_categorical): - for i in range(self.nb_features): - if (i in self.categorical_features): - for j, _ in enumerate(self.encoder[i].categories_[0]): - self.extended_feature_names.update({counter: (self.feature_names[i], j)}) - self.extended_feature_names_as_array_strings.append("f{}_{}".format(i,j)) # str(self.feature_names[i]), j)) - counter = counter + 1 - else: - self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i)) #(self.feature_names[i]) - counter = counter + 1 - else: - for i in range(self.nb_features): - self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i))#(self.feature_names[i]) - counter = counter + 1 - - def readable_sample(self, x): - readable_x = [] - for i, v in enumerate(x): - if (i in self.categorical_features): - readable_x.append(self.categorical_names[i][int(v)]) - else: - #readable_x.append(v) - readable_x.append(str(v)) - return np.asarray(readable_x) - - def test_encoding_transformes(self): - # test encoding - - X = self.X_train[[0],:] - - print("Sample of length", len(X[0])," : ", X) - enc_X = self.transform(X) - print("Encoded sample of length", len(enc_X[0])," : ", enc_X) - inv_X = self.transform_inverse(enc_X) - print("Back to sample", inv_X) - print("Readable sample", self.readable_sample(inv_X[0])) - assert((inv_X == X).all()) - - if (self.options.verb > 1): - for i in range(len(self.extended_feature_names)): - print(i, self.transform_inverse_by_index(i)) - for key, value in self.extended_feature_names.items(): - print(value, self.transform_by_value(value)) - - def transfomed_sample_info(self, i): - print(enc.categories_) - - def build_xgbtree(self, outfile=None): - """ - Build an ensemble of trees (forest). - """ - - if (outfile is None): - outfile = self.modfile - else: - self.datafile = sefl.form_datefile_name(outfile) - - # fit model no training data - - if (len(self.X_test) > 0): - eval_set=[(self.transform(self.X_train), self.Y_train), (self.transform(self.X_test), self.Y_test)] - else: - eval_set=[(self.transform(self.X_train), self.Y_train)] - - print("start xgb") - ''' - self.model.fit(self.transform(self.X_train), self.Y_train, - eval_set=eval_set, - verbose=self.options.verb) # eval_set=[(X_test, Y_test)], - ''' - dtrain = xgb.DMatrix(self.transform(self.X_train), label=self.Y_train) - dtest = xgb.DMatrix(self.transform(self.X_test), label=self.Y_test) - eval_set = [(dtrain, 'train'), (dtest, 'eval')] - evals_result = {} - self.model = xgb.train(self.params, dtrain, num_boost_round=1, - evals=eval_set, evals_result=evals_result) - print("end xgb") - print(self.model.get_score()) - print(len(self.model.get_score())) - #for i in range(5): - # xgb.plot_tree(self.model, num_trees=i) - # plt.show() - - - try: - train_accuracy = round(1 - evals_result['train']['merror'][-1],2) - except: - try: - train_accuracy = round(1 - evals_result['train']['error'][-1],2) - except: - assert(False) - try: - test_accuracy = round(1 - evals_result['eval']['merror'][-1],2) - except: - try: - test_accuracy = round(1 - evals_result['eval']['error'][-1],2) - except: - assert(False) - #print('Train accuracy_xgb: ',train_accuracy) - #print('Test accuracy_xgb: ', test_accuracy) - - - #evals_result = self.model.evals_result() - ########## saving model - self.save_datainfo(outfile) - print("saving plain model to ", self.mod_plainfile) - #self.model._Booster.dump_model(self.mod_plainfile) - self.model.dump_model(self.mod_plainfile) - - ensemble = TreeEnsemble(self.model, self.extended_feature_names_as_array_strings, nb_classes = self.num_class) - #ensemble.print_tree() - - #y_pred_prob = self.model.predict_proba(self.transform(self.X_train[:10])) - classone_probs = self.model.predict(xgb.DMatrix(self.transform(self.X_train[:10]))) - if self.num_class == 2: - classzero_probs = 1.0 - classone_probs - y_pred_prob = np.vstack((classzero_probs, classone_probs)).transpose() - else: - y_pred_prob = classone_probs - - y_pred_prob_compute = ensemble.predict(self.transform(self.X_train[:10]), self.num_class) - #print('y_pred_prob: \n', y_pred_prob) - #print('y_pred_prob_compute: \n',y_pred_prob_compute) - #print('\n\n') - - assert(np.absolute(y_pred_prob_compute- y_pred_prob).sum() < 0.01*len(y_pred_prob)) - - ### accuracy - ''' - try: - train_accuracy = round(1 - evals_result['validation_0']['merror'][-1],2) - except: - try: - train_accuracy = round(1 - evals_result['validation_0']['error'][-1],2) - except: - assert(False) - - try: - test_accuracy = round(1 - evals_result['validation_1']['merror'][-1],2) - except: - try: - test_accuracy = round(1 - evals_result['validation_1']['error'][-1],2) - except: - print("no results test data") - test_accuracy = 0 - ''' - - #### saving - - print("saving results to ", self.resfile) - with open(self.resfile, 'w') as f: - f.write("{} & {} & {} &{} &{} & {} \\\\ \n \hline \n".format( - os.path.basename(self.options.files[0]).replace("_","-"), - train_accuracy, - test_accuracy, - self.options.n_estimators, - self.options.maxdepth, - self.options.testsplit)) - f.close() - - print("Train accuracy: %.2f%%" % (train_accuracy * 100.0)) - print("Test accuracy: %.2f%%" % (test_accuracy * 100.0)) - - - return train_accuracy, test_accuracy, self.model - - def predict(self, X): - classone_probs = self.model.predict(xgb.DMatrix(self.transform(X))) - if self.num_class == 2: - classzero_probs = 1.0 - classone_probs - y_pred_prob = np.vstack((classzero_probs, classone_probs)).transpose() - else: - y_pred_prob = classone_probs - return y_pred_prob + for i in range(self.nb_features): + self.extended_feature_names.update({counter: (self.feature_names[i], None)}) + self.extended_feature_names_as_array_strings.append("f{}".format(i)) + counter = counter + 1 diff --git a/pages/application/RandomForest/utils/xprf.py b/pages/application/RandomForest/utils/xprf.py index acd3fd8..c22b618 100755 --- a/pages/application/RandomForest/utils/xprf.py +++ b/pages/application/RandomForest/utils/xprf.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -#-*- coding:utf-8 -*- +# -*- coding:utf-8 -*- ## ## xrf.py ## @@ -9,32 +9,34 @@ ## # -#============================================================================== +# ============================================================================== from __future__ import print_function -from pages.application.RandomForest.utils.data import Data +from pages.application.RandomForest.utils.data import Data import os import sys import pickle import resource -from pages.application.RandomForest.utils.xgbooster import preprocess_dataset +from pages.application.RandomForest.utils.xgbooster import preprocess_dataset -from pages.application.RandomForest.utils.xrf import XRF, RF2001, Dataset, Checker +from pages.application.RandomForest.utils.xrf import XRF, RF2001, Dataset, Checker import numpy as np ################## -from pages.application.RandomForest.utils.xpLime import lime_call +from pages.application.RandomForest.utils.xpLime import lime_call import math import lime import lime.lime_tabular ### -from pages.application.RandomForest.utils.xpAnchor import anchor_call -#from anchor import utils +from pages.application.RandomForest.utils.xpAnchor import anchor_call +# from anchor import utils from anchor import anchor_tabular + + ################ # -#============================================================================== +# ============================================================================== def show_info(): """ Print info message. @@ -42,35 +44,37 @@ def show_info(): print("c XRF: eXplaining Random Forest.") print('c') - + # -#============================================================================== +# ============================================================================== def pickle_save_file(filename, data): try: - f = open(filename, "wb") + f = open(filename, "wb") pickle.dump(data, f) f.close() except: print("Cannot save to file", filename) exit() + def pickle_load_file(filename): try: - f = open(filename, "rb") + f = open(filename, "rb") data = pickle.load(f) f.close() return data except: print("Cannot load from file", filename) - exit() - - -# -#============================================================================== + exit() + + # + + +# ============================================================================== if __name__ == '__main__': # parsing command-line options options = Options(sys.argv) - + # making output unbuffered if sys.version_info.major == 2: sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0) @@ -81,35 +85,34 @@ if __name__ == '__main__': if (options.preprocess_categorical): preprocess_dataset(options.files[0], options.preprocess_categorical_files, options.use_categorical) exit() - - + if options.files: cls = None xrf = None - + print("loading data ...") data = Dataset(filename=options.files[0], mapfile=options.mapfile, - separator=options.separator, use_categorical = options.use_categorical) - + separator=options.separator, use_categorical=options.use_categorical) + if options.train: ''' data = Dataset(filename=options.files[0], mapfile=options.mapfile, separator=options.separator, use_categorical = options.use_categorical) - ''' + ''' cls = RF2001(options) train_accuracy, test_accuracy = cls.train(data) - + if options.verb == 1: print("----------------------") print("Train accuracy: {0:.2f}".format(100. * train_accuracy)) print("Test accuracy: {0:.2f}".format(100. * test_accuracy)) - print("----------------------") - + print("----------------------") + xrf = XRF(options, cls, data) - #xrf.test_tree_ensemble() - + # xrf.test_tree_ensemble() + bench_name = os.path.splitext(os.path.basename(options.files[0]))[0] bench_dir_name = options.output + "/RF/" + bench_name try: @@ -118,23 +121,22 @@ if __name__ == '__main__': os.mkdir(bench_dir_name) basename = (os.path.join(bench_dir_name, bench_name + - "_nbestim_" + str(options.n_estimators) + - "_maxdepth_" + str(options.maxdepth))) + "_nbestim_" + str(options.n_estimators) + + "_maxdepth_" + str(options.maxdepth))) - modfile = basename + '.mod.pkl' + modfile = basename + '.mod.pkl' print("saving model to ", modfile) pickle_save_file(modfile, cls) - - #data_suffix = '.splitdata.pkl' - #filename_data = basename + data_suffix - #print("saving data to ", filename_data) - #pickle_save_file(filename_data, data) + # data_suffix = '.splitdata.pkl' + # filename_data = basename + data_suffix + # print("saving data to ", filename_data) + # pickle_save_file(filename_data, data) # read a sample from options.explain - #if options.explain: + # if options.explain: # options.explain = [float(v.strip()) for v in options.explain.split(',')] - + ''' if options.encode: # encode it and save the encoding to another file @@ -143,25 +145,24 @@ if __name__ == '__main__': ''' if options.explain: mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + \ - resource.getrusage(resource.RUSAGE_CHILDREN).ru_maxrss - + resource.getrusage(resource.RUSAGE_CHILDREN).ru_maxrss + if not xrf: print("loading model ...") - cls = pickle_load_file(options.files[1]) + cls = pickle_load_file(options.files[1]) xrf = XRF(options, cls, data) - - - #expl = xrf.explain(options.explain) - - #expl_checker = Checker(xrf.f, data.num_class, data.extended_feature_names_as_array_strings) - - cls.print_accuracy(data) # print test accuracy of the RF model - + + # expl = xrf.explain(options.explain) + + # expl_checker = Checker(xrf.f, data.num_class, data.extended_feature_names_as_array_strings) + + cls.print_accuracy(data) # print test accuracy of the RF model + samps_file = options.explain.strip() print(samps_file) with open(samps_file, 'r') as fp: lines = fp.readlines() - + # timers atimes = [] lengths = [] @@ -171,46 +172,46 @@ if __name__ == '__main__': utimes = [] nSatCalls = [] nUnsCalls = [] - + ltimes = [] ctimes = [] wins = 0 - + for i, s in enumerate(lines): sample = [float(v.strip()) for v in s.split(',')] if tuple(sample) in tested: continue - - #print("inst#{0}".format(i+1)) - + + # print("inst#{0}".format(i+1)) + tested.add(tuple(sample)) - #print('sample {0}: {1}'.format(i, ','.join(s.strip().split(',')))) - + # print('sample {0}: {1}'.format(i, ','.join(s.strip().split(',')))) + xrf.encode(sample) expl = xrf.explain(sample) - atimes.append(xrf.x.time) + atimes.append(xrf.x.time) lengths.append(len(expl)) nvars = xrf.enc.cnf.nv nclauses = len(xrf.enc.cnf.clauses) - - #mSAT = max(xrf.x.stimes+[mSAT]) - #mUNSAT = max(xrf.x.utimes+[mUNSAT]) + + # mSAT = max(xrf.x.stimes+[mSAT]) + # mUNSAT = max(xrf.x.utimes+[mUNSAT]) if len(xrf.x.stimes): stimes.append(max(xrf.x.stimes)) if len(xrf.x.utimes): utimes.append(max(xrf.x.utimes)) nSatCalls.append(xrf.x.nsat) nUnsCalls.append(xrf.x.nunsat) - - #inst = data.transform(np.array(sample))[0] - #expl_checker.check(np.array(inst), expl) + + # inst = data.transform(np.array(sample))[0] + # expl_checker.check(np.array(inst), expl) #####check_expl(np.array(inst), expl, xrf.enc.forest, xrf.enc.intvs) - + del xrf.enc del xrf.x - + #####################LIME########### ''' _, ltime = lime_call(cls, data, sample, verbose=options.verb) # call lime @@ -218,20 +219,19 @@ if __name__ == '__main__': #wins += 1 if atimes[-1] < ltime: wins += 1 - ''' - - _, ctime = anchor_call(cls, data, sample, verbose=options.verb) # call lime + ''' + + _, ctime = anchor_call(cls, data, sample, verbose=options.verb) # call lime ctimes.append(ctime) if atimes[-1] < ctime: - wins += 1 - - #if i == 1: + wins += 1 + + # if i == 1: # break - + mem = resource.getrusage(resource.RUSAGE_SELF).ru_maxrss + \ - resource.getrusage(resource.RUSAGE_CHILDREN).ru_maxrss - mem - - + resource.getrusage(resource.RUSAGE_CHILDREN).ru_maxrss - mem + # reporting the time spent print('') print('tot time: {0:.2f}'.format(sum(atimes))) @@ -240,22 +240,21 @@ if __name__ == '__main__': print('avg time: {0:.2f}'.format(sum(atimes) / len(atimes))) print('') #### - print('avg length: {0:.0f}'.format(round(sum(lengths) / len(lengths))*100/len(sample))) - #print('max SAT: {0:.2f}'.format(mSAT)) - #print('max UNSAT: {0:.2f}'.format(mUNSAT)) + print('avg length: {0:.0f}'.format(round(sum(lengths) / len(lengths)) * 100 / len(sample))) + # print('max SAT: {0:.2f}'.format(mSAT)) + # print('max UNSAT: {0:.2f}'.format(mUNSAT)) print('max SAT: {0:.2f}'.format(max(stimes))) - print('max UNSAT: {0:.2f}'.format(max(utimes))) + print('max UNSAT: {0:.2f}'.format(max(utimes))) print('avg #SAT: {0:.0f}'.format(sum(nSatCalls) / len(nSatCalls))) print('avg #UNSAT: {0:.0f}'.format(sum(nUnsCalls) / len(nUnsCalls))) print('') - #reporting nof_vars and nof_clauses + # reporting nof_vars and nof_clauses print('c nof vars: {0}'.format(nvars)) print('c nof clauses: {0}'.format(nclauses)) # print('c nof instances: {0}'.format(len(tested))) - print("c mem used: {0:.2f} Mb".format(mem/(1024*1024))) - - + print("c mem used: {0:.2f} Mb".format(mem / (1024 * 1024))) + # LIME runtimes ''' print('') @@ -263,12 +262,11 @@ if __name__ == '__main__': print('avg time for Lime: {0:.2f}'.format(sum(ltimes) / len(ltimes))) print('#wins {0} out of {1}'.format(wins, len(tested)) ) ''' - + # Anchor runtimes print('') print('tot time for Anchor: {0:.2f}'.format(sum(ctimes))) print('max time for Anchor: {0:.2f}'.format(max(ctimes))) print('min time for Anchor: {0:.2f}'.format(min(ctimes))) print('avg time for Anchor: {0:.2f}'.format(sum(ctimes) / len(ctimes))) - print('#wins {0} out of {1}'.format(wins, len(tested)) ) - \ No newline at end of file + print('#wins {0} out of {1}'.format(wins, len(tested))) diff --git a/pages/application/RandomForest/utils/xrf/archive/build/lib.macosx-10.9-x86_64-3.8/pysortn.cpython-38-darwin.so b/pages/application/RandomForest/utils/xrf/archive/build/lib.macosx-10.9-x86_64-3.8/pysortn.cpython-38-darwin.so deleted file mode 100755 index 8037905889ba350ca148832a64d0dfd51f823953..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23084 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 UHjGwMkh6kwQU_rr#lXM-0A?!RR{#J2 diff --git a/pages/application/RandomForest/utils/xrf/archive/build/lib.macosx-10.9-x86_64-3.8/pysortnetwrk.cpython-38-darwin.so b/pages/application/RandomForest/utils/xrf/archive/build/lib.macosx-10.9-x86_64-3.8/pysortnetwrk.cpython-38-darwin.so deleted file mode 100755 index 7aa11a7e970e9b6d0a19149ddf63f889f952f4a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23116 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 diff --git a/pages/application/RandomForest/utils/xrf/archive/build/temp.macosx-10.9-x86_64-3.8/pysortn.o b/pages/application/RandomForest/utils/xrf/archive/build/temp.macosx-10.9-x86_64-3.8/pysortn.o deleted file mode 100644 index ba7953dbc2b8e701d652333c93f2d2aa33024d72..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252064 zcmX^A>+L^w1_nlE1_lO31_lNe1_p)%HU<U;1qLvXWME);!3t(#CAQ1}>11GN0O?_1 zU|@st*%=rZKv)Q>D?Yv?wW0*dVPIg0j}LK;2tn{+tTW0G7RWr1TRP@3Gb{lKu`o1% zC>V~9Pft#cPpwE!EhvdENlZdF4`xmT$Wsgq3_e;63`{W1Sm^lpl*E!mghYJ2i(`l* zf^VP-VXH&U+n@~zs}+lx8K7Q=D1egj@yW#{MVWc&a6YPk!_^=Xw;>e6bsZ=JN};<o zK0c|q7%B&%(A_5h4R>%@ffPXF63PU}EsPDK<Kt6OlS<R$i%W_?T!#2~mvF}*H!vGS z7^#Cu1_pIGh=(`nLik7|iW6bx<>V)Wm7tp!=?XEYtqLs7aMK&Yhw#88R`U{*l8REx zK<Ne5efRf6^q=4W>t%>P2H`_^U=pi&nR#jXAX#+xEk6O#-(&}&)z3rd8;hA4oFM5R zt9eC<dFiRenC{bLhvo}ekZlYMD|sP&2oFqRH7_?Y8SF%K_pMZc=!dw9fk9In!UvlK zA<)cAEGWoHjn7NW1vw8Repf-wQ_zHH)*{lp{G=>!1f#p}lrO|RDiGrsyh0#+C>KQG zc3(kaGP-&1pyt7fj65REE2%8N>fa<kh<oNMft<p?@Q9#!$@#ejiOD7LrFrF<c`5Pn zJ}wZQ5R#)1V%`F1gmjcMGk`>1oMmQ!Mmd^)Q#0bziV|~EA^OqFs})5c-3$yTpt>|F zA?95;#|+N9+zbpE5S<Vbp5HR_z$T)HUqLCvylGJXeyE1<Z$QmsKr0SG@g@K=nv;ux zg`W#tR!T51Fg!TN%wWyHz%bzwGlKvd0|Pe$1495v9RmXcsB8yeP6h@BX+)I)l_ib} z_2_&W9N^Jw3sS!CD>DPb3lPhr^+1V>N9SRWURy&o1_r}#hL<4Xo#4Fa@t?t?*HlG~ zfx)BmzDMUFuw3hbN@0&~ut6UG`Ab>Bf`+#}I&XM1AK{3OJ<KofzyPw(G2AiCG1M_6 z*rWMPhDYajk6zQastgRShW|Z!rxyJG|KFq6cZW}JYt8@v|9yIW_ZS`k8`XM%zvVtN z0|S5f0e(%_29M*e6TnXG-V4$LR^r)t!~>-4A*jabd=3@^`2r+X3li%sZSd)>J&>ly zFW&;v%;3@O%<-*ZHK_LGZ((KzdkCzp)AfMIf9_IlkIwsGez)rZkSW3-CEdOq9@f4S zN`yKYJ(>@)cy#)9ycSI3mv>=c@ag>S)A<jq!w1CyrBgls^Qe?^z(kvC_b`-%d-R$z zFfcIe2c<f&CXj0(kpbqm9w;$}g=w$p85L;syxhRVz~IphiHmLvk6zRBaH*+Gupm0% zaoqI+$asED*99KOT{nQ(KFQ#4_2{kL;n7=qz@s;`!K2rA0oXRMn|Q&F@#wq<7V_w> zJ>j8Ud%)x1e`b#zt5-pQ2mksXU}?|JV;<eE2RtlYPw=;ZLebUmKO%7X<r(~Yb?Uvk zYhG}8Y1_Q;IQX9ls_h6!n^(8b3l1-9o);xHhPNT%=he;f!Xw#c23VO-=W~zFd$9E7 z@&7PFlQz!_kApv%JS<Naoq>e8Pv;}BCeQ!JLCQS3eNT939`rc)li6bzlDkiNTAt@` zN(H5|?%EX|+O-SNT(!W%(sf0Nso`yKeByP>0*`Lr6%b3nF1h59?7PFG*VaxMln}o8 zbUuP6UC++rp8xqkk^dd)M&zX6(OtX1qxFA@sz<l$3XkRkEQk=C;L&{GkB8;)((fLf zwJX4SeY#5z__luIZ&}X(N&~JZd@MhdiuiPXe|ZBW(0Rkh@-u(S2@tzC;)O?d#S4(x z&po<5K7bM{!fc5Dnh*Z*usjbkzv2Vf{MUOx>7E0Y?om@MN}6j{f+ok;DtJ`o!Bm0r zcXw?A$TiX)-L4%VpQ8A$18l!f=MRtOBN@?-F^;j0agOn^hdsJ$5BPMJo&ZaGK#VBe z`}!I<@qvS`wBThc0|Nt+K>X`+Bwpa_OeCK3>*&{VuVs)#3}1U9@swX%LwF#!^0#&} zFfhDahGKk)6fCN+#ZT=4-`4*nJ|5kmxcO1a>(lxFwW$XvVt$usdLTv0YgnXsV8+6E zh_7o=d|jdh3pjZBg_J&E;Ri`${M@ke7FN3d|Ns9#I1CYKU;=7+-1w#gR7!Tbc6fC5 zX8iyE-?Q_&XXh8s&c7brMjqW!93GmVJ(_=WlzKr5;RzncT^E2#6@E?E4Ial`4}jPn zy|oj-)_8WCdvv?*@Mu29;$iK2fWJkYk%6I`uag55^B$e9J6`fLGB9`?{LO^NG=9z2 z08nN<-kR|L|9_DA{F<$x0^j4fE4WAE*?G_N;=ALnSHN;D%fShMFIZ1+=oO#NZwR+Q zOltluP$cEm%d^eH@&teLPX-1CuU?)F9+v0$o8K@nFc_Zn=se}|{gMykC!fym9?j30 zOC%5h)-BW5DbwNc|DebJ^QE6Wntw6#H`OpQFu>xYTcod3q@z2ekEJuDgQYv9kE1iB zgQGj7kEb)Fg9nrWJuT0b-hAo72&(YD8J;w}^b*uZ^60JI0CuQHZ|DS%Uf&Hqo$q}* zpZRpRf}+8v+ZPhK9^JJYKp6;>{&s+a5h?z6Kn&=vo#4^>pTFfYxT<oU0aBI*b00jt zzFf@=Dx^MoG(Y^|(Hr>#RFNNi&+PI4c;~O?N6a40za@%!3~zh1UMkIaIS~}7n%50) zPv93|na3~SGf#kDkYxtHpwA2eegT(x3Lqf^enFQR3Lr59keCBVEC3|t01^uTi6wx< z3P55BAh80E=EDje&By<guJCBRRHEn6Ycm(r2=e%T3+7&a0T;Uu`~p07{DLkPANU1% zEIgWzD|q}rRQlA@@*IC_z`y_heY?v!Ji2?qiK2UI1t{5Se)Bx|j|q`3JUXv?Xr2d^ z^gf**JT!llrF-;(n++blp;tUQkAXuDoL<4kcsBpzC@S#kW%=e|d9aw(!}45F5=dk7 zgC8Ef0Y5;dLBh(h^M_;e17?rrUlRPyYe1>zwr}eJ{#GGI28Nf`j0_CL(q6qR8$CLY zduUz<`P8HNI7{g-kIq(*Gr`3;sDlTxuXuvt0ng3@p5HI{GJb%iJUOpknQe&Fmo}kW zq`6b1(c}LCaQgFX{=v-ObO)S-L$>ko%QJMBG=1qbY3wd(`q5d^$kJWX^ry3=k)zwB zsk5Y!2b2^%EsvGne7ORY&oz&G^@eOKFuaYhfnUI7)&zb5pIHm|1zBeD3;N6iMewW* zAfW^Nf-W;b5j+zV!Lu%a#2$deKoL9>6v4AVQ8f!B1d898Nb&32dH@u^BH;M->b2SC z`TYi{eBu{y5eI1!=NEJl1jVnQNAn>C&;JKN@q3KF_0>O6b8spoJNr(6<qFr17f!#y zGT>N8$}g@RFEqe1__Glt@>~CxD0_5+;{p^k{PGO&{Nd5L7ZgR{gyGQ*DNkDem#BDj zw?=@<qviuFAonAy2Z=+~LvpDKr1(Rw(2>;FqU6^Sb&qanUWGSKQQcDuX%u-tiUg0w zBcQSxxti<*)s#dR4@W?G8pBGs`(Dll$%Bl92bBU+P{GyV2q%zQP<ViX6<IAv3?+;R zmt-Zfu#mwX9?%9lqP|1!Ur2a%{`Ki*_vo(Y@a+8Kt9it?^SS52|4g2}?u;It2R#nH zwBv7m2lDDpQ1$r#|9^Ym?ot6?&0{{DpF9r!V)EGi4<aG&VR_4=v-Uu_s^`Ujo|eaa z_?<q0Gw@1~?#|K+KAo;7JT1?a2|)Y@6X`tX)oZgAR5?M#5Bqexp77`{z2Mhtvbmeh zsgq^5UvJHB7T?w<bs`>}_kB8#`E)+=?K}cj@7wvnvon^#x3iYRx3g5hqucj@kLAG< zUZ2hb9-1dW?I)JfU!dG2=F@rHqxpygB1OCeS&Axj*wyfx;qBM0KArEurbFugu;Bfm zVizm|>VR|}hcLUrofD64QLsVKa0WGvpiG}mSW^RDzku2k!2uqfzdd?Q`y`<4Ls+Y^ z`G9~&Co{A+2x;$w)Fa}n@eRmgpU&PNpklrAh)1XI3D3@No}K?ax|uvWLl5|LXK{FH z9`$Vg%Tk);+0CQk*<GT-;nDfoL-RDKA#uFb0oqFNX#V|=zxg{TZhEJJ1owgZSg_s~ zNULKv`~L%uo$Q?~GvQ2^nJhltwFf-A*<U^ZwfGMHg|tn;#(EqFHy}WP!LJE!j(8jg zH$@;Kh%PB|e~VwUl>t;<9B&nXx{P15RRJPm02T4P_!i!N*$sB_UXY7Hb(2r$J5Z1? zK)N&x9^GKSc=ne5cj<iD{E*qB`5!ZXb04VY`R37jlD~C3sI>}e3wiX0%;fO+e%Yhf zWFDe?_h>%$$HVet>37f05ETxPUtJB~8h+C@=oW;<rbl<|36E}Okf3Kbi%PcuOv1C9 z9VF<{&FrGB0haP$@#*~T()kMP#FwRP3=D?1K~0+1WuBU64ZnfvBbyJMHk-O@K5%r_ zY+~uI`5@3)vx%d-=7U6M%_bgD)6moMYw1mo){`Yl9=#%)JbFz&7$S8cyJh}$%Ixy^ zf84|JXXz(U>i6i51l9JS)}TlCR8Z^4L-Q~w?maHPhK3@jeumWcpzfpQzcK}n-o0QA zy`fjYZiNSDFG%>ccCm^_ugOf%SOlb+hNov(eZ3WIQS0rJ9FN}O|DCtMO{9O!#hixU zKusjm*C8I7mkqy7=&t#|(rL4?yXFH=XU#^ChebMTHiA4X(^<0->|qbf&!sm&?Hxsr zUY?B}y)GYEKtTl=kLU)4*G7;3$2=@Qf&F{Jqni=zWeiVt`!;xVhjw6iR?4HdwgHrO zU_L$J(aqq|?c4BLwO9(xn-gIEEA8-Tz0KcpgoS|ts|Sr=2ZKEbaUUc;!QK;qdQSq` zdpAMeQ-XL8OMLDG$LBAY{~|dsW3bzIfk$`f3ap-6fW>nQUaJ(#qIwS6zlF57KrPJM zCHYwWX7M^4>^D$-PUZN66g?ijz70OT;BvsH^S@8$H=k~B3HRdPFK`<Mlm<bAFh0HD zk^xoCEs&b-t)N20v)e_5!_(SDMWBQq){pY+bW!1W&5J15TtMaFF;GtN>CWWv(bn|5 z_}8;rM8!k%n#aL^OkTY{djDYg1k~pN7dV}zCp>#&|A7J)GUx(MJD@!7*&F&7JP6eJ z)1&z@bBUry=TAg&GQqLi{Qoh>PV-I^NT=v@>03~zsL0=w@vo=mS&v?pj-8-_7uKG4 z>=yrj$gxwrGo<4O68jIFEz$vJhIFt%I!tFvPk_Dd(Y;jzRB|>S`vVSzQpeYRW!fIS zJYAlQU%h%oR(WV1@@PKv1<8FL&4*Y@e|dKLfI{U2x&i3H2p^p@ybUTE`Q;fryWKfF zwb?xm{$TR>f5OA^aB;dvH#jB@ziF4uU;zbDcgPJ;IS39ik8W@j8h+C@nSn(P6pIjz zFol=2MIZ`&Zg6<~KMX5tU$=R5?*&&At^Z5(J-S;V9!G9ULen>Vd}uF73DgmLK^B2J zilFu?2RO_y+p8dPsCw`y3aD|5J^+Q(c7u*TK?h*K?N#s?4kEPC+GnsXE2QXc{SVRt z?#_Z5h5Yj1-aC@{dqG7k)IE^;58B@Lz~O$7I7EFTxUGa}`5ZR9{c;ni7XWU*LW8kX z@U=dub%O|3P$Lx-Xdw3>I|L*KF}NEZkRY|707F*`5`(IR1R|(G3m(NoG7&B4KuW+t zhpYr6v_Lk3f&|@0kQmfPcrfXDbhm<n1EdyLeC!1&fM|ra-}t#9?LVaPcn#0af1RZ} zIz#tB#$@1Q$R5452RwR9VSN_Y6CT#C7fNKhefPk}b58hn*Kzn-*9nv=Kza`lEqlOr z!sPf{K=JN*+#S^7Wbi!h4xT{tJPw+yX7K2aJpe9jH1C&y8<7WpGlAw04!*GCZ=DL7 z3I{c{JUfqgcDi$TcCvf)vdr-8bQb{W^Xbk#;i-AoxAkqED5MPYfi_Hh8Q=JJrgL~U zyKzW(wB9Zie{BaE`i5mSkY<n8+a;Qy0Xx(HOaryA|9Ds)291x#o`8*sdNd!=KuT;r zoseNQes0gsW1ijipnRtRDmXxf!K2u-vz`MS5}<)SkJkUCe6LMFZRzgX17Ho9wu9;; zxOR_D=ujZc+1UF#koeou8M>p>7e^Fsfw}_J3Guz)VR@oNuRC-{rvTWsovtT9B4*g* z)#@dvBZHX~y20j@o`T9yE5;{NFUD=K#W<+TeFEfdM3#Ys_YjJ2kIu`Uo!@=B^ErIF z(*=AwANXj#0M}NQABt;yy4ig?U-@Vr^6b3qdGI%re=m=<Pv;2_aDG|^8Xw#N>D>Oe z_tiY&)A<lQr?L;x<NfH-S-Zoh)As;>`$15D=;9w=%QL?GP7i%spYXR>FoA{;V=s7g zhMw^4JmzV6gue|mumnzEp3VO`iljYyof&;BU+}k;GBPlD_qyz5@UXnW-<HnEz~I^I z{@(}Gs(8p=B5QaF(jV+LcI+%=@N7QH;_?5Ghvmi6cb=dY`44vfrh|+O3=_JU9Xnka zz$6Qp<N%XAU{U}~ihxN8Fe&5Nd{n`+`S_30V=o&SQC-`4#H-h4DX2h!xVQ6=Z|4V( z?$8rH-LV(^drfA6e8ArXaw^0ZAIbzl{RYoomL`xV+I_(W{_p^g3KsnE==|t$@Flay z|AUU5Cmov~GJ1e!X-q(2q<J!pKaV+$zu*9acW=!s14MiOGk?9y_6uP00hs*onZKT8 zyGQde0gvW`|4Q%sww^2zgX{k6$Y0O04Me(Z6Y%XdY4frC!QWy43Qf)9NCC><x);<B zyaXEM1I?#^#w|fE{N!=)6|=|xL!B34?rQ-J!E2s^+hF(&ks0{q8NgO;g;D|#o&tn2 zfH?BdztUTv?wdH=2#7RHk8f{ID+9=xt)Pi?pU!-am!R-=HGJY~cnKcN%`^Y~|BvK> z5-G#~pz;rt9?U#JGYF6_;CoNa{~pah*o*9;>4n*`lMNKrZs6qL22Kuc;N;*2P7ZG1 z<lqKQ4sJ4@&Bq|g;kb9N%p#B0OLgKto!5OjkNI{U_w9uA4Shj_FF!y-cRrm0KAi;| z9-R>azLrNzBz-y$_-MXB2_I1DfinJrR58HDUyy_jd!j`X%isV1U&{Rb|KAYWegF6W z|I3sAKzv_Ncb*Bv7ybvExS4=DUef%=12jCcA2KVuipv8u;}Q>^r8)SU*%Llr>&d_V z1|$vt;BQ|Dit%250gvu*0S`^kAQ!VI|N09a`$8dr)x+|WM`!JfVl@xOOCFYoJoue1 zcpP^H%_uT>boyTK?7R-@@`|_`{&zKe`&t26&a0Q@FDOTO^x8OpVwu6S^Qcc}?go!u znP}hMl)DT*ov8<WI#YLe_p;P`_PQKp@BodP9e244Z4S8Hg|-J=?t;u=@a$&u?Jnc+ z)I3%a<I(B505l2@YKwOs^yqY50V&9?f>SwUC<-*w+Uata!?TkGH2S*2vzMjav(x3S zfN$$JkM7b1bz+{qF?Tt@U93-F7y2@O_vy6uY(63Za+^nQ=?0H(_)u%?4p5Hwu)I;K z2b+3<tZVRSKH`DY1VD@zbe{0AyjgO|qu1kwN2l)r(&t}6J-648W)`ed2W?o`sDK&@ zhMv73|8@J^<pA}LkfshT!2a>*MmSpYbvn3-fe;aY9g3QMA?|gc)V-*ogJ`3mr&kHj z&hH-G>^|M)9G;fP_*)>o&)N%~-SHegowX-CI$aOERz^6{v-#Kykeo;J;TN8r@f@J& z@Ui?*QtNTt`3ES4cpP{B0Hwj+_w26w;Hh2rqU5MgZ}JPz&i|m%UeKH}xX$ZEv?z{x zbUJ_V=yZPJ)yuNOqtp3^XLs2P-|n;zo|<2LTc7xJ*Pf_r1kX1>))n|NKK1F${_rvj z)Enupz2MQ!{+b2sv`%@?PInHEZg&pPZhrxfPJa$ao77#vv)f<7qtjo&v(sGy)F1>k zSy6^)4`YksQoh$(;FcsL!sR@=oj-ue8Blo$X`g`C15`ui>k(o7|370aLnH%3q+};2 z!$QWO<(v$SOdOq@4E;>z?VJo(nRq%m89JCXesVCJVrIR|!O+OUI+K%O1&i<=PKGNi zd^0&2rn9o1;b7RpD%{P<@QBsuH3!2=_MlEqhTrTTLA`hehX4N=<$^g+b2D6J6rRV! z(7~*Jnw#M#>tE)1JPhABuYngi{r}I%!yv-IAi`n9AfpY|qrw1MmNJz|_?`g63MSAB zljkfOIPM8BoZt<3FTgN^?>P%toua10KPHCtjI8IF7`8AvGcbH-<oU<MaD<8D923JC zrUFn*gWRB~lfRCc;UOdIKPHA}AayI5c-Ap9d|~4F$Hedlp-zKg1``9r3?`26%nS>d z92giLF!63=VR*~bz{tSxmKh}cm3cQK*lzL3jI2AD7-lebFfuSKVB%QC#IS-1WziXE zl@Qnkgo!NZ`cjxmXfq2ufejNQh7QTdELO<PPbtkwRVXORFUw3xEmla(Q^?FKNi9lC zOioou%P&$$%}dTt$;?YvNK{BmEmr_9!c)jkQ%FuMO3BPi%*iaNR7lRxD=sNY%*-o6 zUdLL5=1%BxI%1p#Rui0GR048OVo_0ICCJL8%#va~hJs3v)q1H#MfpVx5VD}MIKQYQ zj{!pZXJ%$HI472-XOt*pr&cEACl;kZJXKU$P{QEvpU2>zl$DxXqL7lGTC9+lU!qW) znwqOnlCO}I3bHV>B(*3pDJNBr0TdMJsYME@6$PouC8;S4dHH#|RjEb!VDnI95_59$ zlM_qwi)=#dtgN8CRE^@ys?_)rg*;6K^*nV2(4ywllwyV4#EQ(^(p-h&(t?8gqLS1U z1&}%hN6@-Xh2)&XymW=K)S}|d{5%CiLp=jMV+9ScsIH-*fiZ}0q-ScW$pH1YUUD*n zerR!OQL%nyW>r<9zDs^`X>Mv>NwI!FQ9j70#rhRRY5ElfIf<EhsYM_TLoPVt<5N=8 z7y>GN!5o*=G=|*xq{QM>WTAK`kU)MCOac;i4DtEkFl5M2iZ4n{OU^4{2&jxN26-dC zgaJl_mR=W?XXe2ra`N-iL172d21-f{@gNdvR6u1|ViDB%{G@o0Sqvow;B~GH$r*`7 zAWl+Zab_}1CbJ|p7sgIW1&299N@{UQQE75XK3I8KDu|Vwn3EHqpO#jfS^_d7J+&mU zq@;)eN~e|PC4+>Ep~6raES#AK){$5opIBU(m&_1Q=?J2IQ%f@PQ;Hc9bK?`s6EjN~ zO7jwnD#1EHLZAc$mdgVzj4vsOFG?*aVgM0fB_##%iN*1GrMXF|MGOIzeqaX7$h@TZ z#FP|<q)fPpc}elbrAZ}4iOD4lc}elPr8y;;1v!-<c2R0>VrE`SY7vN&l3A9Up8{eP z<d>%wF_fehA)Aqxnx0saS(XY>P@D;4Cngo==aiO!#gp>$a~Lx73QIGKz~*P>m8BMe zZOtjp$V>yXir}ooJg{vQ`C#iIBq+f0KuMxFwWth~VUpt0a`F?wIy3VMauSnM!T!rj ziidHLJqHs*_9RRU#j`L$h*yzJLpT(s1mR$q2-M*)F4O}sF2o~gIr;fT@hO?0Vi6Q% zB}JvFNL-j=bY(Dc4CN`Q6(D1B6HAIRD^Ma4rUhLJl1z$I3rkb;l0jKA7|MhtmEywq zoYcJZk_?8N)I4y?DlUvq&d*CuEMX`v1SPsu5DSz;5{uGd3P72Lp**oTzPK>HI43hX z6{I$?xHujx0nWMkNm+?S=><jk$uNZ=dAQ=_{JfIH%)DZT{G_b>q%5$y;zD?QB3uCT zSy5^M$R!XD<t7#sfHqGARQf_#Fz@6Rz`T=N07~)2$wiq3B@DTs+)|7r0I?P3z><Ra zjKty$1`q-EVn8KWARe4?K{+3sw@bjq0W`<w!?J!pSVu`gJT%YeGr$-yiNxagq|&rB za7J|kGXje8lZzRW(&E!oOQ2G47C0yZDq&h6(%?n^Nu_C^-~z=I11O+Dk-|`vnwXNG z2g=GRnYj#U`9-;)_{vBuNM!)+FiA-*W+*OAf)rfE;L4~dFEIyXcTs9iYGQFJ!~zBs z9@q^f1@UP)iRr}*-~zWauQ)S3FBM!1f<hxDA6(#-6eWUcnN$WC1FW?yvpBN^%ql5} zPtHk&l)FWl$r<2f^F^r)V0LZ+EQrce6SH$Ni%THx1ep&m|I$-SKr~Dhhz%|dVGNi= zF0?ESsDva0a4nPrDfM%6;z8030hP{frFqFEnfZAPxj9g;<>tggJ(8OWDoTq%wHBBK zGNPma6hWX8KcLb*wIn#T1SAUDGXaWx5H3kA0!23ngP0(*l5_HlON&xLegId4B?a** znaSXkl#*JUTm&)_RKp|}rKgs_JOGga*#u@4BgteYBZo>}W(h-P9wKld6&9F;nU$AX z&XAW{4&$a3rKU1~2$(=-aeO*B?m*5f2Dvl0C?7;6Cnjfr-CbOol$?`TT$~D)g~bg> zNlI!Chyq1<W`16LNn$z!dcsHpx9F<C1|h0W1_TrA4p7>SFJVAb?%*~K$n1h5Q2FoX z>Ep@}A72ci3lO$|EAjXuhWK&@XdD)2<QJ7N#HVHEq%y=OrGa#Tatfra0ciom=Om?p zY-ET}&d<-zOl61%#ZoFmJSg`t#22TgW;3J}<QF5mC_gO?%+1UzF*AuTf#d>kRsgv# zzPu>2B$Xk)G>IWTwW6db5o9gMu@MaMr9~j|Qjkj=gMu6*<AXh;T;oF`16<?d8RGN6 zj>}16h)>GNhBykE>T}~kG0Om=KqY-{d~$w4B||PW8G{pQF2p~%;3N%dJ><q0=j4}w zlP#?M6(5|FU%~(qW++R{DNSX_jfZ7UhFoZF%#8=72!{A5A43DARve6(58IsvQecK5 z3KallE07yNicHYNQuE3fvT_SRr5MN-V-O$Qv<7(tR50bGgTxI@(FL6oi&9*{?eh32 zA4>$UxFm%kKHiWaGrt%bvt<P(MJfnxd|63SPJBU05x6<X0BVLL<`iTkGNk2}K+3U{ z)MSRV%!<?$hK$q-hMd&25{CTb5{9D8^o$aQ;^fTKypqhc%w&e*jQny?-T*TS@<GuJ z5-P|qW+=|iEGRE#D9y_RmD>!Z1qG=^$)L7vVoFwNaY<TcYEB9RNH2s1Zni*}Nr@>* zpuC%3T#{Il%8;6$2I8hAX6AtC^!$9VbYejPLw-SOUT%I$Dg#Izqz%WAna7Y{TEb9L z1Zro-$HTl7&k!G9P?VaS32NrYg9`lAL`ZA4prj}z6Pkj{GgC@3KuU{Jz?OrUpk71) zs4Of7@rqKCO4C4$ocv@Em6jLJkXn|SR}v4Z{E`xrvmsoD)S|@V)OfHILuPJLDU1zD zscE?-P?`96P=m4pWD-~@IME__$%zFZP6bp^Vo82(X0lCYUWpw;e0(Ojs|J#XvOrk` zi3`<S09OWO!IVL{5M@z*-oYit@$rThuykSyP71DN3}BieKFSZff-EdjCZJ;3H49YO zr{R{yrqir652_c!0O>||nI$|TUCS8YY>-Mc7a}Rl0ZF49WD1UN*D?k$4N`$-08{~3 zGrANwQeA_*{et7oK%LQ?R98quGeCHt-fJpDa$-qpdVWzQLvnsj4k(!>gSuc0x%qji zC5fPBe`#)NQD!njNoH;;LvCtuaUy6JWMWPZLwr2M9B_>07J!m0s38aLl7V)cX6B{a zfQon>h2oMFE35c;Ln|u~A5?^8mK1~K?2skFRUf#|3{qyN07^s1ro|`c=jP_;*?=0; zcA&t32A7dxJg6MWOorMDRp;rGWa#Q@WDp-;l2Mdj4sA`wgU1M5%NVc;lWu5!X-Ry3 zT0D4jD3YPb!r<}?RHuL{xA@$|;%o+R3I~TX+|RI3L4*}t3KCMF;D9A@Lo>J}RG+6` zaJ(g4&@<W9)zt#ZO?3?lHj2+>fN>eX<zQ+NsK5c0h^dfb7HkWF=m;r*nUY@wR&R&k zBZVD`L(CIXQi@WGi(P|~8K6vtqSUn1B5*e*9-gmpX!1^G0FNid!(0vFp_l+k`6vb; zJf9ojU50R_O<8_s3OMm#(PU@<9X3cTNp%fK&SgMwarw?7H?aa-Cc2g}z?dMlSWLGB zyBsta;Tiz-6o`XEwK;g?BEJ%(7RqFZcPU^1r<!<JXn-ro_{`h_5+hSb0g{QJX(Atz z1VD)t+<2=jNVUP45OowlO(&QM@s6O8E{1rQ%(S$S%7RpccgRVkptu4DQ#>f1V7_FC z2lZo%OHc&C=}$omPm0x1NK4EqPPJo*4=5>urFv+7f$By|35F)n6b4n{8IbI1XaE<> z2c=&G50ofVGC{R&VvY^i8f1sS)fFYeN;(BCJ5U*zmsp~s050Ab;+;UTmX}z<5bv4B z5Fe6}n#WL-nv|KBVgn8W1yB&!F~o-!FyxnHfbuIz*&ih_gGvBUf`(U;#6=D)MY{%h z2OGtc7`4Xc#i==|$tCgmd7$V6jS-|4fg8dgE@W6PGd~Y%Hc@Ixbb+Bkd^|LTLkqzG z?=rvOctdmWNN!PL4#Xvic_p4n;MxMzQGw|IHPKSR84TRlPDfU518S4PvjDsd!)<VK zS(0lRs6AK&s^Anr+96GPhz0TSWwiC1fvc-412~;REW`)^sE@!(z_|iix#IAWfvYRT zOQfYJP>jG675<ojCb@W+ax%gPrqva<O`vdr+C)<BGPaD5Co0L}vD?tq6`J^oG>gO_ zpoSZf!Y3Y7>_gfw@$p5VRv%~t2voJFro<N{W)>k;8OY5xa8Zj~I)aKnXdw%h!`}!5 zm6}DV1;_?Kb11A00%{q7+I$5_Zi!FLNzJ9PgA5QAOgy-I4hoZ^R8Xl7X&r+)#_^Eu z3%HE{k_R0=1EPyTl`W`62x>=HFvNq#LE?)N%NgS1%kzs;K+<Tz3-%I2d_ZDRVr~c` zDHs`nYR6m*&x2ZohDOK{;h7A|2Zl(&4{9f3HXKdkL4(DvKA8rtK1l|yuBP#zfi7_C zHa)cjWHYpEpr_TIDHROy&WU+Wsjj&NC6!K~o;r4qBgHyeLeWt$L@Ki(O*DLdKxt9B z`eYiqf-4C`c)$yOicCRIyP%Yjnw+1P0v?n@6tLzP{-rpMgH7XIP17=qic3KKXb_DQ zy@s^5kmg=9D+Y(7YZ(KCK?lzvtfaZ`Op41B3tWSOE#etKEQa_HLx%VeBZfTC@D_5$ zXQ)HrA^Ke8l@G~~HWad%@nxB*<(|pGM)9t$DD523{4A_n4pIY7+c{}q^`Ox;M5i4j z3$6~3OM0ZT3M>a16abZ>AcHciQZdZ{#W5sn8=7NrBDNyXH8B`e5gW(D8)&v5Q=p|B z@y3`YrKV@*xt1}2X;2rTxCAth25$3_WukFvUW#iOLuy_MS=!B#!7gzvV}LNoGQ=bq z;s_8$mH}o(Fjqhr(10mQ1<gIAA_53q0NM=#r2z#k)HW%x5o=NeaXW}2%kAdL5I2K@ z5W*tM7}I2s3&4hu8<!@aK_gH}21@lvS(xZVZU&hhb}a+VI)bK&$uR_Zyn`J5rm3LX z8<eC$G+AMpS>c)sL{WSL=<SmK(?0P1?ft8fysd0J6^9=O5;(PY_g0vd=16%?TH zcyhwg1XKpPmN9@RkPApH@eGZNQgidmQbBVLY2Xk=;ZtN}acLTgkq|yPM#5@1WANAm z$>p&LXf6XZkeAB<Vu4&hvKeN@rAfslMXtHIpvia8A&TTgmpP~{pIDUY8f+ZT0A-Wq z9JoQbxget`atqjq++51s5#XInnE|=E)G>lQf0(3Y=B0pQC6@ujBFiffGm<HBK!A5L znGpf89HgHtx0@D$ybTEeFq0Bf$P5Cg8$f;_FAR|kAj|oN#-Kom2ls>G^V1-qfg(f| zW62C2bk~s|PS{K$&u2#9(8)<G2F-pUg%?zW8itY^TBuH=Ah0kEBF|gq;IM)uuDpD- z07Dk0n(^cY9Tt~T5PmpJBhQy+;6MZ?FN`om5~Y^m<c1)oGbso_?1nMKJ7**og@Bhp zql}`0{0?mfqK)yHB^HBL{J91t2YDwmKsZqSs55qG`ixQwU6Yd;QVVe#ZIn|2Qj!B6 z7Q}8lyvY*aog8c&4=&=dtAzDXpbY}-iVzhZXi^Ke%S=GcTi1YOPy{f5*m#tJT8A*D zh+!MF(13+vKyog)$%EZ_=Ah)6nxE#H$pB@6W{)6~E;x-gG%CrD2laEo>RdA!kh!?s zZD?4MAD@|50@0NW(gow;)07HYoD0>InaO~}#jVR2<fSsuS|^715b&%fl3KDxnIU5? zrr?%6G$_e62Q|HrYYK9tl4S;b_y@G66*SEU8p|(AEC7#ifQPTphA}9!B|g3!VK`{Z z4R~G|Y6T@B3LSJp>RXWIP=qm*I0k9(h~Rh;V#xwZ*kmLYDQJO54iTMwvV4TwEl6_? zC{`m!3uu}OKF3Iw{jkw2N@Ipv<{*X_DRvQPa1k`aL}3ge4cAfXB>0dWr3S$U?kF_} zRy%@M3c$uO$Vx{z2Jy%<D><<sF*&oO5;V98Wl~x-m=&dh2Rn0<86YgG8Az!?=0&OC zolLH|AeVvmG*N0IXz?P%lc3FaiKRIu;HBfPxu7Xwa4?{VQ)(UD1K?CdNx^JrT%1vq znU@`3k{_Rz2^tPX;Zy2RQ}A9BP@)3wIiWQ3z{i~_H3&RbifG7@m1kgPP?U)wL)a9$ zgery<_<&~5OcAqZ+TiIkN)lIrk1G`#bp<}I6gTS35(^4Ib4Wqn!KU#H5Dukj8^uh> zxF02f1v3uZ)1fdyAeluiU!wGu$jUFEG7=K<C}knIjKm^NslzP`N{ch%!80_;3~)B3 zrdkx_7eEXxV}LO!HPaL}6GdsMhHMZeNf9=$MX7s`%%Q|Nur50!^HQ8Opra_Dl7Jey z7GfNAaxL5}N|O{U$SBXXW|?`#sYNBOxscF@@F;d3#2BcdREPzbc~pr8B*UoYQR+nm zc<BpL_tZ1MJK2>AH6+y6*o~*$`KI8VYM=>NFoV*7g&K$5wKO$6*plMGF7u*P@SzE= zxzJn%<x}czbaN@sSV$&PBWs}=M@8>ao<8AD!=9vqE#n~tAcfTrVQYddPzKk@YHAT> z3)O-jXNW;!g`)lu(&7(FTO&woKq!nv*n$?wus22iGX-yV1a*)>>nlM~LXmN>1x1vG zm7#HZY6)!DO@5JU8R%>U1fOzuf+hkX{Y~&p5@ntS8wM($sA(3J{D?XSNmg!#E{p(| zKa~3rY8rKd3&}8w!wYH_6#@)>g#?vC4&7Ml1R*w4DGp0?L#Yv{s4FR`6{e`BQYlC= z4W&FpQO%@AfMQu%L9I~5Vl<V47Kh1{hc6a`sS(JS%P*)E#+W8kDTuKfOnC@nnoETM zhOY|&2P?&ngc}Fz8d2JkK{pW6C!(mm0XGslxJ@0yFjml#)mDJJ4Qw3ctp!6P(AhC% ziA9--c_qc5x!w58JQx=g+msCK8Ct|cjz5Y|%u9)fOgw?D0M8mB34$!5D3mSZ<1>rF zTVKKEL)jo>DRI9!bYnW$Oz<v6kckvI6xm41mKhkDf%YSp#Dh=c0&iRekF*!3A`4OM zUXU%It^$%RWenh*rbrfpY@sBa4NW0l0dHM~%qfF5j-{4>V-)N+kQEdKJjf1^M-X<v z`~epM*+G#v3?SY>@d1cKvB4$~gTXFMPAq^&G)w?w0cD|M0*O<Yf#4Jm53c0I0+0<9 zg^dN07oZ1kfDTQ;6s3kuaF@euLWygrAjl%h0?h&`(4dBb0}gyJ2<%uC@RBmfX(9y9 zL4h3hLgCnjp(VsokPM6LDo~)Hh*BN^xa^{^WHW|%0p0OXKIP8FG@mjDo5jb2&X)$q zJ%|BvAw`+R5VW@+bdDBiP8+hu1j?h-XfsfCpIHK$w+FS9z^hoOX(qMIf($KE5{RI* z2|7?LsnRtU3_#TuM1WF9f@ZqYAx424G0@?Cs6F6TV>}jlO06|CiH`?Qu7DQvz)}XX z0L2zqg3c}|sEmg!K8K74LPqhxhdZIk(9k;2kTbsHe<;hZpfVD)m>i2gaa#;JV}%+% z1}$<&vlz5yB|aWQf_Apy_9f`Fn}M*G8lh_hF5Jozb23vBOHx6p7rdq$w8k6Jv%w}w zsfUfsL8U6(V%Wm+;`oBZV$cp|JhBXsli5ISWT=Cj)QE5m^gu|+8hiurv?R2_0+lfV z9gPgCcHj$gp%STuploY^SnOpBUhIXcJ1-SYks??Tq|k*LWR{+jpOlybRS4l=IM5t? zcyVSjXqp3bjBzH?dM>Crpt377uebzss6Xg*e~5tre!&Lurl4ypN?bvQ@gS>U01Jcq z0U3!!sVVWv`K5U!4DsMYXyfCHQ3PS!{PMiiBG3V=@bUrFaz;`L56U`pBXH>eb%65o z!1X)S7EpMDPD=yT^iUy0h=BZw>^4yUIxz**`2~3btQEn<qs<J|0stQu4z&WT6?$ek zR0yOU8l&jeT9y{4LPE^7i~-JOsDp+n%(KwQfy4lIpQ0%RHF+T^0^FnqGm+c@HPA96 zu{a)VmunCxij6W;TtSDuL&O*|K_?4?&V!9-$j?ho1s^L7ifGV5z3~k3!C)G4gd)s( zOSnRK6voGAro@A`?HC(@&y5BhR2~m98m0&87^BP-aKQjx{R(egBP1aP8iKPIO4>Kd zOu=%95L6>LgweeS3TdzyQjow;!Zk}zEy>9TWfBMjqy}OiLP-U9l)<%(0m8td#55Ch z@RVyN1DM99pa7}>Of%HM4&ue4)X=;rH9fPq1a#nEVonZtEnR?H87Rg~!RH9O1_c|$ zXS!xGV5q}l8YCPc#T1&q3{627aKx8qmSn^im!xFoyCyN9iGU1*CT4hWm_yG`b}eIo zvOucP%!V#O#&!y@MR95g_yA_e8Ny&D$OLqIOhBhWgXTc<^N~+*fx82`tqL(z370Ve zohJ=ClqoS2e7Y~X$;L^Epp#*e60w?VXn;5s8g$r3MRF?Sh-i=_(Y%SG7Mo{{jUjz$ z$hp_xb}6VInwgSX6kn7IK3o@EhJXf$@TkFJwK1p=O)ZHB`86rC1i#Vv6k#zNG(-rC zrTDyjh%>W5g#k3`V1iimnt)DkcMT{5pU)4HM-P2d@G;xq)B`>P9#$~GqYtVe0BM;$ zTn<zmf)3+`pU7S8ij*-x?O||T2F*9cAp6mx%pBClOv^2S)OFy)Ez)w4wqU}of^32W z<uxp(z!oE5%~+P8*o62p0Cap-Nj#Xt06JhlC9?>0#1TVsX%PeXT=e*q)V%zn-1y>> z%A8aNC<k;Vcu8teZe||nSZSzWVp4HxUI|PI=+HV47h*_Jeko`$7i<QEjcNo$tR%lY zu_y&xZ8E?_;`34yi&BeA-~wPJnR#iTc&tPf%}Y&>hs)%Z=H!6SnP-TPPs=Zg2c63a zF0P>wZV6YAT;>aor1<!}#1hv`<U_79^GcA8xQ6Qh9bA}~SYl<R#SkA4xibNDOm!;g zcy#15uD}H|sF?<m0B=)6Rt-8F4(ZTqEK;DDg*q2>*fo+(P`!i>!iG2Th|`XIwlz54 zgHLygN1U+?+m(#ij)&<*ScV~Z4s9luldMsXKL!OG-ta`V9Vxhw&iBi7MVwQeNmz+D zSPdjsqL_kq?linnfT9THXx@O#TwL~{?bE_y9rBsdxSWJINjek#l<3U765JsNKPnMC zOb*^-jI_-WHBiycgr+2RK}SG?1`G1g&wB=CGaSb~gDxC^AI1qC%!8#uur~1NVUX~{ zJm)zR?VRUK&;eycAMOk>ADY>9K)0D8TSn-hc2M$0Ne-Y*?a(9vbuTeSAW{mchuMN0 zK-x*o@H9<S-UXfb3r#D;pTSI0`XSK<wDAC9LKkEM5oZa5MmWd`ej<$rIh-8hsc{T2 zxn84&-AMk9Pt8jK9i9uKpy%p>4%0$9_ZL(d;F=5pl@g#$*q~|=)bc2Xo?8q)SQn-d z=}=!-D#UrXYd|KJGjb8NDXxQgv1-HaC|p%21t-~Nx>DmLTU@3<%PcG>#|C7go-_<9 zc;H9RB04~ZWN0PLQj`-~p$#WuZAH;bnzgXjwh6d>3Ds+i(lYeK5=5xe`Y`8`s*h;v zEaSm>3^WxC8is*pG^7TKAz`c0%s^_8GSs2?7i28aE`#>Q!5u2%gTVr6dpe@xBJ2lH zf≧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%0AO%9@98Ag#%&Pw+ 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 diff --git a/pages/application/RandomForest/utils/xrf/archive/build/temp.macosx-10.9-x86_64-3.8/pysortnetwrk.o b/pages/application/RandomForest/utils/xrf/archive/build/temp.macosx-10.9-x86_64-3.8/pysortnetwrk.o deleted file mode 100644 index 972595fc8d85029e1a21ad144b452cd34d8306b4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 252080 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≧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�(MxI)jQf|7k+FqIdM-BugDohG7(ihJ38W>UK>9De1||iTVUpeq<1>K-SfoLf z3s@^Nh|eH>n45vY31k!-h|eek3h(0}qgWZGFTmv3L2^veS73Y&5T8XFbU`avFDHo4 zA$<=f&jsQONI!z{xj}pd&KKMa3=0Jq82E}9nUpy=zi=}!$V)IV@D(#MDGP9l@j$sH zj7-WBobo&j495f+82CyVnUobcwP4&bMkZwyP75ALj^Hb2WK!1PbcAs$7@3p}I6=3P z27x?P$;hN^Arn5Afx!<{+?z1U#_}*Qu<#i(%7KQ}8RYVL7#JAks(Ba~m>4)ac^DXq zK-#JpnUozkC-E>afNBK3YDOky56%TJZVe-oa)3PO)<`Xo>l+vu895L0Fff#Zw6-uZ zDMxUgg{f_2WKvGx1XW64liC=WlruPA@h~vdfE2egGAS2uet{|OU}RFR;AG~7THDD8 z>LV!#@-i^!@-i^+Ni%{14-}M&jdK|o7#S3dVNx;(scw)IFGwYWf*&t<Jeh${7Q1{d zOkNI~Jj4*C4qgTZ(0y}!@*t}j6_G7i&C9?5x<!spkr5P=AO$eDU4=<0A*3K$K`I#( zzVI?I2!P6DWrRG`TVi}rDHVhivQ|Sr28IZbR&_=L2?lT;fVyh_Tm}XP1?dz928$F1 z20jghJj7^a`xFL-XpodPBdA;hIanbng@K_KB&NeyJs-t5kP-%k<`f2oc_4XR#s)0% zDoa3e28@hM0$`_riZ+OI7?jqfFfhCVNt=Rff`#2vAqECW&7le^0{JXJk`OJtt@9Ze z7}WlxFfdfeGcfR3GUkHflM$vBEUh4(%D`Zo%D}*9!?+hB&BzO4Fevz@GB9L=Wb7D0 znFnkz#Oq4MsSFI<mJAGh_8?K1fgn{3N`0ve3~NBz95Cb*wx%*LTmZ>A!7YQwaVi7D z3<CxRK4%Q6_o)mFTxkppd@dML{Ammfnjk4x3@P0-1_pnSlsks=qhL}V7*15GPGex$ z4ASO>B*&n16(p3-z`*B?B5at>zz_uz_Cpfp1qXyWI6fjk;!KbTVNl9VXJF_6DUU`H z1~(!Y6nfJc7*>MhVi-Z~4^X`X4I8EPFsXP9ZAz!p85sV6w51};eFWV|qr{uRz@V4G zz`&P=EC-HvC9@0$h5&sA2EKG;IZz5=PzugqU@(wlVBpKZlq<+!V3+_hGaFeB<YETd zSs9=Lk(W_!Q3eA8gWR$VP=Uy=04fj}SlvOX3siDG5d^iq88ukq_!t;C1S&N_*DFq# z%fKMe%*e>dzzWJKS)gp&pjphvzyOwM0a>P54db?gLPxU^#%%*t)0$l{Zab)&)|>?6 zc7UpB&FL_1C#Z_oTma*CF)}jRvn=6bV3-PW!a62p2Ca2`3=E9gAm<76f-F{?1#&wB zM5GTP!V4}VbifMxLBfm>mEiUq14MiRviM3+nF29pB1jyn9Apew53dJkRu7_J61oDA zW@H6Z(G`G=ftcW*z`!6d9if0hH#`AS3<%5wDMQFW{GeNqz`y|N;R!6*Ck-vP1VIH9 zgKlR61H)pFaSK7k0$3wh2C8vg0t3Sdkn|#~(w7q$7(RleSHg-{h(5g^2@DLvi3|(^ zt6=WYmri70@CONPU}S`aBuJ81Y(4`6Z$4-WNn(yO0|QGONRhx!0}uz)(9;16>;okV zMnw~lv%%dj2E&a>3=9GXp`|HPsuTkQM4G{9M-l_WPmnRk7?}h>?HMFV2II#`3=IE4 zdN*2vOk-p;;Yem+&`V}u5ZDCurXnN|?B+8tFlew?fTRRYvREfGFwAvfU=TPBYHQae zGcbhDXJ8OG!=%h%+5_XAV`S6@Yq$Uo%_NW&4EocO85j;mF)#>R0{I>)xH%abYnS1I zyy+k-&A<j+K@-(IpUl88O^Sg*;2J2nkc?+Ad7aF_Aeh3yAh5X*WFaFXvJV(oPf9Z| zY~f>I5W8f~vYU^AK|=7ZfQ7apxFv0QiJyVt$Xo^n!B?Q5l38WQzyP{zPjCs7<zxw{ z)N7Cw=X?nUhC5~q41xm8Ov(&atUDw@MzJwlYsxS%2y%b~ZCE7)IhZ;3Nis0Rfdsig zf}9T|85kCUxZGgwM@a^TA0RFdh|9oW#d-*A(tRe*ladS!ucR3m1RpXnDKl_hfN>u& zfm(t$BpDc{fiym50*#u<OfqC(0NrCKxPr-w^$FOFk4)CvK`K6j^xLp93Vvn+n*!=@ z34R3$a=wvdV0Z&k^9{sh-~^efIFErr@COr<G9!ZwsE_hglz~BTA(IvBSFov!%$&a^ z85ndys+hr!mbR6HhK(?&g$%vq`Tu`LbtgFn20>AfAfsZ-JW%_~7AzzI7J`cLcFtp9 zV32V(W?;w=Vqg$l#01eN4^{-x$2%FM1|qJ2E)FpOB58*#3GQx!f{+0s>3~&|HxXgB z6S4}BPF_$5K(%`yOM)E43swOpkj(JLt_-5W9~2@PNGcc<V&xbZ_Jf48nX~1fWztJ< zV9DfIGBDf%NzG?cSYiOlB7(Wh??AGkECCKvNZ2U6fyq~)%YO#>Pr=9#s=pdt9+UtW z6v_-481~CEFbMWAf0Bbb18hEnjE^$|!#+a>2Epx23b$d(`k6uJAb_(T)U`p*3=Bs> zChTBRurp#{0M&?slh935Xn{#hMK?j=v=IZtbp-|n!I{iu@~CczaAsf-F=k*8+{L62 zW(-v}hj}hc8PpAN&I}CqKql;FQn+r+z!0Fwz#upu-82O`6R6Z8bQ2WPOc)pfK_)E2 zaNY(J28Jmhsg)Q~KR{9-yVhVB=xoZsa1$i89z&|flz~B7iGe|I6Ei3kAqA$w6;lR= zIFQs93@JG?28OMI3=D!>F{HB07#OyJiluGnQcC;H7#KLsK>>)A`XDJ7oB)&r%%KW) zqbp!giZo|nSPas<7gKJvIRgWW1p|ZNK1?|&3#h(>NOBBHDHaS2TR~b5qX-|ifHb!S zk0J{z2wE~QfOaAX9%qJDN{ot-=vIibWMEKKW?&FJ$-G7pnqa_EV2?4#{GG?ZAPowt z<xC3mVQNn?-+-wFCvd1*ruhsEple74moX_kwq#&P1DSgUtGNoAR#5q~Sj|$%vtnS_ zX2rlDcpg2ofyxaAg@Z8po9Ob8%*t*J)qe|J9voK+-qs8ZGprdH1RtQwL(HEKlYfOx z9_(Q-!JzOCrt%BAN{~ySimYs))_ujMh(VzhCjSjx9+a$k!ERPMZ^OW#VavcE_!B91 zAr>gv*)lM6f#l>^z?lFNFA#lGY#A8tgX9#D<QNoQ*fKCI14WS{3u<&SC>Yp5rIc7u zQw4)Ur5yvq3y>~l3|$9cQYsj_IP4i1V)Pgo1oc_4mc5}cc{6PCU_XKh28AUsmG<Z= zk%IdJOpyaNMGOko4p8SfqRS(KTcOo~f#I?P1A|}`Rz;9>ato#?52qrq!@&fDf|euH z%zUiMk-Sh2Q(1shC4<6Yn4&_gijX|R=LEI5hy}HB;ssSgkOZcX3sY2rRS}YLXPp=r z#GDxz1bcB>%%C9S3{}*R%{T^yN|^jaZ1P}-F(}-0W?;~CVPFuPg3~5w{cY$1RXGp8 zN^n$w2?m8`n4aah^&mycC7ALR_?0s#D7Zo$vl6#Tr0~pzDPN7Q92`Ah0+Qgaz*KI> ztrE$_R&G#t?8L8}L18{j<!;<6kzCB|&cG0;%D^CaiUlMJE_5Ij2Ro<}1`>mYv7b8w z!&H#UGc2IK1CmOFBBhz`kdXwz^GIbBFQ}|wP<ZUlz@X#7z#w>o1>`e?0SpR89t;ec zDhv#Qw=krtJQx_xfOI`%3718#*%%aVc`z`Ps53AKK0$XoD2$=bR`-M|dWWtE<Or}L zFu|Zu3{&|5r%DEeeK18I(G`ITX{br;UJMMS8Vn4AU(gjHIV=>W=pVWwbcZd1sbpXU z1vMhzc;PA;6yCuUF`_F%a+rlT14FYW1A`z7x*{Zp^}`hLp(}!02leMum`VYhDj5{4 ze4us;p({diSg#KQ!)7f|Ckb5<lEWUu6v?A2LU)*jFVr|ioGKX<dSHr_(G?*%?4B<J z!xL==20=A+MMw^_^n)rgKv#tBu*oo$MmSY6D7=9wGC@~_<S=J{1_ljX1_nWMbVW!G zn+sFqh^`3TVc%dXopGvUQ1A<Y+Ubg}2+3hf0vH(Xg31XG@W>ugY6UrrLE$q@J{Dab zl(@ku3tAJn1VT-U!><ye2c(-pVLD7t2D%=Qj~Nu6z~nR0<w5!(CP7ph2SIJm!mkpn zhe4q^h=Jis5Cel?8!KAlT<KvD1A}=m1A|}(D>yX3jXDMeuV4m-=^){5bRB97gBciJ zgQRA%@<0b~Aez)Z!(`^Lf`$t~onLTq&0uF2!oV;ogn>bD3&<AeZ~@3u3~Gx*7#Mzl zr1rq#4cc$8;|yhBhzVt25IlyVDJPVH;Q&bLB)X;xp$rUiVGIm{XV5j-X@)T{RD+~0 zpi8NBg)uPP1xZ~-H}6dt1A}uo1B2joBu$_(9R{_qa0Z4oAgNodAOVnfp#iZUCUci{ zh90<Hfci;>*O-BU7u45T$)pw<!N9O40@Oc1*M9&e^B7IPnnWZ6LuMocgWxlCJ>@W& zmuPzIPDU~?2t_e42);#lfk90&ih&^mB>D^HWk_PND~W=P{Ry&wrcR-81xj{cc`(6X zcLJt}4VxkcJCSIpAsk5Zpa_RF1MT9X85q__GcX9spv!|5VIdgoc1ANWNX0NP2+9$w z2V4g+*crqyFf@TQDx+y+u$vge!0-knrG_L0E(`1!VxdynXi~hOzCD9oB~0E0UB1?g zfq}v9Q!E36PaFe-U>K4-xV2%I5C@ftLz99UeFG++iY^Z^Iv}2bVO=}}gJ32?p26;9 zJOhJ90t16!7D5yfUG|^>G8sJv2Kz=w28KBX3=H<5kvx|K1_lOmR(5^{21dbbCM9Kl z28LwNl8;Ex@F|nxX7EgdQUyN)!w!&e6tb`bxFlh)VtonHF7%vLO-z7+Aw+<IL5PzL zG|<V&$jJL;E&~HEXoQwQ#>^Np_9^s+6+Vn8^paI3z!WlmEA)v~ZMP8A1RhKicyAhl zMj-1=85sTuF)#?dXSEX*VPI$%WMB{y1bG-@8OUacjcO4hkRcc$J2sFLK<@bmn)6Vb zCc?n*NrZtx$eC@PAvk;Tf+Z9rL>U;WL>U-_R>JIOhL{S{4|V_~f)u{M6t2ao5FAqq ztHc->Kv$XyU5B}W8Egd9LJ@JO^eu!mNF!9bSe$|3y*LAd(0!OgQFMz-K&2leq!GHo zQM^isfkCF<8B*v7y=7&vVoeobU|<wtVF4$KX#&u+AO=!+$b^AG3KY0(EDYwXv%m_! zu&J*CMJg+Jv4rADaGFrqBEZ0K9VE=n-e3$4LPo`NASvD+V^B1KmOX+-x`lqS$=sL= z8M6`k&8F}YrjM6>2dcg!V13}xU{I9)Vw1T$7cwp+^oLDBTM(Ku1Q7Otox=MFl*IZ> z7#J9o5(J^?K^)1gydd|1RWT?`5`?A*Np_GnaD@kUHG|SVK?a6LAdA(|^)e{E0WH@6 z1xo~m96S(ZK<gkt^AJMc*%-`O0|Y^Ve2mEv6u>g?KyCyXeu{}fOkM~ygJ2{CQt*u# zZU8vCK(PSHSTZ1IgX7`{GlLatL=IFrXhITXroEOo0|S!sbZ=<XftBB!4OQL~$-n?s zt`>o!JUIfPoWY8<9PFA2EMP}~(u_T5%4VYw0|V4GMX;1HiG{(6m0uWSyeo@6D4P9* zp-Bj&53HO)=B_E!crTFhV6gJj%xYP}3=GqS85o3aGp{!VryAa$pd2X!G6$So&N2(W z0I7zXY{mKm#2324Z2x&K0|U1R0|PiX`9b;j3Nt7u7l9NA?_zWUl}Jy785kJscbhUW zyaTxlRPcQgW`InRfPzza7bAm=mKg&>t0)75unv<IYriN11Ea7AlO<?18pk{a24OK! zIj6Q(l!4(oNRbp%tQpv`ioBpPeFhnjJ)j8}VR0sV5E~T0V9P&%jAD@KG-F^06JuZy z)@8C{O%%gsJcC+;7~J?hP~*jkFdkH3FOgtikPuqLVe#D@JSAqa!2(RHzmaBO5V{Ut z#iUpOHp~_*bPFuR2od8I0iBKwQF|9G0ToZOWMJS0)e8&|$%n|2AWaZS1#TGzhEf>@ z2BBvh2^Qdhftt*qPz{rM&Cv#vDg`@4;h78rL!c}JgU|;KAxl(U5wcLJuN)RIDTpqm zBeIY_yU;IW$JB!+OYA{TGL?fSK1<Nq)K;tppy@B6P!8wyk_-$W1w!Q<Ov((*s?1Uh z3_`geLliB+4uXi}BSd(uEI=g}NRt#uaTtf1k`!bHQ>X~$Q>bPcyLr$uEu2Gb4op=E z%+rd#U@K&tp(EQu5gcIGf)a`gC<hCIPQeE!88Hxx!HQK4G}A3q&0zqF0ECMtgWVSn zHV)$AsR$9?H((cobbwu4!=aWa4R!HMSSTw(G|R-mTwKecwhX3fHY~su)4*29fF{5| zWAQ?D9N@A5#l?^u268bYgDdMlu#4w&Xs|w$V_*;vIV1&|Vw^jVfkEUVBO@bXhLKZ7 zo`GR4NIV8KfyoNWlc4M)a*R`1o`GQzNG29EU#hJo&%hvZ8(b`J2fGI%at|TGy9X5Y zx;FBVc`}iQ$3W^pO>eLUh%`jk6C_>WY6WBw14ItA(vndTq6H+!pxY!5nOPJ0<ZT5_ zou@%YGq8qPL1xTEPP2lPf?Dq)Cv>mKL*~vzzM`qu6;^=EO^N(Kmx)kd08dSc{6?3V zsQ{TQ6Zv-%&Gu?X$XuDoSp^YA$b6UxBO{tBg-}HXhAD~+3?eKTQgaj`Gg~6;7*h8Y zAv0Sd+>D^G0f!gF(+UbokeMwJJ`AZ;B}gSIB8VZiR0%Q(BqD-X0R=Vig%V^ENJN5h zqcw5>^Mb5qV1-roBBvB|lp*srBGOouDr71{W)4J@(c~EvK*y|rW)4I&F{IuqLx%B0 z^cg`hisV@(JrxFqVinNTB}f#OF2L?mYE)rhI0lll#+19F0x6tCoRH-}DUv}!NEI@6 zDdNYt+6KkHpt=t1X)wXS3TrrsoL2}_g$!egL@<J8l|iN|g2NB26ihHE%u$8({YBy# zK}89YB9I;ig{Lt2OmumWkHCiTLR4y~K~2iXuM(mMq?<t@7pA8ST@NU8Fet2p$=9IE zgY-j8f~fomQ`v-HC0GxGf~h)WtW=~EJwQR8fhwwmDVm6`2vq1m6>Wnlnt`qe<S?)z zFu|bk4W@DdPL&J_rW%j|RgsnGijW*u4O6rcT@jMQcES|xKv#tBuwO8h2XLxnP_WX3 z3~q{?L|265u!%557ts|VIqU{Z(N%Os=nhlTg4%f(r%DEeY%RzLsK_&PMMw@i08{i1 zT@jMQ*tDT0eL`1+?l6Ct%3nBDGAK;fhK!YpFf*ZLS|o>kgDK)hSA^s+M;)k1Lg<Rn z9o7$1DTPxdgTfsh2JnEYh%&k&B!^k*LKSJFD?)NuGfa^Yx*~LkU4W^y!l{x0+<QS8 zSYXils=&a&$jqt?8u$`Du5YRbnFkdGEimJ~Fpq(O_bR9k2R8$f^%xjLPnzWFF);Lk zm={6KX;4Rfu_FTmFNk0;nV`qOumL1_8H?m*JxCEIdL3F8^4<s8046{MD}%{hJxEO^ zdK1J4nGKR;Fk#Y%lqaIML424vc1fhJn|kX5Oocb<S+0*s8jAR1x;$SekvP<==t zFM1Co12O|dBde&^hx-08NCvI~q#f$Lh58H(NA(#PM4ugU0@o9~AR4mr^ejmHl*u)H z1_sap7NRdeAp$Z4ti*)ZfPulxfPq2u6^IWK2gx&-I2kZ7<bcHAz(Ncp4>8xc!T_?i zS@a!95VYVFlsZ6h$f`b*fx-9-1B2)pR*RVo3=tsaX$Gz1pfM6H6(a@)MlDrPr(J6S zh_qrAivV>41(8M)Ky@2te~?iI)Yk{~zJ!EX7~DWBC0SBH>m7x5^GX&cA~wl5cO)_} zfO?)n2SHo;m{dWkg!b}++IP~Rv1VQc(0W6)nTe3*pU^&DEs!uHqau>D%I-u42BAZ| zu%(tD`ylcR?xzzWOD%<t@G?QxS|Z8Xf~`9NvJP${$TbW~TuBTJCP@qoLKnf3P}39~ zlNcECLBdzT%hbVDG1wst3JpmN49h`M_rQxq!BYAlw=ytTu{b9)FmQ<5GCBJuGcas- zVPFvV1GS8qWk4J8!jc&n#NC)wL5jp3L0wTrXRt<fu!uKEgc%~l>j4T5g(T?0OmQEk zAdpH%MihAlk5!<x(30(*dovgq>OC)k7DRhK04<1S@OTfFs`F&b1WAczGB7ZBs%J7V zFnU^KGB7ZC`elN)d@-|TWHK;tNQtw679)ZdSW8JVDKnUXM5Saw(bEO87%CtK7vSv& zIgptZ)Td{Wl4dE&glzwkl4eq7U@)o6WMEj5$-p3`08$6iH3Mu6gE`CjOa=xCX;(%A zDGzYpmdSZ_76Zd$R|W>@Fh(Y21}2#)9*_Y==|Dzju|lX^IA{kBle26g14Dx^1A}w~ zXbTRL!o6b1oP~5WqwxZ8E@M)(05KS3K;tN&C5_Uaj0&P9P-St9wjfzXMkYmf5Q9O% zw}gSAt%QL=I*~CDBm$Cxn4mBLCY8b%29tv5Qa=UK0bRHbQ4JBw0;LD26L>*ZF{s}F zDa}I?XHa@x0$FM$U5G5KAX5riKPFww_}vZa8Hjx{Ydjdhi(#d`8I?jy85m}iGB8M& zBkAS^g&>2{s#3_<wsaM;TmtAs8KqC9kilu`dStm&ker=m8B`x=Svw;n2zf!;z=N6$ zcJpEKlR<is<w4_;40f#LP_rS+!NEbo3o;t2KMN*54@o~*9<1LURLD;Q4OxO>%_V_> zK_+w|WROtWpHT)R3+h-(`!dQ@EQEB>rTrLX_`M+GpVC2$4CbtVL8)8XiBVl5i-AE} zA7l}e;v#UmQ_{_XjDSlUK!le=gmbbWBjD18$im>UE=C3`)-73}a_~8;+Jh|UC?zM` z6c2FB@LmC}Q~*T_gN&><B*B74z(MW@r8>|E_$D7nqzQduRoj;XHGv1y1m4@ABZ_1m z`XENY_vb=KJRu|CV9P)@^MY+uW6Fbc)r9QWKmwo|;vOhNsyXDrN5B_A9SW9En3D$| z0SB4G$jHcy@B-KYkeE{V2UEBf=1>fU;3!i_$cGMbUx&E?I))9ga6e4?7D5`NkryH@ zR{$O2zRw1AD2nb`FzLq#X@qX@7%6B}QbsZYk^+R@vMNn_#lZ0I6$69Ne$cD|Ga^la zl8@Ib1_rPXA-)Ffn&UkW3Nky1*9;8FuNfGGz>`Q=bb$jOp+W69KO@5q0Y(O)d2G*S zffEB<6O!Rz4R1j<s4<H(GDu1=G6>b8Xt*iH$N<*)7{+)FWBd?fWWZ_`gB7b>HYicD zuz<C~^9*RjSmq;aFqaK9%<l_Uh&If>5uET9VzS}G{Gb75Q0iCQ29n|}_GVyUkO8?K zJZ}4wP38b}X{OL`HideaK3?|u-eA8oLiMc%>pKd{6`%p}Uu-g<-~|sk{b5sBoDEI> z0_<@6z)k@V;PXO;`A=j+6Fqd8AEE%H9;}K%;e9qV*&_|}gI&#_B$R_X%#YB^pk$WA zz`%zz%#S1o4@Bf)ekH$G3=CDElw<~;7XT{)B_KtFPDtWmuwv~258zK=fu~9I5%x$Q z=#V*hg#ABQxhso3D1^Z+Do}|5O3UC<he5{P7pfdQ!fulbitN+OYC*a15q3deaKQ84 z1SKv+Ou<LkVI~tX!d?$D9(9CW))zX$4$3v)5q1y*)W!piu$!}L6f!VyfX1k2`+@6k zix7V>4H;U7j#0~ls!ImcF>0_FFUWDwVQA<WHAEadMhyxIs3dfZ8X^hO#0!>G*j5A| zqh|33hXbP`SP_H52bk1r4lS6J3fLhE+Qra;=nov*U{X+BX)vj;9Cu(+5M4@(iXp>5 zurX?|4qiP_g$a&6@EA47S<o@+7;w-)$EZPW#xh3z0+h)ZAS1qzF>0^~?>#?QwgZp& zhH<F16hcRQi#VV@RRk+#kO7q{ptaIM;T&qaV5&-Bo>u$=wnFC9d`JZf8lwg|22@nw z7^D7J2ufwu90nlIppQ|rfrAj@V#pXZScG?iKgh)(9bgyNaHwe)L0vo(7RriXr3^CM z3m}!YP%VdA0Zi3wSb!^vf~}AdSO9f#9S1l!p|}`%j9P=mu!4bsL)MB#s{(QuiL4Ei zGJ}ar1p`A_1p|Yu9khR>SP3>+2c%pUx>d9pBm~|F$Dj=scLbMy5aA9`<m$FnK)NBa zPQ4(-p!O@0wDua170w7<47vv@Agc^zT|u2~unfdz24)uXN(KfEIT?d}q2PSN%)(s7 zz;H2ufkDoINtuBaR2zdzS~+bNP(v6jVF)^51Jv{d^Nc`eYJeKPzd%c1jG2@rv@L2F z7~~W{mAK+vkPCSqf!*z1197*U;v0}CsJnn9ZBkbQX$8w!e1u3tG&8V13};~24l+{J z<ULG{<u|ArhJ~Q5LnfNFkan`16)Q-9krArdBn2j6%>|W!=r992(hd}OU`H@`fdwF; z4Hn@AIRh#T2~LPG$YutJb{DvIUalYp1_%Mx#tLfqfaYc8G|d*&GBC)w!j&?ZY^a3{ z`pX5{2Z0L-sAE|{0SekoBd2Tf9Hu5H8L9^2Zq~dY$h?4@9xJSYDW_u+T?d&LkPAjN z(qsZmA_UbO{bO~IR=!*~lFR<qL5Ak#B0>HENkD8hF{y_PvCBol(k@gYrykNPkc&ps zvAmvv;YB?IgIo-n#J73|2D1hR2Dw-?3FijL0J~g#STIVkh(H_Fa_Zn^XP~yWoU%z3 zOnE{pR5`>+tdh{SxtxZ{rUuB8ez`<cBTZhwB$7}y>&rJncBROrfP4>$agaM1^dlM} z8&l*!yNsbRraz;Rf#G^11A`oBdoe_i7i1!X{-Z|7wgoxR=3*2X`6dR2s3rymxqP@4 z4EiZekev*21xSMPniv=!gH#s51;J^ILH`>}rWjQQYPnrA14C;w1A`oB(=gO>P~u|H zp9zxzb)}GGctPz~2K|39Y0ws7WNGl?BmLwSNas$j2VpJ5+!Zhx&?aDHjSzFWTcH|3 zdw!9nA?D__Lh3R(PzMew4JsrUOqRDo))2}~M@@L%&s!mVI=R_M1r10KxE;;l?bimC zUxY3Xb`iMM1S-PqL8U*aPsgCanqJAkz$ho;-CPOjkI9LH_R}hE0F^Zi-iIq8-7z@{ zBvEj?2-LshsbXLdKyG=6hJ#8}4wRP1Nw7(%Ef265mX-%Z9Nh8%IT5wx0g(h%oV;L3 z1@3ChmIqi7gMu4O3aRCB4(t$xrfPW0qb?kr=NJ{Cy7s}OzH%&qNkMce{jP?@7Odp~ z*1>xNRLCP*9w28yTON*8phg+A<pC1M((>2^b`Yc<hqOGvBD@jdpn4pn30#kdaj4Z* zLF@4%4yc<I!Ag<p@o)~cBQRAZFy|}o2U`KI?ZFNI2o7-EgAxI}<$<WjK}$Ri)qoaJ z<gmcifro9tt<4<J3KRJ{P|HLRsj~x$5zKZoqYS7!0@4Q>i8N>3+6K~x*7s2c)lUox zpW5JkAJA$UaBbZVlH$#e00o7{LTGpXC!0(Fv|t4FeRj=&>f>df4H_T?Wl)H|<zRgi z7ef1@zu08lpd}<|iPP5^@V*b+KCn~3y&7oWM}H=2-v^=qq#mq_K_Pc0X5R;FJA=~F znW%jqgkA=v2QyLoK1g!*ur)*|eV;xNMuy8Gj0{51z7I$dxbK6|$qVuw1A{q>PCIBU z?<%9k0as8?WKa)oXJC*9ooB?zsHh7HQU+VF5a<{pP;i08c#Rf<f*I6u1dWtP-(!R* zVgwC<!Zh-}j|3?Kje~(IdFe-t5W`u)iXeuA)$rPYO#^jOK-HG?U8q7ftO_A^t4D#{ zsfwfm>U3QsA&4&_w(6maL(EY~YKJtqqz#xrDFvLAAbtb~ky3v<WR^fW8QB1k*LcrI zf&BN<9n$2Le#oeBpdGU5L^_A*R3x;hhzAFv!uNJadqz5+NiZ5J1-6Gl=0y@@d$9B~ zMg{W@sImek3z#y92{P}JAdMR7=Zp%=yC6*&=|XhV6fVJ}iqK6^_}2wl${=0JG!<qz z)D2vzpgDF12I&`!3NhVKWfe?&V9KCw5J-hAd60g|sBo|wvgSd$8r?L7w=k(XbQ2V$ zdLT<Mq?<6D=h*{UgCX6DAyo#F0xgN?z%X!G4`dOAbT@|7l^#e-O}d{66k*`Fg?L1P zu@}-Llb(bjWz-94#z{|Qf>x)Dicnn%y^tI%Jsn+_(!^d!n@D;FdOBfHIsnpU!N4Fr z6G@Ii;ae|c-G%gQCe2vnBmvG93^I(M5n}-c2I&Wk3i5qWwR4z2$qwNah*|~DKFGoh z>A6_VQYePW&%>^NULT}gDZKzqKZC+)nAB1<tqcl3`yfq6=~WoIRQsV)>oIf%^+T3> zNN;1R1!WF+vBIEG2b0>#)C7})guT-0eg=jo{R|A!`;Y<=QgkSN?uWD^rH>=afdYy_ zNo@k8(I|ZlNsd7wYyxCQr1TB69K;LCcaXfTFc+ri0aitzL<Lp(bOL0vqx4^FDj5{i zCqm`_VUq{j$)J=o5z^g|W`ykUh2%}8nG+!!%cVJygdy>+bQ~tfg)Rqin9`4lkambP z53&MKQOBU5J_*uplomm342OiaUF;;tGInY3X%UdZn!#?tB*-#$X+@A>5K-Q1pc|xQ zK$91sPO$V7M!Tnz7#JicgYq7dGEiVK*r`rtV2B1uDI=s9)G{YCFn~5ZNUJb|lz|ci z*c}j0+Rd8`Y2r((A~ZpzZo;J0(WD^Ww-cYjz~DXwG?{=V&tMk-lQKY)f@oE1p2EPe z1Ekf68Cqf^dsyuVOxlDQlwuHWeg;~)FT?8rX-Y^xWwiS}g@GY*Dg%SGDUwZ~W;lad z$yBJ688avxL8gFXofjkx30k`=QyCZprZF%`n<HrlsRqk~2?jgaX$%Y{AVn5Pia^l} zY3kcG!Q`#b<-tvTyPMM>oeybSBzce}40a;Z85lCAGcZWUf~6oa170_cN-)@UOlM#? z08*KVq!JXP40h+IGca(?U|^6=M@TW)$;@D2hy;n|B1EAvn>&MnVFgI41YHWzEdez^ zK;056)<-WH7#O9ynN>jy>0YoF*}V)5jNmo^)X3j285o>jF)&E?A><ht?4}AbGTahm zWRM1*JYs)pK4dL3G`2xw;0$Vs5{wLwBp4Z_^_XEZ2B2nafCM80R2_&5?x8>|W6)CR zU|?W0XHD$@o#U#>%30UJz`&l&z#wnT%B0L70~%*<>R@1y*I`wk0HRGnTYwl9Q$Xb& zgTkB+28O*L;W$>uWN77(36_$1ngSV$lQ(2lc-6tcz}?BfAfLvXfu`(Z3ZxM%Z@{V` z*2%zN22z&CS`0D-l+K_QIl`pMSwSrfaLodif*cp8kl4w<&<N66g`u?vCe@5x>zYmm zhO;28tq6IrA9%S^KuxE=DGUtPLGt>n3eP(sCpO5pqgew{tH9pHz@X8^z#u;Xt62(0 zT?`CCAo)qy^~ZKWDp2_;XyFMpzpjgcVG&6GTvkvdfrA0;Rt8mY>?{Mt4kU7TK?)e` zK@s=_boYoA>v2$2%l~48i-BiOKm)w;{~5tC4JsPt|1rvdPB#O4`41z5mQFWl-9|Tv zG-r{V1!{?-&#GIdB4*WRq(dSUHmeSnLz-2W%0|qp+bo9+6iP=keuYFhlj1KBgFyzg z-2mKb_heM)f+>q*{11`^O`UTt0*w|b+*}SBEtF1V6b6Zaq#!0JXs&=tr7%jsq#(K= zQ|QoHb%<(+5Oh`@EW``43UyW;EY6@*wE|iJLTA+>!V1S$KpShtjJ|2$yuhRgu}@}0 zI%I+tG^;MQ5?X{oXVt;Fc|oDXpj5OHIy(-XRfotaEduRLxwsNC3Idx|hsdde<m~iU zLG^)#f*2t|$P3a2EmqgS<UxZnDDseERdY4eY{;xS!f2@er7(HOtU8iBSU<djXAg=s zP*EonvIyGW@Mn|(_3Xf1CSOLG?nRJN0W_;F3|h+}$iN^S1eyb11e)Rm?E?EV3)+q4 zWCNuo(46x$P>&ZBhzv5aS&-xfnga*f21+BKIdGpWNDzbOz)#G9n!tl;0`L8FP^PZV zLd=0boCoa^L*~H2mVs>M1>2}*Js;AX7P4al34q+Q0Mr#!>zfas17DI3j&NSEgu?&% z@HudhIgFq=aImQ${a^<`!d0Pc0aW2ym_wO)(G-FMSmEsg_#8OM46uoy@iwT1i3_39 zw_r|W29E+lrLQi8&w)c73Y`OoI5%w(RQfR+TpDC8L^n82LGy+(mer8P0%#6=DmNno zKMx~=&{@bFI4F)m!!KZuLHqz3-e9ov;bCN022yARQV35eNJ^9hL>U>TiZa6I(_v<T z6@!KZ&<q7vmJD`mVvGz~VvMl)bWB~~kOa8`s=-!<kztJtBZE*k*eM_x&;Sp@DZC&d z-u0l!Ww2uP2XBF5VF5b><Tr3gfakvzV7rspKx0Q4b3kK26Ij6VppZhJnGKDEPPKw( zX5~P;+=N_N>_N7H901n`9)V<#xtRr34xX9a23CHWSq-$&3A*<QG=T$3hqFOWl>wOp zD!GN=GqWHOkjX^M%({VACZf*FZqI_w%z}axJTnVofX2KaGqc|pfd&B=aafq<fJb92 z-a%-T@zIB%f*NgR7Ayu1WatnmbY>PJ4jvx`Wof7+bY>PJ3GxvySW;o(Quz4jJkTUJ zsFeU##GvpACiR-*2u$i3*dYoo%i!aq0ielfBwf>BQeQdBU{VlWN-vi|`X#XOQLsI{ zA3(tljy~|rEXY~V@zJ)$prC<{kAmEcWqfoM*g?qSqhJx<iX2eE1kwZ>AHBU8K0XTd zsUlb@gA6E*f+}v%%&h(rsHzf}rxo{st&rIQ8yt+_0J|2Hh~eX-3@E#YT9$y)a5aYk z$TR3OvnRmDL0k-(nFWjRYUP4l4AKF1aSeys8<<;WazH~_5v-I!<}7T0vz9~6Z7I~n zvta?QcpYqo%q5tM>o~x<0>#CM5nV<Ga~8!lpq9v0Mhmf2a4Lihph3q3bwCw9+L$0% zjMorUVIo===wpHqMa+31kAZ4&Y-555HN4hf(?Hn+T*0A@38E>4*o`tK2v&hQCI}Yd zbp;s=@e*`Q5FrjRM`7_A_?VzS$h)8vjZnm(^l%O8m>@(B<Tc*MVE@^tL+j{=j0&o2 z;bVgLV0j=8WGaI~?po+zUp|v+KDe4=R0NyFAakk=F(xRo5vr_!$p@wkVuH-G3dES; zl`Rb5BLk%i(M?kj*b0>@LN`IdcPn(Tuas#e%y6h1n5q$Df-hmpDwr<7ltJCVQH>ZA z?AZn%6GSsj;Ur9|4&4L=_U-U7K{O94xNnD#38G82f}|7~7^FKe3_P|SJ|>9fS_Re} zpm7NX2I+n#P=tZo`4EpNIPZWqGbdq4weG+i6NKtIvIEkHk)DpOONnhK>X;xnTzNs( zGAOz2gv^w}#stA~3<|wFA>9<|*-W;eB^`*Q2i7JN4r=d0#{`eV)Xrf7B|C&yAXX?a z?ShX9Vlzv@7A8LryZ*{u@G(JD{R|4*VNy%cv@$4s+XWr?TZQHW1_k5YP^tA8x(av0 z#{?&UG6&q>3<~RDQahQZ!lWQ!uk>a&>X;xn5Ftf}lEog>F+qqND4-aW>h_?H34-Mq z6!!0dj|rmYM_y3cgXC=m$-PiT574q1L=h;OpejrDLdX36VpGYWa1ti}51TyLI0hxf zeb6oubW9N9RHgWRsAGa)VMx3y&4bB7#{>~_5Qix}+6Sq7VPk?21)!piK|yIh=9nNP zwCytYql^iHburlO-H$RR2o~jiRSYWTL0vCU^9eL2D0%>8Oc0_B6j%&)Q3p`Q1i?}a zY6}m*#{@yjKnViu4u~i1o*zIN69j95N*N!7N<qd15mFHE+qE1-852avGuR!4NkPU0 z5mFGXYTSq5V}j5W0x7T|9##v6Nt-Z(QVhb)ze+&ik(>@`=7Yur6AwcN{vcz55SwO! z>LxX&t57L3W>7eSOhHIPY_coAiZUh$kq4;;%Yz99yJJ^T#sndXK+z0t_A}V&U4zO) z#srb%L7fx^yJ^>;9csv!AVeNy34`5}YbaxakeERo4&()K8SFf-ql^hcRDxoZ!EVxZ zlrcfD6ocKp>nLM_U{Pqy>fAsX6GW0i?Mi?;%Gk#QvxOKL7{P4-sFBNr8Ii{X!SW0Y zcGIL88Qw|5#{|6>LdOIlVE~>QWH4u4y%uR~?{OJ?Y!B4b#5T5<3@X1E6ke}|kL}5p zL+kwvu$0Wf3P>*=G`5$!4nDT$f~M?j1*ESI8rxgF4nDS51TqAaUZ57efJv3Jf*KUy z8Uic@9oth~4<Fk@*O~;AYR0a0{(AV>9^7cKA9$aYgVOrV3dGpn-SzOXJydHTY89k5 zz{mEmnWYf10Y0{eRsYltkV;d23M*=OLe0Ot0Y0_|iX?C_fZd8Rwg(9qkOBs9n;ts0 zr@4-Sfe|#e2Z~gX7<@$mXlxH82rA;x$M(!wgEu0jjsF$!v@vlZ0|U0SQ4Web28Ed$ z;c3GXw9*C?n>Ao5nY&epw4t;Ko;DKDl)bD%q>aQ)@U+neG6ZBA)S~$?sd83OD-s+i zU@2(YxVs6SHqf<7Z-z=WW7itF8J;%aMuYvp%TxtQ8(*ssX=BD_c-la<2BKEs+Gcp# zz-E?$=oWa|z^XrZ3p{P0h9}hgNn7A)0~AT%U;w)nC2c?g2Bd(&9u$F~biiQ6dSfFr zZNS99t42WGM^M@T31UkdT0L7q<Gz~P7#J9>Smz!B^$!J+217t;3N*$5?x%r9J;0+E zj544lE1<Cg(E1o=mP?1REJ{tQhAm134Ud5=hb~G5OBliyrGk0zMXAA{g@)*hQV)TW z3-57Ig`~UwIHW%$rwFQ`Ktp7TNYW;Mk3+_q<t#3OG%+$lWEohkn&694SDb*VvAhOV z^8iFMnEX5e8B3P4dI}PNYc}yd36-#Z1(ks4fUGJ7FG>YF0=oJXvM3cS!V7W+R2Z@- z6(S6>8F^7EM09=)0|PIZ0Bd6fjRJ!DrYMV2!AcoS=ADG}#N-06fL1-h9m@&|Q0Su6 zH!w9pKcH$L?q+4Kh4j_r^jKlzvvN8n)~6s{Gr3??BTd?25+SJO=wCSnX%Rver9xe% zbQ;pFk&6U*1(eMpwwe^2hV)zzi&CKy`%go9J95!zIt0(a7Nw#|WS)U7N=1`6a0b#* zkc)p^3$D&!3E&HKOj=Hz71ooNQ#Ro{3ss&V1zH=%$fyW$66;Us(6*e0N$gojS3xcj z)ku?7Fo`5o&H6viLONTJMXBIm0Y@u?zQ;L8R|~Qz6)eM`KmQ!^qExUTFUUj&{qN@> z9S6vwRAd?7^T>-*!7>c`^Up*25|BlyP{9x9Ax%&@@S;?(Ak;BF7oalWMX3lGsO4)f zATLUVNP`j=gFf#?s0?T(0usQyAQ|v*G=qLOOd7l>6`>K*)YIp@1Zm1a7NsJj8T8X( zGT=q22pOokk73f_MX5;Aph0p5{rJm}t^{OJDnuGoNHCbJzYOU}AQq)UV%eMR3S>$I zx+oQ)2jW!k7MMI_Q7V!=xK)a1>465mKrKB6bJo}+(1oS2fz!N3(9jj?!qRo1as+MQ z6fA~i;1nVb9ykSAgF0{ukpvafykJQM{$rQ}r(i`43W+c&q=D1TV23DdIR+m%1uc&T zS3OW&?8l)}Upf9Zg0mE(B1D%`^l?at!v;>lI(YYj3Tkk(1w3#Hau#&p^z9L(fm4t; zmVwjxU<W~lAt4J(!6LjH8$s1INE3J%GK@nl;wW^0v4{ieW<{`4q+!T#4z<lNRV6Uz zD=q<B0UoS`Ei46@i(?oPw6N6o1ax63OdWV^5mW&R=ddtnuvXk)U|^IyAvNa)0|V%6 zFv+uwj7*GDt6|*pAg<=t8w?Df8GXqMjEqe7ntNc}i;Rp+LYhZm+)Ip%ObnWrZZI$~ zFJ@qnyv)eR)BpqZte~CdAd4kWYu<n<xx&cE1V2cLLFyjN+M6J2rC!3gw?JIYPcVCK zGcqzUY5st5?}M#ny$N;W129(v#(fCpD#EyrKwK$<n^5mQ0ds9(+^1l!H;nrX#MO)i zaX}t>4&q8>fVlG*7$jeSxfL+(J21Bi#(fWRvs5pP`vELF9mf3vmYoaZ{s75puDuC5 z6oP?4@+XL^xAP_g!^@it43bwjH-VEcliu5#3=Fcj7#Jk4!G#oWF))OHgs#JdqHi%U z^n--%z=fvYVqmxc61oc)x^s(xLGU&MgXBxNkkoAkh5(SzE4Wb9Z3c#^AfeZAp~bfu z7;b}v-oS*wGfJRT2x(+7_$U~H=IDJCj6erL_$azSC|9Ay3=BSsZU$h=-49H8q=PBX zRxsr?4@`OQ0aHG=z?AQ2Fy$w>1f<<x3rq!gfT_StFcs7arh?~zsgPY@D)btd3VRQx zBDj}=v`49csc0uK6%z%bRA=OYshJI6Y8L1oDIe9@-C*9_X<%v|Xky1lb^c~BZ^1q= zwdewvT6`N!EqMl}mVN|N%m09>73|9x7<^P$3W2FrvS4bB2AEoF45rrEfvNSLU}|Fs znA#K%rZ#7RsV${oYFh)C+76l%@=@Kn5X{@P21FSqg9F(xWjmOc`UFg+3od71@G;D^ z15;U%U@AKoOyxF$sr;#6s$e^qD!dJ*ihhHs63G=H?Pca*sv;Cj)fR)Px<)WnKM_nd ztO8SwyTDY_IWX1s987h60#n^QD?x_!$bzXpeK6JU45p?;gQ=-Az|^$uU~2k#Fg5cr zn40|^OwAEq1u|ux4wzct3Z@pufvH6uU~2I~Ftubqh%(OwUF_^*o(H-)*vC8{97^Ve z&%ts<zrj>7KWGJkd5H>`Ds=}_Wr<*_yc$eZ%m!1HTftP-c`#M2wT6Mg$GpZ9Ox0$9 zsk$C8Rlf>MHS7aZjd#FQ(^oLnEVLG+uSE?^wc3NJwg@oQUJa%?7J;eG17ND_9+>K8 zTnEzEBMPQ^Rl!uBDVXZ_1XB}Y!PI2XxQCDVlrAuD>KZUL?EsjXeiKa1cn+rK{039= zIM;)WULXsm78-%6r9NP4St6KPUJ9mGbb=_W^hIDQV;7jpyacAQUV*7>rVR`XK2|xP zF$o{5Tq7_q&kIcDCxNMgYA{te1xyvK1yjYxz*Nb75M^Wc15DZTZDe5Zv2joVQ;x1+ z$|)91IhTSdmtHXCx)e;g?FCcrSHYCWTQKFxx(Q^8mn@j_HU(2YzF^8X6-@axfhqrK zU@Bl8m<l`wrh@K+DCg48V5$t9h@8uvHZw5zI9Gt(>0Aj;XU<j6z=G8bTR?I(Qedjq z5=_;FgQ@x|Fx4;xOf_x-Q%x7ZRPz%s)xxwDq`g%dOtqPSsdmsjlaF&pBAC}%1*W<t zgQ@O~V5;X7nCg8DrurGTflQew52hyDf~l#|U}{<kn3_HbOwCvgre=aBn0%aPJp%J) z{{~ZYB)5Z1nQIQF<^_YP`T1aKK{uFMxExF^Isv8@KLk@tzJjTxd^<qem+641<z8TF zMFyB!*#@RoEdf)juY##HFTvE>zhG*e^iGiW^>$!tLn4^kSP!N)EeBIu&x5ILcfr*5 zZ(wRS_b!mWJ@Q~`uLX$mu=E8}R^a&auucZ^Y{1dz;Q*Sd@$qo%1`9eZ0aMNg!IbMQ zFy;0ROu6&yW?=B~@K69#UM9O47+B|YGcbt1XJ8Op;09u{$iHV`Sm5iy;v3P=z`!oV zCLkfhro_l7*~`cXzcX8BAtNJ$?-Ed(l~Hm30nkFrjspw~42J7L;>)1t`!IscgGe)Y z?_*>H-xlh-5xg}FqUi`olQ!6}9Z13_LBhH}7#YD=()#WMDZ`L9U}9v*WnyITJp`48 zx#TifcLhxP7@G8Bu=FvQ^l3Ed&tPd@W~kxk(4;|o0vL21VbbT(q$l$+Ffizr!lW;t zNv~N7l3oduzKA9b+5^L&dlx2s2~GM14@kEl3)E?s(WF7mR0dsFnDiAi>9<@U-IXxu zt7y`o+vgc{*TST)p-G<vyZj+c`Z}8QmE|DAMOmRvyMZPh1eW%MN#8`1{sNY+g-PE+ zlLpTu=x&Bd-$s)Lr#xLIHbw>uHbw^DduY<-eGCi?te~T`Kxdly&e64DV`L}?sl1P- zlKCJ5126clXx&;iMux2*H4jkLFzD`PV`TUYl6i8g58SqeCOZaJQ)kE_UB2^mf3h($ zc(5}v_&!6`&I{7RpzFsDm41OHt<lfGz{>=>-IdkB8FJ2-?*d5v09{Vc1kFrX4tH|{ zT>{M#_@04bhR+*D0}u~%=P76Xdj^KM0}Kp&o0yoDI~Y0J-ZL=t_cJi?ZDwLtp1>#r zI%*7bm>FLplS1En28OHe85sC-nLbZ~`mGX_xfvAvKQJ)Ve*oQ$j@T6gmFoNey#Tt5 z33Q_|s7z3VNGa|A02!;|D~D{pXa*U^3sS|P^yvfi0_X}1IR%Z6&<mg|F>H(e2stE; zuL?t|_apQI=xPk910SImK-XYMefkK!0J;vt`8uDVQuP>4v`ziQz`)lG7H3q1_zRp4 zRpkCLFz~f7!HPgoAqtUaP|*Cxzz_|R?qC8%2~tQY#KWYz5K<6RK`I#(R{n!t``pU} zvIbe}U6@oqLJFc4q>@2F`#<!0=ZQ>PLE#S?9fZj50u^-%DgPN5rvGPP;G4p<W+F<g zgYPc|Wg5OXCWSdLWz!JKAjW`nF({n-54|FNCKK!qUx>dUH~A{?GB7eYGcYpn&0zxN zMT8G{LHZ#Vg(`S4Ff!DE6wO0e0!~X1d3A88F9L-+6U1-^r4|N8$Yt3}k%W1{URS!v zzzDg$dIho^C=?i!*cc)85#KsYIcr8n$nDh|kmbN;V##_|tc)KR7#R72nC$pIFff>b zvPlR?qhc~BycuLN4lpn{gG7Uw7~B{pGcd5^e_~*8@OjB7x%d;}j6F_A9tH+b*!ie~ z&PwCl`H6v{_W%Qfj|S+dG<XT-)4+KUCZoy7q%6UC62{eHWKve(ya?lJGcqY_aNdM* zbr_kH4LBddxVnr?$`*z%KQS=)biz_A$Z?93z^>N)^@)MO`7;B9PcO(#;P?W|K;l!^ z=QHHWd!MOr>FE%S9iJH(PJlGd1cexqMv!Nq<?E%-3=A4y7#Mu!>Q8~DIf&s_Q=lav zub>d9+=dmZKF#nF(WgZ>`wIiZVUYGkXxc$sh)&&eUl<s;zA`ZQEC*Gq2xl<p3Vmf@ z@CV7P0TuShG7(=H7$$>cHg89976U7+ob+kZo%NN0;VMYcE;L2DcfK+(h<#&V@HvPs zBlC@cAp#_G0@X@hq%ev5#=tNKq~<KDZeGjDpvraGHwK1BAn7Zp(hRz<zA-SUd}m<r zxq~VL)u{EIfgv3v{RGW!&>9O!d}!x_<X?c>Sm1bIfQY<Ai14lkl@_|S-yxGhKCd=_ zVjHwA0IUHb?Y;dwWO&l&HIhz{N(SA}-x(P6elRfjyaV|eEDcRCCO;S$@<1~0(PfH% zFfgnG$$UVQ@!s--f#DrU<}=tNh#No=&EWmz2Lpr2PX-2`Z%9%g{gA*0u^4nMe=;zX zfE4`&@xcnAuBrOTz_0}*^ABBS=T8QPFCdx!XfjH_eljqa{9<760cCqeCP)^7%%mz= z{bFD!1IdB5kig|YQNf^8_ltpHH%Jb2bUa)RWIEWb41NcGK}uC0en#jG<V=V>3dxE7 zY`+;8)E_V~_y{qAGaQouXnzy3I<SFY8~vSsGcZj3&A{Lz%m~UWj7$QcEBBBUqvb&V zxxX10K7w?J!gPQ<f~*5%5G2$2|NPCsVDyK9!ABf&bTpFyXh}GdVg`TnKMV||ASF_a zASW?034qS%LQzuxhk;=aNQpE|2`GG!lz>AAl63tK|6yQY{L8@LBf|(z{!9X#py)&d z6N5kZUj_zOkP=y#5-xNl-hUYwIzdVlU`n`AmGFWLXYil=mx19TNS!jwX*_7^5V^|# z#$N^o(SHmKJ}NLnL5Gwg`vYt!mO6#iXeI-L%@+m+vAtSuUl<q|SwZddM3BH~D^><h zMg~T2Mn*d!PDX}sPDTds)-^_6(D9$VpdKQaV6dy?WMtR@k`@9LatLV#rK_Bb48mND z4Bm<$8D?ZDeJ)0ZNRX5lLW+SQppc7^VH!v{n30h&Fd4!ESr`bqD!@CK5oB**CPW;> zX0T!v;bUZA^gqF*X359M5W&aD;C~v{{!(1{7SwB8{g#1&7ep}FgZd}n*$WT@JbMvT zz{kiiAEZr%3#5jT5v&L_Tx<V&CIdq{A0tDc$ZG}$e~5hGV}#nk=MXkX9YfGNK1K#^ zentj=U37yW`XRy){SY=o@DzSVhOPXJ4Bl@+zGP$!0sHeU$ZH{BZ-SW&R;-r<7#SFa zk1#@pkiqxLgo36EgpV*X1TYISGRO-uG6=sDWMl*%{Q+`*;H8%gAR*8}V1dbeU}+FL zOdF*1qabKEAwxI=s58mHz~Bz08N+@HGJ@}clKsKR7{VaO$RPUzbY2xhz*iYY27Otu zIgE_pi6CTaK&#qe)_~YBYd~{Y3=9&x=P)p^oG)i!5Rjc>@MSh=>WqO=2P7an1C$0B z6<34K1>s!@x)BB<J`-6S>;yy2N(Khm*|3(x<k<`i5N$9E?tm@uGXU8J>Y9L${$dMY zV2}-FQs&SBNy~;pjGcsJ9auaJSsZMgHds6YB(4ZiJ{@$pitcmR$zPERL56@DyGYW8 zj37rw!yF0nD?~R#1YacsgDU7;uvn1!(887xtYR6+B$zi|lru1J$RtXBDo3>3v_XP0 zpyQAj6|=yK4Vfw!7-Ujm7J>W>m5Jc3fLJ7xhHMd7MLt+B0|UF(Tn2_n<GBnBf4LYK zL_yUW_d)>%25wN-i5t`~0?$eD@Gvm&E3-cpVqjp8najYy!~0Q)fq^%7E&~Ik?ui0* z1KB~^*+GK??4X3q-Uhm?2P^?1xIH8o7}!sN2v9pNY6(ad%vuLx?UQC;VBY~^X&W*y zu$|>+U|?e823-Qj4!Ycg{W3@j#EJqn>Z4|}Ffbq=M#2ud87MjmbeC6@pcw;06!Sa= z25u0S8#Iu@E(GF&?)+hw0kJ^W^9X@1g%pnEXJ8O#5CT~QW-~LegRazx0^I=<<pEL) zVzCE-SRe^@&_z2@V26O5#GVb30Ew~RF=Jq0uL5yFtSAt{4!Vgpst+Uvx*RrY28aa` z;|AS?fOPEx`zDag97_fUcF<|=Q3pX>FbhPmgSb(kgT13}fh0gIb`Xml%mSGj1u~WW z2S^s=ttb#H3dCXu5m6x9*_X^^U|>&`Vqjng9e5q33fg}RW`PKH5Em>P1&);8Aa!$H z7#N~_LF&LP5CJ~*t0kF%K|+olq$Vl{Bn@J*mw{Ly^P@m%APSTQqCjbYJ;0TLAqJE< z`dk?p*yn<jfrQvW=Q^{m0dc`B&@OBC-5@TA6$R434w_Qs2C<?*tSHa{uu;Xn3=C0^ zLFzzUcF^gPQJ``x>N`jb#A0V$z`(!_l3)j&IT-~u4`edC6i5Oj#tu3gnq3pb1+k*Q zgq9lv13T!1nkXlb1eogsVu8g#M-N0rgScQ8NFoX(!4Aq&>?I%xFsly40+l!HAR-FH zjRLXQL3uoC4oDWv0uk&WE<30UW8Vsr03H3u4mz!h{RoH)W`Pd#W4{dIf>==?f_-BE z14GnvkQkT+CPD)l7@~fI#6T=|kZcs_K(Hu&(5g}}D>0aXAxaL!1+myc8-LhAD`vn% zlsQNObf8R>BZwst#lR2+UXcn?5(OrrKoVcw85r0>66~Oz-0XQEF%T;XOn_xUdf7py zu=jvu!4`pZM1l4vM)77dFhnf{Nr1TQpv4qXpeiD2CrAv$Vm}OGfh5>Ld()yo21J33 zV!s2D0Ew}K_93&s25~{GC@|5G%D})5+D{b4vWS6!8_eYcvA|-Wh2l}NATF2%l86FH zurJ7EV2CmUNr3jwL^*(1I(ZBXQC=VxSQbn~g1Fx43=Hfb33kvbQubVs7>E@GBG^Hz z2iY4zVjxx&m;mblna2(?ISO<L7&~a?2>VKqIxq{gIF5Y>hznvxfe3bxx~MZCF)-^@ zH3LJ`Z4ej4Vh2e?fmY^3y$6YbS>I|I7^41xxF8lcX!4nx&y|6JTho<+A@<pA1_mV$ zP`(6hJp|F<wbPI`T<lwrtS3kmo9tJRtUu^*e~>JQh8&C;`v)Wu3KBq(fEvnjhk-%K z8$*^MmK!7yj3EKlCJd5w2jzQ^p`c+|WS2^TWPM?>pvn#E7DbRm2!;gIP)(4mABHSL ztRYAu8r0qb*#>eG*gS}~ILkW>3^8{Y7?hJBVFPKxf{cMGNWR0s&<axE3)0HS$P1z% z^<r!f$mjr=(Fmu;O}WFsuoI*y1f&|K38a7_?%*8;h9@AoXk<B%jSR7GKn6x&G4S&p z1_trF3=GPd$eO?g#>(AgU{H#Jh(nzRkx&ImctQLHZPkOUfq2YB=Pm<-8AwGSOe;u| zA=Vxw7KH2u2G+`@3=D2}85mUL*nICYFt9PQf@UZp?=mo`$w9glcNrMe<yd?87#K3| zGB9Y!vx4R*3hy#7Xv(uy-DO~4XJQ4-J9OS<V9=6h1x*7?y34?zEzdR^B+0=FT7R(V zE(3#(EGuXY!hR4_juo^H;Vg(L&k9<La2v!_U<Iv5cnM-EvVztmd<QX=SV8L&*zPef z=qR&-)+UI8m?~g%RX|J)u(<{xrY6{2TM$zVY_1oGsSP$a9K_TCo0|e+>VnNJ0x|W# z<~D$s`mEi{7#RBQF)-*VfZI^h?=dhi8nS}=94qfJFzCsFMK|ALV9-|pi|)C{z+j-j zdT1E~!?Ak|3`SvGtQ<zcENAXP?n^KVVNzybxd`KhGAXk#u)bf$z;G3$IGT%9z$gN& z7*zQhMZy$=c~MNt91N^7%NZE%fD|W!6vu%TgF1Ug@i4_;UIIvQ>=Tf}HqdkmC{KV> z3){<k3=AwBu^&KE?VzLpmx}!g66*k2h7kJ&66*$;2^TYAxX-}Aai4*~XeqMMyqiGt zGVGvKX2O4;fk7OkVi{<v2c{FEf=%u|0|N_7tO`heC1^4SO<o5iFA!@1l3$MO8nAw7 zp0o$au0eJevaCBuc0DMXP|Swv^#{pr0wqo?vhfih*+tNhF^dK9KvS2zpmfa;n|z;v z!B`WP*+AI`lF!VtKoVLY13{7uvH2jr28az311V&PEdz;Z!^A)|L~}wN$d+bM_awFj z#B7CH&&#%wfq{XYdnE%yVp2Cq2DGx05#o>J3HKQoOq#%hNDz_OX&@z&K~Vs*6dd6u zbMG@SECq@0gBc1Ik6i;2>jgOiq!zV!20M$l8EkpSN(Kf#kXA_P4N}Npwgsel0Z1dr z0ElvsA0c{DcHL)SIDDUh!IXg+62ZJ6iXrwmNZS-xoPubE*fSup8L*fH(F}2y?lUml zxzE60Rtj3z!^p@B5(X0tu@6A%r-GLKfUF0Z0lt}qA@(UqVkSfbijLPHi8&xIfOLR- z4|Xs^>_?EqJeWkyDh39mI)lA&6$1m?kNXS^tSqq%4;UDX4#QM}0+<&h%@E5Dl9&tf zI>>A^BVq+WvWH-@U~P9nwtz$!*dMK8VBiKB6D#?Efx)65W_&O&0|P^>0!VBUikKN_ z;Lc(b$R>~)a2>@Es|QlJ8CfA%0-PkE9yJ3gnT?_Z6bz{hv34Mtg;-?LTtPB^kbyZ^ z)dq4mIEYdiV*Nn!TVOiDeuJ7B29ntdlK~0B^u&T>;OP+T2e9<p)u3elX*B~wI&0bk z1_p_Yk_QY7pd81f%#cwBXR~B<JYZk|B{?Q#j*MAwwg5xg3XswMaOa|#owfla9R!yK z+X^PYR;TR%Ne9BE!M=femKUrh_7F(T0hqVIN)RT*o(9QIhRK4gXNbKB5}OKA35qfh z4T%(p>~)YVJXwNt@`5Ey?ml2(cmk4~3laor1=|CbjC}=?SO$}Th`k4it%iw#XoyL% zUqBLjK>{FCKr~e1H%MY0$cG>aP=JC{3WNX~YQp%Cfr0ZO1B1m<m@-h-ho}IFKur<= zDVYK?8e|ekEAQ^Lpx6YhLyMIF$-)X#unur$1qTB|tQ<&oF^b;rV7-6VGB9w14NwCq zSpv%CFyk4_bU<Po5PV}0zYorjwE^)bAREgN>j)B?h$3d@0TNpY(gzA(1{42>3=Cl) zv6&!mz{J66m%$|FAp=7yNOC@gB-mdJvAH1GbucTyM#h$a#MUE=L5z#921#s#8Wr0N z;_U$?5Rk1PnjyXmBnF#}ik$@FtpLfuRm4sQiETtSJe47BE=Vu{o{~Y%fTrIiAemLD z%41i91lPa>K{P|`W{}ug5F2C{$OMMi9U!s&$YKyvO%6O{U^w%Tfx+?$OcF#hm|S_t z!0-Shehb7083dvkOkO->VE6(Oe*oem#Q!{GVBmPfz+m|dRb1c^1A`1m{4J`u$|D8_ z1CaP<RB?+(3=A$H@t>&TK93j}B0%E*QN+~}9x*WFfW%qhVFpsbpjPsTfuR8;!Hp)- z@rZ$83P?f_O=8X?28NX&2?;cbO^+BD_JJf+&?JsMVqmxglF&kxU}fIOz;Npk1B0~! zc&z5(BL)V>0#?b53=AJ1F)-LcM1MbGV6fF>)!)d#!1tJe!CryYY9j-K_+thJTWxSN zT=Ovl1Ea2q$zuiv$Hxo|4#ps#fr1>gl8?c}>oEgEI7r+QRXpJ_14AxIj}fYP*<%KV zW{`UDp?U~&dLA<{%mj&hqpDx@n1NwENIVc#e8*!3hNB?ya8&Vgj~N(lgT!M|#h*N8 zVE70UPev90^_YQy{RsnuLnf-Yz!L@rS&(=>s<_${1_l$5cqyv5-4g}|ACR~!vN$hj zAtpm?C`e*1hz;^EI5U{UJYitS1c_IJ0um$+q8Utzo-i=fgTxy_e7JaQ#}fty$4X=| zUeIDshS*6UiE0oVq!?^C>%UD546~jvFgPi&a&Bf|Sn`B{fiaL(WHST9b`aA)leK}- zhvo1S1_rau3=E9EpmzVcCkzarCK96`=sq@~1uP5<;DOKv24>b9PZ$_1T)bIsKY{c? zTzo(}9>I9NOv)@QFJU}C(5}CaFrGh?G7rm77%u>HF$Kd@s40O=$|5WrFkTRovIL6& zj2FzLEW;uJ<ApFOE3ha&h1>|}63V2k!J_??fdN#Oxr8w(8!*HgKV@KWO@{?Os8Hku zHIq^qVr@V&8Q5f8Kr+QJ8F0f3Tq{8}`huj(VA60SA%#|KI7qevCX1>Wsw5Glqy(k} zWGc)}nIIW>If`y{5l9wZpu+V*O|1sWCc#nyNH0Td6G$u><OonA0MX#;5n8Ksf@D)* zIzX*OsKf-2L@J5{A?8g7Nu<FfKw@C?7-HvwBr;(}fg~7W7lXtKVPZ(euLMby!X!X6 z)ZUFCi3zZtAJ~Iywt^~rkjrCtfMnOhdVL7l*!>`hji7D-$d^bG$3YU4VKqEl0_x^- zAlWV8w9Uu}jsaefZBW^3Ala#~ejd8sdm!0uuznu8>~oN81IW=J2Z3m?@eHx=KoadB z0Tc;v%ZDNM8%VYWLzW@-FG!*lLjtOe^%(<$YaJ|7z-|E%46!^QiFzy&A|Q!23<;=t zG9cMLP>RRm$T*c}3=D1{+yikBFNlKlSmJ!2F)$Q?<R*gz85tpRV8_H&J!4>)3zD0K zEC)&z3~@`JF)*A2$t^^dgXp{PjDg_`NNxqP97rG3xqm>;ZG<@&qzM|>EYBGjTw9PO z7-G3WVm-)WP{l$ZiHQ&^klYPU5e%`CAld1-0!$GkI|EZM$Qp)NO_1zNT(U+WS!j?z z?M3*_#OgT%g9}JS6UZ!hbbvTuck`a!0m>d1b}%q-gO*^&`hpZEg0d7yG04FTvB4lQ zcn=UH#}FF{63YY0gVYJ`1eqeXlYxO7v^qaF5hR-pvIQgysyo18&1(r(2Ud~+Qj!Bx z0`eWW^@*e|wg9B08m0tPCWDg+#FW?ykSusB3CIqx0gHArFd!Mg4zf7538bzI#gtQM z>OgTG-vd&Y1@avuBV+7T5D(s91}T7+l5;^4@SYJ!B9$R_2}rOAsu%1?hS;?ru_{;y zffPbb*anh-cX&Y(sSK<UyBHYuJ!fEWmj{p49ed8ez*x$fw~K+{`f~;bPkHcQ-aU|L zh4H)R3=CgE5t|EIN)K}FZxAmZR_=k8)boM}1{0PS3=BLk7#LiNL3~g^?b!v2DsWs+ z;$vWNDT7H|1xtW<vBDr7IiLUs=>R8@SZR=09!!jBH^>zB-3$!eU>%Ae*+P)nARS=Y zSPhU^5sH|J(F+C!8<2PjN`!zokmv_nmgU8lE5N{z#lr)l0$g7(FvPuJU|=}`TCkA` zVeMmKU|<NydBMQY2@<#fl9~cxfucQdE`$vV|3I*oi;Q3`*$hwsI!h14WDHvZ3ZyEK zEF&XWG((n=fu{x}kej)ifx!%<jDdl{5=!$l<tZ~TFqDJBAh%^V149^80(4+Dh{@BM zKWR4uL;k$o3=Da03=9mbKuQ@3HZbmZ!NAZCx=__=4+BHt%NGm`zI#BY)Pg4ki{8Cp zV3-HGZy^CD3!188WGE7U36-csl?Zlt$-vO^l7WGzA2bWi$Qbg36~qBKJ!C3a9CUPc z@hlK?B1p7&0f;#h#4IUZ24aJIzzht*D_$}%903VffWnNCF$Ap10;H0mG@30qj)8&k z2a5IJwI9;Q!RO+agk5{dz#tvZ7Lo)C0d^2omg>X6z-YRc0dlt_=$uZlmm@&uSqFB$ zVgTLj0lHH$uouDxA5qN?noKR1_F`aQ1h?fu%Rj&jkp2px{cNBO+kv3PGD7>=Ko?>{ zOxn)|nwW){bbt+PQh5+|Lm--!ku)nKX;y}4F4(|W{+fZ|ZYl!<<NLkP$od6xIb{B? zAcAH8YX*i_pri2k_d(^=_JJD2KVLI2NHc;@QDXql{1rs7{DrBt#;sO^#rzEegM^nr zrQ;h02GD$<S0R%!1CusL*bBV!NzwlRD7ipHgh7L{5E0%G(3(bX&o>MV+?EUsUZMyo z2Hp5KkTVs$q(J!$NyfY64dnDKFL{J0xBz9)?S2C}Z^TOll!DNuz30AxoC)Toi6jM5 z$>4qc4FkiEHw+A3dPq_rn<0+WWqr%Qp!Al3!OI+UgcCvygSXyW28LXaj15AR7c?!* z;9c>Sfng6w3UWRMI2d>#_MLvqz`*y8fx*iSNf$&)<{blr14zmnNeYy_8N7qvF)&nt zqyo{TAk8=L{&x%vJ3#VL*yN##&b?z`5PHwR;00MR194R(C@S=4vokVqaxgM@fliEu zMiNK{;^?Y0Zbk->!Hf_o1_t(^eGCjyU}9o70|Pr~#}WJGNem1zg$EcIKnxz}Ds1+; z0}Kq@pyl}NU;?y0kR7zLmL1HR1Cj-^mVsCxi71d*6i6%zq$3Js0N8>kkS$T?K<Yp& z_8Xx66`-9QydZ*s{RM~*T4l})A{f|zfcW55IUs_8o#P+_12<?}N|7iBBSRJ_^-CXw z<%NTwlnVA%kvdG)5>>XWu7H7o(GMmV3DE+Y`Yu}uGAsioqXw2KWnlwdKFC-P7X~Q` z1n0Neko;D54<xhzt^lMj#1a$_Dxf6DP?i<Lz`%F_CJ#E=hLIuInuC!ckb{wd#~xJN zF*1U6@PJDlhJw?Ki5!d!n?R-Z512kksa-UQgOR~4ih+Sq@DSA3&;olmOhOA)qI4M} zvpWL=qa#chY*6464o1)&+Ms10Vedig6^tM@L)lS~t$8Sl8Oj&V1eG%2g^ON{pz%?L z@-~E!B3KBrmQfMBmXV>{7a`4zB+U$#hAef2uo=qkfbP<L0J9OPs1^rbmkSPTA#wIc zpcQoG&p{VELyA*Dq~cVN4Rn<xM5!S7&Sg+2uHs^3;7DU&V6;074J=4;TJ(vFks&IN zfq^j`CIK!-8H#kcp%MkC64hP;h1`q`wxF`G8!iQkYKCerfo7Q0GE}M3WsH#^>-WNh z!PdjV9<*Qs7WN=ELzy&4@hcR?3}ptO>iIuRQ0xdOCcrgW1Uu-4EC%qBmvZ?`Q0)aO zxj?m7h0s}~O6x2e=+tRQrFE7KlwKIhJy6s`0@MmgofSk~*$vQTU$sY|!G~nKIM{Yb zh{Gc1HR!}~h*^S2W(k515{D=i1Rn;@P*VV^vl$o|?yy1_jA5^M7#SY&Ff#CL0q2O? zOa=yqEKsuu%&+ZXU|`6Hb8`+cFff#WxZo*>95qG;h6WIK7pSbw>0)GHXa#Y1g1PS) z85lZ2-0dKvbJUm^7$$(Y$3Wqg6T-s4Fd4)>m1@Vx0B(e?197i{ipCskHU@^hAnrAg z;^G4!<~@)x#TP)#S77FK5c30wnVY?bfnhVmPYfVOf|xwV@<Gk0x*#la(jOS}L5;6E zBW#lI8S_EyHU<WU`j$N)qZk-?j^`yXF)&Qs!@!WgU=IUB17kB21H)=CYbO%}!?ryP z42_Hq3?P|oW(I~sdl(qNZAKAL`;~!#K@m#x%t2~1nldvmfZL2<r7$J>Fr{;mluB^J zl%C(iz#zy7ah4>M=2?^{#LU3(0OVS*Su#)wO(@N?7|E>nOfa)Rty*`eb)it2XBm=G zYq+&<_AoG*KuwE=(mbp4K~2Scro9Xdb&K{gFxWvQ9H6vx0$cvBy$lR_Czu%+j)7Fg zVo@ce%9dXXQuUgdfuR$mN(q~)gKYVrMrIx#3j>4wUPu5y0y!IMT_u#}S%>5WLl&rS z8FIA`GB8|&s(A{fd9LPzYO7pcEOK5#`Jj3(S9>3(J};qsP#Z6AE(-&L>pljCy8nAI z6-h_3<bzs`c?Vb+7$iZe?qgHM$dnIidxE_LPRlUIeS|sk8X_&D%b}!Y3`s;<&W$_B zz@WecwuHe7O7q;y2UWhgE?DHeWb#2(HYi~yFfuUYII}V^fT~!Y`=Bbe9%LM-K;gL$ zHliM61ZYJwk~RZI28QC3pltd8oK2@4WMBw}+MEKVc^>40s`0%2tPBjR4l*$07GqK5 zrIt5`m4Tu2AjtK(+YT}?z_b@4i~-g53{8xcP>~~0I_D891H)#JBOZa>4RXW<1_lP6 zM-YoEp%ydLgUn@M1j|6p>VlfF8cOF#urV-f1)232?4i>K85m|j<>o?Zp2zuj!0u#V zU;sPyH&lY18RU8f2A)^>P~-WbB7RUhXFeM=h+l)93Ubf{kb_>sbVx&0nnUTFt1t(> zfjdYADyIphdEUSr1TGpfp~7WQn&%@@X8FMe%`9N0FeNQ8rJs<LO0&b1${b=~fGODo zQ~EU@)F!H9#v&)J#*`0gN!7hLh^bLpn<*dE{;Eqk#K6!CHEk`FmOjsz4{9dWnPQVH zWXuOOxbp1S85q0|fr{eg><kRy;0mFR`7i?m%ovy>r7tk%a~@`3$V+5rU=Tgbz)*MX z5T+_2A+~%_ODV5~oq^%iAqIxJ9W$}0l3>p>=3rnrHj{xN|K3anhPu^Q%<>Ll%oE^X zVAyzwfg%4S$gCc0s@NFw-m)_=OadvW#HK)nG4B*R14BL7Z;)igP(ST31H%DOa`~DM zY7^C0A7)_qz{tShC6EtlKGi23h7<r^0{NhpRx_jLVFrc(CI$vjgn$}l&5U}785kNs zBHB#(p!Qoc<AcKt3>!cq=Na=st)yngjUZz|B880kphi|+7zYExagavF9u5YE%b;-d zKElB802*nqDo}bAV}8^T28O)poD2+UM;I9Dq_L<HvS!OS0;wwDWMHrZsrq^t(=4HL zZ26$(SzaI~0|O^W6(|v++b9&lo~OsjzyME)=nACOnDV$e85rQH5krACQ{D>>1_pSF zd<pdwFSNFlKF^r9i<5x?o+>dE6f)-B<z!$0r%VPeSjx=gLP?o0<KSThOPR``{S=@O z1*J@MRq&MQ#)XtJF;q#g=Y8cuPnqbdKq>PQ7kbLXP{qcWx1I|rWnw5$Va)5{LQ9$8 z1X{P?2m`|!Xs~UB(x4o;3>1CESR_H-1GR#|`3+sCkOX_41TVU;&{cta^_2(RR~V|; z81pXiAo&VIfeK^ZdL9g4)q@h90W$*w52UnfW&{;?3Cxfj1xi%SjG!`Z0!Re8Tq}oq zzZXiQlxrB0uyQSq8<u()cu-Og%$P|q<6x<03O7=@hOP<}yx?-}6gN`p!B8c^p4Y>J z9?s~hK;fK;5zZK@*ckKNki!{6feK@uGI}_JL-_!DD1QKjDYPPigt7t)0|QF!VFB&t z_(ExvP{xpig|am-ER^T)ql7Zdm>`&Ouu#6hixkS}s^FoV%7+xn7^)=L^E3p|Lm6Ea zD3n<R&{H#pDmKQvNBl^s8AE{zW8Qv#wA2g^<p376wA=s+Q<PBN01`n?%NwA<aTZFW zgffOCER=uo!9sbaFiI%HjJX6e4i?G={79jUt_mK?Y5Yi`jG;<`Jx^5xJ(ST^fkK%{ z1U-~7RIxGU-4{j*Wef!>jCp&6(Ly;FR7b-S&~m63c_8(5ZuMaX26Q=S-JJ`nyRpcD z>hU^IHI6O^tJ3R0H9CeQO6~pt6r(7$y8<f%gEXvm_ZEQF?u`OSwR<Vl@w1>byms#q zM5^7<Rl#fbOhKgD9YYnYc6Sp*s@*YEMX={73nJC-=n6o!JA)un?T(>9n<?+E08;H< z2ldQkC=IIJ*9#)m?idOR8S^d)LTmT0g0M6lCxnuwVaCD33YMlNgpkrSx+-{@wiZH4 z(-^8G*z;Zqp{HqdRiHF|TnIf)W2j<d%v&Oal%_Ehs4(U=3ZbQGMD4x^8f>tHjZ(X# zOM<)yuiY^uCD`-IgwcJ4t_tL<U}1D$VW?tb%rijFsTc}W81s11b1DM^Lkr^rsE58n zX~r-iUPcCHUPcBU1IAhp5eA0apw6HHXuyl1l!c8GbT78q4d}ofXwZ)lJOU>@8+-vb zLo1^?FC#+&FC&8&XrppSE|>+H#0V)sFpI%VP!F)U3dEcPVwM!wg4pvxYzBr>HV)r- z1_s7OsCL!!GBQYWF@vtKh0NM<F@tWE4r>94b8vvf8Oo+5GB7aSM%4%&nYIPr=^NGw zQtSXWgrSX*fejqL3}--Rc`-0BFovz+Wn`EFatjwD$mNWT?TpzX3=Fe`7#X~{84t{7 zU}$IDBErD%NS2Yoi-!?3W!293R|GQr=fw-w)XwN83K`<_;)4p*i9$vbz4*by)y<5c z-fsdc1A~_cW8OAV1_p4axsmY#D+5CZBfl5}!wZlF;*6jn!mtkrb{%Lm&;sggcPQ;8 z&WIR7L6<}sLcx$k455HchM5?S&17^*6q7L|kxT{+ufa@=K{6RMzLxh!lz{;>#>UXh z2vRoz6e!}1;IX&7S7H!3@c3IXRA(uahL68BiXn}^p{s(Azbz3%8h^u31si`mE`}I? ztJAu{z>o~JEgedGi8JQKi7_xZ+yEt=M#c&3pcqpSXJB{(iX~}CjD103|3G5@L9oH$ z-3B#vDwOt;Mv6&vNtE!$kVFb^P#S@mxDcDk=#nTVV@RTz3^Q>vHj~jMQB1~=L^By? z;vsA%qf4Tgj3J3IxtY-y6jf{t3|=yf`7t*b81j~iGccrs82RE13`I9UgDJPg85nAB zFfim!yTQP49%}y!DD5>jA5<3Q2}&?9thvF!kiP@0$3%jG;Rwj=Mn(fRkRjm`3=Ewh z0S1Vr2_Q>lp_V?Af?B#j3TA1o6vWbckfjSiilG*{OQBfADGjj*Qfz!+V_=Zx;DC&p z)m^;7z>vlXN{b8(wNP4`ha(?U2Ij4kW?*=FgMk4&q=cc$kr^_ibWs{swW~<Ms&<A( zMgw+`pX{X(egYR-><kQEvW$6$rJ#itLmjB2xSk#2giBD`OOg>WMusj4YQKRxkl-;g z3`ykn_YSCWXQ4Do`x`?N*8V;w0rQZ)B+NtLF*2AjFjs==aPSz}O9`a53c4y#We)C3 z@<=iu#>g;KNwDYbmPD`B(N%$J^%;`rwK|3>HpaYCNu;(4h5{AFydX)mwhA~RU|#zN z4Kb96K$k>`2n<Q&h`0|m4rVM$L|{n5BI2GTEFu^YDT@J;V!nY+z+_-xQ00cC94}?0 z6oW2_;!q4pWQQ_AjZ=WqC=SJtggNvJJPX9iprja>F)&xcQ;fI_Qi?%W1y3<nGDs-~ zLzM)3-b)$u6oak`lwyv_pr;rNRcwrTi)D~f42A*~#=Hg@Y$*ojwNPk?p+p3_BuYeJ zNFqmsA=J14D2);k7?QAv;E{!;m{M7kh=3Ubb0s_?^ktDE0$mk6B7$U*A_7B|1bZH% z9C}2cs{%#DJz4aKz);1;n73ONDIzcws4(Wuki`}eFt0U1LkuM%&?QkK0z(oxB0wW+ zpe$AkH5MfzFeG6Sp&|#1h+a9Ah=3Ubb0s_?+~trW0$mk6BC_O=A_7B|1bd#OJbFZ+ zs{%#DH#zi(z);1;n0HwYDIzcws4(Vjki!-cFt4qIh8Rjjpi81e1coGXM07)qgBgnw z5g3xNh_I1|MMS(jEFu`7W#~Dmi65afN@0&KiQ-TUNo0p!hZ^?=N~1UwLlWlDCb&ai z!yO8)bz#Q9TnSGxOXZPL47w_Kia8;VlwvScNwDXYE1;(sbXA}f6QY2gVlY&(G3FU6 zAf*@#1uBerd<xi749shC(2gWZM4(HeL<EK;azy-tMgYuMl!(BPghj+G1z3vNtAL(j z6rm3Eh0-WV8(k8`p%{|L4%LMk=K-Zr9Eu?cbLa!OLp>E?4h5$em@zO{!cz>hB2tP$ zR|QWoYKllH21Atud)`$=^b~`x3Y20tDWazs3{`B5dHsq=DF#D<3S(Z5BDNF*^I9b| z#84svT@ocCFeH&9A`)s`36w^O2n<PBMEp>MrI<t|l!$;C19K%jBBYg&A_83%JR<Cr zkRk#@l>~d<TP5^}KvxBdh*L`F5rLtKjWKVz5>iB9C{SU{Yf-`$5iqaKfrc1LM4(He zL<EK;azr#ijhhaoQ6d6E5*85x%CLy2R7Qyim@zO{!Xv_187U&rRly@7Oc^O6FjPsf z=dr4wM+CYmP((aZMvn*#RcwrT`<0O*0z-icW8NHPY!LzT+D>SQp+p3_BuYeJNFqnX zQmAn-V^JakLlPDd8Y-}e@K%9E1gH^J`j%NZ0kr<}Ep!|dy!tlqA81%n1w5=6#>vOX zApM>hv<N(m55)ciW;1YuMkveffL6oSz;w5R&fR2S2OX1E)(TqHI}IiSHkW~Y*;@t% zZqTurQ5!%k&{n*%ub`E%`(X+nfs6nTi29#q0v*f=K3fvXh8R#_!YIej$nYwVfr0Tm zOrP>Q1_s6ukOSphxPllMLPGf&8K6wi&ICD^kDwJ#;8WBJOc-Nf23Wj<`kY7u%C>`6 z<L1G1L002}mOBdxfLGvF2nn$FnSl19lp$8)aza+(f|YSXR^OI4qwIvJ5Sj;3^Fn}; zL1-Ri^TS6Z_74afe30jV5PJa|=rSpW(q+t_KrzVh9_kOsNcIO&1_o(U<~JZem#Q-U z3SnSiRE8;mcoj5`EY}Y@Bd(KCt{;2>UfBbXI&UoMdO+$J%2o$4FfeAL$TJiKGwKU6 zGKhktKsNw@H<W;_07)gmq!yy;>SDYAP09a3=a+y-t53aWVDM#|n8d))&6uaczyR8e z1NKfk<0%ye2GF^t(%#IVjU-{9D3uOi>lI;S2m|{ykPUPoUL9ym=Lyu{A5dC4kS)(z z6*|7t%xLtMf#Co<0|Q9-mKp<t-CG8RJY{tT29LL(5u!3R28IwY>xMc5L&94IhPs}& z3=G0hS879P=}*jgi_{qyKq<Vg2%Cb*OnEu#3=E*m!N5>gI*Wn99IDp}N=tubuG7IH z?yt{PxAiTidVe*pd{9OK<=kdQjdu(TA0Yn72c_aX7Yzmmr*{ktdAw>248HFe81f_D zF)%bUK7Y%=puoYvAZNyy56Uljd>RZ4j39*uY77iKAcf-Z7#Qk$-!U-wL!DLwrRB^S z^CyFpR%tLW%m=AT!J<lti!C3NCGzHKFfder3~T`@T{(+^AqQ#@%s?Sg_Phfc3=F$w zF)-vGodxm=sQC|Ck=g`R+6JYigCQ$Y^Wm#e(N(}k!}H-QQ883NN5b==t5EB{yklVK zhFY)%N=t{b<vrG5U;yQze6IHl40UUeR4sw2TFIQh8x$0AstgQ=L7u$*4wPVm)fgC_ zzXN&V{VWCsnCcZUU8|V$*fbd!*k&^@<O|JaVCZ3#n+;P8Q?v%Acr|lAR)sJHa2Kz^ zRLD>_@jU|rOvOW(kzs84psZI{hDA~?gfSnKW$O}=B#%LL%7rrKgR*+ABR0v1d{8lw z*Qm<C5c-~hAs2MZ56o`33BCECGAD0|Dg%S=dvH{P+ry`!Ho)8{7Y<$9cU%>z_D5F* zul--CBGvvFswCL+G&Rv{e{@x#+TTYLz4pgY#m1PIuZdLqV<=Ez%$uZ%TKn6BPA%mY zVPIe=QV?QfI5?YufpP8^XyLs13#gWQAj!ZWI}@}gk^y`UXfI;`^c3bQD9spl;|l|W z6;yvW<5o>bX$aO|>!QWLfG{Js{|f^{BvfNDl$M>D_ga&I0c3HWq80<g@-Lv^Z)FS- zVr1wA&Hhy|g7y=FS)ge^$n<6fXp%5wAy^bNd0D(1#H<A~*MgWeASQHrvjN0rU}$CB zEX2t03M9J}WF~l?bSc;%@H{D)37H&S3DN=8y#~Yv>Ha3f$e<_8$lwLKy9wfqjR@Uf zCPepEkPfKs9UwLXLmy)U)W845LH+|xc?JnHGFXGm+sDXQo2~_&?A#CXWbHLA=v3zc z&`f8oyf$>A^B~B=+AwVf1~xfH2CqY4Zm%|U*7Go!drccU=XnHVH+TVZ00#qu*U3CS z9cbNBulSXLp#da#CNENlfx+M_14CZF4g-TVh;dYhfx+!7r~n8ADPxq=WnhT;3SD@- z2kMXWP}-{|?>F37(0s}Ukg;`nYjqhIK$AE5NE0_9x{&!4@Z<^TerZrpFbRN21_o&! zj=U~?1_tm1$_0I-2^0*Kj?8)K`q1?eYxQ9bMi+f}gRzP6JJfk%{1DR{7`t>C7&5+s zc#Vt)co-OR9_unNaDqbdA!xEUr{9Eufe*nAvtVElgma5U5KJiqQy$I)udr8wT4oNV zy&fW_htcIwrqM7Y5z}a3gJA}GVlfz94#i*$Ni>6D28LoW7+ns<U<^q#gJA|HVlfz9 z4#i*$Ni>6D1{Py67+ns<U<^q#gJA}?Vlfz94#i*$Nrb`mrC%8s9)L2$<NOv-)^gWl zVCV;Ds(L*J2GAWU;EB(EsGTdIwAU)g#OGE$l=;XTdXW6X(8wsj398Y5>oG7a1E=Zw z&0iT995@*mydLKt0@)N}z`$@8Y?Gw{1H+B43=H7e&H|8<Z4lGN3{Xs8VgNB6GTV88 z6MeRmR}hqW7#MV+G<>#G*$^qSVyJ@6cDfnDGU{hUMg^BnpaslcTk{$WprunIqX8Gl zcee}}7@mNAmkSEVMNoU|Kv&{0Ffe#MfrM$MAuLRf8bZSq)VPKz-vHI-wK8v^A=CzN zP$Y0MFu(%(w;@VUI2u8M0^Ca91vTIdlt!Hc{sI-{g1QPGDwmCrLIpz=EL6T3!9qpO z2wr?OGEM*oK)DetdUHY1+XS^DP8bpqUQZxV9d8VaY8zunRD-vOz?AnwwRvsLYc@s> zfCHcafTjgWW0U|mWsDR6)1d~egwm)1a1kmBS}z827d!wwO^^ZrLlrCla!g<Wu-q6a z06u^NfWZWw0zhk2)<Qjg0ZMzl%G+YXzyMy(a@_=J$;xi1g1t~0zGUT>3DS}kbXBlM zdY-H)(vlSnRnUfdo`Wf3$qKka1x@{Vz0PAcgI1_#O`#R)L~}@m+Q4XO2B}IL7~h*Q zFo3F8a1JQoW?=BD$y;TL96bv_f^~V(=8%dsPt_bHiki)!Q3P6va2(W(V_;x-4W&Vq zsk|k$GEKEaiU<sqj?8&~ETEOClO-%Nl1<@}(ZnbVHFX7)ZeZML2CGcLN$n0aoF7AJ zuh)5PaKC_J?g7XzZ}KKsKx6Be1yXD=iGtD%0|N_`hR2qI1yXFGtAfYYD|4jS!cYZ^ ztu5wAu>~q040sqAyxu@obJT-Y93?;mzzd8T87F|62pyJ?ty5m_KusyIS7o7&)P~Yt z@A6h#LZgj=As4hJV-{5EDwOv6j#!d`E{8Inh9QYOp0*5X+65?$GM<JZ2^&v42ai#6 zD_D$zyEZUmV2*?jY<{#v>e`^If_H61tdP1k7^)=L^A1~~cWuyBfx0#etkAnQ7^>J9 z^J=Y-x;7XJR2cK3tWdi)ka&Q3ja3YizL4VqT@EE4FeH)V;UP5q8K9=3!~=#TEFPX& z!E%<rHA+0djDa~49uJ(>Nb!KK3LXzS)=2Syp-O^1@3u91JfN!r#lsG3^mxEf#m1O7 z)fy=tFchdT<`r3EiwBt3jG!Tg91rMnDDi+Hi5w4nP}6jwG)g>RNW$XbpEWEV(rr-U z0cH%$k??p>v_XmobXD+paIry(2Mkpb?0KJU(BlDJ6(}Aq*r3M)hAKA3ytOt+@qnQ~ zg)y(o23tJ9yp{wFG30namqUpM3`yj8u!foz3#C!w0YefN4`Q~kc&N8Ui3gZ5Fh|1U z!O|8f9?(_6;~~ZtDIPFXNwDW}+o8t;x++jSys$-&2MkqgjCn_Gk>UYEfeK^ZB3o?n z0Q1^ZXow-l1G*eaJYYy7$3q^}v<XleB_1#&Vez162aAX4b|~=xGX~~JcsvB!A;kl_ zDtJ7U*dfIOhAIj6JY{?IctBSLiU$UJ^mxEf#m1O-*A6KjFchdT=Iye>77sA59fgJ% zay+2Rp~M4*Byv0~gqn5$N~6RBh9oQ=-0WfTu-+ae9$?1690`wyOnanwKvxBihaP*R zc)(C4!JcRBfF2L%szC7|;eZ|w7^>J9^S;_6#RG-{6~??v_SoX#AvC1qphIKG@qjLe z5)T-X$no$GYN{mERFrtYkc7oUoC7Q#7#vaJ0cH%$k??q!;(!zn=&IoHaLNHG9xzma zwnI9i#{;@5P&{NhqQ?V<D$sUFN2GYbPypHv>4+^JU|#crh8S`@pv$4e1BN7WJZM2p zbA{3<@qi%-i-+}&uy~MgLWu{MF)&BM<KdDcQaqrmg2%&GN2GYbP$j{hx5NoO9?(^R z;-S$AJsvPru`%YwIU&UZh5{AFJZmRx@c{E$E;PiD;{ja`B_1#&k>ep4YFY-AMu`Uu zNmx7_cY?)(fip@xz>I-85*`n)oRH!HT@^eYc%6~r0YjApd)^*r^mss51&W86&gk)g zp^A+$ugn=K9xxQBFy;k2V~Yov*Cs$i3^^Xq<xt`QLlQY2%AlroLur(Fz>tK+!+mF1 zJb1XE!~@J2m?Powz~q7y59q4k@u2F06b~4xB-rz=xS+=ax++jSY;-}72MkqgjCp-7 zNb!K7K!q_c+XY)Zz`V8x8e+)tfG&p;4;Yfj@h}H!+IA?75)T-Xuz2|H0*i+PSCn{w z83S`9JRYQ6k>UYe6+9knU6JAeLzM)3-Wyl+ctBSLiieY~=<$G|ij6UEnJZE}U?@;w z%xiYV77sA5eT9Y?ay+2Rp~M4*Byv2QfSUFJN~6RBh9oQ=_}yUfP~nCW4=`h3j)cd9 zksDGxpsRw%L#P{4JYcAjV9#T5M~??|RiJoy=!PB-7^>J9^Y*zR#RG-{6~?^TZfNlU zI!!gbh=GC8O^6Y41}ylvJMc0j>Eld~^B5T5r>SO?frdTUK~%vm#{a^M46{IMpc-I0 zA;$-T*QaDL+Je^K6x?Dl5n*JA1f5C<notEVkO8l2fmoo+<hBrG0cd%U^aB>qx+(^S zf?F(!Fim%0W@Bh#C`$yLe#a)v$Y2keZUY_23N{|;AUZS1L3GdqT|rhclxL%yZU@(j zewHiZSiJq<<L+Q*xk3zCgx!!pkl%%rk<PbMM$)Xz2G(49hWQa_Q|xwOXn;e!1`Yxx z@WL~O@-6TcQa8mIAqUnzhB02l7(c`q87hQokrq$YA}yYRvfU*Z8H8%t5R0ekp^K+9 zS+*vDqFscM0epXQfCP$j{zxz~Nb50!kFjNuM6kim)B`&cvJy#~1-udoeBiDQ3+SX> zhNx4K3=I8@3=*K^!oaXc5<)YEtrKBn*tZ|F#!1~BGOG_hO0%}voq<6WH1i3*|Dtx8 zI|G9ToI8P$X`+KRh#L%wXYll;6x3)#DD4%Dm={HtLz!B`kVH(a<${KlVFsGP3=RSB zUj?5X$50Pa@c}fb8;TGG?`U;~DtCp_@B!zOpv(<AD-Lv`9J(s_fb$!7qyc9PRj>hP zeh;JpXV3x(1zrXQukbu04+aKM?#&MnVq|D$%oAp0DBxva0J)(}n2{l`+Jk{%k}xAf z{ybrjyrwWC!vbCg29WKZAo(L63=E+l`9!e%XCX!g&{-iu2ifvLxhs#?lYv11BrgM& zKO@A*0J=h3$bvmD%#(oultuHOfvuh{#K>U4$G{+chb3>mCj$d0%ja(tVq~Z*5MpE~ zhXzg`l$O5DlJ~-sfdN#0<adEgZDd@)2b!l#@@8Pz2hs)_R);B{3Dfp~1v19o%(z;Z zks$$O-(!|MIWGnVP?pM@;myEsP?!<2sB1k`(-tT#eSsOWsOy|J(xNVORq#b!AHC5R zbzvwKWzVzsMqAWXXDGtRa1LtaYbY)Kge5QCi-EySgpnc7+=qc70K^dSVPMD*VPvQ~ zCyYglE=&FoP!vV^FfcHPFf!yzh%hqrFsg`vPTT`;x(tM7u3{)H{fs4Vt{2i_5s^@d zJSYu1EaI{k(qR!83JMwXIK83sH|Km|wW7HnO05Vp4sI{(u!xVoNVOumDtN6Z;)hf# zVyFU*_WPmNis-69wc-Ll^jZ-^6=<~I52;qfPyib3_d~B0K_wRWteFdZ3=Cco;OQ2~ zxk(KC=;tPZj(kBm(Fe4<6l8!dBFGWv!C^?k8XzxyU_mYKixSi@V@zSj!Ge0T4^mL0 ztAYo0tq)RAW2ll~&s*(_9@OZnKtbK%iyqV%s@NFwQhkwv8bg5!W1f>QT2O;0xL~Ph z6V!{)5C@;jhc1WG5X6u~ZU}ZkO<N14Q5u36lCXGq<_C+14u6z*fEfdGB)lOg<Bt>% z=&IoH5af>(4;ZQ>*z-gJ(BlDJ6(}A)`lH7KhAKA3ymS6Y@qnQ~g)winKUzF6^fMlS zhSM5pQ0fJ(D2tb2WVi>eu+0OIE9}Vu&<Y!TZ+Y#u0BD5`;ob}Y-T2DL;05L)>hBnM z{e2f|(-$c16@#e1(dAI;ZwyJa`Wt58Pnf~6h?*Kwe<$!WFnGlwM8Wkprxe7;+)x@+ zcY;rZ{R4^<SpAKz3RHuFPlS~ZM5@0rRKe<Rr$D6o8`PAT0CGw^np32qPLPGtaHm`h zM4G!sR|R*<Y-FcksDe2q71=4Ero;h|QxfyogD{#B0s=@)iGU!Cri6n4Qd44P5Jpp? z03;7<N<0d}Xi6*q$y>1JX$NC8B`$!hzQdAN5{%xI$b<$?1C$0eCH4lRHYFScK}`ws zP^6{=OnEm<8){PmbPAL7W0t(n!O*5eZYWYyVj)!1GAIpiN-PdVYD%E1f;T0Og`zhl zFqDe2=ZS=3Yf2n|T6q^rgPIaHA<(7-PZ+c*@iG*tDS@E{)|Ai(-4BAbDd7ms_Q_Bh z)RZU+L262PLM7s$G^i=DA_S=^fuW#~G4Eaov?;MT99FLKM4*(bFyr9%!s@qU;Yj5w zx+-|N`Z64;T*Xi&!JaoG0=-;CR|P6pOC!+BRSZ>ZjCny3NaZSq0u{zQ{Rs4O6;!f- zn-T?r3=CdLNKJ_ag6K_&3m_5XD(oLL#$^#fj%Z3?NW!YHePOVm{t|`~)G%XIVaCCN zx+4rJsL@rygE}Y-DX1}2NwDWNgrf&Fx++jm$A+T^HHIoS#yqQVq@c!7pu(6Z9*!2& z;HCsD6)l2#5gOv)rUbeiN>c(u5;-2Kpr*}*(kM*{3`tl#?2drNLu@2UJiv^BITGHK z_!xl{59q4k@t_`w6b~4xK!;I8qQ?WeDo{Kei$sqH3{{}RC?b*K0Yd@kFp5aDcwi_M zW$^{=%$lWwGNu3?J5UFY9YBVE)FJ17fksWF#lhnU(6J^d$Up+aM8=z$pnX}7VFrOW zSA~EKk}C%9bp!2;k}GZvW?(1=86$Tayw|OZaRW4>*2#nNAE+&(tIEjW#nO=g8h+r3 zg0yD9Loe-&pwq`dW=b1?9oNp75)IvRWdL?zBcp;S0|R8dBLM79=*}w^_|B_)Q2X9N zY3V?gytUELWn7S*R}4a+omVV*KC#f9S5sqQJFi~Ez;<4F#Ubsy;*^0nUKUD&c3z3Z zA?>`vP%xP(?_Mm*&MQNxUK1z{+j)g94%>N!A&#;0$^haI$j+;6anPMt^)VPbuL^{a zc3w4ru51GBAzBoJwDYQ&5w!Jc14tokyVaXGNOjuG2-<J;K!||>UWf9>qt~IVvXBsx zfYP8nR#)QD>QIJe#_KAK3<AOo4AMa?`Jlv<=a9g_@K%M9A@6%U1H%s$P_LR<m64$y zv>VGon1Mm=9^^`ZuL+P=S2H7M1m}S;q_G2T_3cl9wECJEmG&|)G>9-TfQC%KhyQmb zAewsMeOG_wAnw$FCP(RDmOSl5^nF(_RiKkIK<cGo`>rlTqwKpn8iTy=N)~FS0+g0s z#he$Ah-2RsOpyvqF|K`AFa>ZIW7~Jd(9GDU!pKkn+H&d3lD|X+G{6K3!VMr1X%<Kr z&WlG5!vHa)FwBTY4#N*1DOelTC>|*cLHoO4E=hzrJ%k0ZzYARwWq%h;(haH;Wq%ij zBy@k*=V+w;T^Nd>`@6(qQ1^FvLv4V$5x&36G6tz&M^^<e*kfXl3U&-t66|>$iRcA8 zx++k?zB&=TV8>7e>LVsHAkJ>bP@uw?_c0NzU@v{ktX{&vz*wXOE!V+!B*FGfGv_fd z!1hcp)M8|S?U@F#8Mr~RWkzWX42&CKx_4_aGB7f*^DSavD4SWpz`%G4CIdE?p@>_O zks&dMfr0TcOyU<v3*@?*e2xmx{dnxAISdR%v674o+Zq@c7<sj!PBYMEWMB;3Aj!xe z^pFEo&IfLVu+J`JU|?VmZeU<2+6B|)Oq{L)6GmPsMuz$t1_s75n3hE#i=f-D=hwiu zUxS(8D#_*IB9M)4)eH;;CXCTA1GbZBK+#GmMuu693=E7PVLCZ<Kz;<@_><4Eu@PiT zULylT*=EqqJmNagkbq2xfa*7ljoMX+TX{Gkvld`woRFJ%${cDL7#QPW=72p4+Stq_ z&B(9{6b4loQa&)Lsi;z=s*L^h3=E8GP=rGu8?n=>85j^7u}eYfu3%Bu15(G(#kc{Q z#}br4WhAI-=g?(j@MT+C2CCXck|0$(cp9snu_OsvlY29RW?woO6;c=&K+z%{z*b|& z$k4&KHI0D*x{n$ZMRlMXLe4?0cm<_F8>aUrF))B{8fj)s(_&-*O$CF5^O6}DK=~nW zNiqXNjTR$A1EX3p149RxrJc&aFhz@zq3(bdBg1c~VIm3;cY|v4zsU>?pj2PC44Z<< zOnJAG85lqrh5@pVS^=t88A`)yb98Z7ZH^(1RGZf=*Jfl;hZ@uhrKJPe@<Ayx&o7mM z;h;7nL*9cV28J^rhI0x7!*y*&hPpH?`anCZL0KZNC6$4p0i>KcnSr4j#7IkFV3?*2 zsu@hR85u5!Gcd@RGUkJ_TwZ+|1A{L}O=k)NLnK(ue=SA^(9Dt0BaVDfX3q0WV_*;m zso9^xz@Q9Pb5)Cx!9aq60i*_0G~}tJF)+LZX>4YEtj)-f0F?t}l)SGg3=F@uK?CLt zb!Iw@4E|7`CPQh^K5rWxMuxmysSFGrI*bf;yjWBTak1rta#Y@jR0ak`9Y%(HU64}H zKJRF#K`;YBZIJhAm~9Zy#LNT<1_sdPZt%p6P&#BZC2wLT0|R1m<^ag`s%-h-$r+Dy z$cRc_UM2$rVuI!aNDXXMr7j&Zs*>lO$-sb^q*0J$U=Xrk&)bp?8Cl8G$YfwZOw<HO zLMCcnr9(zn@>nw&7~qpNu=KD1>N(H|i$VtK2#bIeXoMv+3u%M}rhFAl+XI%oEt&9U zFlfT20c7uEmOSSS=qSsgETmDE6Htv8pfr4x<$V^USy%^Z6{4#G#SVBEzIrx#3lT%9 zD0`k!7Fz5yGlFJpHh^6Age9*s13I*FJrg>#5}yqjT4`nkP1ArjAWOr>Q~0wWQ!{zf zvl$pLre{_uLh|}0C=D7@nUjGurm`6-aTZF0##HuaAdRVDC@5sidz1kkQ_;wWbucI9 zqjWG~#=-4{b@aXSk=h~Xs^IOAynLi~2!<*N_B`1F^mYikDo{J*S3Y_>1Va@YW8U?A zq;?2~0u{!*E%|8e5Kx#lGq&n5GB`*vFi3~7<%6o5X2vWXMuq|@1_n^$4^%fbGluFg zGJuY01-1A<6<Pf$9Y%%=ASDs`pgJaRS2hE~Jsn1d`UN_S3=Gl?4065sph_z5LpB4$ zHc%D^T@sT3jh#tQT26y8AACv7j~t|9<k3~ZkCB(oMLI?vLlx{8dAnSsW8^VZMX={3 z<{}*<kFEf8jC@Nj(lPQF3bdK>mggcRy-cWQdZ9EZ>7B|&N_rRy3K{d>=0cO6KprgV zRpy~2J(zK@u!4_m80R4+J#<y@q!*Tll=LuEfetvzM^Ad_sz6EaQ675I!%zh};3y9% z>0u}U9dML~CFwCRfNzO0hK8F3lm@l+LAS)@spT**Y=T`EgRTnXQP6?%d7e284DBFQ zpnIAyR7tSs<>a7y6kQd_qy0JP9>q|_#+bJ$2g#!t3RD>LuI8Y6v<{TJV5LVGw50{h zX?38ChAs)qbakLS2b1)G>O{$Z2B2&P&3_IBNck@TBmvETWd%t2PXKC+6O@MMzcmF& z`43$cJpY|9K+1m@s$lu=Qvp)`!%!8$o+ny}l>g8bfbyS3AyWRsP@v6}7hQ;y|0JQF zv4zs0{8v|ql>aak6f)*5EQIF2BZaX1r(1-Q|6s<!!U~@Mo);qJKXg@~WclC_14ABH z5mNrcP$j{hx3dU6S)!`~CCh0==*bd86&qt-aS>9o#89BZm={olnk+#jKj;V<&@D}Y z&~SsLPI&&iQ-qZN&{csv3eJE3i;(gkhAIj6Jf&iEkD{vrdDOKS-J=+)*ckINijh2u zp+JQ(ue%u4qxRkl85qE4sgz#^FE#^pVf};|7$9rRx*@$a@R3>FkTquDBeS4v@R3>F zZ0kW?-7ZF0N9hdcqId>Shsn~4kzpA#TPdi+w5}MX!^Bep?GBkT&sqdJL+Q39Bf|t~ z1_sbz)GJFyhP-(t3=H2ujF%-03`|yx4EcOkpw>O8eS1KffkCLBEg#&zRWF0KZ}*iV zw{IC_AOk?)_HAq#w0%3f6uEut08#^M-%c)rwr?v+k=wVRLy$r3+mmI`_HAe>a{Kmx z45WSgzYN;GH7Z4F-|mDao{LZ#)V?(>M{VCa$b#CpQWZ$;TbS~jFl`T5@*b9=v~L+? z85lsbh!N$`_H94~Qv3EZRO1gQ4R7DJRUox*(N)3Qw<{~q+qW1>McMOM%Fx=kb)e?0 zFf{tjpfqR}v9BE3)O}w8ZR(z>fHZZ%3z9Ijz*@aRm5^31=7OYNsOg8GG^oY9u^g$` zTLP8X3#CED-j#BsVh=+>A!FY6a%iz<S_v!mu2-TIdobhR_QG1c*_BAe9=a+}X#g(v z7FHq^dl;%D*z=OB&`Se!RiM(qp$fe;z);1;m?v9>R2pC?P+`pbRf$>}K#IM(u-Oa@ zR?uMcg3_ST-i#6khFs7oTb1BbwpzibY=IQR6h*-luV&82st~3i3#M=lra}hR0y{>A zIkJol0e0-Ac8m->kc;P|?&UHtFr0+AkpXtQ?QU?78*$kz?9RY!=<RP%<#6g7lm)xB zmymiV=zXPbQ2HvA{sg6=#=$94)x$1mt%aJm4oYu=(r|;J44Aqms60&FekdQR3{Jsr zm@R|K!|b~R<--+188G*wtB2j&3RMQDV7ImkL$89gg3_K)8m<t^fZa9<3-=|^c!J%5 z2vr8BhPwLw&~O0V`3&;ZWhfu!{}oXG!!B6_sX@k+>d%9k54#N!7S4O1;>dP^*tAx^ zA8M~S^b#q3C=I)n4de!7Ol$R0Q2TYDH0-u6*o}M0ZUM1rtv(v+jua@J1EpcNrOku# zVb^wn+=PrN)vp1)!o~<nH$iFG^+CvXf!Og-dGu?KVETHX_kc`<(jYy^7<R!Fx_a0x zFUV>^Y}i#lHBj?l_lq3i0Lfxv*p)oQs&9mv+X1CdK+U}dr9p>cfoxd<y^RFKM#hBn zKZlyb1HF1D0ZPNJ;z2eG#3t6fk5F?#dXO<LdvLiQ7LMrtzKg?rSh|3P7c4$tcdj72 z1;qXXJu=n~dP3!QC=ENK7NiCl!_+lE)qRH2Fn!2sL2OdhuYjJnw+%|mK~FM+oooj( z6B)yf5rm!3cMGZ>b{ZhES`hmt)LhuPeuUJ+PH}^&i-4XoxDHB#%tXd(p!O51J_KqG z%-l^-{ygY$V8~{J*y!rFLDe6D(pRDMcPPycH3xRs8psS}OsskLq2?j$1+ii7MR&(( z9O{2V#nIh`%fGNg(;h<o@eWGEj!6T#0U1Aq%A>1;9rlK-7Q}{~NwyDq`q*hG4LgMl zqy`xug36<-gPo;@tQN$E9We$w+3FeeWGgo45m-V{8g?YsK`0+~02jy%WQ@zak5F@w z)q>c6q2lQF!H(i0WFO33YoYGi0j1IPy@QJXgwo=$(~UrmK*BI{KzA^Lgkk!=LiK^f zkTFah%wCu}m_5j9L2THuTD?&FCqQY~kys!#$QV|x!160BKj2ai+acx)-QJS|r8A*4 zve_UuOkE6A9;Oa7lLwOj4HajGu3UG4(y$#4AT`JswwnsJy=b_rUjz*w*iNqPP(J92 zI8eC2{O<=1H;@=IhHWDwHoRc*@*QdqEM8!{aFERgv1zRywxdB9x+2&HN;^VnkQ<OO zOr0uJ9;PlD%12fUV#Cy#K;>cT9zpqUq4ZZMZ312B2wOG_G6NaImgvLQtPgkfQ=s7j z+a9nI%HIK{Vg9#+h8uENf!MIU3B-mMEM8th&4<McY-u;hOk_-J^`D^rvVg8LT?t+7 z0$YHK>=qCkrY;Jq{x6i4fv)7Nfv%WrhSDHC$e2?7K2ZD6?T4)-MYapXCRIJmACI8^ zf%)Sn4*x8IiZ6xIhoJOPD197CpN7(Bq4Y&44Z0x><j(6*{!J)-7fRoU(vP9^Qz-os zO23BE@1ZovEMz?DK1gVg8-B0_;^^rOmOfzVT?3kL2<0D`Iq#wA7-mi-H2#XA=5#`7 zi0cvLB&fb=P<j)T-Ug+2K<PbDdLNWN1f`Ea=@U@;6qG&(r7u9~D^U6xl)eR}??CAX zP#WPf2y4`RkZ>S3{N6$1{X3L~tv-Y;_?rP;wJ;Y-Lu^BkFm-0og;>r|8n%26p%TI( zSG_*eT$uUZP(H*|1PN0Ia}P`%F89C|uyH{B2lFRvWdg!v2y3XT-v<r1mrxq!-{nyM zLwt!KVd_3X)qjW5u<$~tgs@0e4_gTcGY{q-T;VSZbth~!O)!)XOQ#T5AV_l6YeCH= zWWFL)9j(+~gPQ*kO22^8uoW{1pF&uqs;`DlFvDhh8=y0Lu=!DlsR$A_A$}XG?>>|s z)ei|HLgDue8eXu8{ohbNH#FQ~`n#Zfh^Yt?wz7cS@MrJ{cJu(vxh60$FdSrHV1SP2 zGJwPw86dL(AU0^82gC!78~^|R|363_hz5;^g2uE!<3u1nXuJeOgHF)`(J&0^4}<y~ zpmr@t3{<~>$_|i!L3~vP1_pHo1_o^g1_m7l1_lEL1_qEg2pcglFqkqhFqkngFjz1! zFjz4#FxW6KfDUD4aAII!aA#m(@C4n&z`(%Z&A`Cm&%nSC#K6D++Or%5H76EI$1yN4 z#4|83q(b@W3=9mJ3=9mQ$>=-=28IHtcp(D=1L)u?(29jx1_p+D1_lPuRtb=Mni&`v zS{N7@+87uZx)>N3x)~T4`WP4(CNMBCOk!YQn99JwFoS`C0d!f{Tm}Y)`3wvUpv@dB z7#J8<GcYi$VPIfb%fP^}o`Hd369WUo7O0)u85kILLD?XC_AoFoBvi|FDOw0JC{}D1 zQQW;WJn3?Z(xa0f-#*UcuupE1s8zAn(_XS+*8vtyyRR(AKL1bC;4(jU<jZl5MRp<@ z>i(H4!WEu)?6Uf@@@TPUmc`3GT~Xiu<_J{T`>fEd(mQi1r%2Hx>C(o&HsRpSCBZ^= z=Y#YAy!nzFR9jM1eg50?x;5n)&W+)_l3rD8(wDx`Z{c#onEzYUm#UJg?@ZHn8(XDF zpIfp1w~*{hX@0{`G8dL|*Q&fIlzrk+6zg>4>|9N&FZ<Sgyet=c>5pQ*#-7Ht#m5$| zWcYvR*tA>Cw?6P5=02#v@`qV)$>Xc<T@O_FEN#CLam?zeQ(N++BhU1Id`gehFg@OA znBtx&a7g2hxn##qt?rI*maAXzJ=^?3b@eUHKP(oR^QGfYxdqJAcG(rtlWWb-b7q!9 z&qBYIZ%%MNJ*%=^?W`^1u3qUk-}Ul4xbt=&H1m@e_c^!a<m2}rt2p)7P36ir3R-?X z>%{d9>m0l%-29PW&{q7fsK-)qO7WjJp^i5=N;kf6E8WtQd3C~+f~~83PHo*Q^T*6G zBUg;|`rH`{)tGK%C~f<B%29e|{(0ld85`3iSA3c&Wq13}?%zz)ZZ|Ve+q2mDecTI= zqPhalqI<t3rtM>xHRqnL)tCEQD*ENiKdqPNY}@kS?c5rN7cx5@sOjxlaM0sW<BPbW zg@@UnHT7Q#VKQU<pPZV>ahOTcQ}u4QT3a?}&axZZPqvre??2APb|!tb%{%sOR$oro zUSFm;+fCea+NF?}O;)S9{7mY&^a8%T{u3qM&9P8v&78(LI+FhL*Hq8G;Co?~gRaUf zPu&e`ANhrK#pUIkDbQc0Wxn35-KO6_{++<qAD$DkjxPV${XoHR?nh(6`@vr>@dWX2 zy7owN(-n1%qBYCwC$*ez4{FW2DSXmTV6tY$!O5(@zlhwoW)EGt*3wMBjnPcOO=0^| zeaY|n+qa2-w7xTAeYH}>heNY>N?)F|^CbK7O5?iMzbDN1t!CX8ZY`O!Sf+z{nvMSS z+5eYBINqOm#&ds(XVHB_%hmE)N(WZ3GcfpYFfb%=FffR4GBDV1GBAX2GBBiYGBA{I zGBC7oGB8ZxWMJ6C$-wXdGy%uOz#zcIz+l3~z~I8gz!1X4z>vblz)-=(z|g_Pz+l78 zz~IBpz>vYsz|g|Yz%YfIfdO=LZwe0sLk$lDLk|xF!vY=#hAlh{3`ckv7_RUzFudSl zU;s^a@$fP*fKJdd;bma(;ALQ#!ppz_x|MDZF9X9FUIvCcybKH<co`U2_!t;O_!t;; z_!t;$_!t;`_!t;s_!t-p_!t;^_!t;&@G&sF;bUO<!^gnD!_UB=z|X*7!_UCr!_UBw zz|X)?!_U9~x`yWtXhKMUfnkXN1H%>p1_sbXO@$x>Lx&&(!yG{dh692O44_+G1cVqE zbc7ffY@mg)h%f_#fiMGuhcE*Jj|c<90TBj<J0c7WZ$uav{)jLz@Q5-n$cQp9Scoz( zgorXQWQZ~_%n@Z^*dfZma7L7Y;f^Q+!xvEo1`aU>1_dz&hAUzW44{pcI^qlr4&n?9 zIpPcq9pVfOGsGDfwumz@91&+=xFXKL@I;(};fpu}gMb7BgMtJDLyiOk1BWC7gN`Hv zgN-Bu18Dz9iX;OAXg|jUNyss8HzXMtUPv-9<bZaDNHH*c096#y3=AUD3=AsL3=B5X z3=A)%85n*@GcfSTFfho-Ffi!IFfiE2Ffc^OFfe4uFfi1}FfdF2iODiB1jsTl6v#3# zw8%0roRDQ;xFO5Hz#_-MARz}jaE5`wMUH_XL5_i;M2>->MUH`Ch8zRK8jzSg14D^C z1H%k?28I>#3=DVV85nF77#IQ+7#I>17#Ktp85mR)85kTC85klI85lAY85kNA85pK0 zGBE5=WMB|cW?;}zW?*noW?=ZD%)nrv%D~{E%D_;f%D~W~%D}Kdm4P8dje#LUje(&? zje(&@je%i~8Uw=ubq0nl>I@7=K=)^AFfg=eFfi=UU|=|*!N71wgMr}<h@H*ApvJ(! z@b)wVL;E=fhNBl47_=`jFigD6z>s>4fkE&-1B3HJ28J__7#KpIFfg<~V_?|%f`P&5 z6$8WR*9;6NKQk~aVPIs?VPa(1!pz8E!^+5TgpHBGhl7#f3MV5&3^yag6COr}96m;d zFZ_%QHG+%`lOz}!{z@`3v`RBF+*M#?@K9o8xS-6)uu_we!O)12VT}nRgN_9wgR(8C zg}}h@dkO;sXdROBCkBSu>JYK3oQw=wpgQ*q1H;dA3=HSbGccH6WMG(kiGhLn3IoIS zYYYr)uQM<--)CUh`jCOa?lA+y@h1!nKc6u$Xuo7&*z$^j!S)RUgY_2%1~EoPhIvek z3~DTl4C`1K8O+!j8TN57GPrRuGMwXPWC-JBWVpx2$dD$$$nZ{(kpXl9VZIb2!*^*$ z27g6HhFwaG3{EPH4ANSR42z8zK^w{#*v%Lj=2<W@v|BPVOojSmD?cLxXuUxHM+Sxz zaYlyq@{A0h)fgGd^%)sN4H+4}T0{I6IhBC{wEhR?Uui3d_-{eb4pjyQZP1E31_p*; zE(UOWYAYx&GcYhX?||^<>q68YTLIx8fbyphY5%`h44^x!82pYiFr2%^z;Ndy14H9q z1_u5A3=9iI85t5}85v&7GBPBpGcqjIfY=4P=?}#E2)@vYfx-0!#O|lNA&tt#*$m)T zU&==Y21{{9h8B57hRbS<46h6r8BRg{4cbx)GJ``OL_*3{5DPX5_GcEvOf{(dCoV>C zy0~?Qfnm`Vh&@N4VFH^lo5lr6C&FhK7}lO+U}!$i!0`G414G~?28QjI85p{+F)$=v zXJ9bD&%luRkb&XTBL;@*Ckza0pD{4pf5E_z@rr@r<7)<n_n#RUPBAbt1Tir(++t>A zNMdDVc*VxZP{hH=@Qag?p^2N3fs2=sVG<uBgOmUx!y-XOh8+@&49ZfB46CIX8JHCr z8S<1E8NMkqGMv|BWC%B6WVmF)$gta#ks-)}k-^%Mk--z1PQEok{3!=b>sexq44`&0 zrx+tch#VusB7H`NCTN-foqGzBn=i)5@Jf!6!N-7+K?fS1Q=#c)4dlvChHz+}u{^`T zaQPeq!^-mv41yOK7|Jg(Fx<V&z_9Te14H|D28P)C3=I7b85krUGcYWC!oYC(83P0B zO9qC%R}2i|Zx|Rvzc4U-U|?jZU}9uoU}0qFU}a<wU}t2Q!NJI&z{SY0f}4@SfR~YB z2OlGYg8(DL2|-4NdlHNco>Ghq7o`~)G!+>crYJEo$fz(feAQ%Rs5N3__+i4x@X(Zz zp~8ZZA<>eNAs-qRk`fTV9~5U~;89>?NH=6;2(kgC3Q(QL2+k*)KQJ)psxdPBhNW{} zNIv;@1Ck~{+kipk$0s93hCnlj-dKJ}+IjPVfgw!|BIfWC67GMGLiA0OhM4mTv>A(m zfnh}pq#UaL%)k(>3DLvY3lR(dz`$@(6(R;Y!V1LN0lw>#fg%14M9s+)3=9&`m8r>4 zv%)?zFqlEjx^fDlPRy8*p&RN>@s|t?ptT80jxsP5oM2$sbd!OB=N1D)&20vTYquE~ z4DK*6blqWKxb&TYLHh>-L(2~ahPyu)7|eb$F!cXqV0b0M$goNV<QfKs^h*%)9gP_o z4noZb-S`O#o1k9|42FLo{swJd2kAJW2O=35f<ae$gZd!ggB}?eIHBff7&9`gfSMyy z3NgFl0|Ub+XgH{IK*I0zafrDYQIK*?<pTr5JXJ=99B6#~eGLhB<`WQgnb158%lDv7 z>L8bxK-~knsTAGKkD%$KPn?nAraU8qy&)rmJT#r`cmWB+yGI!qR-RyBcyp71!R;0U z!?xQD3<7r;7_#m#FdVtVz`*^3fg$Aw1H;}Q3=CpF85r_^GBBL@$-tm2%E<5-8itvZ zA^wE<0pwyKXnOm79mHc`c*q0w_YnvmbSEpwy)S+;Fc|!Xi0RK{0O#qn^9&3w*BKb5 znldtoT7rDZz|ap3Z)d2T%u*0L-{>(iz{*C@nZ%%cpDD)3utkoMfzN=E;T^P0SWwHr z0PatJVqlQ@%)oG8gOTBn1|tI~{j(TD@<1Lm-jZKK%6g6C3=Au7F)-}<$iNW&mw|!v zKLbORC?kWFEF;5FSw;pAbw-9RXjy-A8l)^gbeDnQ|2GDP4Zj!|j{Rm}IR1x$!RH^u zfBSPG?TX{485k1JF)+-(z`($IiGd;eG6RGCH3o*)_ZS#tA2Kj3d&Iz?|Ac`d@ficd z<QEJKGOrjImcC|SSp1oRp^kx(fsKigp^ur7L5!7=VICVJgBk}T!#Ykz1~YC(hJ8GY z3~qdk4CnY68Nvh^8FC~T8Lmq*GQ>+WGHh31WKdFKWLTxl$k43G$iQvH$k1lO$iQa7 z$nY1ME*3!3nLa3kF)%P3f#&}S#~^+XhSnYNL#T~W4$Vt`(7cqu3n}NG++kpdybJM{ zMGYkWKxLokM@aeCug1s#%3nFqJSIU#x_AIh(~V~t7~-!oFf21>WKc7Qr0J=mkaAp8 zjFF*4j*;P*J|n|2XnIXN49Wknb`G~C1A`s|14G4W28MrU7#O(DF)##NU|`sGk%2+x zG6Tb%D+~-Tt}-ypxyQhu`hbDq+ye%N@J9>`4<0ixWIknJ5PHVIF#9<JgUbsBhO;jj z7{XpNFx-E`z+m~AfkB^vkzqR{BZECNBg1hPMh1U2MuzL`j12Ldj114Y7#Z?;7#Y6v zGBVVI+Dd|q45AW@3>}h;3<A=O3<(O143`xd8KRXL86-6s8MYWQGJwizeG^D|z22OW zVHq@SB?&^p{r@LO{sV>lRBlKZM4x3~u)NB^&|u8SzyJ*&)*X<t@#zT$291*p3|`Q( z5wwd46c$rYGcahMV_?X=z`$_%A_IfvWd;V$YYYr8?lLg!yvM-c^niik^#cZml1B^- ze;+e2v^`~D(0|6ju;V!cL*fethF32c7>ZvrF#LJLz@Yh^f#KRO28K7k85rLFVPGix z$H3sjz{qfgk&z*WnUUcM3nN1g8zaLPc1DI8PDTb6ZbpV49!3TcK1PN){EQ4Lf{YAi z5{wK>B^eoXr5PC-6&M*lC^9lsC^Ir#HDqK6Fkxi4V9v;J92yq-(0tTzhJiuqJOjgr z^9&3T7a17#U1DHRxx&Ek;~E3Qx$6uJOYSo;TzkmC5dWBg;l&dM2C3%^3_dRz7_Poz zV2FFez!38V6kLo9`<WOS+*ueI&a*NygtId;+~;6qNatc?c+btqP|nN9@Sl&7p<RHH zfnSJ`K~<8GVS*GRgM<ttLxCbA!)+x-hGZ2+1{*C#h9gFd4ECms3>s#P4Erq@8CF;_ zGHipkI}-8KCq2+|<3F_B{dEQ;{rW)Lr7O_Nk%b2!^04}jPY6=>W6LLOc-nf$p=}n= zPYetPp>4w|Xj{GHI0M6%TMP{UJ~A*Y|I5G-`k#T}m?$Gdn=B*vp642MMur2>^84XD zi2a`D85q>BGce?vGBUikfaKHj<&e4t)OPs>ZND(1)o=Q;kapKoTSf*UJ4Oa;JBVJ; zNi3jx4phg$>X-R^5Vh!SG@&8b7Uk!`oqxM*A!FR^#~B#XZZR<Q-eO=d`pdxZ<{txt zvnV4&swgAF2T?`_W?4oCRar)c4YG_3)^d<=lY_=9s4NDR!=SRF^97_1XWPTTV0Dav zA@vvo!^UF_40nz(Fw8&Bz;Nai1H<=IAe9UZ0(i>S7HC?8wP~MDg2eq7(7FBcj0{T+ z7#Uij{e?9$kakNXv|LsYg79JKpbFY9nFMVI?tt>)?G$lH_+V?RgAO+W`F07ket8FN zlN~t9z|eDof#Lj31_sSr3=A`GGcbI<&A{M$hk;@F9R`MX-x(O(e=smC_`$&N^9KV% z&`$=2)jt^+*hCo_jzQZ;yEzycR2Uc-luk1+EI-S@Aaj9%q3I$6!;4D{46Rog7+mi$ zFr2&3z)=2xfq~%>14HLy1_q(03=F%UGBCJ2XJB~yoPnY2B?H6%R}2gtZx|SE{%2rF zWMpJ`$;8M|$im3*la-O7k)4r&larBQA{QfrBo8CQLS9A&O@2m(jRK4eA(D&?yQCNy z<|{HXuqrb$oH1r(@PU@=53(S2t=&fk24QhVhB$dfh8=2*3`YzY8J0l9T@>0*ehzIX zH*-Vkj#XzE82q69+HcT)hTLrih6(>6@h&+TcU<m=wgWVv?SLE-(o>%ZBpyA*7#XI> zF*3Z;XJj}9O%t!s+P2b43=E((9-zJrsO|#wZ$S0eq>~H`uTC;B*q&lws6NHOP;rxi zVf|eO2HkrM3``#w7_z@HFl_tAz%ch00|V!828Q_G3=AuNGcY9lVPIJKhk=3n9|Obb ze+&%u{}~vz{byjfCdSC1D9^}H13EWRmyw~_fRP~?8h*V(knn2w#=vm#FC=WP^e`}h z)?U)m9ms9~9S#Oc-=H=+$OYZdKA-nV28Ii;J|91%9)OMCL_o{N(;pZZT-6vEgrRvO zk%N&zgMon|`ZNQ>%d-p&b{7~JmRw|D;JVDfaQrF*L;XDl295^|3>zOXFjzfeU^x7k zfx+h~1H;#+3=DP885q=GFfeR*$-rRwnt|ca8wLg;21bTijEoFQ%!~}HSQr_M*ccgh zu`@C_aWXQT;$mb7;$dXC#mmT$#Lvj^N`R5!i#Q`gnIt2_XDLPodj&>@gNlp{cFK$l zlMNXe_)HiX`pg*_T5UkSWnhRy8|Qf=4XHms`5e}N3=)QvBe1cd8EEyVEn2w)x}*iv zw`mb$WH>L!$e?S$$iNGY>+?{(u<;#>JrMgqWh<;a)q&=pQ)d_$+MxO8c?knJOhIi* z^!6k<ZAogiBSCFQQ2P<N?YJ45o{{^DipmTOpgmon^i%*%Q^;k(D(G0)n==dy`=NdY zg%M~T6;$?s#@#^W4`}QSR0e^@-$3OMXbcWCo(5{WfXXD$cpRu)f{n@b?u4XSke#4( zeS9LMUJ|;?z|ek|f#Lc$1_th53=E~e7#JFUGcYv%VPH^z_5pVYK=LJWdu0u@Edd*w zNrSeDL1o=8XnB_fb-xd^zBN6|z#x2;fg#G6k>M7!->MI7UxWI$puR20ZA+kOaXWO( z(V7EdzsxBHhPBYT(j1yEL1PlI^7cjv19&VMl;1$%ho0v^;W^myUDXOmx(D@-K>Z<* z|K$ZCGwb!A7#P-kVqm!XiGks}IwOOM1|x$nwC#6G5Rw;RV}g^Q?MG6^dQX)wFo5Rc zLE|ZYC&(XD0gYLL##PYAEyY$s{3dXgf#DrAEd)$~q(gq_*iz&W>{D!jmR+#%hRb;B z*{?E?b~Ab#`<*l-{$OL0-24!Avp+B}h^jF%JcjlgA2&h55HyBd0gd}@W{|cBXsi-6 zP6ryV1dY{!<_lnR1nq(h3?U2*44`ov(3}ux>;^P11nMh*#;QQ$IG{Nq&{z&=o(MFa z1DY!Wjp=~qi$MJe(0CSTd<Qgl1RCQ3%^!irc|dbWps}7%=y(rkE(tW|1Da0)jr)M+ zlt5!Ypm`<G_z!4q2{Z--nqLBq1A*q4Kx09mc_z?!5NNImG$sU^Zvu@Af##e*V?&^M zC(!s1XzmF#Mg*FF0*w=a=Ab}hMWA^o(0CDOE($be1e%WmjT?dHq(Eawpm{0K_z`Gs z3N(fUnx6uVBZ20qKx0Xuc`DF&5@@apG^PZauLAX<Kx25I@g>mQ6{tT28qWibHNobw zj@3cp1T+o-8b1K#*>})30DAltLeuw9nzx8*2aO{@+TnJm85ltIFKBKC)FwXxZI|mn z+vby??eia(Aayio{sz=mUj}WjCqdinuc7VsDbTjNEVTW;4BCd*hqmKyK-=<((Dppn z3rL%OGPGSU^BU5&UkYvCe}%U3YoYCYR%S?BzZcrx7iELA`R790{i@Km|5|AK-xS&h z*bD6kxI+5^XQBOp6lkB|8nj=q9@;lhg!T{KLi-50(0+m?G##L~1v$-$uWy~8<qK>+ za2cNZGq@d6=Yi%GKz%UK*gL4N0GeX}^~XT-44^(4Xs!X&F9Xdtfcj>jIR{Yx3^eZm z>Z5_?9zgvx(EJ0auLhcf0QJ{E^AMmu8)z;9)NcdLM}Ycnpg9Rp{|z)R0qVnn#;-x` zJkT5ks6Pi9%LcXiK;zk<b{}X=8`ky<fwqf~+xdZ5>iC<JA$0|;+ykw-0<~84K^YFT zhN_f-!49;Z>NEobsE$D&R|C~Kps_X3_%=D?YoIwD&>RtHY#cP!1{xm+jkkfu$U$Rn zpmB20xEpA!oSI{Apm`+FycB2*4m39dn&$zH#ewE%K=VDwV{+<P#)aL{>exxpel;jB zgYqvZ?}G9zD9?iODJYME@+T;7g7PIOPlECzC@+HYAt(=m@*gPgf$|+F&w=tAD6fI? z87Pl|@)sy?f$|k7Pl56iC@+EX5hxFV@((EQfbtC}&%p8vGZAeaKWN*Al(8|;iOQg~ z0viV}g!UysZBtmg)Cii-VCm^|KV%LC-`EfGxDO~9dO+7lg6snELF*ntG>8vs#evr8 z!PJ1(0)Q|!H6T5pF}IT74(@{09o(muOcHWofYjkB3=9kpp>8dL&T-s@@^hhlc_Bz% znQa0xi2=TD6SNkQjgf%?w*M7mKgeCo46F<+4BYTFlptLoH-p>&ax<vk#>N0Cvp`Fx zK>P4P!=xZNkd>f)(4eJ6p!Or^26Nc@P0+pzkQ&ff0*D5!;RLNsg{|KNt@VJd;nZbd zU;wS%gst1OW`N{pM+OE4kl(!-7#MsR7#RGZYc>NwYbBsz63)QD09v~VTC17Nz`y_s zqcjEvhHU6s&3pz1h9U+AhGGT=hH~hdNzhu&Dh37y(0a`}=z7go1_p+9=sL|F1_p*+ z1_p+HsQQTv3=C61<qMQQ9aQEpFfhzyU|^WTz`y`nyEzXk2U^1kIu{MJj&mtg4CMdi zp!sH`b)BF!otu%?bZ%u}V1TXb1g+=X%fP^}pMinl00RR9X!;5?>~oHRf#CuJ0|TfD zeT{*E;U)tE!z~5|hI>$Z9x^a6JYis9c*elM@REUn;WYyT!yBj^Xvx3_1_p-D3=9mQ zVPMdKNIw}E7(i3R;Nd4m1_tQ#Kf~3jk7cry-taAHdcD#7mBzW^tn_^?Ckn5%2TF4D zoqM`oTZUWpt>PQL8z-%Na{eiHvlnf6qagjJzecb0N0k*@PtMsNy>rs%R$h$y&-<KN zQo#8^VARCTQ)(KoCzpG4=)L;0ezMH!DwmS8*Jl>@Fl_&onKMx*y13`gr#u;ptQpH% zmsLhGw4T0wy68~O>)k?4+;&rUNz8s&$iFE*$wd0>WflRRvMu*4(_aQ0{Px!=>Q_b6 zn+luX8b16RPCf~|=eT=rs`2bCrvD4R+v;!%1!kRAPkDIG>9Xg!z3<D<O}aB>!W_ec z+)O%qM0`J=3ceBLAg^kf@~21ZrN{j3I->S`x2N7wh_?O7V#{c^`Ofp+-g(~hr5=gf zgVua%H)J1h`P+2HG5*@Q;130FqW@p~JGW^43GV||CxruY--Q2(d$fI-(8<kvGOaU% zLc(@tl-)_}_>gH-5y`+@v$N-!&Af?WB6@-X_PfO@Ih(7PzG{i+#mG3b@10lEUM$qK zw)*OCt+gJqSJ&UuT5tc&e8Zks1<of|F$!F^<urXKzIA5ko!Cj7FJpUxb}r_q%vct% z>G};FgDcG?_uQ_0&=k^N!*Ox?6QA@@&Xc=)KAdbn-{5)bL&hW3H1#Zv6)B&0oOqDM zee2Hmm~v~6j8@Ko>9^)T2oekwIc}46Aku4Zjp=WuX`zAzT2D>2HYZ>6uc?fg`1nM3 zwV=mBw^!euc$(}L-TFZ7{o0@<-0Tv&^+cRSm!Hy^XY_u~|FvqG7kA%IYU{Nt*tn3n z<$)?g=US5{!+`E*SEbh2J-zw<%l%TVr_X}A&xHS&f2XZg+Hk4Ir(dyaH9>1i)g^L& zPAC@se^K8mOZ9QrhS;7NMzjCSn_#!*${as0R|hT`t(aXwa^K}X1V@=oKR@Zk2haJF zKV6V6H4(GVd{OdopU0-j2WQ-H48Jh#+%d0?o9DhUg`P}kPt~lpS@_D^XoofPrg^g; zhOkcBu|9h5)YG308alWQwg-mHkh!$+rLLt_*>jz9#jE}=xi_gXX3d19ty5;iYAl(( z!K7GsQdP3T)Ea)b6|Iji{pjUva@>&4bV5pQJ&VKRuNh3w1m5tm%cSz}nsPb)+QYi4 z1<OzWoObWO*6cqGUV9f=X!gvlEDVzVG*NfO#9jRxZ#R`L4*e>+_YQa9OxCKilWjJg zd|hqwVp%qSvcx;d;{sw27Yf_I%Bx_|FPS(y&Ol*dYwU|)!I~8xVxKHs*XRCAPVR}* z>vw4~2LxUz#n)UrVljW&6^^-Y{EOFl=7*I}?(S|72-r4z#iac&84um;Ir3CqbLpm* zn!i==j^<@2Jz47exA1WKs`V@4oMir7I^g198Q9GctS`Bs_e;f|)UaOh6?e6^J(%eA z`sRwI0rT7cSH(Wi`u0#JVcGg=TvtCt2?!|n&V26Rau~EWb`}={!&)u|h67v-441hW z7@l!4F#P0VVBq0qV36l#U@+olU~uJTU`XR;V5sC~VCdmyV3^O%z_5v%f#E1O1H%n& z28P$%3=IE3>UkI#jCdFrTzME6B6t`WvUwO7>UbC!Ch{;aEa72b*v`YiaEgb4;VusY z1L$I0W?lvcF<u4+O<o2D8(szme_jTLBwhxFQeFmz4qgU^*}M!4>v$O$4)QWET;XM4 zc+Shf@Qas$ftQbgL4l8f!I+PM!HtiBA(D@QA%~BFp`MR{VG<t$!%{v5h8=ti45#@R z81C^gFnr`=U|`{AU=ZhLV9?@cV6f$9U<lx6U`Xa?U?}5fVCdv$V3@<tz_6a5f#DE8 z1H)B*28I{>3=F^d85qh17#O+)7#QXXFfeQvU|={Uz`$@<fPvwI00RTFAOnM#AOk~` zAOk}#=>9lC28PLk3=GQz85nj7GBBKhuF+)|VqlOGVqnk}Vqmx|1Uhw+f#IhR0|SpR z1B1LU0|V%w&O~7bh7w^0hIU~FhFQW43~PlM7!C+CFqn!kFnEYCFhq+mFyx6aFf@uV zFia6)U|24~z_3e%f#IwO1H%Im28Pcfpg9)?1}{+thFDPs@FgqFq6`evL>U-XiZU?l z5oKUFFUr91NR)x$D|CIYrWgZ*jTi%izZe5Uffxfrvls)zG%*H-m0}DGd&C$R&WkZH zJOYV{Gcc?aXJ7!`qn;$ez)&i|z|bMVz%W~afnl8l1H(ZH28JsV3=GdD7#My@Ffi~+ zGBD^#GB7wwGB89-GBCW6WMKF&$-p2f#lWB=#lVmx#lTQ1#lX-Z#lSFIih*IP6a&Kv zDF%kyQVb05q!<_&p=*HEr5PBkq!}1|r5PANhy4~yGcdGCGce4QW?%r_I=Nq(f#H%g z1H)738ewi31_n791_nbJ28JLR28L7_28Ie528M1K28MYu3=A7(7#KhsQLoD|Fuams zU;u3*SCwU8u#jb7@Rns@h?8YtD1@#bo-WJ4uu7JJ;g2i>1HT*tgOVHrgQ*+?gNGag zL$n+NL!KN1L!%r6!xT9NhUIb$47=nQ7(kn>AILE<e3oNiV3TKH0A0+ZBhSEKFVDab zB+tN*D$l@BA<w|jEziI(Po9BcqdWt{5qSoN>+%c?ujCmR{>n2j2q-WxfUau*ZCngj zU|`5nU|^_KU|^V_z`(Frfq`M00t3TI1qOyY3JeT?6&M%<6d4$l6&V=J6d4#i6&V;} z6d4%u6&V<s6d4$%Dl#yvP-I}(t;oP|PLY8Dw0Z1{A_D`v5(9&j5(9&-5(9&S5(7i9 z5(7h;5(7h}5(7hz5(C3gc?R%WP>}n@7#O^*7#PGD7?Oj)ltna{^2rBNKWe}fsFk@x z64Fu?kzrr}?Fs@dT0R010$no#6_R6z2<_&EYut1fB6MLXT!`@lMCkG)xLH^4L4=+x zgR43UHLHvVE@YDnQT5ITuJJ3>T|W@+GX4Tt%wg&b)_AKAOzBSnQy{<0%77TdBmtSh zV_;zDV1)>6<Akev4mur|fq@~PkpVov32M$if~aEN2v_w_8X}Zr33pQB7l@F>Ot`Aw zP>qrZjW40oQCWs?jr<}Ihu<{?Yqa+TQ#Z4~6v*MA^EN@v{Zu<fP@I8;&O(jZI~VTC z{7(@38K8^h7#J8p?N5-#6h^pNTlgTV_DREqK)WwMs-*bgLNB0^(1?hHj5!dET3K+1 z9|Bzf!@$6BE*vg2krSdSmLKk}O9GI=(~Gm<s*0e|o`s0^8&4n_oi@W&F>pdOI?sd) z{RN$a%)r1P<pCMgV_;z5=74BigK(+=G;w@4hijC(4^eexIow@U&=k66DO|`6DwKyv zv~f@msUkcSEDSNL#}sb79aI&lLIQQLKz)d{5LKtj;7(0Rgb2-Xh6^2ohQxM6NGy?n zsJdeYS9N0}MCeo%+{Riqh|m`<c%->P9l?)?#~;wdT+ImA7$yeMSZfB?xCrW@*9Z^E zzlW%r(+zh7=u|^cGC79GE9KCBtR6z6vK~ZZqa)l#MjnWeyae1vX=tQfL`2#xXkPiT z0j{bK8aNGzzyYnM1397r5kudhk;aZtbr|YxKSa8J2{kJSkpNN!AnuYfhC8)o2}I~! z4qPY^YJ4}sMp39)vIrYND|kTenmijGURR-Iiv}0mtbNZR#{2Gq`|&<MWSQ(MNPb*p z2$m@_0aL4Oz|?m)Ftx@5Ohx*DDbUr2VhjwSkzn3?2<4jw=50s^Q=t2{#26Sr*HD2f z{kdSlMf1QEs1RX?CYV`#a2LwWg}5*hk;_3HY|uahs8cJ(z;K%ZuJ|V-L~%VU+{i=F ztQUtUmlfAQR4vGb2hAF2;<ZH77k<!0@>B?JmXs7^M8nDgEc6CK-SY$UCisJ?h;T3k zx&};)fk7)5%mZD61<i#~ED+0gbAV+)zILpF2#F#}EsJD`&~NCPUj_z-KxhVt=!d&H zwF9E+T@qYqH?%Z837vok_45@VwaZ+2u#G1n_3R!<1$zNf!GfG2&J8hbp#WGNNN6>* z)CD!Mq3-_#b-yYi(}5bDAXzhGu*O4>r1B9$DM0Fw00>nNp#&jWy&qCB%6fzKZGt4D zhY+e5Qt3Q|1gB&KScxp83i5$a)ewp|8!Ts84W_J`z|>|4^=uZH2lC5lXzG_mluxsv zIq4*#z<mr&LHURjWDCt)c8JWi&k!;V|49yPygj7NA_xgmRY;ItL9|)ypkcNE5$9^q z>Ux6(Jn`O~4GI5$CU7A~sGD06fj##SL=|5(T-AGMGeXl96449{47`F2450D08G2v` z@<L)}2ZZW_#7r0@A@D*nF~1jB<$Oq7<UxEi8xri#62NlFkW4I`3FiGO0aMJiU<wq% zv!FHR=S^@SBWQWN0O2PdXlnlz3Qx42&_G|#0@s)cjhbnQLhkz_h|i_6;Tm5-vu!3K z+ir%&)<Q&V8CF0vvIW33?uXhKf{11ns74Kh#tb1yeh-%gyK5e#DAa-!ehVPsb_!C? zHKc--EP(_O=<sn+jsT66L5sA0et3K>hgvR)u)G7BLT)2ch~{I6tE~`CwP0wi`>X=) zkwR!VEkuOVU+CDb)?7#$U|?W~$bp!39uW-@(4c$E1#fIjf||7tVOCQIq$S9n4EEmR zGBEYO0!)G8{3+D33IVv2B%%AW#8TlxXZ0b*9C89{?C%Ft+Yv2cP<8{=R;v*SU84}< z<_2H5G3PTOLI+&oLYtxWwjQXH4{{I#!zJiCayLW{;enRr?vNS>qz-gsC}`CAh9cN4 zJ&>%C04dUiEWv_|kSH#O<Ovo?0ly7Gg$09^)IrLpd`L#oj0FoiLPG0l3YZrTNfYyO zz`OuRjbK{{=E;_Wse_OJwX6j5?pA@R*N~iby%Ed<xjDTO;{Sb!tg{uGa2OB)7Yi-F zL5C=bF)&Pmq}m3E2iHRi;K#0DL#IGIm=5uvAf(8>7yy<_hIr{(JeZdO@zO_#mn<Qv zeFns5t0Cp^t75Q97l@b6LcEj!@zP6(m(n0*G{`U0q1mk)k=>R+E1+Yb0S}NG28J4F zyU7Dl$Ipev_<KZ4Z9g>O-bN%`(4aRcK}8}OTwAgrp_k(U&xw4{Jf?!kW4EDZeMFe` zLl}~JPeB@$I=*22#}EyYYG^g-hH%pM8b}fi4Fm_uD}=|T1;N@G)<6>85lFnWK@y$? zB;jqe2J3q14yIN^qDKpo@a{k;(CyM<3=B&k>2EnCvd%|=HP}Pq<p?Cjl|fS6<2<mO zR2`W5i%3<VwNRj-3fc#8GH7+|O9(S03GCL4GB5>-l8?|_8R8EYy50%t$8$l_#$O2a z43Z3PLXrU!B>ulbD3C#ypyf{-qUa8XCW#P4l2C#sZ)QZf$ixnD8)%qNn1P`l(YII$ z)jtiPzilxj&O!IFLWc%G+ZRCIeU0eE&4RYOosA(zgC>fYAR70wgM$m?;udI|EPOs( zXbm(iDkDlCHmD<n5RSM9ZDi*m8rk*G0R&%2S^^oL2<--Sn!!U>a~;GH>nh+vVNgeG zcY!-%Ya2wBS_ItnJ<#%g0%CkZ40Qb}Xr{{<Zq^cLef<wnUvGrwH_%ccXn65M`(m+> z)DLoMfFQ)idK0*fe}o`;<R+xFxeX~;?n4qHNY8X=rN_$(uWy{8!!MsF!Tr(=RrLbV z5_l#Du`I_DZdt_*h>$yUbrS;v!(M1h=`*4nl*@*wV)TalI0YIx@rcN=g{H%ch-P83 z9;6+$*b(fma>%&Nnu%bZ<zz4g^3oG%*J2T(YoP#j{{j}cFB_nCmLlx5fey^5BL-%o zp+(3wZn$G(pjmCUA6#e;)T}iKv!04VW}V;2fZY`fX<6@qP;(%~$yZ1@k_f4?Bp`)^ zHzaO!AjQHrNM!@^)(dEa_qoFDjfK{qAE8@T7#J8nLVL%2h@$f%G&dyk!ZqH33W3g~ z0IkhuU|<l3mbv-}jmM$=m`f>ejlR%gxDwGcFM)>bVMN-9g^v7zE=~sZ2pJd{en7`n z8dt$%U=_4|%!g<n|A%If{fG<_2kkk5?r?>grPB^cK|PW1q*n&@5a_@TsE4$nNe^^5 zKeW*o2OU>QMReb?pvHShfa3`i(6{6u#%Du%5g?&O(6&=SIy@v;px(|zc>6^;MC0x` zaCgbqL4@8R`jDN_Al!_o$?iZkenAWhctKsi0FiO7L(8jVM0w>l4`TdtM5Wg%3K5cn zBsGxhMT{YZKpCW`ITg|$S_$b7ffRH@OVvk+Qgu7D5aQen4;SAP5R=uL;DL|<ZTSTt z(&QazUJzUk*Qf)H`!9$gl?l-HsRXo91ZoUJhh-fgy-y8DW7G=K81;vC#268tJp+yQ z2t+~84ju5+HiSpQHt1MI2SOw0P$p1qBa3K<I75r@xh`<;bwLXuNknD%3tAw6PK$x2 zs<Y4teTIn8mr$WU2qAIkIKjkjc(@#gHmn2@Lm39p&@)DqBm&ULnTv=VUuY4k<qh{^ z0n}Y;h_;Rw)GSYgS^dz&p@pc-jzLpZ1R_;^hlc88K6qYDdjN_1Ppjd9V-9WgZVZ46 zfzlEPgYH^qWMBjZFo+AspkuZ`9MF9z7b93fD?&hA2H0hD4?t_^86eA-p*0>@9!`MP zt}rk#oMB^NK-O;n&GHwZYj8k2{VqnZV%X0BT5k_MI!uv)32uJ~RDS?e9<-bVoBJD} z^7Wjk_NPGggYKdRxpfaCs(cSr{s3st3uqY!n*0{1{08W`$p4tZ`Z3%OyUlz96IdSZ z{yR|pu*>^$(9Gumt<wQr!Ul32C}69C7#J%A7zKFPIVM1-FF;Ft40`{7R=0pkVTejc zK7lqSXI?g^X3z>F@H7W#3D1j35OttsLSTh3bzlzUC^t|V*f0~K4iq0?DVRFnX7(Po zUe-RAez>`yr8f+-A?iWlkD?xGKj?@!(5`)p6%cixa6(asW-iE2AbG~B03WcA*=K`R zKncM74O&$N3c3|N5c5Fk5~QBv^LmH?4)=oe#eft-!vT~YL0k^`4XFA8Q2hyVKWORE z323;0j<5sk<3`ix+|1I)%)kJ$2jpLgSrB7E=?<*^HJba->;dTmEd@$g4ABQlk6?Yb z(e$B(7f7E8BLl;WB@lgYpec~!G+}+9G`C<CL?0-9g6-Q)Sl<%R74B;x`aouY^{vOR zZ@Lnw+}jH(of&`g@iH(ng3B6EjjZpJnN*ZmRH^ThT9%rVUyxd)@0_2To0ym4lbM$q zlAoVbtRL*+U99h$nCu@Mp;w%etzTMPq@S6WoKu>Ts-J0WVa7nIA;p!&`tc=|1*ydd zquh!Tb5qOni?WOL11d{0^7Hi4U?TcqsYS(^`FX|q#(EZTmlS|i8S7b4!wmgoh;azB z$O|7z_3IZ`B83SaH-O?KDKk%BPY)g-$=cfbWrjq#0Hix7Gf6)=CowNw-_TIcK+hOv z4p9c+OCsnoi^muEjLA*R$;nR!9i;#<P%i^?TvU8<ab{I&e2HEL=<uY1%7XkN5Sy8S zAwMZAH5r}F!oZN5T9T2Uf-IYoTAW;jED(=uW_)o;N@l)Z257??+-5cghTQy=(wtOe zZ3UIZ`9&ppsU_t_*?P&K^_UFBsU=yt1rW`d`Ng0Evx-YnQc~0OGC+r##K-64Cnx5l zLd1(Q^U^`A+|=CsqDl}8lqcd#iV`zRpjtsn;>$8q%R#d7@x>(|0T4Sgzc{Tt1;olN zElI5aG2%1xN{o$QL6ei23pFJ^KCd(<r=X+=q^K-4xg;OVO07svEhx#%&jSe;m!v@W zAWnRIaY0UINqkaiT3RYtZDvVoQ6f}dGQ>k5g~<r_Kv)ou!`bW%3?N5Yz}y7VnweJu z(h3qcG=oWicxEPWUTJ1t2}Bbo14BHB2UQB=LcIy&LbY--Fo5DN50nU4AyyZZ6rq@k z%+Jg#$xW;POT!F8;)C3plbHl^YjH_RPG%CsZ}E_1sh0sdW2`hUv$!M$B9WU|lA)J@ zqMV(90c1*MK2#K*s**wR4AGVhW`h*OmuKdcfL+7Hz>r*y5C<tPhNzA&PcA7+%qs>f z134O^42=s>3z34b<8zaWOA<@q`6jtMIU^Aqvn83isSq__Ayg(P{*rU@le57VfSd(V z4t6Yv0TTt~g5<=a6upcL25tt1JV<ISE-6Y)%uOmy1F6r4@IXu(a2$blFfb(Mq~{l9 zmSp6D#0x5OGSgC%E0c3T4g$4%Sa=vXp<P-A2IgN3jI4rO>8zX_BCPCeHmnTHP4#-L z{A|pPj5e&iY@b+IScTY_PcfCS@UXHo@2s_9HDu#ZU}e{1Wo6T6VPWNDzQ|O<X2WL2 z#=NK|f`x~bk&U^FQIC~@S^F9*2NyFhhYc$`8<VCGi!>YaN5(W39##qFDRoa+MVY-y zSQ*%u-`7R3^0F~cW(29TVHIY}1&KbZYhqPrp2cXx%51~@tS*g}i;a0UBZmSjCz}_D zJ-_}0D<|^{h9(vk<}FM%AP2DUFdwgNV&!JDVdd0gkp}r;2X`8)7@HR>rx%M5$dcQP zAPG+9)pdGbS$J55nYWazLAMR$CpP9iOnPiyY-V6jzpZUz^I{cX(+4TtQpX|0%E`uj zj?soylx-I)ryi>~n?5T$TM4Tu8?!5i5GyO&JQitIb~fhuOdLXNPgr<Z_1Kt~)a_zp zURhVd%FKM7@e?aMTQr*&I0U6x^_aIZpI|j*^8y788}qpujtG!Ni|Qg+q*-m*m?yB> zfMl4@*Lblqvw1NutV?5&X60dHZs+;Ls>j?}>BVZw1`2rzHs%X8O(4As>LOUc!K7xx z0<z#03&?OO=1VmZtgLKa%=7B>Shd-hA2T+waxvelYhq<*Ud$N5s&fUTi}^?$To=@2 zDK_RyHBGFnY&LAhtm@1a*FY{~-pFjjs>kNVY6>!3f{pon4F|}DV9jjI8=2Ffo)TkY zz6EjDG;}}RhWcqL#6fQuOIW#>uhx07vNNw?j9^v00=8%=nnky3N?4iMY*^jcj9G=* zyjU5SC)9D+KqBrMGdM9YS2Tg+PntQuiB$-c1Z-Fp*qEdBSXsSU#o3;)vX-#&uo<v; zGcT_9Vv%O$Wd6?(fvhl%RooloVOD)MW_3L_<_$GXtm16UE17M;qAqOdtenisUdUSX zAZByup%~7_ys0(<<~BW0LWQ}FhgF>UKy4E%JKH>n{0^pTU`K-_PC_J@Z`SPsIggF` zEVB(3%OX(h0%bqu<@KP1qtARBlwEk3qrI?tl6iBD7sO02R!$q{%{3(`JXASMUJ0uZ zR3E0C4P0&w!c64Q_d<0vmeAM32>l4u(AUQm`lx0@0$&;wi5HmlSaF61vg>xCxDH|h z4=7g|USnnE@@4_0xBHA7Yd}epi}^njlLjNJ9-9p)8+fq_voW{S+JH(a7DySusK@q% z`E1QDP?_<J$BV^_)tPx?DJX{cnU8VVu<|gks`p|QW4^}V1=7Wq2`Z_WZy*XPR#WD+ z6(>MBw9bp|$u15B7B5x_Hs+VLPgn)gK}m!84POZx^Y{ETP>I(ium<EnHs){nO{`38 z%<~!Nu`xfa<IrQC&*;Vcux<kLd`3N1ZZ?j!tek8%tg>v@tW0b+Ac1tS0JjY*rxz<X zsK|tpvTUBL;%r{5Og799>q<by38+YlU}OGJRRZ-C8}qE<2o^6k<{3;)EYi$d897k0 z5;R|+#thiy7<mqyIZv>%mauq%T>q`M1nl}Jtg>KtGtFb=24y_939Q@`SUKmha?eAM zvTSo%xtWxNSvlDzu*$Oavof(wfH?Of^8{8~HZNAa5>``?$(n4;y|pE*0?ZBdpu)<O z`7?6~D<AVuu6eASY-!Bj^T8D$j-X_+VuZMcMVgh5jrk4VHC6+CR#xV@#a^u9Z1Y%I zy}$*F7ppk)m)a6g=rTX7+XZ$$Hygxx7~$^4iXQGDC9rS@#m;<IPPTa%o(B07)6<}6 z2F1(*rZsHL4{D#VF)swM?t@s1z%jHM5<?}dobXbylvSLq1Ucn{q8e5zqAP5|r4Upm zAm^oP$O^HRv(Ur=sy9JV!@zvK2Gq1*UdHr^jrmqBhXN>};41xyPEsIuFki0$Cs;^9 zitZ&8qwx71r$ThUqbS7ZcTli{GA+pKpjOg(9*#6tTQ25<6&#=n7F4pZdayAcWIw?w z!aTnkR8EvIPpC*^)nH@(!ZeT7gw2b&r*<AF`+sH!CE*fQWi|sAe^z(qYqg*R&cnQl z$%aLaRgC#i6{sO&!+f$fjYWu6kd1i~UlS`Yn+=;j8}r-32v#RH=Ba#ZSiD)em|qk( zvB<H?Fxz}$k!EFOp2Y=jLoq)EmrVT3bLv2RQRZ_D5v+nB16YJvIhoIkaoDhVc`^6J zc(KTVO6=uKpk|H@tM~*^#^7XQ*4JaRVetkvUn)RtF-GPNE{+H`=2gW{Smam**qFC7 zfn3bbyo=R~MV6I;xua?VD=SwSD>vH-R@Nrw);f*|=HHAqpz?TLJ;yv&FRlr!(QLa| zW3GXMkd0aQ1f*O(#SAHzOW@`5&Kg*`Y|F-coLLXjb^$e%gxQ$iRf8IBe9YbapaAqj z6sO=s2`WxcuyTVM#h}n{0%zAIRxLK>GYm~E(yXS;hnc~Rs5&n;4lfRcUGQT1TP=qI ztAH&i5i{RMEvG?-HbKg{HH_ETn6K1v*f6gF2d@De^8>zX;6epd?}0N1s8nHNzFISZ z#fw#wjrlC24XY8G7pt%ys}|dCR!ue=RwFM~;WSn)wq_X5(1z90hE=$Pd1D<Y67@g@ zH>d_;VxCju1+oxS@H4MvjKEX$GqHJr%Ab>9B}{DAAZ;KoLkvSHRwdY&m)4X(d~3>l z3rCp>@^%EM<m?vsgj{lhnoWqJv$qaXbe^c=5MtiJsK<Pw4pjCt?_>l=A~*st>nW&X zcOx8oq7LL(a4XsiQA<m(G0%j#)Ry@fa|t9Zc!8XSQ42I7x%dRKi+6#NG^h~?D(f5T zKsA;PC>FgyvB-P{;^4K6dSKU}7w}%Jpo$ghU|gXK>J)%$dw96og2NTk>L$&#Pmo>P z3w14K@TP%UA*2K^s9*Jrkwbxvc~%{Wd=6@MN^vNIdSJ|-xk^~Y*dkatBiIbl8#e1% z^_W*xG=UltP0SNm!Tks?P?>hS22=#tGJ~4^kPr}OV}4s*!YUjIs&kpU`9bBl4I+>3 zf@J+~`D;Lph6YA2Hs*$U4k1W}y~fJP*2Jm;Z|Fd(;3jbE22R?rayGF_vw5;Iv4P5d zem3U2+<L5f%$qABSb3Pgvz5SGXyBx~j@b)2A#gN7!<Lnwc@t*@SRbfmhoTQl0D#&} zO`zW41l9@Qz7i;jGT*ByVO3(YVdVuC{>H4jY$dE#X{_QPh0PFN1PU*W)v|=uF@lwW zxx223Rh;=NBPjSd*_dxI&SMo~L$ByS`3%wb0r{5BwLGXG!|0NryK)V3!+``xda*Jx z@2HPpWB!HIbbti|qR)eF9ZFq|&pMn6$*%oTOhj%bknKizbpa0L5=alm3shrXVgU78 z*twV=GI2~`V?JB+1k_G^#?!>g&s-h>9V&q*RB$o^jg_$SGgmc1WtkTjm#{ITX#tIP z+%HRGwPn7-$dLvsOgY(@FS3AZ>iK1Qpkm@2J1FCpfSMO<%<HQ_!x#)~%*}NXtjcW6 z7uaoBMc6<EfGxPcp}@vGnF*93K<x|_Hs;yPUaX?F;I@VVtJHOHjhaxxD#ZM%3|xPK zA{XQ^FXrcE*t-0mkW&<-7VH974*bmD*`Ba5Z>#{-{E!YSXb1`3G6szo;EW_tw1aGh z=mYVPo4*_iD3&6{#BB!97z#TV^9?4BU6?T;&*sG{1~LsxWQc(xgOkk$ixlp7f*Z)Z zxL6MqOej%46ygumghwhmyjYo-r$FQHEnVYJ8kCbxb6jJ!;^IhWRb%r4HN2eWf%;Om zY|KY$^jJ;VY*>BRm=7|88|?L<CL^T5ZUSzwvmv$C*_eAPN?19WKeKzWDzjw}+h|_{ zZnT5C|E$cdRS|5=FUpzp7(tnNHb)b<qMgeIYF=|PKdJO$W%XsQY+~iSi6Zg15|puc znPCcP%?CL|$QL~P_^`Z$MF`T@xCSZ=pnVM`W@}L8#Jr^53p8NLp~rlO5j5Dcq>jmy zk(HJC4&wyoC3WB;>mDPM8Y3I?qB;)HfF|=pP?bNwZUP(g9Z==RyoU`khWetMNevn* zOwNpK%umZX(pXv9nCEjuu)6ht_!Hp04pt>wR#v#(pk@&BJw{M3iI@2nj~<I0D<|{v zVjEUgpITPVXW)>82`?+QLE}S079mev{_<ikRv{lyNU}(?GBD4t(_;|=4L&d8^#T`< z`fSX1i#XCi9WplNPs(0wHqg%4);MTqjKd4mV8PZKYi9%X##Wa<0R__x4jWL);)nos zEkCkzJYi*EzQ<Am?VFx}wx=O|Qw}e9=M*%F0Pmi9LA$4GKxW|Uo(i#QGXLW6VgvO$ z#n_ln6qc|Guz`B2df+~x5UA6$gD--u36yY_)p|h_&Mp=?Rz7B{CRQa-IX!`u&x=)t z&6`yaJodxR#@x*41*w+i!JG@Jme`o#l@erD0c0LZt<;35l_FR**qTAL5+tD4vx54( zpk@LCb3-vG^aa_Nn|LEwrPhL5y@6@0te?T1=jM_KRw?H5jG&<*FIHAi-v!hI233JP zY|QW;Ft`KEQ3C5SLxz}b+4RAc+)_qt)fp(KAewQY2$o`wgbXX5VohU?i$JT<K$Qus zYMKx73UbW^8XS;e?y5s|Ec4A;P+&6OV6Z{)1oO>W4k1=?=H*N_ATN>QPF7B4{WLas zFhD9saKXBqeIBbL7l$2dAR8!GNwYCOVf6x)cFdoP(pW9nnEQFX*qA>S?E;NnOyK>* zD*YZL3mI))Uj}NlUt#1Z0X3&V#o<L3P~Kwz$2N;Jq!F@)l@n|=7fN)aH9|nC$qN)< z*c%}wYzC}SYuT9p7VTmY1{wQN*^8As64ZHOvt{M=VCD7(v%QhoEYhqJ%)62ylLm}z z_N@HO^5`uOP(0yoP@oLFd4YqCi3_yk?U*un{gduKWd_hONV+Y`3=F!U8*r2v7%UkW zbiXJuFc>p1=te0))CDO))Y(C4&{lmT1_s@QiV%G>p>&@jM4btgmQ-W_EjQEsrvNec zi~_{m7%06;9-=>19-@z59-@v-7NRaph5<Aysk=-X;*NRJ5OwiT+CmzlUlGdxD8;}a z&cL91NeW`lA}NSD;ZoqEoONxXG-$)UBm;x)HqiBN3=F#KBq8SJLun6?Bm;x4A(a1L z0%Gn135dBHBp~LdN<hptg3>?5A@2Mr4l!>Bl<tAjnNZpdN=rfMgJKZ%6QOh*l-7gN zj8OWbC`8>9QSkaqUC`Bdq6`eWKBD0Dh`Pd}5cf!mFfd3lFzB8UhVXZRj`v_-(7h`N z5&tXzq1_=XTXi)AAo}^C^b&rE{AWH0ox#VzV93B=o5%;gRzo)ibX*AogQz1P#J`q& z;A>EI_4vS7q3Wvffv(A5u$AWnUzcht!3W+9rwck3#e{)D_ct#j-tO{3{4<vq60W(t zkZ=v<g~a<Y9*Ft-K*zQ)FzC*J(xp(^6H31Y9RmZ3M<`tfr30a~B9#6F*}bgG!3pu# zId+KspuMWX3=F!x?2zz!!UmBCZFB=Ag^#S@>s@u9vw~Om%U)xJxa%A%ME_zaJq1ep zLFu(D5cxhRozB9*Aj80*o5TV(M>K+kfkB>u!8VYE0d&2rt|L_51}bmF0zMkuRvRiW z3#Iv>=B;CfnBTw*(O(3mlbFFrGwOyiL+mkTW?%rFrlHEr09qfZ%fZaR0LrrGm>}ZI zq4Z29h<p(fMBW-o%P@hjz|{q<1Q20h&^^lt@y7|!?OhBEqWc&b7-Sh3Y&Sv0*FwdY zfmXXQFv!kkWB^@_t2+%MF5ANhF|Uacyy#oDlo8_oct!>W1qKG)a7IWxs6xd>85tNr zMHJ}RF_1jyBxVf;23^n*XPOKQx}am!SQr>YLF*m085ndySL}kE1X{bO%D|utx{?<p z4?6M<Bn~<T4pel2uJ{FsgSM-vF)-+Yj+<j(V32*mz`!8Lz`zH({fmi#fe*A>oP~jb z&4B^Dznu?s1u#DY10U#!b&$A+9r$nuHU}sz52eMS^e0=0{3|GZ7)tMk(u<(<EGS(A zrAwf67?k#d(gsjk14?s2X(lLr#Rg*E87RFOO0R~}lc01Ll#Yke;ZRx!N~=I=CMf;O z8e;BsD19DEZ-mk-p>zS1&VbUEP}&emt6D+Kk%iJ*Eg}51P<jfK?t#*IP&y4tdq8Oi zD6IsgrJ(d53y67Np!69ieFRFchSH0nbSspuh0^g*Ivh${LTN)NEexf(q4ZsIh<#U~ z^d2a^1xn9`(vzWd6_hT5(veU)5K0?EX>BOY3#D11^m8+aefOdC3@AMTN>@YaVkjL4 zrNf}KDU{ZQ(jrir2TH#)g_!>gN}qtz2cYyKC_M{G*FfnKDD4BKU7)l!lvak)tWf%| z3B;cJQ2IKQ-U+2QLg~p+x*JNzLg`Q_Z3CrEptLlU7KYNlj3M@Xg3>pk^hGGW8A`8) z(!Ef+6-uW=>3Ar8(FkJRNhrMmO0R&@T~N9SN~b{S7$|KArOlwU1e6wl(vJ)w=HG(S z2ch&%D7^qm&w$cOP+AH~e>Z^We-EWELg|xGdIFU0fYOmrIuJ^?=tK0^K<P**9SEh3 zp|m!XuGE95FND&LP}&koD?n)pD9r(-8KCqBU5Ne{Q2H#CJ_@DRK<On=Ivh&-L+LL% z5dCkUw5Jw??+B$eptJ&%W`fecG$HElK<O(`dK;8p2c;)K=?*BJ0i_e5v@?{phSF+K zS`JEcLTN@Q{YC>~?-M8;1*L<av>}w%gwiZf`j0w9-#I9K3`(zn(hHz81C;)u22mdb zrM;lE6_hrD(n?TT3QGT1h3NYZrSC!MYf!oqN;g7jNhmD{r3+Lb`ZJ)kKa_Td(wb0O z5lS;d>EFr_eRrYsRVck3O0S2~tx&oaN@qan1SstdrJbR)9+Xyt(n3(03rfFGg4p{2 zN*{;P`=RtgC_NKOS3~JyC>;u=eWA2Ilvan*e-$C-e}&Qyp!5wWT??g4p>zzC4uR5U zP+AX43qWZODE&$SV*Vp2eFRGHfzo|Yx(!O_Lg`c}?E|G<ptK~E7KGBz<RRwYgVKAT z^cE;R5lVML>1-&S45js;v>KHDE(bC1J(QM%(qd5hhb%<?1C+i5rB6ZW$xyl*O6Nl9 zR4DBZrR|}#0F>r{(jOq##jw4A(wCw1X(+uNO0S2~zEIi~N~=O?St!i{rT<7n+<gy9 zUxU&+p!5bPJqb#8LFpVQodTt;ptKQ`mW9%yP?`Zs|B!;%_ZUjwhSJBO^nNHk7fMfs z(lt=J1WJcNX+J1!0HrmcG#8X+g3?bUA@<&Z(wm_4Dkwb_O7}u(BPgu}r3IlhCzO6I z0Wt3}ls*cj_d@CUP<lF)u7uKsP}&(vTSI9jC@lr08KLw~afm(Vp!6{)JsV0-hSG&l zIulB}L1{ZEtpKGZp!8!gh`G0+^cpC=1WI2Pg~*?V(rcmgQYhUHrR$+|0F?HC(gsjk z14;`+X>KU}T?AtOdni2zN>72(GLUQ7*hHW-^crxs&ycHJ*sen9vru|HlwJ;{JE3$V zlum}y(NNkDN^3%C5h%?ArN2W?&0~8HrEfuL=xKUv`=I=7P<jfK?t#+9P&yk*`$B0~ zD6I~q<)Jhql>W&N376YY`ZAPW38fc8=^iNE0;ThzbUKs{g3?}4+6+qTL1`W+%>t!g z^Fi!=45g1k>Ag@IbfqC90|VQ1D8CX)7eeV^DD4fU6``~wlxBg_e;`*Ou|0><_o4JD zD18V@uY=OdpmYnAu7T3YP&yh)+d^qmC@l`9`Jwbj$Q5pEFQN2lD18`8&xFzwp>z$D zE`ieVP&yn+J3(nHD6Iyi<)HK*Zb*23fzr33^kpc$6-uv#(*01n9ZF|H=|m{)45h81 zv>=q`gwkKQAojh1($}H%c__ULN^gSF^Pn{7s(4VmmO%MAP&yb&dqZhmD6I;m*`f4* z$RUwz525r;D7_m>Z-&yHP`VLH=RoNcDD4lW-J!G*l-7dMVo;h7O26TN`1c8vJ`JT0 zL+PbZdM=c%htlOxIuc5QuF?Sc-x$i*hSH2s`X@Wo9w>bWN*{;P`=RtID7^?u_d)44 zD4hbOW1zG%l(vS_vQSzSN`GgA*!vzzUxd;pq4a7fy%<VYLg_*%9RsC9ptL=dHiyzm zP+AH~vq9;9tPp$eK<O(`dN-8b45g<+>0T(E52e$gv?r8ygwo1TS{h1!WP#Z85=viz z(r2Lbb|}3bO3#AQlc01RlrDqPAyC=}N*hCIZ79tPrCFi$b7qMB_o4JbD7_O(&xX>I zp>!scPK44vP}&7b>qBXEC@ln~xuEnnCWw9Sp!69ieFRFchSH0nbSspuh0^g*Ivh${ zLTN)NEexf(q4YyWh<!Jq^bsh%2TCu8((|Eo7nE*-(s@ui4NAK}X&Wf545g)^^j`*u zeP5yUbtruvN^gYHE1`5Zlx~L7kx)7iO4~qb6DTbYrNyB%6O{h-AAEuW+cPMA4@w_~ z(z~H_5|oaD(l$`q1WJoRX+9`@;~&J_3s8DHlwJ>|o1t_yl#YbbflzwOUx@xSP`VFF zw?XL)D4hVM?V+?el>YSxqW=?=z5=DsK<RBzdL5L`h0>`|+73#aLFu2rA?AIA(wCw1 zX(+uFO0R{|IZ!$UO4~wdQz-rT7sR~VP<k(v-U_89ptJy#zWNiQ{w$Q<0i`!U={Zn( z3Y4ya(j`zj9!iHpX=f;H4W*T#v^11vgVO(gK<s@5r5{1*Q&9R4lwJ#^mqO`@P`VRJ z7eeVwC>;W&eW0`jls16U5>Q$IO8@>2amQyUeIH6+htgS4ItfafL1{fG%>$)bp!DHy z5c76J>EB-={LfID8A|_#9KOVM2ukmQ(wR^idTKVC2bAvsrInzx6qNq+8DjnyD18k| zpM%mHp!5nT-2tT=pmZ{nj)u~1P}&YkYeH#7D9r<<S)lYI$m!Z_x1jV+D7_I%_dw|u zC>;i+{h+h~l-7XK+)$bsO27OF@!vxzeH=>fhthMP^b{yv2&FTjv^SJ?hSE16r+u+q zfYJw`^bRP!0!lA{(ydUs7D}f;=@=-@52e|m^ft)3H*D*mH0N80`x&A1n>P^t6DWNi zN*{;Po1pY6C_NQQ_d@AxD4h(Yy`Z!clvaV#GEn*-<mzR%Z&3OMl)eC^H$mxDP`Uw1 zS3v1xC>;%@-JrA`l-7jOicp#dO0z)eN3S6My#=KYLg}4QdN!1v45dq<bS{+khtlp) zS`$huLh0|2E5+H~L+M*k`Vy4h3#GS0=><@F29$1w($!Ep5=sX`X$vTA0HuYXG#8Y9 z1G(mv?Fp1V2Br5w=><@F29(Z&(rHjS5K4POX%i@|1Es~GG(VL71v$Tn?Guzf3Z?f# z=@n3V0hI2B(#=ph4@##&=|Cv$38mGcv^<n%gVO(=LE`ZNl)eF_cR}e*P<jfK?t#*I zP&y4t+dyd(C@l}A#i2A4l>YS;V&79JeHTiffYJw`^kgXA4W-MVbRLwBgwlaf+6GFS zKxug>Ee@r>LJk6BdkdwnK<P73dL5Kr2BkZobOV%5g3?h?+6GFSKxr;0%><?2Le8OM zdkUp5K<N`udNY(>4W*|+={_i(1Eo`-v^SJ?hSI7~S{6$Gha8y4_8m&!gwhwG^kyi% z8cH`p=}IV_0;OZ1v^$ixhtgV5S_w+?LTOeg{rDjyUT;I`Lr{7bl%4~nr$Fg4D4hqT z1E91Al-7dMN>KU-<m4{44^a9xl)en5_d)4xP<kPho(ZK}pmYtC_J`8$P}&GeYe8vI zD9sC{p$Gr5eSjPS$95Y^Uxv~fq4Y{9JpoF0K<O+fodl&_ptKE?hF;jfCI;pIfSh{9 z_5n&CgVOt;H1sr5wuMlB50q|!()mz29ZCm5Y3ONcY+oTqyRp56(&wS{aVRYhrNyE2 z#XFGrJqe|^K<PD5dODQuhtlOxIv+|$LFphUZ40GMp|mWN7KPFbQ2NJhh`o=Y^ld18 z7)tMk(#xRqJSg1>r5mBNHk4L|(u`30=Pii&x1sc9D7_U*uZ7aZP&yk*2SaIZC~XF% z^`NvQloo{2KW{?p`3R-&K<O(`dOwuj4y8GuH0VA((0B<e<WN$!zt<t=+=kMZq4X{& zy$MQBfzmxtIuA;xLFqs!?Fpq#ptKH@W`)v!uR-j40;TUj>3vXo8<d^_r6)k?A}E~& zrG22Z3zQav(tJ?*>s5$7Z=v)RD18P>Z-&yVq4Xpu-36s{pmYk9c7xJ(P+9>>OF-!} zS0MHsfzs=t^l~UY8A^9U>2fHY52d4_bTE`QgwmQ&S^!FOK<QVPA@)6j(np~59w<Ez zN>78*6;QeWO1nX6J1DIQr4^y{=}Qpv4@2oyP<j!RZh_J@P&y7uhe2rzC~W|xg`hMS zlzwm#V*U*%eHcpbhSI4}Iu=U1KxrE&EeEB=p!AOm5c57j=}S=h6qH^ArI$eIDkxn9 zrDLIVD3tzt9%9~CD18S?UxCuwp!7N@JpoF0K<Q#AoeibKptK*9R)^B^P?`-&|2qe< z_W_i?0i}0A=}l023Y6}F(s@ui4N6-;X#*%N4yE~_^tZDRd)`6mt5EtZl->fR*Ffn$ zDBT97GoW+=ly-vBR#3Y448;6aD4hePQ=qgPl(vJ?3Q$@CO8+_y(f<ibUxCtRp!6ar zJqt>=Lg`v4odKm2ptLuXc81dWP+A>Ivq0%Try%y;gwhwG^e!m92})0c(tS`m1xm+2 zX)h@41f?~hv?7#dh0=ddLhRcKr8h$9`A~W~l&*!+rBFHoN(VscPmoh+*<L~EYf$<e zl->rV*Fou-P<kSiu7%R2P&yh)2SaI7D6I>n1)wwsl>TxY;*U2_`UaG~0HxPJ=_OFQ z5lUA=>1Ze&45dw>v@Vnufzmus`sFc*eGj4ZJ}A8nO3#JTQ=xPbl+J?E?oiquO20Y^ zG4BzSJ`1IfLg|fAdL@*;as;CO43rk$1L1Q+=})^M{8v!=0F>SVrA=l-<aMBQq5uQv z<T*AQ&=rad3~W45{&RltdQ~>i6^zUb3~V+G5WYI-yi&-GdZ6?1*k&+-&VFQI1D#uH z&cMLe09gmiRsj_+U}Rtbi6=nC9iX%YRNeq8uK*R7fQk!1#X**U+6|x^v6vVb*g)6p zg3JTma1Rnc0Cmp}28cU0FhJ~E02Ob5(iKp7(3!U&{RvQU&^lL;ITlcP(0W&pyaH4n zbp9nso*CjEU(ng2AbuG$0|Os31A_tdELYI_T|QO@289`*qr?~(=CLp^@G&wlfb0XA zkq=s2%gDe0J5v|59v7tE0IL25D+2=`69fG0-Gxv->@3|SAp1b)e?rf^eFEjf&dBYD zs)wDOTMOmG&ce-x@?mG+Mnd^pKnJceFfhD=@?mG!9)<E@XVp4_>|<tNSOE3!S_X*! z8Pq_&V_?vR$~!>$QA`XB{2=#2q!~c#rTG~TFf>5j&kmM90J#%^fq`K?j1RhPgn@yf z70QR5(d)_rGVcHb?9AQgP(JL8-T%xGdDxl5*P;4hXZW^5(ihY<3=9#>;Cuk*3!=$G z(;Zy?9V9)#`Jij8k-P`K-w&C;2+cfhH2b8`_@L{qk@ate9ykuOFcVEZ=v-K2_2-~h zK)}@RK;utG)8CH9H%9Z{DKvS|72nAAf!2#7^ADlv2dz6tmItkiN9Kdpy(9Ar(ZUO~ zJ{?*9FIsqju82dH2eCmI=6^Rd^BCfDQ*)CGDjDMA<C7~A<4ZD%^2-_G11fzoi%a7D zQp*|Q<D-0xQ}fC|jFg-JFzx3ZTw)v_Z)ju?9}hXoGCnD>I5j>wKQ}i&&(kN#(A5<r z2R1D}Cp9m<BqKhxs3^b46{0`5#Lx&?*u@Ye5m4z_l3En+ms(K*a)K}TsLy!EloWsP zp`suc_!yc%P5_OE94J~05)27LHxDf8i76UT=~|H-AC{O?n(7L24#*miNJwP?sz6X_ z9_VaEsG|5NA4})Nq7*1Mpc3Msc=yy2kc%1OAqS2!#OLJarDx?9z(Nyzb}Hz=$5i+! zpU`klD@sj`M-mOFbS(n;yxbK@WmH~yF35%8xCjQ@l?(EjkrC*u$GrHA#GJJF+|;7< z)cB&*<kF&`%pgnWoW#=N)Zo;TAU{YPnL#4RGt)2FDBcq4qWmJyOjlP|*I@JbVDos0 zp~gstf|#jA6qpKjw`X2vNj&oLtRTnx7@8Dkrh^XI%t*{j$w@8B1c~|~9ByQoT$Bn5 zw35`Kyu_l)_++q`Tr)E<R2o24CS{^31e=KAeRSVj#K$KV6r|>*xaJ0VXMzJdKQBGr zvDha+FCETxE6UG>2*gME7@C4YCNDlEKN)hoD##`uLo;ZaL=uKXXmDytFyye<_<&0P zU{E?K&P<1BGJt7HO=F0U56vsj%u9(6N-ZwUO=XCW52%cHNd?CiNHsJreQ;!|0Pkd| zDnrAZ{PfIZNM>_3az&Cs$#BkwNK&AzjFe2!!^y}nKE9x|I3qqOF*!TFI48e6z96wA z!_zy{)wL`rBpzxtvMGMS2JxU2hi;UsU$9}kXRvX+tE($cW5LoegMBOtD&xU{9$+4y z4=x9S4M0`~RK`1%X6B@TGjn`!W>snkIM^JE(&GaXi;7c2N(*vQ;Sy2MAcXmoC>NT= z#}}6;7R2Y5mc%D#7A2SFBo;x><8=-43ywE5K|Q1w<g=h)lXzEG26ty?X#S2bNleN~ zwZssyzz{LV5HZCNF$N_}Xvydd&L>6~Y7DUmVJb2Nl~U;y74ZeBMaB7fi8+}imGNZ; G3=9BpqHxv# diff --git a/pages/application/RandomForest/utils/xrf/archive/encode.py b/pages/application/RandomForest/utils/xrf/archive/encode.py deleted file mode 100644 index 3478ebc..0000000 --- a/pages/application/RandomForest/utils/xrf/archive/encode.py +++ /dev/null @@ -1,276 +0,0 @@ - -from pysat.formula import CNF, IDPool -from pysat.solvers import Solver -from pysat.card import * -from itertools import combinations - -import collections -import six -from six.moves import range - -from .tree import Forest, predict_tree -from .sortnetwrk import HSorNetwrk - -# -#============================================================================== -class SATEncoder(object): - """ - Encoder of Random Forest classifier into SAT. - """ - - def __init__(self, forest, feats, nof_classes, extended_feature_names=None, from_file=None): - #self.model = model - self.forest = forest - self.feats = {f: i for i, f in enumerate(feats)} - self.num_class = nof_classes - self.vpool = IDPool() - #self.optns = xgb.options - self.extended_feature_names = extended_feature_names - - #encoding formula - self.cnf = None - - # for interval-based encoding - self.intvs, self.imaps, self.ivars = None, None, None - - #if from_file: - # self.load_from(from_file) - - def newVar(self, name): - assert(name) - - if name in self.vpool.obj2id: #var has been already created - return self.vpool.obj2id[name] - - var = self.vpool.id('{0}'.format(name)) - return var - - - def traverse(self, tree, k, clause): - """ - Traverse a tree and encode each node. - """ - - if tree.children: - var = self.newVar(tree.name) - #print("{0} => {1}".format(tree.name, var)) - pos, neg = var, -var - - self.traverse(tree.children[0], k, clause + [-neg]) # -var - self.traverse(tree.children[1], k, clause + [-pos]) # --var - else: # leaf node - cvar = self.newVar('class{0}_tr{1}'.format(tree.values,k)) - print('c: ', clause + [cvar]) - self.cnf.append(clause + [cvar]) - - - ''' - def encode_node(self, node): - """ - Encode a node of a tree. - """ - - if '_' not in node.name: - # continuous features => expecting an upper bound - # feature and its upper bound (value) - f, v = node.name, node.threshold - - existing = True if tuple([f, v]) in self.idmgr.obj2id else False - vid = self.idmgr.id(tuple([f, v])) - bv = Symbol('bvar{0}'.format(vid), typename=BOOL) - - if not existing: - if self.intvs: - d = self.imaps[f][v] + 1 - pos, neg = self.ivars[f][:d], self.ivars[f][d:] - self.enc.append(Iff(bv, Or(pos))) - self.enc.append(Iff(Not(bv), Or(neg))) - else: - fvar, fval = Symbol(f, typename=REAL), Real(v) - self.enc.append(Iff(bv, LT(fvar, fval))) - - return bv, Not(bv) - else: - # all features are expected to be categorical and - # encoded with one-hot encoding into Booleans - # each node is expected to be of the form: f_i < 0.5 - bv = Symbol(node.name, typename=BOOL) - - # left branch is positive, i.e. bv is true - # right branch is negative, i.e. bv is false - return Not(bv), bv - ''' - - - def compute_intervals(self): - """ - Traverse all trees in the ensemble and extract intervals for each - feature. - - At this point, the method only works for numerical datasets! - """ - - def traverse_intervals(tree): - """ - Auxiliary function. Recursive tree traversal. - """ - - if tree.children: - f = tree.name - v = tree.threshold - self.intvs[f].add(v) - - traverse_intervals(tree.children[0]) - traverse_intervals(tree.children[1]) - - # initializing the intervals - self.intvs = {'f{0}'.format(i): set([]) for i in range(len(self.feats))} - - for tree in self.forest.trees: - traverse_intervals(tree) - - # OK, we got all intervals; let's sort the values - self.intvs = {f: sorted(self.intvs[f]) + ['+'] for f in six.iterkeys(self.intvs)} - - self.imaps, self.ivars = {}, {} - for feat, intvs in six.iteritems(self.intvs): - self.imaps[feat] = {} - self.ivars[feat] = [] - for i, ub in enumerate(intvs): - self.imaps[feat][ub] = i - - ivar = Symbol(name='{0}_intv{1}'.format(feat, i), typename=BOOL) - self.ivars[feat].append(ivar) - - def encode(self, sample): - """ - Do the job. - """ - - self.cnf = CNF() - # getting a tree ensemble - #self.forest = Forest(self.model, self.extended_feature_names) - num_tree = len(self.forest.trees) - - # introducing class score variables - cvars = [[] for t in range(num_tree)] - for k in range(len(self.forest.trees)): - for j in range(self.num_class): - var = self.newVar('class{0}_tr{1}'.format(j,k)) - cvars[k].append(-var) - - # if targeting interval-based encoding, - # traverse all trees and extract all possible intervals - # for each feature - ''' - if self.optns.encode == 'smtbool': - self.compute_intervals() - ''' - - # traversing and encoding each tree - for k, tree in enumerate(self.forest.trees): - print("Encode tree#{0}".format(k)) - # encoding the tree - self.traverse(tree, k, []) - #exactly one class var is true this could could be squeezed - # more to reduce NB binary clauses!!!!!!! - enc = CardEnc.atmost(lits=[-v for v in cvars[k]], - vpool=self.vpool, - encoding=EncType.cardnetwrk) #AtMostOne constraint - self.cnf.extend(enc.clauses) - - - csum = [[] for c in range(self.num_class)] - for k, tree in enumerate(self.forest.trees): - c = predict_tree(tree, sample) - csum[c].append(k) - cvars[k][c] = - cvars[k][c] - - # encoding the majority - cmaj,_ = max(enumerate(csum), key=(lambda x: len(x[1]))) - sorted_lits = [[] for c in range(self.num_class)] - #sorting bits - for j in range(self.num_class): - tvars = [cvars[k][j] for k in range(num_tree)] - clauses, vout, _ = HSorNetwrk(lits=tvars, vpool = self.vpool) - self.cnf.extend(clauses) - sorted_lits[j] = vout - #print("tvars: {0} ==> {3} \nclauses: {1}\ntop: {2}".format(tvars, clauses, self.vpool.top, vout)) - #compare bits - for j in range(self.num_class): - if j == cmaj: - continue - for k in range(num_tree): - self.cnf.append([ -sorted_lits[j][k], sorted_lits[cmaj][k] ]) # (v1 => v2) - #print("-{0} => {1}".format(sorted_lits[j][k], sorted_lits[cmaj][k])) - - ''' - # enforce exactly one of the feature values to be chosen - # (for categorical features) - categories = collections.defaultdict(lambda: []) - for f in self.extended_feature_names: - if '_' in f: - categories[f.split('_')[0]].append(self.newVar(f)) - - for c, feats in six.iteritems(categories): - #ExactlyOne feat is True - self.cnf.append(feats) - enc = CardEnc.atmost(lits=feats, vpool=self.vpool, encoding=EncType.cardnetwrk) - self.cnf.extend(enc.clauses) - ''' - - #if self.optns.verb: - # number of variables - print('#vars:', self.cnf.nv) - # number of clauses - print('#clauses:', len(self.cnf.clauses)) - #print(self.cnf.clauses) - - return self.cnf, self.intvs, self.imaps, self.ivars - - ''' - def test_sample(self, sample): - """ - Check whether or not the encoding "predicts" the same class - as the classifier given an input sample. - """ - - # first, compute the scores for all classes as would be - # predicted by the classifier - - # score arrays computed for each class - csum = [[] for c in range(self.num_class)] - - #if self.optns.verb: - print('testing sample:', list(sample)) - - # traversing all trees - for i, tree in enumerate(self.forest.trees): - c = predict_tree(tree, sample) - csum[c].append(i) - - # encoding the majority - cmaj,_ = max(enumerate(csum), key=(lambda x: len(x[1]))) - - # second, get the scores computed with the use of the encoding - assert self.cnf, "There is no encoding." - - slv = Solver(name="minisat22") - slv.add_formula(self.cnf) - - - # asserting the sample - hypos = [] - - #for i, fval in enumerate(sample): - - ''' - - - def access(self): - """ - Get access to the encoding, features names, and the number of - classes. - """ - - return self.cnf, self.intvs, self.imaps, self.ivars, self.feats, self.num_class \ No newline at end of file diff --git a/pages/application/RandomForest/utils/xrf/archive/pysortnetwrk.cc b/pages/application/RandomForest/utils/xrf/archive/pysortnetwrk.cc deleted file mode 100644 index 8a44d96..0000000 --- a/pages/application/RandomForest/utils/xrf/archive/pysortnetwrk.cc +++ /dev/null @@ -1,248 +0,0 @@ - - -#define PY_SSIZE_T_CLEAN - -#include <setjmp.h> -#include <signal.h> -#include <stdio.h> -#include <Python.h> - -#include "sortcard.hh" - -using namespace std; - -// docstrings -//============================================================================= -static char module_docstring[] = "This module provides an interface for " - "encoding a few types of cardinality " - "constraints"; -//static char atmost_docstring[] = "Create an AtMost(k) constraint."; -//static char atleast_docstring[] = "Create an AtLeast(k) constraint."; -static char sortn_docstring[] = "Sort an array of bits."; - -static PyObject *CardError; -static jmp_buf env; - -// function declaration for functions available in module -//============================================================================= -extern "C" { - //static PyObject *py_encode_atmost (PyObject *, PyObject *); - //static PyObject *py_encode_atleast (PyObject *, PyObject *); - static PyObject *py_sortn (PyObject *, PyObject *); -} - -// module specification -//============================================================================= -static PyMethodDef module_methods[] = { - //{ "encode_atmost", py_encode_atmost, METH_VARARGS, atmost_docstring }, - //{ "encode_atleast", py_encode_atleast, METH_VARARGS, atleast_docstring }, - { "HSort", py_sortn, METH_VARARGS, sortn_docstring }, - - { NULL, NULL, 0, NULL } -}; - -extern "C" { - -// signal handler for SIGINT -//============================================================================= -static void sigint_handler(int signum) -{ - longjmp(env, -1); -} - -//#if PY_MAJOR_VERSION >= 3 // for Python3 -// PyInt_asLong() -//============================================================================= -static int pyint_to_cint(PyObject *i_obj) -{ - return PyLong_AsLong(i_obj); -} - -// PyInt_fromLong() -//============================================================================= -static PyObject *pyint_from_cint(int i) -{ - return PyLong_FromLong(i); -} - -// PyCapsule_New() -//============================================================================= -static PyObject *void_to_pyobj(void *ptr) -{ - return PyCapsule_New(ptr, NULL, NULL); -} - -// PyCapsule_GetPointer() -//============================================================================= -static void *pyobj_to_void(PyObject *obj) -{ - return PyCapsule_GetPointer(obj, NULL); -} - -// PyInt_Check() -//============================================================================= -static int pyint_check(PyObject *i_obj) -{ - return PyLong_Check(i_obj); -} - -// module initialization -//============================================================================= -static struct PyModuleDef module_def = { - PyModuleDef_HEAD_INIT, - "pysortnetwrk", /* m_name */ - module_docstring, /* m_doc */ - -1, /* m_size */ - module_methods, /* m_methods */ - NULL, /* m_reload */ - NULL, /* m_traverse */ - NULL, /* m_clear */ - NULL, /* m_free */ -}; - -/* -PyMODINIT_FUNC PyInit_pycard(void) -{ - PyObject *m = PyModule_Create(&module_def); - - if (m == NULL) - return NULL; - - CardError = PyErr_NewException((char *)"pycard.error", NULL, NULL); - Py_INCREF(CardError); - - if (PyModule_AddObject(m, "error", CardError) < 0) { - Py_DECREF(CardError); - return NULL; - } - - return m; -}*/ - -PyMODINIT_FUNC PyInit_pysortnetwrk(void) -{ - PyObject *m = PyModule_Create(&module_def); - - if (m == NULL) - return NULL; - - CardError = PyErr_NewException((char *)"pycard.error", NULL, NULL); - Py_INCREF(CardError); - - if (PyModule_AddObject(m, "error", CardError) < 0) { - Py_DECREF(CardError); - return NULL; - } - - return m; -} - - -// auxiliary function for translating an iterable to a vector<int> -//============================================================================= -static bool pyiter_to_vector(PyObject *obj, vector<int>& vect) -{ - PyObject *i_obj = PyObject_GetIter(obj); - - if (i_obj == NULL) { - PyErr_SetString(PyExc_RuntimeError, - "Object does not seem to be an iterable."); - return false; - } - - PyObject *l_obj; - while ((l_obj = PyIter_Next(i_obj)) != NULL) { - if (!pyint_check(l_obj)) { - Py_DECREF(l_obj); - Py_DECREF(i_obj); - PyErr_SetString(PyExc_TypeError, "integer expected"); - return false; - } - - int l = pyint_to_cint(l_obj); - Py_DECREF(l_obj); - - if (l == 0) { - Py_DECREF(i_obj); - PyErr_SetString(PyExc_ValueError, "non-zero integer expected"); - return false; - } - - vect.push_back(l); - } - - Py_DECREF(i_obj); - return true; -} - -// -//============================================================================= -static PyObject *py_sortn(PyObject *self, PyObject *args) -{ - - PyObject *av_obj; - //PyObject *cv_obj; - int top; - int zvar; - - //PyObject *lhs_obj; - //int rhs; - //int top; - //int enc; - int main_thread; - - if (!PyArg_ParseTuple(args, "Oiii", &av_obj, &top, &zvar, - &main_thread)) - return NULL; - - vector<int> av; - if (pyiter_to_vector(av_obj, av) == false) - return NULL; - - PyOS_sighandler_t sig_save; - if (main_thread) { - sig_save = PyOS_setsig(SIGINT, sigint_handler); - - if (setjmp(env) != 0) { - PyErr_SetString(CardError, "Caught keyboard interrupt"); - return NULL; - } - } - - // calling encoder - ClauseSet dest; - vector<int> cv; - sortn_half_sorter_recur(top, dest, av, cv, zvar); - //_encode_atmost(dest, lhs, rhs, top, enc); - - if (main_thread) - PyOS_setsig(SIGINT, sig_save); - - // creating the resulting clause set - PyObject *dest_obj = PyList_New(dest.size()); - for (size_t i = 0; i < dest.size(); ++i) { - PyObject *cl_obj = PyList_New(dest[i].size()); - - for (size_t j = 0; j < dest[i].size(); ++j) { - PyObject *lit_obj = pyint_from_cint(dest[i][j]); - PyList_SetItem(cl_obj, j, lit_obj); - } - - PyList_SetItem(dest_obj, i, cl_obj); - } - - PyObject *cv_obj = PyList_New(cv.size()); - for (size_t i = 0; i < cv.size(); ++i) { - PyObject *lit_obj = pyint_from_cint(cv[i]); - PyList_SetItem(cv_obj, i, lit_obj); - } - - PyObject *ret = Py_BuildValue("OOn", dest_obj, cv_obj, (Py_ssize_t)top); - Py_DECREF(dest_obj); - Py_DECREF(cv_obj); - - return ret; -} - - -} // extern "C" diff --git a/pages/application/RandomForest/utils/xrf/archive/pysortnetwrk.so b/pages/application/RandomForest/utils/xrf/archive/pysortnetwrk.so deleted file mode 100755 index 7aa11a7e970e9b6d0a19149ddf63f889f952f4a7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23116 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 diff --git a/pages/application/RandomForest/utils/xrf/archive/rfc.py b/pages/application/RandomForest/utils/xrf/archive/rfc.py deleted file mode 100644 index 411ad46..0000000 --- a/pages/application/RandomForest/utils/xrf/archive/rfc.py +++ /dev/null @@ -1,636 +0,0 @@ -from sklearn.ensemble._voting import VotingClassifier -from sklearn.ensemble import RandomForestClassifier -from sklearn.preprocessing import OneHotEncoder, LabelEncoder -from sklearn.model_selection import train_test_split -from sklearn.metrics import accuracy_score -import numpy as np -import sys -import os -import resource - -import collections -from six.moves import range -import six - -from pages.application.RandomForest.utils.data import Data -from .tree import Forest, predict_tree -# from .encode import SATEncoder -from .sortnetwrk import HSorNetwrk -from pysat.formula import CNF, IDPool -from pysat.solvers import Solver -from pysat.card import CardEnc, EncType -from itertools import combinations - - -# -# ============================================================================== -class Dataset(Data): - """ - Class for representing dataset (transactions). - """ - - def __init__(self, filename=None, fpointer=None, mapfile=None, - separator=' ', use_categorical=False): - super().__init__(filename, fpointer, mapfile, separator, use_categorical) - - # split data into X and y - self.feature_names = self.names[:-1] - self.nb_features = len(self.feature_names) - self.use_categorical = use_categorical - samples = np.asarray(self.samps, dtype=np.float32) - self.X = samples[:, 0: self.nb_features] - self.y = samples[:, self.nb_features] - self.num_class = len(set(self.y)) - self.target_name = list(range(self.num_class)) - - print("c nof_features: {0}".format(self.nb_features)) - print("c nof_samples: {0}".format(len(self.samps))) - - # check if we have info about categorical features - if (self.use_categorical): - self.binarizer = {} - for i in self.categorical_features: - self.binarizer.update({i: OneHotEncoder(categories='auto', sparse=False)}) # , - self.binarizer[i].fit(self.X[:, [i]]) - else: - self.binarize = [] - # feat map - self.mapping_features() - - def train_test_split(self, test_size=0.2, seed=0): - return train_test_split(self.X, self.y, test_size=test_size, random_state=seed) - - def transform(self, x): - if (len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert (self.binarizer != []) - tx = [] - for i in range(self.nb_features): - self.binarizer[i].drop = None - if (i in self.categorical_features): - tx_aux = self.binarizer[i].transform(x[:, [i]]) - tx_aux = np.vstack(tx_aux) - tx.append(tx_aux) - else: - tx.append(x[:, [i]]) - tx = np.hstack(tx) - return tx - else: - return x - - def transform_inverse(self, x): - if (len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert (self.binarizer != []) - inverse_x = [] - for i, xi in enumerate(x): - inverse_xi = np.zeros(self.nb_features) - for f in range(self.nb_features): - if f in self.categorical_features: - nb_values = len(self.categorical_names[f]) - v = xi[:nb_values] - v = np.expand_dims(v, axis=0) - iv = self.binarizer[f].inverse_transform(v) - inverse_xi[f] = iv - xi = xi[nb_values:] - - else: - inverse_xi[f] = xi[0] - xi = xi[1:] - inverse_x.append(inverse_xi) - return inverse_x - else: - return x - - def transform_inverse_by_index(self, idx): - if (idx in self.extended_feature_names): - return self.extended_feature_names[idx] - else: - print("Warning there is no feature {} in the internal mapping".format(idx)) - return None - - def transform_by_value(self, feat_value_pair): - if (feat_value_pair in self.extended_feature_names.values()): - keys = ( - list(self.extended_feature_names.keys())[list(self.extended_feature_names.values()).index(feat_value_pair)]) - return keys - else: - print("Warning there is no value {} in the internal mapping".format(feat_value_pair)) - return None - - def mapping_features(self): - self.extended_feature_names = {} - self.extended_feature_names_as_array_strings = [] - counter = 0 - if (self.use_categorical): - for i in range(self.nb_features): - if (i in self.categorical_features): - for j, _ in enumerate(self.binarizer[i].categories_[0]): - self.extended_feature_names.update({counter: (self.feature_names[i], j)}) - self.extended_feature_names_as_array_strings.append( - "f{}_{}".format(i, j)) # str(self.feature_names[i]), j)) - counter = counter + 1 - else: - self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i)) # (self.feature_names[i]) - counter = counter + 1 - else: - for i in range(self.nb_features): - self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i)) # (self.feature_names[i]) - counter = counter + 1 - - def readable_sample(self, x): - readable_x = [] - for i, v in enumerate(x): - if (i in self.categorical_features): - readable_x.append(self.categorical_names[i][int(v)]) - else: - readable_x.append(v) - return np.asarray(readable_x) - - def test_encoding_transformes(self, X_train): - # test encoding - - X = X_train[[0], :] - - print("Sample of length", len(X[0]), " : ", X) - enc_X = self.transform(X) - print("Encoded sample of length", len(enc_X[0]), " : ", enc_X) - inv_X = self.transform_inverse(enc_X) - print("Back to sample", inv_X) - print("Readable sample", self.readable_sample(inv_X[0])) - assert ((inv_X == X).all()) - - ''' - for i in range(len(self.extended_feature_names)): - print(i, self.transform_inverse_by_index(i)) - for key, value in self.extended_feature_names.items(): - print(value, self.transform_by_value(value)) - ''' - - -# -# ============================================================================== -class VotingRF(VotingClassifier): - """ - Majority rule classifier - """ - - def fit(self, X, y, sample_weight=None): - self.estimators_ = [] - for _, est in self.estimators: - self.estimators_.append(est) - - self.le_ = LabelEncoder().fit(y) - self.classes_ = self.le_.classes_ - - def predict(self, X): - """Predict class labels for X. - Parameters - ---------- - X : {array-like, sparse matrix} of shape (n_samples, n_features) - The input samples. - Returns - ------- - maj : array-like of shape (n_samples,) - Predicted class labels. - """ - # check_is_fitted(self) - - # 'hard' voting - predictions = self._predict(X) - predictions = np.asarray(predictions, np.int64) # NEED TO BE CHECKED - maj = np.apply_along_axis( - lambda x: np.argmax( - np.bincount(x, weights=self._weights_not_none)), - axis=1, arr=predictions) - - maj = self.le_.inverse_transform(maj) - - return maj - - -# -# ============================================================================== -class RF2001(object): - """ - The main class to train Random Forest Classifier (RFC). - """ - - def __init__(self, options, from_data=None, from_model=None): - """ - Constructor. - """ - self.forest = None - self.voting = None - self.opt = options - - param_dist = {'n_estimators': options.n_estimators, - 'max_depth': options.maxdepth} - - self.forest = RandomForestClassifier(**param_dist) - - def train(self, dataset, outfile=None): - """ - Train a random forest. - """ - - X_train, X_test, y_train, y_test = dataset.train_test_split() - - dataset.test_encoding_transformes(X_train) - X_train = dataset.transform(X_train) - X_test = dataset.transform(X_test) - - print("Build a random forest.") - self.forest.fit(X_train, y_train) - - rtrees = [('dt', dt) for i, dt in enumerate(self.forest.estimators_)] - self.voting = VotingRF(estimators=rtrees) - self.voting.fit(X_train, y_train) - - train_acc = accuracy_score(self.voting.predict(X_train), y_train) - ''' - print(X_test[[0],:]) - print("RF: ",np.asarray(self.voting.predict(X_test[[0],:]))) - for i,t in enumerate(self.forest.estimators_): - print("DT_{0}: {1}".format(i,np.asarray(t.predict(X_test[[0],:])))) - ''' - test_acc = accuracy_score(self.voting.predict(X_test), y_test) - print("----------------------") - print("RF2001:") - print("Train accuracy RF2001: {0:.2f}".format(100. * train_acc)) - print("Test accuracy RF2001: {0:.2f}".format(100. * test_acc)) - print("----------------------") - - train_acc = accuracy_score(self.forest.predict(X_train), y_train) - test_acc = accuracy_score(self.forest.predict(X_test), y_test) - print("RF-scikit:") - print("Train accuracy RF-scikit: {0:.2f}".format(100. * train_acc)) - print("Test accuracy RF-scikit: {0:.2f}".format(100. * test_acc)) - print("----------------------") - - return train_acc, test_acc - - def predict(self, X): - return self.voting.predict(X) - - def estimators(self): - assert (self.forest.estimators_ is not None) - return self.forest.estimators_ - - def n_estimators(self): - return self.forest.n_estimators - - -# -# ============================================================================== -class XRF(object): - """ - class to encode and explain Random Forest classifiers. - """ - - def __init__(self, options, model): - self.cls = model - self.f = Forest(model) - # self.f.print_tree() - self.verbose = options.verb - - def encode(self, data): - """ - Encode a tree ensemble trained previously. - """ - ########## - self.f = Forest(self.cls, data.extended_feature_names_as_array_strings) - self.f.print_tree() - ####### - self.sat_enc = SATEncoder(self.f, data.feature_names, data.num_class, - extended_feature_names=data.extended_feature_names_as_array_strings) - - _, X_test, _, y_test = data.train_test_split() - - inst = X_test[[1], :] - inst = data.transform(inst)[0] - self.sat_enc.encode(inst) - self.explain(inst, data) - - def explain(self, sample, data): - """ - Explain a prediction made for a given sample with a previously - trained RF. - """ - - preamble = None - if self.verbose: - inpvals = data.readable_sample(sample) - - preamble = [] - for f, v in zip(data.feature_names, inpvals): - if f not in v: - preamble.append('{0} = {1}'.format(f, v)) - else: - preamble.append(v) - - inps = data.extended_feature_names_as_array_strings # input (feature value) variables - # print("inps: {0}".format(inps)) - - if 'x' not in dir(self): - self.x = SATExplainer(self.sat_enc, inps, preamble, data.target_name) - - expl = self.x.explain(np.array(sample)) - - # returning the explanation - return expl - - def test_tree_ensemble(self, dataset): - _, X_test, _, y_test = dataset.train_test_split() - X_test = dataset.transform(X_test) - - y_pred_forest = self.f.predict(X_test) - acc = accuracy_score(y_pred_forest, y_test) - print("Test accuracy: {0:.2f}".format(100. * acc)) - - y_pred_cls = self.cls.predict(X_test) - # print(np.asarray(y_pred_cls, np.int64)) - # print(y_pred_forest) - - assert ((y_pred_cls == y_pred_forest).all()) - - -# -# ============================================================================== -class SATEncoder(object): - """ - Encoder of Random Forest classifier into SAT. - """ - - def __init__(self, forest, feats, nof_classes, extended_feature_names=None, from_file=None): - # self.model = model - self.forest = forest - self.feats = {f: i for i, f in enumerate(feats)} - self.num_class = nof_classes - self.vpool = IDPool() - # self.optns = xgb.options - self.extended_feature_names = extended_feature_names - - # encoding formula - self.cnf = None - - # for interval-based encoding - self.intvs, self.imaps, self.ivars = None, None, None - - # if from_file: - # self.load_from(from_file) - - def newVar(self, name): - assert (name) - - if name in self.vpool.obj2id: # var has been already created - return self.vpool.obj2id[name] - - var = self.vpool.id('{0}'.format(name)) - return var - - def traverse(self, tree, k, clause): - """ - Traverse a tree and encode each node. - """ - - if tree.children: - var = self.newVar(tree.name) - # print("{0} => {1}".format(tree.name, var)) - pos, neg = var, -var - - self.traverse(tree.children[0], k, clause + [-neg]) # -var - self.traverse(tree.children[1], k, clause + [-pos]) # --var - else: # leaf node - cvar = self.newVar('class{0}_tr{1}'.format(tree.values, k)) - # print('c: ', clause + [cvar]) - self.cnf.append(clause + [cvar]) - - def encode(self, sample): - """ - Do the job. - """ - - self.cnf = CNF() - # getting a tree ensemble - # self.forest = Forest(self.model, self.extended_feature_names) - num_tree = len(self.forest.trees) - - # introducing class variables - cvars = [self.newVar('class{0}'.format(i)) for i in range(self.num_tree)] - - # introducing class-tree variables - ctvars = [[] for t in range(num_tree)] - for k in range(num_tree): - for j in range(self.num_class): - var = self.newVar('class{0}_tr{1}'.format(j, k)) - ctvars[k].append(var) - - # if targeting interval-based encoding, - # traverse all trees and extract all possible intervals - # for each feature - ''' - if self.optns.encode == 'smtbool': - self.compute_intervals() - ''' - - # traversing and encoding each tree - for k, tree in enumerate(self.forest.trees): - # print("Encode tree#{0}".format(k)) - # encoding the tree - self.traverse(tree, k, []) - # exactly one class var is true this could could be squeezed - # more to reduce NB binary clauses!!!!!!! - enc = CardEnc.atmost(lits=ctvars[k], - vpool=self.vpool, - encoding=EncType.cardnetwrk) # AtMostOne constraint - self.cnf.extend(enc.clauses) - - csum = [[] for c in range(self.num_class)] - for k, tree in enumerate(self.forest.trees): - c = predict_tree(tree, sample) - csum[c].append(k) - - # encoding the majority - self.cmaj, _ = max(enumerate(csum), key=(lambda x: len(x[1]))) - sorted_lits = [[] for c in range(self.num_class)] - # sorting bits - for j in range(self.num_class): - lits = [ctvars[k][j] for k in range(num_tree)] - clauses, vout, _ = HSorNetwrk(lits=lits, vpool=self.vpool) - self.cnf.extend(clauses) - sorted_lits[j] = vout - print("{0}:{2} => {1}".format(j, vout, lits)) - # compare bits - for j in range(self.cmaj): - - for j in range(self.cmaj + 1, self.num_class): - for k in range(num_tree): - self.cnf.append([-sorted_lits[j][k], sorted_lits[self.cmaj][k]]) # (v1 => v2) - # print("-{0} => {1}".format(sorted_lits[j][k], sorted_lits[self.cmaj][k])) - - ''' - # enforce exactly one of the feature values to be chosen - # (for categorical features) - categories = collections.defaultdict(lambda: []) - for f in self.extended_feature_names: - if '_' in f: - categories[f.split('_')[0]].append(self.newVar(f)) - - for c, feats in six.iteritems(categories): - #ExactlyOne feat is True - self.cnf.append(feats) - enc = CardEnc.atmost(lits=feats, vpool=self.vpool, encoding=EncType.cardnetwrk) - self.cnf.extend(enc.clauses) - ''' - for cl in self.cnf: - print("{0} == {1}".format(cl, - [self.vpool.obj(abs(p)) if p > 0 else "!" + str(self.vpool.obj(abs(p))) for p in - cl])) - - # if self.optns.verb: - # number of variables - print('#vars:', self.cnf.nv) - # number of clauses - print('#clauses:', len(self.cnf.clauses)) - # print(self.cnf.clauses) - - return self.cnf, self.intvs, self.imaps, self.ivars - - -# -# ============================================================================== -class SATExplainer(object): - """ - An SAT-inspired minimal explanation extractor for Random Forest models. - """ - - def __init__(self, sat_enc, inps, preamble, target_name): - """ - Constructor. - """ - - self.enc = sat_enc - # self.optns = options - self.inps = inps # input (feature value) variables - self.target_name = target_name - self.preamble = preamble - - self.verbose = True # self.optns.verb - # self.slv = Solver(name=options.solver) - self.slv = Solver(name="minisat22") - - # CNF formula - self.slv.append_formula(self.enc.cnf) - - # current selector - # self.selv = None - - def explain(self, sample, smallest=False): - """ - Hypotheses minimization. - """ - if self.verbose: - print( - ' explaining: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.target_name[self.enc.cmaj])) - - self.time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - - # adapt the solver to deal with the current sample - self.assums = [] # var selectors to be used as assumptions - self.sel2fid = {} # selectors to original feature ids - self.sel2vid = {} # selectors to categorical feature ids - - # preparing the selectors - for i, (inp, val) in enumerate(zip(self.inps, sample), 1): - feat = inp.split('_')[0] - selv = self.enc.newVar('selv_{0}'.format(feat)) - - self.assums.append(selv) - if selv not in self.sel2fid: - self.sel2fid[selv] = int(feat[1:]) - self.sel2vid[selv] = [i - 1] - else: - self.sel2vid[selv].append(i - 1) - - if not self.enc.intvs: - for inp, val, sel in zip(self.inps, sample, self.assums): - p = self.enc.newVar(inp) - hypo = [-sel, p if val else -p] - print("{0} => {1}".format(self.enc.vpool.obj(sel), inp if val else "!" + inp)) - self.slv.add_clause(hypo) - else: - raise NotImplementedError('Intervals are not supported.') - - self.assums = sorted(set(self.assums)) - # print("selctors: ", self.assums) - - self.slv.solve(assumptions=self.assums) - print("Model1:") - for p in self.slv.get_model(): - # if self.enc.vpool.obj(abs(p)) :and self.enc.vpool.obj(abs(p)) in self.inps: - if self.enc.vpool.obj(abs(p)) and "class" in self.enc.vpool.obj(abs(p)): - print((p, self.enc.vpool.obj(abs(p)))) - print(self.slv.get_model()) - - # forcing a misclassification, i.e. a wrong observation - for k in range(len(self.enc.forest.trees)): - cl = [] - for j in range(self.enc.num_class): - if j != self.enc.cmaj: - cl.append(self.enc.newVar('class{0}_tr{1}'.format(j, k))) - self.slv.add_clause(cl) - - # if satisfiable, then the observation is not implied by the hypotheses - if self.slv.solve(assumptions=self.assums): - print(' no implication!') - print(self.slv.get_model()) - # print("Model: {0}".format([ (p, self.enc.vpool.obj(abs(p))) for p in self.slv.get_model()])) - sys.exit(1) - - if not smallest: - self.compute_minimal() - else: - raise NotImplementedError('Smallest explanation is not yet implemented.') - # self.compute_smallest() - - self.time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - self.time - - expl = sorted([self.sel2fid[h] for h in self.assums if h > 0]) - print("expl-selctors: ", expl) - - if self.verbose: - self.preamble = [self.preamble[i] for i in expl] - # print("cmaj: ", self.enc.cmaj) - print( - ' explanation: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.target_name[self.enc.cmaj])) - print(' # hypos left:', len(self.assums)) - print(' time: {0:.2f}'.format(self.time)) - - return expl - - def compute_minimal(self): - """ - Compute any subset-minimal explanation. - """ - i = 0 - # simple deletion-based linear search - for i, p in enumerate(self.assums): - to_test = self.assums[:i] + self.assums[(i + 1):] + [-p] - # print(to_test) - if self.slv.solve(assumptions=to_test): - self.assums[i] = -p - print("Model:") - for p in self.slv.get_model(): - if self.enc.vpool.obj(abs(p)) and self.enc.vpool.obj(abs(p)) in self.inps: - print((p, self.enc.vpool.obj(abs(p)))) diff --git a/pages/application/RandomForest/utils/xrf/archive/setup.py b/pages/application/RandomForest/utils/xrf/archive/setup.py deleted file mode 100644 index 15c6427..0000000 --- a/pages/application/RandomForest/utils/xrf/archive/setup.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 - -from distutils.core import setup, Extension - -pysortn_ext = Extension('pysortnetwrk', - sources=['pysortnetwrk.cc'], - include_dirs=['sortcard'], - language='c++') - -setup(name='pysortnetwrk', - version='1.0', - description='This module provides a sorting network to sort a vector of bits', - py_modules=['pysortnetwrk'], - ext_modules=[pysortn_ext]) diff --git a/pages/application/RandomForest/utils/xrf/archive/sortcard.hh b/pages/application/RandomForest/utils/xrf/archive/sortcard.hh deleted file mode 100644 index e641050..0000000 --- a/pages/application/RandomForest/utils/xrf/archive/sortcard.hh +++ /dev/null @@ -1,298 +0,0 @@ - -#ifndef SORTCARD_HH_ -#define SORTCARD_HH_ - -#include <vector> -#include <algorithm> -#include <vector> -#include <ostream> - - -#define NOPTCLS true - - -using namespace std; - -class ClauseSet { -public: - ClauseSet() : clauses(0) {} - ClauseSet(ClauseSet& orig) : clauses(orig.clauses) {} - - void clear() - { - clauses.clear(); - } - - size_t size() - { - return clauses.size(); - } - - void resize(size_t sz_new) - { - return clauses.resize(sz_new); - } - - vector<int>& operator[](size_t i) - { - return clauses[i]; - } - - void erase(vector<int>& cl) - { - clauses.erase(std::find(clauses.begin(), clauses.end(), cl)); - } - - void erase_subset(size_t start, ClauseSet& clset) - { - if (clset.size()) { - vector<int>& cl_first = clset[0]; - vector<vector<int> >::iterator begin = std::find(clauses.begin() + start, clauses.end(), cl_first); - clauses.erase(begin, begin + clset.size()); - } - } - - vector<vector<int> >& get_clauses() - { - return clauses; - } - - void add_clause(vector<int> cl) - { - clauses.push_back(cl); - } - - void add_clause_ref(vector<int>& cl) - { - clauses.push_back(cl); - } - - void create_clause(vector<int>& cl) - { - add_clause(cl); - } - - void create_unit_clause(int l) - { - vector<int> cl; cl.push_back(l); - clauses.push_back(cl); - } - - void create_binary_clause(int l1, int l2) - { - vector<int> cl; - cl.push_back(l1); - cl.push_back(l2); - - clauses.push_back(cl); - } - - void create_ternary_clause(int l1, int l2, int l3) - { - vector<int> cl; - cl.push_back(l1); - cl.push_back(l2); - cl.push_back(l3); - - clauses.push_back(cl); - } - - void dump(ostream& out) - { - for (size_t i = 0; i < clauses.size(); ++i) - dump_clause(out, clauses[i]); - } -private: - void dump_clause(ostream& out, vector<int>& cl) - { - for (size_t i = 0; i < cl.size(); ++i) - out << cl[i] << " "; - out << "0" << endl; - } -protected: - vector<vector<int> > clauses; -}; - - - -// -//============================================================================= -inline void create_vvect(int& top_id, vector<int>& ov, size_t nvars) -{ - assert(nvars > 0); - - size_t refnv = ov.size(); - size_t tvars = refnv + nvars; - ov.resize(tvars, 0); - - for (size_t k = refnv; k < tvars; ++k) - ov[k] = ++top_id; - - assert(ov.size() > 0); -} - - -// -//============================================================================= -inline void copy_vvect(int& top_id, vector<int>& ov, vector<int>& iv) -{ - size_t refnv = ov.size(); - ov.resize(refnv + iv.size(), 0); - - for (size_t k = 0; k < iv.size(); ++k) - ov[refnv + k] = iv[k]; - - assert(ov.size() > 0); -} - - - -// -//============================================================================= -inline void mk_half_vect(vector<int>& ov, vector<int>& iv, size_t offset) -{ - assert(iv.size() > 0); - - size_t ns = iv.size() / 2; - ov.resize(ns, 0); - - for (size_t k = 0; k < ns; ++k) - ov[k] = iv[offset + k]; -} - -// -//============================================================================= -inline void mk_odd_vect(vector<int>& ov, vector<int>& iv) -{ - assert(iv.size() > 0); - - size_t ns = iv.size() / 2; - ov.resize(ns, 0); - - for (size_t k = 0; k < ns; ++k) - ov[k] = iv[k * 2]; -} - -//============================================================================= -inline void mk_even_vect(vector<int>& ov, vector<int>& iv) -{ - assert(iv.size() > 0); - - size_t ns = iv.size() / 2; - ov.resize(ns, 0); - - for (size_t k = 0; k < ns; ++k) - ov[k] = iv[k * 2 + 1]; -} - -// sorting networks -//============================================================================= -inline void sortn_half_merge_recur( - int& top_id, - ClauseSet& clset, - vector<int>& av, - vector<int>& bv, - vector<int>& cv, - size_t zvar -) -{ - assert(bv.size() == av.size()); - - if (av.size() == 1) { // vectors of size 1 - assert(av[0] != 0); - if (NOPTCLS || (av[0] != zvar && bv[0] != zvar)) { - create_vvect(top_id, cv, 2); - clset.create_binary_clause (-av[0], cv[0]); - clset.create_binary_clause (-bv[0], cv[0]); - clset.create_ternary_clause(-av[0], -bv[0], cv[1]); - } - else { - if (av[0] == zvar) { - cv.push_back(bv[0]); - cv.push_back(av[0]); - } - else { - assert(bv[0] == zvar); - cv.push_back(av[0]); - cv.push_back(bv[0]); - } - } - } - else { - if (NOPTCLS || - ((av[0] != zvar || av[av.size() - 1] != zvar) && - (bv[0] != zvar || bv[av.size() - 1] != zvar))) { - vector<int> aodd, aeven, bodd, beven, dv, ev; - - mk_odd_vect(aodd, av); mk_even_vect(aeven, av); - mk_odd_vect(bodd, bv); mk_even_vect(beven, bv); - - sortn_half_merge_recur(top_id, clset, aodd, bodd, dv, zvar); - sortn_half_merge_recur(top_id, clset, aeven, beven, ev, zvar); - - assert(cv.size() == 0); - cv.push_back(dv[0]); - create_vvect(top_id, cv, 2 * av.size() - 2); - cv.push_back(ev[ev.size() - 1]); - - for (size_t i = 0; i < av.size() - 1; ++i) { - assert(i + 1 < dv.size()); - assert(i < ev.size()); - assert(2 * 1 + 1 < cv.size()); - - clset.create_binary_clause (-dv[i + 1], cv[2 * i + 1]); - clset.create_binary_clause (-ev[i ], cv[2 * i + 1]); - clset.create_ternary_clause(-dv[i + 1], -ev[i], cv[2 * i + 2]); - } - } - else { - if (av[0] == zvar && av[av.size() - 1] == zvar) { - copy_vvect(top_id, cv, bv); - copy_vvect(top_id, cv, av); - } - else { - assert(bv[0] == zvar && bv[av.size() - 1] == zvar); - copy_vvect(top_id, cv, av); - copy_vvect(top_id, cv, bv); - } - } - } - - assert(cv.size() > 0); -} - -// -//============================================================================= -inline vector<int>& sortn_half_sorter_recur( - int& top_id, - ClauseSet& clset, - vector<int>& av, - vector<int>& cv, - size_t zvar -) -{ - assert(av.size() > 1); - - if (av.size() == 2) { - assert(av[0] != 0 && av[1] != 0); - - vector<int> xav, xbv; xav.push_back(av[0]); xbv.push_back(av[1]); - sortn_half_merge_recur(top_id, clset, xav, xbv, cv, zvar); - } - else { - vector<int> dv1, dv2, lav, uav; - mk_half_vect(lav, av, 0); - mk_half_vect(uav, av, av.size() / 2); - - assert(lav.size() == uav.size()); - sortn_half_sorter_recur(top_id, clset, lav, dv1, zvar); assert(dv1.size() > 0); - sortn_half_sorter_recur(top_id, clset, uav, dv2, zvar); assert(dv2.size() > 0); - sortn_half_merge_recur (top_id, clset, dv1, dv2, cv, zvar); - } - - assert(cv.size() > 0); - return cv; -} - - -#endif // SORTCARD_HH_ diff --git a/pages/application/RandomForest/utils/xrf/archive/sortnetwrk.py b/pages/application/RandomForest/utils/xrf/archive/sortnetwrk.py deleted file mode 100644 index f18c26e..0000000 --- a/pages/application/RandomForest/utils/xrf/archive/sortnetwrk.py +++ /dev/null @@ -1,74 +0,0 @@ -#!/usr/bin/env python3 -# -from math import exp, log, trunc - -from pysat._utils import MainThread -from pysat.formula import CNF, IDPool -import pysortnetwrk - - - -def HSorNetwrk(lits, top_id=None, vpool=None): - assert not top_id or not vpool, \ - 'Use either a top id or a pool of variables but not both.' - - - # we are going to return this formula - #ret = CNF() - - # if the list of literals is empty, return empty formula - if not lits: - return ret - - # obtaining the top id from the variable pool - if vpool: - top_id = vpool.top - - - # making sure we are dealing with a list of literals - lits = list(lits) - - # choosing the maximum id among the current top and the list of literals - top_id = max(map(lambda x: abs(x), lits + [top_id if top_id != None else 0])) - - - nvars = len(lits) - - #get smallest power of 2 larger than number of vars - exponent = trunc(log(nvars) / log(2)) # assume exponent - nvtmp = exp(log(2) * exponent) - - # check if number of vars already is power of 2; correct exponent if required - exponent = exponent if (nvars - nvtmp < 0.000001) else exponent + 1 - nnvars = trunc(exp(log(2) * exponent) + 0.1) - - cl = None - zvar = 0 - if (nnvars != nvars): - top_id += 1 - zvar = top_id - lits.extend([zvar] * (nnvars - nvars)) - cl = [-zvar] - - # generate odd-even sorting network - clset,slits,top = pysortnetwrk.HSort(lits, top_id, zvar, int(MainThread.check())) - - clset = clset +[cl] if (cl is not None) else clset - - - # updating vpool if necessary - if vpool: - vpool.top = top - 1 - vpool._next() - - - - return clset, slits, top - -if __name__ == '__main__': - print("Sorting Network:") - lits = [1, 2, 3] - top_id = 5 - clauses, slits, top = HSorNetwrk(lits, top_id) - print(clauses) - print(slits) \ No newline at end of file diff --git a/pages/application/RandomForest/utils/xrf/archive/tree.py b/pages/application/RandomForest/utils/xrf/archive/tree.py deleted file mode 100644 index 9e37945..0000000 --- a/pages/application/RandomForest/utils/xrf/archive/tree.py +++ /dev/null @@ -1,154 +0,0 @@ -# -#============================================================================== -from anytree import Node, RenderTree,AsciiStyle -import json -import numpy as np -import math -import os - - -# -#============================================================================== -class xgnode(Node): - def __init__(self, id, parent = None): - Node.__init__(self, id, parent) - self.id = id # The node value - self.name = None - self.left_node_id = -1 # Left child - self.right_node_id = -1 # Right child - - self.feature = -1 - self.threshold = None - self.values = -1 - #iai - #self.split = None - - def __str__(self): - pref = ' ' * self.depth - if (len(self.children) == 0): - return (pref+ "leaf: {} {}".format(self.id, self.values)) - else: - if(self.name is None): - return (pref+ "{} f{}<{}".format(self.id, self.feature, self.threshold)) - else: - return (pref+ "{} \"{}\"<{}".format(self.id, self.name, self.threshold)) - - -#============================================================================== -def build_tree(tree_, feature_names = None): - ## - feature = tree_.feature - threshold = tree_.threshold - values = tree_.value - n_nodes = tree_.node_count - children_left = tree_.children_left - children_right = tree_.children_right - node_depth = np.zeros(shape=n_nodes, dtype=np.int64) - is_leaf = np.zeros(shape=n_nodes, dtype=bool) - stack = [(0, -1)] # seed is the root node id and its parent depth - while len(stack) > 0: - node_id, parent_depth = stack.pop() - node_depth[node_id] = parent_depth + 1 - - # If we have a test node - if (children_left[node_id] != children_right[node_id]): - stack.append((children_left[node_id], parent_depth + 1)) - stack.append((children_right[node_id], parent_depth + 1)) - else: - is_leaf[node_id] = True - ## - - m = tree_.node_count - assert (m > 0), "Empty tree" - - def extract_data(idx, root = None, feature_names = None): - i = idx - assert (i < m), "Error index node" - if (root is None): - node = xgnode(i) - else: - node = xgnode(i, parent = root) - #node.cover = json_node["cover"] - if is_leaf[i]: - node.values = np.argmax(values[i]) - #if(inverse): - # node.values = -node.values - else: - node.feature = feature[i] - if (feature_names is not None): - node.name = feature_names[feature[i]] - node.threshold = threshold[i] - node.left_node_id = children_left[i] - node.right_node_id = children_right[i] - extract_data(node.left_node_id, node, feature_names) #feat < 0.5 (False) - extract_data(node.right_node_id, node, feature_names) #feat > 0.% (True) - - return node - - root = extract_data(0, None, feature_names) - - return root - - -#============================================================================== -def walk_tree(node): - if (len(node.children) == 0): - # leaf - print(node) - else: - print(node) - walk_tree(node.children[0]) - walk_tree(node.children[1]) - -# -#============================================================================== -def predict_tree(node, sample): - if (len(node.children) == 0): - # leaf - return node.values - else: - feature_branch = node.feature - sample_value = sample[feature_branch] - assert(sample_value is not None) - if(sample_value < node.threshold): - return predict_tree(node.children[0], sample) - else: - return predict_tree(node.children[1], sample) - - -# -#============================================================================== -class Forest: - """ An ensemble of decision trees. - - This object provides a common interface to many different types of models. - """ - def __init__(self, rf, feature_names = None): - self.rf = rf - ##self.feature_names = feature_names - self.trees = [ build_tree(dt.tree_, feature_names) for dt in self.rf.estimators()] - #self.print_trees() - - def print_trees(self): - for i,t in enumerate(self.trees): - print("tree number: ", i) - walk_tree(t) - - def predict(self, samples): - predictions = [] - n_estimators = self.rf.n_estimators() - print("#Trees: ", n_estimators) - for sample in np.asarray(samples): - scores = [] - for i,t in enumerate(self.trees): - s = predict_tree(t, sample) - scores.append((s)) - scores = np.asarray(scores) - predictions.append(scores) - predictions = np.asarray(predictions) - #print(predictions) - #np.bincount(x, weights=self._weights_not_none) - maj = np.apply_along_axis(lambda x: np.argmax(np.bincount(x)), axis=1, arr=predictions) - - return maj - diff --git a/pages/application/RandomForest/utils/xrf/rndmforest.py b/pages/application/RandomForest/utils/xrf/rndmforest.py index 583fe91..187dd28 100644 --- a/pages/application/RandomForest/utils/xrf/rndmforest.py +++ b/pages/application/RandomForest/utils/xrf/rndmforest.py @@ -1,4 +1,3 @@ - from sklearn.ensemble._voting import VotingClassifier from sklearn.ensemble import RandomForestClassifier from sklearn.preprocessing import OneHotEncoder, LabelEncoder @@ -16,132 +15,54 @@ import math from pages.application.RandomForest.utils.data import Data from .tree import Forest, predict_tree -#from .encode import SATEncoder +# from .encode import SATEncoder from pysat.formula import CNF, IDPool from pysat.solvers import Solver from pysat.card import CardEnc, EncType from itertools import combinations - - # -#============================================================================== +# ============================================================================== class Dataset(Data): """ Class for representing dataset (transactions). """ - def __init__(self, filename=None, fpointer=None, mapfile=None, - separator=' ', use_categorical = False): - super().__init__(filename, fpointer, mapfile, separator, use_categorical) - + + def __init__(self, file=None, mapfile=None, separator=',', use_categorical=False): + super().__init__(file, mapfile, separator, use_categorical) + # split data into X and y self.feature_names = self.names[:-1] self.nb_features = len(self.feature_names) self.use_categorical = use_categorical - + samples = np.asarray(self.samps) - if not all(c.isnumeric() for c in samples[:, -1]): + if not all(c.isnumeric() for c in samples[:, -1]): le = LabelEncoder() le.fit(samples[:, -1]) - samples[:, -1]= le.transform(samples[:, -1]) - #self.class_names = le.classes_ - print(le.classes_) - print(samples[1:4, :]) - + samples[:, -1] = le.transform(samples[:, -1]) + # self.class_names = le.classes_ + samples = np.asarray(samples, dtype=np.float32) self.X = samples[:, 0: self.nb_features] self.y = samples[:, self.nb_features] self.num_class = len(set(self.y)) - self.target_name = list(range(self.num_class)) - - print("c nof features: {0}".format(self.nb_features)) - print("c nof classes: {0}".format(self.num_class)) - print("c nof samples: {0}".format(len(self.samps))) - + self.target_name = list(range(self.num_class)) + # check if we have info about categorical features if (self.use_categorical): - self.target_name = self.class_names - + self.target_name = self.class_names + self.binarizer = {} for i in self.categorical_features: - self.binarizer.update({i: OneHotEncoder(categories='auto', sparse=False)})#, - self.binarizer[i].fit(self.X[:,[i]]) + self.binarizer.update({i: OneHotEncoder(categories='auto', sparse=False)}) # , + self.binarizer[i].fit(self.X[:, [i]]) else: self.categorical_features = [] - self.categorical_names = [] - self.binarizer = [] - #feat map - self.mapping_features() - - - - def train_test_split(self, test_size=0.2, seed=0): - return train_test_split(self.X, self.y, test_size=test_size, random_state=seed) - - - def transform(self, x): - if(len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert(self.binarizer != []) - tx = [] - for i in range(self.nb_features): - #self.binarizer[i].drop = None - if (i in self.categorical_features): - self.binarizer[i].drop = None - tx_aux = self.binarizer[i].transform(x[:,[i]]) - tx_aux = np.vstack(tx_aux) - tx.append(tx_aux) - else: - tx.append(x[:,[i]]) - tx = np.hstack(tx) - return tx - else: - return x - - def transform_inverse(self, x): - if(len(x) == 0): - return x - if (len(x.shape) == 1): - x = np.expand_dims(x, axis=0) - if (self.use_categorical): - assert(self.binarizer != []) - inverse_x = [] - for i, xi in enumerate(x): - inverse_xi = np.zeros(self.nb_features) - for f in range(self.nb_features): - if f in self.categorical_features: - nb_values = len(self.categorical_names[f]) - v = xi[:nb_values] - v = np.expand_dims(v, axis=0) - iv = self.binarizer[f].inverse_transform(v) - inverse_xi[f] =iv - xi = xi[nb_values:] - - else: - inverse_xi[f] = xi[0] - xi = xi[1:] - inverse_x.append(inverse_xi) - return inverse_x - else: - return x - - def transform_inverse_by_index(self, idx): - if (idx in self.extended_feature_names): - return self.extended_feature_names[idx] - else: - print("Warning there is no feature {} in the internal mapping".format(idx)) - return None - - def transform_by_value(self, feat_value_pair): - if (feat_value_pair in self.extended_feature_names.values()): - keys = (list(self.extended_feature_names.keys())[list( self.extended_feature_names.values()).index(feat_value_pair)]) - return keys - else: - print("Warning there is no value {} in the internal mapping".format(feat_value_pair)) - return None + self.categorical_names = [] + self.binarizer = [] + # feat map + self.mapping_features() def mapping_features(self): self.extended_feature_names = {} @@ -151,17 +72,18 @@ class Dataset(Data): for i in range(self.nb_features): if (i in self.categorical_features): for j, _ in enumerate(self.binarizer[i].categories_[0]): - self.extended_feature_names.update({counter: (self.feature_names[i], j)}) - self.extended_feature_names_as_array_strings.append("f{}_{}".format(i,j)) # str(self.feature_names[i]), j)) + self.extended_feature_names.update({counter: (self.feature_names[i], j)}) + self.extended_feature_names_as_array_strings.append( + "f{}_{}".format(i, j)) # str(self.feature_names[i]), j)) counter = counter + 1 else: self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i)) #(self.feature_names[i]) + self.extended_feature_names_as_array_strings.append("f{}".format(i)) # (self.feature_names[i]) counter = counter + 1 else: for i in range(self.nb_features): self.extended_feature_names.update({counter: (self.feature_names[i], None)}) - self.extended_feature_names_as_array_strings.append("f{}".format(i))#(self.feature_names[i]) + self.extended_feature_names_as_array_strings.append("f{}".format(i)) # (self.feature_names[i]) counter = counter + 1 def readable_sample(self, x): @@ -173,42 +95,43 @@ class Dataset(Data): readable_x.append(v) return np.asarray(readable_x) - - def test_encoding_transformes(self, X_train): - # test encoding - - X = X_train[[0],:] - - print("Sample of length", len(X[0])," : ", X) - enc_X = self.transform(X) - print("Encoded sample of length", len(enc_X[0])," : ", enc_X) - inv_X = self.transform_inverse(enc_X) - print("Back to sample", inv_X) - print("Readable sample", self.readable_sample(inv_X[0])) - assert((inv_X == X).all()) + def transform(self, x): + if(len(x) == 0): + return x + if (len(x.shape) == 1): + x = np.expand_dims(x, axis=0) + if (self.use_categorical): + assert(self.binarizer != []) + tx = [] + for i in range(self.nb_features): + #self.binarizer[i].drop = None + if (i in self.categorical_features): + self.binarizer[i].drop = None + tx_aux = self.binarizer[i].transform(x[:,[i]]) + tx_aux = np.vstack(tx_aux) + tx.append(tx_aux) + else: + tx.append(x[:,[i]]) + tx = np.hstack(tx) + return tx + else: + return x - ''' - for i in range(len(self.extended_feature_names)): - print(i, self.transform_inverse_by_index(i)) - for key, value in self.extended_feature_names.items(): - print(value, self.transform_by_value(value)) - ''' # -#============================================================================== +# ============================================================================== class VotingRF(VotingClassifier): """ Majority rule classifier """ - + def fit(self, X, y, sample_weight=None): self.estimators_ = [] for _, est in self.estimators: self.estimators_.append(est) - + self.le_ = LabelEncoder().fit(y) - self.classes_ = self.le_.classes_ - - + self.classes_ = self.le_.classes_ + def predict(self, X): """Predict class labels for X. Parameters @@ -220,23 +143,23 @@ class VotingRF(VotingClassifier): maj : array-like of shape (n_samples,) Predicted class labels. """ - #check_is_fitted(self) - + # check_is_fitted(self) + # 'hard' voting predictions = self._predict(X) - predictions = np.asarray(predictions, np.int64) #NEED TO BE CHECKED + predictions = np.asarray(predictions, np.int64) # NEED TO BE CHECKED maj = np.apply_along_axis( lambda x: np.argmax( np.bincount(x, weights=self._weights_not_none)), axis=1, arr=predictions) - + maj = self.le_.inverse_transform(maj) return maj - - + + # -#============================================================================== +# ============================================================================== class RF2001(object): """ The main class to train Random Forest Classifier (RFC). @@ -245,155 +168,68 @@ class RF2001(object): def __init__(self, options): """ Constructor. - """ + """ self.forest = None self.voting = None self.opt = options - - param_dist = {'n_estimators':options.n_estimators, - 'max_depth':options.maxdepth, - 'criterion':'entropy', - 'random_state':324089} - + + param_dist = {'n_estimators': options.n_estimators, + 'max_depth': options.maxdepth, + 'criterion': 'entropy', + 'random_state': 324089} + self.forest = RandomForestClassifier(**param_dist) - - - - def train(self, dataset, outfile=None): - """ - Train a random forest. - """ - - X_train, X_test, y_train, y_test = dataset.train_test_split() - - if self.opt.verb: - dataset.test_encoding_transformes(X_train) - - X_train = dataset.transform(X_train) - X_test = dataset.transform(X_test) - - print("Build a random forest.") - self.forest.fit(X_train,y_train) - - rtrees = [ ('dt', dt) for i, dt in enumerate(self.forest.estimators_)] - self.voting = VotingRF(estimators=rtrees) - self.voting.fit(X_train,y_train) - - ''' - print(X_test[[0],:]) - print("RF: ",np.asarray(self.voting.predict(X_test[[0],:]))) - for i,t in enumerate(self.forest.estimators_): - print("DT_{0}: {1}".format(i,np.asarray(t.predict(X_test[[0],:])))) - ''' - - train_acc = accuracy_score(self.predict(X_train), y_train) - test_acc = accuracy_score(self.predict(X_test), y_test) - - if self.opt.verb > 1: - self.print_acc_vote(X_train, X_test, y_train, y_test) - self.print_acc_prob(X_train, X_test, y_train, y_test) - - return train_acc, test_acc - + def predict(self, X): return self.voting.predict(X) - + def predict_prob(self, X): self.forest.predict(X) - + def estimators(self): - assert(self.forest.estimators_ is not None) + assert (self.forest.estimators_ is not None) return self.forest.estimators_ - + def n_estimators(self): return self.forest.n_estimators - - def print_acc_vote(self, X_train, X_test, y_train, y_test): - train_acc = accuracy_score(self.predict(X_train), y_train) - test_acc = accuracy_score(self.predict(X_test), y_test) - print("----------------------") - print("RF2001:") - print("Train accuracy RF2001: {0:.2f}".format(100. * train_acc)) - print("Test accuracy RF2001: {0:.2f}".format(100. * test_acc)) - print("----------------------") - - def print_acc_prob(self, X_train, X_test, y_train, y_test): - train_acc = accuracy_score(self.forest.predict(X_train), y_train) - test_acc = accuracy_score(self.forest.predict(X_test), y_test) - print("RF-scikit:") - print("Train accuracy RF-scikit: {0:.2f}".format(100. * train_acc)) - print("Test accuracy RF-scikit: {0:.2f}".format(100. * test_acc)) - print("----------------------") - - def print_accuracy(self, data): - _, X_test, _, y_test = data.train_test_split() - #X_train = dataset.transform(X_train) - X_test = data.transform(X_test) - test_acc = accuracy_score(self.predict(X_test), y_test) - #print("----------------------") - #print("Train accuracy : {0:.2f}".format(100. * train_acc)) - #print("Test accuracy : {0:.2f}".format(100. * test_acc)) - print("c Cross-Validation: {0:.2f}".format(100. * test_acc)) - #print("----------------------") + + # -#============================================================================== +# ============================================================================== class XRF(object): """ class to encode and explain Random Forest classifiers. """ - - def __init__(self, options, model, dataset): + + def __init__(self, model, dataset): self.cls = model self.data = dataset - self.verbose = options.verb - self.f = Forest(model, dataset.extended_feature_names_as_array_strings) - - if options.verb > 2: - self.f.print_trees() - print("c RF sz:", self.f.sz) - print('c max-depth:', self.f.md) - print('c nof DTs:', len(self.f.trees)) - - + self.forest = Forest(model, dataset.extended_feature_names_as_array_strings) + + self.enc = SATEncoder(self.forest, self.data.feature_names, self.data.num_class, + self.data.extended_feature_names_as_array_strings) + def encode(self, inst): """ Encode a tree ensemble trained previously. """ if 'f' not in dir(self): self.f = Forest(self.cls, self.data.extended_feature_names_as_array_strings) - #self.f.print_tree() - - time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - - self.enc = SATEncoder(self.f, self.data.feature_names, self.data.num_class, \ - self.data.extended_feature_names_as_array_strings) - + + self.enc = SATEncoder(self.forest, self.data.feature_names, self.data.num_class, + self.data.extended_feature_names_as_array_strings) + inst = self.data.transform(np.array(inst))[0] formula, _, _, _ = self.enc.encode(inst) - - time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - time - - if self.verbose: - print('c nof vars:', formula.nv) # number of variables - print('c nof clauses:', len(formula.clauses)) # number of clauses - print('c encoding time: {0:.3f}'.format(time)) - - def explain(self, inst): + + def explain_sample(self, inst): """ Explain a prediction made for a given sample with a previously trained RF. """ - - time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - + if 'enc' not in dir(self): self.encode(inst) - - #if self.verbose: - # print("instance: {0}".format(np.array(inst)) ) inpvals = self.data.readable_sample(inst) preamble = [] @@ -402,73 +238,96 @@ class XRF(object): preamble.append('{0} = {1}'.format(f, v)) else: preamble.append(v) - - inps = self.data.extended_feature_names_as_array_strings # input (feature value) variables - #print("inps: {0}".format(inps)) - - self.x = SATExplainer(self.enc, inps, preamble, self.data.target_name, verb=self.verbose) - inst = self.data.transform(np.array(inst))[0] + + inps = self.data.extended_feature_names_as_array_strings # input (feature value) variables + # print("inps: {0}".format(inps)) + + self.x = SATExplainer(self.enc, inps, preamble, self.data.target_name) + inst = self.data.transform(np.array(inst))[0] expl = self.x.explain(np.array(inst)) - time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - time - - if self.verbose: - print("c Total time: {0:.3f}".format(time)) - - return expl + return expl - - def test_tree_ensemble(self): - if 'f' not in dir(self): - self.f = Forest(self.cls) - - _, X_test, _, y_test = self.data.train_test_split() - X_test = self.data.transform(X_test) - - y_pred_forest = self.f.predict(X_test) - acc = accuracy_score(y_pred_forest, y_test) - print("Test accuracy: {0:.2f}".format(100. * acc)) - - y_pred_cls = self.cls.predict(X_test) - #print(np.asarray(y_pred_cls, np.int64)) - #print(y_pred_forest) - - assert((y_pred_cls == y_pred_forest).all()) - - -# -#============================================================================== + # copie de git + def explain(self, samples): + # timers + lengths = [] + tested = set() + mSAT, mUNSAT = 0.0, 0.0 + stimes = [] + utimes = [] + nSatCalls = [] + nUnsCalls = [] + + ltimes = [] + ctimes = [] + wins = 0 + + multiple_expls = [] + for i, s in enumerate(samples): + sample = [float(v.strip()) for v in s.split(',')] + + if tuple(sample) in tested: + continue + + # print("inst#{0}".format(i+1)) + + tested.add(tuple(sample)) + # print('sample {0}: {1}'.format(i, ','.join(s.strip().split(',')))) + + self.encode(sample) + expl = self.explain_sample(sample) + multiple_expls.append(expl) + lengths.append(len(expl)) + + nvars = self.enc.cnf.nv + nclauses = len(self.enc.cnf.clauses) + + # mSAT = max(xrf.x.stimes+[mSAT]) + # mUNSAT = max(xrf.x.utimes+[mUNSAT]) + if len(self.x.stimes): + stimes.append(max(self.x.stimes)) + if len(self.x.utimes): + utimes.append(max(self.x.utimes)) + nSatCalls.append(self.x.nsat) + nUnsCalls.append(self.x.nunsat) + + del self.enc + del self.x + + return multiple_expls + + + # ============================================================================== class SATEncoder(object): """ Encoder of Random Forest classifier into SAT. """ - - def __init__(self, forest, feats, nof_classes, extended_feature_names, from_file=None): + + def __init__(self, forest, feats, nof_classes, extended_feature_names, from_file=None): self.forest = forest - #self.feats = {f: i for i, f in enumerate(feats)} + # self.feats = {f: i for i, f in enumerate(feats)} self.num_class = nof_classes self.vpool = IDPool() self.extended_feature_names = extended_feature_names - - #encoding formula + + # encoding formula self.cnf = None # for interval-based encoding self.intvs, self.imaps, self.ivars, self.thvars = None, None, None, None - - + def newVar(self, name): - - if name in self.vpool.obj2id: #var has been already created + + if name in self.vpool.obj2id: # var has been already created return self.vpool.obj2id[name] - + var = self.vpool.id('{0}'.format(name)) return var - + def printLits(self, lits): - print(["{0}{1}".format("-" if p<0 else "",self.vpool.obj(abs(p))) for p in lits]) - + print(["{0}{1}".format("-" if p < 0 else "", self.vpool.obj(abs(p))) for p in lits]) + def traverse(self, tree, k, clause): """ Traverse a tree and encode each node. @@ -484,21 +343,20 @@ class SATEncoder(object): else: var = self.newVar(tree.name) pos, neg = var, -var - #print("{0} => {1}".format(tree.name, var)) - + # print("{0} => {1}".format(tree.name, var)) + assert (pos and neg) self.traverse(tree.children[0], k, clause + [-neg]) - self.traverse(tree.children[1], k, clause + [-pos]) + self.traverse(tree.children[1], k, clause + [-pos]) else: # leaf node - cvar = self.newVar('class{0}_tr{1}'.format(tree.values,k)) + cvar = self.newVar('class{0}_tr{1}'.format(tree.values, k)) self.cnf.append(clause + [cvar]) - #self.printLits(clause + [cvar]) + # self.printLits(clause + [cvar]) def compute_intervals(self): """ Traverse all trees in the ensemble and extract intervals for each feature. - At this point, the method only works for numerical datasets! """ @@ -521,9 +379,10 @@ class SATEncoder(object): for tree in self.forest.trees: traverse_intervals(tree) - + # OK, we got all intervals; let's sort the values - self.intvs = {f: sorted(self.intvs[f]) + ([math.inf] if len(self.intvs[f]) else []) for f in six.iterkeys(self.intvs)} + self.intvs = {f: sorted(self.intvs[f]) + ([math.inf] if len(self.intvs[f]) else []) for f in + six.iterkeys(self.intvs)} self.imaps, self.ivars = {}, {} self.thvars = {} @@ -536,195 +395,183 @@ class SATEncoder(object): ivar = self.newVar('{0}_intv{1}'.format(feat, i)) self.ivars[feat].append(ivar) - #print('{0}_intv{1}'.format(feat, i)) - + # print('{0}_intv{1}'.format(feat, i)) + if ub != math.inf: - #assert(i < len(intvs)-1) + # assert(i < len(intvs)-1) thvar = self.newVar('{0}_th{1}'.format(feat, i)) self.thvars[feat].append(thvar) - #print('{0}_th{1}'.format(feat, i)) - - + # print('{0}_th{1}'.format(feat, i)) def encode(self, sample): """ Do the job. """ - + ###print('Encode RF into SAT ...') self.cnf = CNF() # getting a tree ensemble - #self.forest = Forest(self.model, self.extended_feature_names) + # self.forest = Forest(self.model, self.extended_feature_names) num_tree = len(self.forest.trees) self.forest.predict_inst(sample) - #introducing class variables - #cvars = [self.newVar('class{0}'.format(i)) for i in range(self.num_class)] - + # introducing class variables + # cvars = [self.newVar('class{0}'.format(i)) for i in range(self.num_class)] + # define Tautology var vtaut = self.newVar('Tautology') - + # introducing class-tree variables ctvars = [[] for t in range(num_tree)] for k in range(num_tree): for j in range(self.num_class): - var = self.newVar('class{0}_tr{1}'.format(j,k)) - ctvars[k].append(var) + var = self.newVar('class{0}_tr{1}'.format(j, k)) + ctvars[k].append(var) - # traverse all trees and extract all possible intervals + # traverse all trees and extract all possible intervals # for each feature ###print("compute intervarls ...") self.compute_intervals() - - #print(self.intvs) - #print([len(self.intvs[f]) for f in self.intvs]) - #print(self.imaps) - #print(self.ivars) - #print(self.thvars) - #print(ctvars) - - + + # print(self.intvs) + # print([len(self.intvs[f]) for f in self.intvs]) + # print(self.imaps) + # print(self.ivars) + # print(self.thvars) + # print(ctvars) + ##print("encode trees ...") # traversing and encoding each tree for k, tree in enumerate(self.forest.trees): - #print("Encode tree#{0}".format(k)) - # encoding the tree + # print("Encode tree#{0}".format(k)) + # encoding the tree self.traverse(tree, k, []) # exactly one class var is true - #self.printLits(ctvars[k]) - card = CardEnc.atmost(lits=ctvars[k], vpool=self.vpool,encoding=EncType.cardnetwrk) + # self.printLits(ctvars[k]) + card = CardEnc.atmost(lits=ctvars[k], vpool=self.vpool, encoding=EncType.cardnetwrk) self.cnf.extend(card.clauses) - - - - # calculate the majority class - self.cmaj = self.forest.predict_inst(sample) - - ##print("encode majority class ...") - #Cardinality constraint AtMostK to capture a j_th class - - if(self.num_class == 2): + + # calculate the majority class + self.cmaj = self.forest.predict_inst(sample) + + ##print("encode majority class ...") + # Cardinality constraint AtMostK to capture a j_th class + + if (self.num_class == 2): rhs = math.floor(num_tree / 2) + 1 - if(self.cmaj==1 and not num_tree%2): - rhs = math.floor(num_tree / 2) + if (self.cmaj == 1 and not num_tree % 2): + rhs = math.floor(num_tree / 2) lhs = [ctvars[k][1 - self.cmaj] for k in range(num_tree)] - atls = CardEnc.atleast(lits = lhs, bound = rhs, vpool=self.vpool, encoding=EncType.cardnetwrk) + atls = CardEnc.atleast(lits=lhs, bound=rhs, vpool=self.vpool, encoding=EncType.cardnetwrk) self.cnf.extend(atls) - else: + else: zvars = [] - zvars.append([self.newVar('z_0_{0}'.format(k)) for k in range (num_tree) ]) - zvars.append([self.newVar('z_1_{0}'.format(k)) for k in range (num_tree) ]) + zvars.append([self.newVar('z_0_{0}'.format(k)) for k in range(num_tree)]) + zvars.append([self.newVar('z_1_{0}'.format(k)) for k in range(num_tree)]) ## rhs = num_tree - lhs0 = zvars[0] + [ - ctvars[k][self.cmaj] for k in range(num_tree)] + lhs0 = zvars[0] + [- ctvars[k][self.cmaj] for k in range(num_tree)] ##self.printLits(lhs0) - atls = CardEnc.atleast(lits = lhs0, bound = rhs, vpool=self.vpool, encoding=EncType.cardnetwrk) + atls = CardEnc.atleast(lits=lhs0, bound=rhs, vpool=self.vpool, encoding=EncType.cardnetwrk) self.cnf.extend(atls) ## - #rhs = num_tree - 1 + # rhs = num_tree - 1 rhs = num_tree + 1 ########### - lhs1 = zvars[1] + [ - ctvars[k][self.cmaj] for k in range(num_tree)] + lhs1 = zvars[1] + [- ctvars[k][self.cmaj] for k in range(num_tree)] ##self.printLits(lhs1) - atls = CardEnc.atleast(lits = lhs1, bound = rhs, vpool=self.vpool, encoding=EncType.cardnetwrk) - self.cnf.extend(atls) + atls = CardEnc.atleast(lits=lhs1, bound=rhs, vpool=self.vpool, encoding=EncType.cardnetwrk) + self.cnf.extend(atls) # pvars = [self.newVar('p_{0}'.format(k)) for k in range(self.num_class + 1)] ##self.printLits(pvars) - for k,p in enumerate(pvars): + for k, p in enumerate(pvars): for i in range(num_tree): if k == 0: z = zvars[0][i] - #self.cnf.append([-p, -z, vtaut]) - self.cnf.append([-p, z, -vtaut]) - #self.printLits([-p, z, -vtaut]) - #print() - elif k == self.cmaj+1: + # self.cnf.append([-p, -z, vtaut]) + self.cnf.append([-p, z, -vtaut]) + # self.printLits([-p, z, -vtaut]) + # print() + elif k == self.cmaj + 1: z = zvars[1][i] - self.cnf.append([-p, z, -vtaut]) - - #self.printLits([-p, z, -vtaut]) - #print() - + self.cnf.append([-p, z, -vtaut]) + + # self.printLits([-p, z, -vtaut]) + # print() + else: - z = zvars[0][i] if (k<self.cmaj+1) else zvars[1][i] - self.cnf.append([-p, -z, ctvars[i][k-1] ]) - self.cnf.append([-p, z, -ctvars[i][k-1] ]) - - #self.printLits([-p, -z, ctvars[i][k-1] ]) - #self.printLits([-p, z, -ctvars[i][k-1] ]) - #print() - + z = zvars[0][i] if (k < self.cmaj + 1) else zvars[1][i] + self.cnf.append([-p, -z, ctvars[i][k - 1]]) + self.cnf.append([-p, z, -ctvars[i][k - 1]]) + + # self.printLits([-p, -z, ctvars[i][k-1] ]) + # self.printLits([-p, z, -ctvars[i][k-1] ]) + # print() + # - self.cnf.append([-pvars[0], -pvars[self.cmaj+1]]) + self.cnf.append([-pvars[0], -pvars[self.cmaj + 1]]) ## - lhs1 = pvars[:(self.cmaj+1)] + lhs1 = pvars[:(self.cmaj + 1)] ##self.printLits(lhs1) - eqls = CardEnc.equals(lits = lhs1, bound = 1, vpool=self.vpool, encoding=EncType.cardnetwrk) + eqls = CardEnc.equals(lits=lhs1, bound=1, vpool=self.vpool, encoding=EncType.cardnetwrk) self.cnf.extend(eqls) - - + lhs2 = pvars[(self.cmaj + 1):] ##self.printLits(lhs2) - eqls = CardEnc.equals(lits = lhs2, bound = 1, vpool=self.vpool, encoding=EncType.cardnetwrk) + eqls = CardEnc.equals(lits=lhs2, bound=1, vpool=self.vpool, encoding=EncType.cardnetwrk) self.cnf.extend(eqls) - - - + ##print("exactly-one feat const ...") # enforce exactly one of the feature values to be chosen # (for categorical features) categories = collections.defaultdict(lambda: []) for f in self.extended_feature_names: if '_' in f: - categories[f.split('_')[0]].append(self.newVar(f)) + categories[f.split('_')[0]].append(self.newVar(f)) for c, feats in six.iteritems(categories): # exactly-one feat is True self.cnf.append(feats) card = CardEnc.atmost(lits=feats, vpool=self.vpool, encoding=EncType.cardnetwrk) self.cnf.extend(card.clauses) - # lits of intervals + # lits of intervals for f, intvs in six.iteritems(self.ivars): if not len(intvs): continue - self.cnf.append(intvs) + self.cnf.append(intvs) card = CardEnc.atmost(lits=intvs, vpool=self.vpool, encoding=EncType.cardnetwrk) self.cnf.extend(card.clauses) - #self.printLits(intvs) - - - + # self.printLits(intvs) + for f, threshold in six.iteritems(self.thvars): for j, thvar in enumerate(threshold): - d = j+1 - pos, neg = self.ivars[f][d:], self.ivars[f][:d] - + d = j + 1 + pos, neg = self.ivars[f][d:], self.ivars[f][:d] + if j == 0: - assert(len(neg) == 1) + assert (len(neg) == 1) self.cnf.append([thvar, neg[-1]]) self.cnf.append([-thvar, -neg[-1]]) else: - self.cnf.append([thvar, neg[-1], -threshold[j-1]]) - self.cnf.append([-thvar, threshold[j-1]]) + self.cnf.append([thvar, neg[-1], -threshold[j - 1]]) + self.cnf.append([-thvar, threshold[j - 1]]) self.cnf.append([-thvar, -neg[-1]]) - + if j == len(threshold) - 1: - assert(len(pos) == 1) + assert (len(pos) == 1) self.cnf.append([-thvar, pos[0]]) self.cnf.append([thvar, -pos[0]]) else: - self.cnf.append([-thvar, pos[0], threshold[j+1]]) + self.cnf.append([-thvar, pos[0], threshold[j + 1]]) self.cnf.append([thvar, -pos[0]]) - self.cnf.append([thvar, -threshold[j+1]]) - + self.cnf.append([thvar, -threshold[j + 1]]) - return self.cnf, self.intvs, self.imaps, self.ivars # -#============================================================================== +# ============================================================================== class SATExplainer(object): """ An SAT-inspired minimal explanation extractor for Random Forest models. @@ -734,125 +581,121 @@ class SATExplainer(object): """ Constructor. """ - + self.enc = sat_enc self.inps = inps # input (feature value) variables self.target_name = target_name self.preamble = preamble self.verbose = verb - - self.slv = None + + self.slv = None ##self.slv = Solver(name=options.solver) ##self.slv = Solver(name="minisat22") - #self.slv = Solver(name="glucose3") + # self.slv = Solver(name="glucose3") # CNF formula - #self.slv.append_formula(self.enc.cnf) + # self.slv.append_formula(self.enc.cnf) - def explain(self, sample, smallest=False): """ Hypotheses minimization. """ - if self.verbose: - print(' explaining: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.target_name[self.enc.cmaj])) - - #create a SAT solver - self.slv = Solver(name="glucose3") - - self.time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime + expl = {} + expl["Instance"] = '"IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.target_name[self.enc.cmaj]) + + # create a SAT solver + self.slv = Solver(name="glucose3") # adapt the solver to deal with the current sample - #self.csel = [] + # self.csel = [] self.assums = [] # var selectors to be used as assumptions self.sel2fid = {} # selectors to original feature ids self.sel2vid = {} # selectors to categorical feature ids - self.sel2v = {} # selectors to (categorical/interval) values - - #for i in range(self.enc.num_class): + self.sel2v = {} # selectors to (categorical/interval) values + + # for i in range(self.enc.num_class): # self.csel.append(self.enc.newVar('class{0}'.format(i))) - #self.csel = self.enc.newVar('class{0}'.format(self.enc.cmaj)) - + # self.csel = self.enc.newVar('class{0}'.format(self.enc.cmaj)) + # preparing the selectors for i, (inp, val) in enumerate(zip(self.inps, sample), 1): if '_' in inp: - + assert (inp not in self.enc.intvs) - + feat = inp.split('_')[0] selv = self.enc.newVar('selv_{0}'.format(feat)) - - self.assums.append(selv) + + self.assums.append(selv) if selv not in self.sel2fid: self.sel2fid[selv] = int(feat[1:]) self.sel2vid[selv] = [i - 1] else: self.sel2vid[selv].append(i - 1) - - p = self.enc.newVar(inp) + + p = self.enc.newVar(inp) if not val: p = -p else: self.sel2v[selv] = p - + self.enc.cnf.append([-selv, p]) - - #self.enc.printLits([-selv, p]) - + + # self.enc.printLits([-selv, p]) + elif len(self.enc.intvs[inp]): - #v = None - #for intv in self.enc.intvs[inp]: + # v = None + # for intv in self.enc.intvs[inp]: # if intv > val: # v = intv - # break - v = next((intv for intv in self.enc.intvs[inp] if intv > val), None) - assert(v is not None) - - selv = self.enc.newVar('selv_{0}'.format(inp)) - self.assums.append(selv) - + # break + v = next((intv for intv in self.enc.intvs[inp] if intv > val), None) + assert (v is not None) + + selv = self.enc.newVar('selv_{0}'.format(inp)) + self.assums.append(selv) + assert (selv not in self.sel2fid) self.sel2fid[selv] = int(inp[1:]) self.sel2vid[selv] = [i - 1] - - for j,p in enumerate(self.enc.ivars[inp]): + + for j, p in enumerate(self.enc.ivars[inp]): cl = [-selv] if j == self.enc.imaps[inp][v]: cl += [p] self.sel2v[selv] = p else: cl += [-p] - + self.enc.cnf.append(cl) - #self.enc.printLits(cl) + # self.enc.printLits(cl) ''' with open("/tmp/pendigits.cnf", 'w') as fp: fp.write('p cnf {0} {1}\n'.format(self.enc.cnf.nv, len(self.enc.cnf.clauses))) for p in self.assums + [-self.csel]: fp.write('{0} 0\n'.format(str(p))) - + for cl in self.enc.cnf.clauses: fp.write(' '.join([str(p) for p in cl+[0]])) fp.write('\n') fp.close() print(self.assums + [self.csel]) ''' - + self.assums = sorted(set(self.assums)) if self.verbose: - print(' # hypos:', len(self.assums)) - - # pass a CNF formula - self.slv.append_formula(self.enc.cnf) - + expl['hypos:'] = len(self.assums) + + # pass a CNF formula + self.slv.append_formula(self.enc.cnf) + ''' # if unsat, then the observation is not implied by the assumptions if not self.slv.solve(assumptions=self.assums+[self.csel]): print(' no implication!') print(self.slv.get_core()) sys.exit(1) - + if self.verbose > 1: self.enc.printLits(self.assums+[self.csel]) self.print_sat_model() @@ -862,26 +705,21 @@ class SATExplainer(object): self.compute_minimal() else: raise NotImplementedError('Smallest explanation is not yet implemented.') - #self.compute_smallest() + # self.compute_smallest() - self.time = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - self.time + explanation = sorted([self.sel2fid[h] for h in self.assums if h > 0]) + assert len(explanation), 'PI-explanation cannot be an empty-set! otherwise the RF predicts only one class' - expl = sorted([self.sel2fid[h] for h in self.assums if h>0 ]) - assert len(expl), 'PI-explanation cannot be an empty-set! otherwise the RF predicts only one class' - # delete sat solver self.slv.delete() self.slv = None - if self.verbose: - print("expl-selctors: ", expl) - self.preamble = [self.preamble[i] for i in expl] - print(' explanation: "IF {0} THEN {1}"'.format(' AND '.join(self.preamble), self.target_name[self.enc.cmaj])) - print(' # hypos left:', len(expl)) - print(' time: {0:.3f}'.format(self.time)) + expl["expl selctors:"] = explanation + self.preamble = [self.preamble[i] for i in explanation] + expl["explanation :"] = "IF {0} THEN {1}".format(' AND '.join(self.preamble), self.target_name[self.enc.cmaj]) + expl["hypos left :"] = len(explanation) - return expl + return expl def compute_minimal(self): """ @@ -889,27 +727,27 @@ class SATExplainer(object): """ nsat, nunsat = 0, 0 stimes, utimes = [], [] - + vtaut = self.enc.newVar('Tautology') - + # simple deletion-based linear search for i, p in enumerate(self.assums): to_test = [vtaut] + self.assums[:i] + self.assums[(i + 1):] + [-p, -self.sel2v[p]] - + t0 = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ - resource.getrusage(resource.RUSAGE_SELF).ru_utime - + resource.getrusage(resource.RUSAGE_SELF).ru_utime + sat = self.slv.solve(assumptions=to_test) - + if not sat: - self.assums[i] = -p + self.assums[i] = -p elif self.verbose > 1: self.print_sat_model() - + t = resource.getrusage(resource.RUSAGE_CHILDREN).ru_utime + \ resource.getrusage(resource.RUSAGE_SELF).ru_utime - t0 - #print("{0} {1:.2f}s".format("SAT" if sat else "UNSAT", t)) - + # print("{0} {1:.2f}s".format("SAT" if sat else "UNSAT", t)) + if sat: nsat += 1 stimes.append(t) @@ -917,60 +755,58 @@ class SATExplainer(object): self.enc.printLits(to_test) print("SAT") else: - #print("Core: ",self.slv.get_core()) + # print("Core: ",self.slv.get_core()) nunsat += 1 utimes.append(t) if self.verbose > 1: self.enc.printLits(to_test) - print("UNSAT") + print("UNSAT") if self.verbose: print('') - print('#SAT: {0} | #UNSAT: {1}'.format(len(stimes), len(utimes))) - if(nsat): + print('#SAT: {0} | #UNSAT: {1}'.format(len(stimes), len(utimes))) + if (nsat): print('SAT: tot: {0:.2f} | m: {1:.2f} | M: {2:.2f} | avg: {3:.2f}'.format( - sum(stimes), min(stimes), max(stimes), sum(stimes) / len(stimes))) - if(nunsat): + sum(stimes), min(stimes), max(stimes), sum(stimes) / len(stimes))) + if (nunsat): print('UNSAT: tot: {0:.2f} | m: {1:.2f} | M: {2:.2f} | avg: {3:.2f}'.format( - sum(utimes), min(utimes), max(utimes), sum(utimes) / len(utimes))) - print('') - + sum(utimes), min(utimes), max(utimes), sum(utimes) / len(utimes))) + print('') + self.stimes, self.utimes = stimes, utimes self.nsat, self.nunsat = nsat, nunsat - - + def print_sat_model(self): - assert(self.slv.get_model()) - model = [ p for p in self.slv.get_model() if self.enc.vpool.obj(abs(p)) ] + assert (self.slv.get_model()) + model = [p for p in self.slv.get_model() if self.enc.vpool.obj(abs(p))] str_model = [] lits = [] for p in model: if self.enc.vpool.obj(abs(p)) in self.inps: str_model.append((p, self.enc.vpool.obj(abs(p)))) - + elif ("class" in self.enc.vpool.obj(abs(p))): - str_model.append((p, self.enc.vpool.obj(abs(p)))) - - #elif ("intv" in self.enc.vpool.obj(abs(p))) : + str_model.append((p, self.enc.vpool.obj(abs(p)))) + + # elif ("intv" in self.enc.vpool.obj(abs(p))) : # str_model.append((p, self.enc.vpool.obj(abs(p)))) - - if ("_tr" in self.enc.vpool.obj(abs(p))) : - lits.append(p) - - if ("p_" in self.enc.vpool.obj(abs(p))) : - str_model.append((p, self.enc.vpool.obj(abs(p)))) - if ("z_" in self.enc.vpool.obj(abs(p))) : - str_model.append((p, self.enc.vpool.obj(abs(p)))) - + + if ("_tr" in self.enc.vpool.obj(abs(p))): + lits.append(p) + + if ("p_" in self.enc.vpool.obj(abs(p))): + str_model.append((p, self.enc.vpool.obj(abs(p)))) + if ("z_" in self.enc.vpool.obj(abs(p))): + str_model.append((p, self.enc.vpool.obj(abs(p)))) + print("Model:", str_model) - ###print(self.slv.get_model()) - + ###print(self.slv.get_model()) + num_tree = len(self.enc.forest.trees) num_class = self.enc.num_class - occ = [0]*num_class - + occ = [0] * num_class + for p in lits: if p > 0: j = int(self.enc.vpool.obj(abs(p))[5]) - occ[j] +=1 - print(occ) - + occ[j] += 1 + print(occ) \ No newline at end of file diff --git a/pages/application/RandomForest/utils/xrf/tree.py b/pages/application/RandomForest/utils/xrf/tree.py index da81c98..bcac5b2 100644 --- a/pages/application/RandomForest/utils/xrf/tree.py +++ b/pages/application/RandomForest/utils/xrf/tree.py @@ -1,6 +1,6 @@ # -#============================================================================== -from anytree import Node, RenderTree,AsciiStyle +# ============================================================================== +from anytree import Node, RenderTree, AsciiStyle import json import numpy as np import math @@ -8,34 +8,34 @@ import os # -#============================================================================== +# ============================================================================== class dt_node(Node): - def __init__(self, id, parent = None): + def __init__(self, id, parent=None): Node.__init__(self, id, parent) self.id = id # The node value self.name = None - self.left_node_id = -1 # Left child + self.left_node_id = -1 # Left child self.right_node_id = -1 # Right child self.feature = -1 self.threshold = None - self.values = -1 - #iai - #self.split = None + self.values = -1 + # iai + # self.split = None def __str__(self): pref = ' ' * self.depth if len(self.children) == 0: - return (pref+ "leaf: {} {}".format(self.id, self.values)) + return (pref + "leaf: {} {}".format(self.id, self.values)) else: - if(self.name is None): - return (pref+ "{} f{}<{}".format(self.id, self.feature, self.threshold)) + if (self.name is None): + return (pref + "{} f{}<{}".format(self.id, self.feature, self.threshold)) else: - return (pref+ "{} \"{}\"<{}".format(self.id, self.name, self.threshold)) + return (pref + "{} \"{}\"<{}".format(self.id, self.name, self.threshold)) -#============================================================================== -def build_tree(tree_, feature_names = None): +# ============================================================================== +def build_tree(tree_, feature_names=None): ## feature = tree_.feature threshold = tree_.threshold @@ -49,29 +49,29 @@ def build_tree(tree_, feature_names = None): while len(stack) > 0: node_id, parent_depth = stack.pop() node_depth[node_id] = parent_depth + 1 - + # If we have a test node if (children_left[node_id] != children_right[node_id]): stack.append((children_left[node_id], parent_depth + 1)) stack.append((children_right[node_id], parent_depth + 1)) else: - is_leaf[node_id] = True - ## - - m = tree_.node_count + is_leaf[node_id] = True + ## + + m = tree_.node_count assert (m > 0), "Empty tree" - - def extract_data(idx, root = None, feature_names = None): + + def extract_data(idx, root=None, feature_names=None): i = idx assert (i < m), "Error index node" if (root is None): node = dt_node(i) else: - node = dt_node(i, parent = root) - #node.cover = json_node["cover"] + node = dt_node(i, parent=root) + # node.cover = json_node["cover"] if is_leaf[i]: node.values = np.argmax(values[i]) - #if(inverse): + # if(inverse): # node.values = -node.values else: node.feature = feature[i] @@ -80,17 +80,17 @@ def build_tree(tree_, feature_names = None): node.threshold = threshold[i] node.left_node_id = children_left[i] node.right_node_id = children_right[i] - extract_data(node.left_node_id, node, feature_names) #feat < threshold ( < 0.5 False) - extract_data(node.right_node_id, node, feature_names) #feat >= threshold ( >= 0.5 True) + extract_data(node.left_node_id, node, feature_names) # feat < threshold ( < 0.5 False) + extract_data(node.right_node_id, node, feature_names) # feat >= threshold ( >= 0.5 True) return node - + root = extract_data(0, None, feature_names) - + return root -#============================================================================== +# ============================================================================== def walk_tree(node): if (len(node.children) == 0): # leaf @@ -100,17 +100,20 @@ def walk_tree(node): walk_tree(node.children[0]) walk_tree(node.children[1]) + def count_nodes(root): def count(node): if len(node.children): - return sum([1+count(n) for n in node.children]) + return sum([1 + count(n) for n in node.children]) else: return 0 + m = count(root) + 1 return m + # -#============================================================================== +# ============================================================================== def predict_tree(node, sample): if (len(node.children) == 0): # leaf @@ -118,33 +121,33 @@ def predict_tree(node, sample): else: feature_branch = node.feature sample_value = sample[feature_branch] - assert(sample_value is not None) - if(sample_value < node.threshold): + assert (sample_value is not None) + if (sample_value < node.threshold): return predict_tree(node.children[0], sample) else: return predict_tree(node.children[1], sample) - + # -#============================================================================== +# ============================================================================== class Forest: """ An ensemble of decision trees. This object provides a common interface to many different types of models. """ - def __init__(self, rf, feature_names = None): - #self.rf = rf - self.trees = [ build_tree(dt.tree_, feature_names) for dt in rf.estimators()] + + def __init__(self, rf, feature_names=None): + # self.rf = rf + + self.trees = [build_tree(dt.tree_, feature_names) for dt in rf.estimators()] self.sz = sum([dt.tree_.node_count for dt in rf.estimators()]) self.md = max([dt.tree_.max_depth for dt in rf.estimators()]) #### nb_nodes = [dt.tree_.node_count for dt in rf.estimators()] - print("min: {0} | max: {1}".format(min(nb_nodes), max(nb_nodes))) - assert([dt.tree_.node_count for dt in rf.estimators()] == [count_nodes(dt) for dt in self.trees]) - #self.print_trees() - + assert ([dt.tree_.node_count for dt in rf.estimators()] == [count_nodes(dt) for dt in self.trees]) + def print_trees(self): - for i,t in enumerate(self.trees): + for i, t in enumerate(self.trees): print("tree number: ", i) walk_tree(t) @@ -153,22 +156,20 @@ class Forest: scores = np.asarray(scores) maj = np.argmax(np.bincount(scores)) return maj - - - def predict(self, samples): + + def predict(self, samples): predictions = [] print("#Trees: ", len(self.trees)) for sample in np.asarray(samples): scores = [] - for i,t in enumerate(self.trees): + for i, t in enumerate(self.trees): s = predict_tree(t, sample) scores.append((s)) scores = np.asarray(scores) predictions.append(scores) - predictions = np.asarray(predictions) - #print(predictions) - #np.bincount(x, weights=self._weights_not_none) + predictions = np.asarray(predictions) + # print(predictions) + # np.bincount(x, weights=self._weights_not_none) maj = np.apply_along_axis(lambda x: np.argmax(np.bincount(x)), axis=1, arr=predictions) - - return maj + return maj diff --git a/utils.py b/utils.py index 87f4fa3..4b76ea3 100644 --- a/utils.py +++ b/utils.py @@ -20,10 +20,11 @@ def parse_contents_graph(contents, filename): content_type, content_string = contents.split(',') decoded = base64.b64decode(content_string) try: - if 'mod.pkl' in filename: - data = pickle.load(io.BytesIO(decoded)) - elif '.pkl' in filename: - data = joblib.load(io.BytesIO(decoded)) + if '.pkl' in filename: + try: + data = joblib.load(io.BytesIO(decoded)) + except : + data = pickle.load(io.BytesIO(decoded)) elif '.txt' in filename: data = decoded.decode('utf-8').strip() except Exception as e: @@ -58,8 +59,11 @@ def parse_contents_instance(contents, filename): try: if '.csv' in filename: data = decoded.decode('utf-8') + features_names, data = str(data).strip().split('\n')[:2] + features_names = str(features_names).strip().split(',') data = str(data).strip().split(',') - data = list(map(lambda i: tuple([i[0], np.float32(i[1])]), [i.split('=') for i in data])) + data = list(tuple([features_names[i], np.float32(data[i])]) for i in range(len(data))) + print(data) elif '.txt' in filename: data = decoded.decode('utf-8') data = str(data).strip().split(',') @@ -72,6 +76,9 @@ def parse_contents_instance(contents, filename): data = decoded.decode('utf-8').strip() data = json.loads(data) data = list(tuple(data.items())) + elif '.samples' in filename: + decoded = decoded.decode('utf-8').strip() + data = str(decoded).split('\n') except Exception as e: print(e) return html.Div([ -- GitLab