From e0dd0c850ade81669a3fd794d644a77390881950 Mon Sep 17 00:00:00 2001 From: Hizenberg469 Date: Mon, 4 Nov 2024 21:51:00 +0530 Subject: [PATCH] final implementation --- .gitignore | 5 + pom.xml | 157 +++++ src/main/java/com/secure_mailer/App.java | 19 + .../secure_mailer/backend/BaseController.java | 18 + .../secure_mailer/backend/DatabaseSetup.java | 37 ++ .../secure_mailer/backend/EmailAccount.java | 52 ++ .../secure_mailer/backend/EmailManager.java | 36 ++ .../backend/EmailSecretCode.java | 30 + .../backend/LoginController.java | 31 + .../backend/SecretCodeController.java | 96 +++ .../secure_mailer/backend/SecretCodeDAO.java | 73 +++ .../backend/ValidatorClient.java | 260 ++++++++ .../backend/service/EmailSendingService.java | 106 ++++ .../backend/service/FetchFolderService.java | 102 +++ .../backend/service/LoginService.java | 44 ++ .../service/MessageRendererService.java | 165 +++++ .../secure_mailer/frontend/Attachment.java | 50 ++ .../frontend/AttachmentCell.java | 74 +++ .../com/secure_mailer/frontend/EmailCell.java | 89 +++ .../secure_mailer/frontend/EmailMessage.java | 122 ++++ .../frontend/FolderTreeItem.java | 62 ++ .../secure_mailer/frontend/IconResolver.java | 32 + .../frontend/MainWindowController.java | 599 ++++++++++++++++++ .../secure_mailer/frontend/ViewGenerator.java | 70 ++ .../META-INF/javamail.default.address.map | 0 src/main/resources/css/themeDefault.css | 320 ++++++++++ .../font/Myriad_Pro_Light_SemiCondensed.otf | Bin 0 -> 94340 bytes .../resources/font/Myriad_Pro_Regular.ttf | Bin 0 -> 94884 bytes src/main/resources/fxml/attachment_cell.fxml | 22 + src/main/resources/fxml/crud_window.fxml | 37 ++ src/main/resources/fxml/email_cell.fxml | 46 ++ src/main/resources/fxml/login.fxml | 32 + src/main/resources/fxml/main.fxml | 142 +++++ src/main/resources/img/EmailBackground-01.png | Bin 0 -> 244028 bytes src/main/resources/img/EmailUI.png | Bin 0 -> 639497 bytes src/main/resources/img/EmailUIcompose.png | Bin 0 -> 854749 bytes src/main/resources/img/LoginUI.png | Bin 0 -> 16757 bytes .../resources/img/default/email-client.png | Bin 0 -> 5367 bytes src/main/resources/img/default/hover/at.png | Bin 0 -> 9810 bytes .../img/default/hover/attach-message.png | Bin 0 -> 12037 bytes .../img/default/hover/cancel-message.png | Bin 0 -> 8845 bytes .../img/default/hover/compose-key.png | Bin 0 -> 3571 bytes .../img/default/hover/composer-field.png | Bin 0 -> 1646 bytes .../resources/img/default/hover/draft.png | Bin 0 -> 3976 bytes src/main/resources/img/default/hover/flag.png | Bin 0 -> 3427 bytes .../resources/img/default/hover/inbox.png | Bin 0 -> 5686 bytes .../resources/img/default/hover/login-key.png | Bin 0 -> 1428 bytes src/main/resources/img/default/hover/mail.png | Bin 0 -> 5624 bytes .../img/default/hover/search-bar.png | Bin 0 -> 1068 bytes .../img/default/hover/send-message.png | Bin 0 -> 6686 bytes src/main/resources/img/default/hover/sent.png | Bin 0 -> 8180 bytes .../resources/img/default/hover/settings.png | Bin 0 -> 11469 bytes src/main/resources/img/default/hover/spam.png | Bin 0 -> 8519 bytes .../img/default/hover/star-folder.png | Bin 0 -> 7864 bytes src/main/resources/img/default/hover/star.png | Bin 0 -> 30252 bytes .../img/default/hover/trash-folder.png | Bin 0 -> 6022 bytes .../resources/img/default/hover/trash.png | Bin 0 -> 20969 bytes src/main/resources/img/default/idle/at.png | Bin 0 -> 9846 bytes .../img/default/idle/attach-message.png | Bin 0 -> 12102 bytes .../img/default/idle/attached-message.png | Bin 0 -> 6146 bytes .../img/default/idle/cancel-message.png | Bin 0 -> 8883 bytes .../img/default/idle/compose-key.png | Bin 0 -> 3564 bytes .../img/default/idle/composer-field.png | Bin 0 -> 1649 bytes .../img/default/idle/composer-tools-box.png | Bin 0 -> 1963 bytes src/main/resources/img/default/idle/draft.png | Bin 0 -> 3983 bytes .../img/default/idle/email-cell-clip.png | Bin 0 -> 8682 bytes src/main/resources/img/default/idle/flag.png | Bin 0 -> 3427 bytes src/main/resources/img/default/idle/inbox.png | Bin 0 -> 5706 bytes .../img/default/idle/login-email-icon.png | Bin 0 -> 5930 bytes .../resources/img/default/idle/login-key.png | Bin 0 -> 1431 bytes .../img/default/idle/login-pass-icon.png | Bin 0 -> 5350 bytes src/main/resources/img/default/idle/mail.png | Bin 0 -> 5629 bytes .../resources/img/default/idle/paper-clip.png | Bin 0 -> 5721 bytes .../resources/img/default/idle/search-bar.png | Bin 0 -> 1075 bytes .../img/default/idle/search-icon.png | Bin 0 -> 6526 bytes .../img/default/idle/send-message.png | Bin 0 -> 6686 bytes src/main/resources/img/default/idle/sent.png | Bin 0 -> 8190 bytes .../resources/img/default/idle/settings.png | Bin 0 -> 12332 bytes src/main/resources/img/default/idle/spam.png | Bin 0 -> 8529 bytes .../img/default/idle/star-folder.png | Bin 0 -> 7912 bytes src/main/resources/img/default/idle/star.png | Bin 0 -> 30143 bytes .../img/default/idle/trash-folder.png | Bin 0 -> 6034 bytes src/main/resources/img/default/idle/trash.png | Bin 0 -> 20958 bytes .../resources/img/email-cell-template.png | Bin 0 -> 38160 bytes src/test/java/com/secure_mailer/AppTest.java | 38 ++ 85 files changed, 2966 insertions(+) create mode 100644 .gitignore create mode 100644 pom.xml create mode 100644 src/main/java/com/secure_mailer/App.java create mode 100644 src/main/java/com/secure_mailer/backend/BaseController.java create mode 100644 src/main/java/com/secure_mailer/backend/DatabaseSetup.java create mode 100644 src/main/java/com/secure_mailer/backend/EmailAccount.java create mode 100644 src/main/java/com/secure_mailer/backend/EmailManager.java create mode 100644 src/main/java/com/secure_mailer/backend/EmailSecretCode.java create mode 100644 src/main/java/com/secure_mailer/backend/LoginController.java create mode 100644 src/main/java/com/secure_mailer/backend/SecretCodeController.java create mode 100644 src/main/java/com/secure_mailer/backend/SecretCodeDAO.java create mode 100644 src/main/java/com/secure_mailer/backend/ValidatorClient.java create mode 100644 src/main/java/com/secure_mailer/backend/service/EmailSendingService.java create mode 100644 src/main/java/com/secure_mailer/backend/service/FetchFolderService.java create mode 100644 src/main/java/com/secure_mailer/backend/service/LoginService.java create mode 100644 src/main/java/com/secure_mailer/backend/service/MessageRendererService.java create mode 100644 src/main/java/com/secure_mailer/frontend/Attachment.java create mode 100644 src/main/java/com/secure_mailer/frontend/AttachmentCell.java create mode 100644 src/main/java/com/secure_mailer/frontend/EmailCell.java create mode 100644 src/main/java/com/secure_mailer/frontend/EmailMessage.java create mode 100644 src/main/java/com/secure_mailer/frontend/FolderTreeItem.java create mode 100644 src/main/java/com/secure_mailer/frontend/IconResolver.java create mode 100644 src/main/java/com/secure_mailer/frontend/MainWindowController.java create mode 100644 src/main/java/com/secure_mailer/frontend/ViewGenerator.java create mode 100644 src/main/resources/META-INF/javamail.default.address.map create mode 100644 src/main/resources/css/themeDefault.css create mode 100644 src/main/resources/font/Myriad_Pro_Light_SemiCondensed.otf create mode 100644 src/main/resources/font/Myriad_Pro_Regular.ttf create mode 100644 src/main/resources/fxml/attachment_cell.fxml create mode 100644 src/main/resources/fxml/crud_window.fxml create mode 100644 src/main/resources/fxml/email_cell.fxml create mode 100644 src/main/resources/fxml/login.fxml create mode 100644 src/main/resources/fxml/main.fxml create mode 100644 src/main/resources/img/EmailBackground-01.png create mode 100644 src/main/resources/img/EmailUI.png create mode 100644 src/main/resources/img/EmailUIcompose.png create mode 100644 src/main/resources/img/LoginUI.png create mode 100644 src/main/resources/img/default/email-client.png create mode 100644 src/main/resources/img/default/hover/at.png create mode 100644 src/main/resources/img/default/hover/attach-message.png create mode 100644 src/main/resources/img/default/hover/cancel-message.png create mode 100644 src/main/resources/img/default/hover/compose-key.png create mode 100644 src/main/resources/img/default/hover/composer-field.png create mode 100644 src/main/resources/img/default/hover/draft.png create mode 100644 src/main/resources/img/default/hover/flag.png create mode 100644 src/main/resources/img/default/hover/inbox.png create mode 100644 src/main/resources/img/default/hover/login-key.png create mode 100644 src/main/resources/img/default/hover/mail.png create mode 100644 src/main/resources/img/default/hover/search-bar.png create mode 100644 src/main/resources/img/default/hover/send-message.png create mode 100644 src/main/resources/img/default/hover/sent.png create mode 100644 src/main/resources/img/default/hover/settings.png create mode 100644 src/main/resources/img/default/hover/spam.png create mode 100644 src/main/resources/img/default/hover/star-folder.png create mode 100644 src/main/resources/img/default/hover/star.png create mode 100644 src/main/resources/img/default/hover/trash-folder.png create mode 100644 src/main/resources/img/default/hover/trash.png create mode 100644 src/main/resources/img/default/idle/at.png create mode 100644 src/main/resources/img/default/idle/attach-message.png create mode 100644 src/main/resources/img/default/idle/attached-message.png create mode 100644 src/main/resources/img/default/idle/cancel-message.png create mode 100644 src/main/resources/img/default/idle/compose-key.png create mode 100644 src/main/resources/img/default/idle/composer-field.png create mode 100644 src/main/resources/img/default/idle/composer-tools-box.png create mode 100644 src/main/resources/img/default/idle/draft.png create mode 100644 src/main/resources/img/default/idle/email-cell-clip.png create mode 100644 src/main/resources/img/default/idle/flag.png create mode 100644 src/main/resources/img/default/idle/inbox.png create mode 100644 src/main/resources/img/default/idle/login-email-icon.png create mode 100644 src/main/resources/img/default/idle/login-key.png create mode 100644 src/main/resources/img/default/idle/login-pass-icon.png create mode 100644 src/main/resources/img/default/idle/mail.png create mode 100644 src/main/resources/img/default/idle/paper-clip.png create mode 100644 src/main/resources/img/default/idle/search-bar.png create mode 100644 src/main/resources/img/default/idle/search-icon.png create mode 100644 src/main/resources/img/default/idle/send-message.png create mode 100644 src/main/resources/img/default/idle/sent.png create mode 100644 src/main/resources/img/default/idle/settings.png create mode 100644 src/main/resources/img/default/idle/spam.png create mode 100644 src/main/resources/img/default/idle/star-folder.png create mode 100644 src/main/resources/img/default/idle/star.png create mode 100644 src/main/resources/img/default/idle/trash-folder.png create mode 100644 src/main/resources/img/default/idle/trash.png create mode 100644 src/main/resources/img/email-cell-template.png create mode 100644 src/test/java/com/secure_mailer/AppTest.java diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..400e7c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +.classpath +/.metadata/ +.project +/.settings/ +/target/ diff --git a/pom.xml b/pom.xml new file mode 100644 index 0000000..11e4304 --- /dev/null +++ b/pom.xml @@ -0,0 +1,157 @@ + + 4.0.0 + + com + secure_mailer + 0.0.1-SNAPSHOT + jar + + secure_mailer + http://maven.apache.org + + + com.secure_mailer.backend.MainClass + UTF-8 + + + + + + + src/main/resources + + + **/*.png + **/*.css + **/*.fxml + **/*.ttf + **/*.otf + **/*.default.address.map + + + + **/test/** + + + + + + + org.openjfx + javafx-maven-plugin + 0.0.5 + + + + run + + + + + + + org.codehaus.mojo + exec-maven-plugin + 3.5.0 + + com.secure_mailer.App + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 17 + 17 + + + + + + + + + junit + junit + 3.8.1 + test + + + + commons-codec + commons-codec + 1.15 + + + + com.h2database + h2 + 2.1.214 + + + + com.gluonhq + gluonfx-maven-plugin + 1.0.24 + + + + + + org.openjfx + javafx-controls + 23 + + + org.openjfx + javafx-fxml + 23 + + + org.openjfx + javafx-graphics + 23 + + + + org.openjfx + javafx-media + 23 + + + org.openjfx + javafx-swing + 23 + + + org.openjfx + javafx-web + 23 + + + + + javax.mail + javax.mail-api + 1.6.2 + + + com.sun.mail + javax.mail + 1.6.2 + + + + + javax.activation + activation + 1.1.1 + + + + + + diff --git a/src/main/java/com/secure_mailer/App.java b/src/main/java/com/secure_mailer/App.java new file mode 100644 index 0000000..3b0ed79 --- /dev/null +++ b/src/main/java/com/secure_mailer/App.java @@ -0,0 +1,19 @@ +package com.secure_mailer; + +import com.secure_mailer.backend.EmailManager; +import com.secure_mailer.frontend.ViewGenerator; +import javafx.application.Application; +import javafx.stage.Stage; + +public class App extends Application { + + public static void main(String... args) { + launch(args); + } + + @Override + public void start(Stage primaryStage) throws Exception { + EmailManager em = new EmailManager(); + ViewGenerator.initialize(em); + } +} diff --git a/src/main/java/com/secure_mailer/backend/BaseController.java b/src/main/java/com/secure_mailer/backend/BaseController.java new file mode 100644 index 0000000..920d206 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/BaseController.java @@ -0,0 +1,18 @@ +package com.secure_mailer.backend; + +public class BaseController { + + private String fxml; + private EmailManager emailManager; + protected String emailID; + + public BaseController(String fxml, EmailManager emailManager) { + this.fxml = fxml; + this.emailManager = emailManager; + } + + public String getEmailID() { return this.emailID; } + + public String getFXML() { return fxml; } + public EmailManager getEmailManager() { return emailManager; } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/DatabaseSetup.java b/src/main/java/com/secure_mailer/backend/DatabaseSetup.java new file mode 100644 index 0000000..c64220b --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/DatabaseSetup.java @@ -0,0 +1,37 @@ +package com.secure_mailer.backend; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.SQLException; +import java.sql.Statement; + +public class DatabaseSetup { + private static final String DB_URL = "jdbc:h2:~/email_client_db"; // URL for H2 database + private static final String USER = "sa"; // Default user for H2 + private static final String PASSWORD = ""; // Default password for H2 + + /** + * Sets up the database and creates the SecretCodes table if it does not exist. + */ + public static void setupDatabase() { + // Using try-with-resources to ensure resources are closed properly + try (Connection connection = DriverManager.getConnection(DB_URL, USER, PASSWORD); + Statement stmt = connection.createStatement()) { + + // SQL statement to create the SecretCodes table if it doesn't exist + String createTable = "CREATE TABLE IF NOT EXISTS SecretCodes (" + + "email VARCHAR(255) PRIMARY KEY, " + + "secretCode VARCHAR(255) NOT NULL)"; + + stmt.execute(createTable); // Execute the create table statement + System.out.println("Database setup completed successfully."); + + } catch (SQLException e) { + System.err.println("Database setup failed: " + e.getMessage()); + } + } + + public static void main(String[] args) { + setupDatabase(); // Call the setupDatabase method + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/EmailAccount.java b/src/main/java/com/secure_mailer/backend/EmailAccount.java new file mode 100644 index 0000000..ccf59e3 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/EmailAccount.java @@ -0,0 +1,52 @@ +package com.secure_mailer.backend; + +import java.util.ArrayList; +import java.util.Properties; +import javax.mail.Folder; +import javax.mail.Session; +import javax.mail.Store; + +public class EmailAccount { + + private String address; + private String password; + private Properties properties; + private Store store; + private Session session; + private ArrayList folders = new ArrayList(); + + public EmailAccount(String address, String password) { + this.address = address; + this.password = password; + properties = new Properties(); + + properties.put("incomingHost", "peachy.in.net"); + properties.put("mail.store.protocol", "imaps"); + properties.put("mail.transport.protocol", "smtps"); + properties.put("mail.smtps.host", "peachy.in.net"); + properties.put("mail.smtps.auth", "true"); + properties.put("outgoingHost", "peachy.in.net"); + + //properties.put("mail.imap.host", "peachy.in.net"); // Replace with your IMAP server + properties.put("mail.imaps.port", "993"); // Common port for IMAP SSL + properties.put("mail.imaps.ssl.enable", "true"); + properties.put("mail.imaps.auth", "true"); + + //properties.put("mail.smtp.host", "peachy.in.net"); // Replace with your SMTP server + properties.put("mail.smtps.port", "465"); // Common port for SMTP SSL; check with your server if different + properties.put("mail.smtps.auth", "true"); + properties.put("mail.smtps.ssl.enable", "true"); + //properties.put("mail.smtp.starttls.enable", "true"); // Optional if the server supports STARTTLS + } + + public String getAddress() {return address;} + public String getPassword() {return password;} + public Properties getProperties() {return properties;} + public Store getStore() {return store;} + public Session getSession() {return session;} + public ArrayList getFolders() {return folders;} + public void setProperties(Properties properties) {this.properties = properties;} + public void setStore(Store store) {this.store = store;} + public void setSession(Session session) {this.session = session;} + @Override public String toString() {return address;} +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/EmailManager.java b/src/main/java/com/secure_mailer/backend/EmailManager.java new file mode 100644 index 0000000..2c92d29 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/EmailManager.java @@ -0,0 +1,36 @@ +package com.secure_mailer.backend; + +import com.secure_mailer.backend.service.FetchFolderService; +import com.secure_mailer.backend.service.LoginService; +import com.secure_mailer.frontend.FolderTreeItem; +import com.secure_mailer.frontend.EmailMessage; +import com.secure_mailer.frontend.ViewGenerator; + +public class EmailManager { + + private static final String LOCATION_OF_DOWNLOADS = System.getProperty("user.home") + "/Downloads/"; + private EmailAccount emailAccount; + private FolderTreeItem foldersRoot = new FolderTreeItem(); + private FolderTreeItem selectedFolder; + private EmailMessage selectedMessage; + + public void login(String account, String password) { + emailAccount = new EmailAccount(account, password); + new LoginService(emailAccount); + } + + public void fetchFolders() { + FetchFolderService ffs = new FetchFolderService(emailAccount.getStore(), foldersRoot, emailAccount.getFolders()); + ffs.setOnSucceeded(e -> ViewGenerator.showMainWindow(this)); + ffs.start(); + } + + public static String getDownloadPath() { return LOCATION_OF_DOWNLOADS; } + public FolderTreeItem getFolderRoot() { return foldersRoot; } + public void setSelectedFolder(FolderTreeItem item) { selectedFolder = item; } + public void setSelectedMessage(EmailMessage emailMessage) { this.selectedMessage = emailMessage; } + public EmailMessage getSelectedMessage() { return selectedMessage; } + public FolderTreeItem getSelectedFolder() { return selectedFolder; } + public EmailAccount getEmailAccount() { return emailAccount; } + +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/EmailSecretCode.java b/src/main/java/com/secure_mailer/backend/EmailSecretCode.java new file mode 100644 index 0000000..7f2214f --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/EmailSecretCode.java @@ -0,0 +1,30 @@ +package com.secure_mailer.backend; + +import javafx.beans.property.SimpleStringProperty; +import javafx.beans.property.StringProperty; + +public class EmailSecretCode { + private final StringProperty email; + private final StringProperty secretCode; + + public EmailSecretCode(String email, String secretCode) { + this.email = new SimpleStringProperty(email); + this.secretCode = new SimpleStringProperty(secretCode); + } + + public String getEmail() { + return email.get(); + } + + public StringProperty emailProperty() { + return email; + } + + public String getSecretCode() { + return secretCode.get(); + } + + public StringProperty secretCodeProperty() { + return secretCode; + } +} diff --git a/src/main/java/com/secure_mailer/backend/LoginController.java b/src/main/java/com/secure_mailer/backend/LoginController.java new file mode 100644 index 0000000..cf38fa5 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/LoginController.java @@ -0,0 +1,31 @@ +package com.secure_mailer.backend; + +import javafx.fxml.FXML; +import javafx.scene.control.PasswordField; +import javafx.scene.control.TextField; + +public class LoginController extends BaseController{ + + @FXML private TextField emailField; + @FXML private PasswordField passwordField; + private EmailManager em; + + public LoginController(EmailManager emailManager) { + super("/fxml/login.fxml", emailManager); + em = emailManager; + } + + @FXML void loginAction() { + String email = emailField.getText(); + String password = passwordField.getText(); + + saveEmailID(email); + + em.login(email, password); + em.fetchFolders(); + } + + private void saveEmailID(String username) { + this.emailID = username; + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/SecretCodeController.java b/src/main/java/com/secure_mailer/backend/SecretCodeController.java new file mode 100644 index 0000000..df050ea --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/SecretCodeController.java @@ -0,0 +1,96 @@ +package com.secure_mailer.backend; + +import javafx.fxml.FXML; +import javafx.scene.control.*; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import java.sql.SQLException; + +public class SecretCodeController { + + @FXML private TextField emailField; + @FXML private TextField secretCodeField; + @FXML private TableView secretCodesTable; + @FXML private TableColumn emailColumn; + @FXML private TableColumn secretCodeColumn; + + private ObservableList dataList; + + public void initialize() { + dataList = FXCollections.observableArrayList(); + secretCodesTable.setItems(dataList); + emailColumn.setCellValueFactory(cellData -> cellData.getValue().emailProperty()); + secretCodeColumn.setCellValueFactory(cellData -> cellData.getValue().secretCodeProperty()); + loadAllEntries(); + } + + @FXML + private void handleAdd() { + String email = emailField.getText(); + String secretCode = secretCodeField.getText(); + try { + SecretCodeDAO.addSecretCode(email, secretCode); + //dataList.add(new EmailSecretCode(email, secretCode)); + clearFields(); + } catch (SQLException e) { + showAlert("Error", "Could not add secret code."); + e.printStackTrace(); + } + } + + @FXML + private void handleUpdate() { + String email = emailField.getText(); + String secretCode = secretCodeField.getText(); + try { + SecretCodeDAO.updateSecretCode(email, secretCode); + //loadAllEntries(); + clearFields(); + } catch (SQLException e) { + showAlert("Error", "Could not update secret code."); + e.printStackTrace(); + } + } + + @FXML + private void handleDelete() { + String email = emailField.getText(); + try { + SecretCodeDAO.deleteSecretCode(email); + //loadAllEntries(); + clearFields(); + } catch (SQLException e) { + showAlert("Error", "Could not delete secret code."); + e.printStackTrace(); + } + } + + @FXML + private void handleViewAll() { + loadAllEntries(); + } + + private void loadAllEntries() { + try { + dataList.clear(); + for (EmailSecretCode entry : SecretCodeDAO.getAllEntries()) { + dataList.add(entry); + } + } catch (SQLException e) { + showAlert("Error", "Could not load entries."); + e.printStackTrace(); + } + } + + private void clearFields() { + emailField.clear(); + secretCodeField.clear(); + } + + private void showAlert(String title, String message) { + Alert alert = new Alert(Alert.AlertType.INFORMATION); + alert.setTitle(title); + alert.setContentText(message); + alert.show(); + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/SecretCodeDAO.java b/src/main/java/com/secure_mailer/backend/SecretCodeDAO.java new file mode 100644 index 0000000..04426ff --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/SecretCodeDAO.java @@ -0,0 +1,73 @@ +package com.secure_mailer.backend; + +import java.sql.Connection; +import java.sql.DriverManager; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +public class SecretCodeDAO { + private static final String DB_URL = "jdbc:h2:~/email_client_db"; + + public static void addSecretCode(String email, String secretCode) throws SQLException { + String sql = "INSERT INTO SecretCodes (email, secretCode) VALUES (?, ?)"; + + try (Connection connection = DriverManager.getConnection(DB_URL, "sa", ""); + PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, email); + stmt.setString(2, secretCode); + stmt.executeUpdate(); + System.out.println("Secret code added."); + } + } + + public static String getSecretCode(String email) throws SQLException { + String sql = "SELECT secretCode FROM SecretCodes WHERE email = ?"; + try (Connection connection = DriverManager.getConnection(DB_URL, "sa", ""); + PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, email); + ResultSet rs = stmt.executeQuery(); + return rs.next() ? rs.getString("secretCode") : null; + } + } + + public static void updateSecretCode(String email, String newSecretCode) throws SQLException { + String sql = "UPDATE SecretCodes SET secretCode = ? WHERE email = ?"; + try (Connection connection = DriverManager.getConnection(DB_URL, "sa", ""); + PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, newSecretCode); + stmt.setString(2, email); + stmt.executeUpdate(); + System.out.println("Secret code updated."); + } + } + + public static void deleteSecretCode(String email) throws SQLException { + String sql = "DELETE FROM SecretCodes WHERE email = ?"; + try (Connection connection = DriverManager.getConnection(DB_URL, "sa", ""); + PreparedStatement stmt = connection.prepareStatement(sql)) { + stmt.setString(1, email); + stmt.executeUpdate(); + System.out.println("Secret code deleted."); + } + } + + public static List getAllEntries() throws SQLException { + String sql = "SELECT * FROM SecretCodes"; + List list = new ArrayList<>(); + + try (Connection connection = DriverManager.getConnection(DB_URL, "sa", ""); + PreparedStatement stmt = connection.prepareStatement(sql); + ResultSet rs = stmt.executeQuery()) { + + while (rs.next()) { + String email = rs.getString("email"); + String secretCode = rs.getString("secretCode"); + list.add(new EmailSecretCode(email, secretCode)); + } + } + return list; + } +} diff --git a/src/main/java/com/secure_mailer/backend/ValidatorClient.java b/src/main/java/com/secure_mailer/backend/ValidatorClient.java new file mode 100644 index 0000000..d237f49 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/ValidatorClient.java @@ -0,0 +1,260 @@ +package com.secure_mailer.backend; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.*; +import java.sql.SQLException; +import java.io.*; + +import org.apache.commons.codec.binary.Base32; +import javax.crypto.Mac; +import javax.crypto.spec.SecretKeySpec; +import java.time.Instant; + +import javafx.animation.PauseTransition; +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.util.Duration; + +public class ValidatorClient { + + private Socket skt; + + private String fromEmailId; + private String toEmailId; + private String emlHash; + private String timeStamp; + private String authCode; + + + public ValidatorClient() { + try { + skt = new Socket(InetAddress.getByName(null), 2000); + } catch (IOException e) { + // TODO Auto-generated catch block + Platform.runLater(() -> showAlert("Error", "Failed to connet with server.")); + e.printStackTrace(); + } + + } + + + public ValidatorClient(String host, int port) { + try { + skt = new Socket(host, port); + } catch (IOException e) { + // TODO Auto-generated catch block + Platform.runLater(() -> showAlert("Error", "Failed to connet with server.")); + e.printStackTrace(); + } + } + + public void closeValidatorClient() { + try { + skt.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + + + public void sendRecord(String fromEmailId, String toEmailId, + String emlHash ) throws SQLException { + + this.fromEmailId = fromEmailId; + this.toEmailId = toEmailId; + this.emlHash = emlHash; + + PrintStream ps = null; + + try { + ps=new PrintStream(skt.getOutputStream()); + + + String secretKey = SecretCodeDAO.getSecretCode(toEmailId); + long timeStep = Instant.now().getEpochSecond() / 30; + this.timeStamp = Long.toString(timeStep); + this.authCode = generateTOTP(secretKey, timeStep); + + String[] data = new String[] { + this.fromEmailId, + this.toEmailId, + this.timeStamp, + this.authCode, + this.emlHash + }; + + System.out.println(this.fromEmailId); + System.out.println(this.toEmailId); + System.out.println(this.timeStamp); + System.out.println(this.authCode); + System.out.println(this.emlHash); + + String packet = formPacket(data); + + //Packet ready. + packet = String.valueOf(0) + packet; + + //Send the packet. + ps.println(packet); + + + // If successful, show the alert on the JavaFX thread + Platform.runLater(() -> showAlert("Message Sent", "Your message has been sent successfully!")); + + } catch(SQLException e) { + + Platform.runLater(() -> showAlert("Error", "Failed to retrieve Secret key.")); + e.printStackTrace(); + } + catch (IOException e) { + // TODO Auto-generated catch block + Platform.runLater(() -> showAlert("Error", "Failed to send the message.")); + e.printStackTrace(); + } + + + + } + + public boolean bringCode(String fromEmailId, String toEmailId, String emlHash) { + + this.fromEmailId = fromEmailId; + this.toEmailId = toEmailId; + this.emlHash = emlHash; + + PrintStream ps = null; + BufferedReader br= null; + + try { + ps=new PrintStream(skt.getOutputStream()); + br=new BufferedReader(new InputStreamReader(skt.getInputStream())); + + String[] data = new String[] { + this.emlHash + }; + + + String packet = formPacket(data); + + //Packet ready. + packet = String.valueOf(1) + packet; + + //Send the size of packet. + //ps.println(packet.length()); + + //Send the packet. + ps.println(packet); + + //Receive packet. + + String msg = br.readLine(); + + //Parse the packet. + int i = 0; + String num = ""; + for(; i < msg.length() ; i++ ) { + if( msg.charAt(i) != ':' ) + num += Character.toString(msg.charAt(i)); + else + break; + } + + + if( num.equals("420") ) { + Platform.runLater(() -> showAlert("Error", "Email record not found on server.")); + return false; + } + + this.timeStamp = num; + i = i + 1; + num = ""; + for(; i < msg.length() ; i++ ) { + num += Character.toString(msg.charAt(i)); + } + this.authCode = num; + + String secretKey = SecretCodeDAO.getSecretCode(fromEmailId); + String totp = generateTOTP( secretKey, Long.parseLong(this.timeStamp)); + + + + return (totp == this.authCode); + + } catch(SQLException e) { + + Platform.runLater(() -> showAlert("Error", "Failed to retrieve Secret key.")); + e.printStackTrace(); + return false; + } catch (IOException e) { + // TODO Auto-generated catch block + Platform.runLater(() -> showAlert("Error", "Failed to send communicate with server for authentication.")); + e.printStackTrace(); + return false; + } + + } + + private String formPacket(String[] data) { + + int dataSize = data.length; + + String packet = ""; + int stringSize; + for(int i = 0 ; i < dataSize ; i++ ) { + stringSize = data[i].length(); + packet += String.valueOf(stringSize) + ":" + data[i]; + } + + return packet; + } + + + public String generateTOTP(String secretKey, long timeStep) { + try { + Base32 base32 = new Base32(); + byte[] bytes = base32.decode(secretKey); + SecretKeySpec secretKeySpec = new SecretKeySpec(bytes, "HmacSHA1"); + Mac mac = Mac.getInstance("HmacSHA1"); + mac.init(secretKeySpec); + + // Current Unix time / 30 (TOTP time step) + //long timeStep = Instant.now().getEpochSecond() / 30; + byte[] data = new byte[8]; + for (int i = 7; timeStep > 0; i--) { + data[i] = (byte) (timeStep & 0xFF); + timeStep >>= 8; + } + + byte[] hash = mac.doFinal(data); + int offset = hash[hash.length - 1] & 0xF; + int otp = ((hash[offset] & 0x7F) << 24 | (hash[offset + 1] & 0xFF) << 16 | + (hash[offset + 2] & 0xFF) << 8 | (hash[offset + 3] & 0xFF)) % 1_000_000; + + return String.format("%06d", otp); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + private void showAlert(String title, String content) { + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(content); + alert.show(); + + // Create a PauseTransition for 10 seconds + PauseTransition delay = new PauseTransition(Duration.seconds(10)); + delay.setOnFinished(event -> alert.close()); // Close alert after 10 seconds + delay.play(); // Start the timer + } + +} + + + + diff --git a/src/main/java/com/secure_mailer/backend/service/EmailSendingService.java b/src/main/java/com/secure_mailer/backend/service/EmailSendingService.java new file mode 100644 index 0000000..a00aa23 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/service/EmailSendingService.java @@ -0,0 +1,106 @@ +package com.secure_mailer.backend.service; + +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.activation.FileDataSource; +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.Transport; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; +import com.secure_mailer.backend.EmailAccount; +import javafx.concurrent.Service; +import javafx.concurrent.Task; + +import javax.crypto.SecretKey; +import java.util.Base64; + +public class EmailSendingService extends Service { + + private EmailAccount emailAccount; + private String subject; + private String recipient; + private String content; + private List attachments = new ArrayList(); + //private SecretKey sKey; + + class SecretKeyToString { + public static String secretKeyToString(SecretKey secretKey) { + // Convert SecretKey to byte array and then to Base64 string + byte[] encodedKey = secretKey.getEncoded(); + return Base64.getEncoder().encodeToString(encodedKey); + } + } + + public EmailSendingService(EmailAccount emailAccount, String subject, String recipient, String content, List list + ,SecretKey sKey + ) { + this.emailAccount = emailAccount; + this.subject = subject; + this.recipient = recipient; + this.content = content; + this.attachments = list; + //this.sKey = sKey; + } + + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + try { + + MimeMessage mimeMessage = new MimeMessage(emailAccount.getSession()); + mimeMessage.setFrom(emailAccount.getAddress()); + mimeMessage.addRecipients(Message.RecipientType.TO, recipient); + mimeMessage.setSubject(subject); + + //Embedding Secret Key. +// MimeBodyPart customDataPart = new MimeBodyPart(); +// customDataPart.setText(SecretKeyToString.secretKeyToString(sKey), "UTF-8"); +// customDataPart.setHeader("Secret-Key", ""); + + Multipart multipart = new MimeMultipart(); + BodyPart messageBodyPart = new MimeBodyPart(); + messageBodyPart.setContent(content, "text/html"); + multipart.addBodyPart(messageBodyPart); + + + //Adding Secret Key to message. + //multipart.addBodyPart(customDataPart); + + mimeMessage.setContent(multipart); + + if(attachments.size()>0) { + for (File file: attachments) { + MimeBodyPart mimeBodyPart = new MimeBodyPart(); + DataSource source = new FileDataSource(file.getAbsolutePath()); + mimeBodyPart.setDataHandler(new DataHandler(source)); + mimeBodyPart.setFileName(file.getName()); + multipart.addBodyPart(mimeBodyPart); + } + } + + Transport transport = emailAccount.getSession().getTransport(); + transport.connect( + emailAccount.getProperties().getProperty("outgoingHost"), + emailAccount.getAddress(), + emailAccount.getPassword()); + transport.sendMessage(mimeMessage, mimeMessage.getAllRecipients()); + transport.close(); + } catch(MessagingException e) { + e.printStackTrace(); + } catch (Exception e) { + e.printStackTrace(); + } return null; + } + }; + } + +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/service/FetchFolderService.java b/src/main/java/com/secure_mailer/backend/service/FetchFolderService.java new file mode 100644 index 0000000..f83a901 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/service/FetchFolderService.java @@ -0,0 +1,102 @@ +package com.secure_mailer.backend.service; + +import java.util.ArrayList; + +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Store; +import javax.mail.event.MessageCountEvent; +import javax.mail.event.MessageCountListener; +import com.secure_mailer.frontend.FolderTreeItem; +import com.secure_mailer.frontend.IconResolver; +import javafx.concurrent.Service; +import javafx.concurrent.Task; + +public class FetchFolderService extends Service{ + private ArrayList folderList; + private FolderTreeItem foldersRoot; + private Store store; + + + public FetchFolderService(Store store, FolderTreeItem foldersRoot, ArrayList folderList) { + this.store = store; + this.foldersRoot = foldersRoot; + this.folderList = folderList; + } + + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + fetchFolders(); + return null; + } + }; + } + + private void fetchFolders() throws MessagingException { + Folder[] folders = store.getDefaultFolder().list(); + handleFolders(folders, foldersRoot); + } + + private void handleFolders(Folder[] folders, FolderTreeItem foldersRoot) throws MessagingException { + for(Folder folder: folders) { + folderList.add(folder); + FolderTreeItem folderTreeItem = new FolderTreeItem(folder); + folderTreeItem.setGraphic(IconResolver.getIcon(folder.getName())); + foldersRoot.getChildren().add(folderTreeItem); + foldersRoot.setExpanded(true); + fetchMessagesOnFolder(folderTreeItem); + addMessageListenerToFolder(folder, folderTreeItem); + if (folder.getType() == Folder.HOLDS_FOLDERS) { + Folder[] subFolders = folder.list(); + handleFolders(subFolders, folderTreeItem); + } + } + } + + private void addMessageListenerToFolder(Folder folder, FolderTreeItem folderTreeItem) { + folder.addMessageCountListener(new MessageCountListener() { + + @Override + public void messagesAdded(MessageCountEvent e) { + for(int i = 0; i < e.getMessages().length; i++) { + try { + Message message = folder.getMessage(folder.getMessageCount() - i); + folderTreeItem.addEmailToTop(message); + } catch (MessagingException ex) { + ex.printStackTrace(); + } + } + } + @Override + public void messagesRemoved(MessageCountEvent e) {} + }); + } + + private void fetchMessagesOnFolder(FolderTreeItem folderTreeItem) { + Folder folder = folderTreeItem.getFolder(); + Service fetchMessagesService = new Service() { + + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + if(folder.getType() != Folder.HOLDS_FOLDERS) { + folder.open(Folder.READ_WRITE); + int folderSize = folder.getMessageCount(); + for(int i = folderSize; i > 0; i--) { + folderTreeItem.addEmail(folder.getMessage(i)); + } + } + return null; + } + }; + } + }; + fetchMessagesService.start(); + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/service/LoginService.java b/src/main/java/com/secure_mailer/backend/service/LoginService.java new file mode 100644 index 0000000..15c3c4b --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/service/LoginService.java @@ -0,0 +1,44 @@ +package com.secure_mailer.backend.service; + +import javax.mail.Authenticator; +import javax.mail.MessagingException; +import javax.mail.NoSuchProviderException; +import javax.mail.PasswordAuthentication; +import javax.mail.Session; +import javax.mail.Store; +import com.secure_mailer.backend.EmailAccount; + +public class LoginService { + + private EmailAccount emailAccount; + + public LoginService(EmailAccount emailAccount) { + this.emailAccount = emailAccount; + login(); + } + + private void login() { + Authenticator authenticator = new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(emailAccount.getAddress(), emailAccount.getPassword()); + } + }; + + Session session = Session.getInstance(emailAccount.getProperties(), authenticator); + emailAccount.setSession(session); + + try { + Store store = session.getStore("imaps"); + store.connect(emailAccount.getProperties().getProperty("incomingHost"), + emailAccount.getAddress(), + emailAccount.getPassword()); + emailAccount.setStore(store); + + } catch (NoSuchProviderException e) { + e.printStackTrace(); + } catch (MessagingException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/backend/service/MessageRendererService.java b/src/main/java/com/secure_mailer/backend/service/MessageRendererService.java new file mode 100644 index 0000000..053d559 --- /dev/null +++ b/src/main/java/com/secure_mailer/backend/service/MessageRendererService.java @@ -0,0 +1,165 @@ +package com.secure_mailer.backend.service; + +import java.io.IOException; +import java.security.InvalidKeyException; +import java.security.NoSuchAlgorithmException; +import java.util.Base64; + +import javax.crypto.BadPaddingException; +import javax.crypto.Cipher; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.KeyGenerator; +import javax.crypto.NoSuchPaddingException; +import javax.crypto.SecretKey; + +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.internet.MimeBodyPart; +import com.secure_mailer.frontend.EmailMessage; +import javafx.concurrent.Service; +import javafx.concurrent.Task; + +public class MessageRendererService extends Service{ + private EmailMessage emailMessage; + private StringBuffer stringBuffer; +// private boolean isAuthenticated; + + public MessageRendererService(StringBuffer stringBuffer) { + this.stringBuffer = stringBuffer; +// this.isAuthenticated = false; + } + + public MessageRendererService(EmailMessage email) { + this.emailMessage = email; + this.stringBuffer = new StringBuffer(); +// this.isAuthenticated = false; + } + + @Override + protected Task createTask() { + try { loadMessage(); } + catch (Exception e) { e.printStackTrace(); } + return new Task() { + @Override + protected Object call() throws Exception { return null; } + }; + } + + private void loadMessage() throws MessagingException, IOException { + if (emailMessage.getMessage().isExpunged()) {this.cancel();} + stringBuffer.setLength(0); + Message message = emailMessage.getMessage(); + String contentType = message.getContentType(); + if(isSimpleType(contentType)){ + + if( emailMessage.getIsAuthenticated() ) + stringBuffer.append(message.getContent().toString()); + else + stringBuffer.append(encryptMessage(message.getContent().toString())); + + } else if (isMultipartType(contentType)) { + Multipart multipart = (Multipart) message.getContent(); + loadMultipart(multipart, stringBuffer); + } emailMessage.setDemoMessage(getDemoMessage()); + } + + private void loadMultipart(Multipart multipart, StringBuffer stringBuffer) throws MessagingException, IOException { + for (int i = multipart.getCount() - 1; i >=0; i--) { + BodyPart bodyPart = multipart.getBodyPart(i); + String contentType = bodyPart.getContentType(); + if (isSimpleType(contentType)) { + + if( emailMessage.getIsAuthenticated() ) + stringBuffer.append(bodyPart.getContent().toString()); + else + stringBuffer.append(encryptMessage(bodyPart.getContent().toString())); + + } else if (isMultipartType(contentType)){ + Multipart multipart2 = (Multipart) bodyPart.getContent(); + loadMultipart(multipart2,stringBuffer); + } else if (!isTextPlain(contentType)) { + MimeBodyPart mbp = (MimeBodyPart) bodyPart; + if (!emailMessage.isAttachmentLoaded())emailMessage.addAttachment(mbp); + } + } + } + + private boolean isTextPlain(String contentType) { + return contentType.contains("TEXT/PLAIN"); + } + + private boolean isSimpleType(String contentType) { + if(contentType.contains("TEXT/HTML") || + contentType.contains("mixed") || + contentType.contains("text")) { + return true; + } else return false; + } + + private boolean isMultipartType(String contentType) { + if (contentType.contains("multipart"))return true; + else return false; + } + + private String getDemoMessage() { + String content = stringBuffer.toString(); + content = content.replaceAll("\\<.*?\\>", ""); + content = content.replaceAll("[.].*[{].*[}]", ""); + content = content.replaceAll("\\ ", " "); + content = content.replaceAll("[/]", ""); + content = content.replaceAll("\s+|\\v+|\\h+", " "); + content = content.replaceAll("[<][!][-][-].*[-][-][>]", ""); + content = content.replaceAll("[@].*[{].*[}]", ""); + content = content.replaceAll("[a-z]+[.][a-zA-Z]+\\h*[{].*[}]", ""); + content = content.replaceAll("[a-z]+[{].*[}]",""); + content = content.replaceAll("[*]\\h*[{].*[}]",""); + content = content.strip(); + if (content.length() > 100)content = content.substring(0, 100); + if (content == null)content = ""; + return content; + } + + public StringBuffer getStringBuffer() { return stringBuffer; } + + public void setEmailMessage(EmailMessage emailMessage) { this.emailMessage = emailMessage; } + +// public void setIsAuthenticated(boolean isAuthenticated) { this.isAuthenticated = isAuthenticated; } + + private String encryptMessage(String message) { + // Generate AES key + KeyGenerator keyGen; + String encryptedText = ""; + try { + keyGen = KeyGenerator.getInstance("AES"); + + keyGen.init(128); // You can also use 192 or 256-bit key size + SecretKey secretKey = keyGen.generateKey(); + + // Initialize Cipher for encryption + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + + byte[] encryptedBytes; + + encryptedBytes = cipher.doFinal(message.getBytes()); + + // Convert encrypted bytes to a readable format + encryptedText = Base64.getEncoder().encodeToString(encryptedBytes); + + } catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | IllegalBlockSizeException | BadPaddingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + return encryptedText; + // Initialize Cipher for decryption +// cipher.init(Cipher.DECRYPT_MODE, secretKey); +// byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText)); +// String decryptedText = new String(decryptedBytes); +// System.out.println("Decrypted Text: " + decryptedText); + + } + +} diff --git a/src/main/java/com/secure_mailer/frontend/Attachment.java b/src/main/java/com/secure_mailer/frontend/Attachment.java new file mode 100644 index 0000000..5b34fa2 --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/Attachment.java @@ -0,0 +1,50 @@ +package com.secure_mailer.frontend; + +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javafx.concurrent.Service; +import javafx.concurrent.Task; +import javafx.scene.image.Image; +import com.secure_mailer.backend.EmailManager; + +public class Attachment { + + private MimeBodyPart mbp; + private Image image; + private String name; + private String downloadPath; + + public Attachment(MimeBodyPart mbp) { + this.mbp = mbp; + name = getName(); + downloadPath = EmailManager.getDownloadPath() + name; + } + + public MimeBodyPart getMBP() { return mbp; } + public void setImage(Image image) { this.image = image; } + public Image getImage() { return image; } + public String getDownloadPath() { return downloadPath; } + + public String getName() { + String name = null; + try { name = mbp.getFileName(); } + catch (MessagingException e) { e.printStackTrace(); } + return name; + } + + public void downloadAttachment() { + Service service = new Service<>() { + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + mbp.saveFile(downloadPath); + return null; + } + }; + } + }; + service.start(); + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/frontend/AttachmentCell.java b/src/main/java/com/secure_mailer/frontend/AttachmentCell.java new file mode 100644 index 0000000..626a634 --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/AttachmentCell.java @@ -0,0 +1,74 @@ +package com.secure_mailer.frontend; + +import java.io.IOException; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javafx.concurrent.Service; +import javafx.concurrent.Task; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.Tooltip; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; + +public class AttachmentCell extends ListCell { + + @FXML private Label attachmentName; + @FXML private ImageView attachmentImg; + private Image thumbnail; + + public AttachmentCell() { loadFXML(); } + + private void loadFXML() { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/attachment_cell.fxml")); + loader.setController(this); + loader.setRoot(this); + loader.load(); + } + catch (IOException e) { + e.getMessage(); + e.printStackTrace(); + } + } + + @Override + protected void updateItem(Attachment item, boolean empty) { + super.updateItem(item, empty); + if(empty) { + setText(null); + setContentDisplay(ContentDisplay.TEXT_ONLY); + } else { + setContentDisplay(ContentDisplay.GRAPHIC_ONLY); + Attachment attachment = this.getItem(); + String name = attachment.getName(); + attachmentName.setText(name); + this.setTooltip( new Tooltip(name)); + + if (attachment.getImage() == null) { + MimeBodyPart mbp = attachment.getMBP(); + try { + if (mbp.getContentType().contains("IMAGE")) { + Service addImgService = new Service() { + @Override + protected Task createTask() { + return new Task() { + @Override + protected Void call() throws Exception { + thumbnail = new Image(mbp.getInputStream()); + attachment.setImage(thumbnail); + return null; + }}; + } + }; + addImgService.setOnSucceeded(e -> { if (thumbnail != null)attachmentImg.setImage(thumbnail); }); + addImgService.start(); + } + } catch (MessagingException e) { e.printStackTrace(); } + } else { attachmentImg.setImage(attachment.getImage()); } + } + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/frontend/EmailCell.java b/src/main/java/com/secure_mailer/frontend/EmailCell.java new file mode 100644 index 0000000..6846896 --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/EmailCell.java @@ -0,0 +1,89 @@ +package com.secure_mailer.frontend; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import com.secure_mailer.backend.service.MessageRendererService; +import javafx.fxml.FXML; +import javafx.fxml.FXMLLoader; +import javafx.scene.control.ContentDisplay; +import javafx.scene.control.ContextMenu; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.MenuItem; +import javafx.scene.control.TextArea; +import javafx.scene.image.ImageView; +import javafx.scene.layout.Pane; + +public class EmailCell extends ListCell{ + + @FXML private Label sender; + @FXML private Label date; + @FXML private Label title; + @FXML private Pane selected; + @FXML private TextArea message; + @FXML private ImageView attachment; + private MenuItem markUnread = new MenuItem("mark as unread"); + private static SimpleDateFormat dateFormat = new SimpleDateFormat("MMM d"); + + public EmailCell() { loadFXML(); } + + private void loadFXML() { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/email_cell.fxml")); + loader.setController(this); + loader.setRoot(this); + loader.load(); + } + catch (IOException e) { + e.getMessage(); + e.printStackTrace(); + } + } + + @Override + protected void updateItem(EmailMessage item, boolean empty) { + super.updateItem(item, empty); + if(empty) { + setText(null); + setContentDisplay(ContentDisplay.TEXT_ONLY); + } else { + setContentDisplay(ContentDisplay.GRAPHIC_ONLY); + if (!item.getMessage().isExpunged()) { + MessageRendererService mrs = new MessageRendererService(item); + mrs.setOnSucceeded(e -> { + sender.setText(item.getSender().replaceAll("[<].*[>]", "")); + title.setText(item.getTitle()); + date.setText(dateFormat.format(item.getDate())); + makeBoldRows(!item.isRead()); + + if (item.hasAttachment())attachment.setVisible(true); + else attachment.setVisible(false); + + if(item.getDemoMessage() != null)message.setText(item.getDemoMessage()); + }); + mrs.start(); + } + + this.setOnMouseClicked(e -> { + item.setRead(true); + makeBoldRows(false); + }); + + this.setContextMenu(new ContextMenu(markUnread)); + markUnread.setOnAction(e -> { + item.setRead(false); + makeBoldRows(true); + }); + } + } + + private void makeBoldRows(boolean b) { + String style = ""; + if(b)style = "-fx-font-weight:bold;\n-fx-text-fill:black;"; + sender.setStyle(style); + date.setStyle(style); + message.setStyle(style); + } + + public void setSelectedIcon(boolean b) { this.selected.setVisible(b); } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/frontend/EmailMessage.java b/src/main/java/com/secure_mailer/frontend/EmailMessage.java new file mode 100644 index 0000000..016b9dd --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/EmailMessage.java @@ -0,0 +1,122 @@ +package com.secure_mailer.frontend; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.internet.MimeBodyPart; +import javax.mail.Address; +import javax.mail.internet.InternetAddress; +import javafx.beans.property.SimpleObjectProperty; +import javafx.beans.property.SimpleStringProperty; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.util.Base64; + +import javax.mail.BodyPart; + +import javax.mail.Multipart; + +public class EmailMessage { + private SimpleStringProperty sender; + private SimpleObjectProperty date; + private SimpleStringProperty title; + private boolean selected = false; + private Message message; + private String demoMessage; + private List attachmentList = new ArrayList(); + private boolean attachmentLoaded = false; + private boolean isRead; + private SecretKey sKey; + private boolean isAuthenticated; + + class StringToSecretKey { + public static SecretKey stringToSecretKey(String encodedKey) { + byte[] decodedKey = Base64.getDecoder().decode(encodedKey); + return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES"); // Replace "AES" with the appropriate algorithm + } + } + + public String extractCustomDataFromEmail(Message message) throws MessagingException, IOException { + if (message.isMimeType("multipart/*")) { + Multipart multipart = (Multipart) message.getContent(); + + for (int i = 0; i < multipart.getCount(); i++) { + BodyPart part = multipart.getBodyPart(i); + + if ("".equals(part.getHeader("Secret-Key")[0])) { + // Extract custom data + String customData = (String) part.getContent(); + return customData; + } + } + } + return null; // Return null if no custom data found + } + + public EmailMessage(String sender, Date date, String title, Message msg, boolean isRead) { + this.sender = new SimpleStringProperty(sender); + this.date = new SimpleObjectProperty(date); + this.title = new SimpleStringProperty(title); + + this.message = msg; + this.isRead = isRead; + + this.isAuthenticated = false; + } + + public String getFromEmailID() { + Address[] senderAddresses; + try { + senderAddresses = this.message.getFrom(); + String senderEmail = ""; + if (senderAddresses != null && senderAddresses.length > 0) { + InternetAddress senderAddress = (InternetAddress) senderAddresses[0]; + senderEmail = senderAddress.getAddress(); +// System.out.println("Sender Email: " + senderEmail); + } + + return senderEmail; + } catch (MessagingException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return ""; + } // or message.getSender() + + + } + + public void setIsAuthenticated(boolean isAuth) { this.isAuthenticated = isAuth; } + public boolean getIsAuthenticated() { return this.isAuthenticated; } + public SecretKey getSecretKey() { return sKey; } + public String getSender() { return sender.get(); } + public Date getDate() { return date.get(); } + public String getTitle() { return title.get(); } + public Message getMessage() { return message; } + public String getDemoMessage() { return demoMessage; } + public List getAttachments() { return attachmentList; } + public boolean isAttachmentLoaded() { return attachmentLoaded; } + public void setAttachmentLoaded() { attachmentLoaded = true; } + public void setDemoMessage(String demo) { this.demoMessage = demo; } + public void setSelected(boolean b) { selected = b; } + public void setRead(boolean b) { isRead = b; } + public boolean isRead() { return isRead; } + public boolean isSelected() { return selected; } + public boolean hasAttachment() { return !attachmentList.isEmpty(); } + + public synchronized void addAttachment(MimeBodyPart mbp) { + Attachment attachment = new Attachment(mbp); + if (attachment.getName() != null) { + if (!attachmentList.isEmpty()) { + for (Attachment a : attachmentList) { + if (a == null || !a.getName().equals(attachment.getName()))continue; + else {return;} + } + } + attachmentList.add(attachment); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/frontend/FolderTreeItem.java b/src/main/java/com/secure_mailer/frontend/FolderTreeItem.java new file mode 100644 index 0000000..dd15e2a --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/FolderTreeItem.java @@ -0,0 +1,62 @@ +package com.secure_mailer.frontend; + +import javax.mail.Flags; +import javax.mail.Folder; +import javax.mail.Message; +import javax.mail.MessagingException; +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.scene.control.TreeItem; + +public class FolderTreeItem extends TreeItem{ + + private String name; + private Folder folder; + private ObservableList emails; + + public FolderTreeItem() { + super(""); + this.name = ""; + } + + public FolderTreeItem(String name) { + super(name); + this.name = name; + } + + public FolderTreeItem(Folder folder) { + super(folder.getName()); + emails = FXCollections.observableArrayList(); + this.name = folder.getName(); + this.folder = folder; + } + + public void addEmail(Message message) { + EmailMessage email = fetchMessage(message); + addEmail(email); + } + + private EmailMessage fetchMessage(Message message) { + EmailMessage email = null; + try { + boolean messageIsRead = message.getFlags().contains(Flags.Flag.SEEN); + email = new EmailMessage( + message.getFrom()[0].toString(), + message.getSentDate(), + message.getSubject(), + message, + messageIsRead); + } catch (MessagingException e) { e.printStackTrace(); } + return email; + } + + public void addEmailToTop(Message message) { + EmailMessage emailMessage = fetchMessage(message); + emails.add(0, emailMessage); + } + + public Folder getFolder() { return folder; } + public ObservableList getEmailMessages() { return emails; } + public String toString() { return name; } + private void addEmail(EmailMessage email) { emails.add(email); } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/frontend/IconResolver.java b/src/main/java/com/secure_mailer/frontend/IconResolver.java new file mode 100644 index 0000000..aba5319 --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/IconResolver.java @@ -0,0 +1,32 @@ +package com.secure_mailer.frontend; + +import javafx.scene.Node; +import javafx.scene.image.ImageView; + +public class IconResolver { + + public static Node getIcon(String name) { + name = name.toLowerCase(); + ImageView imageView = new ImageView(); + imageView.setFitWidth(16); + imageView.setFitHeight(16); + + try { + if(name.contains("gmail"))imageView.setId("gmail-folder"); + else if (name.contains("inbox"))imageView.setId("inbox-folder"); + else if (name.contains("all"))imageView.setId("all-folder"); + else if (name.contains("sent"))imageView.setId("sent-folder"); + else if (name.contains("spam"))imageView.setId("spam-folder"); + else if (name.contains("important"))imageView.setId("important-folder"); + else if (name.contains("draft"))imageView.setId("draft-folder"); + else if (name.contains("star"))imageView.setId("star-folder"); + else if (name.contains("trash"))imageView.setId("trash-folder"); + else if (name.contains("paper-clip")) { + imageView.setId("paper-clip"); + imageView.setFitWidth(23); + imageView.setFitHeight(23); + } else imageView.setId("mail-folder"); + } catch (Exception e) { e.printStackTrace(); return null; } + return imageView; + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/frontend/MainWindowController.java b/src/main/java/com/secure_mailer/frontend/MainWindowController.java new file mode 100644 index 0000000..678b7e6 --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/MainWindowController.java @@ -0,0 +1,599 @@ +package com.secure_mailer.frontend; + +import java.awt.Desktop; + +import java.io.File; +import java.net.URL; +import java.security.NoSuchAlgorithmException; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.ResourceBundle; +import com.secure_mailer.backend.service.EmailSendingService; +import com.secure_mailer.backend.service.MessageRendererService; + +import com.secure_mailer.backend.BaseController; +import com.secure_mailer.backend.DatabaseSetup; +import com.secure_mailer.backend.EmailManager; +import com.secure_mailer.backend.SecretCodeDAO; +import com.secure_mailer.backend.ValidatorClient; +import com.secure_mailer.backend.EmailAccount; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.Label; +import javafx.scene.control.ListCell; +import javafx.scene.control.ListView; +import javafx.scene.control.TextField; +import javafx.scene.control.TreeView; +import javafx.scene.image.ImageView; +import javafx.scene.layout.AnchorPane; +import javafx.scene.shape.Line; +import javafx.scene.web.HTMLEditor; +import javafx.scene.web.WebView; +import javafx.util.Callback; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.activation.FileDataSource; +import javax.crypto.Cipher; +import javax.crypto.KeyGenerator; +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; + +import java.util.Base64; +import javafx.stage.FileChooser; + +import javafx.animation.PauseTransition; +//import javafx.scene.control.Alert; +//import javafx.scene.control.Alert.AlertType; +//import javafx.util.Duration; +//import javafx.application.Platform; + +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +import javax.mail.BodyPart; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import java.util.List; + +import javafx.fxml.FXMLLoader; +import javafx.scene.Scene; +import javafx.stage.Stage; + +import javafx.application.Platform; +import javafx.scene.control.Alert; +import javafx.scene.control.Alert.AlertType; +import javafx.util.Duration; + +//import java.util.concurrent.atomic.AtomicBoolean; + + +public class MainWindowController extends BaseController implements Initializable { + + @FXML private TreeView folderSelection; + @FXML private ListView emailSelection; + @FXML private ListView attachmentList; + @FXML private AnchorPane messagePane; + @FXML private Label messageTitle; + @FXML private Label messageSenderName; + @FXML private Label messageAttachmentLabel; + @FXML private Label messageDate; + @FXML private WebView messageViewShort; + @FXML private WebView messageViewLong; + @FXML private ImageView defaultMessageViewBG; + @FXML private Label userNameLabel; + @FXML private AnchorPane composePane; + @FXML private TextField composeTo; + @FXML private TextField composeTitle; + @FXML private HTMLEditor htmlEditor; + @FXML private Line footerDiv; + @FXML private ImageView composeAttachIcon; + private static SimpleDateFormat dateFormat = new SimpleDateFormat("M'/'d'/'YYYY H:mm"); + private ArrayList attachments = new ArrayList(); + private MessageRendererService mrs; + private EmailManager emailManager; + private StringBuffer stringBuffer; + private String htmlBackup; + private SecretKey sKey; + private String fromEmailID; + + public MainWindowController(EmailManager emailManager, String fromEmailID) { + super("/fxml/main.fxml", emailManager); + this.emailManager = emailManager; + this.stringBuffer = new StringBuffer(); + this.fromEmailID = fromEmailID; + } + + @Override + public void initialize(URL location, ResourceBundle resources) { + + emailSelection.setCellFactory(new Callback, ListCell>(){ + @Override + public ListCell call(ListView param) { return new EmailCell(); } + }); + + attachmentList.setCellFactory(new Callback, ListCell>(){ + @Override + public ListCell call(ListView param) { return new AttachmentCell(); } + }); + + htmlBackup = htmlEditor.getHtmlText(); + messageAttachmentLabel.setGraphic(IconResolver.getIcon("paper-clip")); + userNameLabel.setText(emailManager.getEmailAccount().getAddress()); + userNameLabel.setText("email.account@gmail.com"); + setUpMRS(); + setUpFolderSelection(); + setUpMessageSelection(); + setUpAttachmentSelection(); + + DatabaseSetup.setupDatabase(); + } + + private void setUpMRS() { mrs = new MessageRendererService(stringBuffer); } + + private void setUpFolderSelection() { + folderSelection.setRoot(emailManager.getFolderRoot()); + folderSelection.setShowRoot(false); + folderSelection.setOnMouseClicked(e -> { + FolderTreeItem item = (FolderTreeItem)folderSelection.getSelectionModel().getSelectedItem(); + if(item != null) { + emailManager.setSelectedFolder(item); + emailSelection.setItems(item.getEmailMessages()); + } + }); + } + +// private void setUpMessageSelection() { +// emailSelection.setOnMouseClicked(event -> { +// attachmentList.getItems().clear(); +// EmailMessage emailMessage = emailSelection.getSelectionModel().getSelectedItem(); +// +// if (emailMessage != null) { +// // Start a new thread for TCP communication +// +// new Thread(() -> { +// +// AtomicBoolean isAuthenticated = new AtomicBoolean(true); +// +// +// if( emailMessage.getFromEmailID().equals(this.fromEmailID + "@peachy.in.net") == false) { +// String fromEmailId = emailMessage.getSender(); +// String toEmailId = emailManager.getEmailAccount().getAddress(); +// String emlHash = generateEmlHash(emailMessage.getMessage(), emailMessage.getSecretKey()); +// +// ValidatorClient receiver = new ValidatorClient("peachy.in.net",2001); +// isAuthenticated.set(receiver.bringCode(fromEmailId, toEmailId, emlHash)); +// } +// // Check if the details are authenticated +//// if (isAuthenticated) { +// // Update the email manager and message view +// emailManager.setSelectedMessage(emailMessage); +// +// Platform.runLater(() -> { +// if (!composePane.isVisible()) setMessageViewVisible(true); +// mrs.setEmailMessage(emailMessage); +// mrs.setOnSucceeded(e -> { +// if (emailMessage.hasAttachment()) { +// messageViewShort.getEngine().loadContent(stringBuffer.toString()); +// setAttachmentView(true); +// emailMessage.setAttachmentLoaded(); +// +// if (isAuthenticated.get()) { +// +// loadAttachments(); +// +// } else { +// // Show authentication failure message +// Platform.runLater(() -> showAlert("Authentication Failed", "Unable to authenticate details from the server.")); +// } +// +// } else { +// +// if (isAuthenticated.get()) { +// messageViewLong.getEngine().loadContent(stringBuffer.toString()); +// setAttachmentView(false); +// +// } else { +// // Show authentication failure message +// Platform.runLater(() -> showAlert("Authentication Failed", "Unable to authenticate details from the server.")); +// } +// } +// }); +// mrs.restart(); +// messageSenderName.setText(emailMessage.getSender().replaceAll("lis.email.ttest@gmail.com", "email.account@gmail.com")); +// messageTitle.setText(emailMessage.getTitle()); +// messageDate.setText(dateFormat.format(emailMessage.getDate())); +// +// }); +//// } else { +//// // Show authentication failure message +//// Platform.runLater(() -> showAlert("Authentication Failed", "Unable to authenticate details from the server.")); +//// } +// }).start(); +// } +// }); +// } + + private void setUpMessageSelection() { + emailSelection.setOnMouseClicked(event -> { + attachmentList.getItems().clear(); + EmailMessage emailMessage = emailSelection.getSelectionModel().getSelectedItem(); + + if(emailMessage != null) { + emailManager.setSelectedMessage(emailMessage); + if (!composePane.isVisible())setMessageViewVisible(true); + mrs.setEmailMessage(emailMessage); + mrs.setOnSucceeded(e -> { + if(emailMessage.hasAttachment()) { + messageViewShort.getEngine().loadContent(stringBuffer.toString()); + setAttachmentView(true); + emailMessage.setAttachmentLoaded(); + loadAttachments(); + } else { + messageViewLong.getEngine().loadContent(stringBuffer.toString()); + setAttachmentView(false); + } + }); + mrs.restart(); + messageSenderName.setText(emailMessage.getSender().replaceAll("lis.email.ttest@gmail.com", "email.account@gmail.com")); + messageTitle.setText(emailMessage.getTitle()); + messageDate.setText(dateFormat.format(emailMessage.getDate())); + } + }); + } + + @FXML + void decryptEmail() { + + attachmentList.getItems().clear(); + EmailMessage emailMessage = emailSelection.getSelectionModel().getSelectedItem(); + + boolean isAuthenticated = false; + if( emailMessage.getFromEmailID().equals(this.fromEmailID + "@peachy.in.net") == false) { + String fromEmailId = emailMessage.getSender(); + String toEmailId = emailManager.getEmailAccount().getAddress(); + String emlHash = generateEmlHash(emailMessage.getMessage(), emailMessage.getSecretKey()); + + ValidatorClient receiver = new ValidatorClient("peachy.in.net",2001); + isAuthenticated = receiver.bringCode(fromEmailId, toEmailId, emlHash); + } + else { + isAuthenticated = true; + } + + emailMessage.setIsAuthenticated(isAuthenticated); + + if(emailMessage != null) { + if (isAuthenticated) { + emailManager.setSelectedMessage(emailMessage); + if (!composePane.isVisible())setMessageViewVisible(true); + mrs.setEmailMessage(emailMessage); + mrs.setOnSucceeded(e -> { + if(emailMessage.hasAttachment()) { + messageViewShort.getEngine().loadContent(stringBuffer.toString()); + setAttachmentView(true); + emailMessage.setAttachmentLoaded(); + loadAttachments(); + } else { + messageViewLong.getEngine().loadContent(stringBuffer.toString()); + setAttachmentView(false); + } + }); + mrs.restart(); + messageSenderName.setText(emailMessage.getSender().replaceAll("lis.email.ttest@gmail.com", "email.account@gmail.com")); + messageTitle.setText(emailMessage.getTitle()); + messageDate.setText(dateFormat.format(emailMessage.getDate())); + } + else { + //Show authentication failure message + Platform.runLater(() -> showAlert("Authentication Failed", "Unable to authenticate details from the server.")); + } + } + + emailMessage.setIsAuthenticated(false); + } + + private void showAlert(String title, String content) { + Alert alert = new Alert(AlertType.INFORMATION); + alert.setTitle(title); + alert.setHeaderText(null); + alert.setContentText(content); + alert.show(); + + // Create a PauseTransition for 10 seconds + PauseTransition delay = new PauseTransition(Duration.seconds(10)); + delay.setOnFinished(event -> alert.close()); // Close alert after 10 seconds + delay.play(); // Start the timer + } + + private void setUpAttachmentSelection() { + attachmentList.setOnMouseClicked(e -> { + Attachment selected = attachmentList.getSelectionModel().getSelectedItem(); + attachmentList.getSelectionModel().clearSelection(); + if (selected != null) { + File attachment = new File(selected.getDownloadPath()); + if (!attachment.exists())selected.downloadAttachment(); + else { + Desktop desktop = Desktop.getDesktop(); + try { desktop.open(attachment); } + catch (Exception exp) { exp.printStackTrace(); } + } + } + }); + } + + @FXML + void composeCancel() { + setComposeViewVisible(false); + if (!messageSenderName.getText().isBlank())setMessageViewVisible(true); + } + + @FXML + void composeKeyPressed() { + setMessageViewVisible(false); + setComposeViewVisible(true); + } + + @FXML + void composeSendPressed() { + + String toId = composeTo.getText(); + String secretKey = ""; + + try { + secretKey = SecretCodeDAO.getSecretCode(toId); + } catch (SQLException e) { + // TODO Auto-generated catch block + + KeyGenerator keyGen; + SecretKey stKey = null; + + try { + keyGen = KeyGenerator.getInstance("AES"); + keyGen.init(128); // You can also use 192 or 256-bit key size + stKey = keyGen.generateKey(); + } catch (NoSuchAlgorithmException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + secretKey = SecretKeyToString.secretKeyToString(stKey); + e.printStackTrace(); + } + + String emlHash = generateEmlHash( + emailManager.getEmailAccount(), + composeTitle.getText(), + toId, + htmlEditor.getHtmlText(), + attachments, + secretKey); + + EmailSendingService emailSenderService = new EmailSendingService( + emailManager.getEmailAccount(), + composeTitle.getText(), + toId, + htmlEditor.getHtmlText(), + attachments, + this.sKey); + + + emailSenderService.setOnSucceeded(e -> { + + String fromEmailId = emailManager.getEmailAccount().getAddress(); + String toEmailId = toId; + + ValidatorClient sender = new ValidatorClient("peachy.in.net", 2000); + + try { + sender.sendRecord(fromEmailId, toEmailId, emlHash); + } catch (SQLException e1) { + // TODO Auto-generated catch block + e1.printStackTrace(); + } + + }); + + + emailSenderService.start(); + setComposeViewVisible(false); + composeAttachIcon.setVisible(false); + composeTitle.clear(); + composeTo.clear(); + htmlEditor.setHtmlText(htmlBackup); + if (!messageSenderName.getText().isBlank())setMessageViewVisible(true); + } + + @FXML + void addAttachment() { + FileChooser fileChooser = new FileChooser(); + File selectedFile = fileChooser.showOpenDialog(null); + if(selectedFile != null){ + attachments.add(selectedFile); + composeAttachIcon.setVisible(true); + } + } + + @FXML + private void openCRUDWindow() { + try { + FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/crud_window.fxml")); + Stage stage = new Stage(); + stage.setScene(new Scene(loader.load())); + stage.setTitle("Manage Secret Codes"); + stage.show(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void loadAttachments() { + EmailMessage emailMessage = emailManager.getSelectedMessage(); + if (emailMessage != null && emailMessage.hasAttachment()) { + ObservableList attachments = FXCollections.observableArrayList(emailMessage.getAttachments()); + attachmentList.getItems().addAll(attachments); + attachmentList.setVisible(true); + } else { attachmentList.setVisible(false); } + } + + private void setAttachmentView(boolean b) { + messageViewLong.setVisible(!b); + messageViewShort.setVisible(b); + footerDiv.setVisible(b); + messageAttachmentLabel.setVisible(b); + attachmentList.setVisible(b); + } + + private void setMessageViewVisible(boolean b) { + messagePane.setVisible(b); + defaultMessageViewBG.setVisible(!b); + } + + private void setComposeViewVisible(boolean b) { + composePane.setVisible(b); + defaultMessageViewBG.setVisible(!b); + } + + @FXML + void starKeyAction() {} + + @FXML + void trashKeyAction() {} + + public String MessageToString(Message Message) throws MessagingException, IOException { + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + Message.writeTo(outputStream); + return outputStream.toString("UTF-8"); // Specify encoding if needed + } + + private String generateEmlHash(Message message, SecretKey key) { + try { + + String msg = MessageToString(message); + String encryptMessage = encryptMessage(msg, key); + + return encryptMessage; + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return ""; + } + } + + + private String generateEmlHash(EmailAccount emailAccount, String subject, + String recipient, + String content, + List attachments, + String secretKey){ + + String message; + try { + + MimeMessage mimeMessage = new MimeMessage(emailAccount.getSession()); + mimeMessage.setFrom(emailAccount.getAddress()); + mimeMessage.addRecipients(Message.RecipientType.TO, recipient); + mimeMessage.setSubject(subject); + + Multipart multipart = new MimeMultipart(); + BodyPart messageBodyPart = new MimeBodyPart(); + messageBodyPart.setContent(content, "text/html"); + multipart.addBodyPart(messageBodyPart); + mimeMessage.setContent(multipart); + + if(attachments.size()>0) { + for (File file: attachments) { + MimeBodyPart mimeBodyPart = new MimeBodyPart(); + DataSource source = new FileDataSource(file.getAbsolutePath()); + mimeBodyPart.setDataHandler(new DataHandler(source)); + mimeBodyPart.setFileName(file.getName()); + multipart.addBodyPart(mimeBodyPart); + } + } + message = MessageToString(mimeMessage); + String encryptMessage = encryptMessage(message,StringToSecretKey.stringToSecretKey(secretKey)); + return encryptMessage; + } catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + return ""; + } + + } + + +// private String encryptMessage(String message) throws Exception{ +// // Generate AES key +// KeyGenerator keyGen = KeyGenerator.getInstance("AES"); +// keyGen.init(128); // You can also use 192 or 256-bit key size +// SecretKey secretKey = keyGen.generateKey(); +// +// +// this.sKey = secretKey; +// +// // Initialize Cipher for encryption +// Cipher cipher = Cipher.getInstance("AES"); +// cipher.init(Cipher.ENCRYPT_MODE, secretKey); +// +// byte[] encryptedBytes = cipher.doFinal(message.getBytes()); +// +// // Convert encrypted bytes to a readable format +// String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes); +// +// return encryptedText; +// // Initialize Cipher for decryption +//// cipher.init(Cipher.DECRYPT_MODE, secretKey); +//// byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText)); +//// String decryptedText = new String(decryptedBytes); +//// System.out.println("Decrypted Text: " + decryptedText); +// +// } + + private String encryptMessage(String message, SecretKey secretKey) throws Exception{ + // Generate AES key +// KeyGenerator keyGen = KeyGenerator.getInstance("AES"); +// keyGen.init(128); // You can also use 192 or 256-bit key size +// SecretKey secretKey = keyGen.generateKey(); + + // Initialize Cipher for encryption + Cipher cipher = Cipher.getInstance("AES"); + cipher.init(Cipher.ENCRYPT_MODE, secretKey); + + byte[] encryptedBytes = cipher.doFinal(message.getBytes()); + + // Convert encrypted bytes to a readable format + String encryptedText = Base64.getEncoder().encodeToString(encryptedBytes); + + return encryptedText; + // Initialize Cipher for decryption +// cipher.init(Cipher.DECRYPT_MODE, secretKey); +// byte[] decryptedBytes = cipher.doFinal(Base64.getDecoder().decode(encryptedText)); +// String decryptedText = new String(decryptedBytes); +// System.out.println("Decrypted Text: " + decryptedText); + + } + + class StringToSecretKey { + public static SecretKey stringToSecretKey(String encodedKey) { + byte[] decodedKey = Base64.getDecoder().decode(encodedKey); + return new SecretKeySpec(decodedKey, 0, decodedKey.length, "AES"); // Replace "AES" with the appropriate algorithm + } + } + + class SecretKeyToString { + public static String secretKeyToString(SecretKey secretKey) { + // Convert SecretKey to byte array and then to Base64 string + byte[] encodedKey = secretKey.getEncoded(); + return Base64.getEncoder().encodeToString(encodedKey); + } + } +} \ No newline at end of file diff --git a/src/main/java/com/secure_mailer/frontend/ViewGenerator.java b/src/main/java/com/secure_mailer/frontend/ViewGenerator.java new file mode 100644 index 0000000..db5fe5a --- /dev/null +++ b/src/main/java/com/secure_mailer/frontend/ViewGenerator.java @@ -0,0 +1,70 @@ +package com.secure_mailer.frontend; + +import java.io.IOException; +import java.io.InputStream; +import com.secure_mailer.backend.BaseController; +import com.secure_mailer.backend.LoginController; +import com.secure_mailer.backend.EmailManager; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.scene.image.Image; +import javafx.scene.text.Font; +import javafx.stage.Stage; + +public class ViewGenerator { + + private static String theme = "/css/themeDefault.css"; + private static String fontFile1 = "/font/Myriad_Pro_Regular.ttf"; + private static String fontFile2 = "/font/Myriad_Pro_Light_SemiCondensed.otf"; + private static Stage stage; + private static BaseController logincontroller; + + public static void initialize(EmailManager em) { + loadFont(); + logincontroller = new LoginController(em); + stage = new Stage(); + stage.getIcons().add(new Image("/img/default/email-client.png")); + stage.setTitle("EmailClient"); + stage.setScene(initializeScene(logincontroller)); + stage.show(); + } + + public static void showMainWindow(EmailManager em) { + stage.close(); + BaseController controller = new MainWindowController(em, logincontroller.getEmailID()); + stage = new Stage(); + stage.getIcons().add(new Image("/img/default/email-client.png")); + stage.setTitle("EmailClient"); + stage.setScene(initializeScene(controller)); + stage.show(); + } + + public static void closeStage(Stage stage) { stage.close(); } + + private static Scene initializeScene(BaseController controller) { + FXMLLoader fxmlLoader = new FXMLLoader(ViewGenerator.class.getResource(controller.getFXML())); + fxmlLoader.setController(controller); + Parent parent; + try { parent = fxmlLoader.load(); } + catch (IOException e) { e.printStackTrace(); return null; } + Scene scene = new Scene(parent); + updateStyles(scene); + return scene; + } + + private static void updateStyles(Scene scene) { + scene.getStylesheets().clear(); + scene.getStylesheets().add(ViewGenerator.class.getResource(theme).toExternalForm()); + } + + private static void loadFont() { + try (InputStream in = ViewGenerator.class.getResourceAsStream(fontFile1); + InputStream in2 = ViewGenerator.class.getResourceAsStream(fontFile2)) { + if (in != null) { + Font.loadFont(in, 1); + Font.loadFont(in2, 1); + } + } catch (IOException e) { e.printStackTrace(); } + } +} diff --git a/src/main/resources/META-INF/javamail.default.address.map b/src/main/resources/META-INF/javamail.default.address.map new file mode 100644 index 0000000..e69de29 diff --git a/src/main/resources/css/themeDefault.css b/src/main/resources/css/themeDefault.css new file mode 100644 index 0000000..dbc8992 --- /dev/null +++ b/src/main/resources/css/themeDefault.css @@ -0,0 +1,320 @@ +/*** Colors ***/ + +* { + mid-blue-color: #212d40; + dark-blue-color: #011826; + cell-unselected-color: #f2f2f2; + folder-selected-color: #495362; + light-grey-color: #cccccc; + mid-grey-color: #e0e0e0; + dark-grey-color: #999999; + white-color: white; + teal-color: #98c0bb; + selection-grey: #d1d1d1 +} + +/*** Text ***/ + +@font-face{ + font-family: 'Myriad Pro'; + src: url("../font/Myriad_Pro_Regular.ttf"); +} + +@font-face{ + font-family: 'Myriad Pro Light SemiCond'; + src: url("../font/Myriad_Pro_Light_SemiCondensed.otf"); +} + +.text { -fx-text-fill: black; } +.font-rockwell { -fx-font-family: 'Rockwell'; } +.font-myriad { -fx-font-family: 'Myriad Pro'; } +.font-bold { -fx-font-weight: bold; } +.font-grey { -fx-text-fill: dark-grey-color; } +.font-white { -fx-text-fill: white-color; } + + +/*** General ***/ + +#main-window-pane { -fx-background-color: white-color; } +#account-pane { -fx-background-color: dark-blue-color; } +#compose-key-pane { -fx-background-color: mid-blue-color; } + +/*** Login ***/ + +.login-field { + -fx-background-color: transparent; + -fx-font-size: 20; +} +#login-key { -fx-font-size: 35; } + +/*** Email Selection ***/ + +.list-view .scroll-bar:vertical, +.list-view .scroll-bar:horizontal { + -fx-scale-x: 0; + -fx-opacity: 0; + -fx-padding:-7; +} +#email-cell-view, #email-cell-view:selected { + -fx-focus-color: transparent; + -fx-faint-focus-color: transparent; +} +.email-cell { + -fx-graphic-text-gap: 0; + -fx-padding: 0px; + -fx-background-color: cell-unselected-color; + -fx-border-color: light-grey-color, light-grey-color, light-grey-color, transparent; + -fx-border-width: 0.5, 0.5, 0.5, 0; +} +.email-cell:selected { -fx-background-color: white-color; } +.email-cell:hover { -fx-background-color: white-color; } +.email-cell:empty { visibility: hidden; } +.email-cell:selected > #email-cell-pane #email-cell-focused { -fx-background-color: teal-color; } +#email-cell-title { -fx-font-size: 15; } +#email-cell-title { -fx-text-fill: black; } + +#email-cell-message *, #email-cell-message { + -fx-background-color: transparent; + -fx-border-color: transparent; +} + +/*** Message View ***/ + +#message-pane { -fx-background-color: white-color; } +#message-title { -fx-font-size: 15; } +#message-long-view .scroll-bar { visibility: hidden; } +.line { -fx-stroke: light-grey-color; } + +/*** Folder Selection ***/ + +#folder-view *, #folder-view, #folder-view:focused{ + -fx-background-color: mid-blue-color; + -fx-text-fill: white-color; + -fx-border-color: transparent; +} +#folder-view .tree-cell > .tree-disclosure-node { -fx-background-color: transparent;} +#folder-view .tree-cell:hover { -fx-text-fill: teal-color; } +#folder-view .tree-cell:focused { -fx-background-color: folder-selected-color; -fx-text-fill: teal-color; } + +/*** Composer Window ***/ + +#editor { -fx-background-color: white-color; } +#editor .top-toolbar, .bottom-toolbar {-fx-background-color: transparent} +#editor .grid, .combo-box *, .color-picker .arrow-button .arrow { -fx-background-color: transparent; } +.combo-box .arrow-button .arrow {-fx-background-color: black; } + +#editor * .button, .html-editor-align-justify, .html-editor-outdent, .html-editor-indent, +.html-editor-align-left, .html-editor-align-center, .html-editor-align-right, +.html-editor-bullets, .html-editor-numbers, .html-editor-foreground, .html-editor-background, .font-menu-button, +.font-menu-button *, .html-editor-underline, .html-editor-strike, .html-editor-italic, .html-editor-bold { + -fx-background-color: mid-grey-color; +} + +#editor * .button:hover, .html-editor-align-justify:hover, .html-editor-outdent:hover, .html-editor-indent:hover, +.html-editor-align-left:hover, .html-editor-align-center:hover, .html-editor-align-right:hover, +.html-editor-bullets:hover, .html-editor-numbers:hover, .html-editor-foreground:hover, .html-editor-background:hover, .font-menu-button:hover, +.font-menu-button *:hover, .html-editor-underline:hover, .html-editor-strike:hover, .html-editor-italic:hover, .html-editor-bold:hover { + -fx-background-color: selection-grey; +} + +/* Attachments */ + +#attach-label { -fx-font-family: 'Rockwell'; } +.attach-cell:empty { visibility: hidden; } +#attachments-label {} +#attachment-list { + -fx-background-color: transparent; + -fx-border-color: transparent; +} +.attach-cell { + -fx-background-color: transparent; + -fx-border-color: transparent; +} + +/*** Settings ***/ + +#settings-pane { -fx-background-color: dark-blue-color; } + +/* Icons */ + +#gmail-folder { -fx-image: url("../img/default/idle/at.png"); } +#inbox-folder { -fx-image: url("../img/default/idle/inbox.png"); } +#all-folder { -fx-image: url("../img/default/idle/mail.png"); } +#sent-folder { -fx-image: url("../img/default/idle/sent.png"); } +#spam-folder { -fx-image: url("../img/default/idle/spam.png"); } +#important-folder { -fx-image: url("../img/default/idle/flag.png"); } +#draft-folder { -fx-image: url("../img/default/idle/draft.png"); } +#star-folder { -fx-image: url("../img/default/idle/star-folder.png"); } +#trash-folder { -fx-image: url("../img/default/idle/trash-folder.png"); } + +.tree-cell:hover > #gmail-folder, .tree-cell:focused > #gmail-folder { -fx-image: url("../img/default/hover/at.png"); } +.tree-cell:hover > #inbox-folder, .tree-cell:focused > #inbox-folder { -fx-image: url("../img/default/hover/inbox.png"); } +.tree-cell:hover > #all-folder, .tree-cell:focused > #all-folder { -fx-image: url("../img/default/hover/mail.png"); } +.tree-cell:hover > #sent-folder, .tree-cell:focused > #sent-folder { -fx-image: url("../img/default/hover/sent.png"); } +.tree-cell:hover > #spam-folder, .tree-cell:focused > #spam-folder { -fx-image: url("../img/default/hover/spam.png"); } +.tree-cell:hover > #important-folder, .tree-cell:focused > #important-folder { -fx-image: url("../img/default/hover/flag.png"); } +.tree-cell:hover > #draft-folder, .tree-cell:focused > #draft-folder { -fx-image: url("../img/default/hover/draft.png"); } +.tree-cell:hover > #star-folder, .tree-cell:focused > #star-folder { -fx-image: url("../img/default/hover/star-folder.png"); } +.tree-cell:hover > #trash-folder, .tree-cell:focused > #trash-folder { -fx-image: url("../img/default/hover/trash-folder.png"); } + +#paper-clip { -fx-image: url("../img/default/idle/paper-clip.png"); } +#email-cell-clip { -fx-image: url("../img/default/idle/email-cell-clip.png"); } +#login-email-icon { -fx-image: url("../img/default/idle/login-email-icon.png"); } +#login-pass-icon { -fx-image: url("../img/default/idle/login-pass-icon.png"); } + +#login-key { + -fx-background-color: transparent; + -fx-background-image: url('../img/default/idle/login-key.png'); + -fx-background-size: 367px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#login-key:hover { + -fx-background-color: transparent; + -fx-background-image: url('../img/default/hover/login-key.png'); + -fx-background-size: 367px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#settings-key { + -fx-graphic: url('../img/default/idle/settings.png'); + -fx-scale-x: 0.04; + -fx-scale-y: 0.04; + -fx-translate-x: -203; + -fx-translate-y: -205; + -fx-background-color: transparent; +} + +#settings-key:hover { + -fx-graphic: url('../img/default/hover/settings.png'); + -fx-scale-x: 0.04; + -fx-scale-y: 0.04; + -fx-translate-x: -203; + -fx-translate-y: -205; + -fx-background-color: transparent; +} + +#key-trash { + -fx-graphic: url('../img/default/idle/trash.png'); + -fx-scale-x: 0.02; + -fx-scale-y: 0.02; + -fx-background-color: transparent; +} +#key-star { + -fx-graphic: url('../img/default/idle/star.png'); + -fx-scale-x: 0.018; + -fx-scale-y: 0.018; + -fx-background-color: transparent; +} +#key-trash:hover, #key-trash:focused { + -fx-graphic: url('../img/default/hover/trash.png'); + -fx-scale-x: 0.02; + -fx-scale-y: 0.02; + -fx-background-color: transparent; +} +#key-star:hover, #key-star:focused { + -fx-graphic: url('../img/default/hover/star.png'); + -fx-scale-x: 0.018; + -fx-scale-y: 0.018; + -fx-background-color: transparent; +} + +#send-key { + -fx-graphic: url('../img/default/idle/send-message.png'); + -fx-scale-x: 0.09; + -fx-scale-y: 0.09; + -fx-background-color: transparent; +} + +#send-key:hover { + -fx-graphic: url('../img/default/hover/send-message.png'); + -fx-scale-x: 0.09; + -fx-scale-y: 0.09; + -fx-background-color: transparent; +} + +#attach-key { + -fx-graphic: url('../img/default/idle/attach-message.png'); + -fx-scale-x: 0.08; + -fx-scale-y: 0.08; + -fx-background-color: transparent; +} + +#attach-key:hover { + -fx-graphic: url('../img/default/hover/attach-message.png'); + -fx-scale-x: 0.08; + -fx-scale-y: 0.08; + -fx-background-color: transparent; +} + +#compose-key { + -fx-background-color: transparent; + -fx-background-image: url('../img/default/idle/compose-key.png'); + -fx-background-size: 139px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#compose-key:hover { + -fx-background-color: transparent; + -fx-background-image: url('../img/default/hover/compose-key.png'); + -fx-background-size: 139px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#compose-cancel-key { + -fx-graphic: url('../img/default/idle/cancel-message.png'); + -fx-scale-x: 0.08; + -fx-scale-y: 0.08; + -fx-background-color: transparent; +} + +#compose-cancel-key:hover { + -fx-graphic: url('../img/default/hover/cancel-message.png'); + -fx-scale-x: 0.08; + -fx-scale-y: 0.08; + -fx-background-color: transparent; +} + +#compose-attached-icon { + -fx-image: url('../img/default/idle/attached-message.png'); + -fx-scale-x: 0.9; + -fx-scale-y: 0.9; +} + +#field-send-to, #field-title { + -fx-background-color: transparent; + -fx-background-image: url("../img/default/idle/composer-field.png"); + -fx-background-size: 469px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#field-send-to:hover, #field-title:hover, +#field-send-to:focused, #field-title:focused { + -fx-background-color: transparent; + -fx-background-image: url("../img/default/hover/composer-field.png"); + -fx-background-size: 469px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#search-bar { + -fx-background-color: transparent; + -fx-background-image: url('../img/default/idle/search-bar.png'); + -fx-background-size: 232px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + +#search-bar:hover { + -fx-background-color: transparent; + -fx-background-image: url('../img/default/hover/search-bar.png'); + -fx-background-size: 232px; + -fx-background-repeat: no-repeat; + -fx-background-position: center; +} + diff --git a/src/main/resources/font/Myriad_Pro_Light_SemiCondensed.otf b/src/main/resources/font/Myriad_Pro_Light_SemiCondensed.otf new file mode 100644 index 0000000000000000000000000000000000000000..56e85155435e987a506120e321abb54481c596b6 GIT binary patch literal 94340 zcmc$`cU%+6`#3(ko85#g1V{*AViLrLjV|^^v3C>|MGX)klmtj{pYnTse}DXbXfpFWQ=T%oA*;*0fLJG5C$X|P3AAPz#H*<7L~gI41MEPX%i>q;InM|{{;x*4Z?tL ze=!C$r(fc}P{d1OJAw&-vsm!dWnv4_hy4}PoP$-n(_jm2IWn867&V%H{~fH$3#te zA;`v5O?fNO4%^z4rxD$gO?e6EfZcD(OA-DP;tLa4AufKx(B3%xlV%z)b9F%2TcILJSwQX~J6pe^S|$r-3&a)|8ik;beYO-VQjB_nPwd zpcDD)J{PY(eZ0G~-@e>;ukJ41o}QlEx39~PNMpFpB{T=TBDK1{_p6)%p`o(Kwbw=|X_c(nxDtGtl?bpleeFDi~3{h%t6>V)N6QCkM5{OZ{UX{^7_2x@yLo=NbE6cG%FL*C0;2VQ-@*e?Vy#k( zQg^O>Jj%7U!e-n4-z-~)WM^ktB)eL&>nQr*4o$0ATXx0ZU<$LKGAjU^N}AVKw$=ak zhoNYJKy=mNTeZfGj^Kq7k}$Tn1Oc6%-|012@5Sa0A=|cfoCN2iybq!6WbhJVbHYkKh@2 z0-mCwEkOemjwT%I)YgMtU_aQ5qL4+{e2@!PU<*JYHW!pNCdWFncxLDk4%d} z6E6-KqX8r$15HNGU@j;HRp0=q28TfnI09-x9jFJ#kc20|Y49yL3s!>#AQNPPY_Je~ z0~UiNU@2Gz1k@E&=Q6@mNOSBM%t9P30L5Sjwg6j$m0;!A7hHw=;1}>q_z%PaBA3V` zRuLt{KH>mzh$tsc65kS+i0=i~f^mWwf?0yqf(Pow>P8nk7Y7%Gi`vE2rIU-NOJA2j zmjst|mjy04E-PJ1+sWEFwsURQshztk?n=4Zx=LN;t_oMRYd6>7uCrZr9WOr>J^SW` z)r&SS+P#1G{*U*6y@w6H4SgDhH261+ZkW_Cvtf2aOha75p@xcv!wp9pjyIfXxZm)& z;SKD=2)=wlGP!W}G#iahF&d+tNS0#k5cW6jjCKjfsTtc!u zfu0Qb^5x4jFa&+tetCxP_;M0}&$p0tU;pMI%oFt4k3P#jquBcM?$4#4b5P3Wqdw31 ztot1K+4r-7ZSsQMF>rrRgP)Fk>ityn^f3B&*S^%E=J@?f0-_&!lRaeQu){UPhb4R`{cglFJO@MQ>MKdaDZ3tNx>M(GCh+0?ovz7F4t9NAc6 zJTZxw+PZ|#6C?izp&4C_X8j^G-X1Xr65V`Dj*e1qEOSn(YVC z94$q&oAo=n$nzXVzNZS!+PbD$y9Ifo6Wq)_i9FI?uma6ocK)6L=RgtiFW(^_bqV>W z%g95mLO$vy@=~mix{JIN>!bD{FZBrdsRzhMJp|j3hk1s473-;;G&A30W!P`nLF^st_pl1=BUXj|fmLF^ zW7XK7SPj;I9mf6wr@#+b9oC4|qV?(xc#oaLzF^0&PuNlHZ|ns28LP(_>^Sxhb{fa9 zv$z19$1dPP>>@4#7r;yWGJXaB4!;UMVau>fxE1nkAFv}BBnA^hz|Y_Vb{?mY?_1X7 zBbOq7xdfku&&Iv*naFGS;J$b-ybnGd?}_)umf|Du33v!T4WEKf#Y3?(IDwtQ0roA9 z2r2%Wkl}9#2mEJ3j{ib9;=dA3_*=pm z|BYyazatd*dqRnSAll*|2^Ic3p~n9pH29x{3;q|;4sRe_aY(esEkpB{(e-9Y!8?c)giY>wl&>sH)_!B_vG4=-g6_epo+!}Yp zCAbr&!y>UcSQHkGO~Qh)$yf+B1=Hhp;BU+dbHUnS9WYm{J*LJqSOgZ1O~fW(Cd`b* zVM$ml7K5b|1BpSn7^iU?+#Zj_b+`<7z~#tKU%=G)z_oZd7JzwULoiRwAM?Tj zF&}I&<^g`^*1AKA9oXxp}ZD(qjY066_nipQglP|zbpp^XNGD*aKg!A78S(W1HzxqyRc z5?@49@&)*a0n7%o!{nF(>y8b=#$sVe+*A|@tiraUDNu)<$8Msj^A>BwDWpyp+#Tf&z8){cx8r;9D*QNp2C3p2eg}Vo|AhaHe?S9@5jKPqp(HvH-3fQ1 zCvsx`#28{4F^kXSC)DkC%%fxl!KJkKhPy9hN3P=Gha299; zodn$kUV>f%f59lU^vw{23!(){f(*ezK@M65HwuabI|K&>wSp6Zvx3Wl>w<@ZXM&f4 zUj-ippGXlYB^}9jWM{Gq=}Gn?2av|+o z$Xn!(!Y6;Ru#ozwxU zlB%KVs1ww;)CKA)b&a|~-J%{+kEtirOX@ZCj`~RbNkQtfP$YB^wiR|1dI<*zM+m11 z!-Y}8SYd)NS(qWr5-t)h6Xpq53pWb43X6r?h5LjDga?IH!W!Xm;VI!6;d$YA!aKre z!k>k|3qOm*B1ch2k%wroXp(5UC|ndPN)n}uvP4ToD@E%?g`ypz{h|s{t>~oayy&Xv zw&;=Qx#(xn2N4u~wj!;ptz=dTt9DjyRvuP@Dsi z9xNUv9xI+Ko*|A9$A}ZfY2r-r67dT0I&pz`yLg|tTzo`)LVQkqMSM&AQ2b2%M*Lpf zApVCI&?4HFcBD0QSK5R2qX*GL>9KSOt)=yJ61{+4Os}B}=v{O0sk&)6Zs< z&2*a>n{=C8n=Ll`ZR%_;+dQ)Q)rOJSNZLz!NrpdGdfElp1=~f~rP$@# zZM55ES8aFJ?uOkHyWi~ov6tAp*n8Or*pIQFVz0F~*{9oQ*k{|Xu-|N7Y`@3;p#5R{ zWAFnWuF3Ao9?71{Udeuuy_5YV z`{Y14h#l-5oEA1;pyW>8`D#w$KmmI%$`p)TRr$6S*($AR{XEf;CP00zmB)u`ooND}xCS8io&;se$L&z4$pl?M89j3)=TlnE*jBEiT(5Yq%FlW{r^q*A- zQps28^oBW{VmJ&hT{9{=Js}!#(X6^Au(_0zy}68&ss&)BY6e)TTJoG!%@8kDGsH>N z3~+rn6Jqt+oM-jglIQf=3~?N^04xX10Lwv3p5vey;yGxB46I(80Zw(zK$B@SgH2j) z2KgaqhD-_C2;Hn?gWl7}+iysC5+XPxUK^2QGz>9DAyHz71Zg9Z&AI^oI|3b*8UiBp zNfF8MbK-Pq0g*mmRfTV*G~|K32Lbk#P=IyhzjDn9>!H0_O-WR9B+Jo z!&=%657#CQ|5|AT*J{Mb5qx(e_`XJ%^>LB9kzcEgYSq_hj``6XKcidY5sk52*;uY@ zY^$4x?+S zfe!UqlhPTYbbQxQT(zjLy+yTBK~zh-Xr!X(ua)#%D}9Wf?@rJ6rRQ`J^R-%RtG?nm z=Hobi;#%Vo4FgwZ;L6ZF4Dw98=@~gP#@0h%#j5B$t_Mimp*w=q7V?lUvhG=IJK$k|wi5pUjDy%8^O^+I?#C(5G@Eo&L2XokPs! z8q94`ZEO@;O$>49{zD&O(6U#TNk-&9%|?UK)Z7&Z42esK*81zr+F@G6Dd#Er_y#4I z^k|_9Md%>2b`ol*9f3T-C~ZQ5cCIiwFqhojikIiE+jIV?+T?=6{T{+fE{@J+q8&VQ|jE@-#{Eh|en zVm6AEB~lk>*6Mg}<{~8ek8X?1T0No_%SsZ*Ny72xA7DsM(;Inl67)&YMiVQJS(}{9 zcaRXRkBHWzyfGe8;|OsioBHSTO){_qI0Tz%=CY}84&T&g>-^Vh&BC;9{NL5&aja(# z@aAOb6{IzwyTmx1o*PDAFHaWj>*d8KTqR#G9}eo%ROZW<_2d&jKIz3Lz4@dMpA6v> ze?AG|lR!QR;*+6V;>~yM&6D-!$$Il-y?J`xJUwroo;Od=o2Tc^)AQ!(dGqwVd3xSF zJ#U_#H&4%#C*;W!^5hA5@`OBjLY_P!Po9t`Pso!eY#PtS*^=fl(U;pzGC^n7@FK0G}io}Ldcm=90ZhbQaHllA2(`0`|Z zd9uDdJzt)lFHg^xr{~Ml^X2LJ^7MRpdcHh8U!I;XPtTX9*OMpIlPA=ZC)ATC)RQOF zlPA=ZC)ATC)RQOFlPA=ZC)ATC)RU*slcx~aCnz}y-PP*7y*N8WiJ#77M*be%?4pp* ztk=dx>gUV}WM^(dk})zl!fZ-LQ`wB}sL|!IK0+IZA{#xr2~O7=%sS-x;?P7+GN$Pg zleKZI^|NW5&Sc^;$OodHlX#?YF1tRpI7s&hZ35?z*$nT0*<6!jXS1v~W>d}~b7d`Y z5esn+mqW8b6PszC!>#kPxN2w>2>%zB^V!W<4q%I0FAXfruMTXkiPLnnASHZt{q7MQ zqE(RRIrQJPTXCG8^sjo&%zkCC1=GS@s|MbFY{z_*&BjMuZjRoJ29Ax0`5YS$H|4l! zn9p;ua8s6zg!wER2RG%oD45UlF)*L!B49p?Vq7i+Zr-+V)Xm!PW|(E670B|@8swO1 zh2S`94YO>uf?3{LgB*jc5ImQy5FD$mVAjlA_b?~Uh^(nK#*iG3o>V}K%)hYggA&NX zqgvNYN1L8jT{lJltuUNsTEU!h(8D2U#WA3Dhz-o#TY;={T7#T&S|K>)w1!#bw1QdX zv<5llv_kO8X@%gF(+cK7qSjqB?O7fN~(n1UTRR{k@@f!Fyjyp|2bGp@5n{zbUh*+JuxiB2X!3gBrHx;7@1D!)O11&|m zvfkb^&}lF0S(m3gFuX@a+Qlb^(050KQ!S-!71E7s%5K`&Zws@GbpvBODksF4~x6n9P0|*{@{w3oVIJ zT=7tT2!`@QFto{3*yst_2y0s?VeJl?3LAW(gpImT!kQmS_?iJcGLT0G^6iH5(9k~o zB8}pja9x}+l^vn~iedG}WB(-<%cr|G&ivmLu`M_r0(nCV;!P`vH?1IElAxwC-ui|% zRcV?6JT!!tYX~pG5H=1(a`7Vgv!Nn_cnt(J3Ckk`nvi@0ZdQ5)1@dKqd|4o07Q|Bs z;wc32Y6;>y3*rd{@$G{6c0qi*p?tfcO{3AIalR~&FALz4z$WIKIBOb)CJOur2eBjU z>Fvc*KuN$jc9%GWjUc&+GHh0h*^J>&<2=2`HfOjdKHl1v+EHI?$2V6pG-vqQKHL(< z9al63QC|=Gy!`p`WNZ3(`8SOu;))$Dl=$o2*(kW>9Q5lEG%EM@^z!7IyU$^dKu`nZ z{kS|wjLUJ)hz1xF&||6Wn57gp1%$ z%oa;V&ncCo8*Mq>8Qp&;q5I~ZL;ztRwxCPID)#bF;4K&}_(rfnP)TagrJpyt)O$}Q zQiarRbVXMoR11d*j|eXdUkks8>_sW)dhCqox|NUB5UZV5m#rS6>nuuaC+;H7LYGxr z#lO=kbP*LwN75B^9lC6KWeuz;>kigEtRt<>)<>;R+2A%(8 zmP<+`_a#3_UP?aLTHE^DPOx2KTW@>M_NDD-JE5JcT_?Lib_P3>U8dbiyKQ#g+5K*> zu=lhdY(ENJ3x(S+u`jW&us>&i6T$p%b`EI^qJxiYz%bn$I4np;P9L41(%Gp<;aXkc#;xkCL*xQeOy+o{U;mS^uVzKL{O;Q7 zS3fCVAMD*HM?=H2jf3TkTds;pXG~DY(9jiXpbX-02~1=NXv1{WEQyfAZkL$8j2d$UraEm#LWDUn!C*);Wfev`Z(4Pr@KD*s z%atEaz)sK_K6MVIIx^=LL}W%TG_=W~7VXcf$Sh}Yc)^*rbbG5}&Qs~j(wAna!!u@2 z8LsS^c%R$snNy@H}Gz(UKJC2%8LU&WmH#}D4DVs^rMxP+o} zhLAbb!Su*uy_N1A`!oKG=3$q=ZXd6xE77bNNimvHGkk()7Zw@S^K_*7!083Yl_$;> zR90vX9V$5k9TZ{ERz5Fh?vlCc0CPxOh_d_SCy<8H3qQWRT|FhFP?NtPZ~i<5-RMWo zq8Oux3dWH%+~^4Fg)rP=OHQRaF_RKP5<^p`Bk@v>n~o-(>;fk{PodzHPqrjeFQnz2 zJCMhzYu8NT>%+*CRL9>*de_f|-><(aT0yNFSunK36DgtszzrwqsrLio(<=?_z0cv{5HGbq^iA3u`bv8k}6cz$7W zN=ABW^5(h4Xr%xCR-R>wT@a@19P|iEA%5l~6xAJAkhN7)P)Tl_tKA%`WE5TuU^+2f zo^*ru=Z+L^*oMZqWJ}T3tr_;;k#7|ZgHMg#tX?UU9s7R!(X%%c^%>=fyVM7xrxXoThG`cs z(rfBs<@uXSR+cN@Ux@G-G-jfgrY|)|aFdc9egA9*;sy7c-6`Ibmp@k{iS@Y%AY(7%8P#TRf+9($CBwX9)xHhOFtR&dH6tp}RT#X&WZlA|sI^DO$eSxUH|d zg7FRW@eUbZ{-+umgvXZbU$kDWrPd^^nAB6jcnBHtYVb?gX!6kWGmaY%_~gRNaR!U4n^Kn-ab@)JWmrt85f&VXDFv9Z{N9CLo=b}u={hd^xHZp zJ$$WB_O4kUEAyAHR7M1n6-y3f#VJgw*=BRbs&yIaOg)*sWyd!q%Gx8_PgKP1j#{PJ zcbt5;_2jMR3Ql|K|J0uB$D&G7_Rd`_sa%u-*H=RKDta^{Pz)?W;iAQC(VL$j*E_*q6&g5}E3h!I}Aoa(O_y4#TcA-y&I$tQe|FCM$`SXfTHU1|_o;u%f|-UC>q)S0gJOB9>i-@r@z!H5seZ zk`>0Rj2J_B@%luytTa$8yK+w~d$>r&GM|;wD5xw*l^(2zhw5dekc9T~)RS2^@*ay| z|GbmX{)Mu7e`<7zrg*k|>(sTw1}T`qvly9Mbo|ybvszXNcUo@BqqmW=xR}x80mGav z;mY7s%NChce2Q(CXn|FcS*W9><+RL;K*^b%;zi z?AnmP;NgstaXvZXnkK(YKE-hL+Nb4Vj zoKznV?Z3xW84|i=;VcdFZ7(6b;>e7I#nh@DrTNuLIPobXU;=YBOnm!}%*fcd<@shc ztb!wjk~@xda67dnZ_A3!>YMA2oWG)6vwC^%Dow30Z^@Fp#mccW!X~9@awr;JLt}NP z@<81g#q+?ky?h3Y^B7e-`)r~*S15ZqG%9%N0EOR;AyDw{$#=ga1Gqi;Ou%mSRJang zI(ar`$jGqBi7A=^JEtGKgogjdnW{_bC7<>q>*zi0CtqB}K=IX(rv`U$!$9`fe7>k}4b5%Vp-@#ImElVww4|YON`G zl}XvIs~^*!@qXbA!P|zraHxjfzPV`Ywv0mLp68~fZB9p?ehnnVH&xlG(mQqV$Whtb zJIqvh9o)Kt3f+A??y~atH;-We>^AU?%g~UxF)>JX+2dtDqUCHw#EO~26?NhAO)EFA z*rb-dy;X4jU$4{tul%`p>F?Z7@g@pLYa#`MUu2s!5|-B?HY4HJ+8$5mM-r($no1xj%ica&7MNymgw@hsfv^i*}w= zSj1t>1!4NKxhP)HW`s{e@q+Qz9SuAa_GyzaAb-O8c=cf_yE6CTDaC!^%XqNu z9W6x*n0(iYwS|SsjT^r~s~_FyCZC_1l9Rl2`25k)v!;k9j)?5c$P`T9M;)LL(pUe2 zR!}nZ2?GK{bYTW{4z&qNZa_Pz+$UPKqd2cn$vA#`BJV!&2iR`Ys*U;UHD~vnE<3G! zd|?tJVywoE9iove7en%q^y2Mtb+R|pRk9B|8r#XydYWwBGI!gK&4t@b<`*SvBxA%C zbqe@sgYeki{naIlX?gjH>ibZnfa37`bB?K_shV-6gBYM-K+K@o1vC2bh-+u6N>6T8ucW3HR_MP~-h1>I20~KzYStmmj2x;) zTj}MZU^-3?3Yn}scQFqcGULbuk@XaGgh7lG3`8*tjh0A@IqZ{JNbi%U?*2CQtP-}p z_S1)Vqt5wn(X0^4KHS|`dH$;6{`6Z6793(S8`VY8mm7g7S2I8A=&Ey<`j06YM31rPRf{FpYuaX^L5CafTVNk_@JpXlCoYQ3w>SG5|QnoX5(FV=N1M}CL*2m=RHl`N&Wx@6OOLs2^c8JN2pO>c5r_D5mDkW9WP!9W4 z(u?P(E{au7j;y|Z{@|(edy5x+vr)6Ylw7mGyf#sJK4zS7SoX{b0~IvWmZasEglE->Za@tY}qyPWHlitSeuep`n*l9nL+Xgv6_|OUP57-~WvD)S@O& zJ)p%?*XiX=4thefgN|w6ff>O&Xc`S$rX0obgOTorlPfkAtSC|5J{T1otc{+gH*8p+ zp~;LPvx-VHE0y=poxXoOsmxfQ*9>1gGH50tZr%)l!$t7bhrG5XS z0=j$$`@(LgYt7LI)jOi)D{{%Ip&N$`SI{ODD-5i}s*l2&qXf*zmjCkGLpTHmcDdK1 zN0D&<{6e@D9}y#DvMZ|gfSID=2`&`l#@Cq}QoNUwGB?JL$66eu@t z;#>|B2>D6Fph-j0#~q;n7LYKQ+QXn^E0tG8GAUF%JW4`S6_Z9K!A&IG%%NXUOeKn5 z(VYBN{t6}{(};qjbA^l_^9PAG4ZYzfa*t3Fw^biP?u?1ps8cecPwnKnd8Dy6`((Z1 zO%>YCkd^xun2Xgr;^Zr+y`gI-M=H=XY~MM?uwlDNO*>XGM^*^yPLpUS*!3kuhN5^H z_L{LCIVB-BTD>)f+_wGj{`1OT4~!VdSo^v#T^LVI@F>zCl$0ja74KQSu~5BeAGtU) zV`-W)F=Y!~qB`Dx@2-Ux;aTfz;%S{bsM#-zXdgI7FGElIu7y$11C!IQ%<;ODRsp(t!$Li&Al_@!*sjt_3?iFi4!|D zE2#koO#AXzFV9=0UR_SccW2kYKa!Pc`#(2%9*g4zBDkn_P$Hi-Q#*=&Y z9NTk5dGcU#=044W1Lfw6%5&$+_U}XM-pJLZGw&&{)|K5`tZu;mY>j?o4l{ z`wyPKKR8}nUxL`Bvu~okNZ2Pe)$hQ(18djh<*iZYmy^2O#YIOH5@uRCcK-+gJLSs_ zhKT7?6*Ec`k8az$dQ*XV(H?T~{EVe@(I^%iIDGU}Q8Ds_G-FHO{H6*PRKoLBiK%q_ z{N|A;QEvM|WodM*qh_O>D{{uppKM6FTdwdxT6D<_W$&RQ8KKMN(GM?{?<+0Tte{o| zla*BNww%%u1-yLvz+|*S)gP`nc096j+9X{>==7?{lbYOp^7!OEdk<{ey}z_1DJC{K zF&2$7is?>L1uF{jH>=NWIePT0@=odKej4UN9lRtgTv?F6MSZg1NHxs|)ALrRv%&Oy z6ijbJ!8Bb4Czbti2rD@Zd)E*!i}u(c-~N|sQ8tPMuA9W?hLR^JPqZgLFW$5n`lwi| zl8@>&oN-`670k5n8QFKe)isp=yI|-5hbiF5)6ntmJGErpytqwq%2~R(2}znc5ep`b zRhTcT>MUcSmX`0_vUU5;j3QI=-1H>aQzc(_X*UD~hhvsF&oj+w-JPs`qoQxIQ-HoCp8L-#`FG;xEm;w}C5wc!Dut3=;zmCqU9hJHQbl*^g<}#J zFi%Sp_Z;E%N@jbbEm}3J7M?`Wn!|-(o?SaJbm)3@e)94(lftk(X>o$ue{S%|(Mo!0 zq&#H*ghyBEj(nesBG{;9Nl~H7aKnMBB^t?*dxvk9K3JLSyx2R}pRrXi_iG#dW(k>O zv_GZ`7gk$fRZ=RA*fAn@lppfe_nx4bFJuPfbswO*T9+fH*#oD%OH4mTtzeIwe9)0o z7dj8Vl-C!<#C#(@AT6meRzt<%_!@e{=G_Gcm9@o2y1p1$`7_v-oK4ZvL&soj9esGo z;gv|Kdy@~ICX)_SWmYMF`SUIub~pL5?ue%1B1sn`ISt3fMfCk_s6+ucjTQ<1Ak4by zAdG-$!@8$&klZ{EJp!>Mefy5hMLTxRFEVQ+3$v>hrdTGH(J7X(6>v%wjTYFr9D4Jn zBW0HqrD?n8Zcxw8B#Sc&%n6DJdU#h>VGpk&hsG%^CoyWeQcJUwr)X0_A#!7zGE-xs z7Q(h-_E4n&?TYS2h-Df7^hC!eIooMVk{gn5S9RrvBZ{*4J(07~%{({tifDFquZNE8 zfx{iu_ng&5e;P|OhT;^<_`2*=p21O7#wyxk-lC$VkWkSt&<=qfp}UGI)`p)rRk!0x zCGr)c7avS4Q$Bt83Xv+DisoRkOeJ7raw)lnHin%R*rKN8roxgXV z;??*=0qU%%Lh8b@lK2SorB6eB^X4?7J2Q=IpQDhv4e6sa+GD;B6UyFt2qhPyZ>l#OnoCVwnY5RNW0zM!Q{{mw zxT%V+JpUTm@Xo_k>yIc7#_f*K(kE3-K_|UCz9L(cBh+Oj#OBf19TdJ=(>dGAmYz`3 zj~F3YO3~5iI3)z>5_Ua63uTXCH4p}jRWO*Oxji=Y?DZ2v(zlC`*J}13EULSxplALgVNx0; zbQiLm8vGj?^X*6KHqmG%Z!DmTQyM3y(g&dD0ooBxdR^&Z=@l;IjOdw|mXBI6-fxt0 zwrM||@|}uiKm{CF0dH1d^cwb*Y*A`zsFDs>VU=}saL-_La+a4_QAih{r4?BgH~gYyEo`MxU3F|-R%I4UTb@SeG9M)0J{pXH-NYgaP*F&2;dTc_r>ro zfVc;+>j1qcN}wM~LcgZ76c952whZ9*fUpMmOF%pX_-laWTMWfh!H7c`Q3Z$!jM#(|hcV(RAPO+zCLoFcaRd-s38EG!z6Zp0fPSZm zxCMxMK%4}`F`T#th#P>|0f^gx*a?VJG_ea1R{*ga5DN+Pl0C5p5c>e}3J^<##9lxg z0K`v#n28auF=93#A_1Yr@fUzV3V($W?*Z`}MvP@|CC8v&aae&~sr(zgU0Q%%j+}^x zqZ`TF=-pL{5EIUXH{nYRB_YMI}>4bIq8rGc9fBPeI^2^FkRP2meUt!ALpLV z-#fo_X4)v)c(qAtvqhm&cq#@dzENya>{A?798-L+R4BVC2Pmg1W0X0{{mK){o66tX zg0|AOUTq`VE@)fQ_HkRN@>S_n4^)4t+o%Vrr>p0vzfo^jm#QDDKWZczH_ZUeY|TQ= z4$T$KpXhfWy15K@iFS!`sc`wwPTg*CyKCsT9*nLTu7$3@v>(@gW%~~u+&g4<_|W0^ zj)Ob;cih==cc(s`ws&^x+_m%g&a*ljJ7;%Z(|Jeds?L`>-*r>CwRQ7w8|XICZLV9M zTd`Y(Ta{alTdmtsw(Z`^cb6eurgVwya;Iy%t~K4LZYkZac6aRV(%rNB zpzcGukLtd=drkLK-EVh)(fwl&y2qFv(LGE(=J#0IV|9;`9_2m0>v6ls%N~FB`0Oro zH@IiGFLAGRZ}h-DtUVk(Ts-=EjPOYGnCG$FqrhXAN1ew-kJla_J#9SQJbgR|cnZ|r0?HlD=+|#<}?4DQs`uc_WZSuR*%eI$&ugG4Hdo}d7 z?j7IT*n3{@oZcIHm-fEeN8HD+&+tA|`|R&?z0bS8HhsJIozXX;@6x^-`tI&~tDjZB zHvPQ%1@>FqZ%e<5e%Jav>-T4WvVWWYUi}05hxE_tzo!4L{*MMw1FQyg88B=>%7FX< zy9d+_xID1OK*PWl19uLrANX+Khe7xtr$KIm{0Hd=Eg4ig=~IZ@VMa_!}Eq04lf=4a`+!3h!M^sI*srh;Xh*BhzTQdN9-6;Iih;R znUVNNdZhEn4kPD|Tsks;xQBxDAnx?Lv+AvKzEpFPvY5CJuPb&zu56ugG6#9O;{qzCTM^E1|eb@A=8Es~` z&R932G0ZWnPgqb`UfA}qgJDO*u7}+WdlmM_Oq-denaMLtWoAjZtpwYMgB>G9EQP zOz58wkuX1@AfYPZyM(8Swu$2tV-wdW9!b2Ecs=n;(w3x0Nq?E7rVb`QQ>f{<>5l0) zvx|AKd8T=(`C_t7^7!PuDu*^9E5Waq43e%$i*IEKDE94D3wEXx|le_BStmCQLgGZ3yN;Twu^ zVNS^*3w&B5{6x*<@^B!7V9Ih5LCji)g(OT3`k(#O@@uN}(!DQVzGdTn_bed0j!x11 zQz(;{ZHeCKAg(Vvet`e?6c-h%ci5+>N9hY8ph;GYF*zJT#r;1|_( z$Bk&Wu%Ft9b__m34% zr=9RUtnOQ>+jCWMtnAFaljW(IMe1#bNZDI+fv#|Bp6FdfC!v4V#0h;By)Vyt5~;qS zuM8id7&bj*(9E!+?FMyf6e;^NY5$4z6UvT435;J{2D8e}mci^Ytn4rxei#z-#M}On z$t~i>-iWbJ;(vOR7FSEB0pfA7KRjM>MJzd-jc#Kb6&2D0M~iEr|B-jKvIUkB$C)P$ z2NL(zUMzXO<*jHYmDMMGpnk%n>w(WFT^Fqs{&BYY^i9RH;G?5FrVi{swIsAGRJ}|n zs~#L0I;y9l^9^4}T)DjC(mAy(Wq)*0+SX)|teVN$EAKh++S4azPgd{I-1fTbeQc~K zEGi^!v{H6#v*jQ8`5jYdj0l}QWVXgwWv)J>xVZo1Ikkkj+1Ni7D~CAova!E>x2klN z^DdQ0!pvnPjpwi%wFC@n9JN8!1jA0X#05sOLF{5#T?(yIOH!-RN4gK*ljXrR=((CP z=$sDSuB{shWu)wEg!u=?n#>V0stx2!AyjW7mkE0@))k50LuZrtGUHgY(+`Ttl|tAq zldKgou9+mdDcSiH+LDsLkd@?BVsPJK0`9Zyl`}a^b|lPZ@(#m1m|e+a!yKW6xxq+b z61D?U^MtKUaaD0E>}uEW(D^9|>cVKUsN~@KGUay_(W8PBwV|Ulp(8Rztedzp#aZ^Ih#AEW z3LNEH0oxpcHHV=5oeJi|9;$jss*)pT%%7lS+IRUK9q7lvHn2VPgRT#{GTj&n^j7@< z#VSU|(1Wk3(6xn+8zdPoCLBHfHG+v{CP9(PM$SGdfD|s zVp;i?DpGcRuvqe93A%=Fl(CQSScLVmH1+|W+E|rjs2JTK5*<{M0AzFzs$fYKd!vZ1 z+#bN}Dr9LT+%s2{WI5ZVg|3sm^%lz>Z$Xb+yzMQPJVK3LR>2dgQ&keC7VU-oQYWwn zjuIvyySmXSRV$XnKU3YS3sXt@Ew5~}O+}sWQAuFx@_Um~EdQL9p0~V}C9F`%%H36x zF!5X!hKLNRC)%kbJ;msW3G;T#-&KdjvNX%(+47L}fknf%A|C+-6?Y(j;}tN8duXi# zx|E>Nb;>JS z8~3Ce;~B)bGwn5!L?q9pa(J|oRlI29996Nk?;|aWB@33H*JX&MYb<(M0$k$=lhE1tbczu&f0DBDcu#}J+N*Q5tlO~$DppJWXD!MCRb7u_8*P8rF{MF z5%h;W2E1t>7!o%wUXugQhf#H(ddjz~*tl||`c~mN{>cOM2$=QM9&Y0%Ry<18EL)$u zaf3qgRE$*~CAz63c`PY(#8goyJ7y6!PL?xuOH{IqTExf#v1H0Z=%qr(VT7dvTp`bM zLH4+Uzy0K|KA#ml{9#w&;>8=)n-7ue7MRu;m9ddo@diy)Wajwc3IluZxv;tax3CK` z@@-<-+m0&9vf>vi7>gcHKo(I)WQirgs_A04S{2Mmh0ZF(N7z4;qtM74fn8MWQPp2) zo^SYF#cCyk{V#jGN_9&4=m4Zu(`Oknla1=Rrx4G}9vH=vA2{W$K<0JFv4>bzyX+xC zrn3^m^KN3vXw~xOr#pDT-&%z1;~kd6=!A`BFJ~}Xa*mm292%~4cOA@(WV-+8`SH%N zsw2hdbQcN)8Ozd^&Q}jKg~U!)wx9i>0ot5?^Xs+alSgmTtVEAC&R0k-v5d;D4@Fb3 zLM%BU#!l2ipE|-rEcr=1MkQH+ezQha+g>G08zU~SQ%L$RKR4&3SXy9_$`T6DMOuIE zA`SXm%*f0;GN+K0XJ|9D**aw9SycnMs8kQOi zimp(qx}eyTzdL`ATJ|!3SN`tZioC1PL3~xTXX&n`yV;7nm+skpTV;4DW-8DRNM&G; zYlz2<3+10PYW~hZ@r+#DP?K1be_r+y&V}b5sP^7cB_J9JYT1V+2}=`=irf*Q%%9x*ERE&f6;Y8foQn{slIq?oA z%TMKQ-&dtPTw_kD*TmgAxUfw5?eRk|mT2ZsGxE}-!j<8(w{D-T**83TW3+Pg%xObb zq42TB;s%9cG$$RH5IOV^%T66rg}AF3+&Fw6}`5PI}oKV)gMYfxmbk4 zx$x!Ha925U_EM;MpWXLb@B6N- zDp9(xbGn6M?2NhOL-SPgWGB@KTf}cX6DK*uyE(`wn}4^!Ug<26`q0e=EUUax38#Gw zU^Q;4w)KQ%FsPCYx*q)}e}`a~a5sdwh8Bht1e6m4@a(llj0%jWMdb6% zFkmVffWOHyvD9jcnjc&Z?rPj@pAPNTX!tw)TlS0Cl?1}aT=3?su>6R^nBKqD+=MSO zRmBkSfXmt*k*(TU8Jy~qU|2(DC3cggsQJ(^} z@!@)it!Ep-i_eu=ZKPgE(~C|{=jVvLoPsRO<(9k5b6k}3=9V~}JTG#~Zw#nW)HGxk z7pYFoDlMIJLA1LlL)#)}uh)fWeM*#<&O4RPpCw`&3*D`)1QbzdPLgiqq>l{nFs4Um9T64qP9IuOWFYC$(Yhxg8KzZBW85G%SHanJvGtS|Z)>mqBr8 zx0=7YwTE`|!InQ6+6}kJ>#Uh1;y}hFi7X{BE-A9Z4bi@lyc>**6xAb?JTeI!MEKoq zdGtIti2iyg696WIi@B5o~b5y$D$P#JH5!{{ zdR!4U`~|oeABEA((y(5I^t7_B^Qzx_S7AhwY#;YFh5nf1_qSutiLm!hJVLAOqpc=X zKkOwlu@U$bJW#;rKR_z|F@(u$87=ENb7=A<#hW+_L zI~Zr-TnINSy8gsXHre!);e#w0UMsl7t6?N-S*@EcV{=z_T|?9$UW5(8)v@D+%QkA` zCa}htvbS#fW`?yq`qTsG&0}jB{&GE62a`C~>?(h5Del?Ac8|jktGUYze^hOtf$@x? zMmKgYzFzxP1N2uJ!Z5zw0l#;}puGJ-yWx5MvTPUw<9ZHbqa1{0$!a$wLHZGduwQ3vq(zp?9@#VhdwY40ZyLcEqLRv;}e2UQf|7D`@ z{r@t--VZEiUtye}>&?FMtTz9o$8fOhOQP-Ta2KV~#hnDr$ZPUn* zYS9Fd8suMO(6d01I3Uh9-aEmFt&I2fjCWNa{zOj1WGh+qiVOkMg1q>IJQeGm8=n)u zJI)C9i`hzYsZJK|WwYH@L52-_1s1UK31TgWw3I}I@54AtsCt|={P z-mPT6+mV$~S|x`MzSGV!w+Y(fthBOqHzgm)J8W>DU!&Xi2gA>i@$$`*Kn`~^&(sF| z&N@R4FO%8uF2t!0QYF$Q+;x7K8rGH?fKdf}@K-lwC_0p^8K?UMr-F$4r4l$x3S?eT zfbh$uWJY9Agja+w;=CevNAB5{vjj|#vEV}r5ZsgjrlPpqxIMe&apGkERJSDmV`NS* zjra)6NX<1VdrB zj4h)jXFUSBy`)IS+VNuDXlj)bzZosUBrQ8+5K={E#EYw{MeXg!&R&zZI31a^VUw?q zw=#2!C?m6IPo?7EKKu2i+1#J8YN&i`emN~8)_U^`)`64W{9-L3WgP`rF&XIccft+M zR5i4yp%)%+8zG?y(KU@QT^yCWFFF^Yu#d06XU+cg&Lye}`&BtJ6wVG&k*+G}vtH6j z=ExGWOB1UVFHWu-IdtxFBJy;POQN7x6$9q`-@fW+8oq~y^$3MY^j*C|g_rdU4dnLG zxAh3c^N{em68gHSp}ak!$uV{JGX!B#?+k_?e2ERx_o(jBWQ6b5!Dig@uKSC~Ir z?t(-OlDh_we!~#<^Mh`1kWRkRn@eB^S$6}+VGW+_g)KDNLCK4HcptSD5-%dHHI)!H$ygi<%;QZTb5rseXRBRS&O67RZ$MI;{|3`EA6b;ncHbvwM8ul zRd{@);B|VmYG^XNq8l!I^IQwN<0Wg0TAWWRet&WUX2FQ5j|R*%b6Vzz$Hraaj!(O1 zCG1Ab*M;n(`%fsIwhqNZBfDbssKrYwfAB`UdUPh@)oJxfDq8oSE(1k{@xz~r>Rjug zM#Fkrp5dR!aB|WEiL^OeoL4ON-W;Q1eJs5l_lS?TdMu7pS-V=z-(;V;BUmXwv#Jo0 z`l#v1aaBy4ZOytgBeZmR=TiJhjl9XJeukC3e~_;dvmf5ORyP&E#Ec6 zGNBn3OW2*3v>EUgHUk$getCrLOqm_m* ziBFW}i1X9K{SsA)o{51;5k{rr?a5I)BMTyP!!rVtv244OGt+bBncFhLQk1Eo!HAyq z^pB46SCPpjXcp-nmy{Bht|-|N8sOs{;id8xm%wn@H#29C`R3BB2R~oD`14P*E{s-1 zZ;@SYTl)R?tCq}+Q_Wa;^zx;HM=z;xT0pa;hR-n6fTpwe`)uc6g-@Fgol%?7wij3| z`)2uzKYy&Dq_d-yu3K_c`)pFz&PB}WssY25`nBuIU{eC92tEo4QFc zeCSvNfPH=Uo7YeOxC-;{`k!?_q;fxC(`MHE{6MdOGSYp?<`S!7t9`va9jZL5-HY6N zlkUp|Q>nf{{5Bc*ks!o#1rJgB&Y_~Kvq$)yDE1QS097D?xEu(+h`VL2Qu zck_XMWyaN--)i~KHSAsZMfatQOhaqD5*-32fdAvZ>^tZQN-#k;0sc?ERYg0>fEwX? zAe40s5s{C{V4V1e5;1xSM!{HwZT5g6Do_xqjD5Z{Xk+F|#o*E36Y-#PQ$SMNl(M%{ z6;>e{zW3? ztA?O4hP!ax7)G`~ZfEac>Su!(vY1~|Ki*+XF3{swO4-2pERF>*Ve3?BZRBXX;0#dkRaGnD6%=xQw`4}0Fdq|w$`y%`AtV<0gmfJ zk$yO0$V*rUmakvIkOS(_AUsl^qt?p$9ln;CGZkbOf-q&o9gWK$4Tj#qDytbHwVo;F z9p>pBK$&8}n?+l*^0(z9Q!MX*ioGh3#gv7O?QsV(iZgqoanl+Wp~aJZJb+`b&*J?? zbF-PM7ig|SizgX-gqlCwu4970_Q#jl$M6^BnMVABXBr`9UlTX}OFh88ARWn;!JTBw z3?y6r$74t)@3)wv2z_iz!5Uf#gGTEwybwNHf(o0@?r&+xNEo!3+oG@AtBt3zat}1J ztJ^y1hjwlMC;u?LZ2|{tk@8>MWuWM+#S2w@Fvb}6(@Al=UUd0DK$LHO} z=4Nibpd3H6m7YOcX*so(p7{#RXs|-}h3wgSu8H>Tx0X`yrImu$Xlv+=r)c)3_0q&$ zzK+-Gu}}@vruu_GY!JHi-?J#EHRipZX~k^yw$g{X!=veyQ#dX@YtPb_A~#|%awAsh zHoko^G^g6Y>;dJ*rALw{*`1~hy6 zpxLvbKV!k0$k=8)iexZ0YP{8qw*v51bAN`2c@sR4GzbThW;~FLVeVf+fNFC4&+YDL zxeTSo(@<(X4egI#=!UaQyDWECc1{e z%hvV5Z+i8?Z`Sp}BGu)RDR34~PR%C5(Wx$XH8+Y5<*#b^@wIfCpMr-Ug7jifhhX#f z=*1s4BE2|ApcngX+_g?Y6nc6w*ZviB!{Iw!v%MlT&Z)PXcesalKq4K!^rTcEoRsq0 z@T7!9&!WadarId_J9|r)F~{hM@C?U3>oV!i;`__k*I4bsJsUONd);-9DEa#+{SeE+!ZaY z_}yCel!;*UEj6K5U-q=gFJOt)ezi@g_R}V-IXu+xli_oYz15d#gkTx_6yM#C){BiA zk2z2KGPs`MOWzV+`YFD&AHFm;Q5C*)^$=zfGDW+NvhU}GP7|8hN}9Z$Q#UnYc^aG8 zYoUD^6Zis-u2esHO0H*ZMb?o9SZeWkM$TY)Z-;>8jh7XEvv=U zLHg7&{Ce7GP5N>1zn)krJaHv6_B4m4Wwu(dErS_sl(84E9MtBF4Q22PJ?0Dd&OUit zKd-n8!h50_n!P@Uf%W`ue9OoBx4a&~&EkHfE=yz?8DDLL2aRZa(-Xt5|6^iC;QRKm zHX9}f^iJC(0!d!|W%y98Qy@`XGJz9ZW_L7TRBa1ODD?XVy43i3-d|R|8aNKQdmOjg z_CSZf7VaRW?~a!Dmsk)Z8Qw608)E8uf``?Rq4z%VCb~~>qdvn1R*($xp)Gt!9%|ts zd{|9Bgbayv{6uelK_wKToj0#3v59@$)L#Z`OOV(Q?t4sk2EpH&v>wD6OO@IZwep{yF}*={NEiBJ1}R zneJjFjeE(Q!}l57>7J?Q1Neio>RA%D5Gcfv$u$wwDQHvsT)y@x+sRryGU(ZG=+6#|)ac;V`BeP_TaUmaTyvO7}n?&tMOu zXc!6es>wWbrwAo|N1H`o<3QHat>1J_vytw;kRdi(HQ-+j18NK&q6s5|UxXV+#==)5Flh%Y zusuya`~RoYDxOvkg8_I(XNjpd|4}8xs*NG0DF&yaGGZkIyZm3#nDU|gr-er+=v(t} zf%ZVV{Q9yZV^**A@^w~b(AKQm+pIWKw`sw|@689etCDR+$pr<;Mc9}>wXFOe_p$aC zW)UiBepqc7`Y*9xmT1{VN=fj2GahNB5-91|j2>gsXT#< z`(~^6zLCxQ5I*oY@ATEYoQUvrWoC^iCB!3bi(;cgu)C+qesjQz?0HMmE$>MZizMu|#|2k@t*HnK-mOF!3$d#4 z_XeL+-1~WWwCOYPYQtRo+AtfBHkyyN4Kp&9>|yLf?4nXP^>X2a9KG7!&yp6%G3UJk z!8s(5u#ZxM9n&2Z>jjRG&Bm}Li{$>u5qge$(VTHBO3?^neX z$=v+*p*|cT?d?c^)>)`c0uc=r3=I9NsLDT_Yj*iEKfC|9UZT5u{?+ zpF}QR{V6+cIi=7azx^`t#YXwN0#COwy>VUe#TMQk5y0J$6CT(AOq*@ zv;+2pD86H%SUM7sKw~uqph4_TH*bb~@C$bzM5mhqn%GxaX3UDOz2SQ`-y5B`z%u;A zFlH!nWNI|90Kapj$x!XgIEK~0d9^`v3*=)SA8%j?Gr^m0#QO(Z4B`w9--01p${+7wTyEcrJHs68 zXqUk+d#x?(5XxSI;EI% zW(agjI|N=7==386I#mlmr*aB(^6COQnH*%sy#qR(rMX$*i)la)bgCABPJFjz9O3jx zr&vTf>6G0m(8+cdW5T&{9(cpFjy6XYE!>H&=2$xhn`7>6Yz|Yg)T6UGZempq@n$@J z;ZUxrvpJ5KF&=N5ql7lc+%U%DU2{A_lbSQ*p>K}E`sR>rU_3fo<2hm_`lRE1p*33G zYYojD&I4PcO=yi98##~IYJNnOUA6J!#_Ls1)wi{{5lfsdyDGW4^WdSg@>Aw@<4Tp2 ziX96Y9!hlVo8A9VQ9QF+e2X3JXn z@)dRq*00-zauVnaWt+T94hA+Urc0zAhic$Vjlosq6IB_)pCFcn`8bAdP<*%a(6a{z zFWgs`P+s+}D*rUQ9X4^jPutCxd=)fj8Y&eSoS5}IR5`QiqNFaqYFB2ek<uz? z4vq;3iHO@8CSPNBP@K9d&!W`X$g=*3-$6y2HhULJQh1Q=YW|~6|Md^le~nA{A#`AS z5KDAmhit}!QU10<#c$O&pjVcv05&|}vbRTMp#xi#8tjwofsTndtD!-p+qUJs(1GoN z{`~K&!A0YN-AUevAieAS#GbVh_A;r87uOZ;Z9FL76`d88t%Tm_(|=6*iX#dmi}uPN zsP|t&pMF@TlD(dVuk<+G$2omH`t=tOBabB4WLFh?d7SNIaiVX$kDq+?rgigNs9WD7 z7QWeBd9uNo*>-7s#t7y9(WazgS0i$=h=sN)3v zNvwz%qch)BaOsQLY9hsKadSJ1!eb3uC^mK)I8tnEPvR)chuMgY^(3=#@0bU(5gVHa zCOGari3wt3^?!TeS-J=3h4K_qvX-B*o8xCpN0{Q@JsbaFXPw896@0@rj-RuF!Nc|R z%3L3qU;bycF|4U)eIZ1L=Kuc`EKsqHZ#4^)|Djn>z9sv=X%>(*{EQS%cj;@UG_z#S zUWRPd6}@6~r@c6|ozEzP)jlw;1`ky*RCj3}L$9SU{ERzHl6uc1ro)&wIct!A!telZ zavnbcdC9?FvR!-koy%xm6VWTeI$(Z?Bf5g^`K9G>r2G_vSl|)7Y!hbqANm(Z9T)#E z{R^DlIby>HRDk>M96wEV{52O|(#x8wW+IJ{m`qOd&!8Kp`{W5jZt@@AWpsb67XEs{ z@E@*3zbF~8nCa+I5LFJyOQe5vP)t~y(NAz!cBpWT$<~<2s7RGtpo_n~!omrUN9CFZm9)c{jMO&; z8A+RhxWD9xOD03?$xQF#Vw3gK#2UULWuIeD1^LikQ{7}HrgCy(_IG2XmgNFFBr0kHV0(v<{*PM z2T#ynX8c@(UgkdNJrZ0;x#;5~?y$Rn!7F-?1KP$jx*CT1NFJ*>^o@9JR_U9k)8CQL z;CT7?8V9>+GeLS+GwJ%$W`Ydt=*o8Gimj!9IQ&fmyWTVHx)NRkW(1i1zYhK3LKJLRA|_tmxNR(f^|T7cL6@ z7k2!Y{yP)vi{C^m3^ri@okJ@OHoRb91Ff*g-CQKCE}Vj1{K53>bc7Q3*aD_!R}DpW zRS^96A3Zk~2H8`7voZ3U*(C6#6Jqy66)PahQi8G}$s%|7Ucx3(ua7GX>Q2~r@neu@ zu3=Dnwsvf_U!rIi1tQVJpfs8kAB6Pd#C zs&@^7FZb#d=1rR<^6kLkRcjar2U|CH`(V|E4CmZBc~wDiJt9slB2$>iw+$3=cD=W8 z{t4FdK!ngjDmJ&Pk(8_@Z6_tRlgUeNCT*o1@1`O;6rN%W2{TOiFIZ9T<;Ii)jYgE& z;WE}2=NiQ4qKt?&0u8H~?f794opMm9ts4jCw8>2GGW>V6#Y|r?rYkvE5K;rZs-U3? zK1U?=6GT$CAd=eC#ynU+QvZQSYDYv;_Y;uR!x2gS2_mWQP$c!|gqem&>M1b#9g=!3 zaU#nRNzJFg83Y{(u!}!rwgT*8hj2;2A>kzfheYae?}n#t2ALtB_oP6*do3KIj)%Vk zKgInw@RL48C(!2BT0}+(KpV27^P2)HD()RtO1Rt!i^Ajx^9Mxfmq4gt3Exd-1);TA zONzj!jBc7G1AV!7$VoK4bs{IXAY@WNPU0WV^5KY_JSHzjI z5i%(tC--eHD!R-$KcG3j2a^2l2d<=@Lm1|E#6wb$q^qkuW-fvx=L;Z7L?Jv*LbRld zdV#D_Wl+Do@udT+`L%2=pZAljLBh6m3_?L2g#8afA*x16$6B&Mv`NCRB@Jj4GecYh ze#L-yK0v|#4YC?c02`2v!4D!cDcpY$ZWT62c(XBGsiB9uRDBEo85Ht$hI|b_G>r2l zW5WoEe1mvA^3BO98>kT@USC9(*uVtwIK0*%M$I84 zA$WjH4J%PosFrW8HRMY`CcAm!Wc%&qho((gv2^uXRrA_aCruPn7nzz&J-p)D%|l1` z?^jtgx0zm1B&uceEDvcmsOr=Q4xd&WQg2+o#%lcv73t`?+@|(mTW#avGxbZY8&JDx z^~!|`X_$9C|DxWYmH)($pMe^Cbzkp4Cp30yQ#H%PmLKEV{Ra-ZUwx?uo&r+1`&Dfo-+E<)= z5W0bCE1qxr${+7&$ls^jm7bN9rASMQj!s30p#)j|-82wiYf#z*C+iKb>w3v@i!{5B zDegWSLu`U$gJVKeG2(i!m37k;eMTT$hx9l$3G+k)7#^ATz&7;4b|Z#!EIr)qRnYHE zZ`lm9Lnvw_zI^xY*~6Ag@>Qf?@GR0}ghHyN1eAx3kd0iBz5HvLrX$n(_M0V*x+Rb; z{3nsN^gnLnZQRIjN9=s9?zqen@$zKZo969)ksi@Oy<@~tnGyNha?q(Q?nOivnf8~8 zVMNC~)E|&;{6?c2sy0qOzL+=bn17tTz_0%XAMqvHD!0Q85qkpHTLj1>&Zc9Sg9OPv zkC0VH63GLRqeL2wr@j*h4YK*QhP-3XG6~tJ6H^7+jc>$wn;(v#tPU{((k5i>&pwz| zi+Z2w=6jZAn;A(LGePuNiPqtd8{k_+g)QMtWhrVAxhh`Zx;4yCmF6N!&M8T#Q*0-L zT#1F1UB4pBCWx8+8Z-jt)p4x;`GsIw{WDY~1=)UT@1 z*x8T^dAe5F;9;UFF?{h{t7{#AxHX5H~yJE_+d4iF!xXJGqzd;zoYUooR|@ z;>E02E{Le3smo8bas8YwKUGh`Pqn{o6zoi5#&E~#jbThVj3|HW;dbH+CsW_{4fWqV z;!b>I1*b)IBbfJAc-5Ha8gNUkwPvVzub=^Y6*XWXRD6Z_iCmnl&DY4+mAj(+QA#?> z9~FzXb;%!<*EY3ce@%-Q;m9eJT}0Vm_7$3PmLs#~3L>bOA-cNJ`1jQp-!Wv6Zm#V4 z`mRsQb<{Oq&Y|-OJ>E;&m!NybgdyMQmXF}NI5_1m(7;MrI8Ky>)8fd%c-=Uf2lZFa z{<PCFRvVdk3OcxEA(>&Kd*wDPuAAJ*j1Dr z1hNK0z84uT+ZGTM9jI{g+EuElZ)hr3CB!Ah#>W|TiZN4!;9G^}EQyWh+O?~wyi`kG ze)0~qy~c9)>uH@B(e|uGuSY0l5`|JK(eu!W3^}SR!j_HYuD`%klxg%3?_Z_2pW$6A zT`AV9z(RuLx|=8?i+AsI-3=tcGVMSnmU|#nyLtNyE&DSjxFY0^UtgqKJc5hme$;!g z5zsM=E6}n(nqZnsCN$9_6HJw^n~M(ZU#SQEk;y9VExYOP3o{M|2;OPx*FRNn5LVu% zZ7Vk{;0R8eSZsRv>J`De?{R2^;Mu>S7Cw?MeyhOGWJ3)sLd$wiLpmDnL2Audpad_= zdpX&gqY9TVSKd&$e|Nqr33qLnmjJN{D?6w?RL0&Z;0D)Yxt@jQWQS)f>a!~vQF{m# z`nCls`~%Zap^v?@itA)t9e%Nqi2~Je&Y3Lm2CqP&0gdY{I57D42eQV2jGl+3cf}WR zFR2$^f2q)in*GPuq1j(A4kc!cLE7ifw(bs)h+W637k7yLPO zJz^VP(BAeZ1vjAA^E+%Qf3ET+UgxLLYY8wX0aG4SzrBK-gWeS!qGT&6c%l$-vO6hG z))sNHm57rC8=Z%2@OwhfFqYG!8jvjp6M47MSO8AIG|&rDWHDla-NlVPpyJ0makEu^)I@=-xqo*r1MJ~k0b%+ z@l2)-sAKQBFb;3-p^p{wY2q%_V|yQ482OeAE*FQ%`fl?iBFSGYL4THDAigejgX++i_l1nko_Z99UW zuqN&fV2}p5xD)&I*E{UfU5b7B>mBy#t{(f;q{ru6)3)LS(k6WW4jr1E7#KB${0Kz8 zMkMlGAIjk(iCq{kzxdnL*}8++B5Eq(3E33C)q=@yVRDJi@hwp0ADNxfoe=OY2$|8t zT@r+B5bvVJr{X2{0)kzB@26`Ol414gla0}3V2`G-7t^<(m&*uxDTWGNDfZV7nAR(l zVJL0?lX48fNw+|j^A8z#M4uy=ip>2V_HdSUy0}ytPr)f5Gy37h1GSTPuRc6HohlT1>#O<@!m(b z;QW+@WqhrN96XEQmI;N>{(kxKJ60n?vFaQU+wue(*AUf`JIRhD03Pk-Rui*o7=}E^ z*9{;+U&}2r1V@kW_CSTF_pY+$qpkJ3RVnc~Dd{PpRlR7Oh^30L-_ke{a88U6__WTr z63VW)5?3*a`)f5_B;-L^+0@;(l)B057 zEAOMLyTG9gMV8{T(19F@;YET5wh|Zn0B$Su2&oTP!ARzONE2SA=`h(KUbdN`fDnX( z2z1Psb)dq-N6y%Bw%|yu`%_8SuF2k z^x^gBV$GIxtf#Awz@2TzNsLla|76(T?|>2!lQl^Gz#(@=A;c)2S5+7Qo2>AFw}?f6pXg_pX9FBSDO zho)757|fm%;2)I~{sBIS>0__rEOeWBAk0GlOtJ(P;9$S1AMEEMILu042#O>DZvkO; zPI%DOlMFF^GhK%KU;$hrjUo%Z!TYShFz#P>8b^ol=sUurKkGP8cRzkO|KJ2xhl8NXA~qdndWBH}AUl95&z^U)I0znF#JAeSxUD zF7B~U#{n680y_gD&IBshJH*)xouMB4Mutw+-^Qxa-+nrZd8RYOMtO&U6FAKG>q;q! z`83%p^slvBHTrZ!L&r3)ExTrt+t@;dLCnf4`o`C+_983QJ)zhdF~; z1L8Vw^yd=37qKngZJ zxJH3=wb-`8O>6>svlee&#+$LQ5nG{LKqA&667e}lF_GYeSUa`_)7-)|3*N!){#*V- zh5Qk|hd4bw+>)aBF6dEw9}D?c3;AEb{QrjWD-a-l`ft)%@h!2u1_tis5ZWiaOBb{+ zKsQjoM|j2kiWI=%myvf4CVYbf<)P{OUKbgSeLjUDt9Yf11=`;?!4w0ST4(qQj~Lhm zbZaT{82Orp;7a#-I=gydAxZ?NuSp zH1dguS71_VCm>djXU}h~b}B+ZETs<8d`f6OJ%tV5KZ@aa-JlG2k%s5q+db->uNZ&? z8J)v)&LcRXq-j{tG`fe>S-v!AgknSJr8|+p=-kja30tttxJ``azR{V|J+cAHhCf#u zBJ1+CY!xyCaBJL3X#vf)HD;6^Qj+WLgxg~mN)4cUW0h2AOApr?+!(X2?E)0N8qd+L ztB`TwMe8#(Asqs1LYW(@;+>JDdHf?D3GQn1=4JJ(^J%xim*9; z4(ga>w`8~Ns5KJIUCXo0U|`48UTF8gV+2(&`I}J2+p{|=lc10Yv}q6p*?G!?rZ5>Y zIzC6cU<68tbcY^fAQ>D(eUt7O6${0HRf%X~>pu%r97ew)7z<0U5HdhT-LHBUw8m(mgJz2k9U;hH* zql%YFy8*+t@rnm$C$4>-hl#G;K17%aswN*;O71a_$_ zNLfc;TokvGzM^6zTTMcv0B%fBH0K-WYXBcMApqDAJ}hOL{t?21jOt0hRU|IOZ;?do zStax<_$**b84AkmOrg(LV4P4GdOpI?zsSNVX8{KjdM-c|^8h=U9>pnz&(Oji3w@E| zdx+XV&;xhI2~R%cI5yyWWt8Zj=3J7DfD+u56+iE4U}9yIVwb$uTuxSMVTGhEwIQ`a z$!0Wz1$^-HiPEsjUQS!hU92tFnJpRVOIV|5aS(jA_Q~oan>8y+of3`M6N4fSG5W4k zgDb?q_DpSY`xh`*w}=*aJQkSTU5Q(P^Vps0u{+6QYxz*2#K)R{I1Aj_8_jGhzqUbk z>EvM?!2{&5hIGTd-4J02ZzNwHA%+*`E2D_g3M?xmQ;*JvFM*ZA7w1tAcrXk(MJAEY zNUuf2c!H_Y9xQ8#Qo`QpSgQN@5EH(gM$*9@Q5o(y`A?&;WY|KxSK}bw8_k`1CABOfoh(IBS;*<4OIyHm9}a zq5R4Gi<8#c1v)t^?Ke9uAx83!Xvw?;8n>oiycOft9F((fuAvlFcj%?L`;(IW_vyMt zGrzT5^lgMHCL$s>LSZ9G#Y38cee+w?g{2t2W%T0N6X&j~Yw%D?hhY>Q-9#LU-!*_C zf{C1nnJn&N?4_tPMrpArNvX=4puB|2>L1B7Vs^x&C@sZXW5c$}$;T#SjQMC~l-LPI zOowTfSBzGP>u0x-?rYgz*VXyU6~nAn zt>37z+Uupt^%rfI3^$uRmV7EFqko(H2Z--Jfk96!F3vipoPJTXzSb?TOkPyH??_vV zTR^UI6t1DCSC%iHASa*An=#2`@)_Jb8eP6}zey?Wi#%;RHJGT4HBDYk&CmzU_+t?l zz`mLpx_0$KdH=^YKb|^k~XGT?lPKIu&fR~m7@UEhcF+$exTf1B_c}kW}DaqXH|r~D7;u5 zTdTMpB_?0>8$o80!E$1JZsGkc%9`Ms@bbtQ55GmehqLv@2}D@L>$%&Uw!$ZVt{KKBeI9V{jESo`bdW^MlJ5PaiW% zST0$*^80BcM;S#ze{oG@NjNIfi&Oj)tgYl7##-=6lQg$3H{Gwgg~9*_#p6L@eqzP> zb?LpOV{jgys5VIB8AJH7XN#Cj;kSw4%XRj5CM&ju$HYXaA~uQQk`rPR6(`DP_Ni1Q z1;>WRM#e_OYzyl#kc{bAi2@nuggcR5ol%oof$pfCmOC8M?TnBx{&nmjdlU?U+l{Pi z8VUxDLBXIp@iiFq6UJ4M$#+I)#H3=lxwzn%z(6^oz(ga+vQ1O5M+Vo2)Ca1EQ}rMs z+Ud>ruYq{lA0nHM!)K{22yr@xD5Zda*tlSX<9(N~u<5$|sQT1{hO%H(sL8AnWqRB0 zuv8GnbjsxURjV&~s3Ilo>xpjjz8@(kV_@(GP|Xkc6S(d{pk7Mnuqi!Jys7L zymV>JRbORPh7ffta63waH$f{t@Daa87Ja@nHct_+5ykkdjCE8vh=Z+Sy)od+SDit^ z{(SiQ8qB%vcym#`YGB7C+1E?-F}MDNZnfl-@x)+BztK2AI9vfnq4{VScAvabSxm&X z*lh~;Et!{8sQK1kl7`O0RI!<3XjrH!Ws4{&J3pyOaRfz5ChS{xZ0D}{#1w?lD>(Yr zv6#ax-g6=+JwXS8oj1QmEl~5Z(36{BQWJX~<{{sAvHhe;q?eq`0MXp%;YzZs36@FV zgPniehRJfInGX5p-n7+Lo5v~1J=_vxt@`<;oV^ByC)*F!AnWw$P}#9Pd4-2hO~9yc zMoYfw8={mBCG)*?)2M=!$S@Ck)lhN`HSvC{4SWce+3GA!Mm2UqbX;7n&m`mF8GH>_ zQDSHsnd)unZx>|Od%Ku?22~>IIh@I>`87TU=d>_f3twSPXXDhVg+=)7)WgshM#}H| zU-2tat{12K=9&zWlaULDe!We}U$E%7AeodryA_7ZVHAcM0h9kXqc=J|ROLUR3YeMYg3*HHX%BA}_Bs*f*q6y?vB)#@H zJN=QfYF~JDSan3Sm!GLG?V|Z5MVA`nsZj|LaZ0OHmn5qUqfuoRC;pJXIQ0^`m*+)n z%~eW;1q>}Soom=F$Y{aC=V_FaLRTAF{pm_}3s{7RS71@Gdo0 zfpibIl&p&4UNe8_DRX;qufiXDw^vy*DGKcpSRTPJfen(ehnxJyB%HxcM>FZ{cQJcV z`(PDzJ-m!LUC@TMKg696S_)O~<@RFVB$`Cu2JI-tz`*T2+%j@|4Hn=kN=ZpB%mxXz zhUfJN1hT?5}CcS;C z^O@u<{Qk(`_-(_BcA~lG2T{MmC6=~{;a#$OU&hai6I80Og$e`)A;g3*!f#aL7 z)_-_y2q`c<@32n}YJ%>_!CgxLWR0?c0#H%2fWX z|9qDXN*7B@SL@)N4!!DjwB~CL8r8Js-@Y$D7Jhc~5#`~{Yl;^t)|h*HJD~zbAW~@1 zMf@S2?>f2d7cj(+6jC%Ouh)lqbF-0jwqFg!6z*Q#fe!6)-NMTpA}}x;1Ksp1e zBqhQ&a6oB{Hy=yb*69374Eb^Ua-KdGN8?FQkh3?gSn=XVb7DY@#xL*V z>>ZzgkNyptez+QzVAFrAg*2_c>8I(NKEM1>zE+_r3iilV<-6|Kyh2WrwU8+}9{7A z3gh-D4mJh5RjR67^R1T3&4V_1Y*E_SFY#Wa=&Y8JoX}m--XnBV>0vZJJk%Jc*FUYt zuuXq;>yBdCEDs~Fci_4G^Y9^_W0ir++*i7r8ChU>78*A!5kYsz85<~0LX2IF5Uqvf z*WfFVU8rvC*zphpI_EXyAILmplz%Vv8T639XBJwG^?0Ka&f@Xta-(6PHG{FvFZ2(w zp6xWex9{R$Q`aR%&ElN;>>o0HNNzO3jeQt`t;}>-sVd7N>)Sj_Oyzbg z_@vKqrze{(^h*afxPWp-2z@(?I>=|&le5kkkrK|L$~SKRkJi9G1hV+9qRDu*yDYZuY4=dLDmbkY@DiruV-)W*c|2>Bt<9ufx#&_af$hx?y^4VqprYAv{e0h?lHAKJ=^|#4#D9% z?`sp%O)x**6vh~xT+V0{|LQgzCE|b2Wh5x0ISl%t3m$tW9b;$c7%SS15veu&r#=Q~ z(l65*Uc#CUk&w|ZT`#sB%q*x=#*_V8-6Rw=6MNdN_FtzMwDH6v9Aj9Wah*fC5xnUS z4rTtXZafU+@CR>ac9uf8?bVp1F9=Ty@`}Gt3&NY}q%?Su7gq2U&oM|!SSmpL+#SI+q`We>P+X-jbg1B78bNviEWik1{%}bc(5TwzIq00Le@*|exu@j6{(Gi^W>yfH&VRA z);!Tl@x7Vv7JJnuXRozOagar7nS{gLiZCZp+xbId!Be)6AWikHl zv0D@arXBv}_sjLa))a2vj>L+8C^~OKbI;dm2=Otf+fTPIsPDf)<{V-hzIp2;zokw# zGmPx!29D_`Cn)eU3k@hePXB~c!KA5|hL|q2o#l%B`=mn|=Zp83AKhPkVOLqICN($B zXj{i@*$4+B9yq`bhTW`8R%ewf8*WJs ze|wCKZHmsRjcQap1U4U0ysOl+h54}MSVnFAVfi!CEoZ9rhV2nf$_9+%nzJXNSn+e4 z=c0L&-4>~4i_wa5TFf@xx$i%5;;_JZZa#7G9(V#CiR<)2jX^seM|v<)CtQvOs*Tfx z@Na*0n}wR9xO_jv(E~lA7$TRLY@Or1KpAT9@8IodWREM-0$hR;pg*oiaQ!O7@*DVt zV&Z5cgKs+ql5lZWac1$(YNMQ!sh4la|BEp76I_qHD`5++M|&F#bMW}OoOn(S-?+hP zQtv>kU<=>PMp|)JX?oSJYNIC=ntk^ayNGuKc<&NlZuK5ouF9~@u*z~VY7+aE1vdva zy4>8*FeL?+qE;?O;hcpM_WrPC1KHw_A5aY+O-;xE-Jpi~HO7$H?7E+Q{2E!Td&TWH zy{0T(VL9E#CS$jw%HLMxTd56hRQ!6c;nzzmw9`{maVQLND5JIRnEc1@E9YBo2zIwo zW;u%Xl&CW*6m9j+E0>yDe~$`c(rvLVJlky0-U#uHhJIY<=bPom?TsmQFtjeMk$vHZ zIxZ=&Y%3=8cR&0j?)+@zhNEj|8UW;94 z1g$rU5eI9$kNP(ahJ0i!O2e?&0UFrkgZ&1g?r>TNfG84x&$l3(NEB?6blHbcxI3V$ zhrw1%$uESh9Sen$F67?onG=;h5sXClNfb`T{b-tn&<~wC{~?ckkeXL)yz{*I2p=RU zqI3aT4<^;a#3r^X6cQ0lfs}OOBq7qR-%KXs&`5EA92ldeWpTZPrdT2YY1)HZFis95 z$K5BNr7FQuV)!q^7F189XVz@IxDAIE#bKn8#C=G3=Or#FQG zNel3bkL?_D`jld6I^DKH9!6Hc4c9O&V8Du&^eBY8pgrpGACyap2bN>$g>f3HNR>c;^Gz+9jwItwvgxUJdALC{fgt*Nz?31 z-2LJbaO-@XN6zDh4$lVKZ5MSFT>k`LEH}+RkmfIx`BG>8<(PkuUzo()J-8rWd+0uL z^k^3oS0P8~SX}qaYQPi^9T%Gn?}CpEg2d#*sJT-IE7sU$?(kLx*@=8B>ceVrS-XS; zkWVfJoZ8%|YO-BXI8U*0eTcV%D&0}EGp}-2y#hXL9`#kCiUi`aXB1Ym4JRr!EK=jL zcd7BGM%dfLZov|Ec;c4hC%W_vPrN$*nc~kIPtcn+`nv}MhMG(ueYdJc(N@o)FvVwrj#zgG38VZYpM(yn!yRD~2ii%k&=yjO>NZw&|wFlrSi??~R2oSAzt?Tn_( zD0@#~TAktoangz{AX(<;6}wrne0*X1jaz$8mE=Tk#~3~TZ@N(NI5tcfm+{Y9 z$ZZ0Sfpe0=l)_y(%9@he0*#`f+`}$MRlYQN{yaJP$bIT2bET`JW1wyL4!d4W$qoC8 zD~wu>7XAVs%Wnl=wQp1I-?DMvO2slW$Bp)Q#QPeyXvh}$jO$#D^bm!1MBd_>G?n5R zD2j2?+s4Hh2>fUK23fk##yxmWA2bnCN)+a88@LuFxo*IR zQ7VY6Araz7$p;?;qtKQGgrZX2`}+RNx&K?YY8?YByE-V2te1^2OAFXXTVDzjH2FB} z+qI6$&~U$qpw8(zHA{7_ChKPyM5kv|{|TmpuayqI_Ke!Pu7UE=FAN=S`xIAx>gvex z@xFL)Uq{DVoW`RXW($+f7GWr-hhmIlJh;_$@PC^us&@b%NeD zbi9@}bh9Koeh-TOv}I`zob3|-(NYDWo^y^&v2)oP;I8xv^7RR#3PO`$jRvW&pK)Ca z8^WQU2ID@OHsUL6L^_#2FE_YHmqNpPy3t!X6pdVlQ4f5&roX?sZNy#2U)?r@cDsW* zev%|I5JQb7!9Wbkj_XU;MB5)vOu{KTO@e4tk)1e@h;e50I&|lO2e3)J#`==VZM)Qq>?XNK7wpRkZEg z?3s+)q^10ka;m+7rLLf*mg;0(pRe&JWDQAq<;@Chp1ozVs!n`5!a+MtG0(z&8mb5( z;DT>2PsYeCPN-5ponbF0qw{nodQ-3A-{EMHH4xAV*N5YoP0H0Wh}~;kgg_#g{fjIm zC=zWM^U>q_BVIYdNcVI18EriV{aC=Ck);MD`})h>LPNerK-CH^cWb6fYIRh79K>jo zzW)@%OjoES>@#!z5K6^OCm%b)#|gOg_<@<_c!9CPX$sTbg3CHol6yLx^l*e8c>C55 z%xs4Xj1~i|{{D_W1b&yKvK%pbJ#yq5X+`+NIj`o9+wc?<`$tBm0YN`>gGkp|$9*=I9$Q=jm3v_bmyID^cLn=iL`oC%-uE}=(noxiY_vOi_b$mM48x5j zbbBg7!_46q7QYGUZeY$22QgFmpJczoAdbC3x~-OdGeFcLK9(kke7-nYVa$(hVDC6_ zSKo=yAmxdIPP7;uI7HM1W1teDAM2m@a?#u9(inOdBwS9W5Lz4qQqzZL2oj$Y5hBZ8 z3B?jTK_wfcxgobHm0oe+*!ECMBwT%U?~y8M`w2JHJIFR z@Avcj`b166)ycJ4IAD%vdz#{Yd*KD0Y6)+ z$NFQ3B%3xI<8O%S`E-}ZXZMxfbs9F-q z+LNf}fewpOTmIbR)`XfrW$bb5qS$4!z_h*AyFe*wiP&Q%SD4*9zuSearPX3v`)pJ5 zY&KsxoFPj@>fQ$Pox_Xw&ex{-V9JP=nwlwlEsJK(S+WE>J4*#72pe<4IuGl2E*)Ml zbjN?eKzFB!{cP**z{QGAl^#!bpE52pt<%BKf{<3&fSvt$4J9iv3K<+O-M($}0 zu*%)Zdv}`vFvulo<;w3uxAzM|L!O|pR|`UJnAQ9;1}OhaqWmRL?xH5?jlHbV^O$v* z1h$-VBPGDKq(ytpPuHN!I4M5Kq`mQLx#$b*fi+*JFGHQy13Z2@_|1g^)>m-8_zN`N zC#y9st2O01q-k#w3P8cCnkQbm&fKeJk*`Ar%2k54k82s0Fjca?4!YLR>aIFK3K^J4flA~c zDv_J0L=K`7`3aTC%}G|rw4U?i9$_h$H_uJn;ab>-&)U|<$q2AMMm@CA;>cMObNK9P z{u!sBUfLGn+UUz>K3Q4qo7&tmcg&oTLnHddjOo>{Q`~&4YhNGp)v#V)^@)^ZM)uU8 z9zVA|WHWzT8SlG20HEI!qpiZ*^Y$t{AU-~3;qb9vjfm_rtV=sog0h&kdN7R)NLVZ6 zq$hIH3OVV8oIFO%3;zzyWW~*O8G&m(RPbdrST3hhOGpImll6{dQ<4p0|k~CDWjy{L5!pGC)b>Tw|rHe}#blQ6bz7{n~GD#WG_khX8{TEH}lPsxv zE$JkPx+e)$@U57Xm8ml=UyYePa%9Ayn3%q{maofUj!f;^ScCPATHL(`tNHH@ptR}9 zw`wa}ig}UOq177`SAD)>(o(zQWed>oNem{2-im2%{Y@=pO-y;YO=czRit3A$YS zq6tAXb=5(ekIEGdKjpSIp~kd3Cjq)vU@}@dzpNe z!&EaRhP+0|a7|P%?9_AE!RuM7kor`QXrVB;)6UCVcUi~nHYZC(!=qzl9Ldl$>)eT204uEiUzu)0HSkjK_oyUu!fZq`Xf|@PZ#Lo( zDcLP$vY}03-aY%!Md;a0x^Q?95*61Ixx3K8MN3jo3z`u@Z%Vbq2c%l!o0Tbs$}X+1 zKUSv24L1*;GL3vQM^buE!a>!PzKCp}3^__uXq>~;I%TA#s>6hu{4sXT#GLkxQU$Ur z#5~Nw$HI+$mB-5va&7rR`LebM^O(X^)xsRH_TQX{=IKYKy$NdhZFtwbt$*(Max20f z%!;t%Fc%A9v&!O)E2jRfTC9TypamzZ#YIb&t%!_68>x5q31hn0i!ZY@+tm06oB2@X z(UkV*JJBeJ-@kAhS_OGGgLVf3k^ZrP$oYXlM40@EqjX9o)d#m(_sCl{6qj+ETtw5B z&u!g)W!F|Lplg>EVJk|N%8SW*}aYoOOl{NXFJvc zywcVJ{EoE%q$Ak{Z!B1Q7UTBqu%_eysD6prFM<6mW?vi{2r-20-(n=PaZ^H5*6aee z7CZ;GT$zcrCHG>Ar*yWM;TO=p7eml~76WK|Mw&>A<YIUO ztm7fKuyY2+0gYEw1?zcUufK?SGX#KrYW=;}^O)w|m=6~u)Kzv+8U0H((-?Ie$a|8= z^$SGN87i;KvbfNc(9}!2N=pl1KC@jtXfa=wg>;6>=ohVsPExTW4h($aEwX^*xa6)q z1NNC8XEP0_7u_UJf2=euT;irae1rP?Fs%d%AI)bDXG8bm@Cdbor7X#o9}kmkxqn#7 zmNSPz_LGM@SjU6x7cRNTt_GrI=GK1wm`JUzvQ{%;USAk=PD5cgu79NKW|(hn1yy9q zK$U&yX&yvR^JZF4^I%=8`6u)=Z+>HP^cXhZ3hy3DvEhC5VRceU3yW$@a0Hg@W-Zw0 z`78VHGj>BAGmkW%iPIvQJ!(Y6fH7kS_8z=s?r=ZI^N^8j<;iI`)AffH;NBff0xUPmO!Q~ zl)*N2K)7>gEXWS~pqO#!u=noJ)VgBg61(Hu&q0RWw`oz~<_;|=JNU?!(s(OUeFN(@ z5x)I9uRY{??esU%Wvs=)GbzXL4W<7T-6DKL`RMg0hFKG5d_Fni^XZePjJJ(w)4%hO zfdl*X8!ErJG>S4t2{og^Y|_k`#}%Rq)jn9#&35B z^<=o(?Da9kk5L;?k*kyTXv)IX{D&yFkSG27j*}gV8|8NoMG4VFmtm-(q$G{uS9Dy;jo@Qyym_h`mRbc;Bb=nhR7j0HBsFSFsgVa# z!yN$am*C^-M7Y&UonSH7mNFv`$&9J8#Uh(QX>s_=KqNHO#69Ni@)hJ^0KH`UN|Tle zDX&wKZd>4((nm@W?;-9*HE#ISp6j@S_95htC3 z8=wg0QO9ENcyuhrVUkKuq;}=W#RG2pTBS6fL`}=#_5x$Pl$=AvH|=3*i^%fCm1KpUipb5 zq-MKO<1qn$f@hwB86aq%3;bzbbm`650kVf&`R zm9sX9E?(HC#yCn?dJgH-re0)&_VH@OH2VrKOc2mtg!BoBxZUB<$JHCPbQH2VHhB#h zK6u2S5zG3AFJH8D;j&ooDPK&T5|M4@&WcYXzdw|CVhaYxZ+&s51HPMX-@8R!c&hD| zMOb#cTiw6=#BR0WZu8LFsoAk}QPn!1U}RbMO{4F=y>I~fSb58nrR`ICS+1#VklIxzN#Wfm(RM{spgx%=J#GJI7If&g=dQ_RiTb z$Hx}ep~fVqua9k%-Pg3kl%(vK>Fb*`)7MWu9Fj85a^K8@1mn!cs%idy0e5i5>}6XH)@MO}4WJ6(+KyzZrbvi@g-(GYAXY^Z1GYZzi! zYdC5wX)I^#Y#eAjX8g{W>eb1sx7QS}-@RUX{pIEK)_E86F6&*@yQBABpFkh8PZOWj zKHvHLV9E<%#hHFLJyD7%C6#f?8fCMxUpb>(@eTED>D$A1knaxPKYZW#alaCN1N}Dp zo$@>9chT>mzuiCDzp{T@|55(&{&)PJ1Ox@-2xuPAHK12OzktC3p9f42*cGrZ;6lLn z0nWgHKzm@0z-ocD0(%F}3j8W?Mc|IWqk$I#Zw3Aq_&o4cP+(9*P_Ce&K_!A32ek-l z7c@9%M9}=8*r44(mx3M#r3M><1A;?>BZIRC7Y;5T+$^|5aOdFu!6SoXf~N-03|h3UF66V2`625SRDETRzuX3Cz>UVYOqcTQ$2$ zw&;GB?KxprUgT+}hLRI|o48t(3Vsh9ms-?jZdjcD1U zORdg5m&6XSDf@KUOv=*3vHKSt!?MJM%@(y;*5sCBWq1O1_P}I@HpYsM<)a#pZ8fnC zbT5zJKlZ@LV`bDO;T@rzFm6^^v&J}n=iqhbywFP zJbFJOdDPy18*K62TP`aX+40lK6T8`ydRx9+vVPW%$meI;*fn@sp)-pXAH)X3qU`j$N5k4~v{8Z=0UDU23XPQf8^Y zSR4(zV1H52e0aBs4I>=|vp-ckVsjeZOSSM(+Wt(bGNHUxp=}5c4Q^=fJfnZ7x{Z^f$VYa_2+SbH$hzHUqG&f^isM(pjg$+op; z;}z8+TXg*VvmW-OUY1!))?>rT7pI%%bBG#E9IXG~nRD>@RZgEDVbX^5-%&9(+O8}d z{ORHbk&dQVI~fIa$Hw>~hnm|z{^rW?>yg(^Enl?RuDqjax$e&9Qq}T$QnlRjy{eWc zP5&IKmIsaLH&Uuv-g-z=wVb|R=aoyx&%bZKP9-&5ookti{aY7Aoaqm>;#q1m=~#Q9 zZMyN>v2Ax&i0sjF{J<{u*q(;vYj-Y6i2Qv?(T?^3UXIGM3e|P+h+2CZ+_`#c*Cm<2 zYAe6(bT#tpeT$ZEu#b;7#Ej@M=99=`wa%&^eQEDd)H0s-s2SU&L;G4YyjyqLd!R-SF~O4Qn07%!MzW5Ldo0%2E|d z4=z(j!B{hN4t`S^A6u1_E+;Ib`m~V~`}5~{u41#jmoL=32Q{?KAK4+cS|k=XYTN8h zQM2Y%b6z~Uc*#b)LSyIAHRN1HEP%%sh5~B7Q|asAbJ&$WR=MMa0*xWE*NRQ5&}ZF- zKI=KP=0gmt;}h;S^jXiN&w4Js1H9CxxQEwiwf$hMwpXz2n@u&VLY-_^CM2uv64eKZ zeD^+eQ%s5^b4+9K4_)t+NZAw#7c4!>-timB|(!Hvn= zQHJC5_pZ~iO^>ea2DhF#Xv)xOqp<&QRLU*Og99ZTxnibFnmWneYCwzLpF~z@dhDs{ zb@Kdoc6?@PZc<`H)q4q!%`=TlR>tCoJtH56Z*pAdqAs51HEPJ{p`(XjYsufk@x^S` zoTbYm7cZWOy;u}W{Z^eC_FCR^_i+0(FZ1&@L;LplG@{AAHs4)1viDq4ziq8o*sxdV zi+!t>#&3x*KT7VNRMTdDKIOIE(z4&S-8pf-7^mVHvRFl`$0mn-B>ONs;f7_z|hGnZThb8j#;#LFfb|y;j>4U&nCxwHo-P@%%D-dBK!1SzVq_^uZ~W$`_HOu*lnD)ZJGil4J8vC zZ?MKLHRTV(#@G1leq*YaBlYzk21WJ3g6$`Xd{^=h=hUckKPKx^>g=&xJab&tsX4U8 z+Ci9-o5!JG87!7-pK$2E^;oWbqE6a!?V?z&o%b~Mm&S7K23W3LAIr5n?sV9_{LSA~ zg8nk>7OC)S)vQX3iJh#98fEaudY-qGZbRet`}J*Wi-z`@=tJYeM8(qe)6NwfJ`oO| z#7a9pwQVzYIN9sks|b~EzP{&#&A*uCvt_#{#Yd`ve}1RxZr3?bX}%r1XQiB8nVftf z;%cLVA2n++47+DxI@SE;yH?2kmijcPTCHutN%ry6XJQHMf@PS$Wq$G7>9$qMRQ@rIw24X-@hxnT3=&GzNXx3Ah0`Q4!=`5mHe^ZFq8pfMu{4vrnMdexHUtJjWR zHq>r@FvwBgGIQYE24mZ_ZfU}q$H>8Gl#H`)QL&@k5R6Wgv?yKF08`o?P>g6>d10Wa@r?#u{_!32*#Jx z%IzKIydO13cea{Z_n7K)%Z}x3ZH#*ksMQ>^3||`^t<^1Rb+wJ5snJo;QG4v@(ZgcK z0t$+ygdDC{CM;X34P@+7L*)br#j-MX>590~ONXB^$sJW&M|PxfE(Po6?ONr4MLY7F zcTUXcmx@}nsv}KNOIk&hU(N4PQAOL8B9=+Zw@uy{sRlj2q6Q?4-qnA-{nPzr7gm{u zy$izC*2cMs2FGW{){Z4Nzxrj|&dyoZ3|Z8tXGGo-&5HHuHG9qoEYoZpngmrfO|^aY zjEbRyab~xf*uF+_boQRx<856S$-sj6^`A9iG~3ksOX$`vE4N&T-OA&3sjV?0QYPh& zrE2wtS))%k{Qlc32UPDF_NUEGm$adJzqY1Q)9PItHfY-Zs}xkj}v;Xgg^Vj4fisthuD&Qj{qVZBKkDD!vi z1O=?h7Lh$;izp(!MO41b;L>#(^u2j==2?>hwGhJ{7VgM)V)b$?zT@LMU*2CAAWnNdA)`9S>tAm9v`8k^(}omrE9p}F@O6u zY~QUwHy!pW%w)qrnlqTmu7gL~8kN(Qgu*FVI(a$PzRrdPWUCz2_Fz(U`vi-lk8%1; zOe-9-d~@u&rSVz5oNk!f^NapHBK&7KIwh#(B|8Ez-WbR6GhTsN@kn8YzVM(==9_;11$ z*O!e!y$8uJ8%l?HU1OD$Ar@u(_LVkeRc!1^kBw_rpe>TT*Q$8#*Lc(GlUdd0^|kGB zDLGNU_w1(mPn@v9s#uEWz#?4L@TcKeXxgQJPh+>KgLuAN)8 zPV92fzER(I==u$tSFGE#dF7y9=#ce+RM%#Yo!h=Md9J;eQQ4ugt!l$9eC00nqusj0 z%15RX$~%+uFp7^)yK;b%rsq{KHBc;PZk>n7`7}apRa>>xyNOl(S95=jRx5Z>WJfNMQ?maSEH28a{KwSwEesy zH|#mLXusUBr_<E{VhHEnib(d>12lo^{n$f1zLu)I&6Y21s&~0d6+pvMk$(cK5 zZb7n?Ynx0;qWqAb_Oa7Fkqg;U`s}XOvFE69kYJl5_igRD*qTFut4o6Z|KW5Q>nvospqu3-7dNuPZ&1Kq5)i@Pr$YKt4Xdi*wJ+OJY1cbwU} zJ@|CP7iUuTAO8aUQRTWxk)Qoe?30}$C_4f;CyF;<+j5 zLu^VK>)Mo5nVx|TY!q-{7mCh#DVt54;=P<`papZ-T!BUCJFnl>u z#*P{`wm*~~ogC46d!xwe9lEs~Xh;30&Rx23@#>X(uquAB`MVS^Ni|PW z-xOvK{<>(dTSpiePO-G6iIITzKD7wg1w;1xwRv>PGpp;PeqW>lpQMz|>d|Rlj^(dk zV4jA$GR0}w1PyES33BD+75D_HoVaBLS#~9C?!S5WPG$J0kyx3p*l%q3>7-2=i#dqh zl+eAYw$4VV0}HCOu=~r?gVFPpJMt_azZg66j2)rv$aCh>4?Dj3_P~yA9p~F;Oqvmc zJqCMqn}`Aa)}^{s?^9#ijPSY7W?WTSgnHdeS+Z;C&P7|jXB%gBpWS*^w-t`Q;Y!L+ z34FiWUbkOrFIBTGT#mhPR-r{XZOrsx10(#6vm80_UFA!)9=a5PJ?>x{meR$#3&Pf` z11956oIYXNBwN!l?FV&?RAk$xQ`)wcjvjGd%FrewT0~ZAu;be+7dGFsA4&KWZI9CO zL(MCEsG0g4L|nLJ#;oP`cqL^FPuLC>TuKoXU&){ zeqUnulrG~t)tX`Rm(!JI%8@Na?(ho5lF%xtVDjdWo(fM$cCuqJY>$&2k74_CN_2eA zVg05}8}43dqFB1C#y40B*Ig}|3gvf}UTTglUjDmM&fN(fa1zi#7n#WBjEk5`{;RUgL( zD+`B?od@vJ1X_ib?yr!+XRSp3$7AV~(#YX$*kV+st=~3fN2HRN8a`aXL>_-^<(HCT z>3se5g(R7prU~k+vrq`4sP(^q0-1}Uo~f4IC||W1^cfD> zt``JV98~nGb1-2@>YoQSE;BZCFX7FeH1!L?RG8K7# zR)Oze+4&JxMI2?>MF`8vwy>OB&uYR1@$t+inzB4>D+}j&@abhME5YkB2LCx=y2Ip$ z$phmD6AdHXOTy%W$uIrOu!y6Uj0dJR@63vel`NMCXEuJ3)#nbDQ&h!yBg`sRUlhfC zSyrE&zD67D}abDw7aD9^1 z6_4QeKFm+>E5kj+IS}V&$ZG@(T@Ln4`#~R_B1@A|k ztRiSr38p9;u?s2GRcAT4M(`&$VBj?h)bFmpxHst90qhPj4(Oa zOO_2~mIYy?k>MhA4_J)eh;r?WvM2zz0&ECOVVHa{MPc&541&o9lOLukOj(!)Fa;6b zCe|<=FADmtaK4tb)&(G*>dYcGvz(w!U3Qk4BrSAC(BT&D&#@3$#{3u1suaT4cD@m- zn3delpuASGg7TVZkq!BH27jv%zc2IRlYl)L_B)oF&IV=>Yk>n`BvYdxEfOyt26!pU zPB?#u`2*%>H&$fYJ&nYR#EPdOthn(aagmvsrC~(k#BD%_a_p${FPO(Lchm48G2&?? zMkGEwjl_owBSb5S?XuuAV42TnkuDrc%;_WsagHFI^=3hWBkwPmzc>y9T*x!w?58X zvU)hP0~bCbk`?5KLC*)kRD1B^4U_?}@5ysg4oVsAY0~7i2meW4B-t(Hx2GXl?tBIQ ztOUMPaSp-xm8Wc%^4)FHF~mf-urg13sG##5s?|57q56fr%WToy3WxE3hDCG1cv|4wv%X zRj>1NXcNeC&IiA;&VK?qCCgFI6wwLkL7gsIuwoLY2xo=dV4@4!F;8GlI3J7dxNi$1 z{SSbQx&t~rLVZ8Y=|sCAH;)0WdcfRA{d)m219cc*$ExtT$OGyul&udRiRY5Ok5~=< zBhDQW_9QDWa^rd`QtiS|-R(hPh$P{q?DeG6_qbk7gP|!f~9k4Cwg*^Ttc}Bc(rs^Uar?gDyuE#;`$ZyMLE>sTVcLp5uzQ= zn?O^^i;p1N)Wvw}D&w8+dY!sWsW_bAI%*4#VKu%T&lA;Ftn6+RXSWh;Hjb@**nI1j` zQ&4wWf$PG+bxqcgwPYPxFE*HsVV|>EEITt)X;mXDt6i;e)2wVjgNF69vPF#>Hpt2j zH*H)mD|_Hdn~wQ13v!>E6@l!k#Xe!5vQDfw8^Xr2$?Qw=6@>Ttp``6-u@_|}QFqs7 zjaVyCqYoR(#<3}Ew#%P^`J+{qmE~o{SSePS)nScUYu1JJWy9EbHkHkB`7^Qr^lq}T zeC#7unpFXHo3J*lE9=LGvlupw&2{BrcQ$~HWE0sJY#y86v16Yhx)`#jl0BR3MP$d3y@BlQ zWbY;WaOaMLyXw9n`#jlK$o_%s+hqSr_9L>NlbzC~U;n~>`LA$t_rQ^{UH_L@FDyLZ$lkiD1egJd5g`!v}X$o`J( z8)V<<({E^B{R6W9Ao~T`e@WZG$TpJgOLj2X;eGmd?qjf#9ZhyVvWt*i5~3WD>5r3P5ZNQh9!K_PWKSo1HrWfvUP|_={)4*oGi)Gx8`(R_ z-beOfvQLnGmh4MpUmqaf^%L25$$m)oQ?g%?{aV^aLAE#9{)2%WV+h$1WM?Hi7uf~K zE=G1~vMZ8ZeQ?iy-Hdg~{)Fu2WVa!^6WKk;?nm|zvPTUb+G(&chV02?&mem)*^9_t zPWBqIH<7)4@X!H+jl0R-PxjYje?#_pvagW+1KGF9{&k4V=_9hAlbu5L-_rKdlWih9 zknB*hqegWd)ZZ&R*?Gt=M0Rnq%aUE0?3!fPC%Z9Zpn#Eb^M5^al7b&@8|nQYW~2Yf zyqGuSw+W&DU*B=m8j@xoY6noL54E*&(QF;XpxK&>fm}Y+_NP!EYAY1#Lv2~la;j}V z#15fQA8PwisQ)*%FTLwS?H~&Ep|+VqeTW^3mP$#q9BQJi(j0YeH`L+7&?cCQHo+nm zhl%;y*e@no6HDVXdp>>z}YI-InH%n?mGXaop}@^uH_Y7_q8<%z-yAb z;OqEa*ORYZ=VPw(1MMulUFUqRbA8u&kQS3zTXD*utwy8*)n+wxQoP zoR8oGc~3r+595RR5Z;IP<^A~p-kXo){rDhZ7K#WE;ld((MX(4GVZvX8h*06jdtq5Z z7tvL8!;*xPx{q|lbtQBqb)|Hrb!BvAb>(#BbrtZAEf}kA!khCJyfJTv-biO&i`V9L zcwJtP*XIrR$GjmHIW&dOiSXHlcjrBLXWor>g3p%xQ{IZV=52Ue-j28D9e79dPjyKD z5SVd9ZHD$9?setJRY0=U1|9v;zO$h2Uc zAp_B#TkZ0XGx?Ke?KwAu;B8gY-mgRIn;Xi)tw@@iFx15e<2lhC&uTL>FUpJa61)ii zh!^HLc`lxt=izyIK8_J;UXT}(K6x?tt%?3-RbGSFHjI(^Ky#78eYqd^=K(yB2k~I`H*<2vITu{V_1wUX z+zY-Ld}s3ROy9)ycYr}})IO53S<&(?gf?(l_9tju3+?3>bgqXHe|g`4JqJE(u~)F` zG8J|`mIAv0hCt$Q{)?M&wH&?PM&essEycJ;H1|d+YdD_aLb67Ke~o8Q%a~3NzK5$o zc%yWTi*Mh9a;}d>OML+PDpS!mU(U8+`OaB(gFRxeLCGkTaCu<84etbO58C~#uK^>A=kcc7~Vu1A2+dH`oNG5XRNd{l&20nPifY2fjXfTw1>8%lj7Fj$#4 z0*`rfANDs&u@-nOCojqV!pMdRrELL^ehQS9!o7mB4+Y1z0%l9&-WNy+1OK)Lg3I9E z54Z>iH@5+v%i`W2D9M8SwgtM&;T~hRz-0q)aDHAM_kloAB>28P=u!dqLBLZKq(BGo zK}FmLb1xwH6YzQ=UJ0fB1;)<=`x2aF;7xf~UW`}ccKFj$j#SIk1D@bXjGl8I3KIqs z4wD5Y0wxkB3dV|+9R}E0xDj>)xP^o29NZ?vc4pSq&s4H?LV0yT{<=vSsA~ZK z9Oy^4O-b75+?`JzhUspg^P*+G-SXV?>R0r7u86ew)vVU*F`}{xy z9n#zp`4*sEE&d5fH(cwg;kj&=$kf%wcT)kBb*AxzC6KQiJOJ*51cl5*UVAXTu7<7# zv*_yS>VeW)Y%LI*e5VY-C(jf2u zM#(Zr%wVDyhs2Wpf`Ck%MO|?o=ZeUo5tPzOt*)!wq{Qv|?@Nz4kd~}G8%gzOi3gNt z-SiR_=ighVrnky8of1_+)j-he6XZ*laxl36FVI-#O4b8*)S!aO0Z>Qjw~*zIl9!x= z@gjDRKhH2;l#j-X%F=jIUE~@E#*1XzNRAh!-)o~n>G#^$k9<5RLGZr4gQ*G{V!E zMtIt}V$()=w3xMV9PL^gtI@8t@fht|8*|aFwQ-fm&I1MyU~9c`^Hp5QCLBkcpA4X<08Uu|sV{zkTW1Ml5al7$r z<5?_+y>0x}i+P#60=*)cD`#zi@2D(F$y`6HVHa~b9e%vG50U{akw@)HL*%cm9g|M@|RD{0cF@VrSs*lJg|q@Ct8u z1>a@xhF5sQE4<+qMygBW4X^NqS9rrK(0sb{xb($OIgjJ%N13=7*lFigcF}nZ{tB@l zoX6lV8gj2L-Zcm2GRzg2t1#ceJVNQFI`89s_mQLfc;9`z?>^plA33^@9NkB{=famp zm;WuM|Ane?vGB)6|6u8C){<7gKu8sc!a~I|w%&#!_@yx|n8h4Q`v7HZL^Fc0Ez_-qt&S#>Q z(;*r;pM(D@0P{vjr|Woj9(c+xK6U;8OqCLCAYF9ivpHr>w8qy3i8p^-1tDB5#F~C@ z5alpSsS##JHD@{CqX@WwD>xsBkDagJDp4N>-2azcC-ULV6`VH^Qw8Mr9%8G76yGOG{EjE5M0Mn} zIV*uD_2`Mrs||N(*~zp(N-jdGYT{dR8V};?Z91h>NXwt3w2c2qrtxdM%ta+B;nU*f zqCCD)=|y>zT^(mC+)YSFFnpB5td$0kI|60;3ev) zLpUG=Zm&J!mv7RjEUygkBjs{+v~G=Kr)E6Of~Pi= zrvW}9MKzqOV|H6DP^Kwj${gPx;`%>u?mP9cDDae_9a-p)kCvjfk_#=wE3Wp(drzPh z!>qP<4%F(*dDGJw-`4-(kn!M~B}2)jA97SvJG_{mjM05Ke{x^_<5^F!y1f|D4`r0z zdq73n;ru@BGUJ78X}@)#mEv&#QOtQCa|qK8=lQhD_gv8X)yyBhMK64V&E)W;k8Cyi z!;e4N@*4z$)Y1+Mv3Ri*gqU;w2t!dWh%2e{8 zJaibFl7|bipqqT|NG}a~%AEJoaKN0uIe&FNmG1BzKjB z(8YBIpwi)7FFDNlGmND4ugIkyh=Ih$GayG&)_K=WeHQ8*La}R>h60(F5a#WCDQi3& zZvK<*5<`+FO;jV{!sC$XPCud{&)&#%pw|(??2?PXOGjWIhB+YRlk)Ds!|5rr?8FiB5pf0ju&65} zMF|hLK_e3|@fsKfyNi@fWK)ivzv0?DEmojW^8xzdKs?XsOzB5_ zPc_=(DkE3rbzVpL-G*Nq-eZy2#hVYo2LCvZIjv$hvPq7f@>e( zF{Cf>_=od5NJH=o1(0p74?2MBy9glTN`)-E>_O!axJ!e>ofG$2bA87yB4rb$q$pyH z&QNz2bo1pqq5h8@P#4BK0kUyuvT&a(@(>NHxU;y7>p{ko zbE(IDPUm*Wdl_2-l}0FuoBY@?2Xxu21@ooC=9Lv8C3?}uNyY6Vxo zoX&%2v7zmO*`bV?otq?@BriaAGH0?=t|D+9o^4aj39W$%&XsA;4@jKK10zbzxeXWT z{V>-PxIgi5CEuA@^6lCodkvngb+`Nb&(6)RkkjAq=fj^k&!OfKw!^a4&r?3%5BPGP z2Pu2(+?7s&jIp8|z0t=rfxfR~Pw4F$C8KZm9oqE|-PiA&jdJuLBRbyklfl9H0JvL; znmQ?iGu;4hKB$)iBr2&Tn&N7od3e=IpX&aNvUTEd$a*N_VLjaTCVfWr$<)>_!+k@gN)( z=S;Xsx}cTlIt(l;T`5{WgRX-idq@V$HfCCzHzS9+f@>$pfM*$Nmkf{JzL7Dx>*}|k zY4-+j>s|Ch&!+v9ES_})GnTo_vQ_5-}*o^*55!{zT!7aiaA?s9QnkYQx{AT`m(LVw|Q z`dA93?-g<>)0f^lryH`+ibs8Xgk+x9ladtnb|%0*0kO)K?JJa$Y>&vgm!Y2v8RU6r zZA9sUnEs%1niPavD*9B^`k;2mUs^~=`c%aHE7JQA@&68g=qbZ?5S?A+fhRwbe_0;5 za(?Hgv77rmYX|D-1ft!0mePP!qV;kIzwfknzH1`{zR18fNgi-6MOxAk&Yb(@9VFUT zitnl%H9(u=2iP#=_LHPO_`_AVp;i7=D=*M1jn6c{3xZRjO9N*boDUsmb5o`WtNBk7?Fnu#AI;Q^V+D6PJ2tn))lbu3wkKB zmH3Z`q%4s52c%0nni2oIfvAm|&eQLDaJzV;{I!%x7sET!<=@2Njtgg3*<-z!q+(_% zOZQA@O~1|L3b9bn13cv?M=VepE)1l3ROi{}l>Q`RrC52y8Li9%`AlwP%#F-8C&EB@14rdw!xQhdG{$^fOVQBB4{(y=(+6rsfj zS@VsI0DiRcF=hy>xW+a$?7O)_1^}m_&HMJ@gBs&Z21lc34dQ;1)=%{%7ir7*&bptw z&nOq8i=$-;WjwUh$Uf`uZfd(mXC&=0im!$AXpd2N=k|=z{4aOuGTIrZ#gp!WbnVyb zB4<3VpUX7TXp~Bv9{_A?63RnPQD_a}yR`D~>{U^{Yd{+`7BQ(5ALe=BYCql`ML(Gc z*;CUFVUCvlk!&S%OvVh7f^f`&ab+J!{*+>Dj;dqYqznySMLCG7t{ys1CkqbW%FKQ$vztngzdU*SL7=PIZOGBq)z3dRMAE1EyW0HG4yo z^eA~L(I2Dt1{o$fibe=Pb$HgpkK|{`w?2r^3s*j}ZvTh4!B5E98+;L^G)qcTzvT%+ z$+iIH6^M4p35rd-1_j@T4H*>QbwT_L5QnRHCeQF*S$3&zY-G;gZoZ?` zNWRM`V>B9|l?;Cpz3xMPE7Dr0l7p!o=YEuSwjtFfU?LYJVi?Y$uGWR5vo;Qau?>6; z$pR@MXRAg5Uos{mdLurlJKVij7sj=^MaB-iKGmccs4d&ze?q#;Z*`Ife@n}O4r!LD zll&J5V?d04cZ16^e5!p6PzJUH4iSCskN{E!kvjYzyNaOV-S*(KZb;5b=+DM-!xX^fzd&V|9Z_@>M9 zq7|BowwpbM;#XoJYL1O_`ksS81I1Fb?U{00gubURZm>s z^pI1Oko=1J3TaMp=S=buaw4$-St*g`dY9Jsk#z%oJ4CoN3c8c?A!jOEP12+OA=;_1 z-7@b(qI%0Oaw5la<&pM{8Zl?Y{##-G-7V6r^QfH=h~D#m5wq;0Yt)bwhWtR;{N+aI zze`=_zDQO9wTROToG!WOH84(fr!0g2{y_QrlBAQPekAeeEuJNqx$O8)uk=C*TF8?L zas?8Ru;~X5m#tF08>#;(nzx_J+7)>I5ma~sIrI`=GF2MyRge>JP)3JwAGG{ro5{Hw z?KFMnQuXb4>E4J`nd!q0uJsX#eZs)Mr{LRgIn)X zottT35BZSk^K?g~(cOlE^h>Mv|93oNmIq>{8qv+sBu6M_T>W>rpoF8Gw0bK&8}dr) zLuGXPkUJB&;u)m9OtT3!G4SU~e;~DbOmCx(^7Aj>AX@~kI>89JEL&!1^#fn>D!oSe zm$A9M$$A@{?C%;Q_C`zrc#n+FMD(Ee-M&BcjF|N>^6*BDO!5?I_T=sljS~J5gKT#` zp`bFZENK+LScIgw>rH7KHSRO`D zSEgL{`2HEkS)elo2XdR2+&^^uhaF6Um&V+y}bRg|ga>(x#T6 zHvA^X$sxChqEhCd4euJO0tFsx)Ii(yg$s4E=P0T4Uesx=1Ng|SZgAx{1NQ$VB9PYK zDa~^JimdH4iRO|z?il5n_)gYRXqU)4HwrZOcZeY!YQUeIzfc3c1sX5Y=6TWkT(pIc zv)UMt^A@ub^)29^pEHf`9Y;4+v})eTiEm!_pb@YFw3a@@x}?|mRm0lekT2nV~5^+Of8Syx$CS*{Gl`Zf;CdSk|SZs4~l*6WtS%#O0q*3$&Ki+W;4 z{S3^n-@%SUW7Pv%1MOb_JOyu?#lOUg-8FnIR_CwhdwCK+%#UEL?ooam>vb>jXIQ8E zCr?3&B1ELH3cJWEvSF=mPLWIG7I{Qokx%3o1wDbgp1}wDjtZciQwVdp zeNjFo(9bS|Uog;89;m5;p9T4AgO*Vb%*+Wx{`vzuBk_x(99p4MY8DW*2)}HU!|cf6 zcDyHn9l|?K;#UgDdVrFbm@3bwVAgvD!c;{*hcAH6yrq04tHoFI)zJC3fp2FY%hF~o z_(>q{Q{=xoYlAZSgiRHVMH}`N@_d>t2jZTw6%uRgh_0%xD*KwsMdntU?aYyb@^F)R z&`}=rz+4~XU*^FFr8Eq(bp(FC$jLP32UJ7zDaF-CS4&q5I;R9uFH64&(K0_u-y5`& z@5l{``hmuBUUe?eHUQVz@$*B@bHFW{)_3Iutu1(-3z8OE|3Fj5A2 z@iSoMOau7;7#hO#Sh?B=@ifNI2rg~{dNjq)2imflA>YmMGXmo+LD^67Q=sFk6|P(3 z=SyXfn>eK?(9{FD?}=XlT9X@%lIa6#^~J9sRyFp+8)Z4=qH-z>Suq^6k)@TB(3gkG zEEh?%KycX%P;VxF7NBt!s687$0c~M(5Zhe*@OZg%*8e4OS9Pl44qOmF`r^pHST+s6nh`J*;eC82(;F4G5#mXK?U1%ML z)WzzYqM|556%)na^CPTdvZGEZ3I9?iS;QICg;~T|aTc1x&xvzL?FI28{NE72!2exn zL$-@wA-62zxk!P}RMeVLI&U3hvo25<1YOy|IxF+i*>us&sLQF#%}laRW!ZFh@g})rLOoa!Z|gBw0csSD?+BWQre26CaW$dXgY|k{}965CcgNZ;~J; z=rcM8%AAJ;34{c>hCE8y5lFHlh-8PEWJd_e4hzW(PVyoU^5S>+e}rEsNsTa)7r~Gd zDaetO0%0Tte4rtu4YW|U=j~Zev@oV(6|8K{`H)-)Be|d_S)eB=Ac*sI#PfRMc7?c| z6So_P+l|ES-o))D;&vZsPdSU2&x6kciO>Cs&qImN!-&rVz~}d&uS0Tp7;$(Yad;SU zco1=TFmbq*OIM9b$0Vd)@ zAL2lN;<`ZMw;-zLqlw>gQym*kh|fic&rOKWPAJbon9fO<&Ow;gQJv{Sb*7HmaKTh7 z`cO@%qnc2|u@9j(h-xq&s=@SxNPlY2MN!@2Lv@ReY85@zCq}}P7u6(sLX{8U$)C^@ zMCj3x%;spr%T=mTA_}rx%5NQ&bP&mJJ(af)$!|T$ZzGku7fEhCNp1}RJ|wyIB)LuK z0px@9mGavkJ%IvP!&y*3TQcDz5dDI}s6C2^B3KzKCAy9zx}GGu4|)ov;lGS1gQsPo zYdRRchH_Z1SstrN!_a%EfZCvpyFYItW`=)J5%7Pt?QO&-$W1bPqQW4dDK<_!u=(L-7e*8jHq=r-^8S zw=@+^5kLATaA_f0z-LR*3VvE+y=ky$Bii6v)wE zv#4S4^TcR&7e;0MV5R!OoA9c&Y4yNtZeUrqWA%huf1tJ?Tx8qThfwS9syAfY)!$Wn z$hNCLVb?&|^(E~3QC$&Da@vhr*$&J`c+F1oI5)}TY#!LnPT2LPR-eC1D$D*y1Yy^o zWU#kO1}C5`=kJolvM=HX1mA~?Y<(H1edSM*(wlG`PSVlaB^PDy#NQKm|hQC zwvK!V)BY|=DO*SWglq#L+mDd#O%lsn_D_L7iEJYw+nli(1^kr; zvUP-P8zCEOkb&$7LUs@#+f2v~BxGkHWJeIPLkZbfqYPw65VC^_*+GQtEI>B&u8BIp zcL?FzO!&4CzQYLLW+Cw%0DPl{7oPy-QPB6*7@;J}0}163gz`v2xfv+`6h2!4>rsUD zNWyxUOS;SUl{XN74|$X=D?LeN1Ic44i8}$4KESH%r{yI{nTI500g{w?NJeTskbKlC z$WO@2OYMPzguMJDFY}^z*aOm{r|1d!)JyaNpY;~K@$NpN52)E!^g}837yTh`28e+u zp+RC0_CXjd1|wxd#1Qc4P%#vKhKu1?9X>*gK%Pg6k%(uM7=@gV7NZgW7%>L^$BMCd zI!=s-{}>SimkDA5t|y9#z|bTy3D=*A&p^k|#pk%5EGDDHIYmrCdZt3RxsRA8rs0j# z#dOHjFT@vUE6)%!@Rpfk7W{uHzQpxxF&pWeBj&(mF0`R5;wv!^an8r+j$SMf3s8y+ z#X@K=Uj+Szxx`|z7*Zz|`u=l>C1MHW+)}X=l5d$osBx;#n)!;(DD}hwJrXJutLEY(ShF#YX5y-y}9cUT%hN^(e7LY{6T$if!;8 zFXC~%9eTX1Vu#oPmjsc3>qM~=@$3@2;IdonMtb&$J&=@p#a_gjB$5#SKCur{Gg%}< z%I+8Yp+WwDH~=0vC=MZp!{RXZr#K>xAkANkuaSnM;wWO1BU?V=IK~4a2}yZrJV4^9 zBekjvkkrgYHM<*I+8BV8nz>1;3l4@FC_FaVedLYc7 z5avq=^8&&Kpj-z6XTF3pBjL=KaOOie^A*FyFqG(UAk3E##yt>bB82IHuoyg**fJ2d zf(To_ge`AiYciguqsmCA@*z~|2~`1vDqo;#CU8FssPZLL8G)*~xc*9f1>TqkRQVFB z0tr>Ygeo&owHVZwc(M?lq6kk}2~Xj`6ZFdylCltzvJsM^2}w~v(mFhq7>XhcMG%H; zgrOXSq3ndAXkch7aJ&r|iY5$207D75P85ki+fHC8nlNN13`G%!LJ33BgrO+HP#9q- zCt)a>Fcb+49R$7)0ZGw>Br72)nvi58Bt;XFd9!QcJ@3dJ-a&^Aw*`;g$LH+we zf_UhHk09M%5v1EoYEhF12LjRKW!%}8V$j^Q@kzuOHVY1}nTKJMi%blgX!OZ9x%On$ zk9&!@iD84`)L(F3R4L+PH01Y3)62k$bTpds8=)|8VkyD(aZQReDpJ71C2Ex|CW-`S zd34G;K|OqbfVnHwyLTm+S1gjvBQkwRWMswP8@(Pn_1>v@#|B+*{6rIJI%Ws&xjJY6%r(JY!ZDH>M9V#JNf z?BBfWpq@>7cJEgpYn^_b3;lo9Tzfc_TiZ7W=VOfsg9$}3tY^ky=*Va%i5!Zpk}(F8 z!)VMnl`>N~6cwS^HdCf{RHA676iHjWNu_$DkZQ;7AVdcpeCu&awZGndeb?6?uj?Au zwbq(-c-H;9fA{acJr~3ZSfB&)1XFqlBO-!CC9UB5g|L~V6fQwQ<{3PUb-{i%sFB&S@ayI z8@(lOZ$*wok$&8rW7`ih7uRtOuMRl&mX%;oc+pgkLj-qpKU3w zPv|PmA^pq!(DttR7vge087!vWkDT^G`QQeBCzh!oXz_1Y9E8*4<3W?);JMB@O*L*Z znI++(N@zR${)60gesxtkm8eVsgawYQ$Y}wR^Agomth97*9dE z&y2nsrNdpP(H{tLu@FOkA{-Wj#j4O|{(I;x<3!%To~~Ktcf4;; zKCvVOk^4UckujK!f(S>@8%Gz(gB{8ux$_vI;q0(Lk~@nV$!4-5NOW5iIKT>6A{Gkx5G^;Cra4E$?@mR+*IGJ6p|hwb`;^>VMRTK4nOUZ)qAlt*Uu6*@8(FEI_4Pj_Bs zoYLdvxbv3uV@;E{!XmGhM!Q$!YJPj_(YjsQIU!CmnL6$FUIun@YnImJ`OfQnctNdz z8O>JRc$_?fngT&B5L^W2QZkTFBqgOW7`zdf1q{a90Fy91h{p@JF*D;ZBf?E1p+85! z2Q+1JLV*Ij5p4nnGmMA%7@(ppUAzgH1B^toLW4Rp}<6g(srF#$|Llp%ITARy)8Zi|p9UqJ~c#9$;= zTwZp?Aim?VqCri&W+{|6hlON?th)!FRihDOu7@%Zm)_`a2Vxu(ah{qyPBe z{@~dIsl+yMR-TW-{)dMyR0+3V^6l(6ZgjWq&@%tlI<3{`k6Fvyrs*A^?ljwx^Q=;O z#zK2rS?O{X(V)_y**^Z+fu?$FnQD_qomxTsns+e^)^g*L)bmW}2OHe4#m#>`$L5Sn zhQy&zxvgv8`M3{EKjo<$e(C+-@l27DdV8%}yl=g-aaaPr@7X}K;SI^lJ?5)@Dwb0E zsnGjs;fFlteM_n|GCNY;exkp*7wVvhh`+irAlNy{6TEGaX@G!Uu?#`MlNG^(|ErNi zXN0p5RWKFpmL|yC^SOSEut;`D2y5IPas(-lAVw6Ag=hmU^lS12)zOYGi5<}e+N1VU z8yiL)IAYv?$J~|*J=OfP+oDbCxZC~^t`K7MCf^E5@Mw?SJr)E#BXb&CSc zE1H$Kwn1guy!>rXJub?H)qc9{*j6DuWuM-rdkYM2=tMuyN9y~Y=xN-mJ+*|Mqq$C` zv*)qTV9%z$xTAiU-Gj^J+pp`bI+EE~oD^Byb5`-y-6sg)Xzegb$ zDadIf6atYc)&T0`_{I?wAca7n(Z~qdf;!p$Feaf<)G_$oQ?D9(B9a`FZJbplJchYL zbZRWw;T6^)GrPd&O2b}47v4?rYr)({|2y`-1Xc%Ue1}-aOc(kk`BKlX3H0 zH!Uri;hTkyK!~q`AEPlpwoNgUR8-WLp@kdHAQ>@d19QX_N@6$}N0>RW`ncw#bNr!NfKdz;3lsp%QK9gkoc}^) zPvz#9Tc16!a(Rzap{nab4rqv&>(w>wPGk zYsWsh%ci`tEKk{|_Nj?*r_o1unXI;Q4C%(ZL({vedtAeNr#pjK_8?MveGA>j4B^MHdgJ z04O3vdI=-OhPM7jMuamN)DibbV+nMBHK01a3)Bo_f(D2CQcFN0m?9-RdN@0%cA&g~ z+8Gs;P+sT(l2`{25lt{1c0lY*8G#IyK28wk)RDlYt%O&@tI7Z^DGZx`|jSeTswZqIbmU zF@gF956<20Tv4nwsMPkrRL~e-5aQ;N#$UPPtX}`kr?&hgGv>-T9S`r!pBq}t1=Z_( zUdNULp`<3HFzgtGZH!dgm-}efyn<9$2ZJ@#;IAp{zm!2xVzfjMfJ_i0q(uq>CWx`^ zOJamV7Dbs1L5|J{VFz%yVQdC61t_DP(gYcIMi|MF6Tw3C!3?xZPF2&^pW_FaD+cN@ zNQW?^=5WI~Tn3Njk1PQ5&@agoEbQ5VY#t+owA7w7PIzR}ayFC8iQokANbc}g6obnm zt%95SkLKBt6od#gN9L;%mWIKjgpLl3Z8d%b-1m;~-DIce#ZK`+<|_04Mz7s*fHxpp zx;@vQvf`p@qbTxUo$FR1txZ%D^yze5w!3OLw#H zr-z>=4wb|V`<*B)o_9_s)F3msYGD}o>8uLIPF4F%UceemopxUKBSl1rONEJAG8TgY zf_m`Z$$nUsZ&>|vy;3CD4`Z|JSjo}|gGl3`wuXgIpfOQLl*J(mlQ4q^#7QlALVD)CCF9AuyziIyiwK>zdNcmxLQ8=Ma>I2zN>On-6<`1;2P-%ur4 zlK}}6KD;1amGnw7L{$b!lx3y<#4T-IRru!|?_((+4SUwoLY1RU$jWNsQ_fS{R%QgX zK9}cru4Y>viYGr*%3aQs@y&3cG_{;`RcTA-4M-KfH6-qu-uGs`Y`m*2-CGBQn9Y!-Vm}{V3K3$0VOJoE zkiZ{OC;OY~oPw0hXdxO4RfOngD2c`k)6i7%6Aft$wA93iB%(Z0aHCPIC=_!V0=yx6 zOpM}@sd$y^Pkz%6oK?}W`j6MGf9`$J^sNO5-qktH2U}Ae=C-pmJbaqB)N;7THC0m` zy-XRqes5}h@=MFE&islU8K<(^y0$dy|0Lh=F~O!G#e3lA*5<2(RT&BiXXTZ`u3s(v z_0%R6B4L0Yn{4|0e3|86e=_K2T)X@iYl}{wXM!Hn$jerL$*pADKiD@caMYZpQD@`OBfXr z9CpN3vlGKD>o9Db_o%Q5-aexqZNjkM12C*hT5y=7%gl`*-Ji^09#lK;X{ixIukezE%>kM-+U4tCXSE|f=`#Tg_S%M9PdC=3h1m~W8ZgfGX~ z7>`xLngsY5;}f5bx!~QPm}C=#8Np(im1C@$5KJ+~B*x3v+YcLwDQGieTcE>V(DW9j z9Dl>A0R0u186bAJpuPPtrjV%t-+U~r4Q63nY+4&kU|q1-HrT8~9X93xy=>&=U^ZA? z8_dOKVb|JVbF3>qx(z0=&UjKAEWmo;bHP8jnK`svg;%%1IA+Tl*9NmN0V}!Rf@3O44o<^LlKx7qtT{mv`U>S)x6_UoSYcYX^4+Tt5P^SI61g_3`tQYsWiGchh%lMv%??GLTv@+i@9O$@aYfV9-y5AHWu2~f;=T~Dquisp;bm=JeCP;&%7juzH#P8PfG0wM#>AZ#s7&lJeo6s~5@If)U77;?%-Ec+8DfQrIvvF3U})13N|=8RP}>yI4ukVPhPaK@va$A0sgfSPuv= zE6f^Z2_Z&dwwMUB!#ZL1SZ7R(Nnn1FVlqq)9_xyA!@6TVu%1{itT)yN>x=cnzJu{K z05o@mxO0ZMb2W^*fiQwRAQlHhybi^NVZ*TzF!vR}c=CZ!<%juWqp$!N|D&-nSP;bO zI4l^(<9O(^Ff1HmAOf3+O~NK)k=PV$D$I4$u^C|4UaSVI#SUP{u~XOu>?(F0X0m$h zCUyh6h26&PVRx{**nR9F)_^_09$}BMXV??$DXcYqz+Pc5u}0{jt>EWq7&S~b`5xPj z?ZVb$h1eXt5G%n-@tN2rJP*%@{#}R9!sp_%@dbD>wisK+a>ABltFU}53R{cM!Bltw zJ`YR8augk6RRp<(Vdt@n*a~bWRs{3+ENnJ57n_I8#};4QVsb(|GR+v4J&6Bk#Y!zaKOwmozOW~v#tngK&DRLDv z6^j&06??i;UG2Jd>)NZULpN48PB*J=!fv8&;%>5T-*pS<7S&DFv%Znn*tt>hYHpKx zQ|G3xzy12#=imPP4K=$pdp3JDdp8F)hc{1ej%rS9PHwJgu5CWte7yNo^M&Te&Ci?P zBTw4w>sPQ&VTi0K=%;e%txB+}9IwIuV%f7?SeL=7$6(c5uxcr>g4jmvBKCk)wZvKC z0#R> zbGucsU=`MAXRr!uvTjoR_RDX-8?5Tv?9n_Jtnz6d*F2$lMzgXxsd-=X{^kSCN19JG zpKHDbR=q?{H1_rD*H@Sqe7byn#oG4u42J!4pXtW-KUkao^AbM0;Ir_b1@K+<&z^r4 z!IOa({4@WbiT_OcC+?qk_^2@K?~m=A05pa*j&5{mls6uRe@7dSG{VZZG4tiym)VU` zFK@prf`1tp_R0yvUPir~@Y3z2^rhXi!;A#QqOM~UeW0(qFqp8r(4Kkn@A5D6?_wAU z*@yoYKG*n{;QJ_322Te_JGTIUJoK->%aE6HSb3}h)_m4-)=I#b&j$EZGWCq#@GOT< z#lJY2Ql{PpRwWTZOd_TdQU6&EsW9|EX@oCO;q&c}7)*@rfcX=!CxJQv1hd~@ph)<{ z8b9zI4WBq7kw}GS34A~Y$ilG@b#d4n$P0^Me6J$G8npMlI(jg`U(XU6#j z>=IT6dFVRivTKmX>LHUYhg^0KvKf=h9zr%_a@h{ZX3rp>J%L>I6x#xs=oRENCZoN^ zDzGNJ1iy|i!t3$H_zk=izlATu@8HYvyZBQ4HogMChy93sz`w^I!dSYGuf`wXYw$<- zD!c(-hd;sB;*aqS_%nPx{uJMYzrfyMA0dyt!nfcr@iP1e7=4ZSX2?gsV=Z_E{u{*h+jS{u90j|A_CxKVZLNZ?T_Y-2R5|#ec!~;lDEZ z5wFF6#}DG4@dNlD_#ylYegtpE595DgXR#OfF}ww@gL&;e_8Wc%|B9c)Tk+%gU-)VK zAN&MPL7Fhh4$mun`hW);-ogtoy95tOnRbJ|J+`L)h^>A_&M% zW~?U!oAs37u$~cI)^mafdDxuw1Hos#BuG{xVZnMuSh8Ld0#*}Y#dm5O{-V?U0p9m4_17XMdndrp&NZ7M}Av&{uCB&@X2np*G(S`LpA!YqR$XK5VIqM6d zVEsvSWi=DsScvG((i1)KODs04h3Lupi|ECoiQa};iJ6fy4Rcc#%!28dj&%#8VUJfu z_~Uc%jd(S_8~cJG{5k#}{~4!X1(b@d!75oomIcd>C17>JRd_5OhsWaycsL%0PrxJa ziMX0&js1n2;|jbh-UIK3cgJP89FM`H@lbp`o`LJ|WL%3U;fZ)IF`O8|;o(9;}DV!Fff0`TEQ`$!7UEB2bdC!M}h;>VBxR;hTIMa{Yx+)-{Q^CS$3@65Q2da zbZS;UYZ+@Z>k#W4>n7_7>m773PFNBWqAxL!@FT*AXhH)M;BuJy_7f+GtHeX1iTFgc zn(@u-&3eML=WUqyQp}3XR+^QY?KL}YcFpXO*^g#_uyM9ETgG-^4`YvIPhlsqXR=qa zE7-N{v+TR@Dxc#|9 zxq;k?+&FF)cMf+2cN=#Pw~l*(d!2iq`;_~d`wRCAm*$!A%y|NyHLo*I&g;b+z;ojb z=8fcy;Z5L8;VF6XymVd;uZTB~x16_$SH-L4o#dV8-QeBlJ>@m>e&!+G-{yq5l{sbJ z#k`w&A9H8(Vdg&OA?6d!qs&vJ!jx#cd)8q0&0b(W_rFIrx;yl#2Nvcd9+1tIj1f!}#0a#40zs)@tDss?D>x#! zAb22nC-`E;w^CR+TMf4Iu?n)9U^U$;-YU&1*J`%aVyo3wWmZ*IHCA<2=d9|j?pr;# z`qAoFD`bsXn_CO5CDuKx2UriZ9$_6|J>ELfI>tKLI@5Zl^#beV*6Xb+tan=lV>x>W{J)BHk)mB z*zC7CW^>-=x=n-43!Aq#zuD-8xR5WTgk6L^g$}|&!jZy2VW@D5Fjkl%%n}v}7YbJk zw+r_PPYTZoFAJ{=?+6=&&xK9G55nJtdf``!Ls?R`l!WR=^`)GsLDX={j|!r~s7Ojl zB~ThFiz=k%Qj4jT)OxC%+ClB34pS$o3sgOImwHUSq~21$P+ut8mSt;hYi--fR%YAN zw!f{b?OhID3MsyRn$l1C>kglCh`@9iK0cBqPe1VqCKLEqQ{~SqQC9< zc2YYhyHR$Lc3QgC~-L-%d`Q26Y4OsIpY4?U;%=1Z>Ar)g2m2 zQ)y%1D6qZIpi!J!2g)(}7$HWRHprlh5jJSj1~PgWK}L%<$e@D}Hfmsm4ecAjZ~p0k z>y*(ZH!v!6Kp8zcq6TF;5DXf1#2K|Z;EZk^QGX9+F^qqOqkILCd}Xg6JlsOww(_SLsOLPSetK5bq$U&AqlxK zY*O2+rYW^BtW}F~;a`h{5W1)M$1)YOuQ1%85xuZMp#FJQDhq>19A}5gF)Dl&|alYRVYi(WacYPs!4vdRvDu*F&dC|CI(AV zwKv>`wikah7Q`BmZ$->7k7fMDT>daBC95(rROy+@WSE3uuGAV}VAE=H3}C88XL!N@ zQp06WZn7p1rfroPB*bf#$sk^*Rwl=)u82Xky|w(Gz3U5I-5}jEN8#S*pq3N+uf!hP9uo zOQeA>vfZ&>eg=Zl(6rLnnzCa^c*htj#2B=V`6e}{T|}&*NM(?qGQ#a;aJk6@naU_J z-cTq0n~?Yp*2lLq#eWNlgl~1#24+}OG6K~`fog*<62DbS>L4)Lpm?%DqvVcsXehC4$GStbM)JP!v>6GEHjZp?dlVg}n9HdN% zj#ZA$9G5vs9h{gFAhlQVne- zF_yqQ2$mT1^Y%&2%u&O7f-y&%pn>%?Bz|RPrjb1@K^>Ez23W&P0R|2q7ei}?cH0^; z!fl2ytr!RlU{bZM0Rz2FbVvAGHIqdhng6GnMjDfg2l*+PSuR}nF|Y7*#b66osM#_np8>}rziYLe_~lI&`d>}rzi zW|Hh?lI&)Z>}HbeW|Hh?lI&)Z>}HbeW|Hh?lI&t)cQ;9PH%WGHFEUAXH%WFkNp?3$ zb~j0OH%T67(s`gs^1wF9&g~iwGzlDN5;)K#aG*(`rwJHnl03*Hd5}rfK_*oPnN%HQ zl03*Hd5}r+Ad|pBCV?I%fgUDRJxr24Op-lJl08h4Jxr24Op-lJl08h4Jx!85O_DuL zl08k5Jx!85O_DuLl08k52eq@eNro6VMwGKtTamMq$-Pc(lAWE}Bs)8`Np^N>lkDu& zCfV7kO=o8(lVoR;WRr#-ZUfsUk6f4@)4okc4lxG8x55syNUkDQb#)pUT;bnaI7$1IyhqsZ>+sNl_ zjeOolK5rwRkCD&E$me6^^D*-I82NmRd_G1#A0wZykgA(1FckO%bR{xr3JJ8!L`;Yqn zCB6gCzuNe3D;Y^f>VFCOm$ghi)85M=7M3e*%WnpTScVgDX3)Tci32AmFD4G)!3-KF z7eh?CxHvO$01wZ$_db0zY4G|eoG^EMFV*mRs{8-1Z>Pe0qW`-WME_53gm!qj6<&ii zyxrRN;wik-iv7miYr4U$4xEnmf`GL#f^0|Gv4&2S$Jv=dQ zHg5y(DBR>V@;;ac!F}Bs^Bd+3=AZc#-BE=U(_5bP5i7Q7eyX~nYY zXEoI-)oQKPE~_I}@2xvoJ6aF1_O>1a_f4~{7g?8D?||E;{nihxX}DYJXEV@dsExNx z0NgD_+T_^GwOMSl%BI}rw9PY{W*b_F3AykBjH7UfaFlSYFkF}@oGUC79ul4r)(daJ z&Cy5UUldO9DJ!ZMOS?1dPRM)<=To3_dtVeN7;tjPPC1) z&9p7BU1Gb!cBAbU+a0zwwnuGG+g`N2X8YLoo$c>%=R=5iB0EtJkqg}Rj1f&1#fwr! z*`fl`JW+{gt*BB|D>^N@Cb}bfBzi7-FZxB)V#l_#vg-slK;7*6*bT6Au^VO=U>9aL z-7eZL-Yyya-r^Tgo9tXjE$` zds%Vm-1*}93+FDFEz6#sqRz-k&rB`MoV(S_e(SO$8;;aoIdi139t}qJ=ofnj&Uf_w zqJ&v-vr{`S;>@Wosx98#6&GpAf$3=S6bzVaq^KYgaC<`aBfLP%nfxq8OQ8 z>e||!OZOcU*xNbaI{Hqg@6ILl(I`v7Cxf=7mK_w=RPQ`fw=chFvux{i_QtfR^^ub9 zL1TuEKQ!faviwFyrA{f1Nl6+rV_Mm!bQvk?L37ymIM?s6OF7s5*$tfTh{GmD)tf7J z?8x4#(PZh;G@EtRax~6vXB#b*p}pe^Hl5jUYV9RnDQ9iy`YD?xJfQRKpK*|rK8Nkb z@uwH$ht8ZdC$jTGPVvdY)47*MqWSh-oS}3{enkGnVun8Z)XYCvAQ*< z#fRc{O`DXG9G@%Oo6X*|W>ZoZ(3U+7Zh(T zn^P`1wsmiPiF_I-Y2oa-1(N*y)vNR6Wc0k-X#Gu;aZC8sXz8;Cr$=W4L^W=h5olc|Knz3VN`L-Q9 zGAq)+CCUWX=`{H?&-*rlOs8KcmlVD!KCYhMQ||fzMZuS|3>M-bjD8f6GB( zEd$vu92fdMo7$8$C}(7$7jF?~*1g=e1N0f4Q?O;E;b@BW|@wwQ`113+;(WS}Cr?b~>-dVO!a%NkSYEslx zkCF1A5Vjy$x;uME_Bz?Q0K! zCGQT{CZj%vm1nQ75^vqG?bx9mg>%-)HlED=Ub7}{N#_gGL%6}S;$tU?!w;n0%#a<= zEzeI8r=(>mWmH3a;@S-v^1Mmx!iw6WT1g03fIeOk(XwHv6Y91^j(U~cM-tQ%{_B_o zZP@kpX;Ms9L7xQmYPwzJV!2ApE_>SFbSOn$*4Cytwi3f#`#j1Ea>LT^xq|KA6KkD zASaR8qUZA)WlNXr^{yL!d}L>oNPl2AwG8y6_i@Pg`nw{RkpU0sP2AAcQI+YkjPgB& zha`KeR;=74UvQJXU}oW>3`u0(-Yasn9tm&JLd4^eBI-=>*y0GU@sb&tyN`an_d`>~ zrUeVXmmg>qi*(TuMc{xwH2xV4K{JpP*`Yzm@pU)4r<{6OO!GoVOt5(HGj42y+MOLUlPSR8BP|q8B{!QW8m-nxfHd0>> zREQ{j=7Cei2PDflF}}wa>?~T6-Z>*{PG)ZQ^6&Fy1ySr-o2uq+lUz8l^>S_E_PFKp z9Y@*JmmfABJ9kffKkD$H-LfKnw^Gkl&ay=%Nq1uJO@7*$PDVem`;(%}+#RKrtJbY7 zK5jp+AZu>2WODT0`tvo1FYMerXWlybx|8fx`MQ-_$;D|Q++ju2#*Gk1uS+P`$zV_x z9GuS!<_h%3ML(hL>_ARPfA%6y$OrZ)&d+prHu(rL^xp%?vb7sFZIzU5n3)wfV`k9| z7{L|C&TP0KJ{q@c>SRMYBb^pc=98!R=TUdz0lxM&b#lCvdOA@`o%G{V&+h^}mrv@Y zcj=l^&eqB;+qP7pWVF|Q$$54w+ZSzE#K}z0)@7yB8oJhA;NM+Jo|4`~-Cy!|fF$a4 z0-rkRKTC=(aMvthQ>W)jNzdX)DFnnP-&qH0s+R3ownI+6XC6Dm@5UV%D9a8n<6J5! zPo5yoSdg(WLq>gCkg-6UCLXgR>1dH`5qCzhMm$>{w7G2fnHWRaN3$-ygXr6NsuxS8duTS-*bvtj!SN4I=9Cy}kP&TfX$V z1#v{U2YwfHRCzH&wvbD`@k*RD(OcZ_wLcOfi(l>_Om;8g?1(BE_1F{TiO!u#3JQyg zpO7yfxn=s^bK*;<_Fs`vZ|1ko5e=Ji{KomZV>h?T-)5Xv28p4bpG=T)LwY;#u6{_i zu;Dc-d`+Fy_kJiEyJ}y?5y|=$OO}2wr=G98&Q2&TE^X`9~%9j~}buA{U@)y_e|oq3)hE9yD~2 z`?zO+zN`EBvz#P$+UbiMS}m7y^gR7x_Sx1c-sr(CN$ToQK2=?Q4^pyV@g4o)d-##JhY*fre;)af z&{sByZe6(fE0T$kKa9DqbTEuJ3H%GE?QZnG6)syq_w+|A&vS>I@ru0!NSFP5@+9#QsSdO#R%K|zk_jO%^1UWr_`}ytYD?>Ii{`vH*`ryS|;-}*u(YAhpTCG}E zF^0Wm$Ek`llIMG-O&mTrag01N@Fa(N-}oZdX^DKok^~=`Eg3hyawE9r6{_QGDBZAp zo$ToPgGbLxZtV>lE~k&YLT9)emu_6PR(52=f&Hf>_x6T4$myzAsFsU{_CGvkT2fJF zsw}%8C#xV0ru>UplMe<;hD?u|mL^}wA?f#Y{GAp~_U{N6HXyuj6ZJlxj-SYfIFotI>DJ;of6gGcajyjPStx6l`CGL0L@BOn&*B+Cr z^*P<7B+U__{FTTRvbj!-1`K#j^JzhUN7|CMc;)ly_W8Ygx5!FM(rA9KLG*~Zosln! z5{(W!`tGOebyx3R4sptumpQvoo{%#oWwJzo*S>uG=~*(Lr1x&)KCZg){z&c2f^u2q zEq0kUV*PXp-DRW)Z7WY76>z)N9fG#cfKN2!mMdmQ%2G5*8JWqm3u%--56vY&{mn^jpi=cokr{o^^ZI+A}VrCJ_wdf-}*lAWlpJxbxMxzDB#awgIT z5o^`cq64v=H|MO?riup*ojy<%y<#N<$hBp+c0Lf3?&Vqfj}L?>s%gSKsxeiX@prw5 zy7MQWYJ_zYb?2=VMcFm!KceUdtqZ)6l0*Jkd{2M+9$CWq{z~2HXKU7%Zdkmggx8Ng zA&St{og^JMYERonL(}_8bzJke(o`2xV{EcXHbq$+csNqX&D9qQC1S zpQ2_@;X+5g`T5hwLO$fM2D=O?weANlb+vTP+$FOlAraA|Gvy07RP}zCl%Q-Al->A` zvOS;pb`5l0Dfi3?HY`u$dhQ)W#PuJm|rpW70WKhZjlccBaTCs{(3XBDh*tI zK>0$_c<|7z8WbdmddKUvh?(v+%#=jb|sLu*Bx1XQhXp` z_w>lr6m_0#H?uFJzN_pS4--FdTe_S{jhGq}t(th+}b_^QNCA&+h zf?<5p4*9*k&WrcX**M(Zs2pt%lo&%U)I4t zO2d<{zbKWzsJ?MdMnW!GwnlbxL*1cEk{_x^50lepxnq`ktWA;q02ABdmlwq73KtFT zelS2bBy9S$3@~+TP1TK!=e_3J&yCCv%8%kfy5=D+pB8uRPYrVD71pum7v(R=m852E-c?(BWW#1qy=GfgjeLKJZhL|xL7NsYk1wfA+ba>&&%KW{ zchSm*AuN;X7m!1AC$0kmxiJ()*OyiMEId&ur^e18i^w#Z+M0?#75hF@fY$jQMly)>&n z-oC%Na=$G93Og?~I6Fe(8@%h{r5oE`%dggt=aAp$s@En;CMa_>8o4q$KR8&NXGmPH z_3kLD)x8NG6Ug1tSEzd}tSCveaq*`iS^C?5K+Lbz<$Zrn$}BX_Ns)kml23k%n!C<& zvK%zsng+XiP1-v?8f#a*rJ|}j%dq#?q%nJck`CS_#m~M(;zok>mA-Bn$R#;TW0piu z7L&vyJ3ZMzAJYHg#vu{w!t)o`PlSwKD_fSgI6p_6R+2M6Q#Pg`B4nI|Jb?r!BhR7L zXAyZ!c;wtDOwJd2X9br$_Z7JKgM|?8o#9$e;vh7wxJ+i5fxJ@qn zz#h(7I(~q8YEbb@3R1qG3HK)d!p)VT)RK6Ro^O;s^KyY$BsX^{?0oCobn)mmqi4 z6OpJ$PG(Br&9cxXa>0H5LS!R6|8_UxfBjlkj6H>ke->%i*diOrq3+P#Mr;Z|?5l9_ zBM`yySr8lp!I4=IEk;3XKaSu8ayx}r+(Nx>6PHN(x8gfdS^AmTIeW8gC}&OL(#S|L{bv(8$|Z3)L|OipFl>_CxXdZaRSCJjqN-+p z#`c5+ZF*chGUG3Z5M8YZ97@uDStyuH3d>Wcj^{1pEW5Mh#A7jvf(725E!%eO$*M?B z%G4z$muKvflaWJ|-fF)^OYB$tSo#K*iu<`_A|EGjD&P+?& zoVi_2K07Nqzx3eq*OE6?ZjlS+f<+6nWoS8PipOySf`6TtVwEbgKRr zcX(*@ziZZ~xB(XLWbTTr9A@sdlag;=p#Vh0G)2|OJr=>ZQ7&#ko_AN= zM@bDq^&||+>r(ghvExb8=}J!QT$y0!0T>K^?7JLtjV!2;y{TZmRx6H%QGv{u)Z_Jq z?KD6{()(JbAalhp!o;6Y04&zFN>NER-td}4qE%?{^3yW)>dAh4*^@&qc)}jOT`EY;(WPi|Dz}q&q>o-Rp?B>jI+INbEA>}lsd87D zrT=<&PWFXt5?Ko`Ab#(!SZFZ@E-Ai+hS$%_LPKwmC!(`aw{t>+)5ym=ZoEHOQ&hNB zCioFAZz67x_`wSVGKa*_|2UbIl`f+^(l=*T!J%ZtGbwrEZ%m}8;AAU|L+U4?x%lO; zm_Iboxs+3qvnWd^7U->7+?dh_QrK667E&RZRNN4qMIJ|v$H?>H$eJwBr^9Bwur(ca zVQcPh|Gf25*gSiZOHZIzuw&6w2(KN-jx<-ibed&PCO|ksI(toC%DyBdnY)B0__>^t z7{!2N;n&-9u?_Is!AN{2OU@d>3Wnd^<0D|m|?s)L7Zq# z8mEABh%4rH;r8M>a=o}yxvAVu+`Zge+$LTqZyIkVZz1n0TtEC`j>C_Lc;-TL2lK(^ zzUKbs`_1djpP0Wh{|kN+G@2j8kKil$N&I4d3I7rQXL1x-OCE#^iA+nmPF6##LapXmZMQmUZDt)|9c7(rT?khVyRDB}-?V;W{non0 z#@S|sjh9WZO$_{e)yBfl3OE-A3eYHa_HsM>tgTd-tT*V=wscddmq<6etp9G zB=pJYv!KuFzP-#ox?K=^=&0m=a}1F{FqA8>X+{eV9la0d$qI|qeBKLbS{qr{hV-D^9jfeVp8# zQk=4#%A7kp_i%P__Hg!g4sxFC9P6xcp66WZyv4cJ`IPfz=iAP&oPT!y;@s+D<`V0Y z>XPR&$7P92xywP9D=sfxkgK_?*ww*xkn2d-K-bBxiLSY>3tZQ_*1P`gHs7t@-NSwH zK-R#Nfy)Qp7{nelVvyIM)gHKqoku^9C7y(*wWrkcJ5MjqP|p}oo#%YdHJ)z=n+@(h z*lTdq;AMj=2Ol1MVetJS=0kc7@g6dMNYs!yLskvhJ+$x8z@h4)B|~=&Ju&q9&}T#c z9%enP`!Kg*;lm~l%Nh3luwBFU3_COI{;(g1j~-q)eBzdg6A9N<@!`Lok2ahcp+c0k6xSVl61=|Mi2w{aR4B0bYK7Q!k&2}Y+2a*@c!Y$!ncQioDeo4Wx|aJJi;L&JR&V(UBs@4a}n<*@+YQG zd^E{wlItYDNh>Cum`qIWJ2`#w_mfXdz8cvzvU_Cz$l;OOBKJ(`Jf&#LrYV=F+?YyE zwVc{{s%+}OsUB0uOr1P6W9rkX&!>r|jh~h{ZRfP+>7mmXO@BRO(u~V9UPSpsO^iAi zbuH>{)VnBJsZlmXyGDCO$40M--W}65W>rje%(Ymz*x|AJRFtZp3V!;bIud6WHzdw4 zE-EfME+wucZgo6A-Xh*RzA%1m{PhHRLT17VHKoo{e@NserX`jpK2Q8R$tJ0Pl0#Be za`)ua12m!V z*5Ve;Wz93qr!?!du4zNk#;0vet4q6?_G7wLde3zC^q};(^mXZ{(yygI(3)w7YLm4K zv}M`@+AG?Z8AOI6!y_XkBPC-=#<`3yI*HC#H(yt)`!mxaGd}Zh=9et9tX^4bvQB3` z&1%jbknNYP%3hGYCi_VC)9gQU$eiIhVL4NBVsgrIp5~h8_Ro#XRput-mghdp@@M%MaE*@jvC1$77YMG>O)dL8>a&iYmz zn`+!kD@8RGRr_jm+vC;R^mrta(j~}T`ti8jN+;>Z_-K>#ts2O7`r=%fyXoOuTrLl zz;DBCeZei^gIAa8!>-+UO?^Ro-9?|de{4Gc;Hmh{#4|k(%iL<>wx1CntUmVm`k~As zI6S(^raq=_iryGp%KJDLCeebBAP=!y{j}d>WDimfsKdpfQ=)ytCT`vqFUtskTZDbu zE4i0Sc)eg}p*k$3YKrGcDNQlrNn3@m;)mN0{iwD42}$)oEI};3U~BPBbyf@eig4G< zInU6b$J8MzS^ukD%#noJ_}WvKt6!G=$s59%IWTK<^3udiTun7gpHALI+_LKkx+f8QQYt0)G7gfhM+$UMFqCQLhG~iMCwN zr-!ykv$tlS%`VRt?nH>1gto%1`#4$wcOO*sSR@~p@DnXy!%nC7X7(s9>a!W({$8{g%!Z*%GIvH_+NJ|G)7@P-hXbp=P8VSm3_UoE1G=&WFr zMbEm9W}&PrbQUUtCAh_RS@-f4=g5U`-Sp5JOwjD+|Z zL=uQ77S&7Xxh-DVcnSKAxEUitds@`6?xT1At!4{i`F^m~yYXUiwh$FJQu|Ty1*sn_ z$=5dENZ&;0qjIEv#rM$an<)045WRjA_?CKqc!m_1kl!72zY*W?2C07_^gU)9>eb#x zgC5|h6G`9(c<{mWQdh#7{@rZN;-*1#bTN{+qt}*%` zf}PMl=Fp0{|R>^t0635>u}uAX@S#t;STP}eJ{ z%N6{fejTAdi+&VcXW;n&9T&C6qSu-`1+-r=ve7TRFN94g+4n0pjyaEWE5?3=E#qUPLE)m3%7v#l)*U_5`NW0VQ@6#B zCf=jD5n=fmYT33R_U6iiYilI+CA-y=#M8C0(QqLJ7ABRWE8o6f?xOwsbH}57k*36bW!N{-Wvlp@s@Fs*@0(>Kwe@rg(guq zdJH|9wudB|OsBxbHXpgoldW4nfBt&;le9N!Z!>uGVdN^Jy9|XlV7j+mj>7@41a-d) zOcL5*7%ik_a>4Y|jOA$F0KQ-sUwEMjrM#gY58_jG+rYZVPJAYh!_hSkN7qEERIo~l zKWst|nuwlKfp+na{<%`&GW|I!4K>)Id9Xoq;LsfU6`R_h;;I>#GYl>wa-V8nq`vKj z8tn&gP#Ppr!6vEUO@>LPHyINCuWvG}`+t9vLEy<(-jSlLCZZQ#&?v=s>Wf36Th7pC z=UaTw<1b+2UPhZe;?wh)Tv3YN6X-*Xh^{mw3slJ@i}uP$e4E(Z;{A}nPXC|*QpXj2 z8WpAAgT{;K7`>7`mP5z1Dq%BDm7^hgdq{g|NUJ?t;6dBK#H?RPj5M39UwDd1Wi8&> z_&(H^fZ;G5HlbCY%b87R+O#Md(+%PYJf*AP{#NgdPIZL?0-kgK7);f*>he+MqSb5cfw7*DZtZ;V&TI zhuOgyr1>q{d^`8S=9>>I%jVBpCtG`)y)rLtWwIoC#>}Kdd30>S*im9#+m*{4KGRC& zYwDvu4}BI<&v){vkKOr#15!``Z}`k7X7L4iQs(;Vn(_LoR!V(J;|rA1kJ6=l0kYuZ z4Nb%gsQ@j5fE{wb7@YMArMyDPuc+q@c2RJ@{z1<*x?a-=O1#d_f35 z`-b$co^=;^jHZ6n_ogF7P5NUT>iMZ9hf5F1JUGX zi`Y-j)t=ZchfWum&0Ltbphz|@J2D|u(r?HkhP;%|k0c18`9?S_Z$xDrw#Ko0un*^^9><&m;rszS#Rsix8-fBYZYcO;CP$>GuJz08qyzLL>U1f0Z}qmCHAhz0EUH~t%R^o2In*b* z2WQ^ydApB@@9jSK{=r$6z9c(C zJaTGafLb=0E7;B~36RgJ`=`(am>yI=5U9=$`5>oLw9|d&+m4Gyp$pK3@U~i1o_c2T zEDgLMSG2RJDt~Wx6wPGOq4WhdZ8sS?`p}N>P5W>JeuHkK=6V!%N4N%N_6?2Te*(P~ zz2oTU$?Tp*y6~}*tlXum^5pqJ?Ae=k%-sW5`iGj3Xrp`^QnHaP81|mF;H)^qez0oi zjoXqfn-M$qbs?r$|0;8oLiiFlOwf7V}Gq*}}{B5}u&ZPp36d zH>d;f9?@sf&h?eME8uGEbpF8t-VGhRDke^zsnO=jbQ@weOe*6ItxnsyPmB(svm&Z~ zvwF(W%6x`8=v2LY+NbC3e3T_eX;4eNwe{syJdw>X?woZJRP=8ROY$ zwU-L7O5T60`*J92Pu_YtRex|-W$hX9kG{2zJ7ps)CvQF@uB)rQeC}X={&tzb4=h7_ z>hT-*(5!m|TCLwDnxV|sYUKWpW=wnN%g)l|Mokn)ZkoO&UFPF^WX7!rY;D!CflAkpJPqx^dW#e_`? zIQ;QRU44UG&?<-R&=W|BxlFd-i%uJ|JrYVaZD}6O`5v&eX)|an6Oumdaa(VOSL+D^ z73c$|@zH4%G!59F8^~xz8@Y{8fuacHjFw-N8ZWp9--8S8h*tO4`kXkaTIzvxS75FS zB6gzvqF{Z{6|TTT-|H(jl38-yF2*3_)UeoB!P`o!=y=+DCEJIKyjRU>oyvZ}nWLYI zyyvj*b7}9nt57`5U|+Gd45NYjVjF}eXA8e#4aL~QuV3qmvD>hS`-I{^;0k&g?X?O7 zQty%1N;VzEZ9_kykt^rZO7?TkT%<%^bD;%@Hm^BsIMi=LKLNTDO@lqC1)2)W+oQ0U z{{u}emHMLEEcE#*j`Hg7T_e!3NKs4wdw=)8))K{Cp^aS{A)(VkX@2)oIc-~tu(3}i zE9sjY0eud96o=QKI0D{Ha28!YcI@({smI5UpE5OMi9F=^bao<9@3dy3)|Y6-*C9&lU60DLSZ_FVMR)+ZM=^Fv-HoIFZ@E3@K(7?=|~j zcb$-t9@ln#iC)|N>t3^CLA_Le_ptOLbNfWqG*S*2>{tT~J64L>v92iA2dw3XCmVOH z)bc33+1VfYrki58URVgXE?WbKx@*UVFttjVeJxyEtIkXH1xmjDIO>jXMM1>YmcX}0 z>=PPGpz$q%Wk$3TEh7-w64(z6x_6mhh1gPR66Ntwe|;REn&i)?)`jyak8r6#|HDPR z7G)B(%K<)*ET!Ag5-MtY9G@yb&ZnY|0spN(@Hf8^NRiLLzvKUlv-b{&BFp-QMW(x% z+Ff)g+tF^T+Z-`q4r9W=m@zA$B0&_DOp~<@MA|fCnDkvZzVn#vQIL2|D zIn{I9-S<>ChTUhLec$i zq&6&Dfc2W9UO#`%)2yFA=i&N!!srDl1L=|{ed)FuiY_T(=*Clcf**jm3Rf9SDZN># zmvRYhy4%u9+0^2bMo9P-s6yzceyPF5z4v)@uoV% z4b0rM9&~B5rg%b?K$HMPukh+dM5B3dVlsIun6?sc;vLs`c+AscOPB= zL5TF_%9b&bfX%||SxYxBw%W2`vw6k!>g@V@sjdPqa$R824t|}qz0wJMLMVD$1V!7! z4-}nJff}2ej3>j%gGD$_FHs)!bb|mlt-A_sn9&zN(0Y}3L$Giq4~iy{j{+lOys0){ z;gJ%7?k@RtG-fTiu2<9vHIL~s1o<5jl75JLm?EX!f687~zD=@y6^}04%0Qm{`Vutv z)`JwYKY`+h5Zp;uDI38}7#bB4pD224fylh^^Ojo8v5^GwZ|z-pW`>yb9X1l#_{P2& z4SjCkDY#c44dee*)UvZfT-_LxRxG9WdDZiLY$!LD53W~D*E_Q0EbDl5AzSwhc=NjP>Ak94i+b^0q! zJ$G44wpltXBYcr+lR!6-iiPKOTCBW5`!qWQ52Q`Rt^rO8bd8w;cJy^HD6=WhgYPc_ zubjSn0?&}GUBvAoxOJ5Y;62F@${>R`n{P%$zHYuQhn@Nd@egPFrTC_rLH~X;`EDrW zUf|PZ(J+}8k`a=bAqwLkaXz{`LRLw}_q)WegfT}mj^;+DBcdk6F4!?d7ELDi)BTx( zg~2sjWl$w+y98!egWWPv9mK!EuD(T|mcw#f!Soq9D_S9-J>=tpsH^0Jkam{C-xyV| zPm_6Eo?9`(uSogZ%~ud%bTdpw3q`A}E63J|46Gnh6M`=}c9zaxD@_^;rH zn1raL*i@jH*aFagTK5#RwIJ~KKAlj-{@BF8F)~`CLV_5wr3u&OYlLg5ZxmoCBp;gK zgWzX2p!+XflEls|hdJe1Ie401)P|`_L*e{Y#&bfXi>r$Y75=gwrFtCH&aG%_u$_6;<4LxDoOO=%$f1YM92Dlk2H(H;>JJ)!4ASOlXD z-VlC}^rsCwH`wAOIi9cT|6M{vazvb@HnqC&lK5%$j4?!Kwc+H|n@-iZOMPSg6XQhc zUevmfa;@fEup9Khpa-@$*R(i*A1~ckDgL#l=9-jtHm|ZST7Q&tCUH(JPsllST2x_k zZnDXCFE1AfEc?_)_+>Pr%~^jO4IlFlS1VV7zacjo(dIZBKIZDt;0J}gRu4yFY#I&+ z$zWHdQ|v0?B!*0fKTd&mR%Ld1o>s}3`l8Dv7td(Ja@Jp%#7~VrakJv#L5a2B((~1NkAQgs$M}|a; z(_;>JdwL$0Nj*@5Zy+2y&v3%H+Y4U)(suL3GsCvA(jZ%5Tea~5!wtp@LZtK8UunB} zvG%4EwT`F?=2VWS;e7WJ*e<`$^6K1WkfXks7e1xiAqDl|#t(jdaQctms`6Z&(xe%C zqAZt-NYAyiCrgMvyGaOxQR!caJ!zg}8W_-zZZELj5os+Zf*{gk0+}EpW8NTs4FPR` zy9Xb6~6SN8k)ezLQq&r0)?o3l;R`dhCn^eA*Y;o6_*tkY<#3uT%r zvN9pMY1k9|@9Z{|-0ZnuXU~$|_!s`S?JW0%U^-8CIrZ{H$-`1ORoYdeRdBxR0^9Sv zHoQ;{K>G|rZ6x^rd4T_-fo3*3kx5`48f5Ta@{=^kLWt69PXyJDBKm~;cTk9w3=JVY zvG$`xppVm-f*}$RBM|r4zOC^a#lsC25dQF{S)g;~+|lFt()~p|Zx?I1rFgta{k;e0 z>Ry%?dL53H>P}%U!S|>gZAb0s>tWPt_N)P_OD_TcYZ?)`y5`m-$}Wn$kpwjinrg&7M$r#oXUdvq=3L1Bk-2^mZPj5T1m-|CVwm^m;S3-X|v-s{O;2X}>FK^YAF zk%-GjVK(eV&1=LM#;!%BFxMS-Pz375oOwuZn1{OI9rI8*d~BXtI}A(iGqg!HcFo3l zD=2#=8@|_TM5We1hGvUlj{(Ca@xLVPgkAV;d#2#MR>6x~*oa%twFffe{uqV%azN)x zJ~ABkti|Gr@Z$w9p5e!zKc^oKWM+TBfp~{sd$@u+Nws6i8WnLPs)+MA6>;MP#2A7* z``b+FC^x6RsE5Iv>jo~3|23_@x+{({*cG=GX;_^E1^rPSGE&lv_tJo$8TOYk8qmIbtR?gF^zLI<*S2 zl}jd5C8~j_Q{9I;)hg7fetl@c-CPjX`R`9}|Eia-aKh`yx=y-8PFM7RQ6o_Fmp>qx zSc;1riz$(RTh1@aC7T&={EuSJaMuNHPX z*!@~6UvUU;P`f(mGXv@3RG6l|MxB|5_o#F8@FG>5x{iS=a{Rx!vf``%!<&_M9f+Sf zGY~&R2B;U*jV&^E!3|Du9d(s%M}4nQ?!4>&!GTgrR}#^Eedy&a**>S-@5F%+hyKoP zhjEF8M|n%UxANr4*}lic7tbHBLr4h9j`IlYUA60SmGJU;av7fAfM^-RGX_7d$z*D<|>8c&_9L zpOy&saSG$^)W=-eai0@^|5eZNU63N^Evha)W?;cDOjS+)mfwLZ`k5wwE(1MlsWyc# zj*FjyuAfJv1M4>RxYWyWTw3KgE?4HQWAM=oRfBLmMW38kO{G#77`Vn&hV&sOgDG8g zfS0hHK-KaBO45Q@WLY4NI{qt&`?`&O3~&L_v36oEk+>(yMGpgs_>MnLX#Y)2E9OtkG}pvM%o!rB8B*7(jq z^@#a)zvE4Dqr<73p@=J7^*ym3%;$*DI@Gqu#wPxUZmJD|@rf!YgY8xW_S*1oUgdko)Q%lhr@gtiG&r z?t&V)PihpbvtZINA-Vr6+~=#|4{cY#Nn<%<{n*z+jc*6uoO`c^-UKgaZP5D)=?zW- z-JxS;O1m3+a9&}97Rq`e5Q1kGj09a6C;DUd_2JQyFah1!e6r@sZBf_!I-+H?(7|oD zB*~Z;n{nm%MRDV~9qWIZw36@~rN>tAVonuDri$s7mm$^0^F=5&FjL56XNfLn&$*0P z$cf!%j(oO}trXIwHFE@X{s(Mc=}@v6|6B)~$&YB}u?wHZyU!2E3#u#?v2z8J$ge`5 zp#1@OZOljGkH(mSKvy`+`78a0kAb^joaLsUyd;T>cz?t{YQc7Zr^d@b?PP%WVa^Cs z%&6P&(vOJ?D%RG6BK5?!tB5OA%Pj_@T<18>MFM>dAgn=vU6rskwc8UW} z?UF0_d3}@qe{;(oZC#uZucD?O*XIl<*lEyCQ9nH#%%*G*pQoPxi zj3)>7S|gY_Q+{hZ8f4L&TiQjJabRoO{nJzqqYtGjV{~UiBXqFZPB;FBajV|LF4(5P zjyLD5bvhbrUCQ-anTdYBagrF$TIU$KTWr~Ft@Glnb!1x#4#1t{+Ln}L-@~zzr0cw+ z-i}fB;`NrEcJ@+hYcFFXkd&gN=`qQYhHOJ$9H~{<4e!w+*`lN;~DY-srL_BIXg&X zE<5Fx0a1(ll{X|57fVae#$SCYVpph(d?n|~^zLr++UEUkT&v9$u%U~q5pqaijh-L% zwvE{>Ubod_&mMHB@L91!B>&QcZifnVA>(sZymzwcS$>+|p@h#)WIHyZ6PXb@k?lYy zGH1?-jF=}0=;vieOVTqWiSemXIpWk*zXM6qZjZEoQ`oOmx0Z8M(URcFN({~`1oW<(E=84za`OFJY(tJ4V$Ev7JFCkU!=2Sb1gr}C&=5& zFWApdw8rEbKWah7>Z0vBtIyxu(=NV#AvN_RDkUBV!*>&8u=zr1C0PEx?0lS?-mQC( zfA8{5n0J$Q?xbBim3x$Zgi{Qcq4Tg-%Zeut?p47LzpZK>BMsavyq3OXwW00C4Q5ss zTI;f|Uy(w86(hVr5;h7{#$>Y)(ojj!34*};{vGIMe`0?A{K5tOVIFDcJy8yxO_KTa z>CPdcvmz%*f`aUuciptS+aIxW_jqGI4d&~@K6wh%B|~irTJ9Ov4hCo|k3)+vEI2Go z1S`ob7>%Cp7UU-~nye%%(Kt66EYRn+$A$aNl68Ee)lS@|SPJ56yik=s8a~A6Z}8_0OBr{T(1q-D7lw>} zLP4%#tazBhKGVf|;SW@eKn>1H(PxoF&u%J?_E75OjeP zBkYSrWAABjUt>7j*O*HT8PE;;n;H!&N&j^bS$MPFZP12>4E z9>jaQnGIhC5ie}qAg-{aHfYAMi5o+ccxr=Y3@f-X{IH7IfMa-GJ%&%Lm<=;w=&}Y- zU0VUe^xi8fFK@bB{gk$)^Ppm;kly=H@G7qQYQ3m&OX-MQ$&?(Iqykalne>YlWnMnV zCFylMdbd;D)`az;I<)DdHB$sr53Jt2L}YY+Ct7t|opanQMcYgrR-3L#NU@VRuS7DF zQ?7Mh7lU-@yjcR>4UXt=o(Fxj+B;s?AQA@$vZ4hktWpf zqTH-wEXCK?83{-aFTMgqqwxJ@vWA8|4v zD{b0xyFliw2n6xFJA1t2_Xz0_wIGIkZ;jhW_p<)xG!k`0g-RW z;SjlGtw}vU$}DaBiM=|e6^*Xf#aFA7;*ou31NpuQI`>=O6mOGPnc#G_RY5a{6Cw-q@U(A}0_ zke+!ucHUsiM0Dm2IbU56F`w$&I{N*B!?;qe5-YPekAr zE(@1Qr>x`CPhRuGyhFUbMH?)(EV1XX4jY1Dx=CeSr5-pvq#bb8UG9rWF#(LLB;)G1 z|I-4P41PS0lxB>VowtMB384-L()Xo%otz3|IjF;E;>RO>OknIPG8X^Orwa+nQX7(F zFo(kyYhC1k#oIxq1{Qzdd!QE+g4;Z>bLJqh*oDkNVDWL7^NvY{83-(PB{L9Moc8(e zw~Q<1&?Uj_Hd&P$w4PKk?Ga*D{=RbFUQr2_!9sC5(_u!$ns>{i(YH&{?g zDQ`}sNVuke6`;k?k03>P&jRm8 zGPv+jucR@%YTZ>`Qt+6`no*Pjrl?oWv0`V&sSpwP(jZGS>?I+w)t zC&Y36$=MUIN88FcGs4}NguM6yaT!_>q-H@IJa>rgw`B3@wq-bdN>IPOPHibDtN3gv zm||k?<&B&JL=MTHM*@;Rj|9Z3M?yK68wsvrGq}lGiIa6CH(A>?leO~eWNrUCSt~zJ zRyd85buc$>5LeDk)j>FPzo5i9OF0Us>Ia;vuW_n=z^VG0o2n3Bt*D5>#d=;(?LJCZ zUV(UFOi)sAVpvspd1Bs4ozsOmb&o`^Hn$i|U%hNTR%Frn&8-r;viL+?da5*pf7sGv zkE6`ReXo3vzgLiVkUT`^16l~G)6CYOe(6xq;Q&90+dd~RTk$rByfdhssyI=28qpn_ zAQq<%#Bx&yHU=_a%1s@}I*w=yZe2i3B?B?)bup&{~#f_t% zdKmqdTFy-?xk62Dd1JKW`m<<&0+M@Kuik+m9Ou zzk3WT;TA+{8N>GD`ql57<-kh0<>1e)27hib_+o>6x%Mm!WPavabM!d1iEGOt=((v1 zeT4NmA7M0FTO7ih-)F8P9lA_j&ij9)JEGnHjqr#rL&_u70Kib1V8!*&YIO&(v$+mh zjs3HF3&O4UBi#D^90qTZ7Z7};22T*-Dm8dwx;jaXN5UjE9*O*p0?;Ky_qD+Ez8to% zvw}jS)R37OM$*)02VSYqMsZ+Y)Q4cONBnPfHYMp>!?Gvo7 za47^g;_6-GQ^P3dZl}lvLj*NmL{Q@eLxeAWT!A=8!>_<#L&ODl|JGoCciqN>8DBgl z963)3?x)&OVn!Td`XT!ZYAHLEi4DG@cm3fEgxjaGS#O0+0=inI2je)Ty&jC`UFVSY z>v+b9k0)iqD=LfC0$uehtksN%bT#)9lp$FaV(QoNmf$;NJcp^*Bjb2K3s{ShpI>=f z7hTtUHM&mkI9q|B8+Y~uJ6Y)Hv~~9u@n+l9*u7GEQ>?AcabxlF)mGNKrTN==*;!>L z&xy~Ua@~JIO0zz>MJ`tmkXdv(SGt=R2<@D`FVvy&7k0lV&VlVQg)^M|#Sf zmy>nw#948b=GD9V@(Nupi?7udmE>}^yMc8e`QkA!P*_LO1qzVxU|Ag*#=j4`yrulP z=qN(2t%7u9r<3r=(p4}NIRJHejr=?KTo+x|b?QJ%rl`}(uV-`Wwb>%j5h@y5?msrZ zHg)EPwJ2g$n69gxFP^k)@lR9gR&=yiU#hB-npV^pw~0gRgsUws6j(`%i_TSE7FQPR z*kopHVIn1}z9u$>Rpmt`=dYA(v?-QaS#L2}E7o1Prvn@*^ap*aeB>1*rD));l7CD zOCh7LDzDcfiB-#*7M$I+${b<%0k1H3G2OXqkKEB&YGdWKb~v)AkP*iaVx=z{MVDCNmA>%?*xc00R6u2i_G9)>VRBYkYNPn&i-}~RJa~W50cjAwSY})? zT}*n7L0sv8K@CGt#vX+25JDt)k{?hZDVe&?&e>K9hALLL$n=8ZP2;TxE!Acw$x_1i zSvG8S&mV+`;U1HuHb4=T`KgE+xCUO4=EQ?=b#00+r+lqgzw8wI*P!8h5^`&yZ7yf$0X z_dL>MvLAS(_{2u_8_z_*&b}!mPx;6<_bH(~=~`4iqCt+Cr!Gk_!K(qoQ9n#-(SqI` zFzK;2o5)TQMz`=(y8Jnoa&K4Zv5maQjQr4Iu|Mf!PuAJ!>vZt*ALM{lIM6yUiRAI; zM4BJ(TmMjXH8tZoJ^1)=bw|z!QH_<)1+V0v7}?k zu{wdl0Rf`1(dUgmh#xl`kvwqJptzK}BN zu|GH9xlK?>IG9g75GweTe*<>%;1Iu+Sn-@4cA6pAN}+~pC6(h^@kOo`Pw`$^N^U`6 zNkW3OAe5)-3wgrpun`^S(8Fd5Q&jkUW$UA%1Hh=Bv zT{hDuBE8%jKzsDR! zZ_!_f7_y`E(HdM^)BR2nyC;vCKrHHD_-4-22YzVLX4evl(AV21&|B=_9+z2Ia^_5? zG~!4|xEN`Uz#rmol6W=PPSxYnRMctPIBzpsFWQ)IclktCWZZEH`W-#H-0gYv7Cnz1 zafa`=vlv2@MOeWw<`LRuHI7OD_BcUVgzZ*4ErEOM-A?)!eEI(8m(P+2;Up@Id7|!> zP@!x#V7!?std+(e?LVHEDA&(K zTmtsqUq823HmX0sJ)P6~{vmCG<=cKOe*}Tvk|_Uz`<8-5WbrIjzSGLLLJa|?UWjH!MU%2l>MB< z;V#rkB7m8c#>4H8*7~tjrRoOOgu^j>|JOK%{mPvNjKQ4$26Y&%w8qw|edXS^mOr7} z5eZSrAtBl)Q1B1Zjvvst%yCE(jn~{g=sA94GjquJJ{{D*e2S1YVW12Q&I7$60FK;4!Uz&aTT#Ubqcy; z7z0zmv>UqfFAloXfzX|QanPL(4Ri+^glq1$q5$`XLIwSB81sl*blq@~L~h1SWZ*0} zy|^EI{IOj}~BN+O8EqRN1d@#>>%rl%jT*P0ue>cBI0(r-VaV^i zB-JUb`xo>HeZG1!WFmh50`9XzI8Q^U;cWlms^7;lU(?DLFfd=W@i zzS@PZ0!d!D@Kv5;nS*HCMpr=%QZPsHpqVb9&wlk-bVHBDf&k=$g#E(!V;2fiQ}C4;NMi?L6V6@o_m)SU+AMnJ;_`L(_Yuq7 zVslDrDvJ}PQDJG3@sZy3{d{b#<;%sB=2pVr0;Ndc5E2y{mn3?!9odv8l0j35fD9+Y zo{WSML6YdBAt6!HAi-`Ii)|*N%>{NBPvjg;NR!~MZ!5eSS^V&c_-*>+wTKHpM7_jD zBHRa^ET6+jZ09R%=N)WkG3gMZyXA9qw>(5WL0V!>rneBHT#neNMdXc;euNp`sxyF9 zA=)mAo;+*@T`Wni@z=Z~=Sq+dp;qDzbY*~%-9pix6o-_3lKNO4nsPnjJyVa1P8TMZ z9FgEhKO*pt~{s;)*`6nLh@}$8=vaw_C%gL>1y57<7uQ#4QQi-trK=W!qu60mEsq zlqTFdX;a*3qRSA!fyE$KnE=_lIgCJjY-K?kLLzcJUo!SyZW7M57V~aG-qMGR?4Q$- zw{$W?8c+}R@*Sk1Z?59(OZ2;ipH)0zR&sh~j$5jugUr?5F~u2K`M-GMBGl)rL+&HC zFSnXi6e6t58M^8{lfXc$8Y}e+CLw~VvYNuAdc^w7N3746gdpxUvhPbCM0FsJhH5QW z&~1q8sC1-Yq^cF09;IH=#T+(qG!FY~9QO8e)E%-4!BtUs=rRb-I(U#GYr5f8&(JsN zNj|uqdWtyn2!?2pk(l$dHwXgMx*b9)p;=wc0jO#I>=xqv)h(oQD^rL!5Nv7}-3WWs zSr30&;`VK-?E+?ws+>#0T-#e^%s$lxA$@r=gAgnPRUuxi=F`N#0%4I=^SC^-)qSw` zf6EiYAeH*%)+3$ti@)+L9>LrujYtQMV;G?JFa}q*JU6`;kD+HX-9DRnV=PRMzI3Wt zlSHeIP_&Zd>Zm1!D2NekCqci7$nR=a`EFS2vFiEw9M{_t<`MJwgBHxhLwBziMNAMexr9-uY3#o`W69b1 z+#6t}G7mwYEIH?th1?(Ll_js>h;(i;#HqvrmgvElR@$6SeSy3FWJYO%Qv63S)dmwz zR#e(v)L2L$_Y*qsq2J$@DQb|ngGlCn(8blg zl|qEKb)+;G9sShr#X^=g=%}T<|M}rbl+yaWRuoF1+E+L+k^A)?QHNuc*7^)GC+cVg zVx0mxsZqHN#q>hBqYd9HoBb%IV~y5HIHY}&6AVKbvP`)WWoNDTC^>7x)<3n>Li4Xw zmG$XW(tsVp6UokYzcQT6EY($7qsW|z0yFKl5f8z08q@#NP+b6L+=~DD5jZ$k>q8TtMK|fSl za2IUkGxWg)qiq=-OatTRL$FkP3XQNA^ z&tO%fEut;s&0vDcs^5PhLNUjSH1hWDy{T2oT4-NHHNXOP#Z7@qpPa$JDEwMd#%OMYUo$9rMj~py} zu>Uh}>SeNiDi2O22?Os4VK2mU+DHqCMQ!BEo2t#IjdUb=WFINuZDjr05UHu^qeg&! zL!1(U$L>$)eI4AT9nJnO+>3r#jv!$DfQRnX1y5mZ2dsUH92-M3(ShX{415P>9Mj9d zU&%n+h1<_h!zcxt(Qots88?DhipUliG8UNql8qgL=^zk}IyUYxj1=KUPE}f;rn0>?sVo!76Uiz*l5~IAq%`=;! z%chxiJd^6WU;q#}T?fH8^jbTAfnG=3?G*GUm~>ufRe0XDN&LsJZ6E^e1r2i(q~QYk zpXZL3UcMvxZSIYc%eKjO?~+*C>{v-8BGq=mqA;UlyCo0#2TFn-T^7-wngl^CBLqq5 zjdltB&)U*03zu0N&-IhipMre-f_%lR1W{2TK~YjgK(omh(X2Jbvlg3_7IG$ej?|bV z34j^DJ;7UJ8VW_t!M6i0OQM1!j~tb}fI;^V3e#J3Ea+HZ6tc}63_0K}B7a*%hHRTD z@#pV_QHC&e+jX6h{K|Qc$+QA8`S_T?F#+Rsba$YW+&Ec@8?3o*%H7Li5ZtQ3Fl`O& z4&@XfefqfF%8W%~!dqv&eoN8L%>P9mC8`rGJR<*!dgGfywQXedx?S3ss<7w+4srmL4?b z(Xj_llmwNDTm5n88f-wO;c$^YtxFYllGFQ259a#?I(n}3anaGW=eVTpIdX5g8+R=P zeMAw`?N=H4wI5?5Z-m_I5Z$O%)CEO|7EhB4VSF2m09V+(5QdR)WXyDgZJU!|1?nsZ zOUV#+oDc?7!#|$9F2h^+;1J1@@5nR+SdE>s>OCx$=+<)g5yUu6!Kpb(^>>6TjR~Z5 z4RGh$eKAf3PTZ{v)wN*=g6Mp3_jYr=PWVv4n$<@0CeP6EhyMK2z9$dGNT%|SdW4x; ziB!E50))lvJ}NjDRAyGW?9R}Bzw#%cv6L<|Y1nwpGzN{1+IX%oty+=n25q)SUo@7i zVC5J!VdK_k`eM0HVBjI?K_gzskt4wo;@ZNWr=FBX><>BQEAk6Gj8x-ffodJ^IsYx> z#pJ~nM&|a9;741<*v8oEpo2Ey2R~kl3`3ymq#eSsL9hrJh92=1FyaMF#{(iZFg7R} z=W2*gu(y{8ky+nOCDSZtO9J>lXZDwPm5$@+hRA4E&;X8&dPUE-D2~HSH@ug?C)P;l z=^5-Jrtkg~wxalk=+c?$jx&Y(F|0w-RSZgDeM#ZQTP{+Zu1_XAFPcAE zL}tSrOX%+|33BpSvCrj-XTR+HlZp$XBLNY<63Zi7j+n*jjLckD)-HO~*bGvPSd_)b z`yO8Q(&YgR(mb`WJ=(OIyC5G=kBN1{t=Tn>^g$7W5RVQ zWWi`bObZWz*+1F%?Dv!&+r$e`%?z&+SCbt6uv4b@l2XDVqVXcHO=&fC!NJGcpkm!; zQM$F<>OgL>Wewa4FldJf9ok^d`U#iVkC;jZipX5(JrDkVP(qB`0fijhV}LF@Get0R z*i(I+`ys2%hl)tKU~uBb`>#d6UAtbDD}f&-3C|^_Wn8*48zY9TG}Py=jC!oQn^p|F zQXAQ(gfNq|llkQBZI@@TKB+i9KQ;$>`(Y@le3*vP1{as@0dER_0U0OT?zPKjPk&tG zy&#UKd$W;gFqg51-1M3{Vdw)G)j?N51@5Hnu!;}!qOQUi7%F<|-r|-knaPip9iKBo zL_Z?Z6$X?2C2Y+sRgGY7gi!?y7QryVdH)l*(q{4_okGmFipY-`0P^En=yizeCV3k> z&kg!eY(Mx{FjFgju3*k>J$0WVGugS#YULNK>!2~X1*^~Q71D)qP8LTocF<4bkQbvb z>D#{Wy`A*Lp@PGCzJbo3D|}pPJ^E$l<#yJHq65MXhf20Y?mS`|t1~%sbJZ`Rx6O}# zE6O@_AYG#S`G`Y(52u2|Q?4C~(dT{r1H@^aAzN|d!o#i-54(0e>?$>f9d5i8m|wm3 zRzj50FrT8!$x5VpquUqCaR;Tz^o*9f|)w;GX+z=HSa!E%iIAT;lTtVey(Tn?6~6eGupbx z*PZx853K)s_KuKt?BPl#@XGo0t{&%M0*|(lBN#(0%u2$TlI|%^jxsk#r({{C6#V;k zr#U*hb*FLly$wim2nJ-p3#|95XQ2Pg<}uwU*DNY@up?$D2GdXEGGf4erA=N520Xf< z2ZrbwAk0ik>;8(&$q51vvCb2Ajj$*^r=Zw5+uFv_-pVG!u7Gs{;mW1EXA;kBY_v?0IYt^NT(po#P7_^#af4u}JpkiY=%> z8V#)ebnGJr6?|!#hz!bdOL1}lK7&1kbyugjr#LubiZ0NU^D7wh3Mt?m(lL194GKc~ z-ayJtB(3ZtoP%o1D}1CTLro>-bbAHE)j6{X?jaSk6u?2fo9CF7xMb<*+3%2yg1Q@uof>GR@@ja8VbuwzA)8Z$(Wl^ie+;j}Kb=0ySR>8PPpzmI-QQWgDNl0JYnRPq&+30QJIjAS7b7P(<%sJ5U;U} z?}f-K-EsuZWZl$@yLGc2th+pJ(JV~HD;1f``BoXY%$9gK!0tCj3;yiX zPQ`B^#a8{`edbGc>GyYC?zPlzh0YUxT3JG4LWR!r+*7sCLwtf<>x64LeCTn?c>GCe zqG`g?<6AM8{WY&fmj>Hc=GOz92TD*AOM5*PH)2Kav{Mv5#{B`R`tXq|mY9nm$n@W-9RsKyLIc7?cH#4O$*oU$Bjd7uLV`61FGWJcI9`x!2 zXKwrL1wE(@61vRG%ii0;FJ@7{;^Ksa4CyZoM=)gPaEyrp&H~z9^#-rL0@R~?tKw0U z$X>!2Kb(5wdRIHs#lC^-syFIu>&(C6!qr%|R|!bpLuA5F#8HGHt%l5lK?fzvJL(1Kg%5+< zVW$XolEIJ3VDxViOjErRj*K4D3{ym~;E$_{2+5xjF42ATyw+^^@95@mb}PP*S2$&YXnoR<1iYd76p!O{*~?^B%m>C!)&d4MH~_ zgZ*Q$!;VufS5BRLhk;XHs?+`GU;lc;QQ|E{rwwneW}eDv{0LkaShI3<%_`M3Lr-Dv zJ4^*G@X8iga8nEBc7fk>+^tZZg+|WT>To!<;-^niYA;E1Po?9VAYx_`D zBH|54i8rr}O|p`@FXp*cT;10sMvBYffH*POM0&tjvUAyL51FYn^=DpkX?grbF-Y5o zlD;ug(uDqZg>vM-h59z|<_KEvbiH}ZN}teYX?qMm1@&(P^jWew5?NAu!!$A8q5Hx= z5HDyp2&uOgkV(jz!Y9Ta(h+>R00R-RKd6Y1=q*IJ-C!wN;)ge4R6G&%uP1|uNJ1Bo zv5OG%NlSDskrug10lp}0_vjm)6cHDhnBI{5_8e|&=_jMkh#N>*mvSsWYTK%aHR7pD zJa%oDTJLc-GZu}%zUq;WBtYQi>$cy^Yu!4Jv37F~xgL}q@X%qkfCz&;?St*a`U}e2 zU$o^tF3$GzkC);W`IjUk4^a>Fk2V;CK4dGqAnuuV5Y8DxScR(?o(a-UoK8eMZh@;+ zru4W?42BMy=ds$(T4HClU1oJ4!KmNa$m+B+3ybQv6ty97cPDk<)iAY(Y#(_tJ<^g!Epb2lm{f8l7l*%IX-A^qZ*vuVmy zF>>4V!@gZZ>`-hM!rBM5i3xd9uO^=kN5%pQh0NNyyZjRxEH^{Sn-95 z{a$&}|Al7yvm*JgX;S`*P8+H|pP5?lLkDc{g0N>uwTWBiMhR}1UiN;mi~1EHQZZfn zvLW*GhPhq!3Kv`%#-DnjNWFLo13IVSIg7Kq_f;ZxwZbD-0+C!iDDHGk6~BCJ#jTXl z_Og&L87{mg^}_48wWb+j)Jrdg`z&3ccDA-htsry&x=5#xhw86f6Tj+6uEEp%R9bnX z2-RWV*O7iZZPZ^$z>T4Rq>&WPKQ#sZAdiHh$?2gd#V;ONj~p^>tG=CPWud{ArCX5! zM+=rIAW+dg3zp-y4=)7Ab1$Tnii@)LyQWHyJ4Nk8-QXbwgbSKHt8EG;Id+zbYsG6; zySP{*z14cykK>Jp4RWfuP%r^T8Ze*t`I<64=+7NgbR}-~-rQzi8BFEE5Fh43_m0^0 zuO80ahPO)I19Wg>1XDpIF~soXN5PN>rnpPu2He2D;r}&{^*VVYtJMex+_X-=fK>F6 zT!pfj?S9ikR=#7se%@pDv(82%7X#8$M5bIK(@^s>_~9Fji#Bd@C;8iABdbMwP_YnR zmDG6hY+?1~%zMXjBhDVph|;lEjT26^(H}j=3UnS6AI(q5krbyCW?c~fc5>((sqS>& zIt=UWd?iQ*v#;v4J_6G&qo>G+x23f&ofMdP$^WAG7nqy?^o@yCSt!06yo_f-=4PA^;89*dxU;lv(Kns9U~p#KB~ zKOB7nTKEyjI7O>AhwxZba|iw`M1=AO;>?fFiaQaVr;~6o>RN*c;Vz$9yE{-ZWm^k2 zsFy73&{nfZuOkkIhs@3Q&hGEI)oYWRl};x=@kDG|#t!ah>R;LEikeYkl^bNYd8xQcsD$gf1|DJ6VGW^|Q4ex# zYwDu-Esx2eehvH=5Ri2%wm9}ITFgR?!&iiDj3HkAI{3Sg;+tskXA>Lu4GweUHi)X1 z7s+b(7fgbHexwIqcL&xNqg`%P3qYRgc?k9h^S8&ZPe$HBPe9cCR|53yU*@K(qI+(- zswN^W1M)Od-|)ecd76wcwM#n&o4p9ea1EM>JcRo{#m7fg5n z6T0vK&Qop@hLGJnGC)3X8XBkQW-{i(Bp7&55=4xVfS4`_g4H|_M?nvS1>0dp5 z#&uH}jv`q(%U7?AW08&5+4 z>DgrV97DIK<)N&&sf*n=nfUPC9jtt;#dBQFT$RE!loiLL5o8i}@?$in!ECOd*_YVE zw;7mu2{mQvL|n#Pb*i}PoM*3puFgYsbsm{;OBJhAb(`_`y9V3qpK>}r1?*60$6-Yl z!w{8$z`w98phDc*9$i)~J(-!3UnPPch@fc1-n~HqE)uLs5OEWRr6!|PcH_R=^f?Qh z4DH-Q!#t$A5B;v$$RNHRCb{Y1*0ZJSY8PGgnrgTgqb@3$E9!59ONZ>X5A=7JzzhL# z`z|agEi^-X{f6`Gd4~2sJGqC3dP?C}b{2|=DtGntovN-WmdR~rdlcHQsn*Au0#owO zi$F*Or-+uLZIC~nrPI|#rlg<{+oKf;>=A-L zf6Sq!D@TjhSR_QdNIjSH+=|cd!vN&dU!azB(0!){i&ANs`SSEd;!SIPoVQDp*YJ*I z7ROg%*n=vg=|`m`00l-}IR}p1)dZuiqrlkuxV;0S6`a5rj&xAF+Btzy65WZECt}cj z^$sbSM@@N$!7y~DO(uQ3rO5PO!0}R_QyB`Unm>DqV&a>!=bevB#!f&1alGZINfO=3 zxW2a4!B4eXXP?VLUAM6)`bz#6NGN=!8YQJbJDIgwI+TfkiOokb zTI^uw`8zEo4twqPTOUeX-0xh(+0^_KI@c}~z5}u7fzKVQOOnbxW;v@cTJv73ohUa9 z1{pH&)Dzi9#C_nG3|cuhrf<(TH1%00QAmu?f?9QMM2j#;{X*7K80%t^ycz{U(sL-% z)C_!v;{Jq|i^;L+Qjcpq>?!Y!;xRv8dv#a}0d*vh|0w!$^Y19rddbm0{{I>y;jiLB zcryPhyVrIG)^RiU+S40aA0GnRjcpa$AGzheUNGq3!Y#Wc@`G-l_wHj!$EEdWlDhZq zsj3OM3d;k^#Wxf&Wf!C;GL!QwMW9Cng`|g*Z4f6lPRC{Fj>|ALEL(i-k=yiHQ(c$Z z<5b6G2&UXROv89a&0FeWntClF35|6ZeGKi#XvN$p$E5{woOkpzIoU6u!{q@5<+$i? zJdEo894@SX5W(q@_PYYOn5DDv!h1}PR%Uag4Z-YimUs!nQc}64d(Um=?3u31_iEPJ zejKqWH^0mcInIp&L1JhkMv^Z}C@rn+rcKIJU^0k}T8Ho4bI8j<;^HlH^KwT1r3tWA zJ^EWeQeVzN#1y$v2v^5J_oiN`Pt@PJ^OSD?T{#<%(AV83XuIYBB~!>|1Qu=W-Y!v) zM9Jn~J(kOR+~f`%FhD`l00XETK}{nVu>;!#eIYcLqD(zZ-1jgxhe)%>;(qs%Roz;LRCQ|$yIbqfEiNeO3a#XN=+~hAkgXGzMx^AGichE7 znukdn_$~gsY9@*2Y}!7;*)8b*eTdQRq%=+dh0WR{ zDc$pwUNPm=OqZ?3oEy>9y$ErvH}LPn_zWR++4zXA+=)dj#qc1ZXeKz!=q@U*t@(v| z@9HkiHPoS|A2Inp7V&HtwTOLFM$z|e5ZQ!q`~Sn;SI0+j z{O`~1p5-`u~OWvlwzB3Y47*E z-*=Z>An>Vt|N8B|W_EXWW_IM6XWlbAa%4wPe5a!xZ)joBLarAx4-P&Uq}9?w&6Zzd z;qoaabUD(-Z|-8o+_5_55ktej`ttklhuHCUE@rS*eUThsnvSAPdT!|sXK&#ulvXQk z^Vjg42+Z~aSQ{Iwz`4TW=oOE(jc-g%?M31fOsAS?9^l^N8@uX~Yc0pFAnn#Mj|WBL zM@=(h2sC?e`A}2LaI22BrFU3{i*vd-D#R>hG`u+V7L?G z$1dOLPb0|gVLj3(Se_yiCSAP2K(Z$_FgH!}TkabAuIQ_hylcZO2FycKv=H-3^e%3(lT@5DI_I6hfP zf5DJRGw3aEMC1(XqFxy2o+7*6h`F9f(KMLLcXn~Sn$VJ}ohXk6nHgM{?|gaM5>Kn4 z4qTgqW_}@uG4boC=eaTQ3&t;6{`oYg?G232osZv(;cAbxV$Zc=w1(-Q>vYTT!)8hU zMLoOs>(i^(g5DTz+yl$9BF$iJ%xTS!tSx+!152H1@^aVIqCQ&tdU#&UX>tmKf-_(W z(L5x`vksVm1Ye8r5nzaGv7m@O0vvH&fFy3jerH@msppFeOSZ8&&fCYS{g-s7?P zCE45sn@!^vT47wm5sGa@VS;YNP(2K=D2!>Uxzm{59UF)5K$?BZ4@Vc5C+HFm#a`&} zrMSzJ1&HYeYz_W$7iCep<5O>0wv};5c0d_~U|Si=qWvY}LxY=9IkJ2HCK%OTiuHRY!J`gM!eOCh z_m#A9`(`uEH*zOeGfxnTQxKXV2#yXI9#dmojk}k2@3|P!$YA-r493#`x_^iH=RYS< z5)$B>+S=J1R?NA`Ym0H?4qLJ1IKBCn<@abCmcaf7Fmn>hey<1{w0!K%NtjME8MA<6 zv0$uLo`N|AQ8Z>8WxKL}_75xVLurc&uQ^I_ zCsNKe;w60n>Y&@GKMV?(8mj(dfA4 zK6{g!z4@~$xx0?|%mHFY-m<)nwY)8ZujGtR1DI;DZkSSylnhfXc8(|EP%Mykh2pbj zH+N@DVn$9qD!3Q!_CIa8vH?=nk@%%ZzSop|7b@B?B?zKY53_ssxr{GzV@43H#rFhl z{5e{e*Vc)$Z;7%e5`qb0p0(SJKQkBV9I{iyXHkW;1tW_wTA=Lpw^8drOcg z^Y2@p#nP*lpaIiIBguAmg+mjkqZ0Odv%rRH7VRKN+1M?p2ElH_^ zAt@9Y2%+ml9ZYPDg&4X{Kn^`Cexk>bX2jmVvty zW#I0|3~=`#4zsyd(rm7cG@EM~py=O?lJvCpYIiT%UFF$}r}X8f@SqdiH-+=gaQzz` z|L|uRlDrF9=NTfWU!3xqAY$2D((GvA=m;yAXu{cyNhBFhFTQJ8rDxeVrmH{y&y&xTKA8y zvJ0O*@!~AGziRmvuCK!JPPn}Zr|bSKh`2d)u>E=e1Qp8)E_-3=*#^TBwBCuw@M@?# z+S+`8yA77>*?|zoQ!KAkq?efKf?Wi#Yttpm8Lb$z!X@Oy17rjyqdBA^Xt~9&aFKQp zmQBJAvg@__2|r-gkDI44uZ9@*TuPQsax>fIW&u0#u=08)<#P+n@he=Etd%;Bfs>yl z_=9`byQ#P54qN<+B;s90v}IY7?c_KUx@kS7A1PiinjQQdnI%QU^CbFiq@5e zoKL+MJ{$)LgDF-7Spsm({@iw?E9S|zS?9*%;dx# z)3#4uKH2#GYg3BXJ`wXvP6@S3TqFdv~I*pSC|3OSIjyh~H%)iL#=-m?+*# zfl_9vp43m;F71;pO82B!awU0}d`~edHsuSYz0yZnsZ(^>bQN_|bSrgtbWXjh|H@!8 z1RG`;wis?1-WjdNNaJ*qYARq_Vmj<&@yXzm+oyrg9-k9F*L)uPyfrt*0-}@5>&@HM zAT^izwK`orq`vbF@$KNd%}?i7%kKxj<$gQ;PWs*VdyMftX8#)g6a2sTU**5i|G58| zG=?o40j~oy z2Q~<75!g9!NZ_)-)qy(#_Xj=*d>a%Ilq;xS(14(sL5qX-1nm#{Ip}uK{UE0$(30K~ zWhra(|z))@9ap)-Bef){EAA z*4H7rkf4yTkjRkiA$dXyhm;H{A5tZxQAqocejx)xz6|*`WOB&7kToH@LJo$U3%L<; zJLE~os}L-E8tNOGE;Kr{KxnbhvZ0kitA{oU{UWqW=z!2+p`$}5hE5Hg6*@n3Rp{2x z1EHrvFNag+TP7Fck4WgdsJ)#Q&ZZqgvlvvfpU7r@BtRI+`}2-PHf{ZP@cf z$&lMo#1VEov*vqg-@5Hf?c*C59R5|C=d0CZ&b%%W{i^7DZ9Mtqk?><@f7rIuzH`fh zvziiCP)lzeI(G1=p%L{4Hto~^BVVpQ(R4qazj<4KM5x-z_^%_)s(Yq1&y!A?C9R_0G@W~PPM{+~{jR3|SHm}}$8O$2s~f0yY})qg zhO1-Nb)1)b?q@UWP8(plZ}@V_kW>905BaI`j4&r((@B5 zzpVe%$}j$@ugt&duC^uRO8n~VZcS!Y3U`DSEE$>eY+X%mYk$yjU5A*k%8i=muT^*6 zqP7vL^)rmPJZaeb7~Ma6b77=oA&k8QY+D$5VI{lqGv`iN7=CS4=g*t9?9rlKr|DA% z+rMn0A2x6Eu&v>bP8`0nyZ4%|v+c8bb)MWg{Hx*P#(iy{aZ9h|G5EhRSNl@`z=m10 zne->Hhcf$`8(mFj4F`Y1w+@{(YidR7k{w&8?h4z~X+?{s-Me=j9IIra)Vh+is3fl_8S%*#C3!hXd-8IUw3ejZf6HoXpLOR4oC?Fb*)#P2-~st;KO6v2Mhz?thL6k`}|h;?e#m4j<+{9^cpp=Z`1ImgO)5D zWmkutvn`IFqr`6wakST-W5L>M`YeV#j{Ln_4(>Xz4Hmr}v~J*<-rMqP`SIgiYwEa- z1;rohe>YsyvaUTkcir5LSnX$i+Xd~{*1he>me$|;5`Ayw4KbC#1=Y{#%NkxI!4Uu6 z^NZ#SbJ)Kq^jX8Y>z_qvO^o|TEgdl};xogPp5q&R7Ur-S9cgdIywS?{`rK{M0iP ztQdt&PwK6#_j9L+hnP2NxmTpgk<%0G$2ae}yddIk?}P11gjp_BZQP_pL|i;xU%9%n zL8IC&+teFqFEg*{+EaLWXw$9>5&l?U3+sj*D+f78tw?(;#=pRJ0=qFj>Xx?XmSriZ zsDyR!)~^p>G*Q90{jaZwZ(1=B|J)YUwEocYyGC`w9K}A5%-ga1>{b0DEYq-^#3rj{ zLW|{kOZzre^{YF#oYgqokv1nLiuH)IXPRGhUA>6rW%ZV6+q$klq3^VI>yVw{TBhqL zAH9AbbgkoIyZ?LpUiH#4IsCM`*H6x#waTtqf7^WxcKsS(&XcchDMx@K;9!|M_VIhI zExI3g_Gra{?RyqC$epuSy{2}5*B^-0==3{*PQTUY^gD%4zpG!{)G0lCO`;W~vH4|T zN3It+Fjd99my8-af9{C+;X49)wOQRw(UDM>)&`} zw=w<34jga7)*Z{O4>uQfC|`~lKI&_G+rFQ7uN_{x>EUY+_n*FqJwQkP)T+Ps<4@YK zpMtL4iB}(3c8}G5wBEojs*WG=dw==6D#F~4k`ZT5E)mjH54%W`M z+z}97Ddw9I4egGtMU2|Z5JwgKy+JL8#}H75q0YXA{qc9nl%?h^uw0}yLKEgq!ozBa_{`qmR);}#)3&b75>MegU40JN~|r7<*M`T=s!TqeG-2SwkO0{EzeS4VE73w zFnl#>f#GK#EHFH+|BxyD!oTR%y5@L9cG>vvXXCfWv~RH8x@tYVb>sg1Z8z77Y1^t{ z{%!$%AWANJ+<=+#scvRa4q8#lU_z3A}rof|YXRj>Yev?Cbv&*%@f zT?@a4@d&DBDTW2w$~WlLn#QKhe0$-A7O`;g#D#Hl#+e*B6PH=@G`;$EtbNwR8Iz|* z>|C^a_5Sc{`|IV--8iNU{t1syC}Ev4=(~P>!nzL|+PO=!B~!bi5=ps zso3LjAZ_ue8pe&kqnW4AnL20s!gS-u>BkKm+rM9!{{?OI&)CyfwN`dmnrfCpV~xuO zwqMvNJa_4e4(zI%>1@UOKW<&RVF5NAo=_J<#>Orjw{~Tiw&(cn8fT5A9dE27#tt9* zb;K93t$ThEUcKYK)8{wrJ+*UPm-ZMOht=%A4)do!Mpy4*L^VQ?l-8N6k)M;wJV(rT)_D82ObWvm*zs7LWyfx9MKJx{9&RYT*l+D>Z80p*JAAP%}J! zqE(q@a+FLQWG&Y4+_lx;FItSt;DQ&RJH*zBV!TOVwW#1Oz@EhF<4Z}e0vsZ~7m z_zM2LM_3&v4Xqrf^b-~>pNMURLk`vYEY4oALW3f;8_t{6lUgkUR{l8PJeH?@@dO<= ztqwI_ZeP@<$+RZneK4POsC}_kT(8BUd!&?iC%Nj#UDuk&B{v>1=Yo9XAOB_iFV?Ap zzUx0QjJs6S(Lnd-Jy)$=y=du{>Gqvpts2lWtV55UEhE(VgKTQ5KR8`~H`QB8v`xK- zDfpW(1%FEGNy$_2r_dC9*982F%Z8p$+v2?m_`}|`PM&~|ttigW{LoFewAGjeJ_qxS z1Al*l`O<}=A5tY9oda7#7k-gPOJk2aV=d6=swUpQ{ZqB{sGBfbLzIh1K8H`2LNfJI?Luyt>6~ zY$>aDiJfj!F|XkoMnN54X4DK@Yvx~RpVM$|two<>JW{tG2OjTzuH%E2XC2B+?R)Kb zS}eIb#5J!5MX0`3f1J@#+Hngd5HmD?({DBUTk|{2XbJ4U06G0YIdDlH&8$~xf zkysTi%Z(hG@yelXM^<4`yRwtk_ShOe^@q3#lkML@dW!pU(P1=c&y2IF=qC-LUQ+eG zlFh8rNRxp^HH*#P3dtk}BT%$-Sl1IuU%{YaX)JBKA(air?rNK{TGod%bqv&FV^*y@fX3>g;qxQZJ=QaM;x^l)^zUjxoc*v!~oGTUB2zsIn3W$+@V8z3_Y(p{k{c=~-8`RO$W{q7C{^Rat2e;XG9^dkE{R6BO{d?LxhDgW8 z!Og#FGprMu_Cq!f*)(_)*m!eVl{Y+}8TM;yNTFFv*J>Nn85_JE8_;xf!SH6a2KQ`f zpI=8mZ~5-oJHmgP`B@*kTGFf?GER%rqvx?8<{1|Jv*`@8TK~HZ&3*~Lx_Qt3$@b3; zJ-=257#+38XR7AVg;m^B`NfUXo6f8R3@R_X*!Ft($wM>dZ?q3NuK%iMyP;LWky&}n zs)WtG8e+;uN$hB*(oeotx73NY7sh?J_CMNjY1!`i8&@7TO)!iuIkt6)Fh{GK@dKkU z;lVKh4cVBuO*QX^U)sO>Qk=aB@V<2WmZ^~QI<53>aL$@Ta^6>v^Qgg@bGlWH&wAg? z+Yn(3qWd=Wj#kaEeUDb$F;xE+3npkAFt(+cKBK`A=_vl?;KBWe(F)kA_2jKHnni0I zrZuUe1y{cwQQ7cw)&rP$g0&T@V4;i(StI=82U!zC%V~SY8XBUbB7QHS~ZkhCu_ zT+vtSb6oq(gcYqY42xFNQn8#$+vI%-u+6h)XM%#5u9fTCo7&OG-wuG~pg9TkEZbFU zxq2;Ybez{^%K-aWquObuP0jBxxl`csK1zY6hE8L8@xRtR+A^6ABKH9Qop_DABRj_<)3h`nm?*E*%Y(!BhK%x9r=#=~(-y z*7(c@O6a|=�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 + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/fxml/crud_window.fxml b/src/main/resources/fxml/crud_window.fxml new file mode 100644 index 0000000..5afbeca --- /dev/null +++ b/src/main/resources/fxml/crud_window.fxml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + +