From 6ef3f6aadcc41b40d6a2909289a07fecb9c1430b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 9 Jan 2010 09:34:06 +0000 Subject: [PATCH 01/20] Lots of fixes: Alerts now stack up a wait correctly Presentations will run but issue with impress previews Transparent themes now work New image for media previews --- openlp/core/lib/__init__.py | 27 +++++- openlp/core/lib/renderer.py | 93 ++++++++---------- openlp/core/lib/rendermanager.py | 52 +++------- openlp/core/lib/serviceitem.py | 9 +- openlp/core/ui/maindisplay.py | 97 ++++++++++++------- openlp/core/ui/slidecontroller.py | 32 +++--- openlp/plugins/media/lib/mediaitem.py | 9 +- .../presentations/lib/impresscontroller.py | 16 ++- .../presentations/lib/messagelistener.py | 59 ++++++----- resources/images/openlp-2.qrc | 1 + 10 files changed, 210 insertions(+), 185 deletions(-) diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 22df9a926..846ff2053 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -136,6 +136,30 @@ def contextMenuSeparator(base): action.setSeparator(True) return action +def resize_image(image, width, height): + """ + Resize an image to fit on the current screen. + + ``image`` + The image to resize. + """ + if isinstance(image, QtGui.QImage): + preview = QtGui.QImage(image) + else: + preview = QtGui.QImage(image) + + preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio, + QtCore.Qt.SmoothTransformation) + realw = preview.width(); + realh = preview.height() + # and move it to the centre of the preview space + newImage = QtGui.QImage(width, height, QtGui.QImage.Format_ARGB32_Premultiplied) + newImage.fill(QtCore.Qt.black) + painter = QtGui.QPainter(newImage) + painter.drawImage((width - realw) / 2, (height - realh) / 2, preview) + return newImage + + class ThemeLevel(object): Global = 1 Service = 2 @@ -160,6 +184,3 @@ from renderer import Renderer from rendermanager import RenderManager from mediamanageritem import MediaManagerItem from baselistwithdnd import BaseListWithDnD - -#__all__ = [ 'translate', 'get_text_file_string', 'str_to_bool', -# 'contextMenuAction', 'contextMenuSeparator', 'ServiceItem'] \ No newline at end of file diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index c4d7444c4..e3e275193 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -26,6 +26,7 @@ import logging from PyQt4 import QtGui, QtCore +from openlp.core.lib import resize_image class Renderer(object): """ @@ -90,31 +91,9 @@ class Renderer(object): log.debug(u'set bg image %s', filename) self._bg_image_filename = unicode(filename) if self._frame: - self.scale_bg_image() - - def scale_bg_image(self): - """ - Scale the background image to fit the screen. - """ - assert self._frame - preview = QtGui.QImage(self._bg_image_filename) - width = self._frame.width() - height = self._frame.height() - preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio, - QtCore.Qt.SmoothTransformation) - realwidth = preview.width() - realheight = preview.height() - # and move it to the centre of the preview space - self.bg_image = QtGui.QImage(width, height, - QtGui.QImage.Format_ARGB32_Premultiplied) - self.bg_image.fill(QtCore.Qt.black) - painter = QtGui.QPainter() - painter.begin(self.bg_image) - self.background_offsetx = (width - realwidth) / 2 - self.background_offsety = (height - realheight) / 2 - painter.drawImage(self.background_offsetx, - self.background_offsety, preview) - painter.end() + self.bg_image = resize_image(self._bg_image_filename, + self._frame.width(), + self._frame.height()) def set_frame_dest(self, frame_width, frame_height, preview=False): """ @@ -138,7 +117,9 @@ class Renderer(object): self._frameOp = QtGui.QImage(frame_width, frame_height, QtGui.QImage.Format_ARGB32_Premultiplied) if self._bg_image_filename and not self.bg_image: - self.scale_bg_image() + self.bg_image = resize_image(self._bg_image_filename, + self._frame.width(), + self._frame.height()) if self.bg_frame is None: self._generate_background_frame() @@ -276,8 +257,13 @@ class Renderer(object): Results are cached for performance reasons. """ assert(self._theme) - self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), - QtGui.QImage.Format_ARGB32_Premultiplied) + if self._theme.background_mode == u'transparent': + self.bg_frame = \ + QtGui.QPixmap(self._frame.width(), self._frame.height()) + self.bg_frame.fill(QtCore.Qt.transparent) + else: + self.bg_frame = QtGui.QImage(self._frame.width(), self._frame.height(), + QtGui.QImage.Format_ARGB32_Premultiplied) log.debug(u'render background %s start', self._theme.background_type) painter = QtGui.QPainter() painter.begin(self.bg_frame) @@ -422,6 +408,14 @@ class Renderer(object): startx = x starty = y rightextent = None + self.painter = QtGui.QPainter() + self.painter.begin(self._frame) + self.painter.setRenderHint(QtGui.QPainter.Antialiasing); + if self._theme.display_slideTransition: + self.painter2 = QtGui.QPainter() + self.painter2.begin(self._frameOp) + self.painter2.setRenderHint(QtGui.QPainter.Antialiasing); + self.painter2.setOpacity(0.7) # dont allow alignment messing with footers if footer: align = 0 @@ -503,13 +497,14 @@ class Renderer(object): if linenum == 0: self._first_line_right_extent = rightextent # draw a box around the text - debug only + if self._debug: - painter = QtGui.QPainter() - painter.begin(self._frame) - painter.setPen(QtGui.QPen(QtGui.QColor(0,255,0))) - painter.drawRect(startx, starty, rightextent-startx, y-starty) - painter.end() + self.painter.setPen(QtGui.QPen(QtGui.QColor(0,255,0))) + self.painter.drawRect(startx, starty, rightextent-startx, y-starty) brcorner = (rightextent, y) + self.painter.end() + if self._theme.display_slideTransition: + self.painter2.end() return brcorner def _set_theme_font(self): @@ -519,6 +514,7 @@ class Renderer(object): footer_weight = 50 if self._theme.font_footer_weight == u'Bold': footer_weight = 75 + #TODO Add myfont.setPixelSize((screen_height / 100) * font_size) self.footerFont = QtGui.QFont(self._theme.font_footer_name, self._theme.font_footer_proportion, # size footer_weight, # weight @@ -556,45 +552,36 @@ class Renderer(object): Defaults to *None*. The colour to draw with. """ # setup defaults - painter = QtGui.QPainter() - painter.begin(self._frame) - painter.setRenderHint(QtGui.QPainter.Antialiasing); if footer : font = self.footerFont else: font = self.mainFont - painter.setFont(font) + self.painter.setFont(font) if color is None: if footer: - painter.setPen(QtGui.QColor(self._theme.font_footer_color)) + self.painter.setPen(QtGui.QColor(self._theme.font_footer_color)) else: - painter.setPen(QtGui.QColor(self._theme.font_main_color)) + self.painter.setPen(QtGui.QColor(self._theme.font_main_color)) else: - painter.setPen(QtGui.QColor(color)) + self.painter.setPen(QtGui.QColor(color)) x, y = tlcorner metrics = QtGui.QFontMetrics(font) w = metrics.width(line) h = metrics.height() - 2 if draw: - painter.drawText(x, y + metrics.ascent(), line) - painter.end() + self.painter.drawText(x, y + metrics.ascent(), line) if self._theme.display_slideTransition: # Print 2nd image with 70% weight - painter = QtGui.QPainter() - painter.begin(self._frameOp) - painter.setRenderHint(QtGui.QPainter.Antialiasing); - painter.setOpacity(0.7) - painter.setFont(font) + self.painter2.setFont(font) if color is None: if footer: - painter.setPen(QtGui.QColor(self._theme.font_footer_color)) + self.painter2.setPen(QtGui.QColor(self._theme.font_footer_color)) else: - painter.setPen(QtGui.QColor(self._theme.font_main_color)) + self.painter2.setPen(QtGui.QColor(self._theme.font_main_color)) else: - painter.setPen(QtGui.QColor(color)) + self.painter2.setPen(QtGui.QColor(color)) if draw: - painter.drawText(x, y + metrics.ascent(), line) - painter.end() + self.painter2.drawText(x, y + metrics.ascent(), line) return (w, h) def snoop_Image(self, image, image2=None): @@ -609,4 +596,4 @@ class Renderer(object): """ image.save(u'renderer.png', u'png') if image2: - image2.save(u'renderer2.png', u'png') \ No newline at end of file + image2.save(u'renderer2.png', u'png') diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index a0e2ce0af..1bd2b1400 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -28,7 +28,7 @@ import logging from PyQt4 import QtGui, QtCore from renderer import Renderer -from openlp.core.lib import ThemeLevel +from openlp.core.lib import ThemeLevel, resize_image class RenderManager(object): """ @@ -146,13 +146,13 @@ class RenderManager(object): if self.save_bg_frame is None: self.save_bg_frame = self.renderer.bg_frame if self.override_background_changed: - self.renderer.bg_frame = self.resize_image( - self.override_background) + self.renderer.bg_frame = resize_image( + self.override_background, self.width, self.height) self.override_background_changed = False else: if self.override_background_changed: - self.renderer.bg_frame = self.resize_image( - self.override_background) + self.renderer.bg_frame = resize_image( + self.override_background, self.width, self.height) self.override_background_changed = False if self.save_bg_frame: self.renderer.bg_frame = self.save_bg_frame @@ -192,10 +192,13 @@ class RenderManager(object): The theme to generated a preview for. """ log.debug(u'generate preview') + #set the defaukt image size for previews self.calculate_default(QtCore.QSize(1024, 768)) self.renderer.set_theme(themedata) self.build_text_rectangle(themedata) self.renderer.set_frame_dest(self.width, self.height, True) + #Reset the real screen size for subsequent render requests + self.calculate_default(self.screen_list[self.current_display][u'size']) verse = u'Amazing Grace!\n'\ 'How sweet the sound\n'\ 'To save a wretch like me;\n'\ @@ -206,6 +209,7 @@ class RenderManager(object): footer.append(u'Public Domain') footer.append(u'CCLI 123456') formatted = self.renderer.format_slide(verse, False) + #Only Render the first slide page returned return self.renderer.generate_frame_from_lines(formatted[0], footer)[u'main'] def format_slide(self, words): @@ -234,48 +238,18 @@ class RenderManager(object): self.renderer.set_frame_dest(self.width, self.height) return self.renderer.generate_frame_from_lines(main_text, footer_text) - def resize_image(self, image, width=0, height=0): - """ - Resize an image to fit on the current screen. - - ``image`` - The image to resize. - """ - preview = QtGui.QImage(image) - if width == 0: - w = self.width - h = self.height - else: - w = width - h = height - preview = preview.scaled(w, h, QtCore.Qt.KeepAspectRatio, - QtCore.Qt.SmoothTransformation) - realw = preview.width(); - realh = preview.height() - # and move it to the centre of the preview space - newImage = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied) - newImage.fill(QtCore.Qt.black) - painter = QtGui.QPainter(newImage) - painter.drawImage((w - realw) / 2, (h - realh) / 2, preview) - return newImage - def calculate_default(self, screen): """ Calculate the default dimentions of the screen. ``screen`` - The QWidget instance of the screen. + The QSize of the screen. """ log.debug(u'calculate default %s', screen) - #size fixed so reflects the preview size. - if self.current_display == 0: - self.width = 1024 - self.height = 768 - else: - self.width = screen.width() - self.height = screen.height() + self.width = screen.width() + self.height = screen.height() self.screen_ratio = float(self.height) / float(self.width) log.debug(u'calculate default %d, %d, %f', self.width, self.height, self.screen_ratio ) # 90% is start of footer - self.footer_start = int(self.height * 0.90) \ No newline at end of file + self.footer_start = int(self.height * 0.90) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 004973462..19cbe37c2 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -30,7 +30,7 @@ import uuid from PyQt4 import QtGui -from openlp.core.lib import build_icon, Receiver +from openlp.core.lib import build_icon, Receiver, resize_image class ServiceItemType(object): """ @@ -111,7 +111,8 @@ class ServiceItem(object): elif self.service_item_type == ServiceItemType.Image: for slide in self._raw_frames: slide[u'image'] = \ - self.RenderManager.resize_image(slide[u'image']) + resize_image(slide[u'image'], self.RenderManager.width, + self.RenderManager.height) elif self.service_item_type == ServiceItemType.Command: pass else: @@ -119,7 +120,7 @@ class ServiceItem(object): def render_individual(self, row): """ - Takes an array of text and geneates an Image from the + Takes an array of text and generates an Image from the theme. It assumes the text will fit on the screen as it has generated by the render method above. """ @@ -309,4 +310,4 @@ class ServiceItem(object): def request_audit(self): if self.audit: - Receiver.send_message(u'songusage_live', self.audit) \ No newline at end of file + Receiver.send_message(u'songusage_live', self.audit) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 46da99ac2..4ad334f8b 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -90,29 +90,32 @@ class MainDisplay(DisplayWidget): self.parent = parent self.setWindowTitle(u'OpenLP Display') self.screens = screens - self.layout = QtGui.QVBoxLayout(self) - self.layout.setSpacing(0) - self.layout.setMargin(0) - self.layout.setObjectName(u'layout') +# self.layout = QtGui.QVBoxLayout(self) +# self.layout.setSpacing(0) +# self.layout.setMargin(0) +# self.layout.setObjectName(u'layout') self.mediaObject = Phonon.MediaObject(self) self.video = Phonon.VideoWidget() self.video.setVisible(False) self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) Phonon.createPath(self.mediaObject, self.video) Phonon.createPath(self.mediaObject, self.audio) - self.layout.insertWidget(0, self.video) + #self.layout.insertWidget(0, self.video) self.display = QtGui.QLabel(self) self.display.setScaledContents(True) - self.layout.insertWidget(0, self.display) + self.alertDisplay = QtGui.QLabel(self) + self.alertDisplay.setScaledContents(True) + #self.layout.insertWidget(0, self.display) self.primary = True self.displayBlank = False self.blankFrame = None self.frame = None - self.alertactive = False self.timer_id = 0 self.firstTime = True self.mediaLoaded = False self.hasTransition = False + self.alertList = [] + self.mediaBackground = False QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'alert_text'), self.displayAlert) QtCore.QObject.connect(Receiver.get_receiver(), @@ -130,7 +133,6 @@ class MainDisplay(DisplayWidget): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_stop'), self.onMediaStop) - def setup(self, screenNumber): """ Sets up the screen on a particular screen. @@ -138,44 +140,64 @@ class MainDisplay(DisplayWidget): """ log.debug(u'Setup %s for %s ' %(self.screens, screenNumber)) self.setVisible(False) - screen = self.screens[screenNumber] - if screen[u'number'] != screenNumber: + self.screen = self.screens[screenNumber] + if self.screen[u'number'] != screenNumber: # We will most probably never actually hit this bit, but just in # case the index in the list doesn't match the screen number, we # search for it. for scrn in self.screens: if scrn[u'number'] == screenNumber: - screen = scrn + self.screen = scrn break - self.setGeometry(screen[u'size']) + self.setScreenGeometry() #Build a custom splash screen self.InitialFrame = QtGui.QImage( - screen[u'size'].width(), screen[u'size'].height(), + self.screen[u'size'].width(), + self.screen[u'size'].height(), QtGui.QImage.Format_ARGB32_Premultiplied) splash_image = QtGui.QImage(u':/graphics/openlp-splash-screen.png') painter_image = QtGui.QPainter() painter_image.begin(self.InitialFrame) painter_image.fillRect(self.InitialFrame.rect(), QtCore.Qt.white) painter_image.drawImage( - (screen[u'size'].width() - splash_image.width()) / 2, - (screen[u'size'].height() - splash_image.height()) / 2, + (self.screen[u'size'].width() - splash_image.width()) / 2, + (self.screen[u'size'].height() - splash_image.height()) / 2, splash_image) self.frameView(self.InitialFrame) #Build a Black screen painter = QtGui.QPainter() self.blankFrame = QtGui.QImage( - screen[u'size'].width(), screen[u'size'].height(), + self.screen[u'size'].width(), + self.screen[u'size'].height(), QtGui.QImage.Format_ARGB32_Premultiplied) painter.begin(self.blankFrame) painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black) + #buid a blank transparent image + self.transparent = QtGui.QPixmap(self.screen[u'size'].width(), + self.screen[u'size'].height()) + self.transparent.fill(QtCore.Qt.transparent) # To display or not to display? - if not screen[u'primary']: + if not self.screen[u'primary']: self.showFullScreen() self.primary = False else: self.setVisible(False) self.primary = True + def setScreenGeometry(self): + """ + Define and set up the display sizes. + The alert displays are set to 10% of the screen as the video display + is unable to handle transparent pixmaps. This is a problem with QT. + """ + self.setGeometry(self.screen[u'size']) + self.alertScreenPosition = self.screen[u'size'].height() * 0.9 + self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition + self.alertDisplay.setGeometry( + QtCore.QRect(0, self.alertScreenPosition, + self.screen[u'size'].width(),self.alertHeight)) + self.video.setGeometry(self.screen[u'size']) + def resetDisplay(self): if self.primary: self.setVisible(False) @@ -235,17 +257,27 @@ class MainDisplay(DisplayWidget): display text """ log.debug(u'display alert called %s' % text) + self.alertList.append(text) + if self.timer_id != 0: + return + self.generateAlert() + + def generateAlert(self): + log.debug(u'Generate Alert called') + if len(self.alertList) == 0: + return + text = self.alertList.pop(0) alertTab = self.parent.settingsForm.AlertsTab - if isinstance(self.frame, QtGui.QImage): - alertframe = QtGui.QPixmap.fromImage(self.frame) - else: - alertframe = QtGui.QPixmap.fromImage(self.frame[u'main']) + alertframe = \ + QtGui.QPixmap(self.screen[u'size'].width(), self.alertHeight) + alertframe.fill(QtCore.Qt.transparent) painter = QtGui.QPainter(alertframe) - top = alertframe.rect().height() * 0.9 + painter.fillRect(alertframe.rect(), QtCore.Qt.transparent) + painter.setRenderHint(QtGui.QPainter.Antialiasing) painter.fillRect( QtCore.QRect( - 0, top, alertframe.rect().width(), - alertframe.rect().height() - top), + 0, 0, alertframe.rect().width(), + alertframe.rect().height()), QtGui.QColor(alertTab.bg_color)) font = QtGui.QFont() font.setFamily(alertTab.font_face) @@ -253,24 +285,23 @@ class MainDisplay(DisplayWidget): font.setPointSize(40) painter.setFont(font) painter.setPen(QtGui.QColor(alertTab.font_color)) - x, y = (0, top) + x, y = (0, 0) metrics = QtGui.QFontMetrics(font) painter.drawText( x, y + metrics.height() - metrics.descent() - 1, text) painter.end() - self.display.setPixmap(alertframe) + self.alertDisplay.setPixmap(alertframe) + self.alertDisplay.setVisible(True) # check to see if we have a timer running if self.timer_id == 0: self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) def timerEvent(self, event): if event.timerId() == self.timer_id: - if isinstance(self.frame, QtGui.QImage): - self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame)) - else: - self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame[u'main'])) - self.killTimer(self.timer_id) - self.timer_id = 0 + self.alertDisplay.setPixmap(self.transparent) + self.killTimer(self.timer_id) + self.timer_id = 0 + self.generateAlert() def onMediaQueue(self, message): log.debug(u'Queue new media message %s' % message) @@ -312,4 +343,4 @@ class MainDisplay(DisplayWidget): self.mediaObject.clearQueue() self.mediaLoaded = False self.video.setVisible(False) - self.display.show() \ No newline at end of file + self.display.show() diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 59dd857ac..c4d52ff57 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -30,7 +30,8 @@ import os from PyQt4 import QtCore, QtGui from PyQt4.phonon import Phonon -from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, PluginConfig +from openlp.core.lib import OpenLPToolbar, Receiver, str_to_bool, \ +PluginConfig, resize_image class SlideList(QtGui.QTableWidget): """ @@ -235,6 +236,9 @@ class SlideController(QtGui.QWidget): self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) Phonon.createPath(self.mediaObject, self.video) Phonon.createPath(self.mediaObject, self.audio) + if not self.isLive: + self.video.setGeometry(QtCore.QRect(0, 0, 300, 225)) + self.video.setVisible(False) self.SlideLayout.insertWidget(0, self.video) # Actual preview screen self.SlidePreview = QtGui.QLabel(self) @@ -246,7 +250,8 @@ class SlideController(QtGui.QWidget): self.SlidePreview.sizePolicy().hasHeightForWidth()) self.SlidePreview.setSizePolicy(sizePolicy) self.SlidePreview.setFixedSize( - QtCore.QSize(self.settingsmanager.slidecontroller_image,self.settingsmanager.slidecontroller_image / 1.3 )) + QtCore.QSize(self.settingsmanager.slidecontroller_image, + self.settingsmanager.slidecontroller_image / 1.3 )) self.SlidePreview.setFrameShape(QtGui.QFrame.Box) self.SlidePreview.setFrameShadow(QtGui.QFrame.Plain) self.SlidePreview.setLineWidth(1) @@ -257,8 +262,6 @@ class SlideController(QtGui.QWidget): # Signals QtCore.QObject.connect(self.PreviewListWidget, QtCore.SIGNAL(u'clicked(QModelIndex)'), self.onSlideSelected) - QtCore.QObject.connect(self.PreviewListWidget, - QtCore.SIGNAL(u'activated(QModelIndex)'), self.onSlideSelected) if isLive: QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'update_spin_delay'), self.receiveSpinDelay) @@ -441,7 +444,9 @@ class SlideController(QtGui.QWidget): else: label = QtGui.QLabel() label.setMargin(4) - pixmap = self.parent.RenderManager.resize_image(frame[u'image']) + pixmap = resize_image(frame[u'image'], + self.parent.RenderManager.width, + self.parent.RenderManager.height) label.setScaledContents(True) label.setPixmap(QtGui.QPixmap.fromImage(pixmap)) self.PreviewListWidget.setCellWidget(framenumber, 0, label) @@ -487,11 +492,12 @@ class SlideController(QtGui.QWidget): """ Blank the screen. """ - if not self.serviceItem and self.serviceItem.is_command(): - if blanked: - Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower()) - else: - Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower()) + if self.serviceItem is not None: + if self.serviceItem.is_command(): + if blanked: + Receiver.send_message(u'%s_blank'% self.serviceItem.name.lower()) + else: + Receiver.send_message(u'%s_unblank'% self.serviceItem.name.lower()) else: self.parent.mainDisplay.blankDisplay(blanked) @@ -635,7 +641,7 @@ class SlideController(QtGui.QWidget): if self.isLive: Receiver.send_message(u'%s_start' % item.name.lower(), \ [item.title, item.service_item_path, - item.get_frame_title(), slideno, self.isLive]) + item.get_frame_title(), self.isLive]) else: self.mediaObject.stop() self.mediaObject.clearQueue() @@ -663,5 +669,5 @@ class SlideController(QtGui.QWidget): else: self.mediaObject.stop() self.video.hide() - self.SlidePreview.clear() - self.SlidePreview.show() \ No newline at end of file + self.SlidePreview.clear() + self.SlidePreview.show() diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index f9b9f7929..d946fb819 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -61,8 +61,9 @@ class MediaMediaItem(MediaManagerItem): def retranslateUi(self): self.OnNewPrompt = self.trUtf8('Select Media') - self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg' - '*.mp4);;Audio (*.ogg *.mp3 *.wma);;All files (*)') + self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg *.wmv' + '*.mov *.mp4 *.flv);;Audio (*.ogg *.mp3 *.wma *.wav *.flac)' + ';;All files (*)') def requiredIcons(self): MediaManagerItem.requiredIcons(self) @@ -84,7 +85,7 @@ class MediaMediaItem(MediaManagerItem): for item in items: bitem = self.ListView.item(item.row()) filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) - frame = u':/media/media_video.png' + frame = u':/media/image_clapperboard.png' (path, name) = os.path.split(filename) service_item.add_from_command(path, name, frame) return True @@ -110,4 +111,4 @@ class MediaMediaItem(MediaManagerItem): img = self.video_get_preview() item_name.setIcon(build_icon(img)) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(file)) - self.ListView.addItem(item_name) \ No newline at end of file + self.ListView.addItem(item_name) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index cd8db7e08..9101220e0 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -169,8 +169,12 @@ class ImpressController(PresentationController): for idx in range(pages.getCount()): page = pages.getByIndex(idx) doc.getCurrentController().setCurrentPage(page) - doc.storeToURL(thumbdir + u'/' + self.thumbnailprefix + - unicode(idx+1) + u'.png', props) + path = u'%s/%s%s.png'% (thumbdir, self.thumbnailprefix, + unicode(idx+1)) + try: + doc.storeToURL(path , props) + except: + log.exception(u'%s\nUnable to store preview' % path) def create_property(self, name, value): if os.name == u'nt': @@ -230,7 +234,11 @@ class ImpressController(PresentationController): if self.presentation: self.presentation.end() self.presentation = None - self.document.dispose() + try: + self.document.dispose() + except: + #We tried! + pass self.document = None def is_loaded(self): @@ -305,4 +313,4 @@ class ImpressController(PresentationController): if os.path.isfile(path): return path else: - return None \ No newline at end of file + return None diff --git a/openlp/plugins/presentations/lib/messagelistener.py b/openlp/plugins/presentations/lib/messagelistener.py index 8094b804e..0b2fd6003 100644 --- a/openlp/plugins/presentations/lib/messagelistener.py +++ b/openlp/plugins/presentations/lib/messagelistener.py @@ -47,7 +47,7 @@ class Controller(object): log.debug(u'Live = %s, addHandler %s' % (self.isLive, file)) self.controller = controller if self.controller.is_loaded(): - self.shutdown(None) + self.shutdown() self.controller.load_presentation(file) if self.isLive: self.controller.start_presentation() @@ -73,55 +73,51 @@ class Controller(object): self.controller.goto_slide(int(slide) + 1) self.controller.poll_slidenumber(live) - def first(self, message): + def first(self): """ Based on the handler passed at startup triggers the first slide """ log.debug(u'Live = %s, first' % self.isLive) - print "first ", message if not self.isLive: return self.activate() self.controller.start_presentation() self.controller.poll_slidenumber(self.isLive) - def last(self, message): + def last(self): """ Based on the handler passed at startup triggers the first slide """ log.debug(u'Live = %s, last' % self.isLive) - print "last ", message if not self.isLive: return self.activate() self.controller.goto_slide(self.controller.get_slide_count()) self.controller.poll_slidenumber(self.isLive) - def next(self, message): + def next(self): """ Based on the handler passed at startup triggers the next slide event """ log.debug(u'Live = %s, next' % self.isLive) - print "next ", message if not self.isLive: return self.activate() self.controller.next_step() self.controller.poll_slidenumber(self.isLive) - def previous(self, message): + def previous(self): """ Based on the handler passed at startup triggers the previous slide event """ log.debug(u'Live = %s, previous' % self.isLive) if not self.isLive: return - print "previous ", message self.activate() self.controller.previous_step() self.controller.poll_slidenumber(self.isLive) - def shutdown(self, message): + def shutdown(self): """ Based on the handler passed at startup triggers slide show to shut down """ @@ -159,7 +155,6 @@ class MessageListener(object): self.controllers = controllers self.previewHandler = Controller(False) self.liveHandler = Controller(True) - self.isLive = None # messages are sent from core.ui.slidecontroller QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'presentations_start'), self.startup) @@ -202,36 +197,36 @@ class MessageListener(object): else: self.previewHandler.slide(slide, live) - def first(self, message): - if self.isLive: - self.liveHandler.first(message) + def first(self, isLive): + if isLive: + self.liveHandler.first() else: - self.previewHandler.first(message) + self.previewHandler.first() - def last(self, message): - if self.isLive: - self.liveHandler.last(message) + def last(self, isLive): + if isLive: + self.liveHandler.last() else: - self.previewHandler.last(message) + self.previewHandler.last() - def next(self, message): - if self.isLive: - self.liveHandler.next(message) + def next(self, isLive): + if isLive: + self.liveHandler.next() else: - self.previewHandler.next(message) + self.previewHandler.next() - def previous(self, message): - if self.isLive: - self.liveHandler.previous(message) + def previous(self, isLive): + if isLive: + self.liveHandler.previous() else: - self.previewHandler.previous(message) + self.previewHandler.previous() - def shutdown(self, message): - if self.isLive: - self.liveHandler.shutdown(message) + def shutdown(self, isLive): + if isLive: + self.liveHandler.shutdown() Receiver.send_message(u'live_slide_show') else: - self.previewHandler.shutdown(message) + self.previewHandler.shutdown() def blank(self): if self.isLive: @@ -268,4 +263,4 @@ class MessageListener(object): return message[0], file, message[4] def timeout(self): - self.controller.poll_slidenumber(self.is_live) \ No newline at end of file + self.controller.poll_slidenumber(self.is_live) diff --git a/resources/images/openlp-2.qrc b/resources/images/openlp-2.qrc index 8fa38c42b..4bea9e51b 100644 --- a/resources/images/openlp-2.qrc +++ b/resources/images/openlp-2.qrc @@ -108,6 +108,7 @@ media_video.png media_time.png media_stop.png + image_clapperboard.png messagebox_critical.png From ee8a92b77fb459cc17d9cb906b98b4ba08ed35b8 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 10 Jan 2010 11:49:04 +0000 Subject: [PATCH 02/20] fix screen lines calcs so they are correct. Prints added for rendering size diagnostics. --- openlp/core/lib/renderer.py | 20 +++++++++++++------- openlp/core/lib/rendermanager.py | 14 +++++++------- openlp/core/lib/serviceitem.py | 6 ++++-- openlp/core/ui/amendthemeform.py | 10 ++++++++-- openlp/core/ui/maindisplay.py | 7 +++++++ openlp/core/ui/mainwindow.py | 3 ++- openlp/core/ui/slidecontroller.py | 1 + 7 files changed, 42 insertions(+), 19 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index e3e275193..30f5c2dee 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -42,7 +42,7 @@ class Renderer(object): Initialise the renderer. """ self._rect = None - self._debug = 0 + self._debug = True self._right_margin = 64 # the amount of right indent self._display_shadow_size_footer = 0 self._display_outline_size_footer = 0 @@ -148,17 +148,22 @@ class Renderer(object): def pre_render_text(self, text): metrics = QtGui.QFontMetrics(self.mainFont) - #take the width work out approx how many characters and add 50% + #work out line width line_width = self._rect.width() - self._right_margin #number of lines on a page - adjust for rounding up. - page_length = int(self._rect.height() / metrics.height() - 2 ) - 1 + line_height = metrics.height() + if self._theme.display_shadow: + line_height += int(self._theme.display_shadow_size) + if self._theme.display_outline: + # pixels top/bottom + line_height += 2 * int(self._theme.display_outline_size) + page_length = int(self._rect.height() / line_height ) #Average number of characters in line ave_line_width = line_width / metrics.averageCharWidth() #Maximum size of a character max_char_width = metrics.maxWidth() - #Min size of a character - min_char_width = metrics.width(u'i') - char_per_line = line_width / min_char_width + #Max characters pre line based on min size of a character + char_per_line = line_width / metrics.width(u'i') log.debug(u'Page Length area height %s , metrics %s , lines %s' % (int(self._rect.height()), metrics.height(), page_length )) split_pages = [] @@ -221,6 +226,7 @@ class Renderer(object): """ self._rect = rect_main self._rect_footer = rect_footer + print "render = ", self._rect def generate_frame_from_lines(self, lines, footer_lines=None): """ @@ -567,7 +573,7 @@ class Renderer(object): x, y = tlcorner metrics = QtGui.QFontMetrics(font) w = metrics.width(line) - h = metrics.height() - 2 + h = metrics.height() if draw: self.painter.drawText(x, y + metrics.ascent(), line) if self._theme.display_slideTransition: diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index 1bd2b1400..cbbc6be26 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -160,8 +160,8 @@ class RenderManager(object): def build_text_rectangle(self, theme): """ - Builds a text block using the settings in ``theme``. - One is needed per slide + Builds a text block using the settings in ``theme`` + and the size of the display screen.height. ``theme`` The theme to build a text block for. @@ -170,14 +170,14 @@ class RenderManager(object): main_rect = None footer_rect = None if not theme.font_main_override: - main_rect = QtCore.QRect(10, 0, self.width - 1, - self.footer_start - 20) + main_rect = QtCore.QRect(10, 0, + self.width - 1, self.footer_start) else: main_rect = QtCore.QRect(theme.font_main_x, theme.font_main_y, theme.font_main_width - 1, theme.font_main_height - 1) if not theme.font_footer_override: - footer_rect = QtCore.QRect(10, self.footer_start, self.width - 1, - self.height-self.footer_start) + footer_rect = QtCore.QRect(10, self.footer_start, + self.width - 1, self.height - self.footer_start) else: footer_rect = QtCore.QRect(theme.font_footer_x, theme.font_footer_y, theme.font_footer_width - 1, @@ -192,7 +192,7 @@ class RenderManager(object): The theme to generated a preview for. """ log.debug(u'generate preview') - #set the defaukt image size for previews + #set the default image size for previews self.calculate_default(QtCore.QSize(1024, 768)) self.renderer.set_theme(themedata) self.build_text_rectangle(themedata) diff --git a/openlp/core/lib/serviceitem.py b/openlp/core/lib/serviceitem.py index 19cbe37c2..603d7cadb 100644 --- a/openlp/core/lib/serviceitem.py +++ b/openlp/core/lib/serviceitem.py @@ -102,11 +102,13 @@ class ServiceItem(object): formated = self.RenderManager.format_slide(slide[u'raw_slide']) for format in formated: lines = u'' + title = u'' for line in format: + if title == u'': + title = line lines += line + u'\n' - title = lines.split(u'\n')[0] self._display_frames.append({u'title': title, \ - u'text': lines, u'verseTag': slide[u'verseTag'] }) + u'text': lines.rstrip(), u'verseTag': slide[u'verseTag'] }) log.log(15, u'Formatting took %4s' % (time.time() - before)) elif self.service_item_type == ServiceItemType.Image: for slide in self._raw_frames: diff --git a/openlp/core/ui/amendthemeform.py b/openlp/core/ui/amendthemeform.py index 24a22a7cf..97eecd1e8 100644 --- a/openlp/core/ui/amendthemeform.py +++ b/openlp/core/ui/amendthemeform.py @@ -694,8 +694,14 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): if self.allowPreview: #calculate main number of rows metrics = self._getThemeMetrics() + line_height = metrics.height() + if self.theme.display_shadow: + line_height += int(self.theme.display_shadow_size) + if self.theme.display_outline: + # pixels top/bottom + line_height += 2 * int(self.theme.display_outline_size) page_length = \ - (self.FontMainHeightSpinBox.value() / metrics.height() - 2) - 1 + ((self.FontMainHeightSpinBox.value()) / line_height ) log.debug(u'Page Length area height %s, metrics %s, lines %s' % (self.FontMainHeightSpinBox.value(), metrics.height(), page_length)) @@ -719,4 +725,4 @@ class AmendThemeForm(QtGui.QDialog, Ui_AmendThemeDialog): if self.theme.font_main_width < metrics.maxWidth() * 2 + 64: self.theme.font_main_width = metrics.maxWidth() * 2 + 64 self.FontMainWidthSpinBox.setValue(self.theme.font_main_width) - return metrics \ No newline at end of file + return metrics diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 4ad334f8b..019c614d7 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -139,6 +139,7 @@ class MainDisplay(DisplayWidget): @param (integer) screen This is the screen number. """ log.debug(u'Setup %s for %s ' %(self.screens, screenNumber)) + print "all the screen ", self.screens self.setVisible(False) self.screen = self.screens[screenNumber] if self.screen[u'number'] != screenNumber: @@ -190,7 +191,12 @@ class MainDisplay(DisplayWidget): The alert displays are set to 10% of the screen as the video display is unable to handle transparent pixmaps. This is a problem with QT. """ + print "--------- Set screen geom ------------" + print "display ", self.screen[u'size'] + print "main geom before ", self.geometry() self.setGeometry(self.screen[u'size']) + print "main geom after ", self.geometry() + print "display geom", self.display.geometry() self.alertScreenPosition = self.screen[u'size'].height() * 0.9 self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition self.alertDisplay.setGeometry( @@ -221,6 +227,7 @@ class MainDisplay(DisplayWidget): elif not self.displayBlank: if transition: if self.hasTransition: + print len(self.frame[u'trans']) if self.frame[u'trans'] is not None: self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame[u'trans'])) self.repaint() diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 854811484..a508189de 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -614,6 +614,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.settingsForm.exec_() updated_display = self.getMonitorNumber() if updated_display != self.RenderManager.current_display: + print "main display screen changed to ", updated_display self.RenderManager.update_display(updated_display) self.mainDisplay.setup(updated_display) self.activateWindow() @@ -704,4 +705,4 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): def togglePreviewPanel(self): previewBool = self.PreviewController.Panel.isVisible() self.PreviewController.Panel.setVisible(not previewBool) - self.settingsmanager.togglePreviewPanel(not previewBool) \ No newline at end of file + self.settingsmanager.togglePreviewPanel(not previewBool) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index c4d52ff57..34c66eacd 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -441,6 +441,7 @@ class SlideController(QtGui.QWidget): self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag), self.onSongBarHandler) item.setText(frame[u'text']) + #print {u'x':frame[u'text']} else: label = QtGui.QLabel() label.setMargin(4) From 85bada91ba69e8addf24476c8bbf6a97774b9953 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 10 Jan 2010 19:03:52 +0000 Subject: [PATCH 03/20] Move towards sorting out renderer text sizes --- openlp/core/lib/renderer.py | 2 +- openlp/core/lib/rendermanager.py | 6 ++- openlp/core/ui/maindisplay.py | 73 +++++++++++++++----------------- 3 files changed, 39 insertions(+), 42 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index 30f5c2dee..f6da3f6b1 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -226,7 +226,6 @@ class Renderer(object): """ self._rect = rect_main self._rect_footer = rect_footer - print "render = ", self._rect def generate_frame_from_lines(self, lines, footer_lines=None): """ @@ -245,6 +244,7 @@ class Renderer(object): bbox1 = self._render_lines_unaligned(footer_lines, True) # reset the frame. first time do not worry about what you paint on. self._frame = QtGui.QImage(self.bg_frame) + print "generate ", self._frame.size() self._frameOp = QtGui.QImage(self.bg_frame) x, y = self._correctAlignment(self._rect, bbox) bbox = self._render_lines_unaligned(lines, False, (x, y), True) diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index cbbc6be26..c4114580b 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -83,6 +83,7 @@ class RenderManager(object): self.current_display = screen_number self.calculate_default( self.screen_list[self.current_display][u'size']) + self.renderer.bg_frame = None def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global): """ @@ -141,7 +142,7 @@ class RenderManager(object): self.screen_list[self.current_display][u'size']) self.renderer.set_theme(self.themedata) self.build_text_rectangle(self.themedata) - #Replace the backgrount image from renderer with one from image + #Replace the background image from renderer with one from image if self.override_background: if self.save_bg_frame is None: self.save_bg_frame = self.renderer.bg_frame @@ -182,6 +183,7 @@ class RenderManager(object): footer_rect = QtCore.QRect(theme.font_footer_x, theme.font_footer_y, theme.font_footer_width - 1, theme.font_footer_height - 1) + print "build_text_rectangle", main_rect self.renderer.set_text_rectangle(main_rect, footer_rect) def generate_preview(self, themedata): @@ -235,6 +237,7 @@ class RenderManager(object): """ log.debug(u'generate slide') self.build_text_rectangle(self.themedata) + print "set_frame_dest", self.width, self.height self.renderer.set_frame_dest(self.width, self.height) return self.renderer.generate_frame_from_lines(main_text, footer_text) @@ -253,3 +256,4 @@ class RenderManager(object): self.width, self.height, self.screen_ratio ) # 90% is start of footer self.footer_start = int(self.height * 0.90) + print "calculate_default ", self.width, self.height, self.footer_start diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 019c614d7..3d545c2ec 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -90,22 +90,16 @@ class MainDisplay(DisplayWidget): self.parent = parent self.setWindowTitle(u'OpenLP Display') self.screens = screens -# self.layout = QtGui.QVBoxLayout(self) -# self.layout.setSpacing(0) -# self.layout.setMargin(0) -# self.layout.setObjectName(u'layout') self.mediaObject = Phonon.MediaObject(self) self.video = Phonon.VideoWidget() self.video.setVisible(False) self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) Phonon.createPath(self.mediaObject, self.video) Phonon.createPath(self.mediaObject, self.audio) - #self.layout.insertWidget(0, self.video) self.display = QtGui.QLabel(self) self.display.setScaledContents(True) self.alertDisplay = QtGui.QLabel(self) self.alertDisplay.setScaledContents(True) - #self.layout.insertWidget(0, self.display) self.primary = True self.displayBlank = False self.blankFrame = None @@ -150,7 +144,21 @@ class MainDisplay(DisplayWidget): if scrn[u'number'] == screenNumber: self.screen = scrn break - self.setScreenGeometry() + #Sort out screen locations and sizes + print "--------- Set screen geom ------------" + print "display ", self.screen[u'size'] + self.setGeometry(self.screen[u'size']) + print "main geom", self.geometry() + print "display geom 1", self.display.geometry() + self.alertScreenPosition = self.screen[u'size'].height() * 0.9 + self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition + self.alertDisplay.setGeometry( + QtCore.QRect(0, self.alertScreenPosition, + self.screen[u'size'].width(),self.alertHeight)) + self.video.setGeometry(self.screen[u'size']) + self.display.resize(self.screen[u'size'].width(), + self.screen[u'size'].height()) + print "display geom 2", self.display.geometry() #Build a custom splash screen self.InitialFrame = QtGui.QImage( self.screen[u'size'].width(), @@ -172,7 +180,7 @@ class MainDisplay(DisplayWidget): self.screen[u'size'].height(), QtGui.QImage.Format_ARGB32_Premultiplied) painter.begin(self.blankFrame) - painter.fillRect(self.blankFrame.rect(), QtCore.Qt.black) + painter.fillRect(self.blankFrame.rect(), QtCore.Qt.red) #buid a blank transparent image self.transparent = QtGui.QPixmap(self.screen[u'size'].width(), self.screen[u'size'].height()) @@ -185,25 +193,6 @@ class MainDisplay(DisplayWidget): self.setVisible(False) self.primary = True - def setScreenGeometry(self): - """ - Define and set up the display sizes. - The alert displays are set to 10% of the screen as the video display - is unable to handle transparent pixmaps. This is a problem with QT. - """ - print "--------- Set screen geom ------------" - print "display ", self.screen[u'size'] - print "main geom before ", self.geometry() - self.setGeometry(self.screen[u'size']) - print "main geom after ", self.geometry() - print "display geom", self.display.geometry() - self.alertScreenPosition = self.screen[u'size'].height() * 0.9 - self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition - self.alertDisplay.setGeometry( - QtCore.QRect(0, self.alertScreenPosition, - self.screen[u'size'].width(),self.alertHeight)) - self.video.setGeometry(self.screen[u'size']) - def resetDisplay(self): if self.primary: self.setVisible(False) @@ -222,27 +211,31 @@ class MainDisplay(DisplayWidget): ``frame`` Image frame to be rendered """ - if self.timer_id != 0 : - self.displayAlert() - elif not self.displayBlank: +# if self.timer_id != 0 : +# self.displayAlert() + print "render display start ", self.display.geometry() + if not self.displayBlank: if transition: - if self.hasTransition: - print len(self.frame[u'trans']) - if self.frame[u'trans'] is not None: - self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame[u'trans'])) - self.repaint() - if frame[u'trans'] is not None: - self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans'])) - self.repaint() - self.hasTransition = True + if self.frame is not None: + print "render frame 1 ", self.frame.size() + self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame)) + self.repaint() + self.frame = None + if frame[u'trans'] is not None: + print "render frame 2 ", frame[u'trans'].size() + self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans'])) + self.repaint() + self.frame = frame[u'trans'] + print "render frame 3 ", frame[u'main'].size() self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) self.repaint() else: + print "render frame 3 ", frame.size() self.display.setPixmap(QtGui.QPixmap.fromImage(frame)) if not self.isVisible(): self.setVisible(True) self.showFullScreen() - self.frame = frame + print "render display end ", self.display.geometry() def blankDisplay(self, blanked=True): if blanked: From 9dc38cf289edc6217079cf8e350e08d68c72203b Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 16 Jan 2010 07:22:50 +0000 Subject: [PATCH 04/20] Refactor the screen handling code to try and set the screen sizes correctly. --- openlp.pyw | 8 +- openlp/core/lib/rendermanager.py | 30 +++---- openlp/core/lib/settingsmanager.py | 4 +- openlp/core/ui/__init__.py | 4 +- openlp/core/ui/generaltab.py | 4 +- openlp/core/ui/maindisplay.py | 10 +-- openlp/core/ui/mainwindow.py | 15 ++-- openlp/core/ui/screen.py | 74 ++++++++++++++++++ openlp/core/ui/slidecontroller.py | 2 +- .../presentations/lib/impresscontroller.py | 2 +- resources/images/image_clapperboard.png | Bin 0 -> 191834 bytes 11 files changed, 104 insertions(+), 49 deletions(-) create mode 100644 openlp/core/ui/screen.py create mode 100644 resources/images/image_clapperboard.png diff --git a/openlp.pyw b/openlp.pyw index 8b847c0ec..2060f09e1 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -34,7 +34,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, str_to_bool from openlp.core.resources import qInitResources -from openlp.core.ui import MainWindow, SplashScreen +from openlp.core.ui import MainWindow, SplashScreen, Screen from openlp.core.utils import ConfigHelper log = logging.getLogger() @@ -117,10 +117,10 @@ class OpenLP(QtGui.QApplication): self.splash.show() # make sure Qt really display the splash screen self.processEvents() - screens = [] + screens = Screen() # Decide how many screens we have and their size for screen in xrange(0, self.desktop().numScreens()): - screens.append({u'number': screen, + screens.add_screen({u'number': screen, u'size': self.desktop().availableGeometry(screen), u'primary': (self.desktop().primaryScreen() == screen)}) log.info(u'Screen %d found with resolution %s', @@ -182,4 +182,4 @@ if __name__ == u'__main__': """ Instantiate and run the application. """ - main() \ No newline at end of file + main() diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index c4114580b..d8621b345 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -39,8 +39,8 @@ class RenderManager(object): ``theme_manager`` The ThemeManager instance, used to get the current theme details. - ``screen_list`` - The list of screens available. + ``screens`` + Contains information about the Screens. ``screen_number`` Defaults to *0*. The index of the output/display screen. @@ -49,20 +49,16 @@ class RenderManager(object): log = logging.getLogger(u'RenderManager') log.info(u'RenderManager Loaded') - def __init__(self, theme_manager, screen_list, screen_number=0): + def __init__(self, theme_manager, screens, screen_number=0): """ Initialise the render manager. """ log.debug(u'Initilisation started') - self.screen_list = screen_list + self.screens = screens self.theme_manager = theme_manager - self.displays = len(screen_list) - if (screen_number + 1) > len(screen_list): - self.current_display = 0 - else: - self.current_display = screen_number self.renderer = Renderer() - self.calculate_default(self.screen_list[self.current_display][u'size']) + self.screens.set_current_display(screen_number) + self.calculate_default(self.screens.current[u'size']) self.theme = u'' self.service_theme = u'' self.theme_level = u'' @@ -79,11 +75,8 @@ class RenderManager(object): The updated index of the output/display screen. """ log.debug(u'Update Display') - if self.current_display != screen_number: - self.current_display = screen_number - self.calculate_default( - self.screen_list[self.current_display][u'size']) - self.renderer.bg_frame = None + self.calculate_default(self.screens.current[u'size']) + self.renderer.bg_frame = None def set_global_theme(self, global_theme, theme_level=ThemeLevel.Global): """ @@ -138,8 +131,7 @@ class RenderManager(object): if self.theme != self.renderer.theme_name or self.themedata is None: log.debug(u'theme is now %s', self.theme) self.themedata = self.theme_manager.getThemeData(self.theme) - self.calculate_default( - self.screen_list[self.current_display][u'size']) + self.calculate_default(self.screens.current[u'size']) self.renderer.set_theme(self.themedata) self.build_text_rectangle(self.themedata) #Replace the background image from renderer with one from image @@ -195,12 +187,12 @@ class RenderManager(object): """ log.debug(u'generate preview') #set the default image size for previews - self.calculate_default(QtCore.QSize(1024, 768)) + self.calculate_default(self.screens.preview[u'size']) self.renderer.set_theme(themedata) self.build_text_rectangle(themedata) self.renderer.set_frame_dest(self.width, self.height, True) #Reset the real screen size for subsequent render requests - self.calculate_default(self.screen_list[self.current_display][u'size']) + self.calculate_default(self.screens.current[u'size']) verse = u'Amazing Grace!\n'\ 'How sweet the sound\n'\ 'To save a wretch like me;\n'\ diff --git a/openlp/core/lib/settingsmanager.py b/openlp/core/lib/settingsmanager.py index 580ec9b31..be5c14af1 100644 --- a/openlp/core/lib/settingsmanager.py +++ b/openlp/core/lib/settingsmanager.py @@ -33,7 +33,7 @@ class SettingsManager(object): individual components. """ def __init__(self, screen): - self.screen = screen[0] + self.screen = screen.current self.width = self.screen[u'size'].width() self.height = self.screen[u'size'].height() self.mainwindow_height = self.height * 0.8 @@ -72,4 +72,4 @@ class SettingsManager(object): u'media manager', isVisible) def togglePreviewPanel(self, isVisible): - ConfigHelper.set_config(u'user interface', u'preview panel', isVisible) \ No newline at end of file + ConfigHelper.set_config(u'user interface', u'preview panel', isVisible) diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index 6b187f5fc..a2252bc41 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -23,7 +23,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -#from slidecontroller import MasterToolbar +from screen import Screen from maindisplay import MainDisplay from amendthemeform import AmendThemeForm from slidecontroller import SlideController @@ -42,4 +42,4 @@ from mainwindow import MainWindow __all__ = ['SplashScreen', 'AboutForm', 'SettingsForm', 'MainWindow', 'MainDisplay', 'SlideController', 'ServiceManager', 'ThemeManager', - 'AmendThemeForm', 'MediaDockManager', 'ThemeLevel'] \ No newline at end of file + 'AmendThemeForm', 'MediaDockManager', 'ThemeLevel'] diff --git a/openlp/core/ui/generaltab.py b/openlp/core/ui/generaltab.py index b5abc2a2e..d821c0f45 100644 --- a/openlp/core/ui/generaltab.py +++ b/openlp/core/ui/generaltab.py @@ -183,7 +183,7 @@ class GeneralTab(SettingsTab): self.Password = self.PasswordEdit.displayText() def load(self): - for screen in self.screen_list: + for screen in self.screen_list.screen_list: screen_name = u'%s %d' % (self.trUtf8('Screen'), screen[u'number'] + 1) if screen[u'primary']: screen_name = u'%s (%s)' % (screen_name, self.trUtf8('primary')) @@ -215,4 +215,4 @@ class GeneralTab(SettingsTab): self.config.set_config(u'save prompt', self.PromptSaveService) self.config.set_config(u'ccli number', self.CCLINumber) self.config.set_config(u'songselect username', self.Username) - self.config.set_config(u'songselect password', self.Password) \ No newline at end of file + self.config.set_config(u'songselect password', self.Password) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 3d545c2ec..505e728da 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -135,15 +135,7 @@ class MainDisplay(DisplayWidget): log.debug(u'Setup %s for %s ' %(self.screens, screenNumber)) print "all the screen ", self.screens self.setVisible(False) - self.screen = self.screens[screenNumber] - if self.screen[u'number'] != screenNumber: - # We will most probably never actually hit this bit, but just in - # case the index in the list doesn't match the screen number, we - # search for it. - for scrn in self.screens: - if scrn[u'number'] == screenNumber: - self.screen = scrn - break + self.screen = self.screens.current #Sort out screen locations and sizes print "--------- Set screen geom ------------" print "display ", self.screen[u'size'] diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index a508189de..cbd2e0ad7 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -425,7 +425,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): plugins. """ QtGui.QMainWindow.__init__(self) - self.screenList = screens + self.screens = screens self.applicationVersion = applicationVersion self.serviceNotSaved = False self.settingsmanager = SettingsManager(screens) @@ -433,7 +433,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.mainDisplay = MainDisplay(self, screens) self.alertForm = AlertForm(self) self.aboutForm = AboutForm(self, applicationVersion) - self.settingsForm = SettingsForm(self.screenList, self, self) + self.settingsForm = SettingsForm(self.screens, self, self) # Set up the path with plugins pluginpath = os.path.split(os.path.abspath(__file__))[0] pluginpath = os.path.abspath( @@ -500,7 +500,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): #RenderManager needs to call ThemeManager and #ThemeManager needs to call RenderManager self.RenderManager = RenderManager(self.ThemeManagerContents, - self.screenList, self.getMonitorNumber()) + self.screens, self.getMonitorNumber()) #Define the media Dock Manager self.mediaDockManager = MediaDockManager(self.MediaToolBox) log.info(u'Load Plugins') @@ -558,11 +558,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): monitor number does not exist. """ screen_number = int(self.generalConfig.get_config(u'monitor', 0)) - monitor_exists = False - for screen in self.screenList: - if screen[u'number'] == screen_number: - monitor_exists = True - if not monitor_exists: + if not self.screens.screen_exists(screen_number): screen_number = 0 return screen_number @@ -613,8 +609,9 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): """ self.settingsForm.exec_() updated_display = self.getMonitorNumber() - if updated_display != self.RenderManager.current_display: + if updated_display != self.screens.current_display: print "main display screen changed to ", updated_display + self.screens.set_current_display(updated_display) self.RenderManager.update_display(updated_display) self.mainDisplay.setup(updated_display) self.activateWindow() diff --git a/openlp/core/ui/screen.py b/openlp/core/ui/screen.py new file mode 100644 index 000000000..0aa06bfc0 --- /dev/null +++ b/openlp/core/ui/screen.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### +import logging + +class Screen(object): + """ + Wrapper to handle the parameters of the display screen + """ + global log + log = logging.getLogger(u'Screen') + log.info(u'Screen loaded') + + def __init__(self): + self.preview = None + self.current = None + self.screen_list = [] + self.count = 0 + self.current_display = 0 + + def add_screen(self, screen): + if screen[u'primary'] == True: + self.current = screen + self.screen_list.append(screen) + self.count += 1 + print self.screen_list + + def screen_exists(self, number): + for screen in self.screen_list: + if screen[u'number'] == number: + return True + return False + + def set_current_display(self, number): + if number + 1 > self.count: + self.current = self.screen_list[0] + self.current_display = 0 + else: + self.current = self.screen_list[number] + self.preview = self.current + self.current_display = number + if self.count == 1: + self.preview = self.screen_list[0] + +# if self.screen[u'number'] != screenNumber: +# # We will most probably never actually hit this bit, but just in +# # case the index in the list doesn't match the screen number, we +# # search for it. +# for scrn in self.screens: +# if scrn[u'number'] == screenNumber: +# self.screen = scrn +# break + diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 34c66eacd..da7b98bfc 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -538,7 +538,7 @@ class SlideController(QtGui.QWidget): def updatePreview(self): rm = self.parent.RenderManager - if not rm.screen_list[rm.current_display][u'primary']: + if not rm.screens.current[u'primary']: # Grab now, but try again in a couple of seconds if slide change is slow QtCore.QTimer.singleShot(0.5, self.grabMainDisplay) QtCore.QTimer.singleShot(2.5, self.grabMainDisplay) diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 9101220e0..28c6690e3 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -145,7 +145,7 @@ class ImpressController(PresentationController): log.exception(u'Failed to load presentation') return self.presentation = self.document.getPresentation() - self.presentation.Display = self.plugin.render_manager.current_display + 1 + self.presentation.Display = self.plugin.render_manager.screens.current_display + 1 self.controller = None self.create_thumbnails() diff --git a/resources/images/image_clapperboard.png b/resources/images/image_clapperboard.png new file mode 100644 index 0000000000000000000000000000000000000000..e4605691442bbb33be05ae054c32168f7ab2b6ec GIT binary patch literal 191834 zcmXuK1yCK&(>08HaEIXT7k78(0s(@%1rP4-?(Q1g-CZsYL4pP@7TopY_kZ56wx+gr zYHO>jXS&b!=`)e4$}(S&2$3KlAil`SN&+DuAQL{vF9f*HnRBRtqR$(o3s6QJq83Da z{P_T9q97v)@$uhP&{LlLIfLjZtK$LzfsFOvfP~1(!T+3u|0$;=1;2(ugouk!mcQ8u z0YL^KCn=`kv3}O$*=?q!bMfZ8^4(i&IkR)|PbM^sWT1EGFB3EFpr9x#Y$;-vg6rOH zD5%~^&3WXY2xu)yRkCSENCNQ$(SU@&1jKPsxKTD3S@H6&#T&kIWzBy*D>s`WD_gE7 zKjCo>#5Sm%(s{I3F@aOI@iAmy-Z9IToO$QF?-J9h z*K)-|onD1m|2*$5YIV8vpO$W|~egis4b@aprx zqqf4q74YD5cKii%vj6;xLFfgqGd|rzkr7z2rzlE%cvF0@>U6G|?z|$>7d-2GZFBGM zD&+%}1`@U~u;6#OZ%+nJu#ergiXv<4!!7)` zcutnFnMtXEa{Mrc#D{`No6U{c@rHMZ!fx|YdTv{=XI-xFKx$lW2MTQ1utcEv%>EL( zQiggG11P4EPE9@M!OG4`k@w$Sk_yS~BoW*<$)run4y*MR>m>K$8)MKa6G zvxs^SW~c=QH%dcU3v+{K>(qm~X;QwmsCgn8Y}o$c+eXJ;CsF(5UcAe02dVKkNdM7k zrZv>m(M71LDy#yVVJWRF)%gTL4{Qz=oM8_ z25JkZsT#?$F&HjE9x@J~oBlOhuNUAl*6m?|?N@G=*B#F#0e6>$h05DQJp4rba>S%jrgqFK zS?VbM`jiUOlC#tb!iqy+st1Z=R=BSzG;yXKi_#PQgP@5#wiL)~7*Uy{;E}9?Cdt!F zY7j>#%qjK{&&9Yoj}r%k^G^y{t-+I`XqNXkRkqxSH?$PZ$)A-4GNn z@;b(ocd17Be=+hJE(TLlxDQ!G7geByNXyZ+j7bq@V*oUb(m1&ib&T7+MjFBygSYSg zH0mLD(_?12#Mhf%D&urk%sfRZUQQqDl%MqoAH+=(O`B97whx&hfu2NzGV}rkpe&8x z9pXbsSps}0O*__#QWa!9f#oIbgrdjGb42^)h5&$cNST7|i>80WN_y^3cf%zf>EVze zEYQcFj_MpYFF&45q!MN=sUqMkq0kAjfG4$;DiKWv(iYb;C_)b{YvRJ)FflRJKlCFR zdQ3c}tp3}3QCXkNd&=Tee&kXqv8ZNDfI=;d16ZOq69i3_mh2GrFi0d7C83jEvLq-5 z>h(H<$Y+WSN;5Dj$UjO`8jm7%a9ORh-;`*QoJP&5e#Y(G3@@9plc&H|P2Op3_Q&SOIHkYrzSRi^YeiezzERvH08Ph|{+ADy^#xf!rq_KDzv;K5J18@($ zL(t2psS*)tjb6TZd!9S=X0ZCb@zabE8#y=$(4}bR%Pv=c7v~(&os=pnGb|h+&q7;( z=9OiLz>d%YX6=-DTfpO2MeYc>#t={~?dOmw-&i#ufeu!G&{n0a<%R9~W^g}Cg)C37 z*Lg47KF-j-^6$)-)%_nlIbo+1WW9&h#4nM^=h^>ycxoU@k0{aPD9frijY=W&h))lY zL{G;v3n)6n2$G39yvq{FF`vs`#YD%MreF|v%tPxvqcFJQsoO6&KNNMqD|STJkfm3V zmeL%qI=(6|!S0RcOP348*B;(QKjxZ_9A61u`MW8m4VYBaj&6Jv?D7y7bP5ticRlqB&`|fQW+6VbUMK z^ZG8}xk$7%V@BS<;S+0yW4a+TD@gBA@pTJ_uSss7Ml5mjg$zS|xQi+KH#bNV=i*I+ z@z)Gf4uW)=nS+A9UF(AIH?Ba&6%KTaXQ_8x*B3#jv(4Vz+!wb-*PCxa#67t|sGs)k z)h2uW{pVM^l@NQ2DQ7#~&o@BD(~X*pA+M>@8;|R-sVPeks>#SpQuKST~A#KAhZ~+aU{&2It+L!h5K1{oNcBFaq527TR zC2n06mG+9>f`um!BP6S;s-g;!JmeT8I4UVGO-`L8=vqY(8x|u?iOWqol*XLxEC4+* zEX3{n^}VS(Tz2@^th3gDYUEj`P3E@u^hHzdpUvL({3?F|O(8h0sP*KmEd>F;=ynTK z#rm+J#M$k#co&dTWKh#sZ52^KF>Iz=cbib(+DDD`a5jMpGBhsU;nSvTzCe|T@qf@c zqL%IW116!nK90=^A+IEi8lI}EY81YH9i4a}eW?ZWRJQJHKASbWkG$PPpP}c^mH*fQ zze%W91XO5h0lKe}VqRUIJJ#%TX?cUCGCmqAdx~!a-KZIK02NM*9?%9cL^kW5#ln+B zoz3bE)G{GXe5xF*^o=5oJ0LugG9+OlG2kIj)ywTqZ*Z_T8ao~Q|ATW5I;(e;W|k!j zC0ar@;FjeW1WA!u6P0R`5*q>7E0w<*Bpylu3$Q>F<}z>QE?Q;O(bmgIbF(nqzK&XB zAzbv6)~(CB=dzg2?4>MM%zK>7!CWmvi1|jV=W)pOx<>kev+N}CZ4=c-t{+{GLP>BS zRq_{xT0e#!*-Ejs#e9$v9Ex3uQdZ(lO5=4c;T~~T3i@|(6E5aO&kMN;x+(St2aU*v zva^RZe~k*S6A7(QgwQ_%+V#YgFn=!DC^!|EJis-2!*SGBhYJP(?-M+Ij6SkF^1yj?|X z81Zp1;)fDXvIcQ7_$Bv7Bdao*hMAxpbU~OC1Sm6h>T_487h)u$j*Cpw-XdQ`RRgh< zh4W?&-ZJl?_B7-Vjv$i$7bKt@S2LLsx2MeWQAkPOLp_9H4URMnazsp6B^Dxv(k!S# zLl$(Wc5z1#7`UY9>p#gP5`^2vPaVWxf^OgA1wZ?CCvtEjU~kf_p%zL$|4o%)E@j!5 zs{p9tOO~MQN&$R;Q}Qi6uC$#K}K~sbY1qQ3zHf!kj{M zHAnY;0|Hoo`}H<<#t$rTKO^fVZb2Br`Osm2orG0%$p4ANRmhPK(M<#B!?x>RcDI@3l@3;LKnDp>qQ!am-W>>qERn_H`nH~jV_eWpzc+e7`_dcR;<@ayiQ5r zB#t?BvlTV#)XOr?lC#s~8bwspD_RIii%Y#CH2mEYucGJ8Mf#ZD^t4c3YhIt!zRO{_ zvqhUD8-?MtL#-GpOUQChE;&e98U||%?MV-Jo;u2O$g1aHey`ctW;FZ&wMWgghAc5Y(xrQ1hyo3=VEm z81`N%4D%~%`s#`v|Cf(CA6Hj9GwU+uxC=}r3~rP_SX4#RNspejr*`{QI0`)5d z@9o1Hlj;6`6G=K}Z5TQBk}G#1CdNJMh3RZy&+Rez9f4B<_5WoB{sSvq3N~A}X1Zn} zc$8&X99mwY0&ci`wyUN6EH2Axt6|t#@w!>9ba$64DboG7k5~KJo--t$pFg&`2}q5N z;;O9g<<*NK0lUw>qYWn7@lRuIy^-4BSaZm2Us5DdYCz5PY5d5R6nHrYNpZkUotedmi7+nwd{Qx`ncm(KpSX z;$MN1fwsPG@aVgS6P7*s$MTVMbrHES}PE4DR9Uz}-!=#-68y z-f%CM-_=XWmEnhZsjx{FAtYC7utQ6@q|}TmKLK;*(VmfF?TobhVbO1TfOmI6MSn1U z^VF|`EB3V*LgIf2BtuA>1SdXUUKN%xYVk~a${s3RJ~@2};({>w;;}5+|Gg;7r8#c1 zsT-b>F)O&9Q)ITr+W|Zf|LkONztFcY_R#In8pJhXeb3C}e#_|tu%%MF{w>~rbEo2$ z+vhhb;xuE)V*WHt4sT9yLSE#Op@k_yg{zdTS5HO91@h!v@x-_@&Vu9vUu)bhwKD{Z zl`1eEF63PES5pe1t(w7Ty znDw`&i3k9&yDejYyzzBd*pSRZZQE`{eJ^_=`y;c@l-v(sjOEe2<*!oLMA8cp$wd?R zC>-G~gB>3~0Ux)o{yQtp(N|?XXL9iL>XE~UCwAXQuWQMybJcTFI8<`BFMFHs>1$L? z?+tj|&bxA3b|ZSRBTh#>x{mfDv^kwe`>|onipfXFCt0|@JL(-k% z@NX*q8TpZDqJh*?URfbm+qk~bmDsokNtS&Or?OAlt*Ck*5Z|!Wq&9k!PZth6R1z;>3jS4 zx<31X1j`r9o@w1Q%k96;K8>+JmzmbeWYS#KDQxK_yeH#paG8>R6^Q1W;dM?n)#Hn@ zkMH2BUe(MLzQ@Tk$ZY717iEpek&en!h552W-`&7Ya0PnE9Z?baOS?;FT;vY1FrpUo zRVNDSyX$g_xnP7RMk3))d-($OnBnh?Uw^0g#_)fGd0wJK=pD1tP{R&vWU8z}GQ@uy zfVd!pyJ^d@&C;=sb=B=XEVC3okAJ!?&A0s6tf@|$vZ}f)liW5fnNuH%Hj!(32vHcu zU!|5KH2NU}%*6wK?=zgaEaWLpGJzrYwuVp+@dFq=IEsvIpPqN03SAsRmT#p8A{K>t z7DD+%t?|nDFU8^O#BmSh*wg)>(I5YUNz*94X>h#}|Nil`z+-Q`J!ltm070%9^XAvh zAA+frmAwn<7jK%d8X@@t*6l;TWC=iYK^~MKc^>Ni#|$RntJwHtC*5l(mcoKyIk)gK zUG%|?D5z9M43cZXnPW>>%NT4x^(aP|-E&VnXHuzc^KVRI8UV;$;)&X%^A*VqH6e z&FKLyMz~AszzYR3faWkA_jj*5UisVKW1q+TS&KsaovNrJx~#RpyRf%5?_PJCfK2=q zd}6hn&<<*Xw2rOEasHBmzskOa&}0RDck;$(YGI@}Tey zwe~W>@CBCTajb3cOHx^mU1^A?`%=OlL{hA5iU;u)OfKDp$1!a8Whm>&R}m8>H}#RX zfCFhSBr+TTO*h_TV+leavup54Apk@N2+eu zZLnl;qv(YyF~aeGygl(J%DMlf>RwK?Q=P2K0N`~-4n`9=| zs<&v^{khA@C-mH$cM6v9!NpN@jfIhM9_&Vr3AgRusph%7m3dyewX6Se>^@rZ$cvbYr@r%?qPkb#0ZYrV4?l4yhY-u8acqH0 zn@E5mh7kc3%~f8fTf9RKSy}ZHn^6->#-$p&#b-i#B0(zDW##91Gct=L_~v29Soe-d zioG?LQ}(*YUmTuewzEb4Hh=s7LJUhHMQLJnKPYmVZ-r~KSo3i=ySNnRR>r(^R(pst zdl!^r4}|;lmU+Ocm(n3qNaNpXueGF;di;*Re&*>(gwJ!nVB)9CJWXKQ?cPw`>vT!2 z_>on7n8_zrev!{r^~A5awOl3&R#GkZfI{n-HSKuXQ6g@tDOr6;F-GmSoXa0Vj!?LT zN0!u=U_xg!y*VTqTJG^V8X}cxp(owrC;4>6t0AMb^?E&i9ixbL(+;9dkZJ*)+KMB$ zm=gQOD)Bb~#n8^$fdV>YV5-#lbFi2J9kIJSef*lAd>RT~uk#yo_hp;G@SS02l1FvJ zwp&12rlkqSh-r!Ihy8>zP0e1dEreOHSvY@=!;&8}Ic8Z=z`un#3og5+O+47H`?Eu> zkG}HD#=b{g<*e;#m||7RLUOv{5L{7CF6`=|k-})o%sw~@KL}QNeMz#M0z{wvcE$R*QF*5=7da`9qz_id z=mcziRt%{AT|DQwXmSz>*lKEyQ8ux%`IAu6lC<#G;^jd!VpQmQV!P3}p_k-y5$JYv zJe@8U`ur_1GuL}*xtETwQ$)hkBHc%+n~j1YrTWz;_Oiaig#Jh>luGAWYs;>Y@!Ze= zTXq~lkVH%*I!t-(RX(AW!o1IUd z0(7ds8h4;H(I-{w8@bK8wXfe@gvU+K{lBvuZ0bDFO{OFV|2^AleS3L)&HLK@aE<&l z-UTvg_vIPW9;l?v6JI+OWB;b5g-9|fUWxg*gOB1>f~}^MLG@g?nt)x%1joeUIa(at z4gLc*39;^*tRC$s`j783p%LSyiq4?E7+9L>a>@j~!kfM=u0qIi_sl9mTdBgo`&eKoZnDz(|>n(^Ni)X`LlRm@NK%BUa@sGM>H=OZ_5W> zZ%>n;TFcM)EnMFv#u@=6z_!*TiY7C?6CnzH9?YcON5wvu(0J$$8&f^4#IuNFU*i?9 zrY+HN`UM)HSOcjN|Jr!<=7$3~%{l0=$Z&cF13fu$eyle~?pg`>-*u;nm~w|pShL_DLj*`j0bDAix~FQC9Jpu#8IZ7ot@eK$*hqgJll)bQ z8`A?H)_w6tx?BC=pO9VmOffv1Hln0T>$ctaH99iV{Sli!XDo*@>%eKbB*HzM^f8wk z`DqnRDLGKR+U@Ld^WWTnTU-)#KWW-4u+6+io&&9vNdYKdeJ;>XnRjCbdfHe;pWcPEMAtuW!9LvCfVFR` z#KGb;GRvAsws^W23E@lU0Bt@Q)71;rI^WBP40><7bGI3Mc>c5-^gVY{fs;a$mLNkW zjY6=swe`3t->E4JG021^SVrhIYj2I;dKEv<%wYRosdLN5vu#@Xlj)v^124uq=O+`Z z=P_fYX$iuvVeaPXCkfHT?Inv$Y;QBdpB>n&7L zS`=#g3>DQp=te{}6~ChpN6t`D(!IeQUpCxj;Ev&cTis`Q^*G%Ah-ABu(|w^n#+6jF z`v#;z1u+@)=8lV3=*BxtE!r4G94k_gt9Pw(Q#MFQ2YS=QfT5;d9&Wm|-dPP^Q!Ihm z7!c8j$f&I68^YVN6xwj%5u74C)SVV{6p&h5evEY@r@49_@1E6Ljlo!xo~@|dyCZ;Y zWRD9S{fPkn#;c!Bvj(I+$06VARwcgV%qDSGPOkkC@0*=8%Q3fD!k>1akS~eD!u5hy z{^KRs=KGJv;O#`K>CWJRW*0%`SgQ{@f#rR1C$WeAEA>`f4#cp$g8(0M^D{Ns)0= zwKI=UY^>g2B^dfKfqU=mU?^S4saPW-i1ka_G8}vJ@v3+Ke=R_ww+5vrU5!z@`|!5V z2Xl_+q3+sG@fp=Vv6PVCg7a0co8L^Q4p0WB>r2S|kTCf+GO7j?AvDx;I*>|V4<-FP3_ng43 zq=g@?hm>v!hT{34pWq*>?|c~*lUsCRDr~Msw6O5>QbaO|S-fG4CK-TNOqn;EejOy< zUp5z?FV54rm5A4%#*OC-^Tb1VL2Ikw6$)E?j{jWBGJ>|F}>f1c+ zBYjqXzg(iyg;wx5HlUAKmkS#+XR(nLEEQpmD!ys<7jOe-=+j9?i@`T?e(=Sq(vD(a^QIkJfTveUkaru=)T+U|EkT$Pa2s~XQUt&s0HPC98@ z-|MZYHl;SPMf=Mjk|1TuW_Bbv5?iq~w75XtK`vAi4`228#-T}HWVarld7QQfoMvKv z+*sQvww2gv_(Zo!1ZLAP=D5s1>3KZi_}qleHgY|54eV*v3pi$fC_yotN9e-rkI|p zUElG8ub+{VsK|3EX~9QP6=g#eVj>Uv$t!+LkoddLIY8t!S_CZB_YgkaVZxwuku99b z;S46kht7XokJa;;;qo~-Ic>jkS>@=k!`ryb>241}g-Wg(#FJuCWB7uB%}EW62|>@A zHy6Vy$zb;1u>HFkz)tt(H!)c<2vpjIdfN(Eo)4L0tk@4xxFfvWPml^lpMaE2~}m zTdk&4j!gArm$H+UMv?T2*?5Ja6Wh15&93RxRlmIG*{%Q;0}q1zKQEc-K}yll5d`$o zNv+69JHA_x*)^-JfQ<~SKVs@UnLFJkX_vLbnLBXQ0uEcCA-{7#_q%HySa>XdxTJD% z)dX86l4J9$1KjmX*Hmb2NPFI=TzypmKL^g2v2-P0FKopq48;^)t1JO zOX`8^pz2eFF{U-PQo;-9n&|w9;+3o|qkx;ZgH#-#s=?h#+s!YLn;RxBhkhPfiQ1PF zt@ghhtIkiQ=~o9T1~X~vy!MNNJ)y$T^!PHR?BS<(m&+LyYr@`{G;{ozv?g(w^oTVj zSJ3{U{#5r<5BRdI$zUu`Xxl9NK7-NQ-CxU-CV#0T_U(vD#P-pD#EGOsW3R7Q}w z?g(X$0O-Ngf@Ro2pA%qW97n;|>c4*~_)zx|1Qr6Lt+8heB?W>j{(L3W{I(h!N5Pwr zW#h1;<#$N1`M69}Ih4Tlpp+sjj(9t#p#<5P8>{^wrWRF1R;gIJ$>CK^WaxQ8)Env0 zsM+Y51Rrk%*j>UWRR{jlJ_xz!!Ydbfy7IX!Cbhgx&E^}yBX-~WhKmcI;a)vLNF)W9 z5)&N;VCCXPsLYvMOP3N$Wp^(_fZaohMpWV>vfXUqa@*bHx7*_q*P$w+lQ(4y;UsY0gwY{kxTAUED?UNijR!QsFj@#KyXF6}L3y zVgF0fV5Cn~iZoG|p3D?83(-=k55T9o!cDu8vk^l9p!4T!cP(fDNLCJSo?ApHy`MtT@y!!;i z#D1}I4TFU6=&af}+2HXMe<<$Mh*^ICN6ji?Wc7oDq-?|BOVP2W`K5bld7g$xaK}4@ zS70)3>%52?Rxoom33hgA%hnot@ zY7q-GH&>#SED&8u#VUi!`T4m^F}i=y%{*3dnspK;hoE0eV&c$9aN5yuVsVB6<_W>X z%Vvt`a~Y1cM(mXcy=bvU`44%GOjkrDqJ$WO1fDLM2Zz~iml@%Lks2}c1E^uk>gm|&zqh0i`Cpqg>5tZ_e!T%RUtb>Y(G%a6%ow)iK=5)emC1O zUOW$vJvNvs7h=+Jt@_&J1Gru?U3lI9B0!;W=+uoVmw-Um41CZe?qs^ zEF5LtBD>p>E2H!-=Vu*93HnA__ldFL=l-fGP!aGrQv%Ybrol9wj^Pl_GIg{Ri}M<^ zo_Hs3o#is>wi8%Va#vDDMUnH4)4?QfSb9HK`U+b1qNGKtGD%#vzRr;1BxJStUY>1x zl7sz^pfzY?=UV_vSPUZ5LKPa-Sf`xH0G{8kG-amUAil{wOMA8gkqlEOC#T5)`lul7 z)d;L8HhBCkWSdC-!$P?3q0&uD+ZO{nXv4{*1i>UsK&)I(K*a(wH7I6zp5d(n(k2L* zI#|^N{+ssuWX-1k2EE|pyT~+U-cvTQf8Wbo_USI%NM~rw@1@%JTA<&_CnQPWE~IF| z%87O{GG(i+OU7U=vF`s6je;$M1xW!Hq!}dfv3;fYqpE=7beZ|tLwK3p2i=@?yQqxx zf9BI`d-S=oT?L#_(rw@GN9y)9S^aTzl^H5u35%;JqBF;sh6)u+=~h0%?2Sa*T%W%D z$+5_?WO$UhuLXge!jeT5m%X5I9Hk;hhX;0%{GV4@51;y8n38Cql<2>_waPij0IfKa zvQ^tjc=TNuXWv>xb~|-z$?dc2{hJk8Z|A(adlwyID!*e@ZTe@FuQF!l=Ue*u<@wEm zrM(?vOhd6`Sg}*g(UfLhX+%*&(9dENj!aWqW#A z44u$rvMph5XJNah2trp4t;%A{jBzvvaWdhQ93}oOEAkBh;bf5$JbEu=$9M7VADeGz_t^<)JLS@vYtjNRi;W$?$zE>#3t-5=#y;Bn*xudQal zrdYRPZg_QbNy}#vmm@~);FrtxZPRMv;E3-E2CLRv+J&lLc)A;SAKH2jL;EwKArPDY z9U8(!*L3`1D8^vaPdnQeNSk+M2K<0Xu8%3ZOVqy*+7dVfgXyP|o}T!kOjsWJ*O_38 zs~E+{&GQWEev}pTcLXE{FixI{1l1yojE3Na!wqRsStTXETM!}L^<3${FV1TH-GAS;bB!weUD$82$ePQo+=p-`6 zXz(O|?mI}&*{HzT8DnI}$GqBo!GsLLp39aaCr5+Zq0&8QJ=9&O@NWhmRL{F2RZJxv z;`yG)`@P@FG??FD1`56tiW}M6#|`MoVL0Q0dt@#{C@v08u`4GIzg3V^!4#j}sm&Zn za**Rf=A+1YDhlf4@-SCLh<}X%h7^dGa~7t^!uu+0kc}MUQUCRMliCA%X!AK(su;$x8hWP`us}=boP>KezTsuO{#{N zy6F)i4n_qn&Wew56Hjt6lRTU`ZZ-$&X;=NlGnCb$T-_4H#M;FpFRRbM)LPRAW4npS z_rIZ(5$GjU-;ji%?D^G-)5?dwLl}pp8>vU)aNnA)e}AiX=biQ_@Xoh<4z>j6{dtYY z>j@C?Tp_J56&YWbLFnasr-yz8L6KEDnV3b{J>8lHp*!=ju>M=TcfdA|xhnm~b8|JT zKjaC{nbIVE!*?1JR$liaR?y|96hk1_ZHqzx#Act;hftUmjFsh`u^e}>DZKT!Pni_xns0_v3PGzru#-t zZ||g9-A4h44h5NWF~#iU-_1Wwq$y`|U(o((sIklPOPfknVH&_Kx#s$I`S#19aTKmH z(tEM^Yf4!}>v{C@+`avwH*1-BQ1!4`$(cD6CbW%v&DaT&(Z@g9t~gBHj4RFd5B z;*{Os2XR4<62w?QS9zM%$kfE|OsJ0C!;Mx}OChDENPA(m6{}rZ-O3b&2!l5sbPY+a z7O6ItB}}46ro`|}sr{)X`35WUI3zMWl=rCpK2=N_H=RD?d4NbK7uJeI&a5-%ioO6j zuHWo$+^C$xG4s@lMb5QSOFt5JkX<%2ZDqTrX=f5~e-w_Xx5X^KTR6W1m@hknl6E?R z-|=pKY$4G4Rk$u2vB6LRn|D79c76{fCI5jd?UtZMxL2h3^$y56yap%t1qe58Ej?G| zMVvHYcMG%qJ3(b&9!sT#yNJoV1LiktLn?;C1AnFh%QNo=w_TB}JbF5_(?8I>M-4N_ zsS<~KVcN8LM8h7@J~?UoAtuOY`B%r&-Y*13EM>vFbK*8@ECmIHC07f_Us6n?IhD+} z5po1pX*_jRNGM5KlZ~RwYGeGt;RKbFWR!c6$q`it3l)dQ{1;7c_3c3obS{UE@G|WO z0C&eSfv*4>pb9Ir)Z5^@gkf2vgNr zh8LwL&RHCXIIqY51vM$!immkvH-^@V_L_G>7qd6XV?F#0vdYt!^SgTZq{A4t9zUfz zr4)I}ffk|YImJ~1hA^!OA$p9Y8WoW1JmfeA8rdRp4z+T5KiL;C`ou9JG1;m|n^Z)3 z6jY#?W{rjTw$*0IJ8CXn@c~y9+s+@|L%r zY3_z{^!&M1xi3cgwg~hEM^Y^w$5{q^7@TEuffy`f@hAdm)W(@W=c?zR^?kw$UOP+bZ&p@7g7+r}Gz< z@ZIRwMCIx*DHhQP47dTFl5Q!ju z>a#g#J+@53$TV0PfBrIm>aGmZba;R^`b&hQuuTL#IdXZjP$sD|TBgM8wOWzNm50bc zzMZrUcc(XMtt)tyNBt8yDU7J@UwJwu+=_x?;8)6!3)NE;>zWA_JwnMj1Zp44O8RqGP;&>c<0+7-2H z*M&$!Y$?ubk;t}P&Q|)fBWCUNjy+IC@7q^V*>3@)ShldpDdv$jQhckF%8j3d9G!kE z9?3VZ!!L$mD4>a5E~69Gx(K|@c8Wi}lY?7`PmYv%tfIs$Q=Y8<5XM8N#l~p+tYUkpnE3{7Q)cqe(*#v@ZHaY4@G1 zGfSvgNbf#U#qpgF?{bZ?)_A+tTs!);|LuHC=fVT;LFkU;%K!t<7ryU(KL2VL_I`3| z<(PW(drTl3&e$5fS;Xcgzk4DNm;F62(0=jWyYS0y!@((nsNWA10?d_V%Va zPLigy-=E#0mJ!_r-aVRcdBM(MYDm4c^lX!2Xm^2~7(~_osSz%-n(&>Vld9Do11f1l zge?-CvQ*odytKp4xG*tjkd#p(ama6V7!K!xO;_$&nmDW5S0Dc5!oMEHJFcq;Cndj6 zq1Ah|nPykA4q0yrRz9rlFa|!4vWxyx=9*ZMf+yQ<=pB)+*XB{h{JEdrXB_aWtTL*y zGKq;R2d1=)W+l-q5*y34@NvYmwT@)xmw^55pbP7cI-Y+{o&WvRFf^Ag7`LgqgD?~= zg3o@VEt~f3-r=TGtB0Ql|Kg~9ga0~r_2gwccF|Lhj{=m8%(I>XDYV^gO*`wi;L`D$ zg}mn0rgWye7ESR5>krrUy11f~1PvfN^luLJ!E}A%3>%`lqqWZMzZV9I*uo@T_Sy#$ssUz;9$UEzzLnbJ{%uqnxvKLrnO-)ej>9%;ib=- zXa^Kt1|*#zIlt3gvd*;HpU9K;NA=}19Q%yTNJW2vc2VkHU}6DrC)l9Uu; zEU8T;B-UV#6qZ_Q_umJ5KaL-0In8*cJO1-bXX|uD8zXTM?EP7BfEr0{$64*ugn(E$ zKG|5zyZgn#3rmG}AJ1u>#iw8);rRP?p4>_Xf6z_0E7|66VS9(ZolTXiYRh*tRF-Y! z-_=XSNqlPqU7fde=Ni6W9%|j811wUlQXQ&Q5iLsOdmhS5t*x4x|d~^GcoM+W9oW5shW$#*6>)0I~+)r zovj#2Bnv?$%Y^2k>%Q&X`m~?p{c;a&)nO8^B!9$!9XRIq_U!r~)VF={^1=d$yw#Y7 zrEMyXdi9PA98)GfP>2_rEEj$UoWH!{@x8>#XwOlybe%y+=`^-CLW>(2Yt$b@Q6Qwa zU~7sk{wOu~XR7CvEo8GmP%HJ%mTe|6UR*lS475fr{*ln2I0$5}JOzlShm5KrNcC`) zRpCT02Bprkv-TbHZ#}22Ha#fSnKhg8U0jPkD4083plvKNz6eA)5OwWG!~UfpUS_3W zhQaZAP|MB7ra;&4Hx=`!&Yt59bysDGz2s5{m!e*d0qYV|k8q+J!Aj>RY)K!Q z^~WD&I`)fdXQ~Cke{HnNKR%kb%Tore2Y$Nd4sE*<_1$EX?oPKuQomk-jHN>+Az&=hEpd8K3BV-Frt z5#k^fQ4JH)`=Xvr_HA&gV#8X=QI?K;Wcx+bWOlJx=oP^hhe5#HPG3kssbhpZ z+u6u#eiiz6{22UncCkG)=C|)Fcq0>E&-;5OZXm)*9}5YQ`{`p`9IJcGL#%%$>RZ`1 z5&+8rmcSC(xKx`2h3|Qjqx)a31K9V%4=uX$2=~rz_pvn;&IIWeLk%4PF+V=}S%B>QtZy zra|9}XObIB7Euw^OHAYoFx1^9VE<++ zg_(}o+V{qGecX`luJH7sM*XyImQ1KH{eFua3Ni~_X?QGp-!p-HLJh6 zeX75g+`Zh|(_bKk!OIK@D}Zis$Y5b<;MNDDUA(Ygc+NUpkCXbww(}W#wvUe^rr`bP zgtMf2>A2jK(WG>D~rsEJZFA{ z`ak!*V@cwsAR3%RCy2b@?!nL}jRB+hpZ^m^yJF)If+;l_Wz=9$*1}ie+1Un z@zqTZnVH4czL~UX+|5%&X|E=?E{|_5__@7LiG`z`0t=9g!K(;`TwZ|E)G5TpPMyP+ z4N9^iMO32<5l0B;r1#$R&Nq@Jr@Mvtx>)5eKO>q(m$?a7oo(Wxq`~hQ=BY(lEW znk^}L8Fb81uAK#E-+SV`bstB%cTf5xJa~-|T7(-E^s^727(e%(umREt*d(iN)p z8ZYLS;?^Jcp9WbJ{v{fV|2&!Uq}2P~tJ2WXBIW#)D2q)IJukk(ufgY8r?6$k)~Y@)o)DdtcGrii*WpUN3yek(p5N zqhIzx+E%cEn4k|D=F<>T(w`tYd#@87L3^JeHD~{0!kMC&&DCv#@Ph&)qCP}Ry+{S# z_|_OCEZp;s8F+To0Yvh#>U51sh_oO!Ju4F_UZm({U<^a1tP&e>w2q`0iV~MMY5r3? zQZXC=oKzKvpNlGF$cS5|hffOVmkH!Hw~(>!c7e%MEHDWH5{@oV*r-%;ar2rbj58~A z=rplKZo2KyY+f0@lCkm%>1)V#StMf_MN}0 zs}}*aC_xtJ77kOA_k`9W(p4cpdY9t+DQ%dK_X#@D~Ltp;}zxSCh@YPR#hRJiMk<-9vw2bzGAO*Du=!~a#OIe{3JF6>n zDTt}>{<@v}-WHH_NQul@iF3P*Kq??H`UGQ<9#7|vHw`f|n+U?$wR61v9q-`Z|Jz?? zWqB!CcN4N(Yg!WPZ{q?obNux*6Zp6P=Wp=~Kle{r+7;Nc=kQuHnNDYRk|Cbwo0Y_& z^Wwu4p&==Xg5hvTQ5dSKq$tV+XBnNKot$PEL+Ijpl~P@yX__g`Ni9JP63%kwGu8#)WN08ph4o3a=dDGG1SutPUr1RJAu z{NsP}bNuX2{SQgOk|<^A;FR*)_W1CbO(lqgm=67?zHywN`N@CG7yjTgglbG3A~M5I zBFqRA{q8)O0_v`4R8`4fFkmzqZB_%E=JPIiiG$eFqpJI%G+^{5JVoBq+ zP|~1PnLigv%^tl=lT>s>6&W^xVy$LDXs*5VFjw7iD|deH>$&n3FNZQ)=J*J~6SV4} zOWDgsX`!cYcb4A8+jmp}>1R3g$Lkid%Ki?SeV)X6b;|XQfe-{CXne5g9x>o;jSvCv z1tNN^wfHFU3MdSXw>&Xvc=GAT`0OV?#^*ov38qI*vrvo}76XD$%oA;LPC zb*5>ObEMPr(56gbI!4nti;IzWz589f<842H2|Wf)-plxGA^(ynC^6Z&wBVA+io6g* zetlyXij^FPQ)UIiqtHC^;M2VJ^>4%bHoEccNQBgM2Uzc)40KOI>E?vPy}yqK4M*iG$4FU2rzaqRa3liJcZ=BXP)EJ zpZYYP|H2oTKJpyOIToa1pfuj43(ZHekWUbUPv?7#M4y(=sd-P`|Aiu6`(JC-%=5Vv z>d$;FLO$H*V6SfxDJ#UxMx|wLweGYn%(c3)$rV>#!3RI|A+EpnI!YG_8f=6zknA(W zOQL=t!n~w=Dk2q$y(EPM=TZcrN-$0Ek!Ls8`RX%A`OWwI-~7(Ie}myxlU}PV!qkH$ zlu9wT!@+=sg(0R$MO>>SLUh4)&a?nVE3`HQsSvVAqCp|kV~RlVsi`nVW!7K7c}Fc$ z%A=TiR9T=0CDazP*|2Ns7?mYg-f$Cdedjy4>F)1>k;wZI-x&~caffm7c5wosV<%;^ z=58Pf(I-|-aJV=ncyJcH11BOeI6~fCC}C(qWb8d&2iBS~epGR6?KB_z$Vd3}M?cKu zo2wW!OM@YWESR`y>gt0-mXg@SbO1?(3$tanXrZPIXSnP!)DJZ3FJAjEYr@dmG`s{) zc^@xW2)e(^er{ZvTIdBL%~3|X@AWzVyMy!*dCA)ryh4|t70;b`mN)**@8bg>`7p~U zs6C>131vb@a3bOQWQSTWK-Q5^Bo~3;0=0A8`|L6P|>m=LF6E0BRYH2CN^v0R{a$-a5qCO&=jfL{$(Qhe1#n!!ysH zk?dq&p+`H|NDD>mEZf&e}H4B80m^wC@N*} ze$293M#=)cvP3Bw1R7J6NTF%OdSX>6lO|9UgtW7gqP2!`-TS4L!nKg0kR7d8W?OhA z4K8|gp%K=jU7AJ)Cnr!(x#LxL@|Ji0AXop5J1B<3&L2u5L8KH(5n98n^e2kkY{htS z0=anmPAnj8!RR~YSdv7_5`x8r#ImxDB?OOi4sQj{Lo=N~Y*-&OluIK{j?Z!517GF0 z-t}8N{_qntr`D;W#KeLiHDEC!B3!@`dLlAO2nrcJrcg}n1TBl)*{8jSlq%6FLmToW z(0X=&&rcfXPYCD3apz}K^z*vgMQl2JR2PWUFEHNwZdu+hO8xstk(ReDldH=Pcb=ju zX{<$QjnW1c1!vdJ@z4LwFY*untN;3ZsA&5?{(=Wr_n2Ld!_21g!asN0{dx(2HSnni z?&Dwm#;@@3C;x!0^$kRb3`~Kq8;07TWwLk~jYjB7Q%H@Jk)RzanqG!R2oaFp zQ7VN{f+kzTw6C>M^EN2OV3CMJljztG@;*#riV_nQlc!I@#*|lGb2IP!-tXt|4}TX6 zyLMp~7H~1ak0D3t${6rMqKJ8nj06ErNK~A;qW^Uj`dMy^c!B@-f}fxlfUGa{ahiXh zx8G;Z8Lgk@)w^%ZUlROT&Rg43NV@OM`Y7@38JF;FFoAetREbk1(v&fAHK>ShnuIS~ zkt{z#!{%gzbtR}S+0BtNC;7^Q5Avl?eUS&g{8cudJ&D+yQYeklI^{=L+m$9C!g*7G z&JzZ>E|&u&KGT5P-9u}VM=lKB`%bOg{<|$EeM^h&hki@9ZS7D{y~#ufWXN!poQJjM zZXuqhobDGPA4B(Z78VxRzjq%`KmBy)jb*J(c@w?oX;ev!fwGirY_74ebA?}d*SmS! z-*{tosSPMGKjB27{=#dL(9%d_M2N@~(3wywV>&QpB8$y3#|50k@yV~<%LhLD2_F8$ z?{ebEQOc%aht{AXAu6I!42+?yN=#97WCUYO%EidPe>=UUT=ul5(z@*IV}wXyUr`C9 zjszQ$`dfIU)OaOu#!xmMAHbA}crmnr>A7{vCUDCY*K*fgcX0dneh)h?Kge+RaxcJ_ zo)A)Oudd8n5&oHH-(PX@pferq9VL*3x?MO|rZ+$!3YQ8(R5|#}kwR-DA~r;HZYq;F zQV__&^VwuyWTk#2<_R!FpGg7|5oKo338YL^YmxU_X}{HanUNeVAwSL_F*0%4^UTZ_ ziq75oV)1y96_6ahL^5a#v1V!;taC)`nYsEoZ{>90SI z7}r#KfX;MSe8h{aI1fp*CB=+;-xu7qhkK&)CIxUyzm-~?2TjdoX6FLZKZN@csoUdI z`x8b#LbY{$?Fv9%(j(_{D`vLhp$i%6!(V+9KxK6I_v^2}p2dYljvYP9@#DvF&M_Da zhytv&9hJDvf)gS^LBdp=J$IHn@4Aa${k31?+RLv@Fj$83ycC$fgbOJKpP-n0kxEoY zFOE{tT7aFv^4nkeeLjEBJ>38KFLCUVZ=%*VSu`cO7*JN4#y6N!qhg8BCDmYrmQWTl zTkVq?hL92p+xJ0hlMfr8b{!%jgqd$1w7~kBC_DpIAzaK;O7bwPii*%|ptc<4Byw=~ zer~_xcJ6rH-5kENj(oQR{y9ARiu_W-!J~MhaTk5Z)eNSENwDw3*Z&L zd%TEFZqXuJ_ILMcVO^J-3z_Nd3Lo09gH(bbvRkr{si|upCC;7$B4zRj=?TH1@?)jz z(*le6{fM(OsekQeF>(uDzu>g=9jc}IYbzj;fR7d%8*1yY8ynPxWL-yU9eMinN$$P( zE8PEw|B(m2bRQ=le}a)PEDRTLjZNK#jRYxh!4tKl(gh+PsIIYd&`{qNq+Nife<$0M zB=}QA5$2|d7((_ooZn|CrRE-I`|e_U0qGz1N~xJ`IDK}P>?V-&mhxHKvAw9x1tn!2 zi1(gbZn=d)RdIIpERR3_I8sWiwN%4FM*si_nMu_C&e{|-&Qewtr`OK%6aURm@bf?S z^Q;UPyN+4Lzc^DX#E{_v*?D$F;Hk+v|L?A9=`aw&-3h8A4X3CqjG>AmMP;s zdJ3sf!vRWy(Hf%^ML8m%@c{}Y5~W)vYI6G;scaF`?S+ys2CWrJiA-|nH3mUa4F)tZ zTcyhq?JaWRQ0q1OMmxCXrptNl>t4rAueyWfYpyu&{cE#E5IG$YP%l~oLVw=G@q&kk zh%>=#a%)T0IC16<(OUAvs4|%(B!YoR`W9jW?!1>Msq;0Zh@nXbJ36x-MJBbRC#96e zx}*n_G6^GtYI6K=JC&2|jeIU9AY)2VM8tIMi?)a*PdXt$N|BR9JpxUPNdpvvc!BV% z?_58yKVJdq%I<~GYUc93&&N5peNX;N6DExP1{2w^*;r1*hNq4^%^%+L`+WKnpW^se zA4S)&YjGz^cx-H#L`k7E$~g{QvX4VIUeAC0%2%kTQ>K$CE(COU;O3l+7<-V_Y=PZQ zCG-G=7$pIhH54W(*fW>D&$ep6w?CO|H|A@L%l6EP?rSPP$Cjqs9$GPEHrgCAkO8)y zhgJ_VYYU{$ifOGiH{N(7iwldKIenT(AAJ-d1pD{z=fI(Z+<*W5OeT|bUy&d_rIIa* zbB?ksi6Kx923Y4qlN;xF=;%>C{DuF( z?|e~p&Aae2@0;x4JzaKHi zO!)n9OHy@uDm<&9i=%MH05 z%D!0<_mZT0ws$?|CgJ@kewogPqgc-`H@YJ+|7%zWVB`Sy@?OGMVt;gAXzqjkx*d zn=!_4-+lL`*JxWY6e7Kk{X!X~pej@TceS*@?|kmly!M7ybcug?i-h*%kR=a#X5J`K z8JC6zI6dCriRVu6zTf{izx}TFa`I~rVVq+3?iG;fJvU{Uc-lm&szNG-sVZbh{!!XM zj1I}5%RJXwe#Z}R`1V(jB9y-MQg)tqFyBypE7W7V#%FFP5@(C-bU?aZ0GjMQaBDc4 zCu8Wk=nj^O5~RobhCsl`GN);#&x8-@J)Fxs@tbHhNG!h)i0Ul(0p3_zo9JkQK?#vWpK(f*8+fY`F}W)X>5_UsNDvMmYValzT4Y=3ElNe4w@6{o z+F)%>#3N96pU$BKSGEL{8ZA<;yHN!egH#&F1k9LH#RSpC0x2t8R2V%(0EO}hVJUP; zkRj2lwLwIK#Lx!M1p*oYJ|L9rHB>!Dz_tlA^<@#fO~12NFNvMYw=5tn8zJP**ax2+ z--zg#Y%s>cQ$&drq+-&>k&0A+niyF3Q=T2K^3ah-`ICnq;G^$;56?XDG`ovshC$IZ z4Iu=qwK$is$`mCUIx!v@pKJqcymQGRHG-BBFQ6=w!)RUCb5q0i3v))H&Gg|Y5;G^v z=Vxy}(EHO&f7<9D-tBUBI~}*bi)nWuK3~YHTLQ-ObR>P)tQD`d1*$)h?A^PUm6a8q zeDXJ~sOdQ{1n<4cJ5qA z3+*g?lqi%*9#K+jN^MZOm${*Ijw;uAkEj7d8{_Q! zR&Ht}Qj}>=kp+{)GX&)s zp@(_={)bsT`V3)xi(n&iU?{Yq3W;K>BFViLh`~`5Mf%X@y#u|}xIUYyJJ6Lx#sxbx0Cky7&T!w+MO;p(fe#yQ7{6DK%y=n(7c z>pb$vBXbi+w}4lQwl8gMFH-S{ltqCHsoMltaXx+<82hNWH0l%oNGnjkFeR@uQ38!3Rd+Oa}N+&W+Pbx{kCy0fF zfri{;S?ADYNo;IKSM}agRaJI9ZRQJ4oVQ8eUJUxUa-Z!KFJM4-p`y}HyW4)h?FFWz z3}>IL{{G~=Bc>N%bnC6RB81>;U;7%)xvo$)O+!^xY;JCL6UKo92M|JV?%cVqK+hFkdatc>{wZ33(r6sj7mESXDu-=Tt#NqBy-lc_S@R|Bu z^e}%=ML<#!L-G?;5~7Wal%fm}>W1msCIdC#&Rbu}JHG$zTz>cM43-@^KS|^LI9Yl%NlBUT! z6&Z;^WRE;Y>PcjmHfeooT!b=AID-}=s)ZfsqCyS}o<90Ck3aDw4?OrFk9^~soP7Q? ztIwUqZBA$=W0r=7LRAPSaJ6SgBdDiP_{b&R5`~~#-b2_?&_s_T;Bw4Fh~R@mjxA&c z>DF`&X(Gx9mKPT|ee!t@?7i$Iu>;Y4n5yfNNj&_Pk?mFF;c$v~zUi%;`T7w|BaliW zg z&d^rO7jqW-+9?1K|dj6Xsqk?QU}vN@aOgey?sU>UfRBs zu-?rb%1X*i-<%a9=N&~^f_1o%ilxfYq-~L~)^?Lkzo51LTkZa(rR8pHY%mxMSXx?Q zb#-;lh!Nn>p+hV#F7n7DkIWUmxd|&DTJ6t>AyVoB+gOq=+9Oq(LV|M`q4@MKzKh@- zdQdS!FwWE6*iWdc5hF7|N`o#WGI)Z4g)kswW5_7dWJCVkMG-MVpaCxePD#A*EXhIg z6;mE59bW15`ev9R28TdHP-rdC7S!sPfs4HQjyt&XHFt5{YwzUJ%MYOzm+%pUw8{OL zWD^o~#&!^x9+9E5jp?IEqW!Bw#H1?{vOm3MCXW#L02JM>qHjf$QU_xP!}!o-O;Vx> zN+GaKLnNf-aj=BwFldn3tv3jq7o7&f%Z8=_fkLUY2yf~sLb~)kqfRhX6jzil!-A~@b6JLLfGtZo4^~CeUt#!f_L?eh{%z%=mVmG^Y?qq3k zKa0yluDtmGhYlR(@D*2Z=c}NK_VB6Ce1=MT!!3fdFN(Ia_Agz5i>kE z_BQ_0=@johqtOU!Ej9}bx7&{NCynhB!wZ=gZl5TG5D8-H?LZ*0oaj-1Tb7r#7A0gC z>J(#S=gysItyx=JOX~YPF_dLV(=_KT^M}JBlgR|FHPh*o(P+fN!UE&*xO;AoJ@y#; z_wQ%t&YdhTFLU$FH}lX#5A}-mjJk~6Zo2~Bc~pLHLku|I^b8!+*Ndt`=7W4RTtJzG zM=NCrD2NiH@}9>zl##>`(OMFvKt=^JcE*N2>tR$#i%=H>Yidea6c{1XqESU~9`7vL z7)DLNk2e{{k{b?R!CiOV$;wwbjwU_ePWAymoJL-7M zL2N!W8446g74gC0n4m&>KYU0Uj1}lo5Y{&6Ov)f~#ndGRYBt{O|vBPOsMt1{NtSA=GJa)_TFFd?nq8VN>7PKbs#zv)fvlS_=xZBWR9CU@;KoP1`7P0U>I zZ49PoCeWvl=IAOJ~3K~#D7UD5qK?|oNbTexfY?%iB*#T8Ul)jiH*k3GhT6DQ`F zR@?ou%ChX1^yBfEojZ3@mStDWilRVk%_EOI!Zp`i!;T$0SYBS{@ZrN8IdWv~wRX;R z?2wLbEM`+$mvs_D#&fH5pCWc4Nm}ca1Svv-tc1t~GHF?iF?gRzib9}NTE;4=LFT4I zNRZh;|0{& zre1mQsz`@vtM^c%ha6of zrZ9_m7c(m=&33Vy76UHYWDY4MzOjfHQCdTE2m#JF;5E)!q*SR$$uyZHVV(wIk`^Za z0iP(6K=2b{P)JIwYaud06SmUS5g~*olULIFT{mNtl31IT-XVB`^b}NB>l0O0c)T6s zJvdz?7!HSZ4K6B_fO_hPHtkP+_MnTZK^GM^SoBb_p)9KKglL#5&-!?RbyL=#Kg+X6 zp62w)Q`FC`a^l4EoIHJ&)2BBWtPk0>xWJ*^JGpdu2RnBybM>LCx#SJ6x`C4 zLTFN;T};yk+0`O70GWc`oq27ZQRH`j?|1Rhql9`1Kv;Rlft1~Jpb$KM;uwGM%?J25 z@A~)X)d@`q6kgyiplg_047bH1#PfsI%LjOCM5-F>>I*0S+HN%mWWRz}ngxO3Cg}in*w^{B|J(%gf71 ztyo)I!&=Ag-MhK|`s?xDv$?s+a5$uC8m_wPD(bpsYin!X*)zM{hWw1A#Xa{(a}wKc}TxS4h=rWQI3zNMNrM5VLMk03M- zji9l0KHMYLO(7(WgA^L?EkT6zS|M<@Cd4LxR(&E{=R+((MgdS*dp5uS$;BX|2wrA# zi6usx7UzgutkP?ircjB8yxRyU*`%q&Zh+K8X>l@JiD*q79C(kB5kC-&x5h*Qlj$bw z(>OLX$$N&jWAdTPow!gJzugyV`{8_{ zg7HGrMSE~crP%%*ZIDn`pmGjIUDw^g+Afxd!y(h@G$Gi1Wp<7qP0X|0Q%bpwN;$tH z*|TR4&N-HrmRMU`>qLxX)p6V1@7uSJtFF2#>uUmaU332*{|Q%Kc_npSbK=Aajvqgc zQi?n7xPuS^`}XbQkw+fMLZ;B|S=!feFc@^t>)^qI#2DGw*dWG8V;i*59sA6C&o{pD z&2&&^s-{+{&~$s8>?YfH0B)7sg(*==gG#F1R;e$Pq9{{=>F*@8k?DYqpoCyrJ8TFH z2LqJR6vpJ@nyz>$Q>c=ZBu_Nw5!O>#!J^RIeDEs1`^|6WyTA7hm{CbRkZf#h&?v<@ z-!Kv-S`VyZ-&x3)$q2!0V~MVg+Z zBVxhJv{=svt(3_oUnxW5BZLV`l{w%ItPxCXVo|McZsCX=f9?cNKYg5|$DZQs>646~ zUSn%>%GTBvAzDfmDfNh9F(eWgm4>sc$GPvzU*VeTUa@UXNGu62)1fQL$OobeRFe@J zJjg&H6AYIck)pTq)Sa*`$h>nEWEj)uP_7i>*4CIHM55gH8I~bnrR3Fje?NQo?ne64 zsY$^RY)vc*LNvX`S!HT;>o%T$rx++o4H}+%?m70X?Cpw__)ij^{uLAu7XwB}R_hH8 zzy1#PZNkEM!s3n!ghP} zzU4?C>gv0qwu}FM5t99-c0RaUtwXEdsOuWZLWc}*9W8)M|jC!a)X&4Uj=%+k^_XHK7DP*&-KD*@@Twjl_K=&VdUMNyzk(fvM3 zC7!!341!$br9>gqg)0?O#sob{(ZN#5=3FC)6gnxp34vizQdWZmmBa~?x?xZZ5K-d_ zMG>bg!~tP*f}D=I=Gq&$^VP56&b#ko&!xK&ro<6BOHDyUG?Jn$F{Vs91(l5tg{BUP zmv61lcyqv#GzcLkJ(H52W@-VQIzrJ=IfyP%WxLO7`}$_)QjDo!5C&M0GRloH*ifUQ zgXn0SO|C{<$IiI@mC zS_mp3C|sLo}g z6N`&&|7{sv^tF9*_PBEXC(FEJ6;j}Gd~wv0|M91Oj+4iqp>eBJIwyMyg;IkwDGE?V zCPB0pC}D{qpoBn6f%j9CRx~a!S{U*t4?e(6H{OB>GZ@Rd{>9Lx&C_gy6Bq z9^>@s)7|sE^wLW^3lZm%7N$Slv{Mtn!Gi};N^$h)QH~rr!t(MmRaJE?ENd+fJn#VC zd+NF-2AFJaQ56H6xAitxaMZB|5h*6*9^kMeG@v5mi}Xq-1Mto$BN!hpsrl8{YgTZoU0Bb|1V1 zU6{mNG7_g1LYoYerK}92J;5hXK`Dt81|cFo)VPpDT#{5UViW`vwRZ?Fk!pw!j`3uT zLJvAkLle_}Od<1>5>c|iW>%UFo{(X!5Fq+7(MOu50Xa>tU34h`%{34u)};yEWTQ^& zBf^!aVoKAD6Z^=Tq}&$Cxwd7(CEI?F^MMf4?=JF`B4x;04T)Box|!lMG~VH*fG{RB zlf+hx0VNfU11S^SX01(OSvH__g@`2+DVdCG);FdcIdX&(j~{1xYMt@)9B0CHCKxu_SuD0E`FW*D zUv~~4g2=+c0uMfTKk{$?ovdOP@FLxZXar~!i-Qr2C$Ip{CU?xHX}ZPUT-Jn|9oTc$ z9NPqR7jmYZ%aYz!IQll_GasAt|JyGp{ep3xEyo2OyAK1kwkGXDxM`YB*w_7>n6Uh! zEbu-snI^_lyUXZo(({DV7LRrx5JF(bjvYuTsq30kr%uh;lC-Z|Q54|oE{{hU0#%IfM#jFMDkNeBt% zGrFMAC8f?2q6nRcZx*SWi)c2OQz{wTiD>dPsDO|c;cXsx>X=NS@_~}zMj;&<(>WC^ zoolE@ftz1`1FwI>8@S|}m$9_G!jv&lgOd_j>U2;?fzkykBuf+{Q_QiCKCyN}f&r{^ zc}bi-r=m!?_D+C8{{P!Zouh@_t#yhX*p)J`x`5=Ek=PbLy21~fJj z#3bz@I!h9T*3j5ZqzY^_4VA7CK8YZ;mMBpne7dIVx?z3Yb8h1Vr%s<#+hyu^Zv5EK3mnhF)54wwXc0GfA{bH_#6S}#Zo-dnUg-_HbkB{@+?30 zBR|IOeM7uEhs@%~J~1eUeq)^UDZ0=d+b^9R19s#J;wZ?LWqaveUP- zx%!WNAst2B*8QX|E-BczCgYAR0T4taDg}i>#Ymw9I~NwY^2#gcSYt89ZhGiXI#NoO zmzS~DvbD7}?=ux=G-D|x*IjoVM~@!mz<~n{1_QL#Jahc`9L%=5y2{qpR#&)MIIREs zD5a?DnswW7`As(vzaf~etwMB^Wrfr-UF@oYOt6jNYtSC^UE6{0d%m+a2t^_GRqae+hA*@EY)zi3C-q zrE4iGq>L$R+)IqCusYz}6r%&yj?r=iF%UxP21P7zcAA#eA;Tpks;jk4N(Ph*xad-s zAEt?x8dPoq0<}a~(CL0vvlC_@th)+Zrh@|4<0Ghe&X5EX3;H2QT zH+^5yEU8H2YkY*Dk|mE60cg_CR+{W?LX!ocB7(_=ll?}pwF)WAlC`s|eEbuim}^S6 zBOHH~w+sE;5G+AxLXf=r)qjh9`&V%B6hTZ-asiq1O6Fo9tV`l(We6^S)`SpITA`%Q zJ2OXFl=u*M^2p=o?UG-N-dI{@HFl*2?7iwBu74ed-LE=-!oGd`()TIJHy?Wx>pdcSd)<5Qz1?H>A;pw}M~9KNg=~8I z6n}dBC|YT%qDrr6b~TM662cg%1TMM^*_Fg7P%36!L*m~HrHBYZ6BrB@AZ!rPl;r|m zNP=+aXfRsil%-NbVzbUNQ?A)_fSd1nIXB#X4Z9B?KrB=QEvc=bE;S0tKve{j7({|0 zTBQTUBbi2-#H`H*Qh<<($ygx7BEo?8n~7mJ8K70b`8p}0L&D0v&o0ZM2H~0b4Wuma zP9SALGu=qAm-h*qR|6)^1}=<==wv=F6yCLyS%Z!ZHfv;Xjz&({a+~S;H0R`5huqorZv>;$0{4O;{?=4C58 zSs5;J#l9t$_O9S{V0n3o9XofTjeY^wt)64@b}z2hl~>S_C%Ud#!cYGnzsQ64Kh7?* zN$mojDtn(LmKW^;A3N{7kbCV^U^5A($J~oPP-w&PqsMsex#!TjctH);U&k%RR)?0) zJXxXyyyb`g0k|!qIg4-+Er#h@%n7QY-4SPK+~}mPM|-?WFqrUyNvKgeDd?MeOrZ@= zeEn(G$7?L+7=;(Bv7&D6N`w;p^gsAXe*Pc+Pr36+~bI}U^ z+ULBnvB4#mTtZov96WfCvuDq;fB$|iz4TI!A3x6h_utQrH{Qt7(o(|6t>v-DALIFx zCox)gc_jVkJ?{ui=l9j_O_b7D?DwBMR@ZbYQgh~XAow9G=3fEtGB{$x53s>E617=u2p|QHcYn2#U2o{HF0UoVG zYEXu3pAQj9^ctxJF*Gk`k<`z93@ z=TXY0r7{s8HO@6jj}RgvPH|yMph?U1Xb{0;8;6e;?`niHxLkBZkSI67iGY`pjk?At zfslfx@w1>o-{7U7R3+08X#6IAV$l`~47M;R1fy!mu&kgc*t7p2gHc6k3ij^V!{TU& z9?qZ~OSUwO5hnyD%p9cKsDSOn9dSW(al!U4in%5Ye)~)J@~{5;f6A^)C9Vz~`zU19 zcMNfEU)P@?l3Avh+grB9quuk2$NwL7ZysjbRo8ic*06_jPR)19y-5r=kc1%tGe85T znM7j)%8ZBtYBx5GwkR}o>x&KQqpgo9jT8ESsBOPE;tO;~Py?c12xKH=Ah|a;H#c`4 zYCgl>dkya&YwunA>^hZbHV_^d#&}GzQcg)ufLu>d-iN+I~dBx<~Bz-j}?bcm2En$inPA`7jIOcP_xoCP8%DgC%c6 z?>Gz_NtUpah=p6Vz?^eD`N>aaetw?2 z@4lOrm6c5-z^VeMAgoF$cJAECrI%jH($W$;cI>Dt6XzTkUwkpk%ggN8u>%M&yJ|LZ z{P=P9?%g|vu&OErDJ9Fx%k|&fzkfd$Uwm=>^V-@Pd7g92Ew_*)2~x_?)+mX2MP3k9 zi?9LTtx-~qPQwe=n)1L>>N z?V!Cv8c$RR=DX9Jzi$s$JpCCw_422%b;UtHeh+>9K)hu@!S#z?tg%{zvOj1=h_#sbLV;V(k^rwqFA+^KoH{-zVfyS z>J1fKNMcIpYKb+H8=g1cD91yA4!(q6*Bg9my3w>^K`29KHtqNE`AFdwCL zRuEcJ>k9M4F~7FE5X=zN-OsQ4~D)xzA-d9CF)jx3RFWQ1dw+c;EpJA3n_GmtW3#=bguJ zI2;RDqtS?Nw>!r6cFxi5c3E3nV|I3yef#!t`t)heoH@h&_utR{{rl^nR1^gdKKLN# z&Yi1=@6H8oNEAgFYeWBBZEUpWaK6s$WT+IY&sSAp;U9&m{9J@UX&nxus;}&P@Jm@G>aK8XtHQL9IN{q6-Vs8Z0FMH-MWIwvmz>Cf7r&!wzll#Ob_W8sDvlZP3Q15;SMGB|6oE<-4dkpu7s zV+77g(2{{)LnWI2`YMCflSq}24f`BFe2|sZA?t$y4;^`!qeqWnR@aDhLKi_N_xy+N zekQTxnjT zTtQE1gv&97Bg=<)<8gU`Phxx&N_AJxMj|1}iUJu&W02b>0%N=vxtTLk4a=MJf$C;8 z58gPAgVk%NGbWebL^4&w`-;$a^ypFc?%m7m>}+6OOG$UC$JER;i;IisIAVHw8Wm}Z zEThxwvbws;#TQ>px7)>g&(hKoOG`^EE-r3DhE>EcLU>O^FAPkDM8+{nSWI4!=p;y==Z^V! zil;pFO1|}3S98I)?4_92c(3SmdJsvbrN;@++|&$(bwRvO6zEjq$SJG^pJA=Ry9lj1 z6n0qqym;?$Se%eJE6NsD2-LYVcoBFz%7seI8v{7<$OMV05^An&rwj&bIIBvisAZI| zp(9U`XP`S+TOhII#fWJ?LsY;>7M#h>k6;wsC1;PEV)@ir7Ehk$+^N$X zKX{bUa7cf7l_ZLh-iF`|BuQF|3Obb5>=ZHdc0#0>H;VliozGAI&ToaiBH~SLqhPx$ z%FVgal2Vb{e2}O{g)X<&YWt@jl>*~)6fs3HAdb2`@3n72o;?@VkTY0S;C;MNDNGO= z9TzMO`*#D{Eyk3fl~R2E^Pk@srnjVewn6+r8if}*t4_0L-wTQpY^O~)or4xa;REE zRrX(dVV4VhI2_hIizG>cQ5BwxF1o0$3@*Iz!XVOERy$Ep3uNY0q$) zo2U8NE4Xkocq`Qg0*qfX(YQBS1#*@s^_HA7L{0{yB@8l(Q37Hi(GH@KA+?sY(_!Cv z`?&I|D|zzem(!V@K_y+#65UHs8Av6N${}@zj;Bhda*)n;u9StZTnfF!nUvs3n3Ibl z%q^U&{i=N~N|cc;QSwpU-W(OfAmeV=gAXnOlNY!sfC2`2j&YuOl{4tCmj{$0$|S-% zx@kmzeGP{rSWtN~3# z<_(GN@UCC~ZSK7OFPWZ6u%+6BA_)~z>#%PcsZHu8xCR}d3Mi*eo#M!mBjZ-j+hFD~ zc1;|h974qW#E<_JNp}hB`@~U<77CZEbB6%($v*D&wX@hYs=7 z%b$jGjwe0oNwpT$@#DvtpP%RK*|Wq+!b1-|#L1Hw=u>c}KHGGom9!LNH zAOJ~3K~&sBd(M>KLrE>fIN@^h2CT?R8`ir{1pnublq5nR`vp-PvuE#KF1_RuE`91H zOwGW+xaV?0R{j2(_i3Y zzxOd_b_~H7hNBTeD55B?d0^G~Q7KcC{%ip1bb< zI=MH2)z0>`m(p!s#gs^y-My2zgd-L>d;{^*#AR<}{<4&chSild=0<`Sz2Lhz^xz@x zJai8y)>jyMIJ>^a-rmI=Ja8Y8*7Ty3_0`onqiHX+NqFpLl~T!jEG#T=@x>Rjva-US zJ$vfPp*d_m|NQf@)^had(NgeG@$kbBbN>0~V~nBK>jhn&vh7o8Xwm3jCP~84qetl; z?s3^=mr)c2S(b7C{r7X?#ECi(C?U~t%y2lY-TubJ_!`w#lYH3Zu2i1X<0vsv68B{7 zhuyB&Hs&J19|IpqUSR+WQ7K)s(3|3d^Y*a+;!8OHqHkel&rYIVheU+~mPkV!p(9P? z1zN@!Z*jT7#5R}@+29LeMnN`2An_(ZIbB_$1|Ej+{h7R=g8y9NK%F z^&}FMgKRhqk~w(1i%8RiPSRn=><*@9yXa1b?(7UQ)^y_zIu>Cr5TaPU?R=>{gg1EU zN}dxqq4||R`#68|;Xh$+z6+y_NJV5tP9a?&?TswTftCtaIE)JSq%bD549j*|_&frW zmydf;cCE=Rq`_~`;34n~q+m6Jx4h;DnV(Iu*=jiOL@7Xs*wQAttr*>0 zo7Ho42?%-bd*92eUiGR?)%kY&^4{~n@pHWLWv}9*^LMj8SVu+?T8Ft^1;K9y&WeO< z0|T&BtlFpIB% z2ram9lM^zDBsEq=G>4_-yh*Dd1EN)^F1%2fvMTWoA^}oHAT&+}-vtVTG>%@k%iPQi zm+pTO=U;FkyU*W6(n)Z-OOyx<9vvmgG%77$2*CX0x2zdwnl^r1AXf#@(gbyk~pE0c1h!u?sS*#RF}Eg zS$dr=z3C}zHzA5dtLaipq++GVBEZ{F_0$4LB`aMLd@!&WtBADcFK+rO@BX)MVRv_$ zV!co13gQH`EE&gAl6!}>BBw`BF9lrzmt6fErj@{q))8U265J}wq((NBrQ4+4_Wo)9?Mm){-@bjk z?|tvvmchf7hFl_~Ec8d7=Usap^ZRzt&lmAJ4(^%t`}VcoUXu%^lwvd*m7t**Teh!U zL#1P^?I$FKDJ9>fL|8!*C){%D&0O`2Z*8pQ?Z^XZ99mj3MeV-pK_Q>|^(N zJJ_*f9w!t@I)f7e8%IbHvhrAKq_gygtKqYY5mJjVD-o9U!8#Es-f41a(IR+wSf%ML z4;e+8fe=J8A<6RqqA0bX6fse*L3rXwvXIOm76kLN^YpqscFixKr=~&=IoN~LP|#)- zCMQiet8b$6YG8tHkZ8mifpiL`9Jem7@qI6UHPbWG=to#W7#~ z+8sdw;xQyrK576N+m8-j`CTvJzx?=55>F-c*Vi{8Dyo~_9-`GKErxvJ6Mx2se($#! z8G{xO*+zS&Y(07Wm_$lNDymvgRr_aVW`-v}`NSmqa9bP-ESOGqi%zkh$t46hD_iVQUxjp_l{;^HEUi;H6mzIu)^ zruJSR3tbCWeW9nB408(fKvesPtp7$MN5FM(DHiy+bpZ!EEnh@&pMcXv2% z*9;f#c>?o0_7HUwqBKH8o|Wiw}S756BBc9BmIJ)lGt@cj5C6iQlg%Cus=J=6^N{?)Xa^R(-)9dl{r$3!M&$;QQo9fM3Nqby! z$t5f-ETFY!X=#aj?zyKX1r|lYp+ko_apD9~6miv6R}n=K`}XbQ#EBE6X&MN4Wq?{= zU#}N*uh-+qkt1Aw`Q;Qv!If8DStB4;R#uprnqqx@9p@Z3-+c2Xu1lM^SHqXfO;S}K zm6dE$hQ8gJYU^ZG*RGPOuLq5#k4N=)D@aHZ#TXmBET)uVdS;rPJ9ly31^d|9nWHlu z6HUdSVw?(d3=u1IEQ4aL6l6t?uo9OIaaQ9r$Vij>0--Vnc^1@n5lHD7nT#SzD1<~s zVTgM6)LE97R_QN~=pQ`CGoE-Uzx3bV4xBVCkXbEROQvFeo=l_pKHSz;KuaCbf_lQ=qjXGq#>RL`i@M_t*RN;=B6ltLc=o z8_qfA=jYkEb7#$ksFZBy=H}SHe}65VUJZ;#qfy=7s;Y>p9Ti0pXU?4A*s){m*s-Io zERGyG!r{Y*>k6fU^;Qd^*+Qz26;->eO?s;2;VY>Rz2LFpvzTRTsCcjs|u`| z^(e3D#3^%gv+UZrnlOq&0JX(~!=}iY`D*>qPYqj3i7SHk3yY69b*8-HYL8RIa5hEbS z8kI;SJolYlWUD=1xubSle+C>4?RQcj#Y{`d(X0)fGjO2s?g`0p7FGydv^8#wvd z8;OL*D#D>tG7Fmnu%_y5jV>?&x|x@9&Fiac;KJbanO9%Ka5$_9fSpc<2OfBU#l=OQ z`OIfxjA4F$p5^7``T)K5+H32>csLyL@WT(YxVTuuaI3ae6-4qpXKHGy4lD-_9N@^| zhsrD>uQSQE=~S~EZB`@Ao4?6_9ctN=q?6X396)KK>c)rYB3y4-`XU=eIB1)+5fbs)a?x| zw+V*76o3pKdlv5uUdFuiWp7}1mta&ZV|{^CI_Q!KAJA*ojY|lXGbdO2hWnNxca+2> zkisCPWo~wXPk!=~by8LxyxV2&;YG>3w+^o&o_y&GnVr=X`B@6DaRg&E=W?V_uf-s5BtMpM9l`jH>!;ISio`EULfDP!;gli9k3H8un);cP`wjBWfXOWCt$ z5BvA;54h-ZAuTN})g+wLr%%^I>gDBS=H})|({xPr_u+>h=G?h+WLZX@=UjH#W%PPI z9)9@YvFxX6F&#U0jG37kPMAZxVuk7? zIIk#_LZ>lK2}Ul%6@tOa3g=E8=iJ$IEH5v!zP83-*hhL8t>&T9Duv#p$q`7pUV@83 z3Su3Hja7tMm2DEo1jJF7#3c+LI?bPd{WhEqvMIhvpxQbKW}=jz*evMxf1Pl9f$#<+ zBuWTAf94qf;SFzQRwh`6NN2F6Hduw46M{{W`^{EnGij)+Q?0Pp6AQ^pUh^v6@B`mJ zmXU9lY+E3LE2EGor?5)%>Nov3#}3>>$|$s|8i13qUTy9CSqqs~fwla%Y_w~`9?OWd zrrYVTvb@5>N4`c;6m`(pPS?Z&ieSxbRK&|(_Ewfw52B>S=7K2BgBrP%!QP@YRjWNd zptM1dVf{-n=ApFVlnPl^&`DB8qYNGEn#^38$yE?%tu;~E4Twb zWmebMSzcZu%ZB8G3}1xo$L0k}NK|?4l#pb`pq0gqGQ72TtI3TH8NUcBqQbi|V=iwk zT5ibX3n_7hrGNG;H+=4IIsdW?OR`|uf>YxEM26{KCb<-Wg>RJL%u1i@E`K)jNeXN0 zWKoXA5S1ERH3?9vG3d2#!7iI^tNPGHlIn;HcJARLfB4Zc)3QghB6uv)Z7BkKUn{}S z|Lz~~$v^uz3)7x_I7CNraNjK9taSxOYk=-+^YGx1D8(2gHHji(9dqKuDZcXMn@H1c z$;fu!FhImNaBhxupj6EN`m4`#<3HX&+OyaqCyAn<{_INwJQdtFjWKxP8N`i&VO9ZRdG#z|>NbL=l;Dq525pHnf&}at zqbfudQ1d;i?C_FHE~yE8QcC)R0f!D9!a2unx7{`t94a(d^;mu2dtb^=2N`N>>?X{5 zTS~r(V3|~TR5Ot=^p&8NL8;_Znt1v7sTpQ=OtWk6PMmb4yXMIY%j$5%$-xTw@*=j# z8Lh2jMmeMPjLdn8;RtDb5dDi33Xig$NJ&)TK?eVCfe6y$LIR%5`oPsG%7apAMng*! zL1D_zDJ2*mva1FZ+0kfW;9+^04}bWhJne()9sf{_>Zraw-7HwjjlR z(|a^*%r2C77zBTP*WLX5yMKXR2c+#|wSpoGP}MS z<#8Dl0`5XJ&YYlv?Mn3lrv%P!5D=@jd6Q2@`P@z?<NtU=HI;m%(y~c-du_)#8C`YisP?yBDoBd-v|;;fEitOJie94dojQ2Bc|P zn=%O@SY2JM=Mhm9ao1gUap|R()}%mV3}?@t<$(hS(Q)v}9_HD&cX?}$QM(70T#Ay_ zGd9y`4g@FhG{*Yi6YO@|sFZ5M3`aw{y&hU?=I7>uX;qq#7X|kne3;>2$oleX>DM7J z)`nqpiC?OquA$`|epY}i0>R5Thbc;ghb`B8IkdC3B7X@)NeGpt^t%+){q1lweekX> zD-8&J+e}!L0nv%sVPanSeXr(aKm5HIXVF3-YcC>C^cZ2*!~H5ZuTZs2iI)-I|Bj#L z)Qxx25yK#A=PbEac;hw(GnHorev@TD6Fujg3#h7c?MNlDL&M*F>5I?}I#B{PaU>p_ zkw@qz1Q3BQ@3-Mt-|*7sy_TtH5oH~j@hI=Z?4z-EoBOAh+L%zK7uFD!S+(%sjOUfF zcr|Z*>)SR4#M_|a@IJUAR=^5RKsjc)<6l4fmF(PiA--6wq4HUtBTBK@3W-(}S-CR_ z()ti2N}BEMYCo~zw&-LD1D76!uUm!HeAb$<7q!$#Eh$`%MG>ip*qKAy`{mzpO&rGv zA?mWPLMa(z>I$Pem`9@#x8Hty-9xQZbF1e+T3Ot-%Wb2_n(c`;U!(c^ZFq0nw`7t$ zef7KR>+4}q?;Kg4V~xRDODSwlF}HfAH5t$hqZV+?L(o7 zu4x9^`g%%9E*y!75M9Oe$g^*Do?rgR@0MCn0RW-2Voa^)F*+QsZsD$*`zxH(Q|^Ck4eC!d%LkPj!1FY0Mx0@y8m^*(Njw zA=toNfk5M=;0@pZHjFz>M_cm7o(-m18!|1EKL4bacXgK4tA*hM1ha`b`U? zjdgG1-6v(L?SNJPJr5=?82P}4w?Z-+vkk87G9}Iiy(`yv?drN!@Z@I8?2)vGCI!YJUDmC~{LUlcel4o-f>g7d|OlS-PRxM3_b3TjUZCQX*Zk9s#M{CRtlc4w2NW_{!q+L~4$zPlJYRlH})YKHGPn}|M@mwvvvE9s&ECMYo)(Vu8 z{I_5GDA!;ADdy)2`u#POOk4XYaHp*Gj~F!Ck5$g3;hYLpzt)=3Xhagn^hYCRW@c&> zYF^4JB}q~OjSRis6vJ#tzrVI^1IVM+MG-JFGl#VsZGvWWt)g=?8*j2ytHn1OjcR+> zD(F<1c_n{d9gIQ1~ZmWacS(7f;kFXX@d?r+p!k_yH3ShZ)`mqiGVvjrXramojN@6WjL zk3NRACz&@L)>MEjH}_S$0%`7}NtLX%mbfI&EiW%~%gwhiJu}m)+_%YT=Y!5>n12fX z;f}lcnRosa^K+rKrIVRjqNLg<;h%8@iE58j`>wh+6$q#T3{{U+-Glnvgc=|e06+qz z0_@qj;B}))NgX8x3%h4o9-Vr81`r9%?w&&;IWluYsJT?Sf``Ws6NoD zfKkbuudlCj(@i&V-+lMh8@tK!u7XMvE?mt)kQ;+eZ|tT_pt`}6 zfNHlsnz9d*luMm+j0QtYUNF_|p@bYeyu*8S<;HUe5tMi<$(1HqtGZ^*1>Jm)O@vW( zEt`+GgOX5zqY`P2ah60S#4Co6{pH7*`j$O-Ve0I%LYzG&Cqy~Ja^7J@nH{5XI3tZqWn^07V0YiC03R!m#seUd>BJaY*ECm|zVQGoeQ2hkMYbS+)~-tn;xSzk;ypPcU=9P7tvi9 z;;qA)ac`Pt3v*LYt!8wMWXd(9#Vf$T)1LM;-u>=(m#@LL)VlH>oX_dVgv-9|I(BwP z!Ly|T-dKxJ!H6yG#N{3}HG)i+6~>@H7~4xT)6=2FOsM#blcb#vd7g)sRg%)_bs3C? zLGdCGcWjEU#gii_@TlMgp2Y1tpU{aOQ zmR@MWGuy$Y4cDDyLECOmO$tnpG<&IDugZiwolcN<>G#JDp=SA9siL};oPN8dHc2j` zd7UO%j#j}i(h6Z5X>W>nU7ju?S++XE0H5I7kQI9UY)sd&qWKFpn; z{YPTc$Cr{jmHhy2+(~cKA=ltO)K#q6@S~5UV(IKzZunoH;i4yQ0Ds%)=|CQOVP;YzR{5m*WY=j zx*e>s+;Yn;V?2-T`lVFDcfI~+SUq_Z#4=I@g5btA@f4;&qsw+wTvz^;HeH-_!aTOr zJ{t@Jhb=5d&u}y(%X6~Ps7yRG!%>hxO45{0w+rPy>`hNIJ3EUvp2fvQ;!etZ9O1kt zjWk(*m273ev!8n9<2Qhuciwpj%DIDOlcj8RFx_*{J?z`Jk0ePbilVMIDp$bf!C4LN z+M9Ti0Acf>ZVvaF!}+FW)TG(PB-rg%6-qm!Z_fzYf4`}XHEHlZ2_D>5Gwt{LbUGcn z-EJujZCe3JOdOg|`g@bwW`2SV>BKC}IGhmdwhDum#JfAVSm?h}8)^wcV<)5GOiodCvhT)Ec}|{XI3dZsCe;aXs>t$;I8g}a>7*&Ww8L;XVtRI-si_`H3C=Ap zlIJ<5DCiG|tgWpP$)Mt~J{%AwG1ortIb8b0C!n#s@C7eKp&!2iWcS?8pnKzN=}xx! zaH{_Mp@$wCJB-`vwawofV?4Lo36pMq?fBQw-D>w{n?a?GFlq;aW+pz#Z0C_+!OdVX zscklCgSKC{?ZQ}Tg9YNDEvpkI;_}BF&>B_5R)^!Hpj$zC!?l#bgCL4gDx$k?_{*C< zg`ZMLU$(b|CGm2bFwK1sI&>B5-+at=KL)SEY|uBo$Gtky7vrAN^DQ;#Ys2`CSpi zepaf&vMHfy8go@uZrv6uGjGWABLt=i$nhSv!7-D;@uc$5G8CiA&3rc7ZD0ynyjuE%X6Re0(!cS zH*@7U{{E(a#QCb?*k*lxA4V}5 zj!qQuj}IQtDwUul+Z8=TH@U`0*A%Jg{T`h4}uEVcMbNz=_Sc z=dD^b&Hj2j=(IEG_Mz9FRWzZv&F}5`!=wsgE9mW3B*FGTy=rA_)%tp*nN1rRRt@0V z*Q5#zmB+x;)D*D6m1(#79&OIjMwLyPi6l`)1blDkaYxGx_Opr3|=b=;CU~488dV92o}STT+d+)q%pPnMd&1GjIrdo!MW8? z#i*dJptVLo&0(uQxAR1CP_f1tRI{pe4yj~td)1mO8PCl%6wq2wsE`uXj_?V|}2Zbf8kvtpZv-XsK4Gx)R* z%1M<_^L5(??4%)iJD^Q^&y%wINl2_o)z()3&sxjc+8R?+Q$hEuM6EUd{-kT&4&sxT z)SG-90GSo+R2^RVyz6+`kG-kZLUKstc9a429w9Y9@sW>m@c;WPQPhWA1o*MZ$4P-D zN26-T)R}bUHrNCdh#+bwtf!l#tS&C|=O6zIX6NV1bINZ|cQ_9t1YMnS;nSW2#Q^74 z@wOD^D_bQz!XBulT9m4_oT{Ij0p!e?GkoPMUwOoq^EadZ^j>Y0!ybGU+ad6&yyX4| z5A*h){C_xf-`D9z3NM1rRZ$dJ>lv70Lq@&)r+GF-N@1)kZ+oyeux?y&Jj=5XSR*}_ zkR+u{iIjrTXh^5ir6{tX|EH6B9SNaODu{YI?>T$+EN4!fWVOG{ba#fr6eyv$2VwW0 z8$cd9canGfz?+D6%`?01Sk6Z%<2Lk}CbXR%X@;=X@NVqzC#Zq82~BO!<#zk3YX3|k z(=`cnTQN!}Wu(xR$XnCTZ#t?QIZ=~L>wt*e9Zot-TcC*ejjBaQ--9F_(*K4py5U3)D6G&nZM#U z-~Llfby95Mkw~mDL2=fZ#yxD_BR_UOHxWr)XybH~gnTgKKfUvvyz~_>r*H<13|eE_ zZ-dR;nnVfcc=$Iz_C8LZI?GhPh?1VXlH#BUNuL*+5}hW=ZDUPs7@Ae+qbQ15U0vl< zpZXLRU3AfSl1B5IRPU|v9$ODJ-+kp;Ic^-Y`6b#R#7J1p3l1DSz`gg}! zn`6h1bN0juvgLCq(P2tYGpz;It>UG`+F|)-ZE4_EIZ;YkOSMR$#;6BM zDWuly+P#}3NjQD_G`d`0O}9cRCCkgpjWeQozBx>(%Vrzv@xX!mc*fJOL~FGzgU3H9 zfE+t>3>F7W@0y`+3nJkWT5VD%-O4w;c{n%w&h2)QP%`u|wZe%i(HkFdH<3=w0rVt` z*k%x^hNaB_FxJzxwm!VKlC@|LyxSSv7<=0rw2F{gfs_cLF+~m(^+3A${OY}Il4>d6 zQ@`J*+wHQ}U*8A16=W|o~U;jixe3M$fgJc*C- zQ82aI4jH!xOkq%wVu0Z86UX?m@Bg>-dKxiW3){<^lE<+bj_O??2v&i#4NR!}*&asT zlH`Uryz({t+^_r+9%}iLfEnHnD1ty7%&kO-45?Cn|4%>7U;qB^(CK(&B!Ya23~NFQ zg%hGQMjF>|YbIoIoVGdy!CE*?Q^4`^?|B*D{oOCcSqm;CB3YUAMP(2fIzucq(uSF- z_W_jPoi8g#8BCnK7z^?lkN_j#3-{c{7r%TnD=W(^udHzMO<&>U*AE8$GVd7<1}I(L zJ3{+M=8ZO!b4+!o@ZM1r%jJMwA-qFNg8hIHSmW?G(lo()Rkp0;20_;t5~WMw!yq$~ zs%XsL#FfFJNlp!Gu9PZr4(Y+!jrCaAvZLSwQMKkARdZ4;`TG3_xbj=Cu9Ql*<(Ke} z0-L!0=Fju8YhTFh!Y+!z2qiqiPi9|FswlP^fHyNAAJhcL4{7H&{eHVG)6CW<%_Q3M zf@Z6&-Mel7+#asBwXh~tTh;%MqKN6~DU!5bJ9+?7IJ_}PEpf(9Bw04sOS|{K3H%`hy*On)?r`V9`-!^Aww(bv>#@=jdC47z zj&tQ@Pi213E{fqQQsg+}f;QKL_VFaXM$^}(x;|1VoOeuhdJNasIk&ik)1k`trS4c< znpZdiiO`j*(o$^X&8Ey&&t@4n-*PKoy6r2qYv-4~_yz8`<&HqcQ>7KI^(Y^ZaDp(@ zjw4a~j9Y85)!@GjU`j@HwPdXY5rj#V(nLB6(A<2uvEQT!XPGzUl9v>vT7!2#jZwywe!i#km^1(VjuJ6V~d!6h7yzZ+k26|HWS^UyE%CkABn&B+Ifg z`ZZ8Xe(U+bRtN7^fo9`sZ+HeY!FgK+sW!J^tO95RsOAl7R~hYUsqF!>6)bVm0aY#P zD2kY#nZtV+^!sQn(UBsFb@|_#Q)kWv7n|0=dy)r9_4f*6=yZcgS0$a%CIwE?!)kuM z;N2|oN+3NXQZc_C@f&~eA(AKVMj2cA$!^D7hg^A5k?@pPzl{FTVvQa^-qD?Kj zN!9$=%(DSW2e8HvB{7Rji`;tatw^**CPpEOMwtgRuvrx&N?T7@`HNP%w2vyd_nXtjPI1b&RsmepEUM zUNmLUtGH8@4TQ%6m4uHA0oN5{GeA@1AY236Rl>fF!B?G&(qh&*hjA`A6bgYUeRM1i ztf(dHo7c8txL1MvkvKS2ODvGABksNX>jZUy?aQrs)Bqw%A{M3bi8mY2xn_3173B8O zW*-wbMhhm})T(M$50g+)c-~FS9JdOxW5aZ%vEI?q39>)p9dCaZFaCj- z; zn|M}L@=-CY+sVgxRvfbQ=fC*HtPF?T@TD91^yfd%_1Aw2gk@%Cnj?pfa{BNQgi?_ZDHMX*Bw0Pnk$)`+kq@R z*1KB4vw2ug8c?~)_oY{;VYUxom5hRl=Nt>Ea&6{5h39GXCO!Fp^A@yKElMGwXIzUj^U=5PGQL|>SH(HK(B2LcAQ zv?mCS`?^)+Y?w)Sf@oqcVt(e=KFY7X=RHhy2Y5T~TTxj9jM?u-8*NW(ZIC=^>?!LT z>!-X)pl-q@D}NMl$EaaJ|a1!@W6mSYlEpidAyAv2@**v)SsJwuMnE4oH2?rC@bwnG>fUX7|qX5U6cgfjnwh>vTF` zJvxrb#RvzrfAk|U#oH~ONo}EKi)vDdS8e)s6|27d_B_VX;&e^ zK31V3jZ)$D`ojUej$*nKF*7%dQJOP%-i5K2NGfD&z}XC-)n^^^6KDP84GibcE)MH{TqpG^M_|!Gn;Z*H*ZWx)LdzLkShoaKW#aLI{p5p5gVcdL6rV zFOc^a>BK2{Zff(fdX^}B3p~((!Fy55w@>00wbxicX~p$HUHy*Mx`wSblfHT%l`Ww> z&xw=@mJG&{+Ylrw)_;`%woT^7T1S54@U>MIZ%a>{mO6lF1kUDXY9r5@-HY}hyv=oM zoOGKJA?Yc&D(fW7(N;y7kuZl1NZ zbyn9_n3Rd#x;I(ontq_a_~o&H2z6L^Fz* zKDEXTx82IZMdx9i-?sSj97iHF2DtK#ZzMgrN?`_cQiXRx^wGE0Q>B{QPGai&YscLy zg#e*6@z8MNJ-2}t8xEI`GVuJy!UG_aVF;oK6;jz~@23gLXO8~rtXv1=1&c{cl8;J8`o{C4(=)oZf5jV#nFViH>=-j?`K)I z$zr;?FBLhia@WlByp;9`fuovVmD`zl`}f;o zitYJK8{)bZAfWBUHi_+SjX^7o6apnB&%XQ$&U@lzoEZ-IlRy3==B8pq8ev4lT5dUU z>?C9b(g(Ps7i?O*?f2~|TjK(Bq$!N4d(KVY^s&lNf_5IXMk81l2!8Q{ALPPkJO$&+ z0r7T06gh+SAf-YHh_Qg;4Zrw)&V1_ch<8}}hJYhcF|Y04+39 zNVJSX_AVtlj>(3jQk*Y1B}yq#)gfC>J=>K@lgv1_cgh)3 z^YWUl5M_bbJi*m^g2EM{);#A zLvMZy8$jrCV?SPIAOO3b{S@TUB}V;0_#AQ^SHI~XR~u-hG)?JtyWxUYC8B`U)m4V; z!TUl>ReLr(n*2v~pf-tfTL}kFn#;7Izgtx}lUhJqWuqGe!k}imJL>ZB&-@iX`1W^D z4A&T~Epzb}nLSlmo%bjNAGzrt_>pga1>K!JqSZw#(WY72BehB=Wtf>Y zq&lLb!Z7uXuYLo+`Tu?-X!ZbBv_J^Hl+7rQz+hap;a-SfSu;uH>%o{8ZIBcX=1>E%hR)we+HvdbQg& z9y{2^c7PZXzzh(!kl@D{0-g+n$s_?o$RwF169(cC_H_sW3}Ya{fQ{`o-W$8!?RM`{ ztEE;iYN_=~?{eRJ {XQB~*Gsaxl&GtZOI>gUlT^}F1A&pB1~+rCRWjPGdMrDsoi z@TbJ(E+vexf5&xAVVRlNrj?Q^6$cL=PWU%hoM?`#ays`~LVpv2}5g6AwR3wYG_^$BvmR6?QVt z`nY!nDSz09Dx<1vZ)PNXwoH?4HRU!2)i2pKDLB0QIzIHo{ceWkCB3cWWutRdTSH;J zO0$yO_uM&Nf9Kuwn6Nk+bD^l|Puho6OeDRW(N=gil{NINpl<|658uc=4}Ko4D~y-% zmXW@a@bkX(zm@Tr<4>LB^qHqQdFBjH9zVgEGiNw`>J+C=pXS2TPct5kkk(T6`>3Lz zSM(T`eQM*lHnko*K989mc1FOao-im&FjM$xT%pHRW(W)c{imc?ZW{(Dm7K{IwZ%1l!hulg!TE;(!-(mg4=J4#neVmgil|M4{A-p4ne%3(Hy;*aVz6mK%@U z#pcQd2KA;p;Dz(7&IR}`#e-O)q?y$zNhu31Ub@K1<43{OA*9FIPEg8T3P0w+#B#q+10f{PoVwd0)>itUSwO%QiTFWXYE71GJdQ)y&b zFwr$i3JT9VPzaPNFj6uxHT|-O3WMQP8pF>AlvLDKw-OqoX<8)~P(n~mT&3Hr&I;#_Fk-n8?t#ReNlB{m5A(W)(7gV)IhU`vCw5hPRXa&5Or_xmh6W!m|hW0HW zi=`0K3l73IdX#Hpe)FCW!j44-#^u#oxdEmU^1qGDj*Z0iM8M>Wgbdf769kDwA>doy z^-ikuPt(Ux*JJ9!VmBv#19flGobo^n?-fE|YJ=@VxiH{+e(?J#c3saSk3YiGXU;HQ zS%LHCnorp4FR*3nGIcefEPGgO*v%s2W#4i&79}MkGj4bfLRXa9t?Q}jl*M4sliF3= zN+N~AYE4fRm|8pe`BKt11!APBY>gFd*s1pIC5fP(R8Y9KsR?TVC;n$O)ViirMWcbH zb?vAx(V*F_JvVCzfg?WO)4kH%NBo`^marPzsLYU2x7TSpG)|?3<{j|4ppbqoB^Rgr z$3*Yh1S4N%3Mu_r@E5DgG>o0S@WCc5O*Ge*8GM z9liBsDT(ls0?0MXOGsNWra)8`f}(Q>74%_*butK6f>1s)t0x#;BT*hTTO z90RJ;)h`?ZImm8qR*@S>r>`6Te0YdmdS0PaO;K85xE+X<*4QS?5JouYr9Y0e7H9;* z3IwV-U~_}PTvZe@JtZ94XfhrS_aP zESsb8Ods9750w6MxeaeI5^CWp8U!feP-B6_S4fGjs`ffHHD+A5pjjrW46HFOIq+hC zMmlJyF}4u~tc}x&!dmy9*6BgHq@|vEoVO0r=^HwQiCL4f8LI>92Idyqh%>e`_o>uJ z2qba4F|C~AXO(jljT5VwFP3W+wYmzv;xrMwR#;l9-&TO|_l!p6!L{6lXwPtBN`e36 z{@RPyz3QSL)RU?;0#9N4A!vw3aoSP{#UKCi2RL@@_Lrld)aA$d7C3a^5Y>3>ZPn7*g^XPg4(p&-(L(FM6oWz%!o zTwT!5++3m+Jd&1JN>c2Sh=}i1r#E@@I`Qv>d6P=!Cji1&Mrev&$u?8+UElF{_=fNO zPN()+D(B$#-yw~W9(g0I7hX5se$=`^7XmHXo!RxU8bhh9on%aJW}RnzkFax;KTIV}RgK$YyUC9k~g4*vPS|LLgBWnAm} zzXx>JSfrIr6@rx1Sf`#Uz!YiDZ5E$a?jsK3H zad`GpN>rhc{*M(f@yNHzXa9vN=nb68aiwc&qZ?D9>7ij80$olfC%j(JUvfr8t|euy zZT3na+BMHu8_)(}XjFvLH53PxfXGVkN3K=V9JW4~TkV3mu-$y9l#i9p2V*XXtGsPC z0qWWp>FafAL*-1~(x4Xy+Bj)QUrTu(4~c6hrmbHorCVp(IQXz9R$3324}a3uTSzQ| zYhzgFX`4NUmZz<-^q%F~?^3uH*W-^JN4_lUkC)iO+Och?W6H_`J#pQSoS0yE__Z+% z`hD!U;@$7~9{$GHzKw5r*E<-EHd$U?W@CNK$3FE5mKGLS6a`w=Srepm;pP5L50SK` zmTri7opjwzHa8?)zNcpTK9PE7h2%UU-fN9)5@?kDuoB=~F!R z_~V>={&_B*zQCo`6~^@@)#e60r4T)Xtw$_t$vE=Oidz%0PV8{-y7n#iOG zBt&%GUV7Z<*-AM@1DQAjHx`XiQC0-0E=5mY2Yvk5iwWUhdEDpt+=f=Wz8%9yr%|iHqqEiiIOQxJw+2?hkWN%iFUO+rFXQ6NylB9{i}Nrf?>jl?K{G_x%K6oHfW!$T$7 zv{!|s8c$G4Ff07 zA?OeKFf3R%RcqtK2X?FUlmY`>9FO?S=l_zg|Hij-?}PW#lLh0=G5xZKHo7&OjtAK( z6Fu$c=H?P9{4UC)@UU0e9t!onhYGGV;ANv|xM ztho7nLa>D7AHC-vbL;Ex#@HH=7^Lg93jxylxr9X&?&~rv0snr_)rO~^Im4xu6`p&&B;?|c;fLBJp1hPoPG8=*3Lf9c-;va3IYB87J9vsey_)5GC^3w7AdI($Wmep zwrH3q$&8>)7w<;HW2t{a>pGg1Ub*T6kpq-n*{ zh15#hOF39^4t|@%vUd$J;$Z_)8CQ_Uu`XAAgdk&zwO&x9XrpIPt#0;*g?LUKrBN z1hfD<(NG(DqGZ$?(N_g%i`5z>6_cuJve;hPqn^}l8Ees&UYTJ%ThENnv?Ee@br%RC z{(4X?Fv7QXv_=&L(uRY-=!AObUNbAuL_yEF*rl(y3jK)U~Bq1tm!%gk%!_IOAhbM5I^ z3A>BT+eK1tL=_{Od7@#^%`uS@XUt#u#YTVtbs%m_(x|VZ)r^2PV zpq+l^SgM>L36c>H%_%>3Rc`UW;{!YVek?-Q&Y$5)vfejyvNOn1r zrk^7h`LQ41 zPk!}xQR@a>Pi9z{xq)(P;RHgNoi&mQ#xc1}DL4B_IT`W6o$@MTFN3t@6b}c3wpL49 zC{r3YCH@@0_jJ&n2EMpm5d06u)r5Y(KW)u;)J=exhCmzNlYYP7ctnSLt)k80F#2}p z0E-93aW6XXLaH#RtZS4H?#&=sMA>WLa)h>qM^~AuZkW%3q}kj{F@^f(ycuGDn68R3 zZ7;?sxt6y@5}?EH1SoX;48qTc&z&>o%6*p98a5}fpJt#zh9^y$(nB~mkWB$A>9wV* z(yoyJ$7HS(E zz*4#y;0)JfmhhKKh~$)Ya{;0YNfswA4FOoTlZ8S!eoFj|+8u?$O`xrz-|MlkH01b+ z#~oRj0{b%Y2YCrI5ck)fZ9AO2vYc(_?^e;zKw+4B~}TRaKM4+%HoWl=)i|rwUY*s{dWP2!*3wjheO5Jj9(W?x z^G%;Y4g#K&wx~RuH*IO;_&GVW-8|os^ni`qN~!Z?ZXM@Zp}A{_*K>NXrO@;EnY9#O z{cu_d={zj7&AR7xC6y_9DmQOw5Jj1)D1N=%-VFCH^&d%%q?#l$RBjoLOzyMhTA-;Z zSr@P+*Hy@I%^I*l0$bGDwC2gF&X$dAtBo~WT3vPXJE6cslCO**y1(!{kKT#~3PEGn zn42}U+Az@}Y9nB1njMm43ArKRy(}i?|y!LZ4E`~z%j;Q+^>iVB-msh zJA5;n)g}c4r}LAvY0`dgYlCDSLYlpIp_Xzz#oVUtYJcSjQ8_v0uEmrd9C0O(2A4F` zQc5+(F{w3Y_^)9>d!4|wwKYFu%V(guc3s>OONX1GqKOaIl${?O;Nl^7Dr^^LM``P6 zrVp-7GhA*REYnF!i$@X9tm5|I%%EI~sFaz)M{|AuoGNVYpiP5tj=+{{V|Agv=FLXJ zL6b`7#NQ(`C{No|xgggS_;Lyet>+eBQ+P%l*2uXEdLF1DZ9V4z6S;kxQ`$`tQ`z7a z&`>@(scSt`sm!ykotHGsJA1lRDRR|M(+!X+Yg{+I#yI%8Ykuglhq&qRO(-t~^m5Qa zeF;o-#~|LexD`9u1Z&Zm%qurYoHC?c5R$YPajrCvGv3_8?SjLmhd>wlD&?A_L$Nrx zgg!MwP<#8$a7Y(LLBHQ`SD@(!PE?e+UYzN~$J!gn$)ZKYpLIRS`aa z42=#8Q)}I@q~n&C$ymb1@*b&&bSy=Ys}gjrG12$K<_!mCU`AtXHYml}b9$eQ7cayU z3>S)#|Bh>(*$tIJjib< zXxe3p7Qbg}_$?w4Piz*E*d-h|a{x!CNx8OHS6eXW8an-dfl}`8E>-O=2yePC)9NCf z3C69rT>Gxe#yd5gi@(-*!sGZrPJlBH2AY*}u}*+d2#Q{xzxde4{QKCJPS?vifPl+P zmIsSaSCq>6B^a!C9W--i5?xtQ?gpkAa{M5=T0!yO=>|zPX?ne0^Z(&s4yIRO{!o@> zQ)Se3&Hwy^Kggt-F!VAkVY7wh^v$Vu-4orW2UG0Ii5}3(UeGrND*t#;t zY}G2oOm&pgE6N?7;Xul@Kw^oJR6#nYT#!3dV`n{M+6?h@J*9k#92zQq-E{plL-}~m zWb6!bhh{wdZyoruyG1nvD@ zGV3wCc39U5ASg}%rZZE&4s2+%mwfy$KJJqX%S&+KczLw2gvT8Zdp$7FUl^b#6Nm=9 zU7Ix*P`VHyF(Z5)A}p7!q*50tgf?cRhXoS*K&P#>m`(oczy50gjK||fODNT%ieEE_ zEQwz;Z2_c%>0A~RXPxmNHf^`eLx<#sb-8;R9}Mv!p7UGJJ-<{THyxD6xcjsk?GnQ4 z;$y@^;uJca3zUu+=d6cqMsc7Ej4{);@Uk+-OO>chJ2%%}%0ZG_*A`^ZJKASyV2jsV zj8f`iDyOZXm(s?~wRO^JH@I;I=&#AJ!DnVL#Lu`*;%tBBDIqa%b#jE@mm;c|4(!vG zRvKJ#fngpXAQxCtVqsV3Mk$4{2BQsw!N9$bZ}l4El$`Im=cA4fBxZ;5FWUfOut)*@ zvIoPGqF17dg3)N?ygYpQovPyIqIP;ybARRy7gGh`xL+SB3<)3b6~bz!K-x*%CpUt zY}nDcmR|h)a^I5)7sfJWvP;hccqt^;6uzDYnp7jKON4RWL6=)s?eDp{l(D8kL(KyP zII?2AUeruL587*Swc7;<3G1+{!p_Z=()WwkVD22s&DFYQvt4^8OC&}#+`6JyQt28q z(Fl)@6TZrP?zwYK(jw&*g2Ix3wT51=&+cokVRUJo#f3%JI`M~bAO)rx{yCCOd|;$) zi!>sqFuX2jv79eTWnR13tZV01D7vxi!p1;vsEZ@r3se)lU2w0^%v> zW)_fFaZ4zNo=RI0Gi?#!TRf08n^u4;A8FLWpEYZ$Phv$J;W3kj#J#EDZFZJH# z8y$orGopC&4*Kvca%-X0ul940dD&nWBs?8@H|V_t!IM^*UBHfZWh5I<@A&%q{XQET z8!ZB04(Ji1;bLfdI`c@g;vB@dixinNYnukY6s~Vu73oY6^4=*B{5WWkV6r6%61+Ji zLgd#&I$+QFisW1dVtoR4ee2F zsCA7JvXPm;0%jnR8Yhc<T0mU49z!+<)? z_~I5%+{Ou?CpIVwgV%TfnEG6#-T}=5_HbaKr2D&r@D<;yR24J_dCdV4TK)&kJ@V#S z(tQr&PK8EJ-TK*CECv~8eqGN#J>*kIxOBLm0x(*92rp}%16!o`scRtb{7u~JU~JRF zPv;{!6jYoHwKD%mu{VGWLWLUJ6{H7axbAdsbX5~EU?lrF5->_GxrqP7s757ZlT3D@ z6r0%t0)>;?k*59JY7;}$ohJu~nKoEjp?4)pxz7^h{6*nhIkh#dnL~X2=~@i?GspjG zT}J{$i4)co*dYlfe2$kBD!C>(5)z96t5K!o<)X|hU)m2jB-UGA{XbA?&Dz>U?)mVC z*}MM$|Ics!2d+M}AGtI{^h<^d3rHUn(soQdm z>FnR9L;3J}At>a$LUN>`@V@DSNx39l1g7x*@xVOJpi<~z`gwB*tX4ZElR3sgAU9)) ziI2HIF$kbJfTh67;O-_}KU;g$l>ZYBTM_=9nGbZ$Vde#qTuX}#L^usBIiy#bRHT(r zT6uNNPr45K^e~-=V9W)h+$@gdSYG@PTHloD0CAY!5o61UBAa_HmnxRuqV{EgfYG?k7B8Ab>!IS6E~7n-7W za)*0Ydto|+CDM>$hEI|9!E>ZYq?aG})k0{CbvfY0-Vnx`hGaU^t_gkpWC-+)8mU|a>Aw3AYD%f;=#XyZ* z3o|9KruR6g4_o1^ji<8jWMR{3t1HX`(geFp=c=m}8QNb{i(c#ZL_#9f&VrkOj*|0{ zqj7NPq9b(8?@~>yE_Qu*k22Ee!dey<7WmYsKE>O=;TvBz)*vsT0uc?Q?9M~CAiQUS zTqqEF#Bl8*8)q*tw2~fzdQvq`T1}Rk4FA$YdfouD%fuzz>@*-W8>9njmpk0j_D61m zr67P5`4MMg@f;;*l+*Q^DN{aoNadio>4HobZm9Co12=77rJ1kJu+LKzObFbfkghc) zz0jjC$pimK8fKjF(#$c(ZRr|7#?@jM+_Xh7W9kRqg_i2-qtCM_&OtfT>{T}HGuzBe z(xGtfnsZrx*VnpKgwy>L@4d8oNe9Vkr8&=oqLt~VsH6_&cf3#I3Mfe4OY1=R54&?~A>2pq#vG(h?k$trX1byP;A4htNhATqO-C7IA z36-r&!~gWp{s|9!CC-G z7b7?g7%Aj8ivsFk;K#ywDO@_Iz?zozIYG)Cl4tHrMdlZGYTT8oE_Z<`VlrJ93^wNt z(}GktGX~JcqQsQUm;yi289~}U%2h}6JZoakL-2nT(fg-sD2D_};oyw8axK-4N?8?XDTVhM<*gD9GT8@-bv^4jEt@1T{_wf18{H2eu>Iw)T1m>^6NWt-E zPxC9k@^kFnzmMPk!}s&)4}O9^660qO80)2qqgI3;4916a7*YoqYp>U99!6*zh3qE` z=ELwamqkh`n|4);#Ui@VMDatK9)tG&~Ot4~pPU9F(BBI}X^$!Uh=pQ)0r zz$)5CT$Yx+O?oKDqLf`irZamalFVtYS(|JCN%wiG#@#iqm@(5!TAwj$vkUGUi)%J} z$NRxd*B$hFC7aa-=U+HSDTrf`!GUhT+}s_nU`MdG*%7#|YI#%=4&|OgaqN(*bfAU^i_y99BBs zJmFxSHyk$^mS`6#a$W$42a!3AqZ|UJ%P1(#R&v9_Sn@p$PU%1|mm$Wen%wu}7F({J z(qcC!ErKp&QWsvoD=SQy@i~R&oactj4B6)m!MhIGE={(1Jdj+AC9OWgzXyZC3=kq$ zrOlJnNRy!Wu*;D=)6YH|05WWOG21#yrGVmRm9_#MR@Js!ni+&u*MK^=cEe`~AcA1Z zG!K=Po3o|sJ-lYFRoVm;KkqRfX~-PTR96dZW(||qYg>JBjnT#iFPHybLIpBKD+Em| zD+FV^$^ZA~f6BN1t+%snaa$whZM7Rj#Z`pXx~V|YaxT}>3BS|y;e+u?=3s1XLYW9B zd)=h24c+N9mzkYhuFaRr2)nolIXUYt9!*OxD}nu{mZG@!t2#zDK%2@GGVtkdBPf5+NZplI!VuY;AU zTwJ*DB2S$2_j%)cmkx^410$_?((0uVVocCSfz%lf z^h2PH2kfC`B84;YDW!7jvV$0w`>gT7mCluNgJcmL7Q_5NxWvoU-knp(?4iHDzTPrk z$_pc3)`gxPq+WG1j6C}5?aOAMB!oM4To9K*6_d+nlvi^Ar>(Ppq z*7IquL*Niz%JEKWqaFM`pdJ191sM$b001BWNkldJ90;&$Y`=aWOdH?RT%KfOExIwBu3I!XU^v&9gL?#_VgK~d!%d6bjbx>&Ydtf zY)D_Bo%Fd2Q%)wiyS(5R`K5t8`z-N*cL<+Pbd9>@A&x> z4vnDBLEG;GANT-{!~a+RU-4i23&P?LFX#!_y=yn4(F)Q^>I9w8Mas$y5<-2 zkQ6zzM%q3~ZC}%}yvvq1%@Dg@GY%|iWsxE`a)(wIW4dW0Lc`ODuOW3;yxdGDcR+M8 zepBdkuD6~0cgpfkWg=qh(=OCi8c=fJgcQD;OJL%AG6VPR_}LWOp9^v=n5mLY1)Sq( z6@rx|Jf`J`or4hP60x~MYA@8NGa!_7{l&L7R8tn_589bkl$gHm z6fHe{wqcLO=)mrTEvMTBPBup>)f9MfyPYtL3CwaaZNb}&_+?W`NVguGZ;X40##->I zxNf*Dy?K^XPFB*tkCfQtY%9vb&4abYPHH9_8;mZkxg^7zOi2`Y8{ROxwbo)hOTJLS zj>5Hkb!B*Q<$}-V?Uhx51ZQ)DMFG3_U(3la9QQXu%n$~12UKo|9S^K>E^G17Hbm|8 z(7v4cOV`q)NOGI2t8bg@A?IcUUD*FL zJL>XK?vjB>TP-=bYVNS$w~F(T29UN(v)Y@ zv%X{gl>@Y>FcXaSX$-7UN>Ld-1^?iJOl95AX%E#cWY0Ma_>MvC2j9J-hmi&eR8@^I zjt6Hs_c`+{@l&%q5>;0$Ey=I#!tYp=N$UDp&viSQoF#^~&V zPumY^mK`6WX^%U_%%>3AG@I^%8K%SHt`fL*|>E@fb^RBzN{r1~= z)m^V(-@bi_GO`-3YD9o~W2v!J)_Bb-hYoEjTmLghj_u`3U-~qIMTt}edOUGejWK9l zdlvijJ*1lM!G(nd9((LD{@QEa1n4U)fHY4^0EUCt9i*yj24$}iT@+G6qNy}b$0(P% zrGX?~fL(0jSTJzj@U82BNDtVV3@@WY6+Dh@f;h?@+Fk0WIi$%vSZRt^&p~O^sw2(r zg3Yh;?r|~vI_GkiLb6j1OKbk*i=X)W@xf-HC2W{KeBIAsR)CE*XK`7171d>{u+(ZGT#V<;M96or3O2h>Z z-zM^&9LDOIfE%iioRmwL2gWX%u7%~>;npG=r@f?;5V`hQBF>Z$UNUKRpOj?@0_XSP z(TbDFgu1HPTw8A-|2uc=&?02h5L|_-*N-n90{=t<{Hn1Vp)kUf?y2! ztc7hD|HA9<2{4T$i;*5F!4&&Q)_waZ(Z7xNP2eFNbmpYrZxbS*WHOGP#x6_;qnqnDHazO>G%6tyW>>JI}nt|y2eUDVO%Rv`LI?g>1H@S?mKU_NcKfY zCc1Vr7Tnozy8O*N{iDZE9pa3`y1L-SolV0IE&l%$ zAYz(ivTf@&kBAURZKyrEB2_p|TOM70*In`$T_!*2>!txG?W4zNp02h{S5(ibuVO=a zYMVZ^%^nQ0bFPt^Mx{ug+_1SzLL@gI$+_$`pUb)(9cEayF)n}vMnALUzFc+II)sh! zO?S}}wrlRWwde@;YK&=>=%Gzy<^+c>$aU9@C?|c9n{UPa{CTc^^Egd8qFCGl%~i== zUNAXMQ@CgGXHEUpMbr*#$=J(8C^EB`av+FY3$W{&(<-gj+M$>N>QM-kD8LF_Cu-^~ z-*Ai!NClH>f*ns7R})r!BC>U13)fw@pMy8-=e4hWEjQe71BVVBVtIL)9XocgecLw5 zUeD1DlI+)HnC{bScd!8wbJ;xXQ~*8UCrQFafmKqv;m{QL5P>Y7T^aH8vuC;Q-p_IG z=RU_nUwW9;bC)>z< zFrBt}=J`u>1%i3jon5n$E_L5{uonOkp$#V+D5RTL0SbIwe|m%{g+FZ4N~@uf^E)J~;{RE@V|2l+v}A=Xi)LpP)-> zq}3+M1mpJW+ZJCVykz*&TZ{BxvbBqAiH%A!lgU7-GJ9h5k#zTkM zw{I^u+;Ag@4%ihuwkr4ARRhP zf)=iQ73M7#!KRWZ;M4bho=<=Aex85+1undJiBpfCVCC5}oIiVxvzOKwZB7sx`m&}s zfZ;-kF%~Hu;KelU-YJ~K?U5-vzN#vJZw=T2YbDQ|Jj-OfN!cqeduG18T38Xf2W#1~ zWs8S-NU$2PltoD$Nn7Xo$?3-K%Fbvo-J%=b+R;-^e<%KTO6JSyPIY-Ir-w@OJ93J< zC(}ZjIS84RuuiY1E9gx(LK{dhi#zIofQG}pL8iK|)sX~tF6+#pu~Nvjh+N$)wuNwt zTX^wxnyB^HHLL0pbW&99v<_HnQBt8X5dtdAGSg(t`XoX$yFFAiB5Ln8ZA~GZ@ZbTC+;TJf_U&Wqwyjy_fQ^w%Vg6u< zW{(mh{dv+XZ!r~tWh$)L-q*8`X)6RL&pgYe)r&lTeuXE`oa6L~lRWm&!<=~ZF&;Vj z5Syb-^mq(fGwdmPWsgEB%CcZ=op#lr5DXTeswVVH!DLclt7SGfYRX=Xwi;s;y@L1qcH;$l*>gglo3ZpA?LG23b2u zT&`a`&(W<>-wjBgDbS@Ex{^Q!XAe`+YD1)(Go25_=$=%kDxH(01Js;|ozNC(Emr1R zN>&PI_gfYYiR8fs?(g=zNFXT+g*IN|zL1#OAcVt%Yg?gINv(1HV*{no7$Fc!F|I2H zy#Z*~6CRH?DawMfKSUYBSZGA09l0#Jm!*hU)EURVc#-Ga*QAtw7UtDYeIGc@g-zTC z6#|8vIcNn_f0MKwl!GScW?Y5$fmRZ=cl^brjf!%xd@aosRhGWN$ za^Ub`uDa@~j+9g&sC=L>VSz;Lpa4hr?IekxJqVQbuOL8}+A-Q|@57BjSlgF@C)}dc#wks9@IG=<=eZ0qHzdsA z{?n2@g#&lV7^E=6T&pTS1In8%rCC6(#bAvia7U0AfK5K1_xsMZMK4mts7 zA;D-CdL^5a4F(GX%4)!c$%sK;ah2>NH!BVvzJb@j;SJnz*Bwmin&0^S_wnJ6eT419 zEv(6rJK%jg($b7BS|@&&;9r+4e0c4>XL$NL- zT^iiG$ahnTnUFwCTOR}#zYm~}6)v)V7iopjHQ(z(9i|An^zRvFcT+pe2FoD7Aq&+E zf&+tEhHAkoMsPnrCy$@xk%zy;iQ^~u&__PX)2C0fdGS2h5o)l=a4=vn7`XXR zJ!1Q^pxCy>W&VEsR(0iwm{OoC-QpZ6{~4#x%(U3?v-d-yjh;c8283W;*N6yJ8dvq! zw|M)50jEwq)l^sxC~}3&K!o4i;lEuwck-e+PF2?w)=QPBL@iYW(-b*y zN{7wd)q786Dsme+*LKJ)=q>}E^pH%owB~8s2;Wz2^`RTtf+@o{{@kTd7-_tmfnqRN zz@XXOSZCN@q7)@{Wf*O4u(WL#E1Q>)C2Z|2U|w9~O>g@ee*O1<$4N$G(NZ9+;9I}@ zyAVop%a^@|^+%2)7&ifgh}f5#A$1MnXIf1@Ah^URBDckXGn$h~FCo#MDNU7Njn-Hx zTi!0|eb1rQa;?WUbk{b!nJqK?% z;9Aw8Umu?XGhCp+6BEsVo=kF>wu}nnD^*>)c{CF1D;_J|yJ_jJ2Lq-yjB9xG$x}S= z*u#A8p)c}@kAId^Pd&xi(`R5~M6tMpQi7s@Eekydx7CJig91-0*13NAJeADUrZVT5k*abU&l8DTa%oUX17hDOR#!(r{8xl+w1o1nfA7;OBq)clcl4^}TGajrhNmPBfHtlLp}oeE zlGxhv;HN*s;iJbm|LoIv+xwYJy-RN?cQCi0t_TeN`C5rVAT!vs^d80cTL&h!hjJQg z8{xJt|CX4@mID~16=;65MHN|QARK3mDN*insIVO3FBS7lfdW%=BwCtO0d5@6KuR%{ zF)5TnnwpK(RYuyfscQ<=XZLm2a_rbKZo2s<-uT8ha^TQ@_U$`BZ!kcj5M`T3qkZ

5H*mMXYBy+qIVpODWKvHWXus<^o0%4PPHt%mRLB#h<9$>V%DbrM ziJ9qME6b8EKJb8#=&tKiDE0EMKmy7tCdu4!=m;O!*hKVtSX)N|bE1)EkdZ)G(Cbh2 zqhgEO_^?X7Cc66D;Wgr3^4!6tkQkvc)=>BdA1GmDg;ZdK`*kEdMCX>A0Z{z zyy9*yojO5X!`Je5R@L1FFa{kiBM5Z3|1iK4N3E!PtlY?TgFYbmV4kzvB*Wz4HzZ?BCBVM~<*% z%T|Vq3k(KBdY)w0RQW+)$yzrn&{HWCH>DQM0T{B3T3VzPO&6jx#<}Ck0x3;HVibPn zC#CmRXL=x>9cvyx@f`p8PyU3{XHIbP3-@yB)M?f(USgsRQdjhg!ozw!7eZK;iVCYH zNVR|v11`LHj#6#q=qnbvERHS4sl zG1j#rn;BDRT`5<6n_7DZLyas-9)9>y_ZZPA*}FoR=tQU;|KFBfJE$y3EIlN3kkE+m z$wAbQh>aPyhyuZ|%Zw-oQ%i$GN?MFfXL3;3;L@g4ffjDlO4A-5OI0GIWjvm+xG-cq znV?h;YeXZ$*Y6KNImJ^e6x3r+&T|fQhD1_A2sdo7w4jkqkF!wRcJvOeIkXq6bmg`)VyFc@acvGIoExDkJxWSR&!}%(nWBOU ztZQ+U6b<~{7|rI!2vgT=)?)w`2Ll%OZ0D9+ZsG9Z!`yh|jog0h7~8gQ=c+w>*s{FL zQb0tefQ5Lb!qn#3nJj@tHV3CrE+{%Ig+v%G%0)*;0v>qm z6puajC}*C2nkOHBl9R_z@YKnZTv)lp#fz6%P#a7tODPmRE0_#wdPPC6lw5e>EPM9s z=B;miE4y~>Vq;^24}S22oH+3ed#}5m(f9(!j9FV<;h+AMfOukYA!9I|g;(IDxI}x-ocb+D(z! zQ(BQUs=vfld$6iDQR3}qQN~kDl1f->&BgN*x~G^P5+Y%cc2zOy>ooH6O1U|Nc0y)B#<|uOVHLx{ z0vJnAD#WG}SgWmOX?Z|zc?*N#kj?R!r=NM6?OPVzFih9(An`Mw_&RE%qXW>%ZHPko z%tvz7)w@HV$0?**c=H{1vbNYqof~uP)}shx(aPkiOuBAa1WzbFW zh%Q4}ls=J>2l?|@xqJf(F)c$A;Lkwj}eBV4`wo9va!yVL5Wr+3rmu^ z8neDxv!z&MW#s~|c*QGt|L?tz*SzMnGuM0H=O5y4{mpL&VGyjNYt8m;+uZCmFy1E; zV@f17noaVqi~wTcx}AHVa&qpC8(Y&y&Tq`zj3Fhg)ynh-ufmE z-*_Xp+;R*1Z#vM*`W}DsB;Wn_zn4${#mDKFrI*JBp%WWirX{aP?}Ihmao1hVwMnlR zBx}vT|E*u)U2l0Cg9VqdhD$&D#8Z6JH-9}fnm!7l3V!D2f10I5OI@vCdRsAO4e7=r zD3@Qdw7f*MvJ#<=>|A0}s)LoAX#{kcm@=fYEyQ@!r6{_~L1JTj)8=qg(v!e^yUVwa zLb3rk71xYS@Qf6Ev_?cn`z`!VS@f{RQVNOHn!2j7+OSz|VzCSc1GaA6%I@8}x$e5_ zxasDbxqk0HZoKJ6_U_%w%{L!G_S##~1XT^63LC2%DT`1^w5vsdl^zWwq;IokR1187 zm~wNb{Emz3o4jyom9x)3%hPAh@W>;NbNulqc>dY5eCgqbc>0+$Fxmt&M#?@#Su*Gk zC>Jz>0x1fHRE+cr!otp-JJ_oJGXD;{PSn|PanO9&wk-P`U?vT z%bH8;Ykbf5elI`yfBz)9u6!G)J-@o+uA`iK`tuw-_&P4G39NmN{-Ez#*jhUXub;hH zBM?ZcYRqtPBCA(Q001BWNklw}YD_fi6Ciq$&wu`N+P7785RS? z`k1@#ekFhRyZ#PueA`!Itl`6daSy-nYrn?FKKclD36qqYvd-+NC#xDx|{Jf<0GXwE7_>d%g9sW;9x7<>HH6y0psi$DiQCpS+KI@BJ)KJ@phXo_ztvmt1S7 z*QeK$^oKo^0#ns&D=o4=#8}trG}eG!$4q)?vx!tC6Fuf%{p+9N-S7IIS-yw=yjH+J z;79rSUwuE{^Y`A#?wx%O+;FW69!C55nPg?HV&&om_Ffx&FE**F9v}b2huOdXc2v=) z==CD$BulRZLq%B(8V*riSJ=9qwxpVb&Fg?kg%lR;gS4wU0vgZ5ZX=JHFvn=z0}IvY zjm6bUoT%uAXlWY#v>0@vRME(}D>aqfH^w3rp0(cAlxAGOQOeB+1j0aBxErl{l4?>TtfJTNF{vi>dWvdnP{I!`i;_Y+ zK{BH?D9b?gSl!&j3c<)s7z~EkK}k6_nA$L?6vqzi<<~y^0j}P26;-8O2456>(>H!2 z-~3JA%!4ORbH}T0XXmyh?70eE)(Bg;0Kz~$zbvmd*rGrJMq7jgMS;cgv%ma{eA%%( zSYBAdY>s9Iyh^r=8C;KCI;jGx9=mq!Zs4xQlMtl_BWiy7SALV>_H9_H5vJhWc+E#y zrv@OT8`PUk&{!sV%vFP(+;Q_h7o>&8B6;As=g@1L^tP6aWr3~?MnHi-pvAOw&OuCL z+)|7hai^X2TrjUL$9(ygm`l+$yl=$#jPQ}#pg9i@KUmhl` z>10+nwRdXtsHA7g8p0gG{ghE|W~Qt_Sn00K2X|?WbFLGv?Se9Xt}Uodjjb(G373Re z?K%QN^4?$k5B&JQ_!pc%eHwJ_c70hg=r6NvC|v&^%l1WqSX_#pk)hgLr;hfk)&^^X zimz-xZ!^JKICktN_x->{kpf|B2ala>qIxA*%R9g8>-edE^K(4*_`N)N@29D1D3m}8 z$#4AbNBBG6{2gG|c>PzsfqOpi2UrB9Qe1bf;^tfL^;oh zTaIw<@#75ped;PwY>lKDLZ+`|iMA6Yl3I_sdf#=v^0KUI%O8F8WBlzmzY!@U-}u$9 zr!WGnBOG14bjfY@jS4yNCASjXeAlglcS|LNd5$E#`0C}Jor zk+`6voH;3to@^ws-D^4WTv?Q^Cto_x%-W;PR@c{AR6R!Z28#;|?7#kcZn)tFZo2tK z-uQ+$aMMjUa^3!Y4xJ=$taK@{VyXo@B|qdJC+M z4SHO&duJbQ`xsOEeYnQjy3eMC^_e!2LhgK-@DTL1t=;%Z2&Ao5MP7C1Ei4I%#LY-v`HG{AHlJZZ_FT27YedoG-S7Hgc3iUsBz)?lf5zuNe;==W z#T{q^QjU4UTVBb-_y3VM-V#YmbZRK3r1#svNvaq#g@YH~rq;DVYf32*qH>=>Sjw`G zHMqc(p$$kWkwwvfWMaGGK>TbW06X|fT{28sYs#{0eJ}o6S(co9>L~>7^Gj7+fh{ax zp*Mh?Tc}nm21+sZOv+SnEgT&2K(Y}pRI+hA6F{#wWMg%eYI6d0g+j7?&2|pmc!>Vu zkS{!NAJ3mX%hJ|8)R$_0?q`32Z}`st(GPGvgf(Ja6x#4rum5t6pFG9&H{Zs#;W9t@ zd%wiQI0)~=_n=Rnzr^)>wlJW?)-{DN{LMGMnZ@h((|dZ<^x2h#b4K$of8xj3f7P{o z;C=s*XIGxbO4rJ>LUR4yy_`Gw6q^^b0D4OY@qf`9Wbe~P!h|AV-fLW6I#2wf|3g$jF+#kJ=a0D zbhdK9f>v@UrlicOs$At{U7{j@cfIom_~=JJj+E=X{p;Sw&;Hx@VpKpd4mou55noxk zXM5kn&#|^PVQX)M&>IYU1ODKTexFy~btkeg2rD>t>^7WMR7rp|+GeifKof&rpBe{a zia8QmS8VYGW;1{miOH39 zIyngAH=Sj1VbP;&44dm?Cg)c9cR%&ZeBZnO9+(N5vLSU{T3?4^$WQ#(Kj(da@;eAD z1+ZI`Jon@YMpeb2S7J>~uaeM{eC_}C9!95E8DF*Ok4kv(i6o*+G;r#f=lIMQzQiMsoZv72@{2t9z@x06JIUt8CfWu* z#TX$bDCy*0`qENtHCSzsY+%eKYO{baPXEjp!`7bUo)3M1uX@w#-Fy&1Aq|JG+kvg1 z>J6Y;=f6<*-eHnm<(>cMgnO&1tK;OL$x$;JWg(G+!C4rPZIKMJu>k|#H8#c=?DhVP z?Zw7kFuN?Qabm&PfNd})SYVXHD2${TjVAYuCgy5l`I7hSt5aO|FiIUE6kG(K(?iWEadmO3WS zUt;mXIv@GaZ<8yH4xvQ`S+<`mN9NM$*H`aCvJVWrh5=@=V78=&44Nz6cV zUJ!g%O%f?L5kGgZj89LHwA%~~42EmqK>PCYv!DA*uH4w5*;iv=u#ZO6;O_f&@WwaY z?$3|QP*Na;?&_L*?Uq!?z3ELLHF*xA!vZtTQ;T~yq9U?Z3R&t(3cH#vM-AIau58pB zfT2CzW+t7YFYc@OYCoT5AfcVVcEeWoo_hqR9p1)9%-Se=4e6Bf1FJ|!9$Lu-Mj8gh zBHr@TcW}c`yckSIt`y4nDm6C=k&KX5vV3reFMadNTs?0yBa7yH6T{r^+)o}q#*@$N zA#MrYdfSiD!k}{r8m`#3nr+u?B$Jl9i#Quw?zsJp^w%s}o#N!tlxKGBXWNZemJ8|P zT9c)#R-lC!529dtY6{vpy3s^r34O63F&Q=Os1tKx>N2sCWc3D0SY*ICRir%}B19>y zw6w7jYECmli;;PQ_Z& zQ@r4&YjMINg&)8+qo70=3Sz;p{rTT==bwC@zQGxuc=91$@UmAiJa2@@zkfH)NRc}q zoKsZI&RQ?F)EXsxrDOvQv|w8m@J&H>5GqFEXITadIt;a)FBXLKESVzfAQBcOBeEpL zT4>EolLZCv(7+%gBZIu)>Kj?Tb`96ucmvB;T*0Cx3zj!N3TKS(60F2Hf-q8J!f?145*IU0pU-WBc1x5)W^2!ak z`~u3=aTwb9G_QL3YjGw+Qp2c(9XqxIiq_?6G!_>iqU&y0!?Qb08pw{re?yV!rBBTJ39N>SE7I~2m!%EqmfBFi&k6(f}7!R_05^-EvH z{{dc}hE3O8MGC}HA~T1L zBnm-Hoh&n`D8pFAwvh!az2!z^e`!jIl!706{ZFC}oMFH$A}zU~9C1m;c0% z`s?K!xp160@+=d3N4cWWPhuT4)nIBOL|;0K5eg#|Tee+YOi3|9aP-V+P=das4zXmx zl6hpxfCnTveQ5?^1vLy3iLAxm(%G0fAdbkl*||hhr{3r*8E6+Lr=V7&)~EQ)r~Zm} zzW*Iqn;@*lX?XhZe(Flmzi=t9eD#m=iBJ3y@BGELcLv-7go1~6@8ws2??3U_ckg6i zFv3jE5JwFT?B3}aV9t=|bj==oJuOgDpL-c$acteRj_+v0GduVB&x%D!!HT7I7A#zVH8V&N5yv%d z`>CG{O2-z82KU}|Kamnh<+~6QtQX#R`>nj`_FMhE*%$o{FMNx^DfHkZP7+ zma14H^{%5u*HWw3cx3w{yy_*d@CDoRO-LB_4>oMv$iJ8zX+df2tG_wa%heNG%`nf+ zG)ihBEwJen%jS;|h4@?*DL(zZ@9^;t{voTHSMc3`{Q^>Zms)@gFSsUPo4IFW0P`D7 zHeY`uuYKLE)E0tqF=;%_-#>VO8bHe zu3xtyEHWO?JbmgkQB;R^&MSW8)u6%U2BSU9wSV_MhGdMMnPSPBD>!ia7)mN)8DVVJ zwHOrE7*a+I4-OI6BR{B@aC&kap)^R#2R`^ge(smw#z3P6UJuBTg9i~=N+Me{`s%#z zz5kxy{+*BU!WX@eg-aH2d2*6_?!S+V$B!{IQfGn8nHif#Mg15%15TivL)TOoFn6E} ztrgA&`k_#M){y(EU550UXA z&XH%2Gcj?Q(b1zEJ^U<(pFPU%z56(K?kvf~6v|H1tTpIs^bzYA<1*T<7IBsmW2o2q zS-5Z!!}Eq&vUD+vmMr1)xy#&h@7-AEbvV)$i?Srk(qQc^%DJEuJ@8;43KY*x;e*xd z^EEXw$xN%oK%?OaqQcUsM=V;sf_&ygIj1Oxy}6mwE3C@0^z%B~E!wPz8J%!lq=#?| zA;Z3YezL`$1EY)#53_asN+Jxofj|7cck=D;e1m{X=X=(A(&+WiELI3+jjK*M%O;|U45%h5vn%}NQ3g=B0T3AC(cVserb zr%rM5%xU)RKE(cgyV<*EABRSdGd+2kMh#Mv`v?VVJ2QyNfV?Yu+1X&Owzx$v60P8G~im*cP+h6%2?(!J9G5p#8_i^6# zp?7n9VvJSGmZMZ{4nL?gwBdrKOO}PI#Sf-;jqXEfO{+CSqd(@>pLzp}<}KyWu|pg_ zIm+buN#+gLFv$$oBn%GL$g(jWd*pj$X`3jDQJG=>P@T-QNu?kX4l7bJA*oA^aL`JV z5>o06%_UO!PQ+S|!AI8D>1jJ5j$`_jVr1bW7A{}H)~mO%cJ&%IZ`#bZYp-T#coMT*&LiY+cFGgU|4~+ivHsZ~bE#2(|2r5x)O#U-Qug5X=HI z&L%akyX7@B8xosmoIH8FByuh8vcx!oIAJ5C7%|8C=?rb&!*D zVIt+&o+F*w)fO~FfwMV6dXqRO1Y%~KxR!G4$K{6}=E^@=9&R#=c9Qq~^w09XpZ;00l7S;ZSk5{4%m+Wr{Jxlp z^V6)l`6d#ezd49*)KNxa@RlV-)sY*4Ml&S^XVYD-2V(VNf?ZEd&*QzGVWn)R;+sosM`O;s0j*orp4{^qVQVjJi!q#B> z{omswzyDD_^ugbxKaP*=t0-X=?IsTdd5!*0H4QD98z zEFH&j#|Tjf(qR5tT(hDerl(`c@(iUlQE^_KBelT`Q2K5{1+5g;(N}MfWf=xfG$@## z&N*aY3pN@J+U+(9$?4;#_`mh%2e5(o8*pfNh@>?`y;++LA5eAX?S$eMorzWon`!DA zG?th;{f!Z%ipg_}vW`#uhyRFl4jtGslfu%E=C}U(Q>?VL&OAm+5`3tPXbYN6pVp@w zT)lBK@AE%D57<7Ap4}tduC@ySd58FARaG z=A%Wk6d4JeatNE#7Zkc_nj)N|H9bYFB9<&z$d)U&uwlz)Ui{)0bM3X)vS#&aMA1Fi zPS;SS=N4?Gt_rA(CKi4u6)3$*6gdi_lDJlQfdMk47+Q-FQIT8bAGqA&l2 z9p%wSo?_Ror@8mO2RM54xR>BNiQ}h-x~u)%49B;2?B_qc?|r=Fh1ZnSP%Q;B zPEp5^8H)kN6L|cooqXwwUq;m>I!)0sCqtFEdN12)&K&!S?;8Q`^jaO)l>-vjYm6Qq zW##harCtW$1vlS<`}CiOw7kMt(NZvSd+pjs%_aj|D*7?P~Ju_YUS!GF%GrHVV(=-kDunp(a zl#IEKDX5!e-&56nL{U__h!-7PZnEx~1>N-9D#0krve3P#E?4qm-ckgv6|hzD^J$t= ztJO%;gz4$Y=ko^Q=aK`BfpF5Kw>Wn_4zzUA<3(`1EG|lxXGkKiWEC2TqQ5!l6}eg> zQiIf4h>MM|zz~u*{MK*s-Ov6VZ+ZFaOH%+N1YfxG+r0DkI~bUX_`=_Oj-Pzvk7I*? z?yB`0`Q-LrQdnIPd&<)Kk;8!ANL`KVjn9i zQ*S>|WShtuM<*uvz(+sAKY#Xbm^a*y!P7ivvdf%3m-E7#Zp22CMjUzf(Oh(CA_U44 z520_waR2}y07*naR9p^1ktVHRVWCPxH7ot1(}+3?v6BK3Y*`k_$mc<4IawD{<%!TP#rXVmvqwso&-3OlKz`mpGeDY}?eCQ#LpE%CxQzvkFiV%`G zuA!qkBaI1iW3dJn=r&{Hh6sa>Et6w2^bIyKS;9;TzxwZfh4=saUnQ#dvLNG|j!CWDp_FIB*l=yyrJRz^$+SNx+ii8Dk>mXMg=y;8F3)pInIy-jk z;N>rUX%KMw6308A+aEoIr@kL&155($Sozn}rj2F$?PTaVyTh=^?w6-JqLo z)6|tn8ORq!H|M>pMAv!k?f8mFidhMt&iU%3r_(HEWm0;B&hr<~uyFp8=O={a5Ja)| z@KNY6X1S+Q@#qmf26oONwQpB7b(E4c`)k;c*p&khEGD8?aBH)tW@h2%N;U6EY!uL~CV%h*U(9wyD=@-kDPhlnDMlDn=UW5fEjyx{s9SiO1`jrqegnoauZb)s5rmQ$aH z5rPJzV!_e1XcX4yWxFtU9BcO-;VU^8D6UR;YJ*g8;`|t+hez3e_&hrve~f+m4{-G8 zQ6|q_V5T({hQ|^~3nh)0j|iy64r$v=PPM4fVELkzT(#|`tX;jDTW-0T4QtlYTr{6r zUC|h9a$z!I&9ap&8X0DM{1X4+KmLBG;1m{1Ln>~(`DL6qx|7`INT61$1&xoxSwof! zuDtmr{OQMj&vyz+QHx@(TloT-@eK8>O>?kW7B9}E&Q&Vk(s{SCIA&P}QgHwM_w#{YeShT{g!%KE&`uEb zI>ITe%P=NE2|c%>zQ?(`cb-`txciu8Z{uN%;V=LCb4c0d(7rP~@X&p;w4*Rbo%B;?Q zi|0SfvaSuMvw8W#yNE3A)nPg3h@+SXAAFG4-Fn;q@lnVR2EuZVhKe9K#P-t3df6hg zT0-Y=2833S<}6>h){E%y?{(zTSvIZTfHabtg?hbCJ=S0hY2ui_WhH}7;$)6Mvv=2S zYQiy=o@4P9BmTlVgK&n6=TFkmDc^tc9)A4gxATcV|4(e%w6+u?A>qC!ck;oH{x*-@ zb2kecgJfv}P0hBeH)EY37CAyiplcvCv1#F?q^32kRtqbfuY#QC$4eFBJ*`1U8e@FG zmaIIi4J@@NMj)7+Nl5axHw#2CGCacCRV!JuejV3da}Ap|Ze-cgWehG_z>>v_85|m# zb6a<=d+~QgyI4?Jm88p8#TiVXx(cM%MA)9VOy?s;yRKygz&dbtlEeE)d1m)B96Rpq zzR#aM#o5zG85_GumS$)vkfDn6fkA#zuW8Rrvey58XB=93r&XL|oBrlNxikr>S=cW)u>0Z4k>wmbdXm&C`hi>| zh&1yy>4mLL$cC?4#`ISHRi>V+3KT0*!8-Px!}3+FjGz;hU~)sGby+kN zk;+wTcvn*4ZTVgj&rmBiq`Y9AD$P9)+{^1;d)xCA!UFngHROU}+>}7%bLWRYSH!13 z`5Gq#aU8L1`4td@Fpw!n>(XVg8AJU;sN7;qhDmc`19@&~_C;7yR2pMqIB@I;H7Ci_ zHmcSLRv9rDrxRYf`3C+jNyrQ$?04h_t)n9O!LwzlI+S~}c^T$2(*w<4^)c`)3o zB$+vdbjB~l^t7A{^!;qqXG?WE;7K`Jeg@|*B)r3}D1LK-x>)e$H{QmF|J|>9zbTtB*zE7TA5f13HQm73+&`p`Jj1>Jb~g+A zQV@o^j%g+B0OQ(_+ipV9SlFUyYPt^OM6ymof|S~`+JcC*TCF~pZmPHjqC-TU_4)!5 zIep?J?KBAmi7y=LeK9opfp#SwvTBRrZCkWdT`scK&ZoS`gzS303*~w-Ll8nxkLwV! zMv`_bz&H-)Oz_(hrAW!<7F9S@2@!;Iu5>;o5OF-j8_t=`u|{;w9}wNP>duC)GR!xm zR3&^>ut1G5Xral{wCq00-zz$KPt_|re+k3ah< zPMkhVYibImGY0!>2$z$%jKLw8Zl7fDo|7O2aV{8a#2!{tHB6o&RAJ`lqb{A&2rGz% z@mz5us7ZyutGF>aY0HNN)$8>#4`S__wX9pcnyuTeX6f=}Ty@n|ELpOIdI^Jcx>g&! zfrH`s}O9FE!L6Bh$*8@Dplupv{$kR*O% zDHaW53>lIgyZ14A;tcyn53=v6o$TDPgTCQGa+e}q2T+--%jiu{f48qw0h9C=hq5wQmt_*6m^J+G9THc)&w7*js=up> z>-Tz2Ro{CqH{2@1QFIBVk5`3qD})T2h%77pDpXY1v@4|oJ1g&s6eu>F>V{b=!^5Iq zjmoZSKni+qHCLoK#^-V=&yB%h%GqR|=f1NNozLTf+pv_9(b2=t&kdx=FhB^_tXt2X zlaJHr;jzzYgWMZFZ*v?qGACHJZbi^__@CK({tPmc7-i4}mM8?7Fw_?G^Xk{Vj)|!m zOzRA>ifIfrQD~-J8{1ByHO9h5om@9b%_Iqi1`Sdy!hjWuB+a}URa#UW(Ml8QI`)pP z0WK-qd}A?L3TUh|)RbWU{6#be2Ux#xBP&<0;Kmzo;JWLtXVt1z9-6EE$t_lij=5S$ z9IT3qgsKenip-N9c3bat@Qs1;b8aCjb*lGZx^y|^a{CgOCnq_7Zk!`Wj`GMokFtBu zZuafnPkU+-%q2ij?`zO#HjvVb`n1$67!*AH$oIHz+uOT-_sXGuY-^_G*WWu^c@z#$Wu!KlAt#k8*T$KVSapU(?^;U*22q zeAl}f|Js*P%Ac^e{nF3#YwvnDOGie?Y(D4W zlpAk`SHrP=`}etW)3wYWZctMhajZ%vi4>CUk3P*SZ+R6`!$?yh1E!zb4Be=qGsle0 zf}Q)^g2(^a|5vYjnK4n>Op0e}e0-cm3l;@0CQo9y^(SA$-~YvEITz_2hCf&Cy)802 zs2E08<_Fck_XaQ(i}GB9`l@2PI+y58oUB@S6rZ`+D7wUWl|{bnh_s%y29j54-vWL6wzn7t? zkJM#dCp3}`+O0|8GV_}eCLRJTsWRwPP!kbpJ3-YV#`6}ru+)jM(q~6RHH9#S+$6-Y z#JZeFG!RzMlo2jTQO0BPQ53Ow{ybK$T**~iHu9pEzLNFpH*@7RSIs($#rz>qWCDil zJwuJNNF~FZNP1D36y7{8%q+Zpw7+RRE-gx?lbb^%7i0spQ%jPynQUboIewfSPwnLC z-FtcPfyWpfJ%Js&477=qrrr?L8X74*tT0%&G;~5{hmfITG1&|zVEaM~l-4}-@OIwz zi*GMKpFl7;)C3$dxAfHqnVy-TQHwE|2|A$yLnnA48I+1<3E<|cz&j5Q96ItOzwx1W z6W1cnojSqz_$L`07%1mezgiOGu}m|BQmop zbQN_ds*{tG-uTn`+tXor!422&r9XEeg~SHotnN5mI%eg@7w}0Lr`og0R4e`}%c)p2 ztCf9kN7ZeaqIz=YnG^0VURQ;#T-Eq9%oYm)s&^T-AvV^t#fsxCXB5(J3?Y`#`WkPiW{Q0 znkW68>Dg=mAod32PT?juJKS%YzoX|1{GhF9{jkNrNc|B09T$1}Bj@xT26tM0ms3#Sec7piL+ zp{!%of|u|bSjN;E zb@uJs!wuJ6?+pQi{mxBSt)iV-`f3rvW;iKISB2s}5IytC;u$U$v0frfQSn!`A=OU0 zD`;$vLb9_MdRu-UC?_##+O=?JS=I#w2?RoWabLlJ@*2xd@}YI!Hobt$M3+>_v$dQQ zWC5;{!sozeAyQWared*qcOfQKOQx`yb#yYatGh1jP9mv@YB4rRsKpWOb{bx<$*lqD z(Fo~e#jLXtFCdW$2 z(9jT9Z@r3JZn~M5z3ioI+OU!S<%@{o7$pQcjzgYEFUA`-1tq%}G1aPQR`5<~t3ihu zBK-FZpj{RW0DXWJvR>?ZSbJ)(n6xLlC%sclLt zOx}S8I@q005R?e-@1zv3d;J?wvA-v9@aXpK-15R}7#}|e0&)jRI6nN5-{kFYdNc8= zrGaQ*ky>;A{o6UXXE*P7>zjGQ*eR@oTI?6G@BHgOuyyTvuyNO-@2tg1Q?w0%jpx8g zgf!UP`9(siSqrJ`%4@e>kd5tuj(XuAV@x?G?Ca~}$tRxXEpMvMIRxw1t@Xr@@ZOm* zr43o{%%OK)**mwaR^q*dVefN47ZOorE%nZI3T9HZitZg`7w05RQ|}!Wd+#Vysr*$n z@wAdFUJZCEUfW9u=+)a)i3-){-Wbz~a_)Ieb;eT+z&)y<%bAl8zw+Y40=}xkVO8;_ zHU4M30MerzTIs;ls`2214|4nKZ|{1({-5taItM9Ov1kc0_rkM+O;8N1syJ&eR#9Rahc3ord*Chv3lupwrttT`VAX+$%|jik`>EY zwsJZB0|N{W4xn{}3qm#2+TKAM9~q}E>K2uuT)E?fjx#}uE@T3qN7=29J3$EY?iv(hYKDwzr@ z*m_69A_R+9uV8v~6rCBeJn5R(^nR7WoUce{6hdHSs2qcKrbsiKYfxJ#+O-N<(1Ect zG&I1)>GLQhxpZ-ix4!i)T{PdHd-I#PuJ^WNY15ZUBJd7cV`##5K3Id$?34?gfXPd&Mt(Srv$bntNo zM>JXD!_o4*d;X&6Q;X@R0w$EILaM%ZNNfsTgZAVqGT> zmifH}&|ENL@7$wTH_|&lsm>gF|E;OmGW`qR3NPZTCFK zR^Gpu$B4@DSM?axp?B{_)z;MF^@D>@MG@M=p4B}-DWG$+YYG@8vzu3-7nE4bm77jVUj6>PX_JqwmBW8S<4 zELyaPdS9&zRx7LAAY!zlqJ$5U2ud+y$O{Ue%9T}6g>o3O1e~1vVJ^NNK6ja?c0a?j z&pyksV<*`2%pOi3KgIcT=b4(G_LScC43Vy*w7`j!K49$P1*EeK3=WV)g3LN6{32bW`fg_3>NP|{2gpA1C6wW|yGM~WNGjQ!aUnW%1rBR=;bLP?)3t|?cq@~mx zIyBnV2-}b&ulpJplOloK77(TE+7#xZ-S>X4S7_K9OcGkd}D&;-UUgtWF zuJa_kc(E489>PmIFjtY3*jpIcN)~w(c~7h=yRkZxDLV%zOPIRYB=S5*D_v%%RLKFc zj{NMf*es0!)q$j>l$b0HHu|m%V=LaPR;zUl`iu9~IwDDu%4cyj8g;A$oaUj29xC-C za}@>u??PC@!!rwHOiN|dbrX{rERH;2;F8%2*Xm6sb>x3WM-0k{^+U_~rC)z9OINOB z-Np?JFB@e3z=Bz`7t!+#7Xo66?X6%bgxaPYNLwL7{A}UQQCMs^q${cXWffmt#EzVu z;P8k<-}$vV^}tSgyBU? zS+#y6a=6LA{Nvv`8^>T*ijR3HC%O+;VXIL;PS+ZdrYqoAe81G>;Ix&r_ z#S9Mi`-eotenW89D{}>$8E^CK;lmt1cAR@3-i~Y35MA*-lcYn^B2Y# zAD`gV$qVe;JIby-dpLRWID4LXhW6!2TI~y%b^=JES|1AsBBK5#I?HL+rf4?mBvWlR zZ(PrH*Imh)b(>hZZUY-PZDj4*H8ckY%VQn~hX3&!^etS#rt7XM1DlKxeD3p~=ciu$ z!^9(tSUqD)CR6dr(llkDf3WNXbD80Yc=4@oCuBa0b|o8Gpgx(HQn z*53b0%AqwOtV;x^-qa5$3)lw7s+Fs-Nfs#2c9!UIE+J%*rdKMS=O9^hEtGghjFsN; zS40+J{ngB*g}jYbF&8eM=a=96z7R3%uk~Bs@h8g zoSKeq2vh_+kB)6dZ=`B95}`LQq9~V+A3x5fjhnj8|EA3wdE&9tK3P-PIcHRJ!?I#l zhf%#x=As18#kTAnL>DUY!g#SO37EOHFh!E5!*;YObTieeG~05JZOyFEEU9ES`^$Fw zRaFIkrRieN^{qZXRmFPgXe^ZQSzM8!s0YSLY_`=+iPxN<%X49xn(m;)~x0wuX-hMze1_Lo>@=#qEP*>yl%#pL+x4| z^UO1QS+VYlaP9riUAbWsB%T_by0nC%o=f~CduC4M{ZReBt5lVN=|7Os#Q*>x07*na zREO{px!&eQQVN)zfMf>QP*?$(v3&o5NBPd3cd~cSGd%LpUG!*teqP^akSoN7R#(2vV;kyVS zM3;!M7vd^r3DttJYol~@;(Lqimx5H$6V7Bq?0^s4atQ0X1dJxIEsI%F_1udds%^0$ z_tJ9dnFCeVE@Mo&pjXdX^)vS7g_KM+XS-fgh!usPTi9`WQ&5`b&@c;hN^B*@ z8U`cDz(PRuGt-(R&nJS_z-RyP4_NcL zzoT(ozlY$YhYi|khE$3uiYptaXAnJp=eNT|!T_HORIi+ zZJi^EVs`F)iXVIJ4~H&9Vu1xC1GrWjqoObaanCt~oohHgtFkR3XR8ZOIV16I&VT=v zZ*%g(dA|SMJ9+ZShZ*RvleT9Vnm@#k{lrh;95fnrw3fJJhNxb{MiEKoXE-)Zku}Zq zs&3S5eN#TxUV(ypJe03eUKsrz0z7KqWJ&uuv(4e%3wbM%6oSsa}(+W}^z5_Udk` zgZ5$|-dhm${x0WyzK(QsZTQAXoKRRiaVV0a9KP3TwKCYP3Rx+od<=sS#8FHV`Hm*i zHC*a5az;l-xn|4tWx@KtdyxKvapM&M2ShM$-D=M6*zYfpDHtHkg0Fg69xl%j8X~7? z6!<;_f;uBx}3qJ9|-(^An2-EeH zT570g4c>6uoB6~4{xNh^!&-*`h(LG0Gm;cb1C5iGx^w)+M}MCk`*w5czNa8f$rVIS z;Ht|-l;w(%5kCFJ|G_uD z`c0IJFd;Yk=*g1^9QFR;aDzEKz-z&_5keuHCPjeBAe+JojWr%BPza>+L-p!ISH-Q1 zMNJoKTxU^n%smg@!-x1_N!hhRFt5?)-2ozv&hqDE3RNGlDg@Bk1ZP{_l<=qygH30t zH)_1+-EZxx_@v8yG;xv=$$;IbEij5mYVyRxcUmg)Gy?~DJ0Y&sJVvczj7>^dQ{b>J z>$zVgKCqwzz4cmk%$4WS3#s&`3Kq{r?>wPo4@v2@0tK1CIa~-DDx#O8U_j|?&d9(Z zPwm>po8S1R3fm2?zwvsKc1(XGAFU?4_qytv7mezpLs) zc9sxFK7kcsF~++sfIuqkWy7KqU!3JRDv(~RwWN8Nby$Zr8O9oh^?bhY`M=`2k6%lk zdmYsC0>bKO9t4XPF64xL#=mhTKuXTR1Mjveh;c42DZy=0zJBMw5%tA<`+Ilt*b}=r zd*&k37cKxft+d6w{+fritglE_eVS$*{GXh`x(J(ig}JpkU|HH&$i}tn_#aRHJtK=3 zf=MwVMp#&~K=bi;e}Iqv;`>?mLocR(-!ZU)#Y-0P@xS_nPsdCz6OyZaP9@;X~ysW`umwzpU0Y2E4k{YUd)n>SMb^Y@#iEHsn?>Y zkmDyo2}$li3(L>F;U~G2P6vI21m~EZnMP?zt>{1;AagRIIeIB)->yA8dhgvlwqrX_ z?B0or8a^aR+R{x`2sd~2-=jvZR)3svadb}wpi4Zz}Sq1 z3mUxZop1A|iCTj&L`pGGH`pwpUQ7M8&z)~=Q-{+L*1BLGD3HR0jl|o7D;072%o(2C zwF|wV>8W!vE@4lTXr#=^V$IjS@^xG^nx-BLKJ>OXdp>~kRm#M~Bv=?67_9u1Vk(1;tJgB16#4XJ+Ibs?$Lj}2hRCh# zf~I=g`l_g^7oRT{%x4cD#^%0SG|tn4wTh@Onon(NlH4S73d^dqfNDisU8H+C_FY3! z(W@EwUqfVb(MWqYm#zv}bg*|pfGm2crncitCQ24x#hN4NiYPQK&tc=!>uWXFLRx-? z3Ja~H#_oZPdKA;o?Aa6G-C)TtKntiTg%k}k*$NPxEf>_@E~@uftg~pLx+tkm^+0o~ z5Pq7jj<(#8157375ENIT?Ow`qb+hOl)K{Hs<2WuIc#U&DwNojC7G(-yao%*KyGRP1 z^{CKe_>RSf)=wx&p62CZE<8OjgTozx&by2e15QcHT6)PaNtW#fj8o>d@ahllM15;vz|Tc-jMo_=aALKtRR(>}Xd2rx4^ z2kk6o#(Do9Clurs>HN-atO3_T3C}+87RwT6I~Pn#%`0B|YWfxq26mU@^!O$2xZ?v{ zy?P6u{NxA7i5LK`S+nGsn;S7j-KO=cYc6& z95Zq8G6xUr#*WP}Z*XZb-Swh1D_Gdy^wehCMrSo_O)!z93=7TB$WU2*I|2W8?_-?X zb(jzS${jeH5Lpef^AJu%X0tPga)O4m{K~uD%nh42vwF>1mMve(f{`K4PfoFE z(kDF03m z?AF7I^ezTI%ez?EdJO}6*=oItdaX5Cl9n4mnB38lKLieR~n zZ<8GgYjbjw5`~*OcByXx^NPaT`3?kYu(|RfR8sk1d#q<~1uCkviuLO^1SrVk*qO0h zK6iva`{vhp^wIB;ix!7Y9%FoLf+eob<`=yTfLavctiuS!iNmLuZxqw{B#pR_Z+!K0 zSQVk2L`E>IYAhKpjQIpcc)&*>xj1b(f9ec750A3@&>_-`mq-&sv)=EQ8{^3caVzCR zfABlJ=Z-hgH>}CDAhMo`WCYC2v=O?FwW=UfBZVQd8K3%-k9VqQ11QN%bP05yclfM8 z3bI$^6*5044I$~Oz>9}v?D9B+LxWyd6S~iB+qQ7%;fILq>{!-bD64l7pKC@kXEu0c zLnx}+UfQJVDZY9as#z?vSythljRKyVr8E~5Tk0lkv1tWHV9%o2yD3z|gu1$0!U zMLKAa8FbndK^I^;#UKbWX=aQ}kj=4UId)=OlC@YHwNZ<;Pz$%qd*Anc&eA{5@}B3s z=b-{5N+k*xlE};VKFc}hw|y6qhMUV+?9=IV_$;mUs59$AYey_etHRN=4Z7D$Ygxk2 z4DEES{XpMq))CxC`*hDLw3Xv+DIt;^g|A{PI7y?F-+OUyg!d*?iw&ML2=9-sT0i@e zp;Ae5NQi)1W1!|6|6k8xb8C~`J6kW-`Ysa*|I$+ym&}Fyp>xyG6KJD-KnTbJ0ab&X z!SEJ;usP#(n4DeUtd}UU#4USapqn>l#xQSLf*8$a^{Kg2)(ul{TH&gZmBbItyP z3C=8li&x&J*%17LzyI?{p+X|@#aNj^EtNQjk~mpAtAyCb zmPfpv7tWqdq%zM#f!lApm4#V=ai~V6wp}z(Dv50Qb$d-Fvpnbv0$-XFS+Dk+jLoe7 zJr|HpF0=z}re^ESs{AvTN~U}F=ZOETIFIo6=~iY{`3xj)?R8B<*EBvkwKfGf>m1q) zQFKf1`2f1NCaedN3D_Vpu}dEtXG^63pAgEVg5fQ8JwU^A)RgMNJMw%GhYw1PQp;cy zEDeN|-ZfJQChY_%y!)XwI@m75=KL~3{`H6{{-p!RvW4KI^uayX(5fa0@+qkj{MJ>n z!y1g#r9owMO(Ti-#SK#S)=NBhUe>1XF@{H;c$#m0{dtt~H9;#a&KVA0dw`$+&;KD0 zefewr@i)H?yLK|y7P@wDox7$TtSMxy6t*n??LYW=zVJt1 zwXEp{A3A-4AN|44@K65nKji=Z*Z(`e{)eCEjoBr3?%KI*p9sOZw_c&y==rVR`Ypcr zAHIgP3l?^PlL`ea&c9952sSq__zYI9bEUVOyR^lNub<eFJmyz zh_lb%TdjJDK_(wKt^|?T5} zf93E0{C~vGjV>`@h43W5du}+*7ryc(K6LsnUVizND2n2LzJLRJb|T;2Le1gsoA2b8 ze&v6{I*qe12j0A}$ywa`k*%iG(q2r|#kqJ*z1u3UZ_ z%$(hO*ZAq5`6-@%;aO~Fd3$Td+(<6G`Wn`4@@IekCw%Ys{}j(X_dL%(`(Wbmq8c`) z9cm)zq-4==A>0CE^1iuDee+ztK}eATfATcR4ym=ZH6DHR+kF2IeBTl?CE(EReaKml zXcf3nQHFn%SZ!IAnRu;QDJz%Syrd+H#kP+O*=9L7uZeorSk)^e$4cc?t>TKxWNgir z+4G7Q2R>_$k}uKDUbtbuy*4Yc*3xz@&ph*tfA%b|>Ns$}FskYXj6#ltlr z$+CgIB}l7SO|Sa_?;;)gS#=j@Ir+?`Tm$Rt>&#}eKxnk-3~Q81%u{XqgwR?-hnJrh zTV$$fQ1L#(Al-z0DW#%QlLQPeikDA(Tf?3z;gAoaLEsJTEm+@(qSnim`^dxy+G68~iW7`ror>$K8DDlm7{S z@});Sww^g)Fv@b*p(EUO^R4{(x4wZhaUSk?a``B^xAV2V-d-6Bg(bV$4|QvFir5HZK91Z$9uqD9_VY=gb z*4B@3VE?TgId~(lo_z^p7i`Vm;{FHk^wgGe z0*yoMX))&(G)^)T4u$m|-PS|uVm6eU;>1O~+(a&vsByy$r6S4}Rf5bqm+A8phM4{W zm2A+Pa}FKe&s`t+FgM?R8^82F|4aVvPyap8hG$;-CaMKz4MxGvgFA2=6Mpd*ewqL7 zSN;jYt3Pndp=){K8{Z6l+#c;3gp*tn@R`s44GyjE;f>3e{XGeRL(&9Tr$EqQ_^taM z;p<=fQ@;J!!?5=tzx~DE&)6Iy9r$sElYOofasbgR(LSZ0$_f`H z`o{!9tqE$gt8L(l>_*f8tH`bAhfO)ex7N}%isyq@_L4W^IC|}rro9%|TtS$gCRUp^ zL#j0@?V+ec76VQmjB~-iQd(sUJYlUzPljQe_i!mB`Yr2Jy4W(*|kq56Fo})jK(TkE@EQCJRKAoR5ecJANLxpSAn3L4=h&`UyA?J%ejx@wEChSV9f z3S#ylNUENVP|zFBoqLn@J!?S#L2>)1KF+WGi(lmjKm9#)3KkeT=dbgr@4QUAZu!+; z`&I7z$i4jdPkt8145_E7<>gTnzLfjO5B+T}zWF8xu{`qdH~5X;{5=2e_y2%1Pd&?} z*ROE-@)fl1SuEzXw#P9;$OXHZW5pHL)^;MaMz*~-$1yfRLS5Ks%WP*U!=B^qYgx4v za#TO8hPGKT@QLp@B2k3k%$YMR(;OeTrIe^WJCU;0z&fdtHW>0Ks4rkl8{*8zHP|1Me+AXT|0#sqTt*r`7;k%d3G#> zOcluT9()GBXYXG6d5;i!kc^e&z`@+Z*+J4#`!yceBSfgx!0KY+f16ZcfA4;&ixgPS{xYRP)^Vb z_@2-GP455w`NTKH#6A20G;(2{Fs@~7>m4y_9;dA#*j~mI2Wa8f(-DwnsWZqCAMcGpLkxYuagMI-&{_|8A| zcU{MoD_554zDkBRo1*JFOz$g?M)?8#VzKavvYtb;#+$Fb%FC~w<;bDq?~@jm^LkiV zZyt5cwb%IUFKa27f;BpnhgfAImnfDo#%jJ9bAdn?4j8KqPDnJKE&3xr_Mh^t`@hWL z8~36`gy%Jg;8_gti@*Ns{Ih@bPuXZ1E-x-HZ6-{1DE{b6pXcBI&ToR~(!q)l?3qZ~ z&SIoyv9L^Q-=@G(Wokkdelm_LX!7*3h%$!Ck7I>{7m1kyB4CJlH zWVLHD3uTL>e2yjmVkkJrl1&{6Yu2Lef;Y~+!J)$k5zdR%v_f#>O(%Km%=2DLHNX_T zx3o*p)*N}WH2qqwQdi;P1v5JnB^;u9RuzWFl9H7yIRZlR`5vMwk1_^LjsxRCLgSXz zL|IYgfuYu>$`9GN&TB4z<>4x&&xT)q`DKnCy?&XY1IKT?k=I^)8g2Si4d#SDC$e=A zcp`o9{*FjK*))TGe+g}lZPYxwj@PXM$R;1|=lA24amP_@`3xhXrPAjX1kvG|_m#ad znzn7wVVEMqU|$r$I+x2Iv*wnnR8|lHcoGexBtqCs%H7d40{B6 z+0{!nMUPNE;~bQkZn-!kNh;5-Yr~{G6UYbf`9YHZzRr8PLb6zFBf3{OdGl@j$3O8o ze)1>(7Hj+WvbDX&wbdb3aLebAX#z2S&arLMVPcW1$tnmu4D2x@};~YSQb8ycRZ>(VE^juzdiz?jR0@kUk9D@zJ|^==Z*eauyjpCyeplAkbQ86_S9;U$Z*Jd6AQNAqL=AY3jZ;zUo=tb3B29BDlaZQh_)QVcI zIF>Cp&t;+tQ639gwKh@PcF0EYz#|WHV&uG>%Zr(gVcOgryolI}}ekUsgd z+R%0#gabO=r;LG5pxOqjhZ!_MI5B#(M?&%7eI(1(pduU;BjVqgP9{EJIg+z!ZcbIU z4PzCuqCTMV_q{ZZQ=&mHEUNW{MQ03+l$c&4TS;$v@2k-?p5-lNQo>Cj1*MqHX1-eM zd^e$;bOG_@iJQxopUI?F8m#r!!VZU7I9v;@YOq1n(P0oWtWPB|3&UEwhS6SqS8I)Q z8fzR40-+RhsaPzwSl_w9*_U4At~);H4b9%u0YnUYwE&fvn|swn^I*O{VQGK!~CpnFs4Qlu!5MR;_pQ3bIUaVpXeqjZ_VW4BQetJ{F4wS{pyV6)@L*3U&_f zljQHm%e*&D6a3Lz9(>?I{`TMevG+cVxAyC$OCHm2HecHs~BC zVD}B<8@@cm^EO5)5$=Rn{51p>PQf7KD(|&C#PTe>l;W-(Ok)5Cz!R4Qy!y)Po>3A! zfSrJk-*Tt-yo%M38A5e!CZ&=xLso~UtHaM#v!&Yeto@xbF)3SDHPT{v;FsBbd0>~7 zU5zI)#te?6OQ!@@1n@`YKJ#}sHX|&7Ds9{HR0KRYkjmGRANlA9@t#AcUe(4Q)F`sbD~b zugILUNU4Z+ECOGtOeP&lDIR|4Vg5RPy(t6zEl z29WFJ6e&G?chN|%Wg`SAiIagV62#zy^X&~6)q2EG+Mpbok9jMMK|NOw953n6$QIKZ zq|i9yXw*7_j$SX36{gq7f_>{Bnn;`hBN*rqd23mRw9dEh0v@}jEwl>vtn&y`DQq2$ z^x0b@Wb%I~RcUJhwHD~&rZdiBgE3UC%~BqC21{?}yz%;*VJsQE7M#FNp)~?6y{fWu z{?AwRs;sY0g!B4B)(sCN0wzBQoTV%_KF6->R-RwY(5d8AtjrUX3|eXa8cZ%7k!6@Q z`J7r?EWegoPrgR@bIxJ(JZ0<7tX9`!f3JkH=iccEfkblo!o_7E1*B}*q2R!Qy%^il zo6tsb9ts^53KRm2=d4(*eQU)SUpa_iW~5EkD6B?|%%9b;o$1oS7%h!$*k9H;7P|K` z^4Xw1f3GnBwr!g_6fwxgswweh+;acMuNYL)vokiJHVFWcIubPQJ8iAkrwV~qHVr0p zAuQfGv4mcC-83UpFF_$bP)HVik8D)%YO!8y5eLTqdm7vcl~Qc%nBp)@R0{~K5xo8S z1+L7ltek)EivS{k$=bwcp^2B_k{}rYf9*2j8-ZXL{jYO$M(vQuA;0Cut_>UW;1c^~ z!%fdsTNs02H8|Am$^lgyaMlQOwM;GEQ+}U0oUmp(H0Ci;tKdr6jo23OXL_9tKCF;@ z3u-#)c<$_Tp);~PxK$*TMfn+QwcQeXy}3;Ha7N=2@{3GYD?XDr)GaHmF~!}oy_9Aq zO_P!r!nNe>sWJl{Dxj_&X0`9BZQLvi`Fx&Gc(Geh2DQN%AV|_dODh49Ksu>HGKRKk zl8&8kWjSWES-PeuDFg80i!Y8Qk?-jM0#l?Sk58 zdDyHRP(|Rhl?;0r==@@rLL`>63M;i?s9 z9+-1hc1^Ljgem)M)1(R~@5R>+?{aQbn@`lxZ!rP58u>LpP;2Ej!PB}Vf5 zHP)co#w!X3WLWO&5t-~c@i4#c$excCkw>mIz9JCO*0z|DWUZo9!Dj>VSRLo^Wx>)w zDqlPC@8syooTwT9{(L@PnUmVUSs^GJEP{4c*LD6g*VI79W{jNso(&-T_U`p1T!gd6 zAd%_q)CS8nf9A5^TK1Fk7m-K$vR7ROiyD@{HiTX|L?arA)r>U{V6_Z*nMFp7I0KJ^ zQX-;8yewru^4WrQSv#=OW3H8pc8L@i7~PB=^3GXwueo&L60XmIc)skv?!*Zsp?|A# zIT@-4f3@lh>n4toT=70jt)+5v)^xDScN7zqICCh!N_16O!Q}s+XWv(o@)+|+i3d}h zMU*PY`TfZebWklA$HOfu2L#PiEO67wqv+lnC&izqb)N(^^TRDY6NVBrdDdPgY_&FO zZSUsx#JQ4g$!S`72U)wTJfMA*G_(nh8GCJSFRw2Sv&~TaHA5BV=S$NxOeT{-f)D`- zOHtS5c@qQNK(sM@cI2}77FV}2pDB4Xs%g;1d%ZWIeHZ2R_wC)w6Hh!*ZK1v|0?3|& z*W!eSCdOo2WdD?q(qs;m!TM?nqhnPUaKfqb>( zjT}9GJSv=|c1bNLT`kBj!2=?}DdY9q;4W7Z#>PA>YKcOPbXhy3%8H>DpvqzK)evM? zBTSZ6NxtT52}5m-4n0G>k(z20k3Ifah7&hf47cBQobByJuqh%b&*uBndw=+rm9v&b zkPgp-M&8a@da?|K6k~fSRss37#=|iF9g}&9#J0DyE_rth(27zfkB?Xl#CA@+#xAtk z;=$c^ZEBMz7;$8%86Ib zW@m#RmMhhGzFC-&sHREh>U1(iAkvv(jMv+G{E5fk)#~G23m^tKeCj5Q@nsdoK(>ZN zAsEz1AqOsbc}AXRV|lh$qB6#iJ2hlXiK3`wNh?)Ljx54eVaK(>?l99)DR|`0Vd+3^ zR9fT$k%Zl@z7Rwb{}UDIn56X-gNKYlbv8gRZ51Jt#N6V6D+G%m1ODQR&xP56Z)-^< z`1B{gi@7s62@*+fT|o8>#R#iOM9gGkhKWm+E1^Xvlm}*%!63fF{D7)SPN15Noh&FA1Xf%2&S{Qx*tvJ=Y(*9;+L4Kl6v3 z4r>R3#7=ltV(AnZFiKtMLt8I{XSrCi3p@UDxb^*@SqX}Il5LH;E%O?RNL&REUTFc@}Ev&rkua(gyV>uBM z8H)b>MSI~j(q7(DtIcA@S{!k6q@O1oPKtr3TW*|{P*s8bixgq8h^ul$N`!H3z*q+6 zs3GK>U$keQe0Cs30&w)$_2}6w%}1I@0<~tKBb4`%Yc0(h!YKdma(JEh%4>&knMsyO zO%53?b*jdyr!s-5T|3#Uh<)o?Ra0wq{zWS2@?Ms0CzYPd*T4Sf9--qL!bt>z58iPr zU{P&H)3iu248F@C6xK=z;3cRaZ}ZjE4D$9(t>X0E2OE+f-@a^$Jrm)sHAr^K{4=s~ z;+tg3)bV?h4wh=Fz=!yIah{MT93=uY{(0QvN-1zHZL=1x3%on7NHYp!d?1UmGA>&8 zMg`$uV*vuCTBK}{Lei?n+vSFt-K<|E*1vHU-5Vy8HGGpn@%-5rGE%1C-7pAwR|1F< zaOCh|Om9-oGl2OCnc%wdA1UN058<8K0arzY71dAKd(R0x$we<5z!8~K3lOznQA5h) zRYP>Gm_L?4HleB zT;#zhsSiuBT=Cf)D-Lt>zJDzs)z(T$uFZp`Z)JEG>x(bE=%0VA+??a+p?%QpL^WMn z3qr{RsZC#Gl0#y(f*a#!)zFAFXTq3tmQePR*&o+^PSDGLevPY>dxWUQ|DEY{x{}n@ zh@^Q-JaRSiAX8prscLKu-pZkwRL=ny_ksh_D4+Zp3&tRQO8{efoHJN!m`o;vZbeP= zE)UQb-Z;-&m);2L>3zfl!8vX`b^|te{Mtfpq}Tn*z%tMF%i&RpZppKZt2xA#Dw^e? zT^pF^vx21CR5^somso!cZe`$I4pYkmH0PR-NuAgth~$e$gbYSVMQ=R!-Gyg52)?ns zl@Df}U2$P6`|7cG97O?bIGDPwKMjE+4Ye+9-&J zHlfFSOQp=1$7T)59@N;C%y_JAS-YMRc~o;ZEO`zo^A0FCn;k@@u3PP(8T%SLK=bN7 zKHD6LmH)c-(2>ykFc_l~;GqN&r1ndtO}msMQYo3Z8e%TLha`d+cvl!VkV;8=GneiO zx@sn?hI1Brx!2mJ4FCX<>|b5bxk_hJm}TVBNwG~8QB`Hq7{51aWX0-2DleGYv@MOC zqWk3@io6pOT34!3IO+XFq?Amj)3CoCLK+-BQd*kE%fCBg5Z2*(lT-_|H94SGRW3K)+z|(rxBlpd~qSezu0gQ?tOUImsi`a(&x^U&NCBv&{KCX)%Gku+V4XuN8$ zao*r5>OrNBfRxBap`CB-sE5DbGiX0Yo=4L(;3U?7 zk}ZN3qa{)_=*0rzdW7>;#KJ6?>7Io(2rE!dc~x#LQLV&UO>d1Ca1;}i?Ql*aTZPC~ zi-cve)wHd38e<0jiJ{XE5a-&AjJmj!B`L)>lR35F>W5H0r5H;)^}|1_!EyO z;mCIq27S*25D9FE36qT-$VMf*%JQ%*+XuPs&=~Ti)IBQ8^;$b3U(C6SUkUvz?Ko?w znc6(2)V*0^>X)W817XCsF1gWbjcp)}ozVnpTZ)gWd^_SXPLou~Fm!l>CVjC0Em+ zD%WD3got28PzI?Lh32bBo{T;BJjuy<4z;AIv-(jkFB6xZa#e@S2h=@ zwxv-G)-EfzzVFf63=+FCQ4vB6gcF^yN&Y#f6Kt9 zwWd*udA|)JRt_!Liq}wD$R91N&OAtidYFmevYUFF36U9Ge#|qRr5s0SCu!xB;Uhu3fEUlQL8?N~z!# zKa{5_-~ZJJnzib!Rt?zbP**X}8spcDRX}5vL+v0c5nam+c~yR-HYclPj^(X6n|fE^2URh#RBULM%$HrmS5kJt=+Dmt;UqF$J)qwm6wZxmTkEBIZXx_ z$&<&jGvSBVHd)K&2YId}yiEFZ@E><9d4D3CTX{&cQgXmE$u+kYiv>n&jG1F>kCgti zgz$RYehBV;QB*MAvsQb3DT zoAC70Pmgvi-m?Lu4-sVl-o5BX(23PjvyQmQf`^jWfC7<1`0S=)d+VH^R|x9{6;8gW zb96+RMdq;75+WMqK};a8X{`~~T@}+`mgHk>@X`rSHVSRc68TafYT{xo@2}iYae>83 zrbLF-&_y)_N6nga85AW-fi{jST;}YvFJOWIpv9pD9J~1>GXZK5J=uj9TZ~nj^zRg7 z>8woXp3?X!4*;dwZhn1L-7{yg!uh!eVcz0|7YWST9r>IpZ$Flai?uo&48xzTgiMBM zV~q9HbuV#FhJOdtpD)&Yzdn-zFB7ZszmvvN+u$OCP=J#P(N3^JAyms3zxXE@XOlIs zwU(pT9rW!by91;i95lW~Bv+EL-0W?Pmoh}9HCT&3@KlR)qHr%1gO-%F7TGpv0Vd2i z@)?s0m8-&=URh_8im($PTjlqY(JOncZCe(L1${q9%BTY;{m|Jp22y}f?=Doo5u2!u2A zdQRJR!CKRc&$jCwO14-7JJxq$jhAq@7TTu6SwFAp=e~QmNAz4QYB|&*oR)Wjb*^_ zkNv8(O~%~p%0nQcNOC8&+F@TqbLFkGk{hz3QkxwxR=7mkEFq%hyeal)Bl1aWgSFl# z`_V@qU1p%6F?RD!AAr91hniRwlgo*bHuQ%}o=0ttP}3S48(s?`gQq!3w6T0gWnX

g9ibJv6{A>5`8#w(%)Djl%u@L_mT&gd{z>{4ta~p7C@9#$!9{FWp&zh-O>Ug zL-WP2(o-k?e696BeK!|RTvn(gS3zejO+biQZ4yDZd?tRsdZAWVRD{;pfoWMT?UT1E z^9s!L8Wnbv48R_QMM%d&&rpp>k}uoa+k^JMwU+60>RlA)nm5nChH&EjqlFbe^w816 zIBf=~mvjgQCTJqPm9WVSK@tzV8Vt9z6s?k!Dnrn6FkBw=%gy3a8!rB{+NxNV!C>EU zep6oSpWh>oJQD8RZ$9B1 zAHMT0=oi?4da8MBjLlod#2oX(;V(8zDB-QE1iV^OQuE+mCKbb0OiohcD(%`alBCG& zoCj;LQhkgu;q$~T$&d$~w)o7XRJ{7?tEoziV3$2RC#>z=6VODf!7}IJ#CH&-)63vm zf(-J?IaZHjU4nA0+K@nsP~oX!kL$iq6+qPO>bfqi(;U8C3+yFvboldS2zuduL(8gB zUTs0I1WmA^4b`*~rH0^{vQ-(Cq~mkxGJ(prZPTm{v6OkqMJKJbNFma^Bcju!k|{Vw zUy`O(JoV(0I593u|K8()Sck@P@}`@-gn+8+{^b3CSD><%JczI$D}%zkrIBY7`Oheo za)+&$x;a&e6pIIU-@n7lzV3mVYdk-a|tz_|Y&f<*5^xDrG zoJf#tfDhhz2SUi?|DJP=Vk8&X>CiR_8ThiO^C7FvVFnNEjU? z5ktWeR$Jo%9z(}vZ)wb=D>qBU7OBcWgOXI8f z%;L4ipb_UWzLFw+Ue|R#h%}ycE`h~thUt5Z=|jaTK)7@dDY?s@f7kgSw6-?oPrv$A zuO;?=8KQf_6dc)q2%{IY&aOg20~%QN_ON{>#FMvZNFSffW+NsvL__YN_i4EAESNkQgNjqVCYZ4?G0sh_M%pi#?X;q7xv3VjFT5@S-lIABC)TGbIH)DBzo0QNTqj6o;|+###`C! zYWXz!Lg&(`(@UVZ&V-g^60=JOdiA5eVdGNJFoJVywolL<}JVzgQEL=be-j>o?JcyJ7r z%U1JW(XZy+AreX&0Y?uX4$O3au;d3+T8OMNRm%WTB5lU}2d-+i6xu>jq;L$8FeVdG zGJf-e+l9k;>0MrA(NNV?%3E7kv!TtO!LYX~t3rCYG{zWEp$y0+gn0}Bw4yF71#iCj z_VDL~cY5sT5gvc@98yV4Z>#9FtMNW+z=P6SHg6%xW)-C-7?*UfktNGR+B!$XcP0hZ zqEfq>|3&`2x!B)W@>4@w)nM*r+sq+8a`gZJAOJ~3K~z^op;E9eB{m*t;)VITuH(#^ zGu(9Y#L_PY$1S%VXSOwGeIh-vEnAm0`H>n)H4jwza6Nu++qP9``~ZHNeXeR0LMlv1 zHdLcl<{B?L_~ zL_td7Xr#BY=o;n43{^v;8W!_8ZQIft!+bVF#~H3_*w|QS@7}%KcH6BSJ931RH-3Oy zZau{ZPTj(tw|@dD)=-Vc+6C6ONoJ|*I!}^RE&dTWY?vWWCu^L0{hS{P2m%7`Jsv=! zhX203d!Z8;7bGYut(BCO3pwgD{Z1}yHAK^}ukDr%Y(%wXQkLZ?aSnH8s|pvo_P1+@t})%Nl2m7{MOwjZyB{P3G0Qo6`~(l( z{|zP?3%&Mk<00@)2Xd9@m1o3Oj1t1~1F@W~i~$iMrzzL)k`-%$TC!5(>ExAHnW&Wh z>1AS3BaoKCH+{Y!%?zYeDAj}mwB^fR{u6%S2fvSHsJHCjzZMt=wd) zOtwlP!ZLtHl3vtl(^{jtE>uz$DHIsz9ZrkA(zb017$q?=qBP?=_v_5Jf1I^6oy2LE zR1ummD9_b{eP!YX_oITBhqV?OMb~!peV?wy(Bq`T2*>8^3Vm;oYQoyugri4~a^&cB z+Y3)FKRdBS9%v0Wl*hHIB-|yA~kwjHm2ri;$a&tX(#M3A$l>M~2cihwav889C-Y zzm6OdSc(aX!gHf+pTv8Pht1ew_)f^8{5|MJ&+D(e$-%?>{dEQj*BfrU!4GcRx-?Ar zPQ919hxFD+Pc>EKK>!fao0vuJOnf(mR82nDi7--8T%XMS+A{~rGH};OgtY`EPe!!X z33)Tt4y&Vs>J?;J9Y}_il?ih^DHRVs_+S89$7ITJVE;bAgqBU8_NXe>Q9c0A1EkhE zwX71#NGU|Ji&Y8P1bE?3WQI0}Vybk-u3UmrHGyJaI&Wuf~X(Y6D7 z=yHE=Z*SAI3T@^gV7sJlE8J4pv4jBU_uq9Li++*g9N3=Cn9a74O0je24)*Lhz<~n? zxaZ!F@rh4-f{%RUBOJQ+XgX{?O)#|alUS=rz!Yx*-6KQ;XdDwhcJIgd<3Biuof|*o zx4jo^Y#J7eKKZn`uy-cigxU5Mv+V_w$r^86e2aa%_s1UWdpm#_=lhpCfQ|hJ;LS@| zVNh{67)_F*`&o9dUyUVxpX1NJ{x!5UG{PH} z3G3LuXD4(M|2+W_=4>Dw%3+YsuRp)9LBb-vOh|7uvXL0)lmh((*C2@fq=p{uAvT0Cl%atn^ z*x1;hao$i$DMdG#q&Z*Hw#*j`wzs#vH#uUz+baF!5G|Xl* zjIpe(D_l^@UM#k-cFwfhLDy{Z&2M~-@Bh9Z{wqgey(X^qORBMX zYuR}1pc-p$)B@bqs<7HKu+{}|#IT3zoI`bM{OMP}#@*lbQGW_MFLiSBsZ+T50;ZER z^v|opI7lr6XX>R_T8Cpp@3Fu)2sF3>Sx*STLhAv@W2^<1KQC1{%+(wZ^ES0F$)wbfb5^(kPsv)7{N9~2^u1y8(q)V`sCIcjT`M_pToF@V-a#Br`aewuV7E*5p8#d3l%3k#9OkvnlPW?{2W{eHdUC1TBWb7cVS&P=N_9b&PH(098 z4NBduk{RAKA_&*Ha3HTMF$&i3X$I-?gEBtV+vvV@fgzt&;T2 zg0*jD)-=|N$}6@i+V3h{nwnl)xyD!E?%D6fV4JuQm6m7IDCYBdvZBpfgb_A-@zO=E zJ#bC7HsOxj@8GNVy_7lwgSnA5)e1ac`@?nVK_xn9Qsw(4C&c9eS3B*CL#0qsM48XQ z>?~i;1V8lTb*_}3J4ERSC0JkEz~PgW3zsjUXT4uk4Rn+1xb?PMx%ci*@X1eplG|>% zg&jL~u(r0w+H@_gKVyxr<`RtGBCKCKjr68zM&{5F&m0$s!CbF|85uD{p$OAqux(V> zM@U#~3!ZrL6&`-*+kE5C9^}jSeFY~jg;u!4=@~+_NC|B_O==NFYu47LfMcN@)@e3& zt#kjk9t>o{_dx|>044n)aO?v&@U=huA`_v|X`v5EV)>z*i?uBli>|8wvF8Ee}tuesii%Do(_fydQ-D;NnP zF>6~A0Oep1=d(?PYNkAS=4p&^NV(L0x$c_%G;2E&hChcW*R;dpoJc8!)u!r8Qa+Db zJE&GMF5gj>_V2rfox69k)=Z0_AJ&4*(4h{R7(9p{Et6KA3;Z_eGPIvuKGkLLSUtF< znDXS)ukh%@Px0`>kMsEB=XmL*C%JI(4c>nHG6;(?GbXL0X*5b|Hg;&%yPeGDJqvRg zA$MRMOjLu>bA*+NK-e1{P{xkQbi!kgJ@IZh+P*shq`~2wFQZNzJc60eq1iySq4YJj z+J=dNq%_RQ58OoMulNR(?VeiZpAV+T$X_)tlJa0G5m)6vyBu1t4)2%fEFlC|2AHU^ zD?uz~T+vm=rbA=(o@&>gXS_4j;f?JiqeH8c~;>CmMPcNkX2@MLnZ@(3~H-d3&jB8JU1IvN~kP@qHOPaJ?I= zLdsxK8>-h3UM1wb=I`D2JzdwW%-{0QDx}XDHedL| zR>(xCMM|7Dh{hjyU8`6ahfxixX_?RGY;Mmmmp8#$+O;+I@88eOH{Z<34}5@=Cr@(X z#0{Lf@g&z=b1g>>AEv4G`W-$CcOoOy1z{IqLxVF6?Nf{0ga9DJOwFxuc8rV`)XTtn z;lehrz4iuApE=8!r=RB0$Dih@r=R1kH!t$m+ZPe@x45#HF=?ml*u9HscL5_LILq#R zf_}b8?>Y|0EwJro%-js6)@kL0ww25lTL{r0g+^c!99fLI1OrgrdUS%0gIS(1rS1Je2 z`2m;f{nYNQ97GQf8`AJC4+6RWGty#%%z`&D8s`YqDzvdy;3_e4b@mjq_Od-ArNrRa z+S)9FufP6d$By&Dw=ax(qSRRQyAkPJvPu;_cFl5}m0&hFc2P2Vrr+Sa}`r4;-2?ql!Xy&OGy zl)LV_i_@o0bNu*mZoTzZuD#}(6$bR6nuG+P7|y^VGSf?~TW1ii1#Dn@JDls&eq43~ zWMYEHUz^*OmtQ=`*|RV6{PS<~=%bJE>UUn`sWVS;?zNX#EUvKVx0tRqOs6fAjgGc! z=*@zro3V3O$GTR4rs*!T*tS>^D#pN9^DXYB_@fL!4}~8A$aQc3=-;tIIEid!x?8RL zL@)4GzBbHS-UmDof<*O!efyyYrrD6x+0nMcuvH^h&>tmHtcFr5H~ZM&GDo|_jav>z z%a+C%fqihY04YO;gzZyR%e-BB4w*q(=<1&?jtmd~d z7+x3E#MrPt!jp3m!IG~Lh4ms+`&-}oR(7urArw1zP7_(OZCb1~w1JJ?G|N_QoIB=7 ztej~sgrHT8H-HL>RKMuGZ?|*kzNZU5<9qk);ozY|+JoPF^uCyt$bpA6AML3qu91AZtHH-vm=i_)?`Uh*)mrYKo6QOY;j7@s89 zWh#9%$^cW^&gKNBt2r0u^OwPa9gDWmO36Pv_hyKWZp-pore1!n{Ztar#tzH86_U61 z-l;MWfy1MNe$UqVORVqT;TbXE`)<1FCVqD@XBy?{!;H#}I8&CDNsXOdzQd9PSpGd% z5W#BeZ_G@ptV~xp7bDe1Z7t@1FY+eJ3OiRis6m!%l}MiCtUzju`?l8d;DZll#81EY zrfXB*;a3ug#W{htmNr0O^SxKv#^wxgV+@z=7D_2L*4NnBv6GuV@Bu!4@4bBAXTO)@ z$B%RT$k77!?*TBTfZV(6{}Z<*%JU-z3f*!3;AuoIsS)RimWaA$c=X-Yl`Xaxnm69q z=K1Ho!&krhH6D53F`jzj46nWR2EDOJ0UJ9NJ9keIviBCU&4Q!H)>teQ);f&6jMI)w zn;^vmVf>9E0Ibdh4C9YrxcwITZAZ7uAr>xVr=-$557zmxIS>5#yUL$uStaDpHS!@M)RKy5 zVwJebat>3r0>}L4ujckv2Aj0rokdA+d<1ySxa_|2^_C|Ihc%QZ(&!QzEwRWBV)*C53bwmYBCxw5^TT3UPd z?&XfV?&MS7{oUMs_uYKtBOl?q{nw1PmxXZN`c-)-tHW!}MHalz!h`6j^!H>8C@D}n z^v9$DF$c5ZdphA_Vhh*<{w!PC+a+JRsCo2TFYvXmeuHm4@B)uL{w>Zv|0pnLZ8B#v zZCT$~M@oxo91FX}o&$aIN3qs0+g`A-=4T4dIVRl>TIGk;+6j8Sz)Fi{MmKG7SXARB zWQ^&Vw30=??Hvd)^!+q&JOtK;7L;%-=5v~+p^*+_v=?GD-i&P_tlw*shWUI!H}T@0 z&KZo^!kWw!O*9FNV69|pYl}bovp?gfKlgV5&!m@eoxIm7kfjPP>|Wb|jivu^()x#i zMpWIkZQP_O*S^Vzkb~?!^SxMRP(u|lpmt* za+qh{LL37*lm~ZiSvr`Th^z-vsdj7fDzK_aR%;EG^O-ymso4^*R4KR>RfBgzS>;uR zl#<>o!31$l4F>GN+0awGKJ^mNjzedP*D2-bJN z-hC6cw=dG`8Qny3==vVnIP_M7v2$jNt$^U1q#3QXbCmQmA?IMen5QJQ4}K*18jQ(d zALK<$ID?wDWqa0p!eG-Nn-*tGP^=()E#>Atv)*B?SJ2gF?mtia=AE^XY%4<2*(R9w zJZNo6DZNs!>gf9g`}Q5+>tFwR2(&(-w?-rXk|E&TsX$zmEQkGaowXx}aBp5-A|YZW zz)+2~HqWTZo76D%HI{Z%xb+#0XME;@Y&G_KNmi_p(#ly!?rl&*%+w?iRt_k!R2Zm= zPL6N}#wJMigs8@MA&I=lokKZ*gco+EUv<#xtfo9 z9`I9ewr=I~^LJQ^W-6sn6jsL4w?0hZ_cS56tnJu=6oReoZLVCtn7APO_wDz(Wx}(( z|Ih#9pL6NLKV{FJJ*=%wY1@{a>lsT4=2_)XYDh=743zGVE(ku8*gp~0d zXne&g*SzT-z8a5zU#bb4GkEOLr?~%{XZZU4f5zG8U+1M4&vX8*1=?I-I@zS_=2-C- zP1B;aW%r&b2M)AsZeF2nrfgr?!WxI3Z=u|pN07}0+W4WllAa*wtOx%sZcBO@(OJn>WlNcaQiFRyI!?#w{K`C$W1=9(Lha{jF+ z{h1;KPPK{MbOhmTj+AiNShQN*;RXp@@tOEfmMK2M>8Pil8ZgUg{r zMxJ?>0kk%J&o!>{Ad>5!#r9S0IaG(|`Tx7RigGQ<8LJvVV-S_zR(hbM1XV;#696xqq2}^bU9UeJ!fTIWZ zg}vfQt^`HmyiIJaO}-_=@-CM+Uu|7^c(*`Fk@yk5CXP_x#WXC0mT?efufwN25)02DFA1aYk)4q7j2cqHUYR znX=Xdh%jig@SiQbXNXd5nD3Ab^Wy$(l<>;BPSG}NSks`S3}AxTwsJ|r-@6blhStHV zMY}$nW1gMwU%6+?3-Oni#d>!t5COutwZlA@kuH1wQ3krkGGA>i$x)ZRJhN7X7s#^hLNfZvAI#QjCp2 zfD)cN28<{x!cr401#Se!*i`YBl|#w*i0>h9V~wHr29>Uo{^x{$R87xKtO62Lv>0~a zlt8+`9G4=khqh_Go|9BuUd-53HVMOFVt%SzdYNO`d%68P2}&5^tP)gYUd_mRUc;iZ^k<#=2*Z@9fr4?h&Gn})?gCxqFgo3K5I{ef&l5cP97-&S%)V}oRP3_5Y% zCWK(o_h@4<^SN)4IK$fdI@7fsoVe*mPMyA)!-ucu)CX?lqaXb+$BrIm&+Y?*BcK+1 z%iglUA%r1Eb&pr1nkAC}M zF1&q_H{X68D=yG964iFBukB*Gp|Fc>cI@hD%{JO7tnS&qa*jnmXG^vq1bg@Hqqkmx z_wJA1&CmVZ&+)+zf0z?TkMk2h`CsydFZ}_Z`qU@+#b5ZPG-Gi{q&J}Sm5;D|`n$iI zbFaV3{(U#HV||UTyMmQ1jy_btdg&PyQu8>gZQE|CJgqfNqtLoXH9@$soqAPYKuLwb z(KIsIEGx82DzPe09_cYe?dgi3YQR_*_90Ynbqyl~6u(`+ra z*(ElRLSxZk5avdQxHahJ7>^-AZJixd9{E8u(9szod)1Uu%L6r8!)Ct85?LL{*9OmJ z`zsF&u@uc`0JY(9Il!$!Psbq9V@k1Quo|nnROYsrKGzu9ro&hrBr39sP{65Er+DFk zM-vf|0AGBkIZv%xD3NVr(%t1OA#ZV&+ElgbqC~Rge->?16Jk#We~36|3vH&hYg1Jd zTTk=(oJKWl&$emXmR()Pz5@q1cI+6ZPMzZVW5>Ano_jcb`ZNdkA1D&DphN0B3tTvt ztPo0wbA5g&z^Satl923%1H|4>A(lH?z}puVTsVJ;OBXNm(o3)N%(LgX|Ckxp_w)SN5C0uRYY+<$Udi{KE8G%gXd7v*y+dN7&|!bt zKr%F1d*Mo@u-14t+rb|5gK@76+=lfKp~?=~2%t$)J5qYs^4i)Ov)L?|aT$a(!3MzL zY>S-wRTzmm1<-g{0}y-WY`zE!7A-MVIGpm`iUk006B_nvcZ)m!iT`~AKfN~WxsUB#Ea z^d)Y(@fNIif9J#FzaI403ZNKL_t)Gcw^!mW6S2tLz@u42%Lh82g5-PUrI{Yxpln=1I~vv!#%z7(OL zt9w{ZztP_Om+Stzu2UCgMXb8Kb4V{RBZEkjkO>lhZs(32{ISWI?)4}~Hfjr&w|QCa zKxkuJ?fcZ6O*aqAb`s!n|8(JA?T)hsup1T=#us4>Rgp&sz-MVZX_7I!Vg>6qY+%RL zJNV|i?qvJ+?c8?jt<28MPK=j`0JMlAIUns+s?u6$6~3pUa#uMtLe_Xq7nx*y z7@`1z!YM|>oU$}rIG=O!!~%~#@&u1R{uGZq{3y@t+0DfZCjpI0`}DE_tJdTQ33_5LcYgan@U5@C6K5TXP<+d4Z>Bf10$YxdECeh0#=6Rj0uQhNHm9;4x?(eaDAE0NNXBpC~f z7f4eb3K(nSNZ8f3Luo1z%7bt?UvTK~3*39}z5K)nfAS^WJYEI|NVpg#a_ZO2tb#Fd zcM15`PAO|E#oNA8UDbG((z`l1st3OPy%nW)IbgKHDB1$X3hZp^4SdIVq&+(8VwZJQ z+RKh4ny(?i8Mkcbw%n*{Ifedm2VYw-*Z#cK!Ih8tGAec+1 zGOpZuB{$x9Bd>hrD|ywcUd0VJ+(4!>Y;c>ZyVgqF){fd8{X-HcugSh=r}! zvYE$;Axh+c4S5>EaOC*296WwM>o)Xx%Uj++F&xEdNBFtxZ@88{Pa2Fl3-nP+v$(i0 ze*Z>yDLY2L6)C65{A*{vG{u`~nqqx0lyugS=OqJ`qLT!?k4&&+jDZTz;^JbxE~}z4 z%X*k{i1(gRzDSwpteBZ%I2-~FV-1<^F&Yj@w5BWzj4ANmVN6M{mvZRPp~hbPa%Ew~ zIk@%$FFos4t%ls;dmf_%x|Bf?x{MiJSM=x-!B@2YMhK)8)xfhej`OAF>TU62Tfy7B zfi)f@WQ^bJ2Atb-`!={fgxomdPbuW7tfumKT|s0WBayk z+;-b-?7IF2?t1lW*|KE|Q-djl4EEh=n%4RUG4X&YDr9RiIWxKl2p<4lS^Yc&i$jU> zB6u^&GFIh-@aXFpL`0Rm7>FZU1u@zKkM8H=zxjLYePTDyJbRe=`HNVWvtnf*W6m&` znj%ROhQkrlD;+CWmMqMlr$05oX-Sb=7UwVEtstH0aqPw8e8+pflYjfO|DMg8HbKn7 z*tc&VKk=cT;46Q9A8S_4;(Y-kXXm!75Ll#BAmQYT9%ltgjQ~q34a$dky%aF?Q_Lg- zlB_?*F_b_U!>08Ee&hf81RwmtA3$n_cLotnMOC74d6grQ5}p{zNC;e>z=e4-op9en z4|3bBx8aPTFq$hi@8I!=A0bJmNt2{@{SFFlg|7C7NOY*&i?b|?Zo`#*x^0Mnd5MwfiKrk~k4F;SN z5Yykf7)nhLv#BxY@(dDep z6WB!T?wp;Z>@H_F(se!Bhs?z97CHWoD!p&{QC4-coeO?EN^0)A?>^rCj<-$tm9AK^ z0=z@Xq@Ld|r{?ZT?W+&BiO(V_eU3uaY#8Z4M!R_#sl-~x!y$^?%CaQSb4J5q-2|tD zKG$4*HP`Ok$?IPGTCTq48m_$JO8WgiSwExK?~$oA9y;TVyV*Tct;yD55$;3XF9h1A z6yOUy8sQY)rx+RXA>y_bqjY`rW(w8m(7^uZ&+@?6cJugSdpU66&-uBZ|F`VC_Ud4P zfxx+v`|p2{|N9UAA6CvRVmVKLpcxFN5VB-`H01cPqliSae*FdnC5I24pf@v(SX{*E zC_J=bonE$iBM&_EAR8~)K$#b4eyjaF2Sy5O^%A;MDZpp2wh;@fbaR9x9}hSx2+hX5K?1Jfz~01Jmi+Q z@_KZJagg-;3{TCmI9$YehgO>0TDEV$5@Un5B8UMeJJ7N$>#0N2wkRA7VT3p#aP~TW zUtp(cJ+?P0%aB2$br0)`Sp1jaz^kpD1f?mF2-37i83`3a>Ii`M(Ar^aq-QISRE|_> zgbWrZ5)ZP6Lea|{T7fCcki1yYyi1EO9A#0GrMA@8A6i!OqC=Z_c z9W(Ie2Hei)Sh6`+p8Xv_`*MdzJDjIoWw!-k%UOQ3&H9!&pGG?dAw`|U*F1!}qH~v8 zbO@^Szi}7RWDkugm^Joe-LjgGwpg=?yL6c)j=Mu&EBd?f78-tBf(IXbc**@=xpEaG zDM&$Ccru-II{P-Ujjn@OiKec?1x-Ly;5z3?2Z|yu7!4N~4)gk&P0!AZ+@_ z<#$rp;V}1b+zHpj{?%Ts7Pdv;17xr*$?f|DwonT>pk%jp)2x(BtB9x<8SmaIL z_6BzDxH_nwRmg0)@#brB;w-rdRv6wpoLpdT?i3&W=&$jXH@}5TH(p9F$pFXs#Svfl z(qHji|Ky#lS-BP|3?db5+IR_Hz4!i5ZQC53s#yK2I5H}*Xx{PGZ{~mh=tue2|LSMJ z3^2x45Pc0Idk4mbHDzkk!v_1!3wph*AqDU_26&){<+GpteI9!B(Q!0wWKI>vkYwpt zdW2#)8j<#e z`u(JVn@*0Q!$jr+RtTg{5VDW89;F;gY4Uu8)(Iqng~bJ?r>0-N7)bliRN7~1&1!sZ z!l~&)$jnP6`7I~*YTlU2!nv*Mm|)XXGwdo*sex}aZ8O>w&PwRjWuVvP0y}X4#++v{ zK{IvBYC4+wjpoK5KIfRKTt#|19}?f9bKKZQp_!c4@(&9_qjJLTqe(}t=eO}hsFcUF z#*AGFblyvpN)aUNdG`6G_kU^tS%$Silt!HMR@b!Y_f(NEs_PzTu;Xi+=Q++=jIkJR zK*Gvo64J_m;P{m<{=pa0nZ0t^`pvX+=ICitm9DNS@z=gW_&_-!*x z!N>pL^StkW_%^VTZC71Nf5i+|fUp9gsM%+0*Q^PmWiN2TlcYWJ+;RT=MP6~otJu6@ zDL| zPUhkF@sQ|@T$Cg_V=x$S^5jX@U9uipmNPHg14IFXD>pLQb0j3;wT zO;paCtq!7Q-c(?7m7n2#(EW6HNVNgkF1w25!ll|ci?=T3zmGTnwx?9nf}8 z9$CfbK>Dy?$FD12QY+GB5ZP2hSMQfqwi?w2+HxSC=+Gkf-Fk<$1wu;Zj-R9~EJ-@P zCOu&L^}9I!!ai157>T0Bth834LbU}-NlH`TBm1r>O0r%?CNef|+{lJam$LoptJ%J7 zJDV@x%=J5O{ajAYTjxMp2e6k2S^gV2Xn;9H{T9b_Je{l|ASW6v8+Xp*eT{7=QA|f5y7i zD{#KVqsa4;BS+`BYWo(Xw@B;Rym~e7`tBd%3xDw$-t^YDaqaeP;0#V^E{;kzZG1h0 z=@ZNj7P##f5!gxyybwrl0~R)1 zM5qyKF1ci4JNwQ5_;Ie;b~$(4el;lxTi2}#lZWWNcJ^X{F!L0Ej_PXVB$us_y#4Jv zxbrpN%ZEPjqgY!6JV|Iyoh#Y>>_bdVEudveVI@lUC@hrTlS&7eXenZ&BHc~U!MzLj zFxZuNv{0Y~))}N$Av(8lfJz}LjU~%8y+mR2MQmb_dVsVNkEX9fQG_$dq?(LGor%^+ z1q=B(q>^|tJdVDe4uzC+42>h}mvQ|_Y#A7LO@A!s9BXFR@X+IraKrUCBAghr{$9=p z2*B0bujZkr4j`RJ7*n_UZU3U>G#+(rSABmyJ87z)QnVnOvdaPWzl9`!lZoF|9yLRnj z=gys6e);9xaNUhddxw~v;N!+$cN6VQ7#FCM!9s^R;3%-{ZB$n$cwrGDY#g2}{!9?Q zR)ZKJ6{pTDa_00!&YwNYnX@^MJ@zDzKmG_$J@yQ9b4NLK_E@BILVu9b?}yO@I8;Ap zHnRxtLN2?UVwf-BBLCOgN!y-gArz`$S9gO|QBam8hYugFt9;LRH(0fLEyej0BuSW~ zzv+!{in@aYrC{f-yEwS-8GiC7Kg0)qg`*cHi^4aUhd(paQ`_3W8dZn%*LKlg>uF}Pqq(iIG}oc~fC`zk7y zR{-QEF$7n)o8bjyjX}sj;2yJbI;=dJm_V1dqK#L)ls2P{$uu|awiS8T&o)T~ZMIlf z65n!WgIxz;7v8X(My7e4+77@nQ8BVqV!fr8r3eIho-@Pb0dmJ{Ud4S6e1%<`ujIy8 z-psD+ZsC=;zmiQGHY_8W9E51$M6hzT zLkf+z0wEm5Xg=`wrNkAL^MCpRz1Da^y%; z&QHbSUA=l8$IhON>$$n(7FeI~r~ma+eE<7Dz<>Psuk#DP@UvX9;Zi7JRC;WFfi0Ua z3%*O3@NQSf9^s6`y(c_e%%I$!KvPhx-&a<>QoTfMFF7F0kaB< zJ6KpON!6G&H{L``&Ye5Mzx>G0@YDb1UoXkhb1u00N}mEfh!h3<%jj>slF43?_DS7;f z#}P;zZX$;FWqp8Lwe6~CYqqObRR)=_SJj4~eH3Ssr<4KVSRmBYgRbf5q{+;~YMGn8o2d5=)i} zrltjH-%yliac)F5B@kJO5*llBv=9heQkFTUNJ%q+b0eG>Mw=FeKqCm+73-r01`}wy zLV*()6Gj!aJ8fePQ5~LI*Q1H*8da9vr%#`bfNok_j(9vz(fmN^=1_uDYCizxX+n5bQs8n7e=Y1N`NmeSx*B)^ZVxPGs}>3Q9+T5CTJO*?)F}L3VUZ4pLoQyNub7sIOmXeC*RpNfHtxLr4!-%- zujZ<&u3~y>IZPv>tnE(6_K4MkTR{= zTh5rsmX=WjSYc>HyB8g=Nu*dS6*M4f99{eT^UrhbwbzEP3yF7@o3Gi(7e7;?Gta7( zYx&;)=|_0;8{b8LDs%@5K$Hltxa!hP{Q0Lp&6)FyY}l|Bl;Yz22=5kUk zFfc?4g%K$aKJ*kYhbN(2EbwEK6(lKn?%A+r4R_ss6Gx96rf{HSz){Z3og!6&M;~~E z_uu_t9((u%d-m?8EH0u`i&Bg9`vT_-GpoZvpGZmR!Xcn_5cUOuYRKy-%d(D;t@fbm zzwZbCI}GoJY;+r=O~Q9c|#%_fJ@e_r7TO*EWuk>;}u=wtBKK3HBX(W#$6qFKiLh$JZ|U5bJ#XM(E*0n z6<>!^y}99b={vft+`BA8+JD->w3wi-vc$$-DTOIYKtu;rzXY48HWd+tbRx!P1}Dx* zmf3JP3`*4^Iu~atS6p!gx8M2-Uir$~*|B3s5X((Xvtq?c2K~WAYhE1;-j8X%-tZ|XzS*8ugHiIo>{?C6jupLm9+pL&!hpV-4Q&+KRJ z*l7xP0%LNN1|ck7mI&!Uc(Pd=0o*jshjT``#alflIm9tTrQWtN^e2p6t4?_-MY9?^ zR2dOn1yN;1(Zs)+Bf(l&>L;BJs`qSSgcUxfL|7LG4<6*2YpxlqprzoJTW(>L8wN9q z!WQ&r`dqScHFv%8jr_{5{t`Q`y%dkcI#4mxXvK;?AN}}m^J90vpC=xBhC6P*9aDnR zl5ctK&E&(=cHr`4cmJL>v$KI&Cmk0S3Lg6EL#$n=`O&*S#J;_6kAg{uRGy#u z@cW{EMj& zD!;0#%C9seW6wBQdu&M&rY536MQ+-|3#CXC#mI(rm?Q~O2=X!zE}ZcwsR_$KVoX_o zCTlH16}Y$uDwSYOusre3V~vj%^N>twj-Ncv+S#>#XFn|A|29PU??agG;qbYWY`Jtj zQ~epV6%$mrE(66%u^VD(BV(%S2#j5t-@x*D5$)*P$pb2mX`~D@NjIs}XnSEb7gd*s zS5xi1oTF}=s@t^tu3s~5I(X_>)-*{dixQz_y%`7VWnH8V3aqz&tDS1GyOcq9})ukFOIx-l4AyOCA` zJ1LTQZ_D5!(5hk1Ux25d+Q*TjbL@WlS)SYX0>_V@;Kr}^-QKZx_OSQHW=sx=@OmV$ru zjvwc1U;jEYvnTO|W!)v0vhI>CoSZw$+^IRN&r#|EMKO<7)2K91T7{0ehhCu&n7l-$ z3MG?(t2jYf6j9+nNjj(!9IdrvSymq^)w5evb~~*|gbEiKn(t8Z$0nxY6S#KB-d zG0fw*(NdIobUzRn;n6~(B8F?NWjg+>j#wg*sy-MDLXjDj^1XhaGB0tZrPs^QQeiQZ zR!qvq14|=B!e}%i%hHL$BTEwY9ofg{|Lo7X^R~O9Wj``T(gOUh9_Rfp^)G{H?xKEq|OQhSGKh zPLc%UCc79P0n7;+ZYqNhQ&BQ13ryj|wMaCpR*_WOCk(@g!Q2z2S1B^U^}4|WobxsiL)-?r7|#{ zOzF@n3sstMI9EWl(+&p)!8JD?(9H_7?N8Qr^X)QY?4nI~g`PFnNVC#yvklvS*Z+tlQ`)N9Rdok8@|w^6J;Vjt~9hhq!L%bqxA_j?bOpz=0R|%xAyIr#|(k$ZUj^ zClJnIjir|j5JHiq0}A6PZO;7sS!SjNcrUTeM`ltP>G@?~3KK>|UIq%fDWesPR&}Rd zbqu{^(KEdO03ZNKL_t(uk37$pFfY3f{iY9J72LJBxVVJeLc~gXaqQ&ExPD|P#I)8J z=O}SOL~9*sHKK|Knve8(r4*(tnd}+oFJ;U8U{6l>3hkpDU1p^WEWCA(>bGEc~2hvsbg^k>XDvO4?H(G@I z4p8`|0Oc-Q_3_s{N{$zb>;S$)ve?r2+qQastfC#ytc3{GqKeL~wO5jqF+U<;I67Jm zRC&wRhU&tLpwOL~p5~HE*0Fy5TCUx>lgl@6=9ZgoWz%Jw*uH&xZC+iEks`Jrmsqce zDC=^y2v9^oyO|PL8D545DcW(=7)3mJ8h&8ad%k#bp5w<(Gk5$rhYua$@yDO$*zp%R zdh8@G96ZFC)2CxMcZR`KMz5z3%459*41<*=h!RSLcM@kTMck;Y2|%PNLNRWN;5{_9 znusF-Uo?X8WYly(S%z74z+pq8n-F27)uqI5|J@Z`+hv5=)sYDqu!&F@jS~pl0b^}E ztH};*Zgzp*84lRF6DQ(I7BSaCGLyjSRWk^GflZsX@N2*Pe^B}W;A^4y%fI?G4?Xx8 z-~Ce(?JcA`JupQ3h)jzzM;}e)}`r{obEq z)dq_xN1?k@Ijh#JV9&F=dD~mx4rD0br*Ju13s$XNiAvAmT#gV~bhFJEjY_okXf>iJ z7b8HOP!u79!?_YoZ@eE^jZh9}L+N9S;8*2M5t9H_J@T%yIgB0OgK7h>sJdktyW*H1 zV_h&IR7x_+hxGdcbdm)6x2;BzE;8)|d6AQ4J!B+FcwdEZIfM)trigy+ooHd4tenU`IKgljIv61&!po3ZV;owFV11JHd3yKL z6KaT;bqC@AXG*fGH!xUmsFA}qGQ^itICrVj+w|C%vLzW$C0D^8RqAZ@;pM7teEYS#BdyI%fM6jB`yl_ z!Zi*LU=iSku|_9aPju;lnpJ+=h_S2kZ+~B#w%o)ex;opg{FW~Jo8=0MYWy^DU;LzL zWxH!_TlrMu+~xsgt)<`Z)9>{-bnsB*w^ssI$*b;o11}ud&FM3zIdteK>({SF_zEYi zDDee|lu|er3(5Aa@4yuY@#YXZ(_EbQ+;a1s{NVfF&n-7yjg|@LE{yoxXTQ!zfBiQo z-6;mW5kgt2G`=JjM^(X9F@dTK7;A0NLo`RiwpyE>BvBY=8+JYdfvU4h%CejwkJMU; z#(gm+r2JKr3u_%(%3$*$L~TVr7yM<}VuvOdE?kZ6VT1xg9LwWLXk)`~n2Lfx#VFU#pe1f(3GR8mxFZuG< zzk>5m9faKCjGX|JyXdY@UWH3YmW)R#%AgQFb{3WJP!MAyaNeTim|7@BhI5LtFf0}YWnnmfzTo-i zU*PE{5A&rjJi-%CJkHU%L%M-eK|r~wfo#aSCwv=U>+34NZ(b6351 z{bT2+Cz&tab~_n&Xo{w!hLWSzA9Tyowc4p1A z$66D)?`qNwpaO)4!y$|F3$cszb&vV&?|e6Z^OY}>B?{pO?B4Szt5!?}$}~29SH`d$ zaq!SNzU9?-Q`&>%!{bPK7UvxO!AiW5al2w_TE>rf1Njq@hn8yBKvI)u&9b?V*RAWjxiRk60EZk)RyGMJW0|+0LFMM;{!}ei7P9*w?}Co2`!?wHxX#8 zFR{ju#@A6g_-j>bEQxqap67L!S{8;R)uGGsmZBIlSkp9RAy1K5W~Nfg;Q}fN`mAc- z3nMni$T`lQpX0;}C%-XRSRr7_vSZf`eEo?7h-K{0+lR+QtVlJbwRmC4N0Q^m z&T;JM3I6nR`*`Nrr+DDOuXFC)865inPcIwL>-EWc665Ca-mrRu!I}bTGpsEr@)1hK zftWMl{k%g8k986$6lD<-+N>4Pa4uA*W7b>v+f{VtI)ukB!4%s5Va?2i>h-!TSDLfz zuEU|-)i#Tom&$VK>iXK>TW>~EVdC#Z%SuMIoD14jb-SYq@unqNmPIqaoQ2^c{cL~~ zVFPwTvF_5%LBnwSiv;Au!ft0j0`AO znnrQb-?wCZDU)?&SjhL#~xqSDmVqrtL7rzv?J zMo88KolBM_F^ntF#=Q+=cr6p04b*F`HBv})n&M1gAzBm0Sora}P)gzqq-h^-3`!>~ zEG*D(TJkig_LcS|O|ziSiNR9dXS?Zo7?JZn=f6S8YW}MVh3+ z4OOZ-1gN%{h)e)QV^fl2^Ka?Lx$YH>*ZR0nMQk>r%GSkhjt&o-V6Pxi3JyF!$5;O5 zQJ#I~1s;3sNe&%6%Hg9&vCdGKi>z3c;Czl&qu7B-re{YenZ!!(BBeP4BTZSD3EPop9k11JO?N^&;lccd{ z&mL~xbyKkQhziSVuiu5sEoD+7M8T@HE15g}Fu(nK&rswZC3^_-B7=SoazG&k(rc8^ zloXU@POq1d=QfN&ouI$6&*DXc^9v{))X>5V0xjEnbfPiN25dkGtoK-BPg2R zMgs*kcBn1{dWDHXf-yD{CQ_Vt6Ku!|$51+?t~4VcDh(B=XmwKMuLQcRi#h8}7iO(B zd8FZ1+K=FcWhqVYnMxBiQGk|3iA-c;3X&iR?zvf(QIsQ0Y0xOVFgWXwsjP#8jSrw{ zmLzo!Ntz~6jM<#9SY~GilqPR5_&gGYN@5oxhe7rbZQyMgCL~FsB5l}^7X@jWFz6>7 zIeL`KF4_F@??Ai=^ZHw^xR#Ig3@aCVI29>qeyNDBeTcNN4%tw-3L!$!j36*@5;#nF-53UZG7m8A}rV5giF8&@X;BM^da{{0L}uan79^<4XrC0fmm`p=k7>CY9JL9Bb-}LOI7e9q z4U4NYXap*eL70VFZKL4KW36G~{6ejy9!yWs@AtX=_S@OEZ5y}TatoU_ZDQlbjjUR^ ziWMtYETOu3CXM<;HG+_nlS4l-cbBn^55l3)E>v#0J_y{rKvvn*LPe$!bymc=3nLzR z^Z-vjwU-0?4|DL~90#7?&%(KroIQIA>w^eT=n+x|4=}011Fi(5%HW;HMDm7rVN ziAH7ob(YPHZ+9DQ>zk&%PIKJU##h?cuU!~*9TZJ_{pNLPUmt|P*)a~Nq~!kl@8<{K z{{zjrG1uruJd_UPp#jN`99;+aBpE}3 zF?b2yD$3j;WgjWQn36OF^p?1ZMpx;oQB)S2LueE8*}ZL8oV>zCpQ zlNG;jjHToR+p3E`+r^S<+u=|6WJNH(jhi*!qhiuk2if@ZsU@SPYJ+NSq-|fc_FC=o zU~7km`3_cDyHKh|S6!pI`rwozm@GPhlfh>GvBw@;>i)257MZO;c!w7`E?)cUU}!3= zE5E1a0ou%xX~wj6=~sNT!#5^aY*ZF50lW^_qE>-qQpXMZF;j6g8chJ=&Ffex{M!kf zO$L=}Slzd?bZYA!p}~e^!3sZV;-i&b!-?=uaMv}#*1hV=L|{!;8*ydr@5R^|BGIyD zWeIe6p5$b4);u)JvP8%3Ib^;^^?kF*i3hE-77-QdTI(34TrwJsTI%<3s0VwefKgg& zf^Sz@GCMWPvrj$yjiCdnQWvI^0kQ=83Zj}^_{mI<<(zrjxfT~MUgTGP?N@p0Ti(hQ zS6tcYDY;w(ZKFsV1KaV?P)&E*>SqBjML2Nk^tmWVX;`LI`P_4742KS%;OyDcJpcS0 z&pq=zPdxH8Pdxbur%oRSN`xAswWL2tP+HJSEO}94j3t{=7+2ziz$t~pu{d9#&;fw+ zHiiQAF)k$C2_X@}1cTx#{f?$MkQkQZmtXw)2UZtlyNy#cZ69P*hlkBy)>LJszX&Y9i8EDb0zf1!<4aF57fD=Pn)&njj~~8@IDq6ZAk; zmr;Sw?e)>@j-(hTVFp%R@csfHE%Tu$M)Bv}1R15?bQ-CD?L)ZjOgzEV6hu9Uqbv%% z3gff9w3OBd4M}{>aJW?e9lC);t6Gs>S;set7-furZFVuC5-hORqjie0fg&5a2_602 zY-LWd4DnJs6mm65Dpi8-lP-(BXr?ftGEX^Uyu&^D6J{u zJu{|cadDA;f6y4o89b)JTy@dwYg|~(&d#v+*?r9o`u`WB_aEc{kzV43r-wlF5(Z{S z;o|~jX$VqtF-@>=Jm`oc%=m=2-tjiBxcpM255~j-6H&4-8bef7j)*OMs2Cg}LKERY zm?$(02ZQl8s)?kg9|+P&_g`?+&&(D>~YHc zD3CLi^bnb(Kc$i6NCm4_1y)HBTUOyLt`IEb4X0n}5jL6~n#he;J**3S^ss@*@cHX8 zPK2i=wJ@-r-BW26#^aVQJwrQGt1XzE80AD8-H@!|f|@;&9B2T5WB;hic~+pL$3&rH zmD$o{$xQ(Ejn1PQH&kIeRizf#J(U99k5e4+OYCfvN(1&|ElMSTox~a%LcONF_C)8} z=uDbjLbcIVpT8^DeayUKa^$CEWGcn(qt(ewP|&TzmLZ_X*^(^PjD`zK7>xkeUw1wC z-gg!)PhtEN(i^O?u`v!KlS-xB{GFTKT_v^)X`2#-#93eKEO3E#t)&jwj1sl6r4S;p z<zpW@*MS&x5!&eCP=i!|EP4yFeiXwhX&nlB75putBMUGjLBQ2;muxf=QuL3B$!j zj0s+FES_)HIUvMk?MGm^m;vUd+PgB3OTI<8^F$TFR0*XN^gt=j34 zqG3tX95=N)s-V;s-3|f`fnL+br2V_J-@A>|OyC8r{Ft#AmKxw!DzXwAS|w*)=g6qK z_SI%vz25x%{E|_bl#;F6xAE8aeu-44fs!g&!a%F;c{4a^xd?>%cN8qKY^jSsGk*WJ zPn(Ll-%Y|o6>Cr(7}Ygx0^FfXa1&S!(qXI#L=HK5Zvx{|MpMsmr%~CNG$Wk75Lf~` z%f{<4zVDTi-Qt}<>l7ygE7VtNOdl*tMtKgx1=4`E!F*IeSq8IEXKWaMM{~n8(J=;0 zQI^9%ITj)?!<>lExo&vM8RqBDlO&p6KSNrB5Sld2NL8OvF<%o6!c%WCb_CL5jUmf= zAX73O_P#Tx&vEqBQ8upK*b_%82Ovg({e|Cm)zCf6`>G*C&%o2Yh?@>|&`{HPi zyl>wDUe9ZyWdPu+_FC0e8@`hL3KQ%r2(wUQU~yRR?BgeS;Qj~Ly=O09{o4H;e*QRx z9ibA7)DEqNXf-4+a^@E<(C=leTsJ_dge$Mu!cTtigY3HHcD7u88L^?o8I90_Z~e#b z*Dw98(=|mBFEuqE?KD`x-3P zd%cir5rlX#W2eEGYu>l&fT=}$QX^$d*z_K2$A*jHnlM4g2*015IOLj>6cd@0O}r+p z?N7pbNVH;9y0KzjN<=h^#Yatv2rREeYFsqPw8GHqrwsEP?NgFOkSIx68qiq{(yM9& z8+Bl5qHrn%`56OFSds+#y=h)JaDYqKUfM~Qe;El0E1=o4e*Jom%$=UF{%A5EmgUM< z2c)QM9TJYu9f^Rp3X4&BL?qG~;K-3hzIx9?%pE(=J%95Md-ojR$gwA*O$VfDMn9eB z;_y847fz6@$XK^_mWvk`c*7gs%qw2`DsFw{OtZPU#5;qp>y^!5SL2FTkLf13%` zh4WMgPW$(NDR+g5N;zseTtf)iWM6gpu2nx@jhwXBBuTmoz86uvm45Q%B7Bo&$ND5=oIt|t)Izj7{#o>Hy-(Hp_&bw%F60tlSTBZmk z(OR%j6VKFDcb6?hlg?LLkW>rMheWkeQu5&L7x>SAcpncx@+5orKF5*g zPjF#)g0mNnlcqg}`9;#SWJ+4jmGdMjrPmMIg(;bF>ik(g@rmDO>-H;IyLv63eB|r= z{6GB{e8-#K&ToD4H-kk1GKl6}iIb6qf#B4EIWAefGRzFE;j|b0+`sv4_CNbP&prAO zbLU=Qq|TFiPw9N^ja30#!IEB1=p5RWW*3FF-GwYiyKQ$M?NLaxQtx`t=7HXPJrx6u z>cgNksF)O3Rc4|33=dNk9@c*ScFLItVDoIU8MBEM3meoxW9# z4ZHmroBzK)Bw`ke^KMB8-9<`hkC_5E9S9GlF(|ELXx8`uElmkZqS8QLwbr6#$ktFo z(#taLfA9fb|Ase=#gPiutyvxPGBQQ!U?DV)clO{XQz|P!xvP65G`6S5d01j^*Sue%;9Hl+Z=g3r4gejCtu~9{CoxwRzFYRNUV7Rz|myjhX!kR#- zwlEy#B#CA;8j&U$(n}JbAPSFDB|6P8#$lyKXBuN2Ygb>!1CQL#4}IU=Az4z3|Ihg# z|1cOx)KEC@*?#qQ{-h|-^x~9BPK*xP44kfwBdDR_zQ;bxU%mG;r0D>h<>LGttJY>* zwtXAd?%c{1*W8E`lCMATRgQfAFPUAp61@Fe*@SWfP zHlBK6FQ56NKO{i}K6+_7HmylDZaZ?e%k!yyU6#Ay%Q?!ntNpG{r%N!`#5sK6JlA6a zV{I)6gdlROHjt`v6w3hf?Qvy0@T==HkJrm2ldL&vX&<6(8=K{>lWoyK+xM)?cBdHt zhQ^Q5-YASMni^cr$lf$u*QLK^pX^VAYkA84~x zM`4{^(%rP9o0SYSWD(b2*vxIj4qR>4SmR7Y+k0auO@VcmjF4lVXbtgDa<2APsWG}* zYvz4qja8ZE)E!g(TNm!%w^TVQHxFroCQ90&i?(+~6All~>2 z001BWNkl%aFYp5AkgJ`*EH~S4kFu8A%*UFF;KQSJ(gKowO=+eBMDGgr zYFpPV=T$X1&arjTQ51$GQA-ZOb`jE4GPiBi+Xvfn9#=~`896y3tbDxM;74Jbwh-Ujuj(rOF>3z(XjqA-TS=2&AmfAIoBNcvM#Y}~k!OV_XG&2N5l9ggOs zgTR_qv#@d%s3e3TV`{38^F@57Q$SLBhj#Fu9j{>j zZ~PWN``-7mS|?0T&+@u=z6s%BBq8;lR0w|H!|&slKKNn2_~l~^&o~y&erK!#1PkZS zz`&5ZV`wL_!!ihjVir3d&d)EfZ|?!V{FyJ3Xo01SGw#VsY`Ji%=J=(#Np%Cuu2D6J z0Jb$4Rezg(NBcdORMw4+WI|LIolWci=V`rf!>o|NQt=(^o;K*;9G@(AcusEm)Rf&Y zLmyj^RU?=-C49odzas#wt+{}1f3}Hef%qB5#lced-{#LXV+ZODB@ZBcPC;H6$n#K% z=7yCkR(}F_MC(vtH-vyq zW6eP2RkdEjMTcM?DaNIDpe7~3&BLm~bSl%wiRaD*&o7GwFG$iPdhi7!N#iUk(RJNi zd3Fh@#_r4rv`m88sRuwhdciJJ-+&AnMrG z<(OFQaZ4}&G_n13te#mLyV?{d;Ge$t-*I5i^L*wLzs#mBDf3$JFJAw4{4KsWRXt7y8a z3uu~oRe%ajGZa%bNoWGpB13tIBir&I+mdBjvnAPj(i`r*=bSzCAA6s3&pq!xQ_WgU zxx7|JJ>7TiIs5GW`+a}kVd#PnzYrcLET4ViI3IlY!}wwV1QmHYEy1{$nm1W!SAEx} zsb8BC+O`uP*H^ez*%Xt8-jk|%(V9awH_~Po(>y%tXCR1nDF&s}2>pzFvZ}Ay{NCdk z;c|?Y+l&#N#1@-mBT~^TA*MP;vD7$i*REnkHH(sZjwD7KaJ#w|Qq(ybQiO_ARUL9g z`!pc{O=(rfmBwh5VD%plGv{m+n57K!Atpi?y6gYtiLFP(H8G+wi^jF-I($k*olZ^UsY2B%NKUCb8(sL(x|T|W zgHA+`zKT(*RqUcfTo1uLHyny0-a}tQ=!r_O7OeB6T2U!&^1NWGHytuYTpqhhg%F{G z)mkD{3@~#JAq_=tnd;4u>WrnUD_mW8osH`@j~u_>b{$Ae612cJI>F{!Ms}?ax{aoF z^`u+|zly0OLshRs9Ol$?iV>c~g{+0Y_~O51!$QK3{@};?|_5c|NRI40V+}K1vc*6Pk#0s3QwN*@v*u+`}#SQG6?4=SYqRroA6GB zD9yz1j<36euYBl1?%Kbby|>-MPyE!!`K!4jd^l3krb=CnMt#WN$jGv4#4(5N;PH( zZd`cShGN>CS3Ss2B4szWQA#RGYwAPERl!=$)oSZR2AXFWc!rHN?PNh45EaQfRoJ{B zFY>U_4?Njam+d>ZbL9T}x%I#S?!N184jwwlz8!n0>i3`<3L8HYi;c)!6CRw4f zA6=vc!3!%*(wG+`qWPka?y&?1h^7ag5J80JJ+=&{t3_Fa&(x}>!2>l6*er;`_tO!6 z6Xa!pdn$YO;8iDL1c66uSvxv}&k6(iDq}?|iOMv?VIH2lw4u{*L6u%9_?-)M-O8FI z)d|9Sq)0-+V@y{XJ8s%s3E}_VC(ln_i7!D}E?`W`^@Yn(4If&;tf#qo=T2_E zeLuL8FP?mr!Rco>`uxiry!!xNdEWnxALRG{)z35SB)XHJ2<)%re1Jm4R5FPf8oV?p zpYWc;ck=mM@UUE%&W=YL~TZUqi)Y0CT*r|Z>Y9HdabzNNnS^j z_}@(iP@Dd{)?j-Q6f}8uBi7V7tTGOqpbcqW^Ozk=17c~4fVZgZ{ve)OqG>-`0hh|VmLr+heVBK zYbd414u*<#RU1UcjkbcQDwwXRwGkpfAk)*+W9Eya_gJ8n9@phWc99fv3__`(z+q92 z7Zxp5x@!pjn(MgwnRdG5Xog{GxYNc6hvxc7)0DwrfcG(P#M#C>7ZNmu6If%wjj~Mg zJg>Xx@I7VS5r*W#AO`d^b)ATKq}BlC`i8irfOMYO+1X&t5Utz`ljB9nhRxGqLB)0_KYxY)@&EYM z8lSvp|85qRuQ1!~U}dmX{-@vj{rvX-_Om!GkUEA4NI3sy7&xU_MxTP*6^NKdK8*$e zsh;NI#UYPB{RB^a{&7@g4P9@1tA%W94UpHO=dPvLZx5%}8q%+2)+ZR5KaPdmwiWVg zkRK+g&(})*TZ=NhmgZ!wZm2ywtGb3s868#TwDqHm4b?c@j4@>0wDuqJK3HR{tPF6& zFk92zgoob!FuQl}=DqKIFGr3XVc*sr2qnqVEHcn!WApb&ALz1`_DMO9*Sg_EEo18u znLui?V6UR8R&;hR3qa#!U>2#UYc|fHWf;(U1UK*7N;z02?a6T#S%gU@t*iRp;cGf< z+s3|zIsHh`SgFjLYs}g(c&?stU@29dGtnb0%q^sVt10(#F>C@B=KH`XCL6cBI?vs%ye-S zg$X8*UeN3HIC}Ib^6w@@|NA;X{0P6rGc!F+d37=J#G{pf8->7BiF8bW97YR0q=Lyb zw1KlTGvW1#6kqe^bry2ZPyX{C4-Y~r3Ol4+9P;q{zcS!yQZXwfOjR0kk8mY-&TnSJ zp55ffPE!o~H9XTdc^p(NGLy~m%Rl#f{K7AOhF8zN$(sx3xc=r@a%0KefNla5OC(Za zXc7ZNtTw0dYl{&ZqYcB1(EtG>1j;J}B{!|x z2u@?X!%2AQg%{Yjb1zA3`%B=V4}UM)H*aIp{0zpH^u6K(U;jOveepUs-nh=6fBKg> z^1yzcef1o3ay?gPuJJSf@)!7}Py8w8&Yk1@`R7Te2jEitl;=}_^U1hi!$Q!BL#mS0 zga}U;{duI&^(I$U`jyDeRTdW3)tmQZIxmq)62pCjrn*^ew$CIh@#c#)iH=%#CxpYT z8q-NBpurkyE5VyOi;C{qp4BwFhe-y5LI`A*Vys1pAWjrYlIV)PHXeVflfb~q%YK9n zEJ`Y5lGbjm!Ccrd$cH#0Tm4Ueh}9Caz8y891))9KvUWbiV+#2J8Qkpfud8>x(%@zjTtZS%#?iU&whiCee^qGl7IoB*|L5; z(7}-+l|xvM)`~J8;DsF9^r>BfeQohy2>_E$F#U7JU>Rk!QyN@l%TihMm?nfMFg8aj zf%Rpa;e>a*BT|a8M5hTwQPeTLPJmB>y?Pd5B@xAiCgzG*Qj$bs@*FJ{nbZ`@Ba{X& z7!)N!N_3KdF*U0z9EQ<;-6~93l4cp!m1q$N5n6_!ypRIp4Ju0;t{4KF8&FXClB6LUHBI1q4AL zEQNeK9w5}2=E4j1@4uO+|Kf9WWKi6;H@->pfK?wS1;RV5DG@s5+@*^k4cdn)|JGgm zA|xibK2&`F5B)P<`pduO`@ZelIsNh?Uw-*ne&hFlmnS~=?^r+Ip))1;y085@N+B7R zOZ27%_#vk+zKFQ|8qOM$o}(-zN|ZQP0tzLAuU1hO0Us5C-Llp&dMsgX44PX#P#&ib zPKJxt5*@ay#4$^Vwz*+r@H_^sP52ID9ffCN^z0;PYSJvL`FpK(BvOI%$Rt525xDz8 z;DjU1QVfDDO#@7#6(SEqM{gZv8Q5>VnOXMi-o+gU53*(J77pBcfc5k1x%<#vY`SR^ zTjp*{KbZnKw%`6aW1K3=xU*hZ|t!&BT&sH7B$T7h{ zgJLeESS8%7;GEhPMF_N%lxx73QYmE6=7o$N@9M6kEQ|0=8?%rmZMdQWH-&)JJ7;|e zK#)>UT8kDM;X~IH1c7OEfDR1Ekb^!Nq6hJyA=OdW;lWvnbAmLP!n#3lKUSR}z|E2| zZ>_ppa{7K_s%+tN;NA> zD*?w|SpgYx?YC^%%>4WYcJJL4a_RT&XWzbkY~Q|%EzwM{aXJK{pRpkeyW*5r*XOGU z@u-#;YtNm+eTiLL1q&z{i-zc>1l(9CxOVLZS1w)U%$YZN_0)NeJ@W!5UVfDe7ca7K zeUXxLNGX|~?vkd8q%#cZd7YAOYH?Htw4pR$oy6Iqp8t6(DNPiip>Qr}C9Yq;PQTxe z5vSohX#sa0x{H%1o*~r=oT|+Xn-086DLkt6p2bX!%2crdX|-n^ZI${c9zaa&M5UC$ z3MaY`*Eu9USRaXKw1{(c1Z`6@EG;dg6Fnx5OmrFo=;Dl} z=}w?^67(iIiR2qkA`+ZZcw1tnk4!mR7Xv!$P?jaehGD->!*wJ&3;%y~DDI>);TaHM zJdq|`S-Hlh-u&AX!m0^a;my6{j@uhN@yL^wYRzhQOaKOnpxtL2HBIYtvP(JUgo!CLy2)k zy^!PnP?NgJ`f%}}6J1xERdrhmi*$x0OX+4Erst-)>&`p*zz06S_HEmlo|@*q!w=Aj zs&~J7Sw&{e2+y~bver3-Rv`zYPLhj%QC4IP#w_zkg^Z_}*=}vgVjl)8H@LAd;L4Rg z$DTUJOE105(?_4@#TQ>@vHuF50jW^Tt?!~VNagU};I(CHuE6Ply<0P2Xn-Pg7{-=J z;jvDjWP))arA`nIK_@&q)s)T>+&JuLj-irTH9bzb7VOxulhUTKn&^nL~gi;78v2j=~rH-_2UE8HJ*LK*L zM?yv^eWZPZR2t(-tQ(LdGpzK(p@MLDO04ymXnkU>rPrHgWo3nKcPhs53Lr-*NjdbS zoheFdao!+B(4mQXmR8iW(JYfI{qlGXMZEm%isTv3usOCkHnnJcVsXal_S z3B-D_m)VeX_1zB!L!b^l?&ku0Vh&LfYAAvy}B=QblZ5t$Z^C zsVxd@b|aGp+N;HVuCaAi9zNp-Y%|oTIY@6)ahvxVptJ_5b-?E3=yw`x1Krw%=v%FI zAdgnhKnSdG^_gy3 zc>dTqo`3EXkACqOFTHr0<^Ic9meFd+>|6(-u9J1TA;xsdvwk{KIfccDlEPSoadnzt zVGB~iCY3~QC0j-cs|?~jEd|yVfh6E8NunXrTOJKP(DpfrvwNhqr>M=6AJNL(GnC1u!4L@at_Y#r0+uT}YN zNue-4Fr2KjI8%@%k@{*1P&z2Wy~i8qCJEL!I=zgg#btCS!8sF!s>RqlTDwgP7rn&< zI?00XpYcpj&tjd$+LAO)qV`17>r9awgU8`w{BKt$l*Wd+hLDsdhyshklcgOL5|bDZ z1EeUy3T)yi?2y@Y>w;2WfTbi;3SZ{vBnbonw-i!G#1v9428(x{ke8n6OtL=haP*6R z$p_y3zWRN5+YQl$s1ocvJGN}2>i4x)A(_jMvv=%-c-1w9ZBbY#7};U8-Cl`m_x5Mh z8>*6H_6_53Of$P$jG2x#4}n^r# z-OBFWyZO*JeG|9uKS0{)1U8A%2u%IVoOdYn*mGN5fOwQ}k({TIXuJb~4wWtzM^Z-z z#Iyw>-41Hk+Z69YRb1wZr=L5^iI>mu*Ps0|ubsNeGf#biyu40nZZI{Ikmw|s<)tOY zE|bjUteYuOva%vy0+ZnSc|+$A=5x+Ed{lQ=#YE^N<#-1bXL?O5m+DYcDjbMaW_k6m z+S#_TrYe2IrAwFCwr$&3$9UktEer-L^k!us8u;KSTb8z!x30!!6KxGmQI@1q#^Ha} z6}vHAhH4Z}N$eOaBgQt9uY%ExEyuGrtR;(oXY`H)>yGMBbIvk7Jx!kHI2W!tOVhyW zjGwK>Le(rN6*I%b{kF~_Vt#w3Gm5xz2LY)-#r5CRn^f;(O<5KxiB8D#AwpVAS)kJl z?~7orsWpOduq8=Cf6zzDIOi)(*aN-9m^@^WxROpX&GPaJy>6F0&zb7>=&$tIym=G- z{(vk?;{N6s4*MZdRk@INBt;O&I#3~Pg|w>~4p$=V*vP8EVG$gA_W8d{qV3=33?yQz zIA)WKwA+O|w2mq?qrtkMG52Wu@U#cC%|oWWiB_?kYt08%4N}+0ELbb(Xwne7?RnI8 zx}7xWo@8Gl)=(ff|1;25lT}&VZCm(uyWLKg6Eaxkt0;ULmWHX`R2V=yM`=nNo|WMW zW)SSG6XDprc{2|`{4ftZ_yBu$?&i>;L#&^lqu1$?>2$2q8fgWnokelFZl;u1R7CXV zp+9yXJm7V(pl~9%$ck|N&PNrnaVTA>jG-t}&YZc*v8P_+(JwsDGf%zDnKLhOW9ce+ zu>`_0yS^Wd7-5+ANoEtIE$DcMAjLS3HI~9u6FiSpSx_#yuzBJG#dTzrPfd4idq6d9 z;@dig=BC|T!|i(#qK@q<->Si2!20#`96frJ`|i6hnw5l3;?Ti8xZw(JI&L0H;H+CU zcN7x{8d~d0pBv%6QTJP2Yvmo4BuTJAse+ao(CC;Gfo;BTtHq@uBcqR!ItuUtnL<`H z{n!zWI{gxzq+{=ou?Ase?QNALDY)@Nx_%!-<*HmAFtR?~n-Ey#9IWdZibU9$oT#FT zO$NBdx-xWCjf7C8RG|9i<>>c_@q3XZs*V{B2eYD#b|+P8p_DpA1xwIUGRy~vq#MMD zQcyaB7D)`t@)Si5!jdFCj0yMAx^So_S%(uRPcd-;ynR?$L?v#x!kMWlY(5N}{4!vs z4mXhnGpQ4qG^B01txjS9z12UHF#k!LeiI66o64y71#Z(ROOShD`a%aY)7ZI zyN|Y~RCD8MGGxN_JNo&M#r_f%FfOu$!}s3HyB~gp9XqzMVSYW^x9?!%#*NIcThIL5 ze50}(L1&eYAuwa&vvz*0ix`#Mt+nyDc}WYfqCk;Wd?uC#meZ#$bK=D-JoV)hJpSn8 z+*o*%%U3Tj94=wZ0HF+yK1pgplqdnvh*;Ui?o`~Kn=zsPrg z_jlK`9U%p2+65OPP=$~|&E8t0?XAhEz%L0;NVYdhe@uVm<%3gU?*2lZL#HG$TneL@Jq{nIThxZZ?haDK2(Efm>cu8jF-Eh=ept zD2o!0q}%CG6b7AYJd(x5J_1D}W%})NfJ~x=&CIW3;mwQSLuKJ7EZnt%f!Z7BB+sm7 zwO+NxH4|)tjrhcnp9z%LwraP@UTRlS?QWoHv7n_I`@AArQ%ecJJHE z#+x>=aegB=&2MO(uA>3~Z|krffejeD*KzhBagG2f$rvOhf@+#*TkWa^8V?Q6C`?H* zuF7BOdtN+#hF4CU=e5)4dF{+4UVH5{XI?wQ!oqb1`E^P&K!^gR9i1$ARY~d4U573D z;RW^4_QMN?!y?XZ!aXZp7o90A4(m%~nE+8lCkKcaOyqrNk&;y6+#s-(Dm(5~ovesD z6jwu5l_(D%hT_(R*^&}!wcBfiN7`^tWf)l7b(jD%TIa`RWXFyjt2vKW1UA#`bOtU* z(F+<5?-4S5PaCWFNPRgJo zAyn##lmU_yG1Ll&PC|BukmIC=+U>b%p|2HAhWSld1f58lCMX$H?amssR9G9ujy}Lw zVLr}A`bA!eY#r7b1PUt>gt08H+`uE=rX7e_ z&8%9tc{6XGI3I@5aUuT4KuCWZqi9^IJYtqKc{`JAwpY;$TNP823DrK>CW-jkvx#)V}iSDISht?GxPHl(z9##9`^0tO*cz9 za^wi_e)!$YPS3J=`wrGkO|PjXS#@uH7zT%dtb)3N6Jhx@3T=EC#Pi}VeBF*8GO7Mm+N#ndiQS2hKgXEm zclei>SVGkuhi-J%e!SS2FgV*qAWrIR6BScDskeoh!x>mLeLWSGwbjUVt!W4NJ zKe_-z3BsCgs?+QF9KNgl%cUm<5^x_WMMcU>7*Fx*s^siyKdURop&7MmYZ+k(4j-zcI$0)WoK-yeCK!n z&%AW(83u#vB%Ns>3x&B17A;xUjXr9wo;6wLp)8nPH^=LXud`)#GjGp4kk&stw{7Po zo+J@6&@CHInr(V%duFiK%%WMrRe?I8U2hKa<=;A!c&kI9`7>+5WNi&ag=JQogHj4D zMyI`&iX>8UD?NB76O@n)^E?bpm1GeAbZ&N*ox66ibN5d6?B2~yn>X{WcfOM&?|272 zp(hTYtACe%9Dnw_b;6-Xfme0K=OJvmk#&U^IGLkGMr7|JB$U>3{aT-eH~U<3JykED;*hR$@3l8R0z3x{`V0Qf)$zv-nOQ-(m~B*`$g zPgx3-l{J*%y+cVFmL`7HMmui&H=aq}&b@dmDs;`5a}A1YYu&UV#r9mQf)Gtxc!)olAwTU9ttVoJ1YCOaQW@6}= z@;Jz@Q~N}i6P2Yw$Ahk-_evQG1g)Fzhm2iI<-esc25dYW9FXWJ3j4P2=poL`1<}JK(@@2N%xA|>418H%3@3`eQ zK5Y%D2sYSijWDCPQeCe#5FZ^RRi!K@ZjfWHqZ6#gCmk4*I-&O8Z(mpS;$>MjI`|@A zU&YLDqhL@JBw8`uog(dZncWbojyvzViyd3Ga`?`>ICSvP*j(9Go` z>gx>5RluXAWop`xq`}434i z&v~^qOVf?DsV`_NpWiCPtgX>$n(tNXOL*2al$_M1HjN(ND&luimVNW*CQ-nfvyz2{ zg>ZmW9TM=sgAZ`__%i`gb8^h`y)4UmeKt4n3b$`srnfunX7{AEMrg36tOvkSDxA0V zyu*7Rtb24QPAnc%4gz&v>6#Ha3I)>?d0B_h)d)kwy*J{&aky{e9HJ?prB3avX#HAg ziWrU-uCpQysM-!*Rk`H8Q2<1tp^YJNN+xutQu2I2NUjw)9K+!dr4-9PXSpny?snO= zXD7RM?&86_@8!Pxk8tlj_cE7sTJU^yXpRMnx3&>n7v5tbHL7m^!}q!GfqneqFI}gX zBqVZxu|x7)p;afS=XIbOCrKA;%Rt#y4m+@Pl9Wdu{UYza@8SOp4iEv`wr&mWU^<19 z4quoxtKik01*=$C&AG)S`;hiVP$iz#RiY1UB-b>^iv!5;oP6CXi^lJ)hFrd>>{c-c zyiv(I=U7@^jtgF~Zu=IF96ZROgNJzd;fJ~Pz+N_Ox{3MDTtz&sj|mYE!b+_^@=gj) zuR)a_Jiw~CwP3X!NBAxy;a`0uMDxTt!#v{mWofY1vACG?+UYAi`S|lZ_UKWbeBxDJ zyKoZE5P>1>6r?F+U59Z4v@S{J3Nop~22q9=I?rq? zEKu5l(9yi2n#s9UEW&CdZ>IM(561TOD;@GHssrTOwQKC!xg#DP0m{1jt~>c%V**Uq zqNk^68X%}-WY_K*F1*!d-i&sw?rqa!s&))+>b3$_79rYrf8r$Gd5aVpnIw^vAnI;X zYfV|2Fk?`%b_uAhJB+DayREedN}LOlfxylSg_Vlyp(qN3RADGy<$xqA=7DsmH+~_Yb9QM&^${qI{VfWr0+KOij)UyjxsxOJ9p*j%#rxQ`YZr-3@WP|ffyv}O(s@t~H_>Pz5p{Z_fpcwT z;$onXiWQ{8QG!bms#=;33mEIkln#;zPYA!NDAhru#>ESLUO9P%FMQ!?UU>RxjvqhH zg$u8f7ltIYIB|ncS0a@`Dn~x-vu?eJRxU*y+*1q#z1S5Iw-!Da9o9B2GT3Mf9UWPN zYS+cc+YpFV4Mu~?*7%?vFHM0lWsE3|)v-uwzJ7BZG%Nh}ysF8zs}7vMjWE$>4o%Y4 ztd(!lo`cobjhaB#JE);T427$Lnd}dLO@4#C`^e^D%jHqi6t0+QkgayLzZ;|nZuXJOjA08$qTwk z2WuUj)Q9jZItcCK@2=GCGW`DFyUzUj^<24jmBI22`pYZW+%UU&p4)fa&Ruui#W#Gz zH*o(0_p@$#9mX3HnUEms&aMqp*2S(HQS^id;S7n+u+@7{up_Zi0BezGS#`5jcw9QB z-MDxjym2UhQR-H7h70sovl*Y1f z<2tqsT~gZXvUl%Z?!NnO-u2FRaoeF=!%(Z!Bg;~>N=TD5`1jPrz{oR?FMQ?6Bt^{N zXw#FU`6OQ8sa|S}_esraLWZNm8i|$}DC&C%3LOX|oV!|b^x0Q=?)j5E_xaU6xiIXMYOvP z&q%FeygAn}T5MJAu2rQ^V%@dL5ly9io2K1{mqxx#O#B|r-&1Yu&BA6a{Y~3y{H=0S zCUx4)jl22TQp!5lq-mXQjA3SGhGWN$@eN=9fw5SGy?ge85h#^H(GP5_)^(_u+hJ`P zD)~miR#}fUT^7c)B8_gXdB}$QsN&q9dggWv4lJs`sz?T)HW;P$dkTk9Knc8aI0B>1 zIbU}`K_?Ncg|rel8w8lC)+pg|8jMOvvo5Z*!Fe}H$cH&suU?_F1*92Uw{GE`k9-9W zKKKB)+;TH_9lDc5Crov^WJxFbh6O|-apC@CB8?F5Nwpnw+lx+^YP?D1?u$=r3Mv#phCp)WT%V&)9_QufuJXz& zCpmrk6)sj1Nj158r_RXYuR&ztIvO>%RXtTMgwg=zMzdwm&QLUFM zg{~PaG|8cshN8R)bJauK#(bh#$W$!4Dl6QHVB*+3q$=h1Bp2#7v{kts2qhg@E&bE=}!uS$Td z$pO`jDRRwYx~TV{qy`zfe+y*MuEYyRl1fZoAb~P&eo6-mbuA&yx(xH2d^lujd4(HG zH$X{x8|FE%YYz{;>mhEx;~)nP+`{giyV*3io~fxRdTG{VuvcbjA==m52rY*W%?l7Z zhQ>uyq5VFO{MS@`zbw|PT9;Cx(&Y+#@k=lA#%0HuGZ%T`x#OHTaf<8L7H}>{=pk9B zBrld&zagRT`^;@hD7=HRq(8_>)Ov*I)9Z;C&0CJV#(YVVrj$jnf-g%;XG+rVuP`^; z8+-5G))3Y#37x4PrSbG!$o6P1#HKQ~4FR;-PR%L^AWaf<9M(B&SzKJAG@%kf!|dD~ zH}Bie%?EDb&|UYid)F>@Y}(3}Et|P%<3={NbPyHX5}1)8^E!BB#dl9OXIYhHOJqA$ zhoF)p(vAqJ7XL$YmIfi`+s=&%O z@T}13bVyUh)i*Blk$?2x@R9HO7u_W z;U`kSn;Tv8&znI<&6lTr5XxHDvbuu^SbaGbk2=;F#~DWLjn>GOZ+8~WINmB{uMLMa zH}ab06g%q5HTSvao*k7mRl=W?$g~L5Z10dlMDW3D5KJPgob!g`w5;Dhi&Pq_IhRl*S+L*fW?k|kXJvVX zMSDHudL)X?J9n`C(0=yszlB>49N^Ynw{pv#oow8?gN?l@n*FAWgLP3qV)`^Qnp<|U2ug&nh{Q5P{oL=IE=U?Qd;}>}D*%Mq@xIuB_2E}lZLRp5a zAXUlSOooyrz4d~kDCu+)j2)uHfPT@#i9T8+XytKo3V~$Zyk>a5k2PI{GO?lalx0qu zY4Rcm7tI?x(->3Wd_i|QXwW8Q39UKK_J6Ac`2Qyw7J}O!Il`5fPctxvq*T%AHu98% zdT4wTXo&!;yyXzqV_9BaL3hIZVcXWNY~QtmZ9BJf$L)7;+pV{aFpB=DjPq9Pyo;GsH;m58h`{WysARW3*v?*__ez-h(U90#smUE$)nH+l8k z1uk8@#>tm2@#2doID6^@*RLm-QRB@Wk`a^M`-% z`;=!dAm(Q1t*w7>p*|xV=S_0W~Q~7l@9}di4Eid7Z^gn+nb|cH$<~?BtY6YNe;I zDd5oUcDZup%2-EM4X5We9Uw~!ydR)R z4;CGO3?j-*=|!JObdVDAqF;;Xl#EHCKBzhRd7q*vD2oD}r1Un;v1Qv9 zcJ0~2zFm7bc>6(iZr{oN{rlOsa}S*fmP%f@`W^IMF!Ixmb59o`sLGr#>Yt1QB^~$@ zDYIxWNp$@+qpk^9S%%B6zro2a}4ohacGgyLVsVG)hw{9KFD?{)i%u~If)5|b+SSK`QI>lKNikc)r z$UtDxS&GP}z!+R-Nd~hsCRp~l>6jDJx@GPtpTz>r;i`SNU?xoi_bKy;n z9eaW2pE}CbtLGRD7eF|sI~fQ=l9i;L0_QAN3#K=a2sQ_rm1Cdn^Ut z`Coktzxb0s&CUPt{k-wHrx@l#e)(5^op1iohq2D!rRJp**XRn*{=GMWw;bNQn{WBZ zf6E{J$|v#B6G=FScWYtx)ZFtrPPlbwtnJ~oI>%*FtZjRP_fcfoba7=uH|ktq#3V_A zaV?!fWWzPPi)Lna1+O&Wtck7!6$8(WGXUGqxnEWL4sV@DS_b?Rkac;O|^pL?Clm#mg+cs$gcr3f-wL zON(!yvL3~7fawR)iS7hLMj7PpF%CBnU%c}qs!N$WgbP7ppt07Fq|@|oTqnyqIAc*A z#nRFu-ENn%5zr+?$TUoJ!qQ*`?{r-_I0E_LvB#d^;k(`&_G6{Oec)|21F2|*v+L%9 zr8RrI>MDsj|eRij=RSta4XnPfc~M0Eki zLD&FP`)JkdWvs*{f*db2Whq%%>2qV*aN)vb&YydeS*nk?LCcEcIqCTHTIyYf^Qa;>FSD2S2AV*wwAAF_JQG z38{C{Y!BeoS6^krhH*Idp?5sQvrj!fib$3!a5B6{sep-Bl-H*7Y#^1WRTe!$1m{=V z@OJZrNLVXF$dk|^l~5=_)=d};S6K0mVr2!TBt1XH)cR@eK6H@%`}Xs`_q~^Q-g7^j zH*Q|7t!Wf1MWnx0vz(;r8e;XliU}nmZCHlX(mDuEc)TA5h8SUJT^d+kTwyrKIdg82 zmyTcM%TK(_i5E`s^2sw?UAc}_D@-RVtlw%880OY@$@Lp-+>=F$a!FbC=@$|uI%w$- z($UXXNR#P0s#!{~&Y)BVr4NU+3DB{ZVffwcWDNSlAZ(1?p-yz9+Q&Ilq~R|vE|PXK z^5`q3lZ4WS>>Zmg;*t~uWSxYS#R3)8>D|s0k3IGn;`>73Wg}Ghwwr;7D2Caxb2~** zkm^o^p?u_khsE4{VcJz|@CzzPRPfL#hi=s{x~gPrzO)ySGAkxByu!fIg~P@P%EB?s z1=d>@7D`@v@io5mhsC6<{vg-`(tFKT3H*qV+Up*hgVN%wyaD&k!#RLJCUTM+nPsFyu3T z{%3%}`3|Q}4S3hPzLgI=u$N!?qo1Q=EuCJ**Zh~?#J03Y*2#j!iB|l;4}Lpax36c$ z3BL2&zm-ot`Ddga?%A*%wSER{uu?a^L^?tQXG1&DHujsucxwLaB&&Q{OrA+TXH6Pt zTm4)e08PWnNrPC?V05)bg-u~x^RQ|vz}qVJFjEj?bB{{Hu~us4Bq*;f2&`zlZEU@NH09EzORLuS!w)~qFaN^N;&kwJvc3vL3(q{uvU;9VX$E|R znJRNZA;;NZLWS;Uq-J+mJd1fw+0W4kdb6_}Ja`8iHg4d7BM4bcsr!+UP!6W-vWB|vGYEl4IQf>#acq{Ye|1u7S zDn5#`7$l0M#-aN;T)N!n(ZBf;Cr@AHu}7cbxnnP~aQ$_hyF$kgnBA}r+3_sDahd6x zruZj6`F%Wa??+h@C4cm}C-}rq{|wG{Nrs*qSFdyI=nHJwxg~_lcoqDcyk+mZzmacy z^n={}T_57apZpa)De*GFm)8Te4~dc*DI8u&RH?c9)?33S>oi`%{qMeoPU3m&^C$VI z-|=JYI&g@;`rP9@_2l316aW0tl_H-sm-=(9x`iN$+T#I70xe4*%wWVkX0~N<1?}>qqL@mHXRX%k*k(*gsZmPT+6O96 z$x68#JL<7cj&Vw{WcGH+nzn#ard2k^&{`)z<~oCx#uvO<~O1ue9{~)i!fdZf!5xJV5*AN8r2=C z)X~5(c7ejz=!Mi8gu_M6kn>>x-VDY<1cT|)!@_0H(MMn8*(c8M*}pl;iPNvJGPp!1 zIZN8f$TCINOVAng{R$g*^+^&%*75XLmNB*u!cjWNM2A5+Ksk-Df#0Z90?v@BAebDM z1rCXECWJwGixN{Li9jcYJTJ*~hV(NCCs0{*8XQk{j zqh}DZy4!C<7M1{R+I$oEa59?GPW1N~(*m^cUuOkE7kHU)b>RjJi`Q5;yB-~fi&Z8= z-j_W3_$gjEev+e4oaXd}^PD_=78V8+>KOg9V6bv6mOp*;)C`?oMxmGK^)h-SXtBiE z3+H(1`DeKI);lp)qJ_gt!PngPK7Qi+f0*}w+kef~zj~aMl-b$Ykeh(QDdL8pk-~sg z{Pn;7w`~5C^>nioH^`&I=qL`!*ua!=h2!wy!(r6oJvWwf2E!pr3;Hw5{NZ2!8|1&w zNMr}q?SO+sB{)~IrPqU=pj(1T6%XC_PC8QJgroqLFJIz&zvmzFv48wAzUd?1!3$45 zP3k6RsI)iX_QBB%$eLv7QXeW2Uc!wBYE|=yNi3%N5EG+k-wqtB67!nZ(1u#tFj{+^ zRq1!lYj!SdzE$S+BvIeQ^<95|H?cb#>*gYSI`+LA)aObU)V5ZsSZr0dke3BINhr#K z>Dd`BT)H&I#42sc)^%|MDjhwYfh~huZmL6$L;@=5fpIKdU&Iy#MV<$G`?gK&x_J*r z?!S-2_uRun_dm$?&0Fc}4q3NDH_5QIBN`*tA``M*R1r`-C&Gap4?>TuDdH}=CwM0! z&9#U^SrZSItX8)Vt>=lqJjaPwF7Tztj`95Q<6OLSlEwZaGR>IkdOAso6W6dplFS;W zvn8gcW*H1`V6|p(U`WbH5%vOWCDv4yM+HIzQ%;{KgjV$PK3)hqX@)Vwur9riAx&7&KEtS)9+YuB0#qnf1mjc4T$$gun{u7kLyiTaqlLEDN+$<90JyN@)zK z(v+q|2_I7}i$I$v4cRu{kWKX{3x_bFP$=?}qA2NhyX3>1nc3+`CU~3DcqOoV_Z}*f zKOrTug+s4}t&cV^jqoL2S~@cwe&~CC8=XjAdhu2I{Tp1o`Z{@@v$Ap?YcB&gKx<~Q zDRyt#%B87g9(l(Re&C0HfDJcoV*T_K-RXIHGgBz3cw=ReU;mv?@>3uC7@Z>J!pmpa zwtG9?Is!BpF?DCyraS!k@BIn;cJHLO&_!jPkk_m*m;V-)&rZ_EoOFafzS(jb8$1aZ2-rXI{W8UFPTi<^O_oDZlU= zzs9?6y#uW}^)R=}o@j1%Z3fk(+>^kdicBhE%3OPq(%ul;^kwH5qqj~fgqpt>5t8qkU5JPb zpQd|ln;@WQX;va^lVurFO1^yb%QcY*?@3jH1G1!~JG-8Rr5p4Y7jQP%pR0AV?Ax}B zyAR&QBagg?12-RF%f?O2&dsuJZjR~cncx~-J*#-QnxJj~=g>mNjqfeFpE#Qak)ZN; zSJswwLbxcn)xqDbp^-RyX2`QopW^6~Cwb+>IbMAE5|^)@r!Y$><&Z3(5{p*_S|^B9 zFq4%yeHo=BOG`PrlOYm=FAAiC!uLUW^3o!cpwL%Z;H->xK4o;(tw1nEVTyQgNvt0Q ziMeP?BBUfQ3Oc=Ru*Fw8$`K6Cn;`LZ9i-M_o*7+{y?3Nhejr6y=cThqt#DeReHxjc z5-F2frK%(`{!SSg2St?8FJ-89TVl2lWeVQs}i89KAlmH|!^3MD0l39#kd+ziY8 zB{t1&h-4;@cnccVe=;*gyl2~v9nkAwyaO9H%Ql|eW_yfYykLWY4LJZNy}_S;`r`OWY}>U9yeHR!@Bi4p;4{DV|L{Nk;CJzTKk=>LExWwt zYrpBkeExs`G)`+O6NqPDeTwN#r}?8lewu$>{0KggC}7LYH`DvvQTl#`Ooujn1nY$E zCQG}VJ$p9Tb$HMG>{O_RwdUHT%lzhV{ubZ)o!Z`y!Vtg9w0SE=FKdZMbc zXrG5ifbAFd95`v8R=wjN z-5)9WmjCWU%+Ge%cVHj;cI;t(ex9vcxBkD(y=k;1Sz4a=>?tD7xl_(#3%%^;xF3~gB07?xx#YzsA5Zpp?VjJ%K$AbMdLwJ5;S3Rb@9+EG_j%d9V`sY{G&70# zyApcS2VBEok^(OzoSBkm0+o7DzsZcKtj3PW9uaC!xBNNU7T^QnLM5BcQ( z@OR^lZarSdOa~<$?|k47T`lfK(&?{nM}VYrp;(?&&S@>7V>*zUPO&g{7VIAOhd>@lWvQ|NKvp3OoV@ ztgNqNgF}Q0R|Rx#83x0VyYA-mr9+t5n#wXoo|`!T@DgWhRIWMo`pLE(poHLufB5h5 zZ~x8j@}qz6NBDss_

#pf&&Nr+=PaPxFud{{Oo^5rx1atL~|6*axE&)Pt`Uppzw?I>b8k)3p;z#+wm z&Z<17TUgVQ*~tS%T+~F8Jl37L&2$@X{5_H96IG{{JWRU=y4Q^%n z^@yz%I(Z=tx?D!8h*D8K<%vJvjUQ*XlJO!|<=#1r$&%tKN}EYDnT^p1?;Lei;Xzy}^a^*SLK78pmIKou{9AnbW7wbLHw8*49@* zT1*z`&jpG+aliX6jZeP8JRW3&!zZ(yG8$XimQ$sbiZIWrhRgr~ZL*jtqE(b7JCC(B zRc%qmfOlwZ;^OaWWJpoFnV@ztpG4`H52BPp$p~dNSw^ljqq@Qvozzqn$|$_`lvT-= zEn8wHd|5?egSX_F##t3-7(!6H7^9NYnB7}*kW2p(=AuGpXu^69z@T^P08?V2~ z*4`4k_w~@g`}Q1U+Z}gd@}+pb(wfiw>wnFU{m?&P!4ulbE%|37f0;ivxDkFc=4j{@pU^UCqleDae&&0l@t59#MM zHYi;0I_3HmdOZhNoD-Y)Rb83ttq|f9_T&O09*Dfj0th4w)f_$dlf`r;fYP3;?s;ZeY8N*ST6k0=i^95yD zB16D>fpY?FKnRNuk`QtNa|me(4MbE5bP(}i=woo4LZX78vNon<3Xhg1Nv}f!j8 zf%TSA?J-$~4+8IE)$F7|s*F%tLQoiKu&yF23_(do8v}fRr=R~a;(PxN0guGIJ!c?| z5##8Qqr7_Qxi+k57I3aD%dMTjQcRe#8d;=(vaUIL=aDFnt>I5zdX?{b^gG!q_H(ZK z6EYduJKOghqSu>CCnU$$f8YuB{=1*!+urpJY}>H}2!8kTPcrz*^X@V+_J*eDL&w0v9kgUc<|_M0A>}j5R{%OvgJIzM9PQPD)sF+{KP{!lk5ZSNTIoHgF z9IJy07dEJ?__%b?=>#9!w=phR;Oao8^Vs%*7(0w<=R?utXj}hQGq-E7F41HWtF$IY zdMxvGsTHmw^UZst&hc2J@MvwKS}w#ODJ4MbEdD+rkS0T`9%a28U-R_ywN`j%$udI- z9-|b(7>0u~Zhj6_YL*4zV}a<#aMj>E0f!O_8yuC5SoT1?hH7icRh|+bO$wCq2o+-c zJpm_cJ0jD4z#v3GQQ};IF$S%2tWzixs6!ynat14F)N5CH^~Kcjh_u!T|JB>0h1Jo( zA2@Q9SN`hRbRyX7&*&~pZw0K9rqDu zaP!KL`Ne)53_8bSN00F6u_Gu4r3>T=e(kq@6U!y+3aGhtO3~+AzWE#Z_y6)&37O&0 z?j1b(?gx{?2>!+Y_RB0SE=KcM09?hFKKogA=yYL_BzaiQ#Yy0r|2&jOqJp7DvAZ9EeO&Q!Z1}30fC-aAgAY0 zw*pyCR|Q?7a(4shrru4bI(9K2Un>=|tC*S|OnW~$@Rvf)oT*KtOQv1(lXB%T3(9)e zN|3u59U;Z51`*?9wMtAeDL`w4kXY~87>@A6l?eP>oM->OeSGvIU(fyb-p76S-pjil zdlx1hx@D6QAKGZJgn&<*f^!5VCybY|x@!P`VH2XWZ6PAt5H2Z4t!^rK&9JHyMZt68 z)$2U-)GM4iagHay{1PW#y};UvrQ`&?eqe6FqfCVjBb1U9+e>mRf?gUnZ(zKntV^`l z_#iPl;z^Xe8Zjz0^!oGIYM4+tjR7>q^qNdXYz_`?SD}h8OS+lF+@Hq&Hvm?9+D53Dy zQRF#w87r7fo7jFV3P#oj5$@AVv*qX1= z8=61+;-B-t;}3!N1nH@96nH!ukLJnO&+^`55Ao8A&vW;E`*1SU=S!|CMX@$9(tle>1e`?uV26Aay9u3UCz<8 z+G@J0m{t@`L)f})sID4ndPB&vtj*<~rY}!Rd#8uiVggt>1`ZOyrk~kv6iGeQV8Nvb zEd{oDzP(J+ia;Mqfu} zil`P+mZ}<}bcXYFYkCwuDhsQsP6&>TyVUp)$W%O~O9W&^Qo?z>3uIcf88IOQ zl&8&TZ!+&g!dht&JrHGWCzxzmrW3s&DW~#2Rb3(pDUDN5n4FElh`FMdT9P*Arx38x z(i8KEfDscHov+&}u-Ozwqan_Z$g%<@dpHq~_EKgHhBdh?BQVLBBo()DuB0`UwI~(y zapE{m(a#I2D#M1Gh=6Ln=GyM6VzQDm4TtCiM38t9xa-hCM)e4z=As(QchxJp?PbOur<;lM zZWkgOWwSO&MjLfJu_?gSWJ&-T62&k7`oHDB{n3Abrl6N8LLD&1@t^!7{n4d%Zjju2bEvB&LYe*U{<*<;JM}nY-^e%;BTA^P%^=kN1D@0~|hln8o=e zbYYk;<|&klv#%KycoP%sLmZX|sx)|3AQdv@)%)O3N+bl2PEKnNScJ@4sc~p=qvJny z3C}%yfv284!59DPMP7dCBotm_&pOLAiTr5GVW_$;=DrGfDsu!fry*;ttfK5cWBv*>w;|VX@>{_ z>qJ5pImDohO0y(8uDn7L?~OdmsX|F+;`m zcZukxkH~wE&H}EIWO+tVl3^8R8D&{9mm7?A4T>~KUs z?}P9d=@>Df4g%4{_zKHt(8F7c)(#g0))+$NSlrPkC;e~J6es43F zVx*ex-@A`cT0~!r1D9Gbsc(;2)9s7tp=!)XwuyO_GuWu`qC#MJ>h%qN@>9Ra8^qdxw7=IUT0d{khYX!K^B88dWkYJA4{ZGX4Hc zyS2M*sIED$+p;8VZgn+ciY^Mi4ZU)%1t?a&LWr0{UzQbRS;o^{i1`*I16b3}h~}}t z)f?BF9uhkb?xmQY`=lgA%PJQmT)Q;nUd-COy_%#!fHARhkqT?$Jkz`28>b-+b;1zrxa7 zK_Q1oT~mz|6&b-gP%%vD=GCiIVHwC73@i&<`dq#_ zM~EcX92*PAY^qo}^|GjgkAl1?S#-|QTa517kuBqmI2=KM-j+ocmKJ&B(MP%c@L>)e zIl`k4KE%X4JKo#pJAH+kj7YrOK(X-=McgPYfvxw3W!Z%eeU(86QpRxp_+NQX5; zvfLm=BD$huYesscs}g`Odand3;{H9r2!f6aS7_eTC>xHD-q~rN&56BAo`TkNs{908 z(pihn%%s;Q8Hoi`95yB+iev6cl1c-?rGsd5=pazlWoje&RMDvPHDXhc*aV2PiRKOQ z`+|t-7nhLsK2e>mwRjb9!69{wr*394UijF)Q#z7}(*a0HMV(fAlSkuUkr#23NM^~b zF!U{~h7L{i-d#a(5rd$NAcP7baxQJGBJ+&lXaz$clme{;f{JpG^UPN-a{BdCJolC7 z(Z1rgCBuUcy_jMmGf(wCi2>+rGSkYbuT^9$gH z^EGXTSpskH$CQyL8@;yIah7J%ot#*`}Q}8V<46QacM$p>oC6o!ja6 zdwj!t-^=#x+qwJb-Q0fk2nP=wc&UV}mzNpOWo{^8f%K07*naROQ@x$@z2Fc%B$jCWc@P{Iu56>-XE(T`dGw>vrQUolCYPkCBqhXb6tV zJMtoDFdC2<9dqVU)HNvS$c&*{@|GWPBK&iKA1`=N@D*^|Xw!w}$T;;GS=2U7K`8Po(gICki z3NrzIt@~I(ISP0*+RU@QY`8JFNqG8I%wP@aEJ3PhmJ1bXN1qS>jc+BeMwV6VSddt2 zxE@M!&ZGK)xxy2ChA%4u5n^UX8z2OwwMePrg{w8#fE86MzPBj_aq^_oQ~+beMOU3P zZJ@i=X43tyM6_8I(`~LWBl+%D%BXIuXu6#>ZN%%o5ADVvqBlZ@ab;N7wq+<<=g>-{ zWYY5|&?O<@lR0mknJ!RaEZL3xpeVku)=}3rzR2;?ux0ml_U+rp!|#29#~*u)d+)x7 zhmJi+@0J3NIDa5?+!CRQqpgzzH>UHYe8$A`3kY8$lu0m!riK_N47Q$&Bq<*ZEH`g% zaPjgom(E@1<>yZF+N-B|@uf4odipxcYnLdv3E5fZ=6e`pFh=6MMb3{{oDVqXQA*-m zh=-HPCEtp}JD&!{0V^Dt)X~G@Jl03ZqEZrsLmRNwD9PR%gJ)b^tIDH{Mv6QQ#oc&w zNKW+H#b{K;I3d!eyot60U}AOQoFg>pg3ck8iuZ)`(eGkQvp(i7Y)vpnR;K+N1vJ!;K5`tx;TBgVib#2K+ zMs9kHY&4(dnL%2Mw-#4h@_Ye;#JiHk`5x;V>tvY%;jkva#yZbF_fnj}2Kn|IqBm#+ zDI^j}Z_8HX)eUD_(oUB=S1@og3m zaFYUQ%Ac_b^)cna=vFG-dBn8ZX_L~eQ~GyvxVy6yw2EV1=LjlETZt_YDWaP@*BX$~yd5(v0-hR4QV6A*U!)x4!Jwk9BXWOvdB_*P@KwI> z#Vfq<{3%|4?JPG|t`oS55;xegB}a$>y`H3Yj*vUH_CeYaS{GE+kWsn8aAc7(Z&NRY zfV!?Dd&!Mql4Ax|oEQ2KucK}ov-y7KT)f6Q*FqFZ&_*f5`Hk4*if?3k(+7>|9QSb* z7tNEd*EYz^K;e@AUC!N)nElqx0|Dg$W&9t{Rj zdh1=>{B50@gCfbQYg~}@OhIjJ%at0Gqlp8mbJ3gAe9l_Smc?xh2E*hbi5pXYZZ5q? zDPlOp*-lkgD4C^J;#mIOBu=X4eyA)uE2x8GSVyt|ULf-xpsA{oB2$TE5Yg~TX@ajP za)ZT@=Y0efc~-E#F{D=%QFd+}rsyN;s93WOw2IkCJ~(8mKCQ3tC~9lDzH*J460gm4t*LxXRh8g8#oQc~f_J~~ zecX3nOr3l8d*8$DM~=`#QzuV^8B3Um{^c;0iWgBPF1R=g2$KpDA;z)1qKQgvbLwT3 zRqFU$1UfpEE01&Wgns$rfYYbW@%+;l_~SqNV_tmmWdQa-3BOiW*Qhy*QJT5=9!dvP zwu%%5S)te>meIyj*$O8VN@#Ab)M!)S8KI=6sy#}PQvYrN!^xG2ept?wj@Y_Q4vcHdg8ikGDNzY zj!80Q=N!7Na#h5ncu+D{>NF*{SYUg6b z>IAly2$55kHXhW(SWy`dxSI9#5jwGG95%ul)9fc!s|F<%gW-^iS1)pK`|WSP3Irl} ztwB8>zU=^SikD+_qjgbEdW#|Kbnmsh&`C3*b`q@?Da#s_71Se7CIV$WLYOGom>BX& zNuUPl6O~kVOjeuw{j(PHZrf+N{nM46PAiS3H^u38*DM6b*Gm7Jg~OlTXlA{RUn?AH z+924R#KuNC+47{CtPUGsWn%+Z*I+$*agGPx^%(p2?`P+ZoqX)$ALHR;_p-RS*eXQ& zLbYB7nW|3_QN5_t2BCXGZG;#?MuQXrm6TgbD5&EgepBjXaP2_Cdr*4(1!vz_=b0~E z;nm~EdH(qqc;%%NoIQVrjnPevcI3SP!J;%MRpIj$`r8Lc7Lc;W`N%vgM*%5EQLc)k z9)YBXR3cVn3IY|1fD8etJY_jdC;u3x)?9<3(;90Ax!r3w&WakQn4X{j&lE*W(2Xs| zh`7NM@5ku97)J>=bIHb}s5^(CD8nr_Z64OSm}wy;QY-SJz*S{Z4GN?%Aj*hMNlii} zOzZrQ8>MY$p3U<$x+yRvRW(AHUgv8(!Nn{N*F;uJfej9wK%`E@?uJYfx#lq0z5cr` zx%Tx z)60=TAhcmPsF`1wkMAJ~BcBHU*REXS;Evnhh80MN{I+H}ICl65pYtUdszrZ~gL338 zRYLLP>(k9eQYHwz8=*5GY~TZo{Mbv;tpb{pv`efQ{Ma-TI)=t+IqURena;tOm3A1W zPBFLgw8$BB;t36Oq}VJ6tSJC)#R&ZjjOGMkGb9s@$MGEx1sM z*k<%HBF=>r)ZVjv^Li&jE?z~&?wx$>Z+?t#`lfGUtLbt3p~LLhww+#D%!JOO-^AIgSEEGvTWgrJca91<}Pj21V~$gIq&rcFxD#cOj9P!CQ;b znvgs@RhqfwS(YTD=@m{`9U(xNShMAGrnAMS)IlQ!KQ5CVWu^~xoHDz6+NOKVsRb7J-ZJQ~}G8Bf&#SKGfg$rp8q~nY( z2x9C24uy(}t^mbc!OHRqb93{I>I#iaa$kp#Ioii<(OQQwn#z@!ETL1Rpt24lBtb`H zyb^+9ZWq;XfH4~BJS8>Oi3H$;(Qt?{bFtl*D~h>3e&7&7bLsMBE}VapvM;&)&SUJ| zxr-eOi@3^j<(gw*p~O4zqCjUk-i{(xUK*s9l-6QvkZ5|nZ43tI(I)5owAhU+U%}v(i9MceB8`@b%<~M5~-37O-2rs-r`s00)v$Z>EJfhGKnOEt9(7RO&N;jUDbkIgVzOa#dMe8@X~-Qm zon&G*gh6RdZeojSZ8TtHEBvS$KarkcvDm^Bk3Y^QKJf|eyyqB&F3`DV-=6(!?a$HA zi?P(THH*e-LWCJcQc@3GL|LqFr_ZrxA28r$`Z%6aWr9;m)ub8f)-wQb_7uGG${UcfjHcxY{`0$!G(fEC8 z*jD4~K_@(iOY=KYYGK#e;N8^Rt9^fcno%S_NT=eMy!O&bxl00OjG*u4m)q3l%CvzH z2iP%{Gq$^;5-FgK!P)q3HK9q}d0hK5X)5c8>hI1-f(Qg3P%@Dudl~{zV+>_EM458bRue@_>lSUG?)Pj`Dor`CXKgsMQ55l%6@SK9Ki&*S z8>wWJoeE?SD6NorhP9Tt`T2Mwdrvj0ST9G>cqjtJLXUm>4sh4qck!VQf0#pu4srP4 zVRrA?gUU49wr*pts|9bEOd;h^3&yIRWb9JiwwM$%Xw1-AN861eCenu_O>WR|z+_|${yMCFH6&xkTczhVrD=b<$WD#&>iKWCC5J6K` z(eZCb71q{h6(5XqqX}^2^hQ3N<=)L4nbnf)&ZeekWs~!-=@zM&Ne`ZoL8r&qkN~<4 zeKCavYLPI`PdWbM;iTC#8vj-IKAXiyYdL3O{Mg&an{K?2q_^IWTW;+^taG2ldtp3V z^S)6m#!W>^k*Xz6CJo3`#fUVM&^n4@l7K+@u{TPn<`B}%B*H{gvoSHkw{^RxO;gIo zW8?`z;=O25_f=J)Gnu?G4wsPpCT+;x`#1}W*xlqPjgLc0fk!}X>1R3lT#w2-*24{Eqlb?0(6PHYbm$P<`U|+u;vEl^2~iW8ja_i?;2qRX zVV!5Nv5LwRnKnpiDDs8KaYK{@Qi?EtBzf(-OBWY=P7> z6#*PB4UlG^&SwpUC*eTck_j}+<=wrwXQ`g14Sv(r#k3y2%kG+PaW(ztS&wac(V9;F zi#KX&pWzT_ilS(LM;&~04*P(&L%de#%&>3o9`@|s!>&DhIC$q#?!4np?mBiCS&?&S z&u$LwJ=mUFnh>Fet0WR3w8`lXfJ=rlkxr*N3P#$UK&AmEGd9(9b%Us56_P$(Texw( z;=-HPIraJ#PM^HU=~HJpeflhC&z$Gt#S5$sE`S`Nl_Sp;D!YLY3S%^8(c|noMi_$A z6sFH`FhGic)&|J%7PL?aaUxL3??7k*ubL_##+eEsH*FZRuEA~=`*ir!^m{m~_1Qg@ zH&uv8a@1L~x9KeTM(ojTjVh(uq{goLM@?Mk9&IAhJIbeRdrEJ8J)KU$v`=IF_#={D zs%B>3QJv7PmJpm4?ugBIodr6QW0f*^7nMy>G$13YCo!dL9RZ32j}0Y4rwT?#jK3G5 z<%h|{8SOoDbsAFLP&>_sUsk4t8h~) z%6+BK2q`f-BjCyNK1OS7@C>Vx)xjzo8yje8DDs?OBujgCaOXXDaP;sI-tq9G+;{iA z9Nm4}rd89W!>|iJnpl;ZSo3_M7lf2avuE!%l+qZJk!N`nR5*u}c{~HEKtkLQ|M~pQhS2*Tto}`i|xOd z-x0H!1p?#Kclwaf8xdtL)1rlFvNFae*3r;07*s6ZTw`Trg_mDg=f&q<;>8zU;nazf zoV#+3welLU#=^WJFDj(62;m}HV;<&vir{=QW`c7u+rg$jyOIS#L`i5lx|tTmfb*lc z;Yx>dc|>1}=q6S&i`3kp5J5qL+Qr$0Y&}TLp+G4W&1Z3tF|!3ZOLQ8ztM%rxzp_M|UB8{GzESvPhSH<=fW8YnL2V|s1Zz}JLyiA1*z z>3R^2|EOtWrPF>LJSw$VL+3hg;hd?(CmK~Bjsbe68!xKTRisH-}La0RHV8ly9+szi#$yd3btQ@WZ$OI(tVMWY%ckX*zf%2LxTAj&c26r3|I0^T(nssrJ1HqO%;l>4+|&-;Y`2)ntLOwq0bDh^O8paSqBRNxmnL zcyZ~uXd`i9fTzNF$O2KOD!ZK1Af2EzeG5v!M#wN=(eB@7h3`8l3=@4I=&Ll5xS zCPo9OFN zJ!G^Nc;|y3;N-b4A@mB$&*3Q%GH$H%^YfI}r-N^_v9Y!RqGoM*h1KdN3uenE zAJto1fizCo^nxz-=V7sra+e71fPqomBym z)Hd;ZWXcYp?K>l*qgol&!puzfX9C038+hj#`FIl)NA~g1{SWcrgAcNA-+u19_a64` z+{Hb2-jx`_F`FQyr9SwW+7|rS%ux6k(V854?bnW9$MmJ`Ff(+72kGBM6>~wn83Vx6 z!WK{bo(pey&Yii$Gf$o5$uB?0SDt*GGZ$W=<_ei8k(s3^408(xYd5IffW=)EHsw_V zSZ{C@t?DNF9-8+}wZr9R1L*o!x|{shGF{GUyELbHe~SdnX(m^9(Vsp@O!K^&g?W6U zcQf0R-H)5E`C7os>Cbhmp@|B7hL@;OF*VAgW?s{6qq>evwS9jQ&Z9e2Z*pT|ieq9! z`6!|eLMD8=oDc)FvpyC7-4UYUwyud=kst(xcaliCmyF5{lr)p=Vdv198LtB(5{hHx zY3Sv7`qFdi*f?(r8t`44_)C{~s^>PO50}z6nt1EaP2?+D^ z^BjBE1ANDKd3B(?Ap1rC4efa+QE3UvC1G4AvKYSW#c-I)rAdi za>GM*SQ;T+jMJNUNEd2)u0kgDcT&fZbLsq$mtHu_SHAcP&pmsblD$s`F)&j4NcF(rZ<*p6#c9XWtOm_TPZaEZRO3x7G!%k5zJKTbvK?{#qP{X zXxx-`IOAt^Uyts6)y3m9Uq7AgGW|2Uk9iuIKMkymhYr`y^1K^=uWEcFX^8HfZ`F0P zVu_=H4Ll;v-5c;hxbj~ zN{U!|tx2}pUz_js&iJ7k8`ps3&yfWlZKl>$~fBsEgc>W~SXce6e zSlC)q^lP*lQ3u#|$Y6F2DRPMqL%g&odRVJs)tKIU>nxed$%>58Xh7c2an8}}&Bd(s zt=l+${5bD^2=(*Z!b4rIZv*l%q@vxCVI%5(+Csmrj_%$*%iYK z<AQ-em# zoc{<;y*A**=g;!oGsk)6*-KnLf0C=$-k=`dpu`eFiSru>RpG-Bp=w0o$qSoW3W~BW zVH8sGVmb{wjT9M9+#ooRGKY{Of~TqnfIzDZ?-f1_V_QUcgzyXoqg2ra5H(U3SUWan z8e=x$UN-TqrV8@%805i7=-5Ut^V!-?Zp=F)z1L)Xmx?rs0>jI`B-J zO}n#>_Iejg7+SlPk=8oB7IH$F*nJI}=g=IUy110?AuGNP>Ax}{lT2KC5K?1pIZ?&? z5XQzrA*r3kjFr$-F3{5zSvE&qTdd7uJ1t>?8Yy~r)6+Vl=!I|f)D%UJs#-^Bjn*ITd+j%s9mZWGdt2>&ra(#S?t#uU_Wa=gzWm zbA@Vfm244eU1CB-uaJ!FDocA6LpeYj#c(*l=LR;0m^@=Ns>$*knJ?j8AEg`{8!KeS zW2+36RC`((5F?a|@1H4p1m`GSO|Rc)X>ki@&Yr{BILncVT_@h^78XH7>_CVF2>~2? z;31y>f4@R+RFenEi0DS2Ze>ljp+Y)Qi}-O`G$!!k&;r%8(NskI0R)^66lq9T^m6K| zrW%#hbxk=Mwd0hz1A91j=bhYr>@JQRJ<1c0Jl zF|V@i>f#+fF_l8_;CgKgE5Z`IN6D;%)d(mN6X_xZQgs&P$VqZ;lD*WN{%3K-Hk&R( zEAwtnwp}GrSG5%Lv?U?fb~e&1qD@#+E0{A}Mb=|98byF%5ST2-R*`i_2vk*x>Ca*7I_7*!iF1a!^0?a3 z*OE$wL`D{%4MG}n6`5dhNUqU6jX~i?CBxMfF0QY#IvgN+89Q&=%hCJq<^BgB;{ES< zf}{Hnvbea!j_upoJ-2iVI!7~%2c$Bsl30+ymGra=fB zYl2r^xXSCVo#*p^@fsH{oagH0iW_X^gouF}hLLQpsrs9eeesY`mrE~GHzxubSf zx}GXr3*ilZLmA;StwnKuZEXs5TQmRw&6oAv7J&AS*X5 zXU^Q@)Ek#M`^sfrJ#mV&r_OL~d6_rfIEQD0>+5gg{khmQ%^WJg&YgS6dIDFk(ASPf zA9;}f?oH0_{>lLQb+8^RDq}e!P))tJrZrzxzFG@^7?ltiYxPe%3r~ zy2Uh$Ixwq}>JI9gpVj1RbZ0D0J1EPtiA`ntGchuH`tq@t3C<%_9S)eRO z#25^Z8zXY-sr^=2#V@M-Sa z9X!8fndsAh{=+L@<{RJnKDL^9T>B<(P9vOVVNKtZN-K;u3$_ucofe{N~wao85vN896U=MJeH4SpO@BgXM@V>#~(?@3cJ z`P6<=O;}P#$T!-kSY7d)J$IceH&!@v`U1yaILXQ5XE}TN0vB(N7_D6)_+>_1C+HF- zJ^4aLp+V_DS=IdTCqK!ze(c+LeC|K8)okV3g^L_Nae~7~ zkDz>oQyL`#p{|jpND3Os;{IKj^(yMlyR8_e-UsWxMi%$xQ~zJ*qnHKGoMon)Hsft> zZH10mQOqP1cQ>PM+-|p3)aWF`)Er^64{0``V0xY~9pO6-t?XX!T@k_byd=-_c7utF zU1;UGB2~FA!44-Yh{*&&DPsUNqDf;vC?AW%IJMTQk{@eC(^uc?$IJ_1<*U5*+ACbWdYRE^$VjfRu%K94bSSk(Ucji1i??@GgWC1ECeZED=ItiY%^4LAM*8)&iWM=*?03 zh^|puv$1lMxw(0&s)is~+`5gm}$(;>rmRTeB&m+^e=vizx{(h7&YMCb7&X& z9mWH&h~9_}>NFG?hv2l8&Un*^9j3&nia9OgA1kI#EBh0F>nV z^_tIp?q&MM@h#u+7+H#2-M)J#EA?eaSd+HTpAz||Pu;T?{cfwJF|*B5PR#;0PWy41 zQ|$j=C;#MzvpF7kRuu0v@t}DxosUtq(~7WZ<7k&~9A;dwMKqO>O9P+FowVopg# zMfB@bWkop}v0ixm$fFSKT-d>$yYJ-jcRa?ucOBz>?|CnW_a0BW z@$^?;=E~JI>hdC$DOp;|*g0PywyZGpBeox!rz}g>{3=R7g+$eovT}H1aUtSmYXAQ+ z_vX=-oo9LH@0<4C=iI3#sU($3Q)#m1!4i^<0UPW%Kp-(BKm&^@B!=$9Np~;OG=phu z2#w8Z!h!@s8v}-J45n?|#CB|VGZ@<%Y|W~YR8pxVl~m)cx^;(h&ffbQ`j7Y9=bn4+ zDf4H`Yt^dqRn-~y{=V;h-{<)~NkXThCdHD`P*atjrXA+0UQ-r}XjRJ0B+p|DTMCOT ziHqJwizy4i+NVgrh{OoCi#^s*w=K!YCeElqYvF-am9!b#rokA;V53F#`m_uw3yn*P zX0Sr#6a&`j*?DRADzoJid);gxyUHCfN~8r#n;J?b;WD#mu(MM2lv0e!K#zhw?h>ly z-B@Et(Qmf8M8gUuk!Xdb)JbD?%!E#x+Zr8#Lv8B)5x|-mJ1WGq)0%{B6r(0GYzM5K z8*t*)5zjtzj=%ZRqrCX?%N%*?ATKW;MTc|rt-}^;6n%}GQ!Jl5&UJU*#Jg_2lT`Hh z+b?~Av(LW>uAprqtLM*eYoWDxTvQ}&IQE%Oqeg}!&%OXL(5jX}qd9wWg?)P#aXlzg z%ZGp9NBHP3{xa=Kz$=>@ypI3;(Ldz_zxZC%`4Oj9kJ35`uvt0NQZ|};dgEqm3@%#D z9P&=LZl;w!lbIru6~JVrGRvSheTu(OJE?;ZYQ1%F>{?-+QmK2~Zc(08UUeosk!EhK z0=koVcS@hmSJ^s`+3Nq;R#jUukGT#Lj@ovOcb`r7yxRx&jAhXB^N>*;0c%QW8>y6K z(p^}TM;VQ=hNkh@AkWh_E#>?iAtvhV$+AY`ag9!d(4urH7?B{zeqB`=kE2=N*ub|f z>*v?#&GoT67P$JrjlAhiZ{qE5e+M^Tb$}}_zH}>fdvaw;oY;5*RU|?a@i9>t&1f`|Pf3X(Q(BQS2Z>s-(XO&Oj1JgM2z(b#n1=$r6KSZfTCsec?0w5dRdV(`NQG zLbnvOPNu_Z@jb+7P#CmsA!&3lU}QL-kg%Q@BP2L+4xV}X1P?v<9EYEKl_QUQnde@5 znd58A^fb&BLzZ^$;`GK@n&vFc@GM$+Ob_<%xtNvVDGHq!4I8ez;tq}-eSy%;J%Cy% zz7o#!kFLI*@BOxKm!H)`jIA)bmFh(P z*_u}}x#&;!=4Ua%W+{s%e?FWv8pA zS-B~b6~l#aC12B5lvjT>@%JNXX6tM6vj{2TtP^y_1dX|4E+ujcCuQk&lET~jW;{bl zEhHZ)ti+qzLQotfr<$kWY;d;K~UEj(5 z_uR`(*WEyc47$lGrfz=dLGs5lDyLIHZtf*U?#tvQH4$N9StSHolLNjWQ;UI^GC2T9 zs>QdF;4Lf5iLXBV5?}es(>(f>r+D(w$JrP(43lGN@eIa6*>C9eJ!!FK=X}GQA5!#$ znHCyD$Y4*}mNt69ig>U^g;y;~6{Kj;QQ?%4LzdRGBtmDrRXN}*BpMyXwM)db3TK^2 zft40Bpe#5z>j-UNl!hb=s?fA;qV*6{izyujMWHOiI6(P=HW`db^h+ny0W2z8t z7+SFReHAf5V~Re5!3I$&=3PZw4;eN?s>L}Tdh}85x&2M31U4#?+4PsaZZ?pju-L0E zBP@@y8#90pe=pZ+awE|`3HrEM=cS`Zv+&7gCR55d3xkgety+}wKrbtZL=Wq696uF# z;_;Vx?2#8a^u!?^f9Mg8pFBfbC)$`;D3(d420K8hnpmx3d$7+1+UU9R`WyK-Km8uA zyx~T!zHA?hPE%^lNEv$8a_KeKv3}+_-}61+%kTZ}hr~=5jIe!Df;8gIagks9lRxGY z|NEap1J6IR!8OB@C7MR1;s6UFXy&BmyJze&MSWZcm9CTFR>vIeYhZ0 zZ`PteYhE!6W;s32m~Lxz6-jsUo}N8S51=o^7@KadO)mJ|#x=P>Uno6tvdWkSD^6C( zldu14c`qhU-jlC?+$Nm?bDTUxbu)zVrWZE{?6UFcocW#PAeGuNU#@#Ddo$l~@BQrCbush05;Lu}c%>-1T=^v7 zUW%@YOG3QW2HQ1!yH@d3=eJY2t7N(!7FJuJC8-vbLN>%Y{0Lrn;Vch5bd1Lydx{6Y z_%O#_KFQkZ8pZ~SD$rll6eTEo8npqCtvqL8oou!?;+3c9RW!B7S=od`-OwxgXfGyBtsOoL!KjRwk&3iw8=T#gwg>Ma zMVu>Xy{GmA%3_X`Jf(GbJVoVr?)m4ppa#|d-$ufj8;Er*UbdHX_GOGxjIwO$XJ&dHnA9k)_to(>#7be2O;y~YcNkMY$9U*Y-Z4|Dp=GK0Z@BECx5 zGmQK>)|wLx+jaI`xu1c4m5Z*P=bn3S=ZYKN#vOOx!GQw@sH&2e&!6O1fBl0z{O6yg zJa74nKlvn=?!Q=0Z1}AIcGQxpP8fOWwU+<*8~Zp`GUS3UFnIOin)BxlN#VVhe-9FzI%L}CnB>#%k+zWDUHvvN?= z3Y?{X>l?WKhU>Zgj@!Ba{`MZjg-9# zw2U`xWl4U34hfqAA%g2y3{MQWWXEn^I`VvORcC(O#J2JJ*g#UEP=+1-9;Zrht6}US zz0hfPvj017Ie1HAL=$T^jOHhQ=(jn0F7VPz$5>uH!}{>NWF@mo>tAJMc#frolASwu z5bX%n8)1uiu7Bfg{J;h$LbGp`i;jf?PrKEdmelCQBEH|Mmax1Z46i_^*D$9^!hT?BUEol=rAWLpn~R- ztFEN>r`mkeBgRsefV*Kn#DA;0-2N^PM?A$JV#Cm z>zv`EpZp-;Da(RnTQ0d~FZEr(auiC*)Td*7DLe36(GMrnpa&0HT;itIr1BR~3M{L1J4HH9re8Inls!k?oZ)S6{bq5_qj>bGXPBEatjFW**j4h=zxuC;t|GcX zup6jhO`$DkPoEi6h}#f>0a5i(23~vhIQw_*$0o}U|M2(oJHPtNoJ}MC!FT>c?z#7k zq>xB@#P9s}9|0xC0=YUnz5D`8yH;ZoTbR zF57n**IaWA2d+NA6<1!tl~-KJ?)=?us?{ep&X{sG_Cz(*8DTR4Srm9WhkQkpPN-C7 z#iWv-VW*gD^849k&#Nz;;pp=(^UMqDJn`5w9DDgVufFmMD}&<x?H5EeAf7-Adfm8FD6b)TV8V}6xMa_}%(GaL@7 zs)D4!SSK7nn+Nnh5S2)Xb)LU!t7*L_?=STFb2KU7L!jyoGbwvDqRd#VlZauRLABkDs07^e^#s-*O8!YA)*S$xNV} z7#AZy{}ca$fBzHzV(j+#=|B2Se&q-M75nyGDy<7;7!Dhf8c`}stA;E$t6XyNW%QTk zIlByLRo41_mtRg3TCCCxhJpt1KHb9j#5nDQTU9^YG_U+@U>#yYv zH{Ha(E3V)Tx82Mgmmgr~+;-Dz>hk5uSrTefZmv-?hyP<$)07OlLx(HOI1v&R(8|!% zaO&hL$6i|H)X5cIc>W|$K5>L2hmY~ftFLhU^f3%Ig@tOt5zT=v$Lv466`+KSwnph+Ro`bOl|DM+Pbig7Yz_dePn35~HGh&RiW z#Nctt5sj5Vt_*8U+Mt4xmZJ8ASc|FII+_$oA<%ObQCpeyq(r~(NGiwh(%=xl>SR9L z>tX}x7NnbQz6l?q_&^jh7l&Cl|K`ayqK(C9MM|ESJdQgAc<}Z7K8}Gb^t8Tg!l479Y zci#V7SgK6sm7t|w%5e=sdf@btb3n!N@(Pz9xSW(C2M+9K;MZ6xF6H#;GyKK>^_P6d zw|^S|-~D6n=2L(1NlL3Z{KE6R*?a?vgpUzYMN9>SQ~d64eTe`5-@cpqix)@+zUBJc zao64oQ4*bxEf2ZtzJJWlxrXzjhK;igFW1W~pI_mbC!Qh!b90w*_1=HRxzn$)o{nMq zL*^@q1|7o}$KC`vv8qiJ*S7Z2tikz(0DhDHiVOX3+N&|W`Ap9vX3a1rPuJ73+G+6N z^oFqgb*OFgo=F7A^m9#erYdb1G&K~K#(UZrh;5BmFjw|iT$*S1MHg}7EjM%5y>H~M zyYJ@OOZRilMVD?l1o?>!9Tf#r;gW=X1-isYSxJ>rn544$C*OH`t9xEN9adcWophFv zC9sCk$aD70faNo*Jpasj4jnwo6OSF|nP(4jZ0#bpsj=COE6mE=F8PChwM$qwXlxn~SR0(ap;K~AGL({aBWnc2-jT*-VyTZymX<`QFy{BP> zi%xRveL$B9mkgotXlF$oN1$*8plE#r8!=9(+I0ASm1)TeLLDewfzptIr-?1|^K(3T z=n3w=;f=DPpkHS#th|9-e))c^bL?2!&GP9p(o1LT^xGzb-0B)8-z0$$4JpZoZk#1~ zFtz~IU{k?|KJr=qhadR>AN=X}@ni41k0QXeRD9Qe^L>2mmws3JtV*G=teiUwwvy9M zl(PKhJr{A}iRVz!)2JavS$_AEpXSKZN9gMwT1mVtR`cMKNBQW7KF@;>ALHoLk8yJC zIWC#IoX>pfZ@A;@ZXw0Q&DS2_zVG{9p8CH($4CC`qkP-9|3hN%Xk+=zXZ{~jv@}t& zpCcmg8x4k774e~#oDSu<>9OKhEMs=L!Ba zm+V~NzBj&|mL8TGy(`kjb5y!vW$=0CmSi~Ch5(_;31^ZWF}=vo8Y0h1a-3`hO@axh z)m)QpsOgH}!VCF~YV-nF^vU_gHY9vLUTp^XFm7dZ*I3Fep3b4ZC1eU&xKUsWp~A*2 zl2A%f`&3RiVbvD*uj76z-oa64SqV*D_B^9A0 zYnEk6RGML1GuIb#fR72M4a$WaouE<5p<~1phB`({XGy`K(2~uf6)LsNFD~%FgAa1o zjdy1Q_3KcD6?NhgvqU&IV#98*V}60UY*<@c+mig(Eh3$pc5}gEj0I6D5uy-3o8)my zqbn<^b0PBC!+*`$yzATE&d=StgV7@|6E%1xAvM4DN595j{HNbVFFF=>%=2SE_Je%% z6MxBXeBcjx&wKt`svVj>k^lO8AEC_phLAiM!>{~rA7SIQRd(&t_~8l*dwQgSCsmfy zFTaLS8k-VrRGio6nctQ8CqMk-v>O-U<4!z|mgBhj7umgc#BeymB*S?>!Y+AAR%AhK z0#-RZ4T;1k8FaKV5KTF-NUL$0;w+rU^y1zv(ih@DO;!feroqYi!Pm<6n0zhMh?MU6 zC;#5~rVLV+8=VslCnUNCg;xnd}Z^DS=5CsVGJke+Y;dl?Hgcqp!E%-&@$W*Fk>PSy)3-O)+hr_2o#0I`yi&iHoq?&iE1cu z$XM_ZtqMqbYfo6-1wMHEK=@*9EJ(pi>oR%zMIW6+?i*F4ZakGOiD*V`lhq6s zqYMs3AY!6a9fMS3O~G8%!`BV{UXOOPfpQ6_dorK#5e=C6K5Yn+yqE(0tYmFMqAceG z3GatI_4GlaN|<0K=}WJl4MYJ>Ym(Cp1_K6-r#IKfIY-kpWBvLpY33|lemAs2$pt5^ z14;Hey|GN4PU21CwHIII(tW#8TCr>IE?_9-Ta>JU!Me;E7UvenN4ICstn*Lq`zda{ z`bs|j`Jch3$o^#cuJ8G7e*dBOVy%b*2%6vi?r-k2I^#KV2D2x34DK zTa!8T+hL5`Wwnz?_F40=S#sQ2`7h%+O5PA%*2s@WBLM}bh_Qw?Mr^+%8jVdBlfc(v z;yiKotlUI>$0b)^#arI|X70S@R=(l>H*?JuSF%{m;jE)7id@MmOtxc+_dC!_hLHJ9 zD7`gcXae9NM!Ssd&yMU)9M#PZqt@A3p0exSj1N;s4=0}b%5!|_%g^xmp`#o<^b}`S zP7q^_HUV9=B1P3hlxbk0Wyu+QY9z}ewbX4xMB!42afNt@=%mUn`zAI;5lt=5e9*)I z!ACG*+YD=xIxsgk$8b0t3mqnva^vqaXQL}LZ5t>`O^9BoM6^WZXhRN~(-}=<^kx8; zwG5hi?28B~qA7Cjxk9S~S4Qf(9#@uKb&^t&bttRuOl174^-%j3Q1&f{4jv-m zWtK9rgS>t=5T&popeqMCYhYt-eeAHER@j@gooN)R*4HE%#lI*RX$a z7vQMthK16hlxBBwaxoh@%~&9wJ3(vL_`<`V=B9nm@RoOeGxxmdTd}=4{_dd%_{?WN z$GPRFDT@(peV(%FF^U78ef856b{D$WP=s^DG?&rp5^&Q~eVV4mlr=_c>Q-_YND56! z@DA#Vc$Mz;TVq5k zZ^Wxn^(tbBY}7SzwV_+DFFtS;R~)#8yKldPw|(O`ap0P3*t@Wcx%oMYs-$q`rWiF> zYfsEJ?_MAf`@y`nHWiB&W`D(35(T@)U;!n$!att(0GtQpxK1)eoR0Q9UVk-%Pu|XM4 z*_&gqwn0%zZi;b^^XqFY?GWgqwHjKH^(qu?+fbDi^=O1GOCehXk17jBqeiaVAgFfj z0>(zXU&FXc4A-&Z+}X1j?6#Dl*NG2AF3!>xEMBySaQrN3#s+gCHP0+`#yF1|PpKRW z3yTu%7vbF6DyL5z%RX+BKBYfh|KEg;RRM}#RHB4M5sTyTVn#Q6S;Z;R5T9zIq^8}iS(>4r!L|H{7 z65D{aJ$&29LX<|>!VrTRE2h+p%3*RdnT7Y5ZdYB%+&QZa)t#_(PMy><2Hl+t+h{Y9 zDZe>`=vbF&VivIFxlz)B?9@>@8~PBs>1Z&d4P8X5X8y`cx#Ef|xcAe*xnket%rDGSDLa0i1ml^;I5st=&DWH*P1IG(?K?smYGIY@#s9u*kbja z7|xR{Cy#IN@Ph|A^we2iI{FgNJ@*o?y!I+9XI2=D&Y|oOT#ZQ^xI&|JO)P6FtMIYr zd|gx0M<<7OLR0Wb{1Qf)EJfCkESe=!YDm%Jqo-zo4=v8jp;95UIkk>5I@4qA7&^Ln zFA7UeB8p}HVkg45VvJ)qv|MLwgHuk55xSpu&iio-JLo*?NO@M2TdqlAjH7L9tTp4d zWl48j)C^I&!dgu-0(A}A zQ@TPnWv#GOKoQzN)Jd+zj72G|g_!V?bVV!-ZHO49X`2x}?ZGTaf?`=nqGW1ln{`sm zxkX8Bp$5D@WV|Zn7v{O-j_Y{&^p`Mo%y?=)9ttY8JsxxtOWmDp#(i}PObn!ACsof7 zlEIsXKYs5oW8V8d?!EeeEM&k-O~WVt=n!p1-{5s$&Hj0m=6*PbOX3X5U+$rnYR zZ#7?j_$iJrYaV{$5&r56pJDgXWxQeUx3aokbAGrgsOut8mP3qdK#jm|U_wP3T3TAL z8+ga~eb&S7Jvia#q=CfUCXdl_@h2V86JKA9V2tRsqgPV$wjND~2{r@|2DQZmsLb|_ zVlt<@<4tv^$P3LPrkPEXn}^K_XkFrf}jIpFU09owkwU`ig4jy6q_Rugm_$2VqpV7r5HZdYl_nvBYgCO^o|qglNyfPq0GC{^ z9Zfigcv+_;aLE}qMs>b^WNuXGE;P)@=H-*nfwe{x@ljE?E!MhB43>z2h#Wkkuj$Y2 zVlZ68BnYtu<*B_4nPU>vOB0ir8MUPeatP_r@=EA;v}jDx!>B+#O1Nr)IyOWtDm8)6gg*tnFg>~J@ak(AyFai*NCq@xMX%%o z|KT@)5vFfYu0`7cr{V+9j}$#QsYr%~A|-=w0uupwWA#s(z*<~r&NE)9^(-)-M9ogN z_Qs3(xO|6bHlI^zwJlR+)@)&N$kC z6*H?8GEQT9@~{o|ll>4XZ^Y7?4s>zKDj9*xr8su`Yi%}_j!AQFdB~}g=Q(w1nb%%f z<%uT_^7tdmyn5^ir%oT^{K^@kSx37-uOCQugwaE+ag@6h)EgwcL>(Lv?0jrPhlJ~CjiwPn3N)OMJW{B!pU$S`7UL!FI7y8E)Urw#tM^47*>u^o1^;4!uUHVtRr}j3X!4^*|Aj`?<4p?@=<&!%;P)LqiU%~ zVgU$rJJIX)$L%ub98KG>xUdMT4URq|r6`IXrB*Uivx=3$vbgexEmg1N(9_Ry z|IPQmK8NU?q2Pw=ujem~B=vO+A5qonZLOue}-`uk7wtu#BdNvb_BgM z=&*x&)Iy#6oyLx%F^w{)qzF-sPi8*U7~{4LivPZ#qUko#G`DFwb9+{{201Kha{lnO zlKo~u6Q_snlQWXZ*EuPd9mD&S+*l?rE?QfBMtiiugR`uMR$@BafGRAD^NZ}h_;N12 zVm~)te*<6t=C9|vYp>L*g~d`H+j<) z4MyHjHoueAbr^08Ie%u26URmzJb0Re2cPB1C!Xf{!_TvP?hFkZlm_PJHP(SDmQm5u zx*^rhI!DS{z|i_gL^SxaQORbds}4`DX#7CbSh4fB*ln1f>HEWH7xOHa{Irz1n^*bP zqmigyW#lC8a|Jj{WHFgR&p6jyZ=YRFw=R`bbwLJ6Bfz6Jh|X zX&aBT1tFxY0u2)6H37y9`TbdIF+mPR*2)~BswzTMIA=4lH(-q>HXfx6F+}=BCCR5+ zqn(jXgBARLS(c2}H!!BcCxu5`=n<%@inb9Pir0avsu(sktE+4I^YQfha|}l#T(6Q@ z&|Hr?v?3_dilTBn^5`Snf6M(6fAPAa@s3lS5_jKu7i|>(hcTL_nU%?$wi&->nbnk% z9$vq?grEGOU**u@Qye{dhLa~=W0Y1&wCvh3WY@*(3`fgY`fTXKxPC!j)sTXaG^rRh z9^*Al3s_HC8A(=S5ua8hA}h&EhMQ8aCqyO4}^dc&DK?J?dc zW(=M)`dXQcBuH#&KTXSTxACdc<^XVVHZrZs>VDr0FEZnPwpNOP4Kz)__z`8lhn_3B z@eOx!|K0a+=WVxh>s#()@7}#!Opju!wUmH+h+TLK#>rD=QwUE)VAT1A?sMyr6)J5k0Eqo-|0B&D+~?*&AI(J~~L`%D%^W2C||T@s*DlJJ+jEZ9j) zvgIVoKDYfs$dq8E$7BNub;_?fh@nkKfev;iK5d|BS}Yo+p(r#diHx<2MHXy`K`7;$ zQM55C3Rh6K4MgPc*v=TMNO+vz#7 zRaSSiOlCTFF`LHdaVaX2$L=I112r)usqw(BQ-*8~_Vkv_@5v-N@+obado($Go<8AE z{{FS(v$KqH)5blmHErF9x~Ow@r!;PfP3LcPe{NF5DNU&istpX0cA+vF9|I~u&lU_r zOLF<=!*(tFO_d^Em6NdKz84Do$ZqP>~qhi2<=}Qrc{t z%`qWEk0Fk8#Jft3d{XQxg~@A07W;^EcFW<(r%1|brVs+eG+rDg<<^sf=k6Nqo;PY~ zvFPq_7UeOks$wu0NQ5m&W#OF6Ir6<#6a`JwjFna0&^x3~>1Ju_njCzIwG!K^v9wkZ zgWTI%Cv?>G`+d%zKTp5kXIOiTbz`NL(VD_Id}cy5u|`>$VfebCbOo)4s&KTv#%e_y zJw;jM7M6n)DV-B(YFSE~i3)V2t_LU`FuEWbjgKt`L%-@XSYM-Z8f^=PA%QAM!J}e8 zrHJd#p-rM`MzY@ICBoQ(mLQBXQ-JpvrP;N#lh;nY!u;GEzG(@qr@yd>_p;$vRl#6w z9c!&b05=W2xjuCx6_{3vUe#k`u*Tfn+-B9MB7Ij9y&~kO+u?AXs&beJVHm&_pj)i5 z6h%cFJj2yB`n?_-v1MWBA}T;x^cf6B?7rj@R+mp>h;sYlAxMI zWUk*w8PP}kMsB2#1dBYalkdvNY5DFnMtnA8d?9%#{^AQ&0~_G-XNCdIp1`bn049u{6(h_uS5HZ@QPaee+w{v$%ts z_Fc(k3%hXIp`Ek?QsyglWpK&^AvHBvMuiOK(zFisPj9!=|oy=3%M`%e*KAcTo*k(?vHCDVlM@wSr={KiCkR_a(-@#U?_2f0@C(;+a_uJZ)&N-5A$CZI|E}H>mLn9ky zjdr9UY%P_;v$_LYkf05$bA(uvXbDN$2Ue{$gJDb2 zuf~TtXEi=HvWX`sijtu8c+M-|J)#s#(k?B_p1eM-#nq2gQPHK8bJe8e|H zIgGSJVjKaQIwbLWSj}Lt#?sObypooBS(emoOMhvOjnxg77M2(dhLSZutSN0p(SqHps~vt))e%5=L2^(zwDSpg^fWQW3O6rI>a15tHSco9_`;mf^W)&hX$DpXQMVU*h@0$2q(5 zDr*~O7!Fsc(@C5QC^LlEVtS{ER#WXN@O6@`JZq>Ug6{SWuCQYR-)PuU7ShUz(PtB& z+Y*z@OjGOD2;FIq%=E!wS~@*VIu0>xxgExMm2sQJk6R?&M$%O$lhW9(T5uWHKY1-p zdT?Sk(sfeW$%EA7znOe*TI(!Xl?AnF28%aUta$3vxv$3&3Y6I9v)G`;T zl*}TmmCwURMNyQp@#e~Tcxw~G)n#naqixO+(>k#9`tyM#1v-kvvFuf}gRr?U z8=V1gYDT|$_U15a;65z@o)wcj85T6{g_uTWOvbs+YFkZ1_NG-y(>W6tqP|YH(Iyv| z>CmGP18Pis)#$7NpIlf9=cv7B7#f=O0jiZnxVU&HmtC`;cijJGF5bJBH{Nk4b8~ZC zx&I1w?%2V6)nlpbZ@#bGs_8r#DuP!MGL*fFL@oPC$C5PN=q+uY1ypw3s%g$u3b~&x z|FSb+ZER?cJiEf7r;qUL<10M=%n@FA@mYo|$5>e%(f9#D4M448iy_+7A_rH2PD}@i6dGxaA%K~MM!B4!0$@ZJe zZs(MeaF|G2q~c7ONTtmv2=)}BTr*11=Erx=+~wAsuP;F5s5x1tkWbEEwZrpdIfFkDV!r= zGC9HuKHf)6_F?IaQ735%T|x{}i6ukpeGY(QbF&LlFQ=SIFNvuFx0DQ!NLg87YuSvK z4?1JzrLAafpot#Ss|c;9ZUS>vpAZs-bNEqYX=#a#!3tU_M#B*c3v+DLBZ{(Qt>4wJXt>?)hdGWuMJB~@lS`IfRuk5StR zgx}MtQj|DtjqP;yT262>CB|4;BurUI?=>Xa!I0XEL5fmidp-7DzK^S~x|(aQyN)~W zx{IY9J9)!xH*@ihU0kuad!`*CW>ktsK?)gKX~rPIZd#oZSk*~mm9$s{GbExKyNTN9 zT39;cW+pd}m9w6gkDlhm!{<2m${7wmbA-dsy~wFk%e;E*HHO1wlp26)G1Uo7S)o*m zP9tKK(8#G*D+nRc)S||b6uyvyk3`uQLx3pnQAODZd@BGvq0z=1#~O2`+vIE1O;n?4 zEZN+=Rzx5LG1XKRJf3sJ&?UmzX>HH|03ZNK zL_t(aF2q!;)O3Og(zaZe&6dhU^zWEEr|@lyV(asEbD$Ul%8JjYYh8`+QzdDI8YERQ zB}N%B(%nlTNSg*i#+DdT@EC0}(p?mqA^ME@h*&M{*zufCN!8S=N}?BUM0ek$7)eIa z;&5dj9~-REqUs8f9NJPgAtsN}(9|20 zu9Wx)W%0q&o9odw4MxixM;kF-+8q6BoCPDFu`3D`P}dFpd5M)64u|xL5|dF+prG|= zo8Oz#grrfX%m(TRcp4w5syUgr#1@?lN*kC@9=y66$ZbD?FCD4zvQX8hf$juNiq1cpjzlOuhN1{~TbmQRjYSw6?BCpI{G_&hHi zIn6T%k8tSl)0{YQoHOT-Qz(tG8`vV^Dn-8`U$km$}n}U^w3mgIIfNIGuv+rUBbt~^gk6=UTtNyVJSc3Q zk@|ostVG&ILu{hxIUeW(dKp)EvON-JC|SC)*11Dr7sJ=!RIiiFUTw8?E534w|} zP&mh^k;=rC1xm^6$CZUhzZDX-3+R+6odiqOqnduz$A>5(X06P3%d(ItU%#w_>ga7r5paoH^#wVsUp@dQw z^hZn&Ag85_vnrBpX0xdl!sJao*;k(KWzQO(caP(&&4Dr+q9^zUqa9@-lo_9uGzo>t zt-FoTGPIF}g?Su`JKuO0*WP*)u2*sY9d}a?hJ5SW-@)GbomXCwlW@{w({C6J>!_}IV^CQ+)1{^uO%yUn_!V{0b zz>^10^5W5FX_~XZ2#WI*l>s%PDn00iP?UCt==_ zG*c4S!+3|(3Dy&-%GqGE>Rjl~gcD#5xpV`st1QpMrc($KnPPo0UxH>jMz`Cc(MS+d zlRE=K(NJNxU(oHn7WhPy2t_Z;NLnG?QA1)9}bdBNL7D2AP2E=8TUu@wSJu8Fcz| za?2B^Pjl}bUt-_JL(j|tB3vMFAK14qxKV2vcOu1NCYB8z>zrWAU+$`zU)7GhY}yyF zWVbAEsM?JTD3Fz*XLVRQvOq<3Xg|wnD1}J^X~5VVn*|szZ8d1Fo8j<@tJt|?7hBeE z;*~G{I-Yar=%8~DgHFKVWnkp{EJs+6SJC)QgcdsZG=&9M`kUDx0t-oQdiMk%z5CxIX-{uoqYO}Pw|z9ALfxK9>!)DNW@u0l97&k z(x!pbVO)>)It5D$7-wj&mFzxvgfHBBM^FfNnjj2PIC9gCw%$e7g9gE3?bNXfePJU!SJuuZP%^Awn?85h}E^w-j_)s2{mp3|fc_*Xv z-l0M|&+}2$f7D?Niy}kFYd{#$1DbH7(V&<0N9HBf=N#?&#X#9#+$LO`BrL2o1$3zG zkNG39tFa}htdS%kk=2GdnDUA&=8Xq2V<-TvNVV4yUP_yd!63fqgpx=FHrC*!Kx+|a zR>9?>=la1G-3L93){PNAGNFT!BPJ*J8EIo2lLxzYm-TVhk)|3fG<1ql8NF^ENexMe z;WZu7Ry$3v?^UO@ou(-I0u{r%bWqf>!Zg-JJnvy8N z($aa(oPQGIvtawqGqeK#5xA6-W1TzuUiUgifc&Uut*15A*zqnQP zZgl`&{vuZwo3iGkyf74Omn_TZ_xpi2?>x4tx$?T_(3qLz*nz#g`cUAkJ5Gq>FE~Xl=}(cL6Ir zMp)MG+r`cU2Whw4eDrt!jH$*LOG}rzG=Gs+vxP#?nwe!xCv@d}ytV=<6Ff0z!ix}! zuPWX1FDHJeQwg7K*t=I574bWpFGexGK$h4tY)o_yj_Hf`BV zF2R_LhVx|o9+MLjT)K3Dc59L>@1a!avQD2rOW!Tx+daPPEpOp@FZ}uut?e_%jTeVU z;f3JT75nH3LrXYpo+G3xF|mqSMFDA1%VsJ^Uk-+hIC?&(nKY4EPU;kkse|0oP)QU> zxdCJx2CsqooTh0Ewds{m@la1Md@{f!EJ!AvfwFK+Dv(Du+B)v0=3p#@|dfkk^~1>FObC?Pi%Sc%k_lRRoGwcPTC|jqG{R>yNgD_nB+ZQ6Srijw z`2x*$$}ls<($6!}W=dZfa&Ku)O<}uvFf@#CqlzY?-ChTgBqT`#VRI7cX|)qNoeZM| z-WXbqu@H`>6iZ@}yxBv`He<;+y?&rxFD-UywVP~SyB+Nk+Nll&F*WqNi#+_;<2>@v zV>H@#vj4z-UU1`$yx_(carnRi*0g76r>&4P;x*-1!e~c3pl9-b{CG}S<3zQb-DYVM|tSJN4f2`yZQ1xkMq>I^K|Vc zL_SXT(4;#IxPWP91?@jMv)`0ecnaQa^f??aipa0<>b8^RCwDa^OBvOz8CJTz< z+~fnBbfuC3E3PW|tab-w%auB~YNhUDnL%aE%&ZDw)rmZ-S?J}WR1CMv&}p$#FF#J* z;5>-wD(4kFzUthlt8iWM-vVwcLu%E|!n**khU*z(lY^dR$S^Bkry|#*(1i#*CeoK} zoQt9L`-Wf&PQm@ z1?hX5B=mbdl9=z~ZD1p51Wts4704Ljd|Iu9tn0BhyzV3kdG)9k*=(@b zT?oEuGO*UNeuuP`ptYviQY>~a(QLLrXIP)p7Ly?r(m`8#673kDYSS1?vE+36m$`29=Ovv^7rU?&Y^0royu<9yZCrW$C~e(f z_Z3%g=-?qv96QeJ%q)}BQ_M_G(W)j;!~h{90=y($5b62CtK3Dura}WLf|A+`fhzpJ zDhrv%MjP;mL3UGFO#zLNP!womG=bGno#la(N->{o+ef29?n=Eqa(q-=W%g?fP zzmJaDlaJ)&{z9tiUHW zY~fpe;$3|7XMZ)22qN=?Jjd(MZIrR~B9pobLsdx&Wy*C`L|PT#Rbk8WP`YkDQ6*ed zXA*UqqUtQJyik{gs%5u=YQY*%wFmQsD7=dcu#2$9&{bC~BZ-u+Q#rh=48K}y5qfA% z5(eyn?rg0^ln5i$f>}0U)WI@4*y;~k=fQW>7(>!%gtWpeCJ4#^(FO`J1Eys$)6t10 z&kfdk5~0Hkq!L0Viy4fNQMWT>qPgg&R}8GBl)({K=`dSYL337IqclzE_4-lMk;nH& zM;4eHkQItfB6P_1h9`-GpU${Wo>)D*O>u0&@=uy@l+R1@E2iP#PhRtg?F|%fhts6G6b$abG zRINxgLxf#*a6+{ZBStOYC8SYF?*S_WqR<8iffXTWNEP-SBLf^?vhgU!){3W2&vE|o z4o^IGmM5N?;|q5@#-oot#p4e@$(b`xU|g3@XC9#!QNqz|JFMy>O{ooHVlTOeY8$t@Q2SEctB3xCmFi%Rh-?o*yeRK>6b-LYVB+4$c)4=U%Z*NwF6K&!XT41D7X z-BHmg6fkjFzflzC;v5Q-&+wYX$ROT2JJ4Y1xafz3$ncHv&eLk9Kro%ux-saeoO9SX z7uB+Xmf*F;T8BqS1LFnxY#vm72Kc2peqTlHOo9{+QOP{ICo)VTyEF|}(4OoOn5 zS6Jy#7WzuEdB=9XGJkInIyp-VN#EOAm3DYjqgJN8t5XsubHsd)dv5*$lbfe&yswH` zUP!DC?v^410!b0Wk8GSo$QVi+Zm$UgL>El=5dxGqK#@rhGZTmyK8idO%w1mM@uxam zI(LbOAG*Z-4?M+#cRtBIciq9<+-&Ly&D<=)$cLZoQVopM=m{} z_|`YPj$eJ>yZGUE|DPcH2%BJ$p~GsdLtBaO8h-F+-v`PgQGEJ=GhDxGJriE=&L4jd z@BgWvV@$PhvV~I)>EQF1x?H(toR-M>+(-VAeww32gRTn+k&0m5Af+Do36%wL>vUi&8fVdIc2M1j#b)@#{_&OEFbfVFv4?$EOgbec%V{FiP z*gR5)1N((wbbhrYpC+W$67G#KMZFCBtrg z!;bCT`^7JjL<2xmGN&8m&6iDDD|!qskuE`rgoo~Xl%t!bN1~_0j>zI%fiLM879?<( zkUHmObbIYbxJDweAasb99l%S1o(JFebQTs^oX-ow}&PY>oQ*U zl9%!m-}??;|IM$)xjdn?9cZ^rr9Q z{cn3WeV>!2p-V$5KK%P1r~Qf-b71Ehj_qBCata@dZ_$BBC08`TEO!j9qUx^OyOY#yVQ?>C}DLbY7JXKh&PIojk>>Q=pR_8c%`7MLa#gFP$%K77z zI{0$xWV6{M&-0N^9w1GVVv7~D2YH4Tdhop|*iX*MkkVK>m!R~IMJ@^o!H;w+UW^Jd zl? zqMd;G&LH!{T8GgcT1`RUbXlCA=Tdf=w2?45GtJ(k`#E&vO0GV3HP>Brf}Jy)gU$Y6 z4mN~jeDT?fu$-Xc_#~EZ*6aQup6)&?|MD3$1MxnxHN)U|*RI`sD$mfmiLo~LDj8d| z`(&6vR{i2e3@_15?!W&*j=tdNh>uIrwMZEi%+euz&FWF;LF=g(C=kD zc>e$ti56@m+rrx$;qKjyUjCR z|MItR``sTw;K+oc!EmTqxMVrMTyb6J2~~!(%J$?{D6?vbUWSNPGP_LcAllKX1=pXd#ugA!zZ}<>Z^Iti(bfqg9q6&xn-~&>|;o* z4l@cThQtX;i2fcpKLkBjZVf`|u-Ow|-F5q!W9J^@O=awsuDIfg7&?~l`LCCnlC(@*|AH+|c)0b~1kSruUJGF!=kzSH8sl<6Aj*?jkd5XTUnX z>xbUS```KwTsCZ|!N@%4+UP zwJ=nFS1iWG&jox`Wl@#$XUdCwnc7-c3|I0_TNX)N-rbjU8&wvU)_P>&uTpzQ)#PfR zP%qA>=*G&o444tfp)WPhqaOe%! z*u^emSb*~=BQVa9>Lk#8RIn6krYQ>x9VTX5oWC%Ka-K&Xy&qbze)AT_wru3a7rcTO zKKFV~o;c2UGBM~P8a|0a%c$@20q7P8JV{stg~v!s9(TJ9A2V-ah?fu=Ydxxfro>mj zf;@A)utYo=5ia7MgL@$}EVdji6J`=Q%T4LZU$iRaQb|qbU_yH?KJ;i{dd2Je-?;BplTVMSe@L+^R zYQ;_8`&NGOKfVhm`{4564Y4>+(q81IA9@?#^4dF4EeQ%*CIjC=_*M{}A(tu0>%@NL zL2BL3dZqZ?>H=Nv2+B!})nR;j)={PIR*OR2!d|vVsdgL#X9MRVq!*zlf~e2?NDzoa z&EoYJ_aAXfunv_Z*gWjqRUt%;yL2h!z{x-oM21C(Q6MfT65SX?bC>W{^e7Uo^x_Qi+#ISVu+7IB{K6(~}#APR8iw1}!XF zH_4qt8i{HO7V|DzH%L`NXUQ<0H0WiHwQFbSb~{W>jpLnXZmC13(_wz$EOJWX#v5Gu z{8N0}bDzs~*WAGVorf7qCrOhgNsHvI09pBcJ1H9#(kSvl#esvGp44S!LHhSe)2tU=cc!OCwsPULnUBD zo0~uV1(bKp&CT(ycij|AlH?N~`)eNi%7Z-b$`Z;LJ#ANu$44t+1&r^JInQ^0=Z|pc=wa@=e~!=Jelz3kwRj?>8eiLWlxG4}Ymus=yUu5- zO1&*F@YNlDnVwpmPgJ{`Iu&^J`Rj^Em6q(I&S@|oi1cMg*?f@!lu-=+>tHrp3azRZ z!@weBkm)g6P{Vz?y$(uBl0?OTuChiXP;6z|h;GHh&TK>wSsLy;XGiSg(=?^m>qS^q z4uYh_K>TP2vlHtAD^JIQB$W>H4JAnv9R-B~l9-Dz7P39ObaD1KjuGSF7qQ(rTyGIS zxfbL5pfmc?lDHNk2?15oc;@r-TzK+PY|nD;@}q1!u!FUS*7BSaS9A4MC)l%f7h{t% ztecu)B5fj3*up{^8SNPB#t@=BkzQd;QS*~nc?MA}7vgKMY(KNCOiIVWwL6gGO%kP$ z-VMC4MnrcNSYY{XvyHWa%Pf$0?k33;K21S&k<#$gg^T>iyML6|ecS7}V$WWL(%gRE zm-rul`%ymp)4#&Bh`#$GXMUl}$N%yZkcfdUKKD>7wjZTWGkmLS!~T`AvXB&f;N&wZ+4VPViL zmkr@ZekPb)4xZn;Ws3Q#4kkcMA^$uGIAg|oOxP>mK1mXkQi1k8LIMb`4Q1Q*^81t| z2{v~)>oIxoYAd$hBJQ-8>$?I?*+#n4IN| z@PVC)4{;2t5DDYIHmms8@OZ`+kR~v(VGZI!Cz|_>T2j<4AXOaM$qeBQ&PuwZ^!pOb z98zd5UtZ!b{`}*->eVkNcXlA4deN>^T>H*b_{lZ=(GULwV>(3|&8d?oNE3|{!Qr;A z;G19jjr`@W{TfrrIL?*4h!9xs*)=xJ_`&^r_d9+7=iuz+CDzQe@m{hpzW{i~(iEIU ziVW=&HZ&#%K#uP_Sg`a&N+U_bj?_37<~{#%%a=KMbT5;$l77?i*T3?AvF3mLcaEKU z4ii)3VYlZ!zx4}08Em*Mq1_d*^LZyxnJV%0`<#C85dnn>}I#LV8T@!50+d zqI2>H!SZfRjOt>Pk|Xa66;eQml?^^zAtu(v%Ceh3ax8t*VX?b_lA3;=(;C-oT)T!HySB4y-#(5Uypru#?BKwG0~}a?Xk^W| zg;vf3&S5cw;kApOQ#k?~0m8-N9o1l7@ocFi`k8!klhaeopI^WWH&9Zrf?BvLnhGXl z3DT*+-moFuML9)3>+&1F`K!F@)h`2^gG{*ROXpeJ9%JJb2@3dMZ~8(0_5;6xesrF> zOBeaz2Y)-*1q(-CDpF^7?aAlyrj3*MIgqLmccljF6rgsax;l zTW&ms)B=+SnsAcpz})anjPU&OZ+wy`Z(rm~58lh2x8KZkdp)LqZm^?NO7kDy{2%%I zKfQx%4{hhuU;2Gg-^XZ;9&7V~U;BUX7Muub=1Yq?=N_A5cCy9vrY1h~-1Oe}@Zq2T zm0_XnLZ>6R=Z>eCTj=qJANwnCE#CXCU+3~U%LDhHqXC#BXWSttc>eQW9Lz0Mld-Y$ zBzl4FqQt8O+EX2z?4vzc-vb(0qw&sSd=D*CnvL<`ZDcLZjv-}m-WAdyX$~N)>JGcg zW_r3^cwND%gS>`CXH*ba9dcJYlk(zURjF4YuQDtKg#|tXGe8lXEeHQCv!n3kB+0;n zv))A;{s2`er3M1lz`rm^A!|LpisvjgVP(-{$Y(bg8ysF+tyYBP{D|XlvDk~~5)iZn z5^IB%iHf#E&RXzp;9F%~j*}`t_@bZ&ORUKTO|bEbJhub84{HOgqz07ZAWl)C#mDw? z`VlKK{0k{#1mph`&a+Lg5-( zPfsF)gKD#paDHKtH@xA^At_EJy!Cy*%WwVs|IIEoa`*h7pj4B~oh~Q#UBl<@`xt8` zCfUAoJKj4Mtmcj{o#uH*H_!%N@!HpM%Wr)oV)&r6WYKuO_~03yzkee?_0Atb0eSBD zgOC3M-}d5bW1?9!J=EdDnTak>E_&Ym-nX!3Vhr8v(>^fC=H@2uy!mYWt69(e&qu{#bURMe5k=a zcRAkl+W*EE@A@(iKJ-~;r)Rk4#MhDgKJAGJ)H$f9XvI< zi+2N!LKS8ze3^>pEoh~6riyT{8a2+fb|HAHlL^)n8lS&{|q>aV}yqJrWt=gqj(IIze737N! zCoax9)p0SE7#oUV;(YLZ$_*HUh>3d+FxHUh=<=X-s4^yY8d#RPi{!@On}W%)NhY?f zXU~ECJpcG%uDk9A_U%2y)|u^CaugbiMSC3w>dV)af{cKGG?tISVkpW31+jv3LM|^7 z&ob!h{}%;h#}#||@;}{*76}@KFQ~4i1)@4Et#bdX`62zKoOgcjJ7~9>;2n=$I>&Fl z|J`iZG|5;$;p*LQv;10>Qb-k&5X(7 zZ3YQ~)|0#7tSiHW8WX$3qKFpsTVqTxMnt2O9-K?6b(lklAObeM41q#5G)e|&s!xv7 zjy!NFX?tiTDS5X~YM|H6F?mMUbQo)oldNxY_{b4n^r9DW%{A9>?C4djNhV21@mM4R z;fw3(@IFJkGz`{-0_S5W*|T(IUo9YT;P62{o&^`na;QMaAn+?LN>zBHj4ij*F`j$P z3kSQv`|p1o%o&#Yk~4CNar*?VnGV7%;w)sB9dCQ*4`F>6{{7_pf05=xm-sI~^ZgiY zdFkWgWK4E|`v5Vq{iRHvt?7MkVo7$rx8q3XP9*ItFG$}YF% z^K?F>Ns4H%pPPIcqpa-FResEs3>u{h5KuM9tPIJey0BSSBeR*pn<_6Q5*DgzYeE+( z5w$a=sy;>t5xRfxkSMY|r=eA}>5BD`a*I%(pi50fBiN)qiKx8F@@(fZ~6}Y`Pcs5(@S#t`DGSF1DiL)7tlC#;xT!S zR1K^*q{%ei1vX8Z^s#x0>wAP+Ld#|xrUs)pAyV)HDHI-q5J6e&oGEn=`Dh+QO`d!; z3%vaMY8P4FsSgT(U@#O8xgl<_r+7N8M;*je5HW&CFhu>99iPiZO{qBeji0mf4t^#2 zu#4EeFQx32Q~AnH(&ZT3@?)4hkHR&E0=$wVb$NzSbQ48U@PZM0lEVD2T9ooUA3$Kv zxj_=;s6Bk37&#ZTDruwu3+F+3w9>R&V`N#M#l=My78Y=XA$c+@Id<|G2aX=*5eTd zow>x^=?>Ohjti3D{STezr7wR~*wq+|Re}@a<48P~9!*lb6@1U@zl%@*=10kZ)OvCy zA%BWnZ~HQ*o_mbBzT>XH_$Rpf<=p#)CI0Di|H^0n_%lqkkMN8C`49NXoBo7_-aJ`9 z7%$3n9xvvwt^=}z^$TR<7C{;pq<~M$dZ?9t3|f}HB~3&rf9db>IZv3lQ? z&a-&DvaLmxIaRg%sAh*(eWt1ms_NhC<}AL%cq+6E131U~fwrQsGSPB*p2uL`5!q5n zlF;pT2l)Ly73k<463}Lvyi_=1pu`zm73I zHdyZS(0hdNv|=<>1M)?hTkz;v$*!e}g+Cn=smd^_rt#I8{#EA?Q; zRmJ?P8jP}sQe8I4N(%Gx?W)CTu+xq3Pcc8KI@~%Raxn%lkCdqBdQiQdMF;E%YVjhm zFV8|ZSoX0hE8eSfxz%V%O|;(vdB_!+D8_Q3xS#H*ESv zAhd-pC}x5clEc;Vv06aBx)>_;o5(;B6Zz4c0HAL@TP(Lwu+g0i*RolIMMt3PyF#hDclM^0+YR z0n^FanDbo2HmciUS6NEcIYe0#Fc5%wk1S=$SBIxV!@wcswmR3Sn>$oHk@EXghNJ%34xhlp8i&!ln zU*!e_0UUVQbv*gS`;dznHsZErTleblbaW?cD~nDsNVT*Y>rrw8YtHUv^Y#Pu)0BHp z-^-=$XPH{#=$o?$6|i7$4aQi!modq!oZAqR)WSkVY}Lc;AlO(3Y}!PKK7-{l?h)3J|6VpCOEq?{iPeZ6%ffk@SEFFaltK8L@B0IljG zU1dcrr^f1-K&J+_;43Bd)j8IVbP4hHR`PP+6B+40;(z$>H?=^ zh#YnntpM4^xp4bD&+)b&U7!_C=rF4jpd*Y^$ndNS!cc1rBo>z$QmqH?yR{bGXyRm4 z;N>~qg$3Tan5E(!xi#n{Wo&Ycsm;@D+q;YB+;BZ74(;RmBgfc0v1cWw%5s`(O>AlT z8yRf?hY6w4+JkaxXlXXFS~*sS=wGAC7Cw91HgD#M+rEql*_3erCu%bes#X@>2RG0n zLAHq11cfn+c-iOCnfp20{|t7)K|7<}%IMqBg6EmRUQ!g2U&Z`K zp|E_AELScN#dWO9E3X#JGWE9@P8aEVWvHk+zbSVH)k0gH|CFy=cs>z)yL^l~HIB3y znL#c`NRLX}p_mDQaE69d_z0DS{)vS8ZbB%5)l>a$iPT)_z*?vgWX0cOug;{Ql3ti z|1f~Z%6~2!ppIzp>K|nFSS=u5trjHgg!b;+&n@;-7~#XtJ^rnlb6tkCh6_*y{}+Jl z;#^9O$NCIw9G(1P*cMtFJa1frmI=aVQKY16VV1gdxoRP+i&6CuXpp{Oj|}09x*>Gk zfV|G?yo%%3K{v}D&xLcqg$((sS5tM)RDOGg8QH#8EVwLkb=gcJ6xq7xszO-H7xiJ6 zR}^e(hlA{5KwWd?J9i>S_qs&f=;UTz~C#y!hH1xMIT=rW$R$025@VAOtNJ zaw7tqMcgIDq&^>DU@rv1dAux&?|hk5J8S%$BrHJIvpDAvEY&ZG#*IHEiXiM zuY~hDw%uT@Ldl}Dv2oE)LZGedAtgA!d}m+vKLSRmoCAhTiD6TPa_Sc4WpItJr>B;8 z=+$9#of~cW+LRUg)rI@%iq~jro~SUiRIQO=_5Pz!Sb&2>ja_w}({kN=P;_|Zzn64tj&fk<9%h^k-O^5PP9(?zE_GSrtLI86GGa_2<`LZOu=x7`rbqaEVDsfZE^aGpeI^4x+5 z&agx}Z?H9Q;-mO5&n^AAOLUFHSfB}0TPNAFXD26)zmVfsALGF8gKV3+f|=PF+GAt1 zbZev!@FmDo#Jp=y_?#CT2`R-;LlKAjGD5nEh@Y7x$mf(VM0W9WN{LXiT0B;dXGH;t zpY^R9H{(ULhY+O!sULp9Ml}P4piK_4(#!Um1!iB&AG~wHO_SkbU-nxHb_rs|PN#0C z9dLb7YaPB4eYJpIs@jSwY&AMKUhW9Hk|lawSF#cuR)vg46v8niXnE@1Xh2e3XH`DG zq996HA0o99bTn7$b<#E}u=og3OA z`1-}M9*!7Y$m;SXRz9_Q6TIqTTnzBNA7cH(=PG0QA*;PClKi(^W=GFiEE_17&#$f! zRqaBC-IJ`HVU%Yd;hKp^E0!bIy$WSj^StYF?5mrAIu==-O^Gh$UKBGR=iI z1*w8ic&G5fppyhIMd(0shcOwwJj1vyq&ZD#*uLWm)~?ya?tMGhxpxnHckgA-?%izK zyonv-Tgu>NNThRq06AH2h5=|ovC3jyJyr|IS9=74M+wR7%q%oga$n}ahh65tKgSW_ z1+@%oFJu4J&Y{Y>sp=V?Zh&2PpXJ>}Slr8ANW(5?c}!}Z{YLrcs`+36i&Z<2mCm;+ z=&QcoY6n!O#R!@QG3exmzjMpFjeo0hOjx~;}cBJ&az?GdiEbW$k9Vra_HbeuHJW?sm4sHJOtfG5j!i0!9p&~tesN> zk(?D_1|e;P6w8FX)!Fsxv06aBx`(rlDb-|R%^GCa;Io_&b3}skrihw~vSPWKAXj)6 z6?xEQW=^s5e>w{6(+!#H;#bS2j@7@_7b5vIx{J{rc=6a}3h>jVGnRi}9kv(gbkz=` z3|W;kF6u1NN3TuIMnK9iuMh$k=SwPjH(6s*QeeCr$pjZd4zd3MTs0K;Aq3u8wA2F) z2m&02Zk8bvMSHBp%$iw_pE}0g1BckTZmtcT000ZdNklz_PSa@R*%&J@>PYfqW+c5 z`}c7AwtLXUA{nj3#n97xS%yNHMqA#UR^h2SC3Kx4x>`i4jy=!SExnA-f zKbPyTI?1V>2WZlW*%Ju@NW4V&p`&dq#ltwE@|;15k-5UM_#h!Ga|yj{PO%DEtsbid zU^t41(5ad)AGe#2PT;x?)ts2_k}8VT;P0At03~sqh|BsaTw!#~4G_59g83j?)A7daNGLf&wBU%Lnf{c<2zFP8Y3P_z;IT5R$Fr;96(ASLdlz2VGU~U)3ZOL)&68 z&a!L}K2#p4R~bpw=O{1CD>(@d&L#XX2-GUNjbU-|wZ$h+xJL?Lp&Tz$Or=!#(j20E zeae|DB0^L`4(BI9tsgSad)*#OofthVp}k>(O*^)6=;U!uTzQ0(hmW#xb{(^8)-ll@ zV|rqWq?AiN@CWlCMNnM}AK72HpnQ-5pL&!FgalV$Mm|9Z(9WZUz8MS@kt~OIkZwJEwIKRmBeAmbIbff2dhIc6|IEXnKkU$x0{{2cXH^! z0ru_M&6aK3nVp_x%lZvWr&BE3_m@}mLX#tW+%yc;>AraNK8zhG{W~xy;(dyTD(JF8 zg!>L+R{hY=Y_*E49;?T{{{k}5832~k1hqT#O1Du! zQOo?RDs~uk#)0LbbaipB8$6FdZo?-U>B5HR9fFFg`i!FRBuRp_V4TNG(5XTS0V-xg zN9{(#IV=XRGGs$C#u!LNZY@h$M%G=#dW)ByiRnou)=si+-3IpTyMkSN_po)#HV*H* zifvoBvU9_ZIHC@R!(nhFUWIe_6i)i1HAF1`S=6lTqVD!j^9QlQ&!e-V)noNoJ^tMn z5bGV%3xpR;%}jxgi?)fCgylwxq~qKhwt_+f=adP(YJcyi(J!VkNF z)#=0Pv3jf)kgr<*Q82DNw8q9@q7@2=a79M#AmFvCx2P`SD+vONMLcv9LuzcbE2+X- z)tJ?)OKh>-6)b01mFEd%G^U769Xv;b@QR_hlxkqzQY7RlsjzOCc`}hS>6t!@S)a^h zB&nj^Y%(@A!G_JdIk5jA$FAAKjW^uLwhcR2+ggVp4FwyA#gRBQ$fyq2#Nma&dWT1W z0Ik3|kCTA`)o{^kOoCOhqw)b<5=9cx>h6E_SUvvT9naiMbUe}tob*TpTdq6G+~ZH8 zIu?utp%K_+P*uT*s?%ds%>zRxp-bs_4yCA7K$oej)#ps52n%_PGfkZWr7%9nD~T}~ ziO^v;t|Uf6;=&w7M**QsTUcXBl?r(qUXWXhOf-p7SZl~dhE@r^r3}-zxHLmG72`9L z96Ef6eTVk)yyxD)$>Z0sZS!uXs{4aMSWqQMC|0qN5kcu6<(rQL2^9fDWjzk%*rC;9 z^;kVtJCLtMWg~cD6%fkNqeuDN1E+Dh1u4n#D3;F>R$@FAGmWx-BiycFa}k4*>cxH4 z$1E3?Jki)Z4%&qvlLqH<5*m0TXv!u^IC23_fl!j^Opz;x)dG~lH!bunrq?0s^ynEE zq|IZ3E!%gpd;2!7z5XQ6Iesn24xC`q`Yj~F1d6QiD4|fpsY(4ZE>;Kxm)?y zq8u<()})O5b@f<1R*%&J@-^x}RLO1hWiNdhpZLh1G0|+IjYku_u&RrFQ7npom*Jvn zv}x6*TuM>v*HnG{5qotPth2R}1L|=q8^MlUN>nq&dlNmFEOx1j?ZRUMNIv+u}Z zo_p$A_Uzon$zxZsee)J(8`HE}El3j*l_HTO9O1^rm z9;?T*t$-9Uu*DqU=+UDf-2dC&*(5b`1X1|Qs_vFXh@X)`HWC5`0cP+FOfV5XfbZc5 z-@~WyZF~=}z4isn3{rPhdQsJ)rExfB2M+Svl~z(O^tv)%<|8`67mj-QXrt}UWpo?p z-E!0Bl=@=>y6sJLGtR#hrqKZL-V#t9(s+3ZKMhai#I1eF2O>VBXeC0hZ zuToDrREl^I@k9qs3S1Dxdz=^4X^NW-HO+F#!~KE~npB2*RWdr*XL3B_`sN4Dj%S?D z-Y`EoV`sd}(e#MDVviEPA&kiw5Zj?V?FgojHt`jy`J94+P5|`qM_(J2K^!9(EGicRepR8P5vWqN8SFz^_9y?ZtaJzk2Y-f71~nN+DCLc4XfUUUweS29fo1NNCDZT z?Dq(-3;JcnXJ4>bMx>weqjednolr?kB_AnJfuMmD)c&$;_}$Ghuyd^no2?MGyz zaGJM3Y0|wRHL7tdzv?QRJiq8`h&XXXQKCRVk{c|iMR=9Y_E*C&3=@!N!Eb;3&aXfJ z!t2Jfbu{7he8%1F2d>^;a&>vZkK^~W#i5wi@O^10jk(N|dkc+Ec43F4)gO70pSqaS z=mZyCk_eZKvBZev#x*$+5oyxRLloAU;)Y=uCLm8vL*PCxsKiqd@G|(Sn~VJGAs;(a za%=N--9b9q;W?0v)1zN3ONK4%GYrE74mg{BN4*3Q)9z zd};l-*z3Mw7={VR*GPz{;x+A?T6MJz!!V2|;UDRjg2wpY)YSk0002ovPDHLkV1h Date: Mon, 18 Jan 2010 19:56:02 +0000 Subject: [PATCH 05/20] Fix themes loading performance by storing small icons. --- openlp/core/ui/thememanager.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index fd0284412..d4ab42432 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -185,6 +185,7 @@ class ThemeManager(QtGui.QWidget): self.ThemeListWidget.takeItem(row) try: os.remove(os.path.join(self.path, th)) + os.remove(os.path.join(self.path, u'thumbs', th)) shutil.rmtree(os.path.join(self.path, theme)) except: #if not present do not worry @@ -259,8 +260,16 @@ class ThemeManager(QtGui.QWidget): self.trUtf8('default')) else: name = textName + thumb = os.path.join(self.path, u'thumbs', u'%s.png' %textName) item_name = QtGui.QListWidgetItem(name) - item_name.setIcon(build_icon(theme)) + if os.path.exists(thumb): + icon = build_icon(thumb) + else: + icon = build_icon(theme) + pixmap = icon.pixmap(QtCore.QSize(88,50)) + ext = os.path.splitext(thumb)[1].lower() + pixmap.save(thumb, ext[1:]) + item_name.setIcon(icon) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(textName)) self.ThemeListWidget.addItem(item_name) @@ -427,8 +436,6 @@ class ThemeManager(QtGui.QWidget): if outfile: outfile.close() if image_from and image_from != image_to: - print "if", image_from - print "it", image_to try: shutil.copyfile(image_from, image_to) except: @@ -529,4 +536,4 @@ class ThemeManager(QtGui.QWidget): theme.font_main_y = int(theme.font_main_y.strip()) #theme.theme_mode theme.theme_name = theme.theme_name.strip() - #theme.theme_version \ No newline at end of file + #theme.theme_version From af3f69afcecef4cc7e438f22b22c7a8785703ff8 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 21 Jan 2010 19:41:17 +0000 Subject: [PATCH 06/20] Finish off Theme thumbnail performance improvements --- openlp/core/ui/thememanager.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index d4ab42432..4e5460b0a 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -108,6 +108,9 @@ class ThemeManager(QtGui.QWidget): self.themelist = [] self.path = os.path.join(ConfigHelper.get_data_path(), u'themes') self.checkThemesExists(self.path) + self.thumbPath = os.path.join(self.path, u'.thumbnails') + print self.thumbPath + self.checkThemesExists(self.thumbPath) self.amendThemeForm.path = self.path # Last little bits of setting up self.config = PluginConfig(u'themes') @@ -185,7 +188,7 @@ class ThemeManager(QtGui.QWidget): self.ThemeListWidget.takeItem(row) try: os.remove(os.path.join(self.path, th)) - os.remove(os.path.join(self.path, u'thumbs', th)) + os.remove(os.path.join(self.thumbPath, th)) shutil.rmtree(os.path.join(self.path, theme)) except: #if not present do not worry @@ -260,15 +263,14 @@ class ThemeManager(QtGui.QWidget): self.trUtf8('default')) else: name = textName - thumb = os.path.join(self.path, u'thumbs', u'%s.png' %textName) + thumb = os.path.join(self.thumbPath, u'%s.png' % textName) item_name = QtGui.QListWidgetItem(name) if os.path.exists(thumb): icon = build_icon(thumb) else: icon = build_icon(theme) pixmap = icon.pixmap(QtCore.QSize(88,50)) - ext = os.path.splitext(thumb)[1].lower() - pixmap.save(thumb, ext[1:]) + pixmap.save(thumb, u'png') item_name.setIcon(icon) item_name.setData(QtCore.Qt.UserRole, QtCore.QVariant(textName)) @@ -455,6 +457,10 @@ class ThemeManager(QtGui.QWidget): if os.path.exists(samplepathname): os.unlink(samplepathname) frame.save(samplepathname, u'png') + thumb = os.path.join(self.thumbPath, u'%s.png' % name) + icon = build_icon(frame) + pixmap = icon.pixmap(QtCore.QSize(88,50)) + pixmap.save(thumb, u'png') log.debug(u'Theme image written to %s', samplepathname) def generateImage(self, themedata): From 56275fbc211ae89d41d41f9bbc9292d5120a8249 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 22 Jan 2010 17:54:08 +0000 Subject: [PATCH 07/20] Remove prints for merge --- openlp/core/lib/renderer.py | 3 +-- openlp/core/lib/rendermanager.py | 3 --- openlp/core/ui/maindisplay.py | 14 -------------- openlp/core/ui/mainwindow.py | 1 - openlp/core/ui/screen.py | 1 - openlp/core/ui/thememanager.py | 1 - 6 files changed, 1 insertion(+), 22 deletions(-) diff --git a/openlp/core/lib/renderer.py b/openlp/core/lib/renderer.py index f6da3f6b1..cc976dae5 100644 --- a/openlp/core/lib/renderer.py +++ b/openlp/core/lib/renderer.py @@ -42,7 +42,7 @@ class Renderer(object): Initialise the renderer. """ self._rect = None - self._debug = True + self._debug = False self._right_margin = 64 # the amount of right indent self._display_shadow_size_footer = 0 self._display_outline_size_footer = 0 @@ -244,7 +244,6 @@ class Renderer(object): bbox1 = self._render_lines_unaligned(footer_lines, True) # reset the frame. first time do not worry about what you paint on. self._frame = QtGui.QImage(self.bg_frame) - print "generate ", self._frame.size() self._frameOp = QtGui.QImage(self.bg_frame) x, y = self._correctAlignment(self._rect, bbox) bbox = self._render_lines_unaligned(lines, False, (x, y), True) diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index d8621b345..78e99506a 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -175,7 +175,6 @@ class RenderManager(object): footer_rect = QtCore.QRect(theme.font_footer_x, theme.font_footer_y, theme.font_footer_width - 1, theme.font_footer_height - 1) - print "build_text_rectangle", main_rect self.renderer.set_text_rectangle(main_rect, footer_rect) def generate_preview(self, themedata): @@ -229,7 +228,6 @@ class RenderManager(object): """ log.debug(u'generate slide') self.build_text_rectangle(self.themedata) - print "set_frame_dest", self.width, self.height self.renderer.set_frame_dest(self.width, self.height) return self.renderer.generate_frame_from_lines(main_text, footer_text) @@ -248,4 +246,3 @@ class RenderManager(object): self.width, self.height, self.screen_ratio ) # 90% is start of footer self.footer_start = int(self.height * 0.90) - print "calculate_default ", self.width, self.height, self.footer_start diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 505e728da..62457df6f 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -133,15 +133,10 @@ class MainDisplay(DisplayWidget): @param (integer) screen This is the screen number. """ log.debug(u'Setup %s for %s ' %(self.screens, screenNumber)) - print "all the screen ", self.screens self.setVisible(False) self.screen = self.screens.current #Sort out screen locations and sizes - print "--------- Set screen geom ------------" - print "display ", self.screen[u'size'] self.setGeometry(self.screen[u'size']) - print "main geom", self.geometry() - print "display geom 1", self.display.geometry() self.alertScreenPosition = self.screen[u'size'].height() * 0.9 self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition self.alertDisplay.setGeometry( @@ -150,7 +145,6 @@ class MainDisplay(DisplayWidget): self.video.setGeometry(self.screen[u'size']) self.display.resize(self.screen[u'size'].width(), self.screen[u'size'].height()) - print "display geom 2", self.display.geometry() #Build a custom splash screen self.InitialFrame = QtGui.QImage( self.screen[u'size'].width(), @@ -203,31 +197,23 @@ class MainDisplay(DisplayWidget): ``frame`` Image frame to be rendered """ -# if self.timer_id != 0 : -# self.displayAlert() - print "render display start ", self.display.geometry() if not self.displayBlank: if transition: if self.frame is not None: - print "render frame 1 ", self.frame.size() self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame)) self.repaint() self.frame = None if frame[u'trans'] is not None: - print "render frame 2 ", frame[u'trans'].size() self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans'])) self.repaint() self.frame = frame[u'trans'] - print "render frame 3 ", frame[u'main'].size() self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) self.repaint() else: - print "render frame 3 ", frame.size() self.display.setPixmap(QtGui.QPixmap.fromImage(frame)) if not self.isVisible(): self.setVisible(True) self.showFullScreen() - print "render display end ", self.display.geometry() def blankDisplay(self, blanked=True): if blanked: diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index cbd2e0ad7..63744f62c 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -610,7 +610,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.settingsForm.exec_() updated_display = self.getMonitorNumber() if updated_display != self.screens.current_display: - print "main display screen changed to ", updated_display self.screens.set_current_display(updated_display) self.RenderManager.update_display(updated_display) self.mainDisplay.setup(updated_display) diff --git a/openlp/core/ui/screen.py b/openlp/core/ui/screen.py index 0aa06bfc0..809945ed8 100644 --- a/openlp/core/ui/screen.py +++ b/openlp/core/ui/screen.py @@ -44,7 +44,6 @@ class Screen(object): self.current = screen self.screen_list.append(screen) self.count += 1 - print self.screen_list def screen_exists(self, number): for screen in self.screen_list: diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index 4e5460b0a..b2288f75a 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -109,7 +109,6 @@ class ThemeManager(QtGui.QWidget): self.path = os.path.join(ConfigHelper.get_data_path(), u'themes') self.checkThemesExists(self.path) self.thumbPath = os.path.join(self.path, u'.thumbnails') - print self.thumbPath self.checkThemesExists(self.thumbPath) self.amendThemeForm.path = self.path # Last little bits of setting up From 2d7c9dd402c120da6f04fc1d82a0118cd9673794 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Fri, 22 Jan 2010 18:59:36 +0000 Subject: [PATCH 08/20] Fixes from the merge --- openlp.pyw | 4 ++-- openlp/core/lib/__init__.py | 6 +----- openlp/core/ui/__init__.py | 2 +- openlp/core/ui/screen.py | 2 +- 4 files changed, 5 insertions(+), 9 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 2060f09e1..968ee92d2 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -34,7 +34,7 @@ from PyQt4 import QtCore, QtGui from openlp.core.lib import Receiver, str_to_bool from openlp.core.resources import qInitResources -from openlp.core.ui import MainWindow, SplashScreen, Screen +from openlp.core.ui import MainWindow, SplashScreen, ScreenList from openlp.core.utils import ConfigHelper log = logging.getLogger() @@ -117,7 +117,7 @@ class OpenLP(QtGui.QApplication): self.splash.show() # make sure Qt really display the splash screen self.processEvents() - screens = Screen() + screens = ScreenList() # Decide how many screens we have and their size for screen in xrange(0, self.desktop().numScreens()): screens.add_screen({u'number': screen, diff --git a/openlp/core/lib/__init__.py b/openlp/core/lib/__init__.py index 846ff2053..93512f946 100644 --- a/openlp/core/lib/__init__.py +++ b/openlp/core/lib/__init__.py @@ -143,11 +143,7 @@ def resize_image(image, width, height): ``image`` The image to resize. """ - if isinstance(image, QtGui.QImage): - preview = QtGui.QImage(image) - else: - preview = QtGui.QImage(image) - + preview = QtGui.QImage(image) preview = preview.scaled(width, height, QtCore.Qt.KeepAspectRatio, QtCore.Qt.SmoothTransformation) realw = preview.width(); diff --git a/openlp/core/ui/__init__.py b/openlp/core/ui/__init__.py index a2252bc41..42f232638 100644 --- a/openlp/core/ui/__init__.py +++ b/openlp/core/ui/__init__.py @@ -23,7 +23,7 @@ # Temple Place, Suite 330, Boston, MA 02111-1307 USA # ############################################################################### -from screen import Screen +from screen import ScreenList from maindisplay import MainDisplay from amendthemeform import AmendThemeForm from slidecontroller import SlideController diff --git a/openlp/core/ui/screen.py b/openlp/core/ui/screen.py index 809945ed8..2321c3020 100644 --- a/openlp/core/ui/screen.py +++ b/openlp/core/ui/screen.py @@ -24,7 +24,7 @@ ############################################################################### import logging -class Screen(object): +class ScreenList(object): """ Wrapper to handle the parameters of the display screen """ From c35ff6b8d10f87560e0af1cd377ad60752174958 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sat, 23 Jan 2010 09:49:01 +0000 Subject: [PATCH 09/20] Presentation display fixes --- openlp/core/ui/maindisplay.py | 3 ++- openlp/core/ui/slidecontroller.py | 5 +++-- .../plugins/presentations/lib/impresscontroller.py | 14 +++++++------- 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 62457df6f..35828e85f 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -236,7 +236,7 @@ class MainDisplay(DisplayWidget): """ log.debug(u'display alert called %s' % text) self.alertList.append(text) - if self.timer_id != 0: + if self.timer_id != 0 or self.mediaLoaded: return self.generateAlert() @@ -299,6 +299,7 @@ class MainDisplay(DisplayWidget): self.firstTime = True self.mediaLoaded = True self.display.hide() + self.alertDisplay.hide() self.video.setFullScreen(True) self.video.setVisible(True) self.mediaObject.play() diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index da7b98bfc..6e3d6ad1d 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -493,6 +493,7 @@ class SlideController(QtGui.QWidget): """ Blank the screen. """ + print "onbl", blanked if self.serviceItem is not None: if self.serviceItem.is_command(): if blanked: @@ -550,7 +551,7 @@ class SlideController(QtGui.QWidget): def grabMainDisplay(self): rm = self.parent.RenderManager winid = QtGui.QApplication.desktop().winId() - rect = rm.screen_list[rm.current_display][u'size'] + rect = rm.screens.current[u'size'] winimg = QtGui.QPixmap.grabWindow(winid, rect.x(), rect.y(), rect.width(), rect.height()) self.SlidePreview.setPixmap(winimg) @@ -666,7 +667,7 @@ class SlideController(QtGui.QWidget): def onMediaStop(self): if self.isLive: - Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower()) + Receiver.send_message(u'%s_stop'% self.serviceItem.name.lower(), self.isLive) else: self.mediaObject.stop() self.video.hide() diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index 28c6690e3..dc0a3bf82 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -232,13 +232,13 @@ class ImpressController(PresentationController): """ if self.document: if self.presentation: - self.presentation.end() - self.presentation = None - try: - self.document.dispose() - except: - #We tried! - pass + try: + self.presentation.end() + self.presentation = None + self.document.dispose() + except: + #We tried! + pass self.document = None def is_loaded(self): From ad40020169981149f3b76f354f17d9a86c709904 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 24 Jan 2010 13:58:39 +0000 Subject: [PATCH 10/20] Fix logging to single file Fix QMessage to displays on correct screen. --- openlp.pyw | 4 ++-- openlp/core/ui/maindisplay.py | 13 ++++++++----- openlp/core/ui/mainwindow.py | 6 +++--- openlp/core/ui/servicemanager.py | 4 ++-- openlp/core/ui/slidecontroller.py | 2 +- 5 files changed, 16 insertions(+), 13 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 968ee92d2..3b97a33d9 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -28,7 +28,7 @@ import os import sys import logging -from logging.handlers import RotatingFileHandler +from logging import FileHandler from optparse import OptionParser from PyQt4 import QtCore, QtGui @@ -154,7 +154,7 @@ def main(): help="Set the Qt4 style (passed directly to Qt4).") # Set up logging filename = u'openlp.log' - logfile = RotatingFileHandler(filename, maxBytes=200000, backupCount=5) + logfile = FileHandler(filename) logfile.setFormatter(logging.Formatter( u'%(asctime)s %(name)-15s %(levelname)-8s %(message)s')) log.addHandler(logfile) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 35828e85f..7b73ab2ac 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -208,9 +208,11 @@ class MainDisplay(DisplayWidget): self.repaint() self.frame = frame[u'trans'] self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) + self.display_frame = frame[u'main'] self.repaint() else: self.display.setPixmap(QtGui.QPixmap.fromImage(frame)) + self.display_frame = frame if not self.isVisible(): self.setVisible(True) self.showFullScreen() @@ -221,11 +223,11 @@ class MainDisplay(DisplayWidget): self.display.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) else: self.displayBlank = False - if self.frame: - self.frameView(self.frame) - if blanked != self.parent.LiveController.blankButton.isChecked(): - self.parent.LiveController.blankButton.setChecked(self.displayBlank) - self.parent.generalConfig.set_config(u'screen blank', self.displayBlank) + if self.display_frame: + self.frameView(self.display_frame) +# if blanked != self.parent.LiveController.blankButton.isChecked(): +# self.parent.LiveController.blankButton.setChecked(self.displayBlank) +# self.parent.generalConfig.set_config(u'screen blank', self.displayBlank) def displayAlert(self, text=u''): """ @@ -313,6 +315,7 @@ class MainDisplay(DisplayWidget): def onMediaStop(self): log.debug(u'Media stopped by user') self.mediaObject.stop() + self.onMediaFinish() def onMediaFinish(self): log.debug(u'Reached end of media playlist') diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 63744f62c..4090f9895 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -545,7 +545,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): if app_version != version: version_text = unicode(self.trUtf8('OpenLP version %s has been updated ' 'to version %s\n\nYou can obtain the latest version from http://openlp.org')) - QtGui.QMessageBox.question(None, + QtGui.QMessageBox.question(self, self.trUtf8('OpenLP Version Updated'), version_text % (app_version, version), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), @@ -576,7 +576,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.ServiceManagerContents.onLoadService(True) if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \ and str_to_bool(self.generalConfig.get_config(u'blank warning', False)): - QtGui.QMessageBox.question(None, + QtGui.QMessageBox.question(self, self.trUtf8('OpenLP Main Display Blanked'), self.trUtf8('The Main Display has been blanked out'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), @@ -620,7 +620,7 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): Hook to close the main window and display windows on exit """ if self.serviceNotSaved: - ret = QtGui.QMessageBox.question(None, + ret = QtGui.QMessageBox.question(self, self.trUtf8('Save Changes to Service?'), self.trUtf8('Your service has changed, do you want to save those changes?'), QtGui.QMessageBox.StandardButtons( diff --git a/openlp/core/ui/servicemanager.py b/openlp/core/ui/servicemanager.py index 7e9fca933..44170e616 100644 --- a/openlp/core/ui/servicemanager.py +++ b/openlp/core/ui/servicemanager.py @@ -348,7 +348,7 @@ class ServiceManager(QtGui.QWidget): if self.parent.serviceNotSaved and \ str_to_bool(PluginConfig(u'General'). get_config(u'save prompt', u'False')): - ret = QtGui.QMessageBox.question(None, + ret = QtGui.QMessageBox.question(self, self.trUtf8('Save Changes to Service?'), self.trUtf8('Your service is unsaved, do you want to save those ' 'changes before creating a new one ?'), @@ -697,4 +697,4 @@ class ServiceManager(QtGui.QWidget): theme = unicode(self.sender().text()) item, count = self.findServiceItem() self.serviceItems[item][u'service_item'].theme = theme - self.regenerateServiceItems() \ No newline at end of file + self.regenerateServiceItems() diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 6e3d6ad1d..e42dbc7f5 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -493,7 +493,7 @@ class SlideController(QtGui.QWidget): """ Blank the screen. """ - print "onbl", blanked + print "Button Pressed", blanked if self.serviceItem is not None: if self.serviceItem.is_command(): if blanked: From e6e6eeb7c025682d1bfb0d32fba72c068b94bf91 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 24 Jan 2010 15:18:26 +0000 Subject: [PATCH 11/20] Media and Blank screen now play together nicely. --- openlp/core/ui/maindisplay.py | 2 ++ openlp/core/ui/slidecontroller.py | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 7b73ab2ac..a4ff53567 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -298,6 +298,7 @@ class MainDisplay(DisplayWidget): log.debug(u'Play the new media, Live ') if not self.mediaLoaded and not self.displayBlank: self.blankDisplay() + self.display_frame = self.blankFrame self.firstTime = True self.mediaLoaded = True self.display.hide() @@ -326,3 +327,4 @@ class MainDisplay(DisplayWidget): self.mediaLoaded = False self.video.setVisible(False) self.display.show() + self.blankDisplay(False) diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index e42dbc7f5..97bd406d3 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -441,7 +441,6 @@ class SlideController(QtGui.QWidget): self.SongMenu.menu().addAction(self.trUtf8(u'%s'%tag), self.onSongBarHandler) item.setText(frame[u'text']) - #print {u'x':frame[u'text']} else: label = QtGui.QLabel() label.setMargin(4) @@ -493,7 +492,6 @@ class SlideController(QtGui.QWidget): """ Blank the screen. """ - print "Button Pressed", blanked if self.serviceItem is not None: if self.serviceItem.is_command(): if blanked: From d6912adbf8058c801b075a4e59cb812bfb888bdc Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 24 Jan 2010 16:28:18 +0000 Subject: [PATCH 12/20] Make display blanking work correctly --- openlp/core/ui/mainwindow.py | 2 +- openlp/core/ui/slidecontroller.py | 21 ++++++++++++++------- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 4090f9895..8e93fbf12 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -576,12 +576,12 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.ServiceManagerContents.onLoadService(True) if str_to_bool(self.generalConfig.get_config(u'screen blank', False)) \ and str_to_bool(self.generalConfig.get_config(u'blank warning', False)): + self.LiveController.onBlankDisplay(True) QtGui.QMessageBox.question(self, self.trUtf8('OpenLP Main Display Blanked'), self.trUtf8('The Main Display has been blanked out'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok) - self.LiveController.blankButton.setChecked(True) def onHelpAboutItemClicked(self): """ diff --git a/openlp/core/ui/slidecontroller.py b/openlp/core/ui/slidecontroller.py index 97bd406d3..3131c2bfa 100644 --- a/openlp/core/ui/slidecontroller.py +++ b/openlp/core/ui/slidecontroller.py @@ -164,9 +164,9 @@ class SlideController(QtGui.QWidget): self.Toolbar.addToolbarSeparator(u'Close Separator') self.blankButton = self.Toolbar.addToolbarButton( u'Blank Screen', u':/slides/slide_close.png', - self.trUtf8('Blank Screen'), self.onBlankScreen, True) + self.trUtf8('Blank Screen'), self.onBlankDisplay, True) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'live_slide_blank'), self.onBlankDisplay) + QtCore.SIGNAL(u'live_slide_blank'), self.blankScreen) if not self.isLive: self.Toolbar.addToolbarSeparator(u'Close Separator') self.Toolbar.addToolbarButton( @@ -485,12 +485,19 @@ class SlideController(QtGui.QWidget): self.PreviewListWidget.selectRow(0) self.onSlideSelected() - def onBlankDisplay(self): - self.blankButton.setChecked(self.parent.mainDisplay.displayBlank) - - def onBlankScreen(self, blanked): + def onBlankDisplay(self, force=False): """ - Blank the screen. + Handle the blank screen button + """ + if force: + self.blankButton.setChecked(True) + self.blankScreen(self.blankButton.isChecked()) + self.parent.generalConfig.set_config(u'screen blank', + self.blankButton.isChecked()) + + def blankScreen(self, blanked=False): + """ + Blank the display screen. """ if self.serviceItem is not None: if self.serviceItem.is_command(): From dd18a4da769d174c164f34f8d3aa7f765f668be8 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Sun, 24 Jan 2010 16:30:48 +0000 Subject: [PATCH 13/20] Fix spacing of media items --- openlp/plugins/media/lib/mediaitem.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/openlp/plugins/media/lib/mediaitem.py b/openlp/plugins/media/lib/mediaitem.py index d946fb819..c2dbc5d93 100644 --- a/openlp/plugins/media/lib/mediaitem.py +++ b/openlp/plugins/media/lib/mediaitem.py @@ -61,7 +61,7 @@ class MediaMediaItem(MediaManagerItem): def retranslateUi(self): self.OnNewPrompt = self.trUtf8('Select Media') - self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg *.wmv' + self.OnNewFileMasks = self.trUtf8('Videos (*.avi *.mpeg *.mpg *.wmv ' '*.mov *.mp4 *.flv);;Audio (*.ogg *.mp3 *.wma *.wav *.flac)' ';;All files (*)') From 9beb6c7db54674ff2724a472ac9daa862254cda0 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Mon, 25 Jan 2010 20:34:47 +0000 Subject: [PATCH 14/20] Add Image layer and rename text layer --- openlp/core/ui/maindisplay.py | 33 +++++++++++++++++++-------------- 1 file changed, 19 insertions(+), 14 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index a4ff53567..933aa93d7 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -96,8 +96,10 @@ class MainDisplay(DisplayWidget): self.audio = Phonon.AudioOutput(Phonon.VideoCategory, self.mediaObject) Phonon.createPath(self.mediaObject, self.video) Phonon.createPath(self.mediaObject, self.audio) - self.display = QtGui.QLabel(self) - self.display.setScaledContents(True) + self.display_image = QtGui.QLabel(self) + self.display_image.setScaledContents(True) + self.display_text = QtGui.QLabel(self) + self.display_text.setScaledContents(True) self.alertDisplay = QtGui.QLabel(self) self.alertDisplay.setScaledContents(True) self.primary = True @@ -123,7 +125,7 @@ class MainDisplay(DisplayWidget): QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_play'), self.onMediaPlay) QtCore.QObject.connect(Receiver.get_receiver(), - QtCore.SIGNAL(u'media_pause'), self.onMediaPaws) + QtCore.SIGNAL(u'media_pause'), self.onMediaPause) QtCore.QObject.connect(Receiver.get_receiver(), QtCore.SIGNAL(u'media_stop'), self.onMediaStop) @@ -143,7 +145,9 @@ class MainDisplay(DisplayWidget): QtCore.QRect(0, self.alertScreenPosition, self.screen[u'size'].width(),self.alertHeight)) self.video.setGeometry(self.screen[u'size']) - self.display.resize(self.screen[u'size'].width(), + self.display_image.resize(self.screen[u'size'].width(), + self.screen[u'size'].height()) + self.display_text.resize(self.screen[u'size'].width(), self.screen[u'size'].height()) #Build a custom splash screen self.InitialFrame = QtGui.QImage( @@ -200,18 +204,18 @@ class MainDisplay(DisplayWidget): if not self.displayBlank: if transition: if self.frame is not None: - self.display.setPixmap(QtGui.QPixmap.fromImage(self.frame)) + self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.frame)) self.repaint() self.frame = None if frame[u'trans'] is not None: - self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans'])) + self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'trans'])) self.repaint() self.frame = frame[u'trans'] - self.display.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) + self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame[u'main'])) self.display_frame = frame[u'main'] self.repaint() else: - self.display.setPixmap(QtGui.QPixmap.fromImage(frame)) + self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame)) self.display_frame = frame if not self.isVisible(): self.setVisible(True) @@ -220,10 +224,10 @@ class MainDisplay(DisplayWidget): def blankDisplay(self, blanked=True): if blanked: self.displayBlank = True - self.display.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) + self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) else: self.displayBlank = False - if self.display_frame: + if self.display_text_frame: self.frameView(self.display_frame) # if blanked != self.parent.LiveController.blankButton.isChecked(): # self.parent.LiveController.blankButton.setChecked(self.displayBlank) @@ -285,7 +289,7 @@ class MainDisplay(DisplayWidget): def onMediaQueue(self, message): log.debug(u'Queue new media message %s' % message) - self.display.close() + self.display_text.close() file = os.path.join(message[1], message[2]) if self.firstTime: self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) @@ -301,7 +305,8 @@ class MainDisplay(DisplayWidget): self.display_frame = self.blankFrame self.firstTime = True self.mediaLoaded = True - self.display.hide() + self.display_image.hide() + self.display_text.hide() self.alertDisplay.hide() self.video.setFullScreen(True) self.video.setVisible(True) @@ -309,7 +314,7 @@ class MainDisplay(DisplayWidget): if self.primary: self.setVisible(True) - def onMediaPaws(self): + def onMediaPause(self): log.debug(u'Media paused by user') self.mediaObject.pause() @@ -326,5 +331,5 @@ class MainDisplay(DisplayWidget): self.mediaObject.clearQueue() self.mediaLoaded = False self.video.setVisible(False) - self.display.show() + self.display_text.show() self.blankDisplay(False) From 04c68a075eec20c5ac6a755534f30ba4372be3a0 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Tue, 26 Jan 2010 19:16:47 +0000 Subject: [PATCH 15/20] More Image Layer changes --- openlp/core/lib/rendermanager.py | 18 ------------------ openlp/core/ui/maindisplay.py | 22 ++++++++++++++++++---- openlp/plugins/images/lib/mediaitem.py | 5 ++--- 3 files changed, 20 insertions(+), 25 deletions(-) diff --git a/openlp/core/lib/rendermanager.py b/openlp/core/lib/rendermanager.py index 78e99506a..600a029c0 100644 --- a/openlp/core/lib/rendermanager.py +++ b/openlp/core/lib/rendermanager.py @@ -64,8 +64,6 @@ class RenderManager(object): self.theme_level = u'' self.override_background = None self.themedata = None - self.save_bg_frame = None - self.override_background_changed = False def update_display(self, screen_number): """ @@ -134,22 +132,6 @@ class RenderManager(object): self.calculate_default(self.screens.current[u'size']) self.renderer.set_theme(self.themedata) self.build_text_rectangle(self.themedata) - #Replace the background image from renderer with one from image - if self.override_background: - if self.save_bg_frame is None: - self.save_bg_frame = self.renderer.bg_frame - if self.override_background_changed: - self.renderer.bg_frame = resize_image( - self.override_background, self.width, self.height) - self.override_background_changed = False - else: - if self.override_background_changed: - self.renderer.bg_frame = resize_image( - self.override_background, self.width, self.height) - self.override_background_changed = False - if self.save_bg_frame: - self.renderer.bg_frame = self.save_bg_frame - self.save_bg_frame = None def build_text_rectangle(self, theme): """ diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 933aa93d7..62d5b2f21 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -30,7 +30,7 @@ import time from PyQt4 import QtCore, QtGui from PyQt4.phonon import Phonon -from openlp.core.lib import Receiver +from openlp.core.lib import Receiver, resize_image class DisplayWidget(QtGui.QWidget): """ @@ -162,7 +162,7 @@ class MainDisplay(DisplayWidget): (self.screen[u'size'].width() - splash_image.width()) / 2, (self.screen[u'size'].height() - splash_image.height()) / 2, splash_image) - self.frameView(self.InitialFrame) + self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.InitialFrame)) #Build a Black screen painter = QtGui.QPainter() self.blankFrame = QtGui.QImage( @@ -171,10 +171,11 @@ class MainDisplay(DisplayWidget): QtGui.QImage.Format_ARGB32_Premultiplied) painter.begin(self.blankFrame) painter.fillRect(self.blankFrame.rect(), QtCore.Qt.red) - #buid a blank transparent image + #build a blank transparent image self.transparent = QtGui.QPixmap(self.screen[u'size'].width(), self.screen[u'size'].height()) self.transparent.fill(QtCore.Qt.transparent) + self.frameView(self.transparent) # To display or not to display? if not self.screen[u'primary']: self.showFullScreen() @@ -194,6 +195,16 @@ class MainDisplay(DisplayWidget): if not self.primary: self.setVisible(True) + def addImageWithText(self, frame): + frame = resize_image(frame, + self.screen[u'size'].width(), + self.screen[u'size'].height() ) + self.display_image.setPixmap(QtGui.QPixmap.fromImage(frame)) +# self.display_image.show() +# if not self.isVisible(): +# self.setVisible(True) +# self.showFullScreen() + def frameView(self, frame, transition=False): """ Called from a slide controller to display a frame @@ -215,7 +226,10 @@ class MainDisplay(DisplayWidget): self.display_frame = frame[u'main'] self.repaint() else: - self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame)) + if isinstance(frame, QtGui.QPixmap): + self.display_text.setPixmap(frame) + else: + self.display_text.setPixmap(QtGui.QPixmap.fromImage(frame)) self.display_frame = frame if not self.isVisible(): self.setVisible(True) diff --git a/openlp/plugins/images/lib/mediaitem.py b/openlp/plugins/images/lib/mediaitem.py index 9ee3a0c6f..8ea1df64b 100644 --- a/openlp/plugins/images/lib/mediaitem.py +++ b/openlp/plugins/images/lib/mediaitem.py @@ -172,7 +172,6 @@ class ImageMediaItem(MediaManagerItem): filename = unicode((bitem.data(QtCore.Qt.UserRole)).toString()) self.OverrideLabel.setText(bitem.text()) frame = QtGui.QImage(unicode(filename)) - self.parent.render_manager.override_background = frame - self.parent.render_manager.override_background_changed = True + self.parent.live_controller.parent.mainDisplay.addImageWithText(frame) else: - MediaManagerItem.onPreviewClick(self) \ No newline at end of file + MediaManagerItem.onPreviewClick(self) From 262ff559534b82ffff463142ddde6f3b22b35d4a Mon Sep 17 00:00:00 2001 From: Raoul Snyman Date: Wed, 27 Jan 2010 14:35:42 +0200 Subject: [PATCH 16/20] Added bible conversion script. --- scripts/bible-1to2-converter.py | 306 ++++++++++++++++++++++++++++++++ 1 file changed, 306 insertions(+) create mode 100755 scripts/bible-1to2-converter.py diff --git a/scripts/bible-1to2-converter.py b/scripts/bible-1to2-converter.py new file mode 100755 index 000000000..226c1ec2e --- /dev/null +++ b/scripts/bible-1to2-converter.py @@ -0,0 +1,306 @@ +#!/usr/bin/env python +# -*- coding: utf-8 -*- +# vim: autoindent shiftwidth=4 expandtab textwidth=80 tabstop=4 softtabstop=4 + +############################################################################### +# OpenLP - Open Source Lyrics Projection # +# --------------------------------------------------------------------------- # +# Copyright (c) 2008-2010 Raoul Snyman # +# Portions copyright (c) 2008-2010 Tim Bentley, Jonathan Corwin, Michael # +# Gorven, Scott Guerrieri, Maikel Stuivenberg, Martin Thompson, Jon Tibble, # +# Carsten Tinggaard # +# --------------------------------------------------------------------------- # +# This program is free software; you can redistribute it and/or modify it # +# under the terms of the GNU General Public License as published by the Free # +# Software Foundation; version 2 of the License. # +# # +# This program is distributed in the hope that it will be useful, but WITHOUT # +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for # +# more details. # +# # +# You should have received a copy of the GNU General Public License along # +# with this program; if not, write to the Free Software Foundation, Inc., 59 # +# Temple Place, Suite 330, Boston, MA 02111-1307 USA # +############################################################################### + +import sys +import os +import sqlite +import sqlite3 +import re +from optparse import OptionParser +from traceback import format_tb as get_traceback + +# Some global options to be used throughout the import process +verbose = False +debug = False +old_cursor = None +new_cursor = None + +# SQL create statments +create_statements = [ + (u'table "book"', u"""CREATE TABLE book ( + id INTEGER NOT NULL, + testament_id INTEGER, + name VARCHAR(30), + abbreviation VARCHAR(5), + PRIMARY KEY (id), + FOREIGN KEY(testament_id) REFERENCES testament (id) +)"""), + (u'table "metadata"', u"""CREATE TABLE metadata ( + "key" VARCHAR(255) NOT NULL, + value VARCHAR(255), + PRIMARY KEY ("key") +)"""), + (u'table "testament"', u"""CREATE TABLE testament ( + id INTEGER NOT NULL, + name VARCHAR(30), + PRIMARY KEY (id) +)"""), + (u'table "verse"', u"""CREATE TABLE verse ( + id INTEGER NOT NULL, + book_id INTEGER, + chapter INTEGER, + verse INTEGER, + text TEXT, + PRIMARY KEY (id), + FOREIGN KEY(book_id) REFERENCES book (id) +)"""), + (u'index "idx_abbrev"', + u"""CREATE INDEX idx_abbrev ON book (abbreviation, id)"""), + (u'index "idx_chapter_verse_book', + u"""CREATE INDEX idx_chapter_verse_book ON verse (chapter, verse, book_id, id)"""), + (u'index "idx_chapter_verse_text"', + u"""CREATE INDEX idx_chapter_verse_text ON verse (text, verse, book_id, id)"""), + (u'index "idx_name"', + u"""CREATE INDEX idx_name ON book (name, id)""") +] + +def display_sql(sql, params): + prepared_params = [] + for param in params: + if isinstance(param, basestring): + prepared_params.append(u'"%s"' % param) + elif isinstance(param, (int, long)): + prepared_params.append(u'%d' % param) + elif isinstance(param, (float, complex)): + prepared_params.append(u'%f' % param) + else: + prepared_params.append(u'"%s"' % str(param)) + for prepared_param in prepared_params: + sql = sql.replace(u'?', prepared_param, 1) + return sql + +def create_database(): + global new_cursor, create_statements + if debug or verbose: + print 'Creating new database:' + else: + print 'Creating new database...', + for statement_type, sql_create in create_statements: + if debug: + print '... ', sql_create.replace('\n', ' ').replace(' ', ' ') + elif verbose: + print '... creating %s...' % statement_type, + new_cursor.execute(sql_create) + if verbose and not debug: + print 'done.' + if not verbose and not debug: + print 'done.' + +def import_bible(): + global old_cursor, new_cursor, debug, verbose + if debug or verbose: + print 'Importing metadata:' + else: + print 'Importing metadata...', + if debug: + print '... SELECT "key", "value" FROM metadata' + elif verbose: + print '... fetching metadata from old database...', + old_cursor.execute(u'SELECT "key", "value" FROM metadata') + rows = old_cursor.fetchall() + if not debug and verbose: + print 'done.' + for row in rows: + key = unicode(row[0], u'cp1252') + value = unicode(row[1], u'cp1252') + sql_insert = u'INSERT INTO metadata '\ + '("key", "value") '\ + 'VALUES (?, ?)' + sql_params = (key, value) + if debug: + print '...', display_sql(sql_insert, sql_params) + elif verbose: + print '... importing "%s"' % key + new_cursor.execute(sql_insert, sql_params) + if not verbose and not debug: + print 'done.' + if debug or verbose: + print 'Importing testaments:' + else: + print 'Importing testaments...', + if debug: + print '... SELECT id, name FROM testament' + elif verbose: + print '... fetching testaments from old database...', + old_cursor.execute(u'SELECT id, name FROM testament') + rows = old_cursor.fetchall() + if not debug and verbose: + print 'done.' + for row in rows: + id = int(row[0]) + name = unicode(row[1], u'cp1252') + sql_insert = u'INSERT INTO testament '\ + '(id, name) '\ + 'VALUES (?, ?)' + sql_params = (id, name) + if debug: + print '...', display_sql(sql_insert, sql_params) + elif verbose: + print '... importing "%s"' % name + new_cursor.execute(sql_insert, sql_params) + if not verbose and not debug: + print 'done.' + if debug or verbose: + print 'Importing books:' + else: + print 'Importing books...', + if debug: + print '... SELECT id, testament_id, name, abbreviation FROM book' + elif verbose: + print '... fetching books from old database...', + old_cursor.execute(u'SELECT id, testament_id, name, abbreviation FROM book') + rows = old_cursor.fetchall() + if not debug and verbose: + print 'done.' + book_map = {} + for row in rows: + testament_id = int(row[1]) + name = unicode(row[2], u'cp1252') + abbreviation = unicode(row[3], u'cp1252') + sql_insert = u'INSERT INTO book '\ + '(id, testament_id, name, abbreviation) '\ + 'VALUES (NULL, ?, ?, ?)' + sql_params = (testament_id, name, abbreviation) + if debug: + print '...', display_sql(sql_insert, sql_params) + elif verbose: + print '... importing "%s"' % name + new_cursor.execute(sql_insert, sql_params) + book_map[row[0]] = new_cursor.lastrowid + if debug: + print ' >>> (old) books.id =', row[0], ' (new) books.id =', book_map[row[0]] + if not verbose and not debug: + print 'done.' + if debug or verbose: + print 'Importing verses:' + else: + print 'Importing verses...', + if debug: + print '... SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse...', + elif verbose: + print '... fetching verses from old database...', + old_cursor.execute(u'SELECT id, book_id, chapter, verse, text || \'\' AS text FROM verse') + rows = old_cursor.fetchall() + if debug or verbose: + print 'done.' + song_map = {} + for row in rows: + book_id = int(row[1]) + chapter = int(row[2]) + verse = int(row[3]) + text = unicode(row[4], u'cp1252') + sql_insert = u'INSERT INTO verse '\ + '(id, book_id, chapter, verse, text) '\ + 'VALUES (NULL, ?, ?, ?, ?)' + sql_params = (book_map[book_id], chapter, verse, text) + if debug: + print '...', display_sql(sql_insert, sql_params) + elif verbose: + print '... importing "%s..."' % text[:17] + new_cursor.execute(sql_insert, sql_params) + if not verbose and not debug: + print 'done.' + +def main(old_db, new_db): + global old_cursor, new_cursor, debug + old_connection = None + new_connection = None + try: + old_connection = sqlite.connect(old_db) + except: + if debug: + errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\ + + str(sys.exc_info()[1]) + else: + errormsg = sys.exc_info()[1] + print 'There was a problem connecting to the old database:', errormsg + return 1 + try: + new_connection = sqlite3.connect(new_db) + except: + if debug: + errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\ + + str(sys.exc_info()[1]) + else: + errormsg = sys.exc_info()[1] + print 'There was a problem creating the new database:', errormsg + return 1 + old_cursor = old_connection.cursor() + new_cursor = new_connection.cursor() + try: + create_database() + except: + if debug: + errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\ + + str(sys.exc_info()[1]) + else: + errormsg = sys.exc_info()[1] + print 'There was a problem creating the database:', errormsg + return 1 + try: + import_bible() + new_connection.commit() + except: + new_connection.rollback() + if debug: + errormsg = '\n' + ''.join(get_traceback(sys.exc_info()[2]))\ + + str(sys.exc_info()[1]) + else: + errormsg = sys.exc_info()[1] + print 'There was a problem importing songs:', errormsg + return 1 + print 'Import complete.' + +if __name__ == u'__main__': + option_parser = OptionParser(usage='Usage: %prog [options] OLDDATABASE NEWDATABASE') + option_parser.add_option('-o', '--overwrite', dest='overwrite', default=False, + action=u'store_true', help='Overwrite database file if it already exists.') + option_parser.add_option('-v', '--verbose', dest='verbose', default=False, + action=u'store_true', help='Outputs additional progress data.') + option_parser.add_option('-d', '--debug', dest='debug', default=False, + action=u'store_true', help='Outputs raw SQL statements (overrides verbose).') + options, arguments = option_parser.parse_args() + if len(arguments) < 2: + if len(arguments) == 0: + option_parser.error('Please specify an old database and a new database.') + else: + option_parser.error('Please specify a new database.') + old_db = os.path.abspath(arguments[0]) + new_db = os.path.abspath(arguments[1]) + if not os.path.isfile(old_db): + option_parser.error('Old database file ("%s") is not a file.' % old_db) + if not os.path.exists(old_db): + option_parser.error('Old database file ("%s") does not exist.' % old_db) + if os.path.exists(new_db): + if not options.overwrite: + option_parser.error('New database file ("%s") exists. If you want to overwrite it, specify the --overwrite option.' % new_db) + else: + if not os.path.isfile(new_db): + option_parser.error('New database file ("%s") is not a file.' % new_db) + os.unlink(new_db) + verbose = options.verbose + debug = options.debug + main(old_db, new_db) From af5bfe30661de83e9bd915d558c6a35ae334043d Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 28 Jan 2010 07:15:23 +0000 Subject: [PATCH 17/20] Clean up SongUsage so it now works again --- openlp/core/ui/maindisplay.py | 5 +- openlp/core/ui/thememanager.py | 53 ++++++++++--------- .../songusage/forms/songusagedeleteform.py | 8 +-- .../songusage/forms/songusagedetailform.py | 19 ++++--- openlp/plugins/songusage/songusageplugin.py | 4 +- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 62d5b2f21..83e245322 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -241,11 +241,8 @@ class MainDisplay(DisplayWidget): self.display_text.setPixmap(QtGui.QPixmap.fromImage(self.blankFrame)) else: self.displayBlank = False - if self.display_text_frame: + if self.display_frame: self.frameView(self.display_frame) -# if blanked != self.parent.LiveController.blankButton.isChecked(): -# self.parent.LiveController.blankButton.setChecked(self.displayBlank) -# self.parent.generalConfig.set_config(u'screen blank', self.displayBlank) def displayAlert(self, text=u''): """ diff --git a/openlp/core/ui/thememanager.py b/openlp/core/ui/thememanager.py index b2288f75a..0bf005891 100644 --- a/openlp/core/ui/thememanager.py +++ b/openlp/core/ui/thememanager.py @@ -249,32 +249,33 @@ class ThemeManager(QtGui.QWidget): log.debug(u'Load themes from dir') self.themelist = [] self.ThemeListWidget.clear() - for root, dirs, files in os.walk(self.path): - for name in files: - if name.endswith(u'.png'): - #check to see file is in theme root directory - theme = os.path.join(self.path, name) - if os.path.exists(theme): - (path, filename) = os.path.split(unicode(file)) - textName = os.path.splitext(name)[0] - if textName == self.global_theme: - name = u'%s (%s)' % (textName, - self.trUtf8('default')) - else: - name = textName - thumb = os.path.join(self.thumbPath, u'%s.png' % textName) - item_name = QtGui.QListWidgetItem(name) - if os.path.exists(thumb): - icon = build_icon(thumb) - else: - icon = build_icon(theme) - pixmap = icon.pixmap(QtCore.QSize(88,50)) - pixmap.save(thumb, u'png') - item_name.setIcon(icon) - item_name.setData(QtCore.Qt.UserRole, - QtCore.QVariant(textName)) - self.ThemeListWidget.addItem(item_name) - self.themelist.append(textName) + #root, dirs, files = os.walk(self.path) + dirList = os.listdir(self.path) + for name in dirList: + if name.endswith(u'.png'): + #check to see file is in theme root directory + theme = os.path.join(self.path, name) + if os.path.exists(theme): + (path, filename) = os.path.split(unicode(file)) + textName = os.path.splitext(name)[0] + if textName == self.global_theme: + name = u'%s (%s)' % (textName, + self.trUtf8('default')) + else: + name = textName + thumb = os.path.join(self.thumbPath, u'%s.png' % textName) + item_name = QtGui.QListWidgetItem(name) + if os.path.exists(thumb): + icon = build_icon(thumb) + else: + icon = build_icon(theme) + pixmap = icon.pixmap(QtCore.QSize(88,50)) + pixmap.save(thumb, u'png') + item_name.setIcon(icon) + item_name.setData(QtCore.Qt.UserRole, + QtCore.QVariant(textName)) + self.ThemeListWidget.addItem(item_name) + self.themelist.append(textName) self.pushThemes() def pushThemes(self): diff --git a/openlp/plugins/songusage/forms/songusagedeleteform.py b/openlp/plugins/songusage/forms/songusagedeleteform.py index b20f13c6b..98faf26ad 100644 --- a/openlp/plugins/songusage/forms/songusagedeleteform.py +++ b/openlp/plugins/songusage/forms/songusagedeleteform.py @@ -33,11 +33,11 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): """ Class documentation goes here. """ - def __init__(self, auditmanager, parent=None): + def __init__(self, songusagemanager, parent=None): """ Constructor """ - self.auditmanager = auditmanager + self.songusagemanager = songusagemanager QtGui.QDialog.__init__(self, parent) self.setupUi(self) @@ -52,5 +52,5 @@ class SongUsageDeleteForm(QtGui.QDialog, Ui_SongUsageDeleteDialog): if ret == QtGui.QMessageBox.Ok: qDeleteDate = self.DeleteCalendar.selectedDate() deleteDate = date(qDeleteDate.year(), qDeleteDate.month(), qDeleteDate.day()) - self.auditmanager.delete_to_date(deleteDate) - self.close() \ No newline at end of file + self.songusagemanager.delete_to_date(deleteDate) + self.close() diff --git a/openlp/plugins/songusage/forms/songusagedetailform.py b/openlp/plugins/songusage/forms/songusagedetailform.py index 93b6d2e98..ead6b5166 100644 --- a/openlp/plugins/songusage/forms/songusagedetailform.py +++ b/openlp/plugins/songusage/forms/songusagedetailform.py @@ -25,10 +25,14 @@ import os from PyQt4 import QtCore, QtGui +import logging from songusagedetaildialog import Ui_SongUsageDetailDialog class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): + global log + log = logging.getLogger(u'SongUsageDetailForm') + log.info(u'SongUsage Detail Form loaded') """ Class documentation goes here. """ @@ -106,19 +110,19 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): self.close() def detailedReport(self): - print "detailed" - filename = u'audit_det_%s_%s.txt' % \ + log.debug(u'Detailed report generated') + filename = u'usage_detail_%s_%s.txt' % \ (self.FromDateEdit.date().toString(u'ddMMyyyy'), self.ToDateEdit.date().toString(u'ddMMyyyy')) - audits = self.parent.auditmanager.get_all_audits() + usage = self.parent.songusagemanager.get_all_songusage() outname = os.path.join(unicode(self.FileLineEdit.text()), filename) file = None try: file = open(outname, u'w') - for audit in audits: + for instance in usage: record = u'\"%s\",\"%s\",\"%s\",\"%s\",\"%s\",\"%s\"\n' % \ - (audit.auditdate,audit.audittime, audit.title, - audit.copyright, audit.ccl_number , audit.authors) + (instance.usagedate,instance.usagetime, instance.title, + instance.copyright, instance.ccl_number , instance.authors) file.write(record) except: log.exception(u'Failed to write out audit records') @@ -127,8 +131,7 @@ class SongUsageDetailForm(QtGui.QDialog, Ui_SongUsageDetailDialog): file.close() def summaryReport(self): - print "summary" + log.debug(u'Summary report generated') filename = u'audit_sum_%s_%s.txt' % \ (self.FromDateEdit.date().toString(u'ddMMyyyy'), self.ToDateEdit.date().toString(u'ddMMyyyy')) - print filename \ No newline at end of file diff --git a/openlp/plugins/songusage/songusageplugin.py b/openlp/plugins/songusage/songusageplugin.py index effc06657..802f73d3d 100644 --- a/openlp/plugins/songusage/songusageplugin.py +++ b/openlp/plugins/songusage/songusageplugin.py @@ -141,7 +141,7 @@ class SongUsagePlugin(Plugin): SongUsageitem.authors = u'' for author in SongUsageData[1]: SongUsageitem.authors += author + u' ' - self.songusagemanager.insert_SongUsage(SongUsageitem) + self.songusagemanager.insert_songusage(SongUsageitem) def onSongUsageDelete(self): self.SongUsagedeleteform.exec_() @@ -154,4 +154,4 @@ class SongUsagePlugin(Plugin): about_text = self.trUtf8('SongUsage Plugin
This plugin ' 'records the use of songs and when they have been used during ' 'a live service') - return about_text \ No newline at end of file + return about_text From 3baf2f2f7baed56c890aae19b96b4ac7e4250aae Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 28 Jan 2010 07:39:34 +0000 Subject: [PATCH 18/20] Import the startup showing the update screen --- openlp.pyw | 2 +- openlp/core/ui/mainwindow.py | 3 ++- version.txt | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 3b97a33d9..f1a710f59 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -131,7 +131,7 @@ class OpenLP(QtGui.QApplication): if show_splash: # now kill the splashscreen self.splash.finish(self.mainWindow) - self.mainWindow.versionCheck() + #self.mainWindow.versionCheck() return self.exec_() def main(): diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index 8e93fbf12..b41b6f1b4 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -50,7 +50,6 @@ media_manager_style = """ border-color: palette(light); } """ - class Ui_MainWindow(object): def setupUi(self, MainWindow): """ @@ -582,6 +581,8 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.trUtf8('The Main Display has been blanked out'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok) + self.repaint() + self.versionCheck() def onHelpAboutItemClicked(self): """ diff --git a/version.txt b/version.txt index a41b1ed7a..fcd5e288e 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.9.0-697 +1.9.0-696 From dc7148b76ed587002eaef391eef3abc43a85f2e7 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 28 Jan 2010 11:46:25 +0000 Subject: [PATCH 19/20] Fix screen display setup when returning from presentations --- openlp.pyw | 3 ++- openlp/core/ui/maindisplay.py | 8 ++++++++ openlp/core/ui/mainwindow.py | 2 -- version.txt | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index f1a710f59..03496e70a 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -131,7 +131,8 @@ class OpenLP(QtGui.QApplication): if show_splash: # now kill the splashscreen self.splash.finish(self.mainWindow) - #self.mainWindow.versionCheck() + self.mainWindow.repaint() + self.mainWindow.versionCheck() return self.exec_() def main(): diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 83e245322..7728fc4c4 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -183,10 +183,13 @@ class MainDisplay(DisplayWidget): else: self.setVisible(False) self.primary = True + self.repaint() def resetDisplay(self): if self.primary: self.setVisible(False) + else: + self.showFullScreen() def hideDisplay(self): self.setVisible(False) @@ -194,6 +197,7 @@ class MainDisplay(DisplayWidget): def showDisplay(self): if not self.primary: self.setVisible(True) + self.showFullScreen() def addImageWithText(self, frame): frame = resize_image(frame, @@ -252,8 +256,11 @@ class MainDisplay(DisplayWidget): display text """ log.debug(u'display alert called %s' % text) + self.parent.StatusBar.showMessage(self.trUtf8(u'')) self.alertList.append(text) if self.timer_id != 0 or self.mediaLoaded: + self.parent.StatusBar.showMessage(\ + self.trUtf8(u'Alert message created and delayed')) return self.generateAlert() @@ -343,4 +350,5 @@ class MainDisplay(DisplayWidget): self.mediaLoaded = False self.video.setVisible(False) self.display_text.show() + self.display_image.show() self.blankDisplay(False) diff --git a/openlp/core/ui/mainwindow.py b/openlp/core/ui/mainwindow.py index b41b6f1b4..226c629e8 100644 --- a/openlp/core/ui/mainwindow.py +++ b/openlp/core/ui/mainwindow.py @@ -581,8 +581,6 @@ class MainWindow(QtGui.QMainWindow, Ui_MainWindow): self.trUtf8('The Main Display has been blanked out'), QtGui.QMessageBox.StandardButtons(QtGui.QMessageBox.Ok), QtGui.QMessageBox.Ok) - self.repaint() - self.versionCheck() def onHelpAboutItemClicked(self): """ diff --git a/version.txt b/version.txt index fcd5e288e..a41b1ed7a 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.9.0-696 +1.9.0-697 From dc6be31d1f1c5ed3bdc84dd1246e8708329ee330 Mon Sep 17 00:00:00 2001 From: Tim Bentley Date: Thu, 28 Jan 2010 17:36:13 +0000 Subject: [PATCH 20/20] Move changes to get displays working correctly and sort out Impress --- openlp.pyw | 4 +++ openlp/core/ui/maindisplay.py | 27 ++++++++++--------- .../presentations/lib/impresscontroller.py | 2 +- 3 files changed, 20 insertions(+), 13 deletions(-) diff --git a/openlp.pyw b/openlp.pyw index 03496e70a..58925fdb9 100755 --- a/openlp.pyw +++ b/openlp.pyw @@ -68,6 +68,10 @@ class OpenLP(QtGui.QApplication): global log log.info(u'OpenLP Application Loaded') + def notify(self, obj, evt): + #TODO needed for presentation exceptions + return QtGui.QApplication.notify(self, obj, evt) + def run(self): """ Run the OpenLP application. diff --git a/openlp/core/ui/maindisplay.py b/openlp/core/ui/maindisplay.py index 7728fc4c4..cda5774d6 100644 --- a/openlp/core/ui/maindisplay.py +++ b/openlp/core/ui/maindisplay.py @@ -100,8 +100,8 @@ class MainDisplay(DisplayWidget): self.display_image.setScaledContents(True) self.display_text = QtGui.QLabel(self) self.display_text.setScaledContents(True) - self.alertDisplay = QtGui.QLabel(self) - self.alertDisplay.setScaledContents(True) + self.display_alert = QtGui.QLabel(self) + self.display_alert.setScaledContents(True) self.primary = True self.displayBlank = False self.blankFrame = None @@ -141,7 +141,7 @@ class MainDisplay(DisplayWidget): self.setGeometry(self.screen[u'size']) self.alertScreenPosition = self.screen[u'size'].height() * 0.9 self.alertHeight = self.screen[u'size'].height() - self.alertScreenPosition - self.alertDisplay.setGeometry( + self.display_alert.setGeometry( QtCore.QRect(0, self.alertScreenPosition, self.screen[u'size'].width(),self.alertHeight)) self.video.setGeometry(self.screen[u'size']) @@ -163,6 +163,7 @@ class MainDisplay(DisplayWidget): (self.screen[u'size'].height() - splash_image.height()) / 2, splash_image) self.display_image.setPixmap(QtGui.QPixmap.fromImage(self.InitialFrame)) + self.repaint() #Build a Black screen painter = QtGui.QPainter() self.blankFrame = QtGui.QImage( @@ -170,11 +171,13 @@ class MainDisplay(DisplayWidget): self.screen[u'size'].height(), QtGui.QImage.Format_ARGB32_Premultiplied) painter.begin(self.blankFrame) + #TODO make black when testing finished painter.fillRect(self.blankFrame.rect(), QtCore.Qt.red) #build a blank transparent image self.transparent = QtGui.QPixmap(self.screen[u'size'].width(), self.screen[u'size'].height()) self.transparent.fill(QtCore.Qt.transparent) + self.display_alert.setPixmap(self.transparent) self.frameView(self.transparent) # To display or not to display? if not self.screen[u'primary']: @@ -183,7 +186,6 @@ class MainDisplay(DisplayWidget): else: self.setVisible(False) self.primary = True - self.repaint() def resetDisplay(self): if self.primary: @@ -248,6 +250,7 @@ class MainDisplay(DisplayWidget): if self.display_frame: self.frameView(self.display_frame) + def displayAlert(self, text=u''): """ Called from the Alert Tab to display an alert @@ -292,22 +295,24 @@ class MainDisplay(DisplayWidget): painter.drawText( x, y + metrics.height() - metrics.descent() - 1, text) painter.end() - self.alertDisplay.setPixmap(alertframe) - self.alertDisplay.setVisible(True) + self.display_alert.setPixmap(alertframe) + self.display_alert.setVisible(True) # check to see if we have a timer running if self.timer_id == 0: self.timer_id = self.startTimer(int(alertTab.timeout) * 1000) def timerEvent(self, event): if event.timerId() == self.timer_id: - self.alertDisplay.setPixmap(self.transparent) + self.display_alert.setPixmap(self.transparent) self.killTimer(self.timer_id) self.timer_id = 0 self.generateAlert() def onMediaQueue(self, message): log.debug(u'Queue new media message %s' % message) + self.display_image.close() self.display_text.close() + self.display_alert.close() file = os.path.join(message[1], message[2]) if self.firstTime: self.mediaObject.setCurrentSource(Phonon.MediaSource(file)) @@ -325,12 +330,12 @@ class MainDisplay(DisplayWidget): self.mediaLoaded = True self.display_image.hide() self.display_text.hide() - self.alertDisplay.hide() + self.display_alert.hide() self.video.setFullScreen(True) self.video.setVisible(True) self.mediaObject.play() - if self.primary: - self.setVisible(True) + self.setVisible(True) + self.hide() def onMediaPause(self): log.debug(u'Media paused by user') @@ -343,8 +348,6 @@ class MainDisplay(DisplayWidget): def onMediaFinish(self): log.debug(u'Reached end of media playlist') - if self.primary: - self.setVisible(False) self.mediaObject.stop() self.mediaObject.clearQueue() self.mediaLoaded = False diff --git a/openlp/plugins/presentations/lib/impresscontroller.py b/openlp/plugins/presentations/lib/impresscontroller.py index dc0a3bf82..d2a31e202 100644 --- a/openlp/plugins/presentations/lib/impresscontroller.py +++ b/openlp/plugins/presentations/lib/impresscontroller.py @@ -256,7 +256,7 @@ class ImpressController(PresentationController): return False if self.controller is None: return False - return self.controller.isRunning() and self.controller.isActive() + return True def unblank_screen(self): return self.controller.resume()