From ea74f4784a338724138464ae3b0fb99bcfbd3ae2 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 15:02:02 -0400 Subject: [PATCH 01/29] init --- Cargo.lock | 22 ++++++++++++ Cargo.toml | 2 ++ crates/onboarding_ui/Cargo.toml | 35 +++++++++++++++++++ crates/onboarding_ui/src/onboarding_ui.rs | 41 +++++++++++++++++++++++ 4 files changed, 100 insertions(+) create mode 100644 crates/onboarding_ui/Cargo.toml create mode 100644 crates/onboarding_ui/src/onboarding_ui.rs diff --git a/Cargo.lock b/Cargo.lock index ef2f698d0a..5ad448cc14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10814,6 +10814,28 @@ dependencies = [ "workspace-hack", ] +[[package]] +name = "onboarding_ui" +version = "0.1.0" +dependencies = [ + "anyhow", + "client", + "command_palette_hooks", + "component", + "db", + "editor", + "feature_flags", + "gpui", + "settings", + "settings_ui", + "theme", + "ui", + "util", + "workspace", + "workspace-hack", + "zed_actions", +] + [[package]] name = "once_cell" version = "1.21.3" diff --git a/Cargo.toml b/Cargo.toml index 4239fcf1e9..bf4b539850 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -102,6 +102,7 @@ members = [ "crates/node_runtime", "crates/notifications", "crates/ollama", + "crates/onboarding_ui", "crates/open_ai", "crates/open_router", "crates/outline", @@ -314,6 +315,7 @@ multi_buffer = { path = "crates/multi_buffer" } node_runtime = { path = "crates/node_runtime" } notifications = { path = "crates/notifications" } ollama = { path = "crates/ollama" } +onboarding_ui = { path = "crates/onboarding_ui" } open_ai = { path = "crates/open_ai" } open_router = { path = "crates/open_router", features = ["schemars"] } outline = { path = "crates/outline" } diff --git a/crates/onboarding_ui/Cargo.toml b/crates/onboarding_ui/Cargo.toml new file mode 100644 index 0000000000..cdfaad21f6 --- /dev/null +++ b/crates/onboarding_ui/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "onboarding_ui" +version = "0.1.0" +edition.workspace = true +publish.workspace = true +license = "GPL-3.0-or-later" + +[lints] +workspace = true + +[lib] +path = "src/onboarding_ui.rs" + +[features] +test-support = [] + +[dependencies] +anyhow.workspace = true +client.workspace = true +command_palette_hooks.workspace = true +component.workspace = true +db.workspace = true +feature_flags.workspace = true +gpui.workspace = true +settings.workspace = true +settings_ui.workspace = true +theme.workspace = true +ui.workspace = true +util.workspace = true +workspace-hack.workspace = true +workspace.workspace = true +zed_actions.workspace = true + +[dev-dependencies] +editor = { workspace = true, features = ["test-support"] } diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs new file mode 100644 index 0000000000..6aae6d7093 --- /dev/null +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -0,0 +1,41 @@ +use command_palette_hooks::CommandPaletteFilter; +use feature_flags::FeatureFlagAppExt as _; +use gpui::App; +use settings_ui::SettingsUiFeatureFlag; +use workspace::Workspace; + +use gpui::actions; + +actions!(onboarding, [ShowOnboarding]); + +pub fn init(cx: &mut App) { + cx.observe_new(|workspace: &mut Workspace, _, _cx| { + workspace.register_action(|_workspace, _: &ShowOnboarding, _window, _cx| { + // Onboarding implementation will go here + }); + }) + .detach(); + + feature_gate_onboarding_ui_actions(cx); +} + +fn feature_gate_onboarding_ui_actions(cx: &mut App) { + const ONBOARDING_ACTION_NAMESPACE: &str = "onboarding"; + + CommandPaletteFilter::update_global(cx, |filter, _cx| { + filter.hide_namespace(ONBOARDING_ACTION_NAMESPACE); + }); + + cx.observe_flag::({ + move |is_enabled, cx| { + CommandPaletteFilter::update_global(cx, |filter, _cx| { + if is_enabled { + filter.show_namespace(ONBOARDING_ACTION_NAMESPACE); + } else { + filter.hide_namespace(ONBOARDING_ACTION_NAMESPACE); + } + }); + } + }) + .detach(); +} From 435dad71fb807244c3deaa56e4bacbde59f652de Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 15:14:40 -0400 Subject: [PATCH 02/29] Start scaffolding ui --- crates/onboarding_ui/src/onboarding_ui.rs | 309 +++++++++++++++++++++- 1 file changed, 305 insertions(+), 4 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 6aae6d7093..5f0b5b9345 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -1,17 +1,318 @@ +#![allow(unused, dead_code)] use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; -use gpui::App; +use gpui::{Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, actions, prelude::*}; use settings_ui::SettingsUiFeatureFlag; +use ui::prelude::*; use workspace::Workspace; -use gpui::actions; +actions!( + onboarding, + [ + ShowOnboarding, + JumpToBasics, + JumpToEditing, + JumpToAiSetup, + JumpToWelcome, + NextPage, + PreviousPage, + ToggleFocus, + ResetOnboarding, + ] +); -actions!(onboarding, [ShowOnboarding]); +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum OnboardingPage { + Basics, + Editing, + AiSetup, + Welcome, +} + +impl OnboardingPage { + fn next(&self) -> Option { + match self { + Self::Basics => Some(Self::Editing), + Self::Editing => Some(Self::AiSetup), + Self::AiSetup => Some(Self::Welcome), + Self::Welcome => None, + } + } + + fn previous(&self) -> Option { + match self { + Self::Basics => None, + Self::Editing => Some(Self::Basics), + Self::AiSetup => Some(Self::Editing), + Self::Welcome => Some(Self::AiSetup), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum OnboardingFocus { + Navigation, + Page, +} + +pub struct OnboardingUI { + focus_handle: FocusHandle, + current_page: OnboardingPage, + current_focus: OnboardingFocus, + completed_pages: [bool; 4], + basics_page: Entity, + editing_page: Entity, + ai_setup_page: Entity, + welcome_page: Entity, +} + +pub struct BasicsPage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +pub struct EditingPage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +pub struct AiSetupPage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +pub struct WelcomePage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +// Event types for communication between pages and main UI +#[derive(Clone)] +pub enum OnboardingEvent { + PageCompleted(OnboardingPage), +} + +// Implement EventEmitter for all entities +impl EventEmitter for OnboardingUI {} +impl EventEmitter for BasicsPage {} +impl EventEmitter for EditingPage {} +impl EventEmitter for AiSetupPage {} +impl EventEmitter for WelcomePage {} + +// Implement Focusable for all entities +impl Focusable for OnboardingUI { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Focusable for BasicsPage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Focusable for EditingPage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Focusable for AiSetupPage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Focusable for WelcomePage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +// Placeholder Render implementations +impl Render for OnboardingUI { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + h_flex() + .w(px(904.)) + .h(px(500.)) + .gap(px(48.)) + .child(v_flex().h_full().w(px(256.)).child("nav")) + } +} + +impl Render for BasicsPage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl Render for EditingPage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl Render for AiSetupPage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl Render for WelcomePage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl OnboardingUI { + pub fn new(cx: &mut Context) -> Self { + let parent_handle = cx.entity().downgrade(); + + let basics_page = cx.new(|cx| BasicsPage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + let editing_page = cx.new(|cx| EditingPage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + let ai_setup_page = cx.new(|cx| AiSetupPage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + let welcome_page = cx.new(|cx| WelcomePage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + Self { + focus_handle: cx.focus_handle(), + current_page: OnboardingPage::Basics, + current_focus: OnboardingFocus::Page, + completed_pages: [false; 4], + basics_page, + editing_page, + ai_setup_page, + welcome_page, + } + } + + fn jump_to_page( + &mut self, + page: OnboardingPage, + _window: &mut gpui::Window, + cx: &mut Context, + ) { + self.current_page = page; + cx.notify(); + } + + fn next_page(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + if let Some(next) = self.current_page.next() { + self.current_page = next; + cx.notify(); + } + } + + fn previous_page(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + if let Some(prev) = self.current_page.previous() { + self.current_page = prev; + cx.notify(); + } + } + + fn toggle_focus(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + self.current_focus = match self.current_focus { + OnboardingFocus::Navigation => OnboardingFocus::Page, + OnboardingFocus::Page => OnboardingFocus::Navigation, + }; + cx.notify(); + } + + fn reset(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + self.current_page = OnboardingPage::Basics; + self.current_focus = OnboardingFocus::Page; + self.completed_pages = [false; 4]; + cx.notify(); + } + + fn mark_page_completed( + &mut self, + page: OnboardingPage, + _window: &mut gpui::Window, + cx: &mut Context, + ) { + let index = match page { + OnboardingPage::Basics => 0, + OnboardingPage::Editing => 1, + OnboardingPage::AiSetup => 2, + OnboardingPage::Welcome => 3, + }; + self.completed_pages[index] = true; + cx.notify(); + } +} pub fn init(cx: &mut App) { cx.observe_new(|workspace: &mut Workspace, _, _cx| { workspace.register_action(|_workspace, _: &ShowOnboarding, _window, _cx| { - // Onboarding implementation will go here + // Show onboarding implementation will go here + }); + + workspace.register_action(|_workspace, _: &JumpToBasics, _window, _cx| { + // Jump to basics implementation + }); + + workspace.register_action(|_workspace, _: &JumpToEditing, _window, _cx| { + // Jump to editing implementation + }); + + workspace.register_action(|_workspace, _: &JumpToAiSetup, _window, _cx| { + // Jump to AI setup implementation + }); + + workspace.register_action(|_workspace, _: &JumpToWelcome, _window, _cx| { + // Jump to welcome implementation + }); + + workspace.register_action(|_workspace, _: &NextPage, _window, _cx| { + // Next page implementation + }); + + workspace.register_action(|_workspace, _: &PreviousPage, _window, _cx| { + // Previous page implementation + }); + + workspace.register_action(|_workspace, _: &ToggleFocus, _window, _cx| { + // Toggle focus implementation + }); + + workspace.register_action(|_workspace, _: &ResetOnboarding, _window, _cx| { + // Reset onboarding implementation }); }) .detach(); From 02f54e5958b2d079a1838bede7c5060c9717b94b Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 15:32:32 -0400 Subject: [PATCH 03/29] impl item --- Cargo.lock | 1 + crates/onboarding_ui/src/onboarding_ui.rs | 563 ++++++++++++---------- crates/zed/Cargo.toml | 6 +- crates/zed/src/main.rs | 1 + 4 files changed, 309 insertions(+), 262 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 5ad448cc14..371ab812a6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -20027,6 +20027,7 @@ dependencies = [ "nix 0.29.0", "node_runtime", "notifications", + "onboarding_ui", "outline", "outline_panel", "parking_lot", diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 5f0b5b9345..75a060da6a 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -4,7 +4,10 @@ use feature_flags::FeatureFlagAppExt as _; use gpui::{Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, actions, prelude::*}; use settings_ui::SettingsUiFeatureFlag; use ui::prelude::*; -use workspace::Workspace; +use workspace::{ + Workspace, WorkspaceId, + item::{Item, ItemEvent}, +}; actions!( onboarding, @@ -21,266 +24,11 @@ actions!( ] ); -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum OnboardingPage { - Basics, - Editing, - AiSetup, - Welcome, -} - -impl OnboardingPage { - fn next(&self) -> Option { - match self { - Self::Basics => Some(Self::Editing), - Self::Editing => Some(Self::AiSetup), - Self::AiSetup => Some(Self::Welcome), - Self::Welcome => None, - } - } - - fn previous(&self) -> Option { - match self { - Self::Basics => None, - Self::Editing => Some(Self::Basics), - Self::AiSetup => Some(Self::Editing), - Self::Welcome => Some(Self::AiSetup), - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum OnboardingFocus { - Navigation, - Page, -} - -pub struct OnboardingUI { - focus_handle: FocusHandle, - current_page: OnboardingPage, - current_focus: OnboardingFocus, - completed_pages: [bool; 4], - basics_page: Entity, - editing_page: Entity, - ai_setup_page: Entity, - welcome_page: Entity, -} - -pub struct BasicsPage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -pub struct EditingPage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -pub struct AiSetupPage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -pub struct WelcomePage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -// Event types for communication between pages and main UI -#[derive(Clone)] -pub enum OnboardingEvent { - PageCompleted(OnboardingPage), -} - -// Implement EventEmitter for all entities -impl EventEmitter for OnboardingUI {} -impl EventEmitter for BasicsPage {} -impl EventEmitter for EditingPage {} -impl EventEmitter for AiSetupPage {} -impl EventEmitter for WelcomePage {} - -// Implement Focusable for all entities -impl Focusable for OnboardingUI { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Focusable for BasicsPage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Focusable for EditingPage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Focusable for AiSetupPage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Focusable for WelcomePage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -// Placeholder Render implementations -impl Render for OnboardingUI { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - h_flex() - .w(px(904.)) - .h(px(500.)) - .gap(px(48.)) - .child(v_flex().h_full().w(px(256.)).child("nav")) - } -} - -impl Render for BasicsPage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() - } -} - -impl Render for EditingPage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() - } -} - -impl Render for AiSetupPage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() - } -} - -impl Render for WelcomePage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() - } -} - -impl OnboardingUI { - pub fn new(cx: &mut Context) -> Self { - let parent_handle = cx.entity().downgrade(); - - let basics_page = cx.new(|cx| BasicsPage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - - let editing_page = cx.new(|cx| EditingPage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - - let ai_setup_page = cx.new(|cx| AiSetupPage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - - let welcome_page = cx.new(|cx| WelcomePage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - - Self { - focus_handle: cx.focus_handle(), - current_page: OnboardingPage::Basics, - current_focus: OnboardingFocus::Page, - completed_pages: [false; 4], - basics_page, - editing_page, - ai_setup_page, - welcome_page, - } - } - - fn jump_to_page( - &mut self, - page: OnboardingPage, - _window: &mut gpui::Window, - cx: &mut Context, - ) { - self.current_page = page; - cx.notify(); - } - - fn next_page(&mut self, _window: &mut gpui::Window, cx: &mut Context) { - if let Some(next) = self.current_page.next() { - self.current_page = next; - cx.notify(); - } - } - - fn previous_page(&mut self, _window: &mut gpui::Window, cx: &mut Context) { - if let Some(prev) = self.current_page.previous() { - self.current_page = prev; - cx.notify(); - } - } - - fn toggle_focus(&mut self, _window: &mut gpui::Window, cx: &mut Context) { - self.current_focus = match self.current_focus { - OnboardingFocus::Navigation => OnboardingFocus::Page, - OnboardingFocus::Page => OnboardingFocus::Navigation, - }; - cx.notify(); - } - - fn reset(&mut self, _window: &mut gpui::Window, cx: &mut Context) { - self.current_page = OnboardingPage::Basics; - self.current_focus = OnboardingFocus::Page; - self.completed_pages = [false; 4]; - cx.notify(); - } - - fn mark_page_completed( - &mut self, - page: OnboardingPage, - _window: &mut gpui::Window, - cx: &mut Context, - ) { - let index = match page { - OnboardingPage::Basics => 0, - OnboardingPage::Editing => 1, - OnboardingPage::AiSetup => 2, - OnboardingPage::Welcome => 3, - }; - self.completed_pages[index] = true; - cx.notify(); - } -} - pub fn init(cx: &mut App) { cx.observe_new(|workspace: &mut Workspace, _, _cx| { - workspace.register_action(|_workspace, _: &ShowOnboarding, _window, _cx| { - // Show onboarding implementation will go here + workspace.register_action(|workspace, _: &ShowOnboarding, window, cx| { + let onboarding = cx.new(|cx| OnboardingUI::new(workspace, cx)); + workspace.add_item_to_active_pane(Box::new(onboarding), None, true, window, cx); }); workspace.register_action(|_workspace, _: &JumpToBasics, _window, _cx| { @@ -340,3 +88,300 @@ fn feature_gate_onboarding_ui_actions(cx: &mut App) { }) .detach(); } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum OnboardingPage { + Basics, + Editing, + AiSetup, + Welcome, +} + +impl OnboardingPage { + fn next(&self) -> Option { + match self { + Self::Basics => Some(Self::Editing), + Self::Editing => Some(Self::AiSetup), + Self::AiSetup => Some(Self::Welcome), + Self::Welcome => None, + } + } + + fn previous(&self) -> Option { + match self { + Self::Basics => None, + Self::Editing => Some(Self::Basics), + Self::AiSetup => Some(Self::Editing), + Self::Welcome => Some(Self::AiSetup), + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum OnboardingFocus { + Navigation, + Page, +} + +pub struct OnboardingUI { + focus_handle: FocusHandle, + current_page: OnboardingPage, + current_focus: OnboardingFocus, + completed_pages: [bool; 4], + + // Page entities + basics_page: Entity, + editing_page: Entity, + ai_setup_page: Entity, + welcome_page: Entity, + + // Workspace reference for Item trait + workspace: WeakEntity, +} + +impl EventEmitter for OnboardingUI {} + +impl Focusable for OnboardingUI { + fn focus_handle(&self, _: &App) -> gpui::FocusHandle { + self.focus_handle.clone() + } +} + +pub struct BasicsPage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +pub struct EditingPage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +pub struct AiSetupPage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +pub struct WelcomePage { + focus_handle: FocusHandle, + parent: WeakEntity, +} + +// Event types for communication between pages and main UI +#[derive(Clone)] +pub enum OnboardingEvent { + PageCompleted(OnboardingPage), +} + +// Implement EventEmitter for all entities +impl EventEmitter for BasicsPage {} +impl EventEmitter for EditingPage {} +impl EventEmitter for AiSetupPage {} +impl EventEmitter for WelcomePage {} + +impl Focusable for BasicsPage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Focusable for EditingPage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Focusable for AiSetupPage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +impl Focusable for WelcomePage { + fn focus_handle(&self, _cx: &App) -> FocusHandle { + self.focus_handle.clone() + } +} + +// Placeholder Render implementations +impl Render for OnboardingUI { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + h_flex() + .id("onboarding-ui") + .key_context("Onboarding") + .track_focus(&self.focus_handle) + .w(px(904.)) + .h(px(500.)) + .gap(px(48.)) + .child(v_flex().h_full().w(px(256.)).child("nav")) + } +} + +impl Render for BasicsPage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl Render for EditingPage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl Render for AiSetupPage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl Render for WelcomePage { + fn render( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + gpui::div() + } +} + +impl OnboardingUI { + pub fn new(workspace: &Workspace, cx: &mut Context) -> Self { + let parent_handle = cx.entity().downgrade(); + + let basics_page = cx.new(|cx| BasicsPage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + let editing_page = cx.new(|cx| EditingPage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + let ai_setup_page = cx.new(|cx| AiSetupPage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + let welcome_page = cx.new(|cx| WelcomePage { + focus_handle: cx.focus_handle(), + parent: parent_handle.clone(), + }); + + Self { + focus_handle: cx.focus_handle(), + current_page: OnboardingPage::Basics, + current_focus: OnboardingFocus::Page, + completed_pages: [false; 4], + basics_page, + editing_page, + ai_setup_page, + welcome_page, + workspace: workspace.weak_handle(), + } + } + + fn jump_to_page( + &mut self, + page: OnboardingPage, + _window: &mut gpui::Window, + cx: &mut Context, + ) { + self.current_page = page; + cx.notify(); + } + + fn next_page(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + if let Some(next) = self.current_page.next() { + self.current_page = next; + cx.notify(); + } + } + + fn previous_page(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + if let Some(prev) = self.current_page.previous() { + self.current_page = prev; + cx.notify(); + } + } + + fn toggle_focus(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + self.current_focus = match self.current_focus { + OnboardingFocus::Navigation => OnboardingFocus::Page, + OnboardingFocus::Page => OnboardingFocus::Navigation, + }; + cx.notify(); + } + + fn reset(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + self.current_page = OnboardingPage::Basics; + self.current_focus = OnboardingFocus::Page; + self.completed_pages = [false; 4]; + cx.notify(); + } + + fn mark_page_completed( + &mut self, + page: OnboardingPage, + _window: &mut gpui::Window, + cx: &mut Context, + ) { + let index = match page { + OnboardingPage::Basics => 0, + OnboardingPage::Editing => 1, + OnboardingPage::AiSetup => 2, + OnboardingPage::Welcome => 3, + }; + self.completed_pages[index] = true; + cx.notify(); + } +} + +impl Item for OnboardingUI { + type Event = ItemEvent; + + fn tab_content_text(&self, _detail: usize, _cx: &App) -> SharedString { + "Onboarding".into() + } + + fn to_item_events(event: &Self::Event, mut f: impl FnMut(ItemEvent)) { + f(event.clone()) + } + + fn show_toolbar(&self) -> bool { + false + } + + fn clone_on_split( + &self, + _workspace_id: Option, + window: &mut Window, + cx: &mut Context, + ) -> Option> { + let weak_workspace = self.workspace.clone(); + if let Some(workspace) = weak_workspace.upgrade() { + workspace.update(cx, |workspace, cx| { + Some(cx.new(|cx| OnboardingUI::new(workspace, cx))) + }) + } else { + None + } + } +} diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 4e426c3837..2b89e65c57 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -21,8 +21,8 @@ path = "src/main.rs" [dependencies] activity_indicator.workspace = true agent.workspace = true -agent_ui.workspace = true agent_settings.workspace = true +agent_ui.workspace = true anyhow.workspace = true askpass.workspace = true assets.workspace = true @@ -65,7 +65,6 @@ git_ui.workspace = true go_to_line.workspace = true gpui = { workspace = true, features = ["wayland", "x11", "font-kit"] } gpui_tokio.workspace = true - http_client.workspace = true image_viewer.workspace = true indoc.workspace = true @@ -85,13 +84,13 @@ libc.workspace = true log.workspace = true markdown.workspace = true markdown_preview.workspace = true -svg_preview.workspace = true menu.workspace = true migrator.workspace = true mimalloc = { version = "0.1", optional = true } nix = { workspace = true, features = ["pthread", "signal"] } node_runtime.workspace = true notifications.workspace = true +onboarding_ui.workspace = true outline.workspace = true outline_panel.workspace = true parking_lot.workspace = true @@ -120,6 +119,7 @@ smol.workspace = true snippet_provider.workspace = true snippets_ui.workspace = true supermaven.workspace = true +svg_preview.workspace = true sysinfo.workspace = true tab_switcher.workspace = true task.workspace = true diff --git a/crates/zed/src/main.rs b/crates/zed/src/main.rs index 00a1f150ea..9d6a497e99 100644 --- a/crates/zed/src/main.rs +++ b/crates/zed/src/main.rs @@ -580,6 +580,7 @@ pub fn main() { collab_ui::init(&app_state, cx); git_ui::init(cx); jj_ui::init(cx); + onboarding_ui::init(cx); feedback::init(cx); markdown_preview::init(cx); svg_preview::init(cx); From 4f52cece6900ea4929b305abb74edf6fa712c57d Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 15:37:43 -0400 Subject: [PATCH 04/29] Tidy & set up for pages --- crates/onboarding_ui/src/onboarding_ui.rs | 158 +++++----------------- 1 file changed, 32 insertions(+), 126 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 75a060da6a..ec01bd3ee7 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -129,12 +129,6 @@ pub struct OnboardingUI { current_focus: OnboardingFocus, completed_pages: [bool; 4], - // Page entities - basics_page: Entity, - editing_page: Entity, - ai_setup_page: Entity, - welcome_page: Entity, - // Workspace reference for Item trait workspace: WeakEntity, } @@ -147,68 +141,16 @@ impl Focusable for OnboardingUI { } } -pub struct BasicsPage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -pub struct EditingPage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -pub struct AiSetupPage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -pub struct WelcomePage { - focus_handle: FocusHandle, - parent: WeakEntity, -} - -// Event types for communication between pages and main UI #[derive(Clone)] pub enum OnboardingEvent { PageCompleted(OnboardingPage), } -// Implement EventEmitter for all entities -impl EventEmitter for BasicsPage {} -impl EventEmitter for EditingPage {} -impl EventEmitter for AiSetupPage {} -impl EventEmitter for WelcomePage {} - -impl Focusable for BasicsPage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Focusable for EditingPage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Focusable for AiSetupPage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -impl Focusable for WelcomePage { - fn focus_handle(&self, _cx: &App) -> FocusHandle { - self.focus_handle.clone() - } -} - -// Placeholder Render implementations impl Render for OnboardingUI { fn render( &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, + window: &mut gpui::Window, + cx: &mut Context, ) -> impl gpui::IntoElement { h_flex() .id("onboarding-ui") @@ -218,82 +160,17 @@ impl Render for OnboardingUI { .h(px(500.)) .gap(px(48.)) .child(v_flex().h_full().w(px(256.)).child("nav")) - } -} - -impl Render for BasicsPage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() - } -} - -impl Render for EditingPage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() - } -} - -impl Render for AiSetupPage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() - } -} - -impl Render for WelcomePage { - fn render( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> impl gpui::IntoElement { - gpui::div() + .child(self.render_active_page(window, cx)) } } impl OnboardingUI { pub fn new(workspace: &Workspace, cx: &mut Context) -> Self { - let parent_handle = cx.entity().downgrade(); - - let basics_page = cx.new(|cx| BasicsPage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - - let editing_page = cx.new(|cx| EditingPage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - - let ai_setup_page = cx.new(|cx| AiSetupPage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - - let welcome_page = cx.new(|cx| WelcomePage { - focus_handle: cx.focus_handle(), - parent: parent_handle.clone(), - }); - Self { focus_handle: cx.focus_handle(), current_page: OnboardingPage::Basics, current_focus: OnboardingFocus::Page, completed_pages: [false; 4], - basics_page, - editing_page, - ai_setup_page, - welcome_page, workspace: workspace.weak_handle(), } } @@ -352,6 +229,35 @@ impl OnboardingUI { self.completed_pages[index] = true; cx.notify(); } + + fn render_active_page( + &mut self, + _window: &mut gpui::Window, + _cx: &mut Context, + ) -> impl gpui::IntoElement { + match self.current_page { + OnboardingPage::Basics => self.render_basics_page(), + OnboardingPage::Editing => self.render_editing_page(), + OnboardingPage::AiSetup => self.render_ai_setup_page(), + OnboardingPage::Welcome => self.render_welcome_page(), + } + } + + fn render_basics_page(&self) -> impl gpui::IntoElement { + v_flex().h_full().w_full().child("Basics Page") + } + + fn render_editing_page(&self) -> impl gpui::IntoElement { + v_flex().h_full().w_full().child("Editing Page") + } + + fn render_ai_setup_page(&self) -> impl gpui::IntoElement { + v_flex().h_full().w_full().child("AI Setup Page") + } + + fn render_welcome_page(&self) -> impl gpui::IntoElement { + v_flex().h_full().w_full().child("Welcome Page") + } } impl Item for OnboardingUI { From 3dfaac0b4d6913cff0f9b2204b1b84b1469eca6b Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 16:51:20 -0400 Subject: [PATCH 05/29] More UI --- crates/onboarding_ui/src/onboarding_ui.rs | 270 +++++++++++++++++----- 1 file changed, 216 insertions(+), 54 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index ec01bd3ee7..17c6851b15 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -1,12 +1,16 @@ #![allow(unused, dead_code)] +use client::Client; use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; use gpui::{Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, actions, prelude::*}; use settings_ui::SettingsUiFeatureFlag; -use ui::prelude::*; +use std::sync::Arc; +use ui::{KeyBinding, ListItem, Vector, VectorName, prelude::*}; +use util::ResultExt; use workspace::{ Workspace, WorkspaceId, item::{Item, ItemEvent}, + notifications::NotifyResultExt, }; actions!( @@ -27,41 +31,10 @@ actions!( pub fn init(cx: &mut App) { cx.observe_new(|workspace: &mut Workspace, _, _cx| { workspace.register_action(|workspace, _: &ShowOnboarding, window, cx| { - let onboarding = cx.new(|cx| OnboardingUI::new(workspace, cx)); + let client = workspace.client().clone(); + let onboarding = cx.new(|cx| OnboardingUI::new(workspace, client, cx)); workspace.add_item_to_active_pane(Box::new(onboarding), None, true, window, cx); }); - - workspace.register_action(|_workspace, _: &JumpToBasics, _window, _cx| { - // Jump to basics implementation - }); - - workspace.register_action(|_workspace, _: &JumpToEditing, _window, _cx| { - // Jump to editing implementation - }); - - workspace.register_action(|_workspace, _: &JumpToAiSetup, _window, _cx| { - // Jump to AI setup implementation - }); - - workspace.register_action(|_workspace, _: &JumpToWelcome, _window, _cx| { - // Jump to welcome implementation - }); - - workspace.register_action(|_workspace, _: &NextPage, _window, _cx| { - // Next page implementation - }); - - workspace.register_action(|_workspace, _: &PreviousPage, _window, _cx| { - // Previous page implementation - }); - - workspace.register_action(|_workspace, _: &ToggleFocus, _window, _cx| { - // Toggle focus implementation - }); - - workspace.register_action(|_workspace, _: &ResetOnboarding, _window, _cx| { - // Reset onboarding implementation - }); }) .detach(); @@ -131,6 +104,7 @@ pub struct OnboardingUI { // Workspace reference for Item trait workspace: WeakEntity, + client: Arc, } impl EventEmitter for OnboardingUI {} @@ -152,26 +126,47 @@ impl Render for OnboardingUI { window: &mut gpui::Window, cx: &mut Context, ) -> impl gpui::IntoElement { - h_flex() - .id("onboarding-ui") - .key_context("Onboarding") - .track_focus(&self.focus_handle) - .w(px(904.)) - .h(px(500.)) - .gap(px(48.)) - .child(v_flex().h_full().w(px(256.)).child("nav")) - .child(self.render_active_page(window, cx)) + div() + .bg(cx.theme().colors().editor_background) + .size_full() + .flex() + .items_center() + .justify_center() + .overflow_hidden() + .child( + h_flex() + .id("onboarding-ui") + .key_context("Onboarding") + .track_focus(&self.focus_handle) + .on_action(cx.listener(Self::handle_jump_to_basics)) + .on_action(cx.listener(Self::handle_jump_to_editing)) + .on_action(cx.listener(Self::handle_jump_to_ai_setup)) + .on_action(cx.listener(Self::handle_jump_to_welcome)) + .on_action(cx.listener(Self::handle_next_page)) + .on_action(cx.listener(Self::handle_previous_page)) + .w(px(904.)) + .h(px(500.)) + .gap(px(48.)) + .child(self.render_navigation(window, cx)) + .child( + v_flex() + .h_full() + .flex_1() + .child(div().flex_1().child(self.render_active_page(window, cx))), + ), + ) } } impl OnboardingUI { - pub fn new(workspace: &Workspace, cx: &mut Context) -> Self { + pub fn new(workspace: &Workspace, client: Arc, cx: &mut Context) -> Self { Self { focus_handle: cx.focus_handle(), current_page: OnboardingPage::Basics, current_focus: OnboardingFocus::Page, completed_pages: [false; 4], workspace: workspace.weak_handle(), + client, } } @@ -182,6 +177,7 @@ impl OnboardingUI { cx: &mut Context, ) { self.current_page = page; + cx.emit(ItemEvent::UpdateTab); cx.notify(); } @@ -230,11 +226,142 @@ impl OnboardingUI { cx.notify(); } + fn handle_jump_to_basics( + &mut self, + _: &JumpToBasics, + window: &mut Window, + cx: &mut Context, + ) { + self.jump_to_page(OnboardingPage::Basics, window, cx); + } + + fn handle_jump_to_editing( + &mut self, + _: &JumpToEditing, + window: &mut Window, + cx: &mut Context, + ) { + self.jump_to_page(OnboardingPage::Editing, window, cx); + } + + fn handle_jump_to_ai_setup( + &mut self, + _: &JumpToAiSetup, + window: &mut Window, + cx: &mut Context, + ) { + self.jump_to_page(OnboardingPage::AiSetup, window, cx); + } + + fn handle_jump_to_welcome( + &mut self, + _: &JumpToWelcome, + window: &mut Window, + cx: &mut Context, + ) { + self.jump_to_page(OnboardingPage::Welcome, window, cx); + } + + fn handle_next_page(&mut self, _: &NextPage, window: &mut Window, cx: &mut Context) { + self.next_page(window, cx); + } + + fn handle_previous_page( + &mut self, + _: &PreviousPage, + window: &mut Window, + cx: &mut Context, + ) { + self.previous_page(window, cx); + } + + fn render_navigation( + &mut self, + window: &mut Window, + cx: &mut Context, + ) -> impl gpui::IntoElement { + v_flex() + .h_full() + .w(px(256.)) + .gap_2() + .justify_between() + .child( + v_flex() + .w_full() + .gap_px() + .child( + h_flex() + .w_full() + .justify_between() + .child(Vector::new(VectorName::ZedLogo, rems(2.), rems(2.))) + .child(self.render_sign_in_button(cx)), + ) + .child(self.render_nav_item(OnboardingPage::Basics, "The Basics", "1", cx)) + .child(self.render_nav_item( + OnboardingPage::Editing, + "Editing Experience", + "2", + cx, + )) + .child(self.render_nav_item(OnboardingPage::AiSetup, "AI Setup", "3", cx)) + .child(self.render_nav_item(OnboardingPage::Welcome, "Welcome", "4", cx)), + ) + .child(self.render_bottom_controls(window, cx)) + } + + fn render_nav_item( + &mut self, + page: OnboardingPage, + label: impl Into, + shortcut: impl Into, + cx: &mut Context, + ) -> impl gpui::IntoElement { + let selected = self.current_page == page; + let label = label.into(); + let shortcut = shortcut.into(); + + ListItem::new(label.clone()) + .child( + h_flex() + .w_full() + .justify_between() + .child(Label::new(label.clone())) + .child(Label::new(format!("⌘{}", shortcut.clone())).color(Color::Muted)), + ) + .selectable(true) + .toggle_state(selected) + .on_click(cx.listener(move |this, _, window, cx| { + this.jump_to_page(page, window, cx); + })) + } + + fn render_bottom_controls( + &mut self, + window: &mut gpui::Window, + cx: &mut Context, + ) -> impl gpui::IntoElement { + h_flex().w_full().p_4().child( + Button::new( + "next", + if self.current_page == OnboardingPage::Welcome { + "Get Started" + } else { + "Next" + }, + ) + .style(ButtonStyle::Filled) + .key_binding(KeyBinding::for_action(&NextPage, window, cx)) + .on_click(cx.listener(|this, _, window, cx| { + this.next_page(window, cx); + })), + ) + } + fn render_active_page( &mut self, _window: &mut gpui::Window, _cx: &mut Context, - ) -> impl gpui::IntoElement { + ) -> AnyElement { match self.current_page { OnboardingPage::Basics => self.render_basics_page(), OnboardingPage::Editing => self.render_editing_page(), @@ -243,20 +370,54 @@ impl OnboardingUI { } } - fn render_basics_page(&self) -> impl gpui::IntoElement { - v_flex().h_full().w_full().child("Basics Page") + fn render_basics_page(&self) -> AnyElement { + v_flex() + .h_full() + .w_full() + .child("Basics Page") + .into_any_element() } - fn render_editing_page(&self) -> impl gpui::IntoElement { - v_flex().h_full().w_full().child("Editing Page") + fn render_editing_page(&self) -> AnyElement { + v_flex() + .h_full() + .w_full() + .child("Editing Page") + .into_any_element() } - fn render_ai_setup_page(&self) -> impl gpui::IntoElement { - v_flex().h_full().w_full().child("AI Setup Page") + fn render_ai_setup_page(&self) -> AnyElement { + v_flex() + .h_full() + .w_full() + .child("AI Setup Page") + .into_any_element() } - fn render_welcome_page(&self) -> impl gpui::IntoElement { - v_flex().h_full().w_full().child("Welcome Page") + fn render_welcome_page(&self) -> AnyElement { + v_flex() + .h_full() + .w_full() + .child("Welcome Page") + .into_any_element() + } + + fn render_sign_in_button(&mut self, cx: &mut Context) -> impl IntoElement { + let client = self.client.clone(); + Button::new("sign_in", "Sign in") + .label_size(LabelSize::Small) + .on_click(cx.listener(move |_, _, window, cx| { + let client = client.clone(); + window + .spawn(cx, async move |cx| { + client + .authenticate_and_connect(true, &cx) + .await + .into_response() + .notify_async_err(cx); + }) + .detach(); + })) } } @@ -282,9 +443,10 @@ impl Item for OnboardingUI { cx: &mut Context, ) -> Option> { let weak_workspace = self.workspace.clone(); + let client = self.client.clone(); if let Some(workspace) = weak_workspace.upgrade() { workspace.update(cx, |workspace, cx| { - Some(cx.new(|cx| OnboardingUI::new(workspace, cx))) + Some(cx.new(|cx| OnboardingUI::new(workspace, client, cx))) }) } else { None From 63dc4925f685741d2d083b233519f8510d126c08 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 18:00:50 -0400 Subject: [PATCH 06/29] Onboarding serializaion --- Cargo.lock | 1 + crates/onboarding_ui/Cargo.toml | 1 + crates/onboarding_ui/src/onboarding_ui.rs | 135 +++++++++++++++++++++- crates/onboarding_ui/src/persistence.rs | 53 +++++++++ 4 files changed, 186 insertions(+), 4 deletions(-) create mode 100644 crates/onboarding_ui/src/persistence.rs diff --git a/Cargo.lock b/Cargo.lock index 371ab812a6..e91833f996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10826,6 +10826,7 @@ dependencies = [ "editor", "feature_flags", "gpui", + "project", "settings", "settings_ui", "theme", diff --git a/crates/onboarding_ui/Cargo.toml b/crates/onboarding_ui/Cargo.toml index cdfaad21f6..b1591e9167 100644 --- a/crates/onboarding_ui/Cargo.toml +++ b/crates/onboarding_ui/Cargo.toml @@ -22,6 +22,7 @@ component.workspace = true db.workspace = true feature_flags.workspace = true gpui.workspace = true +project.workspace = true settings.workspace = true settings_ui.workspace = true theme.workspace = true diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 17c6851b15..3a5853edfb 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -1,15 +1,22 @@ #![allow(unused, dead_code)] +mod persistence; + use client::Client; use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; -use gpui::{Entity, EventEmitter, FocusHandle, Focusable, WeakEntity, actions, prelude::*}; +use gpui::{ + Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, WeakEntity, actions, prelude::*, +}; +use persistence::ONBOARDING_DB; + +use project::Project; use settings_ui::SettingsUiFeatureFlag; use std::sync::Arc; -use ui::{KeyBinding, ListItem, Vector, VectorName, prelude::*}; +use ui::{ListItem, Vector, VectorName, prelude::*}; use util::ResultExt; use workspace::{ Workspace, WorkspaceId, - item::{Item, ItemEvent}, + item::{Item, ItemEvent, SerializableItem}, notifications::NotifyResultExt, }; @@ -38,6 +45,8 @@ pub fn init(cx: &mut App) { }) .detach(); + workspace::register_serializable_item::(cx); + feature_gate_onboarding_ui_actions(cx); } @@ -104,6 +113,7 @@ pub struct OnboardingUI { // Workspace reference for Item trait workspace: WeakEntity, + workspace_id: Option, client: Arc, } @@ -166,10 +176,26 @@ impl OnboardingUI { current_focus: OnboardingFocus::Page, completed_pages: [false; 4], workspace: workspace.weak_handle(), + workspace_id: workspace.database_id(), client, } } + fn completed_pages_to_string(&self) -> String { + self.completed_pages + .iter() + .map(|&completed| if completed { '1' } else { '0' }) + .collect() + } + + fn completed_pages_from_string(s: &str) -> [bool; 4] { + let mut result = [false; 4]; + for (i, ch) in s.chars().take(4).enumerate() { + result[i] = ch == '1'; + } + result + } + fn jump_to_page( &mut self, page: OnboardingPage, @@ -350,7 +376,12 @@ impl OnboardingUI { }, ) .style(ButtonStyle::Filled) - .key_binding(KeyBinding::for_action(&NextPage, window, cx)) + .key_binding(ui::KeyBinding::for_action_in( + &NextPage, + &self.focus_handle, + window, + cx, + )) .on_click(cx.listener(|this, _, window, cx| { this.next_page(window, cx); })), @@ -432,6 +463,15 @@ impl Item for OnboardingUI { f(event.clone()) } + fn added_to_workspace( + &mut self, + workspace: &mut Workspace, + _window: &mut Window, + _cx: &mut Context, + ) { + self.workspace_id = workspace.database_id(); + } + fn show_toolbar(&self) -> bool { false } @@ -453,3 +493,90 @@ impl Item for OnboardingUI { } } } + +impl SerializableItem for OnboardingUI { + fn serialized_item_kind() -> &'static str { + "OnboardingUI" + } + + fn deserialize( + _project: Entity, + workspace: WeakEntity, + workspace_id: WorkspaceId, + item_id: u64, + window: &mut Window, + cx: &mut App, + ) -> Task>> { + window.spawn(cx, async move |cx| { + let (current_page, completed_pages) = if let Some((page_str, completed_str)) = + ONBOARDING_DB.get_state(item_id, workspace_id)? + { + let page = match page_str.as_str() { + "basics" => OnboardingPage::Basics, + "editing" => OnboardingPage::Editing, + "ai_setup" => OnboardingPage::AiSetup, + "welcome" => OnboardingPage::Welcome, + _ => OnboardingPage::Basics, + }; + let completed = OnboardingUI::completed_pages_from_string(&completed_str); + (page, completed) + } else { + (OnboardingPage::Basics, [false; 4]) + }; + + cx.update(|window, cx| { + let workspace = workspace + .upgrade() + .ok_or_else(|| anyhow::anyhow!("workspace dropped"))?; + + workspace.update(cx, |workspace, cx| { + let client = workspace.client().clone(); + Ok(cx.new(|cx| { + let mut onboarding = OnboardingUI::new(workspace, client, cx); + onboarding.current_page = current_page; + onboarding.completed_pages = completed_pages; + onboarding + })) + }) + })? + }) + } + + fn serialize( + &mut self, + _workspace: &mut Workspace, + item_id: u64, + _closing: bool, + _window: &mut Window, + cx: &mut Context, + ) -> Option>> { + let workspace_id = self.workspace_id?; + let current_page = match self.current_page { + OnboardingPage::Basics => "basics", + OnboardingPage::Editing => "editing", + OnboardingPage::AiSetup => "ai_setup", + OnboardingPage::Welcome => "welcome", + } + .to_string(); + let completed_pages = self.completed_pages_to_string(); + + Some(cx.background_spawn(async move { + ONBOARDING_DB + .save_state(item_id, workspace_id, current_page, completed_pages) + .await + })) + } + + fn cleanup( + _workspace_id: WorkspaceId, + _item_ids: Vec, + _window: &mut Window, + _cx: &mut App, + ) -> Task> { + Task::ready(Ok(())) + } + + fn should_serialize(&self, _event: &ItemEvent) -> bool { + true + } +} diff --git a/crates/onboarding_ui/src/persistence.rs b/crates/onboarding_ui/src/persistence.rs new file mode 100644 index 0000000000..944d5c58ae --- /dev/null +++ b/crates/onboarding_ui/src/persistence.rs @@ -0,0 +1,53 @@ +use anyhow::Result; +use db::{define_connection, query, sqlez::statement::Statement, sqlez_macros::sql}; + +use workspace::{WorkspaceDb, WorkspaceId}; + +define_connection! { + pub static ref ONBOARDING_DB: OnboardingDb = + &[sql!( + CREATE TABLE onboarding_state ( + workspace_id INTEGER, + item_id INTEGER UNIQUE, + current_page TEXT, + completed_pages TEXT, + PRIMARY KEY(workspace_id, item_id), + FOREIGN KEY(workspace_id) REFERENCES workspaces(workspace_id) + ON DELETE CASCADE + ) STRICT; + )]; +} + +impl OnboardingDb { + pub async fn save_state( + &self, + item_id: u64, + workspace_id: WorkspaceId, + current_page: String, + completed_pages: String, + ) -> Result<()> { + let query = + "INSERT INTO onboarding_state(item_id, workspace_id, current_page, completed_pages) + VALUES (?1, ?2, ?3, ?4) + ON CONFLICT DO UPDATE SET + current_page = ?3, + completed_pages = ?4"; + self.write(move |conn| { + let mut statement = Statement::prepare(conn, query)?; + let mut next_index = statement.bind(&item_id, 1)?; + next_index = statement.bind(&workspace_id, next_index)?; + next_index = statement.bind(¤t_page, next_index)?; + statement.bind(&completed_pages, next_index)?; + statement.exec() + }) + .await + } + + query! { + pub fn get_state(item_id: u64, workspace_id: WorkspaceId) -> Result> { + SELECT current_page, completed_pages + FROM onboarding_state + WHERE item_id = ? AND workspace_id = ? + } + } +} From db575d8a0400874cacb460bc0721d560a4672c7a Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 19:43:00 -0400 Subject: [PATCH 07/29] Style nav items --- crates/onboarding_ui/src/onboarding_ui.rs | 98 +++++++++++++++-------- 1 file changed, 65 insertions(+), 33 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 3a5853edfb..8ae2c4fe65 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -306,6 +306,8 @@ impl OnboardingUI { window: &mut Window, cx: &mut Context, ) -> impl gpui::IntoElement { + let client = self.client.clone(); + v_flex() .h_full() .w(px(256.)) @@ -319,18 +321,56 @@ impl OnboardingUI { h_flex() .w_full() .justify_between() + .py(px(24.)) + .pl(px(24.)) + .pr(px(12.)) .child(Vector::new(VectorName::ZedLogo, rems(2.), rems(2.))) - .child(self.render_sign_in_button(cx)), + .child( + Button::new("sign_in", "Sign in") + .label_size(LabelSize::Small) + .on_click(cx.listener(move |_, _, window, cx| { + let client = client.clone(); + window + .spawn(cx, async move |cx| { + client + .authenticate_and_connect(true, &cx) + .await + .into_response() + .notify_async_err(cx); + }) + .detach(); + })), + ), ) - .child(self.render_nav_item(OnboardingPage::Basics, "The Basics", "1", cx)) - .child(self.render_nav_item( - OnboardingPage::Editing, - "Editing Experience", - "2", - cx, - )) - .child(self.render_nav_item(OnboardingPage::AiSetup, "AI Setup", "3", cx)) - .child(self.render_nav_item(OnboardingPage::Welcome, "Welcome", "4", cx)), + .child( + v_flex() + .gap_px() + .py(px(16.)) + .child(self.render_nav_item( + OnboardingPage::Basics, + "The Basics", + "1", + cx, + )) + .child(self.render_nav_item( + OnboardingPage::Editing, + "Editing Experience", + "2", + cx, + )) + .child(self.render_nav_item( + OnboardingPage::AiSetup, + "AI Setup", + "3", + cx, + )) + .child(self.render_nav_item( + OnboardingPage::Welcome, + "Welcome", + "4", + cx, + )), + ), ) .child(self.render_bottom_controls(window, cx)) } @@ -345,17 +385,27 @@ impl OnboardingUI { let selected = self.current_page == page; let label = label.into(); let shortcut = shortcut.into(); + let id = ElementId::Name(label.clone()); - ListItem::new(label.clone()) + h_flex() + .id(id) + .h(rems(1.5)) + .w_full() + .child( + div() + .w(px(3.)) + .h_full() + .when(selected, |this| this.bg(cx.theme().status().info)), + ) .child( h_flex() - .w_full() + .pl(px(23.)) + .flex_1() .justify_between() - .child(Label::new(label.clone())) + .items_center() + .child(Label::new(label)) .child(Label::new(format!("⌘{}", shortcut.clone())).color(Color::Muted)), ) - .selectable(true) - .toggle_state(selected) .on_click(cx.listener(move |this, _, window, cx| { this.jump_to_page(page, window, cx); })) @@ -432,24 +482,6 @@ impl OnboardingUI { .child("Welcome Page") .into_any_element() } - - fn render_sign_in_button(&mut self, cx: &mut Context) -> impl IntoElement { - let client = self.client.clone(); - Button::new("sign_in", "Sign in") - .label_size(LabelSize::Small) - .on_click(cx.listener(move |_, _, window, cx| { - let client = client.clone(); - window - .spawn(cx, async move |cx| { - client - .authenticate_and_connect(true, &cx) - .await - .into_response() - .notify_async_err(cx); - }) - .detach(); - })) - } } impl Item for OnboardingUI { From db52799129ce3845b215a3610356b90a5a06154b Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 20:17:45 -0400 Subject: [PATCH 08/29] wip --- crates/onboarding_ui/src/onboarding_ui.rs | 28 +++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 8ae2c4fe65..7b12df0444 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -100,15 +100,23 @@ impl OnboardingPage { } #[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum OnboardingFocus { - Navigation, - Page, +pub enum NavigationFocusItem { + SignIn, + Basics, + Editing, + AiSetup, + Welcome, + Next, } +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct PageFocusItem(pub usize); + pub struct OnboardingUI { focus_handle: FocusHandle, current_page: OnboardingPage, - current_focus: OnboardingFocus, + nav_focus: NavigationFocusItem, + page_focus: [PageFocusItem; 4], completed_pages: [bool; 4], // Workspace reference for Item trait @@ -173,7 +181,7 @@ impl OnboardingUI { Self { focus_handle: cx.focus_handle(), current_page: OnboardingPage::Basics, - current_focus: OnboardingFocus::Page, + current_focus: OnboardingFocus::default(), completed_pages: [false; 4], workspace: workspace.weak_handle(), workspace_id: workspace.database_id(), @@ -324,10 +332,15 @@ impl OnboardingUI { .py(px(24.)) .pl(px(24.)) .pr(px(12.)) - .child(Vector::new(VectorName::ZedLogo, rems(2.), rems(2.))) + .child( + Vector::new(VectorName::ZedLogo, rems(2.), rems(2.)) + .color(Color::Custom(cx.theme().colors().icon.opacity(0.5))), + ) .child( Button::new("sign_in", "Sign in") + .color(Color::Muted) .label_size(LabelSize::Small) + .size(ButtonSize::Compact) .on_click(cx.listener(move |_, _, window, cx| { let client = client.clone(); window @@ -346,6 +359,7 @@ impl OnboardingUI { v_flex() .gap_px() .py(px(16.)) + .gap(px(12.)) .child(self.render_nav_item( OnboardingPage::Basics, "The Basics", @@ -416,7 +430,7 @@ impl OnboardingUI { window: &mut gpui::Window, cx: &mut Context, ) -> impl gpui::IntoElement { - h_flex().w_full().p_4().child( + h_flex().w_full().p(px(12.)).pl(px(24.)).child( Button::new( "next", if self.current_page == OnboardingPage::Welcome { From f6407fdff1710ee67a816fd54ccb0bb730ab3bf1 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 21:08:51 -0400 Subject: [PATCH 09/29] Start on keyboard navigation story --- Cargo.lock | 1 + crates/onboarding_ui/Cargo.toml | 1 + crates/onboarding_ui/src/onboarding_ui.rs | 478 ++++++++++++++++++++-- 3 files changed, 443 insertions(+), 37 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e91833f996..eab5741d25 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10826,6 +10826,7 @@ dependencies = [ "editor", "feature_flags", "gpui", + "menu", "project", "settings", "settings_ui", diff --git a/crates/onboarding_ui/Cargo.toml b/crates/onboarding_ui/Cargo.toml index b1591e9167..2476643033 100644 --- a/crates/onboarding_ui/Cargo.toml +++ b/crates/onboarding_ui/Cargo.toml @@ -22,6 +22,7 @@ component.workspace = true db.workspace = true feature_flags.workspace = true gpui.workspace = true +menu.workspace = true project.workspace = true settings.workspace = true settings_ui.workspace = true diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 7b12df0444..accd01eb73 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -7,6 +7,7 @@ use feature_flags::FeatureFlagAppExt as _; use gpui::{ Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, WeakEntity, actions, prelude::*, }; +use menu; use persistence::ONBOARDING_DB; use project::Project; @@ -51,7 +52,7 @@ pub fn init(cx: &mut App) { } fn feature_gate_onboarding_ui_actions(cx: &mut App) { - const ONBOARDING_ACTION_NAMESPACE: &str = "onboarding"; + const ONBOARDING_ACTION_NAMESPACE: &str = "onboarding_ui"; CommandPaletteFilter::update_global(cx, |filter, _cx| { filter.hide_namespace(ONBOARDING_ACTION_NAMESPACE); @@ -112,12 +113,19 @@ pub enum NavigationFocusItem { #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub struct PageFocusItem(pub usize); +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum FocusArea { + Navigation, + PageContent, +} + pub struct OnboardingUI { focus_handle: FocusHandle, current_page: OnboardingPage, nav_focus: NavigationFocusItem, page_focus: [PageFocusItem; 4], completed_pages: [bool; 4], + focus_area: FocusArea, // Workspace reference for Item trait workspace: WeakEntity, @@ -147,6 +155,12 @@ impl Render for OnboardingUI { div() .bg(cx.theme().colors().editor_background) .size_full() + .key_context("OnboardingUI") + .on_action(cx.listener(Self::select_next)) + .on_action(cx.listener(Self::select_previous)) + .on_action(cx.listener(Self::confirm)) + .on_action(cx.listener(Self::cancel)) + .on_action(cx.listener(Self::toggle_focus)) .flex() .items_center() .justify_center() @@ -163,14 +177,27 @@ impl Render for OnboardingUI { .on_action(cx.listener(Self::handle_next_page)) .on_action(cx.listener(Self::handle_previous_page)) .w(px(904.)) - .h(px(500.)) - .gap(px(48.)) - .child(self.render_navigation(window, cx)) + .gap(px(24.)) .child( - v_flex() - .h_full() - .flex_1() - .child(div().flex_1().child(self.render_active_page(window, cx))), + h_flex() + .h(px(500.)) + .w_full() + .gap(px(48.)) + .child(self.render_navigation(window, cx)) + .child( + v_flex() + .h_full() + .flex_1() + .when(self.focus_area == FocusArea::PageContent, |this| { + this.border_2() + .border_color(cx.theme().colors().border_focused) + }) + .rounded_lg() + .p_4() + .child( + div().flex_1().child(self.render_active_page(window, cx)), + ), + ), ), ) } @@ -181,8 +208,10 @@ impl OnboardingUI { Self { focus_handle: cx.focus_handle(), current_page: OnboardingPage::Basics, - current_focus: OnboardingFocus::default(), + nav_focus: NavigationFocusItem::Basics, + page_focus: [PageFocusItem(0); 4], completed_pages: [false; 4], + focus_area: FocusArea::Navigation, workspace: workspace.weak_handle(), workspace_id: workspace.database_id(), client, @@ -229,18 +258,185 @@ impl OnboardingUI { } } - fn toggle_focus(&mut self, _window: &mut gpui::Window, cx: &mut Context) { - self.current_focus = match self.current_focus { - OnboardingFocus::Navigation => OnboardingFocus::Page, - OnboardingFocus::Page => OnboardingFocus::Navigation, - }; + fn reset(&mut self, _window: &mut gpui::Window, cx: &mut Context) { + self.current_page = OnboardingPage::Basics; + self.focus_area = FocusArea::Navigation; + self.completed_pages = [false; 4]; cx.notify(); } - fn reset(&mut self, _window: &mut gpui::Window, cx: &mut Context) { - self.current_page = OnboardingPage::Basics; - self.current_focus = OnboardingFocus::Page; - self.completed_pages = [false; 4]; + fn select_next(&mut self, _: &menu::SelectNext, _window: &mut Window, cx: &mut Context) { + match self.focus_area { + FocusArea::Navigation => { + self.nav_focus = match self.nav_focus { + NavigationFocusItem::SignIn => NavigationFocusItem::Basics, + NavigationFocusItem::Basics => NavigationFocusItem::Editing, + NavigationFocusItem::Editing => NavigationFocusItem::AiSetup, + NavigationFocusItem::AiSetup => NavigationFocusItem::Welcome, + NavigationFocusItem::Welcome => NavigationFocusItem::Next, + NavigationFocusItem::Next => NavigationFocusItem::SignIn, + }; + } + FocusArea::PageContent => { + let page_index = match self.current_page { + OnboardingPage::Basics => 0, + OnboardingPage::Editing => 1, + OnboardingPage::AiSetup => 2, + OnboardingPage::Welcome => 3, + }; + // Bounds checking for page items + let max_items = match self.current_page { + OnboardingPage::Basics => 3, // 3 buttons + OnboardingPage::Editing => 3, // 3 buttons + OnboardingPage::AiSetup => 2, // Will have 2 items + OnboardingPage::Welcome => 1, // Will have 1 item + }; + + if self.page_focus[page_index].0 < max_items - 1 { + self.page_focus[page_index].0 += 1; + } else { + // Wrap to start + self.page_focus[page_index].0 = 0; + } + } + } + cx.notify(); + } + + fn select_previous( + &mut self, + _: &menu::SelectPrevious, + _window: &mut Window, + cx: &mut Context, + ) { + match self.focus_area { + FocusArea::Navigation => { + self.nav_focus = match self.nav_focus { + NavigationFocusItem::SignIn => NavigationFocusItem::Next, + NavigationFocusItem::Basics => NavigationFocusItem::SignIn, + NavigationFocusItem::Editing => NavigationFocusItem::Basics, + NavigationFocusItem::AiSetup => NavigationFocusItem::Editing, + NavigationFocusItem::Welcome => NavigationFocusItem::AiSetup, + NavigationFocusItem::Next => NavigationFocusItem::Welcome, + }; + } + FocusArea::PageContent => { + let page_index = match self.current_page { + OnboardingPage::Basics => 0, + OnboardingPage::Editing => 1, + OnboardingPage::AiSetup => 2, + OnboardingPage::Welcome => 3, + }; + // Bounds checking for page items + let max_items = match self.current_page { + OnboardingPage::Basics => 3, // 3 buttons + OnboardingPage::Editing => 3, // 3 buttons + OnboardingPage::AiSetup => 2, // Will have 2 items + OnboardingPage::Welcome => 1, // Will have 1 item + }; + + if self.page_focus[page_index].0 > 0 { + self.page_focus[page_index].0 -= 1; + } else { + // Wrap to end + self.page_focus[page_index].0 = max_items - 1; + } + } + } + cx.notify(); + } + + fn confirm(&mut self, _: &menu::Confirm, window: &mut Window, cx: &mut Context) { + match self.focus_area { + FocusArea::Navigation => { + match self.nav_focus { + NavigationFocusItem::SignIn => { + // Handle sign in action + // TODO: Implement sign in action + } + NavigationFocusItem::Basics => { + self.jump_to_page(OnboardingPage::Basics, window, cx) + } + NavigationFocusItem::Editing => { + self.jump_to_page(OnboardingPage::Editing, window, cx) + } + NavigationFocusItem::AiSetup => { + self.jump_to_page(OnboardingPage::AiSetup, window, cx) + } + NavigationFocusItem::Welcome => { + self.jump_to_page(OnboardingPage::Welcome, window, cx) + } + NavigationFocusItem::Next => { + // Handle next button action + self.next_page(window, cx); + } + } + // After confirming navigation item (except Next), switch focus to page content + if self.nav_focus != NavigationFocusItem::Next { + self.focus_area = FocusArea::PageContent; + } + } + FocusArea::PageContent => { + // Handle page-specific item selection + let page_index = match self.current_page { + OnboardingPage::Basics => 0, + OnboardingPage::Editing => 1, + OnboardingPage::AiSetup => 2, + OnboardingPage::Welcome => 3, + }; + let item_index = self.page_focus[page_index].0; + + // Trigger the action for the focused item + match self.current_page { + OnboardingPage::Basics => { + match item_index { + 0 => { + // Open file action + cx.notify(); + } + 1 => { + // Create project action + cx.notify(); + } + 2 => { + // Explore UI action + cx.notify(); + } + _ => {} + } + } + OnboardingPage::Editing => { + // Similar handling for editing page + cx.notify(); + } + _ => { + cx.notify(); + } + } + } + } + cx.notify(); + } + + fn cancel(&mut self, _: &menu::Cancel, _window: &mut Window, cx: &mut Context) { + match self.focus_area { + FocusArea::PageContent => { + // Switch focus back to navigation + self.focus_area = FocusArea::Navigation; + } + FocusArea::Navigation => { + // If already in navigation, maybe close the onboarding? + // For now, just stay in navigation + } + } + cx.notify(); + } + + fn toggle_focus(&mut self, _: &ToggleFocus, _window: &mut Window, cx: &mut Context) { + self.focus_area = match self.focus_area { + FocusArea::Navigation => FocusArea::PageContent, + FocusArea::PageContent => FocusArea::Navigation, + }; cx.notify(); } @@ -340,6 +536,11 @@ impl OnboardingUI { Button::new("sign_in", "Sign in") .color(Color::Muted) .label_size(LabelSize::Small) + .when( + self.focus_area == FocusArea::Navigation + && self.nav_focus == NavigationFocusItem::SignIn, + |this| this.color(Color::Accent), + ) .size(ButtonSize::Compact) .on_click(cx.listener(move |_, _, window, cx| { let client = client.clone(); @@ -401,15 +602,31 @@ impl OnboardingUI { let shortcut = shortcut.into(); let id = ElementId::Name(label.clone()); + let is_focused = match page { + OnboardingPage::Basics => self.nav_focus == NavigationFocusItem::Basics, + OnboardingPage::Editing => self.nav_focus == NavigationFocusItem::Editing, + OnboardingPage::AiSetup => self.nav_focus == NavigationFocusItem::AiSetup, + OnboardingPage::Welcome => self.nav_focus == NavigationFocusItem::Welcome, + }; + + let area_focused = self.focus_area == FocusArea::Navigation; + h_flex() .id(id) .h(rems(1.5)) .w_full() + .when(is_focused, |this| { + this.bg(if area_focused { + cx.theme().colors().border_focused.opacity(0.16) + } else { + cx.theme().colors().border.opacity(0.24) + }) + }) .child( div() .w(px(3.)) .h_full() - .when(selected, |this| this.bg(cx.theme().status().info)), + .when(selected, |this| this.bg(cx.theme().colors().border_focused)), ) .child( h_flex() @@ -417,7 +634,7 @@ impl OnboardingUI { .flex_1() .justify_between() .items_center() - .child(Label::new(label)) + .child(Label::new(label).when(is_focused, |this| this.color(Color::Default))) .child(Label::new(format!("⌘{}", shortcut.clone())).color(Color::Muted)), ) .on_click(cx.listener(move |this, _, window, cx| { @@ -440,6 +657,11 @@ impl OnboardingUI { }, ) .style(ButtonStyle::Filled) + .when( + self.focus_area == FocusArea::Navigation + && self.nav_focus == NavigationFocusItem::Next, + |this| this.color(Color::Accent), + ) .key_binding(ui::KeyBinding::for_action_in( &NextPage, &self.focus_handle, @@ -452,48 +674,230 @@ impl OnboardingUI { ) } - fn render_active_page( - &mut self, - _window: &mut gpui::Window, - _cx: &mut Context, - ) -> AnyElement { + fn render_active_page(&mut self, _window: &mut Window, cx: &mut Context) -> AnyElement { match self.current_page { - OnboardingPage::Basics => self.render_basics_page(), - OnboardingPage::Editing => self.render_editing_page(), - OnboardingPage::AiSetup => self.render_ai_setup_page(), - OnboardingPage::Welcome => self.render_welcome_page(), + OnboardingPage::Basics => self.render_basics_page(cx), + OnboardingPage::Editing => self.render_editing_page(cx), + OnboardingPage::AiSetup => self.render_ai_setup_page(cx), + OnboardingPage::Welcome => self.render_welcome_page(cx), } } - fn render_basics_page(&self) -> AnyElement { + fn render_basics_page(&mut self, cx: &mut Context) -> AnyElement { + let page_index = 0; // Basics page index + let focused_item = self.page_focus[page_index].0; + let is_page_focused = self.focus_area == FocusArea::PageContent; + v_flex() .h_full() .w_full() - .child("Basics Page") + .items_center() + .justify_center() + .gap_4() + .child( + Label::new("Welcome to Zed!") + .size(LabelSize::Large) + .color(Color::Default), + ) + .child( + Label::new("Let's get you started with the basics") + .size(LabelSize::Default) + .color(Color::Muted), + ) + .child( + v_flex() + .gap_2() + .mt_4() + .child( + Button::new("open_file", "Open a File") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 0, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + // TODO: Trigger open file action + cx.notify(); + })), + ) + .child( + Button::new("create_project", "Create a Project") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 1, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + // TODO: Trigger create project action + cx.notify(); + })), + ) + .child( + Button::new("explore_ui", "Explore the UI") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 2, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + // TODO: Trigger explore UI action + cx.notify(); + })), + ), + ) .into_any_element() } - fn render_editing_page(&self) -> AnyElement { + fn render_editing_page(&mut self, cx: &mut Context) -> AnyElement { + let page_index = 1; // Editing page index + let focused_item = self.page_focus[page_index].0; + let is_page_focused = self.focus_area == FocusArea::PageContent; + v_flex() .h_full() .w_full() - .child("Editing Page") + .items_center() + .justify_center() + .gap_4() + .child( + Label::new("Editing Features") + .size(LabelSize::Large) + .color(Color::Default), + ) + .child( + v_flex() + .gap_2() + .mt_4() + .child( + Button::new("try_multi_cursor", "Try Multi-cursor Editing") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 0, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + cx.notify(); + })), + ) + .child( + Button::new("learn_shortcuts", "Learn Keyboard Shortcuts") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 1, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + cx.notify(); + })), + ) + .child( + Button::new("explore_actions", "Explore Command Palette") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 2, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + cx.notify(); + })), + ), + ) .into_any_element() } - fn render_ai_setup_page(&self) -> AnyElement { + fn render_ai_setup_page(&mut self, cx: &mut Context) -> AnyElement { + let page_index = 2; // AI Setup page index + let focused_item = self.page_focus[page_index].0; + let is_page_focused = self.focus_area == FocusArea::PageContent; + v_flex() .h_full() .w_full() - .child("AI Setup Page") + .items_center() + .justify_center() + .gap_4() + .child( + Label::new("AI Assistant Setup") + .size(LabelSize::Large) + .color(Color::Default), + ) + .child( + v_flex() + .gap_2() + .mt_4() + .child( + Button::new("configure_ai", "Configure AI Provider") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 0, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + cx.notify(); + })), + ) + .child( + Button::new("try_ai_chat", "Try AI Chat") + .style(ButtonStyle::Filled) + .when(is_page_focused && focused_item == 1, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + cx.notify(); + })), + ), + ) .into_any_element() } - fn render_welcome_page(&self) -> AnyElement { + fn render_welcome_page(&mut self, cx: &mut Context) -> AnyElement { + let page_index = 3; // Welcome page index + let focused_item = self.page_focus[page_index].0; + let is_page_focused = self.focus_area == FocusArea::PageContent; + v_flex() .h_full() .w_full() - .child("Welcome Page") + .items_center() + .justify_center() + .gap_4() + .child( + Label::new("Welcome to Zed!") + .size(LabelSize::Large) + .color(Color::Default), + ) + .child( + Label::new("You're all set up and ready to code") + .size(LabelSize::Default) + .color(Color::Muted), + ) + .child( + Button::new("finish_onboarding", "Start Coding!") + .style(ButtonStyle::Filled) + .size(ButtonSize::Large) + .when(is_page_focused && focused_item == 0, |this| { + this.color(Color::Accent) + }) + .on_click(cx.listener(|_, _, _, cx| { + // TODO: Close onboarding and start coding + cx.notify(); + })), + ) + .into_any_element() + } + + fn render_keyboard_help(&self, cx: &mut Context) -> AnyElement { + let help_text = match self.focus_area { + FocusArea::Navigation => { + "Use ↑/↓ to navigate • Enter to select page • Tab to switch to page content" + } + FocusArea::PageContent => { + "Use ↑/↓ to navigate • Enter to activate • Esc to return to navigation" + } + }; + + h_flex() + .w_full() + .justify_center() + .p_2() + .child( + Label::new(help_text) + .size(LabelSize::Small) + .color(Color::Muted), + ) .into_any_element() } } From 8c446ecd5957aad1151c9ab8d2811b472d2ed547 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 30 Jun 2025 21:44:17 -0400 Subject: [PATCH 10/29] wip basics section --- Cargo.lock | 4 +- crates/onboarding_ui/Cargo.toml | 4 +- crates/onboarding_ui/src/onboarding_ui.rs | 422 +++++++++++++++++++--- crates/onboarding_ui/src/theme_preview.rs | 200 ++++++++++ 4 files changed, 573 insertions(+), 57 deletions(-) create mode 100644 crates/onboarding_ui/src/theme_preview.rs diff --git a/Cargo.lock b/Cargo.lock index eab5741d25..011f970283 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10828,13 +10828,15 @@ dependencies = [ "gpui", "menu", "project", + "serde_json", "settings", "settings_ui", "theme", "ui", "util", + "vim_mode_setting", + "welcome", "workspace", - "workspace-hack", "zed_actions", ] diff --git a/crates/onboarding_ui/Cargo.toml b/crates/onboarding_ui/Cargo.toml index 2476643033..61ee08fc2e 100644 --- a/crates/onboarding_ui/Cargo.toml +++ b/crates/onboarding_ui/Cargo.toml @@ -16,6 +16,7 @@ test-support = [] [dependencies] anyhow.workspace = true +welcome.workspace = true client.workspace = true command_palette_hooks.workspace = true component.workspace = true @@ -24,12 +25,13 @@ feature_flags.workspace = true gpui.workspace = true menu.workspace = true project.workspace = true +serde_json.workspace = true settings.workspace = true settings_ui.workspace = true theme.workspace = true ui.workspace = true util.workspace = true -workspace-hack.workspace = true +vim_mode_setting.workspace = true workspace.workspace = true zed_actions.workspace = true diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index accd01eb73..72d8d7f776 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -1,20 +1,27 @@ #![allow(unused, dead_code)] mod persistence; +mod theme_preview; -use client::Client; +use client::{Client, TelemetrySettings}; use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; use gpui::{ - Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, WeakEntity, actions, prelude::*, + Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, UpdateGlobal, WeakEntity, + actions, prelude::*, svg, }; use menu; use persistence::ONBOARDING_DB; use project::Project; +use serde_json; +use settings::{Settings, SettingsStore}; use settings_ui::SettingsUiFeatureFlag; use std::sync::Arc; -use ui::{ListItem, Vector, VectorName, prelude::*}; +use theme::{Theme, ThemeRegistry, ThemeSettings}; +use ui::{ListItem, ToggleState, Vector, VectorName, prelude::*}; use util::ResultExt; +use vim_mode_setting::VimModeSetting; +use welcome::BaseKeymap; use workspace::{ Workspace, WorkspaceId, item::{Item, ItemEvent, SerializableItem}, @@ -133,6 +140,8 @@ pub struct OnboardingUI { client: Arc, } +impl OnboardingUI {} + impl EventEmitter for OnboardingUI {} impl Focusable for OnboardingUI { @@ -286,7 +295,7 @@ impl OnboardingUI { }; // Bounds checking for page items let max_items = match self.current_page { - OnboardingPage::Basics => 3, // 3 buttons + OnboardingPage::Basics => 14, // 4 themes + 7 keymaps + 3 checkboxes OnboardingPage::Editing => 3, // 3 buttons OnboardingPage::AiSetup => 2, // Will have 2 items OnboardingPage::Welcome => 1, // Will have 1 item @@ -329,7 +338,7 @@ impl OnboardingUI { }; // Bounds checking for page items let max_items = match self.current_page { - OnboardingPage::Basics => 3, // 3 buttons + OnboardingPage::Basics => 14, // 4 themes + 7 keymaps + 3 checkboxes OnboardingPage::Editing => 3, // 3 buttons OnboardingPage::AiSetup => 2, // Will have 2 items OnboardingPage::Welcome => 1, // Will have 1 item @@ -390,16 +399,16 @@ impl OnboardingUI { match self.current_page { OnboardingPage::Basics => { match item_index { - 0 => { - // Open file action + 0..=3 => { + // Theme selection cx.notify(); } - 1 => { - // Create project action + 4..=10 => { + // Keymap selection cx.notify(); } - 2 => { - // Explore UI action + 11..=13 => { + // Checkbox toggles (handled by their own listeners) cx.notify(); } _ => {} @@ -688,60 +697,363 @@ impl OnboardingUI { let focused_item = self.page_focus[page_index].0; let is_page_focused = self.focus_area == FocusArea::PageContent; + use theme_preview::ThemePreviewTile; + + // Get available themes + let theme_registry = ThemeRegistry::default_global(cx); + let theme_names = theme_registry.list_names(); + let current_theme = cx.theme().clone(); + + // For demo, we'll show 4 themes + v_flex() + .id("theme-selector") .h_full() .w_full() - .items_center() - .justify_center() - .gap_4() - .child( - Label::new("Welcome to Zed!") - .size(LabelSize::Large) - .color(Color::Default), - ) - .child( - Label::new("Let's get you started with the basics") - .size(LabelSize::Default) - .color(Color::Muted), - ) + .p_6() + .gap_6() + .overflow_y_scroll() + // Theme selector section .child( v_flex() - .gap_2() - .mt_4() + .gap_3() .child( - Button::new("open_file", "Open a File") - .style(ButtonStyle::Filled) - .when(is_page_focused && focused_item == 0, |this| { - this.color(Color::Accent) - }) - .on_click(cx.listener(|_, _, _, cx| { - // TODO: Trigger open file action - cx.notify(); - })), + h_flex() + .justify_between() + .child(Label::new("Pick a Theme").size(LabelSize::Large)) + .child( + Button::new("more_themes", "More Themes") + .style(ButtonStyle::Subtle) + .color(Color::Muted) + .on_click(cx.listener(|_, _, window, cx| { + // TODO: Open theme selector + cx.notify(); + })), + ), ) .child( - Button::new("create_project", "Create a Project") - .style(ButtonStyle::Filled) - .when(is_page_focused && focused_item == 1, |this| { - this.color(Color::Accent) - }) - .on_click(cx.listener(|_, _, _, cx| { - // TODO: Trigger create project action - cx.notify(); - })), - ) - .child( - Button::new("explore_ui", "Explore the UI") - .style(ButtonStyle::Filled) - .when(is_page_focused && focused_item == 2, |this| { - this.color(Color::Accent) - }) - .on_click(cx.listener(|_, _, _, cx| { - // TODO: Trigger explore UI action - cx.notify(); - })), + h_flex() + .gap_3() + .children( + vec![ + ("One Dark", "one-dark"), + ("Gruvbox Dark", "gruvbox-dark"), + ("One Light", "one-light"), + ("Gruvbox Light", "gruvbox-light"), + ] + .into_iter() + .enumerate() + .map(|(i, (label, theme_name))| { + let is_selected = current_theme.name == *theme_name; + let is_focused = is_page_focused && focused_item == i; + + v_flex() + .gap_2() + .child( + div() + .id("theme-item") + .when(is_focused, |this| { + this.border_2().border_color( + cx.theme().colors().border_focused, + ) + }) + .rounded_md() + .p_1() + .id(("theme", i)) + .child( + if let Ok(theme) = + theme_registry.get(theme_name) + { + ThemePreviewTile::new( + theme, + is_selected, + 0.5, + ) + .into_any_element() + } else { + div() + .w(px(200.)) + .h(px(120.)) + .bg(cx + .theme() + .colors() + .surface_background) + .rounded_md() + .into_any_element() + }, + ) + .on_click(cx.listener( + move |this, _, window, cx| { + SettingsStore::update_global(cx, move |store, cx| { + let mut settings = store.raw_user_settings().clone(); + settings["theme"] = serde_json::json!(theme_name); + store.set_user_settings(&settings.to_string(), cx).ok(); + }); + cx.notify(); + }, + )), + ) + .child(Label::new(label).size(LabelSize::Small).color( + if is_selected { + Color::Default + } else { + Color::Muted + }, + )) + }, + )), ), ) + // Keymap selector section + .child( + v_flex() + .gap_3() + .mt_4() + .child(Label::new("Pick a Keymap").size(LabelSize::Large)) + .child( + h_flex().gap_2().children( + vec![ + ("Zed", VectorName::ZedLogo, 4), + ("Atom", VectorName::ZedLogo, 5), + ("JetBrains", VectorName::ZedLogo, 6), + ("Sublime", VectorName::ZedLogo, 7), + ("VSCode", VectorName::ZedLogo, 8), + ("Emacs", VectorName::ZedLogo, 9), + ("TextMate", VectorName::ZedLogo, 10), + ] + .into_iter() + .map(|(label, icon, index)| { + let is_focused = is_page_focused && focused_item == index; + let current_keymap = BaseKeymap::get_global(cx).to_string(); + let is_selected = current_keymap == label; + + v_flex() + .gap_1() + .items_center() + .child( + div() + .id(("keymap", index)) + .p_3() + .rounded_md() + .bg(cx.theme().colors().element_background) + .border_1() + .border_color(if is_selected { + cx.theme().colors().border_selected + } else { + cx.theme().colors().border + }) + .when(is_focused, |this| { + this.border_color( + cx.theme().colors().border_focused, + ) + }) + .when(is_selected, |this| { + this.bg(cx.theme().colors().element_selected) + }) + .hover(|this| { + this.bg(cx.theme().colors().element_hover) + }) + .child( + Vector::new(icon, rems(2.), rems(2.)) + .color(Color::Muted), + ) + .on_click(cx.listener(move |this, _, window, cx| { + SettingsStore::update_global(cx, move |store, cx| { + let base_keymap = match label { + "Zed" => "None", + "Atom" => "Atom", + "JetBrains" => "JetBrains", + "Sublime" => "SublimeText", + "VSCode" => "VSCode", + "Emacs" => "Emacs", + "TextMate" => "TextMate", + _ => "VSCode", + }; + let mut settings = store.raw_user_settings().clone(); + settings["base_keymap"] = serde_json::json!(base_keymap); + store.set_user_settings(&settings.to_string(), cx).ok(); + }); + cx.notify(); + })), + ) + .child( + Label::new(label) + .size(LabelSize::Small) + .color(if is_selected { + Color::Default + } else { + Color::Muted + }), + ) + }) + ), + ), + ) + // Settings checkboxes + .child( + v_flex() + .gap_3() + .mt_6() + .child({ + let vim_enabled = VimModeSetting::get_global(cx).0; + h_flex() + .id("vim_mode_container") + .gap_2() + .items_center() + .p_1() + .rounded_md() + .when(is_page_focused && focused_item == 11, |this| { + this.border_2() + .border_color(cx.theme().colors().border_focused) + }) + .child( + div() + .id("vim_mode_checkbox") + .w_4() + .h_4() + .rounded_sm() + .border_1() + .border_color(cx.theme().colors().border) + .when(vim_enabled, |this| { + this.bg(cx.theme().colors().element_selected) + .border_color(cx.theme().colors().border_selected) + }) + .hover(|this| this.bg(cx.theme().colors().element_hover)) + .child( + div().when(vim_enabled, |this| { + this.size_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z") + .size_3() + .text_color(cx.theme().colors().icon), + ) + }) + ), + ) + .child(Label::new("Enable Vim Mode")) + .cursor_pointer() + .on_click(cx.listener(move |this, _, _window, cx| { + let current = VimModeSetting::get_global(cx).0; + SettingsStore::update_global(cx, move |store, cx| { + let mut settings = store.raw_user_settings().clone(); + settings["vim_mode"] = serde_json::json!(!current); + store.set_user_settings(&settings.to_string(), cx).ok(); + }); + })) + }) + .child({ + let crash_reports_enabled = TelemetrySettings::get_global(cx).diagnostics; + h_flex() + .id("crash_reports_container") + .gap_2() + .items_center() + .p_1() + .rounded_md() + .when(is_page_focused && focused_item == 12, |this| { + this.border_2() + .border_color(cx.theme().colors().border_focused) + }) + .child( + div() + .id("crash_reports_checkbox") + .w_4() + .h_4() + .rounded_sm() + .border_1() + .border_color(cx.theme().colors().border) + .when(crash_reports_enabled, |this| { + this.bg(cx.theme().colors().element_selected) + .border_color(cx.theme().colors().border_selected) + }) + .hover(|this| this.bg(cx.theme().colors().element_hover)) + .child( + div().when(crash_reports_enabled, |this| { + this.size_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z") + .size_3() + .text_color(cx.theme().colors().icon), + ) + }) + ), + ) + .child(Label::new("Send Crash Reports")) + .cursor_pointer() + .on_click(cx.listener(move |this, _, _window, cx| { + let current = TelemetrySettings::get_global(cx).diagnostics; + SettingsStore::update_global(cx, move |store, cx| { + let mut settings = store.raw_user_settings().clone(); + if settings.get("telemetry").is_none() { + settings["telemetry"] = serde_json::json!({}); + } + settings["telemetry"]["diagnostics"] = serde_json::json!(!current); + store.set_user_settings(&settings.to_string(), cx).ok(); + }); + })) + }) + .child({ + let telemetry_enabled = TelemetrySettings::get_global(cx).metrics; + h_flex() + .id("telemetry_container") + .gap_2() + .items_center() + .p_1() + .rounded_md() + .when(is_page_focused && focused_item == 13, |this| { + this.border_2() + .border_color(cx.theme().colors().border_focused) + }) + .child( + div() + .id("telemetry_checkbox") + .w_4() + .h_4() + .rounded_sm() + .border_1() + .border_color(cx.theme().colors().border) + .when(telemetry_enabled, |this| { + this.bg(cx.theme().colors().element_selected) + .border_color(cx.theme().colors().border_selected) + }) + .hover(|this| this.bg(cx.theme().colors().element_hover)) + .child( + div().when(telemetry_enabled, |this| { + this.size_full() + .flex() + .items_center() + .justify_center() + .child( + svg() + .path("M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z") + .size_3() + .text_color(cx.theme().colors().icon), + ) + }) + ), + ) + .child(Label::new("Send Telemetry")) + .cursor_pointer() + .on_click(cx.listener(move |this, _, _window, cx| { + let current = TelemetrySettings::get_global(cx).metrics; + SettingsStore::update_global(cx, move |store, cx| { + let mut settings = store.raw_user_settings().clone(); + if settings.get("telemetry").is_none() { + settings["telemetry"] = serde_json::json!({}); + } + settings["telemetry"]["metrics"] = serde_json::json!(!current); + store.set_user_settings(&settings.to_string(), cx).ok(); + }); + })) + }), + ) .into_any_element() } diff --git a/crates/onboarding_ui/src/theme_preview.rs b/crates/onboarding_ui/src/theme_preview.rs new file mode 100644 index 0000000000..32780e6c62 --- /dev/null +++ b/crates/onboarding_ui/src/theme_preview.rs @@ -0,0 +1,200 @@ +#![allow(unused, dead_code)] +use gpui::{Hsla, Length}; +use std::sync::Arc; +use theme::{Theme, ThemeRegistry}; +use ui::{IntoElement, RenderOnce, prelude::*, utils::inner_corner_radius}; + +/// Shows a preview of a theme as an abstract illustration +/// of a thumbnail-sized editor. +#[derive(IntoElement)] +pub struct ThemePreviewTile { + theme: Arc, + selected: bool, + seed: f32, +} + +impl ThemePreviewTile { + pub fn new(theme: Arc, selected: bool, seed: f32) -> Self { + Self { + theme, + selected, + seed, + } + } + + pub fn selected(mut self, selected: bool) -> Self { + self.selected = selected; + self + } +} + +impl RenderOnce for ThemePreviewTile { + fn render(self, _window: &mut ui::Window, _cx: &mut ui::App) -> impl IntoElement { + let color = self.theme.colors(); + + let root_radius = px(8.0); + let root_border = px(2.0); + let root_padding = px(2.0); + let child_border = px(1.0); + let inner_radius = + inner_corner_radius(root_radius, root_border, root_padding, child_border); + + let item_skeleton = |w: Length, h: Pixels, bg: Hsla| div().w(w).h(h).rounded_full().bg(bg); + + let skeleton_height = px(4.); + + let sidebar_seeded_width = |seed: f32, index: usize| { + let value = (seed * 1000.0 + index as f32 * 10.0).sin() * 0.5 + 0.5; + 0.5 + value * 0.45 + }; + + let sidebar_skeleton_items = 8; + + let sidebar_skeleton = (0..sidebar_skeleton_items) + .map(|i| { + let width = sidebar_seeded_width(self.seed, i); + item_skeleton( + relative(width).into(), + skeleton_height, + color.text.alpha(0.45), + ) + }) + .collect::>(); + + let sidebar = div() + .h_full() + .w(relative(0.25)) + .border_r(px(1.)) + .border_color(color.border_transparent) + .bg(color.panel_background) + .child( + div() + .p_2() + .flex() + .flex_col() + .size_full() + .gap(px(4.)) + .children(sidebar_skeleton), + ); + + let pseudo_code_skeleton = |theme: Arc, seed: f32| -> AnyElement { + let colors = theme.colors(); + let syntax = theme.syntax(); + + let keyword_color = syntax.get("keyword").color; + let function_color = syntax.get("function").color; + let string_color = syntax.get("string").color; + let comment_color = syntax.get("comment").color; + let variable_color = syntax.get("variable").color; + let type_color = syntax.get("type").color; + let punctuation_color = syntax.get("punctuation").color; + + let syntax_colors = [ + keyword_color, + function_color, + string_color, + variable_color, + type_color, + punctuation_color, + comment_color, + ]; + + let line_width = |line_idx: usize, block_idx: usize| -> f32 { + let val = (seed * 100.0 + line_idx as f32 * 20.0 + block_idx as f32 * 5.0).sin() + * 0.5 + + 0.5; + 0.05 + val * 0.2 + }; + + let indentation = |line_idx: usize| -> f32 { + let step = line_idx % 6; + if step < 3 { + step as f32 * 0.1 + } else { + (5 - step) as f32 * 0.1 + } + }; + + let pick_color = |line_idx: usize, block_idx: usize| -> Hsla { + let idx = ((seed * 10.0 + line_idx as f32 * 7.0 + block_idx as f32 * 3.0).sin() + * 3.5) + .abs() as usize + % syntax_colors.len(); + syntax_colors[idx].unwrap_or(colors.text) + }; + + let line_count = 13; + + let lines = (0..line_count) + .map(|line_idx| { + let block_count = (((seed * 30.0 + line_idx as f32 * 12.0).sin() * 0.5 + 0.5) + * 3.0) + .round() as usize + + 2; + + let indent = indentation(line_idx); + + let blocks = (0..block_count) + .map(|block_idx| { + let width = line_width(line_idx, block_idx); + let color = pick_color(line_idx, block_idx); + item_skeleton(relative(width).into(), skeleton_height, color) + }) + .collect::>(); + + h_flex().gap(px(2.)).ml(relative(indent)).children(blocks) + }) + .collect::>(); + + v_flex() + .size_full() + .p_1() + .gap(px(6.)) + .children(lines) + .into_any_element() + }; + + let pane = div() + .h_full() + .flex_grow() + .flex() + .flex_col() + // .child( + // div() + // .w_full() + // .border_color(color.border) + // .border_b(px(1.)) + // .h(relative(0.1)) + // .bg(color.tab_bar_background), + // ) + .child( + div() + .size_full() + .overflow_hidden() + .bg(color.editor_background) + .p_2() + .child(pseudo_code_skeleton(self.theme.clone(), self.seed)), + ); + + let content = div().size_full().flex().child(sidebar).child(pane); + + div() + .size_full() + .rounded(root_radius) + .p(root_padding) + .border(root_border) + .border_color(color.border_transparent) + .when(self.selected, |this| { + this.border_color(color.border_selected) + }) + .child( + div() + .size_full() + .rounded(inner_radius) + .border(child_border) + .border_color(color.border) + .bg(color.background) + .child(content), + ) + } +} From 530b24258f1f153420f30557bdc1cfe12697d9c0 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 1 Jul 2025 08:03:50 -0400 Subject: [PATCH 11/29] Add `shadow_hairline` --- crates/gpui_macros/src/styles.rs | 17 +++++++++++++++++ crates/ui/src/components/button/split_button.rs | 7 +------ 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/crates/gpui_macros/src/styles.rs b/crates/gpui_macros/src/styles.rs index 4e3dda9ed2..0038bf49d8 100644 --- a/crates/gpui_macros/src/styles.rs +++ b/crates/gpui_macros/src/styles.rs @@ -405,6 +405,23 @@ pub fn box_shadow_style_methods(input: TokenStream) -> TokenStream { self } + /// Sets the box shadow of the element. + /// + /// A hairline shadow is a very thin shadow that is often used + /// to create a subtle depth effect under an element. + #visibility fn shadow_hairline(mut self) -> Self { + use gpui::{BoxShadow, hsla, point, px}; + use std::vec; + + self.style().box_shadow = Some(vec![BoxShadow { + color: hsla(0.0, 0.0, 0.0, 0.16), + offset: point(px(0.), px(1.)), + blur_radius: px(0.), + spread_radius: px(0.), + }]); + self + } + /// Sets the box shadow of the element. /// [Docs](https://tailwindcss.com/docs/box-shadow) #visibility fn shadow_sm(mut self) -> Self { diff --git a/crates/ui/src/components/button/split_button.rs b/crates/ui/src/components/button/split_button.rs index c0811ecbab..372da9f204 100644 --- a/crates/ui/src/components/button/split_button.rs +++ b/crates/ui/src/components/button/split_button.rs @@ -41,11 +41,6 @@ impl RenderOnce for SplitButton { ) .child(self.right) .bg(ElevationIndex::Surface.on_elevation_bg(cx)) - .shadow(vec![BoxShadow { - color: hsla(0.0, 0.0, 0.0, 0.16), - offset: point(px(0.), px(1.)), - blur_radius: px(0.), - spread_radius: px(0.), - }]) + .shadow_hairline() } } From 124ebb872a819579cde9978335797ae551dcdcea Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 1 Jul 2025 08:44:52 -0400 Subject: [PATCH 12/29] Start on onboarding button --- crates/onboarding_ui/src/juicy_button.rs | 94 +++++++++++++++++++++++ crates/onboarding_ui/src/onboarding_ui.rs | 23 ++---- 2 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 crates/onboarding_ui/src/juicy_button.rs diff --git a/crates/onboarding_ui/src/juicy_button.rs b/crates/onboarding_ui/src/juicy_button.rs new file mode 100644 index 0000000000..39fb132b96 --- /dev/null +++ b/crates/onboarding_ui/src/juicy_button.rs @@ -0,0 +1,94 @@ +use gpui::{FontWeight, *}; +use ui::prelude::*; + +#[derive(IntoElement)] +pub struct JuicyButton { + base: Div, + label: SharedString, + keybinding: Option, + on_click: Option>, +} + +impl JuicyButton { + pub fn new(label: impl Into) -> Self { + Self { + base: div(), + label: label.into(), + keybinding: None, + on_click: None, + } + } + + pub fn keybinding(mut self, keybinding: Option) -> Self { + if let Some(kb) = keybinding { + self.keybinding = Some(kb.into_any_element()); + } + self + } +} + +impl Clickable for JuicyButton { + fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self { + self.on_click = Some(Box::new(handler)); + self + } + + fn cursor_style(mut self, style: gpui::CursorStyle) -> Self { + self.base = self.base.cursor(style); + self + } +} + +impl RenderOnce for JuicyButton { + fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement { + let mut children = vec![ + h_flex() + .flex_1() + .items_center() + .justify_center() + .child( + div() + .text_size(px(14.)) + .font_weight(FontWeight::MEDIUM) + .text_color(cx.theme().colors().text) + .child(self.label), + ) + .into_any_element(), + ]; + + if let Some(keybinding) = self.keybinding { + children.push( + div() + .flex_none() + .bg(gpui::white().opacity(0.2)) + .rounded_md() + .px_1() + .child(keybinding) + .into_any_element(), + ); + } + + self.base + .id("juicy-button") + .w_full() + .h(rems(2.)) + .px(rems(1.5)) + .rounded(px(6.)) + .bg(cx.theme().colors().icon.opacity(0.12)) + .shadow_hairline() + .hover(|style| { + style.bg(cx.theme().colors().icon.opacity(0.12)) // Darker blue on hover + }) + .active(|style| { + style + .bg(rgb(0x1e40af)) // Even darker on active + .shadow_md() + }) + .cursor_pointer() + .flex() + .items_center() + .justify_between() + .when_some(self.on_click, |div, on_click| div.on_click(on_click)) + .children(children) + } +} diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 72d8d7f776..668da2b10a 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -1,7 +1,9 @@ #![allow(unused, dead_code)] +mod juicy_button; mod persistence; mod theme_preview; +use self::juicy_button::JuicyButton; use client::{Client, TelemetrySettings}; use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; @@ -657,21 +659,12 @@ impl OnboardingUI { cx: &mut Context, ) -> impl gpui::IntoElement { h_flex().w_full().p(px(12.)).pl(px(24.)).child( - Button::new( - "next", - if self.current_page == OnboardingPage::Welcome { - "Get Started" - } else { - "Next" - }, - ) - .style(ButtonStyle::Filled) - .when( - self.focus_area == FocusArea::Navigation - && self.nav_focus == NavigationFocusItem::Next, - |this| this.color(Color::Accent), - ) - .key_binding(ui::KeyBinding::for_action_in( + JuicyButton::new(if self.current_page == OnboardingPage::Welcome { + "Get Started" + } else { + "Next" + }) + .keybinding(ui::KeyBinding::for_action_in( &NextPage, &self.focus_handle, window, From ff0345bb4ff975cdb8d35fbc047bb39e895998ea Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 1 Jul 2025 23:04:35 -0400 Subject: [PATCH 13/29] Fix theme tiles --- crates/onboarding_ui/src/onboarding_ui.rs | 309 ++++++++++------------ crates/onboarding_ui/src/theme_preview.rs | 2 +- 2 files changed, 136 insertions(+), 175 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 668da2b10a..21b5999961 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -9,7 +9,7 @@ use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; use gpui::{ Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, UpdateGlobal, WeakEntity, - actions, prelude::*, svg, + actions, prelude::*, svg, transparent_black, }; use menu; use persistence::ONBOARDING_DB; @@ -187,27 +187,22 @@ impl Render for OnboardingUI { .on_action(cx.listener(Self::handle_jump_to_welcome)) .on_action(cx.listener(Self::handle_next_page)) .on_action(cx.listener(Self::handle_previous_page)) - .w(px(904.)) + .w(px(984.)) + .overflow_hidden() .gap(px(24.)) .child( h_flex() .h(px(500.)) .w_full() + .overflow_hidden() .gap(px(48.)) .child(self.render_navigation(window, cx)) .child( v_flex() .h_full() .flex_1() - .when(self.focus_area == FocusArea::PageContent, |this| { - this.border_2() - .border_color(cx.theme().colors().border_focused) - }) - .rounded_lg() - .p_4() - .child( - div().flex_1().child(self.render_active_page(window, cx)), - ), + .overflow_hidden() + .child(self.render_active_page(window, cx)), ), ), ) @@ -697,23 +692,23 @@ impl OnboardingUI { let theme_names = theme_registry.list_names(); let current_theme = cx.theme().clone(); - // For demo, we'll show 4 themes - v_flex() .id("theme-selector") .h_full() .w_full() - .p_6() .gap_6() .overflow_y_scroll() // Theme selector section .child( v_flex() - .gap_3() + .w_full() + .overflow_hidden() .child( h_flex() + .h(px(32.)) + .w_full() .justify_between() - .child(Label::new("Pick a Theme").size(LabelSize::Large)) + .child(Label::new("Pick a Theme")) .child( Button::new("more_themes", "More Themes") .style(ButtonStyle::Subtle) @@ -725,76 +720,76 @@ impl OnboardingUI { ), ) .child( - h_flex() - .gap_3() - .children( - vec![ - ("One Dark", "one-dark"), - ("Gruvbox Dark", "gruvbox-dark"), - ("One Light", "one-light"), - ("Gruvbox Light", "gruvbox-light"), - ] - .into_iter() - .enumerate() - .map(|(i, (label, theme_name))| { - let is_selected = current_theme.name == *theme_name; - let is_focused = is_page_focused && focused_item == i; + h_flex().w_full().overflow_hidden().gap_3().children( + vec![ + ("One Dark", "One Dark"), + ("Gruvbox Dark", "Gruvbox Dark"), + ("One Light", "One Light"), + ("Gruvbox Light", "Gruvbox Light"), + ] + .into_iter() + .enumerate() + .map(|(i, (label, theme_name))| { + let is_selected = current_theme.name == *theme_name; + let is_focused = is_page_focused && focused_item == i; - v_flex() - .gap_2() - .child( - div() - .id("theme-item") - .when(is_focused, |this| { - this.border_2().border_color( - cx.theme().colors().border_focused, - ) - }) - .rounded_md() - .p_1() - .id(("theme", i)) - .child( - if let Ok(theme) = - theme_registry.get(theme_name) - { - ThemePreviewTile::new( - theme, - is_selected, - 0.5, - ) - .into_any_element() - } else { - div() - .w(px(200.)) - .h(px(120.)) - .bg(cx - .theme() - .colors() - .surface_background) - .rounded_md() - .into_any_element() - }, - ) - .on_click(cx.listener( - move |this, _, window, cx| { - SettingsStore::update_global(cx, move |store, cx| { - let mut settings = store.raw_user_settings().clone(); - settings["theme"] = serde_json::json!(theme_name); - store.set_user_settings(&settings.to_string(), cx).ok(); - }); - cx.notify(); - }, - )), - ) - .child(Label::new(label).size(LabelSize::Small).color( - if is_selected { - Color::Default + v_flex() + .flex_1() + .gap_1p5() + .justify_center() + .text_center() + .child( + div() + .id(("theme", i)) + .rounded(px(8.)) + .h(px(90.)) + .w_full() + .overflow_hidden() + .border_1() + .border_color(if is_focused { + cx.theme().colors().border_focused } else { - Color::Muted - }, - )) - }, - )), + transparent_black() + }) + .child( + if let Ok(theme) = theme_registry.get(theme_name) { + ThemePreviewTile::new(theme, is_selected, 0.5) + .into_any_element() + } else { + div() + .size_full() + .bg(cx.theme().colors().surface_background) + .rounded_md() + .into_any_element() + }, + ) + .on_click(cx.listener(move |this, _, window, cx| { + SettingsStore::update_global( + cx, + move |store, cx| { + let mut settings = + store.raw_user_settings().clone(); + settings["theme"] = + serde_json::json!(theme_name); + store + .set_user_settings( + &settings.to_string(), + cx, + ) + .ok(); + }, + ); + cx.notify(); + })), + ) + .child( + div() + .text_color(cx.theme().colors().text) + .text_size(px(12.)) + .child(label), + ) + }), + ), ), ) // Keymap selector section @@ -851,34 +846,42 @@ impl OnboardingUI { .color(Color::Muted), ) .on_click(cx.listener(move |this, _, window, cx| { - SettingsStore::update_global(cx, move |store, cx| { - let base_keymap = match label { - "Zed" => "None", - "Atom" => "Atom", - "JetBrains" => "JetBrains", - "Sublime" => "SublimeText", - "VSCode" => "VSCode", - "Emacs" => "Emacs", - "TextMate" => "TextMate", - _ => "VSCode", - }; - let mut settings = store.raw_user_settings().clone(); - settings["base_keymap"] = serde_json::json!(base_keymap); - store.set_user_settings(&settings.to_string(), cx).ok(); - }); + SettingsStore::update_global( + cx, + move |store, cx| { + let base_keymap = match label { + "Zed" => "None", + "Atom" => "Atom", + "JetBrains" => "JetBrains", + "Sublime" => "SublimeText", + "VSCode" => "VSCode", + "Emacs" => "Emacs", + "TextMate" => "TextMate", + _ => "VSCode", + }; + let mut settings = + store.raw_user_settings().clone(); + settings["base_keymap"] = + serde_json::json!(base_keymap); + store + .set_user_settings( + &settings.to_string(), + cx, + ) + .ok(); + }, + ); cx.notify(); })), ) - .child( - Label::new(label) - .size(LabelSize::Small) - .color(if is_selected { - Color::Default - } else { - Color::Muted - }), - ) - }) + .child(Label::new(label).size(LabelSize::Small).color( + if is_selected { + Color::Default + } else { + Color::Muted + }, + )) + }), ), ), ) @@ -912,20 +915,13 @@ impl OnboardingUI { .border_color(cx.theme().colors().border_selected) }) .hover(|this| this.bg(cx.theme().colors().element_hover)) - .child( - div().when(vim_enabled, |this| { - this.size_full() - .flex() - .items_center() - .justify_center() - .child( - svg() - .path("M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z") - .size_3() - .text_color(cx.theme().colors().icon), - ) - }) - ), + .child(div().when(vim_enabled, |this| { + this.size_full() + .flex() + .items_center() + .justify_center() + .child(Icon::new(IconName::Check)) + })), ) .child(Label::new("Enable Vim Mode")) .cursor_pointer() @@ -963,20 +959,13 @@ impl OnboardingUI { .border_color(cx.theme().colors().border_selected) }) .hover(|this| this.bg(cx.theme().colors().element_hover)) - .child( - div().when(crash_reports_enabled, |this| { - this.size_full() - .flex() - .items_center() - .justify_center() - .child( - svg() - .path("M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z") - .size_3() - .text_color(cx.theme().colors().icon), - ) - }) - ), + .child(div().when(crash_reports_enabled, |this| { + this.size_full() + .flex() + .items_center() + .justify_center() + .child(Icon::new(IconName::Check)) + })), ) .child(Label::new("Send Crash Reports")) .cursor_pointer() @@ -987,7 +976,8 @@ impl OnboardingUI { if settings.get("telemetry").is_none() { settings["telemetry"] = serde_json::json!({}); } - settings["telemetry"]["diagnostics"] = serde_json::json!(!current); + settings["telemetry"]["diagnostics"] = + serde_json::json!(!current); store.set_user_settings(&settings.to_string(), cx).ok(); }); })) @@ -1017,20 +1007,13 @@ impl OnboardingUI { .border_color(cx.theme().colors().border_selected) }) .hover(|this| this.bg(cx.theme().colors().element_hover)) - .child( - div().when(telemetry_enabled, |this| { - this.size_full() - .flex() - .items_center() - .justify_center() - .child( - svg() - .path("M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z") - .size_3() - .text_color(cx.theme().colors().icon), - ) - }) - ), + .child(div().when(telemetry_enabled, |this| { + this.size_full() + .flex() + .items_center() + .justify_center() + .child(Icon::new(IconName::Check)) + })), ) .child(Label::new("Send Telemetry")) .cursor_pointer() @@ -1183,28 +1166,6 @@ impl OnboardingUI { ) .into_any_element() } - - fn render_keyboard_help(&self, cx: &mut Context) -> AnyElement { - let help_text = match self.focus_area { - FocusArea::Navigation => { - "Use ↑/↓ to navigate • Enter to select page • Tab to switch to page content" - } - FocusArea::PageContent => { - "Use ↑/↓ to navigate • Enter to activate • Esc to return to navigation" - } - }; - - h_flex() - .w_full() - .justify_center() - .p_2() - .child( - Label::new(help_text) - .size(LabelSize::Small) - .color(Color::Muted), - ) - .into_any_element() - } } impl Item for OnboardingUI { diff --git a/crates/onboarding_ui/src/theme_preview.rs b/crates/onboarding_ui/src/theme_preview.rs index 32780e6c62..e5d2accd76 100644 --- a/crates/onboarding_ui/src/theme_preview.rs +++ b/crates/onboarding_ui/src/theme_preview.rs @@ -34,7 +34,7 @@ impl RenderOnce for ThemePreviewTile { let root_radius = px(8.0); let root_border = px(2.0); - let root_padding = px(2.0); + let root_padding = px(0.0); let child_border = px(1.0); let inner_radius = inner_corner_radius(root_radius, root_border, root_padding, child_border); From 16cfdf7b94346aa3d834fe9adac590b1d5656d2c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Tue, 1 Jul 2025 23:12:21 -0400 Subject: [PATCH 14/29] more themes -> launch theme selector --- crates/onboarding_ui/src/onboarding_ui.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 21b5999961..877e3b8451 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -8,8 +8,8 @@ use client::{Client, TelemetrySettings}; use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; use gpui::{ - Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, UpdateGlobal, WeakEntity, - actions, prelude::*, svg, transparent_black, + Action, Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, UpdateGlobal, + WeakEntity, actions, prelude::*, svg, transparent_black, }; use menu; use persistence::ONBOARDING_DB; @@ -29,6 +29,7 @@ use workspace::{ item::{Item, ItemEvent, SerializableItem}, notifications::NotifyResultExt, }; +use zed_actions; actions!( onboarding, @@ -714,8 +715,11 @@ impl OnboardingUI { .style(ButtonStyle::Subtle) .color(Color::Muted) .on_click(cx.listener(|_, _, window, cx| { - // TODO: Open theme selector - cx.notify(); + window.dispatch_action( + zed_actions::theme_selector::Toggle::default() + .boxed_clone(), + cx, + ); })), ), ) From 094c2bc32a3a603626d6681c490f4e67d472d72b Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Wed, 2 Jul 2025 00:02:27 -0400 Subject: [PATCH 15/29] Tidy up keymap section --- crates/onboarding_ui/src/onboarding_ui.rs | 58 +++++++++++++++-------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 877e3b8451..5db9634ad2 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -801,7 +801,13 @@ impl OnboardingUI { v_flex() .gap_3() .mt_4() - .child(Label::new("Pick a Keymap").size(LabelSize::Large)) + .child( + h_flex() + .h(px(32.)) + .w_full() + .justify_between() + .child(Label::new("Pick a Keymap")), + ) .child( h_flex().gap_2().children( vec![ @@ -820,19 +826,23 @@ impl OnboardingUI { let is_selected = current_keymap == label; v_flex() + .w(px(60.)) .gap_1() .items_center() + .justify_center() + .text_center() .child( - div() + h_flex() .id(("keymap", index)) - .p_3() - .rounded_md() - .bg(cx.theme().colors().element_background) + .size(px(40.)) + .rounded(px(8.)) + .items_center() + .justify_center() .border_1() .border_color(if is_selected { cx.theme().colors().border_selected } else { - cx.theme().colors().border + transparent_black() }) .when(is_focused, |this| { this.border_color( @@ -840,14 +850,25 @@ impl OnboardingUI { ) }) .when(is_selected, |this| { - this.bg(cx.theme().colors().element_selected) - }) - .hover(|this| { - this.bg(cx.theme().colors().element_hover) + this.bg(cx.theme().status().info.opacity(0.08)) }) .child( - Vector::new(icon, rems(2.), rems(2.)) - .color(Color::Muted), + h_flex() + .size(px(34.)) + .rounded(px(6.)) + .border_2() + .border_color(cx.theme().colors().border) + .items_center() + .justify_center() + .shadow_hairline() + .child( + Vector::new(icon, rems(1.25), rems(1.25)) + .color(if is_selected { + Color::Info + } else { + Color::Default + }), + ), ) .on_click(cx.listener(move |this, _, window, cx| { SettingsStore::update_global( @@ -878,13 +899,12 @@ impl OnboardingUI { cx.notify(); })), ) - .child(Label::new(label).size(LabelSize::Small).color( - if is_selected { - Color::Default - } else { - Color::Muted - }, - )) + .child( + div() + .text_color(cx.theme().colors().text) + .text_size(px(12.)) + .child(label), + ) }), ), ), From 3c5d78800b58647a3913543bc818c76137c520b1 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Wed, 2 Jul 2025 00:22:04 -0400 Subject: [PATCH 16/29] Update keymap logos --- assets/images/atom_logo.svg | 19 +++++++++++++++++++ crates/onboarding_ui/src/onboarding_ui.rs | 6 +++--- crates/ui/src/components/image.rs | 8 +++++--- 3 files changed, 27 insertions(+), 6 deletions(-) create mode 100644 assets/images/atom_logo.svg diff --git a/assets/images/atom_logo.svg b/assets/images/atom_logo.svg new file mode 100644 index 0000000000..d23ad5fe9b --- /dev/null +++ b/assets/images/atom_logo.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 5db9634ad2..84527baafd 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -812,7 +812,7 @@ impl OnboardingUI { h_flex().gap_2().children( vec![ ("Zed", VectorName::ZedLogo, 4), - ("Atom", VectorName::ZedLogo, 5), + ("Atom", VectorName::AtomLogo, 5), ("JetBrains", VectorName::ZedLogo, 6), ("Sublime", VectorName::ZedLogo, 7), ("VSCode", VectorName::ZedLogo, 8), @@ -826,7 +826,7 @@ impl OnboardingUI { let is_selected = current_keymap == label; v_flex() - .w(px(60.)) + .w(px(72.)) .gap_1() .items_center() .justify_center() @@ -834,7 +834,7 @@ impl OnboardingUI { .child( h_flex() .id(("keymap", index)) - .size(px(40.)) + .size(px(48.)) .rounded(px(8.)) .items_center() .justify_center() diff --git a/crates/ui/src/components/image.rs b/crates/ui/src/components/image.rs index 2deba68d88..c4d0389e43 100644 --- a/crates/ui/src/components/image.rs +++ b/crates/ui/src/components/image.rs @@ -12,11 +12,13 @@ use crate::prelude::*; )] #[strum(serialize_all = "snake_case")] pub enum VectorName { + AiGrid, + AtomLogo, + DebuggerGrid, + Grid, + SublimeLogo, ZedLogo, ZedXCopilot, - Grid, - AiGrid, - DebuggerGrid, } impl VectorName { From 66b36b772fc72d9719550dcd6f5886e8af1469a4 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Wed, 2 Jul 2025 10:15:52 -0400 Subject: [PATCH 17/29] Clean up unused --- crates/ui/src/components/button/split_button.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/crates/ui/src/components/button/split_button.rs b/crates/ui/src/components/button/split_button.rs index 372da9f204..235b7d04bf 100644 --- a/crates/ui/src/components/button/split_button.rs +++ b/crates/ui/src/components/button/split_button.rs @@ -1,7 +1,4 @@ -use gpui::{ - AnyElement, App, BoxShadow, IntoElement, ParentElement, RenderOnce, Styled, Window, div, hsla, - point, px, -}; +use gpui::{AnyElement, App, IntoElement, ParentElement, RenderOnce, Styled, Window, div}; use theme::ActiveTheme; use crate::{ElevationIndex, h_flex}; From bff1f1c78a54f24eea5686bd90a2c248d9124d99 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 3 Jul 2025 09:47:01 -0400 Subject: [PATCH 18/29] Remove unused welcome ui module --- crates/welcome/src/welcome.rs | 1 - crates/welcome/src/welcome_ui.rs | 1 - .../welcome/src/welcome_ui/theme_preview.rs | 280 ------------------ 3 files changed, 282 deletions(-) delete mode 100644 crates/welcome/src/welcome_ui.rs delete mode 100644 crates/welcome/src/welcome_ui/theme_preview.rs diff --git a/crates/welcome/src/welcome.rs b/crates/welcome/src/welcome.rs index 31b5cb4325..eed49af766 100644 --- a/crates/welcome/src/welcome.rs +++ b/crates/welcome/src/welcome.rs @@ -23,7 +23,6 @@ pub use multibuffer_hint::*; mod base_keymap_picker; mod base_keymap_setting; mod multibuffer_hint; -mod welcome_ui; actions!(welcome, [ResetHints]); diff --git a/crates/welcome/src/welcome_ui.rs b/crates/welcome/src/welcome_ui.rs deleted file mode 100644 index 622b6f448d..0000000000 --- a/crates/welcome/src/welcome_ui.rs +++ /dev/null @@ -1 +0,0 @@ -mod theme_preview; diff --git a/crates/welcome/src/welcome_ui/theme_preview.rs b/crates/welcome/src/welcome_ui/theme_preview.rs deleted file mode 100644 index b3a80c74c3..0000000000 --- a/crates/welcome/src/welcome_ui/theme_preview.rs +++ /dev/null @@ -1,280 +0,0 @@ -#![allow(unused, dead_code)] -use gpui::{Hsla, Length}; -use std::sync::Arc; -use theme::{Theme, ThemeRegistry}; -use ui::{ - IntoElement, RenderOnce, component_prelude::Documented, prelude::*, utils::inner_corner_radius, -}; - -/// Shows a preview of a theme as an abstract illustration -/// of a thumbnail-sized editor. -#[derive(IntoElement, RegisterComponent, Documented)] -pub struct ThemePreviewTile { - theme: Arc, - selected: bool, - seed: f32, -} - -impl ThemePreviewTile { - pub fn new(theme: Arc, selected: bool, seed: f32) -> Self { - Self { - theme, - selected, - seed, - } - } - - pub fn selected(mut self, selected: bool) -> Self { - self.selected = selected; - self - } -} - -impl RenderOnce for ThemePreviewTile { - fn render(self, _window: &mut ui::Window, _cx: &mut ui::App) -> impl IntoElement { - let color = self.theme.colors(); - - let root_radius = px(8.0); - let root_border = px(2.0); - let root_padding = px(2.0); - let child_border = px(1.0); - let inner_radius = - inner_corner_radius(root_radius, root_border, root_padding, child_border); - - let item_skeleton = |w: Length, h: Pixels, bg: Hsla| div().w(w).h(h).rounded_full().bg(bg); - - let skeleton_height = px(4.); - - let sidebar_seeded_width = |seed: f32, index: usize| { - let value = (seed * 1000.0 + index as f32 * 10.0).sin() * 0.5 + 0.5; - 0.5 + value * 0.45 - }; - - let sidebar_skeleton_items = 8; - - let sidebar_skeleton = (0..sidebar_skeleton_items) - .map(|i| { - let width = sidebar_seeded_width(self.seed, i); - item_skeleton( - relative(width).into(), - skeleton_height, - color.text.alpha(0.45), - ) - }) - .collect::>(); - - let sidebar = div() - .h_full() - .w(relative(0.25)) - .border_r(px(1.)) - .border_color(color.border_transparent) - .bg(color.panel_background) - .child( - div() - .p_2() - .flex() - .flex_col() - .size_full() - .gap(px(4.)) - .children(sidebar_skeleton), - ); - - let pseudo_code_skeleton = |theme: Arc, seed: f32| -> AnyElement { - let colors = theme.colors(); - let syntax = theme.syntax(); - - let keyword_color = syntax.get("keyword").color; - let function_color = syntax.get("function").color; - let string_color = syntax.get("string").color; - let comment_color = syntax.get("comment").color; - let variable_color = syntax.get("variable").color; - let type_color = syntax.get("type").color; - let punctuation_color = syntax.get("punctuation").color; - - let syntax_colors = [ - keyword_color, - function_color, - string_color, - variable_color, - type_color, - punctuation_color, - comment_color, - ]; - - let line_width = |line_idx: usize, block_idx: usize| -> f32 { - let val = (seed * 100.0 + line_idx as f32 * 20.0 + block_idx as f32 * 5.0).sin() - * 0.5 - + 0.5; - 0.05 + val * 0.2 - }; - - let indentation = |line_idx: usize| -> f32 { - let step = line_idx % 6; - if step < 3 { - step as f32 * 0.1 - } else { - (5 - step) as f32 * 0.1 - } - }; - - let pick_color = |line_idx: usize, block_idx: usize| -> Hsla { - let idx = ((seed * 10.0 + line_idx as f32 * 7.0 + block_idx as f32 * 3.0).sin() - * 3.5) - .abs() as usize - % syntax_colors.len(); - syntax_colors[idx].unwrap_or(colors.text) - }; - - let line_count = 13; - - let lines = (0..line_count) - .map(|line_idx| { - let block_count = (((seed * 30.0 + line_idx as f32 * 12.0).sin() * 0.5 + 0.5) - * 3.0) - .round() as usize - + 2; - - let indent = indentation(line_idx); - - let blocks = (0..block_count) - .map(|block_idx| { - let width = line_width(line_idx, block_idx); - let color = pick_color(line_idx, block_idx); - item_skeleton(relative(width).into(), skeleton_height, color) - }) - .collect::>(); - - h_flex().gap(px(2.)).ml(relative(indent)).children(blocks) - }) - .collect::>(); - - v_flex() - .size_full() - .p_1() - .gap(px(6.)) - .children(lines) - .into_any_element() - }; - - let pane = div() - .h_full() - .flex_grow() - .flex() - .flex_col() - // .child( - // div() - // .w_full() - // .border_color(color.border) - // .border_b(px(1.)) - // .h(relative(0.1)) - // .bg(color.tab_bar_background), - // ) - .child( - div() - .size_full() - .overflow_hidden() - .bg(color.editor_background) - .p_2() - .child(pseudo_code_skeleton(self.theme.clone(), self.seed)), - ); - - let content = div().size_full().flex().child(sidebar).child(pane); - - div() - .size_full() - .rounded(root_radius) - .p(root_padding) - .border(root_border) - .border_color(color.border_transparent) - .when(self.selected, |this| { - this.border_color(color.border_selected) - }) - .child( - div() - .size_full() - .rounded(inner_radius) - .border(child_border) - .border_color(color.border) - .bg(color.background) - .child(content), - ) - } -} - -impl Component for ThemePreviewTile { - fn description() -> Option<&'static str> { - Some(Self::DOCS) - } - - fn preview(_window: &mut Window, cx: &mut App) -> Option { - let theme_registry = ThemeRegistry::global(cx); - - let one_dark = theme_registry.get("One Dark"); - let one_light = theme_registry.get("One Light"); - let gruvbox_dark = theme_registry.get("Gruvbox Dark"); - let gruvbox_light = theme_registry.get("Gruvbox Light"); - - let themes_to_preview = vec![ - one_dark.clone().ok(), - one_light.clone().ok(), - gruvbox_dark.clone().ok(), - gruvbox_light.clone().ok(), - ] - .into_iter() - .flatten() - .collect::>(); - - Some( - v_flex() - .gap_6() - .p_4() - .children({ - if let Some(one_dark) = one_dark.ok() { - vec![example_group(vec![ - single_example( - "Default", - div() - .w(px(240.)) - .h(px(180.)) - .child(ThemePreviewTile::new(one_dark.clone(), false, 0.42)) - .into_any_element(), - ), - single_example( - "Selected", - div() - .w(px(240.)) - .h(px(180.)) - .child(ThemePreviewTile::new(one_dark, true, 0.42)) - .into_any_element(), - ), - ])] - } else { - vec![] - } - }) - .child( - example_group(vec![single_example( - "Default Themes", - h_flex() - .gap_4() - .children( - themes_to_preview - .iter() - .enumerate() - .map(|(i, theme)| { - div().w(px(200.)).h(px(140.)).child(ThemePreviewTile::new( - theme.clone(), - false, - 0.42, - )) - }) - .collect::>(), - ) - .into_any_element(), - )]) - .grow(), - ) - .into_any_element(), - ) - } -} From 8fde323dd007de498aea38248bd5e86e6e39fd61 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 3 Jul 2025 10:07:30 -0400 Subject: [PATCH 19/29] Stub out KeyboardNavigation --- crates/ui/src/components.rs | 2 + .../ui/src/components/keyboard_navigation.rs | 59 +++++++++++++++++++ 2 files changed, 61 insertions(+) create mode 100644 crates/ui/src/components/keyboard_navigation.rs diff --git a/crates/ui/src/components.rs b/crates/ui/src/components.rs index 6e3c7c78ae..e23d76a84b 100644 --- a/crates/ui/src/components.rs +++ b/crates/ui/src/components.rs @@ -15,6 +15,7 @@ mod indent_guides; mod indicator; mod keybinding; mod keybinding_hint; +mod keyboard_navigation; mod label; mod list; mod modal; @@ -56,6 +57,7 @@ pub use indent_guides::*; pub use indicator::*; pub use keybinding::*; pub use keybinding_hint::*; +pub use keyboard_navigation::*; pub use label::*; pub use list::*; pub use modal::*; diff --git a/crates/ui/src/components/keyboard_navigation.rs b/crates/ui/src/components/keyboard_navigation.rs new file mode 100644 index 0000000000..2a624cb3a3 --- /dev/null +++ b/crates/ui/src/components/keyboard_navigation.rs @@ -0,0 +1,59 @@ +use gpui::{Focusable, actions}; + +actions!( + keyboard_navigation, + [NextRow, PreviousRow, NextColumn, PreviousColumn] +); + +/// Implement this trait to enable grid-like keyboard navigation for a layout. +/// +/// This trait allows you to navigate through a layout of rows with mixed column +/// lengths. In example, a layout might have rows with 5, 1 and 3 columns. +/// +/// Moving up or down between rows will focus the first element in the next or previous row. +/// Moving left or right between columns will focus the next or previous element in the same row. +/// +/// Wrapping can be enabled via `vertical_wrapping` and `horizontal_wrapping` respectively. +pub trait KeyboardNavigation: Focusable { + fn has_focus(&self) -> bool; + /// The focused row. Always has a value to allow for "focused inactive" states. + fn focused_row(&self) -> usize; + /// The focused column. Always has a value to allow for "focused inactive" states. + fn focused_column(&self) -> usize; + /// Focus the first focusable element in the layout. + fn focus_first(&self); + /// Focus the next row, wrapping back to the first row if necessary. + /// + /// Is a no-op if wrapping is not enabled. + fn focus_next_row(&self); + /// Focus the previous row, wrapping back to the last row if necessary. + /// + /// Is a no-op if wrapping is not enabled. + fn focus_previous_row(&self); + /// Focus the next column, wrapping back to the first column if necessary. + /// + /// Is a no-op if wrapping is not enabled. + fn focus_next_column(&self); + /// Focus the previous column, wrapping back to the last column if necessary. + /// + /// Is a no-op if wrapping is not enabled. + fn focus_previous_column(&self); + /// Focus the row at the given index. + fn focus_row_index(&self, index: usize); + /// Focus the column at the given index. + fn focus_column_index(&self, ix: usize); + /// When reaching the last row, should moving down wrap + /// back to the first row, and vice versa? + fn vertical_wrap(&self) -> bool { + false + } + /// When reaching the last column, should moving right wrap + /// back to the first column, and vice versa? + fn horizontal_wrap(&self) -> bool { + false + } +} + +pub struct NavigationRow {} + +pub struct NavigationColumn {} From b31af62d423f0e6f2c0949cf77f80fb83de74472 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 3 Jul 2025 13:37:49 -0400 Subject: [PATCH 20/29] Refinement --- crates/onboarding_ui/src/onboarding_ui.rs | 71 +++---- crates/onboarding_ui/src/theme_preview.rs | 4 +- crates/ui/src/components.rs | 2 + crates/ui/src/components/ring.rs | 66 +++++++ crates/ui/src/utils.rs | 2 +- crates/ui/src/utils/corner_solver.rs | 225 +++++++++++++++++----- 6 files changed, 289 insertions(+), 81 deletions(-) create mode 100644 crates/ui/src/components/ring.rs diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 84527baafd..ea71a584f8 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -8,8 +8,8 @@ use client::{Client, TelemetrySettings}; use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; use gpui::{ - Action, Entity, EventEmitter, FocusHandle, Focusable, KeyBinding, Task, UpdateGlobal, - WeakEntity, actions, prelude::*, svg, transparent_black, + Action, Entity, EventEmitter, FocusHandle, Focusable, FontWeight, KeyBinding, Task, + UpdateGlobal, WeakEntity, actions, prelude::*, svg, transparent_black, }; use menu; use persistence::ONBOARDING_DB; @@ -20,7 +20,7 @@ use settings::{Settings, SettingsStore}; use settings_ui::SettingsUiFeatureFlag; use std::sync::Arc; use theme::{Theme, ThemeRegistry, ThemeSettings}; -use ui::{ListItem, ToggleState, Vector, VectorName, prelude::*}; +use ui::{KeybindingHint, ListItem, Ring, ToggleState, Vector, VectorName, prelude::*}; use util::ResultExt; use vim_mode_setting::VimModeSetting; use welcome::BaseKeymap; @@ -567,7 +567,7 @@ impl OnboardingUI { v_flex() .gap_px() .py(px(16.)) - .gap(px(12.)) + .gap(px(2.)) .child(self.render_nav_item( OnboardingPage::Basics, "The Basics", @@ -604,12 +604,13 @@ impl OnboardingUI { shortcut: impl Into, cx: &mut Context, ) -> impl gpui::IntoElement { - let selected = self.current_page == page; + let is_selected = self.current_page == page; let label = label.into(); let shortcut = shortcut.into(); let id = ElementId::Name(label.clone()); + let corner_radius = px(4.); - let is_focused = match page { + let item_focused = match page { OnboardingPage::Basics => self.nav_focus == NavigationFocusItem::Basics, OnboardingPage::Editing => self.nav_focus == NavigationFocusItem::Editing, OnboardingPage::AiSetup => self.nav_focus == NavigationFocusItem::AiSetup, @@ -618,35 +619,39 @@ impl OnboardingUI { let area_focused = self.focus_area == FocusArea::Navigation; - h_flex() - .id(id) - .h(rems(1.5)) - .w_full() - .when(is_focused, |this| { - this.bg(if area_focused { - cx.theme().colors().border_focused.opacity(0.16) - } else { - cx.theme().colors().border.opacity(0.24) - }) - }) - .child( - div() - .w(px(3.)) - .h_full() - .when(selected, |this| this.bg(cx.theme().colors().border_focused)), - ) + Ring::new(corner_radius, item_focused) + .active(area_focused && item_focused) .child( h_flex() - .pl(px(23.)) - .flex_1() - .justify_between() - .items_center() - .child(Label::new(label).when(is_focused, |this| this.color(Color::Default))) - .child(Label::new(format!("⌘{}", shortcut.clone())).color(Color::Muted)), + .id(id) + .h(rems(1.625)) + .w_full() + .rounded(corner_radius) + .px_3() + .when(is_selected, |this| { + this.bg(cx.theme().colors().border_focused.opacity(0.16)) + }) + .child( + h_flex() + .flex_1() + .justify_between() + .items_center() + .child( + Label::new(label) + .weight(FontWeight::MEDIUM) + .color(Color::Muted) + .when(item_focused, |this| this.color(Color::Default)), + ) + .child( + Label::new(format!("⌘{}", shortcut.clone())) + .color(Color::Placeholder) + .size(LabelSize::XSmall), + ), + ) + .on_click(cx.listener(move |this, _, window, cx| { + this.jump_to_page(page, window, cx); + })), ) - .on_click(cx.listener(move |this, _, window, cx| { - this.jump_to_page(page, window, cx); - })) } fn render_bottom_controls( @@ -654,7 +659,7 @@ impl OnboardingUI { window: &mut gpui::Window, cx: &mut Context, ) -> impl gpui::IntoElement { - h_flex().w_full().p(px(12.)).pl(px(24.)).child( + h_flex().w_full().p(px(12.)).child( JuicyButton::new(if self.current_page == OnboardingPage::Welcome { "Get Started" } else { diff --git a/crates/onboarding_ui/src/theme_preview.rs b/crates/onboarding_ui/src/theme_preview.rs index e5d2accd76..28c9f0f231 100644 --- a/crates/onboarding_ui/src/theme_preview.rs +++ b/crates/onboarding_ui/src/theme_preview.rs @@ -2,7 +2,7 @@ use gpui::{Hsla, Length}; use std::sync::Arc; use theme::{Theme, ThemeRegistry}; -use ui::{IntoElement, RenderOnce, prelude::*, utils::inner_corner_radius}; +use ui::{IntoElement, RenderOnce, prelude::*, utils::CornerSolver}; /// Shows a preview of a theme as an abstract illustration /// of a thumbnail-sized editor. @@ -37,7 +37,7 @@ impl RenderOnce for ThemePreviewTile { let root_padding = px(0.0); let child_border = px(1.0); let inner_radius = - inner_corner_radius(root_radius, root_border, root_padding, child_border); + CornerSolver::child_radius(root_radius, root_border, root_padding, child_border); let item_skeleton = |w: Length, h: Pixels, bg: Hsla| div().w(w).h(h).rounded_full().bg(bg); diff --git a/crates/ui/src/components.rs b/crates/ui/src/components.rs index e23d76a84b..176f1ec5c5 100644 --- a/crates/ui/src/components.rs +++ b/crates/ui/src/components.rs @@ -27,6 +27,7 @@ mod popover_menu; mod progress; mod radio; mod right_click_menu; +mod ring; mod scrollbar; mod settings_container; mod settings_group; @@ -69,6 +70,7 @@ pub use popover_menu::*; pub use progress::*; pub use radio::*; pub use right_click_menu::*; +pub use ring::*; pub use scrollbar::*; pub use settings_container::*; pub use settings_group::*; diff --git a/crates/ui/src/components/ring.rs b/crates/ui/src/components/ring.rs new file mode 100644 index 0000000000..59047d2d6d --- /dev/null +++ b/crates/ui/src/components/ring.rs @@ -0,0 +1,66 @@ +use gpui::{ + AnyElement, IntoElement, ParentElement, Pixels, RenderOnce, Styled, px, transparent_black, +}; +use smallvec::SmallVec; +use theme::ActiveTheme; + +use crate::{h_flex, utils::CornerSolver}; + +/// A ring is a stylistic focus indicator that draws a ring around +/// an element with some space between the element and ring. +#[derive(IntoElement)] +pub struct Ring { + corner_radius: Pixels, + border_width: Pixels, + padding: Pixels, + focused: bool, + active: bool, + children: SmallVec<[AnyElement; 2]>, +} + +impl Ring { + pub fn new(child_corner_radius: Pixels, focused: bool) -> Self { + let border_width = px(1.); + let padding = px(2.); + let corner_radius = + CornerSolver::parent_radius(child_corner_radius, border_width, padding, px(0.)); + Self { + corner_radius, + border_width, + padding, + focused, + active: false, + children: SmallVec::new(), + } + } + + pub fn active(mut self, active: bool) -> Self { + self.active = active; + self + } +} + +impl RenderOnce for Ring { + fn render(self, window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement { + let border_color = if self.focused && self.active { + cx.theme().colors().border_focused.opacity(0.48) + } else if self.focused { + cx.theme().colors().border_variant + } else { + transparent_black() + }; + + h_flex() + .border(self.border_width) + .border_color(border_color) + .rounded(self.corner_radius) + .p(self.padding) + .children(self.children) + } +} + +impl ParentElement for Ring { + fn extend(&mut self, elements: impl IntoIterator) { + self.children.extend(elements) + } +} diff --git a/crates/ui/src/utils.rs b/crates/ui/src/utils.rs index 26a59001f6..bcb4241ea4 100644 --- a/crates/ui/src/utils.rs +++ b/crates/ui/src/utils.rs @@ -10,7 +10,7 @@ mod search_input; mod with_rem_size; pub use color_contrast::*; -pub use corner_solver::{CornerSolver, inner_corner_radius}; +pub use corner_solver::{CornerSolver, NestedCornerSolver}; pub use format_distance::*; pub use search_input::*; pub use with_rem_size::*; diff --git a/crates/ui/src/utils/corner_solver.rs b/crates/ui/src/utils/corner_solver.rs index c49bccc445..38813c303c 100644 --- a/crates/ui/src/utils/corner_solver.rs +++ b/crates/ui/src/utils/corner_solver.rs @@ -1,61 +1,196 @@ use gpui::Pixels; -/// Calculates the child’s content-corner radius for a single nested level. +/// Calculates corner radii for nested elements in both directions. /// -/// child_content_radius = max(0, parent_radius - parent_border - parent_padding + self_border) +/// ## Forward calculation (parent → child) +/// Given a parent's corner radius, calculates the child's corner radius: +/// ``` +/// child_radius = max(0, parent_radius - parent_border - parent_padding + child_border) +/// ``` /// -/// - parent_radius: outer corner radius of the parent element -/// - parent_border: border width of the parent element -/// - parent_padding: padding of the parent element -/// - self_border: border width of this child element (for content inset) -pub fn inner_corner_radius( - parent_radius: Pixels, - parent_border: Pixels, - parent_padding: Pixels, - self_border: Pixels, -) -> Pixels { - (parent_radius - parent_border - parent_padding + self_border).max(Pixels::ZERO) -} - -/// Solver for arbitrarily deep nested corner radii. -/// -/// Each nested level’s outer border-box radius is: -/// R₀ = max(0, root_radius - root_border - root_padding) -/// Rᵢ = max(0, Rᵢ₋₁ - childᵢ₋₁_border - childᵢ₋₁_padding) for i > 0 -pub struct CornerSolver { - root_radius: Pixels, - root_border: Pixels, - root_padding: Pixels, - children: Vec<(Pixels, Pixels)>, // (border, padding) -} +/// ## Inverse calculation (child → parent) +/// Given a child's desired corner radius, calculates the required parent radius: +/// ``` +/// parent_radius = child_radius + parent_border + parent_padding - child_border +/// ``` +pub struct CornerSolver; impl CornerSolver { - pub fn new(root_radius: Pixels, root_border: Pixels, root_padding: Pixels) -> Self { - Self { - root_radius, - root_border, - root_padding, - children: Vec::new(), - } + /// Calculates the child's corner radius given the parent's properties. + /// + /// # Arguments + /// - `parent_radius`: Outer corner radius of the parent element + /// - `parent_border`: Border width of the parent element + /// - `parent_padding`: Padding of the parent element + /// - `child_border`: Border width of the child element + pub fn child_radius( + parent_radius: Pixels, + parent_border: Pixels, + parent_padding: Pixels, + child_border: Pixels, + ) -> Pixels { + (parent_radius - parent_border - parent_padding + child_border).max(Pixels::ZERO) } - pub fn add_child(mut self, border: Pixels, padding: Pixels) -> Self { - self.children.push((border, padding)); + /// Calculates the required parent radius to achieve a desired child radius. + /// + /// # Arguments + /// - `child_radius`: Desired corner radius for the child element + /// - `parent_border`: Border width of the parent element + /// - `parent_padding`: Padding of the parent element + /// - `child_border`: Border width of the child element + pub fn parent_radius( + child_radius: Pixels, + parent_border: Pixels, + parent_padding: Pixels, + child_border: Pixels, + ) -> Pixels { + child_radius + parent_border + parent_padding - child_border + } +} + +/// Builder for calculating corner radii across multiple nested levels. +pub struct NestedCornerSolver { + levels: Vec, +} + +#[derive(Debug, Clone, Copy)] +struct Level { + border: Pixels, + padding: Pixels, +} + +impl NestedCornerSolver { + /// Creates a new nested corner solver. + pub fn new() -> Self { + Self { levels: Vec::new() } + } + + /// Adds a level to the nesting hierarchy. + /// + /// Levels should be added from outermost to innermost. + pub fn add_level(mut self, border: Pixels, padding: Pixels) -> Self { + self.levels.push(Level { border, padding }); self } - pub fn corner_radius(&self, level: usize) -> Pixels { - if level == 0 { - return (self.root_radius - self.root_border - self.root_padding).max(Pixels::ZERO); + /// Calculates the corner radius at a specific nesting level given the root radius. + /// + /// # Arguments + /// - `root_radius`: The outermost corner radius + /// - `level`: The nesting level (0 = first child of root, 1 = grandchild, etc.) + pub fn radius_at_level(&self, root_radius: Pixels, level: usize) -> Pixels { + let mut radius = root_radius; + + for i in 0..=level.min(self.levels.len().saturating_sub(1)) { + let current_level = &self.levels[i]; + let next_border = if i < self.levels.len() - 1 { + self.levels[i + 1].border + } else { + Pixels::ZERO + }; + + radius = CornerSolver::child_radius( + radius, + current_level.border, + current_level.padding, + next_border, + ); } - if level >= self.children.len() { - return Pixels::ZERO; + + radius + } + + /// Calculates the required root radius to achieve a desired radius at a specific level. + /// + /// # Arguments + /// - `target_radius`: The desired corner radius at the target level + /// - `target_level`: The nesting level where the target radius should be achieved + pub fn root_radius_for_level(&self, target_radius: Pixels, target_level: usize) -> Pixels { + if target_level >= self.levels.len() { + return target_radius; } - let mut r = (self.root_radius - self.root_border - self.root_padding).max(Pixels::ZERO); - for i in 0..level { - let (b, p) = self.children[i]; - r = (r - b - p).max(Pixels::ZERO); + + let mut radius = target_radius; + + // Work backwards from the target level to the root + for i in (0..=target_level).rev() { + let current_level = &self.levels[i]; + let child_border = if i < self.levels.len() - 1 { + self.levels[i + 1].border + } else { + Pixels::ZERO + }; + + radius = CornerSolver::parent_radius( + radius, + current_level.border, + current_level.padding, + child_border, + ); } - r + + radius + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_forward_calculation() { + let parent_radius = Pixels(20.0); + let parent_border = Pixels(2.0); + let parent_padding = Pixels(8.0); + let child_border = Pixels(1.0); + + let child_radius = + CornerSolver::child_radius(parent_radius, parent_border, parent_padding, child_border); + + assert_eq!(child_radius, Pixels(11.0)); // 20 - 2 - 8 + 1 = 11 + } + + #[test] + fn test_inverse_calculation() { + let child_radius = Pixels(11.0); + let parent_border = Pixels(2.0); + let parent_padding = Pixels(8.0); + let child_border = Pixels(1.0); + + let parent_radius = + CornerSolver::parent_radius(child_radius, parent_border, parent_padding, child_border); + + assert_eq!(parent_radius, Pixels(20.0)); // 11 + 2 + 8 - 1 = 20 + } + + #[test] + fn test_nested_forward() { + let solver = NestedCornerSolver::new() + .add_level(Pixels(2.0), Pixels(8.0)) // Root level + .add_level(Pixels(1.0), Pixels(4.0)) // First child + .add_level(Pixels(1.0), Pixels(2.0)); // Second child + + let root_radius = Pixels(20.0); + + assert_eq!(solver.radius_at_level(root_radius, 0), Pixels(11.0)); // 20 - 2 - 8 + 1 + assert_eq!(solver.radius_at_level(root_radius, 1), Pixels(7.0)); // 11 - 1 - 4 + 1 + assert_eq!(solver.radius_at_level(root_radius, 2), Pixels(4.0)); // 7 - 1 - 2 + 0 + } + + #[test] + fn test_nested_inverse() { + let solver = NestedCornerSolver::new() + .add_level(Pixels(2.0), Pixels(8.0)) // Root level + .add_level(Pixels(1.0), Pixels(4.0)) // First child + .add_level(Pixels(1.0), Pixels(2.0)); // Second child + + let target_radius = Pixels(4.0); + let root_radius = solver.root_radius_for_level(target_radius, 2); + + assert_eq!(root_radius, Pixels(20.0)); + + // Verify by calculating forward + assert_eq!(solver.radius_at_level(root_radius, 2), target_radius); } } From fe9ef209a846fa48661e2e96248447072198e236 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 3 Jul 2025 14:04:18 -0400 Subject: [PATCH 21/29] Start scaffolding out ai section --- assets/fonts/plex-sans/ZedPlexSans-Medium.ttf | Bin 0 -> 218268 bytes .../plex-sans/ZedPlexSans-MediumItalic.ttf | Bin 0 -> 233604 bytes crates/onboarding_ui/src/onboarding_ui.rs | 55 +++++++++--------- crates/ui/src/components/ring.rs | 2 +- 4 files changed, 27 insertions(+), 30 deletions(-) create mode 100644 assets/fonts/plex-sans/ZedPlexSans-Medium.ttf create mode 100644 assets/fonts/plex-sans/ZedPlexSans-MediumItalic.ttf diff --git a/assets/fonts/plex-sans/ZedPlexSans-Medium.ttf b/assets/fonts/plex-sans/ZedPlexSans-Medium.ttf new file mode 100644 index 0000000000000000000000000000000000000000..fb75072d87cd07ec19d5a9e05df64ed26f430fe9 GIT binary patch literal 218268 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 literal 0 HcmV?d00001 diff --git a/assets/fonts/plex-sans/ZedPlexSans-MediumItalic.ttf b/assets/fonts/plex-sans/ZedPlexSans-MediumItalic.ttf new file mode 100644 index 0000000000000000000000000000000000000000..1b059bebd5de8f312e3cab5b53ddac640ce948e0 GIT binary patch literal 233604 zcmZQzWME(rVq{=oVNh^)adi{Y6I#o_!1#cHfx*W;z&}`c+lr|Sj2j*>Fy3F}9vte# ze3Z|Ifk7mJfr0agf3Ut$?}lbaEmeUFfcIIFfcG^r4^*-hIjJ|Ffiz9Ffi~przaK{FmN(RGcYiM z^z)?WRHnu8aaJ-gDJE+9Kz_@~efx#>zBQ=qulWQUa17idO1A|IN zZb`-TGj&%P7;M%sFz}zq$xlvfG%|8wU|{ZHU|@fin^;l6`bJ;HcSeo(kEe`2U%U}q>{U}a!p5Ma<}n8m=r=)m91z|6o1l4oK3_m+WymFM60fBRUD zF~49q!GHvqKQR_EurYBk@G$LS;9+{gz{4a13Y-65{#*S2!sz+`*Z;WxU*H-*@x*Lg zy7PvtNj$&JR|YQT7a+N763yR1^y6hmGyi@6_mAZmOAZ4Q0~-SqNR)vA*|# z7Xu@MIRhiZA%?>YObkaDl^GZrRTxzmm>5+Vk1;SZ9%nqxz{GfhNuGg`NtM}&fsuJG z^Bx9f<}=JUp}yi^U}j)o5CM}q3{2(e86}MB3=HKdB^itc42+p2i8+kM3``7i3_=WS z;1FYAGzPl@6ediJMhq!XS1~Z^GD7^v!sNsFg@KiUfoTs@7Xt%B4}@mC%izms$ic|O z&C1Nm#LU3Nynun}eE@@kHP|-{3=E!5z6uPD3=04MLc*FQfl*k2fpI=ao{58L7bun) zm>etxwFE->L-;~@wRl3gwYWkBBKabDBDo?twKziAwb(*gwOB%#wU|N~Ll{CiBH1EY zBAFr?A_W+j_ktYFz{w)XZi$U1p%m=GMXiJ5^x)+ur$6O(gb#6}k8zDOqqZ5Y%B0c4H@0|SFJLnFgi zMnA@W#xG0}O#RH7%rjW@Sjt&8v%FzdV6|gi$NG)UiER$scXkE#687cnpEv|K+&Kz3 z=5ie3c+cs~*~+#$;)deR;-TW{;+5ia#n+1O6n`fEN&KILkc6Csk3^M3o5UoEJrXA* z?n!)+WRT>MbdW5SJSHV6bbO`w6k=mbe43H44ce#nHRDQvi-8V<(%bq z$o-Sgk>4!;R)JB0SHWB%T49pHOGRcyOT}=-OvR~+o0S-pWR%pE!j+1YdXzROT~)fP z%%IGvtfOqH9IITYJXLw8ijGQ&$|Y5A)pcrGYHezd)V0-X)n90+YwXn2*PN*NTdP*< zhqjyc9_@cRMmh_1IdyAw@944XrRXitd#|6Ye^URd{saBj`rix~4R{PB43rJ@4Xg}K z7+f~EXYkVCt09Y_fT4_`hM|d}v!TCXv|+kokzuW2hv8(yd4{VDw;CQaJY$q%ly6jJ z)M_-*Xo1lhqa8*^j4l}6H+pUK-I&>UrSVqd1IDLKtV~=@0!(5|?wE#~CYk1%R+u)M z_L!nRA+pn9G}MnVXtBn0uRtneQ||YW~># zo%v4-77Kn0DGOB#0}C4qcZ-!4TPzM(+_rdT@ySxn(#X=*(!(;ua-!uN%jK4vE%#ZT zvJ$kCu~N4(va+@EunMt?x5~CEvud+E;hAF;n+f7|}K z{U`gs4!I5$4$TgC9G*LTcKGMWFDYh=ossm=~(L6;Mnar&2f?ATF0G^ zM;y;P-g12E_`&hF6PuHulZ=ywld+S%lb6#xrIxx8}u>dNTKO0S_4u4G$BKT#rhRR*#7ub3ImiZ1p(kan|Fe$5YQN&r;7u&&Qtc zJb!tydI@^TcxiZ9c)555c*S@f^SbDD$LodHXRm+Wb>5xcQ@x-1X!@A=IQaDX-12$q z^TFr0FPpERudJ_zuZgd{ub1y?-)+7J{aF13{AB#p{fzzW{Ji|a{F40g{Hpxg{3iL$ z^IPe+#qWUMX}@cJkNn>H{qSe@=kt&CZ}MO1e=Wc=U~a(DK;c05!1X~KLEb^rg875> zf)j(M2G0#X8KNCx9FiKcE#z;ge`tB=x-gNjfUxP|T;W3DQsGMBTH!|FR^d+J3&U52 zZw$X2emnee1Yd+$gj|GLgkMBhL|nwvh_{i(k=BuJk%5shk?E1ek#&(>ky9fVM6Qn9 z7I`r8Y~;l{6{oYBEo9 zV)FVFfs}%j-6@Atex)*{N~cDqcBf8G<4sFRJCOD+?N_>MdQJNJ^zG^U(~qa0Pk)#G zE&X2xTZVDQl1!0InM~)*`pjjSSF?Dse6t#|E@zu(H)o&CzLEVn`(5_W9L5};9E}{0 zoQj;YIX7}1=e*0c&UMcX&OM)}nP-wWIqy#1`@CQItoZ`@()sE6y9-zg;tMtxJTBBL zj4Dhmd|l*KG`*O!IH0(sxW2fncxv&2;?>0$OBhQ`OB_l%OKz4tE!8eHF6}CvR64hG zX&F-)SD8?mR9Q>e=koUQwdFg?50{@VzgGUaLb$@QVoJsQid7X`D>*AgD-|mjReq@a zT@_cgvT9@1-l~&TSF0XW8&>yJ->xyQ>8d$gD^crP8(Dj=&b}_SZhPIodgc1y`ndYc z`jYzk`u6&*^>6CGH`p|^G)!o?(r~Adv5~V;q*11^uyK3im&QL$sZE!gbDO6&KWJfT zacWu8a-mhCHK(M-kIK6 z-r3$cy>ofz_Riy-*E^qge(z%MQtR^V%I})owY}?R*Y9q*Zinuq?yl}l-PgPS^eFVW z^yKzT?OD{bzUN`DXs=IiOYhF!cYQW}U47^KMf#2U1NtlaxAlLWAU?rxg7<`?3DYN> zn(%j`@x;uDGbi4iWHKpXQqiP!lO9g`KG}7$-{kPg36nD?7fr67+%ma$^0dkGC$E@% zW%Aw0&!#X=;hLg5C1y(Ml+9Bar^ZaZJWXXd z^vt<4cg#FJ^WH3$S%$N+X3dy&f41Iir`c(s)-(1qPGVfhxPkEw<9{Y;CUd4praer@neH;PF!L}AF^e)wGb=M|FxN46G50V} zU|z_)l6fQZN#=7b(kv=0`YiD*$t>9{r7VY7ZnC^&`N^uvXD`<(H&5=T0OR_n zZyvlq^PB14|Nnpg{|C3s3>mB#92ue+G8n2E7J&V@fN?$JS;k*X5@0{>W;(`ngPDPu z4em!Z<~rsU<{sug=84RUnO8AyVm`&fz#_w<%3{Eh#FE8Q#4>^9Jj)%HcdROW_Hqq! z^W+vNFenHpNGQlCC@82YXej6_7%5nS{aB*V0QKVvg*6Hr6}BksK=WgOVz6Sg;snK& ziW?NSDegk@qo9(gk|dHJQ=oq21N)H??nf>LhW~dN82&E?$GYl&NiYp2{=NIRh2ajE z2_mL5Ol6qB(8a*;=OF{bzdH;J|JMCm%fRrj6eRht_g^1~M#Y~B7#JRhgTx**UVoS7#SWxIv9*x3=E74jA|hBm>w`aVtT^N#LNTYF)%RmF!M1>Fe^ZK z3=GUF3=GU_3=GT$AQ2GBY{TpVW|uKvVZO$EgZUnd6H6FN0ZSVL0~q(QIxsM>MzF@P zCVtYBEjP|Hxq+{w_u(9DpjmLnCt= zLo34sW>;o6<{l;mhI)qC%rlu?7+M&znWLD)nWGu<7&{o77+V?p7~2?o7-urhWn9I$ zm~k27a>hf9yBYT}?q^)Yc!}{A;}yp1j1L%ZFid2;$Hd6^oADpxeGZGRiQ@GW=#VWVB*5VKirSV6#n{DghOwF9C}TInS;pB6Ul`{xd}o}`@Ply(28ILe3GVWoN zVm!*I#CU*Fg7G+`3gZbzHO7;S>WmtUrx-OE&oF8;o@UfyJj(c3@jGKA<2S|#CU(Y5CKkpt#y^a4Ol*u9Ow5d_OstIQOu~$%OyZ1{Op;8p zjP*?NjEzikj17#Tj1L(dnK&4;7+V;QG45rQX1vB|#`u>po{5jKfQg^6kV%lSm`Q-K zh_RR9JmV~e&y4pO?HRu?hA{qMjAHI%p1?ebxr2Es^DO2T=5FT2%!`wnR%Jbm@SwsnXQ=Rm=&09m?fFTnRS`XnPxK0Vw%k~ zhiNX;e5M6ViXsh6pbsh?>A(V^_!Ys&ifmxa95wjCBBQqP*QDzRNYC zO{N#jMob@>jhQ|%+cN!OwrBds?7;M&S(KTd=^WD)W@e@X%uG!CnOT?)GxIQ=X0~Jc z%go1gmRX4DBC`n7Wo8Mc>&#+ISDBTV9x|&iJ!aNoddaNK^om)B={2(<(+6gDren+| zOrM!mnVv9-GL|z5F_tiiFqSd4Gn{1XWH`+@h2a|GG=>|D(;03u&S1F3IF;c#V?V=1 z#)%A<87DDZVVulxm2m>YCB~JEOpL1;Ss2$bvNNt{a z4E+qV7#1>@GnX=#F_%C`dbk)Fm`oU0T-*=Y7UeK>r5B}UGaSiDEXiY#Vpzw( zOFz~B(%@2kKdz`*eTKZ7V(FB7x`o{RFz_<)G4L}8FbFaTF$gn=Fo-gU zVNuVHSG^qrqmz4(0t2XaMz@I#uTB?YEeEz57^BDV3He5@`6X`#26SD)xa!K1_nk|FiV7ifl&p_5@ujv zR0gwz7#J9pz$`%q21Z4&37|TjkwF~HW(AXcV3HF|f?BwsF;h?@0TgnK4E$hm&`1|( zjFKJ9<6>Z7U}BJDkOI>nwK8n$*gDwK*wWYx*u+@xuufrZV+~<70%Idq6;?Ku4=fEV zQ7j)=d{`{l44A!`wV38HOk=Qujx%yFFfr&b2s3aoN-(N2uVOyKyps7W^Eu}8%omt1 zGGAi8%zTCUD)Tkw>&!QpZ-PflIT$z?7{IBEk$EZeQU+$`70fFbSeVx_uVY|k-oU(v zfsKKUfq{X8@d@KG#wCnBj3o?L7?v@Jfk#D!7#JBYfc*j*!DD2w#ZuOSO4^l7tC&_Z ztzlZrw2o;#(*~xEOq-duFl}Yp#bW?|-F=49q&7GM@;7G;)V zmS&b=mSdJ@R$x|SR%TXVR%g~@)@L?gHexnrHe)ttwqUkmwq~|rwq>@1yT<|U9wr7B zCVQqZ1_q{NrZff#rVOS`1{tPorfdc|uxcd+Mg}1y)l6W&Gk|>!8ve9pkYkW%P+(AG zP-0MKP+?GIP-9SM&|uJH&|=VL&|%PJ&|}bNFkmobFk&!fFkvudFk>)hY-j8Sw@wx^ zE@E8CxR!AX<95cKj0YKyGM;2S!+4JIBI9Mon~e7uA2L2>e8c#j@e|`0#&3*27=JSU zVq#!oW#VAsVv+!lGJ{;l$lwHyTWRpfIxmvA7Lqs*R2-BJKydU}9d(yn%s4D9k9rD9RYlq{bA%l*?4WRK!%mRL)e%RLfM))Xvn!G?8fv z({!eJObeNoF|A+ByNXO+f9EHl|Ld z2~3ljrZLTBS^#drY-HNYw4dn!+_#M2Qi_p*kueNOY!x_6K;;W4JOmh688~5nV_;-p zW#E9>3)jQM;J_fuz(iVjK|=`?0-!Pul!F);jxgK;&8RS`GDt9mGlerqGUYJkFi3%2 z4NB7xSApEk1fDYig&AmE02FtO3~c|uFfcJNF}N^*`X=rS{zyJyWbgvVHpB!b1{(%0 zW?yDMW`E`Y=0N5k=3wR!=1^utI506tF>ohtLEEpIV ztQnk9Y_MbC0+)VF3~CHq;2Z=>ZFF5zQfVGLo6 zV*JAR1C-MlgBYV3KQaDrvb>P&Olj2Db^6&BVaNtpQ~-Gq`X)fwEZ`%(&J; z*{lpwTvMQIHUD4T;pjB^E)&B>6)=>%nSGZ=9SK-oMDDjaX1Y+gnM z_A^j6AA_7D3s}3_5IOP&NyL5?ctA&B|cGCIe-&F-WknK-ugJdaT!=Yz_t$)=f}0CxaO4 z94MQML5H;f%H~G6laU7zK8(B!a;!m6HGB*vtl)Z^g_Dt=L5vk#XR&ZH3NYxf+<~eQ zWYA)P*(Jna$5H|n7iKVH0k;rXI2lD4yqLd0#YGu(m`_02Vhj$<9Z*xwxYJ}1VMv0Sqs73*5CLUtGw?BZLD@PC91PI3$EeG|!(av#*JBW1P=m7d z88{$qC>Bme1Ee%#2&(0wYK*|M@5~G!e;I@Gh#x~fLlFaLR4IqSnIWGc58U_4V<=`w zWk_LgV#sI6VMt*JW=LhoWypl{eZjJs45bXY3?U4u3>6F|3_;*NTPZ^hLn1>FgAYR{ zLpnnSLkWW`Shk2E5lJkBA%h{4A&pP?Kqmdua{cDDjUDnl_t6+AMtBV;j!2ZImDw83Xp@1QWA(a8Uy&#_u=fXq= zPX;FjUxom%X%!5?VBZ%r=)%JoGd4UKO28oi3Kdw)fWiws))W|!RpPP-Jx=l4hpw7@ zdy&%)emjv>l5Za@ed4zZriy%f@SBe*OI$1=@)4#9$gzx2N4^iR7oXN1bMK%p4hH64MLncECLkU9$LpVb!ysp9SZ)DRvz_o<}1E@Z#0@o`^42cZM z4A~623|Zj1p#WSnrGx7oP~DKuP|Tpf0IFL+wG*i9FJnk$$YD@mC}zlHs9;cF0O=@X zD23J?=?s+&x#0S#n4yHBm_d;NwH!ls4aB_)@LE6tUJrn3&Ju>o(o zn#usH=@l4Cp>=-|g912QL282;JQ;i#6d3#&3K&3Y6&MgEgHla0SQOM&&|y$u2m{xu zpilwTND2&w40>R!faEe%dleWUu1RDlV@L$o`H2ik;2KeZp`0NT><$HnL9hJ^*uyYCb*>n zYSkcA27y~8kaig;7n}36%{AIhbx-t^n0z1<=+kq%Euf^@k+`$b}G7K&n9Dug9Rk;0SK@f=VY? z>lx%TP^^IRSP=uL+J;veJ^`qQZjwyxg4Z ztjvt`wA7U3q{M{yxY(HJsK|)$u+Wg;zyNLRVE7%8o+xWQoqi>fOKC#G~I z!z3bgbr?3VJ8xhE8Q~qQ>>U^tq2St;0M@0e;~j#+gUDNeOa#k8SsR#~Ln1b~X-g|A zDk?_m>OlDJU_PAd0p=p4J;D4)T^(hG4GaNYT`3zGm{mg}HaJLcWCSxwqa=7viMkp&PVuM0L zTBL`r&PE0%)eT@2yo141xdOsY*r1TCps;~WRXHgjqDyfDV}i0YlphqKthj+OQMyY} zSy3S}a>xIJG9cB;in=-*nHZclDl>KjZggPm2#$)_DZs#>&=C@`iHVWPIl(D%qY7h3 zV8l)Z1_lSPC=*B&BnVQX0OBxsGkOO_Y+~X7aU!L6IxsLafR(a<1;G5|9gGZMF^Hm_ z4h)P8$vc=JVgg`w8`Z!TIWRCWB=2B>$T)yyb~-SyFeLBbfQU7K#Wrd{RdX;T?+^gV z>|$VIWMBYGMuNdc22eygaIrdYIB+`fF!3@;Z)5}sZDMuc*u}`ez{$w4nTL^=QF>zo zlXFl6NO%Wh!$wXA>78JcAVRws8yGklL1GOIaAiykAY~vOP=g{PBf%c+2;B+yL1Etra*A?r#6|~)u0)08 zL}`WONa?P~WN?VP=;|=)>M-c)up&w)XyL>JDiTza(>5@v?oePzN>EOM2!L`Yx>!28 zK-va{1Y|K~FOYS*I?7%kSL^C1cX=thrfgtR1>wY$4b09#5sC^akswvd8yEt>X_%&J`*(owk?aIV`1W>vR@4J@j9khHRa zMGchlA`~}dNpHxB1f>^7VUXAr9HF>@0hEEHH?W69 zD5NE(Dl1AWg2W=h;R=qv4J@i&8yJEkHZVwcbt!jkV2s?rqUxrQmZ-3SRc!;CnkR^2 zRohUYt(=&;K_LNTpF(0PSg)Hx7bJ8*?vr*^R*Xzc-N2*@3U^Sz?O2@qBHFVh*sW3L6-LA~pnoECnfHSKYu4R#m9I zfl1tA149rff*6CMB0%BK1}+sgu&R0{C~R;DicpjW=~mdl6atoJ0c&Pg^#o~^25A77 zB%t^OiGYh;P_3y5b1yfmc61<8Rt#H0%H04U}i5|uYNBq~eq_vJWF$D;6crUgc>$C=+aakKnzA;eN^i)B z)J}nf4;zH?R8U9;mE6gJpkyBs9igbGtjI2{ki3CORUtW1VMDNXS28HlSykJ?I@G)% zMF=QWGP)@jLIGxn3O#j;Vk7%Obm=1$`&AsQ`ur8 z6C?WuMln!>M}U{7D_OZKIUxm7Q3ph9V6c$30X3D_R5x&f5xd%kGHvAz3?UJ$(k!5y zwSi4-LpdZ$)xa(UDS*qDYwPNOQUxR=IY4q`2t#ucHz*-x?hWi}3IbhL8yVTvpbA()3Yb)_y1KZbRf;mG z_}|IE;J^TGTrxyf+$VF2jMYo)@eE8q2(J8e|GIJ8(H~;C2SJUlMh7 zHgJN%0%b)|{(@DK5}-1M9bD*fscy&z83IZp@TxQo zoTb4+pn?c$B1AMKqILs|Dk!9mf@+ctjH*XBu&OD7urw&>SU^R@1`f3i`Pz|?CRZ&e zZ8U+iRFk%XLT2Iy7H3A~#0?1vAhtrH0!TH78n}?_>Pl3|OiToqL!fdeQbJe9I|$S| z4vvaY7EoZcVX%R8iKd4Qy&qRUjX55WTR94&|3$nN&3G4-B z#SMHipf=M6#>5@}XMkM7z<7f}fys+Oi%Et-oXL?vn(;M*CYaC2pvma|e*+W8|JO_o z49ra2|6eoNGe|S?GiWoi|6j@^0%0@9Fi3;MnUoncnH>LrW^!cEVytA4W_-lJ$>`5u z!DP)~%J_l7is=`FGvkl{w;135f5CY9{|~0R|Bskz85Ec@7%Z4(GAJ-vGbk{rFeorB zW3XV_%%H&7&%n$CT4hzqpuqTvL4jGEK>;Mrw2r}oDUm?|OxH0eFu5|YFc~q#G0kM~ zV@hPmVs2o_WlI15kSUZQnaTYBXQl`SYb0#I6u}_L6u}_F6u}_Q6v3bgmCI*}V9;TT zV2EXkV9-OtMo_g(OcDQoF-0)&Get01F-0&0L)ADltz}SR&StPWx|Hl~>8049q8RQvF7&I9b{@-Ra`TrDz8NM;(G45u_V-#m7V-#lyWqi$0 z#`u~clu`WuEymaXZ!sD$C^8x_2s809C^GRe2!qxLGAc4CGT#6Hp7B0|4`VQc8)NYQ zd5jJWtc>>mpD>0qNHT{1f55o(|1QR*3=J> zA&8la!JhFPLjY3{LlWa$24BXh43Uf{7;+iDG1xQiX0T^sWQb?tX7FGV{r`t)I)emL z1cN7G;WHaE0yUZZT%+H{}JcB`sS(QP7$(%u$sgOa6DTyJTse?hC zsfWRWDS<(SDVD*U$(O;KDTKk2DUU&(sqFthrdkFSCZGQsn8N;V0H=LWexL;gsU{zb=3SqxfCz6@GS<_wxlj8wrQ;PL=eCcrSLj6lZrka7WB zUVzFB1eS%0DMD#&2>t&rh-MOjlrOL{hDi=m&M@jSfYfm?mNIBFN-&6l%N(d3AU3lz zLnxCCgEY7t0+mGs@&6Z0${@_3NxU8gP39;DO>p@JD&s2u-vO6%pt24bEB)WV)XSjD zWWgZK7{;K<7|dY7=+B_Q=+7VlE+efOOhM%$N!X6TlnEO~H|rOJGpMYEVQ_g1Ds!>n z%m06X%3=@(m&c$onFg4-_5TGB2AB1q@*Ww3%Ko_wl1v~Bsskv+p!xw+haltK3@V_y z15~Gwf|;5b+>q-aP(1|4fBydhnTdfx_7jJhnbt9Yum!j-BTkP6^JWGMCQ!Wx!=U;P z9Uo&*U@~F|1J{e7x)Frq8RWrrB&eRG0S48($QWGzg6d#w7*sFAu*3h)Os)TaFfC`0 zWn%w-nrY?#&rG!pTHtcn`2Qy+Mh0zg{$yiNWL(am!sO1N#^lK$v2QC}_|G&lr zGJ}mln{g9^Dp+kkgC&#d|9gxN7&Muz7&I9#F_JLyA$Ll7>2p0oWYFg1A`gkO9nHr{nr@G zn2s@+fy46(gFHA~KxMxYgEo^qgEW&mgDK;325H9I3=&M*44UA!8Y6=yv*`bC%yR#~ zF~0o&hw=RXgYdFOl|hGSK=H6qYc&ok5sMfw7%KZPv zbngFca2SKa`T76TjBE_j@URAz&7knsVUT8uV320YWH4h=Wsqi;`hS%vhC!McBzF!P z_OSZOo@Ji}ndWWitxiUSn0cumZ9S3}0kWV15kk8yGRfF()v@F*!1LpkPS3;?LCd{~=Q? zLp;+ehIpnnhInvXPhfBZ_Y0Ol`VnCFFfp(&Gcm+5^D@MN(jh1hGn+7IgK;W@HB$yd z7GpYtFJmZ!BV#alt)vEHD1#njB!ewuJcBo507D>S4udOW9D^5QIs*@5C<7y7@c%cA z0so&dhW>xY82SG|;lV*rB)V-5o+V;loFa~gvqb1H))a~6XZm>tNV0j5EG5Id1U zk2#6KkvWXPmbr?-k-3b)kvWM$gE@=Amf4;`kGYV+k$D0`1@i=k9Of_v59Tn2b5IOo zZ)Of-=w%LLfYCFV!x%sqB!`UmGKVpMFiZ?&AIKbG<}d~jhKa{BhcU!6`7ump@?%)S z%{FGa(Z3=IEaI16f*HUq=|OsIGU zlOMwrCO?LyQ2+gf`fV)Ve;xzFe-#FX|LIWibcQz!3?R(>f`I{qL8mlt z3=GVl7#J8_7?~Jc8Qd7$89W#~8N3*o8Ce*-8GIOg8T=Uh83Gsr8G;ys8A2FB8NwLC z86p@W8KM}X8Dbb>iQS>ZU;$pkZ_QxCV9OxP$jZnD-AyRYAOYTuCe0wj$j->Y$jQjX z$ju0vHihj=5n|wEP-YN-?2BR8#ITuBjKPUPkYP20ECWA-9HTe`7XvH9HiqpCTNt*2 z*XZwK*w3(%VHLw-1{Q`z3`*eLf_4lJ3~>wz3_=X{40{+Q7&sV?F~l>xU}$6LVCZJ( zV(4L*%P^0jnNgBaih-A*iQy0f8-pW5A_E`8dxpsj9~gEpC@?H%=x2~;P-K|GFqKi7 z;V`2NLp!4^!%l`J3`-g2Fic{UW0Yr9V3@(Mm!XAGkzpA_D+4>jG)5&xWkwZ7RYo;N z(C%tYMlD8dMjb|7MmA#sj6DpMjJ=F~ z4Al%ZjQtE%j1w3qGEQPx$T*pymT?N>RK{tH(-~(l&Sad$IGb?}<6Oph3>z8eGcI6U z$he5%DZ?Me#f(cBmojvMci*pIT*EDm>ANSm>DiGu`sbRTx3XRVq>_>#LmRQ#K|y`iHl)96E_oR{Q(~nKa&8HAd?W2 zFp~(AD8mLOF(z>)2_{K~Ck(%tq?n|cWSC@`BNu5c9Ns~#7Nt;QBNta2FNuSAp$&ks2$(YH6$&|^A$(-RelLeC{!)_)kCTk`e zCR>JQOm+;@8CEdNVwlM=pUIxdfyt4{iOHGCg~^r4jme$KgUOT0i^-eGhsl@8k6|{G zKT`lxAX5-iFjELqC{q|yI8y|4e|-#7EO>8y0#hPW5>qmCAAUM$2PIP$Q#Ml$Q!aS# zd;wD-QxQ`!QwbAj2YoqH1ydz-7kw>L9aBBpPWpE6UivPS-SiW|`{}2Echpa3n!$wF zt3MCCTYn*Zzy30&R$}ZV-GqHFDbqgC9y8E>Jf_1;N0^Q>9b-DqbOO9*|1{GX zrn5}vn9eg@V7kb3iRm)a6{f39*O;y|-C(-Obc^XW(;cR}O!t`XGd*B>$n=QmG1C*K zr%cb7o-@5*ddc*P={3_ErngM*nBFseVEV}PiRm-b7pAXF-=Jpz{9^je^oQv$(?6#F z%nZzo%uLM8%q+~T%xui;;N7jD(+YT)d71f``I!Zn1(}7Ig_%W|MVZBz#hE3TC84`s zW#Ri?mB2e+RhiY8)tNPzHJP=TwV8F8b)h?94Z(Y1O_)ug`(Z(+A3%4+GTSpdFgr3k zVcTnlZKoV_IC#f<6mv9l48uo;PYj=t_P!@ECo`uor!uE8r!!|TXEKBK!sjr2Va{dF zWBAJOjX9sWfVq&lh`E@#1iS;joVkLzlDUex8oXP+j=7$>fw_^niMg4%g}Ifvjk%q< zgSnHri@BS*hq;%zkGY?D0`o-XNz9X(r!Y@tp2l#Kc{;-_<{1ok82XrJGTdkAWpHM= z!90uMA@gj8+st#A=Q7-7o(DQPg5e&+1LlRyivH#2Wx-pag!VeJRi*9D#<8Hg@|#c<(C$L1v%3)%OGML#hDdgA+F-oveY~XGc_|k zqXf+4%*%ut$X=S4X=Gq%0HqC~v=Njx1+678OEHQ9`n&Sj@o)gqOC#bWXpyoM2&2xg9=L9v!$&D>BsVKE96=bY|p)=T6 zLsy9N3|$?K*%NaUlZ*26*c0>9^Yc=(xe|*q^U@QOOH0673|$?;J~DK5G6xx9=n8R> zp{oIk;k(A5#D-Vy9FLsv&9o%avX#w zn3$Ydlw6vdmXlfm5#div$xJOuEzT^4@ImT9o`CRp64Q$k%Tgg6sFX332lX9{2k|3> z#|`!=ge?GOqd2c5GbaVrOgD&Hhz(BWC_F)^;X0Tpk*S&^U2&Vo!xe ze<~zspz_c-bb`jcGc+!p!Ku;E)fpQ1&fqvVFfz5|PDeP0Cp|eoH#ZUDAg*+{-8|`F zM?w4{h@=4`B803BA|!y&3=v?-NJ=c?&Oq43mI*c!MqFrI8Ahx25o7p11=1_GPE(T|7Lsw^LfIGYK=4X`Vr6(4Z z=H?`pmaykT+|Qj~oRe6b0k(uSKO?^=59EGBR~M*HU7-=;0yW148gZ`B2y=na(1>?| zsRu`(p{t8ITM^iBwjziRijaK3Rt%QnE=CHeVkCKxQw$8v-2~E8i*gh5Qj&6@*_5Ru zDY1yH1Z*N$k&z+Ty#|J6#%!g?!2mAR3|(EJ&T%#8Eky~2Qb;hcmqMbEwG>oHv6X@& zleH8P9SoGT36_F#q4~wllC27C99I=Q7qB@Zc^nq+j?k3rXvFRa z^{OMpt6YvCuYwJMnC%EH!kxfgFm!c-YK7DghOUqr!q62`^BB51g1u(w>IhX2seue# z9Ua*nUBTvZJ0rZq<&1Es3pnD~T#}3O6HC}!!OmuL1q*Vy!j(Z>1*wM&U7Z}+U7;Ru zg?Ioe4|RnT)b-9#*EmC6?+nWb;FMrsXyL}~j&K!^J5qAva);Z^;sGiSJP-=mJi)F6 z*=bpvH5`g&Etb4 z#o`0X`F;?2KZv{^l036(UOJmUl7nEm&>0#S&aS-vD9PL(;yiADq}=Y0NZl?_kGMhu z3zBLLU0tAo>Iw}^SUCtu-G;6%F!kWTHFR|`V+(?~Itb$GAS73_1%suygOLIx7)c%! zwuY{jt}G#-%pC$Y03>E$WC(VifuWfZTPU)xp=FIL)OJ@h-cS@@heCYK9tw#R)=*H2 zXA1>K4QnXE`>x>3YUt_)^`K0{YmXmGlMgTcVi#T4uwLlSn?g36_F#p-I=xf-MSc99I-PL9!<16l5fFgGp$O zm6TeN$eNy*o14g*lA2SJ$evnIoSBoK$5NGAlE@5_EXhbMNo2{)FG*z0PAn)$WXnm+ zO-cc`It`4SoSE`UnJO~b^K&yn?KI}1jC{7@%=FwuLsl@wT#{JIUJ5ajxgaBxIXNSf zxu7_cH9t2sJ(1NBOJjA9PR$YgfT$Yc&E&V*RwXvqZ* zijw@i{9*wF6B0B$(2xMja-^0df*G8kfB>_2KrC472qJSJ($ElraG)Uo=I}!~FufvZ ze6S)eaQHx&;6MU1d7!}p=5V;e+yn|0un-T31v8fi8X^!GXefX={7?=|C6_-aGQd*c zkTEef05u~GOpFa6VF48dS6c=q#zy?07O{!3ksj!rF(>yRsJt;$+!#&V1S)QVCJxC7 zCdOt^c{4P5bEvpEnm9P88JHM@t5X9LV@IeuM>KU#P;nQ!vyMn6IZCbE1EpGhA}XKbT$o4459up1Q)mlCXgK{XB zd>BIAZv>4GBdGh0pzb$^9|k6n zHm!k)Db%m7Q2R}xVPFY0#}X6#muSVH5*6l$&`Odm8XA^mLw6IZBv%%Sp-Ca{4i zEN&qEa03%Zs6CMWxq%6!-)>+6Z4#S6n#=|!ZcuYfp=kut|2Hs!^!p7=ApL#=6E|r1 zLB<6POdul=1}1J$_nN`XfvPiw`3IU-Orh>Jg{Bo#Xqq#Hy3+|tyFkr@jA$5`I6=*U zj4K$Jm_yBnG;$0~AdMdb6BlUw89?1(35{nrsQs2kkTTU0rVc7^080l@bp}v*NMp;u z1kwjKFtLQnn?d6P(g-s!v4r{u(ik%^fwXW9Od!o40}}&iJVP3B1||lubO1HS63T~k z2@Fguq48h<4F^Z4yA7b~A?FNBTOIE9!P(|zy#WQ zGJ&+N3{2dh<`_Wjhx9uPOd$OY0~1Jp!@$H1YCfbtVqgO42^g5TLBqieW)3u-450C6 z0ClecG#wZ~)f>RnL*pMZqGezLY0Mg!IKkWva~D*fIoKUW2Ik;+G%|qm!S)&%n1k&z zGB5|*XJlXw)@Nj34h~l%0}H4=3vm1!8CZbbVPs$dPCrHl7EtpopypXX&9i`-X8|?O z0%D#ar2H{5gp?yjhNcjGhNcjGhLH4cWC%(BMuw1lZe(Z*jvpgKNV#NW2+0pdhLG~Y z$PiMF7#TwHr;#C~+%htU)HO!tCgAWfGK8deBST2}XJiN|_lyi7>E6f?l75X0A?2Bo zA*B2=GK8dGBST0$8yQ04*~ke}w;4G>;?KwlQs)^tLDGkjA*6gTGK7>5Muw0co{^z5 zB-{)k`OL`B5*iMW^kQTPDL;%1A^F+J5RyKP3?cDuWa#9?4ekj*%6J|~Ujf45gEg-p zTmeMG9U{OD?wml`;2sHt%>`j6R~F@Pg8CZZRy?>gFoKpkMo!MG;MN*1%nC3Mti~8x zq8LL<24iRnHio8PV*^OaHHMZX#s=V&Wnc_V*~ZWuZw$==#?YK>49(%j(AI-7v~^$% z9W*h9)~?3TTG<#{>lzzbKs*HY280Rju5g0AnUSBL4G{zfBiut^)o>m-q~JWTc78-~ zg4H7N!3HDo!Rq-C>OpqGBL@;=NUFi^-~y9+$%)0O0uUy6ngJ}p4bcK-^TGR8U@qK= zV4fgyKN2j$1$HWg33e5jiDWsL&jt1_gbDTwn8^=iRu<*NgWLs98(CVT`#4N0;D$g#!ChXu~5Nai5BIR1>Y^oRj&!0mU3KRn3|GzLkXA)u1VX$Vfbx_t4)0I;cV&i9fVEn)S}!$!B=j25B-e89E3$ zt7tGWOQ}c%2q>7VvGT{5S#dBkY4CVhg~qFK^0G@Q3#%zw>zHe}>2itjd<$2VXXWD( zkux$35>b=#RZ$Y)XO)&=U}BK||Ak46=?Q~4gD!)rgNP`*ganJSGP@9W5d&8dJ97~u z8$80m@nv9GENskdjPL*-ld_VUx-z@D5h#k_UStDBl$emfPFW#t2JRwmaOevf8-YU`DgCfR!W)`ojE&69#o5^2 zSVkDJu<*HMJG#g7hVy7^nz`@@F)@khDyf@E2P$Us7$v%kX^FV!+PPaQtEju!hjEK@ z$s0=R7^=B>g3<;kod+>J0jG0K2Qj2{&RxXFRV2d(Pv)T10Kx=PIVePlOXX~Q;4tK1 zwasXD{&xc$d~Cw(!iH)VkW{XQl**;erCjozO!XLz{}zLixs_79oPi7^R6)s{i2)Rr zZ<$0G6dCjwY#lVz<<^Vt7iG#9trumg7ws2i+An%ul*wN-UX)2xR9Z<|iHm`|hzl0j zfA{ZK)I{w^Y8DF%pJ%?iyuFdU zlv!}T2P31YrM8=blVJ{{ij5`*n@5z9urW_bhKRb5Yk`x1qM5p)nU*X+6Q>ZHft8wu zxs5U78ATgSDP}%NMKLu=1_s9e8~$4`&SZMRAj+WZAS}es$;HMX%*s>5&sHSNRK&#u zOTtEi#-Nx8W@ckkRyH>lRyGIaN@HVoWp-osZ>c<Wbci32b5#<{4i6GJMi1atf7U{#lB;>&3-|b=1sE>}B%|%{W+?HFdz0mb{XK ziM))7vW^)aJEyXwh6yLTu#=uyj0GpBfQo9EtgwZWS&TU|GrP2yppbpAqztc$sIaV{ zs2Zb}o`#qpyMn5orl=6Rf(qzFagV!e6 z!zEe4Rn$?-%7aggMc!Xn5nNG-u!`xcTDtS`f+`9&Pz_-!>6+(Ysu%wEk86UlzK)%| zvWsh;gF_^^x=0bzmh*6NhE^Al6alLFOc~r6!WqmRWEAB@%*-@3S*3Z6jC_28?St*5 zS$T`(n4pP58zW7C(k1>>Va%>9iX}xre2$y~gwfIn<6UWof>5s*9axG`RWVER5>ppk z&hN^>VV>?KD9tCODyvu-=6?em@tQgY<{T`{S~Hb&AW6gA*j`pn$q{>EU}yDX;!+Yc zjRmCyDKTL|`v;)d=a7fQzP#$cv!IkACIm_u42+=rahbT8o-n8~$U6w~vB=4>3vywr zY>;ajvm11IMmDloB)nsA}%?Nj9 zN|O*`TeNVPi;X#faemw)%`JZaZ5KK}HFPy($o@kg4+TGHdH_rt7GdL&IK+=?Q}{ zxSV9+;$>lA=Y@nm6QZgIwaP&05meK&8=IROvx|dUDeCI%?9x**JcQYTXI0;ib`Y{u z*5-8&Q($`XZ+3iS|E2rk@=BZhmoPAbLsXpU2?I9+-!?8rt|AU_NE#U!79$1PsX$OL zHD)xsg9C-B^=~n#ewSuoVAfy~VX$T}c90e0kyKOTXVo(`<&fkm(&GZvul&qK9Lz;b zkU-K#lompkU<-te*&)pnaR`Mk?I;U_8)eX>)SQu#A;v1>V`X8>!X_PHZD-HIs_P&a zpaf1)EOJWX+QOo8Y!(^z%q+5slDdN8@@z~T`8M{BR@M%lj>2l9Ps5eu*?CzX@yqZi zsfvq=JIeig!D!7d%d4m=AtGrn2lXElHThuMr!6?C1Ok317&mqFY zHJDR`OF>`C!!?*gluJQRnt_4o|L6Y}OkzwT*jlDM;Fc*g0e}Nb5LBzW!-EUzOmNGT zSr}`}ly^dgIEy@_Wy-?qm}C!XnObhZ(lR~4bfE;?GL)%*95Q54dOLT#IZ zdO#N7S`O5jR(B8;W>r>Z5|EH!W#B1d7Xb3bwv}nf!YM6i;bD&fw!N#j;t0^n0tmmN4&csnHZK|9uXRgM; z$iVsk3*%wX{$d7o2Vp5?S!FR6c0P7KSy@opg7lR@#)1Ms5Y#FHw;!SPxv7boy1E{d zsR_7`Ar5K6i;9Sei-Q`LY;2e9vK3t<9d(V&rPOq_?38t)T&<$yU4*PO^$lfIbhYgj zjbnKXbnO&XbW}y<**Vx1%(e9V4K>v5B;>Ue#pKx8ITS3kOak;77#S=W7#K5{rZI>y z$U5+giU@Lo3M)ZylaZf6A5yk}dKK_uOW7RU;xGnv+n9~NM;queF*zD73MI(o z26a|T8RX9fmlVI~f6ds{@9olAg) zfvZS>tB9AWh@A;me`#xjJOvssfEfibkXcz>U74LdMKO(omDRI2S(uy6Ei>(Hi6|GV zeK8Zq!(EGhKHIwd%ikZbr}cgTweD{*Fff63Jn}NgItcKxvNAJr6>)QcY+{C%0iYTS zoJQ4+!D9x(%IeB~B`+!p0$691JgP4YV`Jp|wP(-2pa1?J0-5;YzXg*769)r7DBk(F zxHz~$RWBn`5jVs@aKbb;FmyCGW`y(=%)x$OG%C;kw@%vD++Q%>&_7*Hn3YlS`QM4g zdSNk4a?kfOF#i9+z`%G99IDa|yzDG2tV|pnj9f*mU~|FY0jgOO70nry%@x@h6&YLp zl?XDr{}*Je5%{-*kuQufIy~&(QU<2~j~E!3Oqq5uuru&7C^`u8GIO&rGqbXR4C5+d zV*w`{P=^B2r%6;+S7ujcG-d{eEt6@!*ssK5#{3>r2`)Cnoc;TmcKu7bk(7KLbjOJT z0|QeA(=Kp(N0UL*L5x#Q?tv`hepyCYSs_g!P0(NuBiI6HGc~pl+-oToRs=VG*x1>j z4N-MaZh%ywkemT!EA%i5`A5s!=`k9aSZ2EK+No>B#mb_oxlL%Uz6~cUv#RPcrd>X6 zx;|z+th^2;j+wS`dU{fl?DERd>bepV?6S(B6l(GR3sV`>F$NV-y(A~h!@ym{!wT{@ zxJBj)tCyHTBSny60yOBr2F*RlhebvK;++94MtJnf3LuXfXdDPUzjE^9b?dCPm1Gi9QDJ4^0@ZUu;7Ee>;y^hGWMU$ymj)f&Gc&it9%rC3&fJ)p@vIn|M54D- zsueRU3%^Zxk!y6Lc$|R0y=9mMuP8IKzmuMyIVWeg@Mo_q12_Ac7*Q=v5!aG1gHT^R zQ!9fgyKH`0KK~FUCq2Emf4#79-3AUQ{;RP8g)=)S7tV5RQY#bI4V6#h*1$lMKQ5OMg9E+ zaxKgMFHCGqyFfPtI&cax@Un6jF@T*0PI1ACpbmkOni{meG#6Ih!|0VRR1|9wq|2Pf zq^YfM%@cT+Y1cod*le8uQxP3YD{IE7(3sx{PRp_m0!$nn+z_90Bl{d&Ix(}eD+?R5 zvxAF&Va7vKDm8O@a&#owito4myR?nbrR*HjuGqY%@szssQNnWdR_F^GWrA^fZyJgm$@+~8;sVkzPQ`xVqi z0*9M{VWP0PGCMP~x-vT`GN6?RlUlGOTloG6HCFN9%$`~=Rpy`-Z9R-LYHR=fVB{|= z`tk8jM{w+b@)aolLFK&w7Xvdp8`v^lmLhhzWe}f3EfE$s26gNhH?|wH$@^sV zR6=RShS{_KH8Ab^*D!lFW5ZuJ1||kjDK(kt7`UA(?7*qaBLOd`!10ArPC*)`%#dMT zNMQ+TO+gyajCw8wPHb#^wh=|nuKCU&R%DTtMVJ+@2n&;sn|Zh;p9l-H507nitemy1 zYk8!RZFQ`yjjT&Wq*0<#oMW1hJg;YvQLGb);Smfiy>h^*Qi4I(L5BAMH=_VIV*+;p zHlHxCaenZgPbLCA<6qy#XA6!yx>!t9`8-i`@0$k3D1^FJ}czQB8(gU(8A zYfctcW;GqAT?qlM`F4y>k92i}B?Z~#)xhBr%mfM-B?b!yX$M|CWl<$2MNaM_QPv_R zP}>R|xkd(tuJHB^xX}kG8=&FD&JGzl1dnWi#=FcRy$;5WLP-Xi%uGCHVTPb!f(00_ znSY8kzb`DL++krC5UZiYDa2*L<6P*E5_Asv;pQA}Ok3fB1`kH0(Bor}W^i!O;O6J| zXJD*nU_8%opMgo9f$={B<9vqo3{0Tri8M1WR}m9e5i=w`fk&`v^fqr<@Hiv1&IGru zK@~b5)1RPb|+5St=@|59atDQ`$ zWoBhzWphQQn3EN`l_!N6|1m}VUB(oZz`)4h_x}sie5PFtQVhZlTpYsOMZ7G~LQvbt zz!0gG3~nQX#{M!&yqjQ$^AGcf*t z$iTp~glQK8FK8T%g^P=ggNdt%jSEzKazGNHHgtZ?QCOK-nOT{U*;v?E*qE_#T1h_J zg<3|13B|c==j#|F|1D?a`S*n}o6#TSB~aQ*W?*1i01gpp2R=?FNRykL1(v!&&23Qa zs4NUMl2Iqud~#kk+tbQ_2N?wzSN+@1==d)X)YAUUz`&FOHHnu4lm<9CLGA>*5R^#4 zBl4;2isp=ppawDHCy{@mB8(^hEf-;GSvESZimNHZ9M z+G6T_G7Q{Be6ZwhVCbp@E_C+ZKvxir9IY z#@Q8$YKho+GBBgK(wRZcLDXo2HDiD^qkuJ|wKbZXEo(qUgfVGOH^&$WWW?<@!DlE0X6}45qWU|RzY?V&>e1w_|Rdn1@-hT zwX}2@bon%_tz}T+29#dFB_gPf#UD$cnOd~Fpdm_i(CiwhpaxB*F@6;OXD#|)+ftsDiCIKb$;4SSR@^z-&MwN(DB6B+Y;5i^ zC0h$g4lzzKZ5cabbt4~bgFsW8gb0IvkUM1le__&OI>unk;OZc#sVK?Fc)*A;!KlE9 z>46cW(T@KI93+e^JQ$1wjF=`EEihs-GUDPAROBua1UnNnc%xrfq+M7D>KTG!H5k-H zfHi2?5fj{qz9LeK6{1f0xr?PU7Za0_p00=z-8>b8#6)Qz6En{ml4gn4=BL*hW zea=j3OuHDk82A{J9R#_U*;#man3=h`LFF=}kq`EOv7j-y^hs1US2SldW;SM5W@a=N zW}KBS{qLkOV}5UZv|xOVIx6m|4i4dFd=dN(Ha70OOf04*TDIchNld%q{~74(1X-IW`e>_IgM9C7 z$1TdMYpNp2%h(AT)dl5E8KzwfvJ8fxd3_On1_2Gm2O5kT8gg86pjlk73&Fj!*jTXp zTp`7Z9h12+9}~McIIV$(ox!8MpcNRP<{zlB3T})sawX@mum~o!dCZFFNfKif(X&(u zNML5-cF(m_w^CzgVlp>Xw^HR`Vz%HZ%M?))4x7`UVU}Oz#-yMtksi(~&1W5N7A0?~ z#wo&OY$b1@4yHjVGoOKhDV1p#0|$eQ11|?ND=RZIXwU=FlLEzCtv)Eh6)Q6;vxCM^ z-V`(D{g;l@Wjrau6yI_`88pJ7^ZyHz1=BIG@0}T39R$QUjEoF495k37KtchYz%>Lk zm;}JVVl8LQ&%j;84^80UpaCUu@Zbk%&K4X#X6A^AT2T>DMucQYaEl%mk8F_kJZRt< zCIk^-WX;Og^f71D*0sv>iBC~>)MGTXurKpfw^n0gVz#nSvj&BnRjH{XCliy2p{XM$ zBeMxls=q;yB`3R}tARzVMTEPir#T-7ueZ5Fx?QA{p)$81x3;k~gf?RIFw@}@WLMKO z)#VgoSJPu)Vu)p6V6ugVg{p&yBo~9c9OHXAMmaeR4K7ixA}*+h1ugZVO;ty*PtB21 z0K2jslesz{lR0R43d~DTUowh<;+@AW*EKnZnME+6)oW&WZ=yJxu%0Em1}r65t8g+h zTQD-Ehx1AE+QgZaWeTechs~+iG|#JcWs=vEh(JmT9HLytpxbHn{(oUoXVPF0WKajy z_p+Qq4BSPWoS+dPaL)=dFAR1jI7?xlmH6)%YpfHHdzQzXvm_u z2r_m;oU1S^aYF92l@MoPWRa4Q5NBp$ks|EsZV`S~K{jC-5k58nc45%{t_VLUG8i%_ zItb|Na0R<6sFMlUFk}!3?v7jes|XiIU3uq$Yo7#bMZ$p^Zc2HI-#*+zog z!1ObNV|$v6cVL}o^KFq+%g6$O}wTJie{JDFL#@h~yjm^l71H0I!C)6mt> zvsW>citunr_j6v=;Fmy%Kr|QDWjEwck^8fY=Ggh|7MhQd(yR!d#G;3BIHZxGSkqJ#^l8O0msGAsVn&73S zXr*edukT^aC(31Lq9n)5*v`PjVD5?CK(0}&}c8XHf3WJC}M*LD=7Db!>ZELg^am>rDAm$4++m=ifg@_2&zj# zrG`1U{?KP|1f^O_elZSpbpr!Aeo#XKQeT2=OJgBR@On;&-|^Ixh@1s(OJJ!d*)t2Y zeT|v4b**xIVpCO}w3&>}>`Q&DJ$RUytj%mZxS5%3N=%)=wWOINClj+NPjaAfkU0mt zpo@`3j77MIwx<~{2cM^{O`2V}wJDDPr=F3ODUTqho)M#`IjD}*&@-?g)zE%y2#_UYj`6vLA9*8r(u$CN}bx8a%?FC}w6*`u~M#BGWMjbp~?= zR|Zc9RckdSSp{Wf8Ch9j3mG08LmO5NLknRGCRPm%VaNczFu2MG2=VO94cb*wD zX=XUaCKv}92+Nzq+3R@f$eTGSr3%Y%P80IvQ4r4frfkU0$RsGLVyUDtQOjMrLDo>7 zosr4HLrpKv!#c=TT-sILEYeioR$txTP)o2+IY2W?%}s7HQ?afR8$XAbj+~I1fxM#1 z-`k2ZoB0*AWZC#RbU~dq2D|_5%nnRP7y=lQ8O$A|{285i%*FM!bQPnb z6&ZP0ix?U7wLvwvv7n{CkR_;;0hMAP3@XWBlT4uH$dExv(0W%>6BAQ-=s*?)f#)5; z$r)5;LsGb!vJxK?sEPzFST;5Ww-Hg7F*7+`NbK@tWfQO2Q54%7z|6{P6>e!@#LDNY zXW_-nDw5``Ys|sIA7;VGA|Rw;C&0nXWSj5pR2=KT$IZfQk?nJJyNs?Jt0;?*nzW`F zrywJvTBZNQByn?vlFeyeU2y{1QcihJI$F$Z%ocv%#Iymd=Kp_2X6BzzHBh&K)G$B)BO%26 z0;1;l|6s;L|5qcM;|g;BhJWHhj4#)Mj)G*6|Nn(yBSSZXAOqKCP6lq!Vs~%@$kYVX z^??k9v$L_qD#)=gvZ<&l$gwc7sPf2)uuE`AsY;7-h;d4(f&4B1{|nOnHeM>nwyywE66c3u_>CU1gV<}iV8C`u_<@Uh_j1u%DFmADmbXH zN(i!xa!RTG|NsB#|5B)pu?QP+i8C-VwnVv9!e8RvW&V|qqD!N;RR3_Zc;r z-hs{L<`!pQFJb`YT?4~ltfBN85=y4Z0qRCVqQWeUtSU_JWJEcHIi+2kz-EgJvWsv^ zfMc$V@hX!X*gr{N|0FS71*c??oqw6$v8XX5gT<3U;tY)cZ~gCKSj#Y*L5zW8BR2zs zzP^DW_P8ogkY!?GQ$%*fY;2DB{~u%~V-v${7Bz-6uw7{oyBHK1oEQ}uUo)^Xux(&r z0NKQ@Zf-8lF8WMsw#a44xy_Et5*K;(Gl9ZLn8Arr7^;>PtXAFJRNY*hT~}&ulGbct zC$D~{UdQDLpwtR7_dnxn7Bz+puzeW}_rQJzneh=Uo(UGu1c`$tI{t&sZ53f)We{f& zbKqoVW@KaIX9gFcplY#J-@q_j88mSw42f&-5*|>4m5r^aNF&-%ieFxynTbtBO+k*4 znN4NW2}Z4d*BCRUMA-%Tq|~Iu*gzBm6NBRaFN_M{`9yIB2?uUQMrM9~Hg4$fGsvbI zP#7o+n;Ww;W7ss$P+FrveU^e86EmxdI)pmGsCDARKPD+LHX&YVRY`GHAwDTJP|NoH ze<#K%Od<@D4B8Ab4m@1!>>M0YQo;<%poLoc#zsPxwV)N;u(H4mv>K8PTH}EVdT};3 zOuw!PPcuz&5J^)ENaAK>Hq#h zZEJm1&qyX)jIi+e|Ap}r(=o6M6&(1vnIt6{7=)CSrMQbA6YY@j04*~&Ficej4WPn$ z=+JRE@Hho#I5D!NDF!5SF)=|Mm>(IQZkFhn2hKFGD7w9X)xn5ej6+@9+Ca@C3gYO0 zyU_xYk-_bMIpZ0o9}J=l92;4MAi2Q=I+g@!42Uc1F}dmarTBKC(F=SlXQ9T-&2FH^A;9s5f${%?|7DDUU^huSa4WFOa|j4B zvU4ziLRH@wG=dEt1$8$!1`Rhus~B@-b7-Xpi9KU>CGg@JWd;6FeKu($btWY(7DoM0 z!DuBlMkXyrCUvj_bvTXGxbJp-~!tBR%j6s+|oxz&H zpCOn*+d*8;#wJL_jmyZ0K_if>$c?)wh^0sa(puIA^+JsWjX}fx28NE1;1GqZ)Puw# zBYdGLXwU!>Zj7*s2^!yaOjtye8I2j`6g0Vbn3(0H6g0Sbn3!Z3BNa730QW_-g_RSmY3& z4iexpg+u|DnJ=TeJtQtbaRQ2)KN~?&z*r3nXc+x(7mS6A#*C7`da%erj~W=C2NXk$ z4Eq1e810#Uz}vUrT3Fb)D|$;z7jqM6HUOc59aKIufy+}+dk(aq=6j4s%+_d+XvQgw zDSzr1Qy7>SME)l+$uJ#buw?KB^_{#~+=Vn86>Yio&4e@*CAszWS%ieRHCT(dL47Ca zJ{{1YA*dq>=|Mqy$dFbZ8)zLiWU~&^5(LnQA*gSOw0chzw8~cuw8;syOaZd%NnBh^ zOx(1WZ;+j&jYP=$1&RW*N{G8$ziWb583d)Y+Qex_02~ih+ zB`rQ-W>#hqD|sa?J`pBXW?^ek86WgNo2du9ep1|li;sbaQ9yu`rHFw+AGF{VT$Y9l zL;8(o#-OEM%EHRb(;~Fpv>ozY8Qu8pXNJy7n>m$nlVPx-W0q~uUuLGif0-GW8SMXm zVS2-KltGk1o57bs-$C5V%H7so$JWe@K~YDCn_H1VjJrq?oUuTqwxvF3`6pz+$4SHfvvWJw7ikJ6FV=v zoSK5HriK**3qt^-7UMmpV+?`}stm>qb_~W25=I&ZYHB7Xb{ZNocAA<(GBQF84ECI$ zAOUsZK`kMDNIza5wA~K0f*0(6J81VE`&^beJG`N9&1w7OUTG#<@x_~FuL1_V;>VlO)wKlu5xUw*0 z8MLywxiY)DGW#A|J#X$y+@AGTmM+RH!Csb@;$keBdMvz*^IsSnzhIQEuKxG5Fk;G- zNCqYbUq*k%iA)C=v=}TH%pDYTM6{R`L<~e6M3@hVTo8F6!Ym>pBg1WK%EZTKsSFEw zP#FLk9xDWu@t{#!XmtnP)C^%8gZ5fN<`5C>Qg(KAW!L}`DDg2)MVa$#X&l#`X$6Vw&=GPQJLWKytoRMKE&Vw4h7G+||&>L4M;%)==xC!?ybVeKHs z!ObQqB_pOGt7T%!A;>j9T3noyn^{m$Nd{C7Ml$*{E@3(VuJc75I7Jv3H00#K6JU^} zV_*o~=LJqMppFYT#Xwt}AeTaF^+&co%*pIzB(%UoIFg7DheQ)kx7-& zKfsY+o?q8X$KO#vj$hYX$KF`ehJ%MyUd33;nw^(TUYUW3A(t_M@dVQ`&?8WQKX`<<_Zy9CcqiC+EVyIxQq-+E#yX+Zr7?qiJF~EBFp!5Xq-7ih6Pi4$u^!xvx z0i^B)(=HY@hBj~yunpR~k7smX5@veMAk4tAi4)ZQ21T~Ixw^W!IH+qRZZ6KwF3zsb zs9EmX#MrOV%_J44#xzZIF{5vQBjfpgn?@$>a9gIOOPH)e4VapZdO&XS_;0}k*)1mR zz{}0d!OX(K#>i8|1{yg4w;#Z%I~=rD%-Gx*wDsazRQ+aw&AL&#n*=tUV5$mw@F0kR z@&BLy7EChW-EG>M17EX>SYj66l)kqEGPpt1r~ZbHokJAy!INrHiaX%W*d25AO)25$#VDJF3l8Fn#wc`jjo zelCA*Mt*KaZf;(7CN?$}UIwlr7Oo;emLkw9Ht_iep!N``q>7CNtw8|g8VEKpOf(10 zYlF5XgRn6>)XN}mvojl;D>JIN_j~xbm-98-m-Dr_`MOVV^9Au7%K4f+s`~Bw4;(n) zzQ+9klwxFG0}5k%Mnxuba0$b;nVAg~>qelMV^(HXXEbIq56fkL=*!5H!RV^OsQ2%Z zK4TUGBZCLSLndj)Mg~a+(e1(vY`hE%QoIcMpdK;EtpO~J)ksc4UrtD%ohUrPKpVhRvGoGIy5ktXVE|W`Sl_JQ#GCl$b0Sm>EPF)EOil zxa7sem{@pu8Nr?ag)s;l7=i{gp{-nSQ2;8Junjvf3H-AVVm$Hhv63`16RWDSk_>39 zMMFuNnUPIJMM;{8iA{x(E#luf31M~-4rzHwAuz?*0%pj_NeHuva7xQFFfo`g%w{rY zJjuY!z|O$4nURT=jX~cSH0}#>3Nt8d)xcqE0}c?z!iayD!a?InMhxXlT8wX4)EIgN zvKiPIdS6asU}P|1uw*i4(q<3_^@*YRl7pFrodawr$d4dwU|0?bd(iA5I480jvny_n zcS{qT7Ij^ak=ZT5Jxy?G^fkeM|16Wj8^V)71StL!{{Lh$VRB<&XW-h*z+J@5ps#IU z=*noW%FfEp%DC^}A_2xD690BEF*33r${*Cuk;4?hJ@`2kR8WN5=?;%>|k>kI5|1Eia-tk zFKZ}=x`EMLk=<34(UbAtD-p&r;eTpEjI)KB(;M0A6SgP(I~EQO@dSn^3?CV*S=bn6 zgGXPXdC6LuN(aRyip{M+0?E1yLh=Q2KCTC}I?0@?cSCh+invAMc3JELkq7bB;C z_rE)Adt%vlGsZJU|6BO!$A=#bpq*)cOwx?846Fu?MrCtjabeI(T}H=FrEsCSyu9p1 ztCJZwL~Q%dz{tRu!NBr77=ctNh_WMgE2)mz}GbT>B^h8*Sq+Owf6R4{?p z(=}Wuexpoti*|0|fAwtL7?>G^7}A)YGQMX}W-wxKWKeYw(6v-i%>|8Ea9c$TX}2>UXo^Y=G<~NEJ{AGeVqg~&19hk&1vYr1YNdxi zGc%7(l!dypAt#Gef~7|QGYhv(l%=W*h@Z%)qUpfR%A%p7=Pt#n_3x#gyA+$IzLq@? z3#(?Ducv@KziE)3q_wH1gO3-KV`Jj!5T0EO{(oV7$n=3hmBElf(?LW_R!EXTjaODkmQ_s+wAe@p)WQMHlY&p8 z0QGL6bNgzhrhH7GW~{j&WS=T{j1@8(WM(eT$Hc6}CMs&jWNK=n#wcy*q0TNM!l5N$ zDy;6N>*;S8>!z+Gt*OHADPZnvDXFY#BBQ{g>O%%&)-5DCZTf9vN(3QebUv zrYC8rs;cX$&9qe8{FSP&pSqx~Is*%69~TP)cw9!A!JNUG!OTI{(#lF+PlZ8AOj4eK zflHpN2(r9OhNVahoRhS{dz(Ootsrz{8#IswUN;X;M4*a=kBL!P*ciJ1MH#d-9h8V5 z16-g$hctl270nfyT`c{WnK%u6jI4Z_m^lr+|MI5vR8?rP%KN1BRF&zl$}`m}=yGx} zG0Mv+=yGu|GRZgpd&I{m$C&Buz$?Y0NPF+;qIST%<5-uw7;W)?oj1WPkFJ~lQT zM|Z_ZN;U>EtgQT=`F3WW+&s+8mWHODJUpP~jit#Vs=^Mb)}}g)24UVdqS7v58Md+( zl0L=uq24w&{Nh}OWuy&AEQCBx%kd}}T7uoDHfwLslGc&-QK4se$bG=dCjeX*-UhilEuKrIe%5f5sDLxzt* z)AQ`=;6tS_dN7Rgn)VXKW~FRw%*^aEB0+BcvhErh_Tn%hX^}uTe_1yLQ*Y2{q>-+P zHxCaJlTnd~P@Hpupo$2;BEO1@WU6JNkT6(CKowai#Ln7=Q=`*cb~+l;s+|9(v1_YqS-G%fFls8B@iHcJI~j*@ zih^1f=KsGi`ArMhYWpzhxy^Dr)+yRHh#OvZ0pcM$w&bwD~BY>kNjU*I9R{(zgD!> z*0I+Y_K@|6<#DKwmA97mC=JtdcQrLM4si1kSC#N#WMtHE){r$)w9#`^0*$cm|6j$# z&$Np{oWa#WTZo09mG1y6BLgdA0xRPLRz?F>#sn6|2`r2ZEQ|&$j0ad485vkuxgoE}gs`=~j-xU&<4K|Q ziUtx)j3FgF8U}`FX-U z%L+(IG3W~DGCj~`+^@^1tE(le#Ujhe%FfQZfR(X;mC=Ef@jokLJS*dQRz`hR#`&Nm zEWpY%feCbl9}6pkKFGzOL&#!dV+#ul!9@qCYY!fbDgqAzLep<5$Ronw-ZW%R20S>; z$D|DER2wUU_c(%v{nQwZ&6Sb)YK%r=fueg__J{_GvIInV+cN5!DcFRY)kLU9tm0H< z*RbYbVbT0|HC!WnhlGZ_mL&%(v#^RtW+v0b^mJcGhcE#a9%oZ^A3GJs>fO6l)rG}4 z<>mgV9Y3z2EhfP!D$NV(3mW}j$CS#bY=v&?V+rs$0V$5ZY~TOkzr?M7e`_nv9a=5h2=Zhgj({4 zajIDBs5qD?bBQrCE8A;m+8c|y$$7>(>I6Bc)VpZ2En`u2QDtAo=Hsl!z6#7<#l|Qq zYa!)a5Ui(ar)n&tEy*Zp=&o15E61nfrXgvdVrgJ6ujH2g?{1F>lRke#1OMNPB0UWv zOx9rbQ4x?|Vda1-I5ikM$Y}9vGiqzA`>Qd^t1-S;V^mWUR}~jv;wlmV7Yv|%6qdF6 zpt{^xLO<3RvNr~_+zhhc3uOjDjtSfpV`ny3WM>8KD0?dmDjsxYSXo(}%Kd!fuyTI6`qoK*c$1bhFz`(*F#lXOP7Tm^EWzc3YWQcY!Fc8#X*Ot^^P-0Qwl4X-& zm*f(Wkl=?!FBcatWE;IG3-SOTc$^Vdl!6K*3=EB1b!Bs7Fb2mhXcZwiZb1tH7{OcJ z6~QDcIIfwLIG3kYu@~~kGY9iKabz;jOfBb{8=sxxz#pU*$5)j4&zFgj#o2(7jg^hX zLI2;H7FJePm*>x)dq;RbefI3xv!~t>-p?6(^XJUT2jQ5)xpP7NG6nFNTe}zp7*rV4 z9Ykehn3)+FRa8LBMTNMEI9Z@gYETIzXbf(kfn%8&+&>dGX69p7R)lSD25r&@m!rzc zm$FjAd)3TUxsp;6xHW9Ut^Vyz>0xB@j$mfCOLb&o(o|l|#Q)D*#6*wr)jws+U^8i^ zT|r*F3jF_0GP-b!ajGdYFf#}D*g>;trm_TV2G#D5z#3rC+qG0FE%))KqZ)j@6%_h^%*Upp5W5Z_?yG_ABjzxe~ zR7YOloRfu>MfcXfXhFuM(?g`SBz%2@RRk=9^|VzwJgluf{+YSTYK!@ctB9HF3(AVI zt7zT<)zhG(XP1I^5}P{62{Q13PUm2Fz{2=|g^`7YiCqM|#he@I)BGlS%drm>3b4tsv1VkcyK1pdXpekjFlF(ziVU4UJH9Vn-% zGcYiL{3^qs%%I7j&*1H#D$6OYrNzJ`rmxQ=tg6Z^prXRYD<{X!&c?*d%*Mva08WYw z;7%;|A`>*K4(c-$gNO4$tyNIn0B>^hF)1sv3$q*RF)6cy_Trhdf=V1^bH_lwK*2!1 zK)GvvksPsn{)`-~KKv1)4uOWv%GJEr7=;wXXA0kDeKiM~KH{Zx0VK zEfEhLC)Ev1=`JF2Lam@#&HGA9pd4lKe;rc}GY^A4gEeS>zLKh{oFIobxI#BH1Ggdt zjg7!(t)SND;Hg`19~<0?G&ff^Rb=O5Mz7K>SV7fzuDx5dDOU`uqP3oBpeeT)GqaG2 zv7$o~Kj%C~aY;UhkZ5g#U^}H{q53=*ne;;qxG%6U3d@;GxfTZN8n`R#$Qa7&hg;?F z$@3~&YD>6z=toz3##@M~x~KlTjZ$YbGN}Cj!j#H%415~0oP{ZeDT6+THm3%^s+54Z zxBx!~CnrC6JAfRx#sTbFsnnK21^D8rYTIj7?c=%9rP5LWw<1{MFp7;uv}naN?>7>2bE1+TnD%>a5E)<4i{nM z<`xtbV&p0k0*}LhqFz6?2(&XszYsJW1FZ>RBdnkfu%fx5nVK3XHLxp#y7ryYBGvwDDDzuViw%TC@#%XE||@2pXwrK#K;vasVNmAry(2? z!osPg6rvwsAP4HZ%QG-A`Ga@CN;&XINH7U=f~qvoVhvC)PRP;{v|_awTACSyOEP}Q zprbJ#lX9?rvOtnxvOtnvuJQ>1FjVt0@wed55Dcgbd#)Rx6R6{_^JHDLe{^89U(7-M zc=zZoAJD4Oe+&#vRZP1WBp6gdV;xdll04#UVqBb@Y;26Itjyp;8W^;-jlgqUU;-3M zsJ$)N!BT9>%IwC>;O+^i$*ZQ!xaz$`jzpkffN-E-pu<1=APuW*ueHJ-=Ibuew&Y}C zWzy8CuC5M>3T3p@@-ec_c8+44^jKe8RGg1pQ61EFRr$XT+#i!;&|)xWuy>G^WfE0T z(AL(G*I|=q=jZ0-~u^FV;n?dRTt}6v$L>j zDnHQJ5A9D$2c@N@fqGQwdAx4Mc9DWCypATOF}7?OOmlWAs|ibhI#q9vtLuu1L;6%q zpi`llLYZDL$TJv%&JtD7lojXV;pb#yV3gr0;^!*TWCP7Hb0HmA2O8=HCr|L`eK6v9 zXhl%37c!3`tPC2<2d)29g$RI)Es&qt*c=4?gm_(@0)>*K85P2u1p-tw7#Ur5r1E$= zc?rekF;>e;GP1BLD#}VSF|#T%ZiE~v{m(yKU7n4Xg)!tGhn;gclhRfxAr>A12{}n& zW?lgaIfnoL!G4JYuTE!Y0Ika7XLJXz)CQeJuEs3Q0y=Mnfq{*=M-w#90ug0^i%vok z6@rUSKoaGIi}oQzneM?wJE5YUpz|%EqU_9T8JUn=Aqf>{WA25j{=%fj%nKD|XI{bR zgHX+M3M$UV+@=XCdA0uQgUn_yWAI_Hci=UXG*WSLQq(s$SK;6X?Y9%*5cFV_cPZWKsm2e;Xv^#)}9iJ7^&IE01cq5*dBWC{9-n@mE2 zrpA0i0=%+3+We*(S`KnnS}aOxXm<}dz>eY!e+IdEK#Wz~KpA%PKzO*4jw}~HKM%jY zpro3Hw4NHjk}T3e?NTO^u0^0D?_t*wWQl9bf=(C(Uq|r&KjdZwW;1w*O+^Y{L^w`E zh%!BZt8GDuGS7jEvNLah$Au@88Z#`Vs4-8{WMDv#SI~Y0Mo_9_-U!zPirId+X`4{Q zJK*A*k;HqL7r@20!^J_i!_uA_b01#YcfxgjVaj4g*uD!%T#dO0Zp$91IQT9Ha2{b| z0Ot`FP#yt^egyj*B032!`kNV)Me5 z!DG9ln2QU8x}M&S|0f*eI0QZ9EI>C@czH4K^NT5P648sHha9-74Q{}L%5Bg* zmNBHL0}WFXyr2S4ULyJ03R7bNApt%aXkL=H)?!zYR8?mp;U)_#SxHTfjTiHBi~s)_ zAYl&5H;_=AiWKIcd;<}k1{Zw;&NmRz7P#mqaJ~VFg7OV4emofwsYi`@5(|1;TJ9@UupFl>L0WcyCI zt}jfkNVe}n5@!VG8;C7?K;jI{pwMHMW)filoqZX>;O(FuYRus4<>D1+CabTaqaq^W z!f(au;=-V#V+@+V3FI!aVlFa<7RsPzKRB_0>r+7?OHgY8l=47Ht{l|pGY1{*18O&m zF@n~svV%ta)zlyhUF?~_Ee7PpMc~uCL8E)H-KB`qU0s=v>8zZY8Y^G4o)hRA6vn-3 zwwfHQ?omd<63YKfJ^ahdQaG6y#kA!0K)0x5IoWs#vMWTG%i9{uYlSw2Gcuc5YJsny zuyuQx*_lk&Wqr^e(m$xOxlKqa&nSF>CJt-3fQH{7%d^3A7UtklRnW?MLw76} zq{zqH2{LgAa!V?^nW~#}>$1s-iAhN+ONbkIYJjg*VG_Z(H^sq&&48JSSxQdVSVB;j zQ&32NPlScZk=-=L0dmvIf5^_rx8O1s;^#hCNH9JD=SqlZ2Ut|={}*O%aBGMa9GWv2 zv%vQjf!aNdOivip8EhH69dy(fRb`drJ^-C-iD@cp@^BYvuoo$Vhsd-+J#^5(n1sF%_}CBFI4)?M2b9^^ z*wIGG%+=ID>)X`S)Q!c&#LYqby`e+4@O>LhOrg@660EEO{`pRE87wS(j&T;IE`024 z8gdD;;nLQ!Q+XtL;$NG3@Pg*g4UIj)G}CS)m8cvCISa|40;|$w5p^Ml6e|-QM$;rM z3ln2mJwYxpUdz8xKK7P8Vw{F%AX=2mz#N`(Ky6?)NFI`htv=c7+7Mvm>q8(6CPsX?4S|23J&b*f4Jv@KE1=so@aW>{& zsOm3_Z^5-bNEB4-JHb`I1K0W>aW>{QPzRO)lAKD zWUN>0S7h3+cwUjoUol>hNl{VVR-MCEi~-bQ=HU?ZVBjs{;D%jK1*`L+*Ya5M4Xry1pBYa2H8{OKng- z1kG?k);@)UPclR~f(BMtv-2@Q&Jo~a78MaYtYBv>CuJI3;LgNoW}ywL!g6g=vY0_P zEZKtsnbkeoP}rD9K+#N1$xKT|fRS4ea*L9!QAvh~ny^cuQwTUX`6WP?DgFNszTF7Y zBj5t(rb%3&{wL_pBQjx-0^;UtO2M-a$=_M@@~Ni;10?`2iE- z0?;HeKLfu2zXCtAB>2Q%R<m$RrbaD!{KzW>`9 z=0R>!VR+5N0a_Ogxk&}QLJ{OxXkQjI)_=?wbdw6`!WngWHg0ytRsZ}!VGFv~CK}YX zV3Yudc+Yg0Xe%flprVuEqJ5xp5h^+nEGo;uz*q!|b*N}RSQKP#5vW{*igtlT75{sJ zZqZ>;W8eYXwzdLl8^dQ%`3F_o3swsL|C&@;udxB$?Zd>6dh^cz z|KJ;O@|o_ls6liiDP1V{LDL7 z!{wD$hE4_94~o-P=Ep2*4E*4f-Shtd!wG1JTm-udB+kY>!vLh3r%flD1w-eM30hjou3OjHw;i=d(tAfo^Nfo}X^Q3H#zGp_>;ra<$&6u3Ntn9%}O z9m>GK%#U>5gdiiR<;%z*{ojI#kx7I>i9yjpNJM~xL!3d02XyI%ICGI8G`b+2E(61G z(6VFbvR_bH1v|m;y43JcJBUFRR9I$FO<~Gn0fd4Q4Ut_XnGGdTtFkowV z8g#Y|lP6Ot_+Cs!2SIIa1yNppeqIJ{(7iB_8>O_tvk2hPb;vo1pdH-CM&M-+po>-@ z(*}?>4s^{bcnkpAcYO=JVJh2EOCdruR)k$ilUGm(6bxBbSg)EA2i-7b&y$;^s>vkb zrUBt%xo`@SqM1CwK6Qln6q-6bL4IOUV+4t!q&y~1P+9_uvoXU{9+M|1<$*;}Q=TWd z^aq*3#@q@u`wLSYxP=M|MNkXX4w_Cqk#dF_bDtEXg^HZ!L1Rl0T{}TB19g8ixP=N4 z--RSD0dAo}#P@*28JIz_#q0*Y_e+T(gdx_!D$vivLW^77ltDV*quzsQy~lnJrh1Ql z52pPd=RKJGJ>or>JUslw{KRazO&PS5xr?;8i)@*TOu=a%Jh*5KTB!xPJp;5L547Y0 zmio)#JNc1glMylO!wkAZ7P5X4kwJ_>>oPDpB5Z75F`}ArH=?Z@Wfv~asuXEs5pKl7 z!taseWELdGCT{7fp=f6$CutH?=*7rrW~JpO?_`+cgL(BBV+pu947pqMpNWC7z6t2c zGEEV;0tW*V1zmALB@-nj3vF2eCQcy^Ju3}0a~oq&o{(l>U|a%9KcKy4pqZHaFwyJa zvQHG8swRL$|KIud4|L-eiyBnzIzNzF@U2;36U4x3d)~uDpMy<+h)#G98Vln5uMfUq z%ay_2LD8CD(@4iiRai_`Ojbunm4SUf`+0UIc3xfw2Y&7%Rd57>ss_-I5NHiKsIvjS zcMCK^6s`ojNdz+bqlUr-j|HKx+5*K1Xwn-#g0xZHj0ZjtB%vQDh5v#s!$>;;CJrGk zDJ8dyNaI0H9C|7QuI)1R*JsjahKwZr{|~-r>@>IzfrL#TB*gyx1BDHX8mN810BZ3Z z0=KGQx5NrENIUQe3UG3JfC7H*ETkQE4Lj)v!#xe|2o( z*TOO|GU$TWM|@y#W-xV-wda=7)Kb(JWU;W2;$~6jDq`U-l435>Vk*)HZzzEb#e*{l zs5t@}5lw}x9#%I8572>Q0uuDlQV_f@1hTrv9Nb_9*W~OVVbJ0vaXBWY7=v(Yn`9Xm zaT_%)V{v(PSzT%Ua9c)ZCNm>VI}NU^jIaQq07kLi44Vi8W)@y6EemN$S#?=Gsg*{- z2D(}{^76WBlG3~a+_Hvh+U`2cY`kLJy1G)f#(&>4u8-u%E7JBc=2sGO5|kGcm*WxO zmNx{oBL7=388SU#&|uJakW}SSQ$9DrkKU=z=xSk!#?)vX#xvm0L2adE8uTg(gZdx(e?1^kin@_Ac{v z6Ef9x(c@%gmbcOt7TS27DcQTSwvaTBtg2w-S1b2FXiz7Oh+%kj%GaTSR%fo^3J0bNi69vef90)p~N zD!k1I>M4Rw4FDeq1zM~J!i?Mk(FS@!!>(UK<wLYM#S1@|R zRojBvDqwLo=5B;)aJv^`Mwrho!mmAq#~)}$5aR2pNMQk*Glz(_K*Qn-Q#Dg5gAV9qC~Zb9 zB^4DVPGM987GZHY|K5X5K&K%KUmbjqM%gt3!W~jLFoc4&c@seRsDsj z8kCB_qM$ac2SPQt4GWrUVPkHEs}^GpfTz&iNNG+CJZ}mLQFi7nDB_FZ>bD_@8zHIR z3Ke$--82dE5ol#L13PmMLp#_t5OL7Bp%i#jp$}OcoR1*loyg)Kze3IFg^2$L-vkLZ zUk1|V0*_!qL_wxQMEek;V6!2jok*e_ENYWa zO*otnG65tS&%6{adK@mA&b$LIdJHb=!@M3YdK50|#oPiHJqQu~@5y8eJ~aen8)zK~ zKiGF5`%IY+z*QfCs0Q6|$-EgV%FcX-aS~j$J#zt6oQ-*ZKB%^M^k1LJ5xka9nZeY7 zOIb#dQAUP=kxLL%LV?BtnWY4Ii=@EAypRhTL46WPB@U_u4GfbRjfJtUWdPls$q3p@ z!7j&`-xFbmUhXiei~UMu3Lo_ae$k44W^5MfoUC*?bngS^H_}F z>TiO?8JPZGU|?Wg$h3=rpFx!^p$K%fZXQAt=bo#KZ!+ zaFT@!c5x%2&A(*9huDYD@661f^C7F*k z8GVHR9T2*>c;7xI@MW0^OtJs={{Ihg6DSWc&IFe=hZ!qC>68I<^IsWA9JCjkfsOfa z0jRWvh=OvF0yxJVD*)B27XS6ZcbVFO=I+f6ROOht_H&)*V&W1Iu(1*1E`qF^Ms(7Q zj0_B2MUYNT19u5vQ}fub&qSWqXY2sY&hzNOXXmY>4B2ttgsRgNE&!R-FGQK5cj9y{ z3sS&wL276yGq^8?@HMEEfcW|-QdqRHs6j*M09aIkfq|(8T+S#$LI`w42?J}t;M*${{_BIxW>94C*d!z=2`YKjI0QYo8CdsoF!pmW?&n~<4`y(1 zaI$bRurNyU7Qs*D1UD2xc@%PEtsrO#8felDkuk9r&I)K3*$RV}WAgLKa_b0~XlmKZ zS!ppsvnyt?j0k;D84K~rUbw&agG)J(C_D2NMyS6*p$D$*K;ml5MLqmv;rJGNFY|eucKIti0Ay zCAJnJR(${FGckGd*jI&%nd?ZZ^0|jfS?Ft<2kALgg~(dUxL3s(CmO^$^UCtN2Z2Hl zRGLiyw-i*sDf)OlLKKurA)-eiqW}JZZUtshV*rVQ<~gLnX$fKmD4l}D*_aR1gVr*t zFfcH^X4=Id%plI-=%6YjF3!f!%?&z;P(*|Qd_8YJD3fzScGvN;fVQE5Tic*LPoT9q zp#Aos;S=y=Un2OXUQn;xm|YQad=oS1MnT3yw*SuA=A^p_xQgV6FdB*Eh`0*6Wc=I2 zXe9pc9QYDn*1(jMl$5}~zZoYLgL>W!3{2a=DF8H!#?E|{p%d&2W(EevJ>a~p1`dhC z;CUdB=u2?;KtzwjML&W|IEd&mxac*o$q><_aM3H^mJ~$vAY60)fJ8wp`N?p%Z2-5gK;mr7M21pb%(sLhf#&sm| z4u;TwXBZg&gRY3)4!-x(&_RNiiJOOq8N9KCm6?Twm6e@|3woz9c&H5=MbI`8WZ$$f zbheY9iE+Egzb4~2p*Z&(`^|z|)e;gInPnqn8RP#QwTw1D26h`bFMxUv+F<`3X6S{v zjcFS=eM7{L!NmXlW7-CGGemqHqbibmP#Fvn-wRR?x{><71xP)E7=yBdh$s_3s}LVg zkq{SX;E;)>hy%QT2s~H{j?H4k!8D-WGiXmV=zN+E`1Q&u6puos%9&XJm%EHXd!gQij*tFIn%$iq}nT3U! z=|rc9iHTW;f}f$Bm8@%dl##SltXYP8SH^KpAU>}o zm=7vPKp_E&dB%H?JPE0@{)569lrkaVwig_3OyIWt8)kI|MFw-wPC8v4B{4n$0Y1=$ zvn)kC;DAD!%Y@a@pn$=c%YvpQ51)IQXNr>r-iIs~fv2vqeK zrZ=E;2o?p^A=8jlw?a)}W8Mc>{S4fyf`sN3c&hbenhY*ILE`Gn;M@WpD?!Qy;C2;A z9@MTvr1k^gb`?bYI^4W3Oq0RwDv0<^kT|4W#eAOW7=sLh9)qKUx{81-i+H~j<9;x@ zFU8m|#V92uEha4{%m|*85oUoNF##GX0403L%1Cgj2|CaZX+{#9gpmQ{F>|r1`PI^+(q`_EC4=63_7zA3+{G<4itlw0pj38sMy%q z;j@IGQUYmy3$&6L!Ug3F(23vBBi=vs{ZXCBM3=)J+EtnzCLx{WP$YZ^$oGBG? z6S;M!6AQSHinj8c&B_|<9p?Z4GeANGRI)=te@&`K(O+ ztc>}r^{h<#toE!-_N@M_O#H0!tW5V=8TYd?va)h9bAisA25+_p-D6)=1iH)K7}m9R zglroIt$qg`0btDdak_nu-E_g}nkR%A{|cYbn!#xC?*yYo@cD#<^Psc_z6&1QVlV`! zz+=8((SQFyH^j53F@QutZJ(#$P>uVq4-#ikV$gMv5EBv-Moe+Z%1THGa6u2G0FReI zr?;@pZGnyq1~p5S5sB~$XsQ}Cmn9{sBq=QozII;tWQCLnctTp)9eMi7n<*+G;qNk} zIV%Rxg6tr0>r0Bk)j^k^myhKEFXMUM`@Br`yo~pG8F_j6S>#!m>RA}yvoPwj*t0OP zuz-#UWdb*5KxL zD=t=6CN*8AU2O^eZg~!j&X4u9MI{B;<-luZ{r-Ppnh(z7M&J-W3|=`05e2ntAfm^S zL_s+pB6%!iOvgW56>(fw7Ra>?(%KFCG}69$b<(n?C8u?HazK@SlQ z4lV8?C0_8+%HS~8);1Ed)CMI7q}eDl&=NmBX6)S)B_(C>WV`u_>`-PFJ99%fJ-*QF z5CI)Cdu2U+LCEG$@PbfDBNawQMn>0oeHJ#RUH>A4l=-df)k9qvm;Q?mOterI7S~ij zZ1j}SR^ee`GK_N;HI(`Pp8*m!ppjvSzfL0g7SsZPi0*~@_6yTraQj2nfgik#ibIMU z$&Zjj@(c{oya=0E0?&+s4|YWMQn+ZW2)nW(kGqIhNvKPL5xO68la)39%}uYjHjHx> zHIxD6P>`Gdf>IR|2P9RMLqt76u47RHi-KZb0v?}#L2U@II2-d3sA`a3Hp5k)VVs4e zx)mzU#=H-%dOq`47BvP?c(60yU_?qQ;I;)s{341tXyh3pei=pF32x3MsCX^|1M@+U zj~Gm#J%D#$*FeNUsUISKlmS^Bl>Q;&2T{a9DIFqy1S+1)z`(QsY`z&J#K3E@A)+AD zA)-eiqW?Xa7JzdRNEFnc{|a^sL^a4xkT@IjL5OOw$sijcqDPQKL3s-#3d&nWNM?Z2 z6-bFMzDRhRy)1E3-#uOaRS( z$}3503yaIMS!9Ge3;L^QFflT-$vfz1XtJ_0onX4~?BxG+(u%f`jU&dkfp!~^ZBL#r_Z zLsxc1b4F9p(PfIl?2L>HMgG}|GU_cAWjrAEZ`}gEfA2C9(ivk|7(>z%{_Sx5cN`oa z44~6Fjxks;C_4yg^DCH}Gs-YB$b;v>AeXa(&W#fUAD9F3zcJDz0<77=4jKywEkK2i zje{5Fftzt+;_SR4bC?vgL|IvQtt0at&7&NYSy;FY1FV_mh&v0*W;L* zD}xTm0Uxyp*_9^->VO(Ei?f1zpwKhwAxlV^oCR&wwHX;%q>W9?aHQE9bzwID&bz>s1o21@AdER zIxazdZ66t?dbL9HRZ-f=P;rgF%Er(LtDtk%>hZJaWUpQ^dzq#DXXWKrt0=&J0>EB__{g zY-VO|3_7&1OvA=p&`L#}MTC#dHdQWH+$+aJzBlx&-7WoCGiAwSEB*b z69y%48W&WTQIO$hWHB~oROII_QUos&f^9RoCS!AP zH8pj0b46woH8pkE<~Go&iRNZzOmf>J8RN}trC7i#tgRx9m|6I|(kpx)b8|8Eva>i^=#a%d>KGN-N1T zfKGo3W&FeRgh2sxGNmw&C}>Ppl)H!#8ulQk8XFh}n=7(I8d#tcPC*O$Ko=o^^QD>L*1mL{PAa^8;18AF(Q!^19Fgt{py8wv_=smSoj2v(?6 z2}sAg>qVy8FJNT{g`3)c3npGB5e8KTWd~s%MtOMwW)=zXDnkKgczOd5c7k$HF{tqm zX;*^}`+_o=m4(4WQqXN&eV|$VA`FdRJ4 z{ab&(F){PY@F=TFh)CFjIs>4aW0{PZJ}{UtxPo%H2?L)F1B0cdy$GX-h=YTi4tJ3p zIERBXcr57pIFJ)TEjQ31iLl`VV{lOgORUIC+(0XZU{$5Lh#2xUI&5qPo+=tl%v{VY zx;m=n8a!fw?xE_63iAF&)dNREnrQL~ zgW^Gtfq~&WbWa*L6IT%@II9~WZK)A9X8tZ1t*^(#7?cqXUH8a1>z_YJH)!XKIui$j z5GWP}c$wJQS)li$@G=##f{jAjca*5k&JNza0$K+PO6lyvjPbet3K5=bRAebC`>%8ZNx@q!6zYAmkyf)1+cEF$b2o~`*z9IfFhihp;6 zt0=CSH}B*B|No(_Ar>|!(7ZPzXrC989N2f_4m@1odj$}Mp&;n;$V6qdl8}+7!U$3j z3Uaf0q{`=rd1ZkM!6gUs&u989-2w_V)&HSP%uG)hj6vtrYjW|*De!V}iHkED8X75Z z7a4(l1oDj$sOSJ!kf3r9UMv`cRtiIk3(UL;y@}1-T-jWa@l%u#Tj)uEXkfR3| zBa^nVsRAUo8ix972iq~~>6;reRS7cIGWA+oaEWlMs)bn?a|v=P=?n71vo61MjH^M2 zIcVZh)5u4JJsh$_0lbTc4ZPC^a;{i2cn6xigMg4ACnqm2A0s%D_#nvuNPxSD1zg%f=CVK~22!01S}g$DlE5sCva}SGTgAkb5+&-BY{T_f zSh+N;ef5pJI9M&$S-9{DGBS&6E6AIvbBeR^>z`nJRMBJ*<0`H%W*F|G4ysQXMciEi zIK}wo^rYnN^@`+7KxM1u|4_zIx#fjNC=MV3&bTaxgFqH&=&rPC>gN z;DeeG3(!sdaNqFTbv zS+?K<8r<9j6=k{PwdHsOq0t7dYXg`#7$g|cGm!Gh#5Sb8ysq!sTpJv}By$LT_h3xyWBSZ<%s^+YYKW_fGx8c6%P{a1F>)92Fc-;yBOg>ef$LRB>j`oZ7^sOZ4qo02y8p`< z(%J>Z1RERZU`ucv0;}EFE~q(0>$9@(7Qw8%1V;v3=E9_H~qI@l3?Os5NA+z5E0@P7iZ;S;Ns;e65%OgX95+qpwUn85~^8cIj z?{&C>(u05Z7%LbV89*^+!L)?RP==O^)2-*RoG>@ zK_`_7GZ*PWqZHK90~gRjpbOONXvTYYO%5MS%#R|*)g$*`kFZTv9j_S`hcUJmzh~!MnX-RLy<9U zvakxblCp%Ai6@^dkEWfJgG#KUoTapLwylG+i+x0>teKQeik}211vm()aw{oInrJQo zjS+y?a5C*;VFRrsg|3sx0Q2R+;|-vB3N;X)X%2`F>xr|lF)4!hpcP=CwL>gy3`!tA zWF!Klp1~Z%2g`%zj@cMM>n@nVvscrZjxmTc=z?!&kud1jXWXyPcppsa>nrm}FmOYs z;*3Cd^MW^>85knZ#ew=wp!rF4)SLmGfdd`g!f4=H=mef}D|T@!aAITSvx_XYwhXi8 z6=7lW@vw-neH_#2OHbu4uL(Y88P)=I{;BFZ??D9$lWNS@a-2sCLUB+u&+ zd^Z6!+Xz~F0rnkah6@xrpp^n_44{<)jQ<}pFfgez?PB0$5Ov^YV_@bg;^Zn~fQ(;) za=fFlurf0<2r>FKhvg|su{A6y2CY41v}P3i_v_y-NDMGbgYD2l3qjBoVgfT(*pQbS5 zWns`D_`e$o3IEO|fP4m?DQ7yy!UmejhPZ-h1;`alYv8T`%|Wp-=z_-b|9@v-U*Ysf+pP=D=Lps`2rOajP021BrY;IT3=A2iOz%wYKcF0(MxZ3cM;JqBBbSO*;&B?CP@ zCM8~3CLw+YQF#x3UI$*r3%n0_nF@Fr^?4cR^D@TsGBWTA@G^mpP1zzU;laSPneK6zGbEJE?qQrWn3dDwk(Em>GWJa%5MST;Rh8%-`QW+tD2 zTsD0l8%=I5CT8y-Hf1N9d~YceiSRaGGc%h!A8BI{(`gRlC212sBO_iJL2n-z%f}m( zYeDI32{?32L9xM*&cMK|%Cw6?0aRkkGl~cbGBOG=a1}|i6bYd$u>$)ObQ>YG=md`} zi;9SW3U6?30xk7XW@nUD_e?TkXIIV9U}tl53C<0%^fwXI%Fz)HZjDnrU>Qeiv^iHP{{iwVfd&S1fEyD&Uv|jh*y@R=YESN&q(I*`PJ>(6bLg zr~80LRM?njgVloj&|tM%;Bm~^zd&gN+(QJ5g64(Um}iTDMD-XL7+t}lpq>jm^X&g+ zU^77CRiO3!OdxSK=C1i5)w&D}j1!Sm&-tGNRt?!}4sr)*A1xd6?2jPT;I;!;wH3r2 zOmI=K$q>;_ZJ4MmlG-`oRa)TM11t*JVLdw*6mQ_t79W zT*(HsGV%0(PPq7Iu(+x%x;Q6TTrCP&9MpryTyJ=i!ks9Su1S(-(i8SFX+HYODvkpDsP3m+SUoz4dyD+8T7$Hbuh{|l25 z(>n$g220SI3vpF_RedP|egm;nPmMV{J0COXOmAbz zpc%>*a%Dur^qp0NAqP9Ry19y4viEe+IqKH>YJ#lNUKTp;+AJ)59$8j~-h4bv%!bBB zzP#Mb%o4gh#__I__No>Y*~)5K90C~vERx27HfBb8AvR((5{W*+Wl zyb|1sdQuF`pz~Z9e=%_|2r$SnXn<~#(O~3|k&%@ZWE2D~hy}MULH>XY`GJ4*oiMeKsa01?dJR z4m%TLcPSi~Nl$qNb|E$qQPBCnrvJY%$uoUm0G*5L2y&YOgP5_g zmX@6zHv@MOH#ndnRRgF2iU?`MkR<5jK8Qn6!&w>9qJi8C0Cl|*8~ZogFg<1#TjAeNwMH3}fRwgE6Z9Pja9-UAtK1D%B z)5L6DUlUG2PBVXARwiE;J{ex?Xp;ytV^a=64t4boE@4hRL&ii2Jy}UkL3R}_Lr|Lx zv>W>v69)q;gTQtcMtG2e3hiQHP@h0LozX?`b~qD9_&8=Z>HMs9}yR;tZ$;Ns%o!d zY?5H*AD$MiqHCb5q3NJyVwl0>Waknk%E6^8CoLzZ=%}mVXycS5!p@~BE32TSX=kbr z?TaxoePGaHum|M_FfeO1h*oE)`QEc~} ziM_H2H)3T09n@y%z{4UUCT6W9r79@QrzmD0AupjIz`-Htmg!*PD#*#gVrZb}!^aQm z>+*nh#%qZn0tdVxLu7}}I#tr`h@cQ)6|1XS3m_!&1 zK%_s?j015%I%xL>D0@Ll9MG9ipiAAs!?K`J3D9LM z;G6{7ODCO?p&eQ+s-tWsWEL+VEzBq=&ShjOsIQ{UZyl<`#Bq6njCgpph#)g7i?~#6 zxSHzJ2Mmm$-I+{AOivgjK&KpWF*A#cvkHP;!O8@kZqNo_tpf`CVo(AHw@X0>2#7;6 zG01AEsTtvcYfIJ&$O$tFiE|p63F#|?Y}I9Y@-Oi6B{Vz#U;Y1=NgO1&qjh?dx2Uuz1LObu3=E7rm^dK4J$6ROmIg*}BLKWm1++6!8RT+yMMi;6hYT5h zwuovbj=w+NZrk=2bjkt)1JiV{3soIN1Q~hRS@`)8u7nx{ZW}?$y<%Zw@U20{%*w*% z%IxeQqnV{MDx9R4EV`>RQXF|%_16T5v+_DJacp(>*z)%WqqC#Ky}OQ%|MtRCgaUYk zU*18GnTv~&fdd>Qph$qY8gw!k=t5{n8Zc&7Hdkf`#rRq6jLZz(vpP&1moEMNaUXQr z3FxF5#JDf?+$(NyyH60*b_I{2i-Gx&)$^d*;0c%yIr$1S-uIS?gMl41LdwR(#LU1| z1UV56=3DSZG|Y8j^Mn|e3e67#kN)~YY+}{`nF004~YfO-a;xMMR1o2Qr>|F?b+Gc#J*XuO4({z zIkK^FtC_iIYM8OJm}Qu;O518$IkK^X#56QaIhiebMHKi&#MxxI6jbF56uJ1=SmhXv zC=D%vP1Dar}* zF@gh(kGY5+T3vw#u|Z*E3>wMC*IQ;b7DfsX(6lV55Cts_RZ~`GzOBY$mt?`r!XH}a zE3BES$z>aF%FN6cR_7e_G$ajID>C_CxcaEoxLTgdb~m z2KSgv|CfME2X#=7S(S-PL`H@Ie6k#Okup<}2rN4ogW89n<|TMc0F(%zD_cNJ__!k^ z?m^`iJ7bRwhoUAE6BDb9uZ6u6bnm~slC+MnxEyHpON3rekBS1j0Q~p@$i9E%#V?N; z7#Zw96&4c*gA9YJgBU9#zlgjDlfMX~hzJh@_#6-(hzr5HrYwyO3=@&kDY)-lmSOEX;}-3QWu@igNlYVyvb6=?EFSza_VxX{0v&)gCZEXi&UA4#F)V2!Jv!-8rOy#69v8x z2-=>;3?T5Ji7`@mL5D)2p$ZxtU1wv<%3_~k&&(pDD5fDKCdX<4;z-JiYYB)efP&Cj zFhEHYw17z3+rrF(nN8Y{$J1U!U4+s0-w}QpJ_S{AQ86dbGNL1Va(oIZ62g*>vPg@H ztR0*ztsEH`8BG6|FoV{**)mu1yB!dqH!Jg`gFzprd0TOIZ1sP&%&h;SEABRO-Au`SY!rH-#VX~ct!1ao%*yho|6E76PZ>nYO!pAQ1z+Xm+OPEvM zKw3@B*wor6!9z@2#4Xp(-CA8s!_7%q3>1pe|GzNZVG?1GWiSTK0BQ=$G4OG6@_;+` zT%a{T&>|bs#)7nQU};`l8L}J#+{*{|DWIoEg4+&iNF!a0SFJ+z8JT3-buuzCw37wh zQthom^+6}}XIdG$@Ch<8iE1ery7CEt7(9jvZk$pgN)MPgE<2`J878=i>4>=H*@KQs z<@O`nnx9tm?iE1z42lU1nxF$@pCv@Z!Veuz47sL;c>M)=Nb-TU$z#TTT@^j{~321MSUZU|>=MucU>Iph0Z~4OS|$D>5teFjfiw z`&7xaE8*`l&OtmCyxMynnlf1?z+e^T;2jHb%MY%$ZmF-1Y`F+I2+8baaV_yO(aX9Ue` zF<)oe#bD0h?Vzo1tf8r7EGr|%!^KZ1ZeW=So^=ChS&JWMyTOk=vZ0q{?T#Q9lxcoY>G zIAyqs6u>=1L9h=YH|&AD2_7*JvNQsadH%!R;P!-yO8D2jmfE>2neW zvWx-}+-aG)sW!Pbskh5ci)u+Q3QFw8!tBc6p(pSjHgH`~ z1WFp9F$JXY9B_$>GWZU!AV8NEgWL_GzXw%lgvbUMS^M!YF`HQ?ibOcNaWFBPnwf>l zIqO#Yr{}1+7%-X{x>WMm+Bxd$7@Bg6a;a-1=xcL{aVcwQD!J>KhxzFH81u05x){3U z*h2H(Ht;Dp(hmH*>?{miMO@&0-H>@(P}u}-cY*E&G-rhN@);F+G6OW3V;G|nA&h^^ zn0Eau>}zD4^Vf~BzpwFM3TW(A0lcSsK8qUDV(|Wl6AaDZehx@{KKOhkQwKTNC{Vu) z<9!+MIZM#7AQtGCp3heRy9Q-`oq>_T z19~5@0O-_Ic4lU94aCJ#1lL>VR2(~VPi%OjHoc5t0M*_@gHzDhQ>@2P#=cT5@qSGbuUmPzE!Zm=v9j<&~rCv+YGR zg?(x~qoVAy97ME4ysJH9;cvC={*@=@~Eu{JzB%*@Iz*Q{b}AuJ=gD2oWYVn1;m(XeKZ zhzQ%F0C8Q>uqKa)O^iqM!tLz%rFnJj74#x(?F6N{_3RY>*+5e=^6CPG|5;4S!L_g? zXtfC|0~5H^g4Dp;peoqF(A8W~*q9lFjoBIh%l%{S$*EveuE?oKH<~t$Y1iLnpoIDj zRCrxm%C&nj}dVP0U0`s)Vrg~I3`|SV+K7-&Iyiuk+K9^Lil9+RP?d$!M{llN zEX*iiHZL*WuF!k=Hf?K8Ha1nAjZ9Gq|2`)MdllFx=;%sm@yM$(FoR2~JaEW}Gf0Eh zZ;LZC^Dy!-NPtUZNu&}PH0l9qn;K)a71ZBV=*cminHXnR=)G`*wlxyYh@dCssf^V>r&KU~+QJwqs`0+-{fClVjZ>U>lxg>ymB920BbG&%!v!3bazr z&Dki}l2??O*$uQxPEbWm>EAh~UH@)47X<6sR>#U(gBHsfB^t&#r3uON`uM{cpnk)D z1_q`krdnAkeMGoa7xyO%y~j;8$=r!d}IJ*RtBv<#wctV zC#)&S=;3Bp=*=kJlWSQ!MaoQr@zioHTTT{sRqZ7S-O@75Y@C6P?s@iq-54dWtI04$ z>FA27^2n)y-1UutfvF7YE=31HDIs<-F$oDF5w0R}*yYyXk{jkGQ0rD)8NA;Gv@#d$ zDrRA0b9g6_YqgMuIIE23zHgnUJtTHY6_@73A(?L@i|y6XnhSEGwgoS zFN|-%Y9XRiz^m%S|9=79^~l1;@Cn=skY-?DJO*0v!&C@f*VF?pkwK!5n5HnWGYC6y zvN41D%aAc9LGX#*!l0>jWoGI0=Q6RnptTh}kD+@${+BQwgU)|(aj=4$5HO9PlMW$E zGC&JALke%$NRe z!FY*@gF&6a&_Py$M_h!5K}JA^>AcK+873JSVG+A4#TDGQdnhJjBi2F;COzfbNLIHp1CC)k+bH`Ot* zgJT*ZIt6rH4tO^119)Ui+JRR}TwGaM2t4ux9vFky7s$7Bz&9PRtAnBlGGhgrpfML` zWBY6uZOF>P=bq#07tJ5WqpN4*!ow+fN8pw+8zYmLftrSeY=BBSk5Qt#xQ?i6j;)KC zhN`Not%j_>j4YQZr@W!GsaqO) z_P+$YO2mP|*+IqLUc|&uM?-^8K~aQ@k55>UiHSj&hpR}KtH=;MGOq|uAK-y`BYkkU z6uS5nlvMOVwXZmII3BhJMA_V!*wrIUu}X@v)|N<1L7a$MKvJUHvsujC3{^K*({3!D==!b zu(AFB{~xse;{+&$GF5=flg_uGX{$f~OTeo_j2ToNgp3%q1Z4$9L{vC97#O*WRKN++ z2%OnKD?>nYYvG79W1txhyxIcFM(&=&dgtuyxzdJiqC~6@F$}Yk>S^K7S0S`U#L(A} ztqJ7%)Bi0P?=o>PsDehEq{PI81?A)<*co_=B)~}xG(7@7FaSBI3SvkT(FH4K7dYF5aIDyMC1_nlPrY8){3_M#wYu>^^ z`~{suVfz0IlNcy27$hKZ0WMjK%0KRyH!9r1(ZubEm+XxH8}X#K{Xo|mw}EnQU{k8;MEU0 z;%*X(g8rAgYME0lN6L=<>g|PlVf0lUS7z>1YPz3%h2F`exQ5-KIs-)$U)r) zo`=&8trCN-#*qQ7i{UbauZv;a7>;c@4s_*-7Sj_3RR%`~6&ZPPZWUnxZWR@I0Ty<4 zMhC6{E+#H6Q0*(v1-j=$02;qSmin>Apq@G;FySLakn=e~S7qQ1OX)mEen;^P@qU3m zLyVY4tRGVGE-m$bj}q6QkbJvQ=XHFlapOej*&qa+*N_E z?Ex1rg+|7ZaUCX5kq7QLfEMtB2BewT+1Qj-A@k7S)m`vaKanb>ULFb-UOLah`(TTI z7`J3D`cqzK-}rs^QV%f!jT!p08jF|%=jG78j* z+F%#LMm)@6dBm96n4NK&OtS7-@bu1E?Tm2HZ14U1OdOXk{qqOa6QH?4rZ3=CLkgg| zc?EuUd3Gjtc2QPQL1tlL21ZEp8huRQb@*ZfxF35I}jr+A2U4(9j zXXxw$FER@M=a0O~=pKt2cy}oqb0_E?H*jm`CwTv-K7%J{%-Vok#X`=`?!Co-3#RoJ z`z@F(EX26QKwTzCeFJJ4fKHbMrC!jQ73lT{jQKXmzI=7)5?g4S2z+lFWJR#J7`TN5 zn_L9lTn4(1D%;6A!Vt93JlopHhmV7kUsXs{PFO%nKuB3!jFpL5LNCV1hmW0uUqwh% zUYK8+UrOPhxDcZbr7wIQkfj)(F4+dx7w3 zE^^0%kwNo+3Ha`LHPD`0Raqf!P!kPur=Jm|mISrUKx>`AIR$itA1HjG`2tjaii5gF zv!oq-K)r=bM{HNi3!6BqO82z$=R}BWi@N35g10HV*oSe8bIBV@>lmtOSgEizgLVM_ zFJT0gA>5!bATD+`Mn=#e9b!!&q)!Q&R#XO^G-M828R!a%UhwL`WsiHn>tR7_yH2sF zF}G44``Jj8*>|I9}?s~4{)mqB8qhT2e{P)5$#4&3tDFj5uNfK z)H<{JZvnnr2jpr#E>=b^(D5%EOz^Y|a&@>lGj!=DBYUbwaGIhJTTo5@zxx^|PB3x2 zT)Xz=-ybJHW^q8x0?l>`@(BuZvoUcM3Gjfv+#?_i!u3&F^Y-tfoez@CeRTxpynE= zksTXr2`;l-&6V-2Z8K(PER{*ZvAzvld177T2ChrNtL&KAnK&4fKy`?egg84Z2L}_s zxV$)%zc{0~I6nhdkpdHJw_h66cyh@Y-`w83bA+$Zl@Tz75;DN@qdXolCwca+NTV2ObnSdg`! z`jFeQ1TDe)wLwt^8+-w!I#3lN$0RBOo?QhmPc;J#H3@@{C9`8THBn>CO37kml*>~P zXJQnI5I5!X%y(0;GnSV&3o3ADWHPhRaZ_+K$YoTv)#PAxk2VxG;wesN5QqwTEF=jl2bonO($WJ9;KN&FCg8ZbbB5G#Fp`xN? zsAVY0$iU29BnkEtsGtQ^>iXb556DmO%ua;2n323SSt?e_+aIgXOoI_V(}8l; zg|8rjRZv6`pXZEB7!MQ!u3OY%|HOG#LDTrCYMk|C< zghRzfg_%*-OIt)u$R@&2&D~H4bm)j83)?&y3n5-TOF2tUAx=3pX+srDP9X+H1}pGh zeGUdb25|=-K5kIO%>*CIfSybbtzscJTK=!~NRt(03-A^*)^ikeVB&aw=g#481ybA7B}=G{`(DlQVekQPn{NJSxw8p6NalXh}N*>{2FBRR~)D2Op&n z2Cr3PS7x@cj~0x!VXPMU_gQO;z*aj(t6)amgtNi_j)B@Y3jc$dbeMKAs4^HjNQ?7G zi3;)XOEJEeVw49R;VlH78xmqEVgTLs0N$%w2qE#v#`{1k+IByEN0VVmG)MTPhnx>7W7KDS(_~8V`e4_njGfl{`Z_|SHe>s zzSuA!U1_t>JTuseFwl9YpffEPQ18?Mo!$vrC&tE%d|MAFjv=Ba0zm!*t?g)GI>w*_ zI-N+SUYb!_T2)nq2Y#{zWI(CIiGt=+#o6_kAo)yPksa0}1FvxqXJcbD@Gh`r zW#h9AFLa78l8)zAvC=gQG3ViyU{n_RcSnVdnaR`3z{x-~%BYpcp*BX&O2(}`!XO|( zN6|n^Kh(-hF+oCxUzW!!T-sDsHzE*}7QZtvFkc7l^k!NB9-BYNC`!_x^wXp9NkUXT{*}pliWw%%iWPE-NRYtjr@M$N{<1i-$*!L68}|vPqDuNQb3J zm8D1yoczEG$3R;-A(Je~E95}^CQz9QIXMQr@C{TOg5n!IglKMTBnCNQ2FnN&GmEOC zvWgZjV)2`eFma3K(v7C=Qc==`t%M`6W)3uQ2wo|-6g+z<%V6vvEyN|k$tEMi&I+1C zWMGG^VG;o^j{vn}A#=2#@la4H3tHt4SuF<}orf=wV>C85RTPyzCutzdSSrl)R^$q! zkQ8@*VR@QO4rpy0|C@FH*cinX6M&r8%0qY8V-CynF?|oLR1T5yHqx@!;$UVLH_|E+{>d18RfKV#_$@Y3 zNrM1G1?My#XL~zCJ#k}AZedPIb+MRTY#fONOQl4WJuFNUJhgG02eS1+4;O$+6;R0zTFa-vVD2C<$1KUqAu7b% z55AlWJRT3pbwVsf+~6<)_2WR-wj-_Pb2UfgGGlD(`WP>&O3Eo|@W&O}=Ja4$+m~)M zZI7Cg`b+RS0Mx~O-=KBJC2;xf=%AvcpdukH%&Y<#l)taS*ssEIHCtRx!X9 z-hc<^K$rSK8pohM0c^DgsND$K=??1RvVl_?(uPoFb7jyP9cvTWKsn8YQbx)a!sac) z3KERM;+&qA!Un3^e4(1MfpVtcm4TBdzfh4)*dr~@!p1HweKbK)B51h2!vcNNfFpm zNv=SUBQ*u$3vHO95^$}RbYWm%It&g|X9rbTd2tmLZXxhEy#N;@7Z)o(HzPMU11scY zU;!4;f+l#$6AP}VL7{34ax%QO28Al94~WyfF8S$#seC!S?SgIc1*>HYK_LrU-x*{n zY@h~N->Dkp>>M-&+Y(O(CeW%&=Dke27~~kV7?d4^v_!eMIOOGFL-o*GfS~;bQ12A6 zavXeuCYv&J={VX*Jz`bnJkuFTpk+q??pK_IFV19=-T+?fq@uG1woVhe>Ikt|Ga0t@ z36x@?tK0cOYXo?iIO|y$@3S!WvoInL+p|DVbOx=^1qEp#sF(!RS<2uwnXq+lOnh>A zw*St9SJW^X+T>J%*1mz(pn}%SFlzi=2C6|oWdZY1@M=^g21^G;C3bdJadBbh`=X5f zqKx&TjH03pjF9OJw6(BBka`m|`2rq6hpe^(2Nr1TP*GTs8F?IEp(n?hQPw8MbVg!4 zGc&hys^h~91P~Sm@gO$0T zhw(lSV?F4$PWa$H(&8{s^#RTlFxP>$6M#Yp>JrGlf*jj_kL@59C;VLovJtvkbuy^j zWYB@ML%{d-Ku!yr3_dN)h`|>$n{3RZVWa5mY-1yVa!wd1OhCm3D22oJ)L^cGf(-7f zp^okggZpWa(S0%0;eE(mKCFB;k;Trg`Oe_;#EPt~BCL72L?x_cL=_bT#kHj*O{FE+ zn3?^SnMYdlafnG<$ciY*3yW$?OPDAtv9mJzg4RySSjxCoMjL|{O-X}J7>hMYa5ChT zl4RrM$S3sf9!^*_S!NJ82y9)-Cb3i>q zN64@`=!9iOrkInd=|(AX`QWQmn4&&R3k}}G!1({+|19wOU998mh%4|wU0mqsr>nU#vofl8)eP4o3u+V zq@KgJ?iy6%F*1PM*9kqHPFPBUot24$LmWJ~F2_>D4{57{!dl4E$OyFJ5WMOe`^dT( z*e#3`O<6=tWuyb7B0{0dzcsbx0~O@WL|t-v7`ZrjnOmDVq61*7z_s<+<}YO8<^Zh( zhxG56^T6S?6I$E60*|V@F)%P?fOnTIZc_1v=4gi{4___qsh6I+lNZ&%>Ga)*{RCumjlCMMw+Z||6##6b4~JJ^;z zP)cR_{{?(26&v_gD#(ZqWc|Ik0}mHCv$4Y)qeh^d8*UC-_6y2m%IxRl&Oq1Rcb}Gr zuf2Bzk9LF3huZ+o1CaA8L43^f;z0JZfmMNS#bjiN`yUK$fod@5I*3d1%1Vfci1Iqf zGRn$|GBOBp6^TMiTu^e>2lqBWH4(VfMIH+TmAc@<0By{Mv0XTdUs8l!l$F)oO4C)w zAs1Zc2%l7Ck@i+kNMU6Y6|jqQT${|NVXl-3S=7({Z!hQo%iTQuvEhQc(pi4lpp$DE z;usj1&Vt*V+79CEQc@1!#xXPKbP-6C3fh7Pm3ZJ@2Y8nOC=S8*UBQRl*_9EK$;|5z z&H?Q=U}IOvQ3mffaFcO>J3`D*ao##nRnUe5ZpdjXpm9CWnszDBiU?*gF$Z==c6J6v ze&kvY*$u|Xl@YT2pau0T(mvYBscdX2IqEEIR<^osGA>NJ{(a*CZFMkGgl~2Dw+57c zK%-BSL3@7~w}8{N_Wv);l1#@K^cXBb=Zxz!Xc-&J3v=@GOK@^BNN^W1fJXp?EcLY`n;FuSpmuL{<0=d8#bf#by*hdBo)}Rr5Lk1mFQ$=Yh36Q5yyaY;!g2u)K z{DdfLNbr@oXPmiAs%&f)3H~zhG2rO!7wFByvRXJnRUbQV)LlonDJ zH1yYlvJ3+BY>l;iI0e~dWR0|aIE2_`WEmJ492q?seIfgF9JpCIn7O$b_=+GMX>gOv zz|c_`KFvx)V5ztwptc;8@Vlv8{ zj>0Y$rk<)+N+FExc5ZQ!Dl#k_%%WmSqEc$+#zra@I-=$bj0_r#&Wwpn2N?7jEFDzE z85tAw3iKNEm?!8h(A%KLd_nJl-UmHqJv~(}RW3m}e(1g&=qN!^5olXA_`GrG(4I2N z;$X-jY@o%F(DNN2a|Ox^wA5so85t!dB(#OJB^(Vb?F=>K6ocHY9C*yRR23DJSs5AS zWwe;oqy<@i8;AGV&F{+X&!67x1b2=E|V80mkgg>gLMqjFO)G8+p$~8yfN$*vYeW zGJ1MAy!>ckF>4kBBZDoYGh-!q7q+5<05hMQ96P(HD3dZDe~~h{kp!7FfW?h6q8eqx z@G~e}%o!_r*Qu}w7$|C*E4o>j+wxm;D$1+LgCa~qOp)8(ifNZam8`U>zLK+!rkt9% zq_PAHH>;=wKR3q(&?*COMrXz%rdFBu4}C3t|Ozy z#>glwBcsa3$Rxw)>}1X*%%$RBuFEfLX|Kw}Cn;c|t?sC9B`e3q$tEf#E6>KsDkcfa z{eg_0jG&e-2ZO+NW;RB?A~tAn85jmD3xn42Dza}6J=)IaD8(qo%jn5y;?n5Ez|7#v z=*(EfbO7u>dj@3(K~+8xc5`zX89hEd2L2*G)*@(j038?szL^T@OURNB(3L&lHE7_S zR#<$>4nF4yw7wMP_ak}>SvaL2u_r05&dS6nBQ2xK&d4akbimPqOPEX9!9qts z&ca@miC0R%LR-T@eJ3>9WaPn-2y!RS|6hzYjOEB>Emsi_BP8s>Yc+{0Yde(;pe3w6 zywufHQsv-hVv?2ymAQ<}(rnNI7E#n1`eP|-89=uYFfj5m7BX;yR>ncfTCO4v2B@n* z?W08GvX=2b18mw)#`EtJ zUx%tX8zZBvn2ZvagOH1*sfVhSVyGRif|h~t|Fi$U7!?@H8T1)U9TYK2+7Eh+uu_(* zND%BCv{JSl)JlLyKD_9M9(9Ra;y@0_jMr3?V`gNO5|_{x)|Ld7vPSB%N{XEM&kaW4Vf0!Lb19FoK%#Mh1q($|z;*O>hw#WdJT> zSv%kbECb{J-~WFxnllzMD1**NX5y8VWn&W&VN~MfDpCR)ic-Q7E?|urweT0P&lwGI z7O+eV-2Z&sGM0n= z1})*rwm4q77sHXob*Kt{+7s~QXp%nD%rZczP^VEuuNHzE4}|6+E* zVt)`5FIXOAzXw=9s{KJw_i6n9#jFpOM>Ri)@dsGH-v3|B4q)@$q4sBi?GIvtoKB6) z|G`lA+y4K>tO?fd0o9)b)*sCH2y8wmeDlEasNoyJ1i7~ZWWEO$`A{ZquzryHjj^~t zl<^x_9%R1_SU;-$p^X2*@*w{Sg5|xS?gQQD%FZ0hco{4Yav!$v4Pz1pt>s{-U|?XD zV7ku0$-uW2v;>%w1#~F}sL9Hx%xn%iXjYh6;@{rd2gw_aH z42%pp42;YwOgkC48F)4`Gjg&s=jC<@4Yvp(7$)y zjDn1U-v8eDpzs)ly#KuiwctD$8kqT*tQhzhI5u*!F@Pp9g3ZO**~QHjMHSWA#l_h@ z?%H`9Fh((+{%0D+Xy9$f7<<>wTZ4ryhK)tT8@yub9QZ_&V+?!@JX=9i3*gq9fuW-~ zySh5NxS+D2xjH+$I^$}HzGzmEKBi-L?R@kZqyCvPo{nPF_pxJOWH|T#3sVQvF0eTa z+|Zdn14CDJb8&HVbwOi6c5!oaai}@0(O~;|AjUvk2Qr2MbixY4PwX6EKRL3io13e% zE1D{bo2#pvGxI^T!EHzL6eGiChG3>sOqt+tVP;^^H!?5`RulzYgvrRxsLn1fs=S%e zGTV;PiP6pR-)Q4Q zW-{#po5#j2zzywBgUl<3q(D$l4w43;=Bd;Y#;Wrn6g4~BAP zKBfu=0S1nZ>|9_!LQ|lqqNpM?4XWO;_10iPXk@CmYwKme7`Zxzkv)>pz{?gCTF54G zLemd4Ei0NTg5r-|oyqX7otGw(k6po4DA)Zc2rwW<^m&P#l_z zGpa(uhDrRN3n**YM&7kW4m?m;c`zW%;ow9z$5hc&5t1*M3?YH?&xJ{xm08ov4r&f8 z&_L$wWnf_12aQ8^E>5l@0eBojbBMB_vLGanFzth6{MFHnY>Qv(CQR<`;$*AvR&%nq4vdsl* z8@H$c#5QOOg&yI_CaMgx7GfJyIw;my*z{8a15*v6H3BOF0xAMD!2X0;=Tz$9S>gn< z6lxu~WOildV=85kW8m1xCJ9c*(Aowx$PKp96f*eDrVNQLXzlY!-b6vcMBX~d#wN-7 z6FBY|l_2gA)l*T?6Ajl2b8raLhR2r&1HvW=NX~<$aLBq(Gh=`}Ds7M*THzoY^+h07F*3ye|HAa0X%~YYXuMK^nL&UXdhZzc zQ~*avr6I>GDgx@;Lps#rP>YQ~ojg4zP%SB{%s7|PGR=`uO~%qt);PM{#jP^NB+S>$ z&fYQK*(KXfNJ&pdieL9VX(eoSg~{LWHTr29AD>5YpYZTRU0Ec zNmWLNR8VR{aht9lzdU!59(aTXJV)#Zsf_rTLAwv35dhj&k8mnz5(!jKG42d!Vb+q- zQxdYvadydbaGLbW|lu>7LOl8{j??kEtqpGByk&UWDs+D!7vu}>J zliB20=i)F!{oq0;^H3)2fstVeQzGLHru%3vL2||d zgiF9qA=V{j!mM0EQhX``#!QKPoLt;Iyv7m=yqsJ-ygbI@ ziVTblYndt;FEE{AU}jKs5MeX`TkF8UD8RsYfPrxXG%!H-@`0Ko=8EiV1sH_|nJNPV zDb)LiDVDK`=>dZvgTQvqeg?*PuvLYzpf)LFco9B9$HvBJDksg%#HyeyC(XpnqR130 zDayjbCn+Z(%F4ql3A(I`VIflz<87vU41x^G418OpIfXbu4Hs~tgAU{&nP-e)!&NCM zCMH$|1u02JW)_9Hk|3VEg0v(P6N@5KlDH5HFOP(rm@o@3kGMQ4kAVrzZcb@w1|bH0 z$YKIV44a^{PDrj{oP=WCT@$HkY9+>uW~-e4Emk>9ZaDeeFjE;a6E!6H86BkHy3A=jg56+a$lwc zwx^BBlkqk)Cj%RUrh^0vGb;nb1Xjiktc?1sjOSSy`B@n+urjhj+#DMV+F%4q4#wi_ z>g?)_5?PTJ37sa)oKv-mOF&z>7!anZJBYKfGBHhnx#B$7As66oiH$YV2dz5{RyPNk zw##G^$S@{P?Wt3>iWwLg7BU4f{$LhjU}JD}&}L<3VT@;HWM(d4WSqdrD8R@Vz?i_u z)Bq0A1&kXQnG8Tde1H+uu8l1$j4cG^4`cm8P_qMcXS2GwxVboET6UCWY?nDx&@`=* z63|^ibh2e0lP}{tW(Ed922BS^UQPp62UaFl)&g+O7669}G+RRpIZ(JbDygZdn?p-9 zb8$W_NUwv0aIXNX&WmQ=PMOV-zdkplnYdMoI<42~S z41x@@4*a~Vtel*X=!T~_BWU<5si`CRg`JI!(ZbL{kUw06Q<|Gsg2OOKTEU0OSKCle zDT=5ZGX`D;c?M+%5ph0t_6-b-7r-Ir&%g+}k_?(MA!!Mc zwV@LOSY`wm^^NRQoivT?)Et#16j(qP;YiA}GBZmsS=j6AI4axe>o}@d%S!PHv5AVw zfGKg%sr37qOc`%8gGyvjS!V5^D$Om#!pP12frU|kg)snhJ(oTUqdyB{J_{p13u6Nd zqX7#e3xhr=5ypa&qp?1y8w1Vr%-{kDk1KCCY8I9l+Nn8dfe0ljc~&MSNiivTRz_w? z=EJjKP;BpF2o zn7O&7Ku44@GBC+8E@T3ogTt{2eA_#y2vRm@To~o9$@JtHc!$x-|N4x53=#}d3`!0{ z4D9>a&$BbJ^YMv_Ita^ni1IVk>Kki=(nKt1{L)oP4b;*wHUiy8qONXk%q|WqgBgX@ z&3W|LT(JS3Gj)qFeL{wGcila=^8UIGDQ8?XEbCG zVi0GL*eD3PaMXd5L(qeP7j(ieXe}A!@O;pmin%%{Ga;7v9no@-v({p^<~K9q7v|@a z;n5K=y{M)kt*6E>$R?zuBg@6l&%>`TD9OOcsKeyOcmZ4{3v6fR2bbvJ;v5>Wj29AI zT$q{niX3EMW;n>?#-s{XD+<{)AEt(*bQ!GOqSWO31q>d?xVF%Ma7Ix-Ns7O1L zJHsbtNfvhIZm7r|CO3wK%+f6E%so(%IZW;hmS8o#P?2ONPlg@LoGk3jeNd4)rXYqZ z%t9>e%oCs@)l9w&r!$F9V z;Q}Y)2TsNYPDXuBMt)94&K>^`Y?hMu;AGI(js=ygpeuQuK|7g1DW6^4+?B6dOT=MIw`Lmkr-7Ix+tP`f8H9$_eD zDrMkc;M>Zx-o(oVO8%QUxIIAI_>7DU4BcVLiCx*u3^KlNZf3@d$oSlX;EZn} zCc?_etq#ujOdTHdjtg*rdVhxEiu@eB+rvR z%>OHy0vUEP&tYI@0F~RS4kGfrVk}I&yag#UyVV0LC5VD{y5)lrSii)yX ziO-RjmuYR8hw3I&9w>iiF*z_gFfU+WX5eCQanKClNZ?@NU}0orXJO}LVG-bDGyqpH zoDQ749{HS%{hW*eoC%yvoS^b7Hdec^u+UfnvWgS5uRj*lK2kSl2X$}Q)fpWcY|`Jw zB$y_)8!?wISJb>`XN`1E$r6XD?z5MXBqcf~${@)lzNYXU1% zJ}aX?D`P(^Bk0;FeOBfMRz?F*&kU(31zQeTYY9q~&Jc^u(aTi!s0_p0HjV8@R`P6S zJVMHH(z>#u#{Bv&Ob>GPLqhc1wC!c3#g!CfRU~BO?6eq|{%bQiFzjTW4GtFv2X$z; zurn|aA1a`%Z6s(MYhdUMN_`Ngl_rEcS;QooCA1qeonEH3MGz7s3{3wsnH(79nEM&H z8H59Ud=XeC4WgisI@fc4r|jVRrFW5S2ET)04^Yfw~7$Dja7HfTmqd2Qg5o zz{tRWEA@hlGh+ioXLCh%RwB}Gv>>CPz`t+M6bzwI%Lb-@K|yO#lPoHaf$4t+lOw}z z<{kz~1_g#l2jc*_1UV)-DOq_jFd`9yruMlj${}qg_D*Z;%Kyf^F1-?C64S=u$T`6Nf}Ao0tN>s2o4Pw4l7O zxw4qNfQUSZBPVR89Ft_8)MCus!w)Wd4aAio3?nhcnXS4xIp7}b6lPY&SIq4UlAy8; zJ|@V<#=yYnz`%GO)Sj5nz{CJ5+X@Sf^obpZYmiVD5S14Ylmv|kDnmE|(gI4tCd{n- zoS>?}SW*#ECzwcp#^IJSb1>dyZpGn_eunuBObfun8KB_?;@wdpA`2c5l;TqnG?Yhh z1dNzDz{7yN#^Q>gtE+f0fWd)*=>o$8Xb8Z@00kL^1eoQ) zV}O5|Ss0s`+ZY5H__lF^oe2sn(69|gLS!_R1vM=dm1RLqOGRcD2~k#V$S59&0<8~Q z$jr`oo4Ex%iYMy8CCw>>WF}Px^O)Jig+PObvY=5sUeI73G7sd2xlC`F*qQf%$J2PW zu*&<6&k{UyN%rR12g;W<1>L zkk346snR9}MuwwIZyA%A4}i+H&Cme_=rEZQXqfEna-HoAj128e9~kd4uV-LmP0JZ{@;$lHfI#48Gj{aC0I0*4a2y;nu^NMpA1<5G*FnxxM{xCDc zM}H15-D5n!d29O^^1;y{udq;-gA%;!#{MnSQmy_%Djk)4{8l9W6P6O#nUWlT&GEGF?9 z`Tz1QbhT_0EMQ|k{464(Qj(kkEFz*PBNIGZn4yUs6!h%s=18LwjQ{sBJz?l(-pl~n zhsejsAkV4K$rR7YIG>Y|6I7nYqIZ&=c&pXr6eQJ6ZJ1O16-8u>Wc6iI7?}Q-GreLs z$Knj`WtliAAbNlWpftz8Ai%)nz!1Q|qz_7cjNsG&Dyw7h_w)qJ?B&?3c?6+7Jz+z) ztS0LWrdK+S3i6Pip1hKSHms)yaf2hw4Tzo|*=_*!=rG-278Pxa?uPc|nwvo_Mu;0s z7`Pc^83G)PB?TE7)-y0Na60hIcyMxx3X1Xw2r38~2r?H4G71Vh@C5KMUEpC{z{9A| z!^prRz{AAD04_BOjrC(egVmsBlD084qa%-2u%ox)ta!^H!xwgH7@@}e(py19##lyQ zCjCEZ*umU|9VO7h7m-B#2b^LdvFKoLw~x4`hog3Wz{^YUV27ZX3UVEU2eekLjTekc!z* z99l!`iz^>P_Zjp5DyHuYyI34SH6?>OgF2*@#>C5;z{0qIg;Ae{@dC>O7A6*ON{8f5 zP&=7~-dol>S#Y;a5nBt5MRd9RmVetM1X%cBy*DvwR2~DwjW1Z7z^#2P24e>ql-^qc zJL3X&Mtye13+xZrnW)i!vjX+sj^c4Pb4QO}e!kwn$EZ$4<$?NdkkEBNgf6uIMj&*F z?7>M!McJ&t=gj=&T3e@}x(byCO4}Js&lsJ+DS(T?z(E?(dAq>L$iOMU$)wN8=)f5O z>a&6K9cV&J5R~aa2?0C^3$3=D8f-H@#Uz>~wHmXCE|cH97}6DB`k%-2lHmr6Jvjc1 z9b}PvYZq7<8CV5aneU}c94MgxNxO6Qu|y{;6B$^d}(e;VBlKRM25;^VEUiV^o-#SixIfbRbK%Plop3y-*K%Pk+mM*Y$unY{H3H7g7#XgDEw+HC*7|5st)WaeRD28}s0GJw{Nx(gZ$athsHe(^^FG@d;F zzY0Slvk(Ix1J@=FHU`LwAa_A_bGsrS{FgQCXt0>B;s@f=uv$IG^2@4w;X|r&1+t@fOa1}Xo7iqH=DT3Fe zfKE+<4Oi)dcE?zPHtB+gHyuSFr+-6wouK_rp!O8>P-He%L3Tk!c4bk>DMP zW@lmH=4Ox<z-jFEW{?t?b(!KVUg10$t}tz^rzXi#1%tS*tNu! zDaIt)GS4!~lsTJ`(ITbE+q)^nf{`(s`M+CJ(-0~L2IDYK+c6t0fHuJM8%EFOdGru3rJY=*X+#F9LQE(X@@)S^6wCNS9rCTD@kNx6wd*$m4Vz-RO^ zOu|ERFfcPrVwlCSh=G#<#Gc2njA0#=y^3KI!!Cwx3=9l=7#J81F)%QkU|;~tu`rxt zxW;gg;TdS|g@Ks?1VEw81m%Nnr(yw%GlB*M7+4rs7+4wD7}yyY8CVz?uXI4^9teHz z7?chJ-RRB0u;KuiW^DQZrWw>zAoMCd2(7;cLNjE5X~wfI5c)U|gg(jznj>RiVqjum zfwCCjEM_=uywR=fl2V|d2`q2F^sXyFD1Cf*w$^#V)y(ijXGR6rgDV}39RCH|lJ z|M&k#28RFt{{I6B{Xg{o`~Qy&AXofj;Qjvx91;xw|A6Ee82;Y@?PY?n8BonR_W#HK z-%uF_28RD9|G)WvlR<=m;r}lN{{R0#Zbg#a`~MOH!~a+RU;lpvw(H&h_Ym3tyZ*oZ z|K|S(1_p>}|4;sZ{eK+;|Nl?_KY>+nfk@Ep*#E!(|MP#@{|yWb|G$AChz7}_V~9EE zq7eT7&k!1!gxUiY`hSXnfr0=3UnrO1|God8|Gxs=kIKM+Pzg2%QZEOX z#Q@R!|H%J8AfH0S7#RNV`v3a>oBv2Qp`yF~Kl}gi|C|56|G)qL`~Odb36I zKqLtN{|-_EW`R>Bh(#R!e*~fq>4k&rO?f9n5-|EK<+{C|Ui z0py1NS3v6jKmUK~|F8ew{vZAS?f*3fR?wK%|K0z8fc8QDfBXLhSoK2&hX3dP-(UdU z`^Err^Z#%EKO(2N|Bo41{(k}6^$twl`TvJOooX9r*KMg8-Ve!kr z@c#m+Oatp-K?)~U1_lOJ28RC+!Kw5g1MB~P45A=&;Qso?zz){MzyK~!{(t-bi-DCv z5S+6F7~~iP8Mqnr|9=A2lmGuQaDZrtdPungVKXrN|IWY-Ne3_y1_lPc|8E#L5jvnU zpmH5a6v-u^(AxI@Bgm}`44^Xa|F8f1|G)bG;{WgeA3-SxmPWxj;m`kn{||%8d8oPQ z6lmubsu*a`7ie7{NEB3pf@n~Q!@!`%06LKv#7D#buYuwnA^88!|JVON!Q2cJ2Zbnz z{r@$ng!}*I|MmZG7)1Vm|9=}&0x&TAU;F>Y|I;8f5d43`|LgzfFi8IY^8XQ71e`8F zX9@oYt?`-je;EVA|NZ~}{NMlog21xk-8wNITZejq15d*{j7a&n^Ey%*a2FvlF_=BV}u)jd}eSZ4? z4I&FQ?FBeZgWLmZEByO^=l@p*5m34H{|Brs!@%$#R6G4)VEF$P6wXkaK0;^+`Ts0h z`E%p{hyQON;qm`1L=7m6p=B+&e*gdM|8H9fN>`8|xXtw+l=A+7N;|L+s67i|ppjsmP%-2X0||lB0*Hp-|2O_W2KnRv z^Z%bfDGj9a|HuE|{+|TNgLn)K|3PWvJE-OX@&CVp=2K99fAs&w{}=Gu1f+#{3@KH? zWf?*fC!T*o` zfARms|5c#)0p;=k4;WY&m_Ysn<7=R@oIwb*lOCl0|1SoX|9?O-3=IEogG6BX{~xf- zFBJERF!25V2CC0NZen0ykYx~Jko$j*ffHm0T<0ffScowwf$scZU<9`lr5L0bBp75E z&sfsuio zft^8$fdh2%0=UfqS{1~_Ai%)Qz|FwVz{9}9z{SAJz{?=Zz{kMH0BTq9gZ9oa2r_Uo z2r+=}xDa6wVPIqct;FVJ5MvMnuTK^Stx;x>0Gka73mFC;23ZDK25AO41~~>61_cHM z1}1R0Ffphxs4;MW<}w)Mz@fv$pvR!cz{Fs{V8Fn~V8~#|Ak1LIV8p-%4lfY~GX^sT zZU%D(a|TIpsPQsHF+?+nF~l&$Fvu{(GQ={7F~l*%GsrL`FeEaFG9)o1F(@%4GbA%8 zGo&!2FeovkGNdvnGo&%3Gl(%{Fk~<&Fk~`hGAJ@+F=R0)Fk~}iGbl0?GZZt(Gn6uv zGRTADK$PJS!(j#~h9eBO7?>GuGkj)XW%$DIgMpFZC&MoWW`^I4ybO$te2jt&0*pe8 zq72N8VvOPp{EQNe5)7P-l8h=0T#TxWY7DZB>Wu0P{EQlm8VsC_nvA*(f{c2Mh76pH z#*D@coQx)nJ`9YEzKs41oQwgCAq+x{p^TvnQj8Id(G22@v5dtG?2ILhjSSL^O^mY`SQuwB&Szj^+`_nnfr)W9<1q#f#^a2~8Q2(4FrHwLW4yxnhJlIk z1LGG4K2Ta=5N7<%B*?(VB*Y}jAi^ZZB*VbXB+Dev0J4%v?6`XE_!RdyV z0hDf7!Rf{ToNh$G>4u8|1VzB@YyPS4C>&N!^8!D&bW zoQ62TX-I`j4EhX;;8Z0DPE}IiRK*TXRnkbQN(r2*_`s=3 z7M!Zoz^O_WoT}8osY(W%s`S9AN*|o6^uVb~ADpUW!Kq3IoT_xesY(Z&s&v6QTML}C zwZN%LhT#yyAqEbH!wiQRco}Xpd}Lr`_ykW|!VEtdelln?{9^dUz{~KP;Wq;t!yiT- z23AI1MqUOsaB33)r#3EdYGY)SU{q${U{qmLW8h*`XVhR&XVhfWWZ-4gV$@>LX4GcX zX5eMiWz=QhWz=IdVqgTPIW9&MMh6BqMn^_B22nv~m zV~k;pVNhkvV$5d{2d6@Lq*SQF*u*%4fr)V@<17Yda9ZSNT)?=9L4k2G<7NhC#x0Cn z7+4s$GVWlI0H;n)aOz|Sr%nyVlZ+=BG#O7Zo?(y#m1+!z{INs z>iY@I<1=8;W&qWZ&|>`mXVA#n|6`!GBDmGb{{J1cHiW8xQQ&bl2?p-}XBi|wEk7{+ z2Odj1G8LbH_tT95zye+wduO#c7;|LXtO|DXRq0jmH0|NZ~-|JVOt z!R%lE?}6G}pwS|*8qgTV)&E~WtwgX(nHU)U-~a#Z{~d5Y^2YzeU~@sEeW3m*s6~6_ z|Ed4a|Nr>^<^TEr?-{s2z3Bh<{y&4XjKHeF#Q%%`Z~njb|IPoq{~!N<02Trh|Ns8~ z{QvL&=l^f~KgGcP|0=j22OeAdf9L<_|JT6g{e`tE{y+Nv?f=F9S3tev|F;>0!KxpE zL-!@96%RHNMDT+~1OMOqe+}%DPye4I#^Av14UihhIL-b4_y2$X|Kk7C|KJt?$Sej1 z25ykO5Je1};P&3v|GWO51GhyuV0|10hW~%T>LFtRpcXP{gpmFJm;a|3_(A5uTbSTc zivO?vfBygE|MmaJ7#RMq{D1iWxBnmh|NZ~#|JnbqAw9bPU;n@Q|K&gE^pzL?zy3e) z|18KI|93NR{lD}7@BcfXb`I24ps@o6cuQH50n`%}`M>4=4+c(X9}N^cpwU@)|Ac|z zKWKHA?EkwAA`I{zC@38;fO?nL;iGgL{vTvu_)4|6l(ffO75sbN_FG#6Wia{|WE;egFRs z8pe?EJ#d)(zXyt0h-wfC^)V>rGyner8jA$wx&MC|SimDY%>RFaN-uCe1@$jMaSIx~ zV`7l_|Kk7i|DcgGkhvfXG7gTx?%mG7@PEbsUH^ZA+T8#D{NM2ZJEScQ4popjVD zf$RU@|NH-cf~tJ~A9Q9m$fvM51x^O$|CbnqKq3GCHaKVBMD*$YfBXLzMwjbr?O52{NbW4Hf*f>O)>U;l42F#rGh|1TtEAj%w&q5pq_W^w+X z{C|^y9W*w;!1ez=s3ZZ&fibwe0kQsr=5!<&*#2K;5COXcbzBvs1d9LP0QJ3~9K6*3 zPycU$atFF1P>evv>OuZPmWB4BK;Z>XZ3ua=f8ldE5OGj>4bGE)L8ktH1R4qW|LgzH z|3Ck~|NjXRCZMzSK(Zj)!1V}7=F|U2;Q4`{|Gy#TDyJ{eKPfA0%!->Jb=}dJ#Mr3ncpg4`^H!)KUYv3nT-|qyN8wQv#^%04ird ztIqx~uz}Qr>M)4SAU$C9zae=Ntb+~Wlm8d~Uj)?);5N`VNVx%43#vOn3{Wixnz>+S zVEum^H2(pz6(oUfb!(8|L^|4{=buf^Z#0K zO$urWeEYxu|GWQB!Lb0!wV)Xi1_sb*&bt4r!STF>f%E_6|3Cj<|Njf-Yj95f_5b1j zm;ZPC|M`CwxUPQ+7Txjx!~grBaDbEoAeVqb_5Zg2XTb8S8QA_G`~U0zaTK#2{r~*` z*8ijb-!TaOe+wEphO|2VzyJUC|0(eJ&X@m>K&CP<{D1KO!~fU+-+@ZD|DQlLFayK? ztDx}se+L{!C%`ibAO4?UVEBImT$-Q#fA#-iNDP2m2%sFd`~Pi_pF!>eVMvSM|Caw3 zVPj?g-~68pk^!|Cpe6oQFdsH63+3RZ{(l154wHxa7u3pw*8cxL!_zAyg@KjA#K0Ud z0cnFlQXW_UGQ-IP9gSiDk4CYB`>c}SKC2YC&nnH7!<5e;$5hBv$e_ej%2dIi%v8lx z!=TPo$5h9l#niym%%IKG%GAoB&(zM;!C=7D!!(n@h-nVfTm}cG`Amx#oS2p}En{$F zTEVn}!Gmcv(`p7!rgco~7`&J^Fl}J)X4=BEg~5kuJJSvZU#4A5dl>wg_A?!02x2X?2r{by)oW@2V% zXk+GN=3(ez=3^FMn7}N=EX**OS(I6nVJfpEvo6ClW+P@JhSkib%%%)$m@Sws8P+n} zFgq};XJBGT2af}=g2w^a!Q%je;Bf$U@Hl`VcpQKYJPsfQ9tV&Hj{``7#{s0l;{fd7 zaR3SMIDjO096$m*4j>60T@nY6E{TJ~l#MBeDThIXDVHgifuAX#DW8E69KMW9#Z1Kv zOiZAC*i1}iOyvw*OchKO45Ca`Ow|m`Of^h342`10&N3rV|W|OedMn zFfcKlWjfEm1&&csrYlTW7*v?9GF@k2X1c+2i-D2pHq&heC8j$}cNoN&?lRqFkY~Eb z^nihp=^@i&1}3H_OivjYnVvB{V_;%>&h(r?f$0U)3kGJUmrQRMxS8HFy=PEl`oQ#w zL4fHq(`N=orf*E&7?_#9GyPytX8OhSn?a1}57Qq86{f#Te;JsV{xSV$P-6yVFD7Ot zW@ZK+W?p7q1{QGY;RUB2VQ}gZVwPc+VUS~%W0qr(VOC;RVPIiaXI5umVb);QWZ+=d zV%BBgWHw+nV31`tWHx5t1E(z^W@}~}1`cLBW;+HJW_xA_232N9W=HUtaydA)v4B$> z7dW+vgHsz9IJJp`QyV8ZwaI}~n>;wR$$?XwJUF#+fm53dIJL=wQ=1GpwaJ2WurxRa zOM_DzCpeu+G37DkF))Htn=m-FiGb4?J2;(*g43BWIEC?nQy3FCg)xCs7$Z1^iGfp? zGB|CCfzuX0I8||gQxy|aKT|&g2RKy;Fim8d$e_YBiD?o86Vqg-$qWKaQ<$bOs4z`s zn$Ez;G=pgd0~0v42{FxKn!_N-G?!^E11r;fruhuq;Pl7Lw2)~bgCaN;N-`~FTFSu8 zw2WyPgCaOB3W3ui8#pa0fm0zbxD;V!+Rn6{ffbwzd6;%F?PB0z+Re0wfsN@P(;)^a zro&8!8Q7VQFdbzOVLHZij6oBeF4dS$GM#2%2bVOW;B+a>bc5*z10T~ZraKIL;8ZBU zbdTvC0|(Q6ruz&6Ob?hIFo-aLQY0hO6Q(B&986D{o-(L`)1@*vU21~UB?mZN@-uy4 z`oO@%^pWW!0|(P5rq2vaOkbG3FbFXHX8OY*22P8N;IzmNPK83uEX*tn+{~=ZYz%_T z?9A*88qA!`oD8bWT+BQS+{}E;{0z*@0?Yyo>fkgg2~MLD%#xsUl9;8Kr5MzirI}?J zn8E3lhgqIko`IEFfmwlphgp$XkwFlgg4vi=nN=BBnbnxp7*xTjS&3PLS%X1?S(90l zffbyldBNo+E4aMm0jFsRW*cT(1_f}MW&@{bEe0mm2vBd8os0DWcqA8Exq$jk3=H75 z2G{@3;MN!a|MTE>46OAJ8d-v=2GgK^8v_Gq_Wb{M204(>|9=cz|GzUxFvx;!++4)Lr^UZoj(Vwegj^~_6F300J#v}>wNux z*Z<%DfB(M^TGIxqsln^oz%Kj`8f^lv?fL(gK^$ZXc+3d2YTyzBs6_`FcL59kzxV$I zTm=K9jSFktf!d-VMc~@T@zS3u*O$nJ@y>hJdiat6IS8CP4mSX8^5;0m&d#fY#qZSKPs7w?PU( z7}QzB{~0uI`u_yDg@6A4jsI8v zp8>7i`hODK(+91-zsM5DOfu4F9kF{{fy!18e#J{r}hhzp$AAmKFt*cnHWWg{{>33&~b&6pcNsYp2Ghhpf)U| z-w1BSLVA##3~c{z{r?GBn*uTgtbzrk0>lGhkjVdEAb0)$2Mq;=|2O{sU|?h50m(BU z#vLJCI0;q_>VJYnK7P3?v0hhyQxe z|LFe*|KI&z#lZ0YD74&p!NBzYENG1nNFAsz3!;(ne>`OfL>*$Z3c`nw{|TgPh$`^x zycoEZfV*X`z@*3^$E3of#-PBY!KA^U%%sJn#h}8Z!=%HY%B07n$Dqb!$YjKz&Sb)5 z!l21y#bm{x#bn21&!ElZ#N^DN%jCx7&Y;ia$>hmk$mGN1%V5M5#1zC}!W71o!eGjj z#+1$A!ob8}2zCb}xV6FzZmn>DTPw`q)(Qu>wZa5$t%!kJE8^hRiWs=HA`Wh?FoRnw zLg3blFu1iM1a7SegIg#}ObSd243bQWOo|K=Oe#z&3_MJ#Olk})U|$J>eZ>#pdR ztW5e$`V1mWhD?SGB1}e1Mht>rA96BTFj+8gg8j+HWXEL3Aj)LVWY56Pw&wNZ_OkoT>OyNus3@l8MOpy%yOi@fx3<6BiOtB2C zOmR$c44h2yOo;4oqWhY=4rjF`Y- z!~+f^M!aFfgfomlD+Kt!Ejm7Mcrjvx7YCCnlPUu*lNys612>LPV*!U3H&S?sfkmCLabiaHw&DLyZd@Y8*`AOyLZ?Oc6{G z4BQxD#{v#JQE=F?g2PUPDVZsmfte|VDTRTJDUB(eft@LXDT9HNDU&ISfr}}dDVu?V zfsr==lw%nWvDvX(@i=kzvG{O45cJ?HVqxMdVz=TpVUgevVDVwMVz=V>#N))m#AU?Y z$NhrME@BDmJ*`QsMl4zUc7ZE+=I{xyEK5JY^Nq!bHAYB>y@7v80t5dNt`4qyY@3*G z;2O;~)`?9d_mF?10GALI|>G3Nu$2b_H{D7uT~2*)R|7)Tr^ z=J>={1c59}5D2o7+l1RhfQ#EiL`Gy8h|O&xEFn-LJc~twg^6PchX5#)#qP2Auzdlk zhF}&Zj!(EC-wgyrsNsCTWdwrUeJ~g*=BmT}LPC%G1@{XcCqzgfSR7FxHt#wF1o1(b z^&S)&u_8g1ED+?kLx%$Q&_xh@mSrr($p8yDg#4zwPWD)))Jl`OY#Rv=RU@>C8 z1xan}4Is$B1Q+CVKtO~VmStQWV0e!U3jMO!HbJ0b4)ZNskhKi~VQNGTAW+N)8M0M? zpdp9p4rMthKc^3XgY^H$495T8GMN6q$-u%O z$socY&A`QA%)rH93SKoW$-uxM&A`AA`TssM=(Y*a8WRSvJZPWLVFm`qP*8gmY$E8E zk3t3(hB5{Qh9>aXuJQkWIAqEg7#PF;|6z7!;9_?F|CQOFft5Mz|62xj22%z>hDZiA z2GE@)P?MOw{(ockW8h+72m1wdo_!eu1G5hU3v)077jp;$Cvzxxb!Q=iAjozcCL90% z#SrlS3rGd%W)o)b|G$}i{{LqN`G5nvy$md1TR?VmFu?Q|GKgX|gNp&QN?VeFk3stX zR|eDn-x;MCq!?uw1Q}%+L>ZMCcp1b0|6-i^e+~l|gCqkBgYo}w%+3t5%pMF%%w7!a z%-#$V%svdl%mM%3Fo*pA#T@$oB?A{jqj4C)Mx3@ps94ARVQ4ARW*3=GU(4B8Cb42BGx3?>Y` zptxcD#=yz=oq?0_2LmVLPX(?sFlOLjF#Z3PQHnu=QHDW@ zQI%t6f%e~G%|29G%<)UJ2Pl7yD_LRdok!Sdo#!}`!HxQ2ZB#cgr(DD1~!IN1~%mM z3R=m-?7|?$?8>0T?8czO?9QOX?7<+x?8zX(?9Cv{?8CqZPS1i2lK;Om82`V|V9LM- z_CGw;|9{Nv_Ww7tJIMe4-+=w^#~=U=1F$ccgP`F6GUXhD@&A1c0sp@-(E2xj8pz*>ADiN5S85o#d{(on7{r`d4 z?f(a6kN@A8J^%k=_WJ*f+2{WU<{$L}=CJ?Yz-|&nbCW8Pn?xDa7(|J3 zlQ4rJgCK)3gAju$11|$wNyYe$L6Gq~gCOG%20_N341&zg3_8p%3>wU?3}(!345rK; z3_8qS3~tQc4C>52;FXV(|KBkf|G&s!`u__<EQ8I1qmL-BFb{};?I|Nk(%GKes{GjKtD$j$7}Ai*5KAOST| z7|BFo<}e0+22lo3DG4f1P5-}P2>Abop%9dV|G!{pWKdyfVi0F`XE0*+U@&6#WYA;w zVh~~WX3${v{r`s9@BbTS|NkGD1O9(t4*dU`IfQ|MIrRS<=CJ?IKxdFLFn~+efd7vf zA{jWrrZ)Zm22LTapc3W(H)gN@ADMmr|7Q06|CZVB|668%1_o$&eqs*#|CTxU|6}Hm z|Ie61|9@f*`~QeRl))HO%KU%GQ1<^DL*xJ7&{X_~+4cW#X1D*}nce??0+&8KM>Oy7?=YYSeQdVvBbat4pT7(V^GRrPy?r&CI$v(X9f{w7Y2T2R|X+w zH)wczFo-aFGKesHF-StoF=1w31{UT3a5=`s9K^uI91J%Z5?f*nlK($2NdJGsVEq3Q z11NkW|G$CQ^8Yh4Bouyw>jIDeKbSrLe`WUi|AyHc94a@V?qy*PWZ-8G0-5~(A0#(2 zurP=*NHVZ71pNQb5cvNGLnMO|*wjV_eugFnW@cw_dB?}>#vsh>4laWwKrIHSyFqC} zfH{CcfH{zXfjRj9Pv(&SUztPy|6>mO{{dw3|4$6k|6hUgROJ6Fpm1hr`u~{O8C)0q zf##<_%%1<O9;pgNavj2Y=8bS3r*u8I=-T!}Q_V^FV|DT}lear02zy>vqfjI!2CK#B5 zK%v3F07=K-v;jK5fS-Yp0kj7hv^HIZL5IPdL4zTHA&0?)A&;SeA&{Yrp^PDfp^>49 zAr#!t3hmKf)NsxP##hcqO_&Xw4>LBI6Y%dB!AWXXY@*bqo>=k_^HO(hQv7 znzN9BjiHf2l%a`1mf4xXklBSnhuM`u9a?J{GJ7x>GJ7%@GJ7$YGJ7-VF#9l=g6krG z1};so+jsHJ@!kcmC|EJ8(|Nnr?4N&dw`Tq~I z*Z;TB7zLG*OwdpQrE?Z=Dh&Sr3lgjU|ATXnBse7+|NjPUwfQl`GVn4KGUzdsF=#S0 zGKerVF$h3&6c@8A10ORYCxOZmE@mGF5pZh?61%eC(h8K`ga7|!4rO41+rkZQ{TlxV zrJ-L8jSRdDO$?mO&I}UFE({=(g_+$LIGNoUgqb}Ugqb}Vgqgh0S?8aaQZl8EEs55&pm@#`Zs4)95s5AS4dR6~_F$etr3a%-G{(oW){{IYG?mh#T zyD|*y;9VZV3|tJt3_J`h47?1+48ja745kcR42Kxh7!EV2G4e48Gx9SCGYT*WGYT>Y zGfFbBFiJ77FiJD9Fv>8nFv>EpFv>BoFv>HqFe)&xFe);zFe)*yFe)>!Fsd-HFsd>b zGpaEdGlnv#F~~3&|NqDUs-FY@-(ZMjkYxbf^a|?dHU57FY9m7WZvQ_pyZryi?E3!~ zv)lh)%f|6fLd|9=?; z|Nmt?@&66uhyR}$KmPyB`04*=#?SvhGk*F1nep5I3yk0YUts+4{{rLB{}-5q{y%0C z{{NUsCxaOSAJ_%S44e$944gJkYCGX`OBSR^rkM!-Sk6KM1sUOq92F$gn>GYB(DFbFeAG6*wC zF$gnBGYB)uFbGr8C7>QPC^Z^0FoXMSf&bq#ME-vS?}6qsh(huOsKp7cb3_@#z+oW| z?N_RRd!_CS+|Zhh586W&VD@29VfOuhp4spJ6=whcH<<(e-(wE^e}y^d|4ruL|L2)Q z{y$<4{eOiy?Eg&$6$VKLb%ucdzZoJK*coyeG#K(3oEZuk62NJsk->(ci6Mkhib0c6 zhCvft`pAPzAWcSP22Dma26bj<1`lQz1~+C`h7e{qhDc_21|4P(1`lRW1~XXo{{Lk5XJBLwU|?hpWME_t`u`W2TmLYJ{s)a>d}mN$5dMFKLGu4| z25C^O$iT`F`2QXQs709b|1(40|2qu%pxWgB5r#$vP@hr?I>rJTUyx^11dp>wLCO#Y z0cIBl0dU{MjX?s^N@w6=_Wb{o*^5D**_(k4(hB&$oZ0XHa^`^l%bA1zuVD`Uzlb^H z{{iOE|BINz{x4_HLO7Sj!;F zSjQmB*z|uNWAp!gj4l87F}D8S$Jq9NA7lIfeT*Id_c3<<-^bYXe;;G_|9y--|MxNW z{@=&g_kSN_|NniA6aMdGocMnqE(<`TJLL6t+!@6GKWC8qe+S&Ql==UVL5@M3 zLGAy426fOV-v8YUCjZZaYhbhgYZxQ`KWB{m|C}-E|8vIZ|IZmK{y$`_{Qr=#>ii-WJYyLlEto{FxvF`sv#wG@F#%2a_#uf%~##RP##x@3V#&!mA#tsH?#!d!t#x4eN z#%>02#vTT7#$E<-#y$pd#(oBI#t97Kj1w8e87DD_Gfrj@XPm+y&N!7poN*e1IOB8% zamE=8;*2vH#2IHXh%@f~|DSQs|No48|Nm#)_y0fR{{R0O5B&enc<}#!#zX)AGaml` zpYh25|BOff|7Se*|3Bji1}-L{|L2*6|DR_P`G1~C^#6G#vHxqB#Q(2hlK8)dN%H?1 zCaM2xn56%&VUqd3h9QK3oq>yi2eeOtL4rYyfq_9BoHisFq#0NkWEf-_l^6sWl^FyXRTu;rRT(50)fglg0~i<>0~r_?gBTbXgBchYL%^fkT#OM6!i=j!i*IRvW%4svW!&>vW(RXvWzthvW&G1vW#^MvW!jtk1{s@Kg!th|0rYY z|D%j;|Bo`Z|3Avu@&71e=l`ROUH^|VcK<)h*z^A=WAFc?jD7!)GWP#J$~fWwQO1e? zk1|gBf0S|Z|D%jk{vTzW`u`~7wEssLr~g07IOG3O#+m<*GS2#cl<~y>D@;NRTuj0Y zTudSiTuh=2TufsBKQM{^|G*^i{{xfc{|`)3|35HE|Np=w^Zx@w6!_FJ&{`4Dj&||? zUm2wSe*@2+gZA4QFff4oYbO8SGMN3}%>X(R=qLjN!!ZU12GF?zCm0wQKzr>$XFGw; z{5ZqFzyLZ2;v54518AT51qKF&iwq15pcN^gGd)22Z$K+&L1&GC*7Mw8U|<04zX9!l z1FaAE#lXNQ#K6EP%)r11x?x_Ffq^mN|5wJy|6duS{(ohR{{NM+=v5kR&v7Lc|v4equv6F#;v5SF$v73Q`v4??yv6q2? zv5x_CR6FRBGX}r`TsWt(CJH8|9@k+_Wv8h_5a@(Zv6ko zaP$8+hFkx?G5q}hjp5h-Z;V3!zcC8`|Hdft{~M#||8I^>;H|6 zZT~kiw*TMA*ztcOW9R>kj9vdXGIsyp$k_9LBV+IXjf{Q&H!}AB-^e)O|3=1%|2HyD z`oEEJ^8byDQ~qycocezw$T;KwM#h={H!{xpzmf68|GP{=4BSk@4BSj2 z4BSkj4BSj&|KBi)|9`_I@&65zaRx4i6AWAo zCmFaHPBCyXoMzx+IK#ljaF&6K;T!`O!+8cSh6@Z_3>O)=7%nkzFjU@T*hfb1t{P-3iP zP-3iNP-3iRP-3iMP-3iQP-3iOP@+?5a}_;S7~&W>Kr>GNe=*20NH8dXN2?ea)EPt= zbQl;JK&SUXN|n6~CjU=EYqI5xeE)wj^8f$EDDeLmqu~Evj7B+{VDjxSfHKaR&n<;|T^4#w!erj8_>L8Lu%gGG1q3WW2$^$as^1k?|G- zBjarbM#eh~jEr{~7#Z&|Ff!g}U}Sv2z{vQJfsyeM10&;O21dpw42+CV85kL#F)%Vd zXJBM}!NAD)l7W%&6$2yVYX(NfHw=t8N|@73!v9Y*iTpp!B>Mj}li2^|Oyd8SGfDhk z&LsJNIg`}?91ZVNhfUWl&@YV^CxWXHaB_U{GX;`hSBV`u`1v*#9>elK#J7 zNdEtVA?5!IhSdKr7}EaVU`YRe13E@}12h}Q*!2GmWApzvj4l7)Ft+}G!`Sx!4P*QN zH;f(s-!OLmf5X`I{|#gJ|2K?1|KBk7{(r;R_x}xJ|Nl3P6aK$pocR9@s-!M-5|Auk;|2K>?{=Z?I&A`Suhk=c8E(06mJO(z#`3!7~TNv0Fw=%FX zZew6$+|IzpxC3-r!vDLBR~XnBuQISPUSnWmyw1SJc!PnB@g@Ts<1Gd@#@h^RjCUB= z81FK$G2UZfW4zD6#`u7NjqxD^8{;DeHpa&cY>ZDB*chKOurWSkU}JpFz{dE3fsOGc z0~_Nj1~$gm3~Y>VK<6&}|G^~u{|A%E{~t`E|9>!v{lCg2{{JeI#Q&>IlK-zVN&Uad zB>n#?lg$6C;Mr?e1}X3eI%IZI1Tvxv9Pq_L>Pq`L>NUFL>NUGL>MI*L>Z+RL>Z+SL>Xlm zM8PxIatxx3@(iMk3Jjv)o|Y20wiT`ghPWpe7aq|D0j8p#KWSsi{CgZgKHyNk@zsWe`|4qi3|8FwR`hS!0 z#Q*b5LJVw7!VGLoA`EOyq6}1};Ws1};Vx1};Wc1};W61};W+1};Vp1};WU1};V} z1};W!1};V(1};Wk1};Xv|Gyde|Nmwb`2U+x@c(Z{69z6uQwA8>2L>)iM+PoNCk8G?X9g}t7X~gyR|YOd zHwG?7cLpv-4+btqPX;bVF9t3~Zw4+#9|kVQlK-C=OaFgjEc^e7vHbrh#)|*X7%Trj zW32lBjIsLvGsc?#&lqd}KVz)>|BSJofs3($fs3(`fs3(;fs3)3fs3()fs3(~fs3(? zfs3)7fs3(&fs3(|fs3(=fs3)5fs3(+fs3)1fs3(^fs3)9fs1hh0~g~&1}?@)3|x$p z8MqjyFmN$WW#D3*#=ylmoq>yS1_Kx4Oa?B-SqxmD_8gPY|5HrD|4%WA{6EDc`u`M@ zEQ1J>9D@jxJc9^BB|J9SLFY04|Ifhn|35rN!F`SYU!gI{#Q>?#4lHj= zIQ0J)!{PtG=n%928TtSJXB7DVpHcAtf4anM=>K1g75~37R{sCWSoQxaWA*>9j5Yti zGS>e8%2@aRE1hDH3rBr{~MVk|8HcH`oED$ z`u|2Ing1IZY8hC-XXCIjaQp|I5cZt`bg#1r0~>=lQl5q6S5^jt|GycG|8HS1`G1zd z?EfMLa|U^aFAQu9Um4gKKxe{zXJBLa!N3MN@r8kn;V%Ol!#@T#hW`v~j0_BHjEoFy zj7$t{jLZydj4TXnjI0c7jBE^SjO+|-j2sMXjGPQ?j9d(CjNA-tj64i%kkexRe`n-n{QsNr)BoR$pa1`6{PO=dlhFUOOv3-q zGKu^@%Ov{$ER)#(MNH!V7coivU&JK&e-V?^|3ysF{}(aI{9nW*%OKAr#{fFwUY?{r|$i`Tq-p5cmX#FAVDcLF50I7|i~E2CqGcWDsFUVBlg%WZ+^* zW)NaXWe{S>`2UR|3%qs$G^+$!&CA8m&cMac!NA3EmR|H5$Q{}+a{|GzMt`~QXE{QoZu7yf@?xcL7I!=?XU7%u<+!f@sP z7ly0URrM#leN7@7WmVPyXQg^}g|7e?0q zUl`f`e_>?*|Amp`{})Ei|6drn{(oWQ{{MxM=l>T*-v3`1h5mnG6#oB(QRM#@M$!LY z7)}0vVKn{!h0*N)7e@2{Ul=X^e_^!z|Ao=&{})E<|6dqw{(oV#{r`p0?*A7?`~P1U z9sYk|bo~E?(dqveM(6)u7+wBi=gZ>HnXZWd46< zc4pvXc7?8l@nGO%_F`aR_GSRh-SRQ}{{I7={Q<2i;DpZnfL3gLW9Y`xFO-G%3t@di z1qKlY6$TLo_5YU{bQnY!^cX}KK=(PD{QtvX`u`Dw+5e9N(oe+RN0eoZWRPWyVvuEw zW{@3peZ<)eB8+nwL>T8Xh%nA$5Mi9pAi}tXL4X3?hs>7(^IP{J+e2 zg+YYzDuW2)H3kvJ>kJ}{HyA`1Z!(B5-eM48yv-oOc!xoR@h*c1<2?ou#`_E+j1L$@ z7#}i-Fg{`sVSLOW!uW(igz+hZ2;(yb5ys~XB8)E>L>ON(h%mll5Mg}HAj0^DL4--@ z{~spd|9_Z7{{LYT{r`ta?Egn5@&6y0B>sP7lKlUXN$UScCh7klnPmQdWS9i6Az(Fw z7z1eJ0Ms5oz@Wgu#h?Oe&Hca4pu@n$pa&YEW#C{iVF0zyKQNg8|3mW{LXAP4F111c z0~cc;0~ccu0~cd30~ccm0~did`T@q~{|6Xb{vTj${eOV5?f(JB_WuVMJN_SF?EHU# zvFrZ<#_sL7VC?;WfU)oY0mlCS2N);(KfpNg{{hBH{|_)u{(pdR%Krn5Q~w`e zoc8|!o<%XW(Mo0c!32zs-1sfs64f0~g~p1}?_y3|x#i7`Pa3GH@~8V&G!D&A`QYhk=Xn zE&~_iJq9ku`wU!+4;Z)@A2M(;K4Rcve9XYb_=JIr@hJlr<1+>>#^(%Nj4v3t7+*4Q zF}`BpVtmcO#rOs^l8x41kp2IMN$&q2Ci(w=7$!5Y{Qu9u25LqA|IZ-u|38B`186)- z7JTxgGy@+4Wb}GJ1ETCXhg9~6K*y&(Fo4dQ`uhJr!?*wc8NUDj&+y~_e}>=x|1dnaT|34$+|No3k|Nk>G|Nqa(^8Y_0>;M0ZZ2$i=vj6|j$npO_ zBj^ABj9mZ!Gjjj`&&c!tKO--w1^NF!qv`+ujAsA;Gn)VZ&uH=gKcnUU|BP1u|1(3GtTl}T`EYy)th8Y;;k~9Mww1){g z%Upy(;s0+2mH)pP)IjAE0|SH3|KALH;1(>X*Li{FZ^rrme=~0R|C@2^|KE(;{{Lp&{{J`Qj{m;S`v05p_5a_DZ@{hT3rxcQFEEMx zzrZB={{jQ(3RwXL76vH>Rt5nEHU=pMcF>8}3<3;73{ngt3{nhY3?dBT;Bt$FLGJ%e z2DSfh8PxxuW-$K$ox$Y)cW^t&{QnCE$XS^j44_lSjxq=^9Agk*IL;uzaDqXA;Ut3q z!zl&XFq~r$U^vepz;J;FbFV;G6*o5Fi0_)GDtC+F-S3*Ge|L7 zFi0_4GDtC6F-S35Ge|MoFi0`lGDtDnF-S4mGe|KyFi0^vGDtBxF-S2wGe|MIFi0`F zGDtDHF-S4GGe|LdFi0_aGDtCcF-S3bGe|M|Fi0^5Fo-Y)GKeq+F^Dh*Gl(#TFo-aQ zGH@_PFz_)(GVn1*G4L@)Gw?B1Ft9LIGO#dKF|aUJGq5n$Ft9MzGO#e#F|aT;{ipqi z+3x>u8Tb5u%eeRdTgH9=-!kt1|CaH<|F?_>|G#BC^#3j6;s0+LkNkhjc=Z2U#$*5A zGM@NP z^Zx^5?f(yqb^kvMsxlBXn@Wc=4aca#O(x<0H+zW1eb|s|8FoH`u~UF@c%yyNB;j}IQst=!?FLr7(gdro%sKY;pG2c45$A8 zVmST(7sHwVzZlN`|HW|b|1XB~|9>%D`2UOH;{RU^m;V1^xcvVY!R#c=Ka zFNW*?e=*$n|BK<~|6dHZK%md_ zM$Z4g7`gucV&wk+i;?I5FGk+~zc6O)g#Q0x6#oBFGlzOzZgCK|6=s~|BKP<|1U=G|GyZ0{{LbO`2UMB@c%Ey zp#Q%Zga7|x4Eg_yG4%f*#@PSA7~}r`VvPU)i!tHTa_v;O~L%>Mt2G3Wm;#@zqE81w%BV$A>li?QJUFUG?E zzZi@D|6(lu|BJEY|3Ajk|Nj`v{{Lev|NoD%;{QL!%K!futN#CEtp5LxvF86j#@he? z80-H3W32!GkFnwZKgP!Y{}{jhf5Z6w{~N|1|KBkF{Qm}{{1f|sgGv1V4JL{IH<%>< z-(ZsZe}hT-{|zRY|2G(xGBEys!NBtW5d-W07YuCwA2D$Jzstb+{{;ir|GNxA{~s|3 z|Np=s^8XQo*#Aci;tagtHB(Xy+zitHe=*1~a5Kn)=4Ah`VNn17n8D!xFYwyWBmZA8 z9R2@-;n@Ed49EY!U^wyr1;fezFBne!f5CA2{|kmQ|6eei{r`gD-2WF0=l{Q8xbXi4 z!^QtE7%u&P!EpKi3x+HIUoc$#|AOJ#{}&9`|G!|k@&5(G&HpbLZvB730J`zz>;Fd# z-~K;h`2PP9!;k-u7=HeL!SL(<3x?nSA2Iy-|A^u5|3?h}{y$>)|Njvq!~aK&jQ<}o zGW~zV$o&5iBg_9sjI943F|z%C#K`{t5hKU{M~s~RA2D+Mf5gcB{}Ch4|3{3x{~s~( z{lCk||Nkzd!2i39g8%O_3jKe{C~t4@c$8G;QvRALH{2y z2LFG=81nxSV*~>)VAOVV+jK{V<`hSV;KWCV>tsiV+8{@VJUeV+{j0V=V(WV;uuGWBvbMj1B*PF*btc!~d^gZ2rH7vE~07#@7F97~B4@VQl}u zhOy)S8ph85YZ$x!uVL)|zlO2r{~E^L|7#fg{;y%||G$QD!v8gl6aTMaob-PUxgKXE6DH0y?J7M)RHt=3E%<$J7J<|7HyQ|C=%B|8K_N|GybS z{{LpI`2T{j^8X9Qs{bz-tN*`Xtoi?fvG)H9#=8G680-K4VQl#Shq3YhAI7Hte;J$q z|7C3X|Ch1#|6j(o|9=_V|Nmv|`2Ux&^Z#GQuK#}-yZ`@X?D_wfvG@O9#=if58T3#@GMK3JiP z2s5%U2s5%W2s5%V2s5%X2s3gp2s3gr2s3gq2s3gs2s8392s83B2r~*X@G}ZC@H2`q z@H2`s@H3h)2s4^82s4^72s4^92s2tR2s2tT2s2tS2s2tU2s7F+2s7F;2s7F-2s7F< z2s1h`2s1h|2s1h{2s1h}2s64c2s64e2s64d2s64f2s3&x2s3&z2s3&y2s3&!2s8RH z2xINRps#Fd`hSJ7`TrHhmj726TmN5SZ2NzOvHkxQ#*Y727(4%8VeI;Ug|Ykp6~>sZ!_>Q-eKTlyvxAHc#naP@je3| z;{ygh#)k}ijE@-j7#}n6F+O47V|>cM$M}qakMTJJAL9!KKE{^}e2lLc_!wU^@G-t& z;A0YE5MUB!5MUBv5MUBz5MbED!1(_)1Iz!{46OfOGqC-C4L&KF^Z#oGUeNi#|6enR z{C~|L{{I()Gy^+>%>UmEaturi>i@riYjeZ@cNmQSzh*FHU|}$4U||UQ|Ary>{~Lyo z|8E#V|G!}f`~QX^{QnzzfGjK7a{Qtp_%D}~t z#=ymp&cMZx@&6A)=Kp^TS^xhqWdHxiP{<(6P{zQ<&;Z^s{GH*@{~rvX(^QZAf6Z|8 z|7(V0|6em4|Nold#Q)a}C;z`@IQ9QE!|DI88P5EF&2aYrYld_GUo)Kl|C-^#|JMu` z|G#Fq^#3)(<^Qi4uKa(^aP|LdhHL*{GhF}wn&HO(*9Q3AviyI|$ol^^BisMijO_nkGjjZY&B*!xH6z#m*Noi%Uo-Ojf6d7I|23n~ z|JRJd|6enT{C~|T`u{bfDgy(f8Uq8P$^X}krvG0vn*D#xX#W2-qs9N%jF$gjGg|$B z&1n7qHKWb{*NnFRUo+bMf6ZwB|23n-|JRI;|6emY{eR8q{Qoth%m3GmuK!;%y8VC6 z=>GpTqsRZ(jGq5rGkX1h&FKCAHKWh}*Nmb6e=tV;|HT;j{}*G_|6h#J;2HMcjFta? zGgkfo%~<{aH)GBJ-;A~Ye>2wo|IOIMz{J?hz{J?Xz{J?fz{J?bz{J?jz{J?Wz{J?e zz{J?az{J?iz{J?Yz{J?gz{J?cz{J?kz{EI#fr)V<0~6yU1}4VI3`~qu7?>ERGB7bt zV_;&O&cFn@3xt7*aTWs; zVc-Ps=h9)|WYA;aWH11qZgK^@uM4u0nT6pf0}I131{Q|n3@i*M7+4riGO#e5Vqjqa z-8gxMfra5L1L%%p7KZZ-EDRSISQsucurOR=U}3n-z`}5afra5J0}I171{Q|v3@i+w z+uUw4urSZ~z{BvDfrsHA z0}sQ01|CKR1|CL61|CKx1|CLc1|CKh1|CLM1|CK>1|CLs1|CKZ1|CLE1|CK(1|CLk z1|CKp1|CLU1|CK}wABGZ3@nVo3@nTy3@nVI3@nUd3=E9o3=E7C3=E9w3=E7K3=E8* ztJd`y7#Iy07#Iy17#NK~DV%|a(UgIQ(TstI(VT&Y(Sm`8(UO6O(TahG(VBsW(T0JC z(UyUS(T;(K(Vl^a(Sd=7(UF0N(TRbF(V2mV(S?DB(UpOR(T#zJ(Vc;Z(Sw19(UXCP z(TjnH(VKyX(T9PD(U*aN(T{o^8XW(Rfz`)7)kb#r&5d$aVV+KyfCk&j7PZ>BFpD}PU zK4;)$e8IrU_>zH>@f8Cn<7);^#y1R{j354gWBmC48{?<{-xxpt|Hk;`|2K?%fcRF4 zp98NFXZimLyi%MEbRQ|`tPAkz)}I)}|G!|6`2UAN^8XD6ssH!Ddqm_wcb5Hs%b)@t zfBnOt^ZzY_-v74@#{btcnEXG^VD^6ogE@mTO;?kD`TvOlbR)yJ|DPDX|Nq4ByUPmEmuKQVIu|HR1i{}Utc|4$gJ)lL3?Vl@5#iP7x;Cr0!CpBOFv ze`2)!|B2D+|0hQ4|DPCb{(oY${r`#4?*Au7`~RO99sYk}bo~E`(dqvuM(6*Z7+wB< zVs!ogiP7!;E6d?EillbN>Hf%>Dm|G4KB$#{B<(7z_UYVJ!Urhq37YAI9SUe;7;t-(xKO ze~%G#rce3*dyGvCl8ns^l8h}3l8mhkl8kK(l8o&Pl8hY;l8l`Ul8jvpl8oI9l8ikJ zl8n6!l8k)}l8pTfl8h4=BpD|%NHR`hkYt?9Ajvp|L6UJQgCyfL21&;043dm97$g~I zGDtGcVvuB<{r@fFod0hb=l*}oIPd>k#`*u>GH&_*mT~L%lP{L zTgEs4-!cjPKh7ll|2UJ#|Km)e|Bo|?{hz@k{(lCO#QzyglK*EgN&TO}B>jH|lg$4a zOtK8hOmYm$O!5rM4Cfid!8zk6gVg^&;G7}z|0ksP$-uy%@c%D^%KyI%YX5&T==}f7 zp!feTwAJ*M!RY@F2IK$l8BG4a2cLyy_WwP2?jCePK@bB2LofpaLkI%{Lns3S1Lzc$ za0Uj32nNuJj%*Ck3~UUs3~USu|35J#{{O^~^#2P(^8YssDgVDPr2c=ykjB8qkj}uy zkio#skOkVg{r@vV;?{r{VB-~Zo?`~UxDJn;WFVuh#vA|tGT!|Em+{vBzl^v4|7E=M|1aa+|9=_p{r}5& z|Nmdc2mk*vKK%ce@zMXkjF12SWqk7gFXPkye;J?s|I7IN|6j%z|Nk<+{QsBn)&IYY zumAsLeDnV=juy^a#_#{%GXD7gmhtERw~W94|6u&{{|DpW|34W2{r|!E|NjprhW|g9 z82|rZV*3AsiTVEzCYJv{m{|Y+U}F3KgNgnB4` z|Nmg(`~QQ9|Njprf&V|41pohF68it1N%;SJCXxT|nMD7;XA=AWo=N=wdnSqh@0le3 zzh{#A|DH+u|9d8x|L>WQ))O#8&OZ6Z?E3!`v)lhq%k#84~_~V@Uk}jUnm(cZTHu?-^45e`iSj|DGZ3|96J; z|KAxh85kI{!KVPdVQBpSm7(eX8-}+3-x%8ee`DzQ|Bd0u|Gx}J|Nmt;_Wv)#@&A7r zPW=DNaPt3OhExClGMxVZm*LF+zYJ&p|7AG$|1ZP&|9=@S{Qt`Ux{>43|Gx~E|NmvU z^8YWx)&GAPuKoYZaQ**Zh8zF?GTi+Cm*Lj`zYJgg|7H04|1ZP0|9=_2|NqPI2Aa|IL{2|2Jde|KE&B|9>+k|NqUH z^8Ytu>i^%2Y5#vSrvLxVnDPHNW9I+gj9LGGGiLw)&6xB5H)HPq-;83L)|IJwN z|2Jdd|KE&7|9>+U|NqTc^8Ytu>Hpu1W&eLOmV?K`zA;w*|HfGL{~KfV|8I;n|GzQT z{{O~U2ioKJ{}*HP|6hzP|9>&I{{O|;_Wu`S`~P2z9shqZcK-jx*!BMxWB31Gj6MH< zG4}rd#n|`%7i0hbUyKv}|6-i@{}~*Q z12ortgPtb`IoSzviVyM$Pn-;o!MiS5z^5ZJfbSk*hn$ZMz6A($1~;TG`^_Nr|0lFA z1NHVr7}Ocq7>xe^g6`;f%K$pZ%k2Ln26F~BhM@mn8G`?RWeEBIl_B*1SB9|vUm3#x ze`SdH|CJ%~|3ii-1}TPU1}TPE1}TPw|8E!)|G!~K`v00C`TsM9l>e_8QvW|=NMn#< zNN13O*H?KA0u1^8KQNRra5FT3&oKhkU5^-=|G!~q0q4Ru4DJ8lFm(KX!vH&D{{O|q z_Wu_X`~P1|9RGhYasL0s#P$Cd6ZijLOg#U8G4cNY#l-jj7Zd;gUrYl3e=!OE|Al2& z?IR}f|Bsj?{y$=p{Qrna>i;7q>Hm+IWd1*5l4XF8^fJ5rf5Yth{|&R-|2NE#bJswp z!n^_R!1Dh8hS>*v&Ym2z9|LGzuoU>zs4xaGhF1)X|9>#B{Qtqg3OX_U{}0f8LJS=L zKQnOt|G~iZ|1*OS_+<7U4B`xI;4|c87(i=YKzr>N7(i!nssDe^pu@nxpvS<#U$p0@4q5r=yg#G`*5dQxQLj>roxBr(IqW+&} zi2i?`A@=`yh6Dx?hC~Jth9m|i@T&6^1}5;z^R)lx8Pfls2an5v#^f3qSr` zL>M|4L=ZXf{||zX`~QRC`2QaaC;tCnIQjnv!>Rv27*7BH!EomP4~Db-1`56 z;miLY3}65MU;y1?_5J@3h9CcbF#P=ggW=cz9}K_$|6us@{|Ce0|34W1{r|!6|Njq0 zhW|ep8UO!aWcvSuk@^1*Mwb6S7+L@SU}XFMgOUCJ4@QpvKNvax|6t_$|AUeH{|`o< z|34Uc|Nmg*`~R7d|Nm!3f&ZTw1^<6$6#D;zQTYE4Mv?zN7)Ag8U^MyvgVFT=4@R^9 zKN!vb|6sKE|AW!;{|`p1|34V5|NmgL`Tv8__Wut?yZ=8J?f?H^bol>+(eeKeMyLNj z7@hzBV08KagVFW>4@S5DKN#Kr|6ug^|AW!<{|`p5|34VL|Nmh0`TqlSel24J0~=!` z0~=!$0~=#B0~>*LHg9OQ7jowRH;l8udmA_D`omHG?XO8v!<#=ydm&cMQu@&7(U z=Ks$OS^w`dWdHxnkk7ydK6|8zL4cu+fq|i&fq|iefq~)3|2qsv|KDLa_WusU@&9)i zPW->aaPt2hhExCVFr5B>hvCfsI}B(4-(fiS{|>|X|92QJ{J+C+@&6r$OaJdMT>gKD z;mZFz3|If(VYv4H4#V~TcNlK`zr%3z{~d-~|L-t-`G1|^>;LNv-~L}``2PPo!;k;h z8Gio1!|?0>9fsfkuQUAlf1Tm)|LY9@{$FSK|NlB8!~g4yjQ_7QGX1~K$o&60Bg_Bm zjI95!GqU}^&dC1%IwQyb>x`WLuQPJ}zs|`0|2iYj|Lcsr|F1Lh{r}3y|Nkqa!2hp| zg8#oV3jM#sDE$8pqsad|jH3VVFq-_o&S?7oI-}YD>x}0AuQOWwzs_j+|2m`9|Lcs_ z|F1LJ{J+j<`~Nzl-T&*1_W!RlI{d%R==lFSqtpNEjL!eBGrIi0&glC8I-}eF>x}OI zuQPi5zs~6S|2m`B|Lct2|F1Lp{J+i^@c$EI;QvpILH|E72LJ!W7y|A;|6z>%|CTZC z|69iR|8E%+{=a2R{Qs6Q>Hk~CJ>B;{R{ya@xe~|1TKl{C~kX z_x}sVdH-K9&j0^{am)V~j9dS|VBGfq1>^SrFBo_He*qq$zw-YD{}+t6|G!|o^Zy0o-TyBb@BM$lc>n(k#s~jjFh2bMg7MM+7mSbp zzhHdw{{`dI|1TJy{eQvu{QnEa7yn-{zWo1!@zwtqjIaN{V0`oc1>^)k@QH>Z%W*^Y$uKzzkPw)J~9PHAKd7(yg#onA6mouNH$&9_$qdo|Co{zUpUjZJz{-%wz{-%sz{UVNi#Y{) z9&_6N$qecLCo^O)Fo64(S9$&kQI3e`YxK|1-ns|DPGo{Qt~w_Wx&wbN@dxod5rs;llsV3>W`@ zX1MhKGsETopBb+F|I7fooABEI&kWc9e`dJx|1-nQ|DPFd{r}AH<^N}fum3+YeEa{I z;rsv33_t#VX88I4GsCa{pBaAt|IF~`|7Ql!joSbIe`fgq|1%@Q|Idt!|35P_{r}9! z{Qol}%m2@etp7hVvi<+e$o~H`Bgg;GjGX^JGjjd^%*g%!Gb7Lc&y2kPKQr?Ef5*uG z{~e>i|96an|KBkR{r}7;{Qonf$p6obqW?cLn*9IFX!`#%quKw@jOPD8Gg|!r%xL-l zGo#i2&y3dpKQr3=|IBFn|1+cA|Idu}|35Q2{Qu18`2RDb)Bn$m&i_9%y8Qpl==%RN zquc+_jPCzGGkX00%;@?5Go#o4&y3#xKQsFL|ICPOEkqcD0AmRQCu1oCCu11{Cu2DS zCu0QzCu1c8Cu0=@Cu21OCu0o*Cu1!GCu1E0C&~-}ZD)=TG0ytGgoIg!(~NYOWndCw zU||wwU||wrU||wvU||yb|Ak5X{}(2S|6iCS|9@eU`u~MV`u`Uung3sq*VKZ~ByeG1 zV|HcWVs>NT0-wta&dm&5%w7zP&>eJK%)bBcF#G*~#_a$98T2&eUCcrMuQLb#-w!<_ z@)9%XROKHGjQ`(&?{i}L{|0N`%|KAXE zdH>&lPsJDc|Aql{2NS5?7XSZ@K>~E=&;RcX3jg0QsQiD!p!5F?gWmr)3`YOogZEY+ z`TvID=>Ini$Ns-zIR5_)!-@ZI7*76w!*J^V8-~;W-!Po{|Ayi0|2GWh{=Z>3|Njlc zh5v6DF8+VRaOwXWhRgroFkJcnhT-b}Hw@SQzhSuk{|&>9|8E#Tw^HBw|Ayhq|2GU@ z|G#1Q_WupT_y2Dge*AyK@bmv0hF|~RF#P`ih5>Xx?BD-y82 zzhPwh|AvwI{~Jb@|8E#s|G!~m`~QZK{r?+Aj{k2MIsd<5bKVwY(|BNx^|1-wa|IZlH{y$?(|No3JU0Av;IG0%>Mt3G3Wm? z#@zqU81w!=W6b~mjIrSVGseRI&lrpTKVvNZ|BSKX|98g9|KAy_{(onz{{Nk^=Kpub z+W+4f>;8Xdoc;d|AN_yB`1t=D#wY*ZFh2eNhVj||H;m8!zhQjw{|)2I|8E#y{eQ#w z`u`ioH~-%-{{H`-@z4MFjDP>XXZ-j7J>&oX@0l3>zh`3n|DK8I|9d9p|L>Vt{=a8p z{r{ec?f-iw_W$phIR3w9;{5-fiR=G+Chq_5nRx!cXX5?;o{8`OdnW$>@0kStzh@Ez zk2!C|xkvsN1LOZk&{e08psP+FGI0KX#K86cA%g(uMy~&F7$B=p-!OnypNjr}!yxwm zHG{-|&^dN*7^MH-WdNPXB>VphgWUgH3=04MF{u3i$DscI7K6_Je++v6|1kvozsCT+ zui<|`L)8D}4AK9WGsOO1j;O!?|7S?~|DPf4|8j=(|I5L3HfTIJA9P~r|MTGb8nv!| z#BlWgBZg!DA2A&N|A^tl|3?fb|36|l_5TsW>Hm)y&isGGaQ6QrhI9WPF`WPZh~dKj zM+_JLKVrD_{}IFG|Bo21{C~u7_5UM=YyTfHT>t-w;l}?*3^)HjVz~AH5d-#Bt&bRf z{eMK|Rjm&h`Tsv;6!`y;QSkpmMxpDi9#ykK2G2Z?EkMZ9Be~kD4|6_dc{~zPS|Nj^t{r|`K`2Rn~ zC;$I3KK=iX@!9`>jL-l7V|?-dALGma{}^BW|Ht_H|3Ahz|NlYHtY?Mqj`#fkm)VPf zlNod)j^FMshFbDoW&m8ps9{9}H(Em4>!$2#p85sYsU|{*bgn{+{3I?|SOBmQ0 z-;|Nk+A(ElY2BL9~#i2c9LApZXpgXI5x4AKk&44@s;vY<8Q47>~q z|N9wK{`W)nAO7FXp!2_Hi9b%l}s}T=~C(;p+bt4A=gzV7UH&1;dU1D;RG6U%_ze{|bgL z|Cca){lA3a+y5mD-~TUR`0;-U!_WUK7=HaFJbihzl72I{}M)@ z|4SGH{$FPd{C}M>=>K)b;Q!YdL;hc93}ujGjQD?wG4lT@#;E_N7^DB6VyyW8k+Jgs zN5-oE9~rCve`Kur|BA?_A&4>_A~G@PGI0=oXEh-IEjImaWVrh;}iy7#;FXv zjMEr+8K*PwGR|P&Wt_>t%Q%aHmvQ$0e#SZf`x)o{?`NF%zn^jb|9-|T|N9xY{_khp z_P?KT`~QB%9sm1D-eYjI2lg$4uOtK6DOmYkYO!5o@jA9Io z|L-xd{J+D%`u`pS+y6TZ9RF`HaQ?r?!1ezIbUo@F29f`F7{va+VUYO$20ADF4YK0m z|1}2q$$$T!A)Wlk#$d?6$^g1q$%KKK!3=!E(j$hz|1TMW{y%33{{NgI<__Ap(2@6KH&VH$(LQ-3+n+cQe3FWJzM+fR2xIK*z^-Go=6D&5-f`B}3-_ zPYhZAUovF>|AcgQwjlThr?UT`K0Y5q6N5ZM8v_^8=`Hsdj{d*LaP0p*hU5S5F`W2+ zkKyG1dkm-k-(xua{~p7c|MwWq{=dg??*Bc8^Z)NLT=;*F;o|>$443}jW4QeP9>bOY z_ZY7JzsGRx|2>B5|L-x}_&GD?`7?b|LVNCx2hB4*;8^+ZCZy3}5zhO-O|AsN+{~N~4|8E$x{=Z?& z{{MzC=l>hV-2ZPF^ZvhK%>Vy}vEct3#=`$^7>oYDVJ!at24goQ>K=+~jLrYAF}D1_ z#@PD*8e`l4YmDvxuQ7J~zsA`4{~BZ0|7(oh|F1Fj{J+N7`~Mna-~Vfj{r|5qPWXR~ zapM1LjFbLfW1Rf|8sn7z*BGb%zs5N2|24+x|F1F5_Xcn*cd-C zurYpSU}OBkz{dEEftB$)11sYX23E$O46IB-49rZz49rX-49rZT49rYo46IDz46IBN z46IC&46IC246IDj46IBt46NW=&RiH&m|YpvnB5pOnB5s9nLQZfnLQaqnY|cPn7tXK zn0*+en0@~rXZHJlp4tEZdFFus=a~clZ)Xnre}Osp|6XSBoeTf>F^By>#c096`2Ph1 z)Bg|9af27o{cJB7*#CcL;Q0Rnx~J_0(%1n5WbA-}fkEK^X9hv=jNA(bVeshT3kFf} z2qI|A{}%)3^n57>$i0Lz3=9mipgYL_UuIDF|DHkR|9b{C1~%~NdpiH$GwA()&tS+P z$6(9=I$c8qGM5gTMf?Aq;qd?O47A)Ecl-YbhCBa1Fx>tBf#Kf&4-EJJe_(j<{{zFr z{~s70{r|x5`2PonC;vY%JpKQH;o1KW4A1|6V0iKW1H;Sz9~fT!|G@D2{|AOQ|35Ii z{r`dC-Tw~^@Be>b`0)P&!^i(07(V^~zyP|R`^*0q3}64hVEFd`1;h9MFBpFOe}T0B z?ghi2|1TK+{(r&n@Ba&i|NmbwGW>tR$oT&SBh&vEjLiREFtYrA!N~gm1tZ)47mV!x zUodj~f5FK4{{i-Ky z>;EqpZT`PtwEh2r(eD2XM*IIS7#;q;DTz@Bc3teg3~-^!@*t(eM9fMt|^#Cgwau=>PAG;S3D4-G$1) zz*x$_zzDi8vz&o}v4Vktv66v-v5J9#v6_K_v4(+xv6g{>v5tX(vHt&e#)kjj85{q9 zXKea^nX&o*WyY5Oml<3CUuJCkf0?oU|7FIG|Cbp%|6gY8`hS_R`~PLep8uB_d;ec% z?E8P2vH$;N#tHu~Gfw<}nQ_wp%Z!u%UuK;0|1#s$|Cbr3{lCmO{r_dg8UHUc&isFw zan}FKjI;m0XPoo@J>%T}?-}R)f6qAo|9i$Q|KBri{r{eE+yD2B+yB33-0}ZC<8B5v z#yt#djC&c_822%-G45wzV?4mX#(0o{jqwlz8{=UHHpU|iY>Y=4*cgw2PI?8Ohw+~A z>i_qQ*Z#j}y#D_^fBPGd}tMp7H7b_l(c}zh`{@|2^Z2|L+-J{(sN->i>Jj*ZTAUo592~DWt2q65rf^Q-wBeNDT*qm{X~X%5-$rN_*EfC}-eZDlAU@|K z&PQBwyd2!~xa7DP1RFR{h%#_|V7tQwI&vGNV;v_La(n~pw*jf=e8lyQ_ZS3nwSdGq z{_xxIgXGq6uH%y9lH;BSg(tWbKqhf9aGu~=#VN#@!u^X|fm?ywi;F?<7Iz7k1D}9^ z7JrxU3;r7-Ny02V=Xm0{E^s9YnQ$`kMe(}v=rAzK&I9?AafNt>#5yqsaW82Du@(t7 zv0Y+HV!I^PiHS%UNVG^BNUW1sCw@qbK}<>fiP$sIZ{iv9lcZ!+e597h@QM8q*AcT5 z^Woa2swB2T@}5|fScYVl7?)y*7?-$^=mVK!Vr4pU;%#aS;!C8Dm|W4$(G3y3B6>yi z1Q?$XeIt4fjIW4ZQQ9HbCu<;jOJSRsh_r!t1}PBaM&hwpi&%@e7Ys_pNt%E}@MG~q zV!NPFNem1@_KAsziAdZ4ktq0rM3k74La>;U_#s?S%m4uqYQ$Q^ zpMap)GZ>U)lZg@i27zJ>xWh?o8Un&pNy$Lr5-B7o!v}(5e@KB`+qkxg*})k6ny}P&t#54p!E;2GF(vV6#~N4h_^xE z5^*FbeFOvzrm64I^ONV%oS+}0Txa=8W0}JXyEMgLT6Jpo;Qu#FLH}^?wcn$mEY;k&ypyn9~1$WME}-VPFN@7x@1O zQ^@~EAUhe@m|&*6gWYt5DGu!JZwzeApu6>a{)5)Ne1qTJ8v6em_*PBOiR&T^W&e+W zZzb~ozl=HX|1ywi{~s|~{C~vc!obfI$RG#yMcn^K3~WrG@OAtD8|-dhklVq&{>{M7 zIv%vk&OBA%-9ZE{0$R zE(TB<2i+$f#=yl8&cMYG!N3Lb30SAk|GNxa3_<@-G6erW$q@4YBtz)`lMG@1Pcnr6 zKgkgB|0I*b|8GqC|GzOAg3M$x`Tvc{;{P`$H*m`M2Jt5YC=}l?#lb`J4FflLy&!l# z1RR<_nLR=4i@~cbeuHmAhu`h{{|y5#+W#E=tKxtIh0?*h#QGYB%N zGH@}eF>om1}>%u1}<>APXeWV@G0q_ zyQx8U{WUR&fa5rt0e0uD9J4Ef95f~o_jN;dG=OgW76IMa4ZiI<7<}V3KXcgs-wce* zp!-u8nf1Ws)NxQb#SFTq9VGG%Ec=^*iJ9g99A>lszZsZ7V?xY6pz;DdGY(Ca3@l77 z3|!2j3|!0>3|!2Xpt1mbn>eV{X=Gqv+Rebgz{)i9{~M+i|KBh({eQ#E{QnIzcqW`_ z!~bv0TK~T>Yybbotn>dHvo0tnGv)sO#&q!iH>N}XzcC&D|BdMVg%*_9fFthwW!mP)@3c7*y|8Hi!|3?rh8oZMABLf>a-WwS}cSb{Qpbcb@ zWDaKFXJ7}Fi_CiecY#wWC=QYG8Us7Xg*Zza4hB%VYy7{O0d%`43j^pTR}to523BTR z%Hd#I4+@q4ZM3>-}B|6gX>@&7W@R|ZyQng5rW zHU3{_*8G2&+4}!wW}E+)88|`r$}x5Sf5Y_t{~M;S|9>$%gVQVMHc?ja{ldWvtYB5} zl8@=i|8Gox{(oa;`M&`aSIn?dkdtZs|6NQw{_kRz`M--<exLW?lwX zW+etzW@QFeW)%ijW_1QuX1)K9nC%!?nH|CR)qvMAL2@&*%YWQCm>rHUOmo=xX5eCa!@$L?!63q{$soe4#~{M2&maOe!J0vY*#@+xgsJ2IBdDDs zAUl~}{(r>u>i;9A*Z&_ez4`x$8QFdV1`)WO{0x!*&oOoU|Hjn){~OcG|KFHi{r|@F z`u{hkH~+sez5o9WZwtxEC2t-tn&XGv-0NlQK#2obhIdky;N6erzA%vK682Fhw800|tnrS}+ zKhpsQex{cUa!jun7(yAs z7{VDM7$O;>7@`?s84?&08PXWi88R5M7;?b3UN{(r>G!obh${Qo(4zX7P#=JEd{ zv*-Wk%wGTRGDG$m++g-);6l1<8Fcdts1y}p4q@P84rSm1-*hj`l*7Qq)D12jM3~kw zh%oJE;9@$!z{T{QfeRkuyx>rO!>q(0!mP|7!mPp|!mQ39!VC*DI|dPEM+VTi#A*gE zrgh+agshv3Srn8y8Mv608Mv5L7`T|#!FdW&cI*BB#%%Hb8?)vAZ?N*4*^YsW*^z;Z zK@{pXn5nF2?!sj*YMA>#izhRpwu7_$FAV#sFzwR?AgQZ|$7|NTsA|MxSQ{NK-H@qa&)_5b}$ z?*D%>h5z5r6!CvQQ{4akOzHoBLPxA6nL#ZFcLr8w4+artPX^H4-g3-73>wV7|Bo>H z{XfU-|Nk6w!2cu6LI2M&2me399P;s5V4MEt+Yko5mILkc+GiD1<0U;l&di-+0D1+F_o!7Z@UQD_F-!Qd+ zTMBQO4*h?_bQsiH1+TwFUA2ea8WUq$%>YS9ppx_}g9ut0`i7B);3ez-Z_N5ADFIx% zGQ-lAB-2a=5vCOkB226Q|7KeE|2MeA1(onj3?j_T3?j@d3?j_D|9^wa2T%@I`v03* z`TuWbmH)q))j?$jv<3i`h8F*!sfmG$sg;3?spJ21rcMSfcuqXYz{PZmfs5%h0~ga71}>(D z3|vf)7`T`oGjK6IW8h+X`Tsf7tN+iLUjKj2^ydF_roRka%nYFR5u%o3ki}vPsNOij zMA&rHTIucoZ%pt0e?!;;u4f>1s|73H?8!~Y*Ko&5iZ>D2#6OsD@pVmkBx5!1u}kC-0)f5i0o|0AYn{~s}Z z{r`yR@Bc^44F4Ztt?fXyI;?h6XUh5ijj8zmH>T46-Ie`9I|)w1An4%`ZY)HMIU zF&+5-jp^k7Z%n8De`7lR{~Obp|KFG%{{P1G=>IpS$N#@EJpK?m1Gl0er5b8W3f3ak1Gh}jOEpLf%b4u)C+GiurriJgnM(ifXKMPtpQ+{lWv15u z`zLLvZDiWaw3}%U(|)D{Ooy3HGM!>N&2)z8 zD$_Nl>r4-s9x**;ddBpU=@rv!rZ-GqnZ7Z7XZp$Xo9PeJU#5Rd|CyPXnVDIbxtO_` zd6;>bMVXbDm6=tT)tU8}^_dNr&6q8iEt##D?ZCAz;X0R*!TA3h21W+y{~s9`!Rv(> z8RZ$|7#KmVb_PaJD~^E)w4#7<*8e#m7O1z&Ai}`JVEX?fGbpz+f%Z)?`+!D=7)%-X zK|Mice^76a!5Ca?gW9^^KsT}fzX7UmK%){2%%D4@nPELDW`?H!&lzX^f65GMaWR8T zW}Nl^8FTRe-wezQ!vDX4S3iJm?Pg{u`~QY<=Kq(Bv;MziU;&R6xG{);_aOTG|H#0? zkjo&#kk0_xg~-JW8ew2zXabE_fLr1Q%NaJqrGO$DJ zU_kVnV0|V~e~F#J`2Qnj&;P%netg612N}_U_C^K-A{~v+oBT&m1 zG*SSn<3+&ZJ)qOixEPEX_`#_r09;qgF-kGWG0HRWgH}j0yD-QxyE7Ou`+~-27|i~E zV-oxSjY<6fHztYy-yhe7BD>d%;yo{{IMV zslQ?N{twz2&IOA*<^TrB=tT(Fc2LXG8QQ8uZc+ODzrhR|+W@s3!x;D(xWVZFG|nQ% zz{Moaz{MoNz{MoVz{MoRz{MoZz{MoP0JnpIo5Aq^BgSw4A2ELa|A_I&|3{2J|36}O z{{IG)1DFFDPEMAPCP@Z4CMgCvCTRvaCK+&Sae;a@4E)GrWQ}1mC6r>Lq@IgwFqO%%F1skjD~XG49U*8>@naH$QVIg9vyO?hUx5 z8A(Df4m7@r+=CMYl{pMe3`VeW2kaXc1`+U1El4X7)DQf|?Dzj0%GdiWQy?bYd zGKMk+H-<)rMh16=LkvF{JQ#j4YBJO_YBOpxtY_3^3}M*77{<7R;RfSw#xso8jOQ57 zG5RuIVSK>o$M~E{o-vx)nK_Jc3WFSj7y~PVIJmxk!yxtlBk0C>2E+fC8O#~v7y}qs z83P$u8G{&D8G{*E8ABLY86*CGV~qU&jWO!~H^%7y-xy2&e`GBE|BC0< zImQMCImSi?ImU1QFEf7sf0^;e|I3U&|6gX3WsqZ%V~}G4wN~W8ck`Ms@YD3ZT<9Kg zCLsoXCSeACCJ_dHCQ$}{21W2`K3w3GD+0cSRPFy821D@8px;pLEhu3SVJu}3VJu@1 zVJv45LAjZ8_y0GHd;Y&+-249x7 z`u`2%vHx!vzcFwzerMof{K3G*_!E3r7SsP9;IXPE1}=u%|9>#t`Tv9A?*AVQ_x}H2 zxc~nL!-M}n7#{xr!SLw+4~ED8e=t1x|AXP_{~rv`{{LWj{{IKVi~m0uUjF~V@aq2$ zhS&dpFueKygW>J}9}MsQ|6q9k{|Cc||34T${{O-7>HiOg&;NfgJ2OZ!yMTMnkUS15 z-Mtw^z$H6q>`R4#{r@+3dXQz{2cHjS`2PrlIfER-q5t0)4*&ng82bMkMmnfx;Ad=L z;Ad=P;AbTDY^!hok1&4!e}wVJ|09e){~uvOPABRNa{rGo7=zjv46F?1ptC;zA7O0% ze}u8+{}IO4|3?_x{vTm%|9^zB$;DZug3U>(NIHxBtIkxby!F!`=UH81DUl z!*Kuq8-@q}-!MG<|Ayhw|2GVe|G!~)^8XFP)BkT6p8bEr@cjQ9h8O?eFueT#hT+x! zHw>@;zhQXu{|&?2|8E%H{eQ#o{{I_>5C7jVeEk20;nV*&44?nMVU+m)jZx$OH%7hx z-x&4(e`7TG|Bcb`|2IbC|KAvW|9@lj`~Qv6|Nl1zeFpabZy03$KVpz&5McntrqTa5 z45r|feQy{*sWkNe8^((Nj~FZeKVq!<|A?{r|0Bkl|Bo1J|36}^`~Qfso*VPgLOhKc3> z8z$EOZff-v4iy`2N3P;{X4KN#Oq* zCP8qnWCE8@j~Jx>zX9h}b&%-)WempucQKg!zrk?(|2Kv^|GzQZ{r`>O-v4h5_y2!m zc<}!l!^8jI7#{uq#_;(6H-;zwzcD=h|Bd0<|8ES>|9@k6@&6mc%m3dPUj6^Z@cREZ zhByDeF}(f%jp5z@Zw&AMe`EOY{~N={|KAus{r|=QI=8aq{~N~A|8E#Uy_s^*t{S8p zdQX5uWEtc4|H~ME{9nfS^Zzm?q5n6Sg#X`Q68V3FN%a2>24e*N?j808s67!{yxJSAv5PX*l8lVc18 zmsW^)Be}Ht|Bdnc|8I;x{(ocq`TrY}?Eg1Ra{u2j$%E4lC{Dz{r`3Z_b^)~_zA*&- zCu($%F7Xxc{|{r}|38dD|Nk%s|Np}n@*i|!I!c>^*&R9#3TgFyV=!l6`VU%l`P@UohPJ|AOKE{}&7o z{=Z;&`2PjNqyH}$9{+#A@Z|pshNu5uFg*MJg5ml97Yr}{zhHRz{{_RV|1TI`|9`>o z=Kl+ZxBp)-y!-!x;r;&?3?Kf#VEFj|1;eNRFBm@me*x~B$uP(<$}-3?Dl*71Dl^D2 zs{a4RsKy}282bM=#`$C=|GzPo{{O~U_Wv7WIjB|o|1Nlr19av!$ak=^9due9s6_Y% z&QH)a0(6NN&^}zuHUw(ks`&p6=gDVCH)Dfm!J%szKyk;wid1_&VgTKEWcYstPJlMSQ*|kurhpLU}gBoz{>E6ftBGi z11r|r5zBqOjNkt6V*LJp7vqoryBL4|-^C>Me-4xQ|2a$&|K~7C{-47n^?weN^#3_b zGXLi=STRU4a4|?Ra4{$_urjDHurlZ{urh$=!$G&{nEijmSi-=?Sjxb~SjND`SkA!3 zIGcf$aSj73<6H(-#(4~^jPn^-8MiR7GHzvHW!%QV%DA0@m2n3HE8`UgR>rFgtc=$f zSQ)P~url6YU}e0?z{+@wftB$#11sYl23E$q46Kaz7+4waGq5r~U|?l@$iT|@h=G;y zF#{{(69!hsrwpu&&lp%4pEIyBzF=Twe96Gd_=vsSD#<=JIH^#mHzcKFn|BZ3~|8I;3{(oaU z`2QQ@q5t0)L9L-9|GzOF{r`>e*#B?nEj)aqCk)o$8Ua)jNHNHPM+{^bGi>lozFeE*xIGfL6gw@kACzcI=E|HdT${~Lof0~1RAd=9S7L2VIJP}}bRG6r*S zdj#CV9I$+fUdyAmOvU~$V-o+rj7j4EGA7CY%b2A8FJqGazl=%d|1u_71`#GX1`#HC z1`!4u2ATh$onN5SK;JNcYIx)SHyF(RA7R8>w*CLc*zo@wV5}cKmcuSr~ZG#IPL!%#_9jxFwOvv#=ZfK05g)q?*Ai(_x~R;eE9!} z;p6{D44?i#V)zW+3;q#hTtJ?IixDw4Ajzol|0AQ`|BsCN|35Ms{Qt;k`2QoL@&AvE zzW+Zm`u+dN=>PvC-k6&CA2hbGpTUlS>Hj$fVFoS+iT@`Vr2gMvF!_Iu;r9P?40ryY zW4QbO9K*f;=NRt)KgaOk|2c+-|IaZz`hSk$@&9uSPyU}{c>4bw!?XYA7@q$>$ME9+ zIfj@2&oR9Ee~#hx|8op){-0xb`~MunyZ`4H-v2+x@ZtYChL8WxF?{-ej^XqFbBr+z zT#T{*Pcp{+Kgk&X|0H9=|C5Y~|4%X|{XfZ={Qo3l%Kwv$ssB$hru{$3nEwAHW5)lJ zjG6yWGG_fh$(a5BBxBD1lZ?6lPcr8HKgpQ?|0H9<|C5Y`|4%X&{XfZA{Qo3l$^RRS zrT=d*mi@oMSpNS8lhFTjOv3-qF^T*?$0Yjy9D_3h3j-Ge8v_@(ycPnlTH^w@CJY(4 zVC6Hz7X~hduMAuapfTd_3|tI97`PaIGjK8dVc=r;%fQ9(kAaKfKLZyd0|OT$BLf#B z69X3`GXobR3j-G;D+3oJ8v_?3I|COZ2Ll%)Cj%EF7Xud~Hv<K}1J z>wYl?(5Q?g11JPRBXDMjT9Dxg0~f;9@wkM2BHyF4W zZZdE&++yHj0FBE0V&GyFV&GyFX5eBJVc=pEW#D2Yz2?=xddm+aCM6jg7$g}R86+7= zjiGO7BaC9WXJ;6~7??o06Wo(|!yx$|(tnoz52}woGJsmfM*n{^n1XtpkZ~P`+YDR` zcNn-BK&yD~F>o>5XW(LZz`(`ukb#Tg5d#;)V+JmUCk$K+PZ_uvo-uGSJZIoyc)`HM z@REUx;S~cH!)pdE2GA)-ZyC54-Z5}7yl3EI_`tx$@R5Ow;S&QF!)H)V0*@WNVT}C$ zhB4~@8^&nxPF2+Q|L*@E8Tb7E$hi0aN5*~sKQiwB|B>;)|Bs9Z|9@mW^#3E{;r|~Q zkNp40c=Z2A#$*3KG9Lf`8@)Bn`1}8F#y|gmGyeVmoAKZO-;DqN|7K$N|C@>N|8FLy z|G$}-|NmxU`Tv`V_5W`sw*SAG*#G}#;`slYiSz$&Ca(X#nYjP|X5#t(n~C@TZzjI~ zznS>||7H^S|C>qh|8IsQ@OTQx|Bnn@|35NFfyY(27!>~hWKjA4lR@YIPX@jJKjHlk zqyM0ur82{z|B$g3zW*N?`Tu`p6!`ymi>RkSPmX<;bLrH z;9_h9wdDW*WSsN=C*$1zKN;u!|H(N2|4+s(|9>)W{r{73+y9@8+yDP$-0}Y>Q$$0huPsVHie==VG|C8~?|DTLE|NmsX_5Ua1?f*X+@BIJCc=!KL#(V#NGT#6H zlkvg-pNtRx|73jh|0m<)|34X@{Qt@L^#4!BXa9dPKL7ud@x}k2j4%KHWPJ7iC*$k? zKN;Wr|H(*1UxxAb|8IDdf z8x!mQZ%l0ezcI1@|Hj1e{~HtM|8GoO|GzPD|Nq9s^Zy$Y@BeR1eE+{O@&EtEB=G+m zlOSju0_l!}EN~i!)kLsb2y_}dsQm>lJ^mk|N4lnYO-GMf4qw}pw<{(sI` z_WwC!`TyrAb2GF5e`B2U{~P1n|KAwr{r|=||Nl3}E&snUZvFp_aohiIjNAWzW8Cro z8#r{Y{Qt&y_5U};K;v-+)F2P)B=c8G{VX;Jz4WWC3;_8R!f$(3vC{F$dr6F9)6vHfP|cQ~&G@$!#i) z|Jcv=LOyqkmgi{@o1*BFnlN@_qplc{W#DI$W8i0!XW(a;4Q^pGf$#j}0`I5*_1Zu! zZCHIN#=r$1Uz7&jVgg#d!obB4`F|4pUW5z=IfhIIR)#DFIfiToR))6!hh(;VlC{!#f6khW8Bo3?CTy89?i8J~8k!da;Qu!U(QaNgSAySTv8UcRRHMYrxpL7Ggkh8&RF&TIb-$z=ZrP~pEK6}f6iEkR$K38 z;9}gvz{R+ifs1h;0~h0d1}??}3|x!{8Mqh^F>o=0#`=#ia4{Zb;9@)mT4{sYx*)IeF*qm3)09I9p;=FzWo2j@b&*UhHwABF?|33jp4`tZw$Zxe`EOb{~N>K|KAw? z{r|@B|Nl2ehX3Cf8UKG{WcvS&k@^2OMwb8I7+L>+V`TgPjgkHTH%5;C-xxXne`DnO z|BaFR|2IaS|KAvS|9@lT`~QZK|Nk3Cf&Xt91)=K+BpD$H z7|#Z;aOezcJeU|Hf$h{~M#-|8I=;|GzOh{Qt)2`2QQD)BkUb&i}tLy8Qpf z==%Q~quc*)jPC!xF?#&}#_0L~8>83%Z;ammzcKotu5kd5&_ysvGDb2;GDa~-GDb5< z()P9{JnMppoqHp-PeqrxI>_d` z&v=}YF=E;x@I%Ik?;q18rY#_nrwRm_wn$Cu@JTwR$Ds5ru8Orp)PjXY!U04|P2+Ye zQ{r@MdZPUx^NirK;w4Jol)lNWkXym+#_a~OlPQiVj^m6-mC7ZiX@y!s5gcbgFsw|N zi-D2x86-3W|77c^Zs6F&u}P7Mc?bV15ac>nK8x!d2=acAR^k01oWl)<(kdb^I5#nN zNULxfKw$Exw1_Gd#%0nfjLR68@qX|O;(w*D=3FHGEkKCn0LuaH9QJ+e`^0iI_DOa~ zcCe)BeA4;E)HlIHbQMb)2nJ6Q(Gt;;IboP4ZX|AGrp9al;(^3Ov}9)~zL1@z^NGs> z1QlN>sBl;?^(ns4x&(n;8ohcgH6S%U>zECg4TLt;+weQ^J8)SrS}|IQ|A=q1{blXv za>r(g@h+1$4x9WEEdRK9sqC`YWS*n_K#xcBgxWf92B|P70R~2%c{{PE#`TuujMg~@9Cvce$+TFAJ|6gX7|G${^{-0;o|9^?u>;F$? zpZ`A@I2iK(KVm5V|DCDe|2L+}{|}hz85o$l7#Nr){y)wHIwOaPftBeTvnT@tvm~# z;AG%t0_~{kWZ+<$0ScS{FPJtm@H6fH|Ced+|IbXv8N``c{(pzM?*#)7QwMm5AurR+ z|NEF${NKm)l0lT|6@w_#YX(uKHw>ao?-_WRnf~u%X8ymAndSdJ1|EjU|0fvo8CVz! z8CV#~{$FCs`~Q=v^ZyB^x&Lo6ZT$a{>GJ=5%#8mZGmHHH!Ys?c!NAK@#=y)}4tC9J zru7V*Oq>7zVLHpe%yf={ndv+OGqVN*C$lC4C$qu-Kg`w)oXj>1oD6)>UH+V)+gq6O z{(l39T+#oxOeO!{fMc%(6oUUBF-`pcjA_dM``}pI^#2!w00YQASXfPEU|^cTzyM7J z3`}ns7?|EMFfe`n|DEXvg9J0<|3A!5|G$DyT5$jWl{xJHTLwXt^roaFHF|+*N0`{*S0~fPC0~fQ^ z|3?g>3<>}LG9>>0%h2}!FGKtPzYHD!|1vEA@7w#wwBi3>X1@Qwnfd?!W)=YN&HKl! z`TrlY*8jiE+W-GD>-_)Ato#2jv)=!|%=-WTGF$)u$87We9|IEuA432`0Rsa=5knD! zB0~v734;|G$_S85ltMgISh=iP`G^XJ%IhX3%~XW}pB6nM42oWsqQq zWKd(sW8h~fW8h+F`u~`z9+b=ee`cEU{}C*S#;o)I8ME&HXUx|B&obNmKg%G+l=uHTQ}O>N zOfCN(Fm?Vv$~5)=W2PDZ&oRyYzl3St|H(`n|KA6P(BA*AnU4Rz%5?ev8>Y7m%uMeX zn3=x*KhO02|7WHj45Caw|9@fn`~N62%l|3NBL6=y>oG7e>oYJgoBjX8Z1w*(gEUhf z120n%xTN^NRR8}OQzrvEQx^jp)5QNTnIQT4BGbJ8PnZ_|zreJSL6B+p|2Ir~|G#0{ z$H2gJoPiG>9-99jGh6+?#~{O0%)rT1%D~Cg#K6ha z%D~Cg3C^pawEBx_!~gH#((@z(C(|hgPNvfgoJ?mJIGG+Ya56n&;ADEtz{&KCffMe} zzYLtr3=EvieE)wj^Z)w+SriGxIwIZ~yOQdiVbn(^m!t@P2eq z2+RI|#H{y!H?#i#-OOeT3=DD%k^gTnlrgX|H2r_Ul*hmc&RbI%*rBBoJJhuAOmF}H zVS4xf4>ZMdF|#mmFzf%n&TIuPp`J0jfcGFlOgi|2Zllh(2lt8OnLwRGIjp{$pk7BLAByM1}>(J|G$II zP+{83zyQwGf5E8)RD-=|*8l&W*@}S;dYU;Svn$vIY|LK&|1x|3|HJIVz|8E+Ak6H? zz|0)Pz{(uTz`_i=n^~SA;Qud%$p6n6^8bHhXaJv|@{*zH|2d`^pql&tXJ{_@#dMs3 zo$2!b4@_^NduqS_|I5q>K5Jzsv;O~+(42mo+4=u_X3&{M9{;~Fd;WjV?DhX8cqf<7 z|Ch|5)p!96puHiy%pnZS3<^wn49w6}1&ZIFOkMwfGEHOr295t;Om7)jnBFn4Fo9wKRHm{pa5C%tKh3QF|1`4|xRvpi*^Pmp z*^_~r+3WuwW`71g<^b?*!l3x)V-9A3#Xl!=7y}D~DnsP|!whBr?}7F|g3Dc)?Q{RX zWt#W@J=4PfFCp!y|38`b{{O|a@Bc@p;|yHj8V;0?LFrlK{|{!_|KFJP{-0vj|9^+s z?EhbIDenZklj{F>W>*FVW_Jb#W{>}0AiKT(gU*oQV)pz0kJXLe&?XLe`cW%gtMrPTM#J`4=ZzW;xMQz;~^urmk#|HTZx z6ZZdK=8*rNnL`;Em_d7r)S=r;2Aw6u3EN!>&Cz_!p!=aUm~#IAVk-Xsi>dVgFQzI62BvDzUi|;R zm|Fk;V(R$+kE#3rKc*fA2Btm+2Bv;+efNfG|Nmc12mb$JI{E(>)2aWzm`?xy#dPNX zFQ%&u3{2M;7?`eu_U!-v#q{X^FQ&);e=$A#|BLAb0|V2`|Nod?{r|`G`u{(sH~;@J zz5o9YbV?A@HwFf9z0dIf7qiCyH_V!#Q-}V)VYd1IhCzd=?EfdG^8cThDj6)8S{PWE z+Wx;{>iz$TX~O?k;Fk4V1|6n(4E9V58914i|NqIf0dz_YgEY9cefIw+rgQ&4F`fVa ziRm%}Khy31ubA#I2r)hX|BC6u|4&RG|9@io^#2pncLo-w9}H$pKN*afelZ9!{bmqi z`uG1a)BpdEnPnKHndScfWY%KfV%BEhV%A~cV%BBgVz&SPmD%C{R|XA+$p2p%lF-@+ zpz;~iItR58%KrahD*yk7sq+6nruzSXn0mpj^lwa4z~On4X~X|VOk4lIVcPNk9&#Ik z>FobMOy~apVLJc+57P$*2Bwb;3{0QEZHs%%8vjo+YyLmUto8p9v-bZ-%sT%cG3)++ z#BBKg4YSezH_XQ1Fg(d@^Zz7+CPU!=ztGb24Y=lL`2UNc@&9IqrvLN6eE?8VrfraVv{})Ve|374U_x~{yqy&At+tr2YTJkPgn{4B&G)Ky^JlW&Hoc z)CM{`f`I`Vw%@^de*OPjOdI}xKslQWIYnGxU|@O;DI4 z?f)N`b^d=~*8Ts1+4}!2W}E-F7_=B78Q2(d88{j8|AWGl6PmZTGc^5Q0d3*3F>U<+ ziD@^u#QDo~oPn9??f=(I@BY7rhUXV%z5nZ(_5Ys-mpG92=Q(EQ|A(1f{y$-M{r`^H z?f)ZY_y3ofJ^o*YhUsBu@Be3+eg2wL-$;QN+HmGS$^g~ z2GGelJfNNA%pnX6%%KcC;96dXA@Y9*F)eR!Pp*uCfeD1m!ToLqux~&o70vtqoe5Ni zE@EJSo?3K+X~X{)Oq&@Pn0EYs1g?|LGB7ZmV_;x9&%gkxE#apb2{AA*3xjjmBW8{N zH<&g5-(c4I|AJZj{|jcF|1X$z|G!{1U|?Xj{(pnn=Kl=_9q4}LPv9Fy^Z!2q?`kb$ z5MyZg|D2)m|4D|X|LdUj&^M;3|9>*g`2UM(E(0^u#{YMrsRPtPxWV)ed}7*nX2$=| znf3n9X4e0I2q~u>Vs`m|lG*kDJ!ZH6_n6)P-(~jre}UQa{~>0t|NEJ}{~u!Z`M;al zmw}Dh@Be>hfACGn0?dI70?a`SoXo-C6v4|J#=ym(%MkGYB}3r;GR&f5EM;v&{Pc&qC@d@L2?Z!L_P80~@o)f6xhtf0@1hzi0OT{}(i>!R-70FLU7k zzsy1Z|1t;v|H&Nk|1Y=})nkbKf0iNY{~Lzr|8E##|G!~K`~QXkbT(w!|9ebj|9>)- z|NqHU_x~?b_y504z5oA0a^e54OpE^iWm*nCyXr5~hW|gAcKrVfu3gXm|H*Xj|4*j# z|9>*w{r{Kg{r|sAAO8Pk`uP7Z(o2qB|G&&y z|9>)T|NqIX^ZzHa?*E_6R{y^+TmS#dZ1evwvo8ZPwAJ>VIqd&027QKr|4$hr|1SmK z8(aAQFGJb?V+;)pvJ8z3(hN-u?BJdms3kX*fe&12&HaC!X(IzKWQ2f$4LmM$`TsZg z2*FndHm1J}e9SEWFEH!WW_W%EwIpF_e=D`1ZnS=h{XAb^Yp{}9@{`OdWW z|5v8t|KBoQ{{NWi?fu2rl0?RGX4Gko|*CgM`jjq58)-VEO_Jz z)VlczO)>A7o&LXNcK-ht(GL6np4sz1=$2A;aH;{f!~Xwd4*LI-Ir#rK=8*r7Kw|{V zVgElc7!aL1+x{P8>iqwWX~O^GICJUk|Hql0|3Aj`_CNh{E64{wAtwniFr(Hu|KBk* z{@=yW^nW!t*S3I15Pw2l{}VKZ$+YqRJEqD!o{|L4i7+R*YG5a&{ zFb6R3G6ynngHB~(4rTz=Ky1vA)6hUW&lCQCWk>|IkpBN-Nd6DHU-=h9>i=I1`Tu`0 zwEh3e(Ek4`L&yKGOvMaLOr;D=Ol1sAOyvwrOce~QOm*Nf1SY0d1}3Jq{~wq-{{Lp` zWME?IW?*4D$-u;Pih+sgGy@aU83rb%vkXj3=NOon&NDDEU1VToy2QZBbeVyH=`MI| zfr;r60~6C@1}3Iw3`|VV|9@b5`TsZ5tN*{5UjP5i^ydF>ruX2U5);!u1}3Ke3{1=n z3{2pjqtpM}42BGm|F1x5o&R5<{m;J)P5hJx4aC1^<6Bf$GfVpn8*mjcNV=*WlLER`BTDZ>GBp zY)sGp|6zLh{}0ov|9_ZX|Nq1E2GlbB|A*=0|36Hh{{Lb6$H2+-pMjH^iGhuonSl*u z%m!Asiv0h>Ec^dEvm65hv&R3|%$omSW3;pk|Nmk(`u~gB`2R0v>;JErZT`Pzwr5~t zc3@y*Fk%Q|U}FeoU}FejU}FenU}FelU}FepU}K12U}K16U|@*)|CJ&7|5t|C|6dsr z{=Z~M{Qr_6?f+MX^#5NO+Wx;}X#f9`q2vEca4)Rv|2L*`(6|_=74iQEQwOYV4sJz! zV_N@zH`9jyH<-5mf5Eil{~4yU|GzPv`~QvUJm_>u1_q{A3=B-K85o$}fLje`m^J?I zX4d?_n_27s4QB2CH<)$)-(c4Le}mcZ{|jcL|1X%0|G!|i{=b{q=KpR6(3w@BmIFUS z{{Nc{Wehw_dH>%s75x7Kc3H{)SCBCW1}3J?|L>W)K>eNn_n4;q{{$Xy0gu`-@GwC} zQXesG0{0u=fX6#QV-Jv494ObnWP11iB{;`J!u|>P6j}ZMN0`n2e_*!y|BKlPbl%SY zoy;!(_cFWwzsl_P|2VVz|KrRa|MxO`{@=^&^?xn1_y66@KL0l|`!aAd`!Vo>&*TUM zoxuz~`;djf7~H4^DY+m_Gi0!}JMsPA>x&GcyBdjEjqz@BdF`{{KIj1^)kJ7W)5_S@{1? zW|{v7ndKOGnYI2OW!CjXe zhQR;t86p`p8FK&sWyt@3kD-u3hM|l>grVX81BS-`HyN7#A7IM+|DLG;)Vl+vAO;Sm z&j0V2CjNiOH0A$yrm6qGFwOW6Dvf!WHvWIawEO=DroI2aGadi`8Px7%di(z=)4Ts4 znZANg4Hjbh`~M5LHq`sSm0AD)4)7_OR-m&F|38NIwH`CO{eQsh{{Jzv$N!tmp8p>+ zd;Pz{?EU{Sv(NwAkWq>MznB9U*qDQ1BN3q7|Nk=s=mZW>-uT84{r?+7?Eh~JN&i1G zB>(@*kn;Z{L+by(3~B$rF@R14hs?u(%D3;}z7}YP0o0CK|NlC;4F#HQ0hJ2i{wmVB z$5;OUWBT*|A9%hBc_sqUjso>tuQO}@zmCy{0-aL`nyo?2`PZ3k{$FQy`u~gBg@GM> ziZkf!EU*9nn0@~L1IN)@hQR+17$O;r8S+7GS_Wl?G6p$@hW}3)8vnnC^m_ikW$OI@ zk_l8Y&t(v0+W7xE6C@sfG9CZ_hUqc`FVoxqpgi)K>FfWmOg|Xdn0_)yF#QFO9D-UW zT%cJ#XvzGVS^xiQW;1ZB?3Q+_U`uPZ4j?L9azUH<=?>FxgyOz-}G29GK;g3oOI z1sTs~U|^R04=N4Tfk)yXz0k|d&i}7Md!e8@=QFeW|EJ6z|DQ5@{=d!a_5UKX_y7CM zKK~yu`!WbJ`!TRXd-k9<058110qKQ;`W%7`W=uH@Y~a}v&@5Ql|G!M-|Nk;o{Qt$& z1{yDCU}x(6|BGqD|MyHY!Sh+565=n@ivOS%`#Gkq|KBt1_8%rsx0PGky5~i|OP4Ure9=|6*qP|CgB= z+`0$Nl_8fBu$KNgX089{n6>|(W7he9j#>BrIq2B?31-9p@0pGMzh^f7{~p>4W@a!0 z=MUI8L-ppH2422rUn1+GcEf6mTCF_r%dbrUtrqs|2%kvbo2jvOk4kd zW7_fmHq-9^znS*_e~)vV;^P0GOqc%uWV-$T8`ItYZdovo3fZ`5v>u|9i}a z|GzOC{r|>n{Qn!X+5gX=Gs~H+|6gFX`G0}I96Z(!Iu|dJjF#v6|7*dm&mI4_;BA4* z{NKW?@qaC|=Kr-Atx@a$Yng5SuVr@nPyJS@B}35vUkt(je=&so|HTmc{}%(OuNMCQ z7emDVUkp(UYz)y1Yz(msYzztie=#J2#-slKg_f0nA!Q{48$&t+8$-8FfcIHF>o+7{r}C>`u{gm+y8$|o&SF`bu%zA zfm&eu|Nme*@c#$X$^XBZPW}JQbo&2qrZfM4GhJk0V7dfu!E!J?{QsNj(f{8}kN^K> zdiMV}({s@HDFYMJ2c*{5-~Ydv{{8>S^#A`)W`_U28LSur{(oQy{Qrd^l0lsz|Nm!( zLU8#g&Cu}wGehJ5y9`bLZ!qQk{|uf92hHPv);WOs_mHxZmuVh@Ak)VGPoX_J(3n1C z#v0tVU|@%i5&i^?X)*m|5M}!N|0gr!{}13gOyvJRW?9f&<)0>3AD!HC$t=ekHRzkVBlnC1eYS9cEvkpjsMq}HUD437>m{We;-;~Kt}4V z|6gOa`G1WWGGhOU+2#LV=%_ttBm^{S4;l&i1Q`hd&&h$t%&?E#+mbb|u%3a9X~X|N z;PHjcpwb7j=7ni5fpG>I1~z651~z6*1~z7`|9_aZ|Nmju`TvJm7pcc?04hbG;}F&i zY|J(cY*ZhQuw}|+U}J)`F)uRp{{PH0;r~UZnG6z4a~UL1G|A(0M{x4_N|9=a7;=SSjTg*oPZ!sJHzXh#T z;Ah!0+c7XQJ2Egb*fRt%Ffar&FffELFffENFff4TM8g>v7$QKu9l|RW7(nBsInWgg zpmi*uQDD#rI_UIe(2P0g1ZGgn0yYB#T1x~wkr}k6sGETSJPQPxxq!_Cf#&`|WyO95 z2BrfH3@CLn`U%b`Gec;nIfG_~-lLAdLuQ0PR{}9GFgP;RF^Ds@{lCrB@&6%oeD5jK zg#WjhW-^E~&1FzzTJ--P({ct0rWFk0OsoI@WLo$CClly)14!TEJ2c)eGVS<(kZJe- zA56FZ-)6eYAkOss|81t1{~t2F`u~vW_5X)VZ~i}omS|6)`TyHYEB-%ZTL1qN(}w>~m^S}^ z&9vkHLvUFDT8p*+|4*g^|3STie;9S~+5i8T&i((#bpHQ8a2pK0K7RNAA9%!@;s0-D zMh0ePrvDF_ng2gzX8He?neYDxX8!*lm<9fW#*{xY3;+MfEc*W|v&{d8%yR#4Gi&_6 z#H{)M60_F-C(PRapD^qEf5NN_ZkIn{)(6cv{C~}C@&7Bc<^QkD*8eXt+x)-8?DYQy zC?t^bG$=2F@-Zm4!18X}|3^$6|383x3y_iVpG*_}KVq88APDV=gK`cZv={!HY3u)& zOxW@>sEv)Dr*Hp%1kOe1r?Wr*|A^`3{|`*B{(oS4{r>~g8}Mq3w@mN;zlY|kpG+VB z|77|E8UcpnakL&gBxlJn@L}n#gL2LVX2bt4nT`IxWH$c)lG%!ZhryX4;Qt+l!2j17 zBLCMjiYkJY2yEHOjG`Y=4$RU&G>(vY3~0cO!NMqLTUwp+614WV|h2gsr>T)drWWt z|AeeA`+pCz#`FItroaCmGDG@X8zB9y|DTy<8JLk)XMyGpZbH@?fKRFw2cHJz4w}ga ztvC4ppV^B6bUzXsvkwC=v+w_1%zpomGed4TIL#dRe*<&S|0B%7|JO2y{6Eed`hOQQ z=#~Q)@JI~o41Cbq((?bmnCch=;pgE)N>kVf%{ypm3L2r|Wm@q68+3$*3u%PrFVj{~ z9}JW`7}%N6Pq;t({}Oa5}m8|0UDq|670Cr`NW_DwcfUJ^X;A8e=;A8e;kZ1O05M}mZkZ1P& zzlPcG|7K?Y|C^Zu{%>Xu{J(}d=>JmY;QuR_L;i1O4*kD@Iqd&-1~;Z01}2pBQo+E? zRL3BPlvY5ad0*k zh&pJM7^sW^wWR8C%&)Ki4_X2FjcGFjKhxI#@0fP{|HTAaDF^ORfmVw_=G;MZWZ-#s z8St8zU(A}|RgWk)k1^~0f61)>|0S~l13$Cj|98wr|KBkigJ%O7!1FoQ|9>&tfJb*h zbM>6eE(~nUuAn;!8915U8CaM-7+9D+8CaOT7`U0e8914J7`UPHI-q_B{<(S&hM@n~ z7=r&_V+i?wjUn{^HHNVN*BHY8Ut@^)e~lrEftw+kftw+gfg9W&0j-=(W8h{;XW)jk zMgPBL%KiTpQX(@jFctrQ51wx>{r?_3=8fD20nM_s{(ld?OA6E$1+7NHY=<&4&12wa zS`Qwj|IW1k|68U5|KBnl{Qs5d(EqPYhyQ<7w`-w!~gfpGXK9bYy5w~tO*|7f5B|?{{@2w z#jW;y1_p3wfzlMd);g@VhlLJ$3mw!iTFt<~v<|f1h=GA=D`+JI0|UlAD=49XrIij| zrvFBmrUnKECeWRHP5<98HG|e7 zfLEryVQOb!VCwk)9o#mB`F0Wm1Jh&%2Bv8Y3{0#4zhPSU{|(dn|I3*6|9``D;Qt$@ zBMb~oM;REHjxjJWodEg%{~M-L|KBj3{{M#Q%>Oq`SN?xTS;2OLfr05J0|V171_q{k z3=B;785o!zfLFG?VS4oc4b$WQZ|GzW6`Tw2i zGkBHZCr~?=>HGg*Oh5krV*2y{JJa9)ZX|Nn+r zd&Hu~5<&*XQWz07JmoeM@f5Ytf{|$o=QyzmjQ!#@uQz?TmQw4)GQ{De3Oic{J zOsx#UOl=GzOq~n@OrX1`dKpBRCNPLFO=XZ~0<8_5`Tq*j-2Z2p7W{wDwCMjgrse<7 zGOhT3g=sYdAJaMpPz&%U(?-xuZU28WZDkN(+QGmFZWo_q5N0~XAk1`{L73?bgD}%Y z25F{C4AM-u8AO=w{(r*skU^N~5rZ((V+LWSXAHtj&lyCR-ZIEBy*Hgqax_gqfNCUtwnce}$Rl{}pCl20muK|L>Xk|G#Gz`2U_+=>Ion z;s4*5Wf=IF<^G>#R$|~|R%YO1R$<^{RtL8VQP*D>{Qu2t$RNOM#2~|8GqH z7#NuTGcYhS{r|(v{QnO#sN6!GAB6NaAan1abw2+v%d-E_bw3OY%-ReL%sLDV%)01h z8+82-sBE+U|C8C_|4(ok7s!;uz{-@%z|54#z{XU}z{XSx9>D^&#o3rz!SnH;k&S0e zoeZo@-3)BdQ7zEuh6uEu_8ro@obee&U=?nuKbOZ#{MrUJs#K6Y%n1PMy8F+sGHkKLJH{jK2 z?-|&TN5h!@GO#f-Ft9N*F^Hht6~_1fJ2U_P@5}=KzazENd707g4nrRm)Bk^s+3^1< zW~2Y7n2rCR0_{D6-ys&n1iE`F7qo^EdCPQ|tdvOl{z{`d6lI z24-;W(EI-ieC_gt|3{c+GDtGbWsqW8^#424at1-B6%3M0tN*`cTKE4g(}w>im^S`@ z&b0Oa5vJY$K`Yz-GVO=nXLa!ZC#FOHKQSHt|B313|4&S({(oXR{r?lwng5?qYK`0f zk1*Y35M+Az{}a=r|DTv1|Nq4F?EfdG=l_p@YY52v^;4$z49rX){$FAG`2Pyir~g;L zHN@ZlpO_i`e`020kYr|NkYr|IkYwil|CU+k|958L|DY8Ug3L<)-!d!zf6J`$|1Gon z|F_Iq|4%S$|3AU3^Zx|1?*9|adjDrI>;K=xZ212Ov(f(}%*OwZfcJaY{eR2s`2Q_K z2xKnq|6is&1|fKQgsp<8U|?se`+uFOi2<56!FPB{Fm-~`CAd7~V}k57VP=~7{{Yk6 z|9hbQMbIj{JxnY9A7I+>|1;A@@SeO6(3(U5ye0uYclZA<)1m)=nGS<@zx`oCPn&0v zR#;qQU}w6-z|M4=fsg6#|LaT-8PL)z10T~%1_`ED3=&MQ86=qAFi0@HWsqQc#~^`L zCUSw-%z@ME{{zg-{|_*;{6E0V_aC`W37rFE5MY-3zlT}t|7T|H|DTz4{(olH{r{O+ z|Nl>Bga04UYMR>&p-edp0!(=f0!+mWQcR@`Qt%b)klN)rQxk&}Q!9fMQyXYaJp&84 zj_ze(XPUsk$TXFK3%vez=Kq`EzT|@c_n`BI$Cy_9zsa=z{~PdF6=+4^=Kr9(H$i({ zAZxnzGYBvpU=RSWE|i6w?_7DJJA~&WM_Yk?HRL=S&Y7q?jHtNHINT zkYakqAjS0j|1YMO3@l8q7+9EIGq5ndVPIi;%fQa`j)9%&0|PtLM+SDLPYmqP`df;b zfkBFy>Hke;=KnXDS^nQ-=KFt-ng9PiW`Y0r;B%0o;CaZ;%yR#a!PoSok8eT7wjMEC z{C~@A`Ts4m)&JAX*3fnTpil*^^aiCshs&AR&T$D*V&+zpc@(3nLu+OTNyZ+b}$HlcVoiGzL3%=`nVVNI-3`oK2dKf ze9pkj^pZiA=@o-4(`yD=v;O}N%%J%gLk3P}BL+@pV+KxUtN&LR!l11o zP^bzr761RwRQmrv6MROVfsd)~{|%<5|Nog<|Nm!dV^D;KDl=0z10NHlMWhH0RnY3A zng91gOMp+18tOl&1lSKP0YsQK|A&i>VH)Bpc7 zo%#Qt31vo~fsg4D10U0E21Ta3|8Foo{QsZn(f|KUkN^K?diMW6({lzzETJsR^o~K6 z={*AyedyTy zedzuHZicr1rx@D*pJM3ve~KyR|3@ZBP4|JR;QtGzBJdv34@@QhKQfj6|G-rF|1VS3 z|4&TS|386u{x$voz|;y}8~K^3>p!UGV_@p}|B0#h|6``U|DTxp|9@hd`2Q-?l>d*J zAiGuXGj00+iD~QqZA?4Gl85OmF^wW&+RY{C~{! z@&99{PyZh?eFKk(eqd(!|AATN{|ThsvGGqo`YF(F#;f=m+_gpkrJ zs3h3WwBY|6rbYihGcEtWAKZdp|Nk2_%?g6=H{Qy?10I(F?QuW&A1R%J_B=5#Go4~! zW;)Hl%yfoEcE{~v+)1V%rgIfG0Xkm&#dwP z8?z?(c6!uWOYi?jX8r#knGHaDgBW<2jTm^CjTv~Dt-$xTe`B`!|BWGn33+Z1HjhyD z|1(qh|IdiN(f^A~9sgf|%h=xk@4>73K>LP3Yj)-`ut0m3pp|_r;I%ue|NmiH_x}&m zhW}f^v#(qKUxm)Vfz}cHBzm6V?ElY9=l*|YI{*JOc&rekU-bVX)64%am|p#V!Swq7 z3#K>Vy-P2c-u-{U^x^+|rjP&MGkyC1p6ToV-%Nj@qZi2QfO!A^LF;`YuNY)uR{H;k zS^57TW|jYcnAQLPVb=P;m0A1$R%V_5TbXtLZ)Jw8AiU0O`2Q-i(f_N=#{aKE_FXe@ zG28wB!|eF~4?`4WERjK%A(26sA&EhNA(=sxA%#JJA(cUtA)i5+p^(9dp_oCAp_D<6 z0kmJIkwK23iNTVgjX{^8ok5qOgFzQON(&kb0*%n(8)IC+Ak4IgL4;{NgEG?w21%yP z48lxX8N``(FlaOF2JMW4?h%EJz+V3Ui|Gn@$2H_6gYOL7Og|V{nEo(ug2y2F7=)Sm z8HAYy7=)RH7(|$b8AO<67_^x+7?hbc8I+l|7$ljs86=r?7$li>86=tY7$lhW86=nu z7=)P(8N`{57{r;48N?yG6u{#^%FH$l%FIrnI|~_PnOzuEm|YpvncW!FnIR{0$%1co z_F}ML_GXY`_F>Q@dR#J^DTe`cb2F&F&&O2Ez{ga|zz5$UQUU6Ff$q&^;A3h9tyBfK z8$j(_(2d=ob^|lC-M|Un6%T2ZfksVWBPKV&x7=d39|V~|tM2wQh%g;s5Me^?_wzEH zWZ+{u#lXjOnt_k$3YD+*wvc(9RM(CA&=|10njJkaP}8v`F?jt2{cCw9?AXx7tuds z;A27_#hU>h7uX1GV|->>^#2#ra&Q}CBh!ZeZ{(k}Q&P3Xk#q^7TiRm{36KI_o)4%_3 zng0KO%gpfq3o|1F3)=V=v@iGn5wjfVJQ(;4`%7l+|1X(!{=a0_{r{3#@Ba(%3_IwQ z5yZ^;CuU~`K4w=27G^gF&@2gPW{ri}hk=jT7j!-dc&EGoa{vP;bI|`k%)$RZF=R6Y z{r|)OVuk$w#1Q)b6GPblPYmJzKQTo7|HJ^gjWp{2Z-(gqzZqix|7J+||AHa${|kns z|A!fp|6gKA`G1%p_5US?wEw>u(*OTv$oT($-W_CflI$kq%{Qt<*`~N%Bg#RDF```J>;M0m-u(X$KS|{M|6kD3je+S8XxBai4>JP; z4>K?Le3nPd{Qn;@3;ch?EcE{kv+(~n%yR!fGb=H0GAlE1GOI9fGOIIiGHd_#h~Md;;(7fz&x45OvP~mrOGm7?>6?Fo658E5Nfyf0@?( z|I4)g|4XI~|KBlf1dZXLkSpiP_^nXiqn2 zed>4cDJ|erCBUU1Gjjj~19KoKe=)E?&b(k?VaQ?10i8_q|1VSi|2Is9|KA|xsSiw5 z|KBiG|9`_&^ZyM~-TzZe4gcRTHG<~%{=Z>r`Tv2b?f+k<_Wy5~IvBW_I{)8i0_Cfo z|8Kyv1bzSCF!h6X6#ZqI^#2Xh{=Z>5 z{{KDGiT`iV^3?~XOaDJGUH$)t>DvD{OxORvVY>1E4b#p4Z*$-vF@ih-NyH3K)(8wPHsw+!4&?-;n5 zKzRyz#^Uq;H%#CDzhV0R|1Z-I232OJ|7)0;|F285o$Y{y%26 zW{_jHVUT0UV+i>F8GK4a)PKbOpoIT77!v>AU`YCZh9UX?9fp+uXBbld-(i6569Vnv zEM#D3fSe`)+6{Gtq3!<-hW7tA7&`vnV9NdfnF%(sT*tt`)b{@+Q^)@=;4?))b3POP zzhRpB{};41@tJAG|6fe2|9@v%_y0T7`u|s%HvB&aJ}YhW|DVwPcMq6$|Njg=+2i2< z&rFB@e`Y%T|1-*-yxafZFx_QfV0!-lCDY6QUzlF~|HAb8{}-k=|GzN3{r?fX+v@%Q zf5>x0;FG|Z{{LcT{{IWScZv7^ceK_7tgromS?T|GX666inN|LOXIB3Yn)ScRtoi>c zmR%#D(`{}s8~p!?viA=Z1J?hqGTZ#W%53-lJG0~e@61mB4=_9bf6DCg|2?zof6$un zU(h-Yy4U&tZD#NPFTrOi_%pCG2QaWRgHO)*|CgZGl6lOmF^wg6}H- z@E^X%hv_c^JABrU@&8|DrvE>gng9P}X8HeHkG$=l`J9{C}XU z`9Y=ScV@5upTMQ15BTgN9%g?A7I14Mkb#{!7#xG3leO5v=kSy=1TZi&ME?JbHmAzT zkjTKvkOVph<^LbpxpUx_ekKD0xV4|nzyLmttC)eAp%lFC@dra211Cc}11CcV11ET` zZ0`SW;FG$F|Nmqv{r?lXABByn>Hklr*8e}j^Ae!bCn0S|&o) zuKF+2hX3y&E4;w@@)zVx1qKGl2s(5P?Lnk{fhYg}WIFZ#C)4TwKbg+_{|VpMa{K=; zaQ*o3|4*hz|9>(){{NHd+5ey5`G~iW{Y}X2OD52cJcj>2!RxP)+m?v^g@3{AOU!lH z(D~c{@0qp#zh~C@|DIVFd}bZwL^4PoMeH~RovH*o&%q8fj|jKRko^B2L(2c>45|PBF{ClDGo&-HGh{F@Gh~5cmq7rs`y6}<*i)vQ|9`*>!&7w_NRi+vV@!*28n5Q=q|O3@ZD+q|Nmt= z@c%DLuNt(!7=5=A@(O9#&ZXP`ze8gfefQFLrk4!NOs^Q2nO-w6Gra+wj{`l|5L_Q3 zPCEjhh6!0!4LTE#0e&in=>LC^oo)>5NITswGHd_8$gK1KBD3!Qi_CiePk>LYLEh;t-q7QEY05PFW0 zH1r%J&?#}CGj{~RC#=*l1pNQb5X8XF5X`{N5W>LD5X!*L5XQjH5YE8P5W&FC5c&Tm zL)8D54AK8zGQ|FW$$%)aPctO{zsQjC|1?AD|BDQ1|6eks|9=UNeQ4M9|GzLZgLXiJOX|1G{QuuF3xMapA-#D>jGtka1D|fX zhglOmON(A&?*X5aYw-U)T8aIa84>f$%+~++Fx&j!!|e3`CiE;o&|X*232K<<0s1m< zf%7-4?gf?LL0C%h2Bw_5~}!rjj58s zkg4kbNv7)mCz(Jkqo)5$m|FiYVQTxo6x@sN{J)zCw3@G*L4c{}|4F9a|NcyU|4%aY z|3Aqz;r||{iT}Hqru@IjH1+>ACh#a3125BD27RV^40=op{)1-Y4lu1?;AL97_{C|$=(EoEx zhyR~rI{yDP)5-r!m`?p)!gTuo5~ef%m!Pz^F8;s9bm{*!rmO!?GF|(BlIi;YlT5e& z?*X^K9{yj#^yvQ*rpN!6Fg^Rfgz5SJrA#mWpTshfu!-s2{|`*>83dR<{P$=2_}`!D z(|>=aum7(zefxis>HGiJOh5j=X8OsX#q{_85~hFuk1+lJe}tLg{}N^<23}@n23}?s z23}^~|NUq)c?Xz<{~ur$`G1>P=Koe^&^ek)|NEJh|MxSi{O@O0|KHE7@qZJu=KoF1 zTL1SkYyaQJtn+^#v+nk(*{{zfc|93N6|KG%H z^M4bw-T!`O`~OFn9sVC-cKqMZ&;rf-c+RKze}y6H{|kob|1TI~|G!{J`2Un4@&8kX zr2lsqlK($oNcn$&3ri%Z+!RI2i{r}1YIxQHqZ@l~ecgV=z z|Igr^JTw1)2A=?pSR43@X~qA~OzZ!HcK4ivjupLO+VTGmwEv4VdxKQZgU;SO`~L&e zx&I%S&j0_wbn*Xhrc3{SGhO}d#rq}=fGQIi#mkCzazyJT8 z33;>+Q8xTxX8Qk`nfX8H+}Y1)vo(-b9HeZx!z>40FAdvGguaveIJ7kf8ec-3lLspo ztp9^|7%@Bje-A%*#SOF<1AJ1|Pe@Jh{~NQ<|Ig6*2+;XAT+9IsurpU+Ejv(cz{MQK zz{}9a5cK~JL-7AQ3?cvTFogcU!w~lW4nz3=I}8z^-3SbNs4c$#TNo1mZ-LGeFN4k# zFN3%I^8a6AC}gl_C}t34C}j|3C}Xf;DE|*?w{Kx+|G$NyW$XZ7R@VHjN|Ci9U zwZFh8Jc3RmM;@UE?ejydvHb-Z+xq_tGOh(W4I8%a@BcISh{?qN=ip;ppq(HjnEm=<_-^Z#GW zpi?NB7`U048Mv8w|373F`u~Gj`2P>^oVC*bhs?_VA2O@_f5@!<{~@!+|5MDG|4(7; zus2{}V>bN1irMJ@DrV#VtC&qevtIvCG28q<#ccQgA+zKEhYUSTIsc!6&veND|DLJv z|9ht5|BsnU|37Ae&Ae9p|ISqN|2d_mX*L5h z(;V=r%uksXFmN(0Vi00l%)rdFl!2LP`Ty5UEB@bMTFJo7w2FZlJZia?ff+n9a zX#;}@(?$jcrp*j|Oj{ZFn07EIGVNv%gtq^mG9CE;lCFGfOvt^yi~qkfUHbo>>Bj%}OgI0(XS((OJrk&ZaEC#j z>F)n~O!xl3XS)CYJ=25#@0lL{f6Vmg|6``d{~t3w`Tw5jDR{;HV{pIWC0Z=Q&OmHoijYZORr z0y@p@D?`)&Hw zGl6Ot$SCVqc$qQb|7WI&ptEoo7{DVwpjipf=~(a{=KsIo(VzAIA2V(Ee;0g`31o%> zRO>v2);fQ1tQo+vt{UllM_6A3v}zc+47vUPGo+n@w$tJH|IgsjTF42~Kbb!K|H}07 z|5v6@|G$D}^gwF};NuIRHP)b$m61n}u=Pwq=Pt?of66TT{|B=ic$D@rv*!QD%v%5N zGHd_8%dGSNF0=0cyU=?V?n7rl5H*zb|HsTW{~t5k|NqDA@c$pP(|^$Upx>Ci{(pd; z^UDctp@K$Y!KV;G>|Z4Aud@p;g^Ft~Thz{~_boAm!*rkVerfKS(6@c#vL@4`c-75|?wtp=A#pc%-g z;1fO}^TDr~wlc6W?fCy5vg#DRe)kR2q5p4~4ueN{e=?o?|BdO?|8GpE|9@jT^Zy&l zyw^nr*o-_g)7}3sm>&NB#`Ng_H>St`zcD@g|BdN612YpwIRo9d^#Qr(%D~Rd@c$b# zBLfpN)Bh*T%>SP-v;2R}%*(*c%=iBVGyne=%mV*k!1p_dg3l0p&n)-v$D)BM9G4L_FGe|RgfcFxLFnfXSTwvgX&U(IQ_WS>W+5i7H z=79h2nFIgdW)AxQo;mpcL+JT(FPK4TiI`OOfg$SuDTe6(rx;@YpTd*MPBEnaKZTUa zK&@Uvsf?Mam|!YnKucw8XsPTI6C#y8p;Ibj!;#7uC`e^5h)88msF2Fon5mn}UNigu z|H&Ni{}VKoeL_oRpBQE{1pNQY5X2zJ5X>OR5W*nH5XvCP5XKHjl^`ads*qI(PuroblUdSv+nI6DLDw=O_7%cYAh?wcKBJr2j)9HYo_`F`w*bXoJ46`86`MnH+%%KdRk$EnLx!{^J@c(E0 zD?Av~;Co(Uz$Zs>GsH2lF~oyUkowG!`2RCQ(*JJ^$^U;ar2PNJkox}z18hHR#{ZWL zS^r-`&##kVC}!YdC_zDWXn zLk}-xwH0_a{2S9c@CnMGn{KXyNB*~hPg1@CPLccne`Y%H|1;CU|L>U&{eRDN7~JCj zfU(~ed1VQ#O?LJF52kDXe=uGD4?2|v)E?tudWg0U7u+8E{{yougw7Cv$BU76e0^nL zVEXp|2h&dmNl;sjnE`yt@K5lWRJ`D`1E4Ff{@;Mk7JOq?{{M|x<^MNk_5Yw#p3g#W z?YYjZ{r@_%&j0Joy8o|3?+QA`Z212tv(f*b%*Nm|0KdW3C^Osr|Hkb2{~Kg18FXUd z|4+K`?=eC2+0pwy1`TqrSYVQBP4D-M<=(+ztFy;OK z#FYR4HF)(_;s4i6MWB;%|G!`=`Tw1%^#2Q{vi~QU%Kx8assP<#_5TG^)&JK_)&E~J z)%<_WR0}$H?Ef*Q`u{JP8veg#YW)A2sp8e{C~~V`~MnK-~ZQ4{r_JxP5A$WY2yDsOq2e%XAN>D;>CpcVOo#t}U^?>uHPg}mubGa4Z$Em-bmISOrj!3)FrE7U zg6Z`C7ffgVzhFB1|0L77|0kKw|33-d(S7m%8>UO3Qyu?5V!8sllj8qtrfdISGhP4x zn(4;>*GxD6zh=7i|25O?|4*3i{y)Za@BeG2`~P1vJ^25c>EZtuOppG*V0!%j1=ExN zubH0yf6esl{|lz)|DQ0u_zzkGg?fL*+yB3r-hoaI{{M^V!~bhcAOBxt`t<)A(`WE0 z|DTw?{eKOe#aCkb`TsA|AMmN@FPQ%Qzr*zZ{~czA|1X%C{$FNh{(l+V*W~^Go|*6e z7iRwdUzi2{e_OapBNys zm7sNU47kogXJ})PWoT!RWdQBtfy`@t1>ZbZ{Qoag>Hoj*JKri8xS8tyzhr9q|Cg!t z|6isy25zPf206&w76a%82ri}x;Cp#M`*uOKEhuGPXIk+88PlTwpO}{azYa;647^P1 zz-JgeXWH=p8}v*xQ15}8X~+LhkliZqxi7>y0-)PtPX7PPbn5?KrqlobGM)MVm+36x z?m4E54BSkY7`T~kGjKEA{r{5b;s3u(kN*Ed80Iqs{lCHx{Qn9=$p0%0p`hJL|F1BF|G&Zz z@&5|=euXFo7KUgB7KWJrpBQ2pSQz5|e`1LL|A`@ifsG-NfsG;QKWMZAbiz1jwBr{; z8UqVMIs*$s#{c^ang2gCWc|O-kp2HNI0cq5@Gvwn2r#rUurahVurYKnurcL;S3Q94 z4SE7T5fOam!v6ivI#sqg<=rvCqLnI`w^D(A$?m0CZ-jjF}MFO znAU;rTKs72r`okx{u`lFJ>PGE@t2VAD9CfKqn-BVGjBKf;sg68-|4pk^j3HqW({2 zi2gsBA@=`dh9m|yhGYgdh7<-ihExVNhP3~a8PfkxhRn!-R$qW-WWcL07#JEDKz&md z2GG7)P}>Z25)5obJR}u?R$hQsLqTq;0QDFkYfEo~_i!P`;6Fph;6F39F>pc0;W@#p z<-xNy;GP5*_@sH*I#bYoT+kRi=w?O8DGwKz=KVj#stv>~o zcc6PS-!N@u-~yjn06K*R)|Nvaj|Z)EgpA35W;*r%Gt=q+pP9~pS6v})&;X|_=xL>w z|NlT;d&nl5!h${ptVDOppG5W_tYpGh+Se|IbX%8Mv5UGH^1zV&G(Y&A`d@ z2D~#xi0K`J5Yv0m3=z_P2gvyvznOk9Ff;vTU}pLYK7*bCyyKtY|7T`K&{_2GlO_%^ zb1-m0Mstx?;)CuagYB>u`Tv4h?*9dp(Ok%yRrE6R3p3=z>Nm`W3|!1c3|!2{44_*& zPlHEn?HTx(9l$40Ku+E91ob!=7@2+l-(mLq|BTuH|1;)*{~wrx{$FPf`TvzU^#3Jh z(0;*1&=Xs~F$Dd8#1Q=d5ktuTM+~9=A2EPR$ngJ<7$W{ZVu)lgz|-6K!I1d>2eh~G zAKKgakE6Gt%uvk0$56_^$56(g%Fys1)Z1WWX!`$zq3!<Z~XtBsT(wl1fG}pz|{Bu zD^vgfuS^p_w+4dlN&w%aDgfFWQlOxON@Wx5WYll;ka2Xvkvg9y{Z|Ato;8ov&#R^%T^e`aFX^m)Vnnk=g723uf>C-|AC&U z3+jP@&Ucbz4rCC5o~R2tiToFHD1#9Au0K#p{L28kCn)Iu6NcdbPZ&b}KVb;{|AZmz z{}YDr|4$eq{y$-eWUyq2Vi07AW)NhEVGv}9We{YDV-RGBXAopa`2Uk3@&8ZgT;@;c zT;@-PGzLM2bOu3&jQ{T$vi`qk$Yo$=C}c2TC}t30CZ%T)UREfeU@gmMNRCQx}=_5UwZ_5Z(2bqtD3P5<9Awf=w0 zgy{4Bf~La1;MuXh|9_eK|Nlkwc^NpN_h3kYXTz2=h%v2TU}IYSAJ+Fh4L;{`Izv(< z{G?i@Z~y-?{RG`43|b5M{|(ds|Df}R-ZF#dDxi0BurRPOgZjgKNHbe9;6AY!v(kU` zKJjU0&Htw{&gazo54x%39<--{7?AAk7@iAi*5+|0i=Og9I~Z)zo6}ja7J4;s4DHsB;%042cXP3`q=v z&>o2(v_}G)yZ8+4k$h$Vt)B#)vjw@C=>kIogB0{;CKiS^1`&pK1`&o11`(#5|NoeB z|Nm#oW8ep$Azl3cA5-c7e@M60@G{l?|H#zz{~uE;=zJUS$r+$t$v<$)>t*0!n!o@$ zJwp(>v+x1a-2YFQ7W{t=-gmJ4KWMc10n!-YBcwTvhme))pgVaP*qHYJ|HpLT|39XK z|Nk=``v0Hl@c;iz$Nz)QEd9rH>i<8c)Bpc5o%#Qd3H3%CUZzV7yx?29Ap6`tGClnN zkLl6>e@u`6|6_UvI!_0DnuZ*no(T`rM+P3IPYgVuy9Aj2G6*1M!v6n*&T~9qX8!+x zndSdOW?t|Z;A>|7|F4+^{=bIrtrrFNQb4;yKqJuTV}FmBHUB@tGS6`rd?${<|A(k6 z+8H>R5xtZ*%+~)OG28rq1Rno`jQfG+ITXQdLBx$%YRn!CBFvr)(#+lrlFU8~V$8n( zLA{ix%>Mr$F$esA#2onl0&~#+N6f+huQG@Hf5{yB|2}ir|ECPg2#f|R0eEl&(>|Fvd1{}S*8Ts)wEq7R=qWj$n80Ue z{6EID1g-D<|2or) z|9_cY{(sN(>i>JD*Zg)0 z|1vZD|I5t#{}VInJS}9;wKJ=;{OksO8)O> zD*Jzfsr>&9ri%YpnJWL^W~%ysj;Z?pIi{NbmznDRpJuB6e~zi)|7E7e|CgDX|6c~5 z<=y`OG81TzNaz1UOkMwXF?Ihx$JF!x98>TAb4-2z&oTA?KLsQV*t@wYE33dX(dInym z4Gi2&8~?vy+VuYy(^dvvrX37I&@)Mxn2!9v%yjhsWu{~QFEbtgf1T;X|I18g|KDIb z_x}dd`TvkJenDrqUIO31et_xf|8q>&{-0yI{{I})jsKUKZvMZ_bnE|R@aY71z$X=* zX1e$PGSmJ4mzf^?zs&UH|7E79|1UFvPQZQf{~XiH|2LRk{lCHV`u`24H~()iz5V}) z>D~WFOz;1nWBTy_9Mi}D=a@eIKgaa>|7E7H|MxR}`+ttN3l-pTi# zA?W{EhT#8a8AAS_WeEL$mLcr_S%&ccXBi^?pJj+-uxE&35N3#G5N3#B5N3#F5N3#D z5N3#H5N1gD|B)f_|3~PFtY4ugvVLVqV-RLYXAow{`2Un46TBDtDMR-EZw$HMTRJ{4 z6f)>Dlrd;AH2nX>(D?roL(~7C3~m2EGPM8y$N<_o3+lH++Lxc1ivNFRDh2IcV&G&d zXW)dkFMlyrgU?Y`W@`HXnW=?=nW^>vXQnoAO8&~!`TsLhHv=bA&;MUcz5h=#_5J_F z)DPYhdKWtL$HO#}0d&)<4ATMz9wyMKoXZ&$m{u@wGOhmqm}wpOe3tj%d!jZo@IY?_ z{sHZq^Dx2s=9ukFw0=1QC(}6wPNwq=oJj3VP|xQV)3yJVrQ6 z^}YXJW_kfS4eCGoxx1jdYyU94XW(S|@c$&!$NwjpKK(z*^zHvIrk@OQ(EZr^nEwCY z#|-Xw|9{2I#K6hS3_d}ElbQGbV`e@E9%g<99%cas9{9;G@?E-ly!Pw>ie2IvV{|L;S_CPDWk|NjX+ z8}BpH3av*>6aRmJrc}_V`9JU;0mv$?zf7R>t-(7){)6@k{6o5D;U;v&);I7tC8Skw zk7>vMo8Z|&(5TWr1_s2+EtC^6x$vKe312__677t=M@*nSewZi0+y}4R!W^pv-GB9! z3DP=1^pe0cg$xYPvXudJ1~+KNkm(--3)6oF7Vzm?jQ_tfGyVU^%>4f!bZ;PN7a3x_ z5?r=I?}-)p{}VD_^ZzEZ?Elx`eF~U+k!~_;{=bQ3`7~+1 zO=g?_H<>~ElI;I~V|D<~I{t*-75N6bhwuY4Wbf`BW{>}`m_7eLg{~BP1zo!gy0;57 z2EYkE#UK!TiytR=?-JzRF3|oZL5712f&cF@1pPn75d8lXL&*PA459x|F@*g;#Ss4g z6hp-SQ_#JKyBVVY?}oNGb|bYoAm>vgF>o*>Gw?E`FmN!WGVn5_{ol=y{(m>P#gX~{ z2DsIc{r?6-&i~I0dH?S)HkwqW&bZQmH)rMRPp~FQ`P^QOx6EyGS&RQ!c_PFBvZrxD@=|5uP`)OcVY;WSaE<3e)8O zSD2>$zsEG~{}rYg|1UsW9%m43?Ee*}E!=Y zOsD>zVmkf*6w{gir(*Ju*SO4E+y7vDj)Aj#1nQr{Q z!gTZh6{cJNuQ1*I|B&ep=;o;ZCzFfV%OyBQ{ z|Am~l^#38VH3KWN4FfB)-Tx2Fj-b2w7zCJI7zCJI8AKqb<%4#!GjK6`{{IO*EuW3q z_y2NczyHgb1O6{(4*I`_Ir#q~=8*pfm_z?BVh;PioZ%RFMii109y0|0f6Nf_|1m@8 z|Hlkr{~t4i|9{L7@&7S2Cmdmj{(l6T6OIs(6OJ&X|3AWz@&5$_BqzLJ0ObTw4k-J7 zmH~S%xC_k%uaR=WYo^lwSCDeS6SQ1#4Jj8~f#!l6Os)T~pyh(ANVxzs_YcbjPmprK z6KF1Yz%=v!MW(s`FGF(y=mgL!Oe_9hWLo|IHPgEPubI{}Fhg^}L#D0&|1#}h5J1WW zcbN|Szl$dqyoTn2D@>>UUtv1^{|eKY|5wm*!4sxS|DP~{PP@RJ6P`eG!ZoyXA7A^iUhhKT<+7$W~KVu<=bk0JX1JcgM6_ZVXT z&tr)De~%&l|2>8T25E*w25IO>9jJ}~jnskaha5xp$AiH^g-Re+2EN z-bU)B-e#Kg|02`m{}-XX(~C?q{$F95`5$sS2>4_X1_q|(|Bo}R_HPmIOc(!OWdikBQG2Tw znQs2S$aL%fMJCWKSdcnmKhwSc7n$z=zsU69|3#*U|4%bL`hS|~@&D6IPySzIdiwt& z)3g7lk$SI>m|p#V#Ps_ABc?b1A0hQ#A2EISf1By!|JzKT{@-T${Qn};*Z;SXdawH6 z78at8c*4x^|1>k>|L@F9|Bo;;|33o0{e<`bXJ$U6-Ye{uHBs=4usE~a|Kpf5CJg+{ znhgBRS_~Y_+6)}bIt(1lx(pof+fxh~kk>UZGh6)s#ccWi7vvN~27YE627bg03eh*L z9B20Xf0fz)|5fII|5up<|Lg3vFaU(C;h*Kmc2zv0dktKbY0iIXf4 zHL zm^}XnF^Do{Fo-f`GKex|Gl(+qF=_w*#-z)@&1As9!espaJCi8`3zH=S3lm6J;Qt#; zA^$%yh5rA=l*Yiol)=Ejl*z!r1e!hIW71||VA5q^U@~CfXEJ7BU@~K1W-@1BV6y!G zm&xY;A12%Xf0K3UFfeKV|HY*H|1ZQ1|Nk*r{{P8j^ZzH4Edv8n@c-XTF$|ncu?#ZIuAsI3 z|9><4{Qu7!`u{J35X6N4Z9GBCSwMECNl;uCUXWZCd>aHn5-GN;64oa|Ar~>{}rZS20^Bf|2IJ) z%#{59BU9S{&rBKrKQm?if5rq_{Ugex`TskU_W$opy8nMcO=Vy*WsqPp1Bd)~CQAk> zChPy-nQRz@nF1LknSvP@m_iuXm|_@YnPM3P%Jvj1OY5NA?nU}Mr|;AYZcU|`Z?U|`Y* z=L|L`Lk2b`V+KJcGf=+z|A)zjfgfyY6axcOG&pCPF~u?jG9@!8GNmwBGo>+D zGi5MXGi5SZGi5VaGe|ON{Qt+K1dOg{hL zF$Mg8&lLFo0#nHUdrYDKpD{%;Ffb+m|IU>1{|{5@|36G=|Nk&${Qm<@A%7SonbiNk zWzzirj7j_dbtc{aZF-PGXMXK$@>2@CL0C@XdM1!@?l_O3i$tt zDUgAeDfs_$Xv+S>6vH6M6w4sXl*S;#l))gwl*u5&l+7T+AkC!y{{@rg|I8HNA`2JkJpWelM8N(>C3mB5gaivt{z#{YjanL*Ph zD3`i`a_RrS;9MH`e=k!o12a>||MyIx|KEa7L2+YX1K%PAS=aoFIgo*YIr#rK<`B?H zVE=zH$S`UAe+Etkx(r-Q1`KRWM*p8Nng0L6WcmLNlgCOim0EOl}N}Or8u9 zOg;=OOuh_^OaTlcOhNybGX*oSF@-R2F@^p=!vsnt$qZ~vDgWOxrT%}*l=lBEQ^x({Qtz1`F|hO)=v!b43P|K44{*OoBn@dnDhTFw9Fy776Q-7 zLr!@64L&^)a$XT=R|NVkVEoL%4E&%q>LAHpv0QrhPKD<+@+KcF?~E@(>n!W8=dDzo$d*U(dwJ~4a#2c0o@54xj~ zkJ*m_~6b2QhR0b8MGzJx>3LEYz7quMTW@#hZ)NL-(zU}4>>h!&i`M~&=+Ph`2Pu99)U`HNJ-DYWW&J72T9xiUx4a9W@iQlW|#lpnOzwenB5r|m_7b~VfOt04ICTbvq%2_ zWA^|5pE=VbWxf0*8k#gFLuKGXjT!6q6Z)D3dvZ z6q5ym6q6+b1Cup_6q6l;6qEh`n@mpsZ!)?3f5GGqE-7y^`TYON6!8BoQ!oQRQ^@~E zOrih3GlerqF-0&)fx{>k+!B*wN&=NI|35ROgK{7P1A{WSWC;Y{gATe~mVu%1|8s_> z{|~@vLjC_=Chh-UAnl|7Uzm*le`PZL|B1=+|8pjr|KFKx|Nn%xYz{+PHFv;i0&*7G zA7(drn1Iegd(7(aC zKy{G8|Hn*548llhLjamK1ek0XxS5dChR^?B;4&}h{|BaE1{S7}|KGs=k75vj)>C{; zu?*5o_|i$%{}14_qQa!gz{RA-z{RBT{}&UeHKWDA!lcc>#-zi*4QV5R%SC9-0&m%T zgSKpbG1)P2G1>qB%jER`FOw&zG-hC63i`jBDfIsnrf>!>rU(Wurbq@BrYHt(rX&U~ zaM_>o|2tFa|L;s`|KCIFwZlwV|93NG|Np~)?4oB-7cnsDfLe|WEbvm=gn^66^#401 zGX@TDTgw96-ntES)gy?j7`T|67`T``8Mv4N7&w_i|DQl|5d%{cs8!Fv1$7k*Q_BAr zOsW50Fs1!}0d0?M0hga@OsWiQOlk~lOd9{6FljQdL1GW?A|WQD|4*1q7}%gLVq-FA zU}LgiV1u-f8Q7R?{y${0V_<`q=5GIggG+SZ|G$|67ZkS%NRM#K(Po)PoO>s8Jh!Hd9kuqL=P zh(xL#Af+UzhIq!L&A^1EhWN+?sv%td|He~Gyam@&t_)n@+5%BZzGwFO|B~7J{}*PT z|4*60CzFED=;CGuost;Hz{(uN0IIjRm_ry4HHa2;4(|^`;C@%_p7Y`|6#KE|BuP`|8FK2P|J^jg(>j=8A#p60P3AR z1K;Zlxo?w;*`0xh*^_~d+3WvDW^V>IW}p8*nf(~JnEe?*r-=zO2Qu)3&nXUOV1Sfo z3@prH|9>%PF+?)RKxHkfJIsdOfYaCF0532J(ZJU2gW(>U0p66R8oBw~I zJx>uP9|mr4`zG-J38oMRL2w(+`Ts{|m;W!BUH^ZD&K7-U_W1vi+4KKLX0QKGnZ5si zX7>62f!UWql-Z9#iP@h)i#dS7ggKBwi#dov0kTeyfsHwoL6SL)L6|`seD+b`|6dG| z3=H74BcQp_3*5v0%w+l> z@C8~=g3hM>1+EvstrpPzrT^bCdowUF`~3d}IiZ^Yv|0vqLN_Q}`4Hjy{~Pp-S_TFk zhJgQ|*gwEf_Wu(DDE7f882tYO?#Cf|v3yJh|KCAtbU}De){;Sx$@>34a32QLyLS2i zg(=|w7pB1fcbS60qY)pNLKzsCof(9fA-ApyF}pDcF}pL!GJ7!aLvAJdV;Q!AcDdGPI@M(e|7k^?1{Qrg_l7XKg|Nl(} z&>oh?|En3A{x4*h^M4nmqY2E;|93LG{NKy$`u{4k+yCRt?*ET7d;H(a?D>B$v)BK% z%-;WZGyDAC$n49&&FsejnkfgZAr@hV%pYdW(*FOJN%#LVaN7ku=J5X`liB}MOy>VjL3==Fm~8$(W3v5!n<;>S znJJKgl_?lB9s}+-N-)JT=%I~lOW+vU#y{7i!=(EEKa<-3|KJv;=KufTx(L)ug0wP) zz&%=n|96-`ElrdE|Dods|C!AH|7WuJ|DVZ{L4wKp|9>VM2013X|Noin|L8|#VNzvaW>RBdX3}6#V$x(_hPe3uFD4xZDd@P#O(r7- zC2$%xVPIx5Wl(^WWDLwq77WZxmJA9^)(p%L7lX&y5bb2hD9vZ4p#LA4Ag+GI6wbiR z6v4m@b+Ht*e=Euq$H2^##J~)7EjLpt12=<~M?Eimba{B*`$&G=N$@Bj=@Th_>11GqZ4{9p~GYBw+{{O%f&cMSI z!N3D`IRjH10}oRY0}oU3|36HKHq#sE7!;_72Wm5YXV67zp}c^%P{4gma4Q8=>oS0Q zeUQEfwwB6GXw7>EQu9JvbfB8U?f)Ne%MR4;^!@(_+)F~#!bjk>Flf{Q(x!sd#0*R+ z|35RO{{M_L#s%sPgKFZ>40=qe48lxm48lwr3|dT@41&;b2KAU^p)F$;CWHUan2Z>- zpeW$-v2E%fJF@K|*_Lp8sz`QwOML0ve6^ z25&urQwIY#)WyQ!9!fj|3sV9E3sWKk3$zsu>eXU~Ijpy0$fWxJ8ogbLO|9@kO0QI&0e_)CNh5i43 zOfd}n;1R9(|G$|M{{Lo5{QsLN>Hjxq>cJid#!RaJA2F%@f5fEz|1)?LPYX0Q@&7BN zeEI*4N$>x6CVlXz-a974|8KzM3}}?w?EfPs^Z$>)J!Px^ZHiB%W(>ki=Kq&4S^QtZWchy*lhywnOxFLGFxfB&Fxmd! z!DRP;36nhoFOw4kFOv&{0F&GQekM-_UM5JX+RqgDe-l&C|1C_x|K~u*+M1Zc|1V*R z_`ifH^8W#*sQ>qvqW@oKiur$?Dfa($rnvu0nBxEMU`qJEgDLU<4yL64OCa&}|0YxF z|C>x{|8Fv7{NKrx`9F;*>p!R``;5T~+*VIu5MoGV5MoIB{~xk{^#6bG{?S|p7KTCw zIfh~eUWQTzUPPOofuEs?!G@uYL5QK9L5QJ)L5TeJJ%b=PB|_TxpP6DA7(gkB*_lC} z*@Z!a*_A+n-!r*0urYc5zs%(O|2?=I z3G4Ob$9JD8d zt?wqqBBK_GQ}`3fa5rwL6#|tL7mx|!Gzg`!JgTb z!HL<8!IjyaL4?_Z!GzfpyaL;w*_*+T*@wZF=y-Nu2>AaI@2P{4|KBh~{eQp^{r>?& z%>NGzvHu@1#Qp!k5dZ%J(w!}D7?S^k_T|4}Nd5ndA?^PIhV=gr7;?e)7qBsu{r?5+ zfw3?&{r`@9p9{mB{~wqX85o#U7#NuB85o$H7#Nt`7#Nt`85o#685o#+85kgG;r~^p zAn@!TXs(WdDU5-EDIJvh|6gHtX5eRbWe|m|0ArA3hV;OAnZ3Y0FhOP?1_p2sEb#wF z=Ai%In1lbnVh)A&x*Wjc8TeQF-e8FO|C}NE|8s`e|Id+p4LXhBJ44EU&}jtU8Pfhg zXGs759G*6s{=Y!>DU;&=UtnKqFfc${4WO19XjBI>KV!rInvX@Dqp|=0i^=K#FDB4j zjXQXR@E4O0Xq52(FQ&l%dzpg%pM}lYfI|e*N?>40|NoaM>;GAz=5bsYK%+URH%!3p z1=-1v{C_V)%Kx1VssH!FZ|W^(`ko5}P4Pm~d(p#Lay3rt}QOiTzL|7Obi zzY9FJ3>!uA_>X(eA%KCE8Q18M8#qk_{{P1i`Tr$D)c-#W(f|K2#4s>0#Qy)o5XZp4 z5YNDXv`^s!L-PNR3@QIVFr@zf$dLB`4?{ZWhA#$AhHM5-hKB$D7#g9YPe}U_80P$c z!ld#4FEn&uX#q6e1L|u)=H<;8Si!3dtiYpDKbdU*|6{U)<_^fZg>Otj|DQ93g6ePv z25^fc{{J7Qg#Uk-694~UN`mK-=giLk|1rD&{{y}4=MS?N0|T=+=)?r@u3;W#KL*ep z7W~k&?|GPmKqn|Lfc7AP#(-Fu!x%UjJZZfLi2*cfpz!}Plj8rAOe+8XGO7Q6&!q7m zG+TR(N$dYXCT-B1HWXVr2qdiwEnrwWc2?nxVK>X|0R>z|NTtn|MxRl z{=dg$_5U1nmBl$GyZ`%{?Ejx+a{7Og3DPq=3F%M%{{x=c4FZomd}j(}U}g&Y|CcH9 z|3Rjx|F4;%|6gW`VNhX;WiVrk|9_4t;r}_N#Q*1*lK$^!%3@$;M&1MC1s=r-`j2PL z9D^J~6oVW?G=m&NEQ1_F0s|{UA_FT!5(6JYG6Oq93IiWQDg!%18iO1|I)fZT#{W0a zJuhzm09hH@8CV%Q7+4wR{QnLvV^sgYV^aJ7j!FIhZ*UsZ{QnNx z&VR?G^ZzfC?*A`L1`LpN23pZ#^8X!^>Hoh>=KtR@S^R&;1e$HP`u~H;`u{uV%=8Z? zJMio@6O-HjZ%n?Rkq!oCrr`fy!R1c)|94Cg|KBl1g4*`~|3X*cXfVb7f5#O6{|8gT z{~t_=|9>zg{eQ>o!NAGv`Tsw&F9RooAKtnr>Oa*^yk!85Q-Vrh)&GB))c*fv0+qs= zu-y0mFSu+n`2Uv)TnaNVFqyzs#xO82S^WPC4UxZ0)(i|xHvfNv$1p)T5mrKb!e`S# zt2`bv1^vGP9cKsieEu>;fYK5)hsOQ?%M}0rFH^$*zf6h$|AKRA*8dyKZs0jV;!b?^ z2bWPn3|tJs3|tH$3|tJM3|tIh3|tK13|tHm3|!Ds{WU}M|JMw$|6emC{C~!f`2QJ0 z(*F|-$^XwXr2Id@kox~DL)!n>4C()0L+dSO=&a{QhPMCD7~20oW9az*jA73IXH1wS zIukh5U^Bv~B|2!#|24R*qNG#@mtX&3B|GXI0b~}Hy!n9u$jvSPKQILU|G*IP{{utl z{|^jd|35H<|Np=c@&5yOj63T87l!EnUl?Nle_=>qU|~pPU|~pNU|~pRU|~pMU|~pQ zU|~r6|AiqPv_|Vc=$u^WxHtm?LmLANLpuWtLk9y3lL`YDlj{FJOltrCFljLGFlqk( z!=we8Q~v**NrwU2QvCmi$q2kc>^GCi|36Hi`DNI;Dhtq@1Oo?jM4Fq)?*Bg~HwJbl zUj}yYTyxO>>rBB6yr4C5OkoUMOyU3kFh%_T!xZ`d7gH2yRu@zg{Qt+4_5V6_6qSwH zl>szjEyC>1AkXZIR~;QybYqt&35V80lGsCAwW z!yE=~CWZgMm=ynCVNzjWV^aP9nMv*cXD0RkznC-__?a~Se`eD9|A|Ta|3@Yr23~Nx zTJQfaCVlYguIo&O|9>$VfmY`I2Zh{cCQ}ApCbR#a!Q&Jb|35QXGVn54|NqKl!@$L4 z_x~$=gbOq`4jNH(2emZ+UjetPAft+3n1cR)fzFe^VG3nnWeQ_pV+#NOnJMD`XQs&i zpO~T;c$uRA|6+>y|BEU1KWKI1XQrh8U!g71FW@-=V$XyLV<4Q1A2LM$f5;FEx+n4f zLx#lv4;hmFgYJ^K1iecJbhqe3hV=gr8PMBiu-Un`{|_13|375t`2Ub$&i{KTxmgq5 zBE{cEvjUfWufQv!@aO6WOhNx|LFUT-gVurEMro_XGO#ekGcYhEFfcGBf?6ox9Da-0 z`Tu9sSwL`W1=fc9#q15*$@l*gbQTb@b_8ELE|MXTfrY?Hvbz|f{y$@g{{M_2_Wv`6 zg#RBH690c-fSe@z0(z3{3x>4+&luAGKV!&bU}4B+U|}fx|AwJ~frX(Fe2&RehPMA7 z7~21TVCeY&fdRByMDhP8aO+oOu7uh;B{w444lxh zdln{B1~%x}JqwcsXdN8`8;D^QDFIri#0V`R z?mH4m;Q!~CL;n9_ z4*ma_8B|ZjF$Dbo2T9-me=!9A|HTmU{})5(|6dHCS>^EmzZfDwGqwLgyHxKmME}17 z?Z4bX^j{cw84?+I86f96ibKzJ6lX~Le}^Ic{~hoNDxmexkoi+yhDHWih9+>$#>>#o zz{}9Vzzd#BRs8>rNrgd_NtJI<1|~yr%l{d8Evm`?>rAHq-$U0%UuUua zuMd8~WcB|AbdB&MCR@-v-2dx{@tOZGAY(KCUx3GEg2C(Delmsq|H>5p|2k8||LaVV z|L-wH{r?83B^lV5Vi~xZ;{IP}ivRzDDdGPMro{g*n3BNl5oTr=@CtL{&hblN2>Ab% zA&`NAA?W`bhT#8i7()KPVE~=*7xw=RL-_wU3=yCi^#8Bmw=hBa?JtnhJ**|i3~k9V zLtAo?8<{|7nL^V2Ge{ZFz{$|`{||DD4w~-&KwEa-nbiJ&XVPF0gtk?FFlmElBS38x zR`7~JBL+cm&(s9G?|_}j?EeoYbI@AV|Dcr-pqAY)CL0DmCcFPXne6}nVRHHpDsi}> zY5fnAFKB(oe^Ac?RJPxSwoN`mTYKM`BL078iv0fr+%Adx|D7r6|4(RJyj|8FsA{eR4){r@48&i{8zy8j4A4xurL|@ zzX_csxxr-m|2dP{|KCjJ|8Fo^{J+6u`Tr)9)&HAJ*8guX+5Er4Wc&XnlimLt@N^B@ zf#LT5F*t35X2yO0KV}L5hx$9n3^{mx`46VB|KFIx|KDMX_SnqW^zp zieX@3ie(UHiu-?qDgOUWriA}DnG*lsWJ>yf12j9%?EL=&v&;XF%&z}`F}wW--2r=p z+2j8kX3zhRn7#i$gRI5@ts4U0y$rfdl!-a;{~zcr^xv67{y&DSZ~6a$Asu>d`45Jm z|M+&T{%45#|CJ&7|5t|C|6h@MF|3fe3kFv3+(p{|uMFw`zrtIOh5vs+`h)*}LC3CM zA*X*Ph5vt<6dBmi#u`AqYE~x1Si@r`@Orxc|Csdt|7Ftu|Ch<&|34-}a4(w`ycY&M z?f}|5@&7Ag?16!a2{N|`s*RbTbBphp>>1dYoEX@cz_A2svoo+EjSk;|_qf3`1^<6z zj!Q7GFhzsLCjS3riv9l=IyUheY2NWY6Q~ys+VA4Z0IHRFnBBp*We75R{r|@7&A`X( z`~M@e9|HrkKLd1U{r|7bklxW-Xzl!oIqd&eh8*y|oxuN38G`;FX9)g(oFU}@afZvf1DxW|8ek{w=w_!AnlSAU`S>VWJqBUU`S;UWXSygk|F#5OYq4i#SEMb zr3|3;w~`DE|KBh)GVn4qG3X)hj%1kg|1p!o|KCiC;65j)Cv}ZU?f*3<&>CHh|KFH2 z|36@Y%$0tGjsksR()<5`N&o+ECIbd`Cd2=~nT-B_gVfOfuYuQhgVz`Szrtkk{~D9! z|F29||L-$d|G&lr-Wl=#K9k-5t4#I`EKE)eEYNwm50H5r@ID41Cg1-bm;xAtm;xDO znSvNZ!K->gKEivItBDTcv-DVD*JDenI@ruhH&nG*ir zXG;8kpDF48Rq*^x7K13WGXpoX3xfo+D}yw%8-p~n`~P3e9t?uao(v4kUJM${-VEH# zJ`7UeaeqJXdNE<<00z){F$TzbvH#zgL;k;mtSkQil_8fQ;Qup*K+tT+{}&9w|6eeK z{C~j^`u_z(*#8#{;s0MSMErlj5Xqp#5cU5!L-haS44{~cWnf^4`~Qa_9u$lJ|1c!} z{{xv9{0};r^FKrC|NjhW|Bo|(WH*|2dP+|A)}J>ok-8|I^SF7pIww{=b6e!Ocvj|L-!H{ol-F{(m!*#sAGrmj7=s zS^Yo4Wc`0DbWHmQlimNVO!of|GCBP}$mI6_Gn4!OUre6=4>I}w|I8G~z|Rx}9;yAn z6b4!&^?x%{#Q)7qk^i?aMg4!s6#f4+bX?n*DenJfruhFym=gXUVM_denkni3R;Kj- zznHQZn3=$p6jEq5n59hyCBqPyp>UzG4Xaf0`lq|7nJh|EC#3|DR?E z`+u4t{Qqf&i2tVza{ed-17iN=|1XB@ z|GyY=85kJK{{LryoD21rp^1SDxmO7(H9@WE|9`+U4)E3ns4w&X9kez51iX(EybI|6 zPbR(pKOp(2{r|%pz`($axO0qw8FEtMFXpiSuNexVCw;wO2>O4X zA^87!hLHc~8AAV`X9)X$o+14Id4`Dp=ON>$47?1{47`vYC<8B|CH{XJL*oBw3`zfc z7?S@_Vo3Sl!;t!a51 z@Bc^0SOJ4DWUS!-NoecjIg{!Cr{G<4=CBg<|1Ku0{|}k0|G$K`As;f?{eKDHn*dpx za)Sx96!ZThQ|$kb z(9-iEQ^Nm;Oo{&=G9~?g$&~ef4zu(BRm?8`4=}s_KhNy;|2(t%|AWjP{|_>I{$CGW z!@CB$hF5~wk3odlpFxQ^fI%I)s#_d-+7;*=U}5l#UJ*mU|6dHCxy~R4MuuPpMurdu zMut!ZMusp3Muu<(MurFmM(F7$j~Sx>KW2#e|BE5^|6>Nwj_&yXzZeq!e`QGg|CJ%> z|9ghy|8E&m{=a8P{r{FB?f+wj^#70HZOU9wz4!kQL-GGV45k17FqHlO2sx4Z{~v~? z|6du}{(og?|NoVt(>5(_c|K>{|A}L`Tv*6v4qgHF4?L=F z|NkA66KJ06|1aqH8faI}J0_q1zoFx6pxs@snS%abWdiSB{QsIM^#2cNOXeR_#Q%TL zei#E&G-!PrXb<)Oe@t=z|1rh?|HqW@{~uH0|9?zL|NlYf=s`Q={y^vH8Ik5^zcYhZ zFZ}-lJ=K{JeE*+612g0{TBKe<=>I>=VGL{xpqTv15cnT-wm80d4Ho!~v@!p`F+f@{ z-x%Wme?z*h4b(f}XGj6}4*21>(}M0;0PV1btaQ>wTIs~Y&;af!fZC+$$ae%X%=!NY zsZ9zRxBI}P_WuKPX7U%4CTM-Y|JO{~|9>#){QnK!-ws*72WpctL))aFbw!|<`~Yo} zvM`zd|G;GN{{ys53MyScFhSa+pwjgNYMT^1W6sOu32u|}LVFFMz28zyK@8$dkp17h zOrhX5DQJz+2d0SsADANlzh;X1|CnfmcfQ8?*9k0()9yVIs-3L7K1pmGXpQP z3xhPXD}yAn8v|$^3NJJGd~R_4$jj`*APDV2upspyKyxb}p}mLC;NAlh!yC|v5{wFr zT?||d+zc4t{}-6h|79>11H=C<5H>>W|D6A`8TcWh#E}30U{m$~J52QdS{RFg;s37x zUl|zw-(X<)zxMwNnE3xy{~s_g{D1R*9mwAQ-~a#lzwG}81}>2N|BwGaLRbt8|L^>N z2U5Yn#K6H2#1O&2z!1d{&A`qO%Mi=J$&kR1&A-7>#E`&{$iT>u1ijG#GJg)a)gcu;hn~*B#E`*|!N9_h$&ksw%8Am0^7~b zkj#+Gz`>Bhkix*ukjjwCz`>Blkj}siwwo1fHyhY)R)%bbYz8*4eN15cxWM*tGBC1; zfMT9Oharg}gW(Ws3J5afF_eHXm_3QHjiHKR8N)AzUkq~??l3ekw6WY^-N%@~WW=zA zQHJRRO9;y}rhm)}SmhWuFy3P5VK!m3V`5>>V!p+c!ZeM6kxB9YUoiQGfsrBa|6DNH z&A`Z{z`zC;KLRHAfk*}s1}1RZDwTl&#QML5A@%Y5$iU0M&XDkbB}3x>l?=)M7civ$U%=4z zeo^n|9`_A!l1z%%D~AS#vs7J!BD}#$xsQ3 zoBv0dUH*SzcKiQ>*#kUN@f);~g@J=fk%0@N-2&b{%D@2LV*_eUB5tQl`wzZ_l1cIZ zerA{df51D>y#D`U;9`jS-^&pFzn3BQe=kE41E^On1nrdzF{J(PWk~RzyBYh<7=Rio$rvDRq*&4 zs9p7ofg4^vgUaSKxS626IFQy@Fmw+Y$Xp(V3I<7rN(M<#=tD=Co-sqt!33@K`OfV5 z{{wUn9q5LD*9<&3%m;D8M|Nk)ufn50i4|B-> ze~|Gr1_qqE#KB{ruy!xlU;qCwhcYlRhyDMHKx=T&ee(anI&U&W|G&u)`~N0G+W(sj>HlvsDgOTk z-sK#?zzG@Y1MhhL!wlKW2uiao3``7M3<2N~??{Gd21uF5%87^460Vu<~}iy`g*E{62~yO>@7{|1-$ zyBHGx?_x;$zl$N||1O5M|GOC4|Lf}G6*q9FfcMOGOuD_WME*hVBlu3V6bCwVen$G149tYi@}S5k%60m zm4Tl@oI#UOlTn*dhcSxr6yq7jvmkv;PZ$`PdO;*(2$)P`W?*1s%mA?&c$i!m7#Wlp zjxd1kt(wccl7WGF1M?mRUgk5*HyNZDG#D6|m(U5XVqjn<9q(s;!~BWGg!vycABz|> zAIlErFcu9K8J0CHO3Wh687!Mv1em3m6QowwI%#)ZcnC)1muv}o?!~6zh1M?@AWnf$WvFu}ZVfJDU zU=CvrW07Hw0old;k7W(Z8s;RheVbSWSOl2!nDbclSln3LSdOqXvG}m~utcy#u)JU{ zVXk7i!*T~?D{}+$36QYVCrV-Wtzk^lW8{79H#k93z!x$EoNHEw32BR z(`u%*OzW7|Gi_kn%(RthC(~i3M@)~IzB2t``peA1EXu6Rtir6vY{qQCY{hH`&f_v* zau)+5qc)Qa10$minA8N5tH7ipm~3DIsi^~#%^;FV5JWQU0?9J$1(A%tAd=w;sC;0G z1hE-Efk|dC=>aAefpjr$0g((3K_ug15XqDVA{pm_$ys314Xi#HL^2!#k&J#|awV9| z0jrq`CO3k~onZ1Mm@EU6XTaoRFzExU~&@J{1z~o2qtSlB$FwKWQ6!@J(ztTOs)Zw^xL51lR10#bTYXPE` zU<8d?F*2_Qr2&o_21W*E<~7V~nb$EeGca)Ez%diJPGMqTU|?flV_;(7Vc=n4W{_Zz zU|?a8V~}HDWl&;JVqgQ;r0fhv3`Ptb3`ZEwFmN)QV|dIU#PF2iBZCIRA4XONQ$}`1 z9tL|x2}W54S4Me8MFww1WkzKNKgL+bGzNdh48}}`NX7!jVuonOCdMv?c*Y*a84MYW ziy7B2lrpYk+{{qVxSR0^Lo4Gk#$ycqjK7&!7$z{WF|jkuV&Y>GWSGOG#-zrufXSZ8 zo?#)AGm|sJA|`hxcZS7G5lj&bOF(&yVJTA@Q#!+PP#$Ag$yCZz%CMTLim94m4bx1f znGEZg<}=M_SkJVd=@7#Prjtyk8MZK8WxCF=o#{K%4~AXLOw7y-dziVHc^LLFi!zHc z9Avg&wq!WOaD+XGJ%T-sJ&Qesy^Otvy@}m{J%|Jt!A?AkW5*8**fC)WJAPQkPCTq( z#}Av>u|WrR{4fX_ZXnu?-G{vi8loU~gF+M(nxHU(_#Gsg!k)!m0CqRTJz!fIm>9Ad z7#Y|Y7#O%2co^6i_!xv3I2c43bQyRV^cl<<)EJI1oM6yrIK^;=!Gz%)!$k&jhRY1s z7_1p?Fx+RbXL!i)n8BUlDZ>i}FNRkPZyEd;-ZOk<2x9oo$jA`M$jr#fkiy8$$ia}# z$i>LZkjW^v|ItIUl=MGbr^LRY8dqx^%-gz4H=CX>KRQKEf^XZtr(pc z+8A9J-5L5BJsJHNCNl;w1~SZK3}y^wn9Uf$7|Ae)F_tlrVIE^LV;aL^#tg=6hUJX8 zj8zP)8EY8Z72BL_zKQ9KNwFio?!UNc#82f!!O3OjAt4CFrH_;!0?yx z65}O?|BP1{Z!j`2-eP>j$jbPH@i`+O<4eYOj6#eb7(X&fFn(tI%qYe9jqy99G~;i^ z|BSLsj7%(yN=$4_oQ!Hr+)Uz(T1=8m@{H!7yvS(BWWr>^Xb-CU7#*0LnOqs2Ky@FZ zE2#EkbZ7Eq@@4d7@@MjA^a9m`jNVKkOd*WEp!~|{#}vmD$LP) z^^BQJo0&E<<}mGNI?R|0%HNDdp#05P%Jh)wF=GYOOQtuB)l6TRzB1N>ay(-LsP1HJ zVrF7yVQc~Ad&YK9zGv)WR$^9R>}J+u)?@5rHe)tp><87Vj1!pcnC%!RGfrU%V_Cvn z!6L<6$CAX-#?rvDgt?1FfhB+?k9iJD74r&~43;Y9bu4NuCCpn`Cb8(SxG?Wxna5(s ze2m3{WdqAL=5NerSd3UKn2T8KnD4QyV)0^r#nQ(7fhB-t3Ck*$FrwfR7GhuwOALz? z1Txn#*D<%SB;kQQENx)_G_at~Gc^C5m<^wGA@W4IH$H4FsIEFT`pu=s< zXF!m}0tA_haKKBv!el=%gCR;BgUkS>jy!Oh zn#ZyVwz2F1 zwLKU>{mOa}$s`IQ85=+(6R7XX$aoFJX7m7)A3-F;F)(=?M1sy9Wng5y31Ty( zf=2Bb86obJ0EM?v4YrXHG%m@=@DeOi4I&v%g2`VXk}(WS zs)9%c2wN7+ehMN%fx*DY2x^5fGNyw>7~X@)|6uYth-8cckqn2xWCfV~2PTh#NJh|{ f1|#DwFdJkXBg0n^o8dE=Dm|k literal 0 HcmV?d00001 diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index ea71a584f8..6a8b75fe38 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -20,7 +20,10 @@ use settings::{Settings, SettingsStore}; use settings_ui::SettingsUiFeatureFlag; use std::sync::Arc; use theme::{Theme, ThemeRegistry, ThemeSettings}; -use ui::{KeybindingHint, ListItem, Ring, ToggleState, Vector, VectorName, prelude::*}; +use ui::{ + CheckboxWithLabel, ContentGroup, KeybindingHint, ListItem, Ring, ToggleState, Vector, + VectorName, prelude::*, +}; use util::ResultExt; use vim_mode_setting::VimModeSetting; use welcome::BaseKeymap; @@ -1124,38 +1127,32 @@ impl OnboardingUI { v_flex() .h_full() .w_full() - .items_center() - .justify_center() .gap_4() .child( - Label::new("AI Assistant Setup") - .size(LabelSize::Large) - .color(Color::Default), + h_flex() + .justify_start() + .child( + CheckboxWithLabel::new( + "disable_ai", + Label::new("Enable AI Features"), + ToggleState::Selected, + |_, _, cx| todo!("implement ai toggle"), + ))) + .child( + v_container() + .p_3() + .child(Label::new("We don't use your code to train AI models").weight(FontWeight::MEDIUM)) + .child(Label::new("You choose which providers you enable, and they have their own privacy policies.") + .size(LabelSize::Small).color(Color::Muted)) + .child(Label::new("Read more about our privacy practices in our Privacy Policy.") + .size(LabelSize::Small).color(Color::Muted)) ) .child( - v_flex() - .gap_2() - .mt_4() - .child( - Button::new("configure_ai", "Configure AI Provider") - .style(ButtonStyle::Filled) - .when(is_page_focused && focused_item == 0, |this| { - this.color(Color::Accent) - }) - .on_click(cx.listener(|_, _, _, cx| { - cx.notify(); - })), - ) - .child( - Button::new("try_ai_chat", "Try AI Chat") - .style(ButtonStyle::Filled) - .when(is_page_focused && focused_item == 1, |this| { - this.color(Color::Accent) - }) - .on_click(cx.listener(|_, _, _, cx| { - cx.notify(); - })), - ), + h_flex() + .h(px(32.)) + .w_full() + .justify_between() + .child(Label::new("Choose your AI Providers")), ) .into_any_element() } diff --git a/crates/ui/src/components/ring.rs b/crates/ui/src/components/ring.rs index 59047d2d6d..22081d03df 100644 --- a/crates/ui/src/components/ring.rs +++ b/crates/ui/src/components/ring.rs @@ -41,7 +41,7 @@ impl Ring { } impl RenderOnce for Ring { - fn render(self, window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement { + fn render(self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement { let border_color = if self.focused && self.active { cx.theme().colors().border_focused.opacity(0.48) } else if self.focused { From bdabdbbf91482fe3ebbd22eb87cd40ebdb7a182c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Thu, 3 Jul 2025 15:19:18 -0400 Subject: [PATCH 22/29] Use existing welcome page --- crates/onboarding_ui/src/onboarding_ui.rs | 61 +++++++++++------------ 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 6a8b75fe38..01b8770e51 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -26,7 +26,7 @@ use ui::{ }; use util::ResultExt; use vim_mode_setting::VimModeSetting; -use welcome::BaseKeymap; +use welcome::{BaseKeymap, WelcomePage}; use workspace::{ Workspace, WorkspaceId, item::{Item, ItemEvent, SerializableItem}, @@ -144,6 +144,7 @@ pub struct OnboardingUI { workspace: WeakEntity, workspace_id: Option, client: Arc, + welcome_page: Option>, } impl OnboardingUI {} @@ -225,6 +226,7 @@ impl OnboardingUI { workspace: workspace.weak_handle(), workspace_id: workspace.database_id(), client, + welcome_page: None, } } @@ -1158,39 +1160,32 @@ impl OnboardingUI { } fn render_welcome_page(&mut self, cx: &mut Context) -> AnyElement { - let page_index = 3; // Welcome page index - let focused_item = self.page_focus[page_index].0; - let is_page_focused = self.focus_area == FocusArea::PageContent; + // Lazy-initialize the welcome page if needed + if self.welcome_page.is_none() { + if let Some(workspace) = self.workspace.upgrade() { + let _ = workspace.update(cx, |workspace, cx| { + self.welcome_page = Some(WelcomePage::new(workspace, cx)); + }); + } + } - v_flex() - .h_full() - .w_full() - .items_center() - .justify_center() - .gap_4() - .child( - Label::new("Welcome to Zed!") - .size(LabelSize::Large) - .color(Color::Default), - ) - .child( - Label::new("You're all set up and ready to code") - .size(LabelSize::Default) - .color(Color::Muted), - ) - .child( - Button::new("finish_onboarding", "Start Coding!") - .style(ButtonStyle::Filled) - .size(ButtonSize::Large) - .when(is_page_focused && focused_item == 0, |this| { - this.color(Color::Accent) - }) - .on_click(cx.listener(|_, _, _, cx| { - // TODO: Close onboarding and start coding - cx.notify(); - })), - ) - .into_any_element() + // Render the welcome page if it exists, otherwise show a fallback + if let Some(welcome_page) = &self.welcome_page { + welcome_page.clone().into_any_element() + } else { + // Fallback UI if we couldn't create the welcome page + v_flex() + .h_full() + .w_full() + .items_center() + .justify_center() + .child( + Label::new("Unable to load welcome page") + .size(LabelSize::Default) + .color(Color::Error), + ) + .into_any_element() + } } } From e32e1baf5f6b3f83ba110948ee4c569ce98188fe Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 4 Jul 2025 19:52:55 -0400 Subject: [PATCH 23/29] Add SelectableTile --- Cargo.lock | 1 + crates/onboarding_ui/Cargo.toml | 1 + crates/onboarding_ui/src/components/mod.rs | 1 + .../src/components/selectable_tile.rs | 170 ++++++++++++++++++ crates/onboarding_ui/src/onboarding_ui.rs | 1 + 5 files changed, 174 insertions(+) create mode 100644 crates/onboarding_ui/src/components/mod.rs create mode 100644 crates/onboarding_ui/src/components/selectable_tile.rs diff --git a/Cargo.lock b/Cargo.lock index 011f970283..addc8d2d8c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10831,6 +10831,7 @@ dependencies = [ "serde_json", "settings", "settings_ui", + "smallvec", "theme", "ui", "util", diff --git a/crates/onboarding_ui/Cargo.toml b/crates/onboarding_ui/Cargo.toml index 61ee08fc2e..fc903dbaff 100644 --- a/crates/onboarding_ui/Cargo.toml +++ b/crates/onboarding_ui/Cargo.toml @@ -34,6 +34,7 @@ util.workspace = true vim_mode_setting.workspace = true workspace.workspace = true zed_actions.workspace = true +smallvec.workspace = true [dev-dependencies] editor = { workspace = true, features = ["test-support"] } diff --git a/crates/onboarding_ui/src/components/mod.rs b/crates/onboarding_ui/src/components/mod.rs new file mode 100644 index 0000000000..707b2d2ea4 --- /dev/null +++ b/crates/onboarding_ui/src/components/mod.rs @@ -0,0 +1 @@ +mod selectable_tile; diff --git a/crates/onboarding_ui/src/components/selectable_tile.rs b/crates/onboarding_ui/src/components/selectable_tile.rs new file mode 100644 index 0000000000..6c58c806af --- /dev/null +++ b/crates/onboarding_ui/src/components/selectable_tile.rs @@ -0,0 +1,170 @@ +use component::{example_group_with_title, single_example}; +use gpui::{ClickEvent, transparent_black}; +use smallvec::SmallVec; +use ui::{prelude::*, utils::CornerSolver}; + +#[derive(IntoElement, RegisterComponent)] +pub struct SelectableTile { + id: ElementId, + width: DefiniteLength, + height: DefiniteLength, + parent_focused: bool, + selected: bool, + children: SmallVec<[AnyElement; 2]>, + on_click: Option>, +} + +impl SelectableTile { + pub fn new(id: impl Into) -> Self { + Self { + id: id.into(), + width: px(120.).into(), + height: px(120.).into(), + parent_focused: false, + selected: false, + children: SmallVec::new(), + on_click: None, + } + } + + pub fn w(mut self, width: impl Into) -> Self { + self.width = width.into(); + self + } + + pub fn h(mut self, height: impl Into) -> Self { + self.height = height.into(); + self + } + + pub fn parent_focused(mut self, focused: bool) -> Self { + self.parent_focused = focused; + self + } + + pub fn selected(mut self, selected: bool) -> Self { + self.selected = selected; + self + } + + pub fn on_click( + mut self, + handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static, + ) -> Self { + self.on_click = Some(Box::new(handler)); + self + } +} + +impl RenderOnce for SelectableTile { + fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement { + let ring_corner_radius = px(8.); + let ring_width = px(1.); + let padding = px(2.); + let content_border_width = px(0.); + let content_border_radius = CornerSolver::child_radius( + ring_corner_radius, + ring_width, + padding, + content_border_width, + ); + + let mut element = h_flex() + .id(self.id) + .w(self.width) + .h(self.height) + .overflow_hidden() + .rounded(ring_corner_radius) + .border(ring_width) + .border_color(if self.selected && self.parent_focused { + cx.theme().colors().border + } else if self.selected { + cx.theme().status().info + } else { + transparent_black() + }) + .p(padding) + .child( + h_flex() + .size_full() + .rounded(content_border_radius) + .items_center() + .justify_center() + .shadow_hairline() + .bg(cx.theme().colors().surface_background) + .children(self.children), + ); + + if let Some(on_click) = self.on_click { + element = element.on_click(move |event, window, cx| { + on_click(event, window, cx); + }); + } + + element + } +} + +impl ParentElement for SelectableTile { + fn extend(&mut self, elements: impl IntoIterator) { + self.children.extend(elements) + } +} + +impl Component for SelectableTile { + fn scope() -> ComponentScope { + ComponentScope::Layout + } + + fn preview(_window: &mut Window, _cx: &mut App) -> Option { + let states = example_group_with_title( + "SelectableTile States", + vec![ + single_example( + "Default", + SelectableTile::new("default") + .w(px(120.)) + .h(px(120.)) + .parent_focused(false) + .selected(false) + .child( + div() + .p_4() + .child(Icon::new(IconName::Check).size(IconSize::Medium)), + ) + .into_any_element(), + ), + single_example( + "Selected", + SelectableTile::new("selected") + .w(px(120.)) + .h(px(120.)) + .parent_focused(false) + .selected(true) + .child( + div() + .p_4() + .child(Icon::new(IconName::Check).size(IconSize::Medium)), + ) + .into_any_element(), + ), + single_example( + "Selected & Parent Focused", + SelectableTile::new("selected_focused") + .w(px(120.)) + .h(px(120.)) + .parent_focused(true) + .selected(true) + .child( + div() + .p_4() + .child(Icon::new(IconName::Check).size(IconSize::Medium)), + ) + .into_any_element(), + ), + ], + ); + + Some(v_flex().p_4().gap_4().child(states).into_any_element()) + } +} diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 01b8770e51..0a8b23255c 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -1,4 +1,5 @@ #![allow(unused, dead_code)] +mod components; mod juicy_button; mod persistence; mod theme_preview; From 6e6e6d86c3243914b7444d51e41f20cf59514adc Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 4 Jul 2025 20:00:55 -0400 Subject: [PATCH 24/29] Update selectable_tile.rs --- .../src/components/selectable_tile.rs | 101 +++++++++--------- 1 file changed, 48 insertions(+), 53 deletions(-) diff --git a/crates/onboarding_ui/src/components/selectable_tile.rs b/crates/onboarding_ui/src/components/selectable_tile.rs index 6c58c806af..b33b186270 100644 --- a/crates/onboarding_ui/src/components/selectable_tile.rs +++ b/crates/onboarding_ui/src/components/selectable_tile.rs @@ -1,7 +1,7 @@ use component::{example_group_with_title, single_example}; use gpui::{ClickEvent, transparent_black}; use smallvec::SmallVec; -use ui::{prelude::*, utils::CornerSolver}; +use ui::{Vector, VectorName, prelude::*, utils::CornerSolver}; #[derive(IntoElement, RegisterComponent)] pub struct SelectableTile { @@ -15,11 +15,15 @@ pub struct SelectableTile { } impl SelectableTile { - pub fn new(id: impl Into) -> Self { + pub fn new( + id: impl Into, + width: impl Into, + height: impl Into, + ) -> Self { Self { id: id.into(), - width: px(120.).into(), - height: px(120.).into(), + width: width.into(), + height: height.into(), parent_focused: false, selected: false, children: SmallVec::new(), @@ -77,9 +81,9 @@ impl RenderOnce for SelectableTile { .rounded(ring_corner_radius) .border(ring_width) .border_color(if self.selected && self.parent_focused { - cx.theme().colors().border - } else if self.selected { cx.theme().status().info + } else if self.selected { + cx.theme().colors().border } else { transparent_black() }) @@ -117,53 +121,44 @@ impl Component for SelectableTile { } fn preview(_window: &mut Window, _cx: &mut App) -> Option { - let states = example_group_with_title( - "SelectableTile States", - vec![ - single_example( - "Default", - SelectableTile::new("default") - .w(px(120.)) - .h(px(120.)) - .parent_focused(false) - .selected(false) - .child( - div() - .p_4() - .child(Icon::new(IconName::Check).size(IconSize::Medium)), - ) - .into_any_element(), - ), - single_example( - "Selected", - SelectableTile::new("selected") - .w(px(120.)) - .h(px(120.)) - .parent_focused(false) - .selected(true) - .child( - div() - .p_4() - .child(Icon::new(IconName::Check).size(IconSize::Medium)), - ) - .into_any_element(), - ), - single_example( - "Selected & Parent Focused", - SelectableTile::new("selected_focused") - .w(px(120.)) - .h(px(120.)) - .parent_focused(true) - .selected(true) - .child( - div() - .p_4() - .child(Icon::new(IconName::Check).size(IconSize::Medium)), - ) - .into_any_element(), - ), - ], - ); + let states = example_group(vec![ + single_example( + "Default", + SelectableTile::new("default", px(40.), px(40.)) + .parent_focused(false) + .selected(false) + .child(div().p_4().child(Vector::new( + VectorName::ZedLogo, + rems(18. / 16.), + rems(18. / 16.), + ))) + .into_any_element(), + ), + single_example( + "Selected", + SelectableTile::new("selected", px(40.), px(40.)) + .parent_focused(false) + .selected(true) + .child(div().p_4().child(Vector::new( + VectorName::ZedLogo, + rems(18. / 16.), + rems(18. / 16.), + ))) + .into_any_element(), + ), + single_example( + "Selected & Parent Focused", + SelectableTile::new("selected_focused", px(40.), px(40.)) + .parent_focused(true) + .selected(true) + .child(div().p_4().child(Vector::new( + VectorName::ZedLogo, + rems(18. / 16.), + rems(18. / 16.), + ))) + .into_any_element(), + ), + ]); Some(v_flex().p_4().gap_4().child(states).into_any_element()) } From ffb557c2d96e94c9d8506d3d4b2491b82b61224e Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 4 Jul 2025 21:38:49 -0400 Subject: [PATCH 25/29] Add additional row components --- .../src/components/callout_row.rs | 86 +++++++++++ .../src/components/checkbox_row.rs | 134 ++++++++++++++++++ .../src/components/header_row.rs | 78 ++++++++++ crates/onboarding_ui/src/components/mod.rs | 4 + .../src/components/selectable_tile_row.rs | 124 ++++++++++++++++ 5 files changed, 426 insertions(+) create mode 100644 crates/onboarding_ui/src/components/callout_row.rs create mode 100644 crates/onboarding_ui/src/components/checkbox_row.rs create mode 100644 crates/onboarding_ui/src/components/header_row.rs create mode 100644 crates/onboarding_ui/src/components/selectable_tile_row.rs diff --git a/crates/onboarding_ui/src/components/callout_row.rs b/crates/onboarding_ui/src/components/callout_row.rs new file mode 100644 index 0000000000..2d7f600c0e --- /dev/null +++ b/crates/onboarding_ui/src/components/callout_row.rs @@ -0,0 +1,86 @@ +use component::{example_group_with_title, single_example}; +use gpui::{AnyElement, App, IntoElement, RenderOnce, Window}; +use smallvec::SmallVec; +use ui::{Label, prelude::*}; + +#[derive(IntoElement, RegisterComponent)] +pub struct CalloutRow { + title: SharedString, + lines: SmallVec<[SharedString; 4]>, +} + +impl CalloutRow { + pub fn new(title: impl Into) -> Self { + Self { + title: title.into(), + lines: SmallVec::new(), + } + } + + pub fn line(mut self, line: impl Into) -> Self { + self.lines.push(line.into()); + self + } +} + +impl RenderOnce for CalloutRow { + fn render(self, _window: &mut Window, cx: &mut App) -> impl IntoElement { + div().px_2().child( + v_flex() + .p_3() + .gap_1() + .bg(cx.theme().colors().surface_background) + .border_1() + .border_color(cx.theme().colors().border_variant) + .rounded_md() + .child(Label::new(self.title).weight(gpui::FontWeight::MEDIUM)) + .children( + self.lines + .into_iter() + .map(|line| Label::new(line).size(LabelSize::Small).color(Color::Muted)), + ), + ) + } +} + +impl Component for CalloutRow { + fn scope() -> ComponentScope { + ComponentScope::Layout + } + + fn sort_name() -> &'static str { + "RowCallout" + } + + fn preview(_window: &mut Window, _cx: &mut App) -> Option { + let examples = example_group_with_title( + "CalloutRow Examples", + vec![ + single_example( + "Privacy Notice", + CalloutRow::new("We don't use your code to train AI models") + .line("You choose which providers you enable, and they have their own privacy policies.") + .line("Read more about our privacy practices in our Privacy Policy.") + .into_any_element(), + ), + single_example( + "Single Line", + CalloutRow::new("Important Notice") + .line("This is a single line of information.") + .into_any_element(), + ), + single_example( + "Multi Line", + CalloutRow::new("Getting Started") + .line("Welcome to Zed! Here are some things to know:") + .line("• Use Cmd+P to quickly open files") + .line("• Use Cmd+Shift+P to access the command palette") + .line("• Check out the documentation for more tips") + .into_any_element(), + ), + ], + ); + + Some(v_flex().p_4().gap_4().child(examples).into_any_element()) + } +} diff --git a/crates/onboarding_ui/src/components/checkbox_row.rs b/crates/onboarding_ui/src/components/checkbox_row.rs new file mode 100644 index 0000000000..a2e0957335 --- /dev/null +++ b/crates/onboarding_ui/src/components/checkbox_row.rs @@ -0,0 +1,134 @@ +use component::{example_group_with_title, single_example}; +use gpui::StatefulInteractiveElement as _; +use gpui::{AnyElement, App, ClickEvent, IntoElement, RenderOnce, Window}; +use ui::prelude::*; + +#[derive(IntoElement, RegisterComponent)] +pub struct CheckboxRow { + label: SharedString, + description: Option, + checked: bool, + on_click: Option>, +} + +impl CheckboxRow { + pub fn new(label: impl Into) -> Self { + Self { + label: label.into(), + description: None, + checked: false, + on_click: None, + } + } + + pub fn description(mut self, description: impl Into) -> Self { + self.description = Some(description.into()); + self + } + + pub fn checked(mut self, checked: bool) -> Self { + self.checked = checked; + self + } + + pub fn on_click(mut self, handler: impl Fn(&mut Window, &mut App) + 'static) -> Self { + self.on_click = Some(Box::new(handler)); + self + } +} + +impl RenderOnce for CheckboxRow { + fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement { + let checked = self.checked; + let on_click = self.on_click; + + let checkbox = gpui::div() + .w_4() + .h_4() + .rounded_sm() + .border_1() + .border_color(cx.theme().colors().border) + .when(checked, |this| { + this.bg(cx.theme().colors().element_selected) + .border_color(cx.theme().colors().border_selected) + }) + .hover(|this| this.bg(cx.theme().colors().element_hover)) + .child(gpui::div().when(checked, |this| { + this.size_full() + .flex() + .items_center() + .justify_center() + .child(Icon::new(IconName::Check)) + })); + + let main_row = if let Some(on_click) = on_click { + gpui::div() + .id("checkbox-row") + .h_flex() + .gap_2() + .items_center() + .child(checkbox) + .child(Label::new(self.label)) + .cursor_pointer() + .on_click(move |_event, window, cx| on_click(window, cx)) + } else { + gpui::div() + .id("checkbox-row") + .h_flex() + .gap_2() + .items_center() + .child(checkbox) + .child(Label::new(self.label)) + }; + + v_flex() + .px_5() + .py_1() + .gap_1() + .child(main_row) + .when_some(self.description, |this, desc| { + this.child( + gpui::div() + .ml_6() + .child(Label::new(desc).size(LabelSize::Small).color(Color::Muted)), + ) + }) + } +} + +impl Component for CheckboxRow { + fn scope() -> ComponentScope { + ComponentScope::Layout + } + + fn sort_name() -> &'static str { + "RowCheckbox" + } + + fn preview(_window: &mut Window, _cx: &mut App) -> Option { + let examples = example_group_with_title( + "CheckboxRow Examples", + vec![ + single_example( + "Unchecked", + CheckboxRow::new("Enable Vim Mode").into_any_element(), + ), + single_example( + "Checked", + CheckboxRow::new("Send Crash Reports") + .checked(true) + .into_any_element(), + ), + single_example( + "With Description", + CheckboxRow::new("Send Telemetry") + .description("Help improve Zed by sending anonymous usage data") + .checked(true) + .into_any_element(), + ), + ], + ); + + Some(v_flex().p_4().gap_4().child(examples).into_any_element()) + } +} diff --git a/crates/onboarding_ui/src/components/header_row.rs b/crates/onboarding_ui/src/components/header_row.rs new file mode 100644 index 0000000000..e13d48f84d --- /dev/null +++ b/crates/onboarding_ui/src/components/header_row.rs @@ -0,0 +1,78 @@ +use component::{example_group_with_title, single_example}; +use gpui::{AnyElement, App, IntoElement, RenderOnce, Window}; +use ui::{Label, prelude::*}; + +#[derive(IntoElement, RegisterComponent)] +pub struct HeaderRow { + label: SharedString, + end_slot: Option, +} + +impl HeaderRow { + pub fn new(label: impl Into) -> Self { + Self { + label: label.into(), + end_slot: None, + } + } + + pub fn end_slot(mut self, slot: impl IntoElement) -> Self { + self.end_slot = Some(slot.into_any_element()); + self + } +} + +impl RenderOnce for HeaderRow { + fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement { + h_flex() + .h(px(32.)) + .w_full() + .px_5() + .justify_between() + .child(Label::new(self.label)) + .when_some(self.end_slot, |this, slot| this.child(slot)) + } +} + +impl Component for HeaderRow { + fn scope() -> ComponentScope { + ComponentScope::Layout + } + + fn sort_name() -> &'static str { + "RowHeader" + } + + fn preview(_window: &mut Window, _cx: &mut App) -> Option { + let examples = example_group_with_title( + "HeaderRow Examples", + vec![ + single_example( + "Simple Header", + HeaderRow::new("Pick a Theme").into_any_element(), + ), + single_example( + "Header with Button", + HeaderRow::new("Pick a Theme") + .end_slot( + Button::new("more_themes", "More Themes") + .style(ButtonStyle::Subtle) + .color(Color::Muted), + ) + .into_any_element(), + ), + single_example( + "Header with Icon Button", + HeaderRow::new("Settings") + .end_slot( + IconButton::new("refresh", IconName::RotateCw) + .style(ButtonStyle::Subtle), + ) + .into_any_element(), + ), + ], + ); + + Some(v_flex().p_4().gap_4().child(examples).into_any_element()) + } +} diff --git a/crates/onboarding_ui/src/components/mod.rs b/crates/onboarding_ui/src/components/mod.rs index 707b2d2ea4..1685b82618 100644 --- a/crates/onboarding_ui/src/components/mod.rs +++ b/crates/onboarding_ui/src/components/mod.rs @@ -1 +1,5 @@ +mod callout_row; +mod checkbox_row; +mod header_row; mod selectable_tile; +mod selectable_tile_row; diff --git a/crates/onboarding_ui/src/components/selectable_tile_row.rs b/crates/onboarding_ui/src/components/selectable_tile_row.rs new file mode 100644 index 0000000000..f903e4a663 --- /dev/null +++ b/crates/onboarding_ui/src/components/selectable_tile_row.rs @@ -0,0 +1,124 @@ +use super::selectable_tile::SelectableTile; +use component::{example_group_with_title, single_example}; +use gpui::{ + AnyElement, App, IntoElement, RenderOnce, StatefulInteractiveElement, Window, prelude::*, +}; +use smallvec::SmallVec; +use ui::{Label, prelude::*}; + +#[derive(IntoElement, RegisterComponent)] +pub struct SelectableTileRow { + gap: Pixels, + tiles: SmallVec<[SelectableTile; 8]>, +} + +impl SelectableTileRow { + pub fn new() -> Self { + Self { + gap: px(12.), + tiles: SmallVec::new(), + } + } + + pub fn gap(mut self, gap: impl Into) -> Self { + self.gap = gap.into(); + self + } + + pub fn tile(mut self, tile: SelectableTile) -> Self { + self.tiles.push(tile); + self + } +} + +impl RenderOnce for SelectableTileRow { + fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement { + h_flex().w_full().px_5().gap(self.gap).children(self.tiles) + } +} + +impl Component for SelectableTileRow { + fn scope() -> ComponentScope { + ComponentScope::Layout + } + + fn sort_name() -> &'static str { + "RowSelectableTile" + } + + fn preview(_window: &mut Window, _cx: &mut App) -> Option { + let examples = example_group_with_title( + "SelectableTileRow Examples", + vec![ + single_example( + "Theme Tiles", + SelectableTileRow::new() + .gap(px(12.)) + .tile( + SelectableTile::new("tile1", px(100.), px(80.)) + .selected(true) + .child( + div() + .size_full() + .bg(gpui::red()) + .flex() + .items_center() + .justify_center() + .child(Label::new("Dark")), + ), + ) + .tile( + SelectableTile::new("tile2", px(100.), px(80.)).child( + div() + .size_full() + .bg(gpui::green()) + .flex() + .items_center() + .justify_center() + .child(Label::new("Light")), + ), + ) + .tile( + SelectableTile::new("tile3", px(100.), px(80.)) + .parent_focused(true) + .child( + div() + .size_full() + .bg(gpui::blue()) + .flex() + .items_center() + .justify_center() + .child(Label::new("Auto")), + ), + ) + .into_any_element(), + ), + single_example( + "Icon Tiles", + SelectableTileRow::new() + .gap(px(8.)) + .tile( + SelectableTile::new("icon1", px(48.), px(48.)) + .selected(true) + .child(Icon::new(IconName::Code).size(IconSize::Medium)), + ) + .tile( + SelectableTile::new("icon2", px(48.), px(48.)) + .child(Icon::new(IconName::Terminal).size(IconSize::Medium)), + ) + .tile( + SelectableTile::new("icon3", px(48.), px(48.)) + .child(Icon::new(IconName::FileCode).size(IconSize::Medium)), + ) + .tile( + SelectableTile::new("icon4", px(48.), px(48.)) + .child(Icon::new(IconName::Settings).size(IconSize::Medium)), + ) + .into_any_element(), + ), + ], + ); + + Some(v_flex().p_4().gap_4().child(examples).into_any_element()) + } +} From 5b2874b01a6267a25061bd35ac74583734a4ac8c Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Fri, 4 Jul 2025 21:56:04 -0400 Subject: [PATCH 26/29] WIP use components --- crates/onboarding_ui/src/components/mod.rs | 6 + crates/onboarding_ui/src/onboarding_ui.rs | 209 +++++---------------- 2 files changed, 55 insertions(+), 160 deletions(-) diff --git a/crates/onboarding_ui/src/components/mod.rs b/crates/onboarding_ui/src/components/mod.rs index 1685b82618..77ead73641 100644 --- a/crates/onboarding_ui/src/components/mod.rs +++ b/crates/onboarding_ui/src/components/mod.rs @@ -3,3 +3,9 @@ mod checkbox_row; mod header_row; mod selectable_tile; mod selectable_tile_row; + +pub use callout_row::CalloutRow; +pub use checkbox_row::CheckboxRow; +pub use header_row::HeaderRow; +pub use selectable_tile::SelectableTile; +pub use selectable_tile_row::SelectableTileRow; diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 0a8b23255c..32818a4467 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -4,6 +4,7 @@ mod juicy_button; mod persistence; mod theme_preview; +use self::components::{CalloutRow, CheckboxRow, HeaderRow, SelectableTile, SelectableTileRow}; use self::juicy_button::JuicyButton; use client::{Client, TelemetrySettings}; use command_palette_hooks::CommandPaletteFilter; @@ -708,31 +709,38 @@ impl OnboardingUI { .id("theme-selector") .h_full() .w_full() - .gap_6() .overflow_y_scroll() + .child({ + let vim_enabled = VimModeSetting::get_global(cx).0; + CheckboxRow::new("Enable Vim Mode") + .checked(vim_enabled) + .on_click(move |_window, cx| { + let current = VimModeSetting::get_global(cx).0; + SettingsStore::update_global(cx, move |store, cx| { + let mut settings = store.raw_user_settings().clone(); + settings["vim_mode"] = serde_json::json!(!current); + store.set_user_settings(&settings.to_string(), cx).ok(); + }); + }) + }) // Theme selector section .child( v_flex() .w_full() .overflow_hidden() .child( - h_flex() - .h(px(32.)) - .w_full() - .justify_between() - .child(Label::new("Pick a Theme")) - .child( - Button::new("more_themes", "More Themes") - .style(ButtonStyle::Subtle) - .color(Color::Muted) - .on_click(cx.listener(|_, _, window, cx| { - window.dispatch_action( - zed_actions::theme_selector::Toggle::default() - .boxed_clone(), - cx, - ); - })), - ), + HeaderRow::new("Pick a Theme").end_slot( + Button::new("more_themes", "More Themes") + .style(ButtonStyle::Subtle) + .color(Color::Muted) + .on_click(cx.listener(|_, _, window, cx| { + window.dispatch_action( + zed_actions::theme_selector::Toggle::default() + .boxed_clone(), + cx, + ); + })), + ), ) .child( h_flex().w_full().overflow_hidden().gap_3().children( @@ -810,15 +818,8 @@ impl OnboardingUI { // Keymap selector section .child( v_flex() - .gap_3() - .mt_4() - .child( - h_flex() - .h(px(32.)) - .w_full() - .justify_between() - .child(Label::new("Pick a Keymap")), - ) + .gap_1() + .child(HeaderRow::new("Pick a Keymap")) .child( h_flex().gap_2().children( vec![ @@ -923,88 +924,31 @@ impl OnboardingUI { // Settings checkboxes .child( v_flex() - .gap_3() - .mt_6() + .gap_1() + .child(HeaderRow::new("Help Improve Zed")) .child({ - let vim_enabled = VimModeSetting::get_global(cx).0; - h_flex() - .id("vim_mode_container") - .gap_2() - .items_center() - .p_1() - .rounded_md() - .when(is_page_focused && focused_item == 11, |this| { - this.border_2() - .border_color(cx.theme().colors().border_focused) - }) - .child( - div() - .id("vim_mode_checkbox") - .w_4() - .h_4() - .rounded_sm() - .border_1() - .border_color(cx.theme().colors().border) - .when(vim_enabled, |this| { - this.bg(cx.theme().colors().element_selected) - .border_color(cx.theme().colors().border_selected) - }) - .hover(|this| this.bg(cx.theme().colors().element_hover)) - .child(div().when(vim_enabled, |this| { - this.size_full() - .flex() - .items_center() - .justify_center() - .child(Icon::new(IconName::Check)) - })), - ) - .child(Label::new("Enable Vim Mode")) - .cursor_pointer() - .on_click(cx.listener(move |this, _, _window, cx| { - let current = VimModeSetting::get_global(cx).0; + let telemetry_enabled = TelemetrySettings::get_global(cx).metrics; + CheckboxRow::new("Send Telemetry") + .description("Help improve Zed by sending anonymous usage data") + .checked(telemetry_enabled) + .on_click(move |_window, cx| { + let current = TelemetrySettings::get_global(cx).metrics; SettingsStore::update_global(cx, move |store, cx| { let mut settings = store.raw_user_settings().clone(); - settings["vim_mode"] = serde_json::json!(!current); + if settings.get("telemetry").is_none() { + settings["telemetry"] = serde_json::json!({}); + } + settings["telemetry"]["metrics"] = serde_json::json!(!current); store.set_user_settings(&settings.to_string(), cx).ok(); }); - })) + }) }) .child({ let crash_reports_enabled = TelemetrySettings::get_global(cx).diagnostics; - h_flex() - .id("crash_reports_container") - .gap_2() - .items_center() - .p_1() - .rounded_md() - .when(is_page_focused && focused_item == 12, |this| { - this.border_2() - .border_color(cx.theme().colors().border_focused) - }) - .child( - div() - .id("crash_reports_checkbox") - .w_4() - .h_4() - .rounded_sm() - .border_1() - .border_color(cx.theme().colors().border) - .when(crash_reports_enabled, |this| { - this.bg(cx.theme().colors().element_selected) - .border_color(cx.theme().colors().border_selected) - }) - .hover(|this| this.bg(cx.theme().colors().element_hover)) - .child(div().when(crash_reports_enabled, |this| { - this.size_full() - .flex() - .items_center() - .justify_center() - .child(Icon::new(IconName::Check)) - })), - ) - .child(Label::new("Send Crash Reports")) - .cursor_pointer() - .on_click(cx.listener(move |this, _, _window, cx| { + CheckboxRow::new("Send Crash Reports") + .description("We use crash reports to help us fix issues") + .checked(crash_reports_enabled) + .on_click(move |_window, cx| { let current = TelemetrySettings::get_global(cx).diagnostics; SettingsStore::update_global(cx, move |store, cx| { let mut settings = store.raw_user_settings().clone(); @@ -1015,54 +959,7 @@ impl OnboardingUI { serde_json::json!(!current); store.set_user_settings(&settings.to_string(), cx).ok(); }); - })) - }) - .child({ - let telemetry_enabled = TelemetrySettings::get_global(cx).metrics; - h_flex() - .id("telemetry_container") - .gap_2() - .items_center() - .p_1() - .rounded_md() - .when(is_page_focused && focused_item == 13, |this| { - this.border_2() - .border_color(cx.theme().colors().border_focused) }) - .child( - div() - .id("telemetry_checkbox") - .w_4() - .h_4() - .rounded_sm() - .border_1() - .border_color(cx.theme().colors().border) - .when(telemetry_enabled, |this| { - this.bg(cx.theme().colors().element_selected) - .border_color(cx.theme().colors().border_selected) - }) - .hover(|this| this.bg(cx.theme().colors().element_hover)) - .child(div().when(telemetry_enabled, |this| { - this.size_full() - .flex() - .items_center() - .justify_center() - .child(Icon::new(IconName::Check)) - })), - ) - .child(Label::new("Send Telemetry")) - .cursor_pointer() - .on_click(cx.listener(move |this, _, _window, cx| { - let current = TelemetrySettings::get_global(cx).metrics; - SettingsStore::update_global(cx, move |store, cx| { - let mut settings = store.raw_user_settings().clone(); - if settings.get("telemetry").is_none() { - settings["telemetry"] = serde_json::json!({}); - } - settings["telemetry"]["metrics"] = serde_json::json!(!current); - store.set_user_settings(&settings.to_string(), cx).ok(); - }); - })) }), ) .into_any_element() @@ -1142,20 +1039,12 @@ impl OnboardingUI { |_, _, cx| todo!("implement ai toggle"), ))) .child( - v_container() - .p_3() - .child(Label::new("We don't use your code to train AI models").weight(FontWeight::MEDIUM)) - .child(Label::new("You choose which providers you enable, and they have their own privacy policies.") - .size(LabelSize::Small).color(Color::Muted)) - .child(Label::new("Read more about our privacy practices in our Privacy Policy.") - .size(LabelSize::Small).color(Color::Muted)) + CalloutRow::new("We don't use your code to train AI models") + .line("You choose which providers you enable, and they have their own privacy policies.") + .line("Read more about our privacy practices in our Privacy Policy.") ) .child( - h_flex() - .h(px(32.)) - .w_full() - .justify_between() - .child(Label::new("Choose your AI Providers")), + HeaderRow::new("Choose your AI Providers") ) .into_any_element() } From 7e22e57e085774055cd4153f6d49ae1fc06dc0db Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 7 Jul 2025 11:41:55 -0400 Subject: [PATCH 27/29] Introduce global ai setting --- Cargo.lock | 2 + assets/settings/default.json | 6 +- crates/agent_ui/src/inline_assistant.rs | 3 +- crates/language/src/language_settings.rs | 21 ++++ crates/onboarding_ui/Cargo.toml | 1 + crates/onboarding_ui/src/onboarding_ui.rs | 129 +++++++++++++++++----- crates/zed/Cargo.toml | 1 + crates/zed/src/zed.rs | 50 ++++++++- crates/zed_actions/src/lib.rs | 4 + 9 files changed, 188 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 809074fb1b..4a684484c4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10826,6 +10826,7 @@ dependencies = [ "editor", "feature_flags", "gpui", + "language", "menu", "project", "serde_json", @@ -19999,6 +20000,7 @@ dependencies = [ "collab_ui", "collections", "command_palette", + "command_palette_hooks", "component", "copilot", "dap", diff --git a/assets/settings/default.json b/assets/settings/default.json index 985e322cac..0e46115ae3 100644 --- a/assets/settings/default.json +++ b/assets/settings/default.json @@ -25,7 +25,11 @@ // Features that can be globally enabled or disabled "features": { // Which edit prediction provider to use. - "edit_prediction_provider": "zed" + "edit_prediction_provider": "zed", + // A globally enable or disable AI features. + // + // This setting supersedes all other settings related to AI features. + "ai_assistance": true }, // The name of a font to use for rendering text in the editor "buffer_font_family": "Zed Plex Mono", diff --git a/crates/agent_ui/src/inline_assistant.rs b/crates/agent_ui/src/inline_assistant.rs index c9c173a68b..966e18de54 100644 --- a/crates/agent_ui/src/inline_assistant.rs +++ b/crates/agent_ui/src/inline_assistant.rs @@ -33,6 +33,7 @@ use gpui::{ App, Context, Entity, Focusable, Global, HighlightStyle, Subscription, Task, UpdateGlobal, WeakEntity, Window, point, }; +use language::language_settings; use language::{Buffer, Point, Selection, TransactionId}; use language_model::{ ConfigurationError, ConfiguredModel, LanguageModelRegistry, report_assistant_event, @@ -1768,7 +1769,7 @@ impl CodeActionProvider for AssistantCodeActionProvider { _: &mut Window, cx: &mut App, ) -> Task>> { - if !AgentSettings::get_global(cx).enabled { + if !AgentSettings::get_global(cx).enabled || !language_settings::ai_enabled(cx) { return Task::ready(Ok(Vec::new())); } diff --git a/crates/language/src/language_settings.rs b/crates/language/src/language_settings.rs index 9b0abb1537..f1ce1fed47 100644 --- a/crates/language/src/language_settings.rs +++ b/crates/language/src/language_settings.rs @@ -54,11 +54,18 @@ pub fn all_language_settings<'a>( AllLanguageSettings::get(location, cx) } +/// Returns whether AI assistance is globally enabled or disabled. +pub fn ai_enabled(cx: &App) -> bool { + all_language_settings(None, cx).ai_assistance +} + /// The settings for all languages. #[derive(Debug, Clone)] pub struct AllLanguageSettings { /// The edit prediction settings. pub edit_predictions: EditPredictionSettings, + /// Whether AI assistance is enabled. + pub ai_assistance: bool, pub defaults: LanguageSettings, languages: HashMap, pub(crate) file_types: FxHashMap, GlobSet>, @@ -646,6 +653,8 @@ pub struct CopilotSettingsContent { pub struct FeaturesContent { /// Determines which edit prediction provider to use. pub edit_prediction_provider: Option, + /// Whether AI assistance is enabled. + pub ai_assistance: Option, } /// Controls the soft-wrapping behavior in the editor. @@ -1122,6 +1131,11 @@ impl AllLanguageSettings { pub fn edit_predictions_mode(&self) -> EditPredictionsMode { self.edit_predictions.mode } + + /// Returns whether AI assistance is enabled. + pub fn is_ai_assistance_enabled(&self) -> bool { + self.ai_assistance + } } fn merge_with_editorconfig(settings: &mut LanguageSettings, cfg: &EditorconfigProperties) { @@ -1247,6 +1261,12 @@ impl settings::Settings for AllLanguageSettings { .map(|settings| settings.enabled_in_text_threads) .unwrap_or(true); + let ai_assistance = default_value + .features + .as_ref() + .and_then(|f| f.ai_assistance) + .unwrap_or(true); + let mut file_types: FxHashMap, GlobSet> = FxHashMap::default(); for (language, patterns) in &default_value.file_types { @@ -1359,6 +1379,7 @@ impl settings::Settings for AllLanguageSettings { copilot: copilot_settings, enabled_in_text_threads, }, + ai_assistance, defaults, languages, file_types, diff --git a/crates/onboarding_ui/Cargo.toml b/crates/onboarding_ui/Cargo.toml index fc903dbaff..7bef93e457 100644 --- a/crates/onboarding_ui/Cargo.toml +++ b/crates/onboarding_ui/Cargo.toml @@ -23,6 +23,7 @@ component.workspace = true db.workspace = true feature_flags.workspace = true gpui.workspace = true +language.workspace = true menu.workspace = true project.workspace = true serde_json.workspace = true diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 32818a4467..4d48ba399f 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -10,20 +10,22 @@ use client::{Client, TelemetrySettings}; use command_palette_hooks::CommandPaletteFilter; use feature_flags::FeatureFlagAppExt as _; use gpui::{ - Action, Entity, EventEmitter, FocusHandle, Focusable, FontWeight, KeyBinding, Task, - UpdateGlobal, WeakEntity, actions, prelude::*, svg, transparent_black, + Action, Entity, EventEmitter, FocusHandle, Focusable, FontWeight, KeyBinding, Subscription, + Task, UpdateGlobal, WeakEntity, actions, prelude::*, svg, transparent_black, }; use menu; use persistence::ONBOARDING_DB; +use language::language_settings::{AllLanguageSettings, ai_enabled, all_language_settings}; use project::Project; use serde_json; -use settings::{Settings, SettingsStore}; +use settings::{Settings, SettingsStore, update_settings_file}; use settings_ui::SettingsUiFeatureFlag; +use std::collections::HashSet; use std::sync::Arc; use theme::{Theme, ThemeRegistry, ThemeSettings}; use ui::{ - CheckboxWithLabel, ContentGroup, KeybindingHint, ListItem, Ring, ToggleState, Vector, + CheckboxWithLabel, ContentGroup, FocusOutline, KeybindingHint, ListItem, ToggleState, Vector, VectorName, prelude::*, }; use util::ResultExt; @@ -87,7 +89,7 @@ fn feature_gate_onboarding_ui_actions(cx: &mut App) { .detach(); } -#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum OnboardingPage { Basics, Editing, @@ -139,7 +141,7 @@ pub struct OnboardingUI { current_page: OnboardingPage, nav_focus: NavigationFocusItem, page_focus: [PageFocusItem; 4], - completed_pages: [bool; 4], + completed_pages: HashSet, focus_area: FocusArea, // Workspace reference for Item trait @@ -147,6 +149,7 @@ pub struct OnboardingUI { workspace_id: Option, client: Arc, welcome_page: Option>, + _settings_subscription: Option, } impl OnboardingUI {} @@ -179,6 +182,8 @@ impl Render for OnboardingUI { .on_action(cx.listener(Self::confirm)) .on_action(cx.listener(Self::cancel)) .on_action(cx.listener(Self::toggle_focus)) + .on_action(cx.listener(Self::handle_enable_ai_assistance)) + .on_action(cx.listener(Self::handle_disable_ai_assistance)) .flex() .items_center() .justify_center() @@ -218,31 +223,57 @@ impl Render for OnboardingUI { impl OnboardingUI { pub fn new(workspace: &Workspace, client: Arc, cx: &mut Context) -> Self { + let settings_subscription = cx.observe_global::(|_, cx| { + cx.notify(); + }); + Self { focus_handle: cx.focus_handle(), current_page: OnboardingPage::Basics, nav_focus: NavigationFocusItem::Basics, page_focus: [PageFocusItem(0); 4], - completed_pages: [false; 4], + completed_pages: HashSet::new(), focus_area: FocusArea::Navigation, workspace: workspace.weak_handle(), workspace_id: workspace.database_id(), client, welcome_page: None, + _settings_subscription: Some(settings_subscription), } } fn completed_pages_to_string(&self) -> String { - self.completed_pages - .iter() - .map(|&completed| if completed { '1' } else { '0' }) - .collect() + let mut result = String::new(); + for i in 0..4 { + let page = match i { + 0 => OnboardingPage::Basics, + 1 => OnboardingPage::Editing, + 2 => OnboardingPage::AiSetup, + 3 => OnboardingPage::Welcome, + _ => unreachable!(), + }; + result.push(if self.completed_pages.contains(&page) { + '1' + } else { + '0' + }); + } + result } - fn completed_pages_from_string(s: &str) -> [bool; 4] { - let mut result = [false; 4]; + fn completed_pages_from_string(s: &str) -> HashSet { + let mut result = HashSet::new(); for (i, ch) in s.chars().take(4).enumerate() { - result[i] = ch == '1'; + if ch == '1' { + let page = match i { + 0 => OnboardingPage::Basics, + 1 => OnboardingPage::Editing, + 2 => OnboardingPage::AiSetup, + 3 => OnboardingPage::Welcome, + _ => continue, + }; + result.insert(page); + } } result } @@ -275,7 +306,7 @@ impl OnboardingUI { fn reset(&mut self, _window: &mut gpui::Window, cx: &mut Context) { self.current_page = OnboardingPage::Basics; self.focus_area = FocusArea::Navigation; - self.completed_pages = [false; 4]; + self.completed_pages = HashSet::new(); cx.notify(); } @@ -460,13 +491,7 @@ impl OnboardingUI { _window: &mut gpui::Window, cx: &mut Context, ) { - let index = match page { - OnboardingPage::Basics => 0, - OnboardingPage::Editing => 1, - OnboardingPage::AiSetup => 2, - OnboardingPage::Welcome => 3, - }; - self.completed_pages[index] = true; + self.completed_pages.insert(page); cx.notify(); } @@ -510,6 +535,40 @@ impl OnboardingUI { self.next_page(window, cx); } + fn handle_enable_ai_assistance( + &mut self, + _: &zed_actions::EnableAiAssistance, + _window: &mut Window, + cx: &mut Context, + ) { + if let Some(workspace) = self.workspace.upgrade() { + let fs = workspace.read(cx).app_state().fs.clone(); + update_settings_file::(fs, cx, move |file, _| { + file.features + .get_or_insert(Default::default()) + .ai_assistance = Some(true); + }); + cx.notify(); + } + } + + fn handle_disable_ai_assistance( + &mut self, + _: &zed_actions::DisableAiAssistance, + _window: &mut Window, + cx: &mut Context, + ) { + if let Some(workspace) = self.workspace.upgrade() { + let fs = workspace.read(cx).app_state().fs.clone(); + update_settings_file::(fs, cx, move |file, _| { + file.features + .get_or_insert(Default::default()) + .ai_assistance = Some(false); + }); + cx.notify(); + } + } + fn handle_previous_page( &mut self, _: &PreviousPage, @@ -626,7 +685,7 @@ impl OnboardingUI { let area_focused = self.focus_area == FocusArea::Navigation; - Ring::new(corner_radius, item_focused) + FocusOutline::new(corner_radius, item_focused, px(2.)) .active(area_focused && item_focused) .child( h_flex() @@ -1024,6 +1083,10 @@ impl OnboardingUI { let focused_item = self.page_focus[page_index].0; let is_page_focused = self.focus_area == FocusArea::PageContent; + let ai_enabled = ai_enabled(cx); + + let workspace = self.workspace.clone(); + v_flex() .h_full() .w_full() @@ -1035,8 +1098,22 @@ impl OnboardingUI { CheckboxWithLabel::new( "disable_ai", Label::new("Enable AI Features"), - ToggleState::Selected, - |_, _, cx| todo!("implement ai toggle"), + if ai_enabled { + ToggleState::Selected + } else { + ToggleState::Unselected + }, + move |state, _, cx| { + let enabled = state == &ToggleState::Selected; + if let Some(workspace) = workspace.upgrade() { + let fs = workspace.read(cx).app_state().fs.clone(); + update_settings_file::(fs, cx, move |file, _| { + file.features + .get_or_insert(Default::default()) + .ai_assistance = Some(enabled); + }); + } + }, ))) .child( CalloutRow::new("We don't use your code to train AI models") @@ -1148,7 +1225,7 @@ impl SerializableItem for OnboardingUI { let completed = OnboardingUI::completed_pages_from_string(&completed_str); (page, completed) } else { - (OnboardingPage::Basics, [false; 4]) + (OnboardingPage::Basics, HashSet::new()) }; cx.update(|window, cx| { diff --git a/crates/zed/Cargo.toml b/crates/zed/Cargo.toml index 779e0739bb..6305947246 100644 --- a/crates/zed/Cargo.toml +++ b/crates/zed/Cargo.toml @@ -42,6 +42,7 @@ client.workspace = true collab_ui.workspace = true collections.workspace = true command_palette.workspace = true +command_palette_hooks.workspace = true component.workspace = true copilot.workspace = true dap_adapters.workspace = true diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 10fdcf34a6..08aa0dae7f 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -16,6 +16,7 @@ use assets::Assets; use breadcrumbs::Breadcrumbs; use client::zed_urls; use collections::VecDeque; +use command_palette_hooks::CommandPaletteFilter; use debugger_ui::debugger_panel::DebugPanel; use editor::ProposedChangesEditorToolbar; use editor::{Editor, MultiBuffer}; @@ -52,6 +53,7 @@ use settings::{ Settings, SettingsStore, VIM_KEYMAP_PATH, initial_local_debug_tasks_content, initial_project_settings_content, initial_tasks_content, update_settings_file, }; +use std::any::TypeId; use std::path::PathBuf; use std::sync::atomic::{self, AtomicBool}; use std::{borrow::Cow, path::Path, sync::Arc}; @@ -72,7 +74,8 @@ use workspace::{ use workspace::{CloseIntent, CloseWindow, RestoreBanner, with_active_or_new_workspace}; use workspace::{Pane, notifications::DetachAndPromptErr}; use zed_actions::{ - OpenAccountSettings, OpenBrowser, OpenDocs, OpenServerSettings, OpenSettings, OpenZedUrl, Quit, + DisableAiAssistance, EnableAiAssistance, OpenAccountSettings, OpenBrowser, OpenDocs, + OpenServerSettings, OpenSettings, OpenZedUrl, Quit, }; actions!( @@ -215,6 +218,51 @@ pub fn init(cx: &mut App) { ); }); }); + cx.on_action(|_: &EnableAiAssistance, cx| { + with_active_or_new_workspace(cx, |workspace, _, cx| { + let fs = workspace.app_state().fs.clone(); + update_settings_file::( + fs, + cx, + move |file, _| { + file.features + .get_or_insert(Default::default()) + .ai_assistance = Some(true); + }, + ); + }); + }); + cx.on_action(|_: &DisableAiAssistance, cx| { + with_active_or_new_workspace(cx, |workspace, _, cx| { + let fs = workspace.app_state().fs.clone(); + update_settings_file::( + fs, + cx, + move |file, _| { + file.features + .get_or_insert(Default::default()) + .ai_assistance = Some(false); + }, + ); + }); + }); + + // Filter AI assistance actions based on current state + cx.observe_global::(move |cx| { + let ai_enabled = + language::language_settings::all_language_settings(None, cx).is_ai_assistance_enabled(); + + CommandPaletteFilter::update_global(cx, |filter, _cx| { + if ai_enabled { + filter.hide_action_types(&[TypeId::of::()]); + filter.show_action_types([TypeId::of::()].iter()); + } else { + filter.show_action_types([TypeId::of::()].iter()); + filter.hide_action_types(&[TypeId::of::()]); + } + }); + }) + .detach(); } fn bind_on_window_closed(cx: &mut App) -> Option { diff --git a/crates/zed_actions/src/lib.rs b/crates/zed_actions/src/lib.rs index ffe232ad7b..1daba076b5 100644 --- a/crates/zed_actions/src/lib.rs +++ b/crates/zed_actions/src/lib.rs @@ -50,6 +50,10 @@ actions!( OpenLicenses, /// Opens the telemetry log. OpenTelemetryLog, + /// Enables AI assistance features. + EnableAiAssistance, + /// Disables AI assistance features. + DisableAiAssistance, ] ); From adb2e95e2aa13cf4ba4e7b210685a24bf969f2e4 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 7 Jul 2025 12:15:42 -0400 Subject: [PATCH 28/29] Update focus outline styles --- crates/ui/src/components.rs | 4 ++-- .../components/{ring.rs => focus_outline.rs} | 21 +++++++++---------- 2 files changed, 12 insertions(+), 13 deletions(-) rename crates/ui/src/components/{ring.rs => focus_outline.rs} (75%) diff --git a/crates/ui/src/components.rs b/crates/ui/src/components.rs index 6d9599c491..d21bc16b4c 100644 --- a/crates/ui/src/components.rs +++ b/crates/ui/src/components.rs @@ -8,6 +8,7 @@ mod disclosure; mod divider; mod dropdown_menu; mod facepile; +mod focus_outline; mod group; mod icon; mod image; @@ -27,7 +28,6 @@ mod popover_menu; mod progress; mod radio; mod right_click_menu; -mod ring; mod scrollbar; mod settings_container; mod settings_group; @@ -51,6 +51,7 @@ pub use disclosure::*; pub use divider::*; pub use dropdown_menu::*; pub use facepile::*; +pub use focus_outline::*; pub use group::*; pub use icon::*; pub use image::*; @@ -70,7 +71,6 @@ pub use popover_menu::*; pub use progress::*; pub use radio::*; pub use right_click_menu::*; -pub use ring::*; pub use scrollbar::*; pub use settings_container::*; pub use settings_group::*; diff --git a/crates/ui/src/components/ring.rs b/crates/ui/src/components/focus_outline.rs similarity index 75% rename from crates/ui/src/components/ring.rs rename to crates/ui/src/components/focus_outline.rs index 22081d03df..042ba588cd 100644 --- a/crates/ui/src/components/ring.rs +++ b/crates/ui/src/components/focus_outline.rs @@ -6,10 +6,10 @@ use theme::ActiveTheme; use crate::{h_flex, utils::CornerSolver}; -/// A ring is a stylistic focus indicator that draws a ring around +/// An outline is a stylistic focus indicator that draws a ring around /// an element with some space between the element and ring. #[derive(IntoElement)] -pub struct Ring { +pub struct FocusOutline { corner_radius: Pixels, border_width: Pixels, padding: Pixels, @@ -18,16 +18,15 @@ pub struct Ring { children: SmallVec<[AnyElement; 2]>, } -impl Ring { - pub fn new(child_corner_radius: Pixels, focused: bool) -> Self { - let border_width = px(1.); - let padding = px(2.); +impl FocusOutline { + pub fn new(child_corner_radius: Pixels, focused: bool, offset: Pixels) -> Self { + let ring_width = px(1.); let corner_radius = - CornerSolver::parent_radius(child_corner_radius, border_width, padding, px(0.)); + CornerSolver::parent_radius(child_corner_radius, ring_width, offset, px(0.)); Self { corner_radius, - border_width, - padding, + border_width: ring_width, + padding: offset, focused, active: false, children: SmallVec::new(), @@ -40,7 +39,7 @@ impl Ring { } } -impl RenderOnce for Ring { +impl RenderOnce for FocusOutline { fn render(self, _window: &mut gpui::Window, cx: &mut gpui::App) -> impl IntoElement { let border_color = if self.focused && self.active { cx.theme().colors().border_focused.opacity(0.48) @@ -59,7 +58,7 @@ impl RenderOnce for Ring { } } -impl ParentElement for Ring { +impl ParentElement for FocusOutline { fn extend(&mut self, elements: impl IntoIterator) { self.children.extend(elements) } From 94102e962c76066d025fabbffa5d2b09893cd843 Mon Sep 17 00:00:00 2001 From: Nate Butler Date: Mon, 7 Jul 2025 12:15:52 -0400 Subject: [PATCH 29/29] Update global ai setting --- Cargo.lock | 1 + crates/language/src/language_settings.rs | 27 ++++++++++++++++++- crates/onboarding_ui/Cargo.toml | 5 ++-- crates/onboarding_ui/src/onboarding_ui.rs | 32 +++++++++++++---------- crates/zed/src/zed.rs | 20 ++------------ 5 files changed, 50 insertions(+), 35 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 4a684484c4..979d349427 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10827,6 +10827,7 @@ dependencies = [ "feature_flags", "gpui", "language", + "log", "menu", "project", "serde_json", diff --git a/crates/language/src/language_settings.rs b/crates/language/src/language_settings.rs index f1ce1fed47..c4e908df79 100644 --- a/crates/language/src/language_settings.rs +++ b/crates/language/src/language_settings.rs @@ -16,8 +16,10 @@ use serde::{ de::{self, IntoDeserializer, MapAccess, SeqAccess, Visitor}, }; +use fs::Fs; use settings::{ ParameterizedJsonSchema, Settings, SettingsLocation, SettingsSources, SettingsStore, + update_settings_file, }; use shellexpand; use std::{borrow::Cow, num::NonZeroU32, path::Path, slice, sync::Arc}; @@ -1136,6 +1138,21 @@ impl AllLanguageSettings { pub fn is_ai_assistance_enabled(&self) -> bool { self.ai_assistance } + + /// Sets AI assistance to the specified state and updates the settings file. + pub fn set_ai_assistance(enabled: bool, fs: Arc, cx: &mut App) { + let current_state = Self::get_global(cx).ai_assistance; + + if current_state == enabled { + return; + } + + update_settings_file::(fs, cx, move |file, _| { + file.features + .get_or_insert(Default::default()) + .ai_assistance = Some(enabled); + }); + } } fn merge_with_editorconfig(settings: &mut LanguageSettings, cfg: &EditorconfigProperties) { @@ -1261,7 +1278,7 @@ impl settings::Settings for AllLanguageSettings { .map(|settings| settings.enabled_in_text_threads) .unwrap_or(true); - let ai_assistance = default_value + let mut ai_assistance = default_value .features .as_ref() .and_then(|f| f.ai_assistance) @@ -1288,6 +1305,14 @@ impl settings::Settings for AllLanguageSettings { edit_prediction_provider = Some(provider); } + if let Some(user_ai_assistance) = user_settings + .features + .as_ref() + .and_then(|f| f.ai_assistance) + { + ai_assistance = user_ai_assistance; + } + if let Some(edit_predictions) = user_settings.edit_predictions.as_ref() { edit_predictions_mode = edit_predictions.mode; enabled_in_text_threads = edit_predictions.enabled_in_text_threads; diff --git a/crates/onboarding_ui/Cargo.toml b/crates/onboarding_ui/Cargo.toml index 7bef93e457..456d81f64d 100644 --- a/crates/onboarding_ui/Cargo.toml +++ b/crates/onboarding_ui/Cargo.toml @@ -16,7 +16,6 @@ test-support = [] [dependencies] anyhow.workspace = true -welcome.workspace = true client.workspace = true command_palette_hooks.workspace = true component.workspace = true @@ -24,18 +23,20 @@ db.workspace = true feature_flags.workspace = true gpui.workspace = true language.workspace = true +log.workspace = true menu.workspace = true project.workspace = true serde_json.workspace = true settings.workspace = true settings_ui.workspace = true +smallvec.workspace = true theme.workspace = true ui.workspace = true util.workspace = true vim_mode_setting.workspace = true +welcome.workspace = true workspace.workspace = true zed_actions.workspace = true -smallvec.workspace = true [dev-dependencies] editor = { workspace = true, features = ["test-support"] } diff --git a/crates/onboarding_ui/src/onboarding_ui.rs b/crates/onboarding_ui/src/onboarding_ui.rs index 4d48ba399f..5901b9c249 100644 --- a/crates/onboarding_ui/src/onboarding_ui.rs +++ b/crates/onboarding_ui/src/onboarding_ui.rs @@ -495,6 +495,22 @@ impl OnboardingUI { cx.notify(); } + fn set_ai_assistance( + &mut self, + selection: &ToggleState, + _: &mut Window, + cx: &mut Context, + ) { + let enabled = selection == &ToggleState::Selected; + + if let Some(workspace) = self.workspace.upgrade() { + let fs = workspace.read(cx).app_state().fs.clone(); + AllLanguageSettings::set_ai_assistance(enabled, fs, cx); + + cx.notify(); + } + } + fn handle_jump_to_basics( &mut self, _: &JumpToBasics, @@ -1083,9 +1099,7 @@ impl OnboardingUI { let focused_item = self.page_focus[page_index].0; let is_page_focused = self.focus_area == FocusArea::PageContent; - let ai_enabled = ai_enabled(cx); - - let workspace = self.workspace.clone(); + let ai_enabled = all_language_settings(None, cx).is_ai_assistance_enabled(); v_flex() .h_full() @@ -1103,17 +1117,7 @@ impl OnboardingUI { } else { ToggleState::Unselected }, - move |state, _, cx| { - let enabled = state == &ToggleState::Selected; - if let Some(workspace) = workspace.upgrade() { - let fs = workspace.read(cx).app_state().fs.clone(); - update_settings_file::(fs, cx, move |file, _| { - file.features - .get_or_insert(Default::default()) - .ai_assistance = Some(enabled); - }); - } - }, + cx.listener(Self::set_ai_assistance), ))) .child( CalloutRow::new("We don't use your code to train AI models") diff --git a/crates/zed/src/zed.rs b/crates/zed/src/zed.rs index 08aa0dae7f..ac82e5a040 100644 --- a/crates/zed/src/zed.rs +++ b/crates/zed/src/zed.rs @@ -221,29 +221,13 @@ pub fn init(cx: &mut App) { cx.on_action(|_: &EnableAiAssistance, cx| { with_active_or_new_workspace(cx, |workspace, _, cx| { let fs = workspace.app_state().fs.clone(); - update_settings_file::( - fs, - cx, - move |file, _| { - file.features - .get_or_insert(Default::default()) - .ai_assistance = Some(true); - }, - ); + language::language_settings::AllLanguageSettings::set_ai_assistance(true, fs, cx); }); }); cx.on_action(|_: &DisableAiAssistance, cx| { with_active_or_new_workspace(cx, |workspace, _, cx| { let fs = workspace.app_state().fs.clone(); - update_settings_file::( - fs, - cx, - move |file, _| { - file.features - .get_or_insert(Default::default()) - .ai_assistance = Some(false); - }, - ); + language::language_settings::AllLanguageSettings::set_ai_assistance(false, fs, cx); }); });