From 616d65d32a53bd17789957f064461221791ad639 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Tue, 25 Sep 2007 14:04:01 +0000 Subject: [PATCH] Merging r327:r331 of the branches/processing-sync into the trunk. This adds the Processing core, and some new features including printing, copy for discourse, better auto-format, improved keyboard shortcuts, etc. --- app/Base.java | 533 +- app/Editor.java | 415 +- app/EditorHeader.java | 42 + app/EditorListener.java | 131 +- app/FindReplace.java | 48 +- app/Library.java | 4 +- app/Preferences.java | 40 +- app/Runner.java | 5 +- app/Sketch.java | 257 +- app/Sketchbook.java | 131 +- app/preproc/PdePreprocessor.java | 38 +- app/syntax/InputHandler.java | 58 +- app/syntax/JEditTextArea.java | 77 +- app/syntax/KeywordMap.java | 2 +- app/syntax/PdeKeywords.java | 2 +- app/syntax/PdeTextAreaDefaults.java | 66 +- app/syntax/TextAreaPainter.java | 35 +- app/tools/Archiver.java | 23 +- app/tools/AutoFormat.java | 21 +- app/tools/DiscourseFormat.java | 313 + app/tools/ExportFolder.java | 2 + .../macosx/Arduino.xcodeproj/project.pbxproj | 74 + build/macosx/dist/libquaqua.jnilib | Bin 0 -> 30848 bytes build/macosx/dist/quaqua.jar | Bin 0 -> 1135692 bytes .../dist/examples/Digital/Loop/Loop.pde | 4 +- build/windows/dist/avr_tools.zip | Bin 22629388 -> 22525538 bytes build/windows/make.sh | 4 +- core/PApplet.java | 8334 +++++++++++++++++ core/PConstants.java | 322 + core/PFont.java | 1019 ++ core/PGraphics.java | 4308 +++++++++ core/PGraphics2D.java | 1672 ++++ core/PGraphics3D.java | 3943 ++++++++ core/PGraphicsJava2D.java | 1381 +++ core/PImage.java | 2598 +++++ core/PLine.java | 1295 +++ core/PMatrix.java | 640 ++ core/PPolygon.java | 772 ++ core/PShape.java | 289 + core/PTriangle.java | 3827 ++++++++ 40 files changed, 31946 insertions(+), 779 deletions(-) create mode 100644 app/tools/DiscourseFormat.java create mode 100755 build/macosx/dist/libquaqua.jnilib create mode 100755 build/macosx/dist/quaqua.jar create mode 100644 core/PApplet.java create mode 100644 core/PConstants.java create mode 100644 core/PFont.java create mode 100644 core/PGraphics.java create mode 100644 core/PGraphics2D.java create mode 100644 core/PGraphics3D.java create mode 100644 core/PGraphicsJava2D.java create mode 100644 core/PImage.java create mode 100644 core/PLine.java create mode 100644 core/PMatrix.java create mode 100644 core/PPolygon.java create mode 100644 core/PShape.java create mode 100644 core/PTriangle.java diff --git a/app/Base.java b/app/Base.java index 2bee7b3d9..4b8e6e016 100644 --- a/app/Base.java +++ b/app/Base.java @@ -42,6 +42,7 @@ import javax.swing.undo.*; import com.apple.mrj.*; import com.ice.jni.registry.*; +import processing.core.*; /** @@ -52,21 +53,8 @@ import com.ice.jni.registry.*; * files and images, etc) that comes from that. */ public class Base { - static final int VERSION = 3; + static final int VERSION = 10; static final String VERSION_NAME = "0010 Alpha"; - - // platform IDs for PApplet.platform - - static final int WINDOWS = 1; - static final int MACOS9 = 2; - static final int MACOSX = 3; - static final int LINUX = 4; - static final int OTHER = 0; - - // used by split, all the standard whitespace chars - // (uncludes unicode nbsp, that little bostage) - - static final String WHITESPACE = " \t\n\r\f\u00A0"; /** * Path of filename opened on the command line, @@ -76,79 +64,18 @@ public class Base { Editor editor; - /** - * "1.3" or "1.1" or whatever (just the first three chars) - */ - public static final String javaVersionName = - System.getProperty("java.version").substring(0,3); - - /** - * Version of Java that's in use, whether 1.1 or 1.3 or whatever, - * stored as a float. - *

- * Note that because this is stored as a float, the values may - * not be exactly 1.3 or 1.4. Instead, make sure you're - * comparing against 1.3f or 1.4f, which will have the same amount - * of error (i.e. 1.40000001). This could just be a double, but - * since Processing only uses floats, it's safer to do this, - * because there's no good way to specify a double with the preproc. - */ - public static final float javaVersion = - new Float(javaVersionName).floatValue(); - - /** - * Current platform in use, one of the - * PConstants WINDOWS, MACOSX, MACOS9, LINUX or OTHER. - */ - static public int platform; - - /** - * Current platform in use. - *

- * Equivalent to System.getProperty("os.name"), just used internally. - */ - static public String platformName = - System.getProperty("os.name"); - - static { - // figure out which operating system - // this has to be first, since editor needs to know - - if (platformName.toLowerCase().indexOf("mac") != -1) { - // can only check this property if running on a mac - // on a pc it throws a security exception and kills the applet - // (but on the mac it does just fine) - if (System.getProperty("mrj.version") != null) { // running on a mac - platform = (platformName.equals("Mac OS X")) ? - MACOSX : MACOS9; - } - - } else { - String osname = System.getProperty("os.name"); - - if (osname.indexOf("Windows") != -1) { - platform = WINDOWS; - - } else if (osname.equals("Linux")) { // true for the ibm vm - platform = LINUX; - - } else { - platform = OTHER; - } - } - } static public void main(String args[]) { // make sure that this is running on java 1.4 - //if (PApplet.javaVersion < 1.4f) { + if (PApplet.javaVersion < 1.4f) { //System.err.println("no way man"); - // Base.showError("Need to install Java 1.4", - // "This version of Arduino requires \n" + - // "Java 1.4 or later to run properly.\n" + - // "Please visit java.com to upgrade.", null); - // } + Base.showError("Need to install Java 1.4", + "This version of Processing requires \n" + + "Java 1.4 or later to run properly.\n" + + "Please visit java.com to upgrade.", null); + } // grab any opened file from the command line @@ -183,14 +110,34 @@ public class Base { // set the look and feel before opening the window try { - if (Base.isLinux()) { - // linux is by default (motif?) even uglier than metal - // actually, i'm using native menus, so they're ugly and - // motif-looking. ick. need to fix this. - UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); + if (Base.isMacOS()) { + // Use the Quaqua L & F on OS X to make JFileChooser less awful + UIManager.setLookAndFeel("ch.randelshofer.quaqua.QuaquaLookAndFeel"); + // undo quaqua trying to fix the margins, since we've already + // hacked that in, bit by bit, over the years + UIManager.put("Component.visualMargin", new Insets(1, 1, 1, 1)); + + } else if (Base.isLinux()) { + // Linux is by default even uglier than metal (Motif?). + // Actually, i'm using native menus, so they're even uglier + // and Motif-looking (Lesstif?). Ick. Need to fix this. + //String lfname = UIManager.getCrossPlatformLookAndFeelClassName(); + //UIManager.setLookAndFeel(lfname); + + // For 0120, trying out the gtk+ look and feel as the default. + // This is available in Java 1.4.2 and later, and it can't possibly + // be any worse than Metal. (Ocean might also work, but that's for + // Java 1.5, and we aren't going there yet) + UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); + } else { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } + //} catch (ClassNotFoundException cnfe) { + // just default to the native look and feel for this platform + // i.e. appears that some linux systems don't have the gtk l&f + //UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { e.printStackTrace(); } @@ -228,7 +175,7 @@ public class Base { * specifically a Mac OS X machine because it doesn't un on OS 9 anymore. */ static public boolean isMacOS() { - return platform == MACOSX; + return PApplet.platform == PConstants.MACOSX; } @@ -236,7 +183,7 @@ public class Base { * returns true if running on windows. */ static public boolean isWindows() { - return platform == WINDOWS; + return PApplet.platform == PConstants.WINDOWS; } @@ -244,7 +191,7 @@ public class Base { * true if running on linux. */ static public boolean isLinux() { - return platform == LINUX; + return PApplet.platform == PConstants.LINUX; } @@ -472,8 +419,9 @@ public class Base { sketchbookFolder = new File(documentsFolder, "Arduino"); } catch (Exception e) { - showError("sketch folder problem", - "Could not locate default sketch folder location.", e); + //showError("Could not find folder", + // "Could not locate the Documents folder.", e); + sketchbookFolder = promptSketchbookLocation(); } } else if (isWindows()) { @@ -502,11 +450,15 @@ public class Base { sketchbookFolder = new File(personalPath, "Arduino"); } catch (Exception e) { - showError("Problem getting documents folder", - "Error getting the Arduino sketchbook folder.", e); + //showError("Problem getting folder", + // "Could not locate the Documents folder.", e); + sketchbookFolder = promptSketchbookLocation(); } } else { + sketchbookFolder = promptSketchbookLocation(); + + /* // on linux (or elsewhere?) prompt the user for the location JFileChooser fc = new JFileChooser(); fc.setDialogTitle("Select the folder where " + @@ -523,6 +475,7 @@ public class Base { } else { System.exit(0); } + */ } // create the folder if it doesn't exist already @@ -551,6 +504,68 @@ public class Base { } + /** + * Check for a new sketchbook location. + */ + static protected File promptSketchbookLocation() { + File folder = null; + + folder = new File(System.getProperty("user.home"), "sketchbook"); + if (!folder.exists()) { + folder.mkdirs(); + return folder; + } + + folder = Base.selectFolder("Select (or create new) folder for sketches...", + null, null); + if (folder == null) { + System.exit(0); + } + return folder; + } + + + /** + * Implementation for choosing directories that handles both the + * Mac OS X hack to allow the native AWT file dialog, or uses + * the JFileChooser on other platforms. Mac AWT trick obtained from + * this post + * on the OS X Java dev archive which explains the cryptic note in + * Apple's Java 1.4 release docs about the special System property. + */ + static public File selectFolder(String prompt, File folder, Frame frame) { + if (Base.isMacOS()) { + if (frame == null) frame = new Frame(); //.pack(); + FileDialog fd = new FileDialog(frame, prompt, FileDialog.LOAD); + if (folder != null) { + fd.setDirectory(folder.getParent()); + //fd.setFile(folder.getName()); + } + System.setProperty("apple.awt.fileDialogForDirectories", "true"); + fd.show(); + System.setProperty("apple.awt.fileDialogForDirectories", "false"); + if (fd.getFile() == null) { + return null; + } + return new File(fd.getDirectory(), fd.getFile()); + + } else { + JFileChooser fc = new JFileChooser(); + fc.setDialogTitle(prompt); + if (folder != null) { + fc.setSelectedFile(folder); + } + fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + + int returned = fc.showOpenDialog(new JDialog()); + if (returned == JFileChooser.APPROVE_OPTION) { + return fc.getSelectedFile(); + } + } + return null; + } + + static public String cleanKey(String what) { // jnireg seems to be reading the chars as bytes // so maybe be as simple as & 0xff and then running through decoder @@ -631,20 +646,44 @@ public class Base { // ................................................................. - /** - * Given the reference filename from the keywords list, - * builds a URL and passes it to openURL. - */ static public void showReference(String referenceFile) { - String currentDir = System.getProperty("user.dir"); - openURL(currentDir + File.separator + - "reference" + File.separator + - referenceFile + ".html"); + openURL(Base.getContents("reference" + File.separator + referenceFile)); + } + + + static public void showReference() { + showReference("index.html"); + } + + + static public void showEnvironment() { + showReference("Guide_Environment.html"); + } + + + static public void showTroubleshooting() { + showReference("Guide_Troubleshooting.html"); } + /** + * Opens the local copy of the FAQ that's included + * with the Processing download. + */ + static public void showFAQ() { + showReference("faq.html"); + } + + + // ................................................................. + + /** * Implements the cross-platform headache of opening URLs + * TODO This code should be replaced by PApplet.link(), + * however that's not a static method (because it requires + * an AppletContext when used as an applet), so it's mildly + * trickier than just removing this method. */ static public void openURL(String url) { //System.out.println("opening url " + url); @@ -707,11 +746,19 @@ public class Base { } else if (Base.isLinux()) { // how's mozilla sound to ya, laddie? //Runtime.getRuntime().exec(new String[] { "mozilla", url }); - String browser = Preferences.get("browser"); - Runtime.getRuntime().exec(new String[] { browser, url }); - + //String browser = Preferences.get("browser"); + //Runtime.getRuntime().exec(new String[] { browser, url }); + String launcher = Preferences.get("launcher.linux"); + if (launcher != null) { + Runtime.getRuntime().exec(new String[] { launcher, url }); + } } else { - System.err.println("unspecified platform"); + String launcher = Preferences.get("launcher"); + if (launcher != null) { + Runtime.getRuntime().exec(new String[] { launcher, url }); + } else { + System.err.println("Unspecified platform, no launcher available."); + } } } catch (IOException e) { @@ -721,6 +768,36 @@ public class Base { } + static boolean openFolderAvailable() { + if (Base.isWindows() || Base.isMacOS()) return true; + + if (Base.isLinux()) { + // Assume that this is set to something valid + if (Preferences.get("launcher.linux") != null) { + return true; + } + + // Attempt to use gnome-open + try { + Process p = Runtime.getRuntime().exec(new String[] { "gnome-open" }); + int result = p.waitFor(); + // Not installed will throw an IOException (JDK 1.4.2, Ubuntu 7.04) + Preferences.set("launcher.linux", "gnome-open"); + return true; + } catch (Exception e) { } + + // Attempt with kde-open + try { + Process p = Runtime.getRuntime().exec(new String[] { "kde-open" }); + int result = p.waitFor(); + Preferences.set("launcher.linux", "kde-open"); + return true; + } catch (Exception e) { } + } + return false; + } + + /** * Implements the other cross-platform headache of opening * a folder in the machine's native file browser. @@ -742,6 +819,11 @@ public class Base { } else if (Base.isMacOS()) { openURL(folder); // handles char replacement, etc + } else if (Base.isLinux()) { + String launcher = Preferences.get("launcher.linux"); + if (launcher != null) { + Runtime.getRuntime().exec(new String[] { launcher, folder }); + } } } catch (IOException e) { e.printStackTrace(); @@ -780,7 +862,7 @@ public class Base { * for errors that allow P5 to continue running. */ static public void showError(String title, String message, - Exception e) { + Throwable e) { if (title == null) title = "Error"; JOptionPane.showMessageDialog(new Frame(), message, title, JOptionPane.ERROR_MESSAGE); @@ -793,23 +875,29 @@ public class Base { // ................................................................... + static public String getContents(String what) { + String basePath = System.getProperty("user.dir"); + /* + // do this later, when moving to .app package + if (PApplet.platform == PConstants.MACOSX) { + basePath = System.getProperty("processing.contents"); + } + */ + return basePath + File.separator + what; + } + + + static public String getLibContents(String what) { + return getContents("lib" + File.separator + what); + } + + static public Image getImage(String name, Component who) { Image image = null; Toolkit tk = Toolkit.getDefaultToolkit(); - //if ((Base.platform == Base.MACOSX) || - //(Base.platform == Base.MACOS9)) { - image = tk.getImage("lib/" + name); - //} else { - //image = tk.getImage(who.getClass().getResource(name)); - //} - - //image = tk.getImage("lib/" + name); - //URL url = PdeApplet.class.getResource(name); - //image = tk.getImage(url); - //} - //MediaTracker tracker = new MediaTracker(applet); - MediaTracker tracker = new MediaTracker(who); //frame); + image = tk.getImage(getLibContents(name)); + MediaTracker tracker = new MediaTracker(who); tracker.addImage(image, 0); try { tracker.waitForAll(); @@ -819,17 +907,7 @@ public class Base { static public InputStream getStream(String filename) throws IOException { - //if (Base.platform == Base.MACOSX) { - // macos doesn't seem to think that files in the lib folder - // are part of the resources, unlike windows or linux. - // actually, this is only the case when running as a .app, - // since it works fine from run.sh, but not Arduino.app - return new FileInputStream("lib/" + filename); - //} - - // all other, more reasonable operating systems - //return cls.getResource(filename).openStream(); - //return Base.class.getResource(filename).openStream(); + return new FileInputStream(getLibContents(filename)); } @@ -965,7 +1043,7 @@ public class Base { if (!Preferences.getBoolean("compiler.save_build_files")) { if (!dead.delete()) { // temporarily disabled - //System.err.println("couldn't delete " + dead); + System.err.println("Could not delete " + dead); } } } else { @@ -1040,197 +1118,4 @@ public class Base { } } } - - - /** - * Equivalent to the one in PApplet, but static (die() is removed) - */ - static public String[] loadStrings(File file) { - try { - FileInputStream input = new FileInputStream(file); - BufferedReader reader = - new BufferedReader(new InputStreamReader(input)); - - String lines[] = new String[100]; - int lineCount = 0; - String line = null; - while ((line = reader.readLine()) != null) { - if (lineCount == lines.length) { - String temp[] = new String[lineCount << 1]; - System.arraycopy(lines, 0, temp, 0, lineCount); - lines = temp; - } - lines[lineCount++] = line; - } - reader.close(); - - if (lineCount == lines.length) { - return lines; - } - - // resize array to appropraite amount for these lines - String output[] = new String[lineCount]; - System.arraycopy(lines, 0, output, 0, lineCount); - return output; - - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } - - - ////////////////////////////////////////////////////////////// - - // STRINGS - - - /** - * Remove whitespace characters from the beginning and ending - * of a String. Works like String.trim() but includes the - * unicode nbsp character as well. - */ - static public String trim(String str) { - return str.replace('\u00A0', ' ').trim(); - - /* - int left = 0; - int right = str.length() - 1; - - while ((left <= right) && - (WHITESPACE.indexOf(str.charAt(left)) != -1)) left++; - if (left == right) return ""; - - while (WHITESPACE.indexOf(str.charAt(right)) != -1) --right; - - return str.substring(left, right-left+1); - */ - } - - /** - * Join an array of Strings together as a single String, - * separated by the whatever's passed in for the separator. - */ - static public String join(String str[], char separator) { - return join(str, String.valueOf(separator)); - } - - - /** - * Join an array of Strings together as a single String, - * separated by the whatever's passed in for the separator. - *

- * To use this on numbers, first pass the array to nf() or nfs() - * to get a list of String objects, then use join on that. - *

-   * e.g. String stuff[] = { "apple", "bear", "cat" };
-   *      String list = join(stuff, ", ");
-   *      // list is now "apple, bear, cat"
- */ - static public String join(String str[], String separator) { - StringBuffer buffer = new StringBuffer(); - for (int i = 0; i < str.length; i++) { - if (i != 0) buffer.append(separator); - buffer.append(str[i]); - } - return buffer.toString(); - } - - - /** - * Split the provided String at wherever whitespace occurs. - * Multiple whitespace (extra spaces or tabs or whatever) - * between items will count as a single break. - *

- * The whitespace characters are "\t\n\r\f", which are the defaults - * for java.util.StringTokenizer, plus the unicode non-breaking space - * character, which is found commonly on files created by or used - * in conjunction with Mac OS X (character 160, or 0x00A0 in hex). - *

-   * i.e. split("a b") -> { "a", "b" }
-   *      split("a    b") -> { "a", "b" }
-   *      split("a\tb") -> { "a", "b" }
-   *      split("a \t  b  ") -> { "a", "b" }
- */ - static public String[] split(String what) { - return split(what, WHITESPACE); - } - - - /** - * Splits a string into pieces, using any of the chars in the - * String 'delim' as separator characters. For instance, - * in addition to white space, you might want to treat commas - * as a separator. The delimeter characters won't appear in - * the returned String array. - *
-   * i.e. split("a, b", " ,") -> { "a", "b" }
-   * 
- * To include all the whitespace possibilities, use the variable - * WHITESPACE, found in PConstants: - *
-   * i.e. split("a   | b", WHITESPACE + "|");  ->  { "a", "b" }
- */ - static public String[] split(String what, String delim) { - StringTokenizer toker = new StringTokenizer(what, delim); - String pieces[] = new String[toker.countTokens()]; - - int index = 0; - while (toker.hasMoreTokens()) { - pieces[index++] = toker.nextToken(); - } - return pieces; - } - - - /** - * Split a string into pieces along a specific character. - * Most commonly used to break up a String along tab characters. - *

- * This operates differently than the others, where the - * single delimeter is the only breaking point, and consecutive - * delimeters will produce an empty string (""). This way, - * one can split on tab characters, but maintain the column - * alignments (of say an excel file) where there are empty columns. - */ - static public String[] split(String what, char delim) { - // do this so that the exception occurs inside the user's - // program, rather than appearing to be a bug inside split() - if (what == null) return null; - //return split(what, String.valueOf(delim)); // huh - - char chars[] = what.toCharArray(); - int splitCount = 0; //1; - for (int i = 0; i < chars.length; i++) { - if (chars[i] == delim) splitCount++; - } - // make sure that there is something in the input string - //if (chars.length > 0) { - // if the last char is a delimeter, get rid of it.. - //if (chars[chars.length-1] == delim) splitCount--; - // on second thought, i don't agree with this, will disable - //} - if (splitCount == 0) { - String splits[] = new String[1]; - splits[0] = new String(what); - return splits; - } - //int pieceCount = splitCount + 1; - String splits[] = new String[splitCount + 1]; - int splitIndex = 0; - int startIndex = 0; - for (int i = 0; i < chars.length; i++) { - if (chars[i] == delim) { - splits[splitIndex++] = - new String(chars, startIndex, i-startIndex); - startIndex = i + 1; - } - } - //if (startIndex != chars.length) { - splits[splitIndex] = - new String(chars, startIndex, chars.length-startIndex); - //} - return splits; - } - } diff --git a/app/Editor.java b/app/Editor.java index e2c9955cc..316104d5d 100644 --- a/app/Editor.java +++ b/app/Editor.java @@ -28,11 +28,13 @@ package processing.app; import processing.app.syntax.*; import processing.app.tools.*; +import processing.core.*; import java.awt.*; import java.awt.datatransfer.*; import java.awt.dnd.*; import java.awt.event.*; +import java.awt.print.*; import java.io.*; import java.lang.reflect.*; import java.net.*; @@ -45,7 +47,9 @@ import javax.swing.event.*; import javax.swing.text.*; import javax.swing.undo.*; +import com.apple.mrj.*; import com.oroinc.text.regex.*; +//import de.hunsicker.jalopy.*; import com.apple.mrj.*; import gnu.io.*; @@ -78,6 +82,9 @@ public class Editor extends JFrame boolean handleNewShift; boolean handleNewLibrary; + PageFormat pageFormat; + PrinterJob printerJob; + EditorButtons buttons; EditorHeader header; EditorStatus status; @@ -133,14 +140,12 @@ public class Editor extends JFrame // used internally, and only briefly CompoundEdit compoundEdit; - //static public UndoManager undo = new UndoManager(); // editor needs this guy - // //SketchHistory history; // TODO re-enable history Sketchbook sketchbook; //Preferences preferences; - //FindReplace find; + FindReplace find; //static Properties keywords; // keyword -> reference html lookup @@ -167,9 +172,13 @@ public class Editor extends JFrame // add listener to handle window close box hit event addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { - handleQuit(); + handleQuitInternal(); } }); + // don't close the window when clicked, the app will take care + // of that via the handleQuitInternal() methods + // http://dev.processing.org/bugs/show_bug.cgi?id=440 + setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); PdeKeywords keywords = new PdeKeywords(); sketchbook = new Sketchbook(this); @@ -188,8 +197,14 @@ public class Editor extends JFrame // doesn't matter when this is created, just make it happen at some point //find = new FindReplace(Editor.this); - Container pain = getContentPane(); + //Container pain = getContentPane(); + //pain.setLayout(new BorderLayout()); + // for rev 0120, placing things inside a JPanel because + Container contentPain = getContentPane(); + contentPain.setLayout(new BorderLayout()); + JPanel pain = new JPanel(); pain.setLayout(new BorderLayout()); + contentPain.add(pain, BorderLayout.CENTER); Box box = Box.createVerticalBox(); Box upper = Box.createVerticalBox(); @@ -251,6 +266,17 @@ public class Editor extends JFrame listener = new EditorListener(this, textarea); pain.add(box); + pain.setTransferHandler(new TransferHandler() { + + public boolean canImport(JComponent dest, DataFlavor[] flavors) { + // claim that we can import everything + return true; + } + + public boolean importData(JComponent src, Transferable transferable) { + DataFlavor[] flavors = transferable.getTransferDataFlavors(); + + /* DropTarget dt = new DropTarget(this, new DropTargetListener() { public void dragEnter(DropTargetDragEvent event) { @@ -278,14 +304,17 @@ public class Editor extends JFrame Transferable transferable = event.getTransferable(); DataFlavor flavors[] = transferable.getTransferDataFlavors(); + */ int successful = 0; for (int i = 0; i < flavors.length; i++) { try { //System.out.println(flavors[i]); //System.out.println(transferable.getTransferData(flavors[i])); - java.util.List list = - (java.util.List) transferable.getTransferData(flavors[i]); + Object stuff = transferable.getTransferData(flavors[i]); + if (!(stuff instanceof java.util.List)) continue; + java.util.List list = (java.util.List) stuff; + for (int j = 0; j < list.size(); j++) { Object item = list.get(j); if (item instanceof File) { @@ -298,7 +327,7 @@ public class Editor extends JFrame File parent = file.getParentFile(); if (name.equals(parent.getName())) { handleOpenFile(file); - return; + return true; } } @@ -310,6 +339,7 @@ public class Editor extends JFrame } catch (Exception e) { e.printStackTrace(); + return false; } } @@ -322,6 +352,7 @@ public class Editor extends JFrame } else { message(successful + " files added to the sketch."); } + return true; } }); } @@ -488,7 +519,9 @@ public class Editor extends JFrame listener.applyPreferences(); // in case moved to a new location - sketchbook.rebuildMenus(); + // For 0125, changing to async version (to be implemented later) + //sketchbook.rebuildMenus(); + sketchbook.rebuildMenusAsync(); } @@ -576,11 +609,19 @@ public class Editor extends JFrame menu.addSeparator(); item = newJMenuItem("Page Setup", 'P', true); - item.setEnabled(false); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handlePageSetup(); + } + }); menu.add(item); item = newJMenuItem("Print", 'P'); - item.setEnabled(false); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + handlePrint(); + } + }); menu.add(item); // macosx already has its own preferences and quit menu @@ -600,7 +641,7 @@ public class Editor extends JFrame item = newJMenuItem("Quit", 'Q'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - handleQuit(); + handleQuitInternal(); } }); menu.add(item); @@ -639,17 +680,9 @@ public class Editor extends JFrame menu.addSeparator(); - item = new JMenuItem("Add File..."); - item.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - sketch.addFile(); - } - }); - menu.add(item); - menu.add(sketchbook.getImportMenu()); - if (Base.isWindows() || Base.isMacOS()) { + //if (Base.isWindows() || Base.isMacOS()) { // no way to do an 'open in file browser' on other platforms // since there isn't any sort of standard item = newJMenuItem("Show Sketch Folder", 'K', false); @@ -660,8 +693,20 @@ public class Editor extends JFrame } }); menu.add(item); + if (!Base.openFolderAvailable()) { + item.setEnabled(false); } + //menu.addSeparator(); + + item = new JMenuItem("Add File..."); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + sketch.addFile(); + } + }); + menu.add(item); + // TODO re-enable history //history.attachMenu(menu); return menu; @@ -681,20 +726,39 @@ public class Editor extends JFrame item.addActionListener(new ActionListener() { synchronized public void actionPerformed(ActionEvent e) { new AutoFormat(Editor.this).show(); - //handleBeautify(); + + /* + Jalopy jalopy = new Jalopy(); + jalopy.setInput(getText(), sketch.current.file.getAbsolutePath()); + StringBuffer buffer = new StringBuffer(); + jalopy.setOutput(buffer); + jalopy.setInspect(false); + jalopy.format(); + setText(buffer.toString(), 0, 0); + + if (jalopy.getState() == Jalopy.State.OK) + System.out.println("successfully formatted"); + else if (jalopy.getState() == Jalopy.State.WARN) + System.out.println(" formatted with warnings"); + else if (jalopy.getState() == Jalopy.State.ERROR) + System.out.println(" could not be formatted"); + */ } }); menu.add(item); - /*item = new JMenuItem("Create Font..."); + item = new JMenuItem("Copy for Discourse"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - //new CreateFont().show(sketch.dataFolder); - new CreateFont(Editor.this).show(); + SwingUtilities.invokeLater(new Runnable() { + public void run() { + new DiscourseFormat(Editor.this).show(); + } + }); } }); menu.add(item); - */ + item = new JMenuItem("Archive Sketch"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -706,13 +770,17 @@ public class Editor extends JFrame }); menu.add(item); + /* item = new JMenuItem("Export Folder..."); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { new ExportFolder(Editor.this).show(); } }); menu.add(item); + */ menu.addSeparator(); mcuMenu = new JMenu("Microcontroller (MCU)"); @@ -946,21 +1014,18 @@ public class Editor extends JFrame menu.add(item); } - item = new JMenuItem("Troubleshooting"); + item = new JMenuItem("Environment"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Base.openURL(System.getProperty("user.dir") + File.separator + - "reference" + File.separator + - "Guide_Troubleshooting.html"); + Base.showEnvironment(); } }); menu.add(item); - item = new JMenuItem("Environment"); + item = new JMenuItem("Troubleshooting"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Base.openURL(System.getProperty("user.dir") + File.separator + - "reference" + File.separator + "Guide_Environment.html"); + Base.showTroubleshooting(); } }); menu.add(item); @@ -968,8 +1033,17 @@ public class Editor extends JFrame item = new JMenuItem("Reference"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Base.openURL(System.getProperty("user.dir") + File.separator + - "reference" + File.separator + "index.html"); + Base.showReference(); + } + }); + menu.add(item); + + item = newJMenuItem("Find in Reference", 'F', true); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (textarea.isSelectionActive()) { + handleReference(); + } } }); menu.add(item); @@ -977,33 +1051,11 @@ public class Editor extends JFrame item = new JMenuItem("Frequently Asked Questions"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - Base.openURL(System.getProperty("user.dir") + File.separator + - "reference" + File.separator + "FAQ.html"); + Base.showFAQ(); } }); menu.add(item); -// item = newJMenuItem("Find in Reference", 'F', true); -// item.addActionListener(new ActionListener() { -// public void actionPerformed(ActionEvent e) { -// if (textarea.isSelectionActive()) { -// String text = textarea.getSelectedText(); -// if (text.length() == 0) { -// message("First select a word to find in the reference."); -// -// } else { -// String referenceFile = PdeKeywords.getReference(text); -// if (referenceFile == null) { -// message("No reference available for \"" + text + "\""); -// } else { -// Base.showReference(referenceFile); -// } -// } -// } -// } -// }); -// menu.add(item); - item = newJMenuItem("Visit www.arduino.cc", '5'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -1083,22 +1135,27 @@ public class Editor extends JFrame item = newJMenuItem("Find...", 'F'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - new FindReplace(Editor.this).show(); - //find.show(); + if (find == null) { + find = new FindReplace(Editor.this); + } + //new FindReplace(Editor.this).show(); + find.show(); //find.setVisible(true); } }); menu.add(item); + // TODO find next should only be enabled after a + // search has actually taken place item = newJMenuItem("Find Next", 'G'); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { - // TODO find next should only be enabled after a - // search has actually taken place + if (find != null) { //find.find(true); - FindReplace find = new FindReplace(Editor.this); //.show(); + //FindReplace find = new FindReplace(Editor.this); //.show(); find.find(true); } + } }); menu.add(item); @@ -1116,9 +1173,9 @@ public class Editor extends JFrame /** * A software engineer, somewhere, needs to have his abstraction - * taken away. In some countries they jail people for writing the - * sort of crappy api that would require a four line helper function - * to set the command key for a menu item. + * taken away. In some countries they jail or beat people for writing + * the sort of API that would require a five line helper function + * just to set the command key for a menu item. */ static public JMenuItem newJMenuItem(String title, int what, boolean shift) { @@ -1191,7 +1248,6 @@ public class Editor extends JFrame protected void updateRedoState() { if (undo.canRedo()) { - //this.setEnabled(true); redoItem.setEnabled(true); redoItem.setText(undo.getRedoPresentationName()); putValue(Action.NAME, undo.getRedoPresentationName()); @@ -1339,10 +1395,12 @@ public class Editor extends JFrame redoAction.updateRedoState(); } + public void beginCompoundEdit() { compoundEdit = new CompoundEdit(); } + public void endCompoundEdit() { compoundEdit.end(); undo.addEdit(compoundEdit); @@ -1352,6 +1410,8 @@ public class Editor extends JFrame } + // ................................................................... + public void handleRun(final boolean present) { doClose(); @@ -1576,42 +1636,71 @@ public class Editor extends JFrame String prompt = "Save changes to " + sketch.name + "? "; if (checkModifiedMode != HANDLE_QUIT) { - // if the user is not quitting, then use the nicer + // if the user is not quitting, then use simpler nicer // dialog that's actually inside the p5 window. status.prompt(prompt); } else { - // if the user selected quit, then this has to be done with - // a JOptionPane instead of internally in the editor. - // TODO this is actually just a bug to be fixed. - - // macosx java kills the app even though cancel might get hit - // so the cancel button is (temporarily) left off - // this may be treated differently in macosx java 1.4, - // but 1.4 isn't currently stable enough to use. - - // turns out windows has the same problem (sometimes) - // disable cancel for now until a fix can be found. - - Object[] options = { "Yes", "No" }; - int result = JOptionPane.showOptionDialog(this, - prompt, - "Quit", - JOptionPane.YES_NO_OPTION, - JOptionPane.QUESTION_MESSAGE, - null, - options, - options[0]); + if (!Base.isMacOS() || PApplet.javaVersion < 1.5f) { + int result = + JOptionPane.showConfirmDialog(this, prompt, "Quit", + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); if (result == JOptionPane.YES_OPTION) { handleSave(true); checkModified2(); } else if (result == JOptionPane.NO_OPTION) { - checkModified2(); // though this may just quit + checkModified2(); + } + // cancel is ignored altogether - } else if (result == JOptionPane.CANCEL_OPTION) { - // ignored + } else { + // This code is disabled unless Java 1.5 is being used on Mac OS X + // because of a Java bug that prevents the initial value of the + // dialog from being set properly (at least on my MacBook Pro). + // The bug causes the "Don't Save" option to be the highlighted, + // blinking, default. This sucks. But I'll tell you what doesn't + // suck--workarounds for the Mac and Apple's snobby attitude about it! + + // adapted from the quaqua guide + // http://www.randelshofer.ch/quaqua/guide/joptionpane.html + JOptionPane pane = + new JOptionPane(" " + + " " + + "Do you want to save changes to this sketch
" + + " before closing?
" + + "

If you don't save, your changes will be lost.", + JOptionPane.QUESTION_MESSAGE); + + String[] options = new String[] { + "Save", "Cancel", "Don't Save" + }; + pane.setOptions(options); + + // highlight the safest option ala apple hig + pane.setInitialValue(options[0]); + + // on macosx, setting the destructive property places this option + // away from the others at the lefthand side + pane.putClientProperty("Quaqua.OptionPane.destructiveOption", + new Integer(2)); + + JDialog dialog = pane.createDialog(this, null); + dialog.show(); + + Object result = pane.getValue(); + if (result == options[0]) { // save (and quit) + handleSave(true); + checkModified2(); + + } else if (result == options[2]) { // don't save (still quit) + checkModified2(); + } } } } @@ -1739,9 +1828,15 @@ public class Editor extends JFrame * Open a sketch from a particular path, but don't check to save changes. * Used by Sketch.saveAs() to re-open a sketch after the "Save As" */ - public void handleOpenUnchecked(String path) { + public void handleOpenUnchecked(String path, int codeIndex, + int selStart, int selStop, int scrollPos) { doClose(); handleOpen2(path); + + sketch.setCurrent(codeIndex); + textarea.select(selStart, selStop); + //textarea.updateScrollBars(); + textarea.setScrollPosition(scrollPos); } @@ -1761,7 +1856,8 @@ public class Editor extends JFrame if (!oldPath.equals(newPath)) { if (Base.calcFolderSize(sketch.folder) == 0) { Base.removeDir(sketch.folder); - sketchbook.rebuildMenus(); + //sketchbook.rebuildMenus(); + sketchbook.rebuildMenusAsync(); } } } catch (Exception e) { } // oh well @@ -1893,7 +1989,11 @@ public class Editor extends JFrame message(EMPTY); } // rebuild sketch menu in case a save-as was forced - sketchbook.rebuildMenus(); + // Disabling this for 0125, instead rebuild the menu inside + // the Save As method of the Sketch object, since that's the + // only one who knows whether something was renamed. + //sketchbook.rebuildMenus(); + //sketchbook.rebuildMenusAsync(); } catch (Exception e) { // show the error as a message in the window @@ -1918,7 +2018,10 @@ public class Editor extends JFrame try { if (sketch.saveAs()) { message("Done Saving."); - sketchbook.rebuildMenus(); + // Disabling this for 0125, instead rebuild the menu inside + // the Save As method of the Sketch object, since that's the + // only one who knows whether something was renamed. + //sketchbook.rebuildMenusAsync(); } else { message("Save Cancelled."); } @@ -2007,6 +2110,7 @@ public class Editor extends JFrame null, options, options[0]); + if (result == JOptionPane.OK_OPTION) { handleSave(true); @@ -2021,13 +2125,57 @@ public class Editor extends JFrame return true; } - + + public void handlePageSetup() { + //printerJob = null; + if (printerJob == null) { + printerJob = PrinterJob.getPrinterJob(); + } + if (pageFormat == null) { + pageFormat = printerJob.defaultPage(); + } + pageFormat = printerJob.pageDialog(pageFormat); + //System.out.println("page format is " + pageFormat); + } + + + public void handlePrint() { + message("Printing..."); + //printerJob = null; + if (printerJob == null) { + printerJob = PrinterJob.getPrinterJob(); + } + if (pageFormat != null) { + //System.out.println("setting page format " + pageFormat); + printerJob.setPrintable(textarea.getPainter(), pageFormat); + } else { + printerJob.setPrintable(textarea.getPainter()); + } + // set the name of the job to the code name + printerJob.setJobName(sketch.current.name); + + if (printerJob.printDialog()) { + try { + printerJob.print(); + message("Done printing."); + + } catch (PrinterException pe) { + error("Error while printing."); + pe.printStackTrace(); + } + } else { + message("Printing canceled."); + } + //printerJob = null; // clear this out? + } + + /** * Quit, but first ask user if it's ok. Also store preferences * to disk just in case they want to quit. Final exit() happens * in Editor since it has the callback from EditorStatus. */ - public void handleQuit() { + public void handleQuitInternal() { // doStop() isn't sufficient with external vm & quit // instead use doClose() which will kill the external vm doClose(); @@ -2036,6 +2184,27 @@ public class Editor extends JFrame } + /** + * Method for the MRJQuitHandler, needs to be dealt with differently + * than the regular handler because OS X has an annoying implementation + * quirk + * that requires an exception to be thrown in order to properly cancel + * a quit message. + */ + public void handleQuit() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + handleQuitInternal(); + } + }); + + // Throw IllegalStateException so new thread can execute. + // If showing dialog on this thread in 10.2, we would throw + // upon JOptionPane.NO_OPTION + throw new IllegalStateException("Quit Pending User Confirmation"); + } + + /** * Actually do the quit action. */ @@ -2050,6 +2219,26 @@ public class Editor extends JFrame System.exit(0); } + + + protected void handleReference() { + String text = textarea.getSelectedText().trim(); + + if (text.length() == 0) { + message("First select a word to find in the reference."); + + } else { + String referenceFile = PdeKeywords.getReference(text); + //System.out.println("reference file is " + referenceFile); + if (referenceFile == null) { + message("No reference available for \"" + text + "\""); + } else { + Base.showReference(referenceFile + ".html"); + } + } + } + + protected void handleBurnBootloader(final String target, final boolean parallel) { if(debugging) doStop(); @@ -2083,6 +2272,7 @@ public class Editor extends JFrame }}); } + public void highlightLine(int lnum) { if (lnum < 0) { textarea.select(0, 0); @@ -2169,7 +2359,7 @@ public class Editor extends JFrame public void error(RunnerException e) { - //System.out.println("ERORROOROROR 2"); + //System.out.println("file and line is " + e.file + " " + e.line); if (e.file >= 0) sketch.setCurrent(e.file); if (e.line >= 0) highlightLine(e.line); @@ -2205,7 +2395,7 @@ public class Editor extends JFrame * Returns the edit popup menu. */ class TextAreaPopup extends JPopupMenu { - String currentDir = System.getProperty("user.dir"); + //String currentDir = System.getProperty("user.dir"); String referenceFile = null; JMenuItem cutItem, copyItem; @@ -2251,13 +2441,14 @@ public class Editor extends JFrame this.addSeparator(); -// referenceItem = new JMenuItem("Find in Reference"); -// referenceItem.addActionListener(new ActionListener() { -// public void actionPerformed(ActionEvent e) { -// Base.showReference(referenceFile); -// } -// }); -// this.add(referenceItem); + referenceItem = new JMenuItem("Find in Reference"); + referenceItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + //Base.showReference(referenceFile + ".html"); + handleReference(); //textarea.getSelectedText()); + } + }); + this.add(referenceItem); } // if no text is selected, disable copy and cut menu items @@ -2266,14 +2457,14 @@ public class Editor extends JFrame cutItem.setEnabled(true); copyItem.setEnabled(true); - //referenceFile = PdeKeywords.getReference(textarea.getSelectedText()); - //if (referenceFile != null) { - //referenceItem.setEnabled(true); - //} + String sel = textarea.getSelectedText().trim(); + referenceFile = PdeKeywords.getReference(sel); + referenceItem.setEnabled(referenceFile != null); + } else { cutItem.setEnabled(false); copyItem.setEnabled(false); - //referenceItem.setEnabled(false); + referenceItem.setEnabled(false); } super.show(component, x, y); } diff --git a/app/EditorHeader.java b/app/EditorHeader.java index 2fc60c90f..e4ca49b4e 100644 --- a/app/EditorHeader.java +++ b/app/EditorHeader.java @@ -241,6 +241,7 @@ public class EditorHeader extends JComponent { public void rebuildMenu() { + //System.out.println("rebuilding"); if (menu != null) { menu.removeAll(); @@ -248,6 +249,9 @@ public class EditorHeader extends JComponent { menu = new JMenu(); popup = menu.getPopupMenu(); add(popup); + popup.setLightWeightPopupEnabled(true); + + /* popup.addPopupMenuListener(new PopupMenuListener() { public void popupMenuCanceled(PopupMenuEvent e) { // on redraw, the isVisible() will get checked. @@ -259,6 +263,7 @@ public class EditorHeader extends JComponent { public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { } public void popupMenuWillBecomeVisible(PopupMenuEvent e) { } }); + */ } JMenuItem item; @@ -352,6 +357,43 @@ public class EditorHeader extends JComponent { } menu.add(unhide); + menu.addSeparator(); + + // KeyEvent.VK_LEFT and VK_RIGHT will make Windows beep + + int ctrlAlt = ActionEvent.ALT_MASK | + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + + //item = Editor.newJMenuItem("Previous Tab", '[', true); + item = new JMenuItem("Previous Tab"); + //int shortcut = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + KeyStroke ctrlAltLeft = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, ctrlAlt); + item.setAccelerator(ctrlAltLeft); + //int modifiers = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + //KeyStroke tabby = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, modifiers); + + // this didn't want to work consistently + /* + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.prevCode(); + } + }); + */ + menu.add(item); + + //item = Editor.newJMenuItem("Next Tab", ']', true); + item = new JMenuItem("Next Tab"); + KeyStroke ctrlAltRight = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, ctrlAlt); + item.setAccelerator(ctrlAltRight); + /* + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + editor.sketch.nextCode(); + } + }); + */ + menu.add(item); if (sketch != null) { menu.addSeparator(); diff --git a/app/EditorListener.java b/app/EditorListener.java index 8f6c41ad7..b8b9e791c 100644 --- a/app/EditorListener.java +++ b/app/EditorListener.java @@ -60,6 +60,10 @@ public class EditorListener { int selectionStart, selectionEnd; int position; + /** ctrl-alt on windows and linux, cmd-alt on mac os x */ + static final int CTRL_ALT = ActionEvent.ALT_MASK | + Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + public EditorListener(Editor editor, JEditTextArea textarea) { this.editor = editor; @@ -105,6 +109,16 @@ public class EditorListener { //System.out.println(c + " " + code + " " + event); //System.out.println(); + if ((event.getModifiers() & CTRL_ALT) == CTRL_ALT) { + if (code == KeyEvent.VK_LEFT) { + editor.sketch.prevCode(); + return true; + } else if (code == KeyEvent.VK_RIGHT) { + editor.sketch.nextCode(); + return true; + } + } + if ((event.getModifiers() & KeyEvent.META_MASK) != 0) { //event.consume(); // does nothing return false; @@ -195,8 +209,8 @@ public class EditorListener { switch ((int) c) { - case 9: // expand tabs - if (tabsExpand) { + case 9: + if (tabsExpand) { // expand tabs textarea.setSelectedText(tabString); event.consume(); return true; @@ -286,12 +300,40 @@ public class EditorListener { origIndex += offset; // ARGH!#(* WINDOWS#@($* */ + // if the previous thing is a brace (whether prev line or + // up farther) then the correct indent is the number of spaces + // on that line + 'indent'. + // if the previous line is not a brace, then just use the + // identical indentation to the previous line + + // calculate the amount of indent on the previous line + // this will be used *only if the prev line is not an indent* int spaceCount = calcSpaceCount(origIndex, contents); - //int origCount = spaceCount; + + // If the last character was a left curly brace, then indent. + // For 0122, walk backwards a bit to make sure that the there + // isn't a curly brace several spaces (or lines) back. Also + // moved this before calculating extraCount, since it'll affect + // that as well. + int index2 = origIndex; + while ((index2 >= 0) && + Character.isWhitespace(contents[index2])) { + index2--; + } + if (index2 != -1) { + // still won't catch a case where prev stuff is a comment + if (contents[index2] == '{') { + // intermediate lines be damned, + // use the indent for this line instead + spaceCount = calcSpaceCount(index2, contents); + spaceCount += tabSize; + } + } + //System.out.println("spaceCount should be " + spaceCount); // now before inserting this many spaces, walk forward from - // the caret position, so that the number of spaces aren't - // just being duplicated again + // the caret position and count the number of spaces, + // so that the number of spaces aren't duplicated again int index = origIndex + 1; int extraCount = 0; while ((index < contents.length) && @@ -300,23 +342,58 @@ public class EditorListener { extraCount++; index++; } + int braceCount = 0; + while ((index < contents.length) && (contents[index] != '\n')) { + if (contents[index] == '}') { + braceCount++; + } + index++; + } // hitting return on a line with spaces *after* the caret - // can cause trouble. for simplicity's sake, just ignore this case. - //if (spaceCount < 0) spaceCount = origCount; + // can cause trouble. for 0099, was ignoring the case, but this is + // annoying, so in 0122 we're trying to fix that. + /* if (spaceCount - extraCount > 0) { spaceCount -= extraCount; } + */ + spaceCount -= extraCount; + //if (spaceCount < 0) spaceCount = 0; + //System.out.println("extraCount is " + extraCount); - // if the last character was a left curly brace, then indent - if (origIndex != -1) { - if (contents[origIndex] == '{') { - spaceCount += tabSize; - } - } + // now, check to see if the current line contains a } and if so, + // outdent again by indent + //if (braceCount > 0) { + //spaceCount -= 2; + //} + if (spaceCount < 0) { + // for rev 0122, actually delete extra space + //textarea.setSelectionStart(origIndex + 1); + textarea.setSelectionEnd(textarea.getSelectionEnd() - spaceCount); + textarea.setSelectedText("\n"); + } else { String insertion = "\n" + Editor.EMPTY.substring(0, spaceCount); textarea.setSelectedText(insertion); + } + + // not gonna bother handling more than one brace + if (braceCount > 0) { + int sel = textarea.getSelectionStart(); + // sel - tabSize will be -1 if start/end parens on the same line + // http://dev.processing.org/bugs/show_bug.cgi?id=484 + if (sel - tabSize >= 0) { + textarea.select(sel - tabSize, sel); + String s = Editor.EMPTY.substring(0, tabSize); + // if these are spaces that we can delete + if (textarea.getSelectedText().equals(s)) { + textarea.setSelectedText(""); + } else { + textarea.select(sel, sel); + } + } + } // mark this event as already handled event.consume(); @@ -424,6 +501,34 @@ public class EditorListener { } + /** Cmd-Shift or Ctrl-Shift depending on the platform */ + //static final int CMD_SHIFT = ActionEvent.SHIFT_MASK | + // Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + /** ctrl-alt on windows and linux, cmd-alt on mac os x */ + //static final int CTRL_ALT = ActionEvent.ALT_MASK | + // Toolkit.getDefaultToolkit().getMenuShortcutKeyMask(); + + /* + public boolean keyTyped(KeyEvent event) { + char c = event.getKeyChar(); + int code = event.getKeyCode(); + + if ((event.getModifiers() & CMD_ALT) == CMD_ALT) { + if (code == KeyEvent.VK_LEFT) { + //if (c == '[') { + editor.sketch.prevCode(); + return true; + } else if (code == KeyEvent.VK_RIGHT) { + //} else if (c == ']') { + editor.sketch.nextCode(); + return true; + } + } + return false; + } + */ + + /** * Return the index for the first character on this line. */ diff --git a/app/FindReplace.java b/app/FindReplace.java index 43f6ce43a..1dccf214d 100644 --- a/app/FindReplace.java +++ b/app/FindReplace.java @@ -57,6 +57,7 @@ public class FindReplace extends JFrame implements ActionListener { JButton replaceButton; JButton replaceAllButton; + JButton replaceFindButton; JButton findButton; JCheckBox ignoreCaseBox; @@ -132,12 +133,14 @@ public class FindReplace extends JFrame implements ActionListener { // ordering is different on mac versus pc if (Base.isMacOS()) { - buttons.add(replaceButton = new JButton("Replace")); buttons.add(replaceAllButton = new JButton("Replace All")); + buttons.add(replaceButton = new JButton("Replace")); + buttons.add(replaceFindButton = new JButton("Replace & Find")); buttons.add(findButton = new JButton("Find")); } else { buttons.add(findButton = new JButton("Find")); + buttons.add(replaceFindButton = new JButton("Replace & Find")); buttons.add(replaceButton = new JButton("Replace")); buttons.add(replaceAllButton = new JButton("Replace All")); } @@ -169,10 +172,12 @@ public class FindReplace extends JFrame implements ActionListener { replaceButton.addActionListener(this); replaceAllButton.addActionListener(this); + replaceFindButton.addActionListener(this); findButton.addActionListener(this); // you mustn't replace what you haven't found, my son replaceButton.setEnabled(false); + replaceFindButton.setEnabled(false); // so that typing will go straight to this field //findField.requestFocus(); @@ -189,44 +194,28 @@ public class FindReplace extends JFrame implements ActionListener { setBounds((screen.width - wide) / 2, (screen.height - high) / 2, wide, high); - // add key listener to trap esc and ctrl/cmd-w - /* - KeyListener listener = new KeyAdapter() { - public void keyPressed(KeyEvent e) { - if (Base.isCloseWindowEvent(e)) hide(); - } - }; - findField.addKeyListener(listener); - replaceField.addKeyListener(listener); - addKeyListener(listener); - */ - ActionListener disposer = new ActionListener() { - public void actionPerformed(ActionEvent actionEvent) { - //hide(); - handleClose(); - } - }; - setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { handleClose(); } }); - Base.registerWindowCloseKeys(getRootPane(), disposer); + Base.registerWindowCloseKeys(getRootPane(), new ActionListener() { + public void actionPerformed(ActionEvent actionEvent) { + //hide(); + handleClose(); + } + }); - /* // hack to to get first field to focus properly on osx - // though this still doesn't seem to work addWindowListener(new WindowAdapter() { public void windowActivated(WindowEvent e) { //System.out.println("activating"); - //boolean ok = findField.requestFocusInWindow(); + boolean ok = findField.requestFocusInWindow(); //System.out.println("got " + ok); - //findField.selectAll(); + findField.selectAll(); } }); - */ } @@ -256,6 +245,10 @@ public class FindReplace extends JFrame implements ActionListener { if (source == findButton) { find(true); + } else if (source == replaceFindButton) { + replace(); + find(true); + } else if (source == replaceButton) { replace(); @@ -276,6 +269,7 @@ public class FindReplace extends JFrame implements ActionListener { found = false; String search = findField.getText(); + //System.out.println("finding for " + search + " " + findString); // this will catch "find next" being called when no search yet if (search.length() == 0) return; @@ -299,12 +293,14 @@ public class FindReplace extends JFrame implements ActionListener { if (nextIndex == -1) { found = false; replaceButton.setEnabled(false); + replaceFindButton.setEnabled(false); //Toolkit.getDefaultToolkit().beep(); return; } } found = true; replaceButton.setEnabled(true); + replaceFindButton.setEnabled(true); editor.textarea.select(nextIndex, nextIndex + search.length()); } @@ -322,6 +318,7 @@ public class FindReplace extends JFrame implements ActionListener { if (sel.equals(replaceField.getText())) { found = false; replaceButton.setEnabled(false); + replaceFindButton.setEnabled(false); return; } @@ -332,6 +329,7 @@ public class FindReplace extends JFrame implements ActionListener { // don't allow a double replace replaceButton.setEnabled(false); + replaceFindButton.setEnabled(false); } diff --git a/app/Library.java b/app/Library.java index 24a7eac17..09b5d44a1 100755 --- a/app/Library.java +++ b/app/Library.java @@ -31,6 +31,8 @@ import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; +import processing.core.*; + /* * Provides information about and builds a library */ @@ -552,7 +554,7 @@ public class Library implements MessageConsumer{ continue; } - String pieces[] = Base.split(line, '\t'); + String pieces[] = PApplet.split(line, '\t'); if (pieces.length >= 2) { String keyword = pieces[0].trim(); diff --git a/app/Preferences.java b/app/Preferences.java index 671837b2d..29916afba 100644 --- a/app/Preferences.java +++ b/app/Preferences.java @@ -41,7 +41,12 @@ import javax.swing.filechooser.*; import javax.swing.text.*; import javax.swing.undo.*; -//import processing.core.PApplet; +import processing.core.PApplet; + + +// TODO change this to use the Java Preferences API +// http://www.onjava.com/pub/a/onjava/synd/2001/10/17/j2se.html +// http://www.particle.kth.se/~lindsey/JavaCourse/Book/Part1/Java/Chapter10/Preferences.html /** @@ -50,6 +55,10 @@ import javax.swing.undo.*; * This class no longer uses the Properties class, since * properties files are iso8859-1, which is highly likely to * be a problem when trying to save sketch folders and locations. + *

+ * This is very poorly put together, that the prefs panel and the + * actual prefs i/o is part of the same code. But there hasn't yet + * been a compelling reason to bother with the separation. */ public class Preferences { @@ -88,9 +97,12 @@ public class Preferences { * inside a static block. */ static public int BUTTON_HEIGHT = 24; + /* + // remove this for 0121, because quaqua takes care of it static { if (Base.isMacOS()) BUTTON_HEIGHT = 29; } + */ // value for the size bars, buttons, etc @@ -107,15 +119,18 @@ public class Preferences { // gui elements - JDialog dialog; + //JDialog dialog; + JFrame dialog; int wide, high; JTextField sketchbookLocationField; + JCheckBox exportSeparateBox; JCheckBox sketchPromptBox; JCheckBox sketchCleanBox; JCheckBox externalEditorBox; + JCheckBox memoryOverrideBox; + JTextField memoryField; JCheckBox checkUpdatesBox; - JTextField fontSizeField; @@ -145,7 +160,7 @@ public class Preferences { // check for platform-specific properties in the defaults String platformExtension = "." + - platforms[Base.platform]; + platforms[processing.core.PApplet.platform]; int extensionLength = platformExtension.length(); Enumeration e = table.keys(); //properties.propertyNames(); @@ -195,7 +210,8 @@ public class Preferences { // setup dialog for the prefs - dialog = new JDialog(editor, "Preferences", true); + //dialog = new JDialog(editor, "Preferences", true); + dialog = new JFrame("Preferences"); dialog.setResizable(false); Container pain = dialog.getContentPane(); @@ -249,6 +265,7 @@ public class Preferences { button = new JButton(PROMPT_BROWSE); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { + /* JFileChooser fc = new JFileChooser(); fc.setSelectedFile(new File(sketchbookLocationField.getText())); fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); @@ -258,6 +275,13 @@ public class Preferences { File file = fc.getSelectedFile(); sketchbookLocationField.setText(file.getAbsolutePath()); } + */ + File dflt = new File(sketchbookLocationField.getText()); + File file = + Base.selectFolder("Select new sketchbook location", dflt, dialog); + if (file != null) { + sketchbookLocationField.setText(file.getAbsolutePath()); + } } }); pain.add(button); @@ -286,6 +310,8 @@ public class Preferences { box.add(label); fontSizeField = new JTextField(4); box.add(fontSizeField); + label = new JLabel(" (requires restart of Arduino)"); + box.add(label); pain.add(box); d = box.getPreferredSize(); box.setBounds(left, top, d.width, d.height); @@ -468,9 +494,9 @@ public class Preferences { String newSizeText = fontSizeField.getText(); try { int newSize = Integer.parseInt(newSizeText.trim()); - String pieces[] = Base.split(get("editor.font"), ','); + String pieces[] = PApplet.split(get("editor.font"), ','); pieces[2] = String.valueOf(newSize); - set("editor.font", Base.join(pieces, ',')); + set("editor.font", PApplet.join(pieces, ',')); } catch (Exception e) { System.err.println("ignoring invalid font size " + newSizeText); diff --git a/app/Runner.java b/app/Runner.java index 0ae4829e6..ba912f770 100644 --- a/app/Runner.java +++ b/app/Runner.java @@ -23,7 +23,7 @@ package processing.app; -//import processing.core.*; +import processing.core.*; import java.awt.*; import java.awt.event.*; @@ -40,7 +40,7 @@ import com.oroinc.text.regex.*; */ public class Runner implements MessageConsumer { - //PApplet applet; + PApplet applet; RunnerException exception; Window window; PrintStream leechErr; @@ -497,6 +497,7 @@ java.lang.NullPointerException } if (codeIndex != -1) { + //System.out.println("got line num " + lineNumber); // in case this was a tab that got embedded into the main .java lineNumber -= sketch.code[codeIndex].preprocOffset; diff --git a/app/Sketch.java b/app/Sketch.java index 19dab5b9f..2623baabf 100644 --- a/app/Sketch.java +++ b/app/Sketch.java @@ -24,7 +24,7 @@ package processing.app; import processing.app.preproc.*; -//import processing.core.*; +import processing.core.*; import java.awt.*; import java.io.*; @@ -73,6 +73,7 @@ public class Sketch { static final String flavorExtensionsShown[] = new String[] { "", ".cpp", ".c", ".h" }; public SketchCode current; + int currentIndex; int codeCount; SketchCode code[]; @@ -225,7 +226,11 @@ public class Sketch { } } - // remove any entries that didn't load properly + // some of the hidden files may be bad too, so use hiddenCounter + // added for rev 0121, fixes bug found by axel + hiddenCount = hiddenCounter; + + // remove any entries that didn't load properly from codeCount int index = 0; while (index < codeCount) { if ((code[index] == null) || @@ -330,7 +335,7 @@ public class Sketch { // ask for new name of file (internal to window) // TODO maybe just popup a text area? renamingCode = true; - String prompt = (current == code[0]) ? + String prompt = (currentIndex == 0) ? "New name for sketch:" : "New name for file:"; String oldName = current.name + flavorExtensionsShown[current.flavor]; editor.status.edit(prompt, oldName); @@ -436,7 +441,7 @@ public class Sketch { } if (renamingCode) { - if (current == code[0]) { + if (currentIndex == 0) { // get the new folder name/location File newFolder = new File(folder.getParentFile(), newName); if (newFolder.exists()) { @@ -494,43 +499,17 @@ public class Sketch { // having saved everything and renamed the folder and the main .pde, // use the editor to re-open the sketch to re-init state // (unfortunately this will kill positions for carets etc) - editor.handleOpenUnchecked(mainFilename); - - /* - // backtrack and don't rename the sketch folder - success = newFolder.renameTo(folder); - if (!success) { - String msg = - "Started renaming sketch and then ran into\n" + - "nasty trouble. Try to salvage with Copy & Paste\n" + - "or attempt a \"Save As\" to see if that works."; - Base.showWarning("Serious Error", msg, null); - } - return; - } - */ - - /* - // set the sketch name... used by the pde and whatnot. - // the name is only set in the sketch constructor, - // so it's important here - name = newName; - - code[0].name = newName; - code[0].file = mainFile; - code[0].program = editor.getText(); - code[0].save(); - - folder = newFolder; + editor.handleOpenUnchecked(mainFilename, + currentIndex, + editor.textarea.getSelectionStart(), + editor.textarea.getSelectionEnd(), + editor.textarea.getScrollPosition()); // get the changes into the sketchbook menu + // (re-enabled in 0115 to fix bug #332) editor.sketchbook.rebuildMenus(); - // reload the sketch - load(); - */ - - } else { + } else { // else if something besides code[0] if (!current.file.renameTo(newFile)) { Base.showWarning("Error", "Could not rename \"" + current.file.getName() + @@ -593,7 +572,7 @@ public class Sketch { // confirm deletion with user, yes/no Object[] options = { "OK", "Cancel" }; - String prompt = (current == code[0]) ? + String prompt = (currentIndex == 0) ? "Are you sure you want to delete this sketch?" : "Are you sure you want to delete \"" + current.name + flavorExtensionsShown[current.flavor] + "\"?"; @@ -606,7 +585,7 @@ public class Sketch { options, options[0]); if (result == JOptionPane.YES_OPTION) { - if (current == code[0]) { + if (currentIndex == 0) { // need to unset all the modified flags, otherwise tries // to do a save on the handleNew() @@ -672,7 +651,7 @@ public class Sketch { // don't allow hide of the main code // TODO maybe gray out the menu on setCurrent(0) - if (current == code[0]) { + if (currentIndex == 0) { Base.showMessage("Can't do that", "You cannot hide the main " + ".pde file from a sketch\n"); @@ -933,57 +912,14 @@ public class Sketch { File newFile = new File(newFolder, newName + ".pde"); code[0].saveAs(newFile); - editor.handleOpenUnchecked(newFile.getPath()); + editor.handleOpenUnchecked(newFile.getPath(), + currentIndex, + editor.textarea.getSelectionStart(), + editor.textarea.getSelectionEnd(), + editor.textarea.getScrollPosition()); - /* - // copy the entire contents of the sketch folder - Base.copyDir(folder, newFolder); - - // change the references to the dir location in SketchCode files - for (int i = 0; i < codeCount; i++) { - code[i].file = new File(newFolder, code[i].file.getName()); - } - for (int i = 0; i < hiddenCount; i++) { - hidden[i].file = new File(newFolder, hidden[i].file.getName()); - } - - // remove the old sketch file from the new dir - code[0].file.delete(); - // name for the new main .pde file - code[0].file = new File(newFolder, newName + ".pde"); - code[0].name = newName; - // write the contents to the renamed file - // (this may be resaved if the code is modified) - code[0].modified = true; - //code[0].save(); - //System.out.println("modified is " + modified); - - // change the other paths - String oldName = name; - name = newName; - File oldFolder = folder; - folder = newFolder; - dataFolder = new File(folder, "data"); - codeFolder = new File(folder, "code"); - - // remove the 'applet', 'application', 'library' folders - // from the copied version. - // otherwise their .class and .jar files can cause conflicts. - Base.removeDir(new File(folder, "applet")); - Base.removeDir(new File(folder, "application")); - //Base.removeDir(new File(folder, "library")); - - // do a "save" - // this will take care of the unsaved changes in each of the tabs - save(); - - // get the changes into the sketchbook menu - //sketchbook.rebuildMenu(); - // done inside Editor instead - - // update the tabs for the name change - editor.header.repaint(); - */ + // Name changed, rebuild the sketch menus + editor.sketchbook.rebuildMenusAsync(); // let Editor know that the save was successful return true; @@ -1168,8 +1104,8 @@ public class Sketch { * */ public void setCurrent(int which) { - if (current == code[which]) { - //System.out.println("already current, ignoring"); + // if current is null, then this is the first setCurrent(0) + if ((currentIndex == which) && (current != null)) { return; } @@ -1182,6 +1118,7 @@ public class Sketch { } current = code[which]; + currentIndex = which; editor.setCode(current); //editor.setDocument(current.document, // current.selectionStart, current.selectionStop, @@ -1286,6 +1223,9 @@ public class Sketch { //handleOpen(sketch); //history.lastRecorded = historySaved; + // set current to null so that the tab gets updated + // http://dev.processing.org/bugs/show_bug.cgi?id=515 + current = null; // nuke previous files and settings, just get things loaded load(); } @@ -1746,7 +1686,12 @@ public class Sketch { // make sure the user didn't hide the sketch folder ensureExistence(); - current.program = editor.getText(); + // fix for issue posted on the board. make sure that the code + // is reloaded when exporting and an external editor is being used. + if (Preferences.getBoolean("editor.external")) { + // nuke previous files and settings + load(); + } zipFileContents = new Hashtable(); @@ -1773,6 +1718,7 @@ public class Sketch { /* int wide = PApplet.DEFAULT_WIDTH; int high = PApplet.DEFAULT_HEIGHT; + String renderer = ""; PatternMatcher matcher = new Perl5Matcher(); PatternCompiler compiler = new Perl5Compiler(); @@ -1785,20 +1731,26 @@ public class Sketch { // modified for 83 to match size(XXX, ddd so that it'll // properly handle size(200, 200) and size(200, 200, P3D) String sizing = - "[\\s\\;]size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+)"; + // match the renderer string as well + "[\\s\\;]size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+),?\\s*([^\\)]*)\\s*\\)"; + // match just the width and height + //"[\\s\\;]size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+)(.*)\\)"; Pattern pattern = compiler.compile(sizing); // adds a space at the beginning, in case size() is the very // first thing in the program (very common), since the regexp // needs to check for things in front of it. PatternMatcherInput input = - new PatternMatcherInput(" " + code[0].program); + new PatternMatcherInput(" " + scrubComments(code[0].program)); if (matcher.contains(input, pattern)) { MatchResult result = matcher.getMatch(); + try { wide = Integer.parseInt(result.group(1).toString()); high = Integer.parseInt(result.group(2).toString()); + renderer = result.group(3).toString(); //.trim(); + } catch (NumberFormatException e) { // found a reference to size, but it didn't // seem to contain numbers @@ -1865,45 +1817,6 @@ public class Sketch { if (is == null) { is = Base.getStream("applet.html"); } - BufferedReader reader = new BufferedReader(new InputStreamReader(is)); - - String line = null; - while ((line = reader.readLine()) != null) { - if (line.indexOf("@@") != -1) { - StringBuffer sb = new StringBuffer(line); - int index = 0; - while ((index = sb.indexOf("@@sketch@@")) != -1) { - sb.replace(index, index + "@@sketch@@".length(), - name); - } - while ((index = sb.indexOf("@@source@@")) != -1) { - sb.replace(index, index + "@@source@@".length(), - sources.toString()); - } - while ((index = sb.indexOf("@@archive@@")) != -1) { - sb.replace(index, index + "@@archive@@".length(), - name + ".jar"); - } - while ((index = sb.indexOf("@@width@@")) != -1) { - sb.replace(index, index + "@@width@@".length(), - String.valueOf(wide)); - } - while ((index = sb.indexOf("@@height@@")) != -1) { - sb.replace(index, index + "@@height@@".length(), - String.valueOf(high)); - } - while ((index = sb.indexOf("@@description@@")) != -1) { - sb.replace(index, index + "@@description@@".length(), - description); - } - line = sb.toString(); - } - ps.println(line); - } - - reader.close(); - ps.flush(); - ps.close(); // copy the loading gif to the applet String LOADING_IMAGE = "loading.gif"; @@ -1929,13 +1842,13 @@ public class Sketch { new FileOutputStream(new File(appletFolder, name + ".jar")); ZipOutputStream zos = new ZipOutputStream(zipOutputFile); ZipEntry entry; + archives.append(name + ".jar"); // add the manifest file addManifest(zos); // add the contents of the code folder to the jar - // unpacks all jar files - //File codeFolder = new File(folder, "code"); + // unpacks all jar files, unless multi jar files selected in prefs if (codeFolder.exists()) { String includes = Compiler.contentsToClassPath(codeFolder); packClassPathIntoZipFile(includes, zos); @@ -1980,7 +1893,18 @@ public class Sketch { } else if (exportFile.getName().toLowerCase().endsWith(".zip") || exportFile.getName().toLowerCase().endsWith(".jar")) { + if (separateJar) { + String exportFilename = exportFile.getName(); + Base.copyFile(exportFile, new File(appletFolder, exportFilename)); + if (renderer.equals("OPENGL") && + exportFilename.indexOf("natives") != -1) { + // don't add these to the archives list + } else { + archives.append("," + exportFilename); + } + } else { packClassPathIntoZipFile(exportFile.getAbsolutePath(), zos); + } } else { // just copy the file over.. prolly a .dll or something Base.copyFile(exportFile, @@ -1991,6 +1915,7 @@ public class Sketch { */ /* String bagelJar = "lib/core.jar"; packClassPathIntoZipFile(bagelJar, zos); + } // files to include from data directory // TODO this needs to be recursive @@ -2049,6 +1974,53 @@ public class Sketch { } + static public String scrubComments(String what) { + char p[] = what.toCharArray(); + + int index = 0; + while (index < p.length) { + // for any double slash comments, ignore until the end of the line + if ((p[index] == '/') && + (index < p.length - 1) && + (p[index+1] == '/')) { + p[index++] = ' '; + p[index++] = ' '; + while ((index < p.length) && + (p[index] != '\n')) { + p[index++] = ' '; + } + + // check to see if this is the start of a new multiline comment. + // if it is, then make sure it's actually terminated somewhere. + } else if ((p[index] == '/') && + (index < p.length - 1) && + (p[index+1] == '*')) { + p[index++] = ' '; + p[index++] = ' '; + boolean endOfRainbow = false; + while (index < p.length - 1) { + if ((p[index] == '*') && (p[index+1] == '/')) { + p[index++] = ' '; + p[index++] = ' '; + endOfRainbow = true; + break; + + } else { + index++; + } + } + if (!endOfRainbow) { + throw new RuntimeException("Missing the */ from the end of a " + + "/* comment */"); + } + } else { // any old character, move along + index++; + } + } + return new String(p); + } + + /** * Export to application. *

@@ -2135,7 +2107,6 @@ public class Sketch {
 
     for (int i = 0; i < pieces.length; i++) {
       if (pieces[i].length() == 0) continue;
-      //System.out.println("checking piece " + pieces[i]);
 
       // is it a jar file or directory?
       if (pieces[i].toLowerCase().endsWith(".jar") ||
@@ -2299,4 +2270,16 @@ public class Sketch {
   public String getMainFilePath() {
     return code[0].file.getAbsolutePath();
   }
+
+
+  public void prevCode() {
+    int prev = currentIndex - 1;
+    if (prev < 0) prev = codeCount-1;
+    setCurrent(prev);
+  }
+
+
+  public void nextCode() {
+    setCurrent((currentIndex + 1) % codeCount);
+  }
 }
diff --git a/app/Sketchbook.java b/app/Sketchbook.java
index c79096258..322ea9e01 100644
--- a/app/Sketchbook.java
+++ b/app/Sketchbook.java
@@ -130,6 +130,7 @@ public class Sketchbook {
 
       //System.out.println("resetting sketchbook path");
       File sketchbookFolder = Base.getDefaultSketchbookFolder();
+      //System.out.println("default is " + sketchbookFolder);
       Preferences.set("sketchbook.path",
                       sketchbookFolder.getAbsolutePath());
 
@@ -170,11 +171,8 @@ public class Sketchbook {
     if (noPrompt) prompt = false;
 
     if (prompt) {
-    //if (!startup) {
       // prompt for the filename and location for the new sketch
-
-      FileDialog fd = new FileDialog(editor, //new Frame(),
-                                     //"Create new sketch named",
+      FileDialog fd = new FileDialog(editor,
                                      "Create sketch folder named:",
                                      FileDialog.SAVE);
       fd.setDirectory(getSketchbookPath());
@@ -228,7 +226,7 @@ public class Sketchbook {
     }
 
     // make a note of a newly added sketch in the sketchbook menu
-    rebuildMenus();
+    rebuildMenusAsync();
 
     // now open it up
     //handleOpen(newbieName, newbieFile, newbieDir);
@@ -257,10 +255,25 @@ public class Sketchbook {
 
 
   /**
-   * Java classes are pretty limited about what you can use
-   * for their naming. This helper function replaces everything
-   * but A-Z, a-z, and 0-9 with underscores. Also disallows
-   * starting the sketch name with a digit.
+   * Return true if the name is valid for a Processing sketch.
+   */
+  static public boolean isSanitary(String name) {
+    return sanitizedName(name).equals(name);
+  }
+
+
+  /**
+   * Produce a sanitized name that fits our standards for likely to work.
+   * 

+ * Java classes have a wider range of names that are technically allowed + * (supposedly any Unicode name) than what we support. The reason for + * going more narrow is to avoid situations with text encodings and + * converting during the process of moving files between operating + * systems, i.e. uploading from a Windows machine to a Linux server, + * or reading a FAT32 partition in OS X and using a thumb drive. + *

+ * This helper function replaces everything but A-Z, a-z, and 0-9 with + * underscores. Also disallows starting the sketch name with a digit. */ static public String sanitizedName(String origName) { char c[] = origName.toCharArray(); @@ -280,7 +293,12 @@ public class Sketchbook { buffer.append('_'); } } - // let's not be ridiculous about the length of filenames + // let's not be ridiculous about the length of filenames. + // in fact, Mac OS 9 can handle 255 chars, though it can't really + // deal with filenames longer than 31 chars in the Finder. + // but limiting to that for sketches would mean setting the + // upper-bound on the character limit here to 25 characters + // (to handle the base name + ".class") if (buffer.length() > 63) { buffer.setLength(63); } @@ -290,12 +308,12 @@ public class Sketchbook { public String handleOpen() { // swing's file choosers are ass ugly, so we use the - // native (awt peered) dialogs instead + // native (awt peered) dialogs where possible FileDialog fd = new FileDialog(editor, //new Frame(), "Open a Processing sketch...", FileDialog.LOAD); //fd.setDirectory(Preferences.get("sketchbook.path")); - fd.setDirectory(getSketchbookPath()); + //fd.setDirectory(getSketchbookPath()); // only show .pde files as eligible bachelors // TODO this doesn't seem to ever be used. AWESOME. @@ -324,6 +342,23 @@ public class Sketchbook { } + /** + * Asynchronous version of menu rebuild to be used on 'new' and 'save', + * to prevent the interface from locking up until the menus are done. + */ + public void rebuildMenusAsync() { + // disabling the async option for actual release, this hasn't been tested + /* + SwingUtilities.invokeLater(new Runnable() { + public void run() { + rebuildMenus(); + } + }); + */ + rebuildMenus(); + } + + /** * Rebuild the menu full of sketches based on the * contents of the sketchbook. @@ -333,6 +368,7 @@ public class Sketchbook { * the menu will disappear from its original location. */ public void rebuildMenus() { + //EditorConsole.systemOut.println("rebuilding menus"); try { // rebuild file/open and the toolbar popup menus buildMenu(openMenu); @@ -359,6 +395,7 @@ public class Sketchbook { "sketchbook menu. Things might get a little\n" + "kooky around here.", e); } + //EditorConsole.systemOut.println("done rebuilding menus"); } @@ -444,25 +481,8 @@ public class Sketchbook { if (list == null) return false; // alphabetize list, since it's not always alpha order - // use cheapie bubble-style sort which should be fine - // since not a tone of files, and things will mostly be sorted - // or may be completely sorted already by the os - for (int i = 0; i < list.length; i++) { - int who = i; - for (int j = i+1; j < list.length; j++) { - if (list[j].compareToIgnoreCase(list[who]) < 0) { - who = j; // this guy is earlier in the alphabet - } - } - if (who != i) { // swap with someone if changes made - String temp = list[who]; - list[who] = list[i]; - list[i] = temp; - } - } - - //SketchbookMenuListener listener = - //new SketchbookMenuListener(folder.getAbsolutePath()); + // replaced hella slow bubble sort with this feller for 0093 + Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -477,18 +497,23 @@ public class Sketchbook { list[i].equals("CVS")) continue; File subfolder = new File(folder, list[i]); - File lib = new File(subfolder, "library"); + if (!subfolder.isDirectory()) continue; + File entry = new File(subfolder, list[i] + ".pde"); // if a .pde file of the same prefix as the folder exists.. if (entry.exists()) { - String sanityCheck = sanitizedName(list[i]); - if (!sanityCheck.equals(list[i])) { + //String sanityCheck = sanitizedName(list[i]); + //if (!sanityCheck.equals(list[i])) { + if (!Sketchbook.isSanitary(list[i])) { if (!builtOnce) { - String mess = + String complaining = "The sketch \"" + list[i] + "\" cannot be used.\n" + - "Sketch names must contain only basic letters and numbers.\n" + - "(ascii only and no spaces, and it cannot start with a number)"; - Base.showMessage("Ignoring bad sketch name", mess); + "Sketch names must contain only basic letters and numbers\n" + + "(ASCII-only with no spaces, " + + "and it cannot start with a number).\n" + + "To get rid of this message, remove the sketch from\n" + + entry.getAbsolutePath(); + Base.showMessage("Ignoring sketch with bad name", complaining); } continue; } @@ -499,7 +524,8 @@ public class Sketchbook { menu.add(item); ifound = true; - } else { // might contain other dirs, get recursive + } else { + // not a sketch folder, but maybe a subfolder containing sketches JMenu submenu = new JMenu(list[i]); // needs to be separate var // otherwise would set ifound to false @@ -523,22 +549,8 @@ public class Sketchbook { if (list == null) return false; // alphabetize list, since it's not always alpha order - // use cheapie bubble-style sort which should be fine - // since not a tone of files, and things will mostly be sorted - // or may be completely sorted already by the os - for (int i = 0; i < list.length; i++) { - int who = i; - for (int j = i+1; j < list.length; j++) { - if (list[j].compareToIgnoreCase(list[who]) < 0) { - who = j; // this guy is earlier in the alphabet - } - } - if (who != i) { // swap with someone if changes made - String temp = list[who]; - list[who] = list[i]; - list[i] = temp; - } - } + // replaced hella slow bubble sort with this feller for 0093 + Arrays.sort(list, String.CASE_INSENSITIVE_ORDER); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { @@ -591,6 +603,8 @@ public class Sketchbook { String packages[] = Compiler.packageListFromClassPath(libraryClassPath); for (int k = 0; k < packages.length; k++) { + //System.out.println(packages[k] + " -> " + exported); + //String already = (String) importToLibraryTable.get(packages[k]); importToLibraryTable.put(packages[k], exported); } */ @@ -600,11 +614,10 @@ public class Sketchbook { menu.add(item); ifound = true; - } else { // might contain other dirs, get recursive + } else { // not a library, but is still a folder, so recurse JMenu submenu = new JMenu(list[i]); - // needs to be separate var - // otherwise would set ifound to false - boolean found = addLibraries(submenu, subfolder); //, false); + // needs to be separate var, otherwise would set ifound to false + boolean found = addLibraries(submenu, subfolder); if (found) { menu.add(submenu); ifound = true; diff --git a/app/preproc/PdePreprocessor.java b/app/preproc/PdePreprocessor.java index 5690e3298..d20f17be1 100755 --- a/app/preproc/PdePreprocessor.java +++ b/app/preproc/PdePreprocessor.java @@ -30,7 +30,7 @@ package processing.app.preproc; import processing.app.*; -//import processing.core.*; +import processing.core.*; import java.io.*; @@ -99,6 +99,7 @@ public class PdePreprocessor { /** * preprocesses a pde file and write out a java file + * @param pretty true if should also space out/indent lines * @return the classname of the exported Java */ //public String write(String program, String buildPath, String name, @@ -109,10 +110,19 @@ public class PdePreprocessor { throws java.lang.Exception { // if the program ends with no CR or LF an OutOfMemoryError will happen. // not gonna track down the bug now, so here's a hack for it: - if ((program.length() > 0) && - program.charAt(program.length()-1) != '\n') { + // bug filed at http://dev.processing.org/bugs/show_bug.cgi?id=5 + //if ((program.length() > 0) && + //program.charAt(program.length()-1) != '\n') { program += "\n"; - } + //} + + // if the program ends with an unterminated multiline comment, + // an OutOfMemoryError or NullPointerException will happen. + // again, not gonna bother tracking this down, but here's a hack. + // http://dev.processing.org/bugs/show_bug.cgi?id=16 + Sketch.scrubComments(program); + // this returns the scrubbed version, but more important for this + // function, it'll check to see if there are errors with the comments. if (Preferences.getBoolean("preproc.substitute_unicode")) { // check for non-ascii chars (these will be/must be in unicode format) @@ -193,26 +203,6 @@ public class PdePreprocessor { extraImports = new String[imports.size()]; imports.copyInto(extraImports); - // if using opengl, add it to the special imports - /* - if (Preferences.get("renderer").equals("opengl")) { - extraImports = new String[imports.size() + 1]; - imports.copyInto(extraImports); - extraImports[extraImports.length - 1] = "processing.opengl.*"; - } - */ - - /* - if (codeFolderPackages != null) { - extraImports = new String[importsCount + codeFolderPackages.length]; - imports.copyInto(extraImports); - for (int i = 0; i < codeFolderPackages.length; i++) { - extraImports[importsCount + i] = codeFolderPackages[i] + ".*"; - } - codeFolderImports = null; - } - */ - if (codeFolderPackages != null) { codeFolderImports = new String[codeFolderPackages.length]; for (int i = 0; i < codeFolderPackages.length; i++) { diff --git a/app/syntax/InputHandler.java b/app/syntax/InputHandler.java index 3c2186792..6963d2dad 100644 --- a/app/syntax/InputHandler.java +++ b/app/syntax/InputHandler.java @@ -136,9 +136,10 @@ public abstract class InputHandler extends KeyAdapter { String name = (String)en.nextElement(); ActionListener _listener = getAction(name); - if(_listener == listener) + if(_listener == listener) { return name; } + } return null; } @@ -180,7 +181,6 @@ public abstract class InputHandler extends KeyAdapter /** * Grabs the next key typed event and invokes the specified * action with the key as a the action command. - * @param action The action */ public void grabNextKeyStroke(ActionListener listener) { @@ -743,19 +743,32 @@ public abstract class InputHandler extends KeyAdapter { JEditTextArea textArea = getTextArea(evt); int caret = textArea.getCaretPosition(); + if(caret == textArea.getDocumentLength()) { + if (textArea.getSelectionStart() != + textArea.getSelectionEnd()) { + // just move to the end of the selection + textArea.select(caret, caret); + } else { + // beep at the user for being annoying textArea.getToolkit().beep(); - return; } - if(select) - textArea.select(textArea.getMarkPosition(), - caret + 1); - else + } else if (select) { + textArea.select(textArea.getMarkPosition(), caret+1); + + } else { + int start = textArea.getSelectionStart(); + int end = textArea.getSelectionEnd(); + if (start != end) { + textArea.select(end, end); + } else { textArea.setCaretPosition(caret + 1); } } + } + } public static class next_line implements ActionListener { @@ -774,7 +787,13 @@ public abstract class InputHandler extends KeyAdapter if(line == textArea.getLineCount() - 1) { - textArea.getToolkit().beep(); + //textArea.getToolkit().beep(); + int doc = textArea.getDocumentLength(); + if (select) { + textArea.select(textArea.getMarkPosition(), doc); + } else { + textArea.setCaretPosition(doc); + } return; } @@ -901,13 +920,19 @@ public abstract class InputHandler extends KeyAdapter return; } - if(select) - textArea.select(textArea.getMarkPosition(), - caret - 1); - else + if (select) { + textArea.select(textArea.getMarkPosition(), caret-1); + } else { + int start = textArea.getSelectionStart(); + int end = textArea.getSelectionEnd(); + if (start != end) { + textArea.select(start, start); + } else { textArea.setCaretPosition(caret - 1); } } + } + } public static class prev_line implements ActionListener { @@ -926,7 +951,14 @@ public abstract class InputHandler extends KeyAdapter if(line == 0) { - textArea.getToolkit().beep(); + if (select) { + if (textArea.getSelectionStart() != 0) { + textArea.select(textArea.getMarkPosition(), 0); + } + } else { + textArea.setCaretPosition(0); + } + //textArea.getToolkit().beep(); return; } diff --git a/app/syntax/JEditTextArea.java b/app/syntax/JEditTextArea.java index ba367d360..5b45b4e40 100644 --- a/app/syntax/JEditTextArea.java +++ b/app/syntax/JEditTextArea.java @@ -888,22 +888,20 @@ public class JEditTextArea extends JComponent */ public void setText(String text) { - try - { + try { document.beginCompoundEdit(); document.remove(0,document.getLength()); document.insertString(0,text,null); - } - catch(BadLocationException bl) - { + + } catch (BadLocationException bl) { bl.printStackTrace(); - } - finally - { + + } finally { document.endCompoundEdit(); } } + /** * Returns the specified substring of the document. * @param start The start offset @@ -1502,7 +1500,7 @@ public class JEditTextArea extends JComponent /** * Sets if the selection should be rectangular. - * @param overwrite True if the selection should be rectangular, + * @param rectSelect True if the selection should be rectangular, * false otherwise. */ public final void setSelectionRectangular(boolean rectSelect) @@ -1644,6 +1642,7 @@ public class JEditTextArea extends JComponent switch(evt.getID()) { case KeyEvent.KEY_TYPED: + //if ((editorListener != null) && !editorListener.keyTyped(evt)) { inputHandler.keyTyped(evt); break; case KeyEvent.KEY_PRESSED: @@ -2145,21 +2144,52 @@ public class JEditTextArea extends JComponent bl.printStackTrace(); } - // Ok, it's not a bracket... select the word - String lineText = getLineText(line); - char ch = lineText.charAt(Math.max(0,offset - 1)); - String noWordSep = (String)document.getProperty("noWordSep"); if(noWordSep == null) noWordSep = ""; - // If the user clicked on a non-letter char, - // we select the surrounding non-letters - boolean selectNoLetter = (!Character - .isLetterOrDigit(ch) - && noWordSep.indexOf(ch) == -1); + // Ok, it's not a bracket... select the word + String lineText = getLineText(line); int wordStart = 0; + int wordEnd = lineText.length(); + + char ch = lineText.charAt(Math.max(0,offset - 1)); + + // special case for whitespace (fry 0122, bug #348) + // this is really nasty.. turns out that double-clicking any non-letter + // or digit char gets lumped together.. sooo, this quickly gets messy, + // because really it needs to check whether the chars are of the same + // type.. so a double space or double - might be grouped together, + // but what about a +=1? do + and - get grouped but not the 1? blech, + // coming back to this later. it's not a difficult fix, just a + // time-consuming one to track down all the proper cases. + /* + if (ch == ' ') { + //System.out.println("yeehaa"); + + for(int i = offset - 1; i >= 0; i--) { + if (lineText.charAt(i) == ' ') { + wordStart = i; + } else { + break; + } + } + for(int i = offset; i < lineText.length(); i++) { + if (lineText.charAt(i) == ' ') { + wordEnd = i + 1; + } else { + break; + } + } + + } else { + */ + + // If the user clicked on a non-letter char, + // we select the surrounding non-letters + boolean selectNoLetter = (!Character.isLetterOrDigit(ch) + && noWordSep.indexOf(ch) == -1); for(int i = offset - 1; i >= 0; i--) { ch = lineText.charAt(i); @@ -2170,18 +2200,15 @@ public class JEditTextArea extends JComponent } } - int wordEnd = lineText.length(); - for(int i = offset; i < lineText.length(); i++) - { + for(int i = offset; i < lineText.length(); i++) { ch = lineText.charAt(i); - if(selectNoLetter ^ (!Character - .isLetterOrDigit(ch) && - noWordSep.indexOf(ch) == -1)) - { + if(selectNoLetter ^ (!Character.isLetterOrDigit(ch) && + noWordSep.indexOf(ch) == -1)) { wordEnd = i; break; } } + //} int lineStart = getLineStartOffset(line); select(lineStart + wordStart,lineStart + wordEnd); diff --git a/app/syntax/KeywordMap.java b/app/syntax/KeywordMap.java index c19b4a777..d0d834adf 100644 --- a/app/syntax/KeywordMap.java +++ b/app/syntax/KeywordMap.java @@ -76,7 +76,7 @@ public class KeywordMap /** * Adds a key-value mapping. * @param keyword The key - * @Param id The value + * @param id The value */ public void add(String keyword, byte id) { diff --git a/app/syntax/PdeKeywords.java b/app/syntax/PdeKeywords.java index cba279213..8dec16b6c 100644 --- a/app/syntax/PdeKeywords.java +++ b/app/syntax/PdeKeywords.java @@ -76,7 +76,7 @@ public class PdeKeywords extends CTokenMarker { } } - String pieces[] = Base.split(line, '\t'); + String pieces[] = processing.core.PApplet.split(line, '\t'); if (pieces.length >= 2) { //int tab = line.indexOf('\t'); // any line with no tab is ignored diff --git a/app/syntax/PdeTextAreaDefaults.java b/app/syntax/PdeTextAreaDefaults.java index e9caca886..e85dad955 100644 --- a/app/syntax/PdeTextAreaDefaults.java +++ b/app/syntax/PdeTextAreaDefaults.java @@ -2,9 +2,9 @@ /* PdeTextAreaDefaults - grabs font/color settings for the editor - Part of the Processing project - http://Proce55ing.net + Part of the Processing project - http://processing.org - Except where noted, code is written by Ben Fry + Copyright (c) 2004-06 Ben Fry and Casey Reas Copyright (c) 2001-03 Massachusetts Institute of Technology This program is free software; you can redistribute it and/or modify @@ -32,41 +32,65 @@ public class PdeTextAreaDefaults extends TextAreaDefaults { public PdeTextAreaDefaults() { inputHandler = new DefaultInputHandler(); - inputHandler.addDefaultKeyBindings(); + //inputHandler.addDefaultKeyBindings(); // 0122 // use option on mac for things that are ctrl on windows/linux String mod = Base.isMacOS() ? "A" : "C"; - inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.BACKSPACE); - inputHandler.addKeyBinding("S+DELETE", InputHandler.DELETE); + // right now, ctrl-up/down is select up/down, but mod should be + // used instead, because the mac expects it to be option(alt) inputHandler.addKeyBinding("BACK_SPACE", InputHandler.BACKSPACE); - inputHandler.addKeyBinding("C+BACK_SPACE", InputHandler.BACKSPACE_WORD); inputHandler.addKeyBinding("DELETE", InputHandler.DELETE); - inputHandler.addKeyBinding("C+DELETE", InputHandler.DELETE_WORD); - inputHandler.addKeyBinding("ENTER", InputHandler.INSERT_BREAK); - inputHandler.addKeyBinding("TAB", InputHandler.INSERT_TAB); + //inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.BACKSPACE); + // for 0122, shift-backspace is delete + inputHandler.addKeyBinding("S+BACK_SPACE", InputHandler.DELETE); + inputHandler.addKeyBinding("S+DELETE", InputHandler.DELETE); + + // the following two were changing for 0122 for better mac/pc compatability + inputHandler.addKeyBinding(mod+"+BACK_SPACE", InputHandler.BACKSPACE_WORD); + inputHandler.addKeyBinding(mod+"+DELETE", InputHandler.DELETE_WORD); + + // handled by listener, don't bother here + //inputHandler.addKeyBinding("ENTER", InputHandler.INSERT_BREAK); + //inputHandler.addKeyBinding("TAB", InputHandler.INSERT_TAB); inputHandler.addKeyBinding("INSERT", InputHandler.OVERWRITE); - inputHandler.addKeyBinding("C+\\", InputHandler.TOGGLE_RECT); + // disabling for 0122, not sure what this does + //inputHandler.addKeyBinding("C+\\", InputHandler.TOGGLE_RECT); - // beginning and ending of the current line + // for 0122, these have been changed for better compatability + // HOME and END now mean the beginning/end of the document + if (Base.isMacOS()) { + inputHandler.addKeyBinding("HOME", InputHandler.DOCUMENT_HOME); + inputHandler.addKeyBinding("END", InputHandler.DOCUMENT_END); + inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_DOC_HOME); + inputHandler.addKeyBinding("S+END", InputHandler.SELECT_DOC_END); + } else { + // for 0123 added the proper windows defaults inputHandler.addKeyBinding("HOME", InputHandler.HOME); inputHandler.addKeyBinding("END", InputHandler.END); + inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_HOME); + inputHandler.addKeyBinding("S+END", InputHandler.SELECT_END); + inputHandler.addKeyBinding("C+HOME", InputHandler.DOCUMENT_HOME); + inputHandler.addKeyBinding("C+END", InputHandler.DOCUMENT_END); + inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_DOC_HOME); + inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_DOC_END); + } if (Base.isMacOS()) { inputHandler.addKeyBinding("M+LEFT", InputHandler.HOME); inputHandler.addKeyBinding("M+RIGHT", InputHandler.END); + inputHandler.addKeyBinding("MS+LEFT", InputHandler.SELECT_HOME); // 0122 + inputHandler.addKeyBinding("MS+RIGHT", InputHandler.SELECT_END); // 0122 + } else { + inputHandler.addKeyBinding("C+LEFT", InputHandler.HOME); // 0122 + inputHandler.addKeyBinding("C+RIGHT", InputHandler.END); // 0122 + inputHandler.addKeyBinding("CS+HOME", InputHandler.SELECT_HOME); // 0122 + inputHandler.addKeyBinding("CS+END", InputHandler.SELECT_END); // 0122 } - inputHandler.addKeyBinding("S+HOME", InputHandler.SELECT_HOME); - inputHandler.addKeyBinding("S+END", InputHandler.SELECT_END); - inputHandler.addKeyBinding(mod + "+HOME", InputHandler.DOCUMENT_HOME); - inputHandler.addKeyBinding(mod + "+END", InputHandler.DOCUMENT_END); - inputHandler.addKeyBinding(mod + "S+HOME", InputHandler.SELECT_DOC_HOME); - inputHandler.addKeyBinding(mod + "S+END", InputHandler.SELECT_DOC_END); - inputHandler.addKeyBinding("PAGE_UP", InputHandler.PREV_PAGE); inputHandler.addKeyBinding("PAGE_DOWN", InputHandler.NEXT_PAGE); inputHandler.addKeyBinding("S+PAGE_UP", InputHandler.SELECT_PREV_PAGE); @@ -80,6 +104,7 @@ public class PdeTextAreaDefaults extends TextAreaDefaults { inputHandler.addKeyBinding("S+RIGHT", InputHandler.SELECT_NEXT_CHAR); inputHandler.addKeyBinding(mod + "+RIGHT", InputHandler.NEXT_WORD); inputHandler.addKeyBinding(mod + "S+RIGHT", InputHandler.SELECT_NEXT_WORD); + inputHandler.addKeyBinding("UP", InputHandler.PREV_LINE); inputHandler.addKeyBinding(mod + "+UP", InputHandler.PREV_LINE); // p5 inputHandler.addKeyBinding("S+UP", InputHandler.SELECT_PREV_LINE); @@ -87,6 +112,11 @@ public class PdeTextAreaDefaults extends TextAreaDefaults { inputHandler.addKeyBinding(mod + "+DOWN", InputHandler.NEXT_LINE); // p5 inputHandler.addKeyBinding("S+DOWN", InputHandler.SELECT_NEXT_LINE); + inputHandler.addKeyBinding("MS+UP", InputHandler.SELECT_DOC_HOME); + inputHandler.addKeyBinding("CS+UP", InputHandler.SELECT_DOC_HOME); + inputHandler.addKeyBinding("MS+DOWN", InputHandler.SELECT_DOC_END); + inputHandler.addKeyBinding("CS+DOWN", InputHandler.SELECT_DOC_END); + inputHandler.addKeyBinding(mod + "+ENTER", InputHandler.REPEAT); document = new SyntaxDocument(); diff --git a/app/syntax/TextAreaPainter.java b/app/syntax/TextAreaPainter.java index b1e4ccc82..80487b820 100644 --- a/app/syntax/TextAreaPainter.java +++ b/app/syntax/TextAreaPainter.java @@ -18,6 +18,7 @@ import javax.swing.text.*; import javax.swing.JComponent; import java.awt.event.MouseEvent; import java.awt.*; +import java.awt.print.*; /** * The text area repaint manager. It performs double buffering and paints @@ -25,8 +26,12 @@ import java.awt.*; * @author Slava Pestov * @version $Id$ */ -public class TextAreaPainter extends JComponent implements TabExpander +public class TextAreaPainter extends JComponent +implements TabExpander, Printable { + /** True if inside printing, will handle disabling the highlight */ + boolean printing; + /** * Creates a new repaint manager. This should be not be called * directly. @@ -405,6 +410,32 @@ public class TextAreaPainter extends JComponent implements TabExpander } } + + public int print(Graphics g, PageFormat pageFormat, int pageIndex) { + int lineHeight = fm.getHeight(); + int linesPerPage = (int) (pageFormat.getImageableHeight() / lineHeight); + int lineCount = textArea.getLineCount(); + int lastPage = lineCount / linesPerPage; + + if (pageIndex > lastPage) { + return NO_SUCH_PAGE; + + } else { + Graphics2D g2d = (Graphics2D)g; + TokenMarker tokenMarker = textArea.getDocument().getTokenMarker(); + int firstLine = pageIndex*linesPerPage; + g2d.translate(Math.max(54, pageFormat.getImageableX()), + pageFormat.getImageableY() - firstLine*lineHeight); + printing = true; + for (int line = firstLine; line < firstLine + linesPerPage; line++) { + paintLine(g2d, tokenMarker, line, 0); + } + printing = false; + return PAGE_EXISTS; + } + } + + /** * Marks a line as needing a repaint. * @param line The line to invalidate @@ -600,6 +631,7 @@ public class TextAreaPainter extends JComponent implements TabExpander protected void paintHighlight(Graphics gfx, int line, int y) { + if (!printing) { if (line >= textArea.getSelectionStartLine() && line <= textArea.getSelectionEndLine()) paintLineHighlight(gfx,line,y); @@ -613,6 +645,7 @@ public class TextAreaPainter extends JComponent implements TabExpander if (line == textArea.getCaretLine()) paintCaret(gfx,line,y); } + } protected void paintLineHighlight(Graphics gfx, int line, int y) { diff --git a/app/tools/Archiver.java b/app/tools/Archiver.java index facf49dd5..0c90e5e69 100755 --- a/app/tools/Archiver.java +++ b/app/tools/Archiver.java @@ -25,6 +25,7 @@ package processing.app.tools; import processing.app.*; +import java.awt.FileDialog; import java.io.*; import java.text.*; import java.util.*; @@ -35,7 +36,7 @@ public class Archiver { Editor editor; // someday these will be settable - boolean useDate = true; //false; + boolean useDate; int digits = 3; NumberFormat numberFormat; @@ -79,6 +80,9 @@ public class Archiver { String namely = null; int index = 0; do { + // only use the date if the sketch name isn't the default name + useDate = !name.startsWith("sketch_"); + if (useDate) { String purty = dateFormat.format(new Date()); String stamp = purty + ((char) ('a' + index)); @@ -93,6 +97,20 @@ public class Archiver { index++; } while (newbie.exists()); + // open up a prompt for where to save this fella + FileDialog fd = + new FileDialog(editor, "Archive sketch as:", FileDialog.SAVE); + fd.setDirectory(parent.getAbsolutePath()); + fd.setFile(newbie.getName()); + fd.show(); + + String directory = fd.getDirectory(); + String filename = fd.getFile(); + + // only write the file if not canceled + if (filename != null) { + newbie = new File(directory, filename); + try { //System.out.println(newbie); FileOutputStream zipOutputFile = new FileOutputStream(newbie); @@ -110,6 +128,9 @@ public class Archiver { } catch (IOException e) { e.printStackTrace(); } + } else { + editor.message("Archive sketch canceled."); + } } diff --git a/app/tools/AutoFormat.java b/app/tools/AutoFormat.java index a24bc6021..8d95c1645 100644 --- a/app/tools/AutoFormat.java +++ b/app/tools/AutoFormat.java @@ -24,7 +24,7 @@ package processing.app.tools; import processing.app.*; -//import processing.core.*; +import processing.core.*; import java.io.*; import java.util.StringTokenizer; @@ -915,26 +915,25 @@ public class AutoFormat { if (formattedText.equals(originalText)) { editor.message("No changes necessary for Auto Format."); - } else { - // replace with new bootiful text - // selectionEnd hopefully at least in the neighborhood - editor.setText(formattedText, selectionEnd, selectionEnd); - editor.sketch.setModified(true); - + } else if (paren != 0) { // warn user if there are too many parens in either direction - if (paren != 0) { - editor.error("Warning: Too many " + + editor.error("Auto Format Canceled: Too many " + ((paren < 0) ? "right" : "left") + " parentheses."); } else if (c_level != 0) { // check braces only if parens are ok - editor.error("Warning: Too many " + + editor.error("Auto Format Canceled: Too many " + ((c_level < 0) ? "right" : "left") + " curly braces."); + } else { + // replace with new bootiful text + // selectionEnd hopefully at least in the neighborhood + editor.setText(formattedText, selectionEnd, selectionEnd); + editor.sketch.setModified(true); + // mark as finished editor.message("Auto Format finished."); } - } } catch (Exception e) { editor.error(e); diff --git a/app/tools/DiscourseFormat.java b/app/tools/DiscourseFormat.java new file mode 100644 index 000000000..23e90ab1e --- /dev/null +++ b/app/tools/DiscourseFormat.java @@ -0,0 +1,313 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2005-06 Ignacio Manuel González Moreta + Copyright (c) 2006 Ben Fry and Casey Reas + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +package processing.app.tools; + +import java.awt.*; +import java.awt.datatransfer.*; +import java.awt.event.*; +import javax.swing.*; +import javax.swing.text.Segment; + +import processing.app.*; +import processing.app.syntax.*; +import processing.core.PApplet; + +/** + * Format for Discourse Tool + *

+ * Original code by owd. + * Revised and updated for revision 0108 by Ben Fry (10 March 2006). + * This code will later be removed but is included with release 0108+ + * while features for the "Tools" menu are in testing. + *

+ * Updated for 0122 to simply copy the code directly to the clipboard, + * rather than opening a new window. + *

+ * Notes from the original source: + * Discourse.java This is a dirty-mix source. + * NOTE that: No macs and no keyboard. Unreliable source. + * Only format processing code using fontMetrics. + * It works under my windows XP + PentiumIV + Processing 0091. + */ +public class DiscourseFormat { + + //static final String WINDOW_TITLE = "Format for Discourse by owd"; + + // p5 icon for the window + //static Image icon; + + Editor editor; + //JEditTextArea textarea; + + // JTextArea of the actual Editor + JEditTextArea parent; + + //JFrame frame; + + /** + * Creates a new window with the formated (YaBB tags) sketchcode + * from the actual Processing Tab ready to send to the processing discourse + * web (copy & paste) + */ + public DiscourseFormat(Editor editor) { + this.editor = editor; + this.parent = editor.textarea; + + /* + textarea = new JEditTextArea(new PdeTextAreaDefaults()); + textarea.setRightClickPopup(new DiscourseTextAreaPopup()); + textarea.setTokenMarker(new PdeKeywords()); + textarea.setHorizontalOffset(6); + + textarea.setEditable(false); + + // Create and set up the window. + frame = new JFrame(WINDOW_TITLE); + frame.setSize(500, 500); + + // set the window icon + try { + icon = Base.getImage("icon.gif", frame); + frame.setIconImage(icon); + } catch (Exception e) { } // fail silently, no big whup + frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + + Container pain = frame.getContentPane(); + pain.setLayout(new BorderLayout()); + pain.add(textarea, BorderLayout.CENTER); + + frame.setResizable(true); + + frame.pack(); + frame.setLocation(100, 100); + //frame.setVisible(true); + */ + } + + + public void show() { + // Format and render sketchcode + + // [code] tag cancels other tags, using [quote] + StringBuffer cf = new StringBuffer("[quote] \n \n"); + + // Line by line + for (int i = 0; i < parent.getLineCount(); i++) { + cf.append(formatCode(i)); + } + + cf.append("\n [/quote]"); + + /* + // Send the text to the textarea + textarea.setText(cf.toString()); + textarea.select(0, 0); + + frame.show(); + */ + + StringSelection formatted = new StringSelection(cf.toString()); + Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard(); + clipboard.setContents(formatted, new ClipboardOwner() { + public void lostOwnership(Clipboard clipboard, Transferable contents) { + // i don't care about ownership + } + }); + + editor.message("Discourse-formatted code has been " + + "copied to the clipboard."); + } + + + // A terrible headache... + public String formatCode(int line) { + StringBuffer cf = new StringBuffer(); + + // Segment + Segment lineSegment = new Segment(); + + TextAreaPainter painter = parent.getPainter(); + TokenMarker tokenMarker = parent.getTokenMarker(); + + // Use painter's cached info for speed + FontMetrics fm = painter.getFontMetrics(); + + // get line text from parent textarea + parent.getLineText(line, lineSegment); + + char[] segmentArray = lineSegment.array; + int limit = lineSegment.getEndIndex(); + int segmentOffset = lineSegment.offset; + int segmentCount = lineSegment.count; + int width = 0; //parent.getHorizontalOffset(); + + int x = 0; //parent.getHorizontalOffset(); + + // If syntax coloring is disabled, do simple translation + if (tokenMarker == null) { + for (int j = 0; j < segmentCount; j++) { + char c = segmentArray[j + segmentOffset]; + cf = cf.append(c); //concat(character(c)); + int charWidth; + if (c == '\t') { + charWidth = (int) painter.nextTabStop(width, j) - width; + } else { + charWidth = fm.charWidth(c); + } + width += charWidth; + } + + } else { + // If syntax coloring is enabled, we have to do this + // because tokens can vary in width + Token tokens; + if ((painter.getCurrentLineIndex() == line) && + (painter.getCurrentLineTokens() != null)) { + tokens = painter.getCurrentLineTokens(); + + } else { + painter.setCurrentLineIndex(line); + //painter.currentLineIndex = line; + painter.setCurrentLineTokens(tokenMarker.markTokens(lineSegment, line)); + tokens = painter.getCurrentLineTokens(); + } + + int offset = 0; + Toolkit toolkit = painter.getToolkit(); + Font defaultFont = painter.getFont(); + SyntaxStyle[] styles = painter.getStyles(); + + for (;;) { + byte id = tokens.id; + if (id == Token.END) { + char c = segmentArray[segmentOffset + offset]; + if (segmentOffset + offset < limit) { + cf.append(c); + } else { + cf.append('\n'); + } + return cf.toString(); + } + if (id == Token.NULL) { + fm = painter.getFontMetrics(); + } else { + // Place open tags [] + //cf.append("[color=" + color() + "]"); + cf.append("[color=#"); + cf.append(PApplet.hex(styles[id].getColor().getRGB() & 0xFFFFFF, 6)); + cf.append("]"); + + if (styles[id].isBold()) + cf.append("[b]"); + + fm = styles[id].getFontMetrics(defaultFont); + } + int length = tokens.length; + + for (int j = 0; j < length; j++) { + char c = segmentArray[segmentOffset + offset + j]; + cf.append(c); + // Place close tags [/] + if (j == (length - 1) && id != Token.NULL && styles[id].isBold()) + cf.append("[/b]"); + if (j == (length - 1) && id != Token.NULL) + cf.append("[/color]"); + int charWidth; + if (c == '\t') { + charWidth = (int) painter + .nextTabStop(width, offset + j) + - width; + } else { + charWidth = fm.charWidth(c); + } + width += charWidth; + } + offset += length; + tokens = tokens.next; + } + } + return cf.toString(); + } + + + /** + * Returns the discourse popup menu. Another features can be added: format + * selected text with a determinated tag (I'm thinking about [url]selected + * text[/url]) + */ + /* + class DiscourseTextAreaPopup extends JPopupMenu { + JMenuItem copyItem; + + public DiscourseTextAreaPopup() { + JMenuItem item; + + copyItem = new JMenuItem("Copy"); + copyItem.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.copy(); + } + }); + this.add(copyItem); + + item = new JMenuItem("Select All"); + item.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + textarea.selectAll(); + } + }); + this.add(item); + } + + // if no text is selected, disable copy menu item + public void show(Component component, int x, int y) { + if (textarea.isSelectionActive()) { + copyItem.setEnabled(true); + + } else { + copyItem.setEnabled(false); + } + super.show(component, x, y); + } + } + */ + + + /* + // A false listener (use the mouse) + public class DiscourseListener { + + public DiscourseListener(JEditTextArea thisTextarea) { + // I'm a... I know this gives peoblems, but all this code + // is a funny hacking experiment + thisTextarea.editorListener = parent.editorListener; + } + + public boolean keyPressed(KeyEvent event) { + System.out.println("Is your mouse lone some tonight..."); + return false; + } + } + */ +} \ No newline at end of file diff --git a/app/tools/ExportFolder.java b/app/tools/ExportFolder.java index e4e7492bb..bfe9e9d64 100755 --- a/app/tools/ExportFolder.java +++ b/app/tools/ExportFolder.java @@ -99,6 +99,8 @@ public class ExportFolder { // skip .DS_Store files, etc if (!folder.isDirectory()) return; // false; + System.out.println(folder.getAbsolutePath()); + String list[] = folder.list(); // if a bad folder or something like that, this might come back null if (list == null) return; // false; diff --git a/build/macosx/Arduino.xcodeproj/project.pbxproj b/build/macosx/Arduino.xcodeproj/project.pbxproj index 00867cd76..d73263d7a 100644 --- a/build/macosx/Arduino.xcodeproj/project.pbxproj +++ b/build/macosx/Arduino.xcodeproj/project.pbxproj @@ -151,6 +151,7 @@ $JAVAROOT/mrj.jar $JAVAROOT/registry.jar $JAVAROOT/RXTXcomm.jar + $JAVAROOT/quaqua.jar JVMVersion 1.4+ @@ -170,6 +171,22 @@ /* Begin PBXBuildFile section */ 332D4DB609CF147F00BF81F6 /* Sizer.java in Sources */ = {isa = PBXBuildFile; fileRef = 332D4DB509CF147F00BF81F6 /* Sizer.java */; }; + 335A28F50C8CCB0A00D8A7F4 /* quaqua.jar in CopyFiles */ = {isa = PBXBuildFile; fileRef = 335A28F30C8CCAF700D8A7F4 /* quaqua.jar */; }; + 335A28FE0C8CCB4000D8A7F4 /* libquaqua.jnilib in CopyFiles */ = {isa = PBXBuildFile; fileRef = 335A28F20C8CCAF700D8A7F4 /* libquaqua.jnilib */; }; + 335A29140C8CCC0900D8A7F4 /* PApplet.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29070C8CCC0900D8A7F4 /* PApplet.java */; }; + 335A29150C8CCC0900D8A7F4 /* PConstants.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29080C8CCC0900D8A7F4 /* PConstants.java */; }; + 335A29160C8CCC0900D8A7F4 /* PFont.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29090C8CCC0900D8A7F4 /* PFont.java */; }; + 335A29170C8CCC0900D8A7F4 /* PGraphics.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A290A0C8CCC0900D8A7F4 /* PGraphics.java */; }; + 335A29180C8CCC0900D8A7F4 /* PGraphics2D.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A290B0C8CCC0900D8A7F4 /* PGraphics2D.java */; }; + 335A29190C8CCC0900D8A7F4 /* PGraphics3D.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A290C0C8CCC0900D8A7F4 /* PGraphics3D.java */; }; + 335A291A0C8CCC0900D8A7F4 /* PGraphicsJava2D.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A290D0C8CCC0900D8A7F4 /* PGraphicsJava2D.java */; }; + 335A291B0C8CCC0900D8A7F4 /* PImage.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A290E0C8CCC0900D8A7F4 /* PImage.java */; }; + 335A291C0C8CCC0900D8A7F4 /* PLine.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A290F0C8CCC0900D8A7F4 /* PLine.java */; }; + 335A291D0C8CCC0900D8A7F4 /* PMatrix.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29100C8CCC0900D8A7F4 /* PMatrix.java */; }; + 335A291E0C8CCC0900D8A7F4 /* PPolygon.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29110C8CCC0900D8A7F4 /* PPolygon.java */; }; + 335A291F0C8CCC0900D8A7F4 /* PShape.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29120C8CCC0900D8A7F4 /* PShape.java */; }; + 335A29200C8CCC0900D8A7F4 /* PTriangle.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29130C8CCC0900D8A7F4 /* PTriangle.java */; }; + 335A29240C8CCC5E00D8A7F4 /* DiscourseFormat.java in Sources */ = {isa = PBXBuildFile; fileRef = 335A29230C8CCC5E00D8A7F4 /* DiscourseFormat.java */; }; 335D3B010C4EE1B80065B27E /* ATmegaBOOT_168.c in CopyFiles */ = {isa = PBXBuildFile; fileRef = 335D3AFD0C4EE19D0065B27E /* ATmegaBOOT_168.c */; }; 335D3B020C4EE1B80065B27E /* ATmegaBOOT_168_diecimila.hex in CopyFiles */ = {isa = PBXBuildFile; fileRef = 335D3AFE0C4EE19D0065B27E /* ATmegaBOOT_168_diecimila.hex */; }; 335D3B030C4EE1B80065B27E /* ATmegaBOOT_168_ng.hex in CopyFiles */ = {isa = PBXBuildFile; fileRef = 335D3AFF0C4EE19D0065B27E /* ATmegaBOOT_168_ng.hex */; }; @@ -363,6 +380,7 @@ dstPath = ""; dstSubfolderSpec = 15; files = ( + 335A28F50C8CCB0A00D8A7F4 /* quaqua.jar in CopyFiles */, 33CF03CC09662DC000F2C9A9 /* mrj.jar in CopyFiles */, 33CF03CD09662DC000F2C9A9 /* RXTXcomm.jar in CopyFiles */, 33CF03CE09662DC000F2C9A9 /* antlr.jar in CopyFiles */, @@ -424,6 +442,7 @@ dstPath = ""; dstSubfolderSpec = 16; files = ( + 335A28FE0C8CCB4000D8A7F4 /* libquaqua.jnilib in CopyFiles */, 339514FA097AEB8000193C89 /* license.txt in CopyFiles */, 339514FB097AEB8000193C89 /* readme.txt in CopyFiles */, ); @@ -433,6 +452,22 @@ /* Begin PBXFileReference section */ 332D4DB509CF147F00BF81F6 /* Sizer.java */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.java; path = Sizer.java; sourceTree = ""; }; + 335A28F20C8CCAF700D8A7F4 /* libquaqua.jnilib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; path = libquaqua.jnilib; sourceTree = ""; }; + 335A28F30C8CCAF700D8A7F4 /* quaqua.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = quaqua.jar; sourceTree = ""; }; + 335A29070C8CCC0900D8A7F4 /* PApplet.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PApplet.java; sourceTree = ""; }; + 335A29080C8CCC0900D8A7F4 /* PConstants.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PConstants.java; sourceTree = ""; }; + 335A29090C8CCC0900D8A7F4 /* PFont.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PFont.java; sourceTree = ""; }; + 335A290A0C8CCC0900D8A7F4 /* PGraphics.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PGraphics.java; sourceTree = ""; }; + 335A290B0C8CCC0900D8A7F4 /* PGraphics2D.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PGraphics2D.java; sourceTree = ""; }; + 335A290C0C8CCC0900D8A7F4 /* PGraphics3D.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PGraphics3D.java; sourceTree = ""; }; + 335A290D0C8CCC0900D8A7F4 /* PGraphicsJava2D.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PGraphicsJava2D.java; sourceTree = ""; }; + 335A290E0C8CCC0900D8A7F4 /* PImage.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PImage.java; sourceTree = ""; }; + 335A290F0C8CCC0900D8A7F4 /* PLine.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PLine.java; sourceTree = ""; }; + 335A29100C8CCC0900D8A7F4 /* PMatrix.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PMatrix.java; sourceTree = ""; }; + 335A29110C8CCC0900D8A7F4 /* PPolygon.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PPolygon.java; sourceTree = ""; }; + 335A29120C8CCC0900D8A7F4 /* PShape.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PShape.java; sourceTree = ""; }; + 335A29130C8CCC0900D8A7F4 /* PTriangle.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = PTriangle.java; sourceTree = ""; }; + 335A29230C8CCC5E00D8A7F4 /* DiscourseFormat.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = DiscourseFormat.java; sourceTree = ""; }; 335D3AFD0C4EE19D0065B27E /* ATmegaBOOT_168.c */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.c; path = ATmegaBOOT_168.c; sourceTree = ""; }; 335D3AFE0C4EE19D0065B27E /* ATmegaBOOT_168_diecimila.hex */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ATmegaBOOT_168_diecimila.hex; sourceTree = ""; }; 335D3AFF0C4EE19D0065B27E /* ATmegaBOOT_168_ng.hex */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = text; path = ATmegaBOOT_168_ng.hex; sourceTree = ""; }; @@ -576,6 +611,27 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 335A29060C8CCC0800D8A7F4 /* core */ = { + isa = PBXGroup; + children = ( + 335A29070C8CCC0900D8A7F4 /* PApplet.java */, + 335A29080C8CCC0900D8A7F4 /* PConstants.java */, + 335A29090C8CCC0900D8A7F4 /* PFont.java */, + 335A290A0C8CCC0900D8A7F4 /* PGraphics.java */, + 335A290B0C8CCC0900D8A7F4 /* PGraphics2D.java */, + 335A290C0C8CCC0900D8A7F4 /* PGraphics3D.java */, + 335A290D0C8CCC0900D8A7F4 /* PGraphicsJava2D.java */, + 335A290E0C8CCC0900D8A7F4 /* PImage.java */, + 335A290F0C8CCC0900D8A7F4 /* PLine.java */, + 335A29100C8CCC0900D8A7F4 /* PMatrix.java */, + 335A29110C8CCC0900D8A7F4 /* PPolygon.java */, + 335A29120C8CCC0900D8A7F4 /* PShape.java */, + 335A29130C8CCC0900D8A7F4 /* PTriangle.java */, + ); + name = core; + path = ../../core; + sourceTree = SOURCE_ROOT; + }; 335D3AFC0C4EE19D0065B27E /* bootloader168 */ = { isa = PBXGroup; children = ( @@ -660,6 +716,7 @@ 33FFFD3D0965B1E40016AC38 = { isa = PBXGroup; children = ( + 335A29060C8CCC0800D8A7F4 /* core */, 33CF03B009662CA800F2C9A9 /* arduino.icns */, 33FF07D50965C3560016AC38 /* targets */, 33FFFE220965BD100016AC38 /* app */, @@ -789,6 +846,7 @@ 33FFFE710965BD110016AC38 /* tools */ = { isa = PBXGroup; children = ( + 335A29230C8CCC5E00D8A7F4 /* DiscourseFormat.java */, 33BEDDD309D6E8D800430D5B /* Archiver.java */, 33BEDDD409D6E8D800430D5B /* ExportFolder.java */, 33FFFE720965BD110016AC38 /* AutoFormat.java */, @@ -843,6 +901,8 @@ 33FFFEAC0965BD110016AC38 /* dist */ = { isa = PBXGroup; children = ( + 335A28F20C8CCAF700D8A7F4 /* libquaqua.jnilib */, + 335A28F30C8CCAF700D8A7F4 /* quaqua.jar */, 33FFFEAE0965BD110016AC38 /* bootloader */, 33FFFEB20965BD110016AC38 /* drivers */, 33FFFEB50965BD110016AC38 /* DS_Store */, @@ -1065,6 +1125,20 @@ 33BEE0CE09D7446100430D5B /* Library.java in Sources */, 33F9446D0C2B2F6F0093EB9C /* UispUploader.java in Sources */, 33F944E10C2B33560093EB9C /* AvrdudeUploader.java in Sources */, + 335A29140C8CCC0900D8A7F4 /* PApplet.java in Sources */, + 335A29150C8CCC0900D8A7F4 /* PConstants.java in Sources */, + 335A29160C8CCC0900D8A7F4 /* PFont.java in Sources */, + 335A29170C8CCC0900D8A7F4 /* PGraphics.java in Sources */, + 335A29180C8CCC0900D8A7F4 /* PGraphics2D.java in Sources */, + 335A29190C8CCC0900D8A7F4 /* PGraphics3D.java in Sources */, + 335A291A0C8CCC0900D8A7F4 /* PGraphicsJava2D.java in Sources */, + 335A291B0C8CCC0900D8A7F4 /* PImage.java in Sources */, + 335A291C0C8CCC0900D8A7F4 /* PLine.java in Sources */, + 335A291D0C8CCC0900D8A7F4 /* PMatrix.java in Sources */, + 335A291E0C8CCC0900D8A7F4 /* PPolygon.java in Sources */, + 335A291F0C8CCC0900D8A7F4 /* PShape.java in Sources */, + 335A29200C8CCC0900D8A7F4 /* PTriangle.java in Sources */, + 335A29240C8CCC5E00D8A7F4 /* DiscourseFormat.java in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/build/macosx/dist/libquaqua.jnilib b/build/macosx/dist/libquaqua.jnilib new file mode 100755 index 0000000000000000000000000000000000000000..4c552def8d3e07e94fdeaf4b3cde5f861d79fcee GIT binary patch literal 30848 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 literal 0 HcmV?d00001 diff --git a/build/macosx/dist/quaqua.jar b/build/macosx/dist/quaqua.jar new file mode 100755 index 0000000000000000000000000000000000000000..d45b0aac4d615d1f45fe0d758f8158850c37c0f5 GIT binary patch literal 1135692 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

e{*x#N2n65XDnv)juOf9NxSA;ORhtH| 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 z

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

;F_v*Il$Ul94vw@5WT?n z1oQy4dV$7Gb9fzu#_t7}caj&RuET7Y&E)cS?zDEAGk@NmFQ5Zi(pXrGkfNc`&^3-) zMC?UHN$S;Awv`%538O90m}%&!I|>V9+f}xaB2IACD(4_Y{5ejV3kQ*!rd|cPl#a8e zx9`zt{6w{`kx88BFq12apPt~rUNJ(t9dp}FdLi?P5rWvVe zu%4#&{sMq&_&Lf7q=VchstMxip$`>#jL%8hIK1Mn-K1 zvomH3#6*uYt)|Iwga)cs> zIT4A77mhobrHAkd4R=_5aM8+45zDdck5@|d9+|Mt@^C*_A_w)kgu>?m;R<%t z!8lWbjY;Oq{xyS%&j?UO&Gl>&lUo65Lw6Gnl}wTh&DF=(E2eD~kAC>y<9YekACt)I zIPiwKZ89CV;D6?ce$lN=>4=#PJEA;5^mVH_Af1@TfuJ9b4gELi^?%&@Cjx8uT)t5P z?3>;v{C_Ta6#v7kh>`g}-Z^0ldwXY7Csj!j1t(LtZ)ZOlOJ^5TyZ`D1l&EOSqX=T~ zf`;0ri6SD>N2rL`M9yX)- zM2S7*iMO!*Qd*y$Ve)wWFhj>&B1Kh};X&1h@`|0kipXcM3U~@uC3z&+74MDAPPR10 zM5r#zXak)am499+>Sv#3>S7uwo@fwI^d)5m$DlYWSHiJYGPcgLXsjWR`r7WsM+Wxg zOT$%^En#!khu2EXfffcO&O1b0fproUJcbm+&s?NK(x6R^txU*}GG9`4*j%)A>q<;7 zqcL{57#v;6F$b3Yx!Jxy*?`+dk zcA?Dx97lW=b_z=2C;8ONx<8Yc!Qy}a(Be*X%tlJW3b&7q@2Qv={i1z!fp19!QEO+( za{JR;x1rr4Z1TIITM1-ml;^Vj_f5FT8LL!TFlIz&fT@@ zVGwE*{jNkT?eB^W%liPAK2`dKF}Wb9kN-x=Csza>H5HTd7cw>PEgon8qzSDQfr(Z3U*^MM*zKxUS{7rm$ znYr1(m5>oqt6PVB9^c9Nb@sv*v-{sKFYtgkcGaeQ{xCBfrCSCy_Hg}ars3GQukY=Oxu=eQ% z{J$i#uPnnP#;0MzE-eR;4`A*!_jC?5lUQUexksifuP~f&sE8ApG|h23DR8d;aB58g z;Dgz$H2WnpHeJCnvo~>)YO#2t9JCo#N}xA0OG=(e=be2L&NcgJ)n`kKX{9hr8Xwb+eAe$;b&g-?9ZHaI4BAC;Jo}JBMJlfP^pPl-NEGo=B%+gdS+t(Hb zWrERiOttKesxx~-M8>K!m>gy)L+K$oFySHEM+(Q>R=ukVSGVU1XCDC6I7&HcjfngL zZN>`dtq2npr@=BL!J6)$We8^sL-|{k4$J*vlMd+NOUOatq>?`YMM-AUk=K~7;UlD8 zzr9hJH_JxV^EAqyQRX^`yn0wqOv)7=!l^DqI<@G8gceY%;Y_F{zwD*IVgHIF;(QYm2lDa&$)v7B _3jpYMn#rRqM8Zc*g}jL9y= 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�m(!Yeu&M$dQn*!+lXOiVHF~YmaTzn;$}`2GX@509H@L*B02;uh1?NuOv=UN zn#YmPCXZ4dRf*6rZO=bXZz@bhHO|g-I;&N!%(T3oPh91xw)`;O0z2rp$-%HnENVmo zf@O)jJ@8o)a2KsZPjfb^!e&WWI6${PM-v538#2IAR6Hc(E*;Df@f6CYm`TSka}nEu z$Pm-~?BSjf9o6iK(*>uF3v(oq*nHVC=@3Z~txfUWkRnV1t|3~-XTj1o-Xio%*1PPE zmS~D<%TS_-?6=eKs!ay zM8EtzTBSK&RD)9vl+?QOnB#y_KRD06B&rcAwQTE>)rx9mAsHR1j%vjdnX`9vo$30% zAhPBO$0CJ;_oF&%?4@*XaT2Omd3LgSw$cMmZ^pDremn#RY*j)k2QK_NiBfSu)t<`i zZ?Z@>iB$J{vZQNI@>YTGtb>K|(XwZ(gf-|Bt7xj@ntrRNg<#Ij(z1I*krmpd6&bMP z4M;n)E3zKiBNunj@WE$%+dzJgPT5P{f^*_rIXR($3=eOFz{IXG%phYL+jOb$w>?A3 zpVqp%TN^m=Aq9udR%kRbNQ@vT-_d&HCBLbl?d{sQQXLY0Q+Ws*t~x)qLh)z3?fio; ziFn8yLOp;D4U_t+b=o?b$*#k_6Uk}i4*5M$jo&6YbWbD`;KY4B2CL4Vz`0p*kmZe? zH9L^$WeE}1l6Dcvt~JteM}$O+e1lHv*JDl83&ZIzGZGF}k0P^H_fOtIr7te&i4MMh^6p=i8)hD# zB;uscu$^X<*%J&y{M@g!iOkGiakR%mW>i3kNBkj|8BNF@Hm+9L&EV?#wHl{w|qkN1{^cFaoKHc`mr5^vHvY#ekXS6KVf#(L$E>MNpVyK#@r z40n;A0$S-4fQhMlmCR1(awVDgtsxADxIZDTZ%P8BNnWRL?rI{(LJCiiQp`G`VHhssO3{Jud0nDVLT(8vN5k1U?9%Xjp?{D z6orUjg-1K97!O4i)MbkRh!AiO`;RnYn?GCrh;$38`O25 z31-SEaV%>#uv!mt&&7#iiXtwVPu4y?$HmT6;^?x61!S6IB?CCBD1V<~Il;OFxM|Ej zHOY3w*Gl%mfog{P&hH?_*@0K*QqzFiPt&O!E zA8RD0rVK&4^;T9qw%f4PXdJE_?TLiXk}nTNPA`P?HA5x&SvJrD&}tP=%K5X1VnhBXBlT4u}_3H zhN{v(G>*HE{KC~}ky}ClWOP|uVLpO#MtKP{LF+X>K{~`t%PjyenxyL=7$BLsYc%fD z(4g+tI81T+4zoGN{ID<4h+@-tlYS+KnvaWy2zjL+HpLx+1aw~}BLmdIo@FZ(*u61^ zKZ+w%h`~NKW^2st2IDJX$j=?X4OONiEMzR&lk~G!*{9>u!j#_gOW9}Ok}!!McR;B| z++aAkGsSA3?4o=ucry}&UGo%Uh3|9VY26fk4PAz)3aiHvdp695qw`hcUU!WU+T;B$ zyKzlR$_lSPvRn3!(+lr-aL6kGJ1Drzqa>K>r!hMF_)U1+(lKyH2n@vOdRdSay{=b* zGMaT&&`bm`Q=-#bMncmE%J@47yf+3lpN9-RiadRcJrzgl8E$^ zGPjQb2O&0oh@ckv9sXX7UqI?N(z!8_0P>s7isNZ0HE?+FdQaAd9~sU&vQi?Cj7Y9H zW|t%48&5fOpASn>rCzNm%qlAl_R5s(EK2y{jb-@WjRJV{&a5k6-4uh@b`*IC}mTdAd-yuT0r zNE;6~)O`+At)>b9uUZ6B@!= zPvC7{HVNdrvR7M-ig`5XM@mId7(?_^WZX=&VzlcWHh|801n-*m520%6^e?8p z#@~oSkOd%9c1>1;zB%(F_d5#6Ienb$!V-m}+(NwycEkScPuWHA$L$`}iaW4N4R^{# z*%?%OXI1KJsl(doTYFW%9M0LpdgpZEy2r1F`TcW*ED+Sb6Ho)Dzk3%Y57)<#4eQByc^bD+z zd7e{WgBTG}@RXWs_NZb~3xqE+2!R;=Q9x8djCu5)G#4ALUj8)v7R~1Xu2t?TID%Mq zGSkYWf9tTuv9cv4E$>@Nde-l6nDE#;E*~uU+jS@cAG?@>H{tod(obL*EBtka5By!- z;5cpJVnb()q}JTgHP6Y&zy9&8T5J13J!|+$Q{DwQ3r^uPp8TnZ6<-5OyaB%^Y(OE{ zt}_)-I5lv7V$vx)D)V;ayFbonS<7t51 z)}=QYWUXykJKZ6f%uRZ)zQ;Wir+~JAWUFPRRxl?hX5*eT|HBgHV=ROZjx>o-p@Ryk z&FaoZOrZ^TXgG*p(wx`2|EM$DJXT}9CWKq&v8*JF zkj)~bddNlgP#pD1&P;kx@@sh7L(BcToyaU8U8SH)HT7!Qb^O zdEm#Kg74+j3R{jeh5nW39zo@U z{$Ilk{IApus2}pH3_(i>ml*w)2=<^}|BxxnRe>Oz?R8(6W&RJPxC~@@M?ST-GmW;g zKUZYR7RN5a*k#t(3v94un~5R!fvGi+zB6d`1jUu$+9Y8O>M1EYYA?JFuO+5PO@tU3Ab+uahiSc$|9-M%wV+PW%lUcce7tuM5Q!_S)vD z;y9EI`)zgIjm!Q@qLL9tA@lWRuJF)&`ABs&cjdZQSok_xI0soce;}lggjkR!KwP#| zPzNr2*MCO44IhPD@{dfS7om$EGYRxfXq7|yOa3xfb;wvO#xZMA8za3hN0aOy)eH^S z6@)hYdEFu?-f$IHpo{lraptez3rvp}-~T4TegFz{R=(5u@F(b&(oiQ_9S!B{4J}hR~k8+6+y17MYnns3IE6o9^pK<_s*;7n3re?X(+F#%E#F!Y# zi^BBaBH&2x5cw@nNrjs2{U|uc)Wy)mWOi2C>l7#4%cZqCGoWsg(GRAy99PrJ=`ueV zlx9oIXIH)yx}lI5G~gR*q>^vV@XizUhm*Ht*hZAODsZdW)pq*+?B}}a`;*1LVPnx; zBGCGHXUtP_5T7wZSEXs5<&|kt1Pq6`d|%D$u`2XY^$R8ZFAg!7e_Zk_4Z7!xxT#a4 z?WvP>2i#}ilu776d+3hRjIIKiy5%Gy(C)GlR`N9>Ua!YC`fDWg15I66=q`*u!|V$% zH>T0e=pT3#yXhsGjcAdJE4sPHHoTKV?h8XILPP9ALhRfQlgib8z|WX8vfARWWQ}qm z_dOwBWKns*CZ-cdEmUGyaZv`8lo5X7(6R_)!JX%*9YJ?!CMA+gP*9fg1jMNV-jAi> z+Utm`g(0{JA)JIaNrLhNd5j=RUIt>&a9mVAeMy+Y(GP2I+|K$IhjxZhtDm%wd?8cX zkoV?wYa`|DVV) z&HqBYB*b!6pay*_ekB8ncMVW~)2YO0LDn$m3C^>S&QV}~V1in3cRB@1Yo@I|{GI*p z`@SeI{74PauP7hE6MN5|56_wG=aCs^BkUFD}V=$ePu}oiWBx=4Glp$`ccW}?$4|tVV)G6_F@%) z1-xOFYGW~RWGjx$p;qW`CmfkpPf$qMb5(n2Q4$tu*+WF`6Km`$7qI3>uX&2R|#2%L+@mz}gq0 zo=g|DA-zl3EPS|*_DMnjsBH5oJhwQfFKx8U1W|rPJNdpHmRjIAE?wi%-QkB0##@}Lm@#td0*cvUM z^}hCO;1OzvUtQgrWl&fg7AsSGuYF3WED<=ORy z<}Em$ljk0h>SnABkyi#EhvX%O=s6-*G$Td=sfonl1xcO%{tVjreyax&*h1wD*_CHR zd^F@y%rE|ve}g3Ozf~!^;FDkcSA{kq{Vyy73jbN9icTJG7P5}c9_}(Gj^_6N1ia^ZT^U)jfVYTQ>pBcP~AGf1yM$gu`ZkO{-N(Xu)os znk?dzxw3?aw+e?0@Sydp3iOtYyzYu76I!K>m&U3BRO92!7iY%5MXN<~NCo@*0^+8v zfhdTUik8Z3d_$wA=IpN8lv9^14dl^E?7Rbqq*N&EJ|SZTmG?LWBWVJtgKH$&i2Jlb z@OtNLd!vU!W<8V+dLjf^sn>-Z9nGr7J_2!(y5(_+?OAMZMVNv~KhBtadq1eF*OZj) z6GUuQa0g^%rR9I$Sx(Jn{s?k@1yx@7LP0oKs;P0gO#Sv-5D%C?|MBJ?uQ4&~CdCud%!(3*FT6CoeLQ6s!46cRxe{ zo&jzIX32!J9K@r_%Ya0Ej@QKQPX9e|rT^b7?#rqp&%9}@1(BbwTj~Sy7HTVlMaFVM z9r!@wp~jqz@sh18ivvHQC7FX0d%VH53g<%Zm^XDgs|cwkc^q36PSXL01pzuu^JLuJ zE$J;!pyALO<5sLGm#Vxg;CBmGvo%*wh4DNm8B`6MT_F9kjq(b z?WE8u!=Y&mjsqL0iaCrycKGQ%olqvd0swL&^j#+4WR7SM0p4)%4~e1LEt_3uzd6i0 zrhcyvR1Mo3Ucm}(SKq0k=Nnc*%N+=SD23S>^@7nkQ;*`T+D9oxTz^T<^_IG(d|L*X z!HL;(gEC_I8$YL2>6*4yllBod*P_sE<{CQo@+#V=DYf!j(>ZGnDHGfJk5Lpg%Ys9T zQUK`s0>2Q1uvmZUzDSfuiUr!?G*_NCp4ex(*?a$KfRP?$*^(BPMYK;E$HzDg5Zf_O z@FP%MA&7BOF0vf4=s9R#&GsbNE=lJvjUp?HfUI(LFe4Wv!@s#D1Y#f8M-??%C$+%Y zlyG)z?Uwu+Pt99G~6D%=S|=G^1WGHkH2mYCoR{; zn_`w8&ZHZRe4Af$vfW%NcQ*J0wX(@|h?RInIT^R4bvV-ZCoFnZm=HcW;_l$Dl>ils{+xbi00&(JroT5NlbhSWAEN z(ICv8OxD}etI7I}-GncHb|Ll+@<$#p@a&_YhCuV3Cf*+Dm0F?{mr-H`ZRPwtj>DCZ zOzkIJXm{m`f8xCa20Y zu0n~S5p@r+et5TjaGi^MWv9lzDxLUd0^*9KeBx#i3_c&##MlyHiHb)QbJs{0Wnl>u zxjWK3PuKZQdnpZnLKYhU7c~i(%Z<1X`1* z#TvCPYNU3|EQQ5y1?NZn*cR?&4tg$2LuW&g8-#nSJt8KN(LnpeeekIWB_Q)D+2nF1jHf3VYC3A0xwA$9{Om6d@3OW9tW(dV;U< zfl#~P(5#IJKdSgI{F9a!%jzz@GrJ)sK1Q<64WnFPnT#h!r=YK_vf_fk9y^=TNtdjG zYv+?#lmT^Z!_`x3!)`!Dx0TaC&A|XXx4G&`-zX!YjU<#uVb+g^;P!fSOtP>vQ*Nv% zo@8K`Htn-&IA59g)?yyfW27Mg77XbSX=c9Wo{~gqq#=U@fnO=QMyyfK(aO%@N{`n$ zzqfrPf9s5w3z-*;U1>WQ*DGWJ4pOrH7tMXB0UKq@JkhMVwGMn4;?_V?Cd6#WCE zk&o)wZ>x!Zq+0X;thvPA|C>-}Z|PpL<11|d@Fmm{{$DnvDy~k>UqT%pacdJtD~td4 zbN63T9erOt_{6BvQvJwBz?NDkn4}2ZFcl^X4OO>dN}fTzy^9yZbIB?3?V3c~tFb?e z)ZD2sTec1zHsx&V+T@d`%AHHn5)@2_$jwQg*ajNy0T5JZFGno8iwe}e=GaXG>O}(YBr`1 z^uzjk^f|NQo!w(b)!WPX7ZB&H4K7#V#m$;K>2P!(+G(-q@S#iu_o0FX_WX4YhT&V> zd24v_iv+@|DJwc@8A{R_T^eYv7o@^!aS}6a;OXt0H?SZl77NH+O&P`+8hz}8Ojy#5 zPW1E{VI9}cUDn@|SqQmFrAE6Oeo;IrKSFiySzfRq0!k-9MH!O)kjWF6^5`$_X})i& zbFvXXz7HcoRarmm7X$QgghePR8Ep79#l2bcjL~qJi!nC8Kz~F-My*Uqd1~6txrt(c z&E#x+F!skIo@fq38=ep2402v?o~ZKRH{xyh)nK`0x+r5;_&#C_X z-GFv6qkd?#SzL%{WkJ-8ddkxJniM~pdOK(c-D%I~3eawCPxXD3+I_+6MF{c4xep1w z63U{!#x8cp>KMf!{>Xpi!7i9fvRrBF}2_$X}P5%Bg#RGKkFsZXV;IJyg8HBRxi zRr-xbnM=Wl(cS0yJ5>m)&CmZ<7gfek(Cdg`U|A$!V6^|cy7Wei46nn>$BM!lgF(_sDJr$&=}9pM{1cZ%4-SY{N`^ zZ0W8RRq=exnSqX_?LsV|Vw)iE_PDi<*EA%4YD>zMWO+rDHEs?OU0kiicZ^d%XB7+d zyi#)sPaR*_ESeUH-q+yh$H8k%F+d8w0&wQY)TdF|x6@|cy^Masg}^k}E1hF+ELs8P zRJ=&>sBd8+oW(u)3NVb6$y&LRDDY37!Xt5vv{{hH;{YAF_NTB>&fe{WM&4y4rxE0) z+BPWT3Q=RvWeeD`BIZO60{WokB?I*8*D@)J?Bpw*XwcAUi19ATU53Mo^qxk4mnnJb zRroO%2JuZY&K3hE3^(rY_kOd|Oi92ysGvwEVBujp-CIcJV6MQx^yf*0^Kx$5>(=>L zSlLe)Gsww%$vgnBAV5`znZGUcv9?Vm(6PG7$2eJORMHHL&ehGw;3s$ zuWuIVw|M;K<=}Z1qH7x)dz$qWyNpWfbs=+fDwe0NBvJ~(nhY|W9kbKnZ%HgEUDEje5U+RJ`OE#OUAdc0fl)&aMG7 z3=mbkFGc<2Y9)%KxqYj+OYogP(Sdum)1=IV4o>uGMg!VZ@L_bSm0vtmvLe6hjFg7% z%E<&2Yjb>y4+mx6upUh@ZavsSK(m>R%ZbYGx@ptNsU)2cT$>O>@mQ*KgoLpM$0MdO zWB#W5XsI{#;!#B-(B6+A^?Phz(=kjou&a?R*3I|~IC@=Uxz0>g5R(IMdt+MrtI}-!g+sIhqXPsI^)OB%+)ft>hOB|`8aO+AGmYXY!joh)+1?8_Y&lD{XgXGwmi zl_zg_h_PK*a?@Gldz$~*dT3*-8X}EePUFX%zdT8mu8=O_>NltoQXJvRsw5(-y^>G% zbwW;C&QU2<6Xw`9vZP%Av{j78Mu&}G62wu&`+#10%1^QC>E$eoz++WKP2f?+*h5E(v|bF!83!&5 zF(`6GSSmIGe@Hgkm^P;t0Nc`Gf$SWt$`F$)5*^mF65-mpKz7bL6^40ZxP^!kerlh}vV64SC5CAQUL!!WV6oYDcpAvyv4Dk<%FCti zD5{+%JhCyIt4tQrc~vN?ou`af@kr&w)6VIM%E-|Jc2kVLI5stI+@(4AWooodS?_#X zH{4&uU_w6?zOO+r5-Y@eb8ujmnK=9woYavtP<~~8*4~&-LEk?hl~dU>&DH<$ZA_rV zGSNhkX-l--z3Suz6WEm7RoIg9YpKA>W+^Cf(xt7uh+5&nBx%0)H`7?7OGj^Uhe=;L7e;47WP>qs?Hl<97cllRTUe)e^J8$ z;oO_-lIY;Pxf3@HCNRoT6oQ@mzYUkWx{df;7 zyfpz*hfFtmIB_7c8(z^g+{s65)aPE3%J%>$NhKCrP*lC}pMlJ?x_V5W1w=)e=M!I4 zFK&b*d{!`9eF*TZAhB#5>bX3Ws`&&=UZ#*Hb#V|DWxn#W!N6dd0d;XCq8q-@G$h&e zRl!gR9|udPe3^^(C|eEs3OAGeA){l;!#)bf81+@RI}YN935?XuI^*h3}(Kv?DRhkL}QD9*%%pnHJ*)1 zy8%BdVqE~hXBb10mMi-^mq@1a(nDG)IHx#n_kLTT<*Nhkn4B*RRA>ekm+By(&94h` zczLon?XbbuA0&25<$*oXm3Nw5npl4Tmgb}bs$Gh zKJPT3Jk4}SEL;c*meXV9&a0BPxcDb^ zVpCPLmQ~caEC+eRxo0aM-5IT0+%o_{-}r`Qd9M2s(`;h1Ne>%Bs;odoA(VDXrTY zgAM-M=KTxlLFRfS^z5HfqbntGpYbytvv>ZV(sbahrE_Sh%L3=G!>%meWGt+x1Zp?7 zRAy=&Nw~L!O+WcMb-C=-y~NAt!sG3>h;C>LN9T7H$L67>qOSQ_L!Qhl!m06D`B=s5 zQK*lg_Te)$VUx(CblMbCp}h^4(<3(}@(G_@?s7Hqce5od$R8BP)_Ft^55I;~!BFh>nR&7b ze{GNoi1YRB1pH#(Z!82tlkj7H0E$8VWjE=HT23M$Pj#Wrju-Nd(lD<smncf!|@~zPZjyK zzH066$i7L~qPX8X3vpMKH!*)~gO8>zQ2hYx5%M(D9E>F%%3L?9f)1nIu7`6G85{|S zlg|CGONEJYg5I7;zkVhEL~s3%UB9vhHU_5ucg;Z)#w%$#nctLY+zXSBzzcyOXcPmO zB$2@%;V?Q#fZ$LtNB~yjY4T8-iGf)!>n#KU|Fx!erDB;#17Fp0X@kx0htduct=HPL z?%b|fZgy#{)^TmtajuT7c=WwtXO$hoH_=}wVh$hKsRR6>4y$z7Pv-`0a!SpJ01M4Vzb_ni?1!tn{oF1F-sqe``+oF*-hnYl1wnA5_5w5w@**M;@ zq1(DDbE|iZ%jZVQ3UKYp>U@&sN5gD2VSD!Dh9kDW3IRnS_i>=>71dpr;Mt%@>#^Y4 zu(c_(=+Ire*bC^(Ax^{1U!sTv?x)2?4nk+zYy=vb!@sn>{s|_A7DsJCiJ|P0-qQ_s z?L4!1-x~I|=}4ys>Pv-woZRx_yg@9a7I7>dP>0gdt-fUy8nD#y%8u-Xt??u>iAAgj z7E3b!GYIFMs*BhN+#hkg^vM*~JQ*eeVv;7=s2JeUR{5t96)LE6$YJ`u*%DB(%50Cj zc#6f0)BIT1tO`F8Mbk#l$eG#7q87=>d}LLo+gj|A=!dhmrM;8P9SnAQL|Us?A< zwybuRwPb6tLDOgJqm_M<#Rg}$DMh60;V3z%ebruPJvZo{3}c9vPOKNZ1o7XR_BN>8tONF` z8uj3En$#eMuYq%gWNVO;Y7Gd*Y8=$Z+C+fFmaSLlL^Pk@3=C1oJX;L}JV^-jg-c%d zPs^V6!e?z7Rl1(}=LwjV)dcf!B2@15In0V{W28=n)VJ(eTJX%iu0fIKN(xftMOoD@T{9I0!Lwsif7#)BCd)tb2%;LxuQ z%2RXw#bUz#+DW~@s%2o=^e0WMp0RVX4#^@Q^blApkztc03R}jJ{87Uaqdy~2NREPX z`p^olFrnP6C_F=^awRI5d!gMK;~{+nwsck{ji9rWXagn!)jaZ#e4j+QoKh_eK#Zgc zVpWW&B#wmNn)Zu z9~UyA^d=@+?}gh@BA`n8?CxPq$ZW#1svp_=b&7xAbH~CJ135(6j1-`mw|6Bf$jLJ8 zMI_3M26ELYOefeJeYqs{I=`^s%mM?MQRtZN;7~*i%(l6@juo>qi;&mP=Fj-^)R-La z0x6MLh%qEsIytOk((h)(*J3*pZTUS(;uP$mDul%tR++}0KDY6;{WV@amIs92DIbC1 z*dv_;(@W2GyNY~L3B4xxnZ!a6PX z27Nzf79l2`>LNg}P#WHYrhb0WT#U!j3XE);c@!Da6Di9x2)o>ief#(9RGs56<(MSn z;^!(F`@{Ugl|148JS}`dj%m!qu2I+k#uhbAMtG<(CPq)}jrtql5wtD-F`?36ae%C? zHWFXqP0$C@y;wCisQ*YQmg90$=H!*>a4A74b~g%)d%%$<_WA{Tz6`=&a)(8}lp~+Q zUL<~Y7`}3gzDDF4{LH-P&2CS$^bUIy6Zx9i*T36P<62U&oJ*NX6|<}@)7mt3iiY!d z`cSZhed3xUmXNBcOc@n2VX>$-*ZAzfVqE+x({S|AtVF>%tfWe|6j3eNAF;w|!R-L% zV3P7>Q#p&ZW0npoT%;LxHpKja5?+C#v!y^q;U%H?w7q?C6(5yXXaAi=WEQW1&YY(-9P~oHaTj6(K?h8}#_wy@o z%F#1TzXl`#VX`fHiWKwT8ze)#*(X0QZd377(v`VbRE+p+s^R71!Ef~$TE0^DSRRIe za~FT4xB~M3P8{*#@rH494A?@dR%`F{Fd>t|Cw6od;7%gG8BkR+dcG6+*Vs%dbK33% zw42R5Hwmqa4K-3u!&_gDFZbt}Cica6uwg0^H%y-1u1m{xX3ht2Z3gmhBeQZ>>+%Nt z!Z3?Hjqd^dqr(h~#)>fT2nSDB0%>jnnc4#H;LauEO9P7OlrLW|7^K-_Ah+S#-bnDV!X8%S^{tao_k!oE%G7d+)fP5+y}~ z$F0go&+JOm#ccH)qUs@~kCHncX^?iYS|TGANlvLbgSb8=1(9M93y5$$+eT)Q8xFB0e7GjbzU6e{GPutkTcIf=-S zmCf3k_4p*E1xaPCxJV6!F3}u1Q3B$%J{5oAYKRVqpZYKpJ9$zvn3^~b6Vm&PzQ4?D zj+O5m3YHAKySL(`-+M!p1j(1=Mij9;RTWQSwEXPDE3Ash8%188TYIsdKdm#RFHMNC zd@A9>PF3M286AKCCt3cP#tQ2$Bt4!`-w)3Jnxi(#2rKoilq1a$$T@FWW@PQ3}4%Q8bYYx3+K z&E;oyx$2oIa1dP^k4xizn_U}GKf?vw!rEw&$qeDgX!xv*SJ&&*sA;`MW4LT{r&lMo zp)yJrI$oSuSmCyOQ z!T&&xJ2kvxcSdi>AAvkiYk5NXjPSjOV9pG6<#O+-xCBG{(?c8j7U8gxW|(tmJd`>v z4DAd(57E;3_6VYrgxBrj<`CRB;1)GQ%T5WVy@1dt@rpF9L(NS1kMzYdaZ5R$b`Bm7 z5t5sJD^fmQ^2!*8mUkJ19k&?#wWOH^AeKhlcNrH%FLvFlxh<(4$uXN2`7tRZ- zte4Po$f(ZhI~XMPjRWGd_yIGM*1+y1X*dOw`Z`ZfNNY-NU3#oT&>>+G4GaoVY>Munu6nlMkol+LE<) zsNMahi-4|>o#Ww0IQl)zu7K{Y1oV5(F6iDT?P-8J>xK59pe}W`Dd|=}QFh2*3QfCw z^G6mjIjs=4XJIbjo>c;9K4J0x7aEV4oML=~RcG+Ke#eSDDH#FWIB zQCg4%4+n>A9;N2^Q;u#wzEmF>dNN3vWa_rMwt?8me@bCroPSbg!H%WV8DPZ!*np7f z8ncn@Ml6c{;^2}1G*xR+2gJDKM4{IRT44Y6um%XP6WCkw%bG22B5kiA;Ov&)^_6f!=aN{gQbgfswM(hb$5pPndis^+ymb%vS<$nhK33u3u0i0lX^ za*707C4_pKlf5V~>d82ANF8-WQmqxZ;}lZu$Wph(&YVb}3H3y6xWjKVvs0Du3{B?x z_l`^03p0VE5&=Q43hDT9yhjG%a{JLXF*(Q41??X=%_}ZIoQIC>f{$~RD^ zyl&>iX&`GILYT4eOBlWqW(>qi(2@P|hUV)P!4Z}8-!%-I9~k}qZNI@+kJ-&(-{2a@ zg*}l|T;t8saY^AkT;7?Rr5PK0yBU}?9jdfc4?q8HbJlx+_~1)?vRFoEWg^0=K4bm*)>bvI45zif}X-D`K0=r6_h{m=yW~;KMI9|1`{)p)cV` zi=b8eF+k9@3>racSGgr z0=MAxl$ z;gsFd@X1nxSCj{|yWAN>un>ZYOvY@<_cRd8ccyYR&dkir(%Ip;`;nn@JT%r@{8plo z>txf-oc`e!$HmuQzxhcAtx1YM2;92Vq}Q+ z2@T4U<@Wc5J>$pjnkx7wWZ}9%R3Rku709AOQQU`s^6E)Z6SP8hdbEJA9KuWQu9{bm zF5YE6eo8L#)KGcnb$9$U6R(sW8w0Nt7q!m|Ml~k-jjp|j>)nW? z4M!c(cqE7IDq_&dSXfgos|Kr}Qu(N#l_^}03_8eC)G^zvhbH4f)G^S^Mn(;eoizo1 ze%jjIVh8ljGpz@yv{uNlH81H^iyFLj-*FRY+yX95Dg+Zh8aPuG!5Q(03oT)@K8=hc zMZw>YvYEr8Y_dMY1IKdQVQIl;v_pl!NjmbM)WU_Z|4U2PIe5cyF5@aN{VR+V55)Pa ztKvRq(W@-fg#{!E&#(E$jlQG@2II}WS*U-K;9li?8<`E}aIm+01GJNKum2VxpEm{a z;g#0kPWq6cZT8-$z;>@FUa=-(79WlJ)l+C*vGU7mS5qekCf5IY`=eaJMRkRqHVAeg zhd=qjR!l0|lV4;?-HJGo=XJM1x$dbp!$0-=EbX|0-014>1QxvUS%^s4iv8J*O3Gf^ z1zr9rr5qO?EP_SY&v7gvbv2z)JFMVGxY3H~)MnXIz2I&`jy1|m!iEXj(*8IYm$_Fh;mqgP3iGokp;1{V z?=mF=j15FZ`)(?rj7QXExMiLYqs)$_WI5Al!sb;UTdrb#^S$h*A#8kLoCKeX;$+%H9h4k2RqD2-`31wqwb37fA6`-`ypki~Ou+3@1n(t~+dpO-^qo<5LeoWrz zIf{?c+5yo}_)EY*9sYPYDCaodGb zMGENd0|eAu`YNJ~G3Ay(5=>d7kZ`{B%Ha||mF#ue zq!M@=E@s!6EzgrJ$5P*KpAVqEp>4&YdNYFD5lCq8h{CyglF|eb8%zpphTmHzV{bXT zPx$VFfe@KCp`o|~7M&~HlTFV;%mGxeKX$yUMVoTfy$HK#!AW!%j7R6%e#{2ez5CK_ zmuv|7YLCdc@eETyH7+%R1Ad^#DddD=*?J77hD~5ASIkQY#PMd0DE~vdR!iGvG#x3l zVGrpR!v<5*13ArVcgs!t)^BR^wS&HUTmx6C%tuKd^UjlD240#JgCa}_Mw#E^Lw(QY zRts*kaa+jIbA*^UbQy4@(`@c;TKU8II55J8vf&&?+D-*Hn|x4x$!)cmVtQ`deaEVV z&D`7+a++jQ`Z$^)nC3T`*}Qvf)8w;8uEmDnhGPh${*}ga4&bhJ3H_L7b+5T!dFc5{ z%`_b*ojsG*N`Hm^Z95;CK5s>P)gnrEiV7(p-`68~b5f-hLu7!fMuDQ3d(1~*S99&D zkW3?=XDbt%$)d&f@g>F!#2hC9+v+QUQ9;NUWT+{@G27cEh7i{G_Z2{Ig~1&Nm}d{V zJIkr=6NyS(Akhgcub?(K8S9WzmseRDjc2Wvmz*wuY)Jo$F4mLq>iZ;Y+8y%_{hpYE zy@DL4pM(5}Sdu>l;4^wc61&WuD#L*r)C-?2GQMys$x;dZGheVsPpc+~^`to9Q@i`6 z%A?|p8h!+9pGItsR57C)jBOvRI#8%AMl>@zC0)M)b)_#*+sv1bJSs$Awmt3pUvFWu zr5qVT$X~x^e-=&tSGTaFld<)G{@rw|M|z?xqyCe9X3RAHBP0YV-3MAxmnnh-8eH9q7P{1t5{aEyrO{%Rp`|QayRkL z8$j*nU^gJXeMRBnXciFCFSzGY| zktS}Aho7so_(Xh46iost>5Y=LFq2qxl<{{8Ydp5+0uxNeQC4PClcu*~BdJps7JngK z*8EC*sI{d+wV0SUJO4M)pWzfzPI7d8^6d zjORJX$5f7dvHtE+drK)gDy8vcN^?4bUqj{0_p|JkrqqK+5ROzwC=5XX_lkqmQ(Q%) z8KZSpN#M>?Y}%`zg=G*kVwnP()0s_I4O)7S`Ru4ZNVYPakf9+%874I7_q+x%i$`QI zEErqOW{inh3a^RQ(+>rWS)vATte_r$%|>}GmSGn6keA2(Mnrfe4ex5TpmLIYp@Cdlxq)T+^wl%t~eH7ap>xcU=W3kb(C{9@uh^&1!^}|FudJlwhvwo@R01rIr4}tt<`a7c% z^R%jbUBq$Fl(xzGtsU1%HpE_$X4Aq(+RR5+qYv@TA4h1u0DG`b`^o^`HEIJ(>x3On zRrC8DEbrxd)$|6(X!4(&^;&(%L1;3&+yF_qBMM|(ewAC|tkgS0F#djd)K6G`^;?)v zrT$tw!G6({?tun%d%+P)XuABOzf5wJZ3BnSUHSUZwp4BSy=u2;6w9slQUk}!{c5+^ z+R65^{kC`9V7;T6qh>k{xtvf1=<%qbCdA zS=j3f>Q_&-VCW5SakrrElq4;2uCa1JcC@Y|qHG=viI~-#`JL9Z~5#0^*5Wmjtb7IiMS8Ls9vyhn;wuZY1aV#spTA91d=hWT^?I=uTPEKw9SS`&$s z@V2_7=0(ffyHn^nd<@&%cksG(DJ}H!g(z0+n_Sk##G7Z8Bk*Fd?xViXH%n%8hH(pZkiEA&>x3+wbOx35Tua~TphRAiZNTx*bBAAxF{iitPvH=Z zi@9QoF;E3q3=8hnVB!y_nR>zTF;=d!Z@K>dCJp)=JjqAE*AOCL_#_Kp-cBXdqww6M zLE4rt>>OLzKD_$HH7<_sUhZ}^Oo)SKY4h0i9^c2Cv)WCPdb;@uE#zI>-&*>Ij{+q$ zh;lglko50pH^vL>_ATasHHn=bN<5JytWP(l^*-N+bf`pM?hEQKEdMD z7+P|6GO`F}zV!r}>*F25Cj6DyUm_0Hwn$ICRK`geD*kThU_>9uk9kUJ(_@T{i zG!74~(bFzq;SS0sgroPb91<*0e>NE%MO&=0`gl=qZh{?%OniuGv!Wl0Ug>VMnWJ~( zI#GuA^_ByRH4(U^9XV*x)U?}t6O^yd0>6NM`!`aNLAH!p(wt82>)_!v;$FpSwwep6 za+%G3!y21*Hw#mZra27QicAL>wC|+8{$HvVIB?>ABpaNh59w1(*t-TsI^{9?|T3mTa}zxnrLc0#CR`H#{<3fq1Ti2FNLNPjC;Wo~N(F z$Sz-87F5%2f)^^GoM=VGhqZ`oyzXA_e|^``-+47D`gu*h{@MRWN$3BmZ2v!#@_$M? zqoa7C2Lw=pPTpF{O6nR~>JVViX9*zD3ihE^p3IR_ey_`d)|%`A@g%j4ER49rPTi*6 zymj#Zk{|&VA|M+IEpW+DPd6Aa)2nPy!)|$!Gj93AKD(@nSTH!PMyZ~ThJj$hl`OZ8 zjGc>S>e684a&P)0aS)JLS!n=Z9r1b&+=3*Ftw(O*Ij*1@ywf8d^jYpzx^M)o2)3Rn z+TnZ$=}LUD|JN%e;S4O{x=1}e_pYIm4TtLnXT1NwIKO_jf~mK|6yc& zHuJRR1qHg(sT8C|<=jze8X3}`%b>!5_0g@dv>kV@-LaJ#j|>l$Z!NdZlX7g*nw>$|70)=FWU=_=r^a3>P5TdKts7LJA1PkQk4d+ z$L~Rp|HvObbKE7_q|W!qREa~IpAw*|uxp}iV$_3Ne|Ad235xrTwuVVjRbQtFj!$dgq8&|M0MF|;4zGpa;G?o+Ak5;kY(QK)o z`UT#~<@FHhtQ^R=(x;6vlL#j<0FScH?J*wnDM zgGYsUQLMl7GkEe19cIW0L$+IXVRvx}E@d{Gjs8gJW2s>CvV6Ra;kR5^o5d6E$(`xt zvXW9c;j6V+%+_{E^i1s3|uV^9Q>J({o^3vMyDp{}7fR>vS`NeGm?4_hsVPZ}!{#ZixR{+8^7juuEU4rh`8 zhY%&)T#7@>)?5glfV8=Pivr*4ccXj)?dDmm*VWAf{SG^KC-=|iglpF8ZLUy6rSxsv z2``lcQ!iQ?X1w2c0Yi??^#DMW4Q)=f?Sz&I93598l@Y%Xm0;2o6@zG2l{nfyK1*tY zH;bIbGcOB{uK+nk0xy5;msx7p>||Ml?c`9MS?Z9TSlVvRBA;p!!UECZPKHmyvxFY- z+#l=(Ig3O=GH2ya2IW*HzzU3ed_4FDX?{GW1vZ^*lH-KU!;>3}G9li63cUVc#!mlN z%s(dHIwrY3cman%HjyQ=h*K_OnCZyPKZV1+Jj*&fH1*EGUu|qnYTZ2fuNt>|w3mF` zI{Cz!qzzxXyuBlHsIgk4K(&p{L0D9av}<)FchGcMqP+8>gDyD=mvNi)Aqq0vfza*G zDU9#i_`^BencK+OEeun(2jU^VIGL}&1pfxMc6vDT3Srqr5Su~4>!F;}T*#u`%q4Df z+-~xlP2`=W4`S0MphAqxrc0uPfPRb2@~Y2VnY^O=D-GJQG@W|a3fiGHmpW0 zIS;PJbq=?yqFqS83~LofaxQ%ex~si*doqt0@<0nMtXCmn%pBiE`+>EbN zuTA#F$ZUnR6=kX+U7tm)6uhF#y|%YjRwPVG5aouE9g)LdLyEWcMa24zhU4Z-?EYA@ zkPRB^-$h9f^^h!N{GkH4S-5$((RC53l84z@S(_TQ-~gM}o3ts#M^nPkz`ZCpGwiIy zNL+M`Y#G^VuwC4Au80$3(;%$M3~vV(qrPttWpGF={9Uj&V?mR}oiT!u(d;*}4QmxV zABHKcA1lbINs;)Y*;b5<@o&J*vdvMH12NeL++5yS#NI!rIbOx^dL+P~^25>eT7(2s zaR7*vpMuptzb1!n&({1AR?%Oe*Uvtdl4f{<@@wpEzD9xuQ}tvItt8&U%uvTcn5Ct~ z#zvYc8M3wH_^C+AB7(PK=y*0W84*I9FyY#c2x+o+?c1BNl-8EQ_C<~CAjp5RqvL=P zVKA)~Fq5S!TY?U(2ax%lt(ZSA|8gqQ)=9jPk(KQlV))*Q?a|_`&t&B?g8Z>w^}Y@Dq8#84G{34w3R7bKLCwq1goXo4EK)MzJ&s5|kxu?M%UsA7Fi?H5LblJ# zSQcnoXT`9CCoj@)@ZDmjBvW!#1~jIGgJl6fjT!bdW^N2~)CJxFgV>N}(z8U!xAp*> z#ge{!)*<(r*KwdF2j+}ed z4Z-2i2M{-UN$^?0LX{dyg{@6Bgt@Q*qXsheDhPI^sDr}e{AVQ_uQJeqe0A7GImRB4f+a&ajZ9g{JohH(^y@{Z!Z0wP-p+ zaV_Hs%CB&o*zi2Se!|S5yhGzmWgwqcP9!fUTmqoBl>)GY`XnFW9(oONm3U6tUtUF& zql=iurC{-8Y3IQ-M>xvCwp0d!>!QXlj+1c&{ue)}cr7sB2wP&%JN_HG+!AG2q-9nG zWybMJzn2zqM}M1oQSu+_zl>7)=;&xm6mn9{)fODCcr!nkz!VnPKKdxzvHho<%dBC0 zjEJ3dTqT`q+>*19Cvl{GF!kS;RU?d!*-^bTGlXbHG6?Co?hPMQ89h0KsoX?$@E5tj z+jQr!xp+5c@bWyadX1s2^Z5ZAz3##cdgN|L08pP0<;;KZ+J*;7dpwba(#278;ZN}* zR1u&SHl|M2RnlN}3o&j)9wD!B{%Z}FGWJYu<7Gn-ZX@60Zyf%yfY&r@%_w;qO{Znw5uUF6)w;Gbcu!0hHH{B&Uv$nw2vu7B5`A+QsID zZn=z$;&#D|8?8e2)28s6kXf8_!|YF;Z1y{owAG$Ox$NFi_VY&^o#Vqyr=E0M`}=CH z-I3OdM;@J$hnF`riXns-X2YJuo4GfLPvNb@x|K3V`rYye9k0k4SD1DDGcWjm8l~K) zWZ5l~Aus1%_|JLtMui{6?gAOKOf9M>)?GR$EH`uRK%f{1p#|U4WC( zH*&7-X?c#fQZ9ZyKau1?M2!t z?l;ct=X+u<{@5Qos_)7hn2+K~>MP>fWZdBSV~vatX4JyRqkp1r@k8w!DtT|kgXLO0 z-~OtzPvEZ8J%Fos`sSCg@A4b_CqSe>Mn%1J#`A4k&|%6rh3j98Z|wtq&_e1XD#kwl z`6pg)?E}OoIfwe5L51;*+;=17n=prL{|pQ{6A0J8VE%=-+BVDYOuG-p-P1#Pr|+bH zH4pqnZ{)sYOyAlkzIW(c|KNSgAJo@Wh$+%Xh$8Uk;GJa)Kb)pZ)}5;b9F2lFmUf(` zDJ^xh@|7JgGQ<~)50;yWsx?-T-rn9EoMNYIKx^B~#m(&Tl1}pwW@l(WnHd!$uzAy5nPB|(!Bgbj$@^J$YDP&g- zGs|L<$!0L}&(gn`J}c1yFg=&^7LQIYnHU{2g#0wg9;}(k*({X|$tvl8!;aB9x_jRd zphQ(6zcCFZL=c0ck}x$3O5=Dr8PjmxD6DL2pbCul@irJocNnTtze2#7!qAv9b#CBe zG-*7RPzduRx-rP&FCfrL9f4PHD4Vix=eraXsCE<4} zCjag@@K2T#)#vy^KaMs?)zI2m(yLA_h@3C^3@GQBYcqLG`n6b1so9Cek`Ifl20QIB zA^H^}?L`GXH7jpF)kXSdSWp(pJj;6YrnT@-U%4KBP{DaK!i=c`uTgtEt0x&8yfX7% za{h2jBvr*(w;1rn+G%_Hmj8-qCPsc}0UDxJqbz>E8L-XgTcnR23N37(@SEBc#R$qby}p)j9jfQP%{w^XuVB0>a;osTSifuKZ6;j-q#49f z)X23e!5E^!e#J%~bd+R9eQeu^nphD0DQ*LC=TM}>+6eOJE4lQ>|0H(ReTCy+U%Sc=EXo=oB z=Zs{sg!#B~epJt`X!F+R6v0m1-u%LLWNPE`>u6MK!aF*L8r^|efbw5oAIo~V@8&B) z6v~2*SSwrchGzhkyfXauU~NDdgX}f!;W)4d+O3Iy0gZxHV{+CP>UZ&YYp@iJ(?7-$ zVI+~szDtMuMd*rxWR`d}|L|p&%#}GWE`z@Lm?<3D#0=8GHF5ooaN9|``vZkySypo@ zfKg>D_Vb3gZE0|Gi1)~WkyU{(*oLfFSs#srviq0;*SnbmLt8YJ%xIv>cvIrkl?q`R zVnF$XzL>WD$xdwx_|2?6Z!(XWJkZT_TRVfQ0*q66az%M`iE_|+c{bXd)-C=>l=C?# zOrJ4p(1x_DP|~6~^tPz0@DiVv41a*!`VnmU1C$f|7Y4bL|46qJ{_~TN(90qSM|F0~ zoZ7`>444X>d%U%w9eebaWTBA9l?@i|eZ~$;G!*K%sg-xV*U0jR#UcwI2^Xv2cBG=! z>rypJ?T#4obb_^$z=KPM*%P^>FVlPC&l2dn@-IUR$4wV#jZ+K3RfU$1sJydyTh5UZ+k*WJ{pz|qf@unZz570eU|*9mq+XLNIj%CF zAkBGk!|4c?JB8|^+i!0J#A)9tLdBj4h0a?gc<}sJVgE(&-)7vt-jz$^B z!D7!oPvniKf&u*NBF0Sp#2^ps@rygsE`TqJW?y_%RS3)aWJW4k@r`qF>_WCgJQf{u zu8LGR6lif~tKO<-d#$=~89^54@%=m~7|sb@{toryz!k>R43|rgfD&HW(F_y(uMw6n z=EWvE<}WPr_zR|mr6q0tkt!9pTQn9~R+f2;#1heNr&`kC`j&V55slroMjJBq@gR`% z(e#j7O4(7tkYhP5*yvh(+o&~>hb7r%)m6}GDMRg)1jY%B?2>~<*Nk<+W`7evCSwn6 z<0g*f(27-*ZB1^R_+%PGQVgTuv-~2GWw+)sx$JS+gXNd>Vv`j+EqpZN=%ZpiCs`P^ z%wmKtG~_%L;;vMPjvESlPL=@EM;e$ni*4PUw4)F`Y=)c!W=2z>nstFxV;&kd3Z<4A zIj=+|424$e;Q3+%}AzJ*2g_;wBKjJt&b}Q-%Xgk!*AXYhA%6 zcVxsP9g)Nr1j+9Z)!fDCuCVLFBPaCMx$P~WrL4i!=8t0uMo$d1)==?gH9; z^=8$_475V_CY0`S9Z}Eb%rl)UxcBUol9%StGmtCIcMZ=(zWHy7TnpclUd!Bhe(OR+ zA999GIMYmPKJ>MWH3Lh7*y=!MKvZ|jZ*7wA_}KzU4s}lJ!S+f4_Y5Ag1<+fE(1B<$ z@m58wIgVS$nuJ-mJuJC*Cagf-i!(uwu#qtKsdq(z&QpVMTtB>gaZ*^|j$FJ%1qd^C zuR0yUSP&|OIe7xt&;TFkvGP1}pmvlch%yC1&$?QGp#1z|7-Vn@hs}j)nCfr~#aEUO zP_B-RW&hO|QoeK26{ve`u#HR;ZKAk_+qcCg(bh#IzVPTqEu#c z>#2HQ@_hD&H`Qf-0Ko6XZHcZHBxwW+ z1BJm^_vxq(<0pLzgxXEmy?Bjvu_Ix#6}79szfA5iI&?l8OE+jx{#~ZLkq0>~8l0PR zA?A-0-n|Sd#Df-CJa&~#(lBk8j5-Yrat@hu|Hl^Mx=~X#DwY;Hs#~rE6Fb47Jz+I3 zr(`YAyqs2-D7PU+TG9#Mvz2|9fLW?zg<@L*J*8QV7RLUN%u4(Y)<@ta)IED^T_D;H zrEBj>1xXcT(8?vc!WG$v%fiLZZ<{AeHrX!+mz+lGt&*BvLR1IcIQ`Y6>X%(rP^DiP z3}5^2hoi!wIwNi6ugd!(1F_1`dS}j>5+XhaT2t^VwulQ) zl-ZpHcf!z&FSgLoorm@S$_Yungn>ABFa4GiVm{IfvU{}gR2Z&)B((lhy!H=Y!00_r z&C#1*%pt26O{hCzt0VFcnEz^_JHURc)DxZhklmHwJ5~7#r8`}FKThSj@!Pv9@H>)x zPL#P34Njse9hGFIic+F#y(EuU%?3=Os_7TGm+X28$cdNYk-l8k^T{K`S{RI}kCLV; zq1<;{11bB=zpw^+csZ}^1_|7g9&ODc^iqC3O(R5}d;Zhdy5c`BhAWiRM29zXW3WX+f@<7 zhnM7SOChUMh4~5B2X6F+=IyS zjC(7?!D8OV9CLaGx`16-+J|ixmS+&&-Yk#%$0gAd`H2%q9e{tD%mv}}`_3>OV zflzyyNA@Zoi8q;R`_oH+d5mIsWUb|$Z?G#O8}fCY-PE#E-Glp-qcxaaV%Du|>2`R* z>hua|-K(a*EUphxcXm2U!oujpHP2JeLRA=Zg@IlBCMs0u1d~+Dko(;p4ZNsh$^2Jj zl@QFL<^?0h1DB%TiHN=OW#b|;09?B=+`BX5%9;R>RHD)AmP#OlkSoi^7pm<=r*gxS z#B#Ez(erD>lTh|3@|2(_&E$cU1s-YuiQ*RO(;DL%wJD{xDB24(JG^L5sV9W)#PUq7 zhtSlGFC$dtz))L+R4GmVmwTQD^Qp3N6cEM!E|9z8?Nk6%SAaXV{};I(9tkh<88hpR zQrNpA>y5+hJH3D?(f$_cPRj3PKc;-FxU^zf!84h7r%WkWXp~1Vg3y4&h-~NtyW@e3 z%rjpGEl4iC1$E3pZZy4ofMOw&0R8@E0Lw7D>3$zCr#)Aac)MbF-j-H^VUy4se9FK1 zaVtczp+$30G+W^(&eB*iRa;`u=05H+Pws58Z5Glx_?HA_4?=P&{6+InB@Er5-am_` zNmoUOQj)3$p>KEPTNJw@M`WK}*1!KB&b~1?wpw5N15UI3j z`_{lEPC>U$#SH2Ah-5XF*j8*}ZbJi;Rgxn|tVTI5RLz%psbKK7%Pr>y5i4pKjX^U7 zQ~5>IfIwfJ*Pwp;Vqk>8Himh3B4QyYZc|c5pcLB=o*csKnP4K^h(=a!RXmpG#rOK_ zXd++2k76uo99@ZAt~h{Vsvzh>%8$hna6Ku*I`K>uh>0<{`CKNUrlNsye<~W~B=+rI z)cduNcx{dxrS!G1_~&siZ2DC1g=9k1@ckhScqmTZ%QIT$w1j$+KghC2W97kaO4z=G zy2m_EJ>14LU)9frh3#Q^Ln98{m5^y?7s4uPA0!{)zazSLRny=Hx;`*s4_VoIZ6BO` zQcv!0;J?3nBVV~~j-OwlzWi#BdTyUz2)nbt$2VSWKahMUYad8I@O>-jeM{J19H&Nf z&5%EeSrU5YEtuv7Ff5}pN~-6r)-|STs#hQyA(=y6s*e}DYug&BGc=b_2;t0aN)?s9 ztSxld#G&cekUXa}nDHhmKoUl4$jJ_T0K}tOD8>E+0R60-T{$@t62Jtv3x&8tykMaE zsR|^3wPZ!4vfgnc0QMxsB;DSBi5-pNJ0)2Q-j=@Pi#wr zn79f45xP2JdR}Bsc-^dB2~$$l{6MZuIuElc+$oX;oFGTa)l$(6GNSrQBMwKT{w+-< zG{FPo=V&LJgegjG^6-$%OqSe|I7PkeQxrdgEfzSt%5!W^pagSwh|3A=WG@rLyU=z4%kD^ya3my#Jj(+|d7dv7?e%kQE zNFMzBnEnH1QqaoW*v9D}Y>#t{Gz=g=T(IsdrWKnXaNXQr7os3IAp>0v#;H>r?gh5Y zU|_bSwDhi)G9{gEk0+j;6-+-qLO!@W8MC1(X$}K-cJ_-Yf4WneX)n{hSS2a!k^Gdg zy1E%VTWn(czQ;)4MI zq{IFX{ObOT?E1fhZ<=nHOYmQ@)aJ(S*awjav?QoNpyc*daVY>USQwl{Ve9q?8-V@J zO&Xe+Vj8Bd$Y2^Y)@@CEt-70-D=gHFa5Tu`8?m&Vw*a=cLb-1MvbU?DKHg-LS=vJh z*2H@U?=L)OmzR_2>EDx+>5hL3zrR1d0mzdKTYs^Vx3Y(TZVuA6Fu^-pLbdGuMRPKG zS=z;)2psDq$0B|+%)Dd#;EK?td*I1&>Inct;v$1vGeD-ct>iN#Xp_Zb zvNDzSUxu$VyQV;9C}GSuy&p8kt%v6Bk#(i=flb4wHEjdpCKRDLIvuJ?cXj-mbXEkD z?DSUrcXXsool3d{>{mgE;du^wI!Y@8y#pU_6|Q(&gNi+e^H!a9T79I+9H!XvZsrlT2+Fwn1H&ki;Y4m&A&uI;|*UdiQc;i6c=MipMs4hq5>Xsd>nT=qWdtr>`Mw8N(QYb*PjDzQ zSHZqKmhv4Ms4~~|0HT}1PmX(1gteQ-?#J7%5?7$9IT#hZ8uHAZdw^!5mPoz<%uK}# zvrpk}3x&@Jt*847Hz;yv-o9{W(Y|qK!LBm0Z!az~mf{^LSMC0co3tJ~Ci;9f59{xC zT`-^t3ZNbyq|Tas+Ly}SVrK$I-Slp7WZPY7kP+q1;FikESCBzS57D8Hm(1RE;Vr7d zjud_r^G8AIS=Z&D%i~XdjsbVcl<|mo;lBO1Jcuw_^1OWqX#hvt8!Ce@@jrwOIadRT%w8N zOf1nQRkWvfEms2f5Sf;O7%{&3O>3FHDsunx;T=WNHilv?5kS2V0(YQHL{kX&t04h~ zVjQqRZtFtAdbvq+^=>BxGfwfFn4;8`kQll7BXN{31DY)nu?CN>IdaO}9ZCDVS)zIK zZ?ej@p~N%!t}@vMhK_2cdZi!5H|7Ku9wH=-ETn8t48{sFCncik^87hOIql1d%k6Ti z8pXBbW%oD(ZB0i|2E!o}i299M()l5emYD0lB;Qu%^)9@}Jih1whdW{EKzh!e^9_He zun_PvSR$ViZFB`MAm*&-42i-T8kudu8dc;MFf?m-=ps~;~Kb0V1G^Y3w1H+&4aWzQ*5+TuxBmeqRF_hwyb40o2>YJ^+;Kn)> z{7U&Z)*)mJLu00y%oAF;U5KiF6myT-TAVZ!3r6waqM9U2<8z8fNwrFPJ|!^)O**kV zeG5u?cyaA$Tz>pl7AOz^?u5FkL;!?tw^7lezoAXHcOYdUrvoM(LQP96?9mm92Ji_6 zRL}_+zvY}Idhq9M2I9-hDWe)f*=L%T*3PmQ_>+}=^ z%jQ={{hg9WaeZVpmnNMfKaGK3>Br5phOwRuhivyC%QyVZY!fqN=y;k`uTv8&t0#=E zJyJ)GlRZ$e&Cm#2FAzy5Km7V|??T;=(@u#+J-^z@AcJfNNV(n1Qg}rfi@(`j(W7q3 zDoXb-fBI0N(Wl|t&0y0m<($mDJ9dV-52`y3kq&8h zkq0I|(bh|r9F#(h$1QC?gNXB5q%8Op&bqfDn~d9VnM~{NfC@Z|&06I*>6a#nMWQ8v z!lJ)p6=A!+LEoV2$gJaNm*1fOdd?CsVDh#8SRUQ{j6%`>|C$Y1J128n8##R&vg(mL30Cj8KsJ!C{$E zPx(;XYcVuzNDtS;dyp-7WqHSue5w8RIbc1qW2>iF;Lbnl2s}>Yma&15UNsZmGPI}I zS2~sVVq;4QKa%drMJ9=-O_p3^tDSYB2lT2!SXN-!o<0&n(`P)`)A4&Z^KgUH!<+(u zog;{oU44ZO4T?1NhG&taNEO#l${yw}lv&#ogV80T`CFUz#nf^iRL7CfZ2Bjh$wgw- zh8nBIHhR9W>y%44>}!ouRgx%t^1-C^!O4D(U30sQt$Eiz7fz+soZ`bCeakzAdN6t4 z{&fy@_Qc^G$grBowQd;g;|uWO_ul$01Iuw=?Qvgp9mBvp)Y3B}mG6jznxo^}qbQ9~ z@*Vxjj&V9mOIcY$BX2G<{lgU6R+ zT)A?zZ&sd1Nc{jhaICD_%Jeq+Vgf-0o5GB@IrL70<*|&kri2nk&Z0*HLK7BXXrQxZ zAk!-#YX+ZA!}_p$$_P+`qel1DDAb|Q-mZwbI1oWS)24q3QYT4dB|j_1Yu}j*NO4OM z=194bICtY&Z&3iFeZ(seV3KgnfY85x({6AS9e3Gln8dTiuQ$D_F7_P6ZjMl7@TkZY zuTkyEPFE-{dJbF(V1AKAR z*nd?X<{y=Z59FRK3CPEhAf7gPMvT|J6PJj>HKCU!%#qBd71L}P2LQD#N*WC%r-k63 z{Q90~hADS<&6>Jb%M!a<|DZhIxnqB>izo?2Rx)Rid{KOOdv%oK5_iVTvfwc;YvhFg zYj)4_20MfeUT4!?uy-aD0vP`BD?E({PaG)COY=wsEx@WGx zaO%AXEjcvB?E~UH{oJJZhq=zq5JG5xdhia)7Ed}!Popb7$%sKEp}eHC4D z0T4POq3A-{edKv~-m)9PG>9(rYXM(WxI!afBc!+=vIRRO#d09=jcdmpk68_-Js+#z z_sD*cqA&=pbHJGBV665N!`5KxhggU5b@cj$W`+s*nk&L-=>}v;70#@;M$zy3+SL!e z-W#{47u_*FDJ@NM_sOKM>-~lyIZMw9D{Uys0d53Evkg#*Ym9n_<50_;74{+B32|QK z^~!sFn6>+gCUr#>Il6y=^!HWf85Gcax&Zh4nh@(|3PB~}W`db!b3pLbZ4=vi#yN>j~p14>-E=z%x#9+QFvg(#}HKsM;0TMD208rwBxFd&hi% zCQx|@{`wc7y_sKyxRX;s%|6&QMAn56Ae9D>l_l8dlb_R{p7rDG@90s>c!{hi+;Jid zg>yUM0>KtWF6R>2?d`tljMfa zir?hE9f&?Quux42{+bvqSH!RK6&R#Ld5S#{FoGhyD7^T$8Rlh3NR7px&4c|%ll-4S znE781Z<|CDX!H#Ts{=zi3D$WLs?OVA>ymRtV(?JN6n7yT9*bp7k%^dM|UA-`xxi+8dVK;cNHlO95Z~gKU zV2zjECgF-d^{rYl!sJ;NMf(SFOS86Ll&5{Z-hFKVxz- zy4m8ESB8btxi#VNel9_fef+R56;x4?xwxR<3e4-N+k+&T{*10HAB3w296=q;=2VGN zYt%wnMrKc4(S9eU<(r=HErADOl884%TEAJQ=)rcHbmYB4Tq+jO_A(5qnm5VTPrXzl z)~P%K7vF%G1P?=8dYf0xdw7TRW7MEhePt!?fnH6ude}iKbvZ{lU}P8kg`CzT%S%Qm-YfA+0kZ*o?un;1y_pK=UjTL1G5~3kP+sSk`<8w}% z>(8M3J+xo!28)#v1eu<4CbM;oX4yJgUpout`evP6!!CVVI@cIl3FgRt_3efL_UpSk zLV2Mllp!`TXMKbKC<+`igyB=B$A0Ne*bx{K;rZ#OnD81f=nD2U64Xu^wp@4iiyVU# z3juMi6Q^`K7wS~=BJ#dmBdid@*(aWvNi~@mX`g_;b1D1(gp8lCR8~yd&NT{TpYLq4RRNdtte*xbW@Wpm3!0%TV-jo2!6p(NEyd z)nh+}H^{#2*bZ?rS3>GeuAjgVT}L|*XE0$lm|^-oJp@H4##E!lNog?6RTr~fR_aZI z)`#31qqH~1+^*w#DD$_?r3W%?1`g~Ng>;bDQ?RIfag^}8myg;so4mj#UzIS3Px(wA z+R*%W{+xWx1VU$GQ8~mCerSSPY0pHvWlrFSb8fV41K7=t^S+Oy2Gg%)W)<&3Jr;y86 zuCQ(jAgo>_=aJI~1zOO+sxJ_}a@D|Pe- zh=5?XjVD<;eGBON?^JvYG?0WWjm>YVYf0nirJ+d{!XBBOl;iB-ZY?QU+t~;5HWwCT z#&n9`Qe91DH)Q7%ktOL9G!vK}x!shiOdvqA z*Q-yx)D6u7b7&YION6BPRXxEvQi3S+rmm6`rkjsMu~Qc77EUHk2UK)k zWI|S;pzIpCB99^%*kpp!8J`*n`RddBcr_=J3|&waI*8>1G{>hs6wwJa^)8?$6371t zqnMH9idIqcD7hxvx6YGvC>k1nNH^^=?yin+)X+=5@; z8Q2267wvbw6rsKYv-!E}Y@+slz9<3Yrm(<(-U9F-_5w{p?lw5Q^OxVoVZ9yQ(($17 zo*Y?W;DGBvFMHg9_!ocMQr_*y^%8`8u_>YL7yO1UdGeoS>57X8PMNTeia$SA(d}Yp zS5Y2XV%kF?x#)621aTL{MzoVP9z!56X>?uG`#iMQob+ZK3Et8=GnD2TDpbT|q_|o{ z(66+%rR;?-g76;pYol?^l%5;5aPLs9p{8FtK3)79ZecW9;;P-ITs?mj63H3il|ul( zme%#>QzIpb>HQ?I6PoX6HPtaQ+!3gg3akFD%TzO_mh9m4L1d)EB%1HN;|SE`R&k@B zma8zqxxaxU$8qiUMMuZlKk^$8I=gydn$Kz8T(0zjNsH7ykuG~gL<&b6zh*g-XQqj6xz7ogj z5481X zK@`}$F5)P26XQM(tPvsb8WUjLtBgoZbvpdB8=j^GP+N_Qh}MC>l`-C&>*#1e2D*JT z7(yjDQ4}oOIP0zN7`eSemO(*)oxx&HuK?AbC~&G_gh;!UgTQ8b;=XpkWpBOd-&~dL zG_zkdj-qC=D{a@!rF+^{x6QWo9Yfv_7ONAG*1x{$WOWYl`JX8JD=06)J=S9kTp|%3 zoj|xBMBz?hD;$`=kw})_3ryuvRh~Tt>nC~=++i!`>Utc1CBo{%U{;ypn|I^Wj10TU zSxYvP+mok94R4**xj^OT-N4mUz~Ru61T#%Ys3rbkTu-XaV=t>uLZF=xeqFQ;`6Qm) zLZFp&7rm1~=SQ@CDJ~LSjz;i>g698*FY|0_H@v-E(rFQ3_m$e*qY&+BW$>6#`HZM1 zXNwj;suIc$(y9Yk-|erEf_Pto(N95^oVv7=VDlZB#XqpZOiV->B90z8s!xRONosEh z`q47f@}5%fl|`)&h{ZU}e;~wg$rYd|v8c)nAv?^Im?mO@F_8Ljl8Q?BcQ@zLuZ}wg zUJImLi^N~|rJCW!%y+TLJ|C!iz|G7Fy7}V_OFsVADIR!1^_Dkt5@MPyG{E2{F_}#r zvhv7!|IoLm_Eru$yVwVP3sDmv5svC62X*gC?56%ZD{k*66CUWKkyS)G^qZSFr?hm4 z_$}uJnw#)Th<7*VPVjy%)(k_tXzkIkJ;X;q@|69&#I!6`Cr|m2fcOlxF_UJF=Z*O4 zq$}`|voeXc06erUtD`N^{N?)83V(Z-W)=c@hG6f~*d9mH{rCjI7kI+$7=Fir>0`gN zu%T`>=tw~o3(n@z&T@W`IICWky~8y>)s$xX4$fv!`lDh@Y6r^4bC95ZyLmEwC+7D| zXO=HE_nQ3FF$Hmfbb(l%DnEJ zr0;-*2Q=pC&Fq=;p__J*@4meUqU@}%UBFjl!y`(!Z0a3Bt?w0r+nTU|vpLEf%>DB; z=wA;?n}f=p^qo#)lyZ;yCH!^u&KdSk4BqL#XNX~IO8cxgxG2_0!yg$R=O>UkF{*Vj z<_CKx&n;@U@y75uro7csD9N})nP^gh2-a@Ra|O}8B?#&-QxshtQW3|9hC5uUTfb~= z#-^`UFIUy|%vE?ZYeFCplV^@aYKXoFQ+dCNK0@u1pOQsC%3C87^Bu}?`?Tf0!T$C7 zLiC{3^!lfK#B z_;it;!YbFM&}{ZxpumYN=W3IZFhHF)<%gZ1ie zF$+#nH>LN|X(hA1ju-f5Y zZ;3j3Z zO{~&nIo^O0U`a@wLF*e6PS9$K+C4?BPMLs1CP9|+7w}Z8X&!tklvAPTh&M1SUCBYd zzr7UPk)7e2nW=~1%RHs}JWb@R#V$Mvw3L2S{@E{6;Dt11x=?p)bYMs|qtTC4qzg5J zG$laY^sgFeeAfuCg-OSq=1FyC96^ra59`v^o1h^MSSPvWN>kM!3_Z!wIufYr@I%`r z?Xe!XlnV9xP51mahY5skTwIJI6|Gh|Tx`zOgFZ?%*Ve0szD(P=ZGU7p0 zhp!o&ycUvp1@(-0UZ5ISdMxe|;HpuZVjObO^9CB-muOW!c@v1QvMW{%KjZ#)V_ z7Cm@xL|PHv!luS7x6mGk(2xGWi`czv1@_1sb7-PXEdD6g2;A#P`|C{e>rlr{R(v-c zATbMW!JWu+le7isT7;a0mbQLwz}Z9{qdhr1e5vNefP}4*4snm@LcT!%x~%*|_)@;n z006XpCNF6JlV$aff5_E8DqE$cCEk;1qwT{ZV|=MzgUm9gN+X{Ps|2Lh$tIah8(Sab zeWnV|-AuX5FN_@2dovP_{(0|N!?~%+kj&j;2a(3-2>I^{(XG0dkP1;WCYstn2_N{`mjc3^_p;fUe8z$_j;}#g}IFtyXW1RkY#296bUgJ%?

R`8SN$7h#chL)e$`iVhiy|_9jvB5@GvK)xq_+ef9qdy5g z*8pi!c{5H0GetI<&R&#m6*}<-`hAyG!QFK|l^jiG27A_02QW>UpG368(JFXS|!U4P72OGC~7%sA3f#c_PCZlrzm=*UVvT#I`gM zIM~0hhCXZ%3u#PLeh2{dvl@%cUvXxWQp30-=-;JpMU~~gG3920J=(D;gB>m?wL1}l2(%mS1?0|5m0IsHF2>=ledDX zRiJ_l>N7lETtm6Mz7K>C-LAl3dY_3g*n8luM?#s%2^_5vB|q6AEGt1sZ+&Ea6XoI-E+k1X`*dm|&|IX=p3aXG5>lx#IU*l7 zXhjP(o8mJxyR)xa?wCF*=2RSf0Q>WBhd(o|RXX|4g%cQmYlPluSXdOcAK-5x62ccM zBxL^;o7$E^=tS{5Yeg$f?{wPKwTZRs93fjbZL(HmK6SeA-DaUCD!yMea-I6tj);o< zwZY2?$=ldcMM{@Fr`w}yzmgJndW$8kaUGna%=lzZXM(A!)T!!!ZT+ z{6tg@sIY`d-mh+xmXmDntf0bxa4JHArE8Y z>-Z8RqKq8l3CL}ujNOafvejC*#;&SFSN&Ecug4HfjR?vs8)Ht+3%qZ_X?(W^nIRwx?!^qt@7kc;(uqbYV9v_ko<@)DN%=I zRg`u>{WA<@!*Qt{lw0Io{&`f~(QZB~i;pYT5-Pb=D`Ot&NagjnEukcel8HI!$zus* z-q4(yDP0NqmK?}9ol-u9z@-$uDYYg7lTtkef4u#nK@jzvyfvGQV&U$~6Tdid2u1Mb zqM7;dERN8!lU>YUU>u{;oqs-;1=Xc=GP*?;8b3}49E4^;y-+NFPYEm3k@7((z;axfS|PU2tg5S zEdn$1l-vS(ei>B1g-8j+QmCN+l%=OZpPQ^KQ`83+@c>y>g&|s4zDZfSfl33EiAu3{0REFn+GN`9E>&!^yA2p2{D=s8-*m>wp^11 z&w@B%jWqU`8<|{}+B%lNSUXazTr7utwow^Ju-O@UUpo?f2#0#ML7C!`Kp3@Tq_w{q z6Bde{U^ZxJ$Q2cX8&WEU1^uMVQYG;yUvT?l3J!85DVjyP290!J2?lhNKsA$6qD2a! zh64u;grAusQkFVd^i;3{N*0hs*^@;e z_Ae17UG_8jt}!Y)sHGYf3=70q#zl036vicWGWVFeiuuL05Drn7s0lVBPdXcN2kJ1o zBwc4C#CQ$aWi?RQz4F@@E3`XsL6AkzcuK1tDnoVz>0H0n97AI5p6GFnrfaiwPM|L_ zJhbUS)>pVn^Q;_rxWCv8hCJ=Ba!e$u4hv{oR(llaI)dmFWGtMoh~pEN4fC>sDi(CD zQ0*Z?9cd-%!`!66T%y$M7DD9aWj6H5IN)UXkEhaa1M=>(T+-Q=Wm6F5)2>B#K*9=4 z%t9DEQrfCqRXF`mwUii^^t3q+Cw1PE*I4WjOU^Fh4ENrk#F}K?6|k3jw)t8*AO2G* zx&s~!JH-9+<*lYz0wmQ6u3~x2fc~hX8r5Kh8asAOZP%~prs?mKq+v)gbKQFr$I8&5 zMYhNe{KGta9QcFGp7%;x!=Ix8+`Z#HdOZY%S3rjgb zQ&yf@ov?@C7fVu*Ld@^eUnO@oX8ilsdIw&;Xl(DLY9zR-lvis8KUmfa2MeSJyX_9K zd2H^-og+1cK%UNKuj@Nm5Ec4ROrv zvXrM`bt>#il!X4FPg=(j75_r8t)6M5;m_5Ci3eKRm<#x-%?1uQ6@;d88kfi`3ki1Z z8tw&5x(Qc5>o1|p&5ExQY=+-P-MkieL|)~#s|DfH5Oep2$}rz_(1XY@BJIL)8e%!3 zs?OL1jw~87gz3cFJMb;i&Q+t_E1vNqsh-_zi4j9{*5x~Z2{IPb(KyHKX-Qq!pY?A2 z0wCXEFwbk3uFLQ>bSz++(PNwDC+BCOsU8eZs2K*b%b#oPYXRaE3lwmrST%5ebY!6~ z(3#PJ9nSR#i-;RTh%1S4g+jXi8Y6OF0`l5)2}kr$X`1lZ0&Aa}H_|byS@Ps$%*}ZL zPW|3kyJ;jIIH5|CtXffn6iz6XC15lrgt5Xn{v+;u1aohL^!qLko#DX?lR7)(a!0)y zsm{pgjB_~Zk4YmP;FT^|)kvco-7GF7aWi4f7-hj~$|l>CZZPLh2*Yd&+_lVog-@rn ziG}EoL2P)N62GE&>3cX??C`=sV`$o6gCaA418?*L{twR}9AVv5Q~p7mK8^0!dt4@Xua(V;SsB981GYCDj}Q^$Xs##dkiNR41YV$z#f^#GUpi|tGd2{^qluOD;@lzvYo7k04c1>`}4{i;v&Gx zipKYP&5*v5VP;R6!VT-=PnG7)@Mm*H4$R=EiaZ`#9rBp)QgP=UiFhMs{(z@$$DWRm z&^MgA!xaL&0(}}0F&g$pnX)lX{7I{~<2Vz3GndGKaisPQ8*UaXFdl%f8s&@26}W9E z;&9^-5xA|v#{dKBlt!NJV(RX%PbE=8x+xB4$WrPKReA-$R;1@kyvv@~a*r!9wzV4% z;lgZI0BBfwU|8`ttO$qvoHxWRFqf6LKYQfQnERrW-jJr59GwT4!YWcX2dT=ZH`Bxq zTT%*>CvTERuPzR6jPYvpuPDnto)h5+XW^GNzMu3Z!wWTDl!6T+u`o|!w zf{xMDuOif}rp!?10d7g`q&1~tasN&^xtJ76&bqkTadP!fg`>yaNH0IP&4^9;;tcNb4xWq zbNDC!jt4WOA-o2k41P^B80)}Jnjm&vDatbhu?GdQ3x@N8334gjJT~umngZInCMRSf zC+Mw^oY6}+Nl^0iEuq@k%D7pmmleyB$zy=`i&J*LhGZX*aE`m@mB$e4cHZWrR?xwf zNa1R%0^+OWcQbRzWJkXg;mWL)zqv%DZG#&fhRX-=2S zyD!AI38GVvoNry`#J2OeRM%K1fgJ{F69aTnN3wDQG!8s!?r}F2o8Lc4Vpy!p9NA6o z$?ulhTBYn3TUx0%Q@mor+aI6F?>#bUQ_pO!3D@@AB9y-bp7VS$QI$L%GunY{`w$x) zNTrmo*kUbzJS5k6##4bS1z1v#saIMR3Q8Grk-vF9ckliC;60WHqQJ`l< zZ1uD8lMGW?cM1o(S;6-jxZOF;+gIEIRQ#lBkLS9E0X621?IE*GFY_6}&Z;z8M01@W zrzoE>JkPAquGUCil+FNGiw?0)@Ls!u1sCyskkIm`Bb~QD=R65kfRU0Kpx7lHuSM?B z@@Uf4$rzn+RJX4VY3vR8E2-@kF>rthiVXRqUX~hP zI{^go4q35Zs{z`qq5f>R9X5-P+9<|vl@QiW0U5DJ8SqRNz=&JmD@-#GWvUzoIMdxX zz)5}dE(WII3LkDq#5n*$ok#>FUBD?_2W@aciMnIe+z~-ttN)1d=t@)dqRhp9{X>Wa*~fnGgTqq@8H?TF)ZW-SN(I{x1JXJ%lC1Q|m%CXZQ^Nk`iVc67;1% zS)TJf)qbNiy4Q?YRm0$4+mS;)?SxF1|9kF5oF#P()g53G7|6X!pJSW%eCo|MLA1^P z%|{zsa=-K_Th(sH;hX*?{2lTzxlcO}mgcC)t}BDPKj>v&TJ)a(th?}8^bGG!bp*^C zwTE+?cUTI>IcYT*5%ioepTiF!o@K9!*OZ&N>`>0eA{#t|4Vh6YPyfy^FCad?C)xYJ z*?SI@6qvn#d%qEXbqkV43y_1YEZetKDfO%sJ9DgEbZ`(zt0F;DEu;c{L*iuhRQV5uFu=~d^@FpsOYYuTF+IsLPH{bP%1;esNX_~hZi$f9vYIRFlxwNz_*-3zw+ z3Fnz6u@he+4EC8c7RwM}_qG+xEK;~hIDRA1cN)ODsl;VLA@k17S&NPZnlJG?&5O>aUew;~!Xp6vW)$OW8v1od6|ma3t;+(#OJdZ5|atgi{Ac zN+ZyXahT@dwSMNcMJzT2(3?^xc9hN!7U#hY)(0%@NIR8o*xEA}XE57*u8y40_vnqe zGexAYR2~^KC8n#gGxlKIGue+EU}x6XKk+dOzHOn-F!uPi#|qcMi6X55Ee~TK<~jqY zcAUO3Gy5~Z=K|aPsrSNO=vr?M-7q!ypdP?lt+6D3KnqvoDy2+VvHF6mxFR0*GH9}H z_+Q+?K|SNSO9`Dmqnv*+phCTiYUy2j$H4s2=h%37)TR-V&9W99UvnwSvJOoLA6j#< zgBS1{xI{J#UARn6gQ-4rrP%<)1&KO*4T+e406SX%enbzto`IPMDV5q32Pw`CRPD!> z;ElC~G#OS+(qZF6#m^h~m~YQAS8!)O3apU#;+8(Z%pb@s z3$ZOxd_~ciY?*iH=1!iIhsGm|p?`1_9IwWdYTI3wcvu5IN4CLdgkvhEaT$+AM!~gU zFFNRVzbJ0y7_F?vxVSHgC~e(7*R`*B`V_!+h}TJF6;oYiC%q~d?i?vAZkwkUqP{BD z#VDdpP1QMazAmgy(%}|cNi%<0ZFUhXNk8li_R#v~tQhBVe62jb zhhDy)o=h}Iytf%6@kj;t{5j+n!V+PkEm9uD>bT_Y0C)lDW%)$1g98>6ZrVnh2A|`H zp9x8L`3hh0GkOC@;RWR$2$?c*i`hTe7QF!~JOh^R_*)MdAJKhMXby4bt3QCScXJmo zKOnlsYUepWFi>x8TO)S%F?=#rA38RNeNPr%y%&Vqcd-`6`gCw$5!0h@>HJCit&SH6 za*RyUAosphZn6)tR`5L49T8uIj7-LO9o<5ri_=o?jH)6os#>IF#%iOR9kmQl;)INm zOW15|`2UVNZfY`%>2|bCpS7Y+2#d)T%J*mppxdtRh8`Y&_h;}H5DYPCu#XmIk#jx+ z?5hzm)Ia=5%1+HUdTDltrD62PE`^a)>a_CNx0`N zUgh-F+o>WR-TA}g&E3A#j+1}hRo&(lhOv%KEXLb%L(D?!=L$8O4R%_C;^qcVf+o}L z>DMif@2yn~H(dXa3GC!L>}(QqsBx6fr7RL`ffcQMU>=ac*RUj1p`2JIgDohzgk+(j zXx^2P(q0(ImU$~+vA=elYz#ybsRAM&38yfP3>TJ3*#^PbzpV8hb4@Ywv`GIEz)dYk zMw4UM?W=Z!V^ee7#u5{L%rW>B7wq3aN3?fh9}T@jpd7VG(yGCMYlcCf$|+QKMfiMh zj6*7vohmGvDn6n%*`|j!l24PgHm{GA-P`mRe5u?O?R3{p>IiVC4+`lao?EnFw~*gn z;hcHY)B(H|za4DZ;RbK3<*P5rt4cI~ZT9KzHiKiq6(ugK5h&l6YPknw6vYd7um|+R z^Y??}*qfrEFXyFg+_h;ND9Pm=HwyE=QtV}tW|Q~3`w7hNw~s;{8kpEwjHS|2&RqedUuun`xrq1JFv6eC2=a9V)rZB^8X(0eBkG(CuNSfswd zZ*3@2VBGKY^-OlrBRJR+H)^TgL73uHYKH(;#=WaGiD#LS&tdQrbqUoD_YvW znrIt|Dt-h?XGzv)DH~gV7&Zgu1>^S-&Q&$1R-q}cEK1f&Wi8MbjJ+^ZU+;m=QO+dD z!JCSc5Goj!A@Z6;JbDeT>ACSIAx7b?hog~<>G&=7v5xyv&&E6?99K0LR|+0n84HH0BGlrKfZ z`eVKwa+J6NWWXy}FY6SQ&KOLTv<4v=bd>H8bX4kLvl(>c?OZ;s_AyeoyL5P0q@F;uks z3w8K#N0Vc=iYYC^1NK>;#6u|PA#*JomO- zpS(S)g&4EE`C2@D`YvdQ)F<19YkL{q+Js?@>cn}c2#wc0|JAFo0vUiHkEQ;2&lS)#t?TT$yY}>ZJIA83FQL$~?wr$(2*zWW=-Q)kyx#-h9#=2c& z?2EnUUTePdeV=u2z9{xo`U?^tZaS zBTXk0wn@j84Ri}Ax1~sUKmSUF=FNd5W~Z0+tGxP7x{aMLd_<^PRkuemXrg8^5wxs6 zTs!%V0R-&brX}2!))vPPuZ17-LT2)VhDy$X!{=Cl@VK6R86PByXO1YM6E87&;}rfq zlJ`QqL9&SNaX@=Wa~_yzBvDZk=!?UbIms8I`x}{owYHjkre*~Et z->KEE-d~^Aqw*d;Q-;G13FWP8W8(kV0dq?>jw@lf94_?Bl9_t$O<6W%bq7*)sLDB; zlr@#cJwvrl5ymyag3ZBml=Pa?Lcg$wu@rs=*ct~ouwb>zH(g!vN+wy4`W>QvZGSy) zE`L2OoBKT0CWADL?vq~*|NW`Qtmud7eB%IyDf{fK=qJtfCIXWD@Ft0x-G`2cg6)ODW~b+NOE27Q#kg(NlB?8bJ|Ba*5Gj#QZ@J++=YsSpt&|!BNH-5fa8oJ?W(hrX^=6Wh<0R z0-q&$Xw#8GrM_1ca$L=E8<&9|1wv@%_DkWbVb`t2oP)FVhvkN;$g?K8?8zzBv>mtb z0-9GT=53}5Q01GQ(X+ORO4?X(qKlfLsrw^CAiAbR29Rn0g$-qTqZ$Xu-RgNV4rQ)o z4aDGcTT|q>P1(NA<Kpu%x(L)=sZ5HZWYscovhmup^@zHs@2ZaODT6PVpl}A@`X)Tj+dGlwyf`>wqi% z2CP|9-_Sy!reYRsqFzeS#v$A~YAq|977ucEeKTcyJPSdy<(&aUx^os#cQ8r=)wUyv zrUIFwlN&{rBF-}((EDhVIzLtFw9fkkq%|kTB$odJPBYgqvu34~3p(;*&&p;v>~V1* z!Ajq9cx-xkHjgj=`!qppUIW9|A*}z*fg4BuX|-R@TB?SX2Mp*sM?e^fP^e?40*5eX zDEbc)n>V5i;VD0hFgH~?hougsc7y<^cMhZ&2b)r%bV}MtnN%{psa)>1I|rb^kJBcg z-&KB+fp(yYQ3F zI)P1tniP^B1#{{MB}6yA&kWCl;h9;=QssC|8#U`Jy44BHckoQ4KCseBCg& zwq?VT*3n&l?8pMiX3GV|klQ8+%rki_a@4SfVXGoiCsOh~WGSaR9xW$Kv;g4=Rx!5; zhs}5n|I!X%LsG)er^4bPd=3s?Mnf{jHx$%SqGFmd%&FTr4ykgK`fJ80Xf2=E@{vA= zjGSJxV$y4g52Kt0m2-$p@wpwtRyb>L-TO~^141z=<{$vSQ_;@4FTo88^gs6WtVl&&s_ zK3x@9ssV5lZqfplZ-~W@UL-ZZ%Ib3zr`fKVj$|fnkge0M(pv*|` z?t@&-UvuE&{>P&sYh*blfedjBLz*Bigzh(a(@vWe+ONMid?peDDB{8J*tHtqT#L$z z(oy>WX}J@mcqZw+xEd23f?86l3U86j7`ZJ*$N6w{Cpp5!ZSN7uR)DD?3I%*>!$Cnt zoxK{i%xF1n2O(k2fg=2)y7n!Odu0&+O#LwDjwTPCMV4@4D*?U{t9?eI`JwFhO@Bot znl~{;!c*6Dep*OGr5fU zMY=kYSWVrNHUFY=71Xkhv$!b@BcRI{moFF9c}Ml6wOottzp)o>6=!{OS}94O9NGp_ z)_N;jlI77EtmKpH@gyPXtPXTX7f)^8(E^m~Ia^WYrUGp)rkVrVVd@rRHPP$*tOhIo zVsO6MjA7-Zs&bJ)Sg`AS)m$3HCde($f@*yRZ##CCqi5tE%0$lLCGu6<@p#obNh^it zRmj-fxbtbNs+HdiORZ|&!<1%q8a8{rqcR{*90 zuA3)n0L*F#vCd{ZiX-PH@1AWHaAfXw)BcSG68k2N76rrduz(kaXMFBmaZy{C-xH?=sHcwl)O>xe?%?;aeJKnF#o7bfF}#y}hT-u&L8(D3 zcT1W|mfL?0eG!G;`T6)iZ5ZFUWKii)l- zyESJKoZAtaZb@4rJdoI(y#y*J-eV%LmG{#}$vTogHLPjVr<+B%L<%WU#$@zqsqFYb z5$xy(b=iO{0H=;I#I=2KkJO(ZI5I=L0^?!efE7TF>R}}DaWDaJgl<7NW75AJVKW{W zEq}uO?n-#LVZVxgyn~1#AFAJPCJp*xB?dw+aj<2FRKNUqFHl-c@QW49VILs^bHrK1 z)?mq_`-Nf;3$fQ0)HbfV4z$%IAsh3Of6sh2+=jP`#z5aK?)HT?X35YXK5Jkw^KUluy4 z^jo{~D;(G&>c@ys|MgAB4JvrSOPUizJ^xUHQ@P!Cuiyi#Ckr@-V(Fi*zi@cH05_%zCcBTh)!SE`ytAFW zWv}()DGt4uSGQLSPX@G8`@E$w7)`P+J(l%8*-RMdwlf^G`xnJrp)6$&wZ&W!FLnQc zuXz8A@ilfdCG)E~-iH51f`H+?7#7YlM-ClD%FbJ)IVhv12KZ27`BIsZl|`+m!J#uV4Gg(^>#OXg?hmfMPy7N7-op|ffqhcE;S(Ab=`3u zxW36ie5~+i>MIdc<1nAuSXYwfw&jV$QFX+rG)GbxT{jC^IOpUOtnbPad=;zct42$4 zan?&)bOV!juO}7>)pwSCvvOk|e-W%g>+0QiR-T5~;F+oTd$+Q%&b%*Kjlv^Y=!5^@ zrVLshOj{0uar;k}R7XBzyC+>&&8}DbSnS?R?4GVZ|F)8hk1EnqZ^x%#2fUr@_&oRZ6m2PCOhT@th^XBKAZy45XX4Gu?$}!YZV1p|6^eb) zWt|B3(jc}KTOR9b>7?81O!P&z;fw=M^d-8nsJDnR2W;aEu$f=cGiXy&aeOE7*wGwX z(M-D~kqJDm!6Ph$&Nk=e8Gatg!8~?ABXn$B5q|N&=ID-eRct5Y`O@u3SE?4|-V$bb z4Q<4@GIe^{G}-~24Vzm{SD3=xb2{6(FO$| zP`)-wUy#4*mi>eEe8gOnf^T@>y~C=2!Xn3q>-p)1RkkC^`2{Y%F`V^s2(r~YW)9(l zH~6L@6a7Z`nKAe2`WuGnNq)MxgLsPNJgvfKP*nGnI+aDH6U5Cuu1N+cKIwo?>rTSF zb1XQfI1oP-neMqF2~3I|$DHYJYbo1uCFs2POq6E|emB=GSFgP9#7q}ft z5)(c1`?FjF2c}F~a<}WXr`ECM3N9(+{a!SNyA9#R*&}8^w*-`s19Ib3kzbRbu)$p& z-%JQh-(4_u5$OP5$Ixb{joj@y)tMegiqq0MB=q^Oq0*?t(+~t>qLWi@)VkM?C#; zrW5wOCWWrcrt0a`f-aww7Xky)vb;P0$V6I>C$)X=;=kw{Zd+j@&dFcyFuh;@C1T^* zJgq_w8U#e~+kE=pj&%R;Tc{eq)b)Rvp4Gqq?Z@ao42~h(EIJOx3&h1#|hq?47xlon=`I5o_LSFw!NOOaIZj12JO6|b_);_vDg{+0$`)1rp-lP zGgz~qc46IQ3WiOWFbiMe{3yH_P5r4*Wq2-4pW=x#se6)d5+w9vyQ;&RswMB7-MzIM zcu6KXyq?Ls$iTKS4yUE=@D)EdfAEAHi+c3_h3TN2l-9!=Dv{x{*)hfTECi|EV>|tA zyyFaJ&h{LP0^qiNGWi!8Y&sqe%ffFP`-MqS?P#85`-1%VyNn;4xvGdwXUhD~&Y*=@oq8kKum{g6A3;yfka^ zylU?;iQ%K3Rm#&M#sGNL3*Onagv8L58z?;hJ0IYWcC<4yjFz1`y-0(dacBMmX`lEA3P1F##Ah_4T*qxAzbrRb95C9smlND(V0EtZH)>-R zk~m?R26UeKN4^+;(GFGjzEWMk%4&99sv8ye+;0OW>IVaDGPYLYJ&PMJ^vThzT%Ekr zrBKpZb8&edby6KcXi9x^AmyTQ^APF0`n3FEyGUtRd+p-D(+!x}>|U6;5gb43Y-lF= zkf;ajF1s`M5=R~eoN`Sg}B*TOem)T{j@zjbmSe?*ygG=7#^Tv>7-`bh?Z z^b-gcufcZ(rW@(^v7QieAG-2a!4;aXV}TatwmppjxLUYvd^5 zS|=HN?Yh+oqonl-8g$wB;@+*D*cvVn3+>$7wbEa-2`rmgy4v9wXT@y4z^CyN!N3|D~(hS;EbPYV+GHL{MPB* zaOZ@(F0?(HX$ajjFfv`3AK3(@;9jpel8r{5h}$m2(Y^vcC6*{_WK!-cMP`y$9xaN& zo>Y}%Q+>k=1o$HhbIanKeKxPM0^d6B52K9$iBRuP5xpvP z$v_Ek{mkL3$MaaO>hh`MrdQFp#7zKFM$xt(`l6-<0MeZ}EB zx!a&3WR&0;K-C^z>P6K6UdbHw6se}ntV?!FM$pRS)^-MZXo#GCTr=CD@zrm~4CMqKz?<&iE(nFwyeT$#P-kA z`ZC1FtDnwVMKrL~Tyv%JNe6cqdtIsiUMpO2bacr#V#u~?+GClp380~|PdF#F``}D6 zX1&Zo7e{+hk0plaf9`)70lFLcnqm*pv)CgDx~;)N6HwBXhlwGJw$` z`)rFe;0m=ZD|Af{>XlvU_!ra@H+mP0XZ-Jx<`#W%9Dp~=UWqbIIv1nJFJ|ZPj9kwJ3*BowOyv$zMdmAWJdqq$o1K)nx9V>U)PTFq4Q%-AfK|v8OKl zNWyt=QK@EPT}_UOKcGP<8fkD*K5u0S+<_HHA5GW(W^e1=m%`@mNrE$Qwge?0b_*l> zM1y?xpgfEJT*-Em`bypRH3a!g?D~p?xVeH!e*>(uXXUi3%&`F@f9)NuOC{xlzA6b; zK>WrW#!2*bca)mSfl)wIGWm6W_nHwB>@)8TQO-b>T#We7S3y)Pm1p2^)vDjnYyuhl z^S=lLnyFx13E#;yhuzhFLDSe?Ug7p-(=C>6*0% z+qRs!$#hzYK}c7krheAzMT9Fmge3^q3foOn^cnKqWtiLvx?rE=7OmdA(b)|?ZzU2Q z-t|1{s#Vi6m%!)@Hb|jfuUa{4I`8YAK1To)jb{yJ>Rztj;?b;12P^LbnF^}ctMIoB zB(Pd_`w+BUdTKP9w2G!TgYEs3nkl^Qj_Hf}?`#`vJTq;Ji8pLjrd2}LZCgewk7c*d z+u(zxKaONRiCOJlI_B#t4ZL;W3*%%a(%@JKLyb}zJ{`$gWhDt$B5OpE2lB|Ln}as3 zV--s|{$}mJz=E6^>(W2tILfj}?tvftFGhP?Czd?y z=yxP%a?`%ExAaB>*(!zDvu4sSxS_8@jyUh@jf6O4cXD3Jd zUznUkNJoB0Y9};`a|N^Q+Y<#G??#IjMC_R~_VNuyIIPf$%Wl@=9}}pG9pV%!`F=7d zxZ4MkN$D(1NRYMaW)w#6vwlp^95ee#;tkVg%FO`KQAt71wha*VjrUyRDD2~woC?11 ziY*r3_(t|vFJ!u2IX{^%=909$A_oZHdT}m#ev{TRg2eRk@I`{~k?cVInT&IZbJ}vc zg;xq%nA0wRJ+*FwEX+CZRDdnxk?9g*D}RTM+*LOza0=W-Kf1NcHCL9li#gqm_abKE zPyc6l*1RI%Cyuy&tJxT03|UyEo7S+$Taxx5L9kU&tUSrIdtm$Xs#?ca~ri>&6!~JfbWXlxLZ+ z_^Sv&nGZAhUvq!7b_9C`zfJ0@;Qtr7KT3us0K5N4`uUC*{Xh8A3zfC)Pz2FFi*%YQ zU@JAODuaYdVH!+3_5GQ&jEqqSVAmkGgG~c%n%X(rcMh}f&7b|l5Qoft6K*E_0Sa2O z6Sh;SzmK`ir(TXGo(T23elR+yheWC3|2|06m{&*{Y>WEaQa}5+Lba=ytTZkE}y^6+Ua<_{Cs!6xGt%$VP{=Mo+OybTad)|%@aS?W_sq?}I$?dXy z^P!Zg9IkXLFd$c<;_42RL)*W->o@kJ#jlN=ve)oX!Je2m+ypJ)i{OfFsMClkI~brH z|9iL&z*G@f^;Gl~RdLjxL?~ekk>3Yhz|q;&Fc4J?n$OxACPr)$e^Pzh1!SM9 z;cC2lq2F2PPI5jnbB6-0>^`Sp4{|`au-JnNg(Y6lEE=rkjAFjVJ4@bun(g3YdS7m) zMM%CJxokK=v#P_P?=ieP>4_gxM&2^Ja9UNY3ALAJ1m7>UPq;@ar|H-T8WQbZp2|pM zkm6c_w6eiH&S#R`{DNin;1qWu;#>IHAu}#^k$0rhN}>i~ivqJ~W(Fnl8d@W3bjc*) z;KNw+pzDHL%JpZ`My?PtE}CGtDdSXT($jlb4Z*;rR7P_QbBXdJ6iTAV0r~%|Qqu&{ z#KwO22D~Z$FWBe*=_UP-20@_)w1LWDBcFK__qZ&SA84>B8WAZA5va%ls3O#lUT|V$ zaP&!&Bl1?pRA`oXkR{#qGUsiFUM)=PMtWMJQ1nLhHr}_bb8V|eZ<~wr^E>C-i}Typ zhV7TDOiA+8g1=)Ko}U-*$Nb0K$NauspS$DLD2lwktMcuq_=JTgx zyXQ`pebQvQXHR@T?zLYt#k!LLzSr|#vxGtK-L%gNM?Qg|)V(3(Qli>SI(hV6R3dm=)tiwZP(M#*d<7WW6`ly_vX^WObBx^q>i}<_F`1gQp zCf)~T-{PA)9|KaILIR(x8tvS(6Te*J%DDOSiwvJMSH7O!kGDG|WY?zbS6ySX(_1uOm!LJP9sWMQ;YTuDD@Sws z=EumLuI_|5Ph&o41?fgVv`8bPyk=5ZuT7qhd| z8>THNH;BfkPGVE78V~9dnY&2x5^W}5M3Kcu-Z+Jq)&aCD7@ErY+UI4Qm!t{FWn{4M zYqw13JzGrqD)`GLMG?-On-^k7eHxx~F)YRVwFgBSLkUfrr(@2kGkv(zShX2M zeBAYIBkWeVbDO-U39(~zrBpa4l0#f)--&X*8&j;N4T}n+GNz84!&2)LGAw_ew6?M) zO^t3c4#&uVY2T4je;z!PNdnbYc-^0K%Ig?yB+T85W9!v5b4os7A+ zV)*~l`vsoiS)4lJOf=FCS6>f{>V3wES$1dpSs#iO+%YT9wP1FZ5ul7aH`=gMQ^9TO zRIF^)f$Z*v`6o8wLhk7ZCoLt50QIVnmj}2VE6CntK6F`51raPTob$7$vs4EulwvZA zfW#1+4Fr({DU$S-Vm?AKbA3gF)y9bwFl`C9iaZYFS1vMan)%l z4{XPdKgG~=z}Bz4V`D`0P9j)7#l4r!tUf$<>dLa4c@g_8n9AOhw~8p`kba^Q;v@NM ziw;a@wZjC4uwJ17lUc7YfYGd1hvjTt^2cv4pgp-X%b5!=f?EM76()~Mr&K-?#i;kH znS>Zb(SK&fom7s+-K&S9M+2wN-Z}9=g}vnVDV%)bvgcj^NUw04)J3Zy_rIC7d*R>V zfbBYoW*F*=wj{GWtne1^?wQ>^-@EX(dz|Kwb`}pE@5@-vQX_t895dYBadr2sv;I%6 zut@%gm%wpAA3n+)!vUjR{iXTn50s>GV_qD@6R$x1rI(UlXY2R!!ff>5aTajr-FbJ( z&#IZxH&$HTQ+A9&U$-c6ryJ4QcEnV0<>yXq@JU7MK^ub2%!?7K5ODLwW@z3O74aLJ z1xmH5bCK%m35D@Gs^q|jfwQ>N8C2mdX)>5X`5QLIym2W6CDemCwP{8fTWjm6LZeKe z*W@FCvg*S~U9O4XVLz=kecmkxxd&mMv zo;bCzgsfJ&?(XG08G2S&QPQ7ggAQKOzgt(vMAX1!PJS~KgQ=|9J_{(ieSzt87~-8AM-sMkda6VE64BJ2MjG-{?UFj>EN!fX+i;^=M3;hs;uC+$639CyxB+K-jUugbD6N)mZ(u zQn!|%|5i<%)=K^BuxPL`bj&CeByQV)Cr}zv4?2jnGy-LdCh}3QV6dqBsFwY)z0IJ^ zOCPKU_TMBvaznnT`O6M;n(=L#y-T`%a{F4DVdf?i_}afSWJPW2s6}E6r!&gqD^a8J z;U!%_sk$@EV)B-41v~I}ua-0PRaA#tf|4oq+W{;j&HSq3Z%?NPxX67eZo~$cRQ%Ql ze0)w2pcoaZ=8ILUu2u+2>WZ9nVkD=&7{QMg7Upp#3~YR7QHmOCR>dudo<{6wvSfK&hnOKon?WavBXQ8R_8)?{VWW8{<%6U71-N*a>`4J+4*q&oKuqtmF@G3WG zD{>s4o>rsIvN*$Ku_#nL3t{;sxkS)(*~cppEdZ9>0kDx(Gme^o2_-)yg9jqBufU;N zV-vF~AmLC#ZE7Q}S-{ev=I#@}mF8s+A!2$$59q;kHX|Twt08@_Hw{2-V$uq9|DYa1 ztql?`t}^X-`Vz*v$=^(r)8eoXv@p>*fb#NUm)Lw>RZMwy zk@#lg49{6uAkPOYSTQG6S+2R+0`3n^`O9KugqhJdfZB*>j2y2>y^YHhQQ42b*pPrK zCzX8X7_(+F1Vve&U$kJzYzkyxjc)+G-RwIfrycbG{X`TU^=A$*8P>|^SI)Czi(h!a zAlB1V!drX_yOHMT4#ScT0UOv^=Z^-)vi#!)UMD3HGy1dQc@nwe!pcG|e!8SXyPys6 z6F4!qOyZ4HIR1puxca;p&vJXk-KykSGG>o5d+8w9(UVn0{SjCHwIF?R77omV40`Y5 z6`Co!3Ju%J6nzav)t#bs8gdM^=R)(K#y-1rqJ#1v#bbQ5bU!ux+@Bm5`6bLk4YVpQ z8D|6OFcJHV=CI_g247_gnqi4VADlK-l{%~P$DLy36%YGDrpTrvi{I{1PGW@;*wc>& zF%^pq;l*3scJUZR*BHykIg`PKOHrIqO2Qw%k6|~C;1!e$*m(pd19~6nGeOh9soVX= z(I84gie?c^9^obn@h0>2xZ+<+{9K4>F7o6K-mGG;2y^9UK$t(73_jpZ-Z^3~w#9wE z(Cgj^Ps!-FUKE3r`b#%wy|72!M6k0Th2g_ps1- z<_*c^ZuZ;T^bl}2pY9ci5CA*#=EY&{3O+hX=KDZxBHF4Q`dnx@dWd_5WN1|rqr+Lv z=mYfQLZeWxK;2e9kxtSOCt2uKbZ5IAZRbHlq+JRI7ne<6 zv?J=U`NK~8sHK?iQD)M`unnqZHQ6j?wdmzLgS&w87fjH1CRw9G_+iPX?HZ){UjU!rQjyS&*ZZr6-ZwfoS*(U;w-zUlYr_J+=J`(Sj80rc4iFdkO-qjr5 zD}iOq)jq}-C|xn(4`=>7HIL}Idt((Y{$B5AmR~2w_jIphX5IpXv(>A@-Mh@Mbn->p z4)7lY$aj#3@3?fBN12FIZ3Sa5v_UeEvOA(M%5pFc_?<8rt(5+2$5@PKMe}ZXeI=0G zd;-<8=QFR`p+_7&?zNs2-q;z4Tot+1f9{0i4{yy)VFa>E-ZeFIAHa#ngw8`^4&$X8 z)O2;u>TVa*^bW9cCjYW=$6w{%LJc+lIwZ+e)8i3H7U_(QQLlnwur>9B`%PC8R_}nS zvqr9$kkHyF%LaK;*ZZd=jyE?wgl%qBS`cAI#scfeq2Uiri60Hsl%Q$7G?Oc+YM+vR zKlWkUbckFY5*PHkN1r6pZ*&S5r(Lh))!M3j>$(cef`@x&Q{Lov{LQ98^&QXJ!8!># z1$bqhD1BTXruQ}B%NU9RQR;mh85V)C63k(C>M?@i+Zgj}u4@G1awQ@B&x~<+)@=2? zDs5FxWEZLoW9+HNP_AL-SMHNzg^ZvdyIV?>NOIJ+&3gq$kCbv# zzYMZVFzZb}C+r7!y~X&QH8h1B{{_s^JH$x;IB)eI^I6Tn14BlB z0aD5t91g7g>N_DX8M_q+a@%d1qDyt`Q##u^aG8VahLqBrWql&K3)v?2=MnggzL$^_ zIwC?GXh*|{bSa|AZlO|!6xR0G1~#BBS(Xb~hrJS0BU=A`Elj#aOj7+6(qt2MhAo}K zR1r+Z!9;n{XhchZeNhl_|2sxjLiH;8)522)ardFd*#SEkByp8U_l!%r?3zuA2)hg> zNm5)@J6%aTa>=Oqbh>ZuVNAZ@A7R}~t5l);M?yr~Q!lG+qbEm&vi%wQi1EPW2=jRf z3WsY9#|*1&p{5s6<{&Nr+xGUGOs4g0WO-QGkjRjaV4IJRmrv7*&*6*5(dxHe6R>qe z|N5tSJ|x40!__fH*^9aOh4pgRG~;k`W8C3#A7LvfmIgi4wi!fW#Dn|x*N>-ZjL@FW zQUTJ8o>2&!{gEO6C%}yS-a1(1a(T;4&QmHieaFnwSQy_4UXJfz=Y=>%mzbz9$P3+H zFCWyp2;9ZlZebwyl2`HdCr@5p=t)_ALZ2~%_n!>$Qpk-cFcqSwLBp{eEzE0zqJN-i zsyj#MEp7P;U=5j5{R@A;QH1CO=e~>c9C_x&_ii`YmKPq9FZTqh_|Jk?g2%HWT5!Xe zf{TI2Pw}lE*FQ4H5xxK}U=lv~cfPkQU zyYM9bJB>xz7-(m0Eo2D%?!f*>^tvDrXy^JLU0E4`qm!wvDe!-_z0}rSQB9G)Y}ilZ zOxBgOejtyD!phDINzFDTgvVhtqyVk{DhaNV>Zb>pH2)$E~p=_AZ`&UK}W}mhw)ibr#aUwH12f4cDt6YYjaW-#+ zcvvTk3EYvz@HX94$p9EN%Bt<$q-O#Q8_e^M`=KlppgeOCr3XDKQx#LkO2QEC(wl*- zb_UeU*FQ_}OdruSt4&#|D6I`Z=|feAEB=MYD-PA)mdhPN`cJX~Kkqyua3?es6D5tM zjVLNvTGLS0a+MgsZZeUf#*?qfHLhwJgPMr+RD+W?U*fD|`ap#YL!F>d;o3De8>OaHS1!4P4jX zN@1bWml~(Vb${zZFBYAejabdgL63#5w>}(D%tT~*6gYjlB}Uh6sW9T;QoT3q4hO?h znw{PNd8DaPS+Q4vt5Z;8iiUvrOI@{77QS4QvxlQs+~v*)3bCxZ(IflK7A*4TQ0*A( zTbJ1~yrqw)?VaC$1M$X^z}SywJB?*4&LqclQ>< zOj?dMMnSRK#pH zAxp=~MyHtR&oS>)Ld(SGMySho}oZD2ond`6Q6UwmRN z1JGhzD+isNuP{g@g-VoJ;{;s7YgX!VCrmFCZL3mnF3YbO+8TDzUz=7s#(BfzK1J{R ztGDH(#p8971>%c?RFE1&+L~Tqj+DcIB%JE@#*|5kzx{V9z)U_t7XD z7PZn}if5tBK)l=l`Dc7QI=FgG+AmZ!D56$SL(S6Oi02e!p0Hw_iO<)RT#ppwz6g|} zSHcu9z9SR#`bZ|+HX4N`yG|e6v5ynn5`~y_s7~xjAgtEmQW}(vPar#gpTP&zxmq+* zK2$oTPzJHJCYw;qHohJ>00kx!@md`S?Wd1a^(*dX#RB5&+0KGzy*`kJwot%5$83Yl!WLIussaUr@gFRNWfEfbu}{28ICk^ACaiTAewx_NisD z)q0Ry=x*rdB@q4JGqP^h{#4n%%W`Q@=9+F4W?NKb*8V;^PpwjB=YnxeGZD3&xXhMc zLkBK)E2=W^hmc%fQu|HkMu_Jv(q}@*<`{lnnoMqB09KJDbjI*}0jxu2*V0ozBt z${^O|9-}6h#QZvAB=T7ih}h<{_{@2h{2zim)cY?EiRd`L-{4>W1--K0yQx?6Eq)Dt z7hkFW_rm*s5Wp%`)|I}=Q=d(sKLCMBIRpx{N(BvtR0M)@S~1AQ#B#B)S51bwhC)j5 zXaoHxnbSL{ZWj@G`$331!oNQyK}&xuVY8%uxPE;+zD2ih`+9x+6cE<)3;$#fbdc-? zL8-)2vBwsMiNjKh5o$xn_GQ`wt7m4#&WEGZTeV019jqeAV1>}E7Id0)!M1B5U!LJ} zq4+Dj%{bjGi#r;V9BVC{J4qcQD;KrDzz}#^C!nI_s;3A5srZC0910phP-2} zB`(8+JY8oeCcEd>(2rf;rSI4P|8i=%T-_ly^ks*DmScS4N#G_+Q(#0o^$;Wdeo{EJ z%vg#NQzUk9FOKo!A7*W)R{C4j>3TZXRXt1{PP<& z;VLBcR$5{0!BvMJH;l7PqF2AgvP&0BK#y`XyeXE$a1!HcRMbl^53Us(!{4j&rHLsa z$Qw=MZ)d_n3gL5=%XthX*wf^K8JC@R+rnyZ@HW?5eOsNKp<8`xMEQoJwhUwN6?cOP zyA$r`8|*S8;vaHn^X-5yvsXs&=0QsrY<*41q{GbGwC4h{PF*kp4^^>U$LEQ}nqxtAhd#Kbo7gSTJ?5*}r!OLM+TJ z0&qSem|#Pka`6#!v@%!r5scKpmLHF(|M@^tNbzFE{ryewz=41W|G$41|8Ye5uV<0} z$P1u%O^MA#77-%0+#u&fIQd22!mz{6l>>z`NcMQoDq}ni=kf$)Av0n5=*?2ARO=;i z$fU|yE2BErtnwZ8N}*bsG0%$tZv>NYxN()`c=^)Ret+?Kz76RM61pG4NX)4b#Kt*r z#F$QENNUd-XuLtb>J%~?upc3(l8Z@!{lIiqEre9uht)Gql!1_sV9v=tazsm!VeFJO z3nAwn)Q-7YVy&d3Zk%9Nz=C7MIzib#v~wu|l`J#@qf!Vjy^Keajfw>ACkml`#d^0^ zC?Z#XUyn1Z+02ybx`M>(iIqV_rF@^G%MWn-yDTO8qN1 z^G5wmkyML9WhL7tB<@_i358amrdWCdWpoctB`dp^`1EPgpSTglbZ|6W~DL{ z-r?^YO63MU3A03u(^uj@o>Sj)u8BrTxfAZs6cNIhyF*?YfLF5?WgjNZ|E zBFh?bo#fwqgTRaSO);{K#%|qp>yAB?y4ox9f8zY|W+%MPLB#eRI5B3=wtrGKdxzVH z;WKYz!15kFp%K$(c@3Uzw(ja@^V^(uA{TBUt65}lTTltvqgrHdaHG)n4N9FJ?n{kQ zyK0?Z#d%1@}8njFQ_j<3v#HLnN1@J#XS z-dFWp_qV z_-aY6iiIYeXE%c}b28=>mN$)5tD#j|%q(6W#`Y_s&}Y9_%8_(?0@0nHjr$QVu{W$t zA|n0{x;`4+R)5EE<8tJ+Kmxjey3aQ)_NWqt4WM8Vo&)Hsy){s$7d@~$+JT6_$?cJVi?sq!9)&cZeBS*kpCJ){m!bg@29S^mM(L1DKSt`L4AKgu0w$9%1S&o8xxWMx`N1=(X>8kovSngZK+C zunpHG>!EJYG~@Yd=(Vr(mPJa%N$;dM7Nc*9bn>}+2nMY@kr?hjFMvqAw|G-ycZ`P+ zG7{(4X}*bjRNiL`YENpeRu4i`FjPq=eQk z{RBiievlzB1e63}FrjD-CFntHSqAbQXM&ZDOBm-ijj9!mk2RU@cGZZK{vYU@UmSN^ z6CJ7UcSqj(S#L)-#h^WY?bbCYE~bAVyQXW_e|qld;ch_k8(1&W zzU>$Wi(@^q;2Fe1P4kV-3>Fa>pE=<2fXXvJp#9~UTo4Qvp5W_Wh)#KBQsy^2E0+0~ z_{ksAZ+)m)lx2M8p5@jnR^B}zs{s&}Gn z_BC*A9z2c3XAU-;^6J0K0H?pUQ+9 zBB)d)xS^p`T=3I)YAi-ha~Q738ZH$MM>q++{$({1qK#!SAeTZIL6{*}CwL3a9nKr; zmHEDY4n>ZD5{ksogXlW>?paO4^bbQ7QXolgml4Yzj}0_su9 zwVq_>*4@djW_7y+67M@S^>v#`pU-j=w0oI*6J0}tDU5cZ>MmORXY$|ooV?t%q~5a(Q6{y9qT2kQHd0D;iy-CYm<>eFIKPXE)5P^48 z-=dW^+-gOfkX@lNr!lP=EFQ3VksMc+4{QID(Zwla;n?i)gNGdL95v~a zr488Ro4+|vs^FV41hKx*q%TxmFUpplWzclegMVqcc@X7SSspH9sf^`9Yo|^J|EyK! zD#WP!XBA*cIy-^5P`pbyh(@M!$>5litC+Dqa>h)Y>$pNXju{a!Vx!n33rRuBnYb>v zaUp_E&12*CQw^hsbkzA*TFWSrNrk$;B6SBQ>2E&5S8$;ke(}pyU?@8IdG+c}3b~p- z%b+B0*>0H-%|p9=ew*e``@ZT_EN#Yax!+gy7Xe^a_Hkg9c{+it5Sk8kAwu?LD4`ba zsBo({*4P!h9P9%TFPJe0h+HuX_RO(S^Y+v~S)Azs^Z-VHL462`dPP3+s0G4K{VjWc z1Tst3PcG)HC?aNVv{G~S0}0$!18oz?HQ`+1$$Oia|A;zr!*)g7v4_A za1~6|#&_+EJ`Zlz-24#LQOz9nzKd^y@8gN6dg(4r%LGOOQXysQR|Az-p|_8gwozYFr=KQLPg)CQ9QIM!xgAXR9_&;&46 zzeg@8tyk??Vyg|>(uBH%2c>QqVOJToW7N#uNd{G@>td2un5^~ZqcL@-^K}R9X=>ZU zk6D?#aFkY=Hv8;}I$MLgyTjKq*Va`-v~E;`#=oSj=5AP7eYwEb`boKNzgd7g^<3%Q zkp@_?HplfiQ(My)vNge82$G4j{FSTAC+7B`u&qX%Mt6IoENxZ$&+{+Ir4|w`rM}|> z%~8-oA*&D=n>1dS{g{R28anWcgZT*C(4|-IQiykQY_Z0b67b6*T3R3e^7fiSbJwt; z&X$y5+x!O+++)TJqY$bXxUp(%9EMKqFMaTII0@rACT{GFWUW>_^bo3kbT6Acr%lx6 z{c5-rnMOea5Jd5SJW-0O5;sZBD0@*{D@%7K38lYgKMA`!Pe{iigPnH3hrCyZCuemj z%3h#WLdf1z!-ESoxKqDKCEhc{kQhz5n=WMP^gH%)VM|BJ?c8ctc=?#9!-pJLd+#$L zW63FM;!BWPD5i*Pe|d_I(N(+-H?&Xz8i^&ePz5?RuA%39?*2-?O{7Od0~+~REv8}7 zjc1CtR`wQ2xN(jpWwH{Vm}jDyrlZ*$kP|o@DI{vk=7uDGReQ%AYKdLH$CLfK4x<8O zN=vy_JGW_S3RNan^3`M#TSt_PS?o#A1IEqo#wrNC1~$Qm`gF*HZ^Dy%vab@(eeaFO<_)EOnYyA<6!I z#86{hRNvE6TB|a{Zos+r$pMU;+;?eljU!zq7tg4 zj0QQ2Nxy|9kgU?df3-zau3|YNSte$5C|q?&pz^vHK7}yN(Ok4Uj2PaHgGRDnxIYFg zU&LUj)b(MtrQb=0rojZhemJ+rdIIKn&wwC04}pp<3K@Q+PVjlob)mzsGQiLh^|U60 zHrp3Bt@2pn>{4nfXz)nt7SA=>D5I%!=BN7bg+Ua#3X;MWx%ipj#X9@50H0<%&=yMa z*c3hqk$y10e#2?Gfd9CY7DIQ?MIiB@t|`Is%N55VD@ZwiSMB}uB=e>Njvi~wj~xr` zF(l3+x}X<~0t-b4K^geLQUH_^E?9;pQl||NQcoH~4<*0eXK3m7{LNp_p^s`ER5{K$ zz*29nq$$2Gcs})!Vty|@{}|4{EqhX$=8Jf;{X-)H1Hs=v0@FC({-ThO{uu~n_jnG3 zURowwB$nU-3)O!Yr%oC+2gl#(Q8LzS47==C@Pp9n-`2*i1Z;uRzw*FOaUW$QnA4?0 zUIiA-&i!K|Z+rE>m8qqY@_1V2+9l4T!fO_1Yl1}QSBgCk2|4BowiGx3ItEjOHJ$Zu z1)XQ=MMF@8^6Dh#^0y+lZE&R3s|c}DP$*(~MId1FNX6w_6pSnWT>X@fe!(=C{>_pz z68X8-9lA2Hk(n5HEKEbxZ0h4OdD_|R)kmbF`iehE-2z5{De_N#F6!9VB%~wJt(SA- z`riZCq946GJ`~8Ml5Q83-SJBlG2}`aX$u*11WdHy7KfK^8!gL4iyTK~kGw_xINXQ zAy)hU-ktnGuw#xD-dJt0BLWw$J`sZ*l+=>Tmr zc-aJtBTvnlFT4q+alEbTR_W!jT+^N*k!`xmbQUdeqWfuXI zW}N2>-ln#k2B=c50?o=B^t>+cON{B|RVIwa_03g5&HZHRi78D%&ELRS4`zN+r$wh~ zF8s4MZ&welY~S(aGNpOMbKB-Zyg*Qhpl>Ok9oWSyPidOEfZ=sBK?qAm5o^Tkz@%&q zHhSNtNfR^Lq@nR)Dd`nyu|djc^6?6E@{aMISue-t#pUWeTcc^8S-9gg2UcQG@-kqP zx>=T|J)RsG?}5yb&3GYv7V&8S$bs+oFo--kZV=-w0yXMeo(MP0<(`B(RZalS9{vSt z=nmv93^r=$F3BymH)W1kr90wVcfE%m>_Q%lqyd$Js=Bn=3XO2FQP_bk2_^L91E)Qfg>fEo#;$9D zH9P28eqfn2HCeW70rRHtN-?wy%(B}F9khNZGeri#twZK z?q5q9xNy&A(8faD%aGb+wW4ku*Rq6Bk2@F;Y$cB#dSEmXStFmW#X&5I>dyr8O1!>m zN30}D1GMG*0?cRhZ?6*w?xhX40oCDiMDrp_MQJ7NLXGgt0MubD#i}jiUmV$xBGo&A z`Qo+8*bT^%fNeq)G4c_#)f=jMoqDP6oiGhZoe9_vTTqR$;cA$FtEfRU`@w8>Nx{%)X`8|DwXHoQD;QwciX14kFAO#Z$s6pv}Q8e{0 zg5E!6yKYTzZ>@hglxg01rR0iPPsTLT$L+EYhKE{TP;Zn zzc8M%oJQ}FzdTOpfs`X^+wtLN#|sX$X??;I>6{#KTeD}2Ywb@fwG#sAcFuycw1>vw z&@P4|QQkS9bf%K+%ARG=bOW{(?a5-FTOv{`+|wgcJ8z)gVbq{I->D-e}oz?UZjw(Xz%~Y|*55-c8Y@2ebfP%bO z+3skqoBi6G({WGse|6CSyFS|8xf~nk1K>9TXw;*=pij4cKhUm5K`3#RZwZcGhRT$o`d`4n=U?i(G-mQGbB>Oc+ z_yf-AG*+8)pmbDB@T3-Y@0%T1tMzGN}9r7!~$1F?I>!cnKx; zc1iM~7Ve1Bz`4B`{fP?1LS!^Ul(vQw6n!~phKPAFz#}-M`G#3YLH@?mxU_*+lb-FWNbn{V9HEI__Gmv14jyEJNi`=qmiamG(=9O3 z*j>xS*$RJ2#be^#Ue1pF0Dc&gOpDVqaBF5lxKy|wE+}4Tn)DMS-#p5BY47^s5!7gC zzpO_WFJ7h=;uzJgP7aC!1-(e6N_(Yee7j%02z@~*f2PHR1P~t@m)O8gmRxGk^9Kvo zS((+za$&@MQkhVt0$IWcDq@TbcVT^O(*Qvlgx`4d#JE~Dizue z7)j{G|Ag|9=CM?z{?d9s*qAs_r<%PcQQ2&=ba#@-*D)Y$yEHcY6T_4jLMY+ER*K;C z;xCwB{m-ndX8OI$OE_m?tk5EU-e{el>85Z2Qi7705YvPGGH^N)x`H7H4^o;Q46LUm zakDoJQ1Pf?kM=`ixA_{TQvy-pY;T>w`E75*p)IcBCS{I80dcY140A#SQBn(V5AL1s z$}kLf!;>%1BH}N%9f6)X`LEmTJDm zojIIHscD>ke!JRScjXP2el(KE^EA@f$i=BBOsNXd4J{!BzR^-di2zSz#7P3!IFpgR z`z3Y5XK}{(WmT1PP7(CXJ)m;RRhSk{3SB#*Z0l1}h&dDSnxM; z;-JDGuCfCJi*TN;p>Kv(F0~dpx*JIS(X|OGD>SGHg>YqiX}xE*{$#62{+MXR{^@^k#`s8+N~y{2N7yK^cqD<>E+n&&dR- zz@!}(?JXZRTVrB-@kY^Pw|HVeDmgfnGPc8SnB@iOgY)zs^$Ei* zl(H2ZlPRqqyV ze;Hzxw+8=|i5zN14Y#5}TGb@3X%@ez|JP=|ZL~Z5FRgfHKq@;pl@prI1y%Qqx@$?p zz5KgRX1o9O!V{YA@AnIut|cw^^41$gyWQfg0jcib)PKH^&0w%zB?Wh?hI$g=eE%+Q z;#A@`pK@;DgS8F0wk!bJnitL|UkK6ySQP|G5s8$8srB1rpp%GN8N#?lq3km|U~5;0 zGdgsU%KG`j*7#o&CgD+;VO|{Fj*?`Ql=>{m4~1u-(~-^{>ffkH1YY+gI|s=bHYJ8S zi#)ekTU^12z26>bJ2{b;goS6M5l@_ERNk}mtZio=)$=1JvMBV!M88$}D={;uNE`jp zsSZ2MC<8D77?hAz0u29D8L2EiGt2Q8S#L_RwHO!{`S6-!kd7hP>4@pMBb%@$tsG+U4PE+TEg4^F!Jd14K7v zghvXr8O-xAt@A1z)6;Uu_q(hj@;&@>(?!I?mZjh==&2`&A z$%(^rwP7R~>Xa$Pf#p0(?&6_ze+3J);BsifQaF~GSp=%DOOITIAao0>M)mCWg>Dw2%g1_jsve5y%cq z$vNDyIH^zzO4V9r&{ma4Sr({S9|h6nGA@}DQW|!-5sO+D$XP24smfRznXS)^a};bC zIwM6B?l^ZSlj{0OBeIcpj%2wmfk!BJseEpoq9&DDr|Dawzpe=)9}g^MJR{ku>zQ(K z2ttJlWqD6|a>-@YhSi$yRbIR%#@v#J$iKD2*+4|I>RKXl=U!v>+x;9bg_NOVv(rO{ znuFq+IHcfC#Y>ukH%dX1y?5avdr?nEjQv9DlgX_Gz5%i8m9?=RN!~ z6Y<&+(@eY|^)d9s6jtJMrTaUj%+XaOB;d9y{F8Da~jvf*>~qt@QPip}B4)VzKvN z&Qy3{3jQw8=N-n6{`R4Hu8MOL`s*=GwYp3VamIadyz%qnG;d3FbAVucT}0{l}0-&4!KdY~JV>gV0I)@b;G2NVofMyC)%EEhDfberEwW zx>`HbWWo3PSlJom*pBa+jS+5j&up*pomNCEN?IQl-@-EaX;YVkMNKF~0Nn`49nILk)r-3ls z3Czzxs$zHxFfmfvy<8lq>6F}O+4$52VOy*uv+^i(Jics1ouDb#eev{E^}FY1iPLE! z*lNVU2l2kwRRK+Bo`=$}mE?C$gs(29=RjkF3{%IYA_dyp2Faqr1SP5-{w6l;zvn+@ z+B(m+fmXo^emG{9;I1bdiuPVD57oA|uFks6m!A^u=8^j3W4%~Sz85}J)YokZc8a|0 zI7D|?&_KSq^I>G)#fzh;cin`qqey72+Yix73p z^@O-%y$F4OLq<<;@QJYKfnpnwNl5+!2_{>L`IOBM6IDh|&JGkD%RkR+uY^PODgXeW zB>|$ifr=%rBEpgVBr`Zb?hHr)h-jmULUhRdOL0lbk3Gwg^IguQLSt343p+uL`C=QAqEC7R5>lLT>|9a%{E@6JZ3; z&Um%5K~)_M8PPrj)0Z9xVixc3A(MoKWLeCWCE(Fwpc*{%7^SmAX#IpMPo9}hIb@2g zoc|-(Ig!_z|B_gLWf=;mLffoy!htA?{ig`lUE{sjRjB11yarZ!u1xcr68Pa^YC2f* z;qh%AV6DXuSj&Ji%Stm3B^*?fU=W0EEn*z=5dG4 z&Tpn%*Nay^obC6x-?Ksf~O;=?evPk2^OlYdLF36>;;o58ZL z`ky$JGxBLnKNgA21!>4NRJ4h*x4j}T{YzYT-O}b5i)y(#&f_vio1K2F#K81E{q`e? zbXg)nibc8OQ!|(pDj`N6=XUjwMd$PbLkySPaAoB2vm9g8YKJ20wJrxbri%ZlF6Q+*-j66ua2 z!0!6=;#X0^G2KI$_loWs9pC|Oajp&H=dmZGzeqW9sk4@M4w@-k9)+;TwiLzqnkFk^ z7vb>O#tPI*eDP?sg-nNmoEv!PCj?HA=JH6hE$BE}8lZbLGR95I87WCVTmIC!K($Wq z8q<>9AH@AQu^lTo_5bl(cqr=+E}Dksg!~uXj&$anQzOmY!1PSz!5 z8+Z<8RB_^RA<(APo~og^AkOHR%^SY$@%W2P!h8&S;k|U!3=5(JqoKW)tFmokNNwCFDqIsVr-ln=idq(z#urnm+ieB8&(T2F*#dODW z>*u>6ef|kQ_$6N06BqDAs}9~v$~0M!ULCXsPm5{SG+(7!FhAR$1+z*oO^MN;D;Z*- zc*Nb z^*eQMsh2yf{$8=en49O9_43EjiynsOr&?%6Ze1Q2REnQ0c@aK4Qlma;2fjFK18C%q zr1KyxbxEGOpnn|zcbMS@9T!|qAEV>urv*)<`EpGOif`}*L7;5J?ZU2b_{wx$ykJ$J z+AfRca=bdpU?P5G`)~APKR#l(2&Sk&Y197Ila6>tSp0LD9Aif0&~Cng^H*yzs$1rS z66!pr!*nTf4y#k;JB4*tcd1kJdk^`1Ee|2v@Wb zq)idpU4!Y|Hjws^C<5JCyH)MC{MW%`F?`R`GV>0LyIe?&&#hs*T;1fM4RbMb=OKDB zGG~Esr&Kzdcs%1&$t&066|~WeHPR`@9*7%E88KU^3C>tYrgtaFj1oLEYMDv4k$pY$ zIGzGyIc|NAK!^2EPZ2~MtROAGn6Z#~t-66kAK-t#*Cz||ZBpX8ARem4k|emyT|w#j z7r4SyNrmXLzQJt?t*+<$)-d9h1aMwKQ?M9~@od%FP|(v>O!D~)>--bjFETuxCodV0 z3P=G2v+C@PJ2>61mZuYzDRio@^awOtx2_z`+qoK(?KJex{L zgl9se0FnW&A*{`Md*d$09gQ30lMYsF^DZmuqdd-&BrQ(im)N>1LAN|YZwx!q_6fHg zb*Q5G;1l+&Q+*tDFvp5F8Q{Lw0l1t(LH0j}>=CttB6k_Jfme4t+Ysdn_m58N;AipO z?h>e)2WRU*azydEr2Vg5E<$4I`D$H$x0IV~%$@ z+K}n`sBQ(j;OGXl9Kg4t(e`!U!Fa<{cOsu@yrFxe@%D-dLFkaz+}qjVY7vkfQqw|K zBRsown|7Xl$DbH8g7E^g*}#9qMMJgkVJR=102)JP=sx1ao+68H%qR~dt}}aU6L|)5r$9fKttq40u6A!zpgmGS2-N8Gd|+wbPQCXb7r?t`bo$tsBdS?nQR5xjSBua|7vw_BHl^u+96AzLpQBUk@ z5;jCN3!`Gd-;XC!@H*&QNC_jw9?f*2cF-=_!@Eo5NrCNXY z!9rwGMNzD-BspJFmspVc)@UR{dz&-Zm1#H)P9Mqb#5SCfIsW=2U)7#%IPC+lx++y~ zOf{Sa0a)P{sV~aaoAP-q2^~mnu4j_8N`9{qS(%pc% zqy7S?+ljoP{A2YQRXe9}qw);+^22x*Q@(Xsx{*8JvC~KV1QpxmQjfVdAnA$y`}`v( z3U8P39es75k0BygKIjEthX8DsPwtdzzXLK54lY8+i5!H- z6Y3>}BNm7P!bB@rA{Fa}qfoJi)G;D6@}s(1fIf$NWa9}k;fk>%;rN-}wMGhv<{-Y} zeSOHNL%$RO6#UV)D*QIV1yf;i#TTXF&rJ-7xhuqbi+94_8KLGwrCPQumH+Bsn?p8@) ztRz*M5MxOXMEDX~KI45P!cjv5y&UgBnK2L%m;em_iakEmg_DAKsXR`>y!*H^rKsH| zI7d0%ph*cEqX>9B2^*gw=}yEcekL64+wa{P*8b=srd$0V%exTl6Fo7a8=>e%c!pIz zVGfT3F^%vFDJwTPgZ}JWyl7;B z_hQ22!-5ZdJLJyvn4VwOUQ7Ir3yCDyWaAMo^bs&!Lo;sqP};_R3z#Y{tf&9n?x*<5 z?Ned!ocf(am4HzyikDpHmTG(5up~@EAT|B!MVx$e@6RVtd-#>U1^lMTyVjF}wjQc( zj90MCJ4EqFAlnRI|C@IR=}p0-+=n)04W4N7QmCpg+2ZFoHrx>9+nKhFUL4CKsD_nZ zoXhu*9iCyJkB)UyZRFwwv}1>lz)T(8So&l32lX3*jRhRvn*hel?x(X~1_D{6`sc_B7%-72P00PqbuAboi-pq+^8{!%BQ_7ty zbdDr#Hz4oiw=?9ZRahhhPX`BEPI3vYPpN7^*eGZkQ(Wry-%!krw~^}PO{id` z7TX@x)pIsUN()mlN8&U3#GtIl9&sUYc{A(S5NA23tna?_y8aNZ4}(0wfcrepFu0a0 zJ|MN=I+*AAr8WJbZc!PPmdFZYuvt!TLzf?Ix% z2r5XGZ!s(vOp!SdDV*3mMLuLiTT@4rq1w!1kpjRA^gl;xv>m>H;~U;M^L>_|>Hj)X z{~VrVRV^og2;kGytugUWR1h(7To4y#LU$bjKB0gz5^$shzoP=JrKuZfXJBTwiCKc* z9?tdNC5;`gIw(Bv5G7=p3Tl^lGT$hk{)@|OUHheB`?#~5TQ2W0*EUC~*XQeTD<4qN zjSpah0kxksD$zfgWQ)X0@zg9Ib1-YYE2=@o+N@18>J>f1H}od;M;AY#Ar69u>_b# zhdSfXKj4bJq)$ zBeQ}|`tnPzr-rMMl{bOHrWy@tsKHH6BVn%Boyj$d>JRfNwEM8!R@@YWqCX|z7P+RGz%S!AsXWqgJFe)bFGHx?J#U}`0q=SClj-7qI738rl##jS~p*Qdq*jgE7g55{3vhMo933>FFVYl zr(Tuf2>xmAR5^fylX%E(9R7FajH6X9ZDB6j1GckXY%sBa!!HoZwMv*Eg4{*(;Hb}W z&qg;Hb+Up*dzb~q&cYpQm8C0i5L2#7w`4LSt-@Vx(92zKPzrtJ<_8#yH+e>^uoFli zCGW}&x9;2xB(KVCddTc;a7g!w;%#wAt-aEq(#ZmSgb`)W$_=ciig)EMS6x@)SLHk4 zqMU%wf}_#XU?}!}_pA8tc=B<<`Um+MrYfK`;PEOagJeb1#lOQF7HYl2Dyhy5xN2xi z1>~*D3gtab`XH=_%^-7TJ`ZfZZ!f(5{Si7PEdzr(~9OfbK9ZmgQ_9 z0nhomNe;}e_1cn-=*wD0>jc!o0-C3)c=ot9Ya^j?Gw^{1puS#PYO@@15~HE9F~;Hs zP7}|E!oGlf1`MRr-No)$O$g$L!htt*7-uR^rP!mFNv+_n#@rz5$h=k8W#EODp~2^s zVEFJgK7!Pyz>Qfu#Y{`OrT<5n7+%iK_pCk19CVdxkGXx%FIIdN#Y{kW!eh5GefEtRmdI=jDM4p4-i zMh=+aQ4o9u(B`i=u*c^rD&5eRsH|b}XVIdG;a={9^=% zOVq@c)Zb}YvCHjhW64^YD|_=CDp-hLqm`;%9IeAz#?4_TH8?C;eMKUnLJDnvOhb+o z%5qEnc80H>3||s(?$fxtVO(bjLChLu?=@^}BfizWqgQdKr{qSD`t5*01OkGdG|x76 zkY_xDpBu4Y<(ijc#S}WgBjmpAbtDueGIO&8r^E(1a3>isJ%*2HB7@>SE zh)}rTgr~W7AQpwyR`IoJXmg1PSu5D^Q~hm2!ll+MAt7@^E|GUmCpMuH7}IO!M#9j@ z_oCdr(RXIk-zhsgP}jPlXjj;F%O0Bt)gK@=yJB1G0oO_g$3X4ayWkov=s8qgHM1YDcTi#lcTGAo>mL?hWXIhvlzG`PEcd4%&b;t@cmVo)`DFsxz_7Mm!$OUrNXW->L0 zy-;R!W->XjaN&x-Qj}(9=$<+fj15+5{t{}L5cCK+uyiNruGW^-=42M_@JHQ}iul{u zwIiEWzSL94bo%T=a&mWn6Xj^u%!@2)y0@l!xT1X)7bMotso>HWy-oFKHxwv7FFIs@ zv#t9*#+1btXDxD@e3VYp*G*}+?U=0dc`S>*=EqTRuwv+;cx66$-EUBjf}$YMK??ZL z&Jc^&KZ(_$ZV&x*_5`q@7a~u*|E;d|rH?!G?>Er30pkC(=Ku3c|JRzYA|nq_L-@pf zV;W>{^P}x(BWA#C0g}La9Nzd+27f5?8|6?_&g9-(a$x zKegLq;D5q9$k+t}oUeQz#^1Ivqu{5$QupxLK2UT8W0gos@K?i2l1YqtbjJk}#>*pc zue4F=rKwPZPu3Eey*Pc$J1aHis# z(>f?k^|aS1V^?Y{ami0sRZ8f_mSU|7QcLxkt9i(?t8*q^VM&Mh&(xpBqb)o!vI5?X zkrr-Sb*2kqU{X+z%#|Dm_x|EfF#@N(JF+q8HM@FRS)}-SKgJe~IgP2~%3xkt&REd5 z8(e{19U)L=^JGN0T+8Y0We2P%r2)$7U3Dr`dtE=pf}!OGvLc|c%c z?>{>%Ce1t26(M(19x?0w!l4Lk6RYg%Z+u9At9tE0?6yG#PAGhc_`9p4t3M_XbG6pM zCYrx_H)T?sh(8(ja82!F&;}oW`b4*O+D0+evS*tdMj+-*sOY=>^w697K@{|5ZqiT7Lx~E98t6(8cnr$ zX(e%IGJ?w?&|C3Iq#>7WVi{!uxOJow*x7_4Fj057Z|RV`-#@T|R!@@#GP-PM} z=qfK}jc`CjeAfyh^l_0BsV^Stng5)yATlmMCc2;W17XP3VJ9ice<8^&A#D>O*@}i6GhU8G8|#$j?H!F= zQc$>i$KjMnAm7UUE#*M82~kXHV8I6`pGiEd;Ji!1>DKu>I8_45Kzoc`+-oq%_08?9 zAFlWIXNwXYU+~%2zhzF3>H!H=-}!CHcO|sQ|2}j24`l3rfC1zII;Av0A^P>3%794i z3s8tHI(!Hf(X0r16kKmESTRge;=jas+^^7QfiW?@flL9Z;G<@I6AroZ4p0#6ri^c! zkGfu$F0Oa`$E$Wg(whqgd3-UVSt_K}M1fU|?O-q`=tFT}N~82MEZ@fGEZR%<5`!io zuYQvxi1ZJDlow1kseeGLsk$TL`aOH5{*Wlteekyl#*jZXTt2}u9YCqBC2i^eV)Pzy zAuV`y4<9m|cIBIjj@cVGQSKK3sB|@*0vbPCL=XyFtiX+6oKAoBvH$Fx0v4jarhy6( z?spxYI+K(b1MfPRlWo}1*wolrP(430l~x&?Q-yX9Md$eDZ7Y*-Dz4m6;9l)yO>5A@EPJxi)Pq3^~;YQPj-(w1XAbgNigvUlrg zqNWJWMed#^RUe%G*7+S5!7vv<1(xBk)Q3pStj%H%y9yhnpCm3VF~K`j-KUF;X^W0N z$S%|w;cfXU7Z&2dc3rK^ovLotW}y$92qwFi6v93D{HtPWuB(wgSWN%O|_ z#PNTC|B%jy(q@$;xd_t*+X~K~9>92pSqBvWZ1D*E9x=+De~co&{9E|OCYV1)0uBT; z3;(|`>H6oP=6`JY{I^eZvf7&#wi<>ncuKYjr(axL5dQ)*>1l(Mx>mJKelwKC-~x$T zSa|Eq72HM9;FPH;D*&syxq8|2blB>wTDP*uU+;>ZF8Kk=jTZQ~&as@dwdZxC80J zkIc9{ZcH$85(AHeJq5~YA^sNJ_^3ShlkP9o!|ZoN*hM^k=d2jDW$r4&R#30A z?zU?W0f*xWyVPk)Axcd$a{f6k*o&D>u-j}tptqsaqfophc|084rTDC;s4}2D9Fq)k zDya7*ZvA5$o2QfQpo2L~+)^v^rqtvbN%1o%k{Gd2(i?Q`_a&+AnhejG99Xi)&^cBc zW-y~!(=k-y0PaNyaVmHG^iD%Zh{^y&Jzy_NsGt1C?KyjYF zUgZW9C(S54%myk=V0H7{UOr`3^wxxiuRiBqP2o6YlJpicHs4}aG?W)%Fxiwxp&|Ig z#2jg}3tN!qeoOs@DljNGTitTI<1UAYm2aEcQBHt=iXh5^Y8DN-C+d{`%pFw-kC8ic zO5x5GWldB)z?hYbdvl7j2je-ZwG)FVo=!BuGjlUsZ9=3&soy*>BQZyTRs-~xcPBqN zG?Xh#d*Ke;I=#VjiA^{-Toa5LE7z308@0x8p0G#JKFOjcIcT(Pnmv_ld`!C;7Q-5t zT^1Ac4>MZTGz6?D$;5PYh)$T)l`%VZ4wn_D$W ztPtyq+|Sarlo9jmD<{n%ck{Pkz9Y`-NzX~ES$e~>F7Lp-0J0Cs(c0URnC+cb%B_W4 zuC8h$sHl}|2Z2#M<7XnEH(|p|CYVYbj zy;AVR>VuHjS=W~d_P0sd-2#-PGqEbmft)59)AbG;s2CQ{JLgZRM#JtxHrx5bXehJB z=C&}p6{Qz*D+4Ue?u;qP$|4NNNxfJ!J|gt~nmQx29POJT(1keBC)th`D%;CH3+EK! z4TDZSpyShO1Mq;2tWvXekXC8iigxwO$0e%n?aCG}1~W>_59>jJ9ohu1tp*zk^t)tO zsR*Ak5o5Wu7pUCA&C4!>jbHUuWShbd0odYjc5flrR{m8;>aKtQjfD4{d#aZ{CMX!a zorbPNEyCrCzZf}#I`1*q!2_{+{QFaEA^T!&2^zbb@tVPRaN(?*XpGGcUEmB2zDY^C zCIcVteokb#L+Zpkx{ebXhOjoNs`I{$q(rz^+pG3`{tnzj8u4sY9bfG2B5HD!-4W^? zwfm@hRPyKY9rH7{0+e_}Jh%}XO5I5Ph>|~es0eulV55I?I}haxzq@5L|yHI zIqSr?rFGfG$N6m*eAeZ45_JQA0tv-1fUE=nML)sB9|eRk=> z==Lzd=bzzagZxNrUiE{su#1T^a|h5-MaRpl2k|r11Q#)!pb3ZgLLssC_v6Z`q&CS> zcV<3_`I55kT=AdjJ2^GGIU^QXkV5{p)eWsCH#qw%D&xr&!~xC+A=#$f4 zI>AQnJIoyYGQ;|#Dy0Ax76l%BiYtA>Wym-PothR!jRZ{H@85&b_yDUbM6p-sHe$SEHk)TQP&B#6A&m$l@5MdyN?LhW zZAnSd>qV z?CIJ1B$aVbZ09s_M>NL;aZs`W3aWy568e;;A=v3p7?{ zedE;Bgr2t7RP${bi{+K&!qdUO)R3VTO*4OCRCyMD5BkaX^&gG5l%-mR7NH(lYY$RHY)>cfYdXm(UWC1vjqzM<|4KfGJ#!VT?Y+FJ(I4^lJi@-eQ z`N1ts$yzl)i1I=b8CBUp{jz~l1M`WEpqi2t!7UH8G6YB6zf9GrEKD#Q-|z9Re~mu% zT3x2C*M<+=yb~l2v3uOq;OJi6M+86DP?d30qUjOo7T{o)Zx9otokf|^J5Zf(0 zqnDJ^yBNWj3&wZg^~jA5<`+k#Z*TY5=Jn}|EADshKA-akxH2~x8A0p>ti~}8a1`RhhB9LU;-2$;=ryMOb5Ivmsstx^N}fVo zL!mS&hP_qMIgTZ#=*^=s8MUhZpVZpmqWS$Kp1;w>Zf1}CtTsi_sV<63TSe0xsS~#v z&DLhqTRfNSs}lrFOmRpgktq#}m`AA0NFXZxpa z%u6*X=u}tZDHeqTgq4s~l}xHbn3K^c6SlXJOw*j!o5N!72QBp$6w)J$h1DbCa<_n{UA z;`(eEd(xDIZMuj2CikH_N7FO$q{0mJH()!Pa71y6VW;tRsp1Hbws zK^asWdkyzfv(qtKu>*$3aO2t1N7%Invrz68@XjaJkAFdw0r`78C9gA;a>!rc(y3k6)$UG@ljWpgI|uG;p>#Y)ZT45d zPbUn_2Q?p*kCbi^w(b0>O@K$qat<%Si5W1bc!*Otrc(^{)u3|#n7Mp0K>*x5V!%~` zR)63ppFQex1MP}Ns8chedsiL3Ie0wBup*1M(CKC=Ak~};3%kjI5~?MWB0CYH-RB}u zC=_rSMcmfRJT#WP=${n+S7pkZK%jWrArF1)=00Mj zQB-87$(FcNa@P{*I*>W;JxL{E7nU@^i-JwVbX3&W8{Gh_TUFXj4fBzDSg+ylju%p` zHVq>Ja~PY-l8{yRzVK(Ym5EHhRr1QM)owzK0^Jkjs`c@kac|VQplgd}7oL}CKu98n4MzZ7-AZl;TF|93+D{9O==H@`Cl0)VQqS~h*(pyP6&f;&Br3c_~ znWVL_K{H-zjfE$1^u~Ox<;wl=YkhN&P0DVm5}&f=&SJTQT)aS?*XV>uX(F*tCR@>_ ztizEgKKJ~4exsrCn`m^S#@SEv|ef8l3zt<5gQO3{co{P7- zg1kyndivFE3`>>Aq9I4#zM89FrUoiKt#8#o*wwF8>S4f{jo8k+xx~>`kmKBM$lOTOn!<~!A>yas#z7FK9pcr1o1ydHUib;{BBO!Gmd{Lh4NsHS0l0n%I z6g*=MALiX3*Pbo1bY#1xJXQ6lbfQ5(qk!sQ3)J@SK+p`-fXZdNj@CycRXlxS)kTYI zcN#ZRagU9%SRNgLEuwH!UyWS2L`Kx7$az&5Yac#r%9wC^P&BLsLxp%K&O5ZUp!d;H!SM?7Yd57?wbqBwv818@K z`dPA%q^EN}lw=Jbjkh!sVZiG4UzPA-jTlLZm2jLz1n2cinYa8)Gry6rG9gn+movn^ z#>)=sCVBv+nwbnY#^6S8fU7VL;+@X%Mg;SQTzoKDm{D8d=nhwX!*ZElo)y{VXY)pW zo@u_pdSm@Ie4{No@r25uP0atcKiKX3ZmT}NJIDhq)#_P6i&b;F950wsBAS8 zC&OUo@5=0SozT1d@LPr&!B7v1A9v*r@*kxai;qa~10uXwq-cR6Nhay_>|J!x_UcDW zX2j_G;?$kI73{}rH!vD3)0*x?vr4Qr5XRMBWF92_;|+{i_efD-#BI+S&b;yBx}fC9 zXW4C$qopB^*Ctn;Z~ehRL!6&EEwC*{(iyq<08&w`rhejlG5e2Jrk`Ol1iTRlZ_b~+ zFbGAzzv2e(Vkg@d8Acc#>xO*V>1ogB1II@t8IR_crg)&4xXY#S{jk2B2mw}mFbgwM7(}gxY;W4gHbi$8FA_BW%`qmI zs!Ytkz1naaMsoq+eQFAE zJ;16h&`8`pgX`R|`s;Vr?^^uM7m*J}5Y0(ErJLHoW246lSKtnOEzBLZJ(>8V*I!U} ze3}nU%N|>zZcILtQtj|ebngGGX_D>VVOW{^Tn}n}!B{3Kk0m&EHnPRQ)%>Sg54vUX zRMv-+nvFVLxL7UUSMOv^W;v6M6auU>*nKh&5w{cp*h;$a6?UzzrF~4pK7|K(mq1RJ zvS2S&NKI7XR%$4#U5z6y*?T>-Ov99as)`-~H93UPlyxsrhZ+xb{d;W5W{B+s&@x{q z14g&M!T9@*{Knl>@W8hhF?f)S?yHG{S5nBY|%cWqEa*osmr5iMCv|si>ZK)RyVV#}0uND_YL!kB- zGP3I2h-STR>ZWss-R=Z~*r$JnBLhX5;GhbJLWa2gKjguBH#8LGU*Nzz?G8Avzsm9? z(@syn+KP+2vsU5pI-YrfU{yh_F~a`P2AeTZ2G2ufMeq+{{x<6u7ro&g3jE6Ow`Y(O z&e2zdIUc+b#3-ew6-E%z>{SNEEa-13*%2|Aq--hB*X)f9oC!6+yebLg&x=UvHE!)8 zVJ?7)C{9Lq+~_JemYy3>JnXQUI%y(UQZbpK!Hf<(iqz5FYx3mLn5%T>&DHvyu#U7K zG5%u&S-=fJwqj1CvtY$+Jq3)3*jU=qo^I)JG@Rbb~b*pNU+~nk!~~IduelJ9ARrdPvN@va+gXcNk4unqQPaWkW`*q>KE#ZVm zDgb&pCkH8JH$Tn}b+kVq(8?QW2$-8c!N6?h{o1Rv5LaByHEHv>MAez7`~5H~De3_F zJ73y>z#-VYVh3pMYf1J7qvisb;X_?d(z8P)!S`-9d>*9xjmd=uJ*7NLOAtjPgqiD* zNd!J;{}E8cgGRMUuC1t{$=lz%fHsP)+<~PToqD7^6t6MriIXG7XElp1MV-qgj?1{? zb2i^Uwe!%m3A)-zp;^<8!>1T0#ZvQ1&;7S0=Q(z$iDM^CYFkNG6u-_zM z){8cQ929-T=TrK}Lc4#wgZ3WmxJB^`fl^wk8aQ{n^G>|;G_HKmFVG-iE}4S^uhob5{KoRPjHR**bV7G%vqjC#)z4^<{9SK9M3}|)ivU@M0BFI1A52uah#qgQ6@!6gvu9sA;S%P#l(~qyd_>))G@RPz z&=gqO=Ad+mt~Aj5Z5G%NPD)qXtM2H0U6vG&@*2i`*wPW41ckLcg-;6!yo(^YVm}8v@%Uzr>9@5SKH^) zzkcD`(f`#0`$T3_+ie%Z)5G(`#tQ@V41&Z9IifqbotGAaBqC-XnSwFQODwK9BenfS z>x7J6xpR{1{Lih$pBG0A;Te*uf?$I{&j5B0FO8=>5N7+Ju|IYb~#FV2MU z1^!>}vfG?MM*AO<(+Lg;i1WV>L;WZI_P+|KGSw{Yu+>n%p8l#)RjS3)Xu(Nd#uvyE zN=X13MC6NMcM1rg!V`uhN`$aGl31Te=f*TDKOi1Ng!Bk#P{<4D$O{;l=wtcQ0-b^} z@#cYi$6%OdwkK|4^gedMad$S_&l^7=5_*j?d7if%r#`2Y%K1Lthv$Oa}x>FPhz^(oVGb@396k2 zGMF4hS+I52>!w$%7hT#UBV;>GP?T?3O^gRkh955B8eTP9jc*bV08aS`1-3M*Q;?8I z##uws8X4v}j3ZSn$TZ55qs|cfYhTv30h^HJ1O%+y7OPFCfXG#k`NSOb*S}_q=FHNZ zw16>W_u(2U(?$jbJ{!(gC7FP)d-$-BYOj`+<`I}&S**nHW(cpine1Eb3alqLpA~0n zPp@}LS!i3Ue9{`a`Pe^+Bn3G2s@aUmo3)gVR1pkN#O^yOi3aD)sZ&+dtu?LVWvMRx zW$R8RW;qv|E%A`+EaVSUmC}J^uwwidni3NJeGvxBdHbr5CtkR*p=XIe_6|ZokXkPN zP80^X&|@OCB5AlRWeJ+~OX1v-W&w{yIs}l^d=vhElA?Uv)1&1X9Ydqu7&EtjbeC_zwia%6Iw%M( zjkXQhWxYLWNDe5wh9^4<_upUq!l600hD55mwfZ{0r!!(_x@I=thh@^-Z?EIXar$Xibs z*9y0bO26_OR1zO`vqsYcYMkB~#4p2S`m(pLZOvKEGq&l%=G5{7t;|-h6H!rPi9tph zy!D_wSR$ifH*%JAjPhV++I~W;yKE-#?nLPvKjLB-oSZtqo<~{x*fosJd!!n4`K?|) zqKc6887;D4NAq>q)U+6tC@kLo>W6?Y>JEXSos<GeA^ z!zt>Hs5W)y9EEJtiz!YOEyp(J446xd!V^*A3CUxHYNY;tWl~optP?DtGn(Ql*v>iz zoYT%4ZQY))6{S#Z2D~PKn)KBAF<~HRCP3_#V$V2!GeQozI45utqrm*m?h?wMVW*fq zgM?3&2KG#gMgSI^E#xyDGyAS96KoR!O~V7eR$IE zzN24BBZ+3pI~eE5L4%l*0bHA^fy!U?Sb@3x{~ zL6TFlwF+g;1I^7F&eguDKBxErz&SRUf4^5pMtdbC0yr}#ND8-S4wEFHEu$-R53#;8 zr*weDN4*)9-{`Lh{fpAhcsUe^oN==mWRBlYY3K_Y^ofD>4!O1}XMv|Jh~FORxiU>Z z;^Rly?nm%M3s1b(`oaBI zzzIE3blwUZ(1ZZcurlFaK6`5?WHJ!oq4Vyn{u@3g=u!T@;oOXKuOTBw5SK6Qa3bc`5zO**-BL!msdqU~ow2xoIyP!4gE0w#;N+py)R>F+0?TsdV^6%kE#%Boh2v6X-^NmpRDMKIqIQ5OJ~~yH7>GCWrqI@D^MPok zVheUbxj%P$|8t0Yis`Y}uqS36hxw9y9zVjCxmjP_L?-rDFji2hNI(;8G*wpd~{>jmpCV7Fpml z%z9YaA!nt%5>a(a#FN1Av;{$P6Un06H8VmH=Cv8xdwGR-I!AejcRB=*n!PLlPKQx#7$Se(-$I(5%pWI8)}jSd~_lUCIUrk%{#>K+ZV zLg;fM4h`DD=OAEovCuPFYLdIc_V4>T9wIz9O zqY15>%mgxy^*3>X;Q>y)CuYRs1d{XoTXRz)fm^m~Qg#m{#4YVv^eD@9 zQL*5Lg{c|&NV5*_Fgx-lEkpzmW<_Fe^+aJ_gmu<^)tYP6@T+jwL{feUw@ zeFU2lw#PbYO+91?AcGzF%lG;^ckoCfw4G=cfHox@1YEn3(XVkihmhXb`(7kWNvH%n z&ma7-no~O>U)Jli)O3Cc%s~1sbUP#9ZEK_&8bssm{&exa(&oyHX^=u=Uz;+*AN*dy z)vbegD@{(B{v7%XEhHqrc7)lnv3v|uHgbrmk6(rWVk-v|pw8(Dffw*b(&0yz_woG? zquE&zZ2+i2oH;>U19;64t{#}u+{A<;N`}eGT9>DsXZr84m!2yj+9+Ym{#u+>HvyKM znP6=S11ob%f=~ZNSAWVQg*7ol5h|}HAM8uKup9Fxwp{p8!o`fjrxF`1Py2)`El-Jw zL%a9a*3qgActVAls!99g57HJC-#=^T zATI^zd5$U#ZGeHEK%*44Re*rqEqrQJMlvIb1aV&f~SR}2YD z*bOOLmOOh!;rzI&v(o_&#FN-8j~#Uu<`Uzq-POQf4n+3jV%f;56LYbvk2JXT9d68r z45k(BBps)Qgu!lJ9HwpiX?{ay)Fs-mF%X@EkOf+P$|-%pK{fl3aIu0`)aKF_Tvr6u z3~V7vo8C!E-hk;Nq@pKgDbE!Na22eg63L%;0V>3XyqA<0-d?an*ppm|^v^E62c z&0ZrYi3+DQMdBPl!9uy|t*#_@L+P(um86kVpwU4jv7y>E98INENKH!*S1EMTkrJg3Q2go0429UiG4~Qad`V^gH^E%ooEYFe6mDdv23$t z@&`M6s1zQTo-f9-2l}p@IrN(rNxcKGY4LkluXzc*JvyGeJ!ffzvHD_UiKXg1lcsjQxZdb>#V`ANOU5X33^qc zbG`TPDf>sZM5PKu9na?Z@%YWZM}ePJs`N=Z#q8@DyW>K+PRuwP#FZj(RB?{RQ9`Db zxDIO7sV{fXWE8UMNHM5isnx2wUC2w>&}N*T1xtL6I{r>1*D0p=8Gm0Ny_Qd}6PHyP zd!1;VOKzvd;f$qJ$dOvr>3%!BZXm6zT1OsYWOViCOoP9_dN+{VM3`lyHwo|+F`DoQ zF{99p%CK@kbyeHlMZ`3IaU>n9kByN^x%XaT2&N8d`cy}9i*`H= zOx&Czqy}1s8Zs>3ig@Blr>)(1Nx8Hz(;sg+ew?@kvn^Xz?2j&BUSZ8s(0UvJN7_v638ebH}ut2kRe$zxRS zlV7wp7{m6CTa*H0?9X@UYJj8j@ONdeN{2`{g4$othj?CEAZx;1$I{MGB*DmbxeW{e zC-=!~Q|)$iSNqi<**!n;MVInUnk+OwSu<&Y?Q}bj(z#B+fB%H2Ott?jPq|yXF_a&! zV4Bk4PTWg)LCNR5Iqf?!0rPmJJ_*4f8ag3z%tM#>G|Br0*)B=xj#DbxX;-tcR3epM zbb;Cu2>O=J^8jYCu0$?LERt0{c0ZQuUB0~G&=vY*ug((uIj8~&<{A9+_ATpPa90iP z=qcnRoMU}WIL+niX*~u-nSz*e=EA|S`hZ53V4&!mHwCBtfEFCK9ZA+;0#@+WS*!rH zd(k;hp#3&oLbq6%f>6ZgU4pK{K8*4k4zDbeQ=sFWq+0SfpJxhcEaN2fW2$%F^tw$_ z0`RU-x=B!VLLjO8UwE`Y^2CRAkTtWQB~}(3VJ3IJz~f}Kgxe1IV!yL$3{=)?@K|c` z45{P9&GdnPG8?00;Cu1S)Bfo-^skwt;WkF*R}3DrM1Ts=2FS zt4@EiY~4qG*)yL=9X657KRT!}S6retMOD|L=!wvDMF(leyuGeZHLkqAkb2yJulO;w zB#qae-_U%n(M;TNf4vvDuL>QR=s@gKa8Ih059p%Jd%qoK4MN`6EuSQVdmWLyYXT?y zv1lvc*gk4VLKjoDtEmEZFAf!F%$ajGaA}$nAUBY)@_j1Z36BkSKL0r-@x1+Sh>rq^V7|v z*liUDxF7|0O-;VMtxE5E1Ft2x!D5Zf&q`f=;VgTd|DqS8jK=PrZ>gcP1B0z|0yDXr zB?=|G;igUN8FZ(P2ce}DMQ*M2m#mE*s|_o&$~&!9zhDqiB1WwrRbMlv)@N+m(62xc zBLzvn!z?iX`>P;!UmJT?3&5HYgtmeKr3M2=15rW)Sx#@eotACM3nH?T^X0e5>^t&0 zlTwhSqL2A7&oQMgQmrUZNeVvb^n#>2_j;k>{XoMnUfF@=jeo;9F?Unko-dkb_@V}J znq+lrmfnq@Z+QrGEnm&eNc0$VJ@sOq)1)qTHZO){rEpST;9BV&a{gOgXNkG6oLcRe zxC_%+Tzf)H%M}&g(ISy$Zy~_H$O6u!Coc^FA=XMWmr7 z@D4RbHRP3Eg=TWG5&9(daEe~AjKE~LbqHlG(6UEpDfV}w^Hg<9Q^UeMtW7fTyDX8m zUwCb^MJbBsQC~^F>lXt{>-AllQfl3h+V5DL$cVOrG~3pLHO+Fn{A|-pJSW%bP{^sJ+yD zm$*N0zA(Fn*+^c0&*}@T4lF5-*SYVZRPCZvl`b)aS++-D;|qsXzX<1pBDD=i5*27A z&+;uW`oTNhXZ0qmTvKs`&3vJ^67_d7;_U6}dSfi96^32Jbc_h4ZWLd~i6)GC4_k0x zFZv`$-KwM)Ch&!Ggj>jeMJ-@MWcnWj13e0!yhDF8!mscP5013p!L8I#+K zt@cl+7-*xkwysD2}6Tq*$ioiY}akbxvGNT2#GC zzEoMgv@vR*lCLagZ|WY`I!C<=6IW}Te#DC3UpaHk6rDS^s!*}yq1&}%XtR`_U9>Yo z#)W^z%1f|OPfmV#s*P1ANFv#wL)5v=(=HAEsrsp8gvSks*OBCDB8OcmWhN|R-W4_Z zWuu6;3unS`rINHGV1kLKl(cVQ^1G|(#a`6nC#emsqY(5adM;d#+?u_-K`9ZbKtz(P zQdw1@y)KPbaVnp;Fv5ijeWr0tle5BUUJT&uR9%-flnDD!;!tZ7$G3k`8!_+B@Pw3c zxO`5x@+SGpQQf2GAXiA*G}yhTiy0E3@?zOEg0&$K<$>bhaO950*RyRmb;s-z-ED%x z*3H7#3;!AzvbJgh(-FbW!gQm$Cj^E!JdeLeQ-wXg+S@gqdSWeoPZQn7x3?(S(NFiZ z&7_Mec3R$ogLV9`5&JVE;WmK=FZPk}Dphx&6Ce9$VT(G5_1u$#gL8+s!+Yj=;zz%K zX1zvAwpr*5+#kKS%b4*dRim%y;XAja{eb>j+`w;GY>=eYH-TR{Uv+hQszczTflzp8 z=l{U|+6+8lCDIMc>OmW#2i6P=Bk25|DFleT%TZBYFHr%>4%a8nL${ouCb!pahpj<`)adyB^rWgEr?PNn-+cRahmb%`ztsogGZlYRzT(l z>qMo^pN40YuO>iI)UN_T)LZacL(PI;w)QEroKu0Nc}lxJ>9m)O_5q_{4=fMAJMLA@ zJ`6f;etD4(*XIVDJdkpYN<6JQcHOsk`+UDZ_5_&a`|r9OSlJ|x0=X5&T8`LH z)f}4YMN!3BY0=-U0zrp`mH{ts8MZr}$U_bH{-lr2Hws?uHup#|KwH9Dn8|ZFkPh<7 zfcJSy^QxtSfPBHB?r`o zSqfiu_c`BTIK1>fDx0HzXpUX3P7uVCNruaQB%Oay6BWubW)l-V6~LWJDMg?h5rpF$Jv`VJA*(w!m)1@EDu$WmT{4R1ll z7Dr=JDw1UNz29QqyhSfFu%b$!TjEE5Png(X6vkElZ-?m1v}gV4=Me4x|2jmB|CzFo zAY(hvj}W{qGtbUo1Dy*CxKofMmzCUaTF#S12n0~d%bQ?f@g< zqk{VY@j)@1YZm5c8?IVjw=+#oTvYgee%&JT|LYNfRFfn(9352AcC^Q33sulx`W^~b4(yPMU`&4?5#Jr^c!IW5puaE?@A;UY9=ZWb`7LgXM9?%o^7(&nwZ^v^iq{8^NQsCQ4>hE z4AdEo+qOJM;m_9oB$+!quTE1}9UL(P>R8NLSTk2H(&Rq8T1xUq84| z#^xVlIQIa?=3JyO$wIr|0hz7@*|%CVlwPX_zCE;_;Ejo z{eQlV6r2t0oelo;Zu(#O=R#ErJ0%sAFPr-xb@-uYEToaz|PDfT$!`(OR`AN!1NKWhNf)C-6S_wnX3 zbI?t`(0s;5{l;~M=Tz%)=d@h6FEBrZ?JEPw@{1h>=ZAWPvovR__W7`f)r}ERm5~c_ z!nt?LFE+;2i;!SiQU%tqS9(lNs-~N=^r(FwjFqwS^b}(C^n=7v;=zKDQC3n5I!2#0 z3x))fxp8AIqleouI79G+OdlwhWOO!9`v~-AD7T81xY8L32Vv5zwY*}X z^*XH2kfjwqTpq}N&C1j_#r);a(^Jx4dc$z@;pa(+Bq<`n7V4A0jsf`tsjCz@4F!g6 z{1WK~XH@m0v^<@v=aR9;URso8B%F;6y&Xi#?8bf$kS9A07F>!NQv6XVMOiiy=Bbgg zqBQvtMQuQ&nGM7S)tZV$g$kh-e$f8bT8+9i1=h`i9JStPdTNBIou&ON5^>=WCZgB% zb88-kE-(z(p{GPc^h|9c0!gq&B36j4D1e141cSiz_WnymRqi}x|S^eYXm`Wjs zpQ5HG50;(nDaQDGh!V%IoZ2js7gux$#*Wu2#cR{hp^!9I%yDb^y2OG9S5wRnJAxA> z?AR7Tmh6#gabQ&jn`Q{xusC%&K``JIcK2IT0HBP-D=$SVFzen4WpReE(e6YUjqEl$ zs8c|COX1lV`E;T)GA$V#EyU~`MebZ2)x$5Ql4Y{>nSMb`RS7Z-&eEDSaPvWDL`n%v zWx+*SJcwug^84dGeBY6~t$C9T4yAL>xo3vF97*^F^p$3Wz|we~dxE$-^LsW% zUamn=(*W*ho!kdpDd(3#mX%KhOR4wV7Q-v` zL^eEVDn&I_R7bKt8%QqR9MBDwE4M|UvBCnv9E5HTvP-e-2kep8O5+26pK+XSBj^{J z(PvMA9vPnzk*RA?Ex{~Y3%(+$!JxuoNjVD1DLcbxeA+=YZSe;q5B&E)BtG%eFPNwo z9JM`Y>cM37sOp(8+ZxF2Jos$`x~^ifet33&e0vr;h_BDCZM!em+o0NB-}zxxE#|C zV0d`qfusSL!FPhdRFVg@M!5Hl-lKSI&o3zW|zs$6xpT<-32iwz}2)g^<9#GseR9YTCb5Hwc?uq{Y zoO?31&WffPN>QMxC67`F%~I%x0)ApnoZ=RW_t4}a%&E0uZkpHNJX`*G_tudDlZ>+|Hz zaQCqfD8dk(0P{{XP?EkBg4QhV0IL=H0+D%$x@&lgRFdxOCgy-ni`Iar@CMC^u0UE2 zuYkP(q<{y)=L(S&BM^uu$Vv!6ecq5oWFnOP&$v&nv4~liIW!5`UQVcx08Wp923(k1 zHudxP9X|s69)SRS#4wRRp2|&%KN$os*N?6X3vzeLjWJ_!A~35iKGlZ@dnyNLIo4MSCo)DmYbr73AIwli=J zuw~nfcoda9n2j+!6Cr6)1m8utbTWaErK9_M&c{EgmZ;@&QAp z;zip=C;Xw9q(qp7Hl{|H6(=dC;uX~qZfndz6=-WOJLqcouKV{}U@#`{3zDvkJtjX; z>&w=W;w804aq5bH1&eWlXV(v~gnu zezOjZ#@gmUi->jKK3jQrC@*upa<31K_2P$}!b=f^X+^doGI9u5S{Nc#ZV;rTG`nLq zjH^>5H&Rr}7e`$Z$@8={bl^`!$2IQ4Vozl%vrf$z861%!xub5fnZlaLP!v^4NT~)` zkETS!k}fMMdG7krc!&--!g<;_le%p*j;NDH{=83vX0x~$%rV87mgx&y1%h(p14Q{pxz-WzL@UWPWT%&650N@v=!{9XeCkKl4=~b5& zyuvBeK{b-{jR}#z$|YW~ZJ;rkm?`>JcLZZijQE z1SESb>rv?{Wa@+J0Ydoy=bJ=3Bi`0yPc^D_eufrX9ayWRX6I-hJgZEw{I4rzl( z)ccFW#PUQ*OjULkp@xOXMHL8u1GWN$3-=?p*VYaj6cV%D(f;1osk(!x`XB)(Wib+N+OLmYZRu;}K%6^vi z&_wW-wzyQ)2lz?j?02_s++&g-q zTiZK4mw(6aQ`QwVy@5rA@a|>*48+WkQ&LKa*)Mh~Y(x0NMZQsX!Wo2}yE@|~<{{b$ zVk{F6#EK=7=Z!&JIfg9?I$h*lWCKjPFwi2+H0W8z8{M_lMi{q8>+HD4y~y-ONOb9h zhw)Un2@a`kVvFTw2ob$H`d0}^&fs73BuDTcTW#3x(xcvVyb|8kGsI+=5ugGA2B4{! zIDUQ60!yIV0*O*(u)pt19PPcy=}#;90$1q^1v#jz{v-~DKg>a zsXPER&If#0Khaw}K#-g=NX{D6oj~vii=ATdTsp0}Pl#l+o8msl$ME@Zn;RAUiGuyT zS(0qx#6!e)TG1Y*5c`~DaP6}7XegNj!q6maPR7c3cSpOt>*AD$;(O~F zgIx{WD%jx?y>vEkeu$X_2QMG)xfwN)$-{~q*_M$?-b;EM$Y%7LZyb|m_uG!yu?UPi zy8q^X6%zl)uP)PWtgQ+P2&fVNzZ1b|_g^ul|CAxALAojbD2QztnQTq(APoNaF#~`L z5lCbGAc&r;6R38Ixu{2NyOqrfX_7HfbhaEmFG7*TKp+RBDzk zZ7w}JHeaO!*ENk{^79bl|lSy1{gbCdViS8kgB zISF?|fnY}~zmR#~%a0_gD2NBqyEzFfI+7$YGmb!Hc`r_u7JMi^tyV&!RLclAq8ZYy zZ4NS#{NXQ!vyqFF_@tFWaQp(&naptF0V_#^h0P;Z=~+dT&9)&!cDf02BO*<0w#_@( zLMF(p00fh= zR1)r@wFyJz6go`5yfwo&=5WjZn6fGqSDa$cVP1|ojmgI!x35g*5aLR62=Q!j(=ER62;m(JFu^mjp;H z^pc$IAUWHGakdEKYUllr?T7%Wh*6W7O+)t2UM2cNyM{rhg>KTUhM3hcQC?GjkW(wt zsweXfCG0URThnz$pMdSL7hEut4?J(iFCd*E{MMDoUw+OB4(0-><-vYm#QW1P5rN6Z zAE>?wx2_*jL*2LdnBRlrNV;*ie4Jo*z2yw59?zqK2qh&w<8>v(LVZLXbvL`Z8sdF) z5&s~@er{YReyxCX=$y%;TG9xLJk1=_k6F>-EC#`5gh5wv0wyJqD1K-An<`n7eRGUl zFbU}d5pn6{0T_)1MLQ8(bf(snK@lEwvs^hO*t!&&sUoAAQ2n)fICqT+#N(M!-3wwQ z)nwwMF~h7_69&DJcy={3=oil{YP9hGgR*ywt}M*geN(Y*+qPM;ZQHiBVw)A)cEvU; zwry5&(&zTQXLs*0?(XwpeqVE}cRuf*zelve;vjd3n06noE&6I?49ue)$YhQ*b=Feg zb}KIeP1qmLyX4zZ0#;wq)ADZQfxV;%`}LtJpER&;?JYT( z*~WS~<(P(%r!cm}y*!Kgl!?vw;u1Tbtm?_CBfsR&X(;0mmik^}N7Np!BW3#FnY7qbu_u1yK1K?`wF-+Odd_aW zv>igFn554P_OHR@niOoZ1k7V4-5yKc6|XbSCEBUk2cL?CZu96Mv%@x*2IUI%U%9iU zG4hZSGRu?qXEwPg%-ulcgBK?DUgb(eo0a4-pYx`2Zd8a1W$iR$Q=V%>hbH*Re?`(N z9S3^mab=VBE1HgyOd47?Anz(#Sj)7HpR`&}+}5z150aPVQbgtPj`527x=hE&NchCW z-|XlNqi0t(ItHD7Hq(e$t_>HWUMLqV063KYb}i~OJax<$8na4M6&A`+;};6(1@Wq9 zPyeEi+@JrdM8(_Tq*D0pw~G|5sg*Vl zn{KDIoSNO9^mu!jj!`33;XF#FUTFkz z*q=QpT2Qs$XGzHSvoZKy;_61|`t>SVF?tV*6-^2HD<>45$`L+H*yVB&I4Rm?rX;+J z&>{V@;=3@v0-E@IP(N{jA!Po3x6y+2&!%pOgDf=wwxmm%g$_{kV3TWZutCaAD~I(% zRygm1FN}kdRfqDNVT8Vwas{iX<(a`cRdP_;+g9&9Y_zd?)Eh3KXtERukQ|2!&VwrC zgF?%msV;H`*bDIWRzIw~>bVERDw}`1vZrKxOc^fo_mAfL34GYdq3RNliU+DmSPZCC z5nHl_cHv3S2BK+*d|B7SW6Yvf72dcj8FW%2o+lJpuF6)g>4iL!IFic`M^00Ws*8tGVw)o=*eHt7p5Zv#VT_ zp4i7t-sjyj!q8KPQWkpf_s@pD)#d~r`OeP+I9d*{$Ib6&zPu%tr-rme+XZA{a}wJ_ zP<9gWs7Gq4naCscKY@j&*z&D}rQ`D3H;*k-o{TLiji7nEw%lpPiST4RNz1se^`r911 zuW<^-aIw4>tp~_Z(UXeuR{X#bofI# z_OWzAF&xag>URyD zV}A6NPIJd#Z*-0h^INrN+N~o$-L6f(LD?(gTli;0j!ylZ*0#7Io=uUi3BJM3O_7Z= z{5`%aB0FaU$4>9?=Z-LsU*6$78zNoXe1i}hB0jTxgZ$&pF&l*g2UVRQEPj#1id>l@Jtv^`nQVnRjKkh2$;V)60 zRCVOsNtFKdrXr5%SpqJupV!PHl$IEvBFegLlX&G%s-_ZP z<3QjfwwnEtnH#QPmTz)C)-!~mdaYx{hfEO`}W2NDAFE2W*Nxg-E zWOXW&^bjAHs7kz+o1~qsV*w|o;^0p?XkoNuyZIJg%aqH8tX&?r)q6#!pL&WOSXW+D zQj$xnBzk{YoEAL!8FZ{hK-o;rST7IM4}3Q^$rJaKn@OmpUtUnaV}Qrris8k*;uzdU z47ZCPSX(_5Ibq=r&eDSNOV`B6DUw!~Toazf5b|HuLKdBhj3I}r^P5CJ-4#PP=GYoz zQB&1TPYDEqBY!FLai}I0QqAwvL21$|I$~YFRL#SNjTGYMD^ka5!5Sah64X$EKhweTNnB3Ql+{sK7fx+Gval^!fo7V zFtjJLO&`sd{Wr*Mey*gvz@B_l$VPWoqNhkkPqBpSVUG=P3&`Ejo_7#9vWqOiA$ib! zESy;?nAydyQC|G<@Dk49Fg6o`Wd8XA^RI2fjefjwzwa%3kng1OKj6XrGok!{d4R=g zw#qoF-(^u`i3VM&kQM3zRazo2WUc0M7*K_vN=ieCu{~zJ|gwa5WR&Dvaz;@t{ z(uGs9&9BrUwQL*1*#Ojep^dq`-5RBtN<$${)8s2X$Y(Z_TfqV1)MPuZ=rE6>7OrM5 z+`&kIp%2O+x5zV`rPMQeumE@aIHH6mSf2wwjcmQf<|^`&agS*{X=3x;hQ?uw%6kXn zPHOQ0;>6K}V^$WJA*X32<;6=Qb*cVGKF1+7z$LAnN{v|(ps^WcCLMS0V=}1_KGIolT&B^tFFHtWPuJw{U}S$EaiI(h;xiJ zrk2u}&Rq4ftBpog7e0qET`}9mW+x)HG=2G&e#^chgw_g7*6>%-1c=>TVufTi=?2#XGiYfpcGaWG#?ArH@!C%!u67}JAFmXuuzuY;yRbK! zj{G$n>NU-z%Kn1=zXt*ncpS1&>a~1nYjfU0N}NciP0xv?#A0i6V02ZAC!~?E|DT$pN*Q~wXvK!S#K5T9tRiv!Cu>PytvHkLo9H)q!)D zV-(sKA}^TxtPm>xE0@Zy@BGBGc-~O@q%YX{A|Y8OUOS~sLS~I8L&tOhzOKTsX^eB> zqt~bX_IcGPC+%)xW9R`6AcRsf)ByZa$-=TKFAvp-ZgY)Edr0LxCuPe19_%Fo*EcX2uMKG;P;yFSE5s3*l^(#nQb4_b zFl-309^K*hRplLO5N8()p;tU$(s^>K*DS48Q%-*pULAy8eLFD;x^p4M7@)==xop?q zBf}u-Sg3TdT6~w{rbdWt+4OkOu=F{@@;|DFMq05h6|B>r0doBNCH!&|%HbEmR$GMS z3-Fxz{jW+^M>WQ3^Uc-A`;HCR|EJhM#n8ycRKnEod-Cd^=5hZdT&AdK%cBUPewMTr zPY5HGqk+{@cCQ{1zbJ@AlL{w^88MQ+v2Vt15}CGM*@5Bz72vn{W(Dmb+=ye%$Y3xQ z@w%*K@U^~9b8Y87&20br{o{`Y2NPh378VsQS%y@RT~WvtSCf}nfyDqv!)Wwp4J?L) zh81@WoR8U>qodg(&0U z8<$n3h$?P{-RGn4<|GiYwJ333SL^kzaq0I8P9=_X#jJt9O*#&D3w~k}c~fX1N!yB~ zF&T-$oYehIz_}Ny@-U^_FDBckmEPL`hO$36845_TAL^|L9nolH4D-y)Qp7S(pRd!s za=pk|?r|vV(KO|57!Z*hPK|An=OW%Jb1d|b60&WIUgUMhMVe1$n9IITIKIEr#ME-Y zb3ak%5F5xS=BrLu35IS~YNBA2^olKlBRv60KSZf>I>bTNmykAyoQ53&vThSTZWcl{ zJY=IX$oO+d%ygUyq83};ko)DQl;gum-c>A~5_OVWLP2qd;OXvFx z|BtBB|9*b|yZPb&V`OA$z2f(0?G4IH0r58Kh?WMQHXJ4@@7u{}vnj@=G1I2n|NnC` zY86Hp3QlBX@yzhNCx89$`U2{$*A&CAgkQ$3;`w7hnM+lj=nVJ^@+HIzgAc{GlQT%k z=TI7+PP(z6M!w8C}%u9D>y&VRJPQ>ViHaang?sYSW4CYYrZ38S+zcZc;NK6DofL++C*InyWg&x z@czw+#KUVeeCOy~?Y#B^28$MHT$Kn#+zqei@yW{p+(k-1F8WyN7|0JY0HtCRi!6x` z)Mx?r+0R6=2@3@`_^B!{u%)V8Q&}2HUyy$loBqAYZn*ETDfk;s#QJ|NHvgQ`Q?*vc z6-DLit_>W6l)xVrBt;6@{LvWyBBAjU1YojHP8!G?P{uYH+li8q?&PQr zuRoSg+6%4N!dI9rmp%>CwS)9xM zK6~NC(@`Gb88XNk9!IO>%iW$j5CclQqZ4m>aTyFrLCuG zu=6u}Bl^63x2o6TlW|`J6h=nG>{|+ey=ZEVH@4R_+&@fDH2{+*IP$dHDd!$6D9gHH zESmM_qT9slVhZ+t;@|={njdHc6_)LxZ~Tp0nJ8jWe?wvp5g?~HIM}mt_d|>Okt|VL zdNT@>!DCxPEZg-aHFw7SIXf=3vs_o;rA$A^ z1|u_jPf4adiKRc32s@@mkdo%ITex7rnOchkSMiGoKkFUzeZ84$uOtaOgUd zCShc9;_vrwTqjy`2r)CVvr+5ra#DMo!^(3cxnvUF=A{{`c=9K}XVVsSbsbCz;PLk_ zBL~?O`lADhc-a^Ogj%f4lf_T4=07t6qdaDMHM3c6;HPmgL&wzY&dJIU`u z2Ao@@&FR73;A_tJ-e5+|c%t!w9ot0hTrdsJ7e>s?8+FdxYUZUTuH8F53tUYa3|0*n z%=eFNw(Eu8az6!XRXkmr6)b1upweEOo&&Gx8zjb%Z%GmoRh3wx^39g@r>aPf?amOs zqt*$XZ#gL9(r12-XI|)($g+>u+@PS0hm#slCe-8W1 zPjW;HAX5qnL-GNll)OWhN}NVpDD-<6{j7?k{41gNQ5h`C@F z)}Own#L`+vQa$T6V{It|+zSRm01_5A4MtL-v<@lF(ln>o#nFlU1<9)OBgv#k6fdl9 zTG6LwQ~L4NabH3(`!@YA+;)S*jf<&v&PPBvy8$gVZolS_G^P2RpdN8cBtx!Kd|ZsG z?AvLY0g{6+D95tX*k7GZGDmD%Zycagvf)NN&x~dy z`{!3(gnfJv3ivMa{S!WUiT;N6x0kC?O_n?2n{z%ZpB-;LkKZc|J8b!mX?mL>ZeP#5OLK{hk*G=q8#*17G(8C2cR%y zTN}Erap^PZ;-2I4PoTU6YRb@%_^Rnp4rV?rB9}BUeQ3S=<#8Dg3O^QtoR{&C<+GzZ znY%(o3lsqPLhh!V&FHlE?VFO{89~rzI*>58yWGd16C^TZPMn&y8$|b?+`)s8zAw3l zg8Cr)3P;3pfY(^{AJQ$Tm^QZUf0fiCIl7<;Ek*OJ-FMNQIC z=>uMbIjI9pJYrYCAPg|5galzAD6+&23ZlE4Zk9sYAC0lejSTM@J{ISrt7CuP8zdk! zKr~Z!YQk^^Y0QzyUpDb}$Ae;|y}tEeHZMA@i>p(19K(LKZ$mHTM%d7bEd|{v_O?T|Y>xKIo~8K{`EFDf^(NIQ28XGgtEF)&z`=OxB}be6 zcZR&yB0il^96-8Wm|N}C3SwL{>iyfpo>{%sM*@v7EA33m zY$OsC7ddCvN4Sib)!RkCTzBzWZT#DyE<1DG@gyOGa74X}41#F~Up#3DsserT({3iR zWKaQ@K3z!9QLAQ}AzhgJ{mlbyNDfWL=$Az-<)0`=s5G>yoyd?%=(9GlL}-#IA&a^D zR$BU9Q?S|{?%;#hn$-h95RQjxpKRAKvQXPbQY2k`Xj`x;|WvZRMW!qk}tbgCYb=SjeDE-rpzqf*r#=c)^ zgRDuz-zc%SK1~1a<)k)FACksDa!#)>;`xfN| zKaj&AZIilxRdF>CFHW>~h9BHrlf2PuBH`w-%klSOcqFey%)-R&Dg+R_Gm;3`;Z-3} z8HK#zv_B(uhb6EZEq$2B|KX81TDWB|(%My?#F&p@Pjq*n-3EL>DY+{k7RDuLWm<~l z-=3`h5kNr$$^7H$KW|~|9=9PRvFInc{ik;H6PwH@8096kr)PVYy9YtyID8taz#Ubd zkUHG;q_i%YidV7;VfNVvTONsA1blT`Y#I~?#K?ux+l%VZ;0^-#?=68j@_DXgH1ZKu zGCqx#Qycj16(Xk7r;@s46J0`Qa#Q6bwf+1T2y!fS`nrEkI zA8`MwH42YS2fp7dHZ%PHppN`6TJz7)O%uu|`7q;4fF;R?C5Ztd5DJz^hgb%gFb|P2 zPy!OT4>Vr+PxYbnT|#uu*yzHM`4&3bi9OEX(_iyT~d=9OJ% z>$=^u!n0oI`X+wO#n)?(eNDW>hu^{9t^M|`W52NLuKPP0pv;41#E%yv%=O#oK!(tE z4>642c*Bhz)4gc}j5lbyy!rr)8y;>S)wI%n52QlF=-pyQxqVX*bKws^*|6=U-4w=( z8&@zsoWXX+p1^IEn<+-K9c}RGv~O7O7)e|epTiYiwenkUuuCJ}&e#pbn zA307h-a{V{Ie(3@zCW|b*OEYg=t8uws-{m-#m{EgFM$8bt^n*usqpXO00Fvu_-}qc z3q|oMg*(XDu49hjs zN79SfsBbuCvGv}VM~UoC+|o4?D7OcF*+nG9W%WQXpW9j=nu>d|SM?x14c1K`z)`jf4+VIvUl?EP7qMNk1 z)r|tRWP_G8I&&0lqfkiO%p}6|fuX844 zU=H>%b(3@s&y4{rGc`?|qsqj;U+wSn0tf|SN^bI~0`jW-*NN;P!fjF=LZX5yzLz)k zl}0%!-ZjA}rGY!|sSoYAf*vX6ey_6&&1S7a-&VGbYHms+e6<7t(Db!#6@qEX1~(> zFpD>u!T{*B`YkebY;J5=jefx5t4crx5l58e05^PTGw=(U>Tc(eHpp>PG7Ewil03k9^#)HYsOtMsI z&?3~b<%v`Pl`Lk}5-enl}95k-zt0w2CU58z@8>eds z4!tP2``zgr#&_V+OvPiGM${?0S}3&<6&&;ywc}lt@4+BDQZGSqp6?1K99HvloX$adbeb(Xj6dss|<6Ikw>#8m@k#xdV}7eGRg* z8`n4?%9T5n%H3Mgd-#XJH7ZVAVKb#t+3(GqO||(mbp%B|bMG#41QsE~%$COux%%Oy z@LON~A%$frJsf7$u^4HqMZ1f6lc2#nuaS6VX?5*H>I>WZ%|1{%S@Y6L z)=Oq~RF2?#`s3MZyW(rgGpq?1FLqnpsP|@J@AIh^ZA*$Wt4Q5MJ9KyL-tV8Oi|<(+ z>kJc_q;9?ySdai%@#m+K&ZPa<=kyppD%zDd zp?u^1d|XfjFx~aUnc;hmxe2}5LwE90A1I!ONk0hqW&qpwfZaL=nGKy}ky2_?oLN`# zyUlnvW`q1}R531wYv`qqsGjU*YQa0iWBZB8A32V*O__yLwudP4Ne-|@XIsC+HacJ4 z;y?FkPesfbi-bpgahJ0Mroe0Ij%s~eIOehMZ5_G#yRAiruss-@w}t{EjK6!4iRp%F z9nCrfUtGJQwh`?HI{AQCkd$VE%y+gq0KNBI*u~SIcfcQn@V!nUr(;lcD+9m8e@J1= z35h9s!4E@LbPs7_s_rU+-uJ62(;ASCn91}}Pl`(aNb<~$=eITBBY$=-=6s}|QfU2M zZFg%K0`^N}YOiB~@;?98GI^2DdxL?3q3g<5V-O0@0&SH>;4+-Wpd_ zRGJVQQ`A&?3`^xQ3S7=G5`GB+*!L}m8(>LSj30q6Lg7jRDJCsfK&r(ZDdEi6s$Stu z)`1ZT>MLKcxQ!bf!s+S0=+Fl7mMOBt#$f0r&56w)hDE|yxZ9Y%izBMSVHTUG#9@{z zRxKDfy`O2JfyF8&?57^7nV|5Cr%=lr$Klu+QkL8qY^vnyXHa4KijrJ=i)hePO2W9r z3Fum(SkZjFsI+L45$b)`M8RP~L-^`5aYZ58+zo~SJF8QrQ?$>-vm!=90|+~ zumq1O`-H_{L8cH>yfABk77AKE-l!j1Gc+k)5L?5;=b%uMcTMI1b&`i~_zL z(&}>};Bb?1wugYqL?W$4qB(^q#7$4c>I#h%>uXdgT`^Y3~EqCq~StOUEvv(gV#I zVf3j-vt74_fZxoXF>RhPCrR_qBg6IO_k?5j%LOKGxk|=s2_uhT%4Q}H54}%K=pWHS zmKtxcs{X7H8f$R%`1mvj2y==D%KOFji>Tx)!||?K<&0jM;j-H6-cgTt5jVI-@MsPN zFZunBGvL4+WvLAOtR2CO+Lum`TzDu>J0;PdF!iA0SncXTMwlh8I;;9|M!|11Iby#f zq_z2d;d&J0l#(^OU09Uih(sOTI$PlN1zGISYKhkmkJYiQqTSoTEI8viR}VWHv*sZ) zm<`_BQ-4)}KyVIgz%C!D@@K6;^z_|kMc>)ag&b2|S84#RnTLNLk8X=mVZS_Uzr;IF zWPcGK|IRMAf6ZP6kt1VCXTdijR{-(FB)GkLz^Zwas}#9x?^qhv>Yd0LjtN3qJhRE! zpUG+;X48nm&Hh^~H<6eAZ6?pMDWUJD-K(VB$A^06Ya z1&>}ova9=L6$;}A1yb2mE0^}^U_7Fa%+U`j@p2W$OI4#5m3+Mtqhgr>tq21Yl(X+; zbv|U%v&;yg@*%~HP>ABdhz=wIqG<|~jKU@nm3~F+W91iC<7c3l2Tl~L@To<))YPz3 zqpVrUwE2V5sl?2VWOB|cQX{rE<@WHes?VzvmwNdf$!VXE57rsBCAE1}s}P`5A9xCn zk|X#@8TYO@f8OSPH75x8OL(19z_#w2!Nx>#raGmdc_hj^%%s z2=~69|B*=gzf;+NDH1~WGopqZzhY>2BFgU+w6S`C3!O+6c?DqpY9T9XvIMI=>IdsvKtpfm5qi$t|+U3&R4Us1LSp}q!SEKB(Yz-KB zNa(al^+iO?#5l`J!x{UXId&~1;m?R>o!S_uSUkhGA5w)EqIPj$=K#bnk%5gyua}Bz zgdRA?3$Go#Hvz+gg_nQJ+V}a0Rms1*V-??3LXQ8aD*FAZV)n+a&i_&xOi9wVM;7`v zu@niUt3$1dY_VuYPl$3W_g%D5GHRY09$b9#)c`P?eP@r-l>`$I47YtR6^ba2@0c?( zP_sp%8=I5aEY8#R)27Ggzv6xYX=uokgjP~b8c9m7%(umwf^f`h2uW6NusTc#rVwGd znrc`vCfk-;gKb#Da9q6MA!#tYXY-$DiA<;FdaV7UyL-(%`Ms;K$%ijdjDWsREeP(s;QqFY!rhDZqg*?eBB*3y zKw>Ctn>a66K#Pvt1X5H7OeSw96GM3)!vrlZ*cB4(pGPU z$f*X774KA3zLQR_Kj*11UA88H)kaS^;8md@ z<*Y1oz?ItA)5xeZ!NrtR^}I3gL=mD8PQap)Gm2s#7fn7)Ewe-qmPWZK(zHX5s>5zk zYe_g$w#*z*M0;d0nec?jScrE3=zA>gJCoQn!kDMda1c2|t{nR``4{OO1Myd` zL~MT9-NAJI{k*26a>7X8?efbl> zz;q6j=LHxQgiip|=OK%VMDEmscL~}?S8Jvs4b$?Nn4^=~F0e4!dX+Y7X0bmth4D3Y z6xc2lh1o8=^Urr$IU%l5}eX*_b;Gx;-YjAH^;NffPib`{Dd}6fT9$3_sAxr1( zU-Vu*u+!TbX?SkDz%Pkqe*96wKe`y!^}@*Ceu@^g88uk0=2Uj&;* z{J;5u;Tgdic;G0Tq+n0MT$988sGO~Q7eNp%SReWja2eT_pK^xG~W*` zDg!u5V$T4Uuh~>IXL%}?GqliMET|EcLWRx_{u_+VCx}bat?Se;Jrd!Zp;9Puu;5_@ zUNW-3wt|3v`N@s0wdx^^#7v(U`~pLljZ+#B!HVNz`U_-AP_!KODB%;b==rn@dZZPB z4~q#g$~s#tMtn{Sms2?#*_`78s4{T7a8*=}VLESK4bB|P9@+DHtdBNzr)6awwAt$Q z_~q6ZidIRTfEc>QT=&bVm@${14K7zwzvy3Wx5{ANH_TuH#$z+LFdTm6J3?EJG#6?&*63e=)$O|mbX{oSKP3hX z*8U@F+xrO6pQDQ+GJhk=1@;ZW{@S?Xt@HIah_Ch;%lr+UdFE91AKKn{=?wDUfdZ4? z`vskAbPLAro0;anyAAz0&|vQ2nVNR&5bI!>VpDGBfalFRpmL+nE8j@2eB0b1R~=35 z5y%U5Q`keV6_Zcf1yNY&n3SYg*u^q3(p%G=oemnMz$rsntGg`YZ1)YE zu8_3YGKqjPGR2UVv=nca6F9anE`%17{dlXVDlh&+m3*XzI`0fzBSx*Zw)Wh271sIx|lVn!B5RlumbJSk^+ zUNXptHTeT(UegWLe0Nd}Rhp&ap$v&&mr1t*i|>rTlfrtxWNbx(J45xfL~IoT3&V0) z&6kybjbOoIbYbFBRM?jU%aXWUfW)>ZN0EBEpet z1_O2te*fVJvL8PZLgLCI~iiX(#iPi1Dl-CrQriApTrfi?bx zqsV~))}p1VIA9J{yVgh7UC#R63kMns$I6EG{?#CN`|4@)^$IJrBWkvO$jg*WRv>dX!ceUTZ@f_|&>=0Zja3P1 zjVBMwol1^>=9RkWN+yMlBjh-4n?h%+a|0gg{;-iL71c@jyn~qgsrB(V)(4 zx$EqIx;$9P9Z zs+exnpv|4IlFLD9hi9O;aBzO&Hs3bB4T$4rK8CcyCTHXbq~;vTLDFAJ1f3+o6KjL;5x4EJ3PwjY;Xv8soBtCF#T)G6f5kN68o4NH^A&W3{7P zaYa+R0Zmp(QbfYjc_qhPi;8et&(FIq7RW!^nU{ie4=b624KjG_bK3BlAwHVXz?uMJ zE*MoO_S8}6rg1I}^2%AdN~GlbI^AW1S{)!+`ky-V{nZWVVTVQ=bmtDjZ&e+(MUl8- zY=%`)G|@?NVDcr@8b1ZDUS$&&gF6w23G=O>t^%Zzqx^dGV|+0S#-U+(eDUNTn{(w@ z7y`lM`YwZB!Mevjak(#<4&*H#gbz?w1!L@f*4qe2*ocMN2sPUb5x3*=ucj{Dcu{P6 zLFlbT2TRp-9ONPY5onBBVrgr0G{ab#+#%j0ba#Yq4=X{R2cB^1SGV8yL}f4OLmSU5 zrpbi-V@sc9X>DY3oO+Dh00X&=WudRy!W^M`>6zmBT=>0dKi>5|n>%#y7I3O;+z( zur5NZmM?a_9MKR)3+E)!IQ|fs)0!!$3~W|JE+4)aT2+)AKqw;D%8WB)c7BEoDhJYy z`0q~lIgzuq6W<8~%{LE3@IOr${(lVQa#XaH7Zeabl0 zDOsAw^Ed~zv13_fB$y->{Qz+vz`yXC31j)+cH*2il7w@Bt%hY9z1ch8FCQO9W`ga3 zRKA-i@u_ox_3YfHCMNk}2}w+`P((U$MoMLpqx%3t4zi6z2km}Tk-=(AIo=UQtwoxO zYEA167wV<74K@8G*0*wLeD9JJ*-szG%zRtV5ht1rHkZ5HZ<0cesRa2)JB2!?aOfGf z`3W^PI>QqC#Kuz-Y`u}{$|Twpdx*~q6DhLEiMN${Yun`&Ds^V_G=U;%(mL#TfvIDs zfmQ6ln9Z;{_N{VXS<7@aI@o|jL0i79wN-|7YGF&ql)dxBBQ>L+FAKY5B|nwD z!zS4zBZeES$d|BDysJE|W!6Ya5pxvy;D#$%L@nvhm=RV zR-jqwubX(~TKRzX;L9CEd*%4h2 zxuISkFg~?M2tJ_v>lcH_^X)Ao?3W{@=zwE8*@oEP$6%s##2nm@_iW4im3HqUi^&d- z1YWMoR3Dt}lVL|_%Sf06&UTwIRe&2X!|e)9OpFbf-Id9PyeO-l>`MFo;D|E{EY&aR zR_X@MyX?_J#-IMucumbY55t4lhyozDph$=?!cGj5jig}V6XkrMN~iLWJrq;{`~^ti zLtg=Y+|L|U4(K5Gkv`#L4nHsu>bH>H!aewP#ZPWEXm!L*FeDR;l+H+kGOkai2Mb)A zE`_1HMJU@4UPEUu3jezQ`2h{9CZ2v-nB-dm#w!T$?IV3ZD^4sRVlBR5d@N`e+14L1nf)s0I96JD@o~)Ueg7bw`+0RCx zWt*PaB>cj-;h+D-Yw;g@RghMz^6Y3pKom?sK-B-?hw@LFz&|?SOU(ilEJ^mM3_pko z7~|_0M8F}f0|KBy`vf&e5lQV}S&~c~m{H8h3GGy)q?@Vt=7S=km)fGxfrGTtI;_vV z*H%hfYWdgSY;^V3)tlccp8T(#r&7W0-iy=UHxD?J8bY9>@ac)B;+2BnSm$YSV+GkRVPBF>`igCXOeUfBS%sf=OkE){vNHC3o zbt!SkA5qaKhAJetw*{4spRgjxhsl*q#jnY5%pmgy(-hmcpgR9tZC9#HG|EN27Y#-! zc1z5XN9TfIh(8kMVA!(?)S_)xHZg#r9hctppZOo*S94_*IQj~pvu<3 z`GYDdFKNq*8NLjGjAW^u^Q7Voii4$(V^bp`*yq5yifa!`K|O5^v-3N0VNo2awz6+; z+JG2WB7d57q;!$*H*q@~vUP=q8lJsn%t(LzVpoJGNcEhcv8b6szC*mFgnVO$93zI} z@}!n|(ac~qq>ZdaHB&4|NNUYUm*-tmH)`@M7jKqPdr_w6lBLLhKjGK z)ZaG=4{K}QK&+&=-!V;f?J((c=+WXCVh57NA%19)A$2O+(lV5&hSZQPj4^yIC(s@u zDhK)ceW@n7Wa#2r{q-iK^d4YN*|5@Rq?w9+B{mT+YNz7P4hT{M0ag>zjukQ@o$GdR zpA_ECG*ips!a*ZI^sv-_(|N597V9ictI3cn;l&G;V6yF(dGiIO^QdsOAX|I6%E>S& zfMqjkxHfBja7n1Up{IWVjIvOV<1);y{zTpYi@T0_a?f1O*BUdG#q(cD25jTL=`dT zj@wo^C730!OvZT~23AJZw&ga253hG1Rah{cQozNFKTkjD1DQ|by|QUW@F2kl#t!~i zD)+@Y>0i@F0V3dpE6VE>Hd{0*xUwTb8xU{QOrjNU%PYCuiGkk%mrA$ zXg1SR*2^YsC#P*E$80B402IbKUCT{f%MV@4(Ot`vUCUKnYNmSDZhF>odNlHBr=A@$ z>K$$8d$th<9+E#zK|BGO#AfraxLailY>OqzL5bYOWpKC6900S-Wt{r@cBsUi-xI7d zF|trawU?rSJMFR&9@@05rWL~qR!Jr>Bk`Ff3upy*+7B&q)h@ZiL^%T+WeX`M!&BjF zstqXC6Us7WCRW<4RnCn%q+0V`d2Cx%_wCV`3iFSN0X-W9`)1+iZ4}cBNZ(gImYqPA zbWdZAnJj1dWQ@h4EPKd1KMnEdtP70&lB2Bc!YlAr$!#dN{vd|6PsH^0zH~<9eXV)U z)0|rlgNTs3#HABe&kSYF4h>t6)N$o21h;-LzE?W_+$k6pec^;_Pim{xhe%Fs(ojv> z9{5)NeN30~ahAztmTOO_{nCp#_g6Y$Ta>%CPu6s6)CFFb_&$$okMz;T6jjdi9e<90 z|MQ7YEv+ZYc7-#K)dMbH?Y*zh?_q?K2kh>e`{0lGVTAJ!NP&ubzd&zTFxOe49D?It zRz8Bq!A^E~K`s)Y@Y1)S1amKC)AD!9+yZo|Z&(6__l+Of(=$;YGp}Gd`Uhz)ei{0P zcUq;mvBWz24-Fx6ud064tsztLH1YRPoWEH0Y8UjwQEzRY`KZ zY7?ep(2u0)wTSfY;^ULg5N-sBF&kU1Y&5`32ROa%#Q81rOZ7c9P<9*pRcdk>n)uqEI2{3z1yp#v!fY6H`a4Z6g zm=$A$1Oqdbku7(Bv`D^$QHI`NpVRN$~yMsL#Wh+j9 zjw9GPpSt;t@pd(`5XfcZ!aLa|RZyB#JY^v5Skl9kCU(33#n?Lr=Mr`6+ACbK%@y0W zZQHhOtk||~+qSb}+j(N=OMR!_sbx~EWYK1PT27BKOAI0!rF9VF zSgZqNA~aae?e8Ui!4@#W{_doCK3q?(R4m_&`# z^yIk-X*di_R|z%U$Mc6>xl z-sRU%{ z4TYbeF`pLWJGh|b6Mk~s5NO~jF>WoOCdHmOGcJX4oQL7Wr`bv>v2h0Kq3wvHZHOz; z5}zqNT(u8_dN#9%Qu(gRdX?=+qwQaj-6@o+er2l5h-!~XXaQPh=K`6U1hUtFLJ{w= z16tbG^0)go=p0ws=ajzwB*CNLvM~or(Fvnbrs@(n#(|cz+$p`{Zy+An+@~>1|n8 z4(BlxV{~lLH-u#nTOMmy&gf#;!@>|8FPSDZ>JkHImQQ|-uZ)KU?q6i2if)D)8?>4< zmH5T|*q2X2%tb+63oR~l@~`V$=4swsWld-m?Vq!XYqU}Y9M?)p3F-|6~muxbWG!e$AgW_x2ZC5X;&GI_t;dm)VkRy)E4Z_CKJDMd2-U!4rj z$glF-7$?M6I|4-)n;(SIb_=9oN$X&SopE*S(og884g_{OODYPVEK!3VdL#wC|s>o1Kw?{`^r-X)u zO*XWG^(s?js!ZfGcPv&q4{<{0=+5&ODv>RBHsQiuut=3{-D3o3hj2x*VYy#B_6CT+ zz~B@_Y>q5dnOyYC4AlHCAfd*EvWgO3V#id~3?Z+BL)?WK@^9R8CTP>faqd6}UI*gb z0>S2m=;RS(TL4;@;49QRb6FR;nX@%{R9%d~T=7Y@?c-Ku38w>7zrvi_3SY#O5IZI9 zz)a#zw=L9?chdjF<=>21R1Zz|3(g2>p3TQ6lI3J*fw8g?D{KE#Iun*GLcVxX&z32^`w4^@A119g^*C*xupZGYSZQ6#2)4A)g{^DD zv`u7!eCQ2>GI+?9tkv&1XHW1u+{+>~-vBmMnwcwx>k;?+z!^!Iewn9z;^2{606MLY ztuL(`S^#QGRl^tsb6q#%@DW2qZms~hf|Avl&QSAlL~_gS)PLDz8BVjS8)D9`S*d(S zn7ugiwLy9vB$l`X#LSs2@Ii+;>uDb24N^w&#EC9j_^K)CI;eIVe%1#;_YGp^OdP5bl>s&IbCVHd&)P|T#;VYsLje6_}mX&5nFM%{s=ck2H<^V^RDcO zx^>iJ^19T;t+YL$JDAsM=z4D$_|ceaAU(4B0G=(7o*6@2F65pZP@ZcgZyiZJqtteSA66O8ax+;u`~!oVW} zeDbzNBx84OSA|$97NpM9&!=6XPR_Fe);4gZ%fv7SK`g{H*OP*hND@h|!15^Oe?uty z{lfebKj5#XctD)a=bNW^Ff)e0CwlP?q&ikYI5h&T?)~%Y3)T1&yX@W#=kz4+3O(;E z^#SWM=qtOYV5jgC@)Nn)ZdG>25z=Q=S9IV1Ntt%{uk}H)b{WJgCGZWUwu~SmylNJ7 zC_=;%p$?P93)aJWZ5d=~P$mQ{{%A2-@WU@Io;MlO2T^mPAs2zc&p6bi+B#?!p|K=_ zoeG#&)pCBVJWC{Vn+nps9yjfV8-aU%zE%Wv0q6hh`KK|@buLgH4 zl?UQ1c=3rn$n23Q?Fsp;+Ji4P$MBUq297H6rWn&1q{x66Vo)r3175M>M?l}@AS{45 ztcb|*eL0FyH+V_a6y;tLLC5sr0G!2&i}2M<{eWWX_D}9=x%L=M(&StxiO@|7Ot%)} zgKdAeV`+gKv@LpmYvN#=5wS0}cL!ky_#};*u-kxdp`>-vaIr> z_T%cFA?y3i$TaB;8k;N`@ypRp5ru~FGGfy9E6;1PyLzDf?hj6 z=$1QHt@F1>8NQB)D8uQE3zhA~z}3}o-9RE`?dqazYjNs&dN0cD6{dFp_PhxuH2%B^ z3GHBXx6-sCF|q7Fk!hS|L)|M8Zoo&eNtkTiT85DFZ`c*rxsIyDD^QMbtFht9vB~DV z38*+@*y%k^%`qzr)Y?Muno|1OQgVpqzie~Ec{j`6q+3z-TX7qs*k=TAbBNo*boK}o zQeoS`uzr)#4~T4wCwJd)cc%YdwDEqmQXZh;O)}K%nzn6=vg={f?b6uyK)d7Wr8#ua zE7I_h!{y=5~m<`$;ss4J>{%Kkzi^{+;f(heykEAKy9addNRjen(wtIH zmg+^a;-KP6{{nxw)n~$_iFdT0)B`8nTgSHTcY-M`hj#uuy;@A0qCYA_LY^G z*~^`Mr~0%7d{kNX;tci;EXL`#?tE_%o5DtrTH%949Cm#EXc!ESD7heN**XZ?&rQb~ z;ASUI(&crFg1DFKFW2Yw(6j4%=c3jv2(muu?ozCwSh<4`2Yx}x3wcG{drndivae}Tk!#%fLSmPagwuJ8J!4=f;@64Qp9;nHhd;{ch0HZDUf^#nRQc(%%W(Sb>+-qVwotJ z^$g{J5muRwG}f&JpPgqPy|44yop!slXrMdfo6gDh9gb(NlN_g$;cuRMYJY^Ui_uE^ zE>Mv+g;5z_-`IBmT9=Ba-Tj^^pKX6N?67-3uZ6ns}Ru_N!WVGA8S3egeU5S(TPtd!ueeVO_?SVkn(*Xf@)d3=3%6jpP0#8R!pfRySwJpdm8?U$Q$>}#BCr% z)C)rd1LA8N^Q^d&!YG-uw_*@ttY{1AR1VyzGd1kG0BrFV;FiB(T9#9FO43|?$#oTn zS?HL7%otXafov(EyGKF@knB3;TC*UJQngXqzlalyV5ypk+vp1a;Gz-UZK{^UbYugl z!`w0>wZ<$Z<&mw;UXouyyM`s1QXh&S^*Y#6C3JS~JJdVnd|b1F<7n^9)QU!O3d>OMn-TRI{3@b6NE6X4YuNp+cHq#TXK3t*M|(2MbNs{j0j#rRxt?_9c(0SeEV+ z2kmt;XgKajNpS&(Q-UfBN&WnmSP2s}4IpjNcAg+&R-;KjHyek(PzDg79*kjCQdhu2 z)$|-^uZZ6qJW=CLNNA=T*SL}m%TgZ8UQ6Yp+FQp^<7jK39Luz6M`5ofeX-vY^TJPP z-MpG$M|qDtVcE}M&%%nm8cfAf<(-}`KH3P*`}YKfJ67&KBMx=EXu~jJm5`IyXt(hN z2R(rU8k}|y41`N$ht|UN01KpcL^tU5S`4(kP} zr|N(TyeA?xjY$*9G`D#jhU+P>_`nLhC&murg|x>+pN`W*k5oIgSqt{3V8vjMP|I?w z<1IJ(4EynmZwWvI!Z#wvOr6Qw@pmTI5<-?D9r-1)bX*ABH{_>V4$RkLSM8-aW(VVi zrhwDeZ1?#E#O`Ux9)ar1d{^#;Dacxo<r@~+ulzOBL7mh_DGdy)IO5~2j6~^v&~Slh7*^|lB;Dn z>}g{hH$@_pEU{uA&)G`IsU&R~O_C6K!Sjk3>USCC(Bw9D>bucueg6xhRp${o8(0uB z^65~Pk9-uRlUs|c9kwB=RL@8E)KTNKIB~5oEv&2#fr*yLzpdQ$S#;{_CNLY9U(D-dfrUbXs)j$aK`XOCdBZAm zjxd=YM10x;ZRKc8^o|3#X#in|>qSXN;PQNg2qV`8^bNH>@$x_Efe+P6EC0}k3S@J0 zD&++-u9>A-&UsEgtpcI-stu-4SqJE+6!lffg-q!ejko(;xpq`v9s7a9hgtdzWx?v| za!;-J&wo;C+Sy2oCKd)y9nv;T^pLjsSL1)A|XD1B1& zZAhL~N)c|C2!Oj*TB_0AV&hC>*(+U0_&{^hS$mRt)QuM!0qB-e`F|zy-slR>`Y1V0 z7Ey*QejfjP@m=$h^>m&P<%RI-Px(YwC5P1{~X!F#jb`LQA;jKC*+2>nBC&BUc;m>)8^cXohSFo}L0%uPiQoC@!)3JA)%& z9t@+y2(Ub_&LbA`)s++hNkZkO4j z41K>eyjGtW+iV)#K%v74-%{GdEqo%!4t&o6g#IhLzYw|a(xfe}3!BF1Y~A6YN8}f2 zGtegVmocUll41=Udd}I$PsJ!=3XmWx#7)a}vsAk=YK^k)*+8-Z;9Uykyr4`M;9(!! z&uLQYw1#Iu#SSQw>uM&e)JleSgj0{oZbB&)9uz9PQ-bKPras3x5Y)vLnJ_Z9jx^og z8a<`9l&2=V+)D2^#Z5Cej!2DN^T@YR`XYsFd7M;Y2-eha?z4ro^4x)MLUPA{Kc;o4*<*7pL7Jv3tmr{FWraTWUi@bCtDj2SkN104_uvKSic;#kCe7EZi?wyTL+ zlCeKIot%m=_$BDu02UwsIo>G=om@#y#rSOlN<{D`lt2= zr_=Ywl!kw+`UXsr74OhTwS`chyaWzU##VMMO2=Yb^w(njiM|!6b@9e6Zh-4-vC}d8IZFxi~aBi^47EImeL~1;mQghHGzYBd z%Ckdy(QJ@wn6+Y>kA8^%aKV%_v@=a&LZlj7}|cvqcn(<;Q88#JyEF`$55j|>FdVgYQSprFe^oL z*RCxWgqyoAvBXBrdHvloc#_Ss!4^mKAQ+bwH<5Mw0CFVabe@0XuN+VYZ4~?04d-Hn zq;XPz*O9-_-Ckrbl>@I_ccJ-c<#3@oBaA1>FO@!%Fl8soB0JVg630)J4bBky+hRY*7o2~UB711u%Y3}+)$i3??up-#-s2)XQH{^11$8eGQ?y=PVba>KyE z_{xPlWt)g3)K@ZQe1XcylT;e(a(C+GCi~-(=Y0{Ky4B$;s5Vbz{w5ZaR)FgATl1D% z#KL!X|8$046y~DD%NKwo0R|M1k91w7JhwAqEXA9z1bz~7g1JJHqY`@0l-3hvgWafj zti`i+w|uY}%nH4o@lQi3mffBRqy4NbCaYJ&$~a99F<(8RXKyiQ0yH8{aOV<>X?<~QC zi_Bsd>EQ@;ZU&j+=dH2FLStPK-a%?g)Q)pLJ|jkXL>sudA;W~!-ntmR;%RsS*?GdJ zpQMpTV}AE-3biEtC!Pd}A_+`$_ zxyW<#at|hk{^IY7VcsYsqjk(TwZ}T$v_BX5e7pOA^eNC80xct45U>g^VceBYlr@dZ zZ$#S;b?<7XA>I_JrYjiLj>cJ$)Ek!xPmD#L717zKJ+KfglVd_`A*-6avZYClPB5U< z&ej%5mALY&pKW4TXlb&OmAfMSR7{|drLIQC8!J{ceGuq!s*08bo4w6;F_%P?mc;AoPH|l|}!W zf~r4eu_SRvzRFCJd;d2*QZOTaQ0WiHaSZx@!$1133+sR2Y8p<9swiKFSDX?4abOv7 zNs6putQd+=!F5fbg0OH}Xc_#GCQ|jN*5l%gkV(~EQmN0}&jfTn;%0v&CZ$7pT}l@9 z7V+oK+7o_)eF-wWi|tCMS)OOE9gT;T-ri5RKjHWy&IWON4Pn1(So4s7JSugD5JE(v z^p%TNu)Sa645Wj@1P~9}#z|VSP9KSQy{AGqyvLXY1yTse3cxBLV39ZVb%lXA2X$$4 zP#k`X_=<%0>(gUSz_@{h5tUzL*r--zk@8DohL}F0qi+1O2FiR)NLaaSN>{?!Vg_X{ zB}?{_Y$(HcJ&ZFt6YY`vHJOo8p;5HsvAC5hyROuf{BStlcr6@36T^B1bE>JpQ+arO zNYiLo2JBkpMe3-?=6urR-=coCwN(f#_*o)3)>`Bu)TvEj!eXU9j>Zy`tdA~+Ds^(x zLw|_k4D3mtO+`#IEZ=56JJJ#Q-Gs^ zDjgz6%soT|iGCXpJjzbA2Z^6^x2Ke4@FG0`8K=jU$~7HH?GYbTzCgI=SS^N2D~`aXc{j7PRH3zpx$iUy?pnZ~!FO3od6@Jjg!owXRj_-` z$G$_*l!u_G;Ie{UMlYjy*d*@S)RoB~1m+o~oYftz==^iWX(Z0`nXdR_0?Z+(?^Z?G z?pPqIcxZWo)i-Og2F3EXZbJ>U$jGH*5ULSfjU@whMdkTa_B#2;pNa<_JSoda zbIFyELrMvUu(x%lv>>Eu$^DtJnrcmgW>ly{)xQhd!`fNwWM>3?3y(IdzW z6}9tpa03j;j!<0Bjnd=o@VEPLJJTaj2Ikf1oJ^s#-2ucR+#G=z;ocZ9=qm}Z(H(Fg z9YVqZ9m3Zz4|ZuiCIJ>5L4=UG2-X#ba3JvpH#EC{kbmbso08u_^>FVA@fpNs2zTrl zx4P1SoPNGWa3G)Bm6&#PWsS`E;)ub+9Q7_P4uFP-h$rTt3`cH?h!aCkco0TYPY}l{ zg1O!tS&RRGIwKYIgJAp!BwR#1yj^7*1{t3y*eU69$KEc5=R(CUrUL`i?U9xTXu*_S zwDONcY~jjia$dR>m?d{d`&6O7o!V~qBHt@K!#aN>xIaRnt)JmK zjMD~uPx0o+#m+{=O<`BHwYzv5fUXs5VvvMNT>_Ez03mVHo5TIIB|F3RlLMOIeO9D@#0`kK@6p~(}a|A#S8$& z6^Ufm)-S}N8wn+fdlXoGvg8LXln8$>;Q!vs%ECPpH}!*MviS4AfRQWzXW9QxCNx_e z(i>&PkSP@BZYQ1uTpZjp3)c}QaM-FES-H+^eaQWLWEW6tY- z`~CXD$FBEfF;x!;A-+^*)x8*|4RxE0@HI4~253g;skzUk4Ch`B7Ch6!QToYQvpig_!w`EOrF`G0LUPITH%}@*|cA}p?+mUeEYdc zhkR5^y=gCMADQ8Pqkh4+xujpv-_;v@D*oRLV1yx4jP(i=Fpz0&TS`iSMZ`x049;+W zivkJ5EOrk%YL@yLjaz1%q}yeWGZ^J6oH=@dsZ0XkmOEPIL$P?&i-cB_h8u?Bib

8L2{5vQ)DL_!&H0Z|vk*-iQ$qY_@LF{`CpVN93ATjE-PS6pDGA(l z0TJ$Whbv*hHJbDsT$WVwniui9V%G|2w{nHj#uXH@S;z9t2`j~Xps{wc9LxsfY}XFH9F)yB)pW17CNid& z%=tR3vAtO;2Xzkf(L~$StrKEVP-v@B0oS6deq@08$o*K=wl1d)@cXth=g95)u}l&1 zC$kfza|q_WIazy|led4c46v7%9H#=^HSR3$$E^j_F-(b4knB3H1&4sR=<|7&es@gv zl<<=b`xb9jY-Zkx(A%SCpK-Fo;*w#3u+Dal<}iFJ8rN0a=KeYo@8e7oLaSl= z7>&`*qc2v!Am{Z&n75SR>~Z#oYVwsq;bz=uw@O6v>WkxP!jP&D}HiDUz)_Da#xb<3# zLlPJyo$p~Zo6t?pfl7b|>Gs^ODKPq#bv-npC4+u%#tV!};owWBmE?03hHr`(x)z5l zD3sFFuni4RsPQK*G$D*iKr0M^HrqYk)$JOF5tE(FwB+*^XeOfcmn;qOBNA zX&Q&?@KU5HW{@1jZdf$TyDrE!X(hp380X|DmaegDHjce)HqO07ugVrZv~hh<_S5va zO4X5q8}pU=X$&ISa-569lY$%PLEDae)^Jph!Emf45j)})iqUZF6;3;}vGD4%XehMx zUS&9JBWZciL>i9!TYB3>z+6k@6R5I6t5Ko&-CR&orm8WeFe0LTib}MCq2VZrgi?8? zoS$M$jTwiVLQG;Zp2z*C?F;MgSVB`>o&#Qjfsm}0qo~XREl~=0*a?k?cxdbR28~B( z*J48GkxojN*0#|YQA(E@+#Ob0hHh1n5@+u96Nv1{Bn9-%KqqW|I)3sfbrfaL^W*_q z&TuKUhhWerNQ$?7PLsXvY|g$vbq@L_dtrM-Ms%~%Y9sqlVH9wT$T+)C*!v?n!-7F< zQHXZ0LY3czNH!ai5~E+h^`y!**lUf&ezt}!JRGM4TKvd*`KS`Zhh#qLtc=Ui^*#%e zX33)L`llyJhNoJQBBU6!y9>6CatQ~&vD@w)v!x-uHAc#4s@bSs!sl+HpruYZv&#H_afaX0-7&Npu$T~rOoA`c zAF8TO(c{t?KmhPoDQ21WtIpi!{=F};A-L>1fSt5#5(X(3?<^Xtcts5@VwTGIi zS+Z&9LQ4u-dk?H+XMi>n1tM|d=v8-+sXmJdv(0Plh66+Qig!G_{g{aRCnt%YtH**0 z$%E%cl5yXqK$+ftz`2t8uRXXpyu&#|-PXl3G;L8pj$S~lymZ+4bAC!r_Nc@A7;eXI z^zOHp`vF58*=T1EH@O8NQ+dQ;^5V1adbGgyh z@`$+st-Y3Yip&+?>v^Qc@nySO9~LSotCrivl>LP*4=^Xb*bP-+H_fH=u$0FOWbw!+ zRaV?`Vj2}CEjEC|UhZiuWO$Me!k&8gZ@ZYw?=u_4gj6+X@}zGk;cz{Uq^xHUv1w+p zugW9-J+Qft?>C1(&wt8kJ$85K-j)X#1(;@PX;ii*w0+Mq!E{oR28;Q1-9}!fH(&cQ49XZA@b9JznHwni4zXD0|&YP5i{|Lkvt`w zfQu!x@8K`p-01Cw;0tDE%o5Ry3aR6Tahke5kOb4<3E`O4m*82`R%2nK5Aj&q z)>3w0$OYG+pRp!b`=wPr%Sz1;onpk5-hz6TY=$*=VivQE7g1&wId)Ec{5EuoN?_{k-M;~d5j>1Ix$G;g_hz*1BF6y!s}Hf8?Vfg0P}_u)%rrDdZ)sW9!5fL1 zTG!ABU>Vu0V5s_6>w#W>XOH#tmMUnj-r z#t>H5?^pz`yc<9kirt*+QC24w?cNAO)s=G4jYg`7jnf~Twum?TUB>enLlt&=NEf>N zoM%aT9PJf(Rna`~FP5HQ7jR~uj3m(m3_{q8^HKZ7w#@T!oT*R*Cj-`Op4=IA0XOD_ zGA(j#s_6xRL7Y7QiUHGzCGj#bK-$S}O(3I=J0D)@DZ%9k^2@KYSyM{yIOYimKeim= zkmFS)cg|A%Kzhr#BUp{i%{BFA-bk$(!fZDTgmOpA@e^Fu>_0&TKt*ln%wDb71AAi`7|sXk-w!17o;kX2e16?dVW~@)4zi z;)T631E&(9W{_?_RlF^O-3$;ldY%fPQX+bD6?MKpEc=iT4};rP1MJ~^WgeQ^^Gcpw zpPFL~W@80-RbKC}2r#|at$ANLxpMqcfQ0Y3L1N@}3zal`G)E z?!MjV`MS_2<{;IUMRG!k)z!WRft~8GOFi(|aSio*)Se!P`-89pq#pW|Hxve>vXo=B zuZTBkm}eRsNP;_Zu!&V6=5%hHzbADDvM1#49+V3O1x_^_Zm)mgNgX>*5glb);f1|C zU#G-oPzPP#^n2H=kw62ts0DP*xd9rmp5dl%x@GUoGIp0s&w%bxCG*jW`C;vS%@_Dh zw;j@x7JH1{BF2uv{5!48BTvWSJ2g6ApBO-BWIxvY7Jspx51`F1ejui<-V}#9#C^>% z^v9PiNC5X4;pTgm@ek!v6&RTg1^XEk$gtZ2>a32*c4`L|e>h#-B9-$3(($l~q>^kz zF4bmFB@cJr9pSZE4*oYxO7E_Y??JIKh(L{d$qTnH?0OO;s>SfAJm9}s+hBzWbr3@Q z`gMZ%zZ3|`8`zrsXImVt7Vd{FhWhm{rD?&`hO7r^*n##W?uywGn4(-8svdV#GMlvi z0HyPb6;KkI9!4z9y$FIzL(w2oxG6*0Fb~++ z{rW$=w8x`hGsuSSio;6#Lu5nyiTf8ySiI4*<}cJassIjH18?17bmpc$Re%W4CkcbM z2Fz^mEvmQ5VBqPs&8h@ba=P=#wDW`Jzun$b5e^;3lTGLl8@N#lx-{|3C0F*EU1MQNHuUK! z%_rdp>sTh1t5xNON}uHs=Lw8hG**%bSC;w))jA^{3@|Mkt^=&{rHFpz7G5hgBy8^L zH&re>yCNT^=jEe%&uIsuOh?G(YJa^Vn{-y{4P3^N>7}l~V{ybs>GianAIvW8p0`P0 zMpgYNIfs$jbTHMxpH?Ms8Xh`}&8>Zl9it){yfsXXE8f)W*a;pWVa0{?;tUZEcyT1Q zPe}N^z7c?S|N3$GRVyi}(#K6ohjsF80?}Q(5&V$v`GbE9c0A?pHL8Z3t;Djl)az%*F(Tu&w48DbMM8 z>Wu_FS9&lItH+whnxW{DAXP5g zix0}A1kiCF(@?5J4)Y;*s?H}HvQ`=nDQr2SwUZjumx~gSws=W$(Z^$)pH&`L_FgfF za3sb>-HhEDSJ=zhbuwME5RUzaJZ95rmLdPPVzQ;fz@q#ML?j;q-Wa9q?{hkH1$47JtMm1s--N(fOEF-eDG1c( zN>Y{nM8a(#um~CoG)FDj>Lwdd zetH72v5q89>nZs={E>C?)wKYc!jzemNKV?8h3}1sbC$tbfNezBd>id0>7_4c7kNeX zpL1z}rBCO$)eQm>o5wy2&*V@&y`fq%e2kD^L38{@t&5w4Pcgu(`1l@|6o$~xH)r0+ zu#@K8EA#0>iRw5SqE4mGcZ@BmnR9ZvLkdBS<^w*=M*I!{ZO_<-GwEm3{KjKhW*_k9dqc>$*&E=%dR{W1eP3b2m><5n8FAs z&XGc>g0=?qZz$oPZn64RhlEIGzq#cqv)~sPsu}cFTZ6Y4{M3CfH3qiT|6J5CtY#@!|<=NxGgnO(E4i&j)>WqNbqguS|L{c7$cVS&HA>kbZ+zu(5;!JfAqegk^ z4LY_D`$G67mKmsq=I}u38uBUAZy$zI5BENNVqiF_q<|l;@aj>Ti*!>I0@e!Kz{(F| zWnstzYaJMl7Ioi|E{uX!%aQ5f6J4HcdZ^t&4E>wwBV!onn>ShvfP*&}>7I4-OjhS# zTC`E>K_jezF0o&J=&jDFaKtVBpdh+Ua1B}<9E=UUH;y`xSm;d0&4F2F`BPyzDr~9U zrS$k*dIaMhhzq|hDpFDU?;g8^Gv!q=KjrY%pK|yQ4&s-QIh~_{t+9!B4O&5n4Xbt;a!V7k+H%0* z8A_0$SILOsb*D{VBo#vz!xK&F(y>Q<@E@x|qg)p6ET-c=2{GC1#GivAdRf>u72}(g6CrtpCXkbmRYrOh0%8#k~E$sJ$ z*zJs**Th8os4&JfRzfBg3vyZH7muyt3w#_4`y;}L#;!&$`oqubbLW@)6CEC>4KqH% zL+B>7`3O`KAYly5^Y<)H3!;5q+Br=VCr@;+fzah$$eO+>CRyPgIpl5oD>$E_sonUrXkx7K&XsaYU7CeqYspklE?7zBQ;7BW z?;Q+a`BczTt0St-*f`2rh^8xb>7rDlKbyXNsi%(V?8S%T^zI&Eu z)45iN!d*`lkm+scRVES^YQz@c*8o<7J05=ws{CH8Iw9^bBLPp$E4u&snVH}`VjF)H z{hUbu8-EeI|LZgVAN4}Cnw7KiGV0e%m#wKI2m!smB0<6*X*_m9B;AO=FaZJn83^Qg zeKN-h+L)#TQ^C9MIyA$-A30tiG)a<0k1)%~mo+Uan_DU?bt=C*Ro`2GF4{G|?^DF- z#Ea+rPitnmK2K|2x!t{9HzzyZ_L%$_dSG=B?=V9k_6EHH!oOCCD2mjGe+L%3QGm%mcsT~ z6VvW+IEJ{V>tLj>-`7_OuFG`W5did;U#w|bmh4?orzH?mhWJw1X;ZTFswuFR>B#xn z7-d51rU6dVppp;SR(2$@JQ*q{EqT3Ee<&+Rc1l*^m6UAHSe2qp$VIDtJ1c5_e@T_h z!0viu$D*`FJ=;N&QZrFU)w?p;(KrX)laU7w-rD-=9I~`Zcq*pUE5YkZ`Gr4s_W+-I!xN68 ztc>0b`V4(RNFjAVy8A|+ed~s}V-Wj}?0$+umNNmGBcb69d1u~fI)M8}YC@LV5mcp~>bZ*I(3*Uq}zJ*Ep$7-SeUo@msM3V|8C7uNC))QXS zzR#QFLr@0mlFmq4Q`lxjF7&eq+zf{kg zu#8oI8&X&OQb=sOj2DV+#-Hv>WDMr{;9_uJ(|z15W`Gk+x_U@4X^Ihrl$l`JJ~ApN z0@IJnFcW}R7L(m(A7%!N-E5yb1ht07xt-1S3f4{2qLivj)I2~9eJC~Zu*ejV76=i^tf;a3E6YcVP`IDErN8nbspT) zaF)EzMUi(5sY5ZiH0uFM#ZHE!di|?zA^V#R>O#E3zU&BM9j((s_0#rLim_G=rYUMD zL=LkJ(s5mz1`g-!P|=)l6M7wWylf&b@o}gqLKF9T57!UKG`h-W1J^>U+veV#+G4f{ zgPtgBWHsXeX~U-6xHfwNVe>eYv`|)u;ZFuDsn%fC8k*C=+QPqjR}^08m9~8E0z}rP zY2#r`v%1ytDTzNj-w&xea&C5u{KLNm%4+CwyKs5u4h7^HG$xkp&ES5GUQq?}Gw=da zED8Hl~oO;rktlnkZ*Fvri3wewcgKlf!MrY&HGX`>So8dAEBGEAr#W`WGP*(&@FO2?C0(FPgHSxhF;iGU3dj z9S^n!SxLff-N{ZC%VjiBEkrK71VWb5ub4yvk=%#8oL?hF0j z4K!wNV6}fLi?b+8dc_1;GCo_{^xF9YSEE6A@-W0lg87aA`tbPwD0|1o zO1Pz4G&VZ6y<$7**tTukPF8H&w%M_5CmplHj+5@3?7Q#1@7epydCq^RsyS=afSZB5 zY_YTY1hcQUm2RkD^i{0IH*9e$6Q;c#G`h#@JBX>6btYLj=~4LE0=n|E> za4R8ylY7?e{o0jDzw7z$rVy>2juFH*hY+6Vb-R&Kxw4MF!@jkYh%>&6rmfLnO^i2v zC1mW1fS)5~1mS6A%V^rl`To$Co?uB^b8cynZf}zB)-p$S9*d^yUDNWX>Ud+Ax?#z> z!ytX3T|FRL{)>B=il@X5kEaUGQH3{OrQINPC7j)~P={n3?F~k7VP&fZzCLRFvk=&* z;up%hEZ8XX2d{f2z_63=%oQi1(|pift!PUvnsCjR+!c>+M%kd~`fviJZQR){!a_nZ zDq9UmD7sErt;V>TNGp;$Wx7}-YmR7V-!Gn0pzjx}UiVgNbU#DBO=+7poZOAkE_IoB zNS3Qdho66IE4sfq;lL$wNS6n zLD}x{5L)fV^MZbq`U$dCd6m@OxUE%{xvA_?&;E^HV07AOng>{%qw5A4ZiX#>T(+&* zntAxF?g`*Ob#y!Ap4Rt7axo@fY2>`uXZJF@!)2H)?GeYc8N>7wa!^+!g|D}fd^s=T zS73`D(qTEmNovI*?NPT?Il}{R0(DIW+L(;`!4Zy0pq`jc?y_45s~bNftr78HGf>3695`+aI%tq7Z*-#qr@we!awt_JPPit{vDp)qg# z32wTRF^)>FO3z47lT~BOo?3maO9_oTL%ZzDkXloUgS6}zLCjYG$uqGZogO(7?4Q=J zoTq%&n5bFVd_oGC`(e1;)!frWqrr3}B|SOPA(}Or7edQ6W#$P|t6gfvU8S)=b^64{ zE`O3c!RTUR_W@zQzG0vurdsS)rpp{5E=rv?*XC6sVsA1Jo4FxEiuV2QPR+x zYV+16eor7(QqY?C4h5(V#w300n1}RWTU$L%XgyUz9FM#;e@OJ#-q*ub=u%ia@(qyU zZ}Ik+1cs|W5V!{F1Dij0gRBLj@~y zUz)qn0v5ztqtXp3NxPV~HES+j7n)HBue%|AwDk39ViUng)5D3KcXZtvWqia9P_-fa zU$O&WAGc_6`LO0aF+utF#q>Nd&9abf{3osajFQ4>a6wPd5U`k#NwnQu-#WiL08OPw*{6pmN|pse7y}vSZS(*#jJn>JLk}oj z+dgxWm4#;q>RS8LH@?4qeEQ_OnE&;>o2mx^tV@$ccW=`@kc5bpQP>MCIx)tQr?Ga# zW7u2seKf{F^QdDix?2pn;NLVJ(^lAp9ocQQhIo}iMOPbS#m`Ws&h}nitGn~{S-qx; zd8vMesBEF>z-=b2wV=Og*sXc5?`$=GbafuikMC8jG3C-PwRaLBS_@5GQ_I$KXk+|z z%}!gg@`@in*3e7#Pj&NJ=AYAI`!izy&GXva5K0|Aks~w*A-_n9#Jsh$klLwQuGU() zeZmmU@j)}0de;=6*8i^p?8QDdJt4PU?V#*YwedA{>SkW2javNUP8^1-H*_0?_~OYi zx^cl+m@o$dI_`WDArTx-Mn+5%TYUUiikbmt#gZ=U`WmtCMM zt>W2s9v8Na2d_^mbBMC1Hp(j;cAPMm#Y|qZvq|l1Pr6fxaU*><*;i>hXR0<2W4Ne3 zu1(a)hpAQJ;l{D$FI;Ts_f)T?db_0sB2+I_)l?5(?sV_&td>fzI%z+)id0dHG8TV6 zbomcyx4lm5bN^A4cMhd{YaE>!qMP04TcX*$PpMz_yB_ohZSFj?zXMf~_=@iB{1*gjVI3Dsl#ChL(yZ!znRx53tG18K9bhs_|L zuql*DrQI@c^YHJ5C%0uSdEV3XDV* zCKHt^R3gcFThuTLOX)p{acLqEN&wAUkL(Yb{iq{D z;n4W7srXQfTg)L3{2MASW@k@m z4GQtNW%N=m?nM>!Eqv)CF*IYyeW+A2$e)Tv9mKE7UZyFW6$yNzMXK`(ip(-kE+qv3 z0Ecil8HShckegEC7&%QG>`sL3?;;5_<5*Y{^)z&2Gajv_Xj_f%&tm5ay`M26dve_~Pw+quS;%N;@Ve4t|K@<{Mv<<24hdk|f^@#X*rnBgj47G&fY!88{H^ks_+i^Ec5?VS1{>Rlad1_ zD3%!i5d8uFvsuELK$9yk@SOgjk+PeLpKZazG<|LTy!$V5{Po*Sz~>A6cie737gO;b zJO=1=L_9PKpDJ@SHwKPxC2{ou%E?Fq+K>qb3SVT>W3VPYKvNxMNae1v=zz8cpsBJD z_qaDFAt3?Bq3U{&8C*{>jNdzDd!qeRWuwE`8QK9Ar z{aZMBCivq(&L+)ln#JdlKlc%TBo^InR<}1V*^%-5&O6op$+bDhpU>jzmo_EmPUQd^ zbT`zN^cpfhdL?z?C8>k72q!^0jyTYvv1%W6B~PXCqNGgpDai$@&WKoO*R1PY8vDyp z&)2khCraP7jA8lny7`dec}nba6gJANE|PEd`j}A@<1c$I@lC z(POKl)?7kdZ-h37;aj|~(^HU?Q`{YV!{&>8p!7`yg#rUT!{*q>4R$$I^-H@kaN=fT- zkpz=!G0XBryGc;||T|XH?b9<_(7|lI3fPkGr@@RI`k{Ug-vRHV?J@rVLJIegI z@o@I-nA&c7ZL_=67nL`UFI;Q5@)Wi7`2D$-%O=FD-^T=T{NqOWXy0M;L0$qs;b zf;x)!5=CL-+`CpGRc0boS3$E(M24VY5XX+&VQxgM<}HO1M)A-;C~F*ZY zsF%!dxaIk0yqY5r_Z^qVOgGKdrwvlQGzw*M3S}ULwaFG)_YQ+BB(aH(cH=0k8Req{ z+mw7HzxB4O&He=1hH`9@Z2qp5tCfR3-ZUkcA!k#X z0 zs#d%Fr`h>SZfW=>x8(kZbMGth=-=q{|Nf=QRkcxB(!}Ol8rEH3Y6Df_+p+6JL}n&v&mjsj>$ez zZ=jq3fr4z?%Z|}P21vrYFd=CM7F?Qs_McWdPujLK5c=QbzxA2(GPb>RO09VuRwHON z_ly@zL%7Y(E4lgk*S9Jk?g#7rj#yMf#NX0s5z+XiQiRI66R|J6Vx?VpwbqHn9%4qQ z&8Wk{zY6}U1q0@=i3u#zal(ID64E>+O^AbvPnH{r_moYO&+Z=5(?ayU9z#1OFea7k znl?JyRmj*6#G_C@RiEHbujDtf)M?cdd>muysxK$ltew}l>yl?vD$K7ysAhhU`b$fz z?eYi6t`>bT?|wi|>s(W(c*h4^^e~3?QEw34Mg)qycaY4|dec7iQp(ua^V=(XWNq8A znE*dZ4ohPfPeattZnNvo`updk`2gG4X9J9?m;4myM_UL#1m(xSLwX==j}!o_g0v8D zJE+p^(b=bQI^vqYixtd%vL*7V zSeZR7o4VXgBp1?m=RGT)B(W|zsx{x2^hAL2tm_erb-{a!C7xS8M=dUDQ1G-St|s+x zSxQ5=S%Uu}04)SLBEN(A14@SSo#^d+$`O4``S_AN9R)ReobLF(^8>0W;HJ?@catk; zyp#iiM_veSt=gM}?|-E!18nrOU z72tX^C7KLrWo25&Derxg;P!vE4@B3=b>j57*>IWt(ox^!`20RK_)_{61kNFtGF2T$ z1;LEE#^B8}B@S+NWDQI8nC$84CJ&Xc$)0C$Bnr!r>N{Jy0m^(? zPZa$;^Xc+cSZ!?56{8MCde$s=y=^CL+RgZLnKHb!yojM|oi6Q*`VZso*sON@_b|pb zy1#JkD=ojgu1k&?eO9V$6zm~`H1btpU`vawq4%d`e;7d{tmfN5_B5WaTzNC)2`U5Q zbZIBSsPa$g=C9cXE26VS4Xf*Q$XK(}R2)vwu>I}J$aWBaZq{%gkG>!amV(4gk~MV_A4`ff^ZkOB;VA`%CFrDW0yikp(W*6Bop3E=ed(531h>*zUa6d4 zR101{-y&z~jJq&@Go)Q_n%(ExL84v93u??Zh^dD5I4eIeUJm^m+e&Iigc>> zw&qxf<5U4lg}TFyd8iAYHcpb}e>9j%N-P}Gl{-*AKl)J98@;Ycn!PTeyC={~^oF5I z0eoZ8rc8^xA;qDgEKR?IR(?)YKTs)gH^NMIwJ&y|d{rdTQ|2D3mNMJ}25+}4UG41`_(TSACE+_)lx!l{#~#jcq}2rKe?wdvePoJFMz_qi+b^dp zjOZ{hX6740+B-tsJB0BO$ovrs%XdT+eq@!ai?DA~NAz8}$$9)uKG}^1agnO1B>Ev5 zV3mJ z==@ty!X^dEZ~&eN?Lr8X!Ffsg`IN}tZ!&5q=(t!-aq$0joLErls3ml-zOw84Vh#IJtV&cGR`m?13;XWW86dN|S>>h62 zRKgOBp|r2QFi>?{(J5JI=V%pgOV7ek0ViuHiomqOGrF+#$ZHni*~0GHQ+4fBPvZqL z96AUFTRcjA<^{ZjLjnchfZ^Rtz<4{>lJu$ZqdCdlPU;+mQFiZYVXKCqZxy3NhgT=_DEJU>*@)w4D^n}%CMqRM|V&ds+m3_||I zv>zAQaw*OuesquIAdp|j35JtTE$ci#xc39b9Ym7e(Uz8C0NNbXhl0soG5s8py^XUA z1>fgl!d4KC!c3@G7eEurv46M@Z=J=Hh-0&E9i-SLlJWFDCrqpQ?e?x(b4TL2t#s2wiOJYeN z>$w1spSUhGg~fJ5+z1^js(?cL7uHIIL<@E|#D7{CSv5)_;x7)1XPi*acS1(yU=3{O zc-!;vV0Im5-KYbzlH$j)GfFXVRkrHC&&i@z zMz#(X|Ar8Azjpn9mAMX_l?}BbVUz=8A+nvK(DK_+>BxP;T8yvG;35zfwk*28Pg!DN z0Vg2vtG=(>df=vA$6Yx#x}Wo0o_@)_J^!p11fi3aScvIn9(Gbd)B;yWFxrma6GA{{ z#vb}cD8__8V#24CTy8y%<7vLfEs{*feY^__G#y~j0)18w(_whEA#D(_cY4#hd9)jN z-a#RxJ8?l+c-2!#3w5=v3OMnM^BrK)EU{$u%l6K6^dXkTns)j9M0Rc(;Gzz_d>ujJTdY z1H3k2or=lL9}}*YQ}KZ8Kx}QBm8B$CQ?a$k*!crs-=rQ?+cc94QgjvA>}|!BD5=Oc z5=6T3?DH|*v!sRxOX-q(%{_;jcJjMS3O+2-B12v#`e7UWi$Lq8LhRxAif92h zp&Vrvf>OU|eor&ay{GdCOBw9PLvu*vWRCQpgv&6-=1J#AxElNQGyaL<(pT>-`H^F0 z$t9l{!-G(*Gb8_ikg@7{kQ%OX+vH4&a6eZ|3#)CqG|o0S$(fxiIef-C<=F{!B8znA zHhi9}M9wi@|4&%wh|_(&qj9X~CP({G#U+fwEY#mJn4{}LH3^KoqRg|R5_9upStWxE z^3L$=ht}Ao@brhu>tY|gWsKECcU)de^&&5_ox}6)XPzO!Z_*aMA%2CDFu8y@DBRy) zq$xI)8`lNf2IZjWjvAChHQz^9NR3Kme!U?#J-ji*MP;KOZcsKul{G5E+Qh5pJem&q z1GwVI-qkfWEk#ZCpW-hfZ_v2#nW9Sy*gg@as0;NGSNp=0JctR*>4LGIf>23lh?YP_3@XnbCmT35e#yi@8KbusG}wZk<^YM z1O-Qkn1VY>5#{&(1^>@pgXlL%)BJ+!$1wj%i0;1|?EeGOay4Lm@zn_aQg%<+mMxJ< z=xi=7CfhHTY^5#I9$O|6R!ZSIvtiD=H}USs@@~L(Czq5K!9-N-1r;sph|=cqpOq>0 zs~+*z@x!n02Ci#FTt}@Z`9~6 z4?W&!;4ET&2cQEo&C-R;E{7Fw$p^(7W+YBy$+0jEdCx6WTxiGyx zm_67=0h&V^Sd%QCwl)WA``s2VyYA5Y6N1eGOqNznwq>KSSj`ssL5LzY4m*2m-L2l% zMn5@^>QE=ADYjZ6etm}#GH=~Mws1!cYG%&FZAT*S)N+Un%>)8%qO~`lSjQrJ)xwruYFveP*6;|@Vk;tZku)|`j@<|f+Zi^z$E(di zt0l73y39*inP!^utq8Fi64_46;0174vv;UMh^$uqGg%+Z4-F7v?ujHdARX zTJU-3b3Wv4TXNf-l{J^|{_+aQ>bXrwl-;JaWYtD*Fp~Cis^qR)J099J2=`Nyf!m5Q z{HU|j3ubZ(gK;)S-TwV;1RALio;|ei%!T01qUPsfea9dNezH-6_Z#vgr}cU)6GPz@y7Q{U;f)p;?rE;p37UP}whUV#)WhZK=TnhvhzVEMaEgLy ze`_+JBdGC3bVSj2WVFRtG61^1L#v~oQ31N{++i*9^WJC(J0Hmp(*b#-^`;-%Bdjm6 zQ5JVP7<2m`0Dnfpfd1bA2I1}~l3&UTB<|fKbt=CYu(}C4G)IZlK41gPY31Ryu-4uz ze|MIb?{1Imwk^>9X!N?VR*9L|HMEWl%}cn$!uZM>4c+=Xo0foiVH|ykRRPah9Gx_z zo-=`;cvlpae%lnIq51({-&Bn_JQ`PeCLp(dPnr3 zF>?7r6ms?$875vN$LhAVss`I3o<^<)Nb>C&;Na<<==Vxd5H1!cPPKDQogu;ZYVkym zU$fcIUFcx{7Ts~YxUyVFmGdh_(QT5tQ!ESc_pS{uQxz7@VF_M`yl?IHLTo6T$Gf#! zxlxtWXtLr*B-Tp=FHLbRU_zFchB&n2W(ZlbK_OmjVy^)+VC=xGc42CLT0&9EPG6_1hNZ$B z#3=nze$Ww6&VuSgKX(;ceXYh0DVnX3KALP$(205x)0^AfURq4~as%?Y+^%QC5Q&n% zD_~AS#4NCcyJ91DE~nXAYEz)`T*)?NlKS0;*tQ;-+MOFB1A>b0&;D-a+$XMIJNcVP>ao9K9Eh zj-^rDIiIu#Q0pA&lpFD~x;m04-iAt}w}BlxI{=V){#M?ae@97OHXX*H@AenR$(wAE zB!5;M{I!>zz`f*S;j^ZFp*4?uv?XZBnE@5Kb)eoy*zRGW?1jGONfrDWvqvM&8MJ4@ z=lP0ds5#$QM5i*dA~CaQ0O3$3BV-0A0}T1Q^3Pts*&Gxvr8j6LZs+lhm1zL~2FN z$-Jx%&dKZdW~lSW6kQbG+Tj2{nW8%B_tgbr`a#2Alm*66a54}DtC$E^JfVN8rsLlX ztJjsTL(Q1{2vr5cdBYa zi$ba!0n}AayfWh98$htky$VK`X5(|2^j;TZOXyEFA|WN1N?V_}%C1LnB$(}F+^(2q z^%90NdyQlrHo`|jXU2nPZVfF^I2O25nqaLbE#Be{)j0{cx_yz_UAmtOJyZL{4auF{ zV;Lh~*_g(QY5tN|;SXPg5ciC3teIb7nO})$y^CqRkL>yj(r=08UuK+oS+P>ycP6`M zJ%|#a@d1hH-p*Kzk(jKYBm1(^MPfDxg?C4$JA#uRyPYU@qc5E>>_=BRFxCtOcf-3K z>HDziT==$TVWtgb-^ZIHb``FQLbc93nhr#HXyp}+w-+4Z!!=^w6AIXfN?VoEg_K`L za&C?#2$)5GO~x5dq!n{n$hMkhz@kZgyrj9jKwLbY%Pj_|w$k@aG?dyhm8kwVg zg-=^#oy3(t9~h|LfK@sj>_^QV0iUe7q&GBOHJ2j8&Wq{D%e!TCF(N&PGCe?`8QP80 z<8w8C!0%am6#uy)bz`1j%BNL+WRtX zrh+>TO4uf@Fz7K~^iW`Ib5ce7a;niC)(x7ltTo>8nffsxW>rAmCcmInVR5s3{b#=U zjX$vRg>LD#ldihhs+v(s$F97#ZAslAwaq&}dA47A?V@x;y&gk-ZMm#P!FY$c#^5;r zpf8_5WBC(^zp~T&1f~{{Sk)s-p+Df-BfX+85<%ok>$s@oMgv*(%Z5hH!n;cSH(_Vi z3Lvi2et1rqsASd~$0g5Y7D@mq1! z7ZIMF4o>yzd%4UU1flC-5F6lHB?T$TkL7+z@s7-+X`Ws5hEoIbqT9fjm$+I);6r(A zvlq3%yl^Qu{-T*D?L09K`6vy1P9zQGHSKAIsmZ=wPU#^|b2&lF?hyiTRq{odARt(J zx^;|~)wmLiVdIgiD9U5mtd%ev@j?p>?86x|-At5LF*fa#Y?Yz?)#f_gXMPdfwX+)a zU9rcXftRg>t~Gfbz+nhso>eRRy^4(Xb5HisJ-P5}P3I*_4oH7ozVq|!xGV8 zHMrge4ymZV4HVx{`%P)CdDgMOd&WBDh2(_8u8O1`S21J{x|UrY@|d%X;B|1n4Z`d5 zs{f&yBnn1T?fpykNtyiYvMAXbs6H7vL%$M_Dpt;AyfzrSi(k1kTbp6u` zVEKRP%j6i_?=tHh z?nZYVdmT^pFGS0{R;d6_TX`1F=Us>EXR~YBUjI*DgzrPjFo4mn`Pe%UR3X{W1W`b! zdx;2o4gv|dTo)&~BOuTgWCPvGyX_5( zgpb~_tIeEW^FB;tX0*Z#i)(FPYfsZ{4A@EzE8UP!e}ZfaSAcP}(85)b;n@^knr8L2 z9lS+|LpD0>=@l4fdxwc+ABt+pwK}A^l%YfzUfS32H_3rm^5il!IBB@FV&-F)hebq4RLv9#N(<%Q_*l)VC)TVjT*Blg;& z2p`bya8_`jIEI7TZDE=-HcrAcD8}lvM?kJCI--35=FH^>0)!Au^#>$`m70Nd#xPho z;yT&|AQ5Kb&P0~iy+)~Q@hqD~>-%a;$<%roC&~-Awp99@U3OkACBf>|H>xERt298> zA9$Zsk2>gfqxL82og*?y^qQ!7_SqaiM)9uLxrOrVZlZ!Yc^9@Zgq0+MuWxV?hksg0 ztsJJ?wj^+D8X6xE%^>E-EjksP!#7FQZ9B<<=_e2;nZspO{=zPMEf0KTsfRJ>*R;6| zHsaX^9Bm*@5gh4wwJx9yfV?VsXHyx7cO_SnHJDzIZ3?^;V8`Y{fVmn_2@HStW~nl@fmxk@lsCEw z@Rccx|HflP@OAzct7-|=r%PVP&>b})A2+{+;JjPbV3Ui$KJOIO8hH+|${xkgrH~_d zc*h%Mufi*If>@I>z&j9FqMl78D3WBHe<^w^MIEAV$p4>h{aWNYU9@1{si*7?_19Q#z+WUy;j{9dgn76kT#TIEiu7&eyL+{Cz} zN1&(X+7ExYM-3`e2G6}pF##p44)xs`!b!TR}oaFq>o0_iw`7;1yuOnL= zZcQa)xJZ9T@{lqOfv&tUxM;NoSCdoGToP!9fo_9Powjq*>zKU=yQwep_R&Fmb~smT zHJ9!ja7rj*{hW%|W>#VA+*_}UAz(SFW6)iENj%g@95LKLlA7}Y->E@?nPn$b7?MRJ>YeX6y70Jdz zdEa4NV10mT&wBKDEkl?Ccuo+k^^qW$qv#4kOy<#HZ7it0VOsvnX#<{(;EVm!Ni>>M zw7|Bvbj&3Odv(s5b(0FP_z~7xm`5<#kdI)d_2pu>v8DpMCT`wJ1ds@m_TayqLULo= zzW*pgYQFWz2$>Wstc_8k10DxZMNxFA(R7))8oNDPaunvnYMU{O9kNLwqZDI}t5z8d z09NKA{79LB__0zfVEQJ&(T_}=0S1W-S>(xw%CmtQLb`Gzv=zpPPtgOsB=7_DKZKqk z5W7iZ-6YO+3bXrw6SDikSJOk|dmqvO;`n&731)QCKAR5F-*mN^Aslt*|!T+qi z5Dcyw%C8B``sGaePis%k!Og|&KWeX3{agXx4Eqz2&UOQ-bUqAj#X51-tWeK;Vad94 zay3kuL1%f>==tipWe6cRGweXkq4xO|RKSy?l6gV0M8~)XRZi}sDDo#RJLSCxcD{u< zqgiQ%+;irscfieWfwA}dKScR{u*9L9eiafrI2;8#;YhA;5tqhy3CKGztlYnb^dgwn zhDy>WP*xwAJyN6ulR;MzSvZHcnOrID{6918mCCb zhz%U2U^y|O>Q|rw=n5k%=#3>F1XMKBAgn}%D{~cVftav(WDBC>st+0SHK9(@8HLSK zVSmHpc=Cl*A_{K>V9mf)x^lm@;g*iPtLe2OOTs{;wRSma27md!!A4OQT@-P0a{#7= z%v8zb)P^Gfn+?WQbmggpND9H*Cgk)BaxYm-QV5q_Ok3?4b`+Cz~EX!Zk2dSP=*@s(k~$Ki6S#G6jg>jZL%*+F4;pkvqdqaxjx2|)Wp6zeNZ(}*O;d=WWc$(ej z^LB>6TU>D{4Jfa_+0(kVICeNq7)|}^$o8P4a$RjNE$=M;c7W;_8&=+D-I!JvLes^8 zDjZ8y@#Es289D=Lqe@)sSf^gOmGmIxs>MWSvF)`+=BKgO@%GT^g|7ZjdM6fXGC9eK z65PXg8?!nL*gwOc;(fDPRol??dbbav*RUTF{YKucobxvFXfdST+vfms?U8iybFjUD z(qVQ|$(G0x@T0N3-aQP-fwC#;EQ(5)87l=t-0aBJ4*m7uTBIn(SgG2`E2|nbtD3Gd z^eBr49!Ud*c^4dt^afH**`N6Ch|&?gkc_*)7>~U%pNf%@o*x%YJ}XAh?mUex=1)nK zdrsdlgI%bzB+k`7emU==tIHljW9o`&!Sz}#cMndYA6coM)*RE+WCdBQrUH~T`D2|m zDr5@*ryW3~!*T;RIClOS4dyh~T08lDpnjWOo(TP)3weF=@iMQP>`~k&t693dvDoQ0 z?<)Qyk0mi%XPmcM!B+u*?y1){U&z7qppLWFr7*>UjAk@)#OJs0TNJ1}X0yL&-fIG- zW43YnCFm=^;LLBicSo=?Ml{I%LcUbxb^E*@aYVUvHw7Ph{V?uEoKX|SnMCxH)~GyB zMtv$FVYY~vi|h%GK5e_axg8bQ0S=k@_mk9SBqemiL6;)B-AKa(S`odjYp*+Xhv;e3 zihWMMj}@nuR%tU0cCQuigL4xn{F^I6$j$GShcrFy*nn}n(-NC!*rWiIT;EiA>>Ne=e zgL*V}SaGGuv?6;Mu{AV)RCz2{Yux-{zr9GG<3k2fdm+Fo84z^*9WQU~zaLD0n+E5= zdQ4yTkqq})Gsw%}IM@yNsD@|R4L5N9O|<<%#p+)$Sg)G^{aHE~&Op6) zBZ2hN3JCuzV^of3Nj1-{V?L4rgH=}%(cum-1B+#B4rOk{ z!O0CcxgX@iq8s}_p!=Rnf!_2%dX3Rc$H|(?WS0dlGXat_JA+W>8=IZUkQ3J2$r%ng zVcS0n}_eg|#*~TiRa!z?`I7|7Z}PJKdGm5NMsJIf*va!JTPESeBae*J;SlRlg z=nawHt(G396A{a&-K)B1t61$ZC;}z6hIkFt#!Ei!5C+k@91yWNHflk5snAK4~j{gC={fUG$7UrB|ADHsjC z&C}9=>RFWh)dnNmDykhMgY{eS%J_yJ+4Z(!K+_I_t43`-;uA0!l)j=z?8nV;uMDZ_T z>Ve&c7YeiWy|~XR)DXwrGP-(mXOH!WXxr^Zc+Z#h4rM}MfKtPUe3{7YVTVw&YT!X3j(#93l#=P6=zHR7Att@%rAouy5~ z#-`JkH#+e4&DtmYylk9E^u*T4`%fC#{V=JspI$-z8jR1#51J;`2Qj$-wH$fQV77_< zJ@@-Olr!>pb71VOp-ue4-VV+$vXL-hbv(O?hsF;_R}+m8Awo;M=WPiuU)i>7;skC1 zU4cHFsGA1O3Ii;J>~u)*1r#WVGV||MVwJH~H)m&tL(UQ%!79vyNqyvRmzS4XNY}*q z5+NigRST94>0oxt9Q6Be;UKww>rp`;_GHp)MXZT4S+Cm_-xUwsU#tds{K69`PI6>x z%X!6cb9*}o$n3?P<7U~&hRq{SLEOCj1jtY`yFKrWL$jKsQj-%qefd?Snp#50xpds2 ziuj?t95f$LF$suNsgTnsk<%!U<>d)Ilc3AVk<+M<<&VF(C2dSf)Dhq*?sWTQS=pto zufS(vX@;DpB(!D9G3hR1OfJV(i1$GOliG<&T28IMq-llw06vi+R;N~AYlnCUAyeh9 z{2(9Vr6c{yCR*yIxiqeL#?o1jlw_`qJ$Mt?oN$I)3x;4iF36SefPoTD|2cGwYFdUX|DL;Tf&O>_K-KbhzK7@EnPrTi_eS+nXA-*28 zzRCkV+})YDuJCNor0;|q<@@b>6~Le7?Y~at1QD4rZdPtV2$%Ojl5d9IVPRscWbo-U zNTvzFTiU(J%IdAz+tp=JBT!%>ZeVJ&zsHsT*ESt;b765#v!^N!$PUQ(>PL=xq&5ug{AKaVx26bDyY9P zQ(ww1qhYiF_N_vJ#x0&2$EY#goukQ7N47Y$B5AE3FprW4Nhj&Cy@@%-_#eQ8{nw=HJjJ)>pr@L z?C(6$NM+bn*YeS^#8C{2bJ8W|Try25+Dx*+khp_mwo_TYs6}>=oqivVf-wrOb@I=W zw4rp_x`MclIc{K>c~bCCv*cluRUr*UL(fnxDhT8j`X*a8cBzLKihyCM#NtcdNtI)F zz~JD!6pIbjUoqnh&P?$+zvKX=!^?T4U8rVa#5RyX2#T04v3NsnKN-+hNQtWvHf?DG zZ+Ri@k#E%T(Prt2mqm>IsEP%+AN_OmjWFIM-wmiBNKD}?%2N4Gx!|m>L=ygL3X69Y z-e8bFeMYke&yPj#cO_JmtDVG0)%1Q`SAh!1Z55e#HW)`uAT)`1Hk;)TPx zk{u?Q2f7_6$_8R2z?Tp3Sq4MS(>-7=e(=3*L2rdZPW>XFZXj@9$E+!4)KOIQ!e)Uc zu4aMK0xtlB6pY8mY|8lv18UpNoE)fh#ec*3`jJ*{97^qYgH=B8w3gaKW&Q;@%0myy z0hJ_zun;?z5=r3ob=5K!N{DlWK1u+=8TY+)rwa;|$qvq)gSrsC*azTzGA*aEs;ae5u%vAv0MON`Kexy=i? zFQ%!lvd6#$#f%zI)lCe=E@2o3k;ljH0K(R}lYBTq1kuhEWv=0Uzu|nHcQVmfaXpBg zqhH+Z_7tz<5CEqRJEN0VhJ;M(RKDW-IEUe0^ zMe(-F&3GyLRRtr2-Iy9m=b`5Py9!@tNP_%To-F={b+ z5a((cJiw+L^Als2*Dq&%Do)5xu8sE{dzx&GYloq%=9JpiLJ-tqtiY)Ghxu)_2My8$ z);jJpWF65lyzU3*9pvw?6IYXLtk5AXlU)zNy6cW!fyKqEcU&G;2x1764kK>hx%Y_x zwR~q0saJ~=@naRGJfv3I55QKI^#V5<;cR;N_~r?A3%N7fUmzT0zl7?y0J+jjH0odl zBaRQuw4obAaQtw&Tb!1Gn|;z3@RbWerHzjyxK#~DZs`U*v-J?bFEQxtAchWTRzpGa zL6Yg#-Qt}lef!MD7)dX%+pPpH4BHh17P zL-9@ogk#31Bjh&_7#@Hc5cM?qgTIu!mQJWmA-`(O-%OH&f6M&0?F5&COzBND034u+@v zzEdj2BGRZEB%5@5iE-u?s75&WJ^8J-fG=E7Rev}=)#SzGxcmj6!Rw0va3ToGwb|zx zA9z$HtuNOXc&k9wX;Hf+=m_%m@?`kcYC*dPU8IgBiO~=dz!Rp-Cm(Swe$iQqAB@AP zR4ta|Vw>>vL+tWMZBNHxuZpF7%lrPKKiH?#!~U5^yz+ju9Ay*Q&#EzvPG&~W7S z+g^1{AaIm{`*&AJNUq`|KHwpQ$lA$W0bTjpXr{lVw)Yt=GcqPt&M{h^k^L9tYoNX1 zC_3TPo{f;YM`Z8{u6q2NTF`upLU(Rrhat9*BgQI5ergM@c3ne$c!oF;hW@@1LF48D z4*dL1;g+GQ5b<~d{bU3EXw25lW>c0j};7+CX0NK%9KbbeEtBqBbQ}KmAFZi#635= zXaE>1cOHn*L{{eIUZ6^5@l1Z;AkkT1iM;Ish)cI)u*E~V`kVUr3;&39+Xa5D`4DF# z1;+a!jT0nzxp5 zJ~(U)tfR^B{5WFg+g?1Ba1K%}v(Zv+Nt3tdVFgIQ&|p07dDMXuWh#i{?@JIT*cA0> znsQLZ7zs8qp>q`2wFs1RHP((vxx`+$soBHgXzMYR41bvcvm*ZB4z zenr0dw#IAr;@m`=h8~$+1h(J7%vmBJ9t3kqGGbPL!RC@}eO@m^g4bDnJbn^?2@$=5 z?mb2i+<_Y%QbfDyD-CxsJ^gOfwuazJYxUQDKN_AAe0rS{c)?V!5~K;ykf;kAp4?-I zMHeS1=vLMi+FX%7rmq86%R@-!Jt@Wp>~ehTQ8zozukijXxqmNKVtPdnye%;9N|Vba zQ7S3$%l@$KsV0Tm_+dL#Vulk4y=M4o3_;_DMBxITQjp`9vV|bA6;RnNE=2+p1E!re zkzWn}?0t{&^^WDGtuN|nKP-~Ru|O#nEUT9`VR8ruJ7+dfjRR;G^*!85r? z9MV@{0Gy640Zw%sFG);HOui7Rr2n``gkHkZ2K$+Ygb0ksCt4r_1R0t1Z1b+|ZtjJr zYm*lULW%)~PNp_lFFPi~JpTh!myTN-X}7luRaet2|8T>oa6M9!xk5@pW5kF&6Yfce z{;|;t5^rB+kW7WC&JvZfzOF1V-l#IIsp)Anv{>dAG5ohxhgHK;88-(vp}|sb6ZGBAoGzdgFmb)LLh z|E9iIyHEaQ)p>a{?&1@IJxz&LcTMkEgN1t)yBXlIyMe>y9<}7L`p&zr_GNIdb~kv` z2ep1ULN^Qzxw~fbB}2>;_IagpZ|^nV6f$U%)PuubKG+S50$(z=Y>C>lo$H5#!~AA) z86HE#)tOXrVLvV89X_v#8T7b^7=rzch^7KXqH8ldL@qNtR05;VfE~AEgO9sY{^$MR70bw0!Q4R^;D_Y2uuDJc5odC#L)bmJYe_K?)@IYEkxWb8NV zb3spb(g{6gju$TPPCf#!>2*Lf*x!lmsb{j@?8Kc0m~6)9yTEr)uhB8tw`a`HJiPBu z+2vaVpS?;$vX9WAdd|mweAM&l+}x7We|5RMl!JYhM_27shaPp(RDA|jycY2Vx4%>S zcU|OTA<|=fN-uhd=AZ|TIU7DZ<9bJT(e}Z^eCD?7iZZ;b24xRlE8>2Ee-*><-rait zO|K?JV*Fg+)^T|u#{G)ZdAzL-xU24X$4Y&z?D@LL2hZg~`ci>$^au>!;`uyB?2TY1Bwy6%%?XOunnW$pcl*d_oMCL=?vE zPpT?G2T0vnq+?r&3C#8ch1Uzf&2-0P?6mudQJEITv77y5me@a)t=3JmC$ZX|N#0}# z9voy@zFl6|BNrn}V4u1Cb1;0b<{zudp`4<87<$dD!D@hIYrJ(3!cp-6TLjrF<=cLS zXQml{B(jAPPC$t^X`vnOeU}P7khST;)Q+<_)Y>an$Gpj#)_@o6Or?kOE0lEq`RJET zH6wnUXxv(*9Ge+&JO?X&>-%*ZQFN8q@~U3o`Fmpp$J6~G`x(+57oIqEGEy38CY36E zTu8L9r6d8OY=gRT3+=r30A@Y15~BjdJ0$^TKBRbaWW4H?tZHsTqoD)P3c`>R8&k-0 zh4b=2g;HPEhNWrp$ZUul)Bd!7WVtnp9qqfQ!6uoVJq1!UKIg%uPdq~H6U_vap>gUK zn!@CcN$+WbeQ(3=ID-+g6$0||*0O%THs@PJL*R@HnPuSZ=}F#keQ@f4S|{|Nf-(U; zM_gSmb?{pyqC9+r(of)hWGk&wIWs15J)&(&c3!o$W{n-OlC>-ZXFT3PQN`6ju_DV{ z9?DTBuR(*DF1+!Gii`(-Y{OE@o^i9054>n~tW64<6jt=s*loQNxv>>^cC&Gboa^8` z>6zi2Il=_^0p!?nqF@7k%Gre7j7b*;yz>lD^zCuuBbc&eLD?1anyZ;rGyOW=Y6&q=~>u;CHzPQ z`+@xQwX75j7d#MXMIgWHnkA-uv}!@%*r~-ZsaOy&`&Y(^9!5R5Y%3(>p3ez3 zQE)J!a-$4lITtppiYk~Dg+pl{!JQsErOfrgP9r_h3cN;V2ZJ)7S3MhHfj+@m9XFHXp&ScL5!$+#^knLu8cSG7U z@J~X_^C}m8q=^js_m`d><9Q~%d-+IVKI=!kcfOdPt4T5oRA4{TN4$?%r2^e6N)zl- zM=QC4DCiP%+lwfacob2|=adEn)km5s)fFr)vPXv(y=- z6blw?-XeQOW$XyTfK;=pG;kebxZDbni3|aY$bdZC{sz{#hBX1f3D$)ljR?MBy%ptc z&#O@oBa>+N%HdLts?_u+TPK`k0&`jvD8{K~rG7&ot{T9C)T|3DW`U(;15lKPCGw3y zWsD0H9F}En%wtNhKQamX%s4Ddn2XfQe@Q!Lacn7}Pg_ejYFpBsnBSX1q}NNUcoY1N zbPCd=n+Y__FJ&nWPeGetb3q@o&918|Wtl54GRsrh0pbifJ&?(Z{PW~gv?{PgcS6WC z$)vNq&=>OHYUMy;eMq9nTwZAh909*XDyq+caQ5){pv52)c%0TC$q;KgD{2_OTPjWD zopw*pZ|1)QZRyEDYWVV}c<#wCFfd_*UktvhA*Bpp$++M|?<%KdQG!!srih+imMN1` zCV1h%#HnbkS2r>cbjq|q)3~OjRkkMQF4d@V!8lL6JN5gi{Y;c#f-?^StMzUTX8pHMYc=$ zGApYQXoo53$smfUHl&}ADJ3|y>sPADZ!>(lnIPB@7w~X;a)+;YTDz0>qP?85_sNu@owlB920^w4;!gVOjYC zGf9U?b-vU5(h{dB;TzFv7UM$WDaVN5Qu^sdTt{a>N55?##m@`@WpR;&v+4nO{a6bhjuDsGfsO4N^3qS^$&sWVZETXs9A zo^G64L3FlyRhC}LU-9>Fr%W7othko5{}w(4Tq!=~EgPg8I&)>k+4DFyGAww;IZb+* z^ZU80u&}PTfd6_G7!mXCL&KaiLU5a&oG4l##aJUj%(X*j0NV|P%hd7|%eZLSIqq!9 z8diaLG8*zyo=ukGdicvY=SxprI(fQ(7i(d2?kM8tkTv|sp)}k+U~nn=jDkuDggx zjIx0En9*WItmTcMX#ryFr0tPU2lpcdGO5VGWo9VbqJ)ZzQ`7MYrBmlw>xwb@W5=V$ z#5mu0n90iU$+_N#G6Slt!KL?HRlDn^eNxuWc7z_t{`kBcR|NOCm<5$rVB>^@sk_qA zjDC^g;sZ1LSd-9b=lIcoUUkV6!{GNe z6K%5O>ceulPz0!sW{7L@3y=Odj}dQxr*pLWOI!97Rs9)a5!`@3XhpOO;=dh0!5wdQ6ob<1i8eU248O@}9tjnAva;)|p4l+f|D_wa zD=11$0byiezfOV^;3;;|RUj1?vpbXNG6oo=6W`?lIB<-M;n!UR@@K})oU;w_&BD)% ziH`=1Z&J4sX07E@MHsGdxerI?vfqITuFiKYV(;WEYPKS9)Mjoqlr74c(N3E8h1sUm z-R%S)S4K1IC@cGFR{qL!0&Xiju*zbKR{d|fxn!^s!bfZvwlAE-ig_Bmff6t|xzr?i`G|HRl4vm>G@oMJ@4 zktP6WvkAUvt}xX5D|@ibosZQww=)L!o(v6yr6Qf|dy}E?_r*f&#vPQxX;bML=!irU zDWWNqeQz{rZoMJ>SRA&e3T*DmCN6@ly+?Vu6CobL2kexk*+iM#kKsdMNQ*WeR2M`4 zm%^$MMHN-&NhOceU2UNpL32$z=dxEz`xhhuGNfomWpCittShW=8#{+rC+(#!t+iAm zQq92*SnSxLri^D%Bh1(wFbjq2hAJG#7AjfmdHG{{XO~5Xm)nz3MNN-Mmm58YH1`rL zHxZcMCr7jAyy1}b9Zp3ng;xfL-zpA%&v?s{)x`76fm)ZsnoXp)BzK$y7ILEqRuG@h zc?5mlM9{?U2II*T#Jv$1TckX70dD+V2WUk`wtkqykn9&yJxu|>-WEkWgmw;Z3*gKp zv+SR+nnIaCatlQ7LVfAl#j0#-0(~Kmcx$_2kG#IBE-qOp+|mVK$!?odk4S>V79XOZ za>4P7@~Q-#vxq$5h@!7APP~ed!&NfwZKhxfXBR zipd8!&%n=!*=-{-klEJ{$Oc(y^$ZTY-M1H#VvNk5g@vdUWlcu})gk6kfwr;$p)!xB z)#vp@07{YcTM!Z)Z(P%?K>QWvr-nG?alON@vWmRIdv-oB;3oKlSayx(q_f4Sqf-1tsQNSq)5 zW)ao-RAv}jgUpWAOB`_ow%y1){FS}qsY8@~neGik!ifZr1jegKbn_JrF$aG;_4xxe;YrAf0*s-fuGn~|6Jg54~KFOpJOUE z{v=mt;5VL_O3_E2=yf6GazTH0Vx`V=$9o(?z#;t;Cd*eTJ1c^r%PHW&`r}>U=NZ4t zmmQfCGuJ0M&N$d2+T79!mRud&sb^#-!j5)NU#RgW|cjmGIJV{-$?nfpuD-^=l%xa7xi=IfQi@yQiNnRMpCj9#hY>`5Bu z=DCK7;>pHs6zZwt2CQ%Skr=F8MW39Tp5KKv#;8=S7{4k53V;16zthc@o<7$*UV+4M zKX$L#d@>F3;Ab^>1FavaEE>iw@BIm{#FseloWi;v&}S;kE+_ubl;d(IPF(v> zLS_EAK;{^kH<;R$hdMt<|P{U@Tz^c;J0#wyyGmF;SXm9BW)*i6VXD3d#LEnKNr z*oIy$G`Ek*oy~n4T9hifyT5azDBo^U{Ag_g!I^wr&dVRVWq-Kge<2p2s}E@&<#|k$x*$SnIO$Oj>gT`=!I2QL2;`1B+r%tXs~O5S$u*3 z-uM=Z7HDY+;Wtb08Ulu1TgPYRC)(6eY2%P%ToYvV1xvMM+EP>1?D)&YBgTQuzL5?RIG3{mX}F}g7_X$U;LQC1(Tbl|bhC)t#t#xB6S zn*LGkPlvj%XH*Jzq?me1*FVL%JYamdg#E<;NuycM|hF^mq~THlgMBH?_(%CE9|IYe|9ZSb6+$=DyP5t7I^~d2(sTt z%*(Rv&jMP{m|!0>^6<~GPD;6jlbe?w96V+gj;qRJS+2rbeXz9D9k$p|tDiCoQh0gz z3He${jz>kJr4v*i&e>iT(JS1V%C<{~9zs=tIpO+TD^dDM_|2BOnyw>D#{0QzuDvMs zKv1@uduWpRW3|zGC*1tG6`6B=aWuQ zAQKxJ2QK+>L|WiyjUM;*!!{^w+%D4WSZ7o2e?_-oP52bovi)I7!gG;CR1kL<9xCl7 zM#fD};Z>28Z3WE=_nxh*gh?41=HonK`4v87n)JzZUFv#bIL%ydl~rFwVy-2A*&3I& z+6n-6{$|P8i6=If)r_K(r4=X*-nDY?nj_jQ@gJO(hFJ5Zbo!S)i@3a#3EVqjoWrdS zI?JPXC5t?3w+3D1pS@sgOv0NHZd#XDmV=p!t(q*xI3y5U6KamsI|_04+BbxPmf1;4xr_f@!JNpn;!Nz z(ly;XY&BZzBgi03S+d#@F9W{{jy;7!{)rjY;R7)esxO63BCYf(uirYFh|gr%jZWp- zojD);Xj$BmDL$E`4M}x}Rujm1lkRzQ>!^wbtN4=ckCA;hA8Sz$G+rQn4{q6M)f~2p zr9Zb|R1hgcBdQNSFlqi4qcBe*_16RMv7xHC@^7kg$Q=ACqexh&ck7ER1n>Y$;uh`^ zNYUptp>PeIIDK(0CNC%_>b{BaDpXh3_AaRYCWBYvlEV6NkcFs;ca4lg$|&bciQjFb zkGEZ23H|fjUEeyNcN={YbWh1ekv+QWX5F+E5%a8wBRS^m?2xm3lx`lBg2^AU6;lV< z;ae~Kj?ecEpM&yG&Q+jrc7eu_X*9+YBpFvZYayZr2WxTN=x)98+yL&i~$EBGp9!ddG3q0vjKnwMf*K9!e4yt$|BRk6sO zS)uwovtSLRaA%MqwFMy83{|`JiK50-o5fxc`k|Y$4*MZFVA(wC3@v_yB48$~ z(1Lwl9d4}*jQKZyur6G1@%aS&18mG-T!Vs2h4LIEZXkueb=usltp2E*-R7I99H&uW z6b-#Uwthi`+>}ApUk75g2b{J$lsulwEd(Gni837}6&=w&v@@l>Ez1JiE2Z zCJ!`}2)8O(?mWvvapg3g`^o}I=bd;e{obh;2Dbng@01H8)#X;7>8tq?^E`km8hPeZ z9}ZcyG5~Bz%`XLURC(v}lvde+h5T;=Z23gFsWSP8JdO&llBkm8g@se+(_hJ=T32b+ zR!)F&4b8K8`6VOA^m6Hqoz=oiTdlIqy|5B@Vt^f%6$!5Z4m*}qQYE&8%_lPfyg&c{b2C`Vh^%s}T4FY?FHgd9m@st$+_AU+Vm>NA^=}7j zQ7c0&^{8AVi+Hra$zez=;LVi`gq`2G_q0O6YB`*f(I9*v=$KkWPdww|*(%i(oRl`f zyd-mOSTLedBR!dncSwfqI3w!dJc?5ySEq1QcH=d0^(mY8Z&32YE2q>B;(0OMSfdt* ze=$F230}GbE6yYj7B29?DRuQ-kIoPMizSZD`vkG9edImWp8jzaDLwl(J$7++y~Qg2 z^cF2WeWQ<3ao6R&NyP0FDt)%WTzt}##o*TW>Agw*+WphB<`C2E7=t=U0NxYKs~G!N za*^w^?M4-CuAu{MWzT~np;vtx+Jk(_BRRu@KHar=z;Jwn5Vz#m{7-6?_y!Trq{VV$ zlY9MkauwIdrJqro9oVdH@}~}mrmtJwqLy z`LZ_7oz(}Z-7F5oQ$a3r2Hh7pI<+&;Xx{$^Im~LkP`lu};d}NyXurq5wN6tuHFUPI zwsZI|qIP6N2UIT~LV)o{cqqBWIrY!ln`_LU_=#fEpAqHaY&3^7@*d34xZS}>Q_E`X zW8E-g9#cynzQ9oze`6zYA4W4eLt$P*g~sqmL~ARb|>z zr5mK1b9$3z!}{T;QTJnqqky79gL$ms)Yo+kRfcW^0eZ9-7spr(UBYm#9y?v-z0N(` z{m@@J-0RRUEzEDJyb67NBwo?uCKoxu6;A?XJI_YQCUi%s>ev%|&r$2dp9Vs> z%;9Sg%I(}mBepDs#8rlmR+~jB?LC=4LC1iBy1yC z?13|wV2)CwKMvVG689}ZfthSPUe!jA`Cfh8R7-V`Q-NvdcHt5+{&jMjOdTM_Kum!KZ0Vt&xHA(ft?FfTF;Q^g%s;LN!#vo!qf|qo<3$m zZBK{iDc3XL;3ilQPvz}&eE2o?_~j8D$r3lS%R;@)Lc8{tcCGU^oUbmn6Ep)awHVrI zE>N?iwhEp7^u}#!mEn{EkJl~2Kbg#bSE~zL<`>@H$1a=^pAqYV8#1^q6U9KW8;ct{ z2+EOw5A$RWL3AYeJE+BlOeePpUzrIoL_1jXdF2(5%EWO=&1S^;8W^F+jxQq%F?Qt` zyP|_<;XN_}BeqNDS4FVxwnXbU{DR6fX>$fl8|Xs^$!9OD_Ovm9^w z>ztJxk?u9Ce^9s#Dva0KIcO{UT9&L$oktmd1CjXx@v={6jt6y_-PjG_DB_no6G*@r! zZ|+A|-rjFGK4G|o5PAZGz)}(^ai;X-dr&-awa_PYMTX;llzSJPglwb-u@4P3hx~Fz zLUw{wHxq0m`KW?yH3o4!sAMjoYTWhSI#W#bRFP)uesGe4(deoTdhHXV5FNw(kt>pl zUn3W^$G)Ui2PAvEv#nr6XK+RLvPV?hLcpuW9mJ^!jh!aLvHSJ$|QTkp~JCw=I z3r$iDM#b7Mb4*Oe%nqgnb=878)@&IYP?VsK`N>>~~ z%PksfeB)@acQP^eEgYRrfTzNclZ=-;0;z&RtT?KSFnYH?FJMVlE{N-coRWFBB1r$T ztK*lfoNrzmm*Mk+>D?$R2rbsBU9y4nk;*be45&xxd#rgtagh`Zza!64+o%-Njoc}Z zOy1gR5lP7s&c<}he=BOEV2eiVxP()Px#Vo)!+=uKk?*=*TB<{Zx%AsuV5La=loRl` zRCWgu_5kF1%L14|qi=+INS~E@jP;(ebz&AZewA(I%>I<`~R0eza zwN(voQPv(Zl&_>ZTPj!^+39GzS)@Dxvi{H?8^6C=riD%Pgcu4e824uaV;Jsy4%xU^Yz z>Q%Bl6k}CBr71Z`ft7PUPBY25<9DrCAcp3>Y$Omj<82Mw}S%FM-AX*UorB0jGW zN=}n~Tf+!IV2h`bV+pbO^26(eZ2o2el0htFgYFWzUgQwq1<*OUycL^2_pycQhJ=46 zkg8sP36@yi&&wptJi<65b@?RL>Kk3tik-9X_muQ&6L{dyqrZa08XuoPcZd*?4|@e- z_uKb-Ch^+Royd-v&$pj0Ry_?>t%P?<$~MMx*Y<2joM{!EMq^F zf1*Dm_Xt}Y$B98vuOT5b|YK0%@X&kcRD)47h3WE$=fP04ZItv{nhd0(EQtO*O zFyiPyoIjJitR>={7m-zF){#ZaLnIrS4}#o~)z2g4T6S;MtBR@ww(!}<7(zQ^ zq`Kxy*{^c1aKyZ9FQ6M8$R z*d;~V-k&X^+xx!~IJ9pmjcH0d|F&-_je~DX1=9aL2rHTx8afC&8Cp5~GyEndjLEF= zp#*)2pRdy;D?kvXC_q^v+uM#g@+ZPlDN(kznWgDm{1qIO^ED>^wEh zf3H@Y4H-9PE z;VA*0WO>P|)vVw2ROSpHu*Ce$mY_oke#7K>*SSq=Nz`xcXj#8uVrONdM+q9#7t=|} zs-{R9?bFbYFaY-l{f43!NTT1eCwwX4qt^Teg3N+-N=27r(=yZAioVRVeq4f%Inef` zySMCMjw)TWi+@#mK+egAb%lKW$wdrx$`#1$QXgW_e1tnjp z5XBs8JQj^`I0EkaYz9}BGaNn|r#E08|8u~D?RbDluEwW{oeQZ=9T|%i0%Jf|5B#*4u)3$DIen* z&HoM7V1&KRE=)iXS+)6uSSNus&&sy*w!JL!EisE$W!%}&e|HOp&IvRNctMQpk-m87 zSOXz3`i6EZ;Sr6G1y4vK*B|!VNi19B6U8Soke_i-T5FCN=W7nL={F4}MRK3h1kll> zQ|u^KrPiDW%WG?}XkI`sQ1rfL&vbv2KdBoToLxK7E@67hteIJs>U7w;fql2xBi9M{ zkv$^XpnS)E_rw3!eE%Vx6S?KYG5jr?lkjaFMfGpyYhh|&Xs2Z2XsIWzZ*BF@KYgY0 znmsZA`?G1qU@j&}AxAYwH9;~Bg#ggrpc=?Btk+ve9*CmeCcXGL@6c?(O6>@Sfr%~Z zX*&pB48zECTgC{dWNdIhg87B^1vYe*0ZZRd+UGxaxpL*q-u1?w&inOwK<>j72DTZU zi&K1HCqhG5Y0_r`gP9Sz1CkNm)9(s`I~XHO6Qr!U92DMSuwCa%533#&U7Bmz@5r@f z_YPUE*(k^a2TPqQiDasTnV2I?gMTY39qIrZtJsV9Srb$$afkZ@kd zdgW!IGRsg}#kR^wgl1p9PPy4$nnUM4hfkaHxhP0HZx2k?KcbLa)Tn<4f zAmFx9D_)UX-ejz(t;^pp&6z&Td@f_bWGFMLMX!@^5w~k{ynJ2-7!_SF+he5MiIlvs zw-WX^<>&-x8#2U?>rXnJhaIf3@3=acfyD+O%?i#_C!4|OPd*YGaAWmi+M*|G4mrK& zb{fT=30#D@l+BLsvlrg+gBX10i3O>EAiVZDVI3;Q0oBb)<*-LJ{PZ?+!KbLP4XVCD zvfbtI0?nw=166GDd#vFh`Y1{;lHHatb1*1dsa+1NX(ApF*4>m|2W(v3K_Ap1sv>4= z*V@wA>9#<PP4G1h2meVmRPlb5$?{zLT}IyIgvTIR zdjw&$p7;dvLLPP=cC?LJUr+xXvVD-fdYz;`%(61Yx#yHOMU4hiu@%J}rGXI%HI?bv+*2^cOCJE-|XfBU^lq{`y%-obK zoQsU{huNV$iq-7*XPypuTl_oZPVvl@EngEMWvLtm3f&T-TJTMXe2fx-=Qg~B3LiP# z{sHBC1g6y=kt}*bSgAeCIf%!DuZc71C|sM=>}C2W-K>wcUML;I^(EC6aj%H#c+Nnq zltC^d8)P)A{1UV2vGrB8rTDU_@lxeTo>d4Jj*Bi-gDOwqXk7{1qD4d;nUAPNW~m}C z!Lyvr`k?sIp^(ZQx#mxdH7^m(zF(_;^Y+m(aB=t?*amzJw97MS2GSx_Vu>a(VDL;K zIu6EP@DHsKH{HPY5vq7mpudM?Q%qCqgdaC`d6QLf;g4#@bx0`5{v-naPT)9`b%bj? z!#vsG>g?KkgwtLF>6E8!76UVi=$rpSGLfY*gl3pN1?{ z%I*uQ^A4=?;_=1=-QY|mW{5@Bj!A93f&Xhn?4J|~lK#$s;J=|L)Bhe3l?+`R9PJDR ztu3tWhydaWhW6HucKU|@jEtFaYgTi72tmfkq%x7Y4KWEZSvlkdxdwl?tH{uW1nN*I z@JtaPh*(BQ=shSmL*lWcjg7xPx;93F;amR$)bY zu^RDD&fcmA!@EAUIeEQg@zzAgz!{SqW{Ey1p*Gk>2m{8VraXUKsQub+RTySOBdUtWvM?tsK!@W4} z-}&CeJ5Q6?RWN88IWol(g%-(NVcl^4v#npFe~xI;=t>aZ5`sxv#6KsIk-awaZ}ros zT5FO{7N0O%fJru)!6aP>!=DEPbsKEwgRps2Ef>+cdGwO}!!f9}JYhiD0whxadZ<+2 zLYtFS-GF<%YP;P9a1dM{h5Dw>S|82D3&_jeQYZ7l*7?eS&wY`VUqzdS|wN?PH|Lc&Qd#Fl6AiiW=Mkk{Fb5zf&lu*hTXo& z_3`U_!=C=Gu>Kp>oBzH%|D!^ZX!-5$h%oeJY%qovR+}5s$|nIKr&f?M+hE$03tUWO zwGrSGpTI*fu3N5Opp>NXEaI6uSwKHG?(kYh`PZf57aEqL6D2P%7q^+o z|1$1~Z@}sKGW2(PCWg|atYBj<1XiR;ja#N)oeiQ6p`Pe>A0Vyc@{5^(E&(nM-*Fs!4 zYt8At$eG2!TigJXAlJS1_O7ZgwX_-7r9yVc=bQ8Kd+f#cmsF|jrsv?Ju<&PQBjf32%K0G zIkcAAB8(tiWa>yu228oqv1swDOs1Z3bjV0ero6U@vIs$maIcdLMzOt)BQ1z7A~4i? zCWwO2m;&z6Ov1AfF^f6Ih=e$Y`iBX;IS!$wf9;~`D7KLfW##4&nQ`R*d8s1>X2w zA^$#L*@^SKCGDNo; zA|X18R}YL!R*FEeE|X3^JNXgvuRpqv5Tygpk|rAL2gI+_>xe78YbdsX%jLs)0mAE%qZx(Do_q)B+5==e1k8Iu>$-@zfuOVsu|hq_ z4qf7b3d66Z`&3B624cJl4t&9}|J_s(`8&WsllIZ%eTSRL@9}RC!GAVyoJgV+`ZtlOCPb ztU$iZ(Of@p?=Iq!=C04)jPY>)%z;BP> zY3r)sp8tV;BqFGnFQCJauM zrCN1D-CUHVvV=i}vdW6k#42Pthm|%x8pblVV7gj5U04*Cn(-pscWIV-q{D16D!p)E z@aVeUXu#o-@u!>fINi^o3ea23bUMnx`CEm}8rkEQIzBzr``ZYsbPrm1|H(Wx{bde$ z)$vs~!yd9Fw8}hPV_KTC`{Yb|^D(y-=?tGCvbBX5V)rGI@508g!Ve|4qvIiXkSIW5 zis5La&5^JI41T(C--X@%o)eWQc8J!VQ4LvDP}rqb;c^Q$&FI>h`;t(IE#(}(i7I3SMNNCc-wo%WeUsnjjzx$|y_P@lIV`Ey zK=s%62PB@6F}DXPSoEOb}Y7Dx#qR}2<+PZzQ8p!wSm zK3^ff)~{X-WZ>8ZDcLPiT+aM6U&_SK3y){?Tz){Qvo+qwHD3P;ZIrC)Z&G#NPfI!@ zsco9^EMp(3Y)B`RjadAB!IH8#qaez62C;}Z>m};K!q>GXcN+3ez-2+0DiE@7521&i zw;ay)7{3LwEK^)|2HmmDPw5{N5y41yIk&8))Hj zoUo`STHaI}Rk8>WO-~|fKm7nA6_-KmCJfmji(@0%J-6j{u~nE4+V~+F=2okbBPK8C zM2OdrSpW*E+eQ>-E`;$EYbBw2G+1R&!>(WK5ix-zYR|)G3NM#76$q4Y*oO~P_!0oY zXUao@H2oX$8287##MyNpkm(4*5jEyvKQU^LrU9z`T0s6BPmVFfu^I=js3V(f@g0UA zjZe0%zgu@O_jcd!YhC!~nxB)6{JTs<4IKr6fsZhzVbeik;UPb<9KS>uc%Ea>JjFCx zMh-kjP|4DEQihGb*-z^*NxOcIOYmi zsc_3En9qc_1DPxv`LO@?e@;JJtJI&_cKeF{+x43 znmzcb^F-Dn13%>@;R&r>NNNl+@aO(2hkp?N6kA43VC-3a4{dSFe~*U)_xV}cWfFOo z-I@LLFAM}kSkg&b;QmJx4^otyCh}A)0gmm2@W@>(japEJ>xlBJK?io8%IQTxvn02O zo7Ac8?4H$26_3J8(Z=n-n-Mt>?M}OjpzY%18QT@ALdJj#{ZWTmSUp?y@%w39R8HnT z>HVs=#8)U!zMhAS|0n1~U-Es1x3J+yns$rz$|Zwe+G98S1DarYexrNJ&XUqaGw99 z+jAEe`U;r(0@K&TgNFar5QvQsP?%Au#b;$UrO+3&P<%Cq@c_aNZ21}V&BJf1aCW}R z+Io9;`vL-j66L{uwh{Zo8n*I`FLf0+1_|5?aZgYgaWFdB;*b}($M*-Jkadpcs0 zHH>e#HwIOSdqOpJ2P)<#L$aP&4(CkOcs~GN{`T28d%fQyKl8wze3J72A?=-mYjKcm z;hfkuPi)(^%@f-;PHfvwPHfw@ZQD*>elvHzH#6URRqx)Z+JEewovPGMcdy#ry;d(& z-=CVZabd;yTzvf?tT!cGN`jzD0K^=1z3D*V6`2GS`g=R?1Pi{>wJoR{fkX z>mXH;HQl%Xo!rY+NEb^TJ^$oK_g5!Ua9Qmg@ZBhHe0L*^|My1u|NsB}-xI_{g1z~q+1^fXt0!~!nqy)`KFA$pHm$XP}e9Ng>Eh3|AekI_>xQhO(>H~jsE zGnJdM&$ttAo32-B-y-Diy@1NR0Q<7uU5)h|h4(4{=@#wsOYf

l=ktoKngDcq=FiT7^>9E9?${w`xr_DAf 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®5>v-4 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

=Qsr+4Tb8>RZ4EVs8BXHIDM8`IOBgw1X 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

{U-M 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

KBE6?+I})WJt>y;8svtK; zW1nHe_zL#`u*_QzBr+V7^l&1{$?)@$B1W}tjabrUUh08@;x@SLH$?6n^fqwLn7rnT z_Ot8R`}F6QBtsI*?wOZH@-J?wxPk*UIfjbv+3Wc#vgF4&>pzOG&orE;8-O*Zi{QVZ zPscFV3m=VHfpauIH;fU(^3HOL3X;jR=qQVRidCX;^ z3F={=>d@jyqu7jRTNhR4P3Js%a_c8$vsf`3QHL_Peaj-y@8{KAV5QgVZB^fLCNQ(M z*KyuUmUJ1iT<Uq9 zESl##skC5YAZbVG4ytrvu0q<{;-*q?x*TOT;iJr<8U|Cz0K1=-1vIPS|JsAJ4p{;T z9j2ctTPlEI#m$<^bXl|D1kY>dU#FbFJJ2p(eSrUBoni;3Ng5upFMV1ZzH5ToLFACc zdx>8H!9g{V&3^EWxk=nfL^k|~H|x6G_Y=6p_+>!eV_Tfu=R-W6k<;2rNW zf)UHHg9zGEC!OQGts8okQpm}yITMLyl7$j5Tqc~eRx)?yyXOa_g>Z3Vs5x4{=CJ5K z3Hb_0CVgfe&~p;0_>FkeI%fm2pKUu7PwmPIQpKn`4!Z6UHf+I{&0a>mLg?-pld3sWB1W3{cX zTg{~Qj+}5Eh#~j^ozFvVeb8kWp#~XS1L3yOO)Hejws}=9cdO1p6Dn0#Y#rLX>i7qyNSFJqBEee&4)1s4 z!*l`_1(==t8S;bvN&u{&?3?fMku6q-bwZ+^tvKJak@21{RX_fe+gs-C12bTed6ol;=wHXoxc%N~!0JNaZapsM<{`(IK%H|^F>+uV z*)gx(F(>)k5gFgF8KT@sBm}uEV-8mF*0Z@Zy$NNwL7eu{*z7?L_Ky1#Y#m)lZkQ69 zQ%%3VH)RU4-G?*l&R7;P>0=*S{ybnRv^pzPv5qi6c`Iz`tYCI;X_)9i9?XIDF$nK=fw@k z+n8=gfIPegd1Pa^jHilY&Q9y%&P%-G!2O%!fJ?@}eV`-Y)Z_b~kp_$8&#;cp@W@#$ z1vtCB5-)j2-H3EBgT$S7tf6WoBM}@nD>$ojW;!X(kl+WbX}Ux65oU$iU93J5E4auC zX1bce>Uo?#7WRAqk^EKjpW(?>h<(K#S<#)|v}uiHy#tYZ*d zi!i@P`j(U$W!N)AbYhD;3QQ_hnS@%-u&h~!4T?KBNOjeIQQ&6aHKtc6)YH@;+~*Mn zzNkVPc+fD4A?P|c#$~|lea)LFQ+=huqf2;3?1@lq)~%8uS2!cuQZF|@V{0s=3{Vd5 zE>!^`okQWus5qC@XGi9uPY|-u1lg=!gZC|Ip>ibT&<%p!I(DH#bA?(YA=sok4Geih zg3y^h8n--2LFcGzC005a*EKWYB=oF#`CY!A;-lhPtzt(!zb6$CO_noYHXF7bg{S3EZg&j{IjY}zKTzd*(~MC zCFR;G<;pF^Ad|2ornb$gEX~j;#c&)b4Y;)cm$T6~QqUO8-BA&t$3>JqYRHV#J$11r zITJX4@ zKyr=#q<`6BI^g!s5Dz!HWdbkS<`;v3EFGPMJ#=Jt_#R6mf|1CenxPD! z#x%;q*qVQ^odshcS$=S`8$S}kcS+7|^JyYf*7-d8$l?x5D8~a~G3SF3=EaQ^qZmZz zs$!i9$w>ViqDu|`2&_*u=Z`u*6+8q&Z&S(Q5wRv$@%GfN4U{K8JYx5Pz@3@tLpBi^ zcvb$^#MjEw)MPp7QCi^o%xtSR(@7cNpc;4)KR|r)qnXle#J^7kkXzGMavzeEALe2D z0<+a+*b}!Y^m^j%2?Il607L~QW8fuVOwZVO8I6aKptO)MC8txOV!t;>Rj33ufA6gt zS@I+gizIu~#kNuoY!1r^X4V<}PUdSqXrnFzO)|NXK!ia|fAZ<5cuxJzn@#>nEi3^= ziK6h2xw%vq>oRR!1l3924^HhiTsf+%i_lZ5=1yT)^;6-F?ojN^5Z>;*^W&d}8oD+I zN(3_@<*hF3ny-oh|r(p2QP@WI@VY`N4CrZO6N!v&ap)9W8GWzPdA$rla z3+&bDI*?XN_x2R83}j2P)hX*Cp6*2z`*k^p(%+dDyY&}|jm$(4c(qOr6@K(^)XGBX zVUL@oF^ga6*hcO;Hj0JsI#OdX7$tHssP7;x?Q%oaLH4Xilo|wj@h9#XRzUhJq=p|{ zSUR$_f8BjZwnSC>hNY~tRrTQTZ94MmDX4SRpp6dx1^QY@*x!CUmJo(4CWJmzu_rxu zHHX9esaMRc8?GMpLyOpd0CNkkdU&mxGkMpFsuey2JUaJM*q~68_r3h~_Eu)mR)%4d zRk0?(hmhO>5$jAh9m`7}>=ii5P*6m|ic!Yw)!uO})chh8BIJ~qqw6<6)SqmJ%^;Tx zqc0~LR}zxB95E7n{}v>JL*hVg^G)^YTV_)s?z1?#)U4li`&ZfYp^)S++JmVDcwl(O ztND0vPsEy@sTiQ!2(AI?7^J^L@f|gz0?U@n2G*RS} zqiPu~BzO#76g5cHz2r@K@8DK)%w`byL+w9d&Zl9`#e5@OkI1=FIzS?q%Ai)Pir=b4 zNxeXGyipnS?fe4pYsR5+Xd6ZW5m6*`nZHi z3o=W#k@{`)f#;1-jjJU8xxtSbp<);1gNn)R1dA>K^K}XDjJZ~e3p0w8Wus$nm4cLf z%m22%2;P*GXs{O(FRCs;;Oz~Ps{$|T4xiplxm<+e3}z8swB&jpu}pqM;HVNHO)r5t zNsO7CzD(xO;<7tOUc+vhBOA5cpM1{AvTA4CxH)Xy6}#+9TK6tq_$D5$6GGcQGEBV} zfQo1+4@2p6b}q25m2ST*2w=7{mc&#G+klZk1iJ6f%=;FRx;lj!w&_=ou77e5PnbOTUc09<=|UI<0B7_Q=UI0 zD?=-a{AuvSD}1)?)lWbVom)a{^)s) zevjd!O(~vG7d;j09k3I31Z%UO*|@%38qcDFsb|c~emyr*}+8zCT5zRg)u51}U9Jf)C4Ib)Rvr-7B0RV2U5aqmKI+YLs!s3MJbZO6sq z;zW8E6dS76DkB@bYnfdz@3=jdFgZ%3VGfLFp6^uv=(9cPr#C_V}*GrYCiAjP>U;T zo7na{!(tCR@^xc8Sq;fXErYvf?UdBX0YT&g24}C@N&wiqQ7NctKV2KTckb5| zbwL|h$3X5jVx;kz-gq(kX#H#+&SYFR+t3pbl0)bNHP@agSm$3wu)d1^UhND|`?g1V znrg<08169bI#=V9+G}!rEpwk9hlgz;Yf$V3!ZzPA_cnlxWLQLJ6-U%nLcVO_u`9(- z!QXtYZv8|AJ~7d55cRP>p`@Pu^hrLk3U5DqEkB^^ujCa?vw9FdxU~amXV?RK@RQvT z7guSW-G4l7OCtN5i6OMp!MzBo7VuRG8L#TIw4o~&MUP^ic{v8_Mr%#1?ui$G7uKxq zix;3w)^XBYuHal%b`W)1F@{}AQNxr!LvpvV4ToYb<8!s~DL_qanI>>#_iagX?|PdD zBi6Ms748=Eo|i4T@^}r|rBFYb+5K+gjN&&l+e@p_!w*4sDF&IM48WD4tsD;ZKSF%} z28wGGKW`N+F^kI+2ISfSUQ*dO={Y$&kRd5U>$m^ViMUD z@vcB0rg|o!)Smv~EK)OeHjv{h;H^ktsEKXg8 zyCJoIfVO8W0Egznq)qqJ!7v;&OzL&ZdlPfaR19a?{7k^L%hDZV`O_I5_iSJ{^1b7| zd6)CO!=sDjK4d zs`qWC>^CF5H_(HN$fw+J-kop7HqhB67&FgECiganKe47keOM3K3#P|C|=Yx>f{f~hFwz5%DGwyoy*M55p#+UQg5<_rCci=tz!MmcO^9I=cGK; z!J^8u9yA?OX4i@RHq@0dM3cb3xG)_DJeY*i5&QbV&5K=oztzB+M#36|H$yE(L>iPe zqcLD4^)&1_F40&1Z0m2@@^wIW4lmngc7W$2t_(UHunjeP&5eGHgt0^9tFnc2+O}{F zd;j6th^SFUuV-c(uF(tjUbU#WvAL(1IahQ)>u|VXN$B&SdMX@Ea&)iAP|-o4K{WT; zcd`Ps#SXbrMQzfC?{^y1IZF~sxS}8{@hJeniKC?lAebxs!3q4}EB8Aovpmo86a3)0n$eKSCB-~L1ph0@gX!+}=@)2-Xk0kb~5Z5!m; zr&(zYG-F41K9K*)|B0B7-WSX+tmCS43Gx%=k+o`RDxx1)jiPl4>l!GHfxsBHpBMu} z(DZy~d+#1f`o~Hjv&jQf;W)wIeCgz5ewS9hY6ko4=6kH(P$Es2Em|5QXO95ZnCX~o zHNxDodkgeKp1L9(XAdymp}|8jiwtII$2yb^P36v~_Ky!Rv~BIrKk!KXQ;=;vZGgFu z?M+x-LBBStmO6l!^fi@jieF&lvQgOlt^$!SjMxqoS|la@t^QAbMDgmZ>Y;oy#c_fp z(%T+~vm#3ZzMdGWOo9HI-$hP59?yV|amU?HJ`Kj{0{l_N=@BF!D)<=*fDd>l=|PVp z=2{rFU4S+5UeAN@lYH-=MR>xzUA-;(xFNx#TS{<&KpxaCuqtlVq93^3<%_K^BfrO*vWDdN@O%SJ04mRjNuGv*<_pdtAcpTsqVn*}?lcYN@wO zew0`^!MccYW7(fX-lazhV;%6$hm=MJFl~Jvo$4Mp+uql){T8qc3=Kp}b4vFZ%glJcqSraRd^Sz1E?47omB)FemQAw`t?Q1zvVTGS$HfliTAN}c2f3$*0C+QzI#|l7Yt)AD1@Db8eY@-<; zeM6`xW>UaK5N$waQo@DaU!f|V6&Gz#10JidX{@1B{c*&!7(?vGL396~UoZ)lTxyDo zN59+?I6TlXtdy#|8?KLL^z|F=q!Nf_+EbWQfP(5v?Atlu#Vsg>gE>GOOgZMwownI* zGNVV#al@q`DXgqz7MGICYnU~RjA{o5jiaMSaBu zif34HH)al5m9(U?lj$uECPplNohZQJ4Hz8Nl|Z+B8s8oQ&(WW+N7&|qydKSFxJ@+` zR^f&B<7t!H11hchMg}B0MW!(VCA7eRZJ75grE|V(g=i`x<~8gyDQW=&8WNb$Z_O-< zB;yZ=lSq#pBl&;jjrQ>`XtU3X;}(doD)MG@bo)kAfp4i;w1Br-k1gBT%M1H)d}w*y z6%})8_`vYj7hSEx5d69YQn|pZM{-;av)uCjzB+W#@asg?h_N;aZT&czV&sl1c5wxt z!RH0_IBDTx7d=fAzp%uY&;!URwDnW2pnXKRh0+bpOZ8kt&!|f|o_F5VpxLKy4ZKCU z;+rDoQxQ5sOM^rx1)Y|n{b8^EIbUcK)7pi5b1UpfuyE;a&+k6nq~7VJ%Vom(e7wlB zIkDNq+8c%g1He1@2W7T=Kv#M9pMmxaq=N-uFI~BMwwWf}(a|sW)g%J&4gKyfOY%2x zO-xue=el$`u7DGrCFz9tL*^B+;$+OAN}ZV9Hk6{vrW}Pfj6sV(J#6QmKMK~th|f)z z%GYh>H${GoZ74JeYgvOeE&*I4`7N5N1#3AA!WzG$FBn^ADDBgq(W{YDo@2D2Ka3=M zZ0CrkcT9ZzgovsUtaC&2Jgw$f;E{oJ7s+;W{*4XbKY|rd**Z3D5o_C)TXB(j$Yp&9 zaM1u}!j1C^UskdikG6_Fm~n`4s}smjDEByjB8u`-S-aAF2G3MI(HPQQ%hZvO>`&l( z3<1T;nLRZrS=(gWQhV~$D5@$aZQ@K0my~x@r<|(mpcEpsW5(OXM+n|PW*XOmxoyug z2yenW=|Hz{b)#c*rzJkA2*j{scXp@jk-Ic*Uf~75c*ul8^e9>uH^TB(-v~!44YgUu zOEjyL8Qf5<<)&NbCpP-^J!l2;!pJW+6gB;$i;dmF)d)XMEtpSk5pzuRk+=AKxg^KIJFu;!$R$$8EK9K;p&Y_P?Puf9cy5J^(zKSJ5G%{@vgN=xkMdhN;PdMdo zZaFV$p>MOcM_o-9NMPzYt?+zMLwva^qd~Y%hlE6Qb?1eca1Zhij45eT0@;FM3VzbL zb$)e-s)&W!(?-D7J@9X z3XVK2%Z^cU)TP8>3XJMF>xWDPPeV=R4SzfYa(|q%<57Bdz$!2kW)9lJ9S3$UW5)<1 z^fB+8ns^vLjH<@H8)GMQn8ushagEj<8ahAxi1)JzF_L+R6dCw)3K~5@km;}tD1P&V zR2>+ib)+oA^&nH92X8qZNeMOJA66VszvI}3Zs%D?=zX%}4GXsj7-KrP>s~Pa^`3ur zxU_dBDKp|rL}}VZAUBcC6=02SruiWLwM$ZFiXaF3llG^nsU41)iM*lf15`#je>nFt zAUW;bJ2mOOymBI&{=>RqKmH6kHH$yI^-NgzH~%o~r#cbiC_&D^GT=uX|FHC@Iu!k@ z9&+UrLDT-%rq~W)ofLk|qOaet`e1cf)mD#^?Ch1M;g#y0}fHINK zW%fdmUDj&0e;^~#(4)9^Y3E*l_@2Lc<2UnQ?(+aAR!8X|u8Hc0q*Nu{RUab0R+ zOIbtgg;KE$2>Uw!%h1rwL^|-c8E$nMC>!z>L`{_c^cTDQfE`j7?G-Q5(kJNuX(%B* zjkh27<#Z(b<#Z(eUp^mTYGG|+WNv5YWa7vuWnkuF;3)pJMcKp2*~CW8!o-b?`QM)u zC{VF+LRCfcwT&~Kb75u^@(*ku&Xt7Gh|nC+*9-$kjmyoCM!g<8e<)n8U5;+!Z0E`& zeA_~_-{ZW(#tY~{emjT~9KBwX4S~RU*Jn+8b-ZwzQ1V?Vdl)y|7Ja^**x zi$?dY;`iZXg?y}TeHDIrF!ZF*9HOy(odd&3)QS1*uAYJ)Wi0(pG%ZWr23(4pJ5A3z zwC%g@X=W)P*t%*Lc417QX=YS&*i7-}Y)J-j;n{EYrm+qt)okMxpKUqry^Q~LIj->K0S z?3(@(X8?DQ#cRjTZ!yLt9Fys-2P@=MCTxU{$Yuz&nnL582>SB}c6}~3xgw54sG!B` zAoPvAm-NYK)mm!M-o%^xKVXHuiEc@VeTrIQEP3hURFqC_LU6387cvMs#WtM5)=PikQJ7rH^;U zwq`>e`7-Z?Jgn=K5Vh1TK342ojh0zq)>t>PD`!*tZnFgsX(|mEa?_7&u=lDX#htm& zO!JK5pBi{M?~0lU7FBef+t5D@F4X%8#FLxMWl$iBx3Hp@iD8DWUD3n{2aLJEovh&4wm1j@km}R4o{AH8+79x{&@MS*Ww|^EHiX4D~EN6tgxx3o@x{mb9*G- z&R&Wb0r(1I+$UZ|eDR}%$e=w1&eV=E8I3Ay9Ofs`|Jmyo_lE@dV1R(aF@S)+{nNev zfA)EGXm30d^iRKKBhw;))$BA1vIrwb=(<1p??jO_q`0_{-ogrL#q9iJ_q$j1tI+Lul{3c!e|=*#QO?u1+Wqu-_1rO&0$ z>(d+}KOE73oMJWMWs-g5Pc8KMEe>$xwMu;?x9`o$gE}x|Ynk1qYxKLIZ(hGd_H+e! zh_-`ZPOc5WA+M3a2?u<dpoN1fKfc(VL|%-{zb5390B+x zS^ae5AV;8P&p@!fr-<<60B&^!-FYo3ConKlgr44Ql$;4Y?(9OhKe(=%cO=$4T5cB)sFO#=# zgYqVP)VpRZz6`sVEWRTKF_KRSKlNDWV>E(qins4HgVPOI=i$$0hwkDn3OpwQYZ9>{ zLfVFE-Q-z^HLU7YT%Q$O2J!!3ty3VGnEuNGN&pr!~*;`RD96{iX`I@uV@P^t7_x5sqGZdB(Znk@`@>r=z;)(ui4tx&55GI> zglJd%6Bb}somcmq{FqM;WLeI30;~m0P6yHz?Qa&DGWJ($ zBL@mg;J5zASKVcWbCk0`Z=Jx=DRjiHsZa7qTv@q)yV~5qhSwRubROH^eowjxm`|Pj zUGWRMaTna(5fF09-)23h^HV>K!9qV!3$!$JE|byY}$R~h&jF7CQ*Bi zCXTsB%`b7PY*$ty^=rWmYaZQttjXf7tkbNgYCo5}zMUsN-F1(;-$qBJGmJX6J!#4s|X`)|mdFE0kM}!^3aEBKKtmdIi zOi=0XvHCn)kR}(J)rqjwC=U7i%Wo9w9?y<>&{weP*L2IY$8~Bst-^qyCmDFoTdjMl zh--57N?cW78{!&AT^Fz9JS`hUs#B#UpQ0l+cT7VTgJrTKx%yblp(z~whm2PfD|XzT zIwJ6&Kq=Lg`Ffd2SCw_~?Nzj6=)DDw7M#)5^&=xPhD)(})k+_EWz`d{Z9iy0Sz6 z>?w};+_6CaBsGbu!ATJNp<=@92pW0I9zH_TXwWu_(m#aOSp!8%qkLW8Z>bu!%QNZM zF?zyPG6Zi-WtHuyS~yoRsXQrJu4sZ|rL=6gSiVCMrNA$#2%kEaO(jpu8sL9dYZa~Z z+nl#{E}zMAy*)l&x&n7?vA%58w&mM$e1mnSER1UKdZnu6`7&1K-E2W}rcBe;_em^L z%jWsz+&oVX`Gs`9%4M4+u{$ke>vHZqhn&)5UiAIk-BeIBksgPLJWpGHy6p(*gIB#s@-|~p^Z5%bnSv^;U8>?EC zmWPKN^OJ(X2utm;F)HtX=W*>Ec)*UFK0xr8uq|&c((AU0sdGje>yo$=c))u}7pD!t zk46RVV&0fJRz8lW-hylux_5Nl5G(QX_caV&HuHfuE~$-F>)ec$f@|vA1LK%(|hy>chVmIlvIRqFBrazx+Am96IX(K*8LQp zuL|o-Hs#4>1DUkU`qu6Pqa+TXjOBtENTWkRZOCY}`jva(3;c&dQWt%6nOYHf8yF#Cq8k3rXUCy0D z4t#zu0S}+!1GoxMjt^+ew)57}SSqt{Dt~z(UVl6CIz~%0rl@gdeLkKKh(T50<&DWP z0hwCf_yCHBPUrBd0jMoN^SODM9fHXTB3OW!@kK0Ri>k$*3U#fUtOaVWNg1?7JMPKR z_36~RaVq7%c;g|3GG=4y0aTtLOiYXB_%vsbiML(u_Gl11et+{}0mf!Zk)CrHHdlkHs@M(w&Oun8XlRjg(!GaK zJ`WPG1gLD3fNRFS`&%Iw6%qaxp!u=G;FI#7o|eGH>RTZm*_rCV10=9Q9Vk^dIV>My z=DBQ1JcPU9^E1@5`8E_lF6qJSLZ;CQKa{CF(m<{#+BN-eXROTo0gnyt8C8Y9Y&j0q z-Fr@t()&-O08?-|G{B{Se_o4W7Lsd)e2ji;9?m8a)=+51(pkF<1G58b%5M2{f@7(_ zBA9PeH@5&PB@f%fsY)r@fS4OOjBTX-H+R%iv2?Ohhp2Ov;-XuE5Tv zG`kA(kXl&HVQXk5O|tbjz=lh$c;?o+BG3GEWmXhh6>^Skj4dv8L9JNu3|q8FLaO-V z8O~vzgkm%Q5@x9>I74BBIy10hay(Yt*%aBxR_${zGA(ilI+??oDN!`G%VwGPdThBN zn&h}r^jZUT+2a*F{tC7(u^t>6?&|?1zxDYa)u~VxfNisR)2#QaDxLTWuK%(+wXiWT zGjU>+HL-OOF>qvXHgR`$aWrADw>3M3yK*|*kJ~ZS*WbFovxf$m#UmQ;0VC^hV!s5U zJ}{)5LP9`@Sw(y&1ZqhKCx{(@gIg0J8h1aoT_?=W774fdCTZ`hDd}OTNE2jd=&0yx zYbj-#8>nTfXzAgr=votK*MAYNNh8!iLewxRRuWF0^6UXaoYGPPckm+q0#O)bnXkV_4PT5Wae4kjRb?Oh$#NyL=*Iwi%X9NB_WbBK{ zl0Uu>fd&Qw68yhK=08j@84L{^MeLlN?Q9sn{o}-06B-}vfglr$R`La+PW-pbAu8Vf zehhTO4a-Lo8F2DbDEWGJy;V?1I2h$mSlrfIecVldt_s9v|6cCf+I;-@H}IzM-1(cg z+%rS)&9HUU1{HtH0b$FGNF`KhmfKr25f&$9>?rspmzw&q)H0n}6s+u1+pCaN6z5xfcv>?sz#&9eOvLRrKc@e(Lb26p7p(-=~=oSi?JU8y*xr|1LSoWVsC3sOHP&hs&(= zWjIYoN&P!$3Fd;7-oGG){HLLn{QncQ-#q>^v}Op!l9L&W3uII?#Z{QRVnHrL82H>gn@E8?H&g`i%dzRroO3& z%V@g^jAS2BGLS31TgNAdwUg92(0_;Q@zWB7@E59*U%~%RCG9`dx_?c|j$b=Fz?CG= ztri^(rBlt;cHQ{-emjLJP|y-@+%UZehg5@#(tXJ-oDQ| zjjQq{lj_tKJvl;QXQF@JGd&8QxX8K=w0(-2Ig)X3cJi-X?S@MFY;M5LQnwmdMWCNz zO@+5LR@uSPg0%vA<`$+*GL%J7|Bf3(|KQ0ll>y@Y?{gz#V(R=?a&jg#KJg_dobt(? zAm3}ycs)YwfrQ~Dq#%D!X>1{Dz^Rae^+qLKEWQK7(8M>3$AcXfCB#!=6tFx|P+;yK z78V*)&@`K16eJ#EnqbmCiJxT_7l5eHA}F0|$EW^?OUWuiic3iw)wj+z%P}+7*DqJk zV1DZuhmyQmbMW&*EkpBoN4?T*TpdyzUm zzvzAMTJWCC|zt&(DH> zNv_nixjT^4+>wS~=(H|Mh4%~PewK=_ZiA1fV}~7cbseZpw-4>Bj{@^h7cs2sb$siW$ht!=-C1TVGnroute`{;uS+(f5QM>fC^yREogJ`^ACg}uS6#AdA1kJyxO%W^Ee->LFfayeTqqHmmT8Idm=fNzXNHjh;r2c7qP{@LXd!%uMjg5tMnm{!P zMk9ImZ{rMW)1Ti}!ovRh++&@A4XuxYHtQ&cH$}o30g771ZoA;?H!MbloLW`Xgtu2a z-gaffxwqZHafD?noUTk*e4BH4tp{7XziM0xkYPRH*%Rfc1Sn>-*C_E^ z#KiWb%7i$lS^lahm!vo>f%rle`JYAiFSO}jgYLhN;;c<>q;^4pVPihmGAWRUh)~D- zyk2btrn{2*#u~duj^h^ZnK#ELkh$%)JPvrVRD6&2c06gx*+%9EE5T)z-zLhrj;pf! zr;VO20w!C6ehCgPCS-EkS82Yt{K7P2nQEZwq_m^~ByI576PObQ6_sU;@f7`}_`CdN zvPm|P`a)OfEBvwx^J|DM19P;mYw_-dRS?_eo058a>jY99y%B!=Fbe4O#b(Mv=( zk9TmKF>JxxZ8Myi>Hf1lW5sncy}GwJ=+e&qdn0UUY{Cd5 zha^PM`6p~wYk8}n;@Quz<@gSGx*Xd?kSeJZL9|cn){dv4n3pMzQv`4QrrE|-GK+yu z>?8fZ>IH*P&l$EZK zfv0b`6FAm=mzkOlPO0;)KHT`g_y|fMUa7wtZjo;n8e;k@jc;tZsweuwp8B7||1UJ? zUxfeQ|H5Cc#}pDc@#J9^G1!wtOsZFA6iy~0%ENGdg%VVKqe7Y{j@N z6BFlpjYUU%%D6(KzqQ_4-A3Ek-4n8!t-Gi^&)y0{9wGcy=A(I8_zHcYF7XvS|Gm-m zZ<+rOwdr4jyK&;b6+`J8b+|qm_~2L!wpE!7`Xj#?6lv?VGA)t|ke0_Tlc7e-&QATxBgw;Vhs6OA-g*Q8HQ-26V2yJt_FWF-_F;`Zy$H{U;PJ-i+# zTG^$P8#A}AC!P1SGs_6w7&h3VouU&f@703B=j1NO?55;0r+F(X+sqVm6?i)*HHsRkgzb$Ah`e!9R%Ss(Ut@_>8oQ0GjYRh*b(No20xm^|EOB9wlBF9N zpHhYz8J9I-;+U?RW@TYwTBKD>AL;HM-u}1IKuEST# zT0`8h{!hKpCE6pd%~Z;7C4;NL&*@myu6Q)cD=e!1aXycoHMy!ZR$S9>rv$&>nTU&N zlyXg1QaIBw;A-GBVX?+kP#K=@({DO^?AwmJHN%6V3vt=FFPxz+9MhIC8zD`@mAQ=UW2Xsef-aP}xHp%%~ z{r`ixw+@SPZQn*`hVB7|ln&__Nb_5!Bdt}&ES-0_ zU*Jr#VN~=Md-Vf#4wZ{jr$Xa3@D>4%>&Kk7sg|?VEc34S^pCNF(HXzZ7B$?XkZ71z3WrtXlZaDtV@U|tLVJ3nc+&DtjjlsoYP>pu|+JuNK% zr%(vyMVY*g)lhqkhfN8TQ-JUk6=b!5XP~SCM2?9L{C?YorwlxyBBT{{FoDN2OzRln zHI|!#Ap!)#A^N?*Gs{8Oz!&K}t{zSZ zI#q-ABz7j?TC(5Q%6QmVcsjT~rPFb6u>tY(atm_IHiNuLPrP0jXMvT4CojaRbs)@$gRu zlrgwtxQCtFs%%|22CY$KpkUdz_Z*kfaE z6An^NmmUWFlSC6Dz&bX^uY`)V{le@)3?`J@f*Sx^qS!lHi^MpJD9u+ z_)ww7E<|T!r*K%z=4Ks;A5?AF6cXuBF##Nm{^=V}R*9#1c5b%=|J z4WuS#JuDp1F?iktm&ff3xe1~LcR+$odqHNux>jlNF*;e))YO3Y#e_sq{@{MF-q(k6 zaCmqQG6U6;nBqr=ONfcxcm@S^rOGf6S2gkue$|G65{4MP+o_wD_K(lb&K`!Wf|RP- zcH5pJ{QNFYzkK;}vbebTNhBH?X2$(RcZbR{{%B?6^769r@ajqXay7=0wh8=n(m0&p z$NU^p1CT^v z{1cKdbjQ{BA44lImjv&Je0O4EiKb$RNiAI~_88@G4@Iodu?Y9aP>B~A&@n8oENAZS zjzrQ_?Hi`1>zR%4o0`tebze59?36_83TV8 zK)|2{3IZQlZ-s%1Qu9)!F~Le@;ic%Q2y}iKHZ)uAkYwcokl!I37v*({)KZfiQI(fs zQDZe9CL7{%NaL&1y%4*W59XgqDpS{yi_u9wNJ!njjzfpGo^+cD*ztB3SVT* z#45Y?qp1+hf9Kj6LgDa{K-7cap!DZejgh}TV$OdW84$Id z9IKsAATbAV#$S84b46DI$VEOoLLzjbmu4fa$5EiQp_%=a)z!lD6_Fj@tnv4GL5;wn zo;J3^J8PXoLES?`Lyu8w?415 zghVh(Em{vB`RDUamV!gFxB=%ngS8(&hycr(5D`$-4sv=qM$5mkzmG>iK+w|NeRqC* zd`w__iy=v~mv7gws9rJmZDG#wv=7)id^SY*26Y0M8W^7JjN3K@01hRfVewi~HaL(y z>h+QTmzz6O^^OgR(yb|`uPM^N4)%90V^w9rYz=T1OaJvI{s-RyFQG8~V?74Sjl|lZdcAq$MLz*E#pCYyYx937A(6}TN?CV7FdjZ-B;)iVl?Wus7I~wLluU}kHp7#)OTj=uI_=d*h}Aw6n8IXrhVNee<~0|HY;Uk{Bbu+c|^ zSdg!EVi2-{x=}7{0mso#p8u!g$Sy@q1t9p_aZCV?g8{|waQa-Vyjc<_Bb&;s%(kB) z1yYvW5Fa2%Ow&im(CsFH;QaA$3JrE1MV4;(Ag3v2{upaLIhtHgLEW0U4ZA94?30)aqi zjQ50HUWo%=1{@tOFTCSz`=;NKJc?Srk2fS{>O61}S2p#Ox}B>S)k;OP39c-%*Et!I zGUInhC>=6SsjC|rgP*(~T}ypWdUNmU7Rnj{a^gxKWlnhc@?;9Tp^Svd+;X3s@l#Xe zyuW`!Wux1~K2!Q8pFZ>MX2<8UJ<53_Pg5Vv4_?$r#6#{`qaBgUn50@VnHZuJvE4rYWCDnhPy-6ac=(_ori~qD`cq7Gi%)TB(T#gxU;3DXJkZi#f$b|zN4eF)1uRC40VE?5y_K4nlZGLs$2fONtaF+VnZ|Y zn|CM$a(4rhxLNtIw#dL0&}dxN4kV679vpOcm109fnUD15=Gg5r&<*Yli}QlR2jhF|<{#KG8}V$f8hRw+A=DT4tO1MQ8uBqo0Z zV#@nf>)Ty)?a&m9PiV#TNzap>C$nTwaXuI^p-a`X^SK$|s~9Cb9sR5>ja8eG&B-j9L$s>G}Mc(AMNtC)didp?V}6PO<;V z1-`wCb5y@=gbkS_Ll_-H>ZgffxOcIWJfWi(Zy~7-5}kZ|jMqASy2TGB(zZezPDCP$ zw%C<4XRLMY6NBpLRWHRocB4d62lZ z5RVpKd{Ofjx36elE9<}Iy@ZC)MODmT^qOFLkKV_EvRiF5@3Qoc5ll= zC2Vu?uV?~VQFB-3K=G`3ghJnR5ZqT+R5}#dH{U!pcMGS`BqQEbe7}?4Cv-ZW^{N1z1FMShZ zY^i=uohp%`qMeEMx}nBM*-Fh(^)6Ag@x>4;M_N~%Gw&u)+cQ5d6C7mD=WfJLkJg}#qs7wnM<=qADGQ?2Tqqcw z9xjB!2B><0?PfU@a^`bvmPc31c(g&+7!rZMwy4i1SE8dOP`nL~F?l+$YPv>ym22FO zeiC*{myQzx^R3ca@2d7s8gPT}{BTzT(VhgOHg|ty7rLq;tZBKEC^T`O?8d29C;lMl z^x^M4W6i^%K~W&2`mK-rC-o@*n~D9VVS*^{|0<~ZM<^pP|5iro)Bt59uxY_fl$D`a zA-bPnN~1_QTOx0CVN+RJU71PLsJiv*YYs+K4B#L_%f_am4OlCMAK8;$g?WFUA=jMT zTnvycXkub=@~(1WF9X4S_yURW^YvwY_39N?4@F4kfYA2I<>MVBZ4~(M#UHxJ)W`$0 z`wT^?KMj?n*yP9#ux$r8D;6to6|qw$(`GjUUshnI*{rZf&^MlNLPU($!dRK^*ZU6f z7DBhx^Vh60O=5WNi3&+tS`|VR_pB1Nv`WTst>S6Slqne?{C!4C;*X|TcjA!^^=S|< z6`q$!Kp9CTLL!78J?eKB(pGhHaU#GG=4Tv?sos-+sA+B+b#6v%wDf9}At)WtLmEi~ zSDm`foQ?&-rXPFw>UK#-v>ds4=4q!L+dpQR!e={0TH^{BZf5B^cVRm-bm4$`nNkT$` zI1u|;eb{C&J6&Nc27WMrkEI_+6YAXU!Y9uR{Jao z9Sm-G==9J;IA0PQwu>p9q~$Ix>lcyQ0YO9SK<9Z^p;?;WTG(Q|l=9_m`eg8t4f|D= ztKD{1_A-h0w$AC${{H@tU%&k83^>K3p&y?%r`ohK3O|ldf*T_o?>~PEykQ5fj+B|pT%-{i z(B$Wk#_TNrv}xs)dq1GEb!K! zz^Y2^bi5}8lb`HF*x9|(WuUjFA||ZBDuNRZ_8*`~yEYQBb$Koswo2Cv z_TihU7D##bJy{3KUYy+ab*tUM`epyp8zaWg4(Ul{JpO0|-rgr>JX@;9^8VDv|2!S|>|!MEQ1@ zc}O|C%ToQ)J}pgZI{!A0s`T043pN@0i!v;07m4Nc{0?tvI zHDuq|t=HWhJqXyqa_Tt)B+pcy7kt&nI9k~W2kGd_>FP#6c^g)Y@O2f3ubRDVn829R9HuzxywXPwRfJEd`72 z2F??_k(p}eHiQrjcS+I>e<>m4vf3e5z*bglt)UA$)$`U1b4~PtaxCie4v^wtjdYI0 zM}8iCTAXp&Yf+MUxjl9`MvFt8BxRw52|68JU3$cXqxIj% zfka3t;J99^mHxa6{PF0q?#sy9MQ1aLqpzErn>Pak17CmqNG>nOq_17tPe6amx3&vB zPNwZ;b9O#>;UzM~T_sA@EO2Ba06PWZs2zn(te*am_aeZ?)mDAHLTn|gt1ZRbqmx$R z@bU0GgMuDa8dG>DS&B+>RzN^C{13yA?pyzOgXU}36HW|dfOOKJ(tIaX*?^!cjoD9* zMbEU@k@havqiXNQjcSPPjDrm<6N-<=TOYXPzxr9;WlAm8*F@c z2nF%?1*mJnsOkLf8>V|rLpsiP=|I3W>CApPR<@>2B3gtO&LG2dO_#|1s2-Dq(4Q&-pS!}BXUmn{7`>v2NKp^anpwWaZKJRct) z0$lw$CcrCHS68E6fI3j4dNyPgBL*yw`$6fWHn60ZJ!Iw}ozGY3xB4fS*L!Zln-7ZM z;hWgyyT65;zsWDDE)rA>0v6x=U8n`>GK1D&O)N(jT!qo<p<2PyD}ON>ve z(U8OMV=yOSpDDk0cRyHM^%tXP@UrWHT=?abnS=7ot$dH{?Oe0Hx!k-BSsN1Wi}sh( zJ0}Vm0~0GIRmL&RGPrQ0Dr6URYrUSz)gzERdBqwXGGd!reP2^pSznQ#OvK!`=J#Ov z`faOC`jKLWzeOfa9A^fW)C*(<`5`PsNDGSnuAU#s??L*F3X2sI|Ak*?yR4)$PPdWm2 z#h{SwLCxm&>&n$9ASg5T8y22GUH4^L*xK0l7LI44qPG(@4HT*6n2w@Axwit?fhg?QZtqi|q(V;&LAtQV)hZ5DR@ zdw`h5n>s@Q%8vuA|D>Gz-;vO7(vO4k^RGz%KZ0MF{hMF>LHeV*>xSAgn?|eHr zIx@{VTp-boFM|nC2rVU$@J}ZOxo`2&5z1W%lIBT}O9! z^N6+O*w&H8A3qBc((lB_IB&AL{m#6}>&C*lovF$v#z<>bsRSE3 zq3^VGO;?y%xcUk;_=fx@}ffPKvd)5^K3Mge+rt*62>=oa*C^d{ zLZk=jj@pooXsaF(Y3|pOdmy=}bCfR~C0zZMX;4AQ!R`Bda5~*`PnIw?R65UrvSgMG zNCh6=%!p(xnonLCtk!_al`z4FVk-f%sJf;ambR%D29c+8%~qsZ#4{5oGm6%iG`5Y;SlyWUy5{CMsJk+I#)0=&YH;%@Bh7VL{ z?{hqOM!k(R{=sn+Aezn1v|G+vugo!TQQT?T{d{w?ln>eJeno>#D69;CFA>MeJUe zIJnvy*1U_lwzU1cvVwg?K^`}ZVeYzRf1R5N%iK85Xm4-#QJtkiiMDMT8ohg06IVNO z3yD)#A!GBun)rL5IV5LFfB=wP0XxxuNICvT9X|L9g8Elm(LVxfYX7Djs%rP7ppo4N z)tOR&l4Ouy`SG#kD=Rn3v)V0amx3M@9V4M$5|L%33yArnRMQm?4r{3xO+aFDvh!k% z*}~zT5Fo19sm^NXlKc+G8H!OuVl);6o12?)-8;^Kw2?|pb#+&>%N1M15s8AWP*%3c zjt2i=B4UsnMRFpOoKXe|g#h&4m_FZ=pr zfOOodiJ4iK>(W`4?_u41H5x0y4iZCzjX56v!E3y?7Yrl}U6+~y0cOoy=iHjL#!N+B z8dKZd{RCW7M?j#H%m+p^8i;VyATC z>X~h((JD)0V}jr77QC6w2A(iM z+53BJU1A!ggaEh-0M>t))%zE={*3biAQ68Bu73odpZGVp#wUp2Kvqx9m^=)<@4YNh z2k1ddqVW-*2?AVcijV^u`Spk%$P+Q<-eaVI6sTn62Xp5gwdQmwrj)RVsIQ)skkF$7 zGnN7<*&`$|L+d$T%4uE;Q{m@Ul>b8a)lA<~UNgm3(A5RV2w-(U#C`7Hd8@H-s_!M5 z{raqXBtX4p!RirB!}8PI{qw5_S>xLQ9+;Bt%eKN)Gl%C-oQ1MV-;|GjZjALPG}0Sr6*zuh?gWbWaRXa88+p8vOP z*HzE*!lERG)Uu}XwaA##yCBpW`YT~%=H=v?7&Q4fJZ>y{q=WbhbS2!ZDhk=`Oc5}m zMpQOOttGfj&Fm=EUCI_?_T=5=79$b?u-hR?ksY@Q%>^$r*ubmu@)beV2DJD$d%r}E z*iefcDBssxH!syKKMkhBk6v(D3ewm)@w2}(1MDkX&5-+5s*Q+5wpz`PM|b2@5MG*> znUgzXwheZEITD&id!_UsabhQ~d849KmHR1=d#r4#@Opbh9xr$qI87UEAZ3)Wcy(94 zXj~47?(h!gHQs;D04lC*!laZ8r_;%D4>f75b-gk zQk|V@s+vUAg~{=TOcqo-#ls&A+Y4Yr;DbMRm=qOeQ-u?1pv5}Sm{cMwTrH)_#z)^P zl9{j|(?;iXRf2`nU$>bOHXg3+Ys6@kKVdOlNGjQ_+IEoHdb|~?n7np^|2md7rSU8{ z2KvPqGX@$aoB$t$4#72H^bw$os*VATWUaI6grN<6I{n)|T-^mPO!}CDnDTN!djK6a za9(i(AML^(FFDA6 zdmBf~%9Eb}?0e+Dwedgw_XtGjpK9X}s(;z|2Qeprrw<QIg-kzaJ)~ z*ECOh2}w`a3&Ju+ga4o6W!pm(097J6BP?zY9yNhs>(_&dSGK9qmUt8zXiWcDmwM!y}toG&_ z577hja%_p7QS?`!!8W*bpQA2GyZ)L#)RjwQ4Lc>h7un|V^NI!?L9L~`4nH#2V_H*$ z4Ek^PYwBZP?sCo!bE2l`QeP6BiXKDv+V&hGgB$KNBR zoX~p~3!o9G!1_vvm!tN* zivgMkxQT7Qsxv&1?}5d0Nv6ocXo7c0RdT^=QqUC zUsv0L@prbj@2lTW0SJ69kP!?9xq_2YiA3z)7q1Rx1l>_h{P@A=45RcjylA@j?em*-ddEnW8(sN0h{JMyWSZ{x%kl zzGKq(jG16xaEu%%DsbW&Bp=+UyU%zd>Bv$1v)`=GG9FN@*-rOEqe%^&V&P|*zp2Dc zF&pp~jFd6KJ5&rme9+r8Dbi)A@So9?gw9>g&5`u*Xo{o-(%!G43Ux7*sw8>U$5j&vlB2%rDikce8|+t>KhtPQtq0AP*&wO`vAd4AB56z^|+J}lVF0SM{(j(`b9A4=7VuE-(8u>-$TqO zfVD>xfS1aD4zd5$%?egQY4|IM{UZuta{q)_piaA*u@qG7VS7V>mz74y{b6Ybts+T} zP~~r%WKgu=ZQ2nDjfne6m~!@S801)``L2`*Cu;-h_-8&jtvZ&9)Xc$}qzVQXr zuU#OMyYJE3zrIcngh#mXQdJ~_*UDv$48;*Z!TRUrWuVFE#;i*33FsMy1`|IrJ3Fuo zC}#Ev3QD-S2~_1S{`y{oai=l>WNsV35d-950QIH|D8{)!r<;!2Ujb4r*PENDD*>BG zLMvG%EV#TWTk%sd2?@p>+(R)y0RV~xwn1m0#3kOG@f`%s5FuM}wY8Oseh^1oC6XV= z$B2qr0*yJ{sKN$Ly0co?F>g?uz|5#EsSqpN3Q1GpBo$9MNDfUBwKS44&W6jouyyW+Y(<{>zet_YYgd&TaQw3Kg2Uh37M-6%d*`Pn z1}8}js-?E=frlrH8XW^KQ0Du->69B};FRVv+J%SaJrSDuyXHnObHS*6R3WG|RZ{j_ zfEDhb`!hVwwRt0;Kq$f6+(;xMzmc>!RV_-N^5Kr8Y&mcs;NlK4%_RWnB}pCAd(nCR z>CxrW%;zgJk3?GL%k!!xOiyAk=}~&XOE`6L|vE z(-_@e;apqPCKE7k{HEQ1liuk^`}zeNDCI>1)_<7P`~#|ghK*>bzy7JkyeI~LV)cdI zs2ZapG~VA@*M~wmgc%1OE$2J!Vccbz_%bGU^Pc<{lxHRmMVTl8J;^UQ@J6xQ+RYFl zl@85I{Km=4O(xk%gqle%p|r}5Rl&KFJHa{G**8MDlLWsz0Z>3dH_TS&<9Nc~$-*S9 zcfgM!c<=O=d#BmmoWM9r2r4K{D(35tZ{NNFJsQUGfKPO%)_~K^ z-~Sho$5#P+{tCS7ot`FCy-)0Wn4}dp-v%@9Syy5saWL%q-H!xx?FeNNhM<7%coXN0 zWRwh5_5+BmsL+zN7>acaic_%@Q;BAGVIWRWttVfx&a-JFGK!+qVUd>*_ue3W5xWRz z&uNP|fAX_;zA{g+*|yZhzC9Q@2d`;!WNIeG7RSJ)*>v0Xy_y>hxF-ntM@3|uI@3BK zva)inU70mkA0wdeU2kl)l#W&ktM^Rv+NueqflXFJi3D_JKgM$V;{1o*L^|A-Y?wSe zl?cceOgC}Gyn(GTSk1suy1Y%JOB~Knbam0Hye#@ezF1yuqG+hSIqxzsuUbANB$RS8 zjsLFvfb`RPr4^8E(ojkZ?O-(3)m@9_Dvr={E!1Gs-K0oKuu0KkhzR-J_LMSWO%}5? zW7KD4T;CV}YZ=dQ3#klrTy7%cqzh;29zV0G4N{AW7Y-N`jsP(L{Tdt5Kygrcxuooy za%}0C8S2po=mNN0!8?=>CFhOEt=5nzgf6O4cPAO?M^9I9LIG$9{Xpt6F=t@zXMIXb_UK*9E;XIdl!!k0DgRs7Hy+19=|!nu+p4d3 zK0+*oI;P3B#T&@1BxQ1?F^lJ?3PEcP^S|beIASm-TB#QY$>F|tn<6{Dymp737)KNr z$38d>i_UE(+;=S<9gi3o%2J738-FY<Zj{e@s%m>fj?E$gC_J0=-{3*X|qfq=+Jn&Cw7(fyEw~rBXWqbfbGSiNjVozM6 zB;pCeIa?C4oN7*6+=Z&D9mK0X_j zA3g_=ySo9OQ*-KnQ|GcIfu<2MOn!0#lv~ySYO=%%&?@r%J1(FQJ}q}dg@8otbaW$u zobQBhP|%=lL$71wyPKOE37~ZZh5rs5a=Ks_1lYm#KG0rLy0m0WMN3;)&d$r9K@qsh z7*TuP2b9Xv?ZlTjxcT}5WvckJG&E|tIXOWXQ$%Kg1|}vZ9j4r`0M%ws^k*PJ@dv$~ zRZC_*|HC>HZXjA%c`B5J7IN4BeYUWWQ6g*nkETjl9c;|CgWonV=ZMEn_*2OiCxd{{XjGL+PgGao_zd5s-&tV;)JS>~nI)xAVnIQa;AYo5@sI z4M_eNdyW7!0DC{vqqo{#;_<&)jT--><8xNP3g~3&83P)vjP@XOG^&?O-6Ng#ubd5? zh5!f`r5^qG5mvot9?ynWG@R=BPO>_1wa{hhM$*ePJO=yTND^#`g*L=PS_X3fvhz9U zWjvg&z;aWgt!(OGLiAX$7`4iaVwiFFTU(Thb202~5Ot){9>Zj+CqtGN_E}#C zL9OVL;()SbjzvQGz60++e2$URZ=aJg6Z_bMq}D>sn?ms{0?yw@9$w;5LJ)pV<7Eo` zxvg4LS9e!!GYj$wuj<(=N=CXJs>;Trl|J$YL5i*&LHhdG4=zgwlSz$D3U5*&gf3_v zK6uRcRycCzy~M^9obaknNnJ+fbj)q6@t%$rB$%@#%q1@ddB465G$f zC$|V^FxI`+X(QvaF9WctYV|P_$9?|~kP8*rTqGh5j=pl03atN-xBre*{tQ$`Q3d{~feI?kznn;VX9bfS zY#{i2{;|(w2Z6=hP#2yjo`8l%zb@}b4Lsa4o{y4!s;AvhD^*L0!PtVZb9 zoLr=dH9>sQoWJa_GKHu1vf-lrg2V*`H(VSCT&xqfob01(sD*si2s{tpJM1|AP?e>A z@@|f6yDDth4?0+bhbtpHJkWAyzxL`Oj`-a+_mkl3<=ow)!t=HBnvl)G9q+Zl=*f=D zv$(@m|8$O5#?O1!HG~bwNCVf`#teQ&4wO$s@4d4$CC6=QesrbYbbai0`?2%M-C}rd zH>zIHPm5d@v-Y#kqpzmq{c6W9yar=6GW66Q7Ysk3^fc&Bmr3mMp1MZVBqxOxyzg_tBVD1FDNXB(fnd~c8f9wngk3OiaY zFU|i!DfY~U&aj+8DSO-kyXlh&l(G*=%GnEL^;GqmP;7|lBloNOqC@^6^b~=Fve;#q z>=3?u>UW9n3B@=f84^_T)!leO#s^=2vgHkc2{nGTos7_I?&k@j2~YT$5Yy>T9b;I7PjQcO7_RBfBc|o9d9L-R)lr>96wV?v~8l# zSsc7+F)t?_GbYOXCa+vjljTu8BQO~_f}ENy{Eb}>wTpm#IJy5ekCopT|k%vjf;b zuUC6Zx7sMc_1#%tXhI)aL-wH}HijA zOyE$lGv8-5oNrMzD?!H?3dSI6rEG${yiZYgBab&xv^0v_T>Sw!?y#xotmrFVGC#;p&OM z63|b6d~{UX(%E?vh(Me$7XNfI=>ZFOx3si$x3!hOeEHI=)nuN$&{jz?*yiTP4=u7d zxz4VxYM`I#95k_&{uBI21c;x-b0>kKC%X)l`=Agb4kfnNB6gcdFFep#JQMyiG2msPLxJRM+4%|4iE)sDaF7YOH$D<&(5Nd{2k{XmzMgRg&v~S67(n{ zN-!`mfNt_sBF8G;ZPOsD_-d!BUsdzvnTRL^K2Uc9?t%5tf>-V{Ks!0Kl|mc6LGutL zOgA>PL2_PxkhAhE6Bq~y(MU>&zC4G!WreYXY<4buoBsqJZjr>{d{NbiO%DOJJ0Nga zF_!K=xh4m$awI@TK`~K~86gi`QQKv&Y)C~DJr$HN_!cgH~n zLO`uAL-E`Br&bzuuP-k9NM!z{z=*Hrk{UdvBZ^VY^mCKf|AOkol|dm}S%%C8rzL})Kp-4pa;ynN_X|16;#>)jns`H457AVk5Q5)Lrz4f#D+ql zC*VENYgExjVU-#POrL3Tl~+<6shs;5P&1ygnqKymYdqy$qaK=z7mdKAQC#)jTBm*! z*TZS@3##<$y`O|e59!{043J2a#cx!%3Bd8o8VaIqk#6JA8dm+3=#T=D?lF4ET3%`` zvwF^9?h?`9+rI~_&^Tq*5b*8a z&4vHJ2lnf@x;p>=8rYA{^z!I%5B)D@i}Lfj;rvI#MZ^A|!$l3h-rKvEfqfxM0w%Hd z|6??`;_V5bRQL;JMFA80?`ojSM?0%eb}xm-N`nFRsL3G}#r!g~_vcH`AE!fIoRX@4 zH9(!TXk4H>3KAC!d@xKvW|IbZ{+j_e&K9=Zp1z*iM@lL@s+=?Y0!^wDQyfZT%8KJ` z6T|AtTr(V;s;CT|oH1dNypvPp1uHBP5=(HN0WLwoAtNvtLUf|Ur*)jE2hs)e8IU|kXD-BH~sxc>4b1lgbb z_PW4iMn!h|x#gq(F@qBZ{3l|?@jff#fk4lw|3B+%+$^4Y+5Z!H74R8{Hm9qr`k!^tW3^qq`XLgqHYCM_qCDUgpU1DOQY2rgFY0M;ZNRsN* z0HQvV2_-Ar%T|c$Q+ksbmsn9_^xHbN~l~R{tAC8-q0RD!C zEZG|`!>+)?o7MBq!ytaY&8>%rXd$Sr@$Z1{TKp$^YaE1_J^L`VAFFkk$gqbOU)8XE zG+VOXiNOwv-Do4PNPI)y>9ajjSa*VTsjbsvujU=8ViRclM!YM8b;+$S!MbGD+hH_? zN5YXTtdA7e*|62MFK8kUwSA-B5wJc|UXO+a$*vE4}5g!a^nbp0v>OXbP*Y*C0<^VYk&i5)ilT zu}sXjeG+Wfaqqg>t{;cq$(yrusI13J(?OOaG_>RuL6ZzpO48U^kLhCXDTsI^V=|MZ z%Ccn^B)-S|F7qI%+=GZwo6Q0{lQdNMQp*dJ&htb~5s$esRYiX|9uwDNnjgjO=T}W7 zTTQ;KWD&wQ3<$Q&A@wYEMQUaoR>L=ma@b`rL-3j(_b|k<8A>anFu%Yyqzq+zBkoX8 zl$mUk`u3=ABbABOkS1idR9(A1O!;A4a$0I-fwdsB6RV-}h^W%M_Kea9x{?sPb&9kQ zF{bN>hPD^sk{dIfs9{U-;1`m*uX5(Rw;ulzY|!7IT*Kbun{l+Qas2k|fD?V+Vws^f zpF<4EJNG>#y)Np7)VPXCj{b4haG7BMdFf8C@xfHsU7zd`Ot7N@S-=D9)6qT7Q(cV<+wd?*sJvF!M%nIHR* z!H)P1*Quj%5cC9H)AvEBO=q7`_M@t&1Mfw5Iz+ik@Ea-nM9u!`@++ozN8>u~?f4Y6n9dxJYYk|q+IS@VT zj_GJnEdf))M{G;)BbRd=>t=N5G*)aWF}TLR@AXeLZ@DZD|FE!Ls!bQ4vZeZxqC`05 z(igSv%xPSg+ykS5uUdLVTO_<`s>1u}82ugJbQJe!i!I;-c$rn9`nzCM6rYhre!s+eZzAevMO1)!wVI3)tSvR6Zz(4iao)2+-(oS$BiuA2GFKgK`uQu zFWicoU%zHAA~n>Q3m*uc;>GA7saxENe@Z*0S@IC?+*0#66gU*piK6a9v9Scd}( z1os$kqBbn#eu}Ph!$0Mhq0CfFFBkNf>|)bm<|lQwdGp$3NV{3Tw1B~k>gsuQhtF7d z>2_q-XOAd8^ptt$r|+F$(t291W7D=Jo%76JgnfNdb3#)1TBy=D$V49tube_TE}0tj ze4#tt_MLH8<^rsqUulBbRP*A|=ZN&uEuk^Xb(G5TpP}@#!*&=2MOoj!n2?iv7+Ll5 zyJ437b>?+2%{lGh8}RYP(qj!d=fr9;@le$5%jAbS{EeEPO)++M^E18+M!W~GSQzcB zjCsiuEu&Fu|I^P;wP|OjCzRIlPxG?B!hcqdi%j(4!$TW39B9%e1kNW0`RK^OOS|ywa)p;XbTp(;8^|}L@>}a`72Oecwi+#!*cPwd< z6ZAA|)Q>%u>id9XEjaBYe+dz)B*3#fl0X;KGiZ#O18q_iSA@nnl^%{+h}<)w+?alj zx5Wjx#8p-H#e>VXtx?RUjMrtuqsiXXhDeV5NvVTM$SH zHeIWsw&;i!JP5TRb|G(OqK!K4?YvFHkr^*%@MFA?f2%K!zmZblqQEwxeRlDRYOK{{ zg?r5L9*ZyGx}$#HXPUz_t7X)-Zc-;9nAqpGwn)LZbXI8>V`5ZKydl2AT^lM9YCk{0 zoWF0fbG*pDAgu9!@x$j6P=(-Er2476YUKVrZzw#Q7#shAC?wFO5bs_`NkN9j(0ui# z_oE^ws+dZcDwK@lDXV`eN!&A(1y%O9P3}~;?k*8Waf}6L+?Yj!bi>jt^v|$iMJ%B~BPryh?c8UI6{kgkJt^~H z-BdWWKeXm=#OFhXe)VD*Fcw#0u$be$i(b1wLWwPd=@Pz{R#}iG=Tpa4C8f7W`P`)y zqg)G2s$3G5;KgN68mG9FTn5d0trB@Nr9-Agu3Ykl){+~B)8L>$B4IE-BH)T)Bd9Q% zP0in`Z1^Ht-hgWcTOzm$Lw?b-Nc(!tlc3U?KT+?pmx6}eia$y1G@M^7vCdGTl*B<` zRHkClxkxZ2uhAKQW;du8@yHE5E6%fo7P%MN@bOVm!_C?w0%YGdWA?+5{1XG}nM-cU zP5bQV`8qTOvI{hxqn=1-`Wd+(w|tEG1~~Ds<<(4 zz^JwuO{_i*AARIT?IhKxOs#DeV`_NDIhwff`t-YUZKlPE5ofw?p*9cosFHrem zP+@MboUV|()bAPz>pj2tMaK#PhJc~D%uUl&bK zVZ8v0*?seab*qAq8dphEwTP1iH0KRoL|t_|N3Kp$Eyinnxk&bLR&nnNz0=#ga}lSt zt!3W;6EUIY+RaAVnac}_Qv>9!3gYzw{Y|kV@Ufd;fZY~N!Ql1r(MbMLW!~THrN<4m zpR$7$t~#b_6tj1{(WGXAPp@8>b1g^WE~Bb7199_yUZN7jj>jXpNAjeo6=%j|)JtY0&|hZO zi}2$c|Lej28LewTvuapVAPp&Wz(|_o$apz7UhYtDX1@c?F+`;q?V%v~?7OK?xcStV zB`ZnoKUlyu?k{)Ij*y+MUmjvGB`$z!yaTf9uv~OMiGx+PQ`XlQt99EQsi;j9Fp0h? z_kj=XLTy!Cj!5wmvdV;i>}Z8xObRkg3MTX_8;~k?s=|SFBkC82NxbNj&+ccQq*Uty zMvH(x!EWy=+i%>m4}W(J$2a=KrusI~( zrp9lvHK{ny7z`@kaivi@KF z7N5zMJdO$rDsRY^dT~(2!9>w0zX|=XX{!GOn}mMQOWx=Z5ZUzqf8sQb|6`n{gJ?w1 zpZvPXUceL$XRVhIN@-ZnxOy{0v^-D(11HxcLb58FKnN!)b{pn)O zLxrx=>vomB%#-9rp~i6>9_?C^rr!M{-y^wnt5S@Q5So~ z9?`c?3IL84UdZ5B))yYIE}nnTHZ|VHz?E8~7lEVYqcteU_)!Ps$?`$~o@9T40yDF{ zBm^3AT~!#nG?D^PcMw6IY%loW8uk}Ba68aHaeE!mZN4P{w-Kf6>Q9$QXD5Z=Rw?)$ z?W|#tAp{htKCq(u6Ti`g{J<)M$M?5l#xb-76XgY=MJ-GE2>Bg=g1X(s!eUJJkow%2 ze$icjx==}LVGN7v_>arCcK_YnHsacIF+Miac1HU3U}Yg=Y>%%`W=zS9g=YX!wZW4> z+i|dk*2VJdN z^KVI`Q^>ofv!C)SSo}I1B&|fZnMr>@T~#Nb*&{z1+Li!8n%U5xS?z=cX>CHEY`r0i z<671`T}?P#m^}HgoGv<{c*&da%gkYzP-*|+uxi_EqMpsCQoe3+43Ua5X@P_@o;Ea? z1BqB}U*cfEWA%$InI$f}DZ=PTLYhM6uD+kg%Eb94as7=4Yw9nnpROfCPqoR#GE=|X zzCmk*CSPzShUtBJ$ZR$qrAMORXUMuxjKJ1Y?M&I}MHY=pA1|)r3B}$N$;c3e@&Eon z%Av(%@96w9GNtf}8o^eQs)~zKdi6QleuBlmSK)KASEkdP$I{5Y^;diJ4q{@Kt5tM< z#7QY9xa<;G*B^v(A)##g&gs=H(pq{cUpusvLnMZWTe`mOlxyycpomsRzI@g3jLD!A zjqHl7Z@?t9Xa4o5Q|2=)8LnB4C2H?Dkv*aN>qR}evtP7lB7D?ovoM)|&XyRR`@UZI znaX}ud|?$vfy2}U zPD6gi{(5aPr>jNJL|Hq+gGqaO7hSUlMZ#%k!UZ1Vr`cs=}w- zDGn(7*gf#qc?d7qFOg(UQ(~a~13?C+XXJ$>`3&8U9{22~G~R%&mBs@%QbD>c#h|Pu zH<*oG3tmTwD-M77yjMFXMYm$TX|}6v1i_$92`ffp(K@JCvMWmyUVF=44oITSf=9Vf zk=3RCkMBZEEU~oW4w6jEV56?|O_lfS5SB9>)48^@APb7!-i6U$0fkdnxp`A0ucyi> z6k18%yX++8REzK>(}p``lU!ZNP}|##_ynl#ZNJ!{e~EugFBxL1$@j(x5FWl&!!M$1 za)HAzaY#>YGoWSIul8G1Z*uyTAU9mu8+#Y!N5j{VjLZH?>Mqrc(fA9Ks7(E&lFE^L zV6d@iR@+3Wn2KulPHGFA(fKyGSe2{i(?%(PfC{%4#N0nd1sGS}p+gdU8)q&55 zs4*&3gfB~W=Gepm@%rzuM-V=xAZ#~A#SKRmEXVBe&-D8&FS()wuD^d|)8FrKo?503 zTRK$z2O?w{I~_DnzNFaa%QDDW(5rHY^^Xbi;uI>3EJGQhEOw1s=F%o|{k1KhN*DsS zRMh83rutbf+>S@TSKbl)wMzOXdc+UCq9@y{9dT7@6D{er*nz|%(aQSm6E;Q8u8q^ ztI;QZzFVK7>>H+KvA)M#F6IOrcar@Xh*u9Z(uO_Ztf$m?Y0V7HUL83@+L0s*k+s}n zo2ty%jKqw!t;qTYBd__hd=%fqcK=#MXwi;O%)(;XI}D#!2GL?z2PPmyNOH*yF1DdS z8R81l7t%PHn)6sVqiN61H^;wq(=LA_F{D|Q{>4!J7wW+oxfJ}^X)F=TtOPIKoEDpA z=fQ3v{~fOwhjl?$Af@}n>V=g=YpUBMJ{W&;aGcd>raFZ(*J!>0npn6ElNA0NUG zy>c)Eu>FsZCG(?cQc@cO*OTvo7sl&Ro*gdv=8f}5x@yr~jlY&2oTb=rHKqjYe84qg z=nI;4$;?qn#_4YzG0Tp0{hufCy>}YLS!`dhEb8XyYl+HF=yv(8j4iA#)kMLVn%m#K z5kbF^nr?PFbTd(O)!&v)^4u2Jwr{J|LiDBl;XAoAb^T0)GMDd?I!j$lE9$J^j(sI2 z)_Q6vLSx?E{Lv-8=jXyh32}C7B~R1d#&PBwOHMWzU%wPGU~;uNn?dp@ust>^jACP^_@0$R@l zT$7XJjD1ZF&dZmViPQMQ+%QRP^#MTXV&%Bt5eA3jG)ke>c|3*Li4sa88u(HoRvSts z3MC)Ci=x?R^T<>ca*=kHKPRy|W&5F|dF#&6Yg9C=NlyX6gzawn%d_Vqz zM5u(X@3h@EpN|*>68|n0hABcl)`&$MTTT*&Nh;{cqf!uc&_)(~yA3ldv4$;S>qV|2 zhRcOGb7ajT7;9BkFiqwHKKwSr;z;$iWR=^e7eOfX=u6v`o|5+DA*TIQ=&gWpQZrgs z1+p$b>0y=l=TS17`$7d@$mwrw$52X3W4IUsTDVMiA-7Lt`HXE&@zi$vQ4vg2p-}?c zqFo_JWZe1qr20EDxVK#Sa&EI+N=pN&82Vq$*+vU@_caKbZ_UNEj$%^3^(Om%nbv4? zYNbBgIv3YE?e$Os?$U>Qob+O6JE0iLxK%Of9V71gVox*aw~Sy`?-GhHp7wrHY6+~N z^3G<`J4fWc0ZuElu^b?B-zw(ox*2~=Z5~-fTQ5dl^y+o!O0kM%(mO?*Jao>-J?d?t zUYlqSHz-AJ=iip_C7dQ~bIPJV+dqx?bKHv(Q@eU(M>_U}nG5=}W0=}>_{udSHs8i7 zJZV>%$)F?M`Qtb?pMOKsZnOHuBjbw2X1VfJV*o%2roDnpI(SAkm0u9wqBihA4&Kb;++xFgoWVo`sb0a$c#-%c%Yekl!jdu zt{@-r^kGQ|I^g{kwM0r$H(2dziPC5HAkH1FU$aeA6zVpqjpM zUw(l-MEwb2ih7B6w706%8|o>eXMyzqJ3){!O#Qo{&nKuQ7TrbY6UtnucqJ=-dVI4` z$#onBn}TrPBNY}-onXN z-3-%mi0RPmPU)p%kmd4S)Ux_+HKhZ7_4x3ZBG2i8qvqJ3BIwTczOSZRsdG{?Cr_E`j;%p-oTPt;lk;;blh=3Y<^?`c1x?qY zS7ilOn6G*@*nEb^%u}W*O&fn zxt(~c^ksW!nm5Nc74CL`0kIhH`6wdmFBoqI`LC>Rf|GiE z#L5e)HxHPd3%;Yb-;tz6Bx}g%D3MD*wLvS7h4$+d>yuLwGfdMl;L1^94 zxq&0^YA=tpE&AWVC5QxHgD@}!$yr1&F&KO`dwK~G-&*k=JNkl|5%|#peN|vFwhdjJ zw*((=0KO7rzrPDZ;0CwZDvqUx|9OVH(^!_^bYgo%M3VWO3)(FEYEiQU!#&#Kfa!dk z2YOn>Qk?#SUU6&}i16NqG_fjt|MD5>C%g zGX=|f!FQR#xu+KcNV%*R!O*g*7k@~ptQSc4?zjNmtyr$Q{+GR4{&a6l+g)}jAC4^Z zm!zO9cto6_z}c&~4MxSu-<}izfwNv^Wjok|-YIe@kaEzZXV`wk>}NVEO~Dn~RR3tb z=SFYA-4`Du%RAcY-A!DYg3#tbp>mRe+jfvSUE%K{ahU6Ni*s5&0L8UVfLLsjM=ZD8d#%ey!QG+V1)xpi$}q!O4KyZ> zuiKZ~#3Wb*fVp0wne7q~$GeQ=&16e(m#$0zTJx^NUEDYLrfvA+zank#NOS*wts_r7 z8uL&6#Xsv6rT@=01pk(P|DV@7Y9EWF?CjKyO-#(qK5lxRD-Te>;9%|@YVx9cM1^= z1_9AHDOqv!#VCYDJJpxz8;3z1qpEYfM>^~07*m-SnWm`icxHJkiN)qTo+AkRUiFfZ zI)%PH>n6;Si5vp==Yi6kx>t0_kcr-}&L4&1OkeW;f@r}WH7VCBZX#(fa-x&2bdQ?z z+#Th4Z_|uIdGDC`{wS&2f^v4z= zyN}gx|5dP1rK#gND~a_sfTt@N&HzUZgaX?9R)mt(R>ikMLdVg&ISZ#q?0tkRP!jtpBG5^W$461jPw{19Y%QJ7^XY=^`S0fDJ4Eho zS)_xW#&oc)j}>RJ3Be+^{Lm99h*_hLl{PFtlGe8XU@Ulh%)*h}r&fZoJJzrdd-9C=h1Uw&)f-vX8e|{Ry zL-r)|Ubxd+&1OG1lt^ysTi-DU2{gp+8ylrlJVown_t1dF{SWhz&EW(uG-1W0hF$uq zl8e4=qem(5l_l8Xdn{iu$SiWVy8Xy=U2}&DcJN9x`_9M@S9OH;#o==obGWI;;KF{> z2?@oDf~WPedkCgpg{DOEws_awls2cEDdSW>-T7&>E@lEi->d>4K)Ts>QKK`FPZWMH z%&cn?ZN}zux+GP|(idb78uJk?&RD<@TdUOJ(s9eBwRy>^yICTmS&-3N1A_PqxPq z@u6-jhX>gCDSr|JEP9Gj1oNI&dlk1B%U~(_-A(8qCV~tI;=!KyY&?ZqJ}B5P!s*w6 zX*Mh@lTKc@*Y)-cN1jpay{ITtM)~C;Mj}1=AbbW`RL&O!U2p;cK?{D$wRB)fkCZTL zg?cZ9CRFoIC~K8EN9A|bU$(j&oR!Arit#_6IJW=Y6gYSd&?n}P_ zHD4wRb!b**K;GomrER5Avuyvw>iC#a7CX#ZZpKJ=d=#1VOJ6ZC^7TZK)O^V{t@!G7 zZK_{{uJy)&A3eT`KG6KsT=tU|*}5`2!@QlUcT8T>=V;5!i4==pnb|B*q;<)iKaKg{ z{evAq4X``JzG%G7<@t-#F238am`&OVj!Go#mA@Jtm~hRxJck*6F`BgRwvM_Tvo@CE zjD?=-8oQ#7fI7)~S8~6*Y|(|jtd}QUA_tz zl%1ndVa=HD(h9%7e+M#(GHz7Fb zL&1|nOQ#g!qat|GK@yQHupeNXzz^q7V&!cMT9EfOq1j{D1!ZCOLR=9q_tZUH8G81% zW1i(u&nx&EbSQONfkGfX7$72*B|pd==dd#+)dM9Y!Sj=f;3h;Y&3&LR`^V2v`^**`O8F?$vPglB!(Q< zxg6G+&Tq3=H$zd{CIRY=!EoxjXM34=|IuDm+)|lXmU{h_$+BDE@3~CZ`{Ogp_Xu}F zYyP?Tc(G5h91JJQ*V^Xvv-+%|@a=U)t=&BPpDi+Ox)PLcVlg5`1lwHHdxxf753S((uinOrM;S92p5B-` z+$2t64fdjp17B2Eu)onrs$ae#i&K;GhGax2msmKNw1*v>%HhMPJad5$rUuKbv@IaO z6)#s+v{Hv^igJL}MU`k$wRf7?Jp1X+h0ZR=2twVB`<;Nrnvo5>Db{@B{@--+pyTel zSz$zT5H8q-s}@8JaI97_12l9eZdk$PDdo3IJAB$a==r1-6<@uj9O8V4M|Bgb-SUZ= z$uU#kSf-T<(M8!@8(7FZ^oL-B>s|RX7@?T~9j3KWHNvc(z2k&#UKINF?%S~N8;0^; zR$_ki(Wuzv=kehkOPZV^WvAeQBtW^qj|BTZh##cLPah=KXXKnZMK`V{XDR(tY+YYa z?1rGMGx-kJDs{ddqv%<>0&-v;Ezw4(Tw6y7^d5$IxcDw9 z^wvwYUK;3`Gn*MT)-A1LiVM@2o7?yjBT{_gEemm_JVv!&=`nm9(8oFd3g4l2lf3f} zZ;I>#zN-HT_{zAM+yAS}pti0!r;PSitlMO#1H0IbkY7<*%Mf9X+1ZN*4suR}BdTG>Ir^Y!qZaK|VeqPGMQQ0Lpc-eGnMZbR4a{X;>6 zctL_!66lMQ-p}~XeVCW7NyudJL%R&z^DCIkIRA9d{y;b4Tl_}Ub{>Gkc$+!ura)fK z9HVJODOlM$6HkayE|lv1SnXwB{mD8Fy{@`P4_n*9>&NL2EGSn6%M>MUo03HB$S*Q}j8DA+7DwCaXfmwH`a3z{Y!EqMdW z^F5{P{3Hu>=LxlbUxUax9H&h7NJ&P9gPTv)wGOrByMhPWn`S8T?@<2=u1QI{Ae9ep zO#e@D<3FS3|CJl{Ke!R=A8tfcp);X>gtY2!@-5ULay#LHid16^558MgXe;W8Gy31T z(TkflpPdGkGI6<+*zz*F(@}tS24Ow5|Wu+YKZ4 z%aTyP5hO{4LMni#%x}V0$p^h>=&FOtiw7}rf|3?~f+c>T9$y{Qd)1M3<|P&F$!j88 z+$eQ6m>H{Vht#eaB#>GZD_o~oVh~MGO#GtATy_UTRGurBmn&}(w>*zI9842#)apu% zc!@5zWaU4|k^O@lKXX7Y8~!VPGa`%|KUTs1=kTj&?)7i@{lB#xQN>1r?jLO*Wn{eB znRAB0D)~yMSaiASmiG^QMLS<<{$1Ot8vg1}`1|}>P4s=gzW)q?Im$cJQe`Ur>D$^g zOMzIwJ_;-$Ef(jPO`55+K&?KX?@$~KRwm#iV-W{H&bf+xe_03L@k)nmWzLt=7&vZv{xsyN7lkT#=w9t(NK#&K^4G@`wzserS8~=rQL*>t~N4 zKfKoc{qZG7?XE)}^=`@)EDYWG7wdZ@*4_9<+86uDO-y^xu&8}1u~Q;3sF(-M!D?WO zdZv0vj5Xi;)sTc2ahi0_E94}-C-3|sZBo%1P5gKTPytO`l5d<12~a`~ZZ0OsQaVls z66Hv7g7OA*(?8iqT{LdH`^i=Jx6Vv5hJ4AcZoBq+6XSUVZ^yOTXx=ok^rWvsj!GRAh&%>M!)yZ$~}_ zU%vds8=+>y(#vI~47NeV9p*BDkclx@-!TlchtXGbB&dk^I%MX zn!$ObRmLHtT=riyufp@F=9>q8AFc(NSq*)S(W9~7FKQ;c;Tq>K*H>Gz?QKxkOWzZj zzQH?jH4&R=Z=d*qr(F%swIq=8c5S-ylX)tt)ZyUY#wt9=U3WjmW0nhg8)$M0A`6u> z=3z^r9~><{T;ZA@8ii6Ao|m6oMpElj4lz*lKCN!1Ljt1X@YZT z0%SP{!(9fuh3C*!$kcViSJ+?lN0(W$b5u#C3(Z)^G}kfC3*pIf8bWECOL?Y8t$-hK zc!T;qH5Wz`!Ll6tm|>p-pmDTDowrsV)K{;2BmXp~%69a6`E2a|lh;je#z|`sIDq%{ z-KCG0$|-i+x$&p_+F)S}eA)~v%1*ae51pCSduM2R2eDV-$nKuqeV9R+Q`gtyV7sB* z7eZi$nxDD(YETQq0e4Z^9RcN#4JfZ7L6EB5KFWO;^$Qo8$NmqpV};yC_g;>o%ZDE^ zB{K3KLUf=mDRXPK8sUb|okzrYUm+rX9O5A2_gFaHN%HypJ#q-wh0H3KwV3M3mLs7i z6|&`rMd|2lkeT_lU|xaQEHr%S7pMSMukT0bCdg)uh#S36QgcmLOVo2H{h!d^e>^I` zpf#4bI|vu>I-(sqP7iI84nItfZx-YPd>5(Ec&&4Zmi60j+@WI)pM_ond90Mhue5_c z*)YmnyRRgNb+przcqwA=s#+&xZJN~scxW*sxE)lwsDF^P5XN-2h&Dy=-w$w4FUjD9 z|GRf01F4emk8Kcq*oNAF$~H8d{?$K``^PfgsO0NOD>2Z6NFqs0dTlYoX@XL|oAe{0 zMGgAZ;|-~f!f}889boiCH(CMT`Rz|o5`0vH&`7-{Cehc@usGR!)3%bor^}89gOiS% zkiZsP5g2ZAD^;?XkCGq+9ym?_tpI@t0=X;@KLKAAkViXO*YOvCa@|Jc(n| zgQCR)Yn>WZ#CeQAN%vtHDNY?^txA5}$rBo{l(US>T<#y1!8n{Ozd8Jz7^3*7sn}*q z>8XYTY};K%sbd7x?c%xU@@A_j_!pkZa01C&^xtLktr5`7-5+(@CBF^2EJRZe3e!+3 z*8wd~h{EZPvxg4tj7Jn~6tCFuCGmb=@ff^+D|(5CZkGXtS*k?mIUlzo`J@b^>CkED zsZHoaLcPAP3+2bCg~hny54aUNN9DaTOI4Z@G~*G?Md=I@${)2v$q=fMyxdxjh=3*% zq2&)pv*mvB119DI_8LExxF!n@w%wH*2Ig^Qm)@-4gqX8-lPdHdkQ7y#0ljUu#cFk% zwAtTCOxgFD-Up<-QLG#jSrl}b9-?C?BV=9g*-dp+F^TIIOXz-p zEUZwlfk>K$2y}`O7{@>pezrWm3t;^FYED~RA(*+{4<@-SuB> z;~(D#>y4{W;WN}+WYrd|a$kz>*S-F-T?87%tP%6LF2`9$6c9`z*46m+O|Y-XAbgl* zK+^7VVfa|CV3NGWgI<@w;cA2B!++UDn)Y0LuRfvm7x|rR5G^6yg)PmIbbhJvS1>^A zCjNY7+Z5C#S~rnf?WNGeqTZlix3FxB@Q&@sV>Z0NAI0Z>v8sBBKVNGP4+#F;#Z%j< zSZfyAbjSwOSj2vd1P2Sp1vFSRD&({)Y{S^sQ2O2~gv~l$xN_Siw&9iS_eX1Q*85I6 z(@2SN3{x~!Bp$M>hm*z@qHH(w2Pkpi4Ink@`~Oz(2WIRDx8&gk=g72@aSw*yj0Xf- zNr^`&lcS#u0Y2G#4*EJvhLXq*T4-NLjrIIM+oG%v24R?~_XE|nW}{RH_4?*%M{P>O7knM& z*{3`pe+L~h1S(t{**Ut3PEUiPua%}hvokpM7U3nb`P>^nmT$TpS}Dp01m2{>z(R9S z6{+}zi6le=zmuAgGJ`b$p19pqzhqtg4}gBu%7zm}x8jX2E!f}fTd))KCfmzLcj*997%#I&m*7;A+{C_ufDty4%{9i6Q z8k5!?K87_9zB|Zu7B9om=X}QE8aaZ`4Ev4@12t!3mB_oKzJPqOHdi2N&6e=%GeV!3 z)1WTNH6@c51QC++PtDpum_*+Ep+E1BkCw!Lmo~cso{)r%rlAJi;H<~Ad7@l#Zg?E+ zaCt1gFtHUD#C$@Q1I)M0q6glsjG*wnr6Bb+WEUFR$uXbAt%dK;pPoXmJ3(!_6Ax?3 zH4YbYX*sf*;ZG`977~(eE@a1CurT0CNu_20$}%=J0g3MCW$>L2amA%JGv2L#OmFUy#p1>zv*K${Y%rq=uD3 z$$qqZiWKUG-{QkxQx(`hv6MZdgU1XzfR&(4WCC}?OyJ>rYpn#hKE9vwv+0o2*lNoU z45?*FSS>q(K}66%KzNR6;5I1TUn_)f#fPj(zm@VU+gwa(h70jlGxQ2GE*zgHnsP_{ zgJg6VDLrA>M3vL+3WoltOkQxtru~yfK9?Tn5 z;+)_YC$P$%iM$7bIaNSdZJ3yL^$StNq_n^I3F83ZX^8mw=nJ zDn$)OVatvG0?-d3KRd+HnKxJ(X8H-X{I)Qv*8ktqc7=Jjl0pAW(?WoN_-7F3|Dh@R z|9e97zrm^O;^<`V;`Z%d@u{J!h9!mdmZ8hs0G$CVevP3%XRd>%tloic92&0Us*1_IgDaZBT^iuDz zrhBsk)@VB=kc%QSUbrR@>)Ay5Gf%jGup6`u9)}Y`7z$up8X%Rtrwss){NWiyq!hvf z(}ucan1<{E#MIQ?db1%xb(Q+Rpti?lxfz~a*=jG6U|*{euJXwUnNN1Nl&ifbRs%2F zQYG?8EM+Ka_f{_woNuEl$$)HrTvzl!AO=!s!txRrRx zFH@m)6?y2${tBInbqBFbN3dd^A8ie#@kBYpF$rML>%<^pZtfBc7Dn6-Wu*0T48mf5 z(c5b=Ba0oyT8sG3bC1mDf>RVhue_Xj+d0&yp=W9}t=_L{reL-0zLwh|nIDHe>i=cr zsoIn|^Ju^UlwOkvjL8I$M-J-K>*ZVNP->0oz@qauaTYId0&T^*RV4^>;)pAYALVl0 z>pfosQfPT@*}QAg7M>iG{`fQOX1+5PNG9!dRd|!OoX- zPk#@8Vo*@lc8z3$&C&f^nAh0KFG^J%Eg&%KIHXMCyip6GWS{UW{Zf*m9o4vFIBoW( zZ*E$U2-ammypS+`K)Bxv`ty@1;FcP=ujCvdG^p^#?!VJ*#obl`qqT;%6x=D^jov&J z?8l4$m-89&EWb1A4D+sTQ-;ePt4d`h?C1shN5H??{-*f!tNp8wI{b54niwK)qn8mPN~@faqI^T+9={YwC$26YKPqP34#9*rD1VZ0P&70nBO>?uE%%S|TE#qI?v zAMBmW=ni1`)xavFaEwTL)N_p`=go5{PV+H#@r(cAb6Kqj;}Ibb5Z5WrfqUe`dh}U(fsTAJ6*ZJW zeJf_(COC+w7Do9w7+N?Kg*Xajk$6XeTfN1x#Qd)Tz?pL^Z3Qs|gs?aSg#LdNn*XEp zM&9_Fqr2OGCpa5*5slO(W~wh9+6>v!L-d%3<38eKNEFh=5Q-seBN3AAnD0iQF^E6{ zo^;{gy4Pkst{TdakkQTgXoJY>`i>IU9`2o&e+3ty-^%?R4GtjN-rt$q+n)^FJ>50j z-8)ZCxX&A1CL@&fPGAM5U;Iil_{P zMHGcWM!>-UlV!|F&za<>cxhwWQd!CLSyvG?C1nY#r)jT9YlW10%+Fg6)wF z!bDUg<5>nP8kbr_AmvHj;;-NL&DTuK7s6}=8C8Yp|7M~% zAq$F%xWve3qC8<1*OzqqM%EtGh(QBhM6aZ7N!X$bszBsIvny=P1bCoSc_1_T)4LnW zIT1#?W4H_Spulh^C~%{@v-dFexzMXLqpvB}j)O0ZJTV%xjNnCZd-P#cg4z);NLy03 z1cUw}dSLJiU*&q7Y;^iWJk$4VBD^VHq4j`aV$t|zue70jelmO`ix(Kq&d=5-0)n%t zPVj=(_hKv~ykoY$1>qtX6b7b-d#7(<2L+&Y$X?<12q79!dj)SP1T`aUP)_f@z;>1pnJAXM4Jd=b7P?@@wzCwola z!VNM+^e0~u6BgVR{*AyBD4C0i03~CDMlrO#8TgFah=IrtBLia)WEO-KL@7GkLZHn3nPH&vVXO{etV1HjZPpsmAR$-L);&z;)n2w`bcgnb_*fs z4Q`VA5h57XjD$Q2fA#s31&fUdIKS5^ml9}WqdV6|g2lw2C-D89UJu_Yf}!^SYo38F z%dWA6GekEtqZs~R5*4r>3c#LR}+UMh!vRlo)bmHk{D>Pjt^ix zVy&yARG;187s8TEp*oYvSz1A}%D_Y5R$aZAvo;3QGc2$7Qo(8dYLWta4L1J@>77>y zY-&Qg8GnwoKl3qCI7+?~X0hTd*Ue0AY6|(P{QmtVA_{sGDpVmbB{X!FY&c0C0ew6NdX~nNOummgZa~m zm2Y%%ite_2$5`&LYf~$88*8FAS}a!#!s&H+L<$}}%erljJYTj0 zxBJKmVdxQ3Fmv%Yg#A$F7C#^TqT6M){c}-8(CJO0zdN%#@zkb z_-Evs{*Q)LvOuShjXPy{!C%VA)dIBgZ`oJ~%yxEpj8=eV3AyuT#Px+(k!e!6Hj5S4=^O#F%LP;}him|7vT}kl_nVRlb@OU8A z&#f!GBhS%W8KCGWRlXtB49@8u=~|37H50xe;amd+)>mG(mX=P&AVe%^%hq#DF8uXK z|2m3U`JbE`=gLstOCBNcsNvFM^e!T~q%)D%lLI??W|2?aGS2;95fx$zvD8_{4bbUC zZ=L-X(2isFu_u2m{BaVqvLnwjlX_V#utW>(z%?)l^V$C9)q|YVa|kCiGa9=C3rD=S zAL?71ihFIs%)DJ>U@-9Nm2s9MBqJ^qoa*z0_Bb#~k3ff5jsUuWViwAvKq0r`AvV5> zHxP`}@_Dj?d4%m^eFQRp2B+cr7txwN<#cFEvN97(VWDwm6YuV0O81JN?IwCfr!L+M z8wiHN6({u1cKGrhr;7mC5l;|eDAOb=8=eT5g<*jF)>N2+rBsH@5kOE{?E*n1aqgeUvLh z|A+vW__mu5`Pn|r{h&FU=v`6AsX;eg8$d;0% zm2Kw>@5b@|;_c^-7fJub)J^#vM-d}l*r}?yj_A#c{Z;83LM(}44kv2sRmIw1?Y8iJ zCX)z^H3h#1v^6>C2bIlN7(VL(Xc$!0+ZyrLXzhPwh?BV3I`&Gc^M&=T1@{!*?H!Zj zilRr2qb*7@XF%l*aDOgoq-KqpT{L}&kWK9sC}~JB%sl-gwe0dkj;4NBa9rV|yd*yV zBS_C1h11R9-kDp3L7ruo0znVf1Mo1!Ge15wsW?z6{5ffh-Ns*Wwk!AGe~A*zCc3ZE z74-OH{1&y%Thx|ikRgIUUjP;j2p4*~Xom%zs?Y^|wCOQH~LVr7L` zzcwe4_=Tc!-zf2~na4{5Y*43pwSI9c7Rdmrh6D!BrTI#BO>t9Nn;wrRE>(T!9meo( ztfI?J+wmN;b#cpATg%BEWG4}mtt4qN<6D=(av?>?jjk0B& ze{&^{A(_x)%Gpv)x+^sNYYkGacTw%&TS@4<{>0Q+Q(^}(QKLBPltA&_3cFN24418+ zAr?to&rbLEJ2R%f%SBl;2yE28hLkb#(in<5g&uSX)}E?JW!k37>bI+xdqjM+ef<5j z$3oLg=;KsC`*!b&RYsWZj)wKR(flK=m@Qerd!S_5I)t4pS|K`K^7$>XKDUmt^dg~g zbUxW*E3iB6=G8Xw)J(ZU5=fW=80;a2d`g1x-&!d zIWxUyqh5`)j)d>1(9*n1)mV+@K{R*bg_fIwg59Zs!==+v$RA~0@h5jXTdxEEW;^}~ zi@^wuiid&8$j@$!Yla?I7`A$akNOig?LYUmCfJU~Rb)1gJzJ~R_M2Sxo5=kKrAJ#@ zXyhI2GJyfnZ&{OW&P?>4=J_`}j|>_Yve5fQ)vSx6qx#Ou1{XVSjE>>-pFl13J8>q9 z+7Y&6MSjxDJ>K{5V^6!dHsQ8eVtS_pA7w&li@fxDrmF zQM>;B;fqPudpmpNuIRmg)@%`N=xvn2-iJS(Ct{(lCMX5&tbmbhzMbPZG>z~pHVmyZ zcyP9|zbIZUCu`P__;_wvC%_5bBn?$WHG8Bf})?yj;yc(LNm@^|}p6n+=@ zEBmFLD^&3a{@m_QHDp=l&ONqQpnGr=V`5L{RSKgm&ztq*;2-SkVhra}&ZBUnE3OW) z-Ny%}jxcs$2P*MW??}=QXapa=iEJ-pilDP6G{Jfa^%dJh=tia~hfS#oA7__Ba;e_I ztB8c#W5~TD__*6?;*sfN`fkdw97HJ9sW~0!X6RTbBupvHW!QR9_BVYa^^?d*QPH9n zTntO=75%NUBtbtu3Usg2S2%%0MAeg5#0(*oTOW@9i?z23s_R+zc0&RLch}(V?(Qyg z;_mJa2?_4*791w-?o8a>-QAt!@Lzj>=j^rX)OWS2#?2gEHLu?4?zhM9dHP3unrYbi zG*oGZQSH1mTSDu%j+xV2!O#1GT4|YWNc)~`-}2GXj?%Q!&g8yBI{OW;_OJ`64BhyI zPH>`!De5Nm^FF$#!cvK^K|A5^p|a)rH^YSvv%^U{L(qr_ zxjBr>azmcKAjIEIl8F8N?0sw?`s3Y(dZFv*_Dd79%3mbw`%5FxA2!H)gKy=3;YRN_ zx5WLB%P}=uV3F{Hpt-i6IO9I4#K9oLAipWx`8SF4zLBz~G0G>C*J_3z4MT_W1L?hM z;HGtg`Y@l;vtR?A?c;{TW|Rg?8o*D z^deu8b+U9UDL=u|5WdtIKVhqW4%hnegi9fZGvPgh%xl;!o-E&WApCib75Ob#omAco z`b-4wJb2WoYNl-Vk`E|cyG@PB@Y9`6^TxW|f+_M_SLJh1se`{(tAX|RhTIkvZgHs0 zG|Q8WTU-|vtt|CNBuq2ozF#23oKD*^192osjP88Err!Hm! zgVn_tcddtmQbjv~_D6`bslkbXg3M{(YlJ-rp-j@0FM9X+9PHYhh1BM%tjW-Rr^&eH zL#Lq_!Y&nyagLdUNyEAp4LTjjuBPcQP!XB))hV^JO*Uj|O+kgcqC0~nrH42;MX;P! zkS_3pzPn|`qAt3LW4tW#=rc8TD1ION`)I#u*0#=SE{u)f`q~N2I`t@(e;JZ{8Ipe~ z_4`sP?@}uFvW&za@~1Hi)r5)sUJ7i+k{|dPy2&lrmPUkw%}eLT(a?HAJBrhk@vM45X5!f2bd7lJv!^d^C8AL z?NP1pi)Aw8!$;0LETM3f5WA(j3Jy$(3 zSD`+cn{cUhL5^rz!bk+Far{VUx<}<+OF2nc1X;!IB&bk(K^9ynk(nD17xLp9S*BAu2|;r`DC$&VC~RC= z2n!H#drHa-@@t($iOlaZ3nViE@r9dmbs@A!9DEd(l+c*@y@|htyo8>uL85a>GsF5( zb!V2REN31J5v6M3Ym|SQ&dS!5f`wQn_O=&HAos}zU0BjKejmgB$vJ!F8pv(-I}5n~ zVY?}P$}(cMdD()v`4nKDb}-4#HXb=XWu&ESXYSr}Bs**I2Xml2Ks!gqO)QxS-bF}; zQCYUO+A_3vi7@t@jpYjkDEhZ0XfRmgfnGtk8wnM=7Inwiy}dbc96O~hX$P)RvfM-?;@-BbIo%E&e@U?>u7je|$Onuy z0d`x%$Z8kXosj8UzY%xh-QJIRP{DsmlZ;8EKDYw#|VvjDX>tzMG$Ca zna=a%9U(#!Zy(5?_W6irq{6}IU|gB!NypMGEiom|0*3Jo zo!^rFYbl01N1&~j&h?tw%~d(yV*KEOa2ta|2AM-K*(HP2#zrc?J{&_bzaTGVOh)Q( z62Cr5!eDX#-nAEt*PH2)#qch^$xXdC4%k-{!OTj{u|uF{jI|-xF`n0j^%?#uyW*U~ zbA6#Pz^buP@2a%ooNUR?<`tHxzTRrtF{)6Ztov5hDgbvy21IZQfv62XDq&YzEv(af zQ|&JoFxnuy0RNtbq*E_a&NVUgJAvB0lEiEsF1}vsT$D*|wKSZU{;r-7v^Q(y@BW2P zJ+6IOD(Oy2`!g%|U4x#4=ZjNr_bdLb+XJ_}tJ$yf zG}4ZUyF=M8l#?@FO~bH z1X?=;Ji=QW?x<;ys;zUB4C++Hp9$?A5aS1Fx%DSiT;PZp%fV_FjUoMUD5!`^;G}{Z zJU5AAlL&iQ$vcE*uu29N&c$<*Dz3Cs6Z~~pXq@!*G461)v{ZqaL;VSNxVT^O)h}b& zM8GtahVsC*oc$*K?Ksu3ChM%8W!C09TSre$kcaeaLKCiijr@REZZm5Xu;@Dy3@Z?T^*p?= z3fVAi+Xzst1R$n366o3BHE*3 zl&5&0Kx=&V%pB0M(~#xj-L%GL>^xcSg7x}WXNk6fnav2@)IDTM%bOX_Vo}BRtR^WZ z|EpC_m1z?2Rd<$cD93L4FpVgJ+W^^EdxjUnLBad|+mGn9IwXGcXreR7v=B633~Z{j z<-0KOo!!r#h4y)Kw1LRFcrEwDy&0)QAvOOJC8|koKbr+3$bB}rjc-x*HM3j1^LTjV zi&OA#i6gH}1N-mT=j~P5imc$?Ihj%!cVmhMp7hP)XP;zDWG08hB)(o-Ok841 zb{dW+`IBl5xPii+8MDu)4Cq>gchxeiVG7AK<@yhX!dEr6*rFV#b=`zaqml;WU)yq$;=`9dd*RrzR4J~&1Z)ALsxNsa@gt(ktd*w z?(|9OMzbO$v*LM=pdyA}kxzAEKHRK>Qysb7aUpq_V#TUfrcIO6 z27h1moY(7@dkBJ!$1vwP)N*A9Ns1Nm$o`5(t=LzuJjOkl7nK`~bta|xkkQ#YryJJ} zVC9U(aNQlnjctcmc5x2vyZpeAY{`ii) zSA?hZ1|?BSQ^evP;SRc2>65G^IOaxhc<-H6P4Jt~@Yj8A--RJ5vjkt!%4DUHh8r5M zxHSr{;o|-A8(iF^wzyZVJzpfLoRq5FTfOJJH~CKbuH>pA;=MBHgeqK0L6?2TUFPTD zX^l=B^-<)=(i<_8?6)CJdLhpAeJaV2w>fU&9PE+FD7PDUld`v&&>a`58$t3e4x%I> zWwQ}v2q9g_kTPU<{iRP@CkZO7wtX{yVE~a`$C2L;A}^w%jGy&PqiRQ%s5AB=1w++; z6wE9Oct#But7iGZ;xB!o-<*BIKa+_-J9bQ!IQF@=W{s_cF>aWBWIi2??(ejH_oG}= zk={QN>h>uAM3Zymk7N@(7AVUZ`m{Ih2|*`Lt09^D6H$^@Nk4oshqSxQ&BFe#qjglMj;MbLyrUcS9W_PU5 zH@%CXJ_LVfUm`ol)W~->L_NK-;9MTcy|VL<15&(!;8KTVf+9NXX(c1KiN^`vLmvx5 z{7O!73$i8YSC4!jWl>~)ipkAKEHkE4NqW_S3oh2}qHxGr%|X2K1W2+otggYLQr=cf zI@p?xmk*8oYWeK4^%@bM))}keDi05=+=42Es;%2vF3y?u<-}61m5T$_h5V8Tn>-;C zf%y%vxd*RpG|^m@;ds2BH&3(cP8F(NZ(`lf%{5iVyF&oOU9;i*}~H~<@KPQDXy_;W)N?T*9Q(0@CCHJ?fyKct&GpDQp@ z%qVU8D6Zi{hiOSD167RB5jKEP*V^pUrIH%76yjWm+8g z72iL#LUuM-=)ya!vN1Pi66a6EfJyl_6_LaVt-$oECh7#mHJB%uSh0iJ>a}rG84N}y zHIx3Gwh*uA_#v0!ihmao_@c2%x!$h;Haz#a`rsr|jpEn=?I%3iBHVm@Mot(+gB!Ug76}=?y$j*{CsT?`!meLMlI+&eP4z-dvIHK!E(myiI?b*f zuleGdvaSvRDla2F1+`X`IqNL`TmZOz-Q`a@q!Ny2L6tW_!@%QUUMm5A%KWSrS<1Ya z3XM46$~~A0t6{QAE<<8M_iaORs$`+=8lqz#NT|gQp=fvxKN4c+CQ$IBIM3aK_lNxD5JJ7WM z&Rf+y@W=B;zEEG-toFWzz$DKQc(&Ve|AkKi^4?9;V9dz?&K%sCqti9G*w!eVg*<>Z z6-6oC)5kMt`I9UXSi+vX!PpbGm}Y=AS9$L-o|tOgNW$ zmC>JdxCLS3;wjTq0!VGkwog4{N;)j<>{l~!D*9H4n%XaQBQXulp0||v$65Wujn$$ z%CuA?=8Isb)OC{*o(e>0Kbm8>;9NzV2#e=vraid}Dc9LEa)=ntW`rbNy%Q}ad6`Gi zvjfuc)Y=W8{ zeHs!wgeg_Ty?mz&>1sMz-))jPN%oT!kW=)~KW$S12pl{I_dne;C0-(VlN%_4WNgjWX)?shHEk zVb;`-9~Gt#u{LJ=ao<%++c@3r4?8FcUxz@}b^I%e$Bc7w>pkR{HIi_$?Wj1d!0NBE z;8B+vAUL7PzqOg7w$=-wPqAz*H55Jh@J}PmT=vopj&1PkyKx?s^^^|405LuN^LZ+u z-E>9gBZ(3-C5V#0jgb}HI=9(Pxxt9Y9LlC#=7lvrvP`B;#>?#yx`KVAbcn1X1m~kaC5O0&us-|dfqK)S6x2^1&{CwwNT{fIP{UW|aWP*OG)mV?SR6TMdVdcrLw z)=u*8X<@_&Iqxb1E~_M|-@d1Eo_8GXw;b{xZp^;E4}O5n^7N-iU^hY<9{JtiU|d34 zd+VViY0@&1VxwdduSNIsDVszrzUtvF<9~(OPb=x(etm@5QC<|LL1}^>biJ_F`hcec z`-oW^&KCRyX+Nw|xzUW8PP6CiUFCt=l2{qrDy5txCZ#hkayz)LlV?N~qtqdcQ{R{j zUmCoMj*{bAaFKItwu|I$7vUEiSN)k-5q!8Ui7P zb=_e>RXxYKdgyA);3Ld#_y303_jQcNli!(d7w_SnFAqN(w+04(d7({{3 zEfRa~7F-(r8frVc4Y+OklP@$N)Ufnx(bC&KF_tk>Beg(>66*O*IBrl@!A2Y#JBayrR0#X$v>SvtV`E6(IG8CnmWgvbeGaWr` zU7f`^^Jif6;Le4_%eYVOuex*!_;3n+|Ne^9-5(y!ZhtZ~WQ5hkK6b3^q$8#%1?Pnb zg?Nil`t?IMfsBjR;u|HR_lWn)sKmI;6gafU= zT;bkq{jVZ6`yet}{~Wu#(G7$eEGH85nO;ToUE}TDzj2Bkb2s)h_{f2*t3=uu{ zA@au2y5ioHQ2dwzhHWl^A5!c%Mb1e`o4b^o$O<)7Yg3UuN(H*{tH$CFCtbqz*gIk+ zVK8on(65cFtT|a%-$G{^a2H-Slw|rof5FKP61y%19Zp9 z2a{^MbW?x$!KBJ8d@!jHh!N1qhOCi)3$vkkNw?<^&cjc-__cR?B#hXD4$2`>GM7tEF9xhYP{qs!b!rx}&iVP|7 z9JY)|D?RACt5<7k(prVltL$O{k=NZnd36EOd<>HG68Zv89cQt37AaFlz?lh5heN-#eu% zFz%qi)>pM4)Uy1np9b4ZM%*3=Gpc#tL(N$qvwbF74)=Ku*ZgkoddNOu39?N^G$G!V z?jvkWJ1u+~_?2F?G$4PHcO9mb{5Kxc3R`oXR{Gn8sKgPT7-lB>Gw!)C(Vbo6DF zB}T1a>s0zGhozg?FjPo9{O>Q8KQOp|=$w7Oc>Upn{QE`lFS^0?pvw2UL^0?DZrN{E zC^-Er?TRo6+gKaI;h*G;a2 z3vq1aW?cvwt@-_@|0tn5 zoe@J{nwdYJqz*(z0D4bt-cN#mktZEf39hU{&c~y2sQtw3{B}R@%f-u-HH}*P zWD;oBK9d?ro4ePg)_tyw!d`lR`vXchiv@hCW${-3)YD}bl}EIohih}PKY8SG|( zwqN$G@T|o!Aq&*Mwg1|l7X^sBCalGS$L*Kb>!FBqp2+5qd3V3^(N6e_`i>uMeRU&{ zG8@1p-YsE^W_wX8IlQpvBvIJ=GFJb%;d04y_{jH|=~HX)emhO|N!61j90y5qIv~KV zeni{}CMKMOF1T;!E>x2cvyX*@2)i#3g$nE_8cLO)+G`@}%O6hV7``n-l4;KUp^WZh zLx2-g6m2%eXr?rhc*tZe8!Im70SIOAx{40(dv2%Z-4dcDN0zo)$H>7@1{aYB&X|(s zl9ipjNw*~KQd-&6&n9u)gmV_Af?_+yWA)S-V6(`zt@0Du9&m0$^yGQ+PuJva!p)pi zdE&;g)r#_F(*W#6Eor<4z#}G({3G|c{@rNq*5_0@r2_@AS!;PE^96>_BoC+&t3+GE zd1i^E)u9uIMHm(G<@ZoDZkiZ z^2H;6Y*tPtnNW&!JeJ%N{k;i4II*(nYO0zgMU+JKmqi+q@C#aZj@!*_E?Kr<#u99} z_HRZ}hl*)+YQD)2YF1)Rn6f!7N}BqE0giMb;RG!1B zm{+xCbeu}qVWxx`)@b}VhxG%JI{?Otdz>4zZ`;B<6Yv&uB8X!S@zswXhR7*SFA;)O z+PFwXJTtb*$Fdy}+vbY*&`=#oA!yU`?hXVfT!LBFi9BjCaA>59Coq`uLDpCaJC7t7 zH#5ZuF6lMau-bHqdNdVG(AORb-%Op`^+(@=-Hg|b^#cP4$&Wm|;_rh;qrCWIlZa9k zvXND1t2VrFNc= zs|B)5iha4fugDo^IFKuCL&>dISvVH(P%5LGJmTcCz#RV(=cn)@N4e`y7bJ>)k!9TW zQ`w@!rfQbku{V22>rX@soGhr~nzF)mhLeV1n)_t6comSs1yVWOO(Yn%o+ed_i)t8B zpxzF|`nx$Hxt;@4u)eXNW49L3nlXDBqxkC6(AEwB+}-PWXj|bF7~Bv+PDco?iDfZ< zTY>PS5Vw+8|LMLn!S&@{F1>H~5w%%1;uCPDS=_dkt2%t4woDjlQM7){P4g0Wvta$x zc;Oxgq|jh>YCL9OI}iNW+_Lhny74|d)NLo#8vS*ZJ z)M2ikC7mNfhx{150qX}O&KkO<-b&-hj);yk0n=p;`I^(MvoDrsVpJviDb3i4ns&ce zQ9VQ|CgCr?9m7b__5F7VNr_1q)Oa3sePEE>^pO z5uKMce{6Al{&sl|4O*qCy4Q{EIP!98C|23BPpu^zM85&bTdx{z zh{(ou=v!E{kSS(qXON@Z(?|ULzF+jJntPBnrUbI(2X@sZIcPi7I}L@tjeQRs`!0(7 ziu>gZJ4X~*h499ISJ06_2R5_Q>z5 z<0JX|)Bd42fcI!+VO|NdtZxv{<%YJ}Jq}w1Do%n)tlg=)>&Wa)PlEw<(*bhVvtPzt z=wT}Ds&V}o)t)Lg-Q)A3!jcENB%aT)Zw?t$^(HQ|VHCQt|B+D8ytp~`IONO!vNfW^ zzmY3_w9xS%3xLvpV)FmrzK{QQ8vN5g_x#g8TY^8F2Kzz(avC&{Dh55;wNA~km&(9B z)%|}$19HqP5kKm*4{27X%fo6N)qkG`l^+l7WJhNbz%^GHiG+lI#S7(Tx^@*p=$~6HoGfx)8|TpT@fy$lN!k`y|I5^v z{@ziKL0hvE zS5No$W%4o{tIxJ(V_Rx%Z!ni8IuJjd<*6mH%vmhba^nR%)Lq0BhJ!FyacpbJ9eF(E zkQ^rO&MtU7mrHHFdhAm$Hh3FeE$pEUShu->lJxjVx3Op+U}uB{*%9#(_OxsyG>+n=6FLxwaQv zA^p{ny0`fPVHd2r*7%R9F`dw8*jxeKv}%Akr}?X?50Vh`-y@D-)PFi>xTJelj^T%o zYZ@w&9$2KX<&bVT!#t z>LC;@V^?C#B6WklzrUfGu^2ilFERL?Wicw3xFQ1di(#4X30#R{Wg3{4F{e?OlF~r; zDs~LW8~n&LnuoH7-r3a-xh=xxlNT(53#d%GtLCiMdgz}INfmm0**Cxqq1mEx=9Vmk zTvpJvLjUWG)4JhI<(lKur}@%PpCtbSwfkQi-41?OPxblv!%iQI@lnyZX`0Q35KJB8!-fMTO6e@koT}jLLsy!Amk0~zV>K9KRsc>b-I^L#fam%; z?~^SKX^)iXi4%7rOpojLYc3N4tA3B2UKguUL|^?`c9@88%6+%Nd&r5eWE4O0_T*$c z^Y(14-`OaBBQeaC_?8j>SNVp4V$-M>LdsE+CkRbZLL{tj z)ZDQ+qOD!Ie_ego$)zg7!prEJMrr2x4i7st-@dmI^`y%+kv`7Et(7T6!=0;B4z_Gd zLcG5HMn<;Z+S;YLgO8Vi{?UPi{zl9rmE)H+-){mjPPZa=1ZM|gM?7=mA=56+8Q5xv zsOr>CbYAMzg}u^T5mPRS88JnNI88GN*(U401OlUL;W63!_WB~Tz*evB(XuB`rkw7w zbz2G!Mb|pO9sdG2=C*fOx6l;ro;%x_O4*)uS}@3&LwrO1L?|kJw$zgp(?Yo>Ih?JO zJ0iTUlshEc1$K^~cA|JkX0EjxjP0EpcBnE=3eu7vMmzCl-B-*trJ)#YKZE>EyRVqP z=ZY=V2Y-0wi!C$@e|oHS7vITv#;~KufH^0^?Og2t1Eor z#hR;Y09-Zx>+6$J?Uu{;tgqPzi)zkaqSg-%R$=#|#4i-o{n!ATqQe#XodKH%JA55i zI3Bz|9wtpXwb4GtZYZzyvgu@Jp7oG(4oGP>mCUh$budo~MOAKTyj z{`}1NA>Ma&S1sS(J!a5QB ze`>GJVc3_3LF?%BRUmlN!!bHkgmEy&D1=pHp~DB|BfL>HKuy}i8;|xnvg;DZ^rxFc zW{6HZ!hgwG;OwGUAg~XsVmrNUc;TsOT&UJs9)+yuCrBr@g_}gGjA#Jkn$8dOMTObJ z_c_@WIhHiiVCeH{O$`6G6nQ#pbhPpHF7K>x^DZ}&Dd4E($Ky=Dtr(Xyn|RwAxtd!_ zr_2{E3>EN^3)7neiDB_W#AR8cNqAWO!UQi_0* zN)h;-@`nsJ&R&997?xNF?Ce4-V45O%bZ#u=U8-p|{3W8yc4-f6_Ji&jYAo4%dcX~0 z<=s>}rl@=SXVNzOYvL}C86C9Eyxf${l!BD)ylWW5YBp8_7Xl}UuIMJv6fvbT7Xe=c z5U&T0;-x(iWfeL(e=`t;MQi;!#mYzGX|CVK>aT1pGn)E!!p#e++5-U_S~r#PzV^csmm&EhzxG&|Cvbs6CUbD;zGw++=!Q|H!E~td5BD<+N;gOPydrhIr^$oA7)Zv?NVP_^qEaDQj_m^S-KOq1usQneY2eCDGk`LB zcBhFkeOMH$ILJUetRdWKHqgRs$s^|CLQ!B0meF^1O=9~GQ2?n61tR(vjRH3kTw#m} zGimx?a#lCqSjB-6BZVyrYK+x3c{zY)!g0%~8ZTF;y!ZZOLl?1vPB-HwydcmZkaSTs zvM1SF*PokmxdM0@^_JkW3?l-T<6x$Dk_&IAm4X(mEL{kYhM>OW49B5Dy+NZg1kf*-WjIjiZzc*_gq%VnF6t z>|3hex~Y^-H{aC-j1KoZFjOksrAIR#1Ws3?2I(net+#CjqN9spe0FQPB( z@!+t&#h)mL*B=V;BxkJfE6|rz)0-A$rY>bqQYc4r$)}$EVBGnlebqo2!kUt!uD3JG14U=9aeOgcHd`Z&6e`}i9#w*Vf#gbcD zLR9g2F;s+lzh8!(AZyD5)u4YGmH0SqNTbRoUez3`LgsLV!*LmQ)kMv>MJ7gKrV?)$nH8xEwVV>W zs{NnlQ67ajSakEG(RtON-xGR&_p_U-qegdABfdVjod?%*twyfCX^JOEBL>ir`%q68 zf@yeo^YD3)x1$kyteGhXX*%aPWuuJ|YiymJr*Z6sIHFuRCDW_1&3@UK4HQcK#d+t5 zKiyyQk7eN%kqqMyDV4SxCkeN{+akPn#sA3<@q7Fetc#)?j$dJ+29Oye-NZeSJMKY} zeS5U1WOjy+IAHgskyUyj#q&U+_}`*(^P&N4&(hk2u%!g=CXBc)$c z9;q4D(6UoS8$`&+lGnzGBRm`#UW#cml})8Q80i{vjvf)TaU_mq7#lXv`iq5==Q~+} zbj{@TZxv*TJ46?`CHtQ)J1hu8wwkAyFM)X+&WcM1EJc#cS5{HdDWWrG1D1iogzz>` z!Kcvz&J9n~tVN%i$n2)4K4$`*KhsE=!;-_8l<-%)MoPGt+vuo`77cY8xy{*};Z4Qg za0E~k^(w%K=&u)&&}kYF+uIScRyv<)S{2M}uoU*IYeh^6z%Ne!<{qvv+hB!8#7%8F ztzS1}onZCxFX5B}sHbN`=oZMP8xF2grWrCMMKvT1EX$fTs-=_J{hX9yrl@btU}#6D$Ee}0b+Axn zLtv+9hMw=7fs>?RX6;6;1$bemK<+qM>}F`$C(V2PF5U+ zlw%kL8tv)_MfqR?8siI&6UP`!-O6kg*-6w|bF7KVqRQ$^WeV+RXzkp~XBsh*IQf89 zCPsx(K}nogz?J^I8A>b&e8&IF1K`vJ**2>$i`S0?%K?Ha#)IXO5K}<3I!gGAA7cZn zb7t*`Dc78xkxWhZ_1mnStR{a7GNOuj5~3!qIe75D3eOq%frU#JZy%p_jqDF)#tEt{P=%UY>Xr6sAhB-bKGQkA?C|J!1 zJT^$rG|cKOHM56%x;huo*hDESU-8IUChfm|&@iO3MeMtm(l(g@><2+>AKMKNsx<+a4T46Z0ZD{qw0yvH4R>N4;`vF)4tNtg zhWqVfRBu0lGoN`^_GcLYMr{`;FLb@ImTOrDbTpW*K5c-Yob-8&#;=4s_FV^aFjNGD zBi}-zIXGeJ2Ew5YE;VkZ27+N^Wl_SZG06ZdvXMYA4hs--S3He&q$UZhSw~A-EkXm7 zETJC*mXs%f0q!Jip(6G(_ON9Vg(DMrvmxb>EBUzeLvN)l3Ruco_#FvCBzji}GajqS z5#IuJFar{1gVSCXV1E)<)qX6LNfo&XTl&M7#l`g%-OuVQBI@~(3|yOCWyYlUj~^3v zU;|zXHxP3W7DGZRapPx8|22qPL>~Ao>>gVwYglNj48{OCHgZCW)o{=fi&HpIFF7xW zc9_G=a|5T!sFINLMX?BDrk+Q`L=yAySOEKA^3bMmD^UC(o;ntZ*0B{qD@pEc0Eu4e zljYg(y8;byDk>V6eP6HL;bXE^#%qreAJfIn|VIyTF6DoeiI|W8pQ<=EU=?5-gUa5h1u5c z2WmDr11_JQAp-b?;TL7t-h(@eYhzeYk;6lVu6K;Yc+G zW;r#RxnVK*hou!DZei7oI!V6E8JikXf_ja;`H+ly9mfIbhg{Yf3L+qwEN_;Ah$7cZ z9y3M_@`lZI40TYH*Qb@rEaro1pOq|KJ{!e)x)e2cd;X5Q`+WCegDFnIQt zlxU}O>GT0_vIx#$De6H+{YBJ?%~m5RadP1yyzQc=o}6N3`Lz+cJBuJsKzp!yJ>@zt z0DQWGm;st6RiJC=Hf3+$mC|M)rP@QToNqyR42wTTPN)*g4Gg8?urE!_ zyt)~6+UjQbr0!=ZH)-s#@od;R6~pvjWn^>#*H^k;42Hm!P7{&d|4{(>{foGdt@k-A78joRyS_s zPOzi^HhL$-QLMTqvn;ZN^S^y@PVfy`^A^nvlV+SBzn^7;YdCd#zT*O}ug^}(2~xX< zO#-fiQcJ^yLWMv(N}sdtG(b=31ixe#o+tN$!he*A88TDYtqoeGEFX-@v20negJJkv2Vz*kW-+DJFXojtNo+EumnrHlW_dYaHKBVQ4#V+C{V= zNAQvq*1JQNb-JI1GM@3xbvbvzo5VEwoHWeoeZV<|{A(G#|FNiflT`Y153m(QqDI9g zs$CIvrbt&bg=sHqr62;OBchFOmsT?k^rLF$-_jDBVZ*0rF9)Q#)_l48)%kA7?H)%Lc=Z~ zufge)?lJ3BH6=TLQ?x6yzA<}wVZ0S*6N;oGUDv$OZhM*hSd`D=Rk6nEx^V-brhjnJ z-~G%)GlH-yfLJT7A01BRmudK^r111Y3er~JZ)joJ2y!Yv`WLeJZmc~}ck>OO+y~Xb zk8WxFE9PiC*0?h&41Jz^7H z#WPqYiaqtK7le7xbOYtZIgt-n14T^ z1j-}7;LuoI{U*LC6+_PKIF-WM6pE)Dx3B-PG5z;d@M0+6C-#A55QEqYWjrCG?~Hf| z;f!_U!7tJkVkL({he7+ ze|M_Af{5$Nm=*guU3$d}@EbsRtyiVc+tvik_*_AxJ-TP0j-Nisw6=(Xa(A&#qCKlD$Te~+MUcd;@bDA5rVt2 zQCo9YH=M3#bukA4zsY_WNokgiaugT*7?jG^Lf$_5LQ5t{xQ3{BHxIGizv#<@m|f-9 zh*9kYf3v;0E3nrbmaZ{tgn>cDB{$kaiWbHAo6B_ND^9lYc^}-f-Y?hMbYkM!icGi1 zWhjZxVF#XLooKR{k@%*HsEvFz?_v8+XcqOrX6c;8Eh6RMVZVebZyllTd6e(uWLQ&Yan@JitXw@d>P|1|e(reXS#|7C5nRZO<7oz(o1J8F!PZ>vV zD4-?1E0qfxcoy&$KKDu7nJt>)julb*c&0R$w^e*2k$vMb9bVk8gE*ICIWNoAex_Nz zE)~*vG1}}H)=bHrx}$*07b+{YEUt8)#8eUdq)$%=G8ks6d(-M8(D^QMhNdxJ4A( zd4uehDGsQ7)U#uK1*KAH@!)Gaz|UuB;j&UYZPfg#=X&9idG4>VC1bGh79<#vZr?sn znS=x|$j}MUwIiX%WMM7{iqv4hk5{?3-4#~nrp4lEt$pN`%$?ql*?yPqz>*H&IY*re z?w$O3B|N^XS1Ne}fAE*-UN_i~y(QWV+f%*fE3z{>*~c$*0%ety^gp-z>?lWHf|R~5 zY9mtgEw$V!g|~88%GG~duu_GKW-#)oaFY{Z6V(_d^R+n)YcA>ntDnenr1UG1Ow3Um z>5FAu66?Td9Kk4;)J*am!FW-Z&f*z3R0a9E&5Nm~f5c8MHkEjK4l!%O`i^LY2JrI_ zmd;`L*{8v7L(VUsoP~4C6jRlXNP~PA>SBF^m*Jjuhw=8<@`N;wC+qfR<-T6kt_`K{ zu??i}-`Xya=2Xx#=GfVC2yT87!FKYmak~pJ?!FT8&o^bd^AmRG`>Ix4ZfkyM46-I% z@_r!mWpyXwGa%-N#dwS9kdu8B+59>_t*^BThZHIY(^0R_3pt|aPrcpm${`m5_{zvL zSsnkbtT_WKA;7fZc)`8i z@CSW&UIJ&vjUqV}2rPM=9#jbWt;E6PYTrA}+B57-Q?}Hm+_3$8p(dp4HWYDM>mlRt zk`cB^;UTM{e;TILDDVb4Z`F>^!uF+*j)R9kacY0^l>d~07)+Bwwmk#{M+8VEx(W~5 z>WVJF7D`VJ%^=|<3E?Fm;h0q5tu|O^0^L51$d=FVOS*vtOX?dS=@|fx$=Auru#L&q za--rpqczFNyS5Aok;%J{Js&TJB}WtgAJWb-$dho{)6MB=|J$~0+qN-n+qS!>ZQItg zZF}0bZEl}EcX#i(yC3exi6}(9QBhG*k(F;|R^{{amN&FavoKFHu}rfu=a^k&?4MJ# zv`jNMPcybmv+lK)W!yT#jJk{0I>e$ObM67b>IqIRLtW8C)zVDHM$i+aNcMxDmmx3I z>H$p=qS1zYutRzOSsik=gXspS4(_+Z@d_xq+Wv7EYF&xl)WBg!qy@=V2fc&pLUgVN zp-1M4VPmS>lNABslP+&E2r!T7TShIL2(V^JdO`ffQ%u-($|N5NmL*;8ImRnr2KDvB zxkr&_oKsH&B2$v1{KRiwwir%x`~5=JShOm0ZnYh=wEp<3Wg}#pD#k&M4VRpjfi!j zx%dLE9YF+CVdcUsh|8jX6$p<3uiyzyf0Z{P-M37I+DxJ%t;Xc zwveBdw$b*+7`IFT(dFxXK&gF^+!NIF@qbshcbw6oZ3R&}z?HVG*%3AaTd#SkgW{vd~mOD%>=spm9A=7bcx;-w>pzBb+_16}mqZJj)e}8rMaO{Im$vlGS zmfV9Z)mpZLsLKKQB*JXhPyoLN{aQllaR=LeHv;++hurp1s-YDGDx@cp5{A&m&x$4I z0YXc*D;P1Z1Eq~mcGw4QVb>`6igNUZXq5)W+nd2lvY>Yqq;MQf~Y`(Bs9d)YB0=S)U7` zq|oh1eG{RZLyx8G!W5!zv}?mqf>8w_yGzi*9By108f@HWv{H4rY|S}t!A$aTV`VgD z>?oOX87xC|Q)7c?mEUJVZ8g+qLTT08he~ag*QZKtHQ1*L%@Ch35xOI3OFRPat)YuP z1(g?o(rdIh-8YJfL&7F)#6_&X0*EC>B(pW-au)Hy9F3!w!SZ(3S-jXryug1Z-sk}f zk_*F`so7$^HuxLwVz*WTmcc60QA0)K4Mmw;@TZM8Y%%-O(f} zI%?IaTa94tNECE3IWXFk9{;J85pSEr*ay*x$ksK64pT-~h(mD|zl~9!2&q-PPuf7= zUhLSCsBeToiHCMZo?i|IkR_ukTW8*`+$7LzmcDi*e+bO!;wXJz5cV|cV>cKr^_O$Q@I4iEyU-2X1g-ye_r{RJgxe&&}TXt1Y zre$UIk>WjEqaWHM7W$wW;A(X%Eu@Y+tgP^tdeGYfP3qMm;ZrDvp>uhTS^{6)LX;tB zE_LlIJVrDtomMH;qqaNjWV~p{tNfbwzq++%=XbgeIGIb9EMeKef|6HI?es1l;}vuI zLmzKNX#lO}T+uTXHncbz4nQ{U^b%dk`35-=6`q*YZzpCMr+NVB{P4<92K4$U(1-jMV&*{D22;>IczPRm9WanJr2GI|XM}V(|wj79j}KAvh;)tR(& zHJ_S=Oc!6u!Xa%LtE-ynTLXNra(6!+7p|Wt=eACF|Iv-Rw+7+9k_frnWdFftQRsD} zWdZpoFHuByH)jdXE7_mRrp8ytY(I!5foi@ZeC})d2s-%7oY>6c@CT0aY?qlA^gQYNfz^-Jv2m z&YHd)&bqUK(Zm%V{s2hkp(9_1t^Mv*hZ{{cKf5%=NiQ_GbTL08f67fs z7}4^7wiQr^FDOjjo%%$uaweoXn%S^VT(m$9!#q*svI#P&MR6L&aehH=3gQWA zr7m>h^u%_g^!lw8mQxpa%snlZ6|c^K)+kjqEn@8!z*D9*Ygx-?0Mq_K{?{jEYmnh{ zGtk%bBs?bG2dB1X_3Y{N#=|FcYYq6#_<0Y_2jYmE4*C})6whLo9T1$dXv7t}QmUWq{)@cLcp^^>I zGSN&Z4;1LPoO3;{SbUD($~n0DfDfc;ty(NYjUcoq>|(=`0`ew*!wYFht!*B82T{tE zLlk(i`-(L?`2^3P53Nw?#+-_MnkS}fxZojNo$0<*#>P3?xrTY6OT!WUQG9EEs^j?j z-SIki>8)Bl8i0&$BE;j7P;fK=mHE0m{&y4Z*osu@_z<|q3ccDnZ_t4VIvp~H4Y+HZ zB}8WU+JV?8Z@8=*%%8Ix3$Zvu2$)+gkG^Rqse>?`^bzMCqzih#^qd8n^cAo6MQP|2 zU_M)j7-p}&pJCWp*UVFPrK{#f+Uze(e{G^k$Mzi0gAkUJ-nfl@Tp`{KuG27x>xSlkWU!MuUV>U9UtFJI|_zhUQ} z$IJ|M1>G&H*-^Yt4gW{cv^siW_%_V{G^-YgALKySIy+ zdqli}Xh#xhP$PLE;FA9PBOos?b)E&;F+D_-pftu>h{rOqYo9xnEM*xorO&B#fOa|J zxr-D{YbFKn)v^k<#f~SoO(njpT7g$V^`f{4Q*3=LRlo#vb+QLw+#PA(;g2RR(Oj(wl< zAUMMys3i)Wc7CZ{Njx;4+U<@=5zwZ*N8einJg<^Rzgk2Ntn!a~%A%l2Wzo8#F?3Xg zF&Im^3X9cemEtH}o z`!?dUIwl<5<&kZoC>ivoU&YGWIZopBlYRoT>`IGPw>V}#_A}I?gk0QjhIi>l+P-n2 z@OM~Gxs(wuJ5t6J=l$4<&bIV|NSHYsmX$|^ml`aa*Qmg2lRqUm>95vur?;vODH_aC{*a2NWF?8*boXM|XLmjd?R1}&TaNhJh+(9KffE zqjp`2plp=$J8%cWEplbSA7j$&g%bh&V^(frY0%wjsC_A8gwM_OsRxu&>i!OlSh>{3 zhDpYiq8x!)WtkMlw;aci1x8@EypmI1OwF4UJi)E-g`V#76M4j`irS_F3#m+nEmL+L zscWTD_F0i!*o;r9k;>#xE#Dh4#Iq2r9dmCTGA&Zw3XdH)w?yx-Dh)flbA3F0+2E~y z3!D_XJdMj+2YCZNR$|mJ*7_ytUd0y!K@E~oUKvZ~C=MpJ9}~=n6Zh*A_#lp)2&wbo zJ(;p#hs=av-iak|J5kFJ7(YBE71Xz=ZaB!PZ({-b&pbu@r<=B+ScORg#qc0)4xR0= z<&k6X%>w3S3eTmWytE_@2d;5hPI1A)doL0jz|W01hZ5kEjQ7O9@AsPzZvq-SLT6G8 zYHOzNRuFnf)Y0$}6HV;MX=1Ay1-s^cd?fynugnBZNOaUsuE$j+M-xwY97j(Pqz_;Pz*I_7V1Mqq+k@?3hfEV5?fXqH(!!Wb~Zmt>Y=1MjQ1u zc@w7OqU8D_XuSi{y2HDeMBL*~CML|4bYhqzT>#~nBR_mqCUZAvCAvS@KLM8wiZn zT?&19@vZi5ScTsLajCe+Rw+N$Iwp2nRm}C;D8Y%3@`N#LXT4rdfKI2kc4KfH2GV%^ zB4`i#z%7~{kI*Y%M$@pO7tJ=JRaOPDENmSy*_+XfYaP*7sg+!%xvk)mv22@fEdHOn zNJy7-hF)1F(&e&YutcIV*Sv!c35yIY_ovpE_%@ZUabWVli#u{_ut?WM8gVrTU7SC4 zr-$4=rXe4niXaokdMcdqxjaBtzKCIzvI7tg%uV2neP4>E&Cv}P#YFL@_=>U3Qq-M>6M_3?Nu*kQb-f2`aZ{Ei&;^3eJV z>8qi+V9WQeV&ib^{g<^dqDo zMsWYzcCAJ(Ppd|c^=EcmIL@DrkZ%!7oB_Vvnp-;bYOg?oabIfN4N%f9;8Ax{$1lMf z6~GYN`Brj2Fyn>czNg^FAHwf{nm=3w^NecAsi@~Ls9dZ8Bg=Bskx3B1>)|)qSjv~c zcu#$RZ18>tz6eV)Y!r48+WV9VVqgqILN?L**wOWZ_%uqGz;u@%<6^v4-q zFH@=OmX27Y;Fo64+CNR)W2zqLn_ky>uVfo*vi(4NFZnIJaS=FyzE*>2G@1o;b4(GZ zkP({=mCq5Jor3VSc-mLLi(z!VeN4G*^?--;rx1`$2oFa-n0@cOOtik64m|0-4}Ca1 zFz9DJ_CR=l6JG4aJA>s3scj1#sHK}YJ0v`C*W0?<-!Xw39Wak~4sH=@y$v0!UcL@L z_8V-C(PzR;9=KivE#NAZ_-%|A_gsW6H(-z+RE=6%l|v_sI4kLrK&C0BX;px+XQIJk z<2xe=4}9>~ss3z19@qu;6}58XHj#sz&1lcjnK^OHufcDnR-Y~RVfk+=)%L+XKiP{k z`;`>dn(@7xg1%LMw96$--9H;?pHjq5mk1K%z=1x8(}dsU%_ZQE#ino^!cVic-V?edZpNY7nMZH0P~ZhEZElG_^(mp}T32ZV-qa1Jve^@t1LNq`f%O zA)+KNoV~bvDl_&)aG{f>0>B>jam_O`n@BfdfnoFa7el5-BEx2lVl5IEBM&5Wi}E^1 zhV@8v8-X>qq7zkw>hJ?~r13gQTb%K_dnRkdKm^j{KqqSZugYhZ6lp%X!aYyWXrj6t z*>4C>F!~`@2__N4Hm#m}cx}dmTdtj_qGMN88p(Pk%;58%?d_$!eeIb1PFT_F3;Luj zBZa0DQkMB7LWwBQexL{_lzj`nyW+7DawT#V>Rhf0LuVz|%+FnyYVOuK16Nh~3wl|0 z-N1pe1 zO@Lpk(0>U-H)>_qwkJFY;m!EEm;+~uMf^&Jn#V#d3F15|ykohw{*r#<8 zVc1_wI)K}r`yQE$KQ9$VXb>5l#A2JB0k&9g14hA8^iU`-$47e+`qu-*>+hB{QoQ1k ziXHMV`Km-S)^9Ya=;=b`EC(YtNe7vY@k*ohcJHuLU4?SC=20?kkR|7GcuP1^JGB*- z@R0mO?`msqgnQVf*9aP!zb>_3uK_`R$3WlQPVu*@f@qzmonkYiCPrXw{8iFhLQSGf z(JTD)MdCr%XSUvecSKRq!}gLFn76d89hMud%dCxh3Ylj3;7Rg6q1GOg{3eb2n< zCPg8KZ&$gKs)tSlHJ~2Yu8Ff4rW~r@o?6>uNo2i8!Z`wxwKp?+!rF{Ye7eg z+oS6s-Z}fKsP#E}J|n4y3a?&TnY>%csa{fU3xfBh)kF+amkL#pTpR`Cc9JG>TImX{ zy2Y940WTZ5$>}d8McqCnrVFcCalC@2l+F|bZAY_yKPkuCXM(sY0`M-AF6(BLb9iO) zA_RZa};RbSPGl>+Q=VZ(;*>&ztaeyhLc|IOqL zYnX?ajpuBd{JJt&Tf9ezD7m^`n;SN87R4D#zemu_;0<$5i$aeBW7)!oE*p z*9~_K)@xfG=a$&k3r5jZz&-44a9Yt-e&n31y@eUa7fvJWM(k=7{41{_n+quISvRO_ zxPy7bpM5bya-a9F+M0IihSx3%Z`h6ZFaC$*35(Ii`-jKd`;Re{u_OxqQZdlo^84V& z(|ZB!1l};qq?|&a9d=B>lJR1Pc8-QfJArrHT5?yljht_hjr8|Ab}qS*sj+7#^~&AG z;tk-MGrhA;GrpUesDF99FM5fd5Cw8A?iTtqf5l&&*L`lEgRpmf4O&m=LR_ynpA(Rt zuaRxp|3hbM!QFTU`wLb5(8x$1q)V=qk3>(d&Cj*O_7G1TZy@lb;WO_G4_64kyK_&|Lv*s1H)S(0lU3cwoz5GID}^_(cf#~y`n_&{MU2W7 zPUn%$L)<98V!yh-p4~gWs$)yy4KSSqK8w6|xUqTzrax+o9AL0IJ}MBNW2AovUtPPzOSVDJuHVefOQh+#^epKErQ>@xTjg?`aWd) zKI!}6J-&3LaD{!%A)IU0U6LQkKb>HII5lYK`#+lGJc9Zk1~di3ZsV0GBxa~x}* zJiMj`k2sz)L#KD1Gh?Rno(n+}C7!i`bX=%;(RLj{c+qy4{H6z=sfUjcz2JI}MxTkF zOST=Uc~f>Bk$F>g8o+W&b`!R9Lhjgh?ws~FMxVJs$8{Sp&f$AL{|m#d^MaW#=({1( z;=3VI_5Zu6?7Q{-KLp)WB#8f)=%|pHzK!X>O5;{3Ysn!AAb%DsH~m5_)kZ-Uh_x9v z7PuLD$eRt*sEfGWUTefTi8pS#w3+R~u)U#sW|Brm!i${#B;QN3_D2Rss!K`ZFzvp} z;@HYu!Q<=p0oBtN5yKKqm|-a1LmXl${A)!TI~z9`6fGfLrmq=Tq%Yb}Eo7ST` zBGRtj z+NsYt1m%vnFby`uZHfvqM0PFCpsMXx7(T6gn^n!o2J9u*m<{`0IeN%u$CXMD-lBss zE!!Z@*cDVxuX>W=Ge-)9KmKw*l9kPQ425`TwB$T!h{F8lF4sEcPg>9lj`PLnSbb$O zqW$YFKV^LDs8~~?eP}AT%MqEg%ibYm;oA%GoUn-^GfSR(NU`aA=bBTrL2I#a7B6Y{ zdCFyes1(@70-=5sP{)?B8DC)o&?UR9DT;mYjHM2X)F z5wRJVb-thleY{`j0tap7j+0wuOmgUlU%%)>n#!Gw01itki@7W7+#I&;yQ7`F(w9UG zAP>BGT0&p6f5Dku1-%U#C3l?mA+pROyZo|0K$5ebBbSGN&dV55>HDP|=hf9j3(`#q zQ+os^tYUz|RxbsG&u3;Yi;TMtT+Mn}SeI8gqpdq7vE9#|gTDP2 zRcOs?-;u;`o2P~SRyq8)?Ear^ltpTu|C9Ex!OC3ohaajaSambDkOVr+FEItoe?cCk zD2XtPZIpGTZ9|3)YxUKqzz3|`@9Q~qN?gxqXooKIrr?qz=g2iGF8G9|j(yOmu#Y{eM+ zS7EGCnm0A1Q%g4F{)#i%oUsBXF-}jBzMU!z^Q>(Yb=IWgN*`@|YRk7!O)$}zbTT5m z>6&jV<1z*JD5%o_)}0$maL4){kWoQxNS8TboNBcB2 zD|YH2IFZ8W)+=09m)O{)AOA0uSWJ9YCP9UA`m@SRT zxcfP*DA<~Dg!;i$o9d3zyufmb=m#T;@ZK-++bT~G?{FGfxh|u>Nk=)3)+ZzzA2}y< zAi6o@2q{t%sV`BU&`4yd5a-L>(XQ1iFE}2AKR^i}gZs>9x_5*vsx2{%n-xFMx_^u9DS|b@%bh%Acj8^ zZx0DPXO{^)XAc@&cb5vhX0N5^2F>#4nC|aY;|N2+-lblzn+kZxl&0- zx$rK2m${K8g!+XoQB5xOAxiQtT5W&wOCJg-P@|DKJ7(eGxTFo7JsF!=Yib(HQeCVZ zhX3fRAKq;YY4C`j$uj-GsQV*w=Cf4iM*GUhXHuteUMv^-aep%>#q~g{z@vS5DH|;2 zi5@@(QWbh~k9iUB2zw(2=x(zTGdq|D#J0o)#UK_fq=tQ-)e0`dK}{B zJ*E5*&GGat72)+mVwY&&KD^%lB31G!N)3HE0wS1BpSXB;3yq zgHy|+|20U(XW(|u@S0<=_xEO`n38pP7?1E4>Bou7Hbv9S#Uka84K2j*NR>Jook98e zd8Ol$ho37hnO&o@dhi;lJ?5Iz@=w`=B&X{X7V8?sCrDR>#2d${1B7$cruGrD?og*- zqxS%{)cvWpS*A`ihCv_4+-a8gE-CH_7U@Hn2J>maBlS8i8ggiHcp$PHzEFe>;ycU_ zJ7}R)$G`B4{Fvn-JStYoJi`gddT?LznNAli9{{51nQ7p{FCvvlR+fkMvKFC}w%^t* zOYv<4a)B`=X`x&PMLuEn+4{MVFO;72a|2Pa*s*rAG6YE^;L`^17U}N?r3>}EjGBX+F13;ceJ$2!dOIP(`r6JkMiyfa z>erc1$c0P7dL0qo7ayI1AyqEnea`FG`90u+I&$rEZ1yvqMSO6_PC&c5|A+g7TsX<> zpTPuQ_6?09`DV`v{C7RRyuOW-nX!YYxs|bynXRp(vBP(u!|)$2KYmSijUN#5ML=eN z4M%Z=%YHxzD5G8Cw+Wyust2fOUZ%M9{+_^Ggfo9rz5o~8&4-^M%R9gUGz^u;u5Kca z<4(VCzL=OS@m*GTgI>?r$qxylkWg!0xueis*9WMfP$P_)m&Ola^(Ak?^AI`V7Z69r z6y8ih1lV3lA2aV?d!t_R3EQd=bLnG~&3T>MAe47btIDb5#H~qIG|HH<<@9Lt;Uja| z<3l2K&3!Avdyr2;*rV4eKJ9gd!38O>P7UVc1Oo-E{nbpDC5{)aufO}UW@dG788uA1 z#2O73{lW7PY&prg^nqkgz|A1t`OBHoIp1K?k^*1)>myA9(dJ~tNp4QP!#(PkWvuy(-%~mo|)@e&XZ0M$38AmeouxU>{#9UTW zr-zl84NyLobFIR44-afM*x*fktyQ|(pN|Ml$%ayqnfg)cS>v~d3`r<^qxJPI5dUfi zBZhBS|Csq1zi0k`&kh*>!wyuhXoVzcVYD{G_-5*$h5V+BX43wjTBOdgv_*KwT_MjmD>RSyY2`Uohsm^dh zJ_N9eFB2b|Kt=_yN|>QGiu9ohG)pd%9=kxQNwjE6yNWMU9J3(0K$c6Gp)gYtkP4vD zt_{r42H7*9>z@z((N8@FRFeGQiUfNM>qV%<3P2NN43Z6zrn70`2!=UenROeOtxUCP zvu~GiCG?EP{18J-KNt+(*l&O}uO6d+7;CX^Z=2WtHAUZ4r!~SuBuT1~2rdk@GuX$ioOX zuT+U!@q#0CRW6FYD3`hLQv*I2N72na#5z?`hBl+}u|B}#*zr&opgO^x=aFf`Y(a+S z^rY^daff@cIR#)7YfoeoZ_i|-pUQ!L3fDW;`NJ!CD&+Zwev!x^Kv zRl<&stQ16OyLJ8*@mPF0FatB* zvIftrSFGuvjZtM*{F4T@bM$Gms05`!NOw5=&n#_nhyhPAVbBHNFG5Z@5 zc3!YZA8{shz$m}^P}P2tig6h2MqvT7G=Fl*7&(gKT6!MvYyM;Q-C>l1R-0i}M|jaB z=Z#P)#bT+GS0rmuz|}?4W^?88p)ilpB8{_^wG2UevI--;`nKZ&v@Q`JnT38%b9O!7T)mKC<&>jsQ&^6svu)zmpExPu$ zZF;7r)w-bi1L1LoaU?-^X0m{*qPLng;z=|qFM}b1?Cc!#HN@e=u#BFPkkpe#>vyVbW0i^!7lADl9 zF_@8(lAC}^y|@cZED;KEAa>n5l<6`+L z%9T$qnj)i1Epj5pD;Z>HCr*vKdEycXXph=!cGRMmb=>`j>D&2+02)v+C&1ltm@NP9 zl^(Y*n#McN#K9F&j<28MC&A)%jQpgW0n-;c*E5;fUP*1JZ-n^X&f zsJrj(-LhkK``JJvQ z>1)#E#`m3ZR2Ge2H*Lm>B?-OXZ82!Pc9E_L%J=C^{xAihK=8r$>pzim{xS9IF?8gr ze-}9(zj=}Wp37(Yr^~NWw)|#)qx-;Vsi{)c`ZKwKqByHj?!rPm>x(L738&HC7_Pvb zG5q3MohthpD~&bVg})ZV*m4vNL3k%*F1g~kDw@92S^a!}xPSnHhKJ4UOJau6W)Y`8 zZZW|RKl@>WpCbw^LLsS0b5?q+ZX`Zf9fq3hv~HAY^+Tt7yg=r%*?mOl$NZx=?jko? zgxkP%<)%Z`3_%TAYcDH&RaTeK_$i0adHkzl8C}S#;m%Du78nA&?i#eOz8c0{6g(p> zDvhL}$}^#k>GDVpzF6L9Y$dq0?4Q5E(`>IBG`L+3P2BZHX9D9l>9XX7UAEF=F7$r- z7wGQPO3p|;V$b$8$B!U6Zwx}Ty1r)}j?|_AEjhuGqX^YPMkAb%6C$tuJY^F&?ik^e zx455P4j56ncug()#;I?vw7+l7ku<2&=oyT6QIjcJ5lm>V1LR+A&sq$3X)jM&Yz@HS zrIm}m0|=o9^v>Kdk~L2%%%9zcJUD-ZAtu*&>&%&mZ|k!>LWf~*;>M%VqHT02ZP%J2 zC$UdC``rc%|DvRi;Snj3vecaGO9wc$9=9-?m@t`v&PM+VSVhfl9@R2hBq`d}ez}TZ zfPV=dZ)TzjmGJy=i&?<++kDRSxKXyP5q*%S*5HI{h_@`2iC764v?>%k%dww4bFfm7 z;gJDjYUiDI(JxzkMu*~(@TTJ)XOs=Y3%8obtX(`w@qliIC1(Fwxm>3B9{5+X58sSS zt~r6ppP$Awstb2QGYHP$Xm)YrEc^D5j^%#t!44P+P^K^?C-7`}bIMD${~D>7gQo^^ zeVc4M)W2)C%>OjoKdM)bNFwMyO|Tn}9*so?T9oohFvXAus{#D5!e&xMEU-o9fqwZ* zM)TU8>q+fWzNNa)l}r(@;Mk^4*bhuhnCLh-d~aeLU7jh)#OTIh>%{F(pUY1hM;oTD zSJT}-FF1Z7@F@3&9iZOqd3pdcl#U3cdXB1X7*gbp5cXjX@C$MAhcl?Dy?_7-X^D-- zgJDVqRumP~ zb>{4N^dUn9vi_9jFgh=x(Do}bYRzD8j6u%REW7WRHA`}SG&*nGLJ{lS3X%+(21D64;(O6W33 z%x5$pQe!yKij&PW8ToF-CR5IMlnxc70UYR|LX(@btKSE^W7TY$NT zQu`+7C2q;Ej%AeytmwtM^fEiCiAvZat?$MY4RA-X_A`dSP-J1Wy*H-oTh682ORmy# zXfW()g<=-4(+-!R3knYcV=KlDAr99^z*LvJK`*gaSG4#yb8ITuBV9Rk4BK_Bq*ct+ zl|~Vf|Mk~G9=j>Rd41PTx#fDlP>PbZ@QJiZ*=i3o#0}|e zbY_o?*;%t~oXV2$48b3_3{@%_1z>jbRl*=tl06Bv1REn48O^xv&gyw^5{Otvn(aZ) z;H2WFLKzYmx8u7;C0T??X2f8_st`GpdPIuj$uz=xk4GyEo9?R#=;Y~dLUpR?u`7l1 z7eihmo-RrYz%?^7T9(_1Z#$DPAET{aL#06~qavu_K)0PZC0ntD=}`0lsYCjl6{zcP zW5{tHpG0Xh;UNJwh0#AGm)hdf3TTz6!}VBo9AVLEAOXeMASK`vF^Oyw=ZXF%S+AX^ysbbUf__uuDk=fPz7Oq4z4h+9<;J`>!TOo2@ z`&10265k&fokI9LpEi4l<1MNh%u{$FUYdJ6Lau(P`(%6#i^OBlTC;Q0#`Py}o#Lh_ zuO7ZZ1dl7|4#1ECUxZ@#=rt6f05xhKZqUf1#64Lfx3DEfp3%Vr!DHgA>W?qbi@V{m zWAO{jL`KeW`749Wd(W#p%cVKzFEuCK-$}DfibGxL!0PXCyb9@ zVUOr9yt*g`Xpd8I{kd5VQ8ZH+qC|p7kmz|+Gpf#*SB_!3*jIr$n7NVzXyiQj-udVT z_8*UI|LU1&vFTR5zH_LE{~w0#|1*~sbg*^(&Z_?ja5uNLkv4a9GPW^x_z#Drwx*`6 zg8pSa71E!{!Kf{a;Xje?#P2i$O_B;p&ccchWgw{$ng)u^l^N(b1y2=bkb{n^01#^T<3v6eEAfLPXAh%gaDrYZz~Etoqf+-5L&5GH0SDXmS72r_4UKaL*DFe1MVhbdc{okxL+7fH-Qm6tJ< zyHP_%M5g$iJcY1~;}jkM+peT({J|*R;!V0#rG_xR|+{CZAr8`8pdRy4vOF{ z+`KOCs<>q8{sfh1`u%P^qD%CxjxzjkNsO%LM!SZywa}2>^HHSDR-m1;!b~S>yuc*N z3K>wi7_bfrf|-kfHV7e1EbkV6VOfMUDfurehB_ma=_omLN2$~E8>T%a1DR5% z&m6_{x;{c};F?lL>88zZvnMEm?It;*`6fD|!A)(@(=BIb+gFzhW-z;sR7KXvcgud& zc-byNIMXn>FF(j-y-5eziUxNHhpe%v%cr#&O@az@W`mmgz@o*ZOt4JdDkjfJb3r?c ze&JADtG?KTdX18rtBHCXb#H?WN0rn1LPnf?#%RXsCs(IO%~Ty(bE2vAGO0BBm#%b6 zQUHNWdUCI9=lH_Va6T#vBvD?g$IvrZpVTt#oMx7sZu}Xa*hs0yE93r7DF8(~F+`ta zG|D`hO10{7rq=po_f?w%C*ypM*#Fi^Q<2;B=OOKPGi>;YX17|(!U$!9=9)HIo$y&P zDTO&C=6F9_HldpumaONPQxw)qi(%y1CW5kEy``rbv2%vq6-Yd4Pu$^DB-w+oRmsJ44Ihk^3lTB}RkA|g(f#%E z5{J^qAnci?o%R!R>*gyU{Z%>MP zq-L7|RoC-e+dxhFTwa9a4SDU7iBAe6W7k-h!*FvgAl>;0GRR#3pCMUpeu}y1X$lTp zVP4J~43~sN5VL2%q?x}oT@+-a0X$T=XN{>dmW3HDNoj0N21L{?w`p=BlgYH} zZn9On`_tnA)h{GXl6f$eUklm3ad^gGmcc1JkL$a%3FTo}I`D!{yPY2(Wza<(LIw4T ze9tuE(|aG!0|Tm2klWhU*+WyaP3@rOSzA6Y*Iu*c<3F&%p9xuHKfiktu;;eknT4Sj zcDNX{$p#yM&1^l7XMir5Vn1FH zQBB{h!=`Qh8poC9qH;e=;pir8CnI_?*TgEL-CXL4TQ;Qiqe1F&H;^!HCh#weD;kb# zFdaQ}N&Wb%(64#C7fjy~YhCE5;Q`K$qkIZl0Q`lt7}C_w-*LCgI-wYps1&EYn9+jIdN=cnZLr&Dde?Y}d(l~OR@zk9^R9;D@{UT5x-Yev>G6AFC#R{<485^ z#!RgLI??Eaj*;7nfm}Fk~iTf9+)sT9#lji&;`!JZH6-rCFhrTKf)lTUz z9-W8$nQ0MXWJwCXPRB#4v|Z-;wjTfWn7^?qW3vb!kUbHJdstIf@PHC5%vj()CUDl8 zUMaPf^VpjBo~O_7`*{@=fE-UhZhYc?5^jH*5=De)|n z96?t{z84WK<)$Pgvi+z~(+D@3YuQ37|K1&r%)T_W?=*V%tKl4tdK&)XHBLVY7fl51Zff1axVut|Z;n&y>S-zL+aklZf@M ziEe|Yp^5lxD!H(L*L#Fy@+d8T)8*?#GPqL?(Wv)caQQXFP%0#wTd+GQ_yBv%=uM|u zGT5#hsp_VxrkX7>;mHe|V`{wB_lSfM^k0X31g8V+ zDRM;=Fxl%;s3dshO#w=d;-w9VjkWO?n5XL+a76B^t}fa0W|1v}|bEF|6dx-k|%>PH8HPz4AIt zbiqm;)J5C@@+&AM%6)DalabsUd@oGC?|;&4`A77j+9xKl@$JaWz8%?rTWR#a=g1U| zzcs@g{&&Kus-?6hiu{S{Nn^FZPY?^_Kg0iM-wqUcYWGQ(c<53Fn29>1zQe4;8RE{XRjX_S9we$2Ze|Yj*aurrY-e zmLHifXy$i?KxS`ZzzM*sg%pAUoQVL8o(f_KWg-}Gug8YG4kI9<>2ZicEgmokm|Tw! z;npQrhuUGUmTb_Dp)>Z>O6QteSFz&@k~N#F1T!CwWY%ca6i-mP<`>A$lU>3P95qly z&N3RJW-J{wP*ArQYOvO4k}hU^DJ??isl79iRi7O;j{3|esXE>_ck9QQaxakB0Niw# zul8w*KX&FvF@UK`Q&CZeOf3jm{}0x_DLNFbY4XIjZQHhO+qQjT+qRvY*tTu!#C9_I zM{Dj~^Dt|D^SobscXw5HSE*>lu3LHD3M}4>j%Zu9cCX?Y60;qVA06?!VT4WkeDi|t~o8{dpfRq2~cpNTO1c)){O>1r{IE@Uw> zWz?5xv}0ehf8LQpUqWmlVsLJWZc%WIU-OPNtl=b%2CsDD)2fF-?5v83`qepM}Mg>P0~@Y zM7K~ZHDAV1Pr#Mil7$NVAe4$R@f2o4zD_cg%SdOWIH7BId^g)N{h+UQB$gUZB=H=Y zwcy~G$7&{myib8=`m=tTi2cWh+$N}Br-(2LAf!1EN>l_mu;@WI0nt+c*=B2FL|);Sitj=tcM(n` zx-#@Z0VER1{ATvzR9UIShVO+tM`~g{Hz-eSm6)rw1vZLF6{WgStM}qynfgdY1Pr&r zElRiQEzGd8cVsDL_rNps*>}Dqy61Pbh2Y_z1_dQ%=vUgIb%0 zU?ww&{d!^6YCeK3xgez`31>Y{NdJ=|&SWhs_9i|qTEe_!No2YK`PSw`P|Ia^jOfe2 z>pL9SYiP0^dadiUoX|b@R#dUDRRmn55Kzxz8hB$>syJ=P=uRsex5h2ut4&GYt!x`! z^B6Ocu`#c4PvYu5%`D{!53~2|0*igQM5+8Rj@xrO8MnjgZYI1j>R9P+a<;m-P&e*_y1B#xR!^6P-d)IVl!@Ly%{TVY%xgFj59-0x;_Rc2O zOkA?m17vtu&_pvcC)9g@?0PPbVlzcn!M>&<;)Q~fU=%sZDF%4y&v)kTTv9FWl^3Dp z_!p%0!cAqC=DizIR?N6mGHP*I?N-;=>Uy@(JYR?`?*@YTUc&jN5`9+*{cr*Oc!hpk zDeN9&^Qf_P<|OWb?IvtTIGoNPknTXt7i;DP=VS1C-^_Og#d17RU#?6>yB{2a*oz^m zozZrmDQfN{?ZPK!;wrH&oNDo46u}o8BB3EhI3-?oABatW_f2Ns=WlNQlaeKu1Dr#h z->-jic+FU6OJ+YqF`6G9@Bi6E?f;%r?OcAmafPfcjI91i-&HGb$S%qw>zJ9Erz`UJ zLa_n3Buzsr3U|Uoi-O6}2d3J4>|V}t(2Ge$UQ&#fz7+N77l?b`0DXY!F*AGxJLJMD z;Qm6Yv+$f=_j0>zdT#T6eLQ3Og_ekVhdx?}5r`UM-`6jq-5}p<0;NV@WfK!#5RMp_ z|CfdJJ(QL?#{9+ z2~R;M5m0#vMoBi3J!&etV{#oS`g$cJd~D()3IfdyN-lNw((J((VrHq7SWK8*dV>JYI%B>#V8fqc0ymqyLm2RMBVWK@m&xrBQ!3phqBYExyV{b zFe(xeYmMPzkd+biigeUQYYYSuoAu^kQ1p)aicn4s6sNSO+^o3} zAI711;h!Hb9%dPKp+c26a8*h_{$m|Xr-*LQq28AW*o<5oVT6_Rq@nc#<3o;?5flaK z6w%TL+;kk{lktwxE>S%XFc}%UIhF<>qGwQ=_3W+SS2m>|Fm?+wHT<*9z(;TWA>9be z^73WuG8>IMzAT-i`%t|8u9R}mo?T)2(jNB?^Ut`}`Bf75U;d)>KfQw1f5cS$A6s7n zwnjh3_=XNKg?V^|O&lM~yL# zk?bxm`HR@kYCjo1X3lBlOXm>0H!+vDtF0qMXFwb#dIPtet!JMnk6a(OM87YeSIFP~ z*DMbQSs_5^m&Nh<2G9pyH{~G^Su6Gcx#j7Rn7kt-CbE=FwR?;;wg;_j)xj#n1D=Hke>=}s7*!^ zbtq9njA+xXdK{?=5=B*>U0PdOw5K=Zjc!s384 zZ4m;b5|5CIDq3-m}-s)c=tNUjHtb2?Ab?Nm#IT- zx)^AwAc)6c;H)?V7FHRdvbk*bV~^P2xXI5k#Dd^Nwocqe$9O@yO0euyoL$pT)zwiI z56;%kGgu3_*jv5&GnaG9w$R0xYIg%QVa#i|xTkJo1;$9F36ITW;S~b9&(CSi(mwIF zrN?I~)Y0r!wvK~R)Nx)*a7fLB$^<7`AmQ3@P+`{>057N-%RB36LHH`w#9zjIAE^#1xLjEDHE5Z zsM9u+1!f63SlgqCRpht8pk!;3&htDV6uBa6*l@2*dS+GHZUVFzY|fD#su(vx&`lEc zzi?J*hAJJjxiv2IDDZKH!5bzG7eh*ERLS5?w4BUj&?zOJ%ovn-xt@K&WAD%1 z$My?}?3C?c)os3^B<+k~4_+XsjYZPs8|l1*s10{dvURLrd)n!*k;8Dg@XMUd6+T4) zeYJwVWlP)jGf4Q}5+u)sA14c9gvf^?!1Rgju6{Iy0+zy8ht5}>{t=UGmGsdZIugz4 ziA2g?8yh9+I}>2#W@5nFs3g@xU;6_# zP=6B0e^wZO5{R>jEI5c7c~PjGE?dawd;;Q(n|{e(ko(-#+tD64{ByPsq4 zAy&O!2Ze=J?!{1B$6eeMDHQuNZ2G=n-;m z5p)2}6;+&?I@`v&>_=2+xkf~Bb6uT?w?R0^w_K(ZDLHR5mNgnzGN@ST7Jq44a@v+p zK*QuC_N*P6Fs}8rGU0kTXmjmRCm$?^f<8GJWBTkvFO{nd;QJ=hTF&f=PUnu*{Gk$q5{EDsWOuNi2>}j?Le-9& zi!wq)HKyJNfuI|Ahd?u7E|BOa!Js=p388(@La)%-mgSn~+KRuWEMU|fIEQXZcccqw z^&>GR7atcVpb-)g9ZrD98#sVo_&&F1{FB^(A(xSoUsM%js#)`?Ufy+Ked6Cp@k?2U zImc6M!R5_gW8q1DM@kvG`s(zuj#JIB7{Hu&ba+-+{+&54rJIl0ezer^y@#%-k%}t> z!$gB-CwbpdHU1#V(?wydIzdTClxb02x3pcu)ImMtNn^!bJL%85^LRs}!Ds%!4H{YH zW+H4G4;*l6W^~UVw4U0kzhJ0k3KFHy6pWl_*~(yWf9Lpjc>b$UC-ek*e$mRtbF)XSQ6IpYxO^YWl4vCdKlC~u08fIx)uY(`Jw3qNBmQ1Jp4$^9ze5+qd!y*a0|K8L5qdTd))vJuBzAWb zxymQ%1c^9_-VD~}Z;Dd~5c}#Yh_CDA%ZK!i!2gCGc|AEj)Jsy%uSD;H3S_rXGYIo_ zU}tE#2>GRC+X>jE)>SBs{};!KDEoUFZV|Y>8AgnC_c^-8Yi+9M%e+fgTRQ{oSq z0`!5wzE(5>cYxSs#T?Syl>X*4co_oqb^bi5&xBW{_+i-Z13tlhK7{z(OZ^6?L72W9 zVA&3POpnNh$L1iYvd3aOWF(X|4hF#edB)B$)`_>e@L%63Fy4`jTcT_|I`g61hIpR0 z#7CpzT!y)PLfHT+k=wlwS~W=BJ^$LKdv&afviboIvp+fVKVy~unIHej#8fNm{MX4K zk5G$NdrcmH9~?Y|%7&tb4>OBTU6A?$x#D0E9O=Sk60C;n`4#eCzZ5CaXy>3AJo7sNi28*J)ifV00H)`}&D+EWnU_nR` zP$d_WB(GlinhqVZLtia-1-8?$S&xmA2Tq==O4>F$BR8v48%a6k4gvV^8yMQYaQBO3{w9?;Q0$WP_=C~vlQ3)v{5gx_IRic6w_>1kQg2{1C5o96 z4SkH!aM0vJzKt`?<#{R3fkm>}QV&Z8!s(^;-GKyMc_3mP27B#ghB**7dTzujBC`P> zk2Ri?;6Fp3N*5)uDo+p}7gR1@hQomW$@JQIpK&%9%oc#so}B1xSMH-Jg-IvChh)6g zD!oH-M|t>zA5i3aBdl^6ZYg5YOKK$;=y!G@*X{?%wTHAP4Wrr9ZRf(yd8+9xCQ()- zr7(yRxdrxJ&cGOpujzU9E7adW575Vq(uQJ7HB3*@02hL7AgR-EjAby)s-W9snU3pz zTeTB5)EtOv%fYhMhY4HL?4_6zTBTPJPwm7wRq36F)phS&JY4g!l9h zE|&a{@Pot;vuNuqVPt3fKetAe{zphJxOTW|bW1|{{tm-`0@6@cwnSiNF-Jm185|@_ zbv=Wn=x}jEc%c}^>y4x%4d?^IW4WC(FBl#i1oI2IopyZu= zy+ip0qlV0kj}#bC1r9`*rAQAh(+4lh#y^CCFdacpeeh!z%qWUZ*lDZTxX5;5s z$(y;WQmDV)Y{l*tDU6Y+i_$tGCCo8Sa}~`HRs7}8#3Lnxe9_Q1%RNSOa6G@CwKsX{ zq$2dkB=zBM)s;O1TyL0pumHu6058?sXQjvln17s2 zVQno;E*d(O#dq5%twP&M3w#CWPwvXHc;LrQ`n@@t%?T(DmY2I;5sS<2y znU}WpUy0)9I*%2^yQcG6s8P);S1qY2N80rKUmyhTMlfDp~A>5bcWjW#D?w~xUe$9mdtqGbrtr6W9v`7lSw z=g{inKY*GHzUeA_!C(UESRFzEWU}|xkvyI?7nQ9N`rMP0Jzn|)lh!!#^IUlW5}z+R zy2DszGY{WTtv%})kNu_&O2S)U7qkm@gq+@^zd`!vZ_;#leWwTg*&Fz|w)uZH-2K0@ zOtL0!qIT9lT>U@x1=QZvki>rYdO^^AKtMplCi8q2K+L~d{8WUN%-p~NB9*jb@Tx+n zu4w+t>uy$hnpSw4R+mZ__lr5KPm2qMdp zqU!&)_6GGbL4G{t*{ZBinMVnO36-QojRmooLyI#pGgi#`nX5~!2NGYo4a%ym7n2!J z0)v6?^cX%gu^A z42D^T>rO3dJc0UHLt3;<)a!^6l1?3$RbxqjShA-lnMw&ZQcFO-E$co7Bwf)f?DRf+ABBJ9k z2?zjG6Jry!=9YO&kj3`CoHiQK{=&k)EIY4|cM@Eo*4^eYSaUr6O<{snEvw7~DnJ_+ zlR=7Lgp#0bg}n}$@|8*e*#JsDmLmNuC7L8o#AhSj!FpIUVO@X9Dmqo>452)YbI;P5 zvPdyJp(Bst;;uSGxkyf)OB4cVrpz7MSoPi+fp$|6k*e;EQCsGYQd{nxJ>=vrv@3&R zw`YTLZSRDOrra4B35hywTx|%%THy|t3cRg$3&4x~B0glI4c}Uz|L%QIuy3TTatl#Y z{(`J#abisR;{>KNWXAo@;q(otSMdV50^F_Y5ZETSUlL)bzNh6~y6?4F1j8uRU;YAM zh7$DM5-ko9j}dn4JHbj(T0$xn_-yv;I*bNRrgv`&F-rt`n$-ma6C%Tp=2N9kEy zZ*t>hTj;P%=iXB5U=SmaWT9dfJud-1+*zc5av*3(i|LmPDABhP_Ge;FmkZj)EHhbxm3riNQIaB~zOp^*xjm*n5s z@wrC5MWkCo!l68fr-u`mxS>i@^=5?oFD&3%Lg9ikiT1jevq!u#iFm3PDupyzcGr%9 zpI1KuxJK5yxTK9HAB~TIl*>@#g3s7pEuZoNOqdFc7Ia~6Lyj!~tJ9nku!ZdrrW!OP z#eN+9?#u9z;pqIrE|b2mvk82+BE)Ta!*z18>SZstA>>iAy7iwv|E3~x1Za6DZ4_zXzC9r^NI0Y(W85*}SURwN$xX>ato7+Mq$F~V1eGwr-4XZ9I zt!GrjlQZlJEcHCq@D}taV~Zc4nsWi`9$@Lge`h;1KH3c7Q#_XvSZo(+qd4T)LI%7V z4M1LOZb!a5(~{2=+?!E%2NFyd{$1Qb{zfr%sQ|v;j3ZKjVq%D<8n&fQ_oUwlUMO+l z)Jp57;jSGy8zr+UjlHt)m&P2QSkjxhtqLVj{Ul+#Xr#RQm^ETU?K^mawj%);%6g@YoA?d7%p1riYD3z-u0!>#VnKG^TkhI@Xu5??A+SHL5?!#&-Mzz45u$SE0Y zZ1l)wQ%9g{q$aOu`WXzsSnZ`M6JwIJg)H*xNhWxtjd%W#<30QZ*@U*e>wH^CYGXxKu>=6>b%|co=ahaJuxgVQ9y}Ym3 z{qp`}qwS_JP!QpdK>9Sd26fRFyz;0KI!0KsmNEIJroFKNAqx`iIzIzlaqA3im z_hW5TQ0hR~p^$Q<*tNcf&;I$mt~W@a#2dBHx=L(aljZN^!e7_ECXSfV#hyGv7AjP( z8)49&^Qwy)VT`X_bvtQsrV3u2z>FTN!kX-pK3W&n$V|`Gw;`ca-X1>cG`3bNr)T(H zgjY{0V^F12{>11)E*4aryzQR`sfUfyoi+aFX5!GsCNn1d-8?%<*#3P@I9M^YKkA$I zy4#dsGQ8*S{qBBqDCY%d3eRSrPXF$A7{B_WNay{1A^X;Ipn)zq>XDhf0jU@v`zjss z2|5C9Ry(GkP*DEl{nOhUCfwt)2IO{SyfIm>D0HG5{`>*e*4 z>lc*Tf;fQ{el!!Pf*DMfknBhq0L%gC&(Tf{1WrnfM95Pebs#l@6G(^k>n05Z8Mzl+ zupLj0eS5XcRfvhM=;M~L%nc|zzs>8RCw@*ekqcMZto97>4s z_K&DeO@Q;z<@j*LP3lX9P(n_CnUh)YyW%a2fnst0tlptYJ#lkCR*udZysdhi0J-)a zQyLU)wMXcWvd&cT@xTPDqhJ$#u@vXtooRR|vMQ^Z`iV-n35Z-#hiN#ag_cWWW<;dp zCHazYJmA2Mzv|%_8kVlgB9F_e$yH6bV)jfBvOaGL!=Iz1Oz0LH1mLyuH3`eN4ph#? zR^URKXhp+FK&A-Yp_U)p1a!+PzWfMdLZAg}IwUWU6{be)$Xnw2Eq}i+QT#Nz@oK?NB z0#Dk|`S^V0P&T5iif3_T^Z9aYpId@Rs5W&6okvN0c<2QzdYJL_FCI%-^UL4u>+wZj zt_V9ao7{*GKvDH{;!)9lpc|yL{zCDjFo9oD7yjGoP@&;JXGCepfNxgnD;6r6mC6K!SnXeKnRPsKm3}6d@by6&Uz>oB#ndTLEY;>{SNpl(0F;V3efuB ztS0{5^>X@L;@x77?^u7pkhR}oA9!|U6@$J&F+OQLAK~JGm{_Yh#0|hp#XGp(jO)$i zlTKyrSgl87mC9U8TDBk9A@|!K^czypxCBd#d@vr_Q;Lo3Voyz~0 zuOj;MRh<6$PpXx4>=x*edDt%PGeKF0hgXJ&^WcibrGkTiF)QLILr6uU%8jmV|Hexb z__Lp}TKGZ!SL(&w;Qe9=;o zp!&r`{JM(RkSS^kXP8UAVlq-^b<(>oVUw!#Mq6vkaT}LC3g$cMjbg(Vfk80}_GtXW zk-=VNyd>1lonBhL%uJIrmx%fsRQkD9xj;$!*;6AUTynjz`e);m3(;xcPzIQPMlTQC z^BlhQ_sJxL)3O)gLd)0FE`RWa<7=n0teUcB37{O^MNlNofV{<)_e0S_A7<_)#?9IR zt6jrUH|)K#`>;r0{YV*9s9vv)A3zhHZ^(UoeBi_fn-zhi_TKFy15{%bC>N#`VvT`8 z!DE)!Kt&T@-)qEpd4kpcKD;1ywnC-MlBN33Szrf)ikGz-&_hRlA`>EWa$a~)U}lOR zl-lL6H_S`OO#a)yYI%)ayRPF8(A@bsN&3%#rmCIwPquaX7aggpWsjtS{?$A-mf&oK zgwKCOi!#p)f9OlIo+6l+Bt@}GnQGHugPO3_ur>?0O+GFY7fGnhpFM{$2nLd*3V`t- zfJ1lP{jwVsJI&7fk_WfzH~l23X$HJ;c)@Y3+ ziWD!v{5X(!mhyn?ynPpXjgzQ~r(~sg zhN)=dU&GDNbsq2Sa)G&Xi}yAhkRoTLXiC! zK!qC7s9oXfN|r`d?E@x6QrPM>=&Ou?^wmmzPE+wT`cV_j9NYS5c0$KfUXTU&0;${G zbVe;e_9Z7sN%#`@N6{8VIV(|7HW*u9-C-z5-9ahjeF0>(I=o9r*qah$1dyMJl4QEC zWU=(#tpG@XT1EalHcmQh#j26UR-9mxzO>)^|Imj>j-L7-2hljZ;iqW=5x>F4rHZ(OokVyeWE zHV{}XY=@r%xsY$W(j%-rNeO_R0E%O<5R|SP@dIN@*UaKiVlj#3V^>mr;k!!2b`-qz zz^SO6t1X9zEX%qS5>-bn7mAmc4V1?Slx~^-0Z;yw6AV$NIQV$6{9`Y+Lz)C%gjAM$ zNpMBQRp{aLLtVrJ#wcY8aNh6DN=BL~j~4loP|2&4d`5{p&ItYJ4AL2~Cw}3fvL+fx zbbsS@%fe+*E)bzM*Y1@?f*>d0%Eree+w;y*FPGBJn+zsSW_1fHi`^yW@{Pk-zLmXz z$zG)~=ilm^%x_uO2pKc3T-Uz>^0m3#a;#SF3)0}!#IVG!jg2_LYhsR)SQ1c3b$%NV%@E~zmu1EtyZeOsXvTOT;@`q}m>+`Q5%p{~yL znI9Gt6}n>#_T(5YNIM^WYj-w4^vLdNBWz5SxFDhRZEhHWjMBmlo5Ai^bte&6>p_kU z{p}5WTZC+>2McV)jv-0;{}w*PK~#0&1useoEMZCk56$C3o)JQ}BDJb{f{ka`lR=J` zc^Kzpe$al%QxD8c3)Mvz+A;V%hi+xx==E2R$^ifUbo>Pd_)-ovz{Nng?-)&XF3t#Y zevbk`4z=t3s|OLE@6HAwO~e=haQQD? z5L>QM{Ap}tpPt@hKJUeF#Z6rU(KbQ5h4O;yseir&>j>&u1#6w4g||Qim1Rkf}asYk=_%sB*z-xvGX- zQ(GVG6Dj({Gk*bQycSDHOqG4`5K@GatUi68>Zzhma95oy&rRHkHb4mpaa~=4D}>No zfN4ce?NNrXU0rO|e{GAqb*(yy^epi4`L7LVk{QUH%O9B9_rs(9XQ1MLmbd>6Qvca3 zHK}Q-A&bF(VXB&9V=5GcMf?t^+r);4!9*@3M*s|?HJlwZRtI&Rq%Y)Z++;q+b?Qkw z?91xBk0WzRAW1DGljA)UJ1Vj?b3lVbblZ-h_7%fo=Q?^j6PiivDV1A$|b!;M7ezr6(Hyr@RjG=4~d)kUzFla0;1PcAQ zK9c$_A_PHO(LQ}cExmKtNzMJr1=S}oJYQc~K)ElC-yg5BGXvE>rrTUP7Hc}q!i&Le zGwOT=3DoD&D&$}!j3?C)45((KVX7wW+|%?!P%gB0c$7N!T{TG>w+VaV8u=9ZM8DBj z9e?pCCLM6dC&dVsm{e@)C62*zL0lpii{-+A$d(}&7utaw&}5({JB_(3%py}^$1$6C z;$CJX3ThNLbe(qNhC7isbop9$$}$oj)p5KIiP(}IiIhMa@2bO68iT2w&4vT1ox_B) zdwM_CS?*q*a<|i=-|htQb-T)C%ze~xSjYc(NgI#s%pAYE(G)Jcah+u#7UDwFa6LA& zgjd)&j#NS%KCDUZqzW)0xHno`F$?IU8bF(gMp_dj=EzuzKe9F4een>&e|#zUnTZpT zWp%_@+Ys)FGA%BwFQGMp4P_NE(Hd7%}e%8sd+} zV0f*A(mvK^{7Xu5_kfN6{kLB-xV5Z@zEbq5nON<775^5JtFCApQK&K0VW`J7wnhug zI*ll^rKj$ce@cqB97ls{TJ!Sq_%WyxW6Q&-{-C*&od$#Wi(Hz8@l?G5Z!K_h2+-q2 zRooM4!lb519=CSSGDI@Ki9KoavTF=Yj+V8Yf_(fS`3iWdINuhIYYHFOT40;mRUgC# zBlmLThJ95t48N8+h`z{@)2)&;xNGHt*am#Fez-<+WP+WN~U)Ic$>YqiP(*?;=K{*dyTqvk2_|MBeEo{stp|7 zj768wpS9(D=(ZD`)QBcS8Rd{h%bH|Xxi!lnin^`4H>74e6I-Xy9a*Dtp<6_ft%)qi zD)HE&1d&=6dF+`G+q(|J_^rnqn10ET={u*sjhhh5@!f?@?=1 zm50AIMPyPapOP=zCC!*0V`8{Fr-LhqD-zncO_~FMcbJ%dB40fFck*I?ejDed5J`W| z^FuzGOKQx`vz|GGeEQQkgydWkWO&WqK;8KXozeZA1ln_TGu4WCUfFu#$Y9nd|hTEWJCX#nWUQXq|ukt3~ zor)!pXNoB}^^(*R*-(dP1NFUih*xtjY-NY{APph=fj}-%S}Q&0X>LVwHet56!(Cd^ zXg47&SR&b$Pqh~QeNnI(==6l=s|>Z*vyt0#g~vL*o+bX&1b?;s_^pbK|9&52jx}}6 zq#G;m^IOP0N1+rNhk#;wmcmk_A}`+oVE=Zl9FiD!jiMK-{KCE#NKArg)CV`F*qjWr zoF-ov*6&|nl+WhpOp^20ud2jfzxe(WF#12HybY<9;- zBt>!j;Qq5hkogi2*}o8p{{S=RoyI|r@h60*L&%`%c&+HHsMJ*_yV(4ZmPdBj8fve( z(p+{~YO3z4>blQ%+R0?IlLYMl;`2S;^qu}0{CZur9YxE1IDhm0B3Gh&;_sf%w zKo`+x_GidoR8@+}PjKM$QpG5xIB-GFlg{f82OfuzCZtdAMFv!YkS3zf?u74G} z6VY!jnVd5y3O`ksNv|A0XHqB^;xox9!7d$eHwh?FKBHIA;3t7%F^PvwoEkKg(I^;T zW>To8VBwr(Mv`JNNr!Em8oULT#g~`TZ!4*q-D7XO5C$Z(7?;FB&EOzIVi!^B&{gv0T+9ex0>%Vqwv5mVO*VbPl+maRT#;r*FejZA#OKdT?kxvi2M2}- z0{?@gE~ejAVm(WcM~$ywy_h7E;g|s{aO8}$o}?##Y%0Sc6#A%a)X)&$Yl=9WZhMr9 zoKs9;c3zjBwpx`Xw5ttxg20~J3sPh84f-0Zh=v#tN$$$vFSR*dEPO~P(Ys?(<07Gt=gv<;Kt zSP08T3ANeTk||eIwbPcI$$VsrW2d3~@8QShq3&xprnb9CLVo!E-L0Ff`4|X=t1?-BnDv}o%@~8{g0dYY%EAYn^ z>Ar)aInuC$9JNF}Ev-GZm-gq$*<7+zYfY$X^F;N^jmm3l9Eg*u3Eh8WYaEHVnrv%aDd>wXkIKWTo&LyHN zpTf>^Tx;-bgYzTrLoD<<+07hzr&{zAx-jKZgg0`GjXS{h%$PjFXB z=CyVj+C(toF8z+)AH8V^9W8=1Xc}^sxKA?Q5NNOe3lc_)Kz|03O%(-qklLA2hCp9lfO2Ra{2`C> zO!y*?lo8yIRAtmLGKbtV{t}hLc5Z^kvqPjt>*1%BY&ktgeYKsNp?T{N@z;X3hhl6u zjMIX4jU=#TSfmMQ6Uoi&J}?< zK{QH~;7t~G!EL~wE%?GewknV`lL@enR2MgiB==$f5J8g?ZW^x5b7cu~r^we3H5oa# z4rTYpTvFV21f&Ab65l0mVa)woTLej#c=yRqdna|x9(AoNmh;j zPJx-s1dGcp-t^I~PPB~pNNU)cF5g@f_RC-bt$J{~9NDUH9)Au}p(@+(yiA{Gh}GPX zh+w@4f;lsB=uG+KXH=Tri;=;uWX6`5^M&s#fyf@&yT&{Q8V{NM^SKoJ8krq(rmqG~ z#ItG}J19E&&7SA;bi?lQ9z-}dMD~U_&+(I}hDeCFrNSR4z_n#}A@|SKfPH0lC1pNB z%Jf9ScM_m$NbRFDd&wU*uXviaxC)z^XzHfbF0JmCf)L+A{gk7G|%$DAUiY=g%0EIs* zn<71?&@phmV=ElHhCy8Z8%_Rn{G)0>7cc_eTni~O4;{mS?Yv})M26`zm$2p}%iHa! zI;9O-l^_r?na0&|x7x-6&CRHy)8_3eJZrN3nBSn`n*}PMG@DZ~4uSy8IYeZ$l|-Lu zii8H$Io18Tt5X$Peht~j1VZDD4mElQo*?xA`~L*sWi0Pzr=#2b>Q$2 zMaMX2+|-hRR7VPLUUA!!(Z&(KiQ&RN5%{G->Ty`dFnb|2pXbKR*DYZwWgL^K;w8Eu z3*DtzP=b#t(9S{2v>}wwAF08yQNulPZ3D?nZ3)HPGQ68}q;+Xy2bqq}czLmAV*?Nw zyFE7v!>$z=Q(*py=~p&pX4-xpC+Zb;?3_X2<;On_o#f>?t9Pw+lssJb7d`?j9gzVO zZ6!ECZ~aH478gxkaTk(}X_1T35Q6 zhGA8!P3shHc;7o8cM|_P0tPo2l(M8U7N(FwcyxudpIV&Cc@=7+uAzbOy$A1e!X> zhC&X8(}D~Pgu3kjZZSlQYMXACFMcojgguBi%`O|=BsW35N+J^D%D`%wuefrC+a*Gh zKcc~%=0%7h`5}%HY{vCU?~KN>RlXj}d;Ol)T6tY8x?EG34PmPI6=?DD5d+)1FT>>k zrU`FaE?LlJeX4diYlo0YuHZ0pjCM*La($QGvY<6nCor!m`+r&U=>@>FfN0F^NMT|r z%x&&!Xd9tYRS7i|{6V3)_;z;owPv?FAx{!1iYH(FIqeo0?K1Ts`zDQDAP{5b4R~2F#7)N7`M)w4zF}tD5Loh#2J7hT>`HT_E?G}+4PZwB3kZW=eR~C(#A_voR0raAA z6ji}i7|1V{vwu8rCd$XH&F@!c9#}^eECw(HPwxtS2kRk*25q|haANGWn*5L;8W6ti zLGRz@%9NV7hB)MRP|aN$(z^&F*hQDW@IB7LOgTtZn-U+*=o_fQn?pZjOr*T~_`S4n zD4CXYBQz2ZG4Vq&Un|JK3Q5AN=BqnL8-g{`T}8x7O8d|fM$I#Rv=Pk`Se@dr2MYG) zXjNEQUNJir43`KN&(^U1dRM26WSS~4WRqgHkZxo~3}yKbnhjR#a|910)*1|!hbQ!P z_6wg-$MYLz?~QqLs?GLWE@tvZXEm~?uB02paM&O{8!dEXGKHQ<7Nxb)q>54$m7D5| zSry#y(SUksnimG;GThu7vVrvi%twTEUlJxHQ|~VcL<)A?B*E7vn`@ubI1J}50jxJPK=>~h1{;9EVDxY zBYsbTI;wv>H)=q?M}Jb-r6=5EA>z2Y(oNNVM1#|{Wvb~{h+R=BL(!(zvfwGG(KWXP zHTCQfm>*2TI~G79|6rIUBF?9|e+y>T68AddF4uFIwF!S_o@e`hUR;uoFdk0#FrfpG zz#_ssaKJ|UJ;_zZg$z}}QSWfLR3=Q!`Uy_~TdP6Gi)rI;TrEL6`y+y8a@ zF-DT{$O_S)zMO57u)6P*FajH`s65|Ggl z&Qgy>=weUN!O?7Ij?L%Cub+G(>0BaoL7rL`sj|CBn)FHjsrWj_vZT@nb)CT{MF5tx?uCNp?Hy7ruRxm|5Zt zV;7&RcPAOtCTY`#H&=#V%k4XN-%@V~Y<>Hsl>_@3HJ@?0J~e0XZnlgSDd4C-yd!6J zK1Mwlbs?-5e_<$Hn*uY$2=A?Ky-#P>*2PxqINHwSo(BzMSG=?HD9||(&=DEifIX+# zAF;b&L^~+ydqEcLry$Pw+4gOzz=Q^sZNvr6o0BG5^0ja<*w{j2>& zp3*6_s{3YTVrqR07a3kVEFBGH_j632=2A)xrz=nDVkyrKMc>n!gaiHQ%L;z4**5gk zV_m14(|95iu~=^)-cH1=8kn#lrLOo0A!lnG0ltvgT5igRPzPi5eAbjQn>W6E*EFuQ zGIcUxq!H{Uc-Rq(11wPyi5Q}U_(69w!vH3Rcti?S!^P3G#j>=;)3n93w8ho5MFxg) z2L_5UiH+~qUnFZy>(rxPE4YvP&IiCE*S%{ViOFNuXqX0S%w?J zMU>K9n1mDAj+ivb7JG9{IM-&PHzQ>yr|6H^IE6WdBO^tm*j*OR&Q6n~-&_aIX>Lla zREjdFpKwcqoN5koHC7F>zK@n3{pOqipB=-@0XOL0oVf-!$hPR-R6EA@Xz$Crm;h`5 z$-nV$0DJm&fnMdxi0(WMv>0f++pWwm&JC^B{1>Atxl-i{QbVGdM z0ek{@pWW^9sOf85Erlk&t>hY6s9i0wz_e_2l}4jV_9b> zFMGii;Uia%2mT?xO9lug5yAf(VHX(ri6(HI=!AN@hshoE9WKyBEXLk}4Nea_CtL?* zWAGY7n$r=nRTc1RxTCc-e@>7kt6w3J327!8hBwJ=f1w6;*CLVaa%uyAwWqa4igDx<3uWMH5;x1=lH_@ZJ@BPmEfi6+gB`{X9 zU+%DCa`)ghh#iBYMi+)R@dU#g(_uaIWRADXOKfU4u}rgS@h~`{kL=Dd5Ds6N2OvyIxS(8dbr?sn- zm3g5?szB^1im=oy8sz?LBp1Y{Nm$1aPl|KaGY7)QbHt_j-RWJizG&ShJl9Ju`k{-{ zyHQv+JI&C4hl^o#1e_GjVw+}R??bvm-27u;W3c5=fHuy$s7$WOQ`?|;HrUYha@>P? z1sCv6y>c)CCa{-y2yMC~%tV@6n9%il+|oKqHm&w2Qf7XY-G2MY~52yl@$SZ-Sha`FZf_bG%vM7T|+817A{HdOI2c1p`f zRs6r2yrIyHC;_pmG|8KK5Nl`XXOBlC?;W*2W(iT#Naw<{nES0o-H(8PKm%|IcJ&WD zB?5JJFT#Ctd8j<^whR?v~mqJs=ZW#`o$dVdeiyR55}e;|M>-_ z`CFwIFj*ltXWx%uHS>bzB5fST_cxzqS%mxNtd*8qx9(;Ie4`kHa()G|W|CI&U&8i` zKD>iitPhN@s=jR_^5N1~J(w@KFYdP^vF<@qA8yMs+a;s2_Kbf0vAKg7zs8F4ko=Mg z3sAoRK8rG*MQ6~1m5B5HsPVwNxJf3kF21#rG0I8 z(l}6_;b(Vk{?da2Wx2Gw3#RXw;N17x+IxH4sU?AIsW34-x~WRMwL9uJVBXf^8gc$N z%FZb`v#8C&F~8WhZ6_VGW83^R7@WU>W=&s`1FU6{v91poCZF^K76*d z@amJ+kasT1jO@1j*sJw5yH-!-Ru3U?XHKPkMD#bDBnfZPkR;dI+AxW1M;>$QLROIX zH06)nDV_$%ntH#BF-wmf!!~t9g6emGK$%KO@{m6(!3H5nQ8qSN1G!*vMv-F2NCuojdah11AgHa;tLo`QI(}tYW9| zL3G`vy0?8muUW|ie{I{b1mWgkrS;}w7~fTR1=?lu*@~b{)2xc zCy>&oJD^uCzq<4*#50R`SFuu+JrCZ>%n!l`)D?xLNmI|bY#IAdr)5$_QLbO^f74Hw+qnM~bcvf1WCS|ARjA7mE+9~;ID&PrYc;+yZ-L*JB zC#uKa6K>bOOdqWBg(E}TqU`ag_9ag8ld_uRyCU!ZVpo(#WHxPI5Ww+A8%k8&#f!^$ z$L%NU5+!a-)=PAGdjqyLo9C%DytEaO?J&_%W{h=jtTvXS4#J}NMtcp6- z{+x%r!Mir*=LlHe`vY`3n9Vn7B%HUtQ=u0X&=62i zndMr7UxFulVtCTNE_+KlqMS3#owM5YgY_2PlZE&ruFKUHdI1O_YWZowd@;u3>>HAd zaxXEbOB?~$*~=FFOZx)$O(eeBN#E#!b#bclu4S)g*IT3tL;XPL7ujW*Mb7aUToA3( z8rpNfFfS6Ttl2Ss6+hS9$u7Dj?5|7*0!vG)6vAHWBzAUsu53Uu;g?>}Fc(zXNOt$`! zyHR{K*@&uS+{^$sR;LLneS=-d8Z@dLQ>@|d5wDPo~0o*i=$WIeOMBZW) zTby`_Ek5z}jn@gq)P?38drJhAZtRSxTQN1GJ-(&L*t9pv6j2`%hO!$D4snfS(E9Jx z&nyhnO8rm6OFGei_2romMl~KEo!^#&Cs1>&+ z9beB{U^mc^nO+(?!ChMT+^y7+MXOCBF5D7ORqH@_AKxE!$2j`}Y<5(Y7~F^iRvr43 zA5TGrAMS@9KV=}@UTKuJ;lzBg_FIuzjtm1=y(Zd;hSaa0#O)>){&pXy$^t4<%UA3(fEc7t;+Qg$Rgz_;t^EC zMCZKlN`CSFL$lAJ6q$>+%fP|7her#n5Rz9}r2%%9b5u>7=_mo_Xsb+_ySiP~$yr$1 zY4MSkuJif(fU#$B^5NGqu&Xxjk+!S&Sx;TTrb-v6%q4n8t`DS(BK8W)!cK2OBio8Y z?X;ef*C9`+UjZx57cW-QqRB7w3Jdu%FAbqmN5=nZcETj53|o=8SBCyt$8O7w1rrJ@_*Xv}Bz5TuaRq)!{g&Vc!!ije!M=_804u!B9YUX+^gfOQj zO<`s_BnE5s+U)8U!WV#bkK>eQYZyqL}2zxr(&870)(od&5kx!&ZqPe6bB?q+G3SR#j|EXwPW=wybAGaHFF zbXoI``9p!8X$5tvlXK;vc7`}FFj5t?FqKXzj3wVii=X$SB+oB_N6?u>aHE)JC_6z+ z&7=y09?zHWJ3GOi`e!o52>ez8znr-b7-aW_v>P5UPN}>$*U(un>8S|(_yMJ zXlt{1!2*7JKhcBW!)NWZ8%8afsNwVs?j-MfUHaho_6a8Ke{Z>7H!*YT6wF=>=-#7z z7zdfE9#Yj`lBZ4|KGi~Y>+H>5vXeh|WWEf8g|zn-)IH_^=XzCubPOjPI8S1_#Q``q zIv1^c^I$uir+gFlbou=dfXc57!1sy|$2{$$G_{I#iuLt7jgWO}zuR;z^K_yPX*SWw zActwtSH1gFUDI%x$gmjtPM8&cDs;@DELms@4*t~v2UF{KSp5UFvTF%WQqw3MBc^FU zNu7J6fNunDRC}MrI}0#+56hZ0HfhE^{%6#*l1Sx66-U1D=I1G!DYweX#WbBFW7KTI zuSO#tj~9Gj`je^QEXO>M!MQc~*Jkm5`36)EyNovKq%PwP8ZZ16Mk|M-x3Ac&o?*88 zFQ^a>fX&DVzWh8(CO{d(pCEq%=CUx?A4Fi~;xf>Hk~QQAgyJ=3uwaM~G-^^sxxAns zH2x?M6Uc{B1Kbth5+>e&;Ze6fmZ0)$#LRVyIkf$YJP|h2A9P23<#EuN`5-gDNp57R z0~+%HGye4sjB-KuMzp#h7!D{?!IAlJjQvlk{kJz>Wr2LeAbi9S_G2-pY1xPHucWV= zbywaj1_1+xUA&|LQUChE%R$P!xB-V1apSi`M?r{&*twdUu*U?}dhmLOK>tC+H(_XNCSUtinp(JjRVG zLEK02!pg#I`>=*Z?CQN(iB+*en?fI(2#L(X`ILihU}VO51?|9Bpj*LgxDi=67Qz;0UJ$J+*i;Ut%AV ztT=R*8m+WtM8e;J76J!1D^F|aER_wknXBLTumVQZ2!oKEU`AwPzpr`sMDT)*jq7lW z70Cb=EJurWRU^t=<5GYzVf+v+7E_Ad0PPOmJyH=#4rSd7&SaD!&)siFH3@-J%GzCV+vNXIMIuOQuq z=?>`_!^+#%YF;v>hAWx9P%(n{Tiw1W-0eccV3v(#$7F%z8hr8eC`N4~A}vGV^a6oU z>!?^H+NeT97Fw=A@v@=}mS+4xrmR8*4%f)~VwS>dZ0E|IZ)}#X%%YUi0mP^!_5A#r zh&YaeI(CaOP~7v2SvL};Bxs*^BF_W6rc^r#Fo=Mi)rMs!cF@ZfdQJX5$##(?H9nOo z7g4%rpvV4|G?mF9PfZ4B)x^(<`&C)2=1e1@t=5ZWS6Qs+GH^wSVh~mET7bq=!d0a6 zs7e@OJ8II#D>19iSJI2hR*hF>wH^2Bb=s72-_PUzGdNrxC?YeR0LWKcvWyPytz?m9 zRVdHiwU+GGvVAoFDQCaJZ91nSeSLnZpmIWB^djmstt)zr`PA&SFTcc=WJI-PR$x2R zg_o&}LqR{mkp3*jrbBv}27|vClcpzH%%1U>{(N9*Znq20Hxdr4hXmkW0<#48#@~aD zR_)dV0?}IxLVb^8rYvw>NFZ`WRWzdC=IYl_fkbO zxumY2=;imPQUnpI`}F)j)T$g9VjwMoIP3PLE!0U!tf;apoEMr6Vq|gF{}F zEW?O`zkvvrE->{h`eD(xBETp#QkWJuR?a4v zl`2~B-8-jCD076&1Ank(wgJpwr1}Gqkp~UnD~Sg9?1cS^5#Ea$qCt}b>IXAuvmo=4 zc@iV*O2U-S+$I0(9J1tba?;xbsjHo62X1f^v;8aXQFg(cgVfI=w+(~69swd|vNP>g zznyQ@2V^0>^x1ivokXt3M>S@@9+Pyj9cB=ko#M83D9aRm81{{XM(`6sIMGxbI&_~b z!+)tbc6x$A>L`)f8+ZJ(cD)YgOOVY*@!?*|4!fssLi2jEI!>G?#kzSc4%vGd)F5%- zaCg<{MM8q*-zKxSWF)Ak`tE80*`sJR%`Fk%K2^l`lK$bvBh9}`4d0x8%0o#hjfOyO zZV&6qd_Zh1ti2*Ub_@W=mU`)yW@WCR{KU%DF)@W^-jQ_ya0X0BcgGexlE#z%oAwkd zD-P9?nAcCy(%Bks;MJUc07YuJ)Glu8ND2E_VIwWBQ(+UXtnbS3b1|{PW}7{;Vm>J0 zcp$DJlcnh06Cf}|8ZtBt09c`y8cVeRF+<9SU_*-X5U^4CqOnU7tqs$JOYjHf0H?-M zq`9F+3IIBmsSyX75S}GJfY&^5w2o`q7vLk* zd*QWJ{_&fyfoPxh1=bfDdS8Caxxlx7FltaG>{`5J0B;JChy|g?$gYGLN!EmS(u@Yk z%%+L+y=_cm%X~D9)a2FaXI-;S8J9QHx^zjIp0Vg&i>~78%zQM0)+F@Gcr;^b@P5L* z7~L`cSof;>?K1^c7YHQQSSPlt>+j;in}Ad1P&tZAR9pmPSf57%TSe<WX#T`haST(mKldz6|j=$f5L0RYwLJwAT8#w$SECW*sU*bG#uHVB!lEpI+BAXXNZ! z`hlcdN=2jd63{J&H%>1vr7m*G>Jqg%La*d){n(oCU$Q4>r*e1BheUU@Uh&SLZ)M2( z@*jP-=r`ug0>P1%iZ8>}3j6wtWu$e4Kc|-xkHnqh#q~P60&CSZIhULogq_=JQ!VWy zjeNQom-4H|ZmpH++lShte_d_OH}y{I2x{Qh0RH24fb$$ba8HsWP~olh{7GIORGkk#oS4ikCC_tKt+h=cGOI z`R4NYJV(+a@$`QG4Yo_O z_K?E!ckCS3E$fG_pmJ|O>`Lv4$phZ2rVn0jnf>YUo4%m5Uy{O#(1FT>{p%9?NNF+l z_u&PTAe|X;ZnpBoX_4H?XbJs6G7a5JR}z%3lT2K$G4Kcr=kz8rde_*4pm$(x*w2=~ zua^CDs+Kcne-+#QmZ3b#KKYa;RXD?u7ySnJiRR439F<3_e@*#ULjkVPo!Ps`-eq%= z@H>P)e8h-u6w@fC$fU~dJ{@z3b!~azOZcU;gB4K)4>yt!^z?mt!i>h<>mDcPK=8Y% zFPuk|UR|8mEA3pgg&}+G;bWX}7vx79(mlY?yV)nH8LEx{3MYcoDXu%Jq5tWQu5cxS zo!s*&DNr5p<&pU1IuE)R_U$Iq2&Q+~(U*NmPzcxhQF-p!1alix@!NK5DG|ExXDY1Zu@_1k(qQK?fZ}>v@fQjn>c3&>jdoSW#d&vzxMB&c)lB?#oEQO{> z6X_I9a@oVq4tVLmP=W406n0>JUJ0Swy)$)t#A6oSJuusclS<|#s0_u@l5KN)L!&ns zk+3)%8sjn3*^^*yp!=qYAdq$~3ZIFuZGI(IEDJUkT$P(WVMGG8JX1B3L}3_L>5hb$0287x zjDQVM7$(4osAOYcMO1X(T2l~zlswb8F&ppt6e4m`Ro@YPx+)D%C;2^MI&HXgJ2eM% zB_Um+oy^RzX|bF&qPAESgzFN8ti)yBdC(&LGA0oIDBqB%|JDoL@{Fkn)qa>d?L~{hgsLtQVno|9XJoU0`io z==aCFs7Hn$MD0!NzUU{c_pp!|T|=dX7Q>-0<6*2 z12;L`?UEv$07GxGUDN#y^ZkkvX*Qzn-Pa>~wfXZm{g&VIif=9r!31#`!# zCSg?bX!7?rDTmGe(&N?rYgY4GzuQRg$p#LC1<%mR%o*gUCoo75{hmh;S`XLBlPt#( zfaP-bk$rARZq~Xy61YTXTiqO2S6b%*^ZD~pTx_KNOss=r{`fE5o^L@@PwkGn4P$Ck zpLBlyTCu81O{StX69rlXO~l%Mb(cks(XXGMu)XKLmHvX z+(6IGn9BWjU28#LW9Xgvre!YHyil-9J2aeIZnM>mYC%ENOq^qiTH1mfb%3 zQZ5Q;0`D=z?TXhn#Enn4)%B3aPcXdI0ExMf57L5=RC-b(Nb64ecWa5+hCyL+*+COo z$qv_UZqb3?GIfWJ>k8x{U(?MF_wUMjxehUfMj<7479su&Zl&IJf)CdZ^%{v*9tt=_ zPdqh}l6qdX{+$UFq!2Bb*Ea${8|izFW_|Cp^9P}l+T2qZb1AYE#vm=i4zku#%tP)-pRI`*Jew$4}8 zLOe{yU>4_rO`+A-EMF3CR7SFmK;ooEaL8zYVpLlhSeAhYs(?AvF2HpraeAo3_RFq4 zahQR7mjQ!_k_;N?kAW$Xo$3A)?Z7A}!ps8QsT11Ny_pl`l``GI6#u% zvty?KZn+$6E-jf~+A|b^S4SGg@Q|K$Ua$6X8NcP+uzKN4Xmui??pm>(^OtH*R@V^Y z&h3v6bl-;G55VJ;vW7ViXLwmH-G>=vCbqfdp1G^+Y6R50v?EbV6^y?tqL^>|lTQ@u z_oHZQ(Ga}&5O+W@o)(5R+YMdMJl)$Cz!R84zX_R;UeX84qN#-%l`|yuPUH zdPq;q%z3usAqjI;mPdRHiyeb{EwTOEU0B5I>qtKr&>r?)_+-g{%+y4w{5&X&WcQ5P zVQ4=XCe%$Re|OQV{~e7H`aSVQjJpv^EW3`xGcnlq_X8#Q3ni`O9oC!P zLW+A6^vcstkUo@430M|ym_@!5>Kv`!<5jVIU>N5OCMl!-QVU1tu~pEX3;SfXho3W2 zmQBlU24RqsDNpC-+gSJC8=2_|$o9eD`-l6W`ian;yjovq-)DIIQ&(#zehP~u9_+!) zZb%RCVXq`(n_HyHDxB^E>c{ z%h!Z1T|_Y&q(E(dG#7$?G@*3Gdl*$RKrN5p6FpSg}NJMe50b9 zMd9U4FuNlmD&KAk*V-0kg4wgs^xxjl>mT9!x&;QgQ9{M>K2e>V6AiV|b#cM#D<1lc zB7%$|Ku4OR$VtPnwt~pS1gTK>br;bT9L6{T&d1x0vt(p}EX{195cfiKw(_1fRIe|* zGm09K=-2APQ%KHcu+Gz8>a$)(v+k3Sfs3*B+W5M$Rt-}aF8eMZC8S8J`QXAd5q~XK zL)Q@~O;$CM@$*D6J$l7V3h(ZK_j2WW`a_6K{df3R3xQcDxLGG!#Sr67#P$vRypjD@ z9kg34*QUUZCC%s$ZY4rXT1CjhBmWW*rlU#lpBOZ|7O?{?hP+Dj6AA5_Tc>lL=848n zKX&X3HO;kN@SR)oFZ}U%o;qzUDF!b~UO>G;EU-FM4oI?$koYW**4Ulsaigw}k;rQf zxE5)BW#2cRG+Qg%@`yO=71id(Q9^KT-E)-WkJk%cV7Cs4iwe66LSb>9!Vh|mV1k1c z$w^f)94f(3Dx{H}-s1J(_p8+{Y%Hmw5+7HXJ8kLYm@2lTRj!i|&vbxxh{q*$rE2AB zE1f>yb#C>_&1uTVwV);xw$|Zk>t%4O3dHVZbnF6LX8E6iIM%%QrRE~d8OL!}(F}{Y z?acEx{8L|+k-yhTrFe+#+Z;>l>5eo0E2# z&>b!Mj)@r1KZ_+`OMD?S{q<#*A^;iwLoCT9b7_}!BQ#kZpGO2Px75HVJ^43ck=1pL zr0J67(}T346LwkPwoC@m{}1e^=>gAv_g$8Q7k^EI-7GBR$D0wU4qsSx_HCIU4}^}w zeXn-eh$d4Y$}*!!Gaq8|1;i+}*X6H!fFCD{Ff>WnvxZ(NrT7ikr#pPV*k8E z&kTD51*qq-S>|s#*~g4d0`P^IbHACPmMM)H`lCa7xpeFE*h#y(>Tbh4vM z7OV9rxd579`q!lOJ7A@7FyQ!XH2X(rIYqcd`BQpX*9mnrBdzN1!zbhzJWsBFl_n{% z3rRwPmPxPKEv;D|dzo-}Vf7fqBI#fL&X;yVZaD2OeD!YxpSpxm4 z7wkZosALP5qhrQai&G~XH{~gQck>7MTJ`IiVfJ=UwD~n5xtU7shHd_{;#N*G=-)Yi zl9Vw2&N0t?QXg_dQ{RR;v#_T7fvaBqys@+wj(Flcvi|b--QZh`cdsYA?zg=1!LIc= zyJ4Z)h?0-e6*J+|A7mky_?k9QXp*g>^ab>C2kChZ_PAHKuJrW}J7um2xlL{?m;Ch9 z+Ca*)5)y84LxyTk4?Hl;{EsqQs2WGK37{tMh}-BRKcs)feeg^nDndyR!8J<8Nc=2=oI==scAvRLAnlk|;F`{DddYUzZwt(&8eRD} zR_7CsuTx7l_+;h;o_h(az2sy=#vLfOfH`PfsZbs{B5oe zB;}xidpymPl8q2~$43`PdVoM@866Cjh|f2r+zP8 z*SVI616*W$O8PZ^ewP-?a=&bMyhUT+}$Ci%;-h6pg|f2hRn2?1_L@AtBFp$)FG z@FNX!)pdnWpQh${jL3q5=nUjwn6P}Avwi$;Dgjam`A6J$qSz=B2#CP{^LDC=nS+s& z(Ko(CP5Qs@re_Vo_v=2D3B>ev6k?$bcQ6q)$RU|1C*qI~mOuKMk{Ka7)Ef}Y z9RYim7G8)h%Hvh|J_vB0@)$Igj8^twC^hDh(l9+ZW}AByZcJcj6r)iCzp2w8CEA@vY%ZUCox&-XZ_#w8Ut6l5~Roeo2SX3RHz8#9>Hkj4{V>ZPaeD zaG~<*E}6G)DbTV@CuABMb-cC`skMwb*_bi4QzX`RaG74Fat0e!E^ORDxH50ywbv}Z zL>qk49d2=%B#^7sDofjtd`Xgh{#J;03oGYm9B26oyxgKss4_L-2GFQ zuEGPocah;=QI&0dgG{$M5jq~Zck0lY^#t8V4uY#?_uBgzrRukIJMW-KM0YnRBPK7+ z5un~x2ki1n&KsJQS&O?6;nzrrtzQzNY85XGg83Vo8h+?nZ2xp#2*`R@&)B$sVes&y z3|_0fgGPcO0WGzERa>Jsi1Kr0<^JgSW}ZRXFh*I!yG=iO{+*FnQrhfsTcFKZaaA#_ z+&vCCI)}%%)85lx&Jg3}+vjbf?o>HFSpj3|;M-aLE5~sT&#;BXE}2owg4@E7+EF}H zZ7W$AIKGu;Zbd#GFy zkhB&+4JBaW-FPp%q_0eGmh(R4+!w@H93$j_|RZ@BuNFkQ10M`9rl$@8|K^7f)ety9YpF!3=iJTjc zEYiykH@}7y+%wofUjChQJtWHBx)-)J1|m6@uzKK*+|dwqa|J?1`zVR~G{Zkj zWLiSEV7T|Q|A18f4J2ae7v3i6@Ny~dZ~M76de9!y1cD)8r)kPoze??jY z|78*?cwJrP*}pI-i3yi&xpe*Sz*BfUkaSddJyTMQ3y@-Y(rONslJ&Y;cgW5QXp8*J z5n!NSK?#Z#(X>(N2;?2O zUxLCNX5N$_RN<*{sHxU4C@iwa9CBvV%p$to1q3&doEw>1BF}FL zejWL8g~I6)6r`!==OCvXU%Cy|c_}UyW)wn@!lrYsIocJ5Q=><>&)&_SyLWMpk49b=lm2BrlE+DHkYKR-K zu3Xkfu7Wo+x*9%zpM50G4VoK=B07U(+%DBArX4NS^E z5TEp57iU=!=|!ye_FS_pXz*r@_;T!Tvf;c-%cR;5$sLH2|G=JmMMW&%PvfJHz<*fj z8Fi7*dv-5_FdRt^p!#f#Z-u=4lgHc^mwRc;^$z@^Yh|XpRu$Hbu9n(Q9(f1s6asY|L>{Z+zM!BVrg&h zZ05xDA7q)LlbM^9nfrgw^u=1xhN@~SpEH@`T{K8A;II(PPyptjIARVcRhWE;gs>3f zIu?>dQ`59?HYRjBxSE1Bb$Ua4vDJ`Zk}y(C#d>$F&5g;9j*E?z?PP(|ZZ0+&G+(zb z!@r%+Th0o-r&)Nrq42AR8aSWlC;JBS?>cV2&c?lo zd*lZgH1Z8R{2?}U55;claZ#~vFwY##S_V}Lyrf268M1PJ&aLgvETKl@3nqu)j z%4(+?wy=Nts7<(;z&xT!`B5E@J%MNel8oX2p<{8A3-KD7zs%gqWPU|O5UJr#x!e@) z0pj4=bBx$w&lX!=ughJ&_R?c6(n?5Gw#$T(;|SvDi0 z@Y6w{HiHzw-}2Uq!S}PaO&lpCA{Ks#lwqF2zahoJhnhK8I1wf%#E_b~ng%r-vLFaF zx%4gdp9bcrI>cb~aHB=h6ZUd5J9bSix_VF#0SW?jAvdI%zG1Qa*(!?YZRL-UF*JwNdS)*C#K8SLU-W%sgJ(CK`rn4R-+dx`szD9<|4A`(^*`hH(+eZn znHWR$v-B6jO=^a0;#grY%77X-{(|fFFlW~^II+*dgdKe-6T)6Gse)&b|B3;Yil=Z$ z4*1tGZVG=^@9i=-u4V>YekA!=#i1IQOq|< zQIj&ZaJ@lhBxUl9@3eAb>8Cv#7V3{BYp}PFJK6YPR$>UG4WmpZU3%%b-?(hBGz}J8gC+1dpZ}5PL5NfU6yaL5C_k&46iB*}Eo^s; zE)~}f^2&9C!7vh-vn)&N7b~cI;oE+<#@J_uC%79m25oUo`8761qxN~?4Q``+pqz07 zCxHBTAptOh>D5d~t!KEqS6WBV(%=}u3RV#z-l7&P!hvX>VFxj~`LZITT$*|^kM}RK1vp0O(C%mq(41amfk#Yl@{^(Jop4>^0=UFr3Of=@orzVMd5N6i`O7ze zP)pe99w8`!=~sV^`QDF?VE2E>_d`_z0#Cm zEx)GH+eS5fU2teiV%_>!rOrfT{Nw?wRJrvH$;CGH5n01FN#ZUE6xY?v4>t)4#E46g zvbOS}np4hyXS1pf5;?R=q|P4)T|TUf71EtOK3-3^wBGDR5c3kPX&BwpzKMZCCAsZuMhcC7rD~53TfIv^oX|t=z~fB^b@$8CDGw zu`Xsxv@Y1a~duUa@X5iBK7N?_vC%+Bj4 z=d7MVdMXvCvU{duU#WTiEMDdC4BR1)dS_A&m9U@JkKQS9XMZERQaRVle<4h*R{cx+ zd~q55Y?b?R0Uj+_BxLn~a&?@vp>G!dZnCmU1oy@xXD~viTe?XG(QZ6^^zxlFA(MM+ zm+Dfza2iAdP4cB`lt3Fa;`ldCVrjc&-@wF zL$%DV)q{p(|L)n(V@Jp*Y&bLb|x{+@yovk11w6G1WNuc^`Q#H3j*e%6o+afKZPi|Y<|;`?MvK_ z&IZAL>9~(BS7ZjNUtKO`x=gU%(^b41`4#rrZjB*_ywdW~E#wb2{Ma&L>zJ2Bz3UWO z?AcU(4bp-{0%GV(6#yUxQu(yxcL~KdGVu}3irEFPlwa!`y+4?1=>N{V$&mS{oyUou7|;l zqIND=$&alRUw^zx!TaboVUl0`(<75+@13F z_>E|MLZ$AbF=`oZWFk;Worm-qr6(kE$b5PlG`!2d$4YNI&b#*U`tPybNv5@(dDSM0 zS!nc~8h%t_;!-HV7Mr4e^*h{y~ihsE8^QtI;u8`cVi-`Dq~@Ia|w*zR?Fy5OeR-{#{{aThrpu; zBXcc%RIH^UlbL_`8F)de@S!%o|5&L^xGLM`(ouC{*QC1N#FIrVQ6MCg&ES!E*6~o} zp~6AdnqnhRnl7s%4P`7yF3R`ZtH>#0KmVHlbnJ6_WhV3j9-EKvQ9x^eFFaw57|>W3 zQJrs-MBtF?Ux6U6tmKk&ckt!4{!fY-kq%dT%JzB+y?N9?rm4{W+?# zi%#q4_MTx4+2#^8J`Q8|<=M}}5A1Iv6er&Lt*>~rk93o|`#F+IR5X&h8#dzJ*lgFl z;;wzsS;f&?8+|Q+`K}M|o7>#8t8HJuf`o0uckhRcbo;^#F6xj6{i6`R#UHLq1`pV2 zxEm1_5U;aunD@uErC;sX^2Bh#UIp;0#4m@Ir(B#C2gXMRTj z^|DhFzAGKn1g~VIi6Win{gjd6=^Es=3ic?8jownnmqba9P2{2C=gF=64I-et`F55Q zU!At#$Sd@O`QC`1ASdHZc@d@DO4vFhGmW)0z5vt@9zN~03>pw=cYJFNICiApY{pK< z4yBKhM5H`WOuCstp%$aLmOr?ak{ebk8$hQ&(ZV*=p9AV_|&p@O= z$~j6$2sRy6;cskI{~B3biw3M*QKi^(jV`Eqe@9HytFGLm@rQOhGz{I}@(=3DokDh5 zO6ZRujNrEL!MWv?r4-tKf4L?ig~--{(ZzXw0dKmIqP$m{vo-W4Vn~A207M1h(bBwj z8cTgRUQ)>HzQu5UhVVm}oRk$AY93X!W5taSX-Byf?lphGC}&fANonj``;g}|?vf!E zSLknupZ2lTrh3vOvyW*>3kKU!(q2rI38mktL()tF6SPY3V|F&bjY7`xdRBb8J|%O* zs=BJS>WHT59m0&-Irk=?^GxeZR5N$%x2`7EcLYxBF_Xapon3inaI$%@G%ZH7vPQq< zdYm;caO#MeybpD1vf$|Ea>BpG%eHgC|E(T63(4oK(eKfRFyp-FsQ%q&^URS});;~q zFFl^hZReTBvM6S5qRg1aMz&Lwm2_Cl)Bi}1hp+RLzdw%@{@T%TiF}dZN<8Uwk~=&o zJ{l&q$z0yC)NvrvNhI>Nd6h@F*$|ehm08^oL*1AmHgz8WJTPsAv~bSQnl8W8?Fzo< z=Bet>#XfY-ioJFO^&Ji_G9+ksL@8~KEGJr7B-RxPbfiHTHB$|nEQjbV)oM#PF$SL= zRcnILSTxoZB>|EXWS+_CO4>LIRF5LKK-v{mI-==?W}ahiiDWv`350E)OKpb;n_%n z18P*{?g_XIZMJ$BVYkbsRh`L=|D4cTF_wvR7Em;>PNM)<`pNbrl)>!H|eAMY`ql-@D-AOh3yd& zg7Nklr|6>(UxEQR>XwITj?7)0G2-x&w?{z}@m^1UN|tC@Xjm1_?Fhil6ZL3_^#4TUZ=l-1BSL2RY`I+7^A;++-43 zGOLFiF6hpU>x#CsqOLSW=w-X7+9>E>KL)F7O$9|=$O5xcOqjNQ`Qp!W8_T&uyI>X#pRG3N2J_hu;{SyO%se(=y7Lf^5>j-amjdf0rk&GWRe_K+JvACyrbB$Q;Hq{z#<1Z)q(qf2Dl5(bxR*kkqElqVVH_ zQy04S`9RsC#U$I^M{_R`(l;EmcPhxhuJ0bwHyE^cA;_M2FXNfkM2l1=3QgQ8D`wQe zwb~ZCru^!3BgDqW`iifvo^!JvA=BELZOAy7Z(WnaQJ1Qrw%qwO{4O;Rdl+xk~H>*myvPTSbHTpYp&Rcdw zBbHvVhqx_jzNL@Qh#g`?%Orie1SLooN5sacBbL%kcw|(_6M%T{YEr zy1Qnr>4$ju*ZQBnh#fn2=&OrAB(*3JZ}lxpd~mF|Wu%JLjYuqCHA-xxwYEm}N6=muPQY@ygMJIWd94@XJ~UnsYqo=l=iHSa za-eu4Q?Mf^%8=mRJKdKzwwq+ob4aKe6jN0|Y@&zI$n+Jv6f>mC^75l$V;DWB@SN;w zppe;}eh#kP7|VZ#GBM@=C3kV4_)xK~a!BN0&CzR1K-((`H-<2}a|61zo-;oX~xH&i)St)-f(Fp1O zmPS*wazIi-_O^~Uo_C^S3to*(-XJVV`2y_Je+JZ^_-7Ay)n7Wn~!H{?4UE{^}WN@Z7S>It~%QrM0dvlM@W&x z4p%qnRyu`$U@-Lo!CM z^!77Nc5@y^V`Mr|T6CCcq`J#nT4cl4rYp+{wY)Se;B-zz3z%R>vBG3bR_NmNwRh@n zo1iCbn{i0Z&Bot0ToBERKZhak3u!Q-hh@hPfGu6)VsTxP{~+ke@BZqKL+F|F(g2Rz z^Kcvq&D?whn?ogM?!RBAEFW9zVUz?Cv5VXRhWnwSNLGBRwEM=d4O+Da8dq0{9zS-a zjVn>SV*mt0$$)GSzL28t)Oz^@w1uQ?xQ(<f~gF>K0p<$@I@8t zCv$_*pG)@#Lvrm(1qs!wm1`nr@FMwFgC0Hh2bvR1g}&4%Kas}zS9*`FjD*_@uBm*&f@68-xJ1Dcm_iH}VHNgGEuWCzt&Hwcw{;!1lQW8&7J15$LIs-( z427LmPjE)&>s*csDBm&RM$q?)CAb<>~cIm!*L@Qy_Auv|XD;VniOf}Zr z|719vc1&;k=YiL?iwCdpwCjihR!-jxN-=_8*!EHy?e%gIt7vT zCfpP1VxZm|ruXg(;Yqw^fZ$2KhN|*v4%8WYPK?wUcNH75F??4Zx-xv%9>OzxmmA79 zd{-ONF??4V+A@6C8sag0R~Qh=L&5ku7{g7v=7FfD{~e>A`X0LDsGiE# zZ(MTRDv7s{P?UJi$S|Zf5X-cFk<@7w&L^!w(AqH`QpRxDGBhHb>*pLSs-JIWX`)Kl za4yQeHhI2Cs3QZXkz}yUPjQ4l$<%+iofCJ_Y|k}R5_d8`3ZwpjJ<@JWyi&-~Pu5Sg z333v7$r{CPkw3HA(w2!`TPM6|RPq=|&#q>1ltG9n5oNTY*UvN$J&R(z=%_;fdnlcm zUU0RN&%UK@cmmVwC5|e1quOS4CVbJL@L@uDgZX7$C$goVn60Udge#-r;XEhKF1Qk( zef+>J^OMMdz1aZIe!^)JlgDZdD&FNVyus?YY8FGVjBeABv9@eK>A7QL%^<}kboq1! z*JR7QrBr~rc&r(zZAES153XjBaJ^HT)Xq7r6~Tr2BYJ=BjX)6Wyd1k}yd@(EFvO1n z!%m}CEG`9uCobRMmAtFwZ(+nNpfwS)>Nd|uk86xd;3b9SvCbQ#%Lq}La}+R7@p ze^uFG!jdf&0mQLl{SuK1X%}g7lo4w^xnFxN(c{?E!qa*0;h!fTA47LfQd|JtxuDI| z6vjJ4GDho+w%s0D=WX(#G;#d)c+3t}W=5l_y5$^`M}rSiT5L!7UUerGclkb=fL}W| zVX!aNtn`G@(^utQ%M;M_8LEn`=Wlw+G`Jluj&12?6-cXn3N*XnAqX_*@h6VUhb1n6 znHUtwSa(M#MGQfs+&7}-BZJfy1K_!J!Ab0q_*~f#227`g;K7487+ySte810G&Bzsk zm|rQI=f_OIrq|+_2Rgy0kWLyX<}i37XbE`9gz`PCQl3(3>@=|jq>OJ>x_5G>{BpcMv%mL*%Sql)^3A-TYrH&!b2pyq@7rGyBTi|R-d2#L!nhmcW# zmP>Z|r8k2q6jet`Em89o7Lmn}$eH0uC_*S|ArqDA$P<+qqy~w*H2W137wXvQv4iWz zjO*FR)5lMhm}8Vbpf-v3=u4^BcEwL|OHaip$OvRwA|j0sz0OFUuKbrw@Wg%U`9%R&1+>WNl!dOcMg z4w9j@IX8W&N}wD?X*Aa`)Is1$&HG1MYQKeCkw;g09A?10rgi0Y!Xg0pwLNR#L*m6xH(nJ5c%Tt4ox zl>0cfGff#|k_m1)XTD%VZ6KF$mT9x}*J|;CtOm_I>#n7La=2n;^N%j=Jg=2DJEfE&%j_3M5X%By~|g zRGxq_QF`t0KRTR)npUy`tEq&2X!@DwhGTm}tDBW3{6@5Y%UFbmH{#%D|LQ^wwxnAL z=U<_S7?Zcy9zP6C&-M{x$jr4TA#8%OchE;v>ZAgb+u$cBk(D~zSFssyaE@vKbeVC% zhFOjhUMHhua$WV5@N{I;LifXMtT7v??#pd)U95hnq~QRt(nVzI^pNA=gE83s`6p?> zdm^hRLu$W&9paCTxmjvY#~ZEB4=CILy7{V!{QMtJh@iOqM7Y8*xV=BH36pW5S{o)@ zO5+#r(22kd32QR_$F(r~QMx3Wkywtd@?5dok&NQ(FtL{;ny{>e)lOKy7Yov}`UNQ+ zG~ZrystQUBUkzaETXKd%;*JjfN@>tw$9-Or>;cI7>Bu7n?;7s=#CUoQo%^5$Iqwj< z=jON#;MTX6l<(78Ei}gr>s~G;RHf(7)NSVIh+10=T zLy5Y2PPkA^&S@Hk(jb)5B)5N=g~5R6%lVJOxS+4dlCn^mOjs0Qmi2KYB8Sb-V}SMFB%q zeMkX_{F>r_0^mVAT0R2FPRETRNxO|pJ|l}IYK7Amg=D}CFG(;O{Wj&^57`dx&!iIM z9G}`gKj^B*Sughp)FVNN2oyYE$kvS*~vsS+uJum@SKU!liU zXhLJ!^~FqSrEPl)ES>3I4=Ls0oSRmrjt5wFm4?`K)_8;%^Gg`JA$B?B7Kk+8OO;!;EHe=^)RaOV$Y^z?)UTw8p6RFAQ30so#rhv!B}EGYaYD`TzmiAls-i$kg&+546rTtS-UqCYBHiV_{gEKc4aJmaa^iG;KBS14y(KeLxDO*;Yf{3&E7%B%3*G}- z(*=76#j5`)Xu3v@{w&Rel}Yc-$wk9;wLO@x`Ek+KpIxdM!ff$-MyB0zL2%((JPEJE z79x(lfQpuI43Fq%jih*|KAUpQP)>2XKz1qZK*YWQI=Nc3>&kLDq|JQE>b_W#=6nrB zu*s;~e&qNmMo-OVTwn*~q$3W`HKuV7ZQ9gt=O{0MdKeQC52XzhV_y7^HN{#TG^XI% z`xAiDZkMeZtlV{mYx5N=*P>Vuq<%3J2gF`Fe~@UXmXX>}B9L+HC)?~jKwNUy0l6N? z{u=0yoR=%Ayd^Q#Ve&=R#ha8ph%EXF=LT%(`lD?uKO+l`swZJr=;^lF3urF0R{Ju& zw7w^Wh`T?F+3gGRnKLudDD1w?5@X}>+AfOnxeKu&9-o@Zs+NPOt6`{ydE!fp)RubV z3k4B%l3B&Rd@Bfk-&`RX_jb#68}x^vn}shRpzRXwG9>H_&A-)~xWj6$?wgW~TAkA~ zt>#W*w3irAH1i!Y1#lI_UW`KWJKT>kdPygTN7Mx(y?xU@0Fx%YM9wKD_0fx6@b<}E zAdn1Wn)7JGN@Ksd%Q1@RknAcIpz&#wK7v(|xTFR&l&=6^yE1Yz!Oh&D;AiPIhY~|A z!8-NEG73gMg69Oklm)S2LiPX=Z`6^@HC}Qm;-&oR%?wv2;vnt6C`NY3D-j5;9^hFb z^e__)Vdi``;G=-_us{ESmuP0{Gx_$L`VIY?+4NsEe)@lV+cqk1C?KgIe`z7Af|vh7 zFK_y-Y=9MrIA9|;<1cOszyt`aZnUDgK1dYNj>UbR-1vAlYBHS4?O4D{^(_|C8R1yQ}&75prm z!%M_^g7qkS7Sz5q*JA9?qiH)-EoEDw-WJ{q1q~1pgpCjyOBMK&bg9!&0oc(1z<*qc2{NfA9JIvZr{sMFS6O*C zrdqNR7P$PZW`_oTGnWriQaLa&)6x++#V7*fgIA}rGE|RaOgAtvs<4T%*}oY`~f zwD^`2Vs(_}2>e5Clk0-0B`+%Hq|I?-Bu=>viaN>FGQ!wnuwU-6hN&&jaFvc4l?*uF zE}9^xaEXH;-?3teIxk&#DnVmu8gTM48T4IE5ZV~zzE+t$cpd!AqFKYk03o&K(X`_k zL@raL-iPPNwqk(%h5OLpGDA$8Q)Emvye;vqW4k=jE9#S`Ysw;vugbZKLyYA@>4b=J z$)IXHE31})UI6X7>Y*0OGLK0s*sQSqoRR`z zL*8N0mAeKoD;tg)*T=ZI;pUKu#q#cZUR`?vWEzaEBTdOu?29HWx;x7Wo7`|LBgw1C zD76)7z1{c(AJnUjai%k>^M2DjXNbmM{Sz+VF6IjsQZ_=D=B659!H@p+N3Itf{v(rD zNS#e6MgQ3!6<<7L2*I$;ta*NdG%t$W4kS=lh% z&0}NGpHsQ=_c`JNP($S>^7?T;TFgwW%hws zMVZP3SYUT*bY_Z!>UahbunWUkTN1N71!&R?KEplGd+qXC<}SE*kxcVylS+cuu`2Zoy?o!=at!6 zyNV-gW_(J$3~BI*PLC_LX@@DUqxJf?vu>VGXx@M|KR(LP9WOdh_(6F2T{F6HqJn(Y zp>Wkrr2Y^qnGYS{a=CR8V)1qhgbIEVL1EcU}37inRhVEe`Mh!*F2(Z}Uk4@G-s z5||~sk&V7{hn3{}U@WC^SL)w#FtaZBScToas23xCR3MZYDR?6#XpJbzQ z6;rV_VKIg{+WwyvO-890M^+(N!-~4hqlG*SaC>RU6o0hqJbx8uJ`@lYx``PQ^rNyWX?BkcG(&Vq=j%dQ*9bjXQbQPTS~XhBEElS` z+-nJ8v0ke4SLm#7j*(b0T0OZ4QzB7E!%(F2(Pb6g0PC%HA>d5w^--&~#5q z3yhw^i#M=gL#R3 zokjBqW>mrn-2+(^pstNie=vp!W#_OFuY&0b|MZ6BirQ7eL~3B?4gK^*cmNArxPc^8 zD$9||EcsawjhFAW3vLgBz@*7H?1KA(9+f=Gc@4&X&Czy4;x+j$B>Y9p@Wo3sYMY3> zmvSE&{Y)K7veO_qjTzsCggME-SmYfulh79DY;#vCQlg0B$sbH6`L+##M_CIHAA}hz zkK=~J;xBrV4j^wG?uo=h|m5pxK+Y*11_hC}d(L~SLT_8LPwBl#5elQYaO`PU*)>O)@0 z1D_F4ijhj~*e(pN@fmKHT8yay`>);{;(IooZc2`Mv&=0y$_Lr{v(D7k%F`l zYYnekh_4sFS2%E6+%bN+VqG!j#%2ZWYOOzz8JC45 zYRN#{Z9d~_-&Iu!zDgjYhh3&Ty}|wctIC%C>Fe^lSZV-czYQETDo@&A zDZzh5bu&9JGQ*hl;`;&QHsTx;2ccrJm?^LnQcGj*62_v!rawq@F1WL7Y{cGA6z=}O ze%0Cc{}UVoG*$}s2}a2K!;kkTd?=RwW|f%uuBa&Wr>l+eX2;9(WJmMcpiZ_IEN}ms z*ub?uq*@1IX#%9S^bWFiT>lC3knHIYMkEC*1<{ebs6Ktr9VtaitRSWWBsIBfVyrp4 zlb+If+wxD@pxA4yA{It|^lD6)$pyE;Tg<6&+s1SY_OAw|jYq7Bs+1&J%;-HjErv6F zHJ9?DBN>SRBK|sOiPM*&Ug7DKrV|->;yWC*N@P@sTKf4w%Y}x)33Ugxmb=%w!T78) zgX6`#%d~hK2m^XNe#a>_k`k0PRO^*FE}0tJx&+J-KAqww_mr^);-ZMyiVfx;EA@CxJEQxCkGo0*;dU%ma6vTg|l22`4ge2*hSgC>?8^eY8>Np)-_*&cedx*&vfp@g&iKyQ8>W^ z=C&^Y<>%KyR5>}HL-nSv%yc*<2s~hLT7mV>0d@HYx4(8jr!9PdwvXYojF@Vpc`H46 zj*7A3Xe=Y{d**J$U2(7y@uQ`avq+Xpvo0P|mo_xI%JzOr;9cUb&Lj4>hWO<+9i}Ha zi#=h^zm`!Vku>(aGPo<82NfQ+M*>mctTrdS#jzkpH?=FS?Zn;;Ofur8C#_^_qThzVkE}ojFO3^;z(`>rJB|*Bxx)5>k zwd~gKIafo4vAx>KPruhg>Ad1+DZqQG-Fuw5doIX(prT_D%2^rHxoOp6oonik@U?ra z&HSw!?hik>lWBn1R@z=1-pg$a&heAs8^GWnymKv4M=9ZX08k=vN9&LUgw-c zW{>rRVG!7RIA(_-aj#f^?@)&POxz~`0RRTRor>(g=urNx2jee+m6)}$&EJA6c`2KD zUU;uPRy%#kdCajVksOdYY+7u&=h%`!WLjI>M4;xV`qF0m#Xo01-N~*KSQSOFp8?-V z2P!n=dYP6to3k?AY+Q^VkE*YD00ftBcXE&NqqMP-IV{)fY}fjNLpX3R5jCj}bwo4ASR!5olYlW1*vBFhCUXs z6doN73S~?=@}gn(exbam{vKN;iLg#2>&GGjD~i91!*N%J_m5kwTb~M|i~q38FqR{` zS3D%9Fs_SyMDy=H?wnB?I+Q%1pA7H2_Q@-<|23wXddiedwDqpxdAx%Q7?X(yKegr!#cdz)l1Px1iD2&&=J=Gkkl7(lB6^tcDk7L?DoUiD^%q~qPk z=~qRTc35))SE_O#i3E{2I(4r|%#~HTjdK84G3=Y|({5zh*gq%W$Ye>Hc0w=vgady$6@vK{=(1V^gn? zCh6t~;gl2sgPZFR9Wmrk6>-ZZ!`f=}n?@0YU+H)^j#FGzWPD^VuaQ%@SgX&XA|k>y zWA8QL1}}5Cy~IBv7cKi}H_WqZDj|b&MJUk|(3MZEOIDG>P7WpcRP!*el~X9qKC}2# zb0;t27>e=S=@vLOJ85vfRXz>lmUVu#UQ-i9>6&)!o5PlKX>>t4tN6|nZQ)L+CZ(R9 zu5Eb~D#J4j+9IQ4X0(xBlkhAevtwX1x$T+03W+KC^c@DRa>u>4na@$9=*~VGS-Y7AGLTydR3#LHkr0q~`9dT(MA8{cO1hNI&-271H_1m> zhQ%Sq?>OW^xEYxLtg|-M$Sr-gqUTpA_Jv+IiXpkU%)-y|pX2IaS&ddZwtv0{i!pdR z9L2scMYTS8k>kCr_|?>|EbfFS;9CUO`pzmsT@;GLx;Lj(e;!-aF*~W}s`fxri+2IR zwt8D+u3$uJ0S4<+>5ix|EVoTeeJ=Dp=k2N?g{7>W0?nqFcCzVOnZdFQNNKhhlNzy4 z$U^6J>KD*hhc=T%SK7*7$@E=w5V4v>=Tg!W?(AwzHV z8=7Fold{cjdn#+01LSxnA`ayAD#7?aePyDV1s=k5z7Q3(<<+&oiv|QUfGjI2OVb$D zFLoyD2Cx9+TsPWEKsf69`FsS*#!*M0q-sTrX%;bR<4>{p9Nw5&^?GcEa*`b!>`h}- zi*x|Uv=U%r%W`{~n}#~@8IU(uaqqQPWV`z!1uF+Nyp%;K;bFyG`}!z}uQ0l@m$5oZ zK#cn$e=~qSg{IWj1b*`f3JtyLW!`@`Ugn-kB5)FLXW{RO|J)$Q*Tn}t+l5N3qvhhx zqTVyRMvtVcpIucZ11rPhxBS8ErR`}Y+yV3x!@qf8${!HFT5eL@Q_3G4&pws=S>AE( z-YoWyJbeX$ntNMGl~s`MM3Ge=3F`HOL>5tedI-sjVs}}2LVcc9CO3Rt!IGH<$Y~|R z>q7}57c&f+AJ1;nse*13=?tqR$Q*7hH-v*AzxFNm<5rLtutPB*%9-Z*pl^FQVlRH<&{*WS*h6Z zFdL#A(5u30Fsu9;Fm0*UbjR*(y*UE+{(MVwPM~i=mzb~Lf6w9;nVDeyiiIlz)G--mnzt z)&AAbT5MQUTTR55cId8Do7orT0GqwFw?_c{dTY1aPeCh3AyNC)UDXy>3D&w=SBamC z%9i1N%8D)PerHF2B$jieS1HGR`WPQ7>d@Ryqyw&YujnV=4Q`8aLCQX~(ZN&WtSEqC zAG8Oy+h1@4T<$vAw@j`-JllIcd|7#VJmS)R?#;Mm_ri@O;JBGdmWel3`?*eC&<+~V zwbNstTQ=wQrJ0?yN>l^Khd_I$JQ6&FmHie)^r*+_a`fHosnx~^1yu*?<%KqnEP=45 zYZh8igh$@m6M^O)i6K7iLS-{`0(qM34h}z+WF~n z?G>fSzF>eDuGA2;MwOY({EXp^%2&WWgV`(XrXomLq8|iL)Y)b05wtRk&_Isp=3Vp9s0^g@$3!8l; z;QN>$a`}9o8!%I)r(p-V(xI2r$4LD^UTHS?nA)W}_WDv>Y8^NMDdst$fflOjgl~9L z!fyWVT`D4+2%U(0SS(Kxfy)%3&rWPiRGzlZ7l#IFk^+I3r5R7WBHn3;=u%KjXjH|F z4UAjnkDxUKohkm)hvnmwaWN^QN%lNn;ao)Mx0_kYa(J69c&+0dL8xH!6d)LbUTq(2X$0N2!j1m!sCg?j3U_iK!sh@uut_~wnI zl3>HJm!J*{T*E>Va`EN~5FDg(gcS;5w4!~h|8$K*lEtH-Y_wa3u)F?~lWHl(2WBz^f zFlY51WClK;jj6(DEUYibW+H%HxzH~;UOexHoJULN^pgvZ0D=+0Ox~#!mnh{_&ZHDK z5$%;uKBCm*k6D>WV!k^vdznaY(Xn;mTF;v^lM9%)+@T&Ps)Ng{%j{-UvCBv_k06y% zCu80@sZsO2yfjNI?Sz$^Uxo;2b@KX#Ax%9_@w+uSX+4gElLG#th`*yE%ZZUf+bAi; zRZ(PJ>BfGF`Xgf0BKSM!Gme93ST~pzN))dL%K%j|wt2Dssvr^VD%4#WU#+k6{I9m; z(_?ORz9$8Si(Cphkc%M=BRis6_w3gtUsMpt^0=PD(l`L){__u42J21D3UDRmm56;` z{qGhxm61Yi5BLvnqJhu^;=meYT?l3eM9aF~qHSPI4>%O9565_gV0Et8J|d1@p@dWV z-UEi2l^GX*K4G{hkHn!RieLqI(>}l+BCj7tOx3YXT8ag@uydv-5z+GA5^8cZC@dF$ zTF&-|>D>aSutb$hL@8os2J#N<>b&bIa(~Sl(B9i&3dzg}p5~R_1EIeVYK3?CWr03U zejUcNvN%3?iT_$3bk)qHF>(6jmTK^WAV0&xMO!_Oak+>7>|N4d(B7{^GFvdUQr zV*{mPQn+^s9<70gI?82jV--I<%@iDg<$iBBFgDCEn!`7q=OZQX#|tvE>rEF^aZLtV z8ntsnJ1^Ad)LND$21iR;BPUnX@$S2B|0-3#GZQQ*#JAqgR#zTNrY&Yj@yVAZkWem6tcBt*mTH6X;{c zVYS>G^NNxtD&61%8RQLpu-UWODTZ`RMPArkTWq8M<(-F|0pVBpJ1lb@ZU=W}gnNb8 zM_c}+RjlxcIMKUK#%u}@EUwYccg|w3hi?{_+$~W&ISiqRoRk9fk0cdMgMd#+C3(Mc zA=+usV*n#Lx7snQC=|vY*(lHsshI zJRPR=RLZf-y*^4m;%~N}poN(aYP_~BCH?O#?M0USlX+S709aqhHxpOJ+)E}dW%fkz zdUImvK7sSNrR;Vf#PpEj`?4g0BZFL3GPu$FpTVVC(U@T(%U1H}r;8}F1lTk)5&i8G z@Q+^zyW4=f<%~cALnn35*u_y0KRUU-z0MluTx-&ImLuq*gm6vZ{)c*vlOa$7zhtLR zV9`}Rf=FrIAXk2}aaVi`(dhy6Nue4{$2qCej&|yXgad8HTKvzN75CD%)yrC$i(EG? zMcE5haWuUh{n*DDfAjXYcylmshU;<#sR4rT; zeY=iG#0a&l3S9Ml?R5c($9M@`>PqKr=aykEL@aa%R zZh}A=VNdJQw6|80{tp-?caPFcl#p`{js5twa29 zVZd!a39m|M=WL~s-#h!wAOyqN%GF@6v^46brSriILdy=@qg*<>!{xv+Fld-I-i zs_(}@>2VuVT| ziRL*YPX?+3jglZ6f(V=9Nl&ngZ4NV*Eg`UHT=z7WdA+Xe%|otxd>-EJU9Wo%?^y1m zkmX6ZyBAO2&Uf(XqkxV;yaT0o^tWe-%Wdk-KABsXcjT*`V!j(nyq%+GD`fhsTfNUv zox|yu660$+D@ME}@s~j62%Xua>vDC1?xM;AJhQXs;nl|XHfM(J+>KEi^Y$02i=W+< zIJ-{`*4{cC!Jka`HaB31Fs{%jv+{)YGBbMiHE?v#LZ`$mEI+@kOnYpPXe1|kMuK-B zBKDD9*#;*?am{zT>8gFUzv;U4yAFYAIxpdG{R4fs;M*_i}I_lrfLYcbSNmi5T& zjx2}u$h3Bt*swJ`n;Da>a<|wl^f??4X9jwGbwgCrdVzS}BE?}Awlc#zuvHS$ zJi;#Xakon~N65DH*LY!hgRwhKa(RHH6^Nr3&{I(1!d{veP&33Y&0nuki_#^W>7}Y? za;Yt#TdoKyH`%=!pV-KVrWCzzB==}Hq+$DE-@SnA!{`}{6Os_Mu&)wC`^Bf)w!6PP zS$g$_erdTRNs(c)Y$u5wAWkP`LQvDcQfTH?2wxG|Gm}(FjzYc~zC){=m72Fr2~Wb= zQmld29v4n9=*_~Z;?={Q96@-6BNHvkMT67e_LRqbUd4hAoE-5%)WQdin*Sy_862k3 z;ev>R4K-wWTmIns5Wr-mp8}26nd2$a+hN5*{R(W@QAB;L*Sooq?K0qS>AHh}bznaa zk!8ervPbx(%fIGYk*DG@0XTx~De_K6QmtYg`>fi5a z5!yVZfbx`s(pmV}yt4gqbAbB}sIG#j479dTezbdq z?M^#SsRggBhI(*sZV_;4PckU8MVc$|s*- zJ}-C>mv;Mz8m|P4zg*>p_&RkC;Yhw%=pPN^%yc7k_p9eWr>0nA@~IV{nT}u&ufZhg z%e}l$taUkt-I7lRb5A}(Iwi8sA$Mt37AxcD@njE1ZBKW)ErbA%s%RfB(p!u=@A_}U z=Ahh`D8fJY4$|>#Fekd>rI=u)I<-DPDYJF%fvJo)?0{rg; z<6qSBLfil6;XAPi^sN@&|MvvrKT(Udk*nihbt3pbMk~yH^MiB+`qH=AUtbrgD$I^W zBUvd01Pr2YZY?xP^Fk8dc! zzai!R*C73$V&=??{~XXvn|7DWhKyLI)YQ}$TdjC8``V1X6+9nx|0oy?44UC*7b=6p zot>REtw-kaAcp|no=ljPr6s0r_%^*;+Ja$~<(raTz?cg%N@#_q(i4aY3QgFC(BAol zX`@U9ex!c@Hu3bWkMbK-rf(7aZvkujmlbd}P7eRW?6qn9ukcQ7N?^IA!vL$}OoBe!97y$KGEUxsFS$VBb7py~9qKfjzRxhO^ptDJyr zVc&aV!O5b5<#{}z2KAjDtD zh6}ku_x;>wyUNE0EJF8a>fL9{y+0+HBipo{1QpT|C7`%Gdz`&EkoX_8QAqsVE%U7j z_HW_;*R}CK#nhX&{!JI_VqhR}7}qtLPcMbEF8p5{+Oq&vh=A1~o{bKD$}P*Jw9Gh` zsUNd1t7~}di&d1H8u^}|wr*YWZf$fl6c>O3qc2-kxP0q6u$Jxd(+`qv{anoNeTy4F-yCo;A8i>4>I^5=ET(T~2% zEvg>zA>)Td3EiJRGKaQLPLJxQ$Z{e6K_f0)YM-#*+Q9f0p8u9c9QE|So3{QZU9im4 ze>)lwo0>47oYXffE-oFhQ9CV9-8mNCzgyCa=1==Vz#KFFOp(@C>MF8${7QTMTn_<= zep4xgb(Ap4n#?G9be*G!Ms>!zFgU$@ajD}u9eLJqg@229@LU|WI-@uYKd3MKUKuh1 z?p4y8V|AVM5mjmJy&dkHGYOqlqkdB=+cz=)vJ*O-JbsVtdH51OUXBygPyaE)-uZWB$;bNsCF$Df$b)+d4DAp zY0e6t>ot>M{u8r8F_bfQJaLkZ)n-Ep!~S>yo~FzL?mNjg4$=8*v>Da^=%QSIpe7vr z2Jg?eu>H3|{AZ5i{~rivuKx;Q!u!$I*4Be1Gfc*vQi|X9{l~`xUL&%7N@P@&#=`eN z1>Lpu{(H-X>Jv*2?tg^M)L6eo-!~?c-@@{r#^!rhgOTO`ZC?K&GQfnL4op`7WQY1B z)9|pc(Q9xYcmS;#Ah>bgw4a)IyeYG0QKQf~Is9Q3f?~Gb>SAvCa^wLv`u1|(*5=~I zdHx#4a^`N{a?Z8>HUpPo>g2qQzkW9UeLQ{mD*OssAXFYD|EdTwv`wxKuCHy~}y8r!r_^+Hg|NqCSJH|T0N`ZV9L;*xGb!}q}R-6#~yt}%( za%WBloq8dk;I)1I{Ctg3hh&o+8XBrJ2ees6cO|j+UU#l|!;*#jXZJBm!6f6?7>&6p zEC2w`&;O%Kax^pf-iIsaq-W=(N5`P}moG^h8w);bLt&$D+cB`zb8yI1h0@hnQv3YU z6nj!twmcYc-VEDq3EKP)J-NEdB8P5dUM!Pu#lBc;{t zS(IBI^Mys9K@F`Bu8iyj-B<=fzj}I`%-Q3@{B(%ETu3CU1X<$Ze){^n`wq~jzgS7C zJ09nT0e<=^f#N~+d+ZqDcymKzdS>*}gm!0x_tW&zgsqTZc#7M;*THu8ZKHr@!}gnO zt6+F4hfJHNZDcSCxDKj=N!6j zSw08ue?!kQWX;_(M9&(~#@|NnpNF2NU!fBwd?aWumVjvpG}YutRQAMKnSx z!2Tdg@P(a9e1cf(IFy!BRgS#cW>_$N*+FHZ0>1GPKO6CgDDj#}|7^5Fj(UmZB7F)WntZ^bXJ<*PNBw&MIn{R2fw&2D3{2A+tp(iz@x3!XRystX?&f z7Te7|T8ln&4Dm;N7)K(i5rc+P#hCoAA+tr&c!G27?()k#OI^`DlNl-sXePe9 zS2B!oZi6T>m-XQs2tl?=7Aj}dqMP&%KPXOaqwM`jTK!nxMk_;;0X3_0V~W7B&9x_) z%>>Cl#1t`2ic$Nip%h|s6>m}DBqsz3&c}Ga*{H)1VsT5MmgL|dZiC7q^+1$7navQ? zRAS3IJ-3meR|bMB<~+C;g^Xn$y9|OPX$PF1sqt)NX{Wx&LwF)0ifvmfwr$(CZQHhO+qRPx8!I+ek{NR)H}C$RU3;Iq z&)MgmZ?|fWs`+VFjWK5Hy|vbVPkUgT-DZZnYVHo9jQZ0#EnBHapeEOStOlhwVnBc00+h$)Dcf=j7vGlXfOHk3Cu| z^}tVKeKunDNM0z025=~oiEneNDvOZ@Ij6<;%teuRm%1WhWw@VWOH*!N7DY+)OSx8B zlMp4*qsvILBP2tew3Xqbl(gl|oP4XYTAjrH)W{H62|eB=(x}O3s^^JS#b^5_63}y= zuyR3pt_v0I6^{PB^7L`-0!v=rnQLjyEiq}di9&Dat(2oIX;hd|9>10TmG$}&qsn!o z0fXMzCyi~bQ~$HfR$8->FsdY*`<7Gcha!WU?}`y=eE-q^$GXpmLHwgaaCeI6RxGSyw?H?wc|z1QEX|l>1*Yo5h!hs5cISL znpK9Bto%b8ThUz7CaDyRRR-K8)qybjnAi5L>ZjI~Rl!4-jptrZ_3LMfXm1IP zv*FS&t<}AeSn6ihJhTuKH5%R=3*%^22J~sCBFkFQsb9BBjzmG~iC)I(D%;7JgTP7a zAoV0|nrNhpW5^rpQVX=SzoH5F-?+Hjw5~UVAXZH(xNPtUinCpmS1W>R&1VMAg({m` zlBCAh!*(cp)hfUY>)(n5Pv&1=J%3F~+n!-{(Mo%Da;^20;E7a&{}fqiS92%taVSP+ zGEP@IVeRrSBsu77CW`O2qUISIbemO^huI}sQ>Wy2_r9%$mIs}Zpxi#aOFJfAn!yc0 z`6|!FRS?UF>PWkeQNpVMJ^`DEPSMzL8llW{iDwzL%L?`Cw_4QAw82qOZ+Rw_105 z9;L{rI=QnV)NdkP&g@j&lbcu(<{ytxys!qOA&BV-TMhku4R3eNAxj=Vn--;cRfku7zU1$T&+X(mt)0D6dBu-qZ7!JId; zaMERsyjDK>6$Gzk@q@Yn_KilT%UHWgH7#63y1VUp@<=&UX?R#V5iXoBDi^d&8IL_gf?~&YggDPV z$X(&X3WBY}K*zrHu@Hi-%Rplvf>`g5JwAl3spqARIfU!yfxjO=Vj({EfDn4pccl*n z`910(@DCs?dHz5kctr^PtDWi9 zTMDbJ1Jx;kO)0lh&8s7I4J_~h6D;e6owmpig#)X4@B!F76j!_6Rj-_^@n%$Nmw=@K z#(=}0tf(E}1ZA1v`vKpSee(|&uqZ$>3ry0M{D8coEG*LLJwT{dNxzt0QTY7@G`|O~ zTxl+lZ_K_y+FyAmU7Cg)5ln4R{c0Zge~GrwMjQ> zt_ZQ5c3oKzoJp#rDqjJXI#vhezjVV7Da2c<{URI~+f^yv3fKa+*FiSUf_Zh1ytS)O zW+sHQWK-DlV1?7w z7wIX9wEK!H$e?$kkJSkj>?-^j#RW6J@DosY_e2>?C-c=w{R8JkHIHdkk1f}zt=1kt zsw%FAdFZvdQ}2VQPDf=JI$+yq4oFo;bj4#J!bBU>IzL!);+c+X$0xM6A{R?bX?#?P z^c7j_@2uPRyBt>GoYLY2>a>vS4&tjx4+BpD+Y7nhkc{lx-$^Yt-?|BYvWZMISgJ)%qd!DRzG0 zR;_%g6Wcea*Z2p!E)aPozAYByk?&@=g$oF>la{;0@%xmHu)-hOVCeHjytS{Z_x8%Z z?rbO#O$FAAVxLzR5j_JXBwpzpMT#3L_7PE-Y=naweMlD~M_(19{Njmg?N8_}XJBB~`;U=sY_WyEh z=bD#M4QJi#uGs7qNqTQ>SDx{PV#(2YY^Xs2D*DXXdMw6FV_#KG2$?g0a2Y`HpvMo2 z`_J|+=-&k_9KR8YDddkI>EFEje>0=TvA4Of?y0Bc(AQu1j&GeqjU}?w;U{JHaLS=hKkKS&VOh%%)*jS15RR^1cW2h6yH{dWAJ_xVI2d{FMwUx zGegf>cwlrrbC3L(F|0Z!zL^LAFa##w1b`?EVd^CULA_1~%7}oEO2$_P^Q$9f+|*|= zyjr~;e1Vi>`vrE`{1U+FleZ5QMn0;hZ}3tSL(j-VdPps}MFeX6LN&aG**6P-3oFO! zn*_iPx10EIM^wMqAqIP-?R&%Sn!f-IBVgqjzaS0AWBCmMc!pt^^ipn>p<2gTb(`fS z0HWSzq%YyIo^*wdI!mu6ewK0B%ojRo6u&wWm71HYDkHyrMcOe~q=zOvtcdKY-gxG; zV8pVrZ=*d^{SMpG3P&}~9X$-hYQkiPo64H1a@nR!9fvh|D(B*z@_5M#iH5I`>`G;5 z&8@@e4AooAKZ3j@W6f20QRLUl%FHF~+P@_&qfM`i4T-GNNO@}an%VG+_^wCvAjQuO z%unb5DYBcgZA2w9^#;SpYxjCX@PZt*rsz!%=F$mp;<MuR5~~wwHpk z`Rr-p9={k=k%*@xaqtuuYMjyKOJrsrq0EJq5h>+R6=;jog;3p|71FOdPQNkF@&i? z(PlgIq{u5HL0$j;iJPmrhqUH)1P~Z$#CM#2wqK8rfFoA%M`{#3LT0ChmirmPs*`*h zji`t0T?@kyD+1Z<5wb;LqB=$|?15D;(ZQ`(8sl7LM?bHmt;D<)6|G=u%+_ynDvLjL zo{8uedWm|2#s0UEQ@#tre&H;vZk*;Zy&_e+U2(#vGxqSS*l9==!JbYM8*54qONr8) zb?PbQ4!-bGlRfp;Jc80|g!*vNEp5_P#c)JBq_ZZ=4d!WUouxge3kB@X3bKF9UMNF2 z2)eVU#q>jMC=r^v?r+jJ`+UiUV)&thU}t@qC9NJ_z6`nxvnq! z(PBvM1TOlwt+w3YImJ>(4@;duH&eCQ^RA;Xh!E8n^<+Jz@SM236dP;FHqX)fdG2?I zuhfYBW+hpvg>21a7$zA+6(zI>S#BGLrJE`WwwiNMi0*r$mC`Ak@g$lhS}Q^GopaH4 zS&RPXo zy3`?B9ZvYO&_tveHwLX&j`NL+USvHbjMo_NNRC?a{in0_r##fuzYB~=L2o)cba(~d z*~73zgzHWV%DG*nogV;Fc5Vc_C_23wHG1G|@^<8J38UU1sy+998jdv|KN;CwS%%H2 znhVSz6<@2TuhTY`s&boQT|{`rq-wT&MVoF8qgYy2N8a+ome(t%2OSbwBTTPy( z%VIxiIgy`<#6hYU07wf@5YF(&WiPlT94kGdUa(`3;2SWx#HXGNBD&KtLnQM9 z7|t`AO-s#ix=ye@R87$nwnc>IisaEoA5-!PRb+4~=#igz& zATO>Q@k04R9mxy*vG*5zsUccyG99Z<5gU^0{7q6SvS&FVgjcGrRP%tAA8S zdD7>n2vfl_c~Wc0L{ySQQ=0%WR-LLA)Gyms(9A`#hC2BTVKOKfsw>dT_Y`<{Jf$b( zt;RTCNz*TE;z+^H`dFVEn$SDK3rN0zAD#F=(@9Xfx*3GmgFU#D9#(V5T}yHYWV&ZD zfJqv#a*F3c&rNxx?^sLz#uOiu;KU#D82Tl(0T2y=4lFz}8nl|I4)Hw7lL7Agi9${A z3+f?#V_#ckBNllh%cv;DYF2M-)@JR?Ilm<=XTT1?M$(8&A-0Zm#Mef+x{@!?q^R0! z_xG^v@?qV(D9LpvCjpE&X`15Ke$y0%gG}`Dn2f)F5$w!1C>H)qCqag%7KdW1HD=hLe>d4JwB~3F zI}}k)@rJxEc?ol;B!^^!X%X#A-?IyBqk2ZNK{>-e{yFFt=tdz7`V8%o&m`l}FF^7O za!@W1U*Vd3eI+0B;kos7s>=vL6(OPc7sCQ%_QhM$gFTPp;c&7XFI)#}^8!>zXYM@3 z-()LZQZB(a2v_*<_=hd6XB2*2T$#V2QIC|x+2!*~c}b6GZ54uJfiN#E&O8KNw@^M& zS?pobFHF7=mVfb<|6=?HRr60OW6p>W6p!@d2M6{4_g?(JQknmfz2s^_8K91*{?&I* z6$@rTO%fm!2>8J$L;~duJxxRu*Z|t}vjKwKO{+LKkw-HM z2g?rL2*%DBGw;;E8jy|E#{37;z#P%bQ5v!9mMcsxqG9q9NT-{|5rtzM2ybzS%m#0Er;x zFb*a>1Fnfj%08pvx4*ES=P_Csd(=iaR$RnxF>E|D&me#-jGZ}#k!KQs9#(Js;uY4; z)DydpgJ}gjjyd+N15iL1%Jm3F%roGabciY(1f*bc%rFc(WEmzEPBM%F+`=rwu);LM zIK#{_XaDKF;|_BJzl;%Xkxcs~LvV3%VfJP2=fd6?dF1VDhYYnd`Di0r0j^+oiFS4; z0lKieGXP%L-Kp>V@djoOA_&l+aUG87m$5I7>6fxUj=7^8NiZ(Y@bPmP2KEN+Am7M? zU|62{19o_h=>vCoj=6_FKp%1s1L?y%rX+DYde3sh1$gkcaoi;&D~Om9e^xgB(o*rJ zMv&M`0M;5Zc}ok?POYH5+ph`2KbR5nt>vvp9eEQnnJ8Xef1kcRqOLTJll1IT=ySEj zM}G%c=J6%q-Yh+i*oAbZ1uAc1)$$gSlK&QOvLxZ`)Xq@ElDEj5RFp3XT1?uk+{LWr-hEtLbZam>q1}Ci zz6Kp1o4a_ZxerCMlsju$_HZl6TTOZ-mRF*cAeBwYo69TihM9SY<@+;l_3@}6Z`#$` zGNi#lJU?^#kU~lF15-B9RL}msxTbmav#= zC_@nTf`NK4hr;(l5&2;075-=xDaE0a@uH^UM?oWqnwE%mgO#?9lowrxL|45;Qjwa- zV11;-h(^nTkqw=Js^M~_>~32+lNB$;ExEa!Hfb_b;s^68 zdwsaHd#d%QOl6#9GRa0a3jKK@Zp^G3)QXC+q|II#7k_Nt;1iaQiQX3--s~_uVO5XM zN=}C2a8W)#UhD1B7ay6sFgol1dC~=joqS26?H&bhnZPpQaZ$27XRJ&eWKjWUNSB_eh;7lEGFKaH`K*elZM7k23cD}MnG_i z140VtB1BT?hs!eC>z%DXSp)Q;_tS3^5kD9|h%^n*ep;6H;t1Z(%eRWZ&BsAK8{}Gh zZy!#nz*{qKoMli%HT{hGSz^UkNXp~|*&h@iHI_Pi4)kFKNxyFlIdxx|PhFKl^upK^ z(a`4tV}UP~Z9WHQ;hw`?Nb00wQWXs$^p_aZWOt#GxHd0&t*Gw=hJe$D5QBZJwM>|4 zyu$vtxtu?9h1_&-a2(7t=puv~uc)%cFN{slu3G^oh#!&9E~|bMT30@)GKk&^jdH)D zydu*@tUV0CG^?~i$Ddl=l5UWc=fKR`k$K=n%xF~-R~joB{N~ZBLuYI7o?sb4$`h_$ z5yHWVf>+FgsA_sxohH!fjc#6>Y`y@MjwXFKtUPw467*UA3w1W$tc=Bq0!;Yn=<*k? zha6^RP8#O&q7yCk{RTSi3WW8y;|c3qGM4Vc46E~#G*Kwd6AM_fG#?2!sj8r@jRa1+ zDlK)6UuDUX3`pqsH)_A>KT6OTx< zO0AP6ZNm^5M+~+IUSD)MeIWdG9OK`dv%mCc~yy&cU@un$jR85QEgL{ zTDrpF-BOoPZ&7n9y7LZSczth&e1q%PdXpC&i6(Q7G=6c7jD<^@wqnw7nmrX`BFAKG z9~F$J9{#;;+M{U;ZgzfsiM>?)ud733T(B%et*Oy$H1qI@6-p~);*knNE>V#g#GzBb zWhj!Ntg!gbpU%9YPA&|tbW}BFwltmM#f;4FGn`zFW76WgBb=9+A)1-XE9S$_=>{UQ zK0CuKavLa9yGV-pRvEWt)4QioN^~Q;ZWxqyh4!gGO^?MPPsG2a&*GP^C+A&i^b7n* zH7xuiDI6cV)#e|w%rbVrnBVM={E67=zi7AXx4)FU6R)JjVrfzhO)Hj=)YBKt$zgow z(I!ksqj|!Q;wQmGn```|xngK9FBpqt(D8a;xW4WVNJxDb=LP(AbbkKH8fSJkfkSRq zdh+~0&oww=99_U1vM2H7vC9^}(os(Nb+hMgo2r$?mz9!u4;EfLlh_y(oUV2E3%T5q zz0W*vLn;#Il{0VL)6Rz5rtV*E2F?o=LzJL4){0*`# z%H>)~k6`~$oZ7qQpKKoXq(r4*+>(ZP;WQ#(xf%a{&U!$Xs;+gBY2ChrT@OEweVvb9 zTF^`1P`|@2FQdSvpqBuxP>4Sm8vr9Dz3h(bbzd&qo$U)Lv;Gf-W=*T zMpM={SUYQ*tzWKM!UU@B+GcWo$=rFGpP}$tkQr_B4}WR@{^ce^K|gZo;LIAbo4-xU zrglk_Ec(%l*oYU$$>BVzEYY@NmD00-7B?*d)tS)?bsX(C{cREPjOc19$EmcN$%hSc zmZxZwOLWu0+1WeqH2#TeK24{rE+uTsem7bXQ-8}`=@7ZpXcA4@>T0!y#*nekq`R0c zntEOd)xqr^TvXUai%M7VDO{gG_`LU8o_3-RJB6-ujRI?yVt1Dp4|+{D1_+YU>Zq-A zRA=w%H;jWduq(WpKy!f)K}14G3cI98zu=uVK`>q*P-0y3!UIOHngDyLHt3@F0fhH` zPcLXnwik4tY(MW&)z(rYdPitI|B}{_Fh0N_QDvc?qbByqlKWnF3CO-TAgI*3-&F1| zD`3QIaLPA*&>sv~gdU{(=g0>fO*S)1x^6Ce^o+gb~wDj^J%>@LY2>B5% zc_SvQ?rx8;p6i#eu3lfo)OdCG$A0jffb8_}FbQM5sTt13`0%fZ#Ef`){K(hsc_SQX z2R>wDyNKTk>vQRda26S*EgaY(_8z&x;GVn-RP8>!AYm^`MbTS(N)Rqh~yK5z@HrqjApYsk8%=(?8yGd_3=k9H2Z zAa;8*BJ5q?QmvBB)OO_U6LeeGfh!;81w1>4W{~S6TM_rpK{kj#2Z}}A+Xl-( z&j7cgweCSTh^;B^h->FyJot`$cVyl@aBjSY?C)Pc1g~!%s1vXTS;?twxwd^CN_CJh z^$}Ja=N^+e1t(H-UNYo2)ZDuf$KRivzP z3R~q@UcrzbW+m|>JmvJ%q5m`;5U>V=;FTXB-YY*$s)-e@`q&)J%G(P{uWb9^VZPs9 zX`>#n`~LF-p4XG`tQVBOgq&W*n;>wvl$^lfMi}7za8!POKieN9+l zv3jxVJB8Napa1o&7v>v}>Kacz8B?yaT|CAVk=Vtbv^`AyIlwG_{;96~#uBNYD}Ek- zCHLbwF(uuP0QD+XsFHikd%hm{pa3>v2a~fjzDR&4ta{|01{eE*GH-aK+4IQ4T6-{W zIXOOnt0|t#5u$amcNx^X!V#*P*ov=Q5x>P}7pN6L4k#}%q`x}MPn72!c|C0_{mfV3 zhnc^@47KGiol0Cc;;8pC+Yc+Y+FQE_2d^lG(+L#xdtk!-eGQYZZ~{L`iWhl{V{WJ+ z@)QyChlDZS2LYgnH9KDUv{WTOLD45E%IJA=q8Tx{&Rc1uKJC%|R)}S~w^IbHPROs! z4-Iv@RtZmvJx<6wBx{lSeFyp@rUQI>ON-F zhc90pZq-?rHK$R75cer$*vbPdU!m5FW^BmsRz8;gG`VPsMK3^sI==^28KaPD2+r?< z>3irWS>c;ZJ>dBP4AO%xNL>{8F|*{1*|w=VqpBKJt0S#kh1*ekecE2#wq$+?j;9tI z^7id-nkOv}3AQ-rJuy$U*0{#B@E2v~3{Sb1SpE7e-v;??1s_oj%*zna==z|!N_c_c ziLsRf41YCO@Lug*q(uBwnuA;`D5K7KGe$@5ZedoSPJuk!^^v`btNA_2%uSiL+^^X&<&8Bv1rI=903!aVExqmiuq}cTdHGE`J2dDZ%OT;xA%T07kh_;# zgd+0N9mPQdxBanQgeCIgje1S1=8({zZebs?TZ;)CdguG$D}o^U@{aZgYRzN&Ap8{~ z;z|4k0?*N~UtE%4pMcm)IK-dBUN`XN#~0+nAmo=t-eBuz@rSWUyl${Jg)pC7yzmE# zhSwvJi%&SMI`sftJ7wW>{>+;QAd(;WN_a0aWEw0MrK3^5W$C4pe ziocjj_?(g}Vcgv9oPOZDsOJlCD#WK~en=$?51~|WbfDC5a1je2T1qtiiZ1`#%>>+?xXOy-0pCb}QI)KH&8&E* zwqU2V;L3-hsvYhL!`DRw53sW5S19(uM^XiM{IGG;CQn^e?37v+n|y>7%D((BS{Sb( z)skzv+ahEon;qq*PaX6}@*#7ulgAKi>3iB!b+MyL^&|NE4QuNo`Dm_?rVAZ3)$&2= zsW^wf*zL`$ch*%$9Wyp*?~OY<2#Pj+Wl^$uQ}Ce&B%{&GeR@S|PfRWIg$C3g^WKm+ zJ;Cc|c%!L1((4BVV|rgR6@6du)h8zHtX@jCGp7Wl!Grnt*z+(V`8~K>p2a zByEDEJTW)p2tvnSApgTiBa@W0v2H z<@bmFUq@E|Lp$~F5V(=OlZmO*|Aqh;pcxwk{Ta>Xl?n2Hq;y5TDcwkCMJppoGrv3` z2{SvY;KIPX!oR{zU);B0DRYV2ZaBJ}^qcQJGK zZ#cO!*DaxaFc5FGMZR}&-K|$N3+JX=z-@;=UFs8)+KZO)Q|Vlix}lB*hwH* zvKrc;C{w&5@Z%u)Sh>!+ryXyPs)I{i-THMu{Hw2tt$XpE^8MR>Q=HOa^Ge2NhFM77 z9$PKTPgi5|(m#`TZUWl>OaA&F$k^0I^*-`@iX9yIk00N?&HvpW-qpp@hF;Lg$u;#id{I~-9|USs$96<#zTa(9CB+h%?Y-M(Sk5!+Werxad;{{F_ z{0m9eSYb>V^rML@jbuJSH904a8tF^}mLv-8xR%P9b?Cemvd&m`yekd|SZv8t%VP7o zPQaj=5K+tCRcl8acu?f7FhK2W6)$j7sru07Ax{PG*|~f3oCMtA9I9k~NtqpD0A{_ou! zcqMIEWZFK_zP1AiaqD+Z<}W1vYu6iYd3N6Rl@0U^X`AEd@paqo=G^leioGh}>E<=N zV!_{TTrDg3e>>R^?t8(x4b|q)m%+@SxRI9uTYBYY-YLTd$~3hUIG3$Y0_ziI?We0b z-L$0|4QlD-PJA+#K-Y zxyx*g@&>+sxheoVL4Fpztye1g(kiN8{IpoB9Fr+}xQS>z!np8pck}5qiX6(e%9XJ4 z*gibu%Eqj`pajnL?#{axA+(|PYrUS$3t%nsa~wgYR1Tov#}U}GErshv?8m&AO>NGh zbwe zEyl>u<_J-1JU9o5xgvQu^Az|1JQKk1=b~nsQY9EQvS67`u*Obl+`;Jmtcb+S?~o^r zbe9lE>K-^Hjt*bhhnM(}D1yE`A$s@)6celQQH@5+R@@tq`i5ml-NqBjpMSo4`h?`k zqLG+9_i^qlsMlZq#K>3TmiI-l$IFy34qCs+VrPu+o>1(M_v{nZ=_jc(^d4|ClUxJn zMex}KSKCkss+A#}LO&>}w9p3G)V!|n7>3pouQ!0d4F7nPm$S5oy$ERxK!AAFPYN7k z#P-MAXfUcY_&_655>Bb`XF|Zdr&Q#-U#RgL6OcQ`YmS50utt4Fb`P$}hesF(8KSzNl+=I~;F@YQyOX3L=8S@Cw!x%R*6-RnAv; z0)F62#dNtGPxE*Xfb1T6c7q^Fkcc253ni_^(s~rLppa3Ume@AuI`Jj1HtMR}Q9(KG zVCy%ji-sTxqLwx+;%as`@in5Qi-n=Ys%w34m`MXep08rIS<~hki(~fB2uVAmzYC9s zl23mv8ex~<`IO_J2YQ|PbHGau%1ta!+fu0{NHOC&;RwE3n|F_ z+XDAL6cZ}jawv+3pR?$jO*O#B>e{UoR+cc@s7N#gEm1{ik_?E4D@tiiB{q)k)*?m+ zp*=zAdYGv&^q|5~NW&m6#C@S$r!5upR!Z5|Ih^-jGcvPlH~G&$Dl$?QLNZ_pj9f<^ z9i0TnL?65zCZmC{>~u~{5@5nP+(VNyFdY5hotcIvD%Uz%e-jyE0HeYDK>WQpOnHVUL$tbfUZO;0()5DS}#ZZ-IK7Fj|&Cs5w zeN@yd_HV2TF|=B}K&`iyYPQ+F*hCO9^;-P$s>DQBm0n1_i-<6INaQjd3cQoHv5`R^?{;jsCOd zif%J5!rr;i*_S>#2D7)-PWPp!*A?L5L1!%#6`Z6 zWk1FGC^UI}k!CKlZH+DO(s0?#w5aeY{@ll@O?kUH`3%PKmiVo#s*YHaJ}7P~txxTuM<6WBtE8;9Zwv(NqAM;8SFb%6HS4?d&eB;P}ZiVJJs zFRCBg)fTuqDWtd&O=&AKrG!3}JB*Q#<5r1!j*W6&=0A0J0!^v5%hmmYCHL%ZSPlEZ-p67p2QHjse6fL5NBN6M*~R z1=SM6nltRVkm43a1vM}1k}ic}kV>xbNB63JXN5S3;@o>gR;a#!N^bF-qz+2mF=#RL z477*;Kbf@r6J&)Pzhv^igRJJ;q3FL6O8#5I@L!jg?;sPgG^iD5I4X9-0cA4+v~2lvGqlIVHJ^OmX)7ROqr{4=i7<=Q|Qlu`9E^7uJQ*%LoFjC zmGilQGcg^wc0=o`VMxiz!)dO)wPXF+%k2o`5a4_Q zR=`&cYNJ5F;fXB?L+L;mYf2~HNR^U4}#jqdRSpYJ%xNeC%OwQ zQhc&spo89LtkAX8$?AwjAfl4j}=|;N$qU$N6)mKJ|hdkeon6fy~i_EcFh!@2= z&o>v^I?g_haV{Y9!|<+bsSY+d@iz_4%^H#v)$#bt zwBi%wok%?QrPYU^nB-nyoHyZ`e)d4#`bGb+Z;w03JAJ?>w+}SChctW0Sa%48e?Y0X zpQ#adYJ_((D%OLj`!bI6+Y38_Xw_p_$%AF^hifBL_QDk$M;v|=Bhj0LI&e_b8|b4a zV%;5K%(uhM?pj`%K{R>42zRaGW~&h zqP41nu(l&cepHdGPPK+aO{2l3mZddq8{PK%p9}9=-#0ydcF)r-`;)1knd^(`1iQMk zyw5w$`Oe|&e7>I)0mxj}V}3pdL;ja91nevyl38D}*4NN4OT-JF_c|}las3^IhxJW& z?JgSrU`+4bEcs>z1aeNo31KA*$QE423Rx`h7^U5eQ27&GOQLibw?=%X9gLYO+g7Iku@cFPTf7Wgx3mVxu#3TGNWXN)YGHAuUi|6xp#~7vW=Exh&8DLyE~VScFl7^hu1wAnKr9T33J2DhACKqwP1; zr-vIh*D@{RnNX}Cj)iP)5}UEWW1(2}jo3&|kBJHEwwlFbX_PzsIR@8v9{72*taosE zo9ZI|HxSv?qn00;mV_hyE%@`yNl0t|k1VLTX+>(|_{v-G$>#N}88hzgO(k6G3vjlN zVgK}@fOyOBTuJ(Jn@dWF@1Pnp;yGk%=6(|1Hs7cDw%R_z+feW2ao=N~!wBqs?YS-! zaSDc($*VBw%4dKkn|Dj{wC+Mu0X^pC3Kj)tf1R7@z#o=ip?+bW4DMUQ>&*|Lwe`Ys zCTBx^9HKdJ`y*kqEKO7|5g z-mrY)rE0y8>(HC2FA%^qZBVp@2JxA3b=fP*!w`#6s-Wd>O`=x==-2g(a@ELw$^5o! zf=i4jSJhnAEHA4#cT7e-e;G0y+9>bS-^g0m)TY=vH^wH@Xb}rVNvqMU-3uCIGmIkT zrX5Dh#u-F!He#9!kuep#Op@j4cTh=Ai7Vk@@`m z0=#Xcb8+%$=wHr%abq};vhch*F^Z)d+_8ERwNruh3~+>2*hPXCKTLoHOH3BAui~EB zF%^wy49=zrAdN*!MDNeHe}ed}X`E=`Q2|+thF)0LV6CE}ncU$}d=B$d*G?x}wBA5D_pr2xkN>@eji4%C^C;kd(&DA&~< zVvHhf_9M}Lza*uFMr|+Z81KR1l6%Ngej+x3OKM$3yDYzU9kp1KF2eMK>x!p4#~nIg zC>}^<^SkE>t}VfVUzOs(^#s&oxuEz4HoWLVD}wtb+Ob&>Y#Ytj63_oWa|^yMz=4wf zY|R)gc`soNsX$W_H_aWzUk#}u0DVZ+ir8+ z`*B)Zec#qLYn9RJu$UaaIA|m!pPz}>B?hw2$m>sT%MEpx3 z3&CMX6avmG0^e;R9o9?a&-lWXy(+gcxF4a$Zu*I@IN5b1-i|F#0DKa+l=VMGoT>%Fl~1 zVBfIujw#eH?ctl9(`wAkWa!{H2&b-%!Fwh2+0SrX+6Czsrv5}Y9}1qJd8H=M=3&5R zDbm$%eq2Siil4PE3~OCz80=B{Y!s}G29Ez6br0^N#K3}HMtov~*%wj4&&r4O5(aiV z0dR#`k1Iz@-9wqfSEnkUYNw;JQnfk@&ZSDr8Cvm}3uLwkX_GuQTiTu0ImFUjI7Oh9 zt0byy<3UOY&}?ZLswxF0sN5ujQ)27ckftRu3vHy)MhW@l)~I&w>@7r5EG=)*-dd?a zD~VIu{5}p$R@PwVRt?SA9x`e8mW5t147){T>3dw%!;q`b+xRM7HqhkyTzM)fA#{5- zY$?Puv+;MzKex82xxIkYhJcl8%~6vAY_n^UmMlG4hKmYCo+jyJB!%|Pb(a4`XGo)` zs#L_uX6Z&vaYAt;sSc`^@Gx?#_R3}C)fj40NOx*CVM`C3UtTZ;^H9i{#*+xB;ZrKt zYfWJx+mN5`??|ZR0b3ScTR7=X8nSb|sNv)TPm8USHvb@BoUC-Q+|3`8!aWgz;@%pH zQ|K*f^D7OhLc-G0uwP%Fh>jLh{j})QGkY&M6YI1P-9k}aR!{Jvd(tqi?EQVGRb6MW zWp(?8AP*AQY`f$XmbKd9DFPy>niolZ?1e=2lYyEN^;&hSp~|JLZ^Eo!q$h>Q zaf(6Q2V1IV;C93rj^L$b(khy z@u{%~O3M6>@CETxxxg7ZEq}bq?)b@^k1s2UE7lbgl%I0xiR#rABY-h_Na-@Itgx)P z+Wc7Zn8NZI%e0(cdRTnea+!4=p>?%L)Wxftgc4daJ+$IU1GT>L2|3Yyreq5c-mU zzK^2yy`d;ZZBP7~5~R*E!*MiVq8nl6k-`WaOQkIq_DD;uQ^f8I8kT7eh7`}JXE~{Z z`|A<+>^IQ%qRKPp4dIa-eCs-PWS(Yfxw!=Ed~3;l`cUX$d%L#39S=83KcsyD@H%Ny zSz1?EbjAx;bb25}hf=F#UOUeu2X;T73=Gp}Esa5T$wMJxAq!)rz@$ znIC=s?qTZEgwsj#J<#y6kT+ib8L87B1pwV}ne#XG<|&Om-<>$Wq+#}r0+_(`tM+^~ z%J#ys`gp)T^up4qUpj^NyfOQT!FUD$&|vkr!1e|nD}FK$UTS0Km0s{GR_C~STCD_2 zy?HA=ECE?$b6I{l<2@%_nD(j!R%m)@Ys%>^C%8{Zp}~EBc}|+J(@1iE8P0bC=AmVZ zpr=cuP?gcLccj>Qt!heCZM@KIyjTGX*ey$*Hh!%gF&7Sa&+itz*F|t0@oWc*RpU#` z0VK;27?vn{#WOE#x$*9mQ2eE|FQm4k;w^CgMKA#Ot^}8^h_Qvy6k$H90<$bp+M`l6 zDw1TXidZ#e?iFPSVR|Bd+j6{RNnTVHvfpD1m6*&9DV&Z?lXRnurcL-YBhfEh*_s$- zBZgNQk@gM0IWzi}08HHl!ZP!0SGgXk@i6S=nQ?c|MES{zEad#oTWEhZFpAmnn6_GbEZ`w(9vQjPcy_h_WBtq{T4ZA^8=Wc(> zxE(;YBeN~|?aI9YG~3aBT?li{y|~2?x6pVaj$WAd3+Vth-l*p@#;2C?jitOJ!Y@=m z`MEvg*)#t#bH^ljXFt9ny=Pq6Q}$a}zbo`5My<)4&6STL+r#t=H$T_wJ@XSeE;;pu zb_;sn@TUd$b2cu)@H0HGWIqY}rT8=7H^#p)ep3C1PsVRxe>3?C`WNb3dEOMLi}|S# zu7)s05(4cT5y}kPdAY_a$FO_NQ1r)9iZ^=y_pCy`cSag>^1yL#m4I*4;!7mm*V!H)_jiAIUsy zk+;DZ!4)s-qaOD>Mh^c)dvnB**P^Ny)hIKs&(ZUdy7I|xvQ*BID`%7`R8Bd8q00WWt~Qeq1nG6$-vtt)M!6GyHA7ku%KM z^n>PO)h3X&dn8LX9uDpH35girC6*ZedfrK)Ms~!=7I}8{PN7m(td$K6r=`+jzRa-M zjjXE`ONtH*eWeZ7>wqa?;WvrQ;X7OZI2PHWHSWLx*@d`4t-1wYkevM|%ryx|^h)mG z1V3c`|3la}M%mVFNv3Vvww-xz+O}=mwr$(CZQHi(%zHauRdv^^9zFUSWBu5_&)oaO zTrneNq*{jJfLrp60iH!TuQ=6IzsJq>j`n}>5rVq~AManG5DI1n(o|z4HnpdfB>GitdCCSXJvuP9f&9)p2~)_p+i+hg=&IDHA^8V8(KD2V_R$S@q2grRsPge zI3(8k&i4HIbqK@;zK04ZiVSqq0-|N$%nQjWYcQTdlAe%oZkwR$DN;lZp=~LU-vVlC-z&8_a^nDq)xKMy9i(z?Fns3#hhtiIMLV8r8Jh;E2~k1| zvbfUErmPH$I`G+oz!wFbf1HalAfyQ~v4)b`E3I>d*~3u*A%(_|9hsLcJl9Xu79?DU zE7_)7;oM*ex_-trU*w#xz8Oyv(8Y0h{1P_aDm-TpnKz8qpMpa4mQNc{c}PT2H*E)S z%Hqz;{aGKmn;u#XZo>4945E9fpSd;8b0rY7GWn!y!5uc#48jY_#tYh_eKM-6%b8{7 zI~068SM~=vvqAS>Jpmx|k@-24k(CqTRRW=fis}9~3MzR^4Lq1QVY4`ZfmZQ$+Fr*| zIe5bQ7D^RZZHJ{AKNa@anr;!~`Y|i3_UN}A>&%jiBg<|e=msm!bggi(3vX!GHqP|x zKk*emm!Ea;< zPpX}6sGDwx4xRo6`p0`M8GlW{EA2I$=;XLJu7_>ER9)w|NR^!m{yUKA)#pma`YPo& zp0S}XOsRQnWBsp?@r}f^eBNQ8j|OW1I-|`Sj@c5&9NG-`mUr~V_rD3}8Sw*O%xh=9 z*560J5kolLN!k2(rE@HE2Agv(KkU8nZOWuIQ+}PE@oTY@`|{(z)F^L9zv_jqIx6D# z)Zydm%%U&%VGgqSj8Oz-g4e|sdrOuRujT`^rj$Ht*l^JgAF+e$f48X0mwC)yd$%3p z8EGVPyEot)f^O%}Ww*x|da|JD+QN9yN$(%@J+axfwL5w|U~qFA`uXpRt5JR?7{YmC z{;@yW64;+92FE`znS!=9hRzNS#x_nu=8ksyPKIXxHX}_KmlC<WY@7`W0jf)FqzyRXF}qJO9U16~EQ1YtOg?H)D~p1}yT%KWDYUeW#&I1 zRR>478aoXe&Z2un=Fjyg*3%oDBbsYcVcs&}EP04F)4jpE0@uuJyHpi(?P_r8kFgEL z=wVohlg1=WD(1(&oBvLCpnh_*8)#;+XHREU)dvW4EK8c3_7jcIn-ZDzsIYY6yll~z z`6!GcEJPM=F=5%bW|+@eOBES7@~u-Aw3F-03dDJEpW;^g9jvj_NfWYAn`5X8y`x{Y z^v71WP?c}6FBy&(QP`8c2_b%ph8KHrp&?$T2mhq;jJ~g=O{`Hcg83-&Ihnog;{m#= zv}uemvyf;H57-FZXM!PYA4Ty>V7e*_aigChLIS;0e5dMpHCMlz=y9@15fHxVmGPMC zm$P3=<|mL(ahiWqIvKJJWZS>&g1_k)BxqY8bz$zA#PIh{1qK83&A&swv*}%AvA$vsKczZetwqB4Pfl+^wxM3yO zgDHsJYIvGB{bu%D@&_Rmo;Q+`ekw1ad#RZ-ggrNhY@T0}TT_Z|OA&)7l{GVYGZHzT z6)z$*A7Uyg$5biIkttWP5@SwJU|(Ax;;9j{RM`yh;^99vv%5zeB+>iRW+^dnkq4|H zzzQ~~jX8*rzZ`zam&iR$!Xs%erq*~gJ$O(tbTo0AISNmJC~8ohI)5`kCP+Do5&8=i1e6U*NB{{; z${Rm*mw6_Ln4E?XBo>kd*H3z80%x2C*`}TE2}m`i*glD4txt07Kj|-I>znv)vXCyjmS5RvB`+}h##P1MK}DoXVmXp>aEPpQF$*zWz6a&<*}~m2t(@!3P3cW*LQK#$qE?k?G;lvS z{spPPStfWmGZqf+j8|brG#M=8<;xK2gD^{#jbwE6Q<_Co@OY`h=@s+2v}Oh6Nv@!D z-;S#-2H-PEI^L;oNcUmy1SEdjA83wJvaBe0gEQ0t~;ara4hecdXR zs*ZK74;u@41k2Pm9N%3+9s0wkDS`Axgr+#K79c7gj2<@Uu)H8G9 z8s`3REz(Tn_2al*|7;t8=dDOR?*ZkV0hE#bVo9#)OMZ{SorIcJy_lp)-hV9$ zT=t~pO!@UdBM2x6~Y0O7kky&Mw}f=7h|ar=^fb{n}QjN2lMf6pxjd^ zHmQw3yV}JZ7(eG}b5-~R~^ml6fP0)M)INgx0K+JEQ*gk63bfFC2b z-T#(HMaxhA3;J>X3;AzLK?+cW_69(QK>dSI>?sdy6c#Z+OMj4mR^Wipeh;_}s5ek8 z6bjDH?C8p4mAmoq`SSD;8UQ_#?SnyH056fPgh6{q3b7F;m?Z9gfow416ujo7f^>i* zY$n*HRzYS`8X2<#d{ux{2gTV1Lta>s_e+U>{Br!)czM0pcSZnp`2{3x!|)!{$55 zTtF*^#q;0N#w}#Z!QY~yJzQ#u!6(B8oQ&8QQ4CL3$X%)smgkJ6X@{H~PFpuaoAcKs%71 z@%LQ2&e}TAhUvJXq?N_1GadWT|FfEpU5wnVKX9)G{m(Mi|5MHX#Q10xO-E#73?H_i zuoEY9NlEHrAW(jR47LCQ0nQhaM7_7D9f;EJ1a{l-9caqL0rIw>8VOkWO6zVXMnDkoL_9IW5UwA9_9}3az5e<5hHZ z>gKfECF>z=;P}R_8+IgC;>D$jEhZ*URm|4ebJs`bT_e7HMLK}2#_F6z35MT95+tfq zBGQ`cRXHxaw2;yD30N@FIYmW^YDyP9U4QiJgDgZ{Q<0Jlkp~1ao*a!w30rV6+O=Pg}tw~-+ zm8G4Hhb6ZzdgKybs47-Tht8?Y$KVDyiK!{qlv1@2loY_)qeAkt9h#$R4x59OKtXpZ z9f6z+ghmJk@B~X=%^9+qEwVxCnS7U&Z*Hqk+dG*oC@FxivQ3rOd_i`|*<;ZtYgd}? zXjJ9A-IUqIqo+?%aTFfVq`6NLUz8tYjeYq6c;S62Y4r)CcCV4<=S$%#cad5&z1KGo zjT|!%LP}|tRAQDq;uDY7hnuBKtaDFYbD}I=hjR47N+Rn@L_i|bJ|z5Q06WNHt;}H zx5YGX*(~DPH$RojYf4@|fc5xbzvG1>A{~w?ib>JAcVn2{&JdE_A~jy$2aT%Q{UqNM ziSM|`$s+k2#Dj{d@^+ev6(04WP%%bZ^OX0XwH&JVJ=PK5F$|BYoz=wB6QKM>LOq0z zJC(;Iha9Co$sf`@K~#6>4zcO$PGF4EkkUhqDNLtsiBY5zV12&{kUMBf48ITVcU(gS z`A*|va`*jWR*He&BB<<$!m_udCh!1d#7i!wUv?~mi=lFVW0I%U6E?7ii|-#Y_*_*z zm+R+uS~O?>;JF#x4ud%7l$b?60c|=UqV@>i+Zplc3LJE61#$63borGtYBP{r2c8Xh z^}Ph?zHB01k)ry^tMd7cr28Y)V|ZzB9avSlg7zZq=2kO1`6E8By!QFVFTO|>DZQzS z7uJ9?7TWZF=Ici?0VJOS{N6+p2R!_~Sgy^#bHK{vJeZ5sQX<`Cl4s3`*i?cStzD3*d(H@S zi6&Gl6pV@$!9`1a~Xql8Dez1t2ES0ws%CH z=LYu=!q?x@CmP;_542BawrAgD>bA5cC#N6y+(G5*J5<}ok(i}ube=&i6(uckP6KK) zJ6$aaqbB zBn1J4C^A4u5MZ6eX_8KtL~U1g3KdUvYu?M{!N#2?R817@vU-(j)Y_d5k0p=i9$U@I zmcQ(ct|sAMV^i$6-hXdBcJE)#U-7&!{B)N(>oHf8_KdVD_qf<`+C+v;x8HF1Zbe{w z2=G@YM`5XKk~Z1P+ti0?sd~x|R8U(vJJA5BY+PNG$6j%vZj|g(g|?~IF2jq6t!>zW>N23=N(@%^_+H^(bii6gUjm{PqsTRkr9*tZ++=rmN zmIUZhycPexH!~taL@&GGmE0}=BuCD#`wPO0cePk}4fH4yCGX9Yr6yZ4Ju(!Acu8iQ zm5HEc2KeNN_c$sgltAy*)3E4*J4i zJYzd)a`AK$w2^bHk+mxJ;d~w*e70$nQDIm5vAtZ=H+HQeiyua-TBiG(1l8>xz z$aEcVg?!`-I9$!lpsL&cB!LI^af#Q(GpDO8Gl6>4Q7O~X@w&kJCh3RImGe@7cO3=} zX=>_EMPHsWbv5F_N+(eDbTy3i!#LLUGc_M2ltY1V=*{$9QcT=mM_4TEmm}C|iIIw# z#~?+CzDD7op|58Taup5?6d^ziZ`L%e9}feKnv*d!vNm!s2;%fekVe@JeO7mGOn-oc z!&b^42CkQ5VXULhVHh!I({?%^FQXt9Nmw{2$w`7#SBb@pzmNJo$;))Qo)hsHFlIWtm`B~-yGBCcghZiP=)Wb&-xnqsyR5@g}7NW=kqX(U6 zF5*a3nSN2dAO_mIaA)}?GH83x4cj}4Px369plZA_rP@k|R{t*R z7x3RA9?3d&oaXoOW*3K~=(q%~qE~2L_{t{G?W19u;&jFP2r>v$pCv1~=d1 z-3ih*Ffx=j^-GnYY_tPIi(E1W9cwqgqwn_&slX0sqbggB1m(%IIG7Q^DP8?}+-f?I zslypYg;E183sJY8pqeS^ss^vk9h#mR+_M^b5}#nK>`0V-i5~lQ@hU$t3!0Q3q3^8K z$!srC+i|g9l4gs2Pi5OkCs5`$LT`#-i+5g|`L7{wGQG}mt)WvUj`dcSVjX4<0i2ixPQRNBCD9#$Zq*t+CWoF}{*I3R2Vh(=wFyp_p#M)a_J# z+a^QX31i!ty4JON`e|d^=Qq-JY;LJXUi>k&bh1>ply%HQ^Tx$<^&G@*frNCNHWbkZ zcNQ(Ra44KWjXxlQxnbOMq1|Vr zj%#76_2L|M4HSbW^C5us8LrB>n!-Va-#j~rbOUj1P@BWiYlJr=X2Az)BJQZ|9< z$?u?mW~m^mTEKNA_nbj|$_VNP@Z6C7*^x2mAfDEMZ%OXxfJW2R(d^==8}Q$M25iyl za6_{D80z{a;%d27IoJHlEgR)HRBczfCXY$79vE#LkU7QoVv>~pbYu92s{^e(8j$f7vwvFGx zS~RD03}u!b055f9X6lOFMRwbQF(P@jQbs0*|BiCS(s7kNY1akHM-2^Lx&1PQsl>4P z>n4U?ojlh)&*nAs-GMMpOllnl{bILjT?VWZLT!D2_YB`X82r98GfyE;*)U8$=!tx- zh;70{f*{!Ncy(G4xQ``Ml&cwitz|dXSbyLq z?&&V>bvg!94SU=x;A$*RASbHKq;h=<&vO{cC(ry?t{$57TgjR0rLkNFXS%Yz$41|!_y*}`m2z1Xb>M4-_=IqG*wpSi6)tq%Z;5($esB=}*Rdl}pjiUOO)kb*?x8MASo~i)>0ATuurdCYf z%EZ9I+|{I(zDi?jG_K%O|M?Wo+xmu~l`^2cvZj-W7=JhF(ENQ1tt~+d8G*kpzn_IPIVpp7D6g?-V zMV8qzXiXOxaJT80NGw`raKAYeHV&mPTJutL?_ISHZ*ixcQ5y^4z)Tp1WI6<4Te%0f z?57YI=?(p8yX&jD2ETqa=EzrRIzEzh`FL!fqCH=o%C104(k4r+BiXN)s*b@o{q9sZ zj?-1s?j+kQBV*+9njRS)-oOYJ9}crPh7+v%IPttza?jf+zK*r&2U4}7U>Cf za|kHtP?QydsR1`=72V3)EtK@aPP5q1dM1#@vM(7j-kU1JZGI6GIuWPRXj=W0@8L0G zjxVD%vqqp(PxIKk&me^yIO-ATDs8%#iD`1+3F*Dn>BRTE%-ojM=GG?Q8x7Rv3y+)| zH$&O5f zj8INl(SWPp#)BqOj?9ybsIr0XSksVWlwRD{%cv4>LE*XYv6bU#`^sm&FnbOSj-Q{$ zG|jrVy||Zpwa{Onr6RdGvgIzV-Eehy9JUOHv02U+E?!Oy`dQ7jZnV0YkQC1f;H4l;#LYrcLe?hWW zPQf z!~T5@0=u zB`G%fak2j+O37_n(pY3dQmuOqiL(;DLD z^ux=3;7u0QH343_Unaj+^VYCyEL zI2)>|e5qX=r`lP#W80a(quWuu?+Jmw%a4d<@rsgFJEn>*+gHp|u-6zgebXAm+$!0J z_9{Q1*1xk{v5wz>8lAD=AV11LzeR<;K0_ePMklmy_lrbYq31Sgkt-MUw%i;@WP+w}{n;?)a?DhLbGKD+4$AYIsbT8uMR%t*RQYJaW=^LdW_bAK ze^yUOO;HD10eCM&n|rBv^bp5N<+Rc~b2}|(@;A)Z!z%UK8b`tzW!F^W9mo;EcG`%E z=&EGc1RPo{+m1!`xMfO4>3Q7|8So{|&|@6VA;dI8h6N~GOZs)gtLvSM#=!*O6h`tz zkag%CxY^wv(j-^s!hiiT23>sLwJhNZR(~WV17MQ)x^m5_HAB($D*vnk)F{PlX)#tA zMkU=Ooit*KOkR|>_v~Y-*FQW1GZCk$8oDc&SvYakI7HXhptk%#K7=^MI%(`tF0^zL zzL7U=zm`f!-qSH^PLm`k9srfu4#+Qew`75g_@~&Xx z)Mc15;>ILH4N~nOwA{h*OU7GuhEVr_?xV(47;&A)CCp)?oyRjwDlZh`#Zk(<_eNeK zjsAPjO3EHbFTHg&1^G^sj<76a0|K6y>@TiG28;<HH+?ow`kW0E`bd@3 z^`2%28#85G7_TN(`Uxur*zTL<^^shj<*3!4arrK2pYyReU<_fRZm3iJef$P+$j%7l zb{O<~kXb`Nzm(`5nUhyAV~hs$?g535AMVK;NcHszY9q4tlM(&jg(f`W7c#4U+^XTj zE)<*L?5Q??509m2j^-ilXF3Pj0z}tPhaWYp!1w{c4L`iR8sUd8eXgZ_hW(Y%H=Q2n z&ER)ZC30@PgydJ)hMbS4(tL730Z|}(YW>M4wHO?8Yy(bbP;Zl>l3cMt&o z3bQgL8KcB0SwLVeGioWup7~Z7J>@;C`zeKUN_fv0LocKvfxw~}pF=G#jJ4}p#3t2D zt!cVPedyM7(lzv=QYbiv!_n8TrI<(a#=;D6tmDVIBi(hx`k5`KAKQdOm8Q8I7X1PL z%VbE=R-RMCsEu_Kc9HiB8Ix`vfGd;PgNH{{Hv$=wFT2^?gGr;g1?9`3JLT{t2&a9F3hE|7{CO(zOgS zKT621xvQo|1q9WDJPK+PiUg(HI~cKqfB=g;%e`*vwM1%CO^fE-u8!ZYE<|Z7F_wFv zE{a3Xl1$KiEVgat)2wvP({y+C@8{1?SpfB_QG3X93Nk|oeF-U%sirimEEBR29FyUx z@O1RV*aLnPXsCGQ(i68!sQslOYEZ*P+D#~4ZkcJH4IYY(XYEQg;}Y9ZTJ>dBmF@U7 zS*)L+4~ileiDawoisWmH!h@dr%XL@j$X=^O$BOl9jlmZz`tzE)NM$)BoKrlCG-uP=fgtfY zZB_j}d|`LhLv&8iRZ^_!0@YTD9hYfG(8ph!Ih&-j71zqv-ONg-^)=2J${2jWFRwFi z(5>q9>zXlROO8bSO;xgcOde@`f$@C|36N1??UW}eX_IPE29*BBkSaq}5$b{p`#Zx< zs%-_D%HyftDqG~`0!ok2mb>rFa+$AQzvM!RORtnEo;B%kd$)WqbwQ5^Vir_(u^& ziwq->^N}fWh(AcrkmsF6on!yF;BNK#fn^U6@D_K%zHh^=PakoRZG*wKU{Q_f!CdxB zT@W%YluJsurrX}4PdlYDBFfChhI?e_OOXhvc?uZD=_jeKnY;~Qmd9hV=vexp4Q!AK zL5H|NE(DZo4>Tcgwr}`!yMt|iai5RUOwQbwJ(lh<0cw%?O@i2^1JD)Hm%+M@hJN;8 zswd~7u+0nJkuV4$119yMXoJWHgqbZuJ^=no2i^H5x-ks5n=Eyj0OvXe&c1o**}%XL zC#_^F@=4uomkdaoMM)&cv2hfJIz~H4IG1UymmYV@1=S#(!}4EoH^gp&mj$#2`HhV+ z%8P&21OJr%TY<2Y^&F|VqX`@N+h8LaKGqBl*9o4Kn~0~tF7pY$@eO&R%~_&Ni$IGG zfesxa6*_3r{CD6ZrMCA0{Qvyaa8&IG!hgo@3qSXof7(tW{&SDfcd~U5wsE%p*OR%e z&3|2MLW^5CQr4YX3&YMz+PG2SY+03LFV+1yxm7+)&dvjD5%pA35vC z--~6MK`Q`kPitAsZnfR%N&o)x_zSS7Hz=o$3X^PuGRn<7ONk?J()DBqV7a=qihi1>oV*p4iNj<~&J7wM)Q zB5CGRkIAZ%PQP@=g4_R&u6Wb>Q;8EN=>bvF~lCZl5Hif zu|9^U|GiXuV5tsr;OZ6xyle|>mhsiK2PDzc#?F(6W1Ey);y#&aCO6;vftTFPns9Lb zq-vzC-`DaHwW<9X=rEia7#W8=9r`G42uAgU6C8?{tsxEQAX$afrzCxSaVy%f`W@yF z7II)P)`V+^azw)=c6pVEkMx%Yp|~54f*M9S19l_S?*FW||zZ^j~9`=Cn`Gq+!(2-bAa0%;`)}AV`GxAS1&B>6EZM3i&Wdp}=t{uzEmw zwsA6bEf;-yzm}f>J4@S_6VUjL%Ccp)GHHeKWxkCU_m3wN-!hfl7x**y?`GG{+bM3$ zoo)m+Gk3j{?exbSM?TY;sjO7pp1%{a08R(W^gL~&(Xk!(jPw$B_Vg0=wdgut0&KZX zhl&aZi#A)Q!`~b?BfvI1XCtOvcjAcncn^Dx4S%!HmD^UMXFKmf=~Kj|S=(BHF7Jfl z@m?DKCRp`c^{eu{Rd{`6V8^=2$BJ&dO+~W0ZAByNuwR~nCa%slj{^Zy#*IVNT90e6B#D&PzdnypbDP@zPO@UBb#@d{JLd!P4!tWMcPwEozfmO3$ZU5XSO5 zRU4e>Kz&q}w#M&lKV$MCIj$-Pdqc~d2%`GQv_G#~iHT~^ky?f|*K$PLsbfQ%UROJz1`_WIO#a?B4L}+<9c}gX+N?LD z%AN?ney5+?9wyhGFYq3YyooP>mT7tv37MFZ*X24pF)<&BoMV5djbBGD8dZ50pWxUVn6|3qH zqXRvA21h-qqWq7P--W{6!-9^yu{ji8cI zNOMZl6=n*ufiCv|LF3wnb=ndeYRHA6s@EN&MP0hOA)_WnY^V?JGDB+uoGRkZM0ZG0 zYGb^dQSBn|@r|T&BE!MX7#DZp6LwB>pCd$s202PQrMEH=Tc<-eOx?hl*^J^{FT_C` z>Pr*olWhezc0#uWkRc@CG@u9 zORs)OgCdza$)WS@nl6vzFPXE&ICZ>gmTk?QzM56IJRYAD1yX534D^+psltRKPj=d; z(Y?^2<0|tn2{&Ywp|+({5w~@9;uoe|>?78L4c0D0>`oQun>LNl>lkpfUrj6blW=(s z>1kK&zyFjUp5nVw`Pv@QbJDG)f||(rgus)wWmJEOfT#=(+csFf8LbPf1<}2rGI>)F zqJCvD(Y^5co40LB>IR!)p$6gt^0}AFV?xQm<_Is}slSDo)|GiyFn-Ze}jqHNrj&I?|>*TDp+Zk&kdmXz|CvP7F>{oOTWS zK<{eI_-?o5;I})sf$*Lk-&S&L23Ai~_Ug{J zi?M5c5UG3tMOLWJ6xh6xR&hi-#K6RJp}@!uaBFS!>n3MvQEMyayRQi*@SYj1P|Br3ZQz*I0$vXTfF;9sL+qPa z*bzNOt&G{8HSHjAq%Iy9ICg~OrCijG_45v8yQCS4OB97=l?a7oK9r4{*N&eXla;1s zX6f9Hozue1dIWbC|CYJc8(A|O`XW_xuDE>z-cXPiE?ZFU32b#=UOic*R?Zw|wIu~(sxu6p&wcuxb+ z2?;#L2|!^-E>i-1)%#9Klhz*@^4yNf6A1T`t{B!uGcWzb%Kk4!5v=(l0_^jK;*S?A zG5vn>3ORBwGo;8l8ni-T8ve{OkxsRUJT(&nZ!M=!lJdnkV=Qa>(G8ZONX@#TEXr)K zhQ;45NDe}RF?2?VnI-$WXGBmlks?(H(rUzCW+>Blk&|QV0y8R25iNfwiDJxq!cIPu zPabn~ZK;;>|58mij8rOoTL`O&E?6<8fEo~wt09J4)=5|mSj-1|*wc#F5}%uZr_aVs zFUwcLsCN@uI>o)irtikRFPEem9j470^)4IH`a7x}2u!+A=2s~7iu7wsEU(+K_fvz( z5raXZ5-m*!ZSa?6YxQWhc?p8eSf*5u&}er1Te8?q!?mF~?lfVvp*324*)5T8XfDw& zx|yn!Z)GWCF790mDeW7p4uYS6T8{%(r{-1TQ=RDtkU?e;nPuc*2H<`7 z<$XT>zRf^yq6KGRxXR`K42AN*=f5RCvk&0=JqHf?F$WG7ee937lxM40xs@6SC-)9( zs*CIR+CZXZ$GMT`Y7MMC6XFH3d?0_bH0qYl6El4P(lIQqXs=`#-}5^|3UK3^;x{<# zQJz1J5_hu@ukd4q9|zJ0MgnUXjFPe6vhS#M={^=uAxe^>RSii+ipkI-1^R4(K-LN3 zV^-lrC>K*vxx}GZv5Qa!SCO=|f<}iW=!WVv5ruWIm8OlGqg6LZYg$QmsywBMRKH@m zwRkA4;Uv>sij2Pbvt5t!Uz(K}%V%c|??4q_iAvj_^foC?X*8qjtksKJ^Jmwl4{Qx@ zOMaEnrsbrTj1^tv9zQBq`qK3V=^Eyb$ZDq1o6ftiU-KuPUGRUe-i-Weq>O_3Ojk{> zKBNrZoebQM{+eHGBOlmus?u8Cl>0YQ;GWFbP3KM3{4Mr%eD-bs1Cg3y$*Ce!LQGQ? z{BT!BReJrm1nEmAS@>@I-HE-6?Ec;qAp=9?X|2?I5;i;QBfwqgM_}Osxc&oAJbjxw{@7wF{ z4p7`kGzVVaI)}@lJZ>zjqmR~TJ4XTGJ!CTyqtuX`+~hch5sV_E)Tmrkf7HGg47x#` zQ;7X5HNWa_FOnCjAukrjueRGClqOPC9Elnw<6 zOAuY61hG~9VqY?TL|F%& zCA`)8lBQ<~q*v!oVpp3jSwg#XW7HGD$uVWOy_Q%R9Q4q9>zg#9Qh3c-kowE-!(t{9 zD>AU>%S7?aJ{xE)f-O(!S}%2^k_#$O*i(40*cW-cHgp?c9Yx&RBpFWoYLggFHk(H5#wGfPZ$sVGn=xi(gPJWx9x)AU3R?g zZY2bhJ?Co^(G9}r0{EFpk_*~>c^5Nwze#Pq_~#byt#3rLA~fUj?JTw76ePC#_^#L) z{6gK^SPH>j^lC$#CnwhW_T?_Pg_t;Pjm4EySF*eTR9?aX<>bVgj=VSz#nPn_lt za`ElV+t?E~GS_?Q6U9vwK3#b0A|rE@$ll7s;}(&q;t1Ix+W0qE9f?6xL%$8?wH^m$ zg3YJHF=4SU-HI~N7o&=G(S}JC)njBJCyCKSc)hSTQbl%k(=!xIGO2T%6opGkoV{lI zUhm`l@%KWpT#6b`f~dEspV{fMHB_$32|U4kf-0eI@Uc0<^?`r&%Q}Be^-;Sm_s!lz zQ+?$^P4rnx?9<;<1NV+77qkeZU%o~AtAD8s4w>(7z*MrUQyah)Br3Ubq$39(&51ooF?F$t-$tBHDl~Lan%$a=w5{16r&>qRPghmOx_fZOebX7DQyo@c#L25{CVkUGzxlp; z4H|nAm1?~e=o6P}tt;Y@Jdl#yim{r?1y<8($9ZDmd3`ujsGa6o9Cq7v>3guDv_9>2 zX(t*so4NfKnCZY_6kN7OcO$)G>HA;Qk(1L=Uy0? zZw7Soo}^dQhyKF;3Hc3+5Qd$`#MYo9=<}^ZDVt3o+VV4{3dtsq*AStE%!Wn zs-Teg0dHkKFh=aRqKw@9)u`=^&({QvMk9M2>pW+ub<>7(wtUQi_E)xU0inR5+38v+ ztCTYLVpDjU6Y@>>kP%Ak9*s<&5E>qsJ*1!;oO{m@`8`$0J(o=Vear!DR{o6R(gy`! zpWz!h-e~WgklzzS;u}-^uYkg-fyAuXeGcfs!WvOA%c2#lxKIdEl4{&iQ&an#rNXBd z;1ep*&57Gm%0&2wVfI+93LL(I8j91blx2s}kRK<=4p%3row= zKP%}jZ^gg%q=ZXkxc?|*e~3DNY;R9z4CSq1wyk^KwC}!dJI-=;#{T_2qzB;tD$7G7 z)>$%C>fdw|9Z8ESgoqkLCpBXC*9TPEbx%DKet=K*pT-brhOZ zX+iy7ob`4p8<~MeX;8wpJaNWFLfuMl*Jg@5fnS~ma3?hABr`?xBZQ$W-;D2m|rDJ=uOp6$0E) z=wkf&H>0--yTUpkO$MRaoBLVs z?|*+fZ{GLwy1wU{=Q`I}I%B)_tC#!N)brii8_~MY{p>aA8ilK#7R4On3&)ev!e5_< zeRZ)-OT$fHntqqBvMSWomXkW`c5@y#r)7y?71NH00~^mat#7Ry5YoPIC1znQvP|7y zNPA~k>(-fJgWEk~l~qS1lA<4qri7h(C0l9bH`n?}PM+hrm1(tN!A^-WgUuJ_KDvDL z9mmLq<=yG~KE5-*pE!rLw9=*@-(m8FdBIu5IG^2L4~Wh4i`yMxcRNJP`_&Ha^=GdL zYrOcnf4pLQd0*3x2S&$QnICQ4b))C~?1I@1jLdmw+m!pVEY`N2JeG7P|H8hoC8yr4 z4U#z8epmKZXv*g!6^q@1sswuQrMS>T#_8^-*0&43GG}c&aPC0~_r(aK$tNr`Mf(6-M6z*-feQ3PE z#e{Ba9Ny*E-sZq1Y~fe=*w!3s2O_GVk7N6^Rb=xB@(Dc5}Q5bpME!P&` zz2e@eoAj$ot^Nzm^gr6OcfQP{%TP+KzE#NV?Ya9%wyJc1l}BhzqU6qz2O1WqFPw#I zA>_kr@4ZcZZu;OVUAxBcx_xzhCvtPVSY##nzTsH9=6cUs8xzuVuQlDr8lpitNA~FUxwtjgcCKC5!kAuQu3!j-cI?zGwTg z%EIm6RZ}FH^cYtRizQt#^-98Ptu7kb$?-uu?zube;)0x6d*1n_&5kuVWH0)1bcN>` zeokv^-25#98V9*%>+@cyVd=s#avH;vdZYcP_8uEzF?!76*~lxvyNyn`Anxn4gZAJ0 zY3=r(9d0ULdCMXqb4(<2C;db2Qk{&Z{XD&|k{vz5 z$$ojxY17!J1(Da9o*%r`T*X@rid zZi{EN9$bMA3B}(;Z_T}E|LTKwUd{Z|2bVU+m|3LdO4({Fha7#C&g*AbdPVT!ji~FV zuXyWrG!HC(Rl50AQH^|K2Oqo8o;GIY zMJ}9sOl{VS&6}#$&41iO^P_)7mu%EXeMwZ=QOm|H{5v@dm6v@h-Fxoo&zm;~%#7l; zIQ}x~O0p5ZkvLkIDx9}TqeitNW#Kpd#Rf{^<;QN!8RN|8q~#5yDLXoQH$R)F*SgkY zyz09TE_kAM!(Ynmthrt>+gWWPljVDa^ETIR7f-g8Y--G^pY@H4TeIpza)iPY1O4-> zcXZ5oI(}l%N8$ON_-ZGS17qIkMY!Dtn!H^d-Z=iW-Kp@^r$lMq2^m|3ktikA+8oO#YS0?R|n10cN zX040d+&L<6?dLP}^il<{>fMTcSZlCEHz7IU(?*FOj6aj51aqZ^Y1T3LxjfZAl8=90 zSKj`exAW+px~<=7GzLEO7i_H&dwRP<=51Bl5k6(UE%bTrN5f6acLpq7)!_3@qluO_ z`L@B`iU;neiyUPRrN2`Q6kgS9>^*Qp<=*M983Xs#+I5$DtUG^pr2k7} zo${l#y!4sloEd6u@l56yrN~mOo$82sgmv#zUMHKZO*S==VdR#wgx!HhXKi6hO zfpMOUyv$#G+P&q%o}1}!>gc36Ezh>OrK59DKd@c47gx9Mtyh&mscGc2Cl21n6D~%= z&FdzRt4NW_RsL1=Z!I7B7_h{e`}XsP8*MjOz3vQpC2Ew($nLIEDt!3_dwOgh$EK$? ztvnlo#hHYPPS!FM^=|Z+?r_|A#oWEGUBLZ)3-<~+gQ%mjb{#Lpw>reGKi)|5Jo)Ax zv)J?=Rb`{*0sZ}T%E~vwv%h8aRP^*-{8`r?S*)o=KWZA2&|;2LHrUFTtZp1o+|<-w zJ`$_`JpRRx&C2&9ZTi;zVd8er_ubq?a2L#`s?imw82VO ze^|?__Njgs@h)W^EmePh|IXH~vzOf1gEr@HSLw_PQXWju5jbN3uP~lDd+4ouiS+fZ z4}l)}eUAC%o9c$u%uYHy&A4=h(DHh*PVNQaHQAiKBEAaUhl}peDD2>wTXf36Wx;VD zny*H;-q01wn%^z&s^B8XS$AwId*>YRVr5p{N+mf#9xeH_hQ<`xg@t>(Ot_1cdF2$X z?kXAG$3-t!IWVrIc*W%6+i#gU@pmG!1dcVNRFoUcTTAP6yWBv@yxt5HdrJFn zmcPxOzx_?Ld7g5-o=2nezD**Z9X+|Yl#XnwUAyUw(8ajJ(wTeSFa$X3`<^S1Il|WX zz9&;KzOd=t;`W=8jS@5q1QtsvhMw7HJd1ParAC!_`P$XYbWYx@_VCwjbH26mN@#-D zm#1 z$DY$qe#Ni(%u%uF-l126Z#q~XiGRpk%a|1)b}#ca-{*tojZy{DjP6?>zQKpy$~*Eo zJ67>h?yGywVzcKz@g|%Q4c?X(a`Kzjnax{kRvJjXv9@CSWc$(V`jbueH|%^w_@3mw zTvPbOOP=k`;b5nen-_n$Hq5nt=UwA9wg>vSB^*4%SoAku+IrqYKFz1(!>y*vZ?<1E z+wA>n-?6P*&#mV4_%yG$;@#(q3NoK+pJj2d*;;?FA50424!zylZF4!8BYSli&v1#! zzQdM*t!cbY41>0=#r9h-lwE!Q&^BX!d3W609~au)XmXC)p6QAij9_1>dB!^3KkCre zQI{R3);)9RNp;7Kx_`QFo5FXhF6Y6iCeiRCm7J%fTfT^fXJ6EPKR?j!#DjLjCUG~t)3-R&sB!6qO~-Ak8)9p-q7%6myj?A^ znX@jEQT2u*Z#K&*8QBc-CWvjPM=-ag9ePA;-6KT1zSuRFysJrIVjh}TI)rz(EADdW)9>Ls?XnJ>@36_M_^Ua~~sBm2b++=YJDO2N_t!Bu=3 zOD=yu+3C8hKQCs*nW9@3E6YEvd?|c*k=$Udf#{a{gRcYxjIus0G0wvKeT{V$K9cJY zxwR$vSr)sl^2*Ziw6dT4&x|@>1*B;hCYQarGRHAfSlp4G^O592)sQA;`fR1ylp z?-YNp4>E~QXt?jUO1bM>-f-9Hy4?;Y4D&Xmw((>hj@HzWk@#GT!|mXTez~5mTKewy z=;5-sWoy*GSZ!lic<54`Zj1Go%+z06FPd{q_l^Ct6ACFi{POE$yA4^JK5RTB@zmhN z4OQlNzaY4Rgn;w>dkxv|A^p&1pEk8cyPM^Wcg{VB8S3r*zHDpdY`TK?)wjI3 z`>tG3IlyD3Dqrx{vGdlv6NMhE$)8!=kImPm?Fm(GiLr8H{drpPy~huuL8mUl9zyP` z<@f`67Ys#~rN{Rx#>Ylk-c_r6A`^be%hy(Pe3#%FKi{*)jK^N<+>$m>FbkD`5WMH| zv2djVrJ@y=SNzgD9v;2Eh>%;{`-WSej`3K(&9QU*R(JQj@cLz=JCbnr!}d%cj2NR(zy>%DVI`D>V0q8{~v_BoBl) zvhe-%iKNT;m6Xy+-xgTg?6N=R+2T`vjb+koHa+u$1+wR`9$CA+;^|vG-jAJ(ElS3x zWtvXbu}JtA%*u8hze3l(s>YNipP``cu-UVB7wsHA$ew6O-?G7m*V>ZyXlIp#9B;`g z>%s+!k6xE_t$DCz{TS1p{tQL)x1~piW7>`NKRmrM&iSxz?cy}Eo(3t$y@z8mY_j^F z{)idHU%HmJeTehY%_N;pvDM4bLy7_bs^e^z~hlX{8)0+Rtf*vfh2~r1kykL9sfnCvAy~Huq|DjU^1X zvaoJGCH-^g34b`BpM*p7x{tj3X2tN83Ov_N^0UivO;TGyHza$}Bq*Wl0z1d%qk`f> z{h1XxX7})ija%!Q!;jlkmCLu-^?l*A%{p##oI`Iv?NcT~&WLAA_fsGAcE4Y?i*v2P zObx(H$p$dOc063O7ZB)=BY5MTO>o}$->*m>Hk;T#t=jf!zWt-c3>F^Rw6&$1@r*eu z9Q8_S<5tGfns+y!P$_kKYTx0VKPp=py~2XkFpOqd{WjNYDNkQ4EY45~XzoyQ?K?U$ zv3q)PX&{%4p(D>4OPjWp9cDHHdj&U&rO~GZ8Q?7QJB?l#&Hl)A&dIofB}=5&x^-wX zlV_rU>g;U#C!QlrUvyg!jW5_`CGn6u$FhB~g>`bmw)-D>=|2mvcV|mFSI*pZF~Ioz zTH2El`oY`^9tTq2_|+}` zapUSOK`M0@m-A*nZCTiv)xOC1l)Gfe{la#RLs8s~JXc~;qDmOnSZrtBPj53%jNyse zJ{&H0w06+*<-=j!vYsW6Ywcs}e<|xEh*mDNDw95TdN7Q4?Aq#Bn@Bg;3XaiKA-O$Y znMPifFV*zSR;gH7@yTpy!$36C_7J$qyxJjk!ELUz4;hZJMd3HO4+Okjna0h{pA)UK zX~3g^kl>iAFl&FD;2xoitW7~rD`G-54!jJOFyU~E;I`KIa7>LiE+aHY)wOL-iC*TZ zodPO(4BQVSbQuP8^xkVoc_m%Yuv_x$Mg1PTzBMCXr~w!mbYdEVbm&sSTX_1V47Su`ZuqIbW|c3Q=xjkhIZkB#1mxh<@D zV(HM_8Vg-9zx0m5n93K|ccwfsdiUi;k_TbTKq5^ZuK3Cn6%JH+VJf8egm3Wv({;jG z?R(*BFZ#!waF?fIYV7)-BL3fF*Za;_5L+OTB9W)^SZ()4`LE`*@{88IaDS0C=pDn^ zRu^&Vo7TCPb)`DavMCqOwH%TjeVnVa_#C@aiHqUBk|Q{sgwz9m<|~vh-!VS?R>daZ z2S<62yi0UmIU|$IhSK!T3_+gOwu5(N_H4YZtQUU#L6~|U^T@9a_heQqeiB@S#3=^SNwar600yS=G#b2>&$o;U_!#<}d0Hi}*j)i)(2Y%Ow5?-uS*@U6RPpTg8p?7M8CX!3Ho6Wi)Gh2HNn z^EUWCu3|d-+j2)UzfLt>zciT#2AAKCaqsl@+1PH$VtIW-(AJSltP2WT$C&S@a!KCk zVm{n!@{qPGK4Go@H_L?n_k8-ldWB^AM)&n>s%+Sy;&>tIlla%Kj)@tBn{C$}HY>@# zjnBH2)p1RIK}NOiOPn#TKLnoj$MXzv{yihr~zopDfl(ctY_vV*(l zIDa><;Z9PLr7iVKbq;md7jPv_gCn*o&##KiS@1NyH;^=DJQ^6*H95tEZqF@IA<%|)Di7N%|>vR z;r0#5mW}z*bi?!Y6w~O^Y!2u$bF#9r<;T`b z@u{~rOzuWRQ$=J&<*WkJRflSIc<4QO9xIqQw$vPA534%pkvOunOto*}CvOXt6@#^d zodtJI&i+jOs2b}m&P5k%@NDqb$iQi7=Of=$PxwaFT<1G-@oL>IXGMPzruW=CwdQ?n z{Jz^WG)$I7XzAr+ha}6_FY0n;x1%RKH&Rj^k`Gk97Vvqrra^5BWBIpR{23C?dQ5X~ zh2>YiTW^*i@}Qk{HU4QYt@-;nbL-Ihd+OgGo}D`|B{`NbM z``%6NR_t6olyyS2)o|Aa(=&X>WAOWKZQ_)0 z-YMFkvz^1^&Mk=yqt%Dp*Q)Orj#{b9)9t9!MMzKSroN#J&DQeB{l@oOQ0n z-dpmF7Tw9(@mZ-ysX4TKNyLxtGug9V`>x-s9(MejpCLR{^{y^xX}Hb7hs>rODW4p9 z%d{eLo#^!a!t!d=)+OMVUborXT`IbMZ+F6#{CXG3gh9o14-eW&m)A>pr(K-qbk{HC znu)>%OUs8XgDn#6DY4^YStBithYelVgzVU1ys0ZQ*1P$;$HPa3XAQSAKWGTOkP={c z=4|~#GrVqj`6c%izx-D>OZ7bBdvdSO<%?!`>v!WD*V6Afc$tCA8=Eda$dR=F%EL<}tid528mVlUotY?O zQO2;y`S6O>lD9VrvMiF^<+=0d;PyqLe})h>M>nOpj{jnqFITTiQjB!p*wqwHpo0L>w%kc-jjtXruBs~t(Wwi7qF~% zxKhi;)v#W})#1~NyV*C|6mDh3^K)z6xWiGfv3Ir3)-%D$qms7lj|;E$HmT}7`T8VY z_8zzGTN%yIwCzC(@k^~76!NOR$9>^UtLJ_BU{(BVyzw~K_1y+TbZ3qv-nUL$tKlvj z5I=tN0n3){U3PDaCFGCO74G8eEfh-BbI2Bs=uN)+pn6x8>I3_m_*g!d`(3ZaZYJ|( zJEWYk*02qUzMcD&N3Mmg^Rs4T6VnZxVI}_I4UZ2xV!b-Dch*Oh^(zF;{YxcfyrQcFDe|=RVtLwAqM{ERTD~ zJaxUZW$m3i9EW;L`l3XxzdMLKschh%fA^p=!_#Pi=l!{g2Yfbb*ndqmKIFLE_sa9v z^=;$)X{}AGc2+ANGCR9Gd(VmEcSaWtid}o)ZFVcE;Jil$r+OZ*UoYXkU3N+5o9`VO z3xpZDotY&z+o(UeDJE8uj5{yGUJ~~y;7MV#t^G?a`FkPn)}|J%HyVjliZ#&HGVH6X z%|82xXZBiOhs)5=WCoFy%o?TsNa6`p#v)rA1+oeX+TSU}TcWIA{USDvxouzo3 z!RmRK&a1*Y?&S|gsuq8ZNe*Ak!1eiD+8jf7mQzuW`1}HOD#v4DN;!qL9vt1=^1*z5 zG`-kyzkTTsU&TNDd`$Z9uz+aNEFqfa5@?YY?vy2WgT=1(TpQIlg7{p^OW zFVPnjn8h^rYQf;Fz30u2o6%c@%O?oLKJdOy6ZxR*yq=_mw)^uRrk2f$ruD3QZHKPQ zbq6$G|K8a6c|CI7$`=i7aesyt7PT_xUM)DCd(>*gN2fZEVQylZ-BELyOB%PL<&D|b zTJ{@M2SlYVKgnY|``E2H-FI3p#1>z=(WP3@=&*sm+*2jEKx|R7VK1G~qYl{7d;OSP5_zF=D5!SirwP4SzG$}~E$Qt5+|=^UMMnMIa^;(b|f-Y?VKb%}3Yuw~@O z?R!$|Ec~PcX=%H+OIezo-_}={yIe!^+DD1HOE&nZKKC8XXA5n6vD#OW*3 zxu-UrDG?vqS1xaLe(x&K>dO5*@yDTNf5xH%JYOrq)S^U>T~WH&#HLg;R$SYROZz4f zK8w-xm}Z{K&fZ;D^ygVwUQ%pY*SAVTC}yn$&Cf+A@s%w1E-`-LcrV=^v+api982iC z57ig68dC0ty2E<*;fb5`=snd z&+WPO{Dup1xBEqly4kfIwPW6X~awW3bH>&|M>;@f%DJ5AiupH zS`tvUckwD@^oP0ce{GHr^mY^t>5~qmY7D%#d zh-plINY_4-Cgg|_L=l{>05m~g;sjj? zo_H+L;iid>57om$;sgm3ml>ftH(jx4TAzs1a>uy_;n0>gofeW~On!(aR)U=qk=$=u zl=3S)MRr0Xeq`xlusvNT%TOdsh?Dfic?ZHHJ17|es4?l?i`4@!mFXV|)%J>Qt zVP%*X5)tTBFDc-BDT-zUahiby*J*rDw?lMLC?`h>qjS?G$&2dT58@OjmLdNJSvndv z(8-q-QVR^g{{_K{SN)+xLz5e|8uBJ0qEq+ub;D^QQOk0})OPC0p|L5N#aPLj0~HPlvF~T-?uWL_@Q; zX>zOOUoMQfsD!{46I1$o&|r zgZ1`3oQQEM1Hj*KhbZ`pD>(pSx^?n$RcnAKym|iQ{Yig2-R(x4W>8?DkGGDGQ&7ML zr>UD=ruX*k@Zf{x;E~Z_Bgj(t)R!AI>`8{Qc_4%VQvS3tK**;W;?#M#vIM#HY3j?3 zat)@0Hg>O(fluAqvib!?78lm(O7ssSN?8*JkIOl4Kr#pod@$aVSl1DN+dsFQo(EQ5 z3j#-$UZ=j?sFS1yE} zgIuxc8J1+oHA76v0eVU(dJB${pyz@M@(lbP5jF9io>M+aEOhPb8Z~?mFc)XQ$Y=f+ z7$V_IGO2cc4<<}t_J4tq!xmZ&BX@x;aKf{2`bbrj^B-WaK?FGF?+pN6qQORy63x_? z8>MufD9A*(A?8_#{frTQZQcNOnE+>_(J9T>JmOUSab9pF42fqGQ3pFRAmqKo*_KK} zhu=YT_?u-TPPMO?D0y8-4SY3xwqeU5F3+LR2!zcFNdU4^I`!p7jluMp$cQ~X%&a1! zNm&NDz5PJ^9%vFx{KyT;iOXa6JmOZxL1euC4*n`K)ou7YH|jwhY2t{0iI_NlGW(J} zAmJ?#w$Ma1>WLEF_}f*9x##Z19zPLV(}m$;S`=s|PZW~fAg{@h&VT?1FT9D3&0jx8 zYrg^r92g%u!+U(6QW$-FC~1)5ZJe%8!Tbm?IH41KnOrxeB<4+Mb%w0u_tNk5WG6}4$AS(pl)%~0I3?rcaV-4t_&-=AaWZ$A-WY|D zIk;td5MrMBZ(2y5RwY2*JgJD$yRUXA+CyhuEo8+N{*0<(7G&CcsG&IZqSS2zvY8jIuIg_AT zcCtLn9DG74n2#gOgwfg3V**iv1~^BkcuV>E`}pGh0}1$meZlu?R6`{gEB)&p2oK}WyE`-l_%TP-p1_t}Oq z#Y0FNJ}%WpHraUrc{J(ei9|^o;sRk_O=^aUkZ!-#K(`FYeu9|20%gE8hlrDgNfUv1 z@+=|d)wUbDdkX0OEqxo28*ZI@6UA(KbZouM33kB5Tu{DA96f6D2%ZL|Y{{ zL05BfxyW*Z(C?BF={!rSOGQKxWYYy%BO0*p1oeOuu_ROvR?|F*B|_fz&2_bqzvnNW zUO(A$no2-y5$>-MQ~d$rQ-VZW5hcRR0!DnOvDDqPTr3K%31lvy)y2+wUc@MUqBIGxY^yhB|A1#Cxcy*MNBwkZP zequ(v!P_?|kfar?we*xlo*r8!2QWHmFgkP<#&{0ADyVCE z!mbkaiSh`x_P@>A9n1_kqkyv(Wou5$slY*!D1u8UDWt92gKsYaq+fspbD}?AZdAQ6 z6-b7-Z3Hhki$)46QF-tnHdCubseppDZ5T{RBIyr!op%O?#KGD${;-53w3%YmAR(y& zCGpz#>`qoEh}S7FexudpAVme<boGq23 z0_l&TlL|qn)|Kp=2d41`I74$~0pl;3@%#^hkTt;@PSTPLt^BkFk>#MTkHDE0imMV; zs*xztSjCI+#(l7NMnre|`e(B`<%lz#7nw(-GOa&-6OxoskR5t$^%RZ_ZFPTGah^YCbI3$Wq*e;d-xdxbTG0fl5akJZn9N~!_Av!oG za7!W+VlVv*t1m;BD_}_&9r^=&D54%9qy>lceO!sR|$;^(ZH2i=`07 zGzelpMJx$l=gUOE=l~2IC%NJ%1hdBZd&7xU^5Pp2Jh*Q+V4VRhboqpLA7xnB7C<9n z;slbRSr73S9Y@~pCr5W`&k$B3gZN7MGqD`x8U$p$R05@pYYCLn#_sh|KKd>1Uo>=K6WkaK9n0QWsQ#^+}96j^DcbX#Nr03wh0n)Q|LE}g0_CP*Hi&u%SZT7vgmP;&sUHSdXT33Mj`os zx8z`hJj*uu{se@CY<@-y>E{rIAll9Z$TWxvDeESu=>h;~fQHUmMMkItAh)G+#}(F{ z-~==-;B{zqBtq&(a)j3Onbh|rE7+0>uN%x?1X2nGb)bi^Ge0RL53Z-{3AflFdjUy$ zomJ_Qgk*5>N04l6K)D9ntT~ji0$7ukjVazHrxu1dZ`gQ8q~aczo2-5XV3i@9Z$!Z| z&!ZN0D(#<)F{I->=hf3$DNqBS3!5m=>oby!6ywg+8gh)_#gRfYZO|IBN{t@=m;@;y zZQ|n_tc(_d5#$8+nVHAdcN{r34;1Sed6;hzx%yRkW-kLs|L}_Ka%8Aax`;j@P)G~5lmz09;Is;y40I+|X+Y#; zzRGtu66wE!XQJVDuAveRS;!#=7kJ|KjdqY*C%~zoxT95}7|se=33kGHlHyAg_o#0O z__COhwaKre6bM^EsU@1FM}R6Pq$X&y4b-5BGAZqkoO!nNJlK{hbRA9H1}=>Q>f89zsBsT5G<=Wp%z+m@4 zkU~3q4~`6Nq@?(Js!uFR`P**bLKbL?XE^(NkReHR|4ZEfw>@-n28-Ah_Ifa)o2%bU zDv_OC^2?_SD$tE`IBY@rWc1#5fPlLK0xl%%f4vhcX~^UO+SpLcsDJ=FWQxE2PKx zC*N6}Qg?2Y*C~p?u#ISBVRtMCc=9V~Xk{l9kt6$ey9qY!WFz(P9WY%w491T((9gwW zXcNuM5K*l3tbGchfTjqPjIIw9-6ltOvVM(a`Uqu#cDohZK%+^J_n~ty`+7OIDmR)qY`c&#dAUz9vpCt5g>G_+KZ$JpMAkblI;X!`(quLR)+OLj2L0vP}3pH|pbjYM>_5 z#7RJPxYUf;A{~OM+kM5g57=vfK&_9$T*pE^CKZEaRIFO+FG!2*z|ql3{b6=0fU(`2 z<;B7sO=* zl?qv&5*cw(0nD|KzG|Yl9fnQFByD3Rx0C;cG@}_V3c*^C{XgNIzQrOXfNDV4h3Di! z8qc+3@O3I|+%GbpZv2W-l;dHWN{iwBOGYpPA$NnL(=VP(ifAJ-XL4mgh*Z%SF_60Q zg*i&#!1q8=kb(XAa-(XGQHh1k%<7^a`AGe{4H}vmqg;vsCPy5y%#2j6-7^RgqX-5) zG&5IDQHh1k%#clV60E$@oCed@{v#`7L>)g*F#vT@X^qB-JHn7*HbaJq4&lrfser`h z$LK+VT?r@#sq2fQ_=&tsj<_cQ@_MZJjT97qap!G62?XCkLyrw%W#kC^61?H$BzE?S z(C*Q=ue}9aogG{qJqP!I;yvlu@`v_65tQg0905C?@Zqp0nAA!bMKw?oT5+3VFbV@F zg7@WkjI1B1I}ox0^p3u-^%UcoPqIlYPeX9tNHjibWuc+@340XrBV-S4=$v>v%@3Au|79cbd` zQcfMa=LIY8%6mezUkW`(S1zp>$k4Vx&i3fR{m*#+-vcp`srX>Qrl%%g%65Q*4rYs) zsm35T*x!8Bc%2!9wF`n7x*k%qfLbtYkzF$A?#~5x8GweK&%cHx_DxY1nHU|~zjWO35n6CkBm(9i+c zP=pfd#AVd2DrmU^%n34*Y5OJ=;e0K59ROwW6?Z-VYhgH0!XCEiAjM)7f>02f_O)Ds zT{bl05EIovPE%iQ6ak7q6mde~(2Il;I`=2W3UF*z1gbvhNq*8A%FwViz1pGds5gk} zBm49+@FF-BK$;6!2t+C_SZNm0Wr2Lr^gxKMPe4FuhrVk?0qKd_0qOXZom#7>2=NI{ zL`*AJCE8MnKrTAP$S&J;214x}m?2M#9d^_~5z)iidj}iAp9%cahYD^-O6e0*1W%mi zRY90_^gv1_Ic28scW%@wKMH7*TCEnmcP@ECx4Fh7t=p4|o+u4G^|+>&k3}X(8Z+Lmq%; zqdS&D>VNO`ndAr?=#86MG)yLG4gxFa^j2*@WkBY5Uz|S0||r6eq`$2`$K-nkq2eK<`YOl|muRKlVio3Au^VShwQ?Y~!U-1@A^D zX$EPOAz_bp2<-#U-mtI%7s#b8XvMF{pq#da&x9#YZmyoGcm#;HYHO+uSXUiv)Itx~ zNm-Nv&7_P(@z0kNh04MG3V{vuEL{E^Im&Pu47O|#!XbBGnO1|`)j{rP!U`8CBTQs= zq*>)O0B59VPJknzGh?-jlo2MMVeH~i%v%8+mxJK|jZpzNMvxvhC#6C@!KibdeaQpj z(FGXqSE9nULMcTU*b41oHM}|q=%6dv^WB1y-tT>YyJ>w7<;2Ns z*hXyrmG(w!WiXrVU^eKHcwR5XKr;n|)J$5${dXaoKad3vD4YEGa-;TtAxe7U`WNkB z%oSvWXd|bn#aSTL4Go=j?jImclyrgm!1G|`JK&xvFixTEWXB+Jx)Vh`3%4LIN8&5? zwfA&l4M7YGLCWZ)^S~%k%E*?sApgnhF38q#E4tSH)&oh3W4eX zfZo5qpNS}d)4$i;YZ`9S|9yuEv2d8OnT<6CKpY^ppg~#}P!B?6xT}0BzCRfgAt6aqfiHBn-LD0lUr#`qhON2rQ#L#{lmm%DhJF!lWWn~DQkZ8Nq00bi> zS3ppPOsl(DE@b}nQ~kRavWHtcCQOKL(*z=XgH!r4Hm)a zpC>~9Jphk@jHIuvtpE_%l|Bumek1iD7*az(&V**cv(9jmYX-H=b$`a)StmTgPVPauYf*QuL$SqgVi*Pa`2kaC>yyZ*7J*E*)Yp}?4W`dDprI#&P1h)d^M~8Ryor{r&U4ZX7K4t|AmBpf>d%)O zRb4?HfaU}cw$ye;CU98*0LJY*zGz z{dQ_Y{2l|NMvwbRjZ~2*W6@29J2%2^aGJxw3R*GJ&Hn`ln;V0Bt7GN>0uSuaMlWf^ zw^4?og`aq9V`^4|4bwG$ynq3O23r@WW#exmnmDy&)|xxHcD~eWdJv41 z9~l#Z{6;!20tg(xo5sn?m(+t`r2GiT$epv}*dP+!)PrE8{0PW_v{NaUFgcNiLMkQk z|6iS8r2GhoE&oOaY)<5Qs0YEgQXB!1F>emT22prVJqX4n;|NGw{=17BkQ~+tO`p6d zeWV%$+e=RDH)1sgFM)Fr)1u_PA5=gfqw+r!7;G&2M+>>Wf%cI%_R#rL=s0CqdgdBr z95SI@VK-bhO|uDn1&vWfGoK<0`v-%FKkibg^hL_BGciuhrW%8YJK_?~5Y5l5Fu&oY9)yT_y`xVHzy@jLqaK8aeHk25wZkrB7xPmO zLd3vSMA+jGV~Q(7ka`dz;odbpNHQNl!e)$)yM?F+ArkICFYN4C0?FNLSb9P4^w_h4 zY7lH+k#X4ehoJIe@Wo|W?QS5^?Dy={HH&Rx}k z7r`6nNjaowk8D#k7$V$&G;QelU`!e0?}V1f1ARzF&``4e7_y5a9F%8(5@VGq^%(zN zi6t~)ImB1+%9c2B+y+!+M;=;%A1(ejWNddBbfVv(1O_t#?tq^2u)vd(l(@rhX(CJG zL>_uVB&y7OfSv{TG6cg^M@ckiD`hy7wY~}Q{eD_uV*Lo4EqB*9IdCO6Mh?V^rwq_OkhgvVtdkjV(AT+%q@p%7#0>ZY0<90>coj^6GW`wl)=|o{*uZ*-KT#u|E zFOA%itROEm@f?78AZ!Kq!p8ZuRbI{ra6%xYq2+cnn+hD`pg?$cfD}-ij_}G5xUWM} zX8PVX!YRsuu$f53u|*jP(9mSUFo&)}O57kx+Z*TYv(3v>+Q!g8+Y|4Fx!DRa;B&R? z`Qcz)4Pag90jA*vr2r;4{{X!9HYfbVZN}J)gzph=90nY3$V4dVp+lLoeTz!b_$^k_C!nJkbNQ-#B6I zgblpF5yiT|xBm?o#Wmb8{#yoCI9Mh|HjHBnqITVF*=>-avBPj?jOx#opZ|~j!3J+E zNGU?DH0XpasX8d|WAt?YlNN|8Al|Zd#RAa$rx~`##__*n8o?XCaA)Z6J^I*OZ!fZ4 z=mI@}-Rsk=KbiA??}0_AFWDX#vM*9W-d#hE@@+)P-Gk?U>jCm?3US#-EY{MXlgi9g46+?wmus! zAAeFv-wp5SJ8@VE!I&W;go$be-_T4p*l7g~&4l4>ddftEfM6;Zq3uGlHSU{-(1A-0l%HG{$LRsxU|>+mS6n^*Si}3N-XigXZTWIQk0wA)q;R3hckq%N5g|FXBfKpCK$!%(j2~me!a7U`) zD`@BwH1rrHWcDB6Cia&jU|10>Q<>(HHY6!(&@@r3`CI;1EJK_tJi|wTEsxWN6U6+w zecMYUAPT@SifM}|T#o-Upou0HWJ9`-_+p6Aa6u%E8j8m=Zq!3gu22OK)!vvur4PKi zM+46ZPBWGzUjG4YqM(T<4#$sIPD7@N$VnBnvE=$t4>z%olqhRq{8vJYnrLWd!wEOE zN2di*hc&sG4@+6>q4z{`KvBpRD|C3u(qy2@*CsKDGLtYg$7m}Up)EADQy~J?DG;|VeZA=whfG`{#mqib0&GO5Vg!9(HGR!VB><)zHu@MDd9fqqrb7K_YAfwO0*| z0Pz86Xq}uqL^*(`kFRg2mOmkwD30K-V&`9=59Co+w73S6DaLWb`8$(DNhnkEAB0&- zKQ#2zbi)y{DE?3ghawF;4NWxC3@>!ie+EO#BWUPwnQ)Ra`UKDeJPAz{;nMk6*)lLe z5r>8jm)G(rL-6|j6f{wYWdcjao`bJHg@$&Ib)^(S5WERwB;`i8KcXK1K0-t5+y5#R zApeL9(+U4UL6@AaRQ@*<%u#agugeU`WgcD7&`$E}CKWJbHS@TT(f2V-2;M?ND_^;e z3YMX$m-iI7wMB7z*J!P~f2YS+eF4BDbav~J6_d!FW%xa?s<*)f-@seP~ zxnl|iZB}oe{x_7F6;ou2TQ2?Za4T@q1PwjFH@%_;hphb$?Cf~`9+W;f!?=b&Pyv4DG+qU%kL9qAf#9r9@wwa1>HvupP}pUr~4?Q zPO|eJR+a(dFq|X9I=b_1pUIKe_4f(#g@;h3@Ls-wp;$({^TLs0W*Eegw^YP{fvGPy zYS~wcsbd7DouB)wrfdi8a)ATn=x*?aL=E<_PCV)@;kEq)e$!=;N)0r0j^O>BVhAUsGK)Z9G4bg5{@x`}C4kFCrp54} zVR8t6ADofGBaf{U!*JV#r}2O#PnQ|Xp0CHLz#zadSkGm@FT z{lksl@3+Z`F?6&vv2Z>xGaDM(zC75efC-s=m7FNbKg&mG<=^2Whhh>G;6~jN5_$kn zQl!MnWH+A zhg@lG4Gldi*;tc9`R4(bzY8%~AoEH%87pB6Cvq4YJsG68r3QomaRoEa6+h-1BLN(U zKtr$LbGcCiFl{vki3YJ0E3EbTHhwAW|5Qx8Ryqwf6fqF)f}k>m2{)Tbbr3Yb5k zpD55C@fv32rRcyJF_|uuERau-w=>>Z10M`0{)wzjBa!mL=N#rfGLh5hw|qw8!5MmOZ7B-oH3IK4f|}pevlNL@SKJr978RJ0p2AL z%fc)-$I-ztLYiNIfp$s4erhqykOyS3KpdB<$-IVv{xdXm!Qo~SH6X|XJXrLll6f{g zfm!DRXlR!oN~WAXVNx4d0IyH->_ZkS&(8qhPon}LctYJ+04EL!Dt>~+ym!#hM$4Z` zIY0p3SL*lRh#9#Kn{2cX2ZU`iP@K+DhY~zF1Y@E+?zky|Jfw^?bWK*FlnRuI%?YF( zWcWvr4ZOQS122e7LsEu27fF}2|2pAh9G*lX<|fKwB`G?vR)^e~i;nr>*Z&(5QD@mO zpPv?)_aHMXv?=h_P!C1SWoX97RO%ph-Gqi7S+yRK188E(eRKpN= zpSq$eoyg0WNJE=kVm-AmlPJVu@*69@AD_Y8K0rgSqMT^_uSkJ`KA7u*1G2%Y@P5U_ zm8$4rx%d8m!?N)4#fmnmP14PP~>AOQQ)$4 zl7ViWkI^OXs}=+A)S`$Q#_g^w#qu9D1dRn7+(*grOn ztGh%00g4n?4&5%1axh9r%@`@fX_zREtbt@063NeUaD>#>9vV8-l`v6POWbYY8W_ru^-Q#`8Re-!n3%x)et`j_mbkkA zWf?zM6H+8Y^C6@_7G>g!N-0ldRuPC?435c%FT)1fei*<$LPM)M6`lYklb=l@1o@Jn zf86o%W_Un~2A-*!b`$m^4YKqnU&E8~_VEvN!%}l;{)cN$Fv@R%hIR!7JxYmBrj|q@ zQjb44G__)ehUhh*4kExO2%C%Nn=Rih0`V};5RsrM#Sp}Z(^+4#nkvzw`yXjVp7`%q z{iGam{#pbtU$~JR!$`0BXh|Yz$vbFhhyrWMA)H}%&&1n~SP&=gmuMjn@1dbr0$$iq z4&g>*nU9OHQ6A|$5|YpiFxpa19dR_G4D>!*5IUs>^zfsznQ{n!WcE%JBXFG|?OX^) z3!tIv1l#N=$CwBe#FhQbD&xR2kP{*=bm(riryL~6mnauoHO%%S0La`5t?KbDlmi44 zQT2)YA^vtCA4h2Da3|tGmbzaM&L2;@vblCa|5_QKEe8!9u-kCt=>PMM9*Lpt-QzjF z+hAA=fQB|!ODF0PFvos83>aJQkMZ79{1 zTKbp_q^t?eoCUVg#u3$#&K6)Y>TIi67|cAzJD^yhg>AjzH4#LDUB{(M zP;<_+Iv25>qLwO$wp#k_^sKw(!==bNDw#r z5DzZcPy~_7({j%^C0&3Ulp}C7f*8T&k_{y=+^WF$hSC;J+sEKbRKOI&h!B&n$Phx4 zj_0!caIiZ`+!4Gg*KAr08{oL7VkE%_Uz3in)9igxVlf13wBll@VqOng1q(ETGf*o; z-jF2*CVU2G6!C=VCmUT!#YZ><5oo6{w#rs`aW^GMfp?`#5QH%| zMW-JZW0RF>X>||wv#zKxbMuVR=mNGN?_?;U=KfDQ^+UsP5wYgKbKknB+o13>;At;7 z@`-eGm@-4fuJrWBS$cMPmbllQzxD2l3m6OTp#g*u^`}0UFGB!3&o3^3VxOB|71l~O zCmE0EC5q-!M?QW(v*+@{gF)!%>f!7?-I%lQX${Kko4>10hZcIlptvI0=n|)I-K_y( z^&g{(V{vWF9I9tZ=ASa??>N$P0=x>(Y%3zk7acV~Cfthmc#;-w-Cfd3p=jr9+^mAV zB}?(r9@Xz5@;|fJ$dn!>nB=y}G2T_494ZyfCk;N)@me0f^H6-}0AlLpS>{OW+)`|U z1_yGqt}o|qFR$$pdP3^lwZoqMF+^myHNN@xiEeXBX?$_wZEdR}T=0>TLt8VwzkXCbBfCQ1=T>NieHo}>OI=DF?<0?c0Ag zqpUYD9ww;mizT7-$va#VcC9?Nv?nm`CMch!(otLk=KSku2X-2H6bc<1%9cq-am?p? zDe`K4Kv+bcW}-}6AqiBSk;JuMkn{Bo4Z&$;!Ycnt28(Mzw{c5U!Qh0V&|DtRRWeu{ z3zjr)vd9pMrlc$Rl1OaFn`^)Cci-938TxcH(JAI@$t14z+DukYV^P;ZDD<>c`5MV2 zj_n?9{N~jkz}Si6gU-qDQ;?}!Ydr_4);i2Eh4-rCE4vo=!2s!oLOa|!>#fJ>lrdr* zZiCq?t!8h>e`*32U5EUsq^{jdEdwr9rP6rdKIa!5LgtJUb7QOPag z6U|WQ5cyT9bQH%c)Okz26o5Q|PV`eXJSqt!GDJRZ9JSyxa3-VBmKAec4vT9+$Ewvw zW&ZGGJWCuv?xVPzKH~Caky4%3yKz+Sn@NbQ65A1}Jny9*SGp#iQ3XD}*}p zYIO60S=LdLyZ+4fFou|rwq2A&5*+&v+WmQ@DY{!b6xy(&E2NXS<~#T4=@;xOfl3pl ze!eOh#dV53&I|HSKp}QzI{i>~e@Z5Cb((r`)@t^A1$)4ePH0?jOD1vpiuaFoSbi9T z{23IwIK6zwQjSKGEV4Ld7n$y#S$}Re2u^5Buj9Ajry%p$T|r8+a;%H)6P%!KdE&-7O!*&^#y6kV!{W2!Fr~k~`0n@M?5gNetX>Bd6`kcqhUV*=L##GEG3_j2Rv943tr=wdK(GE7C`eBZ% zRHvx4g74xoA)YoKwj>13!7hiR!TU4qZ6E}@=1M4%%U68rp zH5=fAbgFTp>K_kyCucNCj*fS`KA@|Xx6Ap#BK&vUks2;r$>Hkdtg&*UfwuofObZSYMu zTL_?4WvDgjX<{OTrJr$jh6oynK=<*|yW2nnOXBaWEf%c4ACSdH^2Uh4leXB})n;NC zBJrZFvPETwPL43h28{M&h$Jm~*-R32(X|`yqSD+Nzq{L}PT2GJN0g07v!RbIrK#C5 z5!xYOpJ?mVR}Qp+VNSv@)KiX!+d!01mHxg4{pOdL!#by@SHwXK_B41bu}D;;jl~Gi zXd~2VYHWy$3H0rNjol(3&~gYwhY_!6TL`32RTfAKVc(@Z^sf&~(RBKt=};H38*KxA zm`Ydesz}1ZuCQQg1{0<8?&(2CF`~M{MQDc_7-Iub&}z~QoARc+E=+(9zmBVzh3|k2 zDx+<@8F4liKp-oCN#W4!sS|r$I1iG1L|im0(FRh8k12^eZwShaRH4B6~DKGr#I>VL5K6#BP*AvQ7+>EVqa6-9mJ@)2D z;(Il7Gsj!7r+ z%N{v6>oV!mqpk;f!+Y>HrO^s(&jC47Sd~lXa5Mjna9G|2mZuFj^^i@45a=zLZ$}gj z3i=H)BtQl_uW&zNQyIh)slI>h#@TrI{Cn^WI(B`2T$UJ?X4H*RteeipaW~i@nsh0u zQ*s2T)4^DlQx`UPzgr4Pgh~N zf69SZuL7;fbzZZ6{GFXJe{1xPG#{(-FFBG}m*>~w{6lY+=l2ZFlCIBNRoOxc3o`w- zYJME8g+Ekau%iC(@f|rLL}-$c=$Izn2)Z0^x{^IHcmU2wzk+Z*p-^#8!#s=0{SgvV3cdOZ2PH4etSZM?7W zwwGB{-Ap*v!`HmQ%~z`5jqda2!-pfG7>zNY`n{jkZw2}dH)!fdx^4FutC(TxI2Cf$m}lzeE<%}wC(52LzK14)+ck`U@2lhi z1?J}4x7?n$62RpE(t#;EQ67-F5er)LEt}f&(TghhP!baU2NKK9*U00BY9{cJC7JP) zSUBMzuptC_IZYn2+Ig9>!Y^YUo!YH`5}Ie1?#8Q<4jHoOrpmH}(UaTPc=Uy`UMN09 z**|8R#ntQw*O}_M#Nb9+q{#}MZF}rieC7c#uK?#waFgdq!KEPFuV-;{!uDUE5%dg{ z#-P#UgtED^Xq?T>MSndh>JCmH6n~=G+n-BerPf5zg|%DjT+)tZT=qlpCB&WcWD_|W zP8cxqIm?866@{i>49b&NO4jT>OO`-5AHfFv=oD35chJ52>-b0H;x?F7GU| z6f#_Vhy9;eI=?vLnwWrtosON2zs5~kWQrr%Oc7X#9SjR}y9~Q;!u=+PkjakeuRLSA@voUBk z$HD=&tNkg++*l;YO4q5AU2&U;a$-3CXF5o+iWk2+DS17r`x^x@=Gvcv%qb<}75l1F zl-h|QY(5pD)M8-bO{f^+2nOn9H%0h{4ACpZS7vqJBSTh! zv>9_n>RuO*NFe#EV|9Fx-SeV36Wic&{BFjl;7^xX2{Hw+5Zb`}z|8sZtLD(AZ|z56 znG9cD6$cIxSVH!!7gNFT*Ge*6nL>4B-&G5Mk6xvaVTA;cId;_-n7} z(1hJ;@*dG-%}sH}zzlY5PoqiYITjQD{@xxQKS2CQEJS8>Dab5rWTw`X zG?gw*xaa9OBDHfi9D}`+OnaUV&CJvc8?Z;p2c{t4f&bx@Jzw~^W&5&~aE^nWad@Ft zbk>R<{zDuwRHaMM#0h-KsGr*Zco6n@083MsUfEu}TCC~Es?auZ5ZY8?=F%TTpE#>Q z)%P$5=uITv(n-APP!(=b)5fZNanE?NO4#gkuQVC63}&AKv-cu|6lZY)a?#YOy6T0N zQy5-^G*yB5;f);i)=$v^hd>1v0vOrVa)4>w%sel~|K?Bv;RnMb>9FqPW~OeIjF6&J zE0bS#i>3@F|99u>rANa!3(-!g{GL6{FcOrws!gnozKCjDz@85ng1V{v*Ls_&8*e3{ zYfsZ@Sr(rDFs#6ceoZ-Pp$axy3XUtWf9?ln7!&Xu_y~= 0; i--) { - digitalWrite(i, HIGH); + digitalWrite(pins[i], HIGH); delay(timer); - digitalWrite(i, LOW); + digitalWrite(pins[i], LOW); } } diff --git a/build/windows/dist/avr_tools.zip b/build/windows/dist/avr_tools.zip index c85df3d431b5d705b99e1fbc2f296d80c6f728bf..fd8bf0144e8f9bfc45ae8f6bae41c21fb9844cd9 100644 GIT binary patch delta 98775 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 delta 203430 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

  • 8x;IK1>a6M4OQ8JZUb*n@Kyy6 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

    WN(Ks1Ynx>Ll~#Y&4!RsuF)v4R{O}=SZ>~ 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 S0j)SI8J{!AyfzrVTKo@^j>=I0 diff --git a/build/windows/make.sh b/build/windows/make.sh index 9863d3f9c..85e5f3bd3 100755 --- a/build/windows/make.sh +++ b/build/windows/make.sh @@ -145,8 +145,8 @@ CLASSPATH="..\\build\\windows\\work\\lib\\RXTXcomm.jar;..\\build\\windows\\work\ # show the user an error, rather than crapping out with some strange # "class not found" crap # need to do this twice because otherwise dependencies aren't resolved right. -../build/windows/work/jikes -target 1.3 +D -classpath "$CLASSPATH;..\\build\\windows\\work\\classes" -d ..\\build\\windows\\work\\classes preproc/*.java syntax/*.java tools/*.java *.java -../build/windows/work/jikes -target 1.3 +D -classpath "$CLASSPATH;..\\build\\windows\\work\\classes" -d ..\\build\\windows\\work\\classes preproc/*.java syntax/*.java tools/*.java *.java +../build/windows/work/jikes -target 1.3 +D -classpath "$CLASSPATH;..\\build\\windows\\work\\classes" -d ..\\build\\windows\\work\\classes ../core/*.java preproc/*.java syntax/*.java tools/*.java *.java +../build/windows/work/jikes -target 1.3 +D -classpath "$CLASSPATH;..\\build\\windows\\work\\classes" -d ..\\build\\windows\\work\\classes ../core/*.java preproc/*.java syntax/*.java tools/*.java *.java cd ../build/windows/work/classes rm -f ../lib/pde.jar diff --git a/core/PApplet.java b/core/PApplet.java new file mode 100644 index 000000000..b6616cea0 --- /dev/null +++ b/core/PApplet.java @@ -0,0 +1,8334 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.applet.*; +import java.awt.*; +import java.awt.event.*; +import java.awt.image.*; +import java.io.*; +import java.lang.reflect.*; +import java.net.*; +import java.text.*; +import java.util.*; +import java.util.zip.*; + + +/** + * Base class for all sketches that use processing.core. + *

    + * Note that you should not use AWT or Swing components inside a Processing + * applet. The surface is made to automatically update itself, and will cause + * problems with redraw of components drawn above it. If you'd like to + * integrate other Java components, see below. + *

    + * This class extends Applet instead of JApplet because 1) we will eventually + * be returning Java 1.1 support, which does not include Swing (without an + * additional, sizable, download), and 2) Swing is a bloated piece of crap. + * A Processing applet is a heavyweight AWT component, and can be used the + * same as any other AWT component, with or without Swing. + *

    + * Similarly, Processing runs in a Frame and not a JFrame. However, there's + * nothing to prevent you from embedding a PApplet into a JFrame, it's just + * that the base version uses a regular AWT frame because there's simply + * no need for swing in that context. If people want to use Swing, they can + * embed themselves as they wish. + *

    + * It is possible to use PApplet, along with core.jar in other projects. + * In addition to enabling you to use Java 1.5+ features with your sketch, + * this also allows you to embed a Processing drawing area into another Java + * application. This means you can use standard GUI controls with a Processing + * sketch. Because AWT and Swing GUI components cannot be used on top of a + * PApplet, you can instead embed the PApplet inside another GUI the wayyou + * would any other Component. + *

    + * Because the default animation thread will run at 60 frames per second, + * an embedded PApplet can make the parent sluggish. You can use frameRate() + * to make it update less often, or you can use noLoop() and loop() to disable + * and then re-enable looping. If you want to only update the sketch + * intermittently, use noLoop() inside setup(), and redraw() whenever + * the screen needs to be updated once (or loop() to re-enable the animation + * thread). The following example embeds a sketch and also uses the noLoop() + * and redraw() methods. You need not use noLoop() and redraw() when embedding + * if you want your application to animate continuously. + *

    + * public class ExampleFrame extends Frame {
    + *
    + *     public ExampleFrame() {
    + *         super("Embedded PApplet");
    + *
    + *         setLayout(new BorderLayout());
    + *         PApplet embed = new Embedded();
    + *         add(embed, BorderLayout.CENTER);
    + *
    + *         // important to call this whenever embedding a PApplet.
    + *         // It ensures that the animation thread is started and
    + *         // that other internal variables are properly set.
    + *         embed.init();
    + *     }
    + * }
    + *
    + * public class Embedded extends PApplet {
    + *
    + *     public void setup() {
    + *         // original setup code here ...
    + *         size(400, 400);
    + *
    + *         // prevent thread from starving everything else
    + *         noLoop();
    + *     }
    + *
    + *     public void draw() {
    + *         // drawing code goes here
    + *     }
    + *
    + *     public void mousePressed() {
    + *         // do something based on mouse movement
    + *
    + *         // update the screen (run draw once)
    + *         redraw();
    + *     }
    + * }
    + * 
    + * + *

    Processing on multiple displays

    + *

    I was asked about Processing with multiple displays, and for lack of a + * better place to document it, things will go here.

    + *

    You can address both screens by making a window the width of both, + * and the height of the maximum of both screens. In this case, do not use + * present mode, because that's exclusive to one screen. Basically it'll + * give you a PApplet that spans both screens. If using one half to control + * and the other half for graphics, you'd just have to put the 'live' stuff + * on one half of the canvas, the control stuff on the other. This works + * better in windows because on the mac we can't get rid of the menu bar + * unless it's running in present mode.

    + *

    For more control, you need to write straight java code that uses p5. + * You can create two windows, that are shown on two separate screens, + * that have their own PApplet. this is just one of the tradeoffs of one of + * the things that we don't support in p5 from within the environment + * itself (we must draw the line somewhere), because of how messy it would + * get to start talking about multiple screens. It's also not that tough to + * do by hand w/ some Java code.

    + */ +public class PApplet extends Applet + implements PConstants, Runnable, + MouseListener, MouseMotionListener, KeyListener, FocusListener +{ + /** + * Full name of the Java version (i.e. 1.5.0_11). + * Prior to 0125, this was only the first three digits. + */ + public static final String javaVersionName = + System.getProperty("java.version"); + + /** + * Version of Java that's in use, whether 1.1 or 1.3 or whatever, + * stored as a float. + *

    + * Note that because this is stored as a float, the values may + * not be exactly 1.3 or 1.4. Instead, make sure you're + * comparing against 1.3f or 1.4f, which will have the same amount + * of error (i.e. 1.40000001). This could just be a double, but + * since Processing only uses floats, it's safer for this to be a float + * because there's no good way to specify a double with the preproc. + */ + public static final float javaVersion = + new Float(javaVersionName.substring(0, 3)).floatValue(); + + /** + * Current platform in use, one of the + * PConstants WINDOWS, MACOSX, MACOS9, LINUX or OTHER. + */ + static public int platform; + + /** + * Current platform in use. + *

    + * Equivalent to System.getProperty("os.name"), just used internally. + */ + static public String platformName = + System.getProperty("os.name"); + + static { + // figure out which operating system + // this has to be first, since editor needs to know + + if (platformName.toLowerCase().indexOf("mac") != -1) { + // can only check this property if running on a mac + // on a pc it throws a security exception and kills the applet + // (but on the mac it does just fine) + if (System.getProperty("mrj.version") != null) { // running on a mac + platform = (platformName.equals("Mac OS X")) ? + MACOSX : MACOS9; + } + + } else { + String osname = System.getProperty("os.name"); + + if (osname.indexOf("Windows") != -1) { + platform = WINDOWS; + + } else if (osname.equals("Linux")) { // true for the ibm vm + platform = LINUX; + + } else { + platform = OTHER; + } + } + } + + + /** The PGraphics renderer associated with this PApplet */ + public PGraphics g; + + //protected Object glock = new Object(); // for sync + + /** The frame containing this applet (if any) */ + public Frame frame; + + /** + * Message of the Exception thrown when size() is called the first time. + *

    + * This is used internally so that setup() is forced to run twice + * when the renderer is changed. This is the only way for us to handle + * invoking the new renderer while also in the midst of rendering. + */ + static final String NEW_RENDERER = "new renderer"; + + /** + * The screen size when the applet was started. + *

    + * Access this via screen.width and screen.height. To make an applet + * run at full screen, use size(screen.width, screen.height). + *

    + * If you have multiple displays, this will be the size of the main + * display. Running full screen across multiple displays isn't + * particularly supported, and requires more monkeying with the values. + * This probably can't/won't be fixed until/unless I get a dual head + * system. + *

    + * Note that this won't update if you change the resolution + * of your screen once the the applet is running. + */ + public Dimension screen = + Toolkit.getDefaultToolkit().getScreenSize(); + + /** + * A leech graphics object that is echoing all events. + */ + public PGraphics recorder; + + /** + * Command line options passed in from main(). + *

    + * This does not include the arguments passed in to PApplet itself. + */ + public String args[]; + + /** Path to sketch folder */ + public String sketchPath; //folder; + + /** When debugging headaches */ + static final boolean THREAD_DEBUG = false; + + private Object blocker = new Object(); + + /** Default width and height for applet when not specified */ + static public final int DEFAULT_WIDTH = 100; + static public final int DEFAULT_HEIGHT = 100; + + /** + * Minimum dimensions for the window holding an applet. + * This varies between platforms, Mac OS X 10.3 can do any height + * but requires at least 128 pixels width. Windows XP has another + * set of limitations. And for all I know, Linux probably lets you + * make windows with negative sizes. + */ + static public final int MIN_WINDOW_WIDTH = 128; + static public final int MIN_WINDOW_HEIGHT = 128; + + /** + * true if no size() command has been executed. This is used to wait until + * a size has been set before placing in the window and showing it. + */ + public boolean defaultSize; + + /** + * Pixel buffer from this applet's PGraphics. + *

    + * When used with OpenGL or Java2D, this value will + * be null until loadPixels() has been called. + */ + public int pixels[]; + + /** width of this applet's associated PGraphics */ + public int width; + + /** height of this applet's associated PGraphics */ + public int height; + + /** current x position of the mouse */ + public int mouseX; + + /** current y position of the mouse */ + public int mouseY; + + /** + * Previous x/y position of the mouse. This will be a different value + * when inside a mouse handler (like the mouseMoved() method) versus + * when inside draw(). Inside draw(), pmouseX is updated once each + * frame, but inside mousePressed() and friends, it's updated each time + * an event comes through. Be sure to use only one or the other type of + * means for tracking pmouseX and pmouseY within your sketch, otherwise + * you're gonna run into trouble. + */ + public int pmouseX, pmouseY; + + /** + * previous mouseX/Y for the draw loop, separated out because this is + * separate from the pmouseX/Y when inside the mouse event handlers. + */ + protected int dmouseX, dmouseY; + + /** + * pmouseX/Y for the event handlers (mousePressed(), mouseDragged() etc) + * these are different because mouse events are queued to the end of + * draw, so the previous position has to be updated on each event, + * as opposed to the pmouseX/Y that's used inside draw, which is expected + * to be updated once per trip through draw(). + */ + protected int emouseX, emouseY; + + /** + * Used to set pmouseX/Y to mouseX/Y the first time mouseX/Y are used, + * otherwise pmouseX/Y are always zero, causing a nasty jump. + *

    + * Just using (frameCount == 0) won't work since mouseXxxxx() + * may not be called until a couple frames into things. + */ + public boolean firstMouse; + + /** + * Last mouse button pressed, one of LEFT, CENTER, or RIGHT. + *

    + * If running on Mac OS, a ctrl-click will be interpreted as + * the righthand mouse button (unlike Java, which reports it as + * the left mouse). + */ + public int mouseButton; + + public boolean mousePressed; + public MouseEvent mouseEvent; + + /** + * Last key pressed. + *

    + * If it's a coded key, i.e. UP/DOWN/CTRL/SHIFT/ALT, + * this will be set to CODED (0xffff or 65535). + */ + public char key; + + /** + * When "key" is set to CODED, this will contain a Java key code. + *

    + * For the arrow keys, keyCode will be one of UP, DOWN, LEFT and RIGHT. + * Also available are ALT, CONTROL and SHIFT. A full set of constants + * can be obtained from java.awt.event.KeyEvent, from the VK_XXXX variables. + */ + public int keyCode; + + /** + * true if the mouse is currently pressed. + */ + public boolean keyPressed; + + /** + * the last KeyEvent object passed into a mouse function. + */ + public KeyEvent keyEvent; + + /** + * Gets set to true/false as the applet gains/loses focus. + */ + public boolean focused = false; + + /** + * true if the applet is online. + *

    + * This can be used to test how the applet should behave + * since online situations are different (no file writing, etc). + */ + public boolean online = false; + + /** + * Time in milliseconds when the applet was started. + *

    + * Used by the millis() function. + */ + long millisOffset; + + /** + * The current value of frames per second. + *

    + * The initial value will be 10 fps, and will be updated with each + * frame thereafter. The value is not instantaneous (since that + * wouldn't be very useful since it would jump around so much), + * but is instead averaged (integrated) over several frames. + * As such, this value won't be valid until after 5-10 frames. + */ + public float frameRate = 10; + protected long frameRateLastMillis = 0; + + /** Last time in milliseconds that a frameRate delay occurred */ + protected long frameRateLastDelayTime = 0; + /** As of release 0116, frameRate(60) is called as a default */ + protected float frameRateTarget = 60; + + protected boolean looping; + + /** flag set to true when a redraw is asked for by the user */ + protected boolean redraw; + + /** + * How many frames have been displayed since the applet started. + *

    + * This value is read-only do not attempt to set it, + * otherwise bad things will happen. + *

    + * Inside setup(), frameCount is 0. + * For the first iteration of draw(), frameCount will equal 1. + */ + public int frameCount; + + /** + * true if this applet has had it. + */ + public boolean finished; + + /** + * true if exit() has been called so that things shut down + * once the main thread kicks off. + */ + protected boolean exit; + + Thread thread; + + /** + * Set to the an exception that occurs inside run() and is not + * caught.

    Used by PdeRuntime to determine what happened and + * report back to the user. + */ + public Exception exception; + //public Throwable exception; + + protected RegisteredMethods sizeMethods; + protected RegisteredMethods preMethods, drawMethods, postMethods; + protected RegisteredMethods mouseEventMethods, keyEventMethods; + protected RegisteredMethods disposeMethods; + + // this text isn't seen unless PApplet is used on its + // own and someone takes advantage of leechErr.. not likely + static public final String LEECH_WAKEUP = "Error while running applet."; + public PrintStream leechErr; + + // messages to send if attached as an external vm + + /** + * Position of the upper-lefthand corner of the editor window + * that launched this applet. + */ + static public final String ARGS_EDITOR_LOCATION = "--editor-location"; + + /** + * Location for where to position the applet window on screen. + *

    + * This is used by the editor to when saving the previous applet + * location, or could be used by other classes to launch at a + * specific position on-screen. + */ + static public final String ARGS_EXTERNAL = "--external"; + + static public final String ARGS_LOCATION = "--location"; + + static public final String ARGS_DISPLAY = "--display"; + + static public final String ARGS_BGCOLOR = "--bgcolor"; + + static public final String ARGS_PRESENT = "--present"; + + static public final String ARGS_STOP_COLOR = "--stop-color"; + + static public final String ARGS_HIDE_STOP = "--hide-stop"; + + /** + * Allows the user or PdeEditor to set a specific sketch folder path. + *

    + * Used by PdeEditor to pass in the location where saveFrame() + * and all that stuff should write things. + */ + static public final String ARGS_SKETCH_FOLDER = "--sketch-path"; + + /** + * Message from parent editor (when run as external) to quit. + */ + static public final char EXTERNAL_STOP = 's'; + + /** + * When run externally to a PdeEditor, + * this is sent by the applet when it quits. + */ + static public final String EXTERNAL_QUIT = "__QUIT__"; + + /** + * When run externally to a PdeEditor, this is sent by the applet + * whenever the window is moved. + *

    + * This is used so that the editor can re-open the sketch window + * in the same position as the user last left it. + */ + static public final String EXTERNAL_MOVE = "__MOVE__"; + + + // during rev 0100 dev cycle, working on new threading model, + // but need to disable and go conservative with changes in order + // to get pdf and audio working properly first. + // for 0116, the CRUSTY_THREADS are being disabled to fix lots of bugs. + static final boolean CRUSTY_THREADS = false; //true; + + + public void init() { + // first get placed size in case it's non-zero + Dimension initialSize = getSize(); + + // send tab keys through to the PApplet + try { + if (javaVersion >= 1.4f) { + //setFocusTraversalKeysEnabled(false); // 1.4-only function + Method defocus = + Component.class.getMethod("setFocusTraversalKeysEnabled", + new Class[] { Boolean.TYPE }); + defocus.invoke(this, new Object[] { Boolean.FALSE }); + } + } catch (Exception e) { } // oh well + + millisOffset = System.currentTimeMillis(); + + finished = false; // just for clarity + + // this will be cleared by draw() if it is not overridden + looping = true; + redraw = true; // draw this guy once + firstMouse = true; + + // these need to be inited before setup + sizeMethods = new RegisteredMethods(); + preMethods = new RegisteredMethods(); + drawMethods = new RegisteredMethods(); + postMethods = new RegisteredMethods(); + mouseEventMethods = new RegisteredMethods(); + keyEventMethods = new RegisteredMethods(); + disposeMethods = new RegisteredMethods(); + + try { + getAppletContext(); + online = true; + } catch (NullPointerException e) { + online = false; + } + + if (javaVersion < 1.3f) { + addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + link("http://java.com/"); + } + }); + // no init to do, so don't cause no trouble, boy + return; + // call this after making the methods to minimize the + // number of places needing the javaVersion crap + // (also needs to check online first and create empty + // stop method register list) + } + + try { + if (sketchPath == null) { + sketchPath = System.getProperty("user.dir"); + } + } catch (Exception e) { } // may be a security problem + + // create a dummy graphics context + if ((initialSize.width != 0) && (initialSize.height != 0)) { + size(initialSize.width, initialSize.height); + } else { + //System.out.println("setting default"); + size(DEFAULT_WIDTH, DEFAULT_HEIGHT); + this.defaultSize = true; + //System.out.println("zeroing"); + //this.width = 0; // use this to flag whether the width/height are valid + //this.height = 0; + // need to set width/height otherwise + // they won't work for static mode apps + //defaultSize = true; + } + + // this is automatically called in applets + // though it's here for applications anyway + start(); + } + + + /** + * Called by the browser or applet viewer to inform this applet that it + * should start its execution. It is called after the init method and + * each time the applet is revisited in a Web page. + *

    + * Called explicitly via the first call to PApplet.paint(), because + * PAppletGL needs to have a usable screen before getting things rolling. + */ + public void start() { + if (javaVersion < 1.3f) return; + + if (thread != null) return; + thread = new Thread(this); + thread.start(); + } + + + /** + * Called by the browser or applet viewer to inform + * this applet that it should stop its execution. + *

    + * Unfortunately, there are no guarantees from the Java spec + * when or if stop() will be called (i.e. on browser quit, + * or when moving between web pages), and it's not always called. + */ + public void stop() { + // maybe start should also be used as the method for kicking + // the thread on, instead of doing it inside paint() + + // bringing this back for 0111, hoping it'll help opengl shutdown + finished = true; // why did i comment this out? + + //System.out.println("stopping applet " + thread); + + // don't run stop and disposers twice + if (thread == null) return; + thread = null; + + // call to shut down renderer, in case it needs it (pdf does) + if (g != null) g.dispose(); + + // maybe this should be done earlier? might help ensure it gets called + // before the vm just craps out since 1.5 craps out so aggressively. + disposeMethods.handle(); + } + + + /** + * Called by the browser or applet viewer to inform this applet + * that it is being reclaimed and that it should destroy + * any resources that it has allocated. + *

    + * This also attempts to call PApplet.stop(), in case there + * was an inadvertent override of the stop() function by a user. + *

    + * destroy() supposedly gets called as the applet viewer + * is shutting down the applet. stop() is called + * first, and then destroy() to really get rid of things. + * no guarantees on when they're run (on browser quit, or + * when moving between pages), though. + */ + public void destroy() { + ((PApplet)this).stop(); + } + + + /** + * This returns the last width and height specified by the user + * via the size() command. + */ + public Dimension getPreferredSize() { + return new Dimension(width, height); + } + + + ////////////////////////////////////////////////////////////// + + + public class RegisteredMethods { + int count; + Object objects[]; + Method methods[]; + + + // convenience version for no args + public void handle() { + handle(new Object[] { }); + } + + public void handle(Object oargs[]) { + for (int i = 0; i < count; i++) { + try { + //System.out.println(objects[i] + " " + args); + methods[i].invoke(objects[i], oargs); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + public void add(Object object, Method method) { + if (objects == null) { + objects = new Object[5]; + methods = new Method[5]; + } + if (count == objects.length) { + Object otemp[] = new Object[count << 1]; + System.arraycopy(objects, 0, otemp, 0, count); + objects = otemp; + Method mtemp[] = new Method[count << 1]; + System.arraycopy(methods, 0, mtemp, 0, count); + methods = mtemp; + } + objects[count] = object; + methods[count] = method; + count++; + } + } + + + public void registerSize(Object o) { + Class methodArgs[] = new Class[] { Integer.TYPE, Integer.TYPE }; + registerWithArgs(sizeMethods, "size", o, methodArgs); + } + + public void registerPre(Object o) { + registerNoArgs(preMethods, "pre", o); + } + + public void registerDraw(Object o) { + registerNoArgs(drawMethods, "draw", o); + } + + public void registerPost(Object o) { + registerNoArgs(postMethods, "post", o); + } + + public void registerMouseEvent(Object o) { + Class methodArgs[] = new Class[] { MouseEvent.class }; + registerWithArgs(mouseEventMethods, "mouseEvent", o, methodArgs); + } + + + public void registerKeyEvent(Object o) { + Class methodArgs[] = new Class[] { KeyEvent.class }; + registerWithArgs(keyEventMethods, "keyEvent", o, methodArgs); + } + + public void registerDispose(Object o) { + registerNoArgs(disposeMethods, "dispose", o); + } + + + protected void registerNoArgs(RegisteredMethods meth, + String name, Object o) { + Class c = o.getClass(); + try { + Method method = c.getMethod(name, new Class[] {}); + meth.add(o, method); + + } catch (Exception e) { + die("Could not register " + name + " + () for " + o, e); + } + } + + + protected void registerWithArgs(RegisteredMethods meth, + String name, Object o, Class cargs[]) { + Class c = o.getClass(); + try { + Method method = c.getMethod(name, cargs); + meth.add(o, method); + + } catch (Exception e) { + die("Could not register " + name + " + () for " + o, e); + } + } + + + ////////////////////////////////////////////////////////////// + + + public void setup() { + } + + + public void draw() { + // if no draw method, then shut things down + //System.out.println("no draw method, goodbye"); + finished = true; + } + + + ////////////////////////////////////////////////////////////// + + + /** + * Starts up and creates a two-dimensional drawing surface, + * or resizes the current drawing surface. + *

    + * This should be the first thing called inside of setup(). + *

    + * If using Java 1.3 or later, this will default to using + * PGraphics2, the Java2D-based renderer. If using Java 1.1, + * or if PGraphics2 is not available, then PGraphics will be used. + * To set your own renderer, use the other version of the size() + * method that takes a renderer as its last parameter. + *

    + * If called once a renderer has already been set, this will + * use the previous renderer and simply resize it. + */ + public void size(int iwidth, int iheight) { + if (g != null) { + // just resize the current renderer + size(iwidth, iheight, g.getClass().getName()); + + } else { + // create a JAVA2D renderer (the current default) + size(iwidth, iheight, JAVA2D); + + /* + if (PApplet.javaVersion >= 1.3f) { + try { + Class c = Class.forName(JAVA2D); + size(iwidth, iheight, JAVA2D); + return; + + } catch (ClassNotFoundException e) { } + size(iwidth, iheight, P2D); // fall-through case + } + */ + } + } + + + public void size(int iwidth, int iheight, String irenderer) { + size(iwidth, iheight, irenderer, null); + } + + + /** + * Creates a new PGraphics object and sets it to the specified size. + *

    + * Note that you cannot change the renderer once outside of setup(). + * In most cases, you can call size() to give it a new size, + * but you need to always ask for the same renderer, otherwise + * you're gonna run into trouble. + *

    + * XXXX Also note that this calls defaults(), which will reset any + * XXXX settings for the font, stroke, fill, colorMode, lights, etc. + */ + public void size(int iwidth, int iheight, + String irenderer, String ipath) { + String currentRenderer = + (g == null) ? null : g.getClass().getName(); + // ensure that this is an absolute path + if (ipath != null) ipath = savePath(ipath); + + if (currentRenderer != null) { + if (currentRenderer.equals(irenderer)) { + if ((iwidth == g.width) && (iheight == g.height)) { + // in this case, size() is being called a second time because + // setup() is being called a second time, since the first time + // that setup was called, the renderer was changed so an + // exception was thrown and setup() didn't complete. but this + // time around, g is the proper size and the proper class. + + // that or size() is being called again for no good reason, + // in which case we just ignore it anyway. + + // so all that needs to be done is to set the defaults + // (clear the background, set default strokeWeight, etc). + //g.defaults(); + // removed this in favor of calling defaults() from beginDraw() + + // this will happen when P3D or OPENGL are used with size() + // inside of setup. it's also safe to call defaults() now, + // because it's happening inside setup, which is just frame 0, + // meaning that the graphics context is proper and visible. + + } else { // just resizing, no need to create new graphics object + g.resize(iwidth, iheight); + updateSize(iwidth, iheight); + redraw(); // changed for rev 0100 + } + // in either case, the renderer is unchanged, so return + //return; + + } else { // renderer is being changed + if (frameCount > 0) { + throw new RuntimeException("size() cannot be called to change " + + "the renderer outside of setup()"); + } + // otherwise ok to fall through and create renderer below + // the renderer is changing, so need to create a new object + g = PApplet.createGraphics(iwidth, iheight, irenderer, ipath, this); + //g.setMainDrawingSurface(); + //if (g != null) { + updateSize(iwidth, iheight); + //} + + // throw an exception so that setup() is called again + // but with a properly sized render + // this is for opengl, which needs a valid, properly sized + // display before calling anything inside setup(). + throw new RuntimeException(NEW_RENDERER); + } + } else { // none exists, just create a freshy + g = PApplet.createGraphics(iwidth, iheight, irenderer, ipath, this); + //g.setMainDrawingSurface(); + updateSize(iwidth, iheight); + } + + /* + // the renderer is changing, so need to create a new object + g = createGraphics(iwidth, iheight, irenderer); + //if (g != null) { + updateSize(iwidth, iheight); + //} + + //if ((currentRenderer != null) && + // !currentRenderer.equals(irenderer)) { + if (currentRenderer != null) { + // throw an exception so that setup() is called again + // but with a properly sized render + // this is for opengl, which needs a valid, properly sized + // display before calling anything inside setup(). + throw new RuntimeException(NEW_RENDERER); + } + */ + } + + + /** + * Sets this.width and this.height, unsets defaultSize, and calls + * the size() methods inside any libraries. + */ + protected void updateSize(int iwidth, int iheight) { + this.width = iwidth; + this.height = iheight; + defaultSize = false; + + // make the applet itself larger.. it's a subclass of Component, + // so this is important for when it's embedded inside another app. + setSize(width, height); + + // probably needs to mess with the parent frame here? + // TODO wait for a "legitimate size" flag to be set + // (meaning that setup has finished properly) + // at which time the parent frame will do its thing. + + // if the default renderer is just being resized, + // restore it to its default values + //g.defaults(); + // no, otherwise fonts that were set in setup() will go away + + // this has to be called after the exception is thrown, + // otherwise the supporting libs won't have a valid context to draw to + Object methodArgs[] = + new Object[] { new Integer(width), new Integer(height) }; + sizeMethods.handle(methodArgs); + } + + + /** + * Create an offscreen PGraphics object for drawing. This can be used + * for bitmap or vector images drawing or rendering. + * + *

      + *
    • Do not use "new PGraphicsXxxx()", use this method. This method + * ensures that internal variables are set up properly that tie the + * new graphics context back to its parent PApplet. + *
    • The basic way to create bitmap images is to use the saveFrame() + * function. + *
    • If you want to create a really large scene and write that, + * first make sure that you've allocated a lot of memory in the Preferences. + *
    • If you want to create images that are larger than the screen, + * you should create your own PGraphics object, draw to that, and use + * save(). + * For now, it's best to use P3D in this scenario. + * P2D is currently disabled, and the JAVA2D default will give mixed + * results. An example of using P3D: + *
      +   *
      +   * PGraphics big;
      +   *
      +   * void setup() {
      +   *   big = createGraphics(3000, 3000, P3D);
      +   *
      +   *   big.beginDraw();
      +   *   big.background(128);
      +   *   big.line(20, 1800, 1800, 900);
      +   *   // etc..
      +   *   big.endDraw();
      +   *
      +   *   // make sure the file is written to the sketch folder
      +   *   big.save("big.tif");
      +   * }
      +   *
      +   * 
      + *
    • It's important to always wrap drawing to createGraphics() with + * beginDraw() and endDraw() (beginFrame() and endFrame() prior to + * revision 0115). The reason is that the renderer needs to know when + * drawing has stopped, so that it can update itself internally. + * This also handles calling the defaults() method, for people familiar + * with that. + *
    • It's not possible to use createGraphics() with the OPENGL renderer, + * because it doesn't allow offscreen use. + *
    • With Processing 0115 and later, it's possible to write images in + * formats other than the default .tga and .tiff. The exact formats and + * background information can be found in the developer's reference for + * PImage.save(). + *
    + */ + public PGraphics createGraphics(int iwidth, int iheight, + String irenderer) { + PGraphics pg = + PApplet.createGraphics(iwidth, iheight, irenderer, null, null); + pg.parent = this; // make save() work + return pg; + } + + + /** + * Create an offscreen graphics surface for drawing, in this case + * for a renderer that writes to a file (such as PDF or DXF). + * @param ipath can be an absolute or relative path + */ + public PGraphics createGraphics(int iwidth, int iheight, + String irenderer, String ipath) { + if (ipath != null) { + ipath = savePath(ipath); + } + PGraphics pg = + PApplet.createGraphics(iwidth, iheight, irenderer, ipath, null); + pg.parent = this; // make save() work + return pg; + } + + + /** + * Version of createGraphics() used internally. + * + * @param ipath must be an absolute path, usually set via savePath() + * @oaram applet the parent applet object, this should only be non-null + * in cases where this is the main drawing surface object. + */ + static protected PGraphics createGraphics(int iwidth, int iheight, + String irenderer, String ipath, + PApplet applet) { + if (irenderer.equals(OPENGL)) { + if (PApplet.platform == WINDOWS) { + String s = System.getProperty("java.version"); + if (s != null) { + if (s.equals("1.5.0_10")) { + System.err.println("OpenGL support is broken with Java 1.5.0_10"); + System.err.println("See http://dev.processing.org" + + "/bugs/show_bug.cgi?id=513 for more info."); + throw new RuntimeException("Please update your Java " + + "installation (see bug #513)"); + } + } + } + } + + /* + if (irenderer.equals(P2D)) { + throw new RuntimeException("P2D is not yet implemented, " + + "use JAVA2D or P3D instead."); + } + */ + + /* + // ok when calling size, but not really with createGraphics() + if (renderer.equals(OPENGL)) { + throw new RuntimeException("createGraphics() with OPENGL is not " + + "supported. Use P3D instead."); + } + */ + + String openglError = + "Before using OpenGL, first select " + + "Import Library > opengl from the Sketch menu."; + + try { + Class rendererClass = Class.forName(irenderer); + Class constructorParams[] = null; + Object constructorValues[] = null; + + if (ipath == null) { + constructorParams = new Class[] { + Integer.TYPE, Integer.TYPE, PApplet.class + }; + constructorValues = new Object[] { + new Integer(iwidth), new Integer(iheight), applet + }; + } else { + // first make sure that this in a nice, full, absolute path + //ipath = applet.savePath(ipath); + + constructorParams = new Class[] { + Integer.TYPE, Integer.TYPE, PApplet.class, String.class + }; + constructorValues = new Object[] { + new Integer(iwidth), new Integer(iheight), applet, ipath + }; + } + + Constructor constructor = + rendererClass.getConstructor(constructorParams); + PGraphics pg = (PGraphics) constructor.newInstance(constructorValues); + return pg; + + } catch (InvocationTargetException ite) { + String msg = ite.getTargetException().getMessage(); + if ((msg != null) && + (msg.indexOf("no jogl in java.library.path") != -1)) { + throw new RuntimeException(openglError); + + } else { + ite.getTargetException().printStackTrace(); + Throwable target = ite.getTargetException(); + if (platform == MACOSX) target.printStackTrace(System.out); // bug + // neither of these help, or work + //target.printStackTrace(System.err); + //System.err.flush(); + //System.out.println(System.err); // and the object isn't null + throw new RuntimeException(target.getMessage()); + } + + } catch (ClassNotFoundException cnfe) { + if (cnfe.getMessage().indexOf("processing.opengl.PGraphicsGL") != -1) { + throw new RuntimeException(openglError); + } else { + throw new RuntimeException("You need to use \"Import Library\" " + + "to add " + irenderer + " to your sketch."); + } + + } catch (Exception e) { + //System.out.println("ex3"); + if ((e instanceof IllegalArgumentException) || + (e instanceof NoSuchMethodException) || + (e instanceof IllegalAccessException)) { + + String msg = "public " + + irenderer.substring(irenderer.lastIndexOf('.') + 1) + + "(int width, int height, PApplet parent" + + ((ipath == null) ? "" : ", String filename") + + ") does not exist."; + throw new RuntimeException(msg); + + } else { + if (platform == MACOSX) e.printStackTrace(System.out); + throw new RuntimeException(e.getMessage()); + } + } + } + + + /** + * Preferred method of creating new PImage objects, ensures that a + * reference to the parent PApplet is included, which makes save() work + * without needing an absolute path. + */ + public PImage createImage(int wide, int high, int format) { + PImage image = new PImage(wide, high, format); + image.parent = this; // make save() work + return image; + } + + public void update(Graphics screen) { + //System.out.println("PApplet.update()"); + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 4 update() external"); + paint(screen); + } + + + synchronized public void paint(Graphics screen) { + if (javaVersion < 1.3f) { + screen.setColor(new Color(64, 64, 64)); + Dimension size = getSize(); + screen.fillRect(0, 0, size.width, size.height); + screen.setColor(Color.white); + screen.setFont(new Font("Dialog", Font.PLAIN, 9)); + screen.drawString("You need to install", 3, 15); + screen.drawString("Java 1.3 or later", 3, 28); + screen.drawString("to view this content.", 3, 41); + screen.drawString("Click here to visit", 3, 59); + screen.drawString("java.com and install.", 3, 72); + return; + } + + //System.out.println("PApplet.paint()"); + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 5a enter paint"); + + // ignore the very first call to paint, since it's coming + // from the o.s., and the applet will soon update itself anyway. + //if (firstFrame) return; + if (frameCount == 0) { + // paint() may be called more than once before things + // are finally painted to the screen and the thread gets going + //System.out.println("not painting"); + /* + if (thread == null) { + initGraphics(); + start(); + } + */ + return; + } + + // without ignoring the first call, the first several frames + // are confused because paint() gets called in the midst of + // the initial nextFrame() call, so there are multiple + // updates fighting with one another. + + // g.image is synchronized so that draw/loop and paint don't + // try to fight over it. this was causing a randomized slowdown + // that would cut the frameRate into a third on macosx, + // and is probably related to the windows sluggishness bug too + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 5b enter paint sync"); + + //synchronized (g) { + //synchronized (glock) { + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 5c inside paint sync"); + //System.out.println("5b paint has sync"); + //Exception e = new Exception(); + //e.printStackTrace(); + + // moving this into PGraphics caused weird sluggishness on win2k + //g.mis.newPixels(pixels, g.cm, 0, width); // must call this + + // make sure the screen is visible and usable + // (also prevents over-drawing when using PGraphicsGL) + if ((g != null) && (g.image != null)) { + screen.drawImage(g.image, 0, 0, null); + } + //if (THREAD_DEBUG) println("notifying all"); + //notifyAll(); + //thread.notify(); + //System.out.println(" 6 exit paint"); + //} + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 6 exit paint"); + //updated = true; + } + + + synchronized public void handleDisplay() { + if (PApplet.THREAD_DEBUG) println(Thread.currentThread().getName() + + " formerly nextFrame()"); + if (looping || redraw) { + /* + if (frameCount == 0) { // needed here for the sync + //createGraphics(); + // set up a dummy graphics in case size() is never + // called inside setup + size(INITIAL_WIDTH, INITIAL_HEIGHT); + } + */ + + // g may be rebuilt inside here, so turning of the sync + //synchronized (g) { + // use a different sync object + //synchronized (glock) { + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 1a beginDraw"); + g.beginDraw(); + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 1b draw"); + + //boolean recorderNull = true; + //boolean recorderRawNull = true; + + if (frameCount == 0) { + try { + //System.out.println("attempting setup"); + //System.out.println("into try"); + setup(); + //g.defaults(); + + //System.out.println("done attempting setup"); + //System.out.println("out of try"); + //g.postSetup(); // FIXME + + } catch (RuntimeException e) { + //System.out.println("runtime extends " + e); + //System.out.println("catching a cold " + e.getMessage()); + String msg = e.getMessage(); + if ((msg != null) && + (e.getMessage().indexOf(NEW_RENDERER) != -1)) { + //System.out.println("got new renderer"); + return; + //continue; // will this work? + + } else { + //e.printStackTrace(System.out); + //System.out.println("re-throwing"); + throw e; + } + } + // if depth() is called inside setup, pixels/width/height + // will be ok by the time it's back out again + + //this.pixels = g.pixels; // make em call loadPixels + // now for certain that we've got a valid size + this.width = g.width; + this.height = g.height; + this.defaultSize = false; + + } else { // frameCount > 0, meaning an actual draw() + // update the current frameRate + if (frameRateLastMillis != 0) { + float elapsed = (float) + (System.currentTimeMillis() - frameRateLastMillis); + if (elapsed != 0) { + frameRate = + (frameRate * 0.9f) + ((1.0f / (elapsed / 1000.0f)) * 0.1f); + } + } + frameRateLastMillis = System.currentTimeMillis(); + + /* + if (frameRateTarget != 0) { + //System.out.println("delaying"); + if (frameRateLastDelayTime == 0) { + frameRateLastDelayTime = System.currentTimeMillis(); + + } else { + long timeToLeave = + frameRateLastDelayTime + (long)(1000.0f / frameRateTarget); + long now = System.currentTimeMillis(); + int napTime = (int) (timeToLeave - now); + if (napTime > 0) { + frameRateLastDelayTime = timeToLeave; + delay(napTime); + } else { + // nap time is negative, need to reset clock (bug #336) + frameRateLastDelayTime = now; + } + } + } + */ + + preMethods.handle(); + + pmouseX = dmouseX; + pmouseY = dmouseY; + + //synchronized (glock) { + //synchronized (this) { + //try { + draw(); + /* + // seems to catch, but then blanks out + } catch (Exception e) { + if (e instanceof InvocationTargetException) { + System.out.println("found poo"); + ((InvocationTargetException)e).getTargetException().printStackTrace(System.out); + } + } + */ + //} + //} + + // set a flag regarding whether the recorders were non-null + // as of draw().. this will prevent the recorder from being + // reset if recordShape() is called in an event method, such + // as mousePressed() + //recorderNull = (recorder == null); + //recorderRawNull = (g.recorderRaw == null); + + // dmouseX/Y is updated only once per frame + dmouseX = mouseX; + dmouseY = mouseY; + + // these are called *after* loop so that valid + // drawing commands can be run inside them. it can't + // be before, since a call to background() would wipe + // out anything that had been drawn so far. + dequeueMouseEvents(); + + dequeueKeyEvents(); + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 2b endDraw"); + + drawMethods.handle(); + //for (int i = 0; i < libraryCount; i++) { + //if (libraryCalls[i][PLibrary.DRAW]) libraries[i].draw(); + //} + + redraw = false; // unset 'redraw' flag in case it was set + // (only do this once draw() has run, not just setup()) + } + + g.endDraw(); + /* + if (!recorderNull) { + if (recorder != null) { + recorder.endDraw(); + recorder = null; + } + } + if (!recorderRawNull) { + if (g.recorderRaw != null) { + g.recorderRaw.endDraw(); + g.recorderRaw = null; + } + } + */ + + //} // older end sync + + //update(); + // formerly 'update' + //if (firstFrame) firstFrame = false; + // internal frame counter + frameCount++; + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 3a calling repaint() " + frameCount); + repaint(); + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 3b calling Toolkit.sync " + frameCount); + getToolkit().sync(); // force repaint now (proper method) + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " 3c done " + frameCount); + //if (THREAD_DEBUG) println(" 3d waiting"); + //wait(); + //if (THREAD_DEBUG) println(" 3d out of wait"); + //frameCount++; + + postMethods.handle(); + //for (int i = 0; i < libraryCount; i++) { + //if (libraryCalls[i][PLibrary.POST]) libraries[i].post(); + //} + //} // end of synchronize + } + } + + + ////////////////////////////////////////////////////////////// + + + public void run() { // not good to make this synchronized, locks things up + try { + while ((Thread.currentThread() == thread) && !finished) { + // render a single frame + g.requestDisplay(this); + + // wait for update & paint to happen before drawing next frame + // this is necessary since the drawing is sometimes in a + // separate thread, meaning that the next frame will start + // before the update/paint is completed + + try { + // Windows doesn't like Thread.yield(), acts as though it hasn't + // even been called and starves the CPU anyway. So have to sleep + // (or wait) at least for some small amount of time (below). + //Thread.yield(); + + // Can't remember when/why I changed the generic nap time to '1' + // (rather than 3 or 5, like back in the day), but I have a feeling + // that some platforms aren't gonna like that. + + // If !looping, sleeps for a nice long time, or until an + // interrupt or notify from a call to loop/noLoop/redraw + + int nap = (looping || finished) ? 1 : 10000; + + // don't nap after setup, because if noLoop() is called this + // will make the first draw wait 10 seconds before showing up + if (frameCount == 1) { + nap = 1; + + } else if (finished) { + nap = 0; + + } else if (looping) { + if (frameRateTarget != 0) { + if (frameRateLastDelayTime == 0) { + frameRateLastDelayTime = System.currentTimeMillis(); + + } else { + long timeToLeave = + frameRateLastDelayTime + (long)(1000.0f / frameRateTarget); + long now = System.currentTimeMillis(); + nap = (int) (timeToLeave - now); + if (nap > 0) { + frameRateLastDelayTime = timeToLeave; + //delay(napTime); + //nap = napTime; + + } else { + // nap time is negative, need to reset clock (bug #336) + frameRateLastDelayTime = now; + } + } + } else { + nap = 1; + } + } + + if (CRUSTY_THREADS) { + Thread.sleep(nap); + } else { + synchronized (blocker) { + if (nap > 0) blocker.wait(nap); + } + } + } catch (InterruptedException e) { } + } + + } catch (Exception e) { + // note that this will not catch errors inside setup() + // those are caught by the PdeRuntime + + //System.out.println("exception occurred (if you don't see a stack " + + // "trace below this message, we've got a bug)"); + finished = true; + if (e instanceof InvocationTargetException) { + //System.out.println("target problem"); + e = (Exception) (((InvocationTargetException) e).getTargetException()); + } + exception = e; + //e.printStackTrace(System.out); + + if (leechErr != null) { + // if draw() mode, make sure that ui stops waiting + // and the run button quits out + leechErr.println(LEECH_WAKEUP); + e.printStackTrace(leechErr); + e.printStackTrace(System.out); + + } else { + System.err.println(LEECH_WAKEUP); + e.printStackTrace(); + e.printStackTrace(System.out); + } + } + if (THREAD_DEBUG) println(Thread.currentThread().getName() + + " thread finished"); + + // this may not be safe? this will get triggered with exit() + // but need to see if this is it + //if ((leechErr == null) && !online) { + //System.exit(0); + //} + + //System.out.println("exiting run " + finished); + stop(); // call to shutdown libs? + + if (exit) { // user called exit() function + if ((leechErr == null) && !online) { + // don't want to call System.exit() when an applet, + // or running inside the PDE (would kill the PDE) + System.exit(0); + } + } + } + + + synchronized public void redraw() { + if (!looping) { + redraw = true; + if (thread != null) { + // wake from sleep (necessary otherwise it'll be + // up to 10 seconds before update) + if (CRUSTY_THREADS) { + thread.interrupt(); + } else { + synchronized (blocker) { + blocker.notifyAll(); + } + } + } + } + } + + + synchronized public void loop() { + if (!looping) { + looping = true; + if (thread != null) { + // wake from sleep (necessary otherwise it'll be + // up to 10 seconds before update) + if (CRUSTY_THREADS) { + thread.interrupt(); + } else { + synchronized (blocker) { + blocker.notifyAll(); + } + } + } + } + } + + + synchronized public void noLoop() { + if (looping) { + looping = false; + + // reset frameRate delay times + frameRateLastDelayTime = 0; + frameRateLastMillis = 0; + + if (thread != null) { + if (CRUSTY_THREADS) { + thread.interrupt(); // wake from sleep + } else { + synchronized (blocker) { + blocker.notifyAll(); + } + /* + try { + wait(); // until a notify + } catch (InterruptedException e) { } + */ + } + } + } + } + + + ////////////////////////////////////////////////////////////// + + + protected boolean listenersAdded; + + public void addListeners() { + if (!listenersAdded) { + addMouseListener(this); + addMouseMotionListener(this); + addKeyListener(this); + addFocusListener(this); + + addComponentListener(new ComponentAdapter() { + public void componentResized(ComponentEvent e) { + Component c = e.getComponent(); + Rectangle bounds = c.getBounds(); + //System.out.println("componentResized()"); + //System.out.println(" " + c.getClass().getName()); + //println(" visible " + isVisible()); + //System.out.println(" " + e); + //System.out.println(" bounds: " + bounds); + //int newWidth = bounds.width - bounds.x * 2; + //int newHeight = bounds.height - (bounds.y + bounds.x); + //System.out.println(" new: " + newWidth + " " + newHeight); + + size(bounds.width, bounds.height); + + //if (c == PApplet.this) { + //Container con = (Container) c; + //Dimension newSize = getSize(); + //System.out.println("resizing to " + newSize + " "); + //System.out.println(c.getBounds()); + //System.out.println(e); + //System.out.println(c); + //System.out.println("insets " + con.getInsets()); + //size(newSize.width, newSize.height); + //} + } + }); + + listenersAdded = true; + } + } + + + ////////////////////////////////////////////////////////////// + + + MouseEvent mouseEventQueue[] = new MouseEvent[10]; + int mouseEventCount; + + protected void enqueueMouseEvent(MouseEvent e) { + synchronized (mouseEventQueue) { + if (mouseEventCount == mouseEventQueue.length) { + MouseEvent temp[] = new MouseEvent[mouseEventCount << 1]; + System.arraycopy(mouseEventQueue, 0, temp, 0, mouseEventCount); + mouseEventQueue = temp; + } + mouseEventQueue[mouseEventCount++] = e; + } + } + + protected void dequeueMouseEvents() { + synchronized (mouseEventQueue) { + for (int i = 0; i < mouseEventCount; i++) { + mouseEvent = mouseEventQueue[i]; + handleMouseEvent(mouseEvent); + } + mouseEventCount = 0; + } + } + + + /** + * Actually take action based on a mouse event. + * Internally updates mouseX, mouseY, mousePressed, and mouseEvent. + * Then it calls the event type with no params, + * i.e. mousePressed() or mouseReleased() that the user may have + * overloaded to do something more useful. + */ + protected void handleMouseEvent(MouseEvent event) { + int id = event.getID(); + + // http://dev.processing.org/bugs/show_bug.cgi?id=170 + // also prevents mouseExited() on the mac from hosing the mouse + // position, because x/y are bizarre values on the exit event. + // see also the id check below.. both of these go together + if ((id == MouseEvent.MOUSE_DRAGGED) || + (id == MouseEvent.MOUSE_MOVED)) { + pmouseX = emouseX; + pmouseY = emouseY; + mouseX = event.getX(); + mouseY = event.getY(); + } + + mouseEvent = event; + + int modifiers = event.getModifiers(); + if ((modifiers & InputEvent.BUTTON1_MASK) != 0) { + mouseButton = LEFT; + } else if ((modifiers & InputEvent.BUTTON2_MASK) != 0) { + mouseButton = CENTER; + } else if ((modifiers & InputEvent.BUTTON3_MASK) != 0) { + mouseButton = RIGHT; + } + // if running on macos, allow ctrl-click as right mouse + if ((platform == MACOSX) || (platform == MACOS9)) { + if (mouseEvent.isPopupTrigger()) { + mouseButton = RIGHT; + } + } + + mouseEventMethods.handle(new Object[] { event }); + + // this used to only be called on mouseMoved and mouseDragged + // change it back if people run into trouble + if (firstMouse) { + pmouseX = mouseX; + pmouseY = mouseY; + dmouseX = mouseX; + dmouseY = mouseY; + firstMouse = false; + } + + //println(event); + + switch (id) { + case MouseEvent.MOUSE_PRESSED: + mousePressed = true; + mousePressed(); + break; + case MouseEvent.MOUSE_RELEASED: + mousePressed = false; + mouseReleased(); + break; + case MouseEvent.MOUSE_CLICKED: + mouseClicked(); + break; + case MouseEvent.MOUSE_DRAGGED: + mouseDragged(); + break; + case MouseEvent.MOUSE_MOVED: + mouseMoved(); + break; + } + + if ((id == MouseEvent.MOUSE_DRAGGED) || + (id == MouseEvent.MOUSE_MOVED)) { + emouseX = mouseX; + emouseY = mouseY; + } + } + + + /** + * Figure out how to process a mouse event. When loop() has been + * called, the events will be queued up until drawing is complete. + * If noLoop() has been called, then events will happen immediately. + */ + protected void checkMouseEvent(MouseEvent event) { + if (looping) { + enqueueMouseEvent(event); + } else { + handleMouseEvent(event); + } + } + + + /** + * If you override this or any function that takes a "MouseEvent e" + * without calling its super.mouseXxxx() then mouseX, mouseY, + * mousePressed, and mouseEvent will no longer be set. + */ + public void mousePressed(MouseEvent e) { + checkMouseEvent(e); + } + + public void mouseReleased(MouseEvent e) { + checkMouseEvent(e); + } + + public void mouseClicked(MouseEvent e) { + checkMouseEvent(e); + } + + public void mouseEntered(MouseEvent e) { + checkMouseEvent(e); + } + + public void mouseExited(MouseEvent e) { + checkMouseEvent(e); + } + + public void mouseDragged(MouseEvent e) { + checkMouseEvent(e); + } + + public void mouseMoved(MouseEvent e) { + checkMouseEvent(e); + } + + + /** + * Mouse has been pressed, and should be considered "down" + * until mouseReleased() is called. If you must, use + * int button = mouseEvent.getButton(); + * to figure out which button was clicked. It will be one of: + * MouseEvent.BUTTON1, MouseEvent.BUTTON2, MouseEvent.BUTTON3 + * Note, however, that this is completely inconsistent across + * platforms. + */ + public void mousePressed() { } + + /** + * Mouse button has been released. + */ + public void mouseReleased() { } + + /** + * When the mouse is clicked, mousePressed() will be called, + * then mouseReleased(), then mouseClicked(). Note that + * mousePressed is already false inside of mouseClicked(). + */ + public void mouseClicked() { } + + /** + * Mouse button is pressed and the mouse has been dragged. + */ + public void mouseDragged() { } + + /** + * Mouse button is not pressed but the mouse has changed locations. + */ + public void mouseMoved() { } + + + ////////////////////////////////////////////////////////////// + + + KeyEvent keyEventQueue[] = new KeyEvent[10]; + int keyEventCount; + + protected void enqueueKeyEvent(KeyEvent e) { + synchronized (keyEventQueue) { + if (keyEventCount == keyEventQueue.length) { + KeyEvent temp[] = new KeyEvent[keyEventCount << 1]; + System.arraycopy(keyEventQueue, 0, temp, 0, keyEventCount); + keyEventQueue = temp; + } + keyEventQueue[keyEventCount++] = e; + } + } + + protected void dequeueKeyEvents() { + synchronized (keyEventQueue) { + for (int i = 0; i < keyEventCount; i++) { + keyEvent = keyEventQueue[i]; + handleKeyEvent(keyEvent); + } + keyEventCount = 0; + } + } + + + protected void handleKeyEvent(KeyEvent event) { + keyEvent = event; + key = event.getKeyChar(); + keyCode = event.getKeyCode(); + + keyEventMethods.handle(new Object[] { event }); + /* + for (int i = 0; i < libraryCount; i++) { + if (libraryCalls[i][PLibrary.KEY]) { + libraries[i].key(event); // endNet/endSerial etc + } + } + */ + + switch (event.getID()) { + case KeyEvent.KEY_PRESSED: + keyPressed = true; + keyPressed(); + break; + case KeyEvent.KEY_RELEASED: + keyPressed = false; + keyReleased(); + break; + case KeyEvent.KEY_TYPED: + keyTyped(); + break; + } + + // if someone else wants to intercept the key, they should + // set key to zero (or something besides the ESC). + if ((event.getID() == KeyEvent.KEY_PRESSED) && + (key == KeyEvent.VK_ESCAPE)) { + exit(); + } + } + + + protected void checkKeyEvent(KeyEvent event) { + if (looping) { + enqueueKeyEvent(event); + } else { + handleKeyEvent(event); + } + } + + + /** + * Overriding keyXxxxx(KeyEvent e) functions will cause the 'key', + * 'keyCode', and 'keyEvent' variables to no longer work; + * key events will no longer be queued until the end of draw(); + * and the keyPressed(), keyReleased() and keyTyped() methods + * will no longer be called. + */ + public void keyPressed(KeyEvent e) { checkKeyEvent(e); } + public void keyReleased(KeyEvent e) { checkKeyEvent(e); } + public void keyTyped(KeyEvent e) { checkKeyEvent(e); } + + + /** + * Called each time a single key on the keyboard is pressed. + * Because of how operating systems handle key repeats, holding + * down a key will cause multiple calls to keyPressed(), because + * the OS repeat takes over. + *

    + * Examples for key handling: + * (Tested on Windows XP, please notify if different on other + * platforms, I have a feeling Mac OS and Linux may do otherwise) + *

    +   * 1. Pressing 'a' on the keyboard:
    +   *    keyPressed  with key == 'a' and keyCode == 'A'
    +   *    keyTyped    with key == 'a' and keyCode ==  0
    +   *    keyReleased with key == 'a' and keyCode == 'A'
    +   *
    +   * 2. Pressing 'A' on the keyboard:
    +   *    keyPressed  with key == 'A' and keyCode == 'A'
    +   *    keyTyped    with key == 'A' and keyCode ==  0
    +   *    keyReleased with key == 'A' and keyCode == 'A'
    +   *
    +   * 3. Pressing 'shift', then 'a' on the keyboard (caps lock is off):
    +   *    keyPressed  with key == CODED and keyCode == SHIFT
    +   *    keyPressed  with key == 'A'   and keyCode == 'A'
    +   *    keyTyped    with key == 'A'   and keyCode == 0
    +   *    keyReleased with key == 'A'   and keyCode == 'A'
    +   *    keyReleased with key == CODED and keyCode == SHIFT
    +   *
    +   * 4. Holding down the 'a' key.
    +   *    The following will happen several times,
    +   *    depending on your machine's "key repeat rate" settings:
    +   *    keyPressed  with key == 'a' and keyCode == 'A'
    +   *    keyTyped    with key == 'a' and keyCode ==  0
    +   *    When you finally let go, you'll get:
    +   *    keyReleased with key == 'a' and keyCode == 'A'
    +   *
    +   * 5. Pressing and releasing the 'shift' key
    +   *    keyPressed  with key == CODED and keyCode == SHIFT
    +   *    keyReleased with key == CODED and keyCode == SHIFT
    +   *    (note there is no keyTyped)
    +   *
    +   * 6. Pressing the tab key in an applet with Java 1.4 will
    +   *    normally do nothing, but PApplet dynamically shuts
    +   *    this behavior off if Java 1.4 is in use (tested 1.4.2_05 Windows).
    +   *    Java 1.1 (Microsoft VM) passes the TAB key through normally.
    +   *    Not tested on other platforms or for 1.3.
    +   * 
    + */ + public void keyPressed() { } + + + /** + * See keyPressed(). + */ + public void keyReleased() { } + + + /** + * Only called for "regular" keys like letters, + * see keyPressed() for full documentation. + */ + public void keyTyped() { } + + + ////////////////////////////////////////////////////////////// + + // i am focused man, and i'm not afraid of death. + // and i'm going all out. i circle the vultures in a van + // and i run the block. + + + public void focusGained() { } + + public void focusGained(FocusEvent e) { + focused = true; + focusGained(); + } + + + public void focusLost() { } + + public void focusLost(FocusEvent e) { + focused = false; + focusLost(); + } + + + ////////////////////////////////////////////////////////////// + + // getting the time + + + /** + * Get the number of milliseconds since the applet started. + *

    + * This is a function, rather than a variable, because it may + * change multiple times per frame. + */ + public int millis() { + return (int) (System.currentTimeMillis() - millisOffset); + } + + /** Seconds position of the current time. */ + static public int second() { + return Calendar.getInstance().get(Calendar.SECOND); + } + + /** Minutes position of the current time. */ + static public int minute() { + return Calendar.getInstance().get(Calendar.MINUTE); + } + + /** + * Hour position of the current time in international format (0-23). + *

    + * To convert this value to American time:
    + *

    int yankeeHour = (hour() % 12);
    +   * if (yankeeHour == 0) yankeeHour = 12;
    + */ + static public int hour() { + return Calendar.getInstance().get(Calendar.HOUR_OF_DAY); + } + + /** + * Get the current day of the month (1 through 31). + *

    + * If you're looking for the day of the week (M-F or whatever) + * or day of the year (1..365) then use java's Calendar.get() + */ + static public int day() { + return Calendar.getInstance().get(Calendar.DAY_OF_MONTH); + } + + /** + * Get the current month in range 1 through 12. + */ + static public int month() { + // months are number 0..11 so change to colloquial 1..12 + return Calendar.getInstance().get(Calendar.MONTH) + 1; + } + + /** + * Get the current year. + */ + static public int year() { + return Calendar.getInstance().get(Calendar.YEAR); + } + + + ////////////////////////////////////////////////////////////// + + // controlling time (playing god) + + + /** + * The delay() function causes the program to halt for a specified time. + * Delay times are specified in thousandths of a second. For example, + * running delay(3000) will stop the program for three seconds and + * delay(500) will stop the program for a half-second. Remember: the + * display window is updated only at the end of draw(), so putting more + * than one delay() inside draw() will simply add them together and the new + * frame will be drawn when the total delay is over. + *

    + * I'm not sure if this is even helpful anymore, as the screen isn't + * updated before or after the delay, meaning which means it just + * makes the app lock up temporarily. + */ + public void delay(int napTime) { + if (frameCount == 0) return; + if (napTime > 0) { + try { + if (CRUSTY_THREADS) { + Thread.sleep(napTime); + } else { + wait(napTime); + } + } catch (InterruptedException e) { } + } + } + + + /** + * Set a target frameRate. This will cause delay() to be called + * after each frame so that the sketch synchronizes to a particular speed. + * Note that this only sets the maximum frame rate, it cannot be used to + * make a slow sketch go faster. Sketches have no default frame rate + * setting, and will attempt to use maximum processor power to achieve + * maximum speed. + */ + public void frameRate(float newRateTarget) { + this.frameRateTarget = newRateTarget; + } + + + ////////////////////////////////////////////////////////////// + + + /** + * Get a param from the web page, or (eventually) + * from a properties file. + */ + public String param(String what) { + if (online) { + return getParameter(what); + + } else { + System.err.println("param() only works inside a web browser"); + } + return null; + } + + + /** + * Show status in the status bar of a web browser, or in the + * System.out console. Eventually this might show status in the + * p5 environment itself, rather than relying on the console. + */ + public void status(String what) { + if (online) { + showStatus(what); + + } else { + System.out.println(what); // something more interesting? + } + } + + + public void link(String here) { + link(here, null); + } + + + /** + * Link to an external page without all the muss. + *

    + * When run with an applet, uses the browser to open the url, + * for applications, attempts to launch a browser with the url. + *

    + * Works on Mac OS X and Windows. For Linux, use: + *

    open(new String[] { "firefox", url });
    + * or whatever you want as your browser, since Linux doesn't + * yet have a standard method for launching URLs. + */ + public void link(String url, String frameTitle) { + if (online) { + try { + if (frameTitle == null) { + getAppletContext().showDocument(new URL(url)); + } else { + getAppletContext().showDocument(new URL(url), frameTitle); + } + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Could not open " + url); + } + } else { + try { + if (platform == WINDOWS) { + // the following uses a shell execute to launch the .html file + // note that under cygwin, the .html files have to be chmodded +x + // after they're unpacked from the zip file. i don't know why, + // and don't understand what this does in terms of windows + // permissions. without the chmod, the command prompt says + // "Access is denied" in both cygwin and the "dos" prompt. + //Runtime.getRuntime().exec("cmd /c " + currentDir + "\\reference\\" + + // referenceFile + ".html"); + + // replace ampersands with control sequence for DOS. + // solution contributed by toxi on the bugs board. + url = url.replaceAll("&","^&"); + + // open dos prompt, give it 'start' command, which will + // open the url properly. start by itself won't work since + // it appears to need cmd + Runtime.getRuntime().exec("cmd /c start " + url); + + } else if ((platform == MACOSX) || (platform == MACOS9)) { + //com.apple.mrj.MRJFileUtils.openURL(url); + try { + Class mrjFileUtils = Class.forName("com.apple.mrj.MRJFileUtils"); + Method openMethod = + mrjFileUtils.getMethod("openURL", new Class[] { String.class }); + openMethod.invoke(null, new Object[] { url }); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + //throw new RuntimeException("Can't open URLs for this platform"); + // Just pass it off to open() and hope for the best + open(url); + } + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Could not open " + url); + } + } + } + + + /** + * Attempt to open a file using the platform's shell. + */ + public void open(String filename) { + open(new String[] { filename }); + } + + + static String openLauncher; + + /** + * Launch a process using a platforms shell. This version uses an array + * to make it easier to deal with spaces in the individual elements. + * (This avoids the situation of trying to put single or double quotes + * around different bits). + */ + static public Process open(String argv[]) { + String[] params = null; + + if (platform == WINDOWS) { + // just launching the .html file via the shell works + // but make sure to chmod +x the .html files first + // also place quotes around it in case there's a space + // in the user.dir part of the url + params = new String[] { "cmd", "/c" }; + + } else if (platform == MACOSX) { + params = new String[] { "open" }; + + } else if (platform == LINUX) { + if (openLauncher == null) { + // Attempt to use gnome-open + try { + Process p = Runtime.getRuntime().exec(new String[] { "gnome-open" }); + /*int result =*/ p.waitFor(); + // Not installed will throw an IOException (JDK 1.4.2, Ubuntu 7.04) + openLauncher = "gnome-open"; + } catch (Exception e) { } + } + if (openLauncher == null) { + // Attempt with kde-open + try { + Process p = Runtime.getRuntime().exec(new String[] { "kde-open" }); + /*int result =*/ p.waitFor(); + openLauncher = "kde-open"; + } catch (Exception e) { } + } + if (openLauncher == null) { + System.err.println("Could not find gnome-open or kde-open, " + + "the open() command may not work."); + } + if (openLauncher != null) { + params = new String[] { openLauncher }; + } + //} else { // give up and just pass it to Runtime.exec() + //open(new String[] { filename }); + //params = new String[] { filename }; + } + if (params != null) { + // If the 'open', 'gnome-open' or 'cmd' are already included + if (params[0].equals(argv[0])) { + // then don't prepend those params again + return exec(argv); + } else { + params = concat(params, argv); + return exec(params); + } + } else { + return exec(argv); + } + } + + + static public Process exec(String[] argv) { + try { + return Runtime.getRuntime().exec(argv); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Could not open " + join(argv, ' ')); + } + } + + /* + try { + Runtime.getRuntime().exec("cmd /c \"" + filename + "\""); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Could not open " + filename); + } + + try { + return Runtime.getRuntime().exec(argv); + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Could not open " + join(argv, ' ')); + } + } + + /* + static protected String findLinuxLauncher() { + if (linuxLauncher == null) { + // Attempt to use gnome-open + try { + Process p = Runtime.getRuntime().exec(new String[] { "gnome-open" }); + int result = p.waitFor(); + // Not installed will throw an IOException (JDK 1.4.2, Ubuntu 7.04) + linuxLauncher = "gnome-open"; + } catch (Exception e) { } + + // Attempt with kde-open + try { + Process p = Runtime.getRuntime().exec(new String[] { "kde-open" }); + int result = p.waitFor(); + linuxLauncher = "kde-open"; + } catch (Exception e) { } + } + if (linuxLauncher == null) { + System.err.println("Could not find gnome-open or kde-open, " + + "the open() command may not work."); + } + return linuxLauncher; + } + */ + + + ////////////////////////////////////////////////////////////// + + + /** + * Function for an applet/application to kill itself and + * display an error. Mostly this is here to be improved later. + */ + public void die(String what) { + stop(); + throw new RuntimeException(what); + /* + if (online) { + System.err.println("i'm dead.. " + what); + + } else { + System.err.println(what); + System.exit(1); + } + */ + } + + + /** + * Same as above but with an exception. Also needs work. + */ + public void die(String what, Exception e) { + if (e != null) e.printStackTrace(); + die(what); + } + + + /** + * Call to safely exit the sketch when finished. For instance, + * to render a single frame, save it, and quit. + */ + public void exit() { + if (thread == null) { + // exit immediately, stop() has already been called, + // meaning that the main thread has long since exited + if ((leechErr == null) && !online) { + // don't want to call System.exit() when an applet, + // or running inside the PDE (would kill the PDE) + System.exit(0); + } + } else { + finished = true; // stop() will be called as the thread exits + //stop(); + exit = true; + } + } + + + ////////////////////////////////////////////////////////////// + + // SCREEN GRABASS + + + /** + * Intercepts any relative paths to make them absolute (relative + * to the sketch folder) before passing to save() in PImage. + * (Changed in 0100) + */ + public void save(String filename) { + g.save(savePath(filename)); + } + + + /** + * Grab an image of what's currently in the drawing area and save it + * as a .tif or .tga file. + *

    + * Best used just before endDraw() at the end of your draw(). + * This can only create .tif or .tga images, so if neither extension + * is specified it defaults to writing a tiff and adds a .tif suffix. + */ + public void saveFrame() { + if (online) { + System.err.println("Can't use saveFrame() when running in a browser."); + return; + } + + //File file = new File(folder, "screen-" + nf(frame, 4) + ".tif"); + //save(savePath("screen-" + nf(frameCount, 4) + ".tif")); + //save("screen-" + nf(frame, 4) + ".tif"); + g.save(savePath("screen-" + nf(frameCount, 4) + ".tif")); + } + + + /** + * Save the current frame as a .tif or .tga image. + *

    + * The String passed in can contain a series of # signs + * that will be replaced with the screengrab number. + *

    +   * i.e. saveFrame("blah-####.tif");
    +   *      // saves a numbered tiff image, replacing the
    +   *      // #### signs with zeros and the frame number 
    + */ + public void saveFrame(String what) { + if (online) { + System.err.println("Can't use saveFrame() when running in a browser."); + return; + } + + g.save(savePath(insertFrame(what))); + /* + int first = what.indexOf('#'); + int last = what.lastIndexOf('#'); + + if (first == -1) { + g.save(savePath(what)); + + } else { + String prefix = what.substring(0, first); + int count = last - first + 1; + String suffix = what.substring(last + 1); + g.save(savePath(prefix + nf(frameCount, count) + suffix)); + } + */ + } + + + + ////////////////////////////////////////////////////////////// + + // CURSOR + + // + + + int cursorType = ARROW; // cursor type + boolean cursorVisible = true; // cursor visibility flag + PImage invisibleCursor; + + + /** + * Set the cursor type + */ + public void cursor(int _cursor_type) { + setCursor(Cursor.getPredefinedCursor(_cursor_type)); + cursorVisible = true; + cursorType = _cursor_type; + } + + + /** + * Replace the cursor with the specified PImage. The x- and y- + * coordinate of the center will be the center of the image. + */ + public void cursor(PImage image) { + cursor(image, image.width/2, image.height/2); + } + + + /** + * Set a custom cursor to an image with a specific hotspot. + * Only works with JDK 1.2 and later. + * Currently seems to be broken on Java 1.4 for Mac OS X + *

    + * Based on code contributed by Amit Pitaru, plus additional + * code to handle Java versions via reflection by Jonathan Feinberg. + */ + public void cursor(PImage image, int hotspotX, int hotspotY) { + if (javaVersion < 1.2f) { + System.err.println("Java 1.2 or higher is required to use cursor()"); + System.err.println("(You're using version " + javaVersionName + ")"); + return; + } + + // don't set this as cursor type, instead use cursor_type + // to save the last cursor used in case cursor() is called + //cursor_type = Cursor.CUSTOM_CURSOR; + Image jimage = + createImage(new MemoryImageSource(image.width, image.height, + image.pixels, 0, image.width)); + + Point hotspot = new Point(hotspotX, hotspotY); + try { + Method mCustomCursor = + Toolkit.class.getMethod("createCustomCursor", + new Class[] { Image.class, + Point.class, + String.class, }); + Cursor cursor = + (Cursor)mCustomCursor.invoke(Toolkit.getDefaultToolkit(), + new Object[] { jimage, + hotspot, + "no cursor" }); + setCursor(cursor); + cursorVisible = true; + + } catch (NoSuchMethodError e) { + System.err.println("cursor() is not available " + + "when using Java " + javaVersionName); + } catch (IndexOutOfBoundsException e) { + System.err.println("cursor() error: the hotspot " + hotspot + + " is out of bounds for the given image."); + } catch (Exception e) { + System.err.println(e); + } + } + + + /** + * Show the cursor after noCursor() was called. + * Notice that the program remembers the last set cursor type + */ + public void cursor() { + // maybe should always set here? seems dangerous, since + // it's likely that java will set the cursor to something + // else on its own, and the applet will be stuck b/c bagel + // thinks that the cursor is set to one particular thing + if (!cursorVisible) { + cursorVisible = true; + setCursor(Cursor.getPredefinedCursor(cursorType)); + } + } + + + /** + * Hide the cursor by creating a transparent image + * and using it as a custom cursor. + */ + public void noCursor() { + if (!cursorVisible) return; // don't hide if already hidden. + + if (invisibleCursor == null) { + invisibleCursor = new PImage(16, 16, ARGB); + } + // was formerly 16x16, but the 0x0 was added by jdf as a fix + // for macosx, which didn't wasn't honoring the invisible cursor + cursor(invisibleCursor, 0, 0); + cursorVisible = false; + } + + + ////////////////////////////////////////////////////////////// + + + static public void print(byte what) { + System.out.print(what); + System.out.flush(); + } + + static public void print(boolean what) { + System.out.print(what); + System.out.flush(); + } + + static public void print(char what) { + System.out.print(what); + System.out.flush(); + } + + static public void print(int what) { + System.out.print(what); + System.out.flush(); + } + + static public void print(float what) { + System.out.print(what); + System.out.flush(); + } + + /* + static public void print(double what) { + System.out.print(what); + System.out.flush(); + } + */ + + static public void print(String what) { + System.out.print(what); + System.out.flush(); + } + + static public void print(Object what) { + if (what == null) { + // special case since this does fuggly things on > 1.1 + System.out.print("null"); + } else { + System.out.println(what.toString()); + } + + /* + String name = what.getClass().getName(); + if (name.charAt(0) == '[') { + switch (name.charAt(1)) { + case '[': + // don't even mess with multi-dimensional arrays (case '[') + // or anything else that's not int, float, boolean, char + System.out.print(what); + System.out.print(' '); + break; + + case 'L': + // print a 1D array of objects as individual elements + Object poo[] = (Object[]) what; + for (int i = 0; i < poo.length; i++) { + System.out.print(poo[i]); + System.out.print(' '); + } + break; + + case 'Z': // boolean + boolean zz[] = (boolean[]) what; + for (int i = 0; i < zz.length; i++) { + System.out.print(zz[i]); + System.out.print(' '); + } + break; + + case 'B': // byte + byte bb[] = (byte[]) what; + for (int i = 0; i < bb.length; i++) { + System.out.print(bb[i]); + System.out.print(' '); + } + break; + + case 'C': // char + char cc[] = (char[]) what; + for (int i = 0; i < cc.length; i++) { + System.out.print(cc[i]); + System.out.print(' '); + } + break; + + case 'I': // int + int ii[] = (int[]) what; + for (int i = 0; i < ii.length; i++) { + System.out.print(ii[i]); + System.out.print(' '); + } + break; + + case 'F': // float + float ff[] = (float[]) what; + for (int i = 0; i < ff.length; i++) { + System.out.print(ff[i]); + System.out.print(' '); + } + break; + + case 'D': // double + double dd[] = (double[]) what; + for (int i = 0; i < dd.length; i++) { + System.out.print(dd[i]); + System.out.print(' '); + } + break; + + default: + System.out.print(what); + } + } else { + System.out.print(what); //.toString()); + } + */ + } + + // + + static public void println() { + System.out.println(); + } + + // + + static public void println(byte what) { + print(what); System.out.println(); + } + + static public void println(boolean what) { + print(what); System.out.println(); + } + + static public void println(char what) { + print(what); System.out.println(); + } + + static public void println(int what) { + print(what); System.out.println(); + } + + static public void println(float what) { + print(what); System.out.println(); + } + + /* + static public void println(double what) { + print(what); System.out.println(); + } + */ + + static public void println(String what) { + print(what); System.out.println(); + } + + static public void println(Object what) { + if (what == null) { + // special case since this does fuggly things on > 1.1 + System.out.println("null"); + + } else { + String name = what.getClass().getName(); + if (name.charAt(0) == '[') { + switch (name.charAt(1)) { + case '[': + // don't even mess with multi-dimensional arrays (case '[') + // or anything else that's not int, float, boolean, char + System.out.println(what); + break; + + case 'L': + // print a 1D array of objects as individual elements + Object poo[] = (Object[]) what; + for (int i = 0; i < poo.length; i++) { + if (poo[i] instanceof String) { + System.out.println("[" + i + "] \"" + poo[i] + "\""); + } else { + System.out.println("[" + i + "] " + poo[i]); + } + } + break; + + case 'Z': // boolean + boolean zz[] = (boolean[]) what; + for (int i = 0; i < zz.length; i++) { + System.out.println("[" + i + "] " + zz[i]); + } + break; + + case 'B': // byte + byte bb[] = (byte[]) what; + for (int i = 0; i < bb.length; i++) { + System.out.println("[" + i + "] " + bb[i]); + } + break; + + case 'C': // char + char cc[] = (char[]) what; + for (int i = 0; i < cc.length; i++) { + System.out.println("[" + i + "] '" + cc[i] + "'"); + } + break; + + case 'I': // int + int ii[] = (int[]) what; + for (int i = 0; i < ii.length; i++) { + System.out.println("[" + i + "] " + ii[i]); + } + break; + + case 'F': // float + float ff[] = (float[]) what; + for (int i = 0; i < ff.length; i++) { + System.out.println("[" + i + "] " + ff[i]); + } + break; + + /* + case 'D': // double + double dd[] = (double[]) what; + for (int i = 0; i < dd.length; i++) { + System.out.println("[" + i + "] " + dd[i]); + } + break; + */ + + default: + System.out.println(what); + } + } else { // not an array + System.out.println(what); + } + } + } + + // + + /* + // not very useful, because it only works for public (and protected?) + // fields of a class, not local variables to methods + public void printvar(String name) { + try { + Field field = getClass().getDeclaredField(name); + println(name + " = " + field.get(this)); + } catch (Exception e) { + e.printStackTrace(); + } + } + */ + + + ////////////////////////////////////////////////////////////// + + // MATH + + // lots of convenience methods for math with floats. + // doubles are overkill for processing applets, and casting + // things all the time is annoying, thus the functions below. + + + static public final float abs(float n) { + return (n < 0) ? -n : n; + } + + static public final int abs(int n) { + return (n < 0) ? -n : n; + } + + static public final float sq(float a) { + return a*a; + } + + static public final float sqrt(float a) { + return (float)Math.sqrt(a); + } + + static public final float log(float a) { + return (float)Math.log(a); + } + + static public final float exp(float a) { + return (float)Math.exp(a); + } + + static public final float pow(float a, float b) { + return (float)Math.pow(a, b); + } + + + static public final int max(int a, int b) { + return (a > b) ? a : b; + } + + static public final float max(float a, float b) { + return (a > b) ? a : b; + } + + + static public final int max(int a, int b, int c) { + return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c); + } + + static public final float max(float a, float b, float c) { + return (a > b) ? ((a > c) ? a : c) : ((b > c) ? b : c); + } + + + /** + * Find the maximum value in an array. + * @param list the source array + * @return The maximum value, or 0 if the array is length zero. + */ + static public final int max(int[] list) { + if (list.length == 0) { + return 0; + } + int max = list[0]; + for (int i = 1; i < list.length; i++) { + if (list[i] > max) max = list[i]; + } + return max; + } + + /** + * Find the maximum value in an array. + * @param list the source array + * @return The maximum value, or Float.NaN if the array is length zero. + */ + static public final float max(float[] list) { + if (list.length == 0) { + return Float.NaN; + } + float max = list[0]; + for (int i = 1; i < list.length; i++) { + if (list[i] > max) max = list[i]; + } + return max; + } + + + static public final int min(int a, int b) { + return (a < b) ? a : b; + } + + static public final float min(float a, float b) { + return (a < b) ? a : b; + } + + + static public final int min(int a, int b, int c) { + return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c); + } + + static public final float min(float a, float b, float c) { + return (a < b) ? ((a < c) ? a : c) : ((b < c) ? b : c); + } + + + /** + * Find the minimum value in an array. + * @param list the source array + * @return The minimum value, or 0 if the array is length zero. + */ + static public final int min(int[] list) { + if (list.length == 0) { + return 0; + } + int min = list[0]; + for (int i = 1; i < list.length; i++) { + if (list[i] < min) min = list[i]; + } + return min; + } + /** + * Find the minimum value in an array. + * @param list the source array + * @return The minimum value, or Float.NaN if the array is length zero. + */ + static public final float min(float[] list) { + if (list.length == 0) { + return Float.NaN; + } + float min = list[0]; + for (int i = 1; i < list.length; i++) { + if (list[i] < min) min = list[i]; + } + return min; + } + + + static public final int constrain(int amt, int low, int high) { + return (amt < low) ? low : ((amt > high) ? high : amt); + } + + static public final float constrain(float amt, float low, float high) { + return (amt < low) ? low : ((amt > high) ? high : amt); + } + + + static public final float sin(float angle) { + return (float)Math.sin(angle); + } + + static public final float cos(float angle) { + return (float)Math.cos(angle); + } + + static public final float tan(float angle) { + return (float)Math.tan(angle); + } + + + static public final float asin(float value) { + return (float)Math.asin(value); + } + + static public final float acos(float value) { + return (float)Math.acos(value); + } + + static public final float atan(float value) { + return (float)Math.atan(value); + } + + static public final float atan2(float a, float b) { + return (float)Math.atan2(a, b); + } + + + static public final float degrees(float radians) { + return radians * RAD_TO_DEG; + } + + static public final float radians(float degrees) { + return degrees * DEG_TO_RAD; + } + + + static public final int ceil(float what) { + return (int) Math.ceil(what); + } + + static public final int floor(float what) { + return (int) Math.floor(what); + } + + static public final int round(float what) { + return (int) Math.round(what); + } + + + static public final float mag(float a, float b) { + return (float)Math.sqrt(a*a + b*b); + } + + static public final float mag(float a, float b, float c) { + return (float)Math.sqrt(a*a + b*b + c*c); + } + + + static public final float dist(float x1, float y1, float x2, float y2) { + return sqrt(sq(x2-x1) + sq(y2-y1)); + } + + static public final float dist(float x1, float y1, float z1, + float x2, float y2, float z2) { + return sqrt(sq(x2-x1) + sq(y2-y1) + sq(z2-z1)); + } + + + static public final float lerp(float start, float stop, float amt) { + return start + (stop-start) * amt; + } + + /** + * Normalize a value to exist between 0 and 1 (inclusive). + * Mathematically the opposite of lerp(), figures out what proportion + * a particular value is relative to start and stop coordinates. + */ + static public final float norm(float value, float start, float stop) { + return (value - start) / (stop - start); + } + + /** + * Convenience function to map a variable from one coordinate space + * to another. Equivalent to unlerp() followed by lerp(). + */ + static public final float map(float value, + float istart, float istop, + float ostart, float ostop) { + return ostart + (ostop - ostart) * ((value - istart) / (istop - istart)); + } + + + + ////////////////////////////////////////////////////////////// + + // RANDOM NUMBERS + + + Random internalRandom; + + /** + * Return a random number in the range [0, howbig). + *

    + * The number returned will range from zero up to + * (but not including) 'howbig'. + */ + public final float random(float howbig) { + // for some reason (rounding error?) Math.random() * 3 + // can sometimes return '3' (once in ~30 million tries) + // so a check was added to avoid the inclusion of 'howbig' + + // avoid an infinite loop + if (howbig == 0) return 0; + + // internal random number object + if (internalRandom == null) internalRandom = new Random(); + + float value = 0; + do { + //value = (float)Math.random() * howbig; + value = internalRandom.nextFloat() * howbig; + } while (value == howbig); + return value; + } + + + /** + * Return a random number in the range [howsmall, howbig). + *

    + * The number returned will range from 'howsmall' up to + * (but not including 'howbig'. + *

    + * If howsmall is >= howbig, howsmall will be returned, + * meaning that random(5, 5) will return 5 (useful) + * and random(7, 4) will return 7 (not useful.. better idea?) + */ + public final float random(float howsmall, float howbig) { + if (howsmall >= howbig) return howsmall; + float diff = howbig - howsmall; + return random(diff) + howsmall; + } + + + public final void randomSeed(long what) { + // internal random number object + if (internalRandom == null) internalRandom = new Random(); + internalRandom.setSeed(what); + } + + + + ////////////////////////////////////////////////////////////// + + // PERLIN NOISE + + // [toxi 040903] + // octaves and amplitude amount per octave are now user controlled + // via the noiseDetail() function. + + // [toxi 030902] + // cleaned up code and now using bagel's cosine table to speed up + + // [toxi 030901] + // implementation by the german demo group farbrausch + // as used in their demo "art": http://www.farb-rausch.de/fr010src.zip + + static final int PERLIN_YWRAPB = 4; + static final int PERLIN_YWRAP = 1<>= 1; + } + + if (x<0) x=-x; + if (y<0) y=-y; + if (z<0) z=-z; + + int xi=(int)x, yi=(int)y, zi=(int)z; + float xf = (float)(x-xi); + float yf = (float)(y-yi); + float zf = (float)(z-zi); + float rxf, ryf; + + float r=0; + float ampl=0.5f; + + float n1,n2,n3; + + for (int i=0; i=1.0f) { xi++; xf--; } + if (yf>=1.0f) { yi++; yf--; } + if (zf>=1.0f) { zi++; zf--; } + } + return r; + } + + // [toxi 031112] + // now adjusts to the size of the cosLUT used via + // the new variables, defined above + private float noise_fsc(float i) { + // using bagel's cosine table instead + return 0.5f*(1.0f-perlin_cosTable[(int)(i*perlin_PI)%perlin_TWOPI]); + } + + // [toxi 040903] + // make perlin noise quality user controlled to allow + // for different levels of detail. lower values will produce + // smoother results as higher octaves are surpressed + + public void noiseDetail(int lod) { + if (lod>0) perlin_octaves=lod; + } + + public void noiseDetail(int lod, float falloff) { + if (lod>0) perlin_octaves=lod; + if (falloff>0) perlin_amp_falloff=falloff; + } + + public void noiseSeed(long what) { + if (perlinRandom == null) perlinRandom = new Random(); + perlinRandom.setSeed(what); + // force table reset after changing the random number seed [0122] + perlin = null; + } + + + + ////////////////////////////////////////////////////////////// + + // SOUND I/O + + /* + public PSound loadSound(String filename) { + if (PApplet.javaVersion >= 1.3f) { + return new PSound2(this, openStream(filename)); + } + return new PSound(this, openStream(filename)); + } + */ + + + ////////////////////////////////////////////////////////////// + + // IMAGE I/O + + + /* + Hashtable imageTable; + */ + + /** + * Draw an image based on its filename. This is less efficient than + * using loadImage because there's no way to unload it from memory, + * but it's useful for beginners. + */ + /* + public void image(String filename, float x, float y) { + image(tableImage(filename), x, y); + } + */ + + /** + * Draw an image based on its filename. This is less than efficient + * than using loadImage because there's no way to unload it from memory, + * but it's useful for beginners. + */ + /* + public void image(String filename, + float x, float y, float c, float d) { + image(tableImage(filename), x, y, c, d); + } + */ + + /** + * Draw an image based on its filename. This is less than efficient + * than using loadImage because there's no way to unload it from memory, + * but it's useful for beginners. + */ + /* + public void image(String filename, + float a, float b, float c, float d, + int u1, int v1, int u2, int v2) { + image(tableImage(filename), a, b, c, d, u1, v1, u2, v2); + } + */ + + + /** + * Load an image and store it in a table based on its name. + */ + /* + protected PImage tableImage(String filename) { + if (imageTable == null) imageTable = new Hashtable(); + + PImage image = (PImage) imageTable.get(filename); + if (image != null) return image; + + image = loadImage(filename); + return image; + } + */ + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + protected String[] loadImageFormats; + + + /** + * Load an image from the data folder or a local directory. + * Supports .gif (including transparency), .tga, and .jpg images. + * In Java 1.3 or later, .png images are + * + * also supported. + *

    + * Generally, loadImage() should only be used during setup, because + * re-loading images inside draw() is likely to cause a significant + * delay while memory is allocated and the thread blocks while waiting + * for the image to load because loading is not asynchronous. + *

    + * To load several images asynchronously, see more information in the + * FAQ about writing your own threaded image loading method. + *

    + * As of 0096, returns null if no image of that name is found, + * rather than an error. + *

    + * Release 0115 also provides support for reading TIFF and RLE-encoded + * Targa (.tga) files written by Processing via save() and saveFrame(). + * Other TIFF and Targa files will probably not load, use a different + * format (gif, jpg and png are safest bets) when creating images with + * another application to use with Processing. + *

    + * Also in release 0115, more image formats (BMP and others) can + * be read when using Java 1.4 and later. Because many people still + * use Java 1.1 and 1.3, these formats are not recommended for + * work that will be posted on the web. To get a list of possible + * image formats for use with Java 1.4 and later, use the following: + * println(javax.imageio.ImageIO.getReaderFormatNames()) + *

    + * Images are loaded via a byte array that is passed to + * Toolkit.createImage(). Unfortunately, we cannot use Applet.getImage() + * because it takes a URL argument, which would be a pain in the a-- + * to make work consistently for online and local sketches. + * Sometimes this causes problems, resulting in issues like + * Bug 279 + * and + * Bug 305. + * In release 0115, everything was instead run through javax.imageio, + * but that turned out to be very slow, see + * Bug 392. + * As a result, starting with 0116, the following happens: + *

      + *
    • TGA and TIFF images are loaded using the internal load methods. + *
    • JPG, GIF, and PNG images are loaded via loadBytes(). + *
    • If the image still isn't loaded, it's passed to javax.imageio. + *
    + * For releases 0116 and later, if you have problems such as those seen + * in Bugs 279 and 305, use Applet.getImage() instead. You'll be stuck + * with the limitations of getImage() (the headache of dealing with + * online/offline use). Set up your own MediaTracker, and pass the resulting + * java.awt.Image to the PImage constructor that takes an AWT image. + * You can also use the loadImageSync() function (added in 0116) that + * takes an AWT image and loads it synchronously inside PApplet. + *
    +   * public PImage loadImageAlt(String filename) {
    +   *   java.awt.Image img = getImage(getCodeBase(), filename);
    +   *   return loadImageSync(img);
    +   * }
    +   * 
    + * This isn't much fun, but this will have to do unless we find the + * actual culprit, which may still be a threading issue. + */ + public PImage loadImage(String filename) { + String lower = filename.toLowerCase(); + int dot = filename.lastIndexOf('.'); + if (dot == -1) { + // no extension found + return loadImage(filename, "unknown"); + } + String extension = lower.substring(dot + 1); + + // check for, and strip any parameters on the url, i.e. + // filename.jpg?blah=blah&something=that + int question = extension.indexOf('?'); + if (question != -1) { + extension = extension.substring(0, question); + } + + return loadImage(filename, extension); + } + + + /** + * Identical to loadImage, but allows you to specify the type of + * image by its extension. Especially useful when downloading from + * CGI scripts. + *

    + * Use 'unknown' as the extension to pass off to the default + * image loader that handles gif, jpg, and png. + */ + public PImage loadImage(String filename, String extension) { + // just in case. them users will try anything! + extension = extension.toLowerCase(); + + if (extension.equals("tga")) { + try { + return loadImageTGA(filename); + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } + + //if (lower.endsWith(".tif") || lower.endsWith(".tiff")) { + if (extension.equals("tif") || extension.equals("tiff")) { + byte bytes[] = loadBytes(filename); + return (bytes == null) ? null : PImage.loadTIFF(bytes); + } + + // Make sure that PNG images aren't being loaded by Java 1.1 + //if (lower.endsWith(".png") && PApplet.javaVersion < 1.3f) { + if (extension.equals("png") && PApplet.javaVersion < 1.3f) { + System.err.println("PNG images can only be loaded when " + + "using Java 1.3 and later."); + return null; + } + + // For jpeg, gif, and png, load them using createImage(), + // because the javax.imageio code was found to be much slower, see + // Bug 392. + try { + //if (lower.endsWith(".jpg") || lower.endsWith(".jpeg") || + // lower.endsWith(".gif") || lower.endsWith(".png")) { + if (extension.equals("jpg") || extension.equals("jpeg") || + extension.equals("gif") || extension.equals("png") || + extension.equals("unknown")) { + byte bytes[] = loadBytes(filename); + if (bytes == null) { + return null; + } else { + Image awtImage = Toolkit.getDefaultToolkit().createImage(bytes); + PImage image = loadImageSync(awtImage); + // if it's a .gif image, test to see if it has transparency + //if ((lower.endsWith(".gif")) || (lower.endsWith(".png"))) { + if (extension.equals("gif") || extension.equals("png")) { + image.checkAlpha(); + } + return image; + } + } + } catch (Exception e) { + // show error, but move on to the stuff below, see if it'll work + e.printStackTrace(); + } + + if (PApplet.javaVersion >= 1.4f) { + if (loadImageFormats == null) { + //loadImageFormats = javax.imageio.ImageIO.getReaderFormatNames(); + try { + Class ioClass = Class.forName("javax.imageio.ImageIO"); + Method getFormatNamesMethod = + ioClass.getMethod("getReaderFormatNames", (Class[]) null); + loadImageFormats = (String[]) + getFormatNamesMethod.invoke((Class[]) null, (Object[]) null); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (loadImageFormats != null) { + for (int i = 0; i < loadImageFormats.length; i++) { + //if (filename.endsWith("." + loadImageFormats[i])) { + if (extension.equals(loadImageFormats[i])) { + return loadImageIO(filename); + } + } + } + } + + // failed, could not load image after all those attempts + System.err.println("Could not find a method to load " + filename); + return null; + } + + + /** + * Load an AWT image synchronously. + */ + public PImage loadImageSync(Image awtImage) { + MediaTracker tracker = new MediaTracker(this); + tracker.addImage(awtImage, 0); + try { + tracker.waitForAll(); + } catch (InterruptedException e) { + //e.printStackTrace(); // non-fatal, right? + } + + PImage image = new PImage(awtImage); + image.parent = this; + return image; + } + + + /** + * Use Java 1.4 ImageIO methods to load an image. All done via reflection + * in order to maintain compatability with previous releases. + */ + protected PImage loadImageIO(String filename) { + InputStream stream = openStream(filename); + if (stream == null) { + System.err.println("The image " + filename + " could not be found."); + return null; + } + + try { + Class ioClass = Class.forName("javax.imageio.ImageIO"); + Method readMethod = + ioClass.getMethod("read", new Class[] { InputStream.class }); + Object bimage = readMethod.invoke(null, new Object[] { stream }); + + // need to get width and height, then create pixels[] at that size + //int px[] = null; + + Class biClass = + Class.forName("java.awt.image.BufferedImage"); + + Method getHeightMethod = + biClass.getMethod("getHeight", (Class[]) null); + Integer hi = (Integer) getHeightMethod.invoke(bimage, (Object[]) null); + + Method getWidthMethod = + biClass.getMethod("getWidth", (Class[]) null); + Integer wi = (Integer) getWidthMethod.invoke(bimage, (Object[]) null); + + // was gonna call getType() on the image to see if RGB or ARGB, + // but it's not actually useful, since gif images will come through + // as TYPE_BYTE_INDEXED, which means it'll still have to check for + // the transparency. also, would have to iterate through all the other + // types and guess whether alpha was in there, so.. just gonna stick + // with the old method. + + PImage outgoing = new PImage(wi.intValue(), hi.intValue()); + outgoing.parent = this; + + Method getRgbMethod = + biClass.getMethod("getRGB", new Class[] { + Integer.TYPE, Integer.TYPE, Integer.TYPE, Integer.TYPE, + outgoing.pixels.getClass(), Integer.TYPE, Integer.TYPE + }); + getRgbMethod.invoke(bimage, new Object[] { + new Integer(0), new Integer(0), + new Integer(outgoing.width), new Integer(outgoing.height), + outgoing.pixels, new Integer(0), new Integer(outgoing.width) + }); + + // check the alpha for this image + outgoing.checkAlpha(); + + // return the image + return outgoing; + + } catch (Exception e) { + e.printStackTrace(); + return null; + } + } + + + /** + * Targa image loader for RLE-compressed TGA files. + *

    + * Rewritten for 0115 to read/write RLE-encoded targa images. + * For 0125, non-RLE encoded images are now supported, along with + * images whose y-order is reversed (which is standard for TGA files). + */ + protected PImage loadImageTGA(String filename) throws IOException { + InputStream is = openStream(filename); + if (is == null) return null; + + byte header[] = new byte[18]; + int offset = 0; + do { + int count = is.read(header, offset, header.length - offset); + if (count == -1) return null; + offset += count; + } while (offset < 18); + + /* + header[2] image type code + 2 (0x02) - Uncompressed, RGB images. + 3 (0x03) - Uncompressed, black and white images. + 10 (0x0A) - Runlength encoded RGB images. + 11 (0x0B) - Compressed, black and white images. (grayscale?) + + header[16] is the bit depth (8, 24, 32) + + header[17] image descriptor (packed bits) + 0x20 is 32 = origin upper-left + 0x28 is 32 + 8 = origin upper-left + 32 bits + + 7 6 5 4 3 2 1 0 + 128 64 32 16 8 4 2 1 + */ + + int format = 0; + + if (((header[2] == 3) || (header[2] == 11)) && // B&W, plus RLE or not + (header[16] == 8) && // 8 bits + ((header[17] == 0x8) || (header[17] == 0x28))) { // origin, 32 bit + format = ALPHA; + + } else if (((header[2] == 2) || (header[2] == 10)) && // RGB, RLE or not + (header[16] == 24) && // 24 bits + ((header[17] == 0x20) || (header[17] == 0))) { // origin + format = RGB; + + } else if (((header[2] == 2) || (header[2] == 10)) && + (header[16] == 32) && + ((header[17] == 0x8) || (header[17] == 0x28))) { // origin, 32 + format = ARGB; + } + + if (format == 0) { + System.err.println("Unknown .tga file format for " + filename); + //" (" + header[2] + " " + + //(header[16] & 0xff) + " " + + //hex(header[17], 2) + ")"); + return null; + } + + int w = ((header[13] & 0xff) << 8) + (header[12] & 0xff); + int h = ((header[15] & 0xff) << 8) + (header[14] & 0xff); + PImage outgoing = createImage(w, h, format); + + boolean reversed = (header[17] & 0x20) != 0; + + if ((header[2] == 2) || (header[2] == 3)) { // not RLE encoded + if (reversed) { + int index = (h-1) * w; + switch (format) { + case ALPHA: + for (int y = h-1; y >= 0; y--) { + for (int x = 0; x < w; x++) { + outgoing.pixels[index + x] = is.read(); + } + index -= w; + } + break; + case RGB: + for (int y = h-1; y >= 0; y--) { + for (int x = 0; x < w; x++) { + outgoing.pixels[index + x] = + is.read() | (is.read() << 8) | (is.read() << 16) | + 0xff000000; + } + index -= w; + } + break; + case ARGB: + for (int y = h-1; y >= 0; y--) { + for (int x = 0; x < w; x++) { + outgoing.pixels[index + x] = + is.read() | (is.read() << 8) | (is.read() << 16) | + (is.read() << 24); + } + index -= w; + } + } + } else { // not reversed + int count = w * h; + switch (format) { + case ALPHA: + for (int i = 0; i < count; i++) { + outgoing.pixels[i] = is.read(); + } + break; + case RGB: + for (int i = 0; i < count; i++) { + outgoing.pixels[i] = + is.read() | (is.read() << 8) | (is.read() << 16) | + 0xff000000; + } + break; + case ARGB: + for (int i = 0; i < count; i++) { + outgoing.pixels[i] = + is.read() | (is.read() << 8) | (is.read() << 16) | + (is.read() << 24); + } + break; + } + } + + } else { // header[2] is 10 or 11 + int index = 0; + int px[] = outgoing.pixels; + + while (index < px.length) { + int num = is.read(); + boolean isRLE = (num & 0x80) != 0; + if (isRLE) { + num -= 127; // (num & 0x7F) + 1 + int pixel = 0; + switch (format) { + case ALPHA: + pixel = is.read(); + break; + case RGB: + pixel = 0xFF000000 | + is.read() | (is.read() << 8) | (is.read() << 16); + //(is.read() << 16) | (is.read() << 8) | is.read(); + break; + case ARGB: + pixel = is.read() | + (is.read() << 8) | (is.read() << 16) | (is.read() << 24); + break; + } + for (int i = 0; i < num; i++) { + px[index++] = pixel; + if (index == px.length) break; + } + } else { // write up to 127 bytes as uncompressed + num += 1; + switch (format) { + case ALPHA: + for (int i = 0; i < num; i++) { + px[index++] = is.read(); + } + break; + case RGB: + for (int i = 0; i < num; i++) { + px[index++] = 0xFF000000 | + is.read() | (is.read() << 8) | (is.read() << 16); + //(is.read() << 16) | (is.read() << 8) | is.read(); + } + break; + case ARGB: + for (int i = 0; i < num; i++) { + px[index++] = is.read() | //(is.read() << 24) | + (is.read() << 8) | (is.read() << 16) | (is.read() << 24); + //(is.read() << 16) | (is.read() << 8) | is.read(); + } + break; + } + } + } + + if (reversed) { + int[] temp = new int[w]; + for (int y = 0; y < h/2; y++) { + int z = (h-1) - y; + System.arraycopy(px, y*w, temp, 0, w); + System.arraycopy(px, z*w, px, y*w, w); + System.arraycopy(temp, 0, px, z*w, w); + } + } + } + + return outgoing; + } + + + + ////////////////////////////////////////////////////////////// + + // FONT I/O + + + /* + Hashtable fontTable; + */ + + /** + * Set the font based on its filename. This is less than efficient + * than using loadFont because there's no way to unload it from memory, + * but it's useful for beginners. + */ + /* + public void textFont(String filename) { + if (filename.toLowerCase().indexOf(".vlw") == -1) { + System.err.println("textFont() needs the filename of a .vlw font"); + } else { + textFont(tableFont(filename)); + } + } + */ + + + /** + * Set the font based on its filename. This is less than efficient + * than using loadFont because there's no way to unload it from memory, + * but it's useful for beginners. + */ + /* + public void textFont(String filename, float size) { + if (filename.toLowerCase().indexOf(".vlw") == -1) { + System.err.println("textFont() needs the filename of a .vlw font"); + } else { + textFont(tableFont(filename), size); + } + } + */ + + + /* + protected PFont tableFont(String filename) { + if (fontTable == null) fontTable = new Hashtable(); + + PFont font = (PFont) fontTable.get(filename); + if (font != null) return font; + + font = loadFont(filename); + return font; + } + */ + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + public PFont loadFont(String filename) { + //if (g == null) { // just for good measure + //die("loadFont() only be used inside setup() or draw()"); + //} + + try { + String lower = filename.toLowerCase(); + InputStream input = openStream(filename); + + // For compatability with earlier releases of Processing + if (lower.endsWith(".vlw.gz")) { + input = new GZIPInputStream(input); + + } else if (!lower.endsWith(".vlw")) { + // this gets thrown down below + throw new IOException("I don't know how to load a font named " + + filename); + } + return new PFont(input); + + } catch (Exception e) { + die("Could not load font " + filename + ". " + + "Make sure that the font has been copied " + + "to the data folder of your sketch.", e); + } + return null; + } + + + public PFont createFont(String name, float size) { + return createFont(name, size, true, PFont.DEFAULT_CHARSET); + } + + + public PFont createFont(String name, float size, boolean smooth) { + return createFont(name, size, smooth, PFont.DEFAULT_CHARSET); + } + + + /** + * Create a .vlw font on the fly from either a font name that's + * installed on the system, or from a .ttf or .otf that's inside + * the data folder of this sketch. + *

    + * Only works with Java 1.3 or later. Many .otf fonts don't seem + * to be supported by Java, perhaps because they're CFF based? + *

    + * Font names are inconsistent across platforms and Java versions. + * On Mac OS X, Java 1.3 uses the font menu name of the font, + * whereas Java 1.4 uses the PostScript name of the font. Java 1.4 + * on OS X will also accept the font menu name as well. On Windows, + * it appears that only the menu names are used, no matter what + * Java version is in use. Naming system unknown/untested for 1.5. + *

    + * Use 'null' for the charset if you want to use any of the 65,536 + * unicode characters that exist in the font. Note that this can + * produce an enormous file or may cause an OutOfMemoryError. + */ + public PFont createFont(String name, float size, + boolean smooth, char charset[]) { + if (PApplet.javaVersion < 1.3f) { + throw new RuntimeException("Can only create fonts with " + + "Java 1.3 or higher"); + } + + String lowerName = name.toLowerCase(); + Font font = null; + + try { + Method deriveFontMethod = + Font.class.getMethod("deriveFont", + new Class[] { Float.TYPE }); + Float floatSize = new Float(size); + + if (lowerName.endsWith(".otf") || lowerName.endsWith(".ttf")) { + InputStream stream = openStream(name); + if (stream == null) { + System.err.println("The font \"" + name + "\" " + + "is missing or inaccessible, make sure " + + "the URL is valid or that the file has been " + + "added to your sketch and is readable."); + return null; + } + + //font = Font.createFont(Font.TRUETYPE_FONT, openStream(name)); + Method createFontMethod = + Font.class.getMethod("createFont", + new Class[] { Integer.TYPE, + InputStream.class }); + Field ttf = Font.class.getField("TRUETYPE_FONT"); + Integer ttfInteger = new Integer(ttf.getInt(ttf)); + Font baseFont = (Font) + createFontMethod.invoke(name, + new Object[] { ttfInteger, + openStream(name) }); + font = (Font) deriveFontMethod.invoke(baseFont, + new Object[] { floatSize }); + } else { + Font baseFont = new Font(name, Font.PLAIN, 1); + font = (Font) + deriveFontMethod.invoke(baseFont, new Object[] { floatSize }); + } + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Problem using createFont() " + + "with the file " + name); + } + return new PFont(font, smooth, charset); + } + + + + ////////////////////////////////////////////////////////////// + + // FILE INPUT + + + public File inputFile() { + return inputFile("Select a file..."); + } + + + public File inputFile(String prompt) { + Frame parentFrame = null; + Component comp = getParent(); + while (comp != null) { + if (comp instanceof Frame) { + parentFrame = (Frame) comp; + break; + } + comp = comp.getParent(); + } + return inputFile(prompt, parentFrame); + } + + + static public File inputFile(Frame parent) { + return inputFile("Select a file...", parent); + } + + + /** + * static version of inputFile usable by external classes. + *

    + * The parentFrame is the Frame that will guide the placement of + * the prompt window. If no Frame is available, just pass in null. + */ + // can't be static because it wants a host component + static public File inputFile(String prompt, Frame parentFrame) { + if (parentFrame == null) parentFrame = new Frame(); + FileDialog fd = new FileDialog(parentFrame, prompt, FileDialog.LOAD); + fd.setVisible(true); + + String directory = fd.getDirectory(); + String filename = fd.getFile(); + if (filename == null) return null; + return new File(directory, filename); + } + + + public File outputFile() { + return outputFile("Save as..."); + } + + + public File outputFile(String prompt) { + Frame parentFrame = null; + Component comp = getParent(); + while (comp != null) { + //System.out.println(comp + " " + comp.getClass()); + if (comp instanceof Frame) { + parentFrame = (Frame) comp; + break; + } + comp = comp.getParent(); + } + return outputFile(prompt, parentFrame); + } + + + + static public File outputFile(Frame parentFrame) { + return outputFile("Save as...", parentFrame); + } + + + /** + * static version of outputFile usable by external classes. + *

    + * The parentFrame is the Frame that will guide the placement of + * the prompt window. If no Frame is available, just pass in null. + */ + static public File outputFile(String prompt, Frame parentFrame) { + if (parentFrame == null) parentFrame = new Frame(); + FileDialog fd = new FileDialog(parentFrame, prompt, FileDialog.SAVE); + fd.setVisible(true); + + String directory = fd.getDirectory(); + String filename = fd.getFile(); + if (filename == null) return null; + return new File(directory, filename); + } + + + /** + * I want to read lines from a file. I have RSI from typing these + * eight lines of code so many times. + */ + public BufferedReader createReader(String filename) { + try { + InputStream is = openStream(filename); + if (is == null) { + System.err.println(filename + " does not exist or could not be read"); + return null; + } + return createReader(is); + + } catch (Exception e) { + if (filename == null) { + System.err.println("Filename passed to reader() was null"); + } else { + System.err.println("Couldn't create a reader for " + filename); + } + } + return null; + } + + + /** + * I want to read lines from a file. And I'm still annoyed. + */ + static public BufferedReader createReader(File file) { + try { + return createReader(new FileInputStream(file)); + + } catch (Exception e) { + if (file == null) { + throw new RuntimeException("File passed to reader() was null"); + } else { + e.printStackTrace(); + throw new RuntimeException("Couldn't create a reader for " + + file.getAbsolutePath()); + } + } + //return null; + } + + + /** + * I want to read lines from a stream. If I have to type the + * following lines any more I'm gonna send Sun my medical bills. + */ + static public BufferedReader createReader(InputStream input) { + InputStreamReader isr = new InputStreamReader(input); + return new BufferedReader(isr); + } + + + /** + * decode a gzip input stream + */ + static public InputStream gzipInput(InputStream input) { + try { + return new GZIPInputStream(input); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Problem with gzip input"); + } + //return null; + } + + + /** + * decode a gzip output stream + */ + static public OutputStream gzipOutput(OutputStream output) { + try { + return new GZIPOutputStream(output); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Problem with gzip output"); + } + //return null; + } + + + /** + * I want to print lines to a file. Why can't I? + */ + public PrintWriter createWriter(String filename) { + try { + return createWriter(new FileOutputStream(savePath(filename))); + + } catch (Exception e) { + if (filename == null) { + die("Filename passed to writer() was null", e); + } else { + die("Couldn't create a writer for " + filename, e); + } + } + return null; + } + + + /** + * I want to print lines to a file. I have RSI from typing these + * eight lines of code so many times. + */ + static public PrintWriter createWriter(File file) { + try { + return createWriter(new FileOutputStream(file)); + + } catch (Exception e) { + if (file == null) { + throw new RuntimeException("File passed to writer() was null"); + } else { + e.printStackTrace(); + throw new RuntimeException("Couldn't create a writer for " + + file.getAbsolutePath()); + } + } + //return null; + } + + + /** + * I want to print lines to a file. Why am I always explaining myself? + * It's the JavaSoft API engineers who need to explain themselves. + */ + static public PrintWriter createWriter(OutputStream output) { + OutputStreamWriter osw = new OutputStreamWriter(output); + return new PrintWriter(osw); + } + + + /** + * Simplified method to open a Java InputStream. + *

    + * This method is useful if you want to use the facilities provided + * by PApplet to easily open things from the data folder or from a URL, + * but want an InputStream object so that you can use other Java + * methods to take more control of how the stream is read. + *

    + * If the requested item doesn't exist, null is returned. + * (Prior to 0096, die() would be called, killing the applet) + *

    + * For 0096+, the "data" folder is exported intact with subfolders, + * and openStream() properly handles subdirectories from the data folder + *

    + * If not online, this will also check to see if the user is asking + * for a file whose name isn't properly capitalized. This helps prevent + * issues when a sketch is exported to the web, where case sensitivity + * matters, as opposed to Windows and the Mac OS default where + * case sensitivity is preserved but ignored. + *

    + * It is strongly recommended that libraries use this method to open + * data files, so that the loading sequence is handled in the same way + * as functions like loadBytes(), loadImage(), etc. + *

    + * The filename passed in can be: + *

      + *
    • A URL, for instance openStream("http://processing.org/"); + *
    • A file in the sketch's data folder + *
    • Another file to be opened locally (when running as an application) + *
    + */ + public InputStream openStream(String filename) { + InputStream stream = null; + + if (filename == null) return null; + + if (filename.length() == 0) { + // an error will be called by the parent function + //System.err.println("The filename passed to openStream() was empty."); + return null; + } + + // safe to check for this as a url first. this will prevent online + // access logs from being spammed with GET /sketchfolder/http://blahblah + try { + URL url = new URL(filename); + stream = url.openStream(); + return stream; + + } catch (MalformedURLException mfue) { + // not a url, that's fine + + } catch (FileNotFoundException fnfe) { + // Java 1.5 likes to throw this when URL not available. (fix for 0119) + // http://dev.processing.org/bugs/show_bug.cgi?id=403 + + } catch (IOException e) { + // changed for 0117, shouldn't be throwing exception + e.printStackTrace(); + //System.err.println("Error downloading from URL " + filename); + return null; + //throw new RuntimeException("Error downloading from URL " + filename); + } + + // using getClassLoader() prevents java from converting dots + // to slashes or requiring a slash at the beginning. + // (a slash as a prefix means that it'll load from the root of + // the jar, rather than trying to dig into the package location) + ClassLoader cl = getClass().getClassLoader(); + + // by default, data files are exported to the root path of the jar. + // (not the data folder) so check there first. + stream = cl.getResourceAsStream("data/" + filename); + if (stream != null) { + String cn = stream.getClass().getName(); + // this is an irritation of sun's java plug-in, which will return + // a non-null stream for an object that doesn't exist. like all good + // things, this is probably introduced in java 1.5. awesome! + // http://dev.processing.org/bugs/show_bug.cgi?id=359 + if (!cn.equals("sun.plugin.cache.EmptyInputStream")) { + return stream; + } + } + + // when used with an online script, also need to check without the + // data folder, in case it's not in a subfolder called 'data' + // http://dev.processing.org/bugs/show_bug.cgi?id=389 + stream = cl.getResourceAsStream(filename); + if (stream != null) { + String cn = stream.getClass().getName(); + if (!cn.equals("sun.plugin.cache.EmptyInputStream")) { + return stream; + } + } + + // handle case sensitivity check + if (!online) { + try { + // first see if it's in a data folder + File file = new File(dataPath(filename)); + if (!file.exists()) { + // next see if it's just in this folder + file = new File(sketchPath, filename); + } + if (file.exists()) { + try { + String filePath = file.getCanonicalPath(); + String filenameActual = new File(filePath).getName(); + // make sure there isn't a subfolder prepended to the name + String filenameShort = new File(filename).getName(); + // if the actual filename is the same, but capitalized + // differently, warn the user. + //if (filenameActual.equalsIgnoreCase(filenameShort) && + //!filenameActual.equals(filenameShort)) { + if (!filenameActual.equals(filenameShort)) { + throw new RuntimeException("This file is named " + + filenameActual + " not " + + filename + ". Re-name it " + + "or change your code."); + } + } catch (IOException e) { } + } + + // if this file is ok, may as well just load it + stream = new FileInputStream(file); + if (stream != null) return stream; + + // have to break these out because a general Exception might + // catch the RuntimeException being thrown above + } catch (IOException ioe) { + } catch (SecurityException se) { } + } + + try { + // attempt to load from a local file, used when running as + // an application, or as a signed applet + try { // first try to catch any security exceptions + try { + stream = new FileInputStream(dataPath(filename)); + if (stream != null) return stream; + } catch (IOException e2) { } + + try { + stream = new FileInputStream(sketchPath(filename)); + if (stream != null) return stream; + } catch (Exception e) { } // ignored + + try { + stream = new FileInputStream(filename); + if (stream != null) return stream; + } catch (IOException e1) { } + + } catch (SecurityException se) { } // online, whups + + } catch (Exception e) { + //die(e.getMessage(), e); + e.printStackTrace(); + } + return null; + } + + + static public InputStream openStream(File file) { + try { + return new FileInputStream(file); + + } catch (IOException e) { + if (file == null) { + throw new RuntimeException("File passed to openStream() was null"); + + } else { + e.printStackTrace(); + throw new RuntimeException("Couldn't openStream() for " + + file.getAbsolutePath()); + } + } + } + + + public InputStream openStreamGZ(String filename) { + try { + return new GZIPInputStream(openStream(filename)); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Couldn't openStreamGZ() for " + + filename); + } + } + + + static public InputStream openStreamGZ(File file) { + try { + return new GZIPInputStream(openStream(file)); + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Couldn't openStreamGZ() for " + + file.getAbsolutePath()); + } + } + + + public byte[] loadBytes(String filename) { + InputStream is = openStream(filename); + if (is != null) return loadBytes(is); + + System.err.println("The file \"" + filename + "\" " + + "is missing or inaccessible, make sure " + + "the URL is valid or that the file has been " + + "added to your sketch and is readable."); + return null; + } + + + static public byte[] loadBytes(InputStream input) { + try { + BufferedInputStream bis = new BufferedInputStream(input); + ByteArrayOutputStream out = new ByteArrayOutputStream(); + + int c = bis.read(); + while (c != -1) { + out.write(c); + c = bis.read(); + } + return out.toByteArray(); + + } catch (IOException e) { + e.printStackTrace(); + //throw new RuntimeException("Couldn't load bytes from stream"); + } + return null; + } + + + static public String[] loadStrings(File file) { + InputStream is = openStream(file); + if (is != null) return loadStrings(is); + return null; + } + + + /** + * Load data from a file and shove it into a String array. + *

    + * Exceptions are handled internally, when an error, occurs, an + * exception is printed to the console and 'null' is returned, + * but the program continues running. This is a tradeoff between + * 1) showing the user that there was a problem but 2) not requiring + * that all i/o code is contained in try/catch blocks, for the sake + * of new users (or people who are just trying to get things done + * in a "scripting" fashion. If you want to handle exceptions, + * use Java methods for I/O. + */ + public String[] loadStrings(String filename) { + InputStream is = openStream(filename); + if (is != null) return loadStrings(is); + + System.err.println("The file \"" + filename + "\" " + + "is missing or inaccessible, make sure " + + "the URL is valid or that the file has been " + + "added to your sketch and is readable."); + return null; + } + + + static public String[] loadStrings(InputStream input) { + try { + BufferedReader reader = + new BufferedReader(new InputStreamReader(input)); + + String lines[] = new String[100]; + int lineCount = 0; + String line = null; + while ((line = reader.readLine()) != null) { + if (lineCount == lines.length) { + String temp[] = new String[lineCount << 1]; + System.arraycopy(lines, 0, temp, 0, lineCount); + lines = temp; + } + lines[lineCount++] = line; + } + reader.close(); + + if (lineCount == lines.length) { + return lines; + } + + // resize array to appropriate amount for these lines + String output[] = new String[lineCount]; + System.arraycopy(lines, 0, output, 0, lineCount); + return output; + + } catch (IOException e) { + e.printStackTrace(); + //throw new RuntimeException("Error inside loadStrings()"); + } + return null; + } + + + + ////////////////////////////////////////////////////////////// + + // FILE OUTPUT + + + /** + * Save the contents of a stream to a file in the sketch folder. + * This is basically saveBytes(loadBytes(), blah), but done + * in a less confusing manner. + */ + public void saveStream(String filename, String stream) { + saveBytes(filename, loadBytes(stream)); + } + + + /** + * Identical to the other saveStream(), but writes to a File + * object, for greater control over the file location. + */ + public void saveStream(File file, String stream) { + saveBytes(file, loadBytes(stream)); + } + + + /** + * Saves bytes to a file to inside the sketch folder. + * The filename can be a relative path, i.e. "poo/bytefun.txt" + * would save to a file named "bytefun.txt" to a subfolder + * called 'poo' inside the sketch folder. If the in-between + * subfolders don't exist, they'll be created. + */ + public void saveBytes(String filename, byte buffer[]) { + try { + String location = savePath(filename); + FileOutputStream fos = new FileOutputStream(location); + saveBytes(fos, buffer); + fos.close(); + + } catch (IOException e) { + System.err.println("error saving bytes to " + filename); + e.printStackTrace(); + } + } + + /** + * Saves bytes to a specific File location specified by the user. + */ + static public void saveBytes(File file, byte buffer[]) { + try { + String filename = file.getAbsolutePath(); + createPath(filename); + FileOutputStream fos = new FileOutputStream(file); + saveBytes(fos, buffer); + fos.close(); + + } catch (IOException e) { + System.err.println("error saving bytes to " + file); + e.printStackTrace(); + } + } + + + /** + * Spews a buffer of bytes to an OutputStream. + */ + static public void saveBytes(OutputStream output, byte buffer[]) { + try { + //BufferedOutputStream bos = new BufferedOutputStream(output); + output.write(buffer); + output.flush(); + + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("Couldn't save bytes"); + } + } + + // + + public void saveStrings(String filename, String strings[]) { + try { + String location = savePath(filename); + FileOutputStream fos = new FileOutputStream(location); + saveStrings(fos, strings); + fos.close(); + + } catch (IOException e) { + e.printStackTrace(); + throw new RuntimeException("saveStrings() failed: " + e.getMessage()); + } + } + + + static public void saveStrings(File file, String strings[]) { + try { + String location = file.getAbsolutePath(); + createPath(location); + FileOutputStream fos = new FileOutputStream(location); + saveStrings(fos, strings); + fos.close(); + + } catch (IOException e) { + System.err.println("error while saving strings"); + e.printStackTrace(); + } + } + + + static public void saveStrings(OutputStream output, String strings[]) { + PrintWriter writer = + new PrintWriter(new OutputStreamWriter(output)); + for (int i = 0; i < strings.length; i++) { + writer.println(strings[i]); + } + writer.flush(); + } + + + ////////////////////////////////////////////////////////////// + + + /** + * Prepend the sketch folder path to the filename (or path) that is + * passed in. External libraries should use this function to save to + * the sketch folder. + *

    + * Note that when running as an applet inside a web browser, + * the sketchPath will be set to null, because security restrictions + * prevent applets from accessing that information. + *

    + * This will also cause an error if the sketch is not inited properly, + * meaning that init() was never called on the PApplet when hosted + * my some other main() or by other code. For proper use of init(), + * see the examples in the main description text for PApplet. + */ + public String sketchPath(String where) { + if (sketchPath == null) { + throw new RuntimeException("The applet was not inited properly, " + + "or security restrictions prevented " + + "it from determining its path."); + } + // isAbsolute() could throw an access exception, but so will writing + // to the local disk using the sketch path, so this is safe here. + // for 0120, added a try/catch anyways. + try { + if (new File(where).isAbsolute()) return where; + } catch (Exception e) { } + + return sketchPath + File.separator + where; + } + + + /** + * Returns a path inside the applet folder to save to, + * just like sketchPath(), but also creates any in-between + * folders so that things save properly. + *

    + * All saveXxxx() functions use the path to the sketch folder, rather than + * its data folder. Once exported, the data folder will be found inside the + * jar file of the exported application or applet. In this case, it's not + * possible to save data into the jar file, because it will often be running + * from a server, or marked in-use if running from a local file system. + * With this in mind, saving to the data path doesn't make sense anyway. + * If you know you're running locally, and want to save to the data folder, + * use saveXxxx("data/blah.dat"). + */ + public String savePath(String where) { + String filename = sketchPath(where); + createPath(filename); + return filename; + } + + + /** + * Return a full path to an item in the data folder. + *

    + * In this method, the data path is defined not as the applet's actual + * data path, but a folder titled "data" in the sketch's working + * directory. This is because in an application, the "data" folder is + * exported as part of the jar file, and it's not as though you're gonna + * write into the jar file itself. If you need to get things out of + * the jar file, you should use openStream(). + */ + public String dataPath(String where) { + // isAbsolute() could throw an access exception, but so will writing + // to the local disk using the sketch path, so this is safe here. + if (new File(where).isAbsolute()) return where; + + return sketchPath + File.separator + "data" + File.separator + where; + } + + + /** + * Takes a path and creates any in-between folders if they don't + * already exist. Useful when trying to save to a subfolder that + * may not actually exist. + */ + static public void createPath(String filename) { + File file = new File(filename); + String parent = file.getParent(); + if (parent != null) { + File unit = new File(parent); + if (!unit.exists()) unit.mkdirs(); + } + } + + + ////////////////////////////////////////////////////////////// + + // SORT + + int sort_mode; + + static final int BYTES = 1; + static final int CHARS = 2; + static final int INTS = 3; + static final int FLOATS = 4; + static final int STRINGS = 5; + static final int OBJECTS = 6; + + byte sort_bytes[]; + char sort_chars[]; + int sort_ints[]; + float sort_floats[]; + String sort_strings[]; + + Object sortObject; + Method swapMethod; + Method compareMethod; + + public byte[] sort(byte what[]) { + return sort(what, what.length); + } + + public char[] sort(char what[]) { + return sort(what, what.length); + } + + public int[] sort(int what[]) { + return sort(what, what.length); + } + + public float[] sort(float what[]) { + return sort(what, what.length); + } + + public String[] sort(String what[]) { + return sort(what, what.length); + } + + // + + public byte[] sort(byte what[], int count) { + if (count == 0) return null; + sort_mode = BYTES; + sort_bytes = new byte[count]; + System.arraycopy(what, 0, sort_bytes, 0, count); + sort_internal(0, count-1); + return sort_bytes; + } + + public char[] sort(char what[], int count) { + if (count == 0) return null; + sort_mode = CHARS; + sort_chars = new char[count]; + System.arraycopy(what, 0, sort_chars, 0, count); + sort_internal(0, count-1); + return sort_chars; + } + + public int[] sort(int what[], int count) { + if (count == 0) return null; + sort_mode = INTS; + sort_ints = new int[count]; + System.arraycopy(what, 0, sort_ints, 0, count); + sort_internal(0, count-1); + return sort_ints; + } + + public float[] sort(float what[], int count) { + if (count == 0) return null; + sort_mode = FLOATS; + sort_floats = new float[count]; + System.arraycopy(what, 0, sort_floats, 0, count); + sort_internal(0, count-1); + return sort_floats; + } + + public String[] sort(String what[], int count) { + if (count == 0) return null; + sort_mode = STRINGS; + sort_strings = new String[count]; + System.arraycopy(what, 0, sort_strings, 0, count); + sort_internal(0, count-1); + return sort_strings; + } + + /* + public void sort(Object what, int count) { + if (count == 0) return null; + sort_mode = OBJECTS; + sort_strings = new String[count]; + System.arraycopy(what, 0, sort_strings, 0, count); + sort_internal(0, count-1); + return sort_strings; + } + */ + + // + + protected void sort_internal(int i, int j) { + int pivotIndex = (i+j)/2; + sort_swap(pivotIndex, j); + int k = sort_partition(i-1, j); + sort_swap(k, j); + if ((k-i) > 1) sort_internal(i, k-1); + if ((j-k) > 1) sort_internal(k+1, j); + } + + + protected int sort_partition(int left, int right) { + int pivot = right; + do { + while (sort_compare(++left, pivot) < 0) { } + while ((right != 0) && (sort_compare(--right, pivot) > 0)) { } + sort_swap(left, right); + } while (left < right); + sort_swap(left, right); + return left; + } + + + protected void sort_swap(int a, int b) { + switch (sort_mode) { + case BYTES: + byte btemp = sort_bytes[a]; + sort_bytes[a] = sort_bytes[b]; + sort_bytes[b] = btemp; + break; + case CHARS: + char ctemp = sort_chars[a]; + sort_chars[a] = sort_chars[b]; + sort_chars[b] = ctemp; + break; + case INTS: + int itemp = sort_ints[a]; + sort_ints[a] = sort_ints[b]; + sort_ints[b] = itemp; + break; + case FLOATS: + float ftemp = sort_floats[a]; + sort_floats[a] = sort_floats[b]; + sort_floats[b] = ftemp; + break; + case STRINGS: + String stemp = sort_strings[a]; + sort_strings[a] = sort_strings[b]; + sort_strings[b] = stemp; + break; + case OBJECTS: + try { + Object[] params = new Object[] { new Integer(a), new Integer(b) }; + swapMethod.invoke(sortObject, params); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + + protected float sort_compare(int a, int b) { + switch (sort_mode) { + case BYTES: + return sort_bytes[a] - sort_bytes[b]; + case CHARS: + return sort_chars[a] - sort_chars[b]; + case INTS: + return sort_ints[a] - sort_ints[b]; + case FLOATS: + // can't just cast to an int because 0.2 and 0.4 would + // just appear to be the same thing. no good. + //if (sort_floats[a] < sort_floats[b]) return -1; + //return (sort_floats[a] == sort_floats[b]) ? 0 : 1; + return sort_floats[a] - sort_floats[b]; + case STRINGS: + return sort_strings[a].compareTo(sort_strings[b]); + case OBJECTS: + try { + Object[] params = new Object[] { new Integer(a), new Integer(b) }; + Float output = (Float) compareMethod.invoke(sortObject, params); + return output.floatValue(); + } catch (Exception e) { + e.printStackTrace(); + } + } + return 0; + } + + + ////////////////////////////////////////////////////////////// + + + public void sort(Object o, int count) { + Class c = o.getClass(); + try { + Class[] params = new Class[] { Integer.TYPE, Integer.TYPE }; + // takes two ints, returns a float + compareMethod = c.getMethod("sortCompare", params); + // takes two ints, returns void + swapMethod = c.getMethod("sortSwap", params); + // start the sort + sortObject = o; + sort_mode = OBJECTS; + sort_internal(0, count-1); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + + ////////////////////////////////////////////////////////////// + + // ARRAY UTILITIES + + + /** + * Calls System.arraycopy(), included here so that we can + * avoid people needing to learn about the System object + * before they can just copy an array. + */ + static public void arraycopy(Object src, int srcPosition, + Object dst, int dstPosition, + int length) { + System.arraycopy(src, srcPosition, dst, dstPosition, length); + } + + + /** + * Convenience method for arraycopy(). + * Identical to arraycopy(src, 0, dst, 0, length); + */ + static public void arraycopy(Object src, Object dst, int length) { + System.arraycopy(src, 0, dst, 0, length); + } + + + /** + * Shortcut to copy the entire contents of + * the source into the destination array. + * Identical to arraycopy(src, 0, dst, 0, src.length); + */ + static public void arraycopy(Object src, Object dst) { + System.arraycopy(src, 0, dst, 0, Array.getLength(src)); + } + + // + + static public boolean[] expand(boolean list[]) { + return expand(list, list.length << 1); + } + + static public boolean[] expand(boolean list[], int newSize) { + boolean temp[] = new boolean[newSize]; + System.arraycopy(list, 0, temp, 0, Math.min(newSize, list.length)); + return temp; + } + + + static public byte[] expand(byte list[]) { + return expand(list, list.length << 1); + } + + static public byte[] expand(byte list[], int newSize) { + byte temp[] = new byte[newSize]; + System.arraycopy(list, 0, temp, 0, Math.min(newSize, list.length)); + return temp; + } + + + static public char[] expand(char list[]) { + return expand(list, list.length << 1); + } + + static public char[] expand(char list[], int newSize) { + char temp[] = new char[newSize]; + System.arraycopy(list, 0, temp, 0, Math.min(newSize, list.length)); + return temp; + } + + + static public int[] expand(int list[]) { + return expand(list, list.length << 1); + } + + static public int[] expand(int list[], int newSize) { + int temp[] = new int[newSize]; + System.arraycopy(list, 0, temp, 0, Math.min(newSize, list.length)); + return temp; + } + + + static public float[] expand(float list[]) { + return expand(list, list.length << 1); + } + + static public float[] expand(float list[], int newSize) { + float temp[] = new float[newSize]; + System.arraycopy(list, 0, temp, 0, Math.min(newSize, list.length)); + return temp; + } + + + static public String[] expand(String list[]) { + return expand(list, list.length << 1); + } + + static public String[] expand(String list[], int newSize) { + String temp[] = new String[newSize]; + // in case the new size is smaller than list.length + System.arraycopy(list, 0, temp, 0, Math.min(newSize, list.length)); + return temp; + } + + + static public Object expand(Object array) { + return expand(array, Array.getLength(array) << 1); + } + + static public Object expand(Object list, int newSize) { + Class type = list.getClass().getComponentType(); + Object temp = Array.newInstance(type, newSize); + System.arraycopy(list, 0, temp, 0, + Math.min(Array.getLength(list), newSize)); + return temp; + } + + // + + // contract() has been removed in revision 0124, use subset() instead. + // (expand() is also functionally equivalent) + + // + + static public byte[] append(byte b[], byte value) { + b = expand(b, b.length + 1); + b[b.length-1] = value; + return b; + } + + static public char[] append(char b[], char value) { + b = expand(b, b.length + 1); + b[b.length-1] = value; + return b; + } + + static public int[] append(int b[], int value) { + b = expand(b, b.length + 1); + b[b.length-1] = value; + return b; + } + + static public float[] append(float b[], float value) { + b = expand(b, b.length + 1); + b[b.length-1] = value; + return b; + } + + static public String[] append(String b[], String value) { + b = expand(b, b.length + 1); + b[b.length-1] = value; + return b; + } + + static public Object append(Object b, Object value) { + int length = Array.getLength(b); + b = expand(b, length + 1); + Array.set(b, length, value); + return b; + } + + // + + static public boolean[] shorten(boolean list[]) { + return subset(list, 0, list.length-1); + } + + static public byte[] shorten(byte list[]) { + return subset(list, 0, list.length-1); + } + + static public char[] shorten(char list[]) { + return subset(list, 0, list.length-1); + } + + static public int[] shorten(int list[]) { + return subset(list, 0, list.length-1); + } + + static public float[] shorten(float list[]) { + return subset(list, 0, list.length-1); + } + + static public String[] shorten(String list[]) { + return subset(list, 0, list.length-1); + } + + static public Object shorten(Object list) { + int length = Array.getLength(list); + return subset(list, 0, length - 1); + } + + // + + static final public boolean[] splice(boolean list[], + boolean v, int index) { + boolean outgoing[] = new boolean[list.length + 1]; + System.arraycopy(list, 0, outgoing, 0, index); + outgoing[index] = v; + System.arraycopy(list, index, outgoing, index + 1, + list.length - index); + return outgoing; + } + + static final public boolean[] splice(boolean list[], + boolean v[], int index) { + boolean outgoing[] = new boolean[list.length + v.length]; + System.arraycopy(list, 0, outgoing, 0, index); + System.arraycopy(v, 0, outgoing, index, v.length); + System.arraycopy(list, index, outgoing, index + v.length, + list.length - index); + return outgoing; + } + + + static final public byte[] splice(byte list[], + byte v, int index) { + byte outgoing[] = new byte[list.length + 1]; + System.arraycopy(list, 0, outgoing, 0, index); + outgoing[index] = v; + System.arraycopy(list, index, outgoing, index + 1, + list.length - index); + return outgoing; + } + + static final public byte[] splice(byte list[], + byte v[], int index) { + byte outgoing[] = new byte[list.length + v.length]; + System.arraycopy(list, 0, outgoing, 0, index); + System.arraycopy(v, 0, outgoing, index, v.length); + System.arraycopy(list, index, outgoing, index + v.length, + list.length - index); + return outgoing; + } + + + static final public char[] splice(char list[], + char v, int index) { + char outgoing[] = new char[list.length + 1]; + System.arraycopy(list, 0, outgoing, 0, index); + outgoing[index] = v; + System.arraycopy(list, index, outgoing, index + 1, + list.length - index); + return outgoing; + } + + static final public char[] splice(char list[], + char v[], int index) { + char outgoing[] = new char[list.length + v.length]; + System.arraycopy(list, 0, outgoing, 0, index); + System.arraycopy(v, 0, outgoing, index, v.length); + System.arraycopy(list, index, outgoing, index + v.length, + list.length - index); + return outgoing; + } + + + static final public int[] splice(int list[], + int v, int index) { + int outgoing[] = new int[list.length + 1]; + System.arraycopy(list, 0, outgoing, 0, index); + outgoing[index] = v; + System.arraycopy(list, index, outgoing, index + 1, + list.length - index); + return outgoing; + } + + static final public int[] splice(int list[], + int v[], int index) { + int outgoing[] = new int[list.length + v.length]; + System.arraycopy(list, 0, outgoing, 0, index); + System.arraycopy(v, 0, outgoing, index, v.length); + System.arraycopy(list, index, outgoing, index + v.length, + list.length - index); + return outgoing; + } + + + static final public float[] splice(float list[], + float v, int index) { + float outgoing[] = new float[list.length + 1]; + System.arraycopy(list, 0, outgoing, 0, index); + outgoing[index] = v; + System.arraycopy(list, index, outgoing, index + 1, + list.length - index); + return outgoing; + } + + static final public float[] splice(float list[], + float v[], int index) { + float outgoing[] = new float[list.length + v.length]; + System.arraycopy(list, 0, outgoing, 0, index); + System.arraycopy(v, 0, outgoing, index, v.length); + System.arraycopy(list, index, outgoing, index + v.length, + list.length - index); + return outgoing; + } + + + static final public String[] splice(String list[], + String v, int index) { + String outgoing[] = new String[list.length + 1]; + System.arraycopy(list, 0, outgoing, 0, index); + outgoing[index] = v; + System.arraycopy(list, index, outgoing, index + 1, + list.length - index); + return outgoing; + } + + static final public String[] splice(String list[], + String v[], int index) { + String outgoing[] = new String[list.length + v.length]; + System.arraycopy(list, 0, outgoing, 0, index); + System.arraycopy(v, 0, outgoing, index, v.length); + System.arraycopy(list, index, outgoing, index + v.length, + list.length - index); + return outgoing; + } + + + static final public Object splice(Object list, Object v, int index) { + Object[] outgoing = null; + int length = Array.getLength(list); + + // check whether is an array or not, and if so, treat as such + if (list.getClass().getName().charAt(0) == '[') { + int vlength = Array.getLength(v); + outgoing = new Object[length + vlength]; + System.arraycopy(list, 0, outgoing, 0, index); + System.arraycopy(v, 0, outgoing, index, vlength); + System.arraycopy(list, index, outgoing, index + vlength, length - index); + + } else { + outgoing = new Object[length + 1]; + System.arraycopy(list, 0, outgoing, 0, index); + Array.set(outgoing, index, v); + System.arraycopy(list, index, outgoing, index + 1, length - index); + } + return outgoing; + } + + // + + static public boolean[] subset(boolean list[], int start) { + return subset(list, start, list.length - start); + } + + static public boolean[] subset(boolean list[], int start, int count) { + boolean output[] = new boolean[count]; + System.arraycopy(list, start, output, 0, count); + return output; + } + + + static public byte[] subset(byte list[], int start) { + return subset(list, start, list.length - start); + } + + static public byte[] subset(byte list[], int start, int count) { + byte output[] = new byte[count]; + System.arraycopy(list, start, output, 0, count); + return output; + } + + + static public char[] subset(char list[], int start) { + return subset(list, start, list.length - start); + } + + static public char[] subset(char list[], int start, int count) { + char output[] = new char[count]; + System.arraycopy(list, start, output, 0, count); + return output; + } + + + static public int[] subset(int list[], int start) { + return subset(list, start, list.length - start); + } + + static public int[] subset(int list[], int start, int count) { + int output[] = new int[count]; + System.arraycopy(list, start, output, 0, count); + return output; + } + + + static public float[] subset(float list[], int start) { + return subset(list, start, list.length - start); + } + + static public float[] subset(float list[], int start, int count) { + float output[] = new float[count]; + System.arraycopy(list, start, output, 0, count); + return output; + } + + + static public String[] subset(String list[], int start) { + return subset(list, start, list.length - start); + } + + static public String[] subset(String list[], int start, int count) { + String output[] = new String[count]; + System.arraycopy(list, start, output, 0, count); + return output; + } + + + static public Object subset(Object list, int start) { + int length = Array.getLength(list); + int count = length - start; + Class type = list.getClass().getComponentType(); + Object outgoing = Array.newInstance(type, count); + System.arraycopy(list, 0, outgoing, 0, count); + return outgoing; + } + + static public Object subset(Object list, int start, int count) { + //int length = Array.getLength(list); + Class type = list.getClass().getComponentType(); + Object outgoing = Array.newInstance(type, count); + System.arraycopy(list, start, outgoing, 0, count); + return outgoing; + } + + // + + static public boolean[] concat(boolean a[], boolean b[]) { + boolean c[] = new boolean[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + static public byte[] concat(byte a[], byte b[]) { + byte c[] = new byte[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + static public char[] concat(char a[], char b[]) { + char c[] = new char[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + static public int[] concat(int a[], int b[]) { + int c[] = new int[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + static public float[] concat(float a[], float b[]) { + float c[] = new float[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + static public String[] concat(String a[], String b[]) { + String c[] = new String[a.length + b.length]; + System.arraycopy(a, 0, c, 0, a.length); + System.arraycopy(b, 0, c, a.length, b.length); + return c; + } + + static public Object concat(Object a, Object b) { + Class type = a.getClass().getComponentType(); + int alength = Array.getLength(a); + int blength = Array.getLength(b); + Object outgoing = Array.newInstance(type, alength + blength); + System.arraycopy(a, 0, outgoing, 0, alength); + System.arraycopy(b, 0, outgoing, alength, blength); + return outgoing; + } + + // + + static public boolean[] reverse(boolean list[]) { + boolean outgoing[] = new boolean[list.length]; + int length1 = list.length - 1; + for (int i = 0; i < list.length; i++) { + outgoing[i] = list[length1 - i]; + } + return outgoing; + } + + static public byte[] reverse(byte list[]) { + byte outgoing[] = new byte[list.length]; + int length1 = list.length - 1; + for (int i = 0; i < list.length; i++) { + outgoing[i] = list[length1 - i]; + } + return outgoing; + } + + static public char[] reverse(char list[]) { + char outgoing[] = new char[list.length]; + int length1 = list.length - 1; + for (int i = 0; i < list.length; i++) { + outgoing[i] = list[length1 - i]; + } + return outgoing; + } + + static public int[] reverse(int list[]) { + int outgoing[] = new int[list.length]; + int length1 = list.length - 1; + for (int i = 0; i < list.length; i++) { + outgoing[i] = list[length1 - i]; + } + return outgoing; + } + + static public float[] reverse(float list[]) { + float outgoing[] = new float[list.length]; + int length1 = list.length - 1; + for (int i = 0; i < list.length; i++) { + outgoing[i] = list[length1 - i]; + } + return outgoing; + } + + static public String[] reverse(String list[]) { + String outgoing[] = new String[list.length]; + int length1 = list.length - 1; + for (int i = 0; i < list.length; i++) { + outgoing[i] = list[length1 - i]; + } + return outgoing; + } + + static public Object reverse(Object list) { + Class type = list.getClass().getComponentType(); + int length = Array.getLength(list); + Object outgoing = Array.newInstance(type, length); + for (int i = 0; i < length; i++) { + Array.set(outgoing, i, Array.get(list, (length - 1) - i)); + } + return outgoing; + } + + + + ////////////////////////////////////////////////////////////// + + // STRINGS + + + /** + * Remove whitespace characters from the beginning and ending + * of a String. Works like String.trim() but includes the + * unicode nbsp character as well. + */ + static public String trim(String str) { + return str.replace('\u00A0', ' ').trim(); + + /* + int left = 0; + int right = str.length() - 1; + + while ((left <= right) && + (WHITESPACE.indexOf(str.charAt(left)) != -1)) left++; + if (left == right) return ""; + + while (WHITESPACE.indexOf(str.charAt(right)) != -1) --right; + + return str.substring(left, right-left+1); + */ + } + + + /** + * Trim the whitespace from a String array. This returns a new + * array and does not affect the passed-in array. + */ + static public String[] trim(String[] array) { + String[] outgoing = new String[array.length]; + for (int i = 0; i < array.length; i++) { + outgoing[i] = array[i].replace('\u00A0', ' ').trim(); + } + return outgoing; + } + + + /** + * Join an array of Strings together as a single String, + * separated by the whatever's passed in for the separator. + */ + static public String join(String str[], char separator) { + return join(str, String.valueOf(separator)); + } + + + /** + * Join an array of Strings together as a single String, + * separated by the whatever's passed in for the separator. + *

    + * To use this on numbers, first pass the array to nf() or nfs() + * to get a list of String objects, then use join on that. + *

    +   * e.g. String stuff[] = { "apple", "bear", "cat" };
    +   *      String list = join(stuff, ", ");
    +   *      // list is now "apple, bear, cat"
    + */ + static public String join(String str[], String separator) { + StringBuffer buffer = new StringBuffer(); + for (int i = 0; i < str.length; i++) { + if (i != 0) buffer.append(separator); + buffer.append(str[i]); + } + return buffer.toString(); + } + + + /** + * Split the provided String at wherever whitespace occurs. + * Multiple whitespace (extra spaces or tabs or whatever) + * between items will count as a single break. + *

    + * The whitespace characters are "\t\n\r\f", which are the defaults + * for java.util.StringTokenizer, plus the unicode non-breaking space + * character, which is found commonly on files created by or used + * in conjunction with Mac OS X (character 160, or 0x00A0 in hex). + *

    +   * i.e. splitTokens("a b") -> { "a", "b" }
    +   *      splitTokens("a    b") -> { "a", "b" }
    +   *      splitTokens("a\tb") -> { "a", "b" }
    +   *      splitTokens("a \t  b  ") -> { "a", "b" }
    + */ + static public String[] splitTokens(String what) { + return splitTokens(what, WHITESPACE); + } + + + /** + * Splits a string into pieces, using any of the chars in the + * String 'delim' as separator characters. For instance, + * in addition to white space, you might want to treat commas + * as a separator. The delimeter characters won't appear in + * the returned String array. + *
    +   * i.e. splitTokens("a, b", " ,") -> { "a", "b" }
    +   * 
    + * To include all the whitespace possibilities, use the variable + * WHITESPACE, found in PConstants: + *
    +   * i.e. splitTokens("a   | b", WHITESPACE + "|");  ->  { "a", "b" }
    + */ + static public String[] splitTokens(String what, String delim) { + StringTokenizer toker = new StringTokenizer(what, delim); + String pieces[] = new String[toker.countTokens()]; + + int index = 0; + while (toker.hasMoreTokens()) { + pieces[index++] = toker.nextToken(); + } + return pieces; + } + + + /** + * Split a string into pieces along a specific character. + * Most commonly used to break up a String along tab characters. + *

    + * This operates differently than the others, where the + * single delimeter is the only breaking point, and consecutive + * delimeters will produce an empty string (""). This way, + * one can split on tab characters, but maintain the column + * alignments (of say an excel file) where there are empty columns. + */ + static public String[] split(String what, char delim) { + // do this so that the exception occurs inside the user's + // program, rather than appearing to be a bug inside split() + if (what == null) return null; + //return split(what, String.valueOf(delim)); // huh + + char chars[] = what.toCharArray(); + int splitCount = 0; //1; + for (int i = 0; i < chars.length; i++) { + if (chars[i] == delim) splitCount++; + } + // make sure that there is something in the input string + //if (chars.length > 0) { + // if the last char is a delimeter, get rid of it.. + //if (chars[chars.length-1] == delim) splitCount--; + // on second thought, i don't agree with this, will disable + //} + if (splitCount == 0) { + String splits[] = new String[1]; + splits[0] = new String(what); + return splits; + } + //int pieceCount = splitCount + 1; + String splits[] = new String[splitCount + 1]; + int splitIndex = 0; + int startIndex = 0; + for (int i = 0; i < chars.length; i++) { + if (chars[i] == delim) { + splits[splitIndex++] = + new String(chars, startIndex, i-startIndex); + startIndex = i + 1; + } + } + //if (startIndex != chars.length) { + splits[splitIndex] = + new String(chars, startIndex, chars.length-startIndex); + //} + return splits; + } + + + /** + * FIXME this is only temporary + */ + static public String[] split(String what, String delim) { + return what.split(delim); + } + + + + ////////////////////////////////////////////////////////////// + + // CASTING FUNCTIONS, INSERTED BY PREPROC + + + /** + * Convert a char to a boolean. 'T', 't', and '1' will become the + * boolean value true, while 'F', 'f', or '0' will become false. + */ + /* + static final public boolean parseBoolean(char what) { + return ((what == 't') || (what == 'T') || (what == '1')); + } + */ + + /** + *

    Convert an integer to a boolean. Because of how Java handles upgrading + * numbers, this will also cover byte and char (as they will upgrade to + * an int without any sort of explicit cast).

    + *

    The preprocessor will convert boolean(what) to parseBoolean(what).

    + * @return false if 0, true if any other number + */ + static final public boolean parseBoolean(int what) { + return (what != 0); + } + + /* + // removed because this makes no useful sense + static final public boolean parseBoolean(float what) { + return (what != 0); + } + */ + + /** + * Convert the string "true" or "false" to a boolean. + * @return true if 'what' is "true" or "TRUE", false otherwise + */ + static final public boolean parseBoolean(String what) { + return new Boolean(what).booleanValue(); + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + /* + // removed, no need to introduce strange syntax from other languages + static final public boolean[] parseBoolean(char what[]) { + boolean outgoing[] = new boolean[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = + ((what[i] == 't') || (what[i] == 'T') || (what[i] == '1')); + } + return outgoing; + } + */ + + /** + * Convert a byte array to a boolean array. Each element will be + * evaluated identical to the integer case, where a byte equal + * to zero will return false, and any other value will return true. + * @return array of boolean elements + */ + static final public boolean[] parseBoolean(byte what[]) { + boolean outgoing[] = new boolean[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (what[i] != 0); + } + return outgoing; + } + + /** + * Convert an int array to a boolean array. An int equal + * to zero will return false, and any other value will return true. + * @return array of boolean elements + */ + static final public boolean[] parseBoolean(int what[]) { + boolean outgoing[] = new boolean[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (what[i] != 0); + } + return outgoing; + } + + /* + // removed, not necessary... if necessary, convert to int array first + static final public boolean[] parseBoolean(float what[]) { + boolean outgoing[] = new boolean[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (what[i] != 0); + } + return outgoing; + } + */ + + static final public boolean[] parseBoolean(String what[]) { + boolean outgoing[] = new boolean[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = new Boolean(what[i]).booleanValue(); + } + return outgoing; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static final public byte parseByte(boolean what) { + return what ? (byte)1 : 0; + } + + static final public byte parseByte(char what) { + return (byte) what; + } + + static final public byte parseByte(int what) { + return (byte) what; + } + + static final public byte parseByte(float what) { + return (byte) what; + } + + /* + // nixed, no precedent + static final public byte[] parseByte(String what) { // note: array[] + return what.getBytes(); + } + */ + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static final public byte[] parseByte(boolean what[]) { + byte outgoing[] = new byte[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = what[i] ? (byte)1 : 0; + } + return outgoing; + } + + static final public byte[] parseByte(char what[]) { + byte outgoing[] = new byte[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (byte) what[i]; + } + return outgoing; + } + + static final public byte[] parseByte(int what[]) { + byte outgoing[] = new byte[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (byte) what[i]; + } + return outgoing; + } + + static final public byte[] parseByte(float what[]) { + byte outgoing[] = new byte[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (byte) what[i]; + } + return outgoing; + } + + /* + static final public byte[][] parseByte(String what[]) { // note: array[][] + byte outgoing[][] = new byte[what.length][]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = what[i].getBytes(); + } + return outgoing; + } + */ + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + /* + static final public char parseChar(boolean what) { // 0/1 or T/F ? + return what ? 't' : 'f'; + } + */ + + static final public char parseChar(byte what) { + return (char) (what & 0xff); + } + + static final public char parseChar(int what) { + return (char) what; + } + + /* + static final public char parseChar(float what) { // nonsensical + return (char) what; + } + + static final public char[] parseChar(String what) { // note: array[] + return what.toCharArray(); + } + */ + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + /* + static final public char[] parseChar(boolean what[]) { // 0/1 or T/F ? + char outgoing[] = new char[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = what[i] ? 't' : 'f'; + } + return outgoing; + } + */ + + static final public char[] parseChar(byte what[]) { + char outgoing[] = new char[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (char) (what[i] & 0xff); + } + return outgoing; + } + + static final public char[] parseChar(int what[]) { + char outgoing[] = new char[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (char) what[i]; + } + return outgoing; + } + + /* + static final public char[] parseChar(float what[]) { // nonsensical + char outgoing[] = new char[what.length]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = (char) what[i]; + } + return outgoing; + } + + static final public char[][] parseChar(String what[]) { // note: array[][] + char outgoing[][] = new char[what.length][]; + for (int i = 0; i < what.length; i++) { + outgoing[i] = what[i].toCharArray(); + } + return outgoing; + } + */ + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static final public int parseInt(boolean what) { + return what ? 1 : 0; + } + + /** + * Note that parseInt() will un-sign a signed byte value. + */ + static final public int parseInt(byte what) { + return what & 0xff; + } + + /** + * Note that parseInt('5') is unlike String in the sense that it + * won't return 5, but the ascii value. This is because ((int) someChar) + * returns the ascii value, and parseInt() is just longhand for the cast. + */ + static final public int parseInt(char what) { + return what; + } + + /** + * Same as floor(), or an (int) cast. + */ + static final public int parseInt(float what) { + return (int) what; + } + + /** + * Parse a String into an int value. Returns 0 if the value is bad. + */ + static final public int parseInt(String what) { + return parseInt(what, 0); + } + + /** + * Parse a String to an int, and provide an alternate value that + * should be used when the number is invalid. + */ + static final public int parseInt(String what, int otherwise) { + try { + int offset = what.indexOf('.'); + if (offset == -1) { + return Integer.parseInt(what); + } else { + return Integer.parseInt(what.substring(0, offset)); + } + } catch (NumberFormatException e) { } + return otherwise; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static final public int[] parseInt(boolean what[]) { + int list[] = new int[what.length]; + for (int i = 0; i < what.length; i++) { + list[i] = what[i] ? 1 : 0; + } + return list; + } + + static final public int[] parseInt(byte what[]) { // note this unsigns + int list[] = new int[what.length]; + for (int i = 0; i < what.length; i++) { + list[i] = (what[i] & 0xff); + } + return list; + } + + static final public int[] parseInt(char what[]) { + int list[] = new int[what.length]; + for (int i = 0; i < what.length; i++) { + list[i] = what[i]; + } + return list; + } + + static public int[] parseInt(float what[]) { + int inties[] = new int[what.length]; + for (int i = 0; i < what.length; i++) { + inties[i] = (int)what[i]; + } + return inties; + } + + /** + * Make an array of int elements from an array of String objects. + * If the String can't be parsed as a number, it will be set to zero. + * + * String s[] = { "1", "300", "44" }; + * int numbers[] = parseInt(s); + * + * numbers will contain { 1, 300, 44 } + */ + static public int[] parseInt(String what[]) { + return parseInt(what, 0); + } + + /** + * Make an array of int elements from an array of String objects. + * If the String can't be parsed as a number, its entry in the + * array will be set to the value of the "missing" parameter. + * + * String s[] = { "1", "300", "apple", "44" }; + * int numbers[] = parseInt(s, 9999); + * + * numbers will contain { 1, 300, 9999, 44 } + */ + static public int[] parseInt(String what[], int missing) { + int output[] = new int[what.length]; + for (int i = 0; i < what.length; i++) { + try { + output[i] = Integer.parseInt(what[i]); + } catch (NumberFormatException e) { + output[i] = missing; + } + } + return output; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + /* + static final public float parseFloat(boolean what) { + return what ? 1 : 0; + } + */ + + /** + * Convert an int to a float value. Also handles bytes because of + * Java's rules for upgrading values. + */ + static final public float parseFloat(int what) { // also handles byte + return (float)what; + } + + static final public float parseFloat(String what) { + return parseFloat(what, Float.NaN); + } + + static final public float parseFloat(String what, float otherwise) { + try { + return new Float(what).floatValue(); + } catch (NumberFormatException e) { } + + return otherwise; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + /* + static final public float[] parseFloat(boolean what[]) { + float floaties[] = new float[what.length]; + for (int i = 0; i < what.length; i++) { + floaties[i] = what[i] ? 1 : 0; + } + return floaties; + } + + static final public float[] parseFloat(char what[]) { + float floaties[] = new float[what.length]; + for (int i = 0; i < what.length; i++) { + floaties[i] = (char) what[i]; + } + return floaties; + } + */ + + static final public float[] parseByte(byte what[]) { + float floaties[] = new float[what.length]; + for (int i = 0; i < what.length; i++) { + floaties[i] = what[i]; + } + return floaties; + } + + static final public float[] parseFloat(int what[]) { + float floaties[] = new float[what.length]; + for (int i = 0; i < what.length; i++) { + floaties[i] = what[i]; + } + return floaties; + } + + static final public float[] parseFloat(String what[]) { + return parseFloat(what, 0); + } + + static final public float[] parseFloat(String what[], float missing) { + float output[] = new float[what.length]; + for (int i = 0; i < what.length; i++) { + try { + output[i] = new Float(what[i]).floatValue(); + } catch (NumberFormatException e) { + output[i] = missing; + } + } + return output; + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static final public String str(boolean x) { + return String.valueOf(x); + } + + static final public String str(byte x) { + return String.valueOf(x); + } + + static final public String str(char x) { + return String.valueOf(x); + } + + static final public String str(int x) { + return String.valueOf(x); + } + + static final public String str(float x) { + return String.valueOf(x); + } + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + static final public String[] str(boolean x[]) { + String s[] = new String[x.length]; + for (int i = 0; i < x.length; i++) s[i] = String.valueOf(x); + return s; + } + + static final public String[] str(byte x[]) { + String s[] = new String[x.length]; + for (int i = 0; i < x.length; i++) s[i] = String.valueOf(x); + return s; + } + + static final public String[] str(char x[]) { + String s[] = new String[x.length]; + for (int i = 0; i < x.length; i++) s[i] = String.valueOf(x); + return s; + } + + static final public String[] str(int x[]) { + String s[] = new String[x.length]; + for (int i = 0; i < x.length; i++) s[i] = String.valueOf(x); + return s; + } + + static final public String[] str(float x[]) { + String s[] = new String[x.length]; + for (int i = 0; i < x.length; i++) s[i] = String.valueOf(x); + return s; + } + + + ////////////////////////////////////////////////////////////// + + // INT NUMBER FORMATTING + + + /** + * Integer number formatter. + */ + static private NumberFormat int_nf; + static private int int_nf_digits; + static private boolean int_nf_commas; + + + static public String[] nf(int num[], int digits) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nf(num[i], digits); + } + return formatted; + } + + + static public String nf(int num, int digits) { + if ((int_nf != null) && + (int_nf_digits == digits) && + !int_nf_commas) { + return int_nf.format(num); + } + + int_nf = NumberFormat.getInstance(); + int_nf.setGroupingUsed(false); // no commas + int_nf_commas = false; + int_nf.setMinimumIntegerDigits(digits); + int_nf_digits = digits; + return int_nf.format(num); + } + + + static public String[] nfc(int num[]) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nfc(num[i]); + } + return formatted; + } + + + static public String nfc(int num) { + if ((int_nf != null) && + (int_nf_digits == 0) && + int_nf_commas) { + return int_nf.format(num); + } + + int_nf = NumberFormat.getInstance(); + int_nf.setGroupingUsed(true); + int_nf_commas = true; + int_nf.setMinimumIntegerDigits(0); + int_nf_digits = 0; + return int_nf.format(num); + } + + + /** + * number format signed (or space) + * Formats a number but leaves a blank space in the front + * when it's positive so that it can be properly aligned with + * numbers that have a negative sign in front of them. + */ + static public String nfs(int num, int digits) { + return (num < 0) ? nf(num, digits) : (' ' + nf(num, digits)); + } + + static public String[] nfs(int num[], int digits) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nfs(num[i], digits); + } + return formatted; + } + + // + + /** + * number format positive (or plus) + * Formats a number, always placing a - or + sign + * in the front when it's negative or positive. + */ + static public String nfp(int num, int digits) { + return (num < 0) ? nf(num, digits) : ('+' + nf(num, digits)); + } + + static public String[] nfp(int num[], int digits) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nfp(num[i], digits); + } + return formatted; + } + + + + ////////////////////////////////////////////////////////////// + + // FLOAT NUMBER FORMATTING + + + static private NumberFormat float_nf; + static private int float_nf_left, float_nf_right; + static private boolean float_nf_commas; + + + static public String[] nf(float num[], int left, int right) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nf(num[i], left, right); + } + return formatted; + } + + + static public String nf(float num, int left, int right) { + if ((float_nf != null) && + (float_nf_left == left) && + (float_nf_right == right) && + !float_nf_commas) { + return float_nf.format(num); + } + + float_nf = NumberFormat.getInstance(); + float_nf.setGroupingUsed(false); + float_nf_commas = false; + + if (left != 0) float_nf.setMinimumIntegerDigits(left); + if (right != 0) { + float_nf.setMinimumFractionDigits(right); + float_nf.setMaximumFractionDigits(right); + } + float_nf_left = left; + float_nf_right = right; + return float_nf.format(num); + } + + + static public String[] nfc(float num[], int right) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nfc(num[i], right); + } + return formatted; + } + + + static public String nfc(float num, int right) { + if ((float_nf != null) && + (float_nf_left == 0) && + (float_nf_right == right) && + float_nf_commas) { + return float_nf.format(num); + } + + float_nf = NumberFormat.getInstance(); + float_nf.setGroupingUsed(true); + float_nf_commas = true; + + if (right != 0) { + float_nf.setMinimumFractionDigits(right); + float_nf.setMaximumFractionDigits(right); + } + float_nf_left = 0; + float_nf_right = right; + return float_nf.format(num); + } + + + /** + * Number formatter that takes into account whether the number + * has a sign (positive, negative, etc) in front of it. + */ + static public String[] nfs(float num[], int left, int right) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nfs(num[i], left, right); + } + return formatted; + } + + static public String nfs(float num, int left, int right) { + return (num < 0) ? nf(num, left, right) : (' ' + nf(num, left, right)); + } + + + static public String[] nfp(float num[], int left, int right) { + String formatted[] = new String[num.length]; + for (int i = 0; i < formatted.length; i++) { + formatted[i] = nfp(num[i], left, right); + } + return formatted; + } + + static public String nfp(float num, int left, int right) { + return (num < 0) ? nf(num, left, right) : ('+' + nf(num, left, right)); + } + + + + ////////////////////////////////////////////////////////////// + + // HEX/BINARY CONVERSION + + + static final public String hex(byte what) { + return hex(what, 2); + } + + static final public String hex(char what) { + return hex(what, 4); + } + + static final public String hex(int what) { + return hex(what, 8); + } + + static final public String hex(int what, int digits) { + String stuff = Integer.toHexString(what).toUpperCase(); + + int length = stuff.length(); + if (length > digits) { + return stuff.substring(length - digits); + + } else if (length < digits) { + return "00000000".substring(8 - (digits-length)) + stuff; + } + return stuff; + } + + static final public int unhex(String what) { + // has to parse as a Long so that it'll work for numbers bigger than 2^31 + return (int) (Long.parseLong(what, 16)); + } + + // + + /** + * Returns a String that contains the binary value of a byte. + * The returned value will always have 8 digits. + */ + static final public String binary(byte what) { + return binary(what, 8); + } + + /** + * Returns a String that contains the binary value of a char. + * The returned value will always have 16 digits because chars + * are two bytes long. + */ + static final public String binary(char what) { + return binary(what, 16); + } + + /** + * Returns a String that contains the binary value of an int. + * The length depends on the size of the number itself. + * An int can be up to 32 binary digits, but that seems like + * overkill for almost any situation, so this function just + * auto-size. If you want a specific number of digits (like all 32) + * use binary(int what, int digits) to specify how many digits. + */ + static final public String binary(int what) { + return Integer.toBinaryString(what); + //return binary(what, 32); + } + + /** + * Returns a String that contains the binary value of an int. + * The digits parameter determines how many digits will be used. + */ + static final public String binary(int what, int digits) { + String stuff = Integer.toBinaryString(what); + + int length = stuff.length(); + if (length > digits) { + return stuff.substring(length - digits); + + } else if (length < digits) { + int offset = 32 - (digits-length); + return "00000000000000000000000000000000".substring(offset) + stuff; + } + return stuff; + } + + + /** + * Unpack a binary String into an int. + * i.e. unbinary("00001000") would return 8. + */ + static final public int unbinary(String what) { + return Integer.parseInt(what, 2); + } + + + + ////////////////////////////////////////////////////////////// + + // COLOR FUNCTIONS + + // moved here so that they can work without + // the graphics actually being instantiated (outside setup) + + + public final int color(int gray) { + if (g == null) { + if (gray > 255) gray = 255; else if (gray < 0) gray = 0; + return 0xff000000 | (gray << 16) | (gray << 8) | gray; + } + return g.color(gray); + } + + + public final int color(float fgray) { + if (g == null) { + int gray = (int) fgray; + if (gray > 255) gray = 255; else if (gray < 0) gray = 0; + return 0xff000000 | (gray << 16) | (gray << 8) | gray; + } + return g.color(fgray); + } + + + /** + * As of 0116 this also takes color(#FF8800, alpha) + */ + public final int color(int gray, int alpha) { + if (g == null) { + if (alpha > 255) alpha = 255; else if (alpha < 0) alpha = 0; + if (gray > 255) { + // then assume this is actually a #FF8800 + return (alpha << 24) | (gray & 0xFFFFFF); + } else { + //if (gray > 255) gray = 255; else if (gray < 0) gray = 0; + return (alpha << 24) | (gray << 16) | (gray << 8) | gray; + } + } + return g.color(gray, alpha); + } + + + public final int color(float fgray, float falpha) { + if (g == null) { + int gray = (int) fgray; + int alpha = (int) falpha; + if (gray > 255) gray = 255; else if (gray < 0) gray = 0; + if (alpha > 255) alpha = 255; else if (alpha < 0) alpha = 0; + return 0xff000000 | (gray << 16) | (gray << 8) | gray; + } + return g.color(fgray, falpha); + } + + + public final int color(int x, int y, int z) { + if (g == null) { + if (x > 255) x = 255; else if (x < 0) x = 0; + if (y > 255) y = 255; else if (y < 0) y = 0; + if (z > 255) z = 255; else if (z < 0) z = 0; + + return 0xff000000 | (x << 16) | (y << 8) | z; + } + return g.color(x, y, z); + } + + + public final int color(float x, float y, float z) { + if (g == null) { + if (x > 255) x = 255; else if (x < 0) x = 0; + if (y > 255) y = 255; else if (y < 0) y = 0; + if (z > 255) z = 255; else if (z < 0) z = 0; + + return 0xff000000 | ((int)x << 16) | ((int)y << 8) | (int)z; + } + return g.color(x, y, z); + } + + + public final int color(int x, int y, int z, int a) { + if (g == null) { + if (a > 255) a = 255; else if (a < 0) a = 0; + if (x > 255) x = 255; else if (x < 0) x = 0; + if (y > 255) y = 255; else if (y < 0) y = 0; + if (z > 255) z = 255; else if (z < 0) z = 0; + + return (a << 24) | (x << 16) | (y << 8) | z; + } + return g.color(x, y, z, a); + } + + + public final int color(float x, float y, float z, float a) { + if (g == null) { + if (a > 255) a = 255; else if (a < 0) a = 0; + if (x > 255) x = 255; else if (x < 0) x = 0; + if (y > 255) y = 255; else if (y < 0) y = 0; + if (z > 255) z = 255; else if (z < 0) z = 0; + + return ((int)a << 24) | ((int)x << 16) | ((int)y << 8) | (int)z; + } + return g.color(x, y, z, a); + } + + + + ////////////////////////////////////////////////////////////// + + // MAIN + + + private static class WorkerVar { + private Thread thread; + WorkerVar(Thread t) { thread = t; } + synchronized Thread get() { return thread; } + synchronized void clear() { thread = null; } + } + + /** + * Class to help external communication run as a separate class. + *

    + * From a software engineering standpoint, using the stderr stream + * is highly problematic because of its tendency to die or act + * funny, especially on Windows. Threading issues can cause the + * buffers to get full or the applet to not run properly. + * Formerly known as the "code folder bug", this has been fixed + * through the use of this class, however it remains a tenuous + * situation that could perhaps break in a future JDK release. + */ + class Worker { + private Object value; + private WorkerVar workerVar; + + protected synchronized Object getValue() { + return value; + } + + private synchronized void setValue(Object x) { + value = x; + } + + public Object construct() { + try { + int anything = System.in.read(); + if (anything == EXTERNAL_STOP) { + + // adding this for 0073.. need to stop libraries + // when the stop button is hit. + PApplet.this.stop(); + finished = true; + } + } catch (IOException e) { + finished = true; + } + try { + Thread.sleep(250); + //Thread.sleep(100); // kick up latency for 0075? + } catch (InterruptedException e) { } + return null; + } + + // removing this from SwingWorker + //public void finished() { } + + public void interrupt() { + Thread t = workerVar.get(); + if (t != null) { + t.interrupt(); + } + workerVar.clear(); + } + + public Object get() { + while (true) { + Thread t = workerVar.get(); + if (t == null) { + return getValue(); + } + try { + t.join(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); // propagate + return null; + } + } + } + + public Worker() { + // removing this from SwingWorker + //final Runnable doFinished = new Runnable() { + // public void run() { finished(); } + // }; + + Runnable doConstruct = new Runnable() { + public void run() { + try { + setValue(construct()); + + } finally { + workerVar.clear(); + } + // removing this from SwingWorker to avoid swing + //javax.swing.SwingUtilities.invokeLater(doFinished); + } + }; + + Thread t = new Thread(doConstruct); + workerVar = new WorkerVar(t); + } + + public void start() { + Thread t = workerVar.get(); + if (t != null) t.start(); + } + } + + + /** + * Set this sketch to communicate its state back to the PDE. + *

    + * This uses the stderr stream to write positions of the window + * (so that it will be saved by the PDE for the next run) and + * notify on quit. See more notes in the Worker class. + */ + public void setupExternalMessages() { //Frame parentFrame) { + //final Worker worker = new Worker(); + + //parentFrame.addComponentListener(new ComponentAdapter() { + frame.addComponentListener(new ComponentAdapter() { + public void componentMoved(ComponentEvent e) { + Point where = ((Frame) e.getSource()).getLocation(); + System.err.println(PApplet.EXTERNAL_MOVE + " " + + where.x + " " + where.y); + System.err.flush(); // doesn't seem to help or hurt + } + }); + + //parentFrame.addWindowListener(new WindowAdapter() { + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.err.println(PApplet.EXTERNAL_QUIT); + System.err.flush(); // important + System.exit(0); + } + }); + } + + + /** + * Set up a listener that will fire proper component resize events + * in cases where frame.setResizable(true) is called. + */ + public void setupFrameResizeListener() { + frame.addComponentListener(new ComponentAdapter() { + + public void componentResized(ComponentEvent e) { + // Ignore bad resize events fired during setup to fix + // http://dev.processing.org/bugs/show_bug.cgi?id=341 + // This should also fix the blank screen on Linux bug + // http://dev.processing.org/bugs/show_bug.cgi?id=282 + if (frame.isResizable()) { + // might be multiple resize calls before visible (i.e. first + // when pack() is called, then when it's resized for use). + // ignore them because it's not the user resizing things. + Frame farm = (Frame) e.getComponent(); + if (farm.isVisible()) { + Insets insets = farm.getInsets(); + Dimension windowSize = farm.getSize(); + int usableW = windowSize.width - insets.left - insets.right; + int usableH = windowSize.height - insets.top - insets.bottom; + + // the ComponentListener in PApplet will handle calling size() + setBounds(insets.left, insets.top, usableW, usableH); + } + } + } + }); + } + + + /** + * main() method for running this class from the command line. + *

    + * The options shown here are not yet finalized and will be + * changing over the next several releases. + *

    + * The simplest way to turn and applet into an application is to + * add the following code to your program: + *

    static public void main(String args[]) {
    +   *   PApplet.main(new String[] { "YourSketchName" });
    +   * }
    + * This will properly launch your applet from a double-clickable + * .jar or from the command line. + *
    +   * Parameters useful for launching or also used by the PDE:
    +   *
    +   * --location=x,y        upper-lefthand corner of where the applet
    +   *                       should appear on screen. if not used,
    +   *                       the default is to center on the main screen.
    +   *
    +   * --present             put the applet into full screen presentation
    +   *                       mode. requires java 1.4 or later.
    +   *
    +   * --hide-stop           use to hide the stop button in situations where
    +   *                       you don't want to allow users to exit. also
    +   *                       see the FAQ on information for capturing the ESC
    +   *                       key when running in presentation mode.
    +   *
    +   * --stop-color          color of the 'stop' text used to quit an
    +   *                       sketch when it's in present mode.
    +   *
    +   * --bgcolor=#xxxxxx     background color of the window.
    +   *
    +   * --sketch-path         location of where to save files from functions
    +   *                       like saveStrings() or saveFrame(). defaults to
    +   *                       the folder that the java application was
    +   *                       launched from, which means if this isn't set by
    +   *                       the pde, everything goes into the same folder
    +   *                       as processing.exe.
    +   *
    +   * --display=n           set what display should be used by this applet.
    +   *                       displays are numbered starting from 1.
    +   *
    +   *
    +   * Parameters used by Processing when running via the PDE
    +   *
    +   * --external            set when the applet is being used by the PDE
    +   *
    +   * --editor-location=x,y position of the upper-lefthand corner of the
    +   *                       editor window, for placement of applet window
    +   * 
    + */ + static public void main(String args[]) { + if (args.length < 1) { + System.err.println("Usage: PApplet "); + System.err.println("For additional options, " + + "see the javadoc for PApplet"); + System.exit(1); + } + + try { + // true if this sketch is being run by the PDE + boolean external = false; + int location[] = null; + int editorLocation[] = null; + + String name = null; + boolean present = false; + Color backgroundColor = Color.black; //BLACK; + Color stopColor = Color.gray; //GRAY; + GraphicsDevice displayDevice = null; + boolean hideStop = false; + + String param = null, value = null; + + // try to get the user folder. if running under java web start, + // this may cause a security exception if the code is not signed. + // http://processing.org/discourse/yabb_beta/YaBB.cgi?board=Integrate;action=display;num=1159386274 + String folder = null; + try { + folder = System.getProperty("user.dir"); + } catch (Exception e) { } + + int argIndex = 0; + while (argIndex < args.length) { + int equals = args[argIndex].indexOf('='); + if (equals != -1) { + param = args[argIndex].substring(0, equals); + value = args[argIndex].substring(equals + 1); + + if (param.equals(ARGS_EDITOR_LOCATION)) { + external = true; + editorLocation = parseInt(split(value, ',')); + + } else if (param.equals(ARGS_DISPLAY)) { + int deviceIndex = Integer.parseInt(value) - 1; + + //DisplayMode dm = device.getDisplayMode(); + //if ((dm.getWidth() == 1024) && (dm.getHeight() == 768)) { + + GraphicsEnvironment environment = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice devices[] = environment.getScreenDevices(); + if ((deviceIndex >= 0) && (deviceIndex < devices.length)) { + displayDevice = devices[deviceIndex]; + } else { + System.err.println("Display " + value + " does not exist, " + + "using the default display instead."); + } + + } else if (param.equals(ARGS_BGCOLOR)) { + if (value.charAt(0) == '#') value = value.substring(1); + backgroundColor = new Color(Integer.parseInt(value, 16)); + + } else if (param.equals(ARGS_STOP_COLOR)) { + if (value.charAt(0) == '#') value = value.substring(1); + stopColor = new Color(Integer.parseInt(value, 16)); + + } else if (param.equals(ARGS_SKETCH_FOLDER)) { + folder = value; + + } else if (param.equals(ARGS_LOCATION)) { + location = parseInt(split(value, ',')); + } + + } else { + if (args[argIndex].equals(ARGS_PRESENT)) { + present = true; + + } else if (args[argIndex].equals(ARGS_HIDE_STOP)) { + hideStop = true; + + } else if (args[argIndex].equals(ARGS_EXTERNAL)) { + external = true; + + } else { + name = args[argIndex]; + break; + } + } + argIndex++; + } + + if (displayDevice == null) { + GraphicsEnvironment environment = + GraphicsEnvironment.getLocalGraphicsEnvironment(); + displayDevice = environment.getDefaultScreenDevice(); + } + + Frame frame = new Frame(displayDevice.getDefaultConfiguration()); + /* + Frame frame = null; + if (displayDevice != null) { + frame = new Frame(displayDevice.getDefaultConfiguration()); + } else { + frame = new Frame(); + } + */ + + Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); + + // remove the grow box by default + // users who want it back can call frame.setResizable(true) + frame.setResizable(false); + + Class c = Class.forName(name); + PApplet applet = (PApplet) c.newInstance(); + + // these are needed before init/start + applet.frame = frame; + applet.sketchPath = folder; + applet.args = PApplet.subset(args, 1); + + applet.init(); + + // wait until the applet has figured out its width + // hoping that this won't hang if the applet has an exception + while (applet.defaultSize && !applet.finished) { + try { + Thread.sleep(5); + + } catch (InterruptedException e) { } + } + + if (present) { + frame.setUndecorated(true); + frame.setBackground(backgroundColor); + displayDevice.setFullScreenWindow(frame); + + frame.add(applet); + Dimension fullscreen = frame.getSize(); + applet.setBounds((fullscreen.width - applet.width) / 2, + (fullscreen.height - applet.height) / 2, + applet.width, applet.height); + + if (!hideStop) { + Label label = new Label("stop"); + label.setForeground(stopColor); + label.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + System.exit(0); + } + }); + frame.add(label); + + Dimension labelSize = label.getPreferredSize(); + // sometimes shows up truncated on mac + //System.out.println("label width is " + labelSize.width); + labelSize = new Dimension(100, labelSize.height); + label.setSize(labelSize); + label.setLocation(20, fullscreen.height - labelSize.height - 20); + } + + // not always running externally when in present mode + if (external) { + applet.setupExternalMessages(); + } + + } else { // if not presenting + // can't do pack earlier cuz present mode don't like it + // (can't go full screen with a frame after calling pack) + frame.pack(); // get insets. get more. + Insets insets = frame.getInsets(); + + int windowW = Math.max(applet.width, MIN_WINDOW_WIDTH) + + insets.left + insets.right; + int windowH = Math.max(applet.height, MIN_WINDOW_HEIGHT) + + insets.top + insets.bottom; + + frame.setSize(windowW, windowH); + + if (location != null) { + // a specific location was received from PdeRuntime + // (applet has been run more than once, user placed window) + frame.setLocation(location[0], location[1]); + + } else if (external) { + int locationX = editorLocation[0] - 20; + int locationY = editorLocation[1]; + + if (locationX - windowW > 10) { + // if it fits to the left of the window + frame.setLocation(locationX - windowW, locationY); + + } else { // doesn't fit + // if it fits inside the editor window, + // offset slightly from upper lefthand corner + // so that it's plunked inside the text area + locationX = editorLocation[0] + 66; + locationY = editorLocation[1] + 66; + + if ((locationX + windowW > screen.width - 33) || + (locationY + windowH > screen.height - 33)) { + // otherwise center on screen + locationX = (screen.width - windowW) / 2; + locationY = (screen.height - windowH) / 2; + } + frame.setLocation(locationX, locationY); + } + } else { // just center on screen + frame.setLocation((screen.width - applet.width) / 2, + (screen.height - applet.height) / 2); + } + + frame.setLayout(null); + frame.add(applet); + + if (backgroundColor == Color.black) { //BLACK) { + // this means no bg color unless specified + backgroundColor = SystemColor.control; + } + frame.setBackground(backgroundColor); + + int usableWindowH = windowH - insets.top - insets.bottom; + applet.setBounds((windowW - applet.width)/2, + insets.top + (usableWindowH - applet.height)/2, + applet.width, applet.height); + + if (external) { + applet.setupExternalMessages(); + + } else { // !external + frame.addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent e) { + System.exit(0); + } + }); + } + + // handle frame resizing events + applet.setupFrameResizeListener(); + + // all set for rockin + if (applet.displayable()) { + frame.setVisible(true); + } + } + + //System.out.println("showing frame"); + //System.out.println("applet requesting focus"); + applet.requestFocus(); // ask for keydowns + //System.out.println("exiting main()"); + + } catch (Exception e) { + e.printStackTrace(); + System.exit(1); + } + } + + + ////////////////////////////////////////////////////////////// + + + public PGraphics beginRecord(String renderer, String filename) { + filename = insertFrame(filename); + //filename = savePath(filename); + PGraphics rec = createGraphics(width, height, renderer, filename); + beginRecord(rec); + return rec; + } + + + public void beginRecord(PGraphics recorder) { + this.recorder = recorder; + recorder.beginDraw(); + } + + + public void endRecord() { + //println("endRecord()"); + //if (!recorderNull) { + if (recorder != null) { + //recorder.endRecord(); + recorder.endDraw(); + recorder.dispose(); + recorder = null; + } + } + + + public PGraphics beginRaw(String renderer, String filename) { + filename = insertFrame(filename); + //filename = savePath(filename); // ensure an absolute path + PGraphics rec = createGraphics(width, height, renderer, filename); + //g.recordRaw(rec); + g.beginRaw(rec); + return rec; + } + + + /** + * Check a string for #### signs to see if the frame number should be + * inserted. Used for functions like saveFrame() and beginRecord() to + * replace the # marks with the frame number. If only one # is used, + * it will be ignored, under the assumption that it's probably not + * intended to be the frame number. + */ + public String insertFrame(String what) { + int first = what.indexOf('#'); + int last = what.lastIndexOf('#'); + + if ((first != -1) && (last - first > 0)) { + String prefix = what.substring(0, first); + int count = last - first + 1; + String suffix = what.substring(last + 1); + return prefix + nf(frameCount, count) + suffix; + } + return what; // no change + } + + + ////////////////////////////////////////////////////////////// + + + /** + * Override the g.pixels[] function to set the pixels[] array + * that's part of the PApplet object. Allows the use of + * pixels[] in the code, rather than g.pixels[]. + */ + public void loadPixels() { + g.loadPixels(); + pixels = g.pixels; + } + + + ////////////////////////////////////////////////////////////// + + // everything below this line is automatically generated. no touch. + // public functions for processing.core + + + public void imageMode(int mode) { + if (recorder != null) recorder.imageMode(mode); + g.imageMode(mode); + } + + + public void smooth() { + if (recorder != null) recorder.smooth(); + g.smooth(); + } + + + public void noSmooth() { + if (recorder != null) recorder.noSmooth(); + g.noSmooth(); + } + + + public void updatePixels() { + if (recorder != null) recorder.updatePixels(); + g.updatePixels(); + } + + + public void updatePixels(int x1, int y1, int x2, int y2) { + if (recorder != null) recorder.updatePixels(x1, y1, x2, y2); + g.updatePixels(x1, y1, x2, y2); + } + + + public int get(int x, int y) { + return g.get(x, y); + } + + + public PImage get(int x, int y, int w, int h) { + return g.get(x, y, w, h); + } + + + public PImage get() { + return g.get(); + } + + + public void set(int x, int y, int c) { + if (recorder != null) recorder.set(x, y, c); + g.set(x, y, c); + } + + + public void set(int dx, int dy, PImage src) { + if (recorder != null) recorder.set(dx, dy, src); + g.set(dx, dy, src); + } + + + public void mask(int alpha[]) { + if (recorder != null) recorder.mask(alpha); + g.mask(alpha); + } + + + public void mask(PImage alpha) { + if (recorder != null) recorder.mask(alpha); + g.mask(alpha); + } + + + public void filter(int kind) { + if (recorder != null) recorder.filter(kind); + g.filter(kind); + } + + + public void filter(int kind, float param) { + if (recorder != null) recorder.filter(kind, param); + g.filter(kind, param); + } + + + public void copy(int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2) { + if (recorder != null) recorder.copy(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); + g.copy(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); + } + + + public void copy(PImage src, + int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2) { + if (recorder != null) recorder.copy(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); + g.copy(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); + } + + + static public int blendColor(int c1, int c2, int mode) { + return PGraphics.blendColor(c1, c2, mode); + } + + + public void blend(int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + if (recorder != null) recorder.blend(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); + g.blend(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); + } + + + public void blend(PImage src, + int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + if (recorder != null) recorder.blend(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); + g.blend(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); + } + + + public void hint(int which) { + if (recorder != null) recorder.hint(which); + g.hint(which); + } + + + public void noHint(int which) { + if (recorder != null) recorder.noHint(which); + g.noHint(which); + } + + + public void beginShape() { + if (recorder != null) recorder.beginShape(); + g.beginShape(); + } + + + public void beginShape(int kind) { + if (recorder != null) recorder.beginShape(kind); + g.beginShape(kind); + } + + + public void normal(float nx, float ny, float nz) { + if (recorder != null) recorder.normal(nx, ny, nz); + g.normal(nx, ny, nz); + } + + + public void textureMode(int mode) { + if (recorder != null) recorder.textureMode(mode); + g.textureMode(mode); + } + + + public void texture(PImage image) { + if (recorder != null) recorder.texture(image); + g.texture(image); + } + + + public void vertex(float x, float y) { + if (recorder != null) recorder.vertex(x, y); + g.vertex(x, y); + } + + + public void vertex(float x, float y, float z) { + if (recorder != null) recorder.vertex(x, y, z); + g.vertex(x, y, z); + } + + + public void vertex(float x, float y, float u, float v) { + if (recorder != null) recorder.vertex(x, y, u, v); + g.vertex(x, y, u, v); + } + + + public void vertex(float x, float y, float z, float u, float v) { + if (recorder != null) recorder.vertex(x, y, z, u, v); + g.vertex(x, y, z, u, v); + } + + + public void bezierVertex(float x2, float y2, + float x3, float y3, + float x4, float y4) { + if (recorder != null) recorder.bezierVertex(x2, y2, x3, y3, x4, y4); + g.bezierVertex(x2, y2, x3, y3, x4, y4); + } + + + public void bezierVertex(float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + if (recorder != null) recorder.bezierVertex(x2, y2, z2, x3, y3, z3, x4, y4, z4); + g.bezierVertex(x2, y2, z2, x3, y3, z3, x4, y4, z4); + } + + + public void curveVertex(float x, float y) { + if (recorder != null) recorder.curveVertex(x, y); + g.curveVertex(x, y); + } + + + public void curveVertex(float x, float y, float z) { + if (recorder != null) recorder.curveVertex(x, y, z); + g.curveVertex(x, y, z); + } + + + public void breakShape() { + if (recorder != null) recorder.breakShape(); + g.breakShape(); + } + + + public final void endShape() { + if (recorder != null) recorder.endShape(); + g.endShape(); + } + + + public void endShape(int mode) { + if (recorder != null) recorder.endShape(mode); + g.endShape(mode); + } + + + public void point(float x, float y) { + if (recorder != null) recorder.point(x, y); + g.point(x, y); + } + + + public void point(float x, float y, float z) { + if (recorder != null) recorder.point(x, y, z); + g.point(x, y, z); + } + + + public void line(float x1, float y1, float x2, float y2) { + if (recorder != null) recorder.line(x1, y1, x2, y2); + g.line(x1, y1, x2, y2); + } + + + public void line(float x1, float y1, float z1, + float x2, float y2, float z2) { + if (recorder != null) recorder.line(x1, y1, z1, x2, y2, z2); + g.line(x1, y1, z1, x2, y2, z2); + } + + + public void triangle(float x1, float y1, float x2, float y2, + float x3, float y3) { + if (recorder != null) recorder.triangle(x1, y1, x2, y2, x3, y3); + g.triangle(x1, y1, x2, y2, x3, y3); + } + + + public void quad(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { + if (recorder != null) recorder.quad(x1, y1, x2, y2, x3, y3, x4, y4); + g.quad(x1, y1, x2, y2, x3, y3, x4, y4); + } + + + public void rectMode(int mode) { + if (recorder != null) recorder.rectMode(mode); + g.rectMode(mode); + } + + + public void rect(float x1, float y1, float x2, float y2) { + if (recorder != null) recorder.rect(x1, y1, x2, y2); + g.rect(x1, y1, x2, y2); + } + + + public void ellipseMode(int mode) { + if (recorder != null) recorder.ellipseMode(mode); + g.ellipseMode(mode); + } + + + public void ellipse(float a, float b, float c, float d) { + if (recorder != null) recorder.ellipse(a, b, c, d); + g.ellipse(a, b, c, d); + } + + + public void arc(float a, float b, float c, float d, + float start, float stop) { + if (recorder != null) recorder.arc(a, b, c, d, start, stop); + g.arc(a, b, c, d, start, stop); + } + + + public void box(float size) { + if (recorder != null) recorder.box(size); + g.box(size); + } + + + public void box(float w, float h, float d) { + if (recorder != null) recorder.box(w, h, d); + g.box(w, h, d); + } + + + public void sphereDetail(int res) { + if (recorder != null) recorder.sphereDetail(res); + g.sphereDetail(res); + } + + + public void sphere(float r) { + if (recorder != null) recorder.sphere(r); + g.sphere(r); + } + + + public float bezierPoint(float a, float b, float c, float d, float t) { + return g.bezierPoint(a, b, c, d, t); + } + + + public float bezierTangent(float a, float b, float c, float d, float t) { + return g.bezierTangent(a, b, c, d, t); + } + + + public void bezierDetail(int detail) { + if (recorder != null) recorder.bezierDetail(detail); + g.bezierDetail(detail); + } + + + public void bezier(float x1, float y1, + float x2, float y2, + float x3, float y3, + float x4, float y4) { + if (recorder != null) recorder.bezier(x1, y1, x2, y2, x3, y3, x4, y4); + g.bezier(x1, y1, x2, y2, x3, y3, x4, y4); + } + + + public void bezier(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + if (recorder != null) recorder.bezier(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4); + g.bezier(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4); + } + + + public float curvePoint(float a, float b, float c, float d, float t) { + return g.curvePoint(a, b, c, d, t); + } + + + public float curveTangent(float a, float b, float c, float d, + float t) { + return g.curveTangent(a, b, c, d, t); + } + + + public void curveDetail(int detail) { + if (recorder != null) recorder.curveDetail(detail); + g.curveDetail(detail); + } + + + public void curveTightness(float tightness) { + if (recorder != null) recorder.curveTightness(tightness); + g.curveTightness(tightness); + } + + + public void curve(float x1, float y1, + float x2, float y2, + float x3, float y3, + float x4, float y4) { + if (recorder != null) recorder.curve(x1, y1, x2, y2, x3, y3, x4, y4); + g.curve(x1, y1, x2, y2, x3, y3, x4, y4); + } + + + public void curve(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + if (recorder != null) recorder.curve(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4); + g.curve(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4); + } + + + public void image(PImage image, float x, float y) { + if (recorder != null) recorder.image(image, x, y); + g.image(image, x, y); + } + + + public void image(PImage image, + float x, float y, float c, float d) { + if (recorder != null) recorder.image(image, x, y, c, d); + g.image(image, x, y, c, d); + } + + + public void image(PImage image, + float a, float b, float c, float d, + int u1, int v1, int u2, int v2) { + if (recorder != null) recorder.image(image, a, b, c, d, u1, v1, u2, v2); + g.image(image, a, b, c, d, u1, v1, u2, v2); + } + + + public void textAlign(int align) { + if (recorder != null) recorder.textAlign(align); + g.textAlign(align); + } + + + public void textAlign(int alignX, int alignY) { + if (recorder != null) recorder.textAlign(alignX, alignY); + g.textAlign(alignX, alignY); + } + + + public float textAscent() { + return g.textAscent(); + } + + + public float textDescent() { + return g.textDescent(); + } + + + public void textFont(PFont which) { + if (recorder != null) recorder.textFont(which); + g.textFont(which); + } + + + public void textFont(PFont which, float size) { + if (recorder != null) recorder.textFont(which, size); + g.textFont(which, size); + } + + + public void textLeading(float leading) { + if (recorder != null) recorder.textLeading(leading); + g.textLeading(leading); + } + + + public void textMode(int mode) { + if (recorder != null) recorder.textMode(mode); + g.textMode(mode); + } + + + public void textSize(float size) { + if (recorder != null) recorder.textSize(size); + g.textSize(size); + } + + + public float textWidth(char c) { + return g.textWidth(c); + } + + + public float textWidth(String str) { + return g.textWidth(str); + } + + + public void text(char c) { + if (recorder != null) recorder.text(c); + g.text(c); + } + + + public void text(char c, float x, float y) { + if (recorder != null) recorder.text(c, x, y); + g.text(c, x, y); + } + + + public void text(char c, float x, float y, float z) { + if (recorder != null) recorder.text(c, x, y, z); + g.text(c, x, y, z); + } + + + public void text(String str) { + if (recorder != null) recorder.text(str); + g.text(str); + } + + + public void text(String str, float x, float y) { + if (recorder != null) recorder.text(str, x, y); + g.text(str, x, y); + } + + + public void text(String str, float x, float y, float z) { + if (recorder != null) recorder.text(str, x, y, z); + g.text(str, x, y, z); + } + + + public void text(String str, float x1, float y1, float x2, float y2) { + if (recorder != null) recorder.text(str, x1, y1, x2, y2); + g.text(str, x1, y1, x2, y2); + } + + + public void text(String s, float x1, float y1, float x2, float y2, float z) { + if (recorder != null) recorder.text(s, x1, y1, x2, y2, z); + g.text(s, x1, y1, x2, y2, z); + } + + + public void text(int num, float x, float y) { + if (recorder != null) recorder.text(num, x, y); + g.text(num, x, y); + } + + + public void text(int num, float x, float y, float z) { + if (recorder != null) recorder.text(num, x, y, z); + g.text(num, x, y, z); + } + + + public void text(float num, float x, float y) { + if (recorder != null) recorder.text(num, x, y); + g.text(num, x, y); + } + + + public void text(float num, float x, float y, float z) { + if (recorder != null) recorder.text(num, x, y, z); + g.text(num, x, y, z); + } + + + public void translate(float tx, float ty) { + if (recorder != null) recorder.translate(tx, ty); + g.translate(tx, ty); + } + + + public void translate(float tx, float ty, float tz) { + if (recorder != null) recorder.translate(tx, ty, tz); + g.translate(tx, ty, tz); + } + + + public void rotate(float angle) { + if (recorder != null) recorder.rotate(angle); + g.rotate(angle); + } + + + public void rotateX(float angle) { + if (recorder != null) recorder.rotateX(angle); + g.rotateX(angle); + } + + + public void rotateY(float angle) { + if (recorder != null) recorder.rotateY(angle); + g.rotateY(angle); + } + + + public void rotateZ(float angle) { + if (recorder != null) recorder.rotateZ(angle); + g.rotateZ(angle); + } + + + public void rotate(float angle, float vx, float vy, float vz) { + if (recorder != null) recorder.rotate(angle, vx, vy, vz); + g.rotate(angle, vx, vy, vz); + } + + + public void scale(float s) { + if (recorder != null) recorder.scale(s); + g.scale(s); + } + + + public void scale(float sx, float sy) { + if (recorder != null) recorder.scale(sx, sy); + g.scale(sx, sy); + } + + + public void scale(float x, float y, float z) { + if (recorder != null) recorder.scale(x, y, z); + g.scale(x, y, z); + } + + + public void pushMatrix() { + if (recorder != null) recorder.pushMatrix(); + g.pushMatrix(); + } + + + public void popMatrix() { + if (recorder != null) recorder.popMatrix(); + g.popMatrix(); + } + + + public void resetMatrix() { + if (recorder != null) recorder.resetMatrix(); + g.resetMatrix(); + } + + + public void applyMatrix(float n00, float n01, float n02, + float n10, float n11, float n12) { + if (recorder != null) recorder.applyMatrix(n00, n01, n02, n10, n11, n12); + g.applyMatrix(n00, n01, n02, n10, n11, n12); + } + + + public void applyMatrix(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + if (recorder != null) recorder.applyMatrix(n00, n01, n02, n03, n10, n11, n12, n13, n20, n21, n22, n23, n30, n31, n32, n33); + g.applyMatrix(n00, n01, n02, n03, n10, n11, n12, n13, n20, n21, n22, n23, n30, n31, n32, n33); + } + + + public void loadMatrix() { + if (recorder != null) recorder.loadMatrix(); + g.loadMatrix(); + } + + + public void printMatrix() { + if (recorder != null) recorder.printMatrix(); + g.printMatrix(); + } + + + public void beginCamera() { + if (recorder != null) recorder.beginCamera(); + g.beginCamera(); + } + + + public void endCamera() { + if (recorder != null) recorder.endCamera(); + g.endCamera(); + } + + + public void camera() { + if (recorder != null) recorder.camera(); + g.camera(); + } + + + public void camera(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) { + if (recorder != null) recorder.camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); + g.camera(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ); + } + + + public void printCamera() { + if (recorder != null) recorder.printCamera(); + g.printCamera(); + } + + + public void ortho() { + if (recorder != null) recorder.ortho(); + g.ortho(); + } + + + public void ortho(float left, float right, + float bottom, float top, + float near, float far) { + if (recorder != null) recorder.ortho(left, right, bottom, top, near, far); + g.ortho(left, right, bottom, top, near, far); + } + + + public void perspective() { + if (recorder != null) recorder.perspective(); + g.perspective(); + } + + + public void perspective(float fovy, float aspect, float zNear, float zFar) { + if (recorder != null) recorder.perspective(fovy, aspect, zNear, zFar); + g.perspective(fovy, aspect, zNear, zFar); + } + + + public void frustum(float left, float right, float bottom, + float top, float znear, float zfar) { + if (recorder != null) recorder.frustum(left, right, bottom, top, znear, zfar); + g.frustum(left, right, bottom, top, znear, zfar); + } + + + public void printProjection() { + if (recorder != null) recorder.printProjection(); + g.printProjection(); + } + + + public float screenX(float x, float y) { + return g.screenX(x, y); + } + + + public float screenY(float x, float y) { + return g.screenY(x, y); + } + + + public float screenX(float x, float y, float z) { + return g.screenX(x, y, z); + } + + + public float screenY(float x, float y, float z) { + return g.screenY(x, y, z); + } + + + public float screenZ(float x, float y, float z) { + return g.screenZ(x, y, z); + } + + + public float modelX(float x, float y, float z) { + return g.modelX(x, y, z); + } + + + public float modelY(float x, float y, float z) { + return g.modelY(x, y, z); + } + + + public float modelZ(float x, float y, float z) { + return g.modelZ(x, y, z); + } + + + public void colorMode(int mode) { + if (recorder != null) recorder.colorMode(mode); + g.colorMode(mode); + } + + + public void colorMode(int mode, float max) { + if (recorder != null) recorder.colorMode(mode, max); + g.colorMode(mode, max); + } + + + public void colorMode(int mode, + float maxX, float maxY, float maxZ) { + if (recorder != null) recorder.colorMode(mode, maxX, maxY, maxZ); + g.colorMode(mode, maxX, maxY, maxZ); + } + + + public void colorMode(int mode, + float maxX, float maxY, float maxZ, float maxA) { + if (recorder != null) recorder.colorMode(mode, maxX, maxY, maxZ, maxA); + g.colorMode(mode, maxX, maxY, maxZ, maxA); + } + + + public void strokeWeight(float weight) { + if (recorder != null) recorder.strokeWeight(weight); + g.strokeWeight(weight); + } + + + public void strokeJoin(int join) { + if (recorder != null) recorder.strokeJoin(join); + g.strokeJoin(join); + } + + + public void strokeCap(int cap) { + if (recorder != null) recorder.strokeCap(cap); + g.strokeCap(cap); + } + + + public void noStroke() { + if (recorder != null) recorder.noStroke(); + g.noStroke(); + } + + + public void stroke(int rgb) { + if (recorder != null) recorder.stroke(rgb); + g.stroke(rgb); + } + + + public void stroke(int rgb, float alpha) { + if (recorder != null) recorder.stroke(rgb, alpha); + g.stroke(rgb, alpha); + } + + + public void stroke(float gray) { + if (recorder != null) recorder.stroke(gray); + g.stroke(gray); + } + + + public void stroke(float gray, float alpha) { + if (recorder != null) recorder.stroke(gray, alpha); + g.stroke(gray, alpha); + } + + + public void stroke(float x, float y, float z) { + if (recorder != null) recorder.stroke(x, y, z); + g.stroke(x, y, z); + } + + + public void stroke(float x, float y, float z, float a) { + if (recorder != null) recorder.stroke(x, y, z, a); + g.stroke(x, y, z, a); + } + + + public void noTint() { + if (recorder != null) recorder.noTint(); + g.noTint(); + } + + + public void tint(int rgb) { + if (recorder != null) recorder.tint(rgb); + g.tint(rgb); + } + + + public void tint(int rgb, float alpha) { + if (recorder != null) recorder.tint(rgb, alpha); + g.tint(rgb, alpha); + } + + + public void tint(float gray) { + if (recorder != null) recorder.tint(gray); + g.tint(gray); + } + + + public void tint(float gray, float alpha) { + if (recorder != null) recorder.tint(gray, alpha); + g.tint(gray, alpha); + } + + + public void tint(float x, float y, float z) { + if (recorder != null) recorder.tint(x, y, z); + g.tint(x, y, z); + } + + + public void tint(float x, float y, float z, float a) { + if (recorder != null) recorder.tint(x, y, z, a); + g.tint(x, y, z, a); + } + + + public void noFill() { + if (recorder != null) recorder.noFill(); + g.noFill(); + } + + + public void fill(int rgb) { + if (recorder != null) recorder.fill(rgb); + g.fill(rgb); + } + + + public void fill(int rgb, float alpha) { + if (recorder != null) recorder.fill(rgb, alpha); + g.fill(rgb, alpha); + } + + + public void fill(float gray) { + if (recorder != null) recorder.fill(gray); + g.fill(gray); + } + + + public void fill(float gray, float alpha) { + if (recorder != null) recorder.fill(gray, alpha); + g.fill(gray, alpha); + } + + + public void fill(float x, float y, float z) { + if (recorder != null) recorder.fill(x, y, z); + g.fill(x, y, z); + } + + + public void fill(float x, float y, float z, float a) { + if (recorder != null) recorder.fill(x, y, z, a); + g.fill(x, y, z, a); + } + + + public void ambient(int rgb) { + if (recorder != null) recorder.ambient(rgb); + g.ambient(rgb); + } + + + public void ambient(float gray) { + if (recorder != null) recorder.ambient(gray); + g.ambient(gray); + } + + + public void ambient(float x, float y, float z) { + if (recorder != null) recorder.ambient(x, y, z); + g.ambient(x, y, z); + } + + + public void specular(int rgb) { + if (recorder != null) recorder.specular(rgb); + g.specular(rgb); + } + + + public void specular(float gray) { + if (recorder != null) recorder.specular(gray); + g.specular(gray); + } + + + public void specular(float gray, float alpha) { + if (recorder != null) recorder.specular(gray, alpha); + g.specular(gray, alpha); + } + + + public void specular(float x, float y, float z) { + if (recorder != null) recorder.specular(x, y, z); + g.specular(x, y, z); + } + + + public void specular(float x, float y, float z, float a) { + if (recorder != null) recorder.specular(x, y, z, a); + g.specular(x, y, z, a); + } + + + public void shininess(float shine) { + if (recorder != null) recorder.shininess(shine); + g.shininess(shine); + } + + + public void emissive(int rgb) { + if (recorder != null) recorder.emissive(rgb); + g.emissive(rgb); + } + + + public void emissive(float gray) { + if (recorder != null) recorder.emissive(gray); + g.emissive(gray); + } + + + public void emissive(float x, float y, float z ) { + if (recorder != null) recorder.emissive(x, y, z); + g.emissive(x, y, z); + } + + + public void lights() { + if (recorder != null) recorder.lights(); + g.lights(); + } + + + public void ambientLight(float red, float green, float blue) { + if (recorder != null) recorder.ambientLight(red, green, blue); + g.ambientLight(red, green, blue); + } + + + public void ambientLight(float red, float green, float blue, + float x, float y, float z) { + if (recorder != null) recorder.ambientLight(red, green, blue, x, y, z); + g.ambientLight(red, green, blue, x, y, z); + } + + + public void directionalLight(float red, float green, float blue, + float nx, float ny, float nz) { + if (recorder != null) recorder.directionalLight(red, green, blue, nx, ny, nz); + g.directionalLight(red, green, blue, nx, ny, nz); + } + + + public void pointLight(float red, float green, float blue, + float x, float y, float z) { + if (recorder != null) recorder.pointLight(red, green, blue, x, y, z); + g.pointLight(red, green, blue, x, y, z); + } + + + public void spotLight(float red, float green, float blue, + float x, float y, float z, + float nx, float ny, float nz, + float angle, float concentration) { + if (recorder != null) recorder.spotLight(red, green, blue, x, y, z, nx, ny, nz, angle, concentration); + g.spotLight(red, green, blue, x, y, z, nx, ny, nz, angle, concentration); + } + + + public void lightFalloff(float constant, float linear, float quadratic) { + if (recorder != null) recorder.lightFalloff(constant, linear, quadratic); + g.lightFalloff(constant, linear, quadratic); + } + + + public void lightSpecular(float x, float y, float z) { + if (recorder != null) recorder.lightSpecular(x, y, z); + g.lightSpecular(x, y, z); + } + + + public void background(int rgb) { + if (recorder != null) recorder.background(rgb); + g.background(rgb); + } + + + public void background(int rgb, float alpha) { + if (recorder != null) recorder.background(rgb, alpha); + g.background(rgb, alpha); + } + + + public void background(float gray) { + if (recorder != null) recorder.background(gray); + g.background(gray); + } + + + public void background(float gray, float alpha) { + if (recorder != null) recorder.background(gray, alpha); + g.background(gray, alpha); + } + + + public void background(float x, float y, float z) { + if (recorder != null) recorder.background(x, y, z); + g.background(x, y, z); + } + + + public void background(float x, float y, float z, float a) { + if (recorder != null) recorder.background(x, y, z, a); + g.background(x, y, z, a); + } + + + public void background(PImage image) { + if (recorder != null) recorder.background(image); + g.background(image); + } + + + public final float alpha(int what) { + return g.alpha(what); + } + + + public final float red(int what) { + return g.red(what); + } + + + public final float green(int what) { + return g.green(what); + } + + + public final float blue(int what) { + return g.blue(what); + } + + + public final float hue(int what) { + return g.hue(what); + } + + + public final float saturation(int what) { + return g.saturation(what); + } + + + public final float brightness(int what) { + return g.brightness(what); + } + + + public int lerpColor(int c1, int c2, float amt) { + return g.lerpColor(c1, c2, amt); + } + + + static public int lerpColor(int c1, int c2, float amt, int mode) { + return PGraphics.lerpColor(c1, c2, amt, mode); + } + + + public void beginRaw(PGraphics rawGraphics) { + if (recorder != null) recorder.beginRaw(rawGraphics); + g.beginRaw(rawGraphics); + } + + + public void endRaw() { + if (recorder != null) recorder.endRaw(); + g.endRaw(); + } + + + public boolean displayable() { + return g.displayable(); + } +} diff --git a/core/PConstants.java b/core/PConstants.java new file mode 100644 index 000000000..082794b2f --- /dev/null +++ b/core/PConstants.java @@ -0,0 +1,322 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.Cursor; +import java.awt.event.KeyEvent; + + +/** + * Numbers shared throughout processing.core. + *

    + * An attempt is made to keep the constants as short/non-verbose + * as possible. For instance, the constant is TIFF instead of + * FILE_TYPE_TIFF. We'll do this as long as we can get away with it. + */ +public interface PConstants { + + // renderers known to processing.core + + static final String P2D = "processing.core.PGraphics2D"; + static final String P3D = "processing.core.PGraphics3D"; + static final String JAVA2D = "processing.core.PGraphicsJava2D"; + static final String OPENGL = "processing.opengl.PGraphicsOpenGL"; + static final String PDF = "processing.pdf.PGraphicsPDF"; + static final String DXF = "processing.dxf.RawDXF"; + //static final String SVG = "processing.dxf.PGraphicsSVG"; + + + // platform IDs for PApplet.platform + + static final int WINDOWS = 1; + static final int MACOS9 = 2; + static final int MACOSX = 3; + static final int LINUX = 4; + static final int OTHER = 0; + + + // for better parity between c++ version (at no speed cost) + + static final float EPSILON = 0.0001f; + // was around for auto-port to mobile version + //static final float ONE = 1.0f; + + + // useful goodness + + static final float PI = (float) Math.PI; + static final float HALF_PI = PI / 2.0f; + static final float THIRD_PI = PI / 3.0f; + static final float QUARTER_PI = PI / 4.0f; + static final float TWO_PI = PI * 2.0f; + + static final float DEG_TO_RAD = PI/180.0f; + static final float RAD_TO_DEG = 180.0f/PI; + + + // angle modes + + //static final int RADIANS = 0; + //static final int DEGREES = 1; + + + // used by split, all the standard whitespace chars + // (also includes unicode nbsp, that little bostage) + + static final String WHITESPACE = " \t\n\r\f\u00A0"; + + + // for colors and/or images + + static final int RGB = 1; // image & color + static final int ARGB = 2; // image + static final int HSB = 3; // color + static final int ALPHA = 4; // image + + + // image file types + + static final int TIFF = 0; + static final int TARGA = 1; + static final int JPEG = 2; + static final int GIF = 3; + + + // filter/convert types + + static final int BLUR = 11; + static final int GRAY = 12; + static final int INVERT = 13; + static final int OPAQUE = 14; + static final int POSTERIZE = 15; + static final int THRESHOLD = 16; + static final int ERODE = 17; + static final int DILATE = 18; + + + // blend mode keyword definitions + // @see processing.core.PImage#blendColor(int,int,int) + + public final static int REPLACE = 0; + public final static int BLEND = 1 << 0; + public final static int ADD = 1 << 1; + public final static int SUBTRACT = 1 << 2; + public final static int LIGHTEST = 1 << 3; + public final static int DARKEST = 1 << 4; + public final static int DIFFERENCE = 1 << 5; + public final static int EXCLUSION = 1 << 6; + public final static int MULTIPLY = 1 << 7; + public final static int SCREEN = 1 << 8; + public final static int OVERLAY = 1 << 9; + public final static int HARD_LIGHT = 1 << 10; + public final static int SOFT_LIGHT = 1 << 11; + public final static int DODGE = 1 << 12; + public final static int BURN = 1 << 13; + + // colour component bitmasks + + public static final int ALPHA_MASK = 0xff000000; + public static final int RED_MASK = 0x00ff0000; + public static final int GREEN_MASK = 0x0000ff00; + public static final int BLUE_MASK = 0x000000ff; + + + // for messages + + static final int CHATTER = 0; + static final int COMPLAINT = 1; + static final int PROBLEM = 2; + + + // types of projection matrices + + static final int CUSTOM = 0; // user-specified fanciness + static final int ORTHOGRAPHIC = 2; // 2D isometric projection + static final int PERSPECTIVE = 3; // perspective matrix + + + // rendering settings + + static final float PIXEL_CENTER = 0.5f; // for polygon aa + + + // shapes + + // the low four bits set the variety, + // higher bits set the specific shape type + + static final int POINTS = (1 << 4) | 0; + + static final int LINES = (1 << 5) | 0; + //static final int LINE_STRIP = (1 << 5) | 1; + //static final int LINE_LOOP = (1 << 5) | 2; + + static final int TRIANGLES = (1 << 6) | 0; + static final int TRIANGLE_STRIP = (1 << 6) | 1; + static final int TRIANGLE_FAN = (1 << 6) | 2; + + static final int QUADS = (1 << 7) | 0; + static final int QUAD_STRIP = (1 << 7) | 1; + + static final int POLYGON = (1 << 8) | 0; + //static final int CONCAVE_POLYGON = (1 << 8) | 1; + //static final int CONVEX_POLYGON = (1 << 8) | 2; + + static final int OPEN = 1; + static final int CLOSE = 2; + + + // shape drawing modes + + /** Draw mode convention to use (x, y) to (width, height) */ + static final int CORNER = 0; + /** Draw mode convention to use (x1, y1) to (x2, y2) coordinates */ + static final int CORNERS = 1; + /** @deprecated Use RADIUS instead (as of 0125) */ + static final int CENTER_RADIUS = 2; + /** Draw mode from the center, and using the radius */ + static final int RADIUS = 2; + /** Draw from the center, using second pair of values as the diameter. + Formerly called CENTER_DIAMETER in alpha releases */ + static final int CENTER = 3; + + + // vertically alignment modes for text + + /** Default vertical alignment for text placement */ + static final int BASELINE = 0; + /** Align text to the top */ + static final int TOP = 101; + /** Align text from the bottom, using the baseline. */ + static final int BOTTOM = 102; + + + // uv texture orientation modes + + static final int NORMALIZED = 1; //_SPACE = 0; // 0..1 + static final int IMAGE = 2; + + + // text placement modes + + /** + * textMode(MODEL) is the default, meaning that characters + * will be affected by transformations like any other shapes. + *

    + * Changed value in 0093 to not interfere with LEFT, CENTER, and RIGHT. + */ + static final int MODEL = 4; + + /** + * textMode(SHAPE) draws text using the the glyph outlines of + * individual characters rather than as textures. If the outlines are + * not available, then textMode(SHAPE) will be ignored and textMode(MODEL) + * will be used instead. For this reason, be sure to call textMode() + * after calling textFont(). + *

    + * Currently, textMode(SHAPE) is only supported by OPENGL mode. + * It also requires Java 1.2 or higher (OPENGL requires 1.4 anyway) + */ + static final int SHAPE = 5; + + + // text alignment modes + // are inherited from LEFT, CENTER, RIGHT + + + // stroke modes + + static final int SQUARE = 1 << 0; // called 'butt' in the svg spec + static final int ROUND = 1 << 1; + static final int PROJECT = 1 << 2; // called 'square' in the svg spec + static final int MITER = 1 << 3; + static final int BEVEL = 1 << 5; + + + // lighting + + static final int AMBIENT = 0; + static final int DIRECTIONAL = 1; + static final int POINT = 2; + static final int SPOT = 3; + + + // key constants + + // only including the most-used of these guys + // if people need more esoteric keys, they can learn about + // the esoteric java KeyEvent api and of virtual keys + + // both key and keyCode will equal these values + // for 0125, these were changed to 'char' values, because they + // can be upgraded to ints automatically by Java, but having them + // as ints prevented split(blah, TAB) from working + static final char BACKSPACE = 8; + static final char TAB = 9; + static final char ENTER = 10; + static final char RETURN = 13; + static final char ESC = 27; + static final char DELETE = 127; + + // i.e. if ((key == CODED) && (keyCode == UP)) + static final int CODED = 0xffff; + + // key will be CODED and keyCode will be this value + static final int UP = KeyEvent.VK_UP; + static final int DOWN = KeyEvent.VK_DOWN; + static final int LEFT = KeyEvent.VK_LEFT; + static final int RIGHT = KeyEvent.VK_RIGHT; + + // key will be CODED and keyCode will be this value + static final int ALT = KeyEvent.VK_ALT; + static final int CONTROL = KeyEvent.VK_CONTROL; + static final int SHIFT = KeyEvent.VK_SHIFT; + + + // cursor types + + static final int ARROW = Cursor.DEFAULT_CURSOR; + static final int CROSS = Cursor.CROSSHAIR_CURSOR; + static final int HAND = Cursor.HAND_CURSOR; + static final int MOVE = Cursor.MOVE_CURSOR; + static final int TEXT = Cursor.TEXT_CURSOR; + static final int WAIT = Cursor.WAIT_CURSOR; + + + // hints + + //static final int SCALE_STROKE_WIDTH = 0; + //static final int LIGHTING_AFFECTS_STROKE = 1; + static final int ENABLE_NATIVE_FONTS = 2; + static final int DISABLE_TEXT_SMOOTH = 3; + //static final int DISABLE_SMOOTH_HACK = 4; + static final int DISABLE_DEPTH_TEST = 5; + static final int NO_FLYING_POO = 6; + static final int ENABLE_DEPTH_SORT = 7; + static final int DISABLE_ERROR_REPORT = 8; + static final int ENABLE_ACCURATE_TEXTURES = 9; + + static final int HINT_COUNT = 10; +} diff --git a/core/PFont.java b/core/PFont.java new file mode 100644 index 000000000..01cefda4f --- /dev/null +++ b/core/PFont.java @@ -0,0 +1,1019 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry & Casey Reas + Portions Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.*; +import java.io.*; +import java.lang.reflect.*; + + +/** + * Grayscale bitmap font class used by Processing. + *

    + * Awful (and by that, I mean awesome) ascii (non)art for how this works: + *

    + *   |
    + *   |                   height is the full used height of the image
    + *   |
    + *   |   ..XX..       }
    + *   |   ..XX..       }
    + *   |   ......       }
    + *   |   XXXX..       }  topExtent (top y is baseline - topExtent)
    + *   |   ..XX..       }
    + *   |   ..XX..       }  dotted areas are where the image data
    + *   |   ..XX..       }  is actually located for the character
    + *   +---XXXXXX----   }  (it extends to the right and down
    + *   |                   for power of two texture sizes)
    + *   ^^^^ leftExtent (amount to move over before drawing the image
    + *
    + *   ^^^^^^^^^^^^^^ setWidth (width displaced by char)
    + * 
    + */ +public class PFont implements PConstants { + + public int charCount; + public PImage images[]; + + /** + * Native Java version of the font. If possible, this allows the + * PGraphics subclass to just use Java's font rendering stuff + * in situations where that's faster. + */ + public Font font; + + /** + * Name of the font as seen by Java when it was created. + * If the font is available, the native version will be used. + */ + public String name; + + /** + * Postscript name of the font that this bitmap was created from. + */ + public String psname; + + /** "natural" size of the font (most often 48) */ + public int size; + + /** true if smoothing was enabled for this font, used for native impl */ + public boolean smooth; + + /** next power of 2 over the max image size (usually 64) */ + public int mbox2; + + /** floating point width (convenience) */ + protected float fwidth; + + /** floating point width (convenience) */ + protected float fheight; + + /** texture width, same as mbox2, but reserved for future use */ + public int twidth; + + /** texture height, same as mbox2, but reserved for future use */ + public int theight; + + public int value[]; // char code + public int height[]; // height of the bitmap data + public int width[]; // width of bitmap data + public int setWidth[]; // width displaced by the char + public int topExtent[]; // offset for the top + public int leftExtent[]; // offset for the left + + public int ascent; + public int descent; + + protected int ascii[]; // quick lookup for the ascii chars + + // shared by the text() functions to avoid incessant allocation of memory + //protected char textBuffer[] = new char[8 * 1024]; + //protected char widthBuffer[] = new char[8 * 1024]; + + + public PFont() { } // for subclasses + + + public PFont(InputStream input) throws IOException { + DataInputStream is = new DataInputStream(input); + + // number of character images stored in this font + charCount = is.readInt(); + + // bit count is ignored since this is always 8 + //int numBits = is.readInt(); + // used to be the bitCount, but now used for version number. + // version 8 is any font before 69, so 9 is anything from 83+ + // 9 was buggy so gonna increment to 10. + int version = is.readInt(); + + // this was formerly ignored, now it's the actual font size + //mbox = is.readInt(); + size = is.readInt(); + // this was formerly mboxY, the one that was used + // this will make new fonts downward compatible + //mbox2 = is.readInt(); + mbox2 = is.readInt(); + + fwidth = size; //mbox; + fheight = size; //mbox; + + // size for image ("texture") is next power of 2 + // over the font size. for most vlw fonts, the size is 48 + // so the next power of 2 is 64. + // double-check to make sure that mbox2 is a power of 2 + // there was a bug in the old font generator that broke this + //mbox2 = (int) Math.pow(2, Math.ceil(Math.log(mbox2) / Math.log(2))); + mbox2 = (int) Math.pow(2, Math.ceil(Math.log(mbox2) / Math.log(2))); + // size for the texture is stored in the font + twidth = theight = mbox2; //mbox2; + + ascent = is.readInt(); // formerly baseHt (zero/ignored) + descent = is.readInt(); // formerly ignored struct padding + + // allocate enough space for the character info + value = new int[charCount]; + height = new int[charCount]; + width = new int[charCount]; + setWidth = new int[charCount]; + topExtent = new int[charCount]; + leftExtent = new int[charCount]; + + ascii = new int[128]; + for (int i = 0; i < 128; i++) ascii[i] = -1; + + // read the information about the individual characters + for (int i = 0; i < charCount; i++) { + value[i] = is.readInt(); + height[i] = is.readInt(); + width[i] = is.readInt(); + setWidth[i] = is.readInt(); + topExtent[i] = is.readInt(); + leftExtent[i] = is.readInt(); + + // pointer in the c version, ignored + is.readInt(); + + // cache locations of the ascii charset + if (value[i] < 128) ascii[value[i]] = i; + + // the values for getAscent() and getDescent() from FontMetrics + // seem to be way too large.. perhaps they're the max? + // as such, use a more traditional marker for ascent/descent + if (value[i] == 'd') { + if (ascent == 0) ascent = topExtent[i]; + } + if (value[i] == 'p') { + if (descent == 0) descent = -topExtent[i] + height[i]; + } + } + + // not a roman font, so throw an error and ask to re-build. + // that way can avoid a bunch of error checking hacks in here. + if ((ascent == 0) && (descent == 0)) { + throw new RuntimeException("Please use \"Create Font\" to " + + "re-create this font."); + } + + images = new PImage[charCount]; + for (int i = 0; i < charCount; i++) { + images[i] = new PImage(twidth, theight, ALPHA); + int bitmapSize = height[i] * width[i]; + + byte temp[] = new byte[bitmapSize]; + is.readFully(temp); + + // convert the bitmap to an alpha channel + int w = width[i]; + int h = height[i]; + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { + int valu = temp[y*w + x] & 0xff; + images[i].pixels[y * twidth + x] = valu; + //(valu << 24) | 0xFFFFFF; // windows + //0xFFFFFF00 | valu; // macosx + + //System.out.print((images[i].pixels[y*64+x] > 128) ? "*" : "."); + } + //System.out.println(); + } + //System.out.println(); + } + + if (version >= 10) { // includes the font name at the end of the file + name = is.readUTF(); + psname = is.readUTF(); + } + if (version == 11) { + smooth = is.readBoolean(); + } + } + + + /** + * Try to find the native version of this font. + */ + protected Font findFont() { + // this font may or may not be installed + font = new Font(name, Font.PLAIN, size); + // if the ps name matches, then we're in fine shape + if (!font.getPSName().equals(psname)) { + // on osx java 1.4 (not 1.3.. ugh), you can specify the ps name + // of the font, so try that in case this .vlw font was created on pc + // and the name is different, but the ps name is found on the + // java 1.4 mac that's currently running this sketch. + font = new Font(psname, Font.PLAIN, size); + } + // check again, and if still bad, screw em + if (!font.getPSName().equals(psname)) { + font = null; + } + return font; + } + + + /** + * Write this PFont to an OutputStream. + *

    + * This is used by the Create Font tool, or whatever anyone else dreams + * up for messing with fonts themselves. + *

    + * It is assumed that the calling class will handle closing + * the stream when finished. + */ + public void save(OutputStream output) throws IOException { + DataOutputStream os = new DataOutputStream(output); + + os.writeInt(charCount); + + if ((name == null) || (psname == null)) { + name = ""; + psname = ""; + } + // formerly numBits, now used for version number + //os.writeInt((name != null) ? 11 : 8); + os.writeInt(11); + + os.writeInt(size); // formerly mboxX (was 64, now 48) + os.writeInt(mbox2); // formerly mboxY (was 64, still 64) + os.writeInt(ascent); // formerly baseHt (was ignored) + os.writeInt(descent); // formerly struct padding for c version + + for (int i = 0; i < charCount; i++) { + os.writeInt(value[i]); + os.writeInt(height[i]); + os.writeInt(width[i]); + os.writeInt(setWidth[i]); + os.writeInt(topExtent[i]); + os.writeInt(leftExtent[i]); + os.writeInt(0); // padding + } + + for (int i = 0; i < charCount; i++) { + for (int y = 0; y < height[i]; y++) { + for (int x = 0; x < width[i]; x++) { + os.write(images[i].pixels[y * mbox2 + x] & 0xff); + } + } + } + + //if (name != null) { // version 11 + os.writeUTF(name); + os.writeUTF(psname); + os.writeBoolean(smooth); + //} + + os.flush(); + } + + + /** + * Get index for the char (convert from unicode to bagel charset). + * @return index into arrays or -1 if not found + */ + public int index(char c) { + // degenerate case, but the find function will have trouble + // if there are somehow zero chars in the lookup + //if (value.length == 0) return -1; + if (charCount == 0) return -1; + + // quicker lookup for the ascii fellers + if (c < 128) return ascii[c]; + + // some other unicode char, hunt it out + //return index_hunt(c, 0, value.length-1); + return indexHunt(c, 0, charCount-1); + } + + + protected int indexHunt(int c, int start, int stop) { + int pivot = (start + stop) / 2; + + // if this is the char, then return it + if (c == value[pivot]) return pivot; + + // char doesn't exist, otherwise would have been the pivot + //if (start == stop) return -1; + if (start >= stop) return -1; + + // if it's in the lower half, continue searching that + if (c < value[pivot]) return indexHunt(c, start, pivot-1); + + // if it's in the upper half, continue there + return indexHunt(c, pivot+1, stop); + } + + + /** + * Currently un-implemented for .vlw fonts, + * but honored for layout in case subclasses use it. + */ + public float kern(char a, char b) { + return 0; + } + + + /** + * Returns the ascent of this font from the baseline. + * The value is based on a font of size 1. + */ + public float ascent() { + return ((float)ascent / fheight); + } + + + /** + * Returns how far this font descends from the baseline. + * The value is based on a font size of 1. + */ + public float descent() { + return ((float)descent / fheight); + } + + + /** + * Width of this character for a font of size 1. + */ + public float width(char c) { + if (c == 32) return width('i'); + + int cc = index(c); + if (cc == -1) return 0; + + return ((float)setWidth[cc] / fwidth); + } + + + /** + * Draw a character at an x, y position. + */ + /* + public void text(char c, float x, float y, PGraphics parent) { + text(c, x, y, 0, parent); + } + */ + + /** + * Draw a character at an x, y, z position. + */ + /* + public void text(char c, float x, float y, float z, PGraphics parent) { + if (parent.textAlign == CENTER) { + x -= parent.textSize * width(c) / 2f; + + } else if (parent.textAlign == RIGHT) { + x -= parent.textSize * width(c); + } + + //textImpl(c, x, y, z, parent); + if (z != 0) parent.translate(0, 0, z); // TEMPORARY HACK! SLOW! + parent.textImpl(c, x, y, z); + if (z != 0) parent.translate(0, 0, -z); // TEMPORARY HACK! SLOW! + } + */ + + + /* + public void text(String str, float x, float y, PGraphics parent) { + text(str, x, y, 0, parent); + } + + + public void text(String str, float x, float y, float z, PGraphics parent) { + if (z != 0) parent.translate(0, 0, z); // TEMPORARY HACK! SLOW! + + int length = str.length(); + if (length > textBuffer.length) { + textBuffer = new char[length + 10]; + } + str.getChars(0, length, textBuffer, 0); + + int start = 0; + int index = 0; + while (index < length) { + if (textBuffer[index] == '\n') { + textLine(start, index, x, y, z, parent); + start = index + 1; + y += parent.textLeading; + } + index++; + } + if (start < length) { + textLine(start, index, x, y, z, parent); + } + if (z != 0) parent.translate(0, 0, -z); // TEMPORARY HACK! SLOW! + } + + + protected void textLine(int start, int stop, + float x, float y, float z, + PGraphics parent) { + if (parent.textAlign == CENTER) { + x -= parent.textSize * calcWidth(textBuffer, start, stop) / 2f; + + } else if (parent.textAlign == RIGHT) { + x -= parent.textSize * calcWidth(textBuffer, start, stop); + } + + for (int index = start; index < stop; index++) { + //textImpl(textBuffer[index], x, y, z, parent); + //parent.textImpl(textBuffer[index], x, y, z); + // HACK FOR Z COORDINATES.. FIX ME SOON + parent.textImpl(textBuffer[index], x, y, 0); //z); + x += parent.textSize *width(textBuffer[index]); + } + } + */ + + + /** + * Same as below, just without a z coordinate. + */ + /* + public void text(String str, float x, float y, + float c, float d, PGraphics parent) { + text(str, x, y, c, d, 0, parent); + } + */ + + /** + * Draw text in a box that is constrained to a particular size. + *

    + * The parent PApplet will have converted the coords based on + * the current rectMode(). + *

    + * Note that the x,y coords of the start of the box + * will align with the *ascent* of the text, not the baseline, + * as is the case for the other text() functions. + */ + /* + public void text(String str, float boxX1, float boxY1, + float boxX2, float boxY2, float boxZ, PGraphics parent) { + if (boxZ != 0) parent.translate(0, 0, boxZ); // TEMPORARY HACK! SLOW! + + float spaceWidth = width(' ') * parent.textSize; + float runningX = boxX1; + float currentY = boxY1; + float boxWidth = boxX2 - boxX1; + + float lineX = boxX1; + if (parent.textAlign == CENTER) { + lineX = lineX + boxWidth/2f; + } else if (parent.textAlign == RIGHT) { + lineX = boxX2; + } + + // ala illustrator, the text itself must fit inside the box + currentY += ascent() * parent.textSize; + // if the box is already too small, tell em to f off + if (currentY > boxY2) return; + + int length = str.length(); + if (length > textBuffer.length) { + textBuffer = new char[length + 10]; + } + str.getChars(0, length, textBuffer, 0); + + int wordStart = 0; + int wordStop = 0; + int lineStart = 0; + int index = 0; + while (index < length) { + if ((textBuffer[index] == ' ') || (index == length-1)) { + // boundary of a word + float wordWidth = parent.textSize * + calcWidth(textBuffer, wordStart, index); + + if (runningX + wordWidth > boxX2) { + if (runningX == boxX1) { + // if this is the first word, and its width is + // greater than the width of the text box, + // then break the word where at the max width, + // and send the rest of the word to the next line. + do { + index--; + if (index == wordStart) { + // not a single char will fit on this line. screw 'em. + //System.out.println("screw you"); + return; + } + wordWidth = parent.textSize * + calcWidth(textBuffer, wordStart, index); + } while (wordWidth > boxWidth); + textLine(lineStart, index, lineX, currentY, boxZ, parent); + + } else { + // next word is too big, output current line + // and advance to the next line + textLine(lineStart, wordStop, lineX, currentY, boxZ, parent); + // only increment index if a word wasn't broken inside the + // do/while loop above.. also, this is a while() loop too, + // because multiple spaces don't count for shit when they're + // at the end of a line like this. + + index = wordStop; // back that ass up + while ((index < length) && + (textBuffer[index] == ' ')) { + index++; + } + } + lineStart = index; + wordStart = index; + wordStop = index; + runningX = boxX1; + currentY += parent.textLeading; + if (currentY > boxY2) return; // box is now full + + } else { + runningX += wordWidth + spaceWidth; + // on to the next word + wordStop = index; + wordStart = index + 1; + } + + } else if (textBuffer[index] == '\n') { + if (lineStart != index) { // if line is not empty + textLine(lineStart, index, lineX, currentY, boxZ, parent); + } + lineStart = index + 1; + wordStart = lineStart; + currentY += parent.textLeading; + if (currentY > boxY2) return; // box is now full + } + index++; + } + if ((lineStart < length) && (lineStart != index)) { + textLine(lineStart, index, lineX, currentY, boxZ, parent); + } + + if (boxZ != 0) parent.translate(0, 0, -boxZ); // TEMPORARY HACK! SLOW! + } + */ + + + ////////////////////////////////////////////////////////////// + + + static final char[] EXTRA_CHARS = { + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B4, 0x00B5, 0x00B6, 0x00B7, 0x00B8, 0x00BA, + 0x00BB, 0x00BF, 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, + 0x00C6, 0x00C7, 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, + 0x00CE, 0x00CF, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, + 0x00D7, 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, 0x00F8, + 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FF, 0x0102, 0x0103, + 0x0104, 0x0105, 0x0106, 0x0107, 0x010C, 0x010D, 0x010E, 0x010F, + 0x0110, 0x0111, 0x0118, 0x0119, 0x011A, 0x011B, 0x0131, 0x0139, + 0x013A, 0x013D, 0x013E, 0x0141, 0x0142, 0x0143, 0x0144, 0x0147, + 0x0148, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, 0x0158, + 0x0159, 0x015A, 0x015B, 0x015E, 0x015F, 0x0160, 0x0161, 0x0162, + 0x0163, 0x0164, 0x0165, 0x016E, 0x016F, 0x0170, 0x0171, 0x0178, + 0x0179, 0x017A, 0x017B, 0x017C, 0x017D, 0x017E, 0x0192, 0x02C6, + 0x02C7, 0x02D8, 0x02D9, 0x02DA, 0x02DB, 0x02DC, 0x02DD, 0x03A9, + 0x03C0, 0x2013, 0x2014, 0x2018, 0x2019, 0x201A, 0x201C, 0x201D, + 0x201E, 0x2020, 0x2021, 0x2022, 0x2026, 0x2030, 0x2039, 0x203A, + 0x2044, 0x20AC, 0x2122, 0x2202, 0x2206, 0x220F, 0x2211, 0x221A, + 0x221E, 0x222B, 0x2248, 0x2260, 0x2264, 0x2265, 0x25CA, 0xF8FF, + 0xFB01, 0xFB02 + }; + + + /** + * The default Processing character set. + *

    + * This is the union of the Mac Roman and Windows ANSI (CP1250) + * character sets. ISO 8859-1 Latin 1 is Unicode characters 0x80 -> 0xFF, + * and would seem a good standard, but in practice, most P5 users would + * rather have characters that they expect from their platform's fonts. + *

    + * This is more of an interim solution until a much better + * font solution can be determined. (i.e. create fonts on + * the fly from some sort of vector format). + *

    + * Not that I expect that to happen. + */ + static public char[] DEFAULT_CHARSET; + static { + DEFAULT_CHARSET = new char[126-33+1 + EXTRA_CHARS.length]; + int index = 0; + for (int i = 33; i <= 126; i++) { + DEFAULT_CHARSET[index++] = (char)i; + } + for (int i = 0; i < EXTRA_CHARS.length; i++) { + DEFAULT_CHARSET[index++] = EXTRA_CHARS[i]; + } + }; + + + /** + * Use reflection to create a new .vlw font on the fly. + * This only works with Java 1.3 and higher. + * + * @param font the font object to create from + * @param charset array of all unicode chars that should be included + * @param smooth true to enable smoothing/anti-aliasing + */ + public PFont(Font font, boolean smooth, char charset[]) { + if (PApplet.javaVersion < 1.3f) { + throw new RuntimeException("Can only create fonts with " + + "Java 1.3 or higher"); + } + + // save this so that we can use the native version + this.font = font; + this.smooth = smooth; + + name = font.getName(); + psname = font.getPSName(); + + try { + // fix regression from sorting (bug #564) + if (charset != null) { + // charset needs to be sorted to make index lookup run more quickly + // http://dev.processing.org/bugs/show_bug.cgi?id=494 + //Arrays.sort(charset); + Class arraysClass = Class.forName("java.util.Arrays"); + Method sortMethod = + arraysClass.getMethod("sort", new Class[] { charset.getClass() }); + sortMethod.invoke(null, new Object[] { charset }); + } + + // the count gets reset later based on how many of + // the chars are actually found inside the font. + this.charCount = (charset == null) ? 65536 : charset.length; + this.size = font.getSize(); + + fwidth = fheight = size; + + PImage bitmaps[] = new PImage[charCount]; + + // allocate enough space for the character info + value = new int[charCount]; + height = new int[charCount]; + width = new int[charCount]; + setWidth = new int[charCount]; + topExtent = new int[charCount]; + leftExtent = new int[charCount]; + + ascii = new int[128]; + for (int i = 0; i < 128; i++) ascii[i] = -1; + + int mbox3 = size * 3; + + /* + BufferedImage playground = + new BufferedImage(mbox3, mbox3, BufferedImage.TYPE_INT_RGB); + + Graphics2D g = (Graphics2D) playground.getGraphics(); + g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + smooth ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF); + */ + + Class bufferedImageClass = + Class.forName("java.awt.image.BufferedImage"); + Constructor bufferedImageConstructor = + bufferedImageClass.getConstructor(new Class[] { + Integer.TYPE, + Integer.TYPE, + Integer.TYPE }); + Field typeIntRgbField = bufferedImageClass.getField("TYPE_INT_RGB"); + int typeIntRgb = typeIntRgbField.getInt(typeIntRgbField); + Object playground = + bufferedImageConstructor.newInstance(new Object[] { + new Integer(mbox3), + new Integer(mbox3), + new Integer(typeIntRgb) }); + + Class graphicsClass = + Class.forName("java.awt.Graphics2D"); + Method getGraphicsMethod = + bufferedImageClass.getMethod("getGraphics", new Class[] { }); + //Object g = getGraphicsMethod.invoke(playground, new Object[] { }); + Graphics g = (Graphics) + getGraphicsMethod.invoke(playground, new Object[] { }); + + Class renderingHintsClass = + Class.forName("java.awt.RenderingHints"); + Class renderingHintsKeyClass = + Class.forName("java.awt.RenderingHints$Key"); + //PApplet.printarr(renderingHintsClass.getFields()); + + Field antialiasingKeyField = + renderingHintsClass.getField("KEY_TEXT_ANTIALIASING"); + Object antialiasingKey = + antialiasingKeyField.get(renderingHintsClass); + + Field antialiasField = smooth ? + renderingHintsClass.getField("VALUE_TEXT_ANTIALIAS_ON") : + renderingHintsClass.getField("VALUE_TEXT_ANTIALIAS_OFF"); + Object antialiasState = + antialiasField.get(renderingHintsClass); + + Method setRenderingHintMethod = + graphicsClass.getMethod("setRenderingHint", + new Class[] { renderingHintsKeyClass, + Object.class }); + setRenderingHintMethod.invoke(g, new Object[] { + antialiasingKey, + antialiasState + }); + + g.setFont(font); + FontMetrics metrics = g.getFontMetrics(); + + Method canDisplayMethod = null; + Method getDataMethod = null; + Method getSamplesMethod = null; + + int samples[] = new int[mbox3 * mbox3]; + + canDisplayMethod = + Font.class.getMethod("canDisplay", new Class[] { Character.TYPE }); + getDataMethod = + bufferedImageClass.getMethod("getData", new Class[] { }); + Class rasterClass = Class.forName("java.awt.image.Raster"); + getSamplesMethod = rasterClass.getMethod("getSamples", new Class[] { + Integer.TYPE, + Integer.TYPE, + Integer.TYPE, + Integer.TYPE, + Integer.TYPE, + // integer array type? + //Array.class + samples.getClass() + }); + + //} catch (Exception e) { + //e.printStackTrace(); + //return; + //} + + //Array samples = Array.newInstance(Integer.TYPE, mbox3*mbox3); + + int maxWidthHeight = 0; + int index = 0; + for (int i = 0; i < charCount; i++) { + char c = (charset == null) ? (char)i : charset[i]; + + //if (!font.canDisplay(c)) { // skip chars not in the font + try { + Character ch = new Character(c); + Boolean canDisplay = (Boolean) + canDisplayMethod.invoke(font, new Object[] { ch }); + if (canDisplay.booleanValue() == false) { + continue; + } + } catch (Exception e) { + e.printStackTrace(); + return; + } + + g.setColor(Color.white); + g.fillRect(0, 0, mbox3, mbox3); + g.setColor(Color.black); + g.drawString(String.valueOf(c), size, size * 2); + + // grabs copy of the current data.. so no updates (do each time) + /* + Raster raster = playground.getData(); + raster.getSamples(0, 0, mbox3, mbox3, 0, samples); + */ + + Object raster = getDataMethod.invoke(playground, new Object[] {}); + getSamplesMethod.invoke(raster, new Object[] { + new Integer(0), + new Integer(0), + new Integer(mbox3), + new Integer(mbox3), + new Integer(0), + samples + }); + + //int w = metrics.charWidth(c); + int minX = 1000, maxX = 0; + int minY = 1000, maxY = 0; + boolean pixelFound = false; + + for (int y = 0; y < mbox3; y++) { + for (int x = 0; x < mbox3; x++) { + //int sample = raster.getSample(x, y, 0); // maybe? + int sample = samples[y * mbox3 + x] & 0xff; + // or int samples[] = raster.getPixel(x, y, null); + + //if (sample == 0) { // or just not white? hmm + if (sample != 255) { + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + pixelFound = true; + //System.out.println(x + " " + y + " = " + sample); + } + } + } + + if (!pixelFound) { + //System.out.println("no pixels found in unicode char " + c + + // "(" + PApplet.hex(c) + ")"); + // this was dumb that it was set to 20 & 30, because for small + // fonts, those guys don't exist + minX = minY = 0; //20; + maxX = maxY = 0; //30; + + // this will create a 1 pixel white (clear) character.. + // maybe better to set one to -1 so nothing is added? + /* + } else { + System.out.println(PApplet.hex(c) + " has bounds " + + minX + ", " + minY + " to " + + maxX + ", " + maxY); + */ + } + + value[index] = c; + height[index] = (maxY - minY) + 1; + width[index] = (maxX - minX) + 1; + setWidth[index] = metrics.charWidth(c); + //System.out.println((char)c + " " + setWidth[index]); + + // cache locations of the ascii charset + //if (value[i] < 128) ascii[value[i]] = i; + if (c < 128) ascii[c] = index; + + // offset from vertical location of baseline + // of where the char was drawn (size*2) + topExtent[index] = size*2 - minY; + + // offset from left of where coord was drawn + leftExtent[index] = minX - size; + + if (c == 'd') { + ascent = topExtent[index]; + } + if (c == 'p') { + descent = -topExtent[index] + height[index]; + } + + if (width[index] > maxWidthHeight) maxWidthHeight = width[index]; + if (height[index] > maxWidthHeight) maxWidthHeight = height[index]; + + bitmaps[index] = new PImage(width[index], height[index], ALPHA); + + for (int y = minY; y <= maxY; y++) { + for (int x = minX; x <= maxX; x++) { + int val = 255 - (samples[y * mbox3 + x] & 0xff); + int pindex = (y - minY) * width[index] + (x - minX); + bitmaps[index].pixels[pindex] = val; + } + } + index++; + } + charCount = index; + + // foreign font, so just make ascent the max topExtent + if ((ascent == 0) && (descent == 0)) { + for (int i = 0; i < charCount; i++) { + char cc = (char) value[i]; + if (Character.isWhitespace(cc) || + (cc == '\u00A0') || (cc == '\u2007') || (cc == '\u202F')) { + continue; + } + if (topExtent[i] > ascent) { + ascent = topExtent[i]; + } + int d = -topExtent[i] + height[i]; + if (d > descent) { + descent = d; + } + } + } + // size for image/texture is next power of 2 over largest char + mbox2 = (int) + Math.pow(2, Math.ceil(Math.log(maxWidthHeight) / Math.log(2))); + twidth = theight = mbox2; + + // shove the smaller PImage data into textures of next-power-of-2 size, + // so that this font can be used immediately by p5. + images = new PImage[charCount]; + for (int i = 0; i < charCount; i++) { + images[i] = new PImage(mbox2, mbox2, ALPHA); + for (int y = 0; y < height[i]; y++) { + System.arraycopy(bitmaps[i].pixels, y*width[i], + images[i].pixels, y*mbox2, + width[i]); + } + bitmaps[i] = null; + } + + } catch (Exception e) { // catch-all for reflection stuff + e.printStackTrace(); + throw new RuntimeException(e.getMessage()); + } + } + + + /** + * Get a list of the fonts installed on the system that can be used + * by Java. Not all fonts can be used in Java, in fact it's mostly + * only TrueType fonts. OpenType fonts with CFF data such as Adobe's + * OpenType fonts seem to have trouble (even though they're sort of + * TrueType fonts as well, or may have a .ttf extension). Regular + * PostScript fonts seem to work O.K. though. + *

    + * Not recommended for use in applets, but this is implemented + * in PFont because the Java methods to access this information + * have changed between 1.1 and 1.4, and the 1.4 method is + * typical of the sort of undergraduate-level over-abstraction + * that the seems to have made its way into the Java API after 1.1. + */ + static public String[] list() { + if (PApplet.javaVersion < 1.3f) { + // make this reflection too, since compilers complain about the + // deprecation, and it's bound to stop working in 1.6 or something + //return Toolkit.getDefaultToolkit().getFontList(); + try { + Toolkit tk = Toolkit.getDefaultToolkit(); + Method getFontListMethod = + tk.getClass().getMethod("getFontList", (Class[]) null); + return (String[]) getFontListMethod.invoke(tk, (Object[]) null); + } catch (Exception e) { + e.printStackTrace(); + return new String[] { }; + } + } + + // getFontList is deprecated in 1.4, so this has to be used + try { + //GraphicsEnvironment ge = + // GraphicsEnvironment.getLocalGraphicsEnvironment(); + Class geClass = Class.forName("java.awt.GraphicsEnvironment"); + Method glgeMethod = + geClass.getMethod("getLocalGraphicsEnvironment", (Class[]) null); + Object ge = glgeMethod.invoke((Class[]) null, (Object[]) null); + + //Font fonts[] = ge.getAllFonts(); + Method gafMethod = geClass.getMethod("getAllFonts", (Class[]) null); + Font fonts[] = (Font[]) gafMethod.invoke(ge, (Object[]) null); + String list[] = new String[fonts.length]; + for (int i = 0; i < list.length; i++) { + list[i] = fonts[i].getName(); + } + return list; + + } catch (Exception e) { + e.printStackTrace(); + throw new RuntimeException("Error inside PFont.list()"); + } + } +} diff --git a/core/PGraphics.java b/core/PGraphics.java new file mode 100644 index 000000000..c1318177d --- /dev/null +++ b/core/PGraphics.java @@ -0,0 +1,4308 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.*; +import java.awt.image.*; + + +/** + * Main graphics and rendering context, as well as + * the base API implementation for processing "core". + *

    + * As of beta, this class is semi-disabled. + */ +public abstract class PGraphics extends PImage implements PConstants { + + // transformed values + // (to be used in rendering) + + static public final int X = 0; // transformed xyzw + static public final int Y = 1; // formerly SX SY SZ + static public final int Z = 2; + + static public final int R = 3; // actual rgb, after lighting + static public final int G = 4; // fill stored here, transform in place + static public final int B = 5; + static public final int A = 6; + + // values that need no transformation + // but will be used in rendering + + static public final int U = 7; // texture + static public final int V = 8; + + // incoming values, raw and untransformed + // (won't be used in rendering) + + static public final int MX = 9; // model coords xyz + static public final int MY = 10; + static public final int MZ = 11; + + /** stroke argb values */ + static public final int SR = 12; + static public final int SG = 13; + static public final int SB = 14; + static public final int SA = 15; + + /** stroke weight */ + static public final int SW = 16; + + // not used in rendering + // only used for calculating colors + + static public final int NX = 17; // normal + static public final int NY = 18; + static public final int NZ = 19; + + static public final int VX = 20; // view space coords + static public final int VY = 21; + static public final int VZ = 22; + static public final int VW = 23; + + // Ambient color (usually to be kept the same as diffuse) + // fill(_) sets both ambient and diffuse. + static public final int AR = 24; + static public final int AG = 25; + static public final int AB = 26; + + // Diffuse is shared with fill. + static public final int DR = 3; + static public final int DG = 4; + static public final int DB = 5; + static public final int DA = 6; + + //specular (by default kept white) + static public final int SPR = 27; + static public final int SPG = 28; + static public final int SPB = 29; + //GL doesn't use a separate specular alpha, but we do (we're better) + static public final int SPA = 30; + + static public final int SHINE = 31; + + //emissive (by default kept black) + static public final int ER = 32; + static public final int EG = 33; + static public final int EB = 34; + + //has this vertex been lit yet + static public final int BEEN_LIT = 35; + + static final int VERTEX_FIELD_COUNT = 36; + + // line & triangle fields (note how these overlap) + + static public final int INDEX = 0; // shape index + static public final int VERTEX1 = 1; + static public final int VERTEX2 = 2; + static public final int VERTEX3 = 3; // (triangles only) + static public final int TEXTURE_INDEX = 4; // (triangles only) + static public final int STROKE_MODE = 3; // (lines only) + static public final int STROKE_WEIGHT = 4; // (lines only) + + static public final int LINE_FIELD_COUNT = 5; + static public final int TRIANGLE_FIELD_COUNT = 5; + + static public final int TRI_DIFFUSE_R = 0; + static public final int TRI_DIFFUSE_G = 1; + static public final int TRI_DIFFUSE_B = 2; + static public final int TRI_DIFFUSE_A = 3; + static public final int TRI_SPECULAR_R = 4; + static public final int TRI_SPECULAR_G = 5; + static public final int TRI_SPECULAR_B = 6; + static public final int TRI_SPECULAR_A = 7; + + static public final int TRIANGLE_COLOR_COUNT = 8; + + + // normal modes for lighting, these have the uglier naming + // because the constants are never seen by users + + /// normal calculated per triangle + static public final int AUTO_NORMAL = 0; + /// one normal manually specified per shape + static public final int MANUAL_SHAPE_NORMAL = 1; + /// normals specified for each shape vertex + static public final int MANUAL_VERTEX_NORMAL = 2; + + + /// width minus one (useful for many calculations) + public int width1; + + /// height minus one (useful for many calculations) + public int height1; + + /// width * height (useful for many calculations) + public int pixelCount; + + /// true if defaults() has been called a first time + protected boolean defaultsInited; + + /// true if in-between beginDraw() and endDraw() + protected boolean insideDraw; + + /// true if in the midst of resize (no drawing can take place) + boolean insideResize; + + // ........................................................ + + /** + * true if this is the main drawing surface for a particular sketch. + * This would be set to false for an offscreen buffer or if it were + * created any other way than size(). When this is set, the listeners + * are also added to the sketch. + */ + protected boolean mainDrawingSurface; + + // ........................................................ + + // specifics for java memoryimagesource + DirectColorModel cm; + MemoryImageSource mis; + public Image image; + + // ........................................................ + + // used by recordRaw() + public PGraphics raw; + + // ........................................................ + + // needs to happen before background() is called + // and resize.. so it's gotta be outside + protected boolean hints[] = new boolean[HINT_COUNT]; + + // ........................................................ + + // underscored_names are used for private functions or variables + + /** The current colorMode */ + public int colorMode; // = RGB; + + /** Max value for red (or hue) set by colorMode */ + public float colorModeX; // = 255; + + /** Max value for green (or saturation) set by colorMode */ + public float colorModeY; // = 255; + + /** Max value for blue (or value) set by colorMode */ + public float colorModeZ; // = 255; + + /** Max value for alpha set by colorMode */ + public float colorModeA; // = 255; + + /** True if colors are not in the range 0..1 */ + boolean colorScale; // = true; + + /** True if colorMode(RGB, 255) */ + boolean colorRgb255; // = true; + + // ........................................................ + + /** + * true if tint() is enabled (read-only). + * Using tint/tintColor seems a better option for naming than + * tintEnabled/tint because the latter seems ugly, even though + * g.tint as the actual color seems a little more intuitive, + * it's just that g.tintEnabled is even more unintuitive. + * Same goes for fill and stroke et al. + */ + public boolean tint; + + /** tint that was last set (read-only) */ + public int tintColor; + + protected boolean tintAlpha; + protected float tintR, tintG, tintB, tintA; + protected int tintRi, tintGi, tintBi, tintAi; + + // ........................................................ + + /** true if fill() is enabled, (read-only) */ + public boolean fill; + + /** fill that was last set (read-only) */ + public int fillColor = 0xffFFFFFF; + + protected boolean fillAlpha; + protected float fillR, fillG, fillB, fillA; + protected int fillRi, fillGi, fillBi, fillAi; + + // ........................................................ + + /** true if stroke() is enabled, (read-only) */ + public boolean stroke; + + /** stroke that was last set (read-only) */ + public int strokeColor = 0xff000000; + + protected boolean strokeAlpha; + protected float strokeR, strokeG, strokeB, strokeA; + protected int strokeRi, strokeGi, strokeBi, strokeAi; + + // ........................................................ + + /** Last background color that was set, zero if an image */ + public int backgroundColor = 0xffCCCCCC; + + protected boolean backgroundAlpha; + protected float backgroundR, backgroundG, backgroundB, backgroundA; + protected int backgroundRi, backgroundGi, backgroundBi, backgroundAi; + + // ........................................................ + + // internal color for setting/calculating + protected float calcR, calcG, calcB, calcA; + int calcRi, calcGi, calcBi, calcAi; + int calcColor; + boolean calcAlpha; + + /** The last rgb value converted to HSB */ + int cacheHsbKey; + /** Result of the last conversion to HSB */ + float cacheHsbValue[] = new float[3]; // inits to zero + + // ........................................................ + + /** + * Last value set by strokeWeight() (read-only). This has a default + * setting, rather than fighting with renderers about whether that + * renderer supports thick lines. + */ + public float strokeWeight = 1; + + /** + * Set by strokeJoin() (read-only). This has a default setting + * so that strokeJoin() need not be called by defaults, + * because subclasses may not implement it (i.e. PGraphicsGL) + */ + public int strokeJoin = MITER; + + /** + * Set by strokeCap() (read-only). This has a default setting + * so that strokeCap() need not be called by defaults, + * because subclasses may not implement it (i.e. PGraphicsGL) + */ + public int strokeCap = ROUND; + + // ........................................................ + + /** + * Model transformation of the form m[row][column], + * which is a "column vector" (as opposed to "row vector") matrix. + */ + public float m00, m01, m02, m03; + public float m10, m11, m12, m13; + public float m20, m21, m22, m23; + public float m30, m31, m32, m33; + + static final int MATRIX_STACK_DEPTH = 32; + float matrixStack[][] = new float[MATRIX_STACK_DEPTH][16]; + int matrixStackDepth; + + // ........................................................ + + //Path path; + + // ........................................................ + + /** + * Type of shape passed to beginShape(), + * zero if no shape is currently being drawn. + */ + protected int shape; + + // vertices + static final int DEFAULT_VERTICES = 512; + protected float vertices[][] = + new float[DEFAULT_VERTICES][VERTEX_FIELD_COUNT]; + protected int vertexCount; // total number of vertices + + + // ........................................................ + + protected boolean bezierInited = false; + public int bezierDetail = 20; + // msjvm complained when bezier_basis was final + protected float bezier_basis[][] = { + { -1, 3, -3, 1}, + { 3, -6, 3, 0}, + { -3, 3, 0, 0}, + { 1, 0, 0, 0} + }; + + protected PMatrix bezierBasis = + new PMatrix(-1, 3, -3, 1, + 3, -6, 3, 0, + -3, 3, 0, 0, + 1, 0, 0, 0); + + protected float bezierForwardMatrix[][]; // = new float[4][4]; + protected float bezierDrawMatrix[][]; // = new float[4][4]; + + // ........................................................ + + protected boolean curve_inited = false; + protected int curveDetail = 20; + // catmull-rom basis matrix, perhaps with optional s parameter + public float curveTightness = 0; + protected float curve_basis[][]; // = new float[4][4]; + protected float curve_forward[][]; // = new float[4][4]; + protected float curve_draw[][]; + + protected PMatrix bezierBasisInverse; + protected PMatrix curveToBezierMatrix; + + // ........................................................ + + // spline vertices + + static final int DEFAULT_SPLINE_VERTICES = 128; + protected float splineVertices[][]; + protected int splineVertexCount; + + // ........................................................ + + // precalculate sin/cos lookup tables [toxi] + // circle resolution is determined from the actual used radii + // passed to ellipse() method. this will automatically take any + // scale transformations into account too + + // [toxi 031031] + // changed table's precision to 0.5 degree steps + // introduced new vars for more flexible code + static final protected float sinLUT[]; + static final protected float cosLUT[]; + static final protected float SINCOS_PRECISION = 0.5f; + static final protected int SINCOS_LENGTH = (int) (360f / SINCOS_PRECISION); + static { + sinLUT = new float[SINCOS_LENGTH]; + cosLUT = new float[SINCOS_LENGTH]; + for (int i = 0; i < SINCOS_LENGTH; i++) { + sinLUT[i] = (float) Math.sin(i * DEG_TO_RAD * SINCOS_PRECISION); + cosLUT[i] = (float) Math.cos(i * DEG_TO_RAD * SINCOS_PRECISION); + } + } + + // ........................................................ + + /** The current rect mode (read-only) */ + public int rectMode; + + /** The current ellipse mode (read-only) */ + public int ellipseMode; + + /** The current text font (read-only) */ + public PFont textFont; + + /** The current font if a Java version of it is installed */ + public Font textFontNative; + + /** Metrics for the current native Java font */ + public FontMetrics textFontNativeMetrics; + + /** The current text align (read-only) */ + public int textAlign; + + /** The current vertical text alignment (read-only) */ + public int textAlignY; + + /** The current text mode (read-only) */ + public int textMode; + + /** The current text size (read-only) */ + public float textSize; + + /** The current text leading (read-only) */ + public float textLeading; + + /** Last text position, because text often mixed on lines together */ + public float textX, textY, textZ; + + /** + * Internal buffer used by the text() functions + * because the String object is slow + */ + protected char textBuffer[] = new char[8 * 1024]; + protected char textWidthBuffer[] = new char[8 * 1024]; + + + ////////////////////////////////////////////////////////////// + + // VARIABLES FOR 3D (used to prevent the need for a subclass) + + + /** The modelview matrix. */ + public PMatrix modelview; + + /** Inverse modelview matrix, used for lighting. */ + public PMatrix modelviewInv; + + /** + * The camera matrix, the modelview will be set to this on beginDraw. + */ + public PMatrix camera; + + /** Inverse camera matrix */ + public PMatrix cameraInv; + + // ........................................................ + + // Material properties + + public float ambientR, ambientG, ambientB; + public float specularR, specularG, specularB, specularA; + public float emissiveR, emissiveG, emissiveB; + public float shininess; + + // ........................................................ + + /** Camera field of view (in radians, as of rev 86) */ + public float cameraFOV; + + /** Position of the camera */ + public float cameraX, cameraY, cameraZ; + + public float cameraNear, cameraFar; + public float cameraAspect; + + // projection matrix + public PMatrix projection; // = new PMatrix(); + + // ........................................................ + + /// the stencil buffer + public int stencil[]; + + /// depth buffer + public float zbuffer[]; + + // ........................................................ + + /** Maximum lights by default is 8, which is arbitrary, + but is the minimum defined by OpenGL */ + public static final int MAX_LIGHTS = 8; + + public int lightCount = 0; + + /** Light types */ + public int lightType[]; + + /** Light positions */ + public float lightPosition[][]; + //public float lightsX[], lightsY[], lightsZ[]; + + /** Light direction (normalized vector) */ + public float lightNormal[][]; + //public float lightsNX[], lightsNY[], lightsNZ[]; + + /** Light falloff */ + public float lightFalloffConstant[]; + public float lightFalloffLinear[]; + public float lightFalloffQuadratic[]; + + /** Light spot angle */ + public float lightSpotAngle[]; + + /** Cosine of light spot angle */ + public float lightSpotAngleCos[]; + + /** Light spot concentration */ + public float lightSpotConcentration[]; + + /** Diffuse colors for lights. + * For an ambient light, this will hold the ambient color. + * Internally these are stored as numbers between 0 and 1. */ + public float lightDiffuse[][]; + + /** Specular colors for lights. + Internally these are stored as numbers between 0 and 1. */ + public float lightSpecular[][]; + + /** Current specular color for lighting */ + public float currentLightSpecular[]; + + /** Current light falloff */ + public float currentLightFalloffConstant; + public float currentLightFalloffLinear; + public float currentLightFalloffQuadratic; + + // ........................................................ + + /** + * Sets whether texture coordinates passed to + * vertex() calls will be based on coordinates that are + * based on the IMAGE or NORMALIZED. + */ + public int textureMode; + + /** + * Current horizontal coordinate for texture, will always + * be between 0 and 1, even if using textureMode(IMAGE). + */ + public float textureU; + + /** Current vertical coordinate for texture, see above. */ + public float textureV; + + /** Current image being used as a texture */ + public PImage textureImage; + + // ........................................................ + + /** + * Normals + */ + public float normalX, normalY, normalZ; + public int normalMode; + public int normalCount; + + // ........................................................ + + // [toxi031031] new & faster sphere code w/ support flexibile resolutions + // will be set by sphereDetail() or 1st call to sphere() + public int sphereDetail = 0; + + + + ////////////////////////////////////////////////////////////// + + // INTERNAL + + + /** + * Constructor for the PGraphics object. This prototype only exists + * because of annoying java compilers, and cannot be used. + */ + /* + protected PGraphics() { } + */ + + + /** + * Constructor for the PGraphics object. Use this to ensure that + * the defaults get set properly. In a subclass, use this(w, h) + * as the first line of a subclass' constructor to properly set + * the internal fields and defaults. + * + * @param iwidth viewport width + * @param iheight viewport height + * @param parent null unless this is the main drawing surface + */ + public PGraphics(int iwidth, int iheight, PApplet parent) { + this.parent = parent; + if (parent != null) setMainDrawingSurface(); +/* + // if this is being created by createGraphics(), the parent applet + // will be set later via another method. + if (parent != null) { + mainDrawingSurface = true; + // base images must be opaque (for performance and general + // headache reasons.. argh, a semi-transparent opengl surface?) + // use createGraphics() if you want a transparent surface. + format = RGB; + parent.addListeners(); + } +*/ + resize(iwidth, iheight); + } + + + /** + * Set this as the main drawing surface. Meaning that it can safely be + * set to opaque (given a default gray background) and listeners for + * the mouse and keyboard added. + *

    + * This should only be used by subclasses of PGraphics. + */ + public void setMainDrawingSurface() { // ignore + mainDrawingSurface = true; + // base images must be opaque (for performance and general + // headache reasons.. argh, a semi-transparent opengl surface?) + // use createGraphics() if you want a transparent surface. + format = RGB; + parent.addListeners(); + } + + + /** + * Called in repsonse to a resize event, handles setting the + * new width and height internally, as well as re-allocating + * the pixel buffer for the new size. + *

    + * Note that this will nuke any camera settings. + */ + public void resize(int iwidth, int iheight) { // ignore + //System.out.println("resize " + iwidth + " " + iheight); + insideDrawWait(); + insideResize = true; + + width = iwidth; + height = iheight; + width1 = width - 1; + height1 = height - 1; + + allocate(); + + insideResize = false; // ok to draw again + } + + + /** + * Parent thread has requested that visual action be taken. + * This is broken out like this because the OpenGL library + * handles updates in a very different way. + */ + public void requestDisplay(PApplet pa) { // ignore + pa.handleDisplay(); + } + + + // broken out because of subclassing + abstract protected void allocate(); + + + + ////////////////////////////////////////////////////////////// + + // FRAME + + + protected void insideResizeWait() { + /* + while (insideResize) { + //System.out.println("waiting"); + try { + Thread.sleep(5); + } catch (InterruptedException e) { } + } + */ + } + + + protected void insideDrawWait() { + /* + while (insideDraw) { + //System.out.println("waiting"); + try { + Thread.sleep(5); + } catch (InterruptedException e) { } + } + */ + } + + + /** + * Prepares the PGraphics for drawing. + *

    + * When creating your own PGraphics, you should call this before + * drawing anything. + */ + abstract public void beginDraw(); // ignore + + + /** + * This will finalize rendering so that it can be shown on-screen. + *

    + * When creating your own PGraphics, you should call this when + * you're finished drawing. + */ + abstract public void endDraw(); // ignore + + + /** + * Set engine's default values. This has to be called by PApplet, + * somewhere inside setup() or draw() because it talks to the + * graphics buffer, meaning that for subclasses like OpenGL, there + * needs to be a valid graphics context to mess with otherwise + * you'll get some good crashing action. + */ + public void defaults() { // ignore + //System.out.println("PGraphics.defaults() " + width + " " + height); + + colorMode(RGB, 255); + fill(255); + stroke(0); + // other stroke attributes are set in the initializers + // inside the class (see above, strokeWeight = 1 et al) + + // init shape stuff + shape = 0; + + // init matrices (must do before lights) + matrixStackDepth = 0; + + rectMode(CORNER); + ellipseMode(CENTER); + //arcMode(CENTER); + //angleMode(RADIANS); + + // no current font + textFont = null; + textSize = 12; + textLeading = 14; + textAlign = LEFT; + textMode = MODEL; + + // if this fella is associated with an applet, then clear its background. + // if it's been created by someone else through createGraphics, + // they have to call background() themselves, otherwise everything gets + // a gray background (when just a transparent surface or an empty pdf + // is what's desired) + if (mainDrawingSurface) { + //System.out.println("main drawing surface"); + background(backgroundColor); + } + + defaultsInited = true; + } + + + protected void flush() { + // no-op, mostly for P3D to write sorted stuff + } + + + + ////////////////////////////////////////////////////////////// + + // HINTS + + /** + * Enable a hint option. + *

    + * For the most part, hints are temporary api quirks, + * for which a proper api hasn't been properly worked out. + * for instance SMOOTH_IMAGES existed because smooth() + * wasn't yet implemented, but it will soon go away. + *

    + * They also exist for obscure features in the graphics + * engine, like enabling/disabling single pixel lines + * that ignore the zbuffer, the way they do in alphabot. + *

    + * Current hint options: + *

      + *
    • DISABLE_DEPTH_TEST - + * turns off the z-buffer in the P3D or OPENGL renderers. + *
    + */ + public void hint(int which) { + hints[which] = true; + } + + + /** + * Disable a hint. + */ + public void noHint(int which) { + hints[which] = false; + } + + + + ////////////////////////////////////////////////////////////// + + // SHAPES + + /** + * Start a new shape of type POLYGON + */ + public void beginShape() { + beginShape(POLYGON); + } + + + /** + * Start a new shape. + *

    + * Differences between beginShape() and line() and point() methods. + *

    + * beginShape() is intended to be more flexible at the expense of being + * a little more complicated to use. it handles more complicated shapes + * that can consist of many connected lines (so you get joins) or lines + * mixed with curves. + *

    + * The line() and point() command are for the far more common cases + * (particularly for our audience) that simply need to draw a line + * or a point on the screen. + *

    + * From the code side of things, line() may or may not call beginShape() + * to do the drawing. In the beta code, they do, but in the alpha code, + * they did not. they might be implemented one way or the other depending + * on tradeoffs of runtime efficiency vs. implementation efficiency &mdash + * meaning the speed that things run at vs. the speed it takes me to write + * the code and maintain it. for beta, the latter is most important so + * that's how things are implemented. + */ + abstract public void beginShape(int kind); + /* + shape = kind; + + // reset vertex, line and triangle information + // every shape is rendered at endShape(); + vertexCount = 0; + + splineVertexCount = 0; + //spline_vertices_flat = true; + + //strokeChanged = false; + //fillChanged = false; + //normalChanged = false; + */ + + + public void normal(float nx, float ny, float nz) { + //depthError("normal"); + } + + + /** + * Set texture mode to either to use coordinates based on the IMAGE + * (more intuitive for new users) or NORMALIZED (better for advanced chaps) + */ + public void textureMode(int mode) { + this.textureMode = mode; + } + + + /** + * Set texture image for current shape. + * Needs to be called between @see beginShape and @see endShape + * + * @param image reference to a PImage object + */ + public void texture(PImage image) { + textureImage = image; + } + + + /** + * Set (U, V) coords for the next vertex in the current shape. + * This is ugly as its own function, and will (almost?) always be + * coincident with a call to vertex. As of beta, this was moved to + * the protected method you see here, and called from an optional + * param of and overloaded vertex(). + *

    + * The parameters depend on the current textureMode. When using + * textureMode(IMAGE), the coordinates will be relative to the size + * of the image texture, when used with textureMode(NORMAL), + * they'll be in the range 0..1. + *

    + * Used by both PGraphics2D (for images) and PGraphics3D. + */ + protected void textureVertex(float u, float v) { + if (textureImage == null) { + throw new RuntimeException("need to set an image with texture() " + + "before using u and v coordinates"); + } + if (textureMode == IMAGE) { + u /= (float) textureImage.width; + v /= (float) textureImage.height; + } + + textureU = u; + textureV = v; + + if (textureU < 0) textureU = 0; + else if (textureU > 1) textureU = 1; + + if (textureV < 0) textureV = 0; + else if (textureV > 1) textureV = 1; + } + + + // eventually need to push a "default" setup down to this class + abstract public void vertex(float x, float y); + /* + splineVertexCount = 0; + //float vertex[]; + + if (vertexCount == vertices.length) { + float temp[][] = new float[vertexCount<<1][VERTEX_FIELD_COUNT]; + System.arraycopy(vertices, 0, temp, 0, vertexCount); + vertices = temp; + //message(CHATTER, "allocating more vertices " + vertices.length); + } + // not everyone needs this, but just easier to store rather + // than adding another moving part to the code... + vertices[vertexCount][MX] = x; + vertices[vertexCount][MY] = y; + vertexCount++; + + switch (shape) { + + case POINTS: + point(x, y); + break; + + case LINES: + if ((vertexCount % 2) == 0) { + line(vertices[vertexCount-2][MX], + vertices[vertexCount-2][MY], x, y); + } + break; + + case LINE_STRIP: + case LINE_LOOP: + if (vertexCount == 1) { + path = new Path(); + path.moveTo(x, y); + } else { + path.lineTo(x, y); + } + break; + + case TRIANGLES: + if ((vertexCount % 3) == 0) { + triangle(vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY], + vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY], + x, y); + } + break; + + case TRIANGLE_STRIP: + if (vertexCount == 3) { + triangle(vertices[0][MX], vertices[0][MY], + vertices[1][MX], vertices[1][MY], + x, y); + } else if (vertexCount > 3) { + path = new Path(); + // when vertexCount == 4, draw an un-closed triangle + // for indices 2, 3, 1 + path.moveTo(vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY]); + path.lineTo(vertices[vertexCount - 1][MX], + vertices[vertexCount - 1][MY]); + path.lineTo(vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY]); + draw_shape(path); + } + break; + + case TRIANGLE_FAN: + if (vertexCount == 3) { + triangle(vertices[0][MX], vertices[0][MY], + vertices[1][MX], vertices[1][MY], + x, y); + } else if (vertexCount > 3) { + path = new Path(); + // when vertexCount > 3, draw an un-closed triangle + // for indices 0 (center), previous, current + path.moveTo(vertices[0][MX], + vertices[0][MY]); + path.lineTo(vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY]); + path.lineTo(x, y); + draw_shape(path); + } + break; + + case QUADS: + if ((vertexCount % 4) == 0) { + quad(vertices[vertexCount - 4][MX], + vertices[vertexCount - 4][MY], + vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY], + vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY], + x, y); + } + break; + + case QUAD_STRIP: + // 0---2---4 + // | | | + // 1---3---5 + if (vertexCount == 4) { + // note difference in winding order: + quad(vertices[0][MX], vertices[0][MY], + vertices[2][MX], vertices[2][MY], + x, y, + vertices[1][MX], vertices[1][MY]); + + } else if (vertexCount > 4) { + path = new Path(); + // when vertexCount == 5, draw an un-closed triangle + // for indices 2, 4, 5, 3 + path.moveTo(vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY]); + path.lineTo(vertices[vertexCount - 1][MX], + vertices[vertexCount - 1][MY]); + path.lineTo(x, y); + path.lineTo(vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY]); + draw_shape(path); + } + break; + + case POLYGON: + //case CONCAVE_POLYGON: + //case CONVEX_POLYGON: + if (vertexCount == 1) { + path = new Path(); + path.moveTo(x, y); + } else { + path.lineTo(x, y); + } + break; + } + */ + + + abstract public void vertex(float x, float y, float z); + + + abstract public void vertex(float x, float y, float u, float v); + + + abstract public void vertex(float x, float y, float z, float u, float v); + + + public void bezierVertex(float x2, float y2, + float x3, float y3, + float x4, float y4) { + bezierVertex(x2, y2, Float.MAX_VALUE, + x3, y3, Float.MAX_VALUE, + x4, y4, Float.MAX_VALUE); + } + + + /** + * See notes with the bezier() function. + */ + public void bezierVertex(float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + if (shape != POLYGON) { + throw new RuntimeException("beginShape() and vertex() " + + "must be used before bezierVertex()"); + } + if (splineVertexCount > 0) { + float vertex[] = splineVertices[splineVertexCount-1]; + splineVertex(vertex[MX], vertex[MY], vertex[MZ], true); + + } else if (vertexCount > 0) { + // make sure there's at least a call to vertex() + float vertex[] = vertices[vertexCount-1]; + splineVertex(vertex[MX], vertex[MY], vertex[MZ], true); + + } else { + throw new RuntimeException("A call to vertex() must be used " + + "before bezierVertex()"); + } + splineVertex(x2, y2, z2, true); + splineVertex(x3, y3, z3, true); + splineVertex(x4, y4, z4, true); + } + + + /** + * See notes with the curve() function. + */ + public void curveVertex(float x, float y) { + splineVertex(x, y, Float.MAX_VALUE, false); + } + + + /** + * See notes with the curve() function. + */ + public void curveVertex(float x, float y, float z) { + splineVertex(x, y, z, false); + } + + + /** + * Implementation of generic spline vertex, will add coords to + * the splineVertices[] array and emit calls to draw segments + * as needed (every fourth point for bezier or every point starting + * with the fourth for catmull-rom). + * @param z z-coordinate, set to MAX_VALUE if it's 2D + * @param bezier true if it's a bezier instead of catmull-rom + */ + protected void splineVertex(float x, float y, float z, boolean bezier) { + // to improve processing applet load times, don't allocate + // space for the vertex data until actual use + if (splineVertices == null) { + splineVertices = new float[DEFAULT_SPLINE_VERTICES][VERTEX_FIELD_COUNT]; + } + + // if more than 128 points, shift everything back to the beginning + if (splineVertexCount == DEFAULT_SPLINE_VERTICES) { + System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES-3], 0, + splineVertices[0], 0, VERTEX_FIELD_COUNT); + System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES-2], 0, + splineVertices[1], 0, VERTEX_FIELD_COUNT); + System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES-1], 0, + splineVertices[2], 0, VERTEX_FIELD_COUNT); + splineVertexCount = 3; + } + + float vertex[] = splineVertices[splineVertexCount]; + + vertex[MX] = x; + vertex[MY] = y; + + if (fill) { + vertex[R] = fillR; + vertex[G] = fillG; + vertex[B] = fillB; + vertex[A] = fillA; + } + + if (stroke) { + vertex[SR] = strokeR; + vertex[SG] = strokeG; + vertex[SB] = strokeB; + vertex[SA] = strokeA; + vertex[SW] = strokeWeight; + } + + if (textureImage != null) { + vertex[U] = textureU; + vertex[V] = textureV; + } + + // when the coords are Float.MAX_VALUE, then treat as a 2D curve + int dimensions = (z == Float.MAX_VALUE) ? 2 : 3; + + if (dimensions == 3) { + vertex[MZ] = z; + + vertex[NX] = normalX; + vertex[NY] = normalY; + vertex[NZ] = normalZ; + } + + splineVertexCount++; + + // draw a segment if there are enough points + if (splineVertexCount > 3) { + if (bezier) { + if ((splineVertexCount % 4) == 0) { + if (!bezierInited) bezierInit(); + splineSegment(splineVertexCount-4, + splineVertexCount-4, + bezierDrawMatrix, dimensions, + bezierDetail); + } + } else { // catmull-rom curve (!bezier) + if (!curve_inited) curve_init(); + splineSegment(splineVertexCount-4, + splineVertexCount-3, + curve_draw, dimensions, + curveDetail); + } + } + } + + + /** This feature is in testing, do not use or rely upon its implementation */ + public void breakShape() { + } + + + public final void endShape() { + endShape(OPEN); + } + + + abstract public void endShape(int mode); + + + + ////////////////////////////////////////////////////////////// + + // COMPOUND PATHS + + + /** + * Begin a new path. This can be used after beginShape() to draw + * a compound path (i.e. to draw shape with a hole on the interior) + * For instance, to draw a shape that has a hole in its interior, + * the format would be: + *

    +   * beginShape();
    +   * beginPath();
    +   * // multiple calls to vertex() that draw the exterior shape
    +   * endPath();
    +   * beginPath();
    +   * // several calls to vertex() to draw the interior hole
    +   * endPath();
    +   * // more beginPath/endPath pairs can be used for additional holes
    +   * endShape();
    +   * 
    + *

    + * This will probably be available only with the OpenGL renderer, + * because it has a built-in tesselator from GLU. + */ + //public void beginPath() { + //throw new RuntimeException("beginPath() is not available"); + //} + + + /** + * End a path. Use this with beginPath() to close out a compound path. + *

    + * This will probably be available only with the OpenGL renderer, + * because it has a built-in tesselator from GLU. + */ + //public void endPath() { + //throw new RuntimeException("endPath() is not available"); + //} + + + + ////////////////////////////////////////////////////////////// + + // SIMPLE SHAPES WITH ANALOGUES IN beginShape() + + + public void point(float x, float y) { + beginShape(POINTS); + vertex(x, y); + endShape(); + } + + + public void point(float x, float y, float z) { + beginShape(POINTS); + vertex(x, y, z); + endShape(); + } + + + public void line(float x1, float y1, float x2, float y2) { + beginShape(LINES); + vertex(x1, y1); + vertex(x2, y2); + endShape(); + } + + + public void line(float x1, float y1, float z1, + float x2, float y2, float z2) { + beginShape(LINES); + vertex(x1, y1, z1); + vertex(x2, y2, z2); + endShape(); + } + + + public void triangle(float x1, float y1, float x2, float y2, + float x3, float y3) { + beginShape(TRIANGLES); + vertex(x1, y1); + vertex(x2, y2); + vertex(x3, y3); + endShape(); + } + + + public void quad(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { + beginShape(QUADS); + vertex(x1, y1); + vertex(x2, y2); + vertex(x3, y3); + vertex(x4, y4); + endShape(); + } + + + + ////////////////////////////////////////////////////////////// + + // RECT + + + public void rectMode(int mode) { + rectMode = mode; + } + + + public void rect(float x1, float y1, float x2, float y2) { + float hradius, vradius; + switch (rectMode) { + case CORNERS: + break; + case CORNER: + x2 += x1; y2 += y1; + break; + case RADIUS: + hradius = x2; + vradius = y2; + x2 = x1 + hradius; + y2 = y1 + vradius; + x1 -= hradius; + y1 -= vradius; + break; + case CENTER: + hradius = x2 / 2.0f; + vradius = y2 / 2.0f; + x2 = x1 + hradius; + y2 = y1 + vradius; + x1 -= hradius; + y1 -= vradius; + } + + if (x1 > x2) { + float temp = x1; x1 = x2; x2 = temp; + } + + if (y1 > y2) { + float temp = y1; y1 = y2; y2 = temp; + } + + rectImpl(x1, y1, x2, y2); + } + + + protected void rectImpl(float x1, float y1, float x2, float y2) { + quad(x1, y1, x2, y1, x2, y2, x1, y2); + } + + + + ////////////////////////////////////////////////////////////// + + // ELLIPSE AND ARC + + + public void ellipseMode(int mode) { + ellipseMode = mode; + } + + + public void ellipse(float a, float b, float c, float d) { + float x = a; + float y = b; + float w = c; + float h = d; + + if (ellipseMode == CORNERS) { + w = c - a; + h = d - b; + + } else if (ellipseMode == RADIUS) { + x = a - c; + y = b - d; + w = c * 2; + h = d * 2; + + } else if (ellipseMode == CENTER) { + x = a - c/2f; + y = b - d/2f; + } + + if (w < 0) { // undo negative width + x += w; + w = -w; + } + + if (h < 0) { // undo negative height + y += h; + h = -h; + } + + ellipseImpl(x, y, w, h); + } + + + protected void ellipseImpl(float x1, float y1, float w, float h) { + float hradius = w / 2f; + float vradius = h / 2f; + + float centerX = x1 + hradius; + float centerY = y1 + vradius; + + // adapt accuracy to radii used w/ a minimum of 4 segments [toxi] + // now uses current scale factors to determine "real" transformed radius + + //int cAccuracy = (int)(4+Math.sqrt(hradius*abs(m00)+vradius*abs(m11))*2); + //int cAccuracy = (int)(4+Math.sqrt(hradius+vradius)*2); + + // notched this up to *3 instead of *2 because things were + // looking a little rough, i.e. the calculate->arctangent example [fry] + + // also removed the m00 and m11 because those were causing weirdness + // need an actual measure of magnitude in there [fry] + + int accuracy = (int)(4+Math.sqrt(hradius+vradius)*3); + //System.out.println("accuracy is " + accuracy); + + // [toxi031031] adapted to use new lookup tables + float inc = (float)SINCOS_LENGTH / accuracy; + + float val = 0; + /* + beginShape(POLYGON); + for (int i = 0; i < cAccuracy; i++) { + vertex(centerX + cosLUT[(int) val] * hradius, + centerY + sinLUT[(int) val] * vradius); + val += inc; + } + endShape(); + */ + + if (fill) { + boolean savedStroke = stroke; + stroke = false; + + beginShape(TRIANGLE_FAN); + normal(0, 0, 1); + vertex(centerX, centerY); + for (int i = 0; i < accuracy; i++) { + vertex(centerX + cosLUT[(int) val] * hradius, + centerY + sinLUT[(int) val] * vradius); + val += inc; + } + // back to the beginning + vertex(centerX + cosLUT[0] * hradius, + centerY + sinLUT[0] * vradius); + endShape(); + + stroke = savedStroke; + } + + if (stroke) { + boolean savedFill = fill; + fill = false; + + val = 0; + beginShape(); //LINE_LOOP); + for (int i = 0; i < accuracy; i++) { + vertex(centerX + cosLUT[(int) val] * hradius, + centerY + sinLUT[(int) val] * vradius); + val += inc; + } + endShape(CLOSE); + + fill = savedFill; + } + } + + + /** + * Identical parameters and placement to ellipse, + * but draws only an arc of that ellipse. + *

    + * start and stop are always radians because angleMode() was goofy. + * ellipseMode() sets the placement. + *

    + * also tries to be smart about start < stop. + */ + public void arc(float a, float b, float c, float d, + float start, float stop) { + float x = a; + float y = b; + float w = c; + float h = d; + + if (ellipseMode == CORNERS) { + w = c - a; + h = d - b; + + } else if (ellipseMode == RADIUS) { + x = a - c; + y = b - d; + w = c * 2; + h = d * 2; + + } else if (ellipseMode == CENTER) { + x = a - c/2f; + y = b - d/2f; + } + + //if (angleMode == DEGREES) { + //start = start * DEG_TO_RAD; + //stop = stop * DEG_TO_RAD; + //} + // before running a while loop like this, + // make sure it will exit at some point. + if (Float.isInfinite(start) || Float.isInfinite(stop)) return; + while (stop < start) stop += TWO_PI; + + arcImpl(x, y, w, h, start, stop); + } + + + /** + * Start and stop are in radians, converted by the parent function. + * Note that the radians can be greater (or less) than TWO_PI. + * This is so that an arc can be drawn that crosses zero mark, + * and the user will still collect $200. + */ + protected void arcImpl(float x1, float y1, float w, float h, + float start, float stop) { + float hr = w / 2f; + float vr = h / 2f; + + float centerX = x1 + hr; + float centerY = y1 + vr; + + if (fill) { + // shut off stroke for a minute + boolean savedStroke = stroke; + stroke = false; + + int startLUT = (int) (0.5f + (start / TWO_PI) * SINCOS_LENGTH); + int stopLUT = (int) (0.5f + (stop / TWO_PI) * SINCOS_LENGTH); + + beginShape(TRIANGLE_FAN); + vertex(centerX, centerY); + int increment = 1; // what's a good algorithm? stopLUT - startLUT; + for (int i = startLUT; i < stopLUT; i += increment) { + int ii = i % SINCOS_LENGTH; + vertex(centerX + cosLUT[ii] * hr, + centerY + sinLUT[ii] * vr); + } + // draw last point explicitly for accuracy + vertex(centerX + cosLUT[stopLUT % SINCOS_LENGTH] * hr, + centerY + sinLUT[stopLUT % SINCOS_LENGTH] * vr); + endShape(); + + stroke = savedStroke; + } + + if (stroke) { + // Almost identical to above, but this uses a LINE_STRIP + // and doesn't include the first (center) vertex. + + boolean savedFill = fill; + fill = false; + + int startLUT = (int) (0.5f + (start / TWO_PI) * SINCOS_LENGTH); + int stopLUT = (int) (0.5f + (stop / TWO_PI) * SINCOS_LENGTH); + + beginShape(); //LINE_STRIP); + int increment = 1; // what's a good algorithm? stopLUT - startLUT; + for (int i = startLUT; i < stopLUT; i += increment) { + int ii = i % SINCOS_LENGTH; + vertex(centerX + cosLUT[ii] * hr, + centerY + sinLUT[ii] * vr); + } + // draw last point explicitly for accuracy + vertex(centerX + cosLUT[stopLUT % SINCOS_LENGTH] * hr, + centerY + sinLUT[stopLUT % SINCOS_LENGTH] * vr); + endShape(); + + fill = savedFill; + } + } + + + + ////////////////////////////////////////////////////////////// + + // BOX & SPHERE + + + public void box(float size) { + depthError("box"); + } + + public void box(float w, float h, float d) { + depthError("box"); + } + + public void sphereDetail(int res) { + depthError("sphereDetail"); + } + + public void sphere(float r) { + depthError("sphere"); + } + + + + ////////////////////////////////////////////////////////////// + + // BEZIER + + + /** + * Evalutes quadratic bezier at point t for points a, b, c, d. + * t varies between 0 and 1, and a and d are the on curve points, + * b and c are the control points. this can be done once with the + * x coordinates and a second time with the y coordinates to get + * the location of a bezier curve at t. + *

    + * For instance, to convert the following example:

    +   * stroke(255, 102, 0);
    +   * line(85, 20, 10, 10);
    +   * line(90, 90, 15, 80);
    +   * stroke(0, 0, 0);
    +   * bezier(85, 20, 10, 10, 90, 90, 15, 80);
    +   *
    +   * // draw it in gray, using 10 steps instead of the default 20
    +   * // this is a slower way to do it, but useful if you need
    +   * // to do things with the coordinates at each step
    +   * stroke(128);
    +   * beginShape(LINE_STRIP);
    +   * for (int i = 0; i <= 10; i++) {
    +   *   float t = i / 10.0f;
    +   *   float x = bezierPoint(85, 10, 90, 15, t);
    +   *   float y = bezierPoint(20, 10, 90, 80, t);
    +   *   vertex(x, y);
    +   * }
    +   * endShape();
    + */ + public float bezierPoint(float a, float b, float c, float d, float t) { + float t1 = 1.0f - t; + return a*t1*t1*t1 + 3*b*t*t1*t1 + 3*c*t*t*t1 + d*t*t*t; + } + + + /** + * Provide the tangent at the given point on the bezier curve. + * Based on code from v3ga's wordstree sketch. + */ + public float bezierTangent(float a, float b, float c, float d, float t) { + float t1 = 1.0f - t; + + return (a * 3 * t*t + + b * 3 * t * (2 - 3*t) + + c * 3 * (3*t*t - 4*t + 1) + + d * -3 * t1*t1); + } + + + protected void bezierInit() { + bezierDetail(bezierDetail); + } + + + public void bezierDetail(int detail) { + if (bezierForwardMatrix == null) { + bezierForwardMatrix = new float[4][4]; + bezierDrawMatrix = new float[4][4]; + } + bezierDetail = detail; + bezierInited = true; + + // setup matrix for forward differencing to speed up drawing + setup_spline_forward(detail, bezierForwardMatrix); + + // multiply the basis and forward diff matrices together + // saves much time since this needn't be done for each curve + mult_spline_matrix(bezierForwardMatrix, bezier_basis, bezierDrawMatrix, 4); + } + + + /** + * Draw a cubic bezier curve. The first and last points are + * the on-curve points. The middle two are the 'control' points, + * or 'handles' in an application like Illustrator. + *

    + * Identical to typing: + *

    beginShape();
    +   * vertex(x1, y1);
    +   * bezierVertex(x2, y2, x3, y3, x4, y4);
    +   * endShape();
    +   * 
    + * In Postscript-speak, this would be: + *
    moveto(x1, y1);
    +   * curveto(x2, y2, x3, y3, x4, y4);
    + * If you were to try and continue that curve like so: + *
    curveto(x5, y5, x6, y6, x7, y7);
    + * This would be done in processing by adding these statements: + *
    bezierVertex(x5, y5, x6, y6, x7, y7)
    +   * 
    + * To draw a quadratic (instead of cubic) curve, + * use the control point twice by doubling it: + *
    bezier(x1, y1, cx, cy, cx, cy, x2, y2);
    + */ + public void bezier(float x1, float y1, + float x2, float y2, + float x3, float y3, + float x4, float y4) { + beginShape(); //LINE_STRIP); + vertex(x1, y1); + bezierVertex(x2, y2, x3, y3, x4, y4); + endShape(); + } + + + public void bezier(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + beginShape(); //LINE_STRIP); + vertex(x1, y1, z1); + bezierVertex(x2, y2, z2, + x3, y3, z3, + x4, y4, z4); + endShape(); + } + + + + ////////////////////////////////////////////////////////////// + + // CATMULL-ROM CURVE + + + /** + * Get a location along a catmull-rom curve segment. + * + * @param t Value between zero and one for how far along the segment + */ + public float curvePoint(float a, float b, float c, float d, float t) { + if (!curve_inited) curve_init(); + + float tt = t * t; + float ttt = t * tt; + float m[][] = curve_basis; + + // not optimized (and probably need not be) + return (a * (ttt*m[0][0] + tt*m[1][0] + t*m[2][0] + m[3][0]) + + b * (ttt*m[0][1] + tt*m[1][1] + t*m[2][1] + m[3][1]) + + c * (ttt*m[0][2] + tt*m[1][2] + t*m[2][2] + m[3][2]) + + d * (ttt*m[0][3] + tt*m[1][3] + t*m[2][3] + m[3][3])); + } + + + public float curveTangent(float a, float b, float c, float d, + float t) { + System.err.println("curveTangent not yet implemented"); + return 0; + } + + + public void curveDetail(int detail) { + curve_mode(detail, curveTightness); + } + + + public void curveTightness(float tightness) { + curve_mode(curveDetail, tightness); + } + + + protected void curve_init() { + curve_mode(curveDetail, curveTightness); + } + + + /** + * Set the number of segments to use when drawing a Catmull-Rom + * curve, and setting the s parameter, which defines how tightly + * the curve fits to each vertex. Catmull-Rom curves are actually + * a subset of this curve type where the s is set to zero. + *

    + * (This function is not optimized, since it's not expected to + * be called all that often. there are many juicy and obvious + * opimizations in here, but it's probably better to keep the + * code more readable) + */ + protected void curve_mode(int segments, float s) { + curveDetail = segments; + + if (curve_basis == null) { + // allocate these when used, to save startup time + curve_basis = new float[4][4]; + curve_forward = new float[4][4]; + curve_draw = new float[4][4]; + curve_inited = true; + } + + float c[][] = curve_basis; + + c[0][0] = s-1; c[0][1] = s+3; c[0][2] = -3-s; c[0][3] = 1-s; + c[1][0] = 2*(1-s); c[1][1] = -5-s; c[1][2] = 2*(s+2); c[1][3] = s-1; + c[2][0] = s-1; c[2][1] = 0; c[2][2] = 1-s; c[2][3] = 0; + c[3][0] = 0; c[3][1] = 2; c[3][2] = 0; c[3][3] = 0; + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + c[i][j] /= 2f; + } + } + setup_spline_forward(segments, curve_forward); + + if (bezierBasisInverse == null) { + bezierBasisInverse = new PMatrix(bezierBasis).invert(); + } + + // hack here to get PGraphics2 working + curveToBezierMatrix = new PMatrix(c[0][0], c[0][1], c[0][2], c[0][3], + c[1][0], c[1][1], c[1][2], c[1][3], + c[2][0], c[2][1], c[2][2], c[2][3], + c[3][0], c[3][1], c[3][2], c[3][3]); + curveToBezierMatrix.preApply(bezierBasisInverse); + + // multiply the basis and forward diff matrices together + // saves much time since this needn't be done for each curve + mult_spline_matrix(curve_forward, curve_basis, curve_draw, 4); + } + + + /** + * Draws a segment of Catmull-Rom curve. + *

    + * As of 0070, this function no longer doubles the first and + * last points. The curves are a bit more boring, but it's more + * mathematically correct, and properly mirrored in curvePoint(). + *

    + * Identical to typing out:

    +   * beginShape();
    +   * curveVertex(x1, y1);
    +   * curveVertex(x2, y2);
    +   * curveVertex(x3, y3);
    +   * curveVertex(x4, y4);
    +   * endShape();
    +   * 
    + */ + public void curve(float x1, float y1, + float x2, float y2, + float x3, float y3, + float x4, float y4) { + beginShape(); //LINE_STRIP); + curveVertex(x1, y1); + curveVertex(x2, y2); + curveVertex(x3, y3); + curveVertex(x4, y4); + endShape(); + } + + + public void curve(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + beginShape(); //LINE_STRIP); + curveVertex(x1, y1, z1); + curveVertex(x2, y2, z2); + curveVertex(x3, y3, z3); + curveVertex(x4, y4, z4); + endShape(); + } + + + + ////////////////////////////////////////////////////////////// + + // SPLINE UTILITY FUNCTIONS (used by both Bezier and Catmull-Rom) + + + /** + * Setup forward-differencing matrix to be used for speedy + * curve rendering. It's based on using a specific number + * of curve segments and just doing incremental adds for each + * vertex of the segment, rather than running the mathematically + * expensive cubic equation. + * @param segments number of curve segments to use when drawing + */ + protected void setup_spline_forward(int segments, float fwd[][]) { + float f = 1.0f / segments; + float ff = f * f; + float fff = ff * f; + + fwd[0][0] = 0; fwd[0][1] = 0; fwd[0][2] = 0; fwd[0][3] = 1; + fwd[1][0] = fff; fwd[1][1] = ff; fwd[1][2] = f; fwd[1][3] = 0; + fwd[2][0] = 6*fff; fwd[2][1] = 2*ff; fwd[2][2] = 0; fwd[2][3] = 0; + fwd[3][0] = 6*fff; fwd[3][1] = 0; fwd[3][2] = 0; fwd[3][3] = 0; + } + + + // internal matrix multiplication routine used by the spline code + // should these go to 4 instead of 3? + //void mult_curve_matrix(float m[4][4], float g[4][3], float mg[4][3]); + protected void mult_spline_matrix(float m[][], float g[][], + float mg[][], int dimensions) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < dimensions; j++) { + mg[i][j] = 0; + } + } + for (int i = 0; i < 4; i++) { + for (int j = 0; j < dimensions; j++) { + for (int k = 0; k < 4; k++) { + mg[i][j] = mg[i][j] + (m[i][k] * g[k][j]); + } + } + } + } + + + /** + * Draw a segment of spline (bezier or catmull-rom curve) + * using the matrix m, which is the basis matrix already + * multiplied with the forward differencing matrix. + *

    + * the x0, y0, z0 points are the point that's being used as + * the start, and also as the accumulator. for bezier curves, + * the x1, y1, z1 are the first point drawn, and added to. + * for catmull-rom curves, the first control point (x2, y2, z2) + * is the first drawn point, and is accumulated to. + */ + protected void splineSegment(int offset, int start, float m[][], + int dimensions, int segments) { + float x1 = splineVertices[offset+0][MX]; + float x2 = splineVertices[offset+1][MX]; + float x3 = splineVertices[offset+2][MX]; + float x4 = splineVertices[offset+3][MX]; + float x0 = splineVertices[start][MX]; + + float y1 = splineVertices[offset+0][MY]; + float y2 = splineVertices[offset+1][MY]; + float y3 = splineVertices[offset+2][MY]; + float y4 = splineVertices[offset+3][MY]; + float y0 = splineVertices[start][MY]; + + float xplot1 = m[1][0]*x1 + m[1][1]*x2 + m[1][2]*x3 + m[1][3]*x4; + float xplot2 = m[2][0]*x1 + m[2][1]*x2 + m[2][2]*x3 + m[2][3]*x4; + float xplot3 = m[3][0]*x1 + m[3][1]*x2 + m[3][2]*x3 + m[3][3]*x4; + + float yplot1 = m[1][0]*y1 + m[1][1]*y2 + m[1][2]*y3 + m[1][3]*y4; + float yplot2 = m[2][0]*y1 + m[2][1]*y2 + m[2][2]*y3 + m[2][3]*y4; + float yplot3 = m[3][0]*y1 + m[3][1]*y2 + m[3][2]*y3 + m[3][3]*y4; + + // vertex() will reset splineVertexCount, so save it + int cvertexSaved = splineVertexCount; + + if (dimensions == 3) { + float z1 = splineVertices[offset+0][MZ]; + float z2 = splineVertices[offset+1][MZ]; + float z3 = splineVertices[offset+2][MZ]; + float z4 = splineVertices[offset+3][MZ]; + float z0 = splineVertices[start][MZ]; + + float zplot1 = m[1][0]*z1 + m[1][1]*z2 + m[1][2]*z3 + m[1][3]*z4; + float zplot2 = m[2][0]*z1 + m[2][1]*z2 + m[2][2]*z3 + m[2][3]*z4; + float zplot3 = m[3][0]*z1 + m[3][1]*z2 + m[3][2]*z3 + m[3][3]*z4; + + vertex(x0, y0, z0); + for (int j = 0; j < segments; j++) { + x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3; + y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3; + z0 += zplot1; zplot1 += zplot2; zplot2 += zplot3; + vertex(x0, y0, z0); + } + } else { + vertex(x0, y0); + for (int j = 0; j < segments; j++) { + x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3; + y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3; + vertex(x0, y0); + } + } + splineVertexCount = cvertexSaved; + } + + + /* + protected void spline2_segment(int offset, int start, + float m[][], int segments) { + float x1 = splineVertices[offset][MX]; + float y1 = splineVertices[offset][MY]; + + float x2 = splineVertices[offset+1][MX]; + float y2 = splineVertices[offset+1][MY]; + + float x3 = splineVertices[offset+2][MX]; + float y3 = splineVertices[offset+2][MY]; + + float x4 = splineVertices[offset+3][MX]; + float y4 = splineVertices[offset+3][MY]; + + float x0 = splineVertices[start][MX]; + float y0 = splineVertices[start][MY]; + + float xplot1 = m[1][0]*x1 + m[1][1]*x2 + m[1][2]*x3 + m[1][3]*x4; + float xplot2 = m[2][0]*x1 + m[2][1]*x2 + m[2][2]*x3 + m[2][3]*x4; + float xplot3 = m[3][0]*x1 + m[3][1]*x2 + m[3][2]*x3 + m[3][3]*x4; + + float yplot1 = m[1][0]*y1 + m[1][1]*y2 + m[1][2]*y3 + m[1][3]*y4; + float yplot2 = m[2][0]*y1 + m[2][1]*y2 + m[2][2]*y3 + m[2][3]*y4; + float yplot3 = m[3][0]*y1 + m[3][1]*y2 + m[3][2]*y3 + m[3][3]*y4; + + // vertex() will reset splineVertexCount, so save it + int splineVertexSaved = splineVertexCount; + vertex(x0, y0); + for (int j = 0; j < segments; j++) { + x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3; + y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3; + vertex(x0, y0); + } + splineVertexCount = splineVertexSaved; + } + + + protected void spline3_segment(int offset, int start, + float m[][], int segments) { + float x1 = splineVertices[offset+0][MX]; + float y1 = splineVertices[offset+0][MY]; + float z1 = splineVertices[offset+0][MZ]; + + float x2 = splineVertices[offset+1][MX]; + float y2 = splineVertices[offset+1][MY]; + float z2 = splineVertices[offset+1][MZ]; + + float x3 = splineVertices[offset+2][MX]; + float y3 = splineVertices[offset+2][MY]; + float z3 = splineVertices[offset+2][MZ]; + + float x4 = splineVertices[offset+3][MX]; + float y4 = splineVertices[offset+3][MY]; + float z4 = splineVertices[offset+3][MZ]; + + float x0 = splineVertices[start][MX]; + float y0 = splineVertices[start][MY]; + float z0 = splineVertices[start][MZ]; + + float xplot1 = m[1][0]*x1 + m[1][1]*x2 + m[1][2]*x3 + m[1][3]*x4; + float xplot2 = m[2][0]*x1 + m[2][1]*x2 + m[2][2]*x3 + m[2][3]*x4; + float xplot3 = m[3][0]*x1 + m[3][1]*x2 + m[3][2]*x3 + m[3][3]*x4; + + float yplot1 = m[1][0]*y1 + m[1][1]*y2 + m[1][2]*y3 + m[1][3]*y4; + float yplot2 = m[2][0]*y1 + m[2][1]*y2 + m[2][2]*y3 + m[2][3]*y4; + float yplot3 = m[3][0]*y1 + m[3][1]*y2 + m[3][2]*y3 + m[3][3]*y4; + + float zplot1 = m[1][0]*z1 + m[1][1]*z2 + m[1][2]*z3 + m[1][3]*z4; + float zplot2 = m[2][0]*z1 + m[2][1]*z2 + m[2][2]*z3 + m[2][3]*z4; + float zplot3 = m[3][0]*z1 + m[3][1]*z2 + m[3][2]*z3 + m[3][3]*z4; + + // vertex() will reset splineVertexCount, so save it + int cvertexSaved = splineVertexCount; + vertex(x0, y0, z0); + for (int j = 0; j < segments; j++) { + x0 += xplot1; xplot1 += xplot2; xplot2 += xplot3; + y0 += yplot1; yplot1 += yplot2; yplot2 += yplot3; + z0 += zplot1; zplot1 += zplot2; zplot2 += zplot3; + vertex(x0, y0, z0); + } + splineVertexCount = cvertexSaved; + } + */ + + + + ////////////////////////////////////////////////////////////// + + // IMAGE + + + public void image(PImage image, float x, float y) { + imageImpl(image, + x, y, x+image.width, y+image.height, + 0, 0, image.width, image.height); + } + + + public void image(PImage image, + float x, float y, float c, float d) { + image(image, x, y, c, d, 0, 0, image.width, image.height); + } + + + /** + * u, v coordinates are always based on image space location, + * regardless of the current textureMode(). + */ + public void image(PImage image, + float a, float b, float c, float d, + int u1, int v1, int u2, int v2) { + if (imageMode == CORNER) { + if (c < 0) { // reset a negative width + a += c; c = -c; + } + if (d < 0) { // reset a negative height + b += d; d = -d; + } + + imageImpl(image, + a, b, a + c, b + d, + u1, v1, u2, v2); + + } else if (imageMode == CORNERS) { + if (c < a) { // reverse because x2 < x1 + float temp = a; a = c; c = temp; + } + if (d < b) { // reverse because y2 < y1 + float temp = b; b = d; d = temp; + } + + imageImpl(image, + a, b, c, d, + u1, v1, u2, v2); + } + } + + + /** + * Expects x1, y1, x2, y2 coordinates where (x2 >= x1) and (y2 >= y1). + * If tint() has been called, the image will be colored. + *

    + * The default implementation draws an image as a textured quad. + * The (u, v) coordinates are in image space (they're ints, after all..) + */ + protected void imageImpl(PImage image, + float x1, float y1, float x2, float y2, + int u1, int v1, int u2, int v2) { + boolean savedStroke = stroke; + boolean savedFill = fill; + int savedTextureMode = textureMode; + + stroke = false; + fill = true; + textureMode = IMAGE; + + float savedFillR = fillR; + float savedFillG = fillG; + float savedFillB = fillB; + float savedFillA = fillA; + + if (tint) { + fillR = tintR; + fillG = tintG; + fillB = tintB; + fillA = tintA; + + } else { + fillR = 1; + fillG = 1; + fillB = 1; + fillA = 1; + } + + //System.out.println(fill + " " + fillR + " " + fillG + " " + fillB); + + beginShape(QUADS); + texture(image); + vertex(x1, y1, u1, v1); + vertex(x1, y2, u1, v2); + vertex(x2, y2, u2, v2); + vertex(x2, y1, u2, v1); + endShape(); + + stroke = savedStroke; + fill = savedFill; + textureMode = savedTextureMode; + + fillR = savedFillR; + fillG = savedFillG; + fillB = savedFillB; + fillA = savedFillA; + } + + + + ////////////////////////////////////////////////////////////// + + // TEXT/FONTS + + + /** + * Sets the alignment of the text to one of LEFT, CENTER, or RIGHT. + * This will also reset the vertical text alignment to BASELINE. + */ + public void textAlign(int align) { + textAlign(align, BASELINE); + } + + + /** + * Sets the horizontal and vertical alignment of the text. The horizontal + * alignment can be one of LEFT, CENTER, or RIGHT. The vertical alignment + * can be TOP, BOTTOM, CENTER, or the BASELINE (the default). + */ + public void textAlign(int alignX, int alignY) { + textAlign = alignX; + textAlignY = alignY; + } + + + /** + * Returns the ascent of the current font at the current size. + * This is a method, rather than a variable inside the PGraphics object + * because it requires calculation. + */ + public float textAscent() { + if (textFont == null) { + throw new RuntimeException("use textFont() before textAscent()"); + } + + return textFont.ascent() * + ((textMode == SCREEN) ? textFont.size : textSize); + } + + + /** + * Returns the descent of the current font at the current size. + * This is a method, rather than a variable inside the PGraphics object + * because it requires calculation. + */ + public float textDescent() { + if (textFont != null) { + return textFont.descent() * + ((textMode == SCREEN) ? textFont.size : textSize); + + } else { + throw new RuntimeException("use textFont() before textDescent()"); + } + } + + + /** + * Sets the current font. The font's size will be the "natural" + * size of this font (the size that was set when using "Create Font"). + * The leading will also be reset. + */ + public void textFont(PFont which) { + if (which != null) { + textFont = which; + if (hints[ENABLE_NATIVE_FONTS]) { + if (which.font == null) { + which.findFont(); + } + } + textFontNative = which.font; + + //textFontNativeMetrics = null; + // changed for rev 0104 for textMode(SHAPE) in opengl + if (textFontNative != null) { + // TODO need a better way to handle this. could use reflection to get + // rid of the warning, but that'd be a little silly. supporting this is + // an artifact of supporting java 1.1, otherwise we'd use getLineMetrics, + // as recommended by the @deprecated flag. + textFontNativeMetrics = + Toolkit.getDefaultToolkit().getFontMetrics(textFontNative); + } + textSize(which.size); + + } else { + throw new RuntimeException("a null PFont was passed to textFont()"); + } + } + + + /** + * Useful function to set the font and size at the same time. + */ + public void textFont(PFont which, float size) { + textFont(which); + textSize(size); + } + + + /** + * Set the text leading to a specific value. If using a custom + * value for the text leading, you'll have to call textLeading() + * again after any calls to textSize(). + */ + public void textLeading(float leading) { + textLeading = leading; + } + + + /** + * Sets the text rendering/placement to be either SCREEN (direct + * to the screen, exact coordinates, only use the font's original size) + * or MODEL (the default, where text is manipulated by translate() and + * can have a textSize). The text size cannot be set when using + * textMode(SCREEN), because it uses the pixels directly from the font. + */ + public void textMode(int mode) { + // CENTER and MODEL overlap (they're both 3) + if ((mode == LEFT) || (mode == RIGHT)) { + throw new RuntimeException("textMode() is now textAlign() " + + "in Processing beta"); + } + if ((mode != SCREEN) && (mode != MODEL)) { + throw new RuntimeException("Only textMode(SCREEN) and textMode(MODEL) " + + "are available with this renderer."); + } + + //if (textFont != null) { + textMode = mode; + + // reset the font to its natural size + // (helps with width calculations and all that) + //if (textMode == SCREEN) { + //textSize(textFont.size); + //} + + //} else { + //throw new RuntimeException("use textFont() before textMode()"); + //} + } + + + /** + * Sets the text size, also resets the value for the leading. + */ + public void textSize(float size) { + if (textFont != null) { + if ((textMode == SCREEN) && (size != textFont.size)) { + throw new RuntimeException("textSize() cannot be used with " + + "textMode(SCREEN)"); + } + textSize = size; + //textLeading = textSize * + // ((textFont.ascent() + textFont.descent()) * 1.275f); + textLeading = (textAscent() + textDescent()) * 1.275f; + + } else { + throw new RuntimeException("Use textFont() before textSize()"); + } + } + + + // ........................................................ + + + public float textWidth(char c) { + textBuffer[0] = c; + return textWidthImpl(textBuffer, 0, 1); + } + + + /** + * Return the width of a line of text. If the text has multiple + * lines, this returns the length of the longest line. + */ + public float textWidth(String str) { + if (textFont == null) { + throw new RuntimeException("use textFont() before textWidth()"); + } + + int length = str.length(); + if (length > textWidthBuffer.length) { + textWidthBuffer = new char[length + 10]; + } + str.getChars(0, length, textWidthBuffer, 0); + + float wide = 0; + int index = 0; + int start = 0; + + while (index < length) { + if (textWidthBuffer[index] == '\n') { + wide = Math.max(wide, textWidthImpl(textWidthBuffer, start, index)); + start = index+1; + } + index++; + } + if (start < length) { + wide = Math.max(wide, textWidthImpl(textWidthBuffer, start, index)); + } + return wide; + } + + + /** + * Implementation of returning the text width of + * the chars [start, stop) in the buffer. + * Unlike the previous version that was inside PFont, this will + * return the size not of a 1 pixel font, but the actual current size. + */ + protected float textWidthImpl(char buffer[], int start, int stop) { + float wide = 0; + for (int i = start; i < stop; i++) { + // could add kerning here, but it just ain't implemented + wide += textFont.width(buffer[i]) * textSize; + } + return wide; + } + + + // ........................................................ + + + /** + * Write text where we just left off. + */ + public void text(char c) { + text(c, textX, textY, textZ); + } + + + /** + * Draw a single character on screen. + * Extremely slow when used with textMode(SCREEN) and Java 2D, + * because loadPixels has to be called first and updatePixels last. + */ + public void text(char c, float x, float y) { + if (textFont == null) { + throw new RuntimeException("use textFont() before text()"); + } + + if (textMode == SCREEN) loadPixels(); + + textBuffer[0] = c; + textLineImpl(textBuffer, 0, 1, x, y); + + if (textMode == SCREEN) updatePixels(); + } + + + /** + * Draw a single character on screen (with a z coordinate) + */ + public void text(char c, float x, float y, float z) { + if ((z != 0) && (textMode == SCREEN)) { + String msg = "textMode(SCREEN) cannot have a z coordinate"; + throw new RuntimeException(msg); + } + + if (z != 0) translate(0, 0, z); // slowness, badness + + text(c, x, y); + textZ = z; + + if (z != 0) translate(0, 0, -z); + } + + + /** + * Write text where we just left off. + */ + public void text(String str) { + text(str, textX, textY, textZ); + } + + + /** + * Draw a chunk of text. + * Newlines that are \n (Unix newline or linefeed char, ascii 10) + * are honored, but \r (carriage return, Windows and Mac OS) are + * ignored. + */ + public void text(String str, float x, float y) { + if (textFont == null) { + throw new RuntimeException("use textFont() before text()"); + } + + if (textMode == SCREEN) loadPixels(); + + int length = str.length(); + if (length > textBuffer.length) { + textBuffer = new char[length + 10]; + } + str.getChars(0, length, textBuffer, 0); + + // If multiple lines, sum the height of the additional lines + float high = 0; //-textAscent(); + for (int i = 0; i < length; i++) { + if (textBuffer[i] == '\n') { + high += textLeading; + } + } + if (textAlignY == CENTER) { + // for a single line, this adds half the textAscent to y + // for multiple lines, subtract half the additional height + //y += (textAscent() - textDescent() - high)/2; + y += (textAscent() - high)/2; + } else if (textAlignY == TOP) { + // for a single line, need to add textAscent to y + // for multiple lines, no different + y += textAscent(); + } else if (textAlignY == BOTTOM) { + // for a single line, this is just baseline (unchanged) + // for multiple lines, subtract leading for each line + y -= high; + //} else if (textAlignY == BASELINE) { + // do nothing + } + + int start = 0; + int index = 0; + while (index < length) { + if (textBuffer[index] == '\n') { + textLineImpl(textBuffer, start, index, x, y); + start = index + 1; + y += textLeading; + } + index++; + } + if (start < length) { + textLineImpl(textBuffer, start, index, x, y); + } + if (textMode == SCREEN) updatePixels(); + } + + + /** + * Same as above but with a z coordinate. + */ + public void text(String str, float x, float y, float z) { + if ((z != 0) && (textMode == SCREEN)) { + String msg = "textMode(SCREEN) cannot have a z coordinate"; + throw new RuntimeException(msg); + } + + if (z != 0) translate(0, 0, z); // slow! + + text(str, x, y); + textZ = z; + + if (z != 0) translate(0, 0, -z); + } + + + /** + * Handles placement of a text line, then calls textLinePlaced + * to actually render at the specific point. + */ + protected void textLineImpl(char buffer[], int start, int stop, + float x, float y) { + if (textAlign == CENTER) { + x -= textWidthImpl(buffer, start, stop) / 2f; + + } else if (textAlign == RIGHT) { + x -= textWidthImpl(buffer, start, stop); + } + + textLinePlacedImpl(buffer, start, stop, x, y); + } + + + protected void textLinePlacedImpl(char buffer[], int start, int stop, + float x, float y) { + for (int index = start; index < stop; index++) { + textCharImpl(buffer[index], x, y); //, 0); //z); + + // this doesn't account for kerning + x += textWidth(buffer[index]); + } + textX = x; + textY = y; + textZ = 0; // this will get set by the caller if non-zero + } + + + /** + * Draw text in a box that is constrained to a particular size. + * The current rectMode() determines what the coordinates mean + * (whether x1/y1/x2/y2 or x/y/w/h). + *

    + * Note that the x,y coords of the start of the box + * will align with the *ascent* of the text, not the baseline, + * as is the case for the other text() functions. + *

    + * Newlines that are \n (Unix newline or linefeed char, ascii 10) + * are honored, and \r (carriage return, Windows and Mac OS) are + * ignored. + */ + public void text(String str, float x1, float y1, float x2, float y2) { + if (textFont == null) { + throw new RuntimeException("use textFont() before text()"); + } + + if (textMode == SCREEN) loadPixels(); + + float hradius, vradius; + switch (rectMode) { + case CORNER: + x2 += x1; y2 += y1; + break; + case RADIUS: + hradius = x2; + vradius = y2; + x2 = x1 + hradius; + y2 = y1 + vradius; + x1 -= hradius; + y1 -= vradius; + break; + case CENTER: + hradius = x2 / 2.0f; + vradius = y2 / 2.0f; + x2 = x1 + hradius; + y2 = y1 + vradius; + x1 -= hradius; + y1 -= vradius; + } + if (x2 < x1) { + float temp = x1; x1 = x2; x2 = temp; + } + if (y2 < y1) { + float temp = y1; y1 = y2; y2 = temp; + } + + float spaceWidth = textWidth(' '); + float runningX = x1; //boxX1; + float currentY = y1; //boxY1; + float boxWidth = x2 - x1; //boxX2 - boxX1; + + // lineX is the position where the text starts, which is adjusted + // to left/center/right based on the current textAlign + float lineX = x1; //boxX1; + if (textAlign == CENTER) { + lineX = lineX + boxWidth/2f; + } else if (textAlign == RIGHT) { + lineX = x2; //boxX2; + } + + // ala illustrator, the text itself must fit inside the box + currentY += textAscent(); //ascent() * textSize; + // if the box is already too small, tell em to f off + if (currentY > y2) return; //boxY2) return; + + int length = str.length(); + if (length > textBuffer.length) { + textBuffer = new char[length + 10]; + } + str.getChars(0, length, textBuffer, 0); + + int wordStart = 0; + int wordStop = 0; + int lineStart = 0; + int index = 0; + while (index < length) { + if ((textBuffer[index] == ' ') || (index == length-1)) { + // boundary of a word + float wordWidth = textWidthImpl(textBuffer, wordStart, index); + + if (runningX + wordWidth > x2) { //boxX2) { + if (runningX == x1) { //boxX1) { + // if this is the first word, and its width is + // greater than the width of the text box, + // then break the word where at the max width, + // and send the rest of the word to the next line. + do { + index--; + if (index == wordStart) { + // not a single char will fit on this line. screw 'em. + //System.out.println("screw you"); + return; + } + wordWidth = textWidthImpl(textBuffer, wordStart, index); + } while (wordWidth > boxWidth); + textLineImpl(textBuffer, lineStart, index, lineX, currentY); + + } else { + // next word is too big, output current line + // and advance to the next line + textLineImpl(textBuffer, lineStart, wordStop, lineX, currentY); + // only increment index if a word wasn't broken inside the + // do/while loop above.. also, this is a while() loop too, + // because multiple spaces don't count for shit when they're + // at the end of a line like this. + + index = wordStop; // back that ass up + while ((index < length) && + (textBuffer[index] == ' ')) { + index++; + } + } + lineStart = index; + wordStart = index; + wordStop = index; + runningX = x1; //boxX1; + currentY += textLeading; + //if (currentY > boxY2) return; // box is now full + if (currentY > y2) return; // box is now full + + } else { + runningX += wordWidth + spaceWidth; + // on to the next word + wordStop = index; + wordStart = index + 1; + } + + } else if (textBuffer[index] == '\n') { + if (lineStart != index) { // if line is not empty + textLineImpl(textBuffer, lineStart, index, lineX, currentY); + } + lineStart = index + 1; + wordStart = lineStart; + runningX = x1; // fix for bug 188 + currentY += textLeading; + //if (currentY > boxY2) return; // box is now full + if (currentY > y2) return; // box is now full + } + index++; + } + if ((lineStart < length) && (lineStart != index)) { + textLineImpl(textBuffer, lineStart, index, lineX, currentY); + } + + if (textMode == SCREEN) updatePixels(); + } + + + public void text(String s, float x1, float y1, float x2, float y2, float z) { + if ((z != 0) && (textMode == SCREEN)) { + String msg = "textMode(SCREEN) cannot have a z coordinate"; + throw new RuntimeException(msg); + } + + if (z != 0) translate(0, 0, z); // slowness, badness + + text(s, x1, y1, x2, y2); + textZ = z; + + if (z != 0) translate(0, 0, -z); // TEMPORARY HACK! SLOW! + } + + + public void text(int num, float x, float y) { + text(String.valueOf(num), x, y); + } + + + public void text(int num, float x, float y, float z) { + text(String.valueOf(num), x, y, z); + } + + + /** + * This does a basic number formatting, to avoid the + * generally ugly appearance of printing floats. + * Users who want more control should use their own nf() cmmand, + * or if they want the long, ugly version of float, + * use String.valueOf() to convert the float to a String first. + */ + public void text(float num, float x, float y) { + text(PApplet.nfs(num, 0, 3), x, y); + } + + + public void text(float num, float x, float y, float z) { + text(PApplet.nfs(num, 0, 3), x, y, z); + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + // what was this for? + //font.getStringBounds(text, g2.getFontRenderContext()).getWidth(); + + + protected void textCharImpl(char ch, float x, float y) { //, float z) { + int index = textFont.index(ch); + if (index == -1) return; + + PImage glyph = textFont.images[index]; + + if (textMode == MODEL) { + float high = (float) textFont.height[index] / textFont.fheight; + float bwidth = (float) textFont.width[index] / textFont.fwidth; + float lextent = (float) textFont.leftExtent[index] / textFont.fwidth; + float textent = (float) textFont.topExtent[index] / textFont.fheight; + + float x1 = x + lextent * textSize; + float y1 = y - textent * textSize; + float x2 = x1 + bwidth * textSize; + float y2 = y1 + high * textSize; + + textCharModelImpl(glyph, + x1, y1, x2, y2, + //x1, y1, z, x2, y2, z, + textFont.width[index], textFont.height[index]); + + } else if (textMode == SCREEN) { + int xx = (int) x + textFont.leftExtent[index];; + int yy = (int) y - textFont.topExtent[index]; + + int w0 = textFont.width[index]; + int h0 = textFont.height[index]; + + textCharScreenImpl(glyph, xx, yy, w0, h0); + } + } + + + protected void textCharModelImpl(PImage glyph, + float x1, float y1, //float z1, + float x2, float y2, //float z2, + int u2, int v2) { + boolean savedTint = tint; + int savedTintColor = tintColor; + float savedTintR = tintR; + float savedTintG = tintG; + float savedTintB = tintB; + float savedTintA = tintA; + boolean savedTintAlpha = tintAlpha; + + tint = true; + tintColor = fillColor; + tintR = fillR; + tintG = fillG; + tintB = fillB; + tintA = fillA; + tintAlpha = fillAlpha; + + imageImpl(glyph, x1, y1, x2, y2, 0, 0, u2, v2); + + tint = savedTint; + tintColor = savedTintColor; + tintR = savedTintR; + tintG = savedTintG; + tintB = savedTintB; + tintA = savedTintA; + tintAlpha = savedTintAlpha; + } + + + // should take image, int x1, int y1, and x2, y2 + + protected void textCharScreenImpl(PImage glyph, + int xx, int yy, //int x2, int y2, + int w0, int h0) { + /* + System.out.println("textimplscreen"); + rectMode(CORNER); + stroke(255); + rect(xx, yy, w0, h0); + */ + + int x0 = 0; + int y0 = 0; + + if ((xx >= width) || (yy >= height) || + (xx + w0 < 0) || (yy + h0 < 0)) return; + + if (xx < 0) { + x0 -= xx; + w0 += xx; + xx = 0; + } + if (yy < 0) { + y0 -= yy; + h0 += yy; + yy = 0; + } + if (xx + w0 > width) { + w0 -= ((xx + w0) - width); + } + if (yy + h0 > height) { + h0 -= ((yy + h0) - height); + } + + int fr = fillRi; + int fg = fillGi; + int fb = fillBi; + int fa = fillAi; + + int pixels1[] = glyph.pixels; //images[glyph].pixels; + + // TODO this can be optimized a bit + for (int row = y0; row < y0 + h0; row++) { + for (int col = x0; col < x0 + w0; col++) { + int a1 = (fa * pixels1[row * textFont.twidth + col]) >> 8; + int a2 = a1 ^ 0xff; + //int p1 = pixels1[row * glyph.width + col]; + int p2 = pixels[(yy + row-y0)*width + (xx+col-x0)]; + + pixels[(yy + row-y0)*width + xx+col-x0] = + (0xff000000 | + (((a1 * fr + a2 * ((p2 >> 16) & 0xff)) & 0xff00) << 8) | + (( a1 * fg + a2 * ((p2 >> 8) & 0xff)) & 0xff00) | + (( a1 * fb + a2 * ( p2 & 0xff)) >> 8)); + } + } + } + + + + ////////////////////////////////////////////////////////////// + + // MATRIX TRANSFORMATIONS + + + public void translate(float tx, float ty) { + m02 += tx*m00 + ty*m01 + m02; + m12 += tx*m10 + ty*m11 + m12; + } + + + public void translate(float tx, float ty, float tz) { + depthErrorXYZ("translate"); + } + + + /** + * Two dimensional rotation. + *

    + * Additional background. + *

    + * Same as rotateZ (this is identical to a 3D rotation along the z-axis) + * but included for clarity. It'd be weird for people drawing 2D graphics + * to be using rotateZ. And they might kick our a-- for the confusion. + */ + public void rotate(float angle) { + float c = (float) Math.cos(angle); + float s = (float) Math.sin(angle); + + applyMatrix(c, -s, 0, s, c, 0); + } + + + public void rotateX(float angle) { + depthError("rotateX"); + } + + public void rotateY(float angle) { + depthError("rotateY"); + } + + + /** + * Rotate around the z axis. The functions rotate() and rotateZ() are + * the same, it's just that it make sense to have rotate() and then rotateX() + * and rotateY() when running in 3D; nor does it make sense to use + * a function called rotateZ() if you're only doing things in 2D. + * so we just decided to have them both be the same. + */ + public void rotateZ(float angle) { + depthError("rotateZ"); + } + + + /** + * Rotate about a vector in space. Same as the glRotatef() function. + */ + public void rotate(float angle, float vx, float vy, float vz) { + throw new RuntimeException("rotate(angle, x, y, z) " + + "can only be used with P3D or OPENGL"); + } + + + public void scale(float s) { + applyMatrix(s, 0, 0, + 0, s, 0); + } + + + public void scale(float sx, float sy) { + applyMatrix(sx, 0, 0, + 0, sy, 0); + } + + + public void scale(float x, float y, float z) { + depthErrorXYZ("scale"); + } + + + + ////////////////////////////////////////////////////////////// + + // TRANSFORMATION MATRIX + + + public void pushMatrix() { + if (matrixStackDepth+1 == MATRIX_STACK_DEPTH) { + throw new RuntimeException("too many calls to pushMatrix()"); + } + float mat[] = matrixStack[matrixStackDepth]; + mat[0] = m00; mat[1] = m01; mat[2] = m02; + mat[3] = m10; mat[4] = m11; mat[5] = m12; + matrixStackDepth++; + } + + + public void popMatrix() { + if (matrixStackDepth == 0) { + throw new RuntimeException("too many calls to popMatrix() " + + "(and not enough to pushMatrix)"); + } + matrixStackDepth--; + float mat[] = matrixStack[matrixStackDepth]; + m00 = mat[0]; m01 = mat[1]; m02 = mat[2]; + m10 = mat[3]; m11 = mat[4]; m12 = mat[5]; + } + + + /** + * Load identity as the transform/model matrix. + * Same as glLoadIdentity(). + */ + public void resetMatrix() { + m00 = 1; m01 = 0; m02 = 0; + m10 = 0; m11 = 1; m12 = 0; + } + + + /** + * Apply a 3x2 affine transformation matrix. + */ + public void applyMatrix(float n00, float n01, float n02, + float n10, float n11, float n12) { + + float r00 = m00*n00 + m01*n10; + float r01 = m00*n01 + m01*n11; + float r02 = m00*n02 + m01*n12 + m02; + + float r10 = m10*n00 + m11*n10; + float r11 = m10*n01 + m11*n11; + float r12 = m10*n02 + m11*n12 + m12; + + m00 = r00; m01 = r01; m02 = r02; + m10 = r10; m11 = r11; m12 = r12; + } + + + public void applyMatrix(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + throw new RuntimeException("applyMatrix() with a 4x4 matrix " + + "can only be used with OPENGL or P3D"); + } + + + /** + * Loads the current matrix into m00, m01 etc (or modelview and + * projection when using 3D) so that the values can be read. + *

    + * Note that there is no "updateMatrix" because that gets too + * complicated (unnecessary) when considering the 3D matrices. + */ + public void loadMatrix() { + // no-op on base PGraphics because they're used directly + } + + + /** + * Print the current model (or "transformation") matrix. + */ + public void printMatrix() { + loadMatrix(); // just to make sure + + float big = Math.abs(m00); + if (Math.abs(m01) > big) big = Math.abs(m01); + if (Math.abs(m02) > big) big = Math.abs(m02); + if (Math.abs(m10) > big) big = Math.abs(m10); + if (Math.abs(m11) > big) big = Math.abs(m11); + if (Math.abs(m12) > big) big = Math.abs(m12); + + // avoid infinite loop + if (Float.isNaN(big) || Float.isInfinite(big)) { + big = 1000000; // set to something arbitrary + } + + int d = 1; + int bigi = (int) big; + while ((bigi /= 10) != 0) d++; // cheap log() + + System.out.println(PApplet.nfs(m00, d, 4) + " " + + PApplet.nfs(m01, d, 4) + " " + + PApplet.nfs(m02, d, 4)); + + System.out.println(PApplet.nfs(m10, d, 4) + " " + + PApplet.nfs(m11, d, 4) + " " + + PApplet.nfs(m12, d, 4)); + + System.out.println(); + } + + + + ////////////////////////////////////////////////////////////// + + // CAMERA (none are supported in 2D) + + + public void beginCamera() { + depthError("beginCamera"); + } + + public void endCamera() { + depthError("endCamera"); + } + + public void camera() { + depthError("camera"); + } + + public void camera(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) { + depthError("camera"); + } + + public void printCamera() { + depthError("printCamera"); + } + + + + ////////////////////////////////////////////////////////////// + + // PROJECTION (none are supported in 2D) + + + public void ortho() { + depthError("ortho"); + } + + public void ortho(float left, float right, + float bottom, float top, + float near, float far) { + depthError("ortho"); + } + + public void perspective() { + depthError("perspective"); + } + + public void perspective(float fovy, float aspect, float zNear, float zFar) { + depthError("perspective"); + } + + public void frustum(float left, float right, float bottom, + float top, float znear, float zfar) { + depthError("frustum"); + } + + public void printProjection() { + depthError("printCamera"); + } + + + + ////////////////////////////////////////////////////////////// + + // SCREEN TRANSFORMS + + + /** + * Given an x and y coordinate, returns the x position of where + * that point would be placed on screen, once affected by translate(), + * scale(), or any other transformations. + */ + public float screenX(float x, float y) { + return m00*x + m01*y + m02; + } + + + /** + * Given an x and y coordinate, returns the y position of where + * that point would be placed on screen, once affected by translate(), + * scale(), or any other transformations. + */ + public float screenY(float x, float y) { + return m10*x + m11*y + m12; + } + + + /** + * Maps a three dimensional point to its placement on-screen. + *

    + * Given an (x, y, z) coordinate, returns the x position of where + * that point would be placed on screen, once affected by translate(), + * scale(), or any other transformations. + */ + public float screenX(float x, float y, float z) { + depthErrorXYZ("screenX"); + return 0; + } + + + /** + * Maps a three dimensional point to its placement on-screen. + *

    + * Given an (x, y, z) coordinate, returns the y position of where + * that point would be placed on screen, once affected by translate(), + * scale(), or any other transformations. + */ + public float screenY(float x, float y, float z) { + depthErrorXYZ("screenY"); + return 0; + } + + + /** + * Maps a three dimensional point to its placement on-screen. + *

    + * Given an (x, y, z) coordinate, returns its z value. + * This value can be used to determine if an (x, y, z) coordinate + * is in front or in back of another (x, y, z) coordinate. + * The units are based on how the zbuffer is set up, and don't + * relate to anything "real". They're only useful for in + * comparison to another value obtained from screenZ(), + * or directly out of the zbuffer[]. + */ + public float screenZ(float x, float y, float z) { + depthErrorXYZ("screenZ"); + return 0; + } + + + /** + * Returns the model space x value for an x, y, z coordinate. + *

    + * This will give you a coordinate after it has been transformed + * by translate(), rotate(), and camera(), but not yet transformed + * by the projection matrix. For instance, his can be useful for + * figuring out how points in 3D space relate to the edge + * coordinates of a shape. + */ + public float modelX(float x, float y, float z) { + depthError("modelX"); + return 0; + } + + + /** + * Returns the model space y value for an x, y, z coordinate. + */ + public float modelY(float x, float y, float z) { + depthError("modelY"); + return 0; + } + + + /** + * Returns the model space z value for an x, y, z coordinate. + */ + public float modelZ(float x, float y, float z) { + depthError("modelZ"); + return 0; + } + + + + ////////////////////////////////////////////////////////////// + + // COLOR + + + public void colorMode(int mode) { + colorMode(mode, colorModeX, colorModeY, colorModeZ, colorModeA); + } + + + public void colorMode(int mode, float max) { + colorMode(mode, max, max, max, max); + } + + + /** + * Set the colorMode and the maximum values for (r, g, b) + * or (h, s, b). + *

    + * Note that this doesn't set the maximum for the alpha value, + * which might be confusing if for instance you switched to + *

    colorMode(HSB, 360, 100, 100);
    + * because the alpha values were still between 0 and 255. + */ + public void colorMode(int mode, + float maxX, float maxY, float maxZ) { + colorMode(mode, maxX, maxY, maxZ, colorModeA); + } + + + public void colorMode(int mode, + float maxX, float maxY, float maxZ, float maxA) { + colorMode = mode; + + colorModeX = maxX; // still needs to be set for hsb + colorModeY = maxY; + colorModeZ = maxZ; + colorModeA = maxA; + + // if color max values are all 1, then no need to scale + colorScale = ((maxA != 1) || (maxX != maxY) || + (maxY != maxZ) || (maxZ != maxA)); + + // if color is rgb/0..255 this will make it easier for the + // red() green() etc functions + colorRgb255 = (colorMode == RGB) && + (colorModeA == 255) && (colorModeX == 255) && + (colorModeY == 255) && (colorModeZ == 255); + } + + + ////////////////////////////////////////////////////////////// + + + protected void colorCalc(float gray) { + colorCalc(gray, colorModeA); + } + + + protected void colorCalc(float gray, float alpha) { + if (gray > colorModeX) gray = colorModeX; + if (alpha > colorModeA) alpha = colorModeA; + + if (gray < 0) gray = 0; + if (alpha < 0) alpha = 0; + + calcR = colorScale ? (gray / colorModeX) : gray; + calcG = calcR; + calcB = calcR; + calcA = colorScale ? (alpha / colorModeA) : alpha; + + calcRi = (int)(calcR*255); calcGi = (int)(calcG*255); + calcBi = (int)(calcB*255); calcAi = (int)(calcA*255); + calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi; + calcAlpha = (calcAi != 255); + } + + + protected void colorCalc(float x, float y, float z) { + colorCalc(x, y, z, colorModeA); + } + + + protected void colorCalc(float x, float y, float z, float a) { + if (x > colorModeX) x = colorModeX; + if (y > colorModeY) y = colorModeY; + if (z > colorModeZ) z = colorModeZ; + if (a > colorModeA) a = colorModeA; + + if (x < 0) x = 0; + if (y < 0) y = 0; + if (z < 0) z = 0; + if (a < 0) a = 0; + + switch (colorMode) { + case RGB: + if (colorScale) { + calcR = x / colorModeX; + calcG = y / colorModeY; + calcB = z / colorModeZ; + calcA = a / colorModeA; + } else { + calcR = x; calcG = y; calcB = z; calcA = a; + } + break; + + case HSB: + x /= colorModeX; // h + y /= colorModeY; // s + z /= colorModeZ; // b + + calcA = colorScale ? (a/colorModeA) : a; + + if (y == 0) { // saturation == 0 + calcR = calcG = calcB = z; + + } else { + float which = (x - (int)x) * 6.0f; + float f = which - (int)which; + float p = z * (1.0f - y); + float q = z * (1.0f - y * f); + float t = z * (1.0f - (y * (1.0f - f))); + + switch ((int)which) { + case 0: calcR = z; calcG = t; calcB = p; break; + case 1: calcR = q; calcG = z; calcB = p; break; + case 2: calcR = p; calcG = z; calcB = t; break; + case 3: calcR = p; calcG = q; calcB = z; break; + case 4: calcR = t; calcG = p; calcB = z; break; + case 5: calcR = z; calcG = p; calcB = q; break; + } + } + break; + } + calcRi = (int)(255*calcR); calcGi = (int)(255*calcG); + calcBi = (int)(255*calcB); calcAi = (int)(255*calcA); + calcColor = (calcAi << 24) | (calcRi << 16) | (calcGi << 8) | calcBi; + calcAlpha = (calcAi != 255); + } + + + /** + * Unpacks AARRGGBB color for direct use with colorCalc. + *

    + * Handled here with its own function since this is indepenent + * of the color mode. + *

    + * Strangely the old version of this code ignored the alpha + * value. not sure if that was a bug or what. + *

    + * Note, no need for a bounds check since it's a 32 bit number. + */ + protected void colorCalcARGB(int argb, float alpha) { + if (alpha == colorModeA) { + calcAi = (argb >> 24) & 0xff; + calcColor = argb; + } else { + calcAi = (int) (((argb >> 24) & 0xff) * (alpha / colorModeA)); + calcColor = (calcAi << 24) | (argb & 0xFFFFFF); + } + calcRi = (argb >> 16) & 0xff; + calcGi = (argb >> 8) & 0xff; + calcBi = argb & 0xff; + calcA = (float)calcAi / 255.0f; + calcR = (float)calcRi / 255.0f; + calcG = (float)calcGi / 255.0f; + calcB = (float)calcBi / 255.0f; + calcAlpha = (calcAi != 255); + + } + + + ////////////////////////////////////////////////////////////// + + + public void strokeWeight(float weight) { + strokeWeight = weight; + } + + + public void strokeJoin(int join) { + strokeJoin = join; + } + + + public void strokeCap(int cap) { + strokeCap = cap; + } + + + public void noStroke() { + stroke = false; + } + + + /** + * Set the tint to either a grayscale or ARGB value. + * See notes attached to the fill() function. + */ + public void stroke(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + stroke((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + strokeFromCalc(); + } + } + + + public void stroke(int rgb, float alpha) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { + stroke((float) rgb, alpha); + + } else { + colorCalcARGB(rgb, alpha); + strokeFromCalc(); + } + } + + + public void stroke(float gray) { + colorCalc(gray); + strokeFromCalc(); + } + + + public void stroke(float gray, float alpha) { + colorCalc(gray, alpha); + strokeFromCalc(); + } + + + public void stroke(float x, float y, float z) { + colorCalc(x, y, z); + strokeFromCalc(); + } + + + public void stroke(float x, float y, float z, float a) { + colorCalc(x, y, z, a); + strokeFromCalc(); + } + + + protected void strokeFromCalc() { + stroke = true; + //strokeChanged = true; + strokeR = calcR; + strokeG = calcG; + strokeB = calcB; + strokeA = calcA; + strokeRi = calcRi; + strokeGi = calcGi; + strokeBi = calcBi; + strokeAi = calcAi; + strokeColor = calcColor; + strokeAlpha = calcAlpha; + } + + + ////////////////////////////////////////////////////////////// + + + public void noTint() { + tint = false; + } + + + /** + * Set the tint to either a grayscale or ARGB value. See notes + * attached to the fill() function. + */ + public void tint(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { + tint((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + tintFromCalc(); + } + } + + public void tint(int rgb, float alpha) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { + tint((float) rgb, alpha); + + } else { + colorCalcARGB(rgb, alpha); + tintFromCalc(); + } + } + + public void tint(float gray) { + colorCalc(gray); + tintFromCalc(); + } + + + public void tint(float gray, float alpha) { + colorCalc(gray, alpha); + tintFromCalc(); + } + + + public void tint(float x, float y, float z) { + colorCalc(x, y, z); + tintFromCalc(); + } + + + public void tint(float x, float y, float z, float a) { + colorCalc(x, y, z, a); + tintFromCalc(); + } + + + protected void tintFromCalc() { + tint = true; + tintR = calcR; + tintG = calcG; + tintB = calcB; + tintA = calcA; + tintRi = calcRi; + tintGi = calcGi; + tintBi = calcBi; + tintAi = calcAi; + tintColor = calcColor; + tintAlpha = calcAlpha; + } + + + ////////////////////////////////////////////////////////////// + + + public void noFill() { + fill = false; + } + + + /** + * Set the fill to either a grayscale value or an ARGB int. + *

    + * The problem with this code is that it has to detect between + * these two situations automatically. This is done by checking + * to see if the high bits (the alpha for 0xAA000000) is set, + * and if not, whether the color value that follows is less than + * colorModeX (the first param passed to colorMode). + *

    + * This auto-detect would break in the following situation: + *

    size(256, 256);
    +   * for (int i = 0; i < 256; i++) {
    +   *   color c = color(0, 0, 0, i);
    +   *   stroke(c);
    +   *   line(i, 0, i, 256);
    +   * }
    + * ...on the first time through the loop, where (i == 0), + * since the color itself is zero (black) then it would appear + * indistinguishable from someone having written fill(0). + */ + public void fill(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + fill((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + fillFromCalc(); + } + } + + + public void fill(int rgb, float alpha) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + fill((float) rgb, alpha); + + } else { + colorCalcARGB(rgb, alpha); + fillFromCalc(); + } + } + + + public void fill(float gray) { + colorCalc(gray); + fillFromCalc(); + } + + + public void fill(float gray, float alpha) { + colorCalc(gray, alpha); + fillFromCalc(); + } + + + public void fill(float x, float y, float z) { + colorCalc(x, y, z); + fillFromCalc(); + } + + + public void fill(float x, float y, float z, float a) { + colorCalc(x, y, z, a); + fillFromCalc(); + } + + + protected void fillFromCalc() { + fill = true; + fillR = calcR; + fillG = calcG; + fillB = calcB; + fillA = calcA; + fillRi = calcRi; + fillGi = calcGi; + fillBi = calcBi; + fillAi = calcAi; + fillColor = calcColor; + fillAlpha = calcAlpha; + } + + + ////////////////////////////////////////////////////////////// + + + public void ambient(int rgb) { + depthError("ambient"); + } + + public void ambient(float gray) { + depthError("ambient"); + } + + public void ambient(float x, float y, float z) { + depthError("ambient"); + } + + + ////////////////////////////////////////////////////////////// + + + public void specular(int rgb) { + depthError("specular"); + } + + public void specular(float gray) { + depthError("specular"); + } + + public void specular(float gray, float alpha) { + depthError("specular"); + } + + public void specular(float x, float y, float z) { + depthError("specular"); + } + + public void specular(float x, float y, float z, float a) { + depthError("specular"); + } + + public void shininess(float shine) { + depthError("shininess"); + } + + + ////////////////////////////////////////////////////////////// + + + public void emissive(int rgb) { + depthError("emissive"); + } + + public void emissive(float gray) { + depthError("emissive"); + } + + public void emissive(float x, float y, float z ) { + depthError("emissive"); + } + + + + ////////////////////////////////////////////////////////////// + + // LIGHTS + + + public void lights() { + depthError("lights"); + } + + public void ambientLight(float red, float green, float blue) { + depthError("ambientLight"); + } + + public void ambientLight(float red, float green, float blue, + float x, float y, float z) { + depthError("ambientLight"); + } + + public void directionalLight(float red, float green, float blue, + float nx, float ny, float nz) { + depthError("directionalLight"); + } + + public void pointLight(float red, float green, float blue, + float x, float y, float z) { + depthError("pointLight"); + } + + public void spotLight(float red, float green, float blue, + float x, float y, float z, + float nx, float ny, float nz, + float angle, float concentration) { + depthError("spotLight"); + } + + public void lightFalloff(float constant, float linear, float quadratic) { + depthError("lightFalloff"); + } + + public void lightSpecular(float x, float y, float z) { + depthError("lightSpecular"); + } + + + + ////////////////////////////////////////////////////////////// + + + /** + * Set the background to a gray or ARGB color. + *

    + * Note that background() should be called before any + * transformations occur, because some implementations may + * require the current transformation matrix to be identity + * before drawing. + */ + public void background(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { + background((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + backgroundFromCalc(); + } + clear(); + } + + + /** + * See notes about alpha in background(x, y, z, a). + */ + public void background(int rgb, float alpha) { + if (mainDrawingSurface) { + background(rgb); // don't allow people to set alpha + + } else { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + background((float) rgb, alpha); + + } else { + colorCalcARGB(rgb, alpha); + backgroundFromCalc(); + clear(); + } + } + } + + + /** + * Set the background to a grayscale value, based on the + * current colorMode. + */ + public void background(float gray) { + colorCalc(gray); + backgroundFromCalc(); + clear(); + } + + + /** + * See notes about alpha in background(x, y, z, a). + */ + public void background(float gray, float alpha) { + if (mainDrawingSurface) { + background(gray); // don't allow people to set alpha + + } else { + colorCalc(gray, alpha); + backgroundFromCalc(); + clear(); + } + } + + + /** + * Set the background to an r, g, b or h, s, b value, + * based on the current colorMode. + */ + public void background(float x, float y, float z) { + colorCalc(x, y, z); + backgroundFromCalc(); + clear(); + } + + + /** + * Clear the background with a color that includes an alpha value. + * This should only be used with objects created by createGraphics(), + * setting the main drawing surface transparent may cause problems. + * It might be tempting to use this function to partially clear the + * screen on each frame, however that's not how this function works. + * When calling background(), the pixels will be replaced with pixels + * that have that level of transparency. To do a semi-transparent + * overlay, use fill() with alpha and draw a rectangle. + */ + public void background(float x, float y, float z, float a) { + if (mainDrawingSurface) { + background(x, y, z); // don't allow people to set alpha + + } else { + colorCalc(x, y, z, a); + backgroundFromCalc(); + clear(); + } + } + + + protected void backgroundFromCalc() { + backgroundR = calcR; + backgroundG = calcG; + backgroundB = calcB; + backgroundA = calcA; + backgroundRi = calcRi; + backgroundGi = calcGi; + backgroundBi = calcBi; + backgroundAi = calcAi; + backgroundAlpha = calcAlpha; + backgroundColor = calcColor; + } + + + /** + * Takes an RGB or ARGB image and sets it as the background. + *

    + * Note that even if the image is set as RGB, the high 8 bits of + * each pixel should be set opaque (0xFF000000), because the image data + * will be copied directly to the screen, and non-opaque background + * images may have strange behavior. Using image.filter(OPAQUE) + * will handle this easily. + *

    + * When using 3D, this will also clear out the zbuffer and + * stencil buffer if they exist. + */ + public void background(PImage image) { + if ((image.width != width) || (image.height != height)) { + throw new RuntimeException("background image must be " + + "the same size as your application"); + } + if ((image.format != RGB) && (image.format != ARGB)) { + throw new RuntimeException("background images should be RGB or ARGB"); + } + + // zero this out since it's an image + backgroundColor = 0; + + // blit image to the screen + System.arraycopy(image.pixels, 0, pixels, 0, pixels.length); + } + + + /** + * Clear the pixel buffer. + */ + abstract protected void clear(); + + + + ////////////////////////////////////////////////////////////// + + // MESSAGES / ERRORS / LOGGING + + + protected void depthError(String method) { + throw new RuntimeException(method + "() can only be used " + + "with P3D or OPENGL."); + } + + + protected void depthErrorXYZ(String method) { + throw new RuntimeException(method + "(x, y, z) can only be used with " + + "OPENGL or P3D, use " + + method + "(x, y) instead."); + } + + + protected void unavailableError(String methodStr) { + throw new RuntimeException(methodStr + + " is not available with this renderer"); + } + + + + ////////////////////////////////////////////////////////////// + + // COLOR MANIPULATION + + // these functions are really slow, but easy to use + // if folks are advanced enough to want something faster, + // they can write it themselves (not difficult) + + + public final int color(int gray) { // ignore + if (((gray & 0xff000000) == 0) && (gray <= colorModeX)) { + if (colorRgb255) { + // bounds checking to make sure the numbers aren't to high or low + if (gray > 255) gray = 255; else if (gray < 0) gray = 0; + return 0xff000000 | (gray << 16) | (gray << 8) | gray; + } else { + colorCalc(gray); + } + } else { + colorCalcARGB(gray, colorModeA); + } + return calcColor; + } + + public final int color(float gray) { // ignore + colorCalc(gray); + return calcColor; + } + + + /** + * @param gray can be packed ARGB or a gray in this case + */ + public final int color(int gray, int alpha) { // ignore + if (colorRgb255) { + // bounds checking to make sure the numbers aren't to high or low + if (gray > 255) gray = 255; else if (gray < 0) gray = 0; + if (alpha > 255) alpha = 255; else if (alpha < 0) alpha = 0; + + return ((alpha & 0xff) << 24) | (gray << 16) | (gray << 8) | gray; + } + colorCalc(gray, alpha); + return calcColor; + } + + /** + * @param rgb can be packed ARGB or a gray in this case + */ + public final int color(int rgb, float alpha) { // ignore + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { + colorCalc(rgb, alpha); + } else { + colorCalcARGB(rgb, alpha); + } + return calcColor; + } + + public final int color(float gray, float alpha) { // ignore + colorCalc(gray, alpha); + return calcColor; + } + + + public final int color(int x, int y, int z) { // ignore + if (colorRgb255) { + // bounds checking to make sure the numbers aren't to high or low + if (x > 255) x = 255; else if (x < 0) x = 0; + if (y > 255) y = 255; else if (y < 0) y = 0; + if (z > 255) z = 255; else if (z < 0) z = 0; + + return 0xff000000 | (x << 16) | (y << 8) | z; + } + colorCalc(x, y, z); + return calcColor; + } + + public final int color(float x, float y, float z) { // ignore + colorCalc(x, y, z); + return calcColor; + } + + + public final int color(int x, int y, int z, int a) { // ignore + if (colorRgb255) { + // bounds checking to make sure the numbers aren't to high or low + if (a > 255) a = 255; else if (a < 0) a = 0; + if (x > 255) x = 255; else if (x < 0) x = 0; + if (y > 255) y = 255; else if (y < 0) y = 0; + if (z > 255) z = 255; else if (z < 0) z = 0; + + return (a << 24) | (x << 16) | (y << 8) | z; + } + colorCalc(x, y, z, a); + return calcColor; + } + + public final int color(float x, float y, float z, float a) { // ignore + colorCalc(x, y, z, a); + return calcColor; + } + + + public final float alpha(int what) { + float c = (what >> 24) & 0xff; + if (colorModeA == 255) return c; + return (c / 255.0f) * colorModeA; + } + + public final float red(int what) { + float c = (what >> 16) & 0xff; + if (colorRgb255) return c; + return (c / 255.0f) * colorModeX; + } + + public final float green(int what) { + float c = (what >> 8) & 0xff; + if (colorRgb255) return c; + return (c / 255.0f) * colorModeY; + } + + public final float blue(int what) { + float c = (what) & 0xff; + if (colorRgb255) return c; + return (c / 255.0f) * colorModeZ; + } + + + public final float hue(int what) { + if (what != cacheHsbKey) { + Color.RGBtoHSB((what >> 16) & 0xff, (what >> 8) & 0xff, + what & 0xff, cacheHsbValue); + cacheHsbKey = what; + } + return cacheHsbValue[0] * colorModeX; + } + + public final float saturation(int what) { + if (what != cacheHsbKey) { + Color.RGBtoHSB((what >> 16) & 0xff, (what >> 8) & 0xff, + what & 0xff, cacheHsbValue); + cacheHsbKey = what; + } + return cacheHsbValue[1] * colorModeY; + } + + public final float brightness(int what) { + if (what != cacheHsbKey) { + Color.RGBtoHSB((what >> 16) & 0xff, (what >> 8) & 0xff, + what & 0xff, cacheHsbValue); + cacheHsbKey = what; + } + return cacheHsbValue[2] * colorModeZ; + } + + + public int lerpColor(int c1, int c2, float amt) { + return lerpColor(c1, c2, amt, colorMode); + } + + static float[] lerpColorHSB1; + static float[] lerpColorHSB2; + + static public int lerpColor(int c1, int c2, float amt, int mode) { + if (mode == RGB) { + float a1 = ((c1 >> 24) & 0xff); + float r1 = (c1 >> 16) & 0xff; + float g1 = (c1 >> 8) & 0xff; + float b1 = c1 & 0xff; + float a2 = (c2 >> 24) & 0xff; + float r2 = (c2 >> 16) & 0xff; + float g2 = (c2 >> 8) & 0xff; + float b2 = c2 & 0xff; + + return (((int) (a1 + (a2-a1)*amt) << 24) | + ((int) (r1 + (r2-r1)*amt) << 16) | + ((int) (g1 + (g2-g1)*amt) << 8) | + ((int) (b1 + (b2-b1)*amt))); + + } else if (mode == HSB) { + if (lerpColorHSB1 == null) { + lerpColorHSB1 = new float[3]; + lerpColorHSB2 = new float[3]; + } + + float a1 = (c1 >> 24) & 0xff; + float a2 = (c2 >> 24) & 0xff; + int alfa = ((int) (a1 + (a2-a1)*amt)) << 24; + + Color.RGBtoHSB((c1 >> 16) & 0xff, (c1 >> 8) & 0xff, c1 & 0xff, + lerpColorHSB1); + Color.RGBtoHSB((c2 >> 16) & 0xff, (c2 >> 8) & 0xff, c2 & 0xff, + lerpColorHSB2); + + // roll around when 0.9 to 0.1 + // more than 0.5 away means that it should roll in the other direction + float h1 = lerpColorHSB1[0]; + float h2 = lerpColorHSB2[0]; + if (Math.abs(h1 - h2) > 0.5f) { + if (h1 > h2) { + // i.e. h1 is 0.7, h2 is 0.1 + h2 += 1; + } else { + // i.e. h1 is 0.1, h2 is 0.7 + h1 += 1; + } + } + float ho = (PApplet.lerp(lerpColorHSB1[0], lerpColorHSB2[0], amt)) % 1.0f; + float so = PApplet.lerp(lerpColorHSB1[1], lerpColorHSB2[1], amt); + float bo = PApplet.lerp(lerpColorHSB1[2], lerpColorHSB2[2], amt); + + return alfa | (Color.HSBtoRGB(ho, so, bo) & 0xFFFFFF); + } + return 0; + } + + + ////////////////////////////////////////////////////////////// + + // MATH + + + static final float sqrt(float a) { + return (float)Math.sqrt(a); + } + + + + ////////////////////////////////////////////////////////////// + + // PATH + + /* + class Path { + + public void moveTo(float x, float y) { // ignore + } + + public void lineTo(float x, float y) { // ignore + } + + public void curveTo(float x1, float y1, // ignore + float x2, float y2, + float x3, float y3) { + } + + public void closePath() { // ignore + } + } + */ + + + ////////////////////////////////////////////////////////////// + + + /** + * Use with caution on PGraphics. This should not be used with + * the base PGraphics that's tied to a PApplet, but it can be used + * with user-created PGraphics objects that are drawn to the screen. + */ + public void mask(int alpha[]) { // ignore + super.mask(alpha); + } + + + /** + * Use with caution on PGraphics. This should not be used with + * the base PGraphics that's tied to a PApplet, but it can be used + * with user-created PGraphics objects that are drawn to the screen. + */ + public void mask(PImage alpha) { // ignore + super.mask(alpha); + } + + + ////////////////////////////////////////////////////////////// + + + public void beginRaw(PGraphics rawGraphics) { + this.raw = rawGraphics; + rawGraphics.beginDraw(); + } + + + public void endRaw() { + if (raw != null) { + // for 3D, need to flush any geometry that's been stored for sorting + raw.flush(); // this should be called by endDraw() instead + + // just like beginDraw, this will have to be called because + // endDraw() will be happening outside of draw() + raw.endDraw(); + raw.dispose(); + raw = null; + } + } + + + /** + * Handle any takedown for this graphics context. + *

    + * This is called when a sketch is shut down and this renderer was + * specified using the size() command, or inside endRecord() and + * endRaw(), in order to shut things off. + */ + public void dispose() { // ignore + } + + + /** + * Return true if this renderer should be drawn to the screen. + * Overridden for subclasses like PDF so that an enormous window + * doesn't open up. + * showFrame, displayable, isVisible, visible, shouldDisplay, + * what to call this? + */ + public boolean displayable() { + return true; + } +} diff --git a/core/PGraphics2D.java b/core/PGraphics2D.java new file mode 100644 index 000000000..3899b52e9 --- /dev/null +++ b/core/PGraphics2D.java @@ -0,0 +1,1672 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2006 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.Toolkit; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; + + +/** + * Subclass of PGraphics that handles fast 2D rendering, + * more commonly referred to as P2D. This class uses no Java2D + * and will run with Java 1.1. + */ +public class PGraphics2D extends PGraphics { + + PPolygon polygon; // general polygon to use for shape + PPolygon fpolygon; // used to fill polys for tri or quad strips + PPolygon spolygon; // stroke/line polygon + float svertices[][]; // temp vertices used for stroking end of poly + + // polygon that handles tesselation + private PPolygon tpolygon; + private int TPOLYGON_MAX_VERTICES = 512; + private int tpolygon_vertex_order[]; // = new int[MAX_VERTICES]; + + PLine line; + + //boolean untransformed; + boolean strokeChanged = true; + boolean fillChanged = true; + + static final int CVERTEX_ALLOC = 128; + float cvertex[][] = new float[CVERTEX_ALLOC][VERTEX_FIELD_COUNT]; + int cvertexIndex; + + + ////////////////////////////////////////////////////////////// + + + //protected PGraphics2D() { } + + + /* + public PGraphics2D(int iwidth, int iheight) { + this(iwidth, iheight, null); + } + */ + + + public PGraphics2D(int iwidth, int iheight, PApplet applet) { + super(iwidth, iheight, applet); + /* + if (applet != null) { + this.parent = applet; + applet.addListeners(); + } + resize(iwidth, iheight); + */ + } + + + //resize handled by superclass + + + //requestDisplay handled by superclass + + + protected void allocate() { + pixelCount = width * height; + pixels = new int[pixelCount]; + + // because of a java 1.1 bug, pixels must be registered as + // opaque before their first run, the memimgsrc will flicker + // and run very slowly. + backgroundColor |= 0xff000000; // just for good measure + for (int i = 0; i < pixelCount; i++) pixels[i] = backgroundColor; + //for (int i = 0; i < pixelCount; i++) pixels[i] = 0xffffffff; + + //if (parent != null) { + if (mainDrawingSurface) { + cm = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff);; + mis = new MemoryImageSource(width, height, pixels, 0, width); + mis.setFullBufferUpdates(true); + mis.setAnimated(true); + image = Toolkit.getDefaultToolkit().createImage(mis); + } + + // can't un-set this because this may be only a resize (Bug #463) + //defaultsInited = false; + } + + + ////////////////////////////////////////////////////////////// + + + public void beginDraw() { + insideResizeWait(); + insideDraw = true; + + // need to call defaults(), but can only be done when it's ok + // to draw (i.e. for opengl, no drawing can be done outside + // beginDraw/endDraw). + if (!defaultsInited) { + defaults(); + + polygon = new PPolygon(this); + fpolygon = new PPolygon(this); + spolygon = new PPolygon(this); + spolygon.vertexCount = 4; + svertices = new float[2][]; + } + + resetMatrix(); // reset model matrix + + // reset vertices + vertexCount = 0; + } + + + public void endDraw() { + // moving this back here (post-68) because of macosx thread problem + if (mis != null) { + mis.newPixels(pixels, cm, 0, width); + } + // mark pixels as having been updated, so that they'll work properly + // when this PGraphics is drawn using image(). + updatePixels(); + + insideDraw = false; + } + + + ////////////////////////////////////////////////////////////// + + + public void beginShape(int kind) { + shape = kind; + vertexCount = 0; + splineVertexCount = 0; + + polygon.reset(0); + fpolygon.reset(4); + spolygon.reset(4); + + polygon.interpUV = false; + } + + + // PGraphics will throw a depthError + //public void normal(float nx, float ny, float nz) + + // PGraphics will handle setting these + //public void textureMode(int mode) + //public void texture(PImage image) + //protected void textureVertex(float u, float v) + + + public void vertex(float x, float y) { + float vertex[] = polygon.nextVertex(); + cvertexIndex = 0; // reset curves to start + + vertex[MX] = x; + vertex[MY] = y; + + if (fill) { + vertex[R] = fillR; + vertex[G] = fillG; + vertex[B] = fillB; + vertex[A] = fillA; + } + + if (stroke) { + vertex[SR] = strokeR; + vertex[SG] = strokeG; + vertex[SB] = strokeB; + vertex[SA] = strokeA; + vertex[SW] = strokeWeight; + } + + // this complicated if construct may defeat the purpose + if (textureImage != null) { + vertex[U] = textureU; + vertex[V] = textureV; + } + } + + + public void vertex(float x, float y, float u, float v) { + textureVertex(u, v); + vertex(x, y); + } + + + public void vertex(float x, float y, float z) { + depthErrorXYZ("vertex"); + } + + + public void vertex(float x, float y, float z, float u, float v) { + depthErrorXYZ("vertex"); + } + + + public void endShape(int mode) { + // clear the 'shape drawing' flag in case of early exit + //shape = 0; + // hm can't do anymore.. + + int polyVertexCount = polygon.vertexCount; + float polyVertices[][] = polygon.vertices; + + if (untransformed()) { + for (int i = 0; i < polyVertexCount; i++) { + polyVertices[i][X] = polyVertices[i][MX]; + polyVertices[i][Y] = polyVertices[i][MY]; + } + } else { + for (int i = 0; i < polyVertexCount; i++) { + polyVertices[i][X] = m00*polyVertices[i][MX] + m01*polyVertices[i][MY] + m03; + polyVertices[i][Y] = m10*polyVertices[i][MX] + m11*polyVertices[i][MY] + m13; + } + } + + // ------------------------------------------------------------------ + // TEXTURES + + if (polygon.interpUV) { + fpolygon.texture(textureImage); //polygon.timage); + } + + + // ------------------------------------------------------------------ + // COLORS + // calculate RGB for each vertex + + spolygon.interpARGB = strokeChanged; //false; + fpolygon.interpARGB = fillChanged; //false; + + // all the values for r, g, b have been set with calls to vertex() + // (no need to re-calculate anything here) + + + // ------------------------------------------------------------------ + // RENDER SHAPES + + int increment; + + switch (shape) { + case POINTS: + if (untransformed() && (strokeWeight == 1)) { + if (!strokeChanged) { + for (int i = 0; i < polyVertexCount; i++) { + thin_point((int) polyVertices[i][X], (int) polyVertices[i][Y], + 0, strokeColor); + } + } else { + for (int i = 0; i < polyVertexCount; i++) { + thin_point((int) polyVertices[i][X], (int) polyVertices[i][Y], + 0, float_color(polyVertices[i][SR], + polyVertices[i][SG], + polyVertices[i][SB])); + } + //strokei = strokeiSaved; + } + } else { + float f[] = polyVertices[0]; + + for (int i = 0; i < polyVertexCount; i++) { + float v[] = polyVertices[i]; + + // if this is the first time (i == 0) + // or if lighting is enabled + // or the stroke color has changed inside beginShape/endShape + // then re-calculate the color at this vertex + if ((i == 0) || strokeChanged) { + // push calculated color into 'f' (this way, f is always valid) + calc_lighting(v[SR], v[SG], v[SB], + v[X], v[Y], v[Z], + v[NX], v[NY], v[NZ], f, R); + } + // uses [SA], since stroke alpha isn't moved into [A] the + // way that [SR] goes to [R] etc on the calc_lighting call + // (there's no sense in copying it to [A], except consistency + // in the code.. but why the extra slowness?) + thick_point(v[X], v[Y], v[Z], f[R], f[G], f[B], f[SA]); + } + } + break; + + case LINES: + //case LINE_STRIP: + //case LINE_LOOP: + if (!stroke) return; + + // if it's a line loop, copy the vertex data to the last element + //if (shape == LINE_LOOP) { + if (mode == CLOSE) { + float v0[] = polygon.vertices[0]; + float v1[] = polygon.nextVertex(); + polyVertexCount++; // since it had already been read above + + v1[X] = v0[X]; v1[Y] = v0[Y]; v1[Z] = v0[Z]; + v1[SR] = v0[SR]; v1[SG] = v0[SG]; v1[SB] = v0[SB]; + } + + // increment by two for individual lines + increment = (shape == LINES) ? 2 : 1; + draw_lines(polyVertices, polyVertexCount-1, 1, increment, 0); + break; + + case TRIANGLES: + case TRIANGLE_STRIP: + increment = (shape == TRIANGLES) ? 3 : 1; + // do fill and stroke separately because otherwise + // the lines will be stroked more than necessary + if (fill) { + fpolygon.vertexCount = 3; + for (int i = 0; i < polyVertexCount-2; i += increment) { + for (int j = 0; j < 3; j++) { + fpolygon.vertices[j][R] = polyVertices[i+j][R]; + fpolygon.vertices[j][G] = polyVertices[i+j][G]; + fpolygon.vertices[j][B] = polyVertices[i+j][B]; + fpolygon.vertices[j][A] = polyVertices[i+j][A]; + + fpolygon.vertices[j][X] = polyVertices[i+j][X]; + fpolygon.vertices[j][Y] = polyVertices[i+j][Y]; + fpolygon.vertices[j][Z] = polyVertices[i+j][Z]; + + if (polygon.interpUV) { + fpolygon.vertices[j][U] = polyVertices[i+j][U]; + fpolygon.vertices[j][V] = polyVertices[i+j][V]; + } + } + fpolygon.render(); + } + } + if (stroke) { + // first draw all vertices as a line strip + if (shape == TRIANGLE_STRIP) { + draw_lines(polyVertices, polyVertexCount-1, 1, 1, 0); + } else { + draw_lines(polyVertices, polyVertexCount-1, 1, 1, 3); + } + // then draw from vertex (n) to (n+2) + // incrementing n using the same as above + draw_lines(polyVertices, polyVertexCount-2, 2, increment, 0); + // changed this to vertexCount-2, because it seemed + // to be adding an extra (nonexistant) line + } + break; + + case QUADS: + case QUAD_STRIP: + //System.out.println("pooping out a quad"); + increment = (shape == QUADS) ? 4 : 2; + if (fill) { + fpolygon.vertexCount = 4; + for (int i = 0; i < polyVertexCount-3; i += increment) { + for (int j = 0; j < 4; j++) { + fpolygon.vertices[j][R] = polyVertices[i+j][R]; + fpolygon.vertices[j][G] = polyVertices[i+j][G]; + fpolygon.vertices[j][B] = polyVertices[i+j][B]; + fpolygon.vertices[j][A] = polyVertices[i+j][A]; + + fpolygon.vertices[j][X] = polyVertices[i+j][X]; + fpolygon.vertices[j][Y] = polyVertices[i+j][Y]; + fpolygon.vertices[j][Z] = polyVertices[i+j][Z]; + + if (polygon.interpUV) { + fpolygon.vertices[j][U] = polyVertices[i+j][U]; + fpolygon.vertices[j][V] = polyVertices[i+j][V]; + } + } + fpolygon.render(); + } + } + if (stroke) { + // first draw all vertices as a line strip + if (shape == QUAD_STRIP) { + draw_lines(polyVertices, polyVertexCount-1, 1, 1, 0); + } else { // skip every few for quads + draw_lines(polyVertices, polyVertexCount, 1, 1, 4); + } + // then draw from vertex (n) to (n+3) + // incrementing n by the same increment as above + draw_lines(polyVertices, polyVertexCount-2, 3, increment, 0); + } + break; + + case POLYGON: + if (isConvex()) { + if (fill) { + polygon.render(); + if (stroke) polygon.unexpand(); + } + + if (stroke) { + draw_lines(polyVertices, polyVertexCount-1, 1, 1, 0); + // draw the last line connecting back to the first point in poly + svertices[0] = polyVertices[polyVertexCount-1]; + svertices[1] = polyVertices[0]; + draw_lines(svertices, 1, 1, 1, 0); + } + } else { + if (fill) { + // the triangulator produces polygons that don't align + // when smoothing is enabled. but if there is a stroke around + // the polygon, then smoothing can be temporarily disabled. + boolean smoov = smooth; + //if (stroke && !hints[DISABLE_SMOOTH_HACK]) smooth = false; + if (stroke) smooth = false; + concaveRender(); + //if (stroke && !hints[DISABLE_SMOOTH_HACK]) smooth = smoov; + if (stroke) smooth = smoov; + } + + if (stroke) { + draw_lines(polyVertices, polyVertexCount-1, 1, 1, 0); + // draw the last line connecting back + // to the first point in poly + svertices[0] = polyVertices[polyVertexCount-1]; + svertices[1] = polyVertices[0]; + draw_lines(svertices, 1, 1, 1, 0); + } + } + break; + } + + // to signify no shape being drawn + shape = 0; + } + + + + ////////////////////////////////////////////////////////////// + + // CONCAVE/CONVEX POLYGONS + + + private boolean isConvex() { + float v[][] = polygon.vertices; + int n = polygon.vertexCount; + int j,k; + int flag = 0; + float z; + //float tol = 0.001f; + + if (n < 3) + // ERROR: this is a line or a point, render with CONVEX + return true; + + // iterate along border doing dot product. + // if the sign of the result changes, then is concave + for (int i=0;i 0) + flag |= 2; + if (flag == 3) + return false; // CONCAVE + } + if (flag != 0) + return true; // CONVEX + else + // ERROR: colinear points, self intersection + // treat as CONVEX + return true; + } + + + // triangulate the current polygon + private void concaveRender() { + // WARNING: code is not in optimum form + // local initiations of some variables are made to + // keep the code modular and easy to integrate + // restet triangle + float polyVertices[][] = polygon.vertices; + + if (tpolygon == null) { + // allocate on first use, rather than slowing + // the startup of the class. + tpolygon = new PPolygon(this); + tpolygon_vertex_order = new int[TPOLYGON_MAX_VERTICES]; + } + tpolygon.reset(3); + + // copy render parameters + + if (textureImage != null) { + tpolygon.texture(textureImage); //polygon.timage); + } + + tpolygon.interpX = polygon.interpX; + tpolygon.interpZ = polygon.interpZ; + tpolygon.interpUV = polygon.interpUV; + tpolygon.interpARGB = polygon.interpARGB; + + // simple ear clipping polygon triangulation + // addapted from code by john w. ratcliff (jratcliff@verant.com) + + // 1 - first we check if the polygon goes CW or CCW + // CW-CCW ordering adapted from code by + // Joseph O'Rourke orourke@cs.smith.edu + // 1A - we start by finding the lowest-right most vertex + + boolean ccw = false; // clockwise + + int n = polygon.vertexCount; + int mm; // postion for LR vertex + float min[] = new float[2]; + + min[X] = polyVertices[0][X]; + min[Y] = polyVertices[0][Y]; + mm = 0; + + for(int i = 0; i < n; i++ ) { + if( (polyVertices[i][Y] < min[Y]) || + ( (polyVertices[i][Y] == min[Y]) && (polyVertices[i][X] > min[X]) ) + ) { + mm = i; + min[X] = polyVertices[mm][X]; + min[Y] = polyVertices[mm][Y]; + } + } + + // 1B - now we compute the cross product of the edges of this vertex + float cp; + int mm1; + + // just for renaming + float a[] = new float[2]; + float b[] = new float[2]; + float c[] = new float[2]; + + mm1 = (mm + (n-1)) % n; + + // assign a[0] to point to poly[m1][0] etc. + for(int i = 0; i < 2; i++ ) { + a[i] = polyVertices[mm1][i]; + b[i] = polyVertices[mm][i]; + c[i] = polyVertices[(mm+1)%n][i]; + } + + cp = a[0] * b[1] - a[1] * b[0] + + a[1] * c[0] - a[0] * c[1] + + b[0] * c[1] - c[0] * b[1]; + + if ( cp > 0 ) + ccw = true; // CCW + else + ccw = false; // CW + + // 1C - then we sort the vertices so they + // are always in a counterclockwise order + //int j = 0; + if (!ccw) { + // keep the same order + for (int i = 0; i < n; i++) { + tpolygon_vertex_order[i] = i; + } + + } else { + // invert the order + for (int i = 0; i < n; i++) { + tpolygon_vertex_order[i] = (n - 1) - i; + } + } + + // 2 - begin triangulation + // resulting triangles are stored in the triangle array + // remove vc-2 Vertices, creating 1 triangle every time + int vc = n; + int count = 2*vc; // complex polygon detection + + for (int m = 0, v = vc - 1; vc > 2; ) { + boolean snip = true; + + // if we start over again, is a complex polygon + if (0 >= (count--)) { + break; // triangulation failed + } + + // get 3 consecutive vertices + int u = v ; if (vc <= u) u = 0; // previous + v = u+1; if (vc <= v) v = 0; // current + int w = v+1; if (vc <= w) w = 0; // next + + // triangle A B C + float Ax, Ay, Bx, By, Cx, Cy, Px, Py; + + Ax = -polyVertices[tpolygon_vertex_order[u]][X]; + Ay = polyVertices[tpolygon_vertex_order[u]][Y]; + Bx = -polyVertices[tpolygon_vertex_order[v]][X]; + By = polyVertices[tpolygon_vertex_order[v]][Y]; + Cx = -polyVertices[tpolygon_vertex_order[w]][X]; + Cy = polyVertices[tpolygon_vertex_order[w]][Y]; + + if ( EPSILON > (((Bx-Ax) * (Cy-Ay)) - ((By-Ay) * (Cx-Ax)))) { + continue; + } + + for (int p = 0; p < vc; p++) { + + // this part is a bit osbscure, basically what it does + // is test if this tree vertices are and ear or not, looking for + // intersections with the remaining vertices using a cross product + float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; + float cCROSSap, bCROSScp, aCROSSbp; + + if( (p == u) || (p == v) || (p == w) ) { + continue; + } + + Px = -polyVertices[tpolygon_vertex_order[p]][X]; + Py = polyVertices[tpolygon_vertex_order[p]][Y]; + + ax = Cx - Bx; ay = Cy - By; + bx = Ax - Cx; by = Ay - Cy; + cx = Bx - Ax; cy = By - Ay; + apx= Px - Ax; apy= Py - Ay; + bpx= Px - Bx; bpy= Py - By; + cpx= Px - Cx; cpy= Py - Cy; + + aCROSSbp = ax * bpy - ay * bpx; + cCROSSap = cx * apy - cy * apx; + bCROSScp = bx * cpy - by * cpx; + + if ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)) { + snip = false; + } + } + + if (snip) { + // yes, the trio is an ear, render it and cut it + + int triangle_vertices[] = new int[3]; + int s,t; + + // true names of the vertices + triangle_vertices[0] = tpolygon_vertex_order[u]; + triangle_vertices[1] = tpolygon_vertex_order[v]; + triangle_vertices[2] = tpolygon_vertex_order[w]; + + // create triangle + //render_triangle(triangle_vertices); + //private final void render_triangle(int[] triangle_vertices) { + // copy all fields of the triangle vertices + for (int i = 0; i < 3; i++) { + float[] src = polygon.vertices[triangle_vertices[i]]; + float[] dest = tpolygon.vertices[i]; + for (int k = 0; k < VERTEX_FIELD_COUNT; k++) { + dest[k] = src[k]; + } + } + // render triangle + tpolygon.render(); + //} + + m++; + + // remove v from remaining polygon + for( s = v, t = v + 1; t < vc; s++, t++) { + tpolygon_vertex_order[s] = tpolygon_vertex_order[t]; + } + + vc--; + + // resest error detection counter + count = 2 * vc; + } + } + } + + + + ////////////////////////////////////////////////////////////// + + // RECT + + + protected void rectImpl(float x1f, float y1f, float x2f, float y2f) { + + if (untransformed() && !fillAlpha) { + int x1 = (int) x1f; + int y1 = (int) y1f; + int x2 = (int) x2f; + int y2 = (int) y2f; + + rectImplFillUntranSolidRGB(x1, y1, x2, y2); + + if (stroke) { + if (strokeWeight == 1) { + thin_flat_line(x1, y1, x2, y1); + thin_flat_line(x2, y1, x2, y2); + thin_flat_line(x2, y2, x1, y2); + thin_flat_line(x1, y2, x1, y1); + + } else { + thick_flat_line(x1, y1, fillR, fillG, fillB, fillA, + x2, y1, fillR, fillG, fillB, fillA); + thick_flat_line(x2, y1, fillR, fillG, fillB, fillA, + x2, y2, fillR, fillG, fillB, fillA); + thick_flat_line(x2, y2, fillR, fillG, fillB, fillA, + x1, y2, fillR, fillG, fillB, fillA); + thick_flat_line(x1, y2, fillR, fillG, fillB, fillA, + x1, y1, fillR, fillG, fillB, fillA); + } + } + + } else { + beginShape(QUADS); + vertex(x1f, y1f); + vertex(x2f, y1f); + vertex(x2f, y2f); + vertex(x1f, y2f); + endShape(); + } + } + + + /** + * Draw an untransformed rectangle with no alpha. + */ + private void rectImplFillUntranSolidRGB(int x1, int y1, int x2, int y2) { + //System.out.println("flat quad"); + if (y2 < y1) { + int temp = y1; y1 = y2; y2 = temp; + } + if (x2 < x1) { + int temp = x1; x1 = x2; x2 = temp; + } + // checking to watch out for boogers + if ((x1 > width1) || (x2 < 0) || + (y1 > height1) || (y2 < 0)) return; + + //if (fill) { + int fx1 = x1; + int fy1 = y1; + int fx2 = x2; + int fy2 = y2; + + // these only affect the fill, not the stroke + // (otherwise strange boogers at edges b/c frame changes shape) + if (fx1 < 0) fx1 = 0; + if (fx2 > width) fx2 = width; + if (fy1 < 0) fy1 = 0; + if (fy2 > height) fy2 = height; + + // [toxi 031223] + // on avg. 20-25% faster fill routine using System.arraycopy() + int ww = fx2 - fx1; + int hh = fy2 - fy1; + int[] row = new int[ww]; + for (int i = 0; i < ww; i++) row[i] = fillColor; + int idx = fy1 * width + fx1; + for (int y = 0; y < hh; y++) { + System.arraycopy(row, 0, pixels, idx, ww); + idx += width; + } + row = null; + //} + } + + + + ////////////////////////////////////////////////////////////// + + // ELLIPSE AND ARC + + + public void ellipseImpl(float x1, float y1, float w, float h) { + if (!smooth && (strokeWeight == 1) && + !fillAlpha && !strokeAlpha && untransformed()) { + float hradius = w / 2f; + float vradius = h / 2f; + + int centerX = (int) (x1 + hradius); + int centerY = (int) (y1 + vradius); + + if (hradius == vradius) { + flat_circle(centerX, centerY, (int)hradius); + + } else { + flat_ellipse(centerX, centerY, (int)hradius, (int)vradius); + } + } else { + super.ellipseImpl(x1, y1, w, h); + } + } + + + private void flat_circle(int centerX, int centerY, int radius) { + if (unwarped()) { + float x = m00*centerX + m01*centerY + m02; + float y = m10*centerX + m11*centerY + m12; + centerX = (int)x; + centerY = (int)y; + } + if (fill) flat_circle_fill(centerX, centerY, radius); + if (stroke) flat_circle_stroke(centerX, centerY, radius); + } + + + /** + * Draw the outline around a flat circle using a bresenham-style + * algorithm. Adapted from drawCircle function in "Computer Graphics + * for Java Programmers" by Leen Ammeraal, p. 110. + *

    + * This function is included because the quality is so much better, + * and the drawing significantly faster than with adaptive ellipses + * drawn using the sine/cosine tables. + *

    + * Circle quadrants break down like so: + *

    +   *              |
    +   *        \ NNW | NNE /
    +   *          \   |   /
    +   *       WNW  \ | /  ENE
    +   *     -------------------
    +   *       WSW  / | \  ESE
    +   *          /   |   \
    +   *        / SSW | SSE \
    +   *              |
    +   * 
    + * @param xc x center + * @param yc y center + * @param r radius + */ + private void flat_circle_stroke(int xC, int yC, int r) { + int x = 0, y = r, u = 1, v = 2 * r - 1, E = 0; + while (x < y) { + thin_point(xC + x, yC + y, 0, strokeColor); // NNE + thin_point(xC + y, yC - x, 0, strokeColor); // ESE + thin_point(xC - x, yC - y, 0, strokeColor); // SSW + thin_point(xC - y, yC + x, 0, strokeColor); // WNW + + x++; E += u; u += 2; + if (v < 2 * E) { + y--; E -= v; v -= 2; + } + if (x > y) break; + + thin_point(xC + y, yC + x, 0, strokeColor); // ENE + thin_point(xC + x, yC - y, 0, strokeColor); // SSE + thin_point(xC - y, yC - x, 0, strokeColor); // WSW + thin_point(xC - x, yC + y, 0, strokeColor); // NNW + } + } + + /** + * Heavily adapted version of the above algorithm that handles + * filling the ellipse. Works by drawing from the center and + * outwards to the points themselves. Has to be done this way + * because the values for the points are changed halfway through + * the function, making it impossible to just store a series of + * left and right edges to be drawn more quickly. + * + * @param xc x center + * @param yc y center + * @param r radius + */ + private void flat_circle_fill(int xc, int yc, int r) { + int x = 0, y = r, u = 1, v = 2 * r - 1, E = 0; + while (x < y) { + for (int xx = xc; xx < xc + x; xx++) { // NNE + thin_point(xx, yc + y, 0, fillColor); + } + for (int xx = xc; xx < xc + y; xx++) { // ESE + thin_point(xx, yc - x, 0, fillColor); + } + for (int xx = xc - x; xx < xc; xx++) { // SSW + thin_point(xx, yc - y, 0, fillColor); + } + for (int xx = xc - y; xx < xc; xx++) { // WNW + thin_point(xx, yc + x, 0, fillColor); + } + + x++; E += u; u += 2; + if (v < 2 * E) { + y--; E -= v; v -= 2; + } + if (x > y) break; + + for (int xx = xc; xx < xc + y; xx++) { // ENE + thin_point(xx, yc + x, 0, fillColor); + } + for (int xx = xc; xx < xc + x; xx++) { // SSE + thin_point(xx, yc - y, 0, fillColor); + } + for (int xx = xc - y; xx < xc; xx++) { // WSW + thin_point(xx, yc - x, 0, fillColor); + } + for (int xx = xc - x; xx < xc; xx++) { // NNW + thin_point(xx, yc + y, 0, fillColor); + } + } + } + + // unfortunately this can't handle fill and stroke simultaneously, + // because the fill will later replace some of the stroke points + + private final void flat_ellipse_symmetry(int centerX, int centerY, + int ellipseX, int ellipseY, + boolean filling) { + if (filling) { + for (int i = centerX - ellipseX + 1; i < centerX + ellipseX; i++) { + thin_point(i, centerY - ellipseY, 0, fillColor); + thin_point(i, centerY + ellipseY, 0, fillColor); + } + } else { + thin_point(centerX - ellipseX, centerY + ellipseY, 0, strokeColor); + thin_point(centerX + ellipseX, centerY + ellipseY, 0, strokeColor); + thin_point(centerX - ellipseX, centerY - ellipseY, 0, strokeColor); + thin_point(centerX + ellipseX, centerY - ellipseY, 0, strokeColor); + } + } + + + /** + * Bresenham-style ellipse drawing function, adapted from a posting to + * comp.graphics.algortihms. + * + * This function is included because the quality is so much better, + * and the drawing significantly faster than with adaptive ellipses + * drawn using the sine/cosine tables. + * + * @param centerX x coordinate of the center + * @param centerY y coordinate of the center + * @param a horizontal radius + * @param b vertical radius + */ + private void flat_ellipse_internal(int centerX, int centerY, + int a, int b, boolean filling) { + int x, y, a2, b2, s, t; + + a2 = a*a; + b2 = b*b; + x = 0; + y = b; + s = a2*(1-2*b) + 2*b2; + t = b2 - 2*a2*(2*b-1); + flat_ellipse_symmetry(centerX, centerY, x, y, filling); + + do { + if (s < 0) { + s += 2*b2*(2*x+3); + t += 4*b2*(x+1); + x++; + } else if (t < 0) { + s += 2*b2*(2*x+3) - 4*a2*(y-1); + t += 4*b2*(x+1) - 2*a2*(2*y-3); + x++; + y--; + } else { + s -= 4*a2*(y-1); + t -= 2*a2*(2*y-3); + y--; + } + flat_ellipse_symmetry(centerX, centerY, x, y, filling); + + } while (y > 0); + } + + + private void flat_ellipse(int centerX, int centerY, int a, int b) { + if (unwarped()) { + float x = m00*centerX + m01*centerY + m02; + float y = m10*centerX + m11*centerY + m12; + centerX = (int)x; + centerY = (int)y; + } + if (fill) flat_ellipse_internal(centerX, centerY, a, b, true); + if (stroke) flat_ellipse_internal(centerX, centerY, a, b, false); + } + + + // TODO really need a decent arc function in here.. + + //protected void arcImpl(float x1, float y1, float w, float h, + // float start, float stop) + + + + ////////////////////////////////////////////////////////////// + + // BOX & SPHERE + + + // The PGraphics superclass will throw errors for these fellas + + + + ////////////////////////////////////////////////////////////// + + // BEZIER & CURVE + + + public void bezier(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + depthErrorXYZ("bezier"); + } + + + public void curve(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + depthErrorXYZ("curve"); + } + + + + ////////////////////////////////////////////////////////////// + + // IMAGE + + + protected void imageImpl(PImage image, + float x1, float y1, float x2, float y2, + int u1, int v1, int u2, int v2) { + if ((x2 - x1 == image.width) && + (y2 - y1 == image.height) && + !tint && unwarped()) { + flat_image(image, (int) (x1 + m02), (int) (y1 + m12), u1, v1, u2, v2); + + } else { + super.imageImpl(image, x1, y1, x2, y2, u1, v1, u2, v2); + } + } + + + /** + * Image drawn in flat "screen space", with no scaling or warping. + * this is so common that a special routine is included for it, + * because the alternative is much slower. + * + * @param image image to be drawn + * @param sx1 x coordinate of upper-lefthand corner in screen space + * @param sy1 y coordinate of upper-lefthand corner in screen space + */ + private void flat_image(PImage image, int sx1, int sy1, + int ix1, int iy1, int ix2, int iy2) { + /* + int ix1 = 0; + int iy1 = 0; + int ix2 = image.width; + int iy2 = image.height; + */ + + if (imageMode == CENTER) { + sx1 -= image.width / 2; + sy1 -= image.height / 2; + } + + int sx2 = sx1 + image.width; + int sy2 = sy1 + image.height; + + // don't draw if completely offscreen + // (without this check, ArrayIndexOutOfBoundsException) + if ((sx1 > width1) || (sx2 < 0) || + (sy1 > height1) || (sy2 < 0)) return; + + if (sx1 < 0) { // off left edge + ix1 -= sx1; + sx1 = 0; + } + if (sy1 < 0) { // off top edge + iy1 -= sy1; + sy1 = 0; + } + if (sx2 > width) { // off right edge + ix2 -= sx2 - width; + sx2 = width; + } + if (sy2 > height) { // off bottom edge + iy2 -= sy2 - height; + sy2 = height; + } + + int source = iy1 * image.width + ix1; + int target = sy1 * width; + + if (image.format == ARGB) { + for (int y = sy1; y < sy2; y++) { + int tx = 0; + + for (int x = sx1; x < sx2; x++) { + pixels[target + x] = + _blend(pixels[target + x], + image.pixels[source + tx], + image.pixels[source + tx++] >>> 24); + } + source += image.width; + target += width; + } + } else if (image.format == ALPHA) { + for (int y = sy1; y < sy2; y++) { + int tx = 0; + + for (int x = sx1; x < sx2; x++) { + pixels[target + x] = + _blend(pixels[target + x], + fillColor, + image.pixels[source + tx++]); + } + source += image.width; + target += width; + } + + } else if (image.format == RGB) { + target += sx1; + int tw = sx2 - sx1; + for (int y = sy1; y < sy2; y++) { + System.arraycopy(image.pixels, source, pixels, target, tw); + // should set z coordinate in here + // or maybe not, since dims=0, meaning no relevant z + source += image.width; + target += width; + } + } + } + + + ////////////////////////////////////////////////////////////// + + // TEXT/FONTS + + + // These will be handled entirely by PGraphics. + + + + ////////////////////////////////////////////////////////////// + + + // expects properly clipped coords, hence does + // NOT check if x/y are in bounds [toxi] + private void thin_pointAt(int x, int y, float z, int color) { + int index = y*width+x; // offset values are pre-calced in constructor + pixels[index] = color; + zbuffer[index] = z; + } + + // expects offset/index in pixelbuffer array instead of x/y coords + // used by optimized parts of thin_flat_line() [toxi] + private void thin_pointAtIndex(int offset, float z, int color) { + pixels[offset] = color; + zbuffer[offset] = z; + } + + // points are inherently flat, but always tangent + // to the screen surface. the z is only so that things + // get scaled properly if the pt is way in back + private void thick_point(float x, float y, float z, // note floats + float r, float g, float b, float a) { + spolygon.reset(4); + spolygon.interpARGB = false; // no changes for vertices of a point + + float strokeWidth2 = strokeWeight/2.0f; + + float svertex[] = spolygon.vertices[0]; + svertex[X] = x - strokeWidth2; + svertex[Y] = y - strokeWidth2; + svertex[Z] = z; + + svertex[R] = r; + svertex[G] = g; + svertex[B] = b; + svertex[A] = a; + + svertex = spolygon.vertices[1]; + svertex[X] = x + strokeWidth2; + svertex[Y] = y - strokeWidth2; + svertex[Z] = z; + + svertex = spolygon.vertices[2]; + svertex[X] = x + strokeWidth2; + svertex[Y] = y + strokeWidth2; + svertex[Z] = z; + + svertex = spolygon.vertices[3]; + svertex[X] = x - strokeWidth2; + svertex[Y] = y + strokeWidth2; + svertex[Z] = z; + + spolygon.render(); + } + + + // new bresenham clipping code, as old one was buggy [toxi] + private void thin_flat_line(int x1, int y1, int x2, int y2) { + int nx1,ny1,nx2,ny2; + + // get the "dips" for the points to clip + int code1 = thin_flat_lineClipCode(x1, y1); + int code2 = thin_flat_lineClipCode(x2, y2); + + if ((code1 & code2)!=0) { + return; + } else { + int dip = code1 | code2; + if (dip != 0) { + // now calculate the clipped points + float a1 = 0, a2 = 1, a = 0; + for (int i=0;i<4;i++) { + if (((dip>>i)%2)==1) { + a = thin_flat_lineSlope((float)x1, (float)y1, + (float)x2, (float)y2, i+1); + if (((code1>>i)%2)==1) { + a1 = (float)Math.max(a, a1); + } else { + a2 = (float)Math.min(a, a2); + } + } + } + if (a1>a2) return; + else { + nx1=(int) (x1+a1*(x2-x1)); + ny1=(int) (y1+a1*(y2-y1)); + nx2=(int) (x1+a2*(x2-x1)); + ny2=(int) (y1+a2*(y2-y1)); + } + // line is fully visible/unclipped + } else { + nx1=x1; nx2=x2; + ny1=y1; ny2=y2; + } + } + + // new "extremely fast" line code + // adapted from http://www.edepot.com/linee.html + + boolean yLonger=false; + int shortLen=ny2-ny1; + int longLen=nx2-nx1; + if (Math.abs(shortLen)>Math.abs(longLen)) { + int swap=shortLen; + shortLen=longLen; + longLen=swap; + yLonger=true; + } + int decInc; + if (longLen==0) decInc=0; + else decInc = (shortLen << 16) / longLen; + + if (nx1==nx2) { + // special case: vertical line + if (ny1>ny2) { int ty=ny1; ny1=ny2; ny2=ty; } + int offset=ny1*width+nx1; + for(int j=ny1; j<=ny2; j++) { + thin_pointAtIndex(offset,0,strokeColor); + offset+=width; + } + return; + } else if (ny1==ny2) { + // special case: horizontal line + if (nx1>nx2) { int tx=nx1; nx1=nx2; nx2=tx; } + int offset=ny1*width+nx1; + for(int j=nx1; j<=nx2; j++) thin_pointAtIndex(offset++,0,strokeColor); + return; + } else if (yLonger) { + if (longLen>0) { + longLen+=ny1; + for (int j=0x8000+(nx1<<16);ny1<=longLen;++ny1) { + thin_pointAt(j>>16, ny1, 0, strokeColor); + j+=decInc; + } + return; + } + longLen+=ny1; + for (int j=0x8000+(nx1<<16);ny1>=longLen;--ny1) { + thin_pointAt(j>>16, ny1, 0, strokeColor); + j-=decInc; + } + return; + } else if (longLen>0) { + longLen+=nx1; + for (int j=0x8000+(ny1<<16);nx1<=longLen;++nx1) { + thin_pointAt(nx1, j>>16, 0, strokeColor); + j+=decInc; + } + return; + } + longLen+=nx1; + for (int j=0x8000+(ny1<<16);nx1>=longLen;--nx1) { + thin_pointAt(nx1, j>>16, 0, strokeColor); + j-=decInc; + } + } + + private int thin_flat_lineClipCode(float x, float y) { + return ((y < 0 ? 8 : 0) | (y > height1 ? 4 : 0) | + (x < 0 ? 2 : 0) | (x > width1 ? 1 : 0)); + } + + private float thin_flat_lineSlope(float x1, float y1, + float x2, float y2, int border) { + switch (border) { + case 4: { + return (-y1)/(y2-y1); + } + case 3: { + return (height1-y1)/(y2-y1); + } + case 2: { + return (-x1)/(x2-x1); + } + case 1: { + return (width1-x1)/(x2-x1); + } + } + return -1f; + } + + + private boolean flat_line_retribution(float x1, float y1, + float x2, float y2, + float r1, float g1, float b1) { + /* + // assume that if it is/isn't big in one dir, then the + // other doesn't matter, cuz that's a weird case + float lwidth = m00*strokeWeight + m01*strokeWeight; + //float lheight = m10*strokeWeight + m11*strokeWeight; + // lines of stroke thickness 1 can be anywhere from -1.41 to 1.41 + if ((strokeWeight < TWO) && (!hints[SCALE_STROKE_WIDTH])) { + //if (abs(lwidth) < 1.5f) { + //System.out.println("flat line retribution " + r1 + " " + g1 + " " + b1); + int strokeSaved = strokeColor; + strokeColor = float_color(r1, g1, b1); + thin_flat_line((int)x1, (int)y1, (int)x2, (int)y2); + strokeColor = strokeSaved; + return true; + } + */ + return false; + } + + + private void thick_flat_line(float ox1, float oy1, + float r1, float g1, float b1, float a1, + float ox2, float oy2, + float r2, float g2, float b2, float a2) { + spolygon.interpARGB = (r1 != r2) || (g1 != g2) || (b1 != b2) || (a1 != a2); + spolygon.interpZ = false; + + if (!spolygon.interpARGB && + flat_line_retribution(ox1, oy1, ox2, oy2, r1, g1, b1)) { + return; + } + + float dX = ox2-ox1 + EPSILON; + float dY = oy2-oy1 + EPSILON; + float len = sqrt(dX*dX + dY*dY); + + // TODO strokeWidth should be transformed! + float rh = strokeWeight / len; + + float dx0 = rh * dY; + float dy0 = rh * dX; + float dx1 = rh * dY; + float dy1 = rh * dX; + + spolygon.reset(4); + + float svertex[] = spolygon.vertices[0]; + svertex[X] = ox1+dx0; + svertex[Y] = oy1-dy0; + svertex[R] = r1; + svertex[G] = g1; + svertex[B] = b1; + svertex[A] = a1; + + svertex = spolygon.vertices[1]; + svertex[X] = ox1-dx0; + svertex[Y] = oy1+dy0; + svertex[R] = r1; + svertex[G] = g1; + svertex[B] = b1; + svertex[A] = a1; + + svertex = spolygon.vertices[2]; + svertex[X] = ox2-dx1; + svertex[Y] = oy2+dy1; + svertex[R] = r2; + svertex[G] = g2; + svertex[B] = b2; + svertex[A] = a2; + + svertex = spolygon.vertices[3]; + svertex[X] = ox2+dx1; + svertex[Y] = oy2-dy1; + svertex[R] = r2; + svertex[G] = g2; + svertex[B] = b2; + svertex[A] = a2; + + spolygon.render(); + } + + + /* + // OPT version without z coords can save 8 multiplies and some other + private void spatial_line(float x1, float y1, + float r1, float g1, float b1, + float x2, float y2, + float r2, float g2, float b2) { + spatial_line(x1, y1, 0, r1, g1, b1, + x2, y2, 0, r2, g2, b2); + } + + + // the incoming values are transformed, + // and the colors have been calculated + + private void spatial_line(float x1, float y1, float z1, + float r1, float g1, float b1, + float x2, float y2, float z2, + float r2, float g2, float b2) { + spolygon.interpARGB = (r1 != r2) || (g1 != g2) || (b1 != b2); + if (!spolygon.interpARGB && + flat_line_retribution(x1, y1, x2, y2, r1, g1, b1)) { + return; + } + + spolygon.interpZ = true; + + float ox1 = x1; float oy1 = y1; float oz1 = z1; + float ox2 = x2; float oy2 = y2; float oz2 = z2; + + float dX = ox2-ox1 + 0.0001f; + float dY = oy2-oy1 + 0.0001f; + float len = sqrt(dX*dX + dY*dY); + + //float x0 = m00*0 + m01*0 + m03; + + float rh = strokeWeight / len; + + float dx0 = rh * dY; + float dy0 = rh * dX; + float dx1 = rh * dY; + float dy1 = rh * dX; + + spolygon.reset(4); + + float svertex[] = spolygon.vertices[0]; + svertex[X] = ox1+dx0; + svertex[Y] = oy1-dy0; + svertex[Z] = oz1; + svertex[R] = r1; //calcR1; + svertex[G] = g1; //calcG1; + svertex[B] = b1; //calcB1; + + svertex = spolygon.vertices[1]; + svertex[X] = ox1-dx0; + svertex[Y] = oy1+dy0; + svertex[Z] = oz1; + svertex[R] = r1; //calcR1; + svertex[G] = g1; //calcG1; + svertex[B] = b1; //calcB1; + + svertex = spolygon.vertices[2]; + svertex[X] = ox2-dx1; + svertex[Y] = oy2+dy1; + svertex[Z] = oz2; + svertex[R] = r2; //calcR2; + svertex[G] = g2; //calcG2; + svertex[B] = b2; //calcB2; + + svertex = spolygon.vertices[3]; + svertex[X] = ox2+dx1; + svertex[Y] = oy2-dy1; + svertex[Z] = oz2; + svertex[R] = r2; //calcR2; + svertex[G] = g2; //calcG2; + svertex[B] = b2; //calcB2; + + spolygon.render(); + } + */ + + + // max is what to count to + // offset is offset to the 'next' vertex + // increment is how much to increment in the loop + private void draw_lines(float vertices[][], int max, + int offset, int increment, int skip) { + + if (strokeWeight < 2) { + for (int i = 0; i < max; i += increment) { + if ((skip != 0) && (((i+offset) % skip) == 0)) continue; + + float a[] = vertices[i]; + float b[] = vertices[i+offset]; + + if (line == null) line = new PLine(this); + + line.reset(); + line.setIntensities(a[SR], a[SG], a[SB], a[SA], + b[SR], b[SG], b[SB], b[SA]); + line.setVertices(a[X], a[Y], a[Z], + b[X], b[Y], b[Z]); + line.draw(); + } + + } else { // use old line code for thickness > 1 + + if ((strokeWeight < 2) && !strokeChanged) { + // need to set color at least once? + + // THIS PARTICULAR CASE SHOULD NO LONGER BE REACHABLE + + for (int i = 0; i < max; i += increment) { + if ((skip != 0) && (((i+offset) % skip) == 0)) continue; + thin_flat_line((int) vertices[i][X], + (int) vertices[i][Y], + (int) vertices[i+offset][X], + (int) vertices[i+offset][Y]); + } + } else { + for (int i = 0; i < max; i += increment) { + if ((skip != 0) && (((i+offset) % skip) == 0)) continue; + float v1[] = vertices[i]; + float v2[] = vertices[i+offset]; + thick_flat_line(v1[X], v1[Y], v1[SR], v1[SG], v1[SB], v1[SA], + v2[X], v2[Y], v2[SR], v2[SG], v2[SB], v2[SA]); + } + } + } + } + + + + ////////////////////////////////////////////////////////////// + + // UGLY RENDERING SHIT + + + private void thin_point(int x, int y, float z, int color) { + // necessary? [fry] yes! [toxi] + if (x<0 || x>width1 || y<0 || y>height1) return; + + int index = y*width + x; + if ((color & 0xff000000) == 0xff000000) { // opaque + pixels[index] = color; + + } else { // transparent + // couldn't seem to get this working correctly + + //pixels[index] = _blend(pixels[index], + // color & 0xffffff, (color >> 24) & 0xff); + + // a1 is how much of the orig pixel + int a2 = (color >> 24) & 0xff; + int a1 = a2 ^ 0xff; + + int p2 = strokeColor; + int p1 = pixels[index]; + + int r = (a1 * ((p1 >> 16) & 0xff) + a2 * ((p2 >> 16) & 0xff)) & 0xff00; + int g = (a1 * ((p1 >> 8) & 0xff) + a2 * ((p2 >> 8) & 0xff)) & 0xff00; + int b = (a1 * ( p1 & 0xff) + a2 * ( p2 & 0xff)) >> 8; + + pixels[index] = 0xff000000 | (r << 8) | g | b; + + //pixels[index] = _blend(pixels[index], + // color & 0xffffff, (color >> 24) & 0xff); + /* + pixels[index] = 0xff000000 | + ((((a1 * ((pixels[index] >> 16) & 0xff) + + a2 * ((color >> 16) & 0xff)) & 0xff00) << 24) << 8) | + (((a1 * ((pixels[index] >> 8) & 0xff) + + a2 * ((color >> 8) & 0xff)) & 0xff00) << 16) | + (((a1 * ( pixels[index] & 0xff) + + a2 * ( color & 0xff)) >> 8)); + */ + } + zbuffer[index] = z; + } + + + + ////////////////////////////////////////////////////////////// + + // BACKGROUND AND FRIENDS + + + /** + * Clear the pixel buffer. + */ + protected void clear() { + for (int i = 0; i < pixelCount; i++) { + pixels[i] = backgroundColor; + } + } + + + + ////////////////////////////////////////////////////////////// + + // INTERNAL SCHIZZLE + + + private boolean untransformed() { + return ((m00 == 1) && (m01 == 0) && (m02 == 0) && + (m10 == 0) && (m11 == 1) && (m12 == 0)); + } + + + private boolean unwarped() { + return ((m00 == 1) && (m01 == 0) && (m10 == 0) && (m11 == 1)); + } + + + + // doesn't really do lighting per se... + private void calc_lighting(float r, float g, float b, + float ix, float iy, float iz, + float nx, float ny, float nz, + float target[], int toffset) { + target[toffset + 0] = r; + target[toffset + 1] = g; + target[toffset + 2] = b; + } + + + static private final int float_color(float r, float g, float b) { + return (0xff000000 | + ((int) (255.0f * r)) << 16 | + ((int) (255.0f * g)) << 8 | + ((int) (255.0f * b))); + } + + public final static int _blend(int p1, int p2, int a2) { + // scale alpha by alpha of incoming pixel + a2 = (a2 * (p2 >>> 24)) >> 8; + + int a1 = a2 ^ 0xff; + int r = (a1 * ((p1 >> 16) & 0xff) + a2 * ((p2 >> 16) & 0xff)) & 0xff00; + int g = (a1 * ((p1 >> 8) & 0xff) + a2 * ((p2 >> 8) & 0xff)) & 0xff00; + int b = (a1 * ( p1 & 0xff) + a2 * ( p2 & 0xff)) >> 8; + + return 0xff000000 | (r << 8) | g | b; + } +} diff --git a/core/PGraphics3D.java b/core/PGraphics3D.java new file mode 100644 index 000000000..40ec5d711 --- /dev/null +++ b/core/PGraphics3D.java @@ -0,0 +1,3943 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.Toolkit; +import java.awt.image.DirectColorModel; +import java.awt.image.MemoryImageSource; + + +/** + * Subclass of PGraphics that handles 3D rendering for Java 1.1. + * It can render 3D inside a browser window and requires no plug-ins. + *

    + * The renderer is mostly set up based on the structure of the OpenGL API, + * if you have questions about specifics that aren't covered here, + * look for reference on the OpenGL implementation of a similar feature. + *

    + * Lighting and camera implementation by Simon Greenwold. + */ +public class PGraphics3D extends PGraphics { + + // ........................................................ + + // Lighting-related variables + + // Whether or not we have to worry about vertex position for lighting calcs + private boolean lightingDependsOnVertexPosition; + + static final int LIGHT_AMBIENT_R = 0; + static final int LIGHT_AMBIENT_G = 1; + static final int LIGHT_AMBIENT_B = 2; + static final int LIGHT_DIFFUSE_R = 3; + static final int LIGHT_DIFFUSE_G = 4; + static final int LIGHT_DIFFUSE_B = 5; + static final int LIGHT_SPECULAR_R = 6; + static final int LIGHT_SPECULAR_G = 7; + static final int LIGHT_SPECULAR_B = 8; + + static final int LIGHT_COLOR_COUNT = 9; + + // Used to shuttle lighting calcs around + // (no need to re-allocate all the time) + protected float[] tempLightingContribution = new float[LIGHT_COLOR_COUNT]; + protected float[] worldNormal = new float[4]; + + // Used in light_triangle(). Allocated here once to + // avoid re-allocating each time + protected float[] dv1 = new float[3]; + protected float[] dv2 = new float[3]; + protected float[] norm = new float[3]; + + // ........................................................ + + /** + * This is turned on at beginCamera, and off at endCamera + * Currently we don't support nested begin/end cameras. + * If we wanted to, this variable would have to become a stack. + */ + protected boolean manipulatingCamera; + + // These two matrices always point to either the modelview + // or the modelviewInv, but they are swapped during + // when in camera maniuplation mode. That way camera transforms + // are automatically accumulated in inverse on the modelview matrix. + protected PMatrix forwardTransform; + protected PMatrix reverseTransform; + + // Added by ewjordan for accurate texturing purposes. Screen plane is + // not scaled to pixel-size, so these manually keep track of its size + // from frustum() calls. Sorry to add public vars, is there a way + // to compute these from something publicly available without matrix ops? + // (used once per triangle in PTriangle with ENABLE_ACCURATE_TEXTURES) + protected float leftScreen; + protected float rightScreen; + protected float topScreen; + protected float bottomScreen; + protected float nearPlane; //depth of near clipping plane + + // ........................................................ + + // pos of first vertex of current shape in vertices array + protected int vertex_start; + + // i think vertex_end is actually the last vertex in the current shape + // and is separate from vertexCount for occasions where drawing happens + // on endDraw() with all the triangles being depth sorted + protected int vertex_end; + + // vertices may be added during clipping against the near plane. + protected int vertex_end_including_clip_verts; + + // used for sorting points when triangulating a polygon + // warning - maximum number of vertices for a polygon is DEFAULT_VERTICES + protected int vertex_order[] = new int[DEFAULT_VERTICES]; + + // ........................................................ + + protected int pathCount; + protected int pathOffset[] = new int[64]; + protected int pathLength[] = new int[64]; + + // ........................................................ + + // lines + static final int DEFAULT_LINES = 512; + public PLine line; // used for drawing + protected int lines[][] = new int[DEFAULT_LINES][LINE_FIELD_COUNT]; + protected int lineCount; + + // ........................................................ + + // triangles + static final int DEFAULT_TRIANGLES = 256; + public PTriangle triangle; + protected int triangles[][] = + new int[DEFAULT_TRIANGLES][TRIANGLE_FIELD_COUNT]; + protected float triangleColors[][][] = + new float[DEFAULT_TRIANGLES][3][TRIANGLE_COLOR_COUNT]; + protected int triangleCount; // total number of triangles + + // cheap picking someday + public int shape_index; + + // ........................................................ + + /** + * Sets whether texture coordinates passed to + * vertex() calls will be based on coordinates that are + * based on the IMAGE or NORMALIZED. + */ + //public int textureMode; + + /** + * Current horizontal coordinate for texture, will always + * be between 0 and 1, even if using textureMode(IMAGE). + */ + //public float textureU; + + /** Current vertical coordinate for texture, see above. */ + //public float textureV; + + //public PImage textureImage; + + static final int DEFAULT_TEXTURES = 3; + protected PImage textures[] = new PImage[DEFAULT_TEXTURES]; + int texture_index; + + // ........................................................ + + /** + * Normals + */ + //public float normalX, normalY, normalZ; + //public int normalMode; + //public int normalCount; + + // ........................................................ + + // [toxi031031] new & faster sphere code w/ support flexibile resolutions + // will be set by sphereDetail() or 1st call to sphere() + float sphereX[], sphereY[], sphereZ[]; + //public int sphereDetail = 0; + + // ........................................................ + + + /** + * Constructor for the PGraphics3 object. + * This prototype only exists because of annoying + * java compilers, and should not be used. + */ + /* + public PGraphics3D() { + forwardTransform = modelview; + reverseTransform = modelviewInv; + } + */ + + /* + public PGraphics3D(int iwidth, int iheight) { + this(iwidth, iheight, null); + } + */ + + + /** + * Constructor for the PGraphics3 object. Use this to ensure that + * the defaults get set properly. In a subclass, use this(w, h) + * as the first line of a subclass' constructor to properly set + * the internal fields and defaults. + * + * @param iwidth viewport width + * @param iheight viewport height + */ + public PGraphics3D(int iwidth, int iheight, PApplet parent) { + // super will add the listeners to the applet, and call resize() + super(iwidth, iheight, parent); + forwardTransform = modelview; + reverseTransform = modelviewInv; + //resize(iwidth, iheight); + //projection = new PMatrix(); + } + + + /** + * Called in repsonse to a resize event, handles setting the + * new width and height internally, as well as re-allocating + * the pixel buffer for the new size. + * + * Note that this will nuke any cameraMode() settings. + */ + public void resize(int iwidth, int iheight) { // ignore + insideDrawWait(); + insideResize = true; + + width = iwidth; + height = iheight; + width1 = width - 1; + height1 = height - 1; + + allocate(); + + // clear the screen with the old background color + //background(backgroundColor); + + // init perspective projection based on new dimensions + cameraFOV = 60 * DEG_TO_RAD; // at least for now + cameraX = width / 2.0f; + cameraY = height / 2.0f; + //cameraZ = cameraY / ((float) tan(PI * cameraFOV / 360f)); + cameraZ = cameraY / ((float) tan(cameraFOV / 2.0f)); + cameraNear = cameraZ / 10.0f; + cameraFar = cameraZ * 10.0f; + + cameraAspect = (float)width / (float)height; + + // init lights (in resize() instead of allocate() b/c needed by opengl) + lightType = new int[MAX_LIGHTS]; + lightPosition = new float[MAX_LIGHTS][3]; + lightDiffuse = new float[MAX_LIGHTS][3]; + lightNormal = new float[MAX_LIGHTS][3]; + lightSpecular = new float[MAX_LIGHTS][3]; + lightFalloffConstant = new float[MAX_LIGHTS]; + lightFalloffLinear = new float[MAX_LIGHTS]; + lightFalloffQuadratic = new float[MAX_LIGHTS]; + lightSpotAngle = new float[MAX_LIGHTS]; + lightSpotAngleCos = new float[MAX_LIGHTS]; + lightSpotConcentration = new float[MAX_LIGHTS]; + currentLightSpecular = new float[3]; + + // reset the cameraMode if PERSPECTIVE or ORTHOGRAPHIC + // will just be ignored if CUSTOM, the user's hosed anyways + //System.out.println("setting cameraMode to " + cameraMode); + //if (this.cameraMode != CUSTOM) cameraMode(this.cameraMode); + + // making this again here because things are weird + projection = new PMatrix(); + + modelview = new PMatrix(MATRIX_STACK_DEPTH); + modelviewInv = new PMatrix(MATRIX_STACK_DEPTH); + forwardTransform = modelview; + reverseTransform = modelviewInv; + + camera = new PMatrix(); + cameraInv = new PMatrix(); + + // set up the default camera + camera(); + + // defaults to perspective, if the user has setup up their + // own projection, they'll need to fix it after resize anyway. + // this helps the people who haven't set up their own projection. + perspective(); + + insideResize = false; // ok to draw again + } + + + protected void allocate() { + //System.out.println(this + " allocating for " + width + " " + height); + //new Exception().printStackTrace(); + + pixelCount = width * height; + pixels = new int[pixelCount]; + zbuffer = new float[pixelCount]; + + if (mainDrawingSurface) { + // because of a java 1.1 bug, pixels must be registered as + // opaque before their first run, the memimgsrc will flicker + // and run very slowly. + //backgroundColor |= 0xff000000; // just for good measure + for (int i = 0; i < pixelCount; i++) pixels[i] = backgroundColor; + //for (int i = 0; i < pixelCount; i++) pixels[i] = 0xffffffff; + + cm = new DirectColorModel(32, 0x00ff0000, 0x0000ff00, 0x000000ff);; + mis = new MemoryImageSource(width, height, pixels, 0, width); + mis.setFullBufferUpdates(true); + mis.setAnimated(true); + image = Toolkit.getDefaultToolkit().createImage(mis); + + } else { + // when not the main drawing surface, need to set the zbuffer, + // because there's a possibility that background() will not be called + for (int i = 0; i < pixelCount; i++) { + zbuffer[i] = Float.MAX_VALUE; + } + } + + stencil = new int[pixelCount]; + + line = new PLine(this); + triangle = new PTriangle(this); + + // can't un-set this because this may be only a resize (Bug #463) + //defaultsInited = false; + //System.out.println(this + " done allocating"); + } + + + public void beginDraw() { + insideResizeWait(); + insideDraw = true; + + // need to call defaults(), but can only be done when it's ok + // to draw (i.e. for opengl, no drawing can be done outside + // beginDraw/endDraw). + if (!defaultsInited) defaults(); + + resetMatrix(); // reset model matrix + + // reset vertices + vertexCount = 0; + + modelview.set(camera); + modelviewInv.set(cameraInv); + + // clear out the lights, they'll have to be turned on again + lightCount = 0; + lightingDependsOnVertexPosition = false; + lightFalloff(1, 0, 0); + lightSpecular(0, 0, 0); + + // reset lines + lineCount = 0; + if (line != null) line.reset(); // is this necessary? + pathCount = 0; + + // reset triangles + triangleCount = 0; + if (triangle != null) triangle.reset(); // necessary? + + vertex_start = 0; + //vertex_end = 0; + + // reset textures + texture_index = 0; + + normal(0, 0, 1); + } + + + /** + * See notes in PGraphics. + * If z-sorting has been turned on, then the triangles will + * all be quicksorted here (to make alpha work more properly) + * and then blit to the screen. + */ + public void endDraw() { + // no need to z order and render + // shapes were already rendered in endShape(); + // (but can't return, since needs to update memimgsrc) + if (hints[ENABLE_DEPTH_SORT]) { + flush(); + } + // blit to screen + // moving this back here (post-68) because of macosx thread problem + if (mis != null) { + mis.newPixels(pixels, cm, 0, width); + } + // mark pixels as having been updated, so that they'll work properly + // when this PGraphics is drawn using image(). + updatePixels(); + + //System.out.println(this + " end draw"); + insideDraw = false; + } + + + /** + * Emit any sorted geometry that's been collected on this frame. + */ + protected void flush() { + if (triangleCount > 0) { + if (hints[ENABLE_DEPTH_SORT]) { + depth_sort_triangles(); + } + render_triangles(); + } + if (lineCount > 0) { + if (hints[ENABLE_DEPTH_SORT]) { + depth_sort_lines(); + } + render_lines(); + } + } + + + public void defaults() { + super.defaults(); + + manipulatingCamera = false; + forwardTransform = modelview; + reverseTransform = modelviewInv; + + perspective(); + + // easiest for beginners + textureMode(IMAGE); + + emissive(0.0f); + specular(0.5f); + shininess(1.0f); + } + + + ////////////////////////////////////////////////////////////// + + + public void beginShape(int kind) { + shape = kind; + + shape_index = shape_index + 1; + if (shape_index == -1) { + shape_index = 0; + } + + if (hints[ENABLE_DEPTH_SORT]) { + // continue with previous vertex, line and triangle count + // all shapes are rendered at endDraw(); + vertex_start = vertexCount; + vertex_end = 0; + + } else { + // reset vertex, line and triangle information + // every shape is rendered at endShape(); + vertexCount = 0; + if (line != null) line.reset(); // necessary? + lineCount = 0; + pathCount = 0; + if (triangle != null) triangle.reset(); // necessary? + triangleCount = 0; + } + textureImage = null; + + splineVertexCount = 0; + normalMode = AUTO_NORMAL; + normalCount = 0; + } + + + /** + * Sets the current normal vector. + *

    + * This is for drawing three dimensional shapes and surfaces, + * allowing you to specify a vector perpendicular to the surface + * of the shape, which determines how lighting affects it. + *

    + * For the most part, PGraphics3D will attempt to automatically + * assign normals to shapes, but since that's imperfect, + * this is a better option when you want more control. + *

    + * For people familiar with OpenGL, this function is basically + * identical to glNormal3f(). + *

    + * Only applies inside a beginShape/endShape block. + */ + public void normal(float nx, float ny, float nz) { + normalX = nx; + normalY = ny; + normalZ = nz; + + // if drawing a shape and the normal hasn't been set yet, + // then we need to set the normals for each vertex so far + if (shape != 0) { + if (normalCount == 0) { + for (int i = vertex_start; i < vertexCount; i++) { + vertices[i][NX] = normalX; + vertices[i][NY] = normalY; + vertices[i][NZ] = normalZ; + } + } + + normalCount++; + if (normalCount == 1) { + // One normal per begin/end shape + normalMode = MANUAL_SHAPE_NORMAL; + } else { + // a separate normal for each vertex + normalMode = MANUAL_VERTEX_NORMAL; + } + } + } + + + public void texture(PImage image) { + textureImage = image; + + if (texture_index == textures.length - 1) { + PImage temp[] = new PImage[texture_index<<1]; + System.arraycopy(textures, 0, temp, 0, texture_index); + textures = temp; + //message(CHATTER, "allocating more textures " + textures.length); + } + if (textures[texture_index] != null) { + texture_index++; + } + textures[texture_index] = image; + } + + + public void vertex(float x, float y) { + setup_vertex(x, y, 0); + } + + + public void vertex(float x, float y, float u, float v) { + textureVertex(u, v); + setup_vertex(x, y, 0); + } + + + public void vertex(float x, float y, float z) { + setup_vertex(x, y, z); + } + + + public void vertex(float x, float y, float z, + float u, float v) { + textureVertex(u, v); + setup_vertex(x, y, z); + } + + + protected void setup_vertex(float x, float y, float z) { + if (vertexCount == vertices.length) { + float temp[][] = new float[vertexCount << 1][VERTEX_FIELD_COUNT]; + System.arraycopy(vertices, 0, temp, 0, vertexCount); + vertices = temp; + int temp2[] = new int[vertexCount << 1]; + System.arraycopy(vertex_order, 0, temp2, 0, vertexCount); + vertex_order = temp2; + //System.out.println("allocating more vertices " + vertices.length); + } + float vertex[] = vertices[vertexCount]; + + // only do this if we're using an irregular (POLYGON) shape that + // will go through the triangulator. otherwise it'll do thinks like + // disappear in mathematically odd ways + // http://dev.processing.org/bugs/show_bug.cgi?id=444 + if (shape == POLYGON) { + if (vertexCount > 0) { + float pvertex[] = vertices[vertexCount-1]; + if ((abs(pvertex[MX] - x) < EPSILON) && + (abs(pvertex[MY] - y) < EPSILON) && + (abs(pvertex[MZ] - z) < EPSILON)) { + // this vertex is identical, don't add it, + // because it will anger the triangulator + return; + } + } + } + + // user called vertex(), so that invalidates anything queued + // up for curve vertices. if this is internally called by + // spline_segment, then splineVertexCount will be saved and restored. + splineVertexCount = 0; + + vertex[MX] = x; + vertex[MY] = y; + vertex[MZ] = z; + + if (fill) { + vertex[R] = fillR; + vertex[G] = fillG; + vertex[B] = fillB; + vertex[A] = fillA; + + vertex[AR] = ambientR; + vertex[AG] = ambientG; + vertex[AB] = ambientB; + + vertex[SPR] = specularR; + vertex[SPG] = specularG; + vertex[SPB] = specularB; + vertex[SPA] = specularA; + + vertex[SHINE] = shininess; + + vertex[ER] = emissiveR; + vertex[EG] = emissiveG; + vertex[EB] = emissiveB; + } + + if (stroke) { + vertex[SR] = strokeR; + vertex[SG] = strokeG; + vertex[SB] = strokeB; + vertex[SA] = strokeA; + vertex[SW] = strokeWeight; + } + + if (textureImage != null) { + vertex[U] = textureU; + vertex[V] = textureV; + } + + vertex[NX] = normalX; + vertex[NY] = normalY; + vertex[NZ] = normalZ; + + vertex[BEEN_LIT] = 0; + + vertexCount++; + } + + + /** + * See notes with the bezier() function. + */ + public void bezierVertex(float x2, float y2, + float x3, float y3, + float x4, float y4) { + bezierVertex(x2, y2, 0, x3, y3, 0, x4, y4, 0); + } + + + /** + * See notes with the bezier() function. + */ + public void bezierVertex(float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + if (splineVertexCount > 0) { + float vertex[] = splineVertices[splineVertexCount-1]; + splineVertex(vertex[MX], vertex[MY], vertex[MZ], true); + + } else if (vertexCount > 0) { + // make sure there's at least a call to vertex() + float vertex[] = vertices[vertexCount-1]; + splineVertex(vertex[MX], vertex[MY], vertex[MZ], true); + + } else { + throw new RuntimeException("A call to vertex() must be used " + + "before bezierVertex()"); + } + splineVertex(x2, y2, z2, true); + splineVertex(x3, y3, z3, true); + splineVertex(x4, y4, z4, true); + } + + + public void endShape(int mode) { + vertex_end = vertexCount; + vertex_end_including_clip_verts = vertex_end; + + // don't try to draw if there are no vertices + // (fixes a bug in LINE_LOOP that re-adds a nonexistent vertex) + if (vertexCount == 0) { + shape = 0; + return; + } + + + // ------------------------------------------------------------------ + // 2D or 3D POINTS FROM MODEL (MX, MY, MZ) TO CAMERA SPACE (VX, VY, VZ) + // It is necessary to do this now because we will be clipping them on + // add_triangle. + + for (int i = vertex_start; i < vertex_end; i++) { + float vertex[] = vertices[i]; + + vertex[VX] = + modelview.m00*vertex[MX] + modelview.m01*vertex[MY] + + modelview.m02*vertex[MZ] + modelview.m03; + vertex[VY] = + modelview.m10*vertex[MX] + modelview.m11*vertex[MY] + + modelview.m12*vertex[MZ] + modelview.m13; + vertex[VZ] = + modelview.m20*vertex[MX] + modelview.m21*vertex[MY] + + modelview.m22*vertex[MZ] + modelview.m23; + vertex[VW] = + modelview.m30*vertex[MX] + modelview.m31*vertex[MY] + + modelview.m32*vertex[MZ] + modelview.m33; + + // normalize + if (vertex[VW] != 0 && vertex[VW] != 1) { + vertex[VX] /= vertex[VW]; + vertex[VY] /= vertex[VW]; + vertex[VZ] /= vertex[VW]; + } + vertex[VW] = 1; + } + + // ------------------------------------------------------------------ + // CREATE LINES + + int increment = 1; + int stop = 0; + //int counter = 0; + + if (stroke) { + switch (shape) { + + case POINTS: + { + stop = vertex_end; + for (int i = vertex_start; i < stop; i++) { + add_path(); // total overkill for points + add_line(i, i); + } + } + break; + + case LINES: + //case LINE_STRIP: + //case LINE_LOOP: + { + // store index of first vertex + int first = lineCount; + stop = vertex_end - 1; + increment = (shape == LINES) ? 2 : 1; + + // for LINE_STRIP and LINE_LOOP, make this all one path + if (shape != LINES) add_path(); + + for (int i = vertex_start; i < stop; i+=increment) { + // for LINES, make a new path for each segment + if (shape == LINES) add_path(); + add_line(i, i+1); + } + + // for LINE_LOOP, close the loop with a final segment + //if (shape == LINE_LOOP) { + if (mode == CLOSE) { + add_line(stop, lines[first][VERTEX1]); + } + } + break; + + case TRIANGLES: + { + for (int i = vertex_start; i < vertex_end-2; i += 3) { + add_path(); + //counter = i - vertex_start; + add_line(i+0, i+1); + add_line(i+1, i+2); + add_line(i+2, i+0); + } + } + break; + + case TRIANGLE_STRIP: + { + // first draw all vertices as a line strip + stop = vertex_end-1; + + add_path(); + for (int i = vertex_start; i < stop; i++) { + //counter = i - vertex_start; + add_line(i,i+1); + } + + // then draw from vertex (n) to (n+2) + stop = vertex_end-2; + for (int i = vertex_start; i < stop; i++) { + add_path(); + add_line(i,i+2); + } + } + break; + + case TRIANGLE_FAN: + { + // this just draws a series of line segments + // from the center to each exterior point + for (int i = vertex_start + 1; i < vertex_end; i++) { + add_path(); + add_line(vertex_start, i); + } + + // then a single line loop around the outside. + add_path(); + for (int i = vertex_start + 1; i < vertex_end-1; i++) { + add_line(i, i+1); + } + // closing the loop + add_line(vertex_end-1, vertex_start + 1); + } + break; + + case QUADS: + { + for (int i = vertex_start; i < vertex_end; i += 4) { + add_path(); + //counter = i - vertex_start; + add_line(i+0, i+1); + add_line(i+1, i+2); + add_line(i+2, i+3); + add_line(i+3, i+0); + } + } + break; + + case QUAD_STRIP: + { + for (int i = vertex_start; i < vertex_end - 3; i += 2) { + add_path(); + add_line(i+0, i+2); + add_line(i+2, i+3); + add_line(i+3, i+1); + add_line(i+1, i+0); + } + /* + // first draw all vertices as a line strip + stop = vertex_end - 1; + + add_path(); + for (int i = vertex_start; i < stop; i++) { + counter = i - vertex_start; + add_line(i, i+1); + } + + // then draw from vertex (n) to (n+3) + stop = vertex_end-2; + increment = 2; + + add_path(); + for (int i = vertex_start; i < stop; i += increment) { + add_line(i, i+3); + } + */ + } + break; + + case POLYGON: + //case CONCAVE_POLYGON: + //case CONVEX_POLYGON: + { + // store index of first vertex + //int first = lineCount; + stop = vertex_end - 1; + + add_path(); + for (int i = vertex_start; i < stop; i++) { + add_line(i, i+1); + //System.out.println("adding line " + i); + } + if (mode == CLOSE) { + // draw the last line connecting back to the first point in poly + add_line(stop, vertex_start); //lines[first][VERTEX1]); + } + } + break; + } + } + + // ------------------------------------------------------------------ + // CREATE TRIANGLES + + if (fill) { + switch (shape) { + case TRIANGLE_FAN: + { + stop = vertex_end - 1; + for (int i = vertex_start + 1; i < stop; i++) { + add_triangle(vertex_start, i, i+1); + } + } + break; + + case TRIANGLES: + case TRIANGLE_STRIP: + { + stop = vertex_end - 2; + increment = (shape == TRIANGLES) ? 3 : 1; + for (int i = vertex_start; i < stop; i += increment) { + // have to switch between clockwise/counter-clockwise + // otherwise the feller is backwards and renderer won't draw + if ((i % 2) == 0) { + add_triangle(i, i+2, i+1); + } else { + add_triangle(i, i+1, i+2); + } + } + } + break; + + case QUADS: + { + stop = vertexCount-3; + for (int i = vertex_start; i < stop; i += 4) { + // first triangle + add_triangle(i, i+1, i+2); + // second triangle + add_triangle(i, i+2, i+3); + } + } + break; + + case QUAD_STRIP: + { + stop = vertexCount-3; + for (int i = vertex_start; i < stop; i += 2) { + // first triangle + add_triangle(i+0, i+2, i+1); + // second triangle + add_triangle(i+2, i+3, i+1); + } + } + break; + + case POLYGON: + //case CONCAVE_POLYGON: + //case CONVEX_POLYGON: + { + triangulate_polygon(); + } + break; + } + } + + + // ------------------------------------------------------------------ + // TRANSFORM / LIGHT / CLIP + + if (lightCount > 0 && fill) { + handle_lighting(); + } + else { + handle_no_lighting(); + } + + + + // ------------------------------------------------------------------ + // POINTS FROM CAMERA SPACE (VX, VY, VZ) TO SCREEN SPACE (X, Y, Z) + // this appears to be wasted time with the opengl renderer + + for (int i = vertex_start; i < vertex_end_including_clip_verts; i++) { + float vx[] = vertices[i]; + + float ox = + projection.m00*vx[VX] + projection.m01*vx[VY] + + projection.m02*vx[VZ] + projection.m03*vx[VW]; + float oy = + projection.m10*vx[VX] + projection.m11*vx[VY] + + projection.m12*vx[VZ] + projection.m13*vx[VW]; + float oz = + projection.m20*vx[VX] + projection.m21*vx[VY] + + projection.m22*vx[VZ] + projection.m23*vx[VW]; + float ow = + projection.m30*vx[VX] + projection.m31*vx[VY] + + projection.m32*vx[VZ] + projection.m33*vx[VW]; + + if (ow != 0 && ow != 1) { + ox /= ow; oy /= ow; oz /= ow; + } + + vx[X] = width * (1 + ox) / 2.0f; + vx[Y] = height * (1 + oy) / 2.0f; + vx[Z] = (oz + 1) / 2.0f; + } + + + // ------------------------------------------------------------------ + // RENDER SHAPES FILLS HERE WHEN NOT DEPTH SORTING + + // if true, the shapes will be rendered on endDraw + if (!hints[ENABLE_DEPTH_SORT]) { + if (fill) render_triangles(); + if (stroke) render_lines(); + } + + shape = 0; + } + + + protected final void add_path() { + if (pathCount == pathOffset.length) { + int temp1[] = new int[pathCount << 1]; + System.arraycopy(pathOffset, 0, temp1, 0, pathCount); + pathOffset = temp1; + int temp2[] = new int[pathCount << 1]; + System.arraycopy(pathLength, 0, temp2, 0, pathCount); + pathLength = temp2; + } + pathOffset[pathCount] = lineCount; + pathLength[pathCount] = 0; + pathCount++; + } + + + protected void add_line(int a, int b) { + add_line_with_clip(a, b); + } + + protected final void add_line_with_clip(int a, int b) { + float az = vertices[a][VZ]; + float bz = vertices[b][VZ]; + if (az > cameraNear) { + if (bz > cameraNear) { + return; + } + int cb = interpolate_clip_vertex(a, b); + add_line_no_clip(cb, b); + return; + } + else { + if (bz <= cameraNear) { + add_line_no_clip(a, b); + return; + } + int cb = interpolate_clip_vertex(a, b); + add_line_no_clip(a, cb); + return; + } + } + + protected final void add_line_no_clip(int a, int b) { + if (lineCount == lines.length) { + int temp[][] = new int[lineCount<<1][LINE_FIELD_COUNT]; + System.arraycopy(lines, 0, temp, 0, lineCount); + lines = temp; + //message(CHATTER, "allocating more lines " + lines.length); + } + lines[lineCount][VERTEX1] = a; + lines[lineCount][VERTEX2] = b; + lines[lineCount][INDEX] = -1; + + lines[lineCount][STROKE_MODE] = strokeCap | strokeJoin; + lines[lineCount][STROKE_WEIGHT] = (int) (strokeWeight + 0.5f); // hmm + lineCount++; + + // mark this piece as being part of the current path + pathLength[pathCount-1]++; + } + + + protected void add_triangle(int a, int b, int c) { + add_triangle_with_clip(a, b, c); + //add_triangle_no_clip(a, b, c); + } + + protected final void add_triangle_with_clip(int a, int b, int c) { + boolean aClipped = false; + boolean bClipped = false; + //boolean cClipped = false; + int clippedCount = 0; + + cameraNear = -8; + if (vertices[a][VZ] > cameraNear) { + aClipped = true; + clippedCount++; + } + if (vertices[b][VZ] > cameraNear) { + bClipped = true; + clippedCount++; + } + if (vertices[c][VZ] > cameraNear) { + //cClipped = true; + clippedCount++; + } + if (clippedCount == 0) { + add_triangle_no_clip(a, b, c); + return; + } + else if (clippedCount == 3) { + return; + } + // | . + // In this case there is only one visible point. |/| + // So we'll have to make two new points on the clip line <| | + // and add that triangle instead. |\| + // | . + else if (clippedCount == 2) { + //System.out.println("Clipped two"); + + int ca, cb, cc, cd, ce; + if (!aClipped) { + ca = a; + cb = b; + cc = c; + } + else if (!bClipped) { + ca = b; + cb = a; + cc = c; + } + else { //if (!cClipped) { + ca = c; + cb = b; + cc = a; + } + + cd = interpolate_clip_vertex(ca, cb); + ce = interpolate_clip_vertex(ca, cc); + add_triangle_no_clip(ca, cd, ce); + return; + } + + // . | + // In this case there are two visible points. |\| + // So we'll have to make two new points on the clip line | |> + // and then add two new triangles. |/| + // . | + else { // (clippedCount == 1) { + //System.out.println("Clipped one"); + int ca, cb, cc, cd, ce; + if (aClipped) { + //System.out.println("aClipped"); + ca = c; + cb = b; + cc = a; + } + else if (bClipped) { + //System.out.println("bClipped"); + ca = a; + cb = c; + cc = b; + } + else { //if (cClipped) { + //System.out.println("cClipped"); + ca = a; + cb = b; + cc = c; + } + + cd = interpolate_clip_vertex(ca, cc); + ce = interpolate_clip_vertex(cb, cc); + add_triangle_no_clip(ca, cd, cb); + //System.out.println("ca: " + ca + ", " + vertices[ca][VX] + ", " + vertices[ca][VY] + ", " + vertices[ca][VZ]); + //System.out.println("cd: " + cd + ", " + vertices[cd][VX] + ", " + vertices[cd][VY] + ", " + vertices[cd][VZ]); + //System.out.println("cb: " + cb + ", " + vertices[cb][VX] + ", " + vertices[cb][VY] + ", " + vertices[cb][VZ]); + add_triangle_no_clip(cb, cd, ce); + return; + } + } + + private final int interpolate_clip_vertex(int a, int b) { + float[] va; + float[] vb; + // Set up va, vb such that va[VZ] >= vb[VZ] + if (vertices[a][VZ] < vertices[b][VZ]) { + va = vertices[b]; + vb = vertices[a]; + } + else { + va = vertices[a]; + vb = vertices[b]; + } + float az = va[VZ]; + float bz = vb[VZ]; + + float dz = az - bz; + // If they have the same z, just use pt. a. + if (dz == 0) { + return a; + } + //float pa = (az - cameraNear) / dz; + //float pb = (cameraNear - bz) / dz; + float pa = (cameraNear - bz) / dz; + float pb = 1 - pa; + + vertex(pa * va[MX] + pb * vb[MX], + pa * va[MY] + pb * vb[MY], + pa * va[MZ] + pb * vb[MZ]); + int irv = vertexCount - 1; + vertex_end_including_clip_verts++; + float[] rv = vertices[irv]; + + rv[X] = pa * va[X] + pb * vb[X]; + rv[Y] = pa * va[Y] + pb * vb[Y]; + rv[Z] = pa * va[Z] + pb * vb[Z]; + + rv[VX] = pa * va[VX] + pb * vb[VX]; + rv[VY] = pa * va[VY] + pb * vb[VY]; + rv[VZ] = pa * va[VZ] + pb * vb[VZ]; + rv[VW] = pa * va[VW] + pb * vb[VW]; + + rv[R] = pa * va[R] + pb * vb[R]; + rv[G] = pa * va[G] + pb * vb[G]; + rv[B] = pa * va[B] + pb * vb[B]; + rv[A] = pa * va[A] + pb * vb[A]; + + rv[U] = pa * va[U] + pb * vb[U]; + rv[V] = pa * va[V] + pb * vb[V]; + + rv[SR] = pa * va[SR] + pb * vb[SR]; + rv[SG] = pa * va[SG] + pb * vb[SG]; + rv[SB] = pa * va[SB] + pb * vb[SB]; + rv[SA] = pa * va[SA] + pb * vb[SA]; + + rv[NX] = pa * va[NX] + pb * vb[NX]; + rv[NY] = pa * va[NY] + pb * vb[NY]; + rv[NZ] = pa * va[NZ] + pb * vb[NZ]; + + rv[SW] = pa * va[SW] + pb * vb[SW]; + + rv[AR] = pa * va[AR] + pb * vb[AR]; + rv[AG] = pa * va[AG] + pb * vb[AG]; + rv[AB] = pa * va[AB] + pb * vb[AB]; + + rv[SPR] = pa * va[SPR] + pb * vb[SPR]; + rv[SPG] = pa * va[SPG] + pb * vb[SPG]; + rv[SPB] = pa * va[SPB] + pb * vb[SPB]; + rv[SPA] = pa * va[SPA] + pb * vb[SPA]; + + rv[ER] = pa * va[ER] + pb * vb[ER]; + rv[EG] = pa * va[EG] + pb * vb[EG]; + rv[EB] = pa * va[EB] + pb * vb[EB]; + + rv[SHINE] = pa * va[SHINE] + pb * vb[SHINE]; + + rv[BEEN_LIT] = 0; + + return irv; + } + + + protected final void add_triangle_no_clip(int a, int b, int c) { + //System.out.println("adding triangle " + triangleCount); + if (triangleCount == triangles.length) { + int temp[][] = new int[triangleCount<<1][TRIANGLE_FIELD_COUNT]; + System.arraycopy(triangles, 0, temp, 0, triangleCount); + triangles = temp; + //message(CHATTER, "allocating more triangles " + triangles.length); + float ftemp[][][] = new float[triangleCount<<1][3][TRIANGLE_COLOR_COUNT]; + System.arraycopy(triangleColors, 0, ftemp, 0, triangleCount); + triangleColors = ftemp; + } + triangles[triangleCount][VERTEX1] = a; + triangles[triangleCount][VERTEX2] = b; + triangles[triangleCount][VERTEX3] = c; + + if (textureImage == null) { + triangles[triangleCount][TEXTURE_INDEX] = -1; + } else { + triangles[triangleCount][TEXTURE_INDEX] = texture_index; + } + + triangles[triangleCount][INDEX] = shape_index; + triangleCount++; + } + + + protected void depth_sort_triangles() { + //System.out.println("sorting " + triangleCount + " triangles"); + depth_sort_triangles_internal(0, triangleCount-1); + } + + + protected void depth_sort_triangles_internal(int i, int j) { + int pivotIndex = (i+j)/2; + depth_sort_triangles_swap(pivotIndex, j); + int k = depth_sort_triangles_partition(i-1, j); + depth_sort_triangles_swap(k, j); + if ((k-i) > 1) depth_sort_triangles_internal(i, k-1); + if ((j-k) > 1) depth_sort_triangles_internal(k+1, j); + } + + + protected int depth_sort_triangles_partition(int left, int right) { + int pivot = right; + do { + while (depth_sort_triangles_compare(++left, pivot) < 0) { } + while ((right != 0) && + (depth_sort_triangles_compare(--right, pivot) > 0)) { } + depth_sort_triangles_swap(left, right); + } while (left < right); + depth_sort_triangles_swap(left, right); + return left; + } + + + protected void depth_sort_triangles_swap(int a, int b) { + int tempi[] = triangles[a]; + triangles[a] = triangles[b]; + triangles[b] = tempi; + float tempf[][] = triangleColors[a]; + triangleColors[a] = triangleColors[b]; + triangleColors[b] = tempf; + } + + + protected float depth_sort_triangles_compare(int a, int b) { + if (Float.isNaN(vertices[triangles[a][VERTEX1]][Z]) || + Float.isNaN(vertices[triangles[a][VERTEX2]][Z]) || + Float.isNaN(vertices[triangles[a][VERTEX3]][Z]) || + Float.isNaN(vertices[triangles[b][VERTEX1]][Z]) || + Float.isNaN(vertices[triangles[b][VERTEX2]][Z]) || + Float.isNaN(vertices[triangles[b][VERTEX3]][Z])) { + throw new RuntimeException("nan triangle"); + } + return + (vertices[triangles[b][VERTEX1]][Z] + + vertices[triangles[b][VERTEX2]][Z] + + vertices[triangles[b][VERTEX3]][Z]) - + (vertices[triangles[a][VERTEX1]][Z] + + vertices[triangles[a][VERTEX2]][Z] + + vertices[triangles[a][VERTEX3]][Z]); + } + + + protected void render_triangles() { + //System.out.println("rendering " + triangleCount + " triangles"); + + if (raw != null) { + raw.colorMode(RGB, 1); + raw.noStroke(); + raw.beginShape(TRIANGLES); + } + + for (int i = 0; i < triangleCount; i ++) { + float a[] = vertices[triangles[i][VERTEX1]]; + float b[] = vertices[triangles[i][VERTEX2]]; + float c[] = vertices[triangles[i][VERTEX3]]; + int tex = triangles[i][TEXTURE_INDEX]; + int index = triangles[i][INDEX]; + + // ewjordan: hack to 'fix' accuracy issues when drawing in 2d + // see also render_lines() where similar hack is employed + float shift = 0.15f;//was 0.49f + boolean shifted = false; + if (drawing2D() && (a[MZ] == 0)) { + shifted = true; + a[X] += shift; + a[Y] += shift; + a[VX] += shift*a[VW]; + a[VY] += shift*a[VW]; + b[X] += shift; + b[Y] += shift; + b[VX] += shift*b[VW]; + b[VY] += shift*b[VW]; + c[X] += shift; + c[Y] += shift; + c[VX] += shift*c[VW]; + c[VY] += shift*c[VW]; + } + + triangle.reset(); + + // This is only true when not textured. We really should pass SPECULAR + // straight through to triangle rendering. + float ar = min(1, triangleColors[i][0][TRI_DIFFUSE_R] + + triangleColors[i][0][TRI_SPECULAR_R]); + float ag = min(1, triangleColors[i][0][TRI_DIFFUSE_G] + + triangleColors[i][0][TRI_SPECULAR_G]); + float ab = min(1, triangleColors[i][0][TRI_DIFFUSE_B] + + triangleColors[i][0][TRI_SPECULAR_B]); + float br = min(1, triangleColors[i][1][TRI_DIFFUSE_R] + + triangleColors[i][1][TRI_SPECULAR_R]); + float bg = min(1, triangleColors[i][1][TRI_DIFFUSE_G] + + triangleColors[i][1][TRI_SPECULAR_G]); + float bb = min(1, triangleColors[i][1][TRI_DIFFUSE_B] + + triangleColors[i][1][TRI_SPECULAR_B]); + float cr = min(1, triangleColors[i][2][TRI_DIFFUSE_R] + + triangleColors[i][2][TRI_SPECULAR_R]); + float cg = min(1, triangleColors[i][2][TRI_DIFFUSE_G] + + triangleColors[i][2][TRI_SPECULAR_G]); + float cb = min(1, triangleColors[i][2][TRI_DIFFUSE_B] + + triangleColors[i][2][TRI_SPECULAR_B]); + + if (tex > -1 && textures[tex] != null) { + triangle.setTexture(textures[tex]); + triangle.setUV(a[U], a[V], b[U], b[V], c[U], c[V]); + } + + triangle.setIntensities(ar, ag, ab, a[A], + br, bg, bb, b[A], + cr, cg, cb, c[A]); + + triangle.setVertices(a[X], a[Y], a[Z], + b[X], b[Y], b[Z], + c[X], c[Y], c[Z]); + + // Need to pass camera-space coordinates to triangle renderer + // in order to compute true texture coordinates, else skip it + if (hints[ENABLE_ACCURATE_TEXTURES]){ + triangle.setCamVertices(a[VX], a[VY], a[VZ], + b[VX], b[VY], b[VZ], + c[VX], c[VY], c[VZ]); + } + + triangle.setIndex(index); + triangle.render(); + + //System.out.println(i + " " + a[Z] + " " + b[Z] + " " + c[Z]); + + if (raw != null) { + if (raw instanceof PGraphics3D) { + if ((a[VW] != 0) && (b[VW] != 0) && (c[VW] != 0)) { + raw.fill(ar, ag, ab, a[A]); + raw.vertex(a[VX] / a[VW], a[VY] / a[VW], a[VZ] / a[VW]); + raw.fill(br, bg, bb, b[A]); + raw.vertex(b[VX] / b[VW], b[VY] / b[VW], b[VZ] / b[VW]); + raw.fill(cr, cg, cb, c[A]); + raw.vertex(c[VX] / c[VW], c[VY] / c[VW], c[VZ] / c[VW]); + } + } else { + raw.fill(ar, ag, ab, a[A]); + raw.vertex(a[X], a[Y]); + raw.fill(br, bg, bb, b[A]); + raw.vertex(b[X], b[Y]); + raw.fill(cr, cg, cb, c[A]); + raw.vertex(c[X], c[Y]); + } + } + + if (drawing2D() && shifted){ + a[X] -= shift; + a[Y] -= shift; + a[VX] -= shift*a[VW]; + a[VY] -= shift*a[VW]; + b[X] -= shift; + b[Y] -= shift; + b[VX] -= shift*b[VW]; + b[VY] -= shift*b[VW]; + c[X] -= shift; + c[Y] -= shift; + c[VX] -= shift*c[VW]; + c[VY] -= shift*c[VW]; + } + } + + if (raw != null) { + raw.endShape(); + } + } + + + protected void depth_sort_lines() { + } + + + protected void render_lines() { + if (raw != null) { + raw.colorMode(RGB, 1); + raw.noFill(); + raw.beginShape(LINES); + } + + for (int i = 0; i < lineCount; i ++) { + float a[] = vertices[lines[i][VERTEX1]]; + float b[] = vertices[lines[i][VERTEX2]]; + int index = lines[i][INDEX]; + + // 2D hack added by ewjordan 6/13/07 + // Offset coordinates by a little bit if drawing 2D graphics. + // http://dev.processing.org/bugs/show_bug.cgi?id=95 + + // This hack fixes a bug caused by numerical precision issues when + // applying the 3D transformations to coordinates in the screen plane + // that should actually not be altered under said transformations. + // It will not be applied if any transformations other than translations + // are active, nor should it apply in OpenGL mode (PGraphicsOpenGL + // overrides render_lines(), so this should be fine). + // This fix exposes a last-pixel bug in the lineClipCode() function + // of PLine.java, so that fix must remain in place if this one is used. + + // Note: the "true" fix for this bug is to change the pixel coverage + // model so that the threshold for display does not lie on an integer + // boundary. Search "diamond exit rule" for info the OpenGL approach. + + if (drawing2D() && a[MZ] == 0) { + a[X] += 0.01; + a[Y] += 0.01; + a[VX] += 0.01*a[VW]; + a[VY] += 0.01*a[VW]; + b[X] += 0.01; + b[Y] += 0.01; + b[VX] += 0.01*b[VW]; + b[VY] += 0.01*b[VW]; + } + // end 2d-hack + + line.reset(); + + line.setIntensities(a[SR], a[SG], a[SB], a[SA], + b[SR], b[SG], b[SB], b[SA]); + + line.setVertices(a[X], a[Y], a[Z], + b[X], b[Y], b[Z]); + + if (raw != null) { + if (raw instanceof PGraphics3D) { + if ((a[VW] != 0) && (b[VW] != 0)) { + raw.stroke(a[SR], a[SG], a[SB], a[SA]); + raw.vertex(a[VX] / a[VW], a[VY] / a[VW], a[VZ] / a[VW]); + raw.stroke(b[SR], b[SG], b[SB], b[SA]); + raw.vertex(b[VX] / b[VW], b[VY] / b[VW], b[VZ] / b[VW]); + } + } else { + raw.stroke(a[SR], a[SG], a[SB], a[SA]); + raw.vertex(a[X], a[Y]); + raw.stroke(b[SR], b[SG], b[SB], b[SA]); + raw.vertex(b[X], b[Y]); + } + } + + /* Seems okay to remove this because these vertices are not used again, but if problems arise, this needs to be uncommented + because the above change is destructive and may need to be undone before proceeding. + if (drawing2D() && a[MZ] == 0) { + a[X] -= 0.01; + a[Y] -= 0.01; + a[VX] -= 0.01*a[VW]; + a[VY] -= 0.01*a[VW]; + b[X] -= 0.01; + b[Y] -= 0.01; + b[VX] -= 0.01*b[VW]; + b[VY] -= 0.01*b[VW]; + }*/ + + line.setIndex(index); + line.draw(); + } + + if (raw != null) { + raw.endShape(); + } + } + + + /** + * Triangulate the current polygon. + *

    + * Simple ear clipping polygon triangulation adapted from code by + * John W. Ratcliff (jratcliff at verant.com). Presumably + * this + * bit of code from the web. + */ + private void triangulate_polygon() { + // this clipping algorithm only works in 2D, so in cases where a + // polygon is drawn perpendicular to the z-axis, the area will be zero, + // and triangulation will fail. as such, when the area calculates to + // zero, figure out whether x or y is empty, and calculate based on the + // two dimensions that actually contain information. + // http://dev.processing.org/bugs/show_bug.cgi?id=111 + int d1 = MX; + int d2 = MY; + // this brings up the nastier point that there may be cases where + // a polygon is irregular in space and will throw off the + // clockwise/counterclockwise calculation. for instance, if clockwise + // relative to x and z, but counter relative to y and z or something + // like that.. will wait to see if this is in fact a problem before + // hurting my head on the math. + + // first we check if the polygon goes clockwise or counterclockwise + float area = 0; + for (int p = vertex_end - 1, q = vertex_start; q < vertex_end; p = q++) { + area += (vertices[q][d1] * vertices[p][d2] - + vertices[p][d1] * vertices[q][d2]); + } + // rather than checking for the perpendicular case first, only do it + // when the area calculates to zero. checking for perpendicular would be + // a needless waste of time for the 99% case. + if (area == 0) { + // figure out which dimension is the perpendicular axis + boolean foundValidX = false; + boolean foundValidY = false; + + for (int i = vertex_start; i < vertex_end; i++) { + for (int j = i; j < vertex_end; j++){ + if ( vertices[i][MX] != vertices[j][MX] ) foundValidX = true; + if ( vertices[i][MY] != vertices[j][MY] ) foundValidY = true; + } + } + + if (foundValidX) { + //d1 = MX; // already the case + d2 = MZ; + } else if (foundValidY) { + // ermm.. which is the proper order for cw/ccw here? + d1 = MY; + d2 = MZ; + } else { + // screw it, this polygon is just f-ed up + return; + } + + // re-calculate the area, with what should be good values + for (int p = vertex_end - 1, q = vertex_start; q < vertex_end; p = q++) { + area += (vertices[q][d1] * vertices[p][d2] - + vertices[p][d1] * vertices[q][d2]); + } + } + + // don't allow polygons to come back and meet themselves, + // otherwise it will anger the triangulator + // http://dev.processing.org/bugs/show_bug.cgi?id=97 + float vfirst[] = vertices[vertex_start]; + float vlast[] = vertices[vertex_end-1]; + if ((abs(vfirst[MX] - vlast[MX]) < EPSILON) && + (abs(vfirst[MY] - vlast[MY]) < EPSILON) && + (abs(vfirst[MZ] - vlast[MZ]) < EPSILON)) { + vertex_end--; + } + + // then sort the vertices so they are always in a counterclockwise order + int j = 0; + if (area > 0) { + for (int i = vertex_start; i < vertex_end; i++) { + j = i - vertex_start; + vertex_order[j] = i; + } + } else { + for (int i = vertex_start; i < vertex_end; i++) { + j = i - vertex_start; + vertex_order[j] = (vertex_end - 1) - j; + } + } + + // remove vc-2 Vertices, creating 1 triangle every time + int vc = vertex_end - vertex_start; + int count = 2*vc; // complex polygon detection + + for (int m = 0, v = vc - 1; vc > 2; ) { + boolean snip = true; + + // if we start over again, is a complex polygon + if (0 >= (count--)) { + break; // triangulation failed + } + + // get 3 consecutive vertices + int u = v ; if (vc <= u) u = 0; // previous + v = u + 1; if (vc <= v) v = 0; // current + int w = v + 1; if (vc <= w) w = 0; // next + + // triangle A B C + float Ax = -vertices[vertex_order[u]][d1]; + float Ay = vertices[vertex_order[u]][d2]; + float Bx = -vertices[vertex_order[v]][d1]; + float By = vertices[vertex_order[v]][d2]; + float Cx = -vertices[vertex_order[w]][d1]; + float Cy = vertices[vertex_order[w]][d2]; + + // first we check if continues going ccw + if (EPSILON > (((Bx-Ax) * (Cy-Ay)) - ((By-Ay) * (Cx-Ax)))) { + continue; + } + + for (int p = 0; p < vc; p++) { + //float ax, ay, bx, by, cx, cy, apx, apy, bpx, bpy, cpx, cpy; + //float cCROSSap, bCROSScp, aCROSSbp; + + if( (p == u) || (p == v) || (p == w) ) { + continue; + } + + float Px = -vertices[vertex_order[p]][d1]; + float Py = vertices[vertex_order[p]][d2]; + + float ax = Cx - Bx; float ay = Cy - By; + float bx = Ax - Cx; float by = Ay - Cy; + float cx = Bx - Ax; float cy = By - Ay; + float apx = Px - Ax; float apy = Py - Ay; + float bpx = Px - Bx; float bpy = Py - By; + float cpx = Px - Cx; float cpy = Py - Cy; + + float aCROSSbp = ax * bpy - ay * bpx; + float cCROSSap = cx * apy - cy * apx; + float bCROSScp = bx * cpy - by * cpx; + + if ((aCROSSbp >= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)) { + snip = false; + } + } + + if (snip) { + add_triangle(vertex_order[u], vertex_order[v], vertex_order[w]); + + m++; + + // remove v from remaining polygon + for (int s = v, t = v + 1; t < vc; s++, t++) { + vertex_order[s] = vertex_order[t]; + } + vc--; + + // reset error detection counter + count = 2 * vc; + } + } + } + + + private void toWorldNormal(float nx, float ny, float nz, float[] out) { + out[0] = + modelviewInv.m00*nx + modelviewInv.m10*ny + + modelviewInv.m20*nz + modelviewInv.m30; + out[1] = + modelviewInv.m01*nx + modelviewInv.m11*ny + + modelviewInv.m21*nz + modelviewInv.m31; + out[2] = + modelviewInv.m02*nx + modelviewInv.m12*ny + + modelviewInv.m22*nz + modelviewInv.m32; + out[3] = + modelviewInv.m03*nx + modelviewInv.m13*ny + + modelviewInv.m23*nz + modelviewInv.m33; + + if (out[3] != 0 && out[3] != 1) { + // divide by perspective coordinate + out[0] /= out[3]; out[1] /= out[3]; out[2] /= out[3]; + } + out[3] = 1; + + float nlen = mag(out[0], out[1], out[2]); // normalize + if (nlen != 0 && nlen != 1) { + out[0] /= nlen; out[1] /= nlen; out[2] /= nlen; + } + } + + + private void calc_lighting_contribution(int vIndex, + float[] contribution) { + calc_lighting_contribution(vIndex, contribution, false); + } + + private void calc_lighting_contribution(int vIndex, + float[] contribution, + boolean normalIsWorld) { + float[] v = vertices[vIndex]; + + float sr = v[SPR]; + float sg = v[SPG]; + float sb = v[SPB]; + + float wx = v[VX]; + float wy = v[VY]; + float wz = v[VZ]; + float shine = v[SHINE]; + + float nx; + float ny; + float nz; + if (!normalIsWorld) { + toWorldNormal(v[NX], v[NY], v[NZ], worldNormal); + nx = worldNormal[X]; + ny = worldNormal[Y]; + nz = worldNormal[Z]; + } + else { + nx = v[NX]; + ny = v[NY]; + nz = v[NZ]; + } + + + // Since the camera space == world space, + // we can test for visibility by the dot product of + // the normal with the direction from pt. to eye. + float dir = dot(nx, ny, nz, -wx, -wy, -wz); + // If normal is away from camera, choose its opposite. + // If we add backface culling, this will be backfacing + // (but since this is per vertex, it's more complicated) + if (dir < 0) { + nx = -nx; + ny = -ny; + nz = -nz; + } + + // These two terms will sum the contributions from the various lights + contribution[LIGHT_AMBIENT_R] = 0; + contribution[LIGHT_AMBIENT_G] = 0; + contribution[LIGHT_AMBIENT_B] = 0; + + contribution[LIGHT_DIFFUSE_R] = 0; + contribution[LIGHT_DIFFUSE_G] = 0; + contribution[LIGHT_DIFFUSE_B] = 0; + + contribution[LIGHT_SPECULAR_R] = 0; + contribution[LIGHT_SPECULAR_G] = 0; + contribution[LIGHT_SPECULAR_B] = 0; + + // for (int i = 0; i < MAX_LIGHTS; i++) { + // if (!light[i]) continue; + for (int i = 0; i < lightCount; i++) { + + float denom = lightFalloffConstant[i]; + float spotTerm = 1; + + if (lightType[i] == AMBIENT) { + if (lightFalloffQuadratic[i] != 0 || lightFalloffLinear[i] != 0) { + // Falloff depends on distance + float distSq = mag(lightPosition[i][0] - wx, + lightPosition[i][1] - wy, + lightPosition[i][2] - wz); + denom += + lightFalloffQuadratic[i] * distSq + + lightFalloffLinear[i] * (float) sqrt(distSq); + } + if (denom == 0) denom = 1; + + contribution[LIGHT_AMBIENT_R] += lightDiffuse[i][0] / denom; + contribution[LIGHT_AMBIENT_G] += lightDiffuse[i][1] / denom; + contribution[LIGHT_AMBIENT_B] += lightDiffuse[i][2] / denom; + + } else { + // If not ambient, we must deal with direction + + // li is the vector from the vertex to the light + float lix, liy, liz; + float lightDir_dot_li = 0; + float n_dot_li = 0; + + if (lightType[i] == DIRECTIONAL) { + lix = -lightNormal[i][0]; + liy = -lightNormal[i][1]; + liz = -lightNormal[i][2]; + denom = 1; + n_dot_li = (nx * lix + ny * liy + nz * liz); + // If light is lighting the face away from the camera, ditch + if (n_dot_li <= 0) { + continue; + } + } else { // Point or spot light (must deal also with light location) + lix = lightPosition[i][0] - wx; + liy = lightPosition[i][1] - wy; + liz = lightPosition[i][2] - wz; + // normalize + float distSq = mag(lix, liy, liz); + if (distSq != 0) { + lix /= distSq; + liy /= distSq; + liz /= distSq; + } + n_dot_li = (nx * lix + ny * liy + nz * liz); + // If light is lighting the face away from the camera, ditch + if (n_dot_li <= 0) { + continue; + } + + if (lightType[i] == SPOT) { // Must deal with spot cone + lightDir_dot_li = + -(lightNormal[i][0] * lix + + lightNormal[i][1] * liy + + lightNormal[i][2] * liz); + // Outside of spot cone + if (lightDir_dot_li <= lightSpotAngleCos[i]) { + continue; + } + spotTerm = pow(lightDir_dot_li, lightSpotConcentration[i]); + } + + if (lightFalloffQuadratic[i] != 0 || lightFalloffLinear[i] != 0) { + // Falloff depends on distance + denom += + lightFalloffQuadratic[i] * distSq + + lightFalloffLinear[i] * (float) sqrt(distSq); + } + } + // Directional, point, or spot light: + + // We know n_dot_li > 0 from above "continues" + + if (denom == 0) + denom = 1; + float mul = n_dot_li * spotTerm / denom; + contribution[LIGHT_DIFFUSE_R] += lightDiffuse[i][0] * mul; + contribution[LIGHT_DIFFUSE_G] += lightDiffuse[i][1] * mul; + contribution[LIGHT_DIFFUSE_B] += lightDiffuse[i][2] * mul; + + // SPECULAR + + // If the material and light have a specular component. + if ((sr > 0 || sg > 0 || sb > 0) && + (lightSpecular[i][0] > 0 || + lightSpecular[i][1] > 0 || + lightSpecular[i][2] > 0)) { + + float vmag = mag(wx, wy, wz); + if (vmag != 0) { + wx /= vmag; + wy /= vmag; + wz /= vmag; + } + float sx = lix - wx; + float sy = liy - wy; + float sz = liz - wz; + vmag = mag(sx, sy, sz); + if (vmag != 0) { + sx /= vmag; + sy /= vmag; + sz /= vmag; + } + float s_dot_n = (sx * nx + sy * ny + sz * nz); + + if (s_dot_n > 0) { + s_dot_n = pow(s_dot_n, shine); + mul = s_dot_n * spotTerm / denom; + contribution[LIGHT_SPECULAR_R] += lightSpecular[i][0] * mul; + contribution[LIGHT_SPECULAR_G] += lightSpecular[i][1] * mul; + contribution[LIGHT_SPECULAR_B] += lightSpecular[i][2] * mul; + } + + } + } + } + /*target[toffset + 0] = min(1, er + dr * diffuse_r); + target[toffset + 1] = min(1, eg + dg * diffuse_g); + target[toffset + 2] = min(1, eb + db * diffuse_b); + + target[SPR] = min(1, sr * specular_r); + target[SPG] = min(1, sg * specular_g); + target[SPB] = min(1, sb * specular_b);*/ + return; + } + + + // Multiply the lighting contribution into the vertex's colors. + // Only do this when there is ONE lighting per vertex + // (MANUAL_VERTEX_NORMAL or SHAPE_NORMAL mode). + private void apply_lighting_contribution(int vIndex, float[] contribution) { + float[] v = vertices[vIndex]; + + v[R] = min(1, v[ER] + v[AR] * contribution[LIGHT_AMBIENT_R] + + v[DR] * contribution[LIGHT_DIFFUSE_R]); + v[G] = min(1, v[EG] + v[AG] * contribution[LIGHT_AMBIENT_G] + + v[DG] * contribution[LIGHT_DIFFUSE_G]); + v[B] = min(1, v[EB] + v[AB] * contribution[LIGHT_AMBIENT_B] + + v[DB] * contribution[LIGHT_DIFFUSE_B]); + v[A] = min(1, v[DA]); + + v[SPR] = min(1, v[SPR] * contribution[LIGHT_SPECULAR_R]); + v[SPG] = min(1, v[SPG] * contribution[LIGHT_SPECULAR_G]); + v[SPB] = min(1, v[SPB] * contribution[LIGHT_SPECULAR_B]); + v[SPA] = min(1, v[SPA]); + + v[BEEN_LIT] = 1; + } + + + private void light_vertex_always(int vIndex, float[] contribution) { + calc_lighting_contribution(vIndex, contribution); + apply_lighting_contribution(vIndex, contribution); + } + + + private void light_vertex_if_not_already_lit(int vIndex, + float[] contribution) { + if (vertices[vIndex][BEEN_LIT] == 0) { + light_vertex_always(vIndex, contribution); + } + } + + + private void copy_prelit_vertex_color_to_triangle(int triIndex, int vIndex, + int colorIndex) { + float[] triColor = triangleColors[triIndex][colorIndex]; + float[] v = vertices[vIndex]; + + triColor[TRI_DIFFUSE_R] = v[R]; + triColor[TRI_DIFFUSE_G] = v[G]; + triColor[TRI_DIFFUSE_B] = v[B]; + triColor[TRI_DIFFUSE_A] = v[A]; + triColor[TRI_SPECULAR_R] = v[SPR]; + triColor[TRI_SPECULAR_G] = v[SPG]; + triColor[TRI_SPECULAR_B] = v[SPB]; + triColor[TRI_SPECULAR_A] = v[SPA]; + } + + + private void copy_vertex_color_to_triangle(int triIndex, + int vIndex, int colorIndex, + float[] lightContribution) { + float[] triColor = triangleColors[triIndex][colorIndex]; + float[] v = vertices[vIndex]; + + triColor[TRI_DIFFUSE_R] = + min(1, v[ER] + v[AR] * lightContribution[LIGHT_AMBIENT_R] + + v[DR] * lightContribution[LIGHT_DIFFUSE_R]); + triColor[TRI_DIFFUSE_G] = + min(1, v[EG] + v[AG] * lightContribution[LIGHT_AMBIENT_G] + + v[DG] * lightContribution[LIGHT_DIFFUSE_G]); + triColor[TRI_DIFFUSE_B] = + min(1, v[EB] + v[AB] * lightContribution[LIGHT_AMBIENT_B] + + v[DB] * lightContribution[LIGHT_DIFFUSE_B]); + triColor[TRI_DIFFUSE_A] = min(1, v[DA]); + + triColor[TRI_SPECULAR_R] = + min(1, v[SPR] * lightContribution[LIGHT_SPECULAR_R]); + triColor[TRI_SPECULAR_G] = + min(1, v[SPG] * lightContribution[LIGHT_SPECULAR_G]); + triColor[TRI_SPECULAR_B] = + min(1, v[SPB] * lightContribution[LIGHT_SPECULAR_B]); + triColor[TRI_SPECULAR_A] = min(1, v[SPA]); + } + + + private void light_triangle(int triIndex, float[] lightContribution) { + int vIndex = triangles[triIndex][VERTEX1]; + copy_vertex_color_to_triangle(triIndex, vIndex, 0, lightContribution); + vIndex = triangles[triIndex][VERTEX2]; + copy_vertex_color_to_triangle(triIndex, vIndex, 1, lightContribution); + vIndex = triangles[triIndex][VERTEX3]; + copy_vertex_color_to_triangle(triIndex, vIndex, 2, lightContribution); + } + + + private void crossProduct(float[] u, float[] v, float[] out) { + out[0] = u[1]*v[2] - u[2]*v[1]; + out[1] = u[2]*v[0] - u[0]*v[2]; + out[2] = u[0]*v[1] - u[1]*v[0]; + } + + + private void light_triangle(int triIndex) { + int vIndex; + + // Handle lighting on, but no lights (in this case, just use emissive) + // This wont be used currently because lightCount == 0 is don't use + // lighting at all... So. OK. If that ever changes, use the below: + /* + if (lightCount == 0) { + vIndex = triangles[triIndex][VERTEX1]; + copy_emissive_vertex_color_to_triangle(triIndex, vIndex, 0); + vIndex = triangles[triIndex][VERTEX2]; + copy_emissive_vertex_color_to_triangle(triIndex, vIndex, 1); + vIndex = triangles[triIndex][VERTEX3]; + copy_emissive_vertex_color_to_triangle(triIndex, vIndex, 2); + return; + } + */ + + // In MANUAL_VERTEX_NORMAL mode, we have a specific normal + // for each vertex. In that case, we light any verts that + // haven't already been lit and copy their colors straight + // into the triangle. + if (normalMode == MANUAL_VERTEX_NORMAL) { + vIndex = triangles[triIndex][VERTEX1]; + light_vertex_if_not_already_lit(vIndex, tempLightingContribution); + copy_prelit_vertex_color_to_triangle(triIndex, vIndex, 0); + + vIndex = triangles[triIndex][VERTEX2]; + light_vertex_if_not_already_lit(vIndex, tempLightingContribution); + copy_prelit_vertex_color_to_triangle(triIndex, vIndex, 1); + + vIndex = triangles[triIndex][VERTEX3]; + light_vertex_if_not_already_lit(vIndex, tempLightingContribution); + copy_prelit_vertex_color_to_triangle(triIndex, vIndex, 2); + + } + + // If the lighting doesn't depend on the vertex position, do the + // following: We've already dealt with MANUAL_SHAPE_NORMAL mode before + // we got into this function, so here we only have to deal with + // AUTO_NORMAL mode. So we calculate the normal for this triangle, + // and use that for the lighting. + else if (!lightingDependsOnVertexPosition) { + vIndex = triangles[triIndex][VERTEX1]; + int vIndex2 = triangles[triIndex][VERTEX2]; + int vIndex3 = triangles[triIndex][VERTEX3]; + + /* + float[] dv1 = new float[] {vertices[vIndex2][VX] - vertices[vIndex][VX], + vertices[vIndex2][VY] - vertices[vIndex][VY], + vertices[vIndex2][VZ] - vertices[vIndex][VZ]}; + float[] dv2 = new float[] {vertices[vIndex3][VX] - vertices[vIndex][VX], + vertices[vIndex3][VY] - vertices[vIndex][VY], + vertices[vIndex3][VZ] - vertices[vIndex][VZ]}; + */ + dv1[0] = vertices[vIndex2][VX] - vertices[vIndex][VX]; + dv1[1] = vertices[vIndex2][VY] - vertices[vIndex][VY]; + dv1[2] = vertices[vIndex2][VZ] - vertices[vIndex][VZ]; + + dv2[0] = vertices[vIndex3][VX] - vertices[vIndex][VX]; + dv2[1] = vertices[vIndex3][VY] - vertices[vIndex][VY]; + dv2[2] = vertices[vIndex3][VZ] - vertices[vIndex][VZ]; + + //float[] norm = new float[3]; + crossProduct(dv1, dv2, norm); + float nMag = mag(norm[X], norm[Y], norm[Z]); + if (nMag != 0 && nMag != 1) { + norm[X] /= nMag; norm[Y] /= nMag; norm[Z] /= nMag; + } + vertices[vIndex][NX] = norm[X]; + vertices[vIndex][NY] = norm[Y]; + vertices[vIndex][NZ] = norm[Z]; + + // The true at the end says the normal is already in world coordinates + calc_lighting_contribution(vIndex, tempLightingContribution, true); + copy_vertex_color_to_triangle(triIndex, vIndex, 0, + tempLightingContribution); + copy_vertex_color_to_triangle(triIndex, vIndex2, 1, + tempLightingContribution); + copy_vertex_color_to_triangle(triIndex, vIndex3, 2, + tempLightingContribution); + } + + // If lighting is position-dependent + else { + if (normalMode == MANUAL_SHAPE_NORMAL) { + vIndex = triangles[triIndex][VERTEX1]; + vertices[vIndex][NX] = vertices[vertex_start][NX]; + vertices[vIndex][NY] = vertices[vertex_start][NY]; + vertices[vIndex][NZ] = vertices[vertex_start][NZ]; + calc_lighting_contribution(vIndex, tempLightingContribution); + copy_vertex_color_to_triangle(triIndex, vIndex, 0, + tempLightingContribution); + + vIndex = triangles[triIndex][VERTEX2]; + vertices[vIndex][NX] = vertices[vertex_start][NX]; + vertices[vIndex][NY] = vertices[vertex_start][NY]; + vertices[vIndex][NZ] = vertices[vertex_start][NZ]; + calc_lighting_contribution(vIndex, tempLightingContribution); + copy_vertex_color_to_triangle(triIndex, vIndex, 1, + tempLightingContribution); + + vIndex = triangles[triIndex][VERTEX3]; + vertices[vIndex][NX] = vertices[vertex_start][NX]; + vertices[vIndex][NY] = vertices[vertex_start][NY]; + vertices[vIndex][NZ] = vertices[vertex_start][NZ]; + calc_lighting_contribution(vIndex, tempLightingContribution); + copy_vertex_color_to_triangle(triIndex, vIndex, 2, + tempLightingContribution); + } + + // lighting mode is AUTO_NORMAL + else { + vIndex = triangles[triIndex][VERTEX1]; + int vIndex2 = triangles[triIndex][VERTEX2]; + int vIndex3 = triangles[triIndex][VERTEX3]; + /* + float[] dv1 = new float[] {vertices[vIndex2][VX] - vertices[vIndex][VX], + vertices[vIndex2][VY] - vertices[vIndex][VY], + vertices[vIndex2][VZ] - vertices[vIndex][VZ]}; + float[] dv2 = new float[] {vertices[vIndex3][VX] - vertices[vIndex][VX], + vertices[vIndex3][VY] - vertices[vIndex][VY], + vertices[vIndex3][VZ] - vertices[vIndex][VZ]}; + */ + dv1[0] = vertices[vIndex2][VX] - vertices[vIndex][VX]; + dv1[1] = vertices[vIndex2][VY] - vertices[vIndex][VY]; + dv1[2] = vertices[vIndex2][VZ] - vertices[vIndex][VZ]; + dv2[0] = vertices[vIndex3][VX] - vertices[vIndex][VX]; + dv2[1] = vertices[vIndex3][VY] - vertices[vIndex][VY]; + dv2[2] = vertices[vIndex3][VZ] - vertices[vIndex][VZ]; + + //float[] norm = new float[3]; + crossProduct(dv1, dv2, norm); + float nMag = mag(norm[X], norm[Y], norm[Z]); + if (nMag != 0 && nMag != 1) { + norm[X] /= nMag; norm[Y] /= nMag; norm[Z] /= nMag; + } + vertices[vIndex][NX] = norm[X]; + vertices[vIndex][NY] = norm[Y]; + vertices[vIndex][NZ] = norm[Z]; + // The true at the end says the normal is already in world coordinates + calc_lighting_contribution(vIndex, tempLightingContribution, true); + copy_vertex_color_to_triangle(triIndex, vIndex, 0, + tempLightingContribution); + + vertices[vIndex2][NX] = norm[X]; + vertices[vIndex2][NY] = norm[Y]; + vertices[vIndex2][NZ] = norm[Z]; + // The true at the end says the normal is already in world coordinates + calc_lighting_contribution(vIndex2, tempLightingContribution, true); + copy_vertex_color_to_triangle(triIndex, vIndex2, 1, + tempLightingContribution); + + vertices[vIndex3][NX] = norm[X]; + vertices[vIndex3][NY] = norm[Y]; + vertices[vIndex3][NZ] = norm[Z]; + // The true at the end says the normal is already in world coordinates + calc_lighting_contribution(vIndex3, tempLightingContribution, true); + copy_vertex_color_to_triangle(triIndex, vIndex3, 2, + tempLightingContribution); + } + } + } + + + protected void handle_lighting() { + + // If the lighting does not depend on vertex position and there is a single + // normal specified for this shape, go ahead and apply the same lighting + // contribution to every vertex in this shape (one lighting calc!) + if (!lightingDependsOnVertexPosition && normalMode == MANUAL_SHAPE_NORMAL) { + calc_lighting_contribution(vertex_start, tempLightingContribution); + for (int tri = 0; tri < triangleCount; tri++) { + light_triangle(tri, tempLightingContribution); + } + } + // Otherwise light each triangle individually... + else { + for (int tri = 0; tri < triangleCount; tri++) { + light_triangle(tri); + } + } + } + + + protected void handle_no_lighting() { + int vIndex; + for (int tri = 0; tri < triangleCount; tri++) { + vIndex = triangles[tri][VERTEX1]; + copy_prelit_vertex_color_to_triangle(tri, vIndex, 0); + vIndex = triangles[tri][VERTEX2]; + copy_prelit_vertex_color_to_triangle(tri, vIndex, 1); + vIndex = triangles[tri][VERTEX3]; + copy_prelit_vertex_color_to_triangle(tri, vIndex, 2); + } + } + + + + ////////////////////////////////////////////////////////////// + + // BASIC SHAPES + + + public void point(float x, float y) { + point(x, y, 0); + } + + + public void point(float x, float y, float z) { + /* + beginShape(POINTS); + vertex(x, y, z); + endShape(); + */ + + // hacked workaround for carlos line bug + beginShape(LINES); + vertex(x, y, z); + vertex(x + EPSILON, y + EPSILON, z); + endShape(); + } + + /* + private void point3(float x, float y, float z, int color) { + // need to get scaled version of the stroke + float x1 = screenX(x - 0.5f, y - 0.5f, z); + float y1 = screenY(x - 0.5f, y - 0.5f, z); + float x2 = screenX(x + 0.5f, y + 0.5f, z); + float y2 = screenY(x + 0.5f, y + 0.5f, z); + + float weight = (abs(x2 - x1) + abs(y2 - y1)) / 2f; + if (weight < 1.5f) { + int xx = (int) ((x1 + x2) / 2f); + int yy = (int) ((y1 + y2) / 2f); + //point0(xx, yy, z, color); + zbuffer[yy*width + xx] = screenZ(x, y, z); + //stencil? + + } else { + // actually has some weight, need to draw shapes instead + // these will be + } + } + */ + + + /** + * Compared to the implementation in PGraphics, this adds normal(). + */ + public void triangle(float x1, float y1, float x2, float y2, + float x3, float y3) { + beginShape(TRIANGLES); + normal(0, 0, 1); + vertex(x1, y1); + vertex(x2, y2); + vertex(x3, y3); + endShape(); + } + + + /** + * Compared to the implementation in PGraphics, this adds normal(). + */ + public void quad(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { + beginShape(QUADS); + normal(0, 0, 1); + vertex(x1, y1); + vertex(x2, y2); + vertex(x3, y3); + vertex(x4, y4); + endShape(); + } + + + + ////////////////////////////////////////////////////////////// + + // BOX + + + public void box(float size) { + box(size, size, size); + } + + + // OPT this isn't the least bit efficient + // because it redraws lines along the vertices + // ugly ugly ugly! + public void box(float w, float h, float d) { + float x1 = -w/2f; float x2 = w/2f; + float y1 = -h/2f; float y2 = h/2f; + float z1 = -d/2f; float z2 = d/2f; + + if (triangle != null) { // triangle is null in gl + triangle.setCulling(true); + } + + beginShape(QUADS); + + // front + normal(0, 0, 1); + vertex(x1, y1, z1); + vertex(x2, y1, z1); + vertex(x2, y2, z1); + vertex(x1, y2, z1); + + // right + normal(1, 0, 0); + vertex(x2, y1, z1); + vertex(x2, y1, z2); + vertex(x2, y2, z2); + vertex(x2, y2, z1); + + // back + normal(0, 0, -1); + vertex(x2, y1, z2); + vertex(x1, y1, z2); + vertex(x1, y2, z2); + vertex(x2, y2, z2); + + // left + normal(-1, 0, 0); + vertex(x1, y1, z2); + vertex(x1, y1, z1); + vertex(x1, y2, z1); + vertex(x1, y2, z2); + + // top + normal(0, 1, 0); + vertex(x1, y1, z2); + vertex(x2, y1, z2); + vertex(x2, y1, z1); + vertex(x1, y1, z1); + + // bottom + normal(0, -1, 0); + vertex(x1, y2, z1); + vertex(x2, y2, z1); + vertex(x2, y2, z2); + vertex(x1, y2, z2); + + endShape(); + + if (triangle != null) { // triangle is null in gl + triangle.setCulling(false); + } + } + + + + ////////////////////////////////////////////////////////////// + + // SPHERE + + + // [toxi031031] used by the new sphere code below + // precompute vertices along unit sphere with new detail setting + + public void sphereDetail(int res) { + if (res < 3) res = 3; // force a minimum res + if (res == sphereDetail) return; + + float delta = (float)SINCOS_LENGTH/res; + float[] cx = new float[res]; + float[] cz = new float[res]; + // calc unit circle in XZ plane + for (int i = 0; i < res; i++) { + cx[i] = cosLUT[(int) (i*delta) % SINCOS_LENGTH]; + cz[i] = sinLUT[(int) (i*delta) % SINCOS_LENGTH]; + } + // computing vertexlist + // vertexlist starts at south pole + int vertCount = res * (res-1) + 2; + int currVert = 0; + + // re-init arrays to store vertices + sphereX = new float[vertCount]; + sphereY = new float[vertCount]; + sphereZ = new float[vertCount]; + + float angle_step = (SINCOS_LENGTH*0.5f)/res; + float angle = angle_step; + + // step along Y axis + for (int i = 1; i < res; i++) { + float curradius = sinLUT[(int) angle % SINCOS_LENGTH]; + float currY = -cosLUT[(int) angle % SINCOS_LENGTH]; + for (int j = 0; j < res; j++) { + sphereX[currVert] = cx[j] * curradius; + sphereY[currVert] = currY; + sphereZ[currVert++] = cz[j] * curradius; + } + angle += angle_step; + } + sphereDetail = res; + } + + + /** + * Draw a sphere with radius r centered at coordinate 0, 0, 0. + *

    + * Implementation notes: + *

    + * cache all the points of the sphere in a static array + * top and bottom are just a bunch of triangles that land + * in the center point + *

    + * sphere is a series of concentric circles who radii vary + * along the shape, based on, er.. cos or something + *

    +   * [toxi031031] new sphere code. removed all multiplies with
    +   * radius, as scale() will take care of that anyway
    +   *
    +   * [toxi031223] updated sphere code (removed modulos)
    +   * and introduced sphereAt(x,y,z,r)
    +   * to avoid additional translate()'s on the user/sketch side
    +   * 
    + */ + public void sphere(float r) { + float x = 0; // TODO clean this back up again + float y = 0; + float z = 0; + + if (sphereDetail == 0) { + sphereDetail(30); + } + + int v1,v11,v2; + pushMatrix(); + if (x!=0f && y!=0f && z!=0f) translate(x,y,z); + scale(r); + + if (triangle != null) { // triangle is null in gl + triangle.setCulling(true); + } + + // 1st ring from south pole + beginShape(TRIANGLE_STRIP); + for (int i = 0; i < sphereDetail; i++) { + normal(0, -1, 0); + vertex(0, -1, 0); + normal(sphereX[i], sphereY[i], sphereZ[i]); + vertex(sphereX[i], sphereY[i], sphereZ[i]); + } + //normal(0, -1, 0); + vertex(0, -1, 0); + normal(sphereX[0], sphereY[0], sphereZ[0]); + vertex(sphereX[0], sphereY[0], sphereZ[0]); + endShape(); + + // middle rings + int voff = 0; + for(int i = 2; i < sphereDetail; i++) { + v1=v11=voff; + voff += sphereDetail; + v2=voff; + beginShape(TRIANGLE_STRIP); + for (int j = 0; j < sphereDetail; j++) { + normal(sphereX[v1], sphereY[v1], sphereZ[v1]); + vertex(sphereX[v1], sphereY[v1], sphereZ[v1++]); + normal(sphereX[v2], sphereY[v2], sphereZ[v2]); + vertex(sphereX[v2], sphereY[v2], sphereZ[v2++]); + } + // close each ring + v1=v11; + v2=voff; + normal(sphereX[v1], sphereY[v1], sphereZ[v1]); + vertex(sphereX[v1], sphereY[v1], sphereZ[v1]); + normal(sphereX[v2], sphereY[v2], sphereZ[v2]); + vertex(sphereX[v2], sphereY[v2], sphereZ[v2]); + endShape(); + } + + // add the northern cap + beginShape(TRIANGLE_STRIP); + for (int i = 0; i < sphereDetail; i++) { + v2 = voff + i; + normal(sphereX[v2], sphereY[v2], sphereZ[v2]); + vertex(sphereX[v2], sphereY[v2], sphereZ[v2]); + normal(0, 1, 0); + vertex(0, 1, 0); + } + normal(sphereX[voff], sphereY[voff], sphereZ[voff]); + vertex(sphereX[voff], sphereY[voff], sphereZ[voff]); + normal(0, 1, 0); + vertex(0, 1, 0); + endShape(); + popMatrix(); + + if (triangle != null) { // triangle is null in gl + triangle.setCulling(false); + } + } + + + + ////////////////////////////////////////////////////////////// + + // CURVES + + /* + + public void bezier(float x1, float y1, + float x2, float y2, + float x3, float y3, + float x4, float y4) { + bezier(x1, y1, 0, + x2, y2, 0, + x3, y3, 0, + x4, y4, 0); + } + + + public void bezier(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + beginShape(LINE_STRIP); + vertex(x1, y1, z1); + bezierVertex(x2, y2, z2, + x3, y3, z3, + x4, y4, z4); + endShape(); + } + + + public void curve(float x1, float y1, + float x2, float y2, + float x3, float y3, + float x4, float y4) { + curve(x1, y1, 0, + x2, y2, 0, + x3, y3, 0, + x4, y4, 0); + } + + + public void curve(float x1, float y1, float z1, + float x2, float y2, float z2, + float x3, float y3, float z3, + float x4, float y4, float z4) { + beginShape(LINE_STRIP); + curveVertex(x1, y1, z1); + curveVertex(x2, y2, z2); + curveVertex(x3, y3, z3); + curveVertex(x4, y4, z4); + endShape(); + } + + */ + + + + ////////////////////////////////////////////////////////////// + + // MATRIX TRANSFORMATIONS + + + public void translate(float tx, float ty) { + translate(tx, ty, 0); + } + + + public void translate(float tx, float ty, float tz) { + forwardTransform.translate(tx, ty, tz); + reverseTransform.invTranslate(tx, ty, tz); + } + + + /** + * Two dimensional rotation. Same as rotateZ (this is identical + * to a 3D rotation along the z-axis) but included for clarity -- + * it'd be weird for people drawing 2D graphics to be using rotateZ. + * And they might kick our a-- for the confusion. + */ + public void rotate(float angle) { + rotateZ(angle); + } + + + // OPT could save several multiplies for the 0s and 1s by just + // putting the multMatrix code here and removing uneccessary terms + + public void rotateX(float angle) { + forwardTransform.rotateX(angle); + reverseTransform.invRotateX(angle); + } + + + public void rotateY(float angle) { + forwardTransform.rotateY(angle); + reverseTransform.invRotateY(angle); + } + + + /** + * Rotate in the XY plane by an angle. + * + * Note that this doesn't internally set the number of + * dimensions to three, since rotateZ() is the same as a + * 2D rotate in the XY plane. + */ + public void rotateZ(float angle) { + forwardTransform.rotateZ(angle); + reverseTransform.invRotateZ(angle); + } + + + /** + * Rotate around an arbitrary vector, similar to glRotate(), + * except that it takes radians (instead of degrees). + */ + public void rotate(float angle, float v0, float v1, float v2) { + forwardTransform.rotate(angle, v0, v1, v2); + reverseTransform.invRotate(angle, v0, v1, v2); + } + + + /** + * Same as scale(s, s, s); + */ + public void scale(float s) { + scale(s, s, s); + } + + + /** + * Not recommended for use in 3D, because the z-dimension is just + * scaled by 1, since there's no way to know what else to scale it by. + * Equivalent to scale(sx, sy, 1); + */ + public void scale(float sx, float sy) { + scale(sx, sy, 1); + } + + + /** + * Scale in three dimensions. + */ + public void scale(float x, float y, float z) { + forwardTransform.scale(x, y, z); + reverseTransform.invScale(x, y, z); + } + + + + ////////////////////////////////////////////////////////////// + + // TRANSFORMATION MATRIX + + + public void pushMatrix() { + if (!modelview.push()) { + throw new RuntimeException("Too many calls to pushMatrix()"); + } + // Do this to the inverse regardless of the lights + // to keep stack pointers in sync + modelviewInv.push(); + } + + + public void popMatrix() { + if (!modelview.pop()) { + throw new RuntimeException("Too many calls to popMatrix() " + + "(and not enough to pushMatrix)"); + } + // Do this to the inverse regardless of the lights + // to keep stack pointers in sync + modelviewInv.pop(); + } + + + /** + * Load identity as the transform/model matrix. + * Same as glLoadIdentity(). + */ + public void resetMatrix() { + forwardTransform.reset(); + reverseTransform.reset(); + } + + + public void applyMatrix(float n00, float n01, float n02, + float n10, float n11, float n12) { + throw new RuntimeException("Use applyMatrix() with a 4x4 matrix " + + "when using OPENGL or P3D"); + } + + /** + * Apply a 4x4 transformation matrix. Same as glMultMatrix(). + * This call will be slow because it will try to calculate the + * inverse of the transform. So avoid it whenever possible. + */ + public void applyMatrix(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + + forwardTransform.apply(n00, n01, n02, n03, + n10, n11, n12, n13, + n20, n21, n22, n23, + n30, n31, n32, n33); + + reverseTransform.invApply(n00, n01, n02, n03, + n10, n11, n12, n13, + n20, n21, n22, n23, + n30, n31, n32, n33); + } + + + /** + * Load the modelview into m00, m01, et al so that it can be used. + */ + public void loadMatrix() { + m00 = modelview.m00; + m01 = modelview.m01; + m02 = modelview.m02; + m03 = modelview.m03; + + m10 = modelview.m10; + m11 = modelview.m11; + m12 = modelview.m12; + m13 = modelview.m13; + + m20 = modelview.m20; + m21 = modelview.m21; + m22 = modelview.m22; + m23 = modelview.m23; + + m30 = modelview.m30; + m31 = modelview.m31; + m32 = modelview.m32; + m33 = modelview.m33; + } + + + /** + * Print the current model (or "transformation") matrix. + */ + public void printMatrix() { + modelview.print(); + } + + + + ////////////////////////////////////////////////////////////// + + // CAMERA and PERSPECTIVE + + + /** + * Set matrix mode to the camera matrix (instead of the current + * transformation matrix). This means applyMatrix, resetMatrix, etc. + * will affect the camera. + *

    + * Note that the camera matrix is *not* the perspective matrix, + * it is in front of the modelview matrix (hence the name "model" + * and "view" for that matrix). + *

    + * beginCamera() specifies that all coordinate transforms until endCamera() + * should be pre-applied in inverse to the camera transform matrix. + * Note that this is only challenging when a user specifies an arbitrary + * matrix with applyMatrix(). Then that matrix will need to be inverted, + * which may not be possible. But take heart, if a user is applying a + * non-invertible matrix to the camera transform, then he is clearly + * up to no good, and we can wash our hands of those bad intentions. + *

    + * begin/endCamera clauses do not automatically reset the camera transform + * matrix. That's because we set up a nice default camera transform int + * setup(), and we expect it to hold through draw(). So we don't reset + * the camera transform matrix at the top of draw(). That means that an + * innocuous-looking clause like + *

    +   * beginCamera();
    +   * translate(0, 0, 10);
    +   * endCamera();
    +   * 
    + * at the top of draw(), will result in a runaway camera that shoots + * infinitely out of the screen over time. In order to prevent this, + * it is necessary to call some function that does a hard reset of the + * camera transform matrix inside of begin/endCamera. Two options are + *
    +   * camera(); // sets up the nice default camera transform
    +   * resetMatrix(); // sets up the identity camera transform
    +   * 
    + * So to rotate a camera a constant amount, you might try + *
    +   * beginCamera();
    +   * camera();
    +   * rotateY(PI/8);
    +   * endCamera();
    +   * 
    + */ + public void beginCamera() { + if (manipulatingCamera) { + throw new RuntimeException("beginCamera() cannot be called again " + + "before endCamera()"); + } else { + manipulatingCamera = true; + forwardTransform = cameraInv; + reverseTransform = camera; + } + } + + + /** + * Record the current settings into the camera matrix, and set + * the matrix mode back to the current transformation matrix. + *

    + * Note that this will destroy any settings to scale(), translate(), + * or whatever, because the final camera matrix will be copied + * (not multiplied) into the modelview. + */ + public void endCamera() { + if (!manipulatingCamera) { + throw new RuntimeException("Cannot call endCamera() " + + "without first calling beginCamera()"); + } + // reset the modelview to use this new camera matrix + modelview.set(camera); + modelviewInv.set(cameraInv); + + // set matrix mode back to modelview + forwardTransform = modelview; + reverseTransform = modelviewInv; + + // all done + manipulatingCamera = false; + } + + + /** + * Set camera to the default settings. + *

    + * Processing camera behavior: + *

    + * Camera behavior can be split into two separate components, camera + * transformation, and projection. The transformation corresponds to the + * physical location, orientation, and scale of the camera. In a physical + * camera metaphor, this is what can manipulated by handling the camera + * body (with the exception of scale, which doesn't really have a physcial + * analog). The projection corresponds to what can be changed by + * manipulating the lens. + *

    + * We maintain separate matrices to represent the camera transform and + * projection. An important distinction between the two is that the camera + * transform should be invertible, where the projection matrix should not, + * since it serves to map three dimensions to two. It is possible to bake + * the two matrices into a single one just by multiplying them together, + * but it isn't a good idea, since lighting, z-ordering, and z-buffering + * all demand a true camera z coordinate after modelview and camera + * transforms have been applied but before projection. If the camera + * transform and projection are combined there is no way to recover a + * good camera-space z-coordinate from a model coordinate. + *

    + * Fortunately, there are no functions that manipulate both camera + * transformation and projection. + *

    + * camera() sets the camera position, orientation, and center of the scene. + * It replaces the camera transform with a new one. This is different from + * gluLookAt(), but I think the only reason that GLU's lookat doesn't fully + * replace the camera matrix with the new one, but instead multiplies it, + * is that GL doesn't enforce the separation of camera transform and + * projection, so it wouldn't be safe (you'd probably stomp your projection). + *

    + * The transformation functions are the same ones used to manipulate the + * modelview matrix (scale, translate, rotate, etc.). But they are bracketed + * with beginCamera(), endCamera() to indicate that they should apply + * (in inverse), to the camera transformation matrix. + *

    + * This differs considerably from camera transformation in OpenGL. + * OpenGL only lets you say, apply everything from here out to the + * projection or modelview matrix. This makes it very hard to treat camera + * manipulation as if it were a physical camera. Imagine that you want to + * move your camera 100 units forward. In OpenGL, you need to apply the + * inverse of that transformation or else you'll move your scene 100 units + * forward--whether or not you've specified modelview or projection matrix. + * Remember they're just multiplied by model coods one after another. + * So in order to treat a camera like a physical camera, it is necessary + * to pre-apply inverse transforms to a matrix that will be applied to model + * coordinates. OpenGL provides nothing of this sort, but Processing does! + * This is the camera transform matrix. + */ + public void camera() { + camera(cameraX, cameraY, cameraZ, + cameraX, cameraY, 0, + 0, 1, 0); + } + + + /** + * More flexible method for dealing with camera(). + *

    + * The actual call is like gluLookat. Here's the real skinny on + * what does what: + *

    +   * camera(); or
    +   * camera(ex, ey, ez, cx, cy, cz, ux, uy, uz);
    +   * 
    + * do not need to be called from with beginCamera();/endCamera(); + * That's because they always apply to the camera transformation, + * and they always totally replace it. That means that any coordinate + * transforms done before camera(); in draw() will be wiped out. + * It also means that camera() always operates in untransformed world + * coordinates. Therefore it is always redundant to call resetMatrix(); + * before camera(); This isn't technically true of gluLookat, but it's + * pretty much how it's used. + *

    + * Now, beginCamera(); and endCamera(); are useful if you want to move + * the camera around using transforms like translate(), etc. They will + * wipe out any coordinate system transforms that occur before them in + * draw(), but they will not automatically wipe out the camera transform. + * This means that they should be at the top of draw(). It also means + * that the following: + *

    +   * beginCamera();
    +   * rotateY(PI/8);
    +   * endCamera();
    +   * 
    + * will result in a camera that spins without stopping. If you want to + * just rotate a small constant amount, try this: + *
    +   * beginCamera();
    +   * camera(); // sets up the default view
    +   * rotateY(PI/8);
    +   * endCamera();
    +   * 
    + * That will rotate a little off of the default view. Note that this + * is entirely equivalent to + *
    +   * camera(); // sets up the default view
    +   * beginCamera();
    +   * rotateY(PI/8);
    +   * endCamera();
    +   * 
    + * because camera() doesn't care whether or not it's inside a + * begin/end clause. Basically it's safe to use camera() or + * camera(ex, ey, ez, cx, cy, cz, ux, uy, uz) as naked calls because + * they do all the matrix resetting automatically. + */ + public void camera(float eyeX, float eyeY, float eyeZ, + float centerX, float centerY, float centerZ, + float upX, float upY, float upZ) { + float z0 = eyeX - centerX; + float z1 = eyeY - centerY; + float z2 = eyeZ - centerZ; + float mag = sqrt(z0*z0 + z1*z1 + z2*z2); + + if (mag != 0) { + z0 /= mag; + z1 /= mag; + z2 /= mag; + } + + float y0 = upX; + float y1 = upY; + float y2 = upZ; + + float x0 = y1*z2 - y2*z1; + float x1 = -y0*z2 + y2*z0; + float x2 = y0*z1 - y1*z0; + + y0 = z1*x2 - z2*x1; + y1 = -z0*x2 + z2*x0; + y2 = z0*x1 - z1*x0; + + mag = sqrt(x0*x0 + x1*x1 + x2*x2); + if (mag != 0) { + x0 /= mag; + x1 /= mag; + x2 /= mag; + } + + mag = sqrt(y0*y0 + y1*y1 + y2*y2); + if (mag != 0) { + y0 /= mag; + y1 /= mag; + y2 /= mag; + } + + // just does an apply to the main matrix, + // since that'll be copied out on endCamera + camera.set(x0, x1, x2, 0, + y0, y1, y2, 0, + z0, z1, z2, 0, + 0, 0, 0, 1); + camera.translate(-eyeX, -eyeY, -eyeZ); + + cameraInv.reset(); + cameraInv.invApply(x0, x1, x2, 0, + y0, y1, y2, 0, + z0, z1, z2, 0, + 0, 0, 0, 1); + cameraInv.invTranslate(-eyeX, -eyeY, -eyeZ); + + modelview.set(camera); + modelviewInv.set(cameraInv); + } + + + /** + * Print the current camera matrix. + */ + public void printCamera() { + camera.print(); + } + + + /** + * Calls ortho() with the proper parameters for Processing's + * standard orthographic projection. + */ + public void ortho() { + ortho(0, width, 0, height, -10, 10); + } + + + /** + * Similar to gluOrtho(), but wipes out the current projection matrix. + *

    + * Implementation partially based on Mesa's matrix.c. + */ + public void ortho(float left, float right, + float bottom, float top, + float near, float far) { + float x = 2.0f / (right - left); + float y = 2.0f / (top - bottom); + float z = -2.0f / (far - near); + + float tx = -(right + left) / (right - left); + float ty = -(top + bottom) / (top - bottom); + float tz = -(far + near) / (far - near); + + projection.set(x, 0, 0, tx, + 0, y, 0, ty, + 0, 0, z, tz, + 0, 0, 0, 1); + } + + + /** + * Calls perspective() with Processing's standard coordinate projection. + *

    + * Projection functions: + *

      + *
    • frustrum() + *
    • ortho() + *
    • perspective() + *
    + * Each of these three functions completely replaces the projection + * matrix with a new one. They can be called inside setup(), and their + * effects will be felt inside draw(). At the top of draw(), the projection + * matrix is not reset. Therefore the last projection function to be + * called always dominates. On resize, the default projection is always + * established, which has perspective. + *

    + * This behavior is pretty much familiar from OpenGL, except where + * functions replace matrices, rather than multiplying against the + * previous. + *

    + */ + public void perspective() { + perspective(cameraFOV, cameraAspect, cameraNear, cameraFar); + } + + + /** + * Similar to gluPerspective(). Implementation based on Mesa's glu.c + */ + public void perspective(float fov, float aspect, float zNear, float zFar) { + //float ymax = zNear * tan(fovy * PI / 360.0f); + float ymax = zNear * tan(fov / 2.0f); + float ymin = -ymax; + + float xmin = ymin * aspect; + float xmax = ymax * aspect; + + frustum(xmin, xmax, ymin, ymax, zNear, zFar); + } + + + /** + * Same as glFrustum(), except that it wipes out (rather than + * multiplies against) the current perspective matrix. + *

    + * Implementation based on the explanation in the OpenGL blue book. + */ + public void frustum(float left, float right, float bottom, + float top, float znear, float zfar) { + + //if (hints[ENABLE_ACCURATE_TEXTURES]){ + //These vars are only needed if accurate textures are used, however, + //there is the possibility that accurate texturing will only be turned + //on after the perspective matrix has already been set, so we might as + //well store these no matter what since it's not much overhead. + leftScreen = left; + rightScreen = right; + bottomScreen = bottom; + topScreen = top; + nearPlane = znear; + //} + + //System.out.println(projection); + projection.set((2*znear)/(right-left), 0, (right+left)/(right-left), 0, + 0, (2*znear)/(top-bottom), (top+bottom)/(top-bottom), 0, + 0, 0, -(zfar+znear)/(zfar-znear),-(2*zfar*znear)/(zfar-znear), + 0, 0, -1, 0); + } + + + /** + * Print the current projection matrix. + */ + public void printProjection() { + projection.print(); + } + + + /* + * This function checks if the modelview matrix is set up to likely be + * drawing in 2D. It merely checks if the non-translational piece of the + * matrix is unity. If this is to be used, it should be coupled with a + * check that the raw vertex coordinates lie in the z=0 plane. + * Mainly useful for applying sub-pixel shifts to avoid 2d artifacts + * in the screen plane. + * Added by ewjordan 6/13/07 + * + * TODO need to invert the logic here so that we can simply return + * the value, rather than calculating true/false and returning it. + */ + private boolean drawing2D() { + if (modelview.m00 != 1.0f || + modelview.m11 != 1.0f || + modelview.m22 != 1.0f || // check scale + modelview.m01 != 0.0f || + modelview.m02 != 0.0f || // check rotational pieces + modelview.m10 != 0.0f || + modelview.m12 != 0.0f || + modelview.m20 != 0.0f || + modelview.m21 != 0.0f || + !((camera.m23-modelview.m23) <= EPSILON && + (camera.m23-modelview.m23) >= -EPSILON)) { // check for z-translation + // Something about the modelview matrix indicates 3d drawing + // (or rotated 2d, in which case 2d subpixel fixes probably aren't needed) + return false; + } else { + //The matrix is mapping z=0 vertices to the screen plane, + // which means it's likely that 2D drawing is happening. + return true; + } + } + + + + ////////////////////////////////////////////////////////////// + + // SCREEN AND OBJECT COORDINATES + + + public float screenX(float x, float y) { + return screenX(x, y, 0); + } + + + public float screenY(float x, float y) { + return screenY(x, y, 0); + } + + + public float screenX(float x, float y, float z) { + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; + + float ox = + projection.m00*ax + projection.m01*ay + + projection.m02*az + projection.m03*aw; + float ow = + projection.m30*ax + projection.m31*ay + + projection.m32*az + projection.m33*aw; + + if (ow != 0) ox /= ow; + return width * (1 + ox) / 2.0f; + } + + + public float screenY(float x, float y, float z) { + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; + + float oy = + projection.m10*ax + projection.m11*ay + + projection.m12*az + projection.m13*aw; + float ow = + projection.m30*ax + projection.m31*ay + + projection.m32*az + projection.m33*aw; + + if (ow != 0) oy /= ow; + return height * (1 + oy) / 2.0f; + } + + + public float screenZ(float x, float y, float z) { + float ax = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + float ay = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + float az = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + float aw = + modelview.m30*x + modelview.m31*y + modelview.m32*z + modelview.m33; + + float oz = + projection.m20*ax + projection.m21*ay + + projection.m22*az + projection.m23*aw; + float ow = + projection.m30*ax + projection.m31*ay + + projection.m32*az + projection.m33*aw; + + if (ow != 0) oz /= ow; + return (oz + 1) / 2.0f; + } + + + public float modelX(float x, float y, float z) { + float ax = + cameraInv.m00*x + cameraInv.m01*y + cameraInv.m02*z + cameraInv.m03; + float ay = + cameraInv.m10*x + cameraInv.m11*y + cameraInv.m12*z + cameraInv.m13; + float az = + cameraInv.m20*x + cameraInv.m21*y + cameraInv.m22*z + cameraInv.m23; + float aw = + cameraInv.m30*x + cameraInv.m31*y + cameraInv.m32*z + cameraInv.m33; + + float ox = + modelview.m00*ax + modelview.m01*ay + + modelview.m02*az + modelview.m03*aw; + float ow = + modelview.m30*ax + modelview.m31*ay + + modelview.m32*az + modelview.m33*aw; + + return (ow != 0) ? ox / ow : ox; + } + + + public float modelY(float x, float y, float z) { + float ax = + cameraInv.m00*x + cameraInv.m01*y + cameraInv.m02*z + cameraInv.m03; + float ay = + cameraInv.m10*x + cameraInv.m11*y + cameraInv.m12*z + cameraInv.m13; + float az = + cameraInv.m20*x + cameraInv.m21*y + cameraInv.m22*z + cameraInv.m23; + float aw = + cameraInv.m30*x + cameraInv.m31*y + cameraInv.m32*z + cameraInv.m33; + + float oy = + modelview.m10*ax + modelview.m11*ay + + modelview.m12*az + modelview.m13*aw; + float ow = + modelview.m30*ax + modelview.m31*ay + + modelview.m32*az + modelview.m33*aw; + + return (ow != 0) ? oy / ow : oy; + } + + + public float modelZ(float x, float y, float z) { + float ax = + cameraInv.m00*x + cameraInv.m01*y + cameraInv.m02*z + cameraInv.m03; + float ay = + cameraInv.m10*x + cameraInv.m11*y + cameraInv.m12*z + cameraInv.m13; + float az = + cameraInv.m20*x + cameraInv.m21*y + cameraInv.m22*z + cameraInv.m23; + float aw = + cameraInv.m30*x + cameraInv.m31*y + cameraInv.m32*z + cameraInv.m33; + + float oz = + modelview.m20*ax + modelview.m21*ay + + modelview.m22*az + modelview.m23*aw; + float ow = + modelview.m30*ax + modelview.m31*ay + + modelview.m32*az + modelview.m33*aw; + + return (ow != 0) ? oz / ow : oz; + } + + + + ////////////////////////////////////////////////////////////// + + + // strokeWeight() doesn't really work properly either, + // but that will be dealt with in some other way. + + + public void strokeJoin(int join) { + String msg = "strokeJoin() not available with P3D"; + throw new RuntimeException(msg); + } + + + public void strokeCap(int cap) { + String msg = "strokeCap() not available with P3D"; + throw new RuntimeException(msg); + } + + + + ////////////////////////////////////////////////////////////// + + + protected void fillFromCalc() { + super.fillFromCalc(); + ambientFromCalc(); + } + + + ////////////////////////////////////////////////////////////// + + + public void ambient(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + ambient((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + ambientFromCalc(); + } + } + + + public void ambient(float gray) { + colorCalc(gray); + ambientFromCalc(); + } + + + public void ambient(float x, float y, float z) { + colorCalc(x, y, z); + ambientFromCalc(); + } + + + protected void ambientFromCalc() { + ambientR = calcR; + ambientG = calcG; + ambientB = calcB; + } + + + ////////////////////////////////////////////////////////////// + + + public void specular(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + specular((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + specularFromCalc(); + } + } + + + public void specular(float gray) { + colorCalc(gray); + specularFromCalc(); + } + + + public void specular(float gray, float alpha) { + colorCalc(gray, alpha); + specularFromCalc(); + } + + + public void specular(float x, float y, float z) { + colorCalc(x, y, z); + specularFromCalc(); + } + + + public void specular(float x, float y, float z, float a) { + colorCalc(x, y, z, a); + specularFromCalc(); + } + + + protected void specularFromCalc() { + specularR = calcR; + specularG = calcG; + specularB = calcB; + specularA = calcA; + //specularRi = calcRi; + //specularGi = calcGi; + //specularBi = calcBi; + //specularAi = calcAi; + } + + + public void shininess(float shine) { + shininess = shine; + } + + + ////////////////////////////////////////////////////////////// + + + public void emissive(int rgb) { + if (((rgb & 0xff000000) == 0) && (rgb <= colorModeX)) { // see above + emissive((float) rgb); + + } else { + colorCalcARGB(rgb, colorModeA); + emissiveFromCalc(); + } + } + + + public void emissive(float gray) { + colorCalc(gray); + emissiveFromCalc(); + } + + + public void emissive(float x, float y, float z) { + colorCalc(x, y, z); + emissiveFromCalc(); + } + + + protected void emissiveFromCalc() { + emissiveR = calcR; + emissiveG = calcG; + emissiveB = calcB; + //emissiveRi = calcRi; + //emissiveGi = calcGi; + //emissiveBi = calcBi; + } + + + ////////////////////////////////////////////////////////////// + + + /** + * Sets up an ambient and directional light. + *

    +   * The Lighting Skinny:
    +   *
    +   * The way lighting works is complicated enough that it's worth
    +   * producing a document to describe it. Lighting calculations proceed
    +   * pretty much exactly as described in the OpenGL red book.
    +   *
    +   * Light-affecting material properties:
    +   *
    +   *   AMBIENT COLOR
    +   *   - multiplies by light's ambient component
    +   *   - for believability this should match diffuse color
    +   *
    +   *   DIFFUSE COLOR
    +   *   - multiplies by light's diffuse component
    +   *
    +   *   SPECULAR COLOR
    +   *   - multiplies by light's specular component
    +   *   - usually less colored than diffuse/ambient
    +   *
    +   *   SHININESS
    +   *   - the concentration of specular effect
    +   *   - this should be set pretty high (20-50) to see really
    +   *     noticeable specularity
    +   *
    +   *   EMISSIVE COLOR
    +   *   - constant additive color effect
    +   *
    +   * Light types:
    +   *
    +   *   AMBIENT
    +   *   - one color
    +   *   - no specular color
    +   *   - no direction
    +   *   - may have falloff (constant, linear, and quadratic)
    +   *   - may have position (which matters in non-constant falloff case)
    +   *   - multiplies by a material's ambient reflection
    +   *
    +   *   DIRECTIONAL
    +   *   - has diffuse color
    +   *   - has specular color
    +   *   - has direction
    +   *   - no position
    +   *   - no falloff
    +   *   - multiplies by a material's diffuse and specular reflections
    +   *
    +   *   POINT
    +   *   - has diffuse color
    +   *   - has specular color
    +   *   - has position
    +   *   - no direction
    +   *   - may have falloff (constant, linear, and quadratic)
    +   *   - multiplies by a material's diffuse and specular reflections
    +   *
    +   *   SPOT
    +   *   - has diffuse color
    +   *   - has specular color
    +   *   - has position
    +   *   - has direction
    +   *   - has cone angle (set to half the total cone angle)
    +   *   - has concentration value
    +   *   - may have falloff (constant, linear, and quadratic)
    +   *   - multiplies by a material's diffuse and specular reflections
    +   *
    +   * Normal modes:
    +   *
    +   * All of the primitives (rect, box, sphere, etc.) have their normals
    +   * set nicely. During beginShape/endShape normals can be set by the user.
    +   *
    +   *   AUTO-NORMAL
    +   *   - if no normal is set during the shape, we are in auto-normal mode
    +   *   - auto-normal calculates one normal per triangle (face-normal mode)
    +   *
    +   *   SHAPE-NORMAL
    +   *   - if one normal is set during the shape, it will be used for
    +   *     all vertices
    +   *
    +   *   VERTEX-NORMAL
    +   *   - if multiple normals are set, each normal applies to
    +   *     subsequent vertices
    +   *   - (except for the first one, which applies to previous
    +   *     and subsequent vertices)
    +   *
    +   * Efficiency consequences:
    +   *
    +   *   There is a major efficiency consequence of position-dependent
    +   *   lighting calculations per vertex. (See below for determining
    +   *   whether lighting is vertex position-dependent.) If there is no
    +   *   position dependency then the only factors that affect the lighting
    +   *   contribution per vertex are its colors and its normal.
    +   *   There is a major efficiency win if
    +   *
    +   *   1) lighting is not position dependent
    +   *   2) we are in AUTO-NORMAL or SHAPE-NORMAL mode
    +   *
    +   *   because then we can calculate one lighting contribution per shape
    +   *   (SHAPE-NORMAL) or per triangle (AUTO-NORMAL) and simply multiply it
    +   *   into the vertex colors. The converse is our worst-case performance when
    +   *
    +   *   1) lighting is position dependent
    +   *   2) we are in AUTO-NORMAL mode
    +   *
    +   *   because then we must calculate lighting per-face * per-vertex.
    +   *   Each vertex has a different lighting contribution per face in
    +   *   which it appears. Yuck.
    +   *
    +   * Determining vertex position dependency:
    +   *
    +   *   If any of the following factors are TRUE then lighting is
    +   *   vertex position dependent:
    +   *
    +   *   1) Any lights uses non-constant falloff
    +   *   2) There are any point or spot lights
    +   *   3) There is a light with specular color AND there is a
    +   *      material with specular color
    +   *
    +   * So worth noting is that default lighting (a no-falloff ambient
    +   * and a directional without specularity) is not position-dependent.
    +   * We should capitalize.
    +   *
    +   * Simon Greenwold, April 2005
    +   * 
    + */ + public void lights() { + // need to make sure colorMode is RGB 255 here + int colorModeSaved = colorMode; + colorMode = RGB; + + lightFalloff(1, 0, 0); + lightSpecular(0, 0, 0); + + ambientLight(colorModeX * 0.5f, + colorModeY * 0.5f, + colorModeZ * 0.5f); + directionalLight(colorModeX * 0.5f, + colorModeY * 0.5f, + colorModeZ * 0.5f, + 0, 0, -1); + + colorMode = colorModeSaved; + + lightingDependsOnVertexPosition = false; + } + + + /** + * Add an ambient light based on the current color mode. + */ + public void ambientLight(float r, float g, float b) { + ambientLight(r, g, b, 0, 0, 0); + } + + + /** + * Add an ambient light based on the current color mode. + * This version includes an (x, y, z) position for situations + * where the falloff distance is used. + */ + public void ambientLight(float r, float g, float b, + float x, float y, float z) { + if (lightCount == MAX_LIGHTS) { + throw new RuntimeException("can only create " + MAX_LIGHTS + " lights"); + } + colorCalc(r, g, b); + lightDiffuse[lightCount][0] = calcR; + lightDiffuse[lightCount][1] = calcG; + lightDiffuse[lightCount][2] = calcB; + + lightType[lightCount] = AMBIENT; + lightFalloffConstant[lightCount] = currentLightFalloffConstant; + lightFalloffLinear[lightCount] = currentLightFalloffLinear; + lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; + lightPosition(lightCount, x, y, z); + lightCount++; + //return lightCount-1; + } + + + public void directionalLight(float r, float g, float b, + float nx, float ny, float nz) { + if (lightCount == MAX_LIGHTS) { + throw new RuntimeException("can only create " + MAX_LIGHTS + " lights"); + } + colorCalc(r, g, b); + lightDiffuse[lightCount][0] = calcR; + lightDiffuse[lightCount][1] = calcG; + lightDiffuse[lightCount][2] = calcB; + + lightType[lightCount] = DIRECTIONAL; + lightFalloffConstant[lightCount] = currentLightFalloffConstant; + lightFalloffLinear[lightCount] = currentLightFalloffLinear; + lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; + lightSpecular[lightCount][0] = currentLightSpecular[0]; + lightSpecular[lightCount][1] = currentLightSpecular[1]; + lightSpecular[lightCount][2] = currentLightSpecular[2]; + lightDirection(lightCount, nx, ny, nz); + lightCount++; + } + + + public void pointLight(float r, float g, float b, + float x, float y, float z) { + if (lightCount == MAX_LIGHTS) { + throw new RuntimeException("can only create " + MAX_LIGHTS + " lights"); + } + colorCalc(r, g, b); + lightDiffuse[lightCount][0] = calcR; + lightDiffuse[lightCount][1] = calcG; + lightDiffuse[lightCount][2] = calcB; + + lightType[lightCount] = POINT; + lightFalloffConstant[lightCount] = currentLightFalloffConstant; + lightFalloffLinear[lightCount] = currentLightFalloffLinear; + lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; + lightSpecular[lightCount][0] = currentLightSpecular[0]; + lightSpecular[lightCount][1] = currentLightSpecular[1]; + lightSpecular[lightCount][2] = currentLightSpecular[2]; + lightPosition(lightCount, x, y, z); + lightCount++; + + lightingDependsOnVertexPosition = true; + } + + + public void spotLight(float r, float g, float b, + float x, float y, float z, + float nx, float ny, float nz, + float angle, float concentration) { + if (lightCount == MAX_LIGHTS) { + throw new RuntimeException("can only create " + MAX_LIGHTS + " lights"); + } + colorCalc(r, g, b); + lightDiffuse[lightCount][0] = calcR; + lightDiffuse[lightCount][1] = calcG; + lightDiffuse[lightCount][2] = calcB; + + lightType[lightCount] = SPOT; + lightFalloffConstant[lightCount] = currentLightFalloffConstant; + lightFalloffLinear[lightCount] = currentLightFalloffLinear; + lightFalloffQuadratic[lightCount] = currentLightFalloffQuadratic; + lightSpecular[lightCount][0] = currentLightSpecular[0]; + lightSpecular[lightCount][1] = currentLightSpecular[1]; + lightSpecular[lightCount][2] = currentLightSpecular[2]; + lightPosition(lightCount, x, y, z); + lightDirection(lightCount, nx, ny, nz); + lightSpotAngle[lightCount] = angle; + lightSpotAngleCos[lightCount] = max(0, cos(angle)); + lightSpotConcentration[lightCount] = concentration; + lightCount++; + + lightingDependsOnVertexPosition = true; + } + + + /** + * Set the light falloff rates for the last light that was created. + * Default is lightFalloff(1, 0, 0). + */ + public void lightFalloff(float constant, float linear, float quadratic) { + currentLightFalloffConstant = constant; + currentLightFalloffLinear = linear; + currentLightFalloffQuadratic = quadratic; + + lightingDependsOnVertexPosition = true; + } + + + /** + * Set the specular color of the last light created. + */ + public void lightSpecular(float x, float y, float z) { + colorCalc(x, y, z); + currentLightSpecular[0] = calcR; + currentLightSpecular[1] = calcG; + currentLightSpecular[2] = calcB; + + lightingDependsOnVertexPosition = true; + } + + + /** + * internal function to set the light position + * based on the current modelview matrix. + */ + protected void lightPosition(int num, float x, float y, float z) { + lightPosition[num][0] = + modelview.m00*x + modelview.m01*y + modelview.m02*z + modelview.m03; + lightPosition[num][1] = + modelview.m10*x + modelview.m11*y + modelview.m12*z + modelview.m13; + lightPosition[num][2] = + modelview.m20*x + modelview.m21*y + modelview.m22*z + modelview.m23; + } + + + /** + * internal function to set the light direction + * based on the current modelview matrix. + */ + protected void lightDirection(int num, float x, float y, float z) { + // Multiply by inverse transpose. + lightNormal[num][0] = + modelviewInv.m00*x + modelviewInv.m10*y + + modelviewInv.m20*z + modelviewInv.m30; + lightNormal[num][1] = + modelviewInv.m01*x + modelviewInv.m11*y + + modelviewInv.m21*z + modelviewInv.m31; + lightNormal[num][2] = + modelviewInv.m02*x + modelviewInv.m12*y + + modelviewInv.m22*z + modelviewInv.m32; + + float n = mag(lightNormal[num]); + if (n == 0 || n == 1) return; + + lightNormal[num][0] /= n; + lightNormal[num][1] /= n; + lightNormal[num][2] /= n; + } + + + + ////////////////////////////////////////////////////////////// + + // BACKGROUND + + + /** + * Takes an RGB or RGBA image and sets it as the background. + *

    + * Note that even if the image is set as RGB, the high 8 bits of + * each pixel must be set (0xFF000000), because the image data will + * be copied directly to the screen. + *

    + * Also clears out the zbuffer and stencil buffer if they exist. + */ + public void background(PImage image) { + super.background(image); + + for (int i = 0; i < pixelCount; i++) { + zbuffer[i] = Float.MAX_VALUE; + //stencil[i] = 0; + } + } + + + /** + * Clear pixel buffer. With P3D and OPENGL, this also clears the zbuffer. + * Stencil buffer should also be cleared, but for now is ignored in P3D. + */ + protected void clear() { + //System.out.println("PGraphics3.clear(" + + // PApplet.hex(backgroundColor) + ")"); + for (int i = 0; i < pixelCount; i++) { + pixels[i] = backgroundColor; + zbuffer[i] = Float.MAX_VALUE; + //stencil[i] = 0; + } + } + + + + ////////////////////////////////////////////////////////////// + + // SMOOTH (not available, throws error) + + // although should this bother throwing an error? + // could be a pain in the ass when trying to debug with opengl + + + public void smooth() { + String msg = "smooth() not available with P3D"; + throw new RuntimeException(msg); + } + + + public void noSmooth() { + String msg = "noSmooth() not available with P3D"; + throw new RuntimeException(msg); + } + + + + ////////////////////////////////////////////////////////////// + + // MATH (internal use only) + + + /* + private final float mag(float a, float b) { + return (float)Math.sqrt(a*a + b*b); + } + */ + + private final float mag(float a, float b, float c) { + return (float)Math.sqrt(a*a + b*b + c*c); + } + + private final float mag(float abc[]) { + return (float)Math.sqrt(abc[0]*abc[0] + abc[1]*abc[1] + abc[2]*abc[2]); + } + + private final float min(float a, float b) { + return (a < b) ? a : b; + } + + private final float max(float a, float b) { + return (a > b) ? a : b; + } + + /* + private final float max(float a, float b, float c) { + return Math.max(a, Math.max(b, c)); + } + + private final float sq(float a) { + return a*a; + } + */ + + private final float pow(float a, float b) { + return (float)Math.pow(a, b); + } + + private final float abs(float a) { + return (a < 0) ? -a : a; + } + + /* + private final float sin(float angle) { + return (float)Math.sin(angle); + } + */ + + private final float cos(float angle) { + return (float)Math.cos(angle); + } + + private final float tan(float angle) { + return (float)Math.tan(angle); + } + + private float dot(float ax, float ay, float az, + float bx, float by, float bz) { + return ax * bx + ay * by + az * bz; + } +} + diff --git a/core/PGraphicsJava2D.java b/core/PGraphicsJava2D.java new file mode 100644 index 000000000..5766addce --- /dev/null +++ b/core/PGraphicsJava2D.java @@ -0,0 +1,1381 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2005-06 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.*; +import java.awt.geom.*; +import java.awt.image.*; + + +/** + * Subclass for PGraphics that implements the graphics API + * in Java 1.3+ using Java 2D. + * + *

    Pixel operations too slow? As of release 0085 (the first beta), + * the default renderer uses Java2D. It's more accurate than the renderer + * used in alpha releases of Processing (it handles stroke caps and joins, + * and has better polygon tessellation), but it's super slow for handling + * pixels. At least until we get a chance to get the old 2D renderer + * (now called P2D) working in a similar fashion, you can use + * size(w, h, P3D) instead of size(w, h) which will + * be faster for general pixel flipping madness.

    + * + *

    To get access to the Java 2D "Graphics2D" object for the default + * renderer, use: + *

    Graphics2D g2 = ((PGraphicsJava2D)g).g2;
    + * This will let you do Java 2D stuff directly, but is not supported in + * any way shape or form. Which just means "have fun, but don't complain + * if it breaks."

    + */ +public class PGraphicsJava2D extends PGraphics { + + public Graphics2D g2; + GeneralPath gpath; + + int transformCount; + AffineTransform transformStack[] = + new AffineTransform[MATRIX_STACK_DEPTH]; + double transform[] = new double[6]; + + Line2D.Float line = new Line2D.Float(); + Ellipse2D.Float ellipse = new Ellipse2D.Float(); + Rectangle2D.Float rect = new Rectangle2D.Float(); + Arc2D.Float arc = new Arc2D.Float(); + + protected Color tintColorObject; + + protected Color fillColorObject; + public boolean fillGradient; + public Paint fillGradientObject; + + protected Color strokeColorObject; + public boolean strokeGradient; + public Paint strokeGradientObject; + + + + ////////////////////////////////////////////////////////////// + + // INTERNAL + + + /** + * Constructor for the PGraphicsJava object. + * This prototype only exists because of annoying + * java compilers, and should not be used. + */ + //public PGraphicsJava2D() { } + + + /** + * Constructor for the PGraphics object. Use this to ensure that + * the defaults get set properly. In a subclass, use this(w, h) + * as the first line of a subclass' constructor to properly set + * the internal fields and defaults. + * + * @param iwidth viewport width + * @param iheight viewport height + */ + public PGraphicsJava2D(int iwidth, int iheight, PApplet parent) { + super(iwidth, iheight, parent); + //resize(iwidth, iheight); + } + + + /** + * Called in repsonse to a resize event, handles setting the + * new width and height internally, as well as re-allocating + * the pixel buffer for the new size. + * + * Note that this will nuke any cameraMode() settings. + */ + public void resize(int iwidth, int iheight) { // ignore + //System.out.println("resize " + iwidth + " " + iheight); + insideDrawWait(); + insideResize = true; + + width = iwidth; + height = iheight; + width1 = width - 1; + height1 = height - 1; + + allocate(); + + // ok to draw again + insideResize = false; + } + + + // broken out because of subclassing for opengl + protected void allocate() { + image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + g2 = (Graphics2D) image.getGraphics(); + // can't un-set this because this may be only a resize (Bug #463) + //defaultsInited = false; + } + + + + ////////////////////////////////////////////////////////////// + + // FRAME + + + public void beginDraw() { + insideResizeWait(); + insideDraw = true; + + // need to call defaults(), but can only be done when it's ok + // to draw (i.e. for opengl, no drawing can be done outside + // beginDraw/endDraw). + if (!defaultsInited) defaults(); + + resetMatrix(); // reset model matrix + + // reset vertices + vertexCount = 0; + } + + + public void endDraw() { + // hm, mark pixels as changed, because this will instantly do a full + // copy of all the pixels to the surface.. so that's kind of a mess. + //updatePixels(); + + if (!mainDrawingSurface) { + loadPixels(); + } + modified = true; + insideDraw = false; + } + + + + ////////////////////////////////////////////////////////////// + + // SHAPES + + + public void beginShape(int kind) { + //super.beginShape(kind); + shape = kind; + vertexCount = 0; + splineVertexCount = 0; + + // set gpath to null, because when mixing curves and straight + // lines, vertexCount will be set back to zero, so vertexCount == 1 + // is no longer a good indicator of whether the shape is new. + // this way, just check to see if gpath is null, and if it isn't + // then just use it to continue the shape. + gpath = null; + } + + + public void textureMode(int mode) { + unavailableError("textureMode(mode)"); + } + + + public void texture(PImage image) { + unavailableError("texture(image)"); + } + + + public void vertex(float x, float y) { + splineVertexCount = 0; + //float vertex[]; + + if (vertexCount == vertices.length) { + float temp[][] = new float[vertexCount<<1][VERTEX_FIELD_COUNT]; + System.arraycopy(vertices, 0, temp, 0, vertexCount); + vertices = temp; + //message(CHATTER, "allocating more vertices " + vertices.length); + } + // not everyone needs this, but just easier to store rather + // than adding another moving part to the code... + vertices[vertexCount][MX] = x; + vertices[vertexCount][MY] = y; + vertexCount++; + + switch (shape) { + + case POINTS: + point(x, y); + break; + + case LINES: + if ((vertexCount % 2) == 0) { + line(vertices[vertexCount-2][MX], + vertices[vertexCount-2][MY], x, y); + } + break; + +/* + case LINE_STRIP: + case LINE_LOOP: + if (gpath == null) { + gpath = new GeneralPath(); + gpath.moveTo(x, y); + } else { + gpath.lineTo(x, y); + } + break; +*/ + + case TRIANGLES: + if ((vertexCount % 3) == 0) { + triangle(vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY], + vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY], + x, y); + } + break; + + case TRIANGLE_STRIP: + if (vertexCount >= 3) { + triangle(vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY], + vertices[vertexCount - 1][MX], + vertices[vertexCount - 1][MY], + vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY]); + } + break; + + case TRIANGLE_FAN: + if (vertexCount == 3) { + triangle(vertices[0][MX], vertices[0][MY], + vertices[1][MX], vertices[1][MY], + x, y); + } else if (vertexCount > 3) { + gpath = new GeneralPath(); + // when vertexCount > 3, draw an un-closed triangle + // for indices 0 (center), previous, current + gpath.moveTo(vertices[0][MX], + vertices[0][MY]); + gpath.lineTo(vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY]); + gpath.lineTo(x, y); + draw_shape(gpath); + } + break; + + case QUADS: + if ((vertexCount % 4) == 0) { + quad(vertices[vertexCount - 4][MX], + vertices[vertexCount - 4][MY], + vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY], + vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY], + x, y); + } + break; + + case QUAD_STRIP: + // 0---2---4 + // | | | + // 1---3---5 + if ((vertexCount >= 4) && ((vertexCount % 2) == 0)) { + quad(vertices[vertexCount - 4][MX], + vertices[vertexCount - 4][MY], + vertices[vertexCount - 2][MX], + vertices[vertexCount - 2][MY], + x, y, + vertices[vertexCount - 3][MX], + vertices[vertexCount - 3][MY]); + } + break; + + case POLYGON: + if (gpath == null) { + gpath = new GeneralPath(); + gpath.moveTo(x, y); + } else if (breakShape) { + gpath.moveTo(x, y); + breakShape = false; + } else { + gpath.lineTo(x, y); + } + break; + } + } + + + public void vertex(float x, float y, float u, float v) { + unavailableError("vertex(x, y, u, v"); + } + + + public void vertex(float x, float y, float z) { + depthErrorXYZ("vertex"); + } + + + public void vertex(float x, float y, float z, float u, float v) { + depthErrorXYZ("vertex"); + } + + + public void bezierVertex(float x1, float y1, + float x2, float y2, + float x3, float y3) { + if (gpath == null) { + throw new RuntimeException("Must call vertex() at least once " + + "before using bezierVertex()"); + } + + switch (shape) { + //case LINE_LOOP: + //case LINE_STRIP: + case POLYGON: + gpath.curveTo(x1, y1, x2, y2, x3, y3); + break; + + default: + throw new RuntimeException("bezierVertex() can only be used with " + + "LINE_STRIP, LINE_LOOP, or POLYGON"); + } + } + + + float curveX[] = new float[4]; + float curveY[] = new float[4]; + + public void curveVertex(float x, float y) { + //if ((shape != LINE_LOOP) && (shape != LINE_STRIP) && (shape != POLYGON)) { + if (shape != POLYGON) { + throw new RuntimeException("curveVertex() can only be used with " + + "POLYGON shapes"); + //"LINE_LOOP, LINE_STRIP, and POLYGON shapes"); + } + + if (!curve_inited) curve_init(); + vertexCount = 0; + + if (splineVertices == null) { + splineVertices = new float[DEFAULT_SPLINE_VERTICES][VERTEX_FIELD_COUNT]; + } + + // if more than 128 points, shift everything back to the beginning + if (splineVertexCount == DEFAULT_SPLINE_VERTICES) { + System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES - 3], 0, + splineVertices[0], 0, VERTEX_FIELD_COUNT); + System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES - 2], 0, + splineVertices[1], 0, VERTEX_FIELD_COUNT); + System.arraycopy(splineVertices[DEFAULT_SPLINE_VERTICES - 1], 0, + splineVertices[2], 0, VERTEX_FIELD_COUNT); + splineVertexCount = 3; + } + + // this new guy will be the fourth point (or higher), + // which means it's time to draw segments of the curve + if (splineVertexCount >= 3) { + curveX[0] = splineVertices[splineVertexCount-3][MX]; + curveY[0] = splineVertices[splineVertexCount-3][MY]; + + curveX[1] = splineVertices[splineVertexCount-2][MX]; + curveY[1] = splineVertices[splineVertexCount-2][MY]; + + curveX[2] = splineVertices[splineVertexCount-1][MX]; + curveY[2] = splineVertices[splineVertexCount-1][MY]; + + curveX[3] = x; + curveY[3] = y; + + curveToBezierMatrix.mult(curveX, curveX); + curveToBezierMatrix.mult(curveY, curveY); + + // since the paths are continuous, + // only the first point needs the actual moveto + if (gpath == null) { + gpath = new GeneralPath(); + gpath.moveTo(curveX[0], curveY[0]); + } + + gpath.curveTo(curveX[1], curveY[1], + curveX[2], curveY[2], + curveX[3], curveY[3]); + } + + // add the current point to the list + splineVertices[splineVertexCount][MX] = x; + splineVertices[splineVertexCount][MY] = y; + splineVertexCount++; + } + + + boolean breakShape; + public void breakShape() { + breakShape = true; + } + + + public void endShape(int mode) { + if (gpath != null) { // make sure something has been drawn + if (shape == POLYGON) { + if (mode == CLOSE) { + gpath.closePath(); + } + draw_shape(gpath); + } + } + shape = 0; + } + + + + ////////////////////////////////////////////////////////////// + + + /* + protected void fillGradient(Paint paint) { + fillGradient = true; + fillGradientObject = paint; + } + + + protected void noFillGradient() { + fillGradient = false; + } + */ + + + ////////////////////////////////////////////////////////////// + + + protected void fill_shape(Shape s) { + if (fillGradient) { + g2.setPaint(fillGradientObject); + g2.fill(s); + } else if (fill) { + g2.setColor(fillColorObject); + g2.fill(s); + } + } + + protected void stroke_shape(Shape s) { + if (strokeGradient) { + g2.setPaint(strokeGradientObject); + g2.draw(s); + } else if (stroke) { + g2.setColor(strokeColorObject); + g2.draw(s); + } + } + + protected void draw_shape(Shape s) { + if (fillGradient) { + g2.setPaint(fillGradientObject); + g2.fill(s); + } else if (fill) { + g2.setColor(fillColorObject); + g2.fill(s); + } + if (strokeGradient) { + g2.setPaint(strokeGradientObject); + g2.draw(s); + } else if (stroke) { + g2.setColor(strokeColorObject); + g2.draw(s); + } + } + + + ////////////////////////////////////////////////////////////// + + + public void point(float x, float y) { + line(x, y, x, y); + } + + + public void line(float x1, float y1, float x2, float y2) { + //graphics.setColor(strokeColorObject); + //graphics.drawLine(x1, y1, x2, y2); + line.setLine(x1, y1, x2, y2); + stroke_shape(line); + } + + + public void triangle(float x1, float y1, float x2, float y2, + float x3, float y3) { + gpath = new GeneralPath(); + gpath.moveTo(x1, y1); + gpath.lineTo(x2, y2); + gpath.lineTo(x3, y3); + gpath.closePath(); + + draw_shape(gpath); + } + + + public void quad(float x1, float y1, float x2, float y2, + float x3, float y3, float x4, float y4) { + GeneralPath gp = new GeneralPath(); + gp.moveTo(x1, y1); + gp.lineTo(x2, y2); + gp.lineTo(x3, y3); + gp.lineTo(x4, y4); + gp.closePath(); + + draw_shape(gp); + } + + + ////////////////////////////////////////////////////////////// + + + protected void rectImpl(float x1, float y1, float x2, float y2) { + rect.setFrame(x1, y1, x2-x1, y2-y1); + draw_shape(rect); + } + + + protected void ellipseImpl(float x, float y, float w, float h) { + ellipse.setFrame(x, y, w, h); + draw_shape(ellipse); + } + + + protected void arcImpl(float x, float y, float w, float h, + float start, float stop) { + // 0 to 90 in java would be 0 to -90 for p5 renderer + // but that won't work, so -90 to 0? + + if (stop - start >= TWO_PI) { + start = 0; + stop = 360; + + } else { + start = -start * RAD_TO_DEG; + stop = -stop * RAD_TO_DEG; + + // ok to do this because already checked for NaN + while (start < 0) { + start += 360; + stop += 360; + } + if (start > stop) { + float temp = start; + start = stop; + stop = temp; + } + } + float span = stop - start; + + // stroke as Arc2D.OPEN, fill as Arc2D.PIE + if (fill) { + //System.out.println("filla"); + arc.setArc(x, y, w, h, start, span, Arc2D.PIE); + fill_shape(arc); + } + if (stroke) { + //System.out.println("strokey"); + arc.setArc(x, y, w, h, start, span, Arc2D.OPEN); + stroke_shape(arc); + } + } + + + ////////////////////////////////////////////////////////////// + + + /** Ignored (not needed) in Java 2D. */ + public void bezierDetail(int detail) { + } + + + /** Ignored (not needed) in Java 2D. */ + public void curveDetail(int detail) { + } + + + ////////////////////////////////////////////////////////////// + + + /** + * Handle renderer-specific image drawing. + */ + protected void imageImpl(PImage who, + float x1, float y1, float x2, float y2, + int u1, int v1, int u2, int v2) { + if (who.cache != null) { + if (!(who.cache instanceof ImageCache)) { + // this cache belongs to another renderer.. fix me later, + // because this is gonna make drawing *really* inefficient + //who.cache = null; + } + } + + if (who.cache == null) { + //System.out.println("making new image cache"); + who.cache = new ImageCache(who); + who.updatePixels(); // mark the whole thing for update + who.modified = true; + } + + ImageCache cash = (ImageCache) who.cache; + // if image previously was tinted, or the color changed + // or the image was tinted, and tint is now disabled + if ((tint && !cash.tinted) || + (tint && (cash.tintedColor != tintColor)) || + (!tint && cash.tinted)) { + // for tint change, mark all pixels as needing update + who.updatePixels(); + } + + if (who.modified) { + cash.update(tint, tintColor); + who.modified = false; + } + + g2.drawImage(((ImageCache) who.cache).image, + (int) x1, (int) y1, (int) x2, (int) y2, + u1, v1, u2, v2, null); + } + + + class ImageCache { + PImage source; + boolean tinted; + int tintedColor; + int tintedPixels[]; + BufferedImage image; + + public ImageCache(PImage source) { + this.source = source; + // even if RGB, set the image type to ARGB, because the + // image may have an alpha value for its tint(). + int type = BufferedImage.TYPE_INT_ARGB; + //System.out.println("making new buffered image"); + image = new BufferedImage(source.width, source.height, type); + } + + // for rev 0124, passing the tintColor in here. the problem is that + // the 'parent' PGraphics object of this inner class may not be + // the same one that's used when drawing. for instance, if this + // is a font used by the main drawing surface, then it's later + // used in an offscreen PGraphics, the tintColor value from the + // original PGraphics will be used. + public void update(boolean tint, int tintColor) { + if (tintedPixels == null) { + //System.out.println("tinted pixels null"); + tintedPixels = new int[source.width * source.height]; + } + + if ((source.format == ARGB) || (source.format == RGB)) { + if (tint) { + // create tintedPixels[] if necessary + //if (tintedPixels == null) { + // tintedPixels = new int[source.width * source.height]; + //} + + int a2 = (tintColor >> 24) & 0xff; + int r2 = (tintColor >> 16) & 0xff; + int g2 = (tintColor >> 8) & 0xff; + int b2 = (tintColor) & 0xff; + + // multiply each of the color components into tintedPixels + // if straight RGB image, don't bother multiplying + // (also avoids problems if high bits not set) + if (source.format == RGB) { + int alpha = a2 << 24; + + for (int i = 0; i < tintedPixels.length; i++) { + int argb1 = source.pixels[i]; + int r1 = (argb1 >> 16) & 0xff; + int g1 = (argb1 >> 8) & 0xff; + int b1 = (argb1) & 0xff; + + tintedPixels[i] = alpha | + (((r2 * r1) & 0xff00) << 8) | + ((g2 * g1) & 0xff00) | + (((b2 * b1) & 0xff00) >> 8); + } + + } else { + for (int i = 0; i < tintedPixels.length; i++) { + int argb1 = source.pixels[i]; + int a1 = (argb1 >> 24) & 0xff; + int r1 = (argb1 >> 16) & 0xff; + int g1 = (argb1 >> 8) & 0xff; + int b1 = (argb1) & 0xff; + + tintedPixels[i] = + (((a2 * a1) & 0xff00) << 16) | + (((r2 * r1) & 0xff00) << 8) | + ((g2 * g1) & 0xff00) | + (((b2 * b1) & 0xff00) >> 8); + } + } + + tinted = true; + tintedColor = tintColor; + + // finally, do a setRGB based on tintedPixels + //image.setRGB(0, 0, source.width, source.height, + // tintedPixels, 0, source.width); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.setDataElements(0, 0, source.width, source.height, + tintedPixels); + + } else { // no tint + // just do a setRGB like before + // (and we'll just hope that the high bits are set) + //image.setRGB(0, 0, source.width, source.height, + // source.pixels, 0, source.width); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.setDataElements(0, 0, source.width, source.height, + source.pixels); + } + + } else if (source.format == ALPHA) { + int lowbits = tintColor & 0x00ffffff; + if (((tintColor >> 24) & 0xff) >= 254) { + //PApplet.println(" no alfa " + PApplet.hex(tintColor)); + // no actual alpha to the tint, set the image's alpha + // as the high 8 bits, and use the color as the low 24 bits + for (int i = 0; i < tintedPixels.length; i++) { + // don't bother with the math if value is zero + tintedPixels[i] = (source.pixels[i] == 0) ? + 0 : (source.pixels[i] << 24) | lowbits; + } + + } else { + //PApplet.println(" yes alfa " + PApplet.hex(tintColor)); + // multiply each image alpha by the tint alpha + int alphabits = (tintColor >> 24) & 0xff; + for (int i = 0; i < tintedPixels.length; i++) { + tintedPixels[i] = (source.pixels[i] == 0) ? + 0 : (((alphabits * source.pixels[i]) & 0xFF00) << 16) | lowbits; + } + } + + // mark the pixels for next time + tinted = true; + tintedColor = tintColor; + + // finally, do a setRGB based on tintedPixels + //image.setRGB(0, 0, source.width, source.height, + // tintedPixels, 0, source.width); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.setDataElements(0, 0, source.width, source.height, tintedPixels); + } + } + } + + + ////////////////////////////////////////////////////////////// + + + public float textAscent() { + if (textFontNative == null) { + return super.textAscent(); + } + return textFontNativeMetrics.getAscent(); + } + + + public float textDescent() { + if (textFontNative == null) { + return super.textDescent(); + } + return textFontNativeMetrics.getDescent(); + } + + + /** + * Same as parent, but override for native version of the font. + *

    + * Also gets called by textFont, so the metrics + * will get recorded properly. + */ + public void textSize(float size) { + // if a native version available, subset this font + if (textFontNative != null) { + textFontNative = textFontNative.deriveFont(size); + g2.setFont(textFontNative); + textFontNativeMetrics = g2.getFontMetrics(textFontNative); + } + + // take care of setting the textSize and textLeading vars + // this has to happen second, because it calls textAscent() + // (which requires the native font metrics to be set) + super.textSize(size); + } + + + protected float textWidthImpl(char buffer[], int start, int stop) { + if (textFontNative == null) { + //System.out.println("native is null"); + return super.textWidthImpl(buffer, start, stop); + } + // maybe should use one of the newer/fancier functions for this? + int length = stop - start; + return textFontNativeMetrics.charsWidth(buffer, start, length); + } + + + protected void textLinePlacedImpl(char buffer[], int start, int stop, + float x, float y) { + if (textFontNative == null) { + super.textLinePlacedImpl(buffer, start, stop, x, y); + return; + } + + /* + // save the current setting for text smoothing. note that this is + // different from the smooth() function, because the font smoothing + // is controlled when the font is created, not now as it's drawn. + // fixed a bug in 0116 that handled this incorrectly. + Object textAntialias = + g2.getRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING); + + // override the current text smoothing setting based on the font + // (don't change the global smoothing settings) + g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, + textFont.smooth ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF); + */ + + Object antialias = + g2.getRenderingHint(RenderingHints.KEY_ANTIALIASING); + if (antialias == null) { + // if smooth() and noSmooth() not called, this will be null (0120) + antialias = RenderingHints.VALUE_ANTIALIAS_DEFAULT; + } + + // override the current smoothing setting based on the font + // also changes global setting for antialiasing, but this is because it's + // not possible to enable/disable them independently in some situations. + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + textFont.smooth ? + RenderingHints.VALUE_ANTIALIAS_ON : + RenderingHints.VALUE_ANTIALIAS_OFF); + + + g2.setColor(fillColorObject); + // better to use drawString(float, float)? + int length = stop - start; + g2.drawChars(buffer, start, length, (int) (x + 0.5f), (int) (y + 0.5f)); + + // this didn't seem to help the scaling issue + // and creates garbage because of the new temporary object + //java.awt.font.GlyphVector gv = textFontNative.createGlyphVector(g2.getFontRenderContext(), new String(buffer, start, stop)); + //g2.drawGlyphVector(gv, x, y); + + // return to previous smoothing state if it was changed + //g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, textAntialias); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, antialias); + + textX = x + textWidthImpl(buffer, start, stop); + textY = y; + textZ = 0; // this will get set by the caller if non-zero + } + + + ////////////////////////////////////////////////////////////// + + + public void translate(float tx, float ty) { + g2.translate(tx, ty); + } + + + public void rotate(float angle) { + g2.rotate(angle); + } + + + public void scale(float s) { + g2.scale(s, s); + } + + + public void scale(float sx, float sy) { + g2.scale(sx, sy); + } + + + ////////////////////////////////////////////////////////////// + + + public void pushMatrix() { + if (transformCount == transformStack.length) { + throw new RuntimeException("pushMatrix() cannot use push more than " + + transformStack.length + " times"); + } + transformStack[transformCount] = g2.getTransform(); + transformCount++; + } + + + public void popMatrix() { + if (transformCount == 0) { + throw new RuntimeException("missing a popMatrix() " + + "to go with that pushMatrix()"); + } + transformCount--; + g2.setTransform(transformStack[transformCount]); + } + + + public void resetMatrix() { + g2.setTransform(new AffineTransform()); + } + + + public void applyMatrix(float n00, float n01, float n02, + float n10, float n11, float n12) { + g2.transform(new AffineTransform(n00, n10, n01, n11, n02, n12)); + } + + + public void loadMatrix() { + g2.getTransform().getMatrix(transform); + + m00 = (float) transform[0]; + m01 = (float) transform[2]; + m02 = (float) transform[4]; + + m10 = (float) transform[1]; + m11 = (float) transform[3]; + m12 = (float) transform[5]; + } + + + public float screenX(float x, float y) { + loadMatrix(); + return super.screenX(x, y); + //g2.getTransform().getMatrix(transform); + //return (float)transform[0]*x + (float)transform[2]*y + (float)transform[4]; + } + + + public float screenY(float x, float y) { + loadMatrix(); + return super.screenY(x, y); + //g2.getTransform().getMatrix(transform); + //return (float)transform[1]*x + (float)transform[3]*y + (float)transform[5]; + } + + + ////////////////////////////////////////////////////////////// + + + protected void tintFromCalc() { + super.tintFromCalc(); + // TODO actually implement tinted images + tintColorObject = new Color(tintColor, true); + } + + protected void fillFromCalc() { + super.fillFromCalc(); + fillColorObject = new Color(fillColor, true); + fillGradient = false; + } + + protected void strokeFromCalc() { + super.strokeFromCalc(); + strokeColorObject = new Color(strokeColor, true); + strokeGradient = false; + } + + + ////////////////////////////////////////////////////////////// + + + public void strokeWeight(float weight) { + super.strokeWeight(weight); + set_stroke(); + } + + + public void strokeJoin(int join) { + super.strokeJoin(join); + set_stroke(); + } + + + public void strokeCap(int cap) { + super.strokeCap(cap); + set_stroke(); + } + + + protected void set_stroke() { + int cap = BasicStroke.CAP_BUTT; + if (strokeCap == ROUND) { + cap = BasicStroke.CAP_ROUND; + } else if (strokeCap == PROJECT) { + cap = BasicStroke.CAP_SQUARE; + } + + int join = BasicStroke.JOIN_BEVEL; + if (strokeJoin == MITER) { + join = BasicStroke.JOIN_MITER; + } else if (strokeJoin == ROUND) { + join = BasicStroke.JOIN_ROUND; + } + + g2.setStroke(new BasicStroke(strokeWeight, cap, join)); + } + + + ////////////////////////////////////////////////////////////// + + + public void background(PImage image) { + if ((image.width != width) || (image.height != height)) { + throw new RuntimeException("background image must be " + + "the same size as your application"); + } + if ((image.format != RGB) && (image.format != ARGB)) { + throw new RuntimeException("background images should be RGB or ARGB"); + } + // draw the image to screen without any transformations + set(0, 0, image); + } + + + int[] clearPixels; + + public void clear() { + // the only way to properly clear the screen is to re-allocate + if (backgroundAlpha) { + // clearRect() doesn't work because it just makes everything black. + // instead, just wipe out the canvas to its transparent original + //allocate(); + + // allocate also won't work, because all the settings + // (like smooth) will be completely reset. + // Instead, create a small array that can be used to set the pixels + // several times. Using a single-pixel line of length 'width' is a + // tradeoff between speed (setting each pixel individually is too slow) + // and memory (an array for width*height would waste lots of memory + // if it stayed resident, and would terrify the gc if it were + // re-created on each trip to background(). + WritableRaster raster = ((BufferedImage) image).getRaster(); + if ((clearPixels == null) || (clearPixels.length < width)) { + clearPixels = new int[width]; + } + for (int i = 0; i < width; i++) { + clearPixels[i] = backgroundColor; + } + for (int i = 0; i < height; i++) { + raster.setDataElements(0, i, width, 1, clearPixels); + } + } else { + // in case people do transformations before background(), + // need to handle this with a push/reset/pop + pushMatrix(); + resetMatrix(); + g2.setColor(new Color(backgroundColor, backgroundAlpha)); + g2.fillRect(0, 0, width, height); + popMatrix(); + } + } + + + + ////////////////////////////////////////////////////////////// + + // FROM PIMAGE + + + public void smooth() { + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_BICUBIC); + } + + + public void noSmooth() { + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_OFF); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, + RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR); + } + + + + ////////////////////////////////////////////////////////////// + + + public void beginRaw(PGraphics recorderRaw) { + throw new RuntimeException("beginRaw() not available with this renderer"); + } + + + public void endRaw() { + } + + + ////////////////////////////////////////////////////////////// + + + public void loadPixels() { + if ((pixels == null) || (pixels.length != width * height)) { + pixels = new int[width * height]; + } + //((BufferedImage) image).getRGB(0, 0, width, height, pixels, 0, width); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.getDataElements(0, 0, width, height, pixels); + } + + + /** + * Update the pixels[] buffer to the PGraphics image. + *

    + * Unlike in PImage, where updatePixels() only requests that the + * update happens, in PGraphicsJava2D, this will happen immediately. + */ + public void updatePixels() { + //updatePixels(0, 0, width, height); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.setDataElements(0, 0, width, height, pixels); + } + + + /** + * Update the pixels[] buffer to the PGraphics image. + *

    + * Unlike in PImage, where updatePixels() only requests that the + * update happens, in PGraphicsJava2D, this will happen immediately. + */ + public void updatePixels(int x, int y, int c, int d) { + if ((x == 0) && (y == 0) && (c == width) && (d == height)) { + updatePixels(); + } else { + throw new RuntimeException("updatePixels(x, y, c, d) not implemented"); + } + /* + ((BufferedImage) image).setRGB(x, y, + (imageMode == CORNER) ? c : (c - x), + (imageMode == CORNER) ? d : (d - y), + pixels, 0, width); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.setDataElements(x, y, + (imageMode == CORNER) ? c : (c - x), + (imageMode == CORNER) ? d : (d - y), + pixels); + */ + } + + + ////////////////////////////////////////////////////////////// + + + static int getset[] = new int[1]; + + + public int get(int x, int y) { + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return 0; + //return ((BufferedImage) image).getRGB(x, y); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.getDataElements(x, y, getset); + return getset[0]; + } + + + public PImage get(int x, int y, int w, int h) { + if (imageMode == CORNERS) { // if CORNER, do nothing + // w/h are x2/y2 in this case, bring em down to size + w = (w - x); + h = (h - x); + } + + if (x < 0) { + w += x; // clip off the left edge + x = 0; + } + if (y < 0) { + h += y; // clip off some of the height + y = 0; + } + + if (x + w > width) w = width - x; + if (y + h > height) h = height - y; + + PImage output = new PImage(w, h); + output.parent = parent; + + // oops, the last parameter is the scan size of the *target* buffer + //((BufferedImage) image).getRGB(x, y, w, h, output.pixels, 0, w); + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.getDataElements(x, y, w, h, output.pixels); + + return output; + } + + + /** + * Grab a copy of the current pixel buffer. + */ + public PImage get() { + /* + PImage outgoing = new PImage(width, height); + ((BufferedImage) image).getRGB(0, 0, width, height, + outgoing.pixels, 0, width); + return outgoing; + */ + return get(0, 0, width, height); + } + + + public void set(int x, int y, int argb) { + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return; + //((BufferedImage) image).setRGB(x, y, argb); + getset[0] = argb; + WritableRaster raster = ((BufferedImage) image).getRaster(); + raster.setDataElements(x, y, getset); + } + + + protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh, + PImage src) { + WritableRaster raster = ((BufferedImage) image).getRaster(); + if ((sx == 0) && (sy == 0) && (sw == src.width) && (sh == src.height)) { + raster.setDataElements(dx, dy, src.width, src.height, src.pixels); + } else { + int mode = src.imageMode; + src.imageMode = CORNER; + // TODO Optimize, incredibly inefficient to reallocate this much memory + PImage temp = src.get(sx, sy, sw, sh); + src.imageMode = mode; + raster.setDataElements(dx, dy, temp.width, temp.height, temp.pixels); + } + } + + + ////////////////////////////////////////////////////////////// + + + public void mask(int alpha[]) { + throw new RuntimeException("mask() cannot be used with JAVA2D"); + } + + + public void mask(PImage alpha) { + throw new RuntimeException("mask() cannot be used with JAVA2D"); + } + + + ////////////////////////////////////////////////////////////// + + + public void filter(int kind) { + loadPixels(); + super.filter(kind); + updatePixels(); + } + + + public void filter(int kind, float param) { + loadPixels(); + super.filter(kind, param); + updatePixels(); + } + + + ////////////////////////////////////////////////////////////// + + + public void copy(int sx, int sy, int sw, int sh, + int dx, int dy, int dw, int dh) { + if ((sw != dw) || (sh != dh)) { + // use slow version if changing size + copy(this, sx, sy, sw, sh, dx, dy, dw, dh); + + } else { + if (imageMode == CORNERS) { + sw -= sx; + sh -= sy; + } + dx = dx - sx; // java2d's "dx" is the delta, not dest + dy = dy - sy; + g2.copyArea(sx, sy, sw, sh, dx, dy); + } + } + + + public void copy(PImage src, + int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2) { + loadPixels(); + super.copy(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2); + updatePixels(); + } + + + ////////////////////////////////////////////////////////////// + + + /* + public void blend(PImage src, int sx, int sy, int dx, int dy, int mode) { + loadPixels(); + super.blend(src, sx, sy, dx, dy, mode); + updatePixels(); + } + + + public void blend(int sx, int sy, int dx, int dy, int mode) { + loadPixels(); + super.blend(sx, sy, dx, dy, mode); + updatePixels(); + } + */ + + + public void blend(int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + loadPixels(); + super.blend(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); + updatePixels(); + } + + + public void blend(PImage src, int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + loadPixels(); + super.blend(src, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); + updatePixels(); + } + + + ////////////////////////////////////////////////////////////// + + + public void save(String filename) { + //System.out.println("start load"); + loadPixels(); + //System.out.println("end load, start save"); + super.save(filename); + //System.out.println("done with save"); + } +} diff --git a/core/PImage.java b/core/PImage.java new file mode 100644 index 000000000..3c42c7107 --- /dev/null +++ b/core/PImage.java @@ -0,0 +1,2598 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + +import java.awt.image.*; +import java.io.*; +import java.lang.reflect.*; + + +/** + * Storage class for pixel data. This is the base class for most image and + * pixel information, such as PGraphics and the video library classes. + *

    + * Code for copying, resizing, scaling, and blending contributed + * by toxi + *

    + */ +public class PImage implements PConstants, Cloneable { + + /** + * Format for this image, one of RGB, ARGB or ALPHA. + * note that RGB images still require 0xff in the high byte + * because of how they'll be manipulated by other functions + */ + public int format; + + public int pixels[]; + public int width, height; + // would scan line be useful? maybe for pow of 2 gl textures + + /** + * Path to parent object that will be used with save(). + * This prevents users from needing savePath() to use PImage.save(). + */ + public PApplet parent; + + // note! inherited by PGraphics + public int imageMode = CORNER; + public boolean smooth = false; + + /** native storage for java 1.3 image object */ + //public Object image; + + /** for subclasses that need to store info about the image */ + public Object cache; + + /** modified portion of the image */ + public boolean modified; + public int mx1, my1, mx2, my2; + + // private fields + private int fracU, ifU, fracV, ifV, u1, u2, v1, v2, sX, sY, iw, iw1, ih1; + private int ul, ll, ur, lr, cUL, cLL, cUR, cLR; + private int srcXOffset, srcYOffset; + private int r, g, b, a; + private int[] srcBuffer; + + // fixed point precision is limited to 15 bits!! + static final int PRECISIONB = 15; + static final int PRECISIONF = 1 << PRECISIONB; + static final int PREC_MAXVAL = PRECISIONF-1; + static final int PREC_ALPHA_SHIFT = 24-PRECISIONB; + static final int PREC_RED_SHIFT = 16-PRECISIONB; + + // internal kernel stuff for the gaussian blur filter + int blurRadius; + int blurKernelSize; + int[] blurKernel; + int[][] blurMult; + + + ////////////////////////////////////////////////////////////// + + + /** + * Create an empty image object, set its format to RGB. + * The pixel array is not allocated. + */ + public PImage() { + //format = RGB; // makes sure that this guy is useful + format = ARGB; // default to ARGB images for release 0116 + cache = null; + } + + + /** + * Create a new RGB (alpha ignored) image of a specific size. + * All pixels are set to zero, meaning black, but since the + * alpha is zero, it will be transparent. + */ + public PImage(int width, int height) { + init(width, height, RGB); + //init(width, height, RGB); + //this(new int[width * height], width, height, ARGB); + // toxi: is it maybe better to init the image with max alpha enabled? + //for(int i=0; i + * For subclasses where the pixels[] buffer isn't set by default, + * this should copy all data into the pixels[] array + */ + public void loadPixels() { // ignore + } + + + /** + * Call this when finished messing with the pixels[] array. + *

    + * Mark all pixels as needing update. + */ + public void updatePixels() { + updatePixels(0, 0, width, height); + } + + + /** + * Mark the pixels in this region as needing an update. + *

    + * This is not currently used by any of the renderers, however the api + * is structured this way in the hope of being able to use this to + * speed things up in the future. + *

    + * Note that when using imageMode(CORNERS), + * the x2 and y2 positions are non-inclusive. + */ + public void updatePixels(int x1, int y1, int x2, int y2) { + + if (imageMode == CORNER) { // x2, y2 are w/h + x2 += x1; + y2 += y1; + } + + if (!modified) { + mx1 = x1; + mx2 = x2; + my1 = y1; + my2 = y2; + modified = true; + + } else { + if (x1 < mx1) mx1 = x1; + if (x1 > mx2) mx2 = x1; + if (y1 < my1) my1 = y1; + if (y1 > my2) my2 = y1; + + if (x2 < mx1) mx1 = x2; + if (x2 > mx2) mx2 = x2; + if (y2 < my1) my1 = y2; + if (y2 > my2) my2 = y2; + } + } + + + + ////////////////////////////////////////////////////////////// + + // GET/SET PIXELS + + + /** + * Returns an ARGB "color" type (a packed 32 bit int with the color. + * If the coordinate is outside the image, zero is returned + * (black, but completely transparent). + *

    + * If the image is in RGB format (i.e. on a PVideo object), + * the value will get its high bits set, just to avoid cases where + * they haven't been set already. + *

    + * If the image is in ALPHA format, this returns a white with its + * alpha value set. + *

    + * This function is included primarily for beginners. It is quite + * slow because it has to check to see if the x, y that was provided + * is inside the bounds, and then has to check to see what image + * type it is. If you want things to be more efficient, access the + * pixels[] array directly. + */ + public int get(int x, int y) { + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return 0; + + switch (format) { + case RGB: + return pixels[y*width + x] | 0xff000000; + + case ARGB: + return pixels[y*width + x]; + + case ALPHA: + return (pixels[y*width + x] << 24) | 0xffffff; + } + return 0; + } + + + /** + * Grab a subsection of a PImage, and copy it into a fresh PImage. + * This honors imageMode() for the coordinates. + */ + public PImage get(int x, int y, int w, int h) { + if (imageMode == CORNERS) { // if CORNER, do nothing + //x2 += x1; y2 += y1; + // w/h are x2/y2 in this case, bring em down to size + w = (w - x); + h = (h - x); + } + + if (x < 0) { + w += x; // clip off the left edge + x = 0; + } + if (y < 0) { + h += y; // clip off some of the height + y = 0; + } + + if (x + w > width) w = width - x; + if (y + h > height) h = height - y; + + PImage newbie = new PImage(w, h, format); + newbie.parent = parent; + + int index = y*width + x; + int index2 = 0; + for (int row = y; row < y+h; row++) { + System.arraycopy(pixels, index, + newbie.pixels, index2, w); + index+=width; + index2+=w; + } + return newbie; + } + + + /** + * Returns a copy of this PImage. Equivalent to get(0, 0, width, height). + */ + public PImage get() { + try { + return (PImage) clone(); + } catch (CloneNotSupportedException e) { + return null; + } + } + + + /** + * Silently ignores if the coordinate is outside the image. + */ + public void set(int x, int y, int c) { + if ((x < 0) || (y < 0) || (x >= width) || (y >= height)) return; + pixels[y*width + x] = c; + } + + + public void set(int dx, int dy, PImage src) { + int sx = 0; + int sy = 0; + int sw = src.width; + int sh = src.height; + + if (dx < 0) { // off left edge + sx -= dx; + sw += dx; + dx = 0; + } + if (dy < 0) { // off top edge + sy -= dy; + sh += dy; + dy = 0; + } + if (dx + sw > width) { // off right edge + sw = width - dx; + } + if (dy + sh > height) { // off bottom edge + sh = height - dy; + } + + // this could be nonexistant + if ((sw <= 0) || (sh <= 0)) return; + + setImpl(dx, dy, sx, sy, sw, sh, src); + } + + + /** + * Internal function to actually handle setting a block of pixels that + * has already been properly cropped from the image to a valid region. + */ + protected void setImpl(int dx, int dy, int sx, int sy, int sw, int sh, + PImage src) { + int srcOffset = sy * src.width + sx; + int dstOffset = dy * width + dx; + + for (int y = sy; y < sy + sh; y++) { + System.arraycopy(src.pixels, srcOffset, pixels, dstOffset, sw); + srcOffset += src.width; + dstOffset += width; + } + } + + + + ////////////////////////////////////////////////////////////// + + // ALPHA CHANNEL + + + /** + * Set alpha channel for an image. Black colors in the source + * image will make the destination image completely transparent, + * and white will make things fully opaque. Gray values will + * be in-between steps. + *

    + * Strictly speaking the "blue" value from the source image is + * used as the alpha color. For a fully grayscale image, this + * is correct, but for a color image it's not 100% accurate. + * For a more accurate conversion, first use filter(GRAY) + * which will make the image into a "correct" grayscake by + * performing a proper luminance-based conversion. + */ + public void mask(int alpha[]) { + // don't execute if mask image is different size + if (alpha.length != pixels.length) { + throw new RuntimeException("The PImage used with mask() must be " + + "the same size as the applet."); + } + for (int i = 0; i < pixels.length; i++) { + pixels[i] = ((alpha[i] & 0xff) << 24) | (pixels[i] & 0xffffff); + } + format = ARGB; + } + + + /** + * Set alpha channel for an image using another image as the source. + */ + public void mask(PImage alpha) { + mask(alpha.pixels); + } + + + /** + * Method to apply a variety of basic filters to this image. + *

    + *

      + *
    • filter(BLUR) provides a basic blur. + *
    • filter(GRAY) converts the image to grayscale based on luminance. + *
    • filter(INVERT) will invert the color components in the image. + *
    • filter(OPAQUE) set all the high bits in the image to opaque + *
    • filter(THRESHOLD) converts the image to black and white. + *
    • filter(DILATE) grow white/light areas + *
    • filter(ERODE) shrink white/light areas + *
    + * Luminance conversion code contributed by + * toxi + *

    + * Gaussian blur code contributed by + * Mario Klingemann + */ + public void filter(int kind) { + loadPixels(); + + switch (kind) { + case BLUR: + // TODO write basic low-pass filter blur here + // what does photoshop do on the edges with this guy? + // better yet.. why bother? just use gaussian with radius 1 + filter(BLUR, 1); + break; + + case GRAY: + if (format == ALPHA) { + // for an alpha image, convert it to an opaque grayscale + for (int i = 0; i < pixels.length; i++) { + int col = 255 - pixels[i]; + pixels[i] = 0xff000000 | (col << 16) | (col << 8) | col; + } + format = RGB; + + } else { + // Converts RGB image data into grayscale using + // weighted RGB components, and keeps alpha channel intact. + // [toxi 040115] + for (int i = 0; i < pixels.length; i++) { + int col = pixels[i]; + // luminance = 0.3*red + 0.59*green + 0.11*blue + // 0.30 * 256 = 77 + // 0.59 * 256 = 151 + // 0.11 * 256 = 28 + int lum = (77*(col>>16&0xff) + 151*(col>>8&0xff) + 28*(col&0xff))>>8; + pixels[i] = (col & ALPHA_MASK) | lum<<16 | lum<<8 | lum; + } + } + break; + + case INVERT: + for (int i = 0; i < pixels.length; i++) { + //pixels[i] = 0xff000000 | + pixels[i] ^= 0xffffff; + } + break; + + case POSTERIZE: + throw new RuntimeException("Use filter(POSTERIZE, int levels) " + + "instead of filter(POSTERIZE)"); + + case RGB: + for (int i = 0; i < pixels.length; i++) { + pixels[i] |= 0xff000000; + } + format = RGB; + break; + + case THRESHOLD: + filter(THRESHOLD, 0.5f); + break; + + // [toxi20050728] added new filters + case ERODE: + dilate(true); + break; + + case DILATE: + dilate(false); + break; + } + updatePixels(); // mark as modified + } + + + /** + * Method to apply a variety of basic filters to this image. + * These filters all take a parameter. + *

    + *

      + *
    • filter(BLUR, int radius) performs a gaussian blur of the + * specified radius. + *
    • filter(POSTERIZE, int levels) will posterize the image to + * between 2 and 255 levels. + *
    • filter(THRESHOLD, float center) allows you to set the + * center point for the threshold. It takes a value from 0 to 1.0. + *
    + * Gaussian blur code contributed by + * Mario Klingemann + * and later updated by toxi for better speed. + */ + public void filter(int kind, float param) { + loadPixels(); + + switch (kind) { + case BLUR: + if (format == ALPHA) + blurAlpha(param); + else if (format == ARGB) + blurARGB(param); + else + blurRGB(param); + break; + + case GRAY: + throw new RuntimeException("Use filter(GRAY) instead of " + + "filter(GRAY, param)"); + + case INVERT: + throw new RuntimeException("Use filter(INVERT) instead of " + + "filter(INVERT, param)"); + + case OPAQUE: + throw new RuntimeException("Use filter(OPAQUE) instead of " + + "filter(OPAQUE, param)"); + + case POSTERIZE: + int levels = (int)param; + if ((levels < 2) || (levels > 255)) { + throw new RuntimeException("Levels must be between 2 and 255 for " + + "filter(POSTERIZE, levels)"); + } + int levels1 = levels - 1; + for (int i = 0; i < pixels.length; i++) { + int rlevel = (pixels[i] >> 16) & 0xff; + int glevel = (pixels[i] >> 8) & 0xff; + int blevel = pixels[i] & 0xff; + rlevel = (((rlevel * levels) >> 8) * 255) / levels1; + glevel = (((glevel * levels) >> 8) * 255) / levels1; + blevel = (((blevel * levels) >> 8) * 255) / levels1; + pixels[i] = ((0xff000000 & pixels[i]) | + (rlevel << 16) | + (glevel << 8) | + blevel); + } + break; + + case THRESHOLD: // greater than or equal to the threshold + int thresh = (int) (param * 255); + for (int i = 0; i < pixels.length; i++) { + int max = Math.max((pixels[i] & RED_MASK) >> 16, + Math.max((pixels[i] & GREEN_MASK) >> 8, + (pixels[i] & BLUE_MASK))); + pixels[i] = (pixels[i] & ALPHA_MASK) | + ((max < thresh) ? 0x000000 : 0xffffff); + } + break; + + // [toxi20050728] added new filters + case ERODE: + throw new RuntimeException("Use filter(ERODE) instead of " + + "filter(ERODE, param)"); + case DILATE: + throw new RuntimeException("Use filter(DILATE) instead of " + + "filter(DILATE, param)"); + } + updatePixels(); // mark as modified + } + + + /** + * Optimized code for building the blur kernel. + * further optimized blur code (approx. 15% for radius=20) + * bigger speed gains for larger radii (~30%) + * added support for various image types (ALPHA, RGB, ARGB) + * [toxi 050728] + */ + protected void buildBlurKernel(float r) { + int radius = (int) (r * 3.5f); + radius = (radius < 1) ? 1 : ((radius < 248) ? radius : 248); + if (blurRadius != radius) { + blurRadius = radius; + blurKernelSize = 1 + blurRadius<<1; + blurKernel = new int[blurKernelSize]; + blurMult = new int[blurKernelSize][256]; + + int bk,bki; + int[] bm,bmi; + + for (int i = 1, radiusi = radius - 1; i < radius; i++) { + blurKernel[radius+i] = blurKernel[radiusi] = bki = radiusi * radiusi; + bm=blurMult[radius+i]; + bmi=blurMult[radiusi--]; + for (int j = 0; j < 256; j++) + bm[j] = bmi[j] = bki*j; + } + bk = blurKernel[radius] = radius * radius; + bm = blurMult[radius]; + for (int j = 0; j < 256; j++) + bm[j] = bk*j; + } + } + + protected void blurAlpha(float r) { + int sum, /*cr, cg,*/ cb; //, k; + int /*pixel,*/ read, ri, /*roff,*/ ym, ymi, /*riw,*/ bk0; + int b2[] = new int[pixels.length]; + int yi = 0; + + buildBlurKernel(r); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + //cb = cg = cr = sum = 0; + cb = sum = 0; + read = x - blurRadius; + if (read<0) { + bk0=-read; + read=0; + } else { + if (read >= width) + break; + bk0=0; + } + for (int i = bk0; i < blurKernelSize; i++) { + if (read >= width) + break; + int c = pixels[read + yi]; + int[] bm=blurMult[i]; + cb += bm[c & BLUE_MASK]; + sum += blurKernel[i]; + read++; + } + ri = yi + x; + b2[ri] = cb / sum; + } + yi += width; + } + + yi = 0; + ym=-blurRadius; + ymi=ym*width; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + //cb = cg = cr = sum = 0; + cb = sum = 0; + if (ym<0) { + bk0 = ri = -ym; + read = x; + } else { + if (ym >= height) + break; + bk0 = 0; + ri = ym; + read = x + ymi; + } + for (int i = bk0; i < blurKernelSize; i++) { + if (ri >= height) + break; + int[] bm=blurMult[i]; + cb += bm[b2[read]]; + sum += blurKernel[i]; + ri++; + read += width; + } + pixels[x+yi] = (cb/sum); + } + yi += width; + ymi += width; + ym++; + } + } + + protected void blurRGB(float r) { + int sum, cr, cg, cb; //, k; + int /*pixel,*/ read, ri, /*roff,*/ ym, ymi, /*riw,*/ bk0; + int r2[] = new int[pixels.length]; + int g2[] = new int[pixels.length]; + int b2[] = new int[pixels.length]; + int yi = 0; + + buildBlurKernel(r); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + cb = cg = cr = sum = 0; + read = x - blurRadius; + if (read<0) { + bk0=-read; + read=0; + } else { + if (read >= width) + break; + bk0=0; + } + for (int i = bk0; i < blurKernelSize; i++) { + if (read >= width) + break; + int c = pixels[read + yi]; + int[] bm=blurMult[i]; + cr += bm[(c & RED_MASK) >> 16]; + cg += bm[(c & GREEN_MASK) >> 8]; + cb += bm[c & BLUE_MASK]; + sum += blurKernel[i]; + read++; + } + ri = yi + x; + r2[ri] = cr / sum; + g2[ri] = cg / sum; + b2[ri] = cb / sum; + } + yi += width; + } + + yi = 0; + ym=-blurRadius; + ymi=ym*width; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + cb = cg = cr = sum = 0; + if (ym<0) { + bk0 = ri = -ym; + read = x; + } else { + if (ym >= height) + break; + bk0 = 0; + ri = ym; + read = x + ymi; + } + for (int i = bk0; i < blurKernelSize; i++) { + if (ri >= height) + break; + int[] bm=blurMult[i]; + cr += bm[r2[read]]; + cg += bm[g2[read]]; + cb += bm[b2[read]]; + sum += blurKernel[i]; + ri++; + read += width; + } + pixels[x+yi] = 0xff000000 | (cr/sum)<<16 | (cg/sum)<<8 | (cb/sum); + } + yi += width; + ymi += width; + ym++; + } + } + + protected void blurARGB(float r) { + int sum, cr, cg, cb, ca; + int /*pixel,*/ read, ri, /*roff,*/ ym, ymi, /*riw,*/ bk0; + int wh = pixels.length; + int r2[] = new int[wh]; + int g2[] = new int[wh]; + int b2[] = new int[wh]; + int a2[] = new int[wh]; + int yi = 0; + + buildBlurKernel(r); + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + cb = cg = cr = ca = sum = 0; + read = x - blurRadius; + if (read<0) { + bk0=-read; + read=0; + } else { + if (read >= width) + break; + bk0=0; + } + for (int i = bk0; i < blurKernelSize; i++) { + if (read >= width) + break; + int c = pixels[read + yi]; + int[] bm=blurMult[i]; + ca += bm[(c & ALPHA_MASK) >>> 24]; + cr += bm[(c & RED_MASK) >> 16]; + cg += bm[(c & GREEN_MASK) >> 8]; + cb += bm[c & BLUE_MASK]; + sum += blurKernel[i]; + read++; + } + ri = yi + x; + a2[ri] = ca / sum; + r2[ri] = cr / sum; + g2[ri] = cg / sum; + b2[ri] = cb / sum; + } + yi += width; + } + + yi = 0; + ym=-blurRadius; + ymi=ym*width; + + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + cb = cg = cr = ca = sum = 0; + if (ym<0) { + bk0 = ri = -ym; + read = x; + } else { + if (ym >= height) + break; + bk0 = 0; + ri = ym; + read = x + ymi; + } + for (int i = bk0; i < blurKernelSize; i++) { + if (ri >= height) + break; + int[] bm=blurMult[i]; + ca += bm[a2[read]]; + cr += bm[r2[read]]; + cg += bm[g2[read]]; + cb += bm[b2[read]]; + sum += blurKernel[i]; + ri++; + read += width; + } + pixels[x+yi] = (ca/sum)<<24 | (cr/sum)<<16 | (cg/sum)<<8 | (cb/sum); + } + yi += width; + ymi += width; + ym++; + } + } + + /** + * Generic dilate/erode filter using luminance values + * as decision factor. [toxi 050728] + */ + protected void dilate(boolean isInverted) { + int currIdx=0; + int maxIdx=pixels.length; + int[] out=new int[maxIdx]; + + if (!isInverted) { + // erosion (grow light areas) + while (currIdx=maxRowIdx) + idxRight=currIdx; + if (idxUp<0) + idxUp=0; + if (idxDown>=maxIdx) + idxDown=currIdx; + + int colUp=pixels[idxUp]; + int colLeft=pixels[idxLeft]; + int colDown=pixels[idxDown]; + int colRight=pixels[idxRight]; + + // compute luminance + int currLum = + 77*(colOrig>>16&0xff) + 151*(colOrig>>8&0xff) + 28*(colOrig&0xff); + int lumLeft = + 77*(colLeft>>16&0xff) + 151*(colLeft>>8&0xff) + 28*(colLeft&0xff); + int lumRight = + 77*(colRight>>16&0xff) + 151*(colRight>>8&0xff) + 28*(colRight&0xff); + int lumUp = + 77*(colUp>>16&0xff) + 151*(colUp>>8&0xff) + 28*(colUp&0xff); + int lumDown = + 77*(colDown>>16&0xff) + 151*(colDown>>8&0xff) + 28*(colDown&0xff); + + if (lumLeft>currLum) { + colOut=colLeft; + currLum=lumLeft; + } + if (lumRight>currLum) { + colOut=colRight; + currLum=lumRight; + } + if (lumUp>currLum) { + colOut=colUp; + currLum=lumUp; + } + if (lumDown>currLum) { + colOut=colDown; + currLum=lumDown; + } + out[currIdx++]=colOut; + } + } + } else { + // dilate (grow dark areas) + while (currIdx=maxRowIdx) + idxRight=currIdx; + if (idxUp<0) + idxUp=0; + if (idxDown>=maxIdx) + idxDown=currIdx; + + int colUp=pixels[idxUp]; + int colLeft=pixels[idxLeft]; + int colDown=pixels[idxDown]; + int colRight=pixels[idxRight]; + + // compute luminance + int currLum = + 77*(colOrig>>16&0xff) + 151*(colOrig>>8&0xff) + 28*(colOrig&0xff); + int lumLeft = + 77*(colLeft>>16&0xff) + 151*(colLeft>>8&0xff) + 28*(colLeft&0xff); + int lumRight = + 77*(colRight>>16&0xff) + 151*(colRight>>8&0xff) + 28*(colRight&0xff); + int lumUp = + 77*(colUp>>16&0xff) + 151*(colUp>>8&0xff) + 28*(colUp&0xff); + int lumDown = + 77*(colDown>>16&0xff) + 151*(colDown>>8&0xff) + 28*(colDown&0xff); + + if (lumLeft + *

    Szq;)iQUjS{YGwAF9^X?2Qnx8Gq&LEvLv4o)O;37(epAWp4c~0;ZSzRGYy|3KIas)xFbw(Sll;X zE{aK%H0Jh%XQme5E?i<3^g2hTVe>_S#N2$r7No}0gE;U8VoJI3r>!{&)M0=$Y5v<( zU1|gNKxe>$zXfzHyF>yUrV=fY&IM+(-3@pjlu5H~-}W~f@Zq0KJHWVLbKYZ0tbd%? z*9-}cENgimMzaZQAenA>A0{4xz!Z>!uYbg-fo2#-lDTsmOSg5EBhlFfG`)2DcA7^? zp*zU`un?oiw0yttq2k~EBX1>Q38LBik%(x3X-!T#Md@%N05~~2i5S=P*{xr860R}# zA-;}=IJ}P~$ou0f%TCUg5%W`}8I0W$?j%}WVfW<2OpNxAbPB@Rp+Pb;-#~F{`~Zzl zK=vQzPD2w9Y~j{=ex3wwR30kXSCC%t3vM&c{E{8`4!6uK$%@699fV)eh(8kA!$8bf zK2B#X5-EV6R!Fo+1BLay-}*fd>7`6=oUJA|2Rb2z{qhOBb>eczAnQ~VzvhEhv*qt7 zLDX>U%6=lmahm4YZ`9d|oY6vmOhBDYr$Z$|_+|t#02|mWks_X>U*#CB?40D~G25VCDV{C~ zlkxyO=@Uisu1HH1EiqRoVc3uJB)N4Uc!`(Lj)^wn7u&*;U?;#{x` z+Mw|_DILP?4bvk|WsU4)CDaH~u=hEDSFf(Ht}2K~K61&Yc${3Vh|!LVNI1f=63wqD zRitQV2${DVE8ggAAHQi)=6MBpFE%a{ockX=q>+al_-ERTtHD4wBx@0l5T;a1EW=(4 z`%DPZ&XKRI?dFSb#ze4dWC-2vIdJ{{mY$&`ZIp#J|3<%IIs*!Q)~I(hd5f4D$9fga z0*a$PDZvJA-ym3`iU@J57*SmVZ5CPt*_%ug*v&sM*5;#0_{ZlixdSTY;DGv&HW38D zf*@5}PSP_H`bNzZG8y{lN{24eYT#4Otb_^ z25a*l{p0<4Bcuw-jW^Fu@p}N<5qs#Brg^S_94U<6ndPnn=5!<^`_rLPUDU;VL7J?8 zCsV)z6A=KlT*W>B+8-*`3>-N6MlrT+II;nM+P8X9optSitKUnj7AKBW%Sg}kv4C$~ zuTHGszPl$4vU8(HkIiQ{OS8~U)3#p`0iL9t^JGyZ5qWsJ9M)!7<{5eUxo3sZ=IP*Z ziVjX>i%?fzK=CzanAaS`u+F0UgAfc>C~moK4`oYu0}y+fF-9Yly*5_dO=M-p&he`X zb^ruymqwBzY{sb*#%2#RXbmQ?9Wi_9*{Zw zJ54bpcBQ+zZ(GwMk`6cwy8AN^vzD_E24!IP+K{?AGjhftMuVAkH6V9gZ-TSaLP{k1hx z4&F5+yJk|Q(Nd%d_sEisd3BvAWC6;x-tOc^{%6nC43mu;YIDwX7@ix6K;|IL@EB@5 z1I>Lnr(bYgs|SUg&g{z?-~4^-u>ZDD4+ze+%YskdPnV702$iO7oC_eHBUZjq*}W;H zCvJT-d$79YK=5uE97JK)>!Zqb7=&)g^neC$R!5;8Y^&((Atg{TnV6HS5ADwpt#>8S zVx-iXsk&w`D{~ZZk?l@)JphFsqD0E-W(JQkno2a z>xnA<@{G(NW%Wzi02j-E@%lXTG%@TKh7|P+CAgyOkbp>S6m((!5AqP20|f~+v>SbC zY_5>GQ)tF%@;fS-d;SwLF9R-78F$#xg8KPl89LwIEPbBFO};Z>KJIbVM*{Zduyc~| zuVjD&ckIhYw((~w^GuC{DrLdCm?0dABTMctz#$j4GllM&MFa2zQl?ztP2e=KS;`fu zg?zc?G~tI?H)Etj9;O&0*-$MwAAA6z)p)+BN~Vc5^ny0Kqq(ke6cfOjb2KuOrF~I^ z6D?r`_34t>)d(4yd85rQa$ZSXRMMlfcy}*ftwAO|!3Y7*;6|l81Ci^BA6v3yI$d$^ z2s;eDhfV^T%}@uV=3ym3$s76_-Ez?eo38t)-JsxWzY85MDI8=TjI@S$6 zvB63l7eo|jihfU`wABs~Zp!Y~Iz^uJYmBXDzADhGNT%paLJ8}h7}{d9O{K8V{h>zh zf|!>KIlC;QOq$+!+3d4u`42Sw^Ucw_z-q1aT%e-h5+q*;0dBHy%K?l&7mtI@;$*sh zuGYgu8O}3Y0xpqC?VQ>?-fZTv@HZuh<1O}(vqucvJY)&J+3!ba9tu)jXKR_Oiu^}S z5SAH{g`WXMiy{sL61Z|P0vF&1?97WVtD>yL#!UmBg`8RENRN~0Xy&Efx2XhX$=MqK zTCB5yK27_`!lJytD-ot*3~I8qwgwP8Gw z;&fQ%c!*1%d7@0vbcIf}>yk!OmnHF5B4y`>?t8vS={Xj-`6gvR(?=WN6OAWkL>AgD z6mj5DuDp8Ca~TI~`w4Fls6bm@;1fN~+G1Q@8Wz1CY(6{rn*{ zcASN*nAj`ysFhfq_$7&C)APm`#eR3E@>IKw{rK>t4RQ zUY>E~*<09Q^J-+IE_ocF2DHpAM54oo0t$Bum$g|j9^b!Ov{e?{z+Nhk4X@=mMJ^## z{67Tu2;;H|4;qWp#KcI6l;$-a|90*9&kYq&tI%gTB+W&VJ*UCW#G#)b7cr#j3c<`Q zy9uU51-zV!j@)5K*~vk?=_3#`-G$e=-xQlpv=oKJ^!%zHl>?`nPCT)inI&CesWz;{ zoAbAX4wn{=siC60f6<4td)l1u*d7}8NpZ$O>|NN)7PzcCH5L7o%3M{35W$p4-rrt7 z<4X5M);X|=EzMIN=M^L|+gz?lIW}AO;cyq>os38ADYWcW24{1d>(kF^ zwB);eYQZ0l-Q*|mtM%t6daNBkP^7oJVLtFFjolO^gfA+n6nzO{UNb=%UH=#5U>m_i z86hNoPzY%IWz*LSziM3}jajz8C1u0_>sAR2dCF5 zn@li?erz6nk;d8#?-rI{`TMImvUhdNYueF3*SOt)wzfH+=<7+o;s2&(5!9KE6C_Yy zeQbMW6Ls~7KTQTOZ+}GlB{Cljc`XupQDX=}77%?)v9+KgdpvWA<26SUnl6!ZkGVpX zXfA+oe@p0Fh`gx;1E2p@vWV{5cnsW8e1=_jfK5RUg5>wJBQlTPlV{ty9Rdd=L(hi7 z_%=%B=0$!`#TjBO)UMr~*-um$VIX2=_Ma1t?hE!}Mw#il2aEOx?^LUL2!(Rct}RLk zzD-;^F`2vHK9Ny>VmLqi128^L&L2UNfg#gwON&bV&AVydF0^~#?boAlF|ec_wXQW0 zW<&B?y(41examO~*;0sv5vcS*g(C&M)5pS;P(mc3^u5yGrxAh>kpH#N2+Mx(n_3IN zc<(=VPH%Ub51#c0ObR|dvpzRNKE##$084At-Dqj}tewxcfp@F1G^q_Y>F)zNLmz|9 zha~mBN90(!c#IlBturm3+s>8N*^sEKhG|khue@kvukNv34Ryjba+hj0mYz9bt*12E zRL~Tp)gR1xN9%JRA328rJ(Z0f*B5#l#=)443u`|%E__Xs^xvL%BINhcC3PW+9l<4L zDIq5Nggfo8>wg(d=QXq$|9?NW=is%h4+GR4aOx+;8-0n2U!OtQmqHg=I}YrB-6P*5 zgWm^}hK~ILpuTh-0m>0;Tyu z7yBb;!`a&?ZOxfhSEb9$z#4u0CkwMl=R^%6C24GAkS}}hsky5y5w9!Gn~yImW)>rp zx0VlPu944@1JrpHPm-IMLob)1?>-b4701Rw;(FXgDVF+>!;k1{ZSvT4|E7M`gundx7>3~)#3ZW~3dK^hci zO{CtPGdSkKRAbVZ2Ouc1szS^KCBb{~3Mb8tPXl6F(J`y5~bMyAYvgKI|UzrW1&I0^S)n38dRNlmncQ|w0 zC10ftxvsXl^i!UCeQv2C=VnAiE}-8e0-Zm7CGD?0FN^$mNBx3Xw9!g63nmJA+vbqp z%(VxGc!sxWRM5CmSk(7eopTO^j;riC7#NhA z%OmsID~|58p|bnQ>ClxcKl#AQpV#e;^joE3UH10!$l>H{f$g9BVrv0N6hQ^{yqzey zt>Pf9acQXBYgMwJ@00vcWuKov7L~1WfzODp+C;cqOS;_Ohj7~sF=CwUFGq=%Jv@&= zlE6bpoiVbSbEK8~CVJpDYC{jGJ-WVcFlvdUBJY2Q(;d5WXWnltnNkD2^zA<#{*GuTfBKNLbJFcH4X#Sc!mHq3PTOqgMcnNCjO${X$T| z%l@O&n0AZ>nb{u|((e-o4WtnO6py>}$-nSW+@dcKa#lMaTVcej9@v)~waaAqw+z&` zQiZDLOep6=MM9Ozs5%ably;frGu3lcLatN4HnZrzs4J6^6&fKGivc+9A2|AZgED`!Jm z%w^_FXh7V@1*CWZxwF|x{YARTt?~JF-DI8YWMa{=Y^V;+C`3g*ufKFhcY<&3f_Yp+ zrxwl!XSWs9c;vs$*(h_Q(0bV{p|VR0|3|J$hk>V3xBNqLqJl!y?Em`~0unk$ieGSQ zOJBI$DymrZFoKCQ9@OQDGhopDvO4M2wsWIG#F@0j^e*5K=eotb&pNTgw(S>kE8?_S zf_Yau&eFH-_Pi)Q#`jkg@BXdUQ^)7q&y{rcjJpUXOm_+#=;Bqj)O@8QIELOhv|lFb z$VYA2Hi9BJk3}OK$3YRNhTvuq7GO5;zl{s+?4+1V_4c`=^#i1)PVf)R{#rtj_hIcZEl+r=qwDsr8?OvK6zYO+cIpmav)= z+^lY!)ao(0FIKW;;wsvhzqa1e!zik*Z_s<<)L zXM!1>$Mnw%9(rZt#!)mCw>WJ2zFmHJiI~s6;Zy*1W+_{^!1--L zSxc06xy$D?O!zzGG!cU4GAe7|VqH)F0k9Gy&Q1EBouD)>O5m=C33F6j@Oe|Z3K9QP zlHbuDd*DNGkx{5US5e|B=w#mJXq@X_(#`Q$H000PjXrL$Yt(%RVwG3ja zm$Qmb``liFt8;;;C&xOoXq+Ho87J+_xei*^lJGuoADhyC_anVi6BJuaInWiV95=vY z=MEf?HC(3+TORpIGzNbk15m$DsIp^P?#XtY^qRo%39v>3;=6o*<1z3Wd%q4=uDjx4 zw>e8pe(&@q>sK&ER<8Z0l*S#&X-Q+6i|EFLN}ec*iOwG zvzx1-w;d{!`YvEiMr$Q@ZM1yr48oqmj1Q*zpXe>fOfrAb19*VEEFGqqtS;q}61MPbB47vX@p6WwyO(6lb=@?SFkUDXbFH_A!a zy7f&&oN}H>5=5kGfe;RoU!XsZVA|aMyH+le45qrGs?+767d){P-uzQqy7dFkY?fKW z^(*!o+_Lb*t@Nip^5a<|*zeRR^Ko4m*OADY-H&5_O!Y_w z`XxLXA_9N#i^1<4+f|+_k?)q#?b7+IU`(DTLFdOR5n~X0-m&S{d*Sh6u$ei&b9JjYR;qv|&`SRCtl+ldUVJSm- zC#Kj%h_Tlp!;W>zPBjxk|P5xcgy zx*r}-X0f)d+!Tu;D>x@<*bBih{#k743riSLUfV3s2PrsJfIF1&X9w+^3M#ceM8K54 zvE@oQ6^v-5wZ<#+&8dX*@Df|GIw+M3cJ9HKYCSEghd3N_X4-zZ&A-hB5+KK0MuaCl z3L{_QG)`eOdexvK*LHq?ZGy;F4;jqCv}@nHWtrq*WhF38f8;Xkva1Jxt(v8Us-b65 zIrgpjZpYGxjmZ$jZ72Wtd2XsXYRes(^?#e*G#Q@lKe8QOw>Hif93KjUdOWRpbjNMS zzVWl8xg_lKqdU)b?oM#z3KQi2-1_BRc$P>x7$m5?r_Ii;TQGZ_Q}#kKd)oAtf7jr` z5N88WTC$e&20Q1}*>igc0OGyvlj(@F7~<4PhRIm?x~eKD9&)@BLgxLWe()(4H-coBQTm)(3)eW){$}7B zS^UrIm+nywP3o+XNqtj4JKj{sfs+^_Y&NgW?D zWOp+smnEh|r*nm;Qiy9dO8(P(**}Gy3NIXr?VP2lyYU9z!p1OX%JToWci}5Z?ZFHO z<@422rTFkK$HFvix87i7k4{8JsA0ua?p~eZ(zOt6`|b6BLQc?IAJpUi&l54MS1Wi$59L_F*1SV6l-N zzY`#1vuq}0>S&l-b}oRC`N#zs@hDC7-eF2?fszM%eOSlEYT#J)pGVSI4g$aBZL@p> z&Z-pZnah)?IWKgyeTg+uzp_pGdljO-C~F*>rijplxAosxkM;GO5KW7xsC`5DsyOIn z&M*1uG@hLSVFLD~s*bI)FEk{8yS$u8co#ay^(&YFnuD(vJr&`l6LC=r6R`E&!U}ta z8k24j`S%>-`-Ybd7_kYY`-w(2b8cU4DoaKsgN0w_)>Rz`y}wJDFYXRA|3pC>xf+`6vRelo$Jync1h*R9>anmV0(O?qxR1@4#A^ zwYI+G283VL5C|Tb@1~i?N2KjvCC_YUhw2)aEtddN(s?@0ZPHxqL`Fsu=tkYh_hipi z4cRiPUKEI^@m$*8`Y?NBy{^`!+wlh=Y;ZUl_-EuZK%?5ole4zT^)0x+aKNx2FhgGR)``^~h z-pkM1o`11Hi{@oYa4A4F%v+6toR1!q&u1sBEJW)&*03_k!KwP@HUw7;6 zO|ke7_henqb>BO4UQ9ABF5=u5{?3S}QV+SV7d`&_pY2@uP!qLqe3n^kixp7sseuDJ z%QN9<4QgQkx{cJ;o`Yx29q{yd&wn!X-7SHrb|n{k;u;ITuy1_SyKNRrg+qJRVf;s& z9s7*nq~0yWqor7q^1eXFKJ^-Xzl9?RJ2+2t$LKjl=tXED(r@H~j+#2nPo>>i>at^R zC-6$_?7?sBU+VDKHdR7Y(xNj%frWAwFo+*pJU6fv`Dp2OgFq|CK5s@-3?6hdmrZxT zMQBU->W(M-i2zh%$C?Gpwy&E(yMR~*x{+ssZ_rOIwEU$iA2C5sO|MW%^mj!$n{n!Q zbx5~%1y3!UP#07aM4gpM%_c50Y`TB87J{o=w;Q;CGrsTe0nvWoeSREp=)T)};9X`s zWVe5lxYY8Ey*-z9-6=w4XG9drj~%c-|Nn+D!GW3o_q5OQV^NLN2dShNW~UhpN9|NE z=_;6&F`P*^VYG(P+btU#|8Kbe-w-!H@WZE7Pc5ju$DU~gZPBS$!1OK|$zGqDoT#q9 zCl_x3Q9f-2!%A)DE=PL@CRBj~2gZAAdMXEFu=o6)wJNX|M2;I6SFF>%jIPv8jJpZU z<^K;H)NUS>ZszdAOOC`5)=a%{^fi{5GZD;;;!Jj%YIJ+@%jE6phXr_|uGb4)Hhwsd zZs%4!h(9+)PvRy96R0k{XH!v+=`*-vcMBS8qA_s7A)>I#p;~W4Vn=Y7p za>N%q4wt{#&NJz@pWgoZMaBN7PPJ3VZW&EEc$trnNJJLwDSqsE?cS}k*c-}ldL_#V zHxA33>mhJF38*OR9mI7ibdZ>H+Wxb!kiQwpc_UKM`Tw14eOT!oSiC@F#iiYp9!IMa2ki!G zcja`PHy>B~<|hQE?yjLTjZAnqnmBX2LPGn+K1;&MCp<}69^NQ>RLTy-;7K=IeG5BH z6M%Sp@QoueAVJh+ziY=9#%|3oa^r}|ej;0f&~C;-u`!{)oke`4$ejgZruNpZ!D}9krPPHuO(Gr|O;Q5$~#mh%M2=MD17M>26W& z;!(1uRPJM+DylM3#F-=q`w%4TvM2I|@9&eu{*Ui~(t+Ooi7V}?zZm+8?7Q*Z{>-dr z! ze7zCaV%DOiT_;E_p3C9^^~x=zsHE(5eLH`Yt+z7ah>Ncv#fNglwvOox8{Zk#x9|{y zp{CPtyNR&{k-sGPnl|TzO<9UVJT6igL6dnQz!!sKiDLrGL1IGg%lw|+Nm7a5Lkj@^ zuivOW$DC>$Q6mp?STaypdB*y zd7%4@kS7#cyWmmlZIx8~vG9(T#94z3Zgt>q(A|9F*>9P3xn&AkkeV<38^=`!Y<xWv@%mC>P+4toY`=VAvXEsE%c|bu!jYBmp1clIk z6O$!a$lr~W8;-m)L*A|O;_YhMD$g}N7( zcXng;_x(GUqVytKpRqiQrvFK+dwTAP#$@Sh@vt#@0fCO%)aD$cJ#LyWWPM}%UbnE!{c1*+rRU_jMYVP{*oUbKlRkQ**HMB zhiCMamn+B5A3qHWA@>3ID523&G1DTc1%TzP=U9r7C(oBJHJln_Jembx`F|?k9Jg}G zRz{7fz<(MmW_xMvZO-C$H;7{T(JNwSva zPT2oi_N*j+$@xy`MFZAd&0911^Df+210T0rw2!K$y*!O}art7JS7i|^On;Cc$(8&0 zD^unHZlbx+s)`8$l)=dEKGsv`md=YLCF)w*Z&@k1)p6>$NIteM$uo+ck= zsJP-~jkGeQKWD{@HBLQ~{ItHpf^J`2tO^HmB;0GMmp7} zP!$eFfg*p0T%ZQYD?gsxTkpE(UzcAL`tUWhZtxRFp~avg=g8gBJN^Ezez>U(+B7|# z{S3TE|7W59dR*+u>1UYCnuM~!sYjV3QprWcnlndkE4FoL%t#=Z$8iOOIQK8S&^hiE zwpKO$@~_f_OqIh|Z;R@08YL)}O#iy_qh$3TAzD=h=ely`l=&*AthH&zTkIxV`D>(n z>bk4P#k)vv|DdFDr^BUPp}&3-2D$_Fm{ZpQqbuHT7k*rFzTl(;ddjgna^~8vM8xAu zctqA?ZE%BA_nq4vG)7IAl8=`K%C}aI_%beaQ(n(ryC3va!p8sYt1SMKu;=xU<+Jk! z_ri)o&q_0amq!G$WhbXS^TbQ*B`rSQsG&dcn5njQ3flHnI6rhjUOu#$m-U6QU-EqX z+j*cIX%^R6a4$PbAT%ox3){J3DD*W}8Bvu}AU-;n;E?VCSy`NcGm z(0K1r%?7!^OuILK^#<7fyn@%Nh(AgC`dwYC496?>-DJpS&PCYee*jfLs=rl^St6H% z1vAB?;ygnIf)r}gswz~gwPWRyR1h??Gp=;7b3}MHN>-?Abnbd*bTaMKX54FzJINTd zQ{K#5bNWVqMX2b{xMo?;3Ql*c-Oq~ggvNJMt@~|^X zS0UVP9&fhF>+Qm3snRm4${p&(syfp%p1mB>LS~CSL|hV~I#9MTidGAab*5W(oKA#KU%7|c|gx}BSigc(_Nwsw?Dax(!j?Gd^AzdSuMt1uc# zsljn)qHRW$5`?1?glv-zx*2x_FFSYar7xODxyK2nBYH-XGLX76fF|j{o_2<;yJtQosLKGaKLun=GL`#YS-=0?z&s8W-GM=nB>xN26&Q(dy#Uxj4H_AsV%}Q;fUD;TzHP#C) zfk}BP8B)rtPbe_r{Kk0MM(M`Q(Kt}6&y3-J;TDy$lSU8&A3isZMwP+lC{oksaL#HH zMKe3=oRLr=np00s5L~&7>Z#o<94)sCjdFq1fl|bFio?M;8TOA2lO9(|tfcW|#HgrG ztFyyss7g6WhDmLETO5Xojs+gjn^9jZ*I_~&u})RtoN8hFx}ctJk%NI7(M~)XM@b=n zi8>Hgvb^u;GCCjR^0>fcH27X7UraI^yJw{t%5kCc+#Hvn-zfLV3$S*vw$UnI)got! zl{N}&Upgx~JLYkVdMBBbn@WkDa#1O9Qm!c_?vz6kf65a{kaobT{94!SoQ_sVRj@S7 zi5Q7?)|574LUH<{omE4_Odx1wLkm5BqLnnwv2osdv8H&SU3p|EA@pC~I;$wI?O-cI z@o-&q4JE*yJDTEUu;;B^P4Tej*iZtccTww@&0ybr3hbws!c}%hXF}Pp zid-dD==G9lgq{f0BHfsr+KQ5TC+VDu&`*5D>b8}^_Aois8AH~T-KPW7_VQ+7dtpYn zamHNq2t{93-ZkzaLJ2<$_ttxV$OJ})IksM_2=6zV^04H?fbGJD_|LkY1ANXW%VLVRa zt%)c~rV5gIUBSq7xi7naM1|%{QAP~aNlc2*kro?vqi~$skQ2jn&dKCy*tx@{I#3^J z)Nv=2%dXz29IaHvT(z5JssQA@;K<3;llXMpk9KBjII5#k%SKDDkdo3@u#==mKvifz z3FWb59-mT6PVFio97f8;%|@kld}jV~SZ)rg(O_qMf@|8}ZARUHi8xH0D@CJj67NE> zC7UR{x9GHSq%-LCVbAf|?ZccA@k22!`5YW2_LQP2%c*srgU@n%%V)Jbv$nEc7x}Ta z0ab6iT0UB)V~D&zjFf$a!EkWy)NnFd$t)^br56px@pjzB9m_V1Q@di58xD}}EE*?? z8APJH$jqOo0%}ZuftK^RANCffdC%pPLqt2>jEaVKt5GOkA#2w4S_uzi4&6$IDR)1Y zJO-GfZYpI%t)$aE84q^W zp?pETBpy|+Ms`K1vL`eh~O|c&(RC5p_c=HaNYU*()6Z4-FrIxmb6v7 zqP#(JDoKKCrY5b~DzubW;ERCM8lH>>E7VZsf!%YpL2Vc5A?AWTZ1v>fIPE$UWpf8d zC39p<2&V5XXyXcTY+G3!O1nfxtdzhaT>phr%roH;Y@oA3Wb=UKV(gfLRf@GWO^EC=|Bj}%~A)7jldZyJ zd}1hLU1xQ=sZhy6oI91s3K=G^ExdGVV9CqJ^j4It%`&>{ottNefh1mzNZj>y})tklRrq$3bXCiQ7>_v-0c1= z2c0()60aY<5YUWqh zIOrIYQWow@Gmtwf)5VooOHw7=ofsF@5;;_A z+hYuWc^nfQ=naipA!Xs_KwbAB^@t+RLZ~;o;iX!EvS^O9owK|j3X}xMqcgA z0N0)gUZoPsLQiyAAloR7IG0?g4)`EO1ByCwz0f$0deOi#XLzDCJ=IChfm7y>pKgjH z(Gt&kT90{Bsza4dd z{&w*Ey@#-)g{^UC2ZdV4>y&xq;X8uhBae!T5+i%6oK*TkQ|y`Y2^@)MnB;0-WfM3L zQ`QkXe5Ki{6v>J5>^#c)KS)9;pWTfUV6|e*n)0NcN-FA8gVa}DMm|UFCvPR?{pGnq z=TzJ+p6Dbyk-9GyOM~$Wr#o@Kv(;CBms(C3>Nw@=z;)6qA;rV1%{h6|4bzF-_ze9^ z>CZRmZ$^YxQlK)RZ!+L!Q^he}By5f-jGe5$7GRRlA6*H^7HUYwq!g#F13=0g9;UAN zoj^Zft3QX3uivt0p;Eb7Y*fVXjdZ#X=v95H$32DV1$*iMVT8#sIXE#t|K}ioeR4)M z=zCB)Gtx7YRJOvBs>wGSx?Sfax~|O6a{*dI*Aot0PwXv4Iapm!pm=3(c~{G;MZ+ej zU91+G6u$EE0#gXABFZ1MT{(*?xu`VgA_e{9E%Mxh{>dVZZ^r&2uMdJn6WHOLY=r@x zqc&qf8;JxmTCp=oYDDs}es>&y^+e?<$fR*I8jUc=*bcX$Fz7M$Z8s&|h_<678VIdy zvZdJ>^bQZtR)l%u6`PDHOnULSKJ3R`kzmQ1S`zQX;shV)+&b%EoC?aNp+}|kMq#}y zV~_j~R|auU`h#YG{)GN?)E`U3Q=M4e0??le{kSs{Q$T+_7WMo8$KJnxcDI$|h{CXc z%KP#3vvRuk{gQl=WjWE5Y-uDpsq_~wS=x>@ktK~J$4UMAm$>n^xt*k|`Z8yFt?G6} zg4`qkf*=S2zifBUTOorqYc`F-Rd2aO!Bt54aQkJkQL1|>1vlHz&|J}k3;Mgqz0%?j ziWa21>w(j}SQDxE_~Tc9vxuwMuz+ytggl=2Zb!qb;hgyo3`)l|nJko`p6qs;(fV<% z&K_Z54!`L^JmS8Zg&ZUR_WE^Yc~k3TKK}fViM;Ayn11C z;&R!cYS!PJ`QW_SH4f%=HVIU-7#1Hngu5M%m594BR|H9oYElJ%PH^flPkSWqJeKhn zec{6Ow84(m_In5e@Fojim>(9~qgn`VJxvim5d?tkR6Y>|fSnVOWY3O}z)J$GYLj*? zYjCw_aA*niepv3t%=XRGbxliU|o&6sax#6_t7?+4) zqza{d9XdX;Zv<$6f?Xqn$)s#1gAtxhUWVl76k;I5Cb#q6WN7~h_ z-R-g`SFO(qHTsOST!I zK#NEgzz)NI#KB^cB0dTkL1E+(j!C>zi(-m@*1teCOCs?~L^vADtWyx6TVnNh zlLMipWz&kM85|!?ibY?dMc)gsED6O85gQoP06t4Z+h-2J-7n!qKC(6cS}RyWtr+_*#_ZNDc*btOQY;h z2faD6&fG>f8T#AkZV$G#VevRy9pgyk0cNU~YzG{#-AvXl`UPGMuEx`kx97dtu;0?2 zQgp^ks`JIM@mz68b=oMNMri{OQpFyEx{if^y)z?la@uWMo3HH_Cwqz0nl}-P;Jm@U zIqRGW&7K!I_|Q$h1IlYWlQoWhcUObitoL?sI~|a5{dRCYpMGRC!2&NVZ4qg!R6yea zrTt0gN)tsF39!@p7c!+5%^jbk0rE1(7ojf!@-x>|-nn9n_Ds%47wH!G%Q}>=u!0|AQLU;=bqT2J^qW{yvM^YNZUsbvGF~M zT*o0&N&vQOEAKEgZO09NhX%$%IWIypu;Apyvn-|Wr}Cy3 zDrDGJopG%({ovR5*)KFZo3tt!mj%9m0U2JuRR@mNKtP;k*TSJ<ii zcV}T3c~cHJm|?B;Iw~dqsorM&Y5UlC$5|W>IaQg_i4?kM_Ga0!dv^2RPiVYxU9`ml z>UR?3TYw6(RXdEY8i!3fCC>3pPQtrD^Q-U#fCXy3UQoZrx^wG?coN~P9+!b+q< z|DetZyTkcn`5BxLn&EcUe08NnUuntfm8 ztMKIKf*qyTTr_u2pTGz7HFrXP%mNtEwg{~wPQj<R_~g*b!a|V;Gt?$L8=wUobER!Ft2!WWW@lWs!Oh8j4;otmx7JcBQab%q!2l(Eo%UIBRdTYwYq z3?r-P?JK?x?y8Oo(rH=yQ(!hi`VkxH?;} z9F+0p4p%v?_-+S|DsB^UU2nZ1$YMSOdgLN{vRDTHzDW>(wGr_IM9ACm?7h)XjdRDa!vNQ01zolg1lvdAIi~rgk7{cKORkhywRm2ag=kura#zidg!|Hjm zS)9PvS}O?55Xay8vkToBjL=niAX?e~$%I+rC;{2w&5Up$A^;Sg5J1g}PA!T~g|V4} zpos?c(D;GSSfkEc7XP|vtg{dr6UJi_p$C*VHJUr~5H>%IxHdfXA!Q(x@gkm_HprPy>xU^D7{lVClR4! zvm2B?+ofo6gVGH-S6D=b(&he1dMz^PcBi-MN`LB$M{FE_)V=+7ib##+`^BfmdMzd8 zM|f1ayZbNK5CAoeeyhdibp~I4HsGukAh>>?#R>rw;z#Xk1^wO4;&}3FbN%i6_1CAp zT~%dn)zhP^7hspGgViL zBGMl|91lx>^MxXd>7TE#)A;AEW>wL zx3Ls?!+Gni;&ONViQzw}U8%FrR#&Em2_Kq;y#nOjB{NA1B0Gy+cVzRd5uRk$BqW~K zFyY<(y>yfrZlgMD=y_z#_{(~wcVKvg$x>&v`YeJ6Yx0EdX_tB)?3#iAOdQ|ie`3NJjzn#WBzWf4(x~d zZuaf*Znv3RUTd@pbjMhK)NCzg=JEX)Um7kp5*a}B7ThYqO>VJNUtmugsm(GQarR6J zExfzMnZ{fjhPSs^wl@G~)PVu*_F|}xLGv+x+orM@pGLk{LgQ(%(Z*<_ezdNDWprL= z^l^>}h(YkW!T2^TOC(Mp!1EZ#_#{#t&utRJz1UIhIajUy6*ZC3di%Mt)gaktQ4I;z z;(kknvYy$RYl89paJxRO7aR5O)rAoN?1P37H`{d(hPZ%HIlf1m5Hggz1%qkd`8scZ z!BlSbr+qM$Fr@ncdkbdPw(NWMHVkeRttt|Vh&jI2+erJy zR#pLP2mOa;`FW-{3DyntIAj1hE#ZrQ&8B0G=LL?CzBB{fi8WkTiLmPXyGQhdvQ-H^ z(7oH56$(@BHYPbg+QIznSLCc#h*XY3qK`-BH;EMBJLtFUI0(zU?<2KmyZm{9q-RvTF{ zdAmPoQ;(K5eJKRgx#rgNjS)V7@QUs2KCmu@cS7_a+DWAARMWT{R^nfastk=pRUXe= zI)j>AWKGD#qt2F_y?eA!WqTtdx#Y0X4e8<(pcaRRl|CM@ap(4NtxgV`od#zEkNWsm zr@ZEm9nBFU=C2*ih!XjjoN>)jqq$vMBbVuz-b((!=6+#~p6{BP+ufIc?M@2W3fRC| zl;~Rr=o?GKCTQI}n)4)*z2H(gRRi{-Om~}LznOc)t>0)o!}uc_?Y4R5>qeH&`q*L! zi%h`oJ3wH4Wbr{*9_SG3sdZeLB@Ul}KaAp&ZHQ4+;TL{+%3@#()B3_Cxb#(tW!TZ& zvjrw|D~N@l;;?jXR#nk|y?v2KOrlC1V}{`sRRfjobgls;&wy4hS#dZ|yOGccYZJ%L@!Q*H?+2y5-+P0+`4nmyT9We(1Np>p-v-0ir zYJbful^c|GpFh_+2~1a zFM(?_ytq(R`$Ka&Jv?nco6a;7>=lv@&HdfCll7@W#&vvNfRn+(@J^%$vA0Y&nRwW@ zn41;?3)jrrKz$IFshP;s%$Ogp#rb2#Yo$WvyqYPbp@X+=cL2TAL{$XS2Q7u@jc-|@ zot=bIS(}w^J|_o%2uWFxnYG>qV&|?*Co#yXzzpPofsS4Oh&hPT!%kjVo&@Hgf%r@% z4qgb|A_9R5!RkPN3{rA$k)sbew8V$KWf7Qh)H>gM{I|YP(ZlY&rPzT6*qvNF2W1^^>Il+3Z+kf+2rBd5&VY&hB7vx`PX-E zSSklCY_`F0x_GvAEB4Y9L!?(ra@W*0;uNayb86R+sdUX|i;BCarfF^7>%vH2f$+O9 zvN&{*(Wgiutw#x>91E1fFmn)$c~p{UAiNOx44%ss`G z`Z6H`-9xMS;*)W?lOVXVe!#cwDI0BPztK-1Rc2U!%2AX8G1{rO`R){2Vf?ymx$W_J zvqaioK5ey^UsfTZ1M9)=N>_t7q-oyfgWln=pifokWO}iFY_@W54w|pS1aH_qaQ?-0 zNldi+q|&Z%x1cT)Vq@X6%CoT<0R_#Zx#iNBf%nrf4mhj5u-en)JBvNzs|&}Rnio`J2Wqz9JDn)c_FQ*F9acXCpw279ju<_I?-bgSgj)1)yKU zb)$)J%e!r5L_{Yn`-WxW8-|TUJs6C}ee>RbA*+$2Bjio+1AEH4FPxAyTX8{H09f~N zwy5D?#g_amoSQUjJT!LJk7~2;v_O~>YcV$0X3shA%>r{QzkiX&uJf)$ISY46qhMoL zZH!@II3ipgi7Bi$4lASK_2ByE>YUd?4t`8W{Uk33cc!PT1F^Pd6POcIr7gx&=LXn+ z8o>!a$vMBGSkI~j!WqCK)?g740VwJ2SOQ@SCerWtFERUmdA&WC=zKdy0|O6O=cXyTkJW9N@@( z+&MM7dKZ>4qU|D02y36Sg_6wD84eCUVeyj~@e=@IG9@B_k~lC!HUs2vC3&o5h9zpB z{tT^mH@0S~3-uhWGH;T07-D&UbQ2g7O@Jwx6oFZ4Af}^Sp&+ymOrU&wk|$}PKL+6h zk4fe;suwIM$7_=W6@om)ll2Rdg#y1UHmLl}!2lK@cenV_gixPYyI!&_DbxCd4ky$# z9hx{VRqNKF3z9Qd%AG@Q-8r0(Z>}#oF@}CRp;;1+@MVPBkDersMo6oFr+ST$X>;#s z_gWe07z)inn8s*{FT(Rn+B}P8&XqUk%klI>Z>qK@rPy53e6!?t%-4C7(=j>sn>0`s z3|Zn$ECkE)ArtvvHJU3`x!)U&&U^ggGH0`BE@sgjY@hd%Dc!WvTY!kp45MmgnCL|d z1J@Wt?}4_fj_TCi@@(yYu5fp|{$jI%$8#a;)L)x}I(%$4?y?9kTKy_3JTF9uWQw)S zj$t^KI=N^nSqH*I66d6-bRf(Uph1k;p?rLlIZ=Eyjv`LiQ*FxTa2 z7;PGk1yU}$12hQ0Gc+g6#dwq5P`sh!v31Uqr@5}Sn4?d8@sHDg7A;+GWj~zO*IxoL z^sCv>W=@K&8R6vF#tbtvC&ms?W?6Y|jBPp*X1x>63ykQ2n7Vp^7}QNK$Wn|O z*zoA+P-*-smQB&x-^fKsOT@^ss?k>p_@F#K_r(i=pn|DEjE9FA540N|{VID%Vy){& zxb?O<=eNyyk-mU`cBcXFO%lWrTXrLVHlIo|%p4;-W`Sq}fJLLk+VnC zDB0GUm+?!}a$4}hm&eN3G%zo2bbG^dDt>5A5OGT^t$`VsPH8MGF3KV}dLNoeSk^M~ zA~16B61G+XT5IE?iyd1|$zU#<7-uaBhT*)-t&1?Z*BEg2?}fjxmeR`N0RyNvf15F8`3X5?%CL*6T2di8FWuuFO^WOVF$y zicK4vz0gXwc@FuQgWdL6|Ks-Ce>Ouon$}Ak^_{c zGkTSO>5%6zjS)P#!b0=}0!UM&NSdfM{GizH+x&TVzLpLOrM$X{;iMu3mFw(#W20&D zeqNjX{Ch1}?nn+BY$~3U5MspJ@d~(?I40FUOh8$Itn5>4+rgsa(A;vcaBFKvh4p8A z!Wokq0W;Trg+aK4;aG*h2Dg`!u?fFaM0A~h`?OK|ke%`s$GE%$anjO=maAta?~HAl z){-j41b^P?2>Vb>Xdj9yRXS~~Fk7%?zPW$5IL-#|Od;^u{mrpCpO`X5oHqy01QRE@ zDqY@P9xQ83oD{DxL#IraP?9rBVDI#*3a%;zTbajrSHoGKu|^?kfo^^vJ1-;&6y0op z*Gs<5(Q)i-8CrN(GznkPl*y|kdn3XLjqJ6360k;vGvJGwBC0&Tut1n~pG$_++g-C(%zY`rPs z(wMvK5xaJqb`4o=)2~PSi@7 zTDCu0H#DyTxgx@5xBV+gMRt2Vz8IL?Aq89#H5Z5V7qz2+K#E_1%MZPl!h+-#K1<>_ z8sq0JD~b>T->#V{!ZuQ;Xx&>a_9yN%dj+AIK5Z4!4jl0xav}Hwq6w5dfx;a(s)p9M z)rxA)ce@ij34+vmIAZ(}zv?}Iop$)o=(-3$eVWKBB zgu!%bvQJoJfD5W-_(|>e4d$6v!?=btv>W;bY5f#hxh{Dn=M4ItTHmJ+m;vy$7JT3g zJYVO-bN(W#vLat z9ka#y&eeHo1UX)zuJ2r}n4C47U@&ZQ6J_Ucw>}*fhi~BIz`BhzmSA+v=AOPGGF#!n zC_IcH!W?rC=Erg>Dy{&w!Z61(Hl3W`TwaQZOX+4~+UysHV>4ekcfefg#RB`z{SJ;B zE}Nd>g8W(5OL$|&ot-~_-QUxE3(C!2z}vjj`t)>aJnO1RS{J|_2?^fGL1D4onue(> z-Ig?3mg07t>&fEuU`B~XxmvqFg5lu`+@g?hfjNl7n%v#-wZCv1sh^!MO z$b&aqtX*|+pqWGaBQ!GJsPPrV_h6YRm}!!QF^hRojrc#Lg7YZ10)^*s}#c(?schGdoz?oK&a4Vrdm?xwmy&>7*xpB zFVH(}kivlUj>p{+f{8;A`%Qx}u9cc-Lzmu|dPOJ8YPPFp)f!)IVAMZm zjZ+y%udWtfH2_qRAATGweIh^|q$S_}0hKHga!l-A9}};@?MQ3g(5sXRt(dSsI|Lm|=u-3U95Zhab8(d#NZgf>}i^lvG<}j>vW^c~Dmh-JW zkC!^65wSeQz{@|=j+JtW$BZ3VGf^AtxIYAcLri~sH5m=?j1BIFJP&+*VHAg7ns3gr z*i|W97O>~n{TUi1iye%Z{Nt@y<*p-{TNzRgz=Lx9qK*L9amTtq)kk8m7xbtxt+F@6 zofJaCHwuwiWucw)#ZTdwIi53oGO(fkKzo)&wa6k23~e#QuXDu{gNv>uU1JKGI0d?wcj19aclKDp==IW3mcoo2J>T z(pVj`0>z0sT?L9$b*i$8-+_e>bYyjqvY{WIPAff(j}!lS>^)nOqhsh2Bqs4Yz81 ze=i83iVus!;{Z->h!UD+&!l`PImjr?>1-0HPPv)|7{c9N4A6?);ug5-BE(!YV4@Fj z3sqc1f*Jm;IfQ>}*5KcoC+N3-kU3X#3JivZUhvRClym}>3{=Vd6!dv-J|9d!f{jP* zULe?K{oY7gFk>Y6l=|&qv3=Ss4tQWNqQfLQv@~Re{ug`Z{CB0~zk^Sl-P$x!KSsko zU3iuWU3m7)8yZDRemrDbRr!h&GhguCt}(W{EFt~Va9EDuQMM`*ix3GO7F<=8SS?C)u0x#p%?jjY{WU*V9AZ;8e*xc$i_0?h!07 zPW;dj1b}hR4-AziCUkB|2@5DC@n5E~%)azzZVq=C-f}Iv#XL!_w$Ft?sVc#{{*k(gw7bjs!UV=wI{<>?A1czQby15#?{LA z%1b_kte%$5YNTkqU4C;xI9%w5^>(!TL=HmMor6g~lmN}9s)Q@==ou{ zSS=UFlPqeVH zKdO%R8w$XH*%9*sVq##eP2&ME9iI!L2Dk@zrlkkWKsRS z5@T>&F1AAH`EJvHD0#RPlE)>6;ZO|~WjuC>%PgZ1fUSxgm}m_5!(6j6TwfLuI58o$P}(6nOUq}EnrKn zORp3?=2=3;Qb++1sW6d3bcy4_R0=UH78ho^urh_Y6k;ZS3Dh^>!rdDMdiq>GZ8jn? zps-AYpA@(GlY#H{_N`+0^3DF}6{9oI`~lJdY#CV;%t2cfu1VX1N_Y2UVa%S(qun#hUALRE2yC&=vck2<4-QMbulyb?D<$&a5F5$5 z746E>Na1$#m?nZ4d!aIV1B(<~hCca8f<=s5<+MtFfh%I7PuXUy%JSg+>g2yp%?l0A zf9+SZd5sZ|GMSU19hFFiTLXP%VZsnHO?pZcpJH7n&kjsoB6T_}N)U^Lbv`j=g`rRg zj8&#w&P)K$q_mF0wn7M(s_gt@sc^lecCfKZFP7@i@LnyN`)^Xmz)7H3L8o>ffZV(F zMky?R4P4vVYxEm2cW#4Yk$7UO6P3spr@U+rvj22A06SH$daFl8)#K>^=@@POwB}a4 zNo$b|cWwGR&K+EAf5)jw!Xryw$LT8wf&&W@nIz8eH||bUAk!UuZI-CF5Ec}(`)Ih{ zofL9q(s60N>C!B&f;B+5nkm%LQpxb{deuIEiGw{0vXexgZQFc?teNvM7oTl9GRC(F zmH2ixF4S@bC3g#t7&aUAO|39%1$Zkdi}f)CFzcqX*Q>n0+rbr)1WPHkhivC)Xy7dH z@U822K=~*p&t0*N+>wl@juwQidA@iii(u&J^yp0UqIuk%tb4lDy6$P!aNuifGHH~5 z(#K8$JXLPu*3kBEj(=&YU!x-0u{TSp#&BU&Mg2K-wW{;aH*uYEAHH-}U+g*^vHjqM84(`%q=EOk-vwq4lnY&K(q|AUI@7z#Ok-u3$Z!RYo@akwhS=i_U5pk(eD z2!h&GIOGf&0Kw1Roe$?%y$N@J0LoRn0|LPwa+);7ia>Z(J-wN|lMd2g2LM6sGisl6 zdxg+<{qbl#olScEfpk)YIx%3>Q%OBl+>@gDyNkZ`P=|WB=wnL^G@$;(+_FXjPNgk* z3HfaSfLf>2I-}O$%ku7GF#APX=fN*40BT)O>yldoVF%amt_JfSIpp_>Q~=z6KIis@w1-(v-FEDRHgR^&PTh<)}8B+mp`;6P?(jM4y-qRu` zj)VLN5Zpt_Jyg;I2*(fC7rKL>cvJw?J|POmNi6MaS{RB8q>CgdB?*RmNx2u6l+Z*8 zfsyVZC@Fs#aqEJATbI%rM5Sis7-O$NOSLiFOlK?>;)G?Q0>=GiBx#KxP{9%qq=I>1pu^-ks9yQViH!Y?^!2>O>Pi?Iec-sh5ZK zrw0Kbo$^kp=(|TQl7Jf6FMW_{3okz=Rxz_}Dr^h&BMTsZi!^{L?^_j&flM#}s>)~n zl+0;FlghF`dQwd7jM0c`5A1U0f=sv|%Vb&tQE3R7m(&m|#5s%H7<8A<{56;uItRL9`xdxzi(qCc9 zM@~g)DugIAo(ZZ!IFW>(HGJbA@`!=KsVBw=MqjrpO6L7ik?Q-+9YW|{X7yI>Jp4IQ& z_RkMzxBYj$shC2lSGe_o@%Od*0RcJ_eh*D$5cQVl*gG!QYblM*10AS3oet}}Co2Pq zAi{j?r1}Rc!6(lqZh3~~xUpdM?d+;I8r`zks$O9Tg%K}r!TFq)x5oNZmUkl0Z_f4d zPD~_!K&xx`bcvrv8?ReYVMR@2!e^4>>)BZ8H6+(93?gH%p8e?bckkE7HK&g)42y@l zf$!n|jJ+xBbipJ9lQO0v92Pt_#DSm+@~e%bj~-tVFm{zwR~ddzmljl7@&__&-l)Ty zSz}bn?d8sm*1dX$5<&%jq&08T4Suku4_4NHtX&A)^{ZF3=@X+ z@9vl88{PgPvm&ydr_H`uSPww-yS8Tzhoc(laP|6mn^ex0i>+NtsC*Jx1Demz3L6UX zp@>M=sp|85MVH!PzFPA{(L>8CfvdBt@y%?|Mg@AR#D${k?&;Y0EW-Rlx7_w;iFdjN zMT*Ai8GVs#&vY4WU@$mdVhy~aSL*A3#rT7;1Z+~yuyNT3nElOJcSHOHiGUOqIiC62 z7%8Z02(z@?@iJ{@iT zd~+6PgWCzwI>V4`*OME!Lkd)c^sw^=AZraMyH|yVv8T9D#MDJ;EYahUKTLUlD&-^y z==~s2!+;1$uA1$WDHRuWoSFHwdA$v*jiQd(v%o2mIH1t8tx6&+y>ca>->p2{EshOn z4{+3BpWPajhYG^YK#Ux^b945BcWO)aYGgam{hU-ku&vdo7dXW!7NbgswIjDW=jtqQ!B%}Rt4^Yw zu$DR2wA=Cq@qV{?dTeIRVZGQ~+qpsb{&|aGAQYznqTDxjx@rX5PHH{9+FChDK6@{( zuoXtFwR)8Fb-K=Ui4OBXju$Wps4fxJsO*0SvO>t3Xa?*0qJK`jLV=)v)Xz;TInDXv zX*KmF>izk8yU>wDVfT1*Ke4?|3y3RpKYluW?Vpa98$GF_kn)S;!7eYM{Ni-b-Z)gO zb_G>@JUG66SXD;QV*V>MSZ|-2@%Go<{k>Gi{Fz^+077!z54ZYv3coQB1?^;1iW9kh z(xHJ%oW}HYbca-reqS8gD6@1y@u!ji<-QZ;2Es^p>z+yU)!jgut&5!NR2f zq$);)Yy{LnCgweITWFz+Dsj-&(|lNd8&ZzS$&758POW3u)O5n{`&Y}m*E9;?TD8=bB$ym_U)GQk;OWi^NyRJLR6B8g zc}-i5tx#XIrk|HmC*eRa^aAIl1pV{sisy$oAdwm4Vb`xKsIFxEWQ?E5bUY#CP$Jyt z$zu7rIR)PKbB%|8Dmr>7lu`s6D>JYtPA)->$^>q0U;p!|d2$szte83#d~=C4AWPhc zM1(*W^Xwc%RgRmCBcNf}ka~5~Si#e@j5f8_N13L&>cYyq%85sH9jqfuq{TV~DV|fn z&BH|iQ(f1(SYTn!)7>{qK`5tCHWeZ_*iDYONbBIhL7XRllsE`k0C}V)9;t+XbPb-; zYCfgaa!R|pg3Vf;PG-nKbS{gg&0;l#2sB?78#e$b`)V)fg*w+=J#9|w{bsE<&ol{v zDd~AUE%a%Wn22`fmpUV!YQcHE>35yZoN(f#q$G);#I4P!HYc=Dn5gj;_>U1r&>WlG zs}1a(iBXGxyN=qBtRmcNrkmr+D#PstB&=1IO4-ar$HEOqiC6xK+s*vzS|@VDuHA^q z@Rse(@@}~O&nI_NUf!t}1s<77@aXHpiDf-zz$NH<7WIUs=fyXl~J0UmYJxpk1O z@q7q>n4{ouc8?!b7*tK>1N{=3;&buozs8f(F^e95B&%K_%J+i=&iX(08_)-c=DJu( zAp*Ww3*lz~SYe8G{}%qCk6VM%NjMw>l-4?{HSxKOp0NSnQ#z~D6@ zLd4N#j{}m#KH>%o%94&^nA$0k6=gbcg-9m;OjEW}zXVEq2StaXCPE0Np-+brdE3M9 z%ScFnU%-LpwXToiD2d0?(wa~QB+0TY;`x9hlL_eM%>~0oRhbS629eedeZ zUywvb$x(a`zzc+rs==;d92w~)8J=&tq4+GsharGgqaDsWaG&LLa36eKpR9y}dMv?) z_#M&$;3@(}(+x+9Jgay-xs0b{QDQcemj~2;!FM^yfvnae>H;LKk9)el zpg%~GwPl1X{EN-T<;jnb4nnDjZL(CkW?v9{In{G zT}nPv0?_UF{a`xkO(ug2qy{=HB@ybonB%Q9p(&)0Y&E479x@oasKc1IsE%yvKk;PU{r+v0Wtx zb4cN&O@{utJdio!dG@e-mdhf47EE*)hnU)gkwlB62!*}D71iYW#P%>dsgu(FNz<1P zY*4QBaJzzDH9-Xn94hB$O>fQ|vZ0}l_SF&@yIo6cU-4#&!DTF<4@h}*WqXesu-ixdW;h@Adm{+KWR!87F{Zgllh(x% zZgaZ>_g)Z)lK}-bpqe+1n&Juj-+lec2{Q&+OpX$1EG<%r9tU~NzS&{= zB<0FZ?JrySmQz`n$KTk05d_NS$bWFS3Qip{M2vwMGhPCt{iNpo1QTVnCN}3uD;->G z&9AAkZ1l^|`b|e_Y(C2;G%ngzygfd{^COq%h>4)9S@XEqKkN>Tw^71FhX8Wgc%Z5A z{unXU`~o zvC!5;zL0;nd(!>UE&TJ#7v5`GO1-ez6 za;;qHVQTLW!|ODm%cS01Y1!vD^MRzmsL6Bom=^!=+q>Z1oOf+!-Oc4Ju)1eMC}1ml zgu4CrfJ+9h1Yfy-g|BOh+bd|QQ7}dSGw@`L{*k``Ye1C0@A|g^yyq^VFFHWil5>?TgWp8t$C_`>T_Yr%Xa=Rph)f3wk)cB<>X?Nu5BWF zz_|u)k(9J6@~6)0fBePuKZm4ch@=VARH;SXG_3+Og@zgEKyd%oeC9rUhlhjbc5?{l^3t)A7%v{^h3S2i)Fv_)zOSoxbD z`d3fDO~-!Q~aeSRPmGDRs|1sWUl8N?caKx!_51gNR{gLxj zTOxbcjv{y6+m1!fcKlTaDVh&x$KV7d->f5e^BAIzXop^DFxF~%y^+x zBvQc)Gai3?2g>@rT4@xizNW_pcCd#^q^{!6*lD5{rx%E))Pg$0lnwYg!y6pUfHz9I zn&^Px{V|pO5rEs%WpT=BCw^kOe$bRkOQZyHzy#;(M@i9AtblkWNfnqe3y(}_RtIJ* zFucXcJpcmVf4&{eQHcmGK)4BL-Zm$Yn5{La%UesZqe~hDlLn3c{5)TqJ@HM1($@$X zkda9teB5}Fj%x8v;8_Pb=&9wT_M>Gh?NQ6mBG$PvK-F(}wUn+ND98E4=X0J8fUEe|-`-`cJ?s!Q`TB2ixPF*mPim zc=B$Hz8F$#Ufwf6>FDmpwjA?K3%^-uSF=}*T(BTqJBa2DGhWW2`uY%q20UV)#9hb= zL_>KCQwnycOGoQ_6ET53jI5+=F&APe8mmdm%TPY@wApy|a+eqyJx!K3Lb_+^2II|8 zZdwqYf8refb$s3SM8p?0$GA++*Ndb55=IuKmLs{V)TFT`dz4zE8(g5<938zdL=iZQ zN~QG`3GcS}wt;sN_IEJ68}uoaPM=DdLBXYKtxn@q9NoiHCLFPnMYlvR02a)Dg{WG1 zQFJx98c#pkoK=twX7xO3ITEg(Ijk=vpYm=te=upm!#6iAqFQQS7Hhj)7P-lSu->%% zjHr=UDJvUWvJ-r3VM9Z=PRAm0W=a@gabKW!NuZv&v|#@d1iT$x%yp8$nw~fvE7WF2 z#x{w96>j{jG7_tx^nbwH?V6rJJ!Rk*c%_6gcutyk81MuTW3;~e<8HQn0V`H^9hwuwqceW7Vp`~KS)L+Bph5X zJ;enkYo-EvX8NF3qhl0aSz9@PmF>)$u|xos)K@eZg0J|62IYOm==-jt=IZ%o8>$p# z06jE#oOH=8yFZ+VoeDNV^C<9&keu-Ym?!eEprb3aE-1cti7SzE0De2ZRL88FfBu|3 zE%7BvS}b|t>1B3*x&GR$AY7ld)WAEq@AweB3T2IUQ&O3$2(%F%e}fEOa#Bny%B-n2 z060AB!O;Ym3o8^#UL6ahN(54cZ&6*CLc`!8`L;ip&WD%7J_WFY8uAq1)-zd06DJ?3$e+A@aw7*fa zKPjU(0mEIm1%HDLbcr~4Ct!x-7WRdCAob0zK7y2G2gyFf0q*d@%z3MS)Zrg z@N)%yF6S{=H6_(lJP-;}z_FKbAY@m$qfEBenda{C!+Hhc+q%KKdwkcl!!QsaZ+2EN zhP%hfX0f$imD4koyGKwNCu%Fy$6k1NKt^uh~@*!$0?7Q3JFgX%`gr` zsv!&t`s3+9=Wm8ee~d+u+$~$r!Iz8;d*8ZS3ObzqYUxg!?(7sxt=-4C;-lXh2@N;r z;bvwcEf^*{z4~C_F4#)LV*HJ_=kw`MNm8CS-aj2a-6EKr~u@WH`KxvwQAh2mdSp%}W`_{Gnf8D*~p^bF9Z)r|UmHU?N z#DuvY-`~q~C?bo+b=F{L=ot?^HDqbQFzHBwGjJDdsbSA<4dvJ%2Nk3=-#sqZ@06ks zFCU0I$UzUv`@0QVr~tb56POV#U`3)b=zW4@71JuITvoFnm|&?83_!z>sfIKZg=(9k z^yWFbTenu(e>xy@)*+d*cGno)cHgc2HO5!ncWcNa1;#*=B8#m7G>AYZ^t<)1lV$@s z7q1%5w`{@^->p9eD%lpGzP33~Rw4U}4U315kU`x%P2pQMA&iA7LMO9QYDs|>3`>Dj zq(Ew~+M#ao_T%p#ut|1oX3RshvVZr$djfY7=*2_SBP4(p5&VWSE_nEzL3TDrO zvUOK?@3VHqm@FW@R5t% zgaK-7IDp0D<6>%F$raKHE3}M@bt*Zj5`h@&1afb*aPZiKx4%LZf6Qwegv>RhFkJ4` zf3v75$eNPfz0cbWmxmZG4>DXHX1KhQ;qn*QE$?Kv{6%)lUu3tugWd9%*e&m1x4e_x z@-BAEJJ~G{vs?ZWyX9T%mUpvT-ob9FW{BRPQf#P77uc3*xT*`c&VJ977_2!jMr%21 zX|{Hmk;Nzlc_ywr3qqEWh6K3}!JuZtf4A4Y`OTCCKSq#EvisxB@eW@M&~p+n&fXvU zR7PH{l=vFr#MqtCXZX-vk_j#VzzeaIg$R%kwrn<-o1MDkMOaeKjU~n`;-?!rP|kAQ z>rY&Bz&#PXr1LnuVgbyxyJzLTl+$-fVf8SGWbfiXZf0{%Uk`P35MM4dz2um)e_S}0 zdomC&7sJiw2~u%yPma4X9Zi?OdB{!fF=$DQ=hVAGC?Xo%FES8^L z5n|PTfct+>jw}}#7h`dh*luhDP+!APcyF&n^~CoQe=GDHdfcs=9uWxNOT>AxdL*YJGPgrT*1GIv*c@v+spf;Cp`6)nWamIrz17$*)>ktiW%ArODu{!m6fulu_N~y4kF}s4_H0y5pgL z)Ai2kaeP=SnZlV_!A3;SW@7|lBIVNs<5nCdLNT%e=Qrf`7PH#ng*$x%XrU%zqRCCp= z)(hM5CSoU6^|8}Khr4MR|q3$_+pc$Z)!e=Lrx%&BychVB+A zy+nL}HNF`1Sj6xKO0RajIzEHcat6T^+%8NVYZzNHeP9zVMNEub$;9p<5juwirI6;y zpcK-aX-gr^mjNl17g0b8aZWAdqdGNGsLuW^g??NLK|;v36e`mqAcY_uVTTj~B{U?3 z$|?&^x+RQ?BI_1Loba+k7?tv#n1#s)7AAbO ztP@KZNgb=KwWzH4V9bN5H4JF87sGS&Fbr(d5r)*wR>$*4e==4_^41%Q)(_fbN9V!_ zir1%m78>MOg0iVrOmuwEFYY+R3vt8h=)JP$1B^8qzA%!TA;|G^dok{d4>guiOrzzU zh#6s<&Hnh?#cnAs6#QuC!ASfTu@X4bqYK2H5$|qaqjJi0s4uz9te+8Zl@w5 zidUOSZ7w$^e*h=5`5?0?erz`8Amh#^O}l23rav^B4>I0T##>mk(Y10F71eq+bTArR z$vqr}WnNp~q6mpCr=T}y(1`BM{}`t1n({^i5ufYm(mMGKw6 zlnmdWHvMLM;?PrhCXYC_)5U82baXM&PzapuC-yH)f3%6DnLRhn-mR(4O!R1Yi(|-%;39EXurwPG#;koD2t2Q+Um+ zs?ut7fBP$VyfQ}dS}w_&t2h=i5_zxUL<)#Oo2x{F(Be`h8ip2CbMaL(12fRYH;-}N zoYD7rWP)Y9iL-0uHZM*!lIdd40ZI%IbIbW~em-Jb1U)XPiw=f)lE|32;s=wxOca`&yz8sY@;F<6+Aj2K9AS;+ z(LUyB-T-jDvobc8M=^Wz$Rr-t@+i764@#t#s%e|VL4JWrTvd7|aW4e&xENAp znZ!9VhN=PY{jK$;7!RlTd>GlG-7>rV-gkfZL=33RtlQzCZ<-)9TdG)^#f8QnH z8=v-i_!dPkm*qi;X2LMCE^@st^1@x$R*pVGIwqr0XQ|Mt?$3OrzLv27Ix{7$?N#mM z|HHmTb`_Dmq}y;J$O^4f7Lhw{brfOAg#uwBG6^mR)f)XVnM9kDHkz4@$yGSj?qiCI z$l9o+uujY_C6{ROcIAa3^K3=te-@dIl}>O`sS2%@7M`%a8efm??F^r${A(h`43%dm z+h9@I$ne4BDvUD(NdrhnM7inY*$2X4=Cgfc+-kt}X5aXpH~Yr&&Oy(ceWQ&a#_PuU z0uM)oUrBkQ0uUnlN-g?IOga?+Eet5jMoGBG^8xLo+AlVqQ4x^vW{>goeCmlr&hhq+%7IE z3L+O`?TLOz#^UM|ypG~YaIgo96TQ#NqO6=n=>Z9)D!mk|Ow(*2Hk*pv3^%*|HlR{C^ry!GRWvb^~$EjlGUq0Ey{JCNsWdf7B@L;N~qae_RuWo$#$hZmWj) z1g$wEyc>4SN&G<`jkw%KOa-e-JZ&TGY8x5+|JonjTnzdON#;O+k660s(BG{0VM2Ia z@z*Q)x)3A`CWMJ2JxC(V@LFx1V6F68h#gCJ+zFVNu4!Yr9t+3eQ<`HO-CZso*PCx* zN#mX64$_+3>!r@Sf6LtmZ9kUnt=wbJ{dA~TU7gmD| zKiE?zbL(>%es9#k8*ezZb8(K}yjrg|>#cy|Td%uc-`Qis7mcvb;e;6*!YHvmAc1E{ zPw%1xrd;qpPTWMrUGW&*kF2%S))ra>&6BWm`o1MQa`FICHaPGpt#wu zqa+-gdwq+=rS$2^`m}uLZCAuGQW?|tFBg`}13t5AJ#c6332vux3n1(>am3LblAurg zN?A#<90Cw*f8@i70WskR16<9AF?@%0tdoCJ`1ewnFZqC&d7Kzxeh@l{+yT4j#IH=H zQp`9AHfq7;1`b8`uXAt3QhtRxX*Tzx-6u*`$h`Cl+^nNFss`di7`{y0H_1i%M#K%> zgEt!ydNH|EfV%-Otg3Ji>TyD+Woh9CXo|RsViU<7e8=!pCnbNoXP1dwwk=#+OAo+JL%0LW9aQm(`*#y#y^vkbV)8 z@RJaluGamNjCKFbUa9)+(~BzChZl46sY=nVf8fB&{Pv+!jViVc=yFlB*?VVMbJYi# zFjVh+n$2+kvTpnIG$4TLnnaNwI^NhE)Om@@PyY_CM>_cqVvDVBa|Hxb9i^a2=%qyIbpjq!OsRG(f{8H z5%Z$sD7L(te%e|-;cPXtMoe_nP#jeOrlyZP-Y0pO!d-cxrxJt{0i?~ki81TWRU@7P znsT#9pSaZ22e}^XTB3_;9^ob6gh}Dr!wdea*>;0V!i-s>& z;6$vzcAe~i+VYzi%dY|h(D98{V$j-K{>)YC`t4z{e^@V%Hiz-z`O2PbbT!Pj%I2F} zO82Vji>Kx*Z@z_|tC7@tpgb@AY&FxQ^+99@(so@0c3?$*%bS5fcN(NN-7)@Pe??4s zbG8a6W%QEOB!oPiobH9bQwlXprlwyn6fHGH0a5|Z=F{;ngWmOp-y-vR>;%kB*QP@o zpa}M4LzGq*21`Z^U|gN_XE@B456oSzshye2mk~)`yt2@2mb{o$+`!eH6}oK*TQ=IzB0vfk-OC<)tvLt9D< z#m)e0%@tOkJOW{iiW#E?A!gu2n}HFQ#yGrwKbX!9ML3B6@25zMv-$GGfB7a4Q23-y z#3JVbh(M_I_6?xmP1GA++kl1FlV4w&ju-)>;q_oH;Q;C`0;w(3Q(SN++?YETO4LjV zyEcvFb#|nwP?LMs)%d*v8~iGOiPw!^pPG(%4p+U|FWS8*jVR1Uz+C@t|02|_Ti!)& zucK5nakrSxt6%9ABaWS4e;0nUi%4wJz^n(4m96pH<(ArS71xgHZ&%przg=#5ItoWH z%SfPuh^3fUEin!v9poU=LhNdMF}(cvVLTmO%%{EUnQ_xgqpq#-E7_cdjQonv){u2h zfUYm_$Z8pxUJISD61*mjV?7Hk=Ej$ovw^GNr*YD~*e&;GZ^^qofAObfNyaR8fsQFVvW6Az}xi*n#3|3Z(ejT71@WDr4H-@SA#T3&GeqUH7GFIrx2-lF9t*IKkynuHcDFFR+^(u%VeEw8rLqOFT4xM=G- z2`yTAM%7-m@{Fpre{AIu6>=Bz0dtJR6N&ja=+?^GNFvQo`Vcr7k3L>Zdu)M9(RTk+ z47HRUPj3hdEWzFq-)n%`3-$@s=>oG!AI;WZ>4UEx7tJBj0c~QQp;s?!CedpqiTydo zh0L<}X;ppi8&DQ|cJ@j=V>ivRsP%5xnx#?Qt&#COgpx_&f6miD2sKkp&BUQ5C=)zS zup|HUJYS-w5Ka$%L;>^gV~GsRB9UD$BuwQ(0wEdjeDK$y4v(Yb?buzp5QXVXx_B#( zP13Xsw706Oc4O*YD`9EfIRXu%!{}JuIGUW;PFol;5Q)`=OG3@8XjlE?n6-n5n!m*U znP#awXak|6e<6tt6k#1C8Q?O|oexu)4lQDu`Z~~u4Is8hy8|JX0g5|EVnZeEu83p? zB<;YE4U<{j7{Yq%GtYnaRJ)z*Hs5@|IkRR(;s6xJ6FF*wH!D)!a;_?e6TBsx%PPxr zGgBW%2%O7XHH5Z+&BBv7Kdt@@ND-Ot0*KSAqWI~Jf2sp@$Dcu+k@$|u(inR-*BZGI>HkyhtGc8JkArD4eLR0M$iqI~wXclGC-Jym_O^1x}>0mbetLuT7mRZL+ zqV0jWe+)Tly*X=j%-)$2Zp(#$zn4UbHv0Jok>jZTh>zmfr~$iGDptL)D%0 zNQ8hDpUYYRBF`(WUm9EGtgjILemM9r8RHGbf8bXcbJw$%uh&nH4g$YkG~3;y|<=dYuU%di09eI*pTO&h&Lh%W67(R4-Mf0jtm(5D_@3n&pFxo<~sJwWTh(QqIrOta3HyuMUl z8#f;9vE+GZkzTW~A11`~+Q`*!T7%&k=rF;0d*}cZv88?Xvee!pCc|F`qxUk!s>7d0 z9i2_Q{O@`u>5)_4JP?sgsgX<$fEbmsObevc7Dxd#Gt0W}CzKLA_^QL@e-w#xKhf%p z2O!HYGs`asC#x^ht1r{rMoSIMbj)U}+W=H)I&IH+Jbi2C{K5t7_^|%8-g;E>=S-dP zXN4+R)ta*nCw8Vx`?z5Xdo~Vu((X0@m6}dv3y1fM4oueWsST7{9cko+F66Sj=-76{ z7jlBT&~;iS2B0iA(l87te*#fEqh-b!4HD$e`|tGKR)#KVarE!Y>A%_-O_{Ap zR90Xgi#S9|am>pK<1Xbv2=8n6yv(@gF*NP!LhtNn?NR>=lq#DCMW3>#&H9wXzRXcJ z;TX|O84(lW5f}s#ajjhpGqxu7&XrI!zJVFO7!Rycibte@xmyvmfAVJA2N2U-rcHAQ zsvyq?Z->`5Wa4$z0!U3)=o@)`Vb^9}bFVsg8}~=!+2C^cR!26@%EId)08+Z0DD6;b zCe9cuuaf{s?RN5Ec;VEG5lwf|0*KuXKox}ZsrVaYm5<3bgonym@4dF-WtERfx7I`C zbkH05rpc`GaT$iPf6?h!l19Uc#gSF#;odS_w+%_s34ct`UOAQ(4@!(+nf91NcsXW6 zv_64MTK#zdsp-m`JZylh-Gc{_x4HmhH8_CUP({0+5LnsjY&xDKQd_kE zxS+vgaacS;q<=pJ7-Y-U!{_-i)nOiIlXkTv^3X8@bBZn4f)ryHK;mM(e%HcPjCtRp z=m+8pb}9j?f8z46;GEPMN3+Bbt-jwfZ|uJ3GVSeKog~z3>|4U;(cRd$?-twD#stjB zIQOTYUOl4#w_CL{FAwXzWl!WSA6%nbb-eGlAMx|E}yo>HmjG)VWpV-k+bC#0e75Of)EqW^T&8x!t?khx?L?i zuU|#y^eVaqDaOP+c6i>ISwguEe}LtAN_+>c_baDQ{;uFYv2pK$2=4W3;GF%V-u138 z)GiBRe@=#oUI{xCGsNtK*d%~hh_A|a8oML@s30~$d<6gmwc136plVbgxYZ=4!+uXv zC`I^G?)2DxRepNx9hc_yIHB+K2&>C~Q+|4c7+#0%Vlz_07#}ZLS8k_AFqgDz*`lMq z^QD1@Q1&Bswo{!Rl>lzl)jSmExjG+APLG&2e|n+6!p9Re@b#zlNwLGKcibx){OTT7 zTJ;~@lgsH5^E1O(fS*c|ag{2E7$0^qK9E02ux+QN!kY6#v-oV6;}dy>L;Ib5iZA3( zkNTaxgicCp`t0m z%#tk3i)r!#FJ@7Q7qiOa#Sg+jlK(Z$9bVM+A`erY2R6-JUeutq0X@4_CoxFt>nKlP zC_bji>e=5T?X88_aBEUa2@h_kpX?one^~FZL>-H4Q=IyT9`m^apdpHPBaB23Q3i+3 z8pUDt@LFIw56k(}{XM4(%)!*`ZYa^K#Q4Wbm;5LlNt_DDpikq=fHFj(Mk z`;*)0V0JT_&-B3QrNRdJKQi*=b-#NQ|GR&K1k6SdHsvp6MK&&$RZ=#-kjMz^C(2wEl>yqe*i?56moZk zptqO9Uk9S7g9Y@M-5(Z9cXVGC82Qmkh4SW%+Hv0^WD3Y7eASyL(jnhiVXSh7w4;?v zksYsG%It{cQYJou_zC{D5U4-`Sv6u;&9z+>VQ$AabM#zpsoNL{Gl`SkNhhAsJgCa% z&DYaaqt-76b_G2QMy@tTf2h7xN6|*KMmXSSkBjYK+{f{D`~rX18yq>!YMwkn0nt`e`e*970@_2TlVJ*{5QqhF#76`)P5| zpOmLZM$?O|Q}NEy^&b!AEW+qknbi7(`*N;z+lgZ%9)aNph{b}}e zN2Uxd=<}4bG%4xhg4j>yQjYLsfcDKH)Dr}C3IO?irDP2O^ih1T-P6hDU&%t_0GMn+ zgq2M5#}O6D<8pUsf2?F4l8?p(@O#NMzwAk?)LBeolb(iZCEyp=6`FM@a*bQ5*=KK} zH%XmX2?EQS<$#Dr3@O_UCIV8&pv@^>ZFh^pvtQg4=5-VD4bcmHI`<_^VPIZVkOIdM67^S;$^X7 zIHOan1f_-}Ry32mBvx#}(Gn|`=xB=-BRK+MMYB&ptca=+Sk}Dyb%O6QBvv$-=qHs) z^j!wUinNf+e@keg4w=2#d@vpUbuhi1&3p43(V6jWK(V!w)R7{|PJNcHwjC|DpPm+< zn&E|$v`(EiTYd8gL}FHSqU-__iK!n5V1rwEEh2gqJ_*R8uXbLjZ;nQ5gcP5Aj;Dj0 z%IayYy%keq8Il-FX=!3C?N_*%GwZpM84wR#^i}lZe{aGXRQHq1Bj7-!Ih6f+guE0{poNr7kBQw zCdzN^`#)sUt#|v!2^JlfRE`vZH#JraVT{SUM5iJN@g`Aum(yltm7xv}WwVF%y_mA_ zx%Co*f7@H27(<3iZQwYs43x9PRNgi;MmD2j2Ry}Z_Lj@1M;koL zbg?^~7){z#e|k~ znF10C4_B8k&pNk`zINyQeO}n`6~3eMAyR>m#a-}2meClVFnNj63%K$>rpYFdDSZQ( zf701(jbpVEremE_DIjV$kXvfy6`KDs9$X=Vqxj50m{MRWJpm5W90acoIHWT&X^x6m zr#VuyzaD&OnE?vCqA!zw-+27*y>;8FsaZP_`!R0m0B7`e_G(b&U{Q3>7~<6cr2OPW zfn~RbH)kIAF@MTp20wvG7(`aHb}A^ye*+;5og3&D&wmh}FYtNKzj^-Ow|qYDYaVxb z-|%;U_ld(pyf2TTJT7Eb6)BG~eZnA>fYh4zix%$-w0Nf!?49BO4Sp4gPtp4eHQqTn z)D)CeQ;inUvD>PX?%_p{dIem`-n z>FL}T>M+})n_1=ZTCJe_{xFP40{v1Ap+P2$hu8DVUu9mf?^j>F%eimBj!xJ8o9TNwXyo+%^SR|YyxiY^b&UfHEWt)`AW{m9=~c=H z4f{hhD7nXnFM{_;8$hs{Yo#iWtWm!mU)#PY1;#Ooi{+ht#lL!PIijdh^P5l^q`b}Z z`{i-Ss>^dT&=!#3Uk4yUfACu(#Aqx5jSINGM*5~EQM69)?9vunQTKAC4b9Ic?P?Kx zMWVl6dpG;`APUTqkbQc*ckcJ~fUJs-?$}g~cf-%a(^vfW=8iwLvsjxN-KBnA+a4#+ zOBPK5L9RNXL~s`3c!Thx?gpi4fJg4$$H8Rk_fds)G$DF1CQfBRo#FPm%@+aEEQ zEf4d#4)VAe-cstEp+T-<29*5}pBlXYC>|4q_LwNhtKy|LiD`3odp;UmUtHc? zTY*OkxPLun=bL7`8t-{ZFnuhsGl;_6XS=7vvgz-($J1haLi}sGsA?=QZu^oG?#-F| zVIG>SX9!H_a=S7`6!L5(li6&h5$rbS6W(^NYoH)YGBVWdWb|= zEAX;Momt^dN{Kj#K`sx|i;DKbul9-Jn{$-FaFyQ5Te~y;`3yYE*AJ8)T+|H8&G-tf=u7 z%FTY?97fIkf61BHX!qP4rebR`bF-#l!iN>|<_@~FreH$|Noq}!I(LR|1J?#vt-j$5 zgwibqN8uw#8DUD7By*KAdOYML5QKrl0fMTGPbP!}LrV}U?MiPuHTDiGY1XJ2T&Hpq zyi>GetW|p^*rC~~esWh_k zHnKE$ZNSgyb@p`3k9kXZ)K}^VRwbBd@6{yLHgI(b$1fW^74S@h=Kv1(zW9=<)j}o| zm%2rze_M=47kIMcHbP&C_EhTl)+HFR!i{8}VwNfs%|l=@;zps*NTNje-dV6q89YQG z8uqVR9S9|~ZKnh?4u8^WARS6Rz*6S}EYn0ccnd+l6c8Z@|ATwL_* z1~O!A)+p1;YB0IHR_tNk;g(`fC^L=gEG7=1eLYUqmSpj>}BrIm@Vln!|bj zU2iIofL~B!&MwCN;q~QM$|ZGngdgxK1*e(dl)%UaAV50xZ)x&ma-D>9DNWk4xU|w_ z3Rq&mtd}2BEB*o)=($}j0!SwnL%>l0vM`WmF6QN!TajwxR8`VSj0_bkH8xZc87M35 zf1%V$a;BtqvK~sc%->|&N@_Rhp+IH^(sq`YYV9i@d%p4lASft|t2``Y-$O{iwdYY9 z@;nkKVcXI;9;HFYBW@tMs!GfU#aR)igeffEDl8{h>*)Mt=}mR(M& zMf*x)&u}LIf}lztM=)HxZQ&D8(Vfz|WdsxuSt8nx34z@`kYUA@33L&ER}~Opk2=wt zYTVvb1v)j*XMcG*9{#df-~Hv&a`~6FQq=$Ne))eNl^XG!CVxr)oc%fb%b)*jfBsu< zmz$?m^A}aS*suTcyxu;k^VFXo&Mro8MUcm@a5(WR8ceK?8nP$Phga&bs^Kz%%NedP zqF$+)A7_ey*H*73L01f2>t5fD$G=z~j|h&Hg7}r_1ejoSI-WQiVf>2J0`)f&_+0mF zgMVP~g277xuY%xg&yHV_KA^A>e{q8(?r6YYAYDNHO{GDm8w@Un5Y6i1d^+g;Voidy z0rj_#Hl@*Q{5JBPirdser%1Q?aD8Dgnle38P0-X}6tY2p>*2tHXS$|B*tF0SP#xP^ zf~sS(rb5@$5EdXQLfOn>nn*V|yBc2)A%?TlW5&bHWVo4O!0X=Cz@vZ0f1}N0v{?}Z zXRKvB-b}`unenP)`!DkrgXKJ6^&uaE`^;s;N;IqaDs=i?B&G`&Kzc|`53|AbMQ`@; zx^GaD%Sw|u=GIz!2kYnd7LFdO0zBfgwe1=Ch9I~nW|~}>Mm0Elcky8&9Z>F0zXJt8 z?F*i2A;f_&TH`}ga^$ue(! zZoawJ+U28u-z5&X)CqluNnYTMie16TC|W{nBKMo4h`Cc(%!Eh8D955VkGibN^t`lNR~yy}4&4OLhge<#L03k-98wchr& z>qm8z^j^HVz0e0)9HBNb2?4MaEk%lQ>~~7zt0ezTpKgv-4Vdn-YP0Vj8uf7uAA@fu z74Oo}9)@U=q$nhHB_n&dYPL^Uq$89*JZ~Y6g;;45{djXJ?!SCTu@v86zM0U~ba0kh zN!UpDhqg1zW`F!me|xPL+J^;-%`4hM`>w2>2VZs4X%h$L&6$f3!X0lYWGV~*R4i~R z*#S9>y$$+-kc+PB|D%zcreWl!>CYjT1!={Cl-%n>04#JW5jq@rzkfczC2+OHG3%mt zy+STNA40k?P8FsUTARbEcYorX07+z4l-C!1SJWRALO}?Ye@2x^qpE0+jOmUxQfp+{ z-!d}BNX_Dh?3+OdmOr(~pE{C}_4@PSdyQir9Lk{ktKHKPNhU#E9zJYWy(MLPXphV5 zi9XD7sLpt3K_Hezwa6m&p6`#q&}p*(4-Z2OK73ejSG#9g1{v%@EGJj&g|^CBEx?HY*Bni9w1b2!L%EF67iR7G zFaktXk7#vvfn@?FYZMzGq9z|90)vYs3d0Q^>^d1Ne+AvNv)f8M07(uTmu64)y5&)n zG73=i!yuJ_)Ow)2W^bl5b-I4nn+$lAF(tkJ`fhic?RO{V>55y%=>$cLat0R>vXZou zegAB^jMts+H7s11>LAnl23F138XwIij^)@zVxSF>2!Kcd1ck|dm`pLyo}o#M9#_$3 z+8oiDe;v;n9IF90DJ;^v(X%PjWO;0k5X6+pN7Dut*X*qWV>{pH!R9j9Oor%=4|%3= z#}c)NLc_C$V%`)vW05BW<~uwNVIp+9Y}E??#F~FNmEy(V{N^oa?MAbM?*LBMtNDZ4 z?427>DZ{;99<>^#cV_k{4!Aq48gz$N^1wA-~OIhMdD1Gy}%7A`=ncu7hXRGtx{1`F9DH+|@1Ytzl zXN5){*zd!@r2)oIg0)%cA-$`aKnOj-G^9jM=rlcF+>M&;C%pwTdf{UKYH>h+I&1e{ zTli^r5Ll+{{cyXy*{_&63a$GcK3N`CG5Hk3p^sdO?cwoML?g^m zBMblt`L*c_LE$Oj?5)fZ^P*MGh8zX;_PfOauW`Ht20s34Xc8@NN*1F7) zXvu-KQ_G!)I^@raa4t|JJ5@r3Lhri(bgK@t{ZVf=>&cjEd_JxB9lf$QfBXBbI;Tz! zyCoj2Q?u>d^*2YgD;*ZDW`3u@?PA8SZ+8*tDReAzBRTs|ha;zaffNtC$R6$v=Zod% zPX`I3C%LZKRsv^N$3|tWD`-Xu*stE48AK4mO5wc%Z@XI6qU)83#wXmvwBS+$XRyuI ziWseu{|{k1O}nve8MF+xe?<`x!)i>H)mF8>oYGnc=HP6>RR+#rn;(ooF>-gv4D66V z&ctmR2(mpI=)8 z+Nf#@gb)Cc)luu!e?h?gAhfKITB{CV?fooY^NAuWhvJ_6KS&fS3;6elB1~M1vQrm6 zQ8b9~d99UC0`3Q(6R}Vy+CrT~`V?BzN}2Vi8iE0$OR%n$ZK_ zQIa0L9n`_TKajMf;4p%B>e+@5j5dbs7(|4j~KV9n)^6+_k zPdEdFS1aVzCRc=0$L#a*ul?R=bl&U#BCz7rm1?i9G&U|Z)P{^Mg8Wpwb)m&AWEFxF z?)Z7zx_52qT{Ckq%v5p57M2{?P?KPH=3wIE>Fu)G7g^|UpEWxMm ze>Aeq&hH`H+H$^&>@@wyBU__K*f%rmTlvTqVDYB|U|9Ayv%!=yutQztlPd->x*Wy z_+}Ne8GG97n}rQ7m)($_VAN1Q?}l&R^~cw9h~L1P?=&1qBBPf{0gWCJJA|Ap&e@)~1vEr`+0tV@}HOn1%hsIWnQ} ze*i%c5v{paBRD_+*c_QLW$z~cR|U%roB`V9ws+d!p@RmMbV`{1!b60+GqPlzhu?~du--A zua2h&%9dTMcPf$3u`9<+h3C1WP@>1qvlPKXKC-Q95h~hKHepxU>+v=DJ9(=VfBj|C z;Kr@wF6870P^2*_LQ=nDg+#)#NzR*hz#B%YoK~`r-*ct6&TEPdzMee>`sHxl zrqbz|!*y@&b+y|!#H+!+!K~m8mofojg*(`Ug5z!Op{ga4DDuw+4H{2JuNq?DQ1umE zg1PldH;GuJwJAt67t4P_ZpocseP(!Kn4 zYTAbbyVeQhV@Zq4+1tb7-sxMAV}DoK2Z=gqRqNY!b2MC&5AxCJn$Lu8oz=H>qvC*E zj7BDlSk&%fd|0iwi;bX7Zdn}EGo3^kAYb(mgy;j>S3O~8bqiQn8hzFOP0638BxN!C zn3r?xF=TsVzyRGH)gGNcm%ZPnx->pyc z=BW6>xUGoE6K`RM+xwl%iL8NJA3f1W<*6n`An5=~1W0Ix;9by}fktdjd;MP!bnsqZ zQKXT?-1`xn0uJ#0#Y4pE`G4K+OLLeT&nfYX_CLx)D`aRKE+_~j4@~u?3xdN;CRgki z$8+d(*E=i+U-99yzWzuPzWp$r(C6g&G4uvw@~eeFv3^V|Dam2X+9@rK@m4JIT+lco z>|yaZa&LXG?45h*bMo;Rc7N9&<`D|L;g)40l~#Q&^>W{ZkfRW2X@5XXS5jG7m7`W| zZPm)P*jOk`3-GO#t8?>%7%Kn4kGfo zx4z$bVz~6)7~1~gVrO@JICX-})(mLM`b|7V818}+f@^>Fl%ouL4L%5BG9NL4D7oVFW`8&BCyFU%I8L(P`TW2MWN%&{xS{W@H;R@ojlQ#KkC0~~#LbYn9Z=#^ zpK71_G~-+Jjs}ToK#w!V&J(jVPxT&0kvH2r-E6)6>}_$+myhnL$9dMsVc|~~huz*^ z6LblA*lld&$UbL{j)$*fe9%J)zgjpY*PN2``wJhkG=GqIUk{Oqqz?8K7zlFE&1gPU zS~$SSK0+~+A3ys_=i}#Jns1x+k)k0YZYm`}RpI`D9xh~SRRlmddVl%vz>L@yj%V1m}tK_%Gt`@#a7-n_H4YqcmW?iEg!BL zPPz$UWg<6V>l@+(;AljUGg_KZsp$z64*|%U)wb%Cyxv2wnSu4NBjhgge;#&*l#- zF)&^5M}%HgOeTXCfGo;NoJbKALZgi4^WM3ohF~CF`#wrWgKyN14zVDl_tWF{=+JCA z-8~;2vaJ=^on4OtsVjz@4lJ|Ej!92)WRq>VoBjUS(@56knX)5&r-lw^uWFfm(o+6o5y zVSo2{x3e}xb0oB%8?wO*%17&?(TntH$QeG(Pz+%y2K@~I2&-v3SjzD*0-LL$$_I`kYRiwgo51{jb@CL89AdQdoYaI=YlMZt4{?dayPlZ-#}U6V=PP5OP0f zq~1Pbw5r{~%e;}%V}7y9*~k;_#E`q~Y8G6Xj?tJ=)ZG@O*!KXE5{As?!+-0^&D)K<@yWm~isw+H@;unq((odh9-brQ`wiFg%ZNJM))MTh2cSYGY6>(j2az!b;q z4xa;j;RF${^i72MB9BgDBqr<))B+HCXoDewy2IDc5i>Lwmceb~510Y?Bto!rI|O~i zFV4N;(CEeXm$B_H2qW8twtxI(V)?VdKgbL-^xDh*?o-rp<0b!?Hyj?lYzl0|3&My% z(k8r&O?bbYUyMfneOQKeyd?VaS+2RXI=@_OtulUj)$$E)-DbRSIp&XmM=Z;ntZ!i; zG1g_;Scl+U(20RQyPAa{WG%CcvVR}=2#*&mlMBBxv!>q_PQaNzZ-4S)%$kJ9B4pL} zy9^_W^6N%{l2>8mxaHT%($)UK2kO9EV06I_H zq+VWpk}@8G5H{A%wG7)20qfUrsr&9g>h-gb~N`C=j#j{4>w4+t+dfrIA$a5VO0U<4S00ETwQ;_jCfJ6((NsX>sKZK>bv_fwDvVA|bjulR_PVEpsWM)IYS8&%TC#K<1?uHWAD z-VWYQ$2SvyPLvcl!4T=#FiF1CkiSS8bAqALsbTIk#72~mzV*$5o0ihF`fgMCYE4b~ z5n%EvHKE;ahB9Ek6{&{FE7lAXjF;Zsiib%mS%R_Dsee^zh8dh#syW05kb%^iAPBb%Sh8Y7u(o?RP5AzL#hEwR_ z_z==bX@;YgrLN{$#%v~wFE@+tdNjMWv+N}p-M!&hrMHyS;C1}!jSETgfzbq4g0qh^ zEf1(0g@2(&if*qlp!REZSk^_;!CNfKRNvGZWehdWsIhJb&2C5P$Nc7E@H(NN-c&wd#z4eHjFSnR=hd8UGCSQ+0yXIAb-l4=357AFNu2|=~vc}&i?${iQGw) zh=lvG8V+`S{qi??l`}igKIYUg8{{I$FqJEftohpG!OR*XSDd-L z#(z-&*35Zz7c568IjmpF@}m$z3sASqr^BJyF2CJBo|x>Q6d%*%`swjv{fS+L^~_;@ zO8fY0bJ)2a3~vv+r#(Kivwavg`-^6|eq3y3&E9=?u-VTa)CqC1U0GFp0K9HKEx@;a z3j(@*=Go22u`yZ8H6n0>VSCnk|_v?8pDP<=F zKpSbyF`)MUy^v-eDYTH5lz$hbC1n_C%t@s^ zyy}lQ8Ggb1R;R_M_exzG{yMn09Dj}mVqS-J1ozsj=h^zxc5!+-cqn1)zk9iH`P`_w_Z2bH-peO+K8?DNF9hmSGqo+R56ymbleFj zl?xjCt_aF!Pj@F%rSFTN>SA$f^uYPH$kgZ|>l^tN>Q8`rq%t0nfB*5nIe$HWR%E`t z9?YkM+4yG4scW-Wv|}ksE_Zv6xO01YENIuq{bupasu7ajw4%{(_Lu-c#~d^=YqOs= zkGoUjR7nVt{_gP+ukE;8_9sR6FY6U~13TNfGp7^G2{D(wB1227Hl1nSO@$(O``!2IlY!tF)*EWidm8+v(tHJRh_WmC}oXmoP<3x4{_ycBOEJ zVt~b3omW0h7T|{O#vy8dmd417mV$hB0r8?uWzhn3Ya)zWFo=dHqLCY#NK(Eq5j!|h z`?EAgUYeAep$mvtXC|u?pkY@97;{aYp)r*_|Qt&+H8t+fw+F%(f^ezw_5Y2;8M%K9( z;F$V_P`|)z(^_p~D3Q>fQpdH-423WQUWK>{1Z#hcU4Kq*6^3CRDTPM>*xAe&j+va| zY=!_B1*LEeKnCPJL(67WbZiR@#+WGeUZvoDdBvbCuE_l-3{x>eDq%MO{@n+$L-R=; z!={6`v)&baC&zo(409QNS!|w~TczXU&XvEyh=awK<`yfq{;nkzo5mHBQocVO92QpP z)_GN4o`1jZjRx1GWaV@+f)AffobrsyiCS2%$NGWBS_H?cH>N*wtRHAhC5@@jW99OS z%4;60s;6qkc0|>wZpP&?mGk)k0e&~Jk6)H>=AI3vke>V&(n#OnZC8P(?xa$Zra6G) znssnwu|(Eb6LQ9qPW+DT*jp|Y;#z|0!+M)0gMY8W-57=+<_p(XF>SP+xT|jN`k8x@1W7o`T{9;ss*f|#*}jpBp~4e(`$k~ z(|_tJ@Nli_;a1t|5Y|{D#i9NTJoP3F1e}3&?yP#;ZHkPs*)!e(>OGrh+Pb|Em-R|y zTHp#r3y2&M`X&u63;%G*=@Y4ZIIQ)Mb8ECuLf{{!$W4H6Ltc*6hBo5A#>Zm6`u%i&ugXZ<}njPLUT zM$*CIusg6Mb_DQdf4<%>4&UHZ+BPGBWoEI$s~)^V@@&bg=lSB337IbD(u-yf>3XnUW2z4=4MBIwW;~A+-n&&(I_3u7|1yadS7I2CD(<`%cXXx#tB-Cx-5az8wdc9Oj$ z*6SI{bdVAwxG?$i=ZmMq;?%y7et+SMG)|VtWODf~G|S~o`%`PY)r;e0{N(O;BCqXe0dEWxE4wUe z*&0-^o0kv8cq~$ef-8Il1N_DiobrR-4cPmn(~ov-9!;ox>i9MmuL{NhN0uni^kSIL zZ*)uk0|k2)72;V`ppoUCzJH|&c`=yvr^5;HI-&?nFkooEXpYOn+GN8p#{Xbj(*K!h z%ETsC0FLD`crEf7~ltssw1dbPKDGL=Ez*(b5Xf>w|u-`PM z;(B~NQ0EL&FdZm5Pv@^=r|f(@p1)4)qMK{AiCkSN`n^u+m|}kl2Y*%ZZVt{GW-L4m zd@V`)GJ%TkpfM-v^`)Cqw@fFF7wc6raVjBBWfSMJHyqte2i!t-GK?9UL=^Y@G-(d& zohSFF&E0Nyx;lRHuR!4Tc>&Sr?8}cOrA2m4?wkE_q08Z;vLGrub#LcDX>v^E%Hf6% zSYAN2ETF3BMg((e9e@86BJ3*^3lZk>B$SgTduMskE?=)+ROumh|)*^(8=FhH)fXH8kl| zG^7>dj~-2a7g`Sfk*qst7ufIwUN*+0V`CJ!Qu@_9W74U#NPinq{PI7ABr8LSO{Ppc zB&)zN_8!4qPcGlH-Gz;-|MvbZ@c5={Uv0Z!zlHbUXT#o1 z7Cf$fKN`;Fq=i>_Md2&q8VImak%hl{Mang_AOPth>*|48=hV93)=KWYoBdVVmZ7$@ zzf#MJTGrfB>F)1%4e7y0q4w57tC*CPT=`&|v&(Bc6JGU->lByADWmi=?W|69*lQJ$^s*>cm9z7+r)A2Wo)5WE=6VMWq zL6afu*$x%T1~AL@#Y!6u_gY_$Cqq1<=xA{~q1jJYd zl1)FYM>~gopVsfzF7qz$THz+B03?+gHL-l76?Te;68b!jH)Uaw)Dq-GtwG~vQlTXm zGxRy5yFbzi;PwA;G6Pz1ax|xT{541Cb$^O`%zSk`5fg$f*qTHH!3{HZ6|N}ci5VP? zK4U?RVH?`jEWT0^U#X6@Ga6q1;!LyTWEIXd1Cf8632@Ml!SS@X+pLcdI$jw~_WpV& zBrEJyWC=>MhTNsa*`?j3CF{suTC|MrVbK!f7ACYF@V`{h`j^;xxH3436xT>P34a$k zgh!UqV1S*3>RD1}BB|3-@C>WN#aA`@YLgHu8wEXC2uEmY5PJQF!CaiJCHxq}XRAr}2jdC~Y^&1o=P6{5Z2`~+v>aLso}HH>&fHI3J=W@(&@>XvD- ztYo)6V2m zfsN6p1Jx|Ba}n72?{-&OZ9X089aw+*_8gE`(+S{iO47Qd^Yq|2m1J(kFbLm}Q3^9C!o=F_>Yo_6L)qM5ujqRX^oztVN z1K#vt0r32sj}k><8Wm=|57j4JpYr_J^)vvPX-H>+co3xtYFf4441c%hx1!^X=L0rV z2lb_Ot*M_Qs^gA{IBdT|gbK^^SNy%k_xHz!-f39@TrCvw`5A`I91!O=imZC(fLK@{ z&K(q4khO-y#JN|4{=42(IE9duMB+oxLK67U3$+a!c*I{qRMKG1fy44*w|sgG1>1ac z=8uJzCNl@-kqJXEdw(Rt9vqSq9ns$prgIK8LQ~7+xn65(T`vg^qh{-~!08~wb6B9i zd)zw>tPr(WBIREK7r>WMZ{7DifXRw+}-wKT)h721T5`Rh%-I zei%JS`vNw zagWZsq~_#ic|*<3cInm0>K=M|Rye=VZ)!~=dn$ybd^{?$2s@K7?a)spZZoZk5;mCb zn3N?9k~8^pAwMN#=>SeNZ~(i^45%!tiTuyNZpH!=QhzQDb7{APIIrA$j*c~9u zwz;q^Wq9cTE;Xj69$+)<8ae7(j$p-6ju1up&>vWf-(Y9fr*{ z?C(5vJbykOza15usiVhLf2dBSV=%%eu{nOI;)?-Xh+@m?-Yo?9uWo?b(( zqR>Wlwi7DGw=-t)YKdp>7qaMHCsrF3&rkhUn8EmzPDK~j&`l=JMQO*RU;l*jXAH{^)b~a ziHy9aoL6ngR71KS8vIH#Lxnvq{th!+Z6UaV|BmNPYZx?6CL*fTVTghuN}h9)wdSm0 zD-EkY2hSAEYA01W=2)8W5BBo|`3Sw43x7qZWVTFG+ljCZmN8f^ohCdF7p%}=XYW4r z-VcOT)8H*DKyX8zP+Cj>CHFAAmOirJO)J4rFB!8(U$Xapa|B1dY)G<^HL4Yo)=%5htE6f)nQGm1dZm$c)MW1pd z!oc*-W1_$v>>QNVc@!qEL>SMT7Y*u8ZVh8U&je$psx(!Q-h=4T?@iD-5h^N-H1&M7 zrmrIxKr)PpDIgb!FZdkagb2Vbl7A6*{B1&yPvu}$kWE}+2z@DxiGwWH{fEVN+iZ^V z1u(zEN5w@W))hrXF#={!`~6N^gLDWdXF@b%Uh#RwXmYCy<}PwzX1GxZFwuY><~|VS z@P&Jo{ZW|XlU|YGNzX@IUKT;b6;TyNT#;lU#Hlk;3vnNK!o1Fl)J2?BGk^QB{u=W` z`T$_50R?fxYm4Iw%)DCti*p=dNCr+5W6mmsvz*$J8LJe=Dl}ucaEXR<(Zg(2B3niO z+H7TGhsjAPoPjw{z~p02N;&CYwLZqwf~bp= zP(9PD5_(Y-#}H(xAtmHVni+dy%J+opWSAQ;%rMhM^*FxsX zBeMofG$7n61OQl#uSHb=_wmm>gtK>7!;7KlZ*}n00}$L5Q>T_wPhD^iMwP5X?|vAD z&rXpXQ6iaKEhDj%N%Q~@_oS6Ta{R`B$n2mQLCxmVE7Mut)fs?EZ-w+$>fR_hsKEg` zchf&a^Q=n^qvsgQ9Dn0jcNJ+cGXXif#(aZDa}qdfY;h)lxdv3&2Pjvgjbk|}P|}tF zfE-@U=@pKzlinO|aHhSF0>>;0_v=n3)`WbnkmFjd5;CKJH{UOVk4{Zu`h(m?UTvz| zVTyIclC{&vc-;KEDVNXlX8Ew)ZFZl&>CHQ#{@?G`%f{^WDSt_U>)okoDF7^ibkx!x zP&%ENGAhI@fk)a9fH0~)(Z+P74Z&6h*2C-v!EF6^R6YZU1x2Ba*qqWHyNDItA%NKL zDW%Rt*&rmV63wb106q@JsWy+0WiR?3!WEKEeG#&FnjIM7*_K&w8Sf+wF6YUFzqmypC#sYn}9lFw9J)1`l?5+l` za_p|AaH0(baVA>~IjgyK!a-Rf$h0bJs}c~|d}+3p(tjF*L5GZv&E~YQyuC~?>t^w& z9ocmRg)dFZTV%30JRY@=M{P0E;5`ME!Ve0YfMp0qbUYm%?-bD#=i1{+*v#wtD)6Xe zEtmm~2Up=p_pOyF%SR}sgY}`0pNOc&EtM&kF9!PYyjIevcc74ET0tiAVW(C zL~Js#Hp(C{+QmRi*5Y%%@}z)g5?TdMYO7AF;sdn zRDZmK`;di!bg&@{qWXI-h!!$ftqCDRbG|i1o`Y~eRockV)x!O?=6=dH*@CQN1F4ZQ z8eR{CHEIfL*&)oWL3^9tZ1;3n`qA~lBT?_y{FsDF{ksrL=h03k;Jvros?FUBo5Who z(y<3=HD+nzD|?~&mJ(u6iX}7g>|rP2j(>3a?&F;}hu1qI;FC%wn!Nk(u4!) z$%&9*(MVA_*$FgG;hmbN*4WHQdBtsRtfFpiBs90yCSV%XIRyZ&Xqm7X5udq3mP)PH zoKr2TpSBVq;3xoD8%T%Ec+DkXC^{xp^uLqM5-^Xo*er=n?r-5UAfGy~(Iy%tnSaex z37XNW=pWBiEaCvI=xzwejL?tHVyX|~wII$0QDiffuFj-d1bIT{v^Hd6AdMi0oWtW$ zPxuO>fn^=yi>cE(LU4I2KghkVa+qs*^|U#y_nQV>+Pq^~NTO(OYfpM0djJB@cTd~Z zk%_9-)>D%44>aFwuGZW2BP682%zqqoQ+&1fYL&5OO@24jmOOvpfWnQPQ;W2=^>S+M zoCV>AKEeI427oG}e_b`F0|s-)55+j*&5_oIQ<@$(T|6_>{FdFY01EcCRb+)@5%{%zk%|UzexD#$~+yLP~k9ywW+` z0(0WYmooX>7WOSLam7mHM1PY|MAXg}V&6^ViMJ0Z>otx47Oa9%_@9B*Bzp;~!ct<7 zhRFr6s=!#Z!Mryd%>=3C3rG#iKwozvOfj}$kIUM*exgoU z$mkZtUNoo0dUNzKtBWyWpods*VvK-V5a4epE}U4LlPuP#ZEY)FlYhiC@i!NSyoDEH z5H~|aLPqalSM+8zcJYj5iGyTcq2NPjaK_fhc!0t#_$uUwT4;YvF=!;@jd+4@%&r&QBsl_Cru}qa^zdMr1jNi8{e|9Y4}SoDh>-^F>yD4JgwRA?e*Y7W`%xU zn;)DNH{~x0z49)4IpAVHPPF|v$vcVVwoFXR@RV+@ok^k7pW07&R+bD4&PuoD&k3=L zE@Jr&gj(9`E-5;x<+m+OTTDpr`V=H$cTI}g_I3_Hifdb z6SB@mKXTLCvbpf9!RKEe%?u?p(65j7^l086EjTuesxk|X91EWRYQcfRPh|!U3{X&Z z{q%VLbULw>0)J~N2g9ZtwQGb?pJ(*Vsr60q2Ao>oWZUKQjRnW|^{UK*qsSP~?=3hE zU8Kqk9LFqr?l1Ow^kqTcP{ZqeZFDglN_o0Yu^2rTUp*}F)8^AJ%{N1^iX#mj ze}g-`uNNkbeVpq&_L@PMfAp&Y&>;Lu5l~g6nGn?m4}Y$T4V=Y3f9u%6|JSa4^c~EHD=0TxsiwA|gEglpC+dL@LwRw=~>hNI2 zaY1YztT`}<&4V@RiVhFf90SbeLC_{bOc+NT3C!cdII5}+HjLvWa`{l~YQSwkHJ1-j zqb(pOU4LQmp(qn_Uy|T`iC-zgP~Vm$bX(%X6$b9?zjogs3A`n?@unm$o`2;xTt;Mn zv`UyVf3=F3FdhQrUS18tdYdG79ZAIt%C3|3q%S&>O4gGFCbt{_CevuXS`)!rjyxEU zAe3cS+}0SE`q`AYnI?5&2x4l5wQ9{;bz+gk02T)D>=Lrz>9<$( zR1%`YOlI?`lmZ_>R^+pHS69Qa+?OUDZm0@`8m8ienrbIhXmbV-*7MFt-f%^!dFcgj z2!CBDdBUZw)6nqj7QoCyz!Xf=cy6<~hhAncm#RYy*UwXBuG(A0@EKVn7^sOOVp$Kh zPue}s#Hn5`AIQas)n?|fy(wlq3ZJPO?KFht%xkKAuw6mu2CItrjjBEz*8HB7>WJSq z>N6&sicw@X7wh9^w}O~%0U>VgcPP%vl7CpPE&@!-dPs~ zGCV<+kIzRVj`$V-a!E!f0o3^}7pFxq8cHzfu^s}CIhQe`)1X%=PR4PmCq%A79)DbA z;0P~nwY;cI^pi?3w0@QWpb4NqynQ>k9!!V*+evSF#pb3oN$B*{Uu-sai{)qU0M%+m zUzAs^&|J-`3rbdWVqRs^C1zKH!ZeUUk0*m`0_w?-OO9C|8nbmB2XwSv%AO8XMMTD2 zvO52dsvK+@2-~9*m*}fFti>m`Qh#n}?TwFTA=FArMos`mNM>HaCZ(XJ4K5zF0NzFn z>#iw9-u&H&FX$z*gieLfZ4jYzrs_3E*_b$n=eb1 zTDr2$f%Z3eBtpns(QPWr^Nb^fy=@b%O!lQHE<0i#LKnb zkQdf=Hoq9WhclJKV@34hYX31FldaGD0u8GW@)wcb{lb8v_!e@RiA_c?w#iHzy^=o8 z+U!;2FG%~JWUtk;bI9R?yuB@?Z2|9%iia;MWr#5>wgs&Y*CvQLA(g} zmeG&n<$K)w`|%>IEZ(p%yZ~M_m~c#~Ii`$)c+o8~)57c-b7x7E`HM>eeA*?!g0n1o zPpfrkCp7)@7=-AhCb|zH^e#2MOG9rTxHiBtrSs{a=k9~mOY405etkHhp(ipEf?Lq@ zL$mm-Z$a%z*h<~XNK1I_CzzD%AO|VK6EC8Mva7`_UL*gv$D(~LnH~ahb#^gXR zyq(_ai@zwesWffcFhZS5Q>QZ2X@l1Wygdn7hjsL$ld$g{{J!XmVr7C({YhvTp+v1I zQAh1bXzF!{LPfG z`#Moy62c~mT9eQ)iNFXYvM6d#LW5@pTqXfQJ*OA;de5Slh1id3@lMY?011^7X;g=x zN`b2Mtc1(0ZA8h)+S1t| zH4UuU&gO%OGk;q&wsf9LE+N#JYwXoCvAW_<=JLtR%%lw^WYgA@jIAeK4Jy;Xn#o|M zlrUEUXX1X>sYBRl0E^a)+%DqUTE%F2bb(APgq1dKSuuW>(bWBa8LGl8f{Hgi! zpw%URUFel$;i+jrA(?)1oh4bv)O4H5w2`S{=&qJ!D1XBz*hz;q>mO(tlJ}^yX1PPx zQ2SPbFxi>`O;&vGvP77q3s9Iuzp>5|%_LoIQq!gblfoqU==%3#@^_n(ejby;Hu73K zOS3R0HK6dMezu*ZSqCO{o659tFnKW;4dw$!E~fP#vTwD!r=f_uT$VZ<6M__$G2!P@ zmt{hYQh(FPnW=Zi$TE7S{|B5go`>80lXofeJbpS^g*sD-AHoLR|E(90iLRihk?rU< zwHtIQm5PL7CIsW&@Lf(g@D1PQ1R~$SU5@>&Oe)eS>yC-zKX}b`MarR%0yJUb$r{L< zHP8Z+6<}foX6_1TwWv%BbLjlfHdE9bjsABtg@60HS*Ik}wX+e-Hj6KoN)iMHED4`%(7aaasyDZ%5*TqEUV2)H_#w84Fs3H>)};kf5V6ANypy(58dDF zAnB4L=mVxhlL!G$#)sgXc>2Plx$tNgpm3>vD4*q;OS{@srcDQKWyix*>%Skjf549S z`+spO+mv`=!sLRu)qujZg=X5k?!c{XlbSXTZd>P|BKy0YgZvNj(1fQ7ho{|yupdM6?C&wtT9!j?A{0^D!&K!vKML)9Rt4t}c%Te^e| zwyI34PE3frC|^3<|81DC9kn{XO#_wq12BjVOlVMHh)Od=S$ASWw@OVb2NTml-`(M> z>;-H4fpnsjtn8EoC)5>xROnkd^liflaVt&S$|Y{QNoATi^SPNo_8@mgFC8M=Gk7=_cRoVNeJJuW*LGM($$)Dl}ox%qtrCgo&xVj9|PJ%{XbcoXw8YIFFaHW z4|M?w6V;lDYRyDlZ7S2I1Ggd_>i@~wL~Bks{al>=U~)m+YCs7G9%;s{>ki!NHmPaj z;5M)e<g7plY+}E;0D_1@$B&4u=x+{e85!7ihy?-CxsytJVm_4MMms_! zN$E_`Z;+V=FTOw*c>TaW`_2P&X&{)?Hid+(t#1B?ioMy%q@VuYX^)Jg)^r@K+gU{i^MFEzpI5_B=cVLOXb-Z3j<*5wujszcc+) z+lh|B<>(Afh5;Wsfs$QKADaHAn2K?j^9wK4uUsUAT`liD;1+07YDJJRI&pMqv{ffJM(SDHL`3^eT~sc90n z@d=wsZEpL znU!;UmqvenIJ@ojA$|DmyFu?_Fa>p7oqORn;&fPSj}RgCc8&f$vAil?V2H)rC1wkR zKrVDvF09bzRLWT=&)hGZ;0s76_>fY$+O;Xw5@itTwtsigo6HAOeqlkw#2D|e7yq@x*O?^_veF}uxG;x|o6_-#4QzDG z;2zdn-9t&~HxDK-W-MVF?+=fM+e5SbBE^)@28+Kwu20&tfO6TaG07)3xNQyxT}w%A zpuz3pPJdCvcqC+*t~ov}mpFghe1~0mHDtcyZ(&pGTM6ZOz;+OG{q||Q__A1UbbW>s zJH@vUKV zTz>&bUgK+H7?Brnwd9owAs7^ID}1zOf>Vw~et>}O0AV2#Ybg>rh;if{h5_Cxf#y;r z@}-*0|7pAa@2BSWlbX<;%P}XfJziU&kpU1tWRKSYVJdTqAcDOe^{#ujkk^_AiYB4F zXpwNU*e(#GUgn@A&)x_E^h#sSibF0!Vl$y3>#TD{VrD#wO87ECGIT0E^AWMj37y34ix) zm!o$XR~$||{%o4cP>!Z7ldQI~07X?r5ZdW^m7@94lx9@Q?|P~Fb~czn zdT)pIz*Kik3qv3v;E+t_J=TZ51r zxBH{oE`qgHgly}Lm1f1fnZhY82*8p&6;Te5dfK+YqV&PI#fVu{nE2_DcO*T1H4(M% z1qO@E47H2xx6oWNXDYU^%2;T?+v7-rpT2t7FO|AFyq!+^w}0f67so4duaQL5xob#!w>dG2!_JfspFN>QSV z`lFc?rn+!6v5Ik>hg;n@;ynj70V2Z?m{ck#+=;oP}0`1P##yGrwYf(2t1R;^n9u#wK z8tN~j14M>L1H0+_L4Q8RMFIg%)G4M<`#F4rPA}(c27hk3dU!#@i81bO z#NW^9P6fmpgp$9ab5NvumqP{?)8U4SGgeGZzw}8VfKXsE9u4~+`JfFU> z7;IPj-FkcCXefvun)3CqZx@O;yVWy&HsjBNF}+pEbYbHLK>^VC{6FA+b$I=sx0lxp zTQY2Aq9^hcC48cRWq;&@Zgo$BMa!C*LnTtCGE|%_E|BTZPMEtF08*b1EL>Q~c6;Z^ zV}$B9j}7mK#A8VjU^2d=M9Mke>D|oVsV@z#=fn9&hpm#z5v>6DR~Mjm`EEAo-%O#G z{~XVF4N~$jowvY@w!hdf?$(?2Y2CP-FkC5(VSW0Bfg5l)vVS;Y__$YH?da%1o-bG{ zP6(}0;5btz3t9;~K$xG?l+gsR00(xU>$!)e4?H{ailX!tgjrhcN0VR9n%Twfak1VC zBu$9Q9AKKuWN|z`?+z;gXD1ygc3SXZ-(Eo4NvC@XG;fh*8SdmS!xjuHtOSiZanxfR zRSu5oA4O69Q-2t$|9AxTc+$N1)9M8TF)Ur};<6RswQ^_TUg`P8terlUpg>GWXFQ&z_0<#DiR;hSL`5RQB> zL9uDC`i$9tUx47|44_wUuLv*W>F}@Ext5@GBdq?`+<$!@vDlT}V>+J0g9j3K%sP1- zl%kWv?sRPa8%157_@d525N{t|*R+GDG@v{@0AAme-0$T9y<&|L13i$8eO&Z~4yc@F8Hr+3WTO}Xv7t031 z_`wq?90Glh<(#|-yWAb7ik;UaOJWmj@M^JLd}CH5i#;hS`bP^edtXuZZB`H@rHna>A+E-{&`QQI{>~I z&VMj3whx^$bjE#yifF5Qy4}2YKH~9^v93TBQE9Ok>*IcLT0YDdcbldq3!GY{3>)z9 zFgt- zd%x}$k-Aq}w!Cg3LHOhaFvf8rI8O9JAAd}h98mkmd@#N2^?4a3l$y7FI51qidQB^r z0B=B$zwVWy5dUZL95V`$z}UDLDN0<+{B06)aMd=@Yo3_|^1f*97f+j0dy#NZZydXl z0P6oKlx7Obu`zfB(Lv~AZbM(H7r;se6Yc`|TW3#qv0VQT#In6k@}I(O3kirc@@_21 zy7+$r7|RrPZ6tUyG+o`yDN=4hrb_FuGoSXZXP0mngIfx3VwrW^w)d~U<+$yCfri0b zRmyt9`DhFQKHsvoP_UL>h?ZWU1}?`|#KQCjZng!SWlbisCX4?-1_ayS}{C%2cQ-dle>)K&NqG`p*LBhB6FL|5PT_WSe20kc=l zp(;hQ^776PL>+LGe-f9~tLAuIeA02gNXkDAR;Gxyc*|`Sxj=Ep26Lt$nAv#Wob@J? zbF~HbC|OHIx=e+-j9-;g6)7+X^6mnrdrR{PCbIubC7%u5by)^pH@wfSUZ*uE^e4^w!{)mYMVwxJ> z6ow%ZhDdq#cv0wre&FfjMOU8uE6iU~>7ab3Tsr=kX?n~V_(UNLQ7}X)2*6|gyTNEQ z_;t`%5)jUd!T}XJU9>T9e}$p2GfRK%ff#BUDe`(mNxVD%vDf8#qutnf=9@h(2@v|` z4OqeM;1}ydvpnq%-*gQrxm$X!5?N35ABNlGNv&=ehZR42vmaiJ*2k0Nq>|9t`~GHe z)E{Jh_Th8$jms4!Dl1s~yB!6NORY%lOf$amqK)kV)Ox;^Da_9H=B$lnB1wPEBtfsr z4j_7yQK9zt{|R)9Zp^x9k^Cd*W+3S(=AQA=!P|aJl(9!E&o8e@lqmP7_l9o zn*gyG=SbHCt>{Mk*K9t$>Cbt!C3w9VIRv3+ftOF)r3ed-Tu*P~?MIgT`OaNx_bh^N zZxkKmzPJ50-Z$jGbnJnH5xsw(FGwE&Jb>}(YO&v|ZQ0~;E9E`mZwgJH!1-#vKADxA zL>gJ{)CdbDW1%2ag+O>)N@QP3iWZ`nz0uD6vxqXHnGt1p`yYlVOgOJxfq<28a>vKy6CwFaDB1+lcI5-a}Y>bZA19oBbGCmne}((`}7Nno@1b}jjA zz|{{j^gtdSwK;v;H@YeX_XU_fB_Xy)L<8r|i44iQR)`ARU(|p2cuO2F=4yb1mJ>zx&Ud!Sv(wT+#?sZ0!z+*>#aoQN+3Fiww%HpB_1%V#EoZiwwVO z_e@{rEg|JCp#_lfc94I`b^ws>hR=Ya@Wd^RfB{&FWtnU&3ep#53@X}19TIp9!}>+0 z^^5vX9;-8;toO3b=?uY0;Mm&)YKX+Duq>GT_Z}{u*ITvR@4-4cQ3u9bKoK3dfZ8?r z$yT%Vr|shObbwQF{mL~+r;36-@I!vnVnpS_%l4gX%dm2yeHuZ%4(Q^EEGzDB-|V z>c}!th?$ESu_$P7RC9##%L7=)xg2tXa5=!oQMAPXSW=DBfxiR`(HTDHwKBC%7$(ke z_2$f{&Iu@iTwH&nk8!X*qk7tf5ss+Lx5e|1lL3(##ZVT;e8d=BZ`ZIZICUhM0z@IA z6T)FqxEl<&tLCf20Um$^p=M5?+IP)n-)he6;6dp2#1fR1b<})mHZDIXUP0>(YH)U# zGG-L66iy)x3RoD_c;>i2Eu;PSiLe1h%#wtw+%JpP40 zmPTYMj9#GyIE8B^N@a^>#T!GzskDRtJZOQtYXag7(bMDo|GJx5{K`Nr`CnA4o zD%;g5S7%J*B=(5RON6e6|8OGb|4Kx*GEV;xkumkmKb6S5R1@C9D4a*Tnl~}Jq-Hop zxr=trWknkT?gMG*(@f)6~5pKEO`YCHG{9GW_z?Aj`K@k4)AzC zFd+xo;l*K~Sm)k#_@~s#cf)^cl+((;IfDZnSWiI=@)FH>BhToZ5&&QUn8{Y2#ll~_ zhl5r4@5NtUAWNUWtQGtR@E7#DrWpV{r;%Rz^E*)HKSs5DJU+uCAVs-G;>VL;bcnsdR8 zfm?^$9%Ryc{z!+Gf#b1VSfzzf;HIU|80D)U(p|C^|PC{fWB z;BO)-FT{d(%_8=RDgeA|7P4y=v};aep<<5K;-@!FO;hqvY0-a_iixIn{PE61?-tx6 z^o5O4Yq#^AT`DW48U>e%<&XV_JNWlkCZ2d~!1q;~) zi=6pIWI+9Ie))gr@CzzSFY*gQ{BiukBBW&fgrc_km8_qXqMrbiWo%_AmO>PMx?Rn> zMwyE#Hv5xh1!5pE0wt~yh-;Z|OKk&6oD)7n@fJrHEUoH_XG*aw8O~M}8BC5UiLXj> zJjAV zuLgi;=w5#UZU-|Dm-viwuXmD2-^jKbP@jT7KwuXPBQe%kL^O6m=Nh^_OhzZ%U0K7_ z2yG8jrp_pYppdN(3k>5i7DUEHXqXJ0L>l_+w#Acl`IFfM#sQLuHqWC?`uhFVV)?M% zHg*lWd)n`;GkyQFzt}CG9ywl-bx_>Ho+42IEjxefeug1VbSW7Sq|kP?P-EO3)+g~e zX5+zRcU+&0hZkE7(9a0=LX+`{9UN2P;%bJ}pZhO=qK%#;*AMysUkqLp!(acGs4L0VbIXNOjnz1E_YLOR_7F-%>IEz*ZuPeCqIL6UGXJK9MPV4(`b^{?-YsnG8Xi)5x zzta|FCY}FgB+}&D(`}ReB_`osE5tEw)j~pVaWnapy0?4+?zm`<%fotqqA?_uc}L*z z6dUP0p5hBOkEi(btJ)t<k!;a5k5+L_t^ZAK}u!he&a`)D|i&VbjT_ zmL=KaQmhGbsbxxbxU?=qTxwks|C>wCYz`v+Vp*CxvQ*cyEKNn0rmid%xGd6e7MFjf z#H4tw7AGwpy>7mq+KQ=p?3@}8L~GzFf00*L=BzHM6lGc#SLQA*0n0U*QUJ$&SF_4+ zZ6(0|EiH9V7w)$8oL84Gpk@4a_w;c_e1?i*tCkU;3F0$S5q-Ek(s1?^SUlu$YYJL} z^`>A62!Hjqr@&OtnFe|6OhIay2)Ta{A&=cD2wbk=tSQJo3>N%j68#}mSUroGS6_A8 z{HJdk>_N~FnO3<&D_zU9%7s?BODlmZA`NFxR1R)&YodQMt$u!@OpAgkS~wKdwM@}M zC|bA_)o{6nQxlyIDQ<(cw2Gqh@aIBPcXBF4?1uoD0EIr75&;6BWu!s9p)r3M%DD5u z=R#9=jIT2Ghb91wvQki1#;u_VXs$usp~+GxaVca=_f-rrNI)AMY`?4zyREHX@;*=7 zscp!RonCQM;6`xY-)-;LpPZT^fE8i%k_lG&1k(Uauu=$Cwg@JmRir^ZtT4f<`1@F~ z7L11#OZ#!LV(UK^R&4#p#fpEW|9Dst;|cRh<@1ULU|y+&SE?4TXwY1Px>!k>S1Md# z(Z3R}?BVf-Q_fo9MFUah)u*A-oKRRRyxMKoN>Ou;D54gUYa5JYZV7ws1>_-yFvq-E z`MjwCm^Ulo&8o$l0$N8J)T09PW*vW@3jbi&6QQ^C^EJt{E& z*1Q&Ke=TSLUJJFXg}SvCG-$3t&u*{A*TebP+ivR4?ZyYE4w*$LZBP(G457j!oHQr| z8%L1__Qxki#;9}C@!`2kv4uu)Yls>~Y@v}hhDLFFlo~uY;Agj!@pSIlYoksiI>6kU zSV1FvfffJ|6KJGupb>u=`P;B!O$JzJXo9}D6MYUa_onU0u{$&kAc(W9$gwvx4VxQS zkGP38bn`i)t-c1NuBdgRQQL~-aYLfc&D>lzKahH-NY8toa zZwMRM1;X<;#QmG+FC-H)TAaG;)c^pr2!CHYJ*FhdbHHAVsnX8mzJV@#B6u@?pzER ze`GF#N-@C1nM)S~pfBSzT{4d@1~xaaYAzI&%-ev-9#hz^7E#yQW3CKX;`_TtTi!Y@ z1^!_%78^~BMw$*7A(=MS#F@FSZh?!zCPs^m3nPRhv(10^XKJm#fHl{esZkjHnF;~K zloO*ZrvpX^sx3Nk9=B(z!E*!d%~Xq9wC+^deg@Lu&=$DecP+Dr#UXUl;tTG&>z>1C z$__(_nmpPq7dA&3HQBuu5e0eHIASg+gnH9u~_ZpC|f(TdH=yI=XY z7_%KI!-jwC<$vt%j;McubZ*ksQg9b*{pfojgVbQJ+VfX!t!=hsS0Mq;w2y5acQFCZOv*0K z{JFc8|5rFu1e_R4L65rSxo zY+SYpV!(3)?oUrdMOg%=XJkcNhWym@v}cjfu58iHzzFfQX*Dj}#M9tnU5(2Y^>U$J zB}adPF6#MP?u(P7N37So)2!Jv%Tu$OQ&vppcz_|7AJ<1PnoXP2;hPI&jtky^c~Zg# zRf`P_jIe<=w#HSP4Geg0z_wkHuDXKaku5L zqZxleFk5TPc7keOK#kzqAh@Gd5=Ev}#}vfptlPHO(Tu+!{%}#;H3bbS&T-n(m_%{s z6m+ZHv@)zhe#Qifk@t8Kw6^RA{^$sQxo$Qq?O=~y@SbTwk|#Nfi#%7@B_6t0^m>1) z7OQ6}QZQx7vFR)zcywJY@6Mm@okJP^rihm8T1ze8=&*&IlVeQOf(d&ab^wbpG>K!4 zY-d4swM$I9AiBk!6hnL`fg20^IBEs;auB;P=!#oO>^TbKMMf*kfeFoCfGY&9 z)Q*{H2R5WhWtyBpHjOKH%_o>lHcfxpr|w_! z`I|H6gEXQ^Z? zVxozdWZv{NY-L~#8($1AdpD!`Oh|~KG{Eo0J70?x#T=B%LK9PI((6OB>MegIvT;?k zH8S%h8jp4&#as%VP(r{|6ELZ5Hf=RXO@sC{g_Ia-!<(j2H~xre3fjePnqWS(PADN{ zstK89p=s&{m1zLe9KRo4_UjN$U$V46&rbr(kwrAfaKVX_zt%!|nI>G81?HyVD+BM(O>BD!K1I*=Jqz0Nr;+ z0w5mz{zD_F7gT5)MACX|#GqwlKwFP;1SXbiufU@mff2-%slG-Fy~+{r%z%5h^a3G% z31#b!ULXWbrSL~xwr}VKxH7=rg{eT)a%tQ8qJYSGKdFRG;<)`u4V@Th%llJm#mTmG zyg#K@@KXt|WTor=DS&^40kj+vrB*yIosZ~R!HGVd=I%!Xu#OC%?Gzx@!XHuT`UFV5 zAfnd15tW`xfPiKO)V|J?YJCCieo5C0HtJGyq4y;XS{YFLf=;T18&da6T%XDjGL1AV zq~4b_XktKJH%I{x$I#MugA{;FdJt|X%9bCbz!nD9b)*vjaW8-Lzor4iYh62+l&!A` zY#bR_*HuXXm^Ui_YZ^em^AP5!T3^$!nSu3g;siq9gqE#~H~|p^=|fLUYby+08EDUt zEfB&fdFzt`B1e=o(ae&!KdGS;1MS%|1wvb4la?t{Km=7ut}U5K+mb2Jg@N|WT>_!4 zU9C@Q5J8pkq^N(|pA_gcGSFdLiU5jqsWpDPAO&%$mNRwPX-SbrnQ3I7zoc3pzasbe zCG~0wb8p za;-W>EqzQw7Y5o_0|i9Xn7sW_4I@a?{sBqe{-{9bk%52y175T5mY149YgU?I$YCuu!37Htzp2m{TG07&JJ$ zU)@5;tvUQeqg@fHq9t330EF`^t!@{G!{QqjmX4{YNZ(MOaNecFS;&khkq?&%X-RSg^6}-KoLV&&9V3H>4OuJ-k6iL;=gT?|O zrL)cLZo9j`e@&DjTj%DM;kZ!p3U3>0CX_FG+nRsL)}IMaVH=);>Y$-U>lkrTMcs&m5Xi@)LcHl;Gohs|^?=sZDBL&_&QT~YfeYbEUMHu930f# zto9e5ba`4(K*0CScD3UatF-vzg74K}?rdUD`0anf2XD8k;40c;5mwWWF;@}s7MgZ8 ze=KfSWLQt|S-U;UlqU(8j2*r>o_65RK>cGTFolxiF~A(Rx2kx*SP@sIF2Qs20VRKm z5mc?bPg~B-M0_AU5F4j%wx2kTr4LA|SrdifECj@;yyuM)Al3^=>mHhDxikTPeZI1MogmX#3KN7FS`1*R# z7wA;?Pqo8we?D^hdjgzicB)o3C?AQOBb>a~C`m=<}YTR0G7 zK^Ym;5{clL;KNP3%Xjnf^@w44z_|=K7xZQp@Qi_ZthtOeuNgQIgj^5i5XELn4GJD= zA?Pg_y}1p4JsxxHM z2^y=U4LTn)FypWi99Fpx?6OP6c&r4Em50aKyPG-ZQHI)Dqn)cQ{;zqYwT!e*yw$3h z_1$F{M{C})Ud0p6FE~Se~cTrni7&$Q=&&R6i&DHsUF~u)u5_%y+ zjbp)Z%;pMIv0A;D0mPZ~k?TGRs}E|bw!7K9H=W;1q?wF6*5i&nj#Ync`lCVbTDM7L zxQQNalC;_=h8(Gn4W`qv%rg-@CmPR5Zqjv2%eR4+h54k08_pzqxIoEdlK+2u?;0R! zQWc11&kXMY2N@N0ltx}NP%~tH@9gH$)m2&D>C|hgvU;XvG$$+btE!~4GLwAtV?-Gd zS5(wdL0K<)$Caz-Wp#g0c0t8;RJ^h)i?b`PsHmemD~RaMD%WLQ)O#Y%%j}^* z{c~G~%J0O9I1wjKoH%jfM1(ZP!%h%Y1KD=;(>0uxAEEL1)J2X6G@}TWR7k~V9iq=S z=y!g6lX2={q*X3pX>oOx3kV8mEpDG*Un-I=KV)(ujDAcyG@O5x-w<#=;rvw*=JM?P zu5<<5-ay(L_*XB$6mp(KD>92#a2hQxBCk#=Jf&7-POadiYUf9e>r%FAckI-*nFl<< z>acwpP_ESKjHW`TaC%R|={*dYr+i9H8kG#$f>d|p<+6h1?ena%vSjYIh`SBlP6e1zhFMw#ahI--WLyFX zJB0-^62a6)hlRvbxsF|}uN#&~C6-1)$+;wtl44PyS_$N^f()y)vaF_2P6@?-v1uo8 zJ7Y0XwES2&NrqEWqFh^-B<^3uZ##)C0-WJ;X_YKZjcJe+CvBC+_VP>Uq`#FTiPK}M!Mt!YzZjp6fLQGM9*jx(pgf5xXIIB6NY9&L$mD|R- z+Scmg=4Ne~Q4}kxdK*Cv=F>YX51~f(x5*X4SKz_vpQ&X7+zV}9HpIZd(yp_ zGR#{zGi{Ap{Yjd3meXGA3McqR0>grZlch5|i(8B9jT(>tDvO|UO{<=-FV*N>Ne!*C z*RZ+Q8(bO>(>A*&^kdXsV{jquZ|Qqo%i`70z|((IwKC`TfCG7-Fl}8p-RgHPbvx)( z3pnaw6-w#1uMn(CuW>?~&b3BeIwYZ!C=!;MMPYh z>*?guV059TJdR`2pWCgCMuX83-f!b!9Hf8YYp9+yp1&^R(6i}aO)A_G6(013SUiVS zc#hWis`BbKTax~bO|Cq2NV>JYMQ~W}olz^$Ef}B%bh#$*iVa__HEJ+Gb*1g{sXEMh ztv+WVaW{zN?V*J~3%{D-mzs+!TJJ7xta6WNw_?&=>~z!%?JMk`QBEG}kY`e%w$;+c%CrX#ja-9x~}X6#d>PrT++Ez5OkZi z&koRatZHS>Con~AzB#+hOWe@IF7Nm231=4?CxKmkx z8f2*X4$}@WZZU48@Hm#(Z5hUtK(6%2iQXnQ_%tCDQKA}gPXz`2V<9GtSd~_)H*H{9 zdzxw;mNDoa=iNX**-2sdy}_7^PxtnCyE6#n7-@fpUOOy!^r@$% z;sp0!_F|*zzMb0Ed6@oWw}w?tNJ`#8U@^{?)gh~R2e+ExTEcQC35!}-f40Js#r%GL zgvB^p{CN=;<9?`r1Yt2w9slzQ%bmP`$C@N6+rlCUtWhG-C{Z~lEP@+kxF#`9=6ytc z;JqMS1UJqRU<47|D%pS8+bB2vy#XsP^*Xm7E<1!b%ZBoMx z$!77>aILnh#%V;X(dwdlmUU%Awn%vhMF}>$0EZnmI-vK(g1tHm-OJGPjNpM8`wk-{ z`um@j5iB0;Int5En=^1&Mq+joXzV;A1U=5sb5t3Fr()#_+bn-Z;SP$+E+xWAq=P)< zxTUuY`AhJMlUa%_uNrl-JBfBKxku1?Lm@_bCib%6676``>mNs2*xjY0oj2zp@}f}o z%sf0hJTFg}#i7n{$8gq!axagc(sfF(lofUOe7hgmpOf8+Jz(Ps=%zBF40MNzqJ-!+UR0 zyWLLcJtCf7^J_d~Vy&yY7rT4iG=F

  • REPLACE - destination colour equals colour of source pixel: C = A. + * Sometimes called "Normal" or "Copy" in other software. + * + *
  • BLEND - linear interpolation of colours: + * C = A*factor + B + * + *
  • ADD - additive blending with white clip: + * C = min(A*factor + B, 255). + * Clipped to 0..255, Photoshop calls this "Linear Burn", + * and Director calls it "Add Pin". + * + *
  • SUBTRACT - substractive blend with black clip: + * C = max(B - A*factor, 0). + * Clipped to 0..255, Photoshop calls this "Linear Dodge", + * and Director calls it "Subtract Pin". + * + *
  • DARKEST - only the darkest colour succeeds: + * C = min(A*factor, B). + * Illustrator calls this "Darken". + * + *
  • LIGHTEST - only the lightest colour succeeds: + * C = max(A*factor, B). + * Illustrator calls this "Lighten". + * + *
  • DIFFERENCE - subtract colors from underlying image. + * + *
  • EXCLUSION - similar to DIFFERENCE, but less extreme. + * + *
  • MULTIPLY - Multiply the colors, result will always be darker. + * + *
  • SCREEN - Opposite multiply, uses inverse values of the colors. + * + *
  • OVERLAY - A mix of MULTIPLY and SCREEN. Multiplies dark values, + * and screens light values. + * + *
  • HARD_LIGHT - SCREEN when greater than 50% gray, MULTIPLY when lower. + * + *
  • SOFT_LIGHT - Mix of DARKEST and LIGHTEST. + * Works like OVERLAY, but not as harsh. + * + *
  • DODGE - Lightens light tones and increases contrast, ignores darks. + * Called "Color Dodge" in Illustrator and Photoshop. + * + *
  • BURN - Darker areas are applied, increasing contrast, ignores lights. + * Called "Color Burn" in Illustrator and Photoshop. + * + *

    A useful reference for blending modes and their algorithms can be + * found in the SVG + * specification.

    + *

    It is important to note that Processing uses "fast" code, not + * necessarily "correct" code. No biggie, most software does. A nitpicker + * can find numerous "off by 1 division" problems in the blend code where + * >>8 or >>7 is used when strictly speaking + * /255.0 or /127.0 should have been used.

    + *

    For instance, exclusion (not intended for real-time use) reads + * r1 + r2 - ((2 * r1 * r2) / 255) because 255 == 1.0 + * not 256 == 1.0. In other words, (255*255)>>8 is not + * the same as (255*255)/255. But for real-time use the shifts + * are preferrable, and the difference is insignificant for applications + * built with Processing.

    + */ + static public int blendColor(int c1, int c2, int mode) { + switch (mode) { + case REPLACE: return c2; + case BLEND: return blend_blend(c1, c2); + + case ADD: return blend_add_pin(c1, c2); + case SUBTRACT: return blend_sub_pin(c1, c2); + + case LIGHTEST: return blend_lightest(c1, c2); + case DARKEST: return blend_darkest(c1, c2); + + case DIFFERENCE: return blend_difference(c1, c2); + case EXCLUSION: return blend_exclusion(c1, c2); + + case MULTIPLY: return blend_multiply(c1, c2); + case SCREEN: return blend_screen(c1, c2); + + case HARD_LIGHT: return blend_hard_light(c1, c2); + case SOFT_LIGHT: return blend_soft_light(c1, c2); + case OVERLAY: return blend_overlay(c1, c2); + + case DODGE: return blend_dodge(c1, c2); + case BURN: return blend_burn(c1, c2); + } + return 0; + } + + + /** + * Blends one area of this image to another area. + * @see processing.core.PImage#blendColor(int,int,int) + */ + public void blend(int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + blend(this, sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2, mode); + } + + + /** + * Copies area of one image into another PImage object. + * @see processing.core.PImage#blendColor(int,int,int) + */ + public void blend(PImage src, + int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2, int mode) { + if (imageMode == CORNER) { // if CORNERS, do nothing + sx2 += sx1; sy2 += sy1; + dx2 += dx1; dy2 += dy1; + + //} else if (imageMode == CENTER) { + //sx2 /= 2f; sy2 /= 2f; + //dx2 /= 2f; dy2 /= 2f; + } + + if ((src == this) && + intersect(sx1, sy1, sx2, sy2, dx1, dy1, dx2, dy2)) { + blit_resize(get(sx1, sy1, sx2 - sx1, sy2 - sy1), + 0, 0, sx2 - sx1 - 1, sy2 - sy1 - 1, + pixels, width, height, dx1, dy1, dx2, dy2, mode); + } else { + blit_resize(src, sx1, sy1, sx2, sy2, + pixels, width, height, dx1, dy1, dx2, dy2, mode); + } + } + + + /** + * Check to see if two rectangles intersect one another + */ + protected boolean intersect(int sx1, int sy1, int sx2, int sy2, + int dx1, int dy1, int dx2, int dy2) { + int sw = sx2 - sx1 + 1; + int sh = sy2 - sy1 + 1; + int dw = dx2 - dx1 + 1; + int dh = dy2 - dy1 + 1; + + if (dx1 < sx1) { + dw += dx1 - sx1; + if (dw > sw) { + dw = sw; + } + } else { + int w = sw + sx1 - dx1; + if (dw > w) { + dw = w; + } + } + if (dy1 < sy1) { + dh += dy1 - sy1; + if (dh > sh) { + dh = sh; + } + } else { + int h = sh + sy1 - dy1; + if (dh > h) { + dh = h; + } + } + return !(dw <= 0 || dh <= 0); + } + + + + ////////////////////////////////////////////////////////////// + + // COPYING IMAGE DATA + + + /** + * Duplicate an image, returns new PImage object. + * The pixels[] array for the new object will be unique + * and recopied from the source image. This is implemented as an + * override of Object.clone(). We recommend using get() instead, + * because it prevents you from needing to catch the + * CloneNotSupportedException, and from doing a cast from the result. + */ + public Object clone() throws CloneNotSupportedException { // ignore + PImage c = (PImage) super.clone(); + + // super.clone() will only copy the reference to the pixels + // array, so this will do a proper duplication of it instead. + c.pixels = new int[width * height]; + System.arraycopy(pixels, 0, c.pixels, 0, pixels.length); + + // return the goods + return c; + } + + + + ////////////////////////////////////////////////////////////// + + /** + * Internal blitter/resizer/copier from toxi. + * Uses bilinear filtering if smooth() has been enabled + * 'mode' determines the blending mode used in the process. + */ + private void blit_resize(PImage img, + int srcX1, int srcY1, int srcX2, int srcY2, + int[] destPixels, int screenW, int screenH, + int destX1, int destY1, int destX2, int destY2, + int mode) { + if (srcX1 < 0) srcX1 = 0; + if (srcY1 < 0) srcY1 = 0; + if (srcX2 >= img.width) srcX2 = img.width - 1; + if (srcY2 >= img.height) srcY2 = img.height - 1; + + int srcW = srcX2 - srcX1; + int srcH = srcY2 - srcY1; + int destW = destX2 - destX1; + int destH = destY2 - destY1; + + if (!smooth) { + srcW++; srcH++; + } + + if (destW <= 0 || destH <= 0 || + srcW <= 0 || srcH <= 0 || + destX1 >= screenW || destY1 >= screenH || + srcX1 >= img.width || srcY1 >= img.height) { + return; + } + + int dx = (int) (srcW / (float) destW * PRECISIONF); + int dy = (int) (srcH / (float) destH * PRECISIONF); + + srcXOffset = (int) (destX1 < 0 ? -destX1 * dx : srcX1 * PRECISIONF); + srcYOffset = (int) (destY1 < 0 ? -destY1 * dy : srcY1 * PRECISIONF); + + if (destX1 < 0) { + destW += destX1; + destX1 = 0; + } + if (destY1 < 0) { + destH += destY1; + destY1 = 0; + } + + destW = low(destW, screenW - destX1); + destH = low(destH, screenH - destY1); + + int destOffset = destY1 * screenW + destX1; + srcBuffer = img.pixels; + + if (smooth) { + // use bilinear filtering + iw = img.width; + iw1 = img.width - 1; + ih1 = img.height - 1; + + switch (mode) { + + case BLEND: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + // davbol - renamed old blend_multiply to blend_blend + destPixels[destOffset + x] = + blend_blend(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case ADD: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_add_pin(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case SUBTRACT: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_sub_pin(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case LIGHTEST: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_lightest(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case DARKEST: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_darkest(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case REPLACE: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = filter_bilinear(); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case DIFFERENCE: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_difference(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case EXCLUSION: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_exclusion(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case MULTIPLY: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_multiply(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case SCREEN: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_screen(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case OVERLAY: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_overlay(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case HARD_LIGHT: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_hard_light(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case SOFT_LIGHT: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_soft_light(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + // davbol - proposed 2007-01-09 + case DODGE: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_dodge(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case BURN: + for (int y = 0; y < destH; y++) { + filter_new_scanline(); + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_burn(destPixels[destOffset + x], filter_bilinear()); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + } + + } else { + // nearest neighbour scaling (++fast!) + switch (mode) { + + case BLEND: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + // davbol - renamed old blend_multiply to blend_blend + destPixels[destOffset + x] = + blend_blend(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case ADD: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_add_pin(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case SUBTRACT: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_sub_pin(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case LIGHTEST: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_lightest(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case DARKEST: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_darkest(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case REPLACE: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = srcBuffer[sY + (sX >> PRECISIONB)]; + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case DIFFERENCE: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_difference(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case EXCLUSION: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_exclusion(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case MULTIPLY: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_multiply(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case SCREEN: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_screen(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case OVERLAY: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_overlay(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case HARD_LIGHT: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_hard_light(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case SOFT_LIGHT: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_soft_light(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + // davbol - proposed 2007-01-09 + case DODGE: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_dodge(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + case BURN: + for (int y = 0; y < destH; y++) { + sX = srcXOffset; + sY = (srcYOffset >> PRECISIONB) * img.width; + for (int x = 0; x < destW; x++) { + destPixels[destOffset + x] = + blend_burn(destPixels[destOffset + x], + srcBuffer[sY + (sX >> PRECISIONB)]); + sX += dx; + } + destOffset += screenW; + srcYOffset += dy; + } + break; + + } + } + } + + + private void filter_new_scanline() { + sX = srcXOffset; + fracV = srcYOffset & PREC_MAXVAL; + ifV = PREC_MAXVAL - fracV; + v1 = (srcYOffset >> PRECISIONB) * iw; + v2 = low((srcYOffset >> PRECISIONB) + 1, ih1) * iw; + } + + + private int filter_bilinear() { + fracU = sX & PREC_MAXVAL; + ifU = PREC_MAXVAL - fracU; + ul = (ifU * ifV) >> PRECISIONB; + ll = (ifU * fracV) >> PRECISIONB; + ur = (fracU * ifV) >> PRECISIONB; + lr = (fracU * fracV) >> PRECISIONB; + u1 = (sX >> PRECISIONB); + u2 = low(u1 + 1, iw1); + + // get color values of the 4 neighbouring texels + cUL = srcBuffer[v1 + u1]; + cUR = srcBuffer[v1 + u2]; + cLL = srcBuffer[v2 + u1]; + cLR = srcBuffer[v2 + u2]; + + r = ((ul*((cUL&RED_MASK)>>16) + ll*((cLL&RED_MASK)>>16) + + ur*((cUR&RED_MASK)>>16) + lr*((cLR&RED_MASK)>>16)) + << PREC_RED_SHIFT) & RED_MASK; + + g = ((ul*(cUL&GREEN_MASK) + ll*(cLL&GREEN_MASK) + + ur*(cUR&GREEN_MASK) + lr*(cLR&GREEN_MASK)) + >>> PRECISIONB) & GREEN_MASK; + + b = (ul*(cUL&BLUE_MASK) + ll*(cLL&BLUE_MASK) + + ur*(cUR&BLUE_MASK) + lr*(cLR&BLUE_MASK)) + >>> PRECISIONB; + + a = ((ul*((cUL&ALPHA_MASK)>>>24) + ll*((cLL&ALPHA_MASK)>>>24) + + ur*((cUR&ALPHA_MASK)>>>24) + lr*((cLR&ALPHA_MASK)>>>24)) + << PREC_ALPHA_SHIFT) & ALPHA_MASK; + + return a | r | g | b; + } + + + + ////////////////////////////////////////////////////////////// + + // internal blending methods + + + private static int low(int a, int b) { + return (a < b) ? a : b; + } + + + private static int high(int a, int b) { + return (a > b) ? a : b; + } + + // davbol - added peg helper, equiv to constrain(n,0,255) + private static int peg(int n) { + return (n < 0) ? 0 : ((n > 255) ? 255 : n); + } + + private static int mix(int a, int b, int f) { + return a + (((b - a) * f) >> 8); + } + + + + ///////////////////////////////////////////////////////////// + + // BLEND MODE IMPLEMENTIONS + + + private static int blend_blend(int a, int b) { + int f = (b & ALPHA_MASK) >>> 24; + + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + mix(a & RED_MASK, b & RED_MASK, f) & RED_MASK | + mix(a & GREEN_MASK, b & GREEN_MASK, f) & GREEN_MASK | + mix(a & BLUE_MASK, b & BLUE_MASK, f)); + } + + + /** + * additive blend with clipping + */ + private static int blend_add_pin(int a, int b) { + int f = (b & ALPHA_MASK) >>> 24; + + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + low(((a & RED_MASK) + + ((b & RED_MASK) >> 8) * f), RED_MASK) & RED_MASK | + low(((a & GREEN_MASK) + + ((b & GREEN_MASK) >> 8) * f), GREEN_MASK) & GREEN_MASK | + low((a & BLUE_MASK) + + (((b & BLUE_MASK) * f) >> 8), BLUE_MASK)); + } + + + /** + * subtractive blend with clipping + */ + private static int blend_sub_pin(int a, int b) { + int f = (b & ALPHA_MASK) >>> 24; + + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + high(((a & RED_MASK) - ((b & RED_MASK) >> 8) * f), + GREEN_MASK) & RED_MASK | + high(((a & GREEN_MASK) - ((b & GREEN_MASK) >> 8) * f), + BLUE_MASK) & GREEN_MASK | + high((a & BLUE_MASK) - (((b & BLUE_MASK) * f) >> 8), 0)); + } + + + /** + * only returns the blended lightest colour + */ + private static int blend_lightest(int a, int b) { + int f = (b & ALPHA_MASK) >>> 24; + + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + high(a & RED_MASK, ((b & RED_MASK) >> 8) * f) & RED_MASK | + high(a & GREEN_MASK, ((b & GREEN_MASK) >> 8) * f) & GREEN_MASK | + high(a & BLUE_MASK, ((b & BLUE_MASK) * f) >> 8)); + } + + + /** + * only returns the blended darkest colour + */ + private static int blend_darkest(int a, int b) { + int f = (b & ALPHA_MASK) >>> 24; + + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + mix(a & RED_MASK, + low(a & RED_MASK, + ((b & RED_MASK) >> 8) * f), f) & RED_MASK | + mix(a & GREEN_MASK, + low(a & GREEN_MASK, + ((b & GREEN_MASK) >> 8) * f), f) & GREEN_MASK | + mix(a & BLUE_MASK, + low(a & BLUE_MASK, + ((b & BLUE_MASK) * f) >> 8), f)); + } + + + /** + * returns the absolute value of the difference of the input colors + * C = |A - B| + */ + private static int blend_difference(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = (ar > br) ? (ar-br) : (br-ar); + int cg = (ag > bg) ? (ag-bg) : (bg-ag); + int cb = (ab > bb) ? (ab-bb) : (bb-ab); + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * Cousin of difference, algorithm used here is based on a Lingo version + * found here: http://www.mediamacros.com/item/item-1006687616/ + * (Not yet verified to be correct). + */ + private static int blend_exclusion(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = ar + br - ((ar * br) >> 7); + int cg = ag + bg - ((ag * bg) >> 7); + int cb = ab + bb - ((ab * bb) >> 7); + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * returns the product of the input colors + * C = A * B + */ + private static int blend_multiply(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = (ar * br) >> 8; + int cg = (ag * bg) >> 8; + int cb = (ab * bb) >> 8; + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * returns the inverse of the product of the inverses of the input colors + * (the inverse of multiply). C = 1 - (1-A) * (1-B) + */ + private static int blend_screen(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = 255 - (((255 - ar) * (255 - br)) >> 8); + int cg = 255 - (((255 - ag) * (255 - bg)) >> 8); + int cb = 255 - (((255 - ab) * (255 - bb)) >> 8); + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * returns either multiply or screen for darker or lighter values of A + * (the inverse of hard light) + * C = + * A < 0.5 : 2 * A * B + * A >=0.5 : 1 - (2 * (255-A) * (255-B)) + */ + private static int blend_overlay(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = (ar < 128) ? ((ar*br)>>7) : (255-(((255-ar)*(255-br))>>7)); + int cg = (ag < 128) ? ((ag*bg)>>7) : (255-(((255-ag)*(255-bg))>>7)); + int cb = (ab < 128) ? ((ab*bb)>>7) : (255-(((255-ab)*(255-bb))>>7)); + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * returns either multiply or screen for darker or lighter values of B + * (the inverse of overlay) + * C = + * B < 0.5 : 2 * A * B + * B >=0.5 : 1 - (2 * (255-A) * (255-B)) + */ + private static int blend_hard_light(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = (br < 128) ? ((ar*br)>>7) : (255-(((255-ar)*(255-br))>>7)); + int cg = (bg < 128) ? ((ag*bg)>>7) : (255-(((255-ag)*(255-bg))>>7)); + int cb = (bb < 128) ? ((ab*bb)>>7) : (255-(((255-ab)*(255-bb))>>7)); + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * returns the inverse multiply plus screen, which simplifies to + * C = 2AB + A^2 - 2A^2B + */ + private static int blend_soft_light(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = ((ar*br)>>7) + ((ar*ar)>>8) - ((ar*ar*br)>>15); + int cg = ((ag*bg)>>7) + ((ag*ag)>>8) - ((ag*ag*bg)>>15); + int cb = ((ab*bb)>>7) + ((ab*ab)>>8) - ((ab*ab*bb)>>15); + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * Returns the first (underlay) color divided by the inverse of + * the second (overlay) color. C = A / (255-B) + */ + private static int blend_dodge(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = (br==255) ? 255 : peg((ar << 8) / (255 - br)); // division requires pre-peg()-ing + int cg = (bg==255) ? 255 : peg((ag << 8) / (255 - bg)); // " + int cb = (bb==255) ? 255 : peg((ab << 8) / (255 - bb)); // " + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + /** + * returns the inverse of the inverse of the first (underlay) color + * divided by the second (overlay) color. C = 255 - (255-A) / B + */ + private static int blend_burn(int a, int b) { + // setup (this portion will always be the same) + int f = (b & ALPHA_MASK) >>> 24; + int ar = (a & RED_MASK) >> 16; + int ag = (a & GREEN_MASK) >> 8; + int ab = (a & BLUE_MASK); + int br = (b & RED_MASK) >> 16; + int bg = (b & GREEN_MASK) >> 8; + int bb = (b & BLUE_MASK); + // formula: + int cr = (br==0) ? 0 : 255 - peg(((255 - ar) << 8) / br); // division requires pre-peg()-ing + int cg = (bg==0) ? 0 : 255 - peg(((255 - ag) << 8) / bg); // " + int cb = (bb==0) ? 0 : 255 - peg(((255 - ab) << 8) / bb); // " + // alpha blend (this portion will always be the same) + return (low(((a & ALPHA_MASK) >>> 24) + f, 0xff) << 24 | + (peg(ar + (((cr - ar) * f) >> 8)) << 16) | + (peg(ag + (((cg - ag) * f) >> 8)) << 8) | + (peg(ab + (((cb - ab) * f) >> 8)) ) ); + } + + + ////////////////////////////////////////////////////////////// + + // FILE I/O + + + static byte TIFF_HEADER[] = { + 77, 77, 0, 42, 0, 0, 0, 8, 0, 9, 0, -2, 0, 4, 0, 0, 0, 1, 0, 0, + 0, 0, 1, 0, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 3, 0, 0, 0, 1, + 0, 0, 0, 0, 1, 2, 0, 3, 0, 0, 0, 3, 0, 0, 0, 122, 1, 6, 0, 3, 0, + 0, 0, 1, 0, 2, 0, 0, 1, 17, 0, 4, 0, 0, 0, 1, 0, 0, 3, 0, 1, 21, + 0, 3, 0, 0, 0, 1, 0, 3, 0, 0, 1, 22, 0, 3, 0, 0, 0, 1, 0, 0, 0, 0, + 1, 23, 0, 4, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 8, 0, 8 + }; + + + /* + protected boolean saveHeaderTIFF(OutputStream output) { + try { + byte tiff[] = new byte[768]; + System.arraycopy(tiff_header, 0, tiff, 0, tiff_header.length); + + tiff[30] = (byte) ((width >> 8) & 0xff); + tiff[31] = (byte) ((width) & 0xff); + tiff[42] = tiff[102] = (byte) ((height >> 8) & 0xff); + tiff[43] = tiff[103] = (byte) ((height) & 0xff); + + int count = width*height*3; + tiff[114] = (byte) ((count >> 24) & 0xff); + tiff[115] = (byte) ((count >> 16) & 0xff); + tiff[116] = (byte) ((count >> 8) & 0xff); + tiff[117] = (byte) ((count) & 0xff); + + output.write(tiff); + return true; + + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + */ + + + static final String TIFF_ERROR = + "Error: Processing can only read its own TIFF files."; + + static protected PImage loadTIFF(byte tiff[]) { + if ((tiff[42] != tiff[102]) || // width/height in both places + (tiff[43] != tiff[103])) { + System.err.println(TIFF_ERROR); + return null; + } + + int width = + ((tiff[30] & 0xff) << 8) | (tiff[31] & 0xff); + int height = + ((tiff[42] & 0xff) << 8) | (tiff[43] & 0xff); + + int count = + ((tiff[114] & 0xff) << 24) | + ((tiff[115] & 0xff) << 16) | + ((tiff[116] & 0xff) << 8) | + (tiff[117] & 0xff); + if (count != width * height * 3) { + System.err.println(TIFF_ERROR + " (" + width + ", " + height +")"); + return null; + } + + // check the rest of the header + for (int i = 0; i < TIFF_HEADER.length; i++) { + if ((i == 30) || (i == 31) || (i == 42) || (i == 43) || + (i == 102) || (i == 103) || + (i == 114) || (i == 115) || (i == 116) || (i == 117)) continue; + + if (tiff[i] != TIFF_HEADER[i]) { + System.err.println(TIFF_ERROR + " (" + i + ")"); + return null; + } + } + + PImage outgoing = new PImage(width, height, RGB); + int index = 768; + count /= 3; + for (int i = 0; i < count; i++) { + outgoing.pixels[i] = + 0xFF000000 | + (tiff[index++] & 0xff) << 16 | + (tiff[index++] & 0xff) << 8 | + (tiff[index++] & 0xff); + } + return outgoing; + } + + + protected boolean saveTIFF(OutputStream output) { + // shutting off the warning, people can figure this out themselves + /* + if (format != RGB) { + System.err.println("Warning: only RGB information is saved with " + + ".tif files. Use .tga or .png for ARGB images and others."); + } + */ + try { + byte tiff[] = new byte[768]; + System.arraycopy(TIFF_HEADER, 0, tiff, 0, TIFF_HEADER.length); + + tiff[30] = (byte) ((width >> 8) & 0xff); + tiff[31] = (byte) ((width) & 0xff); + tiff[42] = tiff[102] = (byte) ((height >> 8) & 0xff); + tiff[43] = tiff[103] = (byte) ((height) & 0xff); + + int count = width*height*3; + tiff[114] = (byte) ((count >> 24) & 0xff); + tiff[115] = (byte) ((count >> 16) & 0xff); + tiff[116] = (byte) ((count >> 8) & 0xff); + tiff[117] = (byte) ((count) & 0xff); + + // spew the header to the disk + output.write(tiff); + + for (int i = 0; i < pixels.length; i++) { + output.write((pixels[i] >> 16) & 0xff); + output.write((pixels[i] >> 8) & 0xff); + output.write(pixels[i] & 0xff); + } + output.flush(); + return true; + + } catch (IOException e) { + e.printStackTrace(); + } + return false; + } + + + /** + * Creates a Targa32 formatted byte sequence of specified + * pixel buffer using RLE compression. + *

    + * Also figured out how to avoid parsing the image upside-down + * (there's a header flag to set the image origin to top-left) + *

    + * Starting with revision 0092, the format setting is taken into account: + *
      + *
    • ALPHA images written as 8bit grayscale (uses lowest byte) + *
    • RGB → 24 bits + *
    • ARGB → 32 bits + *
    + * All versions are RLE compressed. + *

    + * Contributed by toxi 8-10 May 2005, based on this RLE + * specification + */ + protected boolean saveTGA(OutputStream output) { + byte header[] = new byte[18]; + + if (format == ALPHA) { // save ALPHA images as 8bit grayscale + header[2] = 0x0B; + header[16] = 0x08; + header[17] = 0x28; + + } else if (format == RGB) { + header[2] = 0x0A; + header[16] = 24; + header[17] = 0x20; + + } else if (format == ARGB) { + header[2] = 0x0A; + header[16] = 32; + header[17] = 0x28; + + } else { + throw new RuntimeException("Image format not recognized inside save()"); + } + // set image dimensions lo-hi byte order + header[12] = (byte) (width & 0xff); + header[13] = (byte) (width >> 8); + header[14] = (byte) (height & 0xff); + header[15] = (byte) (height >> 8); + + try { + output.write(header); + + int maxLen = height * width; + int index = 0; + int col; //, prevCol; + int[] currChunk = new int[128]; + + // 8bit image exporter is in separate loop + // to avoid excessive conditionals... + if (format == ALPHA) { + while (index < maxLen) { + boolean isRLE = false; + int rle = 1; + currChunk[0] = col = pixels[index] & 0xff; + while (index + rle < maxLen) { + if (col != (pixels[index + rle]&0xff) || rle == 128) { + isRLE = (rle > 1); + break; + } + rle++; + } + if (isRLE) { + output.write(0x80 | (rle - 1)); + output.write(col); + + } else { + rle = 1; + while (index + rle < maxLen) { + int cscan = pixels[index + rle] & 0xff; + if ((col != cscan && rle < 128) || rle < 3) { + currChunk[rle] = col = cscan; + } else { + if (col == cscan) rle -= 2; + break; + } + rle++; + } + output.write(rle - 1); + for (int i = 0; i < rle; i++) output.write(currChunk[i]); + } + index += rle; + } + } else { // export 24/32 bit TARGA + while (index < maxLen) { + boolean isRLE = false; + currChunk[0] = col = pixels[index]; + int rle = 1; + // try to find repeating bytes (min. len = 2 pixels) + // maximum chunk size is 128 pixels + while (index + rle < maxLen) { + if (col != pixels[index + rle] || rle == 128) { + isRLE = (rle > 1); // set flag for RLE chunk + break; + } + rle++; + } + if (isRLE) { + output.write(128 | (rle - 1)); + output.write(col & 0xff); + output.write(col >> 8 & 0xff); + output.write(col >> 16 & 0xff); + if (format == ARGB) output.write(col >>> 24 & 0xff); + + } else { // not RLE + rle = 1; + while (index + rle < maxLen) { + if ((col != pixels[index + rle] && rle < 128) || rle < 3) { + currChunk[rle] = col = pixels[index + rle]; + } else { + // check if the exit condition was the start of + // a repeating colour + if (col == pixels[index + rle]) rle -= 2; + break; + } + rle++; + } + // write uncompressed chunk + output.write(rle - 1); + if (format == ARGB) { + for (int i = 0; i < rle; i++) { + col = currChunk[i]; + output.write(col & 0xff); + output.write(col >> 8 & 0xff); + output.write(col >> 16 & 0xff); + output.write(col >>> 24 & 0xff); + } + } else { + for (int i = 0; i < rle; i++) { + col = currChunk[i]; + output.write(col & 0xff); + output.write(col >> 8 & 0xff); + output.write(col >> 16 & 0xff); + } + } + } + index += rle; + } + } + output.flush(); + return true; + + } catch (IOException e) { + e.printStackTrace(); + return false; + } + } + + + /** + * Use ImageIO functions from Java 1.4 and later to handle image save. + * Various formats are supported, typically jpeg, png, bmp, and wbmp. + * To get a list of the supported formats for writing, use:
    + * println(javax.imageio.ImageIO.getReaderFormatNames()) + */ + protected void saveImageIO(String path) throws IOException { + try { + //BufferedImage bimage = + // new BufferedImage(width, height, (format == ARGB) ? + // BufferedImage.TYPE_INT_ARGB : + // BufferedImage.TYPE_INT_RGB); + Class bufferedImageClass = + Class.forName("java.awt.image.BufferedImage"); + Constructor bufferedImageConstructor = + bufferedImageClass.getConstructor(new Class[] { + Integer.TYPE, + Integer.TYPE, + Integer.TYPE }); + Field typeIntRgbField = bufferedImageClass.getField("TYPE_INT_RGB"); + int typeIntRgb = typeIntRgbField.getInt(typeIntRgbField); + Field typeIntArgbField = bufferedImageClass.getField("TYPE_INT_ARGB"); + int typeIntArgb = typeIntArgbField.getInt(typeIntArgbField); + Object bimage = + bufferedImageConstructor.newInstance(new Object[] { + new Integer(width), + new Integer(height), + new Integer((format == ARGB) ? typeIntArgb : typeIntRgb) + }); + + //bimage.setRGB(0, 0, width, height, pixels, 0, width); + Method setRgbMethod = + bufferedImageClass.getMethod("setRGB", new Class[] { + Integer.TYPE, Integer.TYPE, + Integer.TYPE, Integer.TYPE, + pixels.getClass(), + Integer.TYPE, Integer.TYPE + }); + setRgbMethod.invoke(bimage, new Object[] { + new Integer(0), new Integer(0), + new Integer(width), new Integer(height), + pixels, new Integer(0), new Integer(width) + }); + + File file = new File(path); + String extension = path.substring(path.lastIndexOf('.') + 1); + + //ImageIO.write(bimage, extension, file); + Class renderedImageClass = + Class.forName("java.awt.image.RenderedImage"); + Class ioClass = Class.forName("javax.imageio.ImageIO"); + Method writeMethod = + ioClass.getMethod("write", new Class[] { + renderedImageClass, String.class, File.class + }); + writeMethod.invoke(null, new Object[] { bimage, extension, file }); + + } catch (Exception e) { + e.printStackTrace(); + throw new IOException("image save failed."); + } + } + + + protected String[] saveImageFormats; + + /** + * Save this image to disk. + *

    + * As of revision 0100, this function requires an absolute path, + * in order to avoid confusion. To save inside the sketch folder, + * use the function savePath() from PApplet, or use saveFrame() instead. + *

    + * As of revision 0115, when using Java 1.4 and later, you can write + * to several formats besides tga and tiff. If Java 1.4 is installed + * and the extension used is supported (usually png, jpg, jpeg, bmp, + * and tiff), then those methods will be used to write the image. + * To get a list of the supported formats for writing, use:
    + * println(javax.imageio.ImageIO.getReaderFormatNames()) + *

    + * To use the original built-in image writers, use .tga as the extension, + * or don't include an extension, in which case .tif will be added. + *

    + * The ImageIO API claims to support wbmp files, however they probably + * require a black and white image. Basic testing produced a zero-length + * file with no error. + *

    + * As of revision 0116, savePath() is not needed if this object has been + * created (as recommended) via createImage() or createGraphics() or + * one of its neighbors. + */ + public void save(String path) { // ignore + boolean success = false; + + File file = new File(path); + if (!file.isAbsolute()) { + if (parent != null) { + //file = new File(parent.savePath(filename)); + path = parent.savePath(path); + } else { + String re = "PImage.save() requires an absolute path. " + + "Use createImage(), or pass savePath() to save()."; + throw new RuntimeException(re); + } + } + + try { + OutputStream os = null; + + if (PApplet.javaVersion >= 1.4f) { + if (saveImageFormats == null) { + //saveImageFormats = javax.imageio.ImageIO.getWriterFormatNames(); + try { + Class ioClass = Class.forName("javax.imageio.ImageIO"); + Method getFormatNamesMethod = + ioClass.getMethod("getWriterFormatNames", (Class[]) null); + saveImageFormats = (String[]) + getFormatNamesMethod.invoke((Class[]) null, (Object[]) null); + } catch (Exception e) { + e.printStackTrace(); + } + } + if (saveImageFormats != null) { + for (int i = 0; i < saveImageFormats.length; i++) { + if (path.endsWith("." + saveImageFormats[i])) { + saveImageIO(path); + return; + } + } + } + } + + if (path.toLowerCase().endsWith(".tga")) { + os = new BufferedOutputStream(new FileOutputStream(path), 32768); + success = saveTGA(os); //, pixels, width, height, format); + + } else { + if (!path.toLowerCase().endsWith(".tif") && + !path.toLowerCase().endsWith(".tiff")) { + // if no .tif extension, add it.. + path += ".tif"; + } + os = new BufferedOutputStream(new FileOutputStream(path), 32768); + success = saveTIFF(os); //, pixels, width, height); + } + os.flush(); + os.close(); + + } catch (IOException e) { + //System.err.println("Error while saving image."); + e.printStackTrace(); + success = false; + } + if (!success) { + throw new RuntimeException("Error while saving image."); + } + } +} + diff --git a/core/PLine.java b/core/PLine.java new file mode 100644 index 000000000..b69780a8a --- /dev/null +++ b/core/PLine.java @@ -0,0 +1,1295 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + */ + +package processing.core; + + +/** + * Code for rendering lines. + *

    + * This code will soon be removed. + * Written by Carlos Rocha. + */ +public class PLine implements PConstants +{ + private int[] m_pixels; + private float[] m_zbuffer; + //private int[] m_stencil; + + private int m_index; + + static final int R_COLOR = 0x1; + static final int R_ALPHA = 0x2; + static final int R_SPATIAL = 0x8; + static final int R_THICK = 0x4; + static final int R_SMOOTH = 0x10; + + private int SCREEN_WIDTH; + private int SCREEN_HEIGHT; + private int SCREEN_WIDTH1; + private int SCREEN_HEIGHT1; + + public boolean INTERPOLATE_RGB; + public boolean INTERPOLATE_ALPHA; + public boolean INTERPOLATE_Z; + public boolean INTERPOLATE_THICK; + + // antialias + private boolean SMOOTH; + + // blender + //private boolean BLENDER; + + // stroke color + private int m_stroke; + + // draw flags + public int m_drawFlags; + + // vertex coordinates + private float[] x_array; + private float[] y_array; + private float[] z_array; + + // vertex intensity + private float[] r_array; + private float[] g_array; + private float[] b_array; + private float[] a_array; + + // vertex offsets + private int o0; + private int o1; + + // start values + private float m_r0; + private float m_g0; + private float m_b0; + private float m_a0; + private float m_z0; + + // deltas + private float dz; + + // rgba deltas + private float dr; + private float dg; + private float db; + private float da; + + private PGraphics parent; + + + public PLine(PGraphics g) { + INTERPOLATE_Z = false; + + x_array = new float[2]; + y_array = new float[2]; + z_array = new float[2]; + r_array = new float[2]; + g_array = new float[2]; + b_array = new float[2]; + a_array = new float[2]; + + this.parent = g; + } + + + public void reset() { + // reset these in case PGraphics was resized + SCREEN_WIDTH = parent.width; + SCREEN_HEIGHT = parent.height; + SCREEN_WIDTH1 = SCREEN_WIDTH-1; + SCREEN_HEIGHT1 = SCREEN_HEIGHT-1; + + m_pixels = parent.pixels; + //m_stencil = parent.stencil; + m_zbuffer = parent.zbuffer; + + // other things to reset + + INTERPOLATE_RGB = false; + INTERPOLATE_ALPHA = false; + //INTERPOLATE_Z = false; + m_drawFlags = 0; + m_index = 0; + //BLENDER = false; + } + + + public void setVertices(float x0, float y0, float z0, + float x1, float y1, float z1) { + // [rocha] fixed z drawing, so whenever a line turns on + // z interpolation, all the lines are z interpolated + if (z0 != z1 || z0!=0.0f || z1!=0.0f || INTERPOLATE_Z) { + INTERPOLATE_Z = true; + m_drawFlags |= R_SPATIAL; + } else { + INTERPOLATE_Z = false; + m_drawFlags &= ~R_SPATIAL; + } + + z_array[0] = z0; + z_array[1] = z1; + + x_array[0] = x0; + x_array[1] = x1; + + y_array[0] = y0; + y_array[1] = y1; + } + + public void setIntensities(float r0, float g0, float b0, float a0, + float r1, float g1, float b1, float a1) { + a_array[0] = (a0 * 253f + 1.0f) * 65536f; + a_array[1] = (a1 * 253f + 1.0f) * 65536f; + + // check if we need alpha or not? + if ((a0 != 1.0f) || (a1 != 1.0f)) { + INTERPOLATE_ALPHA = true; + m_drawFlags |= R_ALPHA; + } else { + INTERPOLATE_ALPHA = false; + m_drawFlags &= ~R_ALPHA; + } + + // extra scaling added to prevent color "overflood" due to rounding errors + r_array[0] = (r0 * 253f + 1.0f) * 65536f; + r_array[1] = (r1 * 253f + 1.0f) * 65536f; + + g_array[0] = (g0 * 253f + 1.0f) * 65536f; + g_array[1] = (g1 * 253f + 1.0f) * 65536f; + + b_array[0] = (b0 * 253f + 1.0f) * 65536f; + b_array[1] = (b1 * 253f + 1.0f) * 65536f; + + // check if we need to interpolate the intensity values + if (r0 != r1) { + INTERPOLATE_RGB = true; + m_drawFlags |= R_COLOR; + + } else if (g0 != g1) { + INTERPOLATE_RGB = true; + m_drawFlags |= R_COLOR; + + } else if (b0 != b1) { + INTERPOLATE_RGB = true; + m_drawFlags |= R_COLOR; + + } else { + // when plain we use the stroke color of the first vertex + m_stroke = 0xFF000000 | + ((int)(255*r0) << 16) | ((int)(255*g0) << 8) | (int)(255*b0); + INTERPOLATE_RGB = false; + m_drawFlags &= ~R_COLOR; + } + } + + + public void setIndex(int index) { + m_index = index; + //BLENDER = false; + if (m_index != -1) { + //BLENDER = true; + } else { + m_index = 0; + } + } + + + public void draw() { + int xi; + int yi; + int length; + boolean visible = true; + + if (parent.smooth) { + SMOOTH = true; + m_drawFlags |= R_SMOOTH; + + } else { + SMOOTH = false; + m_drawFlags &= ~R_SMOOTH; + } + + // line hack + if (parent.hints[NO_FLYING_POO]) { + float nwidth2 = -SCREEN_WIDTH; + float nheight2 = -SCREEN_HEIGHT; + float width2 = SCREEN_WIDTH * 2; + float height2 = SCREEN_HEIGHT * 2; + if ((x_array[1] < nwidth2) || + (x_array[1] > width2) || + (x_array[0] < nwidth2) || + (x_array[0] > width2) || + (y_array[1] < nheight2) || + (y_array[1] > height2) || + (y_array[0] < nheight2) || + (y_array[0] > height2)) { + return; // this is a bad line + } + } + + /////////////////////////////////////// + // line clipping + visible = lineClipping(); + if (!visible) { + return; + } + + /////////////////////////////////////// + // calculate line values + int shortLen; + int longLen; + boolean yLonger; + int dt; + + yLonger = false; + + // HACK for drawing lines left-to-right for rev 0069 + // some kind of bug exists with the line-stepping algorithm + // that causes strange patterns in the anti-aliasing. + // [040228 fry] + // + // swap rgba as well as the coords.. oops + // [040712 fry] + // + if (x_array[1] < x_array[0]) { + float t; + + t = x_array[1]; x_array[1] = x_array[0]; x_array[0] = t; + t = y_array[1]; y_array[1] = y_array[0]; y_array[0] = t; + t = z_array[1]; z_array[1] = z_array[0]; z_array[0] = t; + + t = r_array[1]; r_array[1] = r_array[0]; r_array[0] = t; + t = g_array[1]; g_array[1] = g_array[0]; g_array[0] = t; + t = b_array[1]; b_array[1] = b_array[0]; b_array[0] = t; + t = a_array[1]; a_array[1] = a_array[0]; a_array[0] = t; + } + + // important - don't change the casts + // is needed this way for line drawing algorithm + longLen = (int)x_array[1] - (int)x_array[0]; + shortLen = (int)y_array[1] - (int)y_array[0]; + + if (Math.abs(shortLen) > Math.abs(longLen)) { + int swap = shortLen; + shortLen = longLen; + longLen = swap; + yLonger = true; + } + + // now we sort points so longLen is always positive + // and we always start drawing from x[0], y[0] + if (longLen < 0) { + // swap order + o0 = 1; + o1 = 0; + + xi = (int) x_array[1]; + yi = (int) y_array[1]; + + length = -longLen; + + } else { + o0 = 0; + o1 = 1; + + xi = (int) x_array[0]; + yi = (int) y_array[0]; + + length = longLen; + } + + // calculate dt + if (length == 0) { + dt = 0; + } else { + dt = (shortLen << 16) / longLen; + } + + m_r0 = r_array[o0]; + m_g0 = g_array[o0]; + m_b0 = b_array[o0]; + + if (INTERPOLATE_RGB) { + dr = (r_array[o1] - r_array[o0]) / length; + dg = (g_array[o1] - g_array[o0]) / length; + db = (b_array[o1] - b_array[o0]) / length; + } else { + dr = 0; + dg = 0; + db = 0; + } + + m_a0 = a_array[o0]; + + if (INTERPOLATE_ALPHA) { + da = (a_array[o1] - a_array[o0]) / length; + } else { + da = 0; + } + + m_z0 = z_array[o0]; + //z0 += -0.001f; // [rocha] ugly fix for z buffer precision + + if (INTERPOLATE_Z) { + dz = (z_array[o1] - z_array[o0]) / length; + } else { + dz = 0; + } + + // draw thin points + if (length == 0) { + if (INTERPOLATE_ALPHA) { + drawPoint_alpha(xi, yi); + } else { + drawPoint(xi, yi); + } + return; + } + + /* + // draw antialias polygon lines for non stroked polygons + if (BLENDER && SMOOTH) { + // fix for endpoints not being drawn + // [rocha] + drawPoint_alpha((int)x_array[0], (int)x_array[0]); + drawPoint_alpha((int)x_array[1], (int)x_array[1]); + + drawline_blender(x_array[0], y_array[0], x_array[1], y_array[1]); + return; + } + */ + + // draw normal strokes + if (SMOOTH) { + drawLine_smooth(xi, yi, dt, length, yLonger); + + } else { + if (m_drawFlags == 0) { + drawLine_plain(xi, yi, dt, length, yLonger); + + } else if (m_drawFlags == R_ALPHA) { + drawLine_plain_alpha(xi, yi, dt, length, yLonger); + + } else if (m_drawFlags == R_COLOR) { + drawLine_color(xi, yi, dt, length, yLonger); + + } else if (m_drawFlags == (R_COLOR + R_ALPHA)) { + drawLine_color_alpha(xi, yi, dt, length, yLonger); + + } else if (m_drawFlags == R_SPATIAL) { + drawLine_plain_spatial(xi, yi, dt, length, yLonger); + + } else if (m_drawFlags == (R_SPATIAL + R_ALPHA)) { + drawLine_plain_alpha_spatial(xi, yi, dt, length, yLonger); + + } else if (m_drawFlags == (R_SPATIAL + R_COLOR)) { + drawLine_color_spatial(xi, yi, dt, length, yLonger); + + } else if (m_drawFlags == (R_SPATIAL + R_COLOR + R_ALPHA)) { + drawLine_color_alpha_spatial(xi, yi, dt, length, yLonger); + } + } + } + + + public boolean lineClipping() { + // new cohen-sutherland clipping code, as old one was buggy [toxi] + // get the "dips" for the points to clip + int code1 = lineClipCode(x_array[0], y_array[0]); + int code2 = lineClipCode(x_array[1], y_array[1]); + int dip = code1 | code2; + + if ((code1 & code2)!=0) { + + return false; + + } else if (dip != 0) { + + // now calculate the clipped points + float a0 = 0, a1 = 1, a = 0; + + for (int i = 0; i < 4; i++) { + if (((dip>>i)%2)==1){ + a = lineSlope(x_array[0], y_array[0], x_array[1], y_array[1], i+1); + if (((code1 >> i) % 2) == 1) { + a0 = (a>a0)?a:a0; // max(a,a0) + } else { + a1 = (a a1) { + return false; + } else { + float xt = x_array[0]; + float yt = y_array[0]; + + x_array[0] = xt + a0 * (x_array[1] - xt); + y_array[0] = yt + a0 * (y_array[1] - yt); + x_array[1] = xt + a1 * (x_array[1] - xt); + y_array[1] = yt + a1 * (y_array[1] - yt); + + // interpolate remaining parameters + if (INTERPOLATE_RGB) { + float t = r_array[0]; + r_array[0] = t + a0 * (r_array[1] - t); + r_array[1] = t + a1 * (r_array[1] - t); + t = g_array[0]; + g_array[0] = t + a0 * (g_array[1] - t); + g_array[1] = t + a1 * (g_array[1] - t); + t = b_array[0]; + b_array[0] = t + a0 * (b_array[1] - t); + b_array[1] = t + a1 * (b_array[1] - t); + } + + if (INTERPOLATE_ALPHA) { + float t = a_array[0]; + a_array[0] = t + a0 * (a_array[1] - t); + a_array[1] = t + a1 * (a_array[1] - t); + } + } + } + return true; + } + + + private int lineClipCode(float xi, float yi) { + int xmin = 0; + int ymin = 0; + int xmax = SCREEN_WIDTH1; + int ymax = SCREEN_HEIGHT1; + + //return ((yi < ymin ? 8 : 0) | (yi > ymax ? 4 : 0) | + // (xi < xmin ? 2 : 0) | (xi > xmax ? 1 : 0)); + //(int) added by ewjordan 6/13/07 because otherwise we sometimes clip last pixel when it should actually be displayed. + //Currently the min values are okay because values less than 0 should not be rendered; however, bear in mind that + //(int) casts towards zero, so without this clipping, values between -1+eps and +1-eps would all be rendered as 0. + return ((yi < ymin ? 8 : 0) | ((int)yi > ymax ? 4 : 0) | + (xi < xmin ? 2 : 0) | ((int)xi > xmax ? 1 : 0)); + } + + + private float lineSlope(float x1, float y1, float x2, float y2, int border) { + int xmin = 0; + int ymin = 0; + int xmax = SCREEN_WIDTH1; + int ymax = SCREEN_HEIGHT1; + + switch (border) { + case 4: return (ymin-y1)/(y2-y1); + case 3: return (ymax-y1)/(y2-y1); + case 2: return (xmin-x1)/(x2-x1); + case 1: return (xmax-x1)/(x2-x1); + } + return -1f; + } + + + private void drawPoint(int x0, int y0) { + float iz = m_z0; + int offset = y0 * SCREEN_WIDTH + x0; + + if (iz <= m_zbuffer[offset]) { + m_pixels[offset] = m_stroke; + m_zbuffer[offset] = iz; + } + } + + + private void drawPoint_alpha(int x0, int y0) { + int ia = (int) a_array[0]; + int pr = m_stroke & 0xFF0000; + int pg = m_stroke & 0xFF00; + int pb = m_stroke & 0xFF; + float iz = m_z0; + int offset = y0 * SCREEN_WIDTH + x0; + + if (iz <= m_zbuffer[offset]) { + int alpha = ia >> 16; + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0 &= 0xFF0000; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + //m_zbuffer[offset] = iz; + } + } + + + private void drawLine_plain(int x0, int y0, int dt, + int length, boolean vertical) { + // new "extremely fast" line code + // adapted from http://www.edepot.com/linee.html + // first version modified by [toxi] + // simplified by [rocha] + // length must be >= 0 + + //assert length>=0:length; + + int offset = 0; + + if (vertical) { + // vertical + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + m_pixels[offset] = m_stroke; + m_zbuffer[offset] = m_z0; + j+=dt; + } + + } else { + // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + m_pixels[offset] = m_stroke; + //m_zbuffer[offset] = m_z0; + j+=dt; + } + } + } + + + private void drawLine_plain_alpha(int x0, int y0, int dt, + int length, boolean vertical) { + int offset = 0; + + int pr = m_stroke & 0xFF0000; + int pg = m_stroke & 0xFF00; + int pb = m_stroke & 0xFF; + + int ia = (int) (m_a0); + + if (vertical) { + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + + int alpha = ia >> 16; + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0 &= 0xFF0000; + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = m_z0; + + ia += da; + j += dt; + } + + } else { // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + + int alpha = ia >> 16; + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0&=0xFF0000; + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = m_z0; + + ia += da; + j += dt; + } + } + } + + + private void drawLine_color(int x0, int y0, int dt, + int length, boolean vertical) { + int offset = 0; + + int ir = (int) m_r0; + int ig = (int) m_g0; + int ib = (int) m_b0; + + if (vertical) { + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + m_pixels[offset] = 0xFF000000 | + ((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16)); + m_zbuffer[offset] = m_z0; + ir += dr; + ig += dg; + ib += db; + j +=dt; + } + + } else { // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + m_pixels[offset] = 0xFF000000 | + ((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16)); + m_zbuffer[offset] = m_z0; + ir += dr; + ig += dg; + ib += db; + j += dt; + } + } + } + + + private void drawLine_color_alpha(int x0, int y0, int dt, + int length, boolean vertical) { + int offset = 0; + + int ir = (int) m_r0; + int ig = (int) m_g0; + int ib = (int) m_b0; + int ia = (int) m_a0; + + if (vertical) { + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + + int pr = ir & 0xFF0000; + int pg = (ig >> 8) & 0xFF00; + int pb = (ib >> 16); + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0&=0xFF0000; + + int alpha = ia >> 16; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = m_z0; + + ir+= dr; + ig+= dg; + ib+= db; + ia+= da; + j+=dt; + } + + } else { // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + + int pr = ir & 0xFF0000; + int pg = (ig >> 8) & 0xFF00; + int pb = (ib >> 16); + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0&=0xFF0000; + + int alpha = ia >> 16; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = m_z0; + + ir+= dr; + ig+= dg; + ib+= db; + ia+= da; + j+=dt; + } + } + } + + + private void drawLine_plain_spatial(int x0, int y0, int dt, + int length, boolean vertical) { + int offset = 0; + float iz = m_z0; + + if (vertical) { + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + if (iz <= m_zbuffer[offset]) { + m_pixels[offset] = m_stroke; + m_zbuffer[offset] = iz; + } + iz+=dz; + j+=dt; + } + + } else { // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + if (iz <= m_zbuffer[offset]) { + m_pixels[offset] = m_stroke; + m_zbuffer[offset] = iz; + } + iz+=dz; + j+=dt; + } + } + } + + + private void drawLine_plain_alpha_spatial(int x0, int y0, int dt, + int length, boolean vertical) { + int offset = 0; + float iz = m_z0; + + int pr = m_stroke & 0xFF0000; + int pg = m_stroke & 0xFF00; + int pb = m_stroke & 0xFF; + + int ia = (int) m_a0; + + if (vertical) { + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + + if (iz <= m_zbuffer[offset]) { + int alpha = ia >> 16; + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0 &= 0xFF0000; + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + //m_zbuffer[offset] = iz; + } + iz +=dz; + ia += da; + j += dt; + } + + } else { // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + + if (iz <= m_zbuffer[offset]) { + int alpha = ia >> 16; + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0&=0xFF0000; + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + //m_zbuffer[offset] = iz; + } + iz += dz; + ia += da; + j += dt; + } + } + } + + + private void drawLine_color_spatial(int x0, int y0, int dt, + int length, boolean vertical) { + int offset = 0; + float iz = m_z0; + + int ir = (int) m_r0; + int ig = (int) m_g0; + int ib = (int) m_b0; + + if (vertical) { + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + + if (iz <= m_zbuffer[offset]) { + m_pixels[offset] = 0xFF000000 | + ((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16)); + m_zbuffer[offset] = iz; + } + iz +=dz; + ir += dr; + ig += dg; + ib += db; + j += dt; + } + } else { // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + if (iz <= m_zbuffer[offset]) { + m_pixels[offset] = 0xFF000000 | + ((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16)); + m_zbuffer[offset] = iz; + } + iz += dz; + ir += dr; + ig += dg; + ib += db; + j += dt; + } + return; + } + } + + + private void drawLine_color_alpha_spatial(int x0, int y0, int dt, + int length, boolean vertical) { + int offset = 0; + float iz = m_z0; + + int ir = (int) m_r0; + int ig = (int) m_g0; + int ib = (int) m_b0; + int ia = (int) m_a0; + + if (vertical) { + length += y0; + for (int j = 0x8000 + (x0<<16); y0 <= length; ++y0) { + offset = y0 * SCREEN_WIDTH + (j>>16); + + if (iz <= m_zbuffer[offset]) { + int pr = ir & 0xFF0000; + int pg = (ig >> 8) & 0xFF00; + int pb = (ib >> 16); + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0&=0xFF0000; + + int alpha = ia >> 16; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = iz; + } + iz+=dz; + ir+= dr; + ig+= dg; + ib+= db; + ia+= da; + j+=dt; + } + + } else { // horizontal + length += x0; + for (int j = 0x8000 + (y0<<16); x0 <= length; ++x0) { + offset = (j>>16) * SCREEN_WIDTH + x0; + + if (iz <= m_zbuffer[offset]) { + int pr = ir & 0xFF0000; + int pg = (ig >> 8) & 0xFF00; + int pb = (ib >> 16); + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0 &= 0xFF0000; + + int alpha = ia >> 16; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = iz; + } + iz += dz; + ir += dr; + ig += dg; + ib += db; + ia += da; + j += dt; + } + } + } + + + void drawLine_smooth(int x0, int y0, int dt, + int length, boolean vertical) { + int xi, yi; // these must be >=32 bits + int offset = 0; + int temp; + int end; + + float iz = m_z0; + + int ir = (int) m_r0; + int ig = (int) m_g0; + int ib = (int) m_b0; + int ia = (int) m_a0; + + if (vertical) { + xi = x0 << 16; + yi = y0 << 16; + + end = length + y0; + + while ((yi >> 16) < end) { + + offset = (yi>>16) * SCREEN_WIDTH + (xi>>16); + + int pr = ir & 0xFF0000; + int pg = (ig >> 8) & 0xFF00; + int pb = (ib >> 16); + + if (iz <= m_zbuffer[offset]) { + int alpha = (((~xi >> 8) & 0xFF) * (ia >> 16)) >> 8; + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0&=0xFF0000; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = iz; + } + + // this if() makes things slow. there shoudl be + // a better way to check if the second pixel is + // withing the image array [rocha] + temp = ((xi>>16)+1); + if (temp >= SCREEN_WIDTH) { + xi += dt; + yi += (1 << 16); + continue; + } + + offset = (yi>>16) * SCREEN_WIDTH + temp; + + if (iz <= m_zbuffer[offset]) { + int alpha = (((xi >> 8) & 0xFF) * (ia >> 16)) >> 8; + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0 &= 0xFF0000; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = iz; + } + + xi += dt; + yi += (1 << 16); + + iz+=dz; + ir+= dr; + ig+= dg; + ib+= db; + ia+= da; + } + + } else { // horizontal + xi = x0 << 16; + yi = y0 << 16; + end = length + x0; + + while ((xi >> 16) < end) { + offset = (yi>>16) * SCREEN_WIDTH + (xi>>16); + + int pr = ir & 0xFF0000; + int pg = (ig >> 8) & 0xFF00; + int pb = (ib >> 16); + + if (iz <= m_zbuffer[offset]) { + int alpha = (((~yi >> 8) & 0xFF) * (ia >> 16)) >> 8; + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0 &= 0xFF0000; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = iz; + } + + // see above [rocha] + temp = ((yi>>16)+1); + if (temp >= SCREEN_HEIGHT) { + xi += (1 << 16); + yi += dt; + continue; + } + + offset = temp * SCREEN_WIDTH + (xi>>16); + + if (iz <= m_zbuffer[offset]) { + int alpha = (((yi >> 8) & 0xFF) * (ia >> 16)) >> 8; + + int r0 = m_pixels[offset]; + int g0 = r0 & 0xFF00; + int b0 = r0 & 0xFF; + r0&=0xFF0000; + + r0 = r0 + (((pr - r0) * alpha) >> 8); + g0 = g0 + (((pg - g0) * alpha) >> 8); + b0 = b0 + (((pb - b0) * alpha) >> 8); + + m_pixels[offset] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + m_zbuffer[offset] = iz; + } + + xi += (1 << 16); + yi += dt; + + iz+=dz; + ir+= dr; + ig+= dg; + ib+= db; + ia+= da; + } + } + } + + + /** + * Special "blender" line code by sami, + * used for anti-aliasing polygon edges + */ + /* + private void drawline_blender(double x0, double y0, double x1, double y1) + { + double tmp; + double dx = x1-x0; + double dy = y1-y0; + double adx = (dx >= 0) ? dx : -dx; + double ady = (dy >= 0) ? dy : -dy; + + // VERY small line --> skip + if (adx < 0.0001d && ady < 0.0001d) + return; + + // pixel color + int pxl; + + // vaakaviiva + if (adx > ady) { + // flip if x0 > x1 + if (x0 > x1) { + tmp = x0; + x0 = x1; + x1 = tmp; + tmp = y0; + y0 = y1; + y1 = tmp; + dx = x1-x0; + dy = y1-y0; + } + + // add interpolation params here + double addy = dy / dx; + + int ix0 = (int) (x0 + PIXEL_CENTER); + if (ix0 < 0) + ix0 = 0; + + int ix1 = (int) (x1 + PIXEL_CENTER); + if (ix1 > SCREEN_WIDTH) + ix1 = SCREEN_WIDTH; + + double delta = (ix0 + PIXEL_CENTER) - x0; + double ys = y0 + delta * addy; + + for (int a = ix0; a < ix1; a++,ys+=addy) { + int iy = (int) (ys - PIXEL_CENTER); + if ((iy >= 0) && (iy < SCREEN_HEIGHT1)) { + int ofs1 = iy * SCREEN_WIDTH + a; + int ofs2 = ofs1 + SCREEN_WIDTH; + + if (m_stencil[ofs1] == m_index) { + pxl = m_pixels[ofs1]; + } else if (m_stencil[ofs2] == m_index) { + pxl = m_pixels[ofs2]; + } else { + //m_pixels[ofs1] = 0xFFFFFF; + //m_pixels[ofs2] = 0xFFFFFF; + continue; + } + + double frcf = ys - PIXEL_CENTER; + + int frac1 = ((int) (frcf * 256f) & 0xFF); + int frac2 = 255 - frac1; + int pr = (pxl & 0xFF0000); + int pg = (pxl & 0xFF00); + int pb = (pxl & 0xFF); + + int r0 = m_pixels[ofs1]; + int g0 = (r0 & 0xFF00); + int b0 = (r0 & 0xFF); + r0 = (r0 & 0xFF0000); + r0 = r0 + (((pr - r0) * frac2) >> 8); + g0 = g0 + (((pg - g0) * frac2) >> 8); + b0 = b0 + (((pb - b0) * frac2) >> 8); + m_pixels[ofs1] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + + r0 = m_pixels[ofs2]; + g0 = (r0 & 0xFF00); + b0 = (r0 & 0xFF); + r0 = (r0 & 0xFF0000); + r0 = r0 + (((pr - r0) * frac1) >> 8); + g0 = g0 + (((pg - g0) * frac1) >> 8); + b0 = b0 + (((pb - b0) * frac1) >> 8); + m_pixels[ofs2] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + + //m_pixels[ofs1] = 0xFF00FF; + //m_pixels[ofs2] = 0xFFFF00; + } + } + } else { // pystyviiva + // flip if y1 > y0 + if (y0 > y1) { + tmp = x0; + x0 = x1; + x1 = tmp; + tmp = y0; + y0 = y1; + y1 = tmp; + dx = x1-x0; + dy = y1-y0; + } + + double addx = dx / dy; + int iy0 = (int) (y0 + PIXEL_CENTER); + if (iy0 < 0) + iy0 = 0; + int iy1 = (int) (y1 + PIXEL_CENTER); + if (iy1 > SCREEN_HEIGHT) + iy1 = SCREEN_HEIGHT; + + double delta = (iy0 + PIXEL_CENTER) - y0; + double xs = x0 + delta * addx; + + iy0*=SCREEN_WIDTH; + iy1*=SCREEN_WIDTH; + for (int a = iy0; a < iy1; a+=SCREEN_WIDTH,xs+=addx) { + int ix = (int) (xs - PIXEL_CENTER); + if ((ix >= 0) && (ix < SCREEN_WIDTH1)) { + int ofs1 = a + ix; + int ofs2 = ofs1+1; + + if (m_stencil[ofs1] == m_index) { + pxl = m_pixels[ofs1]; + } else if (m_stencil[ofs2] == m_index) { + pxl = m_pixels[ofs2]; + } else { + //m_pixels[ofs1] = 0xFFFFFF; + //m_pixels[ofs2] = 0xFFFFFF; + continue; + } + + int pr = (pxl & 0xFF0000); + int pg = (pxl & 0xFF00); + int pb = (pxl & 0xFF); + + double frcf = xs - PIXEL_CENTER; + int frac1 = ((int) (frcf * 256f) & 0xFF); + int frac2 = 255 - frac1; + + int r0 = m_pixels[ofs1]; + int g0 = (r0 & 0xFF00); + int b0 = (r0 & 0xFF); + r0 = (r0 & 0xFF0000); + r0 = r0 + (((pr - r0) * frac2) >> 8); + g0 = g0 + (((pg - g0) * frac2) >> 8); + b0 = b0 + (((pb - b0) * frac2) >> 8); + m_pixels[ofs1] = 0xFF000000 | + (r0 & 0xFF0000) | (g0 & 0xFF00) | (b0 & 0xFF); + + r0 = m_pixels[ofs2]; + g0 = (r0 & 0xFF00); + b0 = (r0 & 0xFF); + r0 = (r0 & 0xFF0000); + r0 = r0 + (((pr - r0) * frac1) >> 8); + g0 = g0 + (((pg - g0) * frac1) >> 8); + b0 = b0 + (((pb - b0) * frac1) >> 8); + + //m_pixels[ofs1] = 0x0000FF; + //m_pixels[ofs2] = 0x00FFFF; + } + } + } + } + */ +} diff --git a/core/PMatrix.java b/core/PMatrix.java new file mode 100644 index 000000000..9b19da613 --- /dev/null +++ b/core/PMatrix.java @@ -0,0 +1,640 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://Proce55ing.net + + Copyright (c) 2005-06 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + + +/** + * 4x4 matrix implementation. + */ +public final class PMatrix implements PConstants { + + public float m00, m01, m02, m03; + public float m10, m11, m12, m13; + public float m20, m21, m22, m23; + public float m30, m31, m32, m33; + + final static int DEFAULT_STACK_DEPTH = 0; + int maxStackDepth; + int stackPointer = 0; + float stack[][]; + + + // locally allocated version to avoid creating new memory + static protected PMatrix inverseCopy; + + + public PMatrix() { + set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + maxStackDepth = DEFAULT_STACK_DEPTH; + } + + + public PMatrix(int stackDepth) { + set(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + stack = new float[stackDepth][16]; + maxStackDepth = stackDepth; + } + + + public PMatrix(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) { + set(m00, m01, m02, m03, + m10, m11, m12, m13, + m20, m21, m22, m23, + m30, m31, m32, m33); + maxStackDepth = DEFAULT_STACK_DEPTH; + } + + + // Make a copy of a matrix. We copy the stack depth, + // but we don't make a copy of the stack or the stack pointer. + public PMatrix(PMatrix src) { + set(src); + maxStackDepth = src.maxStackDepth; + stack = new float[maxStackDepth][16]; + } + + + public void reset() { + set(1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + } + + + public void clearStack() { + stackPointer = 0; + } + + + public boolean push() { + if (stackPointer == maxStackDepth) return false; + + stack[stackPointer][0] = m00; + stack[stackPointer][1] = m01; + stack[stackPointer][2] = m02; + stack[stackPointer][3] = m03; + + stack[stackPointer][4] = m10; + stack[stackPointer][5] = m11; + stack[stackPointer][6] = m12; + stack[stackPointer][7] = m13; + + stack[stackPointer][8] = m20; + stack[stackPointer][9] = m21; + stack[stackPointer][10] = m22; + stack[stackPointer][11] = m23; + + stack[stackPointer][12] = m30; + stack[stackPointer][13] = m31; + stack[stackPointer][14] = m32; + stack[stackPointer][15] = m33; + + stackPointer++; + return true; + } + + + public boolean pop() { + if (stackPointer == 0) return false; + stackPointer--; + + m00 = stack[stackPointer][0]; + m01 = stack[stackPointer][1]; + m02 = stack[stackPointer][2]; + m03 = stack[stackPointer][3]; + + m10 = stack[stackPointer][4]; + m11 = stack[stackPointer][5]; + m12 = stack[stackPointer][6]; + m13 = stack[stackPointer][7]; + + m20 = stack[stackPointer][8]; + m21 = stack[stackPointer][9]; + m22 = stack[stackPointer][10]; + m23 = stack[stackPointer][11]; + + m30 = stack[stackPointer][12]; + m31 = stack[stackPointer][13]; + m32 = stack[stackPointer][14]; + m33 = stack[stackPointer][15]; + + return true; + } + + + public void set(PMatrix src) { + set(src.m00, src.m01, src.m02, src.m03, + src.m10, src.m11, src.m12, src.m13, + src.m20, src.m21, src.m22, src.m23, + src.m30, src.m31, src.m32, src.m33); + } + + + public void set(float m00, float m01, float m02, float m03, + float m10, float m11, float m12, float m13, + float m20, float m21, float m22, float m23, + float m30, float m31, float m32, float m33) { + this.m00 = m00; this.m01 = m01; this.m02 = m02; this.m03 = m03; + this.m10 = m10; this.m11 = m11; this.m12 = m12; this.m13 = m13; + this.m20 = m20; this.m21 = m21; this.m22 = m22; this.m23 = m23; + this.m30 = m30; this.m31 = m31; this.m32 = m32; this.m33 = m33; + } + + + public void translate(float tx, float ty) { + translate(tx, ty, 0); + } + + public void invTranslate(float tx, float ty) { + invTranslate(tx, ty, 0); + } + + + public void translate(float tx, float ty, float tz) { + m03 += tx*m00 + ty*m01 + tz*m02; + m13 += tx*m10 + ty*m11 + tz*m12; + m23 += tx*m20 + ty*m21 + tz*m22; + m33 += tx*m30 + ty*m31 + tz*m32; + } + + public void invTranslate(float tx, float ty, float tz) { + preApply(1, 0, 0, -tx, + 0, 1, 0, -ty, + 0, 0, 1, -tz, + 0, 0, 0, 1); + } + + + // OPT could save several multiplies for the 0s and 1s by just + // putting the multMatrix code here and removing uneccessary terms + + public void rotateX(float angle) { + float c = cos(angle); + float s = sin(angle); + apply(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); + } + + + public void invRotateX(float angle) { + float c = cos(-angle); + float s = sin(-angle); + preApply(1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1); + } + + + public void rotateY(float angle) { + float c = cos(angle); + float s = sin(angle); + apply(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); + } + + + public void invRotateY(float angle) { + float c = cos(-angle); + float s = sin(-angle); + preApply(c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1); + } + + + /** + * Just calls rotateZ because two dimensional rotation + * is the same as rotating along the z-axis. + */ + public void rotate(float angle) { + rotateZ(angle); + } + + + public void invRotate(float angle) { + invRotateZ(angle); + } + + + public void rotateZ(float angle) { + float c = cos(angle); + float s = sin(angle); + apply(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } + + + public void invRotateZ(float angle) { + float c = cos(-angle); + float s = sin(-angle); + preApply(c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } + + + public void rotate(float angle, float v0, float v1, float v2) { + // should be in radians (i think), instead of degrees (gl uses degrees) + // based on 15-463 code, but similar to opengl ref p.443 + + // TODO should make sure this vector is normalized + + float c = cos(angle); + float s = sin(angle); + float t = 1.0f - c; + + apply((t*v0*v0) + c, (t*v0*v1) - (s*v2), (t*v0*v2) + (s*v1), 0, + (t*v0*v1) + (s*v2), (t*v1*v1) + c, (t*v1*v2) - (s*v0), 0, + (t*v0*v2) - (s*v1), (t*v1*v2) + (s*v0), (t*v2*v2) + c, 0, + 0, 0, 0, 1); + } + + + public void invRotate(float angle, float v0, float v1, float v2) { + // TODO should make sure this vector is normalized + + float c = cos(-angle); + float s = sin(-angle); + float t = 1.0f - c; + + preApply((t*v0*v0) + c, (t*v0*v1) - (s*v2), (t*v0*v2) + (s*v1), 0, + (t*v0*v1) + (s*v2), (t*v1*v1) + c, (t*v1*v2) - (s*v0), 0, + (t*v0*v2) - (s*v1), (t*v1*v2) + (s*v0), (t*v2*v2) + c, 0, + 0, 0, 0, 1); + } + + + public void scale(float s) { + apply(s, 0, 0, 0, 0, s, 0, 0, 0, 0, s, 0, 0, 0, 0, 1); + } + + + public void invScale(float s) { + preApply(1/s, 0, 0, 0, 0, 1/s, 0, 0, 0, 0, 1/s, 0, 0, 0, 0, 1); + } + + + public void scale(float sx, float sy) { + apply(sx, 0, 0, 0, 0, sy, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } + + + public void invScale(float sx, float sy) { + preApply(1/sx, 0, 0, 0, 0, 1/sy, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + } + + + // OPTIMIZE: same as above + public void scale(float x, float y, float z) { + apply(x, 0, 0, 0, 0, y, 0, 0, 0, 0, z, 0, 0, 0, 0, 1); + } + + + public void invScale(float x, float y, float z) { + preApply(1/x, 0, 0, 0, 0, 1/y, 0, 0, 0, 0, 1/z, 0, 0, 0, 0, 1); + } + + + /* + public void transform(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + apply(n00, n01, n02, n03, + n10, n11, n12, n13, + n20, n21, n22, n23, + n30, n31, n32, n33); + } + */ + + + public void preApply(PMatrix lhs) { + preApply(lhs.m00, lhs.m01, lhs.m02, lhs.m03, + lhs.m10, lhs.m11, lhs.m12, lhs.m13, + lhs.m20, lhs.m21, lhs.m22, lhs.m23, + lhs.m30, lhs.m31, lhs.m32, lhs.m33); + } + + + // for inverse operations, like multiplying the matrix on the left + public void preApply(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + + float r00 = n00*m00 + n01*m10 + n02*m20 + n03*m30; + float r01 = n00*m01 + n01*m11 + n02*m21 + n03*m31; + float r02 = n00*m02 + n01*m12 + n02*m22 + n03*m32; + float r03 = n00*m03 + n01*m13 + n02*m23 + n03*m33; + + float r10 = n10*m00 + n11*m10 + n12*m20 + n13*m30; + float r11 = n10*m01 + n11*m11 + n12*m21 + n13*m31; + float r12 = n10*m02 + n11*m12 + n12*m22 + n13*m32; + float r13 = n10*m03 + n11*m13 + n12*m23 + n13*m33; + + float r20 = n20*m00 + n21*m10 + n22*m20 + n23*m30; + float r21 = n20*m01 + n21*m11 + n22*m21 + n23*m31; + float r22 = n20*m02 + n21*m12 + n22*m22 + n23*m32; + float r23 = n20*m03 + n21*m13 + n22*m23 + n23*m33; + + float r30 = n30*m00 + n31*m10 + n32*m20 + n33*m30; + float r31 = n30*m01 + n31*m11 + n32*m21 + n33*m31; + float r32 = n30*m02 + n31*m12 + n32*m22 + n33*m32; + float r33 = n30*m03 + n31*m13 + n32*m23 + n33*m33; + + m00 = r00; m01 = r01; m02 = r02; m03 = r03; + m10 = r10; m11 = r11; m12 = r12; m13 = r13; + m20 = r20; m21 = r21; m22 = r22; m23 = r23; + m30 = r30; m31 = r31; m32 = r32; m33 = r33; + } + + + public boolean invApply(PMatrix rhs) { + PMatrix copy = new PMatrix(rhs); + PMatrix inverse = copy.invert(); + if (inverse == null) return false; + preApply(inverse); + return true; + } + + + public boolean invApply(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + if (inverseCopy == null) { + inverseCopy = new PMatrix(); + } + inverseCopy.set(n00, n01, n02, n03, + n10, n11, n12, n13, + n20, n21, n22, n23, + n30, n31, n32, n33); + PMatrix inverse = inverseCopy.invert(); + if (inverse == null) return false; + preApply(inverse); + return true; + } + + + public void apply(PMatrix rhs) { + apply(rhs.m00, rhs.m01, rhs.m02, rhs.m03, + rhs.m10, rhs.m11, rhs.m12, rhs.m13, + rhs.m20, rhs.m21, rhs.m22, rhs.m23, + rhs.m30, rhs.m31, rhs.m32, rhs.m33); + } + + + public void apply(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + + float r00 = m00*n00 + m01*n10 + m02*n20 + m03*n30; + float r01 = m00*n01 + m01*n11 + m02*n21 + m03*n31; + float r02 = m00*n02 + m01*n12 + m02*n22 + m03*n32; + float r03 = m00*n03 + m01*n13 + m02*n23 + m03*n33; + + float r10 = m10*n00 + m11*n10 + m12*n20 + m13*n30; + float r11 = m10*n01 + m11*n11 + m12*n21 + m13*n31; + float r12 = m10*n02 + m11*n12 + m12*n22 + m13*n32; + float r13 = m10*n03 + m11*n13 + m12*n23 + m13*n33; + + float r20 = m20*n00 + m21*n10 + m22*n20 + m23*n30; + float r21 = m20*n01 + m21*n11 + m22*n21 + m23*n31; + float r22 = m20*n02 + m21*n12 + m22*n22 + m23*n32; + float r23 = m20*n03 + m21*n13 + m22*n23 + m23*n33; + + float r30 = m30*n00 + m31*n10 + m32*n20 + m33*n30; + float r31 = m30*n01 + m31*n11 + m32*n21 + m33*n31; + float r32 = m30*n02 + m31*n12 + m32*n22 + m33*n32; + float r33 = m30*n03 + m31*n13 + m32*n23 + m33*n33; + + m00 = r00; m01 = r01; m02 = r02; m03 = r03; + m10 = r10; m11 = r11; m12 = r12; m13 = r13; + m20 = r20; m21 = r21; m22 = r22; m23 = r23; + m30 = r30; m31 = r31; m32 = r32; m33 = r33; + } + + + public void mult3(float vec[], float out[]) { + // must use these temp vars because vec may be the same as out + float tmpx = m00*vec[0] + m01*vec[1] + m02*vec[2] + m03; + float tmpy = m10*vec[0] + m11*vec[1] + m12*vec[2] + m13; + float tmpz = m20*vec[0] + m21*vec[1] + m22*vec[2] + m23; + + out[0] = tmpx; + out[1] = tmpy; + out[2] = tmpz; + } + + + public void mult(float vec[], float out[]) { + // must use these temp vars because vec may be the same as out + float tmpx = m00*vec[0] + m01*vec[1] + m02*vec[2] + m03*vec[3]; + float tmpy = m10*vec[0] + m11*vec[1] + m12*vec[2] + m13*vec[3]; + float tmpz = m20*vec[0] + m21*vec[1] + m22*vec[2] + m23*vec[3]; + float tmpw = m30*vec[0] + m31*vec[1] + m32*vec[2] + m33*vec[3]; + + out[0] = tmpx; + out[1] = tmpy; + out[2] = tmpz; + out[3] = tmpw; + } + + + /** + * @return the determinant of the matrix + */ + public float determinant() { + float f = + m00 + * ((m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32) + - m13 * m22 * m31 + - m11 * m23 * m32 + - m12 * m21 * m33); + f -= m01 + * ((m10 * m22 * m33 + m12 * m23 * m30 + m13 * m20 * m32) + - m13 * m22 * m30 + - m10 * m23 * m32 + - m12 * m20 * m33); + f += m02 + * ((m10 * m21 * m33 + m11 * m23 * m30 + m13 * m20 * m31) + - m13 * m21 * m30 + - m10 * m23 * m31 + - m11 * m20 * m33); + f -= m03 + * ((m10 * m21 * m32 + m11 * m22 * m30 + m12 * m20 * m31) + - m12 * m21 * m30 + - m10 * m22 * m31 + - m11 * m20 * m32); + return f; + } + + + /** + * Calculate the determinant of a 3x3 matrix + * @return result + */ + private float determinant3x3(float t00, float t01, float t02, + float t10, float t11, float t12, + float t20, float t21, float t22) { + return (t00 * (t11 * t22 - t12 * t21) + + t01 * (t12 * t20 - t10 * t22) + + t02 * (t10 * t21 - t11 * t20)); + } + + + public PMatrix transpose() { + float temp; + temp = m01; m01 = m10; m10 = temp; + temp = m02; m02 = m20; m20 = temp; + temp = m03; m03 = m30; m30 = temp; + temp = m12; m12 = m21; m21 = temp; + temp = m13; m13 = m31; m31 = temp; + temp = m23; m23 = m32; m32 = temp; + return this; + } + + + /** + * Invert this matrix + * @return this if successful, null otherwise + */ + public PMatrix invert() { + + float determinant = determinant(); + + if (determinant != 0) { + // m00 m01 m02 m03 + // m10 m11 m12 m13 + // m20 m21 m22 m23 + // m30 m31 m32 m33 + float determinant_inv = 1f / determinant; + + // first row + float t00 = determinant3x3(m11, m12, m13, m21, m22, m23, m31, m32, m33); + float t01 = -determinant3x3(m10, m12, m13, m20, m22, m23, m30, m32, m33); + float t02 = determinant3x3(m10, m11, m13, m20, m21, m23, m30, m31, m33); + float t03 = -determinant3x3(m10, m11, m12, m20, m21, m22, m30, m31, m32); + + // second row + float t10 = -determinant3x3(m01, m02, m03, m21, m22, m23, m31, m32, m33); + float t11 = determinant3x3(m00, m02, m03, m20, m22, m23, m30, m32, m33); + float t12 = -determinant3x3(m00, m01, m03, m20, m21, m23, m30, m31, m33); + float t13 = determinant3x3(m00, m01, m02, m20, m21, m22, m30, m31, m32); + + // third row + float t20 = determinant3x3(m01, m02, m03, m11, m12, m13, m31, m32, m33); + float t21 = -determinant3x3(m00, m02, m03, m10, m12, m13, m30, m32, m33); + float t22 = determinant3x3(m00, m01, m03, m10, m11, m13, m30, m31, m33); + float t23 = -determinant3x3(m00, m01, m02, m10, m11, m12, m30, m31, m32); + + // fourth row + float t30 = -determinant3x3(m01, m02, m03, m11, m12, m13, m21, m22, m23); + float t31 = determinant3x3(m00, m02, m03, m10, m12, m13, m20, m22, m23); + float t32 = -determinant3x3(m00, m01, m03, m10, m11, m13, m20, m21, m23); + float t33 = determinant3x3(m00, m01, m02, m10, m11, m12, m20, m21, m22); + + // transpose and divide by the determinant + m00 = t00*determinant_inv; + m11 = t11*determinant_inv; + m22 = t22*determinant_inv; + m33 = t33*determinant_inv; + m01 = t10*determinant_inv; + m10 = t01*determinant_inv; + m20 = t02*determinant_inv; + m02 = t20*determinant_inv; + m12 = t21*determinant_inv; + m21 = t12*determinant_inv; + m03 = t30*determinant_inv; + m30 = t03*determinant_inv; + m13 = t31*determinant_inv; + m31 = t13*determinant_inv; + m32 = t23*determinant_inv; + m23 = t32*determinant_inv; + return this; + } + return null; + } + + + ////////////////////////////////////////////////////////////// + + + public void print() { + int big = (int) Math.abs(max(max(max(max(abs(m00), abs(m01)), + max(abs(m02), abs(m03))), + max(max(abs(m10), abs(m11)), + max(abs(m12), abs(m13)))), + max(max(max(abs(m20), abs(m21)), + max(abs(m22), abs(m23))), + max(max(abs(m30), abs(m31)), + max(abs(m32), abs(m33)))))); + + // avoid infinite loop + if (Float.isNaN(big) || Float.isInfinite(big)) { + big = 1000000; // set to something arbitrary + } + + int d = 1; + while ((big /= 10) != 0) d++; // cheap log() + + System.out.println(PApplet.nfs(m00, d, 4) + " " + + PApplet.nfs(m01, d, 4) + " " + + PApplet.nfs(m02, d, 4) + " " + + PApplet.nfs(m03, d, 4)); + + System.out.println(PApplet.nfs(m10, d, 4) + " " + + PApplet.nfs(m11, d, 4) + " " + + PApplet.nfs(m12, d, 4) + " " + + PApplet.nfs(m13, d, 4)); + + System.out.println(PApplet.nfs(m20, d, 4) + " " + + PApplet.nfs(m21, d, 4) + " " + + PApplet.nfs(m22, d, 4) + " " + + PApplet.nfs(m23, d, 4)); + + System.out.println(PApplet.nfs(m30, d, 4) + " " + + PApplet.nfs(m31, d, 4) + " " + + PApplet.nfs(m32, d, 4) + " " + + PApplet.nfs(m33, d, 4)); + + System.out.println(); + } + + + ////////////////////////////////////////////////////////////// + + + private final float max(float a, float b) { + return (a > b) ? a : b; + } + + private final float abs(float a) { + return (a < 0) ? -a : a; + } + + private final float sin(float angle) { + return (float)Math.sin(angle); + } + + private final float cos(float angle) { + return (float)Math.cos(angle); + } +} diff --git a/core/PPolygon.java b/core/PPolygon.java new file mode 100644 index 000000000..4c355dde7 --- /dev/null +++ b/core/PPolygon.java @@ -0,0 +1,772 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + + +/** + * zbuffer polygon rendering object for PGraphics. + *

    + * Likely to be removed before 1.0 as it's no longer particularly used. + */ +public class PPolygon implements PConstants { + + // identical to the constants from PGraphics + + static final int X = 0; // transformed xyzw + static final int Y = 1; // formerly SX SY SZ + static final int Z = 2; + + static final int R = 3; // actual rgb, after lighting + static final int G = 4; // fill stored here, transform in place + static final int B = 5; + static final int A = 6; + + static final int U = 7; // texture + static final int V = 8; + + // + + static final int DEFAULT_SIZE = 64; // this is needed for spheres + float vertices[][] = new float[DEFAULT_SIZE][PGraphics.VERTEX_FIELD_COUNT]; + int vertexCount; + + // really this is "debug" but.. + static final boolean FRY = false; + + // after some fiddling, this seems to produce the best results + //static final int ZBUFFER_MIN_COVERAGE = 204; + + float r[] = new float[DEFAULT_SIZE]; // storage used by incrementalize + float dr[] = new float[DEFAULT_SIZE]; + float l[] = new float[DEFAULT_SIZE]; // more storage for incrementalize + float dl[] = new float[DEFAULT_SIZE]; + float sp[] = new float[DEFAULT_SIZE]; // temporary storage for scanline + float sdp[] = new float[DEFAULT_SIZE]; + + // color and xyz are always interpolated + boolean interpX; + boolean interpZ; + boolean interpUV; // is this necessary? could just check timage != null + boolean interpARGB; + + int rgba; + int r2, g2, b2, a2, a2orig; + + boolean noDepthTest; + + PGraphics parent; + int pixels[]; + + // the parent's width/height, + // or if smooth is enabled, parent's w/h scaled + // up by the smooth dimension + int width, height; + int width1, height1; + + PImage timage; + int tpixels[]; + int theight, twidth; + int theight1, twidth1; + int tformat; + + // temp fix to behave like SMOOTH_IMAGES + boolean texture_smooth; + + // for anti-aliasing + static final int SUBXRES = 8; + static final int SUBXRES1 = 7; + static final int SUBYRES = 8; + static final int SUBYRES1 = 7; + static final int MAX_COVERAGE = SUBXRES * SUBYRES; + + boolean smooth; + int firstModY; + int lastModY; + int lastY; + int aaleft[] = new int[SUBYRES]; + int aaright[] = new int[SUBYRES]; + int aaleftmin, aarightmin; + int aaleftmax, aarightmax; + int aaleftfull, aarightfull; + + final private int MODYRES(int y) { + return (y & SUBYRES1); + } + + + public PPolygon(PGraphics iparent) { + parent = iparent; + reset(0); + } + + + public void reset(int count) { + vertexCount = count; + interpX = true; + interpZ = true; + interpUV = false; + interpARGB = true; + timage = null; + } + + + public float[] nextVertex() { + if (vertexCount == vertices.length) { + //parent.message(CHATTER, "re-allocating for " + + // (vertexCount*2) + " vertices"); + float temp[][] = new float[vertexCount<<1][PGraphics.VERTEX_FIELD_COUNT]; + System.arraycopy(vertices, 0, temp, 0, vertexCount); + vertices = temp; + + r = new float[vertices.length]; + dr = new float[vertices.length]; + l = new float[vertices.length]; + dl = new float[vertices.length]; + sp = new float[vertices.length]; + sdp = new float[vertices.length]; + } + return vertices[vertexCount++]; // returns v[0], sets vc to 1 + } + + + /** + * Return true if this vertex is redundant. If so, will also + * decrement the vertex count. + */ + /* + public boolean redundantVertex(float x, float y, float z) { + // because vertexCount will be 2 when setting vertex[1] + if (vertexCount < 2) return false; + + // vertexCount-1 is the current vertex that would be used + // vertexCount-2 would be the previous feller + if ((Math.abs(vertices[vertexCount-2][MX] - x) < EPSILON) && + (Math.abs(vertices[vertexCount-2][MY] - y) < EPSILON) && + (Math.abs(vertices[vertexCount-2][MZ] - z) < EPSILON)) { + vertexCount--; + return true; + } + return false; + } + */ + + + public void texture(PImage image) { + this.timage = image; + this.tpixels = image.pixels; + this.twidth = image.width; + this.theight = image.height; + this.tformat = image.format; + + twidth1 = twidth - 1; + theight1 = theight - 1; + interpUV = true; + } + + + public void render() { + if (vertexCount < 3) return; + + // these may have changed due to a resize() + // so they should be refreshed here + pixels = parent.pixels; + //zbuffer = parent.zbuffer; + + noDepthTest = parent.hints[DISABLE_DEPTH_TEST]; + smooth = parent.smooth; + + // by default, text turns on smooth for the textures + // themselves. but this should be shut off if the hint + // for DISABLE_TEXT_SMOOTH is set. + texture_smooth = (//parent.drawing_text && + !parent.hints[DISABLE_TEXT_SMOOTH]); + + width = smooth ? parent.width*SUBXRES : parent.width; + height = smooth ? parent.height*SUBYRES : parent.height; + + width1 = width - 1; + height1 = height - 1; + + if (!interpARGB) { + r2 = (int) (vertices[0][R] * 255); + g2 = (int) (vertices[0][G] * 255); + b2 = (int) (vertices[0][B] * 255); + a2 = (int) (vertices[0][A] * 255); + a2orig = a2; // save an extra copy + rgba = 0xff000000 | (r2 << 16) | (g2 << 8) | b2; + } + + for (int i = 0; i < vertexCount; i++) { + r[i] = 0; dr[i] = 0; l[i] = 0; dl[i] = 0; + } + + // hack to not make polygons fly into the screen + if (parent.hints[NO_FLYING_POO]) { + float nwidth2 = -width * 2; + float nheight2 = -height * 2; + float width2 = width * 2; + float height2 = height * 2; + for (int i = 0; i < vertexCount; i++) { + if ((vertices[i][X] < nwidth2) || + (vertices[i][X] > width2) || + (vertices[i][Y] < nheight2) || + (vertices[i][Y] > height2)) { + return; // this is a bad poly + } + } + } + + if (smooth) { + for (int i = 0; i < vertexCount; i++) { + vertices[i][X] *= SUBXRES; + vertices[i][Y] *= SUBYRES; + } + firstModY = -1; + } + + // find top vertex (y is zero at top, higher downwards) + int topi = 0; + float ymin = vertices[0][Y]; + float ymax = vertices[0][Y]; // fry 031001 + for (int i = 1; i < vertexCount; i++) { + if (vertices[i][Y] < ymin) { + ymin = vertices[i][Y]; + topi = i; + } + if (vertices[i][Y] > ymax) ymax = vertices[i][Y]; + } + + // the last row is an exceptional case, because there won't + // necessarily be 8 rows of subpixel lines that will force + // the final line to render. so instead, the algo keeps track + // of the lastY (in subpixel resolution) that will be rendered + // and that will force a scanline to happen the same as + // every eighth in the other situations + //lastY = -1; // fry 031001 + lastY = (int) (ymax - 0.5f); // global to class bc used by other fxns + + int lefti = topi; // li, index of left vertex + int righti = topi; // ri, index of right vertex + int y = (int) (ymin + 0.5f); // current scan line + int lefty = y - 1; // lower end of left edge + int righty = y - 1; // lower end of right edge + + interpX = true; + + int remaining = vertexCount; + + // scan in y, activating new edges on left & right + // as scan line passes over new vertices + while (remaining > 0) { + // advance left edge? + while ((lefty <= y) && (remaining > 0)) { + remaining--; + // step ccw down left side + int i = (lefti != 0) ? (lefti-1) : (vertexCount-1); + incrementalize_y(vertices[lefti], vertices[i], l, dl, y); + lefty = (int) (vertices[i][Y] + 0.5f); + lefti = i; + } + + // advance right edge? + while ((righty <= y) && (remaining > 0)) { + remaining--; + // step cw down right edge + int i = (righti != vertexCount-1) ? (righti + 1) : 0; + incrementalize_y(vertices[righti], vertices[i], r, dr, y); + righty = (int) (vertices[i][Y] + 0.5f); + righti = i; + } + + // do scanlines till end of l or r edge + while (y < lefty && y < righty) { + // this doesn't work because it's not always set here + //if (remaining == 0) { + //lastY = (lefty < righty) ? lefty-1 : righty-1; + //System.out.println("lastY is " + lastY); + //} + + if ((y >= 0) && (y < height)) { + //try { // hopefully this bug is fixed + if (l[X] <= r[X]) scanline(y, l, r); + else scanline(y, r, l); + //} catch (ArrayIndexOutOfBoundsException e) { + //e.printStackTrace(); + //} + } + y++; + // this increment probably needs to be different + // UV and RGB shouldn't be incremented until line is emitted + increment(l, dl); + increment(r, dr); + } + } + //if (smooth) { + //System.out.println("y/lasty/lastmody = " + y + " " + lastY + " " + lastModY); + //} + } + + + public void unexpand() { + if (smooth) { + for (int i = 0; i < vertexCount; i++) { + vertices[i][X] /= SUBXRES; + vertices[i][Y] /= SUBYRES; + } + } + } + + + private void scanline(int y, float l[], float r[]) { + //System.out.println("scanline " + y); + for (int i = 0; i < vertexCount; i++) { // should be moved later + sp[i] = 0; sdp[i] = 0; + } + + // this rounding doesn't seem to be relevant with smooth + int lx = (int) (l[X] + 0.49999f); // ceil(l[X]-.5); + if (lx < 0) lx = 0; + int rx = (int) (r[X] - 0.5f); + if (rx > width1) rx = width1; + + if (lx > rx) return; + + if (smooth) { + int mody = MODYRES(y); + + aaleft[mody] = lx; + aaright[mody] = rx; + + if (firstModY == -1) { + firstModY = mody; + aaleftmin = lx; aaleftmax = lx; + aarightmin = rx; aarightmax = rx; + + } else { + if (aaleftmin > aaleft[mody]) aaleftmin = aaleft[mody]; + if (aaleftmax < aaleft[mody]) aaleftmax = aaleft[mody]; + if (aarightmin > aaright[mody]) aarightmin = aaright[mody]; + if (aarightmax < aaright[mody]) aarightmax = aaright[mody]; + } + + lastModY = mody; // moved up here (before the return) 031001 + // not the eighth (or lastY) line, so not scanning this time + if ((mody != SUBYRES1) && (y != lastY)) return; + //lastModY = mody; // eeK! this was missing + //return; + + //if (y == lastY) { + //System.out.println("y is lasty"); + //} + //lastModY = mody; + aaleftfull = aaleftmax/SUBXRES + 1; + aarightfull = aarightmin/SUBXRES - 1; + } + + // this is the setup, based on lx + incrementalize_x(l, r, sp, sdp, lx); + + // scan in x, generating pixels + // using parent.width to get actual pixel index + // rather than scaled by smooth factor + int offset = smooth ? parent.width * (y / SUBYRES) : parent.width*y; + + int truelx = 0, truerx = 0; + if (smooth) { + truelx = lx / SUBXRES; + truerx = (rx + SUBXRES1) / SUBXRES; + + lx = aaleftmin / SUBXRES; + rx = (aarightmax + SUBXRES1) / SUBXRES; + if (lx < 0) lx = 0; + if (rx > parent.width1) rx = parent.width1; + } + + interpX = false; + int tr, tg, tb, ta; + + for (int x = lx; x <= rx; x++) { + // added == because things on same plane weren't replacing each other + // makes for strangeness in 3D, but totally necessary for 2D + //if (noDepthTest || (sp[Z] <= zbuffer[offset+x])) { + if (true) { + + // map texture based on U, V coords in sp[U] and sp[V] + if (interpUV) { + int tu = (int)sp[U]; + int tv = (int)sp[V]; + + if (tu > twidth1) tu = twidth1; + if (tv > theight1) tv = theight1; + if (tu < 0) tu = 0; + if (tv < 0) tv = 0; + + int txy = tv*twidth + tu; + + if (smooth || texture_smooth) { + //if (FRY) System.out.println("sp u v = " + sp[U] + " " + sp[V]); + //System.out.println("sp u v = " + sp[U] + " " + sp[V]); + // tuf1/tvf1 is the amount of coverage for the adjacent + // pixel, which is the decimal percentage. + int tuf1 = (int) (255f * (sp[U] - (float)tu)); + int tvf1 = (int) (255f * (sp[V] - (float)tv)); + + // the closer sp[U or V] is to the decimal being zero + // the more coverage it should get of the original pixel + int tuf = 255 - tuf1; + int tvf = 255 - tvf1; + + // this code sucks! filled with bugs and slow as hell! + int pixel00 = tpixels[txy]; + int pixel01 = (tv < theight1) ? + tpixels[txy + twidth] : tpixels[txy]; + int pixel10 = (tu < twidth1) ? + tpixels[txy + 1] : tpixels[txy]; + int pixel11 = ((tv < theight1) && (tu < twidth1)) ? + tpixels[txy + twidth + 1] : tpixels[txy]; + + int p00, p01, p10, p11; + int px0, px1; //, pxy; + + if (tformat == ALPHA) { + px0 = (pixel00*tuf + pixel10*tuf1) >> 8; + px1 = (pixel01*tuf + pixel11*tuf1) >> 8; + ta = (((px0*tvf + px1*tvf1) >> 8) * + (interpARGB ? ((int) (sp[A]*255)) : a2orig)) >> 8; + + } else if (tformat == ARGB) { + p00 = (pixel00 >> 24) & 0xff; + p01 = (pixel01 >> 24) & 0xff; + p10 = (pixel10 >> 24) & 0xff; + p11 = (pixel11 >> 24) & 0xff; + + px0 = (p00*tuf + p10*tuf1) >> 8; + px1 = (p01*tuf + p11*tuf1) >> 8; + ta = (((px0*tvf + px1*tvf1) >> 8) * + (interpARGB ? ((int) (sp[A]*255)) : a2orig)) >> 8; + + } else { // RGB image, no alpha + ta = interpARGB ? ((int) (sp[A]*255)) : a2orig; + } + + if ((tformat == RGB) || (tformat == ARGB)) { + p00 = (pixel00 >> 16) & 0xff; // red + p01 = (pixel01 >> 16) & 0xff; + p10 = (pixel10 >> 16) & 0xff; + p11 = (pixel11 >> 16) & 0xff; + + px0 = (p00*tuf + p10*tuf1) >> 8; + px1 = (p01*tuf + p11*tuf1) >> 8; + tr = (((px0*tvf + px1*tvf1) >> 8) * + (interpARGB ? ((int) sp[R]*255) : r2)) >> 8; + + + p00 = (pixel00 >> 8) & 0xff; // green + p01 = (pixel01 >> 8) & 0xff; + p10 = (pixel10 >> 8) & 0xff; + p11 = (pixel11 >> 8) & 0xff; + + px0 = (p00*tuf + p10*tuf1) >> 8; + px1 = (p01*tuf + p11*tuf1) >> 8; + tg = (((px0*tvf + px1*tvf1) >> 8) * + (interpARGB ? ((int) sp[G]*255) : g2)) >> 8; + + + p00 = pixel00 & 0xff; // blue + p01 = pixel01 & 0xff; + p10 = pixel10 & 0xff; + p11 = pixel11 & 0xff; + + px0 = (p00*tuf + p10*tuf1) >> 8; + px1 = (p01*tuf + p11*tuf1) >> 8; + tb = (((px0*tvf + px1*tvf1) >> 8) * + (interpARGB ? ((int) sp[B]*255) : b2)) >> 8; + + } else { // alpha image, only use current fill color + if (interpARGB) { + tr = (int) (sp[R] * 255); + tg = (int) (sp[G] * 255); + tb = (int) (sp[B] * 255); + + } else { + tr = r2; + tg = g2; + tb = b2; + } + } + + // get coverage for pixel if smooth + // checks smooth again here because of + // hints[SMOOTH_IMAGES] used up above + int weight = smooth ? coverage(x) : 255; + if (weight != 255) ta = ta*weight >> 8; + + } else { // no smooth, just get the pixels + int tpixel = tpixels[txy]; + + // TODO i doubt splitting these guys really gets us + // all that much speed.. is it worth it? + if (tformat == ALPHA) { + ta = tpixel; + + if (interpARGB) { + tr = (int) sp[R]*255; + tg = (int) sp[G]*255; + tb = (int) sp[B]*255; + if (sp[A] != 1) { + ta = (((int) sp[A]*255) * ta) >> 8; + } + + } else { + tr = r2; + tg = g2; + tb = b2; + ta = (a2orig * ta) >> 8; + } + + } else { // RGB or ARGB + ta = (tformat == RGB) ? 255 : (tpixel >> 24) & 0xff; + + if (interpARGB) { + tr = (((int) sp[R]*255) * ((tpixel >> 16) & 0xff)) >> 8; + tg = (((int) sp[G]*255) * ((tpixel >> 8) & 0xff)) >> 8; + tb = (((int) sp[B]*255) * ((tpixel) & 0xff)) >> 8; + ta = (((int) sp[A]*255) * ta) >> 8; + + } else { + tr = (r2 * ((tpixel >> 16) & 0xff)) >> 8; + tg = (g2 * ((tpixel >> 8) & 0xff)) >> 8; + tb = (b2 * ((tpixel) & 0xff)) >> 8; + ta = (a2orig * ta) >> 8; + } + } + } + + if ((ta == 254) || (ta == 255)) { // if (ta & 0xf8) would be good + // no need to blend + pixels[offset+x] = 0xff000000 | (tr << 16) | (tg << 8) | tb; + //zbuffer[offset+x] = sp[Z]; + + } else { + // blend with pixel on screen + int a1 = 255-ta; + int r1 = (pixels[offset+x] >> 16) & 0xff; + int g1 = (pixels[offset+x] >> 8) & 0xff; + int b1 = (pixels[offset+x]) & 0xff; + + pixels[offset+x] = 0xff000000 | + (((tr*ta + r1*a1) >> 8) << 16) | + ((tg*ta + g1*a1) & 0xff00) | + ((tb*ta + b1*a1) >> 8); + //if (ta > ZBUFFER_MIN_COVERAGE) zbuffer[offset+x] = sp[Z]; + } + + } else { // no image applied + int weight = smooth ? coverage(x) : 255; + + if (interpARGB) { + r2 = (int) (sp[R] * 255); + g2 = (int) (sp[G] * 255); + b2 = (int) (sp[B] * 255); + if (sp[A] != 1) weight = (weight * ((int) (sp[A] * 255))) >> 8; + if (weight == 255) { + rgba = 0xff000000 | (r2 << 16) | (g2 << 8) | b2; + } + } else { + if (a2orig != 255) weight = (weight * a2orig) >> 8; + } + + if (weight == 255) { + // no blend, no aa, just the rgba + pixels[offset+x] = rgba; + //zbuffer[offset+x] = sp[Z]; + + } else { + int r1 = (pixels[offset+x] >> 16) & 0xff; + int g1 = (pixels[offset+x] >> 8) & 0xff; + int b1 = (pixels[offset+x]) & 0xff; + a2 = weight; + + int a1 = 255 - a2; + pixels[offset+x] = (0xff000000 | + ((r1*a1 + r2*a2) >> 8) << 16 | + // use & instead of >> and << below + ((g1*a1 + g2*a2) >> 8) << 8 | + ((b1*a1 + b2*a2) >> 8)); + + //if (a2 > ZBUFFER_MIN_COVERAGE) zbuffer[offset+x] = sp[Z]; + } + } + } + // if smooth enabled, don't increment values + // for the pixel in the stretch out version + // of the scanline used to get smooth edges. + if (!smooth || ((x >= truelx) && (x <= truerx))) { + increment(sp, sdp); + } + } + firstModY = -1; + interpX = true; + } + + + // x is in screen, not huge 8x coordinates + private int coverage(int x) { + if ((x >= aaleftfull) && (x <= aarightfull) && + // important since not all SUBYRES lines may have been covered + (firstModY == 0) && (lastModY == SUBYRES1)) { + return 255; + } + + int pixelLeft = x*SUBXRES; // huh? + int pixelRight = pixelLeft + 8; + + int amt = 0; + for (int i = firstModY; i <= lastModY; i++) { + if ((aaleft[i] > pixelRight) || (aaright[i] < pixelLeft)) { + continue; + } + // does this need a +1 ? + amt += ((aaright[i] < pixelRight ? aaright[i] : pixelRight) - + (aaleft[i] > pixelLeft ? aaleft[i] : pixelLeft)); + } + amt <<= 2; + return (amt == 256) ? 255 : amt; + } + + + private void incrementalize_y(float p1[], float p2[], + float p[], float dp[], int y) { + float delta = p2[Y] - p1[Y]; + if (delta == 0) delta = 1; + float fraction = y + 0.5f - p1[Y]; + + if (interpX) { + dp[X] = (p2[X] - p1[X]) / delta; + p[X] = p1[X] + dp[X] * fraction; + } + if (interpZ) { + dp[Z] = (p2[Z] - p1[Z]) / delta; + p[Z] = p1[Z] + dp[Z] * fraction; + } + + if (interpARGB) { + dp[R] = (p2[R] - p1[R]) / delta; + dp[G] = (p2[G] - p1[G]) / delta; + dp[B] = (p2[B] - p1[B]) / delta; + dp[A] = (p2[A] - p1[A]) / delta; + p[R] = p1[R] + dp[R] * fraction; + p[G] = p1[G] + dp[G] * fraction; + p[B] = p1[B] + dp[B] * fraction; + p[A] = p1[A] + dp[A] * fraction; + } + + if (interpUV) { + dp[U] = (p2[U] - p1[U]) / delta; + dp[V] = (p2[V] - p1[V]) / delta; + + //if (smooth) { + //p[U] = p1[U]; //+ dp[U] * fraction; + //p[V] = p1[V]; //+ dp[V] * fraction; + + //} else { + p[U] = p1[U] + dp[U] * fraction; + p[V] = p1[V] + dp[V] * fraction; + //} + if (FRY) System.out.println("inc y p[U] p[V] = " + p[U] + " " + p[V]); + } + } + + + private void incrementalize_x(float p1[], float p2[], + float p[], float dp[], int x) { + float delta = p2[X] - p1[X]; + if (delta == 0) delta = 1; + float fraction = x + 0.5f - p1[X]; + if (smooth) { + delta /= SUBXRES; + fraction /= SUBXRES; + } + + if (interpX) { + dp[X] = (p2[X] - p1[X]) / delta; + p[X] = p1[X] + dp[X] * fraction; + } + if (interpZ) { + dp[Z] = (p2[Z] - p1[Z]) / delta; + p[Z] = p1[Z] + dp[Z] * fraction; + } + + if (interpARGB) { + dp[R] = (p2[R] - p1[R]) / delta; + dp[G] = (p2[G] - p1[G]) / delta; + dp[B] = (p2[B] - p1[B]) / delta; + dp[A] = (p2[A] - p1[A]) / delta; + p[R] = p1[R] + dp[R] * fraction; + p[G] = p1[G] + dp[G] * fraction; + p[B] = p1[B] + dp[B] * fraction; + p[A] = p1[A] + dp[A] * fraction; + } + + if (interpUV) { + if (FRY) System.out.println("delta, frac = " + delta + ", " + fraction); + dp[U] = (p2[U] - p1[U]) / delta; + dp[V] = (p2[V] - p1[V]) / delta; + + //if (smooth) { + //p[U] = p1[U]; + // offset for the damage that will be done by the + // 8 consecutive calls to scanline + // agh.. this won't work b/c not always 8 calls before render + // maybe lastModY - firstModY + 1 instead? + if (FRY) System.out.println("before inc x p[V] = " + p[V] + " " + p1[V] + " " + p2[V]); + //p[V] = p1[V] - SUBXRES1 * fraction; + + //} else { + p[U] = p1[U] + dp[U] * fraction; + p[V] = p1[V] + dp[V] * fraction; + //} + } + } + + + private void increment(float p[], float dp[]) { + if (interpX) p[X] += dp[X]; + if (interpZ) p[Z] += dp[Z]; + + if (interpARGB) { + p[R] += dp[R]; + p[G] += dp[G]; + p[B] += dp[B]; + p[A] += dp[A]; + } + + if (interpUV) { + if (FRY) System.out.println("increment() " + p[V] + " " + dp[V]); + p[U] += dp[U]; + p[V] += dp[V]; + } + } +} diff --git a/core/PShape.java b/core/PShape.java new file mode 100644 index 000000000..0046b975f --- /dev/null +++ b/core/PShape.java @@ -0,0 +1,289 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2006 Ben Fry and Casey Reas + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA +*/ + +package processing.core; + + +// take a look at the obj loader to see how this fits with things + +// PShape.line() PShape.ellipse()? +// PShape s = beginShape() +// line() +// endShape(s) + +public class PShape { + + int kind; + PMatrix matrix; + + int[] opcode; + int opcodeCount; + // need to reorder vertex fields to make a VERTEX_SHORT_COUNT + // that puts all the non-rendering fields into later indices + float[][] data; // second param is the VERTEX_FIELD_COUNT + // should this be called vertices (consistent with PGraphics internals) + // or does that hurt flexibility? + + int childCount; + PShape[] children; + + // POINTS, LINES, xLINE_STRIP, xLINE_LOOP + // TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN + // QUADS, QUAD_STRIP + // xPOLYGON + static final int PATH = 1; // POLYGON, LINE_LOOP, LINE_STRIP + static final int GROUP = 2; + + // how to handle rectmode/ellipsemode? + // are they bitshifted into the constant? + // CORNER, CORNERS, CENTER, (CENTER_RADIUS?) + static final int RECT = 3; // could just be QUAD, but would be x1/y1/x2/y2 + static final int ELLIPSE = 4; + + static final int VERTEX = 7; + static final int CURVE = 5; + static final int BEZIER = 6; + + + // fill and stroke functions will need a pointer to the parent + // PGraphics object.. may need some kind of createShape() fxn + // or maybe the values are stored until draw() is called? + + // attaching images is very tricky.. it's a different type of data + + // material parameters will be thrown out, + // except those currently supported (kinds of lights) + + // setAxis -> .x and .y to move x and y coords of origin + public float x; + public float y; + + // pivot point for transformations + public float px; + public float py; + + + public PShape() { + } + + + public PShape(float x, float y) { + this.x = x; + this.y = y; + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + /** + * Called by the following (the shape() command adds the g) + * PShape s = loadShapes("blah.svg"); + * shape(s); + */ + public void draw(PGraphics g) { + boolean flat = g instanceof PGraphics3D; + + if (matrix != null) { + g.pushMatrix(); + if (flat) { + g.applyMatrix(matrix.m00, matrix.m01, matrix.m02, + matrix.m10, matrix.m11, matrix.m12); + } else { + g.applyMatrix(matrix.m00, matrix.m01, matrix.m02, matrix.m03, + matrix.m10, matrix.m11, matrix.m12, matrix.m13, + matrix.m20, matrix.m21, matrix.m22, matrix.m23, + matrix.m30, matrix.m31, matrix.m32, matrix.m33); + } + } + + // if g subclasses PGraphics2, ignore all lighting stuff and z coords + // otherwise if PGraphics3, need to call diffuse() etc + + // unfortunately, also a problem with no way to encode stroke/fill + // being enabled/disabled.. this quickly gets into just having opcodes + // for the entire api, to deal with things like textures and images + + switch (kind) { + case PATH: + for (int i = 0; i < opcodeCount; i++) { + switch (opcode[i]) { + case VERTEX: + break; + } + } + break; + + case GROUP: + break; + + case RECT: + break; + } + + if (matrix != null) { + g.popMatrix(); + } + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + // can't be 'add' because that suggests additive geometry + public void addChild(PShape who) { + } + + + public PShape createGroup() { + PShape group = new PShape(); + group.kind = GROUP; + addChild(group); + return group; + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + // translate, rotate, scale, apply (no push/pop) + // these each call matrix.translate, etc + // if matrix is null when one is called, + // it is created and set to identity + + + public void translate(float tx, float ty) { + translate(tx, ty, 0); + } + + public void translate(float tx, float ty, float tz) { + checkMatrix(); + matrix.translate(tx, ty, 0); + } + + + // + + + public void rotateX(float angle) { + rotate(angle, 1, 0, 0); + } + + public void rotateY(float angle) { + rotate(angle, 0, 1, 0); + } + + public void rotateZ(float angle) { + rotate(angle, 0, 0, 1); + } + + public void rotate(float angle) { + rotateZ(angle); + } + + public void rotate(float angle, float v0, float v1, float v2) { + checkMatrix(); + matrix.rotate(angle, v0, v1, v2); + } + + + // + + + public void scale(float s) { + scale(s, s, s); + } + + public void scale(float sx, float sy) { + scale(sx, sy, 1); + } + + public void scale(float x, float y, float z) { + checkMatrix(); + matrix.scale(x, y, z); + } + + + // + + + public void applyMatrix(float n00, float n01, float n02, + float n10, float n11, float n12) { + checkMatrix(); + matrix.apply(n00, n01, n02, 0, + n10, n11, n12, 0, + 0, 0, 1, 0, + 0, 0, 0, 1); + } + + public void applyMatrix(float n00, float n01, float n02, float n03, + float n10, float n11, float n12, float n13, + float n20, float n21, float n22, float n23, + float n30, float n31, float n32, float n33) { + checkMatrix(); + matrix.apply(n00, n01, n02, n03, + n10, n11, n12, n13, + n20, n21, n22, n23, + n30, n31, n32, n33); + } + + + // + + + protected void checkMatrix() { + if (matrix == null) { + matrix = new PMatrix(); + } + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + /** + * Center the shape based on its bounding box. Can't assume + * that the bounding box is 0, 0, width, height. Common case will be + * opening a letter size document in Illustrator, and drawing something + * in the middle, then reading it in as an svg file. + * This will also need to flip the y axis (scale(1, -1)) in cases + * like Adobe Illustrator where the coordinates start at the bottom. + */ + public void center() { + } + + + /** + * Set the pivot point for all transformations. + */ + public void pivot(float x, float y) { + px = x; + py = y; + } + + + // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . + + + +} \ No newline at end of file diff --git a/core/PTriangle.java b/core/PTriangle.java new file mode 100644 index 000000000..7142af5b6 --- /dev/null +++ b/core/PTriangle.java @@ -0,0 +1,3827 @@ +/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */ + +/* + Part of the Processing project - http://processing.org + + Copyright (c) 2004-06 Ben Fry and Casey Reas + Copyright (c) 2001-04 Massachusetts Institute of Technology + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General + Public License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place, Suite 330, + Boston, MA 02111-1307 USA + */ + +package processing.core; + +/** + * Handles rendering of single (tesselated) triangles in 3D. + *

    + * Written by sami www.sumea.com + */ +public class PTriangle implements PConstants +{ + static final int R_GOURAUD = 0x1; + static final int R_TEXTURE8 = 0x2; + static final int R_TEXTURE24 = 0x4; + static final int R_TEXTURE32 = 0x8; + static final int R_ALPHA = 0x10; + + private int[] m_pixels; + private int[] m_texture; + private int[] m_stencil; + private float[] m_zbuffer; + + private int SCREEN_WIDTH; + private int SCREEN_HEIGHT; + //private int SCREEN_WIDTH1; + //private int SCREEN_HEIGHT1; + + private int TEX_WIDTH; + private int TEX_HEIGHT; + private float F_TEX_WIDTH; + private float F_TEX_HEIGHT; + + public boolean INTERPOLATE_UV; + public boolean INTERPOLATE_RGB; + public boolean INTERPOLATE_ALPHA; + + // the power of 2 that tells how many pixels to interpolate + // for between exactly computed texture coordinates + private static final int DEFAULT_INTERP_POWER = 3; + private static int TEX_INTERP_POWER = DEFAULT_INTERP_POWER; + + // Vertex coordinates + private float[] x_array; + private float[] y_array; + private float[] z_array; + + private float[] camX; + private float[] camY; + private float[] camZ; + + // U,V coordinates + private float[] u_array; + private float[] v_array; + + // Vertex Intensity + private float[] r_array; + private float[] g_array; + private float[] b_array; + private float[] a_array; + + // vertex offsets + private int o0; + private int o1; + private int o2; + + /* rgb & a */ + private float r0; + private float r1; + private float r2; + private float g0; + private float g1; + private float g2; + private float b0; + private float b1; + private float b2; + private float a0; + private float a1; + private float a2; + + /* accurate texture uv coordinates */ + private float u0; + private float u1; + private float u2; + private float v0; + private float v1; + private float v2; + + /* deltas */ + //private float dx0; + //private float dx1; + private float dx2; + private float dy0; + private float dy1; + private float dy2; + private float dz0; + //private float dz1; + private float dz2; + + /* texture deltas */ + private float du0; + //private float du1; + private float du2; + private float dv0; + //private float dv1; + private float dv2; + + /* rgba deltas */ + private float dr0; + //private float dr1; + private float dr2; + private float dg0; + //private float dg1; + private float dg2; + private float db0; + //private float db1; + private float db2; + private float da0; + //private float da1; + private float da2; + + /* */ + private float uleft; + private float vleft; + private float uleftadd; + private float vleftadd; + + /* polyedge positions & adds */ + private float xleft; + private float xrght; + private float xadd1; + private float xadd2; + private float zleft; + private float zleftadd; + + /* rgba positions & adds */ + private float rleft; + private float gleft; + private float bleft; + private float aleft; + private float rleftadd; + private float gleftadd; + private float bleftadd; + private float aleftadd; + + /* other somewhat useful variables :) */ + private float dta; + //private float dta2; + private float temp; + private float width; + + /* integer poly UV adds */ + private int iuadd; + private int ivadd; + private int iradd; + private int igadd; + private int ibadd; + private int iaadd; + private float izadd; + + /* fill color */ + private int m_fill; + + /* draw flags */ + public int m_drawFlags; + + /* current poly number */ + private int m_index; + + /** */ + private PGraphics3D parent; + + private boolean noDepthTest; + + /** */ + private boolean m_culling; + + /** */ + private boolean m_singleRight; + + /** */ + private boolean m_bilinear; + + + //Vectors needed in accurate texture code + //We store them as class members to avoid too much code duplication + private float ax,ay,az; + private float bx,by,bz; + private float cx,cy,cz; + private float nearPlaneWidth; + private float nearPlaneHeight; + private float nearPlaneDepth; + private float xmult; + private float ymult; + private float newax,newbx,newcx; //optimization vars...not pretty, but save a couple mults per pixel + private boolean firstSegment; //are we currently drawing the first piece of the triangle, or have we already done so? + + + + + public PTriangle(PGraphics3D g) { + //SCREEN_WIDTH = g.width; + //SCREEN_HEIGHT = g.height; + //SCREEN_WIDTH1 = SCREEN_WIDTH-1; + //SCREEN_HEIGHT1 = SCREEN_HEIGHT-1; + + //m_pixels = g.pixels; + //m_stencil = g.stencil; + //m_zbuffer = g.zbuffer; + + x_array = new float[3]; + y_array = new float[3]; + z_array = new float[3]; + u_array = new float[3]; + v_array = new float[3]; + r_array = new float[3]; + g_array = new float[3]; + b_array = new float[3]; + a_array = new float[3]; + + camX = new float[3]; + camY = new float[3]; + camZ = new float[3]; + + this.parent = g; + reset(); + } + + /** + * Resets polygon attributes + */ + public void reset() { + // reset these in case PGraphics was resized + + SCREEN_WIDTH = parent.width; + SCREEN_HEIGHT = parent.height; + //SCREEN_WIDTH1 = SCREEN_WIDTH-1; + //SCREEN_HEIGHT1 = SCREEN_HEIGHT-1; + + m_pixels = parent.pixels; + m_stencil = parent.stencil; + m_zbuffer = parent.zbuffer; + + noDepthTest = parent.hints[DISABLE_DEPTH_TEST]; + + // other things to reset + + INTERPOLATE_UV = false; + INTERPOLATE_RGB = false; + INTERPOLATE_ALPHA = false; + //m_tImage = null; + m_texture = null; + m_drawFlags = 0; + } + + /** + * Sets backface culling on/off + */ + public void setCulling(boolean tf) { + m_culling = tf; + } + + + /** + * Sets vertex coordinates for the triangle + */ + public void setVertices(float x0, float y0, float z0, + float x1, float y1, float z1, + float x2, float y2, float z2) { + x_array[0] = x0; + x_array[1] = x1; + x_array[2] = x2; + + y_array[0] = y0; + y_array[1] = y1; + y_array[2] = y2; + + z_array[0] = z0; + z_array[1] = z1; + z_array[2] = z2; + } + + /** + * Pass camera-space coordinates for the triangle (needed to render if ENABLE_ACCURATE_TEXTURES is hinted). + */ + public void setCamVertices(float x0, float y0, float z0, + float x1, float y1, float z1, + float x2, float y2, float z2) { + //Generally this will not need to be called manually, currently called if hints[ENABLE_ACCURATE_TEXTURES] + //from PGraphics3D.render_triangles() + + camX[0] = x0; + camX[1] = x1; + camX[2] = x2; + + camY[0] = y0; + camY[1] = y1; + camY[2] = y2; + + camZ[0] = z0; + camZ[1] = z1; + camZ[2] = z2; + } + + /** + * Sets the UV coordinates of the texture + */ + public void setUV(float u0, float v0, + float u1, float v1, + float u2, float v2) { + // sets & scales uv texture coordinates to center of the pixel + u_array[0] = (u0 * F_TEX_WIDTH + 0.5f) * 65536f; + u_array[1] = (u1 * F_TEX_WIDTH + 0.5f) * 65536f; + u_array[2] = (u2 * F_TEX_WIDTH + 0.5f) * 65536f; + v_array[0] = (v0 * F_TEX_HEIGHT + 0.5f) * 65536f; + v_array[1] = (v1 * F_TEX_HEIGHT + 0.5f) * 65536f; + v_array[2] = (v2 * F_TEX_HEIGHT + 0.5f) * 65536f; + } + + /** + * Sets vertex intensities in 0xRRGGBBAA format + */ + public void setIntensities( float r0, float g0, float b0, float a0, + float r1, float g1, float b1, float a1, + float r2, float g2, float b2, float a2) { + // Check if we need alpha or not? + if ((a0 != 1.0f) || (a1 != 1.0f) || (a2 != 1.0f)) { + INTERPOLATE_ALPHA = true; + a_array[0] = (a0 * 253f + 1.0f) * 65536f; + a_array[1] = (a1 * 253f + 1.0f) * 65536f; + a_array[2] = (a2 * 253f + 1.0f) * 65536f; + m_drawFlags|=R_ALPHA; + } else { + INTERPOLATE_ALPHA = false; + m_drawFlags&=~R_ALPHA; + } + + // Check if we need to interpolate the intensity values + if ((r0 != r1) || (r1 != r2)) { + INTERPOLATE_RGB = true; + m_drawFlags|=R_GOURAUD; + } else if ((g0 != g1) || (g1 != g2)) { + INTERPOLATE_RGB = true; + m_drawFlags|=R_GOURAUD; + } else if ((b0 != b1) || (b1 != b2)) { + INTERPOLATE_RGB = true; + m_drawFlags|=R_GOURAUD; + } else { + //m_fill = parent.filli; + m_drawFlags&=~R_GOURAUD; + } + + // push values to arrays.. some extra scaling is added + // to prevent possible color "overflood" due to rounding errors + r_array[0] = (r0 * 253f + 1.0f) * 65536f; + r_array[1] = (r1 * 253f + 1.0f) * 65536f; + r_array[2] = (r2 * 253f + 1.0f) * 65536f; + + g_array[0] = (g0 * 253f + 1.0f) * 65536f; + g_array[1] = (g1 * 253f + 1.0f) * 65536f; + g_array[2] = (g2 * 253f + 1.0f) * 65536f; + + b_array[0] = (b0 * 253f + 1.0f) * 65536f; + b_array[1] = (b1 * 253f + 1.0f) * 65536f; + b_array[2] = (b2 * 253f + 1.0f) * 65536f; + + // for plain triangles + m_fill = ((int)(255*r0) << 16) | ((int)(255*g0) << 8) | (int)(255*b0); + } + + + /** + * Sets texture image used for the polygon + */ + public void setTexture(PImage image) { + //m_tImage = image; + m_texture = image.pixels; + TEX_WIDTH = image.width; + TEX_HEIGHT = image.height; + F_TEX_WIDTH = TEX_WIDTH-1; + F_TEX_HEIGHT = TEX_HEIGHT-1; + INTERPOLATE_UV = true; + + if (image.format == ARGB) { + m_drawFlags|=R_TEXTURE32; + } else if (image.format == RGB) { + m_drawFlags|=R_TEXTURE24; + } else if (image.format == ALPHA) { + m_drawFlags|=R_TEXTURE8; + } + + //if (parent.hints[SMOOTH_IMAGES]) { + /* + if (parent.smooth) { + m_bilinear = true; + } else { + m_bilinear = false; + } + */ + m_bilinear = true; + } + + /** + * + */ + public void setUV(float[] u, float[] v) { + if (m_bilinear) { + // sets & scales uv texture coordinates to edges of pixels + u_array[0] = (u[0] * F_TEX_WIDTH) * 65500f; + u_array[1] = (u[1] * F_TEX_WIDTH) * 65500f; + u_array[2] = (u[2] * F_TEX_WIDTH) * 65500f; + v_array[0] = (v[0] * F_TEX_HEIGHT) * 65500f; + v_array[1] = (v[1] * F_TEX_HEIGHT) * 65500f; + v_array[2] = (v[2] * F_TEX_HEIGHT) * 65500f; + } else { + // sets & scales uv texture coordinates to center of the pixel + u_array[0] = (u[0] * TEX_WIDTH) * 65500f; + u_array[1] = (u[1] * TEX_WIDTH) * 65500f; + u_array[2] = (u[2] * TEX_WIDTH) * 65500f; + v_array[0] = (v[0] * TEX_HEIGHT) * 65500f; + v_array[1] = (v[1] * TEX_HEIGHT) * 65500f; + v_array[2] = (v[2] * TEX_HEIGHT) * 65500f; + } + } + + public void setIndex(int index) { + m_index = index; + } + + /** + * Renders the polygon + */ + public void render() { + // removed. done in PGraphics [rocha] + // increase polygon offset + //m_index = (m_index + 1) & 0xFFFFFFF; + + // draw the polygon + draw(); + + // removed. replaced by external antialiasing [rocha] + // smooth edges? + //if (parent.smooth ) + //{ + // drawline_blender(x_array[0], y_array[0], x_array[1], y_array[1]); + // drawline_blender(x_array[1], y_array[1], x_array[2], y_array[2]); + // drawline_blender(x_array[2], y_array[2], x_array[0], y_array[0]); + //} + } + + private void draw() { + // y-coordinates + float x0; + float x1; + float x2; + + // + float z0; + float z1; + float z2; + + // + float y0 = y_array[0]; + float y1 = y_array[1]; + float y2 = y_array[2]; + + // For accurate texture interpolation, need to mark whether + // we've already pre-calculated for the triangle + firstSegment = true; + + // do backface culling? + if (m_culling) { + x0 = x_array[0]; + if ((x_array[2]-x0)*(y1-y0) < (x_array[1]-x0)*(y2-y0)) + return; + } + + /* get vertex order from top -> down */ + if (y0y1) { + if (y2 SCREEN_HEIGHT) { + return; + } else if (yi0 < 0) { + yi0 = 0; + } + + y2 = y_array[o2]; + int yi2 = (int) (y2 + PIXEL_CENTER); + if (yi2 < 0) { + return; + } else if (yi2 > SCREEN_HEIGHT) { + yi2 = SCREEN_HEIGHT; + } + + // Does the poly actually cross a scanline? + if (yi2 > yi0) { + x0 = x_array[o0]; + x1 = x_array[o1]; + x2 = x_array[o2]; + + // get mid Y and clip it + y1 = y_array[o1]; + int yi1 = (int) (y1 + PIXEL_CENTER); + if (yi1 < 0) + yi1 = 0; + if (yi1 > SCREEN_HEIGHT) + yi1 = SCREEN_HEIGHT; + + // calculate deltas etc. + dx2 = x2 - x0; + dy0 = y1 - y0; + dy2 = y2 - y0; + xadd2 = dx2 / dy2; // xadd for "single" edge + temp = dy0 / dy2; + width = temp * dx2 + x0 - x1; + + // calculate alpha blend interpolation + if (INTERPOLATE_ALPHA) { + a0 = a_array[o0]; + a1 = a_array[o1]; + a2 = a_array[o2]; + da0 = a1-a0; + da2 = a2-a0; + iaadd = (int) ((temp * da2 - da0) / width); // alpha add + } + + // calculate intensity interpolation + if (INTERPOLATE_RGB) { + r0 = r_array[o0]; + r1 = r_array[o1]; + r2 = r_array[o2]; + + g0 = g_array[o0]; + g1 = g_array[o1]; + g2 = g_array[o2]; + + b0 = b_array[o0]; + b1 = b_array[o1]; + b2 = b_array[o2]; + + dr0 = r1-r0; + dg0 = g1-g0; + db0 = b1-b0; + + dr2 = r2-r0; + dg2 = g2-g0; + db2 = b2-b0; + + iradd = (int) ((temp * dr2 - dr0) / width); // r add + igadd = (int) ((temp * dg2 - dg0) / width); // g add + ibadd = (int) ((temp * db2 - db0) / width); // b add + } + + // calculate UV interpolation + if (INTERPOLATE_UV) { + u0 = u_array[o0]; + u1 = u_array[o1]; + u2 = u_array[o2]; + v0 = v_array[o0]; + v1 = v_array[o1]; + v2 = v_array[o2]; + du0 = u1-u0; + dv0 = v1-v0; + du2 = u2-u0; + dv2 = v2-v0; + iuadd = (int) ((temp * du2 - du0) / width); // u add + ivadd = (int) ((temp * dv2 - dv0) / width); // v add + } + + z0 = z_array[o0]; + z1 = z_array[o1]; + z2 = z_array[o2]; + dz0 = z1-z0; + dz2 = z2-z0; + izadd = (temp * dz2 - dz0) / width; + + // draw the upper poly segment if it's visible + if (yi1 > yi0) { + dta = (yi0 + PIXEL_CENTER) - y0; + xadd1 = (x1 - x0) / dy0; + + // we can determine which side is "single" side by comparing left/right edge adds + if (xadd2 > xadd1) { + xleft = x0 + dta * xadd1; + xrght = x0 + dta * xadd2; + zleftadd = dz0 / dy0; + zleft = dta*zleftadd+z0; + + // + if (INTERPOLATE_UV) { + uleftadd = du0 / dy0; + vleftadd = dv0 / dy0; + uleft = dta*uleftadd+u0; + vleft = dta*vleftadd+v0; + } + + // + if (INTERPOLATE_RGB) { + rleftadd = dr0 / dy0; + gleftadd = dg0 / dy0; + bleftadd = db0 / dy0; + rleft = dta*rleftadd+r0; + gleft = dta*gleftadd+g0; + bleft = dta*bleftadd+b0; + } + + // + if (INTERPOLATE_ALPHA) { + aleftadd = da0 / dy0; + aleft = dta*aleftadd+a0; + + if (m_drawFlags == R_ALPHA) { + drawsegment_plain_alpha(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_ALPHA)) { + drawsegment_gouraud_alpha(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_TEXTURE8 + R_ALPHA)) { + drawsegment_texture8_alpha(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_TEXTURE24 + R_ALPHA)) { + drawsegment_texture24_alpha(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_TEXTURE32 + R_ALPHA)) { + drawsegment_texture32_alpha(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8 + R_ALPHA)) { + drawsegment_gouraud_texture8_alpha(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24 + R_ALPHA)) { + drawsegment_gouraud_texture24_alpha(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32 + R_ALPHA)) { + drawsegment_gouraud_texture32_alpha(xadd1,xadd2, yi0,yi1); + } + } else { + if (m_drawFlags == 0) { + drawsegment_plain(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == R_GOURAUD) { + drawsegment_gouraud(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == R_TEXTURE8) { + drawsegment_texture8(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == R_TEXTURE24) { + drawsegment_texture24(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == R_TEXTURE32) { + drawsegment_texture32(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8)) { + drawsegment_gouraud_texture8(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24)) { + drawsegment_gouraud_texture24(xadd1,xadd2, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32)) { + drawsegment_gouraud_texture32(xadd1,xadd2, yi0,yi1); + } + } + m_singleRight = true; + } else { + xleft = x0 + dta * xadd2; + xrght = x0 + dta * xadd1; + zleftadd = dz2 / dy2; + zleft = dta*zleftadd+z0; + // + if (INTERPOLATE_UV) { + uleftadd = du2 / dy2; + vleftadd = dv2 / dy2; + uleft = dta*uleftadd+u0; + vleft = dta*vleftadd+v0; + } + + // + if (INTERPOLATE_RGB) { + rleftadd = dr2 / dy2; + gleftadd = dg2 / dy2; + bleftadd = db2 / dy2; + rleft = dta*rleftadd+r0; + gleft = dta*gleftadd+g0; + bleft = dta*bleftadd+b0; + } + + + if (INTERPOLATE_ALPHA) { + aleftadd = da2 / dy2; + aleft = dta*aleftadd+a0; + + if (m_drawFlags == R_ALPHA) { + drawsegment_plain_alpha(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_ALPHA)) { + drawsegment_gouraud_alpha(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_TEXTURE8 + R_ALPHA)) { + drawsegment_texture8_alpha(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_TEXTURE24 + R_ALPHA)) { + drawsegment_texture24_alpha(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_TEXTURE32 + R_ALPHA)) { + drawsegment_texture32_alpha(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8 + R_ALPHA)) { + drawsegment_gouraud_texture8_alpha(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24 + R_ALPHA)) { + drawsegment_gouraud_texture24_alpha(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32 + R_ALPHA)) { + drawsegment_gouraud_texture32_alpha(xadd2, xadd1, yi0,yi1); + } + } else { + if (m_drawFlags == 0) { + drawsegment_plain(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == R_GOURAUD) { + drawsegment_gouraud(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == R_TEXTURE8) { + drawsegment_texture8(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == R_TEXTURE24) { + drawsegment_texture24(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == R_TEXTURE32) { + drawsegment_texture32(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8)) { + drawsegment_gouraud_texture8(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24)) { + drawsegment_gouraud_texture24(xadd2, xadd1, yi0,yi1); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32)) { + drawsegment_gouraud_texture32(xadd2, xadd1, yi0,yi1); + } + } + m_singleRight = false; + } + + // if bottom segment height is zero, return + if (yi2 == yi1) + return; + + // calculate xadd 1 + dy1 = y2 - y1; + xadd1 = (x2 - x1) / dy1; + } else { + // top seg height was zero, calculate & clip single edge X + dy1 = y2 - y1; + xadd1 = (x2 - x1) / dy1; + + // which edge is left? + if (xadd2 < xadd1) { + xrght = ((yi1 + PIXEL_CENTER) - y0) * xadd2 + x0; + m_singleRight = true; + } else { + dta = (yi1 + PIXEL_CENTER) - y0; + xleft = dta * xadd2 + x0; + zleftadd = dz2 / dy2; + zleft = dta * zleftadd + z0; + + if (INTERPOLATE_UV) { + uleftadd = du2 / dy2; + vleftadd = dv2 / dy2; + uleft = dta * uleftadd + u0; + vleft = dta * vleftadd + v0; + } + + if (INTERPOLATE_RGB) { + rleftadd = dr2 / dy2; + gleftadd = dg2 / dy2; + bleftadd = db2 / dy2; + rleft = dta * rleftadd + r0; + gleft = dta * gleftadd + g0; + bleft = dta * bleftadd + b0; + } + + // + if (INTERPOLATE_ALPHA) { + aleftadd = da2 / dy2; + aleft = dta * aleftadd + a0; + } + m_singleRight = false; + } + } + + // draw the lower segment + if (m_singleRight) { + dta = (yi1 + PIXEL_CENTER) - y1; + xleft = dta * xadd1 + x1; + zleftadd = (z2 - z1) / dy1; + zleft = dta * zleftadd + z1; + + if (INTERPOLATE_UV) { + uleftadd = (u2 - u1) / dy1; + vleftadd = (v2 - v1) / dy1; + uleft = dta * uleftadd + u1; + vleft = dta * vleftadd + v1; + } + + if (INTERPOLATE_RGB) { + rleftadd = (r2 - r1) / dy1; + gleftadd = (g2 - g1) / dy1; + bleftadd = (b2 - b1) / dy1; + rleft = dta * rleftadd + r1; + gleft = dta * gleftadd + g1; + bleft = dta * bleftadd + b1; + } + + if (INTERPOLATE_ALPHA) { + aleftadd = (a2 - a1) / dy1; + aleft = dta * aleftadd + a1; + + if (m_drawFlags == R_ALPHA) { + drawsegment_plain_alpha(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_ALPHA)) { + drawsegment_gouraud_alpha(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_TEXTURE8 + R_ALPHA)) { + drawsegment_texture8_alpha(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_TEXTURE24 + R_ALPHA)) { + drawsegment_texture24_alpha(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_TEXTURE32 + R_ALPHA)) { + drawsegment_texture32_alpha(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8 + R_ALPHA)) { + drawsegment_gouraud_texture8_alpha(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24 + R_ALPHA)) { + drawsegment_gouraud_texture24_alpha(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32 + R_ALPHA)) { + drawsegment_gouraud_texture32_alpha(xadd1, xadd2, yi1,yi2); + } + } else { + if (m_drawFlags == 0) { + drawsegment_plain(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == R_GOURAUD) { + drawsegment_gouraud(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == R_TEXTURE8) { + drawsegment_texture8(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == R_TEXTURE24) { + drawsegment_texture24(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == R_TEXTURE32) { + drawsegment_texture32(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8)) { + drawsegment_gouraud_texture8(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24)) { + drawsegment_gouraud_texture24(xadd1, xadd2, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32)) { + drawsegment_gouraud_texture32(xadd1, xadd2, yi1,yi2); + } + } + } else { + xrght = ((yi1 + PIXEL_CENTER)- y1) * xadd1 + x1; + + if (INTERPOLATE_ALPHA) { + if (m_drawFlags == R_ALPHA) { + drawsegment_plain_alpha(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_ALPHA)) { + drawsegment_gouraud_alpha(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_TEXTURE8 + R_ALPHA)) { + drawsegment_texture8_alpha(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_TEXTURE24 + R_ALPHA)) { + drawsegment_texture24_alpha(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_TEXTURE32 + R_ALPHA)) { + drawsegment_texture32_alpha(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8 + R_ALPHA)) { + drawsegment_gouraud_texture8_alpha(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24 + R_ALPHA)) { + drawsegment_gouraud_texture24_alpha(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32 + R_ALPHA)) { + drawsegment_gouraud_texture32_alpha(xadd2, xadd1, yi1,yi2); + } + } else { + if (m_drawFlags == 0) { + drawsegment_plain(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == R_GOURAUD) { + drawsegment_gouraud(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == R_TEXTURE8) { + drawsegment_texture8(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == R_TEXTURE24) { + drawsegment_texture24(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == R_TEXTURE32) { + drawsegment_texture32(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE8)) { + drawsegment_gouraud_texture8(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE24)) { + drawsegment_gouraud_texture24(xadd2, xadd1, yi1,yi2); + } else if (m_drawFlags == (R_GOURAUD + R_TEXTURE32)) { + drawsegment_gouraud_texture32(xadd2, xadd1, yi1,yi2); + } + } + } + } + } + + + /* + Accurate texturing code by ewjordan@gmail.com, April 14, 2007 + The getColorFromTexture() function should be inlined and optimized so that most of the heavy lifting + happens outside the per-pixel loop. The unoptimized generic algorithm looks like this (unless noted, + all of these variables are vectors, so the actual code will look messier): + + p = camera space vector where u == 0, v == 0; + m = vector from p to location where u == TEX_WIDTH; + n = vector from p to location where v == TEX_HEIGHT; + + A = p cross n; + B = m cross p; + C = n cross m; + A *= texture.width; + B *= texture.height; + + for (scanlines in triangle){ + float a = S * A; + float b = S * B; + float c = S * C; + for (pixels in scanline){ + int u = a/c; + int v = b/c; + color = texture[v * texture.width + u]; + a += A.x; + b += B.x; + c += C.x; + } + } + + We don't use this exact algorithm here, however, because of the extra overhead from the divides. + Instead we compute the exact u and v (labelled iu and iv in the code) at the start of each scanline + and we perform a linear interpolation for every linearInterpLength = 1 << TEX_INTERP_POWER pixels. + This means that we only perform the true calculation once in a while, and the rest of the time + the algorithm functions exactly as in the fast inaccurate case, at least in theory. In practice, + even if we set linearInterpLength very high we still incur some speed penalty due to the preprocessing + that must take place per-scanline. A similar method could be applied per scanline to avoid this, but + it would only be worthwhile in the case that we never compute more than one exact calculation per + scanline. If we want something like this, however, it would be best to create another mode of calculation + called "constant-z" interpolation, which could be used for things like floors and ceilings where the + distance from the camera plane never changes over the course of a scanline. We could also add the + vertical analogue for drawing vertical walls. In any case, these are not critical as the current + algorithm runs fairly well, perhaps ~10% slower than the default perspective-less one. + + */ + + /** + * Solve for camera space coordinates of critical texture points and set up per-triangle variables for accurate texturing + */ + private boolean precomputeAccurateTexturing(){ + //Sets all class variables relevant to accurate texture computation + //Should be called once per triangle - checks firstSegment to see if we've already called + + float myFact = 65500.0f; //rescale u/v_array values when inverting matrix and performing other calcs + float myFact2 = 65500.0f; + + //Matrix inversion to find affine transform between (u,v,(1)) -> (x,y,z) + + //OPTIMIZE: There should be a way to avoid the inversion here, which is + //quite expensive (~150 mults). Also it might crap out due to loss of precision depending + //on the scaling of the u/v_arrays. Nothing clever currently happens if the inversion + //fails, since this means the transformation is degenerate - we just pass false back to + //the caller and let it handle the situation. [There is no good solution to this + //case from within this function, since the way the calculation proceeds presumes a non- + //degenerate transformation matrix between camera space and uv space] + + //Obvious optimization: if the vertices are actually at the appropriate texture coordinates + //(e.g. (0,0), (TEX_WIDTH,0), and (0,TEX_HEIGHT)) then we can immediately return the + //right solution without the inversion. This is fairly common, so could speed up + //many cases of drawing. [not implemented] + + //Furthermore, we could cache the p,resultT0,result0T vectors in the triangle's + //basis, since we could then do a look-up and generate the resulting coordinates very simply. + //This would include the above optimization as a special case - we could pre-populate the + //cache with special cases like that and dynamically add more. The idea here is + //that most people simply paste textures onto triangles and move the triangles from + //frame to frame, so any per-triangle-per-frame code is likely wasted effort. + //[not implemented] + + //Note: o0, o1, and o2 vary depending on view angle to triangle, but p, n, and m should not depend on ordering differences + + if(firstSegment){ + + PMatrix myMatrix = new PMatrix( u_array[o0]/myFact, v_array[o0]/myFact2, 1, 0, + u_array[o1]/myFact, v_array[o1]/myFact2, 1, 0, + u_array[o2]/myFact, v_array[o2]/myFact2, 1, 0, + 0, 0, 0, 1); + myMatrix = myMatrix.invert(); //A 3x3 inversion would be more efficient here, given that the fourth r/c are unity + if (myMatrix == null) {return false;} //if the matrix inversion had trouble, let the caller know + float m00, m01, m02, m10, m11, m12, m20, m21, m22; + m00 = myMatrix.m00*camX[o0]+myMatrix.m01*camX[o1]+myMatrix.m02*camX[o2]; + m01 = myMatrix.m10*camX[o0]+myMatrix.m11*camX[o1]+myMatrix.m12*camX[o2]; + m02 = myMatrix.m20*camX[o0]+myMatrix.m21*camX[o1]+myMatrix.m22*camX[o2]; + m10 = myMatrix.m00*camY[o0]+myMatrix.m01*camY[o1]+myMatrix.m02*camY[o2]; + m11 = myMatrix.m10*camY[o0]+myMatrix.m11*camY[o1]+myMatrix.m12*camY[o2]; + m12 = myMatrix.m20*camY[o0]+myMatrix.m21*camY[o1]+myMatrix.m22*camY[o2]; + m20 = -(myMatrix.m00*camZ[o0]+myMatrix.m01*camZ[o1]+myMatrix.m02*camZ[o2]); + m21 = -(myMatrix.m10*camZ[o0]+myMatrix.m11*camZ[o1]+myMatrix.m12*camZ[o2]); + m22 = -(myMatrix.m20*camZ[o0]+myMatrix.m21*camZ[o1]+myMatrix.m22*camZ[o2]); + + float px = m02; + float py = m12; + float pz = m22; + float resultT0x = m00*TEX_WIDTH+m02; //Bugfix: possibly we should use F_TEX_WIDTH/HEIGHT instead? Seems to read off end of array in that case, though... + float resultT0y = m10*TEX_WIDTH+m12; + float resultT0z = m20*TEX_WIDTH+m22; + float result0Tx = m01*TEX_HEIGHT+m02; + float result0Ty = m11*TEX_HEIGHT+m12; + float result0Tz = m21*TEX_HEIGHT+m22; + float mx = resultT0x-m02; + float my = resultT0y-m12; + float mz = resultT0z-m22; + float nx = result0Tx-m02; + float ny = result0Ty-m12; + float nz = result0Tz-m22; + + //avec = p x n + ax = (py*nz-pz*ny)*TEX_WIDTH; //F_TEX_WIDTH/HEIGHT? + ay = (pz*nx-px*nz)*TEX_WIDTH; + az = (px*ny-py*nx)*TEX_WIDTH; + //bvec = m x p + bx = (my*pz-mz*py)*TEX_HEIGHT; + by = (mz*px-mx*pz)*TEX_HEIGHT; + bz = (mx*py-my*px)*TEX_HEIGHT; + //cvec = n x m + cx = ny*mz-nz*my; + cy = nz*mx-nx*mz; + cz = nx*my-ny*mx; + } + + nearPlaneWidth = parent.rightScreen-parent.leftScreen; + nearPlaneHeight = parent.topScreen-parent.bottomScreen; + nearPlaneDepth = parent.nearPlane; + xmult = nearPlaneWidth / SCREEN_WIDTH; //one pixel width in nearPlane coordinates + ymult = nearPlaneHeight / SCREEN_HEIGHT; + newax = ax*xmult;//Extra scalings to map screen plane units to pixel units + newbx = bx*xmult; + newcx = cx*xmult; + return true; + } + + /** + * Set the power of two used for linear interpolation of texture coordinates. + * A true texture coordinate is computed every 2^pwr pixels along a scanline. + */ + static public void setInterpPower(int pwr){ + //Currently must be invoked from P5 as PTriangle.setInterpPower(...) + TEX_INTERP_POWER = pwr; + } + + + + /** + * Plain color + */ + private void drawsegment_plain + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int f = m_fill; + int p = m_index; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + float iz = izadd * xdiff + zleft; + xstart+=ytop; + xend+=ytop; + + for ( ; xstart < xend; xstart++ ) { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + m_zbuffer[xstart] = iz; + m_pixels[xstart] = f; + m_stencil[xstart] = p; + } + iz+=izadd; + } + + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + zleft+=zleftadd; + } + } + + /** + * Plain color, interpolated alpha + */ + private void drawsegment_plain_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + + int pr = m_fill & 0xFF0000; + int pg = m_fill & 0xFF00; + int pb = m_fill & 0xFF; + + int p = m_index; + float iaf = iaadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + float iz = izadd * xdiff + zleft; + int ia = (int) (iaf * xdiff + aleft); + xstart+=ytop; + xend+=ytop; + + for ( ; xstart < xend; xstart++ ) { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + int alpha = ia >> 16; + int mr0 = m_pixels[xstart]; + int mg0 = mr0 & 0xFF00; + int mb0 = mr0 & 0xFF; + mr0 &= 0xFF0000; + + mr0 = mr0 + (((pr - mr0) * alpha) >> 8); + mg0 = mg0 + (((pg - mg0) * alpha) >> 8); + mb0 = mb0 + (((pb - mb0) * alpha) >> 8); + m_pixels[xstart] = (mr0 & 0xFF0000) | (mg0 & 0xFF00) | (mb0 & 0xFF); + + m_stencil[xstart] = p; + } + iz += izadd; + ia += iaadd; + } + ytop += SCREEN_WIDTH; + xleft += leftadd; + xrght += rghtadd; + zleft += zleftadd; + } + } + + + /** + * RGB gouraud + */ + private void drawsegment_gouraud + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + for ( ; xstart < xend; xstart++ ) { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + m_zbuffer[xstart] = iz; + m_pixels[xstart]=((ir & 0xFF0000) | ((ig >> 8) & 0xFF00) | (ib >> 16)); + m_stencil[xstart] = p; + } + + // + ir+=iradd; + ig+=igadd; + ib+=ibadd; + iz+=izadd; + } + + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + zleft+=zleftadd; + } + } + + + /** + * RGB gouraud + interpolated alpha + */ + private void drawsegment_gouraud_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + float iaf = iaadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + float xdiff = (xstart + PIXEL_CENTER) - xleft; + + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + int ia = (int) (iaf * xdiff + aleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + for ( ; xstart < xend; xstart++ ) { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + // + int red = (ir & 0xFF0000); + int grn = (ig >> 8) & 0xFF00; + int blu = (ib >> 16); + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + + // blend alpha + int al = ia >> 16; + + // + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) | ((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + m_stencil[xstart] = p; + } + + // + ir+=iradd; + ig+=igadd; + ib+=ibadd; + ia+=iaadd; + iz+=izadd; + } + + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + aleft+=aleftadd; + zleft+=zleftadd; + } + } + + + /** + * 8-bit plain texture + */ + + //THIS IS MESSED UP, NEED TO GRAB ORIGINAL VERSION!!! + private void drawsegment_texture8 + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + + int red = m_fill & 0xFF0000; + int grn = m_fill & 0xFF00; + int blu = m_fill & 0xFF; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + // try-catch just in case pixel offset it out of range + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + int al0; + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = iu & 0xFFFF; + al0 = m_texture[ofs] & 0xFF; + int al1 = m_texture[ofs + 1] & 0xFF; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int al2 = m_texture[ofs] & 0xFF; + int al3 = m_texture[ofs + 1] & 0xFF; + al0 = al0 + (((al1-al0) * iui) >> 16); + al2 = al2 + (((al3-al2) * iui) >> 16); + al0 = al0 + (((al2-al0) * (iv & 0xFFFF)) >> 16); + } else { + al0 = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)] & 0xFF; + } + + int br = m_pixels[xstart]; + int bg = (br & 0xFF00); + int bb = (br & 0xFF); + br = (br & 0xFF0000); + m_pixels[xstart] = ((br + (((red - br) * al0) >> 8)) & 0xFF0000) | ((bg + (((grn - bg) * al0) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al0) >> 8)) & 0xFF); + m_stencil[xstart] = p; + } + } + catch (Exception e) { + } + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + iz+=izadd; + } + ypixel++;//accurate mode + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + zleft+=zleftadd; + } + } + + + + /** + * 8-bit texutre + alpha + */ + private void drawsegment_texture8_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float iaf = iaadd; + + int red = m_fill & 0xFF0000; + int grn = m_fill & 0xFF00; + int blu = m_fill & 0xFF; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ia = (int) (iaf * xdiff + aleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + // try-catch just in case pixel offset it out of range + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + int al0; + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = iu & 0xFFFF; + al0 = m_texture[ofs] & 0xFF; + int al1 = m_texture[ofs + 1] & 0xFF; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int al2 = m_texture[ofs] & 0xFF; + int al3 = m_texture[ofs + 1] & 0xFF; + al0 = al0 + (((al1-al0) * iui) >> 16); + al2 = al2 + (((al3-al2) * iui) >> 16); + al0 = al0 + (((al2-al0) * (iv & 0xFFFF)) >> 16); + } else { + al0 = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)] & 0xFF; + } + al0 = (al0 * (ia >> 16)) >> 8; + + int br = m_pixels[xstart]; + int bg = (br & 0xFF00); + int bb = (br & 0xFF); + br = (br & 0xFF0000); + m_pixels[xstart] = ((br + (((red - br) * al0) >> 8)) & 0xFF0000) | ((bg + (((grn - bg) * al0) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al0) >> 8)) & 0xFF); + m_stencil[xstart] = p; + } + } + catch (Exception e) { + } + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + iz+=izadd; + ia+=iaadd; + } + ypixel++;//accurate mode + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + zleft+=zleftadd; + aleft+=aleftadd; + } + } + + /** + * Plain 24-bit texture + */ + private void drawsegment_texture24 + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + float iuf = iuadd; + float ivf = ivadd; + + int ypixel = ytop/SCREEN_WIDTH;//ACCTEX + int lastRowStart = m_texture.length - TEX_WIDTH - 2;//If we're past this index, we can't shift down a row w/o throwing an exception +// int exCount = 0;//counter for exceptions caught + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; //bring this local since it will be accessed often + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + + //Interpolation length of 16 tends to look good except at a small angle; 8 looks okay then, except for the + //above issue. When viewing close to flat, as high as 32 is often acceptable. Could add dynamic interpolation + //settings based on triangle angle - currently we just pick a value and leave it (by default I have the + //power set at 3, so every 8 pixels a true coordinate is calculated, which seems a decent compromise). + + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion gave us garbage, revert to normal rendering (something is degenerate) + } + } + + + while (ytop < ybottom) {//scanline loop + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0){ xstart = 0; } + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH){ xend = SCREEN_WIDTH; } + float xdiff = (xstart + PIXEL_CENTER) - xleft; + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + float iz = izadd * xdiff + zleft; + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + //off by one (half, I guess) hack, w/o it the first rows are outside the texture - maybe a mistake somewhere? + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az;//OPT - some of this could be brought out of the y-loop since + b = screenx*bx+screeny*by+screenz*bz;//xpixel and ypixel just increment by the same numbers each iteration. + c = screenx*cx+screeny*cy+screenz*cz;//Probably not a big bottleneck, though. + } + + //Figure out whether triangle is going further into the screen or not as we move along scanline + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + + //Set up linear interpolation between calculated texture points + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + //float fdeltaU = 0; float fdeltaV = 0;//vars for floating point interpolating version of algorithm + //float fiu = 0; float fiv = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + + //Bugfix (done): it's a Really Bad Thing to interpolate along a scanline when the triangle goes deeper into the screen, + //because if the angle is severe enough the last control point for interpolation may cross the vanishing + //point. This leads to some pretty nasty artifacts, and ideally we should scan from right to left if the + //triangle is better served that way, or (what we do now) precompute the offset that we'll need so that we end up + //with a control point exactly at the furthest edge of the triangle. + + if (accurateMode&&goingIn){ + //IMPORTANT!!! Results are horrid without this hack! + //If polygon goes into the screen along scan line, we want to match the control point to the furthest point drawn + //since the control points are less meaningful the closer you are to the vanishing point. + //We'll do this by making the first control point lie before the start of the scanline (safe since it's closer to us) + + int rightOffset = (xend-xstart-1)%linearInterpLength; //"off by one" hack...probably means there's a small bug somewhere + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + + //Take step to control point to the left of start pixel + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + + //Now step to right control point + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + + //Get deltas for interpolation + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + //Otherwise the left edge is further, and we pin the first control point to it + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + for ( ; xstart < xend; xstart++ ) {//pixel loop - keep trim, can execute thousands of times per frame + //boolean drawBlack = false; //used to display control points + if(accurateMode){ + /* //Non-interpolating algorithm - slowest version, calculates exact coordinate for each pixel, + //and casts from float->int + float oneoverc = 65536.0f/c; //a bit faster to pre-divide for next two steps + iu = (int)(a*oneoverc); + iv = (int)(b*oneoverc); + a += newax; + b += newbx; + c += newcx; + */ + + //Float while calculating, int while interpolating + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + //drawBlack = true; + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; //ints are used for interpolation, not actual computation + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ //race through using linear interpolation if we're not at a control point + iu += deltaU; + iv += deltaV; + } + interpCounter++; + + /* //Floating point interpolating version - slower than int thanks to casts during interpolation steps + if (interpCounter == 0) { + interpCounter = linearInterpLength; + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; + oldfv = fv; + fu = (a*oneoverc); + fv = (b*oneoverc); + //oldu = u; oldv = v; + fiu = oldfu; + fiv = oldfv; + fdeltaU = (fu-oldfu)/linearInterpLength; + fdeltaV = (fv-oldfv)/linearInterpLength; + } + else{ + fiu += fdeltaU; + fiv += fdeltaV; + } + interpCounter--; + iu = (int)(fiu); iv = (int)(fiv);*/ + + } + + // try-catch just in case pixel offset is out of range + try{ + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + m_zbuffer[xstart] = iz; + if (m_bilinear) { + //We could (should?) add bounds checking on iu and iv here (keep in mind the 16 bit shift!). + //This would also be the place to add looping texture mode (bounds check == clamped). + //For looping/clamped textures, we'd also need to change PGraphics.textureVertex() to remove + //the texture range check there (it constrains normalized texture coordinates from 0->1). + + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + //if(ofs < 0) { ofs += TEX_WIDTH; } + //if(ofs > m_texture.length-2) {ofs -= TEX_WIDTH; } + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; //quick hack to thwart exceptions + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + int red = up + (((dn-up) * ivi) >> 7); + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + int grn = up + (((dn-up) * ivi) >> 7); + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + int blu = up + (((dn-up) * ivi) >> 7); + + m_pixels[xstart] = (red & 0xFF0000) | (grn & 0xFF00) | (blu & 0xFF); + //if (drawBlack){ m_pixels[xstart] = 0; } + + } else{ + m_pixels[xstart] = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + } + m_stencil[xstart] = p; + } + } catch (Exception e) {/*exCount++;*/} + iz+=izadd; + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + } + ypixel++;//accurate mode + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + zleft+=zleftadd; + uleft+=uleftadd; + vleft+=vleftadd; + } +// if (exCount>0) System.out.println(exCount+" exceptions in this segment"); + } + + + /** + * Alpha 24-bit texture + */ + private void drawsegment_texture24_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float iaf = iaadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ia = (int) (iaf * xdiff + aleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + // get alpha + int al = ia >> 16; + + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + int red = up + (((dn-up) * ivi) >> 7); + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + int grn = up + (((dn-up) * ivi) >> 7); + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + int blu = up + (((dn-up) * ivi) >> 7); + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |( (bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + } else { + int red = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + int grn = red & 0xFF00; + int blu = red & 0xFF; + red&=0xFF0000; + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + } + m_stencil[xstart] = p; + } + } + catch (Exception e) {} + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ia+=iaadd; + iz+=izadd; + } + ypixel++;//accurate mode + + ytop+=SCREEN_WIDTH; + + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + zleft+=zleftadd; + aleft+=aleftadd; + } + } + + /** + * Plain 32-bit texutre + */ + private void drawsegment_texture32 + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + // try-catch just in case pixel offset it out of range + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + int red = up + (((dn-up) * ivi) >> 7); + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + int grn = up + (((dn-up) * ivi) >> 7); + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + int blu = up + (((dn-up) * ivi) >> 7); + + // alpha + pix0>>>=24; + pix2>>>=24; + up = pix0 + ((((pix1 >>> 24) - pix0) * iui) >> 7); + dn = pix2 + ((((pix3 >>> 24) - pix2) * iui) >> 7); + int al = up + (((dn-up) * ivi) >> 7); + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + } else { + int red = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + int al = red >>> 24; + int grn = red & 0xFF00; + int blu = red & 0xFF; + red&=0xFF0000; + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + } + m_stencil[xstart] = p; + } + } + catch (Exception e) { + } + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + iz+=izadd; + } + ypixel++;//accurate mode + + ytop+=SCREEN_WIDTH; + + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + zleft+=zleftadd; + aleft+=aleftadd; + } + + + } + + /** + * Alpha 32-bit texutre + */ + private void drawsegment_texture32_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float iaf = iaadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + + float xdiff = (xstart + PIXEL_CENTER) - xleft; + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ia = (int) (iaf * xdiff + aleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + // try-catch just in case pixel offset it out of range + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + // get alpha + int al = ia >> 16; + + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + int red = up + (((dn-up) * ivi) >> 7); + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + int grn = up + (((dn-up) * ivi) >> 7); + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + int blu = up + (((dn-up) * ivi) >> 7); + + // alpha + pix0>>>=24; + pix2>>>=24; + up = pix0 + ((((pix1 >>> 24) - pix0) * iui) >> 7); + dn = pix2 + ((((pix3 >>> 24) - pix2) * iui) >> 7); + al = al * (up + (((dn-up) * ivi) >> 7)) >> 8; + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + } else { + int red = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + al = al * (red >>> 24) >> 8; + int grn = red & 0xFF00; + int blu = red & 0xFF; + red&=0xFF0000; + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + } + m_stencil[xstart] = p; + } + } + catch (Exception e) { + } + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ia+=iaadd; + iz+=izadd; + } + ypixel++;//accurate mode + + ytop+=SCREEN_WIDTH; + + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + zleft+=zleftadd; + aleft+=aleftadd; + } + + + } + + + /** + * Gouraud blended with 8-bit alpha texture + */ + private void drawsegment_gouraud_texture8 + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + float xdiff = (xstart + PIXEL_CENTER) - xleft; + + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + int al0; + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = iu & 0xFFFF; + al0 = m_texture[ofs] & 0xFF; + int al1 = m_texture[ofs + 1] & 0xFF; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int al2 = m_texture[ofs] & 0xFF; + int al3 = m_texture[ofs + 1] & 0xFF; + al0 = al0 + (((al1-al0) * iui) >> 16); + al2 = al2 + (((al3-al2) * iui) >> 16); + al0 = al0 + (((al2-al0) * (iv & 0xFFFF)) >> 16); + } else { + al0 = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)] & 0xFF; + } + + // get RGB colors + int red = ir & 0xFF0000; + int grn = (ig >> 8) & 0xFF00; + int blu = (ib >> 16); + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al0) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al0) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al0) >> 8)) & 0xFF); + + // write stencil + m_stencil[xstart] = p; + } + } + catch (Exception e) { + + } + + // + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ir+=iradd; + ig+=igadd; + ib+=ibadd; + iz+=izadd; + } + ypixel++;//accurate mode + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + + uleft+=uleftadd; + vleft+=vleftadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + zleft+=zleftadd; + } + } + + + /** + * Texture multiplied with gouraud + */ + private void drawsegment_gouraud_texture8_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + float iaf = iaadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + float xdiff = (xstart + PIXEL_CENTER) - xleft; + + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + int ia = (int) (iaf * xdiff + aleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + int al0; + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = iu & 0xFFFF; + al0 = m_texture[ofs] & 0xFF; + int al1 = m_texture[ofs + 1] & 0xFF; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int al2 = m_texture[ofs] & 0xFF; + int al3 = m_texture[ofs + 1] & 0xFF; + al0 = al0 + (((al1-al0) * iui) >> 16); + al2 = al2 + (((al3-al2) * iui) >> 16); + al0 = al0 + (((al2-al0) * (iv & 0xFFFF)) >> 16); + } else { + al0 = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)] & 0xFF; + } + al0 = (al0 * (ia >> 16)) >> 8; + + // get RGB colors + int red = ir & 0xFF0000; + int grn = (ig >> 8) & 0xFF00; + int blu = (ib >> 16); + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + m_pixels[xstart] = ((br + (((red - br) * al0) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al0) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al0) >> 8)) & 0xFF); + + // write stencil + m_stencil[xstart] = p; + } + } + catch (Exception e) { + + } + + // + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ir+=iradd; + ig+=igadd; + ib+=ibadd; + ia+=iaadd; + iz+=izadd; + } + ypixel++;//accurate mode + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + aleft+=aleftadd; + zleft+=zleftadd; + } + } + + + /** + * Texture multiplied with gouraud + */ + private void drawsegment_gouraud_texture24 + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + float xdiff = (xstart + PIXEL_CENTER) - xleft; + + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + m_zbuffer[xstart] = iz; + + int red; + int grn; + int blu; + + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + red = up + (((dn-up) * ivi) >> 7); + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + grn = up + (((dn-up) * ivi) >> 7); + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + blu = up + (((dn-up) * ivi) >> 7); + } else { + // get texture pixel color + blu = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + red = (blu & 0xFF0000); + grn = (blu & 0xFF00); + blu = blu & 0xFF; + } + + // + int r = (ir >> 16); + int g = (ig >> 16); + int bb2 = (ib >> 16); //oops, namespace collision with accurate texture vector b...sorry [ewjordan] + + // + m_pixels[xstart] = ( ((red * r) & 0xFF000000) | ((grn * g) & 0xFF0000) | (blu * bb2) ) >> 8; + m_stencil[xstart] = p; + } + } + catch (Exception e) { + } + + // + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ir+=iradd; + ig+=igadd; + ib+=ibadd; + iz+=izadd; + } + ypixel++;//accurate mode + + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + zleft+=zleftadd; + } + } + + + /** + * Gouraud*texture blended with interpolating alpha + */ + private void drawsegment_gouraud_texture24_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + float iaf = iaadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + float xdiff = (xstart + PIXEL_CENTER) - xleft; + + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + int ia = (int) (iaf * xdiff + aleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + for ( ;xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + // get texture pixel color + try + { + //if (iz < m_zbuffer[xstart]) { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { // [fry 041114] + //m_zbuffer[xstart] = iz; + + // blend + int al = ia >> 16; + + int red; + int grn; + int blu; + + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + red = (up + (((dn-up) * ivi) >> 7)) >> 16; + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + grn = (up + (((dn-up) * ivi) >> 7)) >> 8; + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + blu = up + (((dn-up) * ivi) >> 7); + } else { + blu = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + red = (blu & 0xFF0000) >> 16; // 0 - 255 + grn = (blu & 0xFF00) >> 8; // 0 - 255 + blu = (blu & 0xFF); // 0 - 255 + } + + // multiply with gouraud color + red = (red * ir) >>> 8; // 0x00FF???? + grn = (grn * ig) >>> 16; // 0x0000FF?? + blu = (blu * ib) >>> 24; // 0x000000FF + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + + // + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + m_stencil[xstart] = p; + } + } + catch (Exception e) { + } + + // + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ir+=iradd; + ig+=igadd; + ib+=ibadd; + ia+=iaadd; + iz+=izadd; + } + + ypixel++;//accurate mode + + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + aleft+=aleftadd; + zleft+=zleftadd; + } + } + + + /** + * Gouraud*texture blended with interpolating alpha + */ + private void drawsegment_gouraud_texture32 + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + //int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + float xdiff = (xstart + PIXEL_CENTER) - xleft; + + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + + for ( ; xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + try + { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { + //m_zbuffer[xstart] = iz; + + int red; + int grn; + int blu; + int al; + + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + red = (up + (((dn-up) * ivi) >> 7)) >> 16; + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + grn = (up + (((dn-up) * ivi) >> 7)) >> 8; + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + blu = up + (((dn-up) * ivi) >> 7); + + // alpha + pix0>>>=24; + pix2>>>=24; + up = pix0 + ((((pix1 >>> 24) - pix0) * iui) >> 7); + dn = pix2 + ((((pix3 >>> 24) - pix2) * iui) >> 7); + al = up + (((dn-up) * ivi) >> 7); + } else { + // get texture pixel color + blu = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + al = (blu >>> 24); + red = (blu & 0xFF0000) >> 16; + grn = (blu & 0xFF00) >> 8; + blu = blu & 0xFF; + } + + // multiply with gouraud color + red = (red * ir) >>> 8; // 0x00FF???? + grn = (grn * ig) >>> 16; // 0x0000FF?? + blu = (blu * ib) >>> 24; // 0x000000FF + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + + // + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + } + } + catch (Exception e) { + } + + // + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ir+=iradd; + ig+=igadd; + ib+=ibadd; + iz+=izadd; + } + ypixel++;//accurate mode + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + zleft+=zleftadd; + } + } + + + /** + * Gouraud*texture blended with interpolating alpha + */ + private void drawsegment_gouraud_texture32_alpha + ( + float leftadd, + float rghtadd, + int ytop, + int ybottom + ) { + //Accurate texture mode added - comments stripped from dupe code, see drawsegment_texture24() for details + int ypixel = ytop; + int lastRowStart = m_texture.length - TEX_WIDTH - 2; + boolean accurateMode = parent.hints[ENABLE_ACCURATE_TEXTURES]; + float screenx = 0; float screeny = 0; float screenz = 0; + float a = 0; float b = 0; float c = 0; + int linearInterpPower = TEX_INTERP_POWER; + int linearInterpLength = 1 << linearInterpPower; + if (accurateMode){ + if(precomputeAccurateTexturing()){ //see if the precomputation goes well, if so finish the setup + newax *= linearInterpLength; + newbx *= linearInterpLength; + newcx *= linearInterpLength; + screenz = nearPlaneDepth; + firstSegment = false; + } else{ + accurateMode = false; //if the matrix inversion screwed up, revert to normal rendering (something is degenerate) + } + } + + ytop*=SCREEN_WIDTH; + ybottom*=SCREEN_WIDTH; + int p = m_index; + + float iuf = iuadd; + float ivf = ivadd; + float irf = iradd; + float igf = igadd; + float ibf = ibadd; + float iaf = iaadd; + + while (ytop < ybottom) { + int xstart = (int) (xleft + PIXEL_CENTER); + if (xstart < 0) + xstart = 0; + + int xpixel = xstart;//accurate mode + + int xend = (int) (xrght + PIXEL_CENTER); + if (xend > SCREEN_WIDTH) + xend = SCREEN_WIDTH; + float xdiff = (xstart + PIXEL_CENTER) - xleft; + + int iu = (int) (iuf * xdiff + uleft); + int iv = (int) (ivf * xdiff + vleft); + int ir = (int) (irf * xdiff + rleft); + int ig = (int) (igf * xdiff + gleft); + int ib = (int) (ibf * xdiff + bleft); + int ia = (int) (iaf * xdiff + aleft); + float iz = izadd * xdiff + zleft; + + xstart+=ytop; + xend+=ytop; + if (accurateMode){ + screenx = xmult*(xpixel+.5f-(SCREEN_WIDTH/2.0f)); + screeny = ymult*(ypixel+.5f-(SCREEN_HEIGHT/2.0f)); + a = screenx*ax+screeny*ay+screenz*az; + b = screenx*bx+screeny*by+screenz*bz; + c = screenx*cx+screeny*cy+screenz*cz; + } + boolean goingIn = ( (newcx > 0) == (c > 0) )?false:true; + int interpCounter = 0; + int deltaU = 0; int deltaV = 0; + float fu = 0; float fv = 0; + float oldfu = 0; float oldfv = 0; + + if (accurateMode&&goingIn){ + int rightOffset = (xend-xstart-1)%linearInterpLength; + int leftOffset = linearInterpLength-rightOffset; + float rightOffset2 = rightOffset / ((float)linearInterpLength); + float leftOffset2 = leftOffset / ((float)linearInterpLength); + interpCounter = leftOffset; + float ao = a-leftOffset2*newax; + float bo = b-leftOffset2*newbx; + float co = c-leftOffset2*newcx; + float oneoverc = 65536.0f/co; + oldfu = (ao*oneoverc); oldfv = (bo*oneoverc); + a += rightOffset2*newax; + b += rightOffset2*newbx; + c += rightOffset2*newcx; + oneoverc = 65536.0f/c; + fu = a*oneoverc; fv = b*oneoverc; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + iu = ( (int)oldfu )+(leftOffset-1)*deltaU; iv = ( (int)oldfv )+(leftOffset-1)*deltaV; //another "off-by-one" hack + } else{ + float preoneoverc = 65536.0f/c; + fu = (a*preoneoverc); + fv = (b*preoneoverc); + } + + for ( ;xstart < xend; xstart++ ) { + if(accurateMode){ + if (interpCounter == linearInterpLength) interpCounter = 0; + if (interpCounter == 0){ + a += newax; + b += newbx; + c += newcx; + float oneoverc = 65536.0f/c; + oldfu = fu; oldfv = fv; + fu = (a*oneoverc); fv = (b*oneoverc); + iu = (int)oldfu; iv = (int)oldfv; + deltaU = ((int)(fu - oldfu)) >> linearInterpPower; + deltaV = ((int)(fv - oldfv)) >> linearInterpPower; + } else{ + iu += deltaU; + iv += deltaV; + } + interpCounter++; + } + + // get texture pixel color + try + { + //if (iz < m_zbuffer[xstart]) { + if (noDepthTest || (iz <= m_zbuffer[xstart])) { // [fry 041114] + //m_zbuffer[xstart] = iz; + + // blend + int al = ia >> 16; + + int red; + int grn; + int blu; + + if (m_bilinear) { + int ofs = (iv >> 16) * TEX_WIDTH + (iu >> 16); + int iui = (iu & 0xFFFF) >> 9; + int ivi = (iv & 0xFFFF) >> 9; + + // get texture pixels + int pix0 = m_texture[ofs]; + int pix1 = m_texture[ofs + 1]; + if (ofs < lastRowStart) ofs+=TEX_WIDTH; + int pix2 = m_texture[ofs]; + int pix3 = m_texture[ofs + 1]; + + // red + int red0 = (pix0 & 0xFF0000); + int red2 = (pix2 & 0xFF0000); + int up = red0 + ((((pix1 & 0xFF0000) - red0) * iui) >> 7); + int dn = red2 + ((((pix3 & 0xFF0000) - red2) * iui) >> 7); + red = (up + (((dn-up) * ivi) >> 7)) >> 16; + + // grn + red0 = (pix0 & 0xFF00); + red2 = (pix2 & 0xFF00); + up = red0 + ((((pix1 & 0xFF00) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF00) - red2) * iui) >> 7); + grn = (up + (((dn-up) * ivi) >> 7)) >> 8; + + // blu + red0 = (pix0 & 0xFF); + red2 = (pix2 & 0xFF); + up = red0 + ((((pix1 & 0xFF) - red0) * iui) >> 7); + dn = red2 + ((((pix3 & 0xFF) - red2) * iui) >> 7); + blu = up + (((dn-up) * ivi) >> 7); + + // alpha + pix0>>>=24; + pix2>>>=24; + up = pix0 + ((((pix1 >>> 24) - pix0) * iui) >> 7); + dn = pix2 + ((((pix3 >>> 24) - pix2) * iui) >> 7); + al = al * (up + (((dn-up) * ivi) >> 7)) >> 8; + } else { + blu = m_texture[(iv >> 16) * TEX_WIDTH + (iu >> 16)]; + al = al * (blu >>> 24) >> 8; + red = (blu & 0xFF0000) >> 16; // 0 - 255 + grn = (blu & 0xFF00) >> 8; // 0 - 255 + blu = (blu & 0xFF); // 0 - 255 + } + + // multiply with gouraud color + red = (red * ir) >>> 8; // 0x00FF???? + grn = (grn * ig) >>> 16; // 0x0000FF?? + blu = (blu * ib) >>> 24; // 0x000000FF + + // get buffer pixels + int bb = m_pixels[xstart]; + int br = (bb & 0xFF0000); // 0x00FF0000 + int bg = (bb & 0xFF00); // 0x0000FF00 + bb = (bb & 0xFF); // 0x000000FF + + // + m_pixels[xstart] = ((br + (((red - br) * al) >> 8)) & 0xFF0000) |((bg + (((grn - bg) * al) >> 8)) & 0xFF00) | ((bb + (((blu - bb) * al) >> 8)) & 0xFF); + m_stencil[xstart] = p; + } + } + catch (Exception e) { + } + + // + xpixel++;//accurate mode + if (!accurateMode){ + iu+=iuadd; + iv+=ivadd; + } + ir+=iradd; + ig+=igadd; + ib+=ibadd; + ia+=iaadd; + iz+=izadd; + } + ypixel++;//accurate mode + ytop+=SCREEN_WIDTH; + xleft+=leftadd; + xrght+=rghtadd; + uleft+=uleftadd; + vleft+=vleftadd; + rleft+=rleftadd; + gleft+=gleftadd; + bleft+=bleftadd; + aleft+=aleftadd; + zleft+=zleftadd; + } + } +}

  • i=B^{6DTbhx|(nCF?X(-fBexKZHnj!X^Md9T!OPnA6`>fL$Xi}wWiId&V}5A=9m+NvY$GE@fQ<;=)pYaQ@4gS> z&3iWJV075;Ld0XNvHD%Cf|C-2bU6nfqYPhY^WQeWLOw=iB7o*m!!`1>Kpno7%&u(d z_JU@-?SoWzj=z`V=N5xV<#ituK@VJOCLDO^e%h3^4|%&efa&pv8>Aoq4$!v(*_oMM zEbQ#;gpori1*(J1HXov)R#sMW0hAsfjcaFN0ZMAP#j@vT!|Pwx$$ z>zZ#G(Xphol!$?mQQ$?A|GcHSxt&|ls%G?oO!}yI4Ol|)u-@gRkrG^D0YfswhA2Cy zpo&QXkz(rb{^kQ0+;6;Dt)EIv1uT6cBqI95TmLGwaElaEeF7|a1QxT79$W|Y&iaey zD~#&&Stc^35FGi1P8n4fI27-C0DDylZ;nI)2psd$i|MG!uW znXnY5n7aH-&MdJwy-qQWA2WdpCno+k-qEBW)NJ*r~P)u>Jy_3N+FisFHZF1{mrM%{+pfpXS^{%C+&_B;XLAyH&zdY zp=@csi2Q3=WlicPFYyH!LWk{BmzNG+WpU}m!Z`<9Tu99}?Ri8v@vacTHTgrhJiSlyIDgzvSiiuf{0B`Z4-v&>+}W=4 z)KlMVusrg_u^9C7^6hq8FMUT9)gdNcl&rEx)}M0~r3azO25MtcS6r<`^ypZQQ)Hja ztnbZ(hQl)iKk;Yd3#&s=ZS`sM>#UyzE#2v3V`U9ObJxESI~D9tE6CG{3Q8y_)EX^* z?a9R<5gkD<-(758yCnF>?y0ED`IurBJ7_>^6|VMj$f)DmzsD;vjDRI~(Uk9XuN+2Z!${>>=!q zXjK>KPOMBJrM(7Ys{Tp4Z-oZE+{DBLj$t0a=y-lpdHUmXaJ0{H%HLGudlDs z6B85jvj7m`3DC11kt$|^!N=yJOC2Y2*5!;C+CEKBPoEjv-QO=!rcLfn9^XUm#qC0L zRr{tQFu3Dj?Cbk>x4UaXZEj~b4QSFo0-yiG=I82`kw(G%Kycp|H?NADpntwbE*yp zNQ9!e^FTku>GBYp4D)==^!1@1%{C4k0OtR0GOIZEnhgUSq)4Fs>wMh*G@1P;-2MdN z!s%cyVcW>SVDt9I9v19}h!FkvJ}B}o`ExJiB8`Y_zE52Kc_C!Q;G+lh7h&{f2Af!5 zhQrcsCvPB-m{K}qQi0cVQs2=dm2kb$6CmxC}$z0`sDuJdW zDV^vfWoRU%=a!-*q-TCN`0~xJ($3)Nc*KM$FAzG1F@^-wX^~rd@yVWn-uf zPTkYbZzn-p?TUltbJly^Vdkd^R3e-=erKMu@)GLF6O*&Svt72M4#V!PN2HiVI%pI1 zt|ntfB?DLV&hgCIR+$>@-$LTz*B?;PIf$^5!3%H^>*|c!A|KqUcd``7W(01xkye55?ykpmq+wa|aPb(? zRnfNBvhR0Z|Mu?ugPlK5AD2(}RcD@?f(`V)6v)Y5m=Y!g?mjNi{lYsw*PmW4Dz3@%Bhn))8D%)|JnP+{wGCmJ~DDMvM@8VpJDr< z0>}AZNInI%{>%R@o?DAHWk(5~RaF&8Ma>YFL6%2>#YI8gl0h>O!jdov_*!yar_0wG zp7&Z$QStIC)(ujxbLXr6`=J}C@B5P*_T4g1BJr>yDo=(?bVcoQmNQcwuHgGs*MTK0 z?q?KSkqQ`1n!vRiO6#Jv70cn4XA{r0(=CX7VzS1BNLtSptbLK%c9+mgn~&IQ6R5P8 zqTfb!S_IGWJAct6jnzEBb)XlWE?_`z7E& zK=5)c=oq}*AZaJkC`$P)bicc8V;SfDZQ%IRI*~j1i3fq!f1Zfw=1N=uj`7L=lym%FEl$SN>`!?W&=V+(f94z`04J9I z)8a&_&HhL|{Tt`_|D?r13H)Vozvj>FFh&SQF7GGa($cfDiLAVv>prqq1?Xj<%{E?+ z$>GzfdMs0hiN9b=yu`zz#l|a$h!m3}DYR@lh52;ML3eBpP{h)TeFxA_$&K``$FmcG zXUxvW1R;*j$gK{D!3waC_cWlvI;|0p;|!~}{KwzBiKKT*~|+p zlYTIvzmyG6N=QU9f!CFi*gb)apM~y#5L^GEqkFL{HqytoMJFk8Q)-R=IDh32t{Ymyefl@wLgeu!`eEscFEMkw<~wTFFRsD)zl$8CRP zedq;6g&Cl%`5EyD`A&6id4hG;#lL+%vPhW#(a0*Xjc{&s4HfCvGw{V+n>}Of4sJ&p zNqsL4jdpEYnm@#fu=|%XNJ91THH33Ep}NL3`*Y#qw{}GuN!4Voif~~?D-~-M~$Ws9>{HIFUTRvAW z+Q!FbE;pGKO-}4h=o)j_mWY~rY_%53qPE9!_3avrIfoH#zNp~Yj(TD3BiWWy&&>ZU&0CihtDbR9mP=T(<2_oSaq zO~6nRsx#%!&7L_k@unE^o&aE{q0fKduq* z&)%&*xjS#w$F8GgNQ43ARG!n~8FYW??D~>xC%c#NYjy~@K1k+X%f(Q-!g`(2_Y3#P z$hiU>1)0giF>u9|*0G^Cwtf_y4NmHpiP{e*UagZK+rz`Qphg>xboILXu1eiB9__W+ zBgUS|hOz0ZX+yg0L++0!JF?#Gr9~&F&fs!iNQ|T;8J}lKirGfI41tT}rTsOq{3HEi z&V6NYb&#mYXhWy5FabtiGGFFhr!2`>F~qDe)q#7ipIhM__<3I18+q&fmk?qS(~zQK zQ^qdom1`uIzQ6?tbL#I2e2FF^-TU?#>vN&cYBhFTE7Q2^+Kn94=|DY+@R+1sn)932 zF6iVGaJyhmijUMfqnCPU##8pzY{4Oo4XSUZU{as6h4Q}mAY$ai+ z?cI;3OH10i-F=UlZW>GLYHAx6_Z=g9NLmT%PpM<>mt znlWvp8iklskPLy38>YXQME|1&E?e$27&;2^L1D+{e!S@X$UCLfcw5+sJHm1Bm&9BAo z@7R@21MlCyGAI509IC1v1_J>N0`d;bq5pb8(0`pnl`PD^{56RJ`~UxT5>@)QNmSPk zV}Zc`@?c^-X5sGa1Cs=7{!gW|gy#aKaQmh68TlVfeJ({R_Ud908EWO0Fk#CxqvRY( zC`CfG;B^DT9GmW^Yw6d%a!h8?3yhqnvYE*-YRlQU(RVL*={+E3+}>iuQ7MowUxI_c zA$s1d$OoSaafDCra4Y$Z-rq={^}Pc(9<430NTAj`@_iQ0w zlPUCGAJIH-c@#hecpvY`KZ<^hg@7>kj zP{x|x91eC_5}CU=0;n+oYZX-a);FcHbq~L(^+Lp5%@)>RL>eV4ktp}VS*e1EuTnf$ zY=M&r{9nLGc|GbQSwdjvh&3YTXzJr<;u2I~(7;sN+I?z~HA@-3ganFUx+6E2j}{Zd z<{a{o6t%9W#)85QTJJ-Afz||F50s<|2y20|!UzhD>~gd*L|ufo=HNz54@wJUjRTRQ zDk81FKHQ(*|B-CvTI+*-2ri(E)(B;F()9cito?50@cz8_7=3VG!%)_BDz=Hs4AKe0 z7`x?E=(Psv**iDe$AtU^X0v6aXn8i(t8fJezwbWx+V_4Z>@JS-_R?@h-0wc@c#HH` zYA%W|&+zk=mh&=tu+UNOPBe*|S~HCs`%RC=_MSdteh&WCSvNZ@2|(#VaItdAHfS^Z zIiU;sZ1IWZ)W2E`uOZj?p)4d%CFgkJ*~!v$(5sm>_>$O&*fZ7vi%b|3 zl!jy+vW#94x>G*;m^4`gr0+}Acswp!5hW%n8g-~~r}=WASpzI+r(Ho2xjZRs01iC~ z<)Xv-DSDo2Hn|<~bS4V;x>jWhf*Q8hz^|Q7czdKkC>CbbK$)#yoSZG5xkNiQv~lg- zf;EOM_dluxH5UDv9bJrfa@G9^JEz}1CXf@87SSxO2|O*4l|x4+joX#o6Xl3vL&S%% z#E+bSpRKOtuQKHKbPnE?rpAf8%L|Ki%|YLuah!OzFy)j=DCfjnGJevvI}(2OZ;U@u zn-Xo&#P&W5D!f%I^z6|?(n}7Qcb4l|%R9snKk2$Sg-J)|I*08ujxsO#WzaAF9pP!` zHs@3(z7%&>8w|7pQH#czq%4XI8`q3W?Ob_{5e%MWGrLd5WRy=>S~A0*I4*X<%Z!pl z63%|}Q=*jAl_+ym3<`k&x%deX%sylCalu>6li$W~vQ26FdfUH#=_*~0i%>i!fB`L; zkc8-TcQ-x>^~2w(!i3SMtA}#U>2b!>Ut8AKeq0$Iezk%x@40=SeqM_uQ+QVqtql^e zyhXj*A`Rk1q)J^VfR7IovY6hvP2j!PQ#!MFu&@Xx67>1h6&|L7!k5L(TYi7a;C-^~ zk-)b1jND>xeA}GA4vr1RBf5N=HD;UW>^kUmhuDb>SB>x+0X+LCYD&0E{{8q%S0YZB z$Yyk3X#0BhQC2uIqlMwqz;K5Az^Y;Sv@DRBt! z?Aj1$sLQ8JiABXuG&^ZE6nf@%xhJ(Wf*l=O5?#eOYvG>WeYx|sin>2#j|MS{ayPyt zG3qRw`;KY>x887n=jG(h&*4R-scU!MrxmS;W+MzEUCUh}h0ZPD1%G@H$c|Nru97pO zfH@^*&1&q|+RT9L?zSArHhIA~umVQmM4QY!nBQ2;9lza@5<9g{`fdCap~wT2bThi( zJ8%thZ+GX6JCWsTZ;6mAEZ3O`*B6&{c!ssdv=pKY*gB7Yb*iTxaOSLaJqecG_kb`s zf^bNgG5P=f#A-w!#Jmf9eGW7hp#6^-!T&h1IvN^V{Q-si_b?Z}(8M$VbJ;oG;)2tp z7*S25AQ6{sNgRP(al`YGM&jbM3ivY@&V5M46%xKgTL?otDEK*;F!90{95=D50`=(= zzcfD?IQX2~_HCdL1spL&-=hV^UbxsdgzoS$vB$P=H0j}Rw&`Nu_8!HShTytUJE$zb zf&Aj}Xy*!1nb7py=b#D#4ZRj)?C5{5bMsDJRYl>xUT-%2MaLafe?@nPWZ`)wB{MM` zN+5y=3E^QT!9pj-KFQZ=;PwbU47=j7ghU}250Wvwd31bGKSh%d`(Gd=#>5YrOMoot zPoVwl#h(9u%`E=Hkp9GvegYW=|Agwo0dB!x_|aPt@(S?g|3Wkm{*MyNHc4G_#^U%x zer{%G3yTXlV=$3}5K0E~3dG8J3YDZJ#redtgk-Yo#7uEi%oMUpB`}&}N?#Jbr!)&` zin9nes~JRL?F>dT-qS(e>!q)~6wiKPD|C7zGLPxIM)8+PP0xWexOk5TacBo4mQv5+ zXWn-OT`X4m*4@-}E8C^_UawZsr2)`9@FXZA1~~H5iR2_P#@k%`XJ@u7_(<=+Z#{dm zb93L>vgN$|a}&sM10bBM)SizwH#a+gR4ktbmv0LvDix}Y^YWTFP$DqfT$B-{fy4%E zA7)Q()8tB>JJvQLk{@(Bf?g)bs8o>Wy>n|xuYattzX9cQv<-;F5ka8eEx6Dy#-KR+qxyZAy|Om z!GaSsIE3Kt5C}Us1b26LcXtmOf_rca?hrg!fIx5w9^juj=f1yR-#({b-&fUjyNX$< zU3={%S#y5#lQG7Z>w5}t5RD-rAvzw}A=_?cWo2t_BqE`$jKO-b&!xQ)Li0jdP@6hB zBxR)QHSQewNN!V7QhXrZoL}r~7d+GaEXv(nT{|zmKy@iBFZ8)IIG!u|aZfC5_$lw| zB^?ej4l+F7c>aQAJKT`3Qi+C4l!QU~8`|9Zz8VI9vbEh^WI8J7P-{HH_pol3&rZv~ ztnw$-9?AHYK;fIBH$tyTG?Rm%$c0Msu}`?9<6HB{kdXW#g*YNe@z1;Lh+sbXzORWy z2Z2Z(&<(EN?_vp*AV^JW7cADY#`~b+~5=XvK#;$BJL;1JwjiB z3Xn;KAyLRNB&QnHIv153&E$~kI`n&djP783NgCQDk=V1#{T3|Kzp0CF<`afj0xR+H zU$qp@e`K5guoNF3DgTwFKnEAa|0C~51z&6iKKvUj1?=5FGR=wOG8U>heLf~fwc{PX zl;HxbG)$`XUl>xPNlC_kdsb&N;g*xDK#mlh`9(eAi#7%m51sgqRW;X`+~tTQL|p=*Ea?|Q+Idb%%@hS^`iMIhX%psE z)1@EDG1|@}Q8G3foHkIp6$eYINTb}kqN0L{H=1(s;35N*wT8i*nnOoNH|f+7!ox2J zmv7R#|EOK*qgpz{Y2QSYCWkQRRBiQaxQ2_LzYWYYUUSY2L0CK?Nmyfn9G&Hrm3wah zw@V)0I_8V91ad&FJgdI`C4eneF`!Iyu)cOEJ9HyC zcfZ44qs-NX&C_D?0W~x=ZEaw+>SpVftP-IHM!%O?1}Ne2u^_rqlYRgGJsfCTO3}qZ zvHDq|GKtXNiwBBwr29c4i^ zsjh~6qYcMLMKAy+J#dz={G}aHemzOTb5@G9kG~mM?~14Cm>3v9Sb{2AHybHI=}(q= zGvM7J_{~U66g$+~#^%AaUZeiYT>BArFu4rqhAxC8j3X{Z$IZ*T2cys_1ko#|*BnC7@~)2KihIDQqXW6oN-SNxt8E{~PWAD-;+b1!RshF9 zJ%2&`_v`Q%)(?WvrRp`33!BBqQe#LZJ%-e%ZHBb@B|tKda#aAAN^5=xB0ys z>da;63KHRjeKBC^r~t6RjYOs-`Od2Tx}EggD4n{<3=6J{|HyhK5CcwlqDFA_@`Mk) zR=bj&gCj7J?Pk&)u^z@w=x1TnCx>k`U`hbU1BensW#pzKeJ49s2j;JM&-syHQF}rm zV3XpC76n=kK_b9i^fC*nAKinQx~5nSgPAHbjh#dZ2L zxnMC0VW29_@wy=KlBPUo0N7Y~@ zne|!nmpAduo>PTR$5^3k%77u8VeP_z+i(roOzDg`+8jB)R{l7i)gy$1X+L@uWnZoW zq%~zX?YVomLd@$4qc_O*&UxxJ%ITEO-|0keu&}aD{*0xI~Ep zV0VeKE?0eWTvpsd3Ja;U-G3CCCdw3IZP}+KB|Qap5$M$tUc18Wz&(4V%Z`~V2~caa zuzcf`Nd7xsFJ8Pz95w<+UwaDd-nLz?Yydgd)~jz3d}kxv5Ffe#6`@w1{6=+`n7QPl&zulS4w_I({YFzcs0OZ;awPF;L ziDXGofSKBb9}Nb zIhWv~@7v7MU9<80U%h-;2pX8>PlhuSH}^JmxyLJ(t8hE*0%sHf0bvI?`4nP%*lWi2 zoi}1Tzi~}arWAE;?eBe2&u9x>FBVKFAtZ(tnQi9H-Uo{>M_iMmLw?*LDgJV!PFNp^ zqs$ca$p#NUDjQY9DKkBLTV40*{a%Xjs4AFS!FtD68!-S&rLp*BXx6oZCkBA_OB82y z!XH&F%+AgA&(GsKI5QEl0~4Rcnwtk@Ba zfSC{u^j{j1dYs0$oz-of77UHKyLvSn)l2AM3t0*}(Q%-axKXP+_}H+&bPv=a7_^@7 zL#nRc69o33R*!dv-G~ku**`g^JnQ9)PLM!CS*N#YtF1mDQM zb$s~lWjpmqHMj+@#b!k|e;SD_>aV;VDaOiT47t2WyjpWlQ$U#Z zG3CvQ zpspd=>)B-5wZm_(@6U7Y{m{KHNqnv^1&s`k^menqsg#WMS{PL@aN#si@o1uL%cW#z zM!}AGtAE>1p+bE`f4C@reC?2s`LIOFc6ygH$?ncD!t85?)O<$F6jDkr&198pNZE0X zJdGjs{w*00OI>jI1$W(bM@!D4=nC`2%kL-+JcH_BoOC)FTrl)X#t#Dt#<@A7ZTy~i zmGA*276FRnFQkVL+jtlU#f>fn_s}w^HzkeoUWk(mf+W#?OL^gQ)c?G883}U=i25Sq zAQ5W*@GqkQ|C2uU`4T4?3X1&*H=((TA`d)Dgf9`eaB z@%vH`ts``ytl}B?iUeQMGJa$cq=hlu;p6sPe*M$Z4F)QH=i_HaqPeqsVTzBxT@UBd6f%820J>+uJ-#MY@nQ{n_w8_6uPDuf1ge_oafg-kb1rHw^ zn~16^9?;<48q4BUG&!ISdG!&kUo}|dedpDcD-KLX1=`Vkb%38AO#9V06mX1Wy@nMp zcdMe)JPRt|m?`j`!11~qTHbVI5B)xNwIkG_%0hwn8PKueN`&G-slVZ$_+>$Gdl6>5}EEiDbd z7Y#{I=DBNAY3N%hjfM=@@VrG6Ec^ZUaPqMy?|6=sb~+YGR2NAocuAJ$%@YD^3Ji~; zep{~~&Kw+~{c^U&1GX;*)%^KYBbvef~*j29if6UUAL%%=HhaBR_t?+KZUd2mnQtlsC#jRP?+mxDt0~e zR?m$aGGvr9UesZjTRhO!c0HERbM`VqH{-SH3hZYMcxC@LJp0N&1N+^F(Gnz?y>3zHRs>dXX-g1WXYIKDDRZ1mGyR6fp z-VgIGedkG|Roi5(ZZcCb-xXWFv)hEsUyV5qE+^E2HyJr(F#RZ3SG&kLI?QLw+0doI zbw=W3CQDgcqb|KunXrHW0(S@8WUAD=pRf=2;|~M-g=ahLh+7{ON^n^`^1J)lsZI$J z-fJa^<+YS=RzWqn7?!gdS)X+Er>Js!xB=|1EW1hS-OTtQ>tTw|r?Ay|mj*`R7^4LC zo`AuF=OK-bYVMk|1uv|039#P!hmiSPDeU}k%lff;mpOBt_F*brfxy*!gBF<#_Cxb~ z81RD)GIYV6Do1*~cm)kO3NpR4t9B6?VfRfIFJ7Onhpanv0seF9bD6jTD}N}y$QlZa zO!e;fMR_#Yrl6jw1v!7EMFbI*5Lj~fbliQfn-EWr{qd{K%MP+Ety}H27m1L$gJNi! z#S8A%!k#JSU-rW1hCQ*YVy;8<+9Qt%GeuOj3KKB`pCc7keVD92Ufn0H;ytT!9Dn7p zko-hiK}j-SIC4uP=;`d(l3Di$h3vG2{I6O(lI_@ARcSEn^?f&iNLgnvrFL^kDumH< zPw`>PB#dSi1VreJ?Attp#EJ*kdo|PqlAlacK7*Lbl=aJ6&`6whDJa{f~k^3M>;6*c6q zLMT3PWuZSpCfPP#ohE?LOR~1?i)oh2z2~jiHKgK`0By0s3UZ8L((?$fNyc6XED; z%!evI$TY}7^XfKN#<|(uxOhWMRAuKjKfW6{hCH$#AMv?g^>ldn{tWQu9`D@>0O$0} zo|EUQB$6<70(lbXSwR9EWrCK4o7QlVS)^NJ zR1pDz46DY3;dHu)!07P~(gv^04xg5d->e4v%a^@(m#Z;}@hYX_z$sQK1vm>pPnIt> zu$R;-S5eo{AVg9r9p?Kv!Qu1sJcK2mt^z(eVlG2V<70l3E>|)BkgK5sT`+R|B>>^s!`1rU>tP{$yPf(lv)=;rNWnHAXURZuH{3~2}iZXE-zgXBpPRIP6kG9Zh z6cm)!U#G)>u%KJs7WIkuE8YI-DVt5l9p~`yaE3nRIlfk#S>sCY<(TcswxIFB&=JdQ zUav%QtaH2dla}M57nP7>ATI|T+stC#qpZGmAep6R;dZ&~Qax)O{zMdmEjVle>{|Uxstvn1B+xJk7u*4afr-f;bm&TDSs-*FY^kd11ot3N zecXfYp`Y~p@FT7evi$un9Nu^ig6`cS?8Dh1b2V-xyhR>vgRh)9X0A%99gz8pw)q`_ zB*|*y}joN|-&;SM{vCR|P?VYr}bR(BLZ1-3DY3Sy9_HOTr! zb~>QjoKX=;cHL{*eb%3mZYaaPtyRtvf+Dr=hTQ^x%-W@M0BWE3k z#;)J`xBhzCcjCMZRPgu#FrG`}v6rvz}bsiw0vNW1M@jd*ic z2e*5eXh=bwfw-bAPD{2~3|}t2K%6gMuMrhvv|K*HcuZE+r_s$~-lVCVqm!wvgV+U~9TsPw+0au0f zB)3WiIq~#^im11jb6ApQ%GIuGP>Fs(p7oTev6>C887Iw2cr8+A-~sY81C~Bp;F*o( z2r6K}ZJxP-?s;+(02SeKNCY}e5%D;NhJ}SWHxi<9a^PBc-S2h#u$SOnC-gI1duBVj z7d+A|Wvr=DlE90`Fh1;2o3K`O092jRYd&yOo&qtmJck-!q5uPtKe+}%e$cNcZhV^n zM+I4!Q`2DEHH{w~&5PbyGQW%FmAvAhc|m$;^Ur#VIq(#qBmzQxRLAW%ud>ref$l*N zV0By^E)VBci4t^;{UWTr4Hm$5{s3J!KgTNV(Gfuu7UImH%98J=emZ{kZD*{a55H!C z0o;dulU$RQ@tgStXh08pzGipPu#xrRGsPg{Hx|U2gqaOrbu1V~Lg)LwnAhXuI2#u< zG45B`GioHq`&wIZS7{<R1VO9QI2IHGfg+vTlwk8@^7 zOa1KdP^w(Zvue8xntm1LGgD}(ba%^>(uB?eXZJLzcXPIGM-ux7G{@s^S9#qzm&f8k zf=BBS$UZBgA!)N|@8YX(MP8&`T7T|i%#_<1+mzDMV|rK)of#B~PwQdXpGZd;tZTt6 zP0+9A&>opje2F_YPk-bvMbsC<3v2UzH z+IlxoRzLe??;L-EpVOV-GkY3pPft(gJ8iwWs0<<=rC%fSrK3c$JsTqzT}v?|i}*bt z)BsW>(UmU+4u(YOdb9aGVxcv&Ri0WT-}XI>F8HoG3p>@( zIGI8&phLQ4-{i%b6g^kHqyJH&MCltK#}_Kmg9HWZEVOd_>PjLzW+;Nl)7D{MhAZ5A z4N1=#b~>C zoFkd#=iv6!Ro7nv-qkE4HWez|5yq{ld8uzV+0(W9MB~D>&=&Egf4`a}Yo3sSY6p-5 zBIb3@U5tJ``16n~NT_6hg){#0YFhA9NHO}VDEWr?VGI@q#c47&>|kH7qhPDo;MaGd z(D1l8Oy|R|1Sa%8R}jaWQXERz9SFqGv>^Qf|t*B zU(DMIiev0Gsk_G?ss+(&2~u|0h_Suc-ZG&^ZvZPqaU`uNVs9I<+gNn9lhgnE|g@~ zsTJgJGr1iQ3{dy>_D;6u_xBk<5GSUv-bi_7b=U(K>Kvd-K%9mg1Ut@mCZ_-h+_u^y z3f_Ayk=|w$hc&pz_C20k7CwGfw-0pnljZTPx0gpTUV>U6`AWoPtBbvIFv!r-4~+T- z$e$6fW_w+z1Hzycc8D!MXLCGd!i(dBqkCI}NZ8x^E9OBQiX%b`3Yu}GrNIoD!qkk6 zy{n6PgBU>hb3eA$FJpC2x=jeZbh2^xbqRe+il!6=cOK=w(B}PB-`iyI$D)>*)1tt zV+>jUpXjQ=TUYc*IcFG6DEBO0IHc3w_!)VAr&U3UtX4DFsL0Vu=G<5Yw!HZC zg0j{zhNb!C&h7p8r%na~^HCaVof-u}TTUHTSoO42-&{lwiQ}p#(1B@LSbm*JWeXIC z#)#mAE!lUgur%^C#3G(?2A&%aEWA)=z`!@X5q2D?;#^Fd^tS#2mXul+hhDR&!|7yx zEdji+Zz3BLA8OA4_p^Y<46o)qE6N*qNceBwlUeY8HEpB_r{3qtvQBCwEkpD71u{9l zGcz-cf)-CidTx)HYwEu2Uzfc^iB12ykX@d7Ux$wK=KToWEl_n&o^7kRl z{MT-VkAPhEd;AVR{!cMCe~NPb&qSpE6@9}eG&1^|WQJn@%@0SmI>7`95#x((fg|KP z6P_fl7Zp{DR48@QENT!nH`g`HLM+Td(Oh5J*gIQ9%GjDd;QjmT!t6LdzaP9O?!viP z@Uii0zv|*oKj$eStbX3i`}Orp;)oc0<4E3@(_eY}`tYlv%h>fwzUB|^f1q#D-0fU! zKI97x_neQTxWUawTVb)iRZ1Nw_`d%B8^gr6Zffu^S*)G+_hAFxB6iD+jQT6(PsKZJ zi>v5Vz1v5(9ZV9+1?&x`ANv^5CS!5KqU+LgNO8;D6Y@x|Id-Gww9iKIk{WGyvTqc< z8jIZ>E#(b{EDf1f7IwwrqF{iCBo>UFp2o~%5+zyO(emI ze#}C&rVy{A;m+P#K5wvk;b40Bu+6o7Z`!N{U#QQ!$bz(C7}k_u{q{KXZ?guDlyosh=8AxKgZ1*`@}m8wZ$FXyH?| zuI&8$E~l;>*!@NsQvgv%9xW>P2rWiITVV99>P6{zvZdkzEpsk?*Ha7_)-}JEX;&V- zKfh&_?K(xVN(|XOe`>`}^ORkea0iA;mx-k|MpW<`Ey4KVx!$I3OxXIn>H5|e_a7H-vn5G2v4E?u=dgsR2A~Ngz z%0Fn?Uh8-5CI?MZ>b$$N&rjdYsChg2CH;*rGuc)0*0<&LlOLoCXB_BvWBWCX#g7hjL6J^2v~!n@_;wnn6KpM`5&lzPUOM{f!E#LG``%q=kAUr$`hfo#2y* zrLP7bjhYtBL>Z{fc`Kw2_b0qQWsJSfC@*)jX6A-cVzP-yq%gF#ERB3I=F9TM&D0jt z%8XGAVEqX1Jn~fy*D2g3_-DIL0Dbd3P#$rEY;{ zGFyRCQa&1iK*Dp}I&f<~2g5J+p1nQ_|H1jhi4qA$2Jz5dLxLuxf4kCq_$}Ve^0m>D znVb?1#>WSw>b$h70fm8YuP#%)k3Ti7jL!<7U+Ln94f>%ov`M!7nCY{$y13p=r({il zJd0scPX{+UEAfRJ+LwuDz|?0@0MX#>-`}k-07@f13SNELRzI@)pfsPt6SNKOX{&Y{ZNo5W^&M;XbuK2!cCc?dm^&jBw=BWH81>WI?Y zw=Vi3zTLv#S89ofbJ{(VP1^Tewo@!;UdFwko{s+%Qx%xj%PY>mRIfrn-mi%Bppe`F zGvaXm-PpB6xf~Wc5FRE3EV^E&svi{U6K_Vfgl&|5t5j;(yrC zQ5zg5B0#T{GjVZlL8+Ts7VxE}E->RW{h8~^LQNQe7eM8Ik8)wN)+fE;XN!6DjL<(3 z@ny2_ij*gkX0sUKuxN@k-SWb6+CtiDZ3v@ZL>ONCL-&iL@wttO!Dn2EXz1n77rqmo zkg5(IX(J}Uy5{6)JB{&VRyk5iZ#ajT-q{UpL~MsuX2KG{>$Ix&5WbmZjSWrdm`BgN3y&6(~#~S-tr-wW8baj+~t|6Ef6w6vLsSX9D*i?GwE>mCCFL5^p70qW~_W^yQ=XQs2He zBRrG)(nYXCLn3U(ETe%i2_yDt?>B7ik`DQ3yHJSCppX9z7Ws|Ir#T zf7|XG++w2T=z^2&w|R&MiRE}|(H)wigdv>KTI$9{!wlLJPY*~neY0>+Dn*l(xb)31 z`qpC*Sl$uT$oYI4u6Z9PlJIy`$b6BPd&5BdMgYmiI=N#3JF%O--R4buCwsj8hg5uK z)^Ebhiu3_29~4wDu_V}K@u{y!Obu8h*mugyOvcp;{HHqmnGeOyL^ILw-CSwLj@mjY zaNr)BA|6O~JEsq4g>+UBy>y3pj?@lv?Y%P+LMX5S~h zP#WwDww6*W72I%Y*^_ zWjAfj*ZA-8{aKMG)fDQJG#B5E)r}P1FsRxtl4W(z3FN;o;?$;KlCjKFM%H8DZc338 zepxGK7rEVqgo`fQ;bKBu)g|^MFo^5q1m!jsN_m?3sh-fph53p4#klVT#!sO~mYWUJ zT8CeC1R9?=q>Cmu#*Dm*gfZYxp#rbzRl^N)+}6@NT)iI>+))x@bqn%l54PEdTjax& zJx+B_QdW~wYz|f3-(J3*EUd&;TQ!?(15Z*&i5rU~Yf02Vgdwk@XU?}d6BEMFNJ1OP zwkZ;~nVz*$m7Kel;ObCY)Rmq4rs5ki?iSpKOncK0QQXMzq;q&5(e+rAS3@RZ3*z;C zgrLXL8*mZ%bMF?6(!Q2c(S5^-hgM1Y1OQQ*+=o3J9~?3<6d$`dEv&CX|0?kP6hV(7A!-o zXYNV87TV&f?HX&^#p2t2m-ok&YRyfQtkH2Sxmu(_gBk-Cq*;)@0L{y%BIfa0dUfwp zq%MG*1q$Wok^x2BaF&N)_Pe3Q z(Ndu$kF$jJP=bvn&s_0V%?S6g_+QM)J}~`g$@U7KHWhzwprsMX;8wub+hF`l=(m3u z=>ILlV6+SF`S^V#6D)M3S3a8@2n98g-UveM|F2REG(7$h{@=_nN}Y=0B*| zaOirQTH8)trhHytKa6`HOtm`x;+ZV{OXAiSZbkiyJIC*OUb%;)j<0SRhQ1LTL*fYT znw}Xq%6cn;{ZDZL?LRXNx?%bMN}=MnTr|obL4iHqG6+8Y z9rZ5Qr+;o}R&lHfOK)(3IxdgT9QNNBihZEOLHHmf5;tEX#vsM8thwxD;|OB$D+62w{a}Wo2CglKZ&$@sq=M!yMKBb8xRl*an9Yno}`{bP~^H< zo}-GE)#DpXXl%G?!(d}(Isg!TABH$4#4TF^vIk@D<+W_aL6`(B5yKC@YS-y3%H5}WL7%Ev+Kwc)0YaXUrvPtn@3Ae6ihCRfsC$p0F1J~eN$NxOSzNY_!$N!2?+`4Be6LSltJe}fr?p30fx{O{tFNTYXESI zX8=uC>9yLZVezv3!tyqAB=E(G^n=xJz9&T)KSC;tSZ zHw<0u9b(tV)rzsJFI`|#{tce~Fhs|D0IZCj|K95OPpJAHSiZkn9Y81@g7wGhh;n-F z^lw@nxPPvWpm;$ApsL^NbGDL^MPMx6FJ$P_&+u3x9teNVznOT0FX-#n-KU^uX3~S0 zTUWz@E7J5l@e96lSOgYXbc-159>RBY7t72~efSFY4hat9+`WVKS5KZD`)c|=LSlhK z5P}Vb*IjaE5fpsTH#7UO@b&B09=`Eu=axG+2ZysB0D8s+AX^Q(EoNrs4vly3ycSG3 zc7eLGb-Bt}#;CECp5FRoSC=q%c;4GJt+~B(8c=AeES>p?2L}VD>~An_jCuX8oSfX( z)rEy0{dT{^M}Z*Slb#8n-BvJZ`i3cmE=k5U`#0JSEIt<#V`Gv>PuaP-uYYGeSx_-C zD=I6i8BqG|Y~Q5--iC6C(jkl=YhNNLPtyg3>PB|eFhsH@%255m%t5qGgwm_Z=&9rO za`pi}4E`gb>}_0MdboV{p(v3%d!UaO*WHmTw#lrgH&(Nct{oPtOoU>PY!r$Fklml{ zB11PJ)WbDEJCuSV6iGT>cZt(19X7X~S~?y-RJmjI!O_!G4o6%|OUu^DNt~$vxwJ@n zQD#<_bmiPFLS}}1ajlc9>y?(p0iv+)UUMiC#4LTvyuKaurhB(m+74ulpT;fe;d9o{ z7VY5XE?c7mnBgiZF>%|YW}fl0pFlb5Rd}AmS~P3l(YbrT!NEbyvuDq2fL8VjEb&^u z>E46aeGa_&jUx7X)o+2#zgZsrHJ_G0fu!Q^@vkS9{#+gZp>XuSCKkU6jr4%TVq=+O z4&q;{SKUCmBjqjRj3My7vOv8mGXjb&%XW5#Bf{qJmH_q1Im3A*DyrOS*c=LM60L6{ z+;(wNA`NaK+Z8o6-qvpX(^A==3-tq_2lI2=U0KWckyL;;X6gQ6IaT z9uq;*2aoHMcfE((Kg#z4@H(bzV<%ha9@dhSv;-gSu8+>n7jQo~*?wZ$mqMQ2M0Uc- z(jVaTJ9=+&jTo)I#fe_Y%<*8mEfnrs6fv~W7wj>9Coq5HD36)mB+k@(OPFIVQsHZh z-!n+rcc`p!L_+ix^Osw6w9#?aNImxG{k}l!FrCSv{<%xkOiJo2^_+JD?Lk)C%IJe7 z&E}Zt>|$PMp>hVV*R@C8oP_&?D`MAF<@6BkWz3g2GMaHxyTzE8xhLO@72puFp0)q< z%Po;yS}f46`(^SW#yXluCE?-`e&FAw8MjnOZjZn&zYB%{m^c4gs`)==grlR4)gN4> zUAU)zm1z8}$nf|NtC?I{mjOQf8!$9*{C`@_nXxt-P37N-#x?=x%y~1YX%^E51fD$9 zG}9D@G)7Dqt2m%`@Gw!0C6yTdn7&932^Wi6%n#}Dmz3k824`g;sF=W6ovHy!1q zd2VdtSD!NQ?QW5PlkF(tGj{bK$*J1hRhg{vva55e?=B=ITHa&y_er?fp`wxcDXe5w ztX$h&usFhZ_m5B$d=3oL&*=2U<@q+0={kMsT*Z zP***td;S=%CHKHjYvWB{0%3&oljYCs1+c%EQrp^LO}-p9JdeXQ66FaK=jzejA3zN( zK$}vM6}l*+NJcPv#1lqt@G?LYAr4RK3G}1al3Zw^_?|CqHPRmb4j~)29|xkP=6kFd zwh3ttf)@iWPbqRJtI6J;Yavn+4~fvs25PXrks3Tei>Hr;$_OFHM-}caAC#O9_aI?H zZ3vKqVk1LYE->W9t+#(9AWTp%sC`^9lTV7lBTv!GH>1U64_r8GU)ES{tOq|j!IWbv zSee3!h{c4p2(kOP=bUq~uzR7@WB1uz8_kfLk}P!FO#1~tG5fxdAc49tD9^-$+YS>Z>{-s zXg^b)sHEBIpk@);@{VLB)2d?S%6xU`WJv$rmU%|Jnnvp-mx0u`)TE%M?;0KT8%e#* z!^;-ZWe%Yj{+;iq6Z<U+9zz74!~#|0#bRk=exVKX=-}+`T<0S>3xb}|2IklJ%wov+785enXIIX3_UET( zv#fdC0(xTF^Oi_lnXkn5W_BiLh8=3WI=>HLQzzhs`jSD)C^Ra?hgaXF%Vykh;!iH9 z(j*RqzY)TBZB5v(P|m+y_5L|x+-b3S3VR~)Z1BT*-bC20qKR4iY^%4C1gE(U#0Q4> z7^}Wj2x_wtph)^1g>51HTL|#qN5@SJ?|hSnQ3|3s1=!7dw7NcPDz@_JSZKGfCERC3 zy;{1`RSH?~k9wxK-Q{U@mZD%19~E%X1#6cdg)Ui-PdhJ98GblEw=3wwiCw9hv*3F- z2piDJ!UEySMG^B|ynU$LUk#Ft=i%RD$OgviZ#LJTY|i{RAk~Nt#(%Ay{m+rvpQcpF z#`X_8iVlDLSINfzC+w*HKkVp?tWBa3e&5N%ZRYBk8Cu=+k2f+XN=q_O%1A=&<=n>! zpMHd=&Ql*QI}KK>hHxM>Hru^71$<(Sd@S1B%s^)zxqk5o;*UC=CN4A`w?p;Kq%n8J zFr=X{DEklvKbp>qm0uk-B#`XE!6n(qjuzAY7zN3qr3CbfGQlQyJ*%^^`f=Z!i{u+u zY8w7Fv9mVu1wH}dbZZ6v)|&hM#i07~sE4YPA5?uS>W2GQjyu_xKl4lXGUk}eoX|Do zdTGULhJ1v-lcQ4i%-{RtGt7ova-W!C0s#RksPYJDV;?= zr_}KGzH{cwgMrhJ^e8$ip5N3GXp%YD4C{l>H}c#bLdbcWTfu3W&B@ixX&ofv)J|_w zpTs|EXlnf^@uHnLj21<<%~t7c&f-Aolc^dvm&$h%dchUE-rd|zl%Qa+8RK^$Qc=W8p$I3 zd8Yb?bT7sJ_W`v)Bzn+wiq!Vu2c&>X2J3XFA}aVmYpi4;)7qzVgArp$F_F$F4$COC zvee*QP-i~j>7s*2!``~Iq~dcNBauvs_K)b>xUJj?6CQD;#NwE5>9GCr<7WDIFMZk* zUnFv>@5U|~Odys#AJWj;!S0Jy>VzMH#VvfD%$tb0bBGrAR%&A)-j^b%3_*{}P?mK2 z`I4rWh)L{hTtBNig4@$yrUSSL#qe#yIi0kLHUr;6`2t!Ix@@hjks>!Mt#c;K673B2 zlO_TMQZWIx5Hn(*?gCB#~ZD<_<9+Pe?4{Rtn~M(LlDJufz%51usm8=h!l=@&-H^%Cno3ZEgWZ$eB@hsbjy~_f`^n%4 z{hx{Seth}U(GImFHNn%wrKugz{MrRVaq#c}VH{*v0Fhfo#oN=z$Lp>`kS2!9_V_~t zTbbFqE48eZ>VHZW7CFY5(;`D4lwkbJ6|lGe%rT}!{(Alw6|mo` zFbsb<_cR-Ozsqs|2Iu~<^Pij2a@w*D(F{SKkHgr=*oe2AORe2Lmr7{-2VD`R{yZ~j z;V=z2tn!aCZKiL$CS^Byncnm&KRl|yie2-60WJ8bTmVh~s4P1jA3ue&)#EFdOor|A zne^7^Xl!gGZ8~C^U{*SPO{H5U#;I;^ax8P3dz=60cElkP&~SGFT3inwi99p|1GfBS zu-@~zJX#T%Fle}WeflrvKp~khJ$&g7)oBfycXZ-7;i{aS5+2r%|yiiwa=n;M1)G9=Dei+T;McF#2Twz1AmNc4toIyLCg;6p&6h(pDX zD!O>U38=MnR3Yf3fQxGbAvXAtqgDP=1PM@xS@UTr5(d8}iPdWu>FSa-t^9EODj4f@X z=;q*Z`^*jSmY^k7pFT<92M=BW#RaWTw&Y!Sl2XOfU1xl9x8+ z0K~1Pp&?^jrBVtg2ErJz;IxI%XU#_HsYOjCPl4hI8B#3t+pT~ee*B=Jnz}kT3m~hC zii$#hlYO;XUE=`V8}v2k1x?J3`Ix(`d7=Z3Zp$hvu*5NcgU^c&(ri4&x@kjRg{I$9Kn`@5Xp z1!AZr_nwUlj#I|)b^mVX1wg5`M2L{p%W8%QIqHPxkZBHVw!0UnMxkG`@e`pCIN{j9 zEVJ~%D+p+kXJl?3PLtz_HO=wZA42{aPmHKvddieKLC@Yk9-Bt~81Qy!P5`eJ0-gzg zoiT&;U};x2i_9nrTXmGIOu@?!>}D~vvWfy^Q}8Mw@h3W-C*s*2hujzY3!*K{@>qdT zt8kUkef$n3)~!f4Kp1i~Rh2fYc`H2TTs~LOFzX9hBc{ zFYQMgZX{6>0SgQ2052UQc+a(E&#hi~udF0P^^#V886YJ??{z<4R!l5(w-dk*B7n=4vs~V9&>pSG>5x&i?sAwPNS}`}e%a ziwAZjIuSOOoEZQy{XE)gNnWI^gW{psHax8V2Ro`Lz*;tGF{Pb&tnV;?01SjwfZaB) zZ>GY6FaH4--i(-2Zobl1rdCqK8v8+tJP_vdAQ>!&MgR+{;}Lgm$;_@Mv!W$0Matua zB(v&iovj?zIl4r2wz_HR@SQjq;>Suj2CPCB6S^`1g4q_9q+$MgHJ84+3oU~!D6)wX z=+!PEL5J(7ZJcRZn5!1~9$JCH(cx-0OQ#ocv=teB&NW2y2@)Z%+-`g5_qubr)WF}` zOp5lJ`_`kHEk5hX-ZAx0@DZARMf!sWl!}4Jiu9kI*dq_LHeQvI9Lc@nIytxI=YCjv z)pRn6NaO>kT9=69@h@W78h6j`&#CDt8{dmz#`~AgD_31P4sOf_X+j2+(iaq7WV+ow zy?<%Kayn`f7F!n(`#!IYpGxM1J?$nSgy}B4E6jzBSq_n}I$ENkBmIRNY^HA-lo5|) zWyKtprzGW2KA6rBC)<(=YxwcDRnq4tJDR|W0bB385Ax5R(s5A71&7++N+lZCcKsSv z2NEMDoM*H{Oyr@tjrzeXT`UtrN3S8v8vaEqQ>iWqw07A?m56qj5mZB9E{n8jufCD| zc40*C(INKOA8jv+&|xqBJPyn;4-5%B%Sa)q2~6LBDOPGBU(0|6>qfJBjf{BOLTFeB ziF>F>1Yin_ z*4AScu8I>Vg}=XTqRpcr@(83@c2G>ev{Te)JEB?H(bZh&z*Xk6>alg0Zk5im|rdw!>|WmA}_9s!d?4RmB9uwqEzU~+u!xj}WL zPJrnI?(YC3ot2HvAA{oY za7#07k(vF@1UZT88Vs=h2~Y4sMpO^-K9BQy|Kb9>3ebQse91U0qlGiwaKH(qPZcQ_ks(;Z)ex*-z=2x1zSV#R)mthBFj%nD*nad^WS zNq89+G}-WNI~$%`ZV8VE;CpWGV7%X@bYE!4$a@6^NT7GRwwYIpgOu{>%d*p}7K-1!d z=1!lysgi4lqB568+iW=OR-r2Jds#|pMLOvnUxX+-x+XmGXpRoqv(677Ns4RrX_Mxp zT6h_oS8W?0nCTTD_;5Hkq9R~?zg_w0c+4@NS2^bB0M&LGT8ROEk^MezbaV!-qxqA+ zklopl$<@wfB}T(sTnUHGg;wPG%b0iY5&q?|`p-yy?hmNruwl^&Kcl-4Ji$f?zC8P( zGtT02uCTdmZR8Xb77fR^x{!^?e_bXjU_lXiNS)Gcd^~@-zLI|nPo8G%0@!9JHUH{-aQnbT2Ky}K=a=;-}1UA)|2wNy1b^}{h18b4~B&~xb( zhyhwSowXIOZjivq_F{hL3!9f}iMOZEdYvR-r@> zdhh|oj~(Y0P{DR@BLN%m53)c|kz(ib46q>~DYmywM1Rz;nUcX!=1jmuJ0w2(M*Gc} z9}4*sn|cjm{L&x{H497;;IPF(Ynq$G6R`?$G%Nx!r08ITO^Mp$zt)fDrz-yXp7Vkh z9_lOP3y=79=tZEek4Mbi04`JZ#ISKUpu&E2l=%6qKGCc z4Lsqb(*=1OKrrnE#E#iTfk~*$lxZyM8zesr|KC1mCRdk5Wt#+3iYQWCX5$zP8jR`I zN&htSagM4&jpq-Bp>dd8xXH}-+Ci{tA_*y!Pm`tZBLuVp4fV1_b=3%{8lH? z!)F6q0bnb4Ndk{A;503jLy4 zF0KM(Ani6H0{RdacP#IEj4CAg`oE~gbdK<7*|>d^i%}725*n{r_zi#Uxz_Zl{y^6? z#CmK>ry$9-Ro{N84b%!$se>TJhd>##T=)nhlW|0}kUiHInRqn?Z7I$jHE?u3%N9fz zNeL`%`)Qgt#Z9qhgGU`|l750e~ zwxg8}#2feZfpr;W&M!Q=ZW>b~)l=~^Us!+qDeB&_u7|c8SoFt|fz0%QuntWaO z@?;iH?^at#t(cv70xiiqw(`+MZpnOpJ_llS9cbi~w`6GQ!iU2fhQg0CjYb;bHI!fb zP3X7AbV##!V-PEnc1}Jxy}h)jIz|}b_f?`o>>~K^4BdgaJhozfDzM`$A|!w)JRUYP zoEM!3`&OlEhPF5EcWq#D^^?W9Uyaa(hL(FJlAGoiqHmDy3+4%fMYqqxR+L%>bl1on zb@l3|j4Rq%c>IaA$Q)F@uPr~c0BA(A8t_a*ooxpEn&+l|%U6T`tyIYlfC;XQ=_3lo3N?~#Hz-zPI_myp;**CikzfBd=}yZ;Vv3l1Nw+gZ zQ1uV^1qzeEtf0u~({Q8X)^SV9LQ^o4*XGpCKBa3mD$*?86v<6juxS0csi;YZ+(ZZg zT+3A5uX2YSz6!Xi=-@GHvwR!3}s^kVk9_ zK84Fag)zU?-3H5-@n`|X?Iqn)2mJda+!`L)b;M@q%5YL|lcYv_8At#hb$RAlh6s&*L_ z?r(P4yoTyqaeYgxQ!RD8y>tR;F@(?elKnByPV9=v=$Q$WDE+b~nr42Hde{dKBY5bO zc8BRl5!y8yli1y7!<{+&2m)+vG4v4~w4EpdF&W&v&)S?sQX$d%`dIL!{LY~!{jquV z<{%#j3N5r7G#Qc!dj=LC;GR&dkSyP`3TPT0PRFT~*!HIz9B&yfv7^lbj0Vj1fs=fc zrXhGYaCO;-IGMX97~Rtc#xXk%Prf~i``poyt@iALi!3$^O z`SG{{nK9Cs$jEM0zSjM`r#7Ym6+4IF9y{W`Eoa!-lZuT=86 z__WrBgRAGR^ZPSOnp737Cm2s~LKm5t?bl=W*DAnzy9Mwpyb95SwJ4p6k(~Q6!|k*6 z4osnflh2`^(rFE|$oIW;6Cr1@2)74TnVM_Fx`N2}TY(QfwtIo~9}QK2M-P<5SVPplXuRk%Lfg>FO>pS~As={Ev#tRlYL2vBVr zclCAM=n=gSCyUD$w~L4IVB%gPPYfw92^M1V3aVW;nWP%c0cA9aE=LwpI?a$}OjcEe zLap+Y#ng3d3e{SgUn5s)YG{B!1u2-Xo4S-oN>D|i0?#t=dY{{mHH6M z(5|;7Ox$!)A3;EJEKJ(;+WO281rRExWT=CK15YM5S`Rx~ACXD4%e`I_g9H*|VG^et z&PekV2)>@#9+!Ury)at>oCnYafaH!eH}jubCelOz@UOxxkp?2h2)L3^M&fWIJn5t# ze6fTC1mD+d*7!OOTPt_@V%PX8cfHxDKHT^%dyp3EJyI79Wndr~!u7Ni0vIaJj_G4hMID@n)So?5I#lCDMS978{0@y$J}V zU=Th$&ng4LE-Wl8ARr(j($Ulup&fD5tGx1sJsJRBzy$S!fZNVOv&-Gxoj4ZAz()8R z?F3`jtn0t?dyu|F>L!wmNHJT54f=R)5r!2k_ESiPRsyNt>C+?=Y>V&JF(AQRJ6KsU z3L8{S15Id-(=>X36o9He#q0yW3*GwxSw{Wo^#<^jl8kQpsj53(}jcM5Y&yL!zDP1$JreGPTZFp6jT|f*CDz1$xPzU0TS8u^lFWQ zm_#zKSr21zh=2K9=c2OXV^S0+EX0Y(b5?>Bkr;xcjGmzOE;C|bq z^CADR{m8wc$*+TWIn4?hXNMNXlc`Yd3c2j^OyGpagrse2bTGsP{8?Jw9B7zc z(&!47I>jrG$x}YXAjb>>KJi+XB}d& zE)oMe6i#Jq>~jKM)GkGx2Fk|t>#f(v4==)0q2qhdLg%xc$r1mH2|NJ~4wX{1F`A*4 zvup`qIy^Bk0e)}Y3WAMOm*TNjkHeASVKOka@9D{xGg@_lmoc~wsugXfWGubbMf-Xk z&o&p7{hb}yK#ekWrewZNI5;?Qtnytv>x>N`Ez{E4Dqr{` zbItc{wzGaJma+B}xC9R?c-Ns;bt%wExI4$>6m#>#5n||5Rp{&Q^lua)P@AuPL(kwLPqm()a4Wn(FEbfr@o$T%SkQ_g?v5p!Z`I30DGh>P!REpQs)Q)pss^iq zId>o^%2o~+_HpfXWt@q@p4qa%>7V>ja+cqXswM?X@ zT?KAfOJ(MOsnDnk>66wPJD>JU7r~aDoZI|kzH!B+&o$w%9XX`~if*@W4m(2Nij!+& z0Gao}z4ij%;5Uv0-=@}?RX_LM(1-$a<4gy~&!IG1`4L;8mWQLSY!9b5%NpN3$nW>y zAm1E67HCLR{gh@cPc}@X(Mr(SWoOr`Y#`hcEgN?zN@4ug+!+&aKkh?q$?@~f@t6bB z#9XA4Lcz1_JsEt~{H+%gm6>lytwNo$#7H-j$OMgx!=v;5z24yg+dZd9zzy!Q5d7w!$XF1WiUS8g483377JWbo>KiJ^ZSlP^V|DI? zM^O-t@u{1lj@^kl|5Q6TdhxmkXk0^nNOyd;(0x#<$AMt=)8&8Ge)<8=8>s5g&_~l? zAico|Gk(%bnk@0HL|<21o83D`(_qoo3=cs$&>X}FF$M-?5KNR|1)d3<1%%;cz{adK z%|)4$*y;qBZ!{C2tTI~7q$Xfav7%x$^ zx8n&&(_sI1Q?>s9DD^)|zi+MD+_%BG+H2#sQr30~QP5l1R=8KVw zgIL}MUHXRiO?e1!8SGT~?P#K+q-e>5v2cX*aO(9-gqXe|pkVkB@hpa&X8V<*ta)z0EcTy`At#bO1!*_Oe;KvK+T zadh?3 z(NW`)w@n#LUOh(7XD#OI4kdU5JEHJ2?{7PDZS2LQWEQIR}5B;UMq(r&CWg z*nO`lALPM=wI6PVh=0;G@=eB;jy@aC;nJk zzEDQAgBOEH8O~@+$8bnQ%r`nHDJjV_vJ8I2;a37?3q&SBxD_xReu!a=B_bda5e~11 zwFY!p7W|I>S!zem5JLUy^z;;9s&9Puxxs8x!u^AC7l3WSFba53zR6#|A%Qc*5_8-= z8zg)<+6i0tFmGCefxLvk?RziOlmmSp(B+e3EG{kvRt1dZ&SxSenoo9U0*v zj$wsBy4>3vA9#HBc{`JiuJ=U^bgEdX8s{&tAuUjsvv~z?S?Bfasl+-#W4RA+z{3cIKSm!VTnHs3chdUo>`cGe zxtFN6t&KSpxKywv{CfT<1z%;*jsgLV0v%hOpl`B(c<_S=&^z`K*HN-wn9jMkALcx4 z-@O*~GTT^8?3X9!)v-pfX6ie8J{kmW z_$fQQ6c+d`fKU9vVyl`bP_L&7J-jg@LKF{-cyl9u);qdD>VJ-HfCb&5==85bxRlN5 zwAt*+uBO_a@1OEvXlu=2W_#JaBQP48Qsms3ZvFF(^OJfrlp3=aKy(Sfd%CQtFk+1L zH8m1J+W>HuQmH#h`1S2iZ2L1f4RK2|jF=EkEJXJiLX4z#x{#Vh$yLJT=h1PZ32$gwFZrm;HlBS?mMRlrluc21)s?RIxgDQ0%^5=cH>6+8co|;+C&2#o$B6YA4^{ZBU zc2??OCBYteE;QJg=5n8^Z6ViLz+#umq6G)KH;L>`{zd_nU>*Odc-PHaLr53DQsQGX zHbRRv6*cS&=;q`z?9?I7S*A4nqVV6$To(A%e!Y04+0lMerRg8~iX8)yO7pS60>l#_ zKkNZWAD|1pjw1ZlQb`jFo?a;%47|bzT7VwH*GSx6+!b+!N#>(gqbGUj== z71X$Z``tiGuG}EK)#lA?!2N*8$jAUJ$~i1sk{y!ke+&eX0ar)jQNQ z@?rBAv1{hFrAf~EgaYz108Ef^e3fM2Io8549sOc^R*!_;Fc8Lit8@$(D@JB*szUd) zL)mpnar{Q2PYcYnP40Bw*sZPRq&z3kgrQ&(9MU2#P-hnk4-d*l5e^D~8LB*fH~v#2 z{O>a?!!`4O7eK?7^*^a&>-sSzE2mTW+VUGBTW(&2Jo!A&heKNgu}uJp-{qnWRdw)S#1%pOj?R z^DzBNl$oN$?9^3^lHQ7`&n2eF){B*VS4ZwPq&G|r{TjOud`&;J4-IYi9Hb8&jBH34 z{5gLgYvE_Uk#%^x**eU-j15?FDd9%By8_i(Xb?u)jH1;W5eXzNg&sG3y=iG^Bo?gx zbTjU;5F61TI~rOK5Hk#K#+PFZSo*e((eek*CkV-Ju6N8$IG!CLs>q5LUZyk> zNAqz`vr2{u*dhS-%d=$Y`24&)GXW}r|1;#$Vu?Jgw6M$sVojLWOv!-!R-wlV{sFsD zkObPuoWLe!w}l1=87ERI7i5&&qz=W>G2>HH1Vi~WZqCk}h63dcpZH^Yy1K*^a;yQ# ztR}$F5Yq2teLc~%qs5dAQeI$D1X`5?rZ|DNJo2omChqP8e_4seCw>0P5JEqS;Z3(MAU6UZ6Yv=@BZ+R(`EY;pxNrja?Fa-3o}t3NiekyP7*3~KD(8pG zqd@hM+6(xI;lDN1CICXDujoQ5cZWtsj5FwB*W#gtuJ)j0x)c9hrOWhO`QC#&jKSGq$U`wJF1ekt5G zQ}7!m_V$lbre@kifM01vJZsxveiXX~nUIAh{r1(5RQXj&u;pc7NJ!cbCRZT<;sgf- zniEGrzLzW72S69$9k1wcXWuXrge-%sU=_q$p@-X((~FDgP?RDoZeL2t#N|L34wa7hKY<8gs#LeF^yi10lX-dRP9>+UmmSJuh zaJhPRetrxrJP>g5J#i(}riu~Axnewp$US3S1%Rtvff^ISN{QI3`YO~{p54&B!Xz+U z8`Vp_?J5AFBaOD3`5csL;2jB&31H9x%NPes_vy_~u79ZEx4Q463fo*C{+{}zXjY`#IBOeJ?q5!W|vj8ly;+F3|Dfv75syNo=7bo!MV(O?^V{ z83?L~=c=4)3+hUkqPOff=ljpnUrhy8Zt$YPO}p8s%gv%o>o(XL0X7p@0l*PgRIqS< zM=$G(k%h@+5K2i(G_ID-QwDAu?^tvj;H}9zM1|g(X+N$`2`BEZuJB#qa{3e)r+8aN zk&(T|L`H`=2Dx_gfc6yfx>zw`*c`51v*eR>>7P3p6|=M;Z;y&!CBXBma@Tgg0e!xK z1X3!x6k$8xQThTYPSau2Rli^P;Ki-T$CB38%=>$PnU^o&2tO^opU7?e1T{JY&n&p- zA++xYz|99%@4~XOveL5l$#1;ruViA!qpLpOz4inTYy9B)m|J^kN2P9KEVu!r!lJrA zueOtUkRc)(ZvQBBb#(=gbF_T-TG5@VYz}q6m%uQ3Y8OU!S!`Ar^xb$?@Zv%dmQTD4bE~ zpza~rd3c3iT58>n_9uQt{n}5HQ^de_xGu!MF?Mlrt1@9HP7I>DozUceFlU=SSg0kP z41&dxrx23o#~&CwAE0Er`AhTM9Vn#uyjv}bdCHXU2iUo|q&U+HT3ZE)8p)FY#Z2(9 ztq16!l589&B2v#1U3J`ShU|I$wknsx@r@h{`+{5`0y z=#uQ=YIXW~R=3F7Fwcq{BOr;@!y$nq0IrwI##?nuu_8IdBCz zYtU7qMT(p7c9hPz2U79fj)lJ^fdlX9a8B^dJED4y;?v^ouhTI{Wm~*+rQ9V2v;1Qc z19&MhYmHg@I?$LI8R|65i6c4nPhy<#>?;Eh)aRTTWV8t`(m|d;EFL_&YPioP`(K~5 z%o%xlrU6bfxQ}N#{Cs-!h6{E!qihv4&xIRhbAPw5;-G_k21Jc(S z5Z(q;*>XB3F@Rkgcs3r}#$Zhjamo)?T^HYFMAH!XU=AWj(AS||>$iaVSz|hY!>ZTR zHSnH3b83#e%zey_Y_O*3V#!Cl-dcV563VjaR^J0`g|yqfxdCrHHVMt_{f^bi#<1;T z3;tk@wU|}2^;>}Lz8tZccQ>sMX%QjaVjSzi`B^iG@jY)LI_ERj{TnqwE|<08$_h*& z-G;etr>sn_`{$Ure)FBS@}*VI4nKQ6WLO}6TH!a>6BIr+ZT5?)kl?LhG-gb9IB z94V&6N^mr;)^fa|$ako$t|yj^al|)qwTv;depkbA-kWYh<5F3%sVo;k)-rS#MoeRG&U| zzpCG&d&jRjlL8}=E3bW3#0($VQQ=zU9rHjQkg62h2IbF*EVs67)OCF?J-$P0)Qg3~ z)sBN84a}`y#TaLQYK=^88x5H$VD4U(&~N{drd}EsPa) zT{ejf<#`s05E#vM;Q7Ay0kTU%)yQwm^r-gvH&8EqMYf?a&^gfu+ka-X>ah^{4=Arb z>c`W6Le_i~o{;&AtQjwTG5KFph@gD_2h5uV3^jV626m>qj4X{*lG)a{Q+6wcR1keb z7yKmgDVL`Z$rDKyp9)VMNrlQ%da_Z3`m8Vx-&z{GL;_zu7`!IkE+uXa{|km*3YqGQ zT$Dae@IK!_^@Ts{&$qQMzV5XcG>SHMi3u{TKIR=)7Wd6r0ryXJ_ZC|f{cjjp4sfM z5=uy6cd7 zE}J7N%mn$!6iN;l``bFuA{Yne)l~hKsKD`0bJ7WYQV(J`;-B|3bspa=}SunkhuhW5RP9LS#ff31es}r zvjX;fT*H>0;A{aWE*Xl@!%jp_-q&CU@+T|asU%hB^F3|bd0-j^PJvpPZQENBuqDBT z0Rr8CS2rG84)7h2l?*~@+Fk;un9$z8t;M(BmoX>x z^N#sO~#f-H+E>-T({m={LDnPq378- zxx9^diQZpNOgLj-{`AS(+<0{}d;3H`_oCw7ZFz_Imtn*=hpXlxRTqx6-P1noMoWxE z`t(Oc9ueDz0uF*TDwzGa8857;TG&5yl4-v%kQJ&uyg}FbNtHbnTmE!9*njKBAFsZ& z2;nQL-OH&{Khfg{%drz6VjZElZn%VWA%r>Y22QKcSpRTm#(EfCUkIFzYb$H+?B&$l zkKoj(53DE}M4BUtgm+`T`C+?c(xg9JqzG49SnGAr)0VX!I%gx_(Y5m*M$I10N_mRt zF(rS5YNg=g7i>lyAn&iZlfIpI==@M<+|Noko5p6qaYGAd6arN4;kia*G!*yMn4~Q% z=;eFK(=*H`hY)xiM*M8fUAcQqEj&CM>Wq6)0QmGVKhi;o**7Rt@vv0PQy7cgH^l;;`(uO)llr-A9zj{!g&$Ri5`eZXeZ8}A^N?K{Y(WHB zYDSS9F!!9bHl4Mt#?2R}A8rem)gupmDlj!LS>MshQf=OXC>Tmw%~@bz zD7QXx0u=Pzc18wSD0 z!YYz{-~X(#7bIu~UhDXPs|T!^ey!MJOh(0I$e2wD!tF|Z0 zbCcG*^EOG0@fAl-Z*jJgO*Q|c)8=1jw~A8Tcb|$`;Eak?hzFV;snHRhfBdi#9gU8A z>O>z_8zH0*^MhEIDpe@R8v3s}{W0<%YX~5>0%r&+K)5Fuby@P$8DzjH&e|G<3Vw4m zXLF+THH)^SgdYc{k1h(vtqB`_tRHOG!Ys%Ai)(VIc&-?N5$5w97rx4N)zYs3h$hM2 zpRIi>k>@zz*p^}od{RMCk3I^TVp4^wR^8zodlJ%xYKDg-Y`bAZ2)^f|nx%NG;oqYe zOIDlkRu(;$&CJb<#KrQIS1KBptoh-q@O@6V#=rfZ0M4I|mw#3fw6q;^4Icy@99I{n zRYDL}QbRTS@R2G!OJwQjJII!vA(=YcM z$8`p|MbOsUr?olX0pWu_K`gZP=c9vPv*!`DM8r4ybD=oU@YsSH348$28d%{%8Nt#} zOi$LLr1&G?6I_o~(#`!7mfzko`jwICqnp49+6cfJAb_MhR%i^WF@+_q3a^8w_Iviz z1GT6i?)I5>MyaVUio|%&MMTpSdCF5}W0~~_Q;iD5)u^=PjOTdpEa>}8j2|D2KAHzB?(Ds0g7I9wVA;fajD`mAze^)1B)Ff+9b zM99OYxP)QwJY?(KJoLGbfQ3#%7$tBWSA615?kxO6Eb|OlE*_yA5#KaQB;dsGj`bbz z+sVE;?CdmKuPPcz-Fxe?HzV%h;UQUM%QFbjc-^@kD8iQA)%nYujTBv<@n$?jGlAyK z?wq_G#0sM!%(A8hx7{hDdH0ZLHKtxrSrEqixVhQ?(SZevpZosYt|?02;AVKYX_ONq|XcgYYF0oQDG}WutMtpbR;(2hYb2wu((VTHs?H z?<+#_0a~tITU5BvJ8_kG_ZeeUV?n3(Me|_=>j{S7(9c9cF z6=@)eRdM|Sz*8tg4FSnGk6zbH2wWEQL0LUqFt+vxQ2|#)o-}_arLYJ>Y%Fg~e6)r7 zgrJviKAKDl%ToQB@Fjqwrf_=R3_^B=ZX*~WCQNEg6JXn_SA%j036WmC&0M8K+EJ{b z)cb^>;wmhCvBHyt1s^1Vz(joQFKnQA@JYRl^|=R!TZ+@Nqn>W%F6)A_@LO2!WfTO4 zFg12=LIW#y6(X4}7((iyd@`GN39UpL4bC5~J4P24^pa*z+O{yHdn%qv&qV!M4?i}l z+;RCmNR9FbSn?ToUKXltWl-7P8vkYu=U&tFKBaQL9UVMtj@$H-Wz7HLxBT)dZJMnxd_+d8gCZA|VhU`09pr>vs9ApD;7*g6*+Wql2Yw#Ug#ubs1Zb9Rt z0o~u^?f;`=02g@IzbfVRA9D8pb_)1!r-1)<3ixlQfd79v1q8HHec=Wp0__!$Ka37LbDkiCj_CC4yzjSb`~4ss8QD?cFsf%coK(VV4|^F?`b zdLg>oORtULI~L61>4luER>3AegaChFHFb=CS+r-?MN0xtO@)nO(%>wY29p|Wo4tdq zr_I1#wrx*sB!h!(Dp@1Tc7%2w5T}8F&qJw4glPZ8(G2M_FcW>JH;5CKl@h%u_lGT_ zB%vo{>hm^?mL4|#1VUgnx-HR0us{i`n;`5nN-n0{k3=!!3^63OaIdDCGoE6<3hi@T zBvEiu9}OxaP@aR!+B(yD;;lScoMf{Xk zMi`0OV@ta{7`%{i{3ho=n%9^O5`xyLuv$+URI8 z7kE9GfTq)+4;{^Cy_-4C2YMlt;nX_j6kc?S+*UC$oFev5iNj=Y^)Ndw_e$;prfgua zXc48Qkw3v>`{D(g;w`Nq=)qHT^T!&nV(Y_V8{_!C;v+mlKK|Gh=A0)Y=D(mLj|WFk z4il32v@k=R9lkt_Ib1- zS)O=*W1>Yw50-;Qtl*wT$sUlxb;z`ryehYtHhb`2N0> zVIXxEO@y?v{_w)?DxN^lfkGtUWt2pOM09XeeA_btrLD6+?Z=DD{>|7yq)363tqv5G z`w0cUOp?I`D<)n2vI(1bmA(jq`@{J>du@J~&Z$YESV{4C2~v*a6tL|=^rM3#nMziCQc|CL#LjM(U3A=Bof_K2=dCh*s9f>;f{)-esahY-%-Er8 zwx8qjav$vK>L%xv#WU`aXtmj$V3%-f!~y zDloa0Dv%lX&$D3?7!PMfz1^r@#k7A27~p3G2O#n5H;uq6&3JzuSj?%#h`%K3^QVUK5~6)ePM>tix3uvo*+LCk9`e~wQafG^Ib)S#HZydoMmRkYOBK+%XK-!26s-n zwyx}wge5sSr$x4S)|4_-Mc=MFAIAMTE)s^WGBLPVm2MXm_F`TlvJaPvRf*Dkg_dyv@LgQfo7?cVN-aS=PGTky-LOzYtk~kMj4x{xwD1 zim9%(qgn_p*pyQ`nS%TXE0fl2z$bK=&r=X>o=#PzGTwcCDd>s2Z9 z9}0I*GEv_wF~n+1dOiJa@{)`Qu`dwY@biNYM%$Am*w(T7w6#V`$o?+Z?k7QJghy`EgB8R% zykh%!OVvdY^c9X_=_L+cH>#E`h66d$h&Zd@5y#@NWLzBI;1L?_r2K{Nj>m-T9d27I zO|JL+6RATlggsbkht#&t`_26&`SB29*+4YM!0q+`)HYZHNLA4O63pbo`!fu;8ETSZ z$J)WuoE!^B^I+Kl!`-D8PiG&ui!wHi@5B885ORo8Aa8r+v%&+EQ*E7U`wkR}UlKU()by3j3iIP7###|-zR&@(sO7QhwN zGIccW+LaF}-@f&A<+M=@D6=D}P`sFYR(o@OMA=4G`vI}UFgLe9-(QmR~T-@Zdr#7OJlvgG=Z6Zgs-j$YL6rC-I! z$Y6j`4{qwyn=7}XfSRosQVLlTtFh@9;H1 z^uKeq^zGu-8?zMXbU5|oIbAhacxk>FuO9f;c4+K&7F}k8EuN$;oNAEEia4=2oNJ0p z_w@+P)wg$52ex?gnM#4FT|6}$JzYu;?6=zp$MKY?1Nve+T+OI*Yk~I~^XYsPUiWV9 zj$Wdb1CqyT@98oYw14mwJj^83%84BN?vKb^d{*~+QCGQSxc3Vo+2#jVZh}?K4E;Ob ztTQ6g9Cx0Pm)XKiwd0F(p3|`g?cz48!Iq&-L-Ctb=|6wV=^u8@M9x)`X(7PRT-ikX zJIMW}`h@)}F>oU6v@m7psVd=nI_$d&+@nkj%wf@~dsjlOCkEIodTTSk62GyC_x!?9 z*kF#CNThFQaC-G{>3X}dEqP+QANPbuyGdsEMxGjzBc`P~{e`fNEUx?p^>u&IT1-Aq zyKBt&XsQ~y@z40L-co(fVqlHSs;97|!|#t2+m252yslT`hgtPaex1-J*yxcb(!r$v zj==#jq z-YCg@#{*v5dUwVtFp?Q1E&J}Eb;`F5t1v_UM3Qgw#5Vu;z&m}|Wy#(68RBy8 z%MPWRh2-kV<-1>9eHH|+1?ib&-t?6mh$hb#@|yNtH2dz4=jXfwX|i{QMlfpr#E>%5 zj`BYD4+u!5IhK7UnXPS$)`91^@#2Ey8w{#!&HE3tO5sheML~&)o4WXo6t0oDG4dug zYPh<8e1rHN(r?a;G8+VIYwvt-TpJu5D%>I!?l4^xap_m&SN5d)jYt&TShMym?CDHe z%V*|-G6R;RNZwT=lJtL#?9(C=_4~RrFtV3Uhe}a=II-&!rTk>ZvdSQh&&_bxoOZbU zr#s(TwQg`N4vB`8#`~{S31Kvd%TFq<+n4C4p3tadyV2ohskq8JGJMIUK@t8nMvq}b za+w=PR_&kdrh_c=++7~YFARq^`*8Kf-!53d-sN|RLe2X%Y$!6U%D8$i&1KMA3eQj( z6Eq^!yNZ0CK>=J2jpr>0S}aGVgrg@%A&^nH3M!;rhtn?az%E>x$hYUTHGwEW<2d`M z5^r$44bekkN?0KVhtHWxfaZd-s;Wk=P>?DPBfKg!6e3#U;c*kOPe7xQCv_KjY$i58j06z|^z86Y0@m_4Wq-V#lAov|7nCUD6qJ*! zTPeSFP7xC>f}v!%kZJfNfh4D{ev@B@vI}<}fTrxaYsvHH6BUJ0^4(f=`_puYB=@O7gu#1x)2b~f0~9_P>r7Zx@n!c@d>bRQybfMI0NbNz?7zMc|Gir8?W0;RBF!W# z+a3J>XPzUlYP(y1S&nS(Z-=y@BMLD;v3otyn|dGD$|X3dGG;Ow{lK+w%y_?V;pq9zWPJudV{O9={MJw!tKcY0I&v|KR%lZ0>E zo?!P0xLCJfd+{$`G-V@uGge~YBX)u{zmY^eY7s-14S!Z4;7(~n|dP?oI9 zZbOd$-5o7VEbZvWVvDGlco@!f#J_0qEG=gJ;XhcqygD5|Lw{A7`dt*^`xCFftkLA| zPaZmjYpo@Ve=I&nL@$5Aw%mCrTA2MVQ}=i^>*3*n;=ZZs{6chnl!SuZe)CP6#PQo8 zc#?V8)c(W6!_?dJd;iX6jk||{_P0OG{Jo%@S&M56uend|WpcOw&g4Ythi&l-0PV4Y z?O*MT{14aA2JW$g-vr|?M8(QE=l@3i7!~-cq2j>&SoDAVCI2(hb9k=O zTCS4LW=5`74)&C4R(56(E;e2^cCKkR3h+3={3H7tPEoM_B8Jx=AV(4wyz(+(OM(!F zumM$be~#4|qBQp06ZQz+pc~f{fw!`Sm36_Yn?T$I8^zu7NAIgVIR#^e3NLncibLME zfMfF|%j``j>)jZ0L}i2>G4gNWO$R|N>`zke6eTT-337uSV5dK+2fo9);9Ys@sb=SW zPa)o?h5z)D%n=n2=Gj+G2uW^vpKeZIx1r<2AyAT=%ey-A^u=2S&T1!a1%V_-ob3Xz zRYc}L;WWD5D~Xj&qS)W}(7l(lj88FBDVwCe0*Vj6PrlVLrWXxl{1W~Qw*=?^lu}c~ zhpbYBfsrmJ9Pc}|%l&gZ_d7)s*KgIl8E$IR%C9sYZZ2_j{|vsYEL0Jrmd_7-l~~V} z6(oG@PiUR>y4n8^R#}Jg&=S2E61ERM3KjJHjkE*D883*;I*;WaU<640mlV$ z@p?$|stTbr_-+3N+B=HqqwN8{OWk1mSE0SXZbEYh6E_!$|D&E}peBuX@t0hA?dh=> zTag%c1Lg_a1s_vgo%Zjgxl$*;U7zlZA}@K7%PFp@S50)6U*jUD$J5pg=Q*m4kG}Q> z*AO81j@o1|KV+u1Ty0=jk+1T{dB*C7Zkg>8kJ=S|L=}LcShB*2ByU;Hc zPLI&tx$l@48`EahS&VunPHVr;V}4$2s6WxWNw)YCKAh&#w~Ehn)hfFDF2c6%BHGrM z`!Mdd52?SSG){mpB6)j`&TeJ_%PZ^o@bt>5MW$Zr=)<|fLV3RZSK%JF;o#!$wa0AU zwLl9l8IkHc|q-mjrD8 zLUgjVdJOBfX6CM}u8-Y^e~V5eh`;|1@BO#vWHG<`Sp5DC-uoY;6aN1iaX9(eUa+xq z&tpYS|L4LNg5y7!mMQwS@70L{bAB$@>rPjin5db)`p7_i&#o6t6P&QM@Nw(b$iOa2 zRr`mWc}?>c5|vCH2lnYt6ry&HzOP>mjepA=bgd*^zAzNvdd=ugR@c*DBY)%9|E^)i zZJ%eSf_}S~zj)MZ=}@>+0y^+uW+a_-@M#fcG(fMs-}ve_#`AUpChfjZwh@NFtve;8 zSF84F>%jCl4ow<4%7{x!E3)|c8 zLU8uv{W~8*Tm|$S8ntSy4VAX;S!}%aB9oaN%KHq*g6PDNCI+1_0=%Q{Zag}f){nYj zr%>jN$>J6UdoZiI*FVWrO~dGftK*W2+@jx{qYKfmH&wB(92^|n4`=fJ{P9D=&W@#7 zoh_6y`H}Z91SEgj+uK`FaVHlS$qbNok36NC4J3mmkbPJWeD6dmJM#!8nfYEgf!T;H zc-3Sgx8Uz)@8X9A4NN^{YN9{0G`LvMKi8Ogf&V(47!@uTH(d`-P4kVs$=cc>tY#u@ zXo+L%;+?*}J{LDPO#CZ4i(zARb$oiotTgUspn{`@;ZwhKYs&8&S;H%Ewd+jGf~*Rc zuCFctBY3^5%^aGeIW4ZRLzD4=Kh=|Mw=AmJDhby0N^e%=CNBO{-xsQUvPxMO^0O7O=+$ zL0GVUb_mu*I&zaf`p54 zM%(k@muoKaFt!7Dd_zc7ufTUMuR88tgyZh+O5BCG8xe@RySux) z65>P&5#q$%jkvqJyA$C%Jo;}vkM7ssteKvyRj_iCd(OF)s$IKw{RAB;Z12_*4-pX& zL`AoPQyJ+|uO-cx(689dW{LChuoT`)BG`!L&}R2-RiKYo4I(k3C8Ep?qo|>-tDz-c zhAGHT4o;;y{iJO@eDwk!6Mlr4qgD~?P_b*Xj$e}Xf-d-bGSrvNM>DfMUO=3Q zmyc+yg}~Uh5TJLVoE#r(uS`v`DMD%0aVF58(?vRJA$zx%9-Vk>h`oAusra6r_w?#v zwt0o%$5FW&dwM7P9#I?0cYGhmNWuKKu%rbT;vU5Ap8EPito_YQZkf-QZU{!oe6yVaM1?oQC&U^prmChw4+=9{drQ$Dy*2y&@d=|6=HXupPfS_f{?XrSJH zgE^AN9RSoukQ6Cz;H{2gh?8LEC!W{wg0t+*n^zAXSI$qa`H@5IR+crD z+`)9=I=1g6Ta3i72YpANh?FsQK+dhTw6t<-Yio1WI{?~-EFuz;ug1O#Mn3L+9l#4) zUR=~v3d|%TAh-rtB8evqbx*@W2@^okW$U74eF*`^{uH>mbH%C z-{Oq|gx2#4EIyH~;sat>vZI}CSTGPsMa7=LM=ol$1R>}^>&PktH#atQLW6m)5fjo2 zGY!Jn0kvO!VwsExB1~gajDjJuUrlUF&Sueg&(6AMME|H1<^FCVRY&Ock1PYrWLU5S z#X$`grs+rIw+|P0h>=REzfVQ%;iMqWAwfWnfc6(QV!u`#7yJLd-W)+<{FyL=dy(e1u_v|s4HaIX zUs)x_n3#kKIZwR99$-!CEfA4h$#qQ-$1KumNFRsFvxMWyhml?$RPT%~BMtRnJIkWq z9TDm%Afh^mk3HRAc}zQN+A`foB!%F1Bd@N^{2TdM$Tp#c?HRMj&>=dxQ7`Ut(IJFcOe0^f zoK;*IqOpE$X#8p)d2!*pDP}$0c4mp2x|ESE*nNB~7lD2uEg_~ENCGHS?cov-yh1u} z39o69rh*9^!A>0^7I~BPxB?l44-a3M>T@K&wS^6E|9YeRAd;H`-Z1SucP{rmJ>jnU zdWDO1ebTJ;etFPg)O#U3*9a=IJ99SyD9RoHf)}MI1JTk3&UPIKtP5=pw=Z5*+avz;rlP3EtP^A^S$m z*#DhMS;cT8K=uQ)Li98nMLx+RpBt(8;6Z1V69@e0Jl5)me4#LwEhv$GQ&9z1f0!~86YZpX}b#iM|)jE3}yCD@RfH&nXo(;^(X z-44#jd+zn?pzAo<%-zg8Gjo~8dm7^QsX~f_4HwUvJa5e@fwLCD?)_;Cq3;2+fVl`D z(QB{crZ%?Yn8D=$mP5F2`{7_EE*AbJn47;_GhIfnBn*IO0=}K z2>|%`b|vs0vxZyU^hKkYsi~kn52EpjS5u(uWm}YdYHvJ!SO<^@7K*IDXyhdu9Y2!0uVpz zVurYHXD&Aqqv{VmkJ-!-qm}fAD5Wh&?V*kj0XM)hf*{W|3ezQDIqfrIpoJ+72>|?SH=9mnVC!Z%RG|Tr5YDFCPT=t*lBle#*BEvS{E~};18L2-0#JHD zjUeVilKi}DF;%hzzRnaU_3L3l7px7Z!j#UM(iikaf=hsa=ab-zO-Ak|huJ9{{syyts#-C@40%WIRfpf*zGH7DbX zNJsS*DK9P8LvqB=k3)3Dn%Y`gM;UGS*bBge2-3msTHkbuSn{MtV$sJldN4zfrW5gp^UG| ziC-CM6e<%q(fKAjw=qliSKe|*u9F2y0Tb05|@%;zZ{E+Tu^dgHJ zK|i+=V~QL=p`Hi`2ndSZLJ1`W+^=IoLPF939nO>(7CkUR|IFrQMV&i15*zHJuKuvvE% zcf}cV6JsUzA7;l~6#)tIJwVgQ*up}pv=$9Q*bT=hPq$)dc{u|ks`tve3`Q)Ew~kw$ z&+l@3?{cKx<-w|vVyFbas-=naW~T1xB8Os)q4e8A^_Qkk(Hi-nLsT)TLFa$~hyv?L5)sLeLdwL_9v(73 zDXJwinO<2`Bc@7#+S#^aBW;db06Rh1?VaBHianxlWzBNik6uTPk8M zZH)D&;{v)ruuE zw2j)MF`7aw4u(fml(MO}}$z5UOMQ&GIj5QnvtqjWzzDX4V_TT`0ldPW__kax;U>F4`&H{o#OI>P1#5%Y#(Xny+RL1PS%!Bbz+Em?PS*C?Ln_C7j*%1s)5Xs?OJN^Hni1VxG>N zIL*xSw5~uW#!LG6UF8*( zfj~>%7+XXHx|Se|1KNxnTwR@GJ_aE8YQ+${_0`9lmn^UrtL(Mr8@pqlRz_Rek!KZy zMw5N1LIpB&27i)V7%+p@8Pd#w@i}x4yYs&9#}2xJdv;TG3gc8Z%|8?G-;@gL$_|^2 z0HCNY(Eb8q;cxNP$;QCi`oBe4U5HPA=EWTi+!p?iC|l-YqWkZOvf!0}i?VZ_R!gP? zeHRsaLyDHX?{YUb(X^fMg03g8-$#K9m>w&xaooPy#_&cqP7%^T;=XH$`qXNXlMx90 z4w2{+ceL=uJ`U!@M>I0tTPvwEq)MIU6Z6jqF(SSs5Eb|5=Pe>4(lq%ESw|1kQix+< z)Q3%Ns*EYbfd5$q23&|%)*fNKW?7KL=L<3E2ex&vc*RI%+Sjh{b%L0PJJjgTdl}q) z5ZVbl&g60)D;OjA^o=K6bm&rsb}uh44L`}JUh$pP%ve4H)_AgciJ%?Z;28bS*w2hx zA5J+xiVs!Q5%w#TAJNj}!vzXS(Ig!;4LT5*Xv}hay+_i;=vrKzpH~{w%<_CFE?J)2 zJKQNL_nf_)?(54!+w5j6YKgC@JdzbabCnx`QlmC z>5u)ww1P(4rQ41xzMaRmLuZ~X!1ZOvBMZ<})&IE5lY{sP>gvcXg$U^uiEqZ+q2S{Q z+szSin`PaY@>OrzBJcV1N`4r4YPKWnp20`czPb|?ATYL_sqtiv-UCi|n;yEoz-v?N zYzdsq1yL(Z1u`|+AXt{Qi>5`&lg>I+2%=Cypn&cl0u*=`v)G)AbUt9QGQ$xNvN81) z#46qCPOWAYF^03%f9mSJUY5YlHQ)9-rW`j>qtlm2C@Uq#4ZyW;5un;7zDVjesg|r5 z85%atKN~iQJ;IWx(PP=+g#r@XKwjLuV(R9W;@Zrw%Z3nSSm}=b4bdicb8=+$gpbPC ze@%@~kZ1EkF3#Q8Ie1Mi;~uni$%C5lU1RVSHCEJu-0+aBt@&H*X1%v5=7Nahh(8I@ zijle%{eTn^AX)C)4oLC+)V6>jWkvuOBG%00rMxN#K=1PN&O5n>CK^Kb}710Ou`15n(9l=z$oxKpASTJmSJp^$B!%MDno z=2%23A8x+Jfh6`V*Yh{}WM*x^0pUblIwYiD_?d4-oPxdp)ZejB?<>j00?@ftglXR<=?<`$8Vv zzv=l9L{j|{mf%2hU?xbo3s5#h9mb8pp#DQ6SBJcMUXsY zK~I8F%@3~wCrA+vShuVMumDB#=(K&On)TTcvT9C#(?}>9V0DnB=ZYmo^&w!OY&gp0 z++lP=`#EsX%3cF%k&cZSrqv5#Rxtn@o{~5i18mM*I%{KQ6-g^jr_R@L!Sndi(k|?S znSG3eZ-)+cD~(%P0*In?q9Tsbml;dI=LY2PhNo7OAu~d85LVa*A!|$Co?WIyMYR|a z1Zc^sB^U%TdtCd-rnfE=>5eJfh_4hd^08&|(Uz8$0Of(*T}ptt+Ntl)5=tEj@_{s6 z(okD%3-eX)!jf{fZLW68jh^pTGjILDO^3_t5AK0O8gUiVTantPez=X=&lV(rFn|wf zaABedjd;GIfss)Vpz`(JHW08h^;^#2@>o%Ol{LAJ)9`2yy5v5%5(Y1ZnqeXTDm-Bh zU3=6MaPVUz4St05G~0q4`DSvP5h*Jkc4oC~MtUqUmUdLKT`|P4RjDt>tf&+v;NLZ9y<@RQ+00MV zNtj=pEJA&fEUQ!sYg1y$B%Lz-c=+mTT57>m@GR`xZeIg^SNE&5v&Wa)R*x%)ab6A% zS0lg~5-^2gfg%OqOCY7SFr+YnfK+`i;7|!jB>_7+v(j2ljRch3yT&`e*7&vhFdwhx zZ^qi%GzxIR{v?|-@^4L0bi$wp=9OSI$q=OOt8j8AV)SP9 z-w*6vvz*q5HLYS;plD3!C22xXz(_aY&rA^(qDA|h4jlRU?%GkYg7sgqgUjFq)2}LV zN!Tq^uIv_eFL=a405XF#6w)*`vw%EembU<)=Zg#whvVbpZ^B?m$9dY$HPk-mcf1a@ zmc7{Nx4X1u=?}q%Jj)!u=zU}MtqDxdil9s$`C#7mW@_V@?+us%J8f!d)A`Z^zEd(5ArASDJ(_(e*UWZIYcK1jPw=HFV1m~y$23J zw`^#Fx&W+$Vp1GLmu6WV217>(3I-e`uz@=`Jv9Z+7Cyg;E3eQ1jCX;rUdZVd-u73C zLQ>;!NViyAUI(m={9fF^f6&O-_S)xfA8#ftrwzGju0+dJtpswjO|?7GHeV&niDW46 zkOw3IQmh(QCq7fpfbc7z|4If(ZXL~idamULzTiu(4a=r|vr{1hX4jkEk91!3`s(68 z_+!i7ZgJJP;l84Vy=s5P7?MgO2F#>v1#`2P93W-F|MTgw=#mBj7Z>xgvmiudG0jg* z@ajLWI+={DkpoED79QO+A$E@oyp56QMnXh<2QE%xRYt)>HX1+4JC*%peKI3h`fRzn zXlFU=dskn(#;E>yqc{7VZPwRwWwEOSyKX!08}d&H^svJlPd%JapV`Iv&lBd?z~LMr z7(@q>1KJ1`sO;jUFqj;85TMMkeD~}LNS1K8e$gz0YCD^QhJxw~=&ZeUL^qEihw_rk zAo4q^rn{l5-wiwixAH?+>Yqt#)W5%?yXj`iCW5X+q(>i^RQb8sX-tw@0J{rv}W@y*V<5YGa)zdGVcy*pxIpCTu!iE_@`f3v`>FNT6)=Nr>g~bi8J&2)NYRazY;beQ`)+T=rAEPH32GC<_z8PxJn;5(vq4prch;O8! z-;ZgmqiPIybliXj<7UpL4uil+CpJhVa$)CFCL8bW(F7as7O>)^9pT~~;^N|@67gra zB7Knn&7X?zNIL%lX7{G=jipY~=3sx}A_&)}ixro7Upos)R!@WRP@x~2tg8T_IF~Cy5pZW6?UIMO=a0Gx% zMBB@q?)fnM#24~@cv%^W+=*XQl%E_NeCl)9)F|i-wf{84USU!q6;?j$JtZaf&R#)* zF(qw-308jc9<~WK-Mz$d)|Y%RWvi1v0G(!sjX^C4Py}z0vfK_EyWwAh`?Xu?sa7iq z2{CI)30GfukCjw6e@>&43ehgxX*$>6gZBNrPPvQUR9kzncN3RZx^a|A3 zQn1ALU>!1)8@USSduWYm!IuKO+AC&Dbu`PE<{Osg_b=nbmcEQ@^tzNk+IW62IW>Px z#SMyReC~YXq_LMc4)J%R?05;u<3GaKU!Z5(|HmkEv@kROf3ffW7RV~i5F2qY+%uTU zf4uB|a5)%)mstR`b@I40>*_PoayJW4*C$!(CmF6OjJlhxhAm7zd41XVzQoli%fr!c zc|3yuK8`sHyn}!QfQCpwe)BbuuFFnbI8U3eFKeF81KH{5BZa@7~i;mH?g>6ZPBZDgoh!&6{ z&A*+-ORDLASkwHR%6|cm{hwpe#r_{m;(zn{U|C3t9Yo$A|7N18_PG@{Ze^-DPQa(5 zhkiLv5v$4h*%}k-^Oz%?G#@X=X>44B6DL&}OpFse+}4uYzl3pk2>tgeI*}ZE_Z4EGeebXcj;9JW7Ydwn*PL3bIXn#ZL4D zan|rX-{bal+GL=a`|0iOE=IN!#>W~FI;PX~huD=%t8FT-ffv(@9ezmm;NL+&KTWtf zY6DZ%5NLk^kmKND;Aq152QFCA!q)81a}E(9`axh}Xq7wjLjH4R1QwV5-U39GHaCL&{b4b6s9-1tK76AXd05@k#^!o^$%&; zg(x4=(g*d;i|k76^uHhW8#Cnup8V>lRb7^0BUTKDR`VzSlW_U;*<7p@L^e%R8=Wp} zT*K{5<}w4&t-L%RC2U$8SpHV0gQXYRR=<+7q~3Jd^!TT5UzxTxKfqccWNPj4ddxnX zZqnbtL`G~l>hNup2KiN&A10cqvB_kAFGLj_p9JJIlekGTygPA#&`azqkR9` zXDnGhZVt6SxXKf5jPYZ}U9)@hXmgvF#9G%$9K7!mg;|nrnY&Nu4%k|BamUURA=4p8 zv)}IQ_s@*3stu8#5Wgd2@FAV^F#~@mHlY1;xURB+p|y#miNR0I?muE=5D3wCbV9sJ zX;CkN%u9{RbJX>jsSb3}NULhV75EV9ik$GlDbqArgoUQA9${5w1&z(>`2PKD+=GHes1e=N5;M?MwKn8-A@@3Vks_N*Tq?p2M_e1iSEbYOoT+}<6a zayS9)pJ!74>tEm(V%iBT`p@_rBtWb}`NM-s%09S#fL4B1065HhK)b!CHsE7VWposUOX+92zXMO0_c%2;XK!RLYjM_Nn|BQ)N8Py_9C@rKcgLf@0g zg6$6z8P@t`13>)K5>|$-qa#>Yo!0Iy!PwaF2IK@>2OZ48ry5ohIpa0VK7+&E z@z;S;#0e!Jz07>ez$z9JqTzI&f@!wFU};Y82gLa@+B+=x&_bi5 zvh%@=JD$a@g3LtD)1zD)#J^bHU58UVORBA{o-DUH8Tzw1Enjf0>WmBKbUxX*ve@jR z!MDCtgGHka(r6Z!G8jH>(Q+>69WYAWLaN~KQSRCx`XMYe>0DFLq1vt^inoIVR3lX$ zLq!ue&mLG})a}Bp$`Gn_9Vf0O#~=hq(6Fc%BOCEg0pa&Y^_PNVS9%RYrzfQPoh`s9 z`prr2-l1&=B@jpelhD5q_?1oEoh2+xtd0L+DEW7gyXxKlAa^zLSdgEgLK3Mx?nGhJ zQsXn5;ltUhv2JrVxJN;qs^5Q79{-%DWPCb#Ph8;_WqYJ^^R0qoY%c4fpIeVAPDD@KZg2ZqD@;%z9jdVPi(}$yi^1=h7~2g2EH02&c)kA08Og4q8!|3mVUGnriS ziO3#*9{f679aI}^;e1U4ZQPvw$(S{we8__oB4HrdwYluulbM-Wn*ombN6MYOEAFg4 zg)&vY?W<4zT6(LkJgf-dDoXiJhHb!U_tD{m4lxcGaS8}E%LoyqtB z_J;A&`M!;yTNmywi?13u9-(JJ!?+WIKUFu03akUxmw>nXt!SS%nmj!gP0CQg*`r_? zSPr#x@zM#80@&mMd!}r^HAlK)+l*yCa6C{SG0UL3R6q2i`#RZd!>NKG+~1v6lF``30fc%6oJs zYUXY48ASTD&;U(kz^u7dSFY)U%@RUb_qVsfD8S*E89ScTGjJw-;M~M>g2G-1Pa5p9 zvgl!n15b0->jtK~LuQ=(D3q@lKYJ%wEAr`_(>pt-#Pp4&Cho|*5!TGNO|aL#uq{Yw zFC5yRK!sU>E4XB#1;w<7tgjI{t%07)but^KO1={a_0R6Ci-1UF%xw@^F3%_9!&ffV|BHc;A4IzkZ>7 zyGLmcMgV5gF+!aaz#{+Jfg0h2(*FGU`}BK7Lta-}9!)Xo{HL-$2LyxwIRn$%fWf-< zcde>qOgg0$_6Wm?yW}ttpA4BPgfI0yI&S#lQYs!6ZXPCl@PeY2`lmc+n(-O!5hcp) zW3bwJj9#X-zkjuwmj+!z)xeh=fkkr|mQ)Si3O8(?vH}&9apNR-gE69kAC2~E5D$dB zthRj*+cqy+5%-IBz=1Oy2YC=IWCVS)kc*+6W&*d#u7=2<#qlzZJ4b382pGB$S*%MQ z0bp+O)=x0Qq1%5@LjCvaoJL=np+1mJ8365{?*x_Y%*=q=^RImQk8mrl2F*?|jHT;y zGZP_86#t%rOd&UFH8+@ABU5aFS{RLfB9J6EWIq?0l%A}Vae_bB4OUg_*szSj>cD zG~KCSnfGq^*>uVZeYe6Fiq;XlC2_k44 z=76pSkWtp1Sj<&?uxWf*w1jTph2{_V9-+>E;R5}QCSa$t3a)wHS(Fv6At1Iu#e7vb zt0GR+Z;9mXs?*V98}Z%B_V%@@CwgVi9cSBgs~2g1293>#is^IE=tP|YLdy6_Cj=m-)QI%J=WSjD<3m!j+8z4$3BVnT2s0zR!RMoCSJkk zJ1VLTKSH+%-ksRB(p`ByV1K@RbuF1S*)XY(Y-eYC;(dB`nY|uD4f$9Bmy+rzgkV1D z)NtVxR#)fB%RoqIc@S0YTKxD~1J81#d>EgD=);E(C5^-a)KyAub8o=J5|?ab*^zl8 z?=}g}MAW+YK7BEsk)7U!CpFW(HRWK4uPQkZjAG@GeaZ7IrVAsO)veJ94?6S|8TG0n zh+|cmjZuCqDPb9zrqT|9z(&d?AV=uqqQt26<3Gmag1PY&&-bbT4wBRLAD}m2qFeZk zZV#;xmf{wS9FQ2+?a6JlwKKAF{QWD>ma!+2$Z{1tJ)8KTp~IMK3rg*DL>Zc~&T%uR z>`xRZ%~GeO<3CPJaA$8)ge(zp=t=UU&p`yx@K0r#*lIkykbQ01@g`ya2!n*oqm9?e zv~eJW9Cs!MJ`4*XaD8-v3+ltuL1LPr#Ds+ESpLio9SCJ^V%sT^UAFcy>=09 z>M{$yMyo6e zsbEg$VH$Y*(-Tlo0TX`3~|_TJRK3>0$(7ZlC7CE-da zBgEQalk#xJK^qu+eZ?0Y3OaaZxonJ%LQGr%eWx?M6Z073iwe$KG=sB#67QlF{K#5a zRRBi~ebSNp(ju&F?K2(n$bi2(d@JjmG1r`S(!{BBH07a?g+-mAS37Y;?c2)DCWY8u zEK6}-!LBPGBTJ!$U?&v(f}^tw7IYp7MsYufs(jz6gqc-Zt~7`P)p!WSNLRYwp;K=i zQyf$deqpw@HrLDmS=$xV9L;)BP!w|B+D;vqPAM6_ zoI%l1UkaQnt4$#am^66pN+X{84wAqdUrvgLu2K=cVGwz6b9L)Yt?5?ne3dPyYQGI& zq!$-989CU4XHFcQAnq0e$lwX*h;O@1hCwg1()nC-&SB<)OR7uhvqL8)A?c^Q#_Ki2 zMwNUAPh;>eBOEv8$c`f4hNxg-?qSu!R8SN6A=TB__iPr(DJzp>9ZKpzGZdb~PBOTd z6nDxHoVI4V#g)byfPLAPkG}qpzA(B30T#fn`&w<4OR&OSkeghy)g5s{z5Wi-Nw+ep zH$z%t%^1@p67pIyN6}m?V6?;T&h>U!RPA&q=r|E?)57`URP>GMkmEvda++yEl zwHBca{YQ^3Fs>4PVljwySgF%>$>C~}wfo&&*@XW4S%LRR%958Cs*-6q*lAs#-)#+f>Z{)#JGd=QdYkB@r| zoNlfp-nkURTqS1s&%)Or1@>&D;mij|@Atjl$ZcW|bVIDO;G zHRh&Ma?gCs=uu;ul-Vid<({_*4T&8J9gC)72vrzX!c#_w7?NUH2^%(C0n|_;2sdL$Q8~d=v3gD=)qP)v0Gs|N(n>}Gi&jMNFPUITKTh#E{$1Xf+ZmvSkQ{SUbeW-nQ_!1Eu6JkF~JF0OJa$mq~^41 zbL|*Q^Nd&Z>jmuM*lEz-UVctY)(=?$0X_>midy{K<46K0(x{eQR?ZGQ%3(55E9}g0ME~wmgd?1%^>*3{$oNsjHz-o zgVZK!c`4qfrzmHUOvS{VEQ?S)lSyWF5QQTd{tvXZ7R}lIgso=O3Y06G_pgdxk=Ln` z_PVgu>>Fh%(UUMSHL7k{(EAUSQ&;ab#&x?_WLsm*ea2i@RNod2-Q-W7scxO=|Doeo zC_c;B(!*ZW5}W&qqI*;L5vA~Xl(QW^LtW@0sA5t|vv=1QrTNQY6h`IE!`MEfl{{ik z*{aul{E4eu#9o1;3!G(E$Z9D0_*}>*3(E+tA8|028^xkkg@b1wqa0aR4vmL?^ap#+ z6K#|?YENUZerd@yWGdFPz&oH03MoFBM`Q)#JfP zKOwHM>_aWz8MTLg^0Y_}ThMb+RTqW$j(u#kmmw+6+6ZlHq)mVicQ_#*9c}t`(+n94 zulF@fbidallQoSdQPwIp+CxD~adGj?okPmh^cf2A=wNh7Lws^KHNveF?*&~|(fHS4 zT3BR>sOnq>1_lr5x+G~I7u)uSBy$DAzT>Cahl44dL0=+rnrlm0D#@fwuQbMp+Y+6w zaw0S(OvSb^lWTSt?>l)})%R`w#rg{af)n+5`;~_JE^ynTqxEEzTBlagjP$y*llHr% zhw1iRV@{2cjR6vfZC2z{l1N7A=(vsrpIF3v=6d@F)$Es4J`Rw4gW%~%bNS}>);vD+ zLN`%gI7vUd4@3gRN$R6G639KzqziLz@ML(@pz4C(R(-lAsd_IQ_gzitgjktcmaTWg1J)jzl4L8+@IxBf$VL)(DegNfzmqh^$YOYQnupGD)oSbY|Q5D zTr)^jm$8=y9crg7YQ4WJ(z-h&dBloMi{Ir};qx@zeki~I1fEkS*peDh*|8qp1|w=h z=fUR?qLW>ddpTOSFd4?h#l-{ABH?HpwkosqQBqB(CHYCD(3XzG;b7x_RENpfr+t#J z&aS}a78q8tSDbb4kM;2Q5&GmA+z1I7>*2@zZU_YF7#UCTC3p9JKv^S-Xi^UjybdNR zbIGoTDcQ)+hTUHxSxsB^sYX)a=NXUUBFphc{W9vEU<4EWei@n6rZxwr-*5Vi#dc@& zh+NyRaHdny#K7Xl9n`S8`;^5PSQsOe7Y_eSCO& zYER9L?f6P?^UbESb+SGMe`!q68?S$h8hm?eN4=R`Bz=W0W8*E0Hb%WrZwt|;M-Z{! zQ;YwNWd&J=+Ib@#T^?dGWGN>(Maako(PVx5P<%FQ)TF)|b5>%bmG zYNLO6)ij(!zxZ0Zz$rO%U-wn+w5=%(8_!)g!Up(z>Ww#&@p!KIG6f-eM)hKkM$S=% zN~BMBNOgztdA_gIPu4^8IhVU1Oa0=-UUMslJ=q+NzkAsPML11AoVMU@eLLfHxIjLDt#;sA zz(YHjxWD*FJ5B9!DNJ2n5YwaPKcyht1D78THe}7wd@&kLLm;{-Ic}Uc!P~xf=Pr>f z;fN}-&dB6aXa{}`kmo?SczD3pXG$K`W?19_ZuXr($JL%4C>PiLQLl@iot@nePsZkrXhBX($D5q}VB|e|a{-~oDz?|sirnKdbK1GHj z9dT&q!7ItynMTE&x)tzGM#f!>pq5jmN(+B0$qm&|QU;?)*9W7S|dp#dmeGs@az(IL#hC?xg(9;8B* zZug3Ni;FdT%%j?)=Lk8g{|@6vdo#(6T{5!!b7#V1b8|Ci72q|ktP)b2TwH8^ljv2A zcr)E`rlhzQ`i%fy}&2s+t}n#zk4xDC42iW}9pY-&deET)(UrC#V*Sllo&? zf#b&oJ2tU!J~2kt)$^+xpmsEbX2oElp=fJxnBz<_)%3;~_+i$g$E>DRbc7aL-#R@z zW+GB)&@?Zm$LZSOfiO)7OQ>RyO~>1uq6fz0gl|rQW12KK{M7kh!D1i_bJ*W|%4|1g zo0Zk}afgMkXLMVBp{2%Dc3IAKLc%8-d)CqrGhf2mBj{!xf2%(mbTwY*5M{G8iSn}_ zM4v31N}vuwwzwNsN}NQjXt9A;8$onmHkThbhkiVjGWiSoU35*+ul>-_TfS+0LVT`o zWz+~#EY zE&qxpp77sk;vq2H!~mjrde5oHkjl(Ue<1WmmrC$G(!s>knV5g@?i#wTt4~o(WHgU9 zR`quo$H69lZK5H#TI?XX-Rg=KoOmSShkeZQd~$VYKd3R0OD{uPOh_D_3|?@=dvH`K zpyq|Isi|(eP z`uX|l346~oKZrObyWw8wG5d3#+KD(;I-6j@Tz_jyt!}-Qui$vv?|>eoc2=B_KjSCR z{=$juuYhS{;N<+@YkZ&}a6fMTq-4AdT=!SF)btYqDBAz`!zHZBuW)&i@y?oH2e;qv z?0DGMosiQ~JcPu8E(BeYqVP+r%4Vun65E?Ri4z7zPZCZ~eL782j3k*zh&=s)x_hjc zkShau1XjlPAi`4CjixpgCe~ZeA3gSbJX7OV-ib~QLz}Aze%LW~+iUmxvFp*EmFAWh z{uSG+5_?TfU9cvgbw27x;a96#&0NyaJ0A`Xj@iB4T}FVoCi~F#18f~U9Og|N5#e}k zX^u^EIWPy+lS9rPsq;7QmQFb8Y^s}@>e?D=oISj(yns@4xndkVP9QO8#yNfy#B&&U zgAmITfhG)AY$%x^gz7kQbpUlc*8gGU$qCnJX>i z+V1l5^5F6DF?QP-ljNGSSW&-R{`z=uI-UI%{QeW&ccFc^FPEfDZGSvh>znqG-u(Qe zld==04umYuGM7#6{P3?$O@n~62$#dAn2m?W!>b%|h&h*?*)fUTQ>;E5RaMp0tgPJ# zDql79iOSQFodOblkydpz*vR!C;b7wTJ^_d)cOjqX0WHVk@#3^|`xeF<1wD;Mtj&{e8j?B=%`{;@FHx) zo)m4#3o?-H*2-8Jez@f)qaHJ>pV%Fs(p&F~X(tSe0p7WI;+h+LkJM&oV{7aCitKVV zsZ0siL4K~B{|0MX5Chesen~V5+2dkmVL@v7z1`Lw!?^$&YNgKHyW*&D5;7bk_x(>{ z?#Gq=u`zLR*`S&yuDq4Dc`GNb+|K(bfcFq_ z{uX7|=S!@i+0q8$UdOUq4!tIY5%_Qf=$E|#1X=h51au)aHII0Sy~DzH`}=Ti&(_8^ z-uQXATU>Zzn!jGjBQ&wkxHZtBxffO zB1C7@b_e9}*J24tbk9O>(!Igq4gVfKtZOAscAIm~ z`&*|SC4uc$J;-~{;G;OhN*IG@z7cuk)+|*TOx!vUcGdF=FYWd(?>|>yQsWOf=$B#~ z(I#b7n*<;gx-$#~RuY8~+|zyw2^t)*D}Q*8y+-gv>)!)x7?S$0`1Dci@lcXY45B}+ z*nX}pP(FN(5TEl#PP1hes*Z=zRd^#hW?dXMzMzvPB<}0VqH7Ls>&Xgqh= zD~i+~y+1D+v^GsR=5~*Wr(M19)@1(9r)HKqAF5o*+S>XR2La;1iY<1(0}d{3#M+}X zVx;S3ntk=jg$;ZpMc9O8gk9I1;G^56CAPnrzSkVYYO(B-r>^(aCbRVev$gMu{pv^R zXcmAhlc;#%{W|ii3Kd6bt%MlB+6C7%`uvE}(z6)eg=3&Mke}nal~VFpJn$NH?q;Hm znMcuJ>X3oyax)z}4EO^XTv=hm4HPO$)8t+jnP^;FD4G)s5Uara@revkOtGI%z z55bZIcWbTCfAx(GZ*LbbZKlN4+Ig%c_<<16Nql474g>`K5uPyM@&G5F3-^>?2DbjC*HgTV00z+f_k8u`dhvW<1X5j^6gph3VDKU4# zyarZSYzg-RUM#Hyut2O9;IgeKl z3I7&Uj8>GD1|_HKY`oX@mK&X%gwQ9E2Na}cTyz+9y#;3(k~(C+sh8@fnKq6ensW#| znw4tdHV$>VVTNTQvGWqG;IsXFR<&@RENkvkl;fI_MZ43V(-Kn|1RWiH3@jUrP;%}HIQe&ac?wy<*7JNgOt)(h$l+zhCtx+Md6Q=U9~F)}7Z_SfX!xf}M1`y$pUO|Cbji&z7+}w&2IcEPYhZ{gzxH!F zwFNbGbkhXu1SZtt`$|1Ab`#e4fcBR+;(z3o|0LNr{FUs#BVO@>{&R5b zcaW}VS*y3E{|Y#^7!$I{<$pqsYotE#L6fdpnPmdmS}zhOZHv4YwUc=p+m>OfaCMFPf8hFW%a|)p~9$46~-{ zU#{jg+Q$+!Ta5Jg;<5NNArKN1DWV2JESWzhS@h)IZ40Iqny4G26~rtjJhkCJlOmQ< zq1P~dcj(YrwVRMN)stP`^h7&if7eP=okg@mos}@`>)ppmk>>J|&+h&jSshaCdiidFSu$x$}DF_PafC zBi;~^1P3^K@00t>FLUi&-&%S%fct(9X#X`Q`X5m5pKd$wIWX#f#zDdQ4?sand->!4 z2A}{I{s*8~6jZL!_|OCo&!DC+45|>@CF*tcYlM#C5<4~;aWC0x!7+ELn9c@u@cY%ojpe&K1XW5 zpAU^biFo-}+|3n^1D>EA5_cKUvq9n)mvt^b1(^??h#N58S7VfKo-krVIXGN@bZ(CMHW~f_0dbmP<%N5mMkWVJTo?9@lm9K@LKl_OOr) z+~@J4UeqWBkZ8pA`#8Urs8j;gRLF`z9OC>ExB}FGIZ<%6j6j=RO^+UGb8fIo(XP(R zzK;r?NZXpYcHM1Uz585!Y}%TrYg(?<)34R*rHp=Y`U8HTUo(RN=&IZD#_ZwoIvvl% zTQqs-yScTVb14jOH)+Wi)d>@v5grTHdmHZd93M9WlnMSOBnYHwX^$656#>%J-gaEm^w?KHZ6MP9ZCf*7BP@FlpoDFrsmgBJ7q{!s}Xws1A_jQ}&Je{ooUA1aCf zs5>hGLCO^GkAkeBSw$g>$9~u9q91X~WUT@`suYPu zKtjLjM|31d%3uIGbaN91H5gRd+s)SW4FUJVA4%Ub@9SRAs3^F+CJ`C`CL(e%W!~-G zo=DK9X!@m_ubog2z{iLKU@cXEdab~+b!RY=%2@a>RLUuW3DHE|`^1h13=#QkLElUL z7B|ZNqnVkR8-On5BH-cx)&3HN$hnQAyOEKR0Ff^cDZAJu3&N#M-!E^zX(MygjadBq=Q?C!t)18KbMgr-B#_IgP&}Kf1ST)9;h0#9tIj9f zj4{(oX|RG7WYb?@uAdA0u8opQ0Ey=hfUh+l;0o7BpDNy5FUs-%eu3`~E>D2d5}s3B zaWQoQc5n*YT`ou>NN}PdM8f1q$7W|$)*mREzfO+s@ z-^?UKQb)w0H(!r&$uDDc#alj4K)?q+ZA+{c^evlyJUF`bn=giKIpDyYjDyT8x^Y|lXC=ok;M~HP;J1< zp=$yE3}s;6Of&{%Y0W~4VK*#euwtsq#YSo;TI=M(T#Upf7ElE^ikyOn<8-vu z($*>;MS2_zw2&fkpVHsX|GhizwmXTLGA9q)B2-HMY*{qzR8hP>Jr zFwv3M0(?n!sqQ{qZ5>s$Y=RI$f#@t9-0TelP!xEwuVg;VHnN=|l z{RAv*>mtd6uYQC16H~oXk@Hk$HWLca;@DbC3h%rHh-~jb;w0{rF#A0&E^@n{W|vX` z(pBe>r>Oo=VMG!Os=ZNy2xQI?aq)mXUgP3uXHm62E#v`@nW8Ej9v*n}LqMROJ_r>; zCG=$*%$^0`p2|Jk_gxhb&=1g2muiorGU=LE>6#k_v{+#LVd;`xx&iMk#n%%ylA)>F zky#Hb$cr|tLS}*1?-Wf)uPUe|cHq@2ZW4Ph0z9HSki^HdWaN)o4^xVXx(|uEdw_9< z7E5sh?I$;&dT=sw*Fn~jszUMnqn9J1pyuSRR~5;Pk>_@Bu~A7!n@6mR1C2kmXATTT zCy`!U+Bk?qveP=}Z=qh{iqMhRQ@L~|d*HAVODpre^tEvt@$8{krg(Q4cK_MLinF$# z@`0S1w(BV1%->1ag-esV2Q6_@ia}5Z<&b@A4(Gyu7DqU7Xdb zM<+qbxN&meCWn^_VsT{|AKTvpKlH&v^Ou?$r~9z~3IM*j*8-G;H*TDAjcG!h3zdxy z&u|eRFE-kFeF*7keQ-Q?E}I~4FGe?J!AW~LFP7?f>dL?en~FsXxjFBIE^^l|xbpCz zCQk3_84aetcp$HrECj34)6;|bJs;r?@?0$e?+1T*+*cy_$H1Og;=}+PpLbqCmFT%(!;2Oe;L0o4Ye9BZ@7f*Y^5rws>4Cjm#INR6O* zi6(My&sd%Zo5dB1shLoiAl=bdkl8Kz)U5`%6rT!IxM{19?&{& z9A<+Z0v@|EWN|wla#X4ZCyjyW(j=qw+D_evK;%+oME90RsS06P)k2&&TWf`MK4geb(&ucHY|3 z(vp1>X#`1<${h1!RVL?A*UMvj#Gf`c7M9(|r>97+=`AbRek3EgfDg0BvGw&%UUbRO z;@d}JSGQKh*0zf{#}K^Iq2IDm6u%%(_g($ObR2 z?kfi0_H532g1XpvL{@zzZ`9Mj9jy2Qec8{qmU*!o{_BPB-Qwe~TmWkNtNq)k`ELu~ ze}Yf{yKU6&-%+zIwN)q3|9_|%^M9abY!7DM2)s8pz2Nroi?GCPdB)x>X&;{61#jHu zddKh06~6kfBRjvU=NpY|>UT_%i!R#xbMX1}d%mu`AFu=8)2Q-4wHA|K6BrcQn7Z_#V_`+RNtYG+dV!hUVk*mMb; zu#RU1Y41eKtun`QmAm4>Z{XC~dXBM$OIC1VHEU1b@Tf1hxUYr=+age!*sd`Ds4~c2 z-J0{YP0``EB?-YINe3ESfUfaJS=8+u3RB z=c0TSnlF)55V>X$BXuXN|Kql{?F(j@62JJp<|jNq_Pr9ev>@GNo}NqyMnzS3%Ic3L zXV;_QY+lxEd|xEt8GqKNsozI$zmM=t(B6#!n(gsjU0wcw@#Sr1cHC>g2N3LRZ);;f zKtOQe%YP*7YhE-XB_y0~yikRS*54P9SfHvu${S(B5KQ?*7j zaB$TO4w0g(4NeEWZf~DIB1A|4()Kn{v9WrJ6p3*vea=6mhJ}sA!PU5)J8Hu&)DX;( z15|Ya{aoNIoEPpI^L-v@k55j1lLX~u?}8duSW2BiXx5^26oKtLI+~r&;YFj+zQz> zi5S{g-w~j?!Oyk12@<bMB& zn2(MUdh^~N9Vs!P4Ttvye~m0xx6`tKDD(bZI2!y}2<&FqY>yT)(o`R9moV0i+gpL2;`2&0roqqXe4=ou zxMJW_3jZPzBo9u!R(&6FZd@5}R8DU{YuIJFps1!T&zyv8k?zLJbOLBZ8X^Pr)X(60 zHDwHq0f8Q-Tf0E^#mSSa7!uovUz?4c|R0?)bRJV@3N zt54()OX#``Em})U)zRc*Wdx zWL=MEvt%Ovr(A05hw?3^(XdBJtOquRNCz&NFSOJ~ip~3tWAA9sAT-Sc-0P4^q?}0> zI%HeyzY;b8HlL{M1N2P~p#2+_mVfn+v74QN&CmatnEt=JN3Fdy(nxBsY99<*-IO9w zoUof?J?_ly^+ue082NFCP{gBB0Gk~ZVZ${3g^a)Z1_II2sHUHA=uz(-IN3_LqsdFM z4_4#+D5KnmRcIUHEdB*EcA1+nna|)=Tzk7S^V(Wh`C$zh1S3oG9q(hV85#ewpq_YZx0itVzr7B;v9Qk;=dFSS=h_m7y``9fBC@u*W&qV ze|3qKv4P2dQ=yZ=#@)sYVuqiiH5Km=6{g24 zD)@P-tqJ-)qb9L`1XRf!HNIH5ALOre`jOvp;3{fkexdtKWkKiHg32Ky+r-HzB)gp~ zpbJbjU@E;Z(^_%XBV-QAbR&a-^;L$7E-?K{xsxV{tq(h1e9GH$%eK&e-NZLP8m|`rnzlL9zZ35~}jHxZ+qoF0L*Y zT;WlfLCZ-{58HV~VlrSB%EbdI9zY~$@#{)l2PuU94hM{4r^FVB;@tNlibBFETtJ~Y zehEI*P*$9qO|G4mHBXi%Zo}%ucyU<}4=huO`t_ycRn@fkZ@~?NU8bqu zUs`co5!Y`kvOyWb`&cGhX~XZ)G$j>8D!R?q&35Wgt<2BgLq&Ys?ChAdPTB)dOD zR)@8nfJVw7L5@Rv{AA!lkrUYZgXB46Z!J+gQdgQU%E3aah4<;eoczvEeNn~|DDLIS zSpcOrV5uM~{cO{%Hv31~l^ZrsMM+2l>1S{Ry$emyJ`rUmDs_cV(WfK$T)+-2^7rWq1Y=td1A=3QK%rRvq8nZ+mi?$=kM?91PGzE z)}cgGea?Gzs0nry*e?qHq5;eiC~{dOU^pc~#$d@%z<1u=Cv6NoF_B_jpzIm}Fu&Yn zXNe@l45fB$(l8v{QE_5T`VaLwov$n^tvUdvpB+b#5(8ibZoB1%V{oV?=7w$h0hFX- z!kj10+P?erpWBa+3yFc+89%`|i?!2S+Wg~n!wr~0)ooz3Fi4?)?7YwUq_<5e+SEJ* zF4f^~33fbLI6Jc!wh+h0#IOZ#k2RPoc6ReC`!t~S+Hzh{+4(+ZKf30d3VJ+0WMf)d zTACOBL8@WIn;iD`@;yH2Z0hKEU%7pF!jwH|@qK^n-57Q%mTVmQhW@Vjh6(&N@Ea8v z>ES;gqG&~vY@?xZA0u#p;fV(X#1Htlf3d!{FfavZ^Drtq8vrzVm|121_EOH))>7E! zr-ZSw6=2bA;OLmG0qvzWi2X&;KALHj@{^TY3M2@KI0(!I9++EP3h4W~5Sf3QmZhGH zUPAC>*Fk4X(0%Q_lJk2TKdbh*WFjwOP8$)q5Hv9J1~)mi!v9E-}nwJj2APIKx=$o>hqI4@H2~7aEnce z9c-{R^}57P1&mj8-vwHXa$1pHRv$jvWszM#-xBq@_>K+CR-PSVuqXAp3t?uq3rtW}gvSm*`GAT9@R`8=8;MPAHm>*p5AnBG|U{vpo<)U@6sm zP@f|8dsN>v^?N`cBlUYk!&?(bcmDMn5Fh-s(lb7xM@pX~nvdd+I}D>;!>7!UPhiv9xCHT}MwR-s z1P+-LrCEhh6&W6?6SWbRU^+^rX5wV&@3_#oB^}CvO5v-s(=RK^KsmRV+rqo0<)+js!ONz5%2^W`m}!+Lj_-S@iE@2`z@=5@ zo3i(35DCTEWa`*hglEOqQ;=k$LQk@JK13NGpHzjSWL&4IQJZhq!I_Wxum@I{I x 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

    6Ef%Cz}4cvaP+e)d+%B-LYq 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