From 13c5a472ce70e51b317341a11f0779b71c5cbb2d Mon Sep 17 00:00:00 2001 From: FliegendeWurst <2012gdwu+github@posteo.de> Date: Thu, 5 Oct 2023 12:56:25 +0200 Subject: [PATCH] Expiration system --- Cargo.lock | 6 +- Cargo.toml | 2 +- default.nix | 2 +- src/bin/main_loop.rs | 122 +++++++++++------------------- src/bin/schedule/mod.rs | 4 +- src/bin/screensaver/mod.rs | 41 ++++++++-- src/bin/screensaver/plate.raw | Bin 0 -> 49152 bytes src/bin/screensaver/spaghetti.raw | Bin 0 -> 49152 bytes 8 files changed, 90 insertions(+), 87 deletions(-) create mode 100644 src/bin/screensaver/plate.raw create mode 100644 src/bin/screensaver/spaghetti.raw diff --git a/Cargo.lock b/Cargo.lock index f61ae00..67d4adb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1934,6 +1934,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "426f806f4089c493dcac0d24c29c01e2c38baf8e30f1b716ee37e83d200b18fe" dependencies = [ "deranged", + "js-sys", "serde", "time-core", "time-macros", @@ -1956,9 +1957,9 @@ dependencies = [ [[package]] name = "time-tz" -version = "1.0.3" +version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a422f65dfdf08a81317d54fa00b45dc58cbccab69be78c1447391cc39ae8c9d4" +checksum = "733bc522e97980eb421cbf381160ff225bd14262a48a739110f6653c6258d625" dependencies = [ "cfg-if", "parse-zoneinfo", @@ -1967,6 +1968,7 @@ dependencies = [ "serde", "serde-xml-rs", "time", + "wasm-bindgen", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 11484c9..fabb02d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ embedded-hal = "0.2.5" libc = "0.2.98" rusqlite = "0.27.0" time = { version = "0.3.9", features = ["parsing"] } -time-tz = "1.0.1" +time-tz = "2" image = { version = "0.24.1", optional = true } serde_json = "1.0.79" serde_derive = "1.0.136" diff --git a/default.nix b/default.nix index 2757dde..db6df6f 100644 --- a/default.nix +++ b/default.nix @@ -16,7 +16,7 @@ rustPlatform.buildRustPackage { nativeBuildInputs = [ pkg-config ]; - cargoBuildFlags = [ "--no-default-features" ]; + cargoBuildFlags = [ "--no-default-features" "--bin" "main_loop" ]; buildInputs = [ sqlite ]; diff --git a/src/bin/main_loop.rs b/src/bin/main_loop.rs index 3c12659..0ed564a 100644 --- a/src/bin/main_loop.rs +++ b/src/bin/main_loop.rs @@ -1,3 +1,5 @@ +#![feature(array_windows)] + use std::{ cell::RefCell, thread, @@ -67,7 +69,21 @@ impl> ContextDefault { return false; } let a = active.last().unwrap(); - a.draw(disp, rng).unwrap_or(true) + if !a.expired() { + return a.draw(disp, rng).unwrap_or(true); + } + drop(active); + self.active.borrow_mut().pop(); + self.loop_iter(disp, rng) + } + + fn pop_action_and_clear(&mut self, disp: &mut D) -> Result<(), D::Error> { + let active = self.active.get_mut(); + if active.len() > 1 { + active.pop(); + disp.clear(BLACK)?; + } + Ok(()) } } @@ -78,8 +94,10 @@ impl> Context for ContextDefault { for s in &self.screensavers { if s.id() == id { self.active.borrow_mut().push(s.convert_draw()); + return; } } + println!("warning: screensaver not found"); }, } } @@ -90,7 +108,7 @@ fn pc_main() {} #[cfg(feature = "pc")] fn pc_main() { - use std::num::NonZeroU32; + use std::{env, num::NonZeroU32}; use winit::{ dpi::LogicalSize, @@ -102,6 +120,16 @@ fn pc_main() { use crate::screensaver::{Screensaver, DUOLINGO}; use raspi_oled::FrameOutput; + let args: Vec<_> = env::args().map(|x| x.to_string()).collect(); + for [key, val] in args.array_windows() { + match key.as_str() { + "--speed" => { + screensaver::SPEED.store(val.parse().unwrap(), std::sync::atomic::Ordering::Relaxed); + }, + _ => {}, + } + } + let event_loop = EventLoop::new(); let window = WindowBuilder::new() .with_inner_size(LogicalSize::new(128, 128)) @@ -116,6 +144,7 @@ fn pc_main() { let mut buffer_dirty = true; let mut ctx = ContextDefault::new(); + ctx.do_action(Action::Screensaver("plate")); let mut rng = Xoroshiro128StarStar::seed_from_u64(17381); event_loop.run(move |event, _, control_flow| { @@ -156,81 +185,9 @@ fn pc_main() { .unwrap(); // redraw - if Instant::now().duration_since(start) > Duration::from_millis(iters * 1000) { + if Instant::now().duration_since(start) > Duration::from_millis(iters * 66) { iters += 1; buffer_dirty = ctx.loop_iter(&mut disp, &mut rng); - //loop_iter(&mut disp).unwrap(); - /* - let mut time = OffsetDateTime::now_utc().to_timezone(BERLIN); - //time += Duration::new(iters * 60, 0); - disp.clear(Rgb565::new(0, 0, 0)).unwrap(); - display_clock(&mut disp, &time).unwrap(); - */ - //DUOLINGO.draw(&mut disp, &mut rng).unwrap(); - /* - let iters = iters % 300; - let (s, c) = (iters as f32 * 0.1).sin_cos(); - let (mut x, mut y) = (s * iters as f32 * 0.005, c * iters as f32 * 0.005); - x *= 64.; - y *= 64.; - x += 64.; - y += 64.; - let variation = iters as u32 / 16 + 1; - for _ in 0..16 { - let dx = (rng.next_u32() % variation) as i32 - variation as i32 / 2; - let dy = (rng.next_u32() % variation) as i32 - variation as i32 / 2; - let color = rng.next_u32(); - let p = Rectangle::new(Point::new(x as i32 + dx, y as i32 + dy), Size::new(1, 1)); - let s = PrimitiveStyleBuilder::new() - .fill_color(Rgb565::new( - color as u8 & 0b11111, - ((color >> 8) & 0b111111) as u8, - ((color >> 16) & 0b111111) as u8, - )) - .build(); - p.draw_styled(&s, &mut disp).unwrap(); - } - if iters % 300 == 0 { - disp.clear(Rgb565::new(0, 0, 0)).unwrap(); - } - */ - /* - for _ in 0..16 { - let x = (rng.next_u32() % 128) as usize; - let y = (rng.next_u32() % 128) as usize; - let dx = (rng.next_u32() % 8) as i32 - 4; - let dy = (rng.next_u32() % 8) as i32 - 4; - let red = STAR[y * 128 * 3 + x * 3]; - let green = STAR[y * 128 * 3 + x * 3 + 1]; - if red == 0xff { - let color = rng.next_u32(); - let r; - let g; - let b; - // star - r = (color as u8 & 0b11111).saturating_mul(2); - g = (((color >> 8) & 0b111111) as u8).saturating_mul(2); - b = ((color >> 16) & 0b111111) as u8 / 3; - // rpi - /* - if red > green { - r = (color as u8 & 0b11111).saturating_mul(2); - g = ((color >> 8) & 0b111111) as u8 / 3; - b = ((color >> 16) & 0b111111) as u8 / 3; - } else { - r = (color as u8 & 0b11111) / 2; - g = (((color >> 8) & 0b111111) as u8).saturating_mul(2); - b = ((color >> 16) & 0b111111) as u8 / 3; - } - */ - let p = Rectangle::new(Point::new(x as i32 + dx, y as i32 + dy), Size::new(1, 1)); - let s = PrimitiveStyleBuilder::new() - .fill_color(Rgb565::new(r as u8, g as u8, b as u8)) - .build(); - p.draw_styled(&s, &mut disp).unwrap(); - } - } - */ } let mut buffer = surface.buffer_mut().unwrap(); @@ -256,6 +213,9 @@ fn pc_main() { pub trait Draw> { fn draw(&self, disp: &mut D, rng: &mut Rng) -> Result; + fn expired(&self) -> bool { + false + } } fn rpi_main() { @@ -318,7 +278,6 @@ fn main_loop(mut disp: Oled) { }, 6 => { menu.push(2); - ctx.do_action(Action::Screensaver("rpi")); }, 5 => { menu.push(3); @@ -327,6 +286,15 @@ fn main_loop(mut disp: Oled) { println!("unknown offset: {}", e.offset); }, } + match &*menu { + [2] => { + let _ = ctx.pop_action_and_clear(&mut disp); + }, + [3] => { + ctx.do_action(Action::Screensaver("rpi")); + }, + _ => {}, + } //println!("menu: {menu:?}"); } // clean up stale menu selection @@ -338,6 +306,6 @@ fn main_loop(mut disp: Oled) { if dirty { let _ = disp.flush(); // ignore bus write errors, they are harmless } - thread::sleep(Duration::from_millis(1000)); + thread::sleep(Duration::from_millis(66)); } } diff --git a/src/bin/schedule/mod.rs b/src/bin/schedule/mod.rs index b9aa527..918e772 100644 --- a/src/bin/schedule/mod.rs +++ b/src/bin/schedule/mod.rs @@ -40,6 +40,8 @@ impl Reminder { static DUOLINGO: Reminder = Reminder::new(11, 30, Action::Screensaver("duolingo")); static DUOLINGO_NIGHT: Reminder = Reminder::new(23, 30, Action::Screensaver("duolingo")); +static FOOD: Reminder = Reminder::new(13, 15, Action::Screensaver("plate")); + pub fn reminders() -> Vec> { - vec![Box::new(DUOLINGO), Box::new(DUOLINGO_NIGHT)] + vec![Box::new(DUOLINGO), Box::new(DUOLINGO_NIGHT), Box::new(FOOD)] } diff --git a/src/bin/screensaver/mod.rs b/src/bin/screensaver/mod.rs index f85f1de..e6fec54 100644 --- a/src/bin/screensaver/mod.rs +++ b/src/bin/screensaver/mod.rs @@ -1,4 +1,5 @@ use std::cell::RefCell; +use std::sync::atomic::{AtomicU32, AtomicU64}; use embedded_graphics::mono_font::ascii::FONT_10X20; use embedded_graphics::{ @@ -15,15 +16,28 @@ use time_tz::{timezones::db::europe::BERLIN, OffsetDateTimeExt}; use crate::{Draw, Rng}; +pub static SPEED: AtomicU64 = AtomicU64::new(32); + pub trait Screensaver>: Draw { fn id(&self) -> &'static str; fn convert_draw(&self) -> Box>; } -#[derive(Debug, Clone, Copy)] +#[derive(Debug)] pub struct SimpleScreensaver { id: &'static str, data: &'static [u8], + iters: AtomicU32, +} + +impl Clone for SimpleScreensaver { + fn clone(&self) -> Self { + Self { + id: self.id, + data: self.data, + iters: AtomicU32::new(self.iters.load(std::sync::atomic::Ordering::Relaxed)), + } + } } impl> Screensaver for SimpleScreensaver { @@ -32,13 +46,13 @@ impl> Screensaver for SimpleScreensaver { } fn convert_draw(&self) -> Box> { - Box::new(*self) + Box::new(self.clone()) } } impl> Draw for SimpleScreensaver { fn draw(&self, disp: &mut D, rng: &mut Rng) -> Result { - for _ in 0..512 { + for _ in 0..SPEED.load(std::sync::atomic::Ordering::Relaxed) { let x = (rng.next_u32() % 128) as usize; let y = (rng.next_u32() % 128) as usize; let dx = (rng.next_u32() % 8) as i32 - 4; @@ -59,8 +73,13 @@ impl> Draw for SimpleScreensaver { p.draw_styled(&s, disp)?; } } + self.iters.fetch_add(1, std::sync::atomic::Ordering::Relaxed); Ok(true) } + + fn expired(&self) -> bool { + self.iters.load(std::sync::atomic::Ordering::Relaxed) > 1000 + } } impl SimpleScreensaver { @@ -68,7 +87,11 @@ impl SimpleScreensaver { if data.len() != 128 * 128 * 3 { panic!("invalid screensaver size"); } - SimpleScreensaver { id, data } + SimpleScreensaver { + id, + data, + iters: AtomicU32::new(0), + } } } @@ -140,7 +163,15 @@ impl> Draw for TimeDisplay { pub static STAR: SimpleScreensaver = SimpleScreensaver::new("star", include_bytes!("./star.raw")); pub static RPI: SimpleScreensaver = SimpleScreensaver::new("rpi", include_bytes!("./rpi.raw")); pub static DUOLINGO: SimpleScreensaver = SimpleScreensaver::new("duolingo", include_bytes!("./duolingo.raw")); +pub static SPAGHETTI: SimpleScreensaver = SimpleScreensaver::new("spaghetti", include_bytes!("./spaghetti.raw")); +pub static PLATE: SimpleScreensaver = SimpleScreensaver::new("plate", include_bytes!("./plate.raw")); pub fn screensavers>() -> Vec>> { - vec![Box::new(STAR), Box::new(RPI), Box::new(DUOLINGO)] + vec![ + Box::new(STAR.clone()), + Box::new(RPI.clone()), + Box::new(DUOLINGO.clone()), + Box::new(SPAGHETTI.clone()), + Box::new(PLATE.clone()), + ] } diff --git a/src/bin/screensaver/plate.raw b/src/bin/screensaver/plate.raw new file mode 100644 index 0000000000000000000000000000000000000000..0ef519bfa0bd88b9b27706d6dd6c67d466f801c6 GIT binary patch literal 49152 zcmeHP2Ut@{*Pc)nK}AIYQ9V8M#m z*S71btFF82r>>v7{;u^uBpO3c1ol(#KKFsi+_`6F-Z^vXBnW-K{#67*gM&{TKibyP z@~`$f={wU|ySAdV_}-5iLsH``RWwB>x5gJac9T`gk2bwD0M|yMI4^_}B0E zU;OsVi(l^^XsQ1Nep$Ei=_m>S~kcC@wr_v_~Y=chkjdUEUHlN;y%bN$@oYu%5pp84a->EAD(+)FAL z$3aX=((BYz%CeHK9dGZ&`G>QATs{5A<&(c(I`P}Z57m_1@9y~R{4p}loxgT}#QDLg{r6Aq`=x8oFUQ;N9c#UN zq~-RZ#;)puC=bW6AIc=7sH?WJI4R;vd&7fM?QjFm_fPC4-8tO& z^TGPt2WoHZspu%p%-rFwqoOd$a2n(33e211?`YLtn)6df)4ij>(tvYQFV2Sm=epbN zH9zgI`e|Rqk9$eC_7JZ&74F5y#d+9iC`ga-I3^!C9aV**n4q49;-3%J-97*~SO2uH zl7jQCwz8YMOK!9j-Dobn-bA=qld~%|G#qQLD6wSn;WWlG=H}!GvNvnP#a?SIq2PS8 zrI>>A^Ole|uj8CAAp~(EXV?2mSNp9mR1$?l}sq(asI5*(P zIA>p}$-GjPez`L3GAZR!dD1a_L|Le_`=)jLv!>IJlk$oc3Gwmtx1T&M7tZDOx6*G( z4Z2j7ex)j-7v~DVIr$ZtH>bJ7XUG8vhW0RN`C znwwWI|Ml$2s~3OL`QjvLrmHBG>tlBe7jdzy7v~GbvFD4TdkP}Y5hBjzhjr)eJcA3~ zpWvD4ve|64+>9x#^uQt}D(vp$SXEkZ>Gbi(zuf-&KfhA%$G`kc4}}TeX2EPO|IOMB zQLbn3VdwJ00q1Uf$l2WBvpGR$vI9?N`JYVpZ4SpK+UpyxSV|8X{PTG1%uP#k(oVIv zKDgS`8+;h-{`ul*dZXZ&;lm5GF zSNVwaCs>1xa!bdQHq~?_*v_! zDn+_G)@Q|^Zz0_|(sJ+E?k~IB3Nwc9Xu>=doWN66Nm3&+lg(XKsL*`*ZtUtd?5f?{R9YOAi_Mqq)Dl^{cqZEb*r%{C z8?TUzveF^>TX!aTp33k)ojJmNJk@7!j4LV7E){F+X|P6BLU0b}kg{u%zz)+~FU%dU zBU)=M-?CMq*>-uOl^nrHGGNuhRRYu4`pTFY>@3>Sg2BeBg|0^XBkYdFJM|izL)`H6 zV6-5G9mXy=yJfX!tt8amBRPJKm-?qv~Z{X<|3>Bww{E{9YmJvwnu+bj-FT z%n`Dz=}J?Q6{iNvux}G#)#YR6|0MHA(dYM9KO@rZ^XSe=FTknWHgm@!0nDo!USI7SCmRSSg$3Jb&P$K}FNRX2aL0@UkzPMb{~v z;pt4^r#sB%JZ+E%hVM7WxUIbFmW@gagEzLva%ru}1Xm@#O1w#0i~6C*(8t};OTZBA z_X?Omo(7}Jmh!M-j%<~wH=W@4*O`bPwUh0K9z!2R`Ivt$ld)XGMf;Y_B4*!BvuSG> zEd&0YlK}r36S3p=vfQH!Ek;<*E%aJIi!i7LPs3TXHH?-){v5EDYB85&^u=$heUq8Q z(XBG09P?Z*Ov*MsS|WhIhry`u2WqVrlKZWsXvt2zGEDG*^%#7)##wJBEjS>5yp2XB ze}GzpsrX?V>6xS3o3x|)3d_grWZSmTbt-uH!CR{LIew-o!|pvg`2*d7Yy=emieUJz zzv-u^9pxG~_qSdcoslRXlik`r4zI8AY_rvUR)kTS(7xGR;*gE>#7+yG*(L|u{0qRL zeZ@kJbMvY`hnEVx7H~}+72nFwVLR!tY?s++d4qPGUtzh!R;GQ_IxZE<-!BSLwL@?; zljUb;sxTJqagq;F;U5j1um9a*ec^7boRjRR4sR5C_c1;t1(@r14iXxr6AeoVZm@g+ z{GyG*6I=KIAi9E_UG}nYgCk5QKK+_03bW+83D8zXS^NNEgt(`5m?UF#ma+WUx8I+Js~%dKN1Ol7GxG7vf-oAYR1k zL4xFC-q+{}g0oYiFAPf%r`|`U4nx^>!)MU)Jp``gFYRXw4f8Jb5!m_7;}hzMS}g$6 ziBh9?I@BT2Q!o-{;4Aa=5QH`$e8B4j3xv-05c$zpnhK5M?dCx)z*@aeAe0^=)0hw_ zpi1Mh|GvpoCJY4e4%$fbv5(8)uBuI9^h}V^HlP6^EEWt+lW0@n}~s5HexeM12~9vt617Z zW!mNZrEm5sp2-qd6=yhUNZ7ChRR0QIhOMUI2MPQMHkI_aB{9$SIw@bsa>I-qq%lK@ zrv!W6#;{(83oL)g2tTNjg`#57L3%bYYCPRaXCQ@vHJe1HpWP-m9{5oEg7m}* zhh<802RQ^nZNq2*h7Cq|g2qDnU*uxLP!sNw3z)mo#eOQ47MR6=$OXL*iw+`)ZnJBI z(amJWfE5QetIzqrU+6x&Qb{h7x!wdG$iFC0% z55}Y}e*F^g0mnp~O3h>`GY|n}a>o>zfmp#R@3WLT?YPWRqEGr`U`sk{fFKw@5cs9D zJ*8Q^9WMxf+E-*2u^dbgp{*IQynPu(S2AoULe#=@`8=>QQ?wR=^GM040{9^OA&xg< zzoTqmvy>a~2Pp&=yY3=RxjAg2(^{fUYWF}~E2pmB=8^rR?RrCL~#0_u`FfEJ$ZjgAO@xh$l zvt?=F#wBKAeVo&wCPJ+T76P5VL5SY)i?S%|AGLC^TjxRuD`t23|SUGh8daV}^eeNX3{+v$%fFb-r?Lq(wx`tJt6TeJtL0GRCHO90Ioy14q z3}$35HWN4mmcVu?y+;vtsPMz2f>(Z4ro)d!Ux}j!Co!n06J;~VrWll(@?3TzSzYGq z(R*qX1nfa;X>e?3eBIv>(_hR5QW3Vppc5ZhDKV1;JTHhtf)zUO>7X^;*%Bu+#06&c z7d6R_eNLnd`Yu#%lbHj`3$|+Eh9&eLLjq9)uM}?-9*XSOQ(wJF3??Yd`8h;9{MaB0 z3hg2HnyMuzL`NVRyxrSn(qM4*3%g~|mx6)rz)*LUW9%n49msY9{XxRvr#!AtW7HRb zN@Xaq0*yg^gCL4nMOWAsQeZz6ETzqP$qTV0Inc%bUpDvfRr6tZkh1x**ZCVp1c%2&qyq_2-Yjdo|)nMrH#6eoP7w?*a|guz9q{md0c-^bi3nbX*Uz!udB)!C>%H2Q#QgMtwS(0%TIaSOwwZ ztHhW@9ZjdBd^d0XVzAc0W*8-%p!wHHk@T*3u`<^B)8ozF`+nSpcQz#$k9r3NBG)9CfcMx3IH-puy6KCb96&abxy z@?SeRN%&Do-u~a@8@wf>wLEMXINSnZx^Yd%FgmK?+b`i~#|0|)V^_&V9Lh`k=NiEC z1^)|9UQr1KoAZDRK>bKt$hSlflab_L`y;^!&7(K+M@w?JGQ`0^cfj5UtpVE~OmR5x zJz{ia6(4(&=E8s#gNGJ}>u=Q0gg?dVTuemXbz`gJ*3gnXgkRr|)1|GUl)?CcU!hSI z|CkAd^M_P-805_i8aJ+X8~RXysvY{%@Yh21*xpKsMPs%H7EEP=1El~v1msiK3I;0k zL5L4*SBTQbt`Qhi2`ccg;npvP@C#YX_u16_M~o1J*9KOOvIcMQk${#W&--&uZ@aM> zzKWD8eO10!ryU>cw;Z&K*2u+h5CXn=1W(}`VI{twJwCvEw;PJkLm**D_PzMO#GzG! zpUHTsqu*1Jt~gpL#r<=ug{t%?CivWh;gTp93!EYV@JYs^%VvM(0La=vObpJv1E_!X7Hm=rpEKazo%-P^O+4?RvVj@uil&7VG% zsi)EyKE6ERpdda-T4(wc415vzdZCom!rmn)@>#(A$wV}eM!%(^_XKn~9Q_>Mi$C0Z z+&^}NRY6bE(T!*XJEbyK9lF2=t)zc0kSzi{`z4Nnjp0BYfREE%JP<}OpJLZ6fL#Di zG`tH*6Nmvq8QQ}a66rV8J8Y$4r?|_1cKoTsh6FkX<3^f-0J@*livwJ9XRy3FUOxA`BDr{MoG7da>+ z03QlaL$E}=+$>K!ZK0RW0zL8&==uY>Z$J`Q5rT4X+H)=&2F}tSwv`4pPFuSO+7F}yAVV4gOiIW;!&y5@12FF)Hw0t@l!sIw{L@e^7U>O0 zv!|J$fAGC>0IsQQnBNXqQ!uCf3qr|ey&$D8;rZ;5PO?J0AH_ZoCuV<~F#IAJJcZN@ zZ3+fP2OLg8p8EG{1iG8pTlrTGlIKV1K8lo%ZZ(-v=)>RjD|xg0R!~0-sl*eZQ|?>t%H(1K4XSI4Pm`73qg>peTNwJBALVj~G~!?6=_ zI06dB54_Jc1w%>7D=k2NTBy_(-6um$1)sLi;e&w4g{ofp2KUp>tw4c^3B|d{JwIx9 zrOx!@fQJ4Ds@7ML7gFA!a3L=+wr8S-?zZ=dC>JxFy8yKgI}YqC_|7ckd`HawZ<0Z; z^Lo+#ISyGV^wOEbj$Yw6N0KpI@lm5K z<3sI1TtFOFnHK7S<#zcp?>PzM=WfRK>tY}dB~B9!6WruCsPaxF|2RWF z8RvdIu3tW-E>y@s3jLBaNH3uJU*%7|-}=#~7^*L*f8XN-Zpfnp)*y&N?dkniLchU$ zZ65_Vd)?1|4iR-1yvb*NL{b?F6JXa9#rlH0>=+D&m6cUWXlAsn(4s|)mXI%D@&(0Q zcgY>5v+sWLc7Zquy$4C?pf}1kM{5?NbQ5&9!C_ftE;Q3tmxX6+t}Dx zTT@d_zN)IKNEM{qs??lli3cex;C6NTv6tD+@Y$>xA0MBepP!JB;OpyaV`CFwtFSLe z=dUjNerWgmc)7-eV&&35$FH`fp5)*Hffjs9`F#O;Uaj)38!SMl({1>}hYz>5wq~Zp zo~?3xeFh7*dZd$Du+O$=U$62A>qzZY4Nk`OcA6EIs#RFMDi@<1(=~2eFpj?FF=;U& z6(MFMGt){_|62c~$p(d!DylD@ zqEtLPge3TwxEPirBbIk1aV1CLG{;m&8@x?eb(lTLKA}7zw>CGiDN&KAxS@PQLUlq> zc~PRTRg5%C<0h%|q2{-v&0pc1UgtTzFY*3R;QFD+{X>z*%PhM)Ne<^D?TC6($(uBb z>IzJ&O(n}Dr88yHs?y9V%mOO|t%z1>#MDb_O3x8`L|%di(%jEFZ9&`>X2pPfON{U@ z2-iDWumQ}Z=f~`l+?RhVP}4Kc1S8D-l3BPi{@WEI9VEFZYt87o=*+^*pvs{9lKfm^ zZv3wJp!%Swil{j2tomnN{xodTI^Omq}D}3^N{Y(6ltC9<<3xM~$%DrrBZ3RmNwTN1-^{%;1xS|6^ zYf4q3mZE}XsM<{9e7wu$om(#Xti6-A{bq*O`B-evPV?)j&Q}thPJ~!DyBX(NtV>!a z9vG?^LE4^JmzdO$gm1+s)+ah;Vq5v=0Os!y>d@8A$W8B1QwHQ;f&3w_!ZA1bqlE^! zxw#n`8M}Ay?&;|{d-iNWL4kzCfQaolfHU4C)zsA5+S=k%!p_xcw^fR@=P!+mu#ZfS zOm0rzTDNsm)u!x*?4stP?A_V88eG)w=(M)<^qTbi`g~j&F0VW%JIFI$LnKBFrAV=6 z>MIw5Alj)DpJbKjVV-2M!driu_ZCifUwQ9DjMfytdcW}22%jb&^-A^F!?8O% zb|$9kzeMOJ8Gl%UYAdVM)YO6%E1r-=&})R=BGj^&D?BU=Fwf4;uBoYkC4j5FyEC&NMQ2tKe1SB~>D&QK7N3a%UbfuehqXsImy27B&}# zR_#btm;&Rw) z>ZW!ffn9RTlA?CFRJqJ5nWa>v6z(YSjLhx-C9lE*__fcKO6j@DsV!+y_^8OJ$YAV7 zUsKfpEY``%DI_GMw6yfxxpVvW?Q?N)0T4c>nnnZ1|Ki<1gvt=|KnUVuJUl$b#l_v{ zy7!&f7g`h=QxQX`Ar!S0l@d#F#kla=@U+^rl=76)>Qb*(uZ)I_pq8Mbn&OzMXsplT z5Eh6R0nG-l?hwFyS zb?a~|SK`&waGN$o*lzLi_5vR{*n3+*fWN1w=kn#t0d_d*0X`VSxIZ6d_+RkwX!-=U zDJA0%s{l6%p*V!h5SlUv!)wcHo?;$X5?4?R99IAmdrSEiPoif*VL@?8aYc$# z`wayJ;O!S=+Xfcm3POh#ATuXsk2DYH2!tEZ@9nbhm6(`lVPOFb4{8f`E3gVAHR0eF z;6HRmeKgqoOYcU};9rXn}TG9)k{?oj8_xE zCq$HA&saZp#8qVGzl#7rzLbk9L2uU+DFBA}v zk(JdqFu=NE1HuBrqQX*AQgX903vjuaW$EA-gRw-w2fle2}Fw?r$$!NL;6F&3VZ5Lk7rGF5C?^XakUtkoOFxjW=MNs#3kp_|m!N_ym!M5C zLU@Ey5Q-o#%2tH5;cy^A0-T(H)f#nmOH0e`+qVONv9YmWrNd_FcLD5B4;KX7C>Kce zxVX58hzK7aA5cBgQc@t*MG=Cqf+|95$QH6PLU0^l*%0`Dqnej?EkWi3_;CMr<;wG4 zetC59;=6zT>57i-hd&X6sa8~M(9#t;f3Yj7(#=R>w>K{CT{ z7Eo>w(I6#gZ>XVEQW^jc0N@%3=^fKL&HNsi}^W z6I4J~Ow2_Ri57nnH}~~Dd*1%@5A2UeSFaM~$=^ z5sHMPZU}{v6$+TUehB%HSIP|`$m(MevM0+oI6?}N&;%hPM(}5z0O%vMfFgo0m{Tb! z0DgB?*0Z~J&leZd;{QW)GawK6zkT%z3g@e}=Ouo*!6%v$e&%ZvX_X&cduW+ zd;9imc6KFrpa`8M5MDlh{N(oS6B!vKd3mr-FMi_xYX=UzfBW{ImoMS(g~rAY@884P zJ$>*Xk&J&lKmUo^+B+97CTVDlE&g*S5cn_^a3p(CEiJuTTMJv@u($VLzyA(A-v|tk z(6y$fE7jEiEL{J*cyYg{=V*L<>FnA02tB)ZuRS&vhr#qTG`xHB=FyEC-ObH^J$X`O zVG+;5a^v`M%3B9YODXvKGc)_Juy`OeO8F1ke1csdoc9|1|jd5uKe6;qm8MTccQ6LH=iG zY6AX;h(y>9f84w0{)zvCwY2;c6u`e@$o`r3jYB=u@F5lf;8XE$Qdh5&lmz?_IXi#E zAE6_usZZ|S{qz2P(7$_peF-8W6#TO=n4CFtDEObLsmYd;>mU#w{rF>DWF*D@4B_H> z^6=sLLx+x4R#NcyTej@p&6_!1UJT(sf2h%a`}K-sLzId?)&8lNI+cn)FhB6{rKTpp zzuCkjf9~9V_J1lf^X-!-LI3`6K+q;`cELpMy@ZV)$jQOd?f*)UqZtzg zc6Jj8^w|Fp{{)%CHtYx|!$a`&!D1;T-^1fiv3~&nTy^!oo<0Tr+uhnq!N17CAzVNJ zWd51Gdp$9j;qli&2<&0b$p9{WbA*lH%?SPp2;p>eju44eetv*|*wm@v{QO}&Ja?~N z4dCYo`)4Tp4G~%eU;U$RRFkR|V1grOVZigE=-+|zpUVG$KQ;aa_=h3{{ujufSPhL~ z;?EF4z>)Dt)dLsdxi}m zi;#qngbcDEgprUvAnd)h{}ZAyfZF-?UEy<^p6AK)JomZZbMCq4o_pi(erNtO6EG7n z6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n z6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG7n6EG9_mm{!b@dDfLwz*t9 zV0U82CrjV?```ZbFZYW7i7zzk#lHvnp5W7Bd(_CGHr#Lrez>E&ucfS!o0SypzI^F> zKdI4w{mUO-oBQmWufG7FApfL${|hfZY`I=Qj~mpXhdW3k-PQ03@JBicBb}ttF7jx1 zWxE2KaM%5%S-+onCPvyuI?0p#i6dPG{*R3;efR(*<)0Z@Azon{d;4e2$dj0RU6hw54wH*z?|8Ce>(HO|Mh?0 zdwb5N^^5lJ`fT-=@6Da_|DJyRzv;IZ&+h7!=Z+1?0sh#4bg&KEDb0{`gX$|iIOU$r z)#0s8NxkZ#(XL7(|A}5!pN`h9Q+IUg^6;1MAbuBb@7!?n}OLm}o?k1gCOTM(Z=+YisVJ;et&dA8PbLWnelhgL?+dus9!?)j> z=i<1xB+Em{h-huj>TAId=%{^Kf~+PMljD5UYURHv=f}SGie+!f1>AGO7r;^yJ-RD>o*LgXx(dRE9Yh%u@KV9N>P(mCe6)^7TbN@*?NB$o!1wp>>;Jnq+OH$Gi(+uOPU}|wv`FBwZU5(kt*Ym1s0J_Fr~p^=fUo?cCBTeCt{Cu**)t*3Ho$W@gJ5q7Mb zKHkfm=&hdUW7i2HjPMOYbnb#mVk((}ub?w37;G|=P0UKgZvW6ozGVIDcRrczw(xn^ z4^7Jpt_xpu`)HQFESlxEc#iwh*Z391!#%?)Y7&DD{7K~m%#P)z z@cov&IF-Dq79PqAUr2Me>}XEyQD*cg(t6}6-Lm9vSz?zoUeCWdrn5OpRTt`dVb{EQ z^L_@0-|`lCLt9(hqN1Ya=H`)+5q)?5{`-6P?x~nm-rW#cd5E$yp{Y1mn01p$b`e%M zlPU_4M2dlbDXFrQM21p~E%*LrZt0qo%0gg_QpIY!)7~-!FwJ?Q$d33lD zJ_um>4JQch*j-#)h(uyrTiboT{{#nme{gtMp=kkU0`^>b z$sX@@wyQa#TZ$DVM-?BL7nb!*dfG=x#V6y7PRAA6#1vTH&HE}mXLd2_bVaVmG;US- zx4;YCA8mtCK+Ox3^E~Pp_FUR24$WT3PUBY>u~;}NgN6_BHS!0~<382xfUEJ_v^d$t z3KMfNA#zn{!XLx3|K|?k_YYP1yTsx>Tt0_e%jeZ_d3*++jceefwl+j|iuL^4Md7Vd z{ABCy4-XDDHZ~?DC2iTV4Iha=@-N%=S^ z6-YmCw4)8xWe?%-m)OnkWV_BXwtAX?L~T|HQt=tdo?pCU)B?TeCIq7Q$2#wiws$ne zbTtNaH3as^vU*jx9woL@lGjofuH^V~5>FcW=dPJ&xZQKni&4T`M+uP!eM6G0dhnr(Z`v1^&-jNgAyCbC@$nPN!rFVJ^!X~Im3@%npb_>pM3U! zs5p0gXmE6NR3H$9hlfKb^$+Dd?corL-?(uDY`_q-0DQ1^kxYrFv2rkk91JlRt1m|W zMad~fG9cuhe|cu}4QHx(2@~T(y*i$laf_DcTzKbb{+$CnqR&`&)xBXg1g+ij-0r5p zUTM<3v7xcSfgYu-mCu$DuyyI-lq)-owG^&8s`m(mV!rn4vaIe@ltBKB}q8 zhtJBxkW(Y`7MZ?7Wa|Hv9C+1uyHUVy{gCW!FGxE}bK8d9`nK^r2vld={*5WWHOZe zNikg$B~81XC)gTbv~@@lE< zs$$~ZG?YVf!3Jc(W~Ak7@PyJ0ug87y%I!~Phb(&uO6VuEqduFH_~k2^t6t4t`x<(~ zgMijpSNX}kGKr+OuMaqYBETBCT<*n-7k_o^@W6N9eK#c~rL(ispz-mE38_khB3EUh z@L8yG1PV_e=GHTAEBOH`zMqoorQ~|+3(rT%yQbv%(gSt_knj~R$A9t4&E@)$(QUBdtzb&;D9b_YirM)JNGMU z;rjLK8jZ$49-a^6i;0vB6h2cAAD@p#3uw2yl=!jXjKHE zCD zq0=mJnbw4yBNh3_35X+EL0fOzEWi5cT+_F`vFs&dMfvt~!ZY;!Hw^KIY>XYBk7*Kv z7Gz!B-NwE^p-?t%-1rN%0AYMpRh8kHz`wn#8$)5Fm6oNKmH~eRBCp8*8t&v4!tpN| z{%&=dv4X6#;_{1Pnlqnpo{6!mLY=NEg<@A#d>Xs$oun^cF>R4izI$pdIrAJ7bCHTX zTUm6vEZZ8DvJ0QJUs>&;;dvvxw|RX0lKYaE3vDfo1b$GE5bqw$3#wt;>M6OT_3=9}-6~+Zfcl>M>T)1!nLQ2D8 zvJ5^mN-#xUZkWyQJ(dIZ+Yibvt}F{Vh)N7Xrbd^>-Nrat!j<4)eHTA*PUN@sy=2d? z3uCrn)Av@Dd?%s1sJWg^q$?gvA4KxRFh_>ZG5r2d9$V?OlY|qW@e6JF_;dAS*Nm&% zy;r@i$N0f>@agr{y!b2MFj1FVhT}_f9h-Ydmjw`A!N^3L4&5g|xX{)Zy;EpCH#z^JJ6V^+2 zZhHIe`9C48ck9-z;o)HedsZWCh>7W){k9K25SW}(1mhE1Q+3@<4s>W_! zKyq4FU2uYpv7;BCB#ym63l=nzH9c|rUN zXL9jr9O5u4!-|+^6J@u?^i_Q=p3ge*a)I5PoJ+G|E^{~e4`r4gG?UIM*q7wI5J?kV z+C*223GI@6HUGMjGYXI>`-9MM zfBy+ z&Lscr$+Saik6h2cttqO3evOPgU6ykchd6@EK3JY}SV+CrAxTlN{cc&Wn4*HkFTyMj zS_cDh?uD1j_I{{jx~O^XYM!f#>#S$azO3ST4Ri`8#s((F2Vih)sgF=pJ4zVm6GL~r z@az*8>AbwW#>U1BmOnf)QbeF6mtc+j(@Sw#XlyP9BcO%UW*>`6`b%WW?;}%xA07Y4 z)WGM8jz0<#W|D_9;DT~i&kI}evT0i$E4zL4e9*2%+1Gb*N-wmEi+gnqJnT(+zHc2V zszXu)>oriu`Wy6lOGy5Y_4UeeYFf0Y(7!IlMUd>=j124$rVq3t2U<${TZ((t`JJ-# z)}~mEFrvLVsauv=k8or7SXBod5hR>z%yklAT#*HPGxJvxN{-?Yhwun%Cf1=-i5(ki z>5`?lHQZ#Bob%o|>BJu9G46cwvayZ4xPxlGhnnZ6;u`p00sd{x*~7i^!ESMnhN7(t z1Ng?09J=GNyFQ7KPiQV!RBWSCFby>=CmQ_1RnU^ID zM{(8pChEC{$}_?W+d9%|0qGQcHd4+==ne)IKrcA7=P@g!R4UZ~A3jxDEs2=gR2|Y% zf4i@hHqs{_9n_BWD~Gxp`&uhInv-=6HwZ-QDf}TM%X$X6cb>6z5HO^CHTT+MhusgJ z^WE@%-1%+T7zZvkP+f=U)m99)lfYuZy};_Q9;ps1B;70y_lmuAE_l!StIHmY#c}8N z4Cv5(nxal=W@}?CK!#AWnc>+)b8VzJH&i-7mWS0#~Q` zts$l!kW@NIDHp)h!M#_N9LbN{hD<%c#oO}mC-~(jdH7R2My`N^lQvehYlW>UzM_dp zLpe+6=RphD%!7aZ^Y2Z2fwi@@(euEPgh~*u=3nhmm%|#ZQ7Mmv`}aor6*^H|K4zm) z1qp@k(@-bM_AfECt9bqEFp-?*UaqZsC(V6NW!9y7vcH^rTPcW8))u_m=CGp#nZ?208_!4pVYf6!|xaypNzl7nCd~1D>^WwS+d!wHbFjJ*6 znNq2m%-!kXF&GS&v!B+J_16?9S?;rV_mjo5wtqc;!^&5YNTdPp_;8n|)*rlCe;fM| z@JR_)T45*|?5OEhmb8mwAxLX&xKYP;uC8*Z=eX$_Z+D3Asu_WJtEB+{`c$(Iu=t3Y z?Wh&pk#K^TxXYv>TVkPYMe&)+lCu<~0}Xwdg?Fo?1t|ovor+xO0_DkW)8M-=o}K7) zu$h%HtRuJabH&A>+&hjm7wd}Cn~BHQRh+S4`a3n`XKFdj0i9-IxN8Ekrh~H4-kL!j zzD<--o9cwwIN!+JAm~H-uiwbK@G@k99vad!QbB;OF^o@uiHr-Y_#DpiQT_z8^KJCG zPx8H2MR|V~=d}V6v97A*kesFW?K0+tYP3xgu_;BagP}^{?tiP?gOHrh23~#CP zYZV5x3WFv`fg3P3ffm}EZnrmub%??tTi7YSTa$bycy-=zlMn2?ZX%REtaQWJw`7C zPnfUcXYub|F1PyZDUs(S*w;uWH*jv*)n#1eC0wfX+=tz>a2k2Tp&=y_vEt>T!0q)7 z83aafdBxE-Q8-KiTI+8LDqLx?hm1GEKxUNDJKoMc_Cc!6`w1S)C zSl|zHG3Wv?lLZgs@9z(8=giTijSn>?V_m>z?(6OCHCp>%SA&WR0hODY@2=rr)zo-t zYrVCQ3gCN7Snf?#PW9Bw^_0u?RHvpYS827ErZ%Xp@ix43hbRIYaB^EatQxYwZd>F%C?T;qmL4`MKB8Vs0vs}kFul_l?7KC z=yx=Y>AL0|e(aUU8gRy{S0h)vd~?}Lx0cV2`1Iw3FJ8%BH4i$V!M2UWW(shDacsgw zU)HaUwlfsG5Ct!wz3C1Zm9{Q~U3?a``+dWspdv`FPJ2$#js@W^OX=VV24jw@6!q+Yl&BAB`1k_NB9+L5Wn*&SmkUcQ9UgL8hD+r4<*}eyQRCwUuAxWYX zpQIF@Q1bnot9&y&cLrE2^jtREcgc$}pU;7Zz!bhof94p-{$Qcb~;u1qr*5sk@I`ePHxaaOK2kpK3Cio$LZ0GL{RaKdW1IqJ`;j#}wZqq=% zTLzNZ8 z5d1?93YUH$aQjEoo^WHs(nuRCuSG9l?X9ak&XLbs5{@q?eD?`0@!Oj6Q`6wXp`7h5 zm56}9aX}UufER2@!T7!j>wX5$Uh`z#7Ft9 zYM=)h4cI6&vu`3IEebtXXRn@Iep>XL+sDrZZeOV4`B9Lku=-@zK^oE??7yzklZif8 zS!h#PcpN^-1;>fGhoRNDto;zcStGX0O2ozNuC&)j{R6zr$K&4U} z;~&5qeB-7mf1^yM(I3Ls|9_}Q0{m4xy$h1FU6G}6DMiT0fSq@JzrbdlZm0^B@nE4O zOv(*yqzAI`?&!3`dC}WZM;0f4H8;TPPoc@rz#>Z_Vp~ncC3J?Rlp73%T5OBYIGF0W z;f~Gn$g`gzZdyQNC&^o3GrvWr?ZKw+t47<>BEN;~jVT|@runQy8=W`>qEndF4(d>S z+LCT%ez!8Ozom4zvvO=ebZ@K&67XZgeK)Olni4aWp<}{)1fGok=5^H8*QQJrH_m7H z?k|h6$`0R>e*2r`koA$yp9dUx&*Rg_Eam%Kyr*EhYic|p3?A$h_UWos97sD{fq15# zY-g$kCi-ko&m+Sg9UHUQxy#7hR5<5&X<~9I=b;wvcS!S%qi_?`KO-$L!sqk&pf#Bh zn+xK1AXD~WGWO%Ltf04o>nP7TM94jiJ-j6O+$@*~8)CWeoIfEmcX5eMliLYm$r+CR z+urwh7#ewg{tC=1F&X>N>3dMAyD@2dX~o}BV=Xb$;7|H|&K+Aw;K1nICQfan`}6RQ zT&z78cdoI@r?oL2^aAs>kuK`Qa7$%Dt|{{=@<-46oc#OU@IOPe8Ik@Bq)qbAO?65e z=a(E?lBjnm;B|3Vl$=A{vXfl==?2Pq zCC3FQ8FD_*1!@VWOa}r1HRRqs{nCu#kHh7eGB=g~{MWzL)Hgo7Q2+mX<3p_tcMV+t z@*DDMS0?&2K3i|A;HYs~mSx!n_}1k)5BOu8zKTpS2GV*h6l81>Gp}`sqXc+w*Qv?R z=<_QHh=YWjg9L;%DfbYq_yi@<3TrWCrPa_22uHqX<;Ox+LBtGV;~d#odp`bxoOcVd zI=w1GG7a*X2+$5_K_$ewEqaX6f+7NZ{`4@&e_$bDna>m-n&Ff-&d;-7mJqZyHehv( z|Eip*t<@MC$R~&?XQ4pEVz6+C8-*2iER2nUeFcnPsrNq@;oGW`!-i`h|2aDR$oL_R z?{Mj|Df4Oac^8j?;Zai+z^2xg`bhmK{4fww@vhcWE-}!j2)PF*`5yoWg3Yu-Cd2f6 zXLi!6sSSK4FL^U6c^@5VSD9t!v-(Zf_n*~A^$Ta^g!uP&X}Vf?asfh6d951jKuI}> z-8p4d7j`m4e>Mk}Vl$ohDEQ&ra;IwS1vbWB%na;SgDzk?7tqvRle0Y=s7~}!J5=g{oTwedoI_QlgQg9P zLcEH}uq;orE|1(py1SQ_c$k@C&nt10vO)(tc=yKp4Yf>+3}{#-c&lZm93YH`7}DT9 z+!nn^Mx0_{F0gUuTbi=QN80;a%M8pRhYvv`tR0K!UXb(Qm%{}~HTY22VQBO`iSFxg z83#%e_vMCKq}^Q=lm1p%_M^=|p>BVN02OkxrnQ4ymveM-NWBEp+xkj7ChBNKfh8WX z50$p7Al@P~Vq-$c>f4^56vpq=+yA8TgO2$46D;&mnB9zxJhFUfW=H?fu`_2)X+Kup zfBa;1vwE5ez=LTd6~fAk@@f|tbS9@`J}@0?5%}t-!*%|x!az-p5BNX@$B9C;OwRi- zDr;^EVks`)l6ZG7c9+RY*@oB4_ADfy-M|X6=0%^WO})Vh3m~1?JuQ0=kv1e4jR4(0 zo=wfS<&-&gC@>JE4|fY7b>FQ>)7D3d7+$qRM-J{R9eIiZ(Nz91$lHJ;s>twwe1+i& z@vduNkr$Qntzn%JCM@|07KoG$*=cJL@tafKx20d)l(A+?R8O+~T*iQ`!X-!)&`J)0 zoukutCEi#Iz=K^r4s==sB|E{Ro=@m$Vf1Lo?aevjDhDR|C@KFyOEc=;#1uEuGdz}s z#y=ML%#*j1vsulWq0tAc0LG5c-_ydY3}>LetEV_BIPTh7A1&|~Tn80E(K|rS6^O7Bsmw=_gH z(%kuY2W-4`vipW;$5nAx))d^?NyR)ZI|4ffN7xee zstrGOIsW~{9~V+Nltx8+-=OKE^iR8gPp7G`EcMBWwjkymsv$Z^SZ?Z?YcM(}*cZVE zLKs{_u!TszMHsB0`a<+>3iijys12{1u2H%zd?EbYvYea^dFb6TbtNo_^eFVd8UUN8 zmz<8Y{oL3`^uogD!PUoHSS_r$0qb0bq7+0{7JWx9{H`2v7@4%s2tPM!drqW9cKFt; z@GW%Yca5~mZTg(U9sSaVFbHy7Ep`5K&eh!LZRvM5!j^!N#2vTXmxs7~4Ddr-Kdz@< zRW%efanq~Iy&)7S%{(U((kCYL8|jUI6Zh_GdWY(DJ#K!1Gwu8-XRK^a<7>nup-kM` zIet&StJCxk+>t_3TaxJ;6R;{HY!fci5*8G|^??rr7sNu_)RC`fxPGM5U;P;1Gp~W1 zfRSq0g^#0iUV||uq4?93(*3E(wWYW{%(9cz;uD0dLs93xge7C+#YVw>@k_szPjNVatAAv? zxwF5qy)PY!eG2L)edQh;N)$?oLYY9@**!FBI)gLl0{TKno03J&B;=izPV(1x0nQZ& zjCp8#iu0zKU||&ub|%9T@Y6G6kWz^JRIdWJCC}f8ni9<#2KTs}1;pGVhJsBwl<2a- zcjH^GA57osOw09v(Yd`j5!^l$Y{r4|WGmd+&u1p_^sl<{4T{s(Qi6K}&4pZeh=s9J zaIR_v*TBtc_+GUnhqBCX5qCF(@f-Nx^jL{0h*ZfNO~ZQwnUV2(>fRwB4~4+3d-ubS zo&@>n=flzvz`vqiUf0qs?HcGE8JpbTY}ys{^7zKPHBU zHX4)C{!3;-(q^WDOwT~BAmqDeO`|EJ9ESKkCVDGAc5g-MK}z;Rl*NKL?=QlAK7)cuw^H#uG&SCB;-Sd zZ)l`m-Nse68O$C&xr&ytdL8SHa_lBlbVKz}!7X7Tje^>aYaHKobB;(}JEhMyo|k~*|?6XVlE z5kr&5VH0vsKUbzD)yvoloe@4?sXOiXw5jfofp56x&3E2SDJ=&TR5fdiDlk+e?;eEi zFmr%5ssqM|!TxTIq*g>M;6`~7j<0@t+kg4D=!;)gbd!o=7}UyD-9Wr&cuoG@Ri>j}c46}WBh zOvyt&&LRAGy`bzqp_QELlEgug5qwCeR^g^@-Pb>A;~VI$3rcstgFL*X%;PXM&cCKC zN88MXJrDQw^QOmpS7;5ylYm{^(pe=^8L-1Asb0=gwHqy;)vWyGZf9oic<#knfl-Ns zI_b<_V5}O(9a;B4`{2mn81%~@&;>LHdIxA^bfB}pUD~eXwn-{G#F)1F+}4`J7G8v= zIz&?8QJw!CDajHQu>%#c{XvP`QEDi6cOaoe?SxV?S&E}~6h-f(m!6;e=^Sk4jP7WP zY-_k%k$oPQbeW6@WTIjPv=VV`rA8*~ZdZ?v4BoppC1RgpGWrwH#ap}kh3Yn=wHx7+ z8x*zLE+YXFzkciPy))_kT4&CC_+Yt>FcuhwV`IHD1yM(zqN}gHzkgtOXl(p(J6Imu z)CVVFh?{_^F3fd@2RnK?)tzm!_7-ugQmB#fRFZ0im?3YXL6J3541z*LS2nZMQm$4} z*WC`gcUs3sIwrnAbulTi4Kj}H!zdevcq(ejmL8-CorwdK(J|x_#Er+PW@Ddzx?`xC(q=OSu9zr(F{!A z|EJ0@c7V$gclOJ=Aip-K?Hkhd54R7DbPkO|@(^?c(|Le4I5q*w8Xngd2!Np&WH+N3-^XENb-uwl=VbMf^SkUrl40=kt{w=-&%YQ6<@I}TT6HE?8tN!-z(Vxfd*S%}a zH(R2z3z<^wuhJ3zxjF)$4hmgJF&#k_Sb`%>U;(oFCMM>=^Umg@|in%*c2j*9=;nam&L_Um4-)9O%Sekn)R@(Z#2Hn)SdO!GMv4f1Nau3py* z@Ch7&SMaTWWt)GJ?v{V?RbXT+kth6@9Tx;G-Bn_>so8_KVJq5zJYS_lU(-Z*l(B*WWmG{!(%Qk}7Qe!SuzCVfgc|flwJ-y>XnaY*K=g=g3=1sjPtT=(U^v z$^WX%Z=g!(5j*x@iB!1inxy;^M-T6hK3?`4 zH2hz%irKHs1zlXb8J1Fn!m;>lspi-18V&k1PABAQAebQvB!yINN-6$kY>NFA*QK9+ z{_pPFe|3d|k6N>FGr$RqjET=F%rCD5rBH=p&hJs?|3I)(=q8Y6S^mYBu$=wv;bTWm+uPWm zKXu_EEHj;Oa6Ep-;egFa=tpZdZhGsz_d$u^;{M~Ym>Xy&U?yNDU?yNDU?yNDU?yND zU?yNDU?yNDU?yNDU?yNDU?yNDU?yNDU?yNDU?yNDU?yNDU?yNDU?yNDU?yNDU?yND hU?yNDU?yNDU?yNDU?yNDU?yNDU?yND@ZUz@{{zg*=}`ax literal 0 HcmV?d00001