From cb3a42c04e76840ca28406760fd187c73c95ae17 Mon Sep 17 00:00:00 2001 From: Daniel Pavel Date: Fri, 5 Oct 2012 02:39:32 +0300 Subject: [PATCH] greatly simplified loading of icons --- app/__init__.py | 21 +- app/constants.py | 10 - app/ui/__init__.py | 23 -- app/ui/icon.py | 11 +- app/ui/notify.py | 39 +-- app/ui/window.py | 254 +++++++----------- app/watcher.py | 174 ++++++------ images/devices/Unifying Receiver.png | Bin 2940 -> 0 bytes .../devices/Wireless Solar Keyboard K750.png | Bin 3254 -> 0 bytes images/icon.png | Bin 20756 -> 0 bytes images/light/0.png | Bin 7506 -> 0 bytes images/light/unknown.png | Bin 3299 -> 0 bytes lib/logitech/devices/constants.py | 26 +- lib/logitech/devices/k750.py | 17 +- lib/logitech/unifying_receiver/api.py | 132 ++++----- lib/logitech/unifying_receiver/base.py | 62 ++--- lib/logitech/unifying_receiver/constants.py | 4 + lib/logitech/unifying_receiver/exceptions.py | 12 +- lib/logitech/unifying_receiver/listener.py | 12 +- .../unifying_receiver/tests/test_30_base.py | 2 +- .../unifying_receiver/tests/test_50_api.py | 2 +- lib/logitech/unifying_receiver/unhandled.py | 10 +- resources/README | 3 + resources/icons/Solaar.png | Bin 0 -> 20700 bytes resources/icons/Unifying Receiver.png | Bin 0 -> 20700 bytes .../icons/Wireless Solar Keyboard K750.png | Bin 0 -> 54741 bytes .../0.png => resources/icons/battery_00.png | Bin .../5.png => resources/icons/battery_100.png | Bin .../1.png => resources/icons/battery_20.png | Bin .../2.png => resources/icons/battery_40.png | Bin .../3.png => resources/icons/battery_60.png | Bin .../4.png => resources/icons/battery_80.png | Bin .../icons/battery_unknown.png | Bin resources/icons/light_00.png | Bin 0 -> 12121 bytes .../5.png => resources/icons/light_100.png | Bin .../1.png => resources/icons/light_20.png | Bin .../2.png => resources/icons/light_40.png | Bin .../3.png => resources/icons/light_60.png | Bin .../4.png => resources/icons/light_80.png | Bin resources/icons/light_unknown.png | Bin 0 -> 5547 bytes solaar | 3 +- solaar.py | 6 +- 42 files changed, 376 insertions(+), 447 deletions(-) delete mode 100644 app/constants.py delete mode 100644 images/devices/Unifying Receiver.png delete mode 100644 images/devices/Wireless Solar Keyboard K750.png delete mode 100644 images/icon.png delete mode 100644 images/light/0.png delete mode 100644 images/light/unknown.png create mode 100644 resources/README create mode 100644 resources/icons/Solaar.png create mode 100644 resources/icons/Unifying Receiver.png create mode 100644 resources/icons/Wireless Solar Keyboard K750.png rename images/battery/0.png => resources/icons/battery_00.png (100%) rename images/battery/5.png => resources/icons/battery_100.png (100%) rename images/battery/1.png => resources/icons/battery_20.png (100%) rename images/battery/2.png => resources/icons/battery_40.png (100%) rename images/battery/3.png => resources/icons/battery_60.png (100%) rename images/battery/4.png => resources/icons/battery_80.png (100%) rename images/battery/unknown.png => resources/icons/battery_unknown.png (100%) create mode 100644 resources/icons/light_00.png rename images/light/5.png => resources/icons/light_100.png (100%) rename images/light/1.png => resources/icons/light_20.png (100%) rename images/light/2.png => resources/icons/light_40.png (100%) rename images/light/3.png => resources/icons/light_60.png (100%) rename images/light/4.png => resources/icons/light_80.png (100%) create mode 100644 resources/icons/light_unknown.png diff --git a/app/__init__.py b/app/__init__.py index 98976f4c..093969d6 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -6,11 +6,12 @@ import threading from gi.repository import Gtk from gi.repository import GObject -from . import constants as C from .watcher import WatcherThread from . import ui +APP_TITLE = 'Solaar' + def _status_updated(watcher, icon, window): while True: watcher.status_changed.wait() @@ -18,36 +19,32 @@ def _status_updated(watcher, icon, window): watcher.status_changed.clear() if icon: - GObject.idle_add(icon.set_tooltip_text, text) + GObject.idle_add(icon.set_tooltip_markup, text) if window: - ur_detected = watcher.has_receiver() - devices = [ watcher.devices[k] for k in watcher.devices ] if ur_detected else [] - GObject.idle_add(ui.window.update, window, ur_detected, devices) + GObject.idle_add(ui.window.update, window, dict(watcher.devices)) # def _pair_new_device(trigger, watcher): # pass -def run(images_path): +def run(): GObject.threads_init() - ui.init(images_path) - ui.notify.start(C.APP_TITLE, ui.image) + ui.notify.start(APP_TITLE) watcher = WatcherThread(ui.notify.show) watcher.start() - window = ui.window.create(C.APP_TITLE, ui.image) + window = ui.window.create(APP_TITLE, watcher.devices[0]) - menu_actions = [('Scan all devices', watcher.request_all_statuses), + menu_actions = [('Scan all devices', watcher.full_scan), # ('Pair new device', _pair_new_device, watcher), None, ('Quit', Gtk.main_quit)] - click_action = (ui.window.toggle, window) if window else None - tray_icon = ui.icon.create(ui.image('icon'), C.APP_TITLE, menu_actions, click_action) + tray_icon = ui.icon.create(APP_TITLE, menu_actions, (ui.window.toggle, window)) ui_update_thread = threading.Thread(target=_status_updated, name='ui_update', args=(watcher, tray_icon, window)) ui_update_thread.daemon = True diff --git a/app/constants.py b/app/constants.py deleted file mode 100644 index 39578bcc..00000000 --- a/app/constants.py +++ /dev/null @@ -1,10 +0,0 @@ -# -# Commonly used strings -# - -APP_TITLE = 'Solaar' -UNIFYING_RECEIVER = 'Unifying Receiver' -NO_DEVICES = 'No devices attached.' -SCANNING = 'Initializing...' -NO_RECEIVER = 'Unifying Receiver not found.' -FOUND_RECEIVER = 'Unifying Receiver found.' diff --git a/app/ui/__init__.py b/app/ui/__init__.py index 73ca10ae..2da03af6 100644 --- a/app/ui/__init__.py +++ b/app/ui/__init__.py @@ -1,26 +1,3 @@ # pass -import os.path as _os_path from . import (icon, notify, window) - - -_images_path = None -_IMAGES = {} - - -def init(images_path=None): - global _images_path - _images_path = images_path - - -def image(name): - if name in _IMAGES: - return _IMAGES[name] - - if _images_path: - path = _os_path.join(_images_path, name + '.png') - if _os_path.isfile(path): - _IMAGES[name] = path - return path - else: - _IMAGES[name] = None diff --git a/app/ui/icon.py b/app/ui/icon.py index 8bf0fcc1..b7218376 100644 --- a/app/ui/icon.py +++ b/app/ui/icon.py @@ -9,8 +9,8 @@ def _show_icon_menu(icon, button, time, menu): menu.popup(None, None, icon.position_menu, icon, button, time) -def create(app_icon, title, menu_actions, click_action=None): - icon = Gtk.StatusIcon.new_from_file(app_icon) +def create(title, menu_actions, click_action=None): + icon = Gtk.StatusIcon.new_from_icon_name(title) icon.set_title(title) icon.set_name(title) @@ -28,12 +28,11 @@ def create(app_icon, title, menu_actions, click_action=None): for action in menu_actions: if action: item = Gtk.MenuItem(action[0]) - function = action[1] args = action[2:] if len(action) > 2 else () - item.connect('activate', function, *args) - menu.append(item) + item.connect('activate', action[1], *args) else: - menu.append(Gtk.SeparatorMenuItem()) + item = Gtk.SeparatorMenuItem() + menu.append(item) menu.show_all() icon.connect('popup_menu', _show_icon_menu, menu) else: diff --git a/app/ui/notify.py b/app/ui/notify.py index 808553d8..8fa43fd2 100644 --- a/app/ui/notify.py +++ b/app/ui/notify.py @@ -7,28 +7,30 @@ try: available = True - _app_title = None - _images = lambda x: None _notifications = {} - def start(app_title, images=None): - global _app_title, _images + def start(app_title): + """Init the notifications system.""" _notify.init(app_title) - _app_title = app_title - _images = images or (lambda x: None) + return True def stop(): - global _app_title - _app_title = None - all(n.close() for n in list(_notifications.values())) - _notify.uninit() + """Stop the notifications system.""" + for n in list(_notifications.values()): + try: + n.close() + except Exception: + # DBUS + pass _notifications.clear() + _notify.uninit() - def show(status, title, text, icon=None): - if not _app_title: + def show(status_code, title, text, icon=None): + """Show a notification with title and text.""" + if not available: return if title in _notifications: @@ -40,11 +42,14 @@ try: # there's no need to show the same notification twice in a row return - path = _images('devices/' + title if icon is None else icon) - icon = ('error' if status < 0 else 'info') if path is None else path + icon = icon or title + notification.update(title, text, title) + try: + notification.show() + except Exception: + # DBUS + pass - notification.update(title, text, icon) - notification.show() except ImportError: import logging @@ -53,4 +58,4 @@ except ImportError: available = False def start(app_title): pass def stop(): pass - def show(status, title, text, icon=None): pass + def show(status_code, title, text, icon=None): pass diff --git a/app/ui/window.py b/app/ui/window.py index e9544e4b..ac18f334 100644 --- a/app/ui/window.py +++ b/app/ui/window.py @@ -4,210 +4,164 @@ from gi.repository import Gtk from gi.repository import Gdk -from gi.repository import GdkPixbuf - -from .. import constants as C -_DEVICE_ICON_SIZE = 48 -_STATUS_ICON_SIZE = 64 +_DEVICE_ICON_SIZE = Gtk.IconSize.DIALOG +_STATUS_ICON_SIZE = Gtk.IconSize.DIALOG _PLACEHOLDER = '~' -_images = None -_MAX_DEVICES = 7 - -_ICONS = {} +_MAX_DEVICES = 6 -def _icon(icon, title, size=_DEVICE_ICON_SIZE, fallback=None): - icon = icon or Gtk.Image() - - if title and title in _ICONS: - icon.set_from_pixbuf(_ICONS[title]) - else: - icon_file = _images(title) if title else None - if icon_file: - pixbuf = GdkPixbuf.Pixbuf().new_from_file(icon_file) - if pixbuf.get_width() > size or pixbuf.get_height() > size: - if pixbuf.get_width() > pixbuf.get_height(): - new_width = size - new_height = size * pixbuf.get_height() / pixbuf.get_width() - else: - new_width = size * pixbuf.get_width() / pixbuf.get_height() - new_height = size - pixbuf = pixbuf.scale_simple(new_width, new_height, GdkPixbuf.InterpType.HYPER) - icon.set_from_pixbuf(pixbuf) - _ICONS[title] = pixbuf - elif fallback: - icon.set_from_icon_name(fallback, size if size < _DEVICE_ICON_SIZE else Gtk.IconSize.DIALOG) - - if size >= _DEVICE_ICON_SIZE: - icon.set_size_request(size, size) - return icon - - -def update(window, ur_available, devices): +def update(window, devices): if not window or not window.get_child(): return + controls = list(window.get_child().get_children()) - first = controls[0] - first.set_visible(not ur_available or not devices) - if ur_available: - ur_status = C.FOUND_RECEIVER if devices else C.NO_DEVICES - else: - ur_status = C.NO_RECEIVER - _, label = first.get_children() - label.set_markup('%s\n%s' % (C.UNIFYING_RECEIVER, ur_status)) + first = controls[0].get_child() + icon, label = first.get_children() + rstatus = devices[0] + label.set_markup('%s\n%s' % (rstatus.name, rstatus.text)) - for index in range(1, _MAX_DEVICES): - box = controls[index] - devstatus = [d for d in devices if d.number == index] - devstatus = devstatus[0] if devstatus else None - box.set_visible(devstatus is not None) + for index in range(1, 1 + _MAX_DEVICES): + devstatus = devices.get(index) + controls[index].set_visible(devstatus is not None) + + box = controls[index].get_child() + icon, expander = box.get_children() if devstatus: - box.set_sensitive(devstatus.code >= 0) - icon, expander = box.get_children() - if not expander.get_data('devstatus'): - expander.set_data('devstatus', devstatus,) - _icon(icon, 'devices/' + devstatus.name, fallback=devstatus.type.lower()) + if icon.get_name() != devstatus.name: + icon.set_name(devstatus.name) + icon.set_from_icon_name(devstatus.name, _DEVICE_ICON_SIZE) - label = expander.get_label_widget() - if expander.get_expanded(): - label.set_markup('%s' % devstatus.name) + if devstatus.code < 0: + expander.set_sensitive(False) + expander.set_expanded(False) + expander.set_label('%s\n%s' % (devstatus.name, devstatus.text)) else: - label.set_markup('%s\n%s' % (devstatus.name, devstatus.props['text'])) + expander.set_sensitive(True) + ebox = expander.get_child() - ebox = expander.get_child() + texts = [] - # refresh_button = ebox.get_children()[0] - # refresh_button.connect('activate', devstatus.refresh) + light_icon = ebox.get_children()[-2] + light_level = getattr(devstatus, 'light_level', None) + light_icon.set_visible(light_level is not None) + if light_level is not None: + texts.append('Light: %d lux' % light_level) + icon_name = 'light_%02d' % (20 * ((light_level + 50) // 100)) + light_icon.set_from_icon_name(icon_name, _STATUS_ICON_SIZE) + light_icon.set_tooltip_text(texts[-1]) - texts = [] + battery_icon = ebox.get_children()[-1] + battery_level = getattr(devstatus, 'battery_level', None) + battery_icon.set_sensitive(battery_level is not None) + if battery_level is None: + battery_icon.set_from_icon_name('battery_unknown', _STATUS_ICON_SIZE) + battery_icon.set_tooltip_text('Battery: unknown') + else: + texts.append('Battery: %d%%' % battery_level) + icon_name = 'battery_%02d' % (20 * ((battery_level + 10) // 20)) + battery_icon.set_from_icon_name(icon_name, _STATUS_ICON_SIZE) + battery_icon.set_tooltip_text(texts[-1]) - battery_icon = ebox.get_children()[-1] - if 'battery-level' in devstatus.props: - level = devstatus.props['battery-level'] - icon_name = 'battery/' + str((level + 10) // 20) - _icon(battery_icon, icon_name, _STATUS_ICON_SIZE) - texts.append('Battery: ' + str(level) + '%') - else: - _icon(battery_icon, 'battery/unknown', _STATUS_ICON_SIZE) - texts.append('Battery: unknown') - battery_icon.set_tooltip_text(texts[-1]) + battery_status = getattr(devstatus, 'battery_status', None) + if battery_status is not None: + texts.append(battery_status) + battery_icon.set_tooltip_text(battery_icon.get_tooltip_text() + '\n' + battery_status) - light_icon = ebox.get_children()[-2] - if 'light-level' in devstatus.props: - lux = devstatus.props['light-level'] - icon_name = 'light/' + str((lux + 50) // 100) - _icon(light_icon, icon_name, _STATUS_ICON_SIZE) - - texts.append('Light: ' + str(lux) + ' lux') - light_icon.set_tooltip_text(texts[-1]) - light_icon.set_visible(True) - else: - light_icon.set_visible(False) - - label = ebox.get_children()[-3] - label.set_text('\n'.join(texts)) - -def _expander_activate(expander): - devstatus = expander.get_data('devstatus') - if devstatus: - label = expander.get_label_widget() - if expander.get_expanded(): - label.set_markup('%s\n%s' % (devstatus.name, devstatus.props['text'])) + if texts: + expander.set_label('%s\n%s' % (devstatus.name, ', '.join(texts))) + else: + expander.set_label('%s\n%s' % (devstatus.name, devstatus.text)) else: - label.set_markup('%s' % devstatus.name) + icon.set_name(_PLACEHOLDER) + expander.set_label(_PLACEHOLDER) def _device_box(title): - icon = _icon(None, 'devices/' + title) + icon = Gtk.Image.new_from_icon_name(title, _DEVICE_ICON_SIZE) icon.set_alignment(0.5, 0) + icon.set_name(title) - label = Gtk.Label() - label.set_markup('%s' % title) - label.set_alignment(0, 0.5) - label.set_can_focus(False) - - box = Gtk.HBox(spacing=10) + box = Gtk.HBox(homogeneous=False, spacing=8) box.pack_start(icon, False, False, 0) + box.set_border_width(8) - if title == C.UNIFYING_RECEIVER: - box.add(label) - else: + if title == _PLACEHOLDER: expander = Gtk.Expander() expander.set_can_focus(False) - expander.set_label_widget(label) - expander.connect('activate', _expander_activate) + expander.set_label(_PLACEHOLDER) + expander.set_use_markup(True) + expander.set_spacing(4) - ebox = Gtk.HBox(False, 10) - ebox.set_border_width(4) + ebox = Gtk.HBox(False, 8) - # refresh_button = Gtk.Button() - # refresh_button.set_image(_icon(None, None, size=Gtk.IconSize.SMALL_TOOLBAR, fallback='reload')) - # refresh_button.set_focus_on_click(False) - # refresh_button.set_can_focus(False) - # refresh_button.set_image_position(Gtk.PositionType.TOP) - # refresh_button.set_alignment(0.5, 0.5) - # refresh_button.set_relief(Gtk.ReliefStyle.NONE) - # refresh_button.set_size_request(20, 20) - # refresh_button.set_tooltip_text('Refresh') - # ebox.pack_start(refresh_button, False, False, 2) - - label = Gtk.Label() - label.set_alignment(0, 0.5) - ebox.pack_start(label, False, True, 8) - - light_icon = _icon(None, 'light/unknown', _STATUS_ICON_SIZE) - ebox.pack_end(light_icon, False, True, 0) - - battery_icon = _icon(None, 'battery/unknown', _STATUS_ICON_SIZE) + battery_icon = Gtk.Image.new_from_icon_name('battery_unknown', _STATUS_ICON_SIZE) ebox.pack_end(battery_icon, False, True, 0) + light_icon = Gtk.Image.new_from_icon_name('light_unknown', _STATUS_ICON_SIZE) + ebox.pack_end(light_icon, False, True, 0) + expander.add(ebox) box.pack_start(expander, True, True, 1) + else: + label = Gtk.Label() + label.set_can_focus(False) + label.set_markup('%s' % title) + label.set_alignment(0, 0) + box.add(label) - box.show_all() - box.set_visible(title != _PLACEHOLDER) - return box + frame = Gtk.Frame() + frame.add(box) + frame.show_all() + frame.set_visible(title != _PLACEHOLDER) + return frame -def create(title, images=None): - global _images - _images = images or (lambda x: None) +def create(title, rstatus): + vbox = Gtk.VBox(homogeneous=False, spacing=4) + vbox.set_border_width(4) - vbox = Gtk.VBox(spacing=8) - vbox.set_border_width(6) - - vbox.add(_device_box(C.UNIFYING_RECEIVER)) - for i in range(1, _MAX_DEVICES): + vbox.add(_device_box(rstatus.name)) + for i in range(1, 1 + _MAX_DEVICES): vbox.add(_device_box(_PLACEHOLDER)) vbox.set_visible(True) - window = Gtk.Window() # Gtk.WindowType.POPUP) + window = Gtk.Window() window.set_title(title) - window.set_icon_from_file(_images('icon')) + window.set_icon_name(title) window.set_keep_above(True) - window.set_decorated(False) - window.set_skip_taskbar_hint(True) - window.set_skip_pager_hint(True) + # window.set_skip_taskbar_hint(True) + # window.set_skip_pager_hint(True) window.set_deletable(False) window.set_resizable(False) window.set_position(Gtk.WindowPosition.MOUSE) - window.set_type_hint(Gdk.WindowTypeHint.TOOLTIP) - window.connect('focus-out-event', _hide) + window.set_type_hint(Gdk.WindowTypeHint.UTILITY) + window.set_wmclass(title, 'status-window') + window.set_role('status-window') + + window.connect('window-state-event', _state_event) + window.connect('delete-event', lambda w, e: toggle(None, window) or True) window.add(vbox) + window.present() return window -def _hide(window, _): - window.set_visible(False) - +def _state_event(window, event): + if event.new_window_state & Gdk.WindowState.ICONIFIED: + position = window.get_position() + window.hide() + window.deiconify() + window.move(*position) + return True def toggle(_, window): if window.get_visible(): - window.set_visible(False) + position = window.get_position() + window.hide() + window.move(*position) else: window.present() diff --git a/app/watcher.py b/app/watcher.py index 3b058496..1d78c162 100644 --- a/app/watcher.py +++ b/app/watcher.py @@ -6,25 +6,31 @@ import logging import threading import time -import constants as C from logitech.unifying_receiver import api from logitech.unifying_receiver.listener import EventsListener from logitech import devices -_STATUS_TIMEOUT = 97 # seconds -_THREAD_SLEEP = 7 # seconds -_FORGET_TIMEOUT = 5 * 60 # seconds +_STATUS_TIMEOUT = 34 # seconds +_THREAD_SLEEP = 5 # seconds + + +_UNIFYING_RECEIVER = 'Unifying Receiver' +_NO_DEVICES = 'No devices attached.' +_SCANNING = 'Initializing...' +_NO_RECEIVER = 'not found' +_FOUND_RECEIVER = 'found' class _DevStatus(api.AttachedDeviceInfo): timestamp = time.time() - code = devices.STATUS.CONNECTED - props = {devices.PROPS.TEXT: devices.STATUS_NAME[devices.STATUS.CONNECTED]} + code = devices.STATUS.UNKNOWN + text = '' refresh = None class WatcherThread(threading.Thread): + """Keeps a map of all attached devices and their statuses.""" def __init__(self, notify_callback=None): super(WatcherThread, self).__init__(name='WatcherThread') self.daemon = True @@ -35,39 +41,46 @@ class WatcherThread(threading.Thread): self.status_changed = threading.Event() self.listener = None - self.devices = {} + + self.rstatus = _DevStatus(0, _UNIFYING_RECEIVER, _UNIFYING_RECEIVER, None, None) + self.rstatus.refresh = self.full_scan + self.devices = {0: self.rstatus} def run(self): self.active = True - self._notify(0, C.UNIFYING_RECEIVER, C.SCANNING) + self._notify(0, _UNIFYING_RECEIVER, _SCANNING) while self.active: if self.listener is None: receiver = api.open() if receiver: - self._notify(1, C.UNIFYING_RECEIVER, C.FOUND_RECEIVER) + self._device_status_changed(self.rstatus, (devices.STATUS.CONNECTED, _FOUND_RECEIVER)) + for devinfo in api.list_devices(receiver): - devstatus = _DevStatus(*devinfo) - self.devices[devinfo.number] = devstatus - self._notify(devices.STATUS.CONNECTED, devstatus.name, devices.STATUS_NAME[devices.STATUS.CONNECTED]) + self._new_device(devinfo) + + if len(self.devices) == 1: + self._device_status_changed(self.rstatus, (devices.STATUS.CONNECTED, _NO_DEVICES)) + + self._update_status_text() + self.listener = EventsListener(receiver, self._events_callback) self.listener.start() - self._update_status() else: - self._notify(-1, C.UNIFYING_RECEIVER, C.NO_RECEIVER) + self._device_status_changed(self.rstatus, (devices.STATUS.UNAVAILABLE, _NO_RECEIVER)) elif not self.listener.active: self.listener = None - self._notify(-1, C.UNIFYING_RECEIVER, C.NO_RECEIVER) - self.devices.clear() + self._device_status_changed(self.rstatus, (devices.STATUS.UNAVAILABLE, _NO_RECEIVER)) + self.devices = {0: self.rstatus} if self.active: update_icon = True - if self.listener and self.devices: + if self.listener and len(self.devices) > 1: update_icon &= self._check_old_statuses() if self.active: if update_icon: - self._update_status() + self._update_status_text() time.sleep(_THREAD_SLEEP) def stop(self): @@ -76,49 +89,55 @@ class WatcherThread(threading.Thread): self.listener.stop() api.close(self.listener.receiver) - def has_receiver(self): - return self.listener is not None and self.listener.active - - def request_all_statuses(self, _=None): + def full_scan(self, _=None): updated = False - for d in range(1, 7): - devstatus = self.devices.get(d) + for devnumber in range(1, 1 + api.C.MAX_ATTACHED_DEVICES): + devstatus = self.devices.get(devnumber) if devstatus: status = devices.request_status(devstatus, self.listener) updated |= self._device_status_changed(devstatus, status) else: - devstatus = self._new_device(d) + devstatus = self._new_device(devnumber) updated |= devstatus is not None if updated: - self._update_status() + self._update_status_text() + + def _request_status(self, devstatus): + if devstatus: + status = devices.request_status(devstatus, self.listener) + self._device_status_changed(devstatus, status) def _check_old_statuses(self): updated = False for devstatus in list(self.devices.values()): - if time.time() - devstatus.timestamp > _STATUS_TIMEOUT: - status = devices.ping(devstatus, self.listener) - updated |= self._device_status_changed(devstatus, status) + if devstatus != self.rstatus: + if time.time() - devstatus.timestamp > _STATUS_TIMEOUT: + status = devices.ping(devstatus, self.listener) + updated |= self._device_status_changed(devstatus, status) return updated - def _new_device(self, device): - devinfo = api.get_device_info(self.listener.receiver, device) - if devinfo: - devstatus = _DevStatus(*devinfo) - self.devices[device] = devstatus - self._notify(devstatus.code, devstatus.name, devstatus.props[devices.PROPS.TEXT]) - return devinfo + def _new_device(self, dev): + if type(dev) == int: + dev = api.get_device_info(self.listener.receiver, dev) + logging.debug("new devstatus from %s", dev) + if dev: + devstatus = _DevStatus(*dev) + devstatus.refresh = self._request_status + self.devices[dev.number] = devstatus + self._device_status_changed(devstatus, devices.STATUS.CONNECTED) + return devstatus - def _events_callback(self, code, device, data): - logging.debug("%s: event %02x %d %s", time.asctime(), code, device, repr(data)) + def _events_callback(self, code, devnumber, data): + logging.debug("%s: event %02x %d %s", time.asctime(), code, devnumber, repr(data)) updated = False - if device in self.devices: - devstatus = self.devices[device] + if devnumber in self.devices: + devstatus = self.devices[devnumber] if code == 0x10 and data[0] == 'b\x8F': updated = True self._device_status_changed(devstatus, devices.STATUS.UNAVAILABLE) @@ -127,17 +146,16 @@ class WatcherThread(threading.Thread): updated |= self._device_status_changed(devstatus, status) else: logging.warn("unknown event code %02x", code) - elif device: - logging.debug("got event (%d, %d, %s) for new device", code, device, repr(data)) - self._new_device(device) + elif devnumber: + self._new_device(devnumber) updated = True else: - logging.warn("don't know how to handle event (%d, %d, %s)", code, device, data) + logging.warn("don't know how to handle event (%d, %d, %s)", code, devnumber, data) if updated: - self._update_status() + self._update_status_text() - def _device_status_changed(self, devstatus, status): + def _device_status_changed(self, devstatus, status=None): if status is None: return False @@ -147,15 +165,19 @@ class WatcherThread(threading.Thread): if type(status) == int: devstatus.code = status if devstatus.code in devices.STATUS_NAME: - devstatus.props[devices.PROPS.TEXT] = devices.STATUS_NAME[devstatus.code] + devstatus.text = devices.STATUS_NAME[devstatus.code] else: devstatus.code = status[0] - devstatus.props.update(status[1]) + if isinstance(status[1], str): + devstatus.text = status[1] + elif isinstance(status[1], dict): + for key, value in status[1].items(): + setattr(devstatus, key, value) if old_status_code != devstatus.code: - logging.debug("%s: device status changed %s => %s: %s", time.asctime(), old_status_code, devstatus.code, devstatus.props) - # if not (devstatus.code == 0 and old_status_code > 0): - self._notify(devstatus.code, devstatus.name, devstatus.props[devices.PROPS.TEXT]) + logging.debug("%s: device '%s' status changed %s => %s: %s", time.asctime(), devstatus.name, old_status_code, devstatus.code, devstatus.text) + if devstatus.code // 256 != old_status_code // 256: + self._notify(devstatus.code, devstatus.name, devstatus.text) return True @@ -163,38 +185,30 @@ class WatcherThread(threading.Thread): if self.notify: self.notify(*args) - def notify_full(self): - if self.listener and self.listener.active: - if self.devices: - for devstatus in self.devices.values(): - self._notify(0, devstatus.name, devstatus.props[devices.PROPS.TEXT]) - else: - self._notify(0, C.UNIFYING_RECEIVER, C.NO_DEVICES) - else: - self._notify(-1, C.UNIFYING_RECEIVER, C.NO_RECEIVER) - - def _update_status(self): + def _update_status_text(self): last_status_text = self.status_text - if self.listener and self.listener.active: - if self.devices: - all_statuses = [] - for d in self.devices: - devstatus = self.devices[d] - status_text = devstatus.props[devices.PROPS.TEXT] - if status_text: - if ' ' in status_text: - all_statuses.append(devstatus.name) - all_statuses.append(' ' + status_text) - else: - all_statuses.append(devstatus.name + ' ' + status_text) - else: - all_statuses.append(devstatus.name) - self.status_text = '\n'.join(all_statuses) - else: - self.status_text = C.NO_DEVICES + if self.rstatus.code < 0: + self.status_text = '' + self.rstatus.name + ': ' + self.rstatus.text else: - self.status_text = C.NO_RECEIVER + all_statuses = [] + for devnumber in range(1, 1 + api.C.MAX_ATTACHED_DEVICES): + if devnumber in self.devices: + devstatus = self.devices[devnumber] + if devstatus.text: + if ' ' in devstatus.text: + all_statuses.append('' + devstatus.name + '') + all_statuses.append(' ' + devstatus.text) + else: + all_statuses.append('' + devstatus.name + ': ' + devstatus.text) + else: + all_statuses.append('' + devstatus.name + '') + all_statuses.append('') + + if all_statuses: + self.status_text = '\n'.join(all_statuses).rstrip('\n') + else: + self.status_text = '' + self.rstatus.name + ': ' + _NO_DEVICES if self.status_text != last_status_text: self.status_changed.set() diff --git a/images/devices/Unifying Receiver.png b/images/devices/Unifying Receiver.png deleted file mode 100644 index 15fae36625c879fbab5c362650a3d8ad636cb346..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2940 zcmV-?3xo8DP)^uMf3kgX? zK~!ko?U`+i9p!b$f9E{U+?RdxOWj@DU~ID?2~Z$4kb)_o1SE(9f}~QLsI62r*r|+& z+An?iShZ?PRJ9*kiU?^GDODAzEir0rKnhY2rP!OQiqn=7H#oLyuuIl<*WSDL&YhX( z^us(eb8RAZy%Z~D zmMvF@Bxy~k$XKwD471#M@7?&=nD^dE2q6GPQ3R)=>b&!+(iZRr;(dZyP;pMgNYrWK zop+)l-gz!uxS$IQ3txHexxf3HRdrxy5gEa2~Nk&C#ePE9;3wp^>0%|iX9USSraY1GV7 z)m!wTG|U=ms?NvCDgRbRiamzBI#UH;)g2gQxm5-sWwA+Bcvb2nEGj%#h1@Vwbl5^< zGoi8DF0V0NE`+@IF`5=LE_Lcvq%Hx~5i=_CuSq!8Ok^>$29kn|md@%!C`$)*l~r8s zyhlYF1`#1m2jzzvgIYDM7=2ObcDto-r3a*GiiI#*EV}9rAYvsvO6x-r_?LhEH?m=h zmSN|@`SaZV(T~#Yc1ojFYDB9D7K~S3d6nTX#ruR13i?ZZuD{_%W@on(LiG1C8riZP zXtg^HltnpvW}X*bc!_go=jnF46h*)gP2nB<|08xcd)NnIE zt<*fdr6o?BI8hd}0T!5?n!-6(vWmP{pRS4nCK9Zs8DrzdjXeDD!_3eBh~Y4ca-+q) z_uhkr0uhaLB4|v50FUq8%X8oO21N*jq97fleER1;MSswzR1lX(q|0}p2nAT=U7^$N z@P#it!J$KQgb;AfF)=a0%*@8fNLDiw7-l7`KCx>T;}a7gf_Dy8;pUrf!9o~8j;%h8 z4)d(cfJp2Ifti_&Jo3mRqq>4%h6-2|bQOJ8B%kLQckSHS3^j}@RN|ndtDga<9y2TH zP(VfB8z-wU+=xA?6l=vqRi7HsNR8a6<{En+iddYeD&pKFMn#2c)sVv_MW{`LrI`dq zg=?AErt8W3(FfF*Rj4W>BV#icRQQdEzbHGkHX6~)^?*}1-)02T%a{k2-^h|gONi(t znz1szp-iz-GK?BrD^m=q^^i3qrZi&DE<;Kz`(Wa|nFUl8=M;4g=N#%hMG-iD{20A{ zpH{1dsKj#)r;1j$C~KzHFn{J8$B&;VwUoy1iJz+oav3AdvK??vlX3>ui*6^v*w`4( zdCo5^@MnMi6c$2rCOYbzDcb{RCZ?1O8j))GbyQ$?bI z2F%XRa_#IaZ@u*cf?15JL#ybjG8pukn>)l!H{HxlKXp@`fgcwXfXDYfzB&#(^w2|e zI_*MLaLyyDh(sr(Y-*~?a4_Jd7hf#*Ln1gg0ww1OA#mi#oAj5KNYmlSXAbW@-g!Em z4$k{AfT#ZADZcnePp*73_shTXt9Un zdiOo|Jho%UPt$I-q#9f*q1FuThN#4u*qYI^=JhB+>J?(sA3{BLmKjwMf|Zh^*IQz4 z?mHg`_OHl+&wXz9x+nkO_cu&TPBKhWvOI5=x|Pm}Vl9MFarniCR@=DP8;ZOrRi{b4 zsk4}(5c`6vAfhrcF;0@SZN-i3XYRPu4jkCekt0WH!$YNq>h39ZGb@8>@7>%<)5t=U z4_UB!K~OFRz-uW2)hQMNvmdyQBx#MWxCYG3Z{4;%o1cG|P*{oE5%E<F*6RIO*!zNJr=V#2nqIq+3RF-YR#jE4*uiwE22>m z$=9u0|2s+2qS}L)K?qi2w+=xlF+Q?)m$>(-c1KmDy54c*Q&;h89~|T3GYP-6t;-!7 zT73D=b)5Y9Ye-a~BnLr+XP$ZX#TEB~`|f{$_3MA)%Ttq6dA-w#w^+a|l#ASIXsLBg z1d=p6b&ERbv$InKGlqq+W8d4n)eC&~m3I+Q!~!2)n_y;azUpc=ZQA_AM{c<>U9kf% zf9oZZ#EYn!ijJb8!FFA*jlz_XRe2-y%lEd7IZpKp7BXYJr9AfPyX>59^TxuEL4XOT zB;M2QbWoAASFA?6ovvY4%IJ&av4Vw*@NLaNQWx$e)xek+zIJqpzy4v53whx6hp(ag zS0_05qak0~xdEpY1eLrf?24qs&)#)6d7fqB93j}n+rmqqY*o>|#Q00E#XRtvH%>CQ zYlgfC-2K979=*E5n~!ed-syy;BF=1P^!rO&uE>FZc6-b20f2_cXd1!V^>cu+6-kM0+pe{fCr_|;?Rsv#?KXVUqA2pX=M+>OW&sN}vNH-4MS-di zBHtU3XE~{Q{$%=XK9~$>i;)FmJWErgTa8UTep*k{QhG{kG{O( z8t8O7OiWC0+wHeAIXOiL0i%s~j$xJ|adU0e(-@55FlTJ6i}MNDFa=R0Y9v+R_s(x6 zh{HRFU=$(XoTuAL*nUl5veRO2?jWspLeVc;D=lIH+CE8oS6#Jb{J{r5!Su`wMV2wl zGQ4*nO5ziI;u*wgEXy*y_w;%_49K#qmd)Nd(ljMlARA_w8AXxPUmCF3Tcq7?vuX2Y z`b$fkI(-T=V=x$Wfi{q?#DVc5&%WIqoA~4nH{8IQsY!ahC6Xjc;4C8@rsR3S*jR@w z%WzI9ii~!<1!iux{--{_EY-#rcJEKL8v* z?wR=iQUeOCPm<)iJMP^1#4t^-%ko@{qKMD1%)IxOv=Z^&OFQWxPQt=}FU(iNOi{M$ zAf+TV@0_TrsESyC5FH62gkEoP020Q>$2%c}#ZI?-a_-Qh(X~D26sHLj@uL0000!&y0NFVp#|hBO$#1`@=G58)#k-RybuUVT+x zeN}IWPR7YN87JdpoQ#ukGXA3xMUgssR$sFrI&MdovG(MtUfJE%+wHc|>-P1LH`4vU zH=^-aA7iee>y{mlJ8sg=>be$|r_1-%S73z6oAc%SzPY^onelAvnYp)DF`BKG*=cu- ze!pjQdp)z?9~zpb%tRs)Po~^d(s5GpL_B4gW@a3QDO_p3M-inJMQN;wJEfGS(wfp- zrD?n$jmKk3xGB2!^0iOZbH>Cz_}kx0dwW&0-fWni&VkwMcCEo^XnMnu>3P02_B}HQ z0xNFEoOnE*jKyNEuIouG>JEn^*YkZBMkIaDbA!-#0m=>WKNfc_(@L7Ap(*U@4?XgI zk34TkQ8*@3*T^4p*M077ntestrf$~ZFq%{RW6 z{K5Bs_&Y<_uH$1{MU;RS9Bn*K;A1BU!$c58jz10oAf#q>NC(|6RcdvD;pB}*vE0p zE)138DBvwi=Yrq#|3>RRSA11_RJ!p+OMP0X%O6 zK80g3Oa);;yj&EG#mN2IJ{=r%0XCdOAjCWs$@iHzpcirUIAh0}F7M&b$%SVh#*Oe@ zEr=!nK%GbvIHU}w5-0@6f@4(3X7N_LD*%4~+g}^acKgLfyGyd*dj;;L z;mE_Lns}8L_WY4}0_lj&H1fR>H5x5|3&~BVL8&3d>D1Kcf8!JumEfD#FZMv+G8 zv_oAu!-SJGEYxeX$-pxb7I%|4VGYm=Gy(60`-Ge$3m`05T`ZNDwx0{`7*HYa z&`za8OXrHTys|}0OXp~Jd!6FRJe(4d7aEi)DZ=w~UL%}}jYrBphG zFj=&Z&o}}cM@{F<&}gI5Rs5t7L!2}F9)Hb%}wwgv}raC8uUSzQ5R7;pa&1usMkFp%N~JIaExvu z@%vaepvq1t)N-99864@sKyqpvfI6TblxtF~;LUgRVpm*j(9!+-`Ai$!|&>=~u-8Hcmi?MXNxvzTLx3UP9A9t_|FC&{YWMWQ)W znn_4DBK@H@F>qK1;E_;=*JIiQ0HEnCmAZJF-=Stn!bgcn_7bWAU?QHNbSkCTwsa;v zN#dF5>D;Ybx6-J7l7uKW;Fm|ad=8rpiIpY}=^Ma18HAXPbyKeVpMCp3hX`WLd?7FEmdj<@-rg3Y`Q6s$mh7n`j|Tm|%w-ld z`iSy4piC-F<=GjQ)=?s)h3i~&}B$I0C9oY zc)CuuZPV(#RoRq{V6U;v3UJSdBtr~(J!&=BBKR zYE8Y3o;Zi+fYQVT3q@0?#ts?{K*6*|Q&S~SHCTaNk#ToW+ikVy_V zKkGs(SG>3YkFMOkOD|r&M2{b>QE7TwD8r#qbV*ww0~a z754Ol)d%8%cDo}U<4{IeltG|1z+x@xW06ljzAe((L$0ty@-s&xX2-upqRttk}db?86b@Dt>U#k$087J>*wh-l4gJb3NLx*Xfm)uSNNM zUctr{0E!G4g+drzWxdIwI3O`#h)q+aDXQ&N!DW*iEYv`R=1$Gg>itzjVu3a{HjspA z0i`q)AhZ(fWlppa=vGII!MVYb*gfb`Ww#=NzzJKI_G2i3ip2uFZHNQB5sD;KYB(MW zO(#7NC>Vw!Dsj9^CSApOSFKd;z5TNrk#Y5#SFH~}{AiIk;Lxr=eG1Q5*km6GI2PGL z`wGwZWl`p00IwtwN~VBmnnF1)I$W7c=y%pYuM3OkAc({afu-jfw-Ad+fQb-zk$YmZU<(n2eM4MEWzUduo$yXc@g=5pBx zMyXb_B}TC)nGVe1YGsc-_K6&yK3RIxoogFD^88CsPRR?8epi=BG?uS@9IqKNwKB~2Z#aLfo|5l|^ zVcAqwP=*tidmf&w4o^IsP&SgSG(AZqmRGK#sdP%b%N-^I;)}!0o2{)q5@3ybLnKrh zHJuaJkvUwj>W!Khnniwaj`5zH%ocKh=X2p=uzc}%cps)5BE1SmNULi=_R1W7>@5^Y zAxtb`tlwBLYPH&|l2Dp(Q}R*mA3c0X=PsNVuo>*_90GLRqzHin5FA-nFutayijdRc{So&p3;?q9 z5lZtdSeeEbG6;Ffj@dXBg<8MYRjdLQ`gKkm2Ectg42`UqsXFZgp_^3Xm?pGqwFW5v zF;OH=Y_1;+(8N0i$54#09)ID<%LJTWSQj_ zAqzTj@j5jHkZwA9^mJcwg0ldOBzZd`r)U^OPMLNL0w+CbDVR2|z5ZR1OpYcimnaqZ z&v|uJ$XH6>K*Im>SHECNUAun$&5!BuEUVsq_uXyW_i&jsIala7tJ?3p^G<%cG+l&* z7Qp2q+KfEBT0{;M;i@7QFCZ8NcrP7<1A4MvRlB=2ni7v&linSreRgh6LA!;^T;Z9H zr{+(i;B5;{7)%HS7rgoTd9>e#({Sm&@E;_n>6~N45F2uJ2g9v{FwtC z$}oNg^qA=nh6xls#l6ygttP$DOV?f!x*)+LR9(f@c?YtM&QkzzJ;>#9T$vxXTAkr> z0CWfKr0qLRJ+^^@a22rNv-Sh;YQxjU?v2?e^W}JKg{0 zhb{Ho^YfSXCD*_Fh{eFpoIUHHGj$*uPA;EMfR(w$#ijYFsi_5Y1M?vKX~^pw1Vyp> zK}H`zJbr%T?Hm92%72*ychzCf@;pH8OTg)00L(;!+AuWE11zvnaT5y*^I0UZ4tjm| z@$K6y%XjV!{#QROsxSFp`+}&cBUL;Gj{iqLr)h{th)DGK7obDo`PzRQRsROC8m;e9( diff --git a/images/icon.png b/images/icon.png deleted file mode 100644 index 314ed2316c46fd022e2eed94a398feed7e7c82b9..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 20756 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 _CHARGE_LIMITS[i]: + _CHARGE_LEVELS = (10, 25, 256) + for i in range(0, len(_CHARGE_LEVELS)): + if charge < _CHARGE_LEVELS[i]: charge_index = i break - else: - charge_index = 0 d[C.PROPS.BATTERY_LEVEL] = charge text = 'Battery %d%%' % charge - if lux > 0: + if hasLux: d[C.PROPS.LIGHT_LEVEL] = lux text = 'Light: %d lux' % lux + ', ' + text + else: + d[C.PROPS.LIGHT_LEVEL] = None d[C.PROPS.TEXT] = text return 0x10 << charge_index, d @@ -61,7 +60,7 @@ def process_event(devinfo, listener, data): if data[:2] == b'\x09\x10' and data[7:11] == b'GOOD': # regular solar charge events - return _charge_status(data) + return _charge_status(data, True) if data[:2] == b'\x09\x20' and data[7:11] == b'GOOD': logging.debug("Solar key pressed") diff --git a/lib/logitech/unifying_receiver/api.py b/lib/logitech/unifying_receiver/api.py index d615bd48..408c0df1 100644 --- a/lib/logitech/unifying_receiver/api.py +++ b/lib/logitech/unifying_receiver/api.py @@ -42,7 +42,7 @@ def open(): close = _base.close -def request(handle, device, feature, function=b'\x00', params=b'', features_array=None): +def request(handle, devnumber, feature, function=b'\x00', params=b'', features_array=None): """Makes a feature call to the device, and returns the reply data. Basically a write() followed by (possibly multiple) reads, until a reply @@ -65,22 +65,22 @@ def request(handle, device, feature, function=b'\x00', params=b'', features_arra feature_index = b'\x00' else: if features_array is None: - features_array = get_device_features(handle, device) + features_array = get_device_features(handle, devnumber) if features_array is None: - _l.log(_LOG_LEVEL, "(%d,%d) no features array available", handle, device) + _l.log(_LOG_LEVEL, "(%d,%d) no features array available", handle, devnumber) return None if feature in features_array: feature_index = _pack('!B', features_array.index(feature)) if feature_index is None: - _l.warn("(%d,%d) feature <%s:%s> not supported", handle, device, _hexlify(feature), C.FEATURE_NAME[feature]) - raise E.FeatureNotSupported(device, feature) + _l.warn("(%d,%d) feature <%s:%s> not supported", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature]) + raise E.FeatureNotSupported(devnumber, feature) - return _base.request(handle, device, feature_index + function, params) + return _base.request(handle, devnumber, feature_index + function, params) -def ping(handle, device): - """Pings a device number to check if it is attached to the UR. +def ping(handle, devnumber): + """Pings a device to check if it is attached to the UR. :returns: True if the device is connected to the UR, False if the device is not attached, None if no conclusive reply is received. @@ -92,39 +92,39 @@ def ping(handle, device): if not reply: return None - reply_code, reply_device, reply_data = reply + reply_code, reply_devnumber, reply_data = reply - if reply_device != device: + if reply_devnumber != devnumber: # oops - _l.log(_LOG_LEVEL, "(%d,%d) ping: reply for another device %d: %s", handle, device, reply_device, _hexlify(reply_data)) - _unhandled._publish(reply_code, reply_device, reply_data) + _l.log(_LOG_LEVEL, "(%d,%d) ping: reply for another device %d: %s", handle, devnumber, reply_devnumber, _hexlify(reply_data)) + _unhandled._publish(reply_code, reply_devnumber, reply_data) return _status(_base.read(handle)) if (reply_code == 0x11 and reply_data[:2] == b'\x00\x10' and reply_data[4:5] == ping_marker): # ping ok - _l.log(_LOG_LEVEL, "(%d,%d) ping: ok [%s]", handle, device, _hexlify(reply_data)) + _l.log(_LOG_LEVEL, "(%d,%d) ping: ok [%s]", handle, devnumber, _hexlify(reply_data)) return True if (reply_code == 0x10 and reply_data[:2] == b'\x8F\x00'): # ping failed - _l.log(_LOG_LEVEL, "(%d,%d) ping: device not present", handle, device) + _l.log(_LOG_LEVEL, "(%d,%d) ping: device not present", handle, devnumber) return False if (reply_code == 0x11 and reply_data[:2] == b'\x09\x00' and len(reply_data) == 18 and reply_data[7:11] == b'GOOD'): # some devices may reply with a SOLAR_CHARGE event before the # ping_ok reply, especially right after the device connected to the # receiver - _l.log(_LOG_LEVEL, "(%d,%d) ping: solar status [%s]", handle, device, _hexlify(reply_data)) - _unhandled._publish(reply_code, reply_device, reply_data) + _l.log(_LOG_LEVEL, "(%d,%d) ping: solar status [%s]", handle, devnumber, _hexlify(reply_data)) + _unhandled._publish(reply_code, reply_devnumber, reply_data) return _status(_base.read(handle)) # ugh - _l.log(_LOG_LEVEL, "(%d,%d) ping: unknown reply for this device: %d=[%s]", handle, device, reply_code, _hexlify(reply_data)) - _unhandled._publish(reply_code, reply_device, reply_data) + _l.log(_LOG_LEVEL, "(%d,%d) ping: unknown reply for this device: %d=[%s]", handle, devnumber, reply_code, _hexlify(reply_data)) + _unhandled._publish(reply_code, reply_devnumber, reply_data) return None - _l.log(_LOG_LEVEL, "(%d,%d) pinging", handle, device) - _base.write(handle, device, b'\x00\x10\x00\x00' + ping_marker) + _l.log(_LOG_LEVEL, "(%d,%d) pinging", handle, devnumber) + _base.write(handle, devnumber, b'\x00\x10\x00\x00' + ping_marker) # pings may take a while to reply success return _status(_base.read(handle, _base.DEFAULT_TIMEOUT * 3)) @@ -136,12 +136,12 @@ def find_device_by_name(handle, device_name): """ _l.log(_LOG_LEVEL, "(%d,) searching for device '%s'", handle, device_name) - for device in range(1, 1 + _base.MAX_ATTACHED_DEVICES): - features_array = get_device_features(handle, device) + for devnumber in range(1, 1 + C.MAX_ATTACHED_DEVICES): + features_array = get_device_features(handle, devnumber) if features_array: - d_name = get_device_name(handle, device, features_array) + d_name = get_device_name(handle, devnumber, features_array) if d_name == device_name: - return get_device_info(handle, device, device_name=d_name, features_array=features_array) + return get_device_info(handle, devnumber, device_name=d_name, features_array=features_array) def list_devices(handle): @@ -153,7 +153,7 @@ def list_devices(handle): devices = [] - for device in range(1, 1 + _base.MAX_ATTACHED_DEVICES): + for device in range(1, 1 + C.MAX_ATTACHED_DEVICES): features_array = get_device_features(handle, device) if features_array: devices.append(get_device_info(handle, device, features_array=features_array)) @@ -161,67 +161,67 @@ def list_devices(handle): return devices -def get_device_info(handle, device, device_name=None, features_array=None): +def get_device_info(handle, devnumber, device_name=None, features_array=None): """Gets the complete info for a device (type, name, firmwares, and features_array). :returns: an AttachedDeviceInfo tuple, or ``None``. """ if features_array is None: - features_array = get_device_features(handle, device) + features_array = get_device_features(handle, devnumber) if features_array is None: return None - d_type = get_device_type(handle, device, features_array) - d_name = get_device_name(handle, device, features_array) if device_name is None else device_name - d_firmware = get_device_firmware(handle, device, features_array) - devinfo = AttachedDeviceInfo(device, d_type, d_name, d_firmware, features_array) - _l.log(_LOG_LEVEL, "(%d,%d) found device %s", handle, device, devinfo) + d_type = get_device_type(handle, devnumber, features_array) + d_name = get_device_name(handle, devnumber, features_array) if device_name is None else device_name + d_firmware = get_device_firmware(handle, devnumber, features_array) + devinfo = AttachedDeviceInfo(devnumber, d_type, d_name, d_firmware, features_array) + _l.log(_LOG_LEVEL, "(%d,%d) found device %s", handle, devnumber, devinfo) return devinfo -def get_feature_index(handle, device, feature): +def get_feature_index(handle, devnumber, feature): """Reads the index of a device's feature. :returns: An int, or ``None`` if the feature is not available. """ - _l.log(_LOG_LEVEL, "(%d,%d) get feature index <%s:%s>", handle, device, _hexlify(feature), C.FEATURE_NAME[feature]) + _l.log(_LOG_LEVEL, "(%d,%d) get feature index <%s:%s>", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature]) if len(feature) != 2: raise ValueError("invalid feature <%s>: it must be a two-byte string" % feature) # FEATURE.ROOT should always be available for any attached devices - reply = _base.request(handle, device, C.FEATURE.ROOT, feature) + reply = _base.request(handle, devnumber, C.FEATURE.ROOT, feature) if reply: # only consider active and supported features feature_index = ord(reply[0:1]) if feature_index: feature_flags = ord(reply[1:2]) & 0xE0 - _l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> has index %d flags %02x", handle, device, _hexlify(feature), C.FEATURE_NAME[feature], feature_index, feature_flags) + _l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> has index %d flags %02x", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], feature_index, feature_flags) if feature_flags == 0: return feature_index if feature_flags & 0x80: - _l.warn("(%d,%d) feature <%s:%s> not supported: obsolete", handle, device, _hexlify(feature), C.FEATURE_NAME[feature]) + _l.warn("(%d,%d) feature <%s:%s> not supported: obsolete", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature]) if feature_flags & 0x40: - _l.warn("(%d,%d) feature <%s:%s> not supported: hidden", handle, device, _hexlify(feature), C.FEATURE_NAME[feature]) + _l.warn("(%d,%d) feature <%s:%s> not supported: hidden", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature]) if feature_flags & 0x20: - _l.warn("(%d,%d) feature <%s:%s> not supported: Logitech internal", handle, device, _hexlify(feature), C.FEATURE_NAME[feature]) - raise E.FeatureNotSupported(device, feature) + _l.warn("(%d,%d) feature <%s:%s> not supported: Logitech internal", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature]) + raise E.FeatureNotSupported(devnumber, feature) else: - _l.warn("(%d,%d) feature <%s:%s> not supported by the device", handle, device, _hexlify(feature), C.FEATURE_NAME[feature]) - raise E.FeatureNotSupported(device, feature) + _l.warn("(%d,%d) feature <%s:%s> not supported by the device", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature]) + raise E.FeatureNotSupported(devnumber, feature) -def get_device_features(handle, device): +def get_device_features(handle, devnumber): """Returns an array of feature ids. Their position in the array is the index to be used when requesting that feature on the device. """ - _l.log(_LOG_LEVEL, "(%d,%d) get device features", handle, device) + _l.log(_LOG_LEVEL, "(%d,%d) get device features", handle, devnumber) # get the index of the FEATURE_SET # FEATURE.ROOT should always be available for all devices - fs_index = _base.request(handle, device, C.FEATURE.ROOT, C.FEATURE.FEATURE_SET) + fs_index = _base.request(handle, devnumber, C.FEATURE.ROOT, C.FEATURE.FEATURE_SET) if fs_index is None: # _l.warn("(%d,%d) FEATURE_SET not available", handle, device) return None @@ -231,24 +231,24 @@ def get_device_features(handle, device): # even if unknown. # get the number of active features the device has - features_count = _base.request(handle, device, fs_index + b'\x00') + features_count = _base.request(handle, devnumber, fs_index + b'\x00') if not features_count: # this can happen if the device disappeard since the fs_index request # otherwise we should get at least a count of 1 (the FEATURE_SET we've just used above) - _l.log(_LOG_LEVEL, "(%d,%d) no features available?!", handle, device) + _l.log(_LOG_LEVEL, "(%d,%d) no features available?!", handle, devnumber) return None features_count = ord(features_count[:1]) - _l.log(_LOG_LEVEL, "(%d,%d) found %d features", handle, device, features_count) + _l.log(_LOG_LEVEL, "(%d,%d) found %d features", handle, devnumber, features_count) features = [None] * 0x20 for index in range(1, 1 + features_count): # for each index, get the feature residing at that index - feature = _base.request(handle, device, fs_index + b'\x10', _pack('!B', index)) + feature = _base.request(handle, devnumber, fs_index + b'\x10', _pack('!B', index)) if feature: feature = feature[0:2].upper() features[index] = feature - _l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> at index %d", handle, device, _hexlify(feature), C.FEATURE_NAME[feature], index) + _l.log(_LOG_LEVEL, "(%d,%d) feature <%s:%s> at index %d", handle, devnumber, _hexlify(feature), C.FEATURE_NAME[feature], index) features[0] = C.FEATURE.ROOT while features[-1] is None: @@ -256,7 +256,7 @@ def get_device_features(handle, device): return features -def get_device_firmware(handle, device, features_array=None): +def get_device_firmware(handle, devnumber, features_array=None): """Reads a device's firmware info. :returns: a list of FirmwareInfo tuples, ordered by firmware layer. @@ -264,14 +264,14 @@ def get_device_firmware(handle, device, features_array=None): def _makeFirmwareInfo(level, type, name=None, version=None, build=None, extras=None): return FirmwareInfo(level, type, name, version, build, extras) - fw_count = request(handle, device, C.FEATURE.FIRMWARE, features_array=features_array) + fw_count = request(handle, devnumber, C.FEATURE.FIRMWARE, features_array=features_array) if fw_count: fw_count = ord(fw_count[:1]) fw = [] for index in range(0, fw_count): index = _pack('!B', index) - fw_info = request(handle, device, C.FEATURE.FIRMWARE, function=b'\x10', params=index, features_array=features_array) + fw_info = request(handle, devnumber, C.FEATURE.FIRMWARE, function=b'\x10', params=index, features_array=features_array) if fw_info: fw_level = ord(fw_info[:1]) & 0x0F if fw_level == 0 or fw_level == 1: @@ -295,67 +295,67 @@ def get_device_firmware(handle, device, features_array=None): fw_info = _makeFirmwareInfo(level=fw_level, type=C.FIRMWARE_TYPE[-1]) fw.append(fw_info) - _l.log(_LOG_LEVEL, "(%d:%d) firmware %s", handle, device, fw_info) + _l.log(_LOG_LEVEL, "(%d:%d) firmware %s", handle, devnumber, fw_info) return fw -def get_device_type(handle, device, features_array=None): +def get_device_type(handle, devnumber, features_array=None): """Reads a device's type. :see DEVICE_TYPE: :returns: a string describing the device type, or ``None`` if the device is not available or does not support the ``NAME`` feature. """ - d_type = request(handle, device, C.FEATURE.NAME, function=b'\x20', features_array=features_array) + d_type = request(handle, devnumber, C.FEATURE.NAME, function=b'\x20', features_array=features_array) if d_type: d_type = ord(d_type[:1]) - _l.log(_LOG_LEVEL, "(%d,%d) device type %d = %s", handle, device, d_type, C.DEVICE_TYPE[d_type]) + _l.log(_LOG_LEVEL, "(%d,%d) device type %d = %s", handle, devnumber, d_type, C.DEVICE_TYPE[d_type]) return C.DEVICE_TYPE[d_type] -def get_device_name(handle, device, features_array=None): +def get_device_name(handle, devnumber, features_array=None): """Reads a device's name. :returns: a string with the device name, or ``None`` if the device is not available or does not support the ``NAME`` feature. """ - name_length = request(handle, device, C.FEATURE.NAME, features_array=features_array) + name_length = request(handle, devnumber, C.FEATURE.NAME, features_array=features_array) if name_length: name_length = ord(name_length[:1]) d_name = b'' while len(d_name) < name_length: name_index = _pack('!B', len(d_name)) - name_fragment = request(handle, device, C.FEATURE.NAME, function=b'\x10', params=name_index, features_array=features_array) + name_fragment = request(handle, devnumber, C.FEATURE.NAME, function=b'\x10', params=name_index, features_array=features_array) name_fragment = name_fragment[:name_length - len(d_name)] d_name += name_fragment d_name = d_name.decode('ascii') - _l.log(_LOG_LEVEL, "(%d,%d) device name %s", handle, device, d_name) + _l.log(_LOG_LEVEL, "(%d,%d) device name %s", handle, devnumber, d_name) return d_name -def get_device_battery_level(handle, device, features_array=None): +def get_device_battery_level(handle, devnumber, features_array=None): """Reads a device's battery level. :raises FeatureNotSupported: if the device does not support this feature. """ - battery = request(handle, device, C.FEATURE.BATTERY, features_array=features_array) + battery = request(handle, devnumber, C.FEATURE.BATTERY, features_array=features_array) if battery: discharge, dischargeNext, status = _unpack('!BBB', battery[:3]) _l.log(_LOG_LEVEL, "(%d:%d) battery %d%% charged, next level %d%% charge, status %d = %s", discharge, dischargeNext, status, C.BATTERY_STATUSE[status]) return (discharge, dischargeNext, C.BATTERY_STATUS[status]) -def get_device_keys(handle, device, features_array=None): - count = request(handle, device, C.FEATURE.REPROGRAMMABLE_KEYS, features_array=features_array) +def get_device_keys(handle, devnumber, features_array=None): + count = request(handle, devnumber, C.FEATURE.REPROGRAMMABLE_KEYS, features_array=features_array) if count: keys = [] count = ord(count[:1]) for index in range(0, count): keyindex = _pack('!B', index) - keydata = request(handle, device, C.FEATURE.REPROGRAMMABLE_KEYS, function=b'\x10', params=keyindex, features_array=features_array) + keydata = request(handle, devnumber, C.FEATURE.REPROGRAMMABLE_KEYS, function=b'\x10', params=keyindex, features_array=features_array) if keydata: key, key_task, flags = _unpack('!HHB', keydata[:5]) keys.append(ReprogrammableKeyInfo(index, key, C.KEY_NAME[key], key_task, C.KEY_NAME[key_task], flags)) diff --git a/lib/logitech/unifying_receiver/base.py b/lib/logitech/unifying_receiver/base.py index 6b57c5db..1bad01d0 100644 --- a/lib/logitech/unifying_receiver/base.py +++ b/lib/logitech/unifying_receiver/base.py @@ -41,10 +41,6 @@ _MAX_REPLY_SIZE = _MAX_CALL_SIZE """Default timeout on read (in ms).""" DEFAULT_TIMEOUT = 1000 - -"""Maximum number of devices attached to a UR.""" -MAX_ATTACHED_DEVICES = 6 - # # # @@ -57,7 +53,7 @@ def list_receiver_devices(): def try_open(path): - """Checks if the given device path points to the right UR device. + """Checks if the given Linux device path points to the right UR device. :param path: the Linux device path. @@ -128,11 +124,11 @@ def close(handle): # return _write(handle, device, data) -def write(handle, device, data): +def write(handle, devnumber, data): """Writes some data to a certain device. :param handle: an open UR handle. - :param device: attached device number. + :param devnumber: attached device number. :param data: data to send, up to 5 bytes. The first two (required) bytes of data must be the feature index for the @@ -146,16 +142,16 @@ def write(handle, device, data): data += b'\x00' * (_MIN_CALL_SIZE - 2 - len(data)) elif len(data) > _MIN_CALL_SIZE - 2: data += b'\x00' * (_MAX_CALL_SIZE - 2 - len(data)) - wdata = _pack('!BB', 0x10, device) + data + wdata = _pack('!BB', 0x10, devnumber) + data - _l.log(_LOG_LEVEL, "(%d,%d) <= w[%s]", handle, device, _hexlify(wdata)) + _l.log(_LOG_LEVEL, "(%d,%d) <= w[%s]", handle, devnumber, _hexlify(wdata)) if len(wdata) < _MIN_CALL_SIZE: - _l.warn("(%d:%d) <= w[%s] call packet too short: %d bytes", handle, device, _hexlify(wdata), len(wdata)) + _l.warn("(%d:%d) <= w[%s] call packet too short: %d bytes", handle, devnumber, _hexlify(wdata), len(wdata)) if len(wdata) > _MAX_CALL_SIZE: - _l.warn("(%d:%d) <= w[%s] call packet too long: %d bytes", handle, device, _hexlify(wdata), len(wdata)) + _l.warn("(%d:%d) <= w[%s] call packet too long: %d bytes", handle, devnumber, _hexlify(wdata), len(wdata)) if not _hid.write(handle, wdata): - _l.warn("(%d,%d) write failed, assuming receiver no longer available", handle, device) + _l.warn("(%d,%d) write failed, assuming receiver no longer available", handle, devnumber) close(handle) raise E.NoReceiver @@ -168,9 +164,9 @@ def read(handle, timeout=DEFAULT_TIMEOUT): :param timeout: read timeout on the UR handle. If any data was read in the given timeout, returns a tuple of - (reply_code, device, message data). The reply code should be ``0x11`` for a - successful feature call, or ``0x10`` to indicate some error, e.g. the device - is no longer available. + (reply_code, devnumber, message data). The reply code is generally ``0x11`` + for a successful feature call, or ``0x10`` to indicate some error, e.g. the + device is no longer available. :raises NoReceiver: if the receiver is no longer available, i.e. has been physically removed from the machine, or the kernel driver has been @@ -189,21 +185,21 @@ def read(handle, timeout=DEFAULT_TIMEOUT): if len(data) > _MAX_REPLY_SIZE: _l.warn("(%d,*) => r[%s] read packet too long: %d bytes", handle, _hexlify(data), len(data)) code = ord(data[:1]) - device = ord(data[1:2]) - return code, device, data[2:] + devnumber = ord(data[1:2]) + return code, devnumber, data[2:] _l.log(_LOG_LEVEL, "(%d,*) => r[]", handle) -def request(handle, device, feature_index_function, params=b'', features_array=None): - """Makes a feature call device and waits for a matching reply. +def request(handle, devnumber, feature_index_function, params=b'', features_array=None): + """Makes a feature call to a device and waits for a matching reply. This function will skip all incoming messages and events not related to the device we're requesting for, or the feature specified in the initial request; it will also wait for a matching reply indefinitely. :param handle: an open UR handle. - :param device: attached device number. + :param devnumber: attached device number. :param feature_index_function: a two-byte string of (feature_index, feature_function). :param params: parameters for the feature call, 3 to 16 bytes. :param features_array: optional features array for the device, only used to @@ -212,13 +208,13 @@ def request(handle, device, feature_index_function, params=b'', features_array=N available. :raisees FeatureCallError: if the feature call replied with an error. """ - _l.log(_LOG_LEVEL, "(%d,%d) request {%s} params [%s]", handle, device, _hexlify(feature_index_function), _hexlify(params)) + _l.log(_LOG_LEVEL, "(%d,%d) request {%s} params [%s]", handle, devnumber, _hexlify(feature_index_function), _hexlify(params)) if len(feature_index_function) != 2: raise ValueError('invalid feature_index_function {%s}: it must be a two-byte string' % _hexlify(feature_index_function)) retries = 5 - write(handle, device, feature_index_function + params) + write(handle, devnumber, feature_index_function + params) while retries > 0: reply = read(handle) retries -= 1 @@ -227,39 +223,39 @@ def request(handle, device, feature_index_function, params=b'', features_array=N # keep waiting... continue - reply_code, reply_device, reply_data = reply + reply_code, reply_devnumber, reply_data = reply - if reply_device != device: + if reply_devnumber != devnumber: # this message not for the device we're interested in - _l.log(_LOG_LEVEL, "(%d,%d) request got reply for unexpected device %d: [%s]", handle, device, reply_device, _hexlify(reply_data)) + _l.log(_LOG_LEVEL, "(%d,%d) request got reply for unexpected device %d: [%s]", handle, devnumber, reply_devnumber, _hexlify(reply_data)) # worst case scenario, this is a reply for a concurrent request # on this receiver - _unhandled._publish(reply_code, reply_device, reply_data) + _unhandled._publish(reply_code, reply_devnumber, reply_data) continue if reply_code == 0x10 and reply_data[:1] == b'\x8F' and reply_data[1:2] == feature_index_function: # device not present - _l.log(_LOG_LEVEL, "(%d,%d) request ping failed on {%s} call: [%s]", handle, device, _hexlify(feature_index_function), _hexlify(reply_data)) + _l.log(_LOG_LEVEL, "(%d,%d) request ping failed on {%s} call: [%s]", handle, devnumber, _hexlify(feature_index_function), _hexlify(reply_data)) return None if reply_code == 0x10 and reply_data[:1] == b'\x8F': # device not present - _l.log(_LOG_LEVEL, "(%d,%d) request ping failed: [%s]", handle, device, _hexlify(reply_data)) + _l.log(_LOG_LEVEL, "(%d,%d) request ping failed: [%s]", handle, devnumber, _hexlify(reply_data)) return None if reply_code == 0x11 and reply_data[0] == b'\xFF' and reply_data[1:3] == feature_index_function: # an error returned from the device error_code = ord(reply_data[3]) - _l.warn("(%d,%d) request feature call error %d = %s: %s", handle, device, error_code, C.ERROR_NAME[error_code], _hexlify(reply_data)) + _l.warn("(%d,%d) request feature call error %d = %s: %s", handle, devnumber, error_code, C.ERROR_NAME[error_code], _hexlify(reply_data)) feature_index = ord(feature_index_function[:1]) feature_function = feature_index_function[1:2] feature = None if features_array is None else features_array[feature_index] - raise E.FeatureCallError(device, feature, feature_index, feature_function, error_code, reply_data) + raise E.FeatureCallError(devnumber, feature, feature_index, feature_function, error_code, reply_data) if reply_code == 0x11 and reply_data[:2] == feature_index_function: # a matching reply - _l.log(_LOG_LEVEL, "(%d,%d) matched reply with feature-index-function [%s]", handle, device, _hexlify(reply_data[2:])) + _l.log(_LOG_LEVEL, "(%d,%d) matched reply with feature-index-function [%s]", handle, devnumber, _hexlify(reply_data[2:])) return reply_data[2:] - _l.log(_LOG_LEVEL, "(%d,%d) unmatched reply {%s} (expected {%s})", handle, device, _hexlify(reply_data[:2]), _hexlify(feature_index_function)) - _unhandled._publish(reply_code, reply_device, reply_data) + _l.log(_LOG_LEVEL, "(%d,%d) unmatched reply {%s} (expected {%s})", handle, devnumber, _hexlify(reply_data[:2]), _hexlify(feature_index_function)) + _unhandled._publish(reply_code, reply_devnumber, reply_data) diff --git a/lib/logitech/unifying_receiver/constants.py b/lib/logitech/unifying_receiver/constants.py index a217a905..7429a1cb 100644 --- a/lib/logitech/unifying_receiver/constants.py +++ b/lib/logitech/unifying_receiver/constants.py @@ -97,5 +97,9 @@ _ERROR_NAMES = ('Ok', 'Unknown', 'Invalid argument', 'Out of range', ERROR_NAME = FallbackDict(lambda x: 'Unknown error', list2dict(_ERROR_NAMES)) +"""Maximum number of devices that can be attached to a single receiver.""" +MAX_ATTACHED_DEVICES = 6 + + del FallbackDict del list2dict diff --git a/lib/logitech/unifying_receiver/exceptions.py b/lib/logitech/unifying_receiver/exceptions.py index 77e71469..452cd5a2 100644 --- a/lib/logitech/unifying_receiver/exceptions.py +++ b/lib/logitech/unifying_receiver/exceptions.py @@ -15,18 +15,18 @@ class NoReceiver(Exception): class FeatureNotSupported(Exception): """Raised when trying to request a feature not supported by the device.""" - def __init__(self, device, feature): - super(FeatureNotSupported, self).__init__(device, feature, C.FEATURE_NAME[feature]) - self.device = device + def __init__(self, devnumber, feature): + super(FeatureNotSupported, self).__init__(devnumber, feature, C.FEATURE_NAME[feature]) + self.devnumber = devnumber self.feature = feature self.feature_name = C.FEATURE_NAME[feature] class FeatureCallError(Exception): """Raised if the device replied to a feature call with an error.""" - def __init__(self, device, feature, feature_index, feature_function, error_code, data=None): - super(FeatureCallError, self).__init__(device, feature, feature_index, feature_function, error_code, C.ERROR_NAME[error_code]) - self.device = device + def __init__(self, devnumber, feature, feature_index, feature_function, error_code, data=None): + super(FeatureCallError, self).__init__(devnumber, feature, feature_index, feature_function, error_code, C.ERROR_NAME[error_code]) + self.devnumber = devnumber self.feature = feature self.feature_name = None if feature is None else C.FEATURE_NAME[feature] self.feature_index = feature_index diff --git a/lib/logitech/unifying_receiver/listener.py b/lib/logitech/unifying_receiver/listener.py index 23eabf39..6e066258 100644 --- a/lib/logitech/unifying_receiver/listener.py +++ b/lib/logitech/unifying_receiver/listener.py @@ -23,14 +23,14 @@ _IDLE_SLEEP = 950 # ms class EventsListener(threading.Thread): """Listener thread for events from the Unifying Receiver. - Incoming events (code, device, data) will be delivered to the callback - function. The callback is called in the listener thread, so it should return - as fast as possible. + Incoming events (reply_code, devnumber, data) will be passed to the callback + function. The callback is called in the listener thread, so for best results + it should return as fast as possible. While this listener is running, you should use the request() method to make - regular UR API calls, otherwise the replies will be captured by the listener - and delivered as events to the callback. As an exception, you can make UR - API calls in the events callback. + regular UR API calls, otherwise the replies may be captured by the listener + and delivered as events to the callback. As an exception, you can make API + calls in the events callback. """ def __init__(self, receiver, events_callback): super(EventsListener, self).__init__(name='Unifying_Receiver_Listener_' + hex(receiver)) diff --git a/lib/logitech/unifying_receiver/tests/test_30_base.py b/lib/logitech/unifying_receiver/tests/test_30_base.py index 4d5c282c..3185098d 100644 --- a/lib/logitech/unifying_receiver/tests/test_30_base.py +++ b/lib/logitech/unifying_receiver/tests/test_30_base.py @@ -80,7 +80,7 @@ class Test_UR_Base(unittest.TestCase): devices = [] - for device in range(1, 1 + base.MAX_ATTACHED_DEVICES): + for device in range(1, 1 + MAX_ATTACHED_DEVICES): w = base.write(self.handle, device, b'\x00\x10\x00\x00\xAA') self.assertIsNone(w, "write should have returned None") reply = base.read(self.handle, base.DEFAULT_TIMEOUT * 3) diff --git a/lib/logitech/unifying_receiver/tests/test_50_api.py b/lib/logitech/unifying_receiver/tests/test_50_api.py index 8b5e347b..24eb61fc 100644 --- a/lib/logitech/unifying_receiver/tests/test_50_api.py +++ b/lib/logitech/unifying_receiver/tests/test_50_api.py @@ -45,7 +45,7 @@ class Test_UR_API(unittest.TestCase): devices = [] - for device in range(1, 1 + api._base.MAX_ATTACHED_DEVICES): + for device in range(1, 1 + MAX_ATTACHED_DEVICES): ok = api.ping(self.handle, device) self.assertIsNotNone(ok, "invalid ping reply") if ok: diff --git a/lib/logitech/unifying_receiver/unhandled.py b/lib/logitech/unifying_receiver/unhandled.py index 0b5b151e..2facbbad 100644 --- a/lib/logitech/unifying_receiver/unhandled.py +++ b/lib/logitech/unifying_receiver/unhandled.py @@ -7,16 +7,16 @@ import logging from binascii import hexlify as _hexlify -def _logdebug_hook(reply_code, device, data): +def _logdebug_hook(reply_code, devnumber, data): """Default unhandled hook, logs the reply as DEBUG.""" _l = logging.getLogger('logitech.unifying_receiver.unhandled') - _l.debug("UNHANDLED (,%d) code 0x%02x data [%s]", device, reply_code, _hexlify(data)) + _l.debug("UNHANDLED (,%d) code 0x%02x data [%s]", devnumber, reply_code, _hexlify(data)) """The function that will be called on unhandled incoming events. The hook must be a function with the signature: ``_(int, int, str)``, where -the parameters are: (reply code, device number, data). +the parameters are: (reply_code, devnumber, data). This hook will only be called by the request() function, when it receives replies that do not match the requested feature call. As such, it is not @@ -30,7 +30,7 @@ The default implementation logs the unhandled reply as DEBUG. hook = _logdebug_hook -def _publish(reply_code, device, data): +def _publish(reply_code, devnumber, data): """Delivers a reply to the unhandled hook, if any.""" if hook is not None: - hook.__call__(reply_code, device, data) + hook.__call__(reply_code, devnumber, data) diff --git a/resources/README b/resources/README new file mode 100644 index 00000000..3b7e38ae --- /dev/null +++ b/resources/README @@ -0,0 +1,3 @@ +Battery and weather icons from the Oxygen icon theme. +Lightbulb icon from the GNOME icon theme. +Unifying receiver and Wireless Keyboard K750 icons from Logitech web pages. diff --git a/resources/icons/Solaar.png b/resources/icons/Solaar.png new file mode 100644 index 0000000000000000000000000000000000000000..45312e3d8856c321348be64f5c935174843328a0 GIT binary patch literal 20700 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 T3gCA~00000NkvXXu0mjf_xL1yGQd z(DGP5?e?sqTk@p*_dHoq+1c%T^y+#);c|cLU?CtCOPjP^8T)}%uOWpBoqU)hTR@z8 zyso-WoE9lEowDa5}UoYRa*OpH0`RcRm zWU)z&G9!MpBq`EJL&`s|E&8q}Iyv^wzP%U1;w;roGm!sx`oECD``b86ZP(LB%AyqX z6b;{!-E57@vXnymf1j=GJz1(>I+N3TUZ^{|Df&Pl+$$>aJ`nB>0U}w9Gp*xlb;xIW z6GAnVh`;chZV{YrArWz0P;A_3IKW9vJrexyz`hjtlq8_!S987fNsA@RsKSQ>$SAx2 z6L%i&h3|dm)ga~L)&ihuW{jU^MOgT=vHo+Z@w-j$8_wf>*JbY8>dTABfe$a{ATRU~ zX!Zg)@QLMYfiFaesW&f~BMX%LG6&9=lQx8Y#);{O`7AvoV1`JIOnq?cu|O33}0g)jl-9KM`CCO2efJ6c&=Xt zc?g8+a1ijAiz^`?N!0U<)O9(4p{7<@Mce%{qximN{CKGPKJ^{(&seW(yVD(sN}kuY zzR@0xs^E+W^hS>+=<983t|-)G>zCS8t{>0fSR)fy-<{fgkusV`)`0F-!SNe z8|pO#b2$m<8Vd4E;7W8EJ*si^9Yal8g&-b4N3Z^vF}UK0@VAZ*vZ#ES<%Fw@-I{*b zzHOYS=P%_`9|`?V8T`n?ama%b&=+eA2O0cs%t$Xho_+}T-j4Uq!IZF`+x7M&xNvqW za3JypE;RcpB0`cnDg>AfI*~LDL_GoMfXq-NnjrZ_G1Ef0JtE2LU$U%oPq$zPUz@AADS*GW1L86Og`~&!qe+uQ7|< zOqo$5yplMDNx#R5n?N@K;W(82#!r!y;Xrt+%_BZ|Rr*fUTQU z76Ip{TmILlbYs7Ym807+IeQ=>=Fq=foC^mrxChys zP=VPEXKGn#69^NYq?$I`u4fpn0&tiUx`QTL1P=3-Iz2lx<)JVW$}!>kQ9k-r>56As z&_Pt{M|!!^o2?Rpl7kUT#(}BcAinF;?1}DoZnbUrLWr1F{@^Qt=>K%FKZ}EjU&}4UmySU!?{>)ySLo#WvpvIJp?j z#?YXoNfmXmvB8i@3r2zSdKJZ{6ucIFuF^-id~Y|nN1x0VeEmr7e0;_Ikp6z%iu~IC z>yZPKNYFA`+BP@hDZ9~=y2at(e4op#2{M!>cyJRlEn?}D%h}QgB6XPTl;#1bQ>qmt zeQ^B1I1Vpkl<~(Sj7K?FMdI^(_pt;%MlB~C`kmv zR7UkwcnvFd%%X`HPKQajFGKBbxsO{->Y%be^tvs~a**~aog{e8fS{114;iz^X7$`q zK$0r~RVW{76e86=FYUaAjdT@fy>2T@EMd4Wtsr$H@h@ooq*F^J;e|F`g-Iz6|^VfkOaDKUhPK z*lZmA^H*s(*xr|Bk#5SDQWL-_Wqo2Tk;zH46l`FXN}^>}&>)E)2F1&P&SN>quO)-3RpVnn4RU1;metuS{{@tP4)aJvNeZu6q_f75UQj$r}t z_)jFiF8kSjGHbw1>@F{B00`k?`s6*gxFi_iX^uRt0O!1zQ6bm|%71G<(eVztYs+Cv zqmPkcXqYU#GY4=Y)u3iu(cpfjp@$0s?7#`o!h>D0?b*ly8IgD+FSQpK`4Ko%>EAr-9l=d6t zI}2rr@!O-Z!MW@-HH}*WXUl+~K4QHToLM-?G8{C`b>Q<|D2L5?@>v8m$ZifRj&fr& z2AAOrI6$1~S17QHRk0yJE1Nc=jFWyAZQCkl%OPUxTg2Mhr|POfTb7t=j6VrwFSAa z`$Iy^v9lg~g(0E9Y_v8h2E2k9a+d*l6jg+{q}4B;5rIe&@Zxlc?5vW}CnmKs6@&mO^BVqzk4f~dwUT-oeX|E{BEylgBgE$7U$r?@9k3TmGJ3GN_FF5$t%81a#7@&jl(0F*^zLeYm8U|z9X zm}0GhKK)ZVw6e+|vYZj})iX>_Xx7snk0uUZ35q{7O0YAH=qU2bg@h)~Oo<+U$k7%8 zL7Vv@TNo`OmzZ8Ijl@JtTWrV-IBozkSQuJ$%YNFM#gJrausAP;N zh%rEtl70HcgW~wv#4yRZi(o=eth#y<>7P>9PygkNehHvO#zsQgkICkejmS`kAekK= zKO>e<#hRwD8MpE)!D&2N%s-PNP=P-KN{dyjVv<-imKlNKklwsGl4?p6J$#cl`cz#m zT50v-S}CTljY_Y=zW{88JwXh;zq&pEu0_Jtf{NADH0rC*zM~ID2$(4$D3f@MMLWfz zMx!@PM5YxdA;>l%58%R+!#jk4^yvy+VSXJhdg${ZO$~&Ju|h2p7I3K*@QX(=tw{8d zw0A~BWCy`+_y6iTJ8k-Y8pc3jQZ^fMjL{R4GCJ(2B@nu$r`}m=>NFW51vfOlOnw>s zNWXXepD!7PXZ5q}r>u>WP)6-D!H>&^d8%F)bOopN-@N?p{!GnaJi*Cg!p$0`;UerT z7fs5*721UaWJoODo$T))B$RMVXTBX@dy$H+bhJ?i6tP)_s-r+4bb~ic9Fn&z)n)XQ{rT+e*x`)Kt#%e6B{c2CgN zNGj6R&b1b9SoQ)j_J7Dj`yp^gm+(A=OjgwJuPjz7(CX^)BDluV&NVinwHif~nWZW! z>MQbLK#fs%m}Y$W^V8US{l<&O<;%^*>D1kUSGSRSD9SXtWfKWvzfgou5S2h5vHre9 zU6T1Dmu1%!{Q4F+UL{)qms1TvL_wpES*J@-9dvE;mYoC z!UPRF)9=6*K?+GGd|4GPX&Px3Fh^~!p3ex;(nbO^Yo(Uz9lvNMro^Ksp3JCd8aJ7@ z_Th6s=IHP4i@bp$mEkFW_%WByk~CGWeHx86jE4glk-(vvCO+h$?-pObTcHhOlU+iL zFP(hFna;WgIp)UpLr1$g;6qE0pHn1$rG~&uEOTW&#*hrr;Onr+C*zP3p_Yt*1VHh& zZ^*CRSl(x4dn$n=*5SzaU8tj?ywMmOW(E<*5fBN_zAjIwkxEToLA&hXvxHKAHl&vF zIagy|iOl9(Rl`ctSilnpyY}vqKaiFBFa{T=kK{!Di>V{7DKNjBC)|`TOZlzZ1aNY4 zGG(cE6_j$_q_y3aB!DwNev17uQ{1OI`$EzM%d;bwelPg$CW_ptL4o?cU&kdwO9mPm}UDj8*-Tx0r5%4d-d zrv`j9!KvKv^y>h#r=`v?kp^uPd~kxqwc(b^28Ikk^Q&!!p}UY%-TmmQ+D)H!x2Ub2 zI0T48o@Q1QH9xPNe!lA&$)nubTg22idA?3I>in--c@Xo<&lGqNHx5yP2CoS5d>pP?*c{xt$B5lk zh72_fqg7VdYb5-G{s3m?>wS$!4^u8#!Vt6JiHMlsuBiCIcTcY`7Ul>D+uS0NpfD}X~^2wDflh|@77G_jU3dRpo+yt(uQd$s( zOYCIp!mcGkO^d~a!5LRXpkCeYYLr)Rlny}(d4Lukr~n?XKj1$$$HSz>qP`yo9793oITm6t1JH()ydc6 z_v@cGS?+w=Mg)lSx6*3#(k+T9p2bMO3~e`eo4ZD*-`Fi4KUu9~>C5LG#(RF!%B6k{ zQzmrS51^xNGe~KZ4Sa3TXq^o#XXa3uG+X{@>X^r?_y2oY1eI(9^vg5)a3mPp!AIcD1*nex5bCTz`DErF_!B*pcsr$pu+uK zYx|SU^|jB2L&sdaqb4s^x?NRu?TPmks#PX+migjF3tXGe9W-eax5 zMGdJdxR_S|%_^iWH(U)Ofi@3NLOecas;+usX%(?9GBF+LFO~!$q7s8K;elom0#f15 zArb-QD@c`ic<5jpAP^w~`=oeuRNz1jl59X5Fyo;qMUIkBl_FWTB9%ms?NPxTj?yM$ z1;+#rW{2dsFNdluIA`L;AO&ij@sbtVIm?&ysnMJw=Hn3taY$?H#FpZuH;`u}Q1BE}H_x_JSAU$D;EC>;LE*POvJ8A01PgS-@p|gLqO* z`X-f@-B*6+L+29|A&aoYLJRggPZ(fgxrqtcVMvgp=29m^P~(b|Pm`@cO~c#m)QP5+ zkG&H{O3x0)Fs(x;Mbx7(CP(@UO!%?L#8o1y|K2(zdEKZtUw++Y9TzL3be6a3%fR}P zt$hOqZ(M|?OEw+rshPloI=Mai^6=h>8%`Z-5hshCyt( z8DkZSCBO`xM!UNQAD}ACl1foyA|sR+ev=l#wdD1XLOgZ};F(`v30+2BYPO+6S2xF; zA+)%aOotq3Lzv{LwahEfh%|_ULY?>xnQ^2O@i?gB?=W==3?D4EmkOCrR%410N~)Z= zsnh>^xC%r{B4fUgL2VT2H-3xE8)6W94EI=c{}lgxe_`frgTf{h+6$_foci7FqC@-J zvH{$BI}u)`Ni*fkOxKNMU(t|B$sP)CS*24dTMn7z76RmmD~s3} z{n>jNE%yFTGhoVZ-?{f;Ka^iRjqp2}(eSp6QvJM}L#rDlL=&(#A4B)Q92M)+?Y&0#dw+k^ z6?mT0>v~&00dO+fn24yU3H@i&JyVk8XE@^FvjNWV^}~t0ODiy|DTzR@p@thXR?T>x zPH5j#Q+8~Ame`asSz;K-M`kZ_;%hNUebu7@X{4~3TMvl7V|Jd-8y~a%PZ5#6Bf44Hvb;Acse+%O@mhIa*MT(WkDr#NGK5L$-2Vsa*4i zY077Hk@r<$$GtJa7ijG}^4qTJ8|s?fhBi-m&EpS)4Y}}Y6q9oMuzwF9A}v~8ln|lq zEDY`XmPIU3@gZEKKn#kMn^YVk{Av}9E#C8tCJduk66`^>%++FBGMcTqOirm5{=S0X z8Oq7W=EQVYNXh8|Z92WjvZY8>C;kyG?n~^Bp0< z;_+#my{D;$K&yArv4jwbUEMi4VNseXYnC`(?hiVMDRj|zRNNu>*6GQ$)qz- zM7kZWbDrP9SYgslQ!hYC4rwfPG6XJ=Lc4KeLoO%1M8}rSW^NTAwR;@;0q3#@Zd-9+~$tn%7so;(jS5b{qV6ZDsIf6|a!-Tj|QAjb_p2G!=;_STu0{luKKThUwOI zr76!dF@{`*Fm#KCL0-+QexQ?LUVb$-NVBOUSJzv;%_3ttntKr7(%#eXAbTdW=B%St zcDSH%hLi4_02HM-Y6SeC$6&&7xcwV%ZTxVSk&3;O;EHG_)(GBXjE}4!m^c6GZM2A? zz9G5?=T&U|f?2K?ix;pRhyYBjm?0DJ==(>1j4qzmyR{K-FO2k{+xzStezDd$Tp%87 zG`y$n>UWAh2mPHam3dMec3egsa?c-cWxlNmCH_ozLc;meSx}daYrW8~u47j_T>3eJ zBMf=PWTpVQi^scmvTU>9w`iMejA@#AuIUm{=tH%>QW?e9fdS--;gIG9`L*uO$leDc zf5i7+8xQP>Lrle5pg4L|ftza;sqCxCtxhzi)DvS}$U=K#1@E(nuf98VB_~p~+H#$Y z=^=GHa$o1h9m}3i^pun?#Um6hW2}_G?`wg9RhmF}YCqP4bPce z>FJETI#%z;jd|j22a1x5BZH&)t~0xYX`bkRCHw^dgNUwtQyAEQHAa{Cx#G(NyiG0r z@4BT|_!Q43pjjT(oh#EGJYvPuR38^a6ExCq9vBYT+GERmo=cfL;2+Byatd=_mzMr% zL8&Uo61`I1O?=u$JT7_0Z6*>#E>w)nRn(OcshvE6#y!udEkaay!i}GsjpaaLZC;N; zLTlK$e*0FdD_uAa3nsJ)XSO%g*xx~}`jvIQdw#bznRd2u_K~V?U~UUoT|yUp6jE?- zWHX>5^;kes-YhC-a@g=}y{HnXM^kB<8%YJ_sTi9_ei^}z)hL*1tVZ$RAfodiV+=ny zG`CXo!57u~LrdiWO&UqzBo|cVl|se;{g-Tgyy*6)xpH^QgnDOMvGID{R6?fh6tv;) z3$m~rV5raI&!(Bfq{HT>MEWwFBWA^=xp92&89@N(*^h}fD1as=D08;BNsk~o%X8qcIz^|7P}PNj)VL9q{+eI2Z?7_j=f!$gF*|1o9y~v` z**Qodc=Io26CwT6wGHq!_pEIW^XaJB+GjzMXL8uCPd>c&{=2q5So<<2*4KF9^Facb zUx}FOdoau9?vkR@9FJgEI~e0z*E-EvIjdRIG2pc=IK9@JDRfG~B%2g)c|t`9`IPwlGh03TBn^jIhJ0WxH?+C^>A;eOX*{5RCRGgSFR zGA=@fRaI322*BZbHHgteoHSr|bT^zJfMZk0;6ve?c)4(zzyX`>90JwxC@XLMue>G` zNv_(SqcP2~qWHvEpwDWcp#2#_K#iml`j9{|P;Dk}Ge}l0yJo&Vtjvq?+vO*UfWpd5 zKV@g(Qxi~p_}WVNv2_kxResv5)gC@RdW<&)YXd^hDr z1#;YWywsF)w{n@}kx^+cH?^qC9AxX zjra4$@4BCfvVw0REzx`s?kh5jfJUO3@{v%aj)n558Xs9Q?{t_*0)$zQlw#vr^VQ__ zT<`$PCcj(9*14^zBJhZ=)yhG+r_r;1H270YjCu}+6SU6L9bdbIValk-g%H9-;2B7T zS>M?htTN{+;v#_XpIOzex9;MsiS?Prf{RX}FQ$l7OPd9WwT32vEUJ9J%e!!Z(g4QbngF01|fn{9IBpsQZnthr3)kB70Dd^W5+dmnW|Uy=2|o0(6iADZ7qNa{MSv;M7S0yWy@%Ue|M{s4)x z60T#KV-H7U2>HgS{6zy1v_8>oVbWGYE&t#LYvJ$O@_1SmQy6KF>?rZpV>5wCLrt)T zn4u>&|7OK)zLxX7;lM#-5U6ct{OW5t$IK8QC2Fo-;$=lFIDU(T@H)DS+1wwm$rSJ| zUT5FW@}TxBfUc|klKZtDUs4U`V`*^898JE#5MZFny)?^E=@D#ULE>8Dp87QeFaz8ku`H~+(TRs zZXm@)&c~OHtBLW2sM}|&>k1>@@)%UmLMr4EL$iOlU@enOf2jQgc2pp$yPe-fMp3UOg4R-hbsr5#Z)t&dT`y!bR$> zgtzDe6>ug`#r)Td$sr}#4z}Xt)=jYZQL3NZsvhz9G;%>{&GVC+mdO@9pDqrcR^fWD z^*f+g!{aVhH@AH78$x5neun%r;Jcj?7Nl55=~H2(R9Y%288~$gON7mmn}0n>R>xF{ z!p68rAei;;mi+v{@ny>ydwh;iib{1dJsBhELhkl-K11YPfPgh%!s;Kd1q8_|+JZipjLB*jZ9S z)Yijr_dyCF4Xo-v=9vmsB1>kBBr-13K(mGc`}c7{*4EcvM8qeL#iW^!u@(oYU`&^x zF1-tmWD})!C_)0o?-I@5V2U?2z+Sp?_ulsbJtyuepFj0+$Yck7Os8*r$3nc1UK%=t z5Z$9o&ZF1we1Je<%>ktf<|(HM_6hHlH49QsQ_8YMd%NY@)uxM^XBnrbuuWHI=U6#| z&K*y+-y5|olDmgvWAK6#oxQt`gqYq*ODd9;7+y2da%#7Kc=hi;>)=g&x+l|F(BYtn zbvQeA6?vVQg~iA|OVL+77onW+|2AwgQwL1^0*qRJ3c8hulMO!%4g0;Gl>iRdyCN-f z{m{i8q$mZ+5aB|A5wn=-cD8&#b)L@Y-Z*U?9I?L^SrO6qbj1ksKJ0QHpz!6z44w4G zV|d7G{;O&1rRS$g$Ivlct{*=sc&3oQ`;u}qXvHF_HOAiJDmI#myl&B5YJ`Mq`0Rzh z{@%*Ell-TcCi;<>!b;AwTIBd7qb&TTq4k!6dXWz~0*^;U1K;Hzr^KtB?7O!L+x%6Q zF$MF<^F5q$)TJM{CBx~0reDS)irW1#|L4kb26QHNS+!mM@Fo4D8_mzoP6UrRbU2Op z)|Yzxe{zJ~v9+~L&CC$GjfjjrA6YiDX`F^SYwZuQt0=_@WIBShcI9Vx?XX9B?>1gO z`keBM{W~KL_@6NByF8DECn>zyG-Xb8NLxk|jl$!k>{SvdzFhCi6@p zNRq2IpZlwRQpv8eYm!UX%gL17hRv&TSQJQ+TQ9fy?6Eheg%%bD5vla-1NX+B_jygE zYOJ5K=;Lx0@Z<98nTFL{*azHtu@dOTQ@PS1Ki9(5+y_i((G(y89#L=RCiw5V3{ZYN zk{`NSHS~v2r=*HApo47{94K=)ng6Y?1BOtwwRvOP#RSI!0=|yOK7GC(`AU(TY<<_9 zoBfy#kRx4RblCTF^e+SRe+&E6wP9?ghCbaBCs%nyPk#+7)VpXLc4N5Q<`1`hx3eS3 z6rP~Kc_M=W=Z%YYt-|#^dDESTuxQ3cR=M0gd$@0m@2#ouTH23>ox6jZd|~*nUa+##HYGlFrq2-Q&?*r%UjRu#9US?7z3n|SOeq{0Yc@=hN&ws%Ni4E^ zEmH{6%Qf~*5%nKOHaY2Eh`(g)+bPR+I6PT>Arn$ZS*$hWr3ts_V5_91@ZWZ1Wo2te zTEDoTKDl?;S`~EZ`~=H5<{H;Qg9U@(j&FC199iZ9e%B#JK1#vgZ=5m8r6c*-vgLZk z`k;>8OeoxD6}mdQ_1$*>qRAYoObf5)eb!*En{%suKd6QP zO~P*r0snI{3X!&W*gtH+h;soK@BNek92i4*C0gpo}HY1R4?FV7h(n+dAW%D$1G4~={%&ls zCkn^!aPaTSnv}LS>^Uur3f-`8oNq>MFbgY>$&*tMX=(^HGf()?@k0Wm8H=^3%wwwn z{Y}17t!UxuTKCLqpVsv~=Zp3q9P(K)2Fd1>dIFpcYq+Pv5_8>B&ApOwz|2Hp?dX6- zXVMF?zXMmXW>|yr(w~iu`HLAt1ymAB8g+YVkT;j_PAGFrDss!ss{Ygd0Msx^o1DPH zRNoaWWRy%ZFRvs|AuO2P0%3)F@p&c{&Ypd-w%fNa_740q`J42bG73viH~(hFZL3VT&Vz z*^2d7zHzQynK0GYQA!&gy>E3DDP(Z?ZSMB?-6}Zlc5BeBBDqVLo(uJTV7`#?t}c<5 z0-W_*O`GuCetlSTN+eeGJxh$!_eC6dcqC>SH*q+dr>t61ZiuFjeuU*hx9I-mUT?Rhdr6vF+Cj>(+6m@; z&S)hFWG6XwB&mKtO|rKR>#L%H#jEbRpLWA4ac?i>ag^0M&_|<7WQz>^Ck$njWlR75MjAQa@{k{jq-q0Td)+of3v^_iBepOYu z9A-aANF93J@=c*0?A&;@bLk*2wu&;UjV9$k-|j9OW{igKeJ|^T#kl^Q6?bq-pYv2V z{+b<;cc-v`%OTK6*q?agd5ABL_4nmLtuCrZ$O^x`skb*uaX@G)UG}GETG=ApkOb5q zfPL2${lY#5>mApNBdfz@AKYq>EB@>iL0O&`-jQt>1BF=RmP1JF4k_dH>e(Vt)vPXH zr~mc2&3ETR$7?R!3;`ei#dbxbWj#Ncsjn}gyZG zoOv8Q2C+1m(=GZtc_Bt1kX zAPeRD(C~&4VqIgm_vYk2eU5;m!ADlMnb;Hit<`qtQY9_PCrn0ppUvQl@B}P+NSr+ZY7v2OGMNVLhy`&F$I#d@`oh9OJ+S1VhoQw`Cvc!d z7;lMn@Ccv5@!=9oCgMY|v@q`BRy0IpgcS0}8yXGaxuylPz-$>^f&dn#1iWm6{9or$ zWfG5H(XR1WY*++(95GEn0ja_d2ma4|#hU`J{GFR4>e}#f@f5!tcqH|hUiyRybJs@d zdC{&|-Yw$*UK5Y?JEVspxVZv%0_S3Xp_H%NgfYngv4;(I38usDqwi))$*sZj&DvGf zHDCPfDD;dr>zkE*ZeNN0-i)jAS=|x}CAHH&f2xad{1>j{&{<)^6t7Iwl00SHqNp z>F+NxWCAV#nTpu}NvGAnXdEQU4wskI=NsN8`}B}(uWbStbrxDw?>D)|76GcUb4@fS zn;kVI`{aeVqQ3%wi;j*SX&{CL@t9^WlzrSDK+8JFq@;h$8Vi7!PbTR_6Ow(qxVwG#M>LAkhP##Tu&?E(~*daI%?P3v5whJ>Y|Z1`N3pP`0Wh) z_lZynzoH|fN%ob?bs4~}E{%!xb65>4OI0-`jBfIw=l;{huWvj{d_H{mU?8ONflis8Q}it|-q=&0sc-)0qQlYHo|#oNJok|f;_mT#a%6puy7rnF{(~*JrGZdz&!GZN49kZ;Q%ZYY(7zmnEW+_ zn!T=#BcA66992~f>-KeB{8YCWrOXuomK`}d!nvQ@!m|zuVGLEuKV+o#?;cZV99KBG)Jc+LZ-YR$kuDS~}h>e^jEU zkykGm!GJOU@CfGTX#$8J=|stc-&Gx=^-{8BD_%vC*XRF_Of9A`Y+i&yLXdw`8NBiveG5`Oq8uJ z^yVPZk~o613sO9eTiR}Zb53r%-i-jTd-wi9oR%QhNE%V6k9P(9m zMY;XyET<0^V1Qn3AZJ(uV**LoksY&|c1dSTAv5kUr|b@{fMYl|ktdwpha?WOytPYY zVHas8^2+mb0Dv!?TwYIN3{hJzbJd`5fhfP=FZ^2@NKI?v}nHdGzn^uLcI$!(WRz^GklokO?}W3JVL{Woo3EGe*HH zB*7+n}LbU>Z`!lZ<6q4}yKO+f| z9044%Ft`R*Ic)`lUO$92yH>bT2)Ljvq?|e1=Y>F=Oe3Yu_vT}Yc4+Uvymw2~BGld& z#drKd#+e)+`m?>3{_$HL`8_OOx_xLtCo^XF3W1zL=-!?=Od1nYAGcW!dP69(hF!Rz zE?l8Nc$S|(1^l)J+}zy$oJk+vKWCbm#zX*x)|!(_xhH0Br+RaZ{1ut{UQzDz*4CFb za>}J*xKUWK_7Btu%yZsBms`~~i?}k02!nvo)Oo_w^YbmJK0hX1tA*6>-@k)#r7|Zj zp^yBlQccgT?6s^k<4y*>Zsa+3TCI5`Cqn#U;YVMW5BF)1I1t;Mj?f1<%Cj`&;5@$1%GcXQr`>>MLIph>hE*Bn=!vdc@1xQ zK6dF$kjx*!P<_n0U07+g^DJTGVQjgeyp*;U1MHo7#$iQN{^FuWyFcBeHJQbsU zIXV!F-&(Ju*#3el7IOsV$acmImm1!0b2t}q!vsFHPhnkEsQQw`aPG=%ogaMVnoiCD zz-C-n(%DS8a^`}~mF;Q)5fC|EdZ3`Z0nTx)cB@0Mh|q`d=_mq3d>Nk&cBC09{^QTBAEq!at5q3? z+{LR)AcX!D?{{3L9t979pjN2uBSjVVO-^FBw6;nB3RM3_Si7*r~P>V)BQcb!l+O{sr&7Fyx_x=0Fm-edx*$XtEPlUSWhvS)B#LO}= zLtt;{jd62x6Q|lIz|HF&795VfQ+?u(>39k6P#UbGn%j4l)!H`z zfP52u3SFGq8mTu!^)%s|Di8NSh8s3h6^XM+uLYy>JRWTSiWczMt&66jZalGXEn@l^ zFLs4^zTW=x#=b!9t6;Il;r$c6yQQ5wBg^8OX;l^ESUSWqEkq?jvCnmfxgr_hTgb>pdeLzY0M1|jiBS8j#{+kf#@?&8z2_HObF z2V~mXM>(;-Com-L)+03_23|MH+1{_NA*SC-O_EoN(@@B=Pa2LY7%1EqtrbIZR8UyP zS&+Sf8Bk3QsF9C8@+M5L2!I&bBBGbfQW@Uw+>xZvO^aIYcxxNXV7j$@Z2#}}%_TST z>b-K#Y$OG&$AM_(+M+}1AEQ>4)xUEH6%6`SjLGt8J#{d`>5b6i^nT+jhE?VZSx;~M zlnuDRdB46i=M_| zB4=xk*(of1hg=%}P5k-*>u)T*y+N*nGjYes?~jL2G+|!xlZCgE4a|I|9ZFz#>tSDT(8u0+)`^7pea`X`q|=sDbTPjP zCrKb<6uck`sY}Vo%W_7y>F&OEH`2h_u!fG@)qMV!pF32gcAskHF!+ z35cTKxL+o^#Vp`5NC3IDDyiOGy1Hj?~Ga2z$$?*KSQ8_ zj`@V3Wx?0e>?UKBj|VRS>d@PpAq}apDwsIa#IfqA)9Sw39vsXtZAo^@;`}tE-+W_~ z+S^NYTne&2RW4hN;qxa^Gn1#Wj^p=iJY6l#so7UN2QRwl_`6Yl8Zr#ucss^Au;r`B zSN{^k&r>vQ(^I<`*!6ptf`sd+r811)G}2&^;oon^6v$(-n=O!vqE{l`nVT)mcsB^i6x z`ER=8PDz2MjLCaZl7e*R{hslO!#PG)hth@xWc18#Inf=58#v*R)=)`i`r9vTzL}TY zH;rzFS}v2;N+ibu)+{|eJ@;KaKc`rKT)jb+jPt9-`QTvScSFr)*cEZmdtwN}e1gTA z^S~U~Hio7BD5^PL@Gyftbm<^z)`5q4xq+OO*7~l7pk@Rc7_)FSzh8lDXMIhXRspth zVuvF>dF#{9It~N$u&FAY#arqIavw=l`HEI?Sdtms-^Y}5?Q|i+f|&#fvtT;DGPdAc zuKSs|-nKnMg)-tm%??7`Kp)H$Qm@4cXb5aU8EqHBYv7LoRdja-q33fu3nH z`_s>x1CF7J*|J0;Bxm;Bk{mCFOotf6I3teFsZ}URHr(cXf}NuESD;<}!uo5HsIboS z`C2DzQh}BA;}>&RBy%Gn^hz<`ZSi`$n6^TOim@Baq z&S*Es0@xOSs6YIJb#}vh7xc3qeGytBf7$-W9Btobamq?joiS!BSVQ#U!R1C_=O4}S zule{1m-y56%qZzs`HfAFhN3^H&zPY0(b?xu!W3Ia_x#QCvVTa(bx7$Zk9$z~x60P5 zml-}j#!64{2(*9iTgwjI&j&v9V`S9U*4oSfXJck*b9?qa?aBWiF2JMzOXJ1|`*8qc z$z{F&?bXG{Yj|^A7P;n*s7mI<;))-~MMM^@E7JfIJ(IKvplqTMt9hh=f=hfrN=8Wq z#T5Z^M42Y62=L!KSxEU9yfz&N2osi}Mo|yL*v$@G16dJ;sGey>mABp{3PDn^bo^9P z)ztZhqELR(e!M}NKn7M%i9wAQdjrW9p{1pz)pfQ;^Gt6Vm94<0G5ZY&wkjG`zj(Xj zMar=5~h;>qMA>wtiUV$tKaG1_9MULE&I{ zZbMI)DpyukU{jBmahB_FldM<2Y%fB+MDEwmvClU;7p61t88({M>kw zF!BG=v6{kjg=m_}0D-9+X>C`M~WQ+2{2{r{VHJ)4%9-hccN z2Nc7H$J^tcKqBNTFT-Gf-2x=LW!Z4CsO3qf_Md{apZhOCR#tXeh0yz7SHJoLw9gVv|B>jfAPs+cG~jbNy&#SA>eWf)t9CC@e>ryHBk&b-^mGNC^hV({n`1}? zVmK^A);35N1NQhIHbYS6_FkTp&PK{w@s6yTJ~!X-;p1RFkbrv#_Uh{ijw3F%i%O%P zwk&XA_ZvTTP>0Y{2?lK|bIB zhnSjuT1~Hl^kq8q6D539(&UxPij~sFR~X0^h%(0BFW6>|!=8qj2hDKmHebB|b@AWA z(&PQPJr9MM+X@O}U$v-4XhqXYc<)ZBG8dJ%M_%#}r9+IcL^qHs#EC}5N;{?U9KDF0 zRE!8VMt>pezNK}glXX9QwS%LNOBwZGxS4IqhB{CqMH6Xsu$alz*!-4w2BLPGFh~EP zU=3M?z1AE38O!_5XK;BB+=ophIzkC}0z(2{zAVzz5x2r#8?YL&;U>ka#dwJh6}tuJ z@d_TX4WyJAchJVf%MoJh``rT#Aq>d0QsL?nD{~vP7c^(Qq9gb$&@~VJLJ>iZeQVWt$Dq zn0T{+HF<5e+C)}fZt(h=gZsyiy!7A?`RX%>sVqTBTSvD*QX|NExwy4?98KlN-X>3G z!f|&raBG`GZlB$R~CEPw9~EA;v$uUX&>NWx5$&pjt;&O&`~-tK@`=V7Bw zsr;nV2<{;Ftm38JBA8B^eOn4K_0yh!;nGf7>D@9n{Au0uTe_v+%yvQm$oEMPYT2gvoq zVkt7szRo)Ir&U%%?Sx*g-8QhhOVtNgZKzD-c?XYLbB*Jbu;Urpo@bOIz%al8r%R5NXc29;%XuG57Bg>{cG zus2t`kd!^JhIginHnZhbCMvuW{v>9~EZ@FaX1(o6OJFu9=^M*jPG zS(vQ6VsG+>b74qUBg&o9X}A$sA$-`B;Un2L6+Sbai!I+wXSxtP_2hBwx~o zd{AvJ=1RB)an^239&D{-G4+o-yJrM3G+o&^fWCOGM2!RLXQa*KNs*i2s7}H-%R*PY6IudX3`S$+h0%QmQqzHvIyd1yc;xyQ@X4@VJxwq$Jq`9rdzWX_pkf{T zeyvD(Wl?Y$zK22Y=2T&f1xH+~=07Fa2JP46j6aO)BeBSvq#Tu{7*&U$;i7;gDD00~ zQi!-mwS&0t@5(}X1sm;|@BYj3J#<^atb%m;#4W%T%5$C<8gNf31b1P9Iu4n-?U(AE zVo({?1QCy@SUp&wi7MwlN?MFV8AU|(w!qZwsm6D+JfF!`VOY#5Wk z&x^22`i_Fw>+qJ<2+pF1Qs{o}A9<@squKU5a!2`A4{Ly+CdYFy=nYqf3{B6uun_(I z``2)eSH#A`Tmurl@!5p?WeQvUHV>JaX&(BUYj~zGY(^C|r)Bc!SZ^j;>Gf)-?nG}B z3_iFrfmiEUYcKcb4Yo*gChSqt`z$%`uU@Peen#O~+#z@6xKl0?!(Pg2rnA>aPFdTsrw!o)&zp5bE&4MqV)bq;lD z^dm=mX?<`kVCo1vQ4~`=Mxc7l6PjRUQ`p0MO^oGa_lhx4SA!^{|pK$`9h$MIeNrg0;eAEtqZBUF6274tE3=dyj;hR;&2qsj$B>s~V9fCO+ zfBUO=e&0UOnYn(i_awxW&zUd>9bx$LMnCZJ*A!^#eIOpP{VNThI1fXk=6PFjrN_d|O&5O{m1I%86B!#?Qi@V*f#py4eL8A#d;)UVE`(z51xt zoT_p9y@@8=BS=x3>n~mpMZLBLkRKt$IYOW?7!PT*hN=2557(}sV)#jVi0!*mioeuU z#d~sXKfg!qJ#R_|+n08JkM9zpv(QpX%Kl^B=%1Ai#fVg|(EIn={(Uft1!V>Qf~dn3eMf|GobTKcGN> zu5f3&RnV8ecU>N3K8HwCP=Tk7B_{{Mu#)px`HKD)ZN5I~2WyXuajv?k!!y=1!o2+g zqMHPbK1(4`3@t2_7|hC#SkCmt=K5-x8lg3v8NYWIe-{u-(v)A?L{-Tgp?UH9K??`+ zOj(Zo^}EF|ugTgDz*BJ4gbQ-$IE#Db0A^+Q`g%}Y{~^b58}M#PB^EN}jV z#njz>wmK2KBZn*g0~;#HsXUJW8A8XUV0}d$=LwrxTa5f@?+-GRK7RwK7pn5mfGB`d*e_I^G8>aKYtjPt4d2=%ZSzdt zi=CG=bicJ>t@K6xw5Qnf-+2aV=h8}0Lkt3!zlMHBA_IAHH- zRB=eKtU-_&38MUGyz~$3q^`Or@eug^O|^{(tGv=V*3Neo4$hvaElae0nN#5P;f*+P z&)6%OZmamm?~Q)>c+bAWt8uF|pO=EVO#f#rPSV5jO2AU97zJ6`IE4!ERN7qS=le;& zUb{LOq-)hDRplYnFnQy@&L}Gj8;$hZF)mzwm-P1T+ntl$C~19@-%GSSs~Aa9a_qyR zrClvprklkig3<_@UiZYAw9QjZhQgalPryW$>QA!|1ei{%-hvMa8T$nLz!Qqenp6PG zWn-SIl*rVtA9?7L!AS<<6u0R||ADa+3BA$C?Le&=0`v5#-Ws>H z+oi-V&wk;ok3bSIB`}fbhV+Ou;8GWQOzn>Z5x~V+43QRU?XWYGuyUraEs`A ztozJX0`y@ncRxr*GSE8g8YaBOk7lD4zV#^R!-xe?F;tiUB86; zHH6kPy-*ZMF=x?2v0G49*|gSd&Zp~L&MR)~W-gfznK^M=zQx+1!hQtT*e zZK21GpRvC$`F8TqvIgFMegxJsMUQw3A22XDXO=4MOfcj-(A%*P$?Z$$1vJCSXf>zC zKw%-fUHSgzN~zK2?5M_S4zXFh!A#}k7Rjsa^CTEXWXJA`H4qQgrmDb}bal^8+$Q?0 zE<^70IbY*#j@aGoR%tKTZ1TlDVy5)zSh~-QhzlP!ov&WUsWQ&@)3yVCy?(ZtP$9u6 zgyD&X2zv!Tf9=IIQ)X#3ztPYj!t(qzTVc_R=ZwvAQxPlTZPgDlBWT1NMTM@ognHP5 z-b>GgK|i@nnf;?5k`!u{ACbS)ux7~3K!d#jj7IyiCJJ>_6wr8ugDs}_tb%QBEFtvW zp66B)O-StbtNnogkl` zaVWF=oHff?b;k51Qf$87hpu#aZ)PIPx0>Q=M(GNdC=r&t*QG-M z9lZ_y_$iaB0!zu%cII-DL?`8`ys;(9O(*zCa8l{I+Sx^(4w`?Bs7ROuk2CCez8g|6 zBl$`Yqk7j5g+xu;KY6?-cHSRRrR924b6@>V2{)U>!jjtCEF~T>$9Z&nGD3yc z&InQr(^=&$BW@1VHpRW1B+zShpa^7(dc%S;FP+(&47Hvqk|5GI@mZ~|JYelU+dExX zy0$IC2q(N#&N7O7$o2u4$ZT9~azjG`!^im+hSr)5^ZmdA1Nm*Yz6K{t4@^?Fy!zvT zA{8Y->eRX>JLu$i3WvDQK%?GS|2(U|E+r=I35Inv*(g(=0)%z#8 zIYAYKL%yqD#M;`t?Dw`jDbP`bBMqebd~#kiL|>Md)Yv|lEtq91rGi$XF^MXbH^m6W zKrxd)>UD>B{SO|gZQ$_Pu=;NVghBX0cagw$5>FSaKhy<5;9gXu?|0(x2?arx`Os9b z<>JA32lHo?cTW#UG-Ea4lzDnGGlvhKePW*Gs7WxSAOTe=V43QQHwJPGux9i4=hl>jTxf^c3rx`aQqifph;FV3+BR@ZnT2*HG2oma` z1jI_0$4ZGDorHi&?o!2P;-a{Is|dOuPYKU!8JEIUA>(eHd8vESV#q(owIR&UwfBi@m?gPCKYA$Defo96 z4b7u?3%00{hlvy+GmbbcNYXq#n+OHBUY3^vdBTFwkEv$`j0dPSycLep7Q4HX1(T{i z&~WML&)CPSz#XOjY-b34%&Y3re>)2ul6A=$3r-rM5B!4ID1?pD#L#BlM;n3AyOwx|l;5|~&ee5_1|L;s0XRMLM4LF*MCVaUrcb|7(o<%b#lnM zoPIwEC0Du{Ellhx=OKX5-1W)(!sr|^G+wBgUZ$QOuR8l~&`$YN=eD?Y-zHPR(D+Zq zf9-2ljM>dp%EhSdwd9YyhXnCoe1k-(ji9|gR==Ms$clMVH6_6}Qr5YWRKK*Tl^5lZ zWfK--zwJ|%2=dbs6H|;v+UE(@&>2B)>6?5}^|iBLtdmk;iYn*hHII}{GMuNVoG9R@ ziFfNm=m*p>TFv+OUUPT_KV`?(ub(j$FqK1bRr7is(za#g-$Lpx`+jrUEBv zIzVs_qjQ$U+aNE%S)vO{O}wE^-7R=)YbEhH2iADK*lzO16#8ZH zYbA*+VcoqwOrGywCeJUCX+uo^wO;$7cLSR2vS{ZZ^d`@!D6)u7&-a#!M1{k9yo`ijNj%TtBMtYDz@s^o*q&AEH8`gND*XEl7Cy{t%aQJQBRtKYtm##r8bL_#Z0*KOXHhZl zhBpr^+^J^xt17gu>E0)!hh*6(w%$CA?8LQk3=A}v(Z$=`jdlHyKp62QC0RCM zrGx6-eR8*N6s^#FMTwuL`u%6e+dk`CqE&fBVOuk%i*TUp8N6m*bGN+^ZhQ6@h?8rA zM8vs%Yl4xUUr%Fi4rC5@|FAadC7OmN;I(f~)!&~1&lQw%&$~F*9^TXo+p#%JmaBTU z0$FaqVUGoA)Cbq<%-U41mhhWa`jR4gU`dKe*BMyPa5UrR>x5!)7yhgSa@2>NGuJg` zp?Cc5@~SquL3aW<{AScyhJb6p-@^=Ejq^ddkwER`72*zKfq*WL&e zhOd7y#oW*Ac#{*XEwC=pmuhxWwj>ins`bezpsNRE7O-1Px)TGf|NKXdIrMn>wi3d0 zM^ZoA_fzRSQ{6}c8H!;SizN#CF`CdPsh@xMStxh6Vc-|W%T5}q-TSi)!N;$bUoxOX zrCCAz9Ly~%Jz;;q?#s}(Z`j!YnuSJHXu@I)Ow&BG&qKXVZRY2@qs?ri1Q))0z94l` z?p=9^73~~J>u^54d6vUt7wXE1{B+w&ZnFtgq_AIqxEM8VuK?sYhqw4?r39B0!p?er zij#ssG@c8de@xA>ixY6RncZ`z{rZ6VX6I$e7+GII@L;+oX}v7?fnA|+*-^dx#Rn$z27H1P2^ zP46g>b8u#TyE}~Ovc<6HK9;jdt3Q{55N;13lKtL2ZF=fP1RoHGb+%XhR4E3oo=ilD zav4$X5!m7MsCc9gVTCrI7o9-W9?QPhJr9I%4;(D{i*2!4^Chum4vil4=4r)Zx~6$V z5I)!_dOZ+0n$9SmF-gB5YoTj5v@&RsHd_UK1V$xZ5$;fu_JQDjP{k{nTADUa2zyEWM?bXrcUoSIK%J%SyJJJ5uwTRTm7Dl`&5h;# zh5Pb{x>xNq0;CD@8GE03MS9Fc=bLbVn+8B&UIM?LbOcuOYH#OCil3rxCG{=B#}-~J z;t_gQo;EW>*InB!5qCaI;bmZiFS#P|i2>Z0U%IegL{l03 zcBa>NLLo8ZkN{hsHkLa>Q8r8tagJGi!rJ}UeR&W}x0cL!IU?lJNZcQEoI;SuhI>C1 zhKlP(Jfx8YOjSQ3f1mrnN-)3%q3nlGJ!%Ef$!24z>JmU(b&wc#%3uAoD*zDj6*Km}&C>%RaRL;z zu1V0~wp%Yo<6vBa=)XYG=yi!hPOE1rQS?f_%wOUMlPh&Jxwj$GqYMVKAmcPm;($p3v+&};}hy^f7rk6zTs;;T*jElF>ep)0Zu z9MA3NlZXTnmgE#8MsN;+CwZG1#AN7=5lTuUc4z~(_tcPNq_!UDw@(65d=g7;P-H}& zy)tVIeZ<*M3S!7QA6oq4B53E&MO-P=JZm%_?g=xs>UvJO6l$yG?tTprRTo-)*Sh1+!!Q0g{<_ZO)~__dDVobrhffs1`V23OmdWxIQ|b{BZu#_z}ds zZ=o$YkxAUa&5g9(YdNiFSO;nhBwe5tnG&XWu5UOc-G7^G5c`k?g^Kk3SDfM*lbW>l zsMO`I%N~3a?bRvc-s>D1zokznvAb+S=`*L_e3hVk-+mS$v>< zhw=m3u=3ul>i!n}#=Q0GuAm)i?avpR4{Z5#+uYU$$6g60s0QF6w68ojI*y$<7=UgI z_NR2%hwJZ()n>2M^yhb%De<%Hds;j?>Z88;p$#fUEosxzR78|k<7WLR^DtWBIwtzA z7<7}cbIepNt8-8N&hb~gHA_Yw%+X{LvdzU|Qum=eNuj}DhHQa`kCnm^uJ?Yadqa}u zEx`o-jw{|RBe!6AYNRQHlN-8*GlaJ`(YLYykI)CQx-YXFxsG*hmCva_ax>*W-#8p0 zY1=E>Y%O9XYJ&AoO{MwK%i-k%4VczfMYxZJEowELO+z{=hezDIv0KxfRU&PEmQY1M zJ^VIWHYpn2oj7@7zrYxJG}Eo#usn2rE_Vr67bZ$ZdvUG5B!}nf6=QILlnSJ>BLNbj z$9$g+(e`VjwxJ9|rSvWDq%Xhfk(uUM;h^Tgpd-K6_ji1)tJ=Kx)ANK*J}2a~%p_K8 ze^)g}8JZR?l}lNcCd!7KL)zMY_Wc=FHc6PK!yziMSjjJ4@&coA-pC044u2~zvZ|qp z87rckZ+-4Y^9)d#V*E);O00d4zkCk=NbkwhzbnMIYin(kc@*7Ci$%$WTK44-@7&K9 za*pWkY22#9rq~8vvC7IR4gw7A+rIQijB5J~(kKg*kX(T+6-tox*A+r%k^{}t!*Oop z%F5XzUn+>@BX%|q8w3;JMc}?j}t5-;z|EF$!Do>wmILDpqutdH2cM? z4VSy4lKG&g&q8lT3gF@`3!Y_eM9YO>PGNRs!-;}Cpdj|y_fX=xr^KV9qjpk5-~vv%VYg&#Wcczl-o*u>>t_e*yw z+0$IMwKM*Bdt&v6=7U}Pt#HSg&*h9PmnDM5;h&7mv-+O01@G@QtY+L(jIuXxgps=# z6sqK__o;I96cU1hQY#$_;8?I2X;d!t?lpw5&o?X&D4l;+>IsnVz56SKYk%mqfv&;i zF;8}nxun~j)1S|}qoSg21t0CYfGWCZ-AdgjX?2<=0mG$FPxcKWCb!`4bN!$BfBV14 zJ3CxCDcRT8>8rIileqP7Zu8{_xe6?5_6A3FGaW8EvWe+HY&1}JBy(7ZC-XqV6YA|$b%yeA{T&9E)yJr`;PdVjNgBtJM&FH_YUF zm_dq({H)aGSSslDYKjYU#1l)0YXmK=cmJ(G9VkuxMla*#Fp~7n_F9e|*J~T5Km$?D zQhm_kqd+-m9HDcot_!o5endVlRPf(*+v)ksD)lv5EtVMoQJU%_!zN>k-Tz4hU`CW4D(V8E945>0`@*unq1rGI-TFJW)~@yhSrnH;^!({J-O{g#ir z6YtmXHIt=Kz3@Il<>xq7U4P%)W=URZ!n`zj#k%7s2RyTxT?)%*KUGm95PJ&B z-{&D^+GL|mlbnA6IjgszI_e(fgSNe1qYPlD&bAGRh!pg9Xxj`-x!c~p!KK9@){iN( z*QD=6&A0lMNYRY(TPhP~YWbsh7>PgeY_?(IsAl495vU9t3jO@^$Ja;tk_@|YRuh>b z{QQ5hQjP#*Ks$f+wl2HAr)QjLLAk5kb`{96JGlVb;-!ER+8>9C? zdMTTyF)bC2RVfi`HY}8@bM%MrrSUY>lcrCpM`t5dq6BD1>i6X2C)8*NhL7<&Wy6`* ztA5a7?SUvYia6YLDeU!iyKu`;dtV<`~ zHEZV5JqVE~FsCrd`MZ2jkz{0?92r5xV0$w-4`vG~CyrNS>)FbL6CyE~$wz@&(-cPP zKCZR(ZiC!*O-2xa*~GW0UszM{`^`3W&Ycd~Hj))lmxC&5B}}v21-TZ$goqFeYJ3YAm`3L21^;Coe69 zw>;E){e9s@Fpj#BUmHe8HzJbw?prf+o57DC$&N|}o^>C420y(*Ps-edbmVOBP!r|o zRZJo>KQXZZ>d6P<*oXk|sHD*FvAo|~YhE9``||;R&vZ#1-o7LB^UwJ|hUvUla}vRD z&o)?N@ykY%PBX-a#sR^>O+|Wv4BDqdA;;B;+IkKu@k_mU-{qG&FtBqujHNTh)G9Mt z`=U^*s4ElGM zN4jwt&~47UFUnUz@+TNA>))>v%`1iT|Na#{lu}}-J~jp0>8DnVb~6XW&Xawu*oUMu zB@y1GznCJ_3{h(^qEN2Ij0C-8Nxde=?xT+)lG@d0SWL-UDRslzAKNpc^Q-!oWvu8F zguXqL-)pHOSvOlOVonMifDw0VJ-uMyH2+>PqBF9V@pAx4^Bfz|H|1quAR#2kX+?UD zmai^u)_2mV!wueEVe46+%t=D22#We+<{xpBxc*pVEPKTx9!*mf>4ptB8WE5v&`Zrv z>XB7zSk73Kf6{kn1J7wAdtw^mldgpy?MzF9NO1%sh_s3N>Rz1%vA0EBKZPC#+0CcvBvW%dh{Q8~=>H+;#D%Mn>Xg zJ+ya#zYe!4m4Wt5`dh>bk%0;#jh~rqo=A4cL#})k`iLSswruDz4~DfjK4<8Yi5C}# zRg^SSUc&v#TWOY*Xe{kwYFec_tac2?Vh(Ll183WUV59#k#gHI8E5t@Mo3P_qTbPbG#sriHcZxj zNTh(dZFquVVpD^du2qM31j%i4G_jF7eleAEzqqLQ`rHHCUYGgD!#M&C3+cGY05V&_ z0rFrhG4V>DBh6_9j=O6U#iwaKsyD$ZbZs7%6y+YkiG!1@c8Hxv;ik)?A5Q9je$)!g zs`}91w9s`~-=8od2lip+Y?WlUJO@dRTi}~nZ5U;ds@bYnAJobk<&IK=+LBz`N&O%s zWObwf!3Sy@!NIU6+ipL>WVVR@-Lb^^s*e;=7&0}P#uGbY^E{HBgm|p5{a32#B#PVi zG&~e)RYembjBkF{7m51}8qT%)6{Q{5suwupvFR-LZ*37lU3|yFp{8?EAw)h9ZhaFn zmra0u0>Vej6G$AVBlm8M!<9!Om_9w!T8s9&gJLpPA_TM$Sm~)lZ!S9g-N_4s|1!%r z#57^tPDdVr@SNf5psekd`>n8+yPiDaB6+7fxd-PaA8sGJd@&Q)vV(p&+MNHuRz6Ig zlO@!}#_t&EF%ZL1mI#|j-ORo08c^>@tXr_$p*){vD+@2+UTDHijYz=P$~Y~KYMVOf!ywA$TZKxcIrhd;JY$GcdFCW<6 zwhG+U9X@8u+BvkEpvQkl016n{MWt}eqc8GZ@lAr87Gk=_8-zmVNAh8DvG5lrOifJV z8^SsXno!NGZR5Xr<-)6TE=I$Gm)ee z8Wmb-VR(Oa{e=<|mHx&<`t|Au@h%diQQE+insa-Fo7uA2kSijqUGzf@{lo8`ci{T; zGrI&RZN+QY=wzE`ddOS!EPbj1wye9|xX1UKH#@OgmX3jjuk3j&lLx)ovpGogho+_^J|^_g`apW&TY7(1y-8z-Zpqe1Dd)to zMZB@Gu>j?PQF`4kCh*F*e}Vn`}Ze~PD7lHw4~p1t8)S6#XNm=I&*v1 zubp{6!t>SIvt>25>t9+o>i;2Sn@kHV?IRs72TDY-6+eRWR1K16Z@vC z$=N%@k;muUvoep6gONfBk+QsGKh;K@O4wb)ncf6Qki^!LiT4tePC>Jrr{7!5k7RS% zu&Gf%xwi;^bzg{mjt)xSlBCG=AV}l`x&6 z5$*A1694#RAEB*vPm*O-JnXM8u%7M7N_A^sy4o@y6JJVFnf8TO^N0Z8(?=pUl0fif`W04+WNY+n9*zyAs}^nn{!k|1PG@&1}@X2Bq$JB zC>!#(MHXJQX=<9+fao7ly6UBV^Y$(AXiJeLI*G=8z#g{ zpkevK4=4C^RdcxMa=NlGIH5mE4e*R$6>9nBDR~qi3PqESN;+Sk`pE+h1!VZ9r)TlK z4h78LQx6qUA6gCCPlwR@z17oG5{eDNDh!!+-rC>SZyTefl^~seE8N1P>^(gxpZ#3w zKRO}Uyf>bgHgq2PY_ooR_qWwZtzja#k6*bAh2D!O`?t4=k1b{J*?3SVOI${9mU?9&x(`#-hndx1bB$ ztn3HT#NDba^e5k2^t`=mVGTWPo@QBmY|#=v6duGVb8X+z&g1Qs3vLUJR;nZkit~`w zWg;>85M1Dplu8_~@vqZ9!o8_Q{&E#0*lYA8U-F`^*YzutpO|7`(B@O;y9%`hk+R7T zvItAykzUZaKAH$w5*e9$+zG0=xZPbLoORM?JYw?4Fi7U*24#uvJf(#Aa5*~|CnLTJ zrPj{VYUe;v=PSP?i;2jo;G;^7-K;zfKHXA{u0HB)F_>1x(Nho5rf!T&(4EmUIAlPo zK%?>4R4r4L&MU*z3y22?$Xa?jn_VV%{fbzz@*ZZ^eQjD%X^BPIXooUP-fTKhV?i>G zF;bAIvwkn!v7oM<~5Jy89Tky6fT=AZ1MD&eC@bz@+?#gwGBbP4MI{w;-v=LkRAtqyFZ>y>fVm1u%6EYiyT56DfepJ1<9I% z(Dqun2i8*>;pZWpD>cnQ472k4=*o=En>vws=8ktb0BrzUnFgw zSHqlY!?IeI5x+7(b*yd6=iD^#YDTjQL9Ad$=oNpwjx5co;!%n6+nK?`LkZ^A1UB&6 zH|<>bv1t;u-cPz@fE1L_?WBvOD`*LN)4hjneG|zaMJxmgOJovLe#jvei)iW*Fnsyp zrt5&Z*EU%8qZPMec!`4?tG(Ro>8xlO=HP?RV1yl;tK^MrHBPl?IKq_@4Yn$)7VDFX5bR60sN!gQ z_*t{k&5IepIR5C zhQG{2Yy5jmx~A;e@^j)g&wjX@(m0bcRbT-(2_798>6kwR34NX9WSY)xL2WHi7mUjK zvhY>K+C-7FsOOF7>gYJ_5bdXFRj7ttK4|fIyRdE!(#Jl3*6)Fh9gzOCB1hbJz+vx9xlGez?Vx=M&7aO0P!B7Qi^CEQLMEM=$Hlsv4G|Ax%NDCyP>F zyyyM@;r57;e@|O}l!k~Ky1wBkNS0F(0m6=ch%~J9{^Zb0Jfb4EXZN=Ta-llKDMiwd z3HZW#pL)zPX{RA~BbG^Qi17%XK$kBt5Y||Dd!+}PN zP})uVxHPjuX_a?*4r`ysECV((vyD)#wH#Z|1BJ6Q5Fe8F<~Msj!70r8Z1%BYR`W5= zd4>#>_1nX3rC*&8FUzrBwb<}&?14PBySqDeh`7J?i23J}&|fDU*TDpu#f&xf{HIa+ zthzQgs^8jP{ZbRgK{CwQ^|(tMj7>w9Y#sz>6)}g)k`VX5r=h8iTPJZ#zdQwEyNI|I z(YDpq(yyy^N~DodcDWU;lvo=W$$H60vDD*=pz}lF-5W4Uf{l1z9}aVe1txwTQMvrszBT-i@Jhv81e^-CIOVNVv8 z$r865@GAy~_sLJh?6pq*Y?0vDGo{Loj@|O7)Rm=TZFDxzlKryG6ptl?jYfM~!u55} z-yF+p(h$tzdH3KkKqD@tZ_;hXR^+N?7{C@^mS)hy>S{}tyd3?W@I0>aYQJ^3 zq%SUPNvoeWyPanw^+uV1Uc3=6H+(FxIfCw0G|{Arc$07=D)FG;ENEit@=1C8=)-`W zr-gb$edD8yp9_u^Rp$|ag3)uiou?h&^jyN&a^C-qThkl=J?YRJ>QK(4+rg((C{^!7 zb!RnRSPc(+uu0SmEtDJKTlP*^TRxHR4%2cz|JwUk-KEV3p)o3gM?wtonllLNOOp&m zrhfRw3ZJ$y7}m=*pY*^j65jC-q9bF8rcFnj?cQR?!J+wZI9lqMCmgo>L3|Y~WxxfB zjg5s<(EG5F;zXukg?+X@F$2f}VO^PNq3;paL@T1D_v5QeGc%sjz}7CMU?rzX+{h-AElxu&MHN@LW87iRj!Hs+;O>J)!ntm|L3cm8MW0-nuJg0Law8T^tff5G~_7k&t&Rt^@#>5 zOGQo1N1#3zhwAOb)9f+vSm<+-S4kfrDK(@Za0gWecam!Q9r8v}StcwYQhn-yYpZ3) zvu&#Dk&|xfB{+yG_c^&%5Iz>AuQ2-~rz)^6OGQ{lw&T_hH#LnxP^-cRd+c)1P7cyc zHn$JFco*_?YK+F2i@zfiopK4#tNFbB_B7suXLDdP{d@8^EaV6M9~W7uou?;Amm)qC zr#D5#^BU}w%}Q1E1+QHw!bUZ+roUAQxdB=_3NbpMW)^v9VHiaAb-PmNgBhV>m#mNa z6MYm{Nl-`$HJEk#9jlff_TM{*5h8RKPVz4-kXL)ks~uqM?Se7&1=5RY|WPGIE=#K>Oxv*zv?c!_9Wsm2D_a@cFJww*@2LVtv$} zj91D0Ug^?qk9#1`(@x%7i6lfLO%zwxG;ENVrIln*;kPgMqxb9|KfcG0Z{C)S&~9wP zs@7EGagPaZeLJ=op4Myn4lUL85-6Bf_r}q60HfHXP;P*}X z=d>k%^+5M`fhizGi+x7f^_B`DB&;1yeVC`)&Mm8nYQ8fQj;oy+F7QU{rS&O|RNlAH zqr)NNTT@Q0GEcuZ@en(tnQ*%1G3t#D{99`OJ|AwTm>E$|PbKcheZ(F0nNmmSVXa2N zCdnL$HXHW@IXtGQYGnXCWZNMR4ZR3VynfxY1)-fGicgDSRd4nlg{Wj-*`nmo6 zA43w286p4!^0iJbx#yw51~)k3N}w;$obH?^5Xn0UX`>}jth4_>^?j24@+a^we=c?= z0$X%gN}@(2yhbujhW;{ku*)?E9cS0R%f%q9Fxn(Rb+7Sw1$VsQ&MoREVbU4d8uT0( zGJS$ggz}ffT(&hYkJ<_1R)-2aLJ)6P(#mZDjK_QFPB-7X?uIpF-;fjIY+GGy-&}?T ze0<8*Q9#@S?PRbUOtb7FAUNW@AoURD}VMwN`qv3wYYGBF7hc@rS^C8;(%uw#(r zIu$QnSLb2}TBoF$|F{bTz`ZuGEM~cpJ&qDZ2kiQp;<$g-5(*vwk5R`*hcEh>C}5tGd;Rv>lZQ>S5{6wZ$ye^wKF{uHV*6BzivfbwgM+Z8 zrrD9wVBrN~%qhgN`v3Ms-5`H8t_&D0Ws!fIEhWOt@fBKWQ~t8j6)Bo$#(pNLt~G4S zT(?+T>#}`ZReTK3u;fVwthp~^JU+SPepzb^D@(Jm+-cU(#)qoEemm>+O)gmW-FV1% z{^o!Ap=(aeVjC8RasXl^rICp@ky*jFf%`FrY{qhwjgE^uNO@;cG>3M#Cic8mp1y5# z?fXh5RG#Knxr1h@v<8}VG$@8_{mAL2Z+*@C>EETG^{dZ}_r*Cq2$nWm!KzZ95i8+B z=C1cH|8L=4VBuz1lE{<#&E4HL00@yyrT^j>8WPMAZWiv=x%=}5YFbyC=_UPBUCNi4 z7g1RNi&g1-bF*UX=!o^PqDc-JX67#EuxknsyuyrOm;s|LTeunJJQzxR`rVc)`m(U% z;8$jXTLn^XY;y0-pSn87TYk-5IGFAi~F>< zE}-o+&Q5FVN;*%NM6-U2vuv4PH%bVQE=U=!0-f85|N zpqdifEitdE()lc~M_XrA?qMEEROf&v%Ahyk1#c);R|DEu8#LbUGjVI6BCQ6Lh2HJr2P;rUp*`eXSr(?E0O>FPtWV5(3ik}#;) z1q7IP4?`pkUla-={q{{;w5b z-#J-_Gb7AvqAl*ohQ5Di>5#R7D%bw@fJ8a!``paQx;)+x5k|(S<;FX#MV_|JEicE- z1YXGgIlm0hB@zJWH%(fpKQ$|JecL1%teG2$+blH6&G71&sbkP;m$!Y%Bcq}wlCUCY ziD;yJN{VaCm-g`&?YQF;666&bWU=OL^W{WLm^Z)4N~5{hVR0N|GZa!FhZJ(Jb{U0+ zy7#X^S`YzV@ADO*YE{;K#KzL7rZjN5fr+1svIJ7?M`Yt!u1%Xm~;snkB=+ z4yuTz*5FaR5?RytB~R;SRH2>)TONl|^XSEO3c;M*C{(6)^#4)V0C>~jU4Uf*sFGvC zBmK{6B#N>^l;d2C^WQ)}N1ukMxh9TqD(-R%c^Fuljgk9%LaT=95-n!+GM&U*qvesK zqv+3*Cnt*)@YOhdPX(9eHa5}MctqP19YTMEm+98J5x@Q-FJ=6#jZw=YvzlzhsYE+f zCAWY#Vy;f7sL3sjX`^!-4D&+=_lMQr=e5iH2UC)M66b)+ewBJBtKcMd^f|jWuk%Or z{){QzYDvd6#*DaHrrnitZ(b!y{+m+9!Jngu^XX+q%tKxdc-PW+sFp{zt+|%E8G@!w za-u64A6mu_|Jp2`MwhDXqaR#b3e^7eQe(`Vwd2_{=eD$|iX12rU(pC9ktqi$`o?N> zmcx?0P6WMt@Hss5HR^PeuI!Ov_WIn{LL>ZCF6-?;k{fPuUx=x^tUd!zCJ$>vygi-< zZ7)0PWNc*=GyR(|~g3Ynw!#}s$u;u4NXyVlqrw-^r2j=NWLGzu>JPa?3JvXpf7 zuB33Vv6)h4WJ;@vL;xDe(bPBW2kq#Jj;ylPQ%x8?>!-`kqvk){v>IX7|XVK@?S@40!ZE~NJ2S{s~;y*e*Ez{K5 zE=Lg;0fWOs2E=~{-a+`hFNDlmX@3a}dBXMooe{-ccAuD_V}LVWlWY)^{}OTu*GZZn zx2rPjQLht5aZgA}EYYcCPPWFQ&WJBSwgHZ~^wl#k8a{X=sHDdfb78BfOL^|IuoYBJ zDVIuKb!4}?{DnNoE=G8tEE?)J^|_-!ldwBCa9znC`DCx|N5vGH*ivvZMOt8&S{30$ zM2qUy$;nlN9#@Rg-yV8`21wcgJi-l!gXuLl9R18 zTFs#>S!SF?{Q<)W)HSVjCI9cQ8&yA_FL^lDxO|xAp=$|Kti>VT3u6rKPaB@Ar=TnU z_aftn$)5Bge^z8gLTMA{9C(1wHsN?M*`Zp4j9_e-D{f&rE;mfEn2PC}90K9l&fog_ zdb2=B$XpP2SaeUP&;(s(BWvmWT3CA8ni8*vgWR-HjZrAz1aly1+bvdO3H^(=bpGGU zWNd!g`#5O_XWfBLF;!^bwDg-&`&b7-9+Al7 zV_WvoYWKcAU=Mdcj$FYi02tK%_PkqX%$iE)C6t!ad^go>^Jj|TKI_vl#g3xMW3$~f zooncc4t}q!UsFp<7$tJ@)Zw2SP1T)S=OCng&XUiJOR~jUY&-oo;$RXCPgrOU()#W= zd--HYv|u48ER-07>hQc<<)C5E$fcybIR}ls+n%$P4|@F3i}#OKd{+6AWoMAmT#C;a zPkAM*Qo-43fGFzfsDzd_Hmb^`a%exez-ak> zxaOay)mSe;2%dTSb@=D<)9GgK8>*?R?Qu*%A^Q85FgR1UtQqobzF4gB_gYxtdWI13 z?j;>PTIE5;qp!4lv>8nk4Zr!RSgT;gaFsn3xJi@&R6t#ghCH)_KBF9_z#-|m4z8iQm5$t@U zcdkkrYwWb8ai_j=I4a)4;$U4(ulUmh#L0bBC|MYM3Jmnqm|~-au_k_WEjdi2uylQeDbVO?@fu;XHucUl<)JeD+%jOPAUWWr ziwfbCpo5(}o2sp%g!i!8x!za2zrhSr2oYTdz;crug$-$sEmc(#l^jGE4DfRS2KAY> zlxydizxbBOjADoQ4yD}Q!TOMgIDnO9ot-g>e^jEDRgAHZ9E!fxbp-e#HunA#s1E@n zWC=@ z$jSeYw=*agtMpCxweD?n$Ci3tihWa2yA;)uIN5f!xkkKu^VcM*Cyyr?#oHbO!1@cA zk)^#{Cm}iAyKUfAXWa9y=&j5bnsX(s@v*1k0_mdyxRI60dcHGp!eX5@7=kQQ{XOAX z4~$Bu!DbdMd+lNQXpK&4@ht4mnK7;SsecK|X+9qEx$Fgq>@)cg7BAURXY48?M!HqR z8?;7(_klZ7S8h}dvvg+@AwOWw0;=<14)CdGys8TIO<=%oqlr$_!MZ{}dTi`PT?pQ*6}It%L9?Fmw-U%K*%TLS%?rSEWEl@84t`- z-hX{LfZZtk^e8{99`090#fuIDDU+#5_I9L1i(cA(g7Hw6Ey)fu%heEO5}+hh96I>P zlc}o%CdB0z>i{A<{up!>!zpIKo}1$ zDWPJ@#<9WG{p0Ub$@n5FW%Jdp%?K6$g z?dOxmj!^Gphe}#mTP4#o#qQ&f``utK{l0zyiEmA53P+rFeyMm@R0SKN_<&m2Dfi()9`K|Fbx1KkFV;%<#RWSDp^t3De5Q#>52PaG`~q z*E`BHQolq{u^tg=OlMh~8kEI`41CIQ#XgU$g1z5)|AwAe5H>f0gIqBdQN@H9g=p!X zRGX^;)*rj<@3Qy?&!{Uw{v`|!PU~YG6KYrq$tCKB>h=%tglk%&7}Z$NCoDA@dS&$*Ew#FzS4~O6alm08z<_u@`llqp!G$s7wHTGy zlzY`hJgo8~1o_-I$kcUAI5O8>^7g?lodLX(R2(be*L59EOthv0xD z!m=>DxQKTl;P*Z=E6W84YXTNzgA{)SP7i<~6?;~?jF}aC3cl{%^K3urkH0o(F%SQn ziI=b&X=zaMYeF;5?ahe{11rzkfVH^PmpwCJ_-M8BpZ+Nqb1x0@z8&mC&blF*aY~kp zo={8BhR-g>e=qr~K#D|1CV383{vACYG3kShIW=Z{b>^%AvA_@i$2lL8E%ME62x(6F z=|hIe#ck6y`2((BJl^)=v2f z!b482)aE7+2 zhu1bd#5UY{fKfT4kbDQ`fYe55XmRn=SLg;{HjvvNZ`7(`JS;WSCnP-@8{FYULPxA2ps%V*zkv-E==TT}pBQb1F%1Qq5K*o<&^Z$?U&%s8Yc*hWA}nK;UgU(1hq zzQ;mrImd&NQ<_U<0q^DI@#*Ywebla zw9bySszYf!_sWfGe#mx3mrFC9HOrdao?l!0K#_DYfyOW82`O9lPmPr+8z8xToc{Kf z^tKJB4O&@Q8SgxA%OAo$Ax0T5t>IWgsBA)$WXv%C8XYrkxVAd5-1iSQx1JzC6;`k! zfe#&4=)T_-Z0Kmz<$=;_kWtia$rJy&-O!m#X)_?t>s5=-zeyonENGqiVQv-Z zk}}?O^ZeDv#6mN48RbwjcX!+e32eZ2S*1f$Ad)oqkz+6MD|O@Nh5@kheCU%%X>@VA zuyC)X;?JWdk=p|%!mf~teJK8QN=D_0@dVgL04|NtbDjP8Mt1-QN4!G4p|J8;ZeEWb z#!Q!zZV{4yu3$6S^#FuiB%x1g(I{x_Nc5-guoxy<)h#iTj_KSTLoBJzl)sI1-!RA% zn|pfVTkP&m;z~?w#W4%!B$h*6*Xdn}RDK7EG7ID1_ay-mTa7dmWf6^96q~Kw9^T%T zP|8xcT34J_>B88kEQbJ3ZEk*!-$zL=bxs^@Pc3oI_@sng;NEAMF6s^j7>A3ep7WLC zb$M8@naW0TRPZ{PnXb>TPuMbl8ko@FMi$XJF9s=1&viZs1pRrQM(Ty7L=JOf3FBqS z>CY=iiLe=tQDVYo9#R@tmRLaUIPw>HeGq-~B%YFU^qpjSX$vWKLIkLISTU%^*)o7!uO~6vtJJxl*%2< zM4BpSB8leV>fw}Ez|^jkQYv322a2H&&m2*pK~XwqQ~iVHG)=3$ZO#E~b8WiDm>J7n zF3+fpvslZ`j>QNrqXX=7%eQ!xKn!r$PpbFTH(E!BKRs=NOJSNC$_XK(rd&j9Ir;&% zGAg<-1D&x`1a3lO2)05FYo%ZCj=Oeu*5jIJ9?tXUa}K_>JA<6MSe>1EdFg{_t{xWucG7}hTO z!@nmZBOB_Ak>_?C*N6$Fl){m{3ZUpa9Qe!h;kvNC2K08tMzif{m=S_;-Rn%D`|;oIwk;(M*T;4@GZC_t(083OnRA zg^K)H6B?3OMy7#|_#x<$6XY$F<$}BeVjf>1?;B1_8oyBhFwn6uOcBuX->cikw~X+X zJvL1x9fwO6)D^|onHTim!*{C8t+H*W}L z-(|rdl8+_{AfE{PZy!NqIsBnIiK!aI-Ovi+@LvxtY>ky1d*!IWD2MwlX@{^47-7@c zgx1{Com^L@=CCcsak+a!(FE$?i#g{gX)3|mKdqJNm06K1YY~+T{fI4Q>AFSy)k!K* z*qXj~HBcR5wTMb8RWa!vRnf{*v7pIFiRZ{S6@zjzcl+6uB08M9*&2*`q_|$eI^LH2 zQ0+j(fr*?f81442}KM^O{+rm{M7=QP1{&c z^B+6mcy>mS9xmdpKpMkKb!*F^xX~R8!DScLMA0;*s8n-dGD=JppT|Ac4y`yPZv1?B zgCkKuOBmi}%f0g#6ibHf$!p>UNOvV^umo~=GmbkcQd_x5lo?35@?(|)9{;!AUe<4z zsFp8@f=o*P?*-Un5KWZm3;ysg?g}n(YSn6GhJ`>`XO5r}Y4&lIQW!51)a$Xa-wI3f7|&57u=+8ybH) zo82NLg&bnl0@Hrp=f=PT!svhhdY|+*v-w<8^lY0i7-UR$Y{k&LCE?r7&k$qxPse$& zB*dn&Qz)bLApoZDa)4cl7&p~H9Uqo?Sl){u<-thG>w~`8zK~r0Dp_Ijf5uTd{}YOy@-~h!MGp-adL)> zRkP58-pyCG3Dq&CZIT>r^oV0e=zM3UqQEX1cWv{p5PDL)92!@eojBqdB(D4Gb3s-G z)IiRc8QLn~rt)s{`QXFR@%hlzII;&svTQDVi?r|kEMl^L#9Rekhde^@HG%_41MP#Q zd3B+Jbb?e1d>thay1?|y39iys9%^a0F*gzScD)$@7j!umgr2{EJllMX#f6S~dv<;* zom!rqXQCGH?W~oLQy_FHLp$0?<&(%hIUtY>+y$^08xDuSX#z(5{{0WS<>SblyP+~I zz>Zs!;``YTT&kOM|3ZecE6P5pePCN;S?^(-3SWllQ$74e^ufqEdCv$T z@s{q+!tJa%rZR5djPb8aIePRN%47@RWS5Oj(P-JkOit!mjEETp5Af7$T2T8+aZR!?d&vY zXlNmHAz4MrWST8dOX@TvXZ?nk+^$s8D65|SREb=kqN!7g+RDBZy19h)z2g&Xgao!c z=}>YmHv7EEN+v>z8@yS#Utkmu$>!;BsV6s{KCfVT9o9+&3O2g1hHH-RwdWC_o;mmV zqIMc3x=}d-Q*#XEHTp}r?saNE=iFMj9qUj3s{Xw2Zb;P_Y4~D`Zvoq>K;LNQVw22s zR=~W&rvtzFr%9bu!~+=@7uVrB3*LxtSvkB$> zKWAsJ_C@c9L_3`A>`sbaXTJS$ep7E!8)x|MV~eP-X9Yy>*ws4sv+p@v|NRaf0)laN zo=8lXFgCL}bMgs4+|I*6;gR5Nm$e31C=0|;i)_}b8)MB27>+Ub3e#G*vd|rk8@a9` zt1S@X(0_ngI==Kd<_6j;0g`S)KkE|f5OlSPUJnhcIO@D*;>Zxj@LIy=AC+OQ2P+#J z^tn!WWlIga+cB~O(BDLdu%AJOSL_m)(IkjM?1CM}N z^*17ctIB4PZY)e7DyOeq`qxp@VZhM7wQH`c1FRk#h*Vdi`(3+fm zN4HyRZMYE9>`8j}=X4!kEEF$HQqpqBlhhM3bN2ullizhqcXq#QUS~ z8S#=^N~s!KO+@9XfX9T~IOANTbd!O8q-m2Hq6Kdw+~pYnwk(cMK?gGRItv+yi9^8B269$Zq( zrfe$5_}Prm4tL5A2Q)PJER?wJo>a3O%c3A(TU^Cz$@=#Ap}`42OT6Fxv@o$COgS)eaKIMMg8pEU-2{}E2N>J-8*H@2B)nbljDr+=Al|IU)*R;xU0NW|3 ztUU;k)yt&iCoU0#vw<2DD*{GHl=?O+d6$Z6tCMX~80z4xjXj1!Pk&dYQ>QSWoO}jS zz;uJ?LT3)$Xn9501I3!LQ2x1YKl^@WVJp#NqcLHjM1Ot<;a9GBleqpTRmGn>Qs&=) z)PUUg%gNvQeIW0X3Dp90~t2y~Q7-d(ZEj%?DLJHvW zDr4-g2p7WaH_+F2dd>@aX`F%O!(7^xfh`8Ylv3sn3*S~2fw=3x{eO1HD1dy$;n)0K zLZt-{L_#ydX5e{d`Tp@g(g5FWm}ZC1HqOuGpL3aD5=7-#@KII?(NSt-@-BPgzK^`u zuNJqFV%m~`5;0=`HDJp!n;rc~KAw*E+tc3UXgqVVR7q1;9TMU?rE;jo4D`ongKc;v z_U?>FwPMlKVUys|F0jV z3`c>qo9U58!V@l-6T~uf^mIf6v3V1hL;Znwo3dq6QI9Z@Dp1$DRf*odFh55mVEv}= zFr`c5$HNQP_e^_PdfNF_yAnIMYsNEV-du)sQC`W#- zs4y7xs3SNrLvH*mEJkJVeeIj#of^|BGE!79rm&*@dwb`Lky&);=;*-S(r?dY?4Fx>6ZJ&P-2NuzrS^F+MujOOj(Rq z-R-}(tIe0Y`}Vgf=YTB?F%NB+8qQQtEB)0c%}#8aYu$fuSQ60>556Lzq7-l|FjtAc zl{7%p1IJ-Qs-m~ww_0X|y^oIOx)ZgSGhzU?ZO@Hl(S6CQM4#RwEpMQ&EsE~p0lOd< zO@mR684$SzWWDvxe{OUH0u`%N!V_})Rj1?#5E!|9^2ysA&dSDS4fuqRzqOk$W= ztktWq3t&=Fz)%7A(&6!6c5FZJd7EnsD0gll)7j6tuVrUvgASPhln~HZ0mcBTRoSQ* zEtre72^@7YX$hmG{ISLwo@z%i=(c_iJy;Wsy)AhqmCDCY`fk!C4J zsiQgm;Q`^k4~Y%_mm_8voF$f_zJ3T)|9(OAfeRf2bGv)@p-`o|A002U+^u&jK~x zt96mT*IUv{FU1Gjc#fGn^~PoOIwy<3KsepT>Fwu-za1WbaQ=&<2a+5pJ(k)_?diQz z61yw$ZBvVzGFKtZ+4);pDa9H1}Ew4;6u*pYo$$r%@yYqQ*$g-1KI}cclfq!o#vv+7WZ- z3e3OmEwx!CB!~da4_aC(#b0=8=Jxif=PD=&U$9jmQdV})7LkeO4(lE!lwE2PS8R4l zIch_Cj=m|aBqh_r-X0eSkn6V=z0>z;h+{{UCpz?XfxM@Ylq4jstiCszPPtgZ12&r? zgDut|v4WHenjQ57@JHd~BqVff!H41t+yQS-&eT~m77hXE0EUc^m~{AV!$(qEui;dE zlj<561_3oIuw!*(KZXrBjf(9BbaZsS03WZBNMmXqXDHVp=?f={&wGYU_jI}$YI`l7 zydNhYf}ZL}qncpK{WsdZORD?{ZZ{%koURnR2a4{T2tdh3y#i}pex7YFON{}(xcxa7 zu_YQcH$exoqW(8I)`dBJcN_jyfZ31X=?Te?-0yzdO{8c>zj9=Ub`ZGOt*otGfs*FC zQQ-jaj&ADch&E_NT=qOh$a3Q*pBfD+NC=^M$7EK$yZ`qRt1JOcJ@QwN(TScdsy5=!}CFWrvR(Y4}>9ui=)E2*quGI}rvA8}=vW2tR` z1`d6IKPt@~S&O=L`|G_Ts(og&7Skl&qXIo|XG0xN;Zg?F$5EG#PS#9HOhGI%RgFhn z#6*p@{KP9mMM=JYqO=}GIFq?oB9|6$wn?;hVNk&X(`9m>EqERtp7iVqFBYNziHfh6 zPd2=Uz?ekLv%9u|B}PsgwiOWr4NX^_nSjX{f(JNbH|avnY2PQB14761kjXOw3oEM` zpzJnCt@{?r`eE>A09loFAL;;Qi;$RD2AJQ}t%g%Mu7zCg{x!jJ`kJm{$|FiH{C z%W@Yh+RiDFYhbduU0d!w3sb*~kjPq73z~CBhQl0^p?4=I{sQpelUi7?g@+bZI#2H| z`tw{11X#`uqMs3~p3YgGFHAZHWPU*;%Y2W(fX6#*Rn zL%>FEem;xv&Fl~o@RuyXy;}z!Y~b(faNRUU{=wS7p|CPKRSJCK2^4loT-MWDi+NQ5 zAB+z8ua(R>Fj^#yg4rP(SqR1A!2T92P}Bmo(juX~zdcEwVIBZ_i3orhqWQ{ygPG33 z2S%UqZ0fy5rJ6^RCSoP?@IArUOHh0Lf*7i{nGr6zrJ)>KZ?kdXM-H$0=Y07ah9vzi zYOd5rHRnXM5s#j6Hfz@MojirK?g-T;6G3^a7U3 zv`m?}jn6`}*~I%UI!JJ?6XTE`o(vuULQAwN!}YUU9o}j08Zf)s$ZVidc_HYs1$sxyS52;2KV>7MbpRi72!J%D z)RD)UT+dcG0`9suGYA9VDxn%fv*3!qnpwykn4xHRXi(s+%5L@LSI%nVz-o-hQ@1H4 z(~05h5z2(aOeL;QD`JF&!PR>2__6^9ZKG#_B>3nt<09wXRfF_|vs>3L0fERrmNUau zF{idw8{1qv5hBl2yVfrE$D8Am%jfB!@9Yz!v$JY{j;o4@fX3_oJ_HU4;GiHeAUz^g zCarrrT-Q_;vIx8@*b=-I;Nj%~fU(pB@87SUeP>~V^u@2{=mQJ;B}-1V6ebpxrE^va za-&Cc3a4{OMKJ)?)2k=P^Er#p!wdkufus*rH zvrmMF`rq3&q^jm5*Lu&m;CPlh5`d%*42bi!CFG~2wfu$u+v2`RB`PHL2&eBy5?LZ4 z5bgj!svd68${e$RPL2PC6gMh~d|>c5X+PoQJ`UhAziQunG(6sAQ1qfIl4L6aXwl>E zuNetYfv+2poCc|4m6DZ=9BW`f4{s8IsUK#CZ(t$~bLalg?v)XyV|#*5oFB>3`F|pW zgEJ6C1=~^2bMk{&g)|5&-qwc4@Pth@u1Ney0%cxlJvdpWk&pU_EnCdQ#Ce&S3cH|z z>*nT$kxZs+HT-jU`yaNn- zT$jK$Kdl$adylEzeyk+t_6%-=+ zvQs4KQmn>Ic@^NIvd<+O>eh+A?5GIK0SQrBr~DBtnHvK3T+*VkcMwpCG2bjr<}o@Z zSEeNv@;CDK%0AIQ%K4>&+QZ2cVzE|z^RHNor6hS~sL7F!KNX$idpaL@4nZ1PzBF@a ziHw|*&iPL)($={hFik6f;Jxg)-E=1Tt89;O>OPu6-8^fUVl2A;W+_7P;-t-OJ#Hn* z#$-f*EnAl2C5I6>IJhj)vBW5{jZDc2+{PQNYZHqT~wf1x*cLstxyZQ47DA zKa>A%4A}p0_zhUJ&adJgRIAYfDoIP_iz3o&5kBF7%O(qN(fj@|hJTlvK{p!~W7ncj zEuv)|;p(J-S7$^=SC@l}D~xwjD1xhM#`M#t!h1hzb>?x0Le(m=EM+zU7~jb`r*4~e zzzNjof#;1gkvX%kc3knJM303Ul?G@xfI=H-xk74Rr*0`nOKyZ@t>COAoK~M3D+-%W zwIU@_U>2UQWMMvK6*VVf)v+DQ0vJq9K0a)4y@D28UZ16j>L8)Jd*jDB^!mRU0Fl(D zI~}2hi?fw60B|DY?^0d~x56N=!q;grr+>*$4YqM{!2+mV*uZEX0XSvad1CbS=hdP) zexzJVy$z>82bV^P1tG5FQ`qO+@cWDRx+?l41YQ@bTN(u3V1D~n0Jw@}O6})wrG*sX zLVd|4cE&rZme^Cs_2y^G@6;MC#t~-3fFz;bi0v`)MX{n8H8N%wV74Fv8_o40AutZk z&YOS8`)_$*nyd$6gyU}g@iLg3uOMgSc@UQ1;PAhi+n_!&e2f!q=BW6ywvkShMmjx8?hpEt1VjRY zgA)64$co-tKd}KiZa`<9^M!SOy-;F;lSg8wf$= zS0|~`>W_9-0d68(o7N+P)E}!cN#ojcX5Dbi>|Y*$UOd>%+PrMj22nmrc2j{nJ> zDluXy(PE?e=uZ=2uI>aHj$UcdsnGk(H95^=0h^M`sS1h>5atw+_#XWEF)RD)#)dJq z$J|(K|K0A#*W)4|!Q02EdH6m5u9q{!s&5?wi2aR!UvKCc-s-gw&)^&o+q?LGep8H;&suJ^se4DSvB{4~q zEGlhtyVzD?K79C)os%P^H?^S?6A@QwJ;+3!Oqdh!BLZA%ERg3DI9bbsMOF z-L72AAXq%CWC6Vguw|DFh{q?W7V9yJEpXFv49K+e@}js6fN6yyN=Uwf(3>SlB5STu z0%1A|6&Z>s#KIy==FGmH;DuS~(R&n}ZDl%2E?4s(OcJ^)FU+njNKWb`xS?Py438*g z0oyfI!Ng*~8sMH~jWuJ2Jb%t`y6Jb2lB(+NIoG8auLs@Qw2EF=Di&Xu$NS;s8LZzo zf5>Q3u}B@4M^^6n9M(n;eiEECr(}8FwZsB>G!93=(sgFvGd+B8lJJ|*J0;}-OxUk` za_Ydee0{Uc(NkFo>dwj4m5`W7m3pOt-#&`q=kJe4Is8|MAac94z)$#|y#chI*KhnT zyknpyumyOG;>daRk9hrxyz=sf{T&H^c{Wh~VpU@3dUJr84efXC`S+_XVcFRK7B=`J z-0b7yz{eL&kYS!@?nXm8XKZD=EW0!T@Utwie&cDgJDUmYNC_O8CGf_uu zF%rbh^N#~oPB8JUASZ0kD!!P15<*Z5Lc-d8&)qM^6;>VGb_40(P6$ojEptvK=0_W1 zdi6Sr_N@j1KoBoxKWuQ;KB9ea$>C~}h~VQ~(kGAS`#-n~G&D4t4@RGCPWrVrV~|vC z@Z%6{lqBocM*(Izkaa)u{7l;I21NuMJWV}c!*6df0E4J}%qV}sYve}G8=A*=Zk&~4 ze-WYOwTxw136jLyR&IdUB^HLra5&zB=w?X}D}CR`psIy&YHtsoO#KB?HqaJM(sJ!P z#m0HQ1FXrJNtTXqD`%+)S4-DVEEq3)P@-XGoJA!*CCjURV%}c~m!cpdOHuo&9Fvxn zmfld5$0%p1on$^a4R{~N_uYWz^46~a9m-(~#5HH471olMI86dzrs_k+JOd929R#Hz ziD_3$I9_Ss04=|rj8FvVk$^6{4ow$g5;n^3m_T%Gx!dJw#HFw->sYTFdBW#k zPuya9YC!=N9<~9Ocf|rgoS8SwIV}Aa)Zcel=&!J_u#hn%`|gs0gh;R_$nLr!CT1c~ z_0t}WFopkxF9Ack$DSX#!8s2wEY>qH7zIXBY(_oNt2sp9XJ*O(*Zm<1IGLL#4Z~et z^h8JMV*k44eUelEov=}!NwRpU(p?~nW2pnz} zU06sCFCN|H@C6!KNr`+ljH|k}Q=tf)alF(>m|<-A_kjOAtl?NL1uz^;MK`I8g0QQ? zB{r=G$ju0;W6jZT?iAzLH}^A`3DDS;x+I2eW4&5d?ZCN;z@c<0i}+NA;M@BHW|`Y# zy@$9TsYB&=OzgG}Z%iKRvmi%7hx&-vP2&kq(0QwF7;y7?lJrAuYj;5Cqk5YRq7UAc zh5i?vWn&k;-kX4?rZw&AH#P>a&`3p6-@aRa3fIp>nATi8Rc2vhi;l};YXQ1AAjJaz z?_V^4mmpg<7kr4r3%ZUiPL0&^sftBNd4OF(_$!AyIN|TujvF!(Y`@%KW@}3{Vh#gX zUjU~pUm}9x!8yk$z{=r%nwO$ib_X`EsL)}To}d1C_n}QS0~03verbMEI!8Hn*bX!* zQ(}5s+U8o>ong&FxdaIin}!YIfL@+u>$zGbp`=LGQ0s^^U+TSu{!RB~%884mr4-cA zsxSHsPxpFH$&M{8Za%$-#x~c~&aSrX_t|wd&^4*05ro$}w;5zPeQCJR!`$+#>hlU* z``OJCavEsyEKn5GD>Afkw`r3SM-orGiowHmjz|*cMe-7L8o05cX>z9DbICo~lagt6 z`Q-f5ew+|P33(1UtM6xkvl{olS%%Gm#VlUm!ong0XsTQu%Vvb!pNHWvNs9^#3;F!^ zY#zo_%7E=j;&Aj5+xUl1!AncrfN6;Qzl81w_d^arfBZE=!_?$*ragno%C(o963Lcr z;^H}TJPid!cC`0^DClk>$(s7P)a9B#1DcGI4bYI-IhruLZiw%j`44@`)eGrr_|fjQ zauA9y0#oT{BV?$UAU`c0jbkv)vgzG;P#T3cb-nLd&<2v{E<24>By8jZ0TLSg`~SAW zv}D3sf3fa^ms)&0SLc>Jl&!30JJ^%4{TCLH1k20MQt)7hhKB6iF+#<@=Kc845#~IK zvGL76yvy*tOAD^?Z&Rx4(*W{s1IvoeCB$;hWt;uZS9i}mBpGLjqKbEeDw|Q%*Itb{ z?X*dmd7*6KTY%6Aa5bhjgSI0Y13$Ld0;>!M6hUWy`us12c?9@5_yvSG1Av564?hPF zkGGqff!{B86ho?Si>g@Y!*{a|;E{h`8TAbfTfbVRjXHc#ve=BvPo-KT87omDYBYD) z;KF8SIK)vYCy5}B~i)|iztgW#$vG5mmKl&iD|EOJyn;;;PV(o2gMH=wA0hm|4QR6A{^!j zD&-H6kx_Jtvk0oT&*KBoHiRa|<_$PUd z`3o<|HErS5Z(sD=#Boqdc!I?2o1lda6B`47idT5UXmhExh(*+#d ztV8SK(ugZ5@P@H)n+K-!cNX0SL#+|^FHC(Th z8jh|g6p=;~pL>bKiG*#Z0Ner@M2=N$VT`dGnHdys>>q+jdV6(k*__mrdvs?&yfsn{ z?MzK1V4B9e-sU?SnNNhcu{Xk%80~^>0pHSM?yluMoc~wab$&IqyxoNGhH|Mv1qsrm zh)Cyx^m-`@g7hXTQl)o@(veW4NmB@*0>Ow7kQREsR0$B8fV6nae%XQcW39{eox4YGyt2x4-}xR)O`66kFRN{L#HA?*_7=($aZ*w=k3ri z)r{ZIG_Yz+DR=;A6hH7iP!;)bAZd6XxA^%nwz_(4UV&1$Oz+c_2lnz^s?N(K*B^LS z+J51fHf+tAE$8qGG!2mm>nfM!@`c0O%V`U0Y;h)Y26xNlXoeO1f7ShNB>8xHl4dYG zs9Z{h+8NPurB?xX*_ys>eUw7Xjfz{xYg&t48RtnD=I1FaOj zK37Me%BVoHimi=JM{SQguC6jt)Y4f}ULFZliLnKLsk6YeBTk^{E!5LZoqq)acQFyT zc65gOpZod20J{GrjO7hqG_U$>3GE)DNdF8GW@uor-36R{AdWc;Tg~T;u8LYkkJLvS z8bYnI83$$41~$Mw&4ky54@f!ec zFyKvrO?t@ftpd2pOoTYRo#e$r73qk!w5qjf8C{$6kV=9d-reIS#Lwny&LvK71a%wN z-wtVUXY{}W zl@SlQgu2Y)vB=x2El-%sF?oQR`W8xAKQugZVBFX7C9EN9a7{{9wm37%KyDM*CXP2D zgnhzY_K|18{>Xr9ZvZO0_R|MLws^g=a*4Fu2Zbtw!*Jg{_Ui zR3m|qRON&CmmIJO;i$FHFXm;_bMyR^h}KBptuL1X!YoBQ%AyPdOERZTc4U6%g!(Q8 z*!+tgqqoWjeO(#4 zDO?KE1cH+N-5bb(tO4~B6JNgul*!(iM&$V;2pkUo&**>Rr**UcF&B5l_Tz+S%;q_2 zMf{J+UCH&q!%70n!TAg(BN=?XvE2w6I`{rQ-O_L$dRyDsJ(Z_U&zBt-HWXx5_!EGbs@PD{~2#=?2=WUdE_MP+L;MTzvw8&2P`MJbrDjY;D2lpoRdHw$1 zKQB)22PIKdn|`#lu}#IFKmr=f$7f%8GSy4h;^y-$As>wl4HekfGDF4rzRr~O>qvUp zKz{-^9rjMLE>G^q@rqu6yp+s}qEU6Fu};)C*v@%^QMhJ$q^0H5-sVE>Ea`9V7@SX9vb}u5Hr`Q2!?SIfU!@EPhNov8R?Fy#uRB%e8!m>TgIRLH4 zS+}sN@7_v3QmC}Flo{~uVP5-l)?ue=*{`6G(XF8UA~8eTS-S2qmhA~<)b*nvJj{9s zwf-P}(|+z}qsuZ>lXFAhb#VVrb9>2L7y}dY@=uon4U`Zd2}U9QjBny8op=(Y#7~ey zf%>e;$DHIU+j+-~%oFL>$*)K^F0R)%b_AGysF;eM6Ri%%8ZKR>NG;$C7x1`)p!Lxi z#(zIpZ{LC#zt2^aJRUdYX*lUGEl~AcsJckmnUz;f!?OnrH|Pi=2COV&5xMBjKgt$m zq_m2U$CR322_;WEU#?zC%uNqiyV+u2=EG&H=m)%yqs>e(*62L6_lQ&B$MW$fxBqSm zAkesOK+Fcd<~W_m26PqN2-I)5DQS!!+HmlA|LC{ha0mn4Yc&&U`tGFZHTgA4q5tsq z!06KBi_8_u?zOjfMZ}#!*t*o1U>Sh3TJ6tBy`*VIRCru92ueJy2)mphl(zNvcs-_C zq#vZqCu>ehYcSZ$r0)Jv#_|mgX}Dmu3zWpVevA*RZ?dz#^78Tu2@el%wkR_+FcaP} zd}KI0-|`A;UvAN>tD|$-+f$E^1{`)9QeM>Bq@Ymw=cP~{?g4T~)HaE9;UZjjVjbUi z7A;(cM+kn;G8ubW>*(yPV_`AxzI*9EKCGrRDWOI=B>nL&i1^uBHujksrwUFFlp8U` zcF3|cirgM^X5{Z*lZ}6$k58NQ7#9;%+w_-%nh!OePY0JrKM3si)wXEjVuKaZtaTSyEg>T3rh}F z0u{tld{F?`YG}cA4~C#qWITdA51KMfAzJ-#HnnJ@><}h+ES}at*6*?CiGzLqaHc6P zrPcDeIi0pB54-DKSZA+}y2-@VnDBcAu}s<0X2bF|+}P>g*d`?p}+Lcf3;@_rP zq6dps69z(@5FQ@e!vK%@X`${)z^$+l*A_7{GdFkn!hH+-v{2>Z{GX!HX}31A{;R!u zD$59}MMW!X>vZR85#Xp6V(gppRMDCwE;fpZHa=N#{H{FX_#prnywum@FP0TQ2TLD) zusTdK!8j(}@eU3S-aS1%^=AFa9wCo@`Sgh584;*?qz2wY+uGY_19c(cME54s@0ux6 z5U^Y|6jo155!bI_4Y+`Owk5-ad4-x!L;G!dm!{rDeB zXp|1=Dfa8vH%nSGx|IxlkKWZNmGyyCgXA6B%j{oA(njX7F)aE#NpPHIy%Ud_GV31<1xQ9$_n3H=JzD;P4}z9%wO8R7Bi8G+=TzN9Zc9 znESz;fw}{+urqMR_Y|Oyy9R&gXwSS!*1e21fjD>-yHPPyQGu|v+EPc{-?=(M_ zZh>e)c56O;FGPc~p~d~v^f{0vnym*|s2UiAU_{8!_Vcj>M7Jm2JlvEfYenX%+KyOr zdj?8Xe9II?n29_)lBT8w@h*hN^t%g_%Hx~hQ~p`8E# literal 0 HcmV?d00001 diff --git a/images/battery/0.png b/resources/icons/battery_00.png similarity index 100% rename from images/battery/0.png rename to resources/icons/battery_00.png diff --git a/images/battery/5.png b/resources/icons/battery_100.png similarity index 100% rename from images/battery/5.png rename to resources/icons/battery_100.png diff --git a/images/battery/1.png b/resources/icons/battery_20.png similarity index 100% rename from images/battery/1.png rename to resources/icons/battery_20.png diff --git a/images/battery/2.png b/resources/icons/battery_40.png similarity index 100% rename from images/battery/2.png rename to resources/icons/battery_40.png diff --git a/images/battery/3.png b/resources/icons/battery_60.png similarity index 100% rename from images/battery/3.png rename to resources/icons/battery_60.png diff --git a/images/battery/4.png b/resources/icons/battery_80.png similarity index 100% rename from images/battery/4.png rename to resources/icons/battery_80.png diff --git a/images/battery/unknown.png b/resources/icons/battery_unknown.png similarity index 100% rename from images/battery/unknown.png rename to resources/icons/battery_unknown.png diff --git a/resources/icons/light_00.png b/resources/icons/light_00.png new file mode 100644 index 0000000000000000000000000000000000000000..58f20dcc66ca8c23a85fa87068b580bea3685cc6 GIT binary patch literal 12121 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 literal 0 HcmV?d00001 diff --git a/images/light/5.png b/resources/icons/light_100.png similarity index 100% rename from images/light/5.png rename to resources/icons/light_100.png diff --git a/images/light/1.png b/resources/icons/light_20.png similarity index 100% rename from images/light/1.png rename to resources/icons/light_20.png diff --git a/images/light/2.png b/resources/icons/light_40.png similarity index 100% rename from images/light/2.png rename to resources/icons/light_40.png diff --git a/images/light/3.png b/resources/icons/light_60.png similarity index 100% rename from images/light/3.png rename to resources/icons/light_60.png diff --git a/images/light/4.png b/resources/icons/light_80.png similarity index 100% rename from images/light/4.png rename to resources/icons/light_80.png diff --git a/resources/icons/light_unknown.png b/resources/icons/light_unknown.png new file mode 100644 index 0000000000000000000000000000000000000000..77d0db90867d8e0208c260a0d5202f2c4f8b34d6 GIT binary patch literal 5547 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 Psvx9}v38lJ6ZU@qdjf#n literal 0 HcmV?d00001 diff --git a/solaar b/solaar index 2d96e6fb..6c32b727 100755 --- a/solaar +++ b/solaar @@ -4,6 +4,7 @@ cd `dirname "$0"` export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD/lib export PYTHONPATH=$PWD:$PWD/lib +export XDG_DATA_DIRS=$PWD/resources:$XDG_DATA_DIRS exec python -OO solaar.py "$@" -#exec python -OO -m profile -o $TMPDIR/profile.log solaar.py "$@" +# exec python -OO -m profile -o $TMPDIR/profile.log solaar.py "$@" diff --git a/solaar.py b/solaar.py index 51d86ca9..2ed7aeab 100644 --- a/solaar.py +++ b/solaar.py @@ -7,7 +7,6 @@ __version__ = '0.4' # import logging -import os.path if __name__ == '__main__': @@ -20,8 +19,5 @@ if __name__ == '__main__': log_level = logging.root.level - 10 * args.verbose logging.basicConfig(level=log_level if log_level > 0 else 1) - images_path = os.path.join(__file__, '..', 'images') - images_path = os.path.abspath(os.path.normpath(images_path)) - import app - app.run(images_path) + app.run()