From da6dbb45328f956e6ac800130908bd46a84316df Mon Sep 17 00:00:00 2001 From: mister-teddy Date: Fri, 30 Oct 2026 00:16:35 +0100 Subject: [PATCH 01/10] feat: show the desktop on an external display with the phone as a trackpad --- README.md | 4 + patches/winit/src/platform/android.rs | 6 + .../winit/src/platform_impl/android/mod.rs | 2 +- src/android/accessibility.rs | 20 +- src/android/app/run.rs | 140 +++++++-- src/android/backend/wayland/compositor.rs | 11 +- .../backend/wayland/event_centralizer.rs | 156 ++++++++-- src/android/backend/wayland/event_handler.rs | 223 ++++++++++++-- src/android/backend/wayland/mod.rs | 28 +- src/android/backend/wayland/winit_backend.rs | 214 +++++++++++-- src/android/dex/README.md | 2 +- src/android/dex/classes.dex | Bin 6864 -> 22172 bytes src/android/external_display.rs | 287 ++++++++++++++++++ .../java/app/polarbear/ExternalDisplay.java | 209 +++++++++++++ .../java/app/polarbear/TrackpadControls.java | 276 +++++++++++++++++ src/android/main.rs | 2 + src/android/proguard-rules.pro | 11 + src/android/proot/setup.rs | 3 + src/lib.rs | 1 + 19 files changed, 1487 insertions(+), 108 deletions(-) create mode 100644 src/android/external_display.rs create mode 100644 src/android/java/app/polarbear/ExternalDisplay.java create mode 100644 src/android/java/app/polarbear/TrackpadControls.java diff --git a/README.md b/README.md index ecb6810..3dd8064 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ Wayland compositor in the Android NDK plus proot) and replaces what runs on it. ideally with a keyboard and mouse. It brings a desktop to Android; it does not turn the desktop into a phone UI. +On a phone, connect a monitor (USB-C to HDMI, a dock, or a wireless display): the desktop moves +to it and the phone becomes a trackpad, with buttons to turn the trackpad and to type with the +Android keyboard. + ## How it works 1. The APK carries an elementary OS 8 root filesystem as a ~190 MB xz archive diff --git a/patches/winit/src/platform/android.rs b/patches/winit/src/platform/android.rs index 65d6717..f1b8102 100644 --- a/patches/winit/src/platform/android.rs +++ b/patches/winit/src/platform/android.rs @@ -186,3 +186,9 @@ pub mod activity { #[doc(hidden)] pub struct AndroidApp; } + +/// The physical key winit reports for an Android `KeyEvent` key code. +#[cfg(android_platform)] +pub fn physical_key(keycode: u32) -> crate::keyboard::PhysicalKey { + crate::platform_impl::keycodes::to_physical_key(keycode.into()) +} diff --git a/patches/winit/src/platform_impl/android/mod.rs b/patches/winit/src/platform_impl/android/mod.rs index be304f3..a8a33c6 100644 --- a/patches/winit/src/platform_impl/android/mod.rs +++ b/patches/winit/src/platform_impl/android/mod.rs @@ -27,7 +27,7 @@ use crate::window::{ WindowButtons, WindowLevel, }; -mod keycodes; +pub(crate) mod keycodes; pub(crate) use crate::cursor::{ NoCustomCursor as PlatformCustomCursor, NoCustomCursor as PlatformCustomCursorSource, diff --git a/src/android/accessibility.rs b/src/android/accessibility.rs index 25b02a8..5481a5d 100644 --- a/src/android/accessibility.rs +++ b/src/android/accessibility.rs @@ -17,6 +17,12 @@ pub enum AppUserEvent { AccessibilityInputReady, /// The first-run install finished; switch from the progress page to the desktop. SetupFinished, + /// An external monitor's surface appeared, changed or went away. + ExternalDisplayChanged, + /// A mouse (or touch) on the external monitor moved, clicked or scrolled. + ExternalPointer, + /// The trackpad was turned a quarter. + TrackpadRotated, } #[derive(Clone, Copy, Debug)] @@ -147,21 +153,23 @@ fn enqueue_key_event(action: jint, key_code: jint, scan_code: jint, event_time_m _ => return false, }; - if scan_code <= 0 { + if scan_code <= 0 || !bridge().lock().unwrap().runtime_active { return false; } + inject_key(scan_code as u32, state, event_time_ms.max(0) as u64) +} + +/// Type a key into the desktop. +pub fn inject_key(scancode: u32, state: ElementState, event_time_ms: u64) -> bool { let mut bridge = bridge() .lock() .expect("Failed to lock accessibility bridge"); - if !bridge.runtime_active { - return false; - } bridge.pending_events.push_back(AccessibilityKeyEvent { - scancode: scan_code as u32, + scancode, state, - event_time_ms: event_time_ms.max(0) as u64, + event_time_ms, }); let proxy = bridge.proxy.clone(); diff --git a/src/android/app/run.rs b/src/android/app/run.rs index 213eec1..5a31750 100644 --- a/src/android/app/run.rs +++ b/src/android/app/run.rs @@ -1,4 +1,6 @@ +use std::sync::Arc; use std::thread; +use std::time::{Duration, Instant}; use super::build::{PolarBearApp, PolarBearBackend}; use crate::android::{ @@ -6,12 +8,12 @@ use crate::android::{ backend::{ pipewire_standalone_aaudio, wayland::{ - bind, centralize, centralize_injected_keyboard, handle, - write_guest_output_state, - CentralizedEvent, State, + bind, centralize, centralize_injected_keyboard, handle, on_external_pointer, + paint_trackpad, write_guest_output_state, CentralizedEvent, State, WaylandBackend, }, webview::ErrorVariant, }, + external_display, proot::{launch::launch, setup::build_wayland_backend}, utils::{ ndk::{self, run_in_jvm}, @@ -28,16 +30,22 @@ use winit::event::WindowEvent; use winit::event_loop::{ActiveEventLoop, ControlFlow}; use winit::window::WindowId; -fn configure_output(backend: &mut crate::android::backend::wayland::WaylandBackend) { +fn configure_output(backend: &mut WaylandBackend) { let Some(winit) = backend.graphic_renderer.as_ref() else { return; }; - let window_size = winit.window_size(); + let window_size = winit.output_size(); let size = (window_size.w, window_size.h); - // Not `winit.scale_factor()`: that reads `AConfiguration`, which still reports the 160 dpi - // default on the first launch and only becomes accurate after a configuration change. - let guest_scale_factor = ndk::scale_factor(&backend.android_app); + let (guest_scale_factor, refresh_millihz) = match winit.external_surface() { + Some(surface) => ( + (surface.density_dpi as f64 / 160.0).max(1.0), + surface.refresh_millihz, + ), + // Not `winit.scale_factor()`: that reads `AConfiguration`, which still reports the 160 + // dpi default on the first launch and only becomes accurate after a configuration change. + None => (ndk::scale_factor(&backend.android_app), 60000), + }; backend.guest_scale_factor = guest_scale_factor; backend.compositor.state.size = size.into(); @@ -65,7 +73,7 @@ fn configure_output(backend: &mut crate::android::backend::wayland::WaylandBacke output.change_current_state( Some(Mode { size: size.into(), - refresh: 60000, + refresh: refresh_millihz, }), Some(Transform::Normal), Some(Scale::Integer(1)), @@ -80,6 +88,44 @@ fn configure_output(backend: &mut crate::android::backend::wayland::WaylandBacke } } +/// Draw to the external monitor if one is connected, otherwise back to the phone's screen. +fn apply_external_display(backend: &mut WaylandBackend) { + let Some(winit) = backend.graphic_renderer.as_mut() else { + return; + }; + let surface = external_display::surface(); + let unchanged = match (&surface, winit.external_surface()) { + (Some(new), Some(current)) => Arc::ptr_eq(new, current), + (None, None) => true, + _ => false, + }; + if unchanged { + return; + } + let attached = match surface { + Some(surface) => match winit.attach_external(surface) { + Ok(()) => true, + Err(error) => { + log::error!("{error}"); + false + } + }, + None => false, + }; + if !attached { + winit.detach_external(); + } + external_display::set_in_use(attached); + + backend.reset_touch_state(); + configure_output(backend); + if attached { + let size = backend.compositor.state.size; + backend.cursor_position = (size.w as f64 / 2.0, size.h as f64 / 2.0).into(); + paint_trackpad(backend); + } +} + fn configure_toplevel(surface: &ToplevelSurface, width: i32, height: i32) { surface.with_pending_state(|state| { state.size.replace((width, height).into()); @@ -130,12 +176,20 @@ impl ApplicationHandler for PolarBearApp { return; } } - } else { - log::info!("Ignoring redundant resume while renderer is already active"); + } else if let Some(winit) = backend.graphic_renderer.as_mut() { + // Back from the background, where only the external display was drawn to. + if let Err(error) = winit.resume_window() { + log::error!("Failed to draw to the window again on resume: {error}"); + } } + apply_external_display(backend); configure_output(backend); + if backend.is_trackpad() { + paint_trackpad(backend); + } accessibility::set_runtime_active(true); + run_in_jvm(external_display::start, self.frontend.android_app.clone()); if let Some(winit) = backend.graphic_renderer.as_ref() { winit.window().request_redraw(); @@ -170,14 +224,45 @@ impl ApplicationHandler for PolarBearApp { return; }; - for event in accessibility::drain_pending_events() { - let event = centralize_injected_keyboard( - event.scancode, - event.state, - event.event_time_ms, - backend, - ); - handle(event, backend, event_loop); + match event { + AppUserEvent::ExternalDisplayChanged => { + apply_external_display(backend); + handle(CentralizedEvent::Redraw, backend, event_loop); + } + AppUserEvent::ExternalPointer => { + for event in external_display::drain_pointer_events() { + on_external_pointer(backend, event); + } + } + AppUserEvent::TrackpadRotated => { + if backend.is_trackpad() { + paint_trackpad(backend); + } + } + _ => { + for event in accessibility::drain_pending_events() { + let event = centralize_injected_keyboard( + event.scancode, + event.state, + event.event_time_ms, + backend, + ); + handle(event, backend, event_loop); + } + } + } + } + + fn about_to_wait(&mut self, event_loop: &ActiveEventLoop) { + // In the background the window no longer asks for redraws, but the desktop is still on + // the external display. + if let PolarBearBackend::Wayland(backend) = &mut self.backend { + if backend.is_trackpad() && !backend.window_visible() { + handle(CentralizedEvent::Redraw, backend, event_loop); + event_loop.set_control_flow(ControlFlow::WaitUntil( + Instant::now() + Duration::from_millis(16), + )); + } } } @@ -208,10 +293,25 @@ impl ApplicationHandler for PolarBearApp { event_loop.set_control_flow(ControlFlow::Wait); if let PolarBearBackend::Wayland(backend) = &mut self.backend { - backend.graphic_renderer = None; backend.key_counter = 0; backend.reset_touch_state(); backend.pointer_pressed = false; + + if backend.is_trackpad() { + // The monitor stays a desktop display, for a mouse and keyboard on it. + if let Some(winit) = backend.graphic_renderer.as_mut() { + winit.suspend_window(); + } + run_in_jvm( + external_display::background, + self.frontend.android_app.clone(), + ); + return; + } + + backend.graphic_renderer = None; + external_display::set_in_use(false); + run_in_jvm(external_display::stop, self.frontend.android_app.clone()); // Kill the standalone-client PipeWire/AAudio backend if it was started. pipewire_standalone_aaudio::shutdown(); } diff --git a/src/android/backend/wayland/compositor.rs b/src/android/backend/wayland/compositor.rs index e3d3f24..ec02796 100644 --- a/src/android/backend/wayland/compositor.rs +++ b/src/android/backend/wayland/compositor.rs @@ -3,7 +3,7 @@ use smithay::{ backend::renderer::utils::on_commit_buffer_handler, delegate_compositor, delegate_data_device, delegate_output, delegate_seat, delegate_shm, delegate_xdg_shell, - input::{self, keyboard::KeyboardHandle, touch::TouchHandle, Seat, SeatHandler, SeatState}, + input::{keyboard::KeyboardHandle, touch::TouchHandle, Seat, SeatHandler, SeatState}, output::Output, reexports::{ wayland_protocols::xdg::shell::server::xdg_toplevel, @@ -30,7 +30,7 @@ use smithay::{ }, }; use smithay::{ - input::pointer::PointerHandle, + input::pointer::{CursorImageStatus, PointerHandle}, reexports::wayland_server::{ backend::{ClientData, ClientId, DisconnectReason, GlobalId}, protocol::{wl_buffer, wl_surface::WlSurface}, @@ -60,6 +60,8 @@ pub struct State { pub data_device_state: DataDeviceState, pub seat_state: SeatState, pub size: Size, + /// What the client wants the cursor to look like. + pub cursor_image: CursorImageStatus, } impl BufferHandler for State { @@ -142,7 +144,9 @@ impl SeatHandler for State { } fn focus_changed(&mut self, _seat: &Seat, _focused: Option<&WlSurface>) {} - fn cursor_image(&mut self, _seat: &Seat, _image: input::pointer::CursorImageStatus) {} + fn cursor_image(&mut self, _seat: &Seat, image: CursorImageStatus) { + self.cursor_image = image; + } } pub fn send_frames_surface_tree(surface: &WlSurface, time: u32) { @@ -215,6 +219,7 @@ impl Compositor { data_device_state: DataDeviceState::new::(&dh), seat_state, size: (1920, 1080).into(), + cursor_image: CursorImageStatus::default_named(), }; Ok(Compositor { diff --git a/src/android/backend/wayland/event_centralizer.rs b/src/android/backend/wayland/event_centralizer.rs index 4441147..449c7cb 100644 --- a/src/android/backend/wayland/event_centralizer.rs +++ b/src/android/backend/wayland/event_centralizer.rs @@ -7,7 +7,7 @@ use crate::android::backend::wayland::{ keymap::physicalkey_to_scancode, TouchMode, WaylandBackend, }; -use crate::android::utils::ndk; +use crate::android::{external_display, utils::ndk}; use smithay::backend::input::InputEvent; use smithay::utils::{Physical, Size}; use winit::dpi::PhysicalPosition; @@ -35,6 +35,18 @@ pub enum CentralizedEvent { /// A redraw was requested Redraw, + /// The trackpad moved the cursor by this many phone pixels. + TrackpadMotion { dx: f64, dy: f64, time: u64 }, + + /// The last finger left the trackpad. + TrackpadUp { + /// What the gesture had been resolved to. + mode: TouchMode, + /// Most fingers down at once during the gesture. + fingers: usize, + time: u64, + }, + /// TODO: Support these events Unsupported, } @@ -136,6 +148,9 @@ pub fn centralize(event: WindowEvent, backend: &mut WaylandBackend) -> Centraliz }; CentralizedEvent::Input(event) } + WindowEvent::Touch(touch) if backend.is_trackpad() => { + centralize_trackpad(touch, time, backend) + } WindowEvent::Touch(Touch { phase: TouchPhase::Started, location, @@ -186,29 +201,10 @@ pub fn centralize(event: WindowEvent, backend: &mut WaylandBackend) -> Centraliz match backend.touch_mode { // Still deciding between a tap, a scroll and a long press: don't move the // cursor yet, or a scroll would drag it along. - TouchMode::Undecided | TouchMode::LongPress => CentralizedEvent::Unsupported, - TouchMode::Scroll => { - // Scroll by the centroid delta, which is the finger itself when only one - // is down. Positive axis values scroll the view down, so the raw delta - // (negated once more in `WinitMouseWheelEvent::amount`) makes the content - // follow the finger the way Android does. - let new_centroid = centroid(&backend.touch_points); - let last = backend.scroll_centroid.replace(new_centroid); - let Some(last) = last else { - return CentralizedEvent::Unsupported; - }; - let dx = new_centroid.x - last.x; - let dy = new_centroid.y - last.y; - if dx == 0.0 && dy == 0.0 { - return CentralizedEvent::Unsupported; - } - CentralizedEvent::Input(InputEvent::PointerAxis { - event: WinitMouseWheelEvent { - time, - delta: MouseScrollDelta::PixelDelta(PhysicalPosition { x: dx, y: dy }), - }, - }) + TouchMode::Undecided | TouchMode::LongPress | TouchMode::Move => { + CentralizedEvent::Unsupported } + TouchMode::Scroll => scroll(backend, time), TouchMode::Drag => CentralizedEvent::Input(InputEvent::TouchMotion { event: WinitTouchMovedEvent { time, @@ -270,6 +266,120 @@ pub fn centralize(event: WindowEvent, backend: &mut WaylandBackend) -> Centraliz }; } +/// Scroll by the centroid delta, which is the finger itself when only one is down. Positive +/// axis values scroll the view down, so the raw delta (negated once more in +/// `WinitMouseWheelEvent::amount`) makes the content follow the finger the way Android does. +fn scroll(backend: &mut WaylandBackend, time: u64) -> CentralizedEvent { + let new_centroid = centroid(&backend.touch_points); + let last = backend.scroll_centroid.replace(new_centroid); + let Some(last) = last else { + return CentralizedEvent::Unsupported; + }; + let dx = new_centroid.x - last.x; + let dy = new_centroid.y - last.y; + if dx == 0.0 && dy == 0.0 { + return CentralizedEvent::Unsupported; + } + CentralizedEvent::Input(InputEvent::PointerAxis { + event: WinitMouseWheelEvent { + time, + delta: MouseScrollDelta::PixelDelta(PhysicalPosition { x: dx, y: dy }), + }, + }) +} + +/// The phone as a trackpad for the external monitor: one finger moves the cursor, taps click +/// (two fingers for a right click), two fingers scroll, and a long press starts a drag. +fn centralize_trackpad(touch: Touch, time: u64, backend: &mut WaylandBackend) -> CentralizedEvent { + let Touch { + phase, + location, + id, + .. + } = touch; + // Only distances and deltas matter from here on, so turning about the origin is enough. + let location = match external_display::trackpad_quarter_turns() { + 1 => PhysicalPosition::new(-location.y, location.x), + 2 => PhysicalPosition::new(-location.x, -location.y), + 3 => PhysicalPosition::new(location.y, -location.x), + _ => location, + }; + match phase { + TouchPhase::Started => { + backend.touch_points.insert(id, location); + backend.touch_fingers = backend.touch_fingers.max(backend.touch_points.len()); + backend.scroll_centroid = Some(centroid(&backend.touch_points)); + if backend.touch_points.len() == 1 { + backend.touch_mode = TouchMode::Undecided; + backend.touch_down_position = Some(location); + backend.touch_down_time = Some(time); + } else if backend.touch_mode == TouchMode::LongPress { + // Could still be a two-finger tap, until the fingers move together. + backend.touch_mode = TouchMode::Undecided; + } + CentralizedEvent::Unsupported + } + TouchPhase::Moved => { + let last = backend.touch_points.insert(id, location); + + if backend.touch_points.len() >= 2 { + if backend.touch_mode != TouchMode::Scroll { + let Some(anchor) = backend.scroll_centroid else { + return CentralizedEvent::Unsupported; + }; + let now = centroid(&backend.touch_points); + let (dx, dy) = (now.x - anchor.x, now.y - anchor.y); + if dx * dx + dy * dy <= backend.touch_slop_px * backend.touch_slop_px { + return CentralizedEvent::Unsupported; + } + backend.touch_mode = TouchMode::Scroll; + backend.scroll_centroid = Some(centroid(&backend.touch_points)); + } + return scroll(backend, time); + } + + let past_slop = travelled_past_slop(backend, location); + match backend.touch_mode { + TouchMode::Undecided if past_slop => backend.touch_mode = TouchMode::Move, + TouchMode::LongPress if past_slop => backend.touch_mode = TouchMode::Drag, + TouchMode::Scroll => return scroll(backend, time), + _ => {} + } + match (backend.touch_mode, last) { + (TouchMode::Move | TouchMode::Drag, Some(last)) => { + CentralizedEvent::TrackpadMotion { + dx: location.x - last.x, + dy: location.y - last.y, + time, + } + } + _ => CentralizedEvent::Unsupported, + } + } + TouchPhase::Ended | TouchPhase::Cancelled => { + backend.touch_points.remove(&id); + if !backend.touch_points.is_empty() { + backend.scroll_centroid = Some(centroid(&backend.touch_points)); + return CentralizedEvent::Unsupported; + } + + let mode = backend.touch_mode; + let fingers = backend.touch_fingers; + backend.reset_touch_state(); + if phase == TouchPhase::Cancelled { + return CentralizedEvent::Input(InputEvent::TouchCancel { + event: WinitTouchCancelledEvent { time, id }, + }); + } + CentralizedEvent::TrackpadUp { + mode, + fingers, + time, + } + } + } +} + /// Normalize a window-relative pixel position into the 0..1 range the input backend expects. fn relative_position( backend: &WaylandBackend, diff --git a/src/android/backend/wayland/event_handler.rs b/src/android/backend/wayland/event_handler.rs index e6eabb8..247632c 100644 --- a/src/android/backend/wayland/event_handler.rs +++ b/src/android/backend/wayland/event_handler.rs @@ -1,22 +1,25 @@ use crate::android::{ accessibility, + external_display::{self, PointerEvent}, backend::wayland::{ compositor::{send_frames_surface_tree, ClientState, State}, write_guest_output_state, CentralizedEvent, TouchMode, WaylandBackend, }, }; -use smithay::backend::input::ButtonState; +use smithay::backend::input::{AxisSource, ButtonState}; use smithay::backend::renderer::element::surface::{ render_elements_from_surface_tree, WaylandSurfaceRenderElement, }; -use smithay::backend::renderer::element::Kind; +use smithay::backend::renderer::element::solid::SolidColorRenderElement; +use smithay::backend::renderer::element::{render_elements, Id, Kind}; use smithay::backend::renderer::gles::GlesRenderer; -use smithay::backend::renderer::utils::draw_render_elements; +use smithay::backend::renderer::utils::{draw_render_elements, CommitCounter}; use smithay::backend::renderer::{Color32F, Frame, Renderer}; use smithay::input::keyboard::FilterResult; -use smithay::input::pointer; +use smithay::input::pointer::{self, CursorImageStatus, CursorImageSurfaceData}; use smithay::reexports::wayland_server::protocol::wl_pointer::ButtonState as WlButtonState; use smithay::utils::{Point, Rectangle, Transform, SERIAL_COUNTER}; +use smithay::wayland::compositor::with_states; use smithay::wayland::shell::xdg::ToplevelSurface; use smithay::{ backend::input::{ @@ -32,6 +35,17 @@ use winit::event_loop::{ActiveEventLoop, ControlFlow}; const BTN_LEFT: u32 = 0x110; /// Linux input event code for the right mouse button (`BTN_RIGHT`). const BTN_RIGHT: u32 = 0x111; +/// Linux input event code for the middle mouse button (`BTN_MIDDLE`). +const BTN_MIDDLE: u32 = 0x112; +/// External display pixels the cursor moves per phone pixel the finger moves. +const TRACKPAD_SPEED: f64 = 1.5; +/// What the phone shows while it is a trackpad. +const TRACKPAD_COLOR: Color32F = Color32F::new(0.08, 0.08, 0.08, 1.0); +const TRACKPAD_GRID_COLOR: Color32F = Color32F::new(0.16, 0.16, 0.16, 1.0); +/// Marks the trackpad's top edge, which follows the rotate button. +const TRACKPAD_UP_COLOR: Color32F = Color32F::new(0.24, 0.52, 0.94, 1.0); +/// Pixels a wheel notch scrolls, as libinput reports for a mouse wheel. +const WHEEL_STEP: f64 = 15.0; /** * As we currently use Xwayland, there is only 1 surface @@ -159,6 +173,9 @@ fn poll_long_press(backend: &mut WaylandBackend) { } backend.touch_mode = TouchMode::LongPress; + if backend.is_trackpad() { + return; + } // Anchor the pointer where the finger landed, so a drag selects from there. emit_pointer_motion( &mut backend.compositor, @@ -268,7 +285,7 @@ pub fn handle(event: CentralizedEvent, backend: &mut WaylandBackend, event_loop: time, ), // A scroll consumed the gesture; nothing to click. - TouchMode::Scroll | TouchMode::Drag => {} + TouchMode::Scroll | TouchMode::Drag | TouchMode::Move => {} } } } @@ -376,6 +393,45 @@ pub fn handle(event: CentralizedEvent, backend: &mut WaylandBackend, event_loop: } _ => {} }, + CentralizedEvent::TrackpadMotion { dx, dy, time } => { + if backend.touch_mode == TouchMode::Drag && !backend.pointer_pressed { + emit_pointer_press(&mut backend.compositor, BTN_LEFT, time as u32); + backend.pointer_pressed = true; + } + let size = backend.compositor.state.size; + let cursor = &mut backend.cursor_position; + cursor.x = (cursor.x + dx * TRACKPAD_SPEED).clamp(0.0, (size.w - 1).max(0) as f64); + cursor.y = (cursor.y + dy * TRACKPAD_SPEED).clamp(0.0, (size.h - 1).max(0) as f64); + let cursor = backend.cursor_position; + emit_pointer_motion(&mut backend.compositor, cursor.x, cursor.y, time as u32); + } + CentralizedEvent::TrackpadUp { + mode, + fingers, + time, + } => { + let cursor = backend.cursor_position; + if backend.pointer_pressed { + emit_pointer_release(&mut backend.compositor, BTN_LEFT, time as u32); + backend.pointer_pressed = false; + return; + } + let button = match (mode, fingers) { + (TouchMode::Undecided, 1) => BTN_LEFT, + (TouchMode::Undecided, 2) | (TouchMode::LongPress, 1) => BTN_RIGHT, + (TouchMode::Undecided, _) => BTN_MIDDLE, + _ => return, + }; + emit_pointer_click( + &mut backend.compositor, + button, + cursor.x, + cursor.y, + time as u32, + ); + } + // The desktop is on the external display, so the phone's own window doesn't size it. + CentralizedEvent::Resized { .. } if backend.is_trackpad() => paint_trackpad(backend), CentralizedEvent::Resized { size, guest_scale_factor, @@ -405,13 +461,104 @@ pub fn handle(event: CentralizedEvent, backend: &mut WaylandBackend, event_loop: } } +/// Show the phone's screen as a trackpad: a grid, with its top edge marked. +pub fn paint_trackpad(backend: &mut WaylandBackend) { + let Some(winit) = backend.graphic_renderer.as_mut() else { + return; + }; + let size = winit.window_size(); + if size.w <= 0 || size.h <= 0 { + return; + } + let spacing = (size.w.min(size.h) / 8).max(1); + let line = (spacing / 48).max(2); + let grid = (1..) + .map(|i| i * spacing) + .take_while(|x| *x < size.w) + .map(|x| Rectangle::new((x, 0).into(), (line, size.h).into())) + .chain( + (1..) + .map(|i| i * spacing) + .take_while(|y| *y < size.h) + .map(|y| Rectangle::new((0, y).into(), (size.w, line).into())), + ) + .collect(); + let bar = line * 4; + let up = match external_display::trackpad_quarter_turns() { + 1 => Rectangle::new((0, 0).into(), (bar, size.h).into()), + 2 => Rectangle::new((0, size.h - bar).into(), (size.w, bar).into()), + 3 => Rectangle::new((size.w - bar, 0).into(), (bar, size.h).into()), + _ => Rectangle::new((0, 0).into(), (size.w, bar).into()), + }; + let layers = [ + (TRACKPAD_COLOR, vec![Rectangle::from_size(size)]), + (TRACKPAD_GRID_COLOR, grid), + (TRACKPAD_UP_COLOR, vec![up]), + ]; + if let Err(error) = winit.paint_window(&layers) { + log::warn!("Failed to paint the trackpad: {error}"); + } +} + +/// A mouse on the external display: it points where it is, and its buttons and wheel go +/// straight to the desktop. +pub fn on_external_pointer(backend: &mut WaylandBackend, event: PointerEvent) { + let time = event.time_ms as u32; + let size = backend.compositor.state.size; + backend.cursor_position = ( + event.x.clamp(0.0, (size.w - 1).max(0) as f64), + event.y.clamp(0.0, (size.h - 1).max(0) as f64), + ) + .into(); + let cursor = backend.cursor_position; + emit_pointer_motion(&mut backend.compositor, cursor.x, cursor.y, time); + + // `MotionEvent.BUTTON_PRIMARY`, `BUTTON_SECONDARY` and `BUTTON_TERTIARY`. + for (mask, button) in [(1, BTN_LEFT), (2, BTN_RIGHT), (4, BTN_MIDDLE)] { + let was = backend.external_buttons & mask != 0; + let is = event.buttons & mask != 0; + if is && !was { + emit_pointer_press(&mut backend.compositor, button, time); + } else if was && !is { + emit_pointer_release(&mut backend.compositor, button, time); + } + } + backend.external_buttons = event.buttons; + + if event.scroll_x != 0.0 || event.scroll_y != 0.0 { + // Android scrolls up and left with positive values, Wayland down and right. + let mut frame = pointer::AxisFrame::new(time).source(AxisSource::Wheel); + if event.scroll_x != 0.0 { + frame = frame + .value(Axis::Horizontal, event.scroll_x * WHEEL_STEP) + .v120(Axis::Horizontal, (event.scroll_x * 120.0) as i32); + } + if event.scroll_y != 0.0 { + frame = frame + .value(Axis::Vertical, -event.scroll_y * WHEEL_STEP) + .v120(Axis::Vertical, (-event.scroll_y * 120.0) as i32); + } + let compositor = &mut backend.compositor; + let pointer = compositor.pointer.clone(); + pointer.axis(&mut compositor.state, frame); + pointer.frame(&mut compositor.state); + } +} + +render_elements! { + SurfaceElement<=GlesRenderer>; + Surface=WaylandSurfaceRenderElement, + Solid=SolidColorRenderElement, +} + fn redraw(backend: &mut WaylandBackend) -> Result<(), String> { let Some(winit) = backend.graphic_renderer.as_mut() else { return Ok(()); }; - let size = winit.window_size(); + let size = winit.output_size(); let damage = Rectangle::from_size(size); + let trackpad = winit.external_surface().is_some(); { let (renderer, mut framebuffer) = winit .bind() @@ -419,13 +566,48 @@ fn redraw(backend: &mut WaylandBackend) -> Result<(), String> { let compositor = &mut backend.compositor; - let elements = compositor - .state - .xdg_shell_state - .toplevel_surfaces() - .iter() - .flat_map(|surface| { - render_elements_from_surface_tree( + // Elements are drawn front to back, so the cursor goes first. + let mut elements = Vec::new(); + if trackpad { + let position = backend.cursor_position.to_physical(1.0).to_i32_round(); + match &compositor.state.cursor_image { + CursorImageStatus::Surface(surface) => { + let hotspot = with_states(surface, |states| { + states + .data_map + .get::() + .map(|data| data.lock().unwrap().hotspot) + }) + .unwrap_or_default(); + elements.extend( + render_elements_from_surface_tree::<_, WaylandSurfaceRenderElement<_>>( + renderer, + surface, + position - hotspot.to_physical(1), + 1.0, + 1.0, + Kind::Cursor, + ) + .into_iter() + .map(SurfaceElement::Surface), + ); + } + // The client didn't provide an image; a small square at least shows where it is. + CursorImageStatus::Named(_) => { + elements.push(SurfaceElement::Solid(SolidColorRenderElement::new( + Id::new(), + Rectangle::new(position, (8, 8).into()), + CommitCounter::default(), + Color32F::new(1.0, 1.0, 1.0, 1.0), + Kind::Cursor, + ))); + } + CursorImageStatus::Hidden => {} + } + } + for surface in compositor.state.xdg_shell_state.toplevel_surfaces() { + elements.extend( + render_elements_from_surface_tree::<_, WaylandSurfaceRenderElement<_>>( renderer, surface.wl_surface(), (0, 0), @@ -433,8 +615,10 @@ fn redraw(backend: &mut WaylandBackend) -> Result<(), String> { 1.0, Kind::Unspecified, ) - }) - .collect::>>(); + .into_iter() + .map(SurfaceElement::Surface), + ); + } let mut frame = renderer .render(&mut framebuffer, size, Transform::Flipped180) @@ -449,11 +633,12 @@ fn redraw(backend: &mut WaylandBackend) -> Result<(), String> { .finish() .map_err(|error| format!("Failed to finish frame: {error:?}"))?; + let time = compositor.start_time.elapsed().as_millis() as u32; for surface in compositor.state.xdg_shell_state.toplevel_surfaces() { - send_frames_surface_tree( - surface.wl_surface(), - compositor.start_time.elapsed().as_millis() as u32, - ); + send_frames_surface_tree(surface.wl_surface(), time); + } + if let CursorImageStatus::Surface(surface) = &compositor.state.cursor_image { + send_frames_surface_tree(surface, time); } match compositor.listener.accept() { diff --git a/src/android/backend/wayland/mod.rs b/src/android/backend/wayland/mod.rs index c356405..d222933 100644 --- a/src/android/backend/wayland/mod.rs +++ b/src/android/backend/wayland/mod.rs @@ -7,16 +7,17 @@ mod keymap; mod output_state; mod winit_backend; +pub use keymap::physicalkey_to_scancode; pub use output_state::write_guest_output_state; pub use compositor::{Compositor, State}; pub use event_centralizer::{centralize, centralize_injected_keyboard, CentralizedEvent}; -pub use event_handler::handle; +pub use event_handler::{handle, on_external_pointer, paint_trackpad}; pub use winit_backend::{bind, WinitGraphicsBackend}; use smithay::{ backend::renderer::gles::GlesRenderer, - utils::{Clock, Monotonic}, + utils::{Clock, Logical, Monotonic, Point}, }; use std::collections::HashMap; use winit::dpi::PhysicalPosition; @@ -29,6 +30,8 @@ pub enum TouchMode { Undecided, /// Moved past touch slop before the long press fired. Scroll, + /// As a trackpad: one finger moved past touch slop, so it moves the cursor. + Move, /// Long-press timeout elapsed without moving; no button sent yet. LongPress, /// Moved after a long press: left button held down. @@ -58,6 +61,12 @@ pub struct WaylandBackend { pub long_press_timeout_ms: u64, /// Whether a synthesized button press is currently held (an in-progress drag). pub pointer_pressed: bool, + /// Most fingers down at once during the current gesture. + pub touch_fingers: usize, + /// Where the trackpad has moved the cursor to on the external display. + pub cursor_position: Point, + /// Buttons held by a mouse on the external display (`MotionEvent.getButtonState()`). + pub external_buttons: i32, } impl WaylandBackend { @@ -68,5 +77,20 @@ impl WaylandBackend { self.touch_mode = TouchMode::Undecided; self.touch_down_position = None; self.touch_down_time = None; + self.touch_fingers = 0; + } + + /// Whether the phone's own window is there to draw to (not while the app is in the background). + pub fn window_visible(&self) -> bool { + self.graphic_renderer + .as_ref() + .is_some_and(|winit| winit.window_visible()) + } + + /// Whether the desktop is on an external monitor, with the phone as its trackpad. + pub fn is_trackpad(&self) -> bool { + self.graphic_renderer + .as_ref() + .is_some_and(|winit| winit.external_surface().is_some()) } } diff --git a/src/android/backend/wayland/winit_backend.rs b/src/android/backend/wayland/winit_backend.rs index 23e466f..9003fb5 100644 --- a/src/android/backend/wayland/winit_backend.rs +++ b/src/android/backend/wayland/winit_backend.rs @@ -18,7 +18,9 @@ //! The other types in this module are the instances of the associated types of these //! two traits for the winit backend. +use crate::android::external_display::ExternalSurface; use khronos_egl::DynamicInstance; +use smithay::backend::egl::display::PixelFormat; use smithay::{ backend::{ egl::{ @@ -29,11 +31,11 @@ use smithay::{ }, renderer::{ gles::{GlesError, GlesRenderer}, - Bind, + Bind, Color32F, Frame, Renderer, }, SwapBuffersError, }, - utils::{Physical, Rectangle, Size}, + utils::{Physical, Rectangle, Size, Transform}, }; use std::ffi::c_void; use std::sync::Arc; @@ -208,7 +210,7 @@ pub fn bind(event_loop: &ActiveEventLoop) -> Result { let display = create_egl_display(handle) .map_err(|error| format!("Failed to create EGLDisplay: {error:?}"))?; @@ -218,18 +220,10 @@ pub fn bind(event_loop: &ActiveEventLoop) -> Result return Err(format!("Unsupported platform: {:?}", platform)), }; @@ -243,13 +237,32 @@ pub fn bind(event_loop: &ActiveEventLoop) -> Result Result { + unsafe { + EGLSurface::new( + display, + pixel_format, + context.config_id(), + AndroidNativeSurface { handle }, + ) + } + .map_err(|error| format!("Failed to create EGLSurface: {error}")) +} + /// Errors thrown by the `winit` backends #[derive(Debug)] pub enum Error { @@ -273,10 +286,120 @@ pub struct WinitGraphicsBackend { renderer: R, // The display isn't used past this point but must be kept alive. _display: EGLDisplay, - egl_surface: EGLSurface, + /// The phone's own window; gone while the app is in the background. + egl_surface: Option, window: Arc, damage_tracking: bool, bind_size: Option>, + pixel_format: PixelFormat, + /// Drawn to instead of `window` while an external monitor is connected. + external: Option, +} + +#[derive(Debug)] +struct ExternalTarget { + egl_surface: EGLSurface, + bind_size: Option>, + // Declared last: the EGL surface must go before the native window it was created on. + surface: Arc, +} + +impl WinitGraphicsBackend { + /// Draw to `surface` from now on, until `detach_external`. + pub fn attach_external(&mut self, surface: Arc) -> Result<(), String> { + // A native window takes one EGL surface at a time. + self.external = None; + let handle = AndroidNdkWindowHandle::new(surface.native_window()); + let egl_surface = unsafe { + EGLSurface::new( + &self._display, + self.pixel_format, + self.renderer.egl_context().config_id(), + AndroidNativeSurface { handle }, + ) + } + .map_err(|error| { + format!("Failed to create EGLSurface for the external display: {error}") + })?; + self.external = Some(ExternalTarget { + egl_surface, + bind_size: None, + surface, + }); + Ok(()) + } + + pub fn detach_external(&mut self) { + self.external = None; + } + + /// Let go of the phone's window as the app goes to the background, but keep drawing to the + /// external monitor. + pub fn suspend_window(&mut self) { + self.egl_surface = None; + self.bind_size = None; + } + + pub fn window_visible(&self) -> bool { + self.egl_surface.is_some() + } + + /// Draw to the phone's window again once the app is back, if it had been let go. + pub fn resume_window(&mut self) -> Result<(), String> { + if self.egl_surface.is_some() { + return Ok(()); + } + let handle = match self.window.window_handle().map(|handle| handle.as_raw()) { + Ok(RawWindowHandle::AndroidNdk(handle)) => handle, + Ok(platform) => return Err(format!("Unsupported platform: {platform:?}")), + Err(error) => return Err(format!("Failed to get window handle: {error}")), + }; + let surface = create_window_surface( + &self._display, + self.pixel_format, + self.renderer.egl_context(), + handle, + )?; + self.egl_surface = Some(surface); + Ok(()) + } + + /// Fill the phone's own window with colored rectangles, painted in order, for when it serves + /// as a trackpad. + pub fn paint_window( + &mut self, + layers: &[(Color32F, Vec>)], + ) -> Result<(), String> { + let size = self.window_size(); + let Some(egl_surface) = self.egl_surface.as_mut() else { + return Ok(()); + }; + if Some(size) != self.bind_size { + egl_surface.resize(size.w, size.h, 0, 0); + self.bind_size = Some(size); + } + { + let mut framebuffer = self + .renderer + .bind(egl_surface) + .map_err(|error| format!("Failed to bind the window: {error}"))?; + let mut frame = self + .renderer + .render(&mut framebuffer, size, Transform::Flipped180) + .map_err(|error| format!("Failed to render the window: {error:?}"))?; + for (color, rectangles) in layers { + frame + .clear(*color, rectangles) + .map_err(|error| format!("Failed to clear the window: {error:?}"))?; + } + let _ = frame + .finish() + .map_err(|error| format!("Failed to finish the window: {error:?}"))?; + } + egl_surface + .swap_buffers(None) + .map_err(|error| format!("Failed to submit the window: {error}")) + } } impl WinitGraphicsBackend @@ -290,6 +413,19 @@ where (w, h).into() } + /// The external monitor being drawn to, if any. + pub fn external_surface(&self) -> Option<&Arc> { + self.external.as_ref().map(|target| &target.surface) + } + + /// Size of what is drawn to: the external monitor if there is one, otherwise the window. + pub fn output_size(&self) -> Size { + match &self.external { + Some(target) => (target.surface.width, target.surface.height).into(), + None => self.window_size(), + } + } + /// Scale factor of the underlying window. pub fn scale_factor(&self) -> f64 { self.window.scale_factor() @@ -311,25 +447,26 @@ where // buffer will be latched. Some nvidia drivers may not like it, but a lot of wayland // software does the order that way due to mesa latching back buffer on each // `make_current`. - let window_size = self.window_size(); - if Some(window_size) != self.bind_size { - self.egl_surface.resize(window_size.w, window_size.h, 0, 0); + let output_size = self.output_size(); + let (egl_surface, bind_size) = match (&mut self.external, &mut self.egl_surface) { + (Some(target), _) => (&mut target.egl_surface, &mut target.bind_size), + (None, Some(egl_surface)) => (egl_surface, &mut self.bind_size), + (None, None) => { + return Err(SwapBuffersError::TemporaryFailure( + "the app is in the background".into(), + )) + } + }; + if Some(output_size) != *bind_size { + egl_surface.resize(output_size.w, output_size.h, 0, 0); } - self.bind_size = Some(window_size); + *bind_size = Some(output_size); - let fb = self.renderer.bind(&mut self.egl_surface)?; + let fb = self.renderer.bind(egl_surface)?; Ok((&mut self.renderer, fb)) } - /// Retrieve the underlying `EGLSurface` for advanced operations - /// - /// **Note:** Don't carelessly use this to manually bind the renderer to the surface, - /// `WinitGraphicsBackend::bind` transparently handles window resizes for you. - pub fn egl_surface(&self) -> &EGLSurface { - &self.egl_surface - } - /// Retrieve the buffer age of the current backbuffer of the window. /// /// This will only return a meaningful value, if this `WinitGraphicsBackend` @@ -340,7 +477,11 @@ where /// likely interpret an error just as if "0" was returned. pub fn buffer_age(&self) -> Option { if self.damage_tracking { - self.egl_surface.buffer_age().map(|x| x as usize) + let egl_surface = match &self.external { + Some(target) => &target.egl_surface, + None => self.egl_surface.as_ref()?, + }; + egl_surface.buffer_age().map(|x| x as usize) } else { Some(0) } @@ -352,11 +493,18 @@ where &mut self, damage: Option<&[Rectangle]>, ) -> Result<(), SwapBuffersError> { + let (egl_surface, bind_size) = match (&self.external, &self.egl_surface) { + (Some(target), _) => (&target.egl_surface, target.bind_size), + (None, Some(egl_surface)) => (egl_surface, self.bind_size), + (None, None) => { + return Err(SwapBuffersError::TemporaryFailure( + "the app is in the background".into(), + )) + } + }; let mut damage = match damage { Some(damage) if self.damage_tracking && !damage.is_empty() => { - let bind_size = self - .bind_size - .expect("submitting without ever binding the renderer."); + let bind_size = bind_size.expect("submitting without ever binding the renderer."); let damage = damage .iter() .map(|rect| { @@ -373,7 +521,7 @@ where // Request frame callback. self.window.pre_present_notify(); - self.egl_surface.swap_buffers(damage.as_deref_mut())?; + egl_surface.swap_buffers(damage.as_deref_mut())?; Ok(()) } } diff --git a/src/android/dex/README.md b/src/android/dex/README.md index 23580ce..ed4a1e8 100644 --- a/src/android/dex/README.md +++ b/src/android/dex/README.md @@ -1,6 +1,6 @@ This directory stores JVM bytecode artifacts that the on-device `cargo run` APK builder can embed without requiring a Java or Kotlin toolchain in Termux. -`classes.dex` currently contains the Java classes in [`../java/app/polarbear/`](../java/app/polarbear/): the keyboard accessibility service and the prompt that asks before turning it on. +`classes.dex` currently contains the Java classes in [`../java/app/polarbear/`](../java/app/polarbear/): the keyboard accessibility service, the prompt that asks before turning it on, and the external display presentation with its trackpad controls. To regenerate it on a machine with `javac`, `d8`, and Android platform `android.jar` available: diff --git a/src/android/dex/classes.dex b/src/android/dex/classes.dex index 4f26184c32a1bcac8fe589497e7ce91914acffb0..3c6dac958311e58b1b97bf1dd490357b157e21cb 100644 GIT binary patch literal 22172 zcmbW93t*JhnfK2-Gr1BblSx7_BD_RYR7e5|5KOoPNF*dcNG1scEKD*JG7#RG%uFCu z>r&Kew|2|6mTK#6-L3A|R@=I*ZCy)u+d{qUy4F&Av$j=hS9{miesy>4=l6TgduB2T zsQY~{{O5VjbDr~@=iD#vOd`?A;`)Xa>Zudzo`xUwerEsdyB<67#5Wg4|La#bByXvh zb7#L&38mCze`64$pU3+MTdq8Yq&r`!>!7a|C{+hNGaDY-QmRx1^qDzItzVz6)32-a;40sa!3e0a(suk=8H-r1Y zS@0(?Z?#fuz)o-&d>DKYd<*;nR9vOhRbT?#1x|r)gBQV{L9kh=m7ovAz`Mam!I!{U z@JmqELj8hHa2@zN@C5h+D5QStKsy)(H-Y=W^I-N`>H|37!{F=SWiW4@Qq7XjKac~;E2xe_istLrv`@rYGQ{YulwUM%cZZHfc zz@)8Gr>OW+~!FW_PD1o$ra33wj7 z2!0EG5B?KaZP*91K_#dL3&6$TaI_ z@N@7A_%kSKCm*m7ECpAAO<)Ju4IkLfRo@;;7i~P_!f8? z{0{sHcsuB~;1aL`w1Hl*4;%*X2JZ)Vg3p2n!D;Xv@I&xZ@EZ7UU~QpYKoDF6t^}(< z8`uGcfdeMNd%;J*KY)k8H^Eu(Echk(9rz>gbTaP1C7=ZifJ5LW@KJC-_$GK7{0#gC zS2RI0hfaBmK_&E3?I1T<4JPCdRehGdL)K;ZR!D6rybb&r_4Tyjk zm;~2@o4{@0Uhoh&1AYX41$^6-3V<5W0M>y{@D6Z2_#pT!_y#x&o(F#f`P-E$2R5h& zYr$4<4cHIH!4Ys1xD9*^d>Y&jz6>4#-v_?{uYmssdENK|t^^IB6?B1K&<~0z_H0lI z7J*B^rQkBK7+emn09S$~U@52tb)X(B1IqzRgknihOy`Q}Suy=8rdh>Qs+cYn)1hM8 zQ%rA)sZ23tsr7)VNHOIorV+((R}4YL5K?q`MVD1{HAUA@G_^8Kq^K%I(G>2h9iRvF zf)MBf{a^s>1iQc>*bVl8Yrs3eUa${@!4Mb*5fB9nAJ1Y_V3a6lX+z&J>P z6i9;!a2Ol`li(%B;0ACbxCwj+{4elX@HrrDlzEB`V^i_c zZk7rA4Zj$9so_N@VEB6YGQ&5)%jQ7Ru7@u-{APIR2Oc2LJdme3)>6ZFqa%Di*a>eN zejohBh98BOv;{yO;b&>i0~S%GihZ^$Rj$nnsa#>1M=8F z#=$K{U&ezxqAz1Y9`R=#IDyVW=tgk6(U-n2kLXChmbR0$(!b>qx$q(vUi$alhTjK& zpV5~-E{_d_f57Mr!=K9GMPK@#j01UY1Hwzc`mo{8z@IeyUUihX0u1rBB{zc;9l?XTt|_c=J3zfPx*FRj{MFX{_Y(9z8wAm_`f&yPvyu} zPMtiC{O^p;Q#m?wb94eZ{LA>0sn6GP_-9F*sl%7x?>07H&awGg4lfga#!g`lAIRaQ zPu^wh%tfBDY3Jzd%<=7|9Dk%A-ec0reDV*5Urbt=8)c4`=aWEq=~tgJd?PxaHoWwo zdkw!nM=tf8(b_}NMyp$!QlRz$GQ`QtImrq&h zX?USOGV~cuJ!+vP@=?_YtsuS>TE)Nj5kHrILNDOoEJObaYNPjlsLWUYuBoM-fHosP zO!~FZ0z(U-ZOrN^=w?>dL(mRGJMr=&(sdI5HBAT9fNo=zy^!^u5Fn z7(WM?8Ks^E=m`Ns%M1-_+Nah-z3fnYq!YSWhsRZ&kuQV#One?*JcnK$E7FUaR_XI` z9`*hw9j;XWscD`1v!k8hE_kQ%#G%MYjqXc0Rlv0G&1#jF$(E@mh8V`z!-uY}#1_*Kg8MdAb4dsNd3 z)r6e@E9Yux8LR0Jke9JTc|p?x^$Ik|N>)L9CH?I`2v@S|{R%pV7Jo|9)#|&NHmUDv z+NHj)X`@<4x;gA1Hfg$2wHca#R?{QJAE6yO+@ao~=@zwD(-mr;rkyGby^vj`=+86h z7O;!@HQ@#Hs21WE(BsCTHS{RaTSWi;1N0Im$p3;~Mh*IiUyMJ$BrI$A{|1*6{;8%# z>Nh6*dqZD?UP1h`np)~-Cj4_vUHvQIE$j;QXnIJ^f?mn${W`K*`s3F%tx^9CtuyUf z#}4UtI=ox;p=x>Ftq8$0qCU&iU=xWkSKU>4@SL$m$J6JE__3U1w&{lTnB5y^boA3r=B)oxL z#c5415n&VORd7re*3SO>OlHO&6&*GeuTWpsbcy;WO_!>NG;LI0(ex_yRZaWUKWn;9J!ayioSmGk=4pTW z)B@v|t?4>7V(6%mC!t-&Z=vFM7xTs+HFea5I{tu~uj!DgG5Ru3ihix8?tCd>nJ>Fo zS+0R@HSM|;xwP9hT2}0DqX%3WWKNm%-)&c*Qj30f=;V1Qcsj;6ipCz`tbet;QK z`a8W>RqOnk)kT`R{eOUyt*k2p)W=nt9#U&Hb;rYi84sejP0O3rpr-El7~muwBfOWD zZ?2|Z)e7Bb+INT(@V}A&un7;V2=ULE_-^8J{gd?a{E2vrdNRe({>z!- zuZg>k^i}vKk1=yj{1qnN5FI}^C;b`|K^FSi$ETD}?B9z0ZW9lypGHF^{!WC$#21iw zfUwlR)T=xae;@JJ5?@SwKVgZ_*pc{C1pdR=w;0@XL)BC(dqM7Z02(bxr~8vecC8tA0xJ=m({Va5^we0gjoJ7^!>ogKe2HH8wJpi zRi?)6YuTX{TXI&Ac9QnEo_M!C%ChZ|Nqb{9Etb!d_I=s3!E9QwEBXF4adP%a*vIj& zSl`KI^1R)|jR&5=hhUlbQ$i~7^W((HJmUne=8RXY$}NxW*qw~!Vk;P2O(~o}n~qs- z7pma0hJaTs_67rsJwavVE%sQFX;!D)DpU=DGFrEoe$#F&7HM8ATKQJhVqZ`N^MeIW zphM!lPGE~rpA*;&omF_G;3RcfN};4)q@R8sA9dT;&!t!S;oUMngnS+Gar*-LT+r*- zH%Q+L93#Gjk{l!70cxX$ov#zPUZhsS-j2kPD{4YXdn+xJi5s`Om_|#m)5}h!#=Du? zJj@>2v3KZj2jNK_?jh{hH)7F`oqTFus^KyGk#o1$v&2qd9{vlxOw%Nn^!VWEX(&PG zFGL5ro)pDuy!#_+!-}af{yl6-e-Zm`X?ahIOzL4=pT4C(yU)*%OFa#7f-i%*BZGHa zMjp$`XX?*+6a9>Qrhd86pDC|;6M5yE*w4t_GX5GrXJfKj&9TMG=`8Z)o;XYIHI}w~ueutJ9FdAe${L$DsQt(kNmzI^beIsK( z^f47!F74#b8HIK3`dh;uG!aOm>DaS~lbmE+>NZ4YF8mND+o09NdM%tgJH@O@LRHK) zBCSGt9hxz#3JaM$=4SI~qX#CW|K{Z3`eA2vuEvivHl}o>USy8D6rEx1M+GymmmG#T zJ6Bt0&~3tM3AaH(&l)QqFWK8zi#-MQ5S}yvp{CDTPGB9@imlbuc<>L4^CV0k_BJdN zo8$T(*0o>5Yr7$Dg-X=FlaVE*a?5xV`qIkWtXRbA6@Wb%u~IKG_e)={woa&EaJ>Ei zqh3bJLF9gVO3Wj*ZlO%pe~2!o~Sb`FeKCXLg%YDo0t}e%rArbM{pKoLWml#JT-Z@|+sKJCRR~ zUw1@agG}}cvTocBjdOVN5+42z2sA^-b1a-Wp!9fdj$ioof={i z0rA2K{5^b$wJ0!3`Vwom~A?W^wkG(l$W`g8#{ zGy4(O!*`mvP=J*@@Okoc%PZyli)^~;Y&su(Oy;E+8@l<;s#{Xo! z&5T{*Nd^`m6+a|}*n1yoq^@>b^VDw7h3DA(YvMT_VRPPF+6)CRWF{}A=DtZkn~!zJ zE+J3JOYTF(zdNv%=`;CAN~q%>Qpaobn5eOe)jUrZeYjdJqxW1WHS2BCE8K5c2a3H- zUdBN=ea2hL^@dwle~(SKU$}Lck^h5{j|UzgXFqd}>%+asZ$MH_+XOAAzKEL?{O~-i zlJyrW+bZ^~_Ds;eg|toyUR=M}q?a}YGM~+>}3W(q;!Z)(`7ChU7>%zbX3eFPo1&o0RJ6WNW)_<5W-Y3opM zfeO*f#sl9WR4n(9*0}u?I#Yf4Y}Sr_j-Bsk?bz6{vGZMR=cn4v_p}}9?~><_(XEG$ z>o>p5IQCxZq}US*EX<~BV%BN$6yeuG8OQbyNV&L5LSosYTQZezD7WUTM(RIQUqdgGQ@zZ%gPNLhuv^+k z{ks}J)-lyqk>%JI>2b0^tyiICoCE?t#H$ik5~qIH?AP3S`7`;=BVED{vFobwR8#VV zT~8@?2QO8-$}gdOm$F_+?^{lPbwdS&8uW-QMN`_jh{~0FG$-(NRs)&gzb2IS{1u)Q z^L{(@ZR~goNx6cYB;*9XAv%l?Mu6vyH{Lk1*r#cOV=vQtKyAx9URLQ*>mOTaYovi;cd^)%=Z>*7^;fVmLd2rSu)+1A32mAG^5Hx4!k0KA-jQMw348c;6#= zk6rR`n^Rw>*5*0&wcL1xp1f2AUy*#NP52>8cE~GC$gvxht$Lokggc7+TUT=jQ^Rh& z(mUB&>AStPGOw_;GXJjiiO@>by)yKjOI4-sYwMieE0uqf=p}ZnRCX{}6ndJNg1f#^ zS(w;R@biNFbpB%2$BMj$hEJ>yeeY80prPU3)(Y=O?IJ*nV`wxwb#j>e?O|xpaMncVy%+wm*8u57%WZ-`eV0 z*6~FWUs-(r`i$kpx&)QpudT22ooJO3+U2_Kc2K$+x2D`SW$oL?JgHU&=BVRVrN?e{ zYvLF+K^twT^mJ>98)B^c7XM;;O;_emwuZh>9eEY?O5NriYb|(Q{PfVKOK4fY9?h~o ztfs%o`c=Vsw@~e3hLbmCD!9w`(~H+I&n4=^e3mizGiQ@llSXzQUixIPwINWzKI32L z$;GS_au)NlYLt?JJBqnSCXLJ=!9Zy?@9oHBU&BbL|7ZHC%w@8c$kR`p_!r{MfcQ64 z-p99RO3y1_qUG)k$r@|y?6HtzTI@&;Vqfx31b)V+d#03;EOBAt=0K0vIDsD{k=a7V zw$RHo?O}%dq{qX2@N3c(drCc-d1pUq1L%b6FK4BV>zSfR@A0awW-D302wrj%|D-;~ z(3f$auq#Nn+q#@u$i#{7dY!djBJOaz_h1S8Mf{EjD*5zNPD|T4O8i3d zlHH?E+O4b!{Y(8Mw+sdA!hMi8rUd0`2qKhmqquHbB9cN1H~iY%>yRnEJ-qeLEKcCNAdGIEdZO}^dBYE`JQmR7ixKKx7G zDoUt^d=mDT*s(kI8TxvSuRoIxdk-Vo-FOA*t{`1iHr*AZ>ml8PI^DO>5?hYFpPWV4 z_0~sfuC4Db6)O`i#t!~xVy;L>Gj(^LZ{-u=g zC$v}z@ltniR<*}n-4?0Lt4*u%UeZDebUj{O9=ift$G?^sz} zv4>eX6q4|x^bGb=^+T%F8`>dt@r16Wfo$4ut9>feFS?Iq_duEc^C*7HyT50AKHs@x zMt0OP?%c7nPzBi2$$pysN8nlV4YB52yXk44Z}9jg$Nr|YM!k6OB%GhTyp)yi;*!TA zsAKn0gEe`roV%N-$sb8u(CV7f))7u<<&20-Owf~wb9$nxlD$qp>6sS+?@;_L@+QYG zujODHga1`S4pN`$M zMtwz_df2rwmn?Xl;Ab!D57R7!WVR7yHCO6J7~XUGKfrry|KMP4=U}Zail_8F@_y2P zg0}N_F1Y!mHMev@%hClOxn};!!ILeX$&2PMWl$*p{LaqK_Cua)?`8|)A7nr4SG=F} z%ch3!YS+RAm4D4-*Wf*!olB9FOXM6;}up=x!NEYpG0^5WY+zvI9I^f^EM zlMi0a`6q8ad+q6)t;@kB1twr-WL3;5-ot^cgNarDdU71%+sb@M%wZyb>K ztA6>igkL3S0;?>r^z=RIl&;FAzg#*wsm@4cot?CTrB-EGXNy%;+7g=_JYZFn4xUE% z#%Zgp^o{w?O%C2Ov2ODD7WF65-?K*@_dq9ix2RXd_^(CUsa@qzB^7(WNLa-A(4Ax{ zUs;q|xmD7gwaNps)kDzLd2`q9!Ool4oNReu^3(hu99(n2Gy6T0@=D0x5?kXbxm%qO zW4ABuoPT<7Y0H|y14~a1t{EKk9K48LLCn&VXV;t@q|->wEiXUUB5R#{XD2iagf2I< z!O*3K&Ng(Jp$r+VFKGnwU>V+BKjr;^gog;bR5*7{6?%<{zlLrh;Sm!af|Ia}VM$kF z(l;_9MZOlud{%-52@A>%9fC@lSvprm&ve5O=7Oom?bmL&dRknyUTY;r>`H1$=a$JW zmm8M+Gycgp9wht@O*1zd?%u=QJ4t*QGmY4keS=V$%Z19_m{7TU7u)W8plUrYx%>!Y z)76nPzu20uYIK@~M!v|<%MHB}DrH=Pmg}{fz80C}QETLqZzB+!jntV--TGgFOyZjj zrMu{`ymu450YWYv(d{9rB<$9Ylvod~B=c6u~= z$WF(F+FdbcV$zO8QwP)WgncBI9<^JYNHQLaT$ZxK!^6>3DmD}wi=~g+sc7Zm0wQ>7k^k~XH8lSKeNz$WZhwa4Z(Nt_WJSLGt z@o+L?hneSjDX*&`pg%eMcV>qH!-AFs0 zwBwX0X@?Vu)DmqS7qjZAbUYaqrBsxBaW1LdOef<9F&K7^9wDt1ZWn$_Ri!7Ax{&da z5j&g~4Lcn>6t!c{ThvfG9dq`lYL$2K<^8I#Wq2&+#L{b3ev3;BTetNNwDq)YQbVSe zaUz;X*{L{|Q={=@dUzsDjgjSfYHS4eW9d|MY-EX@niw9n!zsIUEPZ7tJfzDj4Z1a& z4ok^uZB@R>ZPspDA?l>V=~&!R6>XF0XwnIfZHlE5W8tH<2f~NL%4%1h_73H1@964M z7q-WfN2G5>phi#vwn&W4F}nw+?rE$nRDwPAZ} z&n7t2>}qj_JAe1GG2ldp)6s}pn9*#_?T5Xl8*0D(85NV~yiB+^QyTtJ>I3FLH9VB9qUtZ8VWfas+8v|wt)Sb_vX0_`7JyC}<5^q*> zrV=I+7*EFzGvJ!}4M^4tk&i`_=}oclSbYDY4HL1kNHp23E_gGQW>qmQ%1zj;s;5bF zyGFBGkd31e(sY@+jZ|LTf!h{76wP&LNg0iiR4Il zIJ#)NvvDjoe6TB)B6qPiRRbAoGm-Q0NiHy2IqQs4Ws> zVrW(uzrAj=T6B(5;!s^{B7x6(aJj8{t|_#-!@~!|`=eXK4xi`Ek3mXxJ0r3E6G?6D zeC;7hQr8nnoX>6j{mF1*G&YQhuyZ&})V!>(*{JSt%t*?*-zO7l6XFbqyPDJWvYSEpIfP zqz^Q!VAh0=?uzfvon#KjqDL}GnpIU+SIe0|+YamDGc{A_h^=v1Kh7W5O|M}L%jADf zM!geyY&WY*re|d2o8vN((JRNsh8QEc9am>NO)a-Ma%1}`QM0O>o`DFNQDl4`9iYPF zM>?ETG@Y9222&$d8#4)JOhH$k*Xq?WKgEXKN_jhrp*V~6l+skIXR|%0cEp#flktfJ za}Jx8bayxzK19n_PWQ$wSF^IuCw7awD0DPIkGb&8HO|RAx3-v)*dvYUPTY7t8<|1Y z!MrmTi~R1wbMO{If;q%p=f$E9;w?9 zPDMK;ObKK|p?#Ur2Xpn^mB5|Cr&bQ_a<1ArCYQds3tE>A8SZ2!{wdQ(Vv+sPbR9eJ zXgKNC!;HqB8s+EF%^heaIusA5Soc^o*)AmFW8vfwrt4|kBk;ee_4V0CTI@K`*>p>E?CM`zh5zJ-oE)Mfj0u2Kh+ zP|_G#c%JyJ(L+N)L)*-6$8%y_ zp949ft>N^j><^}twhtX(c9b2;l&ojMab#mQU9*?ng~Lwbf*eg(mOYN-8ty&HF8)xn z3UtLe_nV>Dx@_4|RkTemAHvST6hG(gX>0FQvv>5h_JrDc_J;a;w)Lv~p6#L55I^hc z+1|Hp6W=G6=HOz$bWl~$yQy<;$F`8l?+x{A?`%`vQ0vvIJ;eDpVy-gWivu|kN6mrP zHoL=GyDue|3}~3E1CG(*tnpe^IddSmr^kYj+z80QwqJSr+m*M!y(|!)3p8i4Q>mTgc zqAUV~Xbz%*VM#eCN7g}69YnQi_w<#>ti)_ncc0T>&8pa4To={X^9>WjFN2>o#pg!w zQqe>#&q=VHU!-Q_4LS10Y5bJViX8choU|)* zY#5W_J6vnXbUOExJFRJX%XP>}}gdr(+S8>z(q%B*WTW?P^e?u)xG59q>gZujHrC3E-sc-9(3%eDwe(Me)eyOiigKog^kbb zkkcH)@Lo7JRw-2wi8?9H`>NP5n-VdEvDBehDy0JAYB)VSn%S7^D7m>&ep3pww@{u) zf=EtLt;u1G!EB5r$y^l*FZ&ENTeu!^OHO6V7v=b?=128lkL-0@*xdK+HJ2SJRUDNA zfovmFs$?V@jY#1nsPaa1OO!&=oVi1BcREnT+*HX85fvm0`<-nAGJ^rDjcuT(9&NG{lvlF5>2BZ2xH5W%ZFp zm6O2Tf=hnx9$MvVp_?_evoRi_QIKt=Q@95}o%i(X0$o%il8YD}?um|Y8!*}Id8#I@0su1OYSR_5FEx22G?TyQZ zxJ-4F52c;@bC;?blcsSA(9*T~sS(=RvCBw<1s$@*oJF^a{!b9PM z(GY8p@*av&H;%O5EY@*u%eOn743I!hK=&zCnvs}uwW@RlTm$Tw2q!sd%Tkn57i7hz z#B?-scUobh+=gX~;OwVv=1h~aB-1UAA}?pZ6B{wNSkk3AajJ^A)0%tn>iSlWbmoa# zA>23`9X{BRl9IY7DOG?_Zu3+j47c_4)2a-odxP;-W`?4;W4uv*Sa(deMk3Ol*>I*5 zQ<9$Oq4;5R^3h>pQ>Afd+QD4SiaYvtF*%W7%*Ca?-C~eorgDRE=bY-pcYSD=N^m=D zdwh5zmGPh?!3@Yno(x9zFbTO>Q@%tzl~yJ4&Vva@Zy!}Lojx;P<-_BQDjCmh!`UXZ zSKc?IR8=y%Uv58>rVcW<2C5_}Tf9_S`=KgK$oNL(vMp2vWG$~bRDM!#m{gv-0(p}Y z^k_b|JAJXxsJuB*zEt=y6L^ZQ$_&Ipmow*965Nnoz@%nnGpMz=UL1~&>0lvR`r=NB zK8-2!EUh@4jOmfA{8M7R3|A4>?o09xw}Q9I1XxVO)yc42daD3Dt)yQOab#lbl_JT# zCeZ3z!^!=!j7rk2ykw#=R2lrX=zcx4%=>`(h~DA~NCkELv>P8)t!2~tQMMIa{b~0( zx|rLOv22@5v2!lOv|HVrA!NiGx1>nZM)E8KdXp=IK?2$7OstviDR&d9M8XW)gHbMW zb(6RuxwzG?xIuT4mL}3ywo15AEKMu=n8A)upV<=1&eHUXG_wp+A(__^ zB;*yL#Bl{oPSa#L=TGwB{sp;Ap*{LwU*IZQ-iB8rmsTt;dMvQ!@ z=B0<|dOBigVn0!%;ndP$nZ!~Phf+0HjfBTi(Iqv^*-OKTSj|<-mo2GDjfR&lBT0BD z93E<1xq4_tbSTmoi7X!)TD@#2Tpx|B9BEv!eATLva5&mH9L6f|L{el%qNduFwab@A zqK9kVr93;WKYHeNdIml6t&uxC^F4bI%(JRIo?S52f8&zdUGldsdAF-xeTS#2z_VNH z&)woiebFTkxa2vPJn!Z*;3g|3S%sU-Gq-vmpUTUMIT<0~et7gmUJ*$MkFf=5>#u|By{ z1i=&bB!U}P9kpIq$u|n}-bv{7ChHdau2lt|AFO(pb!wH*ciZYb>+Y*8>t%3ba~?14 z%d4$o_uqT1TX3tzI)2P|%Nj{1A9ptM@t|-I2=};rydWR1%g1dkeB37=XXN8a(R)cg zj;*zdZeME^pIU4EC0{Yjpy+kvcdfIE&+vs8U*6p6yCl!oTdj8=^WDC|W7O`ktot`u z)*0}^2Fv%!R?GL=1}WnOC+vGIiuKaQ`*44gh^kN6pApern?7q{q6YoXuDPXOq*5wY`azT+Ga7d;Dr4pNpfe$mo1CG zU5Cg%VLvFM7drmQvW{^mw5)|E?1!{g=T|K2J}s&_VV@GwgPmWstfx9XcyRGtYwjgM zEBMbMKht&E^4+@ClOOP2h7XqqEl=j(S&4r=gg>wL@^O0~ANL7&zi?-SdqzHP>-Bg} zgsj4s`n;x!yq?EHKF=9`{qg#s$Mfv&r!DKzz5?H=e(HrU6I$Mf#q?`Ek5H98Uh9P( z%X)o>RrMZE)x)dGEz4(lR>iGV&GJ14`Od;0yZL*MK*ISuTv;hpWD-9ohrcL?UzEd( zjVlR@jg?SIw=O5XJ%`_#!-sPC-S9&|Y#f4$4UtWPiV%UEXR!&3t~?1~BWs+Yw|+*r zYesnIjBsQ|c+7+|`P^&rnVcd2%$vwRXXH1|uzO-g_|6&OPtFM6KOOtx)2IOzGdZE_=`FpMMU6wi^f3sD-PxC5h;fp=;4Y>*+f4kMPsdISw`>kI1t?=@j zW`1O(e_Q%&J@%1HUh?-{eemLow7-HEJ2%i?dGL~-{Px^STC&k?n2%g|`E5R5chmmM H-VpY8Mcay~nDd`X=3#c3R{eYW%ES`QmI;1fmVpN2v7wQLKH#&s89thmG~pA)Ha9~Rc(Ls zcF(aBL+K_z&%Al_=FOWoZ{B*H*G>m}*Kedx3Tw8$c_{es&K=3u|M})49~jTycEjx# z>OX!fMpPoA(?>Q$LEHzjv*1|14w#jRz69FgBdQ0z>?hg|nyDhfe@ayoeTdPQLEE5k zH*hXY^eFIc;3?ooK*JKE9-t4{1Z)9vz}JC`z|+7Ffu8`+0WSc*1pW?mMTm9+W55Hz zQ^2o*4}hiyqRqe|;9lT+z-z#tfhhc14;%$1fV04Jz#oBdBYXhzz&C-P0&fF<1?rlx z7N8&44crb)0}lh=0iFSV3|s=%Q8tsYc6z6~IcM4Oj&zKsyizRs$Wt8i4a~Ezk*YZr%Xg z2y_A6Ko5`rdVxNmA6O4;05$@ffX%>7zz$#+z&=)59>1jEaa@ial15+e-S*do#V*Q%>eVSLSEtD0MF-}2N%K;12>!4|(*k zpb||8+DR5D$0!H1AW})tW#p$>&{jnFe$bfLj(P3n(BnGCbStQgZ1#K95OlSul`KDn zw$JPLQytxkwx6o$HbFylT+lGxA!v|J2--$vL1T0uXcatT`&IZiC8&?41@+TukIs1V zGlB-_9?)vB5~dMKqa8wqu$_ANlM=L+Y|t<=bHAW#=m_W%{L?_A&^!v-hzQ*U+C&nm zpnPsKg35HvYma*LPS6%;a?F|Xd@Y#&c0t=o7gV8>g07^ZpiRVaV|`OlH-6ma__bih zyFr(sTClxkkUOBQ*a2?0;@>1_3{`{MF|WPcn}0dR-2(Y?RFABn%_2T5zZdOxPj59& z$3C<>ymkj7uvfGjJsP2}puGlhEP!&|;(8zh{2=ATQ;$M+9^jhBPdmUlj#Qm=tc_w&Q{`8kFD$AD^h#(DbtI=5~T8Id+r zq#&rmR5Bv%Ol2do3bf95Dzke3Mq!2Piy2`Xt}Qf0P%C4q z(8HGeh*bjAjQB85j0Pws)zK+sCGsp9aqYyBfu#t0VMIEh6_Pq4ofsdIj!S-OloUD! zv(0ipjmkdoGGq}@i43I+`mT@cC49qtyw>AVHEa%m<2AW!ZSndtk!q}fZxwgFJZ{C@ zxSF|fe)z>_qaA&`cbRAnS&?P17m{PXJ@DV^ZNV)SlC4NHr0fTeV0)by!?8Lp1?jk4 zd!5Z5^sf{)gP&_N6RoAVFNDaAP)S(|>xNQ?Ie9KWW@7&~!B!lU;}?Jg+R_2Ucm-k{ zqBtV4LT;f_ZzJ^~d$=-$d;^?W$`;(ULEnJSPtiu?jBkmrk{8=y)6EMvh86jcCqEV8 z+c=E8b$!?k`Bx!{QJ$ib(OXLa34X|X$m(q+MGDGWLqP{~OsSm3l*z^T+(vSVaSFo{%r@??9Bd z!s}R70Mc!!dm+D}BvB(m{umC|H8MHo=M370cM10BCgG8xgmF`#t<)pWLsDFhA#!~r z2V#M3Wb{Tzl|zBJ)Qa6mVC^xSKcjaEuQp&rqVP5>_J(tg^Z!o7h2Kl!s4yj^8#`hs zLG*>OFBERuyLa!dN%_o0)PwLS6vK2Q_hEncZo~Uf7(Rq=I-MH*{@%UakTh~#3Y zSrPpRm7wl<<~4DKyYHPm)_vTwyp%?joN6c~)wUI9T$@xJlc|!@jq+(Fuh|ohSyHBT zXIvRH@|LOR*V>Aj%W1Z)XZ51)%qX^IP3bwUCm1|Bt{IB%D7vkfMwdd5$cm-qG<`}F z#+3H8SBvIY$BwdI%xhMX zT0cuANvr0%5Hd$IoWu~8ZW`eBtCQM%^H&vw;$h7;i&G2DFHkw{B&qK@^R90rFkuzc zoYrx`7%J+yiIi?*cD8nPJr!%$3`x?m>#VXp1M}T*T~B&kwY2;}ODo{47$^=M!+9MC zD@m*Ww=Qm$>y%29iNR6{KC6yy8t&d)Zwgum)!c+SrtMP={9JTClp2KFDClElOITZM zKUj%lUAEwSlHzj?l`L~g$NnbLntO&j(ps);Vb7v-I%P*MCQ{~Dl3M0uQ@S>tK*|qK ziI620b}UHcg*ogE=t`knB}!&dwX&LOu_;j<7ti-~pP_xtS?lOa(ic_j|Kh6aleG4W zIl%dlSBq2nL_#%Cti^sLhK*d&v{4{YqsGmAlG+wg8bPhGhKjhSlC*M>{Xy(RR<3b?@E&|Gk6PCXZV&e z4U&$Kd<2E@2p7g9D2(!vQIbZfYII~|WDm)s=o>|uY&?FQCrJvrdDhX}+e>vWzpJQ@ z*|gTHsXexr)jfklL&NFx$c~ZJNaomy^l&CKvj3Je)u@I&jWeC60P+zxBvpYHXQ+nj zhN>Gj`86DMYSToN@+TIg_6e^{+Z5FJAY^7rnoXgCrscCZxZI?wf^caGh=cl)G2Pfw z?U?3p0Y(s_%q}bk6ohPtX%;orpa}Q{M_i16gzHtMgi;7v;&f$jU5oKJR6}N7qXzUW zEF=`ZD&i6?2G11;szYxYF9Tw96F06cfWm!mC6Z1N-S%$7VK+`xGvS?RidMK2bJsA{ z7ELvuQnOl->IAE2E!CQ#P>~bJdkG@H!LCJ+_jtuRU|>07ebnkoP_n#95eo07Zp5k6 z3tnC2K$vBRnoMIsU2&~co9?YawWfiT#T(HK)p0S#tzwl+4h7AtQ$|hWy17Cnw>WbE zkpZRh+=ltAvO)Fualp7$&y4dc8`UEhhg2NXA|E#jqPY)mi74yT0DiwVCYHIQ>^MjX z79B*<;FWu#FhrgYd|^-x+8Nz}Ek6P~O(Fg{QrM5=Lq6Brj%tYn;~So8oJ!t>rqp7G z>fQWQ%PqXF7H~enmNj}(y6?W7183r#z&H@`t?|5eI^Gq};Y!z$!${cfNo1Ai$d<>@ zHLlv-xp6HwVV5WE_|}42w6(7Iq;7PpB|W~izppE9kE`8%7@}rXHM?Qcmh46?o8OSn z_h++P`m$=Tmfuv^u(5yh=7Oqf8*(bF;Hb;&dlC5?_$3QiD_x05(nAfB^h|@~zq~~9 zzt}*MBvqeRx@Two&qjNs*P<+_IjAcbh*`>yQ>77RY1XCB2 zV(TB6^ *mut ANativeWindow; + fn ANativeWindow_release(window: *mut ANativeWindow); +} + +/// The surface of the `Presentation` shown on an external monitor. +#[derive(Debug)] +pub struct ExternalSurface { + window: NonNull, + pub width: i32, + pub height: i32, + pub density_dpi: i32, + pub refresh_millihz: i32, +} + +unsafe impl Send for ExternalSurface {} +unsafe impl Sync for ExternalSurface {} + +impl ExternalSurface { + pub fn native_window(&self) -> NonNull { + self.window.cast() + } +} + +impl Drop for ExternalSurface { + fn drop(&mut self) { + unsafe { ANativeWindow_release(self.window.as_ptr()) }; + } +} + +/// A mouse (or touch) on the external monitor, in its pixels. +#[derive(Debug, Clone, Copy)] +pub struct PointerEvent { + pub x: f64, + pub y: f64, + /// `MotionEvent.getButtonState()`. + pub buttons: i32, + /// `AXIS_HSCROLL` and `AXIS_VSCROLL`, in wheel notches. + pub scroll_x: f64, + pub scroll_y: f64, + pub time_ms: u64, +} + +#[derive(Default)] +struct Bridge { + proxy: Option>, + surface: Option>, + /// The event loop holds an EGL surface on `surface`. + in_use: bool, + pointer_events: VecDeque, +} + +static BRIDGE: OnceLock<(Mutex, Condvar)> = OnceLock::new(); + +/// How many quarter turns clockwise the phone lies from how Android draws it. +static TRACKPAD_QUARTER_TURNS: AtomicU8 = AtomicU8::new(0); + +pub fn trackpad_quarter_turns() -> u8 { + TRACKPAD_QUARTER_TURNS.load(Ordering::Relaxed) +} + +fn bridge() -> &'static (Mutex, Condvar) { + BRIDGE.get_or_init(Default::default) +} + +pub fn register_event_loop_proxy(proxy: EventLoopProxy) { + bridge().0.lock().unwrap().proxy = Some(proxy); +} + +/// The external monitor's surface, if one is connected. +pub fn surface() -> Option> { + bridge().0.lock().unwrap().surface.clone() +} + +/// Called by the event loop when it starts or stops rendering to `surface()`. +pub fn set_in_use(in_use: bool) { + let (lock, released) = bridge(); + lock.lock().unwrap().in_use = in_use; + if !in_use { + released.notify_all(); + } +} + +pub fn drain_pointer_events() -> Vec { + bridge() + .0 + .lock() + .unwrap() + .pointer_events + .drain(..) + .collect() +} + +fn notify(bridge: &Bridge, event: AppUserEvent) { + if let Some(proxy) = &bridge.proxy { + if let Err(error) = proxy.send_event(event) { + log::warn!("Failed to wake event loop for the external display: {error}"); + } + } +} + +fn call_java(env: &mut JNIEnv, android_app: &AndroidApp, method: &str) { + let activity = unsafe { JObject::from_raw(android_app.activity_as_ptr() as jobject) }; + let result = (|| -> jni::errors::Result<()> { + let loader = env + .call_method( + &activity, + "getClassLoader", + "()Ljava/lang/ClassLoader;", + &[], + )? + .l()?; + let name = env.new_string("app.polarbear.ExternalDisplay")?; + let class = env + .call_method( + &loader, + "loadClass", + "(Ljava/lang/String;)Ljava/lang/Class;", + &[(&name).into()], + )? + .l()?; + env.call_static_method( + JClass::from(class), + method, + "(Landroid/app/Activity;)V", + &[(&activity).into()], + )?; + Ok(()) + })(); + if let Err(error) = result { + log::warn!("Failed to call ExternalDisplay.{method}: {error}"); + let _ = env.exception_clear(); + } +} + +/// Start showing the desktop on an external monitor whenever one is connected. +pub fn start(env: &mut JNIEnv, android_app: &AndroidApp) { + call_java(env, android_app, "start"); +} + +/// Keep the desktop on the monitor while the app is in the background. +pub fn background(env: &mut JNIEnv, android_app: &AndroidApp) { + call_java(env, android_app, "background"); +} + +pub fn stop(env: &mut JNIEnv, android_app: &AndroidApp) { + call_java(env, android_app, "stop"); +} + +#[no_mangle] +pub extern "system" fn Java_app_polarbear_ExternalDisplay_nativeSurfaceChanged( + env: JNIEnv, + _class: JClass, + surface: JObject, + width: jint, + height: jint, + density_dpi: jint, + refresh_rate: jfloat, +) { + let window = unsafe { ANativeWindow_fromSurface(env.get_raw(), surface.as_raw()) }; + let Some(window) = NonNull::new(window) else { + log::warn!("The external display's surface has no native window"); + return; + }; + log::info!("External display surface {width}x{height} at {density_dpi} dpi"); + + let mut bridge = bridge().0.lock().unwrap(); + bridge.surface = Some(Arc::new(ExternalSurface { + window, + width, + height, + density_dpi, + refresh_millihz: (refresh_rate.max(1.0) * 1000.0).round() as i32, + })); + notify(&bridge, AppUserEvent::ExternalDisplayChanged); +} + +#[no_mangle] +pub extern "system" fn Java_app_polarbear_ExternalDisplay_nativeSurfaceDestroyed( + _env: JNIEnv, + _class: JClass, +) { + log::info!("External display surface destroyed"); + let (lock, released) = bridge(); + let mut bridge = lock.lock().unwrap(); + bridge.surface = None; + notify(&bridge, AppUserEvent::ExternalDisplayChanged); + // The surface must not be drawn to once this returns. + let (_bridge, timeout) = released + .wait_timeout_while(bridge, Duration::from_secs(1), |bridge| bridge.in_use) + .unwrap(); + if timeout.timed_out() { + log::warn!("Timed out waiting for the renderer to release the external display"); + } +} + +#[no_mangle] +pub extern "system" fn Java_app_polarbear_TrackpadControls_nativeSetQuarterTurns( + _env: JNIEnv, + _class: JClass, + quarter_turns: jint, +) { + TRACKPAD_QUARTER_TURNS.store(quarter_turns.rem_euclid(4) as u8, Ordering::Relaxed); + notify(&bridge().0.lock().unwrap(), AppUserEvent::TrackpadRotated); +} + +#[no_mangle] +pub extern "system" fn Java_app_polarbear_ExternalDisplay_nativeOnPointer( + _env: JNIEnv, + _class: JClass, + x: jfloat, + y: jfloat, + buttons: jint, + scroll_x: jfloat, + scroll_y: jfloat, + event_time_ms: jlong, +) { + let mut bridge = bridge().0.lock().unwrap(); + let wake = bridge.pointer_events.is_empty(); + bridge.pointer_events.push_back(PointerEvent { + x: x as f64, + y: y as f64, + buttons, + scroll_x: scroll_x as f64, + scroll_y: scroll_y as f64, + time_ms: event_time_ms.max(0) as u64, + }); + if wake { + notify(&bridge, AppUserEvent::ExternalPointer); + } +} + +/// A key from the Android keyboard shown over the trackpad. +#[no_mangle] +pub extern "system" fn Java_app_polarbear_TrackpadControls_nativeOnKey( + _env: JNIEnv, + _class: JClass, + down: jboolean, + key_code: jint, + event_time_ms: jlong, +) { + let Some(scancode) = physicalkey_to_scancode(android::physical_key(key_code as u32)) else { + return; + }; + let state = if down == JNI_TRUE { + ElementState::Pressed + } else { + ElementState::Released + }; + accessibility::inject_key(scancode, state, event_time_ms.max(0) as u64); +} diff --git a/src/android/java/app/polarbear/ExternalDisplay.java b/src/android/java/app/polarbear/ExternalDisplay.java new file mode 100644 index 0000000..d6d0212 --- /dev/null +++ b/src/android/java/app/polarbear/ExternalDisplay.java @@ -0,0 +1,209 @@ +package app.polarbear; + +import android.app.Activity; +import android.app.Presentation; +import android.content.Context; +import android.hardware.display.DisplayManager; +import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; +import android.util.DisplayMetrics; +import android.view.Display; +import android.view.InputDevice; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.PointerIcon; +import android.view.Surface; +import android.view.SurfaceHolder; +import android.view.SurfaceView; +import android.view.View; +import android.view.WindowManager; +import android.widget.Toast; + +/** Shows the desktop on an external monitor while the phone becomes a trackpad. */ +public final class ExternalDisplay { + static { + System.loadLibrary("localdesktop"); + } + + private static Activity activity; + private static DisplayManager displayManager; + private static DesktopPresentation presentation; + private static TrackpadControls controls; + + private static final DisplayManager.DisplayListener LISTENER = new DisplayManager.DisplayListener() { + @Override + public void onDisplayAdded(int displayId) { + update(); + } + + @Override + public void onDisplayRemoved(int displayId) { + update(); + } + + @Override + public void onDisplayChanged(int displayId) {} + }; + + private ExternalDisplay() {} + + public static void start(final Activity activity) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (ExternalDisplay.activity == null) { + ExternalDisplay.activity = activity; + displayManager = (DisplayManager) activity.getSystemService(Context.DISPLAY_SERVICE); + displayManager.registerDisplayListener(LISTENER, new Handler(Looper.getMainLooper())); + } + update(); + if (presentation != null && controls == null) { + controls = new TrackpadControls(activity); + controls.show(); + } + } + }); + } + + /** The app went to the background: keep the desktop on the monitor, put the phone's controls away. */ + public static void background(Activity activity) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (controls != null) { + controls.dismiss(); + controls = null; + } + } + }); + } + + public static void stop(Activity activity) { + activity.runOnUiThread(new Runnable() { + @Override + public void run() { + if (displayManager != null) { + displayManager.unregisterDisplayListener(LISTENER); + } + dismiss(); + ExternalDisplay.activity = null; + } + }); + } + + private static void update() { + if (activity == null) { + return; + } + Display[] displays = displayManager.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); + Display display = displays.length > 0 ? displays[0] : null; + if (presentation != null && presentation.getDisplay().getDisplayId() == (display == null ? -1 : display.getDisplayId())) { + return; + } + dismiss(); + if (display == null) { + return; + } + presentation = new DesktopPresentation(activity, display); + try { + presentation.show(); + } catch (WindowManager.InvalidDisplayException e) { + presentation = null; + return; + } + controls = new TrackpadControls(activity); + controls.show(); + Toast.makeText(activity, "The desktop is on the external display. Use this screen as a trackpad.", + Toast.LENGTH_LONG).show(); + } + + private static void dismiss() { + if (controls != null) { + controls.dismiss(); + controls = null; + } + if (presentation != null) { + presentation.dismiss(); + presentation = null; + } + } + + private static final class DesktopPresentation extends Presentation implements SurfaceHolder.Callback { + DesktopPresentation(Context context, Display display) { + super(context, display); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setCancelable(false); + getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + SurfaceView view = new SurfaceView(getContext()); + view.getHolder().addCallback(this); + // The desktop draws its own cursor where a mouse on this display points. + view.setPointerIcon(PointerIcon.getSystemIcon(getContext(), PointerIcon.TYPE_NULL)); + view.setOnGenericMotionListener(new View.OnGenericMotionListener() { + @Override + public boolean onGenericMotion(View view, MotionEvent event) { + return onPointer(event); + } + }); + view.setOnTouchListener(new View.OnTouchListener() { + @Override + public boolean onTouch(View view, MotionEvent event) { + return onPointer(event); + } + }); + setContentView(view); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + // A keyboard typing while the desktop on this display has focus. + TrackpadControls.forwardKey(event); + return true; + } + + private boolean onPointer(MotionEvent event) { + int buttons = event.getButtonState(); + // A touch screen or pen on the monitor clicks like a mouse. + if (!event.isFromSource(InputDevice.SOURCE_MOUSE)) { + int action = event.getActionMasked(); + buttons = action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL + ? 0 : MotionEvent.BUTTON_PRIMARY; + } + float scrollX = 0; + float scrollY = 0; + if (event.getActionMasked() == MotionEvent.ACTION_SCROLL) { + scrollX = event.getAxisValue(MotionEvent.AXIS_HSCROLL); + scrollY = event.getAxisValue(MotionEvent.AXIS_VSCROLL); + } + nativeOnPointer(event.getX(), event.getY(), buttons, scrollX, scrollY, event.getEventTime()); + return true; + } + + @Override + public void surfaceCreated(SurfaceHolder holder) {} + + @Override + public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { + DisplayMetrics metrics = getContext().getResources().getDisplayMetrics(); + nativeSurfaceChanged(holder.getSurface(), width, height, metrics.densityDpi, + getDisplay().getRefreshRate()); + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + nativeSurfaceDestroyed(); + } + } + + private static native void nativeSurfaceChanged( + Surface surface, int width, int height, int densityDpi, float refreshRate); + + private static native void nativeSurfaceDestroyed(); + + private static native void nativeOnPointer( + float x, float y, int buttons, float scrollX, float scrollY, long eventTimeMs); +} diff --git a/src/android/java/app/polarbear/TrackpadControls.java b/src/android/java/app/polarbear/TrackpadControls.java new file mode 100644 index 0000000..89cfdc0 --- /dev/null +++ b/src/android/java/app/polarbear/TrackpadControls.java @@ -0,0 +1,276 @@ +package app.polarbear; + +import android.app.Activity; +import android.app.Dialog; +import android.content.Context; +import android.content.SharedPreferences; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.RectF; +import android.graphics.drawable.ColorDrawable; +import android.os.Build; +import android.os.Bundle; +import android.text.InputType; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.View; +import android.view.Window; +import android.view.WindowInsets; +import android.view.WindowManager; +import android.view.inputmethod.BaseInputConnection; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputConnection; +import android.view.inputmethod.InputMethodManager; +import android.widget.LinearLayout; + +/** Buttons on the phone while it is a trackpad: turn the trackpad, and type with the Android keyboard. */ +final class TrackpadControls extends Dialog { + private static final String PREFS = "trackpad"; + private static final String QUARTER_TURNS = "quarter_turns"; + + private final Activity activity; + private IconButton rotate; + private KeyboardButton keyboard; + private boolean keyboardShown; + /** Waiting for the window to take focus before the keyboard can come up. */ + private boolean keyboardPending; + /** The keyboard has been on screen since it was asked for. */ + private boolean keyboardSeen; + + TrackpadControls(Activity activity) { + super(activity); + this.activity = activity; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_NO_TITLE); + super.onCreate(savedInstanceState); + setCancelable(false); + + Window window = getWindow(); + window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); + // Touches elsewhere reach the trackpad, and keys the activity, until the keyboard is up. + window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); + window.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); + WindowManager.LayoutParams attributes = window.getAttributes(); + attributes.y = dp(48); + window.setAttributes(attributes); + + LinearLayout bar = new LinearLayout(getContext()); + bar.setOrientation(LinearLayout.HORIZONTAL); + rotate = new IconButton(getContext(), IconButton.ROTATE); + style(rotate, "Rotate trackpad"); + rotate.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + setQuarterTurns(quarterTurns() + 1); + } + }); + keyboard = new KeyboardButton(getContext()); + style(keyboard, "Keyboard"); + keyboard.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View view) { + setKeyboardShown(!keyboardShown); + } + }); + bar.addView(rotate); + bar.addView(keyboard); + setContentView(bar); + + if (Build.VERSION.SDK_INT >= 30) { + // The keyboard can also go away with the back gesture. + bar.setOnApplyWindowInsetsListener(new View.OnApplyWindowInsetsListener() { + @Override + public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { + boolean visible = insets.isVisible(WindowInsets.Type.ime()); + if (keyboardShown && visible) { + keyboardSeen = true; + } else if (keyboardShown && keyboardSeen) { + setKeyboardShown(false); + } + return insets; + } + }); + } + setQuarterTurns(quarterTurns()); + } + + @Override + public void onWindowFocusChanged(boolean hasFocus) { + super.onWindowFocusChanged(hasFocus); + if (hasFocus && keyboardPending) { + keyboardPending = false; + // After the input method has connected to the newly focused button. + keyboard.post(new Runnable() { + @Override + public void run() { + if (Build.VERSION.SDK_INT >= 30) { + getWindow().getInsetsController().show(WindowInsets.Type.ime()); + } + InputMethodManager imm = (InputMethodManager) + getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(keyboard, 0); + } + }); + } + } + + @Override + public void dismiss() { + setKeyboardShown(false); + super.dismiss(); + } + + private int quarterTurns() { + return activity.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getInt(QUARTER_TURNS, 0); + } + + private void setQuarterTurns(int quarterTurns) { + quarterTurns %= 4; + SharedPreferences prefs = activity.getSharedPreferences(PREFS, Context.MODE_PRIVATE); + prefs.edit().putInt(QUARTER_TURNS, quarterTurns).apply(); + nativeSetQuarterTurns(quarterTurns); + // Keep the icons upright for someone holding the phone that way. + rotate.setRotation(-quarterTurns * 90); + keyboard.setRotation(-quarterTurns * 90); + } + + private void setKeyboardShown(boolean shown) { + if (keyboard == null || shown == keyboardShown) { + return; + } + keyboardShown = shown; + Window window = getWindow(); + InputMethodManager imm = + (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + if (shown) { + keyboardSeen = false; + keyboardPending = true; + window.clearFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); + // Only now: a view focusable in touch mode takes the first tap as focus, not a click. + keyboard.setFocusableInTouchMode(true); + keyboard.requestFocus(); + } else { + keyboardPending = false; + imm.hideSoftInputFromWindow(keyboard.getWindowToken(), 0); + keyboard.setFocusableInTouchMode(false); + window.addFlags(WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); + } + keyboard.setSelected(shown); + keyboard.invalidate(); + } + + private void style(View view, String label) { + view.setContentDescription(label); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dp(56), dp(56)); + params.setMargins(dp(8), 0, dp(8), 0); + view.setLayoutParams(params); + } + + private int dp(int value) { + return Math.round(value * getContext().getResources().getDisplayMetrics().density); + } + + /** A round button with a line icon drawn on a 24-unit grid, like Material icons. */ + private static class IconButton extends View { + static final int ROTATE = 0; + static final int KEYBOARD = 1; + + private final int icon; + private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + + IconButton(Context context, int icon) { + super(context); + this.icon = icon; + paint.setStrokeCap(Paint.Cap.ROUND); + paint.setStrokeJoin(Paint.Join.ROUND); + } + + @Override + protected void onDraw(Canvas canvas) { + float size = Math.min(getWidth(), getHeight()); + paint.setStyle(Paint.Style.FILL); + paint.setColor(isSelected() ? 0x77FFFFFF : 0x33FFFFFF); + canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, size / 2f, paint); + + // The icon takes the middle half of the button. + float unit = size / 48f; + canvas.save(); + canvas.translate((getWidth() - size) / 2f + 12 * unit, (getHeight() - size) / 2f + 12 * unit); + canvas.scale(unit, unit); + paint.setColor(Color.WHITE); + paint.setStyle(Paint.Style.STROKE); + paint.setStrokeWidth(2); + if (icon == ROTATE) { + // A phone with arrows turning it clockwise. + canvas.drawRoundRect(new RectF(8.5f, 5, 15.5f, 19), 1.5f, 1.5f, paint); + RectF orbit = new RectF(2, 2, 22, 22); + canvas.drawArc(orbit, -80, 60, false, paint); + canvas.drawLine(21.4f, 8.6f, 22.3f, 5.1f, paint); + canvas.drawLine(21.4f, 8.6f, 18.5f, 6.5f, paint); + canvas.drawArc(orbit, 100, 60, false, paint); + canvas.drawLine(2.6f, 15.4f, 1.7f, 18.9f, paint); + canvas.drawLine(2.6f, 15.4f, 5.5f, 17.5f, paint); + } else { + canvas.drawRoundRect(new RectF(2, 6, 22, 18), 2, 2, paint); + paint.setStyle(Paint.Style.FILL); + for (int x = 6; x <= 18; x += 4) { + canvas.drawCircle(x, 10, 1, paint); + canvas.drawCircle(x, 13, 1, paint); + } + paint.setStyle(Paint.Style.STROKE); + canvas.drawLine(8, 15.5f, 16, 15.5f, paint); + } + canvas.restore(); + } + } + + /** Takes what the Android keyboard types and passes it on as key presses. */ + private static final class KeyboardButton extends IconButton { + KeyboardButton(Context context) { + super(context, KEYBOARD); + } + + @Override + public boolean onCheckIsTextEditor() { + return true; + } + + @Override + public InputConnection onCreateInputConnection(EditorInfo outAttrs) { + // No suggestions, so each character arrives as soon as it is typed. + outAttrs.inputType = InputType.TYPE_CLASS_TEXT + | InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD + | InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS; + outAttrs.imeOptions = EditorInfo.IME_FLAG_NO_FULLSCREEN + | EditorInfo.IME_FLAG_NO_EXTRACT_UI + | EditorInfo.IME_ACTION_NONE; + return new BaseInputConnection(this, false); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { + return super.dispatchKeyEvent(event); + } + forwardKey(event); + return true; + } + } + + /** Passes a key on to the desktop, from the Android keyboard or one typing on the monitor. */ + static void forwardKey(KeyEvent event) { + if (event.getAction() == KeyEvent.ACTION_DOWN || event.getAction() == KeyEvent.ACTION_UP) { + nativeOnKey(event.getAction() == KeyEvent.ACTION_DOWN, event.getKeyCode(), event.getEventTime()); + } + } + + private static native void nativeSetQuarterTurns(int quarterTurns); + + private static native void nativeOnKey(boolean down, int keyCode, long eventTimeMs); +} diff --git a/src/android/main.rs b/src/android/main.rs index 5ccac9f..06ae941 100644 --- a/src/android/main.rs +++ b/src/android/main.rs @@ -2,6 +2,7 @@ use crate::{ android::{ accessibility::{register_event_loop_proxy, AppUserEvent}, app::build::PolarBearApp, + external_display, utils::{ application_context::{get_application_context, ApplicationContext}, fullscreen_immersive::{enable_fullscreen_immersive_mode, keep_screen_on}, @@ -74,6 +75,7 @@ fn android_main(android_app: AndroidApp) { .build() .expect("Failed to create event loop"); register_event_loop_proxy(event_loop.create_proxy()); + external_display::register_event_loop_proxy(event_loop.create_proxy()); // ControlFlow::Poll continuously runs the event loop, even if the OS hasn't // dispatched any events. This is ideal for games and similar applications. diff --git a/src/android/proguard-rules.pro b/src/android/proguard-rules.pro index 62dbcf3..62d90cd 100644 --- a/src/android/proguard-rules.pro +++ b/src/android/proguard-rules.pro @@ -1,3 +1,14 @@ -keep class app.polarbear.KeyboardShortcutsPrompt { public static void showIfNeeded(android.app.Activity); } + +-keep class app.polarbear.ExternalDisplay { + public static void start(android.app.Activity); + public static void background(android.app.Activity); + public static void stop(android.app.Activity); + native ; +} + +-keep class app.polarbear.TrackpadControls { + native ; +} diff --git a/src/android/proot/setup.rs b/src/android/proot/setup.rs index 4f7f3c0..2ae103a 100644 --- a/src/android/proot/setup.rs +++ b/src/android/proot/setup.rs @@ -434,6 +434,9 @@ pub fn build_wayland_backend(android_app: AndroidApp) -> WaylandBackend { touch_slop_px: touch_slop_px(&android_app), long_press_timeout_ms: long_press_timeout_ms(&android_app), pointer_pressed: false, + touch_fingers: 0, + cursor_position: (0.0, 0.0).into(), + external_buttons: 0, android_app, } } diff --git a/src/lib.rs b/src/lib.rs index c5b5c8c..bc75f45 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -6,6 +6,7 @@ pub mod core { #[cfg(target_os = "android")] pub mod android { pub mod accessibility; + pub mod external_display; pub mod main; pub mod app { From e8ea99423f34a31c074e62f755a0783bf9a605f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 29 Oct 2026 23:17:07 +0000 Subject: [PATCH 02/10] chore: set version to v1.1.0 --- Cargo.lock | 2 +- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fb85d87..cc96e00 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2348,7 +2348,7 @@ dependencies = [ [[package]] name = "localdesktop" -version = "1.0.4" +version = "1.1.0" dependencies = [ "android-sdkmanager-rs", "android_logger", diff --git a/Cargo.toml b/Cargo.toml index ea8104c..e088fa5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "localdesktop" -version = "1.0.4" +version = "1.1.0" edition = "2021" build = "build.rs" default-run = "build_apk" From 4344e28cf6cf64c5973a39843744009ead71e970 Mon Sep 17 00:00:00 2001 From: mister-teddy Date: Sat, 24 Oct 2026 04:32:53 +0200 Subject: [PATCH 03/10] Keep the desktop running on phones with SVE turned off Gala died with SIGILL a few seconds after every start on a OnePlus Open (Snapdragon 8 Gen 2), leaving a black screen. llvmpipe compiles shaders for the CPU named in /proc/cpuinfo, LLVM assumes a Cortex-X3 has SVE, and this firmware turns SVE off. The app now gives the guest a /proc/cpuinfo without the CPU model when the kernel does not enable SVE, so LLVM targets a generic Armv8 CPU. - Restart Gala if it dies, after ending the panel, dock and daemons it leaves behind: with those still running, a new Gala respawns them every second. - Lower the UI scale on dense screens that are small in pixels. The cover screen got 3x, 372 logical pixels wide, too narrow for the dock; both screens of a 520 dpi foldable now get 2x. - Two processes fewer towards Android's limit of 32: zeitgeist starts without the shell that waits for it, and the keyring only when an app asks for it. Co-Authored-By: Claude Opus 5.5 --- README.md | 14 ++- docs/architecture.md | 4 +- .../pantheon-gnome-keyring-secrets.desktop | 4 + .../usr/local/bin/elementary-mobile-session | 29 +++++- .../org.gnome.zeitgeist.Engine.service | 5 + src/android/app/run.rs | 3 +- src/android/backend/wayland/event_handler.rs | 3 +- src/android/proot/process.rs | 5 + src/android/proot/setup.rs | 19 +++- src/core/config.rs | 63 +++++++++--- src/core/cpuinfo.rs | 95 +++++++++++++++++++ src/lib.rs | 1 + 12 files changed, 220 insertions(+), 25 deletions(-) create mode 100644 rootfs/overlay/etc/elementary-mobile/xdg/autostart/pantheon-gnome-keyring-secrets.desktop create mode 100644 rootfs/overlay/usr/local/share/dbus-1/services/org.gnome.zeitgeist.Engine.service create mode 100644 src/core/cpuinfo.rs diff --git a/README.md b/README.md index 3dd8064..db7fefe 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,13 @@ Android keyboard. Classic session inside it: Wingpanel, the Dock, notifications and the apps. Rendering is done on the CPU (Mesa llvmpipe): Android's GPU drivers cannot be used from a glibc -userland. +userland. llvmpipe compiles shaders for the CPU it reads from `/proc/cpuinfo`; on phones whose +firmware turns off SVE (Snapdragon 8 Gen 1 to 3, for example) the app hides the CPU model from the +guest, or Gala would crash on the first shader that uses it. + +The desktop's scale follows Android's display density, lowered when the desktop would otherwise be +smaller than 540×900 logical pixels (but never below half the size of Android's own UI): a 520 dpi +foldable gets 2x on both its screens instead of 3x. ### Updates @@ -65,7 +71,7 @@ Crash reporting is off. Set `SENTRY_DSN` when building to send crashes to your o Android 12 and later kill an app's child processes once it has more than 32 of them (the "phantom process killer"); everything in the desktop then disappears at once. The session is trimmed to about 23 processes at idle, which leaves room for a couple of apps (Terminal and Web together use -6). To open more at the same time, lift the limit once: +7). To open more at the same time, lift the limit once: - Android 14 and later: Developer options → **Disable child process restrictions**. - Otherwise, from a computer with adb: @@ -85,8 +91,8 @@ about 23 processes at idle, which leaves room for a couple of apps (Terminal and managed by Android. Screen locking is too. - Translations are stripped to keep the APK small, so the desktop is in English. - Shut down and restart in the session menu (there is no logind). Log out starts a fresh session. -- Known rough edges: the panel and dock sometimes appear only after the first tap, and sound is - not working reliably yet. +- Known rough edges: sound is not working reliably yet, and on narrow screens (a foldable's cover + screen) some windows open wider than the screen. ## Building diff --git a/docs/architecture.md b/docs/architecture.md index bbd2194..14d6814 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -57,7 +57,9 @@ The stages, in order: `/etc/localdesktop`, so they survive OS updates) and seed the user's home directory. 4. `setup_machine_id` — give D-Bus a machine ID. 5. `setup_network_and_time` — write Android's DNS servers and timezone into the guest. -6. `fix_xkb_symlink` — repoint an absolute xkb symlink to a relative one (it's resolved from NDK, not the chroot root). +6. `setup_cpuinfo` — give the guest a `/proc/cpuinfo` without the CPU model when the kernel has SVE + turned off, so llvmpipe's shaders do not use it (`core::cpuinfo`). +7. `fix_xkb_symlink` — repoint an absolute xkb symlink to a relative one (it's resolved from NDK, not the chroot root). The first stage is the heaviest: the archive is ~1 GB unpacked. Whether it needs to run is decided by a stamp file holding the archive's SHA-256 from its manifest. diff --git a/rootfs/overlay/etc/elementary-mobile/xdg/autostart/pantheon-gnome-keyring-secrets.desktop b/rootfs/overlay/etc/elementary-mobile/xdg/autostart/pantheon-gnome-keyring-secrets.desktop new file mode 100644 index 0000000..955845d --- /dev/null +++ b/rootfs/overlay/etc/elementary-mobile/xdg/autostart/pantheon-gnome-keyring-secrets.desktop @@ -0,0 +1,4 @@ +[Desktop Entry] +Type=Application +Name=pantheon-gnome-keyring-secrets +Hidden=true diff --git a/rootfs/overlay/usr/local/bin/elementary-mobile-session b/rootfs/overlay/usr/local/bin/elementary-mobile-session index 76de7c7..fe13935 100755 --- a/rootfs/overlay/usr/local/bin/elementary-mobile-session +++ b/rootfs/overlay/usr/local/bin/elementary-mobile-session @@ -84,9 +84,31 @@ export LIBGL_ALWAYS_SOFTWARE=1 GSK_RENDERER=cairo export WEBKIT_DISABLE_SANDBOX_THIS_IS_DANGEROUS=1 ELECTRON_DISABLE_SANDBOX=1 export WEBKIT_DISABLE_DMABUF_RENDERER=1 WEBKIT_DISABLE_COMPOSITING_MODE=1 # Android kills apps with more than 32 child processes, so the session avoids helper processes: -# a forked bus instead of dbus-run-session, and Gala started directly rather than supervised. +# a forked bus instead of dbus-run-session, and one shell that keeps Gala running. bus_pid_file="$XDG_RUNTIME_DIR/session-bus.pid" +# What Gala starts and leaves behind when it dies. A new Gala starts them again, and Wingpanel and +# the Dock refuse to run twice, so it would keep restarting them every second. +gala_helpers='(/usr/libexec/)?(io\.elementary\.(wingpanel|dock|notifications)|gala-daemon-gtk3|mutter-x11-frames)' + +# Gala runs outside gnome-session: it reports readiness to systemd only, so as a session component +# it would hit gnome-session's registration timeout. Its screen locker also crashes without +# XDG_SESSION_ID when logind is missing. Without a window manager the screen goes black and stops +# responding, so it is started again if it dies. +run_gala() { + trap 'kill "$wm" 2>/dev/null; wait "$wm"; exit' TERM + while :; do + started=$(date +%s) + XDG_SESSION_ID=elementary-mobile gala & + wm=$! + wait "$wm" + log "Gala exited with status $?, restarting it" + pkill -x -f "$gala_helpers" + # Do not spin if it cannot start at all. + [ $(($(date +%s) - started)) -ge 10 ] || sleep 10 + done +} + # Start a fresh session after "Log Out", like a display manager with automatic login. while kill -0 "$xwayland" 2>/dev/null; do DBUS_SESSION_BUS_ADDRESS=$(dbus-daemon --session --fork --print-address=1 --print-pid=3 3>"$bus_pid_file") @@ -94,10 +116,7 @@ while kill -0 "$xwayland" 2>/dev/null; do gsettings set org.gnome.desktop.interface scaling-factor "$scale" - # Gala runs outside gnome-session: it reports readiness to systemd only, so as a session - # component it would hit gnome-session's registration timeout. Its screen locker also crashes - # without XDG_SESSION_ID when logind is missing. - XDG_SESSION_ID=elementary-mobile gala & + run_gala & gala=$! gnome-session --session=elementary-mobile diff --git a/rootfs/overlay/usr/local/share/dbus-1/services/org.gnome.zeitgeist.Engine.service b/rootfs/overlay/usr/local/share/dbus-1/services/org.gnome.zeitgeist.Engine.service new file mode 100644 index 0000000..0694f0a --- /dev/null +++ b/rootfs/overlay/usr/local/share/dbus-1/services/org.gnome.zeitgeist.Engine.service @@ -0,0 +1,5 @@ +# Shadows zeitgeist's own service file (the session bus prefers /usr/local/share), which starts the +# daemon from a shell that waits for it: one more process towards Android's limit of 32. +[D-BUS Service] +Name=org.gnome.zeitgeist.Engine +Exec=/usr/bin/zeitgeist-daemon diff --git a/src/android/app/run.rs b/src/android/app/run.rs index 5a31750..4720003 100644 --- a/src/android/app/run.rs +++ b/src/android/app/run.rs @@ -80,7 +80,8 @@ fn configure_output(backend: &mut WaylandBackend) { Some((0, 0).into()), ); - let guest_scale = crate::core::config::guest_ui_scale(guest_scale_factor); + let guest_scale = + crate::core::config::guest_ui_scale(guest_scale_factor, window_size.w, window_size.h); write_guest_output_state(window_size.w, window_size.h, guest_scale); for surface in backend.compositor.state.xdg_shell_state.toplevel_surfaces() { diff --git a/src/android/backend/wayland/event_handler.rs b/src/android/backend/wayland/event_handler.rs index 247632c..8894deb 100644 --- a/src/android/backend/wayland/event_handler.rs +++ b/src/android/backend/wayland/event_handler.rs @@ -450,7 +450,8 @@ pub fn handle(event: CentralizedEvent, backend: &mut WaylandBackend, event_loop: ); } - let guest_scale = crate::core::config::guest_ui_scale(guest_scale_factor); + let guest_scale = + crate::core::config::guest_ui_scale(guest_scale_factor, size.w, size.h); write_guest_output_state(size.w, size.h, guest_scale); if let Some(surface) = get_surface(&backend.compositor.state) { diff --git a/src/android/proot/process.rs b/src/android/proot/process.rs index b553027..0fb9dcb 100644 --- a/src/android/proot/process.rs +++ b/src/android/proot/process.rs @@ -1,4 +1,5 @@ use crate::android::utils::application_context::get_application_context; +use crate::core::cpuinfo::GUEST_CPUINFO; use std::ffi::CString; use std::fs; use std::io::{BufRead, BufReader, Read}; @@ -159,6 +160,10 @@ impl GuestProcess { .arg(format!("--bind={rootfs}/proc/.sysctl_inotify_max_user_watches:/proc/sys/fs/inotify/max_user_watches")) .arg(format!("--bind={rootfs}/sys/.empty:/sys/fs/selinux")); + if context.rootfs_dir.join(GUEST_CPUINFO).is_file() { + process.arg(format!("--bind={rootfs}/{GUEST_CPUINFO}:/proc/cpuinfo")); + } + // env vars process.arg("/usr/bin/env").arg("-i"); process.arg(format!("HOME={home}")); diff --git a/src/android/proot/setup.rs b/src/android/proot/setup.rs index 2ae103a..151d966 100644 --- a/src/android/proot/setup.rs +++ b/src/android/proot/setup.rs @@ -10,7 +10,10 @@ use crate::{ utils::application_context::get_application_context, utils::ndk::{long_press_timeout_ms, run_in_jvm, scale_factor, touch_slop_px}, }, - core::rootfs::{self, RootfsManifest, ROOTFS_ARCHIVE, ROOTFS_MANIFEST}, + core::{ + cpuinfo::{guest_cpuinfo, GUEST_CPUINFO}, + rootfs::{self, RootfsManifest, ROOTFS_ARCHIVE, ROOTFS_MANIFEST}, + }, }; use jni::objects::{JObject, JString}; use pathdiff::diff_paths; @@ -303,6 +306,17 @@ fn setup_network_and_time(options: &SetupOptions) -> StageOutput { None } +/// Give the guest a `/proc/cpuinfo` that keeps llvmpipe from using CPU features the kernel turned +/// off (see `core::cpuinfo`). Every launch, so it always describes this device. +fn setup_cpuinfo(_: &SetupOptions) -> StageOutput { + let path = get_application_context().rootfs_dir.join(GUEST_CPUINFO); + match fs::read_to_string("/proc/cpuinfo") { + Ok(host) => replace_file(&path, &guest_cpuinfo(&host)), + Err(error) => log::warn!("Failed to read /proc/cpuinfo: {error}"), + } + None +} + /// Write `contents` to `path`, replacing a symlink or read-only file left there by the image. fn replace_file(path: &Path, contents: &str) { let _ = fs::remove_file(path); @@ -487,7 +501,8 @@ pub fn setup(android_app: AndroidApp) -> PolarBearBackend { Box::new(setup_home), // Step 3. Persistent /home and /etc/localdesktop Box::new(setup_machine_id), // Step 4. Seed /etc/machine-id for D-Bus clients Box::new(setup_network_and_time), // Step 5. DNS servers and timezone from Android - Box::new(fix_xkb_symlink), // Step 6. Fix xkb symlink + Box::new(setup_cpuinfo), // Step 6. /proc/cpuinfo that llvmpipe can trust + Box::new(fix_xkb_symlink), // Step 7. Fix xkb symlink ]; let handle_stage_error = |e: Box, sender: &Sender| { diff --git a/src/core/config.rs b/src/core/config.rs index 25ca294..26e1b70 100644 --- a/src/core/config.rs +++ b/src/core/config.rs @@ -33,13 +33,31 @@ pub const PIPEWIRE_GUEST_RUNTIME_DIR: &str = "/tmp"; /// PipeWire-Pulse socket as seen from inside the proot guest. pub const PULSE_GUEST_SERVER: &str = "unix:/tmp/pulse/native"; -/// Whole-number UI scale for the desktop from Android's density scale (dpi / 160). +/// The smallest desktop, in logical pixels, that the panel, the dock and elementary's windows fit. +const MIN_DESKTOP_SHORT_SIDE: i32 = 540; +const MIN_DESKTOP_LONG_SIDE: i32 = 900; +/// How much denser than Android's own UI the desktop may get to reach that size. +const MAX_DENSITY_RATIO: f64 = 2.0; + +/// Whole-number UI scale for the desktop from Android's density scale (dpi / 160) and the window +/// size in physical pixels. /// /// Rounds down unless the density is close to the next step: a 420 dpi phone (2.625) gets 2x, a /// 480 dpi one 3x. Rounding to nearest gives 3x at 420 dpi, which leaves a desktop barely 360 -/// logical pixels wide in portrait. -pub fn guest_ui_scale(scale_factor: f64) -> i32 { - ((scale_factor + 0.25).floor() as i32).max(1) +/// logical pixels wide in portrait. Then it steps down while the desktop would be smaller than +/// `MIN_DESKTOP_SHORT_SIDE` x `MIN_DESKTOP_LONG_SIDE`, as long as text stays at least half the +/// size of Android's: dense screens that are small in pixels, like a foldable's cover screen (1116 +/// pixels wide at 520 dpi, so 372 at 3x), get 2x. +pub fn guest_ui_scale(scale_factor: f64, width: i32, height: i32) -> i32 { + let (short_side, long_side) = (width.min(height), width.max(height)); + let mut scale = ((scale_factor + 0.25).floor() as i32).max(1); + while scale > 1 + && (short_side / scale < MIN_DESKTOP_SHORT_SIDE || long_side / scale < MIN_DESKTOP_LONG_SIDE) + && scale_factor / f64::from(scale - 1) <= MAX_DENSITY_RATIO + { + scale -= 1; + } + scale } @@ -262,12 +280,35 @@ mod tests { #[test] fn picks_whole_number_scales() { - assert_eq!(guest_ui_scale(1.0), 1); // mdpi - assert_eq!(guest_ui_scale(1.5), 1); // hdpi - assert_eq!(guest_ui_scale(2.0), 2); // xhdpi - assert_eq!(guest_ui_scale(2.625), 2); // 420 dpi - assert_eq!(guest_ui_scale(2.75), 3); // 440 dpi - assert_eq!(guest_ui_scale(3.5), 3); // 560 dpi - assert_eq!(guest_ui_scale(0.75), 1); + let (w, h) = (3840, 2400); + assert_eq!(guest_ui_scale(1.0, w, h), 1); // mdpi + assert_eq!(guest_ui_scale(1.5, w, h), 1); // hdpi + assert_eq!(guest_ui_scale(2.0, w, h), 2); // xhdpi + assert_eq!(guest_ui_scale(2.625, w, h), 2); // 420 dpi + assert_eq!(guest_ui_scale(2.75, w, h), 3); // 440 dpi + assert_eq!(guest_ui_scale(3.5, w, h), 3); // 560 dpi + assert_eq!(guest_ui_scale(0.75, w, h), 1); + } + + #[test] + fn keeps_the_desktop_big_enough_to_use() { + // OnePlus Open at 520 dpi: cover screen and inner screen. + assert_eq!(guest_ui_scale(3.25, 1116, 2484), 2); + assert_eq!(guest_ui_scale(3.25, 2268, 2440), 2); + // Phones keep 2x in either orientation. + assert_eq!(guest_ui_scale(2.625, 1080, 1920), 2); + assert_eq!(guest_ui_scale(2.625, 2400, 1080), 2); + assert_eq!(guest_ui_scale(3.5, 1440, 3120), 2); + // A tablet keeps its density's scale. + assert_eq!(guest_ui_scale(2.0, 1600, 2560), 2); + // Never below 1x. + assert_eq!(guest_ui_scale(2.0, 600, 800), 1); + } + + #[test] + fn keeps_text_readable_on_small_screens() { + // Galaxy Z Fold5 cover screen at 400 dpi: 1x would fit more, with text 2.5 times smaller + // than Android's. + assert_eq!(guest_ui_scale(2.5, 904, 2316), 2); } } diff --git a/src/core/cpuinfo.rs b/src/core/cpuinfo.rs new file mode 100644 index 0000000..499c598 --- /dev/null +++ b/src/core/cpuinfo.rs @@ -0,0 +1,95 @@ +//! The guest's view of `/proc/cpuinfo`. +//! +//! The desktop is drawn by Mesa's llvmpipe, which compiles shaders with LLVM for "the host CPU". +//! On arm64, LLVM picks that CPU from the `CPU part` lines alone and assumes everything the core +//! can do. Many Armv9 phones (Snapdragon 8 Gen 1 to 3, for example) have cores whose SVE is turned +//! off by the firmware, so shaders compiled for them hit an illegal instruction: Gala, the window +//! manager, dies with SIGILL seconds after the desktop starts, and the screen stays black. +//! +//! Without the `CPU part` lines LLVM targets a generic Armv8 CPU, which every arm64 device runs. +//! The `Features` lines, which say what the kernel really enables, are kept. + +/// Where the app writes the guest's `/proc/cpuinfo`, relative to the root filesystem. +pub const GUEST_CPUINFO: &str = "proc/.cpuinfo"; + +/// `/proc/cpuinfo` as the guest should see it, given the host's. +pub fn guest_cpuinfo(host: &str) -> String { + if kernel_enables_sve(host) { + return host.to_string(); + } + host.lines() + .filter(|line| !line.starts_with("CPU part")) + .map(|line| format!("{line}\n")) + .collect() +} + +/// Whether every CPU lists SVE among the features the kernel enables. +fn kernel_enables_sve(cpuinfo: &str) -> bool { + let mut features = cpuinfo + .lines() + .filter_map(|line| line.strip_prefix("Features")) + .peekable(); + features.peek().is_some() + && features.all(|line| { + line.trim_start_matches([' ', '\t', ':']) + .split_whitespace() + .any(|feature| feature == "sve") + }) +} + +#[cfg(test)] +mod tests { + use super::*; + + /// Two of the eight CPUs of a Snapdragon 8 Gen 2 (Cortex-A510 and Cortex-X3), SVE disabled. + const SNAPDRAGON_8_GEN_2: &str = "\ +processor\t: 0 +BogoMIPS\t: 38.40 +Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp flagm2 frint i8mm bf16 bti +CPU implementer\t: 0x41 +CPU architecture: 8 +CPU variant\t: 0x1 +CPU part\t: 0xd46 +CPU revision\t: 1 + +processor\t: 7 +BogoMIPS\t: 38.40 +Features\t: fp asimd evtstrm aes pmull sha1 sha2 crc32 atomics fphp asimdhp cpuid asimdrdm jscvt fcma lrcpc dcpop sha3 sm3 sm4 asimddp sha512 asimdfhm dit uscat ilrcpc flagm sb paca pacg dcpodp flagm2 frint i8mm bf16 bti +CPU implementer\t: 0x41 +CPU architecture: 8 +CPU variant\t: 0x1 +CPU part\t: 0xd4e +CPU revision\t: 0 +"; + + #[test] + fn hides_the_cpu_model_when_the_kernel_disables_sve() { + let guest = guest_cpuinfo(SNAPDRAGON_8_GEN_2); + + assert!(!guest.contains("CPU part")); + assert_eq!(guest.matches("Features\t: fp asimd").count(), 2); + assert_eq!(guest.matches("CPU implementer\t: 0x41").count(), 2); + assert!(guest.ends_with("CPU revision\t: 0\n")); + } + + #[test] + fn keeps_the_cpu_model_when_the_kernel_enables_sve() { + let host = SNAPDRAGON_8_GEN_2.replace(" bti", " bti sve sve2"); + + assert_eq!(guest_cpuinfo(&host), host); + } + + #[test] + fn hides_the_cpu_model_unless_every_cpu_has_sve() { + let host = SNAPDRAGON_8_GEN_2.replacen(" bti", " bti sve", 1); + + assert!(!guest_cpuinfo(&host).contains("CPU part")); + } + + #[test] + fn hides_the_cpu_model_when_features_are_unknown() { + let guest = guest_cpuinfo("processor\t: 0\nCPU part\t: 0xd4e\n"); + + assert_eq!(guest, "processor\t: 0\n"); + } +} diff --git a/src/lib.rs b/src/lib.rs index bc75f45..0d2bdc4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,5 +1,6 @@ pub mod core { pub mod config; + pub mod cpuinfo; pub mod rootfs; } From 458b2385b77916dc08416ca7040d94b78faa322a Mon Sep 17 00:00:00 2001 From: mister-teddy Date: Sat, 31 Oct 2026 10:40:10 +0100 Subject: [PATCH 04/10] fix: stop gala crashing with sigill on phones with sve turned off --- src/android/proot/process.rs | 11 +++++++++-- src/core/cpuinfo.rs | 6 +++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/android/proot/process.rs b/src/android/proot/process.rs index 0fb9dcb..2eb1755 100644 --- a/src/android/proot/process.rs +++ b/src/android/proot/process.rs @@ -1,5 +1,5 @@ use crate::android::utils::application_context::get_application_context; -use crate::core::cpuinfo::GUEST_CPUINFO; +use crate::core::cpuinfo::{kernel_enables_sve, GUEST_CPUINFO}; use std::ffi::CString; use std::fs; use std::io::{BufRead, BufReader, Read}; @@ -137,7 +137,10 @@ impl GuestProcess { .arg("--bind=/dev/tty:/dev/tty") // User data and settings live outside the OS so that an update replacing it keeps them. .arg(format!("--bind={}:/home", context.home_dir.display())) - .arg(format!("--bind={}:/etc/localdesktop", context.config_dir.display())); + .arg(format!( + "--bind={}:/etc/localdesktop", + context.config_dir.display() + )); if context.permission_all_files_access { process @@ -177,6 +180,10 @@ impl GuestProcess { .arg("TMPDIR=/tmp") .arg(format!("USER={}", user)) .arg(format!("LOGNAME={}", user)); + // See `core::cpuinfo`: llvmpipe's optimised shaders still crash Gala on these devices. + if !kernel_enables_sve(&std::fs::read_to_string("/proc/cpuinfo").unwrap_or_default()) { + process.arg("GALLIVM_PERF=nopt"); + } // user shell if user == "root" { diff --git a/src/core/cpuinfo.rs b/src/core/cpuinfo.rs index 499c598..1de76a0 100644 --- a/src/core/cpuinfo.rs +++ b/src/core/cpuinfo.rs @@ -8,6 +8,10 @@ //! //! Without the `CPU part` lines LLVM targets a generic Armv8 CPU, which every arm64 device runs. //! The `Features` lines, which say what the kernel really enables, are kept. +//! +//! That is not always enough: on a OnePlus Open driving a 4K monitor, Gala still died with SIGILL +//! until llvmpipe stopped running LLVM's optimisation passes (`GALLIVM_PERF=nopt`), so the guest +//! gets that too on these devices. It costs little for a 2D desktop. /// Where the app writes the guest's `/proc/cpuinfo`, relative to the root filesystem. pub const GUEST_CPUINFO: &str = "proc/.cpuinfo"; @@ -24,7 +28,7 @@ pub fn guest_cpuinfo(host: &str) -> String { } /// Whether every CPU lists SVE among the features the kernel enables. -fn kernel_enables_sve(cpuinfo: &str) -> bool { +pub fn kernel_enables_sve(cpuinfo: &str) -> bool { let mut features = cpuinfo .lines() .filter_map(|line| line.strip_prefix("Features")) From a637482c674ef9e394dc6ca650fd4174c52e2e66 Mon Sep 17 00:00:00 2001 From: mister-teddy Date: Sat, 31 Oct 2026 10:40:10 +0100 Subject: [PATCH 05/10] feat: dex style trackpad that rotates the screen --- src/android/accessibility.rs | 2 - src/android/app/run.rs | 10 +- .../backend/wayland/event_centralizer.rs | 9 +- src/android/backend/wayland/event_handler.rs | 49 +----- src/android/backend/wayland/winit_backend.rs | 18 +-- src/android/dex/classes.dex | Bin 22172 -> 23584 bytes src/android/external_display.rs | 22 +-- .../java/app/polarbear/ExternalDisplay.java | 5 + .../java/app/polarbear/TrackpadControls.java | 149 ++++++++++++++---- 9 files changed, 144 insertions(+), 120 deletions(-) diff --git a/src/android/accessibility.rs b/src/android/accessibility.rs index 5481a5d..38c5365 100644 --- a/src/android/accessibility.rs +++ b/src/android/accessibility.rs @@ -21,8 +21,6 @@ pub enum AppUserEvent { ExternalDisplayChanged, /// A mouse (or touch) on the external monitor moved, clicked or scrolled. ExternalPointer, - /// The trackpad was turned a quarter. - TrackpadRotated, } #[derive(Clone, Copy, Debug)] diff --git a/src/android/app/run.rs b/src/android/app/run.rs index 4720003..6f93da4 100644 --- a/src/android/app/run.rs +++ b/src/android/app/run.rs @@ -211,8 +211,9 @@ impl ApplicationHandler for PolarBearApp { |env, _| close_webview_popups(env), self.frontend.android_app.clone(), ); - self.backend = - PolarBearBackend::Wayland(build_wayland_backend(self.frontend.android_app.clone())); + self.backend = PolarBearBackend::Wayland(build_wayland_backend( + self.frontend.android_app.clone(), + )); // Same as coming back to the app: bind the renderer and start the session. If the // app is in the background, this fails quietly and the next resume does it. self.resumed(event_loop); @@ -235,11 +236,6 @@ impl ApplicationHandler for PolarBearApp { on_external_pointer(backend, event); } } - AppUserEvent::TrackpadRotated => { - if backend.is_trackpad() { - paint_trackpad(backend); - } - } _ => { for event in accessibility::drain_pending_events() { let event = centralize_injected_keyboard( diff --git a/src/android/backend/wayland/event_centralizer.rs b/src/android/backend/wayland/event_centralizer.rs index 449c7cb..58e6a4f 100644 --- a/src/android/backend/wayland/event_centralizer.rs +++ b/src/android/backend/wayland/event_centralizer.rs @@ -7,7 +7,7 @@ use crate::android::backend::wayland::{ keymap::physicalkey_to_scancode, TouchMode, WaylandBackend, }; -use crate::android::{external_display, utils::ndk}; +use crate::android::utils::ndk; use smithay::backend::input::InputEvent; use smithay::utils::{Physical, Size}; use winit::dpi::PhysicalPosition; @@ -297,13 +297,6 @@ fn centralize_trackpad(touch: Touch, time: u64, backend: &mut WaylandBackend) -> id, .. } = touch; - // Only distances and deltas matter from here on, so turning about the origin is enough. - let location = match external_display::trackpad_quarter_turns() { - 1 => PhysicalPosition::new(-location.y, location.x), - 2 => PhysicalPosition::new(-location.x, -location.y), - 3 => PhysicalPosition::new(location.y, -location.x), - _ => location, - }; match phase { TouchPhase::Started => { backend.touch_points.insert(id, location); diff --git a/src/android/backend/wayland/event_handler.rs b/src/android/backend/wayland/event_handler.rs index 8894deb..e78769c 100644 --- a/src/android/backend/wayland/event_handler.rs +++ b/src/android/backend/wayland/event_handler.rs @@ -1,16 +1,16 @@ use crate::android::{ accessibility, - external_display::{self, PointerEvent}, backend::wayland::{ compositor::{send_frames_surface_tree, ClientState, State}, write_guest_output_state, CentralizedEvent, TouchMode, WaylandBackend, }, + external_display::PointerEvent, }; use smithay::backend::input::{AxisSource, ButtonState}; +use smithay::backend::renderer::element::solid::SolidColorRenderElement; use smithay::backend::renderer::element::surface::{ render_elements_from_surface_tree, WaylandSurfaceRenderElement, }; -use smithay::backend::renderer::element::solid::SolidColorRenderElement; use smithay::backend::renderer::element::{render_elements, Id, Kind}; use smithay::backend::renderer::gles::GlesRenderer; use smithay::backend::renderer::utils::{draw_render_elements, CommitCounter}; @@ -40,10 +40,7 @@ const BTN_MIDDLE: u32 = 0x112; /// External display pixels the cursor moves per phone pixel the finger moves. const TRACKPAD_SPEED: f64 = 1.5; /// What the phone shows while it is a trackpad. -const TRACKPAD_COLOR: Color32F = Color32F::new(0.08, 0.08, 0.08, 1.0); -const TRACKPAD_GRID_COLOR: Color32F = Color32F::new(0.16, 0.16, 0.16, 1.0); -/// Marks the trackpad's top edge, which follows the rotate button. -const TRACKPAD_UP_COLOR: Color32F = Color32F::new(0.24, 0.52, 0.94, 1.0); +const TRACKPAD_COLOR: Color32F = Color32F::new(0.0, 0.0, 0.0, 1.0); /// Pixels a wheel notch scrolls, as libinput reports for a mouse wheel. const WHEEL_STEP: f64 = 15.0; @@ -462,42 +459,12 @@ pub fn handle(event: CentralizedEvent, backend: &mut WaylandBackend, event_loop: } } -/// Show the phone's screen as a trackpad: a grid, with its top edge marked. +/// Show the phone's screen as a blank trackpad; `TrackpadControls` draws its outline on top. pub fn paint_trackpad(backend: &mut WaylandBackend) { - let Some(winit) = backend.graphic_renderer.as_mut() else { - return; - }; - let size = winit.window_size(); - if size.w <= 0 || size.h <= 0 { - return; - } - let spacing = (size.w.min(size.h) / 8).max(1); - let line = (spacing / 48).max(2); - let grid = (1..) - .map(|i| i * spacing) - .take_while(|x| *x < size.w) - .map(|x| Rectangle::new((x, 0).into(), (line, size.h).into())) - .chain( - (1..) - .map(|i| i * spacing) - .take_while(|y| *y < size.h) - .map(|y| Rectangle::new((0, y).into(), (size.w, line).into())), - ) - .collect(); - let bar = line * 4; - let up = match external_display::trackpad_quarter_turns() { - 1 => Rectangle::new((0, 0).into(), (bar, size.h).into()), - 2 => Rectangle::new((0, size.h - bar).into(), (size.w, bar).into()), - 3 => Rectangle::new((size.w - bar, 0).into(), (bar, size.h).into()), - _ => Rectangle::new((0, 0).into(), (size.w, bar).into()), - }; - let layers = [ - (TRACKPAD_COLOR, vec![Rectangle::from_size(size)]), - (TRACKPAD_GRID_COLOR, grid), - (TRACKPAD_UP_COLOR, vec![up]), - ]; - if let Err(error) = winit.paint_window(&layers) { - log::warn!("Failed to paint the trackpad: {error}"); + if let Some(winit) = backend.graphic_renderer.as_mut() { + if let Err(error) = winit.paint_window(TRACKPAD_COLOR) { + log::warn!("Failed to paint the trackpad: {error}"); + } } } diff --git a/src/android/backend/wayland/winit_backend.rs b/src/android/backend/wayland/winit_backend.rs index 9003fb5..40f4920 100644 --- a/src/android/backend/wayland/winit_backend.rs +++ b/src/android/backend/wayland/winit_backend.rs @@ -364,12 +364,8 @@ impl WinitGraphicsBackend { Ok(()) } - /// Fill the phone's own window with colored rectangles, painted in order, for when it serves - /// as a trackpad. - pub fn paint_window( - &mut self, - layers: &[(Color32F, Vec>)], - ) -> Result<(), String> { + /// Fill the phone's own window with one color, for when it serves as a trackpad. + pub fn paint_window(&mut self, color: Color32F) -> Result<(), String> { let size = self.window_size(); let Some(egl_surface) = self.egl_surface.as_mut() else { return Ok(()); @@ -385,13 +381,11 @@ impl WinitGraphicsBackend { .map_err(|error| format!("Failed to bind the window: {error}"))?; let mut frame = self .renderer - .render(&mut framebuffer, size, Transform::Flipped180) + .render(&mut framebuffer, size, Transform::Normal) .map_err(|error| format!("Failed to render the window: {error:?}"))?; - for (color, rectangles) in layers { - frame - .clear(*color, rectangles) - .map_err(|error| format!("Failed to clear the window: {error:?}"))?; - } + frame + .clear(color, &[Rectangle::from_size(size)]) + .map_err(|error| format!("Failed to clear the window: {error:?}"))?; let _ = frame .finish() .map_err(|error| format!("Failed to finish the window: {error:?}"))?; diff --git a/src/android/dex/classes.dex b/src/android/dex/classes.dex index 3c6dac958311e58b1b97bf1dd490357b157e21cb..e468f1c247e2a542bd2127367e1713e46774b280 100644 GIT binary patch literal 23584 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 H-, Condvar)> = OnceLock::new(); -/// How many quarter turns clockwise the phone lies from how Android draws it. -static TRACKPAD_QUARTER_TURNS: AtomicU8 = AtomicU8::new(0); - -pub fn trackpad_quarter_turns() -> u8 { - TRACKPAD_QUARTER_TURNS.load(Ordering::Relaxed) -} - fn bridge() -> &'static (Mutex, Condvar) { BRIDGE.get_or_init(Default::default) } @@ -230,16 +220,6 @@ pub extern "system" fn Java_app_polarbear_ExternalDisplay_nativeSurfaceDestroyed } } -#[no_mangle] -pub extern "system" fn Java_app_polarbear_TrackpadControls_nativeSetQuarterTurns( - _env: JNIEnv, - _class: JClass, - quarter_turns: jint, -) { - TRACKPAD_QUARTER_TURNS.store(quarter_turns.rem_euclid(4) as u8, Ordering::Relaxed); - notify(&bridge().0.lock().unwrap(), AppUserEvent::TrackpadRotated); -} - #[no_mangle] pub extern "system" fn Java_app_polarbear_ExternalDisplay_nativeOnPointer( _env: JNIEnv, diff --git a/src/android/java/app/polarbear/ExternalDisplay.java b/src/android/java/app/polarbear/ExternalDisplay.java index d6d0212..02733a6 100644 --- a/src/android/java/app/polarbear/ExternalDisplay.java +++ b/src/android/java/app/polarbear/ExternalDisplay.java @@ -3,6 +3,7 @@ import android.app.Activity; import android.app.Presentation; import android.content.Context; +import android.content.pm.ActivityInfo; import android.hardware.display.DisplayManager; import android.os.Bundle; import android.os.Handler; @@ -123,6 +124,10 @@ private static void dismiss() { controls.dismiss(); controls = null; } + if (activity != null) { + // The rotate button may have turned the screen; follow the phone again. + activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED); + } if (presentation != null) { presentation.dismiss(); presentation = null; diff --git a/src/android/java/app/polarbear/TrackpadControls.java b/src/android/java/app/polarbear/TrackpadControls.java index 89cfdc0..bf9f4b2 100644 --- a/src/android/java/app/polarbear/TrackpadControls.java +++ b/src/android/java/app/polarbear/TrackpadControls.java @@ -3,17 +3,19 @@ import android.app.Activity; import android.app.Dialog; import android.content.Context; -import android.content.SharedPreferences; +import android.content.pm.ActivityInfo; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; import android.text.InputType; import android.view.Gravity; import android.view.KeyEvent; +import android.view.Surface; import android.view.View; import android.view.Window; import android.view.WindowInsets; @@ -24,13 +26,10 @@ import android.view.inputmethod.InputMethodManager; import android.widget.LinearLayout; -/** Buttons on the phone while it is a trackpad: turn the trackpad, and type with the Android keyboard. */ +/** Buttons on the phone while it is a trackpad: turn the screen, and type with the Android keyboard. */ final class TrackpadControls extends Dialog { - private static final String PREFS = "trackpad"; - private static final String QUARTER_TURNS = "quarter_turns"; - private final Activity activity; - private IconButton rotate; + private final Pad pad; private KeyboardButton keyboard; private boolean keyboardShown; /** Waiting for the window to take focus before the keyboard can come up. */ @@ -41,6 +40,14 @@ final class TrackpadControls extends Dialog { TrackpadControls(Activity activity) { super(activity); this.activity = activity; + pad = new Pad(activity); + } + + @Override + public void show() { + // Under the buttons. + pad.show(); + super.show(); } @Override @@ -55,19 +62,20 @@ protected void onCreate(Bundle savedInstanceState) { // Touches elsewhere reach the trackpad, and keys the activity, until the keyboard is up. window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); - window.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL); + window.setGravity(Gravity.TOP | Gravity.RIGHT); WindowManager.LayoutParams attributes = window.getAttributes(); - attributes.y = dp(48); + attributes.x = dp(Pad.INSET + 8); + attributes.y = dp(Pad.INSET + 8); window.setAttributes(attributes); LinearLayout bar = new LinearLayout(getContext()); bar.setOrientation(LinearLayout.HORIZONTAL); - rotate = new IconButton(getContext(), IconButton.ROTATE); - style(rotate, "Rotate trackpad"); + IconButton rotate = new IconButton(getContext(), IconButton.ROTATE); + style(rotate, "Rotate screen"); rotate.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { - setQuarterTurns(quarterTurns() + 1); + rotateScreen(); } }); keyboard = new KeyboardButton(getContext()); @@ -97,7 +105,6 @@ public WindowInsets onApplyWindowInsets(View view, WindowInsets insets) { } }); } - setQuarterTurns(quarterTurns()); } @Override @@ -123,21 +130,33 @@ public void run() { @Override public void dismiss() { setKeyboardShown(false); + pad.dismiss(); super.dismiss(); } - private int quarterTurns() { - return activity.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getInt(QUARTER_TURNS, 0); - } - - private void setQuarterTurns(int quarterTurns) { - quarterTurns %= 4; - SharedPreferences prefs = activity.getSharedPreferences(PREFS, Context.MODE_PRIVATE); - prefs.edit().putInt(QUARTER_TURNS, quarterTurns).apply(); - nativeSetQuarterTurns(quarterTurns); - // Keep the icons upright for someone holding the phone that way. - rotate.setRotation(-quarterTurns * 90); - keyboard.setRotation(-quarterTurns * 90); + /** + * Turns the whole screen a quarter clockwise, Android keyboard included, for a phone lying + * sideways while auto-rotate keeps it upright. + */ + private void rotateScreen() { + int rotation = activity.getWindowManager().getDefaultDisplay().getRotation(); + boolean portrait = getContext().getResources().getConfiguration().orientation + == android.content.res.Configuration.ORIENTATION_PORTRAIT; + boolean naturallyPortrait = portrait == (rotation == Surface.ROTATION_0 || rotation == Surface.ROTATION_180); + // Orientations for ROTATION_0, 90, 180 and 270 of the display. + int[] orientations = naturallyPortrait + ? new int[] { + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, + ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, + ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, + ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE} + : new int[] { + ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, + ActivityInfo.SCREEN_ORIENTATION_REVERSE_PORTRAIT, + ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE, + ActivityInfo.SCREEN_ORIENTATION_PORTRAIT}; + // The display turns the other way from the content: a quarter clockwise is ROTATION_270. + activity.setRequestedOrientation(orientations[(rotation + 3) % 4]); } private void setKeyboardShown(boolean shown) { @@ -167,8 +186,8 @@ private void setKeyboardShown(boolean shown) { private void style(View view, String label) { view.setContentDescription(label); - LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dp(56), dp(56)); - params.setMargins(dp(8), 0, dp(8), 0); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(dp(44), dp(44)); + params.setMargins(dp(4), 0, dp(4), 0); view.setLayoutParams(params); } @@ -176,6 +195,80 @@ private int dp(int value) { return Math.round(value * getContext().getResources().getDisplayMetrics().density); } + /** + * The trackpad itself, drawn like Samsung DeX: a border, a cross through the middle, and the + * app's logo on top so the right way up is clear. Touches go through it to the activity. + */ + private static final class Pad extends Dialog { + static final int INSET = 12; + + Pad(Activity activity) { + // Not a floating dialog, which would keep margins around it. + super(activity, android.R.style.Theme_Translucent_NoTitleBar_Fullscreen); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + requestWindowFeature(Window.FEATURE_NO_TITLE); + super.onCreate(savedInstanceState); + setCancelable(false); + Window window = getWindow(); + window.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT)); + window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND); + window.addFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN); + window.setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT); + if (Build.VERSION.SDK_INT >= 28) { + WindowManager.LayoutParams attributes = window.getAttributes(); + attributes.layoutInDisplayCutoutMode = + WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES; + window.setAttributes(attributes); + } + setContentView(new PadView(getContext())); + } + } + + private static final class PadView extends View { + private final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG); + private final Drawable logo; + + PadView(Context context) { + super(context); + paint.setStyle(Paint.Style.STROKE); + // The launcher icon as it is: the bear on its blue background. + logo = context.getApplicationInfo().loadIcon(context.getPackageManager()); + } + + @Override + protected void onDraw(Canvas canvas) { + float density = getResources().getDisplayMetrics().density; + float inset = Pad.INSET * density; + RectF border = new RectF(inset, inset, getWidth() - inset, getHeight() - inset); + float centerX = getWidth() / 2f; + float centerY = getHeight() / 2f; + + paint.setStrokeWidth(density); + paint.setColor(0xFF2E2E2E); + canvas.drawLine(centerX, border.top, centerX, border.bottom, paint); + canvas.drawLine(border.left, centerY, border.right, centerY, paint); + paint.setStrokeWidth(1.5f * density); + paint.setColor(0xFF4A4A4A); + canvas.drawRoundRect(border, 16 * density, 16 * density, paint); + + // Over the top of the cross, on a patch of the pad's black. + int size = Math.round(48 * density); + int left = Math.round(centerX - size / 2f); + int top = Math.round(border.top + 12 * density); + paint.setStyle(Paint.Style.FILL); + paint.setColor(Color.BLACK); + canvas.drawRect(left, top, left + size, top + size, paint); + paint.setStyle(Paint.Style.STROKE); + logo.setBounds(left, top, left + size, top + size); + logo.draw(canvas); + } + } + /** A round button with a line icon drawn on a 24-unit grid, like Material icons. */ private static class IconButton extends View { static final int ROTATE = 0; @@ -195,7 +288,7 @@ private static class IconButton extends View { protected void onDraw(Canvas canvas) { float size = Math.min(getWidth(), getHeight()); paint.setStyle(Paint.Style.FILL); - paint.setColor(isSelected() ? 0x77FFFFFF : 0x33FFFFFF); + paint.setColor(isSelected() ? 0x77FFFFFF : 0x26FFFFFF); canvas.drawCircle(getWidth() / 2f, getHeight() / 2f, size / 2f, paint); // The icon takes the middle half of the button. @@ -270,7 +363,5 @@ static void forwardKey(KeyEvent event) { } } - private static native void nativeSetQuarterTurns(int quarterTurns); - private static native void nativeOnKey(boolean down, int keyCode, long eventTimeMs); } From 98976c02424b80ba1eb42ec608dc7e3b2e2e1ef0 Mon Sep 17 00:00:00 2001 From: mister-teddy Date: Sat, 31 Oct 2026 10:40:51 +0100 Subject: [PATCH 06/10] chore: leave the unrelated config bind formatting as it was --- src/android/proot/process.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/android/proot/process.rs b/src/android/proot/process.rs index 2eb1755..d0873e2 100644 --- a/src/android/proot/process.rs +++ b/src/android/proot/process.rs @@ -137,10 +137,7 @@ impl GuestProcess { .arg("--bind=/dev/tty:/dev/tty") // User data and settings live outside the OS so that an update replacing it keeps them. .arg(format!("--bind={}:/home", context.home_dir.display())) - .arg(format!( - "--bind={}:/etc/localdesktop", - context.config_dir.display() - )); + .arg(format!("--bind={}:/etc/localdesktop", context.config_dir.display())); if context.permission_all_files_access { process @@ -181,7 +178,7 @@ impl GuestProcess { .arg(format!("USER={}", user)) .arg(format!("LOGNAME={}", user)); // See `core::cpuinfo`: llvmpipe's optimised shaders still crash Gala on these devices. - if !kernel_enables_sve(&std::fs::read_to_string("/proc/cpuinfo").unwrap_or_default()) { + if !kernel_enables_sve(&fs::read_to_string("/proc/cpuinfo").unwrap_or_default()) { process.arg("GALLIVM_PERF=nopt"); } From 7ee9aa9163c61d3273fc685e1b5a8c0b893af2b8 Mon Sep 17 00:00:00 2001 From: mister-teddy Date: Sat, 31 Oct 2026 10:41:18 +0100 Subject: [PATCH 07/10] docs: show the desktop on a monitor and the phone as its trackpad --- README.md | 4 +++- docs/img/external-display-monitor.jpg | Bin 0 -> 164983 bytes docs/img/external-display-trackpad.png | Bin 0 -> 17400 bytes 3 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 docs/img/external-display-monitor.jpg create mode 100644 docs/img/external-display-trackpad.png diff --git a/README.md b/README.md index db7fefe..c64576b 100644 --- a/README.md +++ b/README.md @@ -13,9 +13,11 @@ ideally with a keyboard and mouse. It brings a desktop to Android; it does not t into a phone UI. On a phone, connect a monitor (USB-C to HDMI, a dock, or a wireless display): the desktop moves -to it and the phone becomes a trackpad, with buttons to turn the trackpad and to type with the +to it and the phone becomes a trackpad, with buttons to turn the screen and to type with the Android keyboard. +elementary OS on a 4K monitor The phone as its trackpad + ## How it works 1. The APK carries an elementary OS 8 root filesystem as a ~190 MB xz archive diff --git a/docs/img/external-display-monitor.jpg b/docs/img/external-display-monitor.jpg new file mode 100644 index 0000000000000000000000000000000000000000..295386aa89e58bff8eafbd6515d38b4179241418 GIT binary patch literal 164983 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

=4^_w=^EDgiIV9w^Q%F}?EVCi3g@-I| zz~VYExlDVt|07?nABW|K!Dh{Ss!5K(O$V#ss)@Huf++-A7~&H33V3y)gLe>?D$%G; zx-ekv?dC*J5Tp-@P7Jnq5<)IgpV**}qo>CMOGhL|GZGb75#hAQ)2P6v#*W;UB&wo2 zVn##VjIE@d=jpVU0#;JWj>_>H>`aR^voou76QYwTqUsJu)iSEP0ei@h967HeTr zi(CmOYgf*D?4@4Gh*Wql<;7WSCV4~{O`cA1X5WcJSDYXa_!!%4EdM5>y2E=y@9au1 zB|_aJF${}0mfNecE*}t8E$y%^!9-Y_f?U!xsV+nS zBqbUKR~abN3C6w5c=_90Cu5=GI-}g=+GOr4f*%or>pR(P8+0my`>I&dDYkQE+B+77 zMW3O`c6S>uw;}7tGKA4I6zcRn@#X`Fk|m1Y z`G6*G+7?V<(1Ff;+V?oWQ4|KT>ol!ZqnesQ+p?`$xq#$afKrCwBNXeXr)9V&d7-^* zy-|cP^t)8MyR!mN4u_aEBvg z^+yo5eT^0*3SYH@6m!awpmXyZIBG*yY*fQIZ`GDBz}5%+>jJ=X?boQO<`&1bb8deW`|_uOjBH{*fGeUyZqSp&laG!FUiqLFtFt zHp!Zx${U#I!M0nIy)7TY%&zta-0jRHO;uBZ=KadcB77Bzm&kt9=F-g87l=0pmkIXh z@G%qZx~!Km>4DcjW6RJ7V!P7gj&#tRBPI9@nj!H2ChheT`Qv;wH5jSi3*qz&?f8u+ zJZ;_nFyeoULyLru?V(5l#G42qr=)*_@UchalqgDm9oeMX%CP=f-I^Sp(t>JpT3hHIvetnAKScw zcP^sfVhF^85s$C{7N(^sLwXa^)alW6i?n#maE)Ef_3Kt2+A6tEtC?}4<@(Dixw@XH zMrEbb(M~go)Yuopi!`n;57!b^28j;Tj%sw8&6QaQS4tkj+!H}(d6Gs}g_}Cvpa>|U zM$YKQ+cB@%cM60Z7nDV^uX108{~9sV4W-LMkf#J38`5F!cPy4tX+88TvzeHT{#K6X z0}6$l%3c@cTwx|b#+hXOh9_S`(uc_l<6?e>e5|dqBV52m-hj-(y~5j_gBihE+fMzy ziG@8CgypbcQ&SyPwO~E`2Za#1>yi4DIejBUJhgz;w5l^T>lR^0h@2(x$-lXkt5#Q> zgWQ1{0!j%}L6jAHx27`VfPxY?0oe?Tu0PzaqJskBrxs;^3pU;mmL20k;f1S)CVO=Q z!MGd{&jzIcl~uFR#c?&2Re@_kRu)*{}eW%Gxm>4%L7Yy*o(YU-#A6}T1{-xRMrgb7}gYc403xFYc|Ham@ezInyLSd z`fBqrCTH11xSzooo$74xSh=8;16rzO@b9!OVXTQ}=~GqH@``L_uhRClO3cbr<@bse zmgOnlZ-Wzv-+H=t>uFYs4d&{LJ~mf}9FwfY*FLICk{WH&yx(}!eGv8Q#CGH;`OpsF z-}IqZ`gqCY&TLpT6GPIP+l(n`!gZGhiL;>u(ukeS>N4rcvKid~mai zdjVr1b&g+c>mNzM@U0l+yzlkf9FHp zrB2~Zkqn~z1=`Xj{D>t%@kh+0xjB>6?H()UGR40ZG<_HovlqvxQ>28?JEQyd+*=l3 zdDawWm)xnudmwxzsGRjk>g429d$3?}ki;-BQNuppeY zS;`B0O+Q@km%-A?KeXVnrb%Ou@UaTkGdtktGRCVUg6y7@5_EDEc?**IL0x&M;Q#eLI3mRy z5fW$Kh6v&*VQvU9fm4yPiu|*$GF75S+oD4S1$YWfn@WuGnQJgo>PF zcQA1uTJyk3w(2c}TvSP1Af-ugQP+px2J>I42_=#$JBZW)s0L!?*X}u@UK73N7;)58 zNQ5C<`X9{%gfm(Yt8$3dW!BXX^+F;{+I#ApnSrzxx1Qnc@&op&B)g#n=3G&WqN~FpkO5!suk1I!8pbcgq zgBc}=bGi{mn+V%XTFvwTtkJY4Cq(yZmqDe&4f7*<354y|Y98-vv;$gW9PfN+P4tv$$R#yt!h8BFE=~IthX+*(p0R8KM@~m7AFdC5f34F5pD-Zo9tWiGGY+w z&Nh1DDR%0rjF3xL^@>V*R>Zs0L&}s!Kw=CaMDcHl6_hREO&=hE7j3&H&%f?;iupC} zWrX$m@v1S=<^XMlt&ha{1-D+$Pn3xpev{&xW3jFDbx5~=xQ68=>ThJ55ASr6+ZwVb zmM_1x;*rE?O~;Dz73CUZ8tu=KweJT}@i$jjl$+wcPVoX7l<(;{$AQ|QElr&{3O=91+n>nuL$?0HfB$jh2KE#+sYL5l^U`w_&BPB=AR;-s-_)jAkXAE z=3xA?Y|k7u(DN7}Eic^>uS`G3Nl-7nLR?lC%Ob?-o3cOd`u zCVL4MvTW`_-^bSdj%4SUbi%4d>NnlEY-QB~O`A*p8>RUh;xrm*Y*?T3CYIHqqD+-~ zLA>%0%N|HncD63W)@`P!s zYQQ1qV+u9xgs$G8dG~HnGic-qeJH8%VQ_5Quz2{x`T7Pg+lS%Kf>X0^P~s0Va55SL z)m4N=WzSU(fy-C{{iKM(g$cTy!Ss->eBm3dttkos%ZBkZJLix~BH<6zdPwfdIvl3~ zYKiaZ{l@^;g);FJ_>8*9prK5KNNu1(DT3=wKlF>}6xws@7!M=&4(@Mh zIN16KNP5Fli52UY4$BmcO%-U?o)3h6Db^QEYi21M5aqns*I<-9#M@S!OQCI{1X(N8 z4UPD92H1|O(A<=PW^K}_Bl=g!Lgw*lwXUqg@P~%MX!h;-MCsx50hF_cP9pWW$s;LQ@Hj_!JFDmYGgbgCD zdIJYqNsc2?!oK_)IudUb+K;BNhar?^cJ9|7IE@!8Mq%()0HpIo>DsVj82(zYB!>SUCVp1cQ%Gsnet zl^ys*XupM;9PZ9irfwLNv{bm{fd|UnI#)NQIzn)mV)%T?Njq)eSCT0K2)F;`tEz2M z1i%*vuG&NA0HAZifqH|R0(Dhb9#$*15`bLtl&Jd4hh`@E@_*#umr(dnY=n|0SjRCd z<-(V0qrO3ZEAr2OwIDP=1Zo*9hIx@U$U` zFVOp5JXMwH4M48VDP#9bG{6u?CXT!NP~V~C-g!usa|dfr#k)~-kSpczrg!gRYnod8 zFw~~|c0f<@T;;sk3?#q`vbdktfEg`dnXiNC%p`Nc=7^OOX}qGu!sil4J>ap z&go{3Ata$24TCdYN6cLK6$p^D;j?n*=ka#=veo|FOyWihpH^1xrq`htmSltov{Nn= zfjccQB0F%R*rZrou5unZU1Y9Z6>m88LF`;n<4Ca8nPi8B8&#$};3Z&%w_ZbOu!=xU z_4KZ2oXy7O2*y1Vv;@J$S;2PK!{p~HY_|kOzFR5@LzYa=3li=iEZn7!(h_=T!}#y? z+pNG1tkrGgcS}1WbbpVq40k@_wDO&9bD&Oq_qzksg?6qFX(VP@fwE!cSz6F*L0I$4 zQMY6(v4;EAcD-1y0^sr2_*FsfP{GFXF3DtpNpD+uc~JDFTD=v;Xzi!gZQmUJ-s?lN zUY@2*@;)Xf`K)nYTLERzxhm^ZjcqVBr5bKs{#xY zeA58SW1xgW(CZRdAecj4VLuq{*RAU>W&AIx~5=3(NgZE@ZZQI)AAFI9jLq$1FTYxj0L{>B6aLY+!lctx4m zsR(LSR1JTnP<8Mczog3Tw0Q&q(iM+QaG|0Lu)M{-9o<%WT!TeIyS{u zrxH>${D{D#guM$iHAOrKIcA!9PrmRUxe*NtlF$<$F2|dwwy8mLOkJ%Rfn@s&)T#^r zDmSgIhHevIGGR5K?v(^X6*6IGPRc{jXs77?rMt*jxVmfuk8vGakUpiVODX**KXOW8 zMslr5tmg(meQySka{*d7Sin>b6=n)wn-4o+YKc%Wr!Y;&)Omqgv%X?TW>1gb*?`&F za1ULsvlTn>vI>O9ZcB9O8_in589qh*3PA|ADw`#ZFSjNfrKN?j4}HJQf;0|3IfG@F8vo>L2FTf3?cm_J{Le;F0&ntH*7re#3+6;8lpFqcVd#=a5wUvCew0qqyZ({t? zDA!Z*>pv?OHWcTXQxj66Xs<`9Mc{!~Ur?4Eq!zGFcQW3ghc14Q7FxgP9 z9C{jh#t7~grm+QNK|GNwNi)BsDvNH0w+XuWkjI_M3%%q|z$fNn6Zy)b#b%y8pMm~s zvDIdhl-LY(7n%*~^EcBZnlD3xvOTQ}%*BJ;jG!kpBEhV+X)=SBUn_FYR?g&F{!2Ll zbfHpDKnX2~P-vQ&QXyzcH0rkOL1|KsnuQgE!C-g+bY$lC%O49r$H(F8btU?v8zA<> zp03FT>C*x_vBn7A#LdAe$UK%8p--Dn}85@NCTjH%(o2%Xt`k4&Mv> z5zNUH4>IRQ$P*uXq?$=N`AfLd+Eu}H?*h6h{z{4hDm9uZ3$%C&)8m2CtO%7DhK#y8 zmz8os0j>(8PLL|^umsKEGPzLf{H`~p_l=L)0f+v551lYIAgM3U2wZZtq+F@nwZ5xt0Y7KXu+9i z2gJORG8GyMIc0C_UIh37U%W2W?0JW}kG^-_45>qUM-kjK_7p6TC5XezA>6_0SRU)Z z5uqM!dlV?j@1b;eoKA-u4Jw~v%>wL?9KkLJ=Os^v|7_JhNjK52nEL(m_(kiNa@G#( zOOMKy#z!3Hl9yfKX68&}(A|+X-|=JFYq?~zD{1SMZ{b`DuD_+$YFt2Djns{z2tG_} z5M{onYf^D|#v|^eFgHM6&mF3QdJmkYFlmH^bw|_4;E9AnSl?E}AS#?Zx>6!uOH1i* zOC4pNeMLqMr$k<5F@=Te4&`8e-rj?}tRo{aDsDj2J+C{Nqi)me-oD_)b=iJhIg|C} zwtJawLpwcoSieyDrzE!-b4xcV=+rz_8T1KgIgUf>E?Cb>TfT=IKuj}}MrnExy@>m* zQ}9;^mUJ@G+pIkgeu&IR5pa&G1R!EGZJ$=?j*r6Ug$|-UNY~N!oHGN!6&zQ#j|=b7_!&<67nu!HyXyj+2XWX>A%15BjkM3BMew(qDFB z*_sY-GO|OdTviV^zuGRwD_k91ZHrMp4UrqJgxWinN892pX@*2gX9x0AISwmoW-K8q zyanDJ=QFnKasVFFc+*ROQ9{bVrix*E!Ajs9O{hA5hFW$@-8o0FNHN$7B}8y|b-V`H znHsR3B*JW4@|qRYcIm#ByfP?^pSoYh?u8QC7Z(5C z8Xr|ymRA)L|2caz)xj+Npy%>aPJJEg54{=mwhXLxLFOi`0pI_2_P7g}bqk1z%~Sv{vhOjY?bEDD31T;p0hxi8xk^)B5W|XccXu zbA8S8IlJ0BHr+UH$*^Q3jzXz4Vl^b!S1~f^`H!=eNz`5`{xvL1h&($Q{1u$tPG6mq zW-v{@wBl(@4&Wv4t_dL*bHVaNl|zCsPUC=WeTs^{p%%$&S??wK&OHTMnW13M{sX0m z4p@&AE87F(a8)t{^3Xf zAlP>h;jyRGH=2NNX>h)U;9REWOHTx8aA*mV=qudkHbQ7&U*_tH$P+XKXj%#$- ztLnI#Yy8FXzib}Ou%+>%*e)0BX1r`nJqM!@*RWYRQ}F@UNLELEEwQ8(!8N8x6k1UlQGip&^NtF1C4)K8Qeq39 zH}T~c;H|IV=oPfgKnuxHuqrq+M$Mz$^}BcF0Hvzu3`bJI$*t&axHsPIvuZSOf6b)^ z&5Cc==5Q+b!>=Q@)<*GGS2a8nl>~%{q8oOq&qMhlu|po}LvbyD8@;1$C?BLUcp^kQ zAN=D(OP-zpxK*QCZT%N1FycI`jJ*t! zRJt42K;4ukBI6(&3TI=}HOi`Kx+rh*^RCe!H+O)VlG5VnwAD!F1>E)(q(0XahAC=coVys^fbh3dTzx$c|fY)E6!w;%!YANk}*Md8u zti8RVW=-9-mfF#T@l0ns*CWbm?Q>bTUWUxs&Zk_luF}1moe+KVbo1JZI>=d&D4`IqsN)Zt7~RNJY! zzp$*PdjZS2l6Nl;DEIoe;}89mt&yYLLp`}cPJFtU_o#xf794eGXZCpS5+P*c37PZb z$5UXPmpq2nEI_3I0hkpIk#kPu5@Dm8IRY{chOQY(GOkq4R0@>Oy$i=hl;G?SAY}E4 zhk>_uwth!nZP%*x=ZcCHyVKtmZ7zHMAiDBWUDo5Mx#PVxUcXlMj+)7~Ewj=T9qsHb zQVue~>A{>R&|fxGdW0+I2dn_jUE=_?y3%JbV2*+Hj`$@i&horuba*A!XN( zRaaX+o1S=RvT}=U;$TQy_tnm*L!*UFK~YW@x7pG<`ahhBbYGG))==k38k;P+vFCuv zqa0%XyCiDSn3mb!uYKlLJrhMzN?!3JRMT;>otZx3uaDjB2)8=oTWb8RzxlC4(RtI~ zlN^gr_8I=G?3>MLl^@n{U``zR zqKj|w{uN7d2~sTALnf3F8z$u)vNxwzw!Rr=It(T%s0m4 zd>)Hfsk=vn(I?s~f}2*8U&S1W;?`s`jvsDg^;R4qEf0vQ9*cb|%V>%gnN=NU@CEh5 zWgjfRx8PiAmzf&=&1k`@_+_DKV%^q1lU|qI6Q>M(ib{GJeR}G_+_`4lT;FU)o7amJ zm){(fYyAybr^0*cE)w27_z&)Ybe8R$n4uB|uiYdIABs+BX`0*m(s<4E{=^t@SJT=9 zfzt;%=F2`vwSJ2~7kFZBjiG7hXsSd%UR2ZNc0WN=d2!L|mq1>IbHha2%)C3fHN`WT zVto2hpQmN&T}=el8wzlzga&!q4SLN^+2pc!8=INFjx@I()nD$Lx@4n8NaAt(U+gEb z%MUVhj%z2rK?gU-T-(cLSl%zyuj~9tRsQdmv#E*G%Gsfei0gAMJ8dS5n{WR${{FMb zXLDWs+~4Fif+L2%GnPtxbv#zR*ZqA{)v@ejT*#v<&kwy>ebwso1e8@Ck5RHdHfu7- zij@Y~ID?E+xbfi)&h2Rsl_Ml-Yf^iu&B+Y}N3F_bWgZh(d2#hdt=k0`m~obJR!;-@tcNA!1L`aX7lw@k70MT&2b-ZD zqimA52ciF}C`G0r*{+PPB_nHDEn$I@64ilA$?hn*?M4Opz- zsaMKPVDk1O_^G_V&+P9^_CMIp>06nU7rWp#*?6Sj?^g~!Bx0Ifj=SkBCp_9`wVCG+ z)T%Sax*M5i_uA#(thg#;wDz<%nq4{_TsE;P{Dx-P{lZFdVUtHizU=aj&xgO=G8r}) z9gn)obo$O3T_g{xDm8*|6CpqISKbIne>Z2U3n zAE!`m)h~0brcdqrjatN07wua~X}Y*Mzkho!pITOQFVCj<_?f1sHF~ZkD4OL@2=d!o zHKh4Sc59jJ*6~!|14+l?qsks!uWk}nRpsI|T6%v;b#2|-Fmiir4Q@q8r0!QPsGhwtLq*!Er9&3rntV*m2ffByM5uVtFRpBuXmH6Jz|xCm788yM~jow0j436C&3C!z<&f5;PaTmHhl&)PHdNs|DW&;M>A# zP0D+Arrdhj^dH>jM|~gmZf=e4rb`PyYOUbO-0&|)SEYBZK6DN(&9q_Q_OkvCIKM9J zs4Cc_AT)2fjJ*!EJ}7qZ__On0_ZO}mSsQxBD)?vosE&jpE{|BZ=1D}tPrrV;R>KUH zxfx!C{=0z-I;350cKdIfH{%aw|B!AT_vY#3%$eW!#-HRRP+#zZ)~@s(SoB=QwK~FI zQIw1(PVSeU8}e?y_+m8Xa?8BTY&hZh>o6mVb&&EbRq7`?l<`eL5Vf+;?lbYlg8}Tj z8uRiaVTYY=-EIH-rG5Fyf#d}CVxwZdqciUI?u;->*E{{#A30;kyU^$5{ZC2OiZgb< z7t>x(A3%in2A?>apZO|lI)gbF_bNR2=Vo?b^SvwP;^FI;KTmeb8)c7mWZ1Htw=BnU zyOZWwB?GGjo6t=?;u9L;R8RB5COz%rDXEm=?Z+Kj_)yh!CSND4;d%-$}Zjy9M{7-tk6|^jXntlWxY`$-kLH`?sRcS@8^VjiHCQ? z|B;~aSNC6eY21>X)${DU>KIX0)MJtSNp{t#Y{|YCcL#i$Q#MSj&Xn0+Ax12Ep9%bH zA{4VOo!Hj!L{|~VefV=odwRHS%i}8ac<%HhrTNV{*8!f)Q)1Iaa65Z&r8oR!WJF@q+4y)D%Ylw5MxnJe!)YSjLl$iW!#}4Jt zYof9z)9JZ`Z!vxXWYvx0=1>amkOk7sGnSO{%Km zthdbc_WsB^6H&OTlI&-yH~cxdYrp=d^E;>CU0nFLT}E|4%jcuNY%}^T=7rj5|o{c%soQ6hzc>|^#^EG_P`1$_;us~10 zY1~nfMZ&{E4@zGwQ?o`z7YhyY$E_Y;y*o5!i-m^yba{T%{G3tE7YhvX>3q6&4FOFT z3k})tM$u2%N+KlS4rw_DDIN z4MvkoPV&Vr0O?DZb{k3*($eOOg@oDfP6_WuXr*zA5K@E`0q;%}t`<2#D5dj%roWkDIpKD46mwol<%vn-G{*%6TY z)MDU{hOd!5P`TRCo7UHHE?Ku{9SN$pI+Suh$_O3vS*GcT!NI6YWYDSWb`q-Ev85)W zp+c!3eQFidwr6fRss%IO^QhW3>${4z1ZL+WL3J&!mcdinrvA`{`ag0FxBHXsNMxEDO2RU^Nk3IyOl^T7%6P#}tN9j0!9p z8beVeV6h*KId1vuSwZ=y2|3`@@*>qnZHYXwPuJG6n&wGz?4@HImSNC)R5DH&tL)zYyr&0otk=11Z7UgR2UL=JpZtyoxjGamT(p zR#nEMDl>rU%1+Uan|qI8O5K9@+~{Swmq@v{FL2RGD(!fJ1|@O9V0byJ&8(T@Yg8;y zU_5X0A~$WPs6O3mnYz?I(=;>6L)x0x)8wQys21Wwn z6OiYlkUA1SrFC|Cq*|;EGz!908F+_L^z{|X?HW4$oLR}fqZ;I!gZ* zt9gf!+~ifOZEa&;pDKEB&0;B)ln|`T*V?W~kVym0yUHv9!+!~@aqdc$wl@Z#vc_M` z8#|oUWxOs?qKh%JZQOsDtbaB*tmK%opD_OIN&GX9T3ajQ8yF<}jMzyJX8O|Q>^^&% zP|qxi@|Vg6I2|~tKGP&*WN!p#j-s<&-Z*6>h66ZL$Zgoh5A>$B)Qc-bcLY#3wtndE z&#g3t&0}2L3}-m{(uv5dSsdJ~N&~I99FltD)Oynz_TmWGvnU;laz~~;X>x}#zvuhY z{?-7+bCx=sa3aZhB$9_D6i%RegX$}K+88g&uAh4a+p?AsXJnWjpz)u^qE=g)M(<)n zbbV<1NdTHg(r?uRn^{2gBa!%3c1dG9UN=+dREkN(>^7vg9%N(G)0O?|5a4m&(9+~} z%~2@19NSMdb{XPP#{||ozZnLcvXfCLT+%YJr6thZMrj&#RnG+0cK-lFL6a1eN6uPX zmQ$S4wd1kPWzVVFz^-JTB-!_YVUhS&WZp5;pd>5FF&tqRgZP@YPUdc+TeGQKlmN5v z2RS_jP`&YXnQBN$eEApeEF(DldRGOhYxi2L`_5vGKI~z#KBv^x8D;aOjglpd94Xp9 zQht@9q1?(?j>n|kc)!lJQKu-K-=SfEpI?7!<8Jkf$>fq5ZcDSBq!+@De;_M2?GF)n zt>xREB$ZASk8f{!uJb~mBCg;LS%|@Z@D*^Rqp_Uoxo&kfGTWtsuHxB#83s4Ex2`>U zRr`H%TX~~MJhz1g>5PXTFR1sfZtC_63rM!NpK~e(1(ypL_8tEKl~c00yz?#qw`t|M zO@y~mlh%g>^$5+Q(=RUL+6}$RN~|-DrFi=CD>d&nWV~Pj-+0AgTwKMcSS5-%S)Fz$ zR^$`Zu+uN`S9*$fgiku76qAp@_5*0`mjT)3ryj_4-m!eMILK zvDb@fF_JJUL1`kWV!V3S7iX-sy@|NGoUF3~BJ$VgRrd7Htxq3~F726@?F~Ap;IaZ3 z{urd;E`=(Q>UE+rI)hFMeJhzyh!X%7OB6Db!fqq!>s!|TBDT9_jgZGN8Q6LJvDUMd z*5$ zw4P{pINYv{m0|0i-$PfDb#(2ECNZ2ht`fG{J8^53OPCFRwec-wf8h1^I| z0QK~!_DiEQ_N{J@Ls_H4F?9ic_dPzf&)j&i(&fI-9B%+P8?p%=xvot$8%u>?mxv@i zQHczH3{}fpON)e45(dvaI{yHTHBKvWO01s9=*NrXa;lcdoQ=es{#CmUp>KB|?%XVZ zWssglaK}!$wqf?9Hpt8XmR#(~=rS{p#B-!=shYI zm8Dj9a>Y$XAH7nFL^)i)aA3ela7zBa{d$Y{tbxjs0OO8=t9iR~$R?~@UwM&;<6Wzd znEKNsB8{a5_zI`y$>=C)Pz|ApUT_a#{xu!A-4nCR<-`cx@ARmy9a2=oD?^ZeQ-W9e z8Up3_xdI@l0LbJ4gH?RP)84LX!6cXMFhLv;ZBelg2zp@q`kKuwLBa3Rr8}aUv0+&E z%~-Q3_K3rtI#mHC54TEqlWPJA3=aev8n`EBbnW7ONLz?i;VOq4ojz=56xcjpa0nAy zMB}#HsXxxSrqy4AjnV>0X6^V?YdCeuI47U2N`;Y9o!RKxcCT-#FYeoHgRE?M6>pmJ zM7okUStE8wUO`iW4Rm^6iTu2!>ocic!TOMWK9w#l6r`Ivj8TfC2C-#uGabx+m}7(a z8nx#y7$cgJtVy<$ZAAAfhXjn%P1=J3#AkV7%eNY{fs zc&Tz_s4HqeXdLE%p!cX6^+y7cZn@7NojzttiY<9Wbq0-|#*uE~+lQ1W_Nbpyiag=- z_*AJ$l;IRjqstJ z)YIi;-5Z!4c*Q4}gR2U~Hw=54baQ%|R%14|t~!c5#jNDJMeE6?Hlu=e_o=fh-A0j} z0m1%N9o6E(tFVSA^sI-}0+W`@9>c9vy1v{1az=V8^)+fOlH`%8KD1*{OK>{?IjF6* zx%|&FXev7%m5$6m*3W>WfP$MP>`J+m{UaT|wOojfcYB>$__2Jf`6ZZj$KCwuHt|Fg zFbioTd+q}j#?OA!9B`^SD5Z-1hI5t;!9JBLlu=&VOzaz9v{fb2WFs7KbNbaAzY;Me zZKDc5y!@ZaxutXWi6`El<{W1S9=NLIL^-x;wxc!S3pCBQ&`~|eSin}=anrqLMKT8Y zn6D$HERvyO0VIRpr7}s@cG?3HSJ2dhX>b&kApLPw1jS>=9G}XNObH#aKpi%j;vlLa zyh8ZkNT=rfeQR#sXfBRonOS=g)O|;4;9+HKmpB;Dzu{Kxbr@}kMnd2mi4lsptmO`< z)-@K)?Qa-as3n8$>58H+S=&4c%old|BP)1Rp7N*jBdt!5$axPFk5qoOG22qw*67@_ zyp1uvsvDbtXJ%K*lbXwEUOo!7Gwmnvp+j4sbJEP&eM`x=VVn{$25Tv97!pGqp7mN= zoyR91oj~{SMt*4&A3$SheML2{%K{grB$-Y~)oEfJ2g#)KRCMODR$w}k zX~yVdjw+I5b0bVjJt<6p43WpZWgE7}HyVwu9s039Q%{wPnHxf7{C%n3YOmho>sUf& z2ZDb(ah02vVt%HdD7nqSDs|kyoipvQkK?RwH{O%XqmVtJnQH~A=P;JfP=BT=*IH^M zKWKtARa2HyNzG96n<11Cf7m!H{vxc~YBM*;vOWOny+|Fou6CKynjaP1QpkpFsDKq> zfCAo`9X}eH?@71w7s$Si1e~aqO8yxfQeNrc+b#9DA`|z!^Xu#?ybO~<*6ymTer3V$ zQl#UmDaA`hh^5mnB5<1&lhK2Xhw;r?It|y^yxr@#43!}Mgl4T-AGShJgf5GXkI6sK z)-3bMYcqX{=132COW=>EwQQ=+MoyF?x*IYW7%Lu6L+eo&BfU0lLhe!f*+X;uNHh#JXUsmdo9Z|%FRruXhzaz`&+AivW?w`b?E*A!K_o*7jRzmPx zM<^e{$7>J5sZ9mKHYP>~8Ro7tjJ9M-oTIudeWgjll751ZG!fJqsS#itj-Ye&p`=vE zATd*beSWoM7X+i$m(8jTC|nigPv$5W1U3%?wrSX0#p58OcfC><8T!*r;0FhaIYXHj z!+X+(sta;GN9RPB(Z;)(uqfpYV?%hPYlV#oYydmf9Gb(i#7Wnub5!KGnqnGPE$B0W zM<{cfPpb!Dkc{W69+h1#mFFTXNh#xehx5f#`#jAOKTP)Nk?&H)7z?s>Mvg3kI-L3g zMUbw`d!^1@Jjrp8na&T;e_D!X1~8{_C$a)mvHt+jkMgBA3bAdDH9T%HuK<6%d(|eM z?bpl%MhL(-!N;KV6eJfe#EW5xZX{jmFtMj^twiQ~xZYV+5kbnnaxv&CjEcaf7)V@o zUU~GbxG!RRc-`3-9COA9>rH}pFr?Y@vbylt3I}S8u?J|#AoKODd2a0DGCWZSb{QbA z2OaTMVT~^0cFLrrlad#Y&(@xybV9)4aKVc%><-m!^*KJyAy3`LbDh0;?Ny>hmLTzxT}~uS zbC2&2YOB8oX*n6e0*hQOS`z@Qi~%PbPJZn?Kicj>?^RGaW557)HB)LUee(Qt$A3y# zBWYNw2Q8j9j+9tAjX7tIByEv9u~0;^4hZSM>?yW4atYdF7?i6201?8kxvcx|kgBYK zpKtF1oTxs6mLa_uyA%=Q36B1zp~WS3Tx8p_H*~45Q60?8u)Z5%=yA~dR_2p+GMJfO zTRB;oW0N3;9X}DCwTY%&{jHKF+Z!;-0(f!t?OXo<**hj^;S>FyVT*TeOfrL?E&UEg zK7<OEc0Qj+&onGUX!Th7<-5n1DGTu0EK_JRJjo2pK?Mk}~n5Z@_sIzOQvSEzD}t zd&goWyOszH&>!8ag?L!=8UFwb)qAV?FE*-!fzH(x0C|h~I~iJ4+Q1IJhx4fH<1$Q& z>hY4>Lj#N-r{HU;Bayy_l+eyBAW;i&Ng+m0Ju_0;-CCoFQD+Mw0IPsT@9FicGR#s% zjR`DzY z=~%MeU3u~&5#~$su_Kipp2DsoeTvk~q%`fvnb`-R_cZxzE_;ub>S47fc2*>vr1G_^ zrCWWi(XZhq-2AbXZKEI$&yIeXu6bhnL6B}|C^s_>ezj)XQj*q1M|nJ~08sbGPsD%q zyVT7$qAr_B-bMT9MV;8Pidi?L;0WbWj-5gLaZzrcOTLaoWrlRbikUrg+w!QjiJIjg zoR)H+kpBSQT;P6~r_ZbXy3)~QebU*v&m5Tjeevm1qVy@rYuxWNkBF9O^!BN4;I~5ZSzQ?NG7z1}e*@F-uO&A*d<>NX3JK0C^_I1LV;M0>8ZHLMYF6;rL#+dMn{(W8}QHg)G^EUgfA43VTs!tNwxSqj2@&`0r4-M z4)_X^F_dmU`qfei(b&a#Ho#wS=birmPP~swzhqCgI){<1+$5^;vFI3MH2(m!F4Dz- z1F1c$h1C2*FnkFllMTHU$-?>^cH_6_SvPvM-S_-_Ozr^TLBjr3YKwcBy6J3pmwqhM zEe97Kdvx0f-TL&bi_aaiDO)>jgpa=|$sa%~l35jEDYqq#a(jI#g|V8^Qi?K`B23lt zsu?l6<_t$9e}w^Z z!JOlkC)%X5x{4c=mUL+&PnfEZHy*>9q|Br4mLnYGcdZ>oe#>tLoQyJ~&6$AyGthnm z`O^WjUCXKJ238?i+aPCz9lG`vXzDEqm7rrCvUC|_t)ZFR?lzA}_tLjezvmejC zoUji(ughbc{{Z!>T~ZjWbvLrMEg;AnM<;iuzADA_(9x}$8i6cOg$UlVRkUi@dOoXl!FjL?7zO_@$c2o0l{OOzX@~O!6#wqfPn7q=w z(%=oucmNO5w5Pt0PqB*90~_2h%(4%gW_ttcSW(Q$kf$4lKDBxac#Wx%iy4XFV}L)# zl&pszdt%%d2^208FeGlSPE9minVHqlNh^#YCmT<#Q!*0E)MKtY(+S+i135f<)=Db( zHFMI(acQJmMQ*0%5iH~l#oK;6ah}!9Uf5Ypddp~8V+U_shkx#;^*yUkSk#V@rNwHp z7P({!820rw&D&i|W)kW}W-1CnyY8!ZKZbgH)`~hA%0}hY!gzm9`!d}#-7w)78$mts zj-OhuqTSqIUpcy+)&RWB3CIeS%>;(3XP7FiIWR>wH3u<`e9Z;7A1V|PTiwAFn5Lgo_fG|X2d zfB@-_@utlsx7%1-M{(rF+Z`of7_jssvHa_u()BCtCE<|n`!nRKK6W>*Jq>qoTWH=T zh+RcD*)IqR#~?OG_m@2VMLNquXiHMmbKKi$F*;BEqo+R-EQz?l-i$hd=te4pdZpHy zs>04n2g zYg4zGY;51_S5e%)qiGrY9rA^{wQre0@1EH`LF<~OtUUMHYh1y6(>6qMMqB4~=r<1J ze|U8i+f6`Q?nOxUOT)zDcwwHyr94j%x?8<1TGDkVHu7?ef7oNkBlu6@n${DuGMp~0 za+aN{O3@p63vXZHJ?hWe{L~v;h2RhVwNI&7+iLc5>sAW!T*fmjS^KOyQM zG3iz%j_qSxsNj?A&C0$q57!+&l~-Lzv*<`=RXNT+wQAiX+Rt*bae@Fi7&VSAW)gXd zPT}7f#WAIM7_+e~PI66EiMg#4zNK=gB2jM<TwI*xG4m=fQ~3LJttsx!rTk9r8Yf&f z-kIo6)1@MpnO5)4dzk|uFB*dTdT=__LDiHD;OD(r)g`vtKFUZlV6Yqv4xChT+rjoF zniAqgz;rz0)X)i$`L2f<#y#p)ykQ!GgBjtf1t}yPowBbWo{T*{wHD%Wl5jhEQDC{G z@Uwq-<5s4RAa8=Pn0>0aXB?0m+M*Sa;Nx{@HwOx%qC^ol>>^N zQn`_(zdp4bgLPE?(Fy@*&N^ff#W}SoLKYcf25>vlvmY{Kg&cOxDyw&@qg5;vEFcs8 z<4zj9NJp6w$8ryPc9&v(-sP~krvzi`RPHtVNH~d1$J>GV(_6$!EyRlt%y`;bm83hx zbuyKK_^FZ&KktQqi1A;nIuw2-hAq*;^ z_k!PfxX1qhuBsc-07dzgPdVsM)6%Lf*;t+?`H_Y&dm3mVO1hDQ@}FZxg65QW%)5(i zJGmGY5t!if$*OzK3laylCz@NF9CXbV3zxj&00FWoM2FWkNo3=bPZJDMuw1-n7*J16 zzgm1`Ty6qF0t}1~ylX$r9P?7!-Id;e?gdB#-irycc&Bt>^Dtj()U_pXI!ZwuFn>D2 z%ae_*$2^L;YV$?ZFi!a#P?8uz5u2jkTR5D-19~<`{MdqnXdeWSq zz*RJnJk6F`;z@WVn9{2>19OsvyHrqJO5Y@DoujB3HC^Qn#o3wI`teG^a?F>HAlg{% z9kWgIvM@_vbmpOgC%ABkGJBKIR*X7$je|)be0BqhEGv^)th-QoCu<%Xp{+q{=O>mx zEC&RRYdUL_3`MsP2jx^BSf6$T>{sc?p{7!jGzI16nIkMWEPx(VoR7%WsJu`Q%Xwst z{@iD2{{RZ-p6%X3;hBN##*@uyq*Mq2CxD|Fsc=jcMvl349X@ajS1%boR#oZv)VoPt z$jc)7q0i~oxdx5mI3-wn9+as(iy$$(DfQihLXT!QQ@T2Hdk{N8B>DafmF^;zZ!2k|>8kQS`--!rNe~TxN z%CnF&0#u#jwtCbLs0CuO0uQZc$$b&g?Jc>~L#g=X(>H&GYxE37pa*gyfO+tz#6oF_iDIp%v}K>cJK`7Z}Pe(T~HLvtw_k z!7{bXo_gbuxllfx>oFxjKKC?_c^K$V;Cj@w-iWBU$5w7#%Wn$#wzIdFoO9GvcKWN& z2uYD-T%6=%1J@$41=_eOSO8CYv2UnbL<+N#2*IdythO{&Q+t{c03|ZU%u{J3u;^-% zToqSb0vL0elHXH>P79C3)rR{#spi{=%XZIW?~1t8Ye}Oy(o)t8rh(iYsK?%sS9#i4 z15wYb%LIlwt(h2m_4lgBR1U?wwj_^GF!~wA6}SQvV#BJAN&24ESIj9l?-Uu&3lRPR{HjFO zRGqt4KVU(})Y8SM*dc6f1oB%M&*EuVcSKD&!|o-9erF58_6O7X)Dk;|$YHgIMXPrj zjjI*i5|TO>BagsUNFqzQ3pAG(CpZffcnkQR1r{C0J=BtO95;cusg6{{SlQJSXERGHoxy zNZATl@w^Vi_9OUP@H}+$#db#ytV0e#6)K!4loCpuFwg5zT8w6_%A<&tIb9xusljBD zUS3&DlZ=^_3Bf2y-i3QGC-SC8t;Icumo{aKBWyApOBv*3H-4XA!noTlNuk`*xsfsz zqbHVA*9NyW7*hS?zKU0t#$;HYM#lSh9RmUU`_~+(a_J+`jw72`lU<~ij4ogaFjdJ1 zuHW&e+g-tTADarOJ;nw>_o!f)NXFjf(krO`U%UcJF~>atBanI@uT`{bSf%o1iBdvv zAE5`()zfWztj@Gk_o6cFOB_2y!Y#+LjicCmRg3B3NO&={l5?;f#Yd|i=kygpyuyPjZ~@!&>T5))X1vk9%Q6-a zKKR`iu6l#*?^yClPUh;QTrJd_O}T=5ce9x6ibL`ed5w>6b#<+*O$#K1nmoG4zVp^dz$ z7FWxaGlHymEL%G=GnnsP|AUc&K1B2HG zrD{fyX;HAd32`wYmfs(AQK7M)+YE}+oUsBa=?B|^6$PDs1FLK=A z`YmBJrc%u8%DVxxB;0o3~nW~+9WQpO-wSRp`& zq<&`}^vj#L_8V(m-bp!UVTPH#Pq(0`M1%|+jP|QCxX>~IazGucR(FCuCr@BNpUihF z+^%t-(y|@d&H$y$07GX4V~KVo+pnYhe2X2r9pwK22m_o_c%M;&SG$d^ z(p*NkW^hJ(@H>5L8_Z=ZkKs8P8Ro3Zs$X3R1I|Lp_rfS$-&|D23Of}lj$4a8)b}eA zO(x}wg#cg=py^JD+9?cRh6B2sgH_{=iS<5}(Ae8UY=CfE8@J;>Ph!ha=F6mGmopVMe9l^+>Li z=4$}lsUO6d>OHD09`{DQR92qnO1n|S!OKUU*&SEv4k@~ZnWYbiaw^=f zxe7Mek#%@w-qS}FtB>MA@-X%0vhHs5NhMX9DIB-nlHUpk;CTG1&CA5>Ev^DXGOx=j z9LFfe0SD05G@5jAN##gNZW)dHXWps}HD*Ob)~MN*^1|K)Hn(z0a0iy~5Z{RvPUBaQ z+wX=MP#z47ybq;U(ytp&x&g7WQMJ2m=dDYu-@KDGnIy!d76YpuxX)_ZD#j9bC`WKN zv$VN(1#)@DdYTw3H^`e;w>i(fLSh4uKD^btNY&)pSwRCJ9*5e7>`GU58mvV81V|Q#G4KZA-$WfVk zkVv2{Nh1jzoG#p);C3_&P!|Yfk_i@AoTH)0VbmJ8CH%KG?F+K`VYe(`U?J{T(0hB; zOlFK?lS5Kqcs)%>vJs8h_B6rB=BHVg?2QAiNNwoeo}=kNCP{B}@f^n4&)!qfg=s+1 z+{QL8*W5Az`=i(1u?GhttlLY5A2C)P2%^DrZK6hI1(%bR2Bb1a2nxgv++Z5SmEgocmE= zxUTs*t2R@JUk<#tL*A+oN#c;HW0G=c3!0ZVv6z@Fj2Mg!y+vi`X#3b0{OPTLMI#@S zP!}3s){}PPK|E5GBaBl*^GJ6d8;}QD7?X~A@M(Z;VNd=Zy$u!%k(R;7dXVH|qh6Gt8B4q;?`K$}72oS#}nW4CItvn8OY#zR7Q0z@`3;u^`v4+C$#}_?IunINYOkoB#Z~o z$T_HEAux7=LC-zvWB#b^Y^gtRo>$(G?pTWP)T<0Q9aXs>g+57z#^CZg@saa!`Bemw zk%0%0c&VguFb%K<&n0OjChxeN%7dSA(yl{q3dXWdE&`FB6XpEsisYV6S&HIFRANTJ z=(#jlE?$;pYeFoDIN*gGfmuMdao)6}yo}(yY8R=;1y8RXjai;JCs64c8G4NO{HcgY zJewPHC(OkCrE?(jwJpRyNLWLs@Ob?j^dTZ*1$O(L8oGFT7uwXYkqYv?;>r; z#ADK^gHuB`z;mC%lZi@Q%ZqT5{{XE}PxpYqr;y3aXL_Gc@T!7Eax=qv)RDVJatZp1 zRG&@u~#&(jo~Q{1H{wlyy` zSZ87plpnfZndvM!^R?^V*aKQVtG!^rlU~jGj2BBIJ)jN`SHBIqqp&&|m>T z(3vc74Gi0c3uF#4=}awwl13?mb~gdWaX>adZb>}_KdIxN>rs+%&!tLsuF|CE895z2 zs00cy8#txASna`#I?C;W3iMI_H490SK>X>k#khb+6j&SRHB_=m3ssJcr@4`7sz1* ziIf(P(YuwU)2^dv-%q?dVUV4y!FZMUDLWSt7gJr3Fj*A}m|XnB86YX{I*fL# z-?TVkyuQ$Okb3<&sWlxwT{)DOSrGl%Q=vYeT8GbBLko~YxBRunPt=b80AJ@qiW`&a zZt1u0B!6d`aV!#ifRlz9?V8iKwH7vw1WZX>k&%O+dgWsx(UshJ*3a^@MsPl$_C4@% zTDLd%HnEuIc9mnsB#hyT_9xToGCgV>dlwm^zO!PnDovJVf4?R;7$4NuOBo3P_hm*v zJm6PNG|*mYb2M|4wR7_UxqUN_<|~(Lw_@dvUO|G#u=Evh)fv>XcO0#RJoTj$h`{T} z!NI|(M1?>g;UM<*HMie&8@K2W~g0fs$3p49o#Rz^jWda2qQ*XdC(LH9`~)`T|3 z?a9qLIbJzLidZ-~2i}?mC_RAuXkxgG#FE72iODn!C=A@1kSImVQ!pKi8dm{T3!Tnz zJt|PaQxy|R1}b>Gn3PL$3n}}tslj9FeFY|pOkhWw?)<6`%;$hV&!tAV`_W+L9?}!ikVpp{=9qXCp>vKYisRY&z#}HLyhm{qQQ7Ix zP39%Ee>n#uasL1(^Q^$D3~4G!8_4+^al2sY&U^Y)DHBL=qd4o%0Q_i3e9Vk)W9wTM zx-?ett=6k4f-}m*Kh{b3b`@4Ti0pQ>8)Tomk@Baq`}@^t=aS+>Eb=sxH&$cK0=c88 zYm!_?_G>uBt*GN-a9iqYEHFj~3iv;Cjz1bQSa2{sX#mek0_4(NOLHie;O;oU-~b1p z1Ar<`>OjH%n5yAVzI{zUr@8A=#+fiXv7VIj+d%2~cBpsv86Kv9N#x}EE-6^6mSF{s zNX9=}u+nEZ>*!5aSvkoRj`_){YV5S^ja??zJL}lN-T?WDPN0r@_N|W*-NzM!M$5d+ zc7Pin%DJmOVA$HukuUFMAZ{b&RUg)C%`6Mp=ON ztuGRIp8o*FdXM&&qvU;~%UHj29>v z#E$syRcDoj%#KQyE=eiEo_epfSTToP%Hgs3)O!{eG8ooQINg#I(u-Y7kzVPA)IUEi zIn8ElIjs;FlfW50yH$Bt6A@d}cF^aluc;-!&VYl4TG`WeyW0q{1;fM--cic8)lUYo zRBUkS*dnwppq|*NxQL)(m2Bl$dV)AL6G@j&OwoJ$8^!+sNwzkVANg%;GZFfyZ}x(*u}CJfW*s(RUxC4dX+s7;0Orb;$O}HO|G6xD00_tz3#niG;B` zsRyVyVffQ(+Y+UH%eK(kODdNt88852f*5+$OQ>132}}H(=W*^T$J)~BZ!+}DIoplO zz%cjpKaEULB}ELv@;vlhtc&=6`s$-AXiSy%GPq|fN6YLg%n#&Bu42lLcDUHj zG)M2U0 z<2;OytriuIAlLi zdKxS{l01H1H!v;eDYav4S3tZUyO07}KDqi;Uz=!RK3wBI^u#;qP8bx5q4Bq`ah`ET z2^`P@jAt~5siOzErNJZ6ezbz)Sb#e7NX$6xO_3O9gMrO7at>+OE(~+{)LY5rwzteFaA&gg?@Y0Od^c+M<#`4gt+Ifm{)TQU+{eIUbaXxjgpyL2(-v zL&I^6tx$}q;NaA-%+R*w!3Ty@(TAa?x(-ZWmGnJD0s`gOvFd#VJx)ONsE4IE9CV;p zCJoPD%B6}%jQ;Jyax$&c>MFkB^!KGFpIQRto9lcxoTG;Oz;p-vDzq-py1Mo?Zqnsh ze$OzPll-`bGwNw))cRrM6+8>0ksgNlt z<12vb`3`*m$MvrbW>xRM;CgQZOR=~vQIz5LF2LcGXFl9iNp}RHPWBsyc|*t7(y*G< zlGIG4nTZ(&Gk`(pa7X8gjb~)SMxmAQlzeXh9Gr2~9@R@TuibsbybUhK_`J7fz?2c3 z0u-E_6a6Wo^4zl`&ZU%Oj(U3gel?MCJXY5sqa&vBALYRAPk+lb9H!#gM4J@DCvZ0r z?hjw*RI^(CLH(ad-4n#XktYCd&N#=`gDgriWF6}V_pzhRK`sjgC#V&Ta6HJ# zK+dYC5fPBB-GLl|L;06VOsMX50hM6IM&90{pZ2w0%li3?`!=6;ZiynpFqSj4fKK7T zH6djLe8@P?cMM{==JL#cGb!|puGTH6RSU2K~gwg&3&GZ1axC)7Oe}OLAe2<%f3!CIQQF z+>VDIg+J|y{{Si%_G~+|bRF2i$tMGzr_zSNZG?^9ndZ6sd#Qv3zWI7 z+Hi1lgIx6U{hC#mArvuCReyFn^y&R7U$lX~FsdF`#sS*Q2q$+x&oy7#&-p(P{?1>` z_#2?$^e6D7!8`>&m2>TPaR%9-Oq_k(9gey7@7j=E%p{r(?Bo#UHIoEmt_d9}{{U-$ zck%xKfG_Ot?|uhEwY>=ZDL!HMfv#p7hn-~Lf~-Jxe6+*RgM*RBPfC%m-ZQzLU{|Rd zhTQskqqvif0ywW_H+JYw9y9XSq$L;>klf}D_q(?pjU(Y+HqUU}bnlvLG>!fccnLV!Gkp-b z&nG96260*z+JacbKz5bNfD?_Q9`(x&Q&C4i^BE(Lu^CVgatHbEPLEuiP8}T)LkyNs zFsD4{*NjvC)u#T-7xsMDQ=&uVGTz)b%+0xBQOWxH3XQL)p5U^mX&mqZ^Yj&h+QidJ z!acrWP5%Hg@J~Je0HMVtzQ21Ns!IV?lz?}H!RNO_n~fNuTe z(NIbrfc_l?Wi)b@238RU=bpIwR%iC!E;3*YbCP#tsXagabT+ISUCkL{$2n|}e!b{f zr5`YO3cb;&P)Zt1?1^|>kGy}zq9K(7u{`t!s6Mb|xL-5o1P}lmueV+WJNr@>kh8L$ z?Up5~)@eh}?j_(V`F-YuWpW94o@_Y|>eFf&IX zjhftyu@VgD(~gyEGQ;=$33wXai--?nQzNR8(~73Iu}aKcB#2{n0)hwNIi`!KS+FKh zr=dU8RV>2}{?NXsS$&e(lziNbRAIgIQ7n)-P$x~qk%N#y9<;2Wapoc8BL}To#n69k z8N5AjZ1rkRXgP&cJvcwGP+*>vQc*D%||7$F)~7?j)Uuw1kX((M;Xw zDZJ;QAB87h{=EXY{NRFl_NTP$$`thMpkNQeq35a1E)4)Uu{5f?j#%QD7!Om5aXrrm z(t(O_-%3#+QGhx1^riytaDcJ&12r2F$N9|`3z9PyJ#&h5Y)Z2cl^uPmC6fmv40l}h zr%5|VHjFBD3cLzd3zh}=iV++Tq;7uv0LVZ$zo+JN^v_Sis^=#p;*&JxLU}w6^Z=?r zIizMBfg$c z)~0OHO&jfz8X|c+#t-F8la?gplTn^eJX00NmKhl6DTjlTNw}T` zDEegj&?|~EPt0lKf!F~_g$E>xOmF9rQ*od!T;O!4h8sfDG7wS>pPRJ}@P4Kzru+#H1zj7y9Ih4udc3XgEl&B>%Pobk;8an65*MK}c* z;Qs(RkCHL`sjqVsEAu)a9oeypVRAw<)Z^NmtH?R#vTi(4rP@0wxM@m^lM)vg`i?6y zP2qLQE#EvV0IZkw9=;}xgd8ruQKoi_`eix z0_hH`jOXo2**&-ej@6vs7HPi^2<|b(a&e?Y?`Pk+PUi!1KPQXEkscph#4LQ!jZq`$@=vERMdGTA>KbK65C5J3V7&yXNp|S>NJ+d{{Z|f zzYsfMTw4}B0f9&5M7})n7upGVLa-R}f&vdY&%dQ(EHMRn9u^-dVpHcvUrZ5^QNtJd zJi;cDHw+5$SLOBV){kf|M09`fvGr9%V)pDx@*@}^ob&`9pOsioiF&I-1XF;lN|^l6 z2Tr7IA-!|OanT6b%#x&$f(cfPpS}3zopl-}AIwl$F|?3a{xqL!v8bcF9}#C*Qg1yJ zs(i?HF?J{TfWa8{siOFecPwo(T-$jlLOQzO=lk6{cK7<%pUl!IFqABEtfg?u2TbRu zw@QH)RFT#V<@58#0KvymfO+PpmD}QFJ9a%zFNl{#&@>iCCm?T4!~@rnoUhlBP{r{! z`Z}d*MvRHwo+~gS9Td>Vb4y+rnT4F2;@Sm zx<>@c%3CA2Bhs3cWwW@NgXnw2dZwQ~1b2}ZU`SRwNdu_>)bPGQDCpqy!&ia9sD=H+ zu)#EJHpd`i9(nB9`F|?akHuFO%+SJI1VRJv+C4COgP%}GO0TR{T3IrEj8AM?0~`h! z^ry499a&Fm@(1ya-L$dD#z|G;8^&>ip4?|Or3a4TlG-UJDzP~ulFDLX#xMsX@u_&p zt$9BY`vu(ee>BI*ZKL0%W$J!C@TH2n+-eH9N~HOA!_8JBw;yz$t}Bta*0jAtPf4#; zjAVvBRHg9!I0v_0D!kfuizwR}TX>YKv&kBO%6aTRN?+P5`C1p%Uvby}02r8ge_+x` z2PK-~Pvy3-EGwb^>H(F%W&YAfElJvC}+drRq)P zlO?32kg?B?o7@q{=Zf>R+#K7o#5Qr|`B*ETpa6sGRN~vG-aP09q@=eVYbaOr>T(ai zsiz!N*1+h&?vHI&$OJGd!>Bm~QtlqLY0qN_Sv4DxMPz}Qd@z|dES}vCQEzC7XEuHn`I?( zvH4PaGW89|UX{|@d_?fg#ufD>frtkZa6d7{YOxV}5$u}W=+Lq-U~olDBtY2-@{#i< zcr}DPVd3Hl8r6XV{+fzU_)R=GM;hIU{{Xg?TrxcQL-+Rau|G!Fy7S&Bd%!cKo4~&<$C%N+)@F_qjoV% zy+Z}a+(vOgg~bAyB*`3RMn53xM>MZIaVoPo3g-a!q%u%x*{GI8e3WHu9B_J5!*=zi zgj!Y?C=revbSJ;HMpU68h6t#cmNB`APzNN`hUzwt5;(va4b;#AgNk@HU+obRN0_-7 z&px#vl~oIt0dbuBQv=M?Pln1cOzjbJGL8UO$I_;n+{WSI1~`ZWf~V#81P^+(aizmF zi?JMee2|Z@p8a#r<44&!kIgd4o=0yi9)M$-`5t6@SJ2FY!sg!QSe@or<|T*984rJ$ zb^Lg#E}(C~&G7J)>jz^&*2iKF@t`9Ce#?fv)8HnYFzo+u2i&$fTp^P+6I8`|Z zzBZ1B+)(70)XeLM%GoGsgFgT|s9;IsAbNc%4Xp5NgY63r2It^y$F@&DgVvJ^AOo9MS4Nc2E$;E<$;1XPrjIaB@KG2@HrH_GcOY>iD2d{k z%bqjSIpYSLw(8NCXCcew)+8K#GuuCvJ>j|v%N@K-q^c=9j(d#yWAdhL5!$P;3$T_r zB=S3hkU;%8qoBElTcC7)%+Tk{w_EI`=>sMJ_)6Nmd zQFwTVZ1M;l$GFdWiDHWB-zx8r0LF8-Ju~&8TXr`h38IcN#U{CIZBhhfw{z@y_WpF} z;J0K+L&jCIqY;o7oM8Lsx4l{01bJZ|G7f*dcms}^#Ufk75`~RRWk&J=a@ag^pVpPo zb26vd?a?GMJB1CgU6X#(+i!okmRxDsIJBJ*cb?SXFigTa`E|LPJf)zPd2lV_s>cR76x_4EP)y`LN0|V1N zzK8RvWNCbtcDF6K{KO~CfI8#w{{ZXKxcSN=Am(UgPn8%Z=Hr9M2R%pYQoK%ufeen3 z;FZY_j{g9bKU$DU8mVtBmGjDD1cEp@=xN4vTmj}411rXIJu&!EadQxj!CDyiwi6(n zu_x0f^r>gISzz3;Ae1Np9d~5)Ak*WzPcMG&FoHqHPI=&t{{Z1nS>fF3UH))fd2Nyp zUPo{1Q*rYZ!hnd;CNMG1NyzV>)UC0A*|@nm2N)Owlk93^G^R9h<+N&m3-5ujC!mMp;Fw^qk+dv&EKr9MeRuI>PD;yuCj`sb}#j_Ol6 z@{$rH&cmFZzM1s?l!~tM0wIl-KvqGyl#bj1p5FcG`G+tWievZc5D%G|vCeUyr}e1- zbpHTY5UAib1{%NO8I_1^9DKkYrlnDIlQ0`hEP2WtjyU7ep}DzlHI{R= z0nSWBhX>RSzgnaw!boI}JU;ENyb{N6u7A(10J}-IGbv@k`H#vyai3a}VRg7XW;XeD zah`G82aePTF3Dje2uh8>qy6*O9X*FVDwB2%1h{Oe^Jo2O$wdVP+O?x&JBG0PgO5w!X?dLK%aF6M0ckw&{tKK6HgIj&&q z*QJDiXNSyD_Y`u#4_|LWD3e^iiGVxIJHh#449d9a(+5A&txmGqUx_X>o~|cT4xofK z<=MFHIDftQe=30LYN`rbqvxnu4<7l)O2=JFXx(njw*-Fh?Bo9c9qF9sk=m6tDbipT z6`2?|A8t;4uztNMtVMP9n59OK@|vltsYQ0OlLTkvmm?mz#Z4Zi1EJe(GL{?z$)YMutG>JNb?$;qM zr*qY#x*)J1@*A(O{{UK?zuGh06tuLx#EsFIo=;xD3e`@hSwFnZs(mB)9gp_BfHQd! zU=T1{o_o}btTyg!<5eW`9Gw1@$GyjhX55Pe#HiZARF(h_e@@j}VXwGUl;0xoFmgZ7 zS`_L%=lF%7wvXU;a_g`{cRHe}^^kB!UfHN0#u`j&42LJu7A}7t1#wNIUuSB!3+2ab2~(6Lvj)#_4nXWq zI5k60@YJPD;(2h3m{<{(^;Sd3Jw-C!(rKPpz;P4glZ@lhc?6H4&*50ST$|Ec8Y&U% z6LCC3mj&5iL>3>sqN%T3wx)U zFSJB9u|P?FameU+?be9ln%WjmvWW|m<)S9|$On2X*3V+IKHmFNXVYX%w zh4~4|Vx9KCtXa%e;#5@&xo`ty`{0590M@F> z;tfHh21|>?k0&BMrPm$s2R^>_rm2*aeUehowl^|IkU-}nf=T-HsAtimirQO|Ffuz0 zyW%8;9k6RfjFVQAC+g8o=@}Oq-SROJUz>$>1T2M^gZU1BF-;nSI1h|8 zf>(~ijEwa-scs>+GMJ%x-aVU^Ga)MHpu&;}KTqXTiy5x%)wUBHcvX=RvZK1N?kSfR z2H7DnO9M<7c~Ic+eMdq1RH=7kBeu6mSUgU~P@gnLMq=Q5V~?Sz?sQ=kWlS=8jHQkN z0Q18PV~(JM(zGr-KP9Y2bhL_X;BA#<4dpS%P(aRoMNF2L>``PhNpgNvkr*jla&iYJ zA6{xzPN|h{=2TY8f$h>;CBUckbTEmi6XYTNiM{UE%yK+OdfOhN%iM~aYwWZ7|OESGCTqz z#Aj--bt*dWa(Nw&IHGBmH<92a(sa&PZXACPBPub)Y#R`;J;WCVHI7Z&3jD)Ad!Xsh zQPQi8E)em^E&@d4e2&3} zkuuqg7sx>QPC)g?u;kX|#fm{ALm-XIoW>9hz-K(1W4%KivrY3)3}}&zd2Fhy$G%A9 z5B{|!RWuec($+?AE@aN^o#?^HBh+^Kd()QPL=1}@!HM}@eo#h!_6htk_}00FS>9M} zEf^`ppvVi91Ym=akEk_Tdkc2B*&K}o>GMEmbISJH=zXe{OYRma$7vgfNZMAp0DO{Q zu6z8%dQv`@J z5_rc4IjaJ~;@%~Z2b349MhRBQz{t;DduFdKgrrAoUN_na58e3n1ZNoZ$fSzS_SPv9 zQ8c1L0!bW-L|~q92t8VyI^<%P zI=#kMwTk9B7$M$aWoOKrj{x<~2>@rcO%#y`Lq+?gGHzJpR@i@tF6>dsF~pjiVb?jxfWs52g>bX5me(Mx@cX2CD_@pb}fnGp{6fO!I-?(+8z8Z8pyK z5JV`dcVrF-Zogg#tQe!3OMkO8sM4!!Dy&(TpTwSnrCW8ox0A~G7GQy+%VW(@2_R;n z)3f(kT;0dq_+|-RgjX?iEFzV8KziVgrn9bmJ*dYViMA;sAh2z`fDdES@I9+SOWFL- zB&J=k$O_|gXX(!#l_1xIW!cu^Eu>@1JAwdkc>|7ryei`=i_A{U<*zj9qk>6hu~_6r z0i8oHZlzBcKA_fYjks>uV<(&pfse}(Zs17@v*>?Rmg659^G;Ls;$+&mvaTX z$!e(5F5RkdtTWR-m8>x>Xwed;dGgJ)U@GK}4>W{2j`{bgTIyYgY_e_0KX~AurEa%}%DNQ=UyvCF;C%sJJ7fF}QkPAYQ0})V1`gA~ z!93s*&ppL8S}c5)DJ}iVv2QfEBW_%71KXdaZ)w+t^4W}}I1Y+JU^#r@cJcN4eJY5w zhE)+f033n2M=khpPvKY4+i5pQ_Peo^GQ`~m7##DDPI==sok=I9wKS&e^?Dn}T-5Dj z7L(sx2a$_5*Tj*9Jqrws@s2v;w&3`JLPU*f3m!K!Fv;{M7|tt+5;V8}0A#pi%gpjd zW5_$)l2?vde!VI9d7$#ATXfoXnc(}S$mA3BtfNwJ>S-uKT@Ln79my1iDXgMa!Rq9L z#(Ltbx5OpR(`bO;9ByIykzBMBwTk(%v`H8z%~eGkiuB}+a8FJud2ZyNHy%Pd6OhQ* z+6eBv56-D#>KQydPLaHRISFj8Mluz_$Lmnb@gX9{`)HRuVWc19T-w{j<(d}_8Ajf4 zr+>J?>)Y0#xPb%?Vv0SnF45-3bB|&VeCDb+sWwEY`5k;dK9+y=R*^}8oTPw^Q-_Z( zLKF5#20OHXR}%0QKw^f>t~W-(*a!CMfmCFI?YAHsVj~+vZ{+p_k_XnUSCi^5W|u?J z$BnL;R!_1-5wnAmXm1-~Rx@b9R_ALvE|VCnt(O;b1;?pRt3}88yOP>Cwu8 zt>zLD!vQeHeTe|pbhhq_$H|%18*32jkbOJVMyEI0GI49{o{rxTrB)!DKS7Lx`qYc# z`5a|rv-&du{cFowWKu`jrX@yLlC?d7isvI?M!^fUfhMWRrG8*hZ|tMfzu`5!aCRGB znHx%Bm0Z~70O3{ts@dVwFd!7$^Nw>YC6~?ZM8x> zZRAqtpMS(X-p5ed=C-^IM&oxPYnqw&Yy^Gt+1_ zmv1~*ECSpD>V69HCAh=ojAUR;nwb0F8=^K0Fp3z8d0jd zw)q-h-lQ7Ime%^&vn#A%b<2VIjMP%!#T1()zqj4lM2q~vtrj9^he`(My2_v59i!ah zo%V*20&iwj=r?g()9Y4|?rAj}Q-SwM%YK07sV|Hy0b{yT{_JNawT>ch?3qfG7uq{D zk)!BYL8ptkP>f2$9Wr`X5&r-Qv`dg6yV|~>e~n0A3{!k5-QI zZq_iwLQ8K5;28YC6n-^Q@Wl$Wi*;m$xhigPpP}NcHLsqa83@S!ByZ{}1kp<$n)Bu9 zf}sBZHLsFWj_sb?Ph^II^2eNQ+NYreKOF$4T1=BbBfQgYZ9=%)f+XF?C*{u{jai3D zf+Q&`$8e-={oqsmD18dhj6{5}Ix4b(pI(%`q7GJwBDuG|WB!FRI-k4G;lcK%OQ=T; z`Lb4aZJ?_o<$3A}+rbrQ`#MLj7IjBX6dnl8TK&xXRp?+ois89B|z*!Mju{9R&73XCI0}l zOAkR5Tzhq))l5x0Y()+CoJ&n+(GD0PAQl<^FMm$eSZW|oByXl(&lzk9H=-PM`A9$E z(yiinNdEvxc{bxQszeF>Y2I;WVcR;s#;AWZ4L@xh4$;8&Yc0Y+qtbIQVGhWYx}Y4MtgeF zNn>vtd5dm=`!Ik5`HCg7ie@ssv~KJ$S>qdz<43kb=_3Xonf`uiUoz`X=Al6 zPaB>vn@Al=$jw)o;b?ZXypqY-#GrtEF`Rn!tIcWUhIX-0yOKf-XWp2WR_H?u2;(E6 z5Rd6q?a@4?5vkh5N81%3jgHk>kyJ7IlfnEdNal|AQd3Hp#;u*vx;937o_cruD*IVQ zF4weDyB|E`KDns# z9lj5eS@;Yd1`?qE0Dzu<3e!{(o-7L=QIGMdOmep()^!7}+|u^p%j9E8d!$JOu93Th zA)7HX6+H(Z{qcHlV}b!n_wSY zcCD7PxGYZA+v>kJ=}r3;$#0k+<;UYk)-AaCA7c%54Lb5dv0FoONdcBALD|PAsLwsV zwDEaqX)3duGJ%L+pXSLK?nuYirEGnUd}4G70e25VdiquGvfQvB>FT)WC(GyB zkFqMR1ONhZaIuh0SJo2To=4cKZ=;Z`w%TlRMnBibBb8+xNyj6O`Kv9cDGXOjkmQg& z+%E1o11F#5%{{c>?Axs4JJ$y>q226oX+FyFg$ZuJ0k?%-J-X8R%vkv!V>ahm4x3j> zYdkO>V};-!y~j)w#Y_FE7**e+tf|6>jq!n=zyW|N<7u(Ywl}m_Rp<<8K>R8H0NKeL zoBqrR{_{o&`evWjU>?pzNp(%5(&;$!?7v?cQ6)Hs{n+n@x)Nc3i@a|KLetcAeR*6EX)8?~wB~_(_l`Ypf2OsB(w)#{OWlfxCCnOlbA6!y4i5$_Y zNo{Q)Q^x4P$I`FsFzQDnx)hgJ0@Zu3lU5?Bv8NAZJ7B@ zBEcC|2{3KS>`y|YryO(ZR&DiFxk+RYM6twIpEG_yI41+2Ox4uVQWPdT2!`e41w8#S zYBtlO0i0>E$0jfvW)D4cgGu5cYamd4N=vOyZwft(fG|5E`>e`OC*~lJ#0s8mQSIYY zmcrxbZR5+4w(tSN5_mX2{d$gVA{nLMEsQcse~2L`@%gh(HY*$r656`N_{y&D{wt>y zUs#7iZ6s${YH?hLlTy=~4X?Daw4e-+m%rv|w`*$&RW{PeAvjWe&QEQm93DUYRd!7x z)w%mDps^davyA?|C^}p>Sq3SU0~gx9VjbS24UUzk)}wpfiLaaSV&tH0fT8r7R<>=9qG}h72pRrD`0=&y1RtFg;8-DHuS)SWY zxp-%b?H2a#0Ye^G#7NByA+q(7rA(kKAO%VknJ9e>S{A7D)6&#l^%^QisM-{uQiq5$5!0nKF`&G#Ft7n=w zZBA10pOsAP$&W%i)tI!{Kw$UG>Um{piBq1RN|#zYja02z)(J^G4jX%?vuk}st4 z-ypBr8|Ke{S`~Pt7JZDNJhrba@!aOt6M&K_%BkuHb4vtsTS`TNmUylkcu5lr8{`sO zp(F76RoHwvYj3%d`eM#GD{?si=bVpT{c1@xC@v*=zqHx1PURBu`C_T!A^jk;G6OE7 zAhwjwj|kZyQozV_$zFi;{{R{qOT@M|cQQA?~QC6q$(zJ4j?qaqKL%6qXp@`^ljbuvku5nM>Q?}#PJ%obf%O%V)+Zb62rw&Lh>(dSO2PUDG^Zq5xG%F#JHW)jILQffG z@6LPGqoIq1G5-K$Deg6P4YuL`8T6iW9 zNgBlk!YQ4Ul~%~X+s|wcxime~#{}Mfp$UwDAQBd41Fi{Qy^mg?RmnUrG@mrOw2Xzf zg<%;0`vdJwgTlwo^Pttywu}&}oep~Q&1kC9wv3xe^ciKVTh9-aBDG0lV)%v2spA`q z4srF(7Sd_yc(Al`Sr06qF=iVJWOW6&9)hJ`4c%Mb29H@W5R7$NqZ2tf_X1rj|3?vr} z0-P{W(Mp_W8P0K9QFv!kgsQFV5=W4B7y#%x-o_d zl#|?2PqAOioJIDq zmm9MyDeeznemJMi6tdsF!I~)9b{Mz}#N&+fk=GqLroV)5pe-U_1%-g!5rl2&k6xbC z=sY>8n2yV+BRxTm)TvzK(Yfi~QMIm93X8-Er7JBQOg zwHdX$wPO=rPdJl1m*g_8Gsy&VfsQh2)uw^2+Q_WBqD-e5SuIw%%(!<-CYn2-AM-t9qOOKM$=BoIRs2`1tZ(-C7IF(hE} zGg3*RYIhL%LdL-@^PPz!XWtxWCz>PBby(6k*2)N@i#)8EXXhZX$Ki@z+8@k;KO(Kx znf7Q^EybitzdEFH5UG>N%C>nQ%9}2j@=QdpYIcvDXXnY_5OO#?dUfWnHifD@0Uj$s zE_o;j$`9c_y#7^MT@O>(irPiH<#sb9+j2es0LbZ7t4H~e+VUa0g4!gL%*2wv%O98n zFl^&H&ma!GALmS$Lyjv*WX-(puZblfg1dThe!oi7eHT!c+E^JGH=?KwCjL4ebDzWY zq+JJ4NW^XCNgAP0##6W)jDJ!_am^oCjlLk|@-v%F6WTnIn4?i4Z!wgph+`d8`*rAl zDtcNZzF3d!^G-nA)^lK}{_q3SzqLj?PGe zNJ_~cRRf{*{{TJcb>p&;I_^f+7ZJU)HSXLJ6^e8Rt~mGoYOFe1#?rJ`F-IZX`;pV; zjk-yKQ5tqC65=vcO+@n4OjL`4Nv|F;&iot0Sqll361IAte|Ay)Xs`u6?Ph zvDwKE{cJI8X7eSyA7+y*5IXD(c;NAogX!;9B-5H>9m_z-u;H@`9!^w@kFP0W`Dbx6`z zB;i>ZN$d^)ApJP&Od4#)ZSuq)%v`!Fqq4atuctp>tv=sN)GhBr$7cwHv342!cITgRX?sO~i3QhU%jmM&#UjBF`IlitP^27lkiAcS zefg+n(r?x%cHO}mHd$In`A9y4wI}v}h-8n5EJ~<5j`9ooZX>QK%cuCFYe``HExdwG ztg>~-Z+dE?UugrkVJ))sd;1YTBkxEEkc< z9o5H_RdK!8bGtalxX<#W9&2Hxo5+ur-X!@48Ryojy|%k{e(ZB>Pq}?<82tM%x_z2PbzGUfpL&R7nJ^gp!XSBOmOX zcl_#WTWv(#i7#~6e86(DD=;iSx_Z`i?w6|F{`6bIuB2c&VyH)df2kEQoIV!NdDzi0 z-2U`P2KGVoINURjx(FcpV4nW~jaIyQ7+a`;7F_Whpn%GF$2sRc`ihPlZAGICac^rA zD+Uj=x{=)NJa!+_tN#FC>hrvLx6|Gj@&X4TMt_$yDaQMuy?PpuCBnrN!rnD1yE#(( z)ORC{9Os&Kn%sSln9@z(>e@NC1|4?ul0KQpHAw0Dt&|}a!%HLXvYo`R{{ZWH(o6la zk%fm&vxN!;c2y^SIxyoDUN2^W`W83bUq==rjulj82^~2vG|A4YsIWxQN+cOO%OPJtD1uw-TXP-mnQrA2CJQpbplnj)$C8SnqD+WJR!@Sz9a& z+qfNejP?B}Q!o$ZX}55NAh3$yF6PfCgGsw+#!VQxP#}_9tR#mqN`RfG@#pZx6B+JO zJ@&9mC~Ow;fM-+FhW`K}qY@aDNo@iote<*(fChf)IXwI4@TtDhs5P<|)6-;ZtPC^b zuc2)5P0y+XyOS_`S^SH13SS;UNHt_v1Azw^GG!e2Y02K;Zc=Ali7rJC7jyWYk?d41Kyb&}Gu% zByoWs%sceY@)YJeb-aqPSpgJ*fM&=nNWteKq?RdeV_Ae!GXS^(ZU?BrJY|9{IYyEJe(YIdt;pYQ*^2ATg;35Ii50p^j8a%^evDN^{HjIkyb^G+F0^3Vvuge zImP%jAIA?0M$?XJkVUk7C-cM3?+?EY;Z?@x%}!Jlj<6eOGOe8 zlUwgb2O(ZE0RHwmpVFj{MAPJy+_lOEB$BHsRR=$ZKHl|0CzZmPVi39`e7m@Az-OWS zd8sE2c@oA#K2(N@atPy&eR_1Nex)fEKe6H7;7lXjH|0Piu|9|JsGmW$xeUv5YkblF z00NK-jN}ZdsO^5-*D^x`c}W@&5ylu1-AFu>^r@Cx_?9VMB}YSm7w7lnewm?NKZrTJ zhEJf{loLEtw)6YNi{?;Iay`E~V|XqSq1BM72LQy!1K*AfO)cDOdaZCJQ253`E1dMm zvWn(McP60(j>hw8-_XXC;>AdC(ELT?=G?wUROTRI_VW_R>b7?jsC0 zjj;&|XVI~m*}3fB_4gCa9>h>smC7yMw9%>wASMK?r5$gnW7Fsa22+nTpZvN=y6naD@|H^$>mS9Dx&<03a-}tG0CK=EAAg6 zDdCo65<@M#C;}(XAo)mKV;Lhf!4%fky9a z9tovsH5E@XD45B!aFgu+04{&JO8550D*5!?6ML5JwAFlpb1X(cc9wQR557mWPyLOl zkbH~n{DOXE=N(5-YOS^H^pi;>mXj_}7Eu;dk&nBa9Q$UeX@6@;B@)GUvwX}Xb=~HV z?ws`Fj8yZ>T}t~~|Y zwOVf72z;iHOSt3RG)&-QX-}8+%_o;|WDDh7Z6gXhfBNe-KND&QvYDly&(7>T7*C-5 zDO1L}mf*J#lDQ*t#s)`jI*-nsr_e7GS*{ukF4tBg+z)=0VteT>;R)ux2g)|!9C}wf zsrbtI(NQC4z&QmnRQ`PN^~FzX<9RM(Z#Ec(*dM!MKoSp6V@}hGO(8cIbZbWeFfyq9 z->1vS@5rddtX_BuAtAc*I)9&9$WIoVg?~QA$|n999Bmyr?rCkjNo=T0(MNRT8~~vK z^cftArOr!HHinxKJ4z#GuEz`CkEKN}jT}dEThD`nc?WO57_7U06Y28K44Qlq#=zjL z+nF#sjw(g*29+hjM7EFT%9Wh5o_{a}JIk>SF=fWm;sp=yLY|$1((wzLFWg% z!yozN4nDllwn8!;1mx!`L?5m}rk@n(%OgR~bCo52Q}~bYscto$4M;df4UB^!AaU)$ zsppqwS0s8cTY1@lSZ_hc{PXYm@l}Yv5;#ci#y)OhUzV&xu4u3;aPSlNSy#;2bxa&AX0=o|M$(eGx7(wygFRf+Qn!h%?Z$(-Jsbl~SaR2n-EaIwVDg zZW*!A?FSUAqQpxdv_210v{#Y+m0!2wk4x)RiiRjj+DvRmQISWL5j-NF=~kaYfyWZI zGyTA6ub|sI64OXQ>I#l%{>rc0@j>;vMP|2!lx|4?%XyxIp=CC0rcj zD%3CGn3_Q&>K6rvPnCH6DgOXuSA9Pcez{2t_DC50#KlHz?Nks^26@MGPJ=*>*|*1i zI8sR~v~!wsXh`2PUtFGZ+lp%_#P<9}_1ZtuA!sc41SvS(o2`1$h$44m`;Z@h$-a{AmKiBV);sV0Y*$ z$MzkYpPa}~UO1#(2F@ldttceq{M3JA;(wKW;r04G{{R9Mg4Isr9H9FizpVsXaq~;` z$2D z=Cy`biHfp}NR~Q-?s3CO@kD4x+E;OM?IPVPZy4xTXyfQ>TS*$kQoy%ytDq#bhIIg+ zVVwTBt+=$iIG1c_%AIkZDq(AEdDu@F#}wt2*Ky@>kKQGYqMnVEFKpWV3~=3>K+0F; zh)5sQ?hH1bc*c5FZ6Cr1M3}JG8sgY7ap#9JF~A3L&JIUCG19hH+SoSbjgb5(6^tkYyNT+W|+ z5!^bT{CITlQi$PPlvZD(kyYDHvu4bZd88bI=QyVFiS$SwV@~9=*=b@YQ*|s#!vVJp zjQ6aaGsAXvFyTB;sNF9>u8D#8gIa< z&A}{3)}Qtyo7UfmzqBbOvmt^DU$d&oeKThtF#~pc@lzyvYDQIWZk=|5+oLC+P=)(uhxVmD%&?Z4e8U3rMQ(odY@qverrkqhX%Cqt=nIVC z0^g=7i*quM^^O7WnvJAs4%aMu^{rM%-rtCxX&#A}Ak*WywT9*?Nl8!2a0Y&yb5DI9 zMLb4WV6$aLaqW(z)g*HgENBYGIRJFdY2tQAETrz}Nb8EP>^0;c+L7$bf7s*65;7Gh zpDX}e4{`qh*Qvj-(NMXT+(tNNBxF``x_1hNi-2-6X~t5(t1d^l7^Lz zrY1gzj8sx+um{-2-|p@QZbJ`aih$0+!6!Up{{XE{Sy{;Cht{Y27A1dZ$FVW+`XO9H z2hEHTkHVVzF^$6cF>~m{6bUoO&5uD#fDT(3r1EI@ANGRmM<$!)f($X8y>LOKhf9ul zw}|c6Ki?o9)YI4o18@iGDTF8+cCI}FifbfY$$5-dLI<;iDuErlZs-e+wL)cPEgTm1 zSzLmw*(dM}D@dqb%A?p*La*P#?)Aqse_<|?{0RQjU&>_&E<&&FEMr{l+NeqT<0p!m z$~f*zquaw7Q-Qq-@BaXI8O>kFz~Fr-$^v^4OZx-+-++H=FXb}jOJ@a5g5aDJu;6== zDF&IRh9FtO-15u62DI1$0opP3>rL1*_duz61GmTc2lk|Yl%@6<0L*sr9P&YCOCW$sI!Hnz^+~lZE`K@{<7UT%T%}!|(b300O_Xs^ElDkx}9+W;Gf6w>}`%XW~W+ZX0GxKrxU1{zhQM+s>>CS6V zY-Ra^k7G%)EEBN+@4%$Eeg6PB{{Xa?@|bc*IVi(ZXpc>^Ewov<9hj*Cx&~$DGIO5P(gtybA3;<8um1qk&%^!* ze`&}03{=qJpKjY}KB2Ndoi%g_Uy&J74*)|!yuSSQ9DcR7eLw@#0)z^4g#h26^lTeJQL+!6aifOCXO~zqpr~ ze{koHn=0Ud?0TQ`npM(dCzy+5b;$y{4B%(f_XdSw+zvWciy)``?1!1lq)~zWfrj3; z`$_B1S{p%p9k%K70uE1F=m{k8kw%+y+kqo5-pE06Y9Y$Y0tr{#0}0!&2ZEj>(&@e7sZt0I;sW zAMxvv&;>kxIj!B?j&cub3Foyh>NH_{J z)Om)tgAREBeQ9#LbCHi+^`rX=hj;yagZoB(kNX9aGrDg-a1JatwD6Xte9VgJ_qtUgMB#TDr(XJHd@}+$*T2g=FURY;>w+mfp zVUxhX{b>(5BA50Z9_)W!mt&7QZn&h8V8kBYdgJvK8Pj#wIBhZ19^zF$rfaqNcVu&( zxTIGcf&MhVu_*Up_1ShgMbh;xp=7h1o|#tv0PE9NOVm)DT3%rEtZcg+NYV8Y%0;!<&vH6cgGAK9$c|OUe}=n8Y_9_c9r&bDUnC*G zrTvLd`Jdn)U2CDnE|aS;1Iv)(yAm_{P`XC5)TzikbD!y5kSxa=NFMa33J!V>^#1^` z>Hh#T`~&N+`A#{sZB(vJzVJ`oBvgOcdYE8V)p+_3>0Oy_GI5HDmLL)1b40FOmtc;wQ5Wom(f{{Uy9LD)Y^>v!jzaqMZz+2f9Rqx%Y<^D%vW z{{Sh+zMrY8ai&P;({QTs+UiclB++l9$2kQ^uI+Jw>-FnPzk+eiAJ}x)+GG0beGVnG z+thXW>?pIjtWgC^%x)Q z`-d&pYK|(rwl@(uX439@=OPUM04nrPF^@zv;B(QjiWW&9=MS#`0Ce+Ig5*0$+HKYc zAL>r;%N;6K5&$t{dl>8g03PT0SE6qq`j1d)3y^xz{f8I!zX5%B`=^^pIw3o)ucJM3 zwywkU6sdCCGS5k^W%%?~&!hRPP8E_9TCpe_irCsdY_1ARFuu z-5xd|ew60cwAjM#)M3H&T#EHD_&DGi07vI)dU7gWNWYkWU0shV9wO1(uA>1xc|t#> zNSe-;@s|61M;%FD>x%UQ41Ej{ob~wzDDq+|6u}2qYs zrrAHglE2|g`xaYY`ul-m;oJKA&p2IMPjS6yhkn>v00I@Ms33VSaDrv{2?A0&Ofm%fjn@yq&^1l&Po2pwjY7wm-aOKp!(c< z9HQQ;rddwh^~eM9=9BHqxDgzMLHo*?A6$y-M}qu48TmBSQ~t}asGGo^9w&g3Z0!>tWh z5Ut!F^~z$jzp>^YT#15j^z(0LGA}1psVuyGty)@7n-7x{{T-J zsK4P@+65qL`mQ<*%hU4yv^<`D!|RdkQe95XLERm?=RB3hY9{dplDSD_g?R1{HK!lL zk0fC{L#r>aem|X9UjQcuCs6Lx(5FM8jtMS$^0dKVw+o; zEvxB_3l+BxJC1)*L|Uen>4D`l9x=`0EH!&S6^rG53Ew|OAK0EqbYA@Pp}7{&ZbzbivX}dPI)RwBlW5V zFBn6UCxsSIbe%t?L-vmnMC{V|QvEyr=$5H?EJEnUtJ3alw05lLHu19okGy%P!rFzv zwjSU={{UXHpTt_E3OxS+4eJO;qz(M)jGj4?C(N2Isz2XSD?h4N+m)5=sdqYKZ)(5; z2M4zA{=E^|*~XYlcfsm2k^0v){{RaIO#c9umbdUY<0Ugnejw=Nj9o}Rv7RY?UbkjH zYfGWi3kyG+Fn|wHijAzSBy0<4&Ik8M{*{XtjWk)8=G7fD>!0wcQ(VzxBW}4LJ-3hk zwMVk3w@>jOJvZ3WZ6@7-5!zd^=yJq=N?_3A$zf%0=rYw!FErix{@01K=_nt_)wH;= zkm5Vt-|otP_^KP4?k{olL;nDstatCP|zgdt_pm zC1Hd1ge&MtKf!}(0J;9Uv%HamU8{{Z#sBk=n{VlfP$f3o7Yh2)68>tPG@ zJkZzB;4{do4^pIxYY|uZn4LO*%3vRdS_=&MR|6i6%`kj8(QhMod_aaOT7j*XD%Q0#heU`Hbq(SX>-KD3J1-~s@n z86~*-9<}y1Jaor9;+kJ9I42#?N>w==j8k$m%VX+jOQ2t;@f865l2SYsL8+v!Y=o2~;7 zZYd>f;~5_L;+U_X_6iq~ng=7LFg^(5cO8WRxE$^thqVG6rL)+IT!1=`X{Cc_EIyRb zSxzt?>r4>h3GP0artTv=F~?jAY0q8Q2e74l=YR?H&omC`8OS&%Bio8`agYAJFmBz3 zY%K(w{F(POfKwnJDIb`p2Egl|=}g`a@vD3AXktp^Bpmh5DS{*opW^9F4ohPMeS6Xa zjt)9{^Gq&K0GS~6>qukspKq-vAZHmA(VPV!lk~+#`&8#)^v_yiBqw5$GDp2IIA9nl zKcz+;K^rrk#Eu0xuJM_NdxMTpT$chxMe1kIGgyLHg#I zB!iQJa7SuhoO4l-23Vd?so+os8zU{Av;iu%;epp3X&IS1V;;t%AdHYY{ctHa5TF6T z?TnfRSVPW13=gF)G23w+0RFWUXLuMG^v_zCW(gx4^&^UwQWUX`Nn*Wwas27w_}l=` zW7?XFvn;H5>`gi|xRHQ9hl+;HVu=v#QMeMv(~2^xcV&R|$)-r#*9# z>?&@Hu^5yb;N*_@=}K5|di@P31e`Y955pA67~?9W^HiA)3}Q*hQJfz1-M9sd0rjLi z+=4?4j`V1mhnuC+SJ_P)}}pQGiLnCWURx*-|mbJ?Vl%9n8QL86&?+ zHjoGy{Hd;+dME3OUBf#@K=w3&4>%ty4t|uME-~rNF}FDzWhw`71t4ZXcV+Y6Z3zzK zo5LJ(eE>M8l)L_!Nb`e#h8wm&fqe+!G4Z+V*O>Kak*!=jQ;Nt{ira`K?8i7wSPtC_b zMJPZB4EZOzjt}&sXe4BUKo_(x%_Ic+iqh{5+HM&m1D&;>T(diVkbNtA*83|9G+#(_!-@wbHz2=D~$aqpK6IC zE*N8sar#wv*Pu+U2?vaW{VH8$(4|GK%RsppBj)v|V{qk1)Mm5STZA3J{s)R|+UJ(# zLUbAR&-hflOi@b@BSid)1_#$YD0Rw$PaR3-v1jp0$Cfto$&W)K*BKlf zEw(EFrBCskpXFTdA1mn(#TqOuddT&RV>^MTp(laIvF5y1=i;A$%M$ysHc>F6^;@kTqN`hTaV_%n$I`M*!d^&sx9#+L0L>OJ>2C<1jTO6if)_W>kCp+);70QIRz12 zvH17;){J@>+!3{TnoMUUcH`@gl>V_N_P+srU;Dp_T=>sSZLKA?sUGjTUe$)KnQv8Z|eqCHjFXO0f z&&{N2ioHu1urcd^YURI-Y%Yq!9ku@B+(W?pYMsTc-J*Q|0A)Rb$;%(dIjXUx^wEa5 zhTXEHA{dJws5^7|)Xs8B{Qm%u;}v^y{%2(ulO?*!C6I3F9y}la09UWD)-D;A|h;23;oVxjnLC2;sk9yg$pHdK%hB>}W<9dQX_s$8d7ACiIbw-oubOP2+ zuIib=+FPYlxJ!tiX%=2tZo z>2~eQ) zJ5|55DhkOV&#LsM{l3vyfX9=LhnnOx-x6s$g3E6c7-ks)DTBu*ILQQ$uTNUH8luUQ zb#nONe8W5*oOiBSW*E5W>{`OndmTW#w<<`T)cS4WoA&4cIFRs1Vr!U{r8g@XxVVj3 zjtIkWJx8bG-lTzM+6cXQ3CgY%ZqL3CYKNKP*7hsvbe~3a6Kat{q{kebb=tV+^Q!V| zF0O=Hy8=c?BlQ)SCb^AWjNWJash_VE6jxKSkV-RSI0{sbD;Z|Ex7ii-I!mFZd_X}7 zC9IHcw?pfEp`O3iUe z>i+;Cyd^Hif$id{10kcTixK>OQB=iaOPQonJ1N*#@6@lBuy5KFs)00XDz z??QOC)Sa?LDxN!Y?O6v*Bj@sl^#h>eHCkwz1VxfLr(ySs$J;;3g_+_T-|!Eq(_IdU zd|htLfZNKsBc?OWIQXi?l(R)BBdBHMS1I;rRS+~%AMUs10(e?|QPhtV*d7o{SywzLJXA^J4K7K9WVk1>QwEV|B{$BNe+8Ced8N4+kx*j9bo%0(Wo z8;)C|1IBvNh&-5pj_qVof;Wuk6`%IDAv-&L#eGhm=%00K!41VM)3eBx1OEf3*XLA{C4fFd`(J)X>~cQOxl|rGJUX z1bWrH;}Oy*O9fBN?5FV-nQtGNCEP#{;-Nf6rAnd2)FgU_$Q8qh{Ki-N9Aq*3!y9lZ zt1`gfE}4>7EYX3}++qF#+!74JxDsBgsZgc5J_T6>77vc*APWzq7y|!<=aR~#sG^=+50g0m^ z`|^Jb*9K#V5<@8rK{*^#;z)-pD9Ai=c&4+;t9T*(Mjy;~Z9GacCye_8N+*rTB1Hop z)xs8d+jdl+OyeWgoIIkZB!(b^^JDRcb zAC{hTdWA2~6rNCi8(90 zF$8{Hvr|KTbTJ# z3V)??&#Yg>fl}p|=RB~e?@;~Z-aN^A}<$C z2m4Sr{{R(HKf(QVMkDcJvHt*RBp=qh3x6C~N=TU{fr06ON8)oAJU0wk*jI#^tdBGn6FeGAhKpF=JC@x z$Teo$QMI~bqsE`%Z;wk5ZY@}Pi>2nEli_!dSDz*q$Mm&I+vMjw0((}E4@bY`Pd!e@fl2WD$Dj~&sUIACtf%_aE#V&> z#Jhj7Zn6H%LcW9D5I6^IJv_Gn2@ZV#%}>>-KB3P(!;^#0CYLzQ1}Z0z4vn-QdS{xU zK2pRUp4Hjx%vDmyQ_1}4q^UgM`f*jno0zC}$Q@aF{(_W(y${XPBASJS>R+KDDhOft z9McIWCwD%AqjEvX1--C1q~DNmrB85p{#9J0a}OktbH-_h80T{w@C`@2r%lX9t7eyb z=Qsl%oYiuZ%ssitBL~ues8f|3QyJNZOlOZ;XUaHbB%XO%b`c>s=y>$+NCL-_n|be= zZspu|70+>uP$VUCc>4CD!EwWOcW!T|02)SY91?$(G(RL{pI|Ad;e%mVcl)@fVO)DY zc8nABG^g&67=Sw(U~qH89CpPtzsvVn4EGqK!qk&;J)14u|6j%iqs zMn@k?U<;7gC#RvO22=8eAoTU9g97Xd0iHP=(}qS=4T?HoVu6a&Y#~CQ`{dI^r2M#1 z_>o9A0o0bxd7+dKmn5I3N-PA0S7^s>xa~&m-9g9YQE%8bmIFO0xMj&!&$;bLWP@Ui z4WJXyj`XZRp!2K-HE=9tntaM6-aQW}7< zG)WpcAxI~#Y1utXa78gB3^>pD3Qgds9Ij6Uj%f`dVorD?>4QtX#|gKma%u)F#0|`< zIqBAv5Dwl4p&e;5kz`2cJAx2>JASk@$-&yVJqW7iK!k4OV<&^fBC`x`AaUu|rpUXp z%S-?`ZU?`5YRU=DKqO>yPSXCsy;zr8!l4A}*bze+$@GASK1{V3c3=zS^?2IT{j?VMAExIe;i?r0e%*5 z5I?=2=}F{V&4)&eAIQ{BrGhH#=o;-q737dIagHh`zL9XE+EQDmL7K{f(o_aXCrpFT z4CmUeBigt{)AV(@PGe@m&_0^6U@=n;h~!U?^*=!}o3C131e|RgKOf z*wZQ?9BvsPcjmLFmd-X(N#KS1qkvCZ^W~b=*<0~CRtle)dG7Amg_bL5@-vd&_^27D z^GXUOIEC3)M+lJ zjM}~Zylj$a5IO)z&C(3x9eq01fBYpANhysq2+_0262?Yqg~S?MuOV$oq9X)iPX3&e zQpGNcSiIVVUAS$$k>A?0`pjR%-{Nb?md$C?7`L^rwwR}r+9nxJJH@WBuP^zZZ)(pp{E&mWs>6~)T2%WnXL_T%%c{{Z+& zl3ly(VHjMHSC9=${kisZNd>w@7=7P<nQ3bxQ~CBkhS9pk4_ z=|G2EI8Qi;$2(Yqp83WxQ74IFHljeT!F>q?bIATxG&<$9=&rFySak$-2kX|9b3f)x zzhwupO6@hNB{2ks*;nS?!yu2K98?p3!a}er#VxBS7|Nk4$JaRGwvN9F5JU>0PA~;V zd{1pGuMDtkB;?@Wb6c#^pJO+NU(9o}9}~1IFWcjaFu`#YXLuv8UJoPnt2P(foH9jm zcdJPxZpCDb!-6|?9XZ8oL#pA^N6F(%W?0r}L=GN9F@nBhgI zbjljFoHN@b=T*3b9+F1RyRqwmS>Iun?bZl2$z%7-RU`~H`v^T#8txWSOFMr6W z;pDa`>S-HVG#6To<)f3#4bbDzLb8v3?r|O}=s$21F`PJvh%iQbDS_+y}XjQW37qQ%x6k@|?Sov7`S0fa4_Aea*I+E4huX%NE*M$yNieR$SxptwH^!WsWHY zskSP9cFMRo>PI83Oz~eNTOtUm*~tJl54RuEt`+({NtHFaGSb0Ok|n(}E1YGMB?q<# z^%WGt=G}m4t)xdd11ye4J7jZP3u%0|+eO?`K5_%cg2UYH>-bg6ZN?HV1YwV0z^MHN zT7)IKCsm?nD?Ox_5~bohAq0<+agsix9Mq|AaLi9QYZ%&Fkt`{kZ%E%gcqgtY;Y_4#xMB}Y z$j2w@J%6oquW@I)X#ug&dVMK~mIsjsA=r`WxdRChyMUZjvzZAAZ_>Jt)`<6z^fXPN3B9NI3rd(j&O1^-&$n4oruaj${!<^ zP#9KRo=@&B{%DeILf$>>(K3;Z+@HhiRoh*K9||8h`=IcD3XWZ3%_IxwMnUheVE+J~ zYP{NwgwMHVvlt)}6L2HjnsJ0*Mns$F(JO25wsWvIVDEz8N{nj32biHziNgZe{&iAa zLrA)C3fs0p3y8_V^yAv9+i7TTBqr|OYi3`TD52U^`iIH=YhPm&x{=Q-=xV;GfRi~v zj(-0D^r9R1V~9Ly7>_@7NEJ@$EFlrVR!33C4bXewW`PEte7A`%Vp1|ljF5BNky7ZZ zUgPI?G@AB3p`(v*VS*3?f%sG(XomH0mvh1ss*H2^5&Wtc{?7slRznUOcHbzFDyh~k z7Ug6Xts-MC#BIR#&svT~f>K>ej?jhx?`2+j;4i$V_ZHBj#ff!a^cCw6vRg1K& zz%Q4Rw7--IZhKZlTE?p!xw_LYBhCjft0^RRJw;nxQbvUN);DpvYyu+$kHbAFI!-Tf zsV0k4!4#6K$@YcEV7dOCIH_X1g#bYEkj;!bAIM~JSx>0jvdOh&SK#ErL0|FwDzbQn zIHFi0xG%S>Y&l)qHCi#BnOV>d-SbRU-6rM;_!<4!KaaI#L*hXk zL7A3fFgX|p*N&Yk>uTYUHLM0TBxGy=5>KvrR7w(#vKo|L#*M>5Vmr|80ORD(^66DK zd2&ROMByYmM6t$pgXn!acdWauTUA+5!(!W1V5+cD&;I~knwqAs^9HtU%y3kYdwS6r z=qXKH=^5kl*#fRtJJcKj=xV%~P*?1vl^G0IrDNP`I+S1}_95C(PE~RM9f`+GiY>Jp z!VIfu{0_&0eLlTv5^GTAPeXNaD&Rv4;OA&wr@5$_G(h34qy%x5PI2j2%dOrtcUZJ| z*$5?51hDDB^{Vptk5GaMC2czF$HM?mOrCiaqJ*FPIGo~d2ex$rSiW2XnNWPVJY-^= z(A$6=Z36<>4yX=mmwk6pP?J8HF#tALvE6`vzJyZ6;#s08w#MWZC5R2d*j#tz!g_ljXxp6UwvmxMsG5S!t zB0|J@>O*se&RF^n@TMD^Yh;rbHxV)UfRm$h&{WXsu*jjBL{>rz76F0!bDF2jmyo$t z#FoUnM=DAC!bnxmA4;VzmvbkXB1~1mAg=BQ{{X9+wkO(mf%}#_gpm!~eeeOS%Z)&| zl$qKz3P&6_wmAHGrxf18m9438+g^E2vqo9aWEiF&H{n$!N0Vba%?z2q2a(gE!KYhX zJQlIBmF_p5Lq19O%`#m|<~iL20I(dG#&A1lCX$Q3z}|zEWiBR5?U9DTS4@ohRM#msV^^9kg<~te-nBS$FpO8f#kG&T|69SOK|L z2Wjj0RTc3ayU3F+oUNAF7-VCPc&l^ku)y2Rn2fO8*z4>0RxUD6VwFgZ)Gc6^0*`kr zAYc~_w2$+Os)o%xy}GQcu#n6p2Q^@}m3uGGX6(U%&p=Kpi)gwm``Dz(^W)_?&VIFV zoGocKzC^h@=#axYLo@lh{s`qT{YE>~mfj*Tvc}r{KE<#=IpduARa@T&X;(8y@!m-g z=p$v$J6AP(;Q1k(#+MN>!6Te!AJ)2|8WnWr{0yAs7keGUc)HL;jdy=%H(ZiFU_D2z zG5#g!c5bRS$WH=DRHz?bMR|4BnKTcAGCe`6t!m)(Cb}b+)86bBA)j3dGn^+Lxz1`c zF7iNE1HJ}wDdpTTB>)6-f+-6HDmNUH*NXa+!Wv1z03Uwz{iAMo5PIgKcbF0~5EG1^ zl+YZu8Pg!-;ZOL{U{6u&@+sT=yHb{NMgsJv7nrs&85!x%N^ZtuoN?FO{sx$dHym+- z-3dGjj29Va7#RK@!j~I|aD8dAWJXSLif9AR+TX+h=kA~Ips{khS+U=oXY{B=#uuq$ z&<(jK-kewwoDS3<2Ycb1Jg(yFU)J3^#^g1M}Py#SFn%0U^g>kSZ{!2{IK2+k--c2wFaU z%Juvx0#hLi>-dUf(llxaCvUYxTs|3?AnZc(`ie&~;2rzMG6umw$zr+^fsVN7tA$5D)tQErSbM&r&-Kl;@8!eLkf2^|}X09hP3KQP)od(b67xn^Pb@rrKb+`yB+ z)Q{4blO6j?I{rDJ2N{vUUEeS~5^?y7Kpi&^FylQp^G#P>_y}-EEW~xC7{SR0zIM<% z0+v&fV{P7mig7sMLTx=xY9lPT90tcdaY&OphHeuaa6@8%74Z4m924qzKT2_8BOsnI=2CF+<}4x101Y&fJ+fbfg6&83X7n@K&*IZ^U**>F3rKjBhR z5yNlgKwNIgJ?M~p#~B`k8hCFrJ9>kHC?JL^z!GQ}m>WUdPuBp`7?47tJ#ughd1Jb2qp1G*Zs1M9X9`pdA53lJ?3yw3# zu%r?Ubpzit#=L?tmzfX_q_!x~3ASSyBO;_!C!zc+I!%8}iLlqvj2>`viir5bMp6gc zvU7}tWBn^BREp|r7)kUtL|ju?gzKNmvM2FomlS2U%;zL+Sk7`jwMJhVTWs@VwZ38Q zn}4lGwuf|Er7p)s=8nMA9$vM~w~Nfnm@Fq{9ZR~e^{8a=P4Tw#Ak&Cqa6`%n2i}KP z9m!CaW29@Ixs)OF-C6SAI&MC6ZR`$D@~(DI66?l88(3L_26N^&ALr7lPp<3o75OY9 zLU3Jj*dDbGtUH#WJ7|r`b!l0@<)%CQwOU zeRUkHuXh@PaHV3;(z2B4y>7;#RcWE6b+5|~Ryem7IL_1l6-w*H`mAI3P#^%~1UEk2 zDx6w@mNHG$&iLJsp?3QUtoou9e=-5;%%m0O^oUdH(?G(+;(BF%f*ISqhAfqX!@1T-=oR z*z`p%333Ze0}klib<<&w^Qe)pYrkg1P8AR2v~O?3{%w%Da8uYd1~Rl1r~KL-{i0W0zrE z;{ycuq|`5LUgPZO(n|5MRzP{rL)Yo}(d=ZMnWwpHqe+BO#Gqio!ZsH?o;b(hP+d+e zt(I64Nu7UoQy4h)`fzF=?KD`D0+UA^fD!w?oqC^2zKv~l^E`>Q!69-v*Af&gh_y4nfD^ zS3E4=LSrbc%h!5c%m~kEB9MR*A165LpURacxVT1nR}qxjth{IGNhYYDWBWwt$f&~v zu?zvqrNRoKVo8=JQot|0iPW`KuPk|5bl zkF~n}Flh$5ZdF=kJJC)?@I#FB$Q)CSSl;MQ6%)9ZRgIaZf+m=u$Pu_1H52%f zYdb>OXNmF2L%})g`qkSH6VG%OIPM)^Ae@Zn{NlK!m(-4}n@1NGdXbwT@IXB|;}m3o zRh#4^jCQX%PZ3|P51P%jK4m_j{{Spgpz(d<+$;&Xm7J(J=z8_6mL9UzGQP7OsPs|S z=3aRlgLbDeW&ueo4oN*taP6#K$n2ou5q|e4@cinj@qN^CD;07{+CW_Mo(TT{J?Y2W zJ%QJX-5uc`VvVw#gVm!Mp_IQ>1ZR>457xOM;tQD~6DC0{P7ZU&2BUuzI13orxT$3% z^WXZ6Rr^Yx_!4y~C`shHNQT0vrN9pQUkE9yh+Wy=WFO zB8-vG7{++0)8Y*BmW;$Ug&P4m>(p07V^^1N#D|EccI_Nl^G&WBIN#-SjNl)wEy!qN z$!Rde5)3&EKR=~$k@(7U3?-vQNk{-G&p8MR_Q2LhVKbdJugoCsL$(ej`<& z_BPS&<&l@{rBzqv-5v<`2fame8p|YpQZlFjozW=^fO{ItI{o341yEHoSm&@fq<<62 zM$}l8(M8&e9cx9t3El4l)i0QO+_eJPV0~ZjRzKT<+M* zgO5>>gUwFfA&|!-6ivJ%V00%x(xAE5p|(&>w0}9ve7*XAAzLg|_E9r#Jy{f%E(kH* z%OOl1uPzD?!0>5TOR+q(_rUMk$|c|*T!ZgWpA}lk8~))K5s}6+2S5FKfOxjjR1Gz% z0lS01&u{Uo_O+$akflu*uKX>f2^sg@hGI7}mUG9U^{MUrIlW?x$t}`Jl3k{iSx0WC zj{g9qV-FT1Mt^e|3UiJKBfslcpz$gjh``vJdXxFqbCqjZ+-jve>}a=yAp1mPX#^Ag zz1tqx=LhnsKj9Xa?J$__?Hy2X%PXlTKA6Ta{HRY57T!xK>+>FjfyeZzBk=-00+k>r zY%OwoS@lM@r`UUFh%RI;Yqd83FyVs_Tzb^A>CE7XJi3@Y@&82L|1&DOTa(Ml^}yKZ79%vO;|0a!{hMI%WvNrjo1gN>}f9AoMF z(~@gvFBq3`AbQ$FXL}is>Yyt`7;Qk+tRhvzdbC6MiTnQu2RCCY~TE1+IzcOV84tODt zw{ePz-R5>zSeSx-?(Bn(qcx(EOK@>a%SBMCWmz}IpdGGp_3KEI+W!EpEhG{*P>+G0 zypLaczR4QO%*J5*O6~{=$7)u!+&)>>H)1(p2qzwfm6vi-W>fhg{P=HfOpHioBw(L$ zj+JU_i={qV%@X{$F}kZ0`0-0|WiuUtq1X>NK*fml>C{y*p<7Ht-bR-X8Ol0tQlqdm z`BT-hb=eao_m<7(EM%Y@ayp8qb*!Ss>llkC94W}^bM&XClLgcpB9Y?34Ya#*PI$o{ z^+JCP$06F=z$Y7>mumIk_v`%X>B1NHnVj6x&_&l89z<4e$p@aE{=F*18uPnh?I10U zo5Kth8OA?Kfjl>Ak+YS|^1{IN{06G<9@f{qk|I`V5tdlMw88VRgH z<&z+cW0En`+c>CZ@tvik1(GyzjE~~_)Dl?59I&j;7a3FX@J2!DS<~r>Ak0GDW>Q-P zijY6fYGF!~e(_RsOG9ORX{OA}n{C_jNx%c~$fo}QZ|PG2jcKrx{oaK7Rw8J4mU!e; zEW_kY-E+=!?MrXr`_n9Q6A|)G)m&}I9Dho;LWbidK#m`W^3Y-Esf0Pn?3 zABglvPGeG7?c=R;_j-NYQ>JZ1qi*L1p8W<7p{m17ylG{HZIw4Z6z8cu#Wjb7wQ~GP z=aP0v>wmR0TX^Jmws?X7#n+6kartJIb!`!#6L|_#BxDXxrE+uV_rZ;!VxTTxaU@{& z{J^MXOUM*$gfb{>Wllisezd-!&iJ;VBj!8b>EN_({2?*mE zq_DLWpEx?V-5rgehhnzGaJys@%o;*T9+|0T@ZGlm05~faAb%e|_^tv;b)}Qf`%T71 zHiFpCuX@?GzP{ZJvq>vH-0uyH=Zu;sLbBJGQJh~xVt)q1=MbvoH_f;{3FrR+)lnyd zk~1qTQWXFacVG~Dk9ww>zPE1>k1r#vf-+cp@M-q`Cf05Mjcw72FU&F9*R4gdE3L-d zI~vyhABx=xRX7JK2tL(jeKiU^lBNmikWaN^Cy8}v$c?P;C(IXSFnI?!r4h!=s26InAS#UG6_Fo}uSY9R zo}hN5J~E%=2G?m;BPX1b^r`kWdkfk?-+LI!D>Ph@wb38ys3bG~?CCi|-lMpckJ^uhsDmkQ+&DrJUal;3}&(fW;HV0^3-l{rOX50o2V>X^o-ykLdJmgXsk~ILKP`r+n6Cw#P0&p?av;6s} z;*A5j$yPl^a40~@$hHfO$f|qvADu=KW?~hy*llWfmM%cJ2cAP5;+uwzg9$P{0`W{b z5+HFAU4!Twc1Pn)Rz%K05B)vrCoJ7a2dKi4L&?Sf1dnDv){6pT!Up-&${2Luesvs* zo?u{s&U+?JD3Hplz!>A9$MdHwYOj(xJ-MVi+%OpgV1);aD8Zy2RklEEXRhLDOvr}} zQ&zVg7W&2_t8k`5hRLKb11(`raTPapaIj zd-_!-)z`EyoEE`69DX&E#nM_i8hZ+z5ugOJXDK4%u1LY7%gY_Dl~eb7{{TAAk5rJc z+itv!oJsm(qP)Dj1&D?)pzudM`jJ_GXwbd6i~6lgUdFp8BXjy-dQ(r9-#8_(ahwd+ zD&1-f%1H{n#=(!JPaVbEl|u2ad;yIA0Fz7mLXU7*TCbs|&QAf~r(h|*ZWkVA2=JD(N&$>>P&Mg>G9Ex!08R%W9&<_Nw0c|?2C1?x2Otfnu;P=<4Ux0}IrSBg z*N!ccW!yvO81|^llAoML<#XKQzA9dANp6c-b#CVB%vkLs(;l>?utC~a2asEu!@7}U zKw4K_tGMkzO7q1rt|O8V{{U!Bp-;^0z@g7M$KhH30Bq8GBUP2v>duiQ$l2xf^yogd z9FnrH%onbCIsSEr5;U*2Ii6-CffBgE^vUai{HjZ>E@1J_V0C#@b0J~^x%R=}`c_lU zVxEZJIaHd}n;&a~Va(BFbsNTU>r8D@$dVT67>>a7{VJW6gt5q8=H4}cMsmY&WjW)w zIQ%LtLr1am6=0UuQoy!K70Dm~4_uF?4>gze%j{~hsP{A?554BKoo8B zGEP44Ls-q>WRGByDL&}kd|vwqbV!GO;_=K?vPC zD*?t0M*26~47U>5EGo^yt{ZX2F_1qVm6!IdX7px@EuyzXGHX{6%^Ee#5qXSNUw9*q zPu7IjZX{p^p=?x-;XOJ6N$5GLBJliXC3dyA2+{2kvW8$t#(H{UtjFO!E&vrl>b}-f zb8l%Xl|Y0rJ4ycb(mM7vA6~5Wb7ia@6|_q0s$RP^Y|6(2U{?*hu1_3eiprN-y=Ob1 zomb4p@gfBPdy`#qY1Y!k8#Hh$L-%EkL{6*efyOziscvAnxsoul2f!@M3mjvPJ5>E{ zeP;ghzO7HBQOaCg+(L^q@!ZJ~ZH#>N0Zu=Q1o8Bz&86K;=_FFd@vz=;H#>3Af)0MQ z*ZEe`$R)%;oS`8AJ$~*wck51?+STHUIAM-P2j&jI4xKn0{xp4Ibz$sM*yGzz))HiY zvD+AA`G@ZZ$U7c0&IssDTU|R-nbb`oi9++`6-;;RzpZo&9lUI+>lzc1N}hP=IHyY@ zM#LqgK{1TE{{RY~twm}c$#*#$tsYnz9p{{q04uos-FfIg&T3b;m^f^!2I{N_%bwNH z%V9Lq8DjEDDhV5j>Cj^}mpV&s!6vdztU(X6IRy9oYL-1egw4=KWazQVUE>e(59{lXN%1Uipia$&5LU7_s;--I*uI*Qr~D#AwwZD1m|hV z$OAnnc;>f6Ivo*^*9JJc%ALz9p1)Djvt_z@25s8nQV&K_LG-So>5|T1E^ZKs4;y0R zZZnMjHG_FMlMzKaq9Ng;w`>MD$NA|_o+_mN$(*TMsg*Upqb}A&k(U`Ny-s~s?irj?vu0Ov>o^IXn#K ztv2(+C2sQ@qxq$XK;SU$G3{0Dqs?ICcDc)&e4)gHaOQ~6Da*GQBafwY>ETI)dzKjv z2h2ePbJCjr8M+ZNEt9we9E0B&#ykEMUeX<8g~=|*Hc((M%v;cUVuCjASr-fjc|8Sm zpYV<9O2wnoC(LVtRdNRy>)i8D9U@k_NG~9oIc^jrBg;H6TCSdvsUR~;F9<;U!~ytM zObXmuPqJv`g%wdl!ozsv=Lfd~@dmJtpRV4-l0&H?ZC#A$mY z#-7@i(kEx%Q_W2<{aarTxfFmWd+wjeI!tYSI zAWdN!42{f6boTuzW}X<-X4#vcnaZgn+Zn;GnpCW>+Wnfj+ zff&bNzl~@h=1cE=o5%L^B*R-~$}X)TO9>q#w3@3ixkl}F2Qw>a)Shrgv}$pgzW&hU{VFl7OT z2PZuGAJV#u-;_r27iI?_ZvAiv=}=rrYjX;;(Smu%Aaj$@57xL2`&B@|ON~h^F-n;{m(i^%X+q38R`eO;w#@ z11Y;Zjt+SvfmjU|_#MvnDsVRjz&@jzf>@ASE^&C@V)GiY++{_u91xEakLErTg|36q9CI_7XFl$7+%E8LZ(HGKS3MJ1*(T1oh&vt}W-zJhWh^ zuI%Lh0F6f0rBR+(r3a@2C!XS*xtg;4h)pMUZp){V02@xx^0PiiwlP(2ERCZivoaJo zC6Lx~JkbPIX>z>+@XPIrV=MV(%(A}XavzTW0M@hQsoz4mquAECgH609Sg*XifZkh2 z@9XJRUh3T>kwmJ?pOlg?2evCY9LC^EgCOG>{{ZV$g3=iqaD_gEWDowmDAIS;l;*9X zCXqb!GNr^jM<52|_UYcA5!0l%A?1}OPggM`V%P zP8k@;z+jWpnsZ6%eL@%Ou=s84cFDf&Pg0vsGmhNW){->FmMCMEP09l^5y-*s+Z_J2 z$~CcRc)|7K>r=z3PipNnQ_S+P`CD#A zJx{H9&n}nq9X{SYj@_PTLlDA#l9CZYKeSJk^{{U#a z+eI{t(a5K2vZ2Ot+ylp2F0bZ<#%(UA1QMAoxkh=%PCp-dnBi>p2P>m?-%_}1ebNsv zt7E6P<(kB~y_yTSq+&@dN#i4}UQZGEj+U;D9G!+ni*m8;$G$OHcM}$ODv<76o!G-3 z*u_;EE-mv!nXNQrkY7mF?Ka~n5@7Mr8lyQPW*<5PJb$%=kMN~ip%f~DA+U}?1E@Lc zRW5ZOH9WI})RoUe?fDApjXOONgGH$|L>NRXtyE@b2pDD748CeM@KXj4)BAsuqLv)yHRb8#S zhaWNj01D+}omiD^yI7CIv8PJP%$sne5?JG}<6Qp$Q-@;tnbg0CEhB}(tnmrJe7MNZ zVhv~C>(=)%p)5lV$MviU1Aubw>*<_~b?H^4 zuOhjE{{SxonsAy(K~>`;oF2KTl@#>^b+PJE`BDZAm4B4({*`veQ;G@KXV=LY4$X&3*?NEp4?X~vgOo%)=2B$Rf`f#q0sIaP~UWV z)$i@L7Q3QM?4c;Y?5y+@r-f-%pd z8Zp(E8j|R2+4!s?7CdJI0Apyu{{RZKo*{?GW`bE1k}_EJCb=nWFCC^4{OV*Q&~t;I z)bUWAHt8JzX$D(s41OP-Q^L}E+@5)(y0h^alWt`gB#ybyt!P856jD6q0mcDS$TjB? zX;*Q~>Lodh=Q-ejPfF=DyLGnx-Q==wJdzIt9@WoZ4G8NNX$rD?oAO`WO9JBfsRVd306r?{0wjbBsM>< z=}r_Q%ebXdS321ILvoRjCWYBl5J3kg*EI}&B-Ab*SWIw6>OoN0!wzeVdmD#VB4g%n z!8z@dR@cK?hnOXf=j2=h**sRiSEm)MgsV;LbwgFvMY~SYMY+iZRYAg^e)VoGYIxWo zk`kYE0tW~4tO27*r(%6Xpc2?TCBmL|jt#e63xuj(?po365 zBxy`cIK~bMKj#%E_MDrowA^q_&b)W&i*| zJdg5djSK3eH(AF+y-8rTjiENGrIa%$1CmdtO0X_%WrYhX0Kks)2E?er59 zEzacx@OxI2dX>a3z=b$JDN*qymm1ePQFQ}`5+MOb31#5p{Aw`-BuOGa zC+@iP^sJM4G@x<_PzKZ2r&@;Y;#j=32M~q%nGOi=(xoYFb5CgcqkSy_^4zksbOhiK zeQG0UR7#E!H*z@x@XcmgYVvL|%^5K+GEeiZLiV?jd7J^kKIGz)sW`hbl+zM>HI@=r znF8{61D+{|N{aFlvMZ@?y|fj<^~gU;qjRPt+YP+W6GTtkAchC0A45c1Rs1q2`)tzg zIZ{|I0qxVZTC1kveReK=neCNB2*Dk2+~@J_Pny==a=;9-1HdDWL8xOFKl0R>8FP^# zA1LjNRAw8cUolHcLE6gd4^O9mtx~M_DWzeDMT%XeVPh(dxF#(s78!{8FItx+O_ubZp7Ji8wQq<1`7E_B$a-1 zpIU7CLf=dykrm@XmDm8}{{Wtq3ttN}EJ-{ivKg|)dU3&~Sj-IVGdm7)S9v3WjEwf} z*0tuA_af2Qw;qM$$cYoHMh`JC&(!49P2v9lKJAHEx^7a32kHE&TT$6Ce9o%JssO|B zsbXR^GEe&mK$TpifRI2A=~?v3aXB8KCRoHt*s zS#J|WBm?ZuNhA_8jDJqFvubwb_dsQ2hmsj`anyZ!)|Z;y5aR~)Wbnl!%a)0EMigXY zry%iD&th&Z0Bcsr&+i0Ij*IgRy?WIov2y@nZrKMoY~*uYE8HZYEQ(HlPTbNMmNyLVG=rQK zJbUJd)@U6hVp>?L$0N&XW5_tc{5y(C?V)jOVF_u=t50I(P zH2YSX*Lk=kfq*x9VxP2<)IFMd82Wj6Kxctbu%(K&dj9~CR+f9H=OI@r00i#@H*8h( zM})MVP<7leiUx6t%#vG;la+|63`WO{ebPV1v$s2JIb3%=DcHEml}~-btN#F`Zz!dI z-rl)ChALmOmHUD)SZD7yH6A70Lq><(IXL{qeuM2Ie9yCy8no$<(n*2Xka_EckRg%S1weD&4XhEX&2w(@WSo{H3@GOxg(%}_xA6q9wJoA7?@il+$Pf33 zJ!lH3`_BO6w>BsN$1o2{{V$@)Xix}snZ<3PoOiI8~tS5 z_1ZuB)Pf}lFeD?UOJM&1N`~WGjwuL4jg&D2FD9TKBNAXJiBu98mE-WJ{@S6fm^`v& z#%T)e{qW}@fd~52RG1oW%RxQS$Oqe8uP%?LOpXpW1<8uht1$ZE~NB;n- zxxcsLu7=Ml+f$+vTXMc=$?cI%N$q1$;lL#H#d7UCWo}_odCP_*9-m58x@e~nn8*Q& z<2hbE@ljJfllT#I^0=>v>LtE`Q!GXpWPH5TV)abSsH?wjK?9n_k~S)-=U^TRo-xN- zS#bkIWso>z0eIx+j=!C9PdljN=5)s{rk%^T8imn-0V>8=ZVim%+M``g>Fw2x$vb{* z?7$p1YLqvipqn82lSb%$uzlWtwZz+`{jznVUL1znw zBeAS%W;2w?3r` zMnF(X5V=#FeQN}~Hj(V}!1Gi$9PPo+UtVg&Q`>}*{L>>p&z_uPr{hXhWD$%uEVia_ zSLMRw0B||$){*WRm;&Sl#>0#j&t848RNbIe{{UPWw+7Gm53v6LJ!;j)8ITeIjQr(K z-u9u_mdriGX*IzK=S3#=#>P-EK|S$A%^WuwWneb}j=w@hW<_ue?<8QS1#mhNJw+|W z<84`kYz^{)dXwpz#mV;{w1IL$-)SMdvl{%_85k#kc;~G}du0CrXMNA+G@~!Kf;qYK{~N(V(q20(A$U|kcC2W z2+8^Q0DFo>vAun+ZxtilJiw9;J#kqU+NxaJ&hee@hn(j)?~huHc#8rp`vS9IVD~@Q zifL4Bwnx?>V|qAZxqZOhXAHeAJ>{#ui<2A1;ngFk)51^dsCOSda-+T(CB{L z(#&x*Ss>?jNn!Q%sgqKG5{|)`V3uyj+x+&fPEAK-atTYQL%1EjfS;{J9q^PQ#vP<( z`>r`F&m$fC)q6UPY9)wgV>Q%I5oui*XDPH`^yZsweHH{*#@-0YJ+svIu0UTq#T*g~ zgC}9L1dL#RI=c+2UPKH_FfY>?9XkFPskGA6J+o}-8(4`{875YRLEwzi{{X^3k;DqI zA&(g34@?^74Dh^97(Xm|R$w{F?T<{<7Sh3Vg3fcb@wt$$2e%`(X{7gTJ+nIn*5AxV zQc7(-Nay_XO4@^%Sx*6p&L5}JxanT%(jxm(OaKAK2nT{{2iMTeY_cO0AaZ!Y7|H(t zKT2NCq`nt%duwiWGiq-Wx0;zd98 zPsX_@d_tiFA_og78x_x7@_!zcZarBfyIe2&sT6WMAM?_%ag=muzi65|g9I}XvQvT% zAB-IT0EJPO1xX1@nBxa16!l?~)1JL5ggS?uphF_E?qMPU&=2cTNqn;02==6|HkBnY zfKERHkZU-pH)|H;mZqFCFqwi~Kl+e1y{!hz-ko_ij&y`zqZzH5!08Yc2%K!HcfF~b6L+vqBI zW_Y71ELP#j!@lr#{{WBDs=;uRmVA#kGGZ|~Di$@t!+lubv9r^Yj*0lDG z`>dPWR9}hon1Hspvq><;lgsoy^U|k*bgOre>G4E?e|8nsd-8L^tjk+lS*L`A+>DEuF5{TP>n68dN13hz(PAGM3?21?2mtvMBNjAp|6+7E~xEUXYIQONF z*H5|gE@HB?cHi@Wqjq|bM}E1gz?kfiBko~_+_G*2dV2KF6;f+SSq0s@2-u(wsNkt1 z*mLRaL}uSoiaop2nlXIUTxHVSBA4&i5*!806%t43Wk$TE)KPHx8)Ow@ot99u>BX;fKx0XBY>s zrB3l%u^}L}hbMBg=V>JNz^uo62%|S`435q}cu<^Sxcs@O*80ty+aYH1<50p=yB%@v zYIS;#oh{84yS%h> zQ@w@@s8mS?71Ru?{lU|ZVmi|;G>Gj2c`%YBAxyjSa8Kw*t!WyuTJ;s%c3T?unx2k| zk;jJ0uGDf1ZR?Ep=e=1HS~_JQ1g1b!f={n{#!Wg+DmiXhQsLD`#YNn}cmDwE0a@CI ziDA?4t==1B82<}oqCq{kuFd+-ty)fmx3!;AyfrH7YbK6 z>ykV3#wro3>K5RK(bj0m`_YvoFW^3=xczQcya^;8daR@|Awz9$hmH?!rmOkakwlkG zJ;4llByAveKbC8~RGUe+xz6Vl^haF!>lj3jrQAfz{98nuhIq$4Du%78>UX9e?ENw* zS7_Ys%1=Ew9V?lJE1$9_meNZO-J^3H9FtUMc}!qLvu`X@%G|>_{CzW2s!M3SOx*9f zJDoB0b!Hl+qzlf~bl@&|+DPLArCkkWEa@EZ#JuE#&lSQwuCr+zjFUQ;0}>@U&+EeKT0jbtJvn6sDKiJ2~|GXeL#RLX70+_qiCyr`H`SR?+O% zHDIZdaUo^g7~>wi3d2vgOpr)+NX{}#^+Hb^del0E+NauMhcibP8Fi0v2h{rUTz=N1 zpTud*mqT_f7TyJDoJO#>IP)A4k8I;Kl6Y@Sx*luDT!qLR&T-qH!nw^+waaWYXU{#V1=4 z6=;u|5_+QD#*?DKE8EDoktrWG)4;*22g90w*-YYV$4B`=Bz&MB{NZ?% z1)CT-?cTSc)sQ1AN=j!KED84?sHIySUMXD!DZuC7!n$ap7p-M!b`Lu zGWAS?r}-L>OT8BjyxvD52OC;7=)J{ZEPZtw+^0qtvCcu^qaDzN<02!=m%%DQBmDhq zb5QUdjF#&5)4VLi9E8XKpXX1GSYy0rn&m!MB&v=v_4TWh-MySD<-tHf$QdGxJPC5mf>jln`m{{TF5{Hez=uXPq^=+ksI86b7X_|&|{r#9t#2-xBef*vrk!y<2t4al+*7>?Zge=1o#Cp6a6Oh=bDo4Y&6 z8!&r*Jl9)&q(^ZKY^LG~bCSq%IP6d3-l}QZY{o$p^E)vtvNLd4b~U%xX5)L2>{aY? zI(CgLH}J!BSIa^r46IJm?N{}UG6s@Kt&B*A3e4vKpI@&Aw=cBeZ6&|iQb~5P1c8!3 z?@qe4Nzy=@CT7F5GAIRpo~N(pPFT50N=OweE>>}IcyjJ^U|JZ*Vn_S66tD3FTB;Z=>yeqPrj zYVgFd;Nz##x?_r)*u~R|IaToNg5E}SWjM&&&Pn#Fa%i^^0PT>BNDO-qaoV~V?$K45 z*q{XG5_^nNv032rW0hnM#faUEoOiC6)slLc*%_7=SqE`Xo8?z6(E8H9hothn#Z_R; zKw;1jYDKn=NSRsK6(r+0;-ih4FENCyP>hax9+i5xqZXY?ZKXU{s|4$WRv?f+l}B}> zkbzWl>U}$ZTE1r!0rN;%PI);V^%=ZiN*OQ!Bc5wZNSmV`JuTIkKLm626oSMV)pPRq z&uY_amw%Xre6Il2eqTQ>OAnVFs<$P`u9|x8eath1kFILGmH;k8atO$)j~D|1#^dY7 zMofyhEC*~;QDCYI4xc2RUNRgVgCE7u2kYDNtvd}i-f6&|Wlg{XynaMhJIx>i1pXA+ zt|V=~W3k6M&pE88PEyf38b*E2n(EfogzCGCp)8m^KpYB|4OhvzR55^4s8+z^+PQ?i zm!h#Gp64etM=Z0>0AanjKuMOB`R6T1ObE4e$-qrEjR(EwD#jiIJ0? zp!(zM(zqiE)ZV7f5thY?lGfIC4Y`m7Bc4Gy&mWa@H&=1OWIKU%B#&0-zw29&S;uzm zA-UY3e2h*B`9R0ubNbgmtm$v|)Fn26*ep7A1E0_JuFNuzH!PWjSUVEwb4J|n{oo{w z;PcwG?XOT;w65UFyc7o;o9I2OmpW{=@iVjeb3=}udgC=|#p2v0vMK%9%eFEz)BOGw zty(dYx@K^?Iy-Gr(%l(8Zd7BBx_cV49=&Zef-(V+Nyab+2Wax z`qG6vzE<`tRIY2hSdZz&S^I3BR4iL+xdd(K zI)jl|hEp0`MImDG@}zT)20pcAFHOFf8c3L=M|s=XNY75(`cW!cB4c~KO~=#?qAbdx zl=Z;CJk-a;2(lF)HvoXWhfn8O+a$WMPqQB?RZbO$=by%_d4@!0nGl%UXm#z*ai7nM z=Tu`Y&95YFe{aUJg8148CAr=7^{1U)JZ)A+-_vtoF+TN-_Dv?3B!&!;ovOV?GsSbC zVZHlEh=+6t%YZY3$sH?dSXfJEYY^upq2I-*THM4@t%{NS45S_3=lN4*)h#4&jTzk- z1zS7={!MU~x3|pJu_2W<#tSy%^6`v*l@i|S5=n4cHVEg89N_fh^{pd-d)${%B1;^jB(r7BCks&ie**SHcq2x!3V8ysBZ1;qDH{;PVzwIS$d9poPM=d`&_)V zcjaXpi5bsB+M2=2PSKD$)>@;{g_f38E+X1bAZ2@wIRcvm5GC5NnYJk-jB%goUTtr! z-`_a3hEjKu0md=ksQ0E%scQ_aa`!HUR3jmNq?3b>!k_kaRP5vqzme$ESwda>#)?9b zjjgkmCpoHTN{NRhN$a_Djoy{T+jxUnX5B1_AUMjn$F)g);tTjK;|SY#6T4v}=EiEH zhOZaPbW5!lt4C!9nk2dwrX^)n$Y9)pc;c;{77KfPl8Ga!Uof7Z=QZZb;@x39)e{ix zoE-Et$$Ukq-pM+_JN%$9TyxW(>sIiUp6wyVyjIBc*%d8t5#x4mnC=kn zwU1X@RJf1#a(Qzm6!I|M_@*?MQM6)cT0~>CDgZ_g0Q%P_WqWrO(xVwR;5%{-GthhX zu7<~2lJ%vMNSvw-!ZI*W1B&w}IYZ)CM$oBp(A3S#2;zx~=LKACJdQe3W}Qalc;;4B z8D%GodLH?uhUUjrw`rkL(+A6K7&+)_C%uVbYk49jNX7ye&Ozz^eX64Qk7#ic zF~c$GjGlwnitC;>t+yppg4Lr=`^2)_K4OasaIMC1?@j*Qn&6Q0tRFVjkbnUmzvuL< zYv?0m5iDLl1AO0jeLjMkk;E;wsZvxPi|dY0r6-E1C@Zl=LN8-QwRsV|wwmFbeeZ7M z)8)C6^C{B-8BpemaiX#ytLGu(F{PHOBDBzctJZIMY*2S)E$N~Doav`JFp zXi=QXN(LBH##cR0<4k+iVzG?N9)XBw26W!o-ky z&umsIx84e|4AbG_8^|XvNa|bsKgOfCxQ0gyB-@rv(l5(^r?~!OnoF(H0U#_64&^8A zf^a^S7M75=+2NF6IXjMc+;fajwzzw3NtK5ACSu(;1DtNoI(t+w+(Vf`a6=M9li$>5 z)}b&PyEf1I&A8p3!14L?st;i|k{x5f5^Wv89AKRG>sJUTd$J{6?vbZ0~&xND4Lp1Y6^p3s-FW>gWk#C!ZbPpv>}-E%t6G*xHiaE`V<7R5=S>oTeC3jF zm+rY4>+AkClNGbPnyg4-I63M+`t<(*?N8mtw+zgfRRr`0JxAlkSbJ-DjEG&1*+xO+XVco7e{UL# zbSr=q1S1^vBl%Z7)U-B~r?~4~LPpsmPVtt?LLzyY%#U;e#k$*ISC zH<4oHS$7sV;1YA1hfta*odTKUn6M029P^HS1#KKP^k~c4x76R2-J8r*8_KXDPaS{y z)J1D8y|i=A%b8-_FmhKUj2wH`HHM=iGQ}DR2G$H1<3Hg~OR?mM#D$tQ$X9Lv&w7um zwV`UMu{5G>IaMchJ9lA+Ue!kW8>NZ^ZXQe^<~G6I+?>^MdvR}THPMwNXxke(`Be1k zJ?dC>S);O9WPmW?Ks+72&1k7g4`NkLZOqq)R2QZjt6w=}Il)hC@WYL3 zPWJ@UCo*O~mQA0$%N(yfHV^cx+G9y1sT}RSz+g)rq+n!JR(GpCxOjIi_{kX=zy$tP zb8}mt-GnNt}zzTJ>pAzy-QMF`FAT6HhWI}#giNWFik!E5SXt_ zCeJdd%SiY*$;Te%wVqf^pon9IWdb(Kg+E`m@XoW zTtvgm-Wo%J#&gfNHFAWVnn0y)rs>n|r8#%Xvm7ZI$II9B#WA$mCB3vFR1rs!_Xgk( z9eV!&jbg*EDS=}~C=~wyt8zN}kEp8);wyDnV;h-*oSvAh^xn`dh*8b zTn2lKX)Tqp8YEn)7|u^oRvO-LvA@bf<0=<9>)+C_hP4!v0lmR&HbL$?AH(_7QtRjJ z=_*JHy9L?14c{M!6y-*&nne3Z?rmG!%?-qo$Pt5Ma0|{r{{ZWgSHvJlvd08uFbKyZ zaUFjeIAeRKTkou`H^f=m91 z_J>yvoA}w2)9Hg(hP`UAm5SrcjF%3$8Bzd0hgz)$x_39s#X|h7e~1yBarCW~O4e$^ zmmrh)V9ykOXYK;TNW`58IqUW5S~dXLMCh>)j5j%BoMC=!AHaTfNNcvY5R>+XM?k~? zMmg#Hsx;TF5!yC*$ZVk`;Bt5;+Z7U(SuR$FoK~pV-xaFFn@~Y6er%F@o-^svg2{Dv zHK7onm@+p;$i{y@e;igur+X_~!j}F>kxmZjF^mvK54}gH$Yz<^d3QgU+oT640RE=4 z_EP2NEl*n=NrE}0E>ViQmLTvl2Vdt^wG(1vQ6z#kC*@?$M{nvYKl@c!6-Fi7c|7N7 z#}w;rLEL6Vj!4t)6&T3tkIuQ{N_Xac3R8~6kV|n2?P8ZQ#!88}%Hy{kNyTYt^Fw%2 zS5h2+qbY_X(4O^?9n2!;HCVj8&Iuv-H!Bl_x}JIryb0Tb1Y9AV0@vKw+xPIO+NMsH^^gfRls6KGtcwJYky|q zn`T_f=Rj_qtxGya_+OP2dU20xY;ygbqXgjn#sTsOBaf#%RVeRLDc%zU0(QG#e4uy! zRnEm0nbIi7m9R6|mvH&SED7bY*RNXA{`G|9 z+P#a{QYedHC{vKYkj05>reUqI*150mqieF=vOmyQ7 z>C&I5M>UPiajbyGfDP@RlRlomPkOFhc^lMCz3f<+qQ(Q`{ZMwxbGtvwkJhT$+oh}t z8C2XGdu(n1BR`O=yVD{}3^xn0#zU@7Ml+Ah^H!#U_Y?V&hiF&k3z3eW=kcwTJ1bvv zJG<;|+q^JZI=S;O#nwfWjz(~M_Nx+`Ynv1+k(yrt;W|;3noZh^Vg6) zf5NhL9X1)}TaPWB<2b_dP6tvtb5FWy=PLH@-cq>vLgWy5HET}1f*JPD1nSZNLvS<5 z2R*aauAC;9J<5_#-70EpHN~dbQPjp8nKY&O&B+n}sPuv-}9HW9y=B;G`s#yim&-YF(2Ld@HXOSfs!Rmo`F zv2fi`^uRsp8>>6pYg?AHxMp>2<7*$8cXU68Z>?9cyb#*`s#iubDI|b!0L}(a<5uIl zx02s@nRhgM{$?LJ9R9fLSzby;iYcLqcX4$*FCYRr2Pn~!0mcaabegoU6b4wW+FiI2 zN7Q7D9FIzE?Yi9T3$zyn$p>!EF~&V}ikn-r^KD^~42vW~Z zNpPSH91h=wYsq;Nx0i1T^4=jMagE!uavSrlB}#E>T?HFj%!=p3+H`i(Ge{L=OftGJ zUZ8{9(x}O662e+Ippq6KxFmuUaezHf6yvEudo;16as|!`vEz;a{{RYVMFqjQduyj) z(SYcA8;4(^7{U71mY3SOFUbuWMU7> z_al%+M`@Ortj;0TtsX0t8akp*4LZuMLhT1@$J3sD{{WpUTtLjfXWO-%NnGcjr}d>vXstr|F>Xa>RxESZzI|#Z z2sNVAsL7^Zga&aN9ptt~(ZS;!$>*DGEy{@=V!~4EcDI#g5j_ z<8wsVnKxb% zj@jaNPdX{N`3XCE`h6<6&@8Sbm15LkvH7rqW<8HW2p{CvYj3L~*o&35LARiPly$+X zQo&)UNU!!)AptCoMlv}#tz(Om-RwuQheMdP(bhjV?RU1@NH_{}pL~j|Yo^1fzt~~E zLhf-9@`+X>wtvT^cK1+PO>9;jJ!K&V1_JSqx(;|eReL#fxGpwDY|%)-x01x+82#lR zfbCkWY?^Iv@+a!?x=iLSycw#)f#k(6%olPu1fOo+^_6v_&lHUiDAFk)qMY;GSEYk4 zn`&eaAOvpO?URyv{z9-kn1qWoHj=8Uk-SNedi4gXmNs(U!8|lp$0KiIW)dM+Nh4kn zhBsD&X}(Zd7BMuZ8Cd@S<(c$7K^3%Qc?gv0sKr1C#2%RF4k{V%;8Z2FR>Y^vkVd#5 zj(*ey}T+*rN42*PKMb5%af?8q4k zf^ZKU*K=_aUnpg_m07Ye$6RA0@~rz?D5im=D($hbbA<<|>(;l0bk*6MsXN&m)Hdp} zsz{>*mJB%O{3-XA__{JAY`vF`-q^0W^l0LM-AxRUm5?FNCzJfURsAPLwT^T<_M@@b z7;-V+2l>_$#X)Lm8ZvIjpWGRmcHaW%J=^IM&^uVH9%7jr z%?>y@0OWcaW|@C(*NYrWOTs}P>WW!;^&fP&-Q{f!pHV`0cGT>Xz zbo~DS3Z-(h*aeQ=CV0_9NJcqecpr#09lWH%|LA z0viZJJIstgEUS*=>GiA7>9UJ>!XmP=Z8_>kWAv>z(^pc2$#9<{#lb>4^YrGMrNcb4 zq-B8%5x{1{DeAw0sdI8$>?KOf&AB%^Tq4=v-<8UO+??~l?T%@ZPkA1lEy7zdiZF$< zhCbZ>pM`E+YO54U{iO*FAIj{bA-ElKIXw3CsxRU@dr2A(D9LO<9$1eYW4Rws(y2yI zXx)`4#c0`1)5S}6qI;WXiYVj_%A8~lm1@cD^{16>vkNNa31U%$cOJB`+GzUCyEG^* zq>%60IOKKXwP;#sR(9+f8|mT%alC-5o|qW*{{RY#v81-qf{SM?+AYdnGkvLYA7PC0 zWCPc>am{F(X#SRCxv@!m!Ej z$m@>3rB!P?y*}jqj9e|TKngRG6W6^{zdEc8E~Hm!KpT9q$XxN%ag0-r9m+~kXeA{T zW+L9|ULS~C%V%>SCw}!iw)Gr)RYBqiBDjstpL&wU;F3;vA3#5)Yd?rQyIt}n)G}-V z#Do1|9nT;AYG#+>J3FhjlHp-0h13P@c5%WGz8P7Qen{g~xH_?}E z<{nZMa)q+I^U#2MS38n#MQa);t7<<^x1I^*TcYzu8wyrFG4;(+)HKC;Wx7j2a|xM? zu1?^X##9XBJl2ddM|dNR(sf|vS)zO{dSu|>fAy#qOtGv9c`e+2P)A&bW*N^N$>yRh zsa&R$M>QpdjDSt2SWD+1^ERWAj(BVzcx9S0j&H{uLeGp4z-&pu6*81DNDeBvu~&)zj@3jkj**Jgsbwe*XYUxLx08 zk>+KUNK&}t9sd9<=B>7jr%yK~M+J`z(f!hR8C-r9ZLBX~bZDoQal>P;9N_wzj#;%f zk>hbQNh4v{WMpTmp8o(!T<%uoVsT4!R$Urd;0}#rB#bk(#!>oo&-JSZMv3qq$XUvu zlnP0~9=@ZHdeToGsRhij+{Es`c)Cb&jC%TG+P1Cr0j59=!Wp26REAXDjyVMWUiFnp zPAOYcNJcHYoOtlvl+6qebrcsY7(8H%k~#b`DE`AX^G`Ho)9lKu1EvVZLC3EcHPyAI zm8@zuw=!E0Njck*ydM2}k4lE-*3s1Nis9u7H^>PEK+Zt=)%$rpH4~<+L#ABm^G6I% zGBk^V?d6g^GyIKo7P@#t3&k=CRW=3#DC0lUxrwdpt!?AEvNG&Duo&*+Jn@cAT>j9C zZ7w;jZp>0!pOl3vSa5!2?TX>Agyz;avowU#R%M7GmS>-RxwN=h2@=G2B)sx)J!>yj zhU!?iO|@NHfVs}z#-}n{%N%!6&SJRQdz1ya$vux^GgaZd`!&3grRBZgCp%yiAbX!BmuMiYaz(OTL@FbiN9l$D&9Y?T=3 z4^!Hm6{&*4<)z#ij?fQ${{UKLj-=mhNS{yn%BUD4gO6Uk@mg02HPx(U7^2#evq`*T z4crf>^Qx667L>Y<3z=NQiuwG|m?%kD^SgF=$u*~^&lT01y~84*Qc%ZEQGIKkr|)~)H<{q&lEf#fanf!T6B{d?9@!%1I|xYUmA9VB*lP)r|x7%7pA za7oYRY8AY6vyfcERh9PzDaHo}9^RGDzQ1!Os9;E*NWmmI$O4dfis|l|#0bGgRZ*F- z_;#b}la}N5ut!63scMc=Q^Eq{Y2+Sr?c1#-y`#08Ow$dk7$?8X4oS^Zmt1GJF+L?% zAG~)sAu-$W{VJFIC6^XRV~)o$720t9amRjxrA%=1YelI}aJi!#i2iFXzgs#TV1QPts^+tLvx;U$@S}2WxkJ1xm1Qy8Z(9%I2?YRXq_vo zL~457npW~zJ<7Ad5rdq9mOd90No~}gboVaa!C@OsaF){)y4ry(~P^2_IqMmMyzR273EbHOmyZwwPO`x=4Ow8#fF5TpvT)t~KDN%7o!3 z9%9yr@JAA=FGLDHV8pM#(>0~3M6ty@=*bZZPUblSgZ?$gX>*uvAm1AN!|z1H89Wi~ zis-Ikl$oI49zp>bCn3&8K_8WJ*QV7?%Y?5Iv)x;&$1sp4^;SJFPvhFPrHb8Pa}$k* zBI>Kj8R_-nux@SI!7ZYcMI=hCA#7l%>B#g49`$SNv#1vF6+CWG4?sJADk?!VwHzI; zivrGHBhA{7j21wrs-IAL8iMY?OF0QF18S&MehJScWPK{F>A$zJ3K?XW6OhN=ixG1* zvMk5TkdNXV4{v&;q`l3lO$oWF#{#nI79YNqkg5pGsxe@0a5stq6Rm-2Cqhb33!#s~?0Ra|K zhU@hoQ%|#&8`}XRT6uCV3l;mM_x$*%Eo8QyE$=Te?#rLdll7yIL|7UEZjXG|?UCk5asKFFT`@3zZjwIeN zKm_tVu~#oHrj1plX;*0Zk#KU@Jbpv4{Je^8mtm(Ok0M_!;v^L#vB2bhH4da?O*+yGG8z2L?j!hk8}uN)(qV$kc^5X|$sv)s!w^p=*SF*;@xv5zBgDhZRU3fmfJh(IRcpH^yn<_= z-m(c*N`?8co}=?MrDfshT4t6ux_K9pc9kohpwgR3YROS@dlkR1>}89~65|-p%gL(m z;Ru>mB5~y?5t0s0>~Y6)z^&!8jTx<_igicY13ygqk~-$BOQ+2=%J%ZK1fQ4@kZ=dh zgIw{%PBOLhHufo_hix}djf3S{1()x;j0^$E6>{>*;@%XJ)T=Q@c}b9D9N_WkTi5z@ zcFYaU%#uRvN0h6T&p<{wz!@j$RiT#LN-d>ERb&GJH()k1n(X%KNi>XI8x%Z&r@${2 z*dwRUxws9C9D9F_U(@w#cw|O(iYVNmVn+v{&mUTn8(U=2=hLqw^5Tv{;kJ?xc2V!e zNj8j{uZR4bP>iZcP@@N?M_z|N%-1bRLV8QRzDALz)~Jj_6~ntg``RhI*InPio(T5; z01C1NtYQAzGJ$pm#xMyu$J3Ej^i3XHS9#vxGcX&lPT;`f9WmFR#*9GXrpNJ8yZEz$!?H5W^Xx+X^ufccr{w_VOwb!BQp|0l{~R0 z13#$tu76I4Sh1QGGfL*!)a(jDkB~+Wp&VkY>3X!fzN2*`1&r-48Ugol*pJLo`kc9( zlez^_HD--VX8St*sUk6>gA*VmgU`RdasL3t)v90UT`~oDjP?R@yM3y z<}h1kGn8^U9DZE;R=usa*=>NHXmG>;#Xu+6^V7E#m1tS*skCn|BcE%fh}Yad z^P^?p)0q1h)x!cY;`tmwf_0EkX(OfKW;&B-6ZFzFDJWn=DyL!2`BMHS{L_!Q9t2$DQcxHlJ`w92}fhJYwe8SZjFDNdO9n=sr`% zMh{N4QNzWi;vwe=fWuayj>8FDvyg9t$b9AtiUN)A#=PeNlAXQ7uA zSHkk_+*qbIZdWp3l_UTFt*c!uEv>EC%DQCj>dTSHKE3Lr+04rv20{u(VUj(h;YZB8 z{*|FErO4Cbf;*N;qio9A$Cy2bp&perV;5x|3W8g+K3U$`{>x?zk1l5p;4<&euUe)d zx{;G)lKFmTm_iMzGI{(mGgDaTwz6G$KWLfWb~thX*iR!K-&)ohYgx}Tr1D|oQg?Cz z7|0)p=~q$vCCa}PB%GI#O2%9Gpt!fVfO(EL{J9~y??B1oe0V^CdH z1`j9t5m!aIeL6%Dz^tUI;NvGearMnE|dus=4|+wat7t!Yub7I8^Eyb^t(Jfs#IX|UVk4<>Qkvz}ltdZb>`JZg$RL0&3 zZsmQ7&g+HR$FKO(ou=;k8O1cL3Xxj~rntCB+CjC80^7$-@y2>qh1_A1HCcSXu1h+M z5CHx|BBFahE!NUUR1(H;-Isxn$cnG0$8!39+2)UVZG+4HCCD6f#{ksc={uKeXjRlL zqv|-PTR|uGa<=~f^v&D;QZv{Q@7VrzQ&7_y6cQv?8+@{ahQpK2 zKdn)*7aB#(jXckWAYws`u76MdwRGz^D>E$<)aw?-ou1o%6_5-AmQoKre;&17JvMs= zc#0V#Mq?8x$#1FpRz1F?&v4gbLmYzUb80zLW1(w#lLkc9H!+T9ovwSWL;r$N+Jb-s=6Rmt*7|8qL@=HI05gE4K=ke@KGz+? zJc7mH5)ed(?zcU0$DscJIjb>S%PyX~%6ZC8z)nU7Op)84@@fHQvnXi3(Go<(HgCuv z4m$ShRGb=jDcqLcOH@aK7GE!KLNLG{xcq;WGHWYmStEg7If>flJZ0F94?Q~9I@gow zw{B#L>Gy)6cH~LlJ$=7g(9z#yij&VSE&yoSL(pe9{-1?h@cfIKB=f0hV?+BoI~a^! zbdMt(<-Sl(I%n{yFD&L3fvu%7Gdj5g9D9Ewnu}OVgXTp9goA_kazVy(^%$zK-5)tE zgqvIt2^GDIQnMF1>x!Bfo!TZ75F}1P z>~r7S6%@LuyF)7&XPq*9u)BVPKDg$r!7Otrg`$u!J4W8evHd8LX)6VjAiubZLa@xz zMx{3sfWQp(1K*#eWnJluZsvcrOXVhUy-REZr$5rQuN`N9EL=#NfcZ9KjNst*>-tqm zUg2l*e$>)JPV9ls-b(^M5sK)gH_Ps`Ii%jDdz;6KAPNcX_Hl*;usq}r=AUDHmo`y- zrrCmS+N180JAQ|~U)17^Dm+3lunZ#+hEvJs@v7LBZPFs^GDcT)VE_PUs6MqSN=aF2 z4ld(v=4&T;{JF$!h_^Fk2P9`7m1JrcCTn&3PW1B5UY2eLu{F7hS9gwa85=CCbf;@B%F02>{L$>>Qmc2%(j9s7(##?Wr#TZ zKf<)_^;pa%NnkO&Y$JUA)^X^4IsEGyX)R*6wPR;22_s;tlErqM?#Szmo<6mv@}!ny z&T^ZxwC@Dxu5r_~6)C}4rDCApRwCa;_L(i+_Q*gnyGR0@jDi97Bvq@eE=dqe9P%rw zW;{Mo{mAd>n!>xak5#!@rxkau}%cI809z(0*vw3%eLLu-1h(=laNOojmb!;YkqKPtZ@*KG^~ z`#egB0OSqa86MY&xOTV2Sv zD<+ExJ1;vySK_p}6*j3Pu z*c~zLNp&TPpq5=cO2D6*Nl4^&!TkL{I?__SmDAVIX#E5t+FIG)LESI}R(q*u20MN>OM{Hy*o zO)fNxL9ynZKa`;oF?40y!TjpH(`m+kwQ2gKmU1u(QB_$Scg1V$o4u32;7gw_?He-a z=4nmZ3wMKo=SFZx;px+wp!#i|tunc|L-OZ*XRbNN`Sqt*>WOAN%Z)`j!Z!5Ute&4< z1yQ)vbUEh{3Dl9f!@^3HW6N>xN-?Uh%> zPL_9e?+wkXs;)@f0QKPXtqAWd^*CdKJBL0{{o{t<`e#3tQCk~A?<%4&#|L*K7#nHE ztXpb(`U{b*i(8|=1)a*w`3kW*kjIWe^yyieo|APHjIoP*h={`u6@dC4^$p&hk;ac^ z;T^^qF^mx0aA~pXWn@2Y(w1MGD3mb5wg(I|gU6+53Rd@{s_aarz89d|eI?^?lG_$p zB+3_I9`VqSbJsPeWgDc^Wv?J)LFMjXay>Ka(w_{L_t1-bK^bsMq*C*<+<%c&FCJtn zv+3|i5RtwFa7V8k@-g(OoE1jX60}W5xfaQ6ZjxA|2m`i0Ly^#cb5Lqu*^|Ten`VDF z5E@9BoB_~)dXMm{a@^Y7>8#Pq^AdH0V6MZRy>p+!ijk5{t%-%6c}@`g(WcH3jX!v$dX8(^M6anORp1%f=2zO3jk;=FvXSCX+lw0FJ7}fyQ&1(z5Xm zl{)>3;27@n!xB+j*nf>VDaOv%M5LRtWVU*mY6z(N@rBSyvInmlEu{nXW?d9LfPJj)Mo9 z#VENnjT&hp`L_PekL|F)ZXwAsfZ1X>AZ_*MJbO@e3v0W#h8s!BDGZWCqdzdtG5&f} zB$cgfqm>Fqlcwb^r1Q{>kEeRBmP>JRW@#jXbY0+{QS;x|6+EfyJp)_lSdz&uCUPwt zZ3Rlk`1k4G^Qv({F-5rB>5vX7W!83YnV5Nmen zG>JXkylU^A!Ok1MOnw-xBI;`uviXqtUaxV&M7!O#{gvcxrFbA?fCq0{Tivi5c8=mH zRTt+%FyB$=deoE0r@?6>poj?=1$X6rMo&>tn>!6eubm~k0B}Ta)Es+cRK@%2n?yT5 znSM4mY#QF=LRA1|8(Tl0;Z!c}AIxic)>hmy$7VqH>D%6`!{Hk!uZ(Xai8GXBbIAO9 z)9&jD{>rT|>kz|TB zEP_wrBX%+}59d{FtgfVtO)jK-$3HMqL2Lnm{c39%?n^XRR}sq@Cme7FIQ?l(QH+~! zU|OqKsVz)Dl$rEmDnS*r_8>;T82ltdud^nP=&!)LxO(_=%-e1p___2 zd2ix*WRf{911AKw8>si~Pjz24RwQ7H7IFsAbJy$7HBSEkR*KtDaUw#n=L|LF#dHriATYJF-8>VntP!8S+6(VUj zj>bPR3nw|wNeA2W{HvWpT)fUkj(rqM=fm22P0~jBywo8>bDZG%Q*|9W-brI7HEo3o z0yqS7ib>(U1zs`c2%*l>#O1nn=qYXD7tIT0g8+9U9#oa+N9*{|t4`d_kCyr*XCabk zu_OqR2?-29z`^Z`si^4SiKS7|nFABV1Su zi)&dOh#3J(ae{ve=BZj~s}%}K-scN-r%&W;j6ur+pzuAj`qt%y5I|$LGsGuS4hQ#$ z>OFB#J&3x$jqh#bfeIhpxFCbtm>SY;S&=~wxZ2pmK0SXCirS={qigJDp~}ZCwyhk} zn6F`VMg*zP0~qJi+OOG7a5&m&YbZo8e z7Tz%7_J9d)26-mArBO>uYHpzSM0&s2w6hyJqR3BE*kgi!&uYbOa@t)-d1aNPR#K{m z45!=j>sB@Un|~07g$pFHD35SnMh~xl{=HJ4MLK4qYj9RZP=T1ID$VKZj8{zvMMK~C zjOTm%uR`tY(4-rm%Z+$^l{_A}Kb=;6avO^gwa}av1gP2w$2hKuG+TW~%Yp5qee1bd zPbZ-m{{ZXNJH0;HFAAGTUK}#GUzf`#x7V7=oZ$3*2I;4iP4jG;GwuD zpsPAozhf+NnIr;2Nd;7|0CWTNt6nGYiY}cTw&=06I4-FF0P8Y8TIQa}%Vc8_MFS#& z%pW1Y6J4=|I?(3sL%bfQ^J=EgrrVsfwgs8>MQ;Ao6yvBvBv+GJ= zP9xQSGSjZQt=-yD9mgW^pb zL9BhI3%7-)k(kD@DG81+Gus^fDNu*+T{$aQCZ8ge%GyQN{{Sm)(jOVzLhR?)rCn!| zM%;+Axh%WLE0751+Ol6$mdZGmNeiht$xsH<#&9|xYShziA z=_|h7ptk@v26^_XaT{yLhG^{yv^+?_97xBbXQx`mSY;^RV!fkI%GNB)IpRZ$EnziM;moiwPdyR*Dm|wVXdj33BC}e2fNTat?BdKWPjdD?!oN?`% z?23$`b-FT?b3W46NgVJAZ{vw$s|e#^qI@*~CFZF450Fjb+{I*QPYF zx!H*^(e~pV{{Z^b*!8_(VQX}={o0Z9j!6Tr^ZhG1Vd_iXb_C#_gpoC*)=H{gDZ_yx zC?FBr2mJ6WLr%1sL|EC;K5Qve!w`CB@FuFoufoht&8r~t(;347*f7UV^}d!CtsxFjE>$1okPt>#ejIkKO-AnG zCbzee3H-Rp^CU(fF+ae4u~nZ`dzo4oAZab(zz)m`DCZ!N&(POYBD9w(NXkme$&gy> zH!W|zSmeYYux4BiNCWY#gu9f;@-xnmtNhYNxhl=j^Vc=d>C*zTB(9{Z0#|T7dV%>; zz+i>uiCnjstf=5)b~xj{Kl=5eBV`~Xgj<7j)*mF39nk~!;nie+%4o&I+hAPVZl93Sktw5W=L5@#`imcVhb=Mw{hR{ zu0ronzte6R+8E|h9vBA4C%!86mahI#)$Y(nBLE~QpETLvx9i4hSz&$K+T)E*heIZ_ zZ*ZVJq=8#FbR*=!`EoJsR$d8qv@={;q_}qoyA{fl zv=Q9$e?BU_A}d*mS1*PQj+@SV=b*=WZv>j`#qI3%)b2GUwz+s+H78beW&1h+KwKWo{-4MYm5&k2_>g4s95(}whq3Efw*D%(hIpEFl2$)4ECw4ry{l|C7I9a%G92o{*4Wh3 zHHa-;gqJ|MUChOBNX8CG@1Nu=PTNpRx#Vc#cDLx}DawK}Fh|gg*C^VOMR?Z{>}8To z%^6(adRB$4-NNZo-pm}rGmf8kupZUXQkSz=NX=DmLuU5)rn4g2vB*#f4fpuyM}Mtq z#eW6L2Ur#-Blm{`jyUGIO(xP?xXtNPwN;Rv!=9KY^&Hi`G|w!}2y+_kA2Sb^Jd9`Z z#d)}iJ(Jkl4Zep>_DgB(S9$qym6AV{k^$%3R(0w<#jGq@jDj){$I#;#2h^I5JE5k- z1a~7SiSopa!?rRrOrxghXHM@&@ERVA+GvPq&Dp>ZT=F5F@O ztl_Z4l0TRAt8!ai*+FpWc_7?CRB1k33~}F&mZ?vx=_GBQIjzhfDux+WKA`pORxb4` zIqYqc-L5Ab`J^HJ*v2qDdSeySQl26%KJJ8Cn@-ZylTW|Ag4Wu0w~WC#a>*(J17u?z zi0ex@K$j7HnhR!i-U=?z*f}Q^i+kc&?96a^jT$E6i6ZnKnCwky>AJezPj4GS>4Iv?YnJb&MDB3Sf<9f` z^!oFPcCVsoa9v6RMFdQuMo}gVXN}AHaaosIO6pU^X%)&_{g@CA{pETb;C1g^9MGIr zzG88dUZ$+RB8uJYZZZo$%btXenaA_1OC)-Q%(6!+g0b%256ZY7%DI>D&giDLOQn_= zq}sk}jIVMRo}W`%mWeIAZ3J$NyE1kRE1dD~j+p#w8R6q=##d!VZuXKWStxs{?p2rM z;aOONoc-bL)~#FX(OuZQGYR8#94I;6`E{sm^wzmDq{zQ8+RDcr^Nf#iRMSk4PhF_H zRV3xhAC&dS^RA~#okY`mqnp||>|Aw z&wT!sg{Y!m+KZg#NaA2n3^Rfb0QDIHv$WYwoYvPSH@AZyEMSs(11ATkKhC+QPujsg zsMa!3cRNX^xBF3H#{U4Ha*#S>*RFl4#nQtk&F03Drd76{NX{}n`5%>YS27EllfF9BukQdBIS}6iUbk`lHF7}RybaN!nRz=ECfcV*j5B}-U;paRvoJ!BuDZq z$r*o`V6zWjrCGI?ZL&uU;bn-Oob;e_Df9QvPJ7H5=ERhZu06R+OZa zg#HnYJaSs2Wn3!dj^29m2fs?YYjEZj^M>)Th6G?9q<&R}1(oAzuF*JRtUTl&-Q)RY zuR$!f_P$(<>mp+%PImmGk^Xy{b$Z$L6dNr?Z!B!m72b9R$Ri|!V5oNzx{X&29NF4ribR4ch0p~uWVhdCa#EIQ4E`L?)}nTj&A6~n3a1EzTO>shB! zCt~?^7V0IEI55RFqlMg?h&jk3@vQGL*Hmj(5wv?-D}nNmJwF0-?_07%8>}oQ5xE;m zWP*JUw@=ow<?y^jnjL=}i(n;1F5$9@4+M@t zs`03!()lbfP=k%b9OKa9iyLOs%Xx^tV9w7mhX)i! zOOpLbly$MsBzH2{-4PwQon+-yjoBIKK8L5ZV%uEmFvikD2m&q{0OX8kpUS#fv^bt` zo+)FIvRUIG@HrUg*NoGk&{if{QulDV8=Np11ZR$&{{XFeUe+l+wK?1wlY4c0H<0j1 zzERr16dl{2r(9Om#=c;*M3HyTzbHold(|sFFHo_EZyWlulPH67)R*oZ9A zmjnQ#7+^Dl!R`%m)TauPQDsHAqjOKxV!M;dS&YiZ8~`@w+*8)>21iSGl0;xeGC?5l zbNNZ@kpQ?;HWFu`ukOnB}&I2aU7908|BE(IsJJ9-l5bciO@{yR7yrs7l&X72OYE4 zrf3@EM~4NcD(jJeNdO<~*18&Q*JgLKXw$WMWUw2gS8c7ibB9j9*VeHv;M60V?M5Kx zPm&kh2|q4K>DM^?>rU3o>=KnlXO+15oE{=dp>lEjdBJvxI~_ZF8cbYhB7{!!YdGnG-@y~cR0>9}3k#$490`7d@!wn-a! z0#lKkj=bZ)y`-r~g?;hY&hLJoT4gZ04uDo8Z+`%FmDx7;cYe(>agf2CBG1OXx~ zwRi6--CF~vrf_jtN^xyj6%{4B3uj1RGB3)c4f{r486b~*a4O^%1tp6DPbHbLjt+M4 zbK8<@Jz@Jzr0S8F*_Z`>bIHgbUf81IQ)6if-Z!TJKc+oBdscJ2$MB;`HAxNPN4o_u z%u44V^~dAVqD!QLcqfWKy&|DL-!~u1mq{sbjIQWT2QAc&zlR2^+cYR+j5-8{QV7q~ zgIPw=Z6Uc|Q$qJpgee;Xm1B@b2?qoaewLD5fC{U+y^)v`~I~r-M=qFuYJZO5lJysY_sD4F5Iy1 z_#D-XsSVwVM(qliz)}ZXcRx^Scu^!#w3!dy+y}lmKHt`&mr7Y$X{3}SWRj!<)b-E5 zADN+6T-R)Ny0R*HuG(`(Q_di$S4jY5jDQ0J*FAVN%XuX*!y4MfbWw81@51Mf52iWI zBziyD8dC@FVUTS?bDg6($FKhYUX~bM*@^o*$cmt_QbzIV`E?c3Il|V7Jg=yyNg9|* z9@a}Yjra<{1MQzmu|Aap+8FIja$QL=EYr$HM}O=2RV!^#?X83p+{e7*49pasdLGp4 zON(~%5Z$D&k_PXT2qUQcKdnh^tj{gX zUQN_0TY&PGQa-u&HLVVpZ6R=o=gPq<9OMEzet7RxH4QdBJz{xXZRANA_wM`M7!01- z2a4>4N-|upb16nq*P!`suSCM$b&lW>z4vf8^cW!YHK8na+JtJC5XgZ6jq-EHLHQm% z#tmlN%cg2F#8PzKFUrb|jGlQPiKwG%ODO_Q^3IIAows0Qe+VB?4t=UQZj+9U4lkqC z9VU}ur|IW(F~ZNVZ7qUwdC1Qmznx}(!aCC2@48qPH37F`uL7O9 zV4#vcI6XU#^;P^oqg=rAEcVHGjfPb}cyphZJRS#5D(iT8&DzTZ_US8(leml=WMq1E zs{a7+jmdKJ{{W?1EW`o{To6upKjJB?H+4H8ceS}lG}~J!WZ!3XEws-T!xW$sjQZyt zxbICtccxs*t9Ryu^C*;U$QdMiRjc0!UJH1h-gGi34p0z&QhR2rriXI`?9z!REh2>s zIRK7&_4?CFF77h9E>C8xNiMGT*qTQQ2+Vs9;mGG8^yoPr{Ry>{`)D?n795N!%!r3FO_ED7=Q!*;QctX3B%6xMFqMNOkhuQ%jOp(6~pic8SkEzabD_mHDo>Q5()KKq7lWZLvtIJE)407 z*~U2^LsvBYLe}aNF2d3v^4Nt1fE~_#K_9JDylHM6#>$dH7&g<4t_}#`^*qyIvABjg zXS9sQ3KO(Q0T}cny){GKzQXpFm5FB4?X?-CdwJn1jfW;Y5O6R-9Mb9MP|~hhHd$Rm zJ```1?p*M3o^WeDp}a>|x0*qg7)Br*{{W3T^50f>Lp~cEHr2r$#z^h&>su;cWyx5N zYPU;MO6L9ut)3_hRyS}z+$vpLo7Uo7X8n|6tgq%Y>N!1Zi?+A^Ze7ZG6Gj=+ zY1}|KBxm}1RP$fQsd=$9u!V~;k~$2Jl#%aLzp{}a436d1f7Hl(XE+q=yIG;P$$$dH zf`E(wIo+RJS0m+b-8W9lQc{ws-m=BLfJNK83CF*#I(4RB!6mB3?$d0SEOv(b$M~_> z!N>E6kXSYwwt#3*)cF@jpUC1rX z{832u*Cu}~49A?E-7*K|`BfXMi{Xit7&-f+W=?yKp1r;5pZ1lk&d$ws6wi=lMCE>! zakXd}8|-slLjGSz1coE4437NQT7!#v9PUb8OO~%ZHqSH{OAJ>ETgm?84jDl8&-AEd zoa&}IKGz-22tu+TE}b*m2cG_wSnH&!v3VVLZp%fI8@S`3_osU&hqWPk=HH_4iu1y>lw}lLM?vcjN@*Xy>LHu#eUV~KBfstis30K&XH%96} zKA)9Qe;iua&9WUM&5(i#axin$=e}!ZE6qMhQsPTHqzr(z)mGn;#(seI{cDb=HT~#m z@;9ctGNNkt7L2KVra_5721Jk*IO&?Ju2`0o-bHAp+#i}HQMep(cr~SZJUebPcA>QZlnoQ!2w!h_rFc zi{%9&RgXT$98oLDgqzJvc-uHqxXSvI^}wyWO)ScfI!yMCz@d$qBvYUB_|%J|Pi+a0 z%#vtbOl;mx;F&xUGxvU!r&5}ix=djvmCRdP;cD^Bw*|wTxkE;5vLM!dILb=>hZI#a>2jzY1xV8Ajrm^FP*2VH7@16 zu}?PENX%^^EJE(ubLrSqEbgA=413`@9Ht35_0MXl4ekEs60{9?yr@yNh{sWmDQ|AC zB#(TSsu<-@mT*Vu)}PhWT(;M_lbXHmL4SDG?I!2jFI6Crzgo|l=0QBddOQ_NF)&L z+}Pa1gO7gI6_u03Wf8KdVjXeGC#lcpQ(n8M%Y+nG#i6IkCkrD=gn$bk6l7=lRW*+O z-sCbm7g<{bbt{q7V-KP$8WFr(Fr9RvAf*Bxze<|o5yrV zj6%(p40f>2bDwHu?Y*NUmh%FQJZEU%g2O#H{Oe-hPPk1|GAeza%Vogh0FJn*1V3_IG-@RW*h_#U( zMFK_KyLjindgt|9E1L-y&5GdzleT6&j2wP7ttHvFwp&aGkVZVB&BBxXO@Z(FR@JGi zMXhc`9<4H^o}F_f>p$DKBRNw3VapEuXN*>^rFlG7tM*|Wu@Uo3RBjzI3GZ0?VOvN_ zXMDi7n5-~)TgQQCKX3#Of{jcZeFVx*)<(lmS2l-r{a7YGRzJ(|tJ{VP@vCgncY970X<4cnK4jP?Fih=@MZCDU9qcnD5&j>D(7^{q`l`U?>y zw65D%JC9;9#~!}*!&Xl2P&z5J^ktznz3c)hBaE2XG3mkd!K|tD>r6G(w=OD_VUW?w#IrR&AUfp@6*FLlA7cu5KUc_{5BvLEuB8%)<~l%BQOfG z4`J4+YV%oYI;4>qnHwsI+i{bRx=(u8(gniXOLX@Fc!*;go~|>~-?uf3eQz_EF>C>t zF%A9Ek(NIFsZ*R?XDK~LHSVO5g)Wb4ZKw-pw2_CKhgNZop!El@{{X73T*VHTX*{v1 z3e1c*92{W(06hMcrE})Jv=2RzLh7+7QS&K2r_=mt(&?=wi$y##$fyGqVUnlN=hC{~ zBbg^Hj6IdFV;1J#3&l51{&S3kVb>%M2=>P`+bspHe211tSkC40QSdk%AFn;@N9=w| z&j7V;%lqMuLmtF_J*r5>?d8H`#;EZDv@aq|@&NbG>53&$+R5l88|uf~+uYjP-n6O= zj8UV&%dg6EGx!04=~KVL@APWJ4^Q<4xaqiPAzY2AeB+X^D5**8YKL*BdWlx0>2OTg+(>FV6rk^{UAQ)y1+z;x!W#1LXOX6VGp@P@3ZQ&sAGi z)fU^!JDC-7%g?X9I-HV=RNkV4l6=x5@f>#+8jZ~NS}9w7*!xp_!vJTGOy~2e=U2+x z%MprrXgSJ`gpuo5_fi;=dF{+lO$>yp z!ZEmQ&QGOP9$7^yh$?%nxSIACI(DCP16*3G3xKS_(;>j<52ry)hg3s)WJ`FW6EO!n ziC|7ZA5U7Z;rqM2Uj7Z+U0pD)7nL~38sUruDyym$itoeGH zUAXf^+iQq#E&Svu7%OM?RcYEkD9G@Jc0$`adO_-||Pj@BKw#70XnBZi0#%isGoviuH*Ni4*%xwnZ z3h~q)+@4Kps!mDS-5Gl|eT$d=6qdnW?rHqUq>L#}6$|HeDrc@9^X@Nf>n;1ziO95!@=_ip<01&usP2_*P7M{F+taifb3&g^W4nSZAh3N{C%wGDPC$ zL*@|ZuE&AL108$Sg3(8)fjc{tj|v+-7@RTx02);}Cm(qPYBjclFR#C}RwQjK6By$2P^k?>91;mQ{VT3ZTMJt_E_|TTBjAz&2Pco^N}6V$eFM#JHo+kw zqn8Y-NbG+T`Bz$;R;DVOd$SN*w9&_V0BGZA%HwG}mv1=t02-xf1dk)Ei}PEkQ~uch z04BN=(WbJN+ZPSwtbp|&Cr*Q=G1|12!rnXAkO;(LAP&*@_|8E33gfF=lKoATF0?sK zNPUh647>9v4S~XupXtp>73B6di*Q(|ZLPg}A7?dFm;xO4?jqLbH#Khq+Lb(Csqf=ik@8I7n% zaS}q#StFHjdmm%RPX7RfYg<7IT13jO3EY5&-II(SwUrf>ypxE&>o8^sz{nh9KaEYR z-CSB)DUHGeV9^xpPXzP$RZS^12#PXkb24k&lRVb3s)-!B0H=_4@y30#^`}fDy1bb{ z-V=}Uky4)0Cyv%Q|y#%$BVVWRhJSiVHJxRzu`Kz){(ksdGwno(6 zFa|N4{z9^B=8QNoeWetC8v+R)-;bxMrrB%B_K&gM9vz59U@}{=Irro1N^$0sX%iN< zY}sVDxYLWt0kpb_*%$`ow-`Kej2f$R94!Aw~(7_n-q`8kv6)%bKGwHjZ7tYxh0{a>_axC0o!G9G++`F%;-Z55B~sN zPnZA*LHE9G;*3WrDGA&2F~B&;$o&5RDzABKVC9vgDdxyYX5a(UgY*??ETX&9%*Yk8 zsANV59C8mGh$g0Uk1Eu0O|eq(q;@|tw0QFVU=_QOQby8RN|#b$UoRV#`?w>8KbWfa zakOL?wnlj-{n^}pagLnyITc$}o_kG#B=aI!zJ1<<1b$sV3L{P4(H}LH%k$}vYSSbo zLSrgM3D4fg?;H9fuJ&E0Ivh-&15ErX3zzVVZ57qO4#>SvAo0#Vwa)7vB)_$Z)oj&*u*;ryw`_`dd^F_r zBBfX@(Wf?+_7TJ)lV{FDGq!P#!~Eu=F-+HSdDh7LO5~$~jo;6M&(fP|uH8t_75%hQ zTbPk{OLzYO3f?s;Uq_*fakj>el5gzuBHzbwh`SwF;fVDI>%kOW%W*xEdGV#h zH$*gO>${I?z&Co7h$D%W6l9)${&R)n`O?{4UBo<@X7XAbFm+;79CfMswVyj`qwC4$8wlHxXZC4Any zNgkbf%|1zO!^Rb3X(0*=X91U?BitTozISeA=o&4Fg`MJDtXm+$t``6(A20s^Um}*p z^#F>uHeuAOk1`@RM#KTg=y?@3r*N@J4a7GXGbY(k40D1B{W18_XR8ZzRgt$24*&zx zBadF+{;JK+PCHym%3GOp>P79?Txl{OZXHL<&NH9Jq|@#rzO}WB%97SN_Ym{TwN636 z+rjaCTBLXF5?Nd~SpwvR2H`;@nC z<}I+6dq!zA`Cw@Bi79pa+0HTCR4XikWLcpMvY^6(enEksr)pbmS|J&M5)?>|&y{}n z95>gsGAsF(4XT#Yrp`em^d7ydv2!ck5agQNuLi7bJh)jVP+Wj|gM-uj{{Tw8H;5*; zzLwYQ?4DbBYaw2PJay|)KBXGOu+LG}`On>4oUvPBF&Ln48M>^t=7_|-z{JhF|2CY!ot2{jEnP>CK? zYiYMG;UFLm*dDxN^{uTvqDV!gjlNW0FaS6wJONn}E89q<+KCmINK#C&&ALkkcCGi z?_y;r*nO*7%_Mf0R`~^qB^;?=etPD%Y%Mg~nN|TYK4O$8ta9plXP%&rl|i)-W{%}- z)tn50umE^J)_}_{Wm_Q)!i8|?+gBj<+O+I>X$dm3SoeaVqM6~ zf~S&y&$Ve8INB`ANp80-MJgtkgUMMI2~-wVAdp5gpUd;D$Wq4ZNSv4@WhGfK*&y;U z$FU!kao!!jX(tAG#Bdn_A((_=kVyQh!s`?1yVeO|jPKo+0EHc^j=e5#b~~F>ovh?+ zM3&aFNh3nDs0EfXPFESh;+y@iquxd3O=j*Gsa~gR1KXU|72dI_+cw`iCle4@sr%XI zA4<%g?&Tu~XpQ{F=rGI3Jag|_)5EuEIeozEC89dmue3<6Be;UqqjelKtWO!k40Jtl zP(8Mpb#f)Pmt!x?gdM?Kb_mWoW2S2X^oegHm(A4e;<}HWu73AD&rhXSgY7oEe9Pey z%PXUV&N2Y!1KyKOw$!ylwwj~Aiq^td5_p~2Za;e=BZYk6fPFaW?@Dy5OR3sFC(9v1 zqy69xe=dD1iL%yCmf*d>#@rN9mE3Si_T<*4pW}7&(Ip;XRN#pS-ou`rr>Emw6QPJr zxVxLetZinE)Y7E2-l=_MJnGFHuuTuj;PlU@Qh4uB%LB_S5lb9)YZGmbOL?5A^aOfw zR-*9)6WtjT$dNbzQjW~TX#Qs&sF zcW*ADl1VDSe4(?;jrXZfae!3k*0bT#KFqK}&hWI#T!E4Z&*XUL6=8&_sVt2Rt3>Ou zq%swJ4y3QI^QdohyPJ7hiRSL&E{V|H?TKWj(Ee*B(vYfaQJ359K<$L0v zeW+O9h7()dle2=O8-_<1_03LipS+$Z&=OE7#DM-iYby0FWRnJB?~XU74nCur)c)0$7nf2%h9wRgA1h-R{LMoe zNJB7aOLO;+2kVY&V&_VgOyzHF)G68{3U}k`b67VQBptHFy_4l&fC7HC*G{Y^z0;mh zlwZ7eI$UV%OQ3Ngkjw{0JZJN*D_aPyuF9-|K0v==iZEw)(DDaRN* z^z{|1YT|q7q8v8dmF`A5`eawnRIKj#Haa0sO-y;LF5ggQ-m4Qbuu?h#I(~Hak=jVv zk)j{G+MwrgPp7EOY2VxsyJPvcw#|q>;2$sa=cnIy8f%0yB%5*|;tPxG3)p-Lmy zq>&Z&yKRX#ZUZL`)1b+$aWrEq&L))GQnN4XcT>je9kim{MCw}NP+X5uv~qs9tJ+kp zav`5P->*e*wi4mdw6BQkUW9abBvIB{{V$tj( z7~HFs$R6j^^IbSf%{x6&ooaFAGvH6MY%yFWJfdaF5~m)StyjLD*3#Mscva+J?UVPE z45+~T{VHD$cyX?Yn)&15xeCEX-%mmR0N1B#mP~K=wX2&_N)In-J4QdHZC0fjPn9i& zO-?bpD;uXDXr06*S#dCKatPpz^gXKr^Ha8(>wLCzNL4`C$7my`(z<(nKGu1pwbI&I zV;B$TagO{R=CLhwT}f{*VYqc75JW`tmptH%axu?ZczILRy#-P-(#1ay+=$xd813N! zTX;C!dh)sYR>k(D&u1L-M)AdwD##b6JAHFkEVLUtTe(^|efVbhwaZ{Zt=Zi1L2gvA~<$AB0EkV)=EYeqDc zHt(t?P@VQHx@sC*MLZG1B#ad06aZV_K7dr;+PaPNi6`=!W00~YKKJ)eI*)2$QkZ(aBE*uYpGgSmOZ(`fQONj^5h>+=U8yu z*xW^^OL1u@+DO`FU@%#5HsF5|&INQ~qs+OQxih+UM$U<=&2w`aL2!oMQ10KfnHQ%W z0`tvIm+2&uZAL)|Wc}IPP?66a!5I2+S$ZS_8MX@-jSwy&b;krByidQl0dSQmlz8~8#{M^PR$+}LvR}%Gt~C3 zU&K1K?6Wu8ETKn{x8cDjJx5PZO73;I;nd``NY$=p#uh~Yf$B$YJ5+b@SVcX&nvJ~i zP84D@^9eZWKD=ih^`07~IN7+}l~SCfnomQ3w3`0_QB%EbN0I>uS7?(b?)`b`O>3*U zrG{C)&e7X3!W7(BoP6EL9-h_HYWh4k^E{T9Hqf*{6^cFzHc!k42R*Y>!Qpr=e302? zC_|(lc;~Mq_3O{QdJ44_?=*6{Q-11YJ+S$$buIP1yhv6rv_}t?(dVez4;{Zc)zarT zPRpmu9qduA@g${GfW1!#ARav`{jP_j+i6l*-a_zOyxw4vZdx|SayTQO&a*Fk9b(qf zTv*-Ak2&(#Azv+rUUT1}s*P$BR%+VlXz5grshvUAuI_ZmTJjfo?tv1tDY+D9rgO)p zYfjc{Ru*pXpNQ!R*m-toLZ`FJg}H8&;I|5^ZC(y_k-jzs9iP2TL=< zhFDwohD0HlWc1{Wfn3I=t82nEy7FQO%eHn0mOi5gik{z8xbpm&nlCO?XI6IKo;&BK z&~aRIqZlOGH1_v;4AbJ7HCZ0?C`TlQMBBi|2tQCN-Nn|QCB$mXrs1(Hk}Qm@MtypA z=Ac)$b2<`YbQxour`H~y)oRe#INS){R4WiUZgY>JqNPQCZiZ>uSYPe2Z@t3#_YS`( z4S)##=P^&>!Y5ZFS?N){nn>#sA`t8BBMa9gRmp6F^+>E`_pZ8yLhdH9#m1NFB>t)Ib0K; z!nxQk(q=Y};I>rqzcx4n2kYxrzp>RCLnX@tIcCAf%tt*tk~{H=^5qMs2CQ{Pa@{+c zH~OWWtS=O36e^sNle@o9V_C3jUuQ8JS%FC;1&Al+1e}gXAJU_e(mC0scH1P-d1DRo zvlR5~dYY>pptZADWs)gXS8}+14n2krGATlzD%FIf?{swOsHg@<+JxaxAZO`V7TV>i zUzm~@$I1vrP8E+lkH_%MT97TJy}Z#T$li8|Vv{UUah&JtS@DFqoUF+K60ew8a8Dx? z=+jG^o2aT(y{vE9I@}gUSeX$@?NNo=PIHf3)DifFw0O1>q_j?<3gK5Har);Nrs*RMZXr)g(q%?wsRfPeyJaCbO8Mh83t z#Z9Z)3k#`UILVe$kMb^esRMRBI0m+>I7RZMsW5YryJQjE*yV)wG0hZg&eE>%%aPOn z0If)xot!L@EHX4wF-2^Z+NyFtGmf;)7s{IH;|6q$ZDLPT`3jcuNuikC#kJ!x zg$?V^CnK@VX;x92<&e2#wM0VZ2-+#)Srg1m#^B^fChnQ~fGXYIv1@e?nJ3A;cDj|@ zhQQ8#gbHMOt+n@^VC+^Pk0#J?Is!B4gM(bww-d=2@}%5U1#l1X5y|(@Pr|ZL=aNXa z+*5C3se;7Zt)!cd5lBs+$GCd?W~t9A!KlY1#!Rw^%Z^6T)L{B&^sL)kiS61cV3eYm z(`a|fsOU%5ov2(ivqtW6hBB(^bLuxAQ-O*VDYt2L6O#eU++TZNw0wE(0GdbKc zbC1*Ytk!rnHkqYgJ~dOllyU*U0Oz)Aot}AZZJt(?mSU$ea7P$DD>_|m;B_&(GReaM z=s2wDVP7_ZD%a5NY%Sr_5&XO(Ov;SU8oviQ#&iDw>ZZqf7G_yZl#sDt;b2@5$QT&G zJYu4)DNprk6dWN}+)RJh6Dk1v zfL+UupHul&7+vDCcLlS*aaA99AHDr*DA`}sQm4 zY_m^j;w{0%pnzAlK*=85^sGpuX(DEm0m&eeLF0~1ZRrw9t!~l24j8UiJDeUcKMVs^ zRtlPJ8AexnofLA7Lf+Mkn3a{8l<}4y=M^*&#v+66U=W*EI3aLybLt5Es+II;s}$x^ ztf0Dpq?3c36aIQtyG_jl{h;P$V;g!Bc@6nsSC=Pv-E}&;*s%mQ)~#)K=AV@E3H!i~ z^`Cwp>`}=RtZnDCOrUZ`;6@K(Nbl=awX2m!5WeIP#ENj)495eXZhBR%{(gq9vHa;A zlN^JnTz0J~rmZP!alWX*xwmVd-A?HwftPPRx!gK-H8!nyx=hzGNA_`U$_hs7&}WRF z&{gZZi0ocUwZ7tIzh00@Y4?K^< z6{~RZh(a`x%0VT|D9fA-56p_g(&V=*ZERrk7(P++)19~^^!3GF)XH022-*WAa!O2c z0s^>DGEepTS0wEkmPpxMtCyj?N#heY&g=4zl!6!xwT9!KR_8s4SmSr%zZ?2RH;9Bl^#XY#FL(Y4&OMxh+-Ad)htJplCY{!K(} zlnF_25`{bO20kf3B#(upiG_*6L#0bGC#aQI8Uzd+?e=3&wP0huqiHc0P zbMuhc$=XNd`c4; z9DZd@a`vVr)n!}l&oamgAx?4*c>46N!aJzk+RBPtgCjoI=toTY0#D~z^V!(k+=h)M z`%lR-vE`U<2Y!e386mrNZ@MbDz_#NP}&|#?EGq@a$0W zxZ`R31x;&Xc{;qv`@oBG2ag4Y2>DN`J*u?xMQPO39oB=b@})bu}xL^+pAPYBAjxyO1!B#Zan_ta=>!@%*cCB9XNGZYzmbC5Q)a z`Tn(;4v!_wEM>fuO}03~!~sPh1JAMMtP5MacrERtkQq?2H=C2@aq^IRb>_OOK}qRj zI5u9I<}rw8jxUvzKJJ+AarxF^x(hUSh_JLWqb!dRCp_SB{e7!S;zzuW;3NwuSi>Fo zD(j47f1LAJ(I_|Z+A6Ge?;cbYAgbi&r{P647OgIUHtuLz+QH|zk1_^eSm*daB;ugE z)2;7fl1pV%8x&+@=L!d7-l#0o+er-Ga+_b7WmPA1i@N}G-{s9-({63%jEGW8XysrI z{-9?dA8z$dE(y*ol<)4cta9C3MD`{OMi44wb|eCG+>W{THBGKs^5*K&>eWubV=c(e z-h}736>8^Gfp2C=-IPR57-s-ykaN_ZYPoN7X{c`?M9y=WRe2-~{{Sl5Gn6kmD-kHC zqGbr@^&tx}9?Hxe7=vpVZ}B#TfAxVi5Mr7<){pJBd|TX(QO}@V)0KgBGIkFawYO z09{F}+n=yM*%*?nBX39OewgErtu}b<<1H#Ec{mHbauj#RV~o{7aTTq+mi}or>mY5) z-*-K~uj5KBwx!saTGlNlj<$}M2_{T&5>(|z;hx`GsDUMdcs|OHyf)*3ka}_H(zK+% zi7ePhJW@u-dVJh~dXIkHYNA3Sxw@AM(8}2kI*j{gwOnV-cK7Hhc^KDv7?#|K<0|Z= zfKS{YfscNf{A#K5>=>gn6$CP|A1(;#{VR6#+8wgRCgoPbu;YRO{zjn|>#-qMNq}Hf z=Yik9;av)|akPw_Y%=YmTS%mK<}%~U>Q{CTU#&zTx0>xta+sqk2I2`Sf4qMhy>kVG zsIZ1nJ2*SXbBuC29s#KAZmg}YqqdS325r%~UIsdnKf<|__g%Lx*LsuQSTyS9Il4R$rL^0C;1Q^anqHsP8O3)@|fTf=38o>aBv^2>!Kp&N=O( zD=7v@pUWVgT0c?iS*Px&b4@Q}hSj6Ev%ZwaZW<=TZbEPY9C7VZ*w1rw6o%e5CL%X& z>KCpudsjiO=@MNmUQ@-MK`h$<#{gvd{{UL29+PotVL6X%5;GDRbN5u^73!=^WlcV( zJEqj1VokCG9G3(s4f3g8dT@Gn?M*sb$!T!Xd2Y;iDTn1OJ$)%*j^;?qPZLVNH_W7h zxB%o1{M8cD#Smg1Up27Eib)HMNg8L2Q#WI#mh)tm=#U@ouCX3duFm;>f+~W2T}?Xx41YYejHY+{hDT) zXw0W+{v_n7Bb*=enu_Uu#d#gLWdbsOV;%;3{usp+XUf`plRL7Ns@&aaK5Ph#$u`FX z41tX2G=e*MNPw!wWZ_QU5aYl3=~{YpUQm`6Se7f0#3Gz7dzH^`YMAL!h|5UIs-uoM zUPn{?Y0DCno}%QviV{TDsGyZpkAlQx4!Qbs{OPumTBM=F%C@tI3|L^OBcS>k+KHgO zPb%a_#GS6=mF>y*;;TbrWX*SAtg%c%F)3ZhaC!U=GsiUwzc!sqRNeF`q_9T*LBWnU z*yMqh$o1)4k=R*W!s_xQGdx=v+|Fc=H!4*Pfm0I?_(gGc;7~x-&H|4@n-K63RBZ%vIR{#~^dZsl{i*;fG0BM$00p z!}*^fQ}jPk_*R@cjJ6E%eA1ttlz?!@um>Ohs#*L?b8mD^Q5cwkl$Ru-a-(pN8eM}?EgH(^0bwyQ%M`|CVo3pxGPv)NkAAhaE}42DxR%8w2$(97NIU)Q zr>N;r+ua#2H%(;}Vb~qaGmbsI#b&BXak`d^?=I0zU2bs?q}!JArCCVa@$SYs$=ZEt z^}oaU*t`ZN_?f8n8bLRT_TbUF^~7pZ$6~{aJYyT3=4%J zSr2jv;Dc4|qf$;v+)|8K+gV|~x1QEW;y|mo8DjqcSUo$8_o}ezHV1!~CC1o^ zAehGk9E^{xT)Do~?21nkNiKNHsMqu`A8@5NVE5y}@gNHOzyiU}Uziu9vO zFkVL!t0{FoZo=}y*G`r=M2!(#0Koj94u_ug1+Jx~%=a^hk~LNbBpu92=bZ35RdcD> zNfX<|-b6?QdqE^0TxZvs!d*03D=*qvqeU^`4#4O074ndzxn266w5syj$3yn$=eykk z;UdbhUUf>UIwB-KHmdL{dF*I?p;xaceJmZt!`d1O>-`iVC;tj98fOFH=KH%o8 z>1lRsTIfRm0KbrKUVvZ`yB@XE^?N0*hAOtZ9c`TO+Rt-(vq(&sP#yABy#T7V@e8$@ z3%yTqCntK~XFPPQXJW=T1aOO4t|Z*DGlE2Xbt8k@^r&=(wYIfsk;B}s?SP-%@5uJgtz2T)x}30E zg)a#G;BkO|+0S#%NT}`Yts%9$hsfOVjOAOaXCQRo`&O>JJ(^8xp**hlMT?g+SqqDa zJjn)0k<)2FeV4UTyn%|P%d4wKK2Qz-QaL}M{AzEsG@GJB&u|&n$>}l|*zSpeG;d0SNd%=F^2?lkdeO~b$pWyw_}eB2Y9 zA9~V+n@$3pZ>gY7v9x=;IV9U8n?7T^9AM)g=Za;tO6j}IxJhG=%b15hFq4n9Fm(Bip5AUEWO` zvOGRl2X@sM+P;__eQTN#l%>pzQb}rFy45Aq83a-Tn0vQ7j~rvQPiJ*=ZF=!sx_!@) zlyE!$09wh8;uTp9;^t`N>M%nwW zohMenw+1zL{uRK$&ws|16$IZgQ|4<;##?xz+f&mGkkj5v$xq9?l@bhe$mriwimg7M zG&9QfRy%{T?u7mQ=NTY(@6)9|#>I`-pLEhZaxT;mlCE3S9-oJ`Tbo*2BN~RdmPP&9 zlzVr3SxQCJa?3ojXK+?OHaQsl>6h27q{QR^%uWg5 zk5XIPioIc~M>O)^E0|H#yxCk}V~?k;VclNa+d&3s*;?1jb` zYh-W}83!MRD`t73lS*WsBD>?-VpipW;~DLW-lWoTl14Fu{XYuL zvC?dyYuk6q&awH?vpE=GN6WzOyQ-Y2&Mqr)!koF2ItVB8EER4a%v@x)F~J>vw5ezI z{6iXsjILKLv=BNUeAYkPWb-_zE>={49l$5w0CdN1{z*k*noeGeS#w;do?!+!))Cm>>g@$^NyG;<;`nvQpAB$c^$7ki((KJ@7xR zZ7tKw8<_U_GcFcce(xL%e}!Ma)Be{fwGvzTf&d9_NPHduJvi@L(yPfd+6h6*F3jQl zFL;XYy}b5A``J%*CxOW6&r0ZY-A>#FDra_950p{z;BX1(F;YvQ%cp5-h>^64rSQNK z*ugzJ9^Lq=mR2TbxPsCnXss`q<`pBHXYlV`HKhuVnHk12g^|(?Qd6Y3mLWWHfXrP_ zLUGgAzv3%C%1CClw~3%Dzjo(~I9y=#KZRoIdhPXv>}OzmTq8Q;BRT&7>sF-N`L}== zp?701n5nm?%rU$9)=_g%R$H2;r1j`J3uq&qnl_Oo3P5H|VS(sC>BVMEcc@$5&Z*_e z3}CaYfR)-$KaOi^!uQTe8_G!}llQ1L^AjB8esx<{wt{#Hi$gOK3+$K6JBK;+BigjX z*J^fZQ`-O2bou(s2}S7`D|X7z2#^Rcot=Az^Hh{KGkD^2Lj1vFTI>mvJ7Z z@;VG$&l*Q8Z}V&foSbppb6p;br@WtPo_IkL;x!C*;3E;c^F2jYBbqw1I4k?6HNca| z^8|>GE)U(?xDKDvt!XzRL29eXc75dZ`Faok09|S7cG2DKw)+8=*`onjWB{S#00Yy=N>_Z*Gc`t(TO@J1#x56QjASVTll1A2#-D2}EgNY<6i8-N zkUGipZ|VroAb&$q&1G|YGNrB2Wsv{?00K5n<^3tkrX>1=K)`pwj5_te9s72!h|NYi zvl~gh3M*kHrOPwrWSxXzhfp$3KR&f-tZ(d%yzeSCv454e@-xt9r{h{0wAYVs_NyRd z1qo(cWeFoV2ftn`Aozh69JQs-p4*~K$QU~Cau>1Z6e_Z)lY;drK}PAa#;#t{-3daL z<(5ZmebInFJk?8Lml7j9PKg;MivlvN4;k;yI{MVdRI|2*2UHj%jXE zKv}X3BW?i4QTp|*3rjV&(hazL8+IEujG+hkPI~vnQM4hW-6K3;AlWAFHuJ~7L7$~* zUfU}ov|A2bGi+nDwmRdsLHs`&>Z@p^n-pbzk&k<#2fuwn9iCmr1`kl6cOQr2RqiyX z=C^y8)goyLV1SW~cILHon`eg7TYHCTHpo$N)FBz-pw(?wXq}^wvmz?tcqap|r9^A~ z^OZ45H;wF2hfiT{u&b$ZBRiPjZOGhz0tF-KX4(r#pKipsDoPSTOqT2ToYs}?v~lTh zIe1Y4Bg}Wf+)o4a{V7*Vxw+Dr9ilw$8yj#7o_YG3(p9f!-t3QL)`=Ycu>%1U!h}Tb z#Q_;r>%b?|t#cOwq#5J^$K&l+^yzMzNXy_`?obc+0poY( z0jX?s8D&tAoD&+Z!-LM|8RzILRxKtku_{k6Mkw&Hz}myM4|BT$v9942W>gfJ7NFB< zcL11+#9~s&4+NZy=lt{$LNYO!X>>f|tbC9?MW9IeFIrZYa>DoN4?sO<#_Bhifbt!iMV~HPdT!40uryXj& zrQ1Pp5Xl;<;DkB(*Qp&i?fF+%{f7;mox{m8te$hTe7!*<9e$kk?Ogt?YS7&zvBMZi zP=*CQQU{?QLtPN78jY@oZkvj^X8QUIi>?@(>14|>d58WF}#vxR}Z*g z5EqZft#UeTi{D6O5z5Z4=oDp$813uO*F$6B^taR@kz}}sX51_h2g?KZ@<1EDx=)kc=xr$_WN+A5+WnPe z8$l8@i-345*B+T2svi^B&hp&c*<9g_3lLDCVyL7Ew2A1I6F2yuXU>yhc&p-IB6<*3vYm5wZF(_eWu_cI|7pov*}x2{KX z@9k9O(1n8-n(8@T2iYcaK3w%Rxvgl^L4OtPz1zoU5&4ou$OAlpM?EUl%71CgG|+6C zH$^^VQI#Zj1p6HE?OwXBxmPODoQ{*etb%=pb+ zHDAOxt1`Piyt$C7q{Qd1PhN+L=ZbTwn5hT+dcz#?u`2;od}lIt&(fQ1d24H@#BL-IJgPCZw_(8h*!1n% znvAT{?ll#Av22K*&I_Tn=Czt=Ne#Q@ICbgM=E(eOLh)|nvmam)MgS&^ixtdY?+#(X^IH*(aIg zMvSK1g&g(+rz8$)pV`topOCUENJiXqo(WQW9+gg{UG=#6C2bK1mged>8ac#>r;^B9 zcWmTz{5#cq-CjSni(9LCwn(hsCL{{Vah&^unuAcgn#RuNM4mnHI)MyocPAtD+4&$ zag9but`XH@c*Eh;aB0g#k-%!}` zn`>)`q=iAi!3UB#&03r6=mJd_2gH?b8Fr#RHQWc*6Z!M)KfWRSAD zhed3tepn9U^Azvwxm|1?5+vhe=YRm@8t5*pEo3S%f&8Zd%JInQpJD0gP}*s+y__-I z$mOG#Zsa&pyG}m8{cmdQc$VRI_A_+s%9c0RLe>#DG0PReRa4t{AcOc3^{oVDxPnHR zJh|mi@+%HOQ-VD+o_@8Ne+}iW)MiNcBW-3XzbR$G7$c$Pv}Ctzn}}oqo;}It0y*G; zoM2@Bwar$V(XOVEy3rIh8%vm_yAl@i{GH3UyI^F2`TkXd4b<^kq>U;|9K0Q^(TVOl z*GX}y7W-hB$Wb=1TxY8sf&LXfm!;`fag{|8tFGh>fE6R(KQQb1S5-b*aJ<)I8oT#Q zh?(PPnmcr4;YuGv)0(($4agFCZwQ^TVTKrIb9DpidIRf8 zd1)20$F^VHMpdF!J9%T%@~o%HCYm0pYByDa+sH29s8D!Lp!Cnb9Y@lt+1tQxRUS~E z++g1?&5m*D)AOtFM;+atnzAMwn9CN%)0~2RdkW6FwrICXNIz!eoag2v82WH2LEb!# ziT5;}652?e%7lt``fVd49@LjRR_0ilky17cT#S|ZN9)s?fUGxqSow-u$ihMi>Bb2B zf5x(P3#1d>qsxYsKwYD!1N;RRO1N~Jy3#94_X+Mt2}AdGk8=~Z;w%`ACX^P?}7a(faw)hMlz zE@qLX%f=s};gwDY^B-JR5u<4|_ASptMjcvq^PhD$Rr+_rCn0t?9%N~A~y14 zAYqO`kD%cFf5NFvJU0s(tV9-FyR+2$w_2&|2zo&m@sC41L z&j&xHV`#^9%C_WFBkUnt1CjnBq`i%r^;%4;fr@arxD~*Cr7R@k)Wgh)Iv&#~hDwStk5kr;t3$eZgD?IRNd)AEh|!R}nJ8 zOR!;;4lrvO)0Ol^CWt3Dc24lILWGPG#d-{qNv-=U`)L*#%QGqv;G*z4WE1FlHIs9# z+TZE%iJ~*^F0H@?SJ?XIt3i6P4BO63au6AJVV8r{dUWQsGT*ylYSpz5Zq*e`qmP|xKp!5Mxt*EqnlDfJelP) zu6HD^gC6)jYR&!JYi&BJN8};}3cL`f?*1HBD&0d0Dx7oJ4nG>}r#C3z*%MEv9=WX2SCsB4K z@}*oXh{5xcatG_%6qayLB!!jA?T3JRAOP?xglHE|xJQ+u0n4dkPT!Pre@-c}#VmKF zp}ct`X#W6qLCDSqKMdqoH?o&2N!ZrwsK>jWN!B(;bR?FMNCk3n_5T1G>1;J0wOb@| zqZwh!bK>V5wJrCEF73wc*AkvZiEI0OOL9+>`B zRiW;s6je8E&D6NL%N16VGOSFDy%-+Eb>gnswY;{gH`x_V8J+M63(sn$X{w~bql#uL zbT^D+^$TgB5z0KsgkeTT;749K&#&oCGFV9aR^*JY z1b{{l7(b`wSe6pBGfe=AfZPmcJm4NjJ%9T2%lm(`6e(=R2}n3rBWPiq{&=lrPEJlK z+p!$(*EFQk?bb-6jpkyw83*MD`QsSkp_68lD@bNx3Hc;P&O)5<54LKCp)c7MIU;7a z-I2CO#z^!OP8I90SS50q8l!U%S)|++scPDDyWqM+`kG zhN481nG`76pa9&02T$>>Q*TCQ``GOTl6i0$O0&w|WMd=m9y8m3D(gcX>#D^f+NvmN zurdY)03*Lc`PK`!_V9^elg?FTDy(+ld!Ns>Uu_=dT^e}}z>QgqjLJyc$@xDD@#hT^ zZ&P?A`emeb z_gJ6jPO_R?qYy~|W@6j`+(0A0U@*^I_RmVlx1IqSqn|KtTrzfM&OW2wkGFk*d9l7E zE+WFNa1U0;eg#5s9J!g3sEgU>^c>qVZb9v4U6n^}R$$;mk$-<3^qugevp z-0#^4ej~;M{{UPJ^%aEWB<%!J<$IP$+Z?+|l2F{of(jBoZa>d@=5@8Yi%(`N6mIhZ zWI=)L^f{|=YpEu^G>~6N(A<+59zX;VKZ%Ly?^_y9kzuPqW7Y4P-ZUf_*r<6i>BcKs zG-XappJH9*q)I*-`*p>H_fg8fYQ_&jWFx=wtUDhN-Y%;Yv+ph^TX~~c_Yk?|N2h+3 zCc8Dgsgb>Pek_r2@*&1* za7YM1*^cKtbSE`iQj*%m#q68K&BhhB$acmDUOV>os}k#IV~fjq2-~({+%Wg1YLh0V zXFZHFmfV|>wvEFJl0PHU+OmwKteVh0*LIBeM7vwF_M_!8s<2=HZsQ%n2DWW)qJ1;$ zl3@8jEAUS42Y&UBZY}3xvXlmBu!u8>LB~Ghibxq=F#s~NI^p)6r+DCJ@Dx_nA|s=@ zy8_8!6lrsoE4y(6u6l9$Rjm^C#$85hMrmRznI$6zJd^3y7$2QOc`H4p=-Ycc2-$}j z8U7JT3&&!>fTMbacK~PQ2d@>(o$t-LtY>D8O>0bw2_l`RejuEodGCWh7+1`Ma4F-F{iPZ%A5>}#I8hW_VJh|3#!Nf>7s8^#I7 z4}RF=q4ujwtz2DQB&e|@1xfk1!Q($)b5e~`FSN}R#y=sH;r9SapW()PR?&><$-T*P zjPyoLtheS!<%~RK)bC&7I2?T6T-EJK?(W_ep4FX0DtUy31Y@7B4u4vT#^&N=D)(tD zPnL>CZ@+?i6ZvAONv=nFe|sw`6dU}u7~BtB`t;_nk;->VLo1}UX0?Ug;;th?mg)Yj zWK6WD`V1P5Nv71Ncv>0lR#sA7NBX|UIP2Dy%T<=@7PtE}XtAIvCUSB+E@pl|tJLwFfI+tk|92Ff8zo*i#Np0uD_MQZh_FV2Df&e(@HI*Dj%Mg;v@u88} z9t(FLm0cH8M{)Lm0>&9~pyxj>N&43nN|JIqAd}pwJ@nDq`GL?t(rs@$gN$PXziPnM zyi7dVY$A*#&DKENWS>D=R}#Zotd}Urizlgt!Hd%)>a`F}ptG=B@pe zp3dSGka@2T!Zz*N`?HK6U}`Be$nWkVhf$t8dvO}1u0}p%_d?^-2lK6{E>y3wxty-u zk}JdFLXrKY7=b1?LJ2I-jzIS5S~_QmX1JW(Oo44-kq`~NBRmuB&w6d~Bc2chZs)~*!foRZv?%@?UH{-<=&TR+O6 z7Q-BHK|MXNKb00*mE%V*oIX-_##fvcNBYgBMajG^1;KOA%Tie#E(4J?e-vdL?Dyr9Vu?c`*hl{D$4ChDTO?eLkJZ-^$h z1+5v%k@Kr4;GV2M&uZ1Q)E0STxboyryScHI>(FD@)}zyIEVR^hO+7XdxR*I#x#{%g zv@GXDyGv*mBLn3Efww&6NC%wO^<M`5NEb>UIHkDFH9AiGcYt;7@px;B0w$qYF zM|XDx<+L`}1Q{7hqb3Pf3;uXwfjxsAVCTWH$^O@f=hObkRD(ZCf!DDLLZ= z40Y$6RT*SStsg7$zUF3C&z9IDk8YpjR~;%)=H)e39qx;B4V0410Ae%uuyWr0IRo{pt8C3@ zr{1CoF2q=sM=Sv7N8!b9QWV~(&NG_a=%CcMM2#iWTrdSOv~O;E_s)C!ik3Z9OrK^$ z7~BWQ{Ye0gztXvvK(fT@k~0ZI1_vBqe_EdA(&pStcM~f~<&Dm*kC^gL=4;P%qkZ=^ zjO5O;-p)o+)5NXi77}`eAe_A5A zBg7Q`^VFOUPqD4dFI$rSXNu$Hc8P-~a#&}MJ#o%!D%5I4-di0ps}{7}+INkuk#``F zN^(NvxzEkdUNS{KYe?X;pXEd{p$N^?cgV-#$Gv4W;!R_Q$d(7>NAqJ1k@e40T3%=n zTTe7aqAaZPk&I`YW7oZNB-1TBnA(<+=EJ6$Cyk{pp`&bMjGSx-*qWuI3;1oNwA5vg zDQ3nW1Y@To)Z>qOzOc&$-M!PsE+PfWNV|z3o)10p1zeFKHw?Fj4JtGA`-d6N(z{)B zqN4Tx0EaN-_pXfAwuG5ySs29oiy24E8MBU0y&4XmHM}g6VM-}d2WI4wJMs-!cx_tk zZ6v}Xu5v~UnPb=UANSC$Ej8?*c~GOt7+s_ zNiHOj#Ah*Oi32>ajFHD3J7CmW zoubR6+f5zk*_m4cWNxE5>H2;KqHWKW?RLwJJ6$q$iN(T67^ zwV|uUBz9@#s;r=V#~2vTIP@oj_*M2^4On zvE`s}qhkzu=bqKEcYK<1LJ|@qxR}E`M}nk(2pRjlLwPm4PjIOGL_g43KE5&l{_GjtWLxZY92-O0sR*^70s?X2BbbK(0s} zZJbwU=!NMJ3zrOttu}jLU`lU@t;gp+g}NNn^QM-n!y_wZHT5yjy_!X=aKl< za!I!;k8!BA?!{dhdd86PSzH@Kz1{a9fxhbJ1n1L%#bR5k!+jiAR}A7P-KEJO5=a;) z9<|op*S{9aoNTYJQhdb4ejhdBr3`VU@zT0B1y(C+716{d*BWcf}4@;VOniK}Tb3;zJL zJ;YHgZn)rp2*;`Bwe(wP7grHX(#z&XR4`)8(}V5Sm0EFyCw{tuoTVdPc$(@IlIGSq zOCvU7>Iu$28l`z*5GyoyI4Hj|GV%sHpVpl@xzQR3l>MeRxWvpKB%$OGI{}l$H&u=Y zj$$0b(-N7-BiQ~KuRij+irJdV3Hp}w>qwtR`!42@)mfWve|gCn0Qc!!<1E^4y#yo8 zkIhlHF|N$@=hp){@5NuS+Ai%Q`&_72H4C{m?_N%G*qrvM7+gH5i@0Z;KK2X)ZvY(i z{cCtjmQqscOS?#|t3xCN{h7ST8bxQ$=De5Uh=bc^Hj^jt)II zuEOK{GV~3~kxML~ZBw=KK3w{cJLb9RblVta62iE6m@Bs5OoanHaw|$s5>}ejQ;egm zS#@Nd?kOzfRNJ(&9ob?A0qOpIYZP2Urqb3+4e1s^XFqst7zBPMq)RXCjba&+c_UQv zm=2)jd;4VKwHDZ3+2T87xnVBUz}u0>1Gg04EjZt!CATN$7FO3OcR16nL@*XrGNw-_ zIXN7TdY+lUtGaBVAdOtJ9tHzs?hDk8+=`!NtaBAlH%ye}5M+gQ7(FqAj1HAr?#GpFD+Zm*%Wjv*z;w+_F$+zv?qo;dWVHLLif3XBn6QnEt( zcLSVt?s?DUR-~D~vswvKBJpeiB*9;Q)AGrzo2v+ccwHL|PB>mQpFbr}Q?$X9$OlCn9b?#OQ1 zYi&N+(mQDyCs5@B4p?J2_Bs74UryB0^5PpQHb*N1o!!CUkIS`Ix01yX)@VvBk*QTD zCD?JnKEU>=MxUgtsX7P!)5hW1$YsYl$En3ybz^$1W~0*)h^M*)O+3<2x9t=;{FP!BMbxn^b<`=@e{bL~vK(HiDPBrsHM zse|(z<2WO>2TJCp?ljr7moh2EWi*loib*7SKX!c2;T(b2xUATudkl#r+-GyLBDi74 zAbkj~f$W~c?6N$v2-;KT1NT>qbLq(A=~3!-itlp2W)6`bJ8L-`Se_Vq_5CYVTKYXx zGj!Fo+{L=o3~}7s#?t0D+7(!HgOER+Sc>VdH3n4@1dKc`Uyg(j!2N4BE64@pvP4Sm z%E+(770(===M`ebtypdYti-xxQ~+INsgkNhZn6XQui+;` zcFRo+_+5vUz|QZ)W~YpyaAs}rj59lq-(O?=>z)yG-Ja#UHKCPbbfKlTbS@f2F{t3C zM|>W5H6(V{NWw@|mNNxl8|CAv`g5Pot*w$pcPeb!V$4c;8Bxe!e?DuTy1RQh7}~6& zA;T#gmLofX@9AAUp3!o|$C}!+p}M?+DDX+%sh!SAUPo+JWLl`VxkLS=8Wv%Qijc}% zgU@kPp}!_ghvf|WM2^64aDM6U)7q+Cq_)>G%wq#xeE$HAM`@+`7dG=j<-B4~E%0{r9OQl@pK6ZN%5)`@E*Enuoa2Ge zdUfaCou%p)$*IW!Qya^T*d0jEIQOn;siiAwijOVT&W7SBR9UH2;y@i3=aIlaUIk(6 zmZ^QHBCaBZ6@0_kV4hd-tv8Arrbl8>LJt}H!y&hR7_N2Jd(o3|^Fq02_Q?Pd{_S&N zqSw9K^)8}z1hW?w6P3C0%nloPOzvN&>rynZVkf(3q>f+!3O9Lx_0P3FeG=q@b!{?9 z6Kz1b#^fWAPpCcXKKj#8irdIBkg*lmp#dYVNB;m{+PfhL&1oYi?yZe;V`P@5CXv!E z4%aw8LHZBEuvTkZ%lD0kA&6GbIL->6!}(R#xk*G8;x{blS(k4q*pIGpgYQ%?ba@s( zw%bfF&IU^3@FU)}!*fRb&sVWE74|nyhi7qSB1cWkL5%G<-Ht);%}0A>2!Z5Cq>RRS zR_byvMmg>(g`LKuZ*dWwBsT2B&5vj-m^_isQT=Mu>oeRlJ~CSeX&599fRA3^m0;C) zNo#anqSmWZF4s#kB)gol7fA$)ae#Bjw`#GV*~fDg!`wQ@&dAx$J}*$843Bh$j_*%_VO4YHjL4vyNLNo+)t)4jE*aHRn)pfDtxb0WJzls-TFZ+I8sy$ z94=d?4|<+UMz?7Ga}ZTzO~eDWff&g5tqnac(n!44Sq|fn$}mT6eT`3iKG!6cGFz2m ztYMT5$_OOm*9SZwYSwN_T&PJa6^5MlV%eN+LNa8=P@Im0dvjTL_Gk>(Vo|-_imKr5 z8R_loT9&h2`3q$u`G`8FUCWNR{OTstqLTB^Rmo`CTjt|9#Z?GYO{PrT61kf$oYq!} za^QJQwf3Rp_u%_gtEist?6?h;{ovn#3S;?Jtom`g(jhSd+fXBtaBv9i>H(@Z(7YFD zuNjUxAw@37wgJs&zg=}6meCe2Ev%l!5u#D^gk=Me4?~`~HHaq?UBa{HU@TTc}j&(a&seCr!{72MP%ll}))f!E22;AmE+w<~2Jvw9_571Ww#5V6OnYXjj zG3dG-3# zlHEwLAGB$$B1A^!B#@)92h*Say-X6zR*fQ#W|Wjx%JR{$=l=lL>rPJbw3p1K9ds|I zqa3#rTa_7CF@{t1{S8l{Pc&X)-7@TKl>i^R{{Ys<*0JrA`##|Am`NE@xo|fj=ko{J zwd}2}YlK;F5oD)Hruv(f(mS{g%plHAC?aCn2fV+WPa2*(5Ps+aLw zUfeD8@_9xK43C@S$ERb1Rc|0cs9Z~LeKH44;aGfwJRBVJSkg&6C(Clh8v%=Pk?IfU zTF|2{C4QfnrzEsGOKmQ36Gsj5Nt`Og{18uW{Y5_6XND(Rn3h8u6@pb<1{vpY>ycTO zb~}PhhCH!5WhV#ptr;bf-qX*K_5qLGXQ<9HKQGFnw67-^>dJ(yXv$=^xD6Cev9s-5 zE=b76KbJL5>f!{udwaG0++dM3c^Lb$b-AC3}08gkH}iYS~$Ff%$b6qSw-kC-UwjcmOTH3;@qR ztyVf|p2;N>l3kg%ZaiRg{A!(zwDCyuL`mAXaC45CuSQfMS5)>n+}hlowMlMXM7e0n zk)JRwbLquEvPwaC1ZsMG$+Vi1OW!2{mK$bs&}Rqos0Hn?KRv&a!@4);kzJ~qOO)qw zceyKvGUi!!$lL}4miFmKmo#jiW1O>Kk3s9rG7UpxFipFG$`{%*R?ej=qZv{;WAw-J zrO37pW@sy-?r;%)?dsmA-SGv^d=CadZu!bn4 zmKfw{RrfC$ARKf6_NlBU6WcG^lqi|mLiPY2rk!@nCG2y?tbFHC5qhg*?|yZeHTV{; zrrewX5y8R9?^)?rRk(Aw=q2UNrM9N>EG!)qs77prPf$Li^{2JdPi7l-(7-bB-FlD6 z)sq#&iqB~+h${@J$s|V^IL_7w*MpzJw3R+pb;QIC|u8;K9^IPK}sRm=EZ?l@EJ9zY-!Vabf+oDthR8cU)sn`)H;-HcLzIb=Ko z?ae`VHQO@T{iY@I-0+95ryu7vv}B!c8z5K?O}j_`t=0KD41GX+8crj zyG!N#{c-@QE=9+Y_Umhlh|)5_;)-@g-P8;pYDyAQi)PB!X(EP=ZydKmUKBGO%bxi- z9QywNN|yfsQ$aDdkz8ynu{JTDHsIEliKtC^13lN-bpa11JCxeM4pi=39D;pop46fe zYfjNyPXkQZ$jqpRza4u0YT&u5K5fuh#ySpy`K_)N(IuUrVYJ3i0QRj*dBbVf9z<*g zLm}XdgU}CCSa(xCpZ<{~YTHUPvadUjsOmovP{FE{^NsrpAI=V6DaeA7v z-c4%&2IZ8%E$$B zezf69PevTqI;$Atzq%(XqIMvnoGh_;J?*W`_ZG7a!}p2`!4tOSE1Zx|^{!b`ahs2!YF1heeQxIXyb~lpXOcibDiFdO zx)3<$sOW2_$d%7oueBgKC`BqOWWz5#Mt>TKH7AldB9bhEj$O|u z((!kokULWL@Bp4_xH*`qaEE<9S6F87HKN+@dZb+?LFz=1F%F!zZ8vsphFm zqpVFO)WAp`L}AqBfyW$GsO7txQ=D8xZlsA$*7#(z2+!uFQd%q^!$2vQukMd`sm zhZWDg&Y>l%tK7n++jDN1z+ZaB}Ss_)Sh^DG&HEMWAnVE zlWZi(^FPbC`=xt>?^0^__W|ADM2%!nJhIpd0`$r1YACfvh75#~LpT67@S%C@kELC0 zPfnLqY1{0w$Fw3VbyYkOipF&3&&?>BMaP!OnwFZ4yJ^lHp+j(ih$rO)D9AsTN^;#n zWT=8tiXmB)gSCriCmpLlRk+g)xOi45!Z2oJ0fz^-(y?dOkg~K{BX-wPF~XilzZK4~ z+}k5r)ltyuEw3%Enf%t2yjjLuA&EJ_$FKhYs-Dw{Z3{q-ZX=aguy2%bK_}D-W0(pE~;b> z6#|exPyV>aN?cn<6DVTJ>=l?Cj2?LUa%(ymVqdk}LvY2QkhymLCHDH{S6wMbRJJmd zq}}?PcN&Go;^Nq|BPJC<$VNOK`2ve(xPk_V?PWqw%OEP`5yw1rHA>%5A8QtH#v*_y zm6LWi?faqMzcpSbj^^@K8$oVcYU66JQ;tSB>rQ&c$!La~-uj#AaS^pEJ50s0O8lUJ zJu*1t>W5 zAh)B>-_2lyuE!ztU zi6?Y{V_4!K?r)XO;gU1gy=j=y?Z)U(v_pF^9Pq;!KHt`}^$Uq)urNh%V&8(SqxgW& z>x@+k3){@_9JVzgppO=UmY)_V|m7sLgG%L36$>?Hq4{#yoT!)%`x+ zJx5lD_ik$k54nCX?q?Bj#m7K_}31KDn&PE#_&&{zT~! zjf|lG0Lwp=WPgPhO|-TN-CE&pZY4n(oy4KSfIIR(&TD00p36%x-Oq0FG@fGYV%rxS zjQaKGr!~k8ZMMIdjW3u6OL5buPfF{ofxfW1Z!a)g#q&&0ZaB~9Q;4SElVhdU#wCs1 zb}^wU?GuurP;i^G^DsT?tLk&hBuxyCE?06haxsrjN*-sqym=B9Sg-(5lk$)8#U!@T z+Nwz_>~kR!jO1e=oa5I&rEcLKZ+mh%`Xj2+b>)~_k|9Y3JjUC@;PA)r$K_kbc;=IA zr7mSj3nG@vlarJFeJg~q+HTeuqTd^-3n)3-6!iA|Yk$M~tKHrh<%?rGG>S;aPBX_& zE6K!R)LWEJx-}b>nbuxQ0z+>Uq0%!h#xbbpjxpcUnt`4;AIy?A1sfP+oUS;}9)hy< z-F918Macxf>SHe--UlR-KDotD7NGuIF#=u*;U{s!Db5OyP;vaLj#S?&k=ErMg?muC zn4Vyg zO2rl@Q?Q0BmzEoYpDBPPaHoJrsXxxUGpJkYGYFbk2vy%AvK_J^z$;ImPmfO#eU}mv z#l{_o1fPDq_O9$cAtaMpk?gMSo`)BzS?bzAF0z(|%c?X@xpyfWbDvBc{b~9}y>**- z?|io^Hey8Dsx!gIZ$bY6)~%^z`${#03Q!po$kJd5M@9ih0CDxm&0y=gWU@gF*31EA zCD%E|0q@`L*P|H1aZspp%2SJSj>d(}&6cOD+6zM)Z!-f6FWn>VwtJor{{XI|Iv%5^ z&3AgzY&S8;k;vqfIOij_27jG4+V1Ms+(wr+-crF4mI-1fc>_I1PIJ?xb(&+_>pBC; zFhmN4Wo(cYPxnFX$mDu-6`Y%-lDE2FFFoH=kFwI6RY?uQ$2@*$M)G9=f$m4Qdegem z^*JtX8ro9~aTQ3_`b?u6c?YjvPp`d0;h1gwH+4P1l`dj~2`pu>GJQes{uQrls3pvj znB)^jE@f3fc~WvzA3=eNE6d(|is*EbanbyJl2#}NSE??t2~i&C!DRYfH)%^`2JNEs=`@P%-XZs z5Qr+CqZqZh;q@km`IR=|r($+=uo;czq8E-w4C&PrU?=!VT2rSXbejlquWmOHr_$4vb_=$iU-ZRbdZe6m1n@}~pB03Xw@CEsYef zq91pwi_1eKgtM$GA$)Y)K*=7xY4Kg$Pi+ioy-nC8keNU1?))oGWVeC>ffX?+!ru1E1)$=810XK?_U zIf}*-D9Hz4804NkPCq(GwRqr_?ph#*FW*Gx2QE8t*qr`mw&K@~zOb;|O?4!GTgX@V zdK?d@Pg;vq{?66g>~leF0d1_3#}?L!h{@gAlpKOaDw4Wf=q#7O$gVYeT}sN&Q3(>t zQF7$qu3H3T`{(kiwsIb2P`(^agVP|{uEisB)V&c zk?f3IEXd;1LfK=#(&Q>M^du5zb|lOEgB<78mobY-S@wh zWfrF{Rj|3aRoSqbzWIE)uB5sRAPC2T0q^zWuN4|l018?mkhsXW>e+o2RXsP?Yk6M+{JgNUL!24DvYQch9>~2&#$+7NjAfH_X%+b zSulZFdYokbI0m(Zxm%2gpGJwLvNqCONp!J(>@1Np0yegKb>lo!WWBYDK^62!+m{kB zTzvTXxgAH+tZ$y@&Qlyx2+A_d7~sZmNx|p(R(7i+9nQW}EKDTWTL&3AA5+CuI-Jjy zp*7UBE>$~=A$xJe=OfV5cXO21b&0?nJ`By=^M`Lo*=50elxl4u)@wgc$ z8hlT6eeXoNFHWo0Zwz}y}> z5AdsPs#{&@rd!xr6$C=Ds$(B9#zuN^*WRknePV2lt0O24@@@X;ImLIk?H4OsGnKAa z%$cPIrxo1q1d+xki4<%kf=)RAdiDIO!bbwY@W~eFg9K&IL4(eJ&rw)NBbMTL;Q3DM ztgqL1TxX~iuQkju+#46fEx#f{4mj!w^yaXu4`$aPqL(t%W}9OXifHzrSma=ggoXp$ z{V7^u9n)CHYvxBOVq^Thg|cILO31u z0decTu_`2Mw|V&whLn4IF0QX4DWs90Dk`2&<=!V*1w392#K z-OqdWsO=^(I^lvk;P)VBrEA+nnwmA-5?h&>iuqXuHlCv$x#VW8D815rs32(PgC8#J z2S7;UsmS2|bR^>zqa8xmcW*+Z_Ot1(i52D$qJ=J)-_rp90JJ?j)#sS%iX+S?A5qT-sH?JC%Ae^zL{WJkG>#Z`93G!R!K^;7 zq-6ACZtbnnlP#OrM+7S=L&EN41Q+Ulqx>q)kEdK+TgZ~!8DjvJQ5Xa;*(01B{$GftQoFN{R47MVocakY-YLh- zmn5RIp&+p855G=5s*UA>+c`T*xEaeS!R|3zx|RFs^T%%tGRv{Zi5%sR86-DuPC4|a z-0PP*wZf0Fv`{if&z3pIXU_$&4n4gqtJ*$QD_IiYo|ieFwqC5LC6mhxxDsz|fDXqQ z=iam@7jI-W0K(wE0pj_P4h~O##8$1vtd@%NOB^B+c{?(r<_pUH0M(f1h9_vFwzq+l zEWT8HE2#&bxav8_p{SKuyEq_?CiIgzN$*?MW^$pcFa6N17i6>$4E50#Ix#xv{ntf$hgZOm$_(MuYb#E~%>M$cUJ z;PtAfUM=#qW)h^)%#RVgax~sp+}R_8^8G5o)>iju!>h1ezrRH(aCXYK z%^p*iUs|_qWpAfq=)&=@1Ag3Y$ruDzRaXcuXuVE&sY&w557RXWZKk`jyE3>RC_sMe z9A^XERoj@w`o(MnqBxb7IS&M`dLK^WuH1aMO+rxwfwcF#R>JvV za(E!A8SH;UR&Ml5oy&U#;>8^6y%tB^mB2Ys?Nz7L%=V$7x{z!?y;3k39Al?$ynEJ> z<(yU3-%)E8#kIb)xwP2Sew}L0k9jld5u^cS^8*Hv z#xhsm=~q5mz`J7%qbv~tJ5D(uinU=7DC!`J-C)ByzDUnPK>!h-r5KmV9kpQy>N4_1 zT{dZeDCLTQv$k>xAEjeyH*(ms4?TBEK0r^)8P7xLaaQiG;+9L84cHON3ZNr6Imj9B z`WiIr9XjGRW(5>r8P^ytdU4wo%>~Ixs*848P0QUUms!|kv$#l*ZQB`e2qV(5)<~ix zM2QrIwvKU-Mh_yiuDmkH5xnDZ8R~Z6sLfJ+1o9U@Fzj=R^e9k|C%Y@73Y8jmk|JAq zB!y!jI>(aB6J+B(zrvt5_g3#JBTAe8Mo>S`w=~%_$*o*GQnD|&$Kgzt3x!WGNT(!^ zn2i4bjcVv$;?$K@Y$S1SIGvps4y52UGV#PJ6fit)z&RND_NI9fu#jzS*ylXrn3l6! zsS@+XMnzXEzJhGEW#VUraj<-x4m(jkvSn@W9#f2Gtx_;;LRkSB=M=4yfy8P@_ekVc zKURX5GDEu`_Q{csV@FfjhHxrno@NWSG#KP@jN+CjCNN$;anNy4Ok{ko?*S+7n(0wi zBb!r34N~R=3QDf++lO4{n;xiRM@PX7atbaF{{UX7DR%^`D;}6(LbU3?C{jj2=LC9I ze#$B6in}hx)`t=i8OZyrd8?mqv@x8OK)sD&19G6WiU=LM)Y07r8FaCdP| z_uO9PuVWKEJ1RPY8lKHSy#Z`pS%WUCLkCJs-r`qdfI#aCk^Z_WlA88uX5O#G55 z>^ESK@u}Fai5`Kb$nP@V#^qK~ftDvHIBbr!e^9la@Y~KC%Xk4Qdk{K`rl#IIsD|Jh zVPtWPsK+A%*N(NVIhrWqltUm2r4x~WPf$Sjub8P(-86S7t60iwq+5(TBFca}IsX8b zc*)P}`d2k`aP!{0w+_x@A*3L2p1H1zSa+LHlG-bKWxItjG>VzpI49b<3%z>o%4y(< zj82TCVH6U>z6bKI%p@Dzdl*$(*n?2JkSdY#gPn_xS$%&R-0)yJo%AqBqt0GN@Ic%B zeJhr`8lCOV`R*q|<9-1=51{E=nj{t$7q%B|tH`&?{{T8PY*7H|md_{K73kHY`@UDX zG}3QFZ&J~&>}9x_1IHcYZo?<18NvD*=dN1r?@oev;%)FBE!_r7^&tIm#dL3}d6KBx z3fnPuO|Do1-(IKMou|yv$oB1RZt=buAE+dBw>ZjKCUuZankOeKU&B({*`SBvTv($yIY zdv_)8lQfJXP*9R{$5Z^O^@(Pmd@{O#+rU$h;Etm`KtGLBHzFI>g>BR{sz&@}K_joP z&|x?sdKE`YLQ{B(e|OrMoQq5#yvkO+JxoEnngIS zrUZ9;UzpDdMhWPCwE&d)s*I(HKXi2VUB?^mIUCkea6$AVr!`+% z)i11WuC1-6Z?cz1+RMgqoM+oL1aB4MM+|n%NuOw!%sFg~@;YLr@gz@mG65`6LDci} z7Cm$C!2GJC2>V3jgqur49L}>&(oRv?$tN9&=RDN&+^R+xN=xy9PHQ_g(@}-X8FwAo zA1U@9;%c;!M7C?)dQnfVRK+7Ch7k=CohWp5>%V&4jp$F@TF8^?3U;Y^I)7RW7; z$jHw%kF|?!8YIJiXay?za4m zmD<$8lKIk7%H<^_^1OQ-QyrVlw|PNWCrzZD8-}4+}E)dWBbc>Ae8_HPebch=C+axXkBq6CATAB zXAA)u{#f>`t8yc@xP94WAppm0)`s6RMz~mCCMQyxTlhH*k@;6WWoE2gbtcj@`Q+4= zAC@w%!M=PQq-5jr{cA!iJ9w?G=7h!N#LTERXp z@-|ePT9s}fhT6}{`{1bDQ1g;VIQPXi_7nme^|oY=TXYQ;>>R1vk~OJbz5?mPANUTU^a$D|>2jQN*Ye=UQnACKz*SHrk$s#4ZNT|Ss87HSw zdYUxmX{2b{ZQfg{5`q9|!Ol)QRk%gIlDBT9Zlc(#p(6^R$sNa0kyhZA=T$ym*pecN z`_@=?jN_m^Na_!2nNHDZEeFc`>SA29(QA7ID)FfgyKYCP-uL(Qt9REaY~tDDEhJ3O zCL16z9Iw}p=TPXk4%ab7d2G?blE@lDdCoW^*n8H7q2T)~T_D^&&Fi6YvHo4m=O-X% zkZVt8X(b~0T%y`JYrED+jE>ngI%5Xl>e|5Nhmxy-SUt>gkvX~fZknO zK^#U^FSWQ_cgG){E~zBR3dGk^C}06uJu#erg+rn(t=;HZk=>&?3Pu2T5udd;;MiNJ|c*-V082}%eu-4Jd_=sDxmkWfMb~1yUg&50wipn(7i%Y)7vz6^*ys+`cmikB9?zHnX%aCD|hE@b*oSuU? zz^;BT6T>aTBI%aM-Ar+GWyd3LrBZD*G)rck<5x0mCKD+6Lv+fHMlugQYJ}I~&rOoZ zK?_XMB(8S+;r6gUH*i7xFe<6jgS(2|l_xK>&hz_n$z-=f0?gtD+q8667$E-uKWf*s zYiVyGwt-_SIC{hI9T$oGC#2s(>bhm5S5e32Wmux^A5Np6u6~t@Ahpvb z7Of~5U^Z_rmvsZ`~&cS4<5bXGb$Ei+Gs+GJ?qX$&Qm*zLoz;AiQP`PVEo+$_s* z`DDy8?#A5bu6vH(%A{RhXp+t4jG{3m{{Xun2cXYtr#gntvVZ1tee#6OmW%XE#;}id4#Exo~Hzl%B#D)%~zHOr)hB@}EShY*bYiQ({Xr5Cv#r)?&ce;vG6VSYp;lqYz{Bk;%RS7Q=c=~0zz z%Pj0eGmt<7a5(oSt=vp+ZeDhTg@xWA_`y;}dU|kbNP=CsY1JK}VHl1@#u)Hd9eN(W zN)<%xnO3%_#;~7N7ShY*LmVDkp&9#)yYGY4cjB#CUW>R?YW6KI^SPNgRNyOg`qC7> zk>;Vg&<$N(t^p!Mlb>kg!O0&r2+sa8900QW!$zc4h>v3q97E4Lw- zU>y3MKT3|vRJV@G+8GuPEXnf9ssW29f)8GOI&oSWG_lPx24s#HNC5!AEb=-P5tD18+*|-tu^*lwvuTSNh&aPJQ4>P2lD-D z8|`8pvfb~JBJL5&4ZsnG&V2|N$gG15nsf!_%ZL(2Pn#^Gvk-donoC`NE89P_y{juD zgp42qYHjB}rz5GWrxy#!YJs)0dW)>zA_#6;5i5spFK+~c*yBFD)KR>%=vMpHty|14 zHw^r_;PmWqQ(h#tYZSJz31n9ef>t3*AL1jv4O+LiyjxKn^ngh5q^?wCe5WIiUPW*1 zv{LgUmsXL1aXQA{Y!^y)p+JLzjn|>=*0eMUKF@VF;kZiSkYkdKgTeLd`5K1)$4$AN zLIb(f2_}t$ZEW`g`Fqv97Sbu!C%2k3`zw|WyFVh6$MgK_di7JKW0_KMmC)H{OYv|R z6p}PyxOQytdF_EwoB7}ka}2&@kb&~J9QN(kJrCBdc$-a28Pe(%FB31BE;3H+?dj=? z=d{f(>sOxc(io&3TM(|VjxtVp_5!(SD9#+qV@XO;cIs(eTs`fiva~B4S1?AXSmA*z zcjx~3{c9@Hd6w|oOSpSKRs@1DdJ4U$+FZ?}TiC>|u)!k+lo8J)o_ltvbd4rU^tiO1 zb}1VSK1SsO86N#>WjLyQ(%6RG&3JVbI(!!5CW=JdNzONRz;92OjQWpyxn-(GOppl~ zk-%_|kDDLY{{XF7cJ}uRre8;K6A5E=FpdW3&Q5dNwPoq4I$z0Z(grN06p%sRkGg$1 z4DoSczM%?XK?5?b!Z}gaS{ZAW|LF5vv|mMDnR21>wrNYPtep-DYKSXnmGwg%Y&c1K_`#OvrW0CCbYjoc&~06 zNCYgW_h^h1=L^$6%B8)Md+DGp1+0Ni##bD%AaU=`e+tTLlVEMmq^FqL{BvMP}JIxkG7j8%x{RiP&NjSb_5Vp+LhTv)O-9scJ%-+RBT!IMC;&M%6 znDp&Oe2E;9T!{o(VU5Ik^N=%|+O@oek~_Avmwaq9wB@n~ALCs0&XK03t8a6sYH~vh zFnJP2$t}Alfm4LKZtl#gk@=!o1Qt3{OB1Y;#hA$c@?>y-6I1D0p|rRA5G^9_GL7J> z42+OIoPKpJ-K#&FaEos;xOWGKlnv%R*yx0=>i(%MFhwq#C9WU(KGXI$y>ym4?u=07X|avctKpJESxOjWHm z!Wd;HR%V%FIaA2U;OEx>(mm5AunghFy2b_yfUA%&J$mu~0P3d-vWsdAmk7(^8n$gb z*3-!84ADlfCOW!-gM-lVkIt3gdx_EDm`L&Mjf?ec;~@I+T5%XPI9l8kGi+?+V`w~p zKhJu}n@thQ^TB%yW^5R-@)jeg{{U*HHC&}>Xwcj(vD8?k<4*EmS)dpN;0HO# ztzye{Gb`I(*v)S6DUl^mUw_k%4|=&}ZFMwJ-ASN;@unmJ(R-J(x(J;n1Zq{(jbwlZ=s+-KZmW4%`U7NH%XcrJd?BxJJ5<&wnU=brf= zoo>CNT*B6n49m!0F@P?(`?((e)r`|>7KSvD-aU~tWU1Z=3~+PYj%zwqrO5jl$_YEN zjjZ!5i3P>Nf>n7cL10fExcBv`Zlbw}KbsRPoE_NCS3D3$Zk4Mggx4gyuwvNQtf2ha z&u(ye$JV9tZYQ>yGd!&-EQJUd8!?`zuVKY(tJ9Lc#(vILu};cjir}K$BSu`QPN$xR znRISQ!8+ z9P%jz}GjGxe`k)#ggeQ;*s5 z>fVK^EhE(}SX(@fA|uRDz<^I1bBzB0N~tZbrDts;i^tmz9XZ@cBcHEoo5HsDHoeBxXRI$l_X=)dD ziwwX;Jcs0vDN&zY--lY<(lJ0^2m5to(@3l zc%_qBx-f`VR!fyv-4u~4Wk3WFe^0`uaZ+}Q99^EKKZ?crUl)}Q3uNwldy>cWaal!S^H5|4`@cpvNL=%PJBL4so z$4`1AR?FGV4bxBGMp|kby_@-wOByCOB$BaE%m*Mhe2j2?F;@-cwxfFl&m?idHMf+? zgL4NtB>P~Vr;clC(mP#GM{9XnB%U<+!>$!bB;cs;oDgdQL2F}q6jQ+wEgmC3Fe-ER zLBt)rN~#*P?>nSmm<4jDnK7 zU|@FX!Qg#rdG*LFWQkhpSl}v$$!Njy_~3(qpZ>KreO>2-7?#_L-&?bIAF`tHeY_`wYBY3 z*t*GaBO7?F2-`ZNVIldVlq* zo8L`qZX}-0R<~2MkQ8Jep}`eeEq7{|h+`uFfE64b{{W3RYY?P(F-*|1Z97zP&n<)6 zu2AICD(q38GrMD^yn&{fZKZQ)!AgYrO7J);M;+^a9WKh^#cm{4WdVBe^j!4^wriKP zn@zHr=8AbEcR&PkE*ELxhxk_YwzZ~1BiPL`l{}JGWsm}LbGPa3T)2relxf`7lw$7Z zV=r0o`GxZoY|&sb*~?`0&*@Ov+_S7mCAhYZJg)2mkb4k+l}urcCvg^{RSCkgNFM{- zj1F_suU%AIEkE#z8_plHFwVFY;q zalq^KtJX1U*1O@k3oFRPwpcQ-Bm3WvO6F~$M1MBkNkVgn9Z|dVJn>UC{oHJ;7NF8a z_mOkL{&kgla;xsE7Z(+{uW10CcdW^{lIp_&eZe2$Q@xmLFf1=d3lPaCC-9(NEUP@% z5ydkWAOs)8M{FLQe>$kTybw<_rH_)10+7Um$MJn?NDxLmIibkf%ZcBd_6GGRtFkZnCgOQloI)^8=1eXZbpLU)Mf^H*lILcCsvj4)+YWF>&k(%7o^I!O)YBax26v*p#~l3m1w1NcUHsiD^;k-|Eu zPtWnBrQ9sm!n$0altiuSKsi5!SC-kHZ~?<(ImRnOOOS*2bDv(dn{y7 zD_A1gBibpq*k(|D`&1+S9X6{Y=Y!uOnD-^3TtFo!t2ySN%T2XJOqjsy&T1RKLehQ5 zo4bhIoaAF4g*G|&F(;9p-322>GP&BDl=Fks{uJ`+01lg2_7x+tFI!rT+t8~p>5Qo# zh~lA@Zc;+%9E{+DOi3GYL}IxEnz1mA)-m>{n--$436B^ABQ|e8{8Xs!73XH9gYh39Xjz{4x6dK@Jk$P2FVn; z+;}+Ql%HNJ=W0T5R%@}?nv=R^U2^hhEZfSO6LE8Ij!6;$mULZlaPAXMFx~@^(j%wSs-Lwal(<#LG4)HAZu$&g4W(#wsK?S3{RK- z!(*d+j@7regyqP)5}_pCbhjt_%!mH0urYjr!O6KAvkrVGo%oRpQ zPI#_^PqjtSB)Lej3`oUUpXbYPP-lbGR%F^$#+7QaTtw0FnB&j-(%m!u70U@i?RL=B zLA7#)<;;=(_Dg{CJ_*1lim11%45}er=OhjNKT5tdvo_|ql2r-Bi3kOUu+ISdQ)0J{ z=)%!kvH;9?vEJC}&|^6CtyH3s7A{31Jh8g0o^O=S6?^BHK4V)iWrm`2nhTP6OISdJXdMq z>)-7iE9^5y5;-I;g#Q4`G1ni?v__eu*ay0n0<91%$-8q-0LaEi2Q)(xsebNDQk5=k zQ_$sY?IVUrt>m0EbB){1Nsdm1J@M=5S+{y@kzX~enPCVlRe!#E{u%u%bL?$e(LRZyT)}s2kp*5de9U269sdB&6;s9@8k!5O>gusf z09PlB=dK5Hj+LvW>Y_5yT-q$_E2})4nC)+Dbm>+#8~C+Iq_=cCn+809K-<)l*y6Yq zS;net=(IUB-1B?Ic_&*$JVpZG6Z3l2S*CW05=Lo!vQ<|Y!1~vHXAY9LaKSC2Lnu31 zS6*BdBmvuxTENvAwDo9h;}M_%kjS912ZNp~)T352e5X9((z+i7!pfHKCfjIk5L>eW z@~HqEk?&Qkk^IZ+aVO4*-cSHwk=mK_+(#T+1Bjzl2cY*O^Q(8Zb6RQqf{IGM- z5P!m@LNIpf#N_3ux@?!0*3MAw62#%S$mz%Ou7gF4O{U0hAzjAORZ?^P+<<>N%@Y3r zXG;aUg3*1Ple?iiNhEyIm=FxvN%gH;Of;l6GbUH*i~R zTmr54iC$Yhy@hDp+N5!<-K)hdxR@ylHndqB?j63hpQvf=E%W&@Ll{|3HxLvjIO+VW zqtJBwTS*@`Pb|QRB#0>4AOjn5>z*s7t|2AO7DOnyI}t=7ggoLX^KBCeRPq>~f7kJ< zI);ZmzMf>ag_&Mtl%2zc10P;^uR*ZVw7H8X*^!v8_b7PzzV1OErE-_kxAw_{dO#Q$ zz!98C*vBKW&qH2K98{+#%CE60`pu-q?I@UQE|uOOA zK1(f{g}ktRqBDY_{%2oJy#W4oLJ5;mZ?&H;+GxQcV{C2*oDB3LuNGZjPL6x2HoT0= zsH(B;PAf)=;YG;ywobr0~9+nQv{i z8E&FbQOJr$DxpcoLDY}dqElxDq=|6o$!JwJEKu%s4#14`9A_q*r+A9u?8$98UnN&EK1MN-`F$&*6zsY86sup|E@}Erz52Dq z!zxD*>w&$w&e5OeSh|hGd!975XoJbPuJ4zO;QkrnwcAsYdpBftgC8g@f%$sY1j1S5 z-!AC`fEBqUW43;ky$Rj9Nav}0B#Qocw{I~rvMI{4o>cnQ<(>4f#}pHoS;#V(HYHW*{SNBL|`J73fNzZPTV^f%E z^Rgo=$9E8A5vWi*obl^f4!3s>r*UTcfRm5bl?q9|an-2Ov0*Ky)GhBqToT1gG;f?p zbDj@l#dGo*yu!@Kc0D>)z_+}%4jcq!A9b_1gU>HY2){J7c)5NW)sS%%Wi%sufuWKyoloxfO#QjI$(QZc@hp zlh0gL`68BGE+ltv-R@U8&kW-P{#A`tcC1t$nv^c2S*2HeXJBlW{#6rPI19E(GKB2O zJ^IsUgqXv&eo>ELDY8W*WeCan700*IwoBb3sl8)w_S)R-mQ2t1HM%Krc(PqDO~>dah4wY;~u;cWU985JY4=a>s(e{WvvmO`6gjpKOTSBa?`b?NZyi=cx7L z*0?H1mg*+(mowDtd@SPcQN+w6=DT>eKNeJ@Flh@Zhg;uw^fi9q) z+%buzDC*2v3iKprum1q5tXxiRwHVz%Ran|dWi7NHr(shFxX)23^G8z6_28XjRE?O3 zf})qn7$gyn$DyQ=EUz-^!PY(&RUJ<5hdr`IWydVnS1~u1!cdF5X&`5x{?hdYi>9>jxGq0?lOSQ6dF$o_Z8du$ju&#CQKO+}~7^d?ef^jA^M z0_qVUVI0C45U)_V? zdy!f`43Pp)35jBgP4EZkWF>hR{`NrWSu%qTr6NA2z(^R#Hk@bsxb88E-qY<25b5_U z1khYaB=c>f3Z(Lzc{yATPZil&&C;_XG1lnZy^u|(+apJrS{4#09av)=_s>5{=hk4C zk+eJDMj;r3jocDWN7EfU*4^#>wx6Rbv|?0MaOKWh2S0U(L-%jbK){SQqtfgBFRI-A3 zELakLgZkEOy_KGqe5-bj@kI{E{%i(vNzOkX(ywXo+gsmU+{bqKFp`SHXvyvL`d4LG zu1;EHK{qSN&eU~zZ0)XKkUyK|Y)<8X!wmZj)Yd*FwOh}etO(dMNQz4q#xemMoc@Bf z;!P)1vA9{5GjS|x>XGtQz{wf*%_Y{7sIe;jo^-k7K_Z2dDlm4puV1JFrB0larq!8z zlHU3k1nG3@9_>|KaIzub_$)NSVo*_!L=vA-3! z*`8S~%UoN?3M7cZ&QCeV)c%!^du0XD7UdPLkOyX90l+6X^%<>gM(On1M3rD!7&+oU z;TXeo@4?CUtjVu4e+Aq)ok+xtKZS?N%75|S=TSyY`}Z`KniTG1dpS~Em1Rw(U%O|L zJ+NzU&vQ630Pe+{obHh%Mtg5Fqs??O6UHTARi6gsdqmc~G7D9JmI#K_D#523x22RjchY z&byEYRT4l|N&C4y{l-u0R8NO);j)%ErD=)+zGpjwV<2Gl9gnqXO+}@5u7pdQUQ|_e zk_3gEM{ppw*}QgKvE$pGwI$@YaKUaPR#A{rMfYAn^ar2Lh_tJi64Wky#%1#m@VhWF zJ&sA^(vrqWZJ@Zdxn>Ik5tmXjKp+wL{{TwrwdKvdjFStEW>_BEQ-N7wnlfZnZKYc{ z7$1jUYN-wFwy$p@O9OqT9nzUV8^|X(9=OF4mpXhf%8>#h9e5*gJmSx^ytP>e7mA0Hl3N##XM43CCn4Zq1(%48RHAcBlW8mSLO{keCB9a zm62QzlNsmeMhE3w<4GN@{3*OiV{%zouLWH6&%g9Ftqj*z+GMJ*GdLkwfIemCk8l3~ zRbz;QNiK}2N$y_zQd`Ql^Pio#S(B9{j#uh1X_xFJ(d4#;jIu%y?(V>K$?wi99@|w1 zWJ2kQz+#NMwlL&v&wotTowLlZDzjqVMO8!#z$E8>Jt<0`vT2phq*>Fal|(Hkmh91% zW#e$b$3K@^d&C58U<%$~S#rR9x!`1a@l_a$3rmS14~~ zD$M|NB#qezkXP{h>j}Smo1scB+8NEOTxs^!@3c)4lDH!TXOn^|xYeP!hJQCQ+q7UY z+kyzkKbP~XvqmrUW{nl3n2;7V7$js2k509d4UDM+#2DMfAS$9XIG$=t^ZM;$ZAUrOAz)pq%|v!rJd9kIv? znLrsMaQb$xD%g2KRz~oWk|Oi<2q9RMfZ!JM9kztS9tr4382Z+n*XR2VDNwkbosru9s4})9&<`tgY@EDETr7(=4uVaz`Dr zTmJwN#am(&d2e!&keOt4h)E2r95j7)w>cj}>rODgoh-sHk~9*DQ=Pat=iAWKx((z% zVrWzMrY8UfQMfPnv)E^+Zfi>GO*X8aP1eL!BXSY7v%v&<`&CY?qdr@c8cIu;!-rhG z)8jv6jf65u_mpJu&>w7^Rog9k&sWtUNkXrfh7z&{!F=}qRZbly<4uvw*WrXt4$d$K zxb96r{%wP`yk;qOx0nb)xO3Ylj@;Kn!zzijzj75<4JEO)s>Kz{%>tE<<_yNl7oz%~ zL+EQB#=+WHvn#BJ?uSvy#xb8x*{dxqAKDT*X(Qbp_IW^NLQf+g<%hLZZ?oOZLtH=~ zjg1pvNsQ!UKPl;2QHLZgYm+%9?u|=b3d-8fTU3%;d0mSB^akt60ekVrYMtkXCeq-F z_eZ#Uh*De_m~F=(siR>aM8%#qxF@j#X)kZT49Fv^gDW=TcJ~%^dM2+{jf*m2Xgb5z>f!Nh#9;UqY7?3jpu?T@{kM?qyh#{8NvQ_9J*`1-7yDY$TcXIZLm^|fMF${^R*j5Sl31c%TNt3i=gb7M0uBiN@TSLi6WLi>T*)KD zJ|>Ox*C(8MVy?#q>xrScmNOKDD9>K}gWsGV&bVvTQ%xmqT~4ZT*4x~o_O{n)6}j_Z zwTdDVNgtepz|A((PP&5FBSg2c#;VB6C{_x6k80S9Oue+zWKkPQv~P|z0F#5p2d^WK zYRP9=aT!KcUR}!Vz#Nh24?m4_(W^AtO6ui0WlK*DUtj78C-!?=Cz=SDN3@=JKmB@+ z`p)&?be6(6u6)8v6XlS-y_j+7S`cg3I&|XS&z>Xlh>}c{Z%>=IKBBkpb$gPI(%Q!M z-~w_^^f(~$PBEUMyWSzHiAj1HdpPp$d9I|7Ds7tBsTm=a!*QO2+Ni?uJ-^u`gM!!& zIAPDNb@!{M@Mg1`JoEA(>FtAAQfb!HNMy3Pn`rgGJH0=xc1x3&O%6rQo~CGyD6R>R zBZM1S1~JF5ty>*#7_K~s-KEYG61GVIVL+*p(l?UfwMLQ_TrhB%CyseNMlgESHPE0- z#@UHb9EV52V0-h^{{YoopS!Pk%XDq;M`LmEZ+Mc)WY&S>0Z!eanD9T(tzzn$c!7kG z`E40E+sDcPp{3NVw=K$xnAJ7{?0#X`=e1UgQjruG)FJ`3hvDg2)5FxKE8MA6jFpI) z-T)HXGN6scjyDtDpqNc@7T0WUr7-a6Xpp0+aGrw zGflyXO)_Y$6OjbOoMeIsCYW^X#I(!^JYXCV^rVVNqKgDE!0Mcj{t_oenos-( zkxxN8-$EDB51Py+eaGLeDrs(~(A3aQi@>-JKZkK6AB{`)xqj?_J~Q`Nb4G)^DjhCj z`;42v+4QF@b3#X!HtAX}!1B$$!{h{hQ* z4QAa*b7X$b>hY?#%^6{w=Q$u(p<3zJ7y3-;8HO9yk$&gOB_lZlJ@MPUb9&B!ac_Rj zayP!f+p&PkPeb31MR8K7oVjFMjiYj8(rsSQ&H-)lW-*M8N8QhCAJUtqSu7}QO|VIP zveK4(s}YvgwDLOt06M9r-NLsqTCyZW!mYS)4tdAdx8qYN(@}GhyEIiLvd}zLY>e~H zbbmGgi)3|V`k{t8O_g`*puz|a>u$?iGvl!20eOXfz3}os;pYkAQBZq z5%O5>9+~|rmYpNnHSMhN2@8`R_WQesJY)RxNG#v&8=w!kzm!TIgoBgMu@zjAM5#XJ zeA1Pv+VW5jucKz{mU4&1(9_ zd6mg{N#T#QeZ0+WZ8Xrx3#f67IP3uG1!`(AOfFX9N5m|I ztY_sp&(68_>s+RjtG<%`8_Ei56!FMnF^rE&+N`4s*iok`Xi~Dd*kkfGv-ylLdbTKsVrOqTRYSW1j;3>ui20o+fSaw$HXXMK5ERrDee1r#_pW-!C zXsWWhWKQ(=I;ducSB6PqRTo}H<^W&GIfrYFb`KJd<$;mvIpvDQ7)b`ihcE0c+-)QjyBZ%jH z?k%f`*#Y^3=O;f-m9gTuuVBAsb=hweYOrKwN{%{y70+9u-%hAYM(n{usK_5x^!is` z8Viv=gvn}M)aQ6E%+MI#1|hNl1QI*1TAxeR(l$x9yK)1V$pj4Wd8X>n>G7(hQOPyg z0}a0j02sgka!x&KR?oxtcKQsm+M8X{kDnlJQH$q=%JhB`(F|G@BBQ<~-VDRHv!ETRtC;WUohaO%&@6=;8 zUdHLgoveA?Bgj{1&jY_7LtbpCS@Xg99ZsWGM%?xnx3fZ)td^@AM*dk|8G7(NGy0n8 zEW}ZZn}&)EMp#I|C<@&UPfuFmto0A76#AEFhHy% z04K^0bI9&ZQ>8Z2TNN6STC-MU)85uW6t3!wSU*+W*s=X98d*!({_#(nFB~p5o>x6U zsIL5I_mS5MdFpGaVH?#L)ULKCzPyw# zly*Y!smw(1Pfzk|XTujzGPt_FMDq{{QCk5(@1Idz-S(e);csM+N}~avA9vZRSv1*g ztwToQ5h~%nZ12xF{#CoAlvHG3s#;e?``3cX`WuKPTfh$FlWq@QGCE?g?X+pNTgF5& zC}$uRI9!v!ty_q^sWwjDL1Y_7Gq_{FG$iVOl@s#hnFjU@=q)hMtx0QvcHabVTSBy%)-LzNmK2Q z>S~9Gboq3hP+Yio%EKFFq zRY=A}Ms0}kHQ`R}ab z(^3URj4vWH&N}1r&T9(P}W-(EG+4`88Uus=cxDg zrmmxEZI0N65lDWSC)TrWxJ0w8GSitQ0#5bjcpqy|36q2o2r&kQhLtX9tcNnnl`1i^wC2|ZT|eX<5?IHv~P%5zTI6W+%xX&a^fD%h_j;-K4HnveATqlvt+l~ z9Tla#cJ@2A^R>t$qY+v2X}0s9FT77mNm!Iyv$~qz{yCABFzUNixf_V)tcb?OwzY;y zRTQu)56DkmdT;@%7Wdy_K({t4E=V~i7#Q{ZYDhH`eIT}CUM5mTc=E^xj1DU)!u<=3 ztX{EwLrOt%sWfR3P)E@O>>gEr&7-DUx@u?CO+EXVbNcJDCbC%aq!goeQWk(<9 zy;!@~rn-$Gc~m0;WB~vm=dt_+XFNM{xn9#lQcJhCwT3u%1$j59C!Ux%KVEA`Nxl1J z+z`BlB7ZTQaDG6CkMr$Z$J)Hak7!^aQU^SDtxpa|Bi+2h4kJJRB$6mP{b6t#D zy|lLRk1gY9&nT_Cwn06PK^)S=#-t>hRwkN_w=1RMM%K2C61y`bk~5#Xf%n3t}aXNq>2eGqeGar_+;Em|IL9?&ao09Jz)ta0%l+zMNItJw>I4b%)H7;fIvQ zGEVKCv)JQryj%+jwtUVl5jVDE!t&BfU$V$0U5cj* zCeU%u{0P^lM!&Stqn=Pvypt$i%{IFQn@bwTw$0_MV*!py+5rCmJl2xxc6t`447T=B z7$#LS1#g&V86*3?{{TwouctP8R2LTWI#+o6hTI$vUDYn6sHTY$u{jwDQijKh)d-k`GaEU?{8B-Zjp3OU^je{xQ6NF6eB zpTe{(t`Ri&ZU_kxb#>eZ<-lzHds8Q!Ewua3KkTd~aHJ8tkK$||{j={`CC_+C8eMLg zuedyEZ#2&wvC3a=I6IHt1JfR!wUefQXEv*SYxbEUhGuEDqV69y2GNe)KPr8$t#5gI zZ+wpv%>oFYD#2Ask~8b|#ZPNtXB*qxvU#BY0Ieq@1N7tA)^s|og63N}OKhEtXn>r2y#A)Uw+(l18ku7^ zu#n+^=ZuX10H0dpyhU%Q>5^MaOkn-z$O=b20RAEFDzLQ`SIaHzO#R(aYAc^U&g;&P z=Z!!Gy5j(FJ9hl)pZp}RZ)+0GAXkw?7@3a)*Vj135JPo5;^HYhvos}?u-vB@Cm256 zJ*z{?(zQP=ZsYqtq>J+I7*;*A{V97irSEOHE89n6GvakoZRSdfGEftZ=LB{1;~$+o zUBc^mZ#GW~>^k6j{{Sz}tB(ntMtPOmHyixlkl=%ia6Kxut*O%Wi->gxB(k)2`CRZ% z-6VT-^r!4&C+AtgRa+*&k?ODuQ_1`Tc66Y3r=pwD$K2_JKap z8>kF8&Ko?Agl4p1n$_+GmvcEo0u6^4C_p5VdyF2nS6A?$hIty-P-5)6)d@IYdEocs zrFT$WHe;yt(^OQ{^l&b3Vw%!ORiw;rbG5O8G5BZltJ-FuVz8Mff89TqvDtYHNgtpD z{uJv;e90p-%I->sk=;uN1CL(VrPb`xBM$0lsA;I;?&sNfd|WWh1Y#_Y~=@ZKt}p`z_g#6-xmmr!9~PAa)rfQ>4=;veb;N41ysU z1i1ki5X;y>rU7=9SA|4#s8Lwv@y+B$1E?LBQa0LGKa|d zlFhW2UEy14Cm09c+oeZyEWUPHO~xUyqm+gqU<1xQv+GrpNw=0c5XT%!5EIvtzn*=% z*LtHFE@t&G_KiCuPSa722fQXzF$@cNflo|xk6+TE)NWSeb-+O=@{|MsVSD!H1d7IW zyR>O!Qmf`6Sv^4YqSoT;>@KmWX%R?MftFt5@&ME1YgEbRzKquwR`)YceG59W>?REF z7(GYiJ9|_*q!8*7NbzEA%)A8T9QOCdDvp;Vh7Xz~SpMs}jBakAXX#G2x|}`91V<_& zkX3e`2*xX9`CXSnTTfP9($Q@$e#%+b%>_VnwO??-8SS1bJ552YZ^QYv-)BRxz~_}* z@&O&bm6ds^Uc}(u1Liz=bAU<7(J2X!QIQLUea19 zog-^e*+X=~-+!3fLaPnHdYa9TQniM`gleC>KP*k#2d;fNs+ZQ%rk@{~a=0vT*atqJ zUbUSaywahGBy`#i2S7$M#bq2kWgcew{zS^7y^W}v*HMvYln5jMDMoFe^&Drf0<$I% z+1)Uw?5 zao$`_4VbqrC7Mb%Eb%wrMJxPD+p(N=6=z1*VYtvPEo5YCoEK%}vjX6#&-=OjYs^?M zXF#BVoDx4;>pU-|+evE;?d{t6OiIfVkQgpVA6|LKpsq|t9Y#FH)ZCl*PQubzZZzg( zNoH2ak8dY;sP@O}S0dCcF6<$-xReP_8C|2=8G%1}x`rP8bIm&5SfI2^Ydf@_H9%t+ z+lBrt{$HhG#eHg*QOyz?TZVQXY_bx8y)o3E@vaIHZOUF}Yn7~+n#1X~YYGoF!u{c# zI^=QzBRTxVGF@I6tyLy77jA-dz-1#DY=00SbKjp@qp7`#d1GstaT^y28*V^PIQ;(r zD#^N8t`1sq?1YdQ@DE-EdTNX+B;P}hRa{%Kt#hddvw{z`%W#pxQGQXC9N>O_y(&9+ zU`S#`m`aL49-X?@b*r;W0xK#oC;nOB@;L>&gXvbZ=~K*?_eMDoaJe{K9;AOy zYMerpSCO1$cXLt+-u84dGBQR=o&NwZFG!{ zSs~2QVr4ik(Ex-Vhl;Otu0qq7hE1y~ggH-}8SXk(cy&@T=1W4SX0>{i7gBgvZO-z* ze50>=Y?p!aPCY8#~aLMvCNzeQURIywcOGfd6GDyL}zFYLp(d~i{af*uFp*djtNya(<0641h$r)S;nMvvo2BTQ~rxL82z~Bv(Nsci| z8m2j7VKANj`RXW+azKtojfX*=4MT4<^0ot`1N=DW6i(8*4T!CdySb`NhaQ8ZxrsBe zHaAVnjGC)CiOA%EjF$eD5RT$a$M-`VkbNpAkLTo-Vfh+~Gf2dEwT@B%cjuw#Dpa*= zRt=KtlaRxuS2oPRZ3MaK3C3z@m7)2GY-btB;-gZ{2&YoZg&|KltD;!(hUwQPvlY-o zuoAnv1B{bSisj>RyXMEIZ1$}dhEhqFp4KOjltl~%a(Mk}P>cZGkh~tCk}Ew}`ME3Q z$Aj|&#W@~nNGjovV0vPUi<3h0Kb3`K-JalNQx!k~_Nm<17^$LJb`r>>bt98d zX>AWewv$$l%2gK@;^;^uRwOYeIKck^BDEpZQsyITdm$G=*FIp;l&IsGfbt0=W8Ut_8Y zS4*L(Hm7j_2*?6Pz_X5Vla4)wbJJf zAdZ<8v8>-LH?Zz`uHzu568U5tbq5BsZ#44I&39oO<~TqzFkstqc**q7ab380$JyRU z=bWUaXupv@j}6`J-J~)U$bY+>9#4Ps-mU8kb6^tQEXMLP&g;9?h##VgrQsWiM~Lku zaq=c;~4+}`S<*5lC-T|L#3`%RpY4_o|9UAhTWZ~ zg}l~x9FW~e{VPWEP`aGjs!8Qei5nR+$Sl|cBkB6pEfUM@+T^WvRy2D@R}y59!=NLt zYPaRv{{U&*H1_47xtS9R`$7P7yX#!-uW8HB-Z6H$t8p6YCGIWZNG?3htkIv9@OqE# zpHa}&HdoS(#nr}TWrbBn@06aH=coSwT8lXz#@^;BzjeNH3&+o!j+yPxT-DPf>Nh1* zA7@z-R+Zz=$&5B})bWbpb8&pV5xatZrz>~lUR#f{*+69T3p4cx2d+&z()BE3&AJ~k z9j5a-0Nc1D^2I}~Ndmum_TJ+diF5X5KW>EODfvVVMlBI^dqi>0ZYp zs*%O;JIET`taT zcf(g!mh8K+8Q=U$smoSZePZzn@Fzj z?Zjc>x;qKSOpgBmrFZu5G?p<7%SE_Gc8td-0B-&@VaWU|&&1S)DPG%~K{+yn1k0yJ zRul%^fdNO%%HME;e-T>u9!NzQ&|JbUC-Zx2X<)+<=mgBcj2O#FeI zZQX&MJNwm-6))Lfxl21)B)B_cbdRq+e=6~3ChGEA`q1mAPemqOx+Ym2<7G%DEW6dS zgTNdfyqc|TsA+Z)w6a}`nN>z3d=}1eoMWeY;Fndsu($|B=m$H7NN+>W994f4+%4tn zUs-(C(r{lJN16Os`krg9mI1jaN$6DT#cGzPU8`s@c!Jbktg-WGe;cp!E+lO$K+38*SO-X=~_;l z*0#%hzC^ak^R{ux83D(BwV`WkWpQ}7O{=_Vhgl(SmQFYUTReX{!d0Uer$VDm$z8h~ z%yySIvD{rrY#LaJ5s3jChB{z%$6jh3f61AmRSwduafgf!56h8VSvOjm&8EW;c$hF! zrvfO(K4w0-9cvp{farG#JgMeKG{1QO8-O02_^soJ=BSmu5j7~N$3}DW+J=%SV`$Pt z^00HWZ{t$Ubv1#Ha-{M!dsL2#&m8*I%a5_n(%l4<2XG8|%X@*x(vdB$bu?7_GC>%} zL?0^qpHu5yF{`4!#ypFmB3)aXbeefuHH?)246A|%;rP{W5&1LRLS)?7!XRw8BqJ8~5CIjC0FNepHY^NjF28oV_(l6m~m<+Oxt zPykWvayS^Iy3|U^JdnzY>Zk569*5~wd38j;Ak?jHZEa$CN`CNUFG9Z6ma`7{j9Hcv^1496=d}=64oS^Q8;LxH6@1Lhti_AmRngBNG_y|1J@qL zx}Obbv1(TrD{$eTVP{r3+%wP8wg-hE^X)vT19?rdSH>HG#t%$jiki5HC(6PUWi3uZ z?$gS$m-mdpWOWQiG4o@e)~s0C{hv{^g|1LJAH3s*A9+DOxa9rY9P25H<8&$ zl9LCR3kUg$A(zwMxy?hvl4+vuNF-MtSdkpIO6RUezD_HWIH*ZDrfBF%d)7G{;pN;H zV5+2N0OaSmqT2n($b-vL!;mUT(dLnisHrXru-nJht?61f+OK1aiIk%<#hd~{l0RDR zZALedl8xPh;$^e7wS_@qf>HrJOF0AiRxQQLOC#XtErG|Sba$FNDEm>B50@NjRYCa< z+_%)^)<&VHn@JiN6`fQo7AyVX)7rA7QZgG>D_E8fxw6}S@C}R#+|jRWk&IVymflVu z0kCn?9)_stl8awGC9_$HMqXH`2Os@l1%nKD+3pgh` zMl+xD-n)6^m%L=s=wXxgdxwf9Y;GyL9Y?Mz=93~rb0ad4t8Xi39UEx?{$y3-r^4EL zPbx@R7{ovXZc;L*KbWgm7Ukuc?3E*j?9B5pIi@bO73+X6HWPk#jD#&a(4+}c=7Zjc57TV z0(h!-gl@c$t5>H=Uh}uBJSq)6@9ecGtyTwi8x)5MIqG@ta4VL3ceJ{V1WsL8D# zvE^)VO*6)ItJKp>X=FvhI&EcR_c|P|IL3Wyj+?IEO@CyA?CFOsB;HV0jd6lO9;5TG za79^LWm;V?YVH`U)d;~^vqvenb+P6eUBcRH21t?QNg>)|%=x!dvDCD!L12zZt|BkG8F(th zeb903TAGE_cd}+BxYH+P-eOnW2?TFYG51CZ9P^s@Pc2xGF;Ft)h#-Dd>8Re-;8CpW49gs zMQ9C6O}f)1iq+wBa@(CB9&9)VjGo+M)Ys5f`fi#L);N*2u}0eD;Etg4*1S*Sg@hIw zm7T@4qyz>lJFxkLXKp$6+;K#($-Adw{jQr_;&oQI(RA?~&Vu|q+-wSs*?B}E=;{D?Wm2mt;@oer`z_E1%2wRQ7$o~Mpi zC!fl*tZ$@({^QOGCP-Z59P`K@%A78|>&fh0W&Vm0e9`?yGk*G^bm8iINzIk~RI_9F-Xa zdiTx^Y-qZh2og;~6XwjtKyJqvVydi#s)Kj2XVz@Y6*F#;48+eW+Nl!NmTT2Z2py& z78aGRYgR5Mo~Dr8C);2fCU^lk9RT2ipK8aR_IT1L9@t8e5H}eL?il0nsbF0~(&5d- zCh16JW{(UNNbAqNQn-xGCzB+CIcE8Gk}$*9+Pxe-Ic+DWLz<)Nk$OdnZ6V{cyGZ0G z=MuLuo;V)4?0e$0wKlwh&dT5_%QPEcc43e~;Gf5gR}CS#OOqQiw3!iXF@P8j2T$i+ z3>w6e1h$!@b$Lnx^TRPIB$-0W10dMPf6>JOuM_=h$mL;yFVzaBN246QM0x^Oxd*}JqeX@BM2<9^}39@D+kxt;v8mk~j8-rnw-XErFNo--%9az~5XN`-(%y7;- zr#(Sjk%iAW2Rjo2o- zeTj(d^K7x) zTt*gB>=r}|{9V|4dr?w4I3`?smLSz$&=0i59DZ3{tq{*%ihG=6HLW$_hjqcgQWOlX z;8gTso_p0vtZgQ<`$p!A%06_mIO+%($Q^w;de!R|w4A`wDombVlmdodFaebw!+~5C zV+54!Zlv0=kspJ2pERnVw73hj-V7$6VVG)@ic7qDG* zE>ER9v#gGi`CuHD7)}p8vOmr#bn7^wktVp5I=12DZy0693D2&7l`3gBb8ed6bCo;Y zG8`%Alk9K?DV8Pf^$oW$K(daKd1EK=^{RvCPRx2oR)^e1E^U6y@koXdu~`lj4c?xe zIjAml`)dn>ZE|mtK!IZ+6@cT^b^I|`?r$w^q;gsA0Nffx$`t1~#(5dwgU&@sr0N!$ ztg=COb0Y^k5uQD)-`yh}4m-xkqO!NM zl!-#m7(s#;1-a-tbKmf!)%4M!#Ia2?+$G>vhE(SzPb$N)!4(wNZ>r601QN$?TLc$w z0|DQ-r6%WXbR|VcrlTOztrF(!i+JXZoS=?Q7!Jpu!j&}92AWdZAhJBUc++-NsNu2g zmgDJ6n@GBb?nylDss{Cq8_Wzlk8zyyRqZY{7%qDGMNUf$wnwKXwzS&3UC2!*XQ8sX zyZx9IMlCir6Brn8$KS0_VSfyWkX>L%jP2$a`{RT7AI70sCTk7%7DR}_+bRvir&2TN z&T5-k#d&87M)D2hsb$2?YJ>8)>c%W#vl1QOm@$-wEF-jriz<*AI+ zllM$pYnxKd=J6ooEZi{n;;de2mhoKX-eT~u3>}v!!ySKG&$%Kw4#a+aR;ITTl_;$n zjO4CJIQH#ZI&LoUW-*^Kw2+s2LqJr5uNmk)YP3@|yE{i0$lNlHf1PMsT}-76@JOh< zA;x(0sqSqgm>D2KVk71oakY;?ezZbO`?K66n${*+L31`DwI$eYDhD8rry`N(odY0% zsm9XXcYD*V+TzvZ0s?cvD*UML#Un*@B{DAJPdjipKb>2;*jhEIP|EDguNvpqZ$n8J znyOeIy^=BY#a)Aa%y`(S`;S}>ed*p&KojQO(2l>2C9b1wEeb6pz^>^?_5-Cxmovwf zSK~cM&0Uh(H!C5LzEkOp`&2U9fQvoeOyOjUof#6SlK zbIxj8a`G1&lmIvw>T}YS+8b9Rk>K@V&l&AXw6cp;a*0ng`8g<@FM zvgqVvIimO6IczIjBd!>b4+DxtwfRe=&9}Kx$fwH^`C>*Pl=2S;0-tYum>C&R0)`@n zG+NWpS6mW&wXQJ#8Z8SRR$@y^Ookrd#3!kXAdgnEjH z3PIIDmd=rSeXHIQgSdUSZ`E&EsRr7b*L(AQ{}|yMs^7K0Fl&k zd8^B5G;=}rYls>-2sbz*h64nTZuQCN*Y`S}gL9?5$|UTnt8!HCRnAu=bs4Qs4Tr##(5Q#3W&(9kIh`@3Q9B@bKE7G+q$aQ-r-0>k(wLwv_v(xEZL>hgRHxk-i zIJF2#+uhC%KqHPvaa}ZL8S1(jRED=Rbgv3(a=2wl)ljUq1CnvuHQ4xOSto+#(!@HXOXfr)a!P~HWb^+3>#J8T_r6q8##Tj(bdm(f zEsn(cVzm0ql}4HuvX3p#EuQ{)qg-tc8IyCMI300Yehb!rvaZCfZEY+}Of&tYgXSX+ zKpcH*H&WBg&_vM0P;PDHo=N`qU(%{Jo3eLEhUp_Cfs!-a=hD4zal?_EUh>esv{8~VYNuX8-e~mfwCO49|q1y(xdz$vJY1)mXw;;sQ zD~QQw+*k(5Qb7Lz^;aq4G`+OaV!4hj{{X(2$j(L+I2c~wdUvU`$?vUfN>3%UQM{gM zSU@|!+W!Fc9&1m;7m!ck>vl*{4K4Z!iSmiObdE-9y=aX4#a75O!2z-fS zS4@-Fr~}u5gNl`|B;K({1QGclZP+u(UOM-!>R{>5RP+>aPC7JK)uPiaE}whdUAFS6 zwFFpC%!*w{L9igLoz#+)Rl+*q!k&9@$JkYEM%MlUqD53PfX$W}CmpJk_vNjl5wwAn z2HvNUgMpgu_HN6SoQ`*U9Vdm^?Ji|~Hb7(>Sz>kzxS{FWB!WQ)*1B7b8VhqQ%^%pL zmpc(S3~`lUJA036<+Lqo;{MiKiP>898{{js8dWC*zZf{Kf*nN7ZkCq^GeV6dQZXgk zJaRuVUT!majE)E0L8T^&QDNhadKGn@=y zd-M2Kj-M~t;F0cbi_F1-w$gU5pgpN|QkK@STUp%_#O})VVBh|#>GraAi!*VG)e~E3 z*1Bu|0BSq5o5Jm9`AVGq+#bJL>qV?~w}L5WAqhEEH%T3OTPCJv%@~zxAR%?bCR6`j3*&i?b z3xWDoiEV9HQMxxF=9XypC}leV9;9^YI`yiSTHTD&$vnvH*2FMDlg2QA3bk`I7gHO8 z8b{&lP)Iwq8%FaZ9HNATy2bU z2s{@0))A@glk8~X>9b43Hz@|WYaO(T^E@jUmOdMC;G~%Dr@8g6dKsTe))^XW*aMx; z5dj2y`e4?~_i?;4v>JOCx+e*{=8&BH#QJ?IrJc~Z({6gw)UYqrr_rwMfU~!iLY>WZHW^H$bFoil132|Rg< ze;vRVH!RyZV5m1U4wwVIahleS1e4rpvs_@3N;vtLlgZ%p6!6pLcbD|XRw*mQ!E3QM z+7)4FT_fBH`+<*AJM)@$ljX}byf-?iwJ##GE0R^Pc+LkLde*(Jix>7Q7MYYyFljao z?At;42d6nXtbKD#STDr3USoMGuPU+ShB|@RV!Puya=cSHxmx$EcQ?9^+X=I{vfRP9;A!2D~WwY|NP>fZL~0c5+J%Ikt0 zE_nL%t|L;D?Kcv%NWodlWSo@itB9<_$v_Rd7}WOCtOEsSLL9qUr(RMW3+t}XWnQ_NwK zGk^*I06DE{Rg`CCsVkP+9QVs4al}FimCF+=6$Ej#W7n-~K@!aAd8{;-kVXWPLS!LX zLB`*%I#nC=vXRLb{$c+BmU6UZNj{k7w{1TAoUXmCwytoV8;?5v@HOEXSPj}YgK9P&y0Z~&}}jY2(s!r|@hpjo#gMc?IH2WAIMf*mX+JPHFYku zKra_ev)y}k#%qFAk|!jEQ{O$$HF_4)zp(8klx|zLVYHGAYwA9y@T@z%K08Zg2|Nzi z`LcI)=kuhIia+9qI-g&#ALc|7z2r`7yB zC7rCdD;#AVM1LX44hYJhd=P0oH*sw^7Pnh+t_&dY&!P4w71>?eJMO+dOE!UtPgOARzyicY{r{5S3)-Ft& zRQ=WH0qxLNqFObqWqiA+gWInJ^s z6_ytfIaY3a6;g^(_jf$+%TXrM{{SdB^{tH>IXugO6K)<@eh=sVeXDK{3X7FUZ$ERm zW6p`V-@zPr<07os=oU+?O(ZuLF>Q-%E)-&BAc7C~aBH@uc*-s)$~2zr$+KDQ=DZQ) zNE$P|ADAOHNgsf%?GF9nR#{p(7FiD6=tKJB9^6ycLv2FJYp1vf&XA)lVEn-e+ z>zd=5^6uL1OQgG>YLX0n0RZ&+S6i?6p3lTruq0OAOtB2GAP+PQU>~na=hZBAJGo`H zS5{v#Q|25Fyo`4r;YytqOLd`jYAHW;nO9$Bk|v%rChfW7kQ|M}b206OYskHhfU$!=kIt=ntKEKinZzyJm8GyJHFP0=pqSS+rkjzW!zlmU^0g(9_8 zuNyRGscUd&+F}4T6~k5zk|+Aq9GrDH@BHcTS-fyhY9R8~K&-4ray@hP#~$@}S-h85 zydQ11jtNubS5Bbgg5OcjYfHk{*5=Lh{X!Gv$oYa+Co9Gq_2!)B)HFm!DbCj`=wE7{ z>Gb!Iye$}vBk~cr+ksZ~-wfW_F_TY;<(Yv}6al$F1dM$^t%uR!lTn5A!m+e?Nj$Dp z?K$0(--_D0)F6%>({E9|RVE9#r_!7gIt#XmvN#!YX<}r(SWg`QgqX#`bbK4c?UIW*k!!0xy)}lx*@`hv!^D+{rDu0BI zpGxZ@@rH#VRT@j3#{>6C&p7_|eMU{1(ZJD_DJJjd{%4<o}l_wxWs}ORkMMdRzrCEL9~`tZ8q-NP>}L@DYOxvM$J*1;*ODX3bYoN(qNn_ zMwuU9o7$c?9}HDlREo9j`34^X=u?Cw@5nhmyxs*m^gXm_PXSak@9u>{S))cZ(Fuah;?L*1BD6 zkLK%KmA}P33ij2m64v!p5-{qDPBH%1y;om}8a&w#YkvVFC?rK5U_A=qxvqK2FLP9y z*y*nC<7};0g_XJ*;wSi21*XA{I9`dLGA$Na! z(zjfxXk~YOPe4+N+071PlcjmRuf@$CdBkSlP+Yi8%!`bl_!V1=;>L^iq_=xrK^^*T zL>;sJ@AH~cPiu`yGr5i|7U!|9n@k(Dc;nvdxma#Ph8&(j>}$#7_?xF05n`~^r1LTq zDj~_nNc+^bpBZfuKQ7)aP%5XHv&xL%XWgkquZrTAW7M>b9kkcEk?!s$^JRBcd3P=j zFi6MVPxyw}EG5?91} zy{oJfq-cy=?Eq$7*yI7wjiVKAuR3lzvnIJ!hQk50oGBACBs(TW>WYh;f_NmFv3MbY zEt#iS=a>lwTP2C>k@<1!QpdY=7b!4nX|32vlZI>z5^hy%>$ z0CxAl736;!qL*#Wo{`i~?0b8qiYZMkyY>t-l-$ydEsS^^i z50zgy82~~_)FXu3-CHsZ&AlZ;3xn8`>5eMplS`@F$7~^KfKwqwC5oWq`eX60 zN0w1u^V9S*=8UvUQ&+>+Qe2-h>VG(@22m3qLIRQN{uO0oid#7%E;l5YEwC$QX>EXzbArjnKp*F&KVH;b?IUYxk^*qeA0eOI=b_@Q+v+iD3lht4;Kp*Y z1qHF6PfpbBPs7isNA|5gMmEu^%E9m|vac@7GRm!H; z-POlH!|BldMM|2A-b}GfTkP`WkboQ$z#RS+Lf*+Opiz4hIl+t#p>}%ordY)pf_QC% zv}v`=0~t^lVB zc9rfaPu;OBfoFBQazIj9&T)dhYOHp~dzUcEPs&RYdXg!SNpTcHCdk-%-@wH*+?cH% zcmV*7tiTMOarsu<)0eu;V-&SUriZFcV|gOP;#iD@ine)Na&Ug1tzDN=YtcQnSIb!o zE=ObA>0JDJk_2~!3b<0fRG;$GBb*V?_oa(af?1JXLjY6&u{@R|AI`aFhkX3$YHbGaZ(1ppe1N2>jAvmB*B_VXR3p?@-KB|LN=D()h|W3n z^fdi9RDx^Ux#w-F%1nH8CyXCljw;>NC%lzsexw4DBARFPaH zwx4HfeC$!&4a^R4ios2CNRUM&DDg9lvFqqhwOqB4p6cNUQn)fJG4$*YuOFpnG}3Nf zql;tigtEG%FcTYqpbtO}27d~x{i`cmNrZQVF4-ovDErw+ z45ZQBjz20e&1dsd#-Yg=MwcZH!>V#5Uv2O||)X)JCcgn6N5 zk=1;*lM4L?0mmm5g%|FnC331oH=!WZ-qK$pNL)m?KRCg`J-;3+Lic*rLNNRYf^?TM)T?nS>6)#(8Q?I@2xT!zkU{9Jjxq@A zQps^>8Lrk6_Xi=>+jaqNtJAmF+Of6&00&>_@g(t=lG#o-uLTZzd-Uomcy%~$t+9I? zCTNtq$Us+YbP9X(iamsErw4VjDb2<5wPSusmF%1CF#V+iWHKmIBY~Z-@Ac=UL#N$Z z-c4<`IU|_9BP!cU@ObZ#N3R_#CQGK4*;d%5Oulwl@CI;mS{4>i$*Eh%8GA|FY|7mg zThNo(;~5m(RAZ>4Cn*tM+JRGcTR7qhg!#4JpjZhxeh{CR2lql_#&#tm~G#H`)Bik|5=Rv5n7`;Qs)!dS}|GPHt~* z?;Z=Jc-lb|yo9eEvOPGe8h)KU$u{Ocm7l6*ve@GuqO^3HeCk#woi)qKbXpFnV{i7D zCT5x!K(Rz*44`KqIPHUxPrQ!WYiVPJn$&~1vqnfbJYbGNKhn87ttqVISqWt5n$mv~9k(XiMhi_9wV8`ME_Z z4i8Kp!lSrGoR@gab0GzRVi*C`dLQXh-a$B)87~|Jb=t`IR?hF?Z1wIvdQ>s#x|Oxe zC4{#&u}QRp*OAW9dyMDniqTfOy~y@j*`np8kP}A7GN}hDUj(5C<6)~xvM!@<8%6*yup65nLDc$ZgIhOu*0aWoG%p;-0l{1qa5J8I zj)#iLSC=)fb5}+-ISZ?2FBQ8=%P~w6afTg_{{UL6{PqyY;zPOHXgKIS{{SlJbsKAm zf?ZqPrNnY_N~SiR`3JR7nn@BU<&=EV9p?-8amEiHjdm%uWcE2F1+9!rnQr5^LbnCC zWbHW^ALH#zkL?#wu@e*kjDwNSp{vqgCBm}FEIWt#uuz`8y{kQU+p)@%=zqqyl1|n# zk1|h~wQG2`d&R@FyMa=;Do4K+Qaw@DwQUyoe(?2RX;mp3yvIiIH2^ z9D_+;W;;b{ic+$_$kSl)w+++UqY!RQ;&mW#RwRrMFuIYBhd9XhsFEn%wiz4%f4jh` zaV|1j0>;uP+Ti2ctv>=c%N8X5SoNtvc?l7&UmbD$svYu&20++6XKz7IO9|hhGRJ8j zGx?iH=VRc5_|i43bHFEtSmi`GW#BrGQawJE1Zx{^4$CG_LDv-%*`aV_k>kPO6H@ir zjyilrw}LSevO64g801r+5vdHqH%1*>0RD9ZQ?yD@fxzv?Y9h(E=k)Gr?gXtW$th=V zFDK=})p{Z*|X=5`aOI0O&;0{jvRhxPuR2PHc?OOrrD$6<+0EgIhK(>X%niQ z>$TzABMG1K`lZ@FBw70GJE1Ns{NT2ffm7v~frkBG757~-M>z$alhVs`GeI5E%a_S~ z`r^eAm6L~Lo*s2P{73EQ_an_mGkmQpMq1~K|GVaMteo4wf%m@09$OuAY?+?YGpD^f+V~eki6J4OYe%DRX<|Dm z>yErO-ZaYo_j+i!XI7;R-lC|_M+qx-mtwD`PQ?-`iA1D>!(XMPrFK$03EBdN&9ANc zGNagbQ+b~YOUM{_l1{Egk)e?hRxQZO%j-K*%Gc*cN3)JRwv#$k?mkdrUsqRm^Q5qz zNl~8{!6vu+PHH1^&*!^lMdqha+1b;1pO093=Ux>%n=l(#Z6~E`{L*!(y}dn-OH@Zk z#|Gbj@L;cxnKGWhapL^PACHd~_IVZcWuejM`T4W6vI++lJ+s!5j=I$PP?S0PdrdzqHrY2&c7kBIR zd*>E#@8HIO>&nViB((#JOLMPp$CP|p5IdzBvGc2Ldwj%0;p&w;qNJ*4N_z(TD?fv@o>yIBl zy1Kg57S9#aFoWgpo#~eM&$X;#LdL-;NO!p2a#4^sc+Q@ko0~hx!4a}FXk0ol5HagF z(BI)j2&2trs#8|#=__$@hYx1&nL)jea7jeHdi9aMQiFkK!VsYZn@vdd{QO3CLCMFd zc&DqneQBhG-3!C|N%J~@oSd`>9SNA`i63hAz-gLkd`gbRC3n}Y|<`Ov@iAAh^^AQr5 ziE_rip~S>pJVy8V`EwU8TsVJzl!#>W9n6{ZdV=Ysa9+I5+p;>@5Hq0Eb>Mv=GtT%7 z_mSvZuV1vyJ{GjP$VWjF1Jw0SBd3GUw_v*4X)Q{ z(E-`xxVHA%D#I0T;T`b1$v&U%cvK3+1_-27?XRyI;ak_&zFjUlV)L<3`Rx8LCH6I` z!jl&{9oApA&F19f1XiElA0_Zym7>N|ZL~`mqV-*k5Bo<0+h+84v&(R$EbKe{_^*HL z>Ilt=P)J*Ch*p?}nC~KXe!3BXZF#~xft))V5 zJ%>XNSbVIQGWAYuoednR@~18@V^F`_(3E9^%?M~@a$4K0+B~eaJX*J+1jy;hP20y7&ed zFa3{UYpM2ujAsglN29+2Rm7yFXERG7GBRBwBjQ4uS^S$(59^O^ZEa<=&6bswh1Jzx z+V^pOeqQA{eRo&MyF@;-&0LHd!ffwT%W-;t?p>Q!(1dFzJ#T`n8qu&MW3UKA^}&O>InTO=L*aCT-TMs%IC;?w$kW&H{)Y?6?< zTskO<(1@57htaZ=BWA)U*!8i4f)6Nu->FNxySoPu9#nHK>iC9Ah9Z&3*Y|iYT-Y=o z`36TO83QqW_UzgB*$-HS(YMRW)*0Hy72(?}rUg(*$ZOw@fhB^CZ$Lnq32r8^I=!?! zMjUC+*oqw*vSxD{sI9`uwo!2Fpb?TKlfqsfl14_B+>7TYG*6)mclEyYMcO2&i1z_vrVfHm`CpVYGElKWeAqLPuA8;k&}J{Hg*wG;NJqisq@!>?akJ5jNj&$;Q9D9fmkH#8Ni+{|a5c651s{3ng$h_t%Z zM+dle^o%@Po#lX-xy`5lv-_Ne$*+J)I(~_icYpMRq5G#y`GOpB$IcG-Rq2n|QpU z{3*OSZ+Bi`aSgkznq-PQ+aV2mMf9+>`i?SC)Kd%Ti9O|+H#hj!ZCLHS|F6_1N&+e{ z^UGph4BLC$ib~i7&CO~g{W}p!%@1J0OaG~kxpO$z*?E+_Zl z5{v|lF&MEU?`|Gml4Z3^r(@tnHs{%)te{_UBQGUaM}y-;$DU2u1rH^_)}OI=w>?kS zNGRTXi$UqzTYN8Im7O{z3l-K2g8A>nCmab6FMg*dXOB2u>V^L1y)gv)OKbAB!cmpL*P2&^FGS^oI)Fkvp{`z zntQ8pMdX=yIyijpB;sGIu#9{s>g(=ZMK>fj4Z!JJ%kI~2JStCt7H>%=*RbVa zB}!-Ap9o%ez7$Ez>g@S^FH@?R$tiNgKvr%esJd8Iiie7%OVtZn|`M zLv&}TwliY*U=*30tFM^qCiJHHm7SnQp5T$Z^C%ONR@7m9YxI>5skn!;9k0LGiMR(w zwW8b5HqLTY#ge;E|0pWNiDs#A@#PAUkjt^WqF!dbJ3@4JzFvM-T#DeK0t%lrlBN&a zZl2g}heWQ~Nq(eXxWylYTcJ8qmk!$BW&s?vxVg)BKVIe-$H9Z7G*@McU76L=;-YO| zWpGa%d>u26JNoq}jkrouh%-;LwOKR1jN=lQyLb56r{#MgUFlV~`(y;NK37x`I4pd^ zQ|z^ykjpJNeavCJimJx=QlhGQ<}Q?gDvVzxrsA-Yiip=9G(&B~tX|TtBQ74-vim%Q z?a!uCSgMAmvO1Mp;t*^nfUbT&X7Sh`>oH<9TNz7R^woHoCwX(3qs{TpY_Mi!zn%fgLFsOREWVFL_m7{a0i`wZOq$ z@i2;(w!E=9x1wfPfSb8uMQZg{UHFIMtWOGYIHBmSw`Ia8mnfCX%a94wwR`JN%`Ypy znKHv4_cq*K@-9V8CcuJ6s@Rd@966c>09^5_bQBhrA~uWCgsZp5!&{o09}8a1Y%5ax zNR~clUepHwiaEC^wi7Fwx!|7og-)mI>grZGXg+=Dq_K_;><%jZ;7F=&5vdOO zAA#k^=lodk6>u%a7VmF=;Y8fi0*HaQj-f`Zz_E1JHj&ENXh*BsPb8BC7R%SRUsqLa zkNTOtD6o=VSXju)$+^EgnQgo3BlH(jgn}*$-WKW9OKap!!||nvhs@p&37XC0IlHT` z1QpS15^$KQh&+xLDye%ull)Gm`IUize7ehgTi5)2UWjjqh1v*8jopE6M0w`-+?nZp z-0N(dF5D*!56F)rE07h^6w-v#2K7?UB^^1Mw9y8uk(agaAC}BnT$-P^rg(f4@R;IM zI-4@xlAN5F82b&l5B%f5o*5x`$;uNE>y^GEXV0ExocEvzP8M8v6dV*3?f7v`a-4rn z!y)Zp4lC-o47y>SE>BBO?0vm4^3*M^(fyROf%HXtCT6BTF5&0VEn?1_#wmTi_e zuAWzy;mkPWBA?#d=_e&AgY#q$xo%fT2bIHTSA;v>UQ95>iJBZ1ZWT6lPJ+1)2+KqJ zaM-7cq-v8O+p;1gUGv;<9o<=AR7su?WF&m7;k^m2m~vzQ(otq6MpG~=>WdLT>;Qv) z{lSmV!1gum7b^VWChVR76H6DIiN}N+LjRXyJQ$xT}{_n??Nh*+AZB-uKO9 zn-%zy`29XkF8d>E1nPqOb-==`e4Ku+TsLp1JpO2!${Ja<{8!^s>0$Ww6Jc z3ZPB6QQ?I{ zrZfp(z<75k_t>DX;D)ajD5c^xEc`kwQ&>vNJoUe#e~Vxm>zTfET?K$6c>l;n;3m^~ zkgGg>UYm2-{;ZuA2%$W^ z!y-LAe){@{k2LYXYS#`&$xBE{A?EdAyFHopW)f#DAMu`^Zw!?TvWcA;kXi}bDzUq4 ze9F0)m)m?b_f7B|Bk$wHN7mCCvAlG>)VRV{v$d$hiE7;3&gKm0|W#?$C4C=}isj}x0p<}T}x?VCh3=W->vO}Th-kmvcIyCei(20n;l=P_RA zRN>HNZ`dM58NymkrmtoaD!V;ue??3G17j}|S&P5j&_}=iA}AS>0o1IcMpEG<4c5+d zT3Q;*;dw!11hmX5ae4>WT)?8}=k?r``kW*ia2|lvMN{liI4_@HuN*3}0up`k;oUQ@*bl5}-j{A0!K?cVT>&vPd@@+6E%fce3>6 z5+}0fmHXa8<o8IxGy^_pxg^S9L-jK(cDV_6znQ|8moH!bqO zXa&y*bL+y`_hqyZe`&#Ni(N8sYq4w^mhMRwJmlu)2F`D0O>nhrCN+e_-128v%I5cZMLX_15nwn(C#bTrB1I++TC7Fwl;4!DS&}nnez&X- zBpWIR1qJ1KF2q!^Oq)6xHr`COA-UK8*e|M4R(`cziA9k;yhD-Y#r)7FMIY)!Scs)t zoc6<#I&2TRz)$xp?ik1+MV3ojn3pbK7B@(dX{oe*n!PSiG@ocQ&IM{B%Hn`F*`R#m zO%Lx|t+L#OCuHW|?O6M3ZXXa_bo{9R>w@fpPUi*5)-QkP$y0{QIRZ}zyv=EwRa)@2 zGA|dkVfAjx9Ap1XX8i<8_q>3>cCz5bbLXsS`@MOeVIH-b`Y^3&FZ0+%iL$1qrmUfi z$jHdsw{NpD3L`X$a0&@{)lOxDfDY)SY%h;k;>MZ_EdmCE<#zv?ZYd}F zyBE982C8laO12X=d=R543 z-xl?!t%3^pITr{FYDJ#VITOJgbObmwQtvx zO&xmn%p#H7J5kmNzmZ{Jc|Va`_5=R(*<0mZfl;z;Ck`4{5ti-NGjyyMnX#BAbl-Rn z%Zyqmoka*fKEDx@n3$Z*ZuV#BSXvHnB6k`9yF21fWOn!?)`7+Q`O^cyU0uj-clb&* z1rU3z6YsWbDH?#(qyhRR?QY(O$}qnzZ>UlgU?~DV4q7+}hYwHzIaBqD2dgeB6 zrq3S|NSfJ4hJ7G!wjb25$L>%#@+U-n^CgNKwMD77VqHHm@2M7&OEbMuP0~m zr2@GZC6PXe<240zm=f~?xhJc0EfV_SVM0DJ%@ku=ASPxkXe>C39wh5FwP}cEr6pLu ze<(Q4bs`@^G|IDSU8ZE$eIi5&KvRVQb-uIY4xxu2w?m{uTlMn`3QCEr-DJc@E|$%p zY%dL!zkmOW6jHx_TVS`VLwRCJx&rbmiZkNpZGkX~`b71|j~`vh7ZTOV(qS&Cs@y4` zd#SdgAFhZ_eCm&A=3HG}?KEUmub33U5d; zrS$5&G5!%4b-Y+D{c}98xX?7b)l8!;#x3-SMbPmYW6Lgafk%AKjG+eB$!h%d+!+Z` z#BRtq7FWAKxm5&MKnUbFUhoE-JK)$Jln*gl!9p{sNaUkOJ3qT~6A}_87<0;4AO+0d z_7$*=j|F$Ytjd9Tty%fx-LcPT#j%Cf?t-u}9ifDOBj31vp?nbP;A@?mbetV7%}r?RK< zuS1fx5`TD!)SxBH)hE$YDf>50TZFN9r6cF{Cw7{ZfumNnWMDwdWGxXLk6&6(dz+*) z4LpkicnQEjk<@Tls_+DJB_vHav_*aVl(upCP%U$7M0WQ91ITBb znT_p!Jy8;jo$4@>bD32JD)i;*HV&qXkYNE9vX(^a-<+aoK?7Y0lhdHucod}7e%g# zmOg3{C$V$^s(l6&PC1~>x;=`6_r5Owf-rSQ0hMCBKV3&i6>{()Vs3Pz*e?-gmAMtU zC}v^4uPFMC=vh0wC*u@0OK+j#oVN#IyoXDEbknIsVzomT_~%J+b9&if3p2HZmK1Z`wlZ3uPzx1-c%N{_d!{mQNk(sb-F zD$kh}8em714;5P!8L88LgiHg=A%N&kxZgW5fduFazplt=6x9sq)Yt}bm-O?)FNIs( zAkI%7I@xEHJr$dMEOFsTX@6{)4pUM`N4=^{{S_I5bpDa(QPQB7eYn@!19zLnTx-HF7Og| zl#%Po5H<&LBUd0PG4c8`?v}d%j%GUBi3l{QyANwUGz=Nr1~w3w#%!SDk=sAMJZbYs zAcvPUCr99QtXV*LQQ0i2rQGo5biZ49^-w2U5M!08k~XBZp0XNp1Qm=Ou9Me4I^{RN zP=C>TN+C$9!^})xloh&&BfAxDT4lvORRtc=YRy#Nj=H)!CwHYqGP+n=$^PU4;3Yab zh&R0}IR6r!Uv7IpasJxDk(vh6qqwZCIN>lUi$SIX2txzdi-~+c=e}FdT=s{BFB5=j zVej~}xBNl0pl)}e2)3Rzz-S{f+5}jW0`;=3_M+>nQaoX9Gss&~{ zkPkKXyke4^mkRsDrfl$i4ECaIOZV9ft>QjvylF?9wrZgZP4&#=L=(#P>$j~|*5#B} z*v&{!V9KJbx?8i_3B`H}M|?GTf-}Fays-~^^S(?6L%#dv{)fv*c3eKa`sUocV}W1y zLwCGI`0!D$iL6elFh!@$XX!+>#!R7kPdO*?1$n7eVbwvzxiSMP-Dp31NB9n=@UELdzEj_s zy{5@|7xh(B+v5b>hsg!~k{a0!cQm_DVY}bV+H|U&Nc;O=t~rLtez-|Tr)&)*1ImfV z&Z^%1ZNQ`A&8POOpJw^hwNr(0eO`cBFyik5anRBM=BgjTX8E@>UNgQ~QblAggOk)p zE$V1^vc}e+yXHFTH;QAejoK`B4%v0SkZ+S?YsD967~I#Iqfo-b!!1=xhgG`}827AV zhBLT1X3XJh(km5zo+0zM>EE67%kvtPvVnx(wsqBPFWKT*fTE1o{!7I;ZrmWv~5UQDOj?%uZ{yQ{1(izq(x zX)QVTthkJ$TL*YDZZGe&nc zw5_~<`|b_LmCqzJ-Fkgb;w;kv-hujco7B|Qlun)VB-nr;i@9QNkkxX`wDK+At>exB zJpHlH$lSNNnLFcPWE>brWYdtOx?`I&yi|I+r8?|_Amxfu2nFb$=UjAh_V*DY6$MA!}p93mD& zFrVGSO8!AyTikx!sqP65H+63=Ue7% zWgeCxeva+-3&C2zwz-$rjT`i`l2Dm3a0BnK^S7K5P7t{oYaReK=*m&p%$85;?j91>!<4V=m_`0obkb_N zg4uWiqIy#0aH2~-(}85KVXP^)nc+S0qhgbSln^I@z`ehJDK;_9{Gt%gGe`H=p|_PL zcC1OQt*wePZh?Ux?4+=wV;k9A0G2Cn8vC^eIXS;YJttMjQ5fbG$j6^-KZRd4^%U-j zHBY>d?Ke&z^pWD3S$EVF*s?gfPa~Q&ZsKN;s=67cpkqGOj`O4IU?BjIgPkn^R?W4Z7U z2luRe5Ll-)$aDzoR|axhnUX6DcqcbUM@J31o^sdD&W^>!E?u>O za~M5v%Zk&jW^b-uXY90V=(-=Fy{kb_^qVfte-BAtb8_*ioI@AJ!k4)c%s0#8c5hui zniyy5+xR9d3^N9~B_;EzN;>ms65K1Pmv4Swi@P_zG2Rg4g6ehlbzK&%bw{~~>9mX7 zK5$C!L*5vAWwg$v8PJittHae|P|EX75YGp^;I3yf_#v!Ea@0_Frhrt9^l}cc!)z|! zMY}-PUdQb<9vHW_HWDTYn+J$-VqdYh#+;Q7?S|d0>${bAhI`%7@>&*7^k`BqW?Y8K znN^<9v6PcSQ-MzzWDx{zj%q%>-xQ~oq7i8)-fyr&FoTdU7srZM%vdY6}%iz9ywKZA|CSqHDpv~F^edlWQ6 z*WOMXegM7SDRT@YR)Nf=%AIRhB)A;y6SQaT9Ez`LIWgUYE^k`(7zDo7ii-WT+8P~r zsrcn>{)04h(k)xDrz4-w!lse_Kb>E8ZEC~#-SNmjs4trzblC+gIv(rVUw z*TFDr;hti|^!hF$xHfcRbvHu3Ejswo2PwHAk9Xd-B3PHa{t&%Uxnr0HE!KxwnjJElK%iVr4&~JpkBD7)|Hf;J`0#UeRN2tZcuI5kYDSrb z7P)6vAb%PW z=`Dq3RtJN5Q`}}qJdl3*sgq?`wn>3P`_z9*L! zGO`h&KSX#!s!sD9+-iL2{HRc>dB@#%mspT2 zo<}@?{u~N23Il#p=Lmo!J&9Q2R!|G`j>320UVxH%qU)h*(jjuK|v^*1S zE?BHWZWl;vT8$bfO(~f6O{WobQgL@vJvI8H^LuUh)agm;E6i>UUCb-w&JvzeQ;F4p z)s$0J4A1eo^P3<&JoxtKPKC8Mg+hsmiDBN%;I}=`uA)7;!^on~+1Ju%32CB6Py+*W z15%~uuyxBmrNo04O_iq&P4rAaY%Do%yhq2&tBgTLvPrF`1pi3tuS_Cs8r3v6K>aBC zeKuRlE5AD#5i#I=dHSeiICWo3V%%fFGtT(qiDfr=d!007`PI4dNLO(ET-F|H#~RiFn zzi)rNHR)Z&-WdE@T;7eFr@j9@ECG%&Z3)`9zYp=Ny2ns5yTo4tx?H|t0n?JujNhZBa=w>iRbCZ+qWEfzt)6%Hp z{k+-7AKz=5_;xKID>6jb%RY3K#iSRG&fwr`T#M~x`P4Q=Z59#b93DcwcJ|HZcZz%m@=cBq!zpDP0(?wrmF9I=CnAD< zr@T@yE61|b<9tg?vH*2uWra%J7QKXDZmnyp5}=`4Kr$8%hbxDa8Y=Dnl?Ft2VqyZ| zT-8NHhd``!J}enTf;B1KAf3TqoxD5a7y2+HR1lifCYPxaWPRIQo3Fp!2p!SJerW%S zq`BSmyrWV zXAg~xWJKjGb6lC}>mFiYg;5J~&sV0AC=qyf}1umTs;Xf6F^5 zme>31XB+2YLKGoNvHxImmf-s+#VA7m9l~(r2)>1XbGY9>KPCObH3%4*vNFii6#Jdl z`TWhhawLmFC2pTvd%fx&Eg?1ZJthBo)9OQjC_p^J-rhd_Zr;7C59i?O0;F>S`jmzM zQq%8nD#)>Aq(Mjk4u8n;?Sruv2BfN|vT&%ZvVK*h(F>ef>~7}@pT+}1ZJ-?d3;>>jb@!! z;%cYUHgSa$3m5B;_l4|fE!?q3Sv2lsNNDik;Msrao9|Ve5^KzTpvL%MH zichtYF(|Xr0riFws9%P_p|y36kl?Rj_mlF|g!NKg938)~4JhF^D3>=a){2#T;@rg` ztH_zjn3a#r%FO$0ad>&TQz9H8ZX7=NvnA8dv;AkUKrOB?HE8Y^I<|BC!_9Zd;*^RQ zj8kJ_yyAjD`*^5DcTbvfuWG@vw+4G_q?2}N7?yqIz0!M&zD={DkkKt_^7+tju+!h= z-H+ng9!%bK2_uE@o}-iN?h0eH8*0 zac!-`?vwR5Nlg9g!e*E!zh^Qp-lh+_UrRe_F!)r?FV}aNmZl&?4^Apt5ssQD#@=;H zwDK;FJzjhYm4jiZx$`9Xx@8gzJrnA3zN0R>1e^y^szX5`3{$ zTd?y5Pd3Onk>?M&(XjJU?Q$hk%ejD*H@lKUM?{QF(y6NnHjJZ>A5Nh!40$Fp*Lc{W zjz4G`H8~iCIp33nm}7!3w4*&l-S<9 z9~h??YRoOWOgVQ3xKD`&nBhprA&*)tHT@GcVkkk6AMRcDy_>4E z!kB{9Zj4pE+_sxtqzRAQ=tyHsL^Vw+44lqhKXumF8y~yccLt*GSzH$NNund&VEa$W ztwJ{pT)o}I56d`C^K%^x*(rOy6`u9ZRbS{2z9K6yCBhy_oQN))Kud_oNB;AfZG zTN1yE;4Au0Iv2|>ADt&1E8ucg==vuwk&=vMeUvK|!WlnYy)1Dbe z6Laq0_lKOQU*9fD+fu8!^Fn<1DkN}VU}cvA@gW&@8NPs`k(&yYs>-W%#5&K3pwgNh zZhz`{XxY1bz1!uzRUL7>vZ%XR)g|xCM0rQX?F||EM!wPl=YFR*5D-Dv-bWqZ>;0rl z=e4Bhm7Ef6A&1hTuYc9upE&%EO>g4m2SqL?o#%`+H@cMBE2{#C@lJHl?`Ou4b4Z+w zi|k2?5o4oB9m^~n8(@TWuC%S$NA~MnIi!_nEUB~dRWl?MS)?x3jMJ9~N%nNNOGwo6 z(LyhL2j#N2FYlntv9F&q5~3-DjbBg4BYO;#&6v$Qv(#G|IQ^`n(=(4Wl?<(jVvw3?$?faWZ_IH za`s{0sq;^pr& zG^h1=A68w&+9GiLW2}qycm3G)lbnNlKw-z8w_JPfi0*j--6M$kxBEBL{`fD~|Be2i z5BL7_`QZA$)1Tk}ALIXz>;Fa{ya+J=e_sE8&<8K>zx@Ai^ude&Jzp^1|6GWFw+|NX zzg+(}`hRQTLl6Idbm;$l)&EoG!5aQ|$nf8g(f=IpKV{_KmDzv&|KE_=f0g;aA;W(| zM*mgD|Ax%|$HG_M`8W*us}RH9n;p|B>oZg^#HTs*wXYs^HU3ESV?su!kIzcTrp%cX zr?PMQQ60{S0VGgBGW=I`Q6zs|T^&f0JNEd`hfd{?0_~ZvN2O=-KIbE{T&?>@Mi$ZQ z*g$?P6lC_0+S|`-guOHtRT?2-)U{_ol|${B!6oAYSvLm<2Xn)tmUOpNVGxy*+~etFrzZg8O%r z>wg-De=hvL3gW-p|36T!|0<~e+W#AZ`!@vjpBwEzU;Muc;=kMf`-1zwF2uj9vHpL) z@X~+$cL0R{2QvH5J@>Z(!v6yq{_m05f0gn7CK>*}R91hoZ<29^g z-8{iV7K$GZ{JEZ1c<|;uvGj-uwd#>?#_s1^K$aO`i0q^iVr8EVT=*=XnQR5JcFn}V z@qqLGi~}{YI_99L6kcryg9%8h{Ruk;5@bOgSy-5jxuvF%-B=*4u~924ALPu63-s^( z92!oL5&|91EWi+dbMt|&`8)rEy#baB6#52socMu45bonGKrK?lkcFa9MNyc(bp}Qy zKq&qVlfJ#)v+q&<2oZ@qqb&+WfBWEL?tHUm_{;LQZ{Gl~m!knnJ2zP7%*Dk8h8lC?!c@P(p0#7O%WGY)!GYW0ILOLdf6`?LVKu0N+WBoozN7@{ z`bXd>N%a|aPtLU`hLllIEH72RGo_Oo0REv$>HoF8-#dH+yz)M;<vv;(k}X5C-mNcTxl%{fPQq0_{6y7p}&vkyBJmcO3#}!C(^pz1_JLjxpbbbCl3 zlWCdz<{PWU+$d~Nud4}CwKX68ayZ`tYM!WJ&Dr;_F4iQq^2%SoejN~_pbnq&`0>r{ zZBUQ{K5Nj~-u`f0a&NpM%yG5#2_X+h#)8;<9SBVgm5XM!85$UjBH2t3id$UDkA0Pt z6-wy8sPX`OEcySJV!6D|Uqm@`X$TtLE z0w@Dzj1ig;W##RkxyhPagU$%uuHEDxGW;L?M1*J&2=Ez%n&9Py<>lj#1@%&G@N=b8 zX~NbcSN1THTd`>}%E~SJe^{?R>$n;p-{b_o<&fECe8$xpP{8o1#<-M}Q^?fSXAj{G zJ)t@`@B~o#wQt`(AnM?=4^|SpzUy`oH!aE|2a!^%CJyGx3F;KSBptj(Heknt7C Date: Sat, 31 Oct 2026 12:14:37 +0100 Subject: [PATCH 08/10] fix: show the whole app icon on the trackpad instead of a cropped one --- src/android/dex/classes.dex | Bin 23584 -> 24012 bytes .../java/app/polarbear/TrackpadControls.java | 16 ++++++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/android/dex/classes.dex b/src/android/dex/classes.dex index e468f1c247e2a542bd2127367e1713e46774b280..f55ebff7db6b7757afe1146bce1a8943dfa66caa 100644 GIT binary patch literal 24012 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 26 && icon instanceof AdaptiveIconDrawable) { + icon = ((AdaptiveIconDrawable) icon).getForeground(); + } + logo = icon; } @Override @@ -264,8 +270,14 @@ protected void onDraw(Canvas canvas) { paint.setColor(Color.BLACK); canvas.drawRect(left, top, left + size, top + size, paint); paint.setStyle(Paint.Style.STROKE); + canvas.save(); + Path corners = new Path(); + corners.addRoundRect(new RectF(left, top, left + size, top + size), + size * 0.22f, size * 0.22f, Path.Direction.CW); + canvas.clipPath(corners); logo.setBounds(left, top, left + size, top + size); logo.draw(canvas); + canvas.restore(); } } From 59947bcca4ba4694f2cd522f9dcfd60ff4254113 Mon Sep 17 00:00:00 2001 From: mister-teddy Date: Sat, 31 Oct 2026 12:16:02 +0100 Subject: [PATCH 09/10] docs: show the trackpad with the whole app icon --- docs/img/external-display-trackpad.png | Bin 17400 -> 12574 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/docs/img/external-display-trackpad.png b/docs/img/external-display-trackpad.png index f043ac09ce4cf63e9a348fb407cc11980fa0941e..defa6202c145ffcb8971cc88d5266f1613f0db34 100644 GIT binary patch literal 12574 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 Date: Sat, 31 Oct 2026 13:28:52 +0100 Subject: [PATCH 10/10] fix: keep the whole app icon inside the launcher's round mask --- patches/xbuild/xbuild/src/gradle/mod.rs | 19 ++++++++++-- patches/xbuild/xcommon/src/lib.rs | 21 ++++++++++++++ src/android/dex/classes.dex | Bin 24012 -> 23972 bytes .../java/app/polarbear/TrackpadControls.java | 27 ++++++++++-------- 4 files changed, 52 insertions(+), 15 deletions(-) diff --git a/patches/xbuild/xbuild/src/gradle/mod.rs b/patches/xbuild/xbuild/src/gradle/mod.rs index 5f8f76d..46179b5 100644 --- a/patches/xbuild/xbuild/src/gradle/mod.rs +++ b/patches/xbuild/xbuild/src/gradle/mod.rs @@ -252,7 +252,19 @@ pub fn build(env: &BuildEnv, libraries: Vec<(Target, PathBuf)>, out: &Path) -> R scaler.optimize(); let anydpi = res.join("mipmap-anydpi-v26"); std::fs::create_dir_all(&anydpi)?; - std::fs::write(anydpi.join("ic_launcher.xml"), IC_LAUNCHER)?; + // A monochrome layer is the icon's silhouette, which for an opaque icon is a square: + // themed icons then show the icon in its own colors instead. + let variants: &[&str] = if scaler.is_opaque() { + let xml = String::from_utf8_lossy(IC_LAUNCHER).replace( + " \n", + "", + ); + std::fs::write(anydpi.join("ic_launcher.xml"), xml)?; + &["foreground"] + } else { + std::fs::write(anydpi.join("ic_launcher.xml"), IC_LAUNCHER)?; + &["foreground", "monochrome"] + }; let dpis = [ ("m", 48), ("h", 72), @@ -270,10 +282,11 @@ pub fn build(env: &BuildEnv, libraries: Vec<(Target, PathBuf)>, out: &Path) -> R let mut icon = std::fs::File::create(dir.join("ic_launcher.png"))?; scaler.write(&mut icon, opts)?; } - for variant in ["foreground", "monochrome"] { + // Adaptive icon layers are 108 dp where the legacy icon is 48 dp. + for variant in variants { let mut icon = std::fs::File::create(dir.join(format!("ic_launcher_{}.png", variant)))?; - scaler.write(&mut icon, opts)?; + scaler.write_adaptive_layer(&mut icon, size * 108 / 48)?; } } manifest.application.icon = Some("@mipmap/ic_launcher".into()); diff --git a/patches/xbuild/xcommon/src/lib.rs b/patches/xbuild/xcommon/src/lib.rs index 61e7c0a..ad13b78 100644 --- a/patches/xbuild/xcommon/src/lib.rs +++ b/patches/xbuild/xcommon/src/lib.rs @@ -75,6 +75,27 @@ impl Scaler { Ok(()) } + /// Whether the icon has no transparent pixels (after `optimize`). + pub fn is_opaque(&self) -> bool { + !self.img.color().has_alpha() + } + + /// An adaptive icon layer, `size` px for its 108 dp, with the whole icon in the 72 dp that + /// launchers show. The icon's edge pixels continue to the layer's edges, so a full-bleed + /// icon shows no other color around it and a transparent one stays transparent. + pub fn write_adaptive_layer(&self, w: &mut W, size: u32) -> Result<()> { + let inner = size * 2 / 3; + let offset = (size - inner) / 2; + let resized = self + .img + .resize_exact(inner, inner, FilterType::Lanczos3) + .to_rgba8(); + let edge = |v: u32| v.saturating_sub(offset).min(inner - 1); + let layer = RgbaImage::from_fn(size, size, |x, y| *resized.get_pixel(edge(x), edge(y))); + layer.write_to(w, ImageOutputFormat::Png)?; + Ok(()) + } + pub fn to_vec(&self, opts: ScalerOpts) -> Vec { let mut buf = vec![]; let mut cursor = Cursor::new(&mut buf); diff --git a/src/android/dex/classes.dex b/src/android/dex/classes.dex index f55ebff7db6b7757afe1146bce1a8943dfa66caa..69d7252489b39f9dc38860b903ebe16b8f69dbfc 100644 GIT binary patch literal 23972 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 literal 24012 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 26 && icon instanceof AdaptiveIconDrawable) { - icon = ((AdaptiveIconDrawable) icon).getForeground(); + if (Build.VERSION.SDK_INT >= 33 && icon instanceof AdaptiveIconDrawable + && ((AdaptiveIconDrawable) icon).getMonochrome() != null) { + // The silhouette, in the pad's grey. + logo = ((AdaptiveIconDrawable) icon).getMonochrome().mutate(); + logo.setColorFilter(0xFF8A8A8A, PorterDuff.Mode.SRC_IN); + logoIsLayer = true; + } else { + // An icon without one (a full-bleed picture) as the launcher shows it. + logo = icon; + logoIsLayer = false; } - logo = icon; } @Override @@ -270,14 +278,9 @@ protected void onDraw(Canvas canvas) { paint.setColor(Color.BLACK); canvas.drawRect(left, top, left + size, top + size, paint); paint.setStyle(Paint.Style.STROKE); - canvas.save(); - Path corners = new Path(); - corners.addRoundRect(new RectF(left, top, left + size, top + size), - size * 0.22f, size * 0.22f, Path.Direction.CW); - canvas.clipPath(corners); - logo.setBounds(left, top, left + size, top + size); + int bleed = logoIsLayer ? size / 4 : 0; + logo.setBounds(left - bleed, top - bleed, left + size + bleed, top + size + bleed); logo.draw(canvas); - canvas.restore(); } }