From 680b0d463a3ebcac2313c84e550ac2fcaeb051c7 Mon Sep 17 00:00:00 2001 From: Yuyi_Hao <96305382+Yuyi-hao@users.noreply.github.com> Date: Fri, 29 Dec 2023 02:49:28 +0530 Subject: [PATCH] example: add a path finding algorithm visualizer using gg (#20060) --- .../path_finding_algorithm_visualizer/LICENSE | 21 + .../README.md | 33 ++ .../path_finding_algorithm_visualizer/aStar.v | 479 ++++++++++++++++++ .../screenshot.png | Bin 0 -> 37961 bytes 4 files changed, 533 insertions(+) create mode 100644 examples/gg/path_finding_algorithm_visualizer/LICENSE create mode 100644 examples/gg/path_finding_algorithm_visualizer/README.md create mode 100644 examples/gg/path_finding_algorithm_visualizer/aStar.v create mode 100644 examples/gg/path_finding_algorithm_visualizer/screenshot.png diff --git a/examples/gg/path_finding_algorithm_visualizer/LICENSE b/examples/gg/path_finding_algorithm_visualizer/LICENSE new file mode 100644 index 00000000000000..2aaecb938eef0a --- /dev/null +++ b/examples/gg/path_finding_algorithm_visualizer/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) [2023] [Yuyi Hao] + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. \ No newline at end of file diff --git a/examples/gg/path_finding_algorithm_visualizer/README.md b/examples/gg/path_finding_algorithm_visualizer/README.md new file mode 100644 index 00000000000000..82dbe9704ed619 --- /dev/null +++ b/examples/gg/path_finding_algorithm_visualizer/README.md @@ -0,0 +1,33 @@ +# A* path finding algorithm visualizer +This is a simple visualizer for an A* path finding algorithm written in V. + +# Quick start + +```console +# to run: +$ v run aStar.v + +# to just compile: +$ v aStar.v + +# then to run: +$ ./aStar +``` + +# Controls + +- `q` : To quit the application +- `c`: clear the grid and start from new one +- `space`: initialize path finding algorithm + + +# Demo +![Demo image of the algorithm](screenshot.png) + +# 🔴🔴🔴🔴 Area of improvments 🔴🔴🔴🔴🔴 + +- 🚧 Under Construction: We are using heap, but that is not correctly +implemented, since instead of O(log(n)) it takes O(n). For that reason, +having a bigger grid size, will break the application. + +- 🌱 Growth Opportunity: make it responsive. diff --git a/examples/gg/path_finding_algorithm_visualizer/aStar.v b/examples/gg/path_finding_algorithm_visualizer/aStar.v new file mode 100644 index 00000000000000..6080146aff88c0 --- /dev/null +++ b/examples/gg/path_finding_algorithm_visualizer/aStar.v @@ -0,0 +1,479 @@ +module main + +import gg // actual graphics lib +import gx // lib have some constants like colors +import math // for math related function + +const window_width = 800 +const window_height = 800 +const nrows = 50 + +// app struct that has property of current windows +struct App { +mut: + gg &gg.Context = unsafe { nil } + ui Ui + grid [][]Cell + start Point // start point of algorithm + end Point // end point or target point +} + +// this needed to get the width and mouse position part of gg window +struct Ui { +mut: + dpi_scale f32 +} + +// struct for a point +struct Point { +mut: + x int + y int +} + +/* +RED -> Closed +GREEN -> Open +BLACK -> Barrier +WHITE -> Empty +ORANGE -> Start +TURQOIISE -> End +PINK -> Path +*/ + +// struct for a cell of grid +struct Cell { +mut: + row int + col int + width int + pos Point + color gx.Color + flag int // 0->empty, 1-> closed, 2-> open, 3-> barrier, 4-> start, 5-> end, 6-> path + neighbors []Point +} + +// this is a node for priority queue + +struct Node { +mut: + f_score int + cell Point + count int +} + +// Min heap or priority queue + +struct MinHeap { +mut: + data []Node +} + +// main function +fn main() { + // app variable + mut app := &App{} + + // setting values of app + app.gg = gg.new_context( + bg_color: gx.black // background color + width: window_width // window width + height: window_height // window height + create_window: true // this will create a different window + window_title: 'A* Path finding algorithm visusalizer' // title of the window + frame_fn: frame // this is frame function update the frame + event_fn: on_event // it calls on every event + init_fn: init_images // run at start of application + user_data: app // store user data + ) + mut grid := initialise_grid() // initialize the grid varibale and populate the matrix with each cell as empty + app.grid = grid // set grid to app attribute so you can access it by just passing app variable or with method of app + app.ui.dpi_scale = 1.0 // set scale this is use to make it responsive + app.start = &Point{ // set start point to -1, -1 + x: -1 + y: -1 + } + app.end = &Point{ // set end point to -1, -1 + x: -1 + y: -1 + } + app.gg.run() // run the app loop +} + +// this function will run for every frame actually in a loop +fn frame(mut app App) { + app.gg.begin() + draw_grid(mut app, mut app.grid) + draw_gridlines(mut app) + app.gg.end() +} + +// this will run at start of app +fn init_images(mut app App) { + // app.resize() + return +} + +// this will handle user event which is stored in gg.event variable +fn on_event(event &gg.Event, mut app App) { + match event.typ { + .mouse_down { + x := int(event.mouse_x / app.ui.dpi_scale) + y := int(event.mouse_y / app.ui.dpi_scale) + btn := event.mouse_button + app.handle_mouse_event(x, y, btn) + } + .key_down { + app.on_key_down(event.key_code) + } + else {} + } +} + +// handle mouse event to make a cell either start point end point or barrier or to clear +fn (mut app App) handle_mouse_event(x int, y int, btn_type gg.MouseButton) { + gap := window_width / nrows + row := int(y / gap) + col := int(x / gap) + match btn_type { + .left { + if app.start.x == -1 && !(row == app.end.y && col == app.end.x) { + app.start.x = col + app.start.y = row + set_cell_type(mut app.grid, app.start.y, app.start.x, 'start') + } else if app.end.x == -1 && !(row == app.start.y && col == app.start.x) { + app.end.x = col + app.end.y = row + set_cell_type(mut app.grid, app.end.y, app.end.x, 'end') + } else if !(row == app.start.y && col == app.start.x) && !(row == app.end.y + && col == app.end.x) { + set_cell_type(mut app.grid, row, col, 'barrier') + } + } + .right { + if row == app.start.y && col == app.start.x { + app.start.x = -1 + app.start.y = -1 + } + if row == app.end.y && col == app.end.x { + app.end.x = -1 + app.end.y = -1 + } + + set_cell_type(mut app.grid, row, col, 'reset') + } + else {} + } +} + +// handle keyboard interaction by user '' +fn (mut app App) on_key_down(key gg.KeyCode) { + match key { + .space { + if app.start.x == -1 || app.end.x == -1 { + println('Error: either start or end node is missing') + } else { + for row := 0; row < nrows; row++ { + for j := 0; j < nrows; j++ { + update_neighbors(mut app.grid, row, j) + } + } + new_start := &Point{ + x: app.start.y + y: app.start.x + } + new_end := &Point{ + x: app.end.y + y: app.end.x + } + astar_path_finding(mut app, mut app.grid, new_start, new_end) + } + } + .q { + app.gg.quit() + } + .c { + draw_grid(mut app, mut app.grid) + draw_gridlines(mut app) + mut grid := initialise_grid() + app.grid = grid // set grid to app attribute so you can access it by just passing app variable or with method of app + app.ui.dpi_scale = 1.0 // set scale this is use to make it responsive + app.start = &Point{ // set start point to -1, -1 + x: -1 + y: -1 + } + app.end = &Point{ // set end point to -1, -1 + x: -1 + y: -1 + } + } + else {} + } +} + +// draw grid lines +fn draw_gridlines(mut app App) { + dx := window_width / nrows + dy := window_height / nrows + for i := 0; i < nrows; i++ { + // horizontal lines + app.gg.draw_line(0, i * dy, window_width, i * dy, gx.black) + // vertical lines + app.gg.draw_line(i * dx, 0, dx * i, window_height, gx.black) + } +} + +// heuristic function(point manhatten distance) that calculate approximate cost to reach from a given point to end(target) +fn hf(p1 Point, p2 Point) int { + return math.abs(p1.x - p2.x) + math.abs(p1.y - p2.y) +} + +// get the position of mouse in terms of which cells' row and column +fn get_clicked_pos(pos Point, rows int, width int) (int, int) { + x := pos.x + y := pos.y + row := y / rows + col := x / rows + return row, col +} + +// initialize grid attribute of app +fn initialise_grid() [][]Cell { + mut grid := [][]Cell{len: nrows, init: []Cell{len: nrows}} + gap := window_width / nrows + for i := 0; i < nrows; i++ { + for j := 0; j < nrows; j++ { + grid[i][j] = &Cell{ + row: i + col: j + width: gap + pos: &Point{ + x: j * gap + y: i * gap + } + color: gx.white + flag: 0 + } + } + } + return grid +} + +// draw the cells of grid +fn draw_grid(mut app App, mut grid [][]Cell) { + for i := 0; i < nrows; i++ { + for j := 0; j < nrows; j++ { + pos := app.grid[i][j].pos + width := app.grid[i][j].width + color := app.grid[i][j].color + app.gg.draw_rect_filled(pos.x, pos.y, width, width, color) + } + } +} + +// update the neighbor of each cell in which cell you can visit (if it is not barrier or end or start) +fn update_neighbors(mut grid [][]Cell, row int, col int) { + if row < nrows - 1 && grid[row + 1][col].flag != 3 { + grid[row][col].neighbors << &Point{ + x: row + 1 + y: col + } + } + if row > 0 && grid[row - 1][col].flag != 3 { + grid[row][col].neighbors << &Point{ + x: row - 1 + y: col + } + } + if col < nrows - 1 && grid[row][col + 1].flag != 3 { + grid[row][col].neighbors << &Point{ + x: row + y: col + 1 + } + } + if col > 0 && grid[row][col - 1].flag != 3 { + grid[row][col].neighbors << &Point{ + x: row + y: col - 1 + } + } +} + +// construct the path after finding it shows as pink color +fn reconstruct_path(mut grid [][]Cell, mut came_from [][]Point, start Point, end Point) { + mut x := end.x + mut y := end.y + for !(x == -1 && y == -1) { + set_cell_type(mut grid, x, y, 'path') + x = came_from[x][y].x + y = came_from[x][y].y + } +} + +// a* path finding algorithm +fn astar_path_finding(mut app App, mut grid [][]Cell, start Point, end Point) { + mut priority_queue := &MinHeap{} + mut g_score := [][]int{len: nrows, init: []int{len: nrows}} + mut f_score := [][]int{len: nrows, init: []int{len: nrows}} + mut came_from := [][]Point{len: nrows, init: []Point{len: nrows}} + for i := 0; i < nrows; i++ { + for j := 0; j < nrows; j++ { + g_score[i][j] = 1_000_000_000_00 + f_score[i][j] = 1_000_000_000_00 + came_from[i][j] = &Point{ + x: -1 + y: -1 + } + } + } + + g_score[start.x][start.y] = 0 + f_score[start.x][start.y] = g_score[start.x][start.y] + hf(start, end) + priority_queue.insert(&Node{ + f_score: f_score[start.x][start.y] + cell: &Point{ + x: start.x + y: start.y + } + count: 0 + }) + + for priority_queue.len() > 0 { + curr_node := priority_queue.pop() or { + panic('There is nothing in queue how did it reach here idk') + } + curr_pos := curr_node.cell + set_cell_type(mut grid, curr_pos.x, curr_pos.y, 'close') + + if curr_pos.x == end.x && curr_pos.y == end.y { + set_cell_type(mut grid, start.x, start.y, 'start') + set_cell_type(mut grid, end.x, end.y, 'end') + came_from[end.x][end.y] = came_from[curr_pos.x][curr_pos.y] + reconstruct_path(mut grid, mut came_from, start, end) + set_cell_type(mut grid, start.x, start.y, 'start') + set_cell_type(mut grid, end.x, end.y, 'end') + return + } + + for neighbor in grid[curr_pos.x][curr_pos.y].neighbors { + mut temp_g_score := g_score[curr_pos.x][curr_pos.y] + 1 + if temp_g_score < g_score[neighbor.x][neighbor.y] { + g_score[neighbor.x][neighbor.y] = temp_g_score + if !(neighbor.x == start.x && neighbor.y == start.y) { + priority_queue.insert(&Node{ + f_score: g_score[neighbor.x][neighbor.y] + hf(neighbor, end) + cell: neighbor + count: curr_node.count + 1 + }) + came_from[neighbor.x][neighbor.y] = curr_pos + set_cell_type(mut grid, neighbor.x, neighbor.y, 'open') + } + } + } + } + set_cell_type(mut grid, start.x, start.y, 'start') +} + +// change the property of a cell +fn set_cell_type(mut grid [][]Cell, row int, col int, typ string) { + match typ { + 'reset' { + grid[row][col].color = gx.white + grid[row][col].flag = 0 + } + 'close' { + grid[row][col].color = gx.red + grid[row][col].flag = 1 + } + 'open' { + grid[row][col].color = gx.green + grid[row][col].flag = 2 + } + 'barrier' { + grid[row][col].color = gx.black + grid[row][col].flag = 3 + } + 'start' { + grid[row][col].color = gx.orange + grid[row][col].flag = 4 + } + 'end' { + grid[row][col].color = gx.blue + grid[row][col].flag = 5 + } + 'path' { + grid[row][col].color = gx.pink + grid[row][col].flag = 6 + } + else {} + } +} + +// ------------------------------ HEAP ----------------------------- + +fn (mut heap MinHeap) insert(item Node) { + heap.data << item +} + +// get the minimum out of all node +fn (mut heap MinHeap) pop() !Node { + if heap.len() == 0 { + return error('empty heap') + } + mut i := 0 + mut curr := heap.data[0].f_score + len := heap.len() + for idx := 0; idx < len; idx++ { + if curr > heap.data[idx].f_score { + i = idx + curr = heap.data[idx].f_score + } + } + ele := heap.data[i] + heap.data.delete(i) + return ele +} + +// see the top element of heap //TODO this won't give correct result as heap is not implemented correctly +fn (mut heap MinHeap) peek() !Node { + if heap.data.len == 0 { + return error('Heap is empty') + } + return heap.data[0] +} + +// give length of heap total element present currently +fn (mut heap MinHeap) len() int { + return heap.data.len +} + +// Index of left child of a node in heap //TODO heap not implemented +fn (mut heap MinHeap) left_child(idx int) !int { + child := 2 * idx + 1 + if child >= heap.data.len { + return error('Out of Bound') + } + return child +} + +// Index of right child of a node in heap //TODO heap not implemented +fn (mut heap MinHeap) right_child(idx int) !int { + child := 2 * idx + 2 + if child >= heap.data.len { + return error('Out of bound') + } + return child +} + +// Index of parent of a node in heap //TODO heap not implemented +fn (mut heap MinHeap) parent(idx int) int { + return (idx - 1) / 2 +} + +// comaparator of heap //TODO not used +fn comparator(n1 Node, n2 Node) bool { + if n1.f_score == n2.f_score { + return n1.count > n2.count + } + return n1.f_score > n2.f_score +} diff --git a/examples/gg/path_finding_algorithm_visualizer/screenshot.png b/examples/gg/path_finding_algorithm_visualizer/screenshot.png new file mode 100644 index 0000000000000000000000000000000000000000..02f4fdb8eb37dc3f4ec4ffa5f4221638794ccab7 GIT binary patch literal 37961 zcmV)jK%u{hP)HJpzx0`PTX)avmRe#<)Ye)kZlXwn8$bdiNPyUCO`i|PJ;F1qC<)ZG*?eG-h0Kib z<@gDYE$=PB?zrO)CyIN!{j_{qJ}sY?Ps^v})ADKgw0v4Vw$y#2yYKmP(@i&V?X}ke z@an6tHu=A{Tz&P`TzB1d48t&Q`n3FCQp{{#^|5u!eAxRiV%Vo0{b~8Md|Ey&pO#O{ zr{&Y~X_=S0cXZ$NV}N7m4s2L-`M~>WNLk_8^>_&4l|u$81Qi<{ZBC(QfsaH zv(%XxJ~}ppPYK&^ zW0Lnxw#JcmQ?A&kx+!nN(Cq?d1MVfxI8--TWV^*XtIJY3&GuU6`ml$M@;uj{#6N$| z_*`7iG5)D*)vax*KPevlSZzd1*%v7T5p%I86MOra*s6ZxzQ(7DZgY-z?l0>manH(L zHul6?^FQ%K+oVnvlen_X!riJh9;#Yblqd$?Kujr|ewU-MegwqsF)E-qknm-qw%GWyaMwi0651(J+}m<|S>+ zG3<#euzAEWv6r}`RBSM{4`3Khk2hmVnaaan*UG^hZ{l#+J$KLKCmgn$;w#G>L#dnC zO!2sWtPhylsn4^z%14dKqFv(QdnUhE`z|}BF3T=XDK^+!ulm>R^d1tEq}|7s2a*{8 zPvh-gdD7Rrysy|YF3jK)jsGD`^uFxzCsRcpi#Svyn>J|p#97EXXkQin16N{k_vyHb z=h_c0<9+Rl(&o+_>mi%5&+D?(xjNfxnd`$IHs<(h$;Xt>_8`gzlgP}5nd+1I`8DO; zoxzN8hDjn_1|pUspVus@Uwskx^ZHtszSEyE;=TjpHskg>_)bWN&aq?19AH>1SzSBK zuvo>0r2x1Wa@6^a;H-;ePBLp<4Y~y!8*#cy1RLRabVP2}vt=r>3*X1tt4UyLR9iDj z!M^*zfXQAS5EMtMdDv_antavWi-%rjaX`bE)m_Ih%fm{MZ#t3%VQX>8$jmPj{auSF z$za$5Fq=G^*<=9dR-oH+nHXBV_l3J|C?+xGy;;vOgeS`c#~xgyKH*DMBRI-2fp7YK zV&A<1>vG|*OyX&?_qVR{H|zU4UNWYXEpcX<@T!}xUrWPMIGIh#drhzt?yBuQaJc&} z+;bcASSNj4`Wk34)c&8?`#3xvxij;&9Y&I8$P+L4E2bp=9`AEI$tMO7W1MQ$>Fp0%|_km(B4$SsA zNJOc!iE%Gn=?lbNl}WsK*L>Ay*s#% zG5$T);^0758d?h*X|G{`Htr_aljC~tK3Vhfc~@W0`ruF2&F6{mRb|rOUV0U0ldbDX zFi`FMxw4DDqBDHnV`cv# zmMi;P=Qpt4iLSu&zR5z6>8V1J8vo~bYR_3ht=}|O4MFH+jiY?!p=Ih*7|n>buoE}Y z+}bjf9wdX+N&h zxI-|*ZJQ8)p63NcDXME2iVqul%qj*rIZ?Mm3yIs&WZZe)yDs7@{W9U8a9y8UU0`h7 zg^hWc^wA!^s@;@tGLwmv-9Ag*L?%nr@9N(@Vw*1n9~akNcCt(`q5haJ6noj1aK~E9 zM7ET@>gHHg^)WGyxnYkSue6ms(sT8dIOCBF&BB&s+hXozoJ4)o8)Fj>6OP(7jN7pL z6OOcRrh|n{bew-`Ba}L|FB(o1FX#mgQ77J}5F!2heE2iud>aNj_7YmiHphW?N<)ts zN`1}?Weu=0Z)dxNqAne0wF{pUehLR2WZ18|A*brj`P@Fxf|>iu=ZW2ruQCvL2wi9- z^vG3TpKD!>jeLelY&C{mIZ-e++!Ai}Fy#}baqg=nXZa#-!|;uV_w zWSvT$>fDcP{JGNlqVSOO`MjUfUUCfb3F39vI`A=d)z2iKs{Ph4Z~)bYNij zCmN0GBG+_^3{0_9A9K8Ojs_bUH!tGjCd=jO8mntZ7#1sCFhQ6V0I~2DWa-o(7DGK5 zj=MON4aZ!;q{j1x5HT_jzfR{YA$VHFQ zAAbzic^tiOPKKd>1uS#O@;=q$IwX#;RZD{#G8Q=7p(S{n)Rp2MV>$Rq&lZ2AP3WI! zi<8;hORf!)HB)u+-Mz{Nlo%D7;&TtWBc8JUNTc94t%DFapvh}q@1m2#O8P1H6IKFH zu1hJKMKlFyQ@`zM2k^EMh!?ZgAD(r2&H93+$~3twVcXPz6<=AZo%)D@ zE^kpkjyg2_pB?{_NGugc`V^*YFW>qonufj5rIxyew>7QWPhP@i<#W3Jk6?k#f~C~W5|6nb1jkH# zDVt(WteixaRle&zL>{!K-kuodF;_dzf?@R_dA#XqcHE(jT7%R2 zJ9L%Y9)mzJ5i#p$1Q+)WbM-MK9@PtjY~qP8aOYJ$+Vx;!1B4@ewn-)0>L$pn4CqpP z^tKt$vknFFpL`E-ug!TYfmJvOY^IQM(jN5v*aV($uF_8LC*f#5W5Tgv2pdDEv*l@W zlov<-gPUQHZFeveCRZQU$)(!C%D)d`D5l56E`lRXB;{6R<=GYMN zrj4O;6EY2F$a%rjbV5eF$XAxk4RI1a181`_MBk8$sq#~}ymOg#&Af+iRrEOtvOjfz z=y9u9gIfFCov>Brl#tDS5hl%#nyY$@?%5yGQC}+tGs*XjZpRRcaT~lxZnS)f=j1zo zJg$~@!Upu%gelss%t0<(&1b_Q4jMihyyhe0RQzc_E@R0*)BL(?{8yi7^P@vS@M1=; zXPU!07-6RQQ>8BTpaItEv#-)l=S26_XU-mpDCxnG@is;+O5bW2lBbwR+EjNv_-L7>oE0S^G$?M{bWg8^!`e`?Ni9v z_)qS$U-BoEn+=HA{_Obg9JzZ0tRg)JaxM@@dM-TV7)k%RMnxH7epO?U$@tu9Yg^bg z>%1y%skg?!K}!^x9bg(aQ(Ntt_qj%y_-gB2S@Wvg1Wa;S?sKhce9vN(sGiMCVF0uP zVCkdLF^l!z^TjFMSK!M&RFgO<$N;_U0)65Fv0tbhA>C$^fnoJ3hULnBu>Nrxu7vHp zXM&Vs5o87uC1oeTV**IYrjwWUEN~4dbfObYh)z0KRZ}dUo#VO}XAx(ROSCtg#4ill zc^39O?aYV;@L1p^Dmlyoh7pQkr-!8`IT2s+oYfh=sv0*SyNZvnA2Mcm{MWco{Ee(4 zoAz2`VwPT;z}q4l^=8=6eE|iJWxL!2gOFjnK27?60Hk_orY19f@eHY+IMW3Ef#4TfE+)undPGd# z{l!CzOLcv&s<{wM$B!O+PKYPz&^VHxFdySUeGz_D1EyG-y=Vd10O_@{G-#np%x2aO zomp}$Ng*soOs?Dfqxo|uV%I~eS>j6>&#@I(NrjcLLH|Tu&FXV~wKZ^ge6o&gj=_7b z3;C&c@|gLR`eyQ4`3iu6Kl+lWi<0xGlnWjx*d)+$rTMhRXV2T+CF`>P_A0wtf}`xW zo_|sH@YVR3$=2M&V?LZ=ncHvAMRsl{W6xrN8G=rV4g_Y!)Mgq(bcK|Or3_0Zg0qyE3mR#TGEam*4pZEY^(O0=1AzKr>^zFn8eu$FLTblLI9-1<*l4atp-Q6z0AW;QU&dB~4~qfBj{M z!%&N<^pzTd8;|jUw>U7!{>p2FrFI8QqfTLU?&?SX9`X%qPF{smWC|h%OxX1?e9Qxb zJWa;Gds_&^4dPcO8$Ob&HgSec#Hl3oU$)ocIOaXqGU${`OatmeA0?OLruRemhX@!l z58S=yp-b0@9IZGT7ae2cKIGiTAl}1I?>O0s`pBa!J)Z+x*$A|Hvo;P>M>!hzp#wEe zan|z5XyZMes(C_LT{@adETd;ke$mXFRd=>g=*#(1aej~sy$2K zfR3w{hBfM&O!%4mSNrbuKO&VZ+3#iiGvgrZa=wSoMaqgiS)Xx;rB^5Z52M1KU!fzp zoyFMd5#B_Ub?K{elkI|)7|V0$wi3E2mv*LXg|Ff_+65a zX%_LA_?YBsYZnjARur4zs(rX?jzu=+eO=oiVu+Y2@$V&{{wIEuqf(zX`m9q*&cC6f zfI;J;#@5#WHvqlN%RP-u3}`)+pFx{OL*pu(yDJ{kVla*(#T`w=Q4dNg9O+B7y%lw2 zGeb)IHAEdERP^yqcCdnScaah>rG#XnF5A;nB|GKuxD6s|$xe@_s2jn3g0BQ3nYecd z+0@n5LR1M*7g8;RDeE4G5EH*rE^qcc>oqW1Fku@f>Q&cxPFoKy_q#0 z8nr2J;dg2taD3D!A;ga+E!oKM#e+8bHtW9}m>%QHOdI6H;NIWZXI&f29&u54H`BFn zGx~^!vLiqFhTq-g&(xNDC6=^5j`0?W&<*>b14i1%0&`5NX)|%yV{YS5q6^Z7<~{rt)D#b<$u<5)#R-CY+TauH*8^}E~Jg4 z@I8*gRXG}Bv245>io+2f}wUKtH@Dau1r7ZqFCW+qB9|J>tng6bQ-B43Mp z&gaS+>4hyxbiuS|l4*X*=_~|9^FwnFjLLw&QbzuPVq1$g;9&4n=uSa81xZdcFMT3h5HU> z0!t*Fis%1x!HccXC3&60&Qj2l8SMu#JZf}D{Oj#oE5?9!h-O7>!&SF@YHN{yF|y=?>8q!`PR)q13v5rIT3=ma+h3| zoE);!h(VUd4GoYYJ3lP!dM-R>X}ZDDp85$qai-syd=|%Hlz#fefKmE2rgm=@97#91 zF&)2y_n9wC-hxXMg9W#hD-fPq=6qB>dyKs#b^|ikakSwa`Wu3|JOHMA%gyPe-2jhG zdhzHU2Y{&ZF(zUU-b2sh8b>3s2qm8-A8Wp(Uh+Da?B#|ZXtC8CXmdowKN-7$uiDi(mTu-yJuu+n zHv2}4SYSnck@A8RxRYC(9$ruLuye;u24~7l0Z5A@_3L?0z;{d=B z=6u7Qd4m@o(niSE{+pB{m)Eq{`WX3?$kbNnZpw!+!rtrufDYM-Kl35frQKiwjf>Vb zbS%n|@}{|BNuG*qfav%1n1Pnx>E6N)9yuQI)#tQche$N7|jnL>?^CXRZb5UrM^q zb_2~x*5?jTjAE*n+HRJZbf0Y%U;4^`jBZzP#k^K>tm@aXZPxRn9ejrD?^N(cid+x) zsKcI`9kb4@cqw=TlQ4M9-E~fGp>)|j*Z&Aj1Nds|?G1x=&X@?y$0tVRauPke!=Tfk)Gt1peZ+|b!luXl#CXW2{g7`qiyvIv)lHOH z*G;?4PKi%9ai5Q+Us_w`Bz|g~Ee?82?$eEV;u*)-2pizqkb+`>?k{6#{1f^fZ&lL1 zDR(ngvwldZHj3Z@kiX zlwpWN1LC^%iJ}GK_dQ$(832;&h`|Xw(DV(B*NPvEs~-3||MSVi#A_0q$f48=S&fb! zf3uOCnS5#ijkpQyh36d(^YHhc;)~bsG`YcIkw&t)NQ;YoT=(D?_?y4^7XRbFKgq+l zeui&-_W^ES2KV6?5JFeZ$*w%;MT+D{Zsy6q{UVQEy@T13>mGZG??1SPjgC8$F-7!G zRJ8shVzHSO7nM%~+^*q~?>)sAuiFL|T=%)B z`2GX?8PZ1Rkah?R@!YTi?QO4*K=-9FBDiS-ES`xN472ikS%DG2Y#_Y~Q*AHU3f6R( zv3ikFg>WY)1}$Gbf#pxg*0#1`jAtYG2pg%Jb*VqGQJ#(BCwP*Mqoy%j<><)Bdme)1 zAYz4vF?ndh7JcL1VyJpX;0%7U%?O(zgPF!dR$|RX`)Z?EN~=8%Dso$J0MNOHfaMMd zOXIgS22Q}o{u0Wpj(?SUpU>5|F!lTV{lgww;2yQHZvMwOXf(07-vh5lUF%1u&xhg3 z-NAYc-L}bQS^quO|9+r1`6+qWxQKa2*wqH|-+dMiT>aYmzv6Tcz2IS3z+wd!t1t|N z1NG)GV9Qllu42PNCW4FBM`l>8|4Sc5x*TUvC_o#q#lFP;vBhk`uw27;*5i#t-;Cuc zF~TB0qQMq_q3xmB#&<+OB@NHMY-C~sw%q?0*j~VLfp4#4)=z-h2@~7I#1X}Dy_t`y z+TL)DePfnMk#9s>qM+oe38+2^d!|XpJ)h;z5H$G-kaYbfXMJF5A)Oj%Hf1alq(3uA zrebs#FHXc2Z{M3tIXI;(boquM>L74H3>tBQ({V<9)d@wtX$_m{yAQxFTX|{tLuRt^ z0&yOqHD(AO?%-4X#9cQWbG__yJnRyE;!;RonHQNqtv{nL>f82c=(j`IGx<;Xanz?Y zM);*1qKi)YkXad?9IOk6c|Qz8i^VCM;J_)b@rElf04;age9?@nZk|uckCEK=Y-qoC zR^_5UlLx!`asJ;gE_wZjKj-<2OVk$w`_>k0UEXB<@&@aREgWN5UBx!m*(Uffa9`!< zSDxa_H*Dj8k6T zky|+CCwcRu-alf+Xz&u6$xeEeY~)k)P3xn$H&H_JlzKzdhgtCRy#3P4teln2w3E7x zj|pdas4P6RyTIoz+#yqOb~)M7{m4ge{DEh;H{`3>2FSPg)8ehJ9~^Y;o8ymJ|I=1k zJ0#JI@J2jY0-H$yDHnOdM&ZER!6T<8@%K1e|7AV2Hr-BjarH^o)b`8+Kw}}=+?{-@ zYzj=@((vdPD`VXqko`7R<5`9Qw+KHrpk&zPB}j|0_=#4}_EIW`PV{El2z+?tbl7Wu zt#iu6`j_@v|Bz#&`i#cV$b840QRZ-m`c0Cq17=ZgLY(72Kf%oLZ)gn*v0zjB$;%WM zavU+$!-bjQD7LEaKJ825x$3omR6%msU1c7ot(>2l73ut$^*>-sCgo%8m9QAlVP>kM z`m`;>?I6>uWMcSB&jkJ!roC8jVnNPQTD`bJV^2Sc`SOePt+Q>owcv^*xy01`hGH zhbC+NfY6Y-bPcs9_k!TyipxE6zHpphJ*+ImBna{si~)0jDo7vEg36 z`mH0}c-0wx_s`Gr>Q;Oljko~k{0mR>|G&Bgt56^Ni3i;c zwqSY7-F)`Q3%qq|gB>rEJT!Ue+#A+%27s#$aPaaO&RmMV+BwgucMM|V7u1Bm>DTkp z#^i9BoX2(R!&96D9bi2^35xMa_W1;JJeoD^xp&zbCwWEADzlRUc^C;f!)}hEzZAlntF(v7$-RL z24_ycO6mZup9mfhrdr%1H_P+Zho^W4K?|VZjuUwpE#g>pAqnlE(MuZ#X4Lgxj>Scy zNSjSJZ3WI+8g4Vpbrl}PA)(UuQJ;r{$$gRS{pb^YhbE6Jo``IUxm-PXuYVa%?Gqrz ziHV;o8#1n&(4FOnJCHqNV2K+b>{;+Gr4nB(I=I4VmQ+$V`El>unwbt_1uMt~0A5}U znE{3k{eU1D={m8N#CX%yTE6Feo-*xF;xrlej8issU+N-eahUSqoE{V8JeNW=LHEGm z4lbP*uytOiHoI*n@QkBylw9)AYjvRh^tb|fsBf|4RhEICTf*BhnHgH&GY?WGb+cXe z1wnD<8q|CzzO1(aTYQ4O_V#8s7q+v%mMN*fRl@KL&f*sxub}8{+JbRs3qZCQ&|8sQ z&_N&1T&eAa{_)10ZOqDBMB;os;eGES{a?)Sw_W{@I+{+|o5a4u$#(x&^<$AkV;&6|;vBzCE zQAT|ICu~@RgvVDfGUjlf9O@7QNkHA?bz9o3=hv@hkOPm#O_u)Ey^Kd=41@lrQeHAP zvxwgvv+|W7f+tJ992jtfGv#`WRu-H%C^4V|hU7U`IlcbJC^=4 zzVr{cYrG)*ZOqgA#*3<<*wgMX4D77k$~{L;@$xfU-1p^U-2BpuoY)yyaF&<;1*%d z&Lc}!{Sxp0@p*p!>Ls>u#^n+2{`~zsc;h~n+m|@~+WYtj8)o1G*FW(szI5p){L@Pt z*zI57?`}NFZ?=>deTXOTKEwewxbW_A zUgLf~bM|Te^|)iU%E8<3*K%mp z**vy-=7V9x)2Co17xB24b zf9IcG+G5{bpXZzR=qq&2g8ggG$)ElkKYxG0aO6%NfAlD~US;_DhrIFpOFVaan;nku z=y&gC=htts^3Vg^edIiU_`!eh!bPL5|2dw`jP~-x9ZfRR@sC-11K&PvF~fb#GYw2O zTTyb}81qxsvfkxnMtBO@tj)T4$+6$$0=Gk3bDN!vPl8&PL$BE>nEKq@SFMSD#qP2o z|KK?0;<)a$sttGj(R>$O$1wEV`a%j(hx|jxl{h7(VH;Nq`=iIY8aDbT8MO6(uTMSn zs9ez)LIw!iS?AvO8Kzd@Ok{aYY=%+#C1OfD`igIlv-L-A*a6Js%Mo{@Pu;m<_pqt3 z!e(G?KFq*~eUNgvBUYIl}i$ zos`cJaR?cW+9CsiEt<0ACOM0+0VNr=As+#Yq@UT#tb`UrtXS>2@e`9z8^}=_#%vex zes5|6+I?$_bw{qI*dTKtCJewmlW_)-{o)@b{m3MG8SiYSZ}ceo=LB2Q=fU~?s>KpJFY%<(nmA~cZTeGi$}Gi z$KvTamVn~UH|%C$M4v>lu^qCyX6!=K4I7` z5An4-*LmUTU-Rn41#7oH#8Xc$*#1y+o5eWFvUTA-j{nE2oI1Y+hwtZ`Puq$!WVhs-qW1;-AA~=c;FcKuKki9{p)!yt=`5Lzx7$Zd+nS2{F$fu)y6)q zedJ60mxpiUjh~!mJ?0Cuk#ldI;`}#m<<{kUyuQ7}?FhHuYP|FN_u1fD3PxIsR%B{o84Mq)2KzUw^nK5#JJ0HD^gKz$re>}d;xLo7#fsykVX4_mo^ES`E z@jf4JF4%YHinc{BhH8Kg4~Xy@5YI`!oLj><;60_G;!QSf;BpsmEQ7 zXw0?^cIp%3-4!>;keNY@^<+oVy0&>0$;s7h?QOm#-#3$4t@%;5y0087xp8dse&UI? zi9G^W`}8tVtB4jSV{6Yz97MdbWyJiLZB0fO2wYhYVK3r$!k$B}|5h@sxfK79F*pNR z*XLc(OJcLwJp1T42HtICKj(es1Rx*Ybz425mmmN<>e_)LS?$;xNOK53X-B@hhyv3^ev2ar zz8u%v*=RQ9rAaRLOxokbzQn?weX_l_4f?i|@(nVl+?}B&8LmVMtx&(RlBa&1u%a$V zQ&-wwWjhlO&#z&WL1LfW_Am@BkpcRNQ-mod#Q&*Ilj8>ENMLh0Y;6PQc;nTxT-*U0FLLtqC6))*Sj$}EEU&+M zj>{u(`84mGh0E`}!8;oR_$KeYdzP)W0~|Ek+~A|b`L}uX{Eggs>xvv+cPn=+PH_BG z#;jsH7x`%YAUEA{BiHS7#*OoQcp*Nu4~zh2#Mp?8@=Y#W7&&z7QI1}-g6*tx?)+x7 zI+xG9$C(Ys+2PWu4>-4PjkV^L#ytpg+^Op7yZQ11JN)t2Z}7o5u(0^ljG|*a@+N3X2HeRUgX91H`vf> zZB?BVHv`Kt7rf!B@7914Co#U;qvl%q)t&`pxc3|A-^mpo@ed$@EWc4ENk~gba{OwlytsA@>btHW~kU?R_I( z%~G{(NT<#pQQvYPWV&8Akg*hcAnk~lsFJ?=HR?v!J`f5wMmvb$Oy-@ElUGvOJ`7|# z`_tnqTV{Rm14^b(<_l*J{cz~+s{bo&W3k~N$VC1|R}xJ+;tGnRPI5XQlfNP`>dDhC zJtnos0CHE7h5YE{uNMtRsVjT^Z9?**gdWjXuw)-ci9ezs$5C(IlM5+^6AcI{RYI)S zwK&k%^-P1m`EBw*#yAW>^rJgoF-6JbwIQ)NW)Tya(1|H*G#&-5hb7&)3~18GHyJQJ zs01bA6y=MVCZd$7_u0RKE1!@R;>gG7)o5!mc^pKnzeUMXahPe+l}zV^;L{A+*P8-B zs7Jea&HU=0v@|E>00*g^9Q1hOtz*U=dTA#u$Y1ok*+dVZAJ`)XTmjp_lm^9{J`#sF zT^&wxK}>%j&InxEkVk)n@7$#K!%L4fmz~sE+bJNZzy_AfqkQJ7ll=a| z5@VgyFaMF#7z_J=m!FqCv*cJD5FZI%c=6x)m)CaMK~FpmxG%Z-*j+qy`(X|)oY9vY zSQ~kd&aFF`!GI2Gu*Js44(+c%2S$tdJh@e$WL)mvK6z`25)Ydj8#)x?zz$=+HMCXs zudH)vy<=f>oy$8h7t!bjLS|!wb>uIHw8qbZefwbJ%vMe%z$WV(*(b5lgjjr5ICS(b z9z1rKgNqSo$=ZJBJukTpz>ea7YYH)MBoVC3@UZT1~pWv~sv zS-)_J?G}^r4#Z`SM-Vn2UBUV~moLXX;5#FZ^{;pO1{?7!k_L=!Y;ErJjfkU9C=CS@ zTn=33t+y}nxue%})thJ7fAl(rw|~KVEU@TN0~U6U=YRZLF5G(;pZn(hEI)jc=bn3= zw=a6{cbsulA1EGhws`-yzu>2L-pTz>e3i$xPxIRIf8@pYw%J);&8_#|$vro$v5Mov zJ`Qt6;l|vVeV@h9oG=cDxcBj+EM9(wmoF@EclPgJg~Rvo)c5ZS>49O`;{3`I!!g_B z!lf;+MIbhaF&)E5*G_Y^X}oFtN4>o14R#OvVFeMJ)U?RH}UQ+ z+Y_FuT-peq$~Qgx=*lrlABMbHjP2;pY@g@_rp#Lx5UtZ@h|DNv5pU}C*g^mTho>(G zEaV(C$LD?}brqvtOhwEB)%3FDoZMoId-)8m0!Qj83@0ZNBc5AZ`tb;N@AW_9O-eF$ z<%V@XvwJzv1)NTq42eql&L#ut($|0WY0(V%%nctq&n*W7hhZ=j8EE{uD;Lsm%eQC) znyoCIzh0Sk(ns3K`&zVrOJ91!~DRHp>+>Y>YDQL+3Z^fTxr z-Q7R2?Y)Y4>>Hj>YTFP8MnCX?k~=4g#-Tg7F`|!?bFdKiIao8HK=(BX+@1P2@W_6@ zZ{II1r5!RH$V7|y+2i}D(5XnCCOYaM-3onT2KKd?*P!iRZ|X4j zDm}b*GkH@|OHypsH})+?>l2d)hSpCe{6;^Rw3w^d%wE5j&GhG9(Pn>j-@5KToPbe( z&m#THh9st6PcoPt05U)KDs#NLpT;D)JU!;59CnMWO4SqY){-%J#*=c^>~&c!aP<%b zkOv->#8UZ`J@F&E(wj373x(x)>CASC{oHo@5iULd3_p7({VX~3z!!M(j)T1L!aCbd zO!}tD5pkLR(^56vW7X!{4E*{B_{Jmf+E0GPFVDjcM|kAB4|5=JIVE=|JSDEI={)3J z?SsMQxnQ*LT{)y`Noh{nWPNLuwbh>gJ}g;XIGZUmFWF!HHtM(7*o1ximMm;U@9~$c zEW1$ePw?yR=Npe0um1Zl`Ner>v}<|vyAN|ft$=}pkDIJ-z`oTL@C_ld6;@Z$?l$Y| z&f0-};FrO`Sg^LXVB@k5F*51;37)jqiP_B4V`ngVcZhs**|vxy#%{#Pn_VL2aa;vRU-#)zRX)cInT&)qUfVzTW5Lmh2QYzAFkrY2S3NxpV;F3(Hhp5>j-e3q}=@Fq|H?Dw4Bgz?}#eDB+< zK&)F)+J+~J`@o_59_FFV7x}^QO?Di>+1%KIGcWUlpPuGYRWQJmcXb%{xk78DayWdq zgev1d`lkiz6g~A#sHj9=)XjTqD`mdXOFxr3GhvRkWG<6kmHN%56`Mx;icZS6d!z6X zIaM)~@se$|wD_3f##27$Q{PSWVEyVIUSnw|a^!0afkbc@MXDGkghQyV6Q9pXV)RJQ5PvS9Wk1^`Q ze!j3a!l%iuyVn0`o|FlP*o2eZ@V8uSFCNs^cqL>My`BSa_9qZ@B-oJ4{Z)B3(|D}h zPxQPzQ?PinUtuwzuh*)vK|b_dj6#YbaI}rfm6dTE6+jqm1FVwy32pa{LZ)bz_^#q# zf!jx&_$D0N?1vOEut;L+BoMy{6e3yL*I=Rza>MFiy|ahxj_NRU=rHTp3~@OOh1>W;ia-xp50Sv}2(r;)h=n2lioJyHo|BECIAn7e6ieP$ zn>AcOQB9(USg-dL;mV@^imMt!I2FzDmm^yMxby-$R>z+w!0^(S5uNhf~t zld{Co+7mls##Bj;k>o7jA_MI{b(5>)E3cWCStO&sP@?7PuJ*`>K_P;&YZ#w zEofCP+dHOK+N12Xr-)bh;xGg95m&`faTBt_VTLe96n@oF?z!eP$KSlf<@F6NuWxYa z(gogm{WROR9ph%xUzE{0tJw}iy=S65TH_@^J#5*^3j4M$@Zm+hU0=EW7H-|2T#jsQ z>@Zw?HHVf4!<3g6YZO6=v1L)ypk;l6$$H6|#e5PL4P#;FIC*NpE%zMb+NHy=kL&I^ z%8hYQp4cgQ2?b}wZ??nxCqHCy>@IFU0Pe=h4R>(YVdX&k)YoG^TwP^#^8z0PFRQ^z z_F3~`JG}qS2P|*Di#rY)V65J72X`Jyj<-1d<|%fL-Ob&H28@B_HFxpQ&6jxd#Km$T z$;cy=to9LnlZ_2Hc=#%oF0QiOY?v;%S@Pbja|Gl#(Y;FTQ{{)l#ycE;?=ZJLbd+Nk z-{ScB1zJ0rC_WtE+9Uf|;IMs}v**^?8H~Z4txM}{9ln+uR~#FR;hLk|5nP+CaOm2D z>|YqL&84#!Sx28#?%TIyym*dto07Zc=nWh(XY?E$HO$@*cI~}<`Sx=>`I;L+|I}?<8R9QR6L6NWV}r&Ep7Dk62(BHJ(RE@YMBSagX0Hv&yY6KVePt^h7K;!<7KCz?DEwLus1 zhI}+hS0CzDnA29)feswaX4q=Dn*W)7r}@dlgXHvetmY$hWHTe^r5{2xU~}TBpB4za z+VYy*B*)b-%1?+Gqdk95 zO8ho$;W6cMb{~buEKVP<`IQFufkU_7!r@cTa$-B?g|zp<365_*&fT}Z%!#+VmDZk{ zYD(UONYbi9L~rv`ukf2&9^&zDUC-v$$mV-*^7?z%a0D#`>uKD_@NYS#`1=vJce|7==BAfgR4g@Oys$*!_Ivd-t-~zQp^ly}@he zk71@BPZy2vQnE`7aCdf2KF?1NKFsI8@f45vCYMgX&AT7m%uVR)9m$KkGoE^d-`?^N zPkg)Za{3w$XPgF(#^lb)7kK9Chk5)PPw}X4a_RI5-u=M13FVZ(_YyyT{yskc2=o^V`-g)y3Pki}0F8uCU&Ih?U#NEM%1KjxV1AOh!0>&N2%V+q*@8999 z8{@k#^Q)U4;n8n@mHRJkv9tajCr@s3%pGUJ+ObFZ+Lu;Y@g02oBBy@;62~`;?blx6 z_0K)bcfP&F=FTP`y#6+CZ63m`V0XKYJhXB~&!{>j-Gbc{) z%bzcK?BOT*uaB*;WSfn1C-~hjKji$FoD|zI;Zl77bq>QFr_cQ%rM^g>THiE*hB?c0 z{O6p}ZD8o$bwBYLGEF}0XM6fKH1D)cTl$FNKAStOa1prTTb~n|ek;2zHq(#B|1@6p zRf!KIYc^T?JT}7_7l65N>pI(5dd$;B9v~}|1L%C^?~^1Klix3K$z>n5Hk-zoFER4J z+Mfg6Ue+bAmGhi;lAGEW;vo5w|CDp@pMrEkb&%-aWKmPin@C@I=>i>V8~+|Ti4?LF zoq1`xX)p1XJyT-WI6_}D3~X87uAx^sS4G4W{#xG@P-dpOGOxMsV0?nTw(rdB^m}{g zvtRR;Ebf4V89u_Wx{oXQD|Fp=7`LYX@JVm$M1f(;)ho8`TN}Gc5?pl*fZHd=oh1(& z?s4#N2XZhO;x8Pdeogtjhr}n{_&*xdv2D{#bj+lakfAUbq3S+5G3_@zSd(i>83Qao z1<3`w4?F=I%*c;DvzyX}4ho7d0V&ais}Bt6&A(118>KvlCIA2+07*naRGRei;G+7D zS$utWT$6X#KCO?ntyY>UD$1zfDhL!Jd!$vSIEosO87mNE3z1C{Tdg1)6vC#03WgB{ z2_Pf3jGzfbLzD4&=IMtq7mkaBiIZS9hQ_%hmXR;mNmOlCfp&=i&o=y7Y;tm->YGmFO z?PjW2>s_aIuUG#TK|pn-@dD?k1 zB5bF7D2`kV^`d+5`JA9wH4A*>^(&g&OWW{&?G3HcALbwaX>>fM{QgH}$GLPV2m3D#+0TpScoigky0M#NFK#K6Ve_!(DYEVOD3Q%7QcBJ}81ZEu z`Lo!*?TDGxJk)TxBR^~ zHQ5`nR5}-Db0{QtwA9^4+?>BF_*dE6>b5I!(=+)zr>~SJWHVcg?jFu@E+(4h&{f3a z!mrR%k@sqCUx_p4FRuAq?ta=e##b8iQXw3ETHTRJ7$Cu!IH5}!kDo^{hxC+x~=iDmzmI(<*lvT(lk+|W0umamt>|Nd#TI$eF3 zn*58n{N$Cd%>)t!O7UvCCQRc#gU;_Bf6fwPk`VRL%fg1qw{&Mse)c7CCH`F!XW zx&r0oU{m9(D}^tP5MbL=?>^9zDcrX8=qUg4Pp1%ri&-x(2332g-F&y8P?CHxKU_L?-O7tvnpv zect{%zCoK+_V3&NC3}D9tEeyDr&jfIjdo{#<-7js>?y=G4?hb+gu>tH!PT1hKb0@> zv$r4@`<3(bMK^1^nU9R_c<27I-nNK4u2gvDsgXC;RCq2#G2ZXd8OahloB3_d;!{<} zx_8x!557TDwGfRDhsR(yWUT$ti2I@>-5yK12D=J&zFB^s8o8LxXq?;c;0>>6{uZz5 zc3{iE?WxkwE4^DO`M*8q8I@gf92$gI$1P|0$yY_5fIQ)?FaK%0MYlU0l%705xzD-H*9THtV zqZg0VVxJQvHN#% z`mkRoG8Gh}cSKoKOdNSk?)MoWWxY}Xv%62- z+8+~ranyL~>00;Evb+8lYU=)KEXap{7!I4Cq3xg{L^gN*0-vMKT{ygusDA4Cl0k0n z3G>#22@7;l4lD&EaC0pUGI%h;< zmKBnbf3=*vTiB~5c`MI-+tftL)d=F2bTL^+v|uZ@Wmug_f371^UA8_i^`eVcj8Wi2u>ge1%p6lgctv_AuP7J4LgVsr<;Ji~w6 z8~?sLukZH1-u(XAB$(mU7Qg?VxcyFVzJJ%=(FgyU_loOc-x_|AKDUJUD@7qW?IQO2 zgsIp~!DR79+mq;HH9^eBjK^$NP|#G?`Sqg25JDKox9|Q!0K%3W_5P_6K3=qtSCnkn*bM1BVO)JpK)}Vjir5-Qb!3BDZ_nK%H5Ull?g?W91799Ly0r;0 za4Q+x^T0g?9#XxBn4<8-onI|(X|%KjwNN#phaM~LHn~;CNXb8X<=bBlWL)kGSZ03- zz5=CI?%|<{fyu8d&h-!X zF8nnT>RCt&-5C`%T9^Lf4OH5y8Qm+cSpzDaCF#@+kcfwoH7!BX6?py^L|)!ztMD0aPkHb zvwH;lF9Y~JjX$xkcNu1<_7Z$FG#x^nBPyZ|>zdB;fA$~I&faew+)&mf0h6A zkbh=+-2wThN#Fe5+_Il>A^rAFwKV?&F>l?3-_uTnokS>{Xev6f)4ID0;mus$;p7mU z-#+DrLfY)~JX?vObl~m}SYec_3%HTHBC6Vu-qRuSV~4o0T37cXzqqrgxq3t%)pKzA zvk7a1V$AX1@}8Eyc>G=Hse<`}b@aVwZzn%T-0v%Tck7R*kE18M=`~j`nttih8qk~_ zvS1Pc^VM+`Wlb0c&EW)H{im;G!M}}>QIANU^*!_E{(*ww%kg1pN9|aniMVyv^zhlV zvG#P$z9^)hdTYWN^dXk|lZ_9h`>!hpVjGk9|MGC#?g!QmvXSbhnPL6H z`_BHN4F#RI!!pq~M;Y{Ya$nOu>CDysSh3ZgMUkGov#p#amoR=VdyclO&*lYN)pagd z<Ad4zFwcBAg%9AbR^i|hx&Z}tSzW!n=HN>nE$Lc9=_rqZ^t ze%gy1bG-ny@|EyJP|ek_14eL0Vo=^R!A)!io|rdB*{|GcqD&imD}`fn&`PDSIt%~k#dORpPpyyJMQgKietWHTg7iiEe&@ zsteaSop0NQs959G8JuDnZ05MTGG0NX#jMK3oP+JoP)KfS0fagO$uSsqy5l*C+X%Bz@(@}G;1 zopLELizk}p)V?<3cMod)iCwGfP`R34j~$5dKM`-JgHsP-K8YXaQIzbc7_<#s#x#csS$ERZ`7XI^8a=hI-M$B3?m5MnoGIt-)pw zcVZ4LkK*jV(OA*+uhtnx+C&K$I*AK>EGOG* zDQEws2ElX*u|2c~q14N1`ojw+KTZ=F^CX6xAGtj>7g@zHjI*UAem$4x`iF1mPZcG; z2a=3+=ri^hXR8%|I4z`xUX{R9%jGs@c22MZ))fYiRuTfi?cM(J56pn`wCxuLzTjya zWTaw;MA7R{&4l6+d)|p4gr7&-%c|wE4sAHWkn8MjR`ne|fbilmf@xex@?8n;oZBv1 z8)uLB<-l_J2AHa8_^z;K?)>=Se5#9i!3`yR7Tdtg9c#(o7q^cZiCps6w#DRa5!Ex> zEzEmh+WevhOaPLN$a1h+vlC-nt9YGT6C-k23!^iU+%=Yqb=$E(^CiU9)n&#wzt-vY z`VGubW1Nw5(=3DKI8xQBK57(7P5g3}7TSsDx|fY~@dkNe9dM%Z2RUpW&xAPn;5JN~ zYr5JY(jKJpngx;qn4rLpid^x{hr@fHOh%ulAoQs9(V~vHm0Oq{w0-=XKPu|+?%XU` z7{4UeZJt=$pe$WurhaLI!PM0sHm(z)h0D< z*bZ~lCry44j?8jih*hq8u1}eG9nj9e>(3mQxL!Y_-^<6jvb2-`)EU}?E$ zH}k|3_*dEGN14HMTFr5pY*i;qMgoW2d(};RUz;|_yA+iEVI#hOA8VOeRfs`#g-7|h zkVvO5N(_q|)ojCv=$}Vw3&L8e&$jjPS8E1Ivc@O}#7e2pG|4g3ZKP%p+gZ$r3J`*? zk`XTFOd51{EIrl-Q(0Amu$9J%fp6E08k8zrO4+G?3?~ttfL#ElDmpS*gFCvx3EUtj>tXN$Qi4=M~j| zEH+^3L}f*-1pK~_zpvmoWC$)IZafR;;zs?|!(5S?i85y$lTVfJw``5BSO}*a(3<6T z(Sr7{1DfQ!)Kz(A`!9B2&A1Vb6j}G)RG3}JY_ZXL*u&VSmWY6kX-7dqgYfEsu4LBq zBL#j(?TD6&iW*nQH@vn(89|MWNHSj%gt`ZMAk4T;<@;$_?8yLQ*~VC`I*RQR(58)^ zt*_@KSx^im)HR{|@j^UvTIkz37sy0hJyU=+3yWHc#v+bSt~bfS0@YNhLG-_^JS5^} zG>*N>m+f^QY)HixSS|URC9^Qwkmm39g<7ub6$}b+cL`=#q!xxncK-<_(w?#-XTUJ^ zHDa-nTwrIn9_@NBx-_z+B2RC-8O1!;7_+;AH>W<6xl|;~SF<=MZzm zUu`k1?Va~D7>m^<`>O})CuSS_f9?;X58islP#=A875-Y67DoA1IPU9+;kDLP%`!#) zn%tGdXS3|>0^JvFdYM})LP{cqoFk)=rt15%L?LqteY~)8@t_W?)II+_)5*idSBLV( zeCgi9zSIo;4nL39H0rT^?EfL=nh zypnq4mA}W}Fm?RxE-fyhtF@-8+yk$5J8~$W=M7@Sx>4d~|L79>L?K1qa!JP`Nd&_p znnXoEp^~53jJhxuUJyy%Ehe}*?g97cWxg?7_>6!RGS0MK#wDJfImS4FS1t|C?q(FM zW(hc2qy9}=UeVqPY_x^ZRVAteH%OU&dRZZik{}e&7euURY`IqtK17V-T|lp3+;e?b zg|#I5 z|FnL_ABO&t3%ZXDlWL}Jtjg6Ifh32MmSjbkCP~Wm)w*vG!uJh7CI5DnfiGew7-g6?Gonc6p?lqAFZa z4Dv6a`fs2On+1c%*b0$~R;#pGHfzJ~*m|XKQMlO2NuGX3O%8r%a#Bl|ys&{q!w2im zddUlejP=&n^l8TUg1PRX0QNN1@6y%-d%0+H>ctPzTE_vP1w5I!V!K7rC z86MC*`M_>gTtLKC49!vG^K9oz;c9EV+N}7@!5`c=g09@=dGVLH`zG%V%}h)Y#I85a zA!;TzG%xca9bB+qsJAt+gAB3jeBR|4A)_r~N8aFZVJXI?afTETP^3WHKPaA#F(flL z3?<>iyeJK=DrF(efvgpf5Gbn6!Yh=-h80M60+G+}oIR82b=RxBIT^tikik*enVnG{BG@)VnQg30jC;A|{@>wv3> z8mngTPQvFX2Av$sTxBKfELM!^45M}SO1_SsprTQNgsFzw$Jw57+SC#=mf7rszun|8 zr_c%hd6*_Fc0Fy~WPNX`5VIWF-Ox!gBUg(ZMq&k)jv@)t-BkGO$K>A(&59_7oihW) zQ?@y%d{u7bioZU^93>Yjm-EPJmD7fsAm+bSne-oXc{nB6eWk zlu@tnbttycy~5jkn84_W)df zCI$h1MMC*NTX3*Kn4EUgjf5G)*9uwKda{5M+4;OcV%NB%(L`kWxY~`2vG1ypRDT0s zS9l>F9-C>(Q)Mu-K|8P>Ey zC-FKJ4^-{6)_;Ll$hm=QKiSA}mRGCWaM7W8ZI>jCm{QzMrWZ$f0PIh;w9ISB%Omr)_X`urdII~{rRWR*DBF60-gI3%3Xo^geNF=E}t-h%Gl$dIVvQH?@OiAv>p#9kvR zi*z1|IHI~9%++R5WD@mL%vN$W3kkD+%lkO^hJjVl$0mk@DRdppHETGCvvkGsMU20O}YN>@HJATNNi#4;OnQ2xkH}g^E1rI3; z7A=?2Ed~KqTJ_2-W|pFRuh-UyF>X^1TWF%AqC<=n2q|KrZrL0Y=eMLq>S9KhO(}$R zsB$-ow8E06xDnB!+-{U-Z3cqhSg6l;KNt9z(pgS_#-cL3?Q^*&ka9fwRlg~LaCkl{ zi?3D7G#ZwTf6>WKFe{)xQ(iy4{A&FjGr#o3og@_pb2?>bK^-wRZUJ}C3!N~_$<(^) zR}_jDw*aJ3HZH~-!PdbX1aqscJ&QU=lBR}Y#|zGf`NHok^C?&Fd%NiM;wgj0+LSjt zbURbUzUE629saw!s1D{RT#^n$gt+6`(ih+!m57%Eog#LkUHb@pGyre06wI(Q6|D3X z;2(}}SwA7qjB+Umjm}84;m#+x%?h+48wekAT_sptZ%e!VCG+8#S9NCYP1?MO&YDiG zVG-vtgI;U@R5oWy-#*f>$n2O;^sL9qE2<+ph~&08*0#FWy)E@qvB6Iwu;=}n$ezZk}k!r(gnT|_LCIUT1Z#7%nQ8(Pr2@VyoF z?%#7wR8=IUd`Z9y;ro61$?1jr`+$85vKM_hTKon7q!*1(Yx`YmOAFooq(j=B|Y5Dn?WwM)U8PCq;M-6-J&~m+V1RPQhUOl?n$hq3H~5zG!As^IEi*v|GBPg-8AWFwcKAAe zCL=?B9UICr+#@4%B|f2~Xp}r4zg0%&eIpk<{)t6_&-JovdV?Fm=kuS71V1#MEKL8G zj7;Bg)xzcCKPIg{mywyi$i|m@I^$lefD1=G_e)J}{Ns>oCAi9ThI~0o=JNKhWMrN? z^uWpsZ}@BjHzX3<{kno1fJA+d3RQ@s_S#CPEBj8XXi-kO;r?jY_&P!$x45Wo7AYP? zY>?azPH6c)Nk0VVaFn-6d=|lfj5Gp)fX~?Q<-=es(T8L^SP-o}w)*uqKmcP;5Az|N z9!nXSn~g*@9rq#6?Lf66T)%^P{B?o`cnzST*Xg;Nyxl>d-3rlYw71f9Cy=Y}dv@qM z?e&^1K=4al((}U8ag7;9koaAG`@H4lKWI9GTb%0;EbmD&QgI;z9sMp@Sy--^9m+oi zOyQ?HV4iK20@*q-(pp{jJ8-+Ih)2EtX16?+S13TKF^)q!jg&$_9n=C_N*)3$K3wTJ zv`%xHv`VY%m9=nla}zs$(h=`!rZPIHEZ%1atD)cM0zP<(M4Ka9XG)qeu+L;}maD0# zsAj+Z61?whX@1EfKDOO2kP768{xz%I!MZa?2I%4kMzSs)=i{L%K*#XYr9^8*8(^IB z^&+c*hGB5cmzqdX#1W%vaO_}5j5_&C4e3j8pqJ!tOq!UM!?Ul~yaUWAPJLYh5ErOyL`%$_R( zSqX8(*k1J`>rj|QCEAjewgD-lBd9?x=b`lK^ISRToi*`06zcW#X^le_1Hdq$L}L9m zRVYODjH(H?WGDiBhFqsIU_rG#ka_KVMOVw6EzG$+G!Y2Ee+X1V9e6+%7G3pfO#V}V zf+Pf(!~CdQLTs#aPlyN#sdF{Gz1dDcz!5+h!i#$B9{dKOhPT_Jo=V*s5ikHbJFMRa z$*}<;_0qoTkFgAx8WeW+yu;3NBC;zu)fkB!`ui}HaA@AWfhy120no9QNI9fjhX&+e zhdPV!3&ucp<}`IgYX~UUHy(W<%6#HyNKaj7>-EFVftHZ>9j%b&$RQOSC+=dE^?#-y z0Gw7U27dhmL9CFbhkpL{ndv8-Au&i!u1)_&RLKB@r}#B@bKkC{#Vh8(x+J!N3bC+b z4~WE@!%i&&9H6<(oUWG82N@s)9-L-6#b;>t17Y-XG!E4?bAUl!qN@h2<73}E1D@=A z0&Eik`OJ-NkmPpo)#E=PBb8R`<)12)+N-3xH&8fO@UFrVTx1%fU}c_gZf3#;GL$8M zLA8ed+n}0L&jsqnFCsB*mnGcc*_0R5UTF z_Jv?$rE<b{ccZsS2FnPNWx8~&p`p7|! z<01-=>zQ11;G^m}%XqU9)=9BQEBO?@dZRmeF?kE?pnJsXE5y#|82s&x$sP7A#2Bcl zl4qdY6qrdAvJ7V{mzVL%Anlq?Mm`7sXxSmVRCFdU`vw5D!rRJ|*g^Y%kM^eb3lpEm z#`+nh0wsj>a|;^X(tvjJ+HQmNhOmYl*?qF|hAjBwBR7vG)cZY21P7A3_9#CErk)S* zQce?qKzbRVamgASvDe!!WaT=P;}1aOP;bGiA(Q4Hkz=b8HXcddBUwdBHVl-2AL7@R z1iTVrt%Z4+8#z5|QP~9YaH-%?J&Hsn@JaR(F@gFs#YsFtrT&b{>sdy1Li&PdR`20Q z0#i|We@zODq2Nb^niV=&tEdE&S3g?S0Ya?4p2piZBFn3jz`YxoWw)Nkd;qTohg4K5 zpAf(+A>Eez&Kw*`C?UEXe8LV_020r)>M9O^oE;|4=D*ts!l=7H<`BGS0($LtV`N1i zz6_betVA;*#PGFw<;QIAIU!FujO3zwQ#*6suaPXnl zXwDoyj-D{6@boRgBh)$~qhZ6xEI-+*jLMM!*WQx4c8Z2qSldalz@^V@Gx1&KUj((b z6x1FlC5W3jO`!vrtmq8@_Ze~T{W)^`T|MBN_gkHMU=O6(Io{ym+t6?TAlN*|6aD;* z2-1oF$@IP@-86j z`$i`Vi{l?vChL$l&hDQEt{5SqpdRjN*YvHoYLogC_aT*)Kvz)W^x|jW(U)+dniCo$ zZK+Cu;^yPMkS~!v^+`j-q+bq$ON7=-(XS8Kth5FySJN2a>8d)ZhkIPN-^~$&oF{du zTqHm+QriDx8e)S_L7KPVHd< z@fxUQw}vi3o#HTB-BW0FtpWgySw{blZ;6r0z)3e<(TZa$KPo`!WbADHJPF7{dV9kg z0_=nEBG0nnEeF77@<_RwgxKr-5dJ!%E#u#uguvPX8FWz&vVpO3!WwjqEAbyg48f2_ zx+X%xz?ah#Bx_Rz%F-SM#)_6)^gs^{Ts!Dk*KLn}O+)My_u%5~U+@S@sSC0xl2wWc zcxUlE0w)qsf18`n@sogmp5m4&oHf8yQfg12WTR^AfA3jE392`UJsi+rP4#?=@VLQe z2C6_UFK`cB{D3Ls!|X{2(+3--X&4A$X3)y_A8!L4$Nbk>{mM|A^wb%-d~QbVFgW-e zpX;Qda@8yznCVKfGg8Ae4IKHtvGd%_W@9Gp7RgcFG0*`uy-p{jDenNWc~ zjUBWL={=W!SPN*dyzy35NBr5Mgvx${(vqyQQ&ycdCG3}B zYrw13(P9&2iND@UpG^qYB1djC7)g9eIZ$+4F@Td-V-RgY3SDB@$PS=WGRGjPoqi2j z?XuZd_BvfkulED45q4O@!l3d@E}g{o2TB{N`i@9Yp7FPHZUfPj+aq4tBQ=H>zLl!E zCyh0#^f!2a4v7q+#eOM*EY{)V+b9dn@KSvfxLncT)=tnTq9k@~?D%;f<`ZeHukKY& z7>AJTN=^UC;G7zfEB0!A!-jgfrideuhzvYPoJGXW@M4lF#YeE=m_Yf6*n6E#ac+6| z>Yha!jkGo{2*j^FVy);GGWke~$#+jG`vcbfh%wS|Frr z`5~a9WtKcOD1nz^k_50|?e|WzLsp8mvReU2hxeY9b^f+Bds_KDGLtHL%EZdRCBv)lgDv=P}6HA)xIt ze@-_cvA}12AEr+&ZbCv%%{TVa5)QC|xL&>4r)V6~7+k!#2i#<&s2cao-nebocMuA^ zreDi)z(8@LiIgjU4uN3~6l&JeiNwBYC-}Orc0XGAp+#k5ieJz|`~pGR(}=6>85Afa zLIk8v()s{FYK*B){Q3sQ+nCP`XNktx`lX(K^fw=Cbx5HH$J6Gq_`Z41-!1b zy@TdvNxLAn{%aew<;D@^CqM|wIZ}-I&;?JBv3-8zr_ZbJ02sTu3i?$ImBNgQKfeIJ zEr14Qfa!0byzZMZNUE*&ONJ(~rdoPJ=(`WnpspvzWk|z*Z{4!8G?j!6jkMm;OKDx*t8s%YVzsfq=gL3_;6NPsq?PCiRh=;a|HK|P zXbu0z0@)u6Ab@T9vc5Z{Zf1J6v!d0;5&S5K<+XJ5cH1ef9w>*g+;jkWg>`2vT2m^i^zqP0Pc85&n7=lBCl`Mq(P z(l`WzJ%XSDREakK<y0kcsjlmD3h}f=bY^bgnLQdjWv) zsxCmeM+ETQBLAfmG^zmroROuNo405<$H$3(N%QiosIF|M;b%T|^rZreQfk4cX{I_` znh}%deHg6KU2-7f9kS)JGoI)`s#!Yw`v8%{NuUs(gnFLv-{?06!EpLML^>V=vV;`?2xgZtzBN@~LID~e3tp)OuOU-bkC7LvB zV(TU@;zg7@%u%Fu4iE{O?VQ`eyRp{{^HaVAmIlMhbEBkj|3kpm!b?51GjpX{P)wWM zk9g&PiIJi)6x|eP;=WScuPxq_B@JHZJc8fytm@{F4f;GIY4wlluq8V^j)IB@DJTjQ zb(#4`d9s!}&O<$cUMX?vuh>Ya)vpI7Gh}>|5puQ;kZ%k#hB7}(9<)z!aS7t9U^a_O z&gWITHA?KIDJ`AQpjoBK$y$f$WFw{VmRSe?9kx($^8s{FJz_%}Og?h3X9jR!>(xxT z?A~BeFw`Nhf`@PDwTeh7nEQbS#McROM+X<_R8C|`KsS1YP$g?~P1=6^Ni1v~KLdR7 zG-nX1&4ZlU!8r~1FhrO2%^D=(UI8F@ss22+GzOA=C(j?Rd}evGF~LwX63dt zH+RkhMd)ReA{7Rf*_iStpxV55WE&nzz6A{5lpE2{1de211G;IIR_{6M3c->;Ib}#1 zY@s>JDSNtnk3w#^g!JH!zY`k(Ro-tmPC5lKk@Nc-FGf8ULOMHF_qO@tOI@Hs;1^={ z#Pn}>DCrx~HL1=XmYe=t;*u%SC@`+>Emf%z+-~VH_J8$>!uzOba=rwNTi426&-eNp=(2|me6lagNtN7hOsIaWO(LiaN1yEN3Ypqr|F#z@3Cju3RRG72B$$~Qzz_=AV zuOJ0dfF(ETfZk90gB0wLK~rHHA&^I(GNw-jt4rtiDp0GlZBN6+Fct#N*SfMA_!yfE{^y@Br zvpF0(U+Niu*VG45H1kUQN>XS^0&tI3N|q?C{7jw{Xo*D7qVz_!gAi+=g0{nKH3D9Gn*=+2KEi9j3(gKmXvH;2P{t={F(kC7g*&|FT8>s+}1|gkR zULBJS)NHUqlWq;^=u|#|8UtZ2!OxRsu#*5GqmW*q3M!D4EYR~QZv}lVQN^SLYAGjP zc&MwMma-z_Whv$^rbFQP&?m&&j_g-HkIesv^pUc8fTR34Ng7`H|8SI2+CTt}vp2C$ zzNuMVku%(&6TrlTi%5s2FjuHi1WoL{exO>SS=kVd80Nh8mT>mYTScTlH-q z>;Xi6`RUFr4eF>~klv+)sG`c&%dxUAu=t0i0mK9pCDmG7QV4N{2p{qN)_;N;sDWyU zz94MA4DS4mlX>e^4k!%oU4x&;E$vB*fnePDdF+?pfYR~uT$SwU_>!tR05n$!^l8x3 zO9?r9WS6uofS_yFP*tgHln1)bA4V=$sMZvz4Xr}+e>t&GmjD%voIJ)sL!yba_nvH+ z2_$8eK=%+1nLcT}1mQH{8ceqPAR&<=L0j(iF z^Q+Xoa8Rf|H7H$xoKbDog^INLP-LU|<_3q`A7L)#KzvPNTBJM{E(~g4WugF6yWZm@ z9rjlY!I+alfzG^yqoTVS>*9kXHJ(9LfSMI6I@R_ZE6t<94zpwa z)o?&@yo3Yp`hhJdWb>aRdjf@}(jAufh)XFF`J5|lM$mFW@v#OwrR}&GQqB%`7NP*& zAAT#Hi}xA`Q_RN^;Of&zBuEN$2NVj$#5ns96KHp|R)}tH*Qg3pb@cxsRl3~Sgcitw z%BGTzRfL6ki@#fa_2PB&|K5E}b$ntaHk)Qet2v{$#3atZH$d#D=e_9dcdei}iR!RS zeH;Sr3LOnhs2t_~&Rdx@( z6~UWs9~wMtr3mfpyJ>UXBz7j_V1xpw%JZCDtTi#|Iz(>Ie_ius2Xv|%=s<2uCwQ&v zZk2MIOF5i$snc)`z4*Vy*|G zTU`G*glUB0=e;RlwH`yA{kkQPO5JFYjZyuI?QL^JK^4w4Oo9>;GMri|53LoqU6)zy?^^hUKQh%o%b-C;DQ{%R({_{GsFJ-aty6grvlHuVerL04 zIf0GPq;zg`1(e8ybVrN^6MZT1TDbtL7p4q`T? zCA9zTX4(U9+QHp zU-%xp+rGJ+@-q8VvG=hs>i!4hK$4k7ia(O@4Yc0Z!(^SP8ScNKVRKVBwFvOx zJ6IQZV8*3%7{m`m!9MS=2RIIa=^ogpHQ{29ldo(MIH0L)b3F5XhJbLqo}RQ&^Ci<4 z*dPj;(AHy*Y~ou2Hxlw|4d@)F2!5OM`rMumWT+6i@ovH3%}A&Y*&{ct(fw1bCe&@DX4YTC3ogeRng5M4BKGn6GkoSOy2CdZQ!Z)?wxV47pUUv%8 zFN$ttowG>+0CpYuM-p_V`jDE+Nh)Y1uM~l22{hoU&7RVl3JCl+4}j^yHwi4VaiCDR zNli`ZGhbg5#c4pG4_tk2M)U}G2wcgm>Y`8s{Ax>{?*0EmvjpN~jVQ6!=NO~?A92K7 zx{k=|FZigS9>g1Dy@1-*L1Yiu&Fu#*(9`p1P{iy>B4FBZ5^+Hx%@Gbf*5?_TKv9g5 z1{(#cNYB$gLdbrtIq9A@g6B$>!bUv+h~aA>y!$4A4}GMv%YxOpl%_-?yL41UqSB1)|aJHWDJ$eD7eL6k+f475RCTpqn0Erk1=8t)$ zs-18DR)mtjgBV!@lXgxsTu;Kbh&jC*AGL3%>wI3IjLa^Yjrq@)z}c-p z_EHt6Zt04bv}{XusRB7Qt!q?mRl5xBww%$H80ly>*l^nSc}lHx+s}*Mc~{yt4@L~K zBI-df-^|m2JKdHp?Lm(W7PdP4=pSD}evJBnXy=}^*e~}=xgAgf<|^f29}2;(uGFv% zM(vTQuitw&9PHR0JrfR*!V(nKX2 z3sc61LBQQq1jvYsFFp>zEj5RiB2_t5I(dDpd5v|OYFC~7Zj<|@5GTRJ#tr_bnM zEGTD-{d$^5#qg8=?wB@#KKw@&nU@mQh~iR%{~>P$Jh8kCzTmx@M!Wjk*0wL&%mOw< zE4$|C2fsR!lc^gsIjOl~8{r2#rMMya>&~&t()t%RjVczYpI@)*&8Dv@0zj0JIsbk( zIII&&OPO#b97Np8yj(u68OPfJ@>AyKlpz9I?tmGT{;=WB?OW1w9A4X6?Pp5Qsm-=Y z%gUB+G{C;-`p2_)*TZxxlt3oS%KeCmpv{) zzvy(PMWlJ^)lGLn;-bjmx*JCiWrOCq7v=;b(%Pz^W(YwHlRxrs> zxJ~5hhoXnLJJ7{t@()%Ve1<8O3h>@{>~3n?11J=4mU5U)YmY#g1KM=gN{@XB&&&$Y zd}VM9Quq1;6YXF)9Jdcr_~oNA*5%SySQF@zo9e@dyg&MFd*Yz@#i7n*@U~3t+l|*5 zpI&EYEi}hM@8%b0$)lh-8$?6mrX@{o)lc=($FldPo5cO2nye;?4f=6Ty)Bwec252g zXokxZwSp)OA62%HYFpw(wS5aYbk;|QO_2J><+Um9Pt(mLeEG-Xaa-Te*?NdRk(nhLJe{xn6 z9=|2c#1)cQ#-TmXNB8b6X;3raaNSk^JXz>{LhY*rmW4Drp8!+9+0N1c($ozQs@vqM zNCTuA_sv(^q?w%0ZrjWYhxlEpkDXmkT`k7P|8oQb*B-NZQFq9Hu=ceGhF&N-@_#35 zMZ{(ZSBxsf9F$IlAjp2n-{sxp{}B#3^fMj%k4h8AMV)l2PCzcFLE^th`Aks{>ce-T zAeL3;`r)a)sq<~;H-isNpwVf0#xJBfXVvnVR7{hfjl&A1zHV~M z-{+lnV{vLT#*ss8u9H5?W%Q$`xU(;++q$HwK9!X^@NeEp}zD>%!v)#o~1u zgZ*_F_*tg*_j=z!vsYq1MLbBs^Oe^>bmRoDvT7?HW<6hyKRXsTxFw1r^C&Aio+>X# z_P^&G8HK4S!{ipI)?cXk+Y~a~=0z zHL)~XAni?j;d)^zBzdAKnw-C@|0t`279aA~WrXKh^myEhq57Ig?ZkP|jvNr3c%n7u z*fSA5GP9_z!l+bQH+dBq5+ZO4;HC%rIaegRop&Sc*1xdNG;yXZ)a@|SED3z0=jCml zem)WL{>(#Jx}L-3XL1~$%h?qbT-fP)|CQO?>tzLQaQtWEf7v;h%`k?;NS`G>FKQZa zJ3g}NJITH$8gfB*b&{9+_WfuPt*n(C{MLnVfm}KozGG#%Rrbm3dO;U9c+jQ1BiE@) z+uYaf?F9#N-eJ|O@8l|*23S}(yCaymML5e<;ur9Z9T5@fhnckto5D{m*1h9j^!K`P z2`vb_(VIVrUU|%|^XG@Cq$?oX9xzcggyo2~1W(UMirFfk9~i1wL@!Qa24I(ivEeZZ z-sP>r-?BXPSi8#7ai{r>SJ3q^Yr713Dc;*`NV!CM81>#S#lMuC7CY?uu%hUvY2 zROFJRz;T_j@x=$bVAe~{oa0sQCkVVQuC`sly3iixj*$J!!fbrX6<54w=CXxd4Z8M` zhMm6An#M#e<>blGfs5|AY&2U}l zEHT(Ok~w8eU*Jgh5_zH&%#G+S0};~*5P_&@YR!JC-h%OYgX9>V3H#mb9ejx znU&b&;kZ08UA%jy7gwsK9I~XB<~W@&w*ASrB(iE#SP3sB#KVuC{xEYEd8{<0(CH%T zmr4B}2HF+1IyR^VoDKS*Ux7R9Fq%?iZK52pV#bO2!qDtOV2z_}?sC0Kh()(4dG@AN zljFtNhsisitXidp`E?5wd!IE>vkOPU^E~eCCrS1t)4OzKzl&Pe)}4B4_W5J8J-yAg zZoM_Pl$@=O)bEXG_4UC2@~BH|8Mj7mH9F4Dn(=dUg(PPgvQ{y2Zq!$WfQ3-`R9oij$ws7*-!i zuiYDRdC4memDOKzYO>VE(Tw`%{TZK}I=@~!rqvFMUgT8Cg1}@@pLVOWaUiK5$Ghr) zKT$GHE91HCl&2&`XzY#X=mGTQSCD z(!_>SZNMwn4iVU86%FYWXS?fCLlH_=?$44wq=LWj!>v@U9u65XtrkbSNm%!2bIXs~ zNZr0szLK|%dcDi{_{r~#dS3)bf}b$8=+=d3NcQ-Lw^g0OM*+ z^w)IH_y(=m)2@NJ9C~N6a&O4W5C{Bf`tAGP-6lmDb@cPE!=^m-^)UJM>uYU4UroZ_ zr!kWcE&KcSn^n5FYK6FQzm?_d9tMAT;r|8f0~7q^teFzd8S?UpY?qmal4lF`e!0+o196YOZvLDyXKwq)^bPI9M+hl9KO_A z{-~|bwfniTscJj-rjMRW>VNxt-*!u0mS1zt%sggFefb(!9rZmO#oX&pt;gN<>5t#^ z_h0_1?b9EzJP$}xd-a{Zd;LbQZm;#~_MP6mc_Z~V`P?C>+%gz$0x{jUe;!2qur5j$+I3nnpyPMCE3g~^LO8M zJM!!Kw=z~)*H%8Ao9*XLrET$9&A| z1vBsHZ%og8qWAfH^s&sV&ocLAc7K@L#GG5cuBP6vz8%No(lL$U)jorz-6gyI0YPj} zW^-I-eNoSBW6qCxYd*8x=v(e&$8^-6+f%j~<)f~BF7@n(l&|R-D`kA-opnpGZOrwZ z^~Lmy9cl&N;&0CQz@)FEzEt~9cy0Nc))VTDxcjIp`a5%sVoMIazxC@%?)%qpmLDl~ zxy{E=#KM_(ZL5y6OQYTT`k(pCn3!Kb8FuA?Ks|t{>-%N@WOIkj%yxepb6ldH8C&P& z^O(-M<9R)ka1=lKX>ky1WnQkAqr9tHpEUD`>D?kpFUzNUZA72S-_x=qy&lk|+OM_0 zX^pGnSf6{WqOt5K|2qF(y*a)1v&J3GTg$HX=UA+DS2@2PfVj_fyT4ThV{rlJd zTt8X1#$?^=!DFpkdfDH5ZQtv!^!fE5y-_pWtvRmKHO@U= zBcJ~GU7!B=O~3#4i?&a{kGdr3wtFUN`}Dhh`}J?V!ls}9w%e;6FqY47b#^EK0000