diff --git a/install.sh b/install.sh index 0f84dc8..61525ec 100755 --- a/install.sh +++ b/install.sh @@ -131,12 +131,18 @@ then fi fi -echo "Select installation type:" +echo "Select installation type: (default: [1] Complete installation)" echo "[1] Complete installation (manager, webinterface, worker)" echo "[2] Management installation (manager, webinterface)" echo "[3] Worker installation (worker only)" +echo "Note: When there is a default option available pressing enter will select it automatically." read INSTALL_TYPE +if [ -z "$INSTALL_TYPE" ] +then + INSTALL_TYPE="1" + echo "Performing complete installation" +fi check_requirements $INSTALL_TYPE @@ -228,10 +234,16 @@ then echo "Setting password to default value" fi - echo "Should we take care of rabbitmq.config file? [yes/no]" + echo "Should we take care of rabbitmq.config file? [yes/no] (default: yes)" echo "Select no if you already have an existing rabbitmq setup." read CREATE_RMQ_CONFIG + if [ -z "$CREATE_RMQ_CONFIG" ] + then + CREATE_RMQ_CONFIG="yes" + echo "Creating default rabbitmq configuration file" + fi + if [ "$CREATE_RMQ_CONFIG" = "yes" ] || [ "$CREATE_RMQ_CONFIG" = "y" ]; then if [ ! -d /etc/rabbitmq ]; @@ -295,7 +307,7 @@ then cp scripts/renew_cert.sh $SECPI_PATH # generate ca cert - openssl req -config $CERT_PATH/ca/openssl.cnf -x509 -newkey rsa:2048 -days 365 -out $CERT_PATH/ca/cacert.pem -keyout $CERT_PATH/ca/private/cakey.pem -outform PEM -subj /CN=$CA_DOMAIN/ -nodes + openssl req -config $CERT_PATH/ca/openssl.cnf -x509 -newkey rsa:2048 -days 3650 -out $CERT_PATH/ca/cacert.pem -keyout $CERT_PATH/ca/private/cakey.pem -outform PEM -subj /CN=$CA_DOMAIN/ -nodes # secure ca key chmod 600 $CERT_PATH/ca/private diff --git a/manager/dropbox_dropper.py b/manager/dropbox_dropper.py index e2b55ef..278c9bb 100644 --- a/manager/dropbox_dropper.py +++ b/manager/dropbox_dropper.py @@ -36,8 +36,9 @@ def notify(self, info): #self.dbx.files_create_folder(dropbox_dir) # shouldn't be necessary, automatically created for file in os.listdir(latest_subdir): if os.path.isfile("%s/%s" % (latest_subdir, file)): - f = open("%s/%s" % (latest_subdir, file), "rb") - data = f.read() + with open("%s/%s" % (latest_subdir, file), "rb") as f: + data = f.read() + try: logging.info("Dropbox: Trying to upload file %s to %s" % (file, dropbox_dir)) res = self.dbx.files_upload(data, "%s/%s" % (dropbox_dir, file)) @@ -46,7 +47,6 @@ def notify(self, info): logging.error("Dropbox: API error: %s" % d) except Exception as e: # currently this catches wrong authorization, we should change this logging.error("Dropbox: Wasn't able to upload file: %s" % e) - f.close() else: logging.error("Dropbox: Wasn't able to notify because there was an initialization error") diff --git a/manager/mailer.py b/manager/mailer.py index 4a13510..32ea287 100644 --- a/manager/mailer.py +++ b/manager/mailer.py @@ -1,11 +1,15 @@ -import logging import os +import logging import smtplib - -from email.mime.application import MIMEApplication +import mimetypes from email.mime.multipart import MIMEMultipart +from email.mime.nonmultipart import MIMENonMultipart +from email.mime.application import MIMEApplication from email.mime.text import MIMEText +from email.mime.image import MIMEImage +from email.mime.audio import MIMEAudio from tools.notifier import Notifier +from tools.utils import str_to_value class Mailer(Notifier): @@ -20,6 +24,7 @@ def __init__(self, id, params): self.smtp_user = params["smtp_user"] self.smtp_pass = params["smtp_pass"] self.smtp_security = params["smtp_security"] + self.unzip_attachments = str_to_value(params.get("unzip_attachments", False)) except KeyError as ke: # if config parameters are missing logging.error("Mailer: Wasn't able to initialize the notifier, it seems there is a config parameter missing: %s" % ke) self.corrupted = True @@ -38,7 +43,7 @@ def notify(self, info): self.message["From"] = self.params["sender"] self.message["To"] = self.params["recipient"] self.message["Subject"] = self.params.get("subject", "SecPi Alarm") - self.message.attach(MIMEText(self.params.get("text", "Your SecPi raised an alarm. Please check the attached files."), "plain")) + self.message.attach(MIMEText(self.params.get("text", "Your SecPi raised an alarm. Please check the attached files."), "plain", 'utf-8')) info_str = "Recieved alarm on sensor %s from worker %s: %s"%(info['sensor'], info['worker'], info['message']) self.message.attach(MIMEText(info_str, "plain")) @@ -73,18 +78,65 @@ def prepare_mail_attachments(self): logging.debug("Mailer: Will look into %s for data" % latest_subdir) #then iterate through it and attach all the files to the mail for file in os.listdir(latest_subdir): + filepath = "%s/%s" % (latest_subdir, file) # check if it really is a file - if os.path.isfile("%s/%s" % (latest_subdir, file)): - f = open("%s/%s" % (latest_subdir, file), "rb") - att = MIMEApplication(f.read()) - att.add_header('Content-Disposition','attachment; filename="%s"' % file) - f.close() - self.message.attach(att) - logging.debug("Mailer: Attached file '%s' to message" % file) + if os.path.isfile(filepath): + + # Add each file in zipfile as separate attachment + if self.unzip_attachments and file.endswith('.zip'): + self.prepare_expand_zip_attachment(filepath) + + # Add file as a whole (default) + else: + with open(filepath, "rb") as f: + self.prepare_add_attachment(file, f.read()) + else: logging.debug("Mailer: %s is not a file" % file) # TODO: maybe log something if there are no files? + def prepare_add_attachment(self, filename, payload): + """Add single attachment to current mail message""" + + # Determine content type + ctype, encoding = mimetypes.guess_type(filename, strict=False) + maintype, subtype = ctype.split('/', 1) + + # Create proper MIME part by maintype + if maintype == 'application' and subtype in ['xml', 'json']: + mimepart = MIMENonMultipart(maintype, subtype, charset='utf-8') + mimepart.set_payload(payload.encode('utf-8'), 'utf-8') + + elif maintype == 'text': + mimepart = MIMEText(payload.encode('utf-8'), _subtype=subtype, _charset='utf-8') + + elif maintype == 'image': + mimepart = MIMEImage(payload, _subtype=subtype) + + elif maintype == 'audio': + mimepart = MIMEAudio(payload, _subtype=subtype) + + else: + # Encode the payload using Base64 (Content-Transfer-Encoding) + mimepart = MIMEApplication(payload) + + # Attach MIME part to message + mimepart.add_header('Content-Disposition','attachment; filename="%s"' % filename) + self.message.attach(mimepart) + + logging.debug("Mailer: Attached file '%s' to message" % filename) + + def prepare_expand_zip_attachment(self, filepath): + """Decode zip file and add each containing file as attachment to current mail message""" + logging.debug("Mailer: Decoding zip file '%s' as requested" % filepath) + import zipfile + with zipfile.ZipFile(filepath) as zip: + filenames = zip.namelist() + + for filename in filenames: + payload = zip.read(filename) + self.prepare_add_attachment(filename, payload) + def send_mail_starttls(self): logging.debug("Mailer: Trying to send mail with STARTTLS") try: diff --git a/manager/manager.py b/manager/manager.py index dc33e08..94ebb36 100644 --- a/manager/manager.py +++ b/manager/manager.py @@ -108,7 +108,10 @@ def connect(self): connected = True logging.info("Connection to rabbitmq service established") except pika.exceptions.AMQPConnectionError as pe: # if connection can't be established - logging.error("Wasn't able to connect to rabbitmq service: %s" % pe) + if "The AMQP connection was closed" in repr(pe): + logging.error("Wasn't able to connect to the rabbitmq service, please check if the rabbitmq service is reachable and running") + else: + logging.error("Wasn't able to connect to the rabbitmq service: %s" % repr(pe)) time.sleep(30) #define exchange @@ -239,9 +242,9 @@ def got_data(self, ch, method, properties, body): newFile_bytes = bytearray(body) if newFile_bytes: #only write data when body is not empty try: - newFile = open("%s/%s.zip" % (self.current_alarm_dir, hashlib.md5(newFile_bytes).hexdigest()), "wb") - newFile.write(newFile_bytes) - logging.info("Data written") + with open("%s/%s.zip" % (self.current_alarm_dir, hashlib.md5(newFile_bytes).hexdigest()), "wb") as newFile: + newFile.write(newFile_bytes) + logging.info("Data written") except IOError as ie: # File can't be written, e.g. permissions wrong, directory doesn't exist logging.exception("Wasn't able to write received data: %s" % ie) self.received_data_counter += 1 @@ -356,7 +359,7 @@ def setup_notifiers(self): # timeout thread which sends the received data from workers def notify(self, info): - for i in range(0, self.data_timeout): + for i in xrange(0, self.data_timeout): if self.received_data_counter < self.num_of_workers: #not all data here yet logging.debug("Waiting for data from workers: data counter: %d, #workers: %d" % (self.received_data_counter, self.num_of_workers)) time.sleep(1) @@ -377,7 +380,7 @@ def notify(self, info): # go into holddown state, while in this state subsequent alarms are interpreted as one alarm def holddown(self): self.holddown_state = True - for i in range(0, self.holddown_timer): + for i in xrange(0, self.holddown_timer): time.sleep(1) logging.debug("Holddown is over") self.holddown_state = False diff --git a/manager/slack.py b/manager/slack.py new file mode 100644 index 0000000..aed1e7b --- /dev/null +++ b/manager/slack.py @@ -0,0 +1,55 @@ +import logging + +from slacker import Slacker + +from tools.notifier import Notifier + +class SlackNotifier(Notifier): + + def __init__(self, id, params): + super(SlackNotifier, self).__init__(id, params) + if(not 'bot_token' in params or not 'channel' in params): + self.corrupted = True + logging.error("Slack: Token or channel name missing!") + return + + + def notify(self, info): + if(not self.corrupted): + try: + logging.debug("Sending Slack notification!") + + channel_name = self.params['channel'] + slack = Slacker(self.params['bot_token']) + + # groups are private chats + channels = slack.groups.list(1) # 1 --> exclude archived + channel = [c for c in channels.body['groups'] if c['name'] == channel_name] + + if(len(channel)>0): + # we got a channel + channel_id = channel[0]['id'] + logging.debug("Got existing channel!") + else: + # if not exists, create it + logging.debug("No channel found, creating one!") + new_channel_req = slack.groups.create(channel_name) + + channel_id = new_channel_req.body['group']['id'] + + if(channel_id!=None): + logging.debug("Found channel: %s"%channel_id) + info_str = "Recieved alarm on sensor %s from worker %s: %s"%(info['sensor'], info['worker'], info['message']) + slack.chat.post_message(channel_name, info_str) + + else: + logging.error("No channel found!") + except KeyError as ke: + logging.error("Error in Slack Notifier: %s"%ke) + + else: + logging.error("Slack Notifier corrupted! No token or channel name given as parameter.") + + def cleanup(self): + logging.debug("Slack Notifier: No cleanup necessary at the moment.") + \ No newline at end of file diff --git a/manager/spark.py b/manager/spark.py new file mode 100644 index 0000000..311cd56 --- /dev/null +++ b/manager/spark.py @@ -0,0 +1,59 @@ +import logging +import requests +import requests.exceptions + +from tools.notifier import Notifier + +class SparkNotifier(Notifier): + + def __init__(self, id, params): + super(SparkNotifier, self).__init__(id, params) + if(not 'personal_token' in params or not 'room' in params): + self.corrupted = True + logging.error("Token or room name missing!") + return + + + def notify(self, info): + if(not self.corrupted): + try: + logging.debug("Sending Cisco Spark notification!") + + room_name = self.params['room'] + auth_header = {'Authorization': 'Bearer %s'%self.params['personal_token']} + + # get room id + rooms_req = requests.get('https://api.ciscospark.com/v1/rooms', headers=auth_header) + rooms = rooms_req.json() + room = [r for r in rooms['items'] if r['title'] == room_name] + + if(len(room)>0): + # we got a room + room_id = room[0]['id'] + logging.debug("Got existing room!") + else: + # if not exists, create it + logging.debug("No room found, creating one!") + new_room_req = requests.post('https://api.ciscospark.com/v1/rooms', headers=auth_header, data={'title': room_name}) + new_room = new_room_req.json() + + room_id = new_room['id'] + + if(room_id!=None): + logging.debug("Found room: %s"%room_id) + info_str = "Recieved alarm on sensor %s from worker %s: %s"%(info['sensor'], info['worker'], info['message']) + noti_req = requests.post('https://api.ciscospark.com/v1/messages', headers=auth_header, data={'roomId': room_id, 'text': info_str}) + + else: + logging.error("No room found!") + except RequestException as ce: + logging.error("Error in Spark Notifier: %s"%ce) + except KeyError as ke: + logging.error("Error in Spark Notifier: %s"%ke) + + else: + logging.error("Cisco Spark Notifier corrupted! No authorization code or room name given as parameter.") + + def cleanup(self): + logging.debug("Cisco Spark Notifier: No cleanup necessary at the moment.") + \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index a103413..869d794 100644 --- a/requirements.txt +++ b/requirements.txt @@ -9,4 +9,6 @@ tweepy dropbox logging netifaces -python-gsmmodem \ No newline at end of file +python-gsmmodem +slacker +pyping \ No newline at end of file diff --git a/stuff/secpi-logo.ai b/stuff/secpi-logo.ai new file mode 100644 index 0000000..736208c --- /dev/null +++ b/stuff/secpi-logo.ai @@ -0,0 +1,1624 @@ +%PDF-1.5 % +1 0 obj <>/OCGs[5 0 R 6 0 R 26 0 R 27 0 R 47 0 R 48 0 R 49 0 R 84 0 R 85 0 R 86 0 R 121 0 R 122 0 R 123 0 R 124 0 R 161 0 R 162 0 R 163 0 R 165 0 R 164 0 R 166 0 R 205 0 R 206 0 R 207 0 R 209 0 R 208 0 R 210 0 R 249 0 R 250 0 R 251 0 R 252 0 R 254 0 R 253 0 R 255 0 R 297 0 R 301 0 R 302 0 R 298 0 R 299 0 R 300 0 R 303 0 R]>>/Pages 3 0 R/Type/Catalog>> endobj 2 0 obj <>stream + + + + + application/pdf + + + Web + + + + + Adobe Illustrator CS5 + 2016-03-18T11:55:32+01:00 + 2016-03-26T13:11:15+01:00 + 2016-03-26T13:11:15+01:00 + + + + 248 + 256 + JPEG + /9j/4AAQSkZJRgABAgEASABIAAD/7QAsUGhvdG9zaG9wIDMuMAA4QklNA+0AAAAAABAASAAAAAEA AQBIAAAAAQAB/+4ADkFkb2JlAGTAAAAAAf/bAIQABgQEBAUEBgUFBgkGBQYJCwgGBggLDAoKCwoK DBAMDAwMDAwQDA4PEA8ODBMTFBQTExwbGxscHx8fHx8fHx8fHwEHBwcNDA0YEBAYGhURFRofHx8f Hx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8fHx8f/8AAEQgBAAD4AwER AAIRAQMRAf/EAaIAAAAHAQEBAQEAAAAAAAAAAAQFAwIGAQAHCAkKCwEAAgIDAQEBAQEAAAAAAAAA AQACAwQFBgcICQoLEAACAQMDAgQCBgcDBAIGAnMBAgMRBAAFIRIxQVEGE2EicYEUMpGhBxWxQiPB UtHhMxZi8CRygvElQzRTkqKyY3PCNUQnk6OzNhdUZHTD0uIIJoMJChgZhJRFRqS0VtNVKBry4/PE 1OT0ZXWFlaW1xdXl9WZ2hpamtsbW5vY3R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo+Ck5SVlpeYmZ qbnJ2en5KjpKWmp6ipqqusra6voRAAICAQIDBQUEBQYECAMDbQEAAhEDBCESMUEFURNhIgZxgZEy obHwFMHR4SNCFVJicvEzJDRDghaSUyWiY7LCB3PSNeJEgxdUkwgJChgZJjZFGidkdFU38qOzwygp 0+PzhJSktMTU5PRldYWVpbXF1eX1RlZmdoaWprbG1ub2R1dnd4eXp7fH1+f3OEhYaHiImKi4yNjo +DlJWWl5iZmpucnZ6fkqOkpaanqKmqq6ytrq+v/aAAwDAQACEQMRAD8A9U4q7FXYq7FXYq7FXYq7 FXYq7FXYq7FXYq7FUi82earXQbHkaSX0oItoPE/zN/kj8cVee+VvP97Y6pK+oyvcWl2/K4ruUc7c 0HgBtQdsVeuQzRTRJNC4kikAZHU1BB3BBGKr8VdirsVdirsVdirsVdirsVdirsVdirsVdirsVdir sVdirsVdirsVdirsVdirsVdirsVSfzP5ms9BsDPLR7h6i2t60Lt/BR3OKvEtX1e91S9ku7uQyTSH c9gOyqOwGKoNTQ4qzPyL53bSJBZXpLabI2zbkwsf2gP5T3H0/NV65HJHLGskbB43AZHU1BB3BBGK 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 + + + + + + proof:pdf + uuid:65E6390686CF11DBA6E2D887CEACB407 + xmp.did:F77F1174072068118083840C9FA05347 + uuid:ecdbaf01-cab0-b64d-8760-0d26b8deaa69 + + uuid:72b1533f-9e90-064f-87a5-4345918e86e3 + xmp.did:FD7F11740720681188C6F0AB0253E170 + uuid:65E6390686CF11DBA6E2D887CEACB407 + proof:pdf + + + + + saved + xmp.iid:F77F1174072068118083840C9FA05347 + 2016-03-18T11:55:32+01:00 + Adobe Illustrator CS5 + / + + + + + + Web + Document + + + 1 + False + False + + 1024.000000 + 1024.000000 + Pixels + + + + + Helvetica-BoldOblique + Helvetica + Bold Oblique + TrueType + 9.0d3e2 + False + Helvetica.dfont + + + + + + Cyan + Magenta + Yellow + Black + + + + + + Standard-Farbfeldgruppe + 0 + + + + Weiß + RGB + PROCESS + 255 + 255 + 255 + + + Schwarz + RGB + PROCESS + 0 + 0 + 0 + + + RGB Rot + RGB + PROCESS + 255 + 0 + 0 + + + RGB Gelb + RGB + PROCESS + 255 + 255 + 0 + + + RGB Grün + RGB + PROCESS + 0 + 255 + 0 + + + RGB Cyan + RGB + PROCESS + 0 + 255 + 255 + + + RGB Blau + RGB + PROCESS + 0 + 0 + 255 + + + RGB Magenta + RGB + PROCESS + 255 + 0 + 255 + + + R=193 G=39 B=45 + RGB + PROCESS + 193 + 39 + 45 + + + R=237 G=28 B=36 + RGB + PROCESS + 237 + 28 + 36 + + + R=241 G=90 B=36 + RGB + PROCESS + 241 + 90 + 36 + + + R=247 G=147 B=30 + RGB + PROCESS + 247 + 147 + 30 + + + R=251 G=176 B=59 + RGB + PROCESS + 251 + 176 + 59 + + + R=252 G=238 B=33 + RGB + PROCESS + 252 + 238 + 33 + + + R=217 G=224 B=33 + RGB + PROCESS + 217 + 224 + 33 + + + R=140 G=198 B=63 + RGB + PROCESS + 140 + 198 + 63 + + + R=57 G=181 B=74 + RGB + PROCESS + 57 + 181 + 74 + + + R=0 G=146 B=69 + RGB + PROCESS + 0 + 146 + 69 + + + R=0 G=104 B=55 + RGB + PROCESS + 0 + 104 + 55 + + + R=34 G=181 B=115 + RGB + PROCESS + 34 + 181 + 115 + + + R=0 G=169 B=157 + RGB + PROCESS + 0 + 169 + 157 + + + R=41 G=171 B=226 + RGB + PROCESS + 41 + 171 + 226 + + + R=0 G=113 B=188 + RGB + PROCESS + 0 + 113 + 188 + + + R=46 G=49 B=146 + RGB + PROCESS + 46 + 49 + 146 + + + R=27 G=20 B=100 + RGB + PROCESS + 27 + 20 + 100 + + + R=102 G=45 B=145 + RGB + PROCESS + 102 + 45 + 145 + + + R=147 G=39 B=143 + RGB + PROCESS + 147 + 39 + 143 + + + R=158 G=0 B=93 + RGB + PROCESS + 158 + 0 + 93 + + + R=212 G=20 B=90 + RGB + PROCESS + 212 + 20 + 90 + + + R=237 G=30 B=121 + RGB + PROCESS + 237 + 30 + 121 + + + R=199 G=178 B=153 + RGB + PROCESS + 199 + 178 + 153 + + + R=153 G=134 B=117 + RGB + PROCESS + 153 + 134 + 117 + + + R=115 G=99 B=87 + RGB + PROCESS + 115 + 99 + 87 + + + R=83 G=71 B=65 + RGB + PROCESS + 83 + 71 + 65 + + + R=198 G=156 B=109 + RGB + PROCESS + 198 + 156 + 109 + + + R=166 G=124 B=82 + RGB + PROCESS + 166 + 124 + 82 + + + R=140 G=98 B=57 + RGB + PROCESS + 140 + 98 + 57 + + + R=117 G=76 B=36 + RGB + PROCESS + 117 + 76 + 36 + + + R=96 G=56 B=19 + RGB + PROCESS + 96 + 56 + 19 + + + R=66 G=33 B=11 + RGB + PROCESS + 66 + 33 + 11 + + + + + + Grautöne + 1 + + + + R=0 G=0 B=0 + RGB + PROCESS + 0 + 0 + 0 + + + R=26 G=26 B=26 + RGB + PROCESS + 26 + 26 + 26 + + + R=51 G=51 B=51 + RGB + PROCESS + 51 + 51 + 51 + + + R=77 G=77 B=77 + RGB + PROCESS + 77 + 77 + 77 + + + R=102 G=102 B=102 + RGB + PROCESS + 102 + 102 + 102 + + + R=128 G=128 B=128 + RGB + PROCESS + 128 + 128 + 128 + + + R=153 G=153 B=153 + RGB + PROCESS + 153 + 153 + 153 + + + R=179 G=179 B=179 + RGB + PROCESS + 179 + 179 + 179 + + + R=204 G=204 B=204 + RGB + PROCESS + 204 + 204 + 204 + + + R=230 G=230 B=230 + RGB + PROCESS + 230 + 230 + 230 + + + R=242 G=242 B=242 + RGB + PROCESS + 242 + 242 + 242 + + + + + + Webfarbgruppe + 1 + + + + R=63 G=169 B=245 + RGB + PROCESS + 63 + 169 + 245 + + + R=122 G=201 B=67 + RGB + PROCESS + 122 + 201 + 67 + + + R=255 G=147 B=30 + RGB + PROCESS + 255 + 147 + 30 + + + R=255 G=29 B=37 + RGB + PROCESS + 255 + 29 + 37 + + + R=255 G=123 B=172 + RGB + PROCESS + 255 + 123 + 172 + + + R=189 G=204 B=212 + RGB + PROCESS + 189 + 204 + 212 + + + + + + + + + Adobe PDF library 9.90 + + + + + + + + + + + + + + + + + + + + + + + + + endstream endobj 3 0 obj <> endobj 8 0 obj <>/Resources<>/ExtGState<>/Font<>/ProcSet[/PDF/Text]/Properties<>/Shading<>>>/Thumb 311 0 R/TrimBox[0.0 0.0 1024.0 1024.0]/Type/Page>> endobj 305 0 obj <>stream +HKo$+hYuO N^Ck/6,2+*322/ӏnխޅo?/[᧧?ߖ $Y8Y[?|i}zo_?_/BXc>]_|;S}ͱe#zW&9̂%^zZѺ.>-BRlk}s2{Km1͕N.s>TMe?ĝ=ץ5ngiv܏ˢqBn_[ܼcm9]֚}R* ؛PncTwk<[NV}-~O%Do,yO7On˞KB٣rr޲jRzO}tߗ×SC!>d}#?w-uOߗGo(y5r9򇗿> } +e+%.Q7(d,.9Qrbq[gX?h.6eW%$KYC7en=ʒQ9HxR%c/vHu\2;gեʑzEo(WQ᳇fꞪ ]C陒9.VRg1+qŴ3MC}h(={E^0rKkz[XCo.1ľ MVM[-;o܃J`:.'?]%R9\&J-=WZr!P8(JMC2O3w(ÍkCivtDGB46`\25g[U|yQ?WM;'X^\A}8{=46bH;ĞorDW@Ygxz(RDJ)L:;e، ++dxp][pZ-Ce?` dv@)$ea(=`dhHa-GB }Y%"q'fg0zi:q链E꣓FݤNTr_?Fb"$0|c.&!1HÆDf*''zټʅ%fOm'RqQb.+ +'JvՊ4,a(>+IR *W 8M~Xh$qʄکHdpGc6$ + 1s\M {1ldJKh-R67'qaz$ټlafշ U*`=704B1H+X;d{XN!ms}rM^/Ilؽ1Yjك>*Gu%y A\gsHXRdUT,@}l!&!r'yM[* 7ij{{elL"bO hMy-R٪){ >J*$q&!_dX=;3JMEĈ9:lQM +jZOQ!cTcEhTr@/7;d:|sM}_Jc\@1lk`h@2!}Pd%"\*Uل<@US{ZHŨef^O+\vhٞRMh.z$[-M}|K-JxpQoȨ;%r1yAUp_NM7D -kg'f:G 1;?Q D3u.=~پZDSC>DaQc8&!DrdA\x0CJn/ NGI$y7 r0݆U4\%s懚PO ǝ&΃l q%7H"T~&lv+ S_v|g\ ^&&߯9Ǻ0`P BNq{4$̢YLeeVՋXJ KAGp.?RG5=NDpOf˗[\~[~_-|NT'_xz~`ރP9M4@5pM%~ЛQ&:]-v6$"75D)Nl1z8JA6CE)NƼcJO mm 6Ԩp M:4Irte)N{E(UZRՁF$ȇ,yc<g>I"Wo^ y?rPQo+boVwXB; AH:9!]i3ejGSCwVe=Ez;eiuysb8pUY +9 ~`IjZ-jHcB[ڍFb"yF8MNbHLbp{UH7XsZ0zӴP˄c;t|Ǭc*Q%Ffn6a"7DMȃ}T;:N+BI&u4].@d +sE0N")d6>kёI"'޻nKt>?s fj~T My(,)Eג?wx%jpg +"N!4#HI̳qrdnxLxE! Sʢ`W¹ZvvsAvo AVqKSn 9W!jx3Ȯ< ctw\ ]_/eFj5#~,-DJD_BM{>{{_\FwTMj>W wV1.N4Vfl:3P;y$Nt5ue{'>2C(젪'l+RJ]]r%'g4 Q`72@aPUA< $_Y4:˄NMx:MO# +As +o^T:: pHK$@Aѷ:BcsM-nQAV7) x@Id5\g lH`^R>Ep%Hw1fQ:|!).)yrđszD.%פkMcNpպb9#RfMiYN{MCx[(h0ULs +w.#BM!؇; یˌ@#0PMUꋎ,a/j$7Vx(J5+IhTvMu4-!$7w兴hd/X!FMod'QR3 `t ш+X$"¿D_')ucipN큜b 9 j_xggqy_.b>=/w`78sGM#FtrM١EDS0T>O$UrI19ˌ"HBJh~ 4&JJ+ x;D:E]zKkxQ(c6{`hԕ@ 3Հas[t`x\&&'c2iaHIm dA w͍VpZ2\":P-sj5;4Xҍvaƽ4OS{Q}~4Bt*?|۫iiˁ?TkA.4 !ݬM25(mX{~cEَc5)#"8[As; ,!B7^e0n+S 0hp|XF8Xnu >q:%Qf~J<۷eD4x0Y+Ggz.}^\=~F0U@}0QBR X)l@LkKERmVJX Gp+!|9gB+8_dÆ0B{X+TJ##[Yh<mUD"/W:|x䡗}ÆS.ds Npb'uG"c`G8^OrND G9}Ofrs5{]ŮxsS1t& +dO"|~*zl%{Mcxqd j4+֦4ƍ3&>wU_Oz"]\*/\ݕ9|Mc`=^iaqG8$>Œ8yх?&/nR! s!ɻұִtx 9J#\D\;q3ԏ9?x1mJ3S=pW.0׌)JVR]pzWfQD9P$ ]:έш'r̨7m#Uޢ'=;E"]ʠq[Z 8$B)уHJoH\♬e_^'GJ)sSNIݐƑ+,B@;G=yi<TfL2Qҵ.??X),V4_Ucvq(La93+ TYZLkܤk +[mJ3ӴZ|39ጀ:2Rϱ$,Z!f2xCM"LJR-=Vc}|0gm"=1M:%[`oSn>db,Aא(0]An 纬aWh:MRڹ7"oҪ7D/wgHs\YgYGDZN&i.8c/Ak݇EBag?D˒{F`kNTԮH`0 +91NsP`XL!C&RCYW)R@æSλu:e_Mv^>FB?֫ +µ/p^&"s- ~lwsAEYǶsfFΡ1vzh(\ [dP1{wj6(WU%>;Me2PkD[zo ݫʇ8I+=D/3&X()_3|:f^&C* (~^gDqm0f\I`׈؃ІS!<۔Y +Pf{-9Bp@<*t_q'5Ez)kYp_2Vc9Q- E^5N%>.{~/9eARn^+lvD0%EƩeP22OEA^|1a+TpI8QKHzږ?01$zwPOxvP3 +Yڳ5"psYλvo`fj {JƩl1=Ɋ"ɱ-II}/xU?#n&k#ߡ`zeY1¤_Kkr +C[ nGLzJWgqܣ 6ZxP PxW]}.7cVvc;~# ׵KD]. $AD/!(p /mh:f,)y|#N2lVjNDL˼ּ]l<׀yk|Xz62(fGih#Mt%>6C ^g+1Tp`mkkaҺZ^GO}ks;F^IW ,@-R\"7 437G{5g5.28E 4qH~瀩Hq?eNdWNhF'-!>y;p5; k`)˳kĻ"S6QBy"2{.5).RRwV(B_An?qu JATcR窱Oko ~ {"jb_HX=W]ZL/)"zTʪssmI~VKC6F_7Ki5EKy[]K 5Iw&.`$8;49F M\=$UiM^kR\"S;螊NDj u]-s8=Wlv)h=9F]&;rIW$rUKG΀. J$@^̳{@]9ڴFʼcnR=} -)|އ .sɝ'Kk3> Eهמ*b/iY'~CKَ3ꚣaG3嵨4!g +~7vՠ|?TZwAuDgcaFGG}xdH0@"j+$G$rl9Dލ~U({AR?HB_!7}  |I)HHc~FGE=C~啃8^_u_#|B9B}ӯ򌥰E]\8|dPCvKvh9{>x{[tz`,eI9}P8"?NGJ0:<+ݎ ѩ<;$@`PSuVX&MSK!BtROΩڮLǩRu)f%yRi43laă!v8RT! E*kVXrLn +KyZ# +yILyTŎH}) g:F;9T@9eDf^{g)@7e{DM'ؤ&׉H)xȔ.J}];[DD]^7"|+TSsWDߥnG%Ool 10Od>7E͛JXSp{[Ds$N3Epv+t0Q +}7; lOu7yM/+V!\B-wr<[MWᘧdrvY#euٌNi)h*݉E3·CI!DȰB9/Q=;9obY+5 ZAWQ* cuȕ65AEn_]e?`? endstream endobj 311 0 obj <>stream +8;Z]"l]LKU$q@j&5P1.gBP27BGtFWi"NGpDb%,+j`]>)m_8LTX`/,-T:7UfB#d8ec +6@H`>o)^>qnH.nfdW[dO`b&&IdWVZV@O]nG<.-q[9'OC[G&!h\"F;I>q"4f=>l,J\(oLCVBp081@A](uP0I4,lEN[,r(66o-HV3LTDI +&jf<].3LMpk06j(VhqR(4_[BB$m3scP**tK'gb8& +A*LPs..KG-VaDTQbY*-gf04lVqVX=OZm]lM_oZ0LGe$DuEUV)gXTVm-SD[TSFfJNs +rRQ%mb/6^YWtRF[W)AhL(cES*A7*AuTY7>SM:epjAWHn1&iA:-Wt`bHThEY1[pGpD +MG:sQ.]&_HeGV?odZdY#EBo>FBtd2@)Ree5jlmYZ#3@m19n7mUF:CH%MK%[@>c+QD +OZY6H8iOn(2@1:$lHq(e;P%%#!lCjA)8?0GPu;(F,ed+U]]8BF65cDn71cdcTHL +Cpe-2or(rNIaM53,H/**$ArtAgs(]S!GZgpY0`"=-iV endstream endobj 312 0 obj [/Indexed/DeviceRGB 255 313 0 R] endobj 313 0 obj <>stream +8;X]O>EqN@%''O_@%e@?J;%+8(9e>X=MR6S?i^YgA3=].HDXF.R$lIL@"pJ+EP(%0 +b]6ajmNZn*!='OQZeQ^Y*,=]?C.B+\Ulg9dhD*"iC[;*=3`oP1[!S^)?1)IZ4dup` +E1r!/,*0[*9.aFIR2&b-C#soRZ7Dl%MLY\.?d>Mn +6%Q2oYfNRF$$+ON<+]RUJmC0InDZ4OTs0S!saG>GGKUlQ*Q?45:CI&4J'_2j$XKrcYp0n+Xl_nU*O( +l[$6Nn+Z_Nq0]s7hs]`XX1nZ8&94a\~> endstream endobj 309 0 obj <> endobj 310 0 obj <> endobj 307 0 obj [/ICCBased 316 0 R] endobj 315 0 obj <> endobj 317 0 obj <> endobj 318 0 obj <> endobj 319 0 obj <> endobj 316 0 obj <>stream +HyTSwoɞc [5laQIBHADED2mtFOE.c}08׎8GNg9w߽'0 ֠Jb  + 2y.-;!KZ ^i"L0- @8(r;q7Ly&Qq4j|9 +V)gB0iW8#8wթ8_٥ʨQQj@&A)/g>'Kt;\ ӥ$պFZUn(4T%)뫔0C&Zi8bxEB;Pӓ̹A om?W= +x-[0}y)7ta>jT7@tܛ`q2ʀ&6ZLĄ?_yxg)˔zçLU*uSkSeO4?׸c. R ߁-25 S>ӣVd`rn~Y&+`;A4 A9=-tl`;~p Gp| [`L`< "A YA+Cb(R,*T2B- +ꇆnQt}MA0alSx k&^>0|>_',G!"F$H:R!zFQd?r 9\A&G rQ hE]a4zBgE#H *B=0HIpp0MxJ$D1D, VĭKĻYdE"EI2EBGt4MzNr!YK ?%_&#(0J:EAiQ(()ӔWT6U@P+!~mD eԴ!hӦh/']B/ҏӿ?a0nhF!X8܌kc&5S6lIa2cKMA!E#ƒdV(kel }}Cq9 +N')].uJr + wG xR^[oƜchg`>b$*~ :Eb~,m,-ݖ,Y¬*6X[ݱF=3뭷Y~dó ti zf6~`{v.Ng#{}}jc1X6fm;'_9 r:8q:˜O:ϸ8uJqnv=MmR 4 +n3ܣkGݯz=[==<=GTB(/S,]6*-W:#7*e^YDY}UjAyT`#D="b{ų+ʯ:!kJ4Gmt}uC%K7YVfFY .=b?SƕƩȺy چ k5%4m7lqlioZlG+Zz͹mzy]?uuw|"űNwW&e֥ﺱ*|j5kyݭǯg^ykEklD_p߶7Dmo꿻1ml{Mś nLl<9O[$h՛BdҞ@iءG&vVǥ8nRĩ7u\ЭD-u`ֲK³8%yhYѹJº;.! +zpg_XQKFAǿ=ȼ:ɹ8ʷ6˶5̵5͵6ζ7ϸ9к<Ѿ?DINU\dlvۀ܊ݖޢ)߯6DScs 2F[p(@Xr4Pm8Ww)Km endstream endobj 314 0 obj <> endobj 320 0 obj <> endobj 321 0 obj <> endobj 322 0 obj <> endobj 297 0 obj <> endobj 301 0 obj <> endobj 302 0 obj <> endobj 298 0 obj <> endobj 299 0 obj <> endobj 300 0 obj <> endobj 303 0 obj <> endobj 335 0 obj [/View/Design] endobj 336 0 obj <>>> endobj 333 0 obj [/View/Design] endobj 334 0 obj <>>> endobj 331 0 obj [/View/Design] endobj 332 0 obj <>>> endobj 329 0 obj [/View/Design] endobj 330 0 obj <>>> endobj 327 0 obj [/View/Design] endobj 328 0 obj <>>> endobj 325 0 obj [/View/Design] endobj 326 0 obj <>>> endobj 323 0 obj [/View/Design] endobj 324 0 obj <>>> endobj 296 0 obj <> endobj 337 0 obj <> endobj 338 0 obj <>stream +HyxOWǿ{Ͻ'4XjI{P<(3= ^EDkvҡձv*ADJ~s?̽{{sa +4-j~傒orW£Gu+NORJەB|!mq 9> 1_Uk/de$$ٻS셀HԬ3C%EI |Ȥ؊ҭ RSFh:"6CU=_Vƻ2ZEpN"UØکcGj=E'۠UĻ':(r@<U?J\ҵT:UQ(-@M f%#ITL42h͢VZOٴtR9c[r;9r֟Xvkcr%UfUZm;Nz{1jS t\Nrq;i.vIW-W+mt76ܞ8VN1\{j^h-MMSkijl{vT ODT@,+E ⦸'I/oŻY47H3 FL V}˶zZlMYgVuǺg=aWT;^`gl{/Nv;MN7Żd(ކ cxZ)vwDX|: U+.To=w=E+JW*|uĮz~:Pzuu˪z8 %Cz˞ A[EUWgN6x4x'{nZA˗tJڔvgsG~5Nruqǻܱw;J[ݽݽ@^%/|u VgWqeU$/h߼h^Q} +]y?ț~n˪ -s=>5 T淕J@ͷT4MW_m7Rjulio\aTyJo6Bk4n2㞪aOĸ[<;<ս b+KԾUX4 ,bb& `56 6;T7 +XA,0N(8n 8Sj6>H@ ~,$b" T.D +##0H(F1`b<&bvb &c/I#A:$ɇQuz M }TP DD䐋QRcZLSz#5WTQԜ&l֒ޠVBmnӨuN*.ԅR7Nob-AUxbC+Xxqzw*nף$fGH-T|CVܚۈ(7MV*s_|/9_̅|E[6s 4i 5_OvFl#)_d{Av$%eƯ8.NDF"UrT9_\Gs3U"%Q W9'n_Q*]9Zrl1G\E/*PTG8ˢH\nqM\7B";.BESME"ǘ^e.!3$c0M 0vHy`l<13zo4ye޳[ hWߧ 铧dS1X2Cy8<`}]z" B0qSn͸9<q n/aHŋ҂^¯11}{̸p6bc4j&*DZvJTUJқhm]T5H ћTWi5LfjjM)kJr)ͭ) I܊-'&DHejA>Y|'4SgA|(g83Йaأ#{ibO~ANYSidjl:.\n4tWoQ.om*cF(G7=Y98#+ڏ)))B(Q1*NT"yGQRTb rTbUJTPUFթդZT~APK>5,5ԄR5ԂZR<%P"%Q+jMm-%S;JANmu.ԕQwA==Ge^I!&zt8tXtxqנ~~)o45C\>fDf0S olfI;G iM\K,>\ + zY沘{#mʹz)SM{h/_z[pX+cFs:$H<p <'!@• _F)T@4=坘L'I( ?L¹$%IyH…H'$%C#ᰐnV=B}: eK~!1Lx +$?ء\A&W2! c$`OiO1V-8EE1s6a>Xc ,_ +|XXX%|@N哀\2p Ȥ,F6,!qq$2*c$ŗNC:N86b6c bcvbvcb>~ǧ>a|/pGqL@(x/l~&CuS}K#P~GEL@QgBeB$#eH(*yp5PPPPu$.QD:E"2l_lEY\320STaՕwǻn p1exj24ѹj[L6wDD ʽ 9(lOJP L&˪S)z#G^/&W۸Un|@2^~-es*I d5w˂h[y-%`Ǣ%8pMa_'fc7g6j5{ p&O ĝx?&$~)F"@oi tS#8_FQ ƏKMI~\*cF'JLŎ1|XLdžD a6ɒ(0phnEOqR6{5 0[W`*+nMia+:s+xc#\  f ƨJAXa˩`FUjnq+z6Cֻ9;O$ҩy"o m-SUfnTղ%(x!h}琥0I+A\q5Ԛ#<ŰUg.d]N.U2Fl! ˍFMM4(V5e89hQ~"I ἁ0? T<3\.pуΰ N31ga{ ;P3\Շf$9`!1@; gxj. ?:+0\`j <$1ajvr2lK)N0IGᕶD|TٔAɜ$ YJE!!dNb٪.u.(]07tpdM̉QcRRynOz /eBd<4 +cLHl!Ea07 f,rGlu:ܢVtNbfO<)/*Sc͂$k f%:X'ysRaYwyrn>%F)^|DX5ܐΫHdIR܍8ÉkN,q)7dO +RS&ԔɓH͖*XcXl\DB%w֔4'DM~aҭiF?=Öa1Eo6-c5Ŗ%RGk+{fdwp̺o15 "}駆ܢkF.Ϸ{^jԩȕH0'bUԩboS_KYahZ%5`9nU{s[$,[3dAڀ^ scmC+|E\u8$W/+tȔO-Vچǰ+_1@Ÿ6-W:6ܗ1(V6b~@{z&Z4r;1 z3[0_"RB(z1)p뷇֝kk]7j[v?A})ȝJ#y䫴xzk,Z0Y*1.f* +;J>~5Epd.O"~/c?>HWwS뷼G{vؼRV%,\jhgʝ3!!iwľ ~<J_8x *iE~؃V pB#}.Ɨ @C c-z(#`ѻ:3  ~MQ0tn7޻֞ؼxH|}|y-&??=<+/ql~^ƹ68?z?eUusw߾vhJ FLA[[-ȈCPjBD!:8 R +j(ҖQ( #hc+߹{߽sߙ[gޣL=Ca'|W4gz~ᾜcvYre=}=% oCl)<-r_; Nm"0j +L[>P}ms$^2rs>A\8ɞt3XÀ\<~yben޻(A{ w cűFr}gAgJ>[s. +Wh;Yvov"Et䳞}_@b%:s8ߥ ,?ZW0p6m +g>ݫΧ{O7Uy; +=}NEZFv]œ}2mj]ofMv lptW%xi\I\|o` Pbx:N}'2vߢQ3+j:6[9$嗠J%W[i=C#{Ӝ=` X{qO$6YWߤ7\˳n19?yy<.Mf|Ur&MK]Y*R7]s;z:{xpȌ9Xj(k euUhs\?Eׯvט$k{93g{t܋+`+Tv| xT|xVɱn:|c F$Nm\Z cz@k~Z1G_5}S?kޱzn"utUkBU:3϶nu&l^^8?|jZc϶nt;K'laS!W'++"~F^(32ڻ\ƹ䆰Iho?fR06Es͉>2.R* Y=0^Z!7˼7wf>=Χm^kY蓶zYL14frdր\B2oATqW3;wӴ=لOIc /q:8עIc41͑Ϛ=y:j|6kچ]FFc.E^'e۞ߜm9mEԠ}JxڝԜmƣZ36é'}jiЋRF<ø?пj}9g3ֳ6͎þRG6QfI);iFX 4 Sʜ-&&gA3ׂĆǜ͟O?TM+1ޢ4aƥȋpqs9l&+YLvfnglWe)2UOZ=AEAY։DY|6vBj_]L^Tڻ"K=s 6Ӣd1vwU` +gOkKpG&33ƾFj"%ղ#fԁxKۛ|T.}+oΈ\)bLt׻+iP*œ#C>/RۀjA-b eHL5F+-@| Ėgѻ3ZT(yv_Dl|/|5rd(c6ȗs#fzAy,c΁./WQy9 ~ \~#S˩-nverͧlӏln$?s:ooP><)q5/JzF}ΈTF5@A)䠞6y'u[L*~IsnSAx6͝} +o3n<^oA:)f +M*^:Qhj NIt} /똷PXhkR X| +x]`co9Gۂ|1x,\`ח}h.kˏ5>U&'T.NOafon It=ܞGϛkIy%<,"PڃZE?q}jMw Os!ПCi]3uX ;]f;Cg@v=y.:KE3^՜Fs=w9RA  '㌟5iJpG5AɵiCF~9kw{_ykq_pkPFsc' Ћ2BaT7u'њWȈRu/5rǩrN +e_εiu !NRF'ews؜Asv:ZWhh;]2Crv2SȞj^c]7N;,<\R[m8Z8Xn&AXˤ9}}ji~GUa̞B \! 6D"Ae [lMb `[D<(bk`}lHߊz_TiPNj9sb[&gX~Ƞjĭ B;j S-Qj0SQnPea%9X輍7XŻKrItJ$g mdjdjCL$ݑ GNˈx"jI˝=&c|=;tUc9c1C%b KFCo^#y?'|"1A2O[pzc8߁1H_żOlϞPO;iy#n.6% |7ZU2Cv?֚l*Mtl_O/ǫT_9Gʴ(2Z!i kpF`*8m3ik`7I,u YA&j`hh uGzQu{ĹU)#?En(>NjJCBTFL +7KGum&.;bV+N+S8AnжKk.;[Wert9YxKm!9[H(#"le8*f~TkWY3A@ݦ`kYȑP+1M+ +-d؃ Zb(f^hϘ{Ƚv&}r ;NjAhu5} {aI|>8qO[s lrW.~8C]FIYcʴ΄w8Q8sf<^TQl5ij:97I[FTg$ D.<Oezz0vk<|q rnQnT}0鬶>oR,σ"\i'٬#nᶱs\p\#T NDS6o"c ZX:'hakXNڅT|шA'B:kd@Xk̰Vi]b{tYZ͞zK7%{,ݜ|aVrҭ8Y::mc閎dY:#qԆc;[y6mQebߵtU(&l!mFJz'9I3xLaqi7`.kSq"ɜb1t.bL1-%>Q*0[P-fY9JwFS #'7uI2Y$&q_6|_%xR(l%O}l0NM;(R|ĕ4K0l _hL k6@.k{j=C-:ATTtkp_ݿ 3 4_ְNUaT&cCiK Es,&z>FO?Г~zʷʶzu٦A*2=LQ%:({Z +-ZӃA K,ڡ= ]Ye7ģ;=qz!魒R{4܏H1b('>>8\c,a<;ɟ1S`tYgq<9v5\>WBo?)чC?Y<80j(>1''>pŗ8?\ZqgqW8 E\e ?p_㟸kop¿q iFWB-m$FJ'tE!$^KrD-}$Ia= y(`X]KkZ^m-۶m۶m[˶y+ ȈLȌ,Y ّ9rwFȇ?o@ABaAQ?((R(2(r( +J*jZ:zhFh&hfhh +m.d;ڣ:: zzcbcbcFbFc bc&b&c +bcfbfcbcbc bcVbVc bc6b6c bcvbvcbNN .. +nm]}g,Ll\|.B.b.R.rJjZznFnfnVnvNn^~AaQqIiYy^E^e^U^uM;{|G|'|g||W|7|w|O/o +DIVP +0 +p +H(h_KGqO@ HDILɕB)JFiNAIE*)r(~S.ʣ?WR~*B*"*bGUB%UJUFeUNUAUIUEUUMUC5UKUGuUO@ HDMLB-Zڨک::zzhihiFhFihi&h&ihifhfihihihiVhVihi6h6ihivhvihi鰎討NN..鲮誮nn?==#==3= +;}'}}7}e;p(vu8wGt$GvGu4Gw ٖX8xNDN$NdNNTN4NtN L,?[ٜ9grr OnY.B.".b?T%\ҥ\e\\\ѕ\U\\5\ӵ\u\\ ЍM-[ۺۻ;;{{{z{z{GzG{z{'z'{z{gzg{z{z{z{WzW{z{7z7{z{wzw{zOO//om]}?C?c?S?sKk[{GgWwB 8PA L6"HA J5Db1_XA N7 DA I4H$R)TA M6H2tyFYQsΐD@EDP{!@Hm6da6{ j JQ63{PPUPP5PPuPP hH4F^G4 M h8ģZZ ڢڣ:: Hp! H=  ~# /?` a0`(a8F`$Fa4`,a<&`"&a2`*a:f`&fa6`.a>`!a1`)a9 +*:Ǜ؀x [6vx;>>.>!|1>891 ė +_|S838s8 K3~e;pp77[;{9s$Ec1yY8 f|Oaq>|%Y,×2_,rIbRUXX5X3c:zl6b$h6aLƀӌl8Ƴ[[ ۲۳;; Lt1L=ًK؛~3 /?p q0p(q8Gp$Gq4p,q<'p"'q2p*q:gp&gq6p.q>p!q1p)q9 +*:|[6v|;>?.>!~ȏ1?<91 _~S<3o=n +lE=iOV̞笤{J[{^WU+k5+oUVŪZ5n5ղVZ=o EX#e[5kj,֚[[sZ[kku:[jݬ0%eIl)涞op%ߑvfHK0~_ jۛIpg)ZJLxTʑH"|>t$_3ۇE& 9Z6v:#CLLQ\! &ZEewe*2G?RM#DgZvÒ `LJ$ϝaLItd5Ҙ"ݙ+i.wP{f{k^ʈ AOH,~fӞf7ɾL7}dx3/H⳺e=K|B/>%MvG0h?U6IoH޺/6S+4I4oE[eѣ%J$A R;=g缳sfv;=gŽkvrRX/=PBdsRL*J^E4C_owZYQjͩdi?%xk)=Rv;3(L\p>[=c]TzҤ31Ϡ"䀛 }9R-;;x&r \$qXHg ۂN}&XѹpWpkWI\Ur*ܹJ沶"|,Jr1/-l$<ϟ;Kٔ&,j,~>6l_52YYf$WS@Q`+M+*Hx + Iz6NwM[9V`C$WS ۷hA`pSjcWOrZWZO}ь%<^`d<%!nHzx\ Ρ KD@|s_R;ѿt/gC^?ӿu)c3 #©o "~R-Bڙ qSžcQ;_9#w'N7l^YQ;#guBGy}r- Zu[UubOE_"X iYUpL6G{!N>@e fP_3a)WNx"6RSWj8-sP-+:J%tn4;mJ>ꎵZO_V@[ux YKRIwZ99(Gv=rNhvo) u]CX4Vw^-%+D*ԅ_ɇAV!$2=P֌U22ӲQ'|Vf^Vsy_vv odW@H0Ì2!Vm6Fn(`x^[[&4>X>u5҄x+k +K'9"mEx,|T<['38l,( S +TD$,{%tŒ2v$pٮBdfLVYÓBu TT_!( wf]Ik[?Yߚq[}ӀCaO ` +4&)%0NzxQfPI ;!iǼpb乑bȳ6񧣏'> {yif3Zj#mOF8,"5 @}dh2~B\*4Kx69zt{NF8m'/FI˞~c]5~v*WFu3b\U֪|:1dq鳑_yfW#GFF +uXԊfgН0vl%.c#^11WG8BQq#2qWUGLqD#eEm\TF:2F~1rh䙑_ɡGF/ Y"fђ~ [@3آl& }f Oygvx&ݙy#|[#02a1L]ŴeԽ7焻 L%];6/ͅ)+".ѥ3`3ui /ˏ q/rq/#{]Mz5͐E$oW,q\< /Y]}~7g VpٕVueWeUVY \vUV]AU;yw~xnk~ok~߻^ynS.cyTMB,|ÿMX7WBo֍ӼH,F>FCŏdĜr!>F|:пYH\ pH?ɯwq;ԫWBO8~p2gY|'io$y; B_cKG"z|O/q~~CN39}Oz:#N\{/dIZ!f%%n':RWƪKYuY G;9y6??]N𸤥V(uO\?N)WY |??E&;Kή_R6}۰Q̛_on [m"YLI|wQ>sv \.W˒<+U|8H鲿}Ŏ(ʆ/3vԦky[3ܥN6۲duCVc!f2cM[wm$}\E[?WAs͎gfg݆ا%;-i6֡>l>j0}BR<O ?pm0]n]ɬjF[ܚ3X<7FυEAw@ϙ:sg%LL}!óa!C"xPUXT^ 0 +\]wuX줋ܦ.{!C|>vsM~?ļa76>it9~:OMqx_:3Vjhi&Bht XM.Âk6гooAׂ:,69,xxxxxx686moc=66666666666+*UtV`<]r g)+vDOڕ,*+3#E[{z;}aNܸ|!iBtE_{ogjN]'U\o␬ji\)-=p&2NţHwVÖe*ȞU Fj:kZ6ցua=X|7ל +}*UWb}*֧6FM7oB߄ }&MzLL[[[[[[[[[[[[[[ 뵱9s?9s?||||||||||||||||||||||\\\\\\\z}Cׇz Po@?~AC B/^z!By1]L s~JJ=#9F<#e;Uoy%>^Eޢ-Z܆XAH^[%Y\]"zq;/ ex4#u[އ~rܧqO?-mI׵$ IܟPBKb.A H,Z:إM|1 >˹B"c Tszu]iP:>v|7 u|4XG# ;>t|4Ѱ㣑䎏t|$wRAu 2OrxˡR#a/F~"e;^m珪kTJ}͟iz7S:m!){AҔ=OPjY r3X`_qH\w㛀$6Ҏ:,ӤOQ=a5{I-gRom76e ݸM[w#=X]3uEiZ6vlOQ/M jb_rbA%`ao<*\@˙3q K>̙3g` +AT}j5'u0 oTU/YN٪Ōop7zsgz~=|=jizR9RJeoֻklOlګ'[=ǯlVF3=Sq/ts|QH(R$Vo'efi6L'|şCުZw }8Е$}4v>Bm7>>mԝ[f Tzoi`@ T0@3P R0c'3ʠ΁gUv)%l2$$}Da6)՚]s},t,TjL85p.ʗ]pyLג P򙀝$ePUP  t@wL:sK/!KЕ|*aid|Jϊ%@ ATA Ӡ>*pO@(HP[{QdT$"8_ς90eçP0JD~W_A~W_A~yUW__ +З/. uIKB]***jG*tU誨[E %p= ԧR1*C | hGSF^o jjk(w4[w٪Ue;|kvݮXб7qHӇU j;m{πLo{mݻ̬170JSlѬ4>᝘%Ѭ9/\mjdӪ 6r^*l71`r5wy:G;9/4.z; `~unY'|0V`^/tm׮^LSJxm2oުx;4oufymRO>SO>SO>SO>\7 op}qI,ŅG$$Oc y|Bȍc7D"9|>K~Eɋ$A''y#$DVmSKDM +62_oG27e"N,$0$ҽψ{ +0O@Dg~'.Ħ^ѷM2LTъ⿵vD<++OG%1I#;/~kq⏵⏴O;3̷#n io߽=߹X[xgG|C[L=x?+>n]gCq=vV,Lj*~!pfG ̇2~"WWb⤟b9?^̘8{Yd}_ m?)+J3?O. rFn!G>KGWOyiK#i#ߣ6>&_}e뇓+[IɕgeY3]j=NizsZsw*[_.NMm?iy#goK՚[OSK{{6N_پ;K%:mWviaa_urh1\ = ^x˵Zr-fyxW`BF endstream endobj 308 0 obj <> endobj 306 0 obj <> endobj 339 0 obj <> endobj 340 0 obj <>stream +%!PS-Adobe-3.0 %%Creator: Adobe Illustrator(R) 15.0 %%AI8_CreatorVersion: 15.0.0 %%For: (Philip W\632lfel) () %%Title: (secpi-logo.ai) %%CreationDate: 26.03.16 13:11 %%Canvassize: 16383 %%BoundingBox: 145 -930 879 -162 %%HiResBoundingBox: 145.3511 -929.8477 878.6494 -162.4487 %%DocumentProcessColors: Cyan Magenta Yellow Black %AI5_FileFormat 11.0 %AI12_BuildNumber: 399 %AI3_ColorUsage: Color %AI7_ImageSettings: 0 %%RGBProcessColor: 0 0 0 ([Passermarken]) %AI3_Cropmarks: 0 -1024 1024 0 %AI3_TemplateBox: 512.5 -512.5 512.5 -512.5 %AI3_TileBox: 232.5 -892 791.5 -109 %AI3_DocumentPreview: None %AI5_ArtSize: 14400 14400 %AI5_RulerUnits: 6 %AI9_ColorModel: 1 %AI5_ArtFlags: 0 0 0 1 0 0 1 0 0 %AI5_TargetResolution: 800 %AI5_NumLayers: 7 %AI9_OpenToView: -609 147 0.5 1172 601 18 1 0 62 135 0 0 0 0 1 0 1 1 0 1 %AI5_OpenViewLayers: 3666772 %%PageOrigin:112 -812 %AI7_GridSettings: 72 8 72 8 1 0 0.8 0.8 0.8 0.9 0.9 0.9 %AI9_Flatten: 1 %AI12_CMSettings: 00.MS %%EndComments endstream endobj 341 0 obj <>stream +%%BoundingBox: 145 -930 879 -162 %%HiResBoundingBox: 145.3511 -929.8477 878.6494 -162.4487 %AI7_Thumbnail: 124 128 8 %%BeginData: 13452 Hex Bytes %0000330000660000990000CC0033000033330033660033990033CC0033FF %0066000066330066660066990066CC0066FF009900009933009966009999 %0099CC0099FF00CC0000CC3300CC6600CC9900CCCC00CCFF00FF3300FF66 %00FF9900FFCC3300003300333300663300993300CC3300FF333300333333 %3333663333993333CC3333FF3366003366333366663366993366CC3366FF %3399003399333399663399993399CC3399FF33CC0033CC3333CC6633CC99 %33CCCC33CCFF33FF0033FF3333FF6633FF9933FFCC33FFFF660000660033 %6600666600996600CC6600FF6633006633336633666633996633CC6633FF %6666006666336666666666996666CC6666FF669900669933669966669999 %6699CC6699FF66CC0066CC3366CC6666CC9966CCCC66CCFF66FF0066FF33 %66FF6666FF9966FFCC66FFFF9900009900339900669900999900CC9900FF %9933009933339933669933999933CC9933FF996600996633996666996699 %9966CC9966FF9999009999339999669999999999CC9999FF99CC0099CC33 %99CC6699CC9999CCCC99CCFF99FF0099FF3399FF6699FF9999FFCC99FFFF %CC0000CC0033CC0066CC0099CC00CCCC00FFCC3300CC3333CC3366CC3399 %CC33CCCC33FFCC6600CC6633CC6666CC6699CC66CCCC66FFCC9900CC9933 %CC9966CC9999CC99CCCC99FFCCCC00CCCC33CCCC66CCCC99CCCCCCCCCCFF %CCFF00CCFF33CCFF66CCFF99CCFFCCCCFFFFFF0033FF0066FF0099FF00CC %FF3300FF3333FF3366FF3399FF33CCFF33FFFF6600FF6633FF6666FF6699 %FF66CCFF66FFFF9900FF9933FF9966FF9999FF99CCFF99FFFFCC00FFCC33 %FFCC66FFCC99FFCCCCFFCCFFFFFF33FFFF66FFFF99FFFFCC110000001100 %000011111111220000002200000022222222440000004400000044444444 %550000005500000055555555770000007700000077777777880000008800 %000088888888AA000000AA000000AAAAAAAABB000000BB000000BBBBBBBB %DD000000DD000000DDDDDDDDEE000000EE000000EEEEEEEE0000000000FF %00FF0000FFFFFF0000FF00FFFFFF00FFFFFF %524C45FD3DFFA8FD7AFF7D7DA8FD78FFFD047DA8FD76FFFD047D527DA8FD %74FFFD087DA8FD72FF7D7D527D7D7D527D7D7DA8FD70FFFD0C7DA8FD6EFF %7D7D527D527D527D7D7D527D527DA8FD6CFFFD107DA8FD6AFFFD047D527D %7D7D527D7D7D527D7D7D527DA8FD68FFFD147DA8FD66FF7D7D527D527D52 %7D527D527D527D7D7D527D7D7D527DA8FD64FFFD187DA8FD32FFA8FD2FFF %7D7D527D527D527D7D7D527D7D7D527D7D7D52FD077DA8FD2EFFA8A8FF7D %7DA8FD2BFFA8FD1D7DFD2BFFA8A87DFFFF527D527D7DFD28FFA8527D527D %527D527D527D527D527D527D7D7D527D7D7D527D7D7D52FD047DFD27FFA8 %A87D7D527DA8FFFD067DA8A8FD24FFA8FD217DFD25FFFD077DFFFF7D7D52 %7D52FD047DA8A8FD1FFFA87D527D527D527D527D527D7D7D527D7D7D527D %7D7D52FD0E7DA8A8FD1DFFA8A87D7D52FD077DA8FF7D7D7D527D52FD067D %A8A8FD1AFFA8FD047D52FD237DA8FD19FFA8A8FD097DA87D7D7DFFFF7D7D %527D527D527D527D527D527D527D7DA8A8FD11FFA8A87D7D527D527D527D %527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D52FD %077D52A8A8FD11FFA8FFA8A87D7D527D52FD0B7DA8FFA8FD047D527D7D7D %527D527D52FD087DFD04A8FFA8FFA8FFA8FFA8A8FD337DFD04A8FFA8FFA8 %FFA8FFFD04A8FD097DA87D7D7DA87D7D7DA87D7D7DFFFF7D7D527D527D52 %7D527D527D527D527D527D527D527D52FD0B7D527D7D7D527D527D527D52 %7D527D527D527D527D527D7D7D527D7D7D527D7D7D52FD137D527D527D52 %7D7D7D527D7D7D52FD177DA8FFA87D7D527D527D527D527D527D527D527D %527D527D527D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D %52FD347DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8FD057DFFFF7D7D527D %527D527D527D527D527D527D527D527D527D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D527D527D527D527D527D527D7D7D %527D7D7D527D7D7D527D7D7D52FD2B7D527DFFFFA87D7D527D7D7D527D7D %7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D52FD347DA8 %7D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8FD05 %7DFFFFA87D527D527D527D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527D527D527D527D527D527D7D7D52 %7D7D7D527D7D7D52FD377D52A8FFFFFF7D7D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D527D7D7D %52FD347DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7DA8FFFF %A87D527D527D527D527D527D527D527D527D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D527D527D527D527D527D527D527D %527D527D7D7D527D7D7D527D7D7D52FD2D7D52A8FFFFFF7D7D527D527D7D %7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D52 %FD347DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D %7DA87D7DA8FFFFFF7D527D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527D527D527D527D527D527D527D52 %7D527D7D7D527D7D7D527D7D7D52FD367DFD04FF7D7D527D527D527D527D %527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D527D %7D7D527D7D7D52FD307DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7D %A8FD047DFD04FFA8527D527D527D527D527D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D527D527D527D527D527D527D527D %527D527D527D527D7D7D527D7D7D527D7D7D527D7D7D52FD2C7DFD04FFA8 %FD057D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D %7D52FD347DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8 %7D7D7DA87D7D7DA8FD05FF7D7D527D527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D7D7D527D7D7D52FD377DA8FD05FF7D7D7D527D527D527D %527D527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D %527D7DA87DFD07A8FD147D52FD187DA87D7D7DA87D7D7DA87D7D7DA87D7D %7DA8FD057DFD06FF7D7D527D527D527D527D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D7DA8A8FD0BFFA8A8527D527D527D %527D7D7D527D7D7D527D7DA87DA8A8A87DFD0FA8FD1A7DA8FD05FFA87D7D %527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D52FD %047DFD13FFFD0F7DFD19FFA8A87D7D7DA87D7D7DA87D7D7DA87D7D7DA8FD %057DFD06FFA87D527D527D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D527DA8FD15FFA87D527D527D7D7D527D7D7D527DFD1AFF %A8A8FD127D52A8FD07FF7D7D527D527D527D527D527D527D527D527D527D %527D527D527D7D7D527D527DA8FD17FFA8FD0C7DFD1CFFA87D7D7DA87D7D %7DA87D7D7DA87D7D7DA87D7DA8FD06FFA87D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D527DA8FD19FF7D7D527D527D7D7D %527D52A8FD1CFFA8FD117D52A8FD07FFFD047D527D7D7D527D7D7D527D7D %7D527D7D7D527D7D7D527D7D7D527DFD1CFFFD0A7DA8FD1DFFA87D7DA87D %7D7DA87D7D7DA87D7D7DA87D7DFD08FFA8527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527DA8FD0BFFFD05A8FD0CFFA8527D52FD %067DFD1FFFFD117DFD08FFA87D527D527D527D527D527D527D527D527D52 %7D527D527D527D527DA8FD09FFA87D7D7D527D527D7DA8FD0AFFA8FD097D %FD09FFFD0AA8FD0CFFA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8FD09FF7D %7D527D527D527D527D527D527D527D527D527D527D527D52527DFD09FF7D %52527D527D527D527D527DA8FD09FFFD047D52FD047DFD08FFA8527D527D %527D52FD047DA8FD0AFFFD107DA8FD09FFA8FD047D527D7D7D527D7D7D52 %7D7D7D527D7D7D527D7D7D52FD09FFFD0E7DFD09FFA8FD077DA8FD08FFA8 %FD0C7DA8FD09FFA87D7D7DA87D7D7DA87D7D7DA87D7D7DFD0AFFA87D527D %527D527D527D527D527D527D527D527D527D527D527DA8FD07FF7D7D527D %527D527D527D527D527D52A8FD08FFFD047D527D7D7DA8FD08FFA8FD0D7D %FD09FFFD107DFD0BFF7D7D527D527D527D527D527D527D527D527D527D52 %7D527D7DFD08FF7D527D7D7D527D7D7D52FD057DA8FD08FFFD087DFD09FF %FD0E7DA8FD08FFA87DA87D7D7DA87D7D7DA8FD047DA8FD0AFFA87D527D52 %7D527D527D527D527D527D527D527D527D527D52A8FD07FFA8527D527D52 %7D527D527D527D527D52A8FFFFA8FFFFFFA8FF7D7D527D7D7D527DFD08FF %A8FD0E7DA8FD08FFFD0E7D52A8FD0BFF7D7D527D7D7D527D7D7D527D7D7D %527D7D7D527D7D7D527DA8FD08FF7D52FD1E7DFD08FFA8FD097DA87D7D7D %A8FD09FFA87DA87D7D7DA87D7D7DA8FD047DFD0CFFA8527D527D527D527D %527D527D527D527D527D527D527D52FD09FFA87D527D527D527D527D527D %527D527D527D527D527D527D7D7D527D7D7D52A8FD08FFA8FD0E7DFD09FF %FD0F7DFD0CFFA87D7D7D527D527D527D527D527D527D527D527D527D527D %A8FD09FFA8A87D7D527D52FD177DA8FD08FFA8FD0D7DA8FD08FFA8FD047D %A87D7D7DA8FD057DA8FD0DFF7D7D527D527D527D527D527D527D527D527D %527D527D52FD0DFFA8A87D7D527D527D527D527D527D527D527D527D527D %7D7D527D7DFD09FFFD0E7DA8FD08FFA8FD0E7DA8FD0DFFA87D7D527D7D7D %527D7D7D527D7D7D527D7D7D527D7D7DA8FD11FFA8A8FD137DA8FD08FFA8 %FD0D7DA8FD09FF7DA87D7D7DA87D7D7DA8FD057DFD0EFFA87D527D527D52 %7D527D527D527D527D527D527D527D52A8FD14FFA8A87D7D527D7D7D527D %7D7D527D7D7D527D7DFD08FFA852FD0C7DFD09FFA8FD0D7D52A8FD0FFF7D %7D527D527D527D527D527D527D527D527D527D527D7DFD17FFA8A8FD0C7D %52A8FD08FFA8FD0A7DA8A8FD0AFFA87D7D7DA87D7D7DA87D7D7DA87D7DA8 %FD0FFFA8527D527D527D527D527D527D527D527D527D527D527D7DFD19FF %7D7D527D527D7D7D527D7D7DA8FD08FFFD0AA8FD0CFFA8FD0F7DFD10FFA8 %7D7D7D527D7D7D527D7D7D527D7D7D527D7D7D52FD047DFD19FFA8FD0A7D %FD1FFF7DA87D7D7DA87D7D7DA87D7D7DA87DA8FD11FF7D7D527D527D527D %527D527D527D527D527D527D527D527D7DFD19FFA87D527D7D7D527D527D %FD1EFFFD107DA8FD11FFA87D7D527D527D527D527D527D527D527D527D52 %7D527D7D7D527DA8FD17FFFD087DA8FD1DFFFD057DA87D7D7DA87D7D7DA8 %7D7D7DFD12FFA87D527D527D527D527D527D527D527D527D527D527D527D %527D527D527D7DA8A8FD12FFA8527D527D7D7D52A8FD1CFFFD107D52A8FD %13FF7D7D527D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D527D7D7D %52FD047DA8A8FD0FFFA8FD077DFD1BFFA87D7D7DA87D7D7DA87D7D7DA87D %7D7DA87D7DA8FD13FFA8527D527D527D527D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D7DFD0DFF7D7D52FD047DFD17FFA8 %A8FD157DFD14FFA87D527D527D527D527D527D527D527D527D527D7D7D52 %7D7D7D527D7D7D527D7D7D527D7D7D52A8A8FD09FFA8FD067DA8FD08FFFD %0EA8FD077DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8FD15FF7D7D527D52 %7D527D527D527D527DFD09527D527D527D527D527D527D527D527D527DA8 %FD09FF527D7D7D527D7DFD08FFA8527D527D527D527D527D527D52FD177D %A8FD15FFA87D7D527D527D7D7D527D7D7D527DFD08A87D7D52FD0F7DFD08 %FFA8FD067DFD09FFFD0D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D %7DA87D7D7DFD16FFA87D527D527D527D527D527D527D52FD08FFA8527D52 %7D527D527D527D527D527D527D7DFD08FFA8527D7D7D527DA8FD08FFFD23 %7D52A8FD17FF7D7D527D527D527D527D527D527DFD08FFA87D7D7D527D7D %7D527D7D7D527D7D7D52A8FD08FFFD077DFD09FFFD177DA87D7D7DA87D7D %7DA8FD047DFD18FFA8527D527D527D527D527D527D7DFD08FFA8527D527D %527D527D527D527D527D527DA8FD07FFA87D527D527D52A8FD08FFA8FD24 %7DFD19FFFD057D527D7D7D527D52A8FD09FF7D527D52FD0B7DA8FD08FFA8 %FD067DA8FD08FFA8FD0F7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D %7DFD1AFF7D7D527D527D527D527D527D7DFD09FFA87D527D527D527D527D %527D527D7DFD09FF527D7D7D527D7DA8FD08FFFD247DFD1BFF7D7D527D52 %7D527D527D527DFD0AFFA8A87D7D527D527D527D7DA8A8FD09FFFD087DFD %09FFFD167DA87D7D7DA87D7D7DA8FD047DA8FD1BFFA8527D527D527D527D %527D52A8FD0CFFFD07A8FD0BFFA87D527D52FD047DFD09FF7D7D52FD1F7D %52FD1CFFA8FD057D527D7D7D527D7DFD1DFFA8FD087DA8FD08FFA8FD0E7D %A87D7D7DA87D7D7DA87D7D7DA87D7D7DA87D7D7DA8FD1DFF7D7D527D527D %527D527D527DA8FD1BFFA87D527D7D7D527D7D7DA8FD08FFA8FD227DA8FD %1DFFA87D7D527D527D527D527D527DA8FD19FFA8FD0A7DFD09FFFD197DA8 %7D7D7DA8FD057DFD1EFFA87D527D527D527D527D527D527DA8FD17FF7D7D %527D527D527D527D527DFD08FFA87D52FD1F7D52A8FD1FFFA8FD057D527D %7D7D527D527D7DFD13FFA8A8FD0D7DFD09FFFD117DA87D7D7DA87D7D7DA8 %7D7D7DA87D7D7DA8FD21FF7D7D527D527D527D527D527D5252527DA8FD0D %FFA8A87D7D527D527D527D7D7D527D7D7D52FD09A8FD227DA8FD21FFA87D %7D527D527D527D527D527D7D7D52FD047DFD07A87DA87D7D52FD137D527D %7D7D52FD187DA87D7D7DA8FD057DFD22FFA87D527D527D527D527D527D52 %7D527D527D527D527D5252527D527D527D527D527D527D527D527D527D52 %7D527D7D7D527D7D7D527D7D7D527D7D7D52FD1B7D52A8FD23FFA8FD057D %527D7D7D527D7D7D527D7D7D52FD347DA87D7D7DA87D7D7DA87D7D7DA87D %7D7DA8FD25FF7D7D527D527D527D527D527D527D527D527D527D527D527D %527D527D527D527D527D527D7D7D527D7D7D527D7D7D52FD277DA8FD26FF %7D7D527D527D527D527D527D7D7D527D7D7D527D7D7D527D7D7D52FD347D %A8FD057DFD27FF7D527D527D527D527D527D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D %7D7D52FD1B7D52FD28FFA8FD057D527D7D7D527D7D7D527D7D7D52FD347D %A87D7D7DA87D7D7DA87D7D7DA8FD29FF7D7D527D527D527D527D527D527D %527D527D527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D %7D7D52FD237DA8FD2AFF7D7D527D527D527D7D7D527D7D7D527D7D7D527D %7D7D527D7D7D52FD357DA8FD2BFFA8527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527D527D527D527D527D7D7D527D7D %7D527D7D7D527D7D7D52FD187DFD2DFFA87D7D527D527D7D7D527D7D7D52 %FD347DA87D7D7DA87D7D7DA87D7D7DFD2EFFA87D527D527D527D527D527D %527D527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D %52FD217D52A8FD2FFFA87D527D527D527D7D7D527D7D7D527D7D7D527D7D %7D52FD347DA8FD31FF7D7D527D527D527D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D52 %FD177DA8FD32FFFD047D527D7D7D527D7D7D52FD347DA87D7D7DA87D7DA8 %FD33FFA8527D527D527D527D527D527D527D527D527D527D527D527D527D %527D527D7D7D527D7D7D527D7D7D52FD1E7DFD35FFA87D7D527D527D7D7D %527D7D7D527D7D7D527D7D7D52FD307DFD36FFA87D527D527D527D527D52 %7D527D527D527D527D527D527D527D527D527D527D527D527D7D7D527D7D %7D527D7D7D527D7D7D52FD117D52A8FD37FFA87D7D7D527D7D7D52FD347D %A8FD057DA8FD39FFFD047D527D527D527D527D527D527D527D527D527D52 %7D527D7D7D527D7D7D527D7D7D52FD1B7D527DFD3BFFFD047D527D7D7D52 %7D7D7D527D7D7D52FD2F7DA8FD3CFF7D7D527D527D527D527D527D527D52 %7D527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D52 %FD0F7D527DA8FD3EFF7D7D527D7D7D52FD357DA8FD3FFFA87D7D527D527D %527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D7D7D52FD %187DFD41FFA87D7D527D7D7D527D7D7D527D7D7D52FD2A7DFD43FFA8527D %527D527D527D527D527D527D527D527D527D527D527D527D527D7D7D527D %7D7D527D7D7D527D7D7D52FD0C7DFD45FFA8FD357DFD47FF7D527D527D52 %7D527D527D527D527D527D527D7D7D527D7D7D527D7D7D52FD167DFD49FF %FD057D527D7D7D52FD287DFD4AFFA87D527D527D527D527D527D527D527D %527D527D527D527D527D527D7D7D527D7D7D527D7D7D52FD097D52A8FD4B %FFA8FD2E7DA8FD4DFFA87D7D7D527D527D527D527D527D527D527D7D7D52 %7D7D7D527D7D7D52FD0F7D52A8FD4FFFA87D7D7D527D7D7D52FD227DA8FD %51FFA87D527D527D527D527D527D527D527D527D527D527D7D7D527D7D7D %527D7D7D527D7D7D527D7D7D52A8FD53FFA8FD267DA8FD55FFA87D527D52 %7D527D527D527D7D7D527D7D7D527D7D7D52FD0E7DA8FD58FFFD227DA8FD %59FFA87D527D527D527D527D527D527D527D527D527D7D7D527D7D7D527D %7D7D527D7DA8FD5CFFA8FD1D7DFD5FFFA8527D527D527D527D7D7D527D7D %7D527D7D7D52FD087DFD61FFA8FD197DFD63FFA87D7D527D527D527D527D %527D7D7D527D7D7D52FD047DFD66FFFD147DA8FD68FFFD047D527D7D7D52 %7D7D7D527D7D7D527DA8FD6AFFFD0F7DA8A8FD6CFFA87D527D527D527D52 %7D7D7D52A8FD70FFA8FD097DFD73FFA8527D7D7D527D7DFD76FFFD047DA8 %FD78FF7D7DA8FD3CFFFF %%EndData endstream endobj 342 0 obj <>stream +%AI12_CompressedDatax}ے77 +UOl/a33{BAuS٤۷ٗ6?{UjHU(;o./gr 'Lvv\oovXw x1ї {ߗvg~ݟ~f^()֯~?~Y/zz;\>sυ]a&\ 3bz;ȕ$ԍx+TLlPzpƕ ny]j( RU^p}5TaW%9^^-77v]y0m|x ,{^o׋[ \bq6ޮ/y^2ryyţ/z 3zp;۫Kk5VU/f0q<4?I^v?-7mv}5x/R&_^]h .h:!JA9~Eϫ/|n,3_]/w?lV8 +5\4 Tx\bzyX]ZW 0- Jo.7oN} VLo?uY^C[@׻r/|>X^lqq{<yyXKbx^zטk|IwuݺL+s*fP|kݚkѵ[t\zk. [:\_|_,wkPHb3k\˗kX^_lp\:ο^/0_js.r-7WjָνowjW5~q,>5r|zqE+X̫MW[`+n73@Woqo"}oG6Х"SizSyy'^ݖzJ+Qs +l|D!Xurq/p͛5;E(:> f|ffj4_Ks7oܸ1W`!n%B +ytbd.[\Ђ0KڬhvvzZ/no`gbgDL{56 "S?^=L헟7b(n =vvooE]^s.E6`-H.)H xq]]Y-֗WaW$Dm/o/j|ϿZ^ 9 \c[W ]Okp-bÂ}y<Ë׀/vr~qnޓf_!wa_e$7~mo~yeA{X8M߼O | -~xrufWDƷpr`~{?|t +$p9wX]7_X;\o.X~fPk?nu%.O7W5Mo0Gb[?IHuOG DN> 1'dVmj4s}* [T-oZyq L7Czy E j͛9ܷ[ &"_ jy9xmG%ha#(JSeQPd)J^fjfjjEJPr%0Ns(b +ee eTh(\]y! Y>22_؄&jfF H.313(S1c1ZT + !ϠLRD%**UUUjTI5f\gZhsҥ#==3=eh |bxfCYUA9$%hLgw%ʼ-@AŕT͍gyx!gY1ҨoMD;Yпԯ8erAᗰuhj(̆%x"ˊ>pt+)I +\g/l&DOFd:t4, mVfوd62gP.IX +3\i-|S>Ԭ`s4|eʌ^SzMWX2ԶT +P +$\ƳY6Sd:׈RQ)aa"p*4̩M'oLeǢ|3OB43s(9GT`911Z"xbFj j6OjnI=.T |,%S6k4NkFzT娠W?W/=cD~s|i"K^^HW$ o +$ _^%>Qq  <O*+$$+d^ȕ/)LJ+SCC/d%a"1jWr9ϳ<Bdȑfи̥=A,a9v2d<M"ۊwI +ȹ)8Kf +c[F0_BIh⤙8 y8o8k8oW0o~s8 nL\bK>,K1#2>t1qtq>b0 + & &uu ;-"3N Kg+?u촺,O@N ,1QF`vZrA$4S"+H'5ЁV*_\iҒ4 RC^`rZ3*+\F0 +ynR `1[ ^k]JaIP(?!B#*KzJ"Ԉ(PtVi/ gS*(fh@ 4(CERTx0A˨=e_ +2;kq!YJA!iI#Y:9@hJבMc~M@8|@$ ŅXv^ ǧV +i{[]=%$I%$0^ +E:$,#=lj-E*$*#jj)IŬ囓4󊓶JSa%M'U4)KX?nhFd(TZ0{[LGf<2=Oݴ6JҴ$Vgyv^s|9y N0S0b/,xL|b^2iŸ5RZޱiC6-SV2"njl,sCM3XH\Y15<u}Ƿ + pqtd}a%U+N nnP/hÆTZ-B[9fe{'|*[dnн.z,5gs/"]Y+)#FB'{oƇ>7>u_7va _X<|M_~w؅ + )#*%M`BHG9 +db|GCO*#! *4qnN +t+$ :֮iFV0aєfǹu&W #\#AAܒidQ{b + !ڸuOg7n͍>#uK''=P<6Zj/?96i#L4@ kG+1),'p1gnaFZ2"Yi#ScbD #Ӌs/:eCf0%ab2Su5Ɣfj\5)g&(h3#UG-S8}e5FYz3MAxV5coHlmDPIjPe0)2ƕ5*obq 3T/#錥.FFN>o#DaRgtJgmtύ}f}͝\E*8^#R[Œ4.u̻f^'̜nO֤b>XDq[S(8Ec f^}K[VsjS*H @^3݄YΩu! +I$qHSU2HVو$.*HScEP#unj],H3C,))](\U)aMUy֮?\gUy֮?\gݪ|PTN+)sB`C;6*>FRWh[p-"c~FgJР!9Z$\,ٱ p(^xܪ۠xX~<8m,܊6&0Vw^8!՞B 5Z%{ǀRiFan&φ?q^%;Q՜kNWRȶ 2V'Q{ +/(y֠(Γ>?ӱNX8߂0O[xdD ŭL;CJ,qBZŔ6 ;Dk)`v۱%V֞"ʝ.TA!&0` v NbٱA.ɡq&RX5)֜'?]T##B!̆v82!6<BG;3̦ מD4b܈ 0#6BQPъ2>m:qQ2y~'`xEN6ȬP9Ē=f{j}iUUU]N.9cYYŦ3LL&(,Vr_{uiֲ+#3]{ k{1 1KkYDyԒ&VP)B%Zh0f=FI%U,"{k,=m-[m^lNxm%N-PM@C2ġcL q F!!EA " y>Pm>3_¶JmWRmk=ek׵ͽ{IDi +Y\Bd^!ˌ%q%@FVd"=:&z3PH>MaZ#Z(e6 aE| DbL0_Iq4}!]%nqư@/c 8Slsҿcb[G^")bGRQ5> Cf}S?tCab8u-0y +BJ1-Y#mevyWᾠ(n%K ;s͍B1~V8# ~XHQDŽ&s&~qn /lCb=e%ACy ũ#kC}IfXUtSIXr +IAa -ƊBGqAz$ԉOINd' M촡I924٢F6|-.uOi8~ %FREgn"!Kg]o[4}zeRRw`*$G+Lh_, ڃX.5:e4󌑀5k %RqP\ܦ$خ(Dx1$UP@Nf>cu:19K:pI0~Aƾf̌h-E^)oߛS: DSob%v̞cA1C +>:cAuF^,)ḵ3~|Z:xg~GF;A| +UI/;M)N-SBg r?)$1jj3r.B189NLhR?h +WdBTɆMUҗfC >AiGt%dF}(,.,{* ߹(!;58b.nQtذ +mH6Ҹ,Kfe|4"'Mrb6 &Ye]Z31I$) ~B2?& gJQl]FӢ)v<9(0&~LO>UV;|6$ؗ12ږSFr,|6$Dx]0860o7I-'|$_k\lSdsb߾$s99X#I8Fދ1-0)۴۴D!7,|(Qtv7x077i$xMQӪIi['(TDh_1{eqs9h|j5 rKg“5BڶNFnV/+ZٮX‹%XW.C?bvܳye|}T.~}`+/BmA% ?Av ~=|FSMI&o6ClK3 v Q.EZIf>ޢ`I{G>Kf;"0bai!M#2;Naq .L0VS0 RrFNftq("ZjrzHE;rCY- pDz|`."^u ,EBi-rpǓڔ2>ZF&rb5s~\Î6]cnoޏ{ǭڶ鎒A_ŒFPa2E>=r\FZtw{MfzcfWQ)U~Ac0.Ik7*ٺ i,J=[&Ȼ۾'hG٬7  y+2X(N*R +)ZyԘ\5ckZnGƖd"()nL0r֬Ef)wf`֖h080N@G~OhRl*~)R7O~|bT6Qm??$ j2RlN`i\8Z-AuA` +ĉ;= ORDYCNcn6D6Ŭq;cZ̚S9lJk?PEFZ#fBP$s6ҔXP8zRK$g6=$ukNNئi=jNy8wnזBǜD8))ÉM!#ER:,IHkfL4at%f(cйhڝ4 7 ~9j]5ΚykMffۦqn#?}#7p \363p \31jPCbP!(:"$xG6;8MoK%2mU=niz9W~@,@"8i5L 14JFpM+l؃;LW@TqqCh~OgV zŻYIWÌyCZ (MPN7ۦ>+VJG&8?<9 ,5:_>-B㓷|5H`'_sS̬kR Q>ٴ֚=%Ag-n4 }ަ<;:b_XmݱK=lxON{+kycȁoSPnhE.{bX/wns,r(Y{zTjzmά9>Ue-lVhwJt +v8yꞹ6\c)o.x܉K:9/$M3N\\O^rg/ӗ\p= Kz+YM%XՌL&ֲdt7Ȣ\!ć513JRL&Q.cp҆݌}̙O`T ɭAE$+6ωC;ۭ09#lcc[lfm19:6a(:#Ops6nMi3f(3 kRd+1vO[c> uh7F̞Es¶3ҺL1`ܙܮ2_b|>O:\BnmYO{^ (dSX_=m4,Ι:vutZb7_mOg8D۴4c9ngP|\}Cja!އxVc5z, +cq̘w&ޅٻP{n?Aڇ޻B]g\qis> l`Af[cuu粮kx&K]DfQװø,EHcd9 AhsG/clMNVC:򐖽1Fm"%ԁS*PjPs= R-I Ri`ELhZz#?xbrzy=vf @:IYEyU\(W sT LACm 񍄾 \353p \3یסq",u/4xٱz?l6൭pJE࿴Q6j@*~ܧ3R B.ig4%Bevdg.eYN|39_? O;V=V;X64!xu͹pD9A8A)eK- ȐV]I<5I癏|ImȘD rTFߦ3۩1"_jKrTMtE3P_9$D_븎?ܻiG>+fMj [SOLFtr8*Ρdw +Nttg9n?X?sN{$6b}T"G.$G%b go90JҞP2䁊H$}la6E2{&_|;^9gq'r,&ĨH';7`bABvN dN#{W*'AL(7K5hˡek?`9>X٤h@G>JQEw=w#¸sC$d8gJjG&Tc]fzNR +<5dV|؁KAtg#Ub|cfuV_60!DG4ͥLoU76>wڤnemPkwSyE7tdydZ'@wglqe+<:}^&7 ƕn{|+Vs5r~3LL}PK"(G8 JLO}mmĉcpoNv J;q*Q-g= lq"sB>-J,Msyu6~p)͝6S|rJ^ŘE$py79] -p4*d؏ӻЁ3+>^58R[?WGvGoqO=)̍,::cT޳@ܯ>Ч;mU,NMFX EJ&&r+{.rN9KIP}=9٧do6*2c8ec$>ɇ"͘й`GCB\$0: gGdL{DJwAΜV `i&Kì?52{OM#2ivǸ= K>xAˁ3/SK=c$ff$ҶG=fHw7D?wGf- #gI +2(Th G51УB +=*4P!rۋ yㆵ <,z^e\Zx:{)V3TǑ~Յ5w;۳ꫮc3Lg{uh4m[a]|X%~3%㴵6u0vǺqZOdY84%2JEyH>ePHN]"e {&{2eQ" +wKTΒf&P@O¶=jGPJiAb>혲34$,(Oݭ'B&38wiyݷL)e* 6|ԍur߈KF^~J(SӅAaWO{]]IڡG MXܫ$;8D%bv +{ql.fVv$(=QHISPI +ZtlQ#T3Kmί8OZA5A%TT6RBX;ΪVWi-Հ\,2u'V&gV2>%( zkdj['s4\BꪨܝUU{2X4M|GWMORq R"T ܗ9Id3ԄUrPwVy\OI(d`OUr@P呶Ē@*'$T+qt*=Up|3'SyBj:5vC8"=`LRZ}Ѽdff'OR=? /6J3;i"EC^狚`pxwkT,YFrգ8QT,Ͷd,5j ̱4V2}=QA3BTk QX -lJ: 㮨 IKXԅEzZ> T>aw +(GXN186-O:bw S*N@pd83;tx)Jx; +E"3*ar8ޚC5!ᇧju!qȸSY›AJ7lK].sG1V^-s~Aՠjo5[ V>УB +=* pD yL.ǪysW1·cǏ +A{L_N'cRsG=QQo]n.>]J pq#!O!99Oh/S|߼Ky"W޶j59L +J5C#[SE͙HYiuKHT5՚P?dЬ*Ia߈-ffϽ702{^:ó8|t>wEŁV_5G3BQrr?YļS4ej_*!j|xPzF΍k9=Nړ fsָT(L˘f(HΌ(Oj!pӛ[AUDg10Z;諑7&fܜ|r'ǍΪ6 /o +!Η[|i0ɚ|ro&Bݟ#ܟ#\ܟ#ܟ#ܟ#)':7?M{c'w8|ct2>{7'64g:Udөlz#6k[ma=%A}jM>iwf+]E}_?QVO$tfY,t-Y,[>ʅD&4*Ms!R#9l)CsX+,rIMUӡ}l!- 0Y3m/|Gapy` ,i֌Eգ1RI3kj%Oj1T+hPC +1 +Xz`@8*䃯lpI?~o&Bmu jOJܭϚaզo?37&0,\@hO;jR2C-j+5tJ% + &H +>ki^E2U#."yN\}Ҟ{*(59*!dqDz{C}*[is⹬S|@rur!O{nW٧•+E9p>ki_ l᪃Mz{9nukem)ԕω׎{!\uωIsb[â^1cWYl;- &HR"EpN*/O9% DD籴q_O> ciw,-qeڮӑcw?kK}qd;֚"K Qexh+Xj[oTXj{UԶ-8.KvE}57S͇eu!>o=j1X-z{mtiё_*F{5Z͌UUkvQ?c`a,ڵ2JUw_r fD8*:V +t]W?U!kUǍLQzWLut5艙e_o=0í==3-?(nVq }yq>LW7fmgfV ΟV׃Owۛ^OprkCm~z(v+^+ib%CT$ARGP4 #TCQBC,}̫*@*]ⅇbmGJLDi[!=̋A v B~pհ«le3_7UUz֥cV2#8U={p$@ O-<(-WϊӃtN ID]~̓, q +ܠ YJ"P8)#H,@t(J+vhe9 m,sB'm vHK7Jz$Jjq}W ]ِ5RYΦ +)<#JmLTJ 9n1 +p",FmHD r[ ل\a[*uzP@bޖ98B'wwI GD&I#Rz!!ɭ:-"^GVG᪥u]G^痥(-#Yp=C 81c%v]±tvU=-w#(le^eRe־Jc^Ye{HN^* ,5E{H"t˴xBGN*tLlǭspjH'ꊼT^;AGnV4L%(.+VVF{ +xT^x’Ef+sQVDiq.\^kЀxVҩ,,-rƋ̊3H*m'WK]Dce}e%Z^s@H:TdSUC2+] )ܵv@I, +ARV{BH* +BscN q + sAmxQ]~Z?@[HVZFnh煳uH7+{m35V;*@uvhSKAS*PYRTRb 3.иs~׽Uxf~z/54G_=z{JԹz3 l0ן[οܤ?~-~?{z،׷/ެ֗%AQGǽOP:)P>_V7oyIv>7ý]I鱺 +1|1zzjxsbsju Fm^tKIΧWϻz23-7G=co1qn.|ZUG n}Ntjh0nnY|ydqӁ\\/c0OuWğnEש#f Ǜ:hojLYǤhL]4 RЖv9Vھx{3!!{Wcɫu>A%[VEz^|b +Sv[wuJ얘uo#\ֽoav.|=ezѱaN9Mo6͋n!pO:FTУo=}'}c[쯧om\mZz pׁQnpO$'?XA7?7宷iTv +M:5Qzz/2x<1l=I }&?x ;_;ͽ|93J)xo+ +d +\/.~|`o Z {/T]ƸGl8>"xo_&Cի}@tEѻ~Dr O}Cu+dn"#VV#4ЭmISPx9QFMU7Iß.ڶ:5X EܻוzXS#zG! &$~];(# 랊ޟ^9 >PaصÎ6tЕ栺%$=NXS임S:dc )v= },cπs'As`̇`Ƈ   )O蘿Gd|$KF]ɽ"\tͮ#O]8 2[>N  PE9:JM8>()+R|m#xg"gRA[[d$}8 \2wGnJ8?\;&=}2cO"w?ve6_|[l_qYG緛:aY{l3Q/~t~پ葭6,٠[z{t4'L޽#Hծ[5ُrb,uv%=~#e7>&M +|0&@NJ ا_Vǧ)O:5))x<>wTzh7 p~݀]IstXl?7.o閌&Cs_߯q]ˡS>sdc.֓d%3tAH?B \b} PnI:`zu||٭)͉ک<&cq M-r7[;SnViZgOIf;Fӛn᣹SCݮ߮˫_'or|^^}n j rԩA6Qc m'ݏwk@<?:ksq,+qIHN2h|NK^v˴X1bQ[p7c6~}XlVW(}:x٩߻e2O/:~ЎߞXLv},ZZ`Bx}Pal$%S +CX_vd:^3"._ naz:퓴bӁ"}hO׫rѭ +bwtdoBC +.{$U813u3O:p[g.с3]#3E Xg.eK}, x(-޻y!?[Dnti䝶/__f39#?]PapCŧŃw,mn뷸Sw<v\d^^gx~ֹ`<@oф\Zm=<8}(;5xN6wt Uv[:A7w՟P>h-c{JcCS3N󞔮Bcbysߗ8Hv6|]]D1H]H~OV,֧< HT: nѕh?u~Z_tle}r\#r@ޫ!w@-ϻ'NэgHݵyOի3]%,9>| +^} +ozwss:zv||[lz+ͳw!2r Oet_)n\ukX6N-oZkSC&Uqyy@l!omuj|~7#ʌ.޽mQ./@rƨ9goƨ?Yƨzc6FYӓ1FY٤zcToQ1Aj0uOI7>4Ss^kWvmWG`3?-&;fi}v6GhC[XCj4z|.M9>Hڰ^|XcO0t9M}PG_y9u#rtl}y9>XڭHIOmigO`>Չ\0Okէ:N֪c?V}^[eͫW.k mi4HvA^äu?LG=J{~\nĽĄqSո^Ԋ(ոSyױj\Ɲ3|PոM/-'R,)}:c/5=vn$G@@{ow/o͡.}ަ#z9-PxiM`֦WձnmO6]Os=z0:1;?ezTbo. ӽ٣&nqqX]ul o1n.|Zɻ>{:5d7W<~>zD?=dβxEG.:ecpw槰x0D0Utt"zSllYܬ;&ZwO]9^nѭ`Sه[ЂvJI/~ԲrE kCz\@Np9}e{\n^8t?f=2RSk]``W;0^"-'/yb +!VX[ivfxLk-vrɹ}ߗ7`p6v˿e~B2*?_ >'T2?#\ ߱3\jP ^+}g= >{5{glevh7 }rz\-g03Jq_3EY3TeQ{OY 0R*S u!?ɓ?,kr9qa&G@s9}g;}vr]s"L@tϙ(<M\?<LM]Nc>S +#}"|{̓% +Ӑ^Cl/&w畅B/|O^O^d0O^ۯ'߬/5}t#1uk9 vf۴R^{mL6@)I#pN=GE?٫SrDa\mK WZִ֥[Y,:SБ\ B-x^WCYB'~ȇ,[J!ORSbzz$쬂Ì) |*pfj@?|=7B+ ]p6H=Z^h \IlŇvJ" vCf+NfPWJr[D뽼L"ǎ}VO^qHPny]T3yrjƯp/,x]>@B]n_._/o~[/_>=RH*GWB+Q@qO4iD&G9 +-s\1h ,`~ڴ15\.w@^6R_Ksc<lx^YX.;߮ov4[qyB#E{2;I۰H+'$mzH{HS XH ߇^=8zH@/ M,>BXK\Q RPPd9X.$VnAtߙD0u@եDln +APE<{fSFs#wL;T& Xh/vMPOQP-/^TEՏ]Tzi/VYOϬ̿3il?=K g1Άf2FwJj]@+@G?k|gi+}>!vsӛ{>ve^F#!ƍ]0ଆ6_Y gUtFE=7o*X¼VUo$Q*nޭ A;QfsE Q{q"?i H?64wZQ=6,&J@aE 4,N78܉ފ淐V>v|c7dCj~G%{vw|vI +@D^SVR.d9/L +lAiXYgh^UPx1T *FR#+CJ@vB2[z4-TYThbkbhC)ixSVM~C s%ho$+"R3X!pR`F\&#>i)0-g4s3wFӫE|R<Թ6j7a&0 *rw6L% Ie2jݹU *@碸ʹDYF|& .p33]g q58T6p>`E +B*.=8/.#.9ΞȌLiUD_5Lg;aJKTP݆1 ]$dH90HI͓P*BW*"Fx4+yI({InP p "IqNH_WW˄3R+]8Q,J熠ePyV( F=׬k=A݈jj7Z=ޝf_w05VtTuV"d₅+vDFlř\gm3RZl5@ZK +i9̌-@~rPS +c `fHT®i*A[%Z3IhW¤taKMS2R Jl,#L@\̈,1&ez<9m(@-eNS$ TYKEneU$!ىP + *0Un**A" _3ÅJTCLZྡྷBvs|@P@'HH.А#{̴F-W +T(8g0>hgtXTe +..x4)̶P@9='29GUi ބR [`8 */I‡M@N>'O藂P2h[F " 1}kJ$ˢq!)ɱ0K*⥮{cL 8 92Q$U82TTv&SOP sqP=UY7B,W窀5*0Ye@d`|#.s#'+*}MmO5#ppCtW]ݽKJhP{\ +j'e@K"5/ DF| M**|'}.4Q`A)*32ꐖR9YPB Ʊh hQEŽWfY~@9WjDafYѕBmBw +T~+Z yIc8R"xx +p5ւ=c\Mwmѹ~YkA֞1iVUTeQYYsΰ;E&gy7׵pIYkL2ij(*R E?@D8T[ ˜@`1+%Ekp58IuŰ24ߒ1gGsE]+2>DzK~)'ø#a(JĒ {Q+0zeۑg|L+ +ȓe(2I~ }C|q:>Q18 3v7`OMxuF DM1iv +rԻ zo,~hlt5Ѹ zyt-Yv7#IA%PֆJ<@;(#J /'Jj"'|f \ApF<3 +29(&Wo|!jfT(hUJ(\Uh,3qΐg(s*z*Jl-NX{!M&Eo@<Y]K&z-wdK ʌ{N`^&-wNq~*I!R| g*+5,tUEWQ\hF? n`|_#gd|n(HԊ 9%3qGhHt(B))P2 +y/>1J<49=ii^ gZʆ^ WTl$ +$)ddB|u O˂􁰉g䄡 +S;wߺr=p-.O2{̎z8UdMp%RQ6^km%KyADX9I@h%$PB3*f?NUup۳cKՕ:j!,Pʢ @KZ&6FJH`4k蜥!咂P"MO@) Ax5pDT!46-M8CNQZnk3OMӞ~봅4IW$D\3 /ÛѨE?%Rl2e7{aY}DI]o9{ ] ] ,8}vn[9y13 R ^@ZIZr@UF(sm :fB1>`:#ӰӋ]`UpR+!v,Rl唐AMȭLomCQE~ʩ(%SGWzC rldО]):jH 1 -`Z$t-X.d^愓8=/`WG|JN%gNG};CP/Y @]ܵTs'9.GLnv. )`2So^x=Rq)Rb"Ÿad0l:|n/5};dB%!Qy:L{(k&:*;%xh%1tIܺScF啬S4DvkHs9]6hpv^g)E2x/u};pUVEdS( +,'ZW1 2 )ީ ]@!r + -Ihw 9(.>Ȼ%@ytŦ ma02L@8E2TxQoM62LF;V<]]9D_B)cVd=fTY(0wQe~͂S:@ rH7,ʚ蕎*쨂Y gTE6H: D͎3k1 p[ONy_Sb +\&PLmags'45LCτ=." 0x_SX `$ +eSoS~LT(c֏~-NuR + i@/~h"E ڀ2}Zmq/I!u3eh&ij/i !Do u +S1~CG'K#L>*x1aJ\4E4ElGAVQëG0:}_{Q㯛:T y$+t'`6 u̱xFH_AM ^ҤM;5qM`Mߚkv ϧ"KEpV +^i/L*z>s#d ;l@LH&gaC({d(Lc[d&闌2p V")j,#( nuͳ<9&/~o(po]DȐAFi4/d kH)BSْ%L& Z&"*0ubltW/U{[ܨJ[`"y +A&&zda3)!)&3dUEFmh-i&$(MW[gNw9l0!Jb_;s?Q B-PS_I!O($eTC CMn;CSzTu&6a8!ϓd2YU<_:Vpf'{-Fb)4 r'HK܈"12c)P'DȓD,R- +aإb6]Bh\,8_5KG0")v)eal1LQE(=L Cx8H}Uћ^t A!z`! @B%慨 da^qY%Fe|88x=\-2ob +:G +1 Ù虅DȐXo_޻=?F5t#Q0MD*/&B 1(AQDh-dDu@jBPE&*,J{Hh`ǦKIPFǼ&H)"c~ɂ4:Z$x>:h$0eOAڠ"E]PmHlЯ|/>  ETtH$Eԙ2漱$1Aw 7$L&Q#lpNP(U]C.t:"&,Q eW `#@>>݈">tu?]C/O]4ʹ`HҽHHod PC +1Rh4E뙮2>$7P 5CEw)hC{,л Z0U +OS-DJH񅨧hJ3^ + +‡ %9DI6(PzLS1ЦR DrX~cI8IɛoSsH1 rC  $@1cbHc lHŌo1ix0jḒw &Ȼ)B7+6yt77ʎdduQPQZ+Nk=xn[ x7 _Y:/q̛-biٍ6˰&nqND #pT+b VK/^#5  M]ɔOBoiN6 %Yu3s{6~{3x7#p TBԯ@&= +b Fd~P(RpbstFFr'ĦR^2MREV=LSdY"&'n߇mү x^SǞIp=xa|/5W|hѳH NfL=";!Keuv%ԇYL1+NȂQ;$xHq|JXK 2^2,“Q4UJYtJU_KH- +}i[X0_(uo-tgE!m-tLAtgSn8˦2=Yqe7's5sDDSz n6 ԑiYg(Kyagq*]< ݯ('`y&mFLa7e%^أ8o7{g+AhpI_oӔ6D8vp`| +e2DQ(:dTqG1$JY܃3h5Hn8{~yBrwQCA J EO܃cSlY"oRl["H2_Fj]lYKnKݲξ1[_;HpvCL{dogy1,kTuݘH\՘9We^>(n"["+}Nc'fltx.c0 @aUsh"Zhb1]xrlwVN)%3`}bpA(N.XAaT|ooE9v;XEb J&ٚ< 2LbYy +BuH#R| _ҨfBb^ZA <҃12ze?g%O뾙;d "b^X*aV?ǨRL iC'KIs$*DOAx*!DL|c0Fb7wcEs ]DJ/Gbb0~R̤M*fQT&mM-%=y@'Cǝ8d1E 0D.H6@6&WɲTN1O6'4 ?Ld$>c{<%:f5Yv +0ɐZ06e#'ʘ So%̨ d@ɛV|H81D'd-(v`=]eh_'O9:`aSt4=dbjGs8'J'3ʓTLuXJz$ #{2D[mcÞЋd㬎J t 2ƾ2)ѵj(p>U`OtSOi6Q:U"I.̸^[ Ӡ&L<|En\m"Y:eY fzJREcŒBM )a1;3'K̍8ayIf!6Ԩ3 Hfe4Rw OiO(?*У`>g2,xiy_H5ЮIRnd41]g|(!zkBJe͒W<oYaáp9)FGQ~\~l܅9 wlcVQ?ϰ+VF%ǽKqx:%_"]?0[IւI(TVk*;px*k$OER5PTV@؇9PSYdE%c]6D>&i չ+ĬRlF)|V;&Ά,s>SI/CЩck{BHyBCݷ9}`+ApP(,|V ~ QkvCw%r Fj]\7L,1 ]`$ELLjbˡeҹ韻L61O$ܢ(= k + bi+9SጘD1/KEFHސdJAǪȼ)c8>^Yg0ĩa4=*jS`)BLv"YYL!1((=G*RF#є &כɩnwxL@ +`f?mS4Z$>@vQT0N"Hs)st8^d> ӭŠh|*?y0?qQrd2&(ky[{#4}K0& U|4=:*P2GZL Q`/^.x|c%B*AI^~b8n) +wH|^)|@uq,$7(R"Sdݒ%y{?Js(_sϼ z5{:]_̲v/ 9OlkYCZAf":̰o*KeIL(H$?3AfE;A3CT;T;t v_,g !QU p@RY@ă#6iMèC ^F <ҘS%֘. M[@oj*6%= fF+ZE?OQo3=+D5t}Jcj`ZQahٲkܲUhHĒ}3 >+AaHn)qZ(%'{Ӎ[³L%?G}Sr~}HAe #ze"ySmL,E !1!>Bba>A LNREK " n`h_Ѿ)0? \R]ɧgl{_y {o>1 .yqHƥMy$bjvp$.ԃEviK>vE쒧R.إeѾ}Sp٥.BJa$=$ڲ7DqaJwcuz#*Ssө':`LT.1 uK|e-ec2(6Vb j(" +Y&AtJNj֒ޱ_36f{űDoDaΤI҆{=.RӹbH@#kG3weax/P[2!Bf l;{`=9~!i%edK_l(+&Q 1/Z>.<&XY(u*|#dC՞[jU8JkҖCǟ޽vc}M nnQbe& neoF 抯DѰP%D#*Ql٪ZFǪVc1*}7s:+X!m_lCD,j>&sPUDGKkt {96w>n¨~ոރDJG e0fqΏؿ^֊FȾSDC1 \?О??j`= b > Cb!BN1 +"F[($SFEaEt2C2^)-sDc`L0"Ɍ# :;3|hѠ/ Qȷ#0)q>[IX?YW!V22ES;!_C"ߩlsv + x8=oWȉَ[-X2-4njwU5VBGt\^`j:hq9*^SEMM"Ujy6g&Bf=+=@R"3,rh54aϑ&[ C|;`גFW펳#zAsFm .HxҾ\:B:&k8.@z5 wulL`s]Vs  CQ؉(u+;kT|*X +&O ն:ȫVK3t텼Eف3٪meu 7rsFTa3y1MR,UEE_qٹ 3`"WK}H _Bۺ,PeǙs%ض! OV S]+totG 0 ˯փqHv&/"yuP d&sWLI׃ +>KDnyOW|{"GulXVpP\ވ1|}Ȯx3+,c0=]Ob A$]QI?C_>~ȿw5MߏK1R웒 >.ƽc.(uDʌ?𹀏۱^^z5^^"Ka(*&3ļVM)XDyP^2 d@ cd샌}>22A>Mƌ2A>ط"vx71A4|A&_2>x/MyX?24fCL2(CsU|Z폡Khq6d!EL c$%4̢f;.f55cal߇p>-;hQ_QQ(V!|e^4fxhMalxlc|01!V ro >xPHz#D1DL +h$ +$#j.hn|\w-{oLR#(.|d %Ev/V#/o1nv"Ɋx ;Y5k!AT'*?aҐ* A&bU<77*K.IdzB**e>DH~q F~H(EM(n* Sbߗ}d ؇Ŧ1&|'P_d|}G ׄDY''?c_|{QKZv,J>ks:+P`/ـ?Qԉ6paiP6 Gh0nΌָԚ٩vK?>bw0faZ?u"j"ޟ5f鎪l^ݯPQ%j/LrlOVէPjnJ߇0*r8;|VުTDש܏>C\ZFǪ}}#9L"߮:/_q7~9jyD'`;.4sNovί.w ϧpV&a,[[x⏾} |ި%kI_Qur255M .DQ%|YTuDq8oͶ +fMe7PdUQKI5zR;Ğ`5`?ΉB72-i0?U@o7ƾ^#LvErUGRL a(?.Kb0py?asЬϪV7S?슿5OK.ba@Ge;.yUoUG+/ +ɕN Qo?fK( G m~{=0}jOm02ڀ.{wZo %wS7FMCFoSW4^gE YK]Ϛ"=qQ4XxldA肎)Yptf Ow6tvΆո2,4Qƅ](y8MESM g< Owfnh8w*꟩rǪxSMUE o H]jM"BWTCA +o{"nR຦j)Z@`ƢfA!Id2 iAW5F Kg')w4 hR;ȖhITwOSnZfɈA%Y5\+d$N`S.Q) TP\ d:loU6CYar.o)m{ᰱL1d!e]&15GZṞ~`wqld3dN3؏ IH/4m*$`4h)HCI#1C‹>$HM2%P!4Ef4Q$!EQH3~p8IXnq*F)߉T?2ND)ggTdƘY} E 2 "ÌHp7d/R\$Re٪")tU`\M&>Iг^ *qLIP4YF*`B'P BIGh8CH}B6P5:E6!`Mп@K]lNgjxEm

2evk`З;9%oG? ^T=9@ wڗ/6pBN>f|~u|k5śۍٟ[OOV`s;m(tOSE:08s&tI`DXg~DBsU@$:h*L6uBJ |(UHqTk eUkt[te{BKCUS!H_I$1T(^>#ղ 9npV@l0Vi ]ޯDԐ(W8MPhb3lw,F2+YTϬ$8 H\2.Ȍ_1A&t^$VQ$fr!`…ϑDP#m 7v+1$z,j ~9@jw6$g?U|)_[c$!E wi0km%ʎ. _p>LynF0&l׃{cH5UGst( +&0;,^ 5'9A@i"w>8JX$1h^5EsEg6lk'ZXHLYB cL;ُ/07j]&isE^hְ.]nVƅp^=X.=Ti.长Jx|F(:u-Igt^KݎR6^fH^_.?Oz{jP̃Z\?4XrOn8_a5Sbn5|7?y\Vf;S\2gΚ$[h [\f%Mxo2k ſ𾜵|+ޟ͠nu%XڷO@ |FOBY'OBaխSTk%,4=]wU]ןW:yCoKtV>9ѹF:g? 7~oq^۬}_G`U6Jʻ~T5/V5aPkg#WcɿN;j_h!f]K??%xcܭu>]e<k2_lMכbkLRt0~9h)fdU4t_;n^Bq' *Tndu4G;nRJ&@I[y]|j(|?v6袛l0~'߿29!j s'޿j~勿᲼S_X}|DJQ |/5.gҥ<֘Lb sohK4UU,^iWKUtMUsmSrh~jnY4WC {K쥼5?1:&tE'vۭABZPmug+l[=q)COٳtNTbBLH_/tV1.=^6f]:Tt7zyZ*6"Pzl\4:PԷfo&^:"%=UY;<7f[6P;zuvw«oJXɶ(;Un~ՆP!_sEiJ9ұ8hz*]뱡;hSk”NV惥HsA~=yUą|[h%Ћc87k>$fB^uz=y1#k 8^Ni6tju^Z-)l>TZBiV~i4/f5GǏnWUs uZnNi VNT}+_r{#ݦowW-:N?pVة{ 7 '0ëJ.rYӃou'GL?YleC]΀KnGٽ=o|w\50h#ڞb ;hegS&_2Q٩:h~I Eq[J8i bx*{Q݋:9#`hGJ >nm+ L.v=;̄lsYc9⨊{bWQ"9Ts:N,u^"W>̷\NPP&.R woA[OM 쓍#q(GbSnJV{%csyXL Н (|Y!_l!=jK?{CA@rFw`!,H 8,oZ=vy%XA +VfN=I zg{c+e#EXm q6,0o1jNŠ~yA6\KB)X6=,`^< NAu MTҫjm (T/c|{imv4XAզ} 3@K΃ՁMLF pȲh;s$&0X,4r`:5 sV=V+Yq'ߝ! msM@6@rs.;JULvê6:]Ɠj2!&aj(_`hB/ @o{^ +ί!O09c$,20ͧv^B('5FWd zn<%ŝa_JQ^ 2KJ>jM?l6JYLoNɾ;I)?KÌB&k6ϓɷZ]#xZ)li'^l7 . efy2hOoe:o=^Qߚ;mㅦmG Wq] IC&|؊&?cz:mg|웯>d1 ; ^@buxy򻤀ޞǏgvC;n\ogJ6ؾoۛJxĜ>]AۅsI:AXl.|=7 MbPBB1Zbr 5"HulOevXNTm9Kjpxgf 9|kz"W>ȫGpR([+[]>b_*陝L˗/T80;OND 5}F K[=>LY\ 5i$LW._,}Tǯ5!U>)"}'r >Mbkq#\Ol"3/4yy9NV;g&b|k:i_9~nxyTRЦfut|EZ™0^K19 'k'N,Hm<ISSኔړBoOYOԳt<j&+Sfyzv)4SVy}ڼ{|8h)qvzWG/ӥelegn";_.T_>uzӭN,^OD"3WGbo."_lDB9٩T"ۊ\Ov"H鹪E?e#r>.啙ٗLlޚQՙx;UMDfvëNa&/T'Ki.c3L2:fl⠩Jٻ\kW9-k׋lekzx.V64S[[6sիCsg]8Woej A&&gVq~93͇Nl~5ՙ^JWO|u FB$ZS ®.NSRxyx^Ov"χFl;yODKRzhi-ڼ]K}V^*~ꅗd%l,Fh<?zz'G?]F_bhF-&ncL۪`e"6j侼==-,)u9}X>^7ˀk |ETia.RBDV+F2Q<_sq//M] b)6vREi]BlGYR^3S|*א5eT?Y=/ߛ[sP&/M.*k8\-Lwzt鎺UK}RI&#Z> ҂-,$65C94js5ռM7Kig;WņSBrx|idB1n6Vֳ9u%u53-df~kK+ 듕dhʵUiTSZsUIWSY>Zܟ]5anJ]J>WײZ޸_{-|Zn^'7JGJqb`K;T~`aovUmlFɗ͍q+̧RVZ>YފVn.*_ZK\Vۥe9<$f^I8h Cbg*j'"тKdO ;^)uRDZXO>涗g6 ca~.߮.ԯӳϝrLY/q^_Qs).ηw ʶ_v*^|~y{6w=hÚZϝU+m`ʛ@/̜Ѿά?JH&7_T.nF5<<;JωѢT9k۷GQ}.u;Lvt2*]/}螄˽#ݜ<96"6:N7gX<疭i!p<: O-gkgٕ㳧npP:ONg/úxqX8(l?_'rD2T>1"{|u8zrX^4_ qW7+J=˝Pظ_/]qLDWV +'}?(ym8|S~ 珱ǽ9Q,^U?+{OɆ[O[l.˞VOE"[h/NQb"Rub`/_ҖK'E]_[ʾZUKbW~)oO$=f^:pE>iVJݮ*wՓj(糖-=ϭsVzHs+_[>1j=ѪO^7[kzAJ7fx(. %=mʗJac% SlSޟ6˽d;,ǬVt#eݰ/AuU96|vwTY.z˾qXlf2YGTgq. $L;}s^8$JGI`3߰QƑӫCJXj5T?h4]r*HF*V9V?:P*ިybsn@ @&.33 Bͧv:؞5-P1hGC:V_oV%"ݦRu#KkXOyJ '8q76fP'F7z*Z]n:\Us$"RXf᭻'{6F7ݚs5I|;1vf=F]߬s( +(tzmv=j+3dg%#h/WxqI<6fCoƀ]|Hrr2;[#/K1 [c-}t(j>߳`=7UZcm8@ UZ<d +Zs4^,qv ,>NXݭfwp 5]Y-` `U=R f+:,[l1 +X4x*o\z5굋Y۪u\mTڑd:qw DP>$:,魊.?2iXU/Ts0oUJ, keJPA:jp]j|h=C]<5O11ȻrX}[VaZˇBuk闲PZ&\tJl:JM]n/jeVГ͇ŵTn7XІ0[r]j' Fe^rԼ(e~0_Io8?

zt& 'T> +TJ;w' έb%K25H=Dnb,*/n p~z܈Uxvx?d~=mJ7W6{̨ڻ]7Sv 7V/aGq"\ʹrxI;dնhAP 'Dduq7NĄ_;B[g~NznoU;eg@^cxNSJʹf -v{ID8`dv"aZSOA,gj^a:YPJ'Kk"`'Q/ݾnf&{6Dfav^" uF^FBy?`"|Z&  iNUCjJS{V:yD}{Ч;c2,tKx~j>fgwail/6N&"kRHJh+W=s:c@gyv6q}6~Zk-xw*ie!?5&"nu'3ge,̤8MZ܆GJ-~廏80ѝYqxr jzqc]WV=)X,upMm+inE}!{uOunl]Xx8hZ~H;`]N:>5ᴡ\rbmmF?hſN&"T@H7fA=iCw"Te&<m+l<sq ́;AE2gtLe03TF&`QUei8eNؾ; ZIg-[~(q[{lzA`:N5C(0ن0ho8ug-G߲m8 ӫ4<ª(?- F!6O`P_{i׬o-`[ g9MIAeAiӋbs2PX +I_am ɨlydzur'hKl]-0<6 y|*t .\T +Rᙨb$aA 3sAߖiG9 v{؃~:A|qgti@Ršp=ͼ ;Wz~a*}"fݠ_[^5bf?qݢ\׏ݠw.ҩR挠 +Y!sPhwД!ݼL%+wōGB,6` rC4<$^c_VJ }3Ԉ<`72gVdq"jpo\OVZ >vJϰ/miד,D2a'@Ri:*2z)Q?P}bqOPvcxGԫrZ]-VOgb3Y ~tRp*]k +sw7)u!qB(SX&'Z иORa/no΍+pSH9w.g-.‰71:_ڱztv]ŭ*|z XoW"6E-z>7o& L{u~_YsmmƋam{wRS;bB jl{qnsjsmeY>ɕ} szOTTpa7+Ge8'%\{[(Dd$t+~[»aAZf<&m .ڻ#EoyafZ􂯌-5>;w/yZ4V,rBs w8]u{Oڄ:z.͉۟甶RelX)m.\iݥҹx{}0J6?3!2gUfQWb0g) teX  ڒdyq75k2 XJ ˡ>smOoon-kqb~6W^@m_g}Qp-ͩ?Vmݼ-O{oou}2\)I44#@:@Q +%L+Q{~o饗z\nm]]aQ/dVJkІX܌C,nO\}Qx[Y9]0On~].1ۣ? }="kHSPG{{}\^~<\|oO]wqA`\/ozV[t1L룅psmy?s1+wg ͱn~{ܾ>l/|SL[c\ava=VNa{H/Op +h6h_t棽+Lm|C;SsvkWvaQ7]NN콫Z؂ɸ 6dtTJp?{w~>HYjZwS͇Qc~e}.3l}|fU9oi/~p t#lbystkmn9WX:|"~ #M΂lX`̃^Q.~#7o`WN_Wߋڅu{*kyG"vȄ;[_,1`u3|l.{^Yn_VBV@Znbj;UO{7YW F6#B~% # F{|^~"pG{u{SCe^0vtL(}n/L_L,5K:îM^/-޷}ы uueOm?k 5ԕ 2E[tbT͏Sr^G݇Ouojxe:ATʱ[ܢ/}arJ-~|-dZ+#9: @fE{|tǢygK]=p{zS\@U?ՉųE"c]K &Mm|nDOڗ͏,_ǥgnkYSj.o4Wb~H)ԭѺIB|ܕw6~V}J;L$Zח5#SC[-%t󽻾tj=P;ݻUrp1>'t_RZ';=\,N$uTf/NkDQFbOS '_\,rZ7 ޥ^GN/&j~"lo=aآ-t:I?ɝt+|\/-hrVyV+uV|؁N~+y;#^EOҶjjS}>N?NQ&YdսT__S߯y}*1JG͙ t5OVh??[eU^"5wwʤ[soω;Қowc'ab~}g2ۻo7S6j7&{າo)Z_m&~]фR[:ރ}BS?n|ko#vSqSq닇oA%kV'[w #_s[ʈSӉ{L6?Vn؈G77QٗהKbfsp۹;HWO],5Fz_mΗw<-m9h| dmgoJ0-;!9nM2 s#8$Z9mmy${C )H)5Ss:F9c~F;]OYKBOAкt&_ +vjwލ=h5,('w:ܾ:kV=2h_%tz|Ҩ´)`S\'u#4Wv8dSguxO\C7 -*WS#Sɱw=6qPTlF̹KG m|^YѣJZ ]s]/bTT}b8S-9"-85O>23y| =e,?sŻ=n1S+…i>K!\oψ7:XPpTGǗ ;\Kl#(RQQ+j +0 |iQekߏRI˱zt$= P{`%3rtȣp=R2rt5IwQ~7c䪛DXz8|cߪQ&]-W"پQƮ0v-XzUq&IE6?B[C1ZC2Dp^+KjimϾ[gDrl +ܹ {0cg'2M>]q?C"G=]/rݨ YPGX]MPH#rxݵe.}1&ΜǑ +26)$lq=|9+t@ : 6f7z) -ڟlf74b)abhJ:Ya % |ԉ߶\1lFxyL/ n=aq~RTNk"vC(=q@~8 L( VmgqD&]aΠ[H7,2`ƼOp^n/!aS9bFLW^Gq}XVƯ[Hɺ[Z.]r Z*wc[*:U=?ڥLR}DlX(חQЧJ΄p"'wFCMDķ-m͘xHW*1ox=$QQ3,$?H5OlϿ頔h]\u||>)J@Ű[ZN!86|#ɼEvG-Bz}Gk{(k3'=2 +Pt4q[~E>tv:G^Viwѩh*6,$"Q1Z?a'=F,qU*#/00']@586ɾ(E¦t-nJIA)G2]Tk){R!K8] "MmgۦZ‚ZXf '*5 Ui|{gpx': 0v>z0,?,\wHeb.A +5lfU8cB.luD!\#S2et R45%zofG}oRYT[;aG2\C;]@Y+K;M2k>Xh0&mbDX5}$F5#1e0 _P7/A4U%R%Z.%k#y/]X#TѻDI(#k_l!0۶G3>:籎!<_a+aNmn8r[ `{. .@AEckQ/6|bMjCT]Ua;t- VP 6Lׅ+m i^Jmx}:RB6 &Oe0P,Ëv/ȤE:I(k۫6'Âbbd)=Ul%.pkGt =>X ՔuWy.P*TgS3njR7$' \@$e$DoRiK9X-4{7UB=6&Br)prZ˔|K%O`CٌJ8$LbK/ u[YߧI`w]_o}^^ +KPC^A+ .i.^-[ ]z;S:^ItKg[C'ԫU RC^A'K TUC +nu_5tt牢.\4ː+'Q@֏{8gm} &Vs6r g*-[iZm_]'c n1CiZ6UZZ-I?/R`f;A:=[T# +d5~ +BGl,H"}XF,e+H~>D'W1~d*X1/&DkB޾|Dj[G* Gѵ-̓-guψXnq6!m E2ӉeaK^C3>J4n~8K?':xb\zK\ ʓ·W)vdJ*VRc#+}:4S +IĊBS+tWPRοrWu:bٺHPb1nsdp]q*"}}#2=FdbO%ɉ~uoK8}ԊyOj{j%7ޱle`Eje[NCi,?Tj3˱exۍJ[ILvz+ Wra;}/Cls&iKvD %^LșÉU8gHUU~cѽHPtӡn@H=HE*Rӏ굜N'4@REh,OW`YmR +'b/|t_pUOJ+3:R8?v׈"^Dx3|}Zp@1}0j4<)bxLUq( n2o3v_C~u2WW.ZE"?4]|?x;MXdS,WR UP2)W^w63.ZG3pKy.t# ?ɷ$J-Xiӱi:|x[xJms\>c`o &9ukfOLχ{&].I^_ڽo"y:޷n/K/ooTIϏem23V{NG3K%d)әt{T$ ɒZ:6j:Y-]qj:@QV#쪚Nft2 u3jNQTjz9!$NVK׫FNӰU9j:ٜ NT ?߲j5#|Utb c) $ɇ鳚.4<|cNtc NTdwt:){5]#.ۈ[MlsMtZ5V=T,Ϥޫdt1j:nInt'[M'cLK+VM' s%Wt2$g%٣cM5tytSm3|z!]rԺ뾺lEfһ.ź8N8" {NR8eᮟߔ2 7Lu>tHNo7e>v2I0b϶0W~G߅e;QhV+NL!Ǩ ksẫo򒷨bELL.2X7q-ʸK(c=M_N*8F +ONӮSBhHbk?ix+Ns+cYť9Iӓ(}X$99Sidw #3}ܑhhdă~P,v-f] %W,HSeK垾%cjH * hXi ҺKJ)+GPJ87?MWҗۃ%nS63G{~=RBV`/)+Z/iyZ؈k}\yݙ2JW`[=d#vԾp<'Ѧǎ+}ǵ>ms["˹lU}BKuAوMIEfgŵkf0GCyz; @&ftwU;(̈ GUSr]X$ON-ΈdF}(WZGkR}B*vft8n ~&s%Ά^NUσogCe/P7z_gCM}elVdN^[bEPeý~ oKT^tҲ_^qˁ~_v>˚߽~~9b\K_x KWtr{{d)J~us;/K{2gAu_8{[I߫l÷ߗ^t g/ +7Ͻ~鞚د^0^[^/}&׽~ ⮁~\6["eu{/h[/){o0l[UET>KOlr/ӑdt~_"~Wy^,'_Z6{:yYC9ʩ~Ǘ +7>٭~Sn+ɽ~bJ}'_ +쥟{B0v_X~_z~^t=2b=)Ӫ^Lj/$%?m{U0R+~rQ IF^${l#&D{ׯ{҅^pe+`t4G7\Ӱ sUR$ӴnŘwݎU9dr`CP + ˜\E|Q}[v&c?a`V??. R6Q~f?kƕ֯wEi}~,U~vu~*_UewzTv/ߛ;`r~(﫣MS9|ZSοGr5SPf.J&?-'mlgk;?mko ]98ٛ}43z;Ykom[ep|5iSm,{> +;dK=㳛/?ۡ+ >It\S6Dk"[ZS{meim9JR4t<[<aVj}~M#l$d_>s*|k Dn`q1SŶZXvxorQ_F|kY3 ]|y[Z\;<(7+vqye<Зet (JpF&4g}T1D4v?VFk2bs5UvKpR͊}0^˷~1¾;M(Ta!ԖfN4iRz1+XbqY|7`,!26'vԞ\RIY_Qqz;_lSX:3=ڳf4iL҈F+/Lc/N0u{EWSZi=䁵>W7FOݟ=՛+0F.l_肋ycI@sk.TCU0!i7|ҽ'5њ~Ayx[m㔜xDkWţD z|m>}J)h9VJ=Zt0}DMOftnyWN&99>Ms{҂m<3|l@ |WǍf)ۭ'S4J_*}K3dmh%›&(:Cx.,q "12!lt mE]ą{-&"{re=A[[w|!+EX!wfx]eTT ֪,tr?>blK9v& +rv=o1|?8>Xn\=-T 'qvmXݎqiHhb'IF)L㿬6_Uf4Bٗo7^N`ſ̖絒!]o \Ǵ˕ނ' p26puA`֩no>!~THn`0&οZl>ǧ 9g |Pba&Er,JMhTk&e мdnkEyp٨$4T4$+ d "oz~3xSEMX#l| /5B&-qLϋbrXJ0"[cazpܝO}A Y=ɏ+f~ɏmWVRi."y,Y#:YOjG +AYbLhb[nݔFǼyhݴGԶ^wtu=?#Ɲ}kRH(t}Wm +;M"k<4RWVͅZQsnow-e KuG_|^swWpoSHqL]X6S2er !ASl-~K9d9ułgbbFMND׾ÌzRUV|8kW̷0\6/~ozJ r֔vdZ;07ڛ:8=I$^I&_,u80:!>op/ʱEVǗP$K'_45`rmc< bfژZsfCMiQ{ہE0{X ^.ˇ& -~5ҝ+; +(✹V0/V답{ݧr fYoy*Yh֛me6ߜ$s5 _UC+\W:ےyvgCt;].OtPMKξRڣn*_Ft +Ip6: &,; endstream endobj 343 0 obj <>stream +kێ vg E{4J1;H lU>`e@ 6x2۴-ȋbmۯqiXIIs *"` Z|GHڠ~FU v'`1Xsv)'MDvƤ\A|R@MĶYև=X03dm ],Oۣek…]ݕQj[ S#4N4j>a+ MyfJGݗox6v+R7ƪ\ fzf̓c< ZFbwp[V70~\=-|9BO;$eGٯNtf|qLU]m|u7nܷ0Vu%uO@0SLȐ tI70!+dP}3k=̷B?1xfo +C ^n9C \5"sqy{|jM3@~h]Ә\<|ڄf]|udyceL fsf3DjyO*tv/g=\M?[~P8*}a0W婴Y0/(7П}h;J`;F(ט&߿:dlW"}zf&Cw2O{ZPXԞd1zM1oۄ݃䷭ETu*xhHgw[w"6|rڡ5ni7K6DWh?7[dm5=~#9w_;򨯜Md-/FIVzۘU]͒^LppmSlHs@sRyx/;d_dDo:K+oW:RwL݀| KSKR5CɈvܓS3 )霏9~cldD>fMFEOKvZM%ym&i=3c_qII:ǻJ J #7%fbp6"yh3WD|؈eO>c+v{%?+[iշ;>LNہ<;QoFx_ C<>ٲct2FoLU +*P +D`B{)--OhdW% 3?< h_hi^Fbt<"^D&H 8m#ԪGkގeGf~1WwqD?GGގ?#QD\/*GrGۣ3AQя" +.GY#Q?#A:{ Eoo7m׃P % E%:aCaCq\GWGFDpiS!fBqi_a_;pz* +ٽy?sʐ:kC;& Z<~>|ޕ_sw?CS:X_iM ߟ*R%.6:T=7á}~FC{oC<~=<߇އ̩Cm<6῝RuUͰ!j;`چe8Z#s +C21tz a;9U94 KnR |\z?yo#njt)[!ZghW]E2EG/w M:+0I:NUu]{~+zIK5ڡU_w+R'&qF_su1Vh_C,?X[̌ mh:0p ++Wnh)yHdsE禪jp:UW7,ł'` + ݁)3TC DwԪڐjrtlohVUUu a;Іa(UQ\^ LT[:Ιtj[ Vm {pl=RXڮU5-5L \T{crvWrmXmX8<"ݭeÀo0t뿣7"h/Nt2a)JLK s@dX6t9K9*fԁ3Tr,f^`KGSaZ-`< t g620p4Zm{[uKVpSG\%`Mtr 8r 1$6rrWF[USg ЀWUz04K6unj%y8m^9b؄=6 [aZHhs?ra=€q4qm@iUC"Sd8Ar"sb٪!:h @ ,πF뎭?@TAAbzeYjP{\ + +M8@p-@&H[։N,bAϮE鏂k4(Dᘤ@,:jOƄYk +~ b Ac;$x* EqT= +B"rM:8Pb zM-zUL RT1ףY'.7D6y. 8zAmݦ5,0( + * UɃG{-A{N/+5 Q +I*d;Sn  ݎ)@IkYD-6XA9RT?jo`bL՛\Wc=T[ +K*G\1kC3PkߏϏ_Bf$ 05T, Ӹ"m#le:͹0L]`.X0+LڠH샑* Gb!%ne5US\W+o0YivK1]dU%) +%/q.>^5! +>-Eh Qj [":NtD3u[=h#HBd"ה vP)(44w6TN{-F{F)RS%;@& +aU5mNCq8p  I -8z!qbm0':VtBMu%_+ ƈd +t% `d>JR/"i0@gH* A#h:6ԽP1 \QCR +XUא=ˠ `M nqPlA6r\GPCU$VsL0j!-hVSџ|F92=VJOwЁ0Y|cJ<WwP:C\W#֒&g]5⑰/֨K><9J*UDu L(3p. q<,l ?4d\"Pl!2T sp-=MJ&̼?GW3x`2抱3'32t*HUmBIzPVD%/F!@pkCq&%X1#3?mF!Rљ'yTb}-UmA:k0d Ed[7@!.AS&SobM`1%&\#5WPogd6>m1:3/ӴAZ8a8qcpRI5J Ab I +b +ڙ%\[,z 78'('<=R>8Di|(g` = ouKnb ijbћ#7@77Lp݇q~l! jAFk3&A;l٣Gף:#:;"+]Y&idI6|cHAAR_UUAͰlB<0,(\\xh1oI@t ٭:M-t<?O;㒉`~Ti3m$=1MfɵMZ)Q2o#+slMx2\ r'J V%R5\&\Eu-ɃG{/N|N+Ĕv:=\k1M g1xvz@ald%t`wY`]2 <8RL?x8@(#%Q G45&IOD ؆+ԖnTTED +dI< $'=?#@Ri=H%ijlRnhb} q삤۰/Xh50NnK8`qi#@"Qt؁myִ͹zUn{f`0~A-M'cRS+ZA4(mI<;>B|uA*| KCo[;KlS̺iq<RB/HMN՘F '‘>hqpy]_#HW,҄K.N kphMrفQ/! m $ Laic&hB>5$=,bAp3B;cS ( cbb &͂Ӧ pML ,@q$H}3sCc4d^eXb{JPU%j-hЫ Tgq)'6p,_z Q%Iu:pH}1>Nb Ϥ9- KOh@tLX.+?( ͽ1]@A6/H=F:ֽB3 Q94њ#I@l-/;v*Hq 2g7Fd8~t!]vd-R؆1 +2b r2lB#;go$ahJ"irV@CA.(4D A#DZℇt[(Ry!/\1^$ua{('LdPEc$hqC3Ei/8lzuU7Ha,r-tSڊ{TLFMP$1#$pu .{=F! G<y%4ʵ5@-ࢯq8a9™ N9 #b^g1)0~.,[R~: v +Kℇg +jiв'0;#4cXئ!4EU\1"AQ!S g*v8H38l'N}zq ɘJ 8>aÊƞΊ/ 0#Y >*d&׽ ]=fDn8a90M/bѠbB,:11=g=uޚ-qb7=u b x^]L@A_v >Wv$XqsLBΙIFf0-q0A@W@T.oZ0jjLz pCHPn73`nWEHvU*6$= blCN!2a<Wnru5ۛssK@'彧Rfℇ x30\[ԈӎPR02LK*i܂YJÊƞm|EF  8"xP|`.lV[0 lD.T_M-NzN#vtڹB59ERIqāLۮ'(nP<*sSzQ:B: ζtd(bqSJ%xqpucw^ae+ΓN<;Q;@CSlk| 1Ö=2ʼnSg~3 W nk:ЈrtO5S}Gc\_Êƞm9א Ht ~ڎ dSܷW\n(!&×@bi #iunfq度*@hXaBk-\bnv +)L.liGA1(&J B#8b KoK V5taqXcO Sӎqxk-NxN&t#Ek0y.؂&Kf]U&GX 7ȃXxqxkG3iXC Sh7*f|rVrAe1nF㴇I{qWMS{7*}b )ԉ}DH\Rڦp ~;.4=Li`X|ED +90@|ť`p) ,@u_14P$;o +v ButOdT󳈱ݧZѹt[–4nE?x 1;\w02]grI~xPl BftxZnxfڂWLxCes-[~'S :hLdh$xo,% {˾!s Y :lt e@ t1(m@ +;R-=`!b a긍>x@loJfd'ҚY)1 +p fā*YH|YVS7T q{D99| +W8Hp9|/%N"ц$ T6GbGx@K^, lv A9>ptG$w,fq h~OoZ9>D^й:9 f k3o7,WE1[Ege=DL>L^'؎TK1Kwis{8Sm{1`Ҏ[%KwxMd9֨9 ]Yo,H7&ӣRy] 7`+< \&ș zY0V`]^E@ 6Vx{9Qu#xpRsZkچg $7dgW V4B2]: ! +2Ӈl$% >D'ֹp3VC|y7Wq#>4ȘZ  #@ +lM`/bnЫ|{gj09.gp1g<ћVf$vžET\e^$F5v>g$H [U=h`Y3NOQ@w$:1,^.-M틴+ű%?""(|K;xAnƳ *W)e6)3+x?+? v}2ѡ_G`3aL@"b^rqZ,q{"@"w)K!CiXmOAj-Lu;6m~Ghp *L E2ãjux2]ڨlLY +N³R\n$XtfWaBDUqdIzIC4nhxVQ.Sh H"dx@ bA9ޖ,w60gt-д()gp`r PQT|94aY:tr6kJ2$n+A'%'!4xf)t-\0h`v$xBdO+pM딎.G/loˏ!T%Sx@HOvD%3p1ȋhF/jq:.&@)Z&Dd[1";_Y"+ʶXe&ߡF~[:']Ye**:+Ї`eoteƬ3Uc荄ЩJr+,-[F..]tz%;zR--3>cTR`s{sΎRhl4bE ؅D2/?rclg|ϴ Z$()At5ctP[j d * ⤱Q !@J@"BB!XIH d +ԅ.4?~M[db~po1F{g1e2Nn0&fq8N2oN)3?޵WD]gZ!Z32Au؜᠊ɦ,ͯ\kE{jg^>k [ttU툝xQJFU133u泥4lvw@45X0hsKWو>&Hx \i/܈ȶ#6N-piBQwF$ l/ qye|5%&tͨbΔM© RL$IJDYHtA-^f鈢p%ñR6~F0z@君$ܼϹHox6²m&RϾDNHq%8TK0żaH,QIމ fhl#N"Y٨waVh㶱`(fJ @JXeaBZn ҋ1=gotmY"`bߣP0r_&H6m@ A"UPnuƞWadVA+!|vRD̥ĻJJ1`qXIul(.`7 W(+Nu_Ai97>un", XKc/h#2IǹB5!ȘF2IXeaxeQNe@Dbۣ vq`XXBE W%R[q:armpy':'ɰ9p[*@?'$k  +Ih2A( lɯ U(B ?"8y;A1Gc_F0<:+1%# 7^9qZ1`Ǡe3{_stb,~ Gk3Q&>+*K,q6S{]L;|U:8G~yo?_xxX L-,8 Pyj/(kM⊄+ԃ + '\/}?n5)y].R6z m1` +85$=nHDNJT7׬ ` :%^ŠᗩmلC6~ϊk8M׿<6ZV Z8:^H &b1l6a.JP'.}΋= +y%j+OEq`,8Qs* j秆SVu|]!u+mP_f;rl^ɅŞmc0gCSNG]DJ6z3[O~h!{hed9,52{ O1)"DīzoPpomŜ"{TMVBlPJ"VCr1Q7QA\!<>2?^6}Ijb>l&x2aBK4Gژ:UVLvYZmvP5MKQ"5nnOŻCafZh3y|VS:}?&G[=Ehd(Wr+ t_QYW,|!L@|~WƿWd>n0C.fMMof;i$^YH]I CVffw^ (}Ύ,'~N7-@7(M\*wY{UJv;ex/6{rsj.zs=iYNr=s>~"o3M0kqW"@P\)}ڞ`樷2#*LK齃Ee݅ܕi{g̩+ d%+D6<|sȞǽl.lg~Bbz6/^Hֹynshnj^Ж{;k)ިwIǏ4m@ ^BŔ.ITD*9y-e\ym2Ӝ +Ō?Y`W6ޟ,%߀DŌW1D%΍~Xck]G6mve6RUgeupZBP]4%-~\6}!|}NmD)*i>:/],@ @`eoPX%.$ (6_MrTBl +cY}=k`Uo)(bB[N:^X_WZBɩrjޅ4CFjd Zjcy| ɡwP:]3kb(E[=*tu{vm7:$tJL;X{kGz=n P]FT>GzLuAa<\zH*d2aW`9aFƏw$qDB:rݯvy',_My,ӎe>h\]ˡUYioJ|) $sV` +#?di^g_ƯI c~Q}5)ңW9>j8d_7꽷U0Blqe^tO=z=n &$*j*^+4 X["+xpQ_@,}rM]h0ncN7o?`԰|UN!oUa!%B׾8;m +{+=n(gqXSڭ[?C\ "h:cE bG#@$b)KyzsYu*#UXi_bx=A2ӣO*IB6ae)2v9(" D,)hQq1: wc^3sb?`ذ}ʦLGerQNԣՑ@5?NU{jLEswjE^67/W G@:? lJ@nFq3vαwߓ>ٸ`=}3Qtd p0vkq4CV|o=VY#=ib)ZU`WV$؈A/{F֎K%ÞcXe1 3phXbtEzYDH B>+l>Cav q,"GR (Q[lmg㶪 08)wI+l~Mned|%DfQR/bHlV\)Q5mԿS>PYZ` 0kXԄehq 3D +^-XȳDytkKD`9:ݯo;ak(eHlTg\ӆm,WstK42uAt &:v~*Ӝ=.#ر 5q$$^5mn.s6j=n`;agl"cg +6 Gspbc +pwb +dWYIr7Z=nj=l%ti8 +!fN}5;'(!r)gM?.l{6&h,#ބ~.1 !Iq~#{B@㞪0iXe3<4 FpqF/,h\-&J>H"V3[0"J|8ʞEClT.JEj\z54U(QPAZ5>$J.XsҨ5CKuF⨺hwaiذ}&܄tm'}g '#HO<|wEI$MAj'N$Έ3lhw]q0}56k# Yނ/q/$B7 ۫’>A) re;]qs COeURU}h +x=  }::OXId,>|ҩ1v)@.rC$=e]S(6_, +"zL,O66`c#E\HAw'pv6jl\bXZD*q*/Wc@+#ƀZĬGqޠ]-rnI/.!nzGw<,d"J+Mn(fGq>R"'J⇌$hХF-u a0x0T-IS"b@Ļ9|xc 5 :Wʴ4_h`ˏ³&;J XD/ǠԀZ)Q%T$Ϻ]W'Jr!X6D9|OQu&?dǘW +%OE] !&DĜX{~Vm3M0 *[:H; EY"@TkƇ乌]jbP~m'd}#ઢ(,A3:%$ +Y!LY2!QޅugB jͮpzg2)~\xjU)3Y{NDe Qlx(0>ΕtY^}9ju%d2mݕ:Zl_co~XU|waF133pz~8ӻPL)ьάosbǬox}gDqQ.!+)$oD#`0(vX-9[8Ds{;lI,{ho^0B nB,~_o>]gl5\U{oc+”7#y*:wg{zzfa5Ӕl-j;TN5"m4h?Z6םB -UQDع(!E.h\ @[?n2wke)zR®ʍbf f| 5 kzq>Iqۖ=כYZi7Z2[X`vy%4a~叆{ᐹyCϕ3;e&IP8K)m+1JQ$pEm[O].Q,6loBJQ8 "¢tE2?adJ0TVen8ǽvzWQIĐU0z%*EEQ\W2Aqdb6j.8V m=iGm8A\x 0}4nﳰmق6BE-'Amu&Bc?yns h/֒>UEo*` >$wbB3d`eg|ݍ)`EL`A5Wϐ/,D:~¼8pʼU_+=yvQw88qO43yNoEϖ1=ѯo߽77c='f|x o7|}~o4_oo~}7ϊݿ_7ow~}<&woz$1}?ϩ"=ӌTğ/͟8^~wg?o\wo#nq%7b,ۿ7_|~W_ה?Oq|_r(gw3|j??~_c+lQ~6?׿$w?/Ͽ } 8[݆?O߄O?!/޽/ߝ76lkϳ)\fwoWìo7в'10cbGF?ޯq+L,NkR,D1|gm +SPz|Vro +xE-gm,Bן<CW,BEq`*XgY! +md9&D@V-o[6w'X𙕴'.*xeVak܌ϛNYI.OeۙpHsӻ|ԩa?;Ri#$+aWN`bnů?np> +oWg1\v\7c4)+m_v+>gJbyA pT凁\|%lvYSϥd_zqW6oq:eXnrTȕV8= +ծ<>3JB֢z 7xⱟ@Ki‰NtsO/W@2[jW5zU*5˟{تk3nh[A;+zk3h]$ҝד2?L%DN[vD` +j>Gd@yQ7;؈0fWt ۍ/dL" +4)G~T61 +狑^1%"mS +mwiyk\;Ԓz`-!&Ru{u>b逸'eU\-8AxJz/X-ceVID $ꌉ.ӿ\5^Ѣ="[xĪgdkDѡ[f$gzKsMΘ~ǽ\7JZ 0IKHyN/Y+fHkr -JAFaޅ!]lmen/W; ""_RxhN'Šmc:wV"(bYt$-w +k~44h?Fޙ"@~hF zp/zł;=qTA&D@$.<69գ0k!@B#D.!(mLMYp[խG! U"{ +kU"Aȋ.HR~O=$ʯF!xzL?h_LS(#\eT#IcF>占Ƨz͛/#Ap#p5!ȕTe""Nu"Dmdqw' H2zCH f࿦*I'#A1֐xdېJ.j {%Um~篑7v́o?|f"^A8GbbY#0M+3ϱ1i`˞yvsWI1‹E-|j'È7.*21'V-D9`}MT25bV;0PZ̶k_O-vN$dPEӭ"'f/]GbpT3\z9~M"It 5Gέ0";xkq=AdɄ;=s1٠`]bQI sGRF4lVF&:W29" ,|Ul?m OF? *f1LT{tcn;F@ozT6l{ۇgQ[HkDfI/@W=u9'?~Ṇ.{qvʕ58K@Q`X{?7W*&-*f9=h)sZ[+s[XإcWQVL>N(Pu챺X1/DVdZk'C87qᐥjrd("8we`UL{ɄC2h677UdT;"e MM_h$)b +cwzBF[e-%@@ Ivz)Xlu2V-EξRIoWEժ3%Paěe5@9]_f?=Y V0|_rИݎ_cQ +h4}ܦ*r **6&HHvWf VP2 ]%(SU@ƭrA 4,3_ڛk*Z,3@F+S^jtM3$SP΅qnˁ^=;4Ebp4{Hm" bۈht,EJE\(ՎB v`c70ay!$ +sȓ9ަ"`jX7]Lyni?g !"`eݏ0hP-\mW ֕,']ڠQޣe;x0L\>Ov%}`S4YW!YΖFʥOa˟~Y2D@DMIZmOIs;)Q)p$ (wͯ>n+QNI + ,3Dl(I1gLƠ+Ff7E"ۂJNg>)pgJQWiOV|qzO $n)rI|w^{(RO`ݨQg`r4rVs˯>n㵢,͜*8eXEHw05j1~xnfL\G"hNg+dx:]! +5j^T$רH?h*ƒ(LmU:W޹؈kgٳW|]]?C^zVA6vހ"[K?QG,*#D\hs +~&D+V2 +\!b1;2G(9 `P3 6oNKK`О9p@G/y$b^ ,|B*rqc/nX#o+QWޛ^]o7!n{z6k/JcZ"4Yc$5ss-#">Dv0կNh +J[P؍ ?#9AdI{Aؽ^I+^dInĈ]nyNt5 rd:s8Gs([W.yYzVu)9eK8{aR.yQۡr4,waaZX Vղ'\UMC;-"|E3` .y,m⇒';!Fb!NV992īޏ +MsCXX~Qp:Y=e?CB +jLƸk@hnr|3QB]DR䐑EU 90u@(xGxl`K]Y%odyh3ЧQlt3_ntz\CBPD~?*DM6X{#{ULjteK?1 * _X ncb7i1vΎYiaד5gV^''Z-?y?`-!scLĄ RK\TVg]S6xdt"*| ʹwa}Uq BzwiL\V̱a: +VER}iؙQF"Z9LTMLWu^bG}?Diǿd=EQ@;.ǒ<o融z'.z=n TfeFY^ +)p 0d Ff'CJtRX,MAXT2*RU)!T_FtQWsX~sy`rwR/3t(ToT0m,Pg,(pjF DA}H~[D?˼l2֓س8dYt2W].0.dl:H%=>@!I J֓(:g zd7s<}&(2ޚ(ѺA~D^=r@kF:⾋yl('Vv@[/ +=QnBm~:c mVi5I֌fITUEUDwP70h@–ן B 0 +[\[w@ݱOo=NkGODey! gG׮i2o@u5U(hۂVPf$9Ųm[WQv襨ܕE+Y~_w`E/~Z̫&^`^ⴜk +a~ +Ɨ<#f(&Wo[{6&B( 2nFGLĝ7m.gPR"O:"6lԻmUqۘ`ƓN%Y!z/E.$*}#4 +hqt a-z?[ ۭiy/HJ]ݑpxhD߫LgЋ2b~Pm(̏vNjiԷNUŌ}!W;IOa:`}F #V ޺W[Β{kf" +!BeT*4L::_jeegyJ"JTv6zt2I2%pC:K[Ao <@ɵQNE/~@Q&?<;vgt2]k˨w'0E,fl,y!R8wi٢elMFLƮ}սQ=R+2}TU5 t+fF.6[,Ruv#&/G!z^7VmubRɄD +R*NIg}V7OϽs^q #TҌ/S-& :<>>gǶ0҂h^*HgO~فe"Xg*n|"_U/Nr:|ޞ2mQ|iL3C1 C7+PQ {ñ 8=nV(tW, +mx XvIRz<>>y3,CFKH)t?WS@.nEV E`\׷A=ڶ &YI`'mLO!5 ǦiDU>L/U. +V Eo17~i۪kGn/0NK ߫}_yZY+i'TUauS/8#( GhwZZX'órEj}>yIsDNWֶHd"_\{6zz[vO/w٥|v׶O/R˗P߱хCB18V^؁9SJcLBNͨC J攬ȸ,1c.G[.Ɓ:O[>C" 2ɩ|YoӢMؔ"U/?T+`xxis"crBFIJ!"!3\AK%O>^5%5>6r~Ǧ.}kA7eQTAq=#'ԭI|z\Wi 9 !fΥFD8!CL3E̘g=s_Tzwցe`e݅`bN=SA8tnC` ox |8)0' h*GN"8@\致\~Nn{6&h#6TZ (HtR^^GÙ J1$$@xK .:$Պ_ +r"k—z6oz6)4 NRDڅ]"𢚂:=AGiEخNa4R Xj"]G3sH7agF 46=n7[_1-^u'v,%d<(Ǚta#&_f'wOa"DbU5VPhg!ch'5Gt˾iOn7 =>!@L.IP1X7-}%g~.% hNjĖ[_e`=w +YCJ!ɧ!!xN X𷣅C%Tn4UsEuu(M:ZaA-ij* +fъ1Z*9\ȒvwJyGv4_~q<_]tAMPnf VKZ֎\Z@"Y@R{F77ׁ.ɺR"ĮĶk6:I2̪\w ϲ"ޘ@h7]{{NȷZ.XVSh?y)5de(@(_F-,#BpzUx+^S(aҋGF۫ +% TP BCީQ@#&4_6*#,!$oLȏaWuāpGGU/$uv|W|;͗_}6ǣV(ƨf"su{xzT,#zS7Ӎ%q1 { +P#U)Ī;՗UI;KmsALL3J2 XɠJ78h\bVDnhwŲ(8.lv5_ +)]C,2f%{Jz75+SY5oq?W@w3sڽ5>=^K&4LГfY&|k1zѮU-*NIw.(WC^V}m}6, ^S+: PpɠMΪ6O@R"~AJuEEwzT $kh _$z6fmy}ܤ by7hx 堊!MUw/?5E ,jOMiۮ4ĄLyȃɟUAiE=Kc ]Ƨ97`?BP.OZU\ҮX ]ۑ^ވXQ⎃/hlZUB=_m^R:wyHL}Ԯ/ +TݕjSW cr6(p{I){,'kdө%g R)̙~Ld=S~ |X M,TaU[(+"fϝȑFxڨE+;Q%u7՚b1D`_&ja传ı2}~~.vWFz)s@Ya YFkkA +D"2 bc +,BIJCڱd#YSTMrS~]q \ |;p=n`D"0!#I% 2YVlQ 0NCJ0_j$fU+ 0WZp,J-2qdMU(L@8΄_%ht|Īgۮ3\,MDnR<0y[I؞]dqXPo$/.oɅd u+d~ +T$XW*(]ٙm,P☰{a炨7ۧ|e"'L.`)h#"}, f?or`۵tD!Mkwho~Fpfs +ifybʥJ"9 v܌tL\dעrnПin +d-7 +HNe$zT7M~:uS{&,.m(97MFBtezW^4Sl@ q5O̺ir Ni6eRQO9趦БfzLѠΚUX4yeOu.3,y駾p_=jf;),te)ntk׆Ur (w%1Nabbh2Y|f{Sk<uX+豊V~^9P[$7I,nպTvxLچUx<-Ƿګ:1s 9'cz|u!ZWGCVt!)"\;fۄFnprKe#kjSڜKʭo|:0KH(}4Zz67hRܑ@,/@8JŐq5<3㹫QeeJ 3ɓ~HbƄ;]|n&!:44i鲙~YOO&mT~?­j^?vKkBYBV@l +#$qH26VԐ~ղ rGt86SO@if 9}Y&=X`׭o=ͪJ5e_^ +ЛY+AdI +~o7.-(hx@$X S(270J.wp{RUmcL>@ =޶aidD)uM,o 3VW7afQU+W`bBR|tNF~$mUH"5ӀZ ]2P &!*i.FUm\$9{s-y|;u&PC^[̵ -mkٌ'x)SX1wêl?$˼u+<-"^t<֬(iQG;ޔaF+ RnIj??JŬ'x,x,fL@ iBDX'B8lĪa dCޕ̢N;X5P8TˀJB8C)M\@ҫZ?X@&ջjUq +h5ǔ)IDva&ITS)-tEKPCpμ".L0$H&e*-|VjcN֪˫{C'F9 Zͱ ++1oX<;:l WHweA̪A5m0h5 uF{a"lʇ<E:SxGRd"f)€^+vbp,}E K E7 RHug-\Wref5ٳdC?ɔ|`'4g?nP/ a\KΓ~WVdY1$ +qKu)80#qƘNhm.nܕ Eݢc33%XGcآ,O,N$rr>b;uU4܉H YWa^SVB)/ގm'+1w{72vGh"cUՠ++EGj![LU0mDfs ЖOSTYrᤔ!W]gI80\ &n&ͮ[35/KPC$O25Ukaq/ӍU'LӒ; nċnv/F掫ݞ+/rHljᬗL_c0W'?>L`9 "I/fG+TJuYb!E1۾ݥD ^v@eyAUs{rd8Ǒ$xE.΀qc!<5oը:c7]X%Otp +6XF/  #퍃}.4&G#\hᤗl6@''`59į|9 M&BU |֧RhHHn&>GeIkiNjM'd0OvDX ģ[d8bD*u!qN"sb55]JypRK@H߅&wp'n\6m^_U'I)̣0S&dy 6G L8JFK\F$u-BxsuʆWV@O=nݕi +-–^c$5W~_DZBuA&G7;ݗ}6 +ܕsZpyB>2F'f֪]8ɅP̫1v{B?rl'!ͽYg0ke'X;mtɤ%(6ʽC[^~q[oCݖ@)C/ChrM8&J4!+(H\77=~ՀПo /jj;2V^0ϳj4x&ftT;Ym +e|kh7 ʀ3CO׺0Jgr;R SC?)pPh7VxK"v{~k +)EtHQ^{t7yB:*uMD+ϛnc d*SȎ]]tPȓ͏I\Viy[2P4w EEv<3<0Mw7d`ZЅ*DcبӏJgK,boXI3H4D΍ Bbo4[mU"MBT7[lrc)DX%I&"cjE:Q!N$R54 P)4챑U茶Y dQ:|UJ|'mHmDdm5U 0F'jj#y0g׫ hpAۅwN60dPyRt #MިXYZ +DO}3* TD Y+ܫNF;c "{FUd Qm uaz~!Spڡ.>@ /. ,Zgewm,,ރ#oSȪ@V%oA ެRt|*Dbn+r9/ފ6h!RA.ʨj</ln#$'Ƞ|qo5?̰}t[ Y68v*zWFsWBr@]|#NI3N%G6+׵dzTw^98gHa|&ڳvWFt_ΡBuF6躾,>iޝBk#^.I CޕU/z@W j%AGŇlaH&wWTRتuZ`sCdX|ܜܪ*O:ܢ/\ Žv &])VIN უ کU벰Z2d\SHxG^Qn +ļF~Gβ]RB9)G葬wܕ}eg`3"*1zvo,huwpH]W͢uu&9;+?= /܅MeRX֋kUqۨ 8 On){6G6\@XFVU vnIiQXwiTykFXz쒐 ,ߚ6↲g@'X~(1ISJNh:N֊ 0kL>v)V]!x +4zU K*7IV4[Mr6-ZI(I|U-.L)fU\A ﱫk bGpN޸?e^V" lc:ŧS^pm!W tA^>AhT`ˆ/w;t ȶIA.73H(}eҲDڠ0 fg lpp'xEß՟GeQU<.֠ X>+S- t&l(~PYn2|WɉLح -vuWbsx%Np9 O&Xs gA!h)`Bf0'S٢$  _`ݍaC=3b\6V!TםN8DY9Ό קsٰKgxY|hV- +?獚X&d(R +ʡ fto{6zo|ÍUcTOnҥIJ?t =49L)W<󔘑![.kH`A"֟*ћ H;>= g?Db!B"7\q"%O06 2١@T9ǣ"$__ux02; . +JVbh¯)4H`+RxLL@hWaF~iy'_f!?vo?kgk|::Qك:E6Q{o~nؿ>he,µr A$(GB_y>d;Ѻ}jKg\%]VyC,O[/L+JiTQ޸[Bz:C(Acѓn W "" ]rG]Ke' k&|&kw's{ /` +U +5 KRd6CS|1b4\-Lfqs" *7u0o +'S1 O|"iYa[TG9& Zk+&/^ևB 1xf)LFvg0"ܢV +D%k&V$Qϼ,i|;@a RS4ejbeO?7m%ǬuVWlRdc~"zt + L}1ڭ5~X~ֽluZffvc`5Y QFgtexRr!]sו;? (/ hF7V׆UAQXks*#,ݛC4"2ΌرkQ,9-bXwbfcqTMZ:B^"8fLx}cn!2$p7Xf?y 'huR9 &ǡh?̉f;^qAzd'ZғdNq'n RkvrV+ɛ^Aˉ۪u+׹qjPn&W|BN~]PK器>)-˹k +kD.zcV5K1b=O6֝/)|@-QQclL{y`JY*z2AU v8n"B(̎CmīqŰeqƿa/ ˒'8E-H?g;i^2s&J觑: >[pxc +%fv{MHX.E#p4ٻϼ4艻wP"ޚiyg1A&8B&*h#q0Bnw,4pZn 69 9v 7֞ +e8(hw`؊'R! Z2:xA`:fJrvrJ b +5ZqJzt,8=k(iB?fW%C~gxM,6 ;8y2Y86֝.v8_f5@B C1plsZ;+gՖ.sЂH L:fc[6; nd ꄂbNB̋`_O7~EtF=#/R % 4Ƽ&c/#Q\u`4>jdsڿR YCol/lߘRC502}48+G0( +"K`WhyF,kE66vl\ljLf^;5JnQX`DQhPܧH%1K?/Y'eF6(mS ] +7._K3כ֡ +>wdƺ 6f6s6GNKžMqL_6LTqyՁ# Y)6aJ*Uo& W$̠gBvJ6 lʉ-"vMXք2i,]QF"*߬x;rXƢkbnm;ic? ͪDꐪXqEvYLHsJZna[EM-=6 M_;mc"7]: M ""Щ*Hݷ-n +%7̸JqN#SC%Rr + pA- FGA SKFȍuӴ1dX絀QjH^$Yܲ5Pxo!oo%[X*GYR ]wb0xoDgVVjVzP lvLt/N+ 5#zn>*#Wev8y_;5}c<&YyEX\|TFAGiV6Rd$( paxR1D" +|c݉ Z[62`= +0Ǩ9uJqMH>LiCEٱD) Yl;bcথHd<꓍]-R`&;-PcdDE<kpYǵPI ^{H41$Oîč}'Rl _6.8(B?JI058,Z|#Q+6$<~ΙĚ`'S1 .pgcy$G-97eC-px+rdW9 +1P@J(-q[;jcӹc:n[؉66D!~≇B> +%I֑Ki؜J6[v,X ^+-Z)y$ѧm<_6k+ c_$͋dK }%g.P O!i^7}ƆŬծG&IF!f<>hb-$Dkq3 ^HLptseccrᔛHl@&bl5WEJ4D^A{ϑ 7n&&tƐƬ`Vżw/_6h%c ])Kͺ ffR{L7fu SZL!eWޙ\~R&*w.ݴ9 MPa)('aQIKjb(v #l{gzwmtb$g]8+^u"l}ۜ1%+>[$zt@Tv|6Nj/kq0#r(~\_i}ѱjWĶYTT83j;/ݵ T")Cuz9+HlV:WN4^ml@)!K怡Ÿ7×/ۋfA+1R5 +ZSTViYi#18L7s< ŠY\RxmNVi@ԹF#QЀko0Ae| wfzec=%֐ٍB c+SKxl a5g&Z!Ryt(`56[9`? 6},l_ qdDD o }IAI퇡=U'v͍u,_j O .U/AU0<K%na$0`)cjMM_Y\~Y?_Y4r]UNrqтdv~2fc(T抄f5ǫZ?b 2@, $K޻ܖ |A38uegXR6=-ƽ{ƱKfsO ʜ p]YlfhvSVRE4Sbzdf+#n +n7Lg܂Yd&;>& !y 'gU0DrI)_AEdj/\Feqev1;?kG/VDQyZ;IG{db1 "$!!H n(D?wf|~x`llP(+wmgBԭYO}lbFXn8OMž3 &a\mR&&YQlS6Rш!p jCpѪպ3 eajyr@7{ .gG_vlRñ,eHaMZ;>7֝Y!] _6.DgeLW` ;s +I!E"1+%R[J]{|uXDj/Xf^\)`ŁNh&aPObgy~"Q7.N8Y1;+[;ulI|^, ,dXyŦz cN9M1 &&ZڋO-W7N7EaQ\dum G~zF/ϵ 489 "X׃=#e +4֏Mؙ\ݺJ<']PߖT//I/h0?-)'؇ $PP n"p+s\;sC+Dx,Q*2b$j)$Z !,)νHl&h##^ՎecI݉XZ1t^&f m؀з6GỆ} 6E0ǧ =uT$-$ORT;`ĥɉC g2j"L$10([Z#ЊE7XL;sb~؏23 i*{cZå¥jL{h5''㵦l (JU|)N"Cxѹ;G +W<\&wQocb5bFx'/uڇ\eew2IږLWaz09&5nU9EdC\_Xf @΢&\VaR +m%B9k}?NtL3fpEѻu1n/T?"L=Gbi'?o>P)'c81lZ'KO["D8[cGǢ,{|1oAGN :M<$xHn;3F_ S9_ F̦aBSpLE+SJ—ygZ{|;Au걉suaŶl҃*bQ #h3j|O[kVg)I@CxP^XPejG Q#)^ƾ3+a}_(rN.v$;f,V\cQܬM[ZI㢣}#wfam5LS2҄Cd>z/}MɼAؐI]h?iSiygTWl{@ΏpxC;w$7!ZO[3*ZH̏E?u`FomZF()j s> +]qJU;YgN.*}g1D,]!؏"k"@ٲԈiDo[⌐@3\mvT,uP7Kd +50Kv쯨Yz}GAM*d08 ;;jߩ$aWBVgBۢOцQh["K5>;G{"ė}`,1 Ѳج,.‘&'{jR/b$>}u`, jTGĎQEX_*ZeԲ;6'1hsF(͕վ3Y0zfz!ģU3 ښ#061C8[հfl(^_we,LrZ&O՛C#5SV^hȪ`;Sp*j堖TւxjʃXKq1=2f3?ʡӉnMNR#e{o{k\~{A.V_ '|oEd-hEmw7̝8odh={Kdbnr䫑jގ]޴p˘3y(4h?Y~~?$،/M}V(BjE<#2uO/NiQEi,$9>L!\~gseLp0@sdmF,|41,hVIp5ԍytO8RL6BBXgov_aOYZYz0fZ#A#K 2QB= +!%'O(a#.ƝW^Ro|9w. HM V1 +JOƼ!<&2qz<1kGx}L}=iGH87 em16cBD:KI ̜1ڌ5T5J[',[뀎z0nBpOjPGh[ [i$ԆM1R{e>0hA̺T +uUG,Z\sqV!Xǔ(Cy;<_E8ѾDlt8ț Xpe~e]C5RejJ H[+"꼵zǀPS,dp =!47Dݚ5MB z[@l杉\ ,%ϖpX֛=|ռf-MtDˠw^c̀ź3Yi0OO0U iD \*gh7҅jc$G[yNDXfO[Я%!XXwԤf凚zGSgq^q^Ho;Z.ڃrB=BHA +^I/*l`;Ymi!`&Ai$צ DbɎ7='sg)<FAR o^Lպ;|(Pײ 7pHX)R: 9"X\%IWHB%2fyj/v/<mw"!+~}a +B%=&#aj{W/O%X'ZNy?vl\qg!r14FIhe1*qI9J6*ZJi3Drc>(@էFN],Q(WDۂ)+!<3W,켪&{HT|C.~iS(5Ҿ*7CS#ʚCd̦9K?SKLSi +0Q1}O}^JoPDv!eB'At*"fUbmu53BI;߂FS π)̞n2KpMlQpalDd!bg9ҨY?e.3#,iP+:Is9kQYw"cHź@Yw!#-l1DY`QTc@\kxc.%'ϔv6OsBNai̥a'1;ފBl-źy1哤!4F 3h +Ac $sAڒi0cޔJ SGIE4 vO GPFC9<+/Ƞ_>&C*6i{x*E!be~=!5 +9BYݫڪI%fAln?}'uO +߱P5^Lg7DPvt#9a:)-iĵ|H^)b]dYS׻w +ux}X;3z] _6.@@RAx7Vpb1AW KljHg6pռ.|ۋ0jE9#d?GpϤtӥEĦ(gn7 Ҁ41 u}8| $( I@LaUKKI334d!^Oe? ƿYbbL2iz-sc:ɤW (eM ʩaⓂgo񅄷(BC#QђܰlV X :DSh!hcޙ\]R:?xAgE*tfՠUr|պ[ =cb ch 5V,< VOr f&. bb$DO2:ʳQ4.㜦j=p6 J(d#BeZjjӁsR\FhY(c@9婜8Vr=8/'uP|YX5`y@=O*9W3B(\R+D_R%W-D\3U0GD,X|EGZ Q:*摜\.;$<1u2X |;Fe)}!}Qޒ` ޷r<֌-;ǻ#v9'pl>Ha‘>"۱FDpFd,]?mѬdlUmh6}; + \iߴwP҉ 3wxJ9 Yfh0!JgS3VUbA`C\ qL#"jC7gU "9&\a.F5 gzĒ-PXYh5mۄelyBcrXڪ"pB"z(xLF,D[I6ZVf0E=L.18GE; +k[ZA]׶Ap5{yKxwMv^5-(hNoDE)N&lWfzq$re*MMHAb"F_I2D_gG~>/[^ln쾍 +H2EsǮdvZ@U$ 1_kbx%QBj4u΋7v WASEmMˋ[0B=t?Nْ̞׃!qM="F^q3l;1Tn- |$HU˱mf,_o缂Hr{9y?hP$We&Hn`($(hԦ C A< $~Aw) JXef&_xHH!s\f;r#vgt|eVȤTo@$n_ojtn΃/I,ab;z,FY7?-ŷY'r'N@W2|8#eP%*aGEًɼP=6tRgaTJ(n9둣$zAfFaz9@$H#n 畄s:AN0wZmLAN8؇fH6n3XG+*gܣL!I*虤Hh];Lƺ,8p`׹F]~4 eCԲ_Hx'$D"y~ M`Ąj\_$b?"i= ]85Sm'ZajeSXD$jv| +|<1oxxkVT1,*c_ljlqg<zRh`DdxMbxdLGPD-qqj +aJDm@54":wu= E4ɶΌ<^l7>EZuɄE{?IP͚tL`ٰ)(6ͣ}U GпHŐL4rmതS:iG"!}~1ɕ$"X;n1 /`sC;1I$$#жÏ4"q0бvG;X0v86 ZFcAgǤRO1bXy;+ 1B zZ>Dow"V`c_\qIa*:O3Re +CY4t妮Efcqj\&Adj%)Nro _V{랄@!cALZpSO S("> 08/@?C3BG<~$'X~@ d*d~Q~;*Hςt @w3U3I RLnSƙW4hF Q&hLʏmX}?j<>>Ȅ(gC 8Ƽ7EWxg0gIB#z9) +@:K>f3:2#g5sG>;h! ^3 Gqn{0Emgd#+E0(Y,:ߓ]T,t?\k[4r5+<fνg57{.󚬑m'~a^q)52ACPQ̤jBծ(ܔOipB8k'ƺ3YrysžD@xoͤ!35T@g[5dDXy 5񩅠 vmD{}gVRٻ8!0adNhNED׏_"qg +<7X lM3-TY*b a IG0-b?/u$fOY +ZA_@n@Q! viT-\ 6+bWǢ&:@ 23 PH)fQqGI3/)%zH δY-_E]yl?N{Z'ЪAGR& +ARRBYC>RDdQjXl馡ƶƣQxHFmB4hW(ߢ_JHD1`S^{π} :?!ȯGN\/f/nODqo,2lwS?#;iAEu 㱍m.l `ϋR5FԆ{jYB)nV2nrr +Er6j3șۘ>RB7]auSTi}֐"bHw1e5Lf)3Ôl$Zöƞ.^*J+#lC>kE8]'b,%R$9R8~&15w|Wqv/ %'EOyS(3 +xGJTmє3t`!%-z50Xn69ۭ>T@]٧UPR?ϩ6^$A8CCaSJ͌Lyc<1ԇ)*m;s_횡{ҍL8$1i8 f$\ {_C 1!Q)(`u'n4<\Y_q(4&j^C(M sjY5=Vx}Uu|[/N26'Tٓ\j%ǰ)Q  芭乩/wd,L1D,}_~ϗtI|f)E3^J"ZARZoي7LǦټ(7V z_ =]U̡xc"%$ЙG e64 _eg]ޘwƮe[erTWh Z*(jg㼯mm/uum̺_6ßJ0ȸB$ɼt)`,\mHo&J5a#˄E4,^l϶k3Ou5:'pyZ[PEj16Vά\,V')lsR5Ї֬T^!R3ȹ()e-6l%[y*-mg֫Vazs]$9 ɳ6$MIfFր7B.2agFDz}Y@#e0 m^ +(~6}ʜt*ia"Db ~쳊ߋ`\ec lcr]d&sN^ay%hb g8Fh4SOhlœ` +AiSAϢr!zأx Sf5dV 7RpZ zPa +^ +WvbB4(mohq^g0mL4j: Y,ᘋ HYsoO.y0 *k<-ʽw&m5L\{"\U0^#Ib& K&혜(ڟ@MtWl;lH0oT0RK96 473~#j4.D7ktbʓ=;eVyӇ{x"VҿNg>dH8y EINhRPjjMJ 5-z3)(" nwfl~xM`lqAOD Q1è $SӁ3K #zRN^]Dqc .izuM20ҍ}U6v/gIE|3m/ƯS}dJnTۃXgjB +F7o;x~xp s}3i&YnWJ-CA +F6lzCBPt.jJӌ>2$0dz y;SHG8hqH +OKD#M;npu>w{fS7iRb8a9lfCl;l /8H:'c^erV vܧkLGZ&,Pfwd]&=`pHQcHZ@sPgW5sA0}SXwoBXfs@۵LY+Td{ -?u%N 01B,`0z Q G lBnW%M ?`5g߇@r!﷚vb ocqAY1w!1<7>}LZq19ch3\NJZ5t +0y~pFha)XƌP DA1͉(owDGQ-5 {0c?{ ׋ib-C=r+Ðp|DCļo;1 ?H惶 LPēٮucũs1')RF5i =vj{_sCl+o0DWbk;gcҒltll;Q{5J?[ozuڕi/2g׏gBV,rI"ź@Aw:q LRnc0g]ZunY$[TysgNB_J"\OrxCCBO5<7|VlERSn s|F% q22yf#\CȢ\LMsD*pïн}Aɸ>׍x j!1FHhNI@.K=*Q]~ZӟggX`u”$uWlsJ.yړ黓ua jd.!6yk ¾DtoF;sGv,ls֗?1__6X8ǘy4RsT? #^,naێ 3jN+|,V/o$ק&!g~aC=.sј?1DrYŬ| Z1Meu'V7~$² '`Yg}7iکہKUSƾX@]\<^Du6Dv_5",wmv*Us߉|)qfFC3,xڎ,J2NTXV1FBU[5pyBQp݊F1щ~Uל`&nZr6(jHW|p5hgRj۠pÜ{kzJ u<89b:%¦ +jڳ#QvE<ꌐ5NW}R*f%đD5' >[FޤvMx 1몽.#I!GR"tWH$R}mw$>k 8)A`j=\굺EnUujޙЋ. 5<0 +UPBO*3U"(0$rloZisٖQn +o1^,aNX,1%Tқ:q?L=ĸA@|#7`ޙ苣YlX:q D~W.Y-jԳGcΉAݤ#Xw*bKxG8BJp)pK<~L.YoW31 Pv!E YA ;]y~YD&`"i\dU03m L;~KMթ%! DbݙM˫]ƃE?*8B0bs._b%3gǝoV1*x!jB|?ɌqLz B18;H [qrS؀l%39czq~.H %JF(C= *h,zlFJ ,͞G +v;gz5K7u:2Bշ&^wR68rKf$ +g4Qiw0w= <>`(]Lb%e~y4vTycLqXƐ@^Ƽj^ _6Y֥98Bt!Jm. gP̭jDH.MݶMO-Ɲ8%۳0. !)MȚK]3TJPP}cK -)kx6TbPec([b4bQ801:Q`("`[7g5YTb|?xp3> \پ䒆2&N5[vr vEgk'G'ԃ}/  yJO dok|7`:-CK#gru`ݙ.~@WƔ1 gLqz+6[ٚiwh$)֗r0NI[S]|+8QPyov*jp^rr>Sk_;\;?v*Mp<ȹh#xD䚏YJ~y?޷xCEػ)`iφ8$ sEs;Nʗ"F"Q&&(IdmhU1gI]OʿJacMPJ}X_4Dhf{Of?JhOߡm !Xu= !h6*!:7j3b4Ko -^2[,ƞL782Fcn.?CZ#}C<0HZ>7Ɲ)}J|huNNQ)-b4$DJStyfu Np<Al^Rb9X^z$o$Ov;yq6^ZyzN;{Nm^ _6.(M U|_M#Yc[;BhKVX;d&͒c< `8Jݙ0SEl:NZ7ɑKD5EŷR#Sug's/*P 4FoЊ_DDTgBr(hs%5:PadcۙDq00Mg4CN(#<J<LJl$GqIZ2%lƺ9 W^Z0nRɠb{&RmI׏,Wf|!;TG6 + Qփ[CKS\i%@L4ۉ]rVRaG WrtޱIǔ1v`Bs_Q.E^/UW $[ 5Ju=: Q]wqA7w#/}r/HDuvG%`%[)F:E_4:C;{hgX +x|"+a#zQaHNtq!ؚ>܆x +ו yM6ոSGf/MJzldM%N+Ldk%h( !=\O;v@4 օsٺc] W" +9zIܚ I)e)$MefIc+uHEN/s;7杙N__6$HCe)6f{SMD=n'1BѳYOw[}m)1"q wԌb? Y Bᕔ̨94Q + E]7鐀h`kB +bڙհerR +2qF{y:D!uD+HՔUJL*}g&WÔ> |H1@6E,wL1c'Wv )B'Źyo%B&9$^9*u6>NJv._?=\~z΀`/Fo'eO~DʡƾQ"&_j`OH~4 0dd[0@YIf1Hy.2A@68矱3 #Da$ )HBg,f$Zgb ֊MrHW [9ThZy δGzώY8J:Y4iY jp /̸w@aGGwh fqΜb3,>1*B 9mVMD{({BrPzC9C! }j|?8 ߝ>ɦXѲr*ܹSZ,5$$Efĕf̔jQt޻ʪ`Gx.Ij1 SF)n )agсCJu5*b\??|8P֭SC21栍Q#9%UzL,[YP3k5cb٦g]:xszNʋE-Ɲ)eܓ90h< 7-K~Ni csmө(qk&5w25Ɲeڳ7 Lcr=*R^14E⸦q71\<G1 Y2gӅ\ͲĨJr;Q˘զifl{# nB|o`xﳚVKfU0]n1>09z#;TXwfcj|?8ڈo .gQ+:i()Uyź (Q_ڑHHMpq3)VƍTQ }V4bRz@_&!A-ʳ9B |K\5]^ > BJ$'Z &E~Tpp6`. GPP\|TKblJ8oЍ2 x,F$WjZ4[N0G1u9бx{Ub?Dex6_+[LelL|G"MCN0M'NN0JM 8˱OB\@E'Mp25OmKYćf^jJгlϯ^1HU={U<#C +mWNmY Si j@#k᭙C(  אXG_qIZDcd}'VVi FtrE׸_ ȼjgVKjd1GPM+eAq]."+0)2(IKtmĹ6ÍG8{3TSJƥ޻ k Lάx.)98 me0 wp' endstream endobj 344 0 obj <>stream +RР-Ab9r29@ɖ'o8juygV>b|%!CV^K+&B>@CQ *b +p%M-\ĞEG}gV?V zSdI1Cg#kwi)=;p_ zh.nl fǗ\w'F-Ñ?FvUߢ]TFp +V/m`N04Eu,כMĎ{~Gտ!_;[YwWj.#ȆYxC?߰n gyamq;/]V׏p|#b`,#:8ծ >IٲoJ+ݸ~YXQQ>ϳFZaE~LT,-lTu2oS -b1|nThU7V +dTpUuBh.)x: NO/F b*5lEC"%Hݮ#Y=H]fl9&;Io^/\y|dN-3o:7}y?NnϚd*w&1( Rg;+x0* mT42USH{fz!bb[M;3粚u/odN#idW " H`Ңqg,GJnj1RN=s:}|ƒ>33<;qA_ߛx@Iԉ$%$OL?s7ݒƭvư-h]EAwfgKJ~sQPB"AgK>o.#‹gR7M ;bQJ 3,‰վ,/ERS4|.$]ZdTbagxAY*ZCƼS-]ƃ7'6%vYeS ˍsE2S+&v-pEO)bgNLV/y*Q+ft4F =NgcF&PW{$ nگN;6杙iY 3ZgմN!Lc,-B# eM8, +I^aJl*Z;i&.1&{nj(.y8端dXK?l1 &_6֝4]Ҭ?8Y?Q]:"fme+x;Y +XCk7Gri.D[ +Zڻ?r6W`oJ}mv+\KD';\YULOc?0Juƺ3a:)\1ɕl|:1곃yyb<zdiMSNzf%7h{ϧ?8 7ƪɾ)$RT'{ɫIF Ǎg;*[ـź/g +{,rl'*ڕm+D7} hS7O<8h(;DOTj;×/,RzB+ցjPPTV_DyЖO^3pVCŶ7׋Z#J?e | 6`EwO{cI궈$^P11cj;ӗˊ +` +uϑ"]"HB +$Pp&A^B@Lfr[ـ`D󛩉7X{|:Afp#i҉~/O~~~7_?/?и~ۇ~<P9/İ??~%ۋw/\.DžfGW +%D8gGX"۽^^h(K)c\8y;HzA`ˑ//P_S ͔ 6RF ]+_V_7~;o^^Zk{s_ &w^{JyIlxx)S}mZb#eߖiu LJ1'I{q*esk3z a5`j` T0W-4&Sal((x==~ Q'qQL5 6MǃvIh1+I&jmSQis>{IkxU& ƢCUEٞ_k޲1";cq7#;c 5] +c&KG~>>oRQO)WZ;*H7#̖BHe>n ,{;:# +ӯZHhȔ!2_N%K-Øos=:uꔧƪ?};D(>!h "q͌8_qwa՟)\zI0PC!+RPEHD qg5 ;<Ʃ2$EL([8YSv .8<+XcQ41L6wVᲵ (,zU* +Y~Uėq*1nfeW¶Nj<#@\}DKV1{`ѩ=f'di/gxv5|I"0fS5pI-Ct:Z.jĚ]B҆j_]fiEeoKeD߲ ,ܷ[u҇",TnyQp(M5E+`%(πR$kO +/ `Em݃,eBޔA߲xUBe,rՊM\9l2<&69&6a`6`)6ȁǰ ǰb\ XLf`7As6xS)'Ѐcא#R!505b/mŶ1)X4.;O&aڮ?{plkXWub"[e?0 dEnp̀lOCºOj(k2#eϻ$?r\\S2>T?71u뎆XTXd+qe6ƕٸ2Wfl\+qe6ƕm\+qe6ƕٸ2Wfl\ʕkfg0h}[77'"u`X'0xs>otm}q͟㳯߷_n@ƴƔ0ԛا?vs9=/2Cz?~o1&7cH8/뫟S ~Sor抛xٝ;446sl|0D[ [3w^>hܟN[gVMU%f'}lx}y?vww]~ugw>^~oZ)^/ߝ֘ endstream endobj 5 0 obj <> endobj 6 0 obj <> endobj 26 0 obj <> endobj 27 0 obj <> endobj 47 0 obj <> endobj 48 0 obj <> endobj 49 0 obj <> endobj 84 0 obj <> endobj 85 0 obj <> endobj 86 0 obj <> endobj 121 0 obj <> endobj 122 0 obj <> endobj 123 0 obj <> endobj 124 0 obj <> endobj 161 0 obj <> endobj 162 0 obj <> endobj 163 0 obj <> endobj 165 0 obj <> endobj 164 0 obj <> endobj 166 0 obj <> endobj 205 0 obj <> endobj 206 0 obj <> endobj 207 0 obj <> endobj 209 0 obj <> endobj 208 0 obj <> endobj 210 0 obj <> endobj 249 0 obj <> endobj 250 0 obj <> endobj 251 0 obj <> endobj 252 0 obj <> endobj 254 0 obj <> endobj 253 0 obj <> endobj 255 0 obj <> endobj 287 0 obj [/View/Design] endobj 288 0 obj <>>> endobj 285 0 obj [/View/Design] endobj 286 0 obj <>>> endobj 283 0 obj [/View/Design] endobj 284 0 obj <>>> endobj 281 0 obj [/View/Design] endobj 282 0 obj <>>> endobj 279 0 obj [/View/Design] endobj 280 0 obj <>>> endobj 277 0 obj [/View/Design] endobj 278 0 obj <>>> endobj 275 0 obj [/View/Design] endobj 276 0 obj <>>> endobj 240 0 obj [/View/Design] endobj 241 0 obj <>>> endobj 238 0 obj [/View/Design] endobj 239 0 obj <>>> endobj 236 0 obj [/View/Design] endobj 237 0 obj <>>> endobj 234 0 obj [/View/Design] endobj 235 0 obj <>>> endobj 232 0 obj [/View/Design] endobj 233 0 obj <>>> endobj 230 0 obj [/View/Design] endobj 231 0 obj <>>> endobj 196 0 obj [/View/Design] endobj 197 0 obj <>>> endobj 194 0 obj [/View/Design] endobj 195 0 obj <>>> endobj 192 0 obj [/View/Design] endobj 193 0 obj <>>> endobj 190 0 obj [/View/Design] endobj 191 0 obj <>>> endobj 188 0 obj [/View/Design] endobj 189 0 obj <>>> endobj 186 0 obj [/View/Design] endobj 187 0 obj <>>> endobj 150 0 obj [/View/Design] endobj 151 0 obj <>>> endobj 148 0 obj [/View/Design] endobj 149 0 obj <>>> endobj 146 0 obj [/View/Design] endobj 147 0 obj <>>> endobj 144 0 obj [/View/Design] endobj 145 0 obj <>>> endobj 110 0 obj [/View/Design] endobj 111 0 obj <>>> endobj 108 0 obj [/View/Design] endobj 109 0 obj <>>> endobj 106 0 obj [/View/Design] endobj 107 0 obj <>>> endobj 73 0 obj [/View/Design] endobj 74 0 obj <>>> endobj 71 0 obj [/View/Design] endobj 72 0 obj <>>> endobj 69 0 obj [/View/Design] endobj 70 0 obj <>>> endobj 38 0 obj [/View/Design] endobj 39 0 obj <>>> endobj 36 0 obj [/View/Design] endobj 37 0 obj <>>> endobj 18 0 obj [/View/Design] endobj 19 0 obj <>>> endobj 16 0 obj [/View/Design] endobj 17 0 obj <>>> endobj 304 0 obj [303 0 R 300 0 R 299 0 R 298 0 R 302 0 R 301 0 R 297 0 R] endobj 345 0 obj <> endobj xref 0 346 0000000004 65535 f +0000000016 00000 n +0000000755 00000 n +0000044868 00000 n +0000000007 00000 f +0000239282 00000 n +0000239352 00000 n +0000000009 00000 f +0000044919 00000 n +0000000010 00000 f +0000000011 00000 f +0000000012 00000 f +0000000013 00000 f +0000000014 00000 f +0000000015 00000 f +0000000020 00000 f +0000245571 00000 n +0000245602 00000 n +0000245455 00000 n +0000245486 00000 n +0000000021 00000 f +0000000022 00000 f +0000000023 00000 f +0000000024 00000 f +0000000025 00000 f +0000000028 00000 f +0000239426 00000 n +0000239497 00000 n +0000000029 00000 f +0000000030 00000 f +0000000031 00000 f +0000000032 00000 f +0000000033 00000 f +0000000034 00000 f +0000000035 00000 f +0000000040 00000 f +0000245339 00000 n +0000245370 00000 n +0000245223 00000 n +0000245254 00000 n +0000000041 00000 f +0000000042 00000 f +0000000043 00000 f +0000000044 00000 f +0000000045 00000 f +0000000046 00000 f +0000000050 00000 f +0000239572 00000 n +0000239647 00000 n +0000239717 00000 n +0000000051 00000 f +0000000052 00000 f +0000000053 00000 f +0000000054 00000 f +0000000055 00000 f +0000000056 00000 f +0000000057 00000 f +0000000058 00000 f +0000000059 00000 f +0000000060 00000 f +0000000061 00000 f +0000000062 00000 f +0000000063 00000 f +0000000064 00000 f +0000000065 00000 f +0000000066 00000 f +0000000067 00000 f +0000000068 00000 f +0000000075 00000 f +0000245107 00000 n +0000245138 00000 n +0000244991 00000 n +0000245022 00000 n +0000244875 00000 n +0000244906 00000 n +0000000076 00000 f +0000000077 00000 f +0000000078 00000 f +0000000079 00000 f +0000000080 00000 f +0000000081 00000 f +0000000082 00000 f +0000000083 00000 f +0000000087 00000 f +0000239792 00000 n +0000239869 00000 n +0000239941 00000 n +0000000088 00000 f +0000000089 00000 f +0000000090 00000 f +0000000091 00000 f +0000000092 00000 f +0000000093 00000 f +0000000094 00000 f +0000000095 00000 f +0000000096 00000 f +0000000097 00000 f +0000000098 00000 f +0000000099 00000 f +0000000100 00000 f +0000000101 00000 f +0000000102 00000 f +0000000103 00000 f +0000000104 00000 f +0000000105 00000 f +0000000112 00000 f +0000244757 00000 n +0000244789 00000 n +0000244639 00000 n +0000244671 00000 n +0000244521 00000 n +0000244553 00000 n +0000000113 00000 f +0000000114 00000 f +0000000115 00000 f +0000000116 00000 f +0000000117 00000 f +0000000118 00000 f +0000000119 00000 f +0000000120 00000 f +0000000125 00000 f +0000240018 00000 n +0000240096 00000 n +0000240169 00000 n +0000240243 00000 n +0000000126 00000 f +0000000127 00000 f +0000000128 00000 f +0000000129 00000 f +0000000130 00000 f +0000000131 00000 f +0000000132 00000 f +0000000133 00000 f +0000000134 00000 f +0000000135 00000 f +0000000136 00000 f +0000000137 00000 f +0000000138 00000 f +0000000139 00000 f +0000000140 00000 f +0000000141 00000 f +0000000142 00000 f +0000000143 00000 f +0000000152 00000 f +0000244403 00000 n +0000244435 00000 n +0000244285 00000 n +0000244317 00000 n +0000244167 00000 n +0000244199 00000 n +0000244049 00000 n +0000244081 00000 n +0000000153 00000 f +0000000154 00000 f +0000000155 00000 f +0000000156 00000 f +0000000157 00000 f +0000000158 00000 f +0000000159 00000 f +0000000160 00000 f +0000000167 00000 f +0000240321 00000 n +0000240399 00000 n +0000240472 00000 n +0000240629 00000 n +0000240546 00000 n +0000240713 00000 n +0000000168 00000 f +0000000169 00000 f +0000000170 00000 f +0000000171 00000 f +0000000172 00000 f +0000000173 00000 f +0000000174 00000 f +0000000175 00000 f +0000000176 00000 f +0000000177 00000 f +0000000178 00000 f +0000000179 00000 f +0000000180 00000 f +0000000181 00000 f +0000000182 00000 f +0000000183 00000 f +0000000184 00000 f +0000000185 00000 f +0000000198 00000 f +0000243931 00000 n +0000243963 00000 n +0000243813 00000 n +0000243845 00000 n +0000243695 00000 n +0000243727 00000 n +0000243577 00000 n +0000243609 00000 n +0000243459 00000 n +0000243491 00000 n +0000243341 00000 n +0000243373 00000 n +0000000199 00000 f +0000000200 00000 f +0000000201 00000 f +0000000202 00000 f +0000000203 00000 f +0000000204 00000 f +0000000211 00000 f +0000240791 00000 n +0000240869 00000 n +0000240942 00000 n +0000241099 00000 n +0000241016 00000 n +0000241183 00000 n +0000000212 00000 f +0000000213 00000 f +0000000214 00000 f +0000000215 00000 f +0000000216 00000 f +0000000217 00000 f +0000000218 00000 f +0000000219 00000 f +0000000220 00000 f +0000000221 00000 f +0000000222 00000 f +0000000223 00000 f +0000000224 00000 f +0000000225 00000 f +0000000226 00000 f +0000000227 00000 f +0000000228 00000 f +0000000229 00000 f +0000000242 00000 f +0000243223 00000 n +0000243255 00000 n +0000243105 00000 n +0000243137 00000 n +0000242987 00000 n +0000243019 00000 n +0000242869 00000 n +0000242901 00000 n +0000242751 00000 n +0000242783 00000 n +0000242633 00000 n +0000242665 00000 n +0000000243 00000 f +0000000244 00000 f +0000000245 00000 f +0000000246 00000 f +0000000247 00000 f +0000000248 00000 f +0000000000 00000 f +0000241261 00000 n +0000241339 00000 n +0000241412 00000 n +0000241486 00000 n +0000241645 00000 n +0000241569 00000 n +0000241729 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000242515 00000 n +0000242547 00000 n +0000242397 00000 n +0000242429 00000 n +0000242279 00000 n +0000242311 00000 n +0000242161 00000 n +0000242193 00000 n +0000242043 00000 n +0000242075 00000 n +0000241925 00000 n +0000241957 00000 n +0000241807 00000 n +0000241839 00000 n +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000000000 00000 f +0000062965 00000 n +0000061593 00000 n +0000061818 00000 n +0000061901 00000 n +0000061977 00000 n +0000061671 00000 n +0000061744 00000 n +0000062061 00000 n +0000245687 00000 n +0000045444 00000 n +0000085843 00000 n +0000057952 00000 n +0000085729 00000 n +0000057660 00000 n +0000057806 00000 n +0000056170 00000 n +0000057096 00000 n +0000057146 00000 n +0000061147 00000 n +0000057989 00000 n +0000058498 00000 n +0000058135 00000 n +0000058256 00000 n +0000058377 00000 n +0000061293 00000 n +0000061394 00000 n +0000061494 00000 n +0000062847 00000 n +0000062879 00000 n +0000062729 00000 n +0000062761 00000 n +0000062611 00000 n +0000062643 00000 n +0000062493 00000 n +0000062525 00000 n +0000062375 00000 n +0000062407 00000 n +0000062257 00000 n +0000062289 00000 n +0000062139 00000 n +0000062171 00000 n +0000063145 00000 n +0000063416 00000 n +0000085919 00000 n +0000086143 00000 n +0000087169 00000 n +0000100830 00000 n +0000166419 00000 n +0000232008 00000 n +0000245762 00000 n +trailer <<8449E7742B784DF2881ED81EA6BF2753>]>> startxref 245930 %%EOF \ No newline at end of file diff --git a/stuff/secpi-logo.png b/stuff/secpi-logo.png new file mode 100644 index 0000000..16e8417 Binary files /dev/null and b/stuff/secpi-logo.png differ diff --git a/stuff/webui_design/activate.html b/stuff/webui_design/activate.html deleted file mode 100644 index 02d80d2..0000000 --- a/stuff/webui_design/activate.html +++ /dev/null @@ -1,45 +0,0 @@ - - - Codestin Search App - - - - -

- -
-

Setup Activation

- - -
- -
-

SecPi, a project by Martin Liebl and Philip Wölfel

-
- - \ No newline at end of file diff --git a/stuff/webui_design/edit.png b/stuff/webui_design/edit.png deleted file mode 100755 index 3ef2fa6..0000000 Binary files a/stuff/webui_design/edit.png and /dev/null differ diff --git a/stuff/webui_design/main.css b/stuff/webui_design/main.css deleted file mode 100644 index 1c346f3..0000000 --- a/stuff/webui_design/main.css +++ /dev/null @@ -1,218 +0,0 @@ -html { - background-color: #a0a0a0; -} - -/*button { - text-decoration: none; - border-radius: 0px; - font-size: 15px; - background: #42991d; - color: white; - padding: 5px 10px 5px 10px; - font-family: Arial; -}*/ - -span { - color: white; - font-size: 50px; - font-style: italic; - position: absolute; - margin-top: 6px; - margin-left: 20px; - /*top: 50%; - transform: translateY(-50%);*/ -} - -footer p{ - color: white; -/* border: 1px solid black;*/ - margin-top: 5px; -} - -footer { - font-size: 12px; -/* background-color: green;*/ - background: linear-gradient(to bottom, #006600 20%, #008800 80%); - height: 20px; - bottom: 0; - position: fixed; - width: 900px; /*same as body width*/ - text-align: center; -} - -table { - width: 600px; - border-collapse: collapse; - border-spacing: 0; -} - -td, th { - border: 1px solid transparent; - height: 30px; - transition: all 0.3s; -} - -th { - background: #DFDFDF; - font-weight: bold; - height: 35px; -} - -td { - text-align: center; -} - -tr:nth-child(even) td { background: #FEFEFE; } -tr:nth-child(odd) td { background: #F1F1F1; } - -body { - width: 900px; - margin: 0 auto; - font-family: Helvetica, Arial, sans-serif; - background: white; - box-shadow: -5px 0 5px -5px, 5px 0 5px -5px; -} - -#nav { - background: linear-gradient(to bottom, #006600 20%, #008800 80%); -} - -#nav select { - display: none; -} - -#main { - padding: 0px 40px; - margin-bottom: 20px; - height: 100%; -} - -.tabrow { - text-align: center; - list-style: none; - margin: 0; - padding: 0; - line-height: 24px; - position: relative; -} - -.tabrow:after { - position: absolute; - content: ""; - width: 100%; - bottom: 0; - left: 0; - border-bottom: 1px solid #e0e0e0; /*Bottom line */ - z-index: 1; -} - -.tabrow:before { - z-index: 1; -} - -.tabrow li:before, -.tabrow li:after { - position: absolute; - bottom: 1px; - width: 6px; - height: 6px; - content: ""; -} - -.tabrow li:before { - left: -6px; - border-bottom-right-radius: 6px; - border-width: 0 1px 1px 0; - box-shadow: 2px 2px 0 #e0e0e0; -} -.tabrow li:after { - right: -6px; - border-bottom-left-radius: 6px; - border-width: 0 0 1px 1px; - box-shadow: -2px 2px 0 #e0e0e0; -} -.tabrow li.selected:before { - box-shadow: 2px 2px 0 #ffffff; -} -.tabrow li.selected:after { - box-shadow: -2px 2px 0 #ffffff; -} - -/*.tabrow li:after, .tabrow li:before { - border: 1px solid #000000 -}*/ - -.tabrow li { - margin: 60 0 0 0px; - padding: 3 11px; - border: 1px solid #AAA; - background: #e0e0e0; - /*background: linear-gradient(to bottom, #e0e0e0 80%, #606060 100%);*/ -/* text-shadow: 0 1px #22; /* dunkelgrauer schatten beim text */ - display: inline-block; - position: relative; - z-index: 0; - border-top-left-radius: 6px; - border-top-right-radius: 6px; -} - -.tabrow li.selected { - background: #ffffff; - color: #000000; - z-index: 2; - border-bottom-color: #FFF; -} - -.tabrow li a { - color: #505050; - text-decoration: none; - font-size: 16; - font-weight: bold; -} - -@media only screen and (max-device-width: 700px) { - body { - background-color: #fcfcfc; - } - - #nav ul { - display: none; - } - -/* #nav select { - display: block; - width: 40%; - margin: auto; - }*/ - - span{ - position: relative; - align-content: center; - color: white; - margin-top: 10px; - margin-left: 10px; - } - - select { - display: block; - width: 70%; - height: 50px; - font-size: 20px; - } - - button { - margin-top: 30px; - width: 70%; - height: 40px; - - } - - #main { - padding: 0px 40px; - margin-bottom: 20px; - height: 100%; -} - - - -} \ No newline at end of file diff --git a/stuff/webui_design/main.html b/stuff/webui_design/main.html deleted file mode 100644 index f3f560e..0000000 --- a/stuff/webui_design/main.html +++ /dev/null @@ -1,53 +0,0 @@ - - - Codestin Search App - - - - - - -
-

Sensors

- - - - - - - - - - - - - - - - - - - - -
IDDescriptionGPIO PIN
1PIR kitchen12
2PIR entrance17
-
- -
-

SecPi, a project by Martin Liebl and Philip Wölfel

-
- - \ No newline at end of file diff --git a/stuff/webui_design/minus-button.png b/stuff/webui_design/minus-button.png deleted file mode 100755 index 6dc019a..0000000 Binary files a/stuff/webui_design/minus-button.png and /dev/null differ diff --git a/stuff/webui_design/plus-button.png b/stuff/webui_design/plus-button.png deleted file mode 100755 index 10d1f60..0000000 Binary files a/stuff/webui_design/plus-button.png and /dev/null differ diff --git a/tools/action.py b/tools/action.py index 3638c7f..cb89690 100644 --- a/tools/action.py +++ b/tools/action.py @@ -1,12 +1,21 @@ import abc +import logging +from tools import utils class Action(object): - def __init__(self, id, params): + def __init__(self, id, params, worker): self.id = id self.params = params self.corrupted = False - + self.worker = worker + + def post_log(self, msg, lvl): + self.worker.post_log(msg, lvl) + + def post_err(self, msg): + self.worker.post_err(msg) + @abc.abstractmethod def execute(self): """Do some stuff. diff --git a/tools/sensor.py b/tools/sensor.py index 6170435..55fe375 100644 --- a/tools/sensor.py +++ b/tools/sensor.py @@ -1,4 +1,5 @@ import abc +import logging class Sensor(object): @@ -11,6 +12,12 @@ def __init__(self, id, params, worker): def alarm(self, message): self.worker.alarm(self.id, message) + def post_log(self, msg, lvl): + self.worker.post_log(msg, lvl) + + def post_err(self, msg): + self.worker.post_err(msg) + @abc.abstractmethod def activate(self): """Activate the sensor.""" diff --git a/webinterface/main.py b/webinterface/main.py index 63f7807..0c581ba 100644 --- a/webinterface/main.py +++ b/webinterface/main.py @@ -115,13 +115,21 @@ def connect(self, num_tries=3): self.channel = self.connection.channel() connected = True cherrypy.log("Connection to rabbitmq service established") - #except pika.exceptions.AMQPConnectionError as pe: + break + except pika.exceptions.AMQPConnectionError as pe: + if "The AMQP connection was closed" in repr(pe): + cherrypy.log("Wasn't able to connect to the rabbitmq service, please check if the rabbitmq service is reachable and running") + else: + cherrypy.log("Wasn't able to connect to the rabbitmq service: %s" % repr(pe)) except Exception as e: - cherrypy.log("Error connecting to Queue! %s" % e, traceback=True) - num_tries-=1 + cherrypy.log("Unknown error: %s" % e) + + num_tries-=1 + if(num_tries!=0): time.sleep(30) if not connected: + cherrypy.log("Wasn't able to connect to rabbitmq service, exiting...") return False # define exchange self.channel.exchange_declare(exchange=utils.EXCHANGE, exchange_type='direct') @@ -188,89 +196,119 @@ def change_credentials(self): @cherrypy.expose @cherrypy.tools.json_in() - @cherrypy.tools.json_out(handler=utils.json_handler) - def activate(self): - if(hasattr(cherrypy.request, 'json')): + #@cherrypy.tools.json_out(handler=utils.json_handler) + def activate(self, **kwargs): + retval = {} + is_json = False + id=0 + + if(hasattr(cherrypy.request, 'json')): id = cherrypy.request.json['id'] + is_json = True + elif('id' in kwargs): + id = kwargs['id'] + else: + retval = {'status': 'error', 'message': 'No data recieved!'} - if(id and id > 0): - su = self.db.query(objects.Setup).get(int(id)) - try: - if(hasattr(self, "channel")): - su.active_state = True - self.db.commit() - ooff = { 'active_state': True , 'setup_name': su.name } - self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) - else: - return {'status':'error', 'message': "Error activating %s! No connection to queue server!" % su.name } - - except pika.exceptions.ConnectionClosed: - cherrypy.log("Reconnecting to RabbitMQ Server!") - reconnected = self.connect(5) - if reconnected: - cherrypy.log("Reconnect finished!") - su.active_state = True - self.db.commit() - ooff = { 'active_state': True, 'setup_name': su.name } - self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) - return {'status': 'success', 'message': "Activated setup %s!" % su.name} - else: - return {'status':'error', 'message': "Error activating %s! Wasn't able to reconnect!" % su.name } - - except Exception as e: - su.active_state = False + if(id and id > 0): + su = self.db.query(objects.Setup).get(int(id)) + try: + if(hasattr(self, "channel")): + su.active_state = True self.db.commit() - cherrypy.log("Error activating! %s"%str(e), traceback=True) - return {'status':'error', 'message': "Error activating! %s" % e } + ooff = { 'active_state': True , 'setup_name': su.name } + self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) + retval = {'status': 'success', 'message': "Activated setup %s!" % su.name} else: - return {'status': 'success', 'message': "Activated setup %s!" % su.name} - else: - return {'status':'error', 'message': "Invalid ID!" } - - return {'status': 'error', 'message': 'No data recieved!'} + retval = {'status':'error', 'message': "Error activating %s! No connection to queue server!" % su.name } + + except pika.exceptions.ConnectionClosed: + cherrypy.log("Reconnecting to RabbitMQ Server!") + reconnected = self.connect(5) + if reconnected: + cherrypy.log("Reconnect finished!") + su.active_state = True + self.db.commit() + ooff = { 'active_state': True, 'setup_name': su.name } + self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) + retval = {'status': 'success', 'message': "Activated setup %s!" % su.name} + else: + retval = {'status':'error', 'message': "Error activating %s! Wasn't able to reconnect!" % su.name } + except Exception as e: + su.active_state = False + self.db.commit() + cherrypy.log("Error activating! %s"%str(e), traceback=True) + retval = {'status':'error', 'message': "Error activating! %s" % e } + + else: + retval = {'status':'error', 'message': "Invalid ID!" } + + if(is_json): + cherrypy.response.headers['Content-Type'] = "application/json" + return json.dumps(retval) + else: + tmpl = self.lookup.get_template("activate.mako") + return tmpl.render(page_title="Activate", message = retval['message'], status=retval['status']) + @cherrypy.expose @cherrypy.tools.json_in() - @cherrypy.tools.json_out(handler=utils.json_handler) - def deactivate(self): - if(hasattr(cherrypy.request, 'json')): + #@cherrypy.tools.json_out(handler=utils.json_handler) + def deactivate(self, **kwargs): + retval = {} + is_json = False + id=0 + + if(hasattr(cherrypy.request, 'json')): id = cherrypy.request.json['id'] + is_json = True + elif('id' in kwargs): + id = kwargs['id'] + else: + retval = {'status': 'error', 'message': 'No data recieved!'} - if(id and id > 0): - su = self.db.query(objects.Setup).get(int(id)) - try: - if(hasattr(self, "channel")): - su.active_state = False - self.db.commit() - ooff = { 'active_state': False, 'setup_name': su.name } - self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) - else: - return {'status':'error', 'message': "Error deactivating %s! No connection to queue server!"%su.name } - - except pika.exceptions.ConnectionClosed: - cherrypy.log("Reconnecting to RabbitMQ Server!") - reconnected = self.connect(5) - if reconnected: - cherrypy.log("Reconnect finished!") - su.active_state = False - self.db.commit() - ooff = { 'active_state': False, 'setup_name': su.name } - self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) - return {'status': 'success', 'message': "Deactivated setup %s!" % su.name} - else: - return {'status':'error', 'message': "Error deactivating %s! Wasn't able to reconnect!" % su.name } - - except Exception as e: - su.active_state = True; + if(id and id > 0): + su = self.db.query(objects.Setup).get(int(id)) + try: + if(hasattr(self, "channel")): + su.active_state = False self.db.commit() - cherrypy.log("Error deactivating! %s"%str(e), traceback=True) - return {'status':'error', 'message': "Error deactivating! %s" % e } + ooff = { 'active_state': False , 'setup_name': su.name } + self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) + retval = {'status': 'success', 'message': "Deactivated setup %s!" % su.name} else: - return {'status': 'success', 'message': "Deactivated setup %s!" % su.name} + retval = {'status':'error', 'message': "Error deactivating %s! No connection to queue server!" % su.name } - return {'status':'error', 'message': "Invalid ID!" } + except pika.exceptions.ConnectionClosed: + cherrypy.log("Reconnecting to RabbitMQ Server!") + reconnected = self.connect(5) + if reconnected: + cherrypy.log("Reconnect finished!") + su.active_state = False + self.db.commit() + ooff = { 'active_state': False, 'setup_name': su.name } + self.channel.basic_publish(exchange=utils.EXCHANGE, routing_key=utils.QUEUE_ON_OFF, body=json.dumps(ooff)) + retval = {'status': 'success', 'message': "Deactivated setup %s!" % su.name} + else: + retval = {'status':'error', 'message': "Error deactivating %s! Wasn't able to reconnect!" % su.name } + + except Exception as e: + su.active_state = True + self.db.commit() + cherrypy.log("Error deactivating! %s"%str(e), traceback=True) + retval = {'status':'error', 'message': "Error deactivating! %s" % e } + + else: + retval = {'status':'error', 'message': "Invalid ID!" } - return {'status': 'error', 'message': 'No data recieved!'} + if(is_json): + cherrypy.response.headers['Content-Type'] = "application/json" + return json.dumps(retval) + else: + tmpl = self.lookup.get_template("activate.mako") + return tmpl.render(page_title="Deactivate", message = retval['message'], status=retval['status']) + + @cherrypy.expose @cherrypy.tools.json_in() diff --git a/webinterface/sites/actions.py b/webinterface/sites/actions.py index fa30348..f828fc2 100644 --- a/webinterface/sites/actions.py +++ b/webinterface/sites/actions.py @@ -22,9 +22,9 @@ def __init__(self): @cherrypy.expose - def index(self, flash_message=None): + def index(self): tmpl = self.lookup.get_template("actions.mako") - return tmpl.render(page_title="Actions", flash_message=flash_message) + return tmpl.render(page_title="Actions") diff --git a/webinterface/sites/alarms.py b/webinterface/sites/alarms.py index 55b9106..6bfc0f4 100644 --- a/webinterface/sites/alarms.py +++ b/webinterface/sites/alarms.py @@ -22,9 +22,9 @@ def __init__(self): @cherrypy.expose - def index(self, flash_message=None): + def index(self): tmpl = self.lookup.get_template("alarms.mako") - return tmpl.render(page_title="Alarms", flash_message=flash_message) + return tmpl.render(page_title="Alarms") @cherrypy.expose @cherrypy.tools.json_in() diff --git a/webinterface/sites/notifiers.py b/webinterface/sites/notifiers.py index 5ff4b13..a325d50 100644 --- a/webinterface/sites/notifiers.py +++ b/webinterface/sites/notifiers.py @@ -22,9 +22,9 @@ def __init__(self): @cherrypy.expose - def index(self, flash_message=None): + def index(self): tmpl = self.lookup.get_template("notifiers.mako") - return tmpl.render(page_title="Notifiers", flash_message=flash_message) + return tmpl.render(page_title="Notifiers") diff --git a/webinterface/sites/setups.py b/webinterface/sites/setups.py index 811864a..a23d934 100644 --- a/webinterface/sites/setups.py +++ b/webinterface/sites/setups.py @@ -20,9 +20,9 @@ def __init__(self): @cherrypy.expose - def index(self, flash_message=None): + def index(self): tmpl = self.lookup.get_template("setups.mako") - return tmpl.render(page_title="Setups", flash_message=flash_message) + return tmpl.render(page_title="Setups") diff --git a/webinterface/sites/workers.py b/webinterface/sites/workers.py index 83830fc..414f649 100644 --- a/webinterface/sites/workers.py +++ b/webinterface/sites/workers.py @@ -21,9 +21,9 @@ def __init__(self): @cherrypy.expose - def index(self, flash_message=None): + def index(self): tmpl = self.lookup.get_template("workers.mako") - return tmpl.render(page_title="Workers", flash_message=flash_message) + return tmpl.render(page_title="Workers") diff --git a/webinterface/sites/zones.py b/webinterface/sites/zones.py index 92e1728..e284feb 100644 --- a/webinterface/sites/zones.py +++ b/webinterface/sites/zones.py @@ -19,9 +19,9 @@ def __init__(self): @cherrypy.expose - def index(self, flash_message=None): + def index(self): tmpl = self.lookup.get_template("zones.mako") - return tmpl.render(page_title="Zones", flash_message=flash_message) + return tmpl.render(page_title="Zones") diff --git a/webinterface/static/js/app.js b/webinterface/static/js/app.js index 3d86f66..e379e3e 100644 --- a/webinterface/static/js/app.js +++ b/webinterface/static/js/app.js @@ -161,7 +161,7 @@ app.controller('DataController', ['$uibModal', '$http', '$log', '$scope', '$time for (var key in self.fields) { if (self.fields.hasOwnProperty(key)) { - if($.inArray(filter, self.fields[key]['visible']) >= 0){ + if(self.fields[key]['visible'].indexOf(filter) >= 0){ filtered_fields[key] = self.fields[key]; } } @@ -196,7 +196,7 @@ app.controller('DataController', ['$uibModal', '$http', '$log', '$scope', '$time self.showEdit = function(id){ self.dialogTitle = "Edit"; self.form_fields = self.getFields('update') - self.edit_data = jQuery.extend(true, {}, self.data[id]) + self.edit_data = angular.copy(self.data[id]) self.edit_id = id; self.orig_data = self.data[id]; self.dialog = $uibModal.open({ @@ -316,7 +316,7 @@ app.controller('DataController', ['$uibModal', '$http', '$log', '$scope', '$time self.loading = true; self.dialogTitle = "Copy"; self.form_fields = self.getFields('add') - self.edit_data = jQuery.extend(true, {}, self.data[copyId]) + self.edit_data = angular.copy(self.data[copyId]) self.edit_id = -1; self.orig_data = self.data[copyId]; self.dialog = $uibModal.open({ @@ -451,6 +451,8 @@ app.controller('AckController', ['$http', '$log', '$interval', '$attrs', 'FlashS self.ackclass = $attrs.ackclass; + self.btnText = "stop refresh" + self.entries = []; @@ -500,7 +502,8 @@ app.controller('AckController', ['$http', '$log', '$interval', '$attrs', 'FlashS if(!self.refresh_inter){ self.refresh_inter = $interval(self.refresh, 5000); FlashService.flash('Started refresh of messages!', FlashService.TYPE_INFO, 2000); - $('#refresh_toggle_'+self.ackclass).prop('value', "stop refresh"); + //$('#refresh_toggle_'+self.ackclass).prop('value', "stop refresh"); + self.btnText = "stop refresh"; } } @@ -509,7 +512,8 @@ app.controller('AckController', ['$http', '$log', '$interval', '$attrs', 'FlashS $interval.cancel(self.refresh_inter); self.refresh_inter = null; FlashService.flash('Stopped refresh of messages!', FlashService.TYPE_INFO, 2000); - $('#refresh_toggle_'+self.ackclass).prop('value', "start refresh"); + //$('#refresh_toggle_'+self.ackclass).prop('value', "start refresh"); + self.btnText = "start refresh"; } } diff --git a/webinterface/templates/activate.mako b/webinterface/templates/activate.mako new file mode 100644 index 0000000..19d0136 --- /dev/null +++ b/webinterface/templates/activate.mako @@ -0,0 +1,5 @@ +<%inherit file="main.mako"/> + +<%def name="active_tab()"><% return "activate" %> +Status: ${status}
+${message} \ No newline at end of file diff --git a/webinterface/templates/index.mako b/webinterface/templates/index.mako index 352e242..d75bb8a 100644 --- a/webinterface/templates/index.mako +++ b/webinterface/templates/index.mako @@ -23,7 +23,7 @@

Alarms

- +
{{alarm.alarmtime | date:'dd. MMM. yyyy, HH:mm:ss'}} {{alarm.sensor_id}}: {{alarm.message}} @@ -35,7 +35,7 @@

Log Messages

- +
{{log.logtime | date:'dd. MMM. yyyy, HH:mm:ss'}} {{log.sender}}: {{log.message}} diff --git a/webinterface/templates/main.mako b/webinterface/templates/main.mako index 4632291..8e11fab 100644 --- a/webinterface/templates/main.mako +++ b/webinterface/templates/main.mako @@ -1,4 +1,4 @@ -<%page args="flash_message='',flash_type='info'"/> + <% active_tab = self.active_tab() %> diff --git a/worker/buzzer.py b/worker/buzzer.py index 5cbb48c..9581d48 100644 --- a/worker/buzzer.py +++ b/worker/buzzer.py @@ -6,8 +6,8 @@ class Buzzer(Action): - def __init__(self, id, params): - super(Buzzer, self).__init__(id, params) + def __init__(self, id, params, worker): + super(Buzzer, self).__init__(id, params, worker) try: self.duration = int(params["duration"]) self.gpio_pin = int(params["gpio_pin"]) diff --git a/worker/ffmpegvideo.py b/worker/ffmpegvideo.py new file mode 100644 index 0000000..2f21e5c --- /dev/null +++ b/worker/ffmpegvideo.py @@ -0,0 +1,90 @@ +import os +import time +import ffmpy +import logging + +from tools.action import Action + +class FFMPEGVideo(Action): + """ + This module is like the "webcam" module but uses the fine "ffmpeg" for capturing picture snapshots. + For interacting with ffmpeg, the ffmpy command line wrapper is used. + + Setup: + - apt install ffmpeg + - pip install ffmpy + """ + + def __init__(self, id, params): + super(FFMPEGVideo, self).__init__(id, params) + + logging.info('FFMPEGVideo: Starting') + + # Set parameter defaults + self.params.setdefault('name', 'default') + self.params.setdefault('count', 3) + self.params.setdefault('interval', 5) + self.params.setdefault('data_path', '/var/tmp/secpi/worker_data') + self.params.setdefault('ffmpeg_global_options', '-v quiet -stats') + self.params.setdefault('ffmpeg_input_options', None) + self.params.setdefault('ffmpeg_output_options', '-pix_fmt yuvj420p -vsync 2 -vframes 1') + + # Define required params + required_params = ['url'] + + # Configuration parameter checks + for required_param in required_params: + if required_param not in self.params: + self.post_err("FFMPEGVideo: Configuration parameter '{}' is missing".format(required_param)) + self.corrupted = True + return + + # Sanity checks + if not os.path.exists(self.params['data_path']): + self.post_err("FFMPEGVideo: Path does not exist. data_path={}".format(self.params['data_path'])) + self.corrupted = True + return + + def exffmpeg(self, url, filename, global_options=None, input_options=None, output_options=None): + ff = ffmpy.FFmpeg( + global_options = global_options, + inputs = {url: input_options}, + outputs = {filename: output_options} + ) + ff.run() + + # Take a series of pictures within a given interval + def take_adv_picture(self, num_of_pic, seconds_between): + logging.debug("FFMPEGVideo: Trying to take pictures") + + name = self.params['name'] + url = self.params['url'] + timestamp = time.strftime("%Y%m%d%H%M%S") + + for index in range(0, num_of_pic): + filename = '{name}-{timestamp}-{index}.jpg'.format(**locals()) + filepath = os.path.join(self.params['data_path'], filename) + logging.info("FFMPEGVideo: Trying to take a picture from {url} to {filepath}".format(**locals())) + try: + result = self.exffmpeg(url, filepath, + global_options=self.params['ffmpeg_global_options'], + input_options=self.params['ffmpeg_input_options'], + output_options=self.params['ffmpeg_output_options'], + ) + except Exception as ex: + self.post_err("FFMPEGVideo: Wasn't able to take picture from {url} to {filepath}: %s".format(**locals()) % ex) + + # Wait until next interval + time.sleep(seconds_between) + + logging.debug("FFMPEGVideo: Finished taking pictures") + + + def execute(self): + if not self.corrupted: + self.take_adv_picture(int(self.params["count"]), int(self.params["interval"])) + else: + self.post_err("FFMPEGVideo: Wasn't able to take pictures because of an initialization error") + + def cleanup(self): + logging.debug("FFMPEGVideo: No cleanup necessary at the moment") diff --git a/worker/gpio_sensor.py b/worker/gpio_sensor.py index b54eea3..00a115e 100644 --- a/worker/gpio_sensor.py +++ b/worker/gpio_sensor.py @@ -11,12 +11,15 @@ def __init__(self, id, params, worker): try: self.gpio = int(params["gpio"]) self.bouncetime = int(self.params['bouncetime']) + self.edge = self.params.get('edge', 'rising').lower() + if self.edge not in ['rising', 'falling', 'both']: + raise ValueError("GPIOSensor: Parameter 'edge' must be one of ['rising', 'falling', 'both']") except ValueError as ve: # if one configuration parameter can't be parsed as int - logging.error("GPIOSensor: Wasn't able to initialize the sensor, please check your configuration: %s" % ve) + self.post_err("GPIOSensor: Wasn't able to initialize the sensor, please check your configuration: %s" % ve) self.corrupted = True return except KeyError as ke: # if config parameters are missing in the file - logging.error("GPIOSensor: Wasn't able to initialize the sensor, it seems there is a config parameter missing: %s" % ke) + self.post_err("GPIOSensor: Wasn't able to initialize the sensor, it seems there is a config parameter missing: %s" % ke) self.corrupted = True return @@ -26,9 +29,17 @@ def __init__(self, id, params, worker): def setup_sensor(self): try: GPIO.setup(self.gpio, GPIO.IN) - GPIO.add_event_detect(self.gpio, GPIO.RISING, callback=self.cb_alarm, bouncetime=self.bouncetime) + if self.edge == 'rising': + edge_type = GPIO.RISING + elif self.edge == 'falling': + edge_type = GPIO.FALLING + elif self.edge == 'both': + edge_type = GPIO.BOTH + else: + raise ValueError("GPIOSensor: Unknown edge type: %s" % self.edge) + GPIO.add_event_detect(self.gpio, edge_type, callback=self.cb_alarm, bouncetime=self.bouncetime) except ValueError as ve: # GPIO pin number or bouncetime is not in valid range - logging.error("GPIOSensor: The given pin number or bouncetime is not in a valid range: %s" % ve) + self.post_err("GPIOSensor: The given pin number or bouncetime is not in a valid range: %s" % ve) return logging.debug("GPIOSensor: Registered sensor at pin %s!" % self.gpio) @@ -37,24 +48,31 @@ def cleanup_sensor(self): GPIO.remove_event_detect(self.gpio) GPIO.cleanup(self.gpio) except ValueError as ve: # GPIO pin number is not in valid range - logging.error("GPIOSensor: The given pin number is not in a valid range: %s" % ve) + self.post_err("GPIOSensor: The given pin number is not in a valid range: %s" % ve) logging.debug("GPIOSensor: Removed sensor at pin %s!" % self.gpio) # callback for alarm def cb_alarm(self, channel): - if(self.active): - self.alarm("GPIO sensor at pin %s activated!" % channel) - + if self.active: + if self.edge in ['rising', 'falling']: + self.alarm("GPIO sensor at pin %s detected something!" % channel) + else: + if GPIO.input(channel): + state = 'activated' + else: + state = 'deactivated' + self.alarm("GPIO sensor at pin %s %s" % (channel, state)) + def activate(self): if not self.corrupted: self.active = True self.setup_sensor() else: - logging.error("GPIOSensor: Sensor couldn't be activated") + self.post_err("GPIOSensor: Sensor couldn't be activated") def deactivate(self): if not self.corrupted: self.active = False self.cleanup_sensor() else: - logging.error("GPIOSensor: Sensor couldn't be deactivated") # maybe make this more clear \ No newline at end of file + self.post_err("GPIOSensor: Sensor couldn't be deactivated") # maybe make this more clear \ No newline at end of file diff --git a/worker/pinger.py b/worker/pinger.py new file mode 100644 index 0000000..b233ccb --- /dev/null +++ b/worker/pinger.py @@ -0,0 +1,61 @@ +from tools.sensor import Sensor +import logging +import pyping +import threading +import time + +class Pinger(Sensor): + + def __init__(self, id, params, worker): + super(Pinger, self).__init__(id, params, worker) + + try: + self.interval = int(params["interval"]) + self.max_losses = int(params["max_losses"]) + self.destination_ip = params["destination_ip"] + self.bouncetime = int(params["bounce_time"]) + except KeyError as ke: # if config parameters are missing in file + self.post_err("Pinger: Wasn't able to initialize, it seems there is a config parameter missing: %s" % ke) + self.corrupted = True + return + except ValueError as ve: # if a parameter can't be parsed as int + self.post_err("Pinger: Wasn't able to initialize, please check your configuration: %s" % ve) + self.corrupted = True + return + + logging.debug("Pinger: Sensor initialized") + + def activate(self): + if not self.corrupted: + self.stop_thread = False + self.pinger_thread = threading.Thread(name="thread-pinger-%s" % self.destination_ip, target=self.check_up) + self.pinger_thread.start() + else: + self.post_err("Pinger: Sensor couldn't be activated") + + def deactivate(self): + if not self.corrupted: + self.stop_thread = True + else: + self.post_err("Pinger: Sensor couldn't be deactivated") + + + def check_up(self): + losses = 0 + while True: + if self.stop_thread: + return + + reply = pyping.ping(self.destination_ip) # ret value is 0 when reachable + if reply.ret_code: + losses += 1 + logging.info("Pinger: Loss happened, %d/%d" % (losses, self.max_losses)) + else: + losses = 0 + + if losses >= self.max_losses: + self.alarm("%d consecutive pings were lost" % losses) + losses = 0 + time.sleep(self.bouncetime) + continue + time.sleep(self.interval) \ No newline at end of file diff --git a/worker/speaker.py b/worker/speaker.py index 1231139..5d6b91f 100644 --- a/worker/speaker.py +++ b/worker/speaker.py @@ -5,8 +5,8 @@ class Speaker(Action): - def __init__(self, id, params): - super(Speaker, self).__init__(id, params) + def __init__(self, id, params, worker): + super(Speaker, self).__init__(id, params, worker) try: self.path_to_audio = params["path_to_audio"] self.repetitions = int(params["repetitions"]) @@ -32,7 +32,7 @@ def play_audio(self): return pygame.mixer.music.set_volume(1) - for i in range(0, self.repetitions): + for i in xrange(0, self.repetitions): pygame.mixer.music.rewind() pygame.mixer.music.play() while pygame.mixer.music.get_busy(): diff --git a/worker/temperature_sensor.py b/worker/temperature_sensor.py index d35a2d7..8562fae 100644 --- a/worker/temperature_sensor.py +++ b/worker/temperature_sensor.py @@ -17,11 +17,11 @@ def __init__(self, id, params, worker): self.bouncetime = int(params["bouncetime"]) self.device_id = params["device_id"] except ValueError as ve: # if one configuration parameter can't be parsed as int - logging.error("TemperatureSensor: Wasn't able to initialize the sensor, please check your configuration: %s" % ve) + self.post_err("TemperatureSensor: Wasn't able to initialize the sensor, please check your configuration: %s" % ve) self.corrupted = True return except KeyError as ke: # if config parameters are missing - logging.error("TemperatureSensor: Wasn't able to initialize the sensor, it seems there is a config parameter missing: %s" % ke) + self.post_err("TemperatureSensor: Wasn't able to initialize the sensor, it seems there is a config parameter missing: %s" % ke) self.corrupted = True return @@ -34,7 +34,7 @@ def __init__(self, id, params, worker): if not os.path.isfile(self.device_file): # if there is no slave file which contains the temperature self.corrupted = True - logging.error("TemperatureSensor: Wasn't able to find temperature file at %s" % self.device_file) + self.post_err("TemperatureSensor: Wasn't able to find temperature file at %s" % self.device_file) return logging.debug("TemperatureSensor: Sensor initialized") @@ -46,13 +46,13 @@ def activate(self): target=self.check_temperature) self.checker_thread.start() else: - logging.error("TemperatureSensor: Sensor couldn't be activated") + self.post_err("TemperatureSensor: Sensor couldn't be activated") def deactivate(self): if not self.corrupted: self.stop_thread = True else: - logging.error("TemperatureSensor: Sensor couldn't be deactivated") + self.post_err("TemperatureSensor: Sensor couldn't be deactivated") def check_temperature(self): while True: @@ -67,9 +67,9 @@ def check_temperature(self): time.sleep(3) def read_temp_raw(self): - f = open(self.device_file, 'r') - lines = f.readlines() - f.close() + with open(self.device_file, 'r') as f: + lines = f.readlines() + return lines def read_temp(self): diff --git a/worker/testaction.py b/worker/testaction.py index 87b11a4..608ce3d 100644 --- a/worker/testaction.py +++ b/worker/testaction.py @@ -1,18 +1,21 @@ import logging from tools.action import Action +from tools import utils class TestAction(Action): - def __init__(self, id, params): - super(TestAction, self).__init__(id, params) + def __init__(self, id, params, worker): + super(TestAction, self).__init__(id, params, worker) logging.debug("Test Action initialized!") def execute(self): - logging.log("Executing Test Action!") + logging.info("Executing Test Action!") + self.post_log("Executing Test Action!", utils.LEVEL_INFO) if 'msg' in self.params: - logging.log("Test Action Message: %s"%self.params['msg']) + logging.info("Test Action Message: %s"%self.params['msg']) + self.post_log("Test Action Message: %s"%self.params['msg'], utils.LEVEL_INFO) def cleanup(self): logging.debug("Test Action Cleanup") diff --git a/worker/webcam.py b/worker/webcam.py index 9e8067c..b5fc9d5 100644 --- a/worker/webcam.py +++ b/worker/webcam.py @@ -7,19 +7,19 @@ class Webcam(Action): - def __init__(self, id, params): - super(Webcam, self).__init__(id, params) + def __init__(self, id, params, worker): + super(Webcam, self).__init__(id, params, worker) try: self.path = params["path"] self.resolution = (int(params["resolution_x"]), int(params["resolution_y"])) self.data_path = params.get("data_path", "/var/tmp/secpi/worker_data") except ValueError as ve: # if resolution can't be parsed as int - logging.error("Webcam: Wasn't able to initialize the device, please check your configuration: %s" % ve) + self.post_err("Webcam: Wasn't able to initialize the device, please check your configuration: %s" % ve) self.corrupted = True return except KeyError as ke: # if config parameters are missing in file - logging.error("Webcam: Wasn't able to initialize the device, it seems there is a config parameter missing: %s" % ke) + self.post_err("Webcam: Wasn't able to initialize the device, it seems there is a config parameter missing: %s" % ke) self.corrupted = True return @@ -33,19 +33,19 @@ def take_adv_picture(self, num_of_pic, seconds_between): try: self.cam.start() except SystemError as se: # device path wrong - logging.error("Webcam: Wasn't able to find video device at device path: %s" % self.path) + self.post_err("Webcam: Wasn't able to find video device at device path: %s" % self.path) return except AttributeError as ae: # init failed, taking pictures won't work -> shouldn't happen but anyway - logging.error("Webcam: Couldn't take pictures because video device wasn't initialized properly") + self.post_err("Webcam: Couldn't take pictures because video device wasn't initialized properly") return try: - for i in range(0,num_of_pic): + for i in xrange(0,num_of_pic): img = self.cam.get_image() pygame.image.save(img, "%s/%s_%d.jpg" % (self.data_path, time.strftime("%Y%m%d_%H%M%S"), i)) time.sleep(seconds_between) except Exception as e: - logging.error("Webcam: Wasn't able to take pictures: %s" % e) + self.post_err("Webcam: Wasn't able to take pictures: %s" % e) self.cam.stop() logging.debug("Webcam: Finished taking pictures") @@ -55,7 +55,7 @@ def execute(self): if not self.corrupted: self.take_adv_picture(int(self.params["count"]), int(self.params["interval"])) else: - logging.error("Webcam: Wasn't able to take pictures because of an initialization error") + self.post_err("Webcam: Wasn't able to take pictures because of an initialization error") def cleanup(self): logging.debug("Webcam: No cleanup necessary at the moment") \ No newline at end of file diff --git a/worker/worker.py b/worker/worker.py index 4a69fc9..4e32956 100644 --- a/worker/worker.py +++ b/worker/worker.py @@ -50,15 +50,14 @@ def __init__(self): logging.error("Wasn't able to load config file, exiting...") quit() - time.sleep(60) # TEMPORARY FIX for #83 - self.prepare_data_directory(self.data_directory) self.connect() # if we don't have a pi id we need to request the initial config, afterwards we have to reconnect # to the queues which are specific to the pi id -> hence, call connect again if not config.get('pi_id'): - logging.debug("No Pi ID found, will request initial configuration...") + logging.info("No Pi ID found, will request initial configuration...") + time.sleep(60) self.fetch_init_config() else: logging.info("Setting up sensors and actions") @@ -91,7 +90,10 @@ def connect(self): connected = True logging.info("Connection to manager established") except pika.exceptions.AMQPConnectionError as pe: # if connection can't be established - logging.error("Wasn't able to open a connection to the manager: %s" % pe) + if "The AMQP connection was closed" in repr(pe): + logging.error("Wasn't able to connect to the rabbitmq service, please check if the rabbitmq service is reachable and running") + else: + logging.error("Wasn't able to open a connection to the manager: %s" % repr(pe)) time.sleep(30) self.channel.exchange_declare(exchange=utils.EXCHANGE, exchange_type='direct') @@ -207,7 +209,7 @@ def clear_message_queue(self): def post_err(self, msg): - logging.exception(msg) + logging.error(msg) err = { "msg": msg, "level": utils.LEVEL_ERR, "sender": "Worker %s"%config.get('pi_id'), @@ -216,7 +218,7 @@ def post_err(self, msg): self.send_json_msg(utils.QUEUE_LOG, err) def post_log(self, msg, lvl): - logging.exception(msg) + logging.info(msg) lg = { "msg": msg, "level": lvl, "sender": "Worker %s"%config.get('pi_id'), @@ -342,8 +344,8 @@ def got_action(self, ch, method, properties, body): t.join() if self.prepare_data(): #check if there is any data to send - zip_file = open("%s/%s.zip" % (self.zip_directory, config.get('pi_id')), "rb") - byte_stream = zip_file.read() + with open("%s/%s.zip" % (self.zip_directory, config.get('pi_id')), "rb") as zip_file: + byte_stream = zip_file.read() self.send_msg(utils.QUEUE_DATA, byte_stream) logging.info("Sent data to manager") self.cleanup_data() @@ -368,9 +370,9 @@ def apply_config(self, new_config): # TODO: check valid config file?! # write config to file try: - f = open('%s/worker/config.json'%(PROJECT_PATH),'w') - f.write(json.dumps(new_config)) - f.close() + with open('%s/worker/config.json'%(PROJECT_PATH),'w') as f: + f.write(json.dumps(new_config)) + except Exception as e: logging.exception("Wasn't able to write config file:\n%s" % e) @@ -437,7 +439,7 @@ def setup_actions(self): try: logging.info("Trying to register action: %s" % action["id"]) a = self.class_for_name(action["module"], action["class"]) - act = a(action["id"], action["params"]) + act = a(action["id"], action["params"], self) except Exception as e: #AttributeError, KeyError self.post_err("Pi with id '%s' wasn't able to register action '%s':\n%s" % (config.get('pi_id'), action["class"],e)) else: