PKX/5META-INF/MANIFEST.MFeN0EwK7`'PQHLI^ 9_N{-,W2ps)ެh7R8%eX G`l&屋5z Iט}Tbl3)PK~9PK 85de/PK 85de/uos/PK 85de/uos/cogsci/PK 85de/uos/cogsci/ai/PK 85de/uos/cogsci/ai/btenbergen/PK 85&de/uos/cogsci/ai/btenbergen/bscthesis/PK 855de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/PK 5w+59de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/PK !5<XXCde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp; /** * This is the Layer class. * It implements a layer for a Multi-Layer Perceptron Neural Network. * The type of the layer can be either input, hidden or output. * * @version 02.05.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import java.util.Random; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; public class Layer implements Layers { /** * The array of neurons defining the layer. */ public Perceptron[] neurons; /** * The maximum value of weights and bias for each neuron. */ private int maxValue; /** * Constructor. A layer is defined by the number of neurons and the dimensionality of the input. * It is instantiated by invoking rows * cols Perceptrons. Each Perceptron * has as many weights as input dimensionality. The weight vectors are initialized randomly, however * limited to maxValue to prevent very large weight differences. * Neurons in Multi-Layer-Perceptrons always fire bipolar. * @param rows The number of rows in the layer * @param cols The number of cols in the layer * @param inputDimensions The dimensionality of the input vector * @param maxValue The maximum value for weights and bias for the neurons. */ public Layer(int rows, int cols, int inputDimensions, int maxValue) { Random r = new Random(); int currentNeuron = 0; neurons = new Perceptron[rows * cols]; this.maxValue = maxValue; for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { double[] weights = new double[inputDimensions]; for (int k = 0; k < inputDimensions; k++) { weights[k] = (double) r.nextInt(Math.abs(this.maxValue)); }//end for-k Perceptron p = new Perceptron(i, j, r.nextInt((int) Math.abs(Math.ceil(this.maxValue))), weights, true); neurons[currentNeuron] = p; ++currentNeuron; }//end for-j }//end for-i } /** * Given a coordinate in the structure, this method returns the index of the * corresponding neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The index of the neuron. */ public int findNeuronIndex(int row, int col) { int index = -1; for (int i = 0; i < neurons.length; i++) { if (neurons[i].row == row && neurons[i].col == col) index = i; } return index; } /** * Given a coordinate in the structure, this method returns the corresponding * neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The neuron at the given position. */ public Perceptron findNeuron(int row, int col) { return this.neurons[findNeuronIndex(row, col)]; } /** * This method simply returns the neurons of the layer. * @return The neurons of the layer. */ public Perceptron[] getPerceptrons() { return neurons; } /** * Displays the neurons of the layer. */ public String toString() { String s = ""; for (int i = 0; i < this.neurons.length; i++) { s = s.concat("\n" + "Neuon " + i + ": " + this.neurons[i].toString()); } return s; } }PK !5E&Dde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layers.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp; /** * This is a Layer Interface. Layers for MLPs should be constructed by implementing this interface. * * @version 01.05.2006 * @author B. Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; public interface Layers { /** * Given a coordinate in the structure, this method returns the index of the * corresponding neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The index of the neuron. */ public int findNeuronIndex(int row, int col); /** * Given a coordinate in the structure, this method returns the corresponding * neuron. * @param row The X-Axis of the neuron * @param col The Y-Axis of the neuron * @return The neuron at the given position. */ public Perceptron findNeuron(int row, int col); /** * This method simply returns the neurons of the Layer. * @return The neurons of the Layer. */ public Perceptron[] getPerceptrons(); /** * toString displays the Neurons of the Layer. */ public String toString(); }PK 5=1MMBde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/MLPs.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp; /** * This is a Multi-Layer Perceptron Interface. MLPs should be constructed by implementing this interface. * * @version 01.05.2006 * @author B. Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; public interface MLPs { /** * Runs the classification process runs times. * For each pattern update(int[]) is called. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void runClassification() throws PerceptronInputException; /** * Updates the winner neuron. To do so, the winner neuron needs to be determined * by calling findWinner(int[]). Each weight in the winner's weight vecotr is then updated * with the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateWinner(double[] input) throws PerceptronInputException; /** * Updates the winner's neighboring neurons. The neighboring neurons are determined and * then updated according to the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateNeighbor(double[] input) throws PerceptronInputException; /** * This method determines the winner neuron's neighboring neurons and returns * them. This method needs to implement the topology of the MLP. * @param input The input vector determining the winning neuron. * @return The winner neuron's neighboring neurons. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron[] findNeighbors(double[] input) throws PerceptronInputException; /** * This method determines the winning neuron by comparing the activations given the input vector * of all neurons in the layer. This is very close to a standard SelectionSort algorithm, but since the * neurons are not sorted and only the maximum activation, this is done in O(n) time. * @param input The input vector determining the winning neuron. * @return The winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron findWinner(double[] input) throws PerceptronInputException; /** * toString method. Returns the String-Representation of this MLP. * @return The String representation of this MLP. */ public String toString(); }PK 5w+5=de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/PK \(5:XXEde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som; /** * This is the SOM class. * It implements a Self-Organizing Map. A SOM is a neural network * with two layers and the following structure:
* - An Inputlayer with n neurons. The activation of these neurons * is equal to the input values.
* - An Outputlayer with m neurons. Only one neuron in this layer is * active (output: 1) - all others are silent (output: 0). Winner * neurons and it's neighboring neurons are updated with a fixed * learning rate.
* - An input vector with d dimensions.
* - Every output neuron is connected to every input neuron.
* * @version 19.07.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.Layer; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.MLPs; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools; import edu.udo.cs.yale.tools.LogService; import java.util.Random; public class SOM implements MLPs { /** The Topology of this Map. If true, the last neuron of each row or col is connected to the first one. */ private boolean closed_topology; /** The number of classification runs to be performed. */ private int runs; /** The learning rate. Defines how far the weight vector of the winning neuron is "pulled" into the direction of the input vector. */ private double learningrate_winner; /** The learning rate of the winner's neighboring neurons. */ private double learningrate_neighbor; /** This array contains all patterns, i.e. the input vectors. For simplicity reasons, this is an Object array that contains double arrays instead of a two dimensional matrix. Whenever a pattern is taken out of the array, it needs to be casted to a double[]. This should increase the performance on slow machines */ private Object[] patterns; /** Sets the number of rows of this SOM. */ private int rows; /** Sets the number of cols of this SOM. */ private int cols; /** The output layer. */ public Layer output; //The input layer. // private Layer input; /** * Constructor. * Creates a new Self-Organizing Map. * * @param rows The number of rows of this SOM. * @param cols The number of columns of this SOM. * @param patterns The training patterns. Must be an Object array containing * double arrays. * @param learningrate_winner Defines how far the weight vector of the winning neuron is "pulled" into * the direction of the input vector. * @param learningrate_neighbor Defines how far the weight vectors of the winner's neighbors is updated. * @param runs The number of classification runs to be performed. * @param maxValue The maximum value for weights and bias for the neurons. * @param closed_topology The Topology of this Map. If true, the last neuron of each row or col is connected to the first one. */ public SOM(int rows, int cols, Object[] patterns, double learningrate_winner, double learningrate_neighbor, int runs, int maxValue, boolean closed_topology) { this.patterns = patterns; this.closed_topology = closed_topology; int newMaxValue; switch (maxValue) { case -1: Random r = new Random(); newMaxValue = r.nextInt(); break; // case -2: newMaxValue = Math.abs(computeMax(this.patterns)); // break; default: newMaxValue = maxValue; break; } this.output = new Layer(rows, cols, ((double[]) patterns[0]).length, newMaxValue); // input = new Layer(0, 0, 0); // Since the activation of the input layer equals the input values, // the network is implemented as just an output layer. this.learningrate_winner = learningrate_winner; this.learningrate_neighbor = learningrate_neighbor; this.runs = runs; } /** * Constructor. * Creates a new Self-Organizing Map with default values for learningrates and runs. * A sensible maximum value for the neuron's weights and bias is computed automatically. * * @param rows The number of rows of this SOM. * @param cols The number of columns of this SOM. * @param patterns The training patterns. Must be an Object array containing * double arrays. */ public SOM(int rows, int cols, Object[] patterns) { this(rows, cols, patterns, 1, 0.25, 1, -1, false); } /** * Constructor. * Creates a new Self-Organizing Map with default values for learningrates. * A sensible maximum value for the neuron's weights and bias is computed automatically. * * @param rows The number of rows of this SOM. * @param cols The number of columns of this SOM. * @param patterns The training patterns. Must be an Object array containing * double arrays. * @param runs The number of runs to be performed. The more runs are performed, the more "prototypical" * the output neurons are to the input clusters. */ public SOM(int rows, int cols, Object[] patterns, int runs) { this(rows, cols, patterns, 1, 0.25, runs, -1, false); } /** * This method computues the maximum sensible bias and weight values. * @param patterns A sensible maximum is computed according to these patterns. * @return A reasonable maximum threshold. */ public int computeMax(Object[] patterns) { //We need a Random Object Random r = new Random(); //take a random pattern... int rdm = r.nextInt(patterns.length); //...and compute the minimal and maximal element //of that pattern. double[] minmax = Tools.minMaxElement(((double[]) patterns[rdm])); do { //Then, generate a random int rdm = r.nextInt(); } while (!(rdm < minmax[0]) && rdm > minmax[1]); //If the new random int is smaller than the //smallest, or bigger than the biggest //element in the pattern, generate a new one return rdm; } /** * Runs the classification process runs times. * For each pattern, the winner neuron is determined and updated. The winner neuron's * neighboring neurons are updated accordingly. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void runClassification() throws PerceptronInputException { for (int j = 0; j < runs; j++) { for (int i = 0; i < patterns.length; i++) { updateWinner((double[]) patterns[i]); updateNeighbor((double[]) patterns[i]); } } } /** * Updates the winner neuron of the output layer. To do so, the winner neuron needs to be determined * by calling findWinner(int[]). Each weight in the winner's weight vecotr is then updated * with the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateWinner(double[] input) throws PerceptronInputException { Perceptron winner = findWinner(input); double[] winnerWeights = winner.getWeights(); for (int i = 0; i < winnerWeights.length; i++) { winnerWeights[i] = winnerWeights[i] + (learningrate_winner * (input[i] - winnerWeights[i])); } winner.setWeights(winnerWeights); } /** * Updates the winner neuron's neighboring neurons. To do so, the neighbors need to be determined * by calling findNeighbors(int[]). Each weight in each neighbor's weight vecotr is then updated * with the following formula:
* newWeight = oldWeight + (LEARNINGRATE * (input - oldWeight))
* @param input The weight vector that determines the winning neuron. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public void updateNeighbor(double[] input) throws PerceptronInputException { Perceptron[] neighbors = findNeighbors(input); double[] currentNeighborWeights; if (neighbors.length == 0) return; else { for (int i = 0; i < neighbors.length; i++) { currentNeighborWeights = neighbors[i].getWeights(); for (int j = 0; j < currentNeighborWeights.length; j++) { currentNeighborWeights[j] = currentNeighborWeights[j] + (learningrate_neighbor * (input[j] - currentNeighborWeights[j])); }//end for-j neighbors[i].setWeights(currentNeighborWeights); }//end for-i }//end else } /** * This method determines the winner neuron's neighboring neurons and returns * them according to the here implemented architecture of the SOM. * @param input The input vector determining the winning neuron. * @return The winner neuron's neighboring neurons. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron[] findNeighbors(double[] input) throws PerceptronInputException { Perceptron winner = findWinner(input); Perceptron[] neurons = this.output.getPerceptrons(); Perceptron[] neighbors; //allocate neighbors int winnerIndex = 0; //allocate winner index int left, right, upper, lower; //allocate neighbor indexes if (neurons.length == 1) return new Perceptron[0]; //set neighbor relations for rectangle architecture if (rows > 1 && cols > 1) { //... with open topology... if (!this.closed_topology) { //winner is in upper left corner -> only right und lower neighbor if (winner.row == 0 && winner.col == 0 && this.output.neurons.length > 1) { right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); neighbors = new Perceptron[2]; neighbors[0] = neurons[right]; neighbors[1] = neurons[lower]; } //winner is in upper right corner -> only left und lower neighbor if (winner.row == 0 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[lower]; } //winner is in lower left corner -> only right und upper neighbor if (winner.row == rows-1 && winner.col == 0) { right = this.output.findNeuronIndex(winner.row+1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[2]; neighbors[0] = neurons[right]; neighbors[1] = neurons[upper]; } //winner is in lower right corner -> only left und upper neighbor if (winner.row == rows-1 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[upper]; } //if winner in first column -> no left neighbor if (winner.col == 0) { right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[3]; neighbors[0] = neurons[right]; neighbors[1] = neurons[lower]; neighbors[2] = neurons[upper]; } //if winner in last column -> no right neighbor if (winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[3]; neighbors[0] = neurons[left]; neighbors[1] = neurons[lower]; neighbors[2] = neurons[upper]; } //if winner in first row -> no upper neighbor if (winner.row == 0) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); neighbors = new Perceptron[3]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; } //if winner in last row -> no lower neighbor if (winner.row == rows-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[3]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[upper]; } else { neighbors = new Perceptron[0]; } } //... with closed topology... else { //winner is in upper left corner -> left neighbor is last in first row // upper one is last in first column if (winner.row == 0 && winner.col == 0) { left = this.output.findNeuronIndex(0, cols-1); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(rows-1, 0); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //winner is in upper right corner -> right neighbor is first in first row // upper one is last in last col if (winner.row == 0 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(0,0); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(rows-1, cols-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //winner is in lower left corner -> left is last in last col // lower is first in first row if (winner.row == rows-1 && winner.col == 0) { left = this.output.findNeuronIndex(rows-1, cols-1); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(0, 0); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //winner is in lower right corner -> right is first in last row // lower is last in first row if (winner.row == rows-1 && winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(rows-1, 0); lower = this.output.findNeuronIndex(0, cols-1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in first column -> left is last col, same row if (winner.col == 0) { left = this.output.findNeuronIndex(winner.row, cols-1); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in last column -> right is first col, same row if (winner.col == cols-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row, 0); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in first row -> upper is last row, same col if (winner.row == 0 && this.output.neurons.length > 1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(winner.row, winner.col+1); upper = this.output.findNeuronIndex(rows-1, winner.col); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } //if winner in last row -> lower is first row, same col if (winner.row == rows-1) { left = this.output.findNeuronIndex(winner.row-1, winner.col); right = this.output.findNeuronIndex(winner.row+1, winner.col); lower = this.output.findNeuronIndex(rows-1, winner.col); upper = this.output.findNeuronIndex(winner.row, winner.col-1); neighbors = new Perceptron[4]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; neighbors[2] = neurons[lower]; neighbors[3] = neurons[upper]; } else { neighbors = new Perceptron[0]; } } } //set neighbor relations for chain/cirlce architecture else { //...with open topology... (chain) if (!this.closed_topology) { //if winner is leftmost neuron -> no left neighbor if (winnerIndex == 0) { right = winnerIndex+1; neighbors = new Perceptron[1]; neighbors[0] = neurons[right]; } //if winner is rightmost neuron -> no right neighbor else if (winnerIndex == neurons.length-1) { left = winnerIndex-1; neighbors = new Perceptron[1]; neighbors[0] = neurons[left]; } //if winner is in the middle -> set both neighbors else { left = winnerIndex-1; right = winnerIndex+1; neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; } } //...with closed topology... (circle) else {//if (this.closed_topology) { //if winner is leftmost neuron -> left neighbor is last neuron if (winnerIndex == 0) { left = neurons.length-1; right = winnerIndex+1; } //if winner is rightmost neuron -> right neighbor is first neuron else if (winnerIndex == neurons.length-1) { left = winnerIndex-1; right = 0; } //if winner is in the middle -> set both neighbors as usual else { left = winnerIndex-1; right = winnerIndex+1; } neighbors = new Perceptron[2]; neighbors[0] = neurons[left]; neighbors[1] = neurons[right]; } } return neighbors; } /** * This method determines the winning neuron by comparing the activations given the input vector * of all neurons in the layer. This is very close to a standard SelectionSort algorithm, but since the * neurons are not sorted and only the maximum activation, this is done in O(n) time. * @param input The input vector determining the winning neuron. * @return The winning neuron. * @throws PerceptronInputException If the Perceptron's weight vector is not of equal length as the input vector. */ public Perceptron findWinner(double[] input) throws PerceptronInputException { double activation; Perceptron[] neurons = this.output.getPerceptrons(); int winner = 0; double max = neurons[winner].activation(input); for (int i = 0; i < neurons.length; i++) { activation = neurons[i].activation(input); if (activation > max) { max = activation; winner = i; } } return neurons[winner]; } /** * toString method. Just calls the toString of the output layer, since this SOM just consists * of an output layer. * @return The String representation of this SOM. */ public String toString() { return this.output.toString(); } /** * This method confirms the given input vectors by prompting them. * Called usually by methods testing the functionality. */ public void showPatterns() { System.out.println("Patterns:"); for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double []) patterns[i]).length; j++) { System.out.print(((double[]) patterns[i])[j]); System.out.print(" "); } System.out.print(" "); } System.out.println(); } /** * This method logs the current status of the SOM by sending information * to Yale's Log-Console. The output is similar to showPatterns(). */ protected void logPatterns() { LogService.logMessage("Patterns:", LogService.STATUS); for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double []) patterns[i]).length; j++) { LogService.logMessage(Double.toString(((double[]) patterns[i])[j]), LogService.STATUS); LogService.logMessage(" ", LogService.STATUS); } } } }PK 5w+5@de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PK 5 ]de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron; /** * The class PercepronInputException is thrown when the Input-Vector of a Perceptron * is not of equal length as its Weight-Vector. * Javadoc taken from java.lang.Exception class. * * * @version 01.05.2006 * @author Bastian Tenbergen - btenberg@uos.de */ public class PerceptronInputException extends Exception { private static final long serialVersionUID = 42; private String msg; protected Throwable cause; /** * Constructs a new exception with null as its detail message. * The cause is not initialized, and may subsequently be initialized by a call to Throwable.initCause(java.lang.Throwable). */ public PerceptronInputException() { this(null, null); } /** * Constructs a new exception with the specified detail message and cause. * Note that the detail message associated with cause is not automatically incorporated in this exception's detail message. * @param msg the detail message (which is saved for later retrieval by the Throwable.getMessage() method). * @param cause the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.) */ public PerceptronInputException(String msg, Throwable cause) { this.msg = msg; this.cause = cause; } /** * Constructs a new exception with the specified detail message. The cause is not initialized, and may subsequently be initialized by a call to Throwable.initCause(java.lang.Throwable). * @param msg the detail message. The detail message is saved for later retrieval by the Throwable.getMessage() method. */ public PerceptronInputException(String msg) { this(msg, null); } /** * Constructs a new exception with the specified cause and a detail message of (cause==null ? null : cause.toString()) (which typically contains the class and detail message of cause). * This constructor is useful for exceptions that are little more than wrappers for other throwables (for example, PrivilegedActionException). * @param cause the cause (which is saved for later retrieval by the Throwable.getCause() method). (A null value is permitted, and indicates that the cause is nonexistent or unknown.) */ public PerceptronInputException(Throwable cause) { this(null, cause); } /** * Just returns the detail message of the exception. * * @return the detailed message as a java.lang.String */ public String getMessage() { return msg; } }PK 5NkkOde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron; /** * This is the Perceptron class. * It implements a perceptron with an arbitrary number of inputs. * * @version 01.05.2006 * @author Bastian Tenbergen - btenberg@uos.de */ public class Perceptron { /** The biad of the perceptron that needs to be exceeded to cause an activation. */ public final double BIAS; /** The weights of the perceptron that weighing the input */ public double[] weights; /** If true the perceptron fires bipolar (output: 1 or -1), else binary (output: 1 or 0).*/ public boolean bipolar; /** If the perceptron is embedded in a neural network, this indicates the row in which it is located.*/ public int row; /** If the perceptron is embedded in a neural network, this indicates the column in which it is located.*/ public int col; /** The value that is returned when the activation exceeds the threshold. */ private int returnPos; /** The value that is returned when the activation does not exceed the threshold. */ private int returnNeg; /** * Constructor. A standard Perceptron is invoked when called. * @param row The row of the structure in which this Perceptron is located. * @param col The column of the structure in which this Perceptron is located. * @param BIAS The bias (theta, threshold) of the Perceptron. Once set, never changeable. * @param weights The weight vector of the perceptron. * @param bipolar Determines, if the Perceptron is bipolar or binary. * If true, the negative output is -1. If false, the negative * output is 0. The positive output is always 1. */ public Perceptron(int row, int col, double BIAS, double[] weights, boolean bipolar) { this.row = row; this.col = col; this.BIAS = BIAS; this.weights = weights; this.bipolar = bipolar; setBipolar(); } /** * Sets the Perceptron to binary or bipolar. Called by the constructor. */ private void setBipolar() { this.returnPos = 1; if (this.bipolar) this.returnNeg = -1; else this.returnNeg = 0; } /** * Fires the perceptron. Calls activation(int[]) to compute scalar product. * @param inputs The input vector. * @return 1 if the scalar product of the input and the weights is higher than the bias. * -1 or 0 else (this depends on the Perceptron being bipolar or binary. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public int fire(double[] inputs) throws PerceptronInputException { if (activation(inputs) >= BIAS) return returnPos; else return returnNeg; } /** * This method computes the scalar product of the input and the weights. * @param inputs The input vector. * @return The activation of the Perceptron - scalar product of weights x input. * @throws If the Perceptron's weight vector is not of equal length as the input vector. */ public double activation(double[] inputs) throws PerceptronInputException { if (inputs.length != weights.length) { throw new PerceptronInputException("Input vector length not equal to weight vector length."); } double act = 0; for (int i = 0; i < weights.length; i++) { act += weights[i] * inputs[i]; } return act; } /** * This method updates the weight vector of the Perceptron. * @param newWeights The new weight vector. * @return true if update was successful, false else. */ public boolean setWeights(double[] newWeights) { if (newWeights.length != weights.length) { System.err.println("Warning: New weight vector not of the same length as the old one. Weights not updated."); return false; } else { for (int i = 0; i < newWeights.length; i++) { weights[i] = newWeights[i]; } return true; } } /** * This method just returns the weights. * @return The weight vector of the Perceptron. */ public double[] getWeights() { return weights; } /** * toString method. Returns the String representation of the Perceptron. * @return The String representation of the Perceptron. */ public String toString() { String s = ""; for (int i = 0; i < weights.length; i++) { s = s.concat((new Double(weights[i])).toString()); s = s.concat(" "); } if (this.bipolar) s = s.concat(", The Perceptron fires bipolar."); else s = s.concat(", The Perceptron fires binary."); return "Bias: " + this.BIAS + ", Weights: " + s; } }PK 5w+5,de/uos/cogsci/ai/btenbergen/bscthesis/tools/PK !56>de/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorTools.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This class provides some simple Tools for the SOMInput Operator for Yale. * * @version 25.08.2006 * @author Bastian Tenbergen - btenberg@uos.de */ // The methods in this class have been moved here to improve the structural layout of // the package as well as to provide an easier overview of the source-code. import java.util.Vector; import java.lang.ArrayIndexOutOfBoundsException; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster; public class OperatorTools { /** * Replaces all characters which are not letters or digits by _ (underscore). Additionally all non-english characters * like umlauts or ß are replaced. The file itself is not modified, since only * the String representation of the file name is taken into conderation.
* Modified from ValueSeriesPlugin v3.2 for Yale.
*

* @author Ingo Mierswa (original author) * @author Bastian Tenbergen (modifications) * @param filename The file name to be converted. Usually the user's input file, but this works with any kind of String. * @return The converted file name. The original file is not changed, since this operator only retrieves the String representation of the user's input. * @version current: 27.08.2006, original: $Id: MusicFile.java,v 1.3 2006/03/21 15:35:26 ingomierswa Exp $ */ public static String convertFilename(String filename) { String result = filename; for (int i = 0; i < result.length(); i++) { if (!Character.isLetterOrDigit(result.charAt(i))) result = result.replace(result.charAt(i), '_'); } result = result.replaceAll("\u00f6", "oe"); result = result.replaceAll("\u00d6", "Oe"); result = result.replaceAll("\u00e4", "ae"); result = result.replaceAll("\u00c4", "Ae"); result = result.replaceAll("\u00fc", "ue"); result = result.replaceAll("\u00dc", "Ue"); result = result.replaceAll("\u00df", "ss"); result = result.concat("_0"); return result; } /** * This method checks if a String occures in the Vector of any cluster in a given Cluster-array. * If a occurrence has been found, the whole cluster is printed out. * @param hummedFile Look for this String in the clusters. * @param clusters The cluster array in which to look for the String. * @return The String representation of the cluster(s) in which the String was found. */ public static String findQueryInClusters(String hummedFile, Cluster[] clusters) { String s = ""; //for every single cluster... for (int i = 0; i < clusters.length; i++) { //...look at it's Vector's elements... for (int j = 0; j < clusters[i].content.size(); j++) { //and check, if it contains the query pattern. if (clusters[i].content.elementAt(j).contains(hummedFile)) //if it does, print out the cluster in line form and concatenate s = s.concat(clusters[i].toStringln()); }//end for-j }//end for-i //create error message if nothing was found. (s should be empty then) if (s.equals("")) { s = s.concat("No Files found. Please check query file name" + "and/or lower number of neurons to improve accuracy.\n"); } return s; } /** * This method simply shows the processed songlist. * @param songList A Vector containing the processed songs. * @return The String representation of the songlist in a ResultService-friendly form. */ public static String displaySongList(Vector songList) { String s = ""; for (int i = 0; i < songList.size(); i++) { s = s.concat("File number " + i + ": " + songList.elementAt(i) + "\n"); } return s; } /** * This method creates Cluster-Objects given an array containing the pattern's closest neurons * and a Vector containing the Song-Names. The Cluster-Objects can hence be referenced more easily. * @param positions An array containing the closest neurons to a given pattern. * @param songList A Vector containing the Song-Names. * @return A Cluster-Array containing the Clusters. */ public static Cluster[] createFileClusters(int[] positions, Vector songList) throws ArrayIndexOutOfBoundsException { Cluster[] clusters = new Cluster[positions.length]; //initialize all Clusters and assign ID. for (int i = 0; i < clusters.length; i++) clusters[i] = new Cluster(i, new Vector()); //fill Clusters with the song names. for (int i = 0; i < songList.size(); i++) { //vorher positions iteriert try { clusters[positions[i]].content.addElement(songList.elementAt(i)); } catch (ArrayIndexOutOfBoundsException aiobe) { // throw new ArrayIndexOutOfBoundsException(); } } return clusters; } /** * This method creates Cluster Objects of the processed files and shows them. Similar files occur * in the same cluster. * @param clusters The Clusters of similar songs. * @return The clusters in a ResultService-friendly form. */ public static String showFileClusters(Cluster[] clusters) { String s = ""; for (int i = 0; i < clusters.length; i++) { if (!clusters[i].content.isEmpty()) { s = s.concat(clusters[i].toString()); s = s.concat("\n"); } } return s; } }PK |5-lN 8de/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This class represents a Cluster Object. A Cluster consists of an ID (positive * Integer value) and a Vector containing Strings in which the patterns are stored. * * @version 24.08.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import java.util.Vector; public class Cluster { /** The ID of the Cluster. */ public int id; /** All Patterns in the Cluster. */ public Vector content; /** * Constructor. Invokes a Cluster Object Instance. * @param id The ID of the Cluster. * @param content The Patterns that belong to this cluster. */ public Cluster(int id, Vector content) { this.id = id; this.content = content; } /** * This method returns the String representation of the cluster. * @return The String representation of this cluster in form of the cluster ID and the content. */ public String toString() { return "Cluster # " + this.id + ": " + this.content.toString(); } /** * This method returns the String representation of this cluster in lines. * Only the content is printed, the ID is omitted. * @return This cluster's content in lines. */ public String toStringln() { String s = ""; for (int i = 0; i < this.content.size(); i++) { s = s.concat(this.content.elementAt(i)); s = s.concat("\n"); } return s; } }PK /(5e6de/uos/cogsci/ai/btenbergen/bscthesis/tools/Tools.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This is class providing tools for multiple purposes. * Currently implemented:
* - a generic quicksort algorithm sorting double arrays
* - a generic quicksort algorithm sorting double arrays but maintining the original array
* - a method providing the smallest and largest element of a double array
* - a method providing the smallest, the largest and the median element of a double array
* - a method returning the index of the smallest element in a given double array
* * @version 20.07.2006 * @author Bastian Tenbergen - btenberg@uos.de */ public class Tools { /** * A standard recursive QuickSort Algorithm. This algorithm takes a double array and * sorts it from the biggest to the smallest element. It takes the median element as the random pivot element. * This method calls the private method qs(double[], int, int) that does the actual job. * This method copies the given array so that the original array is maintained. * * @param array the array to be sorted * @param onset the onset element from which shall be sorted (inclusive) * @param offset the offset element until which shall be sorted (inclusive) */ public static double[] quicksort(double[] array, int onset, int offset) { double[] sortMe = new double[array.length]; System.arraycopy(array, 0, sortMe, 0, array.length); qs(sortMe, 0, sortMe.length-1); return sortMe; } /** * This method does the actual sorting. * * @param array the array to be sorted * @param onset the onset element from which shall be sorted (inclusive) * @param offset the offset element until which shall be sorted (inclusive) */ private static void qs (double[] array, int onset, int offset) { double tmp; // we need a temp variable to copy values into int x = onset; // and two temp variables serving as the upper int y = offset; // and lower marker double pivot = array[(onset + offset) / 2]; // randomly assign a pivot element // here: the median element do { while (array[x] < pivot) // as long as the lower current element x++; // is smaller as the pivot element: increase while (array[y] > pivot) // as long as the upper current element y--; // is lager as the pivot element: decrease if ( x <= y ) { // if the lower curr elem is smaller or equal to the upper curr elem tmp = array[x]; // array[x] = array[y]; // switch the elements and array[y] = tmp; // x++; // increase lower marker and y--; // decrease upper marker to continue } } while (x <= y); // continue until all elements in left half are smaller // than the ones in the right half if (onset < y) qs(array, onset, y); // sort left half if (x < offset ) qs(array, x, offset); // sort right half } /** * Returns the smallest and biggest element of a given double array in a new double array. * @param array the (unsorted) array containing one smallest and one biggest element * @return a new array with the input array's smallest and biggest as first and second element. */ public static double[] minMaxElement(double[] array) { quicksort(array, 0, array.length-1); return new double[] {array[0], array[array.length-1]}; } /** * Returns the smallest and biggest and the medium element of a given double array in a new double array. * @param array the (unsorted) array containing one smallest and one biggest element * @return a new array with the input array's smallest, biggest and the medium element. */ public static double[] minMedMaxElement(double[] array) { quicksort(array, 0, array.length-1); return new double[] {array[0], array[array.length/2], array[array.length-1]}; } /** * This method returns the position of the smallest element of a given array. * It does so in a SelectionSort-like way, but runs through array only once (since we * don't need to sort the whole array. * * @param array the array containing one smallest element, whose position is of interest. * @return the position of the smallest element in the array. */ public static int positionOfSmallest(double[] array) { double min = array[0]; //the current minimum value in array. int pos = 0; //Position of the smallest. Zero at beginning. for (int i = 1; i < array.length; i++) //Go through array, skip first position. if (array[i] < min) { //If smallere element found... pos = i; //...remember it's position... min = array[i]; //...and it's value. } return pos; //when done, return the position. } }PK !5bb9de/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.tools; /** * This is the Distance-Tool for the Self-Organizing-Map Operator for Yale. * It computes the distances between the a Perceptron array's weight Vector and * the input Vector. Please note that the Distance measure methods can be used in * a quasi-static way be invoking a Distance Object with null as the Perceptron array * and the patterns. * * @version 15.08.2006 * @author B. Tenbergen - btenberg@uos.de */ import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.Perceptron; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Tools; public class Distance { /** Constant for the Euclidean Distance. */ public static final int EUCLIDEAN = 0; /** Constant for the Manhattan Distance. */ public static final int MANHATTAN = 1; /** Constant for the Nominal Distance. */ public static final int NOMINAL = 2; /** The array containing the patterns. */ private Object[] patterns; /** The Perceptron array that needs to be measured against the patterns. */ private Perceptron[] neurons; /** The metric to be used. */ private int metric; /** * Constructor. A new Distance Object is created upon invokation. * @param neurons The Perceptron array of which the weight Vectors need to be measured. * @param patterns The Patterns that need to be measured. * @param metric The Metric to be used. */ public Distance(Object[] patterns, Perceptron[] neurons, int metric) { this.patterns = patterns; this.neurons = neurons; this.metric = metric; } /** * Constructor. A new Distance Object is created upon invokation. Euclidean Distance is used. * @param neurons The Perceptron array of which the weight Vectors need to be measured. * @param patterns The Patterns that need to be measured. */ public Distance(Object[] patterns, Perceptron[] neurons) { this(patterns, neurons, Distance.EUCLIDEAN); } /** * For each pattern, this method returns the closest neuron. * @return The array containing the positions of the neurons.tern. */ public int[] measureDistance() { //We need an array in which we store the neurons that are closest to the //current pattern. Needs to be as long as the patterns. int[] closest_neurons_per_pattern = new int[this.patterns.length]; //For ever pattern... for (int i = 0; i < this.patterns.length; i++) { //...we need an array that stores the distance to all neurons double[] current_pattern_distances = new double[this.neurons.length]; //For all neurons... for (int j = 0; j < this.neurons.length; j++) { switch (this.metric) { //choose metric case Distance.EUCLIDEAN: current_pattern_distances[j] = euclideanDistance((double[]) this.patterns[i], this.neurons[j].weights); break; case Distance.MANHATTAN: current_pattern_distances[j] = manhattanDistance((double[]) this.patterns[i], this.neurons[j].weights); break; case Distance.NOMINAL: current_pattern_distances[j] = nominalDistance((double[]) this.patterns[i], this.neurons[j].weights); break; default: current_pattern_distances[j] = euclideanDistance((double[]) this.patterns[i], this.neurons[j].weights); break; } //check the distance to the current pattern. //Then, find the position of the smallest distance. //The position corresponds to the neuron that is closest to the pattern. closest_neurons_per_pattern[i] = Tools.positionOfSmallest(current_pattern_distances); } } //Return the array containing the positions of the neurons. Each position //in the array corresponds to a pattern (in numerical order) and each //value at each position is the neuron closest to the pattern. return closest_neurons_per_pattern; } /** * An euclidean distance. Taken from the ClusteringPlugin v3.2 for Yale. * * @param e1 The first Vector * @param e2 The second Vector * @return The nominal Distance between both Vectors. * @author Michael Wurst * @version $Id: EuclideanDistance.java,v 1.4 2006/03/21 15:35:24 ingomierswa Exp $ */ public double euclideanDistance(double[] e1, double[] e2) { double sum = 0.0; int counter = 0; for (int i = 0; i < e1.length; i++) { if((!Double.isNaN(e1[i]))&&(!Double.isNaN(e2[i]))) { sum = sum + (e1[i] - e2[i]) * (e1[i] - e2[i]); counter++; } } double d = Math.sqrt(sum); if(counter > 0) return d; else return Double.NaN; } /** * The Manhattan distance. Taken from the ClusteringPlugin v3.2 for Yale. * * @param e1 The first Vector * @param e2 The second Vector * @return The nominal Distance between both Vectors. * @author Michael Wurst * @version $Id: ManhattanDistance.java,v 1.3 2006/03/21 15:35:24 ingomierswa Exp $ * */ public double manhattanDistance(double[] e1, double[] e2) { double sum = 0.0; int counter = 0; for (int i = 0; i < e1.length; i++) { if((!Double.isNaN(e1[i]))&&(!Double.isNaN(e2[i]))) { sum = sum + Math.abs(e1[i] - e2[i]); counter++; } } double d = sum; if(counter > 0) return d; else return Double.NaN; } /** * An euclidean distance. Taken from the ClusteringPlugin v3.2 for Yale. * * @param e1 The first Vector * @param e2 The second Vector * @return The nominal Distance between both Vectors. * @author Michael Wurst * @version $Id: NominalDistance.java,v 1.1 2006/03/29 14:24:47 mjwurst Exp $ * */ public double nominalDistance(double[] e1, double[] e2) { double sum = 0.0; int counter = 0; for (int i = 0; i < e1.length; i++) { if((!Double.isNaN(e1[i]))&&(!Double.isNaN(e2[i]))) { if(e1[i] != e2[i]) sum = sum + 1.0; counter++; } } if(counter > 0) return sum; else return Double.NaN; } }PK 5w+5+de/uos/cogsci/ai/btenbergen/bscthesis/yale/PK Q/5rq::>de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.yale; /** * This is the SOMFileHandler class. * This class requires a String representation of a filename. The file * is then loaded and parsed. The file needs to contain double values that are * separated by a blank space (" "). Every line in the file corresponds to a * pattern and each value in each line stands for an extracted feature. * * @version 08.09.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Vector; import edu.udo.cs.yale.tools.LogService; public class SOMFileHandler { /** Each element in this Object[] is another double[] with the extracted features. */ private Object[] patterns; /** Each row in the file contains the filename of the song, the features belong to. These filenames are stored in this vector for reference. */ public Vector songList = new Vector(); /** If true, the operator will send detailed information about what is going on to Yale's Log-Console. */ private boolean verbosing; /** The file to be parsed. */ private File filename; /** * Constructor. Sets the fields filename and verbosing accordingly. * @param filename The file to be parsed. * @param verbosing If true, detailed information about what is going on is sent to Yale's Log-Console. */ public SOMFileHandler(File filename, boolean verbosing) { this.filename = filename; this.verbosing = verbosing; } /** * Constructor. Sets the field filename accordingly. Verbosing is set to true. * @param filename The file to be parsed. */ public SOMFileHandler(File filename) { this(filename, true); } /** * This Method parses a given input file. Each row in the file is a Feture Vector and is * extraced as such and stored in a java.util.Vector. The Vector will hence contain Strings * as elements whereas each String corresponds to a row in the file. The method parseFeatureVectors * is hence called with this Vector to extract the actual features out of each String. * That method's output is returned by this method. * * @param normalize If true, the input patterns will be normalized by dividing every element x(i,j) by the root * mean square deviation of the corresponding column, o(j). * @param filter If true, features with an absolute value smaller than 1 are filtered out. * @return An Object[] containing java.util.Vector as elements. Each Vector has doubles as elements. * The doubles correspond to an actual feature while the java.util.Vector corresponds to each feature Vector, * i.e. the rows in the File. * @throws FileNotFoundException iff the file cannot be found. * @throws IOException iff an error occured during file access. */ public Object[] parseFile(boolean normalize, boolean filter) throws FileNotFoundException, IOException { //need a Vector to store all rows in the file. Vector feature_vectors = new Vector(); try { String line; //temp variable for current row... BufferedReader in = new BufferedReader(new FileReader(filename)); //we need a reader to access the file... while ((line = in.readLine()) != null) { //while there are still lines left... feature_vectors.add(line); //store them in the Vector. } } //iff file is not found catch (FileNotFoundException fnfe) { throw fnfe; } //iff error occured during file access catch (IOException ioe) { //e.g. file is corrupted throw ioe; } finally { } //initialize the Object[] according to the //Vector size. Important! Otherwise there will //be not enough space for every pattern. patterns = new Object[feature_vectors.size()]; //extract the features out of each vector using //parseFeatureVectors and return it. return parseFeatureVectors(feature_vectors, normalize, filter); } /** * This method extracts double value features out of a given java.util.Vector. Each String in * the Vector is parsed and NaN values are ignored. Every numerical value is hence considered a double * and stored in a java.util.Vector. Hence every Vector corresponds to a row in the input file * parsed feature values. All rows are stored in an Object[]. * @param feature_vectors The Vector containing String representations of blank space separated double values. * @param normalize If true, the input patterns will be normalized by dividing every element x(i,j) by the root * mean square deviation of the corresponding column, o(j). * @param filter If true, features with an absolute value smaller than 1 are filtered out. * @return An Object[] containing java.util.Vector as elements. Every element is a row in the input file. */ private Object[] parseFeatureVectors(Vector feature_vectors, boolean normalize, boolean filter) { //a vector containing all the doubles of one line. //We make use of a Vector here because of two reasons: //1. we don't know how long the feature vector is, hence we cannot initialize an array properly //2. Vectors can be considered as more dynamic arrays. arrays in java are implemented as vectors //anyways so there is no effect on performance. Vector values = new Vector(); //Remember: A line is one element in 'feature_vectors' //-> One Music File //parse every line for (int i = 0; i < feature_vectors.size(); i++) { //retrieve every line as a StringBuffer StringBuffer current_pattern = new StringBuffer(feature_vectors.elementAt(i)); int end; //now, retrieve all doubles in this line; ignore NaN's. while (!(current_pattern.length() == 0)) { //Set end to the next occurance of a blank space end = current_pattern.indexOf(" "); //If end == -1, then there is no blank until the end //of the line. Hence, set end to the end of the string. if (end == -1) end = current_pattern.length(); try { //try to parse the substring from the beginning the the current next //end pisition (i.e. the index of the next blank space) //as a double and store it as an element of the Vector values.addElement(Double.parseDouble(current_pattern.substring(0, end))); } catch (NumberFormatException nfe) { //The StringBuffer does not only contain the features of the song, //but the filename plus directory name. //If the String is _no_ double, it could be either the filename, the dir name //and filename or two subsequent questionmarks "?". This is because two operators in //Yale cannot extract a feature and hence produce a ?. Seems to be a Bug in Yale's ValueSeriesPlugin. if ((current_pattern.substring(0, end)).equals("?")) { current_pattern.delete(0, end+3); //Remove the questionmarks from the string } else { //The rest should be the dir name and songname. Store both in the songList Vector. this.songList.addElement(current_pattern.toString()); } } //delete retrieved double. When line is successfully parsed, //current_pattern should be empty or contain only NaN's. current_pattern.delete(0, end+1); }//done retrieving doubles //store just retrieved doubles in a temporary double[]... double[] tmp = new double[values.size()]; for (int j = 0; j < tmp.length; j++) { tmp[j] = values.elementAt(j); } //and remove all values from Vector so that //it is empty and ready for the next String values.clear(); //store the retrieved doubles in the Object[] patterns[i] = tmp; }//END of for-LOOP //-> done parsing line. if (verbosing) doLogging(); if (normalize) patterns = normalizeFeatureVectors(patterns); if (filter) patterns = filterValues(patterns); if (true) patterns = weightFeatures(patterns); return patterns; } /** * This method normalizes the features in each vector by deviding them by the root mean square deviation. * This is necessary, since there might be a very large scope of the elements in the feature vectors. This * causes features with a very large absolute value to have a larger impact on the distance measuring than * features with a very small absolute value. 'Small features' hence might not play a significant role anymore. * To avoid that behaviour, the root mean square deviation for every column is calculated and each element x(i,j) * is devided by the rmsd o(j). The root mean square deviation is calculated as follows:
* o(j) = sqrt( (1 / ( n - 1) ) * (sum_over_vectors( x(i,j) - mean(j)) )^2 )
* with n = the number of vectors
* x(i,j) = the j-th value of the i-th vector
* mean(j) = the mean value of all j-th elements of all vectors (i.e. the j-th column)
*
* The features are hence updated as follows:
* x(i,j)_new = ( x(i,j)_old / o(j) ) * * @param patterns The patterns that need to be normalized. * @return The normalized patterns. */ private Object[] normalizeFeatureVectors(Object[] patterns) { Object[] newPatterns = new Object[patterns.length]; for (int i = 0; i < newPatterns.length; i++) { newPatterns[i] = new double[((double[]) patterns[i]).length]; } //need space to store medians double[] means = new double[((double[]) patterns[1]).length]; //need space to store root mean square deviation double[] rmsd = new double[means.length]; double tmp2 = (patterns.length - 1); double tmp3 = 1 / tmp2; //first, compute median of every column in the matrix. I.e. Every j-th element in each vector. //take every j-th element... for (int j = 0; j < means.length; j++) { //...of every vector... for (int i = 0; i < patterns.length; i++) { //and add the elements... means[j] += ((double[]) patterns[i])[j]; } } //...then... for (int j = 0; j < means.length; j++) { //...divide by the number of patterns (i.e. how many j-th elements have been added) means[j] /= patterns.length; } //second, compute root mean square deviation of every column //for every median... for (int j = 0; j < means.length; j++) { double tmp1 = 0; //...subtract the median of the j-th element in each vector from the j-th element of the i-th vector //and square the values. for (int i = 0; i < patterns.length; i++) { tmp1 = tmp1 + Math.pow((((double[]) patterns[i])[j] - means[j]), 2); } //then, multiply with 1 devided by the number of vectors minus 1... double tmp4 = tmp3 * tmp1; //...and calculate the square root of the outcome. rmsd[j] = Math.sqrt(tmp4); } //third, replace old values in every vector by the old value devided by the root mean square deviation. //run through every vector... for (int i = 0; i < patterns.length; i++) { //and replace every element by the old element devided by the root mean square deviation. for (int j = 0; j < ((double[]) patterns[i]).length; j++) { ((double[]) newPatterns[i])[j] = ((double[]) patterns[i])[j] / rmsd[j]; } } return newPatterns; } /** * This method filters potentially irrelevant features from the set of patterns. * Feautes with an absolute value smaller than 1 are set to zero. * @param patterns The set of patterns to be filtered. * @return The filtered feature vectors. */ private Object[] filterValues(Object[] patterns) { for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double[]) patterns[i]).length; j++) { if (Math.abs(((double[]) patterns[i])[j]) < 1) ((double[]) patterns[i])[j] = 0; } } return patterns; } /** * @param patterns * @return */ private Object[] weightFeatures(Object[] patterns) { for (int i = 0; i < patterns.length; i++) { for (int j = 0; j < ((double[]) patterns[i]).length; j++) { if (Math.abs(((double[]) patterns[i])[j]) < 1) ((double[]) patterns[i])[j] *= 1000; if (Math.abs(((double[]) patterns[i])[j]) < 10) ((double[]) patterns[i])[j] *= 100; if (Math.abs(((double[]) patterns[i])[j]) > 10) { if (Math.abs(((double[]) patterns[i])[j]) < 100) { ((double[]) patterns[i])[j] *= 10; } } if (Math.abs(((double[]) patterns[i])[j]) > 1000) ((double[]) patterns[i])[j] /= 10; if (Math.abs(((double[]) patterns[i])[j]) > 10000000) ((double[]) patterns[i])[j] /= 1000000; } } return patterns; } /** * This method just shows the retrieved features in the Object[] by sending it to Yale's Log-Console. */ private void doLogging() { LogService.logMessage("Number of patterns: " + patterns.length, LogService.STATUS); for (int i = 0; i < patterns.length; i++) { LogService.logMessage("pattern number " + (i+1) + ": ", LogService.STATUS); String s = ""; for (int j = 0; j < ((double[]) patterns[i]).length; j++) { //concat each element of each array to a string //this avoids that Yale prints out every feature in an own line //but all features of one vector in one line instead. s = s.concat(Double.toString(((double[]) patterns[i])[j])); s = s.concat(" "); //just a separator } s = s.concat(songList.elementAt(i)); s = s.concat("\n"); LogService.logMessage(s, LogService.STATUS); } } }PK /5558de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMInput.java/* * Self-Organizing Map Plugin v1.0 * for the Yale Learning Environment (http://yale.sf.net/) * * Copyright (C) 2006 * Bastian Tenbergen * * School of Human Sciences * University of Osnabrueck * 49076 Osnabrueck, Germany * email: btenberg@uni-osnabrueck.de * web: http://www-lehre.inf.uos.de/~btenberg/ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ package de.uos.cogsci.ai.btenbergen.bscthesis.yale; /** * This is the SOMInput class. This class implements the actual operator that can be used in Yale. * It takes a file as input and parses it using the SOMFileHandler class. The operator then invokes the * Self-Organizing Map and performs the classification. * * @version 22.07.2006 * @author Bastian Tenbergen - btenberg@uos.de */ import edu.udo.cs.yale.operator.Operator; import edu.udo.cs.yale.operator.OperatorException; import edu.udo.cs.yale.operator.OperatorDescription; import edu.udo.cs.yale.operator.IOObject; import edu.udo.cs.yale.operator.SimpleResultObject; import edu.udo.cs.yale.operator.parameter.ParameterType; import edu.udo.cs.yale.operator.parameter.ParameterTypeFile; import edu.udo.cs.yale.operator.parameter.ParameterTypeStringCategory; import edu.udo.cs.yale.operator.parameter.ParameterTypeInt; import edu.udo.cs.yale.operator.parameter.ParameterTypeDouble; import edu.udo.cs.yale.operator.parameter.ParameterTypeBoolean; import edu.udo.cs.yale.operator.parameter.UndefinedParameterError; import edu.udo.cs.yale.tools.LogService; import edu.udo.cs.yale.tools.ResultService; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.mlp.som.SOM; import de.uos.cogsci.ai.btenbergen.bscthesis.neuralnetworks.perceptron.PerceptronInputException; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Distance; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.Cluster; import de.uos.cogsci.ai.btenbergen.bscthesis.tools.OperatorTools; import java.io.IOException; import java.io.File; import java.io.FileNotFoundException; import java.util.List; public class SOMInput extends Operator implements IOObject { /** a class array containing the Output classes. Syntactic sugar. */ private static final Class[] OUTPUT_CLASS = { SimpleResultObject.class }; /** The Results that are to be printed on Yale's GUI. Enumeration of output neurons */ private SimpleResultObject result_neurons; /** Enumeration of processed file names */ private SimpleResultObject result_files; /** Enumeration of all file clusters */ private SimpleResultObject result_clusters; /** Enumeration of all files close to the hummed input */ private SimpleResultObject result_matches; /** The file that is to be parsed. */ private File filename; /** if true, the operator will send detailed information about what is happening to Yale's Log-Console. */ private boolean verbosing; /** Sets the number of columns of the SOM. */ private int numberCols; /** Sets the number of rows of the SOM. */ private int numberRows; /** Sets the number of classification runs. The higher the number, the more acurately the neurons are trained. */ private int runs; /** Sets the maximum value, the random initialization of weights and bias of the neurons must not exceed. */ private int maxValue; /** The Topology of this Map. If true, the last neuron of each row or col is connected to the first one. */ private boolean closed_topology; /** Sets the learning rate of the winner neuron of the Self-Organizing Map. */ private double learningrate_winner; /** Sets the learning rate of the neighboring neurons of the Self-Organizing Map. */ private double learningrate_neighbor; /** The Patterns that are retrieved from the file */ private Object[] patterns; /** The user's query input */ private String hummedFile; /** The song clusters */ private Cluster[] clusters; /** The metric used to measure the distance between each pattern and each neuron */ private String metric; /** The different metrics the user can choose from. */ private String[] metrics = new String[] {"Euclidean", "Manhattan", "Nominal"}; /** If true, the input patterns from the Feature Vector File will be normalized. */ private boolean normalize; /** If true, features with an absolute value smaller than one are filtered out. */ private boolean filter; /** * Constructor. Just calls the superconstructor with the given OperatorDescription. * @param description */ public SOMInput(OperatorDescription description) { super(description); } /** * Gets the ParameterTypes as a lists and adds the parameters for this operator. * @return The appended list of Parameters */ public List getParameterTypes() { List types = super.getParameterTypes(); types.add(new ParameterTypeFile("Feature Vector File", "The File containing the extracted Features.", null, false)); types.add(new ParameterTypeFile("Query Input File", "The File to which similar ones shall be queried for.", "mp3", false)); types.add(new ParameterTypeInt("Number Neuron-Columns", "The number of columns of the SOM. Together with the rows, this defines the topology.", 1, Integer.MAX_VALUE, 5)); types.add(new ParameterTypeInt("Number Neuron-Rows", "The number of rows of the SOM. Together with the columns, this defines the topology.", 1, Integer.MAX_VALUE, 5)); types.add(new ParameterTypeBoolean("Closed Topology", "Choose the topology of the Self-Organizing Map. If checked, the last neuron of each row and column is connected to the respective first one.", false)); types.add(new ParameterTypeInt("Training Runs", "The amount of training cycles in which in the neurons are trained.", 1, Integer.MAX_VALUE, 100)); types.add(new ParameterTypeDouble("Learning Rate Winner", "The Learning Rate of the SOM's Winner Neuron. Note that a Learning Rate of 0 causes the Map not to learn at all.", 0, 1.0, 1)); types.add(new ParameterTypeDouble("Learning Rate Neighbor", "The Learning Rate of the Winner's Neiboring Neurons. Not that a Learning Rate of 0 represents a WTA-Network and a Learning Rate of 1 turns the Neighbors into Winner Neurons.", 0, 1.0, 0.25)); types.add(new ParameterTypeInt("Maximal Value", "The maximum value of bias and weights the neurons may not exceed. Choose -1 for automatic computation.", -1, Integer.MAX_VALUE, 100)); types.add(new ParameterTypeStringCategory("Metric", "The Metric used to measure the distance between the patterns and the neurons.", metrics, "Euclidean")); types.add(new ParameterTypeBoolean("Filter Patterns", "If checked, features with a very small absolute value are filtered out.", true)); types.add(new ParameterTypeBoolean("Normalize Patterns", "If checked, the input patterns from the Feature Vector File will be normalized.", false)); types.add(new ParameterTypeBoolean("Verbosing", "If checked, the system will output information about what is happening.", true)); return types; } /** * This method is called by Yale when the operator is created. Nothing is done here. */ public void initApply() { } /** * This method is called by Yale whenever the operator is applied. The file to be parsed is * obtained and the rest of the parameters are set. Then, the SOMFileHandler is invoked and the * file is parsed. * * @return Just an empty IOObject array containing SimpleResultObjects with the results of the computations. * @throws OperatorException - This is thrown when a Parameter is undefined, the file to be * parsed is not found or an error during file reading occured. */ public IOObject[] apply() throws OperatorException { try { filename = new File(getParameterAsString("Feature Vector File")); verbosing = getParameterAsBoolean("Verbosing"); closed_topology = getParameterAsBoolean("Closed Topology"); learningrate_winner = getParameterAsDouble("Learning Rate Winner"); learningrate_neighbor = getParameterAsDouble("Learning Rate Neighbor"); maxValue = getParameterAsInt("Maximal Value"); numberCols = getParameterAsInt("Number Neuron-Columns"); numberRows = getParameterAsInt("Number Neuron-Rows"); runs = getParameterAsInt("Training Runs"); hummedFile = new File(getParameterAsString("Query Input File")).getName(); metric = getParameterAsString("Metric"); normalize = getParameterAsBoolean("Normalize Patterns"); filter = getParameterAsBoolean("Filter Patterns"); int useMetric = 0; if (this.metric.equalsIgnoreCase("Euclidean")) useMetric = 0; else if (this.metric.equalsIgnoreCase("Manhattan")) useMetric = 1; else if (this.metric.equalsIgnoreCase("Nominal")) useMetric = 2; else useMetric = 0; SOMFileHandler somf = new SOMFileHandler(filename, verbosing); patterns = somf.parseFile(normalize, filter); LogService.logMessage("File successfully parsed.", LogService.INIT); if (verbosing) LogService.logMessage("Invoking Self-Organizing Map", LogService.STATUS); SOM mysom = new SOM(numberRows, numberCols, patterns, learningrate_winner, learningrate_neighbor, runs, maxValue, closed_topology); if (verbosing) { LogService.logMessage("Before classification:", LogService.STATUS); LogService.logMessage(mysom.toString(), LogService.STATUS); LogService.logMessage("Classifying...", LogService.INIT); } //THIS IS WHERE THE MAGIC IS DONE! mysom.runClassification(); //THIS IS WHERE THE MAGIC IS DONE! if (verbosing) { LogService.logMessage("After Classification:", LogService.STATUS); LogService.logMessage(mysom.toString(), LogService.STATUS); } LogService.logMessage("Classification completed successfully.", LogService.STATUS); if (verbosing) LogService.logMessage("Measuring Distances...", LogService.INIT); Distance d = new Distance(patterns, mysom.output.neurons, useMetric); int[] positions = d.measureDistance(); if (verbosing) LogService.logMessage("Distance Measuring complete.", LogService.STATUS); if (verbosing) LogService.logMessage("Creating clusters...", LogService.STATUS); this.clusters = OperatorTools.createFileClusters(positions, somf.songList); if (verbosing) LogService.logMessage("Clusters created.", LogService.STATUS); if (verbosing) LogService.logMessage("Recording Results...", LogService.INIT); ResultService.logResult("Output neurons after classification:\n"); ResultService.logResult(mysom.toString()); result_clusters = new SimpleResultObject("Clusters","Files displayed in clusters" + "\n\n\n" + OperatorTools.showFileClusters(this.clusters) ); result_matches = new SimpleResultObject("User Input","Songs in Cluster that come closest to the input" + "\n\n\n" + OperatorTools.findQueryInClusters(OperatorTools.convertFilename(hummedFile), this.clusters) ); result_neurons = new SimpleResultObject("Output Neurons", "Output neurons after classification" + "\n\n\n" + mysom.toString()); result_files = new SimpleResultObject("Files processed", "Files, features have been extracted from" + "\n\n\n" + OperatorTools.displaySongList(somf.songList) ); if (verbosing) { LogService.logMessage("Result Recording complete.", LogService.STATUS); LogService.logMessage("Operator \"Self-Organizing Map\" complete.", LogService.INIT); } } catch (PerceptronInputException pie) { LogService.logException(pie.getMessage(), pie); throw new OperatorException(pie.getMessage(), pie); } catch (UndefinedParameterError upe) { LogService.logMessage("SOMInput '" + getName() + "': File not found, please specify feature vector file", LogService.WARNING); LogService.logException(upe.getMessage(), upe); filename = null; } catch (FileNotFoundException fnfe) { throw new OperatorException( "File '" + filename + "' not found.", fnfe ); } catch (IOException ioe) { throw new OperatorException( "Error reading file '" + filename + "'.", ioe ); } finally { } return new IOObject[] { result_matches, result_clusters, result_files, result_neurons }; } /** * Returns a copy of this operator. * @return A copy of this operator. */ public IOObject copy() { return this; } /** * Returns all Input classes. * @return All Input classes. */ public Class[] getInputClasses() { return new Class[0]; } /** * Returns all Output classes. * @return All Output classes. */ public Class[] getOutputClasses() { return OUTPUT_CLASS; } }PK 5+[GG LICENSE.txt GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. PK L!5 META-INF/PK 5XznnMETA-INF/ABOUT.NFOThis plugin provides an operator for the classification of large feature vectors with an Self-Organizing Map. PK Ѝ5}3G"RRMETA-INF/operators.xml PK$}S5R+G!1~Plugin-Manual.pdfwTS/FAzQR#"]zD@j*5 Bޑ{;j9{}wswJfug~>{y*\X3AN"92 /_53ʚS-,AkJɓ0\NNv ͸K}u,n _A]ǩ0US Ug ez&SKm^``9 :"^fXLO귱i;Ր͐22vqHa2vJo>Vg/37bu?tS_\20z>OJ7s]6q*DISow#j3ݵ˜rQʔŰ+#Hg_{ْ!Y}.TaؽOL&MpzI {δ5 {TB\nJvZ/+fQnv(u Q%8ݛGO!5W@=^6C sq$:N"_K|e& 3wt:<ĘfJ}SuOA^2XE3d(99eMk~량. Զ \%ML"kIFn;P1Qq_'Я z !! ) ))9C*r j RR*z*jZ:::2JFzZƇtY=e?x@LKNJNܶw1>=<{]|p ࿗{nj*{xxwS<|\FגD\/FQb݃Iyx<U~ldlbem%2*![RrY9yU5u ]='&gfVk[;ӳ ?WO ='xKhFX3\bz($<_9ɳcdx5όzE'SGbK ǂOY |t3s nЁM+7TkG8ڹoKMrIx:"ϹT 8Ƞ1k p+,V|3]` 'J%)̚XL&Lu4w6ɳUzC yܢh w,=D- ^A8+9~9+Cn":U 5rBTAFi1]+V2#*.NgB'(:1_*t,hu_&'$ 4*=L~WE} Yo*O%ooD bmJRk? UWz;MƀWQA F{܊FP/đݕ7!BeڠgAy,~c{/FXnGL-aHGwnoʰ3- d_8`3:G1 r z0KEDfc6Y;2h\}eH$wqkȍLJe˚TgB{{[YuYuU̻{UK/ "ˆRd3LH>f 9S 냑[@,8jBٲH{sqo[%Gg|?׾4ѽ[hb!(?jLENpa0v %@ۤgP\Ԛh)Q1d{A9'YaX߻ZVݘ>?;cz"q0^x2J'adIZoXxkUx~받=t֪ ^ 9ǝ=Ug#)R,tMY* CJ2kOᓈn!klp0ia }{􏀻XASߗMQw(60;|P1M]q -o^ߥbqTBQ-YES*1&bWowj*^IAOn|(^@Ɩat*?Z+|] D!lR&)R~#4R[<|N|Z Erеc/Mt'h.rMɞ`Ԃ'.㯦bA' /c\B=lq+"꾯7ιMy-иޥg C=1,3#1aG+(ʫiVu~ ^;.jg2/~fU(ZtR{>DG3?04o ZcDPցiEGTcQ#뻬]t]hRӑ >>NJlo +GV2>YNUG}4` Ǔ57J7W,yBy޻QvsC3yj=mhZi2YD^,kQJuI|aEĨ912\s'c؟kXTMx5JkTzImrkdٷP.HT򪏹9l^~>Kw=sQaalP8zBM)<ՁhgND6)0eGL6-%QoSi/x0:O1OܴfbW eZQG4)27h&9Ґ[P4s4-HyXZ htpoMKwBFP($'{GSĚ*G3EOioLuCQ^y*KAҲc "[еzQ ȍ^)2]& Psr! )\ z^Oy_=-S``PQ<bM 3+*bYA;i鈅XR>ءffuy ⻖ȋomȹCFrJj ~pV5J1HxC2^*Sc3=써=3 (aLͯ^cSNj\L^V#xR9cu V25b!zu( uZcFY=ѩ9$ooqiSN=tyS|ژ+dNQ܇~3AJJlrCujI2ԜX-^4bqfD[V1_mC-ˡg)5VLe>B#':^,N'1gjvYl`w, oXzVڥ?CUWRN|[b_4uh$kJk^gԭ·Sd\֐",J Kz4a4qbsPDr雬j[@XbAi%ΰlwXKَEZu8@ 'T.$p 2qty>.*B=wXt4=YiW}s#L@VZӲqBL"?q*A..~Yt*f |4ySd/ `ߔU(:j%oE/E;qyK;r)v|n*ўVzhjd M!!WB,dtR9#FQNG 4#Mq#!Us/72XIT^物1r'C~o-~Pp@-_Xr2)F`7[$\"eɫ{<vʓ6V(.|##Pj|d>vz{@ǕAB:1L`!-BcZ{үعFvkHrDvU }onRfoǰxr^f̫@MlcR% >ש`"" ̕;䪰߅bRXX0!.hQM@!яyܨof [ n.y "+Vb0)>`0~TP+CdUoo"YØ:kY$;2_*+STټv)0fJNڝ$wQ?ya3_.1NR\>]oM!ns_OT_\=ǜƈWcvI[?HGذ.эxN!&j=ɚ4j8)Гg:L8[w' Vҷ?Ytxf\@#%"ORȲTf;u͂ -~"1Շbg`K-"N6税RΗwI>>7ox P6DBr6\ pYwm&K,=eQg#tcdMoL--+9O[G$h7I}j+#c'V6~=hkcrFiGV+4>v X7]2 0R-ovW0G[]e{5yG&}9ҧcO:[C4d||"D_RzF׉G7±2;MϞG\:2=uɪض"Ă 喟qx%nBhyJr[=Qk28R)!x":I~?'6e:4 {k:>G/Sgb'Y:7]}Îi.%[4~ȳ/9bxnalZA'wfU\hb;JMk}H{NYŜ|{yvs$e^|GJC ;0[x{ nݦΝB!ԏdSm !BqBUd_[|kլQ v`ؔgw@7q+xT wv^ݱy<_ۉ:Ԙ?ѽ84[͚8'q,{Ӕn1"@󟗒)[$ht"rhGpr#hggjFDa꒖8@TZp f:qThM-T--oJ~ t7 0clY9R3No-xb ӏS}$n-d38&Tf*?/ FRo݉įk$Id~T! IℊG~0:jzn}\vˈnX$+^#V)~vXVrD@cz]ZOH>/f-(&QG?NjQY :p&ً8qSҤ런yn[M6e&To%%s&܃p0 _Ԁ@jn. |56^/0+ch妆k|3B`20#ޡU @OL!̏nK_̀r9ې[>8nROڍSR?[E;~-d$jϱK=D PAuyhuM]7W GguZ׻G>1)ZI^^,g`Py$0,gܺΟt;[YN/43 BQ#3Vxu rJ [+ZZ7Wa??TΠfR)pI`s;sV6ф"ʢK(bNC/O2\kC"ilм/"v⸴"C %ϼX88XEbP5RU4󬮨 cf-&ߢ6#P =*T:+QŊ§Br^qMʃߌ:<3ٓ+5 K/_w4>Q!!3Ɉ(W`Nܵn\T?gPHe!yl΀00[~*GW.GFj5B~^LʦE.ʱF?aIi?p9h"xGs3.~5 r9|n]h|0Quy V3ND a58AܘIᚾ׳05vȲg촡qӞ4L,7`Mӓ ~NT8З0[=gbC -+,_rhF[I-n`̀{zɃ)(ıY9wt\N=3, +!FIFF˛r'I~Q?pEZOUrDJZV"'_xyDי͹+RVJ{jF3+Yxk &S`2Ov/>~W6?fǠ-'ꘜ=y_w D/:sš4gEYAcdWEidp%%HK|b* | q ^8ykB (}/XtM|:I|\d! |$*';}ᩇh麧e\01cW\ZJ0扣GR,MחŔ?<8o6gv^GԮbd%0?SKb[fN;86frU4S|}TxGf% %,Jgx=ns Z :mO]h ]ZY%Nl\/cF5u/s\{a pL4ڶcdQ=>?bA* eR ! (XmFٚ 474M?'MiP8@—a՛uS8>C|#oKȗ6ب7ļS`#;aåI}%ف}D<|>%!9 AȃXawIYD2C~MPS jf{ I!Jthz}qȠT㦠ˊܹ9ǷP T~uѹlR^dQ_MK!?ѩ?r|K[@ӗ8Ulװ< 4&0IV`rz6^Qw4o2&Pqd_nְ$b £VϢT#"&`p[Ht媆G 8yYexG+ ߬7+@uki cě"82=ߗqUA+6}tj}kX J 4P4pl58[Q$B`j$O,]e(v]5Fq=@L9CrVv=,6Q*Юj@@7vRG%;%G`4</ iNJiy`3ڱ_#Iv?Gz[(ц3tS5۳? YN/uaHhQv+ esO/S@VN?[ҏ-ܓ4zӟ)':# 8#hCTzt:'Hڸ SR& тfO낧s my2 BWa3YX[ٶd;!RiE@}i%I9(w z]=WD=?l@E&GA ? 8qB N sS`}=zgh5e$JXVupZBkV݈ -$aGhbmWYGdZ\mE)K xzLUTz3hE\}i^hM k2) hJkQx:eOl*9b0Ƕ=SXoQtv{YbW G:Y`,!换'Qb+seceP׍tRtNY6\IPM 3Q.AE)=C:Xcͭ=M~"zƙkg =v0nW+N)Yݻ#ęoѥjGGmoJOWphyJB<&DAQ/.˰uA$a5*Fà )w^u>GƢkf'.wlft,O\ce/!UZ̲$+hpl>+eng^q#h!$k=aLޒ/LZ綉8\튨N #9(1h5ӴzNӲsK=H5@AR̭jˏ>#Wpo3̒Ԏ"t\3tG9 V*M yE{SҊRXj\O׳t9R 3{zz*GsycdvQ ^<vOĆZ(褤h$ tNf'#bCd='PO Aº jP.!N^jW2)WA\rh qT+I9cth\6OWO\?w`f(3nt|i Ҽi1Mߩ9+A7l Xyx lY{MbQC5 څ 7EoQ"D> $1PdzJHmCŃ? F}4q4_ʕf[/FK>v L SZp Zj p{DFωo.$\G @c+уYE.{e4/ܱh%F!,XƷQ6F`L,\h.f5 ovQ6t-CP)\}Eɨ o%}tiP`jX\h:Q%ٴ1DMFf~㛙WW](ͭG3N VjѪ6) <ُ֜'m kFI o-v.wfy(*;(Xx51-,"BGa*]ZkjqQ-9%9߲5K+"a0L"RiEH!v)@\[ U_rP@ ! eT$jT^!tϩ_ 1w+1V %T82XX_trʛkcgXMi'!1VS,_z/Qr4HK2f[I~# '7sn@#>ȃPS=`&lr|ej}Oc-C?/|t#WV#9.[|ax^ڛ\O{jo@uׯ&HqO.W Â2 @يUˉf(zfN=nX{sa z Sha"˝corMWaCP``HJjTDPO: t9 {S&hNJ>ZW\ Ԗ<$WmRcIn Qa1(R̞g9]ji/~۩fld" Z;m|ݳw(~ Vs]8R层3CŜQ~@# $;m9sjc= _PpƏJ&6WyųgmR lg7ՠyǵ-dE,%b%%!+QOX**(LU#V >,(% -ds\o9u݆PTك?^zfQ,sԚ#WtoM ^OT)M#1%ƣV'v̵A08F%ʼnn >6Y۟e, D^HbWZSfEUsFNNetS_-Cxx{\[}m}ug* )USV&{ [&YB:oRUI 22 cs_z ھJ$J%`hNxG߅0;2rR/.EV=8)Bva2{p1ޔV!p(:_ F7$bkP_r~.dPE)i0VWo^FCj-F ;ʫZ4:ZS6.O*tsn&št/ϜZRrSG,/ph*ŞpTrX}*=r35Ĝx${{BC"nCAyA5Ӊ⏖\ɜl3?r 8#'KKx^DhȡuM_ۙF): ̥isƕkibls,x}ЂóVxT&!;q OPcZa>jQ,RC=jؤA[Xxb쵡NuIљzum3`5zZd(X};c0 .{N^m<9qpP8o.t)'řO;ip|ޫQ|bIsr(޵?ηOI$k߿mvQ) `u0mKdiZAbAoJb$ῃWu&, %›i&c>7D!N=m'gA..7(z|ҭȓ WƸ[H xDy;z se(CÅ&l[^?hxHDŋtZ vs+fGv \t@ :&fCHRt.]  7rLMa]h*sc$T]%kt||:w%O/p"ANA'E0OkZXIϢ2:. u XN𣶹=@;?WWa]㐉u~YvHFJ<Km)Քh !T*\c39 *I}ZĢp8ZQAśCew(7ੇ]j}RKWB.AW_,%vAJՐ|BUa&)TW5V^KNy>R,4Ps)Sә&NgER0zNp2 'K]/ea1MgQ.]ZMFWw[,Ċng#ʠk"%L0m?w4L[YIC~">5:rR2P ~X HO=0XAdpnoT$-UBc}]V¾+K!A(w&_dwu4l|SHb=(c|TvR) 9T]6L: "gyŇZl}?oÍ/M1{zwe2E]Xw$HvH6w?PL! ۈ!1ZN#p5VfU}W@/G 3Okxm2~e%ph̽?AmQC__/YYh-\ BhxYYΝ(K,78%LQdkm]|*78bՈkZ-Z؄mВ s[ kxNj9r{veBJjգ ? _MGןzOR(H'ץb&+e[SφR*G S*pզlV\<)!3|z쳌Ө17K^%[-H{=vo[mv~.E8:w06ς hg^|xx녷g+cV ݙ1ϴ$J^`^uoG Nd}. oeN7!ڗFL>[WX$wKd"q<3s*}'S͗w5mdʴNs[s)<>˟O^Y;W:J2o]ÿ_U.Dv EUTBcMceu%`,Jo_;r0V9DhI/$x:m^Aњl99:|Gjc.p s‚5߉ϮD^5hՑ,F{+BxZj/%kEb]- ,N[*HKQe фow"mdz)(kh5ԝ ПչYdf"̝āF!dE^i&sx\HIa IP]G*Oų٧+U+[үJ0 _n)JrɎ9$"Vwx;JJv6%N}wП'w"-_8+}1}Q?5̞7]~9}Mo*[08VΕg9) S6ȗqL[R*C EQi)*sGAJ,fN*# $K.lj>'*%!oooK>H\s1gt 脽+wN݊Sbb/oBq]tz^6ڣ"jA_M nٲǹH5>0U&o_1r 0E*, NkVmj&/ VƾzCG gr7( pY&̛$s,s96ˡ,qce3LK Vo}o;^M'8˨.jħ3w7nyfCon 1/kRu@xǰl`SfV5݇!w>$L0%{/u8F.}E[Y`_sE17a0%g0y M "S{\\g @!@aMy")B7R|Me+.$,ׁ'Ga(Y& r-bBR0@lLr,;pNZk[/Y CZ'@ﷀo~&X*TΜaYދ)_`rv_K5*kyF٨dMMn/d|>my`9]=kJKMK<vO::I5Ap,I?iT'5iN@;j?fRz8[c1SiZv&;mIKLy"*X r涠?-rrJUW4&ٯ5p_Rnet8 61?Z) Ξ29o0=t~+.S 3k$ӡhUxS̰1FSa\3cpbb5a^ELs|ў_- c_|X夘NQ=rBVb"[Hf3׿ղ2[@J̵V,@U DIT1+Yl1[#f0qΦbkD,@b"}lk4npk]lԲ^U!ѡSy(&w٘{-LY77̡w=ZxaשՒVk{tļ$2|}7m#X~TdE+(a+ +L+מݱdQTx \V`X$d%;޵o-I[tf Ӳ9A(\\}c)vV[DЙ52٫&ȅ̫Il&1]/ %*ЂM Nw**1&uY; Hn-U_U */C3ȂAtN(tlSH~41S2e]/7SMld-I8h:a=Rh\R>'"jLOЏ_U' p Ь1GMh;87&_Q"'yphύ44ow"]ǎէsՍSˁ#?M~Ih%!,e\O[r! < "A=M3@ED\aէB `Q#/^KYB=n$?,snk/M uL,Mn=SW<=:%n5shT|tRqrz"* wLs&/U\WCɽ^ZMRV}_UL +8!7T8pL꽇m3w?*qω`5Y&U # 0,׺^|7t̓rkMq7#:9ك#Dٯ ̍ VgaRX4ÖxNEp0װߊ'uXgw)rpzRw!%K2nٞ˹po8镥ǣWI{*tX]ny )?50h .4: 䬘6]t(g;J=> MUS-&u&3(SnL º G˴}ˀ: jrl<6P[ke "9-}Mwy<{;UniW;1Kz?2CgɃ6?7 ~OLu +j EEmNQZkWÁz4ٯ5,*^  7]LO- .8$Wo ^E*y\s:Y">@SnnW$)a7]&v&N}q,Euqp`-,+dn(VZdUvSvтZ of$_l%\q\Dl` 6 HeW{aX Qc*r]"yw 0eJ2m uL,򞨚%A\|YŐZ(nf-5Ӝ;ʪAu m?FISq$|3$Ǜ̑Qf -L9˚-Twu9֋.VӅ83PMK&>k=~# =hTCJO=!WTthNOjك}+:{s{zOݓy#!ŎaK}9eB'xέ[q_TZ:aN"׉OqU! #-_Io?<h;2'"d76<_QT4@*MޱdBlFo[zTE8G#ӰYaɬ{72PZĂuqn!0Ueb\ʭLsc|R |vHbݛYwiMHL0 լJԄzzgW/,'o`8llY{ovj?P'v-؊ zl|A(w.sTu*[ADߵ][V]fs kt @na<5Xppm&V3F*~3P_84AѩvJV/„ ռ nJb~_=w[Qi_ذzx)@jykb:xߑvѣo].Vﬥ;zL+ȔI{.ʔ;.fqOn)5~u:?w!YT&aX=:Y8$Sj?fm߿Tzt;WχTLZIٔ6K{7lޓ_N+0QI͋‡ȵt?>%k1M& 6+stdKo_C-hbZ=!ZEkk#TH\'@U׶U#U,,2I5 "[x(1ܲ5)xO@^_8T^CA?͙A@xU|\a~ű:TymhD"'X d_g H,ü9 XqY+R2W6~t\K+Y=82:{CD+96BTi65wbμMs^He@*:m&jL30pN ׂ-$\g|BpF.'[cXAKSa‚xEl̻S>V#jS6*vjNA#K56!Y֐ݠds0MF`g$-OLH}RS*Na`c `mN-&2ZaM5m9Y>R~?L:;ap6ќӇ[@\NO|JLoa3Z2F )Pܒ3sUŚ8Y?tYV)~nl%uD٬N$ݮ*(g{%&s.^y#:+~;zm5:-.|n,3X;omfT;ARBntr)c@fn a؜y_]s*%@A%{ K+F鰔O6gA::_ 0;"/<ܨ 6xI x8=5Dӷ:H> LćңTs="9 H*]*ue|Gv⁲#$KL9޺z\ ?ea2LmWDIAՍ24ZYKhj,S^5z~mρfc*_MJqjP36 ||0d¤N+)hLU;wWWW:7!oC=U5W:ߪ$eZneqDYJ]3NyxVC^7W%_QSSWuNقv32 f.8_ gAXdOWZ^#ATiyIq$Iwu@oG =PLZ8s|5mY[!CPcЄ]n =9 AgeFȚuD9kG 6i>1>X$-ۻ mo}*o}hrJQWE9ׁ5^~usBDֵ__(~D%WV2&J}Zի,vԮ,B]&{Ú`PLl@]c{yI5]>CjS?ࡲv/bk_d]3G3"XB F2HIx?8'S=6Jn7yٟ8&=:YߊTL6WmF:V';-owڤ(&>qWiK?Zd&\NI IMs6Lu{["9_4wdpvlcDTY QetG*n8 ;1d,% Pcn鴐"JQ,qY76XOG8Br ~2 D캼CLޫ=ѥ*xp.7Z1}"Be4{qȫ@O}Ύ)3CF)ڃM2j^W)s@U„J["u0/LE5:B=ec(\\R79[?c[@LAOKzoS|(^;&PBi*a?#/So8d]s4~YqSQj-Q$A8>(F6siu5+/!khk" l,ވ,O Űf/)ͤ xNZvm}݉ 64mɐ؂`j< =$QL{+y!he4~@wΖu-#?[ݼFv%r* Rojt+6 u#{T  edDp,sB|ܢQnZZk_ØO4u٩c9$qⰶuInX$M` w?*jќڹfPhŤecJZY\KXg0R)S,lyNQ>Qn/Jy-Sy ?\筫μw_w7/—.o,yT3`?k)a)3!(1\DU kt׈7<^0C>h|xIH9G_TCTǃK՚REOfҤ^gD9Ԩf]//KīOwC&l~yqlW%#u1IhL+N'x܉37۱0YQe#j3_fgu`To<\$j}jp$IdT$)tc }{XK!z-qyhv @b0 FT?ܻ>}WkߌgCl(na [ޔ [蓾퍮m yuɘtx}sO] Ҙx Ⱦn{ei8TJf̳U'ÝQkY<o]HSt/ym5NC'a؊H=t;y*Zd`c̆Vj[?uGLї8GQ a?Wf(Ք7jܱzGJ)cY'*nIvyĐ0?her= IvVT q + 7uA© M:PءYRvҊwV.?0GMnEb1"^{}[<8$~TэJ=-()( jmEgYw[?;nDڟ!j~jx $)e F|E u^`>X Kc|޾ Nd˟x$<+I$͔BbG/-@ɔz6ӛ,]2[Up"3J2~V.dMcqkk$}צ>_.8,-+.t뗖l"'T&쫔J|{KIPX-4:nilO#q_sş[45VOϨH.wTw+qК/OӐA-̑ B Ʌ;!gv׈?9~K cyje:CAX-C6 'Ƹٰ 0gUxped_$97GebfLJKFXA2UuVBtVJ:J{m?l0Oar{`Sh6:xp`Q8?,RilJ"Ҽ&K|ܻj`?γMYZFS7 )2̛ɿԌlI%1?+dr!zKʣ*]oxe/e _Dwfg5 5~K3vGU㯬AOh2cA놯#XІYY4EiY' \=񿽳Udȣ8<Q{<ݦ)oSMDmj}*ѝRG'cr(bz{A>93ấllww 17A0k*i&4= /;ҭ.Vgݐ䦃J(McuUwV+ᐜEGoy%RT(>yqI}Ӌ=[Ґ5adnvhL_}Sy y Ηt⇻L9[5*?g8FyNHrtFuC-x&'V> j!MVm:#E0ゥb O-]n^}>(lzPvsqCs]_R2+y?vY,s:o+^H8SQ>L}ʃ3&؟l7l\pǤN'+4^--.>z"~&8ҟ7I =$PΊ霃TA3/\v;W"7/,9"n P8Ul5"wɚM)vt>R9ceU5/`'ZPSUmes͠zA;3:9-G*~b7g}_3XAEn9yr3 Q|P'^ʉU: xa:2Yo0n>jߧ\uQk+錅9Q};G:zy_n ^) k޹؉Y*fAk/,@[j+o]=PJNJq%)Pȿ)+LHDO;_ )AԷo{Z,a4B3 C&OR$uhOG={`v[} URY*D/p#;7sPR头&s%By+Vu$ѥ.Emzz_ aȢ|0iGMIOO9JAHHۯ{@qA,&& -.P]+>ȓsUCyGhyInʹ"{>MK{[ɫ-Y()K渔&_Zã'+ynR׿υAz;5-SPY߬xC4n3)twQaI߼99EAW*ⶢxa&-8,&uj+Uu}>xO4Ho., khuIo5errK3 (5c kL&:gf_ uPYPZ:2 U$reIZ7|Ǎ1Yф?{_秠T ͵8=.4=Eiǫj9&y^܇<Ӂ `*u;y΍Oq|DC^5(|,XB+jF[7¾wr}zNUX9X@C^?hSMĸ}dT{C r bO3:CC#1נ,1 sL}n@g)PƝSshnpAW#m e)?>V!Q^;&Z=X9M1Rkqۃldl&SoT|e#O)JM"Q_ ՅndNg;gq(7 $%`5A,AT:'fbp쏇?$/qd} (z`EŠ :f=g+F[S_\W)W"\b kݾe= ݷgp~u+~=]"6yUENOkŐ2qFmJdT)"_Vgޞ{ڀHM$ Gtf{fCSTF>6dz::1=I@uQ}&>s|Z)Dxe7ut,l~Cv5Ik J EnڇM˄w}Hl$hUkᣫɩ\w";XP>qַj {t/n9֨xi۾(L.#-Qm?Zh%< wFn3rXvQUu[nWL=FfŽrZr-3Iz|c[rB*+wˋLFxS.ՔpwE%L\eҼ(幙eĸtKCݯb*M4JE򛿄")h+jCBbda-79 ؏U>GИTKh >-:.t\3!\GR8~@+ɳ_I;T"n_C/p\Xú)vs)<2g3"< b魯U0bykP>a|G>|Au(m)Cssˡ'Yb~~V1> ̭g//nmkE&FZ7F7hh\i l%f$6)<5pQd@s=mf*sCFc8\q 2.tJnVt!>txɀ,[2\~%]0ۛ|%x9|'ԯY # ‹{$cki!邺w}\p g(A(o ן?"+>=Ii+r-}l=Y;#ͫEnQ}i0/"T[;ƕo{ X KBO eLOҌz.?_:6IrOo6Lt*G3o)bf5U_X7 t#RJt H7# ݌tItww4tI-L|Ky(vqqS5 ϶'EsĞk03҇7k?z% ŕ6Zzɮ~{tjo}"rsi>ʈ_׌-ZQXOL̨6ߵr7k`=n=(E \opTREGv%O<*UO+̾(Hm=a;Q==U1oJaeBȚE.U ?Z`K3m#CZc6VfdFF:Ef# ˧Ƽ~r]c@dqPԞ L:̩}v&Z/4{)q{n9u~^晚nBkk19vʍ2P.;bIoVmMvy|>WonY;cuht$ 5oZ`2!k?7<3vczI'hGߟmifw1rw\s+&+)QS՞틠vJVa=lgx^6I#R o"U`&߬(9Ηo̟:ܺl*~x+؋hƣ_’ĞX3 Ta=Y#ڨpZzr>h;9N-O32 FrVX)yiQZPS"۳GimWg_TRso=8SheFU;%iQY ຾UnfUʙ} .2$(Yh72ڊՃy ԭDQ[f1y! %i% ); ]= /:yxT=ISL}+ֈV\ ւrMɉ=wɧZf&NSniMC5Gq4?ބf{91L4h:HuCN^zVR^pp~hN}yc$0QI%ke '[h@ԯƺC:KڨL4' N72l_c tEjKY_6 n6pWViSZtZMɐ_S2km= Jeqvr~%fz9\ *G'f7 `K-y'hO|-ez2DtSR%Vr™k~W;Y̧ m½ ,{.UoL`5X_/I]< ?0̄.%tG;+:i/\X}t<:%3uKQhMXO~/* HFOO]5Oe$/OJ6RC%XAMVoQr<: h-` fF 9g1[wr+90YZbkj,U3ѠYO'ZPÊ>]"e$4W(BO2ɤ/MռJUCU]#ffV"Jxy =49}/>=d-kйҮTTc#8DvdͱWnk\4\WHuY9h@픶a㘣Y$FTj7 u9<,vv*RNjFQq*3r˹s#ר*ȒW6.y(5GG=nDu ulWD^l)u]/_MfXx־s9/xgO5oS`#۟Z7`5B;l^0"5o#p^y'ŋF;%;ќ[PO:oxo}[¢tX{,Ag;{|[!XAAK3婛u#NbE]1nhmP}tqϰ \^.lDawQJ!LKP$6yvP:[ɾ%8NiY/d?I&iPFʘ-,/%c1Hgs5rMQ}3,>Srl˻ K6d> ꙱a*'vݙ큝D @JU5(q= Btu֖Ԥ(/ߨQN =;28cM HK!I!ć;i@#l`zC{qIAX^=)bz3?<+G7S;d9ҏMER̊*F}:QIKe#4Y $7[. m`xI(%UkۼfqY,ԻbNe7OIwn30sb$RabP%˗$(lHvAD3h:5Hųw9oKp{wtS8ԺJ6F<ŤLx_I$>aȱBGDx<! ˌhQ4ذ`UPqAXzBaEXxo@oh&i]/m+"\ת%֧~ۖF+@jUήqp)*F__uX\>j%vM/T9ɼ .EP#sXS&ڤ)%ý~煽pp{̷ŁmᶽDL"3BNC$H?|(Rt蹾B^:1ox-ݘ`pg;׷C<ݜ P7n|GhCɻIk ".]MiubG N*qT[8j,ɵ d2A'^({]:vFcwz79LJ>,u*!x)᫞M"ؚ_;_U{vW?wmJkZ,/y||⧒sDg41賯tPt)?ހ{;W]Ֆ>!SbEk,,/-sR}y..UxIp[{]z+s1vt NThap`P1o셄zvfar&1rgl'ϋ58(8OIy^n}/p7$6*~<:/cEW秊6t*«> <!L[6Ts!{ K {N,.p:0}IްN˯FiHQׂ1N!Y"#AR7nc/{ןkj*dj,eäWS`BHm}[$h?Оei[Ikp8H?OM.)^~U4#+g3 *nM cpLtŘۤ%*CDRL{4c!K 06LJZ寪'LE5i13?mXlL*+g(W k")}xiol٭iKS b(~HbI1WaJ8)dwJJ-c5^D L9RK]k_DO侽(i&絉τ˧fK^1uEPU|w'6~z+ʝH³B'-ȬQqh@.?4aaȕ`YAr&?^YفOGh]i$Nu!ۆY&dkBfVK Y4RwWkHEPUCALs>0RlOx{ŕ#*W-PV䇙.k?68p9lenZ.%y쮼 vWLO&P@z:&#7ђžr[d<أB ~r1 w;9d0>c ܦ&Y@9H-P~!U'S1B)D=ƹn=9OF#Yw&LoJd\ZɬUiDXy%N@oYI&,^b&01eF%ٴߦC#ռIoo)E.qE6J'!w| %`Q80iA0d7x1u"\}YL]T@-A$Mҙ~S7ZWcpU7PO(s=q"}seLkB6ؽj5H٨dk'"{|Ò_[=a'7Zɲd'[GUGn(bh>~ ?H}??݃]u`ȕSR|kt#ղS,$-M+b^'C`q")0קKWV3"KqWX6Hi!#)!}_/{Ϫ]Z^nycnH܅;󼓒qr:Pu%|/#TU%{i>_omqҮ%~"Q:PF=pKh` %;Ig}.(OӀI4Xt!Lb1@?m|@Nm| 28k֑-̃0 `9Z0:rXտ45=[D"_E-;#ZP>J>p!g7' zF>"ak˒Lw|Ž38ת02je1D>U2KMFt(=yUs_m{:~d®\ Erwc;2`G?V 7p+t]mÃtq8)e/i_U;$PܴJ{zķv8 MkyK%l){+sf ڐ;)P Je_+yU܃r$+M}FIbW⹟s)es_G_' Uֽbv; <*u|`lҋ("2a#˞/^g/AZ|18QKz&.٠E) k4A!b-b-4ldO:c:PZM4j#^wC ޥK2<$Y8ʵM+=sMOy).XyCPHTx$>׳==yZxu BY!ZR.W7oH|*E)$F)ɏuul#%*ruq6֜^W_P佝8p?, U/jR^05o1j6`Ql aﴆr/.(7Gu;i~lf-5YACbO s׷T1FK92?~xY;y q[Pl 7g2x7/4y1ސo1ij )UP>|7n,5 }R9O`[Wg S?:=~Ϸbby_Y8XZ=Ɣi<~W󿝩[ < <3l9a; R)FM˂ >~씷E=tҏ/2@ r6n>RDKAY_~Ws O;zuZo; KmXT(8f.ctʶW{Wwà?q^qGТޕŭ-QQX#7~E=qNk=kY( lxPGMO&9q65 I(WF|i>,!y#}yWgIe\3D iN>Β( jxO6\n"Mea[p"KzчnxI_%y3_t6$u[jBJ$Uƕ58(bۥw`>鿋9y?jAO!`q5-VAw񘡾w.֐E=r^|ㅡ[AQ_U\r$D~D>1; G,}Ue|ŖoX͍ZQ剐2q,謢 'wYHdxB ^z+kꁾ;Iw } K$~/~OqtqV6jD&qKeK}ϖ"5/ ׆m#dQ\[·spٱ8UtFS:g_-EonR)/zuآ)Ej"2ʖ.:UcSi+Xd"j)2k񅁋p(wDp0k콅jچoGn2؜s@jh"(L~kkN4-D~[9zg4fvtEOeN-[-o?~eUicf~ -3{'-6c9D'zs"H5=ffv&,?L[3Ijz |/d˾>`ecQ1ѧLRܴIma6e3kdάnR{ʟ÷F>5С"[ x7!VEBԑʈ˥&*VكjP ;->r*'4^Vvȵ<t?aѳ ūbABG#-d>;v &Ud vF62],2>4Gn'4?7|mT<{(^^nG1^P^s1x)/GG?{&$U/c֛ВBxȫ~?e~;Aq\B>_ڠ)/V}rgɮVCB-ԩW=HNHap"O+y)ӪG7򧅕NҧaA,o/O'/$澴>X9v<0|+6hyTe0tB3kژ]8ձ˓{[12KdŏKuOJIIُIm!^jX[96Nq]3';eTǢf߼>xNWbq1 iSXDijN'%^cܙ kPpZ^aI g KO)輬aSv[Fۥj.AI, Sxi%C|mgZΟN|7W_f]6yiYE: \OzP4we*eHaxȜ!zbFA|ovF?){9kin& nh>K øU_KRRD(Ikoz f|ﴡN ̘Ej8Mn់${X+"|47ط䔚.߁R(#I.rNFQ)?SRqHų8\j^ka:}`ǧ+3rX{u^ Ñ^Yi,ٌLv.'_, |e5v^ fX񽷡MPey18oRzL[&Aȣ2踶 |28Ptx*X$R!jءk!Fz@u2ѣrn7շ`KWC\*6υe 8N>_=q܌Sɱ7y MsUdeR-JiN]NSv;;AC53oTۦڂoxKF0q2GxE[F_q{kpmƧ} d㣉n?שo6՟V`WY{#B2A"To/G\9?{p;b'"-KѾAb``Qx%ïDj.\;Ϸ>nT{:&=Y*|e| pEOgFqEGaݔLtol~hvy+5T5`OJo1[=cY[M}mfij0.38?8k-Csw_bE?诘'V}8 !x()uEO^YtD5sdz-L`[OT2ػVd([+W$JnJcIw 3$C)r^gضMD^o=ILeK{o~zJjv^{MR-QfN)Y+*~Qެwټg'QQ^ UґbWĭczR}GV6\s.¹26Li`Wq@԰1(gf*JxF`t:P*떛^X-D8d 'ى$+~rRņŹizيmJτ#Rs!M*FOLSh\|a'˸K"/k-ӕVi-+X p}[EZ?m,dg!7йf|i\(E 17Bδx]ŋ?4R4&RL>K3 `y'F>o *М֢O.F ^tF.)*.F,]w |52g6][i-p}ry޺ڭ ont־gxʐawۗ%ަ'SBB}z.^C⛧II޾GɉPTCsv#iՒ$p^lDsiK18d(]q)|KN qDa'~_Owp=9s#c/Yz[hQ5s\ž[k`2dJa>@GX'>`#"RFp69Z Y h2ңPo69Q~FlBGYܞ;?~3N-WfU'qYgdjbO8.U_:{܈DŵE ڽ .C/Tn޻X WWkk!-/oq " ^/xJJܸ#:_/oB#v]3K\mQ`%4Om8e>Oՠ+6dCj]<\/";Vc{ϙdx,p]s&^Vt7} eTx  ?2vCks9fdܾaBA7u^vX@_[%:*+V|'"̏]_V}Nh4wZ4]$2c'ΊVX1('i;ve[2= .z]e}o@40<ԏzm}wt;X]A=V>C~ciHrm?JMP!ä]7sKƣaON]Qɵf9c,Ȏ Ɵ ד?vFcȶڕw>%^|hU"ɦ~h~={d~ۦv?ζy3:>B>uxslFshµÆ~YfHnݦK!#!1&EoSrɶ޵x5<]-k}iq~9rA?Ǔc56$7^ݏ!4S}0trU#٣o£ok:c}?eU~i?\d8}3\)F nMe@a5Ao'ܮ+AY!FSBr 9݇Қ"OSGM?\lLU,x,i"l2ˎbt^؂ -=GfbkOpE= !k:Ox`#暦nE%QRTgkj[ it!1zJEe̞s}s\ ڸ;~EHh":sEn;Mdоrk xX/Y BaYeֻ?z_M^rp?X|uTٓMN(//w| Im7=!9r8o)>t:ڦTpMTj$^/·k}.O7 E6ZEۂy omuBxa1|=JM8}Qڶ3(\RcV>Nr? 8^Z[ J{yi9 > sF;;\w`S;hm X`Hܶx_Rg}ѻ!m x?/e>s_D~ 9r![( \ؠ1϶CO2|ZVPôF<F*UwM|{?ۂ>t' QGRÉ1Oߗ2.vv<`XҸ#l kbUU2Ce(-uޣ˔ɆԵw^) 8g_D{n{F,2YcԟO(c q(F9q@jOhIz8mCl˵xJ8n~ZHͳs`pT08J~3+ٸBLKp-N6!$9MdhmA[Cr oVxY8-5Jb9ȤmV$"% Oܟ%(x>J{1*u\<ކ0ݾB9!H穒\GOHK#h@6ÀR{hq'wT.(!¬)Z ^ŬjM%ڳʵ1J͋Dg[Lާ{Up![);ؐZX=)zD,Ûrw*-^@TkuM+5wޖA׹qv<>2ޞ|7rɧ<,v6i[."/Ii3¼46 u'ӿ`WQ Gl?wᴒM|xRR}zH.\y2A MhX8hH7`MxqJ&O" CL%l#jaW^3.B\zbd&i>C^@RqFdA2|Ο[@sUbc_h;Ű1P9+ h0Y?2̞;ZOe~chR=2Tk kr}5RsFJdck;&uR }ZR= }L.D;+QY_,WwkVq (>){=][HTQY|o{K|$4Kݗ馶 gs)83RDnDF=z8龍O4=kc!67QO Bމ\_a8ϬCo uBѯ9CfB :K>>T>Pd#OM|D!׭4 ma;ރܡNˁ>UDPMjL__Rx<{lM_0eu՚t'I~}?{BjߘVy?yCݸ$74YLǸ1i^μaOt/<9XxdJ7o9hÒIVIV-Pq{៮gl2fՓ29]:2#_d0~50XFO%Dq6K;~L|I(I-C屩9T*ii3coC X=l;Ns#$It7$__>ke |.[3,adM[On ^kV#bF`d ](kY e!=/#G|j9l>h}}Ŀ8`s)r a9A|˨,[}LU3U(z'kD4+:/fKe"X qJG ɳS6|:_EmƙϘA '$u?+%mycYн>cgnF_< PZ7K MQ{[1'04WQT udJ>)D Niۈ8X)؁Sy]2"d4'KVAݹI.cÎ HTL)EJաied>jt.+j\? XHԏ1'+~_ﰁr80a Jp/]/_t;/~^[cZ(NZu@i;j+#HJ&)\fdW!9l$=;P6BF\i[jsPo+X=Z4k`>I<ͣ__v,AG3|vF>ΉC+|޺b4?9yfm^.O:/EprunS U=w&sz4yguhw%|#Mz Yt> |} p5|9S)==BBֹ՘Y6s៞ ~׺/}m+DlY7z">=s9`By,o߇*x7 .?:d*Q ?.~|id)akϟ!`xb44 '9P߽=Yr/I.Q"yH`ildc;\߇tRF?)~55Cu7aRK./2dsyqa'^w}ʉc\RI.9miÓ;E~zf,tOô?調QeǛ~Hr [q2[@2R5O ؂ eș̡rif{nzvL~,zqNm,0̶]1TW&Vk)^Ub)ENHI> }//@/a~UA 9Sdj~L/D΃vN*u˒T*.|{Ofܾ{^*wƤnfR9/7rj 4juF;x6/~bTqy[a1@ MNLJa 磋i8_ &rӵBqK([ҦLBϘM6O,8)%r、_mo;ѧwl孟z4m';l$R/\M~.>KT'^me_@؏Рp3 gO90iyx̫ffcafgtqw.,-\ ?۵k giG^.h3_ß?BB?+B%9E9[-?z }?qwݻwƾw!Ç8xĄxDD$ddd ((I)IHϝ}@G>DoyFbb&Et y֟ǭaiPO} ?aw?ᓼGnDcL}FN2q8T,lB_H+(*ijixgiem90(8$4,6.>!1)9%5'7/Ϲյͭ_;'g??;w`׭4 s =bIulS'gJdWw>`׀93 2ڟؿ5xu <,"peB0vzhKvi9(QDcQR¡(m(^+[yp^ny h'Y/- 7ks[G5`Cl,hFdye[;rbߖaB#s}ҦT- F.Bʰ>8RkT J;À]&`ws{jiGz)+25hVزܤyiLbNY5NoUZՐK؞K EiDQ kEER 0.GHVO_ FVKUNt?MO![cqy50L9̀7zt9V>nB2P m4t:Ն>2᱈mhqLh]T8^6 ЀQu $"qG؟q=\:Уޓdp@‚L ANOр@/4%#K%(l jZ >./hPB㘮|PyR:)n]ܢaI9Lr$&>Zr !eb|k2B c]˒k4`|Ah9S jmCQIhu.l`UMAoPO}o@7vs̃ #'VG"VnG^Ag ,M3"瓾m(4 7Χct]jiyv ®n 4`]{!6P=3< /7@~$, k.tV0lBu _v/ˇb| i57 ܸиsm*-o,WKPO,ccc}]Sf C("当^dF [Gȭ>>W]%ނ-ؤ@r率W H\@F T5g{ h.2V;1j4IhqvN5AӶ3gO.|W}؛-? D4}܅}6122 W'ogPy4v7s%=FGN]x4tARqý-´tA-'I;yBluP\M EݬKLMn nU\1xTD>ۢuG (yxMWAz3#W,by)>=5R6, r%9{60:g(^)`8d'@!|VyqQ~ T֝yՒ-"MVKGfs ؽh_u?o.V1`x)k" PP]DÁ Y4HDOϢ)щ0KtΣt oXot<s×eh?0 C=@YzG_}TQh@!&L :!&^n{]=Ѷ$=x6!jhxPJ'[v5vP0oA%&oLZW3ڎŲOy~:[jsK)wAD>F5["> m+jM3nFݳAiEe~Yaz2`^ˆ$[ fXqCs$aj5ug~}FbB\iXay|,$'2L>eE5m\%覯 jSKh>mIpf([FOvpQTP9kcl\ k۔(j@FI'}ݙm`fOu;vҦ>Gs r$ZlΕdp6U%f`ɡt+f>r]y *FyfWd w%BMM szZu\ql>شbKE{\?ze?8K4a Vŵ7?V&˘MW EڻA`d1\Dc4 S`T+Mw G mryvM[*CΔ#w7Lf -:F]b+нHk6~bO)chCEݣR## ͺ BoEUF@H`;&Ch@'F_ AɽU p]6'„;Wf ڥߠwL_7dph4NN9 Z糮7 gNsb܁C%x(рn0;%R#!ڋX 5qeH$s`Z9]|[@MnL5VM2y;m?HpVƾ4KHф v|):G5Tw|WD9ٸrBdd U}uc&i蚺N A˽¿ASf½ ;)(ʷOw)"..GIISsG =_FCoP,pyFkDb=f.M6yJu3mG -fW]7_ȻAZx D1.h$6&.{Fo-6wGdIB~e\l`s2ewP0N,CsY{f2cp+ٝz_ѝ\Zk)hQpeyj<9Gmq!o^aK_H;>S n57%p-2N6^XˏT ˗XoQy׉NċB3=o_AFa| ) _L%īI1b{bo6φ9̑S4n}t8*6> M)ףn﯇8:gns&,;PӬ+ޢQH / %"Z7>5cbka"Լ!m|Eղ@R!NuZM p9vh缈@|hYC1;m%#X/RvJVeԥ+s Qtr醦3jgjsw.4e]C|2r"kdGd[d2:dGɞ'jn~>3mPsn,!3ڞJRpMVJz]8ecik,&|-D}r8nī\xJG9nh;u fKKu*jmhK?\4[ 8z/Eҝ`6 QqeW&aokn.j}jc$CPmJPWM Cl5A8FEF9o>mUA"V "@$pE=Nrހa`[yS&1x;A?^43}L84@ [7Nh֞kl(.0GmB)(?-xK4߼xWt®Eg} G5>^&뇃<1C>RZr~QOU~PF%UI8d#o&{A4瘋cb5payI}+bfh3c+w8<'KwS#9:¥K\-d2i1ZFrBɺrrc΂E/%`øe:I9^l"T7X̚`>ժB,> N2q&bo/39;Tfc ݋?MCL?Eȸ6HzK2W%&'3\! Ktk?hRHUs$WVwr@f6^8,'[-?g?^3dL~%t\^|YdU @a mh=Th.xPw:/ㅁ\E)]m!e#|y PHx0Kky:KACS\}m^WI}]+n^d/Tl;nc a Š='g9mC_~˜"eL\Fn Yѝ|K!  sg8o_1Vel+.3oxW4s)d5QNJAOZ뛚Maz 7#*wwkQn$bb_6vZ<( / 75.P|C ,Lۦ{IgoOǩU ~ ONYfz.wi׈} Xa஗:H=U/_ gZ^xݏB3J0#t&딇󡞶!g~za?y E[U 9(Z4 `.  ]7/@+1(A|h xk:ՂoQ<3TjKb c_.qGa AuxpU<,cxЮ 86e_z*:ؚ׆L򧰥nٛ\,RkLq*O/Epxn~>`1cqQ\Fs[P"7Aas^ԴɣcF{<갌9Yb!'6"VM $.cy6fMڳ_opj87wG уgzbk {-ʖEĬm&vƵ~.2ow*S 'B hnO3'lr_w8V.& c'$_48H߄xqszd(fN;d` !p ؙUԪdϣL/1Kp A[m|F8lqdБC-^^tY6iF0 9}g` K[A]vݗ( V`O􍪯} թ߆nຠƇU/͕7C&c(uMJujJe^!O0|c@/rQ ԧ$%'K4b-r` ?"=buL@^H*CoPS~rolm4& ň>l$r[v=޻HV`e1v:1J@ۍaχOE$Ooʒj<2O8T'%*d6%yy,SVHTr1esmGzG7DlIl`H6h Of@u y`yL& R 2ι  )L>ŭGh4OzGh[h+L?w j R/:&4_f_ ۣ'uqd:A^G`Vᯀ)`- jtCq>H$;,Ay _dבwe 5:yMLbk,qEyݴ~dR~\!Ҍ"W]d 8*oj@΁8og cF~>[ X|d%2_>h^vlf֢}[=|wn KOf J<毐C1Yt=4~i#nsnMO[=!܋ GqQ}Hy֖̚ݖ=z=2P(0 (5&>EϾBoq IR+4 uqD1A2р^BI]gw{?LU X?^S_,gRQH-sB!LּʂQL !FB=K>*IlfcH!ƒg[T# < zj/7֔73}R#[ Ü&Ӟ0pgE4`֧DS?4@Gs_:rkpuWr0v[ Fph wɷYRߙq%*/v:6z5dz*o]Y$hz4WBn}ώKE {gM-7 T(Yȍp(PO@yUtDpa(z@̾Dd,*Ek:Z]'oK[^ϴt/DiFcn_zym_\&x[RRj́ v%oMV[&.B]-~MGY,zZÞqË姽'F^*7e ZO.\-1L4YOGzjj אS4fP~Q6kN}nm4mkrbzR 8݈x˅k-gAsX哝a6#kŸ[)5o6>Ჱ谟AOfK 8 9E5`a!2{YzCsi"|Sy!3Gg '7dkB(H3<3/&/LߒmƱjud}TyNRe/7^=[Wܛ~7bqhfn7=+@f+dאYlgwiS,ֱXe A.4 4 ox 4@xGB1'C}y0:S-24inX]0/,x/35Wۗ&'#N_Y6K$j@.G>4@,0:1~a0Lc켫Bb"FG5 ;-uCe_0;d,m?s{#p.DC\ 'Ϲ)fr7x]C&D2}#m6I[8y/Ԑq1\ō1-sM_g-MCgjn,Ѐt^ xN2Jj Y?&cEDЀ*9Som qq]$$&&*j-lbH_ҽƗz̔`fy{~iw"YP"r?czI[9U/ܛYQ{R[0gM3+p,|0R ?M(;И [ĂfWus(V1%H#\vq (ętV7 ƅ*t{ 4ap˕4?L15aI8 `|)B oe9"τllo٢ދhYEO/x=._2qJÇw@o\Ypry-p8템C6j]ht]yYыmX'ͽQ냜nbeʅҗp:^A Ic P\(:Oo__&GN1hakGGҪCWfW0-SL2FjGJS)/@lv;h 淿YӱM۪u$O\Lpx} XaG'}%2 lb?ASÖvK"1H uЀ56LO9#PC: 0bE.DQP7 (L:I1n@/-E1q ib"&1)I$&w/F0xW]mL !1JHwVUzWR16rƉoF,LM~#wR[n{(!`R6/'=*x'Y`CZE}swV3 j&i; ?)Adnmzwu{~z gm kzc/(UA"JJS ҋJJ@l%RPBTi"5@B r>}~yI?e53߬5r7I!LlDgHBg:ub 7XT 0D\Ԅ¦ٛ0e;7vqm3&\`eOUi|}B.s& #3l)8G(N G7 ~Z4 ݑFҬЌbQvaF3N|wX'?iQo(Ɯ ց6em'IH0p[OHVw=nӬ_8=+OtPzSۘFYe\J饝 ވRL9ޭ(koy܆áfY^fcgȱRק>n2XV 翭f%1NMA b:Lz?vu;$. ^sP [裊+jtMӋt?#m!m.Y+L k' ꧱V؀$ls9fZgc?>GpZpWLxbwb:6XЪ Jr23qf_YnZbh f$ihesp=y !pZ I)PPg6:sR=V!lT< ! /eh\+8`%jG t3!l v1d~ӹT(8!H Aux< c@gt_;ƚbWXFIfInbd#E M]g[2S[Bc_(޿ul C؛ uG->d# GԾJҍ<5HW\RLYEmV.`09%˜!' s!/%&N(^*4 4mАjh'+9w p'E#"Pd2VLeb9F{݊\Nv!jNuLDz͔s|&?q\ל.K2*t2/fW,#o\9LX(v %oe)b|%D92mw~/1|h 18{? "OH!Dl\,[@U.%W Xy` O:"bv}Wd]NjoS{|k 4\&_:d%7K母LͣI ܁7-Z dMg@mdAۯc"czP}^{z0 iQqdkvǩIEm{SD@ eqY{Y)O>:h\2ɀzEEr : C:et9}b+@#'~<^bka@;eN^7ZAPy{t (^[ l--\Q&afz LW@*(C6~1Qmqw&ڹw|o Mtq.o}_h;Ɯ7x<-~%7b =^n2XQj$ R`UU5 Yc$0Ք7vGz;2J}QX'K PDlFcy$uh heO:^DI<C(-LJ\"2J8naf C ~Y6) M3ё2җlO4UF1@1ȑ*.L^rduo(I^ m_e-~<&VyFX"E0@v@FIOj5 sPeRDHfDa@ֵeuBB5~RzHW8y} k5Θ ۊ ysa{!ŴG/܃$Bbł 6A?,6C&.HNkߛ]9j .mU(d8Pr>ŝR6/WmYji+Sjq._ZARM .l s 8k?d~7Rw;Gfd}ʩx;i־לUP&o+}+SHiU%m. E6 V)(J.=8i'@i\B̗qVy8Uo [,%fI+ia=uU߾'ֳ9I xCR› k"mNJ#&aÄ 6],X D c 70 j+($<.{BOТ!wm&k8\K5fe ! gŖu+F4ـO<w_oTSϥYLcO |yJR󺯳H:qzqA~ء'*Nas`ObI5F5wR]W3aZX5~d3scV؀e6*o .xĴK ?/&i\91m@7B0+q43k,a%2!]SU oLq¹^ ?OCA%ߺn~HӝOZԋ:z/aF1Xu@I]W DDmI ʒ4EG-Ĵ1 ǚ3L~J%sF(|f +J BLqRR`OK?/a.YҦFmwzlM +oqm_>UR1:њ&fn:t F~):5>=4޿ -c{BqlN-4v[m'V(C){:b꽑3#BFj&E?.sYT5Q#l ,ef- :6e4sW 7K<;*@PMvq/wR_Tp'^jQCJbm^c#aM++ʉ3qʇtwAVfo1E9UWw"䘇r3T>6%P0˲TMZ58lOؘUuv}ĢTy֫?.lgfW&[LA-J/Ը?dG3;f:EdXTE!q%Q=B0$g6h&*bq)ha?tEvDzS?pO˖"ೣFK^?1۾',#5x0l^v A\sB;nDQ`ii+Oϥd|z_bIr. xFhI&f%stX*DF5RO4c'ӓQ=ҨV|-p02mD-*,RO}t޷yx8W %:JΞKcJVnV1u+ +jb ¹'%ЈݏͧE[Fiз2ק"{El@ ~+~:BcYT,jF-J+N6}+UnP4atyd?6J9JMhkIbhmR!F(amnJv\NM*A"͖f.l{ ;GNzxI&Zc3[x1А߱QhzΆgcd>"pYL0Y:K ~@vc0~CYw-Űx$>`঴q֕NoqQҝ^S2n~Fb񙫘I0OϮޓKoOb7D5 E0̦f).CuG(6" 5o%@+RE<'<ɱçuT߅)S7;@p40 LZ6jdd޼ţ6phDmI(BJLsw?qa~(9f?32SN6758mssHv)<V E%ZË TmDlذ&U'm4/}.7 #ePQ @*[3n[SuE$I,OUVF bG;v Fn" a.vW mstd`)hE1xAjqw@v{!fo۸B/q^K`JjT;kf;- b\d a%>vEwa63jRjԙ研Ѧ8C #1ڽBh&C^-f[0+ߤjamC(^kp>'#ܫ tIXÌ ]:2`:)p"Iq-vWhvʱ\8D gӪ#O'5(͑+cׂ|P ɼM[> ;2-"EH7oiqWo`kQAb/Z!?QN(kAuP2qB8S:'aCDẘFUl rIdFҍRB7\kZUb4hYAd?mvqMHx&Qg[@goSUw(;@tYW6n=&P1xYVFvI7E̢V5@&y4ۯ)M1y-jfՕO-qv0DH. mfR_PC3>aYaC~k6gԁ3PmbMwqN`\| EVpDKގ0{,j/]lsx"C0#FBQlv؋@A"o3m,D~+c$`5HA8.;襚]J#h^Oɸ1R[|tWMoF엛JXv YtC_*ʉK &QOq㧭Z sn_O$MvV^-F-+'&y b2)LZ>ȵ_y-{P{`L_籉/!OzR,\OힹZI{A콛4 RQ. ig z"H| _p_HhUb#Eisc}Ҝ( @z[k]~х6 ܔsCp(]1JNhkߎ+ԏF/ hYOp |wZQ~eVh9G<~I3x:XuĂ6;2)XŀʪEUX6Lm; mu$Hp|d[_|q41o~' MscIO+z6޲̶~捥w+d:fYOzRa:X͸V?%[%-%9tsHJ&Cp?I+qX1z; i$H=;m-;n^]h] 7IT[r-?zi?֔Df[ɬJ{ۯX U'J~&9PͬDz:oj`#[EbsMn,/ri6U=^%,ڔl̙QWP¤& 鑊FtXMM@ `|Ÿ@zWB58@0/՝ fC?Vlt1 X:Yv4# :/+wx2Y JhSqkb俄XC [l~E>hakykڳe04Y&ha!v2Zڍo7wxcpB_LeTyK6W33Q7+I/VnI֜Ј4~ZO @ 4o#Nu,9Z-YIؓRa(/.{+D.~}'Qo k N0{K1ØEl,qGU8&~ؽgګ <^]3 QT(4_o%m `1hrċ⮽S[bNEdh -e2H?4%jh,cljs”'P\}_;$x%r)%`aI%Lje/S0ѰU]Ŵ Ky#vRWZlm385)SD9U2~a3 ztzF=n?Bħ ',vz)(-IQt2|)I.m/||$$Z8."@Щ>}fi1MS}hZp~CDl pR0h+-M6b]TaNxyF{[ě>DrXxSV5agxM Ts dkR<Œ(''h…~1q !3-mh`~F٩4]Mw21Z7cfzG?B 2ltUdǑWDn<pVlzLZG TZD_g3F]Hq#;FV&6}|$4Zݗ;V], {iF24ĕ-gݠ:HSGZ򁩣7Cc`SFXm'- F8sDyo%]#ƪ":|n ռ_kH̢Cz3Ow9<::ʹ;/\*jAS^kMaɷ2"Vy^ZW2i?aۈS8@{KЇ89Ur3V)ԴE!) 8#1ߩ~'z,D/ r fd«+]|=ضSh oe7- n !t J~pl[ֲ$,!9N~K 4?Ai=Z2sD%(K'{=üje ~SZ2>8 't~JE,"e4LnN1[mafSf7ǀOM'wr6,n|YcFj@dO?"JOe\v/"@;<0$_giLqc ODSGIM}5"Q9iRVGTi)!̪\r,KlM Z>o{taagyrYbP#qCPJ,AƕjOTŎ6WsHO&0ͷ||!C؀ ~e&ӈuuQ;[41fV03{ApRI31A_(z 9]j\ =C}zE=jgDlIv Nm窏b\y KZMAV+UDDt:B YwFJN5:IȄ sob`Ћ K!05oM#^5=6`y0iD"hl'*YF57Jk]`@BwJM8cK" 25ctR}ѰHc=^%2Pbg:X+gg[#K5c ,* ɩ2j@ӘDxUa/Kn9h.Y'\;izj{ NMk_I2A]$ɇb'h_KdZ~-O8WgƜW`xVwR LemF!''ë.ՙ67FXUHo` %;KzH#"Pr"s=]lHze@΃K,3IҘ}ב~*>Lz5͎߯ֈ`~؅~ur}YDmS5R"׀}V7pW\&:v!'R:,SwB|aMlQjx/C3a%mYяq>YbO .vE} fڊojXF\ L!n̩o~~iBExEz T1&.#x%H(D獴p&+ C>)V#r+a0ɴ\$uC7ۗl<B^CA+8XI[pѤV,-%{7eIT,Ѭ{K WGyfo>IਈƄ)יH+5JUF*mC~L>"2m[h&Y)rENf#Ҫеh8UرA@10b [qug#X ]cb(Q()wgus$V<81d9}b `DPXMC鬝dHXCcQ:47p&:`y_}t{V靛g;O5BH^ @F$떭hBel؂aӌ]p(xR?P"ю* 2,FoSPw(weָȯ5Bq<,}"FZ/byd-kὪL ~asu+X͠,\N⠮EFGـΜ`kCev{X_e;#M{ De(VC]^/wl3p߹lfE.{'W3!6u]R67:/yudw[GAMR_| 3&sg~6\K`kACĻ}lqT;Ja9DJ *3 d(h2]D߂X!A_|;~{)j(!ٻYJ FЯ#F޹T"2̅1Vge!UM2J+̴׾)UTc! 5b'\7d7ȶ]w_j6ob lnb NږS>wt߇WeGFm+=GW̜gA Ȏt9uOtuwCY:YU7댳12 o않td#M( .;"~:Vi/,y4oeYUj~}.jջQs _Lfq-ɏRПszm&tzihظ?OWRA4c 6MB–ẶwfHZ'LSdN@Fa@|PDmJ .\Z04)MQ]4+x=Ļb5ZI<~ihE]%t mE*q/r >NP^y<e9hÓu "9𳊠j\q#φ` _;3g]Z}SItJ/h+Wv>svXqk0G=yZ#SVeP[^u|3bغ)v76 uBss;?e΁UȂQaEڏ$Vґ !3>M#ZM7mQ74P?.Um Ϭ_ lO+ƀ1 )uW;׹#0G+C׺em(s[I{԰@ee/ _|z6-NVAe3#R{aɞͭ$^6`7[R,|ymO/'~|EB+az^.M7Tb_ǧ~˰Y뷀ӯwG0չC|ڤ)_Q|ڬD-Nq=)ioI{8J=8+MRxR6ӖPعa^?ҝG?ClT&] @nw5WNg \bdAn5~gnC*I5P%l^kMSk~B5/Xn)Mlq3,^^6Z/[pL!R8C}]D޾CW{FOEH@dl.akjfujʒ`:yrӁ Nd~E6feđ:UzAEj蚌PV4ks(va=VBτs~@z}u~KはXmUo5ekt|Xčjnw{H*jޖK29Wu7bb Tidgֶg[؋5%XnC񽼆;26Jb-/ '=|#`a|=)gܛԣxk*&Pif5'w$gQ;t뱇ML+-.8O4ne[#k|YA)M=fZOƌ تAg9sZ7=dsɤêgMㅧD6c֫mwS`+#wg}u5p3nQ*GN19 wOfH G<[rT"rVkWmҭ1^׳^Lz&ٙX> /T"P{[CX7&ӑ^'VO'r=d:EhF *YOo0E%DzY=l"ߌ}ܪ\#~5MSݨr( 8]y(C`h/#v`^ԙАϻ (L>n$V-ÿ0}X乺scRIxis,eۣ-2 6{7"}EM'-a$Y$ӹg+{MH3^͹{ G[W~Et)X%-x" W̰ktj@#`e1m7{-d׹I^uoD(\?*0IEbvԅuKC~iK ,v@BEC{EKWUi1z6 "6m5oek>oO'њ_#/EvYGM}Lħ>& a_ָz"wy %Ǥ[N3Q-G!qDr.eF&S? uDh8h)(BR~ʂ{9u< =8aH/sȓyϠi-ki0-NDY((\B JbS"Hj/y wn u (tH8.hNrLfWRQ ,]6:pU`,,̛*lp6V;̀I+K1d_zaHۘ%}ÓFOֆލR]DnG5wNy5fnAgSpВ%n$dL *u}et(däY ̯Mk5_T >{;5Gxz f(YtϾũK1+Ɲ~}m,ύ%?zR[\/˂OO%ԯ3`9 KAY)ơaPDv#FaE 2!9d !KclٵDhlbR~Hjs3p0+7s>xx+zCT%cMHh i录JYQLw%C&>3X%. WM>-LFXڋӱm:|wVf xX5=aY|96rW=OftY6J |/ dbp0%f1|@:qCJ4b3Âh0;SSr!FD]qZ65'{kS?hh=Hi)E&&FF>Znu 7=pi,,lZi)3l naT/gwL ("oORpkOb/1Pp0q׭B<[qXj5=+zX~5$:) WcsZ6 4B%QCfrpG-Pl}x;D9X\nS%k< m Q3=Kx2ݭm5{ojUY&e:qpڀ|A?ѣD۾+ݹplj!*]9\5'f%6rbr0f tz.[\M *CLfy5PpQ 6`̋*nLB4 N%sx>T"9}\S4DK1M7N&-It+~oem}w 6\=whtu JbǸj ~D]Cm(-]"ʔuVy|!UX! YÊT$M؀l8emX{hrjHFtLY̵]!(* *8G( qtQ)Fo`А=E'\RӔYX`m޺ZIvy A|JS4b)JMQ5;ztic! vbkW+"H-|=L2eeenn.joou,4;}sɉˁMQBocQjG=ӞB_@IvO XnPxD_w<)`E ʫlYYy^%bÿ( 0zX8gN?Dy+7q#K:4KY{s5`$x(߾ћT^,T.kl)GYEhhv?F w]a}7A;һjpHBYbN7,OrDĊ)^Yso㙍?nq+pu/zt{OwI_ 7xX5w| {y9mo F+㽶$Be}CXϮ`Ҋhie>OZ[>J *@kt/T`J:Q !A儿ZjW^)y/q+0ݣl?.'Ajs*2k)-) JGI+Wraue%"-siٯ%$V4l@h? Deѐ ݁FiPJUf84T9hN vt6zafc=+ʡ )m >ʪ[+n5U^$7.G,6\0}F;|{XT1&/B)d'k4( ~ .D\lFU& |];]-Ӗ;T\%jݸRmj82ϱ,O|Pt8OYl9fѡjfMq@qMuZm!O]&)'P\BBG}m_%1t邌kMdcs)_ qߨ\ao3fq\SmSYEX%7Ytɉ8.Ll+BiŶ iAv8(,a\ f\0HGSYu s>^26F$ۖN^_vy9C3i@I9gӲ*: %I[ao]yvR"EG,ZTf-.k33OBz9<\GrrT)`?ŏe'KAA1;Ufr3) 8 `Z`#<̞~,IC}:oe&؀+}PR#'#m؀oӬ4  xBS-4!Y۵$HT:I~ĺ:K&wFf]׬9Ð }'YͳQ 8Dj.΁/taF[/гNl&'X 'mC?+sZ o^:Qҋ V%aıtaC}{\$%-٬BOb%Ze8IU" ٥mOWgʯDB=>SR\yJ6D9^wt523g$5s* l1۔^>' =,!]7䕐0r&FQvm7> wK3֧t[g4]F,3" ԨKOy4 OWٛi. PV)9zB'Q -"Sc :|vر2jCsClK]~Y?De18_`*Ůhz8:pς0]gK-]fԏC[k̏\$1#0&[X\ 9i_]eeC>-bQ^US/t$~Xfܸ}U"@w8 2P_if؎{jzK5:Q̎z}N'p@!*(uTH73u^/h ?Z+Ў5%lu!!!K?#8_")yg7ĎtF`*~6R=F%y GZVUC(rӯ{ v' IW_Pc3:ZxbxǙdTFOb{ WЬy6g[%C X>h~K)hILz6*i+lnNwO{?YtEײzbY!.J&Tl0L;iA7z{If,'˅<8C簾JKe߽boZBSZ`%st0Ɯ'{SU,n+bRBTҊ~0!wdu+@7y?`1G kz}z ^O-'Q'B.dE=)Z(p^dS**̉RqpA%P)mֳA669~1BFe;ojSu}WuC&*-K=/UTCښwrZc\?W3i8#@63+ib6QPX]m͖g{¦H>MZz|-m(JT D%&FWX.vɸ TMst5f;BÕ r2Hբ#*,}q6 ܣVl}-( ~h.թowē#gZ ~q/Q40)qAU,S#KHd6 ٜ%KdFo6U?H_q$ 0&.g-$SrjyVw"xeW'պrav~֞}_} Ց3>z d:Ocp,ppj ;zunI$K‰^VnN{9f?.^L&49p8W6@yE ,4 ^p.yuu?j) 9ʝ$ Us^SYÛؕ`2-MV KRl֚}mjD8PʜYhOr#45 -(,?ǒo>:GAkN08l,%Ge6C/:k#5`̠ǖ[-na FI}V:o*ũgWXb cjD]r;T`%psl =mj.>:fV`Yhтʥe@]'6j5\t؀D69ބemDzr~]Ӷ7$C'88uBӊڜ Y\tμdŻ_>@qP&VH/W^7̌ uwGs{/p6y Zsά6A7yO`6ưx[<|kB#0 "b)^ " ;$a=*yCZ?{jH٠l0~256F׃)ypD2N{dH2B|a+ifV7aE@ـm8 5dE-b7M0!F2wXyՈb%nx5אqzf:~Rɀ"Bmnf @gCrrtaes} -!4+d4Ni/',nYђo]:|72" JC'?ƸP4kld} ~N6/% B;}I_?\tbNVx}ЀỴDN*u@6 1wM3c( !Lm;c6 'oj 5Qn5a7a .7(Μ J- ~tvM:X> _w9%(hΑ9zQ/9#_ڎ6 ~(Dl9bZT]u;|E=c38eg~^K4=M{ٌ_( Ё65 PP!}T0WEqgMB <|v;ꛈtZhaLan,.MXkDZ;_ymyt{ۉɩa!7;z>yvŃj=L IaV )ƹ ZB_[>~m짾Vly,yOf&ܸ{*p.tݬJ?9M+6@2w^dA^& @;$#&j"G' ]͆ـD' dg1=ǘ;2#`&8 `Y.F7@ԗ, dJ"(+Tp~+&)٤B|r#U]5Z-{YΛğΔ uM8y1,4+' HG$?sn؇A幦 &:";ymDs%weoHAud)/R{Ƚ/$Vbz%0YVF -wcp0LB씚C@Wx=w'vn_rz{CYIKJ5)+I*7M 7~d<i%6ë'v}$,+9=rD403 RQQ.Ҟqn,q~k4P (ח#F[ga@DBXK+fr14E4 ݾe8c= CC %Jα #؁p* #djN  t@X@ xw8HaDۘ5 gyz[ˑ aKlR\|PI-?Ey Di=`l҉*C4)'nHpP&sCiKzEpH*bwVA`PvX6p5"*YϮqH#)6 ~5.59QR%tB\CзPl7lvgT6` h0~Y!/p0錂!y4jÁNDͭl@YIfaـܪ_$ "WDodHɬ'wf5aNig&Z9g@Ǘ:ܻPgj?BcsKwe6 f>=0"l vu'B GNPHqEZs8 H؀eh9/oX^U7$˫Z|$[<JŐɵNϿ6LПWEc6D3ȳBD톘IhL`7719<>b GQto<4Xe/ԢW[ Y$A5 q i(4c8/X/2XVn^> DۯYTD:˵mӰRK2 AgItۆ)bb|֐"_KuMݤ%+a}Al76$X Ү]K }3,`eXM,Eu`{:QF6`DձdKntkYlʗ+vEIR#|lGrhr* sK2gzdG,5NO6@9{;֏嘅C <sVZ.>RųYjwM R{;O"^L\X%h պ7;5~}͛߸-[W"J9\rR#=:T!M3, D:s/xx9M0C\0(=1 ua i^U K pX`B_X5sE~!ᐜ|w$n}e=*YAGYXnaʪ ˥6ieVYyuA]wz׫dA|r't$]:OT*qTS0.bͱժah `,mn[hUXj@"5S # DR]=%cT0_o.tL7ZoO3vS-w {Ez%"6OfC~=oW$[ET-_BQfPP~~|r$u6 sœEtב]O5YGÓ k5%P "JAϤY+Km=4€=Ÿ`6'phfK8 A&.Ġw245tbLXcs/k~onEq#P܍$_$mB")"[r *!6 sEǂH;sp]p4ϙrJgG{dov+ꁗo2;Viv=NdU1z5,Fz0tsl&a0U j$ ,@ĨdSZ ]։3'~_'_Ɓ2,nj6l@s Sz X+'R(6@r3pb MQNF9-:kJL_;833%мe*U3aMLVbe@P/f5*5 i&RDt%4:M}$lQ,t#J=oK=zyl5zu:}J?YčuHkɞXl-tD6ɤm(p&-#5w%~==ǁ;6Pb_ݾ-ƒql|+y"fq9X-FS<|9}6BK}0S֐lOR*F+)s+CѣnUN&ZCڋP tf b5Wd5$UкvJ3;Y[xUqR& IThk/VBڢV `TXȭH=ړ(U@>'aVR ӛH)W;h9s&S(b^H'|z<iU$eBM)wa6:oRͪ l99,~-aS [yO@8[<0*L2Ȁ#6l^FSiR-T,#ZX O=" J7p(zڹ9(M!]d>0`>bi 8h2Nc,PQhaJ\ȅjI':Pش~ $LZ64 닟.PFLY۸>Jo4[7h; (YYx6Z(~ Z"$eV0qN@#}N5Y WIs0|^6UZd)Qp>gšƽP2>OHq % ?BJ Pu9VG25q,\7^G]Kϱ^=i O*qm^᫧f(NgrPr]N3=w5((&. p2ae+ybsK5uGsoMc8+C`Êr ,K^鏜sDDâݶc"`cuJΑ3p5^Pgs+e|ST&;6'3ҷ;땤ِ!q<|s̷Fr8v %Uja+r9q cZ߸@6s4%P,h.xAzA$`:2Pj'dDl5RZvʸݑ 3-33#5gdއU-56"4 >ڼKWy?1f Mnٻy_RmJ^/xt zeX);OY9DW -PśV qgvAMsG[mȤ&){jSNrJ2&LC8|JB KI`9`ɯL^Yњ{lAA߻u`TVз*'Z#{̈U WPQ| 1(27وBˤe.u3a'l@v NdpB5?'2y/Y}UlQEzӲ+S)=d7x!$올sIa3v3B:b4q:"qĐ:~Xq|KcjL%A?k_ )tRB'd+55t6UUIJt^i/|QQ^i6 C뚗]8ցlx?4 mЏfN&SNHOܿY:QO 3BA?q.=Iܯ ,~ť XT W[C?q ?4/j觠~KCCh BC?X6o V`g)T׮ʗʿAke!;~+(x6ov Y?1t\J=Ƚ=?lƽ{ Ԏo8y?~A1Ǐz8=qIĽ_C{d/Dep;0AI_e;v>| ~w@ppza.v˸o uG|xؼLaC/2fsX25〞ڐpV3v=@[ۿʂ<D Žg_PܫF{;\G~MA>.=Gsy=\ n_m~ /{?nm\ im?qEɣ 9D ~.jXJfP둳S;w^{-:G8U,ZT<٠]G:i2|[Ã:2i F<ؐhM[r]z5D"B[NJ]oHfJ{diƮjChm_\z ]|xo0"Ĭ50McQڷ/we^elٳY"_ (e**=u1(m7uU8?Qn̹LL=-]~x 8:g<ڰ/% }#A(|w`\vճP6XxVۚW#Rhayw̝kc{>66O7vI>W?{ډ ]]hO\B~wߥxkt]??ԫ=Ե uzn4Gw=쑗._Jvp?ۺ+2»~ԭoo <)=3gVIYM5T[n r0֯R8r<7o^u^R,l[-otߗZ12D陋2+6ǖv@^'X+ު.yymz3œKKf<؍|φ>ۇ^޶IT5*Qjݦղ^<7"WMԷ=vaOuJϡR ܃cOia\."/i)YGߏ1 3=v_zcY3*)uP;CiL;Guz w(^Jx E0?|s:KOzRdbO޶܊#+/D R.8ۧl u{PvZ;,Nk-p qp2;w1i+W;lZ_-.6j>*:|.˳ 9rNp9ǏKηWL?'BLcj~]P*OUyHd Hh+qrż.Y\;~Hxͻeˇ4  rZIJO ȟKI# |;O6<q.Ed~fۏUr:tj%ᣐ`]E~?QV'odmlDfs>S%be x݈2}^a-CL/{Fɏ"_,K[˜^S6M?,zT!/"x}3XG [7o(Cйu)_'Ԟb[[҅tL9Ԧuu Rv#Tb-?ww]zn'Rj+\9QSM yi@kS#u:99V<(Uu!Νm+%JC)'ۅK<1gIYm#<{](9KZ#B!"nL*گqǿwح_c \NXr]$T*'5vt޼gljdKUy"dv9oCU/^sxzTVAB( Օaj7]n_0[MӮ;toI.j!5;:҃TBN V>mK?M~ﰰ/s1nZ= "ev>ZݧѤj|txb0܅UC^y,N,!LZ(8z0Vb0Bc,.Vk?v0fύ*>`iq|SIY`TYv50'GIQ۩eW}!MW 4e%3}OfBf4͎'nj5_ 1wO#T``{UkKwZOH#E=62o:K(?<ǽ/tַ[}t<2-#,`3XKr0M!gejMGo9 Iվ|l6)f>o. ]o߿ Oɮ['CS]|o c#k*8wVjRdqJp=bY[PNK-Z"C'Pc ❠IgwXb ,7g\:77J/\`)&2aBp] 2E&G ޱ7]8~CVdQTt08w)~e[О/G\ >cxX_Q޳/\ z6x> g OQձd8;,U3驛JSWPӫ(8 ;Q<Ϲl/=&T/;+=~\^IAW)-ƪO2ֶ؉sQ_wv>R|aPMcL߃m S)B87_26(/eD(dMv(}flD&bt`:ѴzA, =6^glZ`>ԞG1%iY`(!6s.4Fŧ VX^=8:ġ聴$%cJm'ՇË/%~z0H_j뀟g?}>`{)O$!7'MxO\ yOw޽|-vl{) u'w4N_:c B{硗‚~]oo>nC6*:}Y#>xE ݮ]P2!X:u1ٳR*޸}.bJx'O˙<[a+qSoғ&yԱ] n(Qy^bݭ O^X&n v=8} +zJ%J!vbʬυWS;&^H=;CݥSf8/FߵF],FNM &*Q R?>RX5ٖpT/_Wvu|rWs".6Ѳwj=*Ǽ~=۵ǥGR\ `=6;R >U>4/d[ .:hsE.}|3D[ix>M|̪՞}_w0C[)BTRw.v{ "ܕJ(mpIv {)\:n%[z+W'z̕+;1F9VbJ$ 6K{_nDm(7r (,9 TOzZ0{ҼeJ;Byc>b:NM/F\:]qLrթջ8㼦N{_p)Q`W,YxL\T@ӂkI)7u`9Pi|e¾72G,;;pֱNhG|ݥv)N8=o9ѳsEl%:>+ O^.rI $a c0+a>bWE~>$8p` ^ed=wFb\wGt?E\9t:*ݶޯ|ܨ@%s9vP~KO>]ݏƫtj|#,O >f3[+ :ߟ8/7E~ǎ %b͌zCx+B}YQ1$lQw4R0Y*p_ޘ3vf/dW︑4B]/%wVEş:-3NlݫGޥѡm>;1 ?R0HM}5=m}kէ:F|VU{Zd\<:p:kr0|4z]aK'!/o=W]}&{c4ŧ9R>g$|> u }A>IǤ SF9ȏbIj܎@+n_yX g|&e̱? I}h,xK"C-f,w7o1:+.mKoze}><~<։YW-q]H}=SN洛l[&o =;k^+mоx/[5 ɫ%r^iRbb76^\:l9{ˈPvF03KTշofڑ8,/[ :KU"U#>|%GCk}`26 j3R Jg'ʾ6y˳Fl}!7YҘ5JiOKr$@:vD7=sЀEޝ{#t6d%JWIJ^G)ks7ɍ(_v8mn5ݞ3GOr]jU/,<7޼i]uv͠1XhMi7^z BZ}ht;g.:/KI9!qaarm7:Ҏ{*7?1Z/{XN_krŰtN9F3;&Hٳ@HB=޻M\=) 1ަZ#ss.Xi fQnU[Jv0mpM{v6э|e\f|E ՝%Q֭GE6z&NfقlK矺9!>gOؖfSix]:| iV-:pS+X*ћs\~Gۓ<jA?IOc!($8{}GZw^mPhתNL=C=Vj_[9m Sl\Ɔu'rv8O4jȀ5N}vinuE'3&t:oTOTŋ {jw)3s|+vnmʫtOl[kmkg5H_S̑M\=|1uh|H$ 靑saDtYK߃'ru y8W: ჌#|}[J|.#ޓ$ +wL{@qƇ*>M]x'>i$%n.hh“;Tk\7N(θ~礖'wvXyWVl8ƣ`NytKafbڅBkӮ_ }Y'7'|x-wo:fMW#qeߗ]o? xuWj˔;Xۍ(ǘa&ؼm۶m۶m۶ms۶m7ld3:>+U:>> ͵8Ҕ'  l]A_t%3B`z>ŧ-ƺ";'@, x$Iz%npйKt_s%W >"й$l#-N1H=@"c@2qAA!0?!mD+AAC$Y|Yz9hVAMp6I:@U``Cw^_&%ɀ7C.6F-L߻Ti!gNR?z{fu(T6h_tB)Z`l2I%,t=nސZs<oH@жBk ]lf8 Xd -r^P bUi+0>ܑNrWc:a#]Yވ~XɺC* [Dx =~#r(r~ʪ_|$%m ^J6蔏0tnI.FUxo=TTH= 5ɤLq'Yv$MM ߥtoC8L_J8,U/:}=tȬ:fEI"'YFgR\&/Gx<~ܗY;pC!+ u@֥Xe]w3o vi;Llq3@u& W)*Pc|;FX]:ά0Z+BSWFܤL$ 2Sэ`4s(aoPk auFFCyעҕAWKp3Th`{ vf*slSS v{(}F`&f& j?q߲C%o n['̕עy:6iw/h0TݸWD?:yDݱvnkYdVWd%MS_@}$.%(X*!H@fW3?{&2gm]O4-t DHbM[)5Piu`VE=YH"'yRy%,CI&g3'2ب@J2cS Q Z;E9S>6N<`=zmFUL1j1W ENfukHEmJԤ a*5Opz+ݚbW5~ *L̚;Јf!Lh.66鯹j2Z̴UZ~A*3sFl*-T}$D^.34DL{PS[ɤF oj`yQϐ9 IY*eC|`|-7TO4чi%Ӱڗou 6Rڃ^' n$ۑ?N"?W٘^zќ:G??Ql6xz`85;V]t"%yh]vvVW +Rw s{=y{8:~ww_]8P߯ _[|׫4Rn~}o~s>$_~ߢL}WoM~#9F>Rޏ#Φ:=s9mU&ů zzq]/Ƣϡ#Cѵ'kr5;)]`\pw?Qd\p`eZ o?jPў=~WE"٫X;b߈+ܥj$v_W_T<*Yk3bB9]y,IR =oOL"ը\=A,QBVЇO$<-#~Y-M8No Nj55086:ǺFىHECͪ{('[Tug0Ê$3?ϳCO١w`&cb"c"Fi3Ê=xv|߫H!Emö$<$g񥠹,$8GA湰Cfhnv` ~Q{ I}qAgL!H/Wrh.ȝX7D'$'smZ ւV_"q5^@(uv0)7OK7t֬#< ޷V7}poU>Yg)Oe0S6FA~A~ȹpt7)Qq|M)77 TT,,Ɉ @7[Q_zxm{ njoiN*>'Ly/p-Q&$c+ Rm]|ףD&KffOE:iCn.Qd/,.lx by^p;jʹ5UYB(fC鑎"O5Lz]usOljzq;2A{y~i(LdkM3>B]ز RsAR^00߬mIJH\ٌ* T0#[9 Ko[!\,FKч'^cvy#U]2Ma U tRUjzXѥ1H tIryqVZQ KOHxzIՇ.\AmuUk#yd +ž)vl&ٓL4JB+dzKOUVq_8|fVbMy &B#-ZE 2Qv!!Bj*G&c!8Gal!AO}mkXL<P=u6{UQ(]5SC=s0vgMU5;щBh12O>9n(LS! a?uR3mKO,y6׈=]iȽȉt/ʐ:dzݡ X 1h6$MuBc6`CZp4!A50?)st3yB[HwUklΒ B滑k8A>5-EV+eG8JU ŜEyEG4Rcܵ89'HqiyuZf\_}8#G }D\[&uz$/0[O*F:kqK; x>N)xV*OSA>pv9-ye`4Pj0A)("`|LMS<$D4NrivwsF @ ҎeRgm3%-l@b~d# YzI0klMJAC0Z-|~(790 96OH84xB=c =ڟgX$N05gY`F!Л֦IFEP8&]Ua߬l˔r?u$AKBF⊾<-/ P1 Iem1Iö}Ӹ媄,Fƪ`]=\y,i1Rb*&i߭:Jل>Dž(! d]M:UciR~(ێpѢ,Z4:0E9HN"< b_f٦vцb^}K"kƒ|ϢhY.H%\4d(q*AJC1yt䑻+SϦ%b3 1&wm$!UWEsunLPҚUλ+GKG}[2VCdA~f 0#lsTC:|ۑ,cDfE>[5U$dCtx5R~הOR tفٵsEd~Fd CRzW Oo ${8v֗,cT؇<(C Lljt#a5Ĭ8gg:n=1UԦ%R\> UM,@?)eהZmƇIG13DZ02rq}w|\8;!Ϗ]:3;p;6$Ni =n&E *lh> *?l%\b7e.\c}D=cuJk2=]2v3?kx"vU==N2oe#$.Y tUWw[?絧F׏z㖏ݓX8K CaȃPzN9cf:$5&m5}7n _To?<=TX^ĉ Hݶ]M (܃=dgܱus8Lד.ȝ.MC}/g(J4~, u~CgtKC*+[@ 9+U~'Ur4ސDbX,H Gjj3't8i^ko 0K/. >)hX_:x6p%2ȷWcsn0( Y(po{XF!#8n)eaaۃUGyN{:0q ķTz"jbj[F3`i)!XzKY +Z#yyS i$,3EOo.OY]xo-JuKTն*c!ARv|MC_b ho_zPr\r&kBJkX"|K|G %H*b@V"J'>(LUzD!qHvϧiGk C-լGﲓ_1ˀ 1o„y$n"5}NL%1ka19g K|~oվnz̿{q n'>Lr;k0RI<~61F11>Dƃ=`DSkI *\"-n30i&FE=ayct$Q]WB3f}5C-2Ι&hlЄ$ A% k=m*?tͤH8 =ɇ|V(k^'cB!C Y)*ldq6:.)֛WVQ UH`X q>PFT#[ep}% 3L)TFM(L8m}jAuMH t酼~ґ9󰚀RL@vS_V ?G w} ِ Sî:^PD*3 CK䂺^:[fIZ(|1<AAh CUTGF3e&d ܲ)[=Ѹ~ShuCϒ[Ah)"4ɖ,|sb_LyB#BVDZ"*qqPխ&9_Wo)I@&v7I {=Xr!WR衤X@7cP2]4{ϊmP\DJ+P7:?3 ۡ8e B-о[/ؖ &9.YC(E[2v0}$uHMPv1YNLKK^k 4 0@4[ՄvQ%!g;]`7O T!XzӬ-8+4<͕qOHS M58BNPĦbsȯ٪*XkgأJDKHKֻՈ U{T]QPnm!d6co63gPϐi( p. _UĀk7tq2궕zf$u4?Bߌƹa|pk.8rpݕ|J~8I` PEBP%&TꍈYhth9$hMxgaIe#;,uǍf~h 37E:wV8U!5Tʞ t&T<9WZh:ԇ3\ۣD!K?w`K%UPJSLB!Gԅ.D$9` T[PFFH3"w]~E 85vV1ӭBL]vՕ~ÙNJ07/ɭFhW-+1e 5 S DH#YYkvPJEm7o))#0x ,K `+k@f"VJ[FDҎccw%ZՓ2raG ӔeF:Onw.+o4@o 8rjE2)=+S &k\Cc$ތئx.SAR}abHE{PH[K sEw5bAU/ީ&u.wЄ- UjTh$Tے[3ΓjbҰnQYw2$a( ۉ*F%t2/M=s^dmTUhWUq#t|3WwbB:L\!ZYNCzMsZt>vٙY +R ?wd{n6Ɇ98m?SjR=ZvW8K&p2|YZ|l8G],u3QO|=܊[q08gW_v/>F%rM笭!>C}f>VcO?oGw ՗\ejkxZ4+ۏO8qUkY'H !ƕ}t^wEaƑ tkh{<\9`d;^g{8>\gkn~?vp7]s;Rg6~1r=ߗqjVUz 9l =Ӳ<*`1[ЌBڒ @swGTz/qH^[gikb}ͫ &7-EB'R] ތ9ח {N a`*;GB\TWB tO(I H*܆NwycwE[ɞ I]0n`= i_-L0a,o׻$ G8lG+N_ ;m!\Ma$%v iQARhSLwR)g {G9,_~)̴U|ֳ/xw.#_ǃpc70σ bø.+@'GoXaZ(IpaPQqXG RPIb㼩04_&޻ sH6e1Nӓb 5C& {ﴤ'p80nS,'fZGJ\JGw4Xx8@ʑ  -Ie2-!*eG>~|;j9b? >0 [à'kR铪'孩t I@<MEJ4L#6;pgI&%"ʶNW n36XmDwV#A^TL*gj'*r8U_ Uy!s ??QU^3s18:C aIN􍚡VJ!"Ex(B,kO`%41ol& P+"N9N֋̐,bbԞlpr$A5Kg xS|Ν/ I 5H6 1ء&\dIec*LZEέA²12wg8~FyNzku;5)^4m~5l A*> HыZWwT2蓝k{gv|e-6(ElNP®hQ7<Ӥn*CȈ8!wחοǷ'à$j4 q9_̲KJ_a$ og6>uy QjF5iد> tx+͍J&]Z.-SH(NRXJ>N($MR$?QX8ɶ܈U @^[C*\>#,;:1JzBuT%G9C:~wh{WqW pH%c vTUwq("9U6XH}6U_~4&0;|<5[]XO{ < t/#Q()Zƪΐ vسED$y } K1iBL\%`YPIY`RŌc2- &*I!۝ \1x6G7A$` ؼdMf_x6 }ذ@,RCG\BY:#\\ ". 0yWd_ƨ:py\`Lط8ؼ>FGp̲ԡyP6Ֆ* &`\Ҭ4*s?u2Mt^XAY/$4U.w Gˇ/}›7L%݈,ʇ 9˦s r98sbByu(j^. p=H~t^R%$84p2#U&Lݬ㉱.PJ[gYgEXt zv=5v#LK58W43ֆ4# 4ƦHREuTNoݦqH/jJ2 < .ݭ"[)ؚoHҾ]pO Zӏ"t2{@ê%xVXq1tTלYu~V 5JZT CtG󛉔fycRd6e$T13B2JBZ.,=RV 4fzZe!#sGlhqS vϾ({G]*Rm:}WWSC@ Ƀ6^&!݇'g9XcrB{5=S=zkqubdzǠ۫3&?-;ϫi?_I`TQ7v|w=@A@oOY% ,X?~XP\!H(՘}ɹZw]mq`w<=_-忹}uzpvw>wzvc{?_~~z, s . mzI>Jo_D㧔`zre*[Q<+{od) I@휁lޛ)Ͳ)4n2 ؕ(dڠ 4M <'UsJFl\0L`lg#{h5G9@㕤O D@rN`j5\&* "+PB2)Ve5/\(ݕ[@1m[y9>X iBPR҈]<`[Yj .7\P#Xy4m jYm Ѥug2ClY^ =owOCKuIpyZ/8) 9Ptn(4ҧdL) j1x)Hu|OaJ=+>1llil)C; GH"yTh19FA_d [/׃@xd1sc{~e!fԶY 2<1 T"%:f4p`T1Yu&•C-F䈿Yq:Hp;*(BOIVX]̬癁t Sd*d/0c ƀ~"D0L 0k}2-oR^nYH!&hGUj5?*gT{{}QJ&j3kJ_R[h3S56~,;8\P8i*1@"cygKP_V]-a\T lV)ϱ$cė9 {ݻj m&" RP!F HvIG% SvvA(LI&qd1j)uQ8W:c/4Ix\爸J;A4Uq ĖZ+PI9n;{(c:1#,/)L zjfEmHNC3!󥲹bES#㈜+ѥlfQjaj,,:ZJՓҜqO0c@P*5 P ^dLB.aע<"tɔZE Z=KP HUiޟOp?0=`j0:ٚ i $h mpf:agflQ$ GmAiȌ*k{#-lǒ;Q4U vBy_b+-nHldDC5@ZkPrx Յ /ۼp'H22ΘpRX{oX*8dsy<)2Ԡs]&V=i>`P@/.F&%= Dw%8{ G&>bѳCw?Zc39޶_ ,1N/(: ir .#D " P&\`,ւBy ]v4 mx>†.CT}]aۍf-MJ TaWB+-ipN"]-3ps\V=tL!YsN[rS(|Eejo+ RMz!-#ӃDKG1@ x\mڈ]ni|שt6nDmn`(Ҧjbs9XFsUπ05 ȚW=vJ `ֽ ,ƕj^˨Ɛ%qFe}F#5re.i3FB\s*H 7q>j|X13,$]#utkJϽN' KTmJrʬ"R 94AQW'&T~6 w'|) 7[G''6(inn&ϦcWMO̾O\\f!m}_9y7$,SΓOۥ8y=tҡQu`nST[Vމ!K2RqNeTܭ/dW&-ClçVۖw5G^Q4S .=و䟌e;XbNk[b6N\BgCr UT S 1gବ14Em{  =p.YY;ڙSl'Ԯ&iG_ ̑ }1#C{NZG8>>gIuvAUz^Q*:y*s)co:qMnw~{z ?xE~];}S;,ߍ_sszp_rC[F|GO7Oў})b:s Q[oVuJXG@G}?ɐS?o[?3n_;뜵SY-h-6HƸ̳f hg8 g]&2dO֡5;ys20'7􄊉|q2EGux H&{*Y(a-IwA#ݢӤ20;(|lT!&FeY_CB%YF]UVyD/H Uje!44/":=u`n @;x4ܴ PBdb"!5  ~PU cT]^F|2bx݀yipHjabv Y 9;x [l3h R9" "`6qݣ 4Qᯌ}.r&['P>Rpd"XJ*:ׅ 22^ۃ嶱L rN B@(tLCc,bIUv1JU)`RP>oE!tO%f Esx\r96K@//brgY)|OxHX3CnpȠ %vh{m8oIZxqiPy5$fNP>;lYALJ0Ɲ x.bcF_ Dcv1̰PN!c8R V+rf,G V\x\7V`m=:,"`>HDSEPMo~S~( bb.Y=qb?fEg>NJ}vu#xQ R*ڌze|+:)c&"ƕ'?sD bx8?6$1W=:"ZP EAd+`v.N{)SD2p{C~lΚn*5Y bؕ(I_@JLK_*T8E ̃}Ş#TlpJ+$  {*ͥT0(r0ROxU!K/(]] .lb%%Ad噯s/gI>;LGi$ dK) 0`U&]D )9l]cW!>7.߭5]tATn#"H|mBv{F.u)9cU2qq7$&R S%zİSP cFFSyUOoY[7["*Y@植9J.KݭYC9>: USA~F45HLCP̙x<ѥ2+N.JpQ22f9E=Vpn8͙5ȉ>O&a_1v %Yha28QN:bR"uWkҎa"뜃E I)E-/@C {~, _Uk$fTI$t^adT,̱]jѲFb97U -[QUV*Us wC,2)M`zGRmՍp;g@xb^ЫJ>bc|n$q^ rr:i lF ;j&zU.QV-KѮ8XxY[ݾ! Kͱ;Jft2UzA ʚL@d-!ɫ9Ddrǚ WkwI!v #UFyN׃~+";)"0@:"Ϣ $Ƚh`5RB4R"C1$}.V J#v[53adpMՌM?u;RY8nBq9dHjџw1JB sԀΪK_s;2 @MOo1 >:=QDؿӾK{@6#@" (@/0斻yV!lXXR%h107Ak BH ݛŎ$>9Gu5#\Ek,/n9=%~d#mT3/<0@gnO_%p 3)YKzh& v(o5O#؆0$lTښ"0fM8hwdDi!YV,CܞhV 8.(ߴQз}z"$I+Z۰iY,4{7k c&-T މ$եϏ jDz!,(uDK:vu Ds,M>nh\ܻC "b_;Yx ]6޾ XZK0k 2<;S?r I&q"@y QYe IM<(ev:qc1<{ tgpUIDE(| _$,cHXODyz.I }USjUZ91\E~vckx݌g~ͅ~ ӫSzŔk..spǽ ΢FO3:燠7T_|T[gJ =O_5uԅlL6:W?{_܌ ߷Cvq[C0ӃJܘ6jg;O Ζk! s edᚏڴ'gKhyuz@P IMeQAO>\w]k-h(?-4:Z^ ck[nQ&3TETo7yEnsXr2h![hPg\mi ẉc^tYUhڻEWdz2BW8ma(8 =rDs pBJ<agN:H4B}/kv4og(]yŐkЫ]uI,֒ 9 Z 0tޒ~d?_<"#E2L@0J5Ckw@H V0 Btc0\ܯFJ-dZ0(eg##hoAď/ZbE(l=,:Z v97n@bhc_U ggM%v h=c,FB8]cґiq8%@]"8׀LD hyzqrj|-]h7dי9IeyMNޛa"1 jFu* *jPA[ӯx9f)N,jVtHY}ͺ{[z.·%w݂3ٵ e* Mg(^Cf`%+I2k_(]hacAI_b f,u8/ IGc{R9d|5$D-#.W]xֲkO@fUn*hL\e}}bZɪZZCUwQs9`B`6iy$»COK|X"K*Coڴ0(U=vȿ\ >'}aW+9J5y7DNzd eBG$(#/_bg@BxE!4LK[+XdchqjG vTSߢh,{#0+ϻH,q|g3b E@6z_b?,|c;ghiyviγodNq> :IVSUN~_ R:g10Gg4Os˭6UvYm@h?㊥!E|e5\lj;RUJ;pfHp^%ÌH^uM<ꔤfD iKL.!Q= |Obv'}&w6U5H۾{< KV-o E)Nb~0z^ \;@`?ID.zBB Ajs?J ;rnu6Kdrp|߯#Ԛ2[lT H7Q/phtf`qF2t} ~ 5 @2$_F{%N"3ԪDʺ6ҕӥd~s gY_=h[ߛ_yf 88?knY 'W|䆮ڡ$Ǘ*zkz/۪~lLjmhp眠-[iN]Aj2(hZ;ul&\^a1a2psQOR@q* :Et4Y8ڠ\%n/f5s~xI&DyJ|`Ŷ" ٤e=tZPpVRDxiZTߩ ҸV,zNTQ+}:E!)bY ⡦O)7ݧv+uUW}y=w atADŽB~R5+*F05w9Wbu%U)-4 zV3b %, fe2\33 B.uG(g&E DŽqw/Rve gH)(MIHB"&5` ť4,eT@2  7Sd0\CFI?z]2n^$\UBZq斡j^@Q_Š•oJ#ĹߎIG[o@?Au9azn[zт*zd\/ k[1a}\R]2q%9ծ}vDWZp:!ƦkUjuH::J,T(":jQ d܈!pWlpƿ;Pml]pm?z XF Īz?wNhk*GGDy3H/T84&k'٨YgadeM4VT.+5|υa7{hQy27T}o( YzS$ wtcB^t40lGE{qr3JDsqi[~<j~ 'W-jrʅpN_XXi_1{Va12S1LF] 1V}MT1m~iy^Ubc[_2 ,!\8G|FU&.g-*(ԜRܖYq+ՃU>SP^U2YN^%Jݡ:{fvZ+Y*86!hn8 IM`֏(W_ u^tC- qRc'D_r?{* Zi,9z?iY.ض]CmS> {&nƚ9q\D~d*(pK[[a(ٓ@n @h6`@ VkL!tcJ6)}Pf@b^f'%ٝ|Q5Adft4/(Ra\gyY TQ6&EIƑHǀ/ =յ:WJ[)<*\# jS 'w-!Jڃ9 Y2Ï7+np b(s٬G,!S]1riszP RB`ć|Alc2Inb6eJ%ЈMj=FzeHE58.1dl ͇ LpRaΐ@534~m+]Y}Q!1#5T} IҺU#BFRzSDKJ% L\@qr=}0@stG:Sk=+?e O/נ0Ru~svdY,kVg@hm,~?#;^H+nOLv79bD&֚6#&LTA2AC5 k$q8HB89!.5 cuPK?ݹߟl5w\ݕyϩDXB D>lYkwMcy>SvIZ1ϙ5[,|!0Q}Na{DcxFWnx8N7mlt~ |^3besBP:]eP!n4CD))<\ @ _O# ¸`?, ILNP*Yrw d͢W9tҁ8bG]'TgVP{Q> مR&ͣ-^&)Ӻ{WBZC0u- PZ\/ lBȽpD+7n )sdXbl*T>zg'-Jp1}`KۙB)8= ;h#,? Ι1zA, vFP;xSx\@~ބmջ+{o<Nq҇r{nCenp>ΉZg{Bg:R''*|a~%y#ъ_ΫϹv5 AlFU!}D׊0> ®yͯۮ)#z*܎{@ϴҠZȧBU zj݃lMdϷ/H>[ 6$~ 577=zG|W`Ҋ[/w"^Js|r( NuS٩TnC߱E ^:uS %7A-xk$A2Oo@ -Zro"aY-ø;:/?GQ C\62{zusO y?.&{Xf-Yhm(zuP*B\Cl~{)&[Sj_*':ՀK(QPpͳUoށ4톘d ޝ ;0Hm|H}>9ɮMݮv+tEWV:&@7BЬx E`?0fN=''ن/N'$ 1s|~QѹaqnNKϳp̪ VbldpSqP I5%++:Gؗ.[<5҃ 2<pk|Ȯ9CVl`͒*g ^yKBvV;ކvl1sߒR]{LHJ"e5L%Do+̲7tRC.GUeT~M|@lC'W0 ք5!!< H9 j:!Kl]b-Lg k'߀5-.[096ܘ,7ƅS+#k$[ʊ=Ͷ hA"PfЙ=G/$; -uI20$x |`l@c os [ 2od!>\DfeAUX]j~p>Wv &S߱q &'L?`l.^pZ|ɤAe Z0-jn~,:w#gdP`N lRɁ18tbllFVF>*h/QI>!_e fµbB$8E8!B|uF\.$͈XhaLNvY) | Mo%f3̬nc\Q9OO T n7mҗ ^ \o0zvSSβrO^@!!$[K~QoRV OWg`ԜcKہ>{s% oGDSR~ejB8Z*pTɨUY>63ȴtz 7yi\2zn7{u!y; yɨCI[01oSo]x!׃Z0[ }4g@XR1f\`hqx0I[ [IRJ 41c#27 ֊Zv-|օ0^5Μ~~=Ƈ'/]tdYg>:O^R7(}վ ?b+2ocnxA!@̅:4n>l u[CS ϶6~aG zzTv֜DOD~kv {ztÇK=+EWgJܜC^ ;y/wkpm.n{7ޯ}cwY}J@6P/F#l y'r4Z4}Vʐ'aVV4db]Tɧ8 2̐͠SU^.BW4yw$\g*QuVC'cZP*1eL H!b*X$*,\v@?!8܆ic=W|xQbQeaċ-|DH.yǂʴ\5)T&ɤoQnM1}i"u!$Q%/gGœTQ.q8=C-LCkӯ'H\\|BjUȅ8{Ǭ"PqB#BTШ`1voƒ Q,)8z{t݌mq:ξ@۬CS yזXܯ鳴l{poPڮ{J"T:Pesxyfnz78Mlc:9@9)$ڴR PLQPM<=o13CM4Z{B}fI^/Єr#.q ʮ*GωeuC˲u[m^ ue f/{y}t- [F'W]_1_lQ-\>blB[Ue&+ B%hѺ56gYQe4mܶ'HkN  ;K mNx柮k'[a( by#eb(+)-fWu)Wk L8!-1mn r"Әטx CXu6&ƫLI.نƸ%e^TA\5-???ݘA ~&4xc ,`>nNx$44l&oIK Dϼi -QYI!``yщРh b>p4L XjqAymFb!@"y\$K'}$7xKI'U )8I妡[Ŕ{CU0ʪ$_0Dz!eccTR 2pK2{+ :E-ZgmtHu~"Z$Ӧ 7e68}ŽLkX{VvA+d {x3}_S4=t~rṊ*Z,xymrsP|B0 hbqCrn1A `_A8۩Yj"LG]wχz# я,<;uf$1M qN.ae/mWV8d{|Z+}=Ded7J(1a> 5 ͈$i E=Xy6 M#(c/8 8c&RYKQ||M>izf)I>򇓺|Tߪ~==CzzнS%$nF3{3\YOfa+4S.|HI<4G=s!ݭ?ׄe$uyZIZi˖q?DŽO,zy#ug^}tx8'E9C99KF 9XIgZ@%-_)KQ |$Sʐ|TLy ~gZ;e$X$Ŕh=;œ>(˰Au(4c ;Ѿ F~[=^ĮأXrV)o Nl ޻EFu|=緒̓xc~+老NzL[Z .0mr/SVxa,P/"vUP!jjy&Ed0: 9ĈNH:$e E \ޤ<[ʇӻiDu':kX[N#Mr 6OL)z[c j 8M<|rl8gAr?-31CGnNGM`\< z&y-ۏ~fpeE*|LV=taȩ `=5uF*he^ܴ:E{O4C 'U3c҃7p!h?jl3]9cgg#MZXC+蜵%;* 9`#6ЕxZKX'YdA5x Ƈa: oIg+@?}: 0vfobN'H1+$/lh@EO,GI'p6l^M5_i[`KZ^ȱ')_88$_Mjτj%H_N bm厰K'&J2xq I xpoL77+16VJuI !% 4T2h)B0" LM)BO J”V(^@-о_"[T2%"iG<(xp!s!Jde3+,e'1K$>ZHP97IV3G )HBlcF-M*ZmխZnIDio 댷G ppb5$̹dd6K ,s⭄`BXPDH3(_EO  䗧3ֹo_6⣵t:Q㑫́p]Z{r"_yS}BފdL'Zǿ'0!Rhqm OmلZKBmVO(,wǥd, QuYvI)BZ¦'D<3{ y6j8x$TS3+=txELCل8ʯ, z5 DhSB@lZ&Lghm/JQy3ydHF=.y6h`nUA#(']E 9@:ԯPãDEf-*r(hEy@PEWבHbDP~e8WZ|^rPƗ0h= 5I{S0#ED!H +hڄ*'H+ˆрcjW4V:B9sj94|<I$(-y{&9Ew $US;޸^7>CfZv<uxH2/ҽw|c cPc|LW]#%_Eʍɍ5ͫo{7cO"1K-{s]YYQUv\ Se[:2ÏIiO^$z0@a \b +,'ZuAQmPcLr^,"J!AM˸~5uu^-=^]L_DUx ^RoN9k%+QvIK4Yyk퍳ع48x8XyMAPq\țpαMSEq޽A8#=6`P28r-`"S^Ls d= )t|KKqmr3 I5 +(De){&4{MŸWR+;Ϛ> ٫8*ӑ6G͑,{-*>s pI=Qc[# h? ^p(lK08BcDLDyKq1"F!1Js ?J,c'# Pmc,Gy1`&"`9nN? E Pd,U }uܕgW0[8W7 /QӼRe"ٛCxW< )F(ՇY h.; ccE8sr9 qQ],%Nx.T-6Y ΄ە Y }]+pp͛q$}i FtK/~10c,Q-R s>n= A+8l,l(QFG~.vѭ, ⼽af~Z~HsݴOyلJFc8Rcc1ޖ¸0!(i>)C6f!a8g<9å[YZFF&Cr|4/eTFܨe;5E hpDC Q`pJ@0~ G>~^"ɒ&u -cߡĦ]}p^ɽa737"DӭD,er 2YƃK~C5% P0pjE3XhK"-$;+* EzW&xzWX,Z4!jYL<1wΌV$EC* Ls_Ď @{M Xx4%QA-Lyy/km.\8w}?l?-kv@c-V_^IսLsК;2+jK#9V+ws m@DA<$\s+mqz6Delؑh7ngeuN[qtvtax`tF-9[Lmf'5}RnWt1fG{{fGmebΰkć#W #OT' aʣ eez:!NρMyEES64cA*"l:K#ڹќ(kwGc7ZE1ڹ KtK䟮{9|I\Zj(V1BxkZ'դkJg$hbږʅ'=`92NI5\DŮR=2`I"DH mQ_Q!Rt@Shԏ"ysn,ٲ=E+怈sE0跣uI댆J}[SSm1N[Bi@ ۨ톴K^\Qqg ̝"u` AxH&sTejNCo)T0Y>W`ڜce?6v4_z3voхbhoǦF>Ddp0Wʗ).HT*Z$j1֥)96ĀcTjզ!;j+O%:d΃1EHT'xkZ-? A L0Flcv)dE*i71/lmlwؐ9,oGPO< =$SO$NC l4L}ix̮|rrz_W7N%_J3@sh[X}xYEXDH"*&ѺffHLHƞ2?!ˣ8<>Odɰ׺i"L( #Đ]1 b@bb] ɰ'u~>i+t{Y-\%z>D8>ᱵxOΚrĴŃ%`ӈlj |ʺwTfEr{$C{5\<05(+h@:FLET@.X lSQKӤ ["zviFFjC>!72\lDl_)5iظQS< Ql(ԩQuß3%ƐT_ccIQrTjTqnjƻNwW( $iU^}ָv"<1k%4`>b-g5xHdS#b"VZDi׏Ȅjl 5#BanB<0<)bRq94Jf@k>d0>ǽiz4ڧZ⧜fqU&iv:Ι&t#.p W^7e^+lZ;O/3QSi$p Avڴx2 G,㇄<_%yҟqfbV3Twy'_ ZP[zrX/hhK?j1iD| !%|ܺ@8 ׀ |~G`H{%G)#iˋHe%RUJ&gf?5s|~[ Ayދqno=w[7i)!MNo ?*?V }O MKڎ$EsG@T":H߉TɎR/ޡp5 [ ;'7/#/ˊԎ YZUV)9YBJ,ϼ-~ ,_;~4qʰJEjnp sZ#,~:dR'?M - GJNYm9bm1HW/W: \a~ ;t33딡ޱOk$XREvֻ6ur~Ve{ t2ߤ/B}N/`ZB4@h:WlDh$1U;!:?')L/kpԀUG?s` >aEA0W8ժ~s+q԰C{:E(ϖ)?ksa&CNLe".t$ɂbZRT)%<5;l/|U7^`⮪:Թ "l\Tm&V`5T49\? #j)'pJh7f-[yUWtNf4- $]@rS?p8zgpz[˹B2?k:hkxzP2CGcP 5;0m9<ֽ=I*2]yQP-bdH 5J|r-K Fc, =|'r&2vk$BL֕J*j0'NERF稆-cU_'ǞF ͆@  󞈃UDL# ]1D"Cș;VxWH@+d6.1e߁)wV6wGĭu7qf5]g+/z@NhA$8YUlU'q^k`9V]kV1nxvp0mNN0)Q)" !mC;AviiaTc9\G Lg@Qn!;ضBO'lK8)1cJ[VLY3DU|IxiHaІ`iݐtR#" v] !QA{ A<"^_E-͌/rggskbmMKsB Q'&yq^}]/}Ii;V<=C q8B!ڃFY_.It<X%6Xlb1!N{  }x,;hQ_S~:% ey"mXP̪O6*j92*ke< 񉓯_.pi/J|ۃii Xx=_F6ʀj͚mW~ۢͲ+ze-bG) ]MsV6URD|ٷ9m?j-hq((#-zQa̓5^c('-7N4\f8dΨZ[L=Q r6ؼ,)"4A5ק#N&K-:u`5y>HyPYhR+*C8yHd[r_)@u=1X&$ėzT|-R+ed. .V/+8T||fZ%_sDe5Y9g`>~|W Y#{l"< x5^|1"DutWu6x!}-01 KPOtfAI+ d6+/Zb֖UX?CzJ&\=+}$ydxUnX+hPjxyw^`d1NwOOFVχ0HY+%rS*O!ih*v?W{P.!i\ {<6#{|!e&5J@^vGktJ}FXM|LQkMz ekW/W+Fd rMlӐ 9@Gu9^-_:B27|1@AѝRc}`O,8{s ÂN/ttj?]o &?H)fиݢL>jzCTf[Y^YG k؄Js;I:nۣ1uHpJ{ C<8tɦ;9A;AC;G]Y^AP#S%2n_hXX`YI \e=׈!5XiG"YbK`t ͉Sut<:&,Xie!Jb͗hU[A~mͻŠ`k^ ZѬ᭨YtR@I&gԝ =@Ey 667\y L '9LqvH\n -.\7E4^QFnŨH1aqjFoYM/ơ*3T[))|5sS?b >u #"!7h~A^`46 SHkyr!u$ƙ?i|#:9}0BK< AԨzHܞ]s!Pۉ?9jʰ^Ό㧀)s U{ [ksV}}zdq&$FY|n iDIҪ ҲU7| j /[ȅ1Ș~) b C;z᮳ $nFQ60đo. |dN}lASrǽ(|ᨣbݨsۍ;o/ow=~ڕyc~P .XUp DF AY6 MǥӀ)@1y$36,ɢgr6(l9B3ޥGLˏm);yC++/@+Og+pgl¨Xn_A]߷FnUM6qEn񕟺N@˜27HrI0L֘%y˨_B!o`~/_ cs{%I;?6'Y4X-JMp$OhRXQeyж^d -rgia(!~Þh&!6D]g~Xvb1w?"z={Lk3`'u4Z{bR[Wxr4KJh\fuj̶87_Z]oT<,ʦ佔09oHzK'W:&J-J%==p J$ 3ϧG^!B%x5ħM 5EͻʔA5lhщ ב$ikTRլpVe))n"tp0:&N]H-lKdɨ5P½GPK8) WL4&bmYTiK7Y.a/*k?`Qp "{Z( :#g3"zOй@s Q wfǞ^zA~K kj0/CR k 3J|د yLߕPcO~sL/ٿ o\Y]hTg~/.6{|0 ]sZ[rb BB$9(64N?Fµ47ϩr?WcZam;Z[2zeʃ\d`'=Ewl]r Ӱy[Ax2%0nMiY݋EBy˖s{~vX :(C\RJZC%vYՅnPdl# >ߘsy.t DJN,F!, C4L3ԌœԺvmu1wj*vZ,: _[1jWRSXRZϧ%HP^^ +(@_A\$<ɢZlHs^\Hmu~82mbڂ߁'VGW=fiMPNWwve'Rxa/- hAX:n[erd3{\U`!Vp+_ M‚"^xPjtc@$zP\CsPD c6ojLӅJj (EvE8=AS@E^^QUEbې#ruѠRȋU[ks9.opsi?┩l[Wm)en@Sջ؇噤BN%f҂\Y&F4sqQN=CuGáN~y oU]rNWuEB5/"O䱣$lS2e1dؼ_D4\ )4D%uE23lJVF>6/Ilʣ'"Li`%jH"w rr$[H!|HfSy68S4)QmC)0Hi]gemeeGrP,/Y'KdzX{bzǧP%ÇR ĺ|T1mAY']~TU'5KҽK 鐜!N=T>Tj֖mpYfgRޫ JIC^jӛ8'6 =Lb qFxkiVeGwku$ :Jivdq A#ʣYZxtޜzx5踎Q[s]{o6}\Y?=dqAjy!r⒥Si,I)DZzn/+}5C'h]m5r۸,+4%TygidL O3R6s$&U$ /ihʜr)"[.y`ڴg> \ԷGHHg|wr{KdE 6%3&.&u:t꨷JtƊtA#J -pM͚)eƥNXٚs- (Z6}a -&jȽyX¿%KUXWBdݯ&2aOKhWE}IVDfFcP襣:Q(kU`A{@:(Bv KCG+0n⻵!t;RJuDi\o3Km|R4m?W_V{_u˶48R3ރ7uϛUE .I^X\D[8y=F3 -RىCdh#*[L``=t|#5 \M$<~^4>6)waxgOJ1qOJ9!%Ch̓jIO7:Z::93ְYL9E$h45!plWE\gfCRilwG cy.Lt#,Lr#y'KG+eÖ5BZ9U/rR iK QF5vPa^3`2,IW_*)1i2JG6-ߛi̞ncUD/Ln 0.gAK3ϛ=F0Wpy37ws5= &U?c؝@v9rcGUҲ̈́>!ra<⤴B[BQc}'{sd=k8+tn/T՛[ +tZ {a\KVD.h2?NF_zۜ0~NN|Vϧ7,?5AMC}SM[ڸkThe*3DWy̒se6m r+9{+_XPK#||w>XěkΦ1eKW}c=d]ݕ)͢{mzcݩCI>Y`Zͼ.+;f lμn6mw6nŷf (ܵ~0@4g`u:#R嚝$l0G]l! D,g:rIݱb)F◘@5:k۸ ;aìJБqu]1q$W6 :J/MhuGDE=f}ls Kzbv®卦{gl/˚Iq5"ź#wKE>s*d[hq{2B֘xLtj$so",A2[ϭ RW -UL u/CFsg2#|;f1 HpldJVC)(aH4d Xoo!h}6aPZEQ,=àKJ[ϾL{} L߇gq?q?AoK p' "P7bR(VՔkBV'wԅz 1[.N~ӝ0 Ki }_v;B`k=t}i[m7wW]vhuwGse`1i˄ƕM:?&i.gVo.k66=Iej}ƀl /6Lt+ :2T^޲ӿ`kz1=g9q|l8,t"DF|ċF 6>~ޓS٧{"Uz\ɔ#́j(j솅ԭ$ ꝛjІfj'@T%eC|f;zz/a,9񠕫,Q'P*E^3ѐ)ݒT}KJS5ˍ^#zwϿZ^^r.@={&,N,^䚎g}HgGf@#;ߓu<`_ w`5Ax)⏖iJyn0 $2\;}1G钙1|X])c$sD&Us*AâU:B3)NQ+NU`7X7BcG3ztJ5eKWUZ +K8V(/Ypl =`x!XC?Y>dT%*Y kUQP{: rI۲vR+B0FqQoF@EĀ 8NuE8wsU=Ӿ Xs 68mSn̙EW[XQ_ceJLf0~-h.Z*[kZ?ws#FczjJTނ?1}r_Hz5P^dXsМ,;P؇{&AVEq~COQ!}7[I`.YB XJfMֈHf<%7U]H0t{ZK*4SIP'L_q}ZkMI.so7зՄV8_) U>-QՔsQQaFQf't2 9bCqG2剃+W[Z͛IaF.~WS %Sgɲ[Oʯ)뺗S5{CķpˤR ɏζ2Kx.v<Rxvv_7,XSiVП+):Rb<猕_ q"/9TeuJ4!g;*lz|{q{ umxId***y{qp?!fʢ]=tHa<* R>#wR|QxG%.0Ā4d>SK;c4cX=FMnŏe3a_-A%E2N5:n %x.#xqyԕ[z:Y̧FءVq !!uJAFIzF i q!57ųUcґ\+;ۓ|}-U߻ a*@&jPMޔYdyݥܵtq[u͛kyQc3ש[JAyИb+S)Up&9,uŻT's1kN}5e;Э=,-9uu܎er+rk  בط:OYkm6uP9-EH< %/YRRJx'0oכ <7X`EoMi Ϭ:t:~'b8 J%h|{L!4>\~>x58v? v7?}{' hb]('@cf.=p_yVZla4E,F~57_ȽAaV80|TFjd0NA&?Hqh=2 R*&L=^sQӼ?6:ZDzj%3imu2Qkۢ )EЋzc3-EGUBN\R Xt0|R~`1t D)>0:R(3(*aU>ce"!$m@SO#>{YCcC8E!X@TCdt_hο+lc٢_=AW}D"( *E%Yts%$!kȲ@k@!h!L f o Z;^23Z_!?pڂs!!#h ȥ66K"(1Ȃ(b Y(ȾN3WCNN d.0.n I Yd-nuCH ,xѨ]`*=.ax/ 6(- 0g%97IF4"}%niY1Jr2b(z AMSh6-4Uh$ϳ"Ί7@q(@)t՛B+aʳRT[Kcx7G9Ϛ7פ=P?~hQNe JLO]jɧγԉ9+^ѭ iSc3+rcU'j6 83])k 5OկB81EV(\r1on7h@,wL~ 뫍e<ԅF~/Fs͒ԛ!>WLl)o Iձ(X>ݗj֨O JnF( \;FGxm%.o(Ӥ j&*ĹF+X UԢJfV0PxC6M##$sYƝn#aUMP  kU.xw16g[;"QN.fkLJ3Lnq|VnF3ZVqtJkO$Dr8%lw4M bPzatK.6a 1C ^Y fLIwi86Gg;yq:2@j''+͛p2dd}CC`d@@-]bTݧ,n0R@I&s1tㅊ$ *$C[*84JecU{G3u^nUO%wL=Vr Q3~0y(0O;@*%R2p$W[9*8%Fq% jX59F|'Z,O_\m0D3R_D⻏m{VlD9f:6( W_-o%@ܚt`~20b/(08"(N@%[N+j'n8TpfG>[ dU3Jg\>Rd;],%wg&Rp>Wqx.8E&mwm$pGߚ }Aގ=|Xp_Ň} ioG$X<1. s;j56F>ʡD6U@99x"P{5BC50:l0Mpbua$o{{zdd 3biDLXmPTà~o~8Co7rp/^Wiu 8)@^%kx8zCv(rxx9W\a0x@K8`"ﶹv>詃Oho|.l([|rl(X$֟ mpGǎŐsԒ 0"DBˆ̓!^Tv k%͘;[e#.] !07sm g%'%ï G  7̲qs_]a,?| ]ƵyJe8#d7U[ڨwxvmwNwzo||~`J|X-C'SꤶRBˀ" L fwNNۜ Å1!^4O2_BEh+AQe~b}wuЄqά.",8nGE.Rc 378;vb$T~Q|)PoHǯS 4S0WۺU#_a,|p|AQAQ<>}ꤻ>'K$N-rΐH1N`dn(ſ]y~rw5MJyKSQx1whZ/w6<'=kc]t);Ym6#U= !P?] +fNz l蔀Ud>;FD#~&1>,!(n}s =xZi˜,xx7qؽȼ!tov\l(8ç2<0oD?Ͽ1Ido 2=*KXfx^d2z-G *( -mt o]\ub- ʃaΜzՐki^Q0M9%Œk()' btPwCo&'VpMޞl+wD5`÷ړt_bq”/ W -u8TrW,#cP ĽOڞf}3&ܧE8gQ@ 3ޑ%6 ܴE=g EQ\ j/g3D~6C?{}Ikr2/{@ovL{{l'doG!^S=C CݿmľѥLiMswddhi,IP&|rdD0@R@22;Y0 /1gu%DNM.`/pe9fkGA~o*bb:׀yS3?NriWv/太: JɹSMi*PIFwS;=PM^->cNFw`KdEM j^8iۀ=aYN6U4M+vc&6( qˆ˂#`ab5 }L 6p1m^&wڠ¬g -+)4/#,-M٢C,D.Q%ka&;^l|G.K4.mt:N6$P=66]GՌCjg!%.+01F.=*_ "Ŵd<8ڹ|yqvuAd@|J6]~U%iT^P_nˈb&Ʀޙ[R樸Z0RE̖x$T\+FTq)_Sp͸xMc[/@Ik(67;Nު,bd9Þ(HL#|9D(w0:L#=)vi;zx0nQ1B"[nXqq/CKc&v]ЕL~9cƕl3'v)-;nDA FL[۩hWbf+q(>iB9~|&uUp}gLF*]l/}૘}R}5 7p}Y8,PTv'\-n+h:`xslcD{{>ۗB6# 1 TNY?3+$ ̜Y"AA;w|-|. _?XFf& 8:s0👅 M,̝?1%gU|v}nQ kF@U7QYǶg Ti"ztW:ޛ<ְ۝a|9c+%[nW4ꞇ+>]#F>>}%ٵn8bZ)[j;6U?W+ޫmJk*LmʫK` g) 5g ȬO?~G]cn1U?K*W;`DAAЙ=[<*^P^vyR~\_](Ehʧ<8 ^<@G>n֘7yD]DI xf/=bf V:: q\q!ri#:q+Mܑ~`֋BcLd|C/oI=MJ7e $1:rtD|w IYN!Uk ɸmtIeH9߱q 6]-{HB9e _hRvB̐q\?+&{9z=",pEkEA~<4N+v:Xz=]e\yvGcw|S90j_3z٣RN EOuWz1վnkv@Evf_U1]Q5QvA$-asހPfy3R^Kv=^ RMVs.9r쐢 zUAxݟ\{>1[Açv{kqlK2AE7 2$(󅈄C#]W(#YwW};# E8D5E<úዂ]Xu@\Ha I^Ҥ[Ȟ5M˳zPsp5{ (#6RHZIst1>H(Tg] a^J07~e^ 3ܐz->{B+@:G80yd-wP[2zLn6U] NThi%$ñ^_!ڗ~;[WSOMfR, $d$09!1+ᑬ("v)r$,2e8ҙH۔%\S ,%g00X׊Oajo\جIAЊFrA$8Ff E1$+Z)C҂, U`F E)XE+cV=-XNQE;Fс-3rH˫b0ޘ @qMW-16 <9o8섚 a$ N/[3 5ݱ(>]nƞ{yqMf.1l+f+DG?gPT*D$pҦBpZޕUWM`LO8i,[ei&ؤaN? }2n+<% 8U^L'$c`[gB3:8u%TS1@& lTtQ_U3ro@81iEUN2iy8=G<{85JWKCaP>_^nk Ib=S Q9A]Q5s ^G&fAhv[o;b*qUYh<MubxhvybM[*0l#ȺIs05`b!&6˴eJoHYxr@v 1bGO#ha)Zuy*})D"eccOZļ@7I{(|\lЪXՐh>BzvtRcS<mIΑ:PMրˌ4`y$| 6,i`Q{^ FdQ$"́`h 9X'ijhZ-_}|P;]( vR0wn/|-~W5Cb%>I'jq`Jvz\OJZtynLTb8eM`zFEW63dmnJm-Ұˠ̬E}&c%tT^ZPE~Zw?0 ljPQN$5oYG˳UvXuBUtTluiX\:_ߛ |_1 ׄcWaLATķ!WF/Yx -M*hK` t61bnZ氉xhj&NfFkETStNXU1T cG 6jF^R@A¬Nޚjק Z:GkVc֨[]C1׌ zS<5sNvw Ŷ5}ZI2{#raXEbt:S̗iƓGxg@ Y7n1i,Tز6LCLԮQ9'7|݌7hSA[Ķ{70h[h;[le}@b r6zXƱ&0ćRP=|}3Y;r.XP21w!2fvL!+0PN 3%6?(9K\` 0+BI.,LK;X.5n$D]mVl0iA3FlW!uq!YԃЇ%in.#H^9܋~~bR ~fe| 8Èx``NU4A-?`Nb{'Iۓ&))g ga|/c玞ZeaϘ8bˆr.ہ`Ia T#,;:uĮ{x'qKÈz;yhGӏ#:#{%/C`i0SB\4 o }=p[cIRZ @ž"nIZ/Kt#JeckEaZɱ]k_*CmG9\AˊSug-[Xl`%Z70e_I}%PЏh:Ԕe<ʠR2hZ|͎jV" |bfwEfY!'ct/`ILt$+VteUqk5tmwJ_ʞ='¦J"M~,gdtvWxwBe8G0i}lեJ2Hp H3_]r#e``L;>f\46qk.e]ox>h(L*^wbj^U+S&[s %;Ւԣ bDzY@R4%$iz![ $+ぃp@=I!3 K/!޽2Iky;qki^D*_K?HQ`k:7NTN:MASǸ`FI RR\Oَ^ H$tϯ=\pz5O9#!=8 !JĆl,%"2abᦛ;H,2C$LLTD xu M.P|u?z -C l^;MINhV'"Q>藧sROW&oWIo& Mlb%| ̬h BI2/'JXCh*z ^G!VHl0{YlփkIP*8PX藍qU,tjbUr >te(H!>1^"4q{Jļl6 z[惐G ?#3L[hO ~ ybU/Qx2\,ߴm\Mx{XW,-L؍B{JUL2YU{4k09= oRxSr4幥j:uY⴦N{{|Vowb>ylUֻ= 't;d`&W(wN1:)J:~I"q G>l)֚j#a~b5JMћh9yߥ@YN p;2сZhY`6` |rD6,eL6@6jqB;LM#Iw%zo5L0aA1PWNnYvtńp8}p{5k\ō"V27utVprdq𞼀w:0 á!4ϖL5oހElCK&?ʛqd^crɰcnMD~H?4UsKjbMEĄ+ACQSS5QC@ROE]N])NGHDs\ZyqQK.4qu/KK]Н MTv z=NҌ2h+b_"]1)o&B:Zc7^cBXv[G3TA׵̯"weHm%ㇵTIJUisf%9{` nC#kI\AV|/wDZT;O~d)k Z 2ixJx WVFHh枤Qd\_Hܜ72YՓSDv.m+ǝ\7Cnj{SUrDƇw`nT nR ImO꭫+`(d;+9=b9|t2Ŝ7܌f#(6t%4ϸ鶮y Wn̲EճJh+>XC1x'=$'^l diƛ I#X* ,U@Ŏ':l=iF9eEq0Oꓵ?0{ٶJm "A/HcE׈LhK۳|t^"u__ aԃܒ^ȃ,QdȢ q"$R l!cn6?"Hw'y6sTL;+U2*ʦtM-ijșPR3&[L;ѥb#L8Fng>5}$J?-u(3Ǜ%YK5*HQ[w|pfYsIG+̂Bfp[R4FΪ`XG-*pO b/6[ՅC'*#Vy[aY6WL>Jt"_ǵ5~@7J/55S̒d=̆ȮFP narqI%* M[zp[MOAf|*Z`ɡx'#9Nx|̀Gu vBx~K3XuM;>ؑ}&|*=bOnؽ4Z:ؽ42Pe#}'=`+dWd"(rI1QM҄6%v($“RE5G<}h+VǪ 1\n(J#ڣHn3㰹S$J5fsG)0Cxi1WS&*8s]h:Gf!f|FSbznK3-`H=`[ͬW#zUGȋk |\Jڒ}Fk,H)$qHt褅M,MkeIeqR}q5y:#ytVQbR>/v8H{q[1+ 3'u$!*d1\`m%\ 4n;Wi@Id)qKbڄ1A OZ%jp~^ W/W*Lэ3RTO Bw0#ƒk#c1g=.c+.TPbb>+- y\ڝɑ7Q47g]V .')(j%t*\vX>&=- gMkh~߯4ZϏ qM3hrEgհE s:7tLm nzи@Th)Fz>qҿA!j=ÀtXvĨe:om[:k%]<3 ->ءZEP=m.0/; +1T&jthC?l 12wB?H?KsF[c;,F{TdR!2.翿!P soT~xp0\S_{y FNzW'o\dF!#}Q>5 8:t}@ 8|Ag eYJNB1W1V a ,_}17ɩ{IԿsJXۤ`$Q$QLLE㑍{[#^ERx}^Sd SjH?Gt= ɶ956:%쌟# v;oׯJb{Uϧ_Xp!(#ʔxN'T=_uCjF٬ȇY amf@ħmE\C }iԗi;rշ\ۼ딁fOdV 8Vl%kvPN3 {)/żVG^,],@7QoVbpi{P|N"Z hܺ!< LիR]Ĥ2Vbue3+)hW)pGPA|'$,dKFl;'@emH\@|7 cFm~`uS.NFJR^'p8DQoʾ)Me^l3oC psVFId˰\{H /f 5Fw=lp!af- k2c.+3ƍ'jSBlX_؍朓9'O Cd7v_ȫl@90'Ldj;yƄI{@@!`'N4[9'ZO4C<1#C>9e&LQ͹FGvPC`H\FI} YUS'A3׼[_(I}t;an_P -xCLɠeC=}B:&HFW*XPEAqA`v膻oe!|G!jC@ |B/ khc@^/bC 1<?K ם%>ۋt0zdPe?3pbTf)ER fM cj,/}ӑ470M ɇ3z'`1"wR$n7z]ts(_ƌ+m2u ͌s%wpƄސ~աO{&5d?jGţq^cK Rvn~V3/ 6 4y Gf띄t6؃w'8K ' m]qRlxV9njgwJ|3Wtbfe]Qę6[-l%YJc!?)_]sLS<;Jh!{tEMc~q_R3/.)908Ϡ*bu5/:-U^ay-(W?flu KSDFt5&'a*ޘs":9Oc+\܄~'> )}.C̩A.wz6ɆTr@±e9> E҅gs{bښ c="u"LgeC65MgV@eksbRyCӡ !f+xE]k5l{nC` NGNK\?յ(JRQ2@yՋvu'Z6bÄ+]`%br2ckLkX!n3\-hŘݟ~a7IS3SڬRHL?*q6ca"UרM8Y܀9Q< s^)6:oa4ͪR:'!FE,fdN=it'R#R)wvv(,\f+gFsD,.g]*-`|~o2Ut~5X"cb&ఽ=# Qywhy ;UX.leZ6-̒`x_5h(v~iVsWJ6"X#*Ckj7?fHuNzvKN$bP[m]j9N/|h`c.rZpT'ț 'wNl9di/{L,043>f;]q!wqWyҘkYɿV碩Y֌HO kǝZ͵T5\eooLd%^ ļ\x ''o:]a&+*ujїXZ BSwX  eB5g&~U> ̊bmK Tydi|Ӄ6Y %}&JhV0݊ܺ:@lxIt9vB ۧ^?OH:E2 gazu!>=^\k)k)R=% lϟf_f>bOzS;sg͙),vSņca.}Ωmr0%5Y%1ҿz3epJګS@8I P@Qθ5Ĥv0"IÀa'=ܽT(צk ך}s;ZOg9)#ڐ[L"8Nx]fT Qg@4 RGa}26$$qa_ege˦ 9ť9dJM19cΩ~* Vu̳IF@3ͺ ac5]{o/ (cFx*Q˸,֯{ۇGGP)SGX)O<*B^K%UFՙpxS8Qt8&(FNNqooyXNN *[G]]H1wYmLPab *i7TwfyBQܾy.ʷlƏG1Hhl|d0mҌ5Jص 2ɟ4]2YiK_݃Ja7'tF륋a=lY g&0W^m\󍃢LVRрEM*,nH24VUʍ$QOfW fl¶۾Frpuߧ`A6~ۺsl]t^x0?$)q3[./DB[]Ӎ' *B' klh[.ݼ]i엔i XM8r :\zPŖj%`f_͜M * 3wI.}0f" %R@] t~]JК` 3|x0{{e=.*+ZR;0sfᲝ*^~sg75m&*s^րԪ K2N4)|ԁߜ g7ݴ*OM002x.m^uϒ߀i9;/Ifi3K|p'ʫVW 1F㇮2m>Chg0!w]"d 떾Y*gy`wΟ0@؁hYb:o[J1zfURKui]Ia$+tCbU7*v2PÛHXfu:99"2`gиz$mmggufxe5>`cie?4PGKs@O QW )o8R{F@?6)ȁKY6F]j,eՌQƍ_D<ߡ(5]xM-Ȗ>M!rM?/ aHS2@.AEjʥ(n1}?_IȴV_2g׃dH]gY">X@CFoU0:^(r_| b8-yTdbҋ}7qׯdnR.* i+8I:Sfmi"e2L aU+Z3#L{]\<] p40ZB)v I^L19r#c!X;0M0*ӥ>٥>ف>ԜK^noy*towΡծ-@l@z~ja(E ,m9&}#RN7gLV;@V YqB̓x ? Zt"77t,V̊Gz~.>ϧ* oa﵏5I? _;[&6 Sĺ;5ףCt=f^H1Hui{ݓ1k>4m'BLkO i:hmCX`M/po3p"Σ:?3)`Ф#·c 28cf(0(.XMMMC![F[׫ ZV@pלE@Y4tyhunPR1y *EfZ<܉ts(Ģ#UOפjQfoo]R m86444ambSG;knA^;uS[ߙ) B9|M~Y7Zo U_'Lmҫn*O c Ksn0U%+ЬY1MpmlV.!1Y[<؊נEnmmnjK$oqUnv1ֹrdY%Ram]3-̢ *5+F䥯c!|gl05loDw~}.݅ꖃ 1 mT&v>[ /ġ^{kR?#ɱ~23 -7q$hr&`Ҧq@-w[EP-*ST.J Ө7}hj·ƿVtsN!:!11Z{{+ަ!+^!X\7NNJOzP(.d}L;$4G_?Y;8Bg9oqI ט1}J0FlΝʱK $L>\s>嘍-^+=t;4:UknpMɭ񙾏x;ϖ,ס٪o81='5c>}=*;.5h)/H:]DIʇHBRN[m+!LK}wil#W(EקÊ/37ĥi;xP"..GH|c,v1klHvP8ф ҄`ԄW][+.*Ҹo0/x';JBeZ=4 -\6C@3 , }-ˠ@Ȝ#9 ڼx3 vև.y "T (,Y7 M"Nz_(~T;/3O7 j;+܃CމA?/FAWoA?:'jdV +^P.UF{-?cUp'[𜟠Ov)X"V+ӛY4:0E"%YԤ26`)P;qOsђVΊ:,h0'eƊPYYQ=(4-Տ@qʐ: 6X 8ĖLwR<*W4Wه&a '6^ X -BZk(s٠Ctot'F߅EF`@/S ߅{eDQ&$DEMfGAy#ȕ2~rO@#iWuHN90$ϕP=AGytX kTe0TMe~Il1' YMG ,O5U<l RB@ds".q !MGF!mP ؓjm\=|ݵm 4sP?gJ7Q8LϸӧpoȝA IeX;$Q+)|+?HQ^c0o0w5*T Pol ̘ QGaU= &˥1%+m h}h7eʐBRٲq! ZUUA=y;6XIF oi\{0VDxM"-#/')ࢷABaRX2 BA h52ܭ0W@^6g>qsCa[xq,/0+WM NCs)b@ m:٭tyf ;x\@."ur2˟ђ%D(p)]#/7EY Ma+kmO[,!+f4 _Q-f{"[X @8%[{څoAVrVz%LfՆZC"J!Pqc0ۏQغ[_58Q['mI_lD!W'I 7΀>ۯRhiKtdPJɩ[u0zt),*_v:VW}u}Q{ZSjzq҇t\ +K۠t$KFSV]h&]Kv]\ _a"]#' ZFI7i%Zϯ["l(|_'\J, چ}hjk(|غ=G cpjc!F7Ђ-ǚ_]ݩڱVaJ2VC:`O&P";vB8iL]M'Tr6!)ym}2kQPBugy@꫌_fo5yϼ4Tgx>Å1M.)yvZ<Ս9'1&rD~Bǘ3oǐJρG}ehv{[pGvtCىwP z%+äFM͊Y_ؘ~YK>K#L̫kg{+x.6vɖ/okS```K W*1RjOU/xf+,}(ɴc5HJt#$*+G7-Ҫ,%ѓT7YAK&-\0*} _~g4 >O%8Q} 'NvyF/y6}fYB,%N7Jf+qiMODY򥛀bꆊ ̳vva}6bm DF}_ޡxC>yN\ ^@,[U7~oʜq׹<)~k__ xgt`J4[ԝ23o`LY|YRyn#MwlhvX9gub19f8 v\!_e%vT ]1pDRMUSZPm9@y[(a5Oi][lV9 #Z}my%v(mT 5]졭 FgLJ_Ea5^yq?|?_HK8z-C_@D{Wbߦ Sқ|UkgXϦޛ{7~.q"dxn4 p SE imϽ,CY!_ ybO 3R`Yjzɭɣ{C.^ZDC4Te>ҟ}4Hns3p2PJqTSGQΎ!z%W p}a|Ռrs:j˫sj{Z AidG7fդ*ݯRt%_>eVa18)j6Yo;o? Vppf3mQF!iUX¯ԒxCpS,(@@JNM8U)mm;zѩ 0xENol64fTh+plѹ@0[w# iߛj_KzQ|_hfh"sWZ2PX ˆGEa2>L?]9|]ˀ=?8{+8 آ{h+ldXA%yZA_Iuxiӱ6å#8mͦJcD _Dz%|T) FsTo ` "c RX$d6c`N8u%$v [7šAD UOE>r=2p'YTѳn-Z\ Ry zmWRJį%cQⲣq$ gnVr"g4x\ 4f:*(](5<ÁFY:l4ӌczYypa~̗VcEo 7(T}w0ýw)׹e٫uE.'G9ڷ5Zb(Ӣo2D,L{ɡ`Ǖq ^NW^"[*6Kܺ(η%s~`YJ~ĵ{bp!]{ /Bgb?vz=k b&Z 'O\jdZ8ZûR_B\~>}#Al𬰌O5Hn(QOnWnO=sN!m97Κ.L}r#]81,^* vT`.q;NN^`ɀ%xRN ߃ V_ V5^nU0 fUb+*?c$!~:Y׃Z$w2D~#5]Tl~2@}|;A[0_ S oBoZ!jO9zQ40Q44b*.%ʃǜtJ#yoV;Χ8&>,eA@wN 1V^.X!F skѭV>--^3h@"y{!BX@ptEWj#N9-(ʺohcM񄲺kUWxY;1cj%W*DǨ.hm'?8 ef:pi; ڈ*0.[]?hDO;^Yq'/Mj ZፋQqI;%1/ΙL:!Q;:ͨmmwRu ~C7Ne͢+\`@B q<~?'ma0A*uB.ع<5#Hi`T&E/fɩ>,][$L";н 2ZiUVa>]c'JpO،fG7o//{ 9|"nG/L S϶C!J]ȚmV [ 18sZh4/aVa<uǥBXFEМ${p!@^-s <?sd㶽*?ց)Y__1}y2!dsk*c}n,Z*HeZz;WqoϤQn9k2O-fݼy-|F' [ _==⋾SqrBe|Lmp_Z1R$sY! &*I%*aK{E iǀ_zaϥ2 T>\jN;}͗}A^/Ųd]~wޭoA?+HW3֌ :Kf+J*)mtU"bTy6*UpbCJ$H"D}3(^%{ V>|ʊI@H8\{;o,0bZH 8 8&|Έ'U#~|UYN,.V2d{ Vڋ @d93†:+k8Tv=ɷZTuQ8:tFZ,~KGUu?x]eH)FѾzaXt Wua~Am3+0b*z}\ V+d;E,{${ js߃;i8wbfx:KJ,ݜ?bۂ2f9Wyr,WgGY&aR!u.w<غXOD|=keT aB& ~F?ܻ~Mfy,λ[ /]Nnp_so7woԳG3cF qaF5γ]26 ƅ_O{ٸY>A;ˈx!5 a~F6v~ιqRxܒo~}u;rL\-tFTI@fTmz =UI Fw@{]XlɇPN]*s 8怽dVBfDD@;-/yM(FF3zfO{Goq\ omnh wi>kȑqk{U~GK zXZVha| o{ .0G9.l,&(h{=~)x؛c*ܮL-رDXtH6~ GŦ*Ww$NVX$P;-'؝ Maczէ w67k@ˁd>;;ŁH&<B u3r~q׼;2[ Gis;U}f%}َhYNGZ?#OTʛ512[̠-=1*8e-mg:t.X$ybIu|DL_VFB UE 2xʛ_H -F~^K8cc+Vpهf:-j5N:R?vxiDw 5Lȃ̦?wUÁtDFf&L@89{Ϊ\t]83&imbv+rٍkpwQ>Pvne?@=+o/b.C9ъTrTpܷT_S6i>g|Z -O -akb9jۨ_>Ôp)帲=%AiFΩ-skzn>昫*f;tW;<{AP|hnE:@S8PeNpbyÜ+]_~1©JؼosW`OrXc hg&pI1jyox> 3#7ˍH#6yBAt=>w+LOLEW@#$[z锁Nm\I1Ra>}# ы.=V%Z(+>->~(vKd c+kS'ZM%ҧ+GDZ% eN9Pw'qɓI_Ҷgb}Goxn5gnƷ5G!|ՒBiʦ՛1ѐx^3B×Q /kz-w|J#ow$$JyIb -aPB}j6Ҫ)5&W-K9=W2bp~PfE>|H11c[]yqFm' FjGidN]s8|gan24dqPsV,P,"0loK{#t2۶Ln.Ń4zm>Z~7 M2Nؚ2;챸jrUi_ο+ 3k/(ߡ=+W;e= ҍ4=WJ:cIrFѯS%Wtxۈ_ĜPt 5)Md*B2?Mj:G h疆3V6vW1fmR<|tkKs"qx:+eY!V"qT8]O/ n,.,^YqZtʢc3?k9Bj-UVpE0z-(GꚟG)d}E'ޤI+ ʯ/+ >YOvUMMNFl#22u3TS0NKzSޡZ o]exwT}IIvlCZ5l7X8) \ΪH %/r}tqR]C{hP}}.FvnI3*oTZ*}ec8o<6̪N>^E}.xO^MA*1=6áf DĘQ '|%r1aaRdhwq %5Z !q$<ۼ\S@T13%wSL&OUN!My7k>P%}F|ۙU#DϹ6 V p({-|Q䬒#/ϊQX177A mFxwQe"b">xRchUf.mQoV"+V7Q-*:Q/gS~To~1k]yQhlIUuu^+OU PAՊSLe *JS;jt *N}(UQwgf=z'ѯQ\ܵ^YsOLd?5:?/'!VTS1oT6T N~朧[f㽠n5`H6ݽZT;}Gl#X-enK/) p%?$Y_3nnu _ 5Yw.aDv8/[糁ͩifÂ+_(;Y/[9h3  vmv')R;|)7Xޯ2 792ɣXMr,Abro=~ @ܧmU{C3Avž߼܉u٦ ^ߜ^_ؼ# _6ZR OG q9ļENd}L.tVfs )}{_޷~'>uS}f?L[O}z픾wе*j4ؕS4?Rw׸=]r&,Oȳ|<-㽜/ë}_:ܾNs7o_TW+lG۳to~)|WtCjm?(G}|'\y3=k'CJ/78O}G=-\'ٵ "zzşлp߹\|iחwuO~6ȣ!iZ"x5ɧeCĢz&͚_Bn CoMyyz!{t]4Le޸⣵uQfHȒz͏ o6'$Qtj`܍gN$(Pt &>@UT׾aXUijKIټD3^UĢ_8I&x\x.GRhN܄zC}16Q xe:z,>๡G<4o1ii_h;UyFSJMNmi|1[y@Ŀ#A.6mRZ='llu|[eb+7Xǡ65ߑ9 ~Cau*'B=62b jGN\{rU7EdlXFz4)PS4n+QX=cfFk|t-ioxDy{FPR (zaW.M`YQ*A/cLjm1#E?ǜT eUf>ira YNp!tx YX ^*A '.4u5]Rܨ)>SεkdC[%b$%LEd&o?CD>[ GNWWX.G噉dDT8!cOƋV#لòb*& -c<{s7",CP[$!MOo15Maի~qvʊ6U%IT2NjpNؿj_פ3*Q߯^qAL ̨DVԨ5E6/-͔nZc wH˼bdQި5Yʼnذ0uMLQ`ࢂU4R${uA3#"x$5wg6Zu@D4R1c\"Frh1X:Co1!-M)̶<=r9냄rD0޼Ĝy!D _54RֺQ5b,3L;S͘K̝Ir!+Tr7;4˸G[d`"*sM j TPIy-<<:ϥ]qA_Ss{륂`rdy1|يG'-GMxZ_ ɬr,FCsiӘjSM$}RDu'눇>h`uKqь2Zt)*3.iK oק0@RJ ʗ7++A-7[1R9/ןӴ(+,Sϔ=oIN)ڍYI#eBoszt{b4EK4߫@]=OgW9ow-.$-c0 vZfa[=ky+>^\S1?%g>\]=Z8}܂A[tϰ3# }*bD-`5eQgJ)H%?~Oy?>!4t(B|$r5lw`bP߽˲N,.ye8d;d tLd-H2z$SS|m N_S7jvmܻ곝.L5pfx=ӥ&vxn=sjcp_p^qp_q^kY<< Kw֗ʭ@$9~(yUZ5eEfac/<.2ﺖ6θoG__w_]>zcNunxoBB^=9KnGwl֘'V>tv0wuѹtnەnL݀lN7|!s{t K}3 4+{+J7;ͬ z؉`]-8Y])c L>0>!=G 9'=ڞ&ON}|Bg0wggx<9y3߿Ww\W>y(_jM6 ٟ?f?ZQ.otfF-gNh*HLHpʀZk6XWAol}绂3YEwǿy쯯>6j rE5BWz4ٚ?ۛznUuKҖ xE6;UD]K%џ$ Y`͑̕  ޽M' *@Ϡ0'7vـ^ˌēD&$FZ?yü1zU#>|+,4fh @ '.pS"R#(JvϊTX%]^wu4u3uWP)+ߧؘ:BOKovfhg'7`qp0'0 ?8FE)R ٪K2,$x|VyGۿrW\]/_g~.~_/ӳ^_B>˩V6[Wʵj,T:%ohX7Ux|l|\[ov*IV_|]jLE7=e9V͛ɖ'+ ◔\3 Fz=hqaRI dr ̅=m ր܂O1]( c ύ1meesR>P(T=(}idX}dG 3b (=|q* gcwК!}aςzrxA|pqKdO.dtχ΍>(}hq9B8YvF CaֆM撾]Ղy_hC,?5gc|zõ?nqK"e_9t5 0gda_ljȊóOl y!n׃P!t"%JV\3,A X$V :V !mԈ:m#JXȳKM?ܯٟ޳[g}ggB20}/4^n79nJTC ĖPыQ#  6"[Kk"׌KJ ~Ҧ٩Q]tGAF0<鴞E٨_?n,vcy ؑJ.?y!]V]B2j1Ls7-h ";^[}/1(4/")[,Gg˞!Yڬ婔ij&aefRq\blCAXa0S{VOQz"Ct9Yi̵H%|VߛA@9*Gr>ʕrE^J6U9F.܅4`$'J _sG],}7SyFay$PE+Ӱ=BPbˤvn:A$~gYDkl By hmba1A{\Uu}^ -gג;uٙa?Gw3[&ŲN`!%Q{t5-*^)4v܆:ezB21rOO,:P(5 TTU c!\ɪ!0)-1/u~WKF$ s\Quxg-<_I.$=C='OU䱻h/&{vO]L-[ŖjJR+++3'ۿ_X?jOZ8wj00@exmjuglsl}:{l.IIAH$ t(%ASʊ-J}lFmSsts3_ZmWEwv˧sjT: ɔP7BRN (Gg\<Oi n-!nt~4n-<>'Z[쵟%BTHac_4秗?^hK\>+ ;ܾ^=Μsfºz9 B^d/ ߼߃ (@;OL+ LbFLצ4)@2Md7=`'#~::acBsbus)Ic%!BX".=zBlxWn P9  mXmX¤<(Dui =>i4Ϗ=|< GѺM>J?_kQ6(u2:K,3܊~Mu }TS&Z`n>/v ˓Yl,ޢcTs !={RveCEs)khcGvҋ앮!TE܀b  ͊|W'xS&x0N A+jƒͳg`9jgy<&XLw,'I qvbwxuu:xREoSikpmq-.sx~D& o߯~x?zE蘰nxNKb/}CNJ3@`~tf ?2_+98.)(ROcmh/BO>?uL+ndΪ }`'~x}O@?ˆ҄8sv`:QDžQ+QtrL}1~>Q![_?q!wI1ԃ>+|fn%ˆٛXHF)#e ӁIE%іXGnn+E'h#1I|Xhˁ"9H$ &dp/8H? UUc4cV~3>6&DC# k|zؗ$̲!Keĉ~O7_2~-L-e G~wޞ0K(0퓸w5YAdw(ZH~KUPegUUdG''gNNH#s`X@q |g+ꏆGl/P C,"7^=H/jbngխ0M>pLƚ49۩{l^&G4;[mSQ[Y\*3dvzMƵ NをruKO(HfATL2 CVI؊.ݴ3DHBo22 5\`MFqpnۃj`yfwEH$+mdi)63OWg;lFQoEu 2:Jsr!BGq# .wUEZV֊sq 'Z(!S E F_GL[-K.J>ө 4 W R$ GĎ?Q¬ ϴ*-<%Tgf  \≉q$°tmJ`hABpx7b0F]%xD9o>B$ĶE.&Gy<h ;3LN^ƈ}mC$U@ZcqC&r@~|]!%h`GBe+(HbH-!jE\s$KEtd4/8ukqiهC Pzzz"6RUxh1] ً|g9:]1젫.]522rgKwf^6bx}?b>sq2Zi0fL䴫NxǤO@n.+ &ͮQ(ٹyx&OqA3% 5aVԴZ:=H%It˓cybMpRW8D^( B}3oB [[fX{FW]|?}3`bi9yΟP~9+i)(h$dEi7g9g- KE& 9-/ٟBدUPKwCfTˣ!lyԶGo[_w\ePPddA0/KSCYa6{-/@s"Rbΐ`(9;Lq÷:C n{::5mpWKW}/Mn@DLD*3%?PvVA1T[~.)/Al-5e 0%kc Mכ S- X/)f#0rmNZZDA։,lx-C.u`L7'Hi?cmJe옲MB/gVbB>BZ 3H6c$&c^4422B1rOf^BiHcNu8+ETS]h:["`qqC=013Qy}Qyxbzz¹QKsz}~v[L "Ghp &c2\[kG".A4+*KRz09ƾ_Jp'cfIjI'K#6kђPǐE5\:z[MU7KT]y%j&NMƘq20hY'X KcCt*bn:҃aNtט R~(رAY8HmGr1CX'r?`H[.9uqk`BjҰ j%訖"QtV%9)oP5 $p464DCr /,"X9 f` YaY< V>Lx(:) t"pc:`}Mi6L2Um9=VלSů4^vPv7!*hbx̃UR_ {QeIM O*?|XlL888 GpIp"z]lrJQ}㨖0GIpI96Z ̪ajiqSN "oA_j nVˤBC Z} nbXw^>l\Ƕˆ^BkVCBO+pn}%'a+58U@Q8RJow&;KQ'o2Ɇeyߨ!{zKZG@5oKVyݾ5f۸zRSÔ=?P}.“獷p(lzq"?=kB tf,+ʛrԖ5@+. 9D$5ɢr`B CU2<,ҒiE!" =4 [Sz?nPMY Gd7lYJ%IKTd,YK~/(* ~]^qu}q2B&sƃ`1I@ 8"گ'HeZ#_HrSgڟq4Tی!BkJEI9l/5:gHFSwZٸ8Bg?yPELvnO{X3a5Bn>+JNx@alc)f_M$P+KUvZ|VthN]Φ1gH3؋&*qԋ:Yh20ՒpK#"m#)FS#Z )E$x=?td$P|g׊ZSϭ r;`DE%E5Mq(IH)Ktp9NhZ^N]*%`˰Sr;*PLz.5vV9(>pCڗTvl>?ΣsqşxpL2;E 6kT%$dTM7OբI[ieb'G8yVhZQOZYWP6&77, ^k=vG{uuro&$HxYz/4g,G2c57ϜY)fUY|/ H1pWO+:f`"x)4A󁔦G4RC-aSz{lHow_ԄGF\y0AR>[w␌ڱD4ǦRsʰE H.u-#Gb1R5 "rW,K-mU:nⰇ0?#l%Ĉwx(|=*r!u:d7r6*U;|cߖKBL:$ppMcƟūg䪪'#(3?ቢU8tUFX[T ;$ޤU,6CLehNj68syXb#sJbAkWy&$Z^ˆ(Z>H+dpCᨳ 倏Eɘ&iL-GiѦ,57n?M65 Iv3!Ύ]ځ®=egvT'7&뿇tֽ?Au۠I{Ѕ~'y'sCkn J<}4Wdj M:<2IGOk29Eȉ} #uɽ~aAqp+٥۶n܄3 kF3۬|_K"JaȲkt0r D&aL6"2?E'#@! cZ!u>4 ;1J F @cp1 s5 V|96(2dPWǔq>&ہ$s>?4uR>=|XxpJ8k/JH<zDH,3I.(TaN?̞GmttRnb7U3{sf?wspS)Ÿtrj%fuTg8miqrϖ42\UUErprϑZq;jR9!M%>H݆iF}z~Ua +.?bU5Nxm4Iԝ0yϊA tr 1Tq= [+kd%[,H \NȠ@$m 1;w4,z# '*gONXh}X"}BBAƧws1yqZ;pex9i|jN7s,+-VvAݲCM9u-ȑ{_ U08;r8,FaDf#eP L|=`=.nY,kktDd& Dd-|Wx,U,ecf/3W%Tn/{à7ǼeMxLAH6B%ID$!u1\FaOwfqNX33 łXQdg=ORX"&ϛ3K̔yZ=EwRw_|mC7) Xq=clyrDɬVTCf[E]!")^fKV}[St-㎐02:cV݆M ԵXڭ Yg\ үkŸF z U0^f}4o 5'(I\}=+Ζi)@|/`9ux ="b7L~ȿ)(DNI6;& yFd xZ>zt閗b9?,`kXcb`gGV/ᄍ\qbe$E0qcg7H]x%!b%]xЪ67]pAҏVa搧aN`EGkaqSF6F :dmŖ)5e2nƊK.I37Q'<#cy1yXljҶ!vBk"9U-aܒ_vwj=r$]uK_0"3o8A~ocmճ}6%;EE%<\Gơa)Gég x"yJs+Bfb!ijWl)׽͢\9`\%Gl,O!g!AȝU{xL[y׎!ngw!|wܾx*.8؊?u)/4rcO812|sB:[ŻfR͎rh,TĮqR:ɝsTQ恱o&ķ,gs (U"p+${:z(T+9RMz(!Q:;VfkAcQI*4js c EVWhREh;=?! t,FhwI.BZDE͡A$hct4U>tbh_q'E;ߞT;` # P y,&_^Tn61 윃ߡ ˀu+rS}Jp聹XbZ%wְg>\րZ/[Wv֏ w4*XT ̧àO9ruXE w}C}GnDqg]ڂWoEvk/|̼دnAOǏ-s,rϽ]>lRKIjBnPl@ٽݼGzIKk&ue6e۶m۶m۶e۶m{>q5#bȬ̊5GAY!^YC%GCڪEPkC(7ofc9H!/=zGɪ''zKl^YѬfZ[M̀kӍ3y(欦n,8n].^D_&hƸ ;˦ӄ3yܨ̸͍+ܷb [)gi]tM}{렷> cל2|ꋗxֆb5eO3*v{kܢƅA%j[Cħ4\g3MڛDy+=baho_^')B%r榞%@ur})A_K! xsٜ¯~nѢtP0vd|So|ܴKs X'6|[ROEG UIi# .;Þ ]>Ie/LL1\o9#Ӽ26&ڟtq7$^mgN XS2~eKE4>_{Ï̭eLRSe9,ubRSoJڥdkԼ\y#jx빖,K?f:3L&'Zta&@w5ڳ5V)b EgJ39pƟ$e>@_Lǹ7vufЍYf6$R7 Dž*On  Ǥt/Wt#3O967u}+?.unYt]jfihMB{\%(k:Ǥ徥K3k d"]҈B/PlϠ+{Ov!x-m[H~r;KM+pV@{U7FvhU"#iV_u ٕ]2\=!=/\Cok  W[T5P߿PUI1k;=˩ `ћ=tusi =r\z> ,)4zqFmEAzsJ:WZW%d2`6h Y_RE*5(3u=++wx+ NOdAN`gz"38wb+< US@N_zBhr vokp/|Z6ۛE³];x 2g} >asQ(ЕԹA%tI\[ĩC2+U~xrXEN7]Y_R4?fڪhϘ]7Nl5 >l}|!OUz;2DɄKqFUUsro֕<AS u|V oQ]yra{(B\-F|aQoGG'")`,)1JILVTم/ė!{:.#7 Kl9cLA1wshMq$j~}Óq!ڍ3񃻓MFSyJZ[:l7b;+K7nda\(ZJk`FwR;ܩ2˯?nU;m |6M Z)o}eY& ߑvY/uPLۀ)#Z$v?hDZG(J,-EfKݪ=A*l!*c3VNhma?zt wYA{x -s]ˑA$z97h(zEӁ *V(~n)Q#1/0@" 6ap%8mHrSgdE $ILJ0`2S6[th i](Ay.h .HHH^9{TjUpY.U r !XsڰGVrxS`X `H`Eg,[2mdZ#5+VZB'Q52dJ2sh9^An |씰j^p!F c:aT(TJp$8›cg]geggy9>Pnweɞ];yպ0w6:TObzAml|j{Wƭ*&)rjDAg/y,8@g~9EHM*]q0.:\+I C :rhǙA9/e&E [B!WFH$&!%&_JS(;O2kFXBFl9TTpmsՎ^ i1Avc_GSӺU֎gE[fn uF([E?ggK . [E0O`y`f)F,D׭H^PƼ&t꩞qd*J@Ds4^]7h1mҿ \VxF߫R:kh*P[5  V|h CHѩ(n΍#OgGx5^M  81r|_n$\d?gtB@CQOEp"r7JwTr2o ËmiuU6*Y`O zI}}Jj'7yn8/E  =+3˳c|5*31+3OsV` 9;9S?ۭn}w>Ϝ^$ IHcAa'D+`\*a*HКz oPU*̺faR[|ϟgtܦ&SGTر 莨,=ߧtDiQ^pBR`Ш)>MkSD,ʆ#fbf1`l#$A%SVZN :B]{ԙj2нWfhžC?M\'%}A6o'lm\d(BgTCw~D1ȱQ˦niLTZqGN!">iOwOQ| >AqmK7v.'`S~}AgOp}Έ~XgTe s]'8r5>|%Z~؞:x_81aɟ7B>x=Ol?Dm>)X.\o׃`0<>I_(ls8G@xOTǡBRE 5ZOZW!JK1M¶>yܱ܃ZJje;BglzȵR%x=gMofJr#~{cfp=~bJ̠?,39cGwcw[6Q-09rf~e1wC~ʶomh飮|ynA#,xz)p&=#|O$j9q^w!<]=$sN~ By_7FUxP֛c|8!ƂzDwB(k/җWnvFVRخRR۶݁ƚS.7D߅dE"7c 5(YA%nk$ Z8%'WPW,#LCIJdW`:TNֲ s6Q_F?1m9g&t.ff7F`~MĆц O4YlzIt`5 ~5hύ{5`N do;~Džnuz/tM7 ,+K$T?RLCWkjˮ3Exd|6 )Tal?(|C:v4XāED[7zh 5mKXSirMi"$S銛XYGX`B KE,QTF$KT]鶧d ]?ӓ4ѓ3ϚO.hSv#<1RC|*N}QVb`Xof$>h3W"~-VWI ^iC)U,U`H5m~>GֶHH`c/}}fyu5ͽ:BIvE8_lF|*`6xcE?¨lԔ6s\|*<6ٕSr3=snŕCHG.Gc(Ҿ}~c n|DIUˮckM -nJr8-p#&7f>+MVKEaTBXA#%5~AiX#5 4j@~Cݩ7~ &lf7VV@Bf7ikbd\܃Z*§<6hlk^sʺqく (ho"$hg2r:*Dž0!+9'nt;ػҴs>:!MG2b{Ǩ3-Ѝs xj5F5']jc؈^n>KD{H}i:Vo<ݬX^g_1Z'ky GHh6^yMr?A^uvfOO!I2GRT ^艴l"L <*poU;wBYDwrRnF|*q6S;=lI>8r_ ִt5e˹7@FQUWz豍ggnaw@O=\ť׎ۮ7(/oK:MQkBa,E8ۻ'R%j6˼?ȼ>{Nf3ԢA'q?MIU1v@5M-@ζvT0Qv苼UuW0ul0s %om҅ -9a(>{%h*0^ `e>}f%XYB ?aZ3Rr P <25'"Xfe@KGvu? S 7+H\RրC@g%TEWY$]_#t mU ;z㶞&Om;}Pt] &an5Z1!y&&yé(@Pd^A\uh=Z<<&=U٩| _I}TǷcHȷs{+\ N 339k.@_т6Z(v~euN]Dg=zo<yNSyX8e_VUoL~Mmv\,L.iCC~~ZIVT8eXׁY7 ie/W~v{U掝ݹt6>˻+NP5aBҶ#eG~̪w,!Cv  8ƈ# QVŪ7{K\6t<{*W +݄./[՚KR<~hbUqڡ ɁtA.Bt81i{jQhY'v˫+Lf>cV5/wPszܘ >. Ka5Q=/Cޕ"<}d ?H(6.9a'nmkj⟑& O]iCe M:yβC^^] k/Fa8Oɢ\90BL9%7K(,ǾNwE&%&/Ť|~3u:Z aokGKZ1g~Om~"G"g(Eq7WS}e x#[?GEg"!8 s+]-t*XX,ahGSQ66S,jq1U4F8 V[_-ԊJh4)*iv3Sy'xPl^l):gwNE} B%$䌽L$Dxl>"IP| ;oS)Ԡq%W6VX[VqYkF(0MK+IUˋ3Q+=>X&&On9m,l iz琜]HpN_F!JǛ .Dm> ~|zոXWi66Nw AgQ]mwgNш=@(Y0T-[H%Tn=%ǐX[qoc!X@K®;(բJܥak&x[!Е!3AB𣺹$<.YlЫ~v+D`\+nDgB^F\V׎:/ h3P 75Uqht`{$:pmƋWSj˦dI> \E2z;Q%|2R~ʜ*zƵsgE(ŐWٲCv@'nY.蹠6V{$n ?- ˇ?a"%;@D6U>\Oqt ڃ}K6;uzśKK{|G.f:Q-`/h7(|ͻY{ZvȔh\ q-ogOwhpbX_#rC'Ժ`k/"V; ꢄAN{Ҏ6}Ího1͗壄^a#,6R&.'#k(/Sz ArasiDHuI{oÎmB٦dF P${2`qN fu׹`ŋumA =|U¢)mZb@ZOo\KB-ƙ!OeY=[M$};< X/kgcG~ʾ+Q?D!!^ijG}=NVXg aU]_\B(@ǹqrW]me]qP [N7ߩZ. xZ][",K(_eض;g ~6"ޏ1lt(8.،?228~ZZh&+ďPg/wU0Ạ@J9gOş鸘/Dbƺ gmu&WXjt"f&s [3MIzy Rէhab#X{x;!ŎjiZDךot-ZY#_XV:f/[;v!p ' N[[5E4J(z {P|?`5qd'u~]},S'$:F RT;o&cɁ(.Wr ]Fb*.V}RK\4x0bH WE3J9(U )Bdݗ\ė8fp9ulq%޲b j#Εu {#^1&֗h[ CW7+K7ʤO96(Jw=4M˽YLTmb4[4e^^Ѐ# eH+u .dU{ژ6t)Bmҽ/i{/u,IR 1[Ȏ$ۺ[6'vzGD&xMf:l[yyhdsa!0++~ 9qt1:ff\^DUI ˆI˖M.{e^챧)mU6uBGwEwxh%3%^ŧPcs@zQb iР W$**.Z!2}~I/TaC=W-&f>*T9I7Fdx|__gGG@MR~)itIhsUq@ тZ:EA瞳ٶj1]O6'!'ZWmOy87'kAJG1ha7osM SQ+<4{AOˀ ܳgkԉ5SX5l:pnzoF c1h7|]] 3g |#)S69Zie[l3&{v+yra…SWpd_=w6myBb4nY,&:ˎ\Xe $y f\\?C'[<>acKJBQyvWDc!WsrO ?y|a֕Nk{yr<2 ;u4TZ̺PS$5|tz"Y Q)fPeUjsRa5ˏj baQ=Gmr#ƶᬞK鉅^X5U..ۚF\dn0xx5zIe% ?p끵_b(Nsc5i;MqB>1"\On\-ۺ7cߌ{W@10 Kt{<˙s?xz BƱ0͙+r-f$R S\g/ϵ?;(<2~O[ݫVB^Úvu\ĕ"?߀)sJ{NŽ;7ld Rjt޴r%hu7lb O ~ }O @B+j^qn93h%X^˭I[m}Q5DtdJ[HIKYVlgo#zb+YB[U7;d"EysD~H.wacːx&zZY6]'jٔqᚷn;>jZ @{[+ wQ}@@Ⴤ)3 |A .]g?Fwh^2 _]<"&y[5DT{ 1WgxX֬3`cM`8S4_Q<9*gfF&LNi'p԰tww@iK!T|d[Jwutv3no;*+o=kTv[mof:MThu(+W8-mQ셷6{Ko;/ʺ]>:^~ o`Ѝ^.\g䫳TMSc XJ79g(lk;ҮxUo'/tv` MPsRKuRYlzJlDAѦ;YO!?zdLFBKZVvvOZMw -Xu:`?Z==c:~q,R֋CHz}H|kɚ`$J*$ڌ G4”T k"xӕ1P!@xdyuM&90\5_x8߁c잮˾iW;/ڏ7-aU_h.d`+8s.yg#67 <;/|xҨqr>ᶪ!CdIʏ&+%nzm9B.w4}YTôkaL[T^ڟt*I9/^8o-]P7T1ppPC,8onAE#vZؿA%ܢ&ܼdu?iu*e,ܾ X;ӷvUiأR"z%iA?j$@gJavh){ DN8G84WY aP(Ԧ//B 8&" Q%P "F\NCƊN痚B`TA0!`咠ټR9oY-zŝ4}D6qHfyOM%%b#SEM]wfzF]wGJ [ ^ܜwBd ¨@D(ڱej@<0_QN\hno5vyPk|k"k3S9cD׿cbͩzkàjX:׸@Y?N&-R_5m'iʼɪO 2}\猻K -ޅt$wCg6k6d'rFLA-ڲXn̆ R,@sz}듓>'6Da:'8taM9_yN浾9tЁs}R+󘵉4*W ]S1m*|z=d}#s6^̘D>U{iNVms v.2'r 5j> cQ`R8+ X|b ^] E&mqnWSJUDF$2|P eiZ5ta;tP3x=kFf}t=zGAbߕhgwk,mgVC5cd݄F b5NHΙ k[ 约]bHn6kq|khoR&;_* &*E]`W[w#MHg߱lाh Zy- SBh[GO ~n,*%g)89l yZu85}@yǪ5նpYjՃnnomYR1jzv.v#simvn:e:@cJA@ikm|6dy!s.C"Iʼȷ9$twýIRq%qlj~ãOa_NU*G4= /%Æ+}^OgD4TeDsr*"wpGUzm:V2[sZcׅ-K&wRWBGO| -'Vt#,lEدY9,&˲o}%Uw9dFZtt #GminGʻbWP3tsxgS &xJw`cu lmCf46h LKI `%s![zk7lw =2b-@į,NɍsS7n3sCmhLJa*ANF՜:֩gW^՗A؄s ~7oqS+ { OFTx>⹌ x.p c‰@R>ɒij!%yOO\)dފ1&k<žYe-W˙{u4Eewk!.]Iθt#l[MijHd-E|J) $QnPEU˨K*E ic7U'j`n%5kO}RXv7SըI0)E,}S :':!mN q*o ۂےݖ۪ fߘ1X)t{U?aDo%Vni 4a܋M룯YS#! Xz"Rv<y CПbڅ +kTqwQ8Z#'IaUT@-Z#oDžP)ǀP? pm8csV(Q\Ap Vz>tV&XIbP+nS+%, M>; {}m\HMP]pk<@"۠B<ùp%jb ,+Or eTH`N'Z"|GI)K.@%@B+l,uT4aXxmQ$ptN @?;@bZ+h"L%6A 5HE鏮a_Pͺ5Q;;cn_^+Yis9<5O)_Y^XVĄ2?'Z\ ۤb "4VϝTVw,J.%l ?,dGz[76{:KJ}/;tyŤm 4hC9=-G{<35GWog$xɘŴ"==94%6@ Kօ c6nC*73s_P嫼L0řS}f$ oFUSwV(7!MB]uD@zp!~)͝ļOָC7ggsl#pوC"1+8UVJFލw 8m87Vև#1d_0Wb Hqt[.y"k>7 hSmw'(eDQB1b4"lo2D\O(R t2c)Բ\m#]Z].,Umc^*f?'\ς8ﳤnA>6,ڂ+$hWqƱmL՝Ջ 5:zNmCNr ܰܰزfy)Dir7'O{~77JJW4r)r;Cif>t?n~t4O Ov蛏~5Sqm(g$Ӊtѵ `M+.xlMLV2j[zzj_їJ N`f6aJHD7_į"ʈ>=9ava2 ȃ(*giyğ| 9_~hw0CV<3H`*_x/րsWi;'[SZrdVfE]>p_AЙ@~r)<ؼʩF#U԰؍8KM݅KWZ%AP0 3?BkW}@Nz Bٷ.9Ą{2qſτ06-z T;5QuC,+ψd.YMw |^ ۰_}msulbo`UGuwqoX>!~Joa"c'[ad}a[6bD$⫒̅ %z^*0e&=| {U1NO7'Ǐۜl|,]Uq䌆td? Z3Z}S7?ߟq3nMQ9WudW4>V@|E@g?mjWD4%! sKuC2}h8(GX"MVePj=9?*"y "6ZڜۅP5F@t`p_wR tjj;/'bi{INHno$djP~li\ݠ* !54BIe'|pD%;O- G:;Ĕ@:7֢)˂>՗zQ$O!7W80#w_j`r>P{ ~>@O`f8r.n7^ɁW8Zdob9]|]EN, K_|3W|3m>[,j^m M}]wdK^hA<ע.u`GsA:)Aod;]g97!12pۑ?V{NS}Tt5i xå[0FMCc#yWPR4ݐW27f%4 ~E&aa/fӕӝ\mRgjoI Ýd5tZs8td6"d62{b+\̢ d,dz @U2 AR汭&G+? PX(Қ3 d6rO_v %72#YW?9dE񿈢ylx_ucǿH9jdNr V6 P 5sYSvS)C_`bK[F }Bd_9lGC?< |N3|pjQ{]~ΠIlgӦĈfa7P"UiΜ(#<|FY{I`Sr]dߔt^P tObt8#gTzV EC`P9J|!9} _3%oA0(gDyDY~ WR4 GSoBBQ_c"Iҙ,:1O2ѦObJXKXsq'E\,8na&=)s&ݻ=?&2<<(cO`Em*e ,. w3@gC/+vZ3A5zu6S|^K4S:Q4ibcδn˫Vn/ڵ[|eS~P7ˍkċjwÖT,8.4M;4.qeo/)F6g!^G>=)v5),lDQ6J|,C~l*T\f,lM?(2^=./..%qV-3#Q O mȥ6Ӿ9Ѣz S|..%K$sSsP҅7e)gSkv=bF#3:ey7ba`!Wz1S_s^s17|a{E |y}ܖa%yxJ_,^U)d;ܖHR؈oU ւŨۼ j$ӢMBשܤS3GhkҦf)ͨ W.٢)-'`UI(M VFBsjs/Yi%咾Ptg{)ᱺP&fY2)d3ij:oYQgEԗOśvkfgeY[ZnL":nVӈťά1QoǪdK8yn]VY]GO믙Յ/kVyO#e jaH}V'zo*Kփ.Яpڱ3Y-mJ GѐOXHڿsM3¡3|ey˼^7һNA>G>>y^卅8:X%' D@JYB`B! qVQ񐕬Gxb%cX_wY_ VC1 ` mBE`&Qcz!R JݱCKb4BC̱2,fقue˥:r QPѶ9Q@ T\&LD"E Vcլ##$~═Ǖ+ҤtfR#WO5ǯKR2V$/Mͫ3/RRLoH+$)W*q崐CkIb-:>ߊ2끢m.i:ɦb8JjWU;"BAbsϠs7u=C(8rrttB}b;<t.s:,jfN4Z%M)Sܭvrbv/G27V猚^+Vuklqb_mu;m߷ցSpX4V>f^k}S?߯smJa5,SUOĶ}ZY.<~c\m`[Muu [=9N YCb^3/wg|=m=lb_mLZ8Z`:b93sD,P*|OzFXhōܭ[ſv4eq{@$ch|S(+ dEɖ0F`.0T?Wam]R D4рnU=+L9THRIQ*g]K4kz(] vU-9ԗ]p:ݷ $>{ Hgv$c^۞o6]+7Iq_YYqߞLF z\&}/v#zP2srd?O4Հ @.8&~-[ y)௧az;kר# />}Kn-Π=mVh8\\'Gu  3Ž 2jAIo?&.  RB ?!H8bĿ9Q/\@Ca"0 Cps`$ei2"gX" /?*Rz3qD TW5A[)/g*Ah ߜ,FL]<+暉~ZNꚉ.Zx=+?Ux_d F x@J'G[d_@\\O#ia4S+Z!m*ol0T=C1 2 ޥM T(ƍoܥ-ͭͭm ]%]kוzIvңdGnf՚/ȦʼnNf O{Z87ڱk4L chJzoy;KȄ'xS3)RWi;P?fL |Vyc='D1Ry3zqbV[[˗'݊)t_3 Gi-2e0J;p75D{aӜ(Hx0mdF6 =:p>#rR~ #݀^c!>۷~Rw%bj6#yꤐcE؞{ UAB_j"gzq{IRdXeugOE]D>(n~7!< LVn!yDPу@Oz}}+z u r˫9}Uywͫ1{x{)(W&*'aji9k1)|4KUu &%%F^$̓jXU8([OƎAyղK sB):H3\2H?Jr{B4nK%rKf6"[ *$,Y,%ՋpVMȌŬbT;~pRau0۝g+X䩑,X3c~a~Gl:ty*/R'n0ff]S-e~΁oE#p03cCr-Y_ŸťuCnpVʰ Jc=W Smۡy&7]eLǯ⇍[ǻx6UfSm  ގq% IhN(^-=YhKaNZ#M@)a2^9ܜHUHy QBajjsJ3Piݠ R4-_V":һTRYoQn1ʖfQ E)U۫|4+m'L czSA=t9_VcGʿDos#.g| dd𝿗4)NALHʕ[.=_Co f6dbDfXbw; ;n6FeόX}?W/gggiLLg,ln1-?JERYŁPX [y-mKiD 0)x@b>a<^:1$IP A~OFj9@vf FBKkWS/Y,nmDhh+wn Kp}/!+WOWl8Elg(ͭvp?7Ҽ< z(iT3 ppőo3)h[\;>qhz[5}"q> P@36e=,_خI+>/ߕ7!hyn]!"{˭tkQ'C1r]fyy^WXohTsk˔O1f"pBoN} Yл//W/u[DT|\;;<._{oM} 0#qkhθ@>bgE @T1q~Cdځtȯ{5o0|}'(&[NUA[tH kYo_coR~x'@Kс2gpSo@{^@h\ukMwQi-bx{xAzF1 ̦ƍ2J52N,zǻ2iiNCZؒ /RpMLA={Gz&~.76on-E5JW "v :(kcV|`par^ Vnsy Oks?(vF|1永GG*\܃5{CgOx`»2t#yMY.9|kt "ue_K//ʇ,34AQ1<ǟSfYvƈ _4π'(o!I X4Dlc8k&ZHWkb2ո1,۽ԝyștZ%˜ #V {<܎s[(Z|/)%ZS8W7$gh(Q+ أS8߶uŦ>YJwFuyatiڶ<ܩig#wp`[ pX.I\'*wQvЂr,nv6:ty0s#,AȘ<Λ7yuNM3hTm6{'s-Xqǫ ó*lKKSlҘֿg>1Dik rtvW5phUlP.1%dOJ*rs+ 1mUbz#5c;.lBx!r0 FCm8i(͋$tnJuI߈+9 i `hO xbPwC77 = {^)ڑ],D(x<xOlh}y!h)=%JBN5Bdb0507*5<-|FʀB/hzB^y l5}m)saL.ck  @cd>*dfTH!)cctC's]WjbQ;93P5}Q!dcV q9;QJf Q 6phDU#P&m7L;t*c{c*#M<#s& +rf%JzKӒ?+)ޜTvfJo_X- hC ǎ4lujhU'zW;~)O昡NVAs(k[b8TeLФx'd{zf 4+oO'+fոc uu {z=Ƚmv5)QC4?Q x91DEPb>&T ؑ ZdD2-h9np,#hapt˘tiIx8J Jj T@}%Ĥ)k(Uo_yH nqYo {4R<YJ/o,S\*D?W7]vEPI<{mtP@{ao~~sדu.dy }l%Ġk&:ecD{Dh>0f{Ck"cA+djR[ãSU}s˵ UbYSY#LaaS?OUYZTVh R:st7d$])M.V_m7Et\S]l }7}u6 ;*"x=s+}$%64R}=ۜk{wwp?n:kٮ1ם[]=7efp)"~M_Ecʢ[<+`Œ@z()t()E-I3Q987\ՍZ6)3_Pr9s y3Oճh(p]Gd#֥Lk^0?x,W/Nӭ$|ox̒Or@\[3›U5*ùW=K\y.,KX*'#'S*{ LPc{ΖIbcϵc3t2&%ܑOW\^2vп~C!gܐ:ь{q}2r\=zQ"U6&ytjfQO04&fN>Գ//]sfҳEHCs$wޘ"ed;4fv'GЬ0'1GTdf%#i@!VdBx eE@N.mdM PM15@c;(#JAcVBg}~F#[U7^Bg~0UUS=r÷8)Y5{Y_<;Tw#QB:h>Gj"{ڎ#H I5!@ܨkp"I8',lݱiP-YssO'#R6+5`0(gj7Z(U[Q̮a_A/ 8U\Ywӕ ̤))ϐ4I TyNkqN ͚9iC򩗟^e) (8=w_AFB3`r`0 JK ToakzgN\7+KDZ ou](iϥ$ge^"){xq>!E5C¾ e~hQ ;p'!KQPBRRlNFE0Ilcfz xKiD ׿_ebI~ ܅@$}]^/ĂA L M Y ꑏՍo긕Oݡ`wJJѓȢe '._92 "j"0-?@i5:dTZ'+kQ~wt'[M8~Sj/|ÍM/tx1 {>WݳXk5 > gp"Y|G FC;_v\ٰl]w }rJmX/ C %TRhǏٻi*7^I`tuVѤTi5]H4VLhbe\-x۶m۶m۶m۶m۶m|ݙ=٤+ݕST]_zqѴر l|J 7 ^dNkDLj \Ј03@S?Z 5WHPОCcNE4֨MMq# fJ(Ј*ҊUf :L_گAr-[&[[fg C+ p28ltwД8X'Y|N[T({0 Lqi)!t/6Ya[& jvU<L(lm@zdP o7JI+d}װߤC\I宺/ѽJuVIF]O*7K[,Ε\*Dgן#aVW2PDjّFjPWJgC~6h]S7lYh9HɊhltnY8%HQh)-2}$?X~c8dey0&ge3W ,VU-U(CkV٠Z0{Yϩ0o& O Z 1 O kCEԯ C$t۳_'}Yٗ;Ys|h{&rމㄙ9~,įR8YU#|||SqO@k$#sEMܨx fB'} *E?} })j$])yCBd‹WKHE\La93}[fU>nLO\a: 0Vm[_)6ըIY71S?#I @U `~?OG3JF HŒ'0hŲg20Ȱ4mpb9H2cib{*¼v3f  [!&䉧TpX,4kyM=Z1mn5ѿRgvݟIxƴ!_=΅k|sJ½sX qp8V2G"aC[4 |>GہB;$yNrAI 僑>PP瘂HP􊔽@bv8`Ǯ`Ss´q/m+;ڌr)61Y>DmE&t fgY*1+pQZfCLGqr@v_cCfCY|w@h}K{#\pϕtCtw+?f f[.(I.BRpy%JLbN'[hL2drgh JW?h Th]-6HVMVMjeb楡{gMȖ޴vоu!nL*YoVOFƏVEJ#Mi$h\ Ht5)]YQhk82h Ҥr⢏vsj:%UÚ*Low'@Z|@.Yx$~u@zb Zpw/)PU/k T0̣XH*ʁߴ3ktF᧠PsW,e1v8BӰ SQ8Kd,Ώw< VPUԪu~G [ҹ0B/ ]>t%=RJc#D܅tKx7Fj֑}y|В,ٵ1źbs8+Ii+Wc}4 ¢Q82S/ ęZl"b೾Nu!d XlzN&7kT\H6*dX*2"57qt(i+ɱ[w"};U{s ).񯭠rdG̕'pFN-N.2@0-{Kať o45w"&8W $HC.|(dmtѦ$ eA s*hH1BI!/M\"7K7%ӓqԩdT6N&A5ךԪ/a4c1A6֙~%;mIq!19C A®'it$HXNlt#\9iP{FQ8'aV}9=)TT?YeKFMgod+\v ε/јp2guž pUWi?`6ׄwhTwHp$xp9qCwa9P})!& QP+V$DŽ5D@ Y$}sE=4E(E߇4; ^lWD /ǥHvʡlCQ=5p:y!yl ^ : \ҹU [f̱`ԭ\&F^K D#eM8$8oZ$ p%a Mf7NRtVQ".sWE5KŸPpYJ]!nny6ji.Fiv N$f_p[Yj h`O_Y+pa+"ϰ*&%Zſ)Icܿ a°BZ %X`#@v3ߔ"GuBk} |m.~bq_sp8Sq4E".“t.1FM0 bD+jMbڲ&\4Bn0SdHK:t'<9be7J2 W5F*1],ho‡J6<޶Jjƨ^Ǔ=FBx7$q7POx 9дN};φE,q]{EIx=u< xn51 bҴh9N5qǞDV+kps G J_6{^z/\kZ}7ϫ3":zU6/1L;GD"`#y?me<4EGr̈́=5ԯZ\{nRi^RG>%Kߔ Sȓ _=LL ҷC?iFF A`1y cX 2} jg+_uȆ-כcU^ǙK5jĒ/k ,TSY^ͪ9t}SFf`jQL.r4S3WYKDI(JE"lQ5IQ:<57Mق>^۲V^ L5]9D>`|jF)}9F^MƩn;)E^]򂥜lWX/~-W{~㥌~)R`Y5ؿ[\IfR dC -Show)T{Ńz>i,*Bqk%*2W@9 ݯȞs`~Di]ꬒBQV7 rCyebOWhUSnߟɏvď_9?HwnJhyK1r\F*Y2џ7ҷp ~.ͼ~ Ǔ͈ij4e{ {$ͮgK VዺTL\T@7k%Pvhե`mwAI]UUIHUH3 ߁Oݖ[Gɏ8t:DMwO¡oTkbB+ j}ѯi 9uRYI)FP7T߉,Dop]*~tT֎ T:̋:/IK$T:^m $t!:-C"U,/$ '5!+ŵ{$&x9ל۪@7t9 5ئĔTνo(ْQ/R;J*Y7+] ; 8{+!f6Q9]ߘ- 8S߄{o%\U$SSV2 $-qJ3q o ~&$!Vt~V4.eQzgrV^q[\#k R: \"q7N G0cd.-)*TUhr5rV)"BCq]zL T,=NRqK :O4F.:čn*;HIUSzYY٪:Ksr'\Eԃntrp ;BAS]a*A[7a;d7Bo"{T ̗)MV,nJ!m-mlrM^a%k|+Iӻ6q˝qK~TU>Ln%yQz;"֣޳1 ({\'Wz9vSq*6h=_NX~*8D V7eǺQVsjVd>1L?2 +4 =ҡ8)k eTDQ52 zodQrz$-1&ƫ:C(;X/Ān,蒯*¡Iߠ2<𞳔TT= Wpp% Ă$90#Y桻G b@N08* BQC.:ckvG⦪ 'a~q% 3Cr@WMN)p\S'8֛ѷ`Caw\t"#^^yA/B@&-b_^\PJY,ihBv_^N9Žyx!?J&%.p 8qQ@?&SlM&Kͺh/1zL5<ü#EL} 3TvOYj{݁(lubI'j9ҭr&~U+'U*L&Vٻ-t'Vّ҃Cʙ}R_=; \횳s4LX}fSk|wʹzXyMg/DAy =^ҙ_#">4>_ZsgVzzB}OZCy@Zԏ k^Tj 4Fe2v94/˶"d]F8zi[v5v߄b,s[, m07sĻN&e}^m?_T7g];g[U?qӲ7O7LO=;ϲwj?=8_ɱo>w(uiؗHF+ڀ*896mG*'5Gyi|GvըU8u - aC5쉮yXi5ص{G[6("K_;7ra1~d43ܗm*}m[ [SYS % Z!y4Mڱm,ٴ:i6- -Zl r?7_5/4/:43ȯA߼z><՚b ժs"M:.QB8[m4jrS#(kc.m1^.rA5tQaJ!US5"kBľ>>Hmg+J=g+)(]6ee+ ? {ra{=j~䷤C_Eұ[k /O` -ɫ,NoGs \*q,Ew8 >ap+~9iDt#OSLqຸG8wC\ރZznW9WF8 QJmݷAGd aA(%% r"FmA'{^ h?.USYV ChZRw3/!^".<VIEdxGX[l(I>IZ<VH!*iǚ]Df?w^yRTm >.5k e) 3s+cjIA (!Ecщ(@ ̌lSp-ML5+fa/sȌ@΀O5 st\X%=U2w N G}#ǏDG~NH\nY9rʢs YTȲ,r8&$>̍U@~^)_|K :lJ>_I9RM/:;!lU*+,=E@${SUBXc>ymRyZ~N+j¨UyH"z0@[$2 |O0 J6Qş  _*?Alj=u Π?<^^ta4/+哟aD/Df q|.pn 9DX*7c(g6ݽu߼>7Ba;T2R sj `m )Oc ;hv&&|wg_f(L?xX!_E?MP ?mO d03?ll yCYdL[Ymی)c(;F< Sם:p _iҳv*-DiO m.颶Gg% mœ0gwDD50xW N<7!xxw6=)֮d͕DH N\:C,Z]̮]lOC "l#* 4vmFn+trwB mZiA =M:Q. Au[$ O#uK:C/׏j A}&.,N ?hXe݂9}^G 2d)c9w+I{1{q1+zׅy^~m?ÿŠi2#TBu0^yk;ۼ]!fpP>"8kbOls dAq~niq#?2]ywKn(1w"p#cDi=v[_6 ҿjѢ,]ChGTƥ t! |~Pߐыwo9Y^ yVҋ`XijaTG2Ҷ m^V'g'9dCUzd|y{d-봿qj$1_<O0X77OmX7oB 3Hʍ(u$m(`8' -ba/zOtx@/z@om]z>p?ӿΑtGx%rDѺ'n^ًtMo ?Jy bgj/Oę!Z rDS989z;m~wq8`v'.E3/GzK }B ĚCl+\)'iA"}Z#E7o;& L(؅Ge_~p׋y  bްm! FLDϧ 'VH!BkpZ , ##<NO\k{;F͑_hatXNI[93c-JX*cxBS;^rNvEhK?C"aqwp6uY<s8k ˦#~ 1O)z$?I0TN!\y@I*D:2|&)0xmGN'-2A~-:^&C)Н`Q)B\#E~&~袪|WPuNA SHt@2]AK!< W :D/hsvs^nv6Cdf^wf 8}g 2,zh'mdqsK?`Je Xz2E!.9 #g"!y%,ٟRT5`e-j 4$/U^hܶnMa]nך<<.G"3==\SQ-ͼʫ0\oS7mBR˼ ?5&ӾI߷Z\ 6[6\w} fj{4`T~#=HqZ s-SGIk901|@Tv>D_ҢV?-X^0h=f~ 7_fap/[['6KqV~]f^]U 'sP؇ #;Q Uz" CG#2?p(/(+)Xoۯ*jXsN)x[[nOq@rT氵CzcTGoBh w뇤)[:׭lgVW6 V&h:.u4r5y̾ua[6*0 F:?-i%pqk»e7Qa^}z`v,T6P,oVܣY!ߋ+ZX4 bqŠSH(./,U:Z3XJ\?Phtl$BvaDHE|ڱ"T[k{B_6 K@ Έ Go m[(=郤}0WJn׋mbI"?믐-AnG۬9öf'<>BTb9HYdRJ#%$oo@WbSAp"35 ~Ht%@h܆,abF4t)QB\^)tCfJQ Ô#Rsc, K ң;/q( :ɻOV2/_!<>9g0{؛ּ>7s01LAҸ#ox))S.XvEԨBkByMS$d?4G$ q\%9 ʍX{Xy7,YnrjN=Ov\((36m4]}L`9G3PVfkNAg[,pʡ,-[*BExr6N-7V[E-ꭸK>W݇Ĩ#4moe61}##ұ7sZ=_u;)l޺s 2M!Z_r ~*͉xXROJ7W%L*opn =[g s|rb]WXF"wRPe]~eeLqthf *"q S. O2"zIJRcURS5EE;W>˖'^ޱ}޼51%=zM 5}t ǥ$u56Xm+>:cS=ߦ 4;-2P12J3J5O+<Y֣=';*ݒI F\O 5%K=W]eV) m~qI +cJIcQuv."!g$!6J3)+ ׎|$]0Bf_Bi;Mo*Ԩ_k[Q fx.nºU]yԳ=Nn V䤆L/#2p=dI,;:'Ԙv}RI6K(kxfD}}0Rv1QK]Vڮ]F!-,6HU US2:)%<K\#d a)éؾ='9O;g %s) g/guu AVڣ+#,9NV$Iޏ)-LJ~F*+DPAJog UoΡ,&VP./ۮ7XPrMi6*I%ЎO$7߳Ⱥ!ZyNaPr$ZN€vrFq.ESNɯ[{ ,P @巗 H" HbXHP\ _,Y ڿn]YǪT2;'$۾(RSlm?z^=QW qgOT.1*H؎՛c{EkJgoq+0<^Xi¿ s"k0R@g1 bJD).͐.yO1fL#cJ/A`R3ҟ}?U8*Ю\O5ʵiMB)#jXlELAˈ%!Q1k` %n#.)sSzɐEHmm_ͮ}Qieح=U '?M3ji3 oj˛A TiE}7“u"­ճT#+ ;vJ<'·gD? 2@%. qMZXP-> )ߎ_./ce4nB.*o6ʨgd5'reT|R^(SNϑb ^6c ܟ8=6 `[fa\VKHvGN^d94̦ q0)iNimOiqyTA: .t 7Bv_[kCgw厌zX +#C~I:abn`RZl@_w$ܷXX6}YX%~?Iɝ Bf>-V sZQ(\!ǎ+gV#Q#>M\cCmR䲈~mk' xSy?$iPxOJ/8:bG~v .p^ɞDH[cS)vBԺ6݉Zn nYsdvX JR| m.LW7+B| B?}mD\ǿK3mF2Kap_4'5෱aLKQ i ɔd74b?}Z 7>z]1/A-`r'pL56(mC)AS |,2X梙mlX`o"ZNc5q7] vRǯɋ4 O7GKsȔx?UF+ yYv?,+,Ţ?ڻ䙽9S)7T&?7j]]! L) \w)S%)L \e0 YA^f1 P^hTHETEFqG,$TI0'(L@,l>C7P0< b+Z[UQEqPVZ[VPQQgi}@"UK6v?QUg 5rE䌏bVI-:ŭ?`3pW9h?JTZ4~e-x"AzZK(D3>~=߆v̭K{Ό6 N1KX'2ۢ8!Ðojd ʏyˠ wNw1nE/$#9!̷R"e:oOU׆@ƘY!=-)ec(Q~ygܡYi *^ vy<[U!.wWT3dX ջX7k"@&iM {q҇CU1Z9Юgmtt̳ ltL7 ,sX")k6,aoC-2{m'4 lRP12c䅈;[ xAr!PNi218EŗSlVtD"D+EJf/=.|NY(LoP|q`YDC Q!@eĈDQX^!'%$JUB+Ҫ&֚T7fI/@;d ($窉 sZӿzr>ͱRv9IUZ'VuvEJ9[l:2m]_Z.$Aٯ1k.R~5ʔȭMM*E;nY{QOh=KA:(w6}فAXҜ.iKayW 4WM d+dB"nQWd #%;TKw֥XPƚ6)WrV}yq?9dۉ%Fŏ&&45}桺V:;spa ล/H] ⅑䉁.,ρ0}P{@::.4y ,N!9tgjWvt37GCw7k{#U GNutRƅrF@Kr]:i}L[%_ l~Uogڲp6iui෶k(5e6L O`>/>:.@Rk~E5 k} @~_R@똡ipfvqHeFHwM6H9NQ)bc]n]I+Y%?CjomE(/~}3lG8 W~Ve`$ ?xt# 4ZtNZ~4֏goKNֻl#e'#ǔU$5S"ٻʃ??4eu[hT ԦwbDV!jja__ޮ{l'X$ʺsMl  Ym1.7ǣkSW$;]>]ږzT lcVq+(Rʬ)*,SVS~E/(vy;=<<*ڵ+,R[V`f521+XV~rފ+N銪Avy$Þ=h*ւB09D1P} Rԍ.rr*?JhS3USM=WdDz}c ԕ'}]* {J'+|1 g_ WQJȬwaj}E_zٿguwq![T5>S8N#n >I*[y3=1pHMaC&@fc\ă?~!4wQ;9BYzXD9߲G{zb04롸܅ &r9*nթj+Tgeiu0^ cDp|.)6fslEr[XS>yQsR9?]B#ͿQ'Fepd{h Bac#D Bd$ԣAJ@ H9vmT<A)RSfb2ofgn~ߵQh)UOa<:$We~RkDg%E]}WDj qFL!ȭ*0!ك񺗼M'm1gv;_jfɷtЇM5 Z(ppKÌj_ ٮ޾Wjy-.ʠ"njdiCeM0za$ko3ťz(!%ɚӁUOէ>Bq0̛G’V_wZɃtm#t f$tFH@4sv5ڦ~9KB=JB1Ct@0T lzl6IpҀט^F]`x)d?@~h*ӽ1}$XY1RS TT[Y}5ýr]/3FS <=ėhmB0pK4=O@)zHyφW@Ơo7wΕ,SQ d>J3ӈP6'gvbb'g[H Okl/h3rӼ9ܗ O1sĐlV}V%\+G.\|C|֌zg)IJ`Aӑ10RVPxRlJDŽ"48iC{Xmc2jl+}͟[][SʗZک5+ֱ]XkuMDt}jZ$2V_D 9lH>!@6.x` ᐁ~aE7^Q="v|5H9^3l5N8 W]2Ni99^Ĺ؉ bp\`Q9nG5w$̈́X -[\<%/g>'Vnh-ߖ[uEu|$A[Qה&)|f R= C^M*N'VN,܍ٍڍ\CD#ӷ\ؗٗڮJ-t:׮>>?;ƿ`޷Nx;h[=jڏŤx+ {NamZ΃y ,cPrP z[#j%DٵX}BfE%U- hQvC5Vy珖_dh]51`]笜ofi3sh`IAafյ7EFx'%}z,~73-%2ԕ hWKl\V]qDZO@ 7)b}9%eK:+:oANS Z4WnGی6MC=2~B#J'19G-88w>_ďKs/ MYu-%m]$dq)l hC=ɔy / 4O2k X+f*cLJA!%W.[ñ`;w2t9DP3Ww_mBhWqNWb La JQv#Ak||eM//4Q{@01%ivlq;~yTx9T]ZT~:byd)ɣ/;9/ݓY:I/V8H^4RNkEkK $N4XO)wi[0<(c:h\y&:GZI3/O8*K$AcnS՟IcFFV<9r'kfOƚ|HgbMSbdX:Z]oEIRg5 ;2IAڂq-ϿRˤ&A+aNM]&Z tl DT@= 獻"nǞhzR2> >zUtrk%C̃'#m*w׬v8c"M NBw4gKlK _-|QdI/ݣDIw C;dLfa?u7xАxy:+(јb:2M/i*mOՌ`$M4`5 M0;UrK#|%}&(63|\Iҭ0r.0ϧ,Jř #9NyuX3ݠ3i39h3R'VV$H> O>PHgxf0H먝,, !v ƙ G==Nhv|>Rm;D|]GKf#kM\z[<7.ץFϘ֪ +ww4n N*.{MnzD]qfhBwo'lUE]qp65uMyEI' |c{]dyHV8<3x7ΥgGR'hKkfS9 Sssef7:1d0йq.\y7 %ypTJn:`ҝ/ P[PTjWkX 7I߯eϨ[f iw0m;'X\B_\ [0SAN1VmN!yYT%"ɏF|RY{.VxmKXK(AhBZS` D0Pwj(S3V` "hڬjU1k7%/j5t;tVw\w^=;!jWF\b麌>mv;}O'{I~"Jܠ „N ɑ0ruà8 CC_FawWRMom5oǐg*EY~*y-6[l6Ny} } 8Ba+ۖ  TH $(:T9$T#!e1B-\;- :cU 2 P I+<3G+"uX\ Nl5SRiXr޴ +J& mMOPӹQG6!O-}y;~eMe:Rk]]!9Ä/Y;zfF=T+%c\F.KṜUJ%l 0.'E #\XukwKoG]|?~VK_L5WlHVRTȶ4fxШ%̔<*^D_E %N> Pjn,l3l9.)R#}=>-p'ꈇulgfvijWWn!U%XCN 9?t)0pw{r&)T 楷$xRQdd :i rv` p{=߂ sPhAywxL+R-;&<}rT淑7r{.%[Z˽/l}ꟷVfB z&71V~osZeDZ\]{grϑݞvbxzkxI>*PJpئt*-%&M5~brqKE޴8;YS`?U=td-\ߎ=ARZ!MR\d)XW!m,̇_pWyCxRo!?Te%p89-%>~?iQǏͯ. _gź(NP#yf Ě-^&a*RQ8UD00cwNpB`,`3E`3DրX*#g :㏘ڣo(U8o`Y OJ޽D՛h׍Ii@bJ֮hgtҲU 1zx0(4Ӭ- jzgڤ4o_1<~fɊYE)$Ea9lU'bbg+խX7o[{qxdHjJq뤋VV$7Ќ6]\ B :$ϯ U5ڣ.׮3 J.Gccap.z * > پXald *آ^봀^W+b{ʎ9P`d]Zk7*Cs =ꎏלVHh3ą^AD;e28lWK[N8]bZ`w>&L ӻ|mXy9J22e' 1N7A6kw8$- t4Kw H[$uC-fmܓSWX<5HcaP@C.y_=x:TڼfCCtw{j6[m<[K6tvW^/c]ǡb{\QoWiMݷ6:aX_*ᢉ֘ ^`A"N 9Aev&F{_';7IP'R6E^g96Qk&!\v,&õ&ݢ MNbY~~}m^u<_&Q^rǴbDsxW 65:K@ Z$(1s~4Vip:bRsvI2\ftq4u 7NÖ#xh^ ފ>W*JU= W(tZ+"q><=5UT? #$'DJ rʁS@nO 5*/'djhH+ Kcǖ7mAe[u-SpUS7zQO$J9Yg1~N`2 px*t&@A^V55rn؊Uӆ\@QK8`&n\t͹fNsp-ۆk~qgṉW-q<݂Е]e:JRD%`^=co]j-Iuf--?ϮKg~Q!\yFuK^RDn&:umԙ]NcrmߕәoIjPh ~w"js[~ 4~ֶ;}}v@F|T$ ; AZi%d-a7f[ +nuSo(g8]YSʖ.TL#G;iP`ns01vιo @8s" htMn~NT7c4tǝtKsHJ)n;s7G3BiŲR7T$tE2?,hzTc,rϺQ'=!py*]M{ۢE`d!ԇ{2%I - rjˢ^,Q'Ý'ddڔskrY<5ls!o>g2ؖ+RWRiJFk=|?G{9V|.:|ς&KDa0U%)J(zx-׫Mz}I9eU3Wv|V{>T?eEa]1弼Zve\ؑѻ\ݵN^{"#a<@5NlVMhF8Jƪnw]#]G%WDSMۀ5\&08Sjw׫ϝkȚ{N+4tBZx"2qtZAayq@"'\SP]r88j>jo+愯u4/ǜVfsǨ|h 0=AͿWOF77S=oУ气 BD)x}fB7৺l#W3Y~|rt1dQvhpDJ_)RO#9?B{CŠqެw 'Ծ925`=Qj7ƶǍħ;cKC\ཞ?0I۟HYl&/=5T45vG+ 7 f؛b("A,P@ *UJ([ T^vd5Ii9bF(՘I 1~%8képȢZ樬8:!ȥz})3Ky)s 3[|7>^#M]fzj k@X`"d@&M;j(5m䘈= #"=/?6-%a3Lgפ7=}|~3fYv}L-X1r%k[_T"Ůh}i(e8+QtN&3'G}G`9jw̷-ps]25h>MYearmWwGdkFXBW[X65 [hF+Ow/Sl}apԨԤ[{xd|4.|zfgNv ?|оǍ+Ɖ5INРt]PFBs#oJq=U>2*q(S-tMʟ1+$V slpY>K^U* , v-YZX7*$L4ë[~RƚL`9c$H6L[;V(+5˩j4j!CHm6l4`4klA-ҥ 7Y5Q%F:IJګU@ *N5iz#Zqy3#7PJ:GGF5Uʜ<1ju0H}+nYJv $SB)U?XKu?&LмW̯7c8^-m{NF^H@Q}^K.JPr5lPڳ)QF+5Vf- ^-JPv-Qm#G#VH7PWmrN9wh$t}V/,]v f`-ZX my65$v3$l,="n3fXv$bPfRe/mHYkfM$DEb cos  ɬ~op:?5OBX(/È>@Ze)&\Ol2l|ot8E7Nte]+SdנG8XmPXr&T5O fR(؍.Qe:yBb%i4qf;KWPq淆*ٍO+ B/c,8)<}ँ#7sBEfVFDX=cgSTt7ųu̧"][ya}qk8li5rD 9ķA79#*WMD{̾f=ioe^? &A 떉H^_GvN!^`B~>:>7}6<|`ܪ]l۽X<8OY1Lm8i"8FDEQյ”)4.b,)Q )'ӛW3;9ҭaoȩه2G3nEOy K5S=6AWACaqHSJwTBݺY|WRH=2pToΘSk v>/w]>ĚHAqɤ0aq;D%bF4 Uirm|/lֳWbu]8?Wsc7"*ށ֡#.l Kjam+;2x#"=EzaJ`"xc1ub]ClmqPa9wq_[h+0]/v(Q E7vg0 +=ۤtÙ!P]8hAJV{P";{"y!X1+yϹ}K>9g&1gm:|q(Diu ùid]ZlXW=y ˫un'6Fg|[Cb Ne$y{hTȨ olFGNn Nh/-PՁ=̢^ҵRZ;{RƁG9_[az^ᯤjnpC1k\ӜI1A"3Y`!<y6hC)]R;DbP V~bMq`֐E} ay9kF""ߪ2ʿ"-Hd46k`W4EL̓9 n%n!\>1[*$tGEX?6\l~g_.h ظl3o"+~P=8e9 3>]q"f[\'B̫/8E{J(|'ϰ0wKd\Ev0JIAd)M>ŃP#hDś",l9UM>W' 'yz=-][IR%2QMRLR}:ْ S~Bzq/٥G.?@-5a|?͘µ{y̘5D?< Q;AQ5%&eKzXѯ|7YR pwelfB"Bv'{Hi=5Nhj4<}Nǒ1(pt{?\it;CSnhlNS1|z#:4V=_'rg<~dZ9e^fU9*PhW=6'4񗈶UhmR.P9_^=>)b2.MVuo&t|+ g4.ʞW:/.נw#۽>*s&+{=^F1l:vJϴe\yAʀNjTr*%g:(f(p,#7釫J=˨|vQu 6gI vq&"άqL5K}IU)'ZYLvsZ/vZ:Ut ~2'$h8CU{8mxܮsXpc=7_WH^, 9@.XfEOn']j~i%-Eܢ)d5f-%͢J8x>Y#ΡS$+sWM+ W?Uy<$sh[ʬpNR"cK~b?fJ/P.T΀;C{̞:V+*u~b]O*,su-J3W*dώ':N,*}ӟXX\%G{;=΂O|h򘹄3MT9).^=M5!&_f-P7^qLnV;ŬeX,JfLK%oiGfgӝVID}wG`m%q|a4|z,Y[8*UF.־FE\8K#FR ͸iX׮K +ᶢ&~1sSy˚t~Sҭ sh9Fɿֻ[^`ହ;pۃv-ީ\ dLLx; ZkӏO'@lTbmS;z&-Xttգcenv˝sG2G/("J\-\,TW~Nsf)('PsT+sN绅?dÔDŽqw%J Qv0qzUΠ M(4 1!Eߖ{ m;,IF`aTw@@w]*+~C\sj Ֆ~H)d /v/uqJP"0U i񟍢f}NͬnDQ<'{_Ӣ >ԕ-uXȤE5B{=@eI푋_7:t`~1$28^i~-5Q~1r*ֳn 18[Ăb_C"Z%vYJvhtxڳߪx(o-TgU/e-5 B(HE(u(*Ee+%mDP83~Sog<\뾮99NO(_kUSbO/cr\'F>"t[TQ!ݰmY :]3u4ov89wT">H1R;#yg<3.rÖq?[q|ݿxئWjήg;&w13Gj}|E>EYPt:iZлxg2u5@H^X:/3kﻨn; X)Ώ_>y};Ű;E6*"?ќ>^?8`ٵw7QN/)),.'Mo=/Y9Zn_hHYW.ea-B@'o/7J<3 2T#Цw,ӝ5[cz#->z#Y5~ίOs`%J X0m |,N.(L8)7nݴYlؽ8fa_QxmyF;(cPٷ1_I6>8zmpQeWLij4KC毋_6?>c]-'kWL.:+ғL&ރ/E_33xavߞC:wlGtH=Z"t),w QQb әs~΍T:Iޤ-eԴ' D M[ʈR-2WCe7V&4,L8 >j>R]}NƍY7Ibl">}B1&"c^fr)s"G0ϒQ$㈤[ mM|0"ҿᾰDi˳W4ՊpUP].Fm{Dk,c_鳕2-tYF?:UfA.ؓuÌ(նr;oMn_koWs4 17ףxSyRf+fbdS"Pc7L%O[BFiv,K hr.6iW"M. S\—@b>>K _KTyW ,n%AUZ;AMGZɋz]--OPhhE.R`zϷCՌfCVVgiި(0֘tӲcOR+ٴˬ'?3hy(Ch–xҎ]3>D'E>=t{J;-F6bZT C扃l5\}abvtn c>2޴pl&iȻ@FJBř\\c&W;E2J/MFsÏ$bdK#.5GdBG'ChΛ 3W+<&|(BONfZـڂ@ w5j_gFrDc\%Yg;բvjt1똆4el M&ܭ2 STRf()ڑG͵b6h_h2<;­qKTPktBڌ4Xub2Ect$GgN ނa{\bhJYFi1YVGVkLS7ϥ=0{]th=ݗWM3Ԙ'L1f PӍb߽?F W89Z?e*q\$c@C[b4n:;ҐSR@Nc6F[&6F|r}P'}=҇{q-c< 3~h8ƹuKՅ1ngUc][r?9[b=LAw9WrX!\<~m8b}O>&!KB]eLNWv%<{!Vy-aI\OZV dO6b!blEɈ [b94W<#i8a2nEؾe\&GROX)SRvҬk18Ґ ,z`ٕ-AUfݓr[$ƃ.QXk Ie[=i,{ɗ=F2=OE;O|{3ԝMmO4ST]߈IBm=^;2 fim9$ĆWWI4N:rN^n /xrZqLtŤKA׶ 8I)>Xh|sX~tBXW5H7_6h ɵ2ͷ|/Xw -Beat9׽v\n2ûKSSMmn^"һ$q_߅` ? ߗm3P0_Ok8*SؘJKkZFA`tMN!a`tX{̍768/jdh\]ԓqViGMΏV'ܯi+|ܙyM <0z]][iҍ ya[؟.F mo)`:fmr:v<]al}xw`*c]픸$?-4fS?B{M-,^uf#mhEcFvrW2>zNՠ\|}ީS6\<#bv#Pul|#i1LMli}AQlj,3xd{Gg`?sHTJ2k K,NQC:}W)NkJ"fgD/\ %ו5盂{J2Bo_,DzDԏ=db|T'vI*-/f(mpZJG^TvlQWO e ucQdj"t+wjlMJa~;:>ܝpJ8pgᗁ1f›e>$+a!Rv(qtBs RS2!,`/9ȋ2>134X nt@A[dSx5f0;o\ʓĖ Z Y4ڷsNx9Xyjf}L\#w΂(7J]2Ol ̝:{tlW^'S { 8z~o?r.7s^a7O9c%g#{ވ 5^0[MѬIۍɫ!fDYsczqO-tFT"IJΓǻR[B)4W JL A oSdh 2C@WI4l~@%LIlˆ~1 V`~W": p]].2|4?Fb`AZCpP1tRU{0*RCԳ!oD"_I/b#wuF3|rrXT(0Ukڠdy#j6s]"shIդO8?u?-؈]5:}XgfMirN6=wЮ^BѯZg꾛ⰻQہAq۸E[_ 0~\丹ڇe ~vh1!6sw;hw:^aSv9pHy5 vO<]ձ3#['QFdw2O䩎$X6}㒈FQXƧgjy9YcjzRb&[ؒW}bpE\2očc>d GW騛{+7\[Ȝb5>pwYYӃ.*GIdp#[6ˢ*.04Kt!QzY3/tͼ_ZrKh??úu[s;FHڪNm;:ŢW΢ Įv7f}ٕ>kĬ>Φ9vJ;fJET;rMh>١j.; l7v{fJvtxVixRXاj;po=tz?\#t(C~Xo7أ\}N~kihAs $7ppqRvvU#[Աh6yS®2/g/lEoFH&!``xMU==I~, ]^w}H^0MQE~ h4%o9hA$`~PRX ~\wZ`?w9kǯ47OC\vF33vW.Ofvw_?!e_e?A5=_95=;׬O@D{گqlR{ܚ;GkiFڝm>`^K ?b f$f2 f%ts$C$M  ZE-H a!FQCԬԴ?:Qe-;̊r<||`6drՄλ6h A`N[5>?7*-ɮgnn~$y5:|NǑPY#k6($  0 EUW??/y9 w'3OȬQ[2 BcAxtR*kT AB+!Yw'W'3b~s%cHCC47D~DON]QY#i[*JFd̿qbK6Qqr 7E-M--,+;sc$zAG`5Wc^4\a Vp ϼd; ?'\C< H :()@It`@ yY<0|q_1$z@6_ơxâP*YTh,z3 CSb (q C8*YR? DRpT OZW$8$tC(1,Oi$,P BMa#P9dA< p %)B|.SBqNk8 Mh*;#<pX4JAKa rTBbt[$0PPQ%ARa)BtQTA*X= EN/(dFR~(c\PT{#n=G)ctHR[#`T!Ʌ֟JIfR,נ$l(Og st9] Ljb45@-: S@ ZV߿RlAZ_4`PKX/5~9META-INF/MANIFEST.MFPK 85de/PK 85:de/uos/PK 85_de/uos/cogsci/PK 85de/uos/cogsci/ai/PK 85de/uos/cogsci/ai/btenbergen/PK 85&de/uos/cogsci/ai/btenbergen/bscthesis/PK 8558de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/PK 5w+59de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/PK !5<XXCde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layer.javaPK !5E&Dde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/Layers.javaPK 5=1MMBde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/MLPs.javaPK 5w+5=.de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/PK \(5:XXE.de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/mlp/som/SOM.javaPK 5w+5@.de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PK 5 ]de/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/PerceptronInputException.javaPK 5NkkOde/uos/cogsci/ai/btenbergen/bscthesis/neuralnetworks/perceptron/Perceptron.javaPK 5w+5,de/uos/cogsci/ai/btenbergen/bscthesis/tools/PK !56>Ϯde/uos/cogsci/ai/btenbergen/bscthesis/tools/OperatorTools.javaPK |5-lN 8Jde/uos/cogsci/ai/btenbergen/bscthesis/tools/Cluster.javaPK /(5e6de/uos/cogsci/ai/btenbergen/bscthesis/tools/Tools.javaPK !5bb9de/uos/cogsci/ai/btenbergen/bscthesis/tools/Distance.javaPK 5w+5+de/uos/cogsci/ai/btenbergen/bscthesis/yale/PK Q/5rq::>de/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMFileHandler.javaPK /5558IDde/uos/cogsci/ai/btenbergen/bscthesis/yale/SOMInput.javaPK 5+[GG 'zLICENSE.txtPK L!5 META-INF/PK 5Xznn META-INF/ABOUT.NFOPK Ѝ5}3G"RRMETA-INF/operators.xmlPK$}S5R+G!1~ 1Plugin-Manual.pdfPK