diff --git a/FUCoin_Commit.pdf b/FUCoin_Commit.pdf new file mode 100644 index 0000000000000000000000000000000000000000..43e9f53fbc46f468a107492c682c1f3e2e394ece Binary files /dev/null and b/FUCoin_Commit.pdf differ diff --git a/JavaAkkaFuCoin.zip b/JavaAkkaFuCoin.zip new file mode 100644 index 0000000000000000000000000000000000000000..0132fed3147d5a390e0b5912d39131413f032633 Binary files /dev/null and b/JavaAkkaFuCoin.zip differ diff --git a/JavaAkkaFuCoin/.classpath b/JavaAkkaFuCoin/.classpath new file mode 100644 index 0000000000000000000000000000000000000000..149cb3c90688952162d8c347ea8ee4ac2a23e17b --- /dev/null +++ b/JavaAkkaFuCoin/.classpath @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" output="target/classes" path="src"> + <attributes> + <attribute name="optional" value="true"/> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER"> + <attributes> + <attribute name="maven.pomderived" value="true"/> + </attributes> + </classpathentry> + <classpathentry kind="output" path="target/classes"/> +</classpath> diff --git a/JavaAkkaFuCoin/.gitignore b/JavaAkkaFuCoin/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..09e3bc9b241c477ea341af9ee029becad0c2148c --- /dev/null +++ b/JavaAkkaFuCoin/.gitignore @@ -0,0 +1,2 @@ +/bin/ +/target/ diff --git a/JavaAkkaFuCoin/.project b/JavaAkkaFuCoin/.project new file mode 100644 index 0000000000000000000000000000000000000000..4610a714e9294dc1ec3988a67610511640c5c0c7 --- /dev/null +++ b/JavaAkkaFuCoin/.project @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>JavaAkkaFuCoin</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.jdt.core.javabuilder</name> + <arguments> + </arguments> + </buildCommand> + <buildCommand> + <name>org.eclipse.m2e.core.maven2Builder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.m2e.core.maven2Nature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/JavaAkkaFuCoin/.settings/org.eclipse.jdt.core.prefs b/JavaAkkaFuCoin/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..672496e107ed4e070613aad776b4df5146306bd4 --- /dev/null +++ b/JavaAkkaFuCoin/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/JavaAkkaFuCoin/.settings/org.eclipse.m2e.core.prefs b/JavaAkkaFuCoin/.settings/org.eclipse.m2e.core.prefs new file mode 100644 index 0000000000000000000000000000000000000000..f897a7f1cb2389f85fe6381425d29f0a9866fb65 --- /dev/null +++ b/JavaAkkaFuCoin/.settings/org.eclipse.m2e.core.prefs @@ -0,0 +1,4 @@ +activeProfiles= +eclipse.preferences.version=1 +resolveWorkspaceProjects=true +version=1 diff --git a/JavaAkkaFuCoin/pom.xml b/JavaAkkaFuCoin/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..ccdd40ba7e08a14b15f3b932107be1e45b380f39 --- /dev/null +++ b/JavaAkkaFuCoin/pom.xml @@ -0,0 +1,26 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <groupId>JavaAkkaFuCoin</groupId> + <artifactId>JavaAkkaFuCoin</artifactId> + <version>0.0.1-SNAPSHOT</version> + <build> + <sourceDirectory>src</sourceDirectory> + <plugins> + <plugin> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + <configuration> + <source>1.8</source> + <target>1.8</target> + </configuration> + </plugin> + </plugins> + </build> + <dependencies> + <dependency> + <groupId>com.typesafe.akka</groupId> + <artifactId>akka-actor_2.11</artifactId> + <version>2.4-M1</version> + </dependency> + </dependencies> +</project> \ No newline at end of file diff --git a/JavaAkkaFuCoin/src/fucoin/AbstractNode.java b/JavaAkkaFuCoin/src/fucoin/AbstractNode.java new file mode 100644 index 0000000000000000000000000000000000000000..912b0a2c0cfdb57c3cab8f0ee36cd0ce3fde9f68 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/AbstractNode.java @@ -0,0 +1,58 @@ +package fucoin; + +import java.io.Serializable; +import java.util.HashMap; + +import akka.actor.ActorRef; +import akka.actor.UntypedActor; + +public abstract class AbstractNode extends UntypedActor implements Serializable { + + // Returns the akka-style address as String, which + // could be converted to an ActorRef object later + public String getAddress() { + return getAddress(getSelf()); + } + + public String getAddress(ActorRef self) { + return self.path().toSerializationFormatWithAddress(self.path().address()); + } + + // The which receives Action objects + public abstract void onReceive(Object message); + + // Holds references to neighbors that were in + // contact with this wallet during runtime; + // The key corresponds to the Wallet's name + private transient HashMap<String, ActorRef> knownNeighbors = new HashMap<String, ActorRef>(); + + // Holds references to neighbors this wallet + // synchronizes itself to (the Wallet object); + // The key corresponds to the Wallet's name + public transient HashMap<String, ActorRef> localNeighbors = new HashMap<String, ActorRef>(); + + // Holds all Wallets from network participants + // which synchronize their state (Wallet object) + // with us; + // The key corresponds to the Wallet's name + public transient HashMap<String, AbstractWallet> backedUpNeighbors = new HashMap<String, AbstractWallet>(); + + public transient HashMap<ActorRef, Integer> amounts = new HashMap<ActorRef, Integer>(); + + public boolean addKnownNeighbor(String key, ActorRef value) { + if(!knownNeighbors.containsKey(key)){ + knownNeighbors.put(key,value); + return true; + } + return false; + } + + public HashMap<String, ActorRef> getKnownNeighbors() { + return knownNeighbors; + } + + public void log(String string) { + System.out.println(getSelf().path().name()+": "+string); + } + +} \ No newline at end of file diff --git a/JavaAkkaFuCoin/src/fucoin/AbstractWallet.java b/JavaAkkaFuCoin/src/fucoin/AbstractWallet.java new file mode 100644 index 0000000000000000000000000000000000000000..e77b6741fe070bf95bb93046940d0c6865db3cf9 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/AbstractWallet.java @@ -0,0 +1,27 @@ +package fucoin; + +public abstract class AbstractWallet extends AbstractNode{ + + // Constructor + public AbstractWallet(String name) { + this.name = name; + } + + // Returns the name of this wallet, e.g. "Lieschen Müller" + public String getName() { + return this.name; + } + + // Performs housekeeping operations, e.g. pushes + // backedUpNeighbor-entries to other neighbors + public abstract void leave(); + + // The amount this wallet currently holds + public int amount; + + // The name of this wallet (does never change, no + // duplicates in network assumed) + public final String name; + + +} diff --git a/JavaAkkaFuCoin/src/fucoin/IWallet.java b/JavaAkkaFuCoin/src/fucoin/IWallet.java new file mode 100644 index 0000000000000000000000000000000000000000..54ec9b3291fdd832ffdd6c67411d10e2bfb80562 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/IWallet.java @@ -0,0 +1,13 @@ +package fucoin; +import java.util.Vector; + +import fucoin.gui.IWalletControle; + + +public interface IWallet extends IWalletControle{ + //Vector<WalletPointer> join(); + void storeOrUpdate(Wallet w); + void invalidateWallet(Wallet w); + void receiveTransaction(int amount); + //Vector<WalletPointer> searchWallet(String adress); +} diff --git a/JavaAkkaFuCoin/src/fucoin/Main.java b/JavaAkkaFuCoin/src/fucoin/Main.java new file mode 100644 index 0000000000000000000000000000000000000000..494bce433d6edc803353107f795c45977f6de723 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/Main.java @@ -0,0 +1,77 @@ +package fucoin; +import java.io.File; +import java.util.ArrayList; +import java.util.List; + +import akka.actor.ActorRef; +import akka.actor.ActorSystem; + +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; + +import fucoin.actions.join.ServerActionJoin; +import fucoin.supervisor.SuperVisor; + + + +public class Main { + + public static void main(String[] args) throws InterruptedException { + File file = new File("application.conf"); + System.out.println("config found? " + file.exists()); + Config config = ConfigFactory.parseFile(file); + ActorSystem system = ActorSystem.create("Core", config); + ActorRef superVisorActor = system.actorOf(SuperVisor.props(),"SuperVisor"); + List<ActorRef> activeActors = new ArrayList<ActorRef>(); + ActorRef a1 = system.actorOf(Wallet.props(null,"","Main",superVisorActor),"Main"); + ActorRef a2 = system.actorOf(Wallet.props(a1,"Main","Main2",superVisorActor),"Main2"); + superVisorActor.tell(new ServerActionJoin("Main"), a1); + superVisorActor.tell(new ServerActionJoin("Main2"), a2); + + //a2.tell(new ActionInvokeSentMoney("Main", 200), a2); + //activeActors.add(a1); + /* + int maxrounds = 100; + int maxactors = 10; + for(int actor=0; actor<maxactors;actor++){ + activeActors.add(system.actorOf(Wallet.props(a1,"Main","Main"+actor,superVisorActor),"Main"+actor)); + } + List<List<ActorRef>> offline = new ArrayList<List<ActorRef>>(); + + for(int listnr=0; listnr<maxrounds;listnr++){ + offline.add(new ArrayList<ActorRef>()); + } + + for(int timestep=0; timestep<maxrounds;timestep++){ + System.out.println("timestamp:"+timestep); + List<ActorRef> removedActors = new ArrayList<ActorRef>(); + for(ActorRef actor:activeActors){ + if(Math.random()<0.6){ + actor.tell(new ActionInvokeSentMoney("Main"+(int)Math.floor(Math.random()*maxactors), (int) (Math.round(Math.random()*100))), actor); + } + if(Math.random()<0.2){ + removedActors.add(actor); + int offtime = timestep+(int)(Math.random()*6)+2; + + offline.get(Math.min(offtime, maxrounds-1)).add(actor); + } + } + activeActors.removeAll(removedActors); + for(ActorRef actorName:offline.get(timestep)){ + actorName.tell(new ActionInvokeRevive(), actorName); + activeActors.add(actorName); + } + for(ActorRef removedActor : removedActors){ + removedActor.tell(new ActionInvokeLeave(), removedActor); + } + + Thread.sleep(1000); + System.out.println("timestamp end:"+timestep); + System.out.println("activeActors:"+activeActors); + System.out.println("revived"+offline.get(timestep)); + + } + superVisorActor.tell(new ActionInvokeUpdate(), superVisorActor); + */ + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/MainRemote.java b/JavaAkkaFuCoin/src/fucoin/MainRemote.java new file mode 100644 index 0000000000000000000000000000000000000000..309bae2951caf6bd4b66df846f58ea8eec7bb4e2 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/MainRemote.java @@ -0,0 +1,32 @@ +package fucoin; + +import java.io.File; + +import akka.actor.ActorPath; +import akka.actor.ActorRef; +import akka.actor.ActorSystem; +import akka.actor.Address; + +import com.typesafe.config.Config; +import com.typesafe.config.ConfigFactory; + +public class MainRemote { + public static ActorRef remoteSuperVisorActor; + + public static void main(String[] args) throws InterruptedException { + + File file = new File("application.conf"); + System.out.println("config found? " + file.exists()); + Config config = ConfigFactory.parseFile(file); + ActorSystem system = ActorSystem.create("Test", config); + + Address address = new Address("akka.tcp", "Core", "127.0.0.1", 1234); + System.out.println(address); + String path = "akka.tcp://Core@127.0.0.1:1234/user/Main"; + System.out.println(system.actorSelection(ActorPath.fromString(path))); + + System.out.println(ActorPath.isValidPathElement(""+address+"/user/Main")); + ActorRef a1 = system.actorOf(Wallet.props(null,"","Main2",remoteSuperVisorActor),"Main2"); + + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/Wallet.java b/JavaAkkaFuCoin/src/fucoin/Wallet.java new file mode 100644 index 0000000000000000000000000000000000000000..70f26fd81a94ae30e0cb5afeaf122774b7750467 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/Wallet.java @@ -0,0 +1,173 @@ +package fucoin; + +import akka.actor.ActorRef; +import akka.actor.Props; +import fucoin.actions.ClientAction; +import fucoin.actions.join.ActionJoin; +import fucoin.actions.join.ActionJoinAnswer; +import fucoin.actions.join.ServerActionJoin; +import fucoin.actions.persist.ActionInvokeLeave; +import fucoin.actions.persist.ActionInvokeRevive; +import fucoin.actions.transaction.ActionGetAmountAnswer; +import fucoin.actions.transaction.ActionInvokeSentMoney; +import fucoin.gui.IWalletControle; +import fucoin.gui.IWalletGuiControle; + +public class Wallet extends AbstractWallet implements IWalletControle{ + + private ActorRef preknownNeighbour; + private ActorRef remoteSuperVisorActor; + private IWalletGuiControle gui; + private String preknownNeighbourName; + private boolean isActive; + + public Wallet(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) { + super(walletName); + this.preknownNeighbourName=preknownNeighbourName; + this.preknownNeighbour=preknownNeighbour; + this.remoteSuperVisorActor=remoteSuperVisorActor; + } + + public void addAmount(int amount) { + setAmount(this.amount+amount); + log(" My amount is now "+this.amount); + + } + + @Override + public void leave() { + getSelf().tell(new ActionInvokeLeave(), getSelf()); + } + + @Override + public void onReceive(Object message) { + log(message.getClass().getSimpleName()); + + //log(getSender().path().name()+" invokes "+getSelf().path().name()+" to do "+message.getClass().getSimpleName()); + if(message instanceof ActionInvokeRevive){ + ((ActionInvokeRevive) message).doAction(this); + } + if(!isActive&&!(message instanceof ActionInvokeRevive))return; + //System.out.println(message); + if(message instanceof ClientAction){ + ((ClientAction) message).doAction(this); + } + + } + + @Override + public void preStart() throws Exception { + isActive=true; + if(gui!=null){ + gui.setAddress(getAddress()); + } + String path = "akka.tcp://Core@127.0.0.1:1234/user/Main"; + //System.out.println(getContext().provider().getExternalAddressFor(getSelf().path().address())); + //log("my address should be "+getAddress()); + //log(""+preknownNeighbour); + //knownNeighbors.put(getName(),getSelf()); + + //System.out.println(knownNeighbors); + if(preknownNeighbour!=null){ + addKnownNeighbor(preknownNeighbourName,preknownNeighbour); + preknownNeighbour.tell(new ActionJoin(), getSelf()); + ActionJoinAnswer aja = new ActionJoinAnswer(); + aja.someNeighbors.putAll(getKnownNeighbors()); + aja.someNeighbors.put(name, getSelf()); + preknownNeighbour.tell(aja, getSelf()); + + } + //setAmount(100); + //remoteSuperVisorActor.tell(new ServerActionJoin(name), getSelf()); + } + + @Override + public void postStop() throws Exception { + leave(); + super.postStop(); + + } + + + public static Props props(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) { + return Props.create(Wallet.class,new WalletCreator(preknownNeighbour,preknownNeighbourName,walletName,remoteSuperVisorActor)); + } + + @Override + public boolean equals(Object obj) { + if(obj instanceof Wallet){ + Wallet wobj = (Wallet) obj; + return amount==wobj.amount&&name.equals(wobj.name); + } + return false; + } + + public void setGui(IWalletGuiControle gui) { + this.gui=gui; + } + + public void setAmount(int amount){ + this.amount = amount; + if(remoteSuperVisorActor != null){ + remoteSuperVisorActor.tell(new ActionGetAmountAnswer(getAddress(), getName(), amount), getSelf()); + } + if(gui!=null){ + gui.setAmount(this.amount); + } + } + + public ActorRef getPreknownNeighbour() { + return preknownNeighbour; + } + + public ActorRef getRemoteSuperVisorActor() { + return remoteSuperVisorActor; + } + + public IWalletGuiControle getGui() { + return gui; + } + + public String getPreknownNeighbourName() { + return preknownNeighbourName; + } + + public boolean isActive() { + return isActive; + } + + @Override + public boolean addKnownNeighbor(String key, ActorRef value) { + log(key+" is newNeighbor?"+!getKnownNeighbors().containsKey(key)); + if(getKnownNeighbors().containsKey(key)||key.equals(name)){ + return false; + } + boolean newNeighbor = super.addKnownNeighbor(key, value); + if(gui!=null&&newNeighbor){ + gui.addKnownAddress(key); + } + return newNeighbor; + } + + public void setPreknownNeighbour(ActorRef preknownNeighbour) { + this.preknownNeighbour = preknownNeighbour; + } + + public void setRemoteSuperVisorActor(ActorRef remoteSuperVisorActor) { + this.remoteSuperVisorActor = remoteSuperVisorActor; + } + + public void setPreknownNeighbourName(String preknownNeighbourName) { + this.preknownNeighbourName = preknownNeighbourName; + } + + public void setActive(boolean isActive) { + this.isActive = isActive; + } + + @Override + public void send(String address, int amount) { + getSelf().tell(new ActionInvokeSentMoney(address, amount), getSelf()); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/WalletCreator.java b/JavaAkkaFuCoin/src/fucoin/WalletCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..3918b11f173ac183c1c7d89ce5f1d76a38d98663 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/WalletCreator.java @@ -0,0 +1,34 @@ +package fucoin; + +import akka.actor.ActorRef; +import akka.japi.Creator; +import fucoin.gui.IWalletGuiControle; +import fucoin.gui.WalletGui; + +public class WalletCreator implements Creator<Wallet> { + + private ActorRef preknownNeighbour; + private String walletName; + private ActorRef remoteSuperVisorActor; + private String preknownNeighbourName; + + public WalletCreator(ActorRef preknownNeighbour, String preknownNeighbourName, String walletName, ActorRef remoteSuperVisorActor) { + this.preknownNeighbour=preknownNeighbour; + this.preknownNeighbourName=preknownNeighbourName; + this.walletName=walletName; + this.remoteSuperVisorActor=remoteSuperVisorActor; + + } + + @Override + public Wallet create() throws Exception { + Wallet wallet = new Wallet(preknownNeighbour,preknownNeighbourName, walletName,remoteSuperVisorActor); + + IWalletGuiControle gui = new WalletGui(wallet); + wallet.setGui(gui); + return wallet; + } + + + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/Action.java b/JavaAkkaFuCoin/src/fucoin/actions/Action.java new file mode 100644 index 0000000000000000000000000000000000000000..926c6b2175997bf4b24e7b75d0796c7d1020e55a --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/Action.java @@ -0,0 +1,21 @@ +package fucoin.actions; + +import fucoin.AbstractNode; +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; + +public abstract class Action<T extends AbstractNode> { + private ActorRef self; + + public final void doAction(T abstractNode){ + this.self=abstractNode.getSelf(); + onAction(abstractNode.getSender(),abstractNode.getSelf(),abstractNode.getContext(),abstractNode); + } + + protected abstract void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, T abstractNode); + + public void log(String string) { + System.out.println(self.path().name()+": "+string); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/ClientAction.java b/JavaAkkaFuCoin/src/fucoin/actions/ClientAction.java new file mode 100644 index 0000000000000000000000000000000000000000..e4f5119d968f78fa6330e753db914a0676160296 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/ClientAction.java @@ -0,0 +1,12 @@ +package fucoin.actions; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public abstract class ClientAction extends Action<Wallet>{ + @Override + protected abstract void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet abstractNode); + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/join/ActionJoin.java b/JavaAkkaFuCoin/src/fucoin/actions/join/ActionJoin.java new file mode 100644 index 0000000000000000000000000000000000000000..93b690dfed24b0cddb3eb7305b3725c174d78e4d --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/join/ActionJoin.java @@ -0,0 +1,18 @@ +package fucoin.actions.join; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.AbstractNode; + +//Used to join the network (a pre known participant/Wallet must be known) +public class ActionJoin extends GeneralAction{ + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, AbstractNode node) { + ActionJoinAnswer aja = new ActionJoinAnswer(); + aja.someNeighbors.putAll(node.getKnownNeighbors()); + sender.tell(aja, self); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/join/ActionJoinAnswer.java b/JavaAkkaFuCoin/src/fucoin/actions/join/ActionJoinAnswer.java new file mode 100644 index 0000000000000000000000000000000000000000..b230b1a51030b0958b879b951f9d36d859105873 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/join/ActionJoinAnswer.java @@ -0,0 +1,27 @@ +package fucoin.actions.join; + +import java.util.HashMap; +import java.util.Map.Entry; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; +import fucoin.actions.ClientAction; +import fucoin.actions.persist.ActionSearchMyWallet; + +// Returns some neighbors that might be used as known +// and/or local neighbors +public class ActionJoinAnswer extends ClientAction{ + public final HashMap<String, ActorRef> someNeighbors = new HashMap<>(); + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + log("someNeighbors:"+someNeighbors); + for(Entry<String, ActorRef> neighbor : someNeighbors.entrySet()){ + wallet.addKnownNeighbor(neighbor.getKey(),neighbor.getValue()); + } + for(Entry<String, ActorRef> neighbor : someNeighbors.entrySet()){ + neighbor.getValue().tell(new ActionSearchMyWallet(wallet.getName()), self); + } + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/join/GeneralAction.java b/JavaAkkaFuCoin/src/fucoin/actions/join/GeneralAction.java new file mode 100644 index 0000000000000000000000000000000000000000..8ddb5175b14c2c77174d588712e6d884df72674a --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/join/GeneralAction.java @@ -0,0 +1,8 @@ +package fucoin.actions.join; + +import fucoin.AbstractNode; +import fucoin.actions.Action; + +public abstract class GeneralAction extends Action<AbstractNode> { + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/join/Join.java b/JavaAkkaFuCoin/src/fucoin/actions/join/Join.java new file mode 100644 index 0000000000000000000000000000000000000000..eccba13555aad1ac4665f503a359952659a22010 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/join/Join.java @@ -0,0 +1,10 @@ +package fucoin.actions.join; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.AbstractNode; +import fucoin.Wallet; +import fucoin.actions.ClientAction; + +public abstract class Join extends ClientAction{ +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/join/ServerActionJoin.java b/JavaAkkaFuCoin/src/fucoin/actions/join/ServerActionJoin.java new file mode 100644 index 0000000000000000000000000000000000000000..9dfc08a69efd041da94c1e53507a07a8fa176cf6 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/join/ServerActionJoin.java @@ -0,0 +1,27 @@ +package fucoin.actions.join; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.actions.transaction.ActionInvokeDistributedCommitedTransfer; +import fucoin.actions.transaction.SuperVisorAction; +import fucoin.supervisor.SuperVisor; + +public class ServerActionJoin extends SuperVisorAction { + private String name; + + public ServerActionJoin(String name) { + this.name = name; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, SuperVisor node) { + ActionJoinAnswer aja = new ActionJoinAnswer(); + aja.someNeighbors.putAll(node.getKnownNeighbors()); + sender.tell(aja, self); + node.addKnownNeighbor(name, sender); + self.tell( + new ActionInvokeDistributedCommitedTransfer(self, sender, 100), + sender); + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvalidate.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvalidate.java new file mode 100644 index 0000000000000000000000000000000000000000..f5068d3317ce4b479ff5f3c020498975e134164f --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvalidate.java @@ -0,0 +1,19 @@ +package fucoin.actions.persist; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.AbstractNode; +import fucoin.Wallet; + +// May be used to delete a stored Wallet on another participant +public class ActionInvalidate extends Persist{ + public final String name; + public ActionInvalidate(String name) { + this.name = name; + } + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + wallet.backedUpNeighbors.remove(name); + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeLeave.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeLeave.java new file mode 100644 index 0000000000000000000000000000000000000000..e8d0102425d73694789694c5a7d2d815264bef56 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeLeave.java @@ -0,0 +1,24 @@ +package fucoin.actions.persist; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public class ActionInvokeLeave extends Persist{ + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + for(ActorRef neighbor : wallet.getKnownNeighbors().values()){ + if(self.compareTo(neighbor)!=0){ + neighbor.tell(new ActionStoreOrUpdate(wallet), self); + } + } + + + wallet.setActive(false); + wallet.backedUpNeighbors.clear(); + wallet.getKnownNeighbors().clear(); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeRevive.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeRevive.java new file mode 100644 index 0000000000000000000000000000000000000000..d1bf1015bcfd9005776c2460c999eac031efc693 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeRevive.java @@ -0,0 +1,17 @@ +package fucoin.actions.persist; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; +import fucoin.actions.join.ActionJoin; + +public class ActionInvokeRevive extends Persist{ + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + wallet.setActive(true); + wallet.getPreknownNeighbour().tell(new ActionJoin(), self); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeUpdate.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeUpdate.java new file mode 100644 index 0000000000000000000000000000000000000000..e71f052f00a7c114f9a4bfadadc5fb0f139d9656 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionInvokeUpdate.java @@ -0,0 +1,16 @@ +package fucoin.actions.persist; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public class ActionInvokeUpdate extends Persist{ + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + // TODO Auto-generated method stub + + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionSearchMyWallet.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionSearchMyWallet.java new file mode 100644 index 0000000000000000000000000000000000000000..885cbd6f17593e6fb281a2682345ebc286ad09b4 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionSearchMyWallet.java @@ -0,0 +1,28 @@ +package fucoin.actions.persist; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.AbstractWallet; +import fucoin.Wallet; + +// Used to search a Wallet by name, i.e. the own wallet if we just +// joined the network; If a receiving participant holds the stored Wallet, +// he returns it, otherwise, he might use gossiping methods to go on +// with the search; +// Note: You should also forward the sender (the participant who actually +// searches for this Wallet, so that it can be returnd the direct way) +public class ActionSearchMyWallet extends Persist{ + public final String name; + public ActionSearchMyWallet(String name) { + this.name = name; + } + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + wallet.addKnownNeighbor(name, sender); + AbstractWallet storedWallet =wallet.backedUpNeighbors.get(name); + if(storedWallet!=null){ + sender.tell(new ActionSearchMyWalletAnswer(storedWallet), self); + } + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java new file mode 100644 index 0000000000000000000000000000000000000000..933692867d9ce1b5ef49a4aad1081ec14b88f59e --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionSearchMyWalletAnswer.java @@ -0,0 +1,20 @@ +package fucoin.actions.persist; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.AbstractWallet; +import fucoin.Wallet; + +// Used to return a searched Wallet +public class ActionSearchMyWalletAnswer extends Persist { + public final AbstractWallet w; + public ActionSearchMyWalletAnswer(AbstractWallet w) { + this.w = w; + } + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + wallet.setAmount(w.amount); + sender.tell(new ActionInvalidate(wallet.name), self); + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionStoreOrUpdate.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionStoreOrUpdate.java new file mode 100644 index 0000000000000000000000000000000000000000..977c1990ead2e8f54354319881409671c2aed527 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/ActionStoreOrUpdate.java @@ -0,0 +1,20 @@ +package fucoin.actions.persist; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.AbstractNode; +import fucoin.AbstractWallet; +import fucoin.Wallet; + +//Used to push the state of my/a wallet to another participant +public class ActionStoreOrUpdate extends Persist { + public final AbstractWallet w; + public ActionStoreOrUpdate(AbstractWallet w) { + this.w = w; + } + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + wallet.backedUpNeighbors.put(w.name, w); + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/persist/Persist.java b/JavaAkkaFuCoin/src/fucoin/actions/persist/Persist.java new file mode 100644 index 0000000000000000000000000000000000000000..1a42e145ad17ba914350aa5c55efe3fa320dad4a --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/persist/Persist.java @@ -0,0 +1,7 @@ +package fucoin.actions.persist; + +import fucoin.actions.ClientAction; + +public abstract class Persist extends ClientAction{ + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/search/ActionSearchWalletReference.java b/JavaAkkaFuCoin/src/fucoin/actions/search/ActionSearchWalletReference.java new file mode 100644 index 0000000000000000000000000000000000000000..05385ada1b2a15721c1afd5e60edc3ab86653f50 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/search/ActionSearchWalletReference.java @@ -0,0 +1,46 @@ +package fucoin.actions.search; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map.Entry; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +//Used to return a Wallet reference (akka-style string which can +// be transformed to an ActorRef) +public class ActionSearchWalletReference extends Search{ + + public final String name; + public final List<ActorRef> ttl = new ArrayList<ActorRef>(); + public ActionSearchWalletReference(String name) { + this.name = name; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + log(wallet.getKnownNeighbors()+"contains "+name+"?"); + ttl.add(self); + ActionSearchWalletReferenceAnswer answer = null; + if(this.name.equals(wallet.getName())){ + answer = new ActionSearchWalletReferenceAnswer(name,wallet.getAddress(),ttl); + }else if(wallet.backedUpNeighbors.containsKey(name)){ + answer = new ActionSearchWalletReferenceAnswer(name,wallet.backedUpNeighbors.get(name).getAddress(),ttl); + } else if(wallet.getKnownNeighbors().containsKey(name)){ + answer = new ActionSearchWalletReferenceAnswer(name,wallet.getAddress(wallet.getKnownNeighbors().get(name)),ttl); + } else if (ttl.size()<5){ + for(ActorRef neighbor : wallet.getKnownNeighbors().values()){ + if(!ttl.contains(neighbor)){ + neighbor.tell(this, self); + } + } + } + //User unknown by this Wallet + if(answer!=null&&ttl.size()>0){ + ttl.get(ttl.size()-1).tell(answer, self); + } + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/search/ActionSearchWalletReferenceAnswer.java b/JavaAkkaFuCoin/src/fucoin/actions/search/ActionSearchWalletReferenceAnswer.java new file mode 100644 index 0000000000000000000000000000000000000000..6cc2f403bc4b5616108ee021ca9375e9e2ab509e --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/search/ActionSearchWalletReferenceAnswer.java @@ -0,0 +1,30 @@ +package fucoin.actions.search; + +import java.util.List; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public class ActionSearchWalletReferenceAnswer extends Search { + + public final String address; + public final String name; + public final List<ActorRef> pathToSearchedWallet; + public ActionSearchWalletReferenceAnswer(String name,String address, List<ActorRef> pathToSearchedWallet) { + this.address = address; + this.name=name; + this.pathToSearchedWallet=pathToSearchedWallet; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + ActorRef target = context.actorSelection(address).anchor(); + wallet.addKnownNeighbor(name,target); + int pos = pathToSearchedWallet.indexOf(self); + if(pos>0){ + pathToSearchedWallet.get(pos-1).tell(this, self); + } + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/search/Search.java b/JavaAkkaFuCoin/src/fucoin/actions/search/Search.java new file mode 100644 index 0000000000000000000000000000000000000000..505f91562dd12d58b8cdd1cd0e168556c11eecdc --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/search/Search.java @@ -0,0 +1,7 @@ +package fucoin.actions.search; + +import fucoin.actions.ClientAction; + +public abstract class Search extends ClientAction{ + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java new file mode 100644 index 0000000000000000000000000000000000000000..2b72a72d38c2c098cf41fa0d97f1e961be6a70ae --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionCommitDistributedCommitedTransfer.java @@ -0,0 +1,57 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; +import fucoin.actions.ClientAction; +import fucoin.supervisor.DistributedCommitedTransferRequest; + +public class ActionCommitDistributedCommitedTransfer extends ClientAction{ + + private ActorRef source; + private ActorRef target; + private int amount; + private boolean granted; + private long timestamp; + private long id; + + + public ActionCommitDistributedCommitedTransfer(ActorRef source, + ActorRef target, int amount, boolean granted, long timestamp, long id) { + this.source=source; + this.target=target; + this.amount=amount; + this.granted=granted; + this.timestamp=timestamp; + this.id=id; + } + + public ActionCommitDistributedCommitedTransfer( + DistributedCommitedTransferRequest outdatedRequest) { + this.source=outdatedRequest.getSource(); + this.target=outdatedRequest.getTarget(); + this.amount=0; + this.granted=false; + this.timestamp=outdatedRequest.getTimeout(); + this.id=outdatedRequest.getId(); + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + log("ActionCommitDistributedCommitedTransfer is granted?"+granted); + if(granted){ + Integer sourceAmount = wallet.amounts.getOrDefault(source,0); + Integer targetAmount = wallet.amounts.getOrDefault(target,0); + wallet.amounts.put(source,sourceAmount-amount); + wallet.amounts.put(target,targetAmount+amount); + if(source.compareTo(self)==0)wallet.amount-=amount; + else if(target.compareTo(self)==0)wallet.amount+=amount; + wallet.log("have now "+wallet.amounts.get(self)+" Fucoins"); + }else{ + log("abort transaction with id"+id); + } + log("wallet.amounts:"+wallet.amounts); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionGetAmount.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionGetAmount.java new file mode 100644 index 0000000000000000000000000000000000000000..ad9737ba7e41b9db992f03e5e798eff1c929dd86 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionGetAmount.java @@ -0,0 +1,16 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public class ActionGetAmount extends Transaction { + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + ActionGetAmountAnswer agaa = new ActionGetAmountAnswer(wallet.getAddress(),wallet.getName(),wallet.amount); + sender.tell(agaa, self); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionGetAmountAnswer.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionGetAmountAnswer.java new file mode 100644 index 0000000000000000000000000000000000000000..4a85da1c2d1b5bb7206ab52954e25a5daf639cf5 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionGetAmountAnswer.java @@ -0,0 +1,25 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public class ActionGetAmountAnswer extends Transaction { + + public String address; + public String name; + public int amount; + + public ActionGetAmountAnswer(String address, String name, int amount) { + this.address=address; + this.name=name; + this.amount=amount; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeDistributedCommitedTransfer.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeDistributedCommitedTransfer.java new file mode 100644 index 0000000000000000000000000000000000000000..655aa8df515de02ff5922f075b989cb0551623a3 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeDistributedCommitedTransfer.java @@ -0,0 +1,37 @@ +package fucoin.actions.transaction; + +import java.util.HashMap; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; +import fucoin.supervisor.DistributedCommitedTransferRequest; +import fucoin.supervisor.SuperVisor; + +public class ActionInvokeDistributedCommitedTransfer extends CoordinatorTransaction{ + + private ActorRef source; + private ActorRef target; + private int amount; + + public ActionInvokeDistributedCommitedTransfer(ActorRef source, + ActorRef target, int amount) { + this.source=source; + this.target=target; + this.amount=amount; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, SuperVisor superVisor) { + log("invoke transaction "+source.path().name()+" sends "+amount+" to "+target.path().name()); + long timeout = System.currentTimeMillis()+500; + DistributedCommitedTransferRequest ds = new DistributedCommitedTransferRequest(source,target,timeout); + superVisor.addDistributedCommitedTransferRequest(ds); + ActionPrepareDistributedCommitedTransfer apdct = new ActionPrepareDistributedCommitedTransfer(source,target,amount,timeout,ds.getId()); + for(ActorRef neighbor : superVisor.getKnownNeighbors().values()){ + neighbor.tell(apdct, self); + } + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeSentMoney.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeSentMoney.java new file mode 100644 index 0000000000000000000000000000000000000000..7a2ee7eae3841bae1fabf6ccfb4cf27d9311cfa6 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeSentMoney.java @@ -0,0 +1,41 @@ +package fucoin.actions.transaction; + + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; +import fucoin.actions.search.ActionSearchWalletReference; + +public class ActionInvokeSentMoney extends Transaction{ + public final String name; + public final int amount; + public ActionInvokeSentMoney(String name, int amount) { + this.name=name; + this.amount = amount; + } + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + log(wallet.getKnownNeighbors()+""); + if(wallet.getKnownNeighbors().containsKey(name)){ + wallet.getRemoteSuperVisorActor().tell( + new ActionInvokeDistributedCommitedTransfer(self,wallet.getKnownNeighbors().get(name),amount), sender); + }else{ + ActionSearchWalletReference aswr = new ActionSearchWalletReference(name); + for(ActorRef neighbor : wallet.getKnownNeighbors().values()){ + neighbor.tell(aswr, self); + } + sleep(self, context, 200); + self.tell(this, self); + } + } + private void sleep(ActorRef self, UntypedActorContext context, int sleeptime) { + try { + context.unwatch(self); + Thread.sleep(sleeptime); + context.watch(self); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java new file mode 100644 index 0000000000000000000000000000000000000000..743e0b873e361acc05a9c8e8ab9eb95a1f3badf4 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionInvokeSentMoney2.java @@ -0,0 +1,22 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public class ActionInvokeSentMoney2 extends Transaction{ + public final String name; + public final int amount; + public ActionInvokeSentMoney2(String name, int amount) { + this.name=name; + this.amount = amount; + } + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + if(wallet.getKnownNeighbors().containsKey(name)){ + wallet.addAmount(-amount); + wallet.getKnownNeighbors().get(name).tell(new ActionReceiveTransaction(amount), self); + } + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java new file mode 100644 index 0000000000000000000000000000000000000000..decf2b9a32fc661a6d1cf4c569c35047d72fd01b --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransfer.java @@ -0,0 +1,33 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; + +public class ActionPrepareDistributedCommitedTransfer extends Transaction{ + + private ActorRef source; + private ActorRef target; + private int amount; + private long timestamp; + private long id; + + public ActionPrepareDistributedCommitedTransfer(ActorRef source, + ActorRef target, int amount, long timestamp, long id) { + this.source=source; + this.target=target; + this.amount=amount; + this.timestamp=timestamp; + this.id=id; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + boolean granted = sender.compareTo(source)==0 //sender is supervisor(bank) has allways money + ||(wallet.amounts.containsKey(source) //sender is unknown, might be valid + &&wallet.amounts.getOrDefault(source,0)>=amount) ; //sender have enough money + sender.tell(new ActionPrepareDistributedCommitedTransferAnswer(source, target, amount,timestamp,granted,id),self); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java new file mode 100644 index 0000000000000000000000000000000000000000..e479c385962a7041be1d47eab25220237613c9d7 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionPrepareDistributedCommitedTransferAnswer.java @@ -0,0 +1,55 @@ +package fucoin.actions.transaction; + +import fucoin.supervisor.DistributedCommitedTransferRequest; +import fucoin.supervisor.SuperVisor; +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; + +public class ActionPrepareDistributedCommitedTransferAnswer extends CoordinatorTransaction { + + private ActorRef source; + private ActorRef target; + private int amount; + private boolean granted; + private long timestamp; + private long id; + + public ActionPrepareDistributedCommitedTransferAnswer(ActorRef source, + ActorRef target, int amount, long timestamp, boolean granted, long id) { + this.source=source; + this.target=target; + this.amount=amount; + this.granted=granted; + this.timestamp=timestamp; + this.id=id; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, SuperVisor superVisor) { + log(""+superVisor.getKnownNeighbors()); + log("granted?"+granted); + DistributedCommitedTransferRequest request = superVisor.getRequest(id); + if(granted){ + if(request==null)//unknown DistributedCommitedTransferRequest ignore + return; + int newCount = request.addPositiveAnswer(sender); + if(newCount == superVisor.getKnownNeighbors().size()){ + ActionCommitDistributedCommitedTransfer acdct = new ActionCommitDistributedCommitedTransfer(source,target,amount,true,timestamp,id); + for(ActorRef neighbor : request.getAnswers()){ + neighbor.tell(acdct, self); + } + superVisor.deleteRequest(request); + } + }else{ + //A client wants to rollback + if(request!=null){ + ActionCommitDistributedCommitedTransfer acdct = new ActionCommitDistributedCommitedTransfer(source,target,amount,false,timestamp,id); + for(ActorRef neighbor : request.getAnswers()){ + neighbor.tell(acdct, self); + } + } + } + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionReceiveTransaction.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionReceiveTransaction.java new file mode 100644 index 0000000000000000000000000000000000000000..6abdc2a14efd5d3822b8644d2ba89c6837c37dd4 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/ActionReceiveTransaction.java @@ -0,0 +1,18 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.Wallet; +//Used to send (positive amount) or retreive money (negative amount) +public class ActionReceiveTransaction extends Transaction { + final public int amount; + public ActionReceiveTransaction(int amount) { + this.amount = amount; + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + wallet.addAmount(wallet.amount); + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/CoordinatorTransaction.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/CoordinatorTransaction.java new file mode 100644 index 0000000000000000000000000000000000000000..7c95795ea03734797cfb7ef4279785cf1f59d0de --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/CoordinatorTransaction.java @@ -0,0 +1,16 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.AbstractNode; +import fucoin.Wallet; +import fucoin.actions.ClientAction; +import fucoin.supervisor.SuperVisor; + +public abstract class CoordinatorTransaction extends SuperVisorAction{ + +@Override +protected abstract void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, SuperVisor abstractNode); + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/SuperVisorAction.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/SuperVisorAction.java new file mode 100644 index 0000000000000000000000000000000000000000..a6bce1ee7b60d7f0008315459b5a5551d97ec05c --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/SuperVisorAction.java @@ -0,0 +1,11 @@ +package fucoin.actions.transaction; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.actions.Action; +import fucoin.actions.ClientAction; +import fucoin.supervisor.SuperVisor; + +public abstract class SuperVisorAction extends Action<SuperVisor>{ + +} diff --git a/JavaAkkaFuCoin/src/fucoin/actions/transaction/Transaction.java b/JavaAkkaFuCoin/src/fucoin/actions/transaction/Transaction.java new file mode 100644 index 0000000000000000000000000000000000000000..d764afc6192c3d786aa74a564a30a5a2e350cabb --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/actions/transaction/Transaction.java @@ -0,0 +1,7 @@ +package fucoin.actions.transaction; + +import fucoin.actions.ClientAction; + +public abstract class Transaction extends ClientAction{ + +} diff --git a/JavaAkkaFuCoin/src/fucoin/gui/IWalletControle.java b/JavaAkkaFuCoin/src/fucoin/gui/IWalletControle.java new file mode 100644 index 0000000000000000000000000000000000000000..f56fbde20afd9e9c07bfa34e1ade438ab7d76786 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/gui/IWalletControle.java @@ -0,0 +1,7 @@ +package fucoin.gui; + + +public interface IWalletControle { + public void leave(); + public void send(String address, int amount); +} diff --git a/JavaAkkaFuCoin/src/fucoin/gui/IWalletGuiControle.java b/JavaAkkaFuCoin/src/fucoin/gui/IWalletGuiControle.java new file mode 100644 index 0000000000000000000000000000000000000000..55d46acd3c35a3504d395644486b94f27b8a5a73 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/gui/IWalletGuiControle.java @@ -0,0 +1,12 @@ +package fucoin.gui; + + +public interface IWalletGuiControle { + public void setAddress(String address); + public void setAmount(int amount); + public void addKnownAddress(String address); + public void addLogMsg(String msg); + + + +} diff --git a/JavaAkkaFuCoin/src/fucoin/gui/WalletControle.java b/JavaAkkaFuCoin/src/fucoin/gui/WalletControle.java new file mode 100644 index 0000000000000000000000000000000000000000..9bb8b77b6a5d1ea972366bf15f2f11cdb4d27ab7 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/gui/WalletControle.java @@ -0,0 +1,24 @@ +package fucoin.gui; + +import fucoin.Wallet; + + +public class WalletControle implements IWalletControle{ + + private Wallet wallet; + + public WalletControle(Wallet wallet) { + this.wallet=wallet; + } + + @Override + public void leave() { + wallet.leave(); + } + + @Override + public void send(String name, int amount) { + wallet.send(name, amount); + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/gui/WalletCoreGui.java b/JavaAkkaFuCoin/src/fucoin/gui/WalletCoreGui.java new file mode 100644 index 0000000000000000000000000000000000000000..6e2e4c57320d94b9b5cdeb486e5993e05149f3e5 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/gui/WalletCoreGui.java @@ -0,0 +1,51 @@ +package fucoin.gui; + +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JTextField; + +import akka.actor.Address; +import akka.actor.AddressFromURIString; + +public class WalletCoreGui { + public WalletCoreGui() { + JFrame frame = new JFrame("Manager"); + frame.setLayout(new GridLayout(3,2)); + frame.add(new JLabel("Connect to:")); + JTextField input = new JTextField("akka://MySystem/user/main"); + frame.add(input); + frame.add(new JLabel("Name:")); + JTextField name = new JTextField("<Name>"); + frame.add(name); + JButton button = new JButton("connect"); + button.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + /*MessageDispatcherConfigurator mc = null; + String id = input.getText()+"-dispatched"; + int hroughput = 1; + Duration d = Duration.ofSeconds(2); + + + Dispatcher d = new Dispatcher(mc,id, 1, d, Executors.newSingleThreadExecutor(),1000);*/ + String path = "akka.tcp://Test@127.0.0.1:1234/user/main"; + Address addr = AddressFromURIString.parse(path); + //RemoteScope remoteScope = new RemoteScope(addr); + //Deploy deploy = new Deploy(remoteScope); + //Props remoteWallet = Props.apply(deploy, Wallet.class, null); + + + } + }); + + frame.add(button); + frame.setSize(300, 300); + frame.setVisible(true); + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/gui/WalletGui.java b/JavaAkkaFuCoin/src/fucoin/gui/WalletGui.java new file mode 100644 index 0000000000000000000000000000000000000000..0c09c87545921ea984b353d1b5c20ec8cbf05c4a --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/gui/WalletGui.java @@ -0,0 +1,163 @@ +package fucoin.gui; + +import java.awt.BorderLayout; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JTextField; + + +public class WalletGui implements IWalletGuiControle{ + DefaultListModel<String> log = new DefaultListModel<String>(); + + private JFrame window = new JFrame("test"); + JPanel topPanel = new JPanel(); + JLabel lblMyAddress = new JLabel("My Address:"); + JTextField txtMyAddress = new JTextField("<MyAddress>"); + JLabel lblEmpty = new JLabel(""); + JLabel lblMyAmount = new JLabel("My FUCs"); + JTextField txtMyAmount = new JTextField("<MyFUCs>"); + JPanel centerPanel = new JPanel(); + JLabel lblSendTo = new JLabel("Send to:"); + JComboBox<String> txtSendTo = new JComboBox<String>(); + JLabel lblSendAmount = new JLabel("Amount:"); + JTextField txtSendAmount = new JTextField("<Amount>"); + JButton btnSend = new JButton("Send"); + JButton btnSearch = new JButton("Search"); + JButton btnStore = new JButton("Store"); + JButton btnExit = new JButton("Exit"); + JPanel bottomPanel = new JPanel(); + JList<String> txtLog = new JList<String>(log); + +public WalletGui(IWalletControle walletControle) { + + + window.setSize(400, 600); + window.setLayout(new GridLayout(3, 1)); + topPanel.setLayout(new GridLayout(2, 3)); + // Row 1 + topPanel.add(lblMyAddress); + topPanel.add(txtMyAddress); + topPanel.add(lblEmpty); + // Row 2 + topPanel.add(lblMyAmount); + topPanel.add(txtMyAmount); + window.add(topPanel); + //<hr> + centerPanel.setLayout(new GridLayout(4, 1)); + // Row 1 + JPanel centerup = new JPanel(); + centerup.setLayout(new BorderLayout()); + centerup.add(lblSendTo,BorderLayout.WEST); + centerup.add(txtSendTo,BorderLayout.CENTER); + centerPanel.add(centerup); + + JPanel centerup2 = new JPanel(); + centerup2.setLayout(new BorderLayout()); + JTextField sendToNewEdt = new JTextField(); + centerup2.add(sendToNewEdt,BorderLayout.CENTER); + JButton addNewButton = new JButton("Add"); + addNewButton.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + txtSendTo.addItem(sendToNewEdt.getText()); + } + }); + centerup2.add(addNewButton,BorderLayout.EAST); + centerPanel.add(centerup2); + + // Row 2 + JPanel centerdown = new JPanel(); + centerdown.setLayout(new GridLayout(1, 3)); + centerdown.add(lblSendAmount); + centerdown.add(txtSendAmount); + centerdown.add(btnSend); + centerPanel.add(centerdown); + //centerPanel.add(new JLabel("")); + // Row 3 + JPanel centerdown2 = new JPanel(); + centerdown2.setLayout(new GridLayout(1, 3)); + centerdown2.add(btnSearch); + centerdown2.add(btnStore); + centerdown2.add(btnExit); + centerPanel.add(centerdown2); + window.add(centerPanel); + //<hr> + bottomPanel.setLayout(new GridLayout(1, 1)); + bottomPanel.add(txtLog); + window.add(bottomPanel); + window.setVisible(true); + + btnSend.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + walletControle.send(txtSendTo.getSelectedItem().toString(), Integer.parseInt(txtSendAmount.getText())); + } + }); + + btnStore.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + + } + }); + + btnExit.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + window.dispose(); + } + }); + + window.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosing(WindowEvent e) { + System.out.println("window closing"); + walletControle.leave(); + super.windowClosing(e); + + } + @Override + public void windowClosed(WindowEvent e) { + System.out.println("window closing"); + walletControle.leave(); + super.windowClosing(e); + } + }); +} + +@Override +public void setAddress(String address) { + txtMyAddress.setText(address); + window.setTitle(address); +} +@Override +public void setAmount(int amount) { + txtMyAmount.setText(""+amount); +} + +@Override +public void addKnownAddress(String address) { + + txtSendTo.addItem(address); +} +@Override +public void addLogMsg(String msg) { + log.addElement(msg); +} +} diff --git a/JavaAkkaFuCoin/src/fucoin/supervisor/ActionUpdateQueue.java b/JavaAkkaFuCoin/src/fucoin/supervisor/ActionUpdateQueue.java new file mode 100644 index 0000000000000000000000000000000000000000..82cc40c06210a1b9719b3c62ed7923ac032dc0dd --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/supervisor/ActionUpdateQueue.java @@ -0,0 +1,39 @@ +package fucoin.supervisor; + +import java.util.ArrayList; +import java.util.List; + +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; +import fucoin.actions.transaction.ActionCommitDistributedCommitedTransfer; +import fucoin.actions.transaction.SuperVisorAction; + +public class ActionUpdateQueue extends SuperVisorAction{ + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, SuperVisor superVisor) { + + List<DistributedCommitedTransferRequest> deletes = superVisor.updateList(); + + for(DistributedCommitedTransferRequest outdatedRequest : deletes){ + ActionCommitDistributedCommitedTransfer acdct = new ActionCommitDistributedCommitedTransfer(outdatedRequest); + for(ActorRef neighbor : superVisor.getKnownNeighbors().values()){ + neighbor.tell(acdct, self); + } + } + sleep(self,context,1000); + self.tell(this, self); + } + + private void sleep(ActorRef self, UntypedActorContext context, int sleeptime) { + try { + context.unwatch(self); + Thread.sleep(sleeptime); + context.watch(self); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + +} diff --git a/JavaAkkaFuCoin/src/fucoin/supervisor/AmountTableModel.java b/JavaAkkaFuCoin/src/fucoin/supervisor/AmountTableModel.java new file mode 100644 index 0000000000000000000000000000000000000000..fb91ce4813b9500f700e02f407b49c3df6ae71e5 --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/supervisor/AmountTableModel.java @@ -0,0 +1,15 @@ +package fucoin.supervisor; + +import javax.swing.table.DefaultTableModel; + +public class AmountTableModel extends DefaultTableModel{ +public AmountTableModel() { + super(new Object[]{"Address","Name","Amount"},0); +} + +public void clear() { + while(getRowCount()>0){ + removeRow(0); + } +} +} diff --git a/JavaAkkaFuCoin/src/fucoin/supervisor/DistributedCommitedTransferRequest.java b/JavaAkkaFuCoin/src/fucoin/supervisor/DistributedCommitedTransferRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..a27f873dc259cdcb19986898c5b2d883bd53815a --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/supervisor/DistributedCommitedTransferRequest.java @@ -0,0 +1,58 @@ +package fucoin.supervisor; + +import java.util.LinkedList; +import java.util.List; +import java.util.Random; + +import fucoin.Wallet; +import fucoin.actions.transaction.Transaction; +import akka.actor.ActorRef; +import akka.actor.UntypedActorContext; + +public class DistributedCommitedTransferRequest extends Transaction { + private final static Random random = new Random(System.currentTimeMillis()+System.nanoTime()); + private ActorRef source; + private ActorRef target; + private long timeout; + private long id; + private List<ActorRef> answers = new LinkedList<ActorRef>(); + + public DistributedCommitedTransferRequest(ActorRef source, ActorRef target, + long timeout) { + this.source=source; + this.target=target; + this.timeout=timeout; + this.id=random.nextLong(); + } + + @Override + protected void onAction(ActorRef sender, ActorRef self, + UntypedActorContext context, Wallet wallet) { + + } + + public ActorRef getSource() { + return source; + } + + public ActorRef getTarget() { + return target; + } + + public long getTimeout() { + return timeout; + } + + public int addPositiveAnswer(ActorRef sender) { + answers.add(sender); + return answers.size(); + } + + public List<ActorRef> getAnswers() { + return answers; + } + + public long getId() { + return id; + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/supervisor/SuperVisor.java b/JavaAkkaFuCoin/src/fucoin/supervisor/SuperVisor.java new file mode 100644 index 0000000000000000000000000000000000000000..a6adcaa7fd08f0feb95ae85cd8b92a8ae72a105a --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/supervisor/SuperVisor.java @@ -0,0 +1,96 @@ +package fucoin.supervisor; + +import java.awt.Label; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Queue; +import java.util.concurrent.Semaphore; + +import akka.actor.ActorRef; +import akka.actor.Props; +import fucoin.AbstractNode; +import fucoin.actions.Action; +import fucoin.actions.persist.ActionInvokeUpdate; + +public class SuperVisor extends AbstractNode { + + + private AmountTableModel amountTableModel; + private Label averageamountLbl; + + public SuperVisor(AmountTableModel amountTableModel, Label averageamountLbl) { + this.amountTableModel = amountTableModel; + this.averageamountLbl = averageamountLbl; + } + + @Override + public void onReceive(Object msg) { + log(msg.getClass().getSimpleName()); + + ((Action) msg).doAction(this); + } + + Semaphore mutex = new Semaphore(1); + private Map<Long,DistributedCommitedTransferRequest> requestQueue; + + public static Props props() { + return Props.create(SuperVisor.class, new SuperVisorCreator()); + } + + public void updateValues() { + getSelf().tell(new ActionInvokeUpdate(), getSelf()); + } + + public void exit() { + getContext().stop(getSelf()); + } + + @Override + public void postStop() throws Exception { + super.postStop(); + } + + public void addDistributedCommitedTransferRequest( + DistributedCommitedTransferRequest request) { + requestQueue.put(request.getId(),request); + } + + @Override + public void preStart() throws Exception { + super.preStart(); + requestQueue = new HashMap<Long,DistributedCommitedTransferRequest>(); + self().tell(new ActionUpdateQueue(), self()); + } + /** + * filters the request for outdated and removes them + * @return deleted outdated request + */ + public List<DistributedCommitedTransferRequest> updateList(){ + List<Long> deletesIds = new ArrayList<Long>(); + List<DistributedCommitedTransferRequest> deletes = new ArrayList<DistributedCommitedTransferRequest>(); + for(Entry<Long, DistributedCommitedTransferRequest> outdatedRequest : requestQueue.entrySet()){ + if(outdatedRequest.getValue().getTimeout()<System.currentTimeMillis()){ + deletesIds.add(outdatedRequest.getKey()); + deletes.add(outdatedRequest.getValue()); + } + } + for(Long delete : deletesIds){ + requestQueue.remove(delete); + } + + return deletes; + } + + public DistributedCommitedTransferRequest getRequest(Long id) { + DistributedCommitedTransferRequest searchedrequest = requestQueue.get(id); + return searchedrequest ; + } + + public void deleteRequest(DistributedCommitedTransferRequest request) { + requestQueue.remove(request.getId()); + } +} diff --git a/JavaAkkaFuCoin/src/fucoin/supervisor/SuperVisorCreator.java b/JavaAkkaFuCoin/src/fucoin/supervisor/SuperVisorCreator.java new file mode 100644 index 0000000000000000000000000000000000000000..a67730de47715233853f4bf71a5f6c026193bd8e --- /dev/null +++ b/JavaAkkaFuCoin/src/fucoin/supervisor/SuperVisorCreator.java @@ -0,0 +1,56 @@ +package fucoin.supervisor; + +import java.awt.GridLayout; +import java.awt.Label; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.JTable; + +import akka.japi.Creator; + +public class SuperVisorCreator implements Creator<SuperVisor>{ + + @Override + public SuperVisor create() throws Exception { + + JFrame frame = new JFrame("Server"); + frame.setLayout(new GridLayout(3, 2)); + frame.add(new Label("All Amounts:")); + AmountTableModel amountTableModel = new AmountTableModel(); + JTable amountListView = new JTable(amountTableModel); + frame.add(new JScrollPane(amountListView)); + frame.add(new Label("Average Amounts:")); + Label averageamountLbl = new Label("Average Amounts:"); + frame.add(averageamountLbl); + JButton updateBtn = new JButton("Update"); + JButton exitBtn = new JButton("exit"); + frame.add(updateBtn); + frame.add(exitBtn); + + SuperVisor sv = new SuperVisor(amountTableModel,averageamountLbl); + updateBtn.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + sv.updateValues(); + } + }); + exitBtn.addActionListener(new ActionListener() { + + @Override + public void actionPerformed(ActionEvent e) { + sv.exit(); + frame.setVisible(false); + } + }); + frame.setSize(200, 400); + frame.setVisible(true); + + return sv; + } + +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/1_introduction.aux b/JavaAkkaFuCoin/thesis_latex_template/1_introduction.aux new file mode 100644 index 0000000000000000000000000000000000000000..4e7c83e047663cb3e096a645c7aaf658f599d32d --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/1_introduction.aux @@ -0,0 +1,28 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@writefile{toc}{\contentsline {section}{\numberline {1}Introduction}{1}{section.1}} +\@setckpt{1_introduction}{ +\setcounter{page}{2} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{1} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{1} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{1} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/1_introduction.log b/JavaAkkaFuCoin/thesis_latex_template/1_introduction.log new file mode 100644 index 0000000000000000000000000000000000000000..eef87efd32c2b0bd24e7986ff181ee5ce318bd69 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/1_introduction.log @@ -0,0 +1,38 @@ +This is pdfTeX, Version 3.1415926-2.5-1.40.14 (TeX Live 2013/Debian) (format=pdflatex 2015.7.23) 23 JUL 2015 11:55 +entering extended mode + restricted \write18 enabled. + file:line:error style messages enabled. + %&-line parsing enabled. +**1_introduction.tex +(./1_introduction.tex +LaTeX2e <2011/06/27> +Babel <3.9h> and hyphenation patterns for 7 languages loaded. + +./1_introduction.tex:2: LaTeX Error: Missing \begin{document}. + +See the LaTeX manual or LaTeX Companion for explanation. +Type H <return> for immediate help. + ... + +l.2 W + e have to make sure, that either all operational participants commit the +? +./1_introduction.tex:2: Emergency stop. + ... + +l.2 W + e have to make sure, that either all operational participants commit the +You're in trouble here. Try typing <return> to proceed. +If that doesn't work, type X <return> to quit. + + +Here is how much of TeX's memory you used: + 6 strings out of 494976 + 294 string characters out of 6179137 + 46219 words of memory out of 5000000 + 3331 multiletter control sequences out of 15000+600000 + 3640 words of font info for 14 fonts, out of 8000000 for 9000 + 14 hyphenation exceptions out of 8191 + 5i,0n,4p,94b,14s stack positions out of 5000i,500n,10000p,200000b,80000s +./1_introduction.tex:2: ==> Fatal error occurred, no output PDF file produced! + diff --git a/JavaAkkaFuCoin/thesis_latex_template/1_introduction.tex b/JavaAkkaFuCoin/thesis_latex_template/1_introduction.tex new file mode 100644 index 0000000000000000000000000000000000000000..fb3316096ed80a5dd8897ec8e146b9c1ee07292b --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/1_introduction.tex @@ -0,0 +1,18 @@ +\section{Introduction} +For a transaction in the FUCoin system we have to make sure, that either +all operational participants commit the transaction or none of them. +Each participant has one of two votes for the possible transaction: YES +or NO. For the transaction to happen all participants have to vote YES, +so a decision cannot be reversed. The init participant acts as the +coordinator and sends a 'vote request' to all other participants. After +a participant receives this request, it responds with either YES or NO. +In case of NO the decision is already 'Abort'. If all participants vote +YES, the coordinator decides 'Commit' and sends a commit message to all +participants. Otherwise it sends an abort message to all participants +that voted YES. +\bigskip +\\ +\\ +\\ +\\ +\includegraphics[width=1.0\textwidth]{pictures/TimelineCorrectTransfer.pdf} diff --git a/JavaAkkaFuCoin/thesis_latex_template/1_introduction.tex~ b/JavaAkkaFuCoin/thesis_latex_template/1_introduction.tex~ new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/JavaAkkaFuCoin/thesis_latex_template/2_actioninvokesentmoney.aux b/JavaAkkaFuCoin/thesis_latex_template/2_actioninvokesentmoney.aux new file mode 100644 index 0000000000000000000000000000000000000000..acd3d5e16eadd20f666c00fd6d484ccec3c4bd60 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/2_actioninvokesentmoney.aux @@ -0,0 +1,28 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@writefile{toc}{\contentsline {section}{\numberline {2}ActionInvokeSentMoney}{2}{section.2}} +\@setckpt{2_actioninvokesentmoney}{ +\setcounter{page}{3} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{2} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{17} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{2} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/2_actioninvokesentmoney.tex b/JavaAkkaFuCoin/thesis_latex_template/2_actioninvokesentmoney.tex new file mode 100644 index 0000000000000000000000000000000000000000..db95e75a8bd855ae8da5164aa60b1991694fd907 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/2_actioninvokesentmoney.tex @@ -0,0 +1,26 @@ +\section{ActionInvokeSentMoney} +This action is invoked by the graphical user interface of the wallets. +The goal is to transfer an amount of FUCoins to a given wallet ID. +If this ID already has a mapping to an ActorRef, an +ActionInvokeDistributedCommitedTransfer will be send to the supervisor. +Otherwise a gossip is invoked using the ActionSearchWalletReference +following by ActionInvokeSentMoney after 200 ms. +\\ +\begin{lstlisting} +protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, + Wallet wallet) { + log(wallet.getKnownNeighbors()+""); + if(wallet.getKnownNeighbors().containsKey(name)){ + wallet.getRemoteSuperVisorActor().tell( + new ActionInvokeDistributedCommitedTransfer(self, + wallet.getKnownNeighbors().get(name), amount), sender); + }else{ + ActionSearchWalletReference aswr = new ActionSearchWalletReference(name); + for(ActorRef neighbor : wallet.getKnownNeighbors().values()){ + neighbor.tell(aswr, self); + } + sleep(self, context, 200); + self.tell(this, self); + } +} +\end{lstlisting} diff --git a/JavaAkkaFuCoin/thesis_latex_template/2_fundamentals.aux b/JavaAkkaFuCoin/thesis_latex_template/2_fundamentals.aux new file mode 100644 index 0000000000000000000000000000000000000000..a1643637f3a177fbf004ca7df18b6897d0c6f6ba --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/2_fundamentals.aux @@ -0,0 +1,27 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@setckpt{2_fundamentals}{ +\setcounter{page}{6} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{7} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{15} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{7} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/2_fundamentals.tex b/JavaAkkaFuCoin/thesis_latex_template/2_fundamentals.tex new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/JavaAkkaFuCoin/thesis_latex_template/3_actioninvokedistributedcommitedtransfer.aux b/JavaAkkaFuCoin/thesis_latex_template/3_actioninvokedistributedcommitedtransfer.aux new file mode 100644 index 0000000000000000000000000000000000000000..ee69f90dbe50d2e89dd16938ebbb4d79b79f937c --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/3_actioninvokedistributedcommitedtransfer.aux @@ -0,0 +1,28 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@writefile{toc}{\contentsline {section}{\numberline {3}ActionInvokeDistributedCommitedTransfer}{3}{section.3}} +\@setckpt{3_actioninvokedistributedcommitedtransfer}{ +\setcounter{page}{4} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{3} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{16} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{3} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/3_actioninvokedistributedcommitedtransfer.tex b/JavaAkkaFuCoin/thesis_latex_template/3_actioninvokedistributedcommitedtransfer.tex new file mode 100644 index 0000000000000000000000000000000000000000..6744be3cbc93e4cd517b5e5d7bd30bc62b5f08a2 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/3_actioninvokedistributedcommitedtransfer.tex @@ -0,0 +1,26 @@ +\section{ActionInvokeDistributedCommitedTransfer} +The ActionInvokeDistributedCommitedTransfer creates a +DistributedCommitedTransferRequest, which contains a random generated +ID, on the Server with a timout of 500 ms, and stores this to a map +Long --> Request accoring to the ID. The Timeout is handled by the +ActionUpdateQueue explained later. The request will spread out to all +clients that can answer with an acknowledgement or an abort afterwards +(see below). +\\ +\begin{lstlisting} +protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, + SuperVisor superVisor) { + log("invoke transaction "+source.path().name()+" sends "+amount+" to " + +target.path().name()); + long timeout = System.currentTimeMillis()+500; + DistributedCommitedTransferRequest ds = + new DistributedCommitedTransferRequest(source,target,timeout); + superVisor.addDistributedCommitedTransferRequest(ds); + ActionPrepareDistributedCommitedTransfer apdct = + new ActionPrepareDistributedCommitedTransfer(source, target, amount, timeout, + ds.getId()); + for(ActorRef neighbor : superVisor.getKnownNeighbors().values()){ + neighbor.tell(apdct, self); + } +} +\end{lstlisting} diff --git a/JavaAkkaFuCoin/thesis_latex_template/3_main.aux b/JavaAkkaFuCoin/thesis_latex_template/3_main.aux new file mode 100644 index 0000000000000000000000000000000000000000..6628d8fdb70a68161fa88be6893e3e5da03bebfa --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/3_main.aux @@ -0,0 +1,27 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@setckpt{3_main}{ +\setcounter{page}{6} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{7} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{15} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{7} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/3_main.tex b/JavaAkkaFuCoin/thesis_latex_template/3_main.tex new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/JavaAkkaFuCoin/thesis_latex_template/4_actionpreparedistributedcommitedtransfer.aux b/JavaAkkaFuCoin/thesis_latex_template/4_actionpreparedistributedcommitedtransfer.aux new file mode 100644 index 0000000000000000000000000000000000000000..08a5abebe37c40498dacf7b42eace75ec9d18a61 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/4_actionpreparedistributedcommitedtransfer.aux @@ -0,0 +1,28 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@writefile{toc}{\contentsline {section}{\numberline {4}ActionPrepareDistributedCommitedTransfer}{4}{section.4}} +\@setckpt{4_actionpreparedistributedcommitedtransfer}{ +\setcounter{page}{5} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{4} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{12} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{4} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/4_actionpreparedistributedcommitedtransfer.tex b/JavaAkkaFuCoin/thesis_latex_template/4_actionpreparedistributedcommitedtransfer.tex new file mode 100644 index 0000000000000000000000000000000000000000..b04a45511affaa587addedde841eec290b8e8135 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/4_actionpreparedistributedcommitedtransfer.tex @@ -0,0 +1,19 @@ +\section{ActionPrepareDistributedCommitedTransfer} +The clients will reply to a request with an acknowlegment if one of two +cases occur. In the first case the Supervisor (bank) will send FUCoins +to a user. Otherwise the client would need to know the sender, who also +needs to have sufficient funds. +\\ +\begin{lstlisting} +protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, + Wallet wallet) { + // sender is supervisor (bank) and always has funds + boolean granted = sender.compareTo(source) == 0 + // sender is unknown, might be valid + ||(wallet.amounts.containsKey(source) + // sender have enough money + &&wallet.amounts.getOrDefault(source,0)>=amount); + sender.tell(new ActionPrepareDistributedCommitedTransferAnswer (source, target, + amount, timestamp, granted, id), self); +} +\end{lstlisting} diff --git a/JavaAkkaFuCoin/thesis_latex_template/4_conclusion.aux b/JavaAkkaFuCoin/thesis_latex_template/4_conclusion.aux new file mode 100644 index 0000000000000000000000000000000000000000..9ad61f2f649eda7a91702b4a5989ca45f754c7cc --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/4_conclusion.aux @@ -0,0 +1,27 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@setckpt{4_conclusion}{ +\setcounter{page}{6} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{7} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{15} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{7} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/4_conclusion.tex b/JavaAkkaFuCoin/thesis_latex_template/4_conclusion.tex new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/JavaAkkaFuCoin/thesis_latex_template/5_actionpreparedistributedcommitedtransferanswer.aux b/JavaAkkaFuCoin/thesis_latex_template/5_actionpreparedistributedcommitedtransferanswer.aux new file mode 100644 index 0000000000000000000000000000000000000000..1c733211d168097ac0a2d661219c55f0b77cc071 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/5_actionpreparedistributedcommitedtransferanswer.aux @@ -0,0 +1,28 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@writefile{toc}{\contentsline {section}{\numberline {5}ActionPrepareDistributedCommitedTransferAnswer}{5}{section.5}} +\@setckpt{5_actionpreparedistributedcommitedtransferanswer}{ +\setcounter{page}{6} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{5} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{31} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{5} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/5_actionpreparedistributedcommitedtransferanswer.tex b/JavaAkkaFuCoin/thesis_latex_template/5_actionpreparedistributedcommitedtransferanswer.tex new file mode 100644 index 0000000000000000000000000000000000000000..110224f62b380407859292bc7e8242dbf7818d4d --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/5_actionpreparedistributedcommitedtransferanswer.tex @@ -0,0 +1,41 @@ +\section{ActionPrepareDistributedCommitedTransferAnswer} +After an answer from a client reached the server, the server tries to +find the corresponding request. If the answer was a acknowlegement, the +request will get another positive answer. When the same amount of +positive answers equals the count of known neighbors received on the +server, all client will be informed to commit the change and the +request will be deleted. If the answer was an abort, all clients will be +informed to abort the transaction. +\\ +\begin{lstlisting} +protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, + SuperVisor superVisor) { + log(""+superVisor.getKnownNeighbors()); + log("granted?"+granted); + DistributedCommitedTransferRequest request = superVisor.getRequest(id); + if(granted){ + if(request==null) //unknown DistributedCommitedTransferRequest ignore + return; + int newCount = request.addPositiveAnswer(sender); + if(newCount == superVisor.getKnownNeighbors().size()){ + ActionCommitDistributedCommitedTransfer acdct = + new ActionCommitDistributedCommitedTransfer(source, target, amount, true, + timestamp, id); + for(ActorRef neighbor : request.getAnswers()){ + neighbor.tell(acdct, self); + } + superVisor.deleteRequest(request); + } + }else{ + // A client wants to rollback + if(request!=null){ + ActionCommitDistributedCommitedTransfer acdct = + new ActionCommitDistributedCommitedTransfer(source, target, amount, false, + timestamp, id); + for(ActorRef neighbor : request.getAnswers()){ + neighbor.tell(acdct, self); + } + } + } +} +\end{lstlisting} diff --git a/JavaAkkaFuCoin/thesis_latex_template/5_appendix.aux b/JavaAkkaFuCoin/thesis_latex_template/5_appendix.aux new file mode 100644 index 0000000000000000000000000000000000000000..4bc2db3dc5030e3a72a5c466d7eb5e0f9f0934f4 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/5_appendix.aux @@ -0,0 +1,27 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@setckpt{5_appendix}{ +\setcounter{page}{6} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{7} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{15} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{7} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/5_appendix.tex b/JavaAkkaFuCoin/thesis_latex_template/5_appendix.tex new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/JavaAkkaFuCoin/thesis_latex_template/6_actioncommitdistributedcommitedtransfer.aux b/JavaAkkaFuCoin/thesis_latex_template/6_actioncommitdistributedcommitedtransfer.aux new file mode 100644 index 0000000000000000000000000000000000000000..4f09358d62547d5f2ac8dd3f425a0658762d8083 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/6_actioncommitdistributedcommitedtransfer.aux @@ -0,0 +1,28 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@writefile{toc}{\contentsline {section}{\numberline {6}ActionCommitDistributedCommitedTransfer}{6}{section.6}} +\@setckpt{6_actioncommitdistributedcommitedtransfer}{ +\setcounter{page}{7} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{6} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{19} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{6} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/6_actioncommitdistributedcommitedtransfer.tex b/JavaAkkaFuCoin/thesis_latex_template/6_actioncommitdistributedcommitedtransfer.tex new file mode 100644 index 0000000000000000000000000000000000000000..da00c1abb00964ed8af3a86e0f1e70833235a369 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/6_actioncommitdistributedcommitedtransfer.tex @@ -0,0 +1,25 @@ +\section{ActionCommitDistributedCommitedTransfer} +If a client has to commit the given changes, it will perform the +transaction on the amounts map. Otherwise it will just print an abort +transaction message. +\\ +\begin{lstlisting} +protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, + Wallet wallet) { + log("ActionCommitDistributedCommitedTransfer is granted?"+granted); + if(granted){ + Integer sourceAmount = wallet.amounts.getOrDefault(source,0); + Integer targetAmount = wallet.amounts.getOrDefault(target,0); + wallet.amounts.put(source,sourceAmount-amount); + wallet.amounts.put(target,targetAmount+amount); + if(source.compareTo(self)==0) + wallet.amount-=amount; + else if(target.compareTo(self)==0) + wallet.amount+=amount; + wallet.log("have now "+wallet.amounts.get(self)+" Fucoins"); + }else{ + log("abort transaction with id"+id); + } + log("wallet.amounts:"+wallet.amounts); +} +\end{lstlisting} diff --git a/JavaAkkaFuCoin/thesis_latex_template/7_actionupdatequeue.aux b/JavaAkkaFuCoin/thesis_latex_template/7_actionupdatequeue.aux new file mode 100644 index 0000000000000000000000000000000000000000..cb8e5d5418b1ca6d966dad8fee1716e288f2f701 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/7_actionupdatequeue.aux @@ -0,0 +1,28 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@writefile{toc}{\contentsline {section}{\numberline {7}ActionUpdateQueue}{7}{section.7}} +\@setckpt{7_actionupdatequeue}{ +\setcounter{page}{8} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{7} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{14} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{7} +\setcounter{lstlisting}{0} +\setcounter{section@level}{1} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/7_actionupdatequeue.tex b/JavaAkkaFuCoin/thesis_latex_template/7_actionupdatequeue.tex new file mode 100644 index 0000000000000000000000000000000000000000..e03fd167cdd37a06c75bd10db7ffa2de033b60b1 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/7_actionupdatequeue.tex @@ -0,0 +1,20 @@ +\section{ActionUpdateQueue} +The ActionUpdateQueue event will be invoked each second on the server +and remove all outdated request. If a request is deleted, all clients +will be informed to abort this transaction. +\\ +\begin{lstlisting} +protected void onAction(ActorRef sender, ActorRef self, UntypedActorContext context, + SuperVisor superVisor) { + List<DistributedCommitedTransferRequest> deletes = superVisor.updateList(); + for(DistributedCommitedTransferRequest outdatedRequest : deletes){ + ActionCommitDistributedCommitedTransfer acdct = + new ActionCommitDistributedCommitedTransfer(outdatedRequest); + for(ActorRef neighbor : superVisor.getKnownNeighbors().values()){ + neighbor.tell(acdct, self); + } + } + sleep(self,context,1000); + self.tell(this, self); +} +\end{lstlisting} diff --git a/JavaAkkaFuCoin/thesis_latex_template/bibliography.bib b/JavaAkkaFuCoin/thesis_latex_template/bibliography.bib new file mode 100644 index 0000000000000000000000000000000000000000..cd4333e6f755b9ccbe4d8feb416232e13d7e79cc --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/bibliography.bib @@ -0,0 +1,111 @@ +% This file was created with JabRef 2.5. +% Encoding: Cp1252 + +@INPROCEEDINGS{DjeOezSal07, + author = {Riad Djemili and Christopher Oezbek and Stephan Salinger}, + title = {{Saros: Eine Eclipse-Erweiterung zur verteilten Paarprogrammierung.}}, + booktitle = {Software Engineering (Workshops)}, + year = {2007}, + editor = {Wolf-Gideon Bleek and Henning Schwentner and Heinz Züllighoven}, + volume = {106}, + series = {LNI}, + pages = {317-320}, + publisher = {GI}, + crossref = {conf/se/2007w}, + date = {2007-09-20}, + interhash = {6a3ff0533f42dc6bf9e882ddad44c477}, + intrahash = {4b914fb7bf85efa120c9b0d76261b666}, + isbn = {978-3-88579-200-0}, + url = {http://www.inf.fu-berlin.de/inst/ag-se/pubs/saros-2007.pdf} +} + +@INPROCEEDINGS{CocWil00, + author = {Alistair Cockburn and Laurie Williams}, + title = {{The Costs and Benefits of Pair Programming}}, + booktitle = {eXtreme Programming and Flexible Processes in Software Engineering + XP2000}, + year = {2000}, + pages = {223--247}, + publisher = {Addison-Wesley} +} + +@MASTERSTHESIS{Dje06, + author = {R. Djemili}, + title = {{Entwicklung einer Eclipse-Erweiterung zur Realisierung und Protokollierungverteilter + Paarprogrammierung}}, + school = {Freie Universität Berlin, Inst. für Informatik}, + year = {2006} +} + +@MISC{FowlerM04b, + author = {Fowler, Martin}, + title = {{Inversion of Control Containers and the Dependency Injection pattern}}, + howpublished = {\url{http://www.martinfowler.com/articles/injection.html}}, + month = jan, + year = {2004}, + url = {\url{http://www.martinfowler.com/articles/injection.html}} +} + +@BOOK{GOF95, + title = {Design patterns: elements of reusable object-oriented software}, + publisher = {Addison-Wesley Professional}, + year = {1995}, + author = {Gamma, Erich and Helm, Richard and Johnson, Ralph and Vlissides, + John}, + citeulike-article-id = {430671}, + keywords = {semwiki}, + posted-at = {2005-12-08 12:16:10}, + priority = {0} +} + +@MISC{DPPII, + author = {Björn Gustavs}, + title = {{Weiterentwicklung des Eclipse-Plug-Ins Saros zur Verteilten Paarprogrammierung}}, + howpublished = {\url{http://www.inf.fu-berlin.de/inst/ag-se/theses/Gustavs_Saros_DPPII.pdf}}, + month = oct, + year = {2007} +} + +@MASTERSTHESIS{DPPIV, + author = {Christoph Jacob}, + title = {{Weiterentwicklung eines Werkzeuges zur verteilten, kollaborativen + Softwareentwicklung}}, + school = {Freie Universität Berlin}, + year = {2009} +} + +@ELECTRONIC{Plonka, + author = {Laura Plonka}, + title = {{Analysis of Professional Pair Programmers}}, + howpublished = {\url{https://www.inf.fu-berlin.de/w/SE/AnalysisOfProfessionalPairProgrammers}}, + organization = {Freie Universität Berlin}, + url = {\url{https://www.inf.fu-berlin.de/w/SE/AnalysisOfProfessionalPairProgrammers}}, + timestamp = {2009.07.31} +} + +@MASTERSTHESIS{DPPIII, + author = {Oliver Rieger}, + title = {{Weiterentwicklung einer Eclipse-Erweiterung für verteilte Paar-Programmierung + im Hinblick auf Kollaboration und Kommunikation}}, + school = {Freie Universität Berlin}, + year = {2008} +} + +@MISC{DPPV, + author = {Marc Rintsch}, + title = {{Agile Weiterentwicklung eines Software-Werkzeuges zur verteilten + Paarprogrammierung}}, + howpublished = {\url{https://www.mi.fu-berlin.de/wiki/pub/Main/MarcRintsch/studienarbeit.pdf}}, + month = jun, + year = {2009}, + url = {\url{https://www.mi.fu-berlin.de/wiki/pub/Main/MarcRintsch/studienarbeit.pdf}} +} + +@MISC{Rosen, + author = {Edna Rosen}, + title = {{Bewertung verteilter Paarprogrammierung im betrieblichen Umfeld}}, + howpublished = {\url{https://www.inf.fu-berlin.de/w/SE/ThesisDPPManagement}}, + year = {2009}, + timestamp = {2009.07.30} +} + diff --git a/JavaAkkaFuCoin/thesis_latex_template/declaration.aux b/JavaAkkaFuCoin/thesis_latex_template/declaration.aux new file mode 100644 index 0000000000000000000000000000000000000000..ad17f0e8c5ce1a0229f2aad4af3d21f4fffa33a5 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/declaration.aux @@ -0,0 +1,27 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\@setckpt{declaration}{ +\setcounter{page}{2} +\setcounter{equation}{0} +\setcounter{enumi}{0} +\setcounter{enumii}{0} +\setcounter{enumiii}{0} +\setcounter{enumiv}{0} +\setcounter{footnote}{0} +\setcounter{mpfootnote}{0} +\setcounter{part}{0} +\setcounter{section}{0} +\setcounter{subsection}{0} +\setcounter{subsubsection}{0} +\setcounter{paragraph}{0} +\setcounter{subparagraph}{0} +\setcounter{figure}{0} +\setcounter{table}{0} +\setcounter{vrcnt}{0} +\setcounter{lstnumber}{1} +\setcounter{Item}{0} +\setcounter{Hfootnote}{0} +\setcounter{bookmark@seq@number}{0} +\setcounter{lstlisting}{0} +\setcounter{section@level}{0} +} diff --git a/JavaAkkaFuCoin/thesis_latex_template/declaration.tex b/JavaAkkaFuCoin/thesis_latex_template/declaration.tex new file mode 100644 index 0000000000000000000000000000000000000000..a0cefc7cc2f8fc7bbf8fc8551d159e808c4425e0 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/declaration.tex @@ -0,0 +1,6 @@ +\subsection*{Eidesstattliche Erklärung} + +Ich versichere hiermit an Eides Statt, dass diese Arbeit von niemand anderem als meiner Person verfasst worden ist. Alle verwendeten Hilfsmittel wie Berichte, Bücher, Internetseiten oder ähnliches sind im Literaturverzeichnis angegeben, Zitate aus fremden Arbeiten sind als solche kenntlich gemacht. Die Arbeit wurde bisher in gleicher oder ähnlicher Form keiner anderen Prüfungskommission vorgelegt und auch nicht veröffentlicht. +\parbig +<Datum> \\\\ +<Name> \ No newline at end of file diff --git a/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.graphml b/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.graphml new file mode 100644 index 0000000000000000000000000000000000000000..e750b6954466a579c60e8a9600eb779dc5363770 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.graphml @@ -0,0 +1,489 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:java="http://www.yworks.com/xml/yfiles-common/1.0/java" xmlns:sys="http://www.yworks.com/xml/yfiles-common/markup/primitives/2.0" xmlns:x="http://www.yworks.com/xml/yfiles-common/markup/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:y="http://www.yworks.com/xml/graphml" xmlns:yed="http://www.yworks.com/xml/yed/3" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://www.yworks.com/xml/schema/graphml/1.1/ygraphml.xsd"> + <!--Created by yEd 3.14.2--> + <key attr.name="Beschreibung" attr.type="string" for="graph" id="d0"/> + <key for="port" id="d1" yfiles.type="portgraphics"/> + <key for="port" id="d2" yfiles.type="portgeometry"/> + <key for="port" id="d3" yfiles.type="portuserdata"/> + <key attr.name="url" attr.type="string" for="node" id="d4"/> + <key attr.name="description" attr.type="string" for="node" id="d5"/> + <key for="node" id="d6" yfiles.type="nodegraphics"/> + <key for="graphml" id="d7" yfiles.type="resources"/> + <key attr.name="url" attr.type="string" for="edge" id="d8"/> + <key attr.name="description" attr.type="string" for="edge" id="d9"/> + <key for="edge" id="d10" yfiles.type="edgegraphics"/> + <graph edgedefault="directed" id="G"> + <data key="d0"/> + <node id="n0"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="75.0" x="15.833333333333286" y="-7.6666666666667425"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="68.119140625" x="3.4404296875" y="6.015625">Supervisor<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n1"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="75.0" x="15.833333333333286" y="354.66666666666663"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="68.119140625" x="3.4404296875" y="6.015625">Supervisor<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n2"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="75.0" x="-283.66666666666674" y="-7.6666666666667425"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="41.974609375" x="16.5126953125" y="6.015625">Wallet<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n3"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="75.0" x="-283.66666666666674" y="403.6666666666666"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="41.974609375" x="16.5126953125" y="6.015625">Wallet<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n4"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="185.0" x="-338.66666666666674" y="52.33333333333326"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="148.80859375" x="18.095703125" y="6.015625">ActionInvokeSentMoney<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n5"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="290.6666666666667" x="-92.00000000000006" y="111.83333333333326"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="260.59375" x="15.036458333333343" y="6.015625">ActionInvokeDistributedCommitedTransfer<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n6"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="282.3333333333333" x="-387.33333333333337" y="191.8333333333333"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="267.513671875" x="7.409830729166629" y="6.015625">ActionPrepareDistributedCommitedTransfer<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n7"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="316.6666666666667" x="-105.00000000000006" y="231.33333333333326"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="311.7109375" x="2.477864583333343" y="6.015625">ActionPrepareDistributedCommitedTransferAnswer<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n8"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="282.3333333333333" x="-389.0" y="343.6666666666666"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="267.8125" x="7.260416666666629" y="6.015625">ActionCommitDistributedCommitedTransfer<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n9"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="75.0" x="346.9999999999999" y="-7.6666666666667425"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="49.609375" x="12.6953125" y="6.015625">Wallet2<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n10"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="75.0" x="345.33333333333326" y="482.66666666666663"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="49.609375" x="12.6953125" y="6.015625">Wallet2<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n11"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="282.3333333333333" x="243.33333333333326" y="265.16666666666663"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="267.513671875" x="7.409830729166629" y="6.015625">ActionPrepareDistributedCommitedTransfer<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n12"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="282.3333333333333" x="241.66666666666663" y="354.66666666666663"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="267.8125" x="7.260416666666629" y="6.015625">ActionCommitDistributedCommitedTransfer<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <node id="n13"> + <data key="d5"/> + <data key="d6"> + <y:ShapeNode> + <y:Geometry height="30.0" width="316.6666666666667" x="-105.00000000000006" y="302.66666666666646"/> + <y:Fill color="#FFCC00" transparent="false"/> + <y:BorderStyle color="#000000" type="line" width="1.0"/> + <y:NodeLabel alignment="center" autoSizePolicy="content" fontFamily="Dialog" fontSize="12" fontStyle="plain" hasBackgroundColor="false" hasLineColor="false" height="17.96875" modelName="custom" textColor="#000000" visible="true" width="311.7109375" x="2.477864583333343" y="6.015625">ActionPrepareDistributedCommitedTransferAnswer<y:LabelModel> + <y:SmartNodeLabelModel distance="4.0"/> + </y:LabelModel> + <y:ModelParameter> + <y:SmartNodeLabelModelParameter labelRatioX="0.0" labelRatioY="0.0" nodeRatioX="0.0" nodeRatioY="0.0" offsetX="0.0" offsetY="0.0" upX="0.0" upY="-1.0"/> + </y:ModelParameter> + </y:NodeLabel> + <y:Shape type="rectangle"/> + </y:ShapeNode> + </data> + </node> + <edge id="e0" source="n4" target="n5"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="-100.66666666666677" ty="0.0"> + <y:Point x="-47.333333333333485" y="67.33333333333326"/> + <y:Point x="-47.333333333333485" y="97.83333333333329"/> + </y:Path> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e1" source="n5" target="n6"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="100.16666666666666" ty="-5.666666666666657"> + <y:Point x="-146.00000000000009" y="126.83333333333326"/> + <y:Point x="-146.00000000000006" y="171.8333333333333"/> + </y:Path> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e2" source="n6" target="n7"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="-111.66666666666677" ty="0.0"> + <y:Point x="-58.333333333333485" y="206.8333333333333"/> + <y:Point x="-58.333333333333485" y="206.8333333333333"/> + <y:Point x="-58.333333333333485" y="206.8333333333333"/> + </y:Path> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e3" source="n13" target="n8"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="80.83333333333329" ty="-15.023437499999943"> + <y:Point x="-167.00000000000006" y="317.66666666666646"/> + </y:Path> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e4" source="n5" target="n11"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="-79.83333333333314" ty="0.0"> + <y:Point x="304.66666666666674" y="126.83333333333326"/> + </y:Path> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e5" source="n11" target="n13"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="97.3333333333332" ty="2.5000000000001705"> + <y:Point x="150.6666666666665" y="280.16666666666663"/> + </y:Path> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e6" source="n13" target="n12"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="13.3333333333332" sy="-2.4999999999998295" tx="-87.16666666666652" ty="1.5"> + <y:Point x="295.66666666666674" y="315.16666666666663"/> + </y:Path> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e7" source="n9" target="n11"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-5.852150537634316"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e8" source="n11" target="n12"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="1.6666666666666288" ty="6.567204301075321"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e9" source="n12" target="n10"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e10" source="n2" target="n4"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e11" source="n4" target="n6"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="-2.8421709430404007E-14" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e12" source="n6" target="n8"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="1.6666666666666288" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e13" source="n8" target="n3"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e14" source="n0" target="n5"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="-8.986559139784845"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e15" source="n5" target="n7"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e16" source="n7" target="n13"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="8.325268817204517"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + <edge id="e17" source="n13" target="n1"> + <data key="d9"/> + <data key="d10"> + <y:PolyLineEdge> + <y:Path sx="0.0" sy="0.0" tx="0.0" ty="0.0"/> + <y:LineStyle color="#000000" type="line" width="1.0"/> + <y:Arrows source="none" target="standard"/> + <y:BendStyle smoothed="false"/> + </y:PolyLineEdge> + </data> + </edge> + </graph> + <data key="d7"> + <y:Resources/> + </data> +</graphml> diff --git a/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.pdf b/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.pdf new file mode 100644 index 0000000000000000000000000000000000000000..f0998dc5a1b0a4d35f58311ca657ce6738162b8f --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.pdf @@ -0,0 +1,1179 @@ +%PDF-1.4 +%âãÏÓ +1 0 obj + << + /Title () + /Author () + /Subject () + /Keywords () + /Creator (yExport 1.5) + /Producer (org.freehep.graphicsio.pdf.YPDFGraphics2D 1.5) + /CreationDate (D:20150724154746+02'00') + /ModDate (D:20150724154746+02'00') + /Trapped /False + >> +endobj +2 0 obj + << + /Type /Catalog + /Pages 3 0 R + /ViewerPreferences 4 0 R + /OpenAction [5 0 R /Fit] + >> +endobj +4 0 obj + << + /FitWindow true + /CenterWindow false + >> +endobj +5 0 obj + << + /Parent 3 0 R + /Type /Page + /Contents 6 0 R + >> +endobj +6 0 obj + << + /Length 7 0 R + /Filter [/ASCII85Decode /FlateDecode] + >> +stream +Gb!!k]<5a-O"H[dVcYUVQ`'7LkfA:*'A*d7)[6"Y:hBFmrdZlG+=YQRD&=u'mt7cR'raut&k,[18P7md +rqH)urqr<n?u(;-If9*.s8)'[_`rXQg:e*qgL7/Rqlb2W^]4/>^])j"rf>m\J+qk#r]gGMInO/Kp&Fi$ +df01%s7N#Ss7?9[=8F<B59b<4s/5mOhtj.nkL`"5o1;$kk$LR9s'K(3s8$_`.U(-ZgO=Ot1VJ7*JtE!u +ht6j$)Z/8mqt!mikskSo7*ANhnL?a7VoldQotUMcS)f(PO$AEin"5=&q(^fW`+-UMH^=6qp\=0i&+J6C +6Mu!pcJN45q<^%'iD\^m3<da\s1!D[gP5^N?[9,lqUZd&Icg'h_=]mLOnQ7BSEntlX3^=$qtJ<G6h=Fg +:sF8Qj*BA1YJ3!njL!mS;YnQ'],/t5V)LYb</:0clZ^[QFFUKeB()^MmUN!Ih$ed;^?[,]rf*3*2E0.4 +j+,_9h<&VV\*l'jB<[?#+]<2FrQ-"I^"RDfrp&oocg1a[fY;LE89^!RfhfL1m,)8/A]#8?q2MYfZo6]D +cX3/6C#f`*[OJJT[d)Jshp)sZpL6aC_dh4[YOaj=nMS&hIUpgZI2G>d'tj*TI^at[l1o4F!nsFG8mjNO +pY7%HE(.D+HgO"5BG2!VT7&agHIr+f;u5j`!>7h*A%O<?dH-demI%,n4p9CoPW*VM8J!jhs&SXcSoar- +%CjZ9*iG=6Jm&@X>30rd*B$mKU[P:h!#tn&VDt5KUAog9s&N?g@a:k7nrO@iTtKYZQd,)h>e5*D[:^sP +#9khk[t*Z9.(,5QGCt6[eg,ntRX6HZlaLHsm%0DR0$nrcQ:G8Lr4S5>od'(Yk0L_k`ciF<@M?C5gP5=b +Mfbq.6X4c,E#[`3\lk@Vc+S`CLJ"2p;YqM;YlR!dHmuRS(G%_jN66:M*^XpW[H?9O>=Th.VG8FmVZE_n +g9eNpMaO3t(/U7$gO"$XJhCU\5V!A?G=(,j(W2S2N;XKo^mBHE[:NFr]`!B\kA$5@K(jT7PW7dXCUsCo +VcIZMCK#E*]qio&>VG$c%2JD;DOB5h[l&R3ChP]s)qJTBc8Ae%V,2J`l)*!A9<Ba1;e;q\lcZ0]DJAJQ +^"V(m^_^e4D&NmYT1ssaGhR@iNE7f7gB+;*msi+`=@oaera'X/g#u\A8J!0<L:6<N0b(SA[ZoSmL6+,- +YT\giO:VSB6GV\+n!FM3=L+/Y94N8n"gjG0#.G!`&&.0B1QLp9bifo!A)8p5Za-QAlZl.3565['+W<V? +5!Rsm6iHutDAPDo+)IN$C%KPTrHihY'jJJBCPt@Rp6#"%nDoHN^X^S$ZZoh91q'nQkgs/VKWS)YMDhW^ +9umbQ66hW,[BObVSVenDVE3c=pK<-Wm,,ui^BM:"6`UN=[Pp!X(OW5Hkc:*B/]"MY2N-/DQt%(pc`ot) +g`\]uh@Z$CZU@)uh-TsHq8++Q8=mjlnAjK>s3fbL2j=Llg41$nI@OM.J.gWBd-(=7[[o(ETooo4XckO; +'.H#]?ELm`%GoIgO1cldgn3%JqHU=UebX)F1+4Pgn<0)J2><])+UcdPl/1"rHkiF6qht+Qo<Dkep"(=H +%AWGkNRV\]*MQi7P'tk/BK^[j(DLcu3#&t:<p1W\k?c+@C1G6^e6_XE=J]i-pAM*##r_M(2Up5Lj41gn +%dqh`=/gPSBkPFl<[YE*U&E_?\^mKspK',Y01&mhA35_:DN:cYjMme@c&Im&"]P8*mpmLIg3#B[:VQpK +c&DS2s.H26WN!)PblH7$QG2rQVV_gS\?4]c%=uZ7:$a`>cAL<1o<>Ug/U>f]mr96bFul"CA#PI#%p\ju +L0LT5LSf7^rEI+MFXT8KflO7oL>CgO%@r`&ag(MjB8';&cttG(Z[$U3RBnkoOC#PSRmt`@8g4LsL(Dj@ +Jj*Q^ZKJZ_p@[PiY2RV7e5<0^r#n0&5EM<Ql46p4U[[,f1a1+K@SO3:h7D-1MO1Z(-YF[Tn/bGTSg`Fn +8Jq?CWWacY`?)?eTZi$G9fiA<9V(K@>LO]bBCpBu5FV8Gs4CBk1rJVU^`UAR=`+8I:/9FQFO^g`m.2&- +X0HC;C`$CAL.9!t[rMHR!./G,rpAQf>)Uho;@+:YX"KYM2>gK[.OBJFQrMe^F[2F&ZB>V+?(bcrK-,(! +HhR>4\7ps0gHJ`OHFC<o[bLmt9RH^j)\^0:VUaW"9CL/KTZnI3-QD]q-V?<DCEg-JTQ2CZ:5t)G(19[E +bXg_pY_Fi=/=WrVhXbA93k-)U7L/=f1ZC!G[6cb1^@gNl:3eMJc47LRG"NQ>2db0W_6<=$#JF#>NuiC^ +`hfjW*%fh35N/4dD@,42m]6SEUW'A"(##8QqbK2#s)3Arlm.tmUm5ccSdFVV^],4!k99$;C*$1O?rKa4 +^)P2u/"+uRYJ8(XqOWdK"0-J5[C`.1XL#50Q4a$Ii=4m'BY!']ONIE4U.*Z]8%!VRDKTqdSa1[h]'2Ic +<a*<2#QR3#[gp!;HUF!_QWZ?Dc@f.Fd#U9T"@usI$[.#l<ZiQ]Rr>e`r738VT^8>A]'G)?JOJCs\XU[A +42G#9l\<T[iKX;MTiSD0P/75;>n!Tab2;?X*HR>=;]M`aDo3mEqVLMhmU8<u>fX!kl0K6mDcc20Uu,h5 +AS?jPND(7V@XP])&(Z_`e%IP]cpouX[2+P*(]O[J)/VGm>*=;>Qd&"M*l![5ZKfJ/^:]6LJ'`]0"4E26 +*!64[BZMC`>;C"U4OOK")PTl2r%5uG@$m>L1`]b5-L8-m.s<sOFLa;h3A(VaPq651GJUq44bCHC<]MJ< +d,+nqb'"V\B$89/]>7PC9cg2+TQ5,2F@iF#[cn/*r?#n^D&QkI2X`eooP^:*MuD+t%[FaFr<]fkW&_,C +<"g;sX@L_q5_%K5$dKos\JZ.ipjL^<Vnqin\OpM0*<n#0oVL+n@4ROr=R!HR["UNMFCOo@)h#mGkRKt# +dT6>h^cD(L'3bZ;_Q:GU!Q(/6f=HC0Z'Sa&`PF2o:Zm*2$GG&!du%9AF%O+Lg(hXjhX6JS%C[!soQ8\` +XhURKN\)o1Nm^(+a_G^5!"[FQ]DV%Aj$Op*ed_JNLQ\JDH%-"dd9q.!-G6:H+g'QQ\]m<3C-i<`A3Fr? +^?Bo@4KRfK:K6]&peo/Xq/Bo-?DtQ&/:;//*d'Hd$;0JK>81C)K?a`*K<HCIQV0+#f@KA`U:s7e\UI\B +9KG2Q?$6\@MBUXWGc=,+GgGO&DZ'e*qcEO;8)$Hq&p3t#fLM^*5#Se8kb,+?Q..%Vi/>=BptRnA[3s`) +-e;]#P:&J+bI,I&q/jlV9hqdjl.Y3Qq?m1@<_D,n->,&m=J]TPSE/DbL/KWoS"+c-hWEPQL3cFo9c=`" +Uqra]be:ktq#Q7_@__qr6^ujb]VVK"U1\>Q2RsujagB/!6[kC\3@cD]d?_.b%])J'*'T_BBK__@$#&Fq +9nMXd\MhPI)6Q\C^0#"$jEpk?8')$k0K/Lp?iE2sSl\bMh\.+/NsHR#0E8=d>2ss@IG_^o3'(-<_>a=- +fRNoC&^&hmEbQnc[EY!h`NN*=LCkAsX:D'd6<P<ui"aE"@$V(0Ff<@naqAe_=]T:2/C[o:b1c5pGJP)D +[4Vtr!LiC@>O^ehasp@14HrkB[*U(M14\q:6<SiJaKSJVT[l5i"fRIqaoX]s$"X-Db<oEdMM-bj!--bu +:f\I\$pAh=#gi[.dPo-I^^+Rt-k"CJ4I!6DoNeV]%H&h1/X-DE4]3]LTEo,";M;=]748PjCaYIdG.WO8 +!$Q$RckW3W:+2&!9dc//\5!QG!E&oqOU`6cN)19[f0,@PQCi3ls1(I!?E-g;>?W)ji`F8s(Dq?;]E3d% +L2i$=f`aUX6Wo+8[>2$fq/6jE!5+/$Te&H56aBN(k'XQMaso53:+-M>m\>KA!5W8I.#Y`[KsJdH&\K:u +cN?J`4/"4,L93gf-jqO\7jr/V.YYqXao[OPX&.AJUMR=bni*6JAXu_FK)mh?AYC,OpBY?8h<-:67KZ/n +ji\C].Q!Ph-jq9B=/bBh9NCs!K@(CU,6(@JAH?Q3KX,Fm==B(ie30%-:kZ-e<1tj`f^M]QgO2gF$SVck +NA"[,*pD!f3ZR0WkirD3eX'(ql6i+@8J]H83P)"_(8-sUPf8oW:+2%dr:*ULaT)][KnQ[,QBs(cAMV%f +=o@DCTe'Ei0r(.aopXbgP_B^IkCg,L^-Yt=YF\Qk)-Cl+FS,_G)VXY0^b]B.n5)<\LU$ngfdVTl*Ft^; +(>F-tP\#9Nd#^O*b48F6Q#(;@aGK5kSPU)'p%7/W,X@8a(3l_,'?U@ciUsLFOJs\_"eX?Zb+a9T*m1ck +o`"\,qe0f+D5>/l7YfnBUQTV_;%O_/^Y\R)KsGLt&^')SfK>B%BWi3[i><jbPf;<**m,\_,*ZY8KX)#p +TT[j4OAiN%!@dn\n-"(P,;=u[]Hp,=:_rea*pnja&^'+s]8*[O+"R1<-ph'CC*Q_QVh;JE<74j#U?p9s +^/l_@]?ra7/FHg0KX,J4Te,b6ohZFUD":C<Ha6BpMuB.eb2O7mLU%>G:mRFtPXR!I.#[XTT26<X/KW'o +^-+TC`BNo-b+bc<:+2$JhE7#kDB0e@U<MsOP\']NKsH)#9V\ns$&,[t<1tjlAU,\^UR<Ko`BFbB?;^." +"!N&66<RRP`C!eBqA%.6Z9b08QQ-?D\PuESlc:'"ZFj/1/<aBUao\r?L6"0JQ9BI]XlK5'o?S/o1*%]. +=o<^B:_pI'a$X!G\XlV5i3YV2j_ItlXB<@Ub48GaZ<20o.#[JY'?['+4Zns?HBX&gf\_-E=k<U'P\'_W +KX/f'YYZ+MgcUfi.%O2#l!5(I,1Jc?APe&c]X/`Ze30&8R;XI;KjHqT]V8`""+lGTS5<8M!Z&BD!W0SI +XaS&"Eu^l)mXrtU=kj7KLU(A2Zr!(UK,2TbY-Ur*n>(cD]MtRU6HMStK^oF\&M>-I+r$_%6K<a)@NUY- +QAmRb=_GY[ARU:QIR717DP=-6/!P0)W_h8t?f/Hs:XK7T1e!<,HOKiM:\Z#8g_/YX>9nT"KN:>*(-Z1( +I>"mS:YH+ddF,]p=b&F]=t#;.:*.R;3k.LZ-EA\^AS]ma=g>7aP\%(QZ3W#mAaq;<KX07.#[VM9oG^\Q +`*plMLU$p1lCfcOfm,negul#!Z=o"N%qSU)>bN_&E8uVW-khMoZ=s8\%qT`Fm3e,ebHZE`MK\)D:_m=h +\47qT*0HD>ZFJ6R'?W(ZYu$bR:);!0]upIGVt;\aD06A#Z(6#(=bM]gZFGBr%qSVi>:5YHHZ=_ECo=^< +QL3ZIb2OIL:+4<Xe#S8`J_?Wi*Eaf6?jgNXH9@F'?\qSpq[fGPe"&*^m5hmoqfjO4ZtTnZEMi:5A^OiK +*m+PKP)$>VbOlOk!^,'@AW\@?LU*kRAIi>i01@:I]N77@7BV&)eEI')i7(+sgsrH\Z2f0+ZC=ROLPN0/ +&mHb7jKsWH:?cT>-*`00#d"c_@_9lP=kk%?f3>soJJDDb&^#,SThlNVIe?MQfD7P%/F)KMK3)<m4Wr@' +"/]+8Te's&bsPXpM<BPta?e'<=f/*CIpIu?^las5W8ofNEhYd4SPU*:>!7,L*p!KLIgsD2L53&odN7e- +Mk1U)E[k4QN.N_Z^*ml"[0;S<DA?.1$mcEEZ$&=)/C$M6Z7&L=5VW=qOVd/R/<^M!DG\`p.dbo9,jBDJ +I'"()nkoXV]V\"jVd0J%r2U0*H&is9rYfUJZ'mRKCH(Hb?Ss<9O,SZDqHfkscmC?/A_Nr6Z:pap:f_7n +(<SCLdR%*603TbSZq1X:H)X,5p/MK3Kf3Y=/CPptfOW^36`s,fCmp06Y("0hR7(h_Y\B::atdh^6<U0[ +=sto.8IK*t2JJj9UTK6UK$kFWo$V.$"1:].AVE$VTe)C9(<SCLdR%*19tofZ5BSC??Pk<if>Y#oc?g=N +X!c3dGCJ\6q&PiYXEgWaM#Wj;=at't_8l^gFqVBr<IUIBn8tLd8C2W+:Zq2ZQ%"Auc7doLVued5?)<!N +U#<KoN,1qQGU!d6Gp*rOC!(S'N]m"5`O9)VIj+6rJT?8'$9oR%B3*TJ^^3gX5u:_T3+kNriTF32^G^]@ +(>KP7AV(Y25>U^n"h'1H63f6sQ;+C(r/e:eG2eXF8f`MURlZ,-XX\oSH0UR(\kZiN#G^>nQ.(ehN9U`] +k<kK\T[$M/U8>2<";=[kRDe#kjIR@p.J*G#G",5s0Cn245Cp?,5csrP4?&uk*B(0?S^So(e90Q"LpHqH +!PoYQeYH%[-Nf#YIdZb0]*I.0#-Or#B(kioXkXTB\HJ1`K@E'iQ_.Z+`3uX[)(I"X0K4Tc1Y'e])/B/% +@&C2r%>f^"9Yd@om,4946i=Y0fp@[0?1c_W1YW-PdKEdMGZfZWfd+XE&1JihP2PUQs$t#/Vn=21c>uHC +=f"#49gm3sR=1K>oK86*+E`=DJPEHeEIF@#9^F%a\*A0L#:&X\@PKa9(&Ri:(@QXVpPqhJ'1Z(/k2[C# +ieqsm4uDur.];U7.F"?0b>Xq9E\"V=HI1f@oCX:!c1eu['T`rJ12JnD0J)K<Z];P^!iu5a>ZnKS72,K7 +p0mmtC6j[f'it-]GVr\\XKFP9iJ9J9Yn7)4lN:#^E!O4Lr,fs`qmRTg["VT>Sau@m)f-kT#+;ACWZ'Pl +)c91s.#6+.B08(S^3)E:ffIrF<rJ6f5oj&ongFb'B.0j(+oJ!g.Wdo>U#rp.p!DmA3U<C,9L%m;cE8Bk +p0dH4$_9HSgog5<XlFUbn3O:^F5g[Si$.Y8*s?r]1ER+HTasZGW=RO>@ioN8e8t&1Li[*cI4O?ZK*!q! +?71)9m93!cjsE=j5qoK`qEpL<If.+:aNf9_YaO'6.2$rM!^qk*7mI??iFbF.*D/:a]d&,,AkL&XW5D+p +@6!kE@0IP4=*]QqA1'[][J:dG&[A4*"X.!6*sU+*W96"Ya'c9[nj:Qp8;d?P7&7>0`'>Dn+IXBQoI<': +91Qs>"S2Zu-LF_9euggV)V.Ak3AjQHeu&:O,6KoBQYT'#FiY,lLR1Q:.MlQ6\I1]")_3t^l1C(T'9`Vk +31S(`'8?XTN0uXFJ]gj/45qFiEY\FH`'mX*q15c,q>E<Ps#COYs#;7_?Z5/XVgQ7jBSb-T=or,4INZ;G +ItX(c;hZ2T<fS>`PuDc#[Tum6cLhQJ3B*[^<iM]k'Ge@nZuTp,EZqrXF!GA[e:a%'Q^)Xj6<;Bk\-I4^ +3SUQ!=R]EQL2\XJ@*`9C!1[K+'FYH&)h_>rYk/_klXf1.&ik`4"&L)7Pll!4bK9ipc*24BTP&tDA)OV4 +U0L_/C<mbuNm5GGEe&C,Qo4(YpFcWt;HVpJZuT;0JN-[?:rY\R3-4"bq12'Q!^Tq!X6$R+!4ESB%R;te +B]T6QV?%00!*iso(jN-P;beiuh0Hl[!Eer)jcH8qbSj7/%6dBO\.NG0Q#jHj<Xunbm!p(7`#uEk3<8pb +/'#GP#)N'Q6F?96GXbdq2,T?R.gKGk3u@_IM0b4e3<5[]jVW6DS1'_h6a2?2@uVKZ#DcX&aoPUV=?-@c +^T<roT[6qE%M3MH_9,>/5&dSCJC-I*4u%gPX;lc9(X9e>b)(-b(aPK%@H@KrPq+A?]e<`Jd@JWChqqI0 +9gum"2eib@XIOVdW6,X(=#j=,h(4PS]3-;[<g&Ap2r\^Ul6f_U?<.Q&s15;%%n%SE[i/9WQ:=JTj\X[4 +bK:-*,V+WXCP7s_i3@;tH'OoEP-_H7-l>=bC_CV@\S1()lm&U%9Ct4g.gO.tSB@)LY];.'7T_[H@)&c_ +8s'li:'_S;3LA*TQ#k)^jmZb1X;m6Pba'H8-qf.m$jb[MPs_89>ZM?25RArrMggDG_c>DC.u2:t+"PC` +JQY!GSX>ZUj[C_W>huW)!3S[lacMh+X?kadF+MMUKA8/r0:3a?<Xu2&Y]A+KHG[g5qt778.!AWn3?b/. +j]jQ7<mE.lQ,D<3X;nZT/h70_3PrpIhca,Bm!HLK*#m+=jZr(/cY_c/E:qu.q2)=<el1ZD!L=QU"I#80 +b)(O=<XtJ6\uZl(QPrnb/LNJ[Y17)('&r38&Lh&J+I8<T&T6]lj[WE5!)'r*SChK!,fpa"#CLW,+qTMP +B%6`H"AukT%g49BpZG6KkI,F1`>6D,d)7AeT5V$6FpCqr(ZKW]Ag"1t%n'CmQ^Tl;o@q#@DmVk:94GUK +o7n5KT,=07&U+sBl]MgFrRrU<d'>:V9p[),8a/BHpm5jIO6;5Tp;>r96Qe&LKc$+0'NLN7FX-='W,#2J +B`afnOC,s=E8HDb)ZaSHkP:e\2?Z0_A.!;[J5r7i2aH`C)!PK@Z/srTXA2QR5[5<PO?_o/F39nIK'$IZ +!(9RZkD9iNHt!3C#`I:fJiJOD>g@d`Sga9(2s-mnQD(7jG`9dL++B-/IiUiQA7&EH)4d\VpCY\N)quh) +aEaRr#%[d,`APf3Fa2c&Y/l>phar#5l`o#p827lXTL>O%@NmM<A(g$i#D<T8X#ji@HMl,m-$msa$Et!F +D=$7I/"`,IK<m*3VhSBVFc("*-;,oQ0f(02V#t$;+iKHib%gN1hlt\R7(P-M?ROI`jG<Z@bMbUl^>gsN +JNa\+.`]LC!0K&]aqTFP."f14\o!&^bNXnFeJo62/)lm2$293]Gj+886-p'1.Cg4qSY(`3XkPh1aq)Dt +5o'`\\H(3Wm)CZ^n5]j:4p$kcX:K#u'M3n_#cu:e?dYQeS<&Cad_Vqg#\:P-K&@o0'Wmr8D.eOn&I<CG +:kttjO2n/gTFKM%hV3r2KrL;$&4':!ncPSBq>E<Pd]""f%)!93_1_u7YIWpV0_`/Yaq$m>\XGt^VqoT) +ELP^30d6!cINZ91S'@9^r$+To!]2R%!l,[Rl9;7fAb9q50:nHG\Q!>%Mma-pqSrVH>rk;$<)FUK"9U/U +rR9fiaTNm=D=jrb!49H^!L]8e;566.]Vi@Z2TWe6__5XFU6%f)c+$3_#h*^a)iVK=0mJ@(C?ouG[gpRQ +k+-e'.+c5HDhkJSh1+6Z+fY$&/YjVGpq\C&Ka&oq8SDPtK+kL:oDk5I&q$'XR:m'IG_T]6?B4O:[>-A0 +nCDO3o'8Zp/pQ8YI/?m5f\)uZH-5AH345gKSOVr!C]*M!;8@M8%(rH(#ToONa2lg-72^M:.&Xd"]&%P\ +<6RaYC%._K5Cp=Fki<W'*sa3uc5Y/VR[KgJMotjfKj!6fmKk1+r%[Gr6gg=p'-f#$*cmE-Y7SIH]M[.. +*`E1O&Yr&<cd'Z#dR4(IgE+fQ%W`d!EK>!BUA5oaTk80>5W"LnL^(a1#BT,ifV%;FDV!pD?-u^9jLO$j +M]bE=<mRRYn@A:(&?O[KoT#TTa/H2L;nJ#CEB5"6;T+64.Sh/X0:!H^>)uFLL[pZsV`)I^,?=Pj\FnfC +kW$+49o-Co@i@QC(T/.f3=T]Gm;SNb__4bP8oHk_L/T<5-Qtd*hOLIlYc#.Noc9QWm*^?(g(7aTVi=fX +jKnoXdtG5$fAQc,J[cQ?gA$4YS2TT"$r.bE@>WH&AV5ceO:1n):;`cYkAV&Sr9MUA8-H]GLJC)>Vs+KV +`G+A;Pq5\:$$T-kc+c5t>4&FWkZ#\^?l2Dhaf6R8pR:Ca4N)IhGS^6%.lXUIir6$HZV>0K7lb7@Wi^2K +MQVYRd$aQV.0lDMmnaM*:(4XQd/<rq96EV3EaZ:\3U",,i)1&(m-.CX)GeAkk-)L+>>1M#@8T54_N8fb +L2"EJ'TJ^*:_$[,]PusT5ju<.>WK%BXrOD590(AN6TJ!#%UF"as15,f-jM^7Ft!ZU0#lQ'=uYF*>@=3d +(0`%NR$Vi$i&)JtHimF:fUgXi9j<'0[WhBr2Lh3R/":IFAZ9]DoVEOL?;#:GhNd^#?gmX88)F`ffLQ8i +Rqg!bebV]PIJlu[R4p>+hK66+:bKr=`#I&$?CJAI"uA:l)Q?1N$$2Phkm.Fd\-9(",a_qj&J;Jg_S3lL +`=$\cJj''`GSpLHAma/d.t8%\.:`3.h9[5L);iTQleF4^6O'd2FZE2(=f%U7GR@Sr5D7VH##i6K]/&qu +ap[ini@/:pqkCP6ZHChcn.`1NgF7lTOR9jm$3a3K1W2j.X1Z5VGR>=WPEf>MF7O?R$5pE"7@,H6[CF\< +S;b;.S'rl#,HpZUC9gaYC?Mk)P<t!hSnM1V?*TNt-'\SXn&Xl2!fPBRT$;W4ebVi-N*27TF!#,/ksk9m +%]Ad0QZ;J8<>oS9.n'k,A5/^Gfq+PSbQ']pT!)NH`*V^0`F]m=biVU::ADj@*6qL\K5;)hZIk_'Ru+=i +9EdlA<9A7AVp6tSH[5U@=R@SVB)UbA2hEj@OA7?T]biKu?h>of=Lh\Ko@5u@$X6Y\6!(/c3=%g:+tnGB +Uaj#j7e*,SE-em,&0+L,,:4VMq[*icJr3"-q6)_*(]]0A'BQk;WY`unA=1Hn`YPNmPYoQG-eSNXaT\g^ +J\=W89(*m<M]KB_"XR-GD0QC,6?27UFulHX-AsWkQ:@`R2m9GYY"]<rnZES?b2](<7jSJkM*auk09drW +0<'=J7f)VU@Ts(BTh5GsA]mP:9?2LZ5V;QIUQj#`&6C@:R$UGO'Lq+9+b1Ep\B:^r7[$\E=3*9qW`peq +UaD@<]49ElIHUh-B2or!q65`I[D$cRC(bB&2HZ!PWm>guJ^6_2rnK7dLPap&ar-/QY+h=e=*`t#@(ib< +Bp'-LeXKNa@DtUuSStUb?t?eT_,jZ:SosaM=^8\G1pq!;WtsYq98^u)K96V-P%,PQXp?Xh4cmLb=)-W< +N?ArOGrEf2!90<DmP?)O5"d*j(9Gdd=)QB+>ReLs=4H$`HF7;I"cmljUFWSLBcYW]N6X'PpR3IE5ECF\ +&b@J"'D?7r15&.DkjufNJF2$,!DV.r$(.'\P'G:N6SU:5d0!#;:^hla'Ed,hFX[NPBjQZ_H!Z@o?8'9* +K5\^Oc^/+&k=[PNj$PQ:NHCLrON1!KfRnH"#)5*p!@h?35oq\uJ@F%aMF!ge`?<Kn@Z]2s@SiY_@^&FH +.g@;J-jD!4'SDQUMLg=K0dujo(ngT!)!oi2M?,'h;@L_>;@F+tIjkSI^(c2^?A_#i+,U(IHRT0=7]mT@ +fZZ<nHmf2E]G(Hqn59\cr(meU'piBkk=[PNlU*DJl_PHVhQKR,^nkEl`;mif'SDQTMLd@1UDUWJ,K0X# +-N3Z6#]]+nq0C"Q$uu)j%,jCBb]n%#I.G/m5!C'!!Oh%[am!gn&tIn^im6FdB'%]N)"RK5\VQ9l#F?Fm +j7CAdQjoZ`JF<"@iZ=Y/Y]%Hk*a'FH&BEtO$T!ji#CXh:kEEe(B]d"6.)Y5Cgo\KB*cDFPJ*9aeEr$us +kED:JGPQV!F'?HD@h\8oT@a"!jV&)U'Cg.^)0""=(-`?B^@Ea<&/"Fo#T[_S9K2Nu?fj)s/)ge%T+USq +=B7ifEiP@S-fV$6>nK:gS8#A\(S^GS!'b@o"@nOJ!L2I%`sn-P2'_+IP9dLW2\:3XIZCoD,+lsf`'mX* +q14?Xhg;5:4_qGFf.[[sV;!kd7"D7@6U[B@^G7#lU/Hqt+td%^NJDI:&MP"BV):CK`9SNm;?JR?@W(p? +7>Q:[ZA!S\LtcR5f&DIG>OZq%<cAAV_:FWNnDV>0QWrrNjsQCaoC*[NE!mS/r&KLN\"M8p[p[.J?'iU` +qf*"<D^i$tlhf'Zp'/WS1noAd+-:A+J5VD%DPT/"R@%1i?uP!>4J;B'&`sl$g?'0XerO%^^@#l)l^QAr +:%r#h<.nHe<SH,qq8!il/V#-QcEFT9je=cU!4ETE1C(,B#[skpX6kp-C]1+^^[@+Fl^R3&4r$R8HCd2E +,[8-:]*4g;kq9+L5+*HIG7-V,gk8nY^l+2XfnaYVWcklUeb\ACeCVSiW4j:`hK7@Kb`?&c&8*Ggos(P: +ip>rjY[&:-[AsC/<6o`1+Kf!5X^nb2nHa*8CKF:^>EI4SZY^i?eIuEZj4`%7BIS+IJ:5G?IR)Z<%<7Hs +@okV-&[(!1%n,dLamomW=(`W$Y)X+,G'+q1>ohjeY"ANCeNprqQbR_:'ENC3eUaYNG'0ErgXY3QD_.%7 +`<[."&RdDjag@uW`%dqcVA1FW6<n_?-<-EeheL$1+t#_di6-dGPP:T=ns=8P+[hkR'+0P]_h8)9R8=aE +BU9%eLbPN)iL!GXm[-iK>e<ZXG,L*%`QfO6#mYO@:`-h8&$>ck>6W["AO<6hnuVt0.nh>r_h<&`R8<nF +^S2$gejmGJ-r/8HTf=^GKL4R'-5=I#f2\DZWR?G$R)`c)).hWWE],ZdlHNq\Gosb#,$((-r89<'d%-L0 +`Vr#/634_m-k>Et:D'l.<W;Qk!dpD4,ZYEh$=F`[6?*=mbCk0P7OlKP2h[ml`UOE)4dfV1K#k#E]X40d +,3V`2Su=s5GOXe>gDn2@nKAEJEG$X1.llV`NHh8b!g2(B_2HPI6#a'M-Q*1C>4rq%+=cgs6c('6UdO-> +Y9`VBqoGj+Z*VU;Qf^XV321Na!n/)Cg_8;F&<.0ulPJ+C'Mju]jo;,JkPm7sh>b?fF)41QcmA5Wc_%tF +#5-sEmsqIT;;hbsC]$h(c?UR>rCX;dWOMB20d)3g'E+CLhsEbCX)L@&MYE+QfL#W-2[ReS$\;?i.cDk( +*c'c;@-`e;Nd$*@N)b,OHFXWA9)klB7$$k)]_]IIonRbF-G7&YgH#o<<TCuREXrF$+)eA0Q"-FR3#U&; +AL8hm`Rf*XoHF@aJe"?H'>uNTGu9]Vpc5WPa!i[Sc5.UH6$S1Z&dG;PI+T,%%U/;QY5[SL"-XiQ=b+DM +Qj.$j#\qlOp"uZi]-fGL??@OHqc9Zk7,J/_W#XP@kK!ZfLGIu=I;_E^_N;^0lVcW2md#4uF[MD6k''lt +9+BlK':Z>]Sbh,JSk6XoRg@gD;4*9_cE8It'?"2&#&<Ma5V(ai:t7U%(-ni%ZPC*`&dZ-/QulTtDs#i2 +d+I@[N/;KVF!FXgdgU:#XW((#Osk\u:L<#)$upug$kKXW,%c&G-DHj=4B6sO-6eAebOC@5e/U*'Ek5k; +aZ``.'aA2bE(P,OrGs.O64)eOfkZj;&WG-8^8h)r9G:rfi8+TUijP9!A:8uCE7mh&#.Legm85kb73oB7 +ee$Z:%fSL0'&rWn+mErG0uW#+]nZ;$BfJgLJ5$u,"lS)"_RiP4"^S`5*^PRC5qDrSPQs0jH0[a!5nN!W +s+CZPHBfS.Cr`L31IVW%O;p<o&ge,TV,t!X3!6W>57h/_DO,SCGI'\Bc/rJ%5-"NG=I%\n;I=1[bM=^E +c)6Yj!:+;A+F34"d6\II+L%9Ed%JP@gilL+OQ?Ol>m=b)5uMR)+Ck[[cXK1#Vg(qP$j"H`r?2cJmi`f( +c<cf8N]T*gE%Fajj+\_acFtMLUIlTf+>TQ3:u@oo#O$RH"<7JMV`%lb3NYASr9L#G^<XGQ?!h^RopQ4[ +Ps9)Y4Yt"b5031c8E!m$>OgG$pf)ciJ29J^W@7$Rm#h?Y30'Bq;kD^SJ\YJS['d*,JG-^Fpl;=mn]hLD +8sEh[o+CH(.q;hdj$!iU7V,rII/pe"`qgHYY`U.e[]$<jHg<s8s12.SqW;mJd9UC6VWg`9XT.H+@YH"4 +gn0']jC&jg"JSi[(]Po>quH9`(tB[ukZP8VW7ZWnf_A-f-\<QH#l5l;aeKh&kmT/C_FP5^l#9kG;a\uC +TSZX\W)X@H3&pQ?:*="f's=5-%u:d3dDc\"btfKT'`oQOWdF85!C?1CkkF!TFW2LLrRj(9$ES:AA6`Co +f!QkMSt?)c&FUjK3?2Bm!*Dm.l/t#7."]:G(DG)iSr`[`9AnO8olY@k`9_KmAE_O'3%SK<INU7k(ge]_ +i\X.nV2PPBrXXhCZp9Grn:4`2_.ei=Q]'=sW/UBd1L5C5_`<S%EF#)8>f*N]a00=b-p2db2o'f\>-[gN +NRO8[E26<\c=r:u1r;]So,eO[=OG,!KQA&bN_)R.!=TE1B.*6?ji(pNTdaNbEH:SAFlt$K8#C$4VdGq\ +Pj=WXk;5:[QKuM((htM9BeeT+[.jK&8h8B!NWOctF2%p<E2i58*l5.q`d`Q4k'0llVWFq.5q,A!&q>C3 +NZGZRO)fcDjCMWUKKN7(.0kY?k3(G"&KruPM1.)4Qom_r#gfDo+J^"HVMGr/!F)1_Ef^teE92TNdpjDD +hd_R9d'''?Nft,6PQO<DB=jC\<9V;DjWG;%(K(_EN4qA?b!FOCEY,>XAaJ`[*-gA2XtRBdH;0)D#J3T" +LC<Xg0k6,775+,L(79&'Zc*]j_-BG\b5c$3NmItM[C&/El\DqBFkbcdDmoJ^<4Ht1j>r:k:*3Qe*ccOr +eu(V_rcMJ;4\srTN4qBj`oa[GjOX1$N.'M2B74j4^?D`!GkeeodDYkQe,27qGTcA,o"TGf@_+Kg(mm5` +ku1/XYjRq4*7:B_%O/<!gtU$FQ172Z0>+2I&B=d$&#%1;<3`Q2Y[*$B)sQr5nN9^5R=2>Q*m62-U6`Ra +/42<jd9K%U1cl84ManXsX?n=t0,5Op#*0M*O68'kC2]m.HTZQ*O_nP$5h]e3KRgSi@nVDmHgr/Nq-Fn( +Eu=cj`ds?FO"oH3hBoE$3qgVg0;s2]Uus$_$]K14)mEK9EG]Ln:t[nr]m%O;LeX%9D-@L1^k8F8Quk4$ +rg[c\fHTj5OE=k).KUUIG%lOQnE`9[4.aflBYihcB+]!i<l,ZU1GD6'm(\PL&^'P!cl-iYGE8r2J2_%o +ft[=#f#NZD4YOOi_6td-PkU1Wj7%H5S#ro25ftM[k@GRQ,FMF<2DmC(&iWB/Y[YMRq@],O]JWDV(t%=P +9"1"k`7s)=[A%k8a!FIS0]n>J34NjqQDJ(W<3,3+OOuCpY4,aA,_-['>C:ORK+C:cP#!m?0f"Nl0E(mN +6f#fg7_YD_r53<rbE*#mn6C<D[d3F6?m)e7[*H:.T9=T@#Lmn0;nu+O$<p5^[:m%,UZ8C;<T$$g#e[p( +IXR09O(I<Jo5H)Wq$Y:ir.XCCLl_2tq^r\%%!nV6e?8-]:V3Bl4l^CVY#1u&ne!oFm>gp4-(WXLU0ZNh +):sI"RZ\m9GL8W=#<3Q4r>"rT`oD+14[+fa'tn\W3a&IpELQfKfN[k&J&4^d$B4?rd@uK[JB`?Q^]/tJ +.,Q7$>.Yf&(bh$ErWZWOUr4M/:\]4>d;R^E7!Hl_I"K>V#VN1$aVPXD($q94ST#],Peo8;,I2f)].GZK +jP=$T\+-qg=fno)*9r]^(CX_+bZ3/<.k`MoQi=i00R:d,U^;\p'$3J>`bf?[X+m&*]L1(_&5j-]=66pp +*2+"q`FI@me0S0>o<?;mRL;a>C;)_2>,'1D&(5g7fUm\7f?UJR8Il&pF$2,HQ>cqW5(ed%I=L5>6Cl!7 +S*=+P+eDZqcGe[a50dVbaK*r=GsE\.LJiqB\iHi4o/GrLX3c=LRB,b&m>t2dB6]F8AU#aMHMER,oN7GG +UAod!<pN[.+4al+nhI_C;\pFZpk4P/:bG<+3m9\:85[iD.j-mVBtG740D"k%04)MmdS0Y;B04l>Eu7VL +9+TScDH^ep'1m:KiYPM&g2>.\%qq.oq]Or;*lU%?9fGI#)mIm_[l@a$Rb_4Le,j;5R13E3k%a+]i:i\d +SrV3`E$H^k=BMd/]Pg7]cRJC->16-n(Xnhj[!g+65,=1.&G\+!V[1qN*'=dJqu^aVp\=\7Ca"[d)55-* +O!@eX!`-9Ym?BH,n<eGPDU4FtO%1;]Pe4Pi\MC9/*h0ZI9'bg;%R2OG&baGR4>)37k'i"1R%7MG.Y1gj +Cffoh5SfOhfZ0VOV"k[IqYBSE@>d=^kCYj=i_u2@'Dqn/R/AO`<-t%n"Rgn.'/i>l+"tVSH8[kXMrT/3 +8&1gO)Z.E*4JD1_f$*<eZh_0k,@WeS-hAfu8BV]pNtl=/"@u+>m*\@Y@jZ/nXT!m*,$t9_2V/MS4U(;^ +N1Q#J6%[92N(4Za`anL]]Jg$R=KF7*-Cm$6TP;)34T^Eu!-_de`FXDYr->TO5gG16Koa>g0.Znd21NC6 +P^+^_`r=nIop>!biQu0&pRgs&6ipke8@3'!7DPdG`:#qLcp[0]NYVQi56pVh6s,L&dl5-6^R(AObk8o" +3V.l)QDW\]_Vr/^G/p;X'm`Gk*C)K%a_\]Fh3u0]nPs+Y4l2rab_6T^*Do[tI]-r3K)#=F7G5@Eg=s9T +^@V/6XOK^S24Y6.DGZ0s%19C2Du0$UHge5CF1@pf"3Oq]PMCP`DL^7h_Icck`V0?l`fI_Fk=S\B2+Q"l +fSA[cm2jNDH65X(+@KWlmoeJ8P^/e]JSYGi:L-8%2<jDtFsU!S)2%HkU\.13OS@@L,p/,3*mNpe5mQL1 +O:Kq`LjZI0'SN8d_'.N<%Yr!&_K4H,-QHpCkN<M=F^5BIOeYBtEsi$'3j"n2D>aR\bAU`AY"qKdM7=8O +c6BqfRM%J@*;VTqd_dH7l(BXk"G[?ebSJVX_TUZ.'`,9*S<_ERRtf,5!^`Kt1(*emG^h8QB\a6-n:5pL +ONcr:lkK-MJ&9Q&LYuVt;#"GrA#lp,8ah*`=ZE;,Je.@,2tn0[#f<>%E`V03ob&s]'PO?]PV:lPTQYT- +'kcGpkf>K2U;gttq:Ku!'lP_\2b_Q7hZ(W]#848gW-qdA!Ls'"^]/s]^C$A)'lI#1hns&dQ6RSHrMlE: +jC)aefc<e4Q(_Qm@guAOC*2$som=O0c>KnUE1+?*nbYgN.E%oeiU1s:MFr7_hJJR%+OdLqp@1AkSbrdU +rVZD^Yj#*Tq;B0D33f5\*8RM/9Q)AO)K4X>j8!n?Si5]cRdUrWeeCbs,/nPQr,g76dW8I-1E)j[:<.:1 +`0:sR<F!8%PC$#dem^.u?;k+bo47#^>e%(-60-Yd)))Pt?0\Y@:%<#*)3KLZRr,^fZlq*:*3X&Y<t4nm +[`Jd>D&jdfVp)KiGU6/<\@Br+XQ)n9Z!9^Y9H.MSpe)QD[1.=o5isX-R*JUZ[&D1/;t&%Rm8oYaO$KnP +VX"V+2)^sP^@XQN.8jUs`8*p!S&S=+-Zi,[8O:73U&Ic)k7HJ0o&:`^"jjX!s$/dt@#NNNOi>B&jUoBl +EM.hcjt7!uB?QQVkjr'.[3LXgp=^Y(X%.gKfj*Z`/#:D3Q]&6@jesj(OFi7W7^.Y>N])BcEQls_Xq;q3 +kG+LLCjR<Y'R5)D/fjlarr>8TYY11sPAOgK/rnCAAj9,_,OPG40)9eUCe0"c"[;bOA;:VaU9l>8;d'DY +$8@8s#uC+Nf2uu$5`4@MJ5"Q$R$pk$,Yr`ucBJ6-nYGnM>j)'.T(LE4WJsk\S^YDt5,XQ#6DpK``V4bB +-]=-D?(VXPg79S^M)[)i/BRSKZ08M?[6D0WfDJK,Q<sIM)+)nd%IKSXNJ)c)@sXJjbbIt-+%Ms$*PN*G +'R,quIam_-Lr?FPBp@RXAOUj)ZqA!G^4q"l<a$`U=?"g-,AT9&U6<7U'NC-"o]=QUYVNTWXJDc%"lhod +`"9L+[.5^:!Df7;[)PV3=-e8()\S3pF);_bs(Q(n(*6q`2VOlV?JMu5?lX^<M@8>j;!&FlJ=,$*ZTc?R +';lpGg?<;9iq^&P^Fc%MCWD1*$hgXW,sI?mnif/(OnLR!Y96!`rgZk*WP"B[#:;S5qCAMOG_MnkON5Fo +^.TB'_iQ<Mo_,4okJQ)oG,2*-]3S`#UUPsW*qjiD#Ss07-Zhn*?a2tgm4b"sBCutJ>2R!,"\6Da+tPcg +XXNsc5u)?RFlSb=XEN3Tg+>pjpTNk='CV(?)"IV%M^''5H_M3\'u`a`/lr9h))YPdmr%NY6Z:d!r8MWY +D2tq(Ys83_CHdlqN!FBCl>?CORQ,>3-(57g)eGTIme&DtdOGL-[1tAA"_sor,1BJ]/B%a!26ZqqdT&X: +oDZ<*L=:9@UmL#$P^*]3U;uB%b@I>1YF^ZdK*TA8\k>2dlTj%YJ=0LP247MYm2@#CX3)p^*Z5,goR0Tl +m#UC$9aKcP:LosSoO#-Sho'I*jXkt,)f2<[#37"JR/%Xt;\-fN]0Sm_C1/TJpIM>0-uNf*LTKW@=\IU[ +e\la6FQF7q^t4D/f&72ap1TukO>t0eN[AN+Yc"npFRZIPQ)mJF_&%McESNT\6Eg4fGWZbCJ%fm+aLm73 +_nb56ZNfZ2kNQ/3<Ns1Q@^4<=DH+pQHtblB#Tq@/4V-\o:L=L]RTY(X<p@IElfrM;JWhVhf+)?5Bb%a% +L*OXGVWP*q-3h]7.TTPq5J6A(:posjCBrHZ(\:(>N/5%C8il$-jN/Rn@bO#)dW=ISPQBB?/hl&91nKhj +\<*0l\Np7!2PS)DSgSo400$uG7+;h/_[Wh_I'BoZn]bXm23)Ul^5@<pM(?'h);gsH@u8XEXfNAs`*'un +HoN!J@XL-PHZG_[ZLKsAj2%S=p\[&<p2AI\K[#uMLXD1>oSIfpUfkt\r[Q%&)?-4EcJZ;*kH#@cr@\'Q +XkMb%a(!HUr("I@XG`f5H]%[42>dpF&c2*G]eKoViL0@@JUfn$J_,L!,26.+H?cK5X?aRe.t];j>+pj% +^%ZMUD@[i*MGe?8[K=pqK:K1J!LMaq&<L$rI!sZj>Cd8S?3+C'Qp5$Bd"'63JF#q]iZGma(EA;eXN3X3 +e7+C`]f-QDMUAn^8un;A1/pku6NLDm*_[$#LNEu=GW(B91EIecre/Vm%(>\;mg$n"^.j@7q"Vj5N/tG# +`<`tj>iX;n\gCj-7up<1Ac%lgR)OCc?,E\a>(D9Ga<ce]+]1_Ii*W^l\>]E6gBtkT*`&lQKo8c:"g2Dk +!*b!kP@_gf#p.r1&KI7Re$W8><pc.B;Z>VPr,!#kjXrYlfR3o)ZD.ZKb.6,n<oEQ;.[)4DRGu;`1&/u& +IfB^]R5Bro9H%is1MIj&bSgHZ-QMZWPc-!ch_j?U,OWSL#MAs3nbZ,7r2p(Lmn--^$%u*SC<QOXJ3E'm +V'@29.>c.6GP-Epht;Ri]CUB%25,V#ie)[AG6MM@=o)D)]8&,Ge9m'['8Og#)K:Y-M,Z^uTV)2^'/i)@ +HTjDV1.fCPHGN6q:,i%h2NJ8mY=%1;];@uk0Dqu'S`6S7pOd1CJB!kD%&Q%2B$sCbArQjI?\bpe1U$ZL +$lWB&B(IQ@hDdi;b$atUo%2RnY&#Q!hj**0Z;oS9jF1/q:M@l6J%toaM9/OjRV$Mh+?s5W]W!`p,H(st +?kfk5'o1$%)DM,m.1P/d+Cl-Q5iL`)4Mm/0*Z\$,qHL.54rDP0b9Aalo2@6Wd/C+5;p(]iOT&P_f:.7< +QXmOrr7&q`*mO.G'0#ilk_8JEaa.NRq2/)@T!2H5;ofpk`E-/QjL#sb_28+]92\6j*?%UM[%Q<Ad,fJ" +pKq]HI9YQ^,d"s:(X&SIID@!Hm.^M[e*lRYQh%aDn6"K79(Vn:XYR;a\_e-m4GO">Pq-Ii!Obq\^.h+? +1Z^WG="7)0'f;a@r2p&0T-]-e[iYb]^RqtS4DA.[T!TP!f;ZN?-T)eqeO\eGFZR%ieYsh/X&DiDfCsZL +-enAUAb,$"oNe\^OdEk*R`LIE.PCIe;IMU(Gt:sD5HB+lZ<_nHjj[6jh._(]Rodk_+AArHk<M=QK=_gj +X4b8Th!#06TKZJtWO\<np`$l\Z%d'O?J9h`Rk^49m2D8$.s-56-\&ho98]&])/#A^WUS?Ma92u4Z>f=J +i_MPb9W?otrIiMcm<bJpaZRR;l;n0kdO"Xj`Sql7acB-:]mcbU/`1GW<gKWP#m,G$`UPo3qOH"+mIt&q +1AXfF2S!XW/l7`f+G?IVQGM[%:nTRdi!16K^XrL=:#cCnq8M!Wd50=-fiRdSqlIAgWPlV:5kF=n:)dQZ +Q1q1]V7uCl6DfI[8u^q,ZR2<JQk<qLEPANUfPf+6Bh!jlJ71?L*DS>n7[85-*.L-75WqSDDA%TURVN:> +>7S$)UN41>^U6Tm[ZkMGg![dOJBdM68Q^7TL<BZE;r%2\FZ<1'FFO*1qb!g+3H"b<ap-mOL/aMXs5]t9 +A@^5,gr1-iSOg;gmO<5S:V_aPeA<RaNU+'"F*=WGV'fut_DphgA(;_a6p"Eih^8d7oU4%5@pt\o.;^\_ ++Y%5J/ZNLhq#\(ld7DNe=a<<]k8g.)eLJ%]F%-iCigKo2$kr9%_']*g],ON22hs"X'E3EtUV>]g3PBUY +3knm0.;OZ$k+)4C&P$mBj]cVTDF\TrmTL8MNd4;HaYY'RGTq.7-CliPg:khs*WB9l"%Qu'gUEeZdL=e$ +/_H#,Z[p]*pW6/DZiC"$S:BP"hd.=^od[A_TQ7m"p$J[3PL8$''-To:F%+Im+*6=R,A&TmZV<f-:2W2X +n,j.bLr2=V%]IER"+\U>cR^Z`k4c\%dWk)]qa"E_p,c,2MH8gNZdKb5NA2.iTq*8Rc?&LH[,Tgpf"+6: +k:uaj-bh65K4>_eqOb"\$Fj*;a0*dHcO>WHCJV*=U",7]K-Pi^o)\&=mKm&;cT32l^P92GL0LoU^E'#a +PcpHOT(@EW05%rLDtB:cZqeD[=srilUu3=Y*$WN96Cs*0C?g@)?V-eI48LGmq9l).>P%2`C%<,F@s8qX +aaREk5<es,Omr.ga&!cHdlI`RHL6c,XOB49#%a=Ukt.b[:@%Q5QHZ,\>Pq-lFaF%q"7jm%p=Lsd!XujL +=ha70:=@=$B1M2d\cP[n!,D)AJ,g'2Vb=f:?sOFPGZol0d1.Sj]JFY%DA@m&fc.M=_q5oEFJnc9(m\jf +/K;ZCGeBZJ8V.X<Xg>`;C`(qS3)8f'q6r>cUQ1hI_.KJ;BcWsud:jWiU%WP6?Zkc04a[\ic/4gIMG:kW +),9PtO3tokpOuSIOg/mleo#Ir*s1%BC6i'Wg'dhc:=%XFFBSq$Djd:F%e_]0`T\t\7Ak;),ON]MlPNp' +_R/DCL/.%WTuq38LS]1R$q!4?8]Kkm%&7U][;qki&Ri#<f'/7ms$:=*F(-lnqfMt,UO/9OF'>K2#&gD^ +-l#F":+Wf$%asSf?R0Wma6k<tR.p<+;UU><3#.3I+)7?"h?+\=.FE%bc,3Juj[8o`d<GbVp>N7!o"KKQ +IDbJ)o\Y/6Yu`&ZkP5FVh`$UB]]&WlJ+"s!(M+@h0Z8Aubt8A;GO9raGJ0\g=fs.iW84g(;Om@gJ'5$V +q4N0u9Ik=jk(2X5`,367#CO1QHlW./]pa2$oZALT,J/qrV*F$h1r&-#+TZ8_%<7Ptnc`CpC6%SfJ\7FB +_)YiHU!:oZctM>.p1bKc?HjYbd_)#^l$,'UQ&ieqRcq^(?Hl>".1>@b-H51$D1*\]o.d0eE>i0.&X!cQ +8mg!djOJ@n]p]GSX#Zcpe%g-FYN@N!,S/>k;*NPWSoq`[RX8k;%Pm,*2m;?LND*YQVl@=tc66)^?i7f! +5H7@9Gr5UEYGRn'Fg!-UX1jTqF&[A!@1rg`O&du%"4?Nsnom<)bn4qTek@\8jjb?m2+'&-GkcM@!Sq), +=9#g#B"G@N5D7:r$>jr5f6+?4D91`I3iSY)`W1<Kmc/iK1`u1_k)[VL;*&N+&B!cohr>6`'ue/d#2B_O +ND%iRg`L!E8?4K#*dkdINP,6<m$dDB[Z-.0H@;DY[/cV-6CKRIA>dTT7sq&tTZqQLj>?UHPa\bu'=,`f +F6T;QH1W&fPg>.:WgVqAEdu/Grr/*fA,IEg9CT^c'&tb/NEFcF^Cd'Xf9UpC&:@,AG@[\q%n'CmQX40, +#"+7CnS=)A,X!5<i@Qeg!qCOZmOGkuW^n9&E<oj\2OM?r#ZSZV._AT9bJFH@gG`U$Cqee1N1Q"(6La6J +]*`D_)fbU>?'DFFG@>TQE?P/tj2.-/^[,5CJlNqs9uGMs;]r7u0"e9WLs2L_G5uW:8`;H;%eAdg#IM/a +2f0/F79lZF630p7(`0p'pP"B?nl5DtLoZ%.oGa"rTkfU^[]V?Ff)6Lss*E*^>i)rc.t5/"afkL0Z!HIP +kb"J7RH2s:46;X.0b1cIlatR#Y;(2gnnX1e5mU_*Ho8rk(d$PnG^;m3(o'/s7KS]g,&j/KdTo$:B6MYA +:(Ho:??OSTiAR:Q0F#QuoQ+>@N:(l_ScM&2j1)l\&VeXi`iLa=j4-EGqW$0Ej6LQE/":M^REVg%jP,J# +g/,=.:O.6lQ>7Zc^W&68=P"BO>p!?^r*BuH1(ir-`-%hjMusYNpYd+@qBpsRaW"6/+T*/<5j0+rJ5b5` +P!Cqhf,+V;N*38F)[MVk_.a"$SIQs\`qVmqV2eEl&=lnJ(h/,SkM29(0a?8U?$)&\&5taMrJI.#%!"nN +5ek;u&;MB2pP\r7"AukT%tn;"r15?/3*u+@Pq[JXkOl$hl96o"KW=r8Ga5mD^H=*:oukeciO9RmPokg' +NH&[sP)"O?=Rug>`[(0fO=b5cqL*af0in>_%6#"'j=MspWA)+iQ]BEeKi)&5'sdK]!ND@5B[_`e7,KTt +BRN)HZ9>o&WLQI^K4>iF/Sn^@Y=k@;DCPbp#((Gj@=ZaL8*HheW3)NrU\-tlIJqPfL#0;3lV7+\YGq#\ +$;ne'#/q!7=H8KC\,b[Jg+#mP!&<.+WL_Bg&9[IN`t5fk0P]pV5]?VJf"UPRgA9skgSZ76HXk@H.5/D: +WA^NTpWV%L&moQW!nR51i*ditf\!jFNSI]%Pd.DRjfEAqf,*7#'fAQiMJJ.[EE4J/%aY0*GiBWO8(]]= +27mV>mB^El3,sptc-@Dq`jPU.;Re/pC*8"$hnghGdPOWj6<qQ5_-"B21Je`NUoe":@:3=mCPZbJr=[?k +iWqD[is-b\Q`\cjJDfOp<LWVkQcms[]:e/(fin&i>qQKlXQNaqoXnFU19O>X=#hjH2?uNHPHQ"=`gF4\ +X*<[k9XnA<r0i,?6lD/8G$3Wen1cpe^X=E6&#/<`?.tqm7]4&c![!!%A)`(-kAYF7)hV'M0<iS:GU)^^ +=k(G3Cffp^+fCsef*a8'MnTqrO8$=IJ%^T;XeO2&Hs%1j.BJD91Rob@]n\S,,4H2CpP;Ej.ebP1eLoST +*BXEVc9G9)]QP*@GjA<ZDu.hcGl!/-Z`aBC]E_-Kmt3SNDr^kK\BPt<(lbX_,Il4c=k<)U9C-`Kcm9B2 +`Spp[!teC1hSfTMIVpo-G>o>`;fTsHed0gTh7lIHXdQYP#[@"koZ)q10q<gWE!aH?i:N_J)<*2nDrV'H +Ud039':KV3-mb[>+s<3d^^.uC!f6>QR^\J2UjsX0GBkpfI2_c)UJ/tp.@\C8GFtrdAHn>YI"hOqS6_V' +.B/ARSo9:bI4`"QfQ\R8B981>0o)l,I;BgbhZI's)PIp6$INYq*='E3HLIYtD[kRbO2-E/`[O6*O&7$X +8!Xor2QNHfBS+d!!i(8WaW/^.?q+U+qq9Ok[Elr#I#@[d)95:t24C3bABFVA7:\TiHchg28R;[l]BaZa ++`&4R;X?a&4LF2:6<FKQ6<Hb1Ks7MX[7MB-7jIH@ejLH_#Rg.d(T[)QbKYp`3EtUu=g^+af%'+,Pgp9$ +D'H9/#Kk=.RqY5fhC;>n)\QU/)@i@(/A1=Sqb%`=erJukflV/gmL$0u=.1t9EU-H3\d"=V9iJfAdp$=q +G@K7WX,-Sm/tc.`Q[j@^56dmJKfn2PgA@KM;=(1CU3uR)La.>Lb"kF;&EX=mP9f+q&;d/3d.Z*=%RYQN +.4$*Ol>A=sN`4ON)a'3#[f033h:*eWV&Ich4HRDr7Ln3](D$.`JY<6/@TmE^UXR4s4[$NUgXjoL[;C?` +[:ObNCX:!9jViDR*'Pd7/F+f7QQGI/3,kgX^*ZeVM\?t:?i@MH>oHD:P)EVO3ORM`>0ut`h;K-jkO<-L +Y'h5gl3ZfU5$\+gmGZn7Dgas$T!'*jGi&ol;dfs<CV@10[GH3hrp8t=R^9^S`l4\@aYF03Cf0'+'2pO+ +SCXb0.*2`Tb13tjm[=JR8?#3TXPAWnWW7`Mib<jB0sJi+=S<MamWX&U2Arb.5?KPbdOT6(Z(ILk:,/hK +8)064[r.4u<)r@h5nN'bW9,9>L>B"Q7N=t#.^5;,8?HA9g@=AqI7t*?g-VCX$MEWGKeR`DMft7g=KiEM +VC3DCkY9C$DX#EK5YU(EoifFI'Z*r''>?;-I?4;s^,hnZ?JG$F>\i(N4"jCtb?I>A(YEPQZg+$X9rF)i +;g:P`A/rGP9/a91`B?d3U#fWrre5T5I^=2-$GgAc<Fm]P$+l*UQoDl%f*@FT%TbekopKR0q/UbXMZRXA +c]TG[JjR&p/P$pa'-p*iBVqJTK<f+/k89`rR\\?#<^ASc-$N%Dq"`8P_2M&3MX;9Km4[5RROpsF0I;%3 +lVV)aaBbD(B5*iq%I.B!cm^'j[B$b#a)6'<^2i>ej']rn`op1]S*s(W4K^Q/4bV:J7Vo6Q`uCg;oH`$L +bT;(ngIqB0H4bLV/^,=94M)h/j]U(fHO,q80nTA:332:t*qLhJ4lg#'6\`*OD:LE=6l^X8#rfg.,4$IU +fO5:Rfff;O^o$u-jA)#T@eL?SI(roh+P1shc&m"g?"]]tI<.)WTg+U=5MYpZZCI=(GHmMuoU9&KbI!.^ +`+0Ba#^Zbc9mu&UOLX5\(^L^H6M"KAAJVW,6[9+O?%QGac/J_YjOJZsPW].;.T^n:2^Ys_J>HTG:r]=B +bloi<VQFT6JJLV:4lhF'LKIu<4iHJPfL,Sl]^-ebB8/Rfc5rMa@)$h>%$m(0bGQ%^fgC$:[hNBa!ATOV +<V,t+X#e]5L-=T'fgDh])OFXB(E:*FN])g0>sU:=IGUh]L:Yf5hE3:9RL&#+g)Q?B@c#dan]5M5(O59i +1hbX"lldRKZU#$$Qt1e2?!n%YP4`a^$alu6q.p-57ta<I.]u#m\T1r_Ve`@,<lVF>`nnj?;_-&Jb#k?* +Uu7.e(gC,i.bt-iLh+hAr1,2k>AqIP\.ZY+H($_UM]!K#DX6o9$mN",\8LD(ML@QOHW/oHm!ULi/LPnP +?CfXFlSSF4DruTB^4ug]4^=b4q/kEnM+W2F*=!k(Yl_a*%&H+K6YFm%[MLcVYXn*_L7d!Tj)fod^kS5& +J]qp$/E1C"hU0^%-&R!`oiEPmdJ%0IBuK4E1O0L4'UW#kM&4HLE[ogbAM\q4rodX2/pS\EfOCL9[M[88 +CbZJI.%OjohM;hLbbJml/Q;Zl/6/<uO[>\]8Ahb[3!:#ObseAS2;d-Eo,.IJ0#98I3Nsg@&aR!M:%`/A +5/B-_3T/5#&N2B5R-pZ9jT<';ie+1$jjV(`#+B9`RfC%BS=N=78W2o>TieNR2=Gl1Y"S`EfW2!rHnDOU +foZGAI:L!"ig"P?i)@tMG&RVa!l;:Ige$oZ;kTO/[dB%qDSE*,>0!-uhabGj/I_>*TAfH!b"f9Km,onC +&U%c3m"psrO%^S;k7>L@$2plCD;&JkbHieV-7W.nJ'<l5d6qUhA!>jY6gd,o\Qn7P*O*Y1f(T.,#uXnI +78^T!3no%5hRXjI>#=V-_@dLfCbo+F&:,R@aNZV[hM)YEVJdtC[`<FdM&<+KV2J<YqZ4.a4D-H+Abetc +5/&=>F$$&:n/8*d#.n.7B5JrI;UlemU+COcD7ptq.[S4LTbt\rDR*-r6@@lLiF1%/TWEhWZsG=?b[7!T +AX*se+^]D'i<1?XmBDuX%tpjF7$Si"cb^!AZ>_QPFo6:73fiXnEnVq)>ia%A!8&O`L1#n7S6r0]ObIj" +CcaUV%cZ?CFq;e7-3!"_WKW%"Q-em3!J&-)A%P"P_?n.(8.DutNAs<Xc6j\>cbatRPkH/'0q)B.q'1Q( +qN9&ND%MFL^oX0On-$W*=]KA=m;,!GD:NaehE<cro'U3IQ(W,s)kK;srW7r=l";b6"*DH0&SI,M347V! +6_fjmp472#'*oO#m3pb$CTF_n#]+eY(niOb+UZHRq9D#>E\5Sn?AmG"/&N$.Z7t,*TA)utipDX#R,Q0/ +1f.HLRU)EPiZ7_!=/bGZ5fCC,BZ1W9hhYJoE`Au,hJB,[NX/A#X8G4fW_mPpg[=tLKH/29Vr\89*]eRm +gs\Mj[&@1(3^0OuL>j>L$+5'UZiHQ^UY6;\p=>Qe>Q=P_qq(_R_Af$CkJa`5mH:>_e#)fhh*(.42ts`S +c1b0&qq5n)Cf0'XXOa&gC#(3#?Z3YEWc'iPmF>V1I7O_#$#^Djl^o'#gk%Iec0B.0*6U/ff)K`X\P:ep +=W$@P^<39U\ImYd4"!b,Zl06p=I-']%OiY;i0ap>R(hLd'b^)g,:)>W[uc^Gc1NpZqpFG?Cf)6gh(oOP +_C=l:1T.Y0eQgg'G7P#9#[`T&pZ*EPZhAe7INU8Zd'@a/HQV;k685e-Sr4,44V;]ZW:/`B"`ZL:'i,rV +Y*$0R?6KpCEK:hn#:'Kh#P%E.*:,)WoR(r&,3-&C38C)KYMgValE!o*`Mq,BJ7_A4,">YSa*qcZ6YEIj +"7b$5+[h^]6uipOr*2$`Q[@8A'C&K.+pC9(bK\QgZhX#m\mgd):$5V`OP.1Sg<[*$#;m9h?_bq_rb]bA +QWNh*-UMWJ/H?jGT-Fj!5&G4.KITnFM#Mr2mEZBArRIW=M.qII6oKch>%>U!XLqln?d518AD1B"B7O]G +p!Z!AW]6_$l>,*\j`Va"?`ib'0^[2Lpg!]si=_jXk?qtQ26mFV+O+3_+,E;6nBlV+6Ml,SPU<S5D$&[M +4pZ3jQ_bGq6Cb+sJF-n/!).T;:+idOW'-C`5tA$0140+j(V1"ckGc,+.RGe1l#'Cf(V2HL`TJdgYb%p9 +JB-TUT0IO#%P+'N*&`#HEqm1bH_JiXPEj&2Su`o^mEWkj?sC=e=7D#sStp3)Lj-VG(E/s=6V&$W?KaYA +(E0^Qf`3PsrG.$:9=1r5["KXImBqm'/(B;70>4`7[it!i0$TYlo0Sf+/!pOGZ]TO,?Yh(:;OU*7bR7^F +V_QO+]g):^X;lcPcH=7Vi9DijaQ8\p^u;q2>\,CWhTOrLMeXoE-K0Y2Q69[Dk[ONio0O8\6cTT5)N7]t +SfSS"D93Bp"_Ye&INXZ0Yq#d,i!"BoQrp)_J<S[ZCbN:8iJrA"]j2W4$a(qiU*R;Nn)duKUcdblpKOc& +m,t<@8Lemq_3Clrr0RIa/-eNGF+gN+?JG8,>/0i6?P!-9hh"'7[sX]qT?([c?SQS&5)h<f3AnsinnN8h +eb1kg`kU3_N+SG:_A)3sn&uPhGNE'-`]\,cZN]9Pfn/(MGKc:uh1-+!kl8b@ah$X'C-A&Me\:JM\%Xj> +;rJ!<>]R>fW>KmG@J8@*h(5kG`S+5IYI0_RCGXca77!>Th'luDGIgu8??Fdu,VttW.?fCg[nJ]sB"(>( +9BQ!0CF4BfO'KoJXlaHa^H;r$GKuLu;m_8;p=&.HJ"A=3#"p5'GC^MA=LJL9cFXo<,@Ae!h;\RKmobZY +eF:uM.?r<XEk_:O00+TcDn^d+hik`k&n?jja.6?)4?@'?JWiG]VEGs2Ebd[WpB2:&,^\T?'eIl+fL2*W +nqf%$fR+koY5;>idrXSI:*3?jSF8#]S;V<iUPj01i_IoZZ6^OVe1&24W8;TJB-IamY,`NkM[XWOlh9I4 +I/V.ofi[.'//?\2ra[BV[e(@h2dLrZ)PW0mh#'EOBnOV"BDY)-W=H*H@>i&Z0)YWN:<fnbY"Icte[$`( +;a-/4d`Qee=p?iI9r\"M)4DHRL.$$78K=pNngH@3:HH81YP/]\9p*Rm/MKWiLhV^FBVN2Q\1<6dIOYpj +YeK:>Fg*uD7Hs_RJ>_khQQW\$YH@D3dJBP1E@4YlYHLUQ^$,HeMQj*Y\W_sH6-Ei-!m?!K)uOQU%S="f +!AhuKUlG1h%&#Id;-PEh]_.2kg#FpELTPL/VL0k&bpB@E;;V72S8*74)<%\.pYtN),BSTaJZ%r]FG0L5 +CAZ(>#B\,PlTr)D.^/&^dp5nG0SV$*ItY&d:5j0UeRKb%H#uY,JfdBk$_F"YHbmtMB8(^!mke\@HMoHl +Ti?YcSgVfiBp%G8J:=q]k>A1a9-uW3B<MAVeAWe@n\GSFBC>oL,t=Ke+(S48M4N@Z\L2)?=DZp<,"hus +QoV+/``6?X>f;MR@c!cuNp>lq*A,rcFtl6HHfp3#FNsc\Do=Ngk"A.\D;HEFf8Rg-h!V'B2;G\S6,VrY +al:2YE=d``_irS-h!#%YICN5Bkef91b_Kul)=D,c6g6$a&]Y"CHj2YP&[;ed5cl0//l/uj);BB[;oo0A +%(M+14@;$(ZZGk'-YN2Aa+RFKA4?<'Bn!YC2V=r'.IoJUiT&uQ^6^<NDd(go8$-)?r#"'m]`9VuK@PmL +863?'0+dMm#[f^28aEo&.t0[K]3JHu9Ulft(SF3/[!L1``9,CDS!7$g!W))(6qesHI%;j37'L_T`6JAM +K4&>8pUSoo"#;ACljU+iPHb+IQoV*TqjPYp:D^:AVgT"i4\P/Y3s-HmEX1gpm"dI/<Sf[:38t@u&N3li +D6r3(38<f;Xe+ZQXF0)E3:/acbb$g3oj6K\G%nHLZJ_hW/lD)Tm@NC5i>Qrq/&X<Vl)psD+r4t$nH7aN +(C2fiZ$HH)l5U#^6*&RHKIp5C>4"N0%Jn:11.h>EX5*>M?S'0W+`$`P;0&aEJCep"n"m&741fuL*g/A7 +4)MbFf*^a007P4L5\-NM&/ia(T-Y$iGDn"9&18$G>G[WbC:UkW&\T4."'QcPpXr$$*sd(3#=<=r1ujhZ +8-1A;<N7E"_Wmiind_c6DJi^o2=oqlp'ueGqa*8*UP^;EjceD+FpI@b!ptqX1Ei(?J]^D<Ff<aDg]>!U +3tR/i7:+"VLr0lPZ;]TcGB:N38s>%Rj0Tffk.VDtC?&2K1BJ&\frYc%M<E+)c&I)>QDq-XM%N7?\.j]r +50Z@/Q$P)0S+kpeX1Z%1LDA+hqUXcjk1+_I%!*3(Z11sY44Dh[*0JCrD(rpRL2_4?\K#L)?Gfhs2`D;M +KU\H4j;eu-K=S>>P%EE;H/sBJ"9%q]VOu0o/'G+l5=dW["hL0b&9;h>bDA#6+^5JPr0QQjFRHRo&ae<$ +8+UeZ-KIY0h;FsMMP)iCC?Y`oVQ@>=K8nsSI^>Gq*(XoQb=S4*4BWG;DLPF:jO6P4hc3TKKr*Z`p&B'? +--p1F!slfX>\sIf^1t[mdT6uQQL7[?9Y2aHAV&ZXX%T[*$q;bJpMf7dLcZfVD)X]$-fW2aX7B$l\[bZ- +/sa$AFEYIUgq9f_5%868U:Qg5f:qC@,m?9r0F]YjXR"m'a'GrR?#eP\.1.:g-3[O!`UtqX!_:IBMX+j9 +f;\08qmcCHq)9M!jBq5Bo;D9[n?7g'b"!F>l%_%Qk'"n8S(m1BDXR70)ZN"T/)AGj#W[(\h/e5^h=Z\_ +B$g62WWB\9[&L!JcD]P"I*+sLL+NJ!GO+'jHMVr3RE`H+(fTB!\WW_r*6lmB4/2]>jq@:"q:`-gT=&<A +Mt5u86a`9$1TY_sS:05XC41HV>uT.OjJHS_j2uS(kF1,aLsTZ.UCcoBi`^(g+eVWL<Q.0!"*)cVELD95 +q]>_BOj@kc!6r`@$Orc"3E?b9&=t4N<BfHUpYWJsrtW];?2X@FYF[UR%BT;@*dhE^Unptp_0'Ye#geb@ +*H=Wui`,FeEHDb1is-c-oiD%F3U-k5j13D:i,df<_%E9n494MZ(NXVN'PR:PL69452@i^Cm.07&pQXRu +lV*V-#W\=ID'&0!eV%#IPOjFRI&c0GKZ;a\So82u]FR?hI>TSJ,ScpEGkNXH70ic6oS"^eF$Eb'W:b9T +KML\;0#VZ.qK7m-`YpR1'0::4)Gmt>-s9^cT/O4j6M!(*EtFcNHCTW7!VuhL$_`4"DqZ'h/b\Q:TcJ,T +c<C$pLkF'%$K]tdlgVgMgihuP#&TFN9-^]3ep1o0JRnQd"d?qRisde@cTu5po0*GN>'M*rjH?E0NAkO* +M'I*RR^Jd*4m`inqa"o@^Ng$"Id9!"NM4l!+EW^f%mjV/*JD-<fr"](U[.Ch;VQB[LpOW`+1t@anI;/C +`W0IS)ado6dSY>@j_iG.@s$lV1dD^t<(T$YmXrl;n:T(Qpi/ZjRrf-,F",rNU$Z!N=T*Bu5!/>Sb6_3V +V\f/Ndl@\NDr$d.cY/rr60M]u-hP[Xg?$J9\`JfkN]<P9f)$(N7iY#rM50Q23s96/&!@P+g@]s<'*Q/l +A_aBP'<.g"i!:\hLQpk"o^W^?^_(0#YW7SU>VAH7;2sLs`'jg$9K!jL>3P(c7Q89=CqP`LLtI,jp+$oh +qqr3qEHWF_+Q'e,9sHnk;.*Zf;LMk['[gpl;dNK-@3?XbU]iFKq0fZpR;gt1pRZkEM<$,X3Z](C59?.` +G%Vl,CkELEA,f2F^V8+*PfU!0e!B"-4g*+//j57[YP/?(J:8LgfYs&ur-01m`ZK&tgnY0\-4]nB\-p.7 +?L32mNlM1-_mh`KLT`@pDG-NT)st`KmAP&?5#f.G`3_H7_sVSm7%5D"lWKn2\(qF+2H$M1H_3E,7u*+W +.nCB\9(%j)D46>QM+b%r;1Tu7@s4Vp]f)Q.A,'k,2V>'X=Z2jKf!:^8T^6YQD_M[2:BN0`_A9-piclFn +S8:MMGHtk0U66UZo9i02*Z(A)XTF-3drI?&,@BQOPF^/6BZ^8"';UeS,;uhR^5U/8o[Y8,:$9"ug5XTk +aU!>XN[qt5il+rOFII"cT/Grs#Un4V<-i?]2S["MV2J<M%3h.B3R8SBM`DCkRgQc7/A4<4\0[[6)JkI> +^.09OE4L7Q8rLlolEsr(4;E(@]D*kI$g-P_;&<FZQ3:QHZ?ElUlS\*uOL2W2Q,Hb4hM4JP&bZXYhgE#/ +Hm%daADGmUDj<)hg]SB5.CMr/Rnp,!?0(879-!s49cqOLI01o?P*l9&#WJhdq*^`Y.Bee\b7LRDM+]Nd +&EgCc@j?&J4d:"4W'C'RLKTS"QY4G(6?0_D@nAOHPfSu,.C+_AlIY2m8Ma/c"$,L(4pZ3DgXUX(`4S4Q +INP)*NqM2HjZ1V+SNQXYbMR?dE6]UqA=_j&[lUcV`F\a9@!R$XF7Ph".'tP!b!fK_r'i4NaG)[Gj8=-' +2Ef)omd_?1?.*dVa1168*m\iOQNYoJ?Cp1^?<0S!DR4#*>3(P[j+[]6mZ`&<&kEfUT&Ue>`&&-K]0%c^ +rT-&beZT7Qk7.$'g!k>6l4P&GR./O]Eq2m8Wp)ON7e7T]WQfMNCh0-t(RpiF81laDF.AG$eP@D-+1s_V +Ss:.aj.&5aMn\(rB+\i;i@).6W0c[,7rVJ9X,C6S*1o&VRUE[`3p&HJeb/bQHuT@#/#uuki#a,dR8#Pd +K;PNpB7rqRbXJ<;V]$p,ciZoYF.Fp@n$(&SH=cQA'NZV\"7<r.o,4BE*RQ3IWAi=B;Hu7j4sNE7l'LNo +ou7S6[WrfV&>?M0mN\N<8DPMn_a)P'mQNsY6;d&CmCj:*jEg?7WqVKS6!s4$V&H9'QN,aG+h0-#A=:u8 +WZTeJT@%Fts-#X`o,mSHc+i`c*rgV]`VJ[M#YOG0Jq"$\%?:c[&74C(q?RW&%C"_j:V9.("-hT`1qij5 +j:oD7Gn@//'Eee]pW]+k2ft`.,[r#hr8ppJXOJ<'^D+3`i9c/IWje<eSS%$NSeORN%UuICOT&*'4V.:i +e&JF1m+TB0&nn^WdVL&9GPids5Y>%j/GJml$UPS9@t6MB@9'J4]dtLjV+`(fI_PSKSeh3m2uQDTnT139 +m&(h;pP%OkXoK9>HG.e?J%h"VXkk4jEktL@D-</*%TBD10pt09[3q2ie%.X*ip1^RT"a_Gbiu`(P7qH4 +EZ_i>[R$<m\QD-X^)_4WarIHLpLS*$,NK0>M1@qHGfq5!lSdQtT7]J4"-iZ;8?*34GJ]Hhc]M4g<30=E +eCZ9LVlUkp<&!t`c^4\PA2_#i6!:!\C@(G(/EBV91#odZQj?2122nr$k#M".N2O&Wip0NJnVA\`b!KTH +_M;;87,P6tdja0!IfrN9#cKb0<8JsrX#[,':02hEIXS:'.Ol+0-o..]_p"K50XQhMfp^'`s+I=_n3iN` +LhVJ-69mKb@"k=*f.'$C\BIR7Y\1pm8BsS+$<2Ga?3/WT3;Dh)&.qtS6TTIWK0Vu)3s+=s%`'Xt'.FY, +6)F<M8>m[Q8M'>=H8+F]:>7u8&Hoq(GiPD-5ub&Y"-Lh]qOT-.38@HM<Q[p\no3j>F#WE@(q<ZCJab.5 +Zcjf2Rn\'(4:p2!HrTomYUX<%pQ($@r'Njk,6T9t,K^U[85t.uV)I?@hP0ZS!K-t[6UBn78gk+pf4?'O +Y<?C_+p"+^3_T:5]mft1*WhLm)^,ehhd&Jk\"r(`^3;u/Lu;C2OqdGE]NMbU"YrT'g&[AQ.RRr0BRP)X +I,Ikk$LVUk.-"[<FPoREN34hFs*@BCV90kikNO50$m/#g6:g'h:0[8Bg'.UHl9Ro>i;m0rJb9(S30'(j +.V^L'+0>cbmHZ*l]l,73^$d-$Ol03"GTV_M*:]&iV:'/A+;=AB3de-Wl'm=QG=U<<]XEgT>7\m/f:?s5 +2lGu"m[OX>RR2FZ`n-i8L_YeO@++lV7.$9s(C6T^s-qW_,_FZ4E=:$UQBTDTGh3C2MTVF:!KO"!#N=6R +CcXY6T-NpX:,u4ZH>#lpd>k'JS<nI?E+oE--A"bO\0$TW(HAoH3oZ).>!i&j6jU26is10*j_shNd269; +o26^1Am&NE2FlRm\=dJM)[0?qfonAi:m^`9)7TOfH-/DhM(o8S4=Zs,lHPTSDVF@Y6%$OpI,ST7`=gOL +*XPb[k(2`^;M?Vk-s\Jo.E)mK2iM*BNYu_*"d<]#*OF]rLr71@!=*+jq#X3qT*mr_b,NWE3)8f36L3gX +[P%>iU2TVo7GkHCf5%nO.e!^MdtT*J+tC-'d?$B@*H?CmkV7!0[M,-pcPlQ@(kQ$[jAH)sp)dZNfF`uR +7W#m5E*DF=\skmBo:3NL/q$N]@VFA8at`1;_t#_b+,J+QTf1\rXo8mZk7c%-f<K!d@+.B6flXtP*l*n, +6\'b"asI9I_.l&^,1R-/fQPEr7i0:5^mQL"'F2[BGIBkXdZMBr$Ba9eA.F-=:.,N#+_nLc!>15RgA$5< +.=fX;Fef$.DH7,o^aK/R9+#'[VE8jbES@J3.`Z*Z:IoN$?XBWM:/qCoW8An!,j16n0okCVaVrk>TZge! +8$&q%T<l]IB2+6]`C1Ap!B9'\0Z*cFdr%R>AdU_6DM@dmoF[OS=afl)<^_>B0nWk-UaWs"r_5iIhPVf= +NfHMYVK+XfZ$*FPl(e:rYm>nL#PhK00dCN<e'MV=aQr&Gp=MBE<+t"\iDW-cAi!J94a1T@:%`LjA;-/% +cH[fE":Sn%98d2tbqUE9bF?pW"Kj0e7$1`7b"Me_*D$Ob/n+DV36Y_GLsGK6%;,t]kU97@F#XqaESa)& +VNQ",qI)ggC!>=&`$/E@(#dHBm1-9hYlE4q<Xog(?>C3_LL;>I`Hed-2^If!13"&HkMAG2h%Y:Ag]#V- +b.-u;Ms?`mrQKaIX5rLCBXKJu2&1D$;i^0,gSp/_A]'F9`#;N5nBrjem%OErW<6H[P!%Rrl5GU^<XS6. +BmbZf,!c]H(gWfn%n&s\B]B>l3W]pZ#WPC*S/WA)>i6@]DTsPGpTrf6=;)!c6NCh>:WtO7AP;:I!F3n@ +*$2oG4Db9-'g0<[F'.[-DD)r[0/]GL0\SeDJcdap;.clBoFQee^AOZAq`7bRrJJ>Bg@Dtug@MRp\W*+G +nPD^#TjN9Qjcg^,kc.8hhNOr5)2;iJ_d>8@Te>lWKHXcSrV[m!F*$%PD(jK]/d=A.5'/aVFR_$Q=:0,+ +rLYr^1BAk1X]M<u5OnF1^\S_=:IQC:f1'W1[F)QIro36absgNWolKutQb(/gXP?<`[@K)C#`;PU?Os`J +Df<5AHUr*@':&1q%o-8/7fZf^kN$E,H`u#aX57_Z\6hsRQ&dQ<&g%E@@'f#."#9K??IXHgK2]Vn;!mM_ +D%kV=`qR.>5$8@MG#qn_M3YrBA3#6tC5u(rs1cd+3L1sOY,pK\L^h!VS;6d5nqG0`X5<q6"6ha:X?NP9 +W^nAjrK?(AJ/AockZ77144Ed;UWOI-Jn#taO5P]ir`tVRq!4dtK>gd^2972H+S[:3j];JC@2+Yu@f9E8 +b?8-DkgGj]g[q$e<i9(sUiFs<FVAD)=,a?J.s-&-XS[KZS&2c;B'Q^laf;J]+D1@[!n`n,b\Eo)M/6NN +Ar"^(`e/4a!fDte!kCA3G7>Mq^'Wp])7]*'.PLRB'egG;$746@)"p#9Y%gWQN[j-!H:AAaWTU.'8D1/* +`8'rj)bC?!,4"tc/@sRU"bY.Xn`q.4Jj)nsBK:DaNJn5"[ctiihh)oR-P*&"Y1h^,0?"'nGH#_CE\S1; +4sPBLAt'Uuk*N4=Z^lF6?flXs\KRPs'g+cpAqWYq#&THrKG,AZIa<A\FF"e>V=W8J3^'AJl/PX/Sdu<n +bMX4:aYM3TFd`^_A],EOm*`r_lN">K0l<M.j)qlR"89`/Se4^>T`U^r#Mq8V$10DCJs(mg&?E7lh0\sQ +K&ATI)nu_*%p9jmOa%^&$`@sN,%a]g*\p!o.BC9^\4=<i%\N8KEofrZAHh['FZFllTI`ohP(dJ/[c\2l +F-d,hHFDfhR;=QWb91ZrkgFhF),MkRa?rfIn])&CG5`ng<()&>Qfem&?uMf3bhTE?1#]`UDWpMP9goo[ +SSYD-'XVXs@l;`7?W7/F\f4NV,^IJ*UJU"+:nPit\J`*"eu"lKQgu[5H,s=M/Xb?q4J/C]j+_'0e[8cT +;!+T(jWSF+Na":)9ZcPQ\'<p/#Erbq9%'^@%d@dIm-2,/MJjPYlX?rA-'Bo0Gpj"B&)#^Mqt,\nR6%TT +CmhX22d=_rdOZ@733T<K=5750rT(IH](\C(Nk9$<AJ`ppRpg"L0f6^^RaJ>,fpADJThY-S49p-[Rh6>/ +amP2IcOl$&dj1)8Pa#i4hG[4Tc!,BmW:0+n1G:f0JB^^S>TT`^N4VEF,I+39m2gH6Taoe;kY/X*+5q-c +G6TS@@f+sga=-Q$&[s<dC*a4Y<f##-fk"1h=A$$2R$.Ttm>7n9kNN#]d;RC'-EJ3MG/-E0gaI[[2;X(N +4hb5[eb/53QH<m2$k:m5.3RO(V,%VE\l(dsZ9Os+;F$\[N/nScOO';F&L]h1/TbZ]$5D6caflMLWEGZR +N,`Kc`XUJW.%%LtZ>3_7r,-dfGPN@>=N0IT47>,aB?E>^iin6I"9(<o46@6\mR"V^N8r<sRnW`VR2R[" +ZRe'c3kk0ci4<-O,2FijB6C[#"hI<b=+1n&h4j"Oi%;R1gBDa>`1R(^DC#=$Iq@[:ab@tmZYcJkd"gn[ +E8>O'gJU.ldF9uha7bVc)9jq^g,1J.TMj<@^9Ke+>_,c/oK)'TCh>kP..JXf^*(Zn:Ou_^gQ@?#leWE' +@`dP0Bk$n^]oAk)hCPOGfoU5k9g8L-**h_$\1sHdY<-#aXt3OVV_?4R\06,\>Ns$CcN4<iB:O6`F>2El +WZ*1n[$iZ/1^XZ+*n/tBLg".$"uPjHZgX?0FUuZVk<El.c_+pXo3U#dolP.XZ:-[:%$*6CAohAk*`Yt, +eS7eTs"b2<_FoB6O'%#JN_ql@J.pSFLSoa9TV'T*$.&(<[?UZP8BV^eR6=8Od9$a6G/ZI/[X:Oh5J6k- +2Jmr[Da,23ktS_FHNKIq$mt7,_e0g:dQ2(#],,q;DY.4CCA%)hWDe+L54p!-)8"0MDk816<NoEA*Beh* +lo]Q44NetUTYli+=?$RrDI!4Gh&As3O&#NCOM]R<N(&a;]ZuJkR2<!NRgDR.i)APg(6,jXZ%H5!W/`*R +(6T19YfInNK4Xo%G#YEd6@"%W&l7kG]u?Q!6hEjTCan#Bs.Ujc88=Uq5+S>"R<i-<]lt[\(6#@jf[&?i +-87AIhs0Ah@+pLVo:MDi2&C^FB.QLYe!dFXdB^bOIMk.Jm7KD*Ak]!`<]#;$4(qV=XPI1.$_,nj3=]:H +n$8lHs2)(%6-V2VM&&8#i0nZ6+KO6-U,>YQp>6"(T)JbSIe!=`VVTIC4T+iU=>O1:`F$M<PBnWl+VkG] +Mde++i-)BQEsAs.m44Y1U$1jI=H09d4jRa2JZ,t^.O7K)r8ip?$]LC'?uA\goD5ObA3>J`Lsi$%7`*** +qt<ig'T)QK0a1#?S]5C>/8T)>HWV8e:G*s)^K(Vs(9I'\hF<tQCX-XZO7e-(P"bd/<-TMIVm'$h=!"dO +D6Mk$I5]Tq,ojY>cUY?sR2e]gLpI#5YUH=15Oi/eU4dneI$$N^?ns2$r$MuG`Isb1.A[,&439DkT8qtV +hq4<q1G4t<+r&HP&?K839Nij28W&?<4ZJg!erXHr*V'^g3SXA4-ZnhReSN8m<f7#VR2ae$^%%sMK&aJm +'?@;f)ED!^7pWKg#@[7ZI];\uL3![c_!_Jm(AqE._1d[U2goNjNYZE$RrA^NXYS-[:QX^\C*>Ao'ar:I +QFD,Z$P<d84"jTi[<[KhC8,_Tg!q'mm]/MbKM1+<Qs[mmCR@BR6!upij%[:@M=:!B7_ag"(q$:uV*3N_ +5"`Kh<_oFH'cj+L'pYF4%LTf439\PT(ZAIrc[L"@@1($ndefXrf!W%*26\@\ZJ5TF3\:m&>gbjp$(nH; +E4Ic1,3Fe*A<3rc2V$uaAZOaZ2(SX'hrNXc_IN%n;4Ouo7]kKCdX8G?C:lECo.0QM_b.2!D(_DjaS%n5 +/:(^ta'uI6r=p):p&$1TmV1i$]/T;W>HX?fYq3qQg./^o,AZV6=ac"8W6ce`1WWOT3uDsuXj,\P?AY)\ +rRkiGdkonJ,rgLL`bTs=c'HHd:J8Yc[Q3;]nGX1#<FF4q68,]q^u?I.r$Nh@Fl?sCR?M^O/BNWm^FY`= +\g\r-!7Rk7i1TA?GB!O2g-P^1=C\8l"'=]RJBc!!#0]jnm@l(;r0<&j:YH7?,_,;bJ]M1%<rXu%g.s9r +l1n+KId0';2F>a)3q$'R;&bm;=\JLOf,IMU/4O-UVLki3g&1.*<,`k[,sp;CGFo1UTd+lNW*!Sd&N732 +-YYA`$er'D0D?LlVO=B3=f\o'*lDWiR?d<\H?N5Fa$Ars(KuNhRC/s#B,5j'[j8Ygr=0S>Y,ej/E1_TJ +C+[Z7'748J9.+M[(lk4U[4BQKNN?F(b08CZ%Sm'l?1pVlZZZZHPX*a<#'ORZV.NkMqe]EEj#X@b]ZEl1 +VjSi?3?4XH/KaE,qhD^na"<'rb]BL^MC.2H\.[A+8-?/1l\HG<.bOLnZ!G1Z8fJLH^pZqS-J-"YL^tnQ +T8hIkbOK..74lsu[Acq\/R1gWitL`E\^W^4=XJ%WD6@lT4E#O@RedbF=//Fq1R'r";0/k?c0.Gj[rQY_ +pA5a_X-J!UPJB9gI9cA^XPH1gIq%b4NhQ1>PM-a/909nZNqp9GonYV"424?)4a);'-&m*1Urau?N3A3V +AVf[AYoSTI0q"F(fbn%((uf-/Ok0p+S5?l_F#(JQ3N6B)S5bD+lUJr&PC<&ZYa.EU=!p%bk7a,r&I&E0 +>C;KuccJqY1\pj^cAd-2YAc^FbA:'cTa-Lb-hcp>p@6T\^*qAjIr&ss_*)"lO+E%nG[:6Ph34bpO/'s5 +OcUtDm+d'&l&n;ZQZ>FjW_3rO,$uYD?EU!c%;OEl]I>o*]:ope<>7iZ?M&BbMFe[FH(%SmE/">(-#O^\ +"J,g#<_#cqcY"fnj+\>bA]ScbXmrN+\i^8HVh\`f>amn'o5)%D7=SP2Ke`OaE<M@3h"ocA:eOp]R0b?e +S**<M1iSHXT&tnADd"g>G8KC]r2N7WM\c+k(@BrI3K)ae<]tRgA^Fj14BGA$ZN^R:Q^IgVI;+*AGai:J +oHmY,rQ?uq!sEpc^ZoL]>dP^F2UrM.NL$_g?g"#7gZp#roSQ:Ek\2Vl?>'0&D"&^-SFQ9QCS182*W>?9 +TXV/o,OqYo3Jd,>3.L3pS#;6HMjfEo=*oK`n!p.rd#6Ib0cM,;Dd'U5c0s4Nmp`3gH[a_.+-r3RcDSF3 +lZ#-,(2l7bQC3[JY$%OZY\QOpMU,1L:s*&1ocUE>^qNbBRpfc<hp#05\3ITcj-6t83(cVdaaoG,MD@,; +C/'1=F[h?[;_Ru@NCJcJ?)Gif@\ADcr@`it$G4&P]]ni^nQjO.^ZniTd3;EV7Gep#.=XJ+Y7d#5r=U,H +T)I6G47?tJ)kGPlmU\,sVgt*mm3)'ef\MYK9fF)Nmu!##ea=JRC(XL%g8hV;N,suD2);74pnl`;?NpoS +?F5F&>2OM<Tb[f@HNU$%H4rHlG=@9,[P>m:l0]_2^$0;HT6=e'H0Q/smf#YuS+L9sYfXRA*/95Y`ostA +h.'kl;np*&^G&>jc,">co1S3WGdK;KE8EK7*A$b:9m-ESe==<rO7tbP+gQ)$nLW6VFPm`H-Y>Z8HhiZ_ +]bS'3%Uc!NBajhh.e@)mFPRjKF-limf,"5I4T*`GU`99@//YcW33lJ?[gGSBS+Tl,Y3VH4`pY(Y\J),b +H+T1,=MiIX%,KbfNrB?[J!kX0qI`^Wh7n`WD5Vk!INoiYVM2"AVgi3o^]es"rtG>eQa(r2Dj^?5oP_fG +#BTV^n"4RSF-nSWr5OnLj8DbID>IA1T52oXAR$1n&bJrMVH][gfq-dT3lC$*>1EOur`]$R=?/k&dUVDU +k]0kE8S9*0Rgr3bbPaq`It"R[>Ckr(]WN!Z)E"M.!gi!UN>8rS8^k'K=-*=MBu_.!g@@.j2u:15YY<o7 +^!o@Ylr\i$#X>I,\5q6]5:^]@"o6^V%)`l/*;:Oe*1D@ec-X6i6d<TAP3=\hQXtm<B8/&!c,+[FR7%s/ +bhVO9[/sEB]238T?"/O@ZV7l@kVD=gR%`[?4i3od69[bjUH`?(SU]\`T.p+SSE]9FNRJL<1VM6$T7t4E +2.l(tkkU)7=aoiU[EgI4:B(sQ1\K)<APW9LYjV/P+S:^SFqiE:jPO&i0&HWH>_+DZK?;SBCDdRCT*;Q; +'jW?:1M4Q4>ilY7/(!iuP^EBnZq=tS)i*'Tk1;9tobFu?kd$fq\BIH"<oA><fa?MXWtp'+hu@NQ#Hp9[ +=;90STD72K71&Fdieu;6"Qk,44TC8urbC28L/jN)>m%-eAt`T3!E60=c[TEh>qc-"`,/Zmn1"tKYrf]h +^$G+A)kE2"j?GLYXd8is?/[!%*Rq\.#OV;6@*?.q['mn?ZUsV#&TT:f\DD@tDLe6\[T^3X4A:&Dl<OLm +s0bPo5@Dl7c[TEh=l88uGEs"\$='k%>m"$O\kRr:?[/EONjTE[j@JZe2S&Z>oWEp[mq9,HLg10[10\A$ +Y_0>rbI?p::eT9RB2RfELj@F\)Q"6DZW^V&618QE@6n9P6nH$P590s5p*Bm)Bo^=uH<4kcXVpK>1*O_" +Dnmp`i2,J>hAnaqAthKQ?2"g\^?])!F8"+fKA@l.;V.KNU>@c3lWro&@fpN(Pr3k2]d^"Zm;5tA]3>*_ +FoQ.B5F2!\OX-pV1;m+7'[\V97q7:`hXs$]r!##%Dj9msR4/lEGP,;MZWBM^dSCXt6[S)4&%ajj_'LfQ +0&tHYDoQ)R2q)u_G"\`,R(M&lma)n:/(/)&AaK82^TS5[Y<@*H_RbBD#RU?aisq:!Iq%YJZeL=cl%[^4 +4Q?(ai]:D+D2(RU]c"uibW=ep3HGg!7TGArRaAZY$ZpUW>n%mhX!-aS905\RqSE=djI8=\j1@#nkP*B9 +W^WA!B^_@Qk`'?);r4C8%WU)q.e+il'Z;U%CV2>K&as"Of>+U`8/'m4>ll2r+1hYk1J`nnD5OYe"N>Ru +@F51ZFLF1d[bg$@]4Ti>X<H)*Zq*_%(P\3/hLl&e^+9'hr@4m-e0;%.[PudaHEFD#)Xhe3&Dne!n>i9+ +>4ePm;`l9)Z&GG03bAj!F0KIfZH'0JL!Q2RK],^ST',QjiilIlE1jkAT`pcQmN`V7!A-Sp\)9T[b8(ju +%5S_7>fE+!c>c5EhM"V9<e*\eV5.b&I+*qZi`QD(L'<p;()C/+BYbu7'JM'9oG`SaP2?5WZJ[3Mb"duK +g6ms)QaN:UMF2fL(h2(V,?4qb_L`.u4\r3*Sb8gU]#TEGo+H`\(Is,o>lC.s'kkF+Nupi5J((pWAPbfe +#.EI)Mj?(_S]8eHAY6!p&N)s?`m1N8@&%c3_Qu)P/]eS^jfS%*6&-MN.I6ld_g)&fGPL4cQQFXk@D2l& +&483(p?u%CO\>-K6aTI2Q<bUO?=,[%B&%K[V-<k!0G7```5f=R*BGph\.?mJ`3QfmH_7V:/Y#q^fc6Pb +AUTV\@MQYf3%("hF.M$YZ`d(n]K&M"_4bk9Qn=9):bK[jLqrE[C2]DcB#aUHU_SkID2`l_gs2>US^q+> +c.E[u(HR%P\?m3e8"u('3@W4D1!KP]-gE./p@%IF[J+(apV'ppC07n8H\L@Ndr9%L6[rdcAsUNh>O4Vp +knPHXQ+ps>\pG?m>IneX"USk2Z\Q8hB[sZg41'5'p+Mq.g]cKYs4S\[*joa`$VLCK`K>7N4rtGYQQ,iX +1il79HQN'p_qYq5PpLfio(pZ-2jPL1Y_U?CFac-Fg+t;ia^`89;<Km?N9pbI*XeC)%LZ]0/j5"\aIfB= +a&m7MoZhJ?M!#Ykb]ns)dHu5&h/7ldPkamKIZOFHa!m\U5I!t;arM@t!]+-O<2`@V*2c+DZ$T:8EP'54 +I,CB7UX$D[<t:;rH[%?8!$*#M?,=?Zs#HfKZM4.jLc8i`D"?m(Q<t/U$dBcTgaPH.EF"-a?mi@FN(A^c +1:O@CV!Qe2Sara3)H#84)j5(qqXc0X$eBXD734U</qcCW?sBh:Ho!0E#,7``Hh1cQqpCfZj!'YnZ1_2O +O*%gSG-.#OmjmiDN8&,=E^Ej!f(#n<'JLqWjY=-Z1%.H)$aI>7A5$IiV3`Eu"d%"K6@ct=-Y#2NpMZ-& +j(r,l<*OH2fbuRp?#Dbo_\(JeL+(Y8Q&s-\5!6]A/j0,T`#S>$KoK/m#5ratrpIK6oZ)5pm11.Id!r,q +gFsl-H,l#R;+Yl'/Qqc#)3uCrjLfPQ_fnUQbSY('!5(/'U!9j-"kJRV45O;n5n8WV@^thSmh%[+JhGuh +)KH2-DoZf([iJ6t'OEkPkd5D>Y)ODR41QO5EMLR7e"8a?_jWZ"9WR'k[iG$H8(P'7JYuMb\u-TM1h>Ma +?ZZ18hAchPj1`3OG+?hnbKaJ)+Rb"si0nT>[W$uSKH]@WBU[`a:V2?<H`^\AYA\``H@Lc$\W;BJQU=XC +)cKrXc[Xk4.r6DghtT<pCui?MGYH?UflD&$2g-&j2f_q&ZXR?TAje)n\C,TuM!@s^>nkV%?i$'Q+62>X +D4fh*T[aaR(/kMQDqr7!e?^eLX_()cSBu$E.N.,=a<'&*lVh`,"1ZS+3KmS"[Als`kgZ=tX4`7b$OsN8 +BJhAfi2tNT%]s>53YuNgc+)hJ2(_Y`Xjqg'/7j^jSmBn\C#3%<?8%;$BC-,0VC.YAX@Y"A+*U?;;`\rt +6)tlZ>0Xjceatdfe)9-.3eRJ-fZ^,@lptC"<S]*\CX)VQI6qE_*KI7.m`;OB>0W(D%+K$,L-Vg8RQjpG +6TZ9pRN2^qWR\@_3a,6:Y511_9r%L2C3J[C+Q(Q#S$VS):T`>#RGHc%htbi<)J)79WLU$9C-&(6Drp=H +mIrIn6K3baA/+90NLLqn"42g^+q>(YOMUSlIE3ho-Oupq7J_0g]91L?jiILNa@P3Ghi)1]p^ZLT"u<2T ++!MtY#]]33I;:1EE9p&?rtC=^*D([bFZko]53%#\S4_^e8,dDHUMZ*&_lPZJgiIN*Ag;&5>I]4)-#Yt/ +O&)_o^3iMH)BPm9kX/\:LCp)E=j5H)H+4f1"au^S93`J,rB.eZ*aW$^0d/,@CM12[Dk5>_aZj_G0*qC* +iX49V]0X7*I/QgL[.='ADp^s"cB.4FiscC)>^k^pkCb#):#q),4?'et,gX`/Q"_aVG-(b6MmH';%Ba8# +a[0=g`%dWA2_2mBo%`;_!I8Q\[g%-G+NsiFe"?2:p2:qW=RU`Kc0AHHa-#OsrFS/nS(4indg?ntHFE9P +=lPk5cX(?u7CSS$Nph#d2!<6!NH%X5C'TMVa#*CPk;8opk?d0V&%ndI#'isGnsfmCVg"m2PLYc2Vk\X_ +F/ss8f/sPdpPGSQkRPe,<u/:+[94_hgq"@+>VR-*%uda_XCeuX>If&)S=p0,Dn2$K__TTu%bKA<g-qF* +nt6Zig!IIp\Q-#3@r3ii%Zoihnk2oQ>8?U!So`qD0?J9nGG^Jb%O,3<7b)\@70sk&gk&3;o%]*Ae-68@ +_`^-LT=:tAL&ROK\k`J=.2R0TY_;F+:Um9!SpM%;A\$NF6_9c<9heAt-#kO1V3N<s6Cnkh+j[EIPh9"P +7g?M>E@%p!8@gU&mQp`9k8)Km;k@2uUQFYl,gRKInf0)NH-XW*JESf41E5nTV6GJD2DKjI/^LCTP38FN +cQgbm/s,6CDqcP`9k;bM4?'aVDT4798Y/#rH8i<D#((D;X\\G;7fO^ZC!C'^=iaP\43f=BI-3XgEDis> +Z[RacrQ'&\8jDTIaS5[c*N+D]OBZPA);hnnAR9<kDB$\OZR'.mjfElV!Lu%DG^e9=T"Wm*cecW$e(E\> +/0tA$%A'dK\!j_&hf>/)SDEu.O8HjBmVS2D!_`OGjGbg?]^$!R1X,"37Y7_'LGn/(:`e=@<lHkhH])p+ +L\;4+$#3P_6R<o=\)\^M,NL"846.Q#s6X)>/:#=/%XH,l%sb)ngC2.jHcNj"]M8(?6Z/oDm9+f$B&@Bd +)Op;ZA\Pb;U"s;Y@ctBA-QRJ'8FhirjItDEf9(j^clF_5BcE$V&++Z"[QX#k^!*T;8'c'9Q_(lP>*hA4 +1up4B?SOoeEUoP_mW4kBW_jgXN#n@</>_eRnkbI6OQ<)E(MHDuH[d,E+R_V;5P?XGLf?ITFnqM*2rB^P +N&!mEg-b^3PD=>:nr1`EFkVm613KMS])]0sP8gmIJ-lunPU8*F+]%5o5,0:aA,)!"Wg>id"HH@6^IrM] +SjWC<LR>*)HRglY;B?05Gt;&LJ>H)ErAW<1&FY*XEfQaM2WQ$");==H%_MS%#5c@9*BT:C#sDl@BbQU> +aH9![$@.G!Y<s@OWeW\N,6GhjR_"2Z(t!^.r^RV7r\sEHrJTnGX64m-Wm-r%c^/<O%P%66"]GSNj]@"> +q,\4Bf'+qhm;<<i;7bRYUins[m,t;(,2NLt.mJj_D4V_C;.DpKHg03D=PtiDIq]V,XZZjU\p"t##@SX0 +$$IeoS@cRrC[P94Xb==ED?lVBDESMYqd>fe-uepf*u$hQ_?pj>h0/sRQM/g9#=P;OlA9;h^a&ae^YO(# +!A+WZTKg0W4/^q`$2s0*4+$arDf?h,mr3&rC//IHos6^O:re0W=]ABT)"X;:O5rl/o_"@*b8.k\:2=4a +[S[l=*c2/Sa3hAp8'_E\6]3_f>9q?*'R9+pdWK*/*HX7-'u/%GU@B8,=LA2@6`nZLKK:0'Z8gVo&=?@B +E$,qS"rp@!IHM#,]c3=UoJ"V?e&GaCT?cIVm5jOaFNTVci#)e8\A_.Sh'Z[#%lY['8Ph9^2O-?:9j6;! +P.A:0"#0p9&FHJ>G,eQ@@mLu[9Sij6dB+5/YFqq1/E[lVX9\rb2j.6L2_AI#Y[B-mWNX2::BdolqRKr. +/9&qB=$]:upee9R1ZF"IK%ZKY[*]41-S+Kri:`Gp*#.A(di]?0/NgXt?9&1l=_,>NbmsnT@KKT[1,A[` +%cs#!%Mr=,6S=a8.APfF8AdFc.QBiX/&)F=@"(:0$9OdBA`G:!G^X#@Nj#\FFI]Q4.aT^?BDoj0ri?o@ +TC#pR]O(D6^fUH?p"BrVU1!Dq6$?msI"Q6cgjV76]!EWq6$dt"0.^W9&<(bRJq522H@$oj=76uVOdWMt +IsmgrZ9)\5)^*ma2@9+[^?R:<kOl:`2-AOTfA-8,2q7^-6S)rfX6hH?#i<k9h-]u*h40ms)O'na3OCC% +HIMi=CFFR3q26nFhsbK[H\1nBUb)<SO#F(!fTH!^3,MsXoIY#gn8nm=[QsCb]PY"tkN`q$na"Qc8)(D! +T:sml0ClX<S'ELrm9-jcYOejCYIfA=C"in?Li$dUqSjOU4ic/-b2Cm(EbJ\(oqjg*U)!/j(2_'HJd#e@ +2GY^t]:`Aq[uUS`Wb@KqKccqhiP_/2TQpS$L[W6[?K10,^pXFFEOWD<ou#F[i+";<"UW&L:Q58U-djP[ +m\-7\AEdL<eN;C6r@U(!R_J<m_"dsGAC,TR[Lo`^^rB;mX+u(-"I]&o)D3,71E#n.VnQVI)W8PAguQ5p +a'GJ&Xg8>3!MA##?K7(q@;.d.n+;Ej*<i"uOK;hts7JK.eP-SaH4)2mOA:O:Ya^-h!d*&ZQKAC6V$5Wg +TKbWDJd8l\XFJOS[XgBIR,u5n5!J)10eM@#Ql_/LTF[c\,>"p)"in(WU'0fJ,E(4PFlOd]X&H)A1=1sf +qVsre*U;$n>Up"i^mL9?#oe$]F=BqcKeF_"h0*Y4r*Vh,"U\SOml,\[JWCfkLlPXa]s-(Mf5sd-)LLjf +e^[OKc;rbHmF6'Y7>94CY6qou99`^$c1QqU[TZ/aFi-!H/?gDN?h(R!Z@9OE];-PJH>bdLfJ^?P0;n2f +)Mi[h;q.i69#lcXJ'Bd')]2XNn:k6/[3DhGbiUj[04,uE-MaY(M07+3=>L_4E"eNH-66uuAk6Rq-3W?G +@"Gfo^+F4(L:%gV;3U.5o)gjaTUf:pgWu9e>Rc/I(ISbID'mI!jsFKB*8Eq*P=KMBn?cI)j<jZ1\-[W_ +E"i.l;3#K,?!h]'%n1FN*XM:POCd\+o/!Y]k4(Jgc)eLK1U["\*@HU"kme&B@e4H-kPY0FgCSLu+(3j1 +VTr"Oc1sN^=`Z4&`nQelkJaLO!b%;-mKp9rgBaus_ufXlDl`(!qOn=I?'JjRK!%&gRI;ZEc0f9KXC.?8 +Git/P?1uNInj7u%P8@>R!>S-p9L/Pap=45TKR&/l:d+M.SV29]4$smLZJ,ETdGU(0E1%B[Os!Q;-od_^ +*ZqC-(*$*5'_jSLLOO3II:V3%hCMGWc@3.^WMKT(c&gbNW5AgtQmj%N.*"Xt-^;)0f/Y!IBTp`o$O.us +K$ug)27!4Ti,n]-G]ueYK>"lCMt(G(4WDN-DTO&Oq*Hag,2(f3qNk,f6U%Q$rPePsM?AOf/IaeQQ8)fi +QN^IZ3mP(XK#?d9)nu`3naj+cL[h]/k/6sWOPI?(dLoH%!X7:8SP'1A'[tn%2dc5lSAeBh1abCnMr1O= +JL@+s5f!>g\$)WceXI>=R'Ct$HVq`fUaa=5=)XNeJn+JNTmbN3PQhV#2Aa*)=*JWVE9\C>"';[3@[)64 +VBE=NhW-W6Z$HR`os3KaB50C>57>bY4p=-@;qDQVFLM(;F\h2]L,:WUPMZuo@LWp5e(JV,`f$3ATBVjm +G)hs8E8cc?S/+"=:1qD,D/e`M;"$:Pl-Fs^]2=+HDD`9eh:dh;?,$k4RoP'W6^ps$En"]d+k3GS6aN`9 +.V%X$RoPS/)k0jt32a#a&Y@5S"kQfAIdb#Zc=5<_IMKfdbp<jY`AV%3>L"="S+X"WeXI543ZU]S6YoD5 +BQL%4q,o;8%2h3-Dkbn%eXIt@EqR/4.T^Q>mo(0l'))@h0FP$4JQI:8gtF_&Kf2\u%;hUB6M[K[IMEi> +>hPYH;Z'"8>$H1ETX2B@UrA9o4ps^I)[0(9)D!HS^BW0$'Ye4kS"^V3"h#+Cr#.-N;Z*O\U%jTKd5,)h +"]Ljr:J83qXqj_$CQRO$'Ye341`2*WK.Vf:2kUl"._#bim:Q#5$4]q"33nSH.=U/!`PI3']";8,hbsN3 +_-`p7/IE9($cj#n\T<Fb_ud$eIR9&ICI8'Cj?8Ekd<:42^r;77;;bIlnM^2DIGIj,aS!GXmsY7*gX)L) +45caWmZIVdF'eU$p/8FR!<&ZU$N)7ZmNig!d*ST4*oJs-g/u*0;B`ViGWO'#m37q4NB<obq/ls^1HJb` +7^S!^T*pNi45ca[]5--Wh$!u+QnW\"UOZLZh>=5[c<'e`YC^Q%M'?dqnQB]f;:'sDI-"GG[GB':\8&2/ +Mun3%p'dEhgoA\W3MAp3aA;Fn$De`G\\u'@`TP\0.0H`_>4BRPknj"s2`.,bE$amf8F9sl4IRsTP;j#t +c?LIb`[F*dDM*q=4sAJ:8>GK87tJ=G0bdf=C!J<MGqX<j`NCfhc3`48Y0:=.ZGL-KKB0C"q-^^LCH6\= +E)'ddCgquV8/2<Bf&r,sOuX)dRr/*"KP#mYGqR>r:F&$rV7btV>aM]j$Hh8%XL,f0fuZ8@lS(u`n!%#o +=1*`R5,05N"f]1c!oMr'F1eEM*2kF]i&*:Dmn[GW3n"6m1:(?\9+0&9E>qUA@jKUa74/=tpYmd>TYA^' +KUf.g1bqAo,QL4jD-ml'-j.4Z'ijCT0Atd^Lk3?9a$P[<Q#P"kT;kH4O^c`ERC;5t8PR/fG/11(Tt_cF +E"u(7^KK@3k)V)J@phfTA@OG?CV>=Do-JF81>^]rI`8EL(W`?-+t-))^$"CG;eh=r^HV?@A39L8Si=-S +K%OmPf$4.`5ofiLjg3la9.D'nA2#*Caa>2Mbq3('d<rI#kuR,d/^:$S6uIhj3o#l*i],:8Vne:AceA)K +?bn>=-EA,,9=(>.>!5Sp9PcO;$n8%pf:G`hFBqRg'HEi*c'+3?i0I[oKsPF%7*>t*^F13XmrXj1Ke!cV +;JDB#+c[^Ka]%/X#tY/\J3i%90p2'+TX2W'Qc.HA3:Q\CdDh?rlNc+q]%6T2=)]r;]F(er9%`)d$P&09 +qhkCf8FWoC/A/8(g=QH'Ae2C6G4^m6P!FRkD;sWf[=hlUY,@l02l8;T,seoF!nkB=Y;99*7]57To@2f5 +F?/8b$>0fmo=Q%Z"]0/o``IU(goQWqJi1thK/HOmE'em4=2DioFn_K'P5+KGi.m6.9"Tic3-^Vfp7R20 +d^]DJW57`j'hV0Dk.X2[i8fsb3e)K%O>jn6jVklt&sOq`S"LJN.c<IHhWC)f^)gm#qK3^:WGO[lg%KLD +Z>WU$T#]SaAjuVY.ApN#?.HA"h6G5*4(kH^=KM\?J1DCB(_b0MlWtF!S/`>7hq*"c[sm316uRRelG6Zo +,.7%Tl<3Hf4mWhF0m+SLp$_^.0bc/M^X0kfYN>@um+#n\)*<4o8mAe!C&?lLfXIeDCgB)d)+s`Vb/)RX +kW1g3a-ef6P24UN/B80Eos<R[HQ9Y)"kUb%Q^9[O9>seEDc;89/+blp"nkRb-s06b.L*4=fa9PA=WD/M +Rj1.?'C'_hk>ROu6:HZ"a$""`Vi]U[@&)[#B2I$En#Nd3kYI:^?4_`tO/jCLf4*ci(E>L%PJ7GUV%<oq +F=HX@RX'Nj,AfR\pIscom"-?_1BI*g4+>L3W9C"jMW^?/OL)IdnYY8aN^X&ArKd1@r`J_S@lr6&jgtNA +`nV\Cgn+o`ffitc'a-%^=$@!%pSS(5IgD>Pg`I.Y>hi]HM+-hCD@aS^_.3,srn*m]rO#GgJ6k5>*QgHa +Ihn%+ir3,[f#[g+\MC\0(+KpZrWIlNA&1Tq.B`$4i"20Wr$i!?mkmu[]K1"Z\fgkD<A5Tk=L="Y;,FKU +5l.QLar-M2A0fS_&h-;eH<PM0M]/.$>WCcdfEuqOeWU_>7V.L:eaJ'i;eMtcXEDU3bt"If9Aod?T2SRR +(#E<UY]Y>c')%jn3Ni+Mf(%I'GI28+rODSRh8XZipTn0H/fl2UPb\/<\,d?3=0;cqkTQQ4rP5S+hGN2X +$@'1S"0gmsNpUQic(4e52%u9c>A\410;5YRqu4c05oJ)aPh.@eGot3"_QJ9WC#g'2+4CX&9-ms3l$WK9 +!.(7un-f0Pk3m4Z#!B[QZkr,02hti^`i\Z*J72riq_kAF=ip?E3,<LPG0'-DWQbhKBPGtg0)((H''Lil +Is6Vt/&d2r\0Vm.&R74rXNuL)a7,AO"hq+DJD66n$8iMaI_=/]EJVY.c*H[?;)<l#c/0_gDU.,Hj1M=O +o>G9DD;pDn,h47?OY]kB^K<&(_h+k<//mEsr8lPVr8k+trj$Aq5>+O28R5WnW^kCSI$-7?3@3e*]ZOQ< +XR0dW3Ie*ZN"erf+9oDXRI3(^D94j)c$imoo3os\M1(LRO^?7[c#J2K[%CD!C>Wj2Y>]YC?VfC^d5H12 +$q8TtG/8lN9<@+(O4_?WQWV27`S)ij(MiE'pY)](j=0auk5%+e(V`^3X)0fO0bf=NR7orB5UN1*0N$c0 +?\.'t-D:Y.\HS2D;LD-'8Z9IcgCZ7;/>]*81'oP/>m1]S5Nf8kr=6p='Wc'o,JL+Wp@AH!M&6CM$.[eA +HRcl-E8L3<BbIGS%@DOCm6`4ol<Dc5k;3J[A\o]lPbUgKkUQS'F:XS^.$.$!^OVqlr'&f0Tn/l7do,LF +p#:@gkF"O2O]ec=[[_baf6LT3/s9I<;hjWMolXSbEfh&Ri\1ZJGQra'<*f$2RY9tl@1oSIVb*i@7[$WU +4\S2UDu$C<00k^tV[TF^Dg6(@p6SH>@tMTDoXuHQ8Fd%%))hl0JoNpF8tN9=JRP<>?Ik:7c4cZI9L93: +<mO2D_:VUeTH/f+dj3GXNm/(]U&OAuW70LE*)+lU_^4HJJOY(.4c/$5;KZr"cOFn@9L92#Cs>.!KNHot +QCr;MI%)IVqKeK"W.$lXf>A@JIso]B4VT&>jY/%NZc[`Y2WOdjE0u79UD8l9)&;i/(uGHYh*D(d0(h,^ +1A1<u[S<KWF/_1$#(.VdU#;B7fjN<*Bt<d-0bN?qQaHP_F^4)ugU;"_eFn=Fam&3V3H$Y_A\nYQOnS\3 +!FBlg:r%e_(mUMEq.0eBYi?I28lD"8*/r%a?!TB02O.0m\s5LIl=H.DO&r;a;.$+ao5c;p?-Mf84([4K +3#A,@Xu]uj(/RJ3.QHd(.bF(J<=i23=+P97WCWGlfRBj;.En2us2B)X.\C,\X,33S#gKc,^PJ;=F,[q) +D(;O627e./INRaIJ?lIY_:?0np?,Aje_MW=GGc@4mS9a*e_M*XM2h@;Y3miC0V7_'Z9n4G*,d=b9Qt^* +Q+ijXjs5SgG/NMr$Vp/2QJ'3gi+N+2aESd1EOV(=PcQL.Vlf7h5;?_k(L1uaTd!.&5ehR5[(nSjks"4M +R7UaC`to+X%V8UO"^Gk"Tq:#/T=;##lDrM<gp@XIrh:O-$#'E[<f>LDOA%f<Y8*k^+NDH!F0k&']"2DA +EnXfkF;%gs+Gk["CBZP5WdL>W`*O80l;^+YVu9k(s%j9Uq'rW5CbQq=B5_\%VR%"rA)Ze5K@WJm,%>"B +4*Au0R&md]CiGDM3ZIJ8Z#DU'cH[G,dociUn%/FBh??u)UB'-;C(Ru2FY9`,?"P_QmZ>9ch&0CVlL'mq +L\e!`$f,+Z"&sK2DV!1j,pSb"_pdFa>o%d"[T$,mJlo,ENF)im]cI<Ua6L&ZF*73$*o&]<hSTr+f-mk` +,Ds<`hb4seG/!6g1oC?9H*(Bl:bK2E0]:I<f]ml<<NKN5K*r-cXkkqlAcjMB1u^%#$Ef<..+1OpHrbQZ +.+#Y;]^i,]>XVb7Y6H5X`m9+$n9S3AqG.:Cfu>P7"ek(=!iWXIUJ5K@L3G^oDNE8T6HsA`b/dhU%,m?G +g8-B$K0mg'"c&[sjV63;-fpFK?)D#;(hZfe6I"lus&Q)/%JCQPmXS2VX5G0mQ^c&d_'*P$l]cUEeD0MT +_Vi\9_\?kRWrQ=?M]YG4i$ugAk0B/l5>ZD?D!Ou?>Cf8\H9.so)biS+grdM=><tocHA1$+.aJUp-O+I[ +lO;O,B#sa2$F=HpE%0'dASg^,duC'#P5TGReD-IH,baAok4DJkHXi+=m@CeiehSiFU-@qXL;P$T?OMp5 +"[MU[dL6,"W4<(!boHsaF8O]^:$>Fk.?o#c"F9E9d$SpGfb8Dgg#V:W4UC>"3,*5+Q3+ugPf4fnbL`.O +:ijCL))f%Yj]DjI[hmuH2DquD+<;p+qi$.0!Q^&U3lL0j<GbmiN)I'/#h3kEj8+FDDM.nnb6P<9$pR&% +"MqS@Y?1k"k'hLY.r24_k$\p)60u%4HBQU+ZcA"8muSrZRbJ1Z/c"'UQLmG>3Au*`jB+Laf%li0<RH=R +5LV\`JjgVRq5VbE%[^Zn8oQNmZcMXMA^p1)`tU3qfI29=>AqR[/`HHReJL'8R(rH?,#m=Cr)Mr*f!FO# +i^oQU!fSf:oZ!&s<-,eZPOg`nXH]/X"]Xi5F%b`D$m%J;mnV;jSH$H"[i4"i]5O09Du[E6QOF)J5/ehi +l:s>T1biq$[LmCJ*/Y>G8u>53gJg#ql_0-cYDWQ(+j]u<@b\)oQelL6ae,lg6^dOg;GOtZ6F1M^\mm-& +Y=M^m\M)e%P&4&^n1f)Qr):G>e3;lOWSi)V5PqM>R+ki`p^q+cIo3GkWnKT%<Ko<r[G78>%q%e="Yp`r +W3=8;T$d9=rUG=u$SpT?J))7Q#"F7]PFburnm<Ks%q%dB:e$*f3$c=Xs1@4Y+Ss*]Jmd.+d/C!9#<d<I +B@V?qm)X=,bC`p;:uoVGn*OU$0YMFTea&ICUd!*aYS4^)&Rn0lDq6U'2&r$^*^?EX!H5?/gQK3rdd=E6 +dQQp%%lDQe_P_5J'MPUX`-Qa3qk86W/=rRYA,j$I)46"?eenXdlZ%5K\YtM#*O2U9'5mlh7NRhn\(In] +Y]:Lc\),o*7BE@8])B3/@,Zg`4>7``Xo\aWHde#9N2m19D&/WjVdK7"OKX7]SWRcIL\##RD1.LY,U.$E +);13!JP@'-gX=/6g@"g=,M-Mq?5.d^EI<]$G<)<PC_,VE6/<2["jX%<!]@,m:Vh/12QE3/fK,R?l1F=K +3)V>L?P^:E^^GTt"UMAW'dSg5X@P8m'd`3PgYpl<6/-[D7d]s9lX8pJ+lH1hj*m5VSK)$tfh9Z^6=Or@ +X/&HWA,6c(aKg!W4[j+qQFL$F[r^Wo(L<bXMFZ(@qFbJaoAZSL6[\U+D\8_i=iRlo[Le1n9sHd/,e(9_ +"/51/O&N2NBLd`';Sb6^PG4,O$]^tF'GOoj8Z0o*V3%O?lg.N8qibs,/P?Q?F16RBrd4LD92X4(m4.Mf +[r/=VB6QF@D,1^cl,<cm;8e'eGPsluB>HTE>3u51"`aCGf^Q/B<=PCh4qH]koCQ`cO+SPYX$]6\?IpT# +YU_o+OaE[(%>0o'&b=$J<,@iEIgnA(5/#"/;khEf^2ZcpctoG+(![pBmW"P/:hJH"O:)\fVcKH5/,k`< +O8Jd\A;%e^q;Ybh8#RLJE'Gsg;qC%Ok:$^_NPNR\Y`9O\cDgrUa"a9]guAf<8e4RU;pdQ4l>mQJ]W(NS +g.Q:\*B1O<b(+,DO#+p1kWRW"UamrkYGZnJSeC@7?fqb:_&T8.!oLP(Q&1SY,.6]"MFVAt1?`!`[p+tk +],j24b'3g2RCGgk*oi0>cVQ?C=/Y+?:i8jKebM04j<!J;*,@n@gcA%E%TKsYq8aN\T<#4gSS:%7;*tYB +qA.)r$*[5((eI`DjBrn6.u*F#p%>iT?Mn%G7nBaY@t]3!Y6YhM9m13V'$%,l\j5\'hD\+A\B"D%-.gU: +.^D#;O;q&q)B"9`h2OdQ8_i3b40AqK*p7IjplI_[lZ2F'2-eZ/StHSL@eo^s6]]LZX*+YIa<[#rlH7A( +Rp/]i@733?2"/MqT$CYrmAoaA+;E6Rn0jbq]s8C1lP-_+!f%HGg<SVY*b7CY6alP<WGu2h0E<-6hgsjD +<"S4]=`:qO-jV]3?MQ-3Vc!ueds&Y$8d+/O.#=MG/&)EPc0;E``3*rZ_-l7J=ilc7WV"oG?k`td[>HJl +Z7jJPT?iW$B3qmRGA<.6!>WS-/m,</964?m9W!1hPo^,@QqsR%$K'0Afl'_D>[$J<&B5(>>L_-\Jst`: +&6khg/d8O22_>nHED%fBlis`!<=kVZ;Ik=Fg0+=.V)^.Sr#^Ys-POpgf$-j/>ai=qG4bb(P;,t3964?m +be^5<0!PL?mtAp3TfFG^RU[(/F'PRh2-/*9cTo`Z)2ag@]1hIU7B*c0^,3m,MXO#_dH-X/N_@c*r'$@Y +1rl%Se/Z6#)7PTW9f"WH<cDc5m0>;hZ)eR*F'P`h'3oT`NYPE'G@!U.Bo9Qk3)//(3B!qUQfe'F/Ri9# +7Ds1#TFBLoX7pgNYd/;1(kg6RjUq$_X@%8$FH@!2RisUJLS(Sb"_KN5*(paH_:0>CK/V4La94`sb`[d' +"-^QqRIL^NW2HbWo//O[%T$fVK!Y@9rAM>d_:dT8NF)k*[HEA5l8q@>g)Z`"cZ';TCX3ZL`X)G.MegZ! +$I:$pV,t@srA,RM%*BlAKJc.d4X1#:FF#q4OWaD^rf:[5q!Y#Pq"O>i=JT85##0.-#.@FtJfb^is0&#j +K5Z.so>881-,\F4kJnWeC"j!'W9fg(#5J"6A7[TeURE/IDpG=hn)n>05<nc:q<8LV?I(i6N^^\9q#9u/ +E!IV&fu'TY`V*F)U/UM5"rG#NA$i6A11<pB`TV5s1`f,>f[-tQX:lpi:!Z=IpVOZ-)1M9OdlH)>4l&lf +*/%"t,1Mfh,7M5n8KcIan[bh<hR"P/As0q-=hcK4k-7gt%Fo6l.?H-KaUn=/m=.$mW--F.MhPbIqaAja +o8uE[>T7:FVX;71`3m6Z]a6iM/$;#Dlu`$uTG&`_NT$6Z2h2F@nV(=0?+>57f0X8YO&WP>chcVXWjApr +QGUp`da?8$"LA4iG)&6dkCb!TH<mq-U$8i2$mE0Va\[651D1W!12;`B@Z2t%RI&GGB-1rHY)Q)!OH4fm +"!dRpB4_^G]4QfV?3eL:&L<s!ZCZE7R48o8-N6$8BFQpBTX.R6I@2_5No0(uSY#)?2L5?V,<u:#Sccfl +?;/`1&`ng&b8t*cWdU?89Z5@5Hft+kGbudZYP)8jTD*N`Y;SJeVC/f/S"Z-=V[%G(++H3g:1I`B4k%YR +5ZNcg1D%m*XAmiLLW5YVH=H"IHZi.+&)ZT,f[kRe4`[TWE]7Wdl,pG`<hJRE0kV).kV,qfUA$c.`iLeZ +mk$S-o9mjNR(tr'B4g3":E7^8(V=<74'tC1\+<&/f,+A\:OIZ>1B1LXGJh,ur2edg])!@`POZN9K\88k ++3H4F!]>GGp8[L_eSLkn$JJ&FD7dkF@QSWiRPlt1?gA9VZgPdD[De?25<II$g0WC9g:$<EI0Y#ZmWL<4 +gJ.)lMmgZ,iQ:TP5Jl+.o],BMh]Jl'N6$Wbo\lu+J$us*[,L/s)n'O#GH'/B!"6oT>9Mt#C=hVD;2poJ +DDC4#o2W$M(tRI:ZsgL+cgD*UXT@*t1M/#=ETX,U=Y?B"7W.@VbH3BJb!+O`>kg7/f7]RZRQ&LWm=O)\ +p"Ra#U:/ds=e&;1.?BR#=/CA(i\[04VUdGh(Giu>BG1b[o>bMBY1TR?`Z3eL4\.G?[$'f<I9:E3_4K_o +M%o]4a*4BI/;n\;SZc<)'OPKSg)_Nj6C2T8`9Jp,PEZs9"72f+<LAtcI//2W0`]if?L>cO6%fX44F`&Z +"$&*6r#5&<GL6%Rc[TEI]F*4_GhK*u#k$oS#>k(,^3\3T_cRf4`sq4$j[si"j'Fil3iT[c0%V^qliqk: +i9BPB\F.0hc<=q\qp(?3W:+!+c"V*OkI.T4m6,F,ro)Q&l@69CpPCR"q=C5Go`+_(%i_4.r0!1)_8H3u +,Vp3s+IiPG`oS"3(Z%otB@;7^f:THf+hsY%YGG]3R&/?\P4P,#&D_(a_P#^;XR'Wrgu!QM\($@OAn:o= +1%]E;-;?Y!2)K,$UuE:*_olZl[%5@%dBM:b$hQ"JY%N`'A$^@4C$7X9TkaHi._bHmit"@%oWrmjH]@W> +m_o!cL$Vqf92[?85+`>Yj]&M.)=8i,9b%@<D(,4`mV4=oYFUDhkKeX6/)($`mon<8B+U\`fY:D#9G_Wr ++F3bG!]luKQ8S5I[N4mO@6*_)I^P^>qi+e/3aM(rHJ:u9T$(cOO,C2^?DV*i[2G0E^T>DO-;YM.'_l+q +\pnF(5*+c<3A73`2eM9se/T@@g2-dn[Z1dX+s%3>3reAJ);@7!CjA4K`#nfrfuZ@sZ\o\AT$]5DHK*Sq +HMI(r.9$7J7+QidU37?)[`UO5QS/1\gbU[Ws2=I*^FN'k#u0.h7Nf?3,Q;]Qg5a=?E'IpnXNfa'5<bZG +n)n>05<mt?k'Gmd)LA,HM2BREL#)0tD;X_'53H"\Hfn`1mLOt;(L>d%YSqQE^BqO!"D!BP'<(Ee!gE$g +Q#.bc`cQs]OJs62nd?%=lZp=QX#T+B,Z&&q$7%OHaQ./N9^dV%BM?a87Kc"iVGldf8pf$'P>#A!U,I[i +SK-B)_fRK,[Er#1+f8_`YZh7Dklf/>ma"KZ2h2F@nV,j[#nLMpXPPDc<lB_RKfaZt8jkT-/pU8?=&!cZ +Li]U&JU4ktg1j-X[fSUrK)*eJJjo:Q1l'P.+$7b],,<K8Zc'l1,:RBO%)6:cLd'(O@2Kp=l$auh)4Y!* +S3e$g-VT(DgufV(.!Y)8[7K$hDu]B)Ip@&1Qt!8h"rhgj@'EE03dDZIl\Yj9_bi&_%f/!O?+V2e30pL# +Z!t:7VP-3KXQ'fN++JSuDA[r4*#4F'E=SK&Z$ibka/7L[*pgZS8%f6Md9F#]=uK?Z8/RAsqHV;'/ZrG8 +F%Oc+*^cIk'].)FL?-4TRmRef#bRNEk<ErKs8Q=(2b*%Zd=$,?006h]i6Qo4qhs4<qZb@Bmu@:gY:fPQ +J)ft'fB2dIO$B,u`e@R*D]lgp1H`u9@Y-VkWDO%t2\ALIERuh;idt.ofZ,-(\1$\#XUr(Jb7+`jX^$4< +E5o#P57MF\e]un#-Nnn$l89ik!LpBX!ZUld[F''_(<c1DUNYo"Ygp/:Dm+f2r8UD1766j@4g9s/fiVqH +VCsWnDUuU@Jacb7?*:ic2C-L_'1O))Wtt;Qq&Smkod9[1=hd+sYL!(4B]7Vb1rT7Z&98"Z<7BHGr]m"! +g84^fcS>,643uiqC#@Y>h1U3S2n"V@6\[qC7"4PT(+_Xm+c+2cSQ[rjni*8:W;)D1krE>EXR2e+YEumj +h9g%Pn)3OnmDg.0i[3GF/o\i7OGS1fqu^OV\Tn)eDfT1"I\n&YHsbLiZ(2d,faS[WX5\Qq2]#`tI"T'! +*]eMT:8ZljT=D\j%J5&+IdJ1/jPn,LFk&0Y1YgptpDG?M\No/@:!Es^ro%"?3W&7hgi"2)j7AnQ_X$SP +*Y>659h+[VIpHT$mI1C4USgbuH"6@YH])t93U<9tefUA0.:EbK"`VB1@Q7<]j!bB[-Nc5_Vk#2)n_+.- +nC`ebZOViVW-+f^3KAh;\rcBf(JYYoRrbp26f?1KC6pok*Lj^/r$'9sl,'hUMBYCEm)N+qYh!)L2<6kd +duL`M#<362W8Ues'KmBeRWt..C009M"CQ/Zh.YW+*N1FGI',FX)O>uG@2ni63$ZuQ/B#8g;bO]HU^BI0 +h]5U;33V>q#$4-A8j5.$*W4<=-e&rto/TJ1F^D(?I=])Q[^K/?MbUUQ%In*K`sR96m*jgfg!YeR51m>t +>pMc@;'86Y+M?:Cs/J'WDp,3]Sh07`1@(81D9g_@?9Ed"nPA(;XQMgQT)U`\Ba`kr%'_1(0XnI<h:Rm1 +qOcY7<2U,]cWaVTjOoe*":4mV)t"8%DjY+to>^@Z5kYA*<k,@AY%8>=^D:,Jff`]pP[inP@Y`Kfn)*jT ++]>ft:9Y"!J_c4Na76LrHZkIJ@Dgb#:Voqua9uYu%q2sMp[5G#!BhMEmds+^carLWe2hg?hlVoT%-NB$ +7kmZ>k1GJEr$&pTI'eM]bW7Di:hsu%^R`brQ^b>7ZhW)494'8SSn(Xa"[_+J2l];BQQ%i@%d"tlrE2r' +=^+;1<RG."GB$Cf9YWN9)Rs=-\g35A`pZTo/UCp8fX)SMJiVQAIZAg1lml_7fD<f4ZKX'ug#M@u$gCD6 +UPjm82Ipt>6:#Nt\6nPr)`^a0EB[@1_,RSdUNh'B[\JsMmik/G[o;UeW1sPXi&``YL.3J"lOX5^^?.Sn +s7hQIUi*UFquS#1Zr>s%JXJ5k5Oj=GD*7iLNBZrnVmY<`H@<Gq,L.bt]C<`>"Z++YlOabX*Yh1\#lTU' +!2"GRg=Gj3:0#qq\RGF-FCYK\.f:GP)Ze[?Xd/=RjQ"!m`75-@qEH\QT31a7o:NP1Z0"1j^*f=$-GJu. +d)6&O,6E7=MW[4/T"i#'N:lk_NY(6%#PVXis,$QaI;rWkQ[R9Km'NBZO!Euf)()W7oW:u_R*C()m^\!/ +p9Sb#f%7_rNU0B`Xk)OEbJ!<BGT083rG9&XRW^6j2qIb_H"jYlLS-RJ1pBcec\#YuBcbI<oD@I,:ROI] +YAc69(qhpgV@^I'?$sS7b<AllMaYCN^41$Xqi:.^Dl;52<l,`*]k.!CYeTR@`stXf1o"Q012V0WGP:5$ +Z+H@dc/n@9qJK,l^Ub=Ar1r/[m6bm\^scd88+"5$Ji=9^i>N`.!r,b4o;G)E0ggKE)nsFco".0mr[Onc +(6O2%qDuT^HWkZ[U@&^CeiI#.Hcd9T8;G(2SO,Ic?#aCffig?CgsFFs3ApZACEf5e;iFkZ\%RL^=gs*G +>5-5Vn$'CKUQ"ZQ0pX13RpMT5)0qn:dDbWl:3V3C.H;5)I7R`B`3+IiY*d,@4b7ZCMCRoo^Vr&ggtZL: +oRHX5VR\jpS*4[AmOr=kDV:AF,@:[n!rg6\XHK_E))6`,LVZ-f52s34r#Q-f&9oF37bJ7Ji.Z@i2C?(G +?aDp=FB1[YQ)>p)C),Am'o6\_Y'_J/\..f1I(\]U^[YS?_hdb^@,(,!,4@h)QWgP9s*PoDEREadonGHs +%5TEjBU<(<'PMK6!TNED$e/B9dB3cVASNj%LJtRc"faLQ3IH#s7"*Uh>0=JUV%tXaOfH)[Vh`&P#AXgU +^Rt9l";P)JcBuA,qpNVDe9JKF7hs@eX=-)m:gc"k-ukf<0?]0OrS=l0.I2rb>1Z"0<t.#,$+R[!RbP&@ +F_HK!5356Ao3lE1Ae.s^br:Y_bNF@`Y%%FuWE!2s3`_t8.)KI/H_6I%Z(ValXOH=c?Rl2!?FALF1T8On +?hc/_%C<i@7CtP"?k?$rHc?R@]"p$Gld=UB4a;eU&4b0.4/=4P0Uc\VN_+/W$eBb^TuU7PX+EB"r2^dB +V/c#Bp?]`>`EI2oU[mMl\(fkb4o$bf[JQO0r2EijU^]nn:i@mi&XhCG`Z2HL2#@n3WeoWlH5LJIi0iE7 +9mQ&`[eA$m:2oObXJ`L@AS!"+LOR^&.&Pijqc/H($XWQo%'LZg\%9\0]m]<%Hl'+$`n/?$8sPJ.C!fIa +%LoMhQsi*G=h?AKOdRkR4.H^Im52aVDtcGc+VS!f?h;<V)Ud':j3H,6EQXa-Dd*"'h%qE\!uq/qiD02W +KAs`?=V!t_>[N2q9[n5?f6.C_4C/CQ'qibRgL\CQWF:e%X"h0L['t6uG+J@()TbGGEOCu`n=X+Ac,>*A +m2C<M(L@>F(,ijLG/#Ze7@pr")#M<*P&&-#a_Ot:C<[43]uE&+CKE6tEm0P+Zo_dcjO!;HbX-,`T69rP +Eg;1`>"C4K*!,k@8;h/6f%^%!MmuC3hH3/3NG>L>\X%gWMk66/P-J<g9,+akeFN8R0;"Hj*)tI@^BYtk +613[0O>JK^3+%uM)#>Uqo*AWeTmY2.%&K#"WRKdpcp"#h(5VPZ<OS;I+ps24??inEe(7':=.1Z<.e<_J +710,5fNo\I(;3QsHE&niL\'?)]tU2+'OCCt9jafC#n\l%j\>81m)0XtidI.DNY2K$lMGqbBGE'!o7i:L +msbESN9u<HSfQ=Z<(GHOH(Y<;*GRM!5-1R,Ci)[(?^)uW;AO%V6H54j^iV9UR"A7Z\[AuAKbMpYpOe?p +-$C<oRng]PPR7F:Ja3_<*[SPiM<i!Q`EFZb.'8[GH6KAa6B*#:=NU=&/<od:F`*-\=6J/VC%okt6Q4qn +<Qto_C#9(&25#%7L@,A,5[eqPlncX;K,.C\9kAnCj2H^DkOk.MT)1FsQg!H(kJj_i,G#1$<+#\54cH(h +FcHA7hs//5(:R)d.PEu-B+H]-NDgdBN/lT'X1lL)Msm)JFPc#'(FZPfD',Pe"nRCG"2aVNG?h$S35(0R +90=NMVFE#>H0l%-WfMJ<:6"9'+emNi/erVOfj$)hGC;SGKmEqH0KE'#d<cr3Sq*a?7sZR&gbts`ZLofI +n^_Cbl(O4)JFlZ#::R6++?"uH:_k<Zeh62I9R8+9gO>rR1,7304W#YKd_gcDH3bK@cOHh%iAg!naQ@Cl +l(LfDa`j"!.EA6>ZJObn=lT"C<X\MTA$i*'is8PGO';())/*C*6\,;ndY!P#$L+8Ncm<r:?fU<r<V>[Y +,<Z<*>,W<O`e@J'l+uraoT1+DUrSQ<C6=P2W.Qc?Oq2<>A-mUk`@6Srh*QFd*B-'C*idt48:%4%B:_[* +#k2kXG%!rQF[umN]R&sAa?Y'M*I:UT&%)R"e%JI-j97p8df3J=;EhKWP(r?mQL&9kdR-`*2aVgU":@^2 +6BWCC+[+>N]/&+oO[SGQJ@.qO@f0Xdf+!\HDp<'P=icbTCAXiJ2T.\>G12Q$"(qn9LY)I?*W\u;8.W+$ +ij$tIG($FMGOrJCLPgF18e4D]ZV/oMRgAB/[9beRhV/am6S79t+[+=!IAEDpaR^_BU%8,Io^HT[ed2"- +lHP!U:U_;7N&*)*_)[7c()AA-X2#]c>1FWH/>sIE4Kra>%AtGr:8592/h!qORF.MNp?K82EpiL")+BuG +64_RPl-8)`6]\3hUu&2]"A+T!,l?F(4du>8mq)"GJ(j#]o<A2WO4t?;`m.V#lT,.&Kqa>c'`@>kD]5`= +^5I,?eAG"@AU4kWn5sEYd%BMtm.7F[H&p_0AI_JD[R<pXr5A+/56$JcX]1PS<[ti)>Gf2'1n??.0-%H! +*h<Nu!A"5)4`]0G7W6YL/qiV*=Eb--95maAlbb02/5b1a%.W#2?oB=lEdP7Y>k?Yn?)L1b+g8.a)rIoh +k!K!PN-W92l%-'O*pf"]1X7_P(WkZ"@,'@mpdgJ3=>6<TRoje`eJA&5PP>p?L"B<<&X!q%XW(]"Gf,5< +e[r2$*OQ!>m9U#4dA;akcH&T&<Bib;%=&'=:iF0e1X#@J`-Z0;8XC&Ks/=1)Kg<OE%@:b\3%q>ankR*% +PU%3`(I?^"`ZK\s16KV(bIEJ3qU.cM=r%!+a9-0ceK!3bTn<:28?BMEm5"f=;1=3l+QE*@)iu_V+&0[> +r,1GM0/[(p+gc4I8/4=XJ1%WXFNA8#1O,Z)4+8j0LcPQ%Q\@T5?m[d&Y9(S3lW._#dW>M:m$i'"+#Fjs +3UfA*P9f"qiE)u&_7>VO[Bt7Y#aVL>\l\.mE0g5:p(OC$`d;+%(NKPNiS\nlp57E49L!dq(I-))[&^L0 +#cq;DM6VP?=pr:?+'@).(M:TPb4@'6/Vc1eF/r.c`9;m8#sE$.fN.p,G0$*rY]aeF+.0P%-Z'e[?AS>3 +Yq?f8\/DcoLiu`XA(Q^qRR6fAIn73D`hK)ss2;:9G`RWP$)<Dg_RVP>)cIqB2Hq6&YK-$jmpDiF#'"p* +mNHXW(1"XD#1fbg.rO&`Oc;%]J4);'$q6#3G!VA6%Y@(qXH=>G2#'!n1G#VdhH1EDW9TR:8?98<K1%V4 +bkA/&eW@jA$TSQYX.akfXl`n>GqFZkm?5O34DLr_NQBTdn4j9&fk^L>U>rOUqWg=jWSK`">tRq,]X:D9 +pKq8A-_`8O'+l#CU$"Z1iC"6KjCi%WU&0N+P4YISCiZn[nC!LqF]R1"\R/L)"X6^o=`-CIN;H+p'1RN8 +]32QS"19t/nJ5\M.j8OF]^RJu'g#k"h9_V]=/f,0Mg2\8]lEVJ2l];Bod2!?pb&M@?O_m=Mf/Cf:<XKo +3hKRL[Zt^,k$`QT9>9Qa/@$G'Gs7/SgB[Yig9!H*mCp'"9erN8=OZ).Nk@B!=?aQjO^)#2#6i)'EE_s. +T(Dktgc4e)H/l[UOW.bVK3)N#<-pU&'QaUd.B,^0.Odn?X(DKQ*!0nU9q"1mi)i>bT20jcopjr%Zd%@A +JR_t)gV/0tQ0EoJm$I8YA;6CC'*2ckpI_X</ZVjK_j2@`_d"JNP:LkNPpAkFD%>6A3hiJt_/$(7hT498 +fhu6JgWhF9ab:BuIo^uiD8\_;^&Nrf0mNB=6IOq_PpPlFTR,KI/U,Ii4>9(Zge,tui67jRqcV4;V-BpN +i(0B+'@3hk74;LtU9:YKO0AHqHg(8(IUMpknjZUVQ#P+66OFPDs01KPonA%53nRL4)S.FSrX,!_LVI"[ +oW@UJ/7G19^0EUH[Go1Ir71Y*NqIeX+\eEQD0^5/nQ0>][4_H9Q;lqK<p0OB^H)YueN.ooiMTiY!=/Qi +(\,N)Y?p64+16fD"Stu(ksKY%=[@9Sl\`sa)!FK!$^F4H\e2$(qU&SVY6>C!Y+#:tpJQ,]eDW83Mo#P1 +YhQ`u2d'a;^m6Ub;%I!_2'_=M7kFW&%Qj9@TK_[D=6p,_8G^_>V.DC[kcXY0gQ59APp*5-eE3,!n4/]p +.majpnFk4iXpsDLkXU?&*u0NZeD<=='q5u<3j6!(ZKj@%_-%8&QFa1KG/]<\g*R-LoV9$VkA6l$5Pe7& +&F)bmoB-VdD9Z9L\f8",d#[TAF3THs/[p2Y-r(6n2"$,\g?#W;!6+7f[97gbJKRef[]Vk6;!CJ/G#.Bn +GLB2IH[E4dK'll!878$CmVc*SA*jbPrYP:!#ai6MUb>p!cHku8Z1GRD@FNNjr`[pTUK)E[aXp9ACUr&L +le#-[ZLjfdV)C:K\=&2C&JD8l$r2UsC/.NLeSn:C=#DA7G^Z3,4(O&`^)`,<ob:Z%kTHHm<!#Q<$A)K0 +Nu-s>!d>l<ra:JEC,J!$^#%<I4!\hBFS=XRXc;T)O6PmG[5n.0d&M8;\#"IT/&[tI(0r=G5"dCl%s4$h +CCknqEe8`T;M85,<MK2Y27-^@D!MRVet>CO+/BP2%oEo/a,@Z$nWkW;\97&nK-rc?%J.<cS0p*LFjkE- +1^iA5RooDebXn,"(*Xs=Jms%f?UM@0=mssr)q%gbQOqqCG6f%:+l/9-H.&Q-mdEJHhRZ&e91Ecl"i^;? +SV!6L;nTOB]O6Y`S%5K25k]$HK30^P$E^,fYUV2G74$u4`g8(Z%U&FhbsGf>I$<F"9u*+;5A&?5guT`n +';^ZI/adW,)7o8?Xfo($g*&UX63nu[hY8^?hDF8^DI2WpLYftPO3sF1JID6Y7(^Cin?uqo0=>J:[6>$C +d(?K[brCOl?.S7jHQKphLfk%&?-QK)r-?P*bkMeHV<g"P97jR:Q[>f+UNfo<3H&Z"CNuM\5_imQ\O,!X +%^qoP2q^G6AMS?inu6>i]i=_akap@O5hc9Z@"r;W[1c_h^'RS2q:$6fi*":k4"pADq:3Q?fNr#'..np7 +C@kg-eEBt&V'0a..<s>97<-Hlp@ba!nR'-C@hDZ2MHcXg<lrt>W46tGlXNSWT'4"VeSrNpG&WiFm\/Xi +)/RURC_9`=%VlKSSP7=o[11hu^0/??!8jp,,l=cGS^6/eqDt7&eJl0#SlVDAU]Z'G<9iHcSUreKS`43g +2/V!i)5_n<KrMB=";i9i?;MuMNi6f5Z=?1^M_]DrfIrN_Z3tO2jqA/Gl8>%Uq1s8+OO1l=mH</ki:6,Q +YD)$^&m1Z+fl=Xr_XmjASf["C:^&-q>"('sV&em>$Hq@N=njgDBaB8*oLno3n8klK]8Wuc!\K/HY>)2` +r_c)R!=BhFl&ns$3;OHb$/WG"dImJrGs&<\9tFs*hsl6**`VK=dD$TChc:])$f4,Cl^n+'Z[i"LeAD2^ +>9<`iCX:8WJ!]%pno&pC'2tB<\:F,c`WhhnW(h1Vlq=SGPoBLjj?4R9$uPR3ir!Y[/\@^icckk;EcKNm +/uo3b92iE>*ph[/XZ'U<Fc%]e$:GpX;7\BiiaN)B--\PQ@,9NYXW;Okg7$U@[Gmcj>EWU7CU7p(C^!"Y +E[Omq$`_nfCq.gQ$7(KDf]'=U,M'0gU>B!.PaF7+FrHaAf#E![cj0<,*Y"B^-kh'UR%\ZgU`nQ-fk3+J +0!0HDd(8:^B/?niH&_3D@YP5j5BXX:RKKU?`9cBd4gP(;TfiPW6e3UWYD255pRl"r7K8hC35)cBIc(%S +[-H>Z.Z*$Z=(SeD%m'Zif1i!I^ZZ1,Kk&*dCS+]ZYZA0\<a]dM5I;/-@hiDUf'ouS'hGAccHt8uMc%j$ +bYpTt'ue3Ej_G%N.:'Ba^cE\M`;"Y^2d_.'go@nCT_6p-Z1+1/GlAAKql;.(rDe5Bq?16`=2jd'3:<tR +>I(@sQsa@1&IC(>A*Ofhq%#$il\01$g5;g?bn7@4i,.3YM[6B>d'4aI?e`pK;7!0D8FIHVBX_=\7LUA5 +Mu>F":+W,;$b:%]kF&PbE/dA';c\_jPNX.@]*b20O#Ym$36$?#e\MVlch\[n+!Dmk%)$Fal<.>pOuEmU +%r*rh(&C@PKLBj`d(?a0#3G)RVp-7WqVGeE!ktsafthoM`;[!&6%.r$M5,,Kkg(m0V`8%YG+Y38=B!)d +]DC!8i6_GGe;+k;C8ZMsn96Y\=P[2/8XR1aZeEp\j/:aER0+MAQa"\Rq9tMhP"t_O&LYM$6q"_(@+W$E +RlPRqL*W8bbj&3BZDL.UmBTd%p?$D_97:&K=[OuZLGKh`m.W)FLm,j<3,s[<n+rV?^+U?uH#e)#;'W`G +#CZt,9>g4]VhDurXkId#oR?T@GRlFq!UJY5+>T0*>XLlMm+<n\1?a8mV!R^f6`_`]kbR(lmIrIn>1c%6 +:+NDoER9(!"39iFkC6q)>np?DHIi0J,O/Q)Q#$Z<X(AE-(?D/2dWK<UNUU)eS/aO?g8l&n"mB5$V5dhB +HG-Ldo7gdge@PpJ>USla=1u^9am[6>*,ud-F)lrKT?XqZ0k)gafc/J-n1[U'LH'oX-0ec-60_`_j5k?& +0I@5$Xqs"P"]B82+(Wco63@ZHQLOQ^8Fe4SlA3&NkZp^+$08L&OmI#WhBos@1!fWqS.f^9+Ac;[H<7gP +]dpi:H<:(qGq?C[X+]l"28n@M2N(M)2<]"nRq-q(:ttPTd7mtEI,J59Ci5%n*1"Bk`B2:s)o<,5f$)\S +_[FNVqRoZEQH*i3:`6?DY^3\71/u+8hb_$Lo%T[CV=i&P=VQBBKDAAHE#DFDe.0aP#uiO<r&2GFgCb,A +SJ3Zc0'!dQJOP.C/kbP`j6Yt#^T]]S);YUA3mSt!-0'5Y<.7m&S0>Won+!YoBjb;o.\9<0Q3"S^grZ3E +:S#@8AMmW([Y@;d+aNBL5't;q7s(#PU?+/oaq;V:!paE2\bmA?1!kP8-OmQSS2=3_F#":i-SIUPC^\Q\ +6bH??ccN%d2XWS>D3.!ZFu1kuaT`EBW%G<)[.,hnk45$!/0!F1[3Id]03%T1\3).rF9:R`D@rpJ=E@&@ +pr)j`(7p`Hf'o4%IU&J.L0Jmt)@_]IOeHsS'H6Y)]saUISs.EZlcX@tE!su`6R=iB"6gRffF?fog_tNH +B3Q/@;kr0cF4*Q44=@6aq=:$a]$PNh_X9E5$pVM8C7LOC;7Se:mFs-R-eg,;:JP-iMX'iSB6kM@D*!j> +8n"3_)-OjuZE6*Y(FV!kccNupS@#2n:YH+25<L<A79uLK:9!`Q1t4l&p//T43pZL-E[le+Us6l#Gto:G +iAmm*.Z3*Sf[$*o'KsR5/Hs^!2N*Ce%p4,hijfYg4A3k3Bk_`kr%#8)CAUD'Ys>0XT!1*pf7o;NH4YuW +F>T+qaiDP!g4^)3Ta+^Jo#(+RFS%[GDDAAJ$HGaZni_H\3!E@Lc>Td_@4h;Npb&papLL1RU*Ai$YR&h= +C"\RV94PQ^.o)#]SPO*g[bp_%4)<t'1!IA,5%k)^<q,o@^)6AdHfC"s?]#3LhE$B/CM"afD!&2=`g5ot +2f8HU_\'mHT2i>?`C\ahj78-"&Gnj$X@p.8[uL\?V[f2ITm>fWDM11B?k;Q4?cgD$cLC+_[uUIuq8/k& +bG:,QAS)pe`P/1M[IW@&ia&%+AflSL[@,=6?RL`M46C76+MGGNg$>:T\jTN9%!pC:@j'tlI8b-cm<Rs@ +%:(_GOu]&=!@\n\2EXU"i'?'@So%p#;EY:@jnaQ/ag@.%H8ZS1Zp0RtfQ$_RaSj^-NC@cVTKg^E[BN+U +MQfrIqfb941TWqUb'h43J1dXd;DK6Fll^a9E5e/e%EWHSEgO6F_sl,Za6,CkSrjcW3P9L/2tY[0E.*&u +"C9eea2:S`bpC`Do)9!Bo!Tnd,]B6h$OJtbXJttAm4be$mdQ`$/bSO59G]#j\9=Ak9:Z*paHN9+h/bLf +%Co\;UbC-`KU$QN(Y`qU@Z.35%Es(d4n7Ab0]SQ0Uo`Og'3!Bpktq>cl\W(d"">$1=Q*Ki9lM0jp:]71 +pU4lJ9Pn3#s+,;nGVK'l)kZ<2X8S%<p[[Wd\Zf9R#Bk5r=-Tn^6lI)78`qE_Zor*h.7MCUM0A`M%JZQV +nM'sNHQpY:ctWc^(:,CRnnoFNc(:RI>>0Z*TIHa=e*m^HAl&$0GOK7f7a(T>_^?e8+kaG0)M9Wp^j/ns +,IEojiY5Qj6g`<:#,YGMT;KW=qj0fd2>q_OXerQO[$ojgfOar:ldaM:_lXm#U"(ugoh2@=(!4Y,RYG>r +h%-5\1N5\GPBLXYm(8-Yg"D)o>"toDE0<]hF_N_8rJ(W_T"!'])VUNYdqKY&:!F5_2;e!1COU&SF02>" +ct`D1KiZZ!^9j?cWmGK!Wkh\[%kc/anBoTbDeE`@%Fn+Pl')LVVU977<\n>E[@6RX@uZG*bPLNa2fZ0Y +[+:kQjW=.+hT?hpDmkgMQ]AthR-*GB!]i:1@pU,Rd?\Q-=6YlR+(CV/pq;#+XX5SHn3O2f$*;rTZ(=-u +lpcC%(FJ<\R!l8_SX]&R+"kB6IGM_dT>K'tHCR?kES:Pn93T#D'd"V]P4$9_J3;ib]7._T9T0!(/uT;+ +O5J:`A<)=m57bTFR3M`h@<t<?L0g=nGiG@2Mce;T@Qjb[k"+_(ehCdF>&^*Ec;7e,&Ni:'i;7f\8FZ$' +g`FpTQA(`\OV8lq-/e[j*"#@J(KeseGeV%g/9#T1L%B[mniu.2pQ6\o4$CVpXD_NZd^.U!AhlT:nd&2; +;qqf5#oGu[=3ET(CmR?'j52l>Nm*&_0NPm-cYo]sWUg<\M[uW:)[gH(E&Lcq(rm,qa>[Xe;kfZs"]mZF +,L8:d:7g@6Ki*3mX-P<?J#PjM(Jel9N*HSNc)I8,ZYfB2_^s_773s5<'*TK=m0.p_<DU.A&k86k1)a'R ++ao!WjQTtJGL2)@]E]*%[dD4bJ+9CQh?+q^J3\%u/?d<;%#)725a&J&<u5D<:(LXAkP-eNg<hAqH4pgu +kOCJi7LiqG\W\N-D/Nq2>Vig.^jTTUg_l]MO,3G2GHEml&%EBghG*2h@oc?+QBQn2Wq5O>^QBaLHAIR. +O`r>F6s_:f>;6$W0?=Umr!/g]4-2/!P;0n%]UPZi2d2/t.p%+qTQ\[N[<N_p92Ia=F\(m"54+68Xlfd> +,7h&eC1-sfX.O@iX3fH8jt--u%aN>ppof=U<[7+u5E[f$_P3Zos2:Ije6h6equ[3hJi>7\!*frYL_TMn +.9f1^^TjBF^=\P+0YZ2t>oIs,+4g%U\1,=(_/0SSYJ2-XIa-NkVJAbN5D.%FYRWAP\FZ[n<5C7T"0Pls +Z+bmtN-H\h@RG8!^=//g@E@u*WHm(JZ.Ro8j)aHqTN\hLo;5aY(d]hj0S9;)1d@bYE&f?#$Ttj3_S5>S +WU(Door4GkD&t1#7AA^7h`j'=I7HP'$Ee]Dhg'a+.FX!eZNnnHPIoP."a>iWPDL(c5g]\m*.c8k>2@%L +rLtKbF]Kg0i,28Ac5&KZj?8=QXqP=GQ$Rqha][GL($X#r,,(Yh0RL\rfi*>YkeLO?Q-^^Pn>7jZ,YW/) +0"_#j*:%DM"<7-OQ3\hNEC"hXT'Cdd2fKN`A+u*1J>;QL4$CTe3Qb"YO68"Vqp[NC#>:E_P9Z(U"rBVd +UpA=f"!LMNSh9j-:UtYqK4?"Of06HPXT\&O[8sg4qFQ?5]Rk22CWuX.>,L!*4[s%oL#4m0f?aic[;HTE +?SZ@iXb3Ht$Db6`EB0a$9$_j3OX%]MUE6cE3>.,Q1`?Nh6('^eZP=0Ep<+!X$tYVV/UIFb!"a2ug7CsH +17co!k5p=XrWcZ_rlm(s2=/T3!oS8<5)66L#s7nP93\)!q-&"eoFp,PSm#"KSV:&)Y>2i.<f>&Xm<TrJ +NVo!lU8JZUTL]=WHcY1(8XMY4UF8*aLkYJle-$#"k*,FL8n37:5q<0(bn)(WD'Bd/gr!b!#jaI]7\/aK +%l_#)k.Tqc@+t(dn#hY@MH@_8>UC+>!<p/jiR#A!#?:'fmMO+EJ6s>,,[cOt.Z<Zt6Jm1jDX,t!g7SO[ +<j&/UA1HUD2.N>oHHg@rHVYfkA<6GEFK%BVOIT5se:q1JSE'*pe2b5ZA/Lis7'TAmiuHqqS35):IQ,Pl +qph^qfQ/lcSIK>;:(#1^:tqs\,&t>"OJnW2G_M0IkIB\UkW6`dZ+\"6a7Ue)EICpO\:,/l;N&Wk^?GHg +37%+%mp'>ai8=oAOhETs0?YHaMbZ2u1Nmi5dt8QZ9E*A/3)TA)6cGdBkAgC*cFLW,MJnLNWb:^8,l#A> +N\m3f*8fh_E/nj<Ep4P[MAZK>ZY9Y'AEPqe)s921Q01,2,RWE#7J-A:_n*lpaU+lg69OT#3Wg$,Q6YtS +%2#0>g>U&L*k=F/*^fi$V$]@oe8ih1\R^LYq*NTt"t:Sp&3LR'>ZqC&>S>UJD""7t)iO0pE'X\[%8&7k +i?s*h1&K(FB#O$`0B&-E+hoLa4^1LhN@DTZ;!j&,0[0&C&nTrQ2,f@MG6CrrdRI?.%ikO0\0,8egS'!1 +rT[a1)]SH'+Z)-)JF"GWIqbXBXIUNP<91>U=9"@H7/]a\HS/AD;"ROCqU9H$HslJAn[2.d^<1N#%.R?S +Z6?s)1N6THQ1la&.aQr`I$LC.Y5*u<+]5kH(!%:[/HOirjJ5f9Gq>-P-/7!XlODMM$M84>JYe0<0hN7s +5gfuj#[@umYZ1"NerG@/,]$t)f8?nI4(]XO4%:/>&DhnL"dT2W%4eXkmGYJTKsUo<A&Lu0fVf<#1\>'" +;X#+7KiX=+^^MeXoIJ[C[*#(9'A\i2[Bl-)>?+l=]fic=L*E[LAnXII?-Z9@R%_CET+$#?"/#PrpASX2 +@mrNVX+023ftRZ(T05_K<@P4>>W_Q.IcEN6H:^#dG9A.M6T(DTL3f]K@>JF6`+8__Z/YD`:TP:uf-T)e +3g,K3H=&0V]1IQS@#fBj1Glcj)oHH`g)R4CaBDED'j.bBbs\*%P%+[0ef.ZJ]!Qj7&I\U+1%?-$4TC8! +:+8f6;i35+7hg1r?NZr#`1^,8R,6?<2gg`Ig=R";ne4sn(=.J<BdNqoB$qpP=(rujolW*TL1cW\dc8"W +koL]M4uAI<LGY3G76<XS\6aI`Nu^H\RC$)XPdIHb]!im.UnKQ>R1,;phnM^[_#@tcXe.T:=/:n+@qm4F +j.XQPKk$!BkeQ,cIls%l(`.'Pfti_.[tJp^017)kYDt#!Xl*?K:+a2(VW:n^g$6S`<I7D*o^<N@Fa\K/ ++o1:cqGia-&K?*,og%mJqX`*!oQYtSif05:iB&-"O;L]_fRCFup1e8`5teLeD%-+,e7fu?*G^(1.!jMk +BA+QgS'r$'Gjg4G+QXMo3DRM:+(ocaC[V.Xrg^NDpCED0a0c`_ogn/I]oY4f^umrP[8X"l4,(DISO-F? +K:`+]B;as5++bnE_J\#sK,E+fMBLca1h;FBbVM(+[WRL44-+JX%QGsKG"?P+90]gU2Z\*de)Ot+[\B@8 +Ai)W>;/6j5TWQl%RHH"C7i-3h5h+@/4rWEO]4?eTe>\:'nX/V&6PeGBEh7=6oR[gFr'Z72UnNMkf`R[Z +bUQ#D[e6#B,'WqL>R)"k-1CoJaj4V<PG_G@ibe_qk.W.^Or-]0?`/\f6pUdu0cI`m"6;@]J@Y\lS2<#o +*g*D$`q08EMD3/E]0o4)J"ftG)%DkX-CKQMFA;5[<L[NIhOn:#Qh>"GL4u=1F_t9NNCqIAp=$m2B2_p? +Ilh6D;<,L;Dc(MW<F[jnh)b0U7m8LuBYV'bg:th1Ab++RQ[[>bYr!!5.gJOrIaXO#Pa#Z@@5M"_#'kO2 +I>g0aL%"EEer="s1!a"Uc(3%:S),cPr5K_2VIl<\kQ52-D7&3`&nkIIV;YQtm/B?0Zbd)tE_C010.6N= +o:'6q_Ro&JmR[+2hZKRUl)M_Z3W'd^V[NGLU1*22EJjha0"$/@q$V5:%nL;q9n^J#4(Zt2=F76Cs+Wm! +&Vb,M4i0q!8Y=B0-(B!5RBfDVOPM(LoVItm9__i,h;rBQE,.TYGi$&fSNYgQS+NE<$HORMF"G7%kcd!3 +2A)*g6@AXeSV@'Y6,0R*nA^Vc?K6T!f=1qaQMs+/BuqpYC_Wq$XQ6b&AE6&fY=W3[n/AV)W3Ri0*j5TQ +7^XNd6@]]N+NT8.i<+UGHI.S]_5->'on+rCp@dKLf(uh(ih4A;H[,]d8$R"$cr!7uA--k;&QVBb.&0&n +KT:YjRT`.T`k"a;e[5HI8PIOZUfB\KH8&ES0=</,OcMeLDJ3_Sfe\*"DU2@(7*"%W6@:32A]9&U9+k*Y +,S@^eP)-=f%mBq5+%^#&@LH9mrraA^)_KM&N\+<9kPRTjo!#;4-mId*NFuAFP-S.^;hf"#o^g6/T<mBi +/9o3:#Hab7&Q)YeKenOG?c(EgpF9K??_&@=e+/u;Tq@m:]hrWD%$4`bq0juqUp!hd=1*Lil0FjArR!Zu +8b!QQ.WR1N(kH.)2Q<'Ybk%5UO"[&#B:dEn^EU9]D`]n&fb'>S4lX<_EgG2ClQQU2:g=jLoo*"PQK,[: +W2'j+6E#o$1de_(lJ(j<X/E;H%<J8D0Tm1"ZXYmj""iWY&Dpcr)%rubBkkEP=[O1$n+a!M3T+iIUNq=j +a1@i`](?*NXR,5'4\T?XG&qYB6@[Rg0c$EVh;%4u_HV]khQ$o*(HD(9YP$WZSIX-?L)7k3+nMoKVgD4? +f1msPE_rJE:)s48q7X6L#=\=_n$q<4pPNp(+0UW^k1<^Q&1'el.rK8M(Hb36,MP6WWEZ`5f*n,%mG1Jm +1c#N2*MU-/O<[AQgHE9\^L1i$LX5:?OUJj4l]liD*&RMhKaLJ%d.?.6aB-6?Y?"^U)7,:N&cqfCE?BaZ +[CTu"7eUlfhN4qnNf^Hq2sj_n#O[\P+^_>u:BuMsgFZbe%6*CL'fH%*"'-soaB-<Xs&Jd.2\,]Sq<qGV +eS@9r1NR\m7A_VJXsTaC.kIKW^2ZN1PgakmmkB:mRC^'baMj[$ilFotBY<ScWr]rW?",U\aI>qXXPUQo +UU)I-/nf:;.]R/9MgFT;aD=QkYosp0(!dl@DpB2NM6CqW^rEa>A2P$VGI^f.cI*N<qDsX\FbR#7!)`U4 +]k;+P[^V*ui*`.$ThqJT6p*U%M>sm$NjKWDVYpk"@^V]mO=Y7Hg\LD[U2QAoje5$KajG0kj4PG0UuquN +kpcS\o^SM;a?*[=kJ3(#]>D.bO\<:N?,jEuJTl>f,BlH'(VC*e8?tk/G2@,;bt_>VU*9A?QmFrT4h-Vo +*H*.-cdU3;OaXs[bI<`;s0NlYcr9]JOUI_IH_G#Cmcc)7GL5qGY]D!rEg)*&iB%;-[qsUTir"/H0'Dk2 +nmH<H44!YkS;7Y_/Rg^hFZcVJ9.&=tqk=Zid63S'KI#k364/keJ&s^mpVr`a=#DAQ,0d\6\cV">HDB17 +(<7,2#ap`QJj_!o6<\bt(Zse?KadOb0Vm)Z'L?;nlCJXD+idcUC$ctuAoTP%S3DM"<f+:12a&CXrKeHX +r-Y]UP'6hQg5HdN,/p<I0(%tke-,R'ckH1SC(Y9E<lpMCKkkAd>QhCe9@p72L\"hK8REK94RCCP^;s5H +m=d9=JJiNA3N;som]JFs?phDNH"lSt8Od$&>YBp@43oJgC]$N-F'd_B*;SX3Q8O$Z9gJ7m?j'ZON>Bj[ +c'Ui@^ECH30O_oTl'LmSke2kadoR-&V\W"fE(TXfkSl*4?AkDl.OdD,k"\lBbag-f$!Hn#b["Vrh"fFk +-K*.5*s_%i]"(4I8rUjQSmnV(p@jXq619t4D:_PGG6,XI9mgkJg`gAnpafnBKFY\r]NtoPN+Cg/hQ*#* +I2+J\C([3*e6^,LH#L^%V8p'=oorf$F6?MSZt('O1h/]2mQJ<>j'+o9+;]@Q$%dhXeVa'6NXC%YZ=4W@ +rpee9757_aEh4\(JM9%eIu0OSIkNsAa=U^UT,'2YV`=XMp.>DX4P9JZp<2XNE'c?imL2at8'^Z8rb;!@ +MY7O^UkoNHZCQr!mpOA1^+(W*n:'P]2go$IVuFM;n&52O7arWG]'OcG+#A$9l8d$X`)-f2*_aNeg=k^C ++^sZLLPeHGY[nP[MmteX`NaS'[ADS$6cf=ComUhF-+VtU"RaUmUAW`;L"2YD)tg0"hF!'SdV5)F1E?hZ +oL1D)L=O4u+4$8oYu[H!)n$L)HrR]:n/HDA8)0,9`]t;^IAt/!)Wo)SjTNmT:?`I<`G,?ZaH%>R,SeW\ +[aOjV+\)A8LEoo4GaE<LLmSPh#:NMXZ>>aOG"^m).8phQ[b$`]4"IVTpP=b0/JJ3m]!8\C8"B77=.A75 +ftj.ocg;iD_uu,"<,!d7I/4Z3qcD=.Kl#X(hu0T:"db?#I(%LV,(@Q2AOK.q2TH+*lQ7`n55gCAGOJm: +9PurUo^?W[[p'2CqMD'K`nS4;>13r0)JC"g8sZ%&G-@'?Y6*$#&^fo)bDT+@A=stU5,?`f7"s$USG<n8 +L(QYA7icZ#,&]O<P3mV"onH`86W+e&T]O?\o;iF)r+uVgWQ7<*^cKFVXW;P<<BiM/p$+j!@F\/p,i2u6 +[Nt`7<aZ<81.+'E/^H1GU_VPA<$k)Y1:$A@3+hBj2FHf]QPNb)Y,G1CocDh^ok<\ZR2'@h)JLqgWL\no +[2E/'cL")-D+`%lq9%INY!b!3Kqgk<[`K=Lr<qujMj$jCq7T_<qpuOkOHD!)e^K/N<Q4sf.gji_Pj`no +=6+"%s,)1\hS5e`Km(i-+*$p#bJ*PaZ/YDamoV*EL,[^b?nGPl[K7=6'e?N>=P_)7f/5o7r7!HN)e:AJ +p,N"S*&3lt/$O1cRSW!=Vbb]@i+p"L(OFJQ@1?oCjYIY^MX^H1q"V%eK`8#sU[/<(oN0$'hf8Fp//NM] +FP?6(G9its,]A1KZn'/fhluIMJ_fbZLjBB5N:R/bAD9"0#"@p:W&i*6?L+l_W?&:V"qK?=\W;R0ASJCX +jn,+&l%kcDDdaKgom+RN!IJ=mN=A6&lB2+1q"2<O%fVH?INtQs?F];jLO2.41NR].+(9B,n3l^6/1LF' +8Gu"f7PM[HlC#44OWm#7$&TrlFUgFhcq@^4:&Y-rNRLq"ICmDVWR9tNJmQ-V>4+X>o+G\&If1KFmB6FF +7W'?`3MkJer9T;=*GgpUWSQ<.Ng/>"]II-6SaFp]pM9iWC6&dHSc1CR],I^A-1lhQEg?gFmcqOq)je6> +\g_ZnB1]:=8*C5F,3S2*p'C2bhCbk1k8@XdE1Z_CcgI9WYe+Y)_!_&j5KJQ8_&[66orR]93@uItms:=3 +fBc3n*&DUo7Cd[Rq0(GM]Eb-arBaQaUQtKrM_qcYPIokP\"9E</7b@pBOO@'H,d"n[s._3$b_3V$G"O, +lb'f?T>&X`$O:n6o09JGY+pfBfWK168ME@dFgJ(6eMTI,Q@jLU=Z=3=a#P%#WI7OYWW9YHlZ"@7o:)r, +C[TmE\]X)$dd)4LV=H20l\[dNHdA2j?_#HaI@[<5HXfgV2lb+7T:LQDYm6Ib[(DKQ[(F&l$Zg>s0;RD] +0PhPr\K,&glLZpT52*LD3X_A(`Pk+4Gt$e>2Xu31Z[@+9<P%'L(fuX!C/1Ej6DCu9"M616#n*]g/,Q9Z +8f;DtcJt>c;s6T:'[Q0JTrldJV$7t"]qc:U8d_jm0Db\-r;d#/dY(lh734\7$GqrH`_uI"$_K<JcIF.e +T',j^j+oh+r8.'S@MPN*&iRKOcZsj?QY/"MNeq$),GMQ42ggBkAk<HlFODhg0s26F4JOoH[d61Db9+N% +)WX5G\Eq_Y[Qp`K>;VHd\,qQi1NM]lE:!OLgNP3*G;aa+4=bGN9VP+kZV.@;C7@BYfAs=eQGmQZgJ$b> +D'j>B^6=,HT,'Vkkcagp,;M+\Rrsq@T(,0;DoN&/lC]Ya@^]A/Z;ed;HT#]ad%r;[)f+:U$m\74eMhC, +0e.a4o4K>UFX[u2d<Thmka#"]1Y;7)I^%+#j2h.H\-;H#93PLY.2m6N.M8F[Q'9tirpq8P<aW?](]$iR +:_(396uN#b=E@&Ppl:8OL:%gZetV!(.Pj$@`>mQ&HAM-+T,h^%NtFI>ND_pI97,P_<ddS;b\nO\1XCM6 +'ueTS,VR*P)0ZtbIV-U:Y*jO`lf?/2&('iL"Sp5a[tPZ=TL3GOh`"$=iI_f`8NS6<S+1dfc\aN]2Z#'T +EHoDaTD?a@k>mloX$pLei&Ef-1HPD#MmM*BBC*rn"2[su(>e)UjM1'>),'\!L(W@#jFXY;eD8V$SMY!) +oj`9ar;h[DXKZDaD,E,b72C-=IR=n@WjBDS[fFd5TB=1@*[<Iaj=a`YN1De(3HOr\1pCrO5n5ekf%Sgm +lsA[?mi\s:GV8J$435!/ru,W\&$op3Fn3u-3Ep2gVpY%kTpalmcbj\K%LP;=MS(n7:M;R<*4s"DX>Fjs +?""3<,+T*9NJucG0_I'b$>YNGZiBi7'PkBup.`(J=M&/32`olVW6,i8k$.2?)Gt/"n+"AQccCHf&YIL/ +)KMM^=emP<L""1KOT1`WjfI7gggb.b[ePH\b)cl*XMN^,1ZGh*/F@UK)`;NSfN"\bde0a]?b;*f+RhYT +NL\HtVpQI1L@0b"[4HA(j[/$jVC&XrH3WSNj\9YtCB\gRhp^^11;3:dNb?J:f8d/7Z8O#Ydd(C$$_\cU +"<PX&c5>$SI.E5J;SMN6Ze+f<T=nYlnb9/Ujh9QZb.n&s8idXqAc8]:9>02]<+M%u0(G\"Lk]0uE>lj` +$(H5?MV^182R?`^k8n_Ka>pKblji8e:Ml0V:uq0/$)^cp([<,,6cPBonNof-f'2j4GZ2eZ\SZZ3H!88[ +RfaI;ORJ8T11p$1"dsZ$@Ir)b*N(VD6g`7>:[8jlKMa45aqO37_*>5roG7RAggLA((`gbLRpQ3*@Xdnu +qgY#Hc%2c@6]sFSmY]M&X`R4[G/aYtd82jmE/O_j\QV5SquqA.fj`Z,"*`i4Vr.*_^/&i]BMNf!7t0J$ +cHriN)'4SWf\:1'[$n:<1_u_NQc7SJWmAH<V4?m$[$hrS?Es6O0-Lg@,BCa&`7dlVr-(77=a]1]3tqlU +_VVqD$$7S`IB0TWX9k=aA=M%,ln,udNQ5sLY0NA6o>20OcY:S7EEG(-[BOClVXDX-Bj%<+=>d^"CtroB +fr;pkO:-KXQgV7;@blp:H!*!V7s5BCAln>WF!3pJZ>'T@<R[QMX/<W\XIB-ZbGsg/#cji30Y"4IID;kP +SsR*\g*Sh0!%@sYZS=FNS"?fi&^pWNUn$P*^3$EQs"Z,7L6On-\^6g$*44_tY+]-IG4<\TBmi&uM!#Wd +X/9NX^T<lu+fq-$+g>^qk7?/A_?h)`2*G_;H;KBHBno]p.i+(E:![`!<_^p&*`c#(_.D0h*9R(HL*+^I +`&CgMH51#.WbJDd<RYUQA^u1;+1]bQ-"[$pb`!ikh`u(BFY/rnjT;>tJm@MZqCOF?GaqpCSDl'+&`bK- +&QG'i>hQ3/GWL-n(OCq%SG(L7W/4@QaW;(^grf3>h_>h^_%$(Gn!K9AI@Hg?>M$F,2qKulIJMg7:N=h' +1Us&[QeRegL:!CnXl>m-W6APHn6(%OlUQoTe/7Dfd,_NGr;NVV6N?N"2u_^$$iMk/\@#7$isJ^[!WNX7 +M;nh*$M98Vc?/9B0$%$gmH+/j5<WX^nU*$^!<(A!MQo-n;t0X?[HH!lK^#(Sb:PlL/n8N/fT-Ag<&3%L +Vs,:?h?>f/RjXQepk]k!b$AEAEa:oO#n$]Xa/^6;Zt2/Gk5!(\3Vk0AYZ"]@1h"I7g%rae.AIRL%il)0 +M-:G)[";_gaI\XCi:]sXbkpXkHn@X2gnIN`WOLqR'lU8cGK&V1MZ#@XeYK_ACXlfOd6IMbYQN#=:Ou_A +cEI19ZZnPeoUmr<p#65'UMUbQ1f)j,d8fY)lIkdga7=g;,p?iG:p,&%CXBK!-m*Oa]M\)20_)jVTVFM' +@itu2)mGbGY@M<RT:Yim^Ycq5T/n$CU^2UT<'g/iRC/IUG)Me<iPk1o#3RI;hsIj5'DIB2O$<LBb]Luk +S*kh^&1X%oeD]!rk(.N?S5UI6m9_dS;"gupT76,4nDW6Tp=bt.[G;U054o]&6.eF?o/:5R[@eLG=6<$" +2>`@thc@ZK?R05^/\Z*bK&RJdYl.A4c_p`DJ6+IrTDU+iA7R/<ILPbqYPQt?&C$o`YTuV7I/;ZcR(^]. +/N,Ot\eTuP<P`%?5q'6H(u-9`&d>_Y%M]gcS0>f6A3#J[10@t6)i"L<9$QZl_Yghc(IWK;pu':B5p#mW +rr05HLoR*F.&[EJpbl$qiU!qIF.a!TldJP4l$f`AU>u*lNro:@IVjZ8H!X^J!1e^2-6GJJ;,F&EI88OT +K4"WJJj*g$8Fp@l1<AU^:<Y33$GXS1JO-#Z/\l!"*N4)u"l$D#r47JGG.cY[]d6(.qq'R.#&.pY_%EI0 +_'Jr+5rnTRGBWr]fs"32-jfI7'bo[gaIi1jkAJt]EkuG$$N*Z-o4uZi&T>ttqIt=_P[iH9f,*7m]nW7+ +U>13\`XFb8naB0<BhW9q$"#GB?ZB]8l"Imeg=fD4['.^^7X%hi3>pl/`GL1rp-W&5h,`S8LpiFo?UFkf +54)[n_qq:sJ$[J)bsM(A3TGtXI,/W!l*O/=g9(MNNPAN?q=[/nIU/1JgI0X0h0g^L(6InOGDAL!`!S@8 +7G`MCa:gak]AQOD$uUQkgI4<nR)d)1E4:E6[#01i`ce_!A)/#D1KtFBS_MJl@.f!69t_Vla-c+M[0(>s +>/f*],[r6omt[QC^]f]C$;U'6/tN#?&54\4nY9JWeabUDOF8^!@qTE-8!#T1)TE&`duN0.9Qqk?)(Ek& +D!%P)Y!(HS88Fdm7o.904!oee,*2l9n@7Qs+i0`V(Ba)<I(kS)VM&ZV$-^mFo-eR%`m[-[LN)[-("?De +nCarD&0@r@h<Y;I^Y?_\DTBCMMi63Mc3]UdfO5#t$]P,(YMDKahX9RAnMn8N-M5bFn'5Woe,4N7f=))[ +#35VM>"/?[>(p7a["eu`$iQUeVdJNgkbj`J!;1/+Ip*-QLee7FLK39p[e"9t;fDD'=`4)GF69jS:Y;5H +41mYfE/.p;S12e`s!YD,)b\i'Knmq1@eY8f_m6^M;]1K;GDD[1:W=BY!+n!/,De-dEe32ReKegh>@9]\ +ok(qZ0rZc%QPhCHJ>))RJh\\hS$$:)e-\cJ0">;)M1Xrq?$3RL?OC8ia#e_aL^R;bh`b;\+t.XG/n!qO +\As..=:Z]>-`=a.2-,"3(l.&1UgMfQhI=Y61T3P-G4<%[M?)7)p%gDR'4>pnC*t+<7b7n#U8&C1<Autr +"`@oNCsP>KT\]hUP,ScAbl[5TG?Z#U9iig$:4["Y[pii*Ji+4KC</BZm]sP#l"1"9Occ*o$"eU*=NW4m +2d:)t5p$FjPGt6fREXL2`j`?-j)GcDfV&0J*BX'Qa8C).)=dAT+9a=ohN$7IpVpjJZ-;ZP;M'%'cV'/" +#jZf$8.351cnPOp_YeLcoV\OHgJe4?lfR&ZFQmWUUrWEJpg(]?8&eLc("DgMPqXceno8a)AC&3Yj"enZ +[".Uf.uDMon1te$R(1u&m=ab(&pI/q5^MbiG"j4-rUF`nq1`FU?<GEhSG!$aJqk6=#7'u>HsbS;A>gis +h2`q5HI2GLqlMqi$XtO,XJao-&B7U%hVHCF**+$lMiY(+ooQsOg;B7B"m:a!?_,$UaqQ:1hu%O1nD;@7 +Ae?<]0*T1?oTPmN6NtI1n:VZNr%J]eX\X_?6On9=mFKc,m&4*86]*V$(*o3L3De!"Ic`mQDrQWlA1)g% +4i?X]%L[(Wg?FZO!IZl3"!n+@JQq3pf.\ksgS#\Cj8:r4/8?-UQJ*Bq:OQ/)HX8J)'.F%Dd'%p%jbb-# +#eJaS4.FO!_=[P--RFk.nD$t#G>ij02l;8uk%^SH?*kbl0@QI4+ZkuRCMk3hR_O$%XL9p7c/R43f.D]a +"E1c>^+I=UA)<kq!AtQg!51:>m>dQYHPlbSFdhIB[c5>oU@!KpC6p4X6^;4@*/?<>p7ND>*csj*hK6e7 +\,dL:eVD#IMDc1dgpD-kTMR6>$GH2<8h9*E?V%,f"-t9D6l0*fO*cEqT()NRBYT%uL(Rg:5+W-68]r&/ +=$=L+<&3J\<i.@gHFo%Z`V*FJVn$uXC3quKb_fR;%3-F6Fl5S[bZt3iop^-M\]Ud$DGa526-)cHbKkc^ +$3i;n4,n'k5-(_*>8gOL[I&1WlEkVMZm9S:#aUNRgD/bLqFXt`8!A>SBf6m\)TLBh@b7ik4j[h#/VSe% +;l7&3Ci?83Z\,T^E?e]o^%ChjYd)q`;(Z`.le^;oNh(ae?6_-9IX)aFE.&HHN+&WaB2V+)<J-R_hE=3d +/g6Dt.GMg4/=H!cOd*'pZ@:+EU)RZZ#l*a,hd/Q!g!_Eaj0RA2bsC&`)M^Hmo@&b$dd!%or@lQC4G#6* +KH6nfF\@%#o@C=mP&9fbh"%cDIC<'mX+L6)6],?P)lY^l:d"uQ16Ji)R-5[bHephs.HUh@g2I"96)>aA +2GcL->t32t:4uOOJj/7^;c"rH?GG_D11L.>je0:MDVicdlA[8f?iTb^mUYlP2O5&-._P"5`G>nFN_S#R +dYCd5X1"B[\,<'FjGeE)NrnQ5ecq![`h0>lku^A*WBmSO!+J*e.Egsg#u8hAqW[FkP[t$i13GU*.A13J +Io:qOI(W%,X^5@G;o.Z3eP8;WNNVk:(LPA+d>+k+W'@FGjDP2:L.Gf%`ppQAH5fRgcBg`UgY?6$[]B&\ +'Jl=*Vgu8(5!urYf.RtmW"5</=i[?L)&&.O\U&\$9P+'^)0]`(G)n&5531;Q(&F$*Nr"e#6hWN47F6fF +SZ:1pS0m2@Zd+f*0"u0aAe-'Pe,+6gWrAo%qN,"9O`oqUG!cbQPLd0mdYFOsqN1Ze[#dbZ$T*u3>.%"+ +/nrn\l5-M+c%"&T.bY)pcVu`=:KcBC+g^1T]XNO!1n9ps'[m?ad!M3AX0GZod`9ajX<9mP0JUMjp>?Cg +7@L>7nbnI7Et9Si+hrOR"e3!hX>&Pditc'M[K3!4jBN)![SY_Y+r290:!T82S)*<=iG=iEo^3,gf!AKE +D1GRdg`&0G$;;tJ^m7M!#D`U]?n$5>MV:"Q,TlW>4\lU0NQk_::D6chI66B*FV:T[^oaSC_oT!iRl(^^ +in(MPCXG$Y+P$0>5eai<$HT(p"/H+hn,fo6fSl_@70T;1n4n;m]Ec,mRR"Ok-HnR7J]6$V@UVms)lgeQ +Yi%/i2_O/lO$#+'5)9YFd6b/&hmCpHD;2<u7,%`lS_foVMH>"1?@6A`Z+?E"r(rg0!VKS2*"s?BntY.6 +/OkkMMt(!H(8F-t`;%H8K((?1O.pIL1&?G+@e>Xa;1X'@6oM$:E`.?_l80IV:jpSdpCQr$V0EcNR;":1 +m31StKpH`0Y$$#unX2l)+qJMjcH'hlYou#H*t_^4`u$H8-6*3<,s$s>kLsb_bKd'ZB`1_*6T3bTca]Il +AOFYK2>M($F)[i-j!JTf.2hE[#;R#Jl%_9%V!<]sp$=ohLs?&&`FmsNgju,iOk97M=9n38E?^mRIc]n3 +G3uA6DkJao,Q;X`6HRmAm..8"JNhE7]S5-n*o<@[](W)#KB(B3CbMgDd[Za8b+?I>m'n'Y'3g*TigY7T +;9NErAQ?MUW.K]<IJ^i'(\A`:1su=$[$KF<a6q^?V`[;2\JgsM1H!G(/YCG3O6f&ac.Yr>b[\g;5sN*E +<([LbYd&IQW$\A=6N1;"'40+Bd<A$Xe\glTVZp=Pl9>o%G5P$eB;q\a>*Fu\.`c<TBn6%+ZX?'A0bFol +l1F5N#.:Z&oZ[rW(Lm/($caWA.)(g*e'Zn,&6q7'#%R]Im]jfNs4E'YUf5,am<)8iIKn!^Q0jr8+5/j7 +^=3g;Yda,d4lb:MCan#B#6IJV.H&bT_p485bLN2t3KZi*4sWqV3BY/*0U\ZAqY:rO=HRk-4(`Gk0Oefk +%4Mlme+kUbesOB/Oje&Haq6RB9&kc&q%`9n<)$b@pNW:^p>WD!\6_p?rHus:6=Jt"8'04Z$C>q=`?Hr` +lE3C0V?tKGRj-5.?SL^\c[WuoRsC'MmiLRn$sU<^+2`sLHmkFX2@Z55!f/:^\CtW56mM_=+-qLR]>ZH\ +l#q3?1$=W#XnEVGWFq5@<IIpc/W>`km"^Oc'tqIHqfF+q[7+M`KW--(pJ=s+M;Ng'<"r&Si`^WW*c"m\ +I362u+S:LoU0X!E6:oDs(;,Vb2:e;H.\Go0V^,>D2H8`J.sSMFj\\8?i`[88I15t^Pf*7jq2!T-PJ`2_ +WiS?,/.1Y;n+[/@;*qf>hFJM00SPa9r]:UX`O;=d)5RGIh:HfnL=A?a2aqkB^Za?KD3#!U[',r19&)=J +L&75ud6iL?mOd+i)X=Z"pU['"l`2?L:b$ls'Ssca^i&It?b.C_n!0GG?\KA#/](Pdp1bgODh-A:r).X` +H\4rieY&SEkY5FE`6i%rF7[.VPS`%I/b3$q/pN/skYs)?P=sKhE?[fpHn[3PLp_M_5&)(AK^S-ioI`Xm +.DdD/0ZB%QKGu6LHP"ggDuC<Ud!Ol+d9#:X;2ZPFWP+Iie/Mfg'_Yh[60;NO$.`N^&>isb=.Ybo>#gk< +ZMqeIL,;*OENEqO'8X?<n(n>oF_Y".QLl!+EVIJ,T,66>[gdEE+dJt*"?g&iZO:t-k3PG?95H&0a"u0Y +n!q5Ib<uamCX#5gnC;6o<C(u8c]3]5"<3&0[<k.]1Z;GL5su7-rn+'CGCP<8;*Fp]-_-:)D^X%!.Z^ur +_KU4"-u'jgEWoSnlZ(0X/h/(s@@OVr3s9P!Le:=i0Vk-$GAh`k:/^9>0h8HmU6t]Mg6sUWS<&eiDi?b1 +T@MeZHkfa?H<SeP?a/Sr4oZO@h7F"&q8uY-/]h(+,4AUoZFQGQMtt&eY\?IVW[HYSGFQQiH++Z2ekMBV +?F[kl"DfLh)8PTI$I;g[ns.nf;\D$fY3AKk&s@VW=T-S$CVOB,:X=O2<VNZQj5JZVm&E<Crgj5[@,/.u +f!G%h'0D*o;1)nu:slkXP7"\EHLa_M]70Lo,EYKP9!qs`MX57n2Vc132O8F1Z8k-3nVU@]));CqY%Hrf +Olg:X[+:%?[EPMd[*77QjI)<Rbqs-nL$+/=<]rqjq7e"/ME7kNr'kKKerd@)>rLANG/DUU/Zn8oOu5b2 +_H_)=(4GBQ#N22>7<hEIh*inXEB*<Y96e4rKfcI9W_Q@l]3.#=1*f!R/a#d)110Y`SZ67mO7=6ug!L;2 +at4MeJBZ;cCPGOD3kjbf11EJ\PS(-kP9D0T$22t_3Nb'2[sp=_^):)'T75/uA@^'Z)&'h6eq4TuPhcKC +IkYXijTJZ-nsR!1KAl5-4/*U$.!<t42K;aIUSq,A*LpE5rQ(AtbcH,$PJGr]m97W'Iq!C&4oYU3k($Yi +qdQJ3(`L[FbG[3O(?57XfTP3L7R,?eK(HIfFchpk0"_gg"7Dl7OOV\EG[VFS/DDFc?"1&uUH'UE"B)*\ +@@)Z>9?]u@=*%8H`LKnc3:"T3'p(Qc]jWL>$E6dBON](%5p@!H+YCFK$T[-YFC*)j8%ardNZlOa3T(rR +*0fq6/:()SP8iQB1U=Y:Zr6J"[5is5Ci)?:)V3njaiA7<T&H_b1Kl%LM@7&'+2:3-K,%QCne1Jncm$s` +X:hpBCIl-I/UPWIOq.$=*l6j-"-+'`MdH$ubDL!OfQmD_NPH!IDfc?p8#3D\n"#P%Z<u[&Q]Q)eRJlO_ +]9&5gfYaL+"RX\0I99+f*p@mXh72495r]6^Vlrf=JDoDShQRjH&s7QjJMDIXo0LUH)gL%5K_VCU8G$6C +"V]UOBUsF[X;2O8T;VAaH/ImH[Ho@/PbJ8?l93J=ONsHDM1UhNK>*;Y&9dL^ktS.]q3raUU]Ge*?hk][ +h0'\(A]<o9LbG\#gt08QWC2)H06Ykt4dC22g8qYt^VAAO0JVV"q!><:d1=h4]nH\dNq8U^o+pi/\`*%U +^7$Xppd6XUSm+MJc-!CIW)jc.D,JK]eslRE:Q'Q=SDJL/R6g<.M:CGSgLe*(FF#eB5DEq`?%4t"i9YbJ +/INGo?c-I(@;\C+!OLCTbgelein=b+SAKctW135Dc/:R1Elu+B%Sg/bc9Wne<t^m+7]UL7VtO8/H,_KV +6G7JQC,BU/3&5'#/BC$tq?KoFL&JY`r6gX!l+NL_V=[bcM(KnT?hAbDSGJ"H+'V)'[kH-$p$c2/"h?Xc +C`Z[_(2=W26^D_GYt*-m##Ytbr>:]H#mjQ!%4^qLOSmTPXH&4uS"m]Y)rHg$Ei6BRRP]?p0R0nK#[$DY +T<>+]JWt4B(qnl]fi,UDkeOBb8o,(gpnFrhgbKm*MTI(GrV0G6:U2P'Zl2+iL1ML$2X&`cC$o#Vn<XYM +?PjrkG//%`o-HI0GcW`C@,>K[`+*L,'rpT.E-"?R,bN%j=%i+#`3WMJiW1*/8Re""Z^7:dVme;VE.Bsc +T"M_\MeB.sgTf8#MBCSR>Bju).+<cc/o>kpc?.HNd];m(]:L+&G!DlnNU_?p/^H!d8)==;`0PB7-e#Nu +%7gF.[f0k/9(^H:XLitCjPEZ3SfMRd_)'C?2,F6'e&[JOch%kKZQiuUlCVWAg!RRN3$$:M+nfiE-m&.D +bdLH!@d1YtqsTp'FN`@C;#a42^]/gb`r4ka8$4WrSkXpIMY&WG:'`Z*1sp[L5.&J;Ef@/c1Ml1ifQ(e6 +%#gUHT[03SgWtpMB\RmIfa>+8cKeYbG0OZ\'kgZac<,XHg$#gF<tG<*ZssP7D0['`p#":%9D:AsQWhO_ +*@oJH_N/I9Xq`\A%rmq)ODh8:5[8lWiW$,UO810S%))-d_<ct@jk&UrlAX`s)7o0jA_%9<HF-nX0fr^V +Xqg`Y6ELCHg5Hna=1Is>L+\AlM&C&`^IK9B%E',6*<!.0kkl)arslL:R;?m>=(?GBs3.WfqI^UO`u80J +^h-jMHZfu)4$9pJ=e>U=mUtgWL!-"cR=92Q-`$_R#=l$5(\oH0MMpAAa'=1e<-;s[>0AnkSeYpq6M%Sd +X\V)\THt'gYlZLsBY!<0jjlN"gEa]Q1VY\-PUg]1g9Q,1/dk@1(&2*R[K>h'g#L!Jo+/Gi[Tu!b=;90S +hsp5D71&oonOD4G!n1Kkc[X!o^Tqs6mQ70!26beJLWSgg0^Xbfr-(iHX"`nCQ>Ea!fj-1Lk,ubmC<6sR +:guSq(<I5U<_Hf00$Bj?+hMMtd8&!q59na3et*#KamNm]Ei>D9h:5CAeh)f8V%6OcJJC_!f>-[dXj[.a +/GeW,n!J:LpNX3o1*NEVm&h.J46ndDdX:#=,!+:Qm%bu?X!c\:a6m\EnUBUFc<iFSe=?GgaH.n]bMS(Y +#,aUn5u,M:W6m?$1DKN">"lQLR#[OL"MmFA[(H1`&J/_r@X.70NYl*/#2@(0L>BO;m<HDZErUoE/E''2 +eY]Mi-Nbs^TIeBcJ*pt<W=]BIm4LHBd/>*@>m%^peUDdQ@-tXb7dm-3O*A"kD-.sn>5Qn4J$epA8:0ZJ +$`d<?p,gr5SVD,"0P6-q?/P7o4fA\]W6+IrH!_laY5Y7'HSn4I'`R*FbLWr)35m+[c?g*\,#DPB&Ta"Y +Qh&!e]XXe:-Gj&*%X6P7T,$THq?hCo\)5e.G1YC:#n+o]a]eq`j7$LJq&buIfBdLOZFa]Zo8qcc-Wd7- +D`,)*--rXR#i'(D+]nK-POiSQ;i;WiYe0$S4S,?7Y(i"neI_,2k3!MC='p3HL#_LO?1m&1-h13]8[M$p +%dcE#'"q-oH:i*:l#:*(5UCa98O7[e?fQi#km!-O]*:`06Ge`UN(Z^_*?9&*$(9KbQbX#iYcJbs@>.,\ +[*gne*#@;Q>>jLp(>Nu*+k1,284XF27[/UUM$OO(2rZXg<CUo279V!Nmo`$D[DL9hr=X33mj47g<Da;Z +HI:=nDPeuO1`dX-c"%L_pVD`8629^UI+F6PW#tdscgQ;&&ZqSjpeA\)rGg%;Q6*lm6oC#HC1!3>)8XiW +;\?iGOCK/kR3A,#G5bp*>fNbF?deQT("(n`\."Q[VXCiD,.I\/JkJ'O?s?h2M'II@^]0</_,YHh*$_s# +1/9WWWur?rX>]BCNO;lMpKB:TmCeAbmXm^2g35<NbZtGc>hs<I<!4"-KFqJ14*i*\md\2NimN.D'?t*F +@bomqbc<]V@&RRi/pu?U%,`"#6aWrJ*d&$'</?GS&2f[iX+@J$;Ed17*VAM6<H52fq15rW?/2/jc"XBS +7'r,C*cqIAT4_s9ii1Xe@"oRNS^1mdLk4.op+r@[3[%B12lc+5W,TtWqG*Ru3$"O8N`EOK,hijPf"8.r +'u.gm4''0lPh_HR$moL7:p7!"41+`b=E6]6j2,<!L/7$?bmrl>kQf3;EFG%@$8Rc[ArJBT=t(A,"r0@n +1.8nO^j&aM##>r0H2.!JID0^<3,,;/GZ34&J%4Bu"7<:%[C>VuRr9+uOeLM)[Gou8dr=S8kR[8UP_S%h +[Xo,$CT7onP]C.:cbNi)fhZrUAZ.>$X=3?TRGUlS>OrW^/'?>i.UP:>pYrF.:<<!*@<Wu$R#d"ER7<*O +k&][JUA$eDIA]tt@&bd:1Quh!r-'\RaFt]gRE]/94%ON_D:G>f$o?&Y\73F*"gE+0lGkd!%[)+$VJ<`_ +g323(e\ct4[]bl8/+`I0fKfSd%O-;s;np?OM.7@Kn%WB"$8jfKEM;)D1:A^_Y#3-?:ktY8rf=7+N@AaJ +L_6i^lhK+lb08%-Rj2*5(7neT_*%<l,O3M24ha,>%<l)hSa-m=\XnO;Ubg<h1u'4EENZ2sXXj.Q)-/</ +o<%0,"_j70H:_$./FNL9D:+.X0=OammT$t*>LDZ(FPX7Bf8aG_"<JuX!g*EpVucG@TqCI%9WR5*?G"(t +@-t"R+'EFKlrkpS]s!u>(8!V>E5*][nhf-g(ct>W7W9@/0sl0ZD["QdSdQK][1k^T8SnEF?$cTq2%.lh +fk]g"Tc8*kfGiI)eJ@OK-9W<5Y%'S^3Lbr!i\<j7hPoS=7/DZ*=^iH2nY[VpOM<5R]JLNf^E`Sr%lu:9 +Ck'AOKDoAO=r1-Y,tG=3/^6ZJ+?i0&`hAkB`:n9Uj7!O-9$OKsIPi/&nbJ0,Z^'&jp5P':WG]&hfcBD' +UgMn/-`qdDs#XH3"UB5[;8O`HoM9ICa!eU\eBWc`)23J\ZsVrTZBH5FHHeRWj7K7.40dqn*n,)c8oU;T +4-<Ot6FX$upZ+f<+VX%kBq<h_cW.'*gO&I0SB_m#c<n*@Y)V3Z&)GmeIQ9;ci3>4tU2=k(b2'5Z7Y"_u +bL[P+V:og/&>ThFna`9cDMrC?=psBdD`IHJ2W&ifnTc2M'E5de@Ud(G(?("hiX;4keL4R#b_h+B=Xd(P +"b,_`32;X06V_X!DqJ9CI2`]`Du5b%%'/O,DT0g?[_*RRLaLBZ8!d7NhAI;6c&R4&EdFYV&U$eTZFR*+ +]P1ESrG*CRAqq*IXI=<jmBLD0nB8(OG2+MYg46E/RN6Shd]1u+\<BqA&f'8(c0cnl=Z(Q@\?*)fhH%m- +08l"@AVF.5ONqD3D!\te9hssKX%"p[+BgW)]2d=0)3tJVDq6!-bK"39X/8boBU>9Y\CQ&r?RI_>dG`%/ +AP^GCENGUWIcY(ie-pn.o/2$%k/Weu,.a"IpfKE@9?4's_,VStWbE/3<m?Xi=NV)d]d<Q9]B`I$V6cZJ +@PdP_C)U[#Wp+RaXI>/oOEYYeSbDq!):\Fm%iIh0<KlQ7OfW?PaM@aR@1O5\5Hoof5gP5XO&=D!fL%dB +kgXWcJ8E9<@)F$@P%5>l^BX,SUch+:p(66A<dea1^Mn-:rVemEj?""N"Nbj5nM6;U8*ij0Hq40Nk="'t +`.hE-[(5A\J7molb$16a\18:X43s<m%t+274_4>1T#VoC)F'2E`6@4X%=-m?[EQ6#Z@s=[)rK!%%@#g_ +[2Te5U9&MobA.1uO3me,V^^lj\$plB@`0<iGs,NR4c/XrH].7AbZg\aNaGnojmj(?5'O6uTY+3iqV:/# +O?PUY<i1lAlrjE:gW^er#%,icI4==7C>2fM-g'dl(S96qHUDj.I;[KA#(96;qAf%i:\cL;-]V=l_c$6K +RalRYda@7E&u?AMg021n=`&Qo^NT<ek:pm,XQ[+`9il2+G'rg&[HVaR9"T^>2lF0@Xa,mSoXWTKiWNT: +>(]!d/:DD9q1q_:ZbQaY4$1To53LN!BJ2)^Ei9g9()D6TFs4'6)Gu^L<sm-\o-k%`^^-Dt^66LfV"KAE +LC-D@ZX5K)%qor)>\jN&TM/:0cq4+NB]&[A.[%?I2A^QBk]79o8UAkK<lK!RcZsKGL\/+\+"?ln'cp?& +-*VCJeRY#mTJoXQ67uE]K3Fe^j%'\29=cBS_LBa5q,9RHl%PiT:V`?6j;/&S5%h>FO%Z)YQ9I6IRjo_` +'m<Q'PC;WFk=C*fF/O_KmD!,sX`l/ThYXlNT6nr!osodgR]+OaY&WZH#P#K4_9h@9;<i5'MSDKM>=G!j +XXq*$!d<mg)*DhcNkGaIc>J(pqAe`dI;[Kf-@O0W+GO]@>1q]:_=\TgBA?pF_4.AJCj[O9)&SnC8"\8! +"&H2;RTlDjhS!Z<--VbD8i.k5p7oqclFG:)?MjsHVb>4oRG[OWT;]tW_$VIZ$Hd5=2Gq4b07^Au+4'EP +k1RA[GrBT5$m*/.;?E4EeRlPr*pr4$T&p&d2no1LB4?-*V"C>g6iYi(NA#ZSf,8$SN6SEj=&L)fB[8?& +,'pc>?EkuO&`$Y,*U#k;LV3hu/+fNuP4'=;LCB6jLCERsLTLIKl+4[[L]$D`LCEk&LWYIuJ3L>an>5Pi +W^e0%:lUBGm4$Aqf1t"<9HVtP4@^LI?-t=6cWbA:d>*CN%gbTFik;GCL\:uqXm\ClGL081g@P$H4mfpY +R9OTiS_\TE48X3./q(fTaP;j<,A)bt6gsj2B5UZ7C9A(-VZ&FAV9ju)UP(rUg07IiksKfIS[1T<K@#,7 +=a5a%414OG5%HJ>eq\Ln1A)f[_pEX%+56AX9_J*s5M!o?S_:Q(i=u,b8OHP4g`97HEIGptTId@\[`+XH +6hSl_$?'!FD>u)Z&!_hFDl!s^m\(./C7u.AU-9hR/l4*6WrL#s$M"#^R$+6'&c.TuX@mRb]E(roULAHQ +8?7-_]$S'Wq1'*'e?7/R**rE&;a'cH(m0h5R,N`gs6oLTT6V73s-NW^^0O8(^;7!0[nKop`9Omt=^VHs +C<kc;N1tbaPPpofBAuE=$MsXV+2iW;_CQL!CWFp@)ZF6_mjKmhqC8^_/C,C4T;O)M?A$_R@ZT\%Y9+LV +*:2RSpuh&2k[+mZf\6C0W?f(ulGj5(I_Va)ISoTmp9"=$ctO:LG.4O$a\8e6i:e[fq-1]+X*'t..b_VS +q-+u,65%"^<)h6%:]-,oE^$SnZcZM"?aImZdB?^7hrr[nU69\3<BTfTAegV`1QBNr@!qm8W:fTq=MP<2 +K8Q\`.0&5R&5O(Jn]^f+@DVa4`4n1SCfJtCc)rt'6qu#5p&=^i)pm/cjnjf^YQ65Pk2;f6iN')4;ec#A +c/_:_US`YBIc=_C!hhFAI)4&_Fh_/NLi+g#Xfri:R8lCPP6q!\DM?&CljU)85Au7t(T%s_`RWHjr*-[Q +&,NOhWPhJ7_ger]7)]i0MZI)V]DeG3a0(t]1m_T9_D(c^pK?KWG52dj:K0Fg^DOo\?2sAA*uEVNpT%Z: +EIZm7_]@q;eXUX>I)#O6.d-\+s0'0*S<LGNrXj%SBhkU;'g4;A6t.barLsqNGPsc+IdoShUHh\1DpLl` +pig,8DHNqjnI=0Hd!E_G#uAJm.WKges*Itu&18UW:#j&&s8KNQ`D1Y%ISk[N\,(T8ah#iU/@T+q"i!ia +0os<pLdfQU^\pZAgj1mUf8l@-k51!b0h`oA%1.NF*!Mp"r&_,iKB$fH8U%eK/R&Wf.sN7ed=pKNs4/l$ +9T*?Mn'BT>`AQ/XnZ5TJMdMSA[;Y_&^Af:<<o6g;?OMA^GoluMs"BQ$J*C2+K"rBnL)iqW3V=Ea1$e0* +qT&Vb>5TKBpqK7!VYg~> +endstream +endobj +7 0 obj + 86690 +endobj +3 0 obj + << + /Parent null + /Type /Pages + /MediaBox [0.0000 0.0000 945.00 551.00] + /Resources 8 0 R + /Kids [5 0 R] + /Count 1 + >> +endobj +9 0 obj + [/PDF /Text /ImageC] +endobj +10 0 obj + << + /S /Transparency + /CS /DeviceRGB + /I true + /K false + >> +endobj +11 0 obj + << + /Alpha1 + << + /ca 1.0000 + /CA 1.0000 + /BM /Normal + /AIS false + >> + >> +endobj +8 0 obj + << + /ProcSet 9 0 R + /ExtGState 11 0 R + >> +endobj +xref +0 12 +0000000000 65535 f +0000000015 00000 n +0000000315 00000 n +0000087433 00000 n +0000000445 00000 n +0000000521 00000 n +0000000609 00000 n +0000087409 00000 n +0000087887 00000 n +0000087603 00000 n +0000087642 00000 n +0000087744 00000 n +trailer +<< + /Size 12 + /Root 2 0 R + /Info 1 0 R +>> +startxref +87960 +%%EOF diff --git a/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.png b/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.png new file mode 100644 index 0000000000000000000000000000000000000000..df5f005ed6ee1ac982705590c2c5c966409fb970 Binary files /dev/null and b/JavaAkkaFuCoin/thesis_latex_template/pictures/TimelineCorrectTransfer.png differ diff --git a/JavaAkkaFuCoin/thesis_latex_template/pictures/_TimelineCorrectTransfer.png b/JavaAkkaFuCoin/thesis_latex_template/pictures/_TimelineCorrectTransfer.png new file mode 100644 index 0000000000000000000000000000000000000000..df5f005ed6ee1ac982705590c2c5c966409fb970 Binary files /dev/null and b/JavaAkkaFuCoin/thesis_latex_template/pictures/_TimelineCorrectTransfer.png differ diff --git a/JavaAkkaFuCoin/thesis_latex_template/pictures/logo.pdf b/JavaAkkaFuCoin/thesis_latex_template/pictures/logo.pdf new file mode 100644 index 0000000000000000000000000000000000000000..9ecc350336e7bed339dec3f703d3af447848a81d Binary files /dev/null and b/JavaAkkaFuCoin/thesis_latex_template/pictures/logo.pdf differ diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.aux b/JavaAkkaFuCoin/thesis_latex_template/thesis.aux new file mode 100644 index 0000000000000000000000000000000000000000..0d78789050064c3d0970250d021682edcec84296 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/thesis.aux @@ -0,0 +1,37 @@ +\relax +\providecommand\hyper@newdestlabel[2]{} +\providecommand\HyperFirstAtBeginDocument{\AtBeginDocument} +\HyperFirstAtBeginDocument{\ifx\hyper@anchor\@undefined +\global\let\oldcontentsline\contentsline +\gdef\contentsline#1#2#3#4{\oldcontentsline{#1}{#2}{#3}} +\global\let\oldnewlabel\newlabel +\gdef\newlabel#1#2{\newlabelxx{#1}#2} +\gdef\newlabelxx#1#2#3#4#5#6{\oldnewlabel{#1}{{#2}{#3}}} +\AtEndDocument{\ifx\hyper@anchor\@undefined +\let\contentsline\oldcontentsline +\let\newlabel\oldnewlabel +\fi} +\fi} +\global\let\hyper@last\relax +\gdef\HyperFirstAtBeginDocument#1{#1} +\providecommand\HyField@AuxAddToFields[1]{} +\providecommand\HyField@AuxAddToCoFields[2]{} +\select@language{english} +\@writefile{toc}{\select@language{english}} +\@writefile{lof}{\select@language{english}} +\@writefile{lot}{\select@language{english}} +\select@language{english} +\@writefile{toc}{\select@language{english}} +\@writefile{lof}{\select@language{english}} +\@writefile{lot}{\select@language{english}} +\select@language{english} +\@writefile{toc}{\select@language{english}} +\@writefile{lof}{\select@language{english}} +\@writefile{lot}{\select@language{english}} +\@input{1_introduction.aux} +\@input{2_actioninvokesentmoney.aux} +\@input{3_actioninvokedistributedcommitedtransfer.aux} +\@input{4_actionpreparedistributedcommitedtransfer.aux} +\@input{5_actionpreparedistributedcommitedtransferanswer.aux} +\@input{6_actioncommitdistributedcommitedtransfer.aux} +\@input{7_actionupdatequeue.aux} diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.bbl b/JavaAkkaFuCoin/thesis_latex_template/thesis.bbl new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.blg b/JavaAkkaFuCoin/thesis_latex_template/thesis.blg new file mode 100644 index 0000000000000000000000000000000000000000..71d1e28470cb0c9e5a702f2999197833710dd524 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/thesis.blg @@ -0,0 +1,55 @@ +This is BibTeX, Version 0.99d (TeX Live 2014) +Capacity: max_strings=35307, hash_size=35307, hash_prime=30011 +The top-level auxiliary file: thesis.aux +A level-1 auxiliary file: 1_introduction.aux +A level-1 auxiliary file: 2_actioninvokesentmoney.aux +A level-1 auxiliary file: 3_actioninvokedistributedcommitedtransfer.aux +A level-1 auxiliary file: 4_actionpreparedistributedcommitedtransfer.aux +A level-1 auxiliary file: 5_actionpreparedistributedcommitedtransferanswer.aux +A level-1 auxiliary file: 6_actioncommitdistributedcommitedtransfer.aux +A level-1 auxiliary file: 7_actionupdatequeue.aux +I found no \citation commands---while reading file thesis.aux +I found no \bibdata command---while reading file thesis.aux +I found no \bibstyle command---while reading file thesis.aux +You've used 0 entries, + 0 wiz_defined-function locations, + 90 strings with 742 characters, +and the built_in function-call counts, 0 in all, are: += -- 0 +> -- 0 +< -- 0 ++ -- 0 +- -- 0 +* -- 0 +:= -- 0 +add.period$ -- 0 +call.type$ -- 0 +change.case$ -- 0 +chr.to.int$ -- 0 +cite$ -- 0 +duplicate$ -- 0 +empty$ -- 0 +format.name$ -- 0 +if$ -- 0 +int.to.chr$ -- 0 +int.to.str$ -- 0 +missing$ -- 0 +newline$ -- 0 +num.names$ -- 0 +pop$ -- 0 +preamble$ -- 0 +purify$ -- 0 +quote$ -- 0 +skip$ -- 0 +stack$ -- 0 +substring$ -- 0 +swap$ -- 0 +text.length$ -- 0 +text.prefix$ -- 0 +top$ -- 0 +type$ -- 0 +warning$ -- 0 +while$ -- 0 +width$ -- 0 +write$ -- 0 +(There were 3 error messages) diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.log b/JavaAkkaFuCoin/thesis_latex_template/thesis.log new file mode 100644 index 0000000000000000000000000000000000000000..01d154f72fc1922219bd3591a9ddd161b546aeea --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/thesis.log @@ -0,0 +1,530 @@ +This is pdfTeX, Version 3.14159265-2.6-1.40.15 (TeX Live 2014) (preloaded format=pdflatex 2015.7.24) 24 JUL 2015 15:53 +entering extended mode + restricted \write18 enabled. + file:line:error style messages enabled. + %&-line parsing enabled. +**thesis.tex +(./thesis.tex +LaTeX2e <2011/06/27> +Babel <3.9k> and hyphenation patterns for 2 languages loaded. +(/usr/share/texlive/texmf-dist/tex/latex/base/article.cls +Document Class: article 2007/10/19 v1.4h Standard LaTeX document class +(/usr/share/texlive/texmf-dist/tex/latex/base/size11.clo +File: size11.clo 2007/10/19 v1.4h Standard LaTeX file (size option) +) +\c@part=\count79 +\c@section=\count80 +\c@subsection=\count81 +\c@subsubsection=\count82 +\c@paragraph=\count83 +\c@subparagraph=\count84 +\c@figure=\count85 +\c@table=\count86 +\abovecaptionskip=\skip41 +\belowcaptionskip=\skip42 +\bibindent=\dimen102 +) +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package + +(/usr/share/texlive/texmf-dist/tex/latex/base/t1enc.def +File: t1enc.def 2005/09/27 v1.99g Standard LaTeX file +LaTeX Font Info: Redeclaring font encoding T1 on input line 43. +)) +(/usr/share/texlive/texmf-dist/tex/latex/base/inputenc.sty +Package: inputenc 2008/03/30 v1.1d Input encoding file +\inpenc@prehook=\toks14 +\inpenc@posthook=\toks15 + +(/usr/share/texlive/texmf-dist/tex/latex/base/latin1.def +File: latin1.def 2008/03/30 v1.1d Input encoding file +)) +(/usr/share/texlive/texmf-dist/tex/generic/babel/babel.sty +Package: babel 2014/03/24 3.9k The Babel package + +(/usr/share/texlive/texmf-dist/tex/generic/babel-english/english.ldf +Language: english 2012/08/20 v3.3p English support from the babel system + +(/usr/share/texlive/texmf-dist/tex/generic/babel/babel.def +File: babel.def 2014/03/24 3.9k Babel common definitions +\babel@savecnt=\count87 +\U@D=\dimen103 +) +\l@british = a dialect from \language\l@english +\l@UKenglish = a dialect from \language\l@english +\l@canadian = a dialect from \language\l@american +\l@australian = a dialect from \language\l@british +\l@newzealand = a dialect from \language\l@british +)) +(/usr/share/texlive/texmf-dist/tex/latex/ae/ae.sty +Package: ae 2001/02/12 1.3 Almost European Computer Modern + +(/usr/share/texlive/texmf-dist/tex/latex/base/fontenc.sty +Package: fontenc 2005/09/27 v1.99g Standard LaTeX package + +(/usr/share/texlive/texmf-dist/tex/latex/base/t1enc.def +File: t1enc.def 2005/09/27 v1.99g Standard LaTeX file +LaTeX Font Info: Redeclaring font encoding T1 on input line 43. +) +LaTeX Font Info: Try loading font information for T1+aer on input line 100. + +(/usr/share/texlive/texmf-dist/tex/latex/ae/t1aer.fd +File: t1aer.fd 1997/11/16 Font definitions for T1/aer. +))) +(/usr/share/texlive/texmf-dist/tex/latex/fancyref/fancyref.sty +Package: fancyref 1999/02/03 v0.9c Fancy cross-referencing + +(/usr/share/texlive/texmf-dist/tex/latex/tools/varioref.sty +Package: varioref 2011/10/02 v1.4z package for extended references (FMi) +\c@vrcnt=\count88 +)) +(/usr/share/texlive/texmf-dist/tex/latex/fancyhdr/fancyhdr.sty +\fancy@headwidth=\skip43 +\f@ncyO@elh=\skip44 +\f@ncyO@erh=\skip45 +\f@ncyO@olh=\skip46 +\f@ncyO@orh=\skip47 +\f@ncyO@elf=\skip48 +\f@ncyO@erf=\skip49 +\f@ncyO@olf=\skip50 +\f@ncyO@orf=\skip51 +) +(/usr/share/texlive/texmf-dist/tex/latex/xcolor/xcolor.sty +Package: xcolor 2007/01/21 v2.11 LaTeX color extensions (UK) + +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/color.cfg +File: color.cfg 2007/01/18 v1.5 color configuration of teTeX/TeXLive +) +Package xcolor Info: Driver file: pdftex.def on input line 225. + +(/usr/share/texlive/texmf-dist/tex/latex/pdftex-def/pdftex.def +File: pdftex.def 2011/05/27 v0.06d Graphics/color for pdfTeX + +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/infwarerr.sty +Package: infwarerr 2010/04/08 v1.3 Providing info/warning/error messages (HO) +) +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/ltxcmds.sty +Package: ltxcmds 2011/11/09 v1.22 LaTeX kernel commands for general use (HO) +) +\Gread@gobject=\count89 +) +Package xcolor Info: Model `cmy' substituted by `cmy0' on input line 1337. +Package xcolor Info: Model `hsb' substituted by `rgb' on input line 1341. +Package xcolor Info: Model `RGB' extended on input line 1353. +Package xcolor Info: Model `HTML' substituted by `rgb' on input line 1355. +Package xcolor Info: Model `Hsb' substituted by `hsb' on input line 1356. +Package xcolor Info: Model `tHsb' substituted by `hsb' on input line 1357. +Package xcolor Info: Model `HSB' substituted by `hsb' on input line 1358. +Package xcolor Info: Model `Gray' substituted by `gray' on input line 1359. +Package xcolor Info: Model `wave' substituted by `hsb' on input line 1360. +) +(/usr/share/texlive/texmf-dist/tex/latex/url/url.sty +\Urlmuskip=\muskip10 +Package: url 2013/09/16 ver 3.4 Verb mode for urls, etc. +) +(/usr/share/texlive/texmf-dist/tex/latex/base/makeidx.sty +Package: makeidx 2000/03/29 v1.0m Standard LaTeX package +) +(/usr/share/texlive/texmf-dist/tex/latex/listings/listings.sty +(/usr/share/texlive/texmf-dist/tex/latex/graphics/keyval.sty +Package: keyval 1999/03/16 v1.13 key=value parser (DPC) +\KV@toks@=\toks16 +) +\lst@mode=\count90 +\lst@gtempboxa=\box26 +\lst@token=\toks17 +\lst@length=\count91 +\lst@currlwidth=\dimen104 +\lst@column=\count92 +\lst@pos=\count93 +\lst@lostspace=\dimen105 +\lst@width=\dimen106 +\lst@newlines=\count94 +\lst@lineno=\count95 +\lst@maxwidth=\dimen107 + +(/usr/share/texlive/texmf-dist/tex/latex/listings/lstmisc.sty +File: lstmisc.sty 2014/03/04 1.5c (Carsten Heinz) +\c@lstnumber=\count96 +\lst@skipnumbers=\count97 +\lst@framebox=\box27 +) +(/usr/share/texlive/texmf-dist/tex/latex/listings/listings.cfg +File: listings.cfg 2014/03/04 1.5c listings configuration +)) +Package: listings 2014/03/04 1.5c (Carsten Heinz) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphicx.sty +Package: graphicx 1999/02/16 v1.0f Enhanced LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/graphics.sty +Package: graphics 2009/02/05 v1.0o Standard LaTeX Graphics (DPC,SPQR) + +(/usr/share/texlive/texmf-dist/tex/latex/graphics/trig.sty +Package: trig 1999/03/16 v1.09 sin cos tan (DPC) +) +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/graphics.cfg +File: graphics.cfg 2010/04/23 v1.9 graphics configuration of TeX Live +) +Package graphics Info: Driver file: pdftex.def on input line 91. +) +\Gin@req@height=\dimen108 +\Gin@req@width=\dimen109 +) +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hyperref.sty +Package: hyperref 2012/11/06 v6.83m Hypertext links for LaTeX + +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-hyperref.sty +Package: hobsub-hyperref 2012/05/28 v1.13 Bundle oberdiek, subset hyperref (HO) + + +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/hobsub-generic.sty +Package: hobsub-generic 2012/05/28 v1.13 Bundle oberdiek, subset generic (HO) +Package: hobsub 2012/05/28 v1.13 Construct package bundles (HO) +Package hobsub Info: Skipping package `infwarerr' (already loaded). +Package hobsub Info: Skipping package `ltxcmds' (already loaded). +Package: ifluatex 2010/03/01 v1.3 Provides the ifluatex switch (HO) +Package ifluatex Info: LuaTeX not detected. +Package: ifvtex 2010/03/01 v1.5 Detect VTeX and its facilities (HO) +Package ifvtex Info: VTeX not detected. +Package: intcalc 2007/09/27 v1.1 Expandable calculations with integers (HO) +Package: ifpdf 2011/01/30 v2.3 Provides the ifpdf switch (HO) +Package ifpdf Info: pdfTeX in PDF mode is detected. +Package: etexcmds 2011/02/16 v1.5 Avoid name clashes with e-TeX commands (HO) +Package etexcmds Info: Could not find \expanded. +(etexcmds) That can mean that you are not using pdfTeX 1.50 or +(etexcmds) that some package has redefined \expanded. +(etexcmds) In the latter case, load this package earlier. +Package: kvsetkeys 2012/04/25 v1.16 Key value parser (HO) +Package: kvdefinekeys 2011/04/07 v1.3 Define keys (HO) +Package: pdftexcmds 2011/11/29 v0.20 Utility functions of pdfTeX for LuaTeX (HO +) +Package pdftexcmds Info: LuaTeX not detected. +Package pdftexcmds Info: \pdf@primitive is available. +Package pdftexcmds Info: \pdf@ifprimitive is available. +Package pdftexcmds Info: \pdfdraftmode found. +Package: pdfescape 2011/11/25 v1.13 Implements pdfTeX's escape features (HO) +Package: bigintcalc 2012/04/08 v1.3 Expandable calculations on big integers (HO +) +Package: bitset 2011/01/30 v1.1 Handle bit-vector datatype (HO) +Package: uniquecounter 2011/01/30 v1.2 Provide unlimited unique counter (HO) +) +Package hobsub Info: Skipping package `hobsub' (already loaded). +Package: letltxmacro 2010/09/02 v1.4 Let assignment for LaTeX macros (HO) +Package: hopatch 2012/05/28 v1.2 Wrapper for package hooks (HO) +Package: xcolor-patch 2011/01/30 xcolor patch +Package: atveryend 2011/06/30 v1.8 Hooks at the very end of document (HO) +Package atveryend Info: \enddocument detected (standard20110627). +Package: atbegshi 2011/10/05 v1.16 At begin shipout hook (HO) +Package: refcount 2011/10/16 v3.4 Data extraction from label references (HO) +Package: hycolor 2011/01/30 v1.7 Color options for hyperref/bookmark (HO) +) +(/usr/share/texlive/texmf-dist/tex/generic/ifxetex/ifxetex.sty +Package: ifxetex 2010/09/12 v0.6 Provides ifxetex conditional +) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/auxhook.sty +Package: auxhook 2011/03/04 v1.3 Hooks for auxiliary files (HO) +) +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/kvoptions.sty +Package: kvoptions 2011/06/30 v3.11 Key value format for package options (HO) +) +\@linkdim=\dimen110 +\Hy@linkcounter=\count98 +\Hy@pagecounter=\count99 + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/pd1enc.def +File: pd1enc.def 2012/11/06 v6.83m Hyperref: PDFDocEncoding definition (HO) +) +\Hy@SavedSpaceFactor=\count100 + +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/hyperref.cfg +File: hyperref.cfg 2002/06/06 v1.2 hyperref configuration of TeXLive +) +Package hyperref Info: Option `colorlinks' set `true' on input line 4319. +Package hyperref Info: Option `linktocpage' set `true' on input line 4319. +Package hyperref Info: Hyper figures OFF on input line 4443. +Package hyperref Info: Link nesting OFF on input line 4448. +Package hyperref Info: Hyper index ON on input line 4451. +Package hyperref Info: Plain pages OFF on input line 4458. +Package hyperref Info: Backreferencing OFF on input line 4463. +Package hyperref Info: Implicit mode ON; LaTeX internals redefined. +Package hyperref Info: Bookmarks ON on input line 4688. +\c@Hy@tempcnt=\count101 +LaTeX Info: Redefining \url on input line 5041. +\XeTeXLinkMargin=\dimen111 +\Fld@menulength=\count102 +\Field@Width=\dimen112 +\Fld@charsize=\dimen113 +Package hyperref Info: Hyper figures OFF on input line 6295. +Package hyperref Info: Link nesting OFF on input line 6300. +Package hyperref Info: Hyper index ON on input line 6303. +Package hyperref Info: backreferencing OFF on input line 6310. +Package hyperref Info: Link coloring ON on input line 6313. +Package hyperref Info: Link coloring with OCG OFF on input line 6320. +Package hyperref Info: PDF/A mode OFF on input line 6325. +LaTeX Info: Redefining \ref on input line 6365. +LaTeX Info: Redefining \pageref on input line 6369. +\Hy@abspage=\count103 +\c@Item=\count104 +\c@Hfootnote=\count105 +) + +Package hyperref Message: Driver (autodetected): hpdftex. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/hpdftex.def +File: hpdftex.def 2012/11/06 v6.83m Hyperref driver for pdfTeX +\Fld@listcount=\count106 +\c@bookmark@seq@number=\count107 + +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/rerunfilecheck.sty +Package: rerunfilecheck 2011/04/15 v1.7 Rerun checks for auxiliary files (HO) +Package uniquecounter Info: New unique counter `rerunfilecheck' on input line 2 +82. +) +\Hy@SectionHShift=\skip52 +) +(/usr/share/texlive/texmf-dist/tex/latex/listings/lstlang1.sty +File: lstlang1.sty 2014/03/04 1.5c listings language file +) (./thesis.aux +(./1_introduction.aux) (./2_actioninvokesentmoney.aux) +(./3_actioninvokedistributedcommitedtransfer.aux) +(./4_actionpreparedistributedcommitedtransfer.aux) +(./5_actionpreparedistributedcommitedtransferanswer.aux) +(./6_actioncommitdistributedcommitedtransfer.aux) (./7_actionupdatequeue.aux)) +\openout1 = `thesis.aux'. + +LaTeX Font Info: Checking defaults for OML/cmm/m/it on input line 62. +LaTeX Font Info: ... okay on input line 62. +LaTeX Font Info: Checking defaults for T1/cmr/m/n on input line 62. +LaTeX Font Info: ... okay on input line 62. +LaTeX Font Info: Checking defaults for OT1/cmr/m/n on input line 62. +LaTeX Font Info: ... okay on input line 62. +LaTeX Font Info: Checking defaults for OMS/cmsy/m/n on input line 62. +LaTeX Font Info: ... okay on input line 62. +LaTeX Font Info: Checking defaults for OMX/cmex/m/n on input line 62. +LaTeX Font Info: ... okay on input line 62. +LaTeX Font Info: Checking defaults for U/cmr/m/n on input line 62. +LaTeX Font Info: ... okay on input line 62. +LaTeX Font Info: Checking defaults for PD1/pdf/m/n on input line 62. +LaTeX Font Info: ... okay on input line 62. + +(/usr/share/texlive/texmf-dist/tex/context/base/supp-pdf.mkii +[Loading MPS to PDF converter (version 2006.09.02).] +\scratchcounter=\count108 +\scratchdimen=\dimen114 +\scratchbox=\box28 +\nofMPsegments=\count109 +\nofMParguments=\count110 +\everyMPshowfont=\toks18 +\MPscratchCnt=\count111 +\MPscratchDim=\dimen115 +\MPnumerator=\count112 +\makeMPintoPDFobject=\count113 +\everyMPtoPDFconversion=\toks19 +) +\c@lstlisting=\count114 + (/usr/share/texlive/texmf-dist/tex/latex/oberdiek/epstopdf-base.sty +Package: epstopdf-base 2010/02/09 v2.5 Base part for package epstopdf + +(/usr/share/texlive/texmf-dist/tex/latex/oberdiek/grfext.sty +Package: grfext 2010/08/19 v1.1 Manage graphics extensions (HO) +) +Package grfext Info: Graphics extension search list: +(grfext) [.png,.pdf,.jpg,.mps,.jpeg,.jbig2,.jb2,.PNG,.PDF,.JPG,.JPE +G,.JBIG2,.JB2,.eps] +(grfext) \AppendGraphicsExtensions on input line 452. + +(/usr/share/texlive/texmf-dist/tex/latex/latexconfig/epstopdf-sys.cfg +File: epstopdf-sys.cfg 2010/07/13 v1.3 Configuration of (r)epstopdf for TeX Liv +e +)) +\AtBeginShipoutBox=\box29 +Package hyperref Info: Link coloring ON on input line 62. + +(/usr/share/texlive/texmf-dist/tex/latex/hyperref/nameref.sty +Package: nameref 2012/10/27 v2.43 Cross-referencing by name of section + +(/usr/share/texlive/texmf-dist/tex/generic/oberdiek/gettitlestring.sty +Package: gettitlestring 2010/12/03 v1.4 Cleanup title references (HO) +) +\c@section@level=\count115 +LaTeX Info: Redefining \Ref on input line 513. +) +LaTeX Info: Redefining \ref on input line 62. +LaTeX Info: Redefining \pageref on input line 62. +LaTeX Info: Redefining \nameref on input line 62. + +(./thesis.out) (./thesis.out) +\@outlinefile=\write3 +\openout3 = `thesis.out'. + +LaTeX Info: Redefining \Ref on input line 62. + +<pictures/logo.pdf, id=32, 199.19118pt x 52.728pt> +File: pictures/logo.pdf Graphic file (type pdf) + <use pictures/logo.pdf> +Package pdftex.def Info: pictures/logo.pdf used on input line 68. +(pdftex.def) Requested size: 216.0022pt x 57.17868pt. +LaTeX Font Info: External font `cmex10' loaded for size +(Font) <12> on input line 68. +LaTeX Font Info: External font `cmex10' loaded for size +(Font) <8> on input line 68. +LaTeX Font Info: External font `cmex10' loaded for size +(Font) <6> on input line 68. + +[1 + +{/usr/share/texlive/texmf-dist/fonts/map/pdftex/updmap/pdftex.map} <./pictures/ +logo.pdf>] (./thesis.toc) +\tf@toc=\write4 +\openout4 = `thesis.toc'. + + [1 + +] +\openout2 = `1_introduction.aux'. + + (./1_introduction.tex +<pictures/TimelineCorrectTransfer.pdf, id=61, 948.54375pt x 553.06625pt> +File: pictures/TimelineCorrectTransfer.pdf Graphic file (type pdf) + +<use pictures/TimelineCorrectTransfer.pdf> +Package pdftex.def Info: pictures/TimelineCorrectTransfer.pdf used on input lin +e 18. +(pdftex.def) Requested size: 360.0pt x 209.90575pt. +) +Underfull \hbox (badness 10000) in paragraph at lines 2--92 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 2--92 + + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 2--92 + + [] + +[1 + + + <./pictures/TimelineCorrectTransfer.pdf>] +\openout2 = `2_actioninvokesentmoney.aux'. + + (./2_actioninvokesentmoney.tex +Underfull \hbox (badness 10000) in paragraph at lines 2--9 + + [] + +LaTeX Font Info: Try loading font information for T1+aett on input line 9. +(/usr/share/texlive/texmf-dist/tex/latex/ae/t1aett.fd +File: t1aett.fd 1997/11/16 Font definitions for T1/aett. +)) [2 + + +] +\openout2 = `3_actioninvokedistributedcommitedtransfer.aux'. + + +(./3_actioninvokedistributedcommitedtransfer.tex +Underfull \hbox (badness 10000) in paragraph at lines 2--10 + + [] + +) [3 + + +] +\openout2 = `4_actionpreparedistributedcommitedtransfer.aux'. + + (./4_actionpreparedistributedcommitedtransfer.tex +Underfull \hbox (badness 10000) in paragraph at lines 2--7 + + [] + +LaTeX Font Info: Try loading font information for T1+aess on input line 10. +(/usr/share/texlive/texmf-dist/tex/latex/ae/t1aess.fd +File: t1aess.fd 1997/11/16 Font definitions for T1/aess. +)) [4 + + +] +\openout2 = `5_actionpreparedistributedcommitedtransferanswer.aux'. + + +(./5_actionpreparedistributedcommitedtransferanswer.tex +Overfull \hbox (34.36821pt too wide) in paragraph at lines 1--1 +[]\T1/aer/bx/n/14.4 ActionPrepareDistributedCommitedTransferAnswer + [] + + +Underfull \hbox (badness 10000) in paragraph at lines 2--10 + + [] + +) [5 + + +] +\openout2 = `6_actioncommitdistributedcommitedtransfer.aux'. + + (./6_actioncommitdistributedcommitedtransfer.tex +Underfull \hbox (badness 10000) in paragraph at lines 2--6 + + [] + +) [6 + + +] +\openout2 = `7_actionupdatequeue.aux'. + + (./7_actionupdatequeue.tex +Underfull \hbox (badness 10000) in paragraph at lines 2--6 + + [] + +) [7 + + +] +Package atveryend Info: Empty hook `BeforeClearDocument' on input line 103. +Package atveryend Info: Empty hook `AfterLastShipout' on input line 103. + (./thesis.aux (./1_introduction.aux) (./2_actioninvokesentmoney.aux) +(./3_actioninvokedistributedcommitedtransfer.aux) +(./4_actionpreparedistributedcommitedtransfer.aux) +(./5_actionpreparedistributedcommitedtransferanswer.aux) +(./6_actioncommitdistributedcommitedtransfer.aux) (./7_actionupdatequeue.aux)) +Package atveryend Info: Executing hook `AtVeryEndDocument' on input line 103. +Package atveryend Info: Executing hook `AtEndAfterFileList' on input line 103. +Package rerunfilecheck Info: File `thesis.out' has not changed. +(rerunfilecheck) Checksum: 1F90E0823F2BF6B7E4CF0DA52FBCF96B;459. +Package atveryend Info: Empty hook `AtVeryVeryEnd' on input line 103. + ) +Here is how much of TeX's memory you used: + 8570 strings out of 495025 + 121962 string characters out of 6181515 + 314442 words of memory out of 5000000 + 11460 multiletter control sequences out of 15000+600000 + 39139 words of font info for 80 fonts, out of 8000000 for 9000 + 14 hyphenation exceptions out of 8191 + 29i,11n,43p,309b,1334s stack positions out of 5000i,500n,10000p,200000b,80000s +</usr/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx10.pfb></us +r/share/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx12.pfb></usr/shar +e/texlive/texmf-dist/fonts/type1/public/amsfonts/cm/cmbx6.pfb></usr/share/texli +ve/texmf-dist/fonts/type1/public/amsfonts/cm/cmmi10.pfb></usr/share/texlive/tex +mf-dist/fonts/type1/public/amsfonts/cm/cmr10.pfb></usr/share/texlive/texmf-dist +/fonts/type1/public/amsfonts/cm/cmr12.pfb></usr/share/texlive/texmf-dist/fonts/ +type1/public/amsfonts/cm/cmr17.pfb></usr/share/texlive/texmf-dist/fonts/type1/p +ublic/amsfonts/cm/cmsl10.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/ +amsfonts/cm/cmss8.pfb></usr/share/texlive/texmf-dist/fonts/type1/public/amsfont +s/cm/cmtt8.pfb> +Output written on thesis.pdf (9 pages, 301120 bytes). +PDF statistics: + 270 PDF objects out of 1000 (max. 8388607) + 243 compressed objects within 3 object streams + 127 named destinations out of 1000 (max. 500000) + 67 words of extra memory for PDF output out of 10000 (max. 10000000) + diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.out b/JavaAkkaFuCoin/thesis_latex_template/thesis.out new file mode 100644 index 0000000000000000000000000000000000000000..70e2555bcb8bcdb51afb380af6207f7a16baf349 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/thesis.out @@ -0,0 +1,7 @@ +\BOOKMARK [1][-]{section.1}{Introduction}{}% 1 +\BOOKMARK [1][-]{section.2}{ActionInvokeSentMoney}{}% 2 +\BOOKMARK [1][-]{section.3}{ActionInvokeDistributedCommitedTransfer}{}% 3 +\BOOKMARK [1][-]{section.4}{ActionPrepareDistributedCommitedTransfer}{}% 4 +\BOOKMARK [1][-]{section.5}{ActionPrepareDistributedCommitedTransferAnswer}{}% 5 +\BOOKMARK [1][-]{section.6}{ActionCommitDistributedCommitedTransfer}{}% 6 +\BOOKMARK [1][-]{section.7}{ActionUpdateQueue}{}% 7 diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.pdf b/JavaAkkaFuCoin/thesis_latex_template/thesis.pdf new file mode 100644 index 0000000000000000000000000000000000000000..7b712167fe7c75da93f488d8fcb4d25ca720861d Binary files /dev/null and b/JavaAkkaFuCoin/thesis_latex_template/thesis.pdf differ diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.tex b/JavaAkkaFuCoin/thesis_latex_template/thesis.tex new file mode 100644 index 0000000000000000000000000000000000000000..244c202d9f9f07ee0f47fcb09d9d92571c0fdf73 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/thesis.tex @@ -0,0 +1,103 @@ +%\documentclass[11pt,a4paper,ngerman]{article} +\documentclass[11pt,a4paper,english]{article} +\usepackage[T1]{fontenc} +\usepackage[latin1]{inputenc} +\usepackage{babel} +\usepackage{ae} +% +\usepackage{fancyref} +\usepackage{fancyhdr} +\usepackage{xcolor} +\usepackage{url} +\usepackage{makeidx} +\usepackage{listings} +% +% PDF settings +\usepackage[pdftex]{graphicx} +\usepackage[pdfstartview=FitH,pdftitle={Distributed Commit},pdfauthor={Kmoch; Lewash}, colorlinks=true, linktocpage]{hyperref} +% colorlinks=false, pdfborder={0 0 0} = keine farbigen Links +% +% Header and Footer Style +\pagestyle{fancy} +\fancyhead{} +\fancyhead[R]{\slshape Kmoch; Lewash} +\fancyhead[L]{\slshape\nouppercase{\rightmark}} +\fancyfoot{} +\fancyfoot[C]{\thepage} +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} +% +% No identation +\setlength\headheight{15pt} +\setlength\parindent{0pt} +% +% Custom commands +\newcommand\zb{z.\,B.\ } +\renewcommand\dh{d.\,h.\ } +\newcommand\parbig{\par\bigskip} +\newcommand\parmed{\par\medskip} +\newcommand{\mailto}[1]{\href{mailto:#1}{#1}} +% +% Java Code Listing Style +\definecolor{darkblue}{rgb}{0,0,.6} +\definecolor{darkgreen}{rgb}{0,0.5,0} +\definecolor{darkred}{rgb}{0.5,0,0} +\lstset{language=Java, basicstyle=\ttfamily\tiny\upshape, commentstyle=\color{darkgreen}\sffamily, keywordstyle=\color{darkblue}\rmfamily\bfseries, breaklines=true,tabsize=2,xleftmargin=3mm, xrightmargin=3mm,numbers=none,frame=single,stringstyle=\color{darkred}, +showstringspaces=false} +% +% Titel and author +\title{\includegraphics[width=0.6\textwidth]{pictures/logo}\\ +{\normalsize Seminararbeit am Institut für Informatik der Freien Universität Berlin, Arbeitsgruppe Technische Informatik}\\[6ex] +Two-Phase Commit for FUCoin} + +\author{Michael Kmoch, Yuri Lewash\\ +{\normalsize Matrikelnummer: 4289388, 4293181 }\\ +{\normalsize \mailto{michael.kmoch@inf.fu-berlin.de}, \mailto{yuri.lewash@inf.fu-berlin.de}}\\\\ +{\normalsize Betreuer: Simon Schmitt}\\ +{\normalsize Eingereicht bei: Katinka Wolter}} + +\date{Berlin, 24.07.2015} + + +\begin{document} + +\begin{titlepage} + +\pagenumbering{alph} +\maketitle +\thispagestyle{empty} + +\vfill{} + +\begin{abstract} +In distributed systems a commit is needed to make changes in the network +permanent and visible to other participants. +The two-phase commit protocol includes a voting phase and a decision +phase to coordinate processes participating in a atomic transaction. We +implement a variant of this protocol for the FUCoins system. +\end{abstract} + +\vfill{} + +\end{titlepage} + +\pagestyle{empty} +\clearpage\pagenumbering{roman} + +\tableofcontents + +\clearpage\pagenumbering{arabic} +\pagestyle{fancy} +\setcounter{page}{1} +\include{1_introduction} +\include{2_actioninvokesentmoney} +\include{3_actioninvokedistributedcommitedtransfer} +\include{4_actionpreparedistributedcommitedtransfer} +\include{5_actionpreparedistributedcommitedtransferanswer} +\include{6_actioncommitdistributedcommitedtransfer} +\include{7_actionupdatequeue} + +%\bibliographystyle{alpha} +%\bibliography{bibliography} + +\end{document} diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.tex~ b/JavaAkkaFuCoin/thesis_latex_template/thesis.tex~ new file mode 100644 index 0000000000000000000000000000000000000000..276a9c01e8bcaa42736d303a6607ef3436cae535 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/thesis.tex~ @@ -0,0 +1,98 @@ +\documentclass[11pt,a4paper,ngerman]{article} +\usepackage[T1]{fontenc} +\usepackage[latin1]{inputenc} +\usepackage{babel} +\usepackage{ae} +% +\usepackage{fancyref} +\usepackage{fancyhdr} +\usepackage{xcolor} +\usepackage{url} +\usepackage{makeidx} +\usepackage{listings} +% +% PDF settings +\usepackage[pdftex]{graphicx} +\usepackage[pdfstartview=FitH,pdftitle={<Titel>},pdfauthor={<Name>}, colorlinks=true, linktocpage]{hyperref} +% colorlinks=false, pdfborder={0 0 0} = keine farbigen Links +% +% Header and Footer Style +\pagestyle{fancy} +\fancyhead{} +\fancyhead[R]{\slshape <Name>} +\fancyhead[L]{\slshape\nouppercase{\rightmark}} +\fancyfoot{} +\fancyfoot[C]{\thepage} +\renewcommand{\headrulewidth}{0pt} +\renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}} +% +% No identation +\setlength\headheight{15pt} +\setlength\parindent{0pt} +% +% Custom commands +\newcommand\zb{z.\,B.\ } +\renewcommand\dh{d.\,h.\ } +\newcommand\parbig{\par\bigskip} +\newcommand\parmed{\par\medskip} +\newcommand{\mailto}[1]{\href{mailto:#1}{#1}} +% +% Java Code Listing Style +\definecolor{darkblue}{rgb}{0,0,.6} +\definecolor{darkgreen}{rgb}{0,0.5,0} +\definecolor{darkred}{rgb}{0.5,0,0} +\lstset{language=Java, basicstyle=\ttfamily\small\upshape, commentstyle=\color{darkgreen}\sffamily, keywordstyle=\color{darkblue}\rmfamily\bfseries, breaklines=true,tabsize=2,xleftmargin=3mm, xrightmargin=3mm,numbers=none,frame=single,stringstyle=\color{darkred}, +showstringspaces=false} +% +% Titel and author +\title{\includegraphics[width=0.6\textwidth]{pictures/logo}\\ +{\normalsize <X-Arbeit> am Institut für Informatik der Freien Universität Berlin, Arbeitsgruppe Software Engineering}\\[6ex] +<Titel>} + +\author{<Name>\\ +{\normalsize Matrikelnummer: }\\ +{\normalsize \mailto{example@mail.de}}\\\\ +{\normalsize Betreuer: }\\ +{\normalsize Eingereicht bei: }} + +\date{Berlin, <Datum>} + + +\begin{document} + +\begin{titlepage} + +\pagenumbering{alph} +\maketitle +\thispagestyle{empty} + +\vfill{} + +\begin{abstract} +Abstract +\end{abstract} + +\vfill{} + +\end{titlepage} + +\pagestyle{empty} +\clearpage\pagenumbering{roman} + +\include{declaration} + +\tableofcontents + +\clearpage\pagenumbering{arabic} +\pagestyle{fancy} +\setcounter{page}{1} +\include{1_introduction} +\include{2_fundamentals} +\include{3_main} +\include{4_conclusion} +\include{5_appendix} + +\bibliographystyle{alpha} +\bibliography{bibliography} + +\end{document} diff --git a/JavaAkkaFuCoin/thesis_latex_template/thesis.toc b/JavaAkkaFuCoin/thesis_latex_template/thesis.toc new file mode 100644 index 0000000000000000000000000000000000000000..c65c343b839c7c59d1980da04ff7a23b1cf2c591 --- /dev/null +++ b/JavaAkkaFuCoin/thesis_latex_template/thesis.toc @@ -0,0 +1,10 @@ +\select@language {english} +\select@language {english} +\select@language {english} +\contentsline {section}{\numberline {1}Introduction}{1}{section.1} +\contentsline {section}{\numberline {2}ActionInvokeSentMoney}{2}{section.2} +\contentsline {section}{\numberline {3}ActionInvokeDistributedCommitedTransfer}{3}{section.3} +\contentsline {section}{\numberline {4}ActionPrepareDistributedCommitedTransfer}{4}{section.4} +\contentsline {section}{\numberline {5}ActionPrepareDistributedCommitedTransferAnswer}{5}{section.5} +\contentsline {section}{\numberline {6}ActionCommitDistributedCommitedTransfer}{6}{section.6} +\contentsline {section}{\numberline {7}ActionUpdateQueue}{7}{section.7}