From baf33dc190a8fdf18439e5f8fa8b67152cc0779a Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Fri, 31 Jul 2020 15:05:22 +0100 Subject: [PATCH 01/14] Attempt #1 at finding all player contact in a game; then, determining who was the attacker/victim. --- .../events/bump_detection/bump_analysis.py | 196 +++++++++++++++++- 1 file changed, 188 insertions(+), 8 deletions(-) diff --git a/carball/analysis/events/bump_detection/bump_analysis.py b/carball/analysis/events/bump_detection/bump_analysis.py index a8774062..0a930772 100644 --- a/carball/analysis/events/bump_detection/bump_analysis.py +++ b/carball/analysis/events/bump_detection/bump_analysis.py @@ -1,3 +1,6 @@ +import itertools +import logging +import numpy as np import pandas as pd from carball.generated.api.stats.events_pb2 import Bump @@ -6,15 +9,30 @@ from carball.generated.api import game_pb2 +logger = logging.getLogger(__name__) +# If you decrease this, you risk not counting bumps where one car is directly behind another (driving in the same direction). +# If you increase this, you risk counting non-contact close proximity (e.g. one car cleanly jumped over another =/= bump). +PLAYER_CONTACT_MAX_DISTANCE = 200 + +# Needs to be relatively high to account for two cars colliding 'diagonally': /\ +MAX_BUMP_ALIGN_ANGLE = 60 + +# Currently arbitrary: +MIN_BUMP_VELOCITY = 5000 + +# Approx. half of goal height. +# (could be used to discard all aerial contact as bumps, although rarely an aerial bump WAS, indeed, intended) +AERIAL_BUMP_HEIGHT = 300 + +# TODO Analyse the impact of bumps. (e.g. look at proximity to the ball/net) class BumpAnalysis: def __init__(self, game: Game, proto_game: game_pb2): self.proto_game = proto_game - def get_bumps_from_game(self, data_frame: pd.DataFrame): + def get_bumps_from_game(self, data_frame: pd.DataFrame, player_map): self.create_bumps_from_demos(self.proto_game) - - self.analyze_bumps(data_frame) + self.create_bumps_from_player_contact(data_frame, player_map) def create_bumps_from_demos(self, proto_game): for demo in proto_game.game_metadata.demos: @@ -28,10 +46,172 @@ def add_bump(self, frame: int, victim_id: PlayerId, attacker_id: PlayerId, is_de if is_demo: bump.is_demo = True - def analyze_bumps(self, data_frame:pd.DataFrame): - for bump in self.proto_game.game_stats.bumps: - self.analyze_bump(bump, data_frame) + def create_bumps_from_player_contact(self, data_frame, player_map): + # NOTES: + # Currently, this yields more 'bumps' than there are actually. + # This is mostly due to aerial proximity, where a bump was NOT intended or no contact was made. + # This also occurs near the ground, where cars flip awkwardly past each other. + + # POSSIBLE SOLUTIONS: + # Account for car hitboxes and/or rotations when calculating close proximity intervals. + # Do some post-bump analysis and see if car velocities aligned (i.e. analyse end of interval bump alignments) + + # Get an array of player names to use for player combinations. + player_names = [] + for player in player_map.values(): + player_names.append(player.name) + + # For each player pair combination, get possible contact distances. + for player_pair in itertools.combinations(player_names, 2): + # Get all frame idxs where players were within PLAYER_CONTACT_MAX_DISTANCE. + players_close_frame_idxs = BumpAnalysis.get_players_close_frame_idxs(data_frame, + str(player_pair[0]), + str(player_pair[1])) + + if len(players_close_frame_idxs) > 0: + BumpAnalysis.analyse_bumps(data_frame, player_pair, players_close_frame_idxs) + else: + logger.info("Players (" + player_pair[0] + " and " + player_pair[1] + ") did not get close " + "during the match.") + + @staticmethod + def analyse_bumps(data_frame, player_pair, players_close_frame_idxs): + # Get all individual intervals where a player pair got close to each other. + players_close_frame_idxs_intervals = BumpAnalysis.get_players_close_intervals(players_close_frame_idxs) + + # For each such interval, take (currently only) the beginning and analyse car behaviour. + for interval in players_close_frame_idxs_intervals: + frame_before_bump = interval[0] + + # Calculate alignments (angle between position vector and velocity vector, with regard to each player) + p1_alignment_before = BumpAnalysis.get_player_bump_alignment(data_frame, frame_before_bump, + player_pair[0], player_pair[1]) + p2_alignment_before = BumpAnalysis.get_player_bump_alignment(data_frame, frame_before_bump, + player_pair[1], player_pair[0]) + # TODO Create Bump objects and add them to the API. + # Determine the attacker and the victim (if alignment is below MAX_BUMP_ALIGN_ANGLE, it's the attacker) + attacker, victim = BumpAnalysis.determine_attacker_victim(player_pair[0], player_pair[1], + p1_alignment_before, p2_alignment_before) + + # Determine if the bump was above AERIAL_BUMP_HEIGHT. + is_aerial_bump = BumpAnalysis.is_aerial_bump(data_frame, player_pair[0], player_pair[1], frame_before_bump) + + # Check if interval is quite long - players may be in rule 1 :) or might be a scramble. + BumpAnalysis.analyse_prolonged_proximity(data_frame, interval, player_pair[0], player_pair[1]) + + @staticmethod + def get_player_bump_alignment(data_frame, frame_idx, p1_name, p2_name): + p1_vel_df = data_frame[p1_name][['vel_x', 'vel_y', 'vel_z']].loc[frame_idx] + p1_pos_df = data_frame[p1_name][['pos_x', 'pos_y', 'pos_z']].loc[frame_idx] + p2_pos_df = data_frame[p2_name][['pos_x', 'pos_y', 'pos_z']].loc[frame_idx] + + # Get the distance vector, directed from p1 to p2. + # Then, convert it to a unit vector. + pos1_df = p2_pos_df - p1_pos_df + pos1 = [pos1_df.pos_x, pos1_df.pos_y, pos1_df.pos_y] + unit_pos1 = pos1 / np.linalg.norm(pos1) + + # Get the velocity vector of p1. + # Then, convert it to a unit vector. + vel1 = [p1_vel_df.vel_x, p1_vel_df.vel_y, p1_vel_df.vel_z] + unit_vel1 = vel1 / np.linalg.norm(vel1) + + # Find the angle between the position vector and the velocity vector. + # If this is relatively aligned - p1 probably significantly bumped p2. + ang = (np.arccos(np.clip(np.dot(unit_vel1, unit_pos1), -1.0, 1.0))) * 180 / np.pi + # print(p1_name + "'s bump angle=" + str(ang)) + return ang + + @staticmethod + def get_players_close_frame_idxs(data_frame, p1_name, p2_name): + p1_pos_df = data_frame[p1_name][['pos_x', 'pos_y', 'pos_z']].dropna(axis=0) + p2_pos_df = data_frame[p2_name][['pos_x', 'pos_y', 'pos_z']].dropna(axis=0) + + # Calculate the vector distances between the players. + distances = (p1_pos_df.pos_x - p2_pos_df.pos_x) ** 2 + \ + (p1_pos_df.pos_y - p2_pos_df.pos_y) ** 2 + \ + (p1_pos_df.pos_z - p2_pos_df.pos_z) ** 2 + distances = np.sqrt(distances) + # Only keep values < PLAYER_CONTACT_MAX_DISTANCE (see top of class). + players_close_series = distances[distances < PLAYER_CONTACT_MAX_DISTANCE] + # Get the frame indexes of the values (as ndarray). + players_close_frame_idxs = players_close_series.index.to_numpy() + return players_close_frame_idxs + + @staticmethod + def get_players_close_intervals(players_close_frame_idxs): + # Find continuous intervals of close proximity, and group them together. + all_intervals = [] + interval = [] + for index, frame_idx in enumerate(players_close_frame_idxs): + diffs = np.diff(players_close_frame_idxs) + interval.append(frame_idx) + if index >= len(diffs) or diffs[index] >= 3: + all_intervals.append(interval) + interval = [] + return all_intervals + + @staticmethod + def determine_attacker_victim(p1_name, p2_name, p1_alignment, p2_alignment): + """ + Try to 'guesstimate' the attacker and the victim by comparing bump alignment angles. + If both alignments are within 45deg, then both players were going relatively towards each other. + + :return: (Attacker, Victim) + """ + + if p1_alignment < MAX_BUMP_ALIGN_ANGLE or p2_alignment < MAX_BUMP_ALIGN_ANGLE: + if abs(p1_alignment - p2_alignment) < 45: + return None, None + elif p1_alignment < p2_alignment: + return p1_name, p2_name + elif p2_alignment < p1_alignment: + return p2_name, p1_name + + return None, None + + @staticmethod + def analyse_prolonged_proximity(data_frame, interval, p1_name, p2_name): + # TODO Redo this to do some proper analysis. + if len(interval) > 10: + print(" > Scramble between " + p1_name + " and " + p2_name) + # NOTE: Could try analysing immediate post-bump effects. + # elif len(interval) >= 5: + # frame_after_bump = interval[len(interval) - 1] + # p1_alignment_after = BumpAnalysis.get_player_bump_alignment(data_frame, frame_after_bump, + # p1_name, p2_name) + # p2_alignment_after = BumpAnalysis.get_player_bump_alignment(data_frame, frame_after_bump, + # p2_name, p1_name) + + @staticmethod + def is_aerial_bump(data_frame: pd.DataFrame, p1_name: str, p2_name: str, at_frame: int): + p1_pos_z = data_frame[p1_name].pos_z.loc[at_frame] + p2_pos_z = data_frame[p2_name].pos_z.loc[at_frame] + if all(x > AERIAL_BUMP_HEIGHT for x in [p1_pos_z, p2_pos_z]): + # if all(abs(y) > 5080 for y in [p1_pos_y, p2_pos_y]): + # print("Backboard bump?") + return True + else: + return False + @staticmethod + def is_bump_alignment(bump_angles): + # Check if all bump alignment angles in the first half of the interval are above MAX_BUMP_ALIGN_ANGLE. + if all(x > MAX_BUMP_ALIGN_ANGLE for x in bump_angles): + return False + else: + return True - def analyze_bump(self, bump: Bump, data_frame:pd.DataFrame): - frame_number = bump.frame_number + @staticmethod + def is_bump_velocity(data_frame: pd.DataFrame, p1_name: str, p2_name: str, at_frame: int): + p1_vel_mag = np.sqrt(data_frame[p1_name].vel_x.loc[at_frame] ** 2 + + data_frame[p1_name].vel_y.loc[at_frame] ** 2 + + data_frame[p1_name].vel_z.loc[at_frame] ** 2) + p2_vel_mag = np.sqrt(data_frame[p2_name].vel_x.loc[at_frame] ** 2 + + data_frame[p2_name].vel_y.loc[at_frame] ** 2 + + data_frame[p2_name].vel_z.loc[at_frame] ** 2) + # Check if initial player velocities are below MIN_BUMP_VELOCITY. + if all(x < MIN_BUMP_VELOCITY for x in [p1_vel_mag, p2_vel_mag]): + return False + else: + return True From 3d989c31435ce4775f48af420c85e03ed1abb4cb Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Sun, 2 Aug 2020 11:52:49 +0100 Subject: [PATCH 02/14] Merge master into this + Small argument fix --- carball/analysis/events/event_creator.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/carball/analysis/events/event_creator.py b/carball/analysis/events/event_creator.py index adddde9c..3c27b6c4 100644 --- a/carball/analysis/events/event_creator.py +++ b/carball/analysis/events/event_creator.py @@ -92,7 +92,7 @@ def create_bumps(self, game: Game, proto_game: game_pb2.Game, player_map: Dict[s data_frame: pd.DataFrame): logger.info("Looking for bumps.") bumpAnalysis = BumpAnalysis(game=game, proto_game=proto_game) - bumpAnalysis.get_bumps_from_game(data_frame) + bumpAnalysis.get_bumps_from_game(data_frame, player_map) logger.info("Found %s bumps.", len(proto_game.game_stats.bumps)) def create_dropshot_events(self, game: Game, proto_game: game_pb2.Game, player_map: Dict[str, Player]): From 38d8ef933eda54afb055bf0b918029a7bfac619d Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Mon, 3 Aug 2020 12:31:45 +0100 Subject: [PATCH 03/14] Create API bumps. (+ some cleanup) --- .../events/bump_detection/bump_analysis.py | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/carball/analysis/events/bump_detection/bump_analysis.py b/carball/analysis/events/bump_detection/bump_analysis.py index 0a930772..805866e2 100644 --- a/carball/analysis/events/bump_detection/bump_analysis.py +++ b/carball/analysis/events/bump_detection/bump_analysis.py @@ -25,7 +25,7 @@ # (could be used to discard all aerial contact as bumps, although rarely an aerial bump WAS, indeed, intended) AERIAL_BUMP_HEIGHT = 300 -# TODO Analyse the impact of bumps. (e.g. look at proximity to the ball/net) + class BumpAnalysis: def __init__(self, game: Game, proto_game: game_pb2): self.proto_game = proto_game @@ -56,10 +56,12 @@ def create_bumps_from_player_contact(self, data_frame, player_map): # Account for car hitboxes and/or rotations when calculating close proximity intervals. # Do some post-bump analysis and see if car velocities aligned (i.e. analyse end of interval bump alignments) - # Get an array of player names to use for player combinations. + # An array of player names to get player combinations; and a dict of player names to their IDs to create bumps. player_names = [] + player_name_to_id = {} for player in player_map.values(): player_names.append(player.name) + player_name_to_id[player.name] = player.id # For each player pair combination, get possible contact distances. for player_pair in itertools.combinations(player_names, 2): @@ -69,13 +71,23 @@ def create_bumps_from_player_contact(self, data_frame, player_map): str(player_pair[1])) if len(players_close_frame_idxs) > 0: - BumpAnalysis.analyse_bumps(data_frame, player_pair, players_close_frame_idxs) + likely_bumps = BumpAnalysis.filter_bumps(data_frame, player_pair, players_close_frame_idxs) else: + likely_bumps = None logger.info("Players (" + player_pair[0] + " and " + player_pair[1] + ") did not get close " "during the match.") + for likely_bump in likely_bumps: + self.add_bump(likely_bump[0], player_name_to_id[likely_bump[2]], player_name_to_id[likely_bump[1]], + is_demo=False) + @staticmethod - def analyse_bumps(data_frame, player_pair, players_close_frame_idxs): + def filter_bumps(data_frame, player_pair, players_close_frame_idxs): + """ + Try to find 'real' bumps, and return them as a list of likely_bumps. + """ + likely_bumps = [] + # Get all individual intervals where a player pair got close to each other. players_close_frame_idxs_intervals = BumpAnalysis.get_players_close_intervals(players_close_frame_idxs) @@ -96,8 +108,15 @@ def analyse_bumps(data_frame, player_pair, players_close_frame_idxs): # Determine if the bump was above AERIAL_BUMP_HEIGHT. is_aerial_bump = BumpAnalysis.is_aerial_bump(data_frame, player_pair[0], player_pair[1], frame_before_bump) + if attacker is not None and victim is not None and not is_aerial_bump: + # SUGGESTION: Perhaps take frame in the middle of the interval? + high_probability_bump = (frame_before_bump, attacker, victim) + likely_bumps.append(high_probability_bump) + # Check if interval is quite long - players may be in rule 1 :) or might be a scramble. - BumpAnalysis.analyse_prolonged_proximity(data_frame, interval, player_pair[0], player_pair[1]) + # BumpAnalysis.analyse_prolonged_proximity(data_frame, interval, player_pair[0], player_pair[1]) + + return likely_bumps @staticmethod def get_player_bump_alignment(data_frame, frame_idx, p1_name, p2_name): From aa9bd9f3ab381a30a1a2212c2a65bc6a68a20b25 Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Mon, 3 Aug 2020 12:55:26 +0100 Subject: [PATCH 04/14] Not double-counting demo bumps now. --- .../events/bump_detection/bump_analysis.py | 32 ++++++++++++------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/carball/analysis/events/bump_detection/bump_analysis.py b/carball/analysis/events/bump_detection/bump_analysis.py index 805866e2..f07ea11d 100644 --- a/carball/analysis/events/bump_detection/bump_analysis.py +++ b/carball/analysis/events/bump_detection/bump_analysis.py @@ -11,8 +11,8 @@ logger = logging.getLogger(__name__) -# If you decrease this, you risk not counting bumps where one car is directly behind another (driving in the same direction). -# If you increase this, you risk counting non-contact close proximity (e.g. one car cleanly jumped over another =/= bump). +# Decreasing this, risks not counting bumps where one car is directly behind another (driving in the same direction). +# Increasing this, risks counting non-contact close proximity (e.g. one car cleanly jumped over another =/= bump). PLAYER_CONTACT_MAX_DISTANCE = 200 # Needs to be relatively high to account for two cars colliding 'diagonally': /\ @@ -26,6 +26,7 @@ AERIAL_BUMP_HEIGHT = 300 +# TODO Post-bump analysis // Bump impact analysis. class BumpAnalysis: def __init__(self, game: Game, proto_game: game_pb2): self.proto_game = proto_game @@ -38,14 +39,6 @@ def create_bumps_from_demos(self, proto_game): for demo in proto_game.game_metadata.demos: self.add_bump(demo.frame_number, demo.victim_id, demo.attacker_id, True) - def add_bump(self, frame: int, victim_id: PlayerId, attacker_id: PlayerId, is_demo: bool) -> Bump: - bump = self.proto_game.game_stats.bumps.add() - bump.frame_number = frame - bump.attacker_id.id = attacker_id.id - bump.victim_id.id = victim_id.id - if is_demo: - bump.is_demo = True - def create_bumps_from_player_contact(self, data_frame, player_map): # NOTES: # Currently, this yields more 'bumps' than there are actually. @@ -77,7 +70,24 @@ def create_bumps_from_player_contact(self, data_frame, player_map): logger.info("Players (" + player_pair[0] + " and " + player_pair[1] + ") did not get close " "during the match.") - for likely_bump in likely_bumps: + self.add_non_demo_bumps(likely_bumps, player_name_to_id) + + def add_bump(self, frame: int, victim_id: PlayerId, attacker_id: PlayerId, is_demo: bool) -> Bump: + bump = self.proto_game.game_stats.bumps.add() + bump.frame_number = frame + bump.attacker_id.id = attacker_id.id + bump.victim_id.id = victim_id.id + if is_demo: + bump.is_demo = True + + def add_non_demo_bumps(self, likely_bumps, player_name_to_id): + demo_frame_idxs = [] + for demo in self.proto_game.game_metadata.demos: + demo_frame_idxs.append(demo.frame_number) + + for likely_bump in likely_bumps: + likely_bump_frame_idx = likely_bump[0] + if not any(np.isclose(demo_frame_idxs, likely_bump_frame_idx, atol=10)): self.add_bump(likely_bump[0], player_name_to_id[likely_bump[2]], player_name_to_id[likely_bump[1]], is_demo=False) From 6922200a018bb4e2868ce3e0a0dbe3a1e51e73e5 Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Mon, 3 Aug 2020 14:34:23 +0100 Subject: [PATCH 05/14] Clean-up. --- .../events/bump_detection/bump_analysis.py | 114 ++++++++++++------ 1 file changed, 78 insertions(+), 36 deletions(-) diff --git a/carball/analysis/events/bump_detection/bump_analysis.py b/carball/analysis/events/bump_detection/bump_analysis.py index f07ea11d..dee424b8 100644 --- a/carball/analysis/events/bump_detection/bump_analysis.py +++ b/carball/analysis/events/bump_detection/bump_analysis.py @@ -1,7 +1,11 @@ import itertools import logging +from typing import Dict + import numpy as np import pandas as pd +from carball.generated.api.player_pb2 import Player + from carball.generated.api.stats.events_pb2 import Bump from carball.generated.api.player_id_pb2 import PlayerId @@ -13,7 +17,7 @@ # Decreasing this, risks not counting bumps where one car is directly behind another (driving in the same direction). # Increasing this, risks counting non-contact close proximity (e.g. one car cleanly jumped over another =/= bump). -PLAYER_CONTACT_MAX_DISTANCE = 200 +PLAYER_CONTACT_DISTANCE = 200 # Needs to be relatively high to account for two cars colliding 'diagonally': /\ MAX_BUMP_ALIGN_ANGLE = 60 @@ -33,21 +37,23 @@ def __init__(self, game: Game, proto_game: game_pb2): def get_bumps_from_game(self, data_frame: pd.DataFrame, player_map): self.create_bumps_from_demos(self.proto_game) - self.create_bumps_from_player_contact(data_frame, player_map) + self.create_bumps_from_player_proximity(data_frame, player_map) def create_bumps_from_demos(self, proto_game): for demo in proto_game.game_metadata.demos: self.add_bump(demo.frame_number, demo.victim_id, demo.attacker_id, True) - def create_bumps_from_player_contact(self, data_frame, player_map): - # NOTES: - # Currently, this yields more 'bumps' than there are actually. - # This is mostly due to aerial proximity, where a bump was NOT intended or no contact was made. - # This also occurs near the ground, where cars flip awkwardly past each other. - - # POSSIBLE SOLUTIONS: - # Account for car hitboxes and/or rotations when calculating close proximity intervals. - # Do some post-bump analysis and see if car velocities aligned (i.e. analyse end of interval bump alignments) + def create_bumps_from_player_proximity(self, data_frame: pd.DataFrame, player_map: Dict[str, Player]): + """ + Attempt to find all instances between each possible player combination + where they got within PLAYER_CONTACT_DISTANCE. + Then, add each instance to the API. + + NOTES: + Currently, this yields more 'bumps' than there are actually. + This is mostly due to aerial proximity, where a bump was NOT intended or no contact was made. + This also occurs near the ground, where cars flip awkwardly past each other. + """ # An array of player names to get player combinations; and a dict of player names to their IDs to create bumps. player_names = [] @@ -56,23 +62,23 @@ def create_bumps_from_player_contact(self, data_frame, player_map): player_names.append(player.name) player_name_to_id[player.name] = player.id - # For each player pair combination, get possible contact distances. + # For each player pair combination (nCr), get all frames where they got close and then filter those as bumps. for player_pair in itertools.combinations(player_names, 2): - # Get all frame idxs where players were within PLAYER_CONTACT_MAX_DISTANCE. players_close_frame_idxs = BumpAnalysis.get_players_close_frame_idxs(data_frame, str(player_pair[0]), str(player_pair[1])) if len(players_close_frame_idxs) > 0: likely_bumps = BumpAnalysis.filter_bumps(data_frame, player_pair, players_close_frame_idxs) + self.add_non_demo_bumps(likely_bumps, player_name_to_id) else: - likely_bumps = None logger.info("Players (" + player_pair[0] + " and " + player_pair[1] + ") did not get close " "during the match.") - self.add_non_demo_bumps(likely_bumps, player_name_to_id) - def add_bump(self, frame: int, victim_id: PlayerId, attacker_id: PlayerId, is_demo: bool) -> Bump: + """ + Add a new bump to the proto_game object. + """ bump = self.proto_game.game_stats.bumps.add() bump.frame_number = frame bump.attacker_id.id = attacker_id.id @@ -81,10 +87,19 @@ def add_bump(self, frame: int, victim_id: PlayerId, attacker_id: PlayerId, is_de bump.is_demo = True def add_non_demo_bumps(self, likely_bumps, player_name_to_id): + """ + Add a new bump to the proto_game object. + This method takes an array of likely (filtered) bumps, in the following form: + (frame_idx, attacker_name, victim_name) + and carefully adds them to the proto_game object (i.e. check for demo duplicates). + """ + + # Get an array of demo frame idxs to compare later. demo_frame_idxs = [] for demo in self.proto_game.game_metadata.demos: demo_frame_idxs.append(demo.frame_number) + # For each bump tuple, if its frame index is not similar to a demo frame index, add it via add_bump(). for likely_bump in likely_bumps: likely_bump_frame_idx = likely_bump[0] if not any(np.isclose(demo_frame_idxs, likely_bump_frame_idx, atol=10)): @@ -94,42 +109,58 @@ def add_non_demo_bumps(self, likely_bumps, player_name_to_id): @staticmethod def filter_bumps(data_frame, player_pair, players_close_frame_idxs): """ - Try to find 'real' bumps, and return them as a list of likely_bumps. + Filter the frames where two players got close - the filtered frames are likely bumps. + + The main principle used is the angle between two vectors (aka 'alignment'): + the velocity vector of player A; + the positional vector of the difference between the positions of player B and player A. + Both of these vectors point away from player A, and if the angle between them is small - it is likely that + Player A bumped Player B. (Velocity going 'through' Player B's Position) + + Some further checks are done to categorise the bump (i.e. is_aerial_bump(), is_bump_velocity() ) """ likely_bumps = [] - # Get all individual intervals where a player pair got close to each other. + # Split a list of frame indexes into intervals where indexes are within 3 of each other (i.e. consecutive). players_close_frame_idxs_intervals = BumpAnalysis.get_players_close_intervals(players_close_frame_idxs) - # For each such interval, take (currently only) the beginning and analyse car behaviour. + # For each such interval, take (currently only) the first frame index and analyse car behaviour. for interval in players_close_frame_idxs_intervals: frame_before_bump = interval[0] - # Calculate alignments (angle between position vector and velocity vector, with regard to each player) + # Calculate both player bump alignments (see comment at method top). p1_alignment_before = BumpAnalysis.get_player_bump_alignment(data_frame, frame_before_bump, player_pair[0], player_pair[1]) p2_alignment_before = BumpAnalysis.get_player_bump_alignment(data_frame, frame_before_bump, player_pair[1], player_pair[0]) - # TODO Create Bump objects and add them to the API. - # Determine the attacker and the victim (if alignment is below MAX_BUMP_ALIGN_ANGLE, it's the attacker) + + # Determine the attacker and the victim (see method for more info). attacker, victim = BumpAnalysis.determine_attacker_victim(player_pair[0], player_pair[1], p1_alignment_before, p2_alignment_before) # Determine if the bump was above AERIAL_BUMP_HEIGHT. is_aerial_bump = BumpAnalysis.is_aerial_bump(data_frame, player_pair[0], player_pair[1], frame_before_bump) + # Append the current bump data to likely bumps, if there is an attacker and a victim + # and if it wasn't an aerial bump (most often it isn't intended, and there is often awkward behaviour). if attacker is not None and victim is not None and not is_aerial_bump: - # SUGGESTION: Perhaps take frame in the middle of the interval? - high_probability_bump = (frame_before_bump, attacker, victim) - likely_bumps.append(high_probability_bump) + likely_bump = (frame_before_bump, attacker, victim) + likely_bumps.append(likely_bump) - # Check if interval is quite long - players may be in rule 1 :) or might be a scramble. + # NOT YET IMPLEMENTED: Check if interval is quite long - players may be in rule 1 :) or might be a scramble. # BumpAnalysis.analyse_prolonged_proximity(data_frame, interval, player_pair[0], player_pair[1]) return likely_bumps @staticmethod def get_player_bump_alignment(data_frame, frame_idx, p1_name, p2_name): + """ + Calculate and return the angle between: + the velocity vector of player A; + the positional vector of the difference between the positions of player B and player A. + """ + + # Get the necessary data from the DataFrame at the given frame index. p1_vel_df = data_frame[p1_name][['vel_x', 'vel_y', 'vel_z']].loc[frame_idx] p1_pos_df = data_frame[p1_name][['pos_x', 'pos_y', 'pos_z']].loc[frame_idx] p2_pos_df = data_frame[p2_name][['pos_x', 'pos_y', 'pos_z']].loc[frame_idx] @@ -145,31 +176,41 @@ def get_player_bump_alignment(data_frame, frame_idx, p1_name, p2_name): vel1 = [p1_vel_df.vel_x, p1_vel_df.vel_y, p1_vel_df.vel_z] unit_vel1 = vel1 / np.linalg.norm(vel1) - # Find the angle between the position vector and the velocity vector. - # If this is relatively aligned - p1 probably significantly bumped p2. + # Find the angle between the positional vector and the velocity vector. + # NOTE: This is currently converted to DEGREES, not sure if this is bad..? ( - DivvyC) ang = (np.arccos(np.clip(np.dot(unit_vel1, unit_pos1), -1.0, 1.0))) * 180 / np.pi - # print(p1_name + "'s bump angle=" + str(ang)) return ang @staticmethod def get_players_close_frame_idxs(data_frame, p1_name, p2_name): + """ + For a pair of players, find all frame indexes where they got within PLAYER_CONTACT_DISTANCE of each other. + Note that they did NOT necessarily make contact. + """ + + # Separate the positional data of each given player from the full DataFrame and lose the NaN value rows. p1_pos_df = data_frame[p1_name][['pos_x', 'pos_y', 'pos_z']].dropna(axis=0) p2_pos_df = data_frame[p2_name][['pos_x', 'pos_y', 'pos_z']].dropna(axis=0) - # Calculate the vector distances between the players. + # Calculate the vector distances between the players, and store them as a pd.Series (1D DataFrame). distances = (p1_pos_df.pos_x - p2_pos_df.pos_x) ** 2 + \ (p1_pos_df.pos_y - p2_pos_df.pos_y) ** 2 + \ (p1_pos_df.pos_z - p2_pos_df.pos_z) ** 2 distances = np.sqrt(distances) - # Only keep values < PLAYER_CONTACT_MAX_DISTANCE (see top of class). - players_close_series = distances[distances < PLAYER_CONTACT_MAX_DISTANCE] - # Get the frame indexes of the values (as ndarray). + + # Only keep values < PLAYER_CONTACT_DISTANCE (see top of class). + players_close_series = distances[distances < PLAYER_CONTACT_DISTANCE] + # Get the frame indexes of the values (as an ndarray). players_close_frame_idxs = players_close_series.index.to_numpy() return players_close_frame_idxs @staticmethod def get_players_close_intervals(players_close_frame_idxs): - # Find continuous intervals of close proximity, and group them together. + """ + Separate a list of frame indexes into intervals with consecutive frame indexes. + E.g. [3, 4, 5, 7, 19, 21, 23, 24, 57] is turned into [[3, 4, 5, 7], [21, 23, 24], [57]] + """ + all_intervals = [] interval = [] for index, frame_idx in enumerate(players_close_frame_idxs): @@ -184,9 +225,10 @@ def get_players_close_intervals(players_close_frame_idxs): def determine_attacker_victim(p1_name, p2_name, p1_alignment, p2_alignment): """ Try to 'guesstimate' the attacker and the victim by comparing bump alignment angles. - If both alignments are within 45deg, then both players were going relatively towards each other. + If both bump alignments are above MAX_BUMP_ALIGN_ANGLE, both values are None (no solid attacker/victim) + If both bump alignments are within 45deg of each other, both values are None (both attackers) - :return: (Attacker, Victim) + :return: A tuple in the form (Attacker, Victim) or (None, None). """ if p1_alignment < MAX_BUMP_ALIGN_ANGLE or p2_alignment < MAX_BUMP_ALIGN_ANGLE: From d847e758083e1d6c82986cbe53e7a28395008669 Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Tue, 4 Aug 2020 17:45:30 +0100 Subject: [PATCH 06/14] Implement testing. NOTE: Have to change demo test, because game_stats.bumps is now more populated. --- carball/tests/stats/bump_test.py | 16 ++++++++++++++++ carball/tests/stats/demo_test.py | 7 +++++-- 2 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 carball/tests/stats/bump_test.py diff --git a/carball/tests/stats/bump_test.py b/carball/tests/stats/bump_test.py new file mode 100644 index 00000000..40ba394a --- /dev/null +++ b/carball/tests/stats/bump_test.py @@ -0,0 +1,16 @@ +from carball.tests.utils import get_raw_replays, run_analysis_test_on_replay + +from carball.analysis.analysis_manager import AnalysisManager + + +class Test_Bumps: + def test_calculate_bumps_correctly(self, replay_cache): + def test(analysis: AnalysisManager): + proto_game = analysis.get_protobuf_data() + count_bumps = 0 + for i in proto_game.game_stats.bumps: + if not i.is_demo: + count_bumps += 1 + assert count_bumps == 3 + + run_analysis_test_on_replay(test, get_raw_replays()["3_BUMPS"], cache=replay_cache) diff --git a/carball/tests/stats/demo_test.py b/carball/tests/stats/demo_test.py index 1b013362..66f51f9a 100644 --- a/carball/tests/stats/demo_test.py +++ b/carball/tests/stats/demo_test.py @@ -7,7 +7,10 @@ class Test_Demos: def test_calculate_demos_correctly(self, replay_cache): def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() - bumps = proto_game.game_stats.bumps - assert len(bumps) == 1 + count_demo_bumps = 0 + for i in proto_game.game_stats.bumps: + if i.is_demo: + count_demo_bumps += 1 + assert count_demo_bumps == 1 run_analysis_test_on_replay(test, get_raw_replays()["1_DEMO"], cache=replay_cache) From e4590f03809aabc505617da8b710669ec79bb55b Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Tue, 4 Aug 2020 18:09:33 +0100 Subject: [PATCH 07/14] Replay key fix. --- carball/tests/utils.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/carball/tests/utils.py b/carball/tests/utils.py index 923367c2..b769557d 100644 --- a/carball/tests/utils.py +++ b/carball/tests/utils.py @@ -99,12 +99,16 @@ def get_raw_replays(): "0_JUMPS": ["0_JUMPS.replay"], "0_SAVES": ["0_SAVES.replay"], "1_AERIAL": ["1_AERIAL.replay"], - "1_DEMO": ["1_DEMO.replay", "1_DEMO_1_63.replay"], "1_DOUBLE_JUMP": ["1_DOUBLE_JUMP.replay"], "1_EPIC_SAVE": ["1_EPIC_SAVE.replay"], "1_JUMP": ["1_JUMP.replay"], "1_NORMAL_SAVE_FROM_SHOT_TOWARD_POST": ["1_NORMAL_SAVE.replay"], + # Bumps and Demos + "1_DEMO": ["1_DEMO.replay", "1_DEMO_1_63.replay"], + "3_BUMPS": ["3_BUMPS.replay"], + "4_BUMPS": ["4_BUMPS.replay"], + # Boost "3_STEAL_ORANGE_0_STEAL_BLUE": ["3_STEALS.replay"], "12_BOOST_PAD_0_USED": ["12_BOOST_PAD_0_USED.replay"], From c5374191057427f64c1131ecb02d1c589268d05f Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Thu, 6 Aug 2020 16:11:16 +0100 Subject: [PATCH 08/14] Head-on bumps are now treated as bumps. --- .../events/bump_detection/bump_analysis.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/carball/analysis/events/bump_detection/bump_analysis.py b/carball/analysis/events/bump_detection/bump_analysis.py index dee424b8..cc958432 100644 --- a/carball/analysis/events/bump_detection/bump_analysis.py +++ b/carball/analysis/events/bump_detection/bump_analysis.py @@ -135,15 +135,15 @@ def filter_bumps(data_frame, player_pair, players_close_frame_idxs): player_pair[1], player_pair[0]) # Determine the attacker and the victim (see method for more info). - attacker, victim = BumpAnalysis.determine_attacker_victim(player_pair[0], player_pair[1], - p1_alignment_before, p2_alignment_before) + attacker, victim, is_bump = BumpAnalysis.determine_attacker_victim(player_pair[0], player_pair[1], + p1_alignment_before, p2_alignment_before) # Determine if the bump was above AERIAL_BUMP_HEIGHT. is_aerial_bump = BumpAnalysis.is_aerial_bump(data_frame, player_pair[0], player_pair[1], frame_before_bump) # Append the current bump data to likely bumps, if there is an attacker and a victim # and if it wasn't an aerial bump (most often it isn't intended, and there is often awkward behaviour). - if attacker is not None and victim is not None and not is_aerial_bump: + if is_bump and not is_aerial_bump: likely_bump = (frame_before_bump, attacker, victim) likely_bumps.append(likely_bump) @@ -228,18 +228,19 @@ def determine_attacker_victim(p1_name, p2_name, p1_alignment, p2_alignment): If both bump alignments are above MAX_BUMP_ALIGN_ANGLE, both values are None (no solid attacker/victim) If both bump alignments are within 45deg of each other, both values are None (both attackers) - :return: A tuple in the form (Attacker, Victim) or (None, None). + :return: A tuple in the form (Attacker, Victim, T) or (None, None, T/F), where the last bool signifies whether + the bump is considered legitimate (T) or not (F). """ - if p1_alignment < MAX_BUMP_ALIGN_ANGLE or p2_alignment < MAX_BUMP_ALIGN_ANGLE: + if abs(p1_alignment) < MAX_BUMP_ALIGN_ANGLE or abs(p2_alignment) < MAX_BUMP_ALIGN_ANGLE: if abs(p1_alignment - p2_alignment) < 45: - return None, None + return None, None, True elif p1_alignment < p2_alignment: - return p1_name, p2_name + return p1_name, p2_name, True elif p2_alignment < p1_alignment: - return p2_name, p1_name + return p2_name, p1_name, True - return None, None + return None, None, False @staticmethod def analyse_prolonged_proximity(data_frame, interval, p1_name, p2_name): From cf987f5d87e33ee37c5d89656220d03ffd82cc8b Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Thu, 6 Aug 2020 16:50:18 +0100 Subject: [PATCH 09/14] Ignore ambiguous bumps for now.. --- .../events/bump_detection/bump_analysis.py | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/carball/analysis/events/bump_detection/bump_analysis.py b/carball/analysis/events/bump_detection/bump_analysis.py index cc958432..f1c81699 100644 --- a/carball/analysis/events/bump_detection/bump_analysis.py +++ b/carball/analysis/events/bump_detection/bump_analysis.py @@ -134,8 +134,9 @@ def filter_bumps(data_frame, player_pair, players_close_frame_idxs): p2_alignment_before = BumpAnalysis.get_player_bump_alignment(data_frame, frame_before_bump, player_pair[1], player_pair[0]) - # Determine the attacker and the victim (see method for more info). - attacker, victim, is_bump = BumpAnalysis.determine_attacker_victim(player_pair[0], player_pair[1], + # Determine the attacker and the victim (see method for more info). is_ambiguous signifies whether + # the attacker-victim pair is clear or not. + attacker, victim, is_ambiguous = BumpAnalysis.determine_attacker_victim(player_pair[0], player_pair[1], p1_alignment_before, p2_alignment_before) # Determine if the bump was above AERIAL_BUMP_HEIGHT. @@ -143,7 +144,7 @@ def filter_bumps(data_frame, player_pair, players_close_frame_idxs): # Append the current bump data to likely bumps, if there is an attacker and a victim # and if it wasn't an aerial bump (most often it isn't intended, and there is often awkward behaviour). - if is_bump and not is_aerial_bump: + if attacker is not None and victim is not None and not is_aerial_bump: likely_bump = (frame_before_bump, attacker, victim) likely_bumps.append(likely_bump) @@ -229,18 +230,20 @@ def determine_attacker_victim(p1_name, p2_name, p1_alignment, p2_alignment): If both bump alignments are within 45deg of each other, both values are None (both attackers) :return: A tuple in the form (Attacker, Victim, T) or (None, None, T/F), where the last bool signifies whether - the bump is considered legitimate (T) or not (F). + the attacker/victim are ambiguous (T) or not (F). """ if abs(p1_alignment) < MAX_BUMP_ALIGN_ANGLE or abs(p2_alignment) < MAX_BUMP_ALIGN_ANGLE: - if abs(p1_alignment - p2_alignment) < 45: - return None, None, True - elif p1_alignment < p2_alignment: - return p1_name, p2_name, True + # if abs(p1_alignment - p2_alignment) < 45: + # # TODO Rework? This would indicate that the bump is ambiguous (no definite attacker/victim). + # return p1_name, p2_name, True + if p1_alignment < p2_alignment: + return p1_name, p2_name, False elif p2_alignment < p1_alignment: - return p2_name, p1_name, True + return p2_name, p1_name, False - return None, None, False + # This is ambiguous - neither player had an attacking bump angle. + return None, None, True @staticmethod def analyse_prolonged_proximity(data_frame, interval, p1_name, p2_name): From eadf10e9568f4dc9a781711a0b7ab6ea7f7eb3b6 Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Thu, 6 Aug 2020 17:10:04 +0100 Subject: [PATCH 10/14] Try another test replay (4_BUMPS instead of 3_BUMPS) --- carball/tests/stats/bump_test.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/carball/tests/stats/bump_test.py b/carball/tests/stats/bump_test.py index 40ba394a..5c51974e 100644 --- a/carball/tests/stats/bump_test.py +++ b/carball/tests/stats/bump_test.py @@ -11,6 +11,6 @@ def test(analysis: AnalysisManager): for i in proto_game.game_stats.bumps: if not i.is_demo: count_bumps += 1 - assert count_bumps == 3 + assert count_bumps == 4 - run_analysis_test_on_replay(test, get_raw_replays()["3_BUMPS"], cache=replay_cache) + run_analysis_test_on_replay(test, get_raw_replays()["4_BUMPS"], cache=replay_cache) From 614633b4915634f5ac27756ce65eb2d2c61126d6 Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Thu, 6 Aug 2020 17:36:52 +0100 Subject: [PATCH 11/14] Record + add new replay (7_BUMPS) and test that. --- carball/tests/stats/bump_test.py | 4 ++-- carball/tests/utils.py | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/carball/tests/stats/bump_test.py b/carball/tests/stats/bump_test.py index 5c51974e..40982aa8 100644 --- a/carball/tests/stats/bump_test.py +++ b/carball/tests/stats/bump_test.py @@ -11,6 +11,6 @@ def test(analysis: AnalysisManager): for i in proto_game.game_stats.bumps: if not i.is_demo: count_bumps += 1 - assert count_bumps == 4 + assert count_bumps == 7 - run_analysis_test_on_replay(test, get_raw_replays()["4_BUMPS"], cache=replay_cache) + run_analysis_test_on_replay(test, get_raw_replays()["7_BUMPS"], cache=replay_cache) diff --git a/carball/tests/utils.py b/carball/tests/utils.py index b769557d..ba916286 100644 --- a/carball/tests/utils.py +++ b/carball/tests/utils.py @@ -108,6 +108,7 @@ def get_raw_replays(): "1_DEMO": ["1_DEMO.replay", "1_DEMO_1_63.replay"], "3_BUMPS": ["3_BUMPS.replay"], "4_BUMPS": ["4_BUMPS.replay"], + "7_BUMPS": ["7_BUMPS.replay"], # Boost "3_STEAL_ORANGE_0_STEAL_BLUE": ["3_STEALS.replay"], From 719b9e85ccad13335803359a29d6b394dd6abb58 Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Thu, 6 Aug 2020 17:36:52 +0100 Subject: [PATCH 12/14] Record + add new replay (7_BUMPS) and test that. --- carball/tests/replays/7_BUMPS.replay | Bin 0 -> 142251 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 carball/tests/replays/7_BUMPS.replay diff --git a/carball/tests/replays/7_BUMPS.replay b/carball/tests/replays/7_BUMPS.replay new file mode 100644 index 0000000000000000000000000000000000000000..f4934ea915cca347d745764dd34c75811529afc0 GIT binary patch literal 142251 zcmce;2{=^m`#=7inK5?8zGN9oA(b^-V#uB%TC^G}sf1)tW=N${NtCo0t=iBkZHBa| zn50q>m9ivM_GRXOpBbgk@AG+ozTfNmUf2Iz*Wt{WGxu{p_x-w;=YF2&%ojx{ZCG4k z6%iqIgpe4V%5ctia1Ge7dYaGb@Q{Ewf8Vf`D+40@=Q|*H9L--Hu)%k2{AwftAKXJD zy(7ZHS4Tv~ArgGX4-8IeI2VKl1+0zuUp+1kkK+%T_^u3#`0td-@ThB8K*%N}1y>Fc z5dm?3IM@ew@B`-ne=aBjdhw5ZvVdW{VQ=W;>WI0&AN7rl_(Kqv2Yv_|4coN(uOHz2 z{v&Oi10gu)hJ^}#5jSTpYUDyf;!VdzR{Ga_NasJJi z)7t3hIO?ove8zxwWKdYd282K17#BI-7Zsc+95|r7LPOSuuKx3^!oS_}_l?Arg7;hS zth*B*CG!@AMXdTG9$a?#;o!MT3PThOXZOD<6Mq;-z<&oP-t%#A{*!Uwv~UI-Hf>tF z2_*U7p5wO}5WV_;@lR#e^uXatNQQiO96WSv-)sa|9`9Rw=enc z>f^)skGm0g?*Hi1aKzyU-VFNNp@;HCcA zF!5N3TZ_+X2xzNZ#zgEA5*G09@e-kK2i*V8ULD5|SWc@UAn{f5PtQ{waG}fzh{gLJ zx*B5PKM9E^j1WcetUzOU;K)2G<&X0B^`UAY#40H{Xbz0wM*$`tMf% zRV${(Q;n^r8e33JET@_oPn~YU7xLVw4K8@3|7S4_fWM_?+wGifqSh;V&ESUB0L>{zL$rtZ8hV&nxhm`3~W3nhO0krm;h9*|=7w z0Sn5A6t2zYB{{Kik$8{Yabt^G;lJ{LdqgIZ67|Cj;gSwLq$3Jj3o~lMDI38v5{O`> zOD8|Wzn%m?!Dwg)sh)|q)(TyTWaFSu0J;R$2QT2U9X@ui3VL|(>q2skyo=>_GUccf z+%rZGaG#J!1DX%uf@v`uo}K|$G%OPjE#c@3-c?5s$U;JLw!At4Q3+_f z2()z`PV^c#iC+Bcn7zn>&njZ_FK{~0!e7_?8)J9yjw46-%L_m}_yS7-YTWyXOOya& zbhzWGu*D&(tSsxv_0uIU9PTz`J;}TK>UkFY1V6$_B7j0VT=6gX*ydm168`HR{s}+$ z-|6EQ6!_hMG;siwBSHla)vZbH)}-TK0mt<7t>Wh;qzXI>ras>z)&9M}Q|kMr(1I~U zvuuTpNQmhQ=Wbw^-xSEN5^rGqplOj1TOQ7MTtI?@Z3x8s;q(8M0Gj~>nL_$P%dpSC z)Dd&32>(PPAc4^Q!-wBOx8&jf;90-{Vqx*2h>E;-*n+enp&YsI)H2H3dsVwbX{MPNo zP3%RsZciG`3si?uK4f8|ye^(SUv0=;k`>A;yP8bAt%|V8KQ2em z=6+C|slz!yLNt^TGlzD8cY$k!n6G)gyguc@FjOfmvCf8d(<$Y+aIknVDV`7MZgmm; z0}M~DJL0@5{nfZ{wZAdCmM~KH9uw8m{=?FWW;ExEQC6uk@*5=b7Rn1np*u4wjejzg zhn!q|f9M`EN#GYp++-k?0O*&bn;T^8+xNmWR9jntRMdMu}gSK&} z$V@^WmUIh#J%76};kv$dk6V@!No=lD>&F>15#6JyoLM<1C~l52d5_|DYEcrk9i_J% znMJ)IU|xhItIf&QcC02|8$GLQD3k9jleZ%yN89_RuH(LfyUwha&`?-f8f^wNBr;<{ z(h_-@_~2VM{Dy)@w~%C^AxuJ2v?4o|V}?%ShPDC+e8+xQ!mDV#p74u@_{?anqlwlY zOXb|}J0aU@2h5o6nus&Auj}Y+D)dGm$#*$sMJb{r-JKjW!iJcVrb<$vC$6g-`}41@ zB}DP%xYR6R#3Jb?bl8P8RoZvoQJUN?5zv+e!HhE(=l8fwusChSMZNU3&{x-wUMxlD z6pgl*EL!d*k(s2*SxF0(W#X6B?dJD^ZcPu3fv2~u9{2>t58F}ZJgY;Ecx;k(PhEf`8CUPdS6LF7pFq8Y4LW|Ce97%_4^(1{xKoK6$5b*|>o6Z0 zF02i@=klJ@%ArR(oajUTi`TFgJL4)@zqhB`i~}mE7P&UM}b=()Ju!%2a?u-`NRKS^T4ksxEIAFz|=5tUN z=PQh36cf5B)r=FElA(_GO!#E*jCARVj?$dPF?;}Cujr!50)dMcJ|?MBW#Y*!e3-%( zhd(tQP# z)vlJ>U^<;$<)5bCCEOG?CbXwbWr5p~Mby5svufaWwsaPgn2LEX6Pi8}2R0w6yPo2` zLjxB}3l^Vo8f8C&@NE^$h$n=;?($Ds@=%$nPfyJbE2Gy$ z)1%VCF^s0A>;k<*vwLavpaf~o0SOZOCPRNZ+jaPtT)GA0(1YFQtI#S$A>FAL5DAdt z6ETXkmqF3k&^BqmaCS_;{DNtlsULA~(dr(7n$FNNRawVIKZ<6*Ej4>Mn6VOBpmgkU zy#-+=IMEdIflT83$WqRz6{2J5^9Rurp?3|765n?w>4F#2VCj|gGu+AZ)-mn+&Q5At zJ2LI8q5}h~Lo{A)(g%?qT~XA1y~$UK^J3Jc|2|~DY^RSzHIepd(;5;7XcPAFJMyfj zbjCLQ>9paY+pkVMt6ip%SyX)!3S-jLcDy{x3{Tq-L7& zk9~uDvjt&zezV`Z18BS)l9Mg+8)~_~U1(51cv{ z4bc(-Q$Qo~qrLVnpmBC+hK%v&f#SChMQ;)4hUhRu^y_c!y0JmKr-!pTcVILkx=z+) zCs8|G?rYta#*GgU;=XBgQ+28ju{OU{9BWMCO$_lWG(-_tHh1(ngk5*Utm7V!VCHnj z+|neYPTr0Uzc4GQl;s;%Y#&S#1TejGhZxdSkSV!WNsAiMC2jpZFGh$h#N<^&^uXn@ zy?b*d7JsV|?@KJNaapBs6O9u6K;}fJ@F(yram?eZ21obgIGw{(YyDH0Q}5X4n`wSg zK)pPvbd~@dEk9;{K{Fe=BJCy6QJ(ag&%|)5$n9^-vWAI!z^H9$UOy|i9!pQuBFT0m zNA{(LT!+JDy<*I^QqtUa0>$Qk0L8u>^#;YV`*{h>NkgtncGIvJv)?En1ab>qL^F=|vZl@JpVc5uWIp1(dHj`#OMTOlWV@d^(~OP@Wb)+3 zxJ=&gW)1(qyh$gNg0}z>3T?+Zns>uAzHCiuya-b~B)#*vlS#EN)yZ#M$~OuzKQ{PZl}k6QZ~>P#uN zfW*lM<0OoDU9ZZ8X(p)yTnfn@vMeBx(L5|W1SGQBq-pG9l>r6;-*kZlWUb86DglY? zyW=D@d4;qxVVXm#u9h5W45u}|!`YH2Yf*3OK3iI0X`aTi<2VT-vzI}9BOsxBeVhb^ zTiTpxhvZXIE$2IU59>O5Nz{XKXa`)=$c>zesRAw;Q1-dt}rP_!ln-j3t zW0eeaPl!3d`1L{1y^V**yT=(VE!$v+B(&$vw-kwh;Q%;;X6x>_BA0WR$Mf8U%$X{) zhEuPJRw0fM>gUOp3f#dD4R8m}4boBI4(P*-cbo*I?Brt-L&5VgJn-4p6Hn~{x0Y>x z1nn8#HfspIK7xUh9^$nn3Y=1oe0(Lg>y~CaI3-#iPj$~AqMT~#)FhRq3RKk$VX zdGN(Zn-&_CXE)>I&xNQ?kKN^;lfWMWkWlN{mOrpXZ+TCfzYuBZrcS98-8=ys=;deK zy*@~{c{{;ZM>=UpBU9U&uoDRo@(Jb4QmX@bUlaV zJZ*Gln(!Q7u4BtSM4UDr1ziY*!5btII!WUlp$;+5@54L7U9Omn=icBJ-`dA`cS1)L ze;tyehCB%Wc%)>H35x8u7iLE(3EZo+>Nq%4xw*|+nuwtA;Qcm!HVz5IuJh{RiI70l zjzkIN*O^8J?dVu7fo5{MFpA3qew3hmuke-fuH{DwbetzV@<^CTJ55N{!iQ6ME>sh+ z#*liNtZ&Uo!X7F~4vv&)suF31yrpQ>3==^T^0Iqe6fL|5O+P>sCeA@39@_B`bXB*iKCs)N->DXvDxqsZkd+ zGM6Dmn6^Vor*!D`9Rgc{IS_VSKw(JZUnqRY#VL@s@U-;DD0G>>xifK$g4jMOhst$| zcL_9g_TYLcK`)NhkN3ig+sKdwr+46)j3cQ;5Eg34UprqyFD|tiIk4qk=eev1y|@z9 z$K)BF{al0V7vAuc*CV*fQ@!>cbwuj%4QcdzZu zWjlBwSOZcNxR>6%4zaI2qTLyH%NN-fSen!!Q+{s z1g3zEi<{cV+4#tNa*)pklc}HlP+)1+h7m$9fsLj8dWQ70uA=!4a(p&uMA}y&fizrm z|7JteQv_#YmC9l5$CCvBU8eI!d)jI8%|u2O!EvjUoOzESUmE6Um4k>G-)BffwvF@A z#9Ocl_y~5ocw%xgKJo;MKj#sl{{#5gJ#cm!eMyt?$OE-TGrm^Xjs$@?^!APOA;N9c zBWt2vF1oh2wSzs!T-T&EBSs*O301eOT+?Y*_p7*_iua zN^L{YL8@dkm(tXOC`H3D;Pud^$MvqY4@lqLW!G%ljJnNDn`DY#ix{JlE%J zVde=LljFBV@KOZC6WzDZ9vt^PhlPG`S(*T}CM*NdQGVk|blRnV8{ssGX!D{<(H zm3DoKvcn>Q!QCO+MCU?Zgt)s^!&%F37H`O?p`aX{z#U+0iin;w?W|gpA8Cb5Du$ed zyj_^m=ml-GqtPPbb-K*&BtiSs0nZ#C;+@9Qvsi!gwmCl^ewDze(oEE}CJbDM7|PD7 zG!V8@Oj<&!!6>sK^5;sUz$60qj*!zmQ=Q*vzu~Pkb2^ODZ!_G9$GPIgLN~T9Ca^#7 zzVqBVAk3>^%xT$2BbY0p;zu<=G834WhX+xUjKs|xJLx^YozTKH$LMcBCQrG85|7sz z&#xNr`z(PL^hFl#D#nwA!x*!5`xq6L5!$H3JTfqdSTf|qt>Nco@T!#=aWmxpeo*|5 zg>l{2x~QBv=dk17a-TEjqWf7{OO>lo(IG~)J$Da?C<9Rg)%hY?CsQXu%M_yqZ?Qvu zsSdYgTeHlG{6aAyJK?R!Pbm3-+E2y3pMDqUNp)yeF~4?~#~sr_K(CSU!`?6n=#`@; zqRJS(U`blDIIA$h4!J$N)T!lc=_vHkD9}r5?sEGOC4dY7W zOV~%(ZH5tss*t44KpIFa4*=M#gfh;DS7LjeS&B(bsNw_C&Tk&J?s(NzknB3HInX*?)pCgV6OeQ{>T@D%IPf2vh#Oe!rr0u<%7LK$xBBknI z7_IEEacvA~jv#zp$?L70bhZ}l81~x0US<*S=JU)<=nR>OF&(v_GlRm+dh&1RSRol} zrp^~odXwk0VcXFDbU6tn7a@pWr(lwFJnVpWNVio*^uGu%Ou(6aO3pq#yt z)NcDPd<4^N(GPd#fu=!3m3^FB{oZAXx;=mVx~>VIH}VvWUq`OoldcBye8Iag!F!Lx z&Dk~=GgKfRQc+XKRuMoL5M6?T9Qj0VI#WH-4-e*=54c&#w{8*7Coh4y21H_R!eqyc z)!pjnZ0wj1@hE|P3p?^+YuXtjPBuQUARxslDKM9zZHh`0awFK6Me4P^Co>=Gu_t#X zAdZO8cNH#46fdsgT4Rk&-v(OKAT`x9`|p<>tBIRhi#WmvLu;hKd;OTeRJ`bA4W1)Z z#!rzJqR@0F+71P$B$v_iQb+;w_z?7wLRTF@Yx{`Z8`yf)O1Krz-(w!Ulx?e{6DnyYa=N~#Ijid~%iRIc3Hw954#Ielx zIjD+ANKq{cohYI(a5hK<*#Qma!7U(?dHT$fK)y&KWNs?aPANAn0Fme~({w$(pFafv zow2BGVt;|om|z6Sx;d1Twj*_y#gQhco1HfkB+{zDo|ey-NQp?jI5kuvTpuJNUoiV& zj~iYe#|sUMwuaLqJS4k|&{A^3FLKVO@3wVN%Hl~Qs7AWVwsH-|Chau4&NHbbSKUtp{yBr40JcNF}2PfnF6df$E#j)J# z%nC*_AxzV^U{VU?y)e7>(GgMwEW61jO`;)^JBH4C|)NAv^DQhk(C1?i5je%Or21g)aBd? zAc6sAFJ|LJI9Q0~7!g_n3jBnY0uh?e_L=Uz6CKEcNSCtr{;5*Xj~+=)vB*=jjv3Xm zKuMq<_l=+*89V0wp1C+=<7HYW(CXFbvq3*r>qfl$50e5W3!G-2^tYejH2YWnd=M5B$#%xNGLs-g(1e5vC-iMhX%p_0T@uT6lrBceC; zn%G#kM{v%G$!G*I2YJSyLwL8Dpld%JcE=jNu1iHEC{!0p(L~U-Z8AY244W5YD~eCx z-~r{RuH7{VD5`HX*E1}YX+1~grRJb+an#Pc%@^=uLdUl#T)^GC+2UBBB*vGGj{LIi zKM51_rz-Fx%KoFlp%$mf!M=>z(cVv}(bvvnGJ$Q026)xy=4Q*Z8uW=8uX<%5thSqN zL~tdgE+K_HsS-xw^YXtEtp#0l&|)QZ9rJeAmB zjLt%SX^<#_F)AfZCOFL?+*k$1m?9rGf1Xb=K0gMT;?AC37Ry06sy%uibM3Xf{XQNk zS4AUgOl@@kIYgBcSI|p|W4MDF(dIZa^WE47I}%X1_uF$j=ZO9utq)EO3<9adS2d!BCh>LAhK_UTK9f2v^^TO|}^mZoLfkpd3daT;AR=8LVoaC_X)c3s=~9(o!IE z>zO}`G4cJ#su9i-3ep_)AF)4V0%QhE*mcHyGWSL5<*CUE-8h*FOxSj__~VQskMvxD zO_uI6Ikpape~Y=y(cKoUN)JDKZbk!bymsE`85}lev4u0Oao8xkP_LmMmzhQYnb~m+r0@l0tWF}%SK$$#%Z(| zEHDc5$BjTv&2vp?{KR}D$5#>dI@kqrtX5ryIZq~{SMKR00~<6l$Uta+3&{3U2b!_q zC@xzG9gaWKDu8_mWLqS%Bf+i2FL`o+EWeIXx#z+HP|)O`kNW)m0yO8Vu_uz)VLUw) zUhJjB0X0_(E2n(K)l64T5+OQKiT7|dJ6p+b4XBdUwK&8t+^1|zxD8ojZMr>&SL-`` zszJ+258WE_$LP1W0^*`6MR(YI#2FJNkW*KX6L7@sw5mzFb^UiWvqo3F_zKwL^yYno zr8UhT3j0=6i7{93)}ZX>08)JN0@9?a+z2q~?J~+Hv^29OzDYOND>oIB)Keznd5~;_ z`ivVuVotLWx77RR2gS&y+2TwtcM;|$_j1&dFtf~su(aIE8lupBkxXT3p9){c^0(&d zvS$CTyMO;`lC~c7>&8_>Ar;k2f32rYMMt=; zxa7uq-8-an2efM42Ing1 z=UGD2V6x>T=?9X`;c6YIM6&2fcMtJCbCaB3tLYu~z$dRU~Q}|3MQZMfr4)GK$7Ux+ z5>x(hkdhpD_;-|lSN6H-H5hWn$ZFmqpJOM}D-O*=H!u$GY!cwjVH5Fl%v|emL&8&$ zJ37=MU2i?`DNaZ-B|-f0%9oy$vAG_-ck{diy-DV+l&=afXuqwGZo^6|+df~MwlTB{N?4eRf)Gm%!fLw= z(4c=xvQ`?Su|$q?LGCe5LzS*&cY1}nL!dw;@_MefFMvo)27O1W$yXUwTQkxKd>XP7 zaX$K!8c1U_&d5<_$p5BcV%%c>yXq5yJt{m8G^__V4R>i5`A3^oToBOcGzS_V$N{X8 z%&kjhf?cRHF&U4fnSfC`rdZu^@73=~iHubfPM!uc7Wz`%R=WLK;&q9L3t~(=5Qo0- z22y;yN6JK)77cY~sU*1wRa6OStOkc9%H~CFexE9nIOjJ+u3q@jzZM`epSz5EKe^rV zE;HslYQ-QU<<)?{f8?57Z~LXmhjd29Zy9Z5dDA?;f)!JT71M)hM_9vxoHW8gN8}|a zxM;+B#B$Ti32WZ2UWIWmNRF}dFrw+oD%ucJS$0~)Q-@Nf0_uAO%i@VUp#n>s;miHUdss18LV*QGJ1vSR|_P z)%NG4R&zl-)_pKwY!30*gi*y6qV!ZOdRXPh&uVE5n9h6IsDJVL(TH#Z!b=e~Gb(qw z_hdfMu#_#k-Ezru)9ohmIho2Zxv~a03Fa;vz3<%;b=}EpjFU(2fRjTDvYoBIG zWRy43?nJT{0w>vM3hP=ilbZI4gfH*G{j7`9n@~{D=-28OrIg?m5}u@Vai$a~DEI*= zC?fj-cOdirF_93R?k;9*H?08oYnWPk_@qS<$)*Z|%)op1F=OyT_kOi}&D}SZxBJZA z2SWVemFIVuE3*C`*cwy$aW3hGOkD!4gGpb^=cFe$rFf6ui?5`&!a6u7HDpC!ADokx z>L;bHbM4})e76fYQSQJwndoxzYv%nUB9S`Aib=6LWp{uRZ;XPz9}d?zMiqsXA&{xN z6rON?3@Vl#Eg5h%dt5BE%Q9S`Vt0IoXS6Ev%~>@sZSTFbF4CtKlK55dB| z{M$IBK~75azC~_5cWg6x%KqNtHy-@zAM~%MG#m{aU=F@gi0?2N78k|~5W@yn0-#Q` zuEsxw;l7Uc=<&jDB?!R8<6UIqExl@=s!rzhIZk`A?_X_@k!hW$pSJ40hk3=2ov#b)+pkK*Z6qCPf7LhK~r1C=% zve0Y#OXO!R6a6Lrqk1w~Idy3kF&B%cG&u#luew2aw&^&&_T@Oa^~teM+l`A-jIuR7qL^;c^)# zaH;z|me-i}dxl!(U+r+*cD;N7cAJt~abj~!8bPb{mgByeK@7YEOy4=eff8_F@1uJE zG}-R%t7^+kQRHZ8mpxArO28}Im%l%y=5f(~IzxO3E#c;XUOq;NdG<1Asxe2@-T_}X zD9L%b`M~{2j$T={;xC0#`m`c;hyFAP-#jj{RXMsE${?}Im;Rd>1^zVF19IpS#OdNy z@NRj5UhXY(4a$hnzma%(q{I)K`LTQ#lSH$_cGF%ZT&OzO>_u70M{>{okBap4l@q7V zO2@YTO6@suJ4xb(+IU||no^Z-Ltip_ls;P8-EYyU`R_U7c`fk=e0i}lA z*v-r}+uu$wCeYU-26N`{2Fr+(G=7~Iq~;YWXCBT~kdgXEKJ`j3BdycOv@l>?YP#jr zhX*|%Nvv+nVicTbx1Y4w1yaLc1ESuS}>+@SBxm{9v!r-}nriD70YAzmcr&&XD`vz!dNmb)u6jfcCVV{Pau0sGfQKFUZ+`81B`%k9Qfd;rnwxQ?So%!H?n#$m9EYXvft3(KZR$oMo|AGgzB9 z?cWf&{(u(kuXY&kDZSp%P9Qg9RL5H6gMVa)B;HOdZ$}kOo5hEPThM%@;)@%5604Le zmVC&24(%8s1A1^{Rb0|S9vp;NMR6f~ov1m@i_%i^W-;N_sfzpWu)|Z*QciAWrG1bd zhh5zA?J9`?yPBV_U5yJpya)6AH%`N6QDEj2W^-OjZ=MykKf?RoXiooxyVUdIMnZN_ zGe{EM5cb?{qpBEQlmT}@72PC~TXFeG+>T4chjA*_u9mY^;wFrPF5{YbTpP>=&io?X zTpE9dmF}>&eHos7@ECf+0TA=od?js6WQGbFQ5h`#Oy1yWF^d%Z-x;Fj_t^gA?4vI2d+xqCHF*F zXYA{IX&S8l7q+ibK83lT!`dHfeq(5qI+#TiEUXb!shoJ=MU$_*b~t_@g0*Tmugi6U zW5Uk{cAOo$iHx}hyS}R}2zPcU<9j%{XWUDfq6Jnm9Pc2uQ?U-Ol{sze+_Le&bETOY zlm&rj*T_a*%LWanrb$oENuowrR!;M^2cMAdvOIXYfpFz@&5^{-x=zjYYqJ1!;^>>E zi45@)7a%8u9vO+@>$Lz3bki_ZtJFt36}NKKDt)=u#Rv=F<4$6 z)^p?HtFPC0?M|1o5#J^>U)BCfx)jCi2XS0{r7Ed&L{N;+gti6J}HlPu^>R(tHp3t6dD-ikK%gFt#CiX#57;yiL*BLqGO>7AX>U^V6X>YpaI`QNH$%1Dh=BkYFxBn~Clb?vs7S z!l}G^fL@@+ek%?8n5L~?F&CSfq_t$)-6cYtCrfOj%;|j zsOdYb$rmk97ry3NndI`lxYU1&*#3)AFm#7CS0p#$^LeLO9WHp1V<2{8nuU#B__CC* z>&X*|X=$g3b)LHh?)?ecZA9ibPq3YbKU<`meqP--y~$*qFs+LxhdL}^N~6r@lU0qI zKwc+Zv_h|h4#ObAoL!3PM`k1sbx*-_Ppcy~iuK*MHd4Yb$?A$4pU;qrGduBS_)lJ_ zn>i}#0;>0T=0AryaX7J+Je{qM8hBxdvat+`9$v|t4`_d(o$Pzx*rmQrpKbH03uYt` zFV=YFT(Q8k3|#S_&b94zUHS6i1@jGN6cx6QBKM@8WQ1NqvXlf>L&$}>2=@xnI&i2?+@BxI8#VFrL%%_46 zF71|9j>gs-4~b_^O$e7{=g+Z8siIBztBrH5!jGYid~3#5O!nKzW9QVwFx<~z?5Cp8 zhEx6bifvm;#W_zO!&Enfob%#H&X_Jmibr}a~JY*reXJ+m%$f*rak7xqoPXgT!#opvf6}#O zlL}C{40U8FxZ|_guWyyKol@hwl$CB;ikGDN!9+-kj;V7T&hS0HZ`y9PHO{fu2QC?Y z{~3$VM^Vq}QcmX`RMm=)U z7bfniG-ruj4vxCn2xZ73W$8FEd_xJ?cc99rk;_``6|*t#1^X_P>MymK|H7*C`?!5i zED^pBOLl^t8LzO6PRW^Ngy$s$wp?r&jFSw4QbU)S7zp#NLD?tOSzrxG+m5vR{zmE} zG1oZ~x z>XuF=qcQpfpVa*qR^rws-E^;UsngHZtYmxx2<`|c-CX2%Q(oqPgeCdt7M)#(q_&uM ztosW|`@h{KNHFqzzYtM$ouM}3%; zCH?b^dF7G%rw`Y>8wb-bXK5lnoZQLHCwewcn6!AcOq39F)dkix*t21fv$WG)e@s>$ z-l>N#ijRP-rc$~!=X}k_H?H7eY44Y*X;R*s!d^==Z+xNkEg~>&J_Ksd=Dn)+*)nJ?z#>tIle&2lm!<|Zn0+g;S1Kaa)k;uUhp5>AU$OZ2A4KU#DVZ#ht}z8Shd@)e;>cdW(8mbU(`eYT>{N=fE=o?27n2QE~FPh@?(cYeP>1zp?}k=M5_ zg9?l@cMRuF#+UKorf@NMf+M?1eDG`06X(Wv^x%*vC5eq~sui>Sp21wQ-nsBtO=;hC z%*tQ=>a5od+%%HPJq!|ZlpGB(x~5kD+;|K|4Y`yjODy{UM#;y_D$b8ph}<2sm-9wb z9#hw-d3+yGRK2+85;ys+!MKE$iWeFOf+56ki--wlZf~Ns4M?)4QAeK?gB>g(c4{e( z*+HjQ>gr1qhQSWXJeH*_pjbHK6av(&pSO4kAAdpU(%WM@kYeA^-nfAFR5?FXuv!;-w!elGlfUVnLQ0c z`0A4jcSlXN1)jTcRP^%2sFk?q_Oq5R5i^CA)8M&v_q~x(mv)uPxTqDMZM(W`psw9C zo%7<4qJOfw*G)X*K)Cd!(3Un@(%7YG!hUdnyL=QBV|N{ly}t(NVU>` zGqZV9X}$dh=Kj?02H)P2YQ?~mPee6*;H3Y-k)HrZl#7v7bRm4xL@gU%LX!=%bD?y6 z8}uAlnPXN2+mxB7;Z(kfZz%Rbuq*Bvd;#myV6g@n9^=3dP%UN!f7$pugS^G*@I6`$ zCv7GZ-{qW*f1Zv_g1=M=_){x%6aLaH;E(qNI=&&51Wzpe@_6T@j&8;~VglT0(ng5B zyP=Mn%=6vJ#9t1=BH`~U5NS$h%7x=iX2A&?#MNYr2n*qoEej{?2cJb)!N&LPt$=6n zcPzNECGhsyo^THq+(?NI{13a%nGYgQyAZg!7f1#06XqCMPr`AwB7B}NAPd{fh!;%jdN~``g1EFGQ2tO&t(15p@*;QBvrw{*sdF8@` zFeuVhxl;8$vM84FSi+<)vr9DS@xrrZ4!Z=Nsvmz}14XJE-34eO+b4{2!-Lt|B+WBQ zhfrQiVhQ6NGDGh(-~1R*qwDMF06_wVXo7b>+eczMG@n$R^IJmG?uH>?u8ykP zkEsFbi2ri1;{f-#nf!-?{eLCUjk`H2sofs_DJQMKKOH~upnmVg|KJ-Nct7H3BFtF; zGyIedRtN68AKE0n#$A#RD+-K)sldO>5?bO4_hQFtoq?=ZP=6|As_?(0u*McB-W2>2 zV|51#eH4uAGOF4GrwU&dc6h|;;&^4zcZc+<$|tw}3Em}MvCn1AekPHBzR_fL)lcg` zE2$hGwkWX7jx`so5nr}v%=g37hqW+K@BH*e!z1dyhrS~&Jv~QWO=981mo9t z66VL@%rAWZOZY!9-#qyee>*WSf5m3`{O;lX1-G=NJr7*kOWaNzXTDLia9Loq zFJ~H8mK1rE&-|u4PaiM9nHRry%;G;V{~TT%!Q(M7r@Pma*@gI)?;9SVOK2?6_}H#j z^`lgx;)w<^o@B>?OUH>Gyk&o~!8f9X%L4-!b0%|DN%DfmwqAJZt_Y2}U$`>-9ty1d z;n&}(&eOLGy#?8zuIPc#^5FQy^rK?Ww>gKCT`Cv8!BV%3XCYrwVvJ1uje;*G3KMId zf7fMfNOE~@=(|c@yaUe$Po1t?ei|wT{2^+;Ud5Hyd$vF^f-cm*#Sq_~57}Tww~H{{ z?6#eo>b5CWUw;s0ufEXLbbaP{x*S?QBRl((vV8VE58~~w(JM-o%T@(0v?NWGhc!*Q zmr6Uo#QR7IDueb~2L&lD$#7QeG6(!+2%_F+0d=^fehw_VP{|yk7P|!!3}wYgUmSO6 zU_zyS%@t;@KLYS=sZ;dtIPH9K+~M2jm4xt99a0t<1x3A5%Xhw9xH<$D%quL9@wPP( z=8yDbSQM=#!uSB@I4ybdjTkFpq!7OK2=em`k*~?K$Zv&zm}jnA5a&d7QcCWjk_R4W z>m9e=)ergq@$%ul$}d!}-Mw2p(s{a5_oTA;?9Qfb^MXUmpnTJIGOGE?fe68%n=bZ4 zKFR^F4=U0m+~(exvua}W?@5WD?#)+B$ghOgszmRuq1jOBN|im{&HaDcc~V^dd8hLJ z3D?T+@P>l6c76_Y`DW8lVnLA6#5Y6CDX3D31i_sd<@O(m)Urvaa<`?TRm5~+z3L6^ zbl2G5m7JR0pPDtvkA>Yk`xCqfrql!_+1`}$zuKuT|D2*cRV^}j#?hhtz|OK0%M1!$%{B8w%lsJh}BdImIu+7v3_bsjK+ePXqB zla=ygja9e5s+zbLGU+RVU&(F#ptSpF>{tB{5NUG7_wfQUBRFSU$?axRhlOXCOi~Lo zRhBZ?kMDYnfK_gm&`xEd;YgXPOk3Z>>&InaA3p^Rh|&C;4e|XdIN(wT9)2>)wspJy zZl|l19hP^Oa%s)LZ6ihNAJ699ff;13lE$0+k6T#lA8)ITF*cDt7%@k+9=m+k*8>(V z>ndawglzDU^4>OjV&Lgr?G<~Ud)w)t9&YKd{Y*8nMWy`3q^c}EgY%)Dy~)?N9=WbH z)1@!6s71UtzMx<@aKBu&+JnuI0Pp_z!$u-gDo41UzC}*x7v11ZMQ(%2NuS^jlZA=n>rHW&W?Wo$Sv*qewc-u= z6njs0tt;2#O5){YZ z^Pa8@xM4kIY#f?lbTwLI>MpbF;(~!YGP&6MGVhybi*JkrL00X!`2CU3tRp3tD)n5a zt~n+maq`9U*~{B*zXc%px)zwO1R%^9O&cQ0kl$IJL?lsscAmH9M)JNaKYT?PK9DQ+ z*r2`maX?Xs{X8eRN@CD9tthWW>;0!hd^&tG7QBwR%^mi(C#4Q;+mFN)TE7jY*%d_F z9&^qTvdjh`)Tn;;Py`_K)_4`#4}~ zNl5nBL9Hx*f8yoQs3%0Ceq82O60M&%%=_k*)EhG8xAm0nbcr!!Pp)fW9tji8C9JHV zl)7eK9T!@>rpAu)Rkf@oU#$1{tF8B)cwj-|9`aE8hnDu`G?;;JCfwW<>uyb3-7~u@ zY^~PKLyu~7boqNHSadPV?v-N;3JzRrG@HLj%cjh2_i(w#PUSj-?P7MWnOiPD-nnM) zrcJn?m`S3*_eXFvstELzf!H%7|Pv3i$oKjh09NJ5_OPwjc&0fk=d6rae|ATvir~t)?wjHt8 zL=MPoC1_=zJ=St!ZdUfipeLU@4sE*d>}~E!gS1#!WDX zxk^5VP&rm~(mSjh`jc!N`BpD?QD1@U*G zS_h+gBWxA~Uda*Jb9T|etQ*VlI2v$0&uMlgHk8|Vit%kx*^LRd4JsI?h4+)!x%7rM zUGJdKVR#t<;NZ%$%DGdW2S_va7%bD@UfA?*QrCpCcLUFtseDS=+6Sh!uVST5_J~4e zs*`P->ZP8FisjR56L$ymc|7z-1#Rc>1E%NdwT$Eb$LwbxJ zxJ}f^Lq-UA5Vssd=@^KNsOFXx|x?SnjAFY@vdf!euUS-Sh4@RdS_0M1OA>J zSXpG=d-?V(m4#())oT~DFP?F;{E3R|*@=l}i?&;RWC0XRZGPMm-+qI%+}Fp*`i{tG z&}FYVUiWitlag+afC*(>tsU4j5nl6AUHGZgyn=O;>u8Xy4TlbL?(+W}H@8CqI?^@(ztgGEBc6eXK#FH&j zX-Vs9WOC(d8ro!60<=BzuN5r@Xg~ioJW%aqqW^*>?xlgw54SbyhaJ|U&lJZu8RG5S z**Wv$6MgZoX<{1|O8J#ituy(z1F?QDo-pP7by0Q1`hcwnYHBm2gh4an2 zng0rwc$plF3xMvH!386FR?2BBsJ>?@Xesv%&yX0_6?e+vPnRBTA1&YMEFwfeQ1X9MAhJue2Y8ByuZ%cb8B4^vVXkaDkS<7UKe)fR;g?|2TgSh zz8%){Rf^oi7M&!6-Xndq>Pi^zMXR$ozA7Jjb?W8TyQf6`#Dn66-z&7Gk}TPHvv-zc)T`-DgD>|i@VkI;jK9d9x7ni-^T=(y%^X<+w`iN=O9 z!H2HTDVaB^*IVlJ+p?c=m$yALu#|}5zgZ}-^7T{zgb>H5rZoFZ(@Nn+u|23&ohiY5 z^KfYt{piczX1jQ^ztWQO>f}9sNf+xXIo*{9{y(O!f+4D|3Gc$Pba%IebR&&4l7c~l zv?w7W%~H~hf^>s|N=XRPDcvF60@5w<-3$8q{ehjGGtWFTXU@#r)yVMW-~YMo66RtL z{GJ2y*Xg1q=XttQ8#>Y-%ss1Q{KNb6V2rSNjrAR9XwgKyC_jJt9epO%;fV$s;u%sA zr0J}(VN>rt3b@_^bX%`)G`THdC~P@?U+(G2%@wg=(mZ~D{LgKlw#HqN9-#H79@^GM8h5)xiF;s>tTfoHhd4;Tse5<( zZi+)cNQ4hvtIrm45G!0i=VvwU;FjhRbQ6{Zy}q3lpqB;UgfAwsFU^4`gX^sI_~Aaj zPEq6Mq&@M+I4MZ2C%^P6)7HwqT<^I9GVvs>vAJm0_j7x9cTiJXC=Gs__h*0G{6A4= zuNV&ZLJ*R)tjM!+qEY!wvZ3?k+p%YZs3+-|1;jump&W=&7DC95rlTY^dFjC8hbE+{ z8pp)i?t4FD^c%{0sXuBxNz0?q>#Xwr(%CG&EfLjNFn++d6#w@0b9W;AY2g( z?DeG?g;X6mez;EOYOCF?7N?9nZI|~e|IaOd;4Ti9xd4$xqTJDJHpkNbhfja^VbYIJ z`HP8gz2(E#dY>s}_>@KScEf8k{r;nyOh!yXb^LCc($2Yr$VYQ}?oVwjj2e2Bo{UZG z3Z+lo0bc7E|7g~g2K`=?e&JKOSi6pVioAaD_MwgGBXG4L-}p!(QzN4_nvVvmBtNX# zy#SV9q4h}$UgcV_5&k|v|8MD=jiOLkmPEyYO!Hi#wux(|gM~-q2f;r%=3hodr2#n~ z+GaO=q8A%R5rbO;s5}={uEG=mkEl3JTqzM^+!>z@@Q32dAZQ{RezL`@y^ZS?Une0f z`$_WW!K}06+az;zJ%Q&%V(@GNjei#Ne6Ba z1mLbxK)mf$^meXgFZ^2@t$}BfMts_L6&+@S3P zsTc&)GX!{{=yYpS>BbwS)OjfFh<7OIw<^}+H6*x_hBuv{Re>gdv-dlxRE8#xV;-UfCS zGu8iQzmQ3JsksNGR|+RWKiZN$RI7d~rcaXLIPt+n*o`|B6P!>3gA0?g7oOrR^eqd0 zd||<4nMw!-M#-Zc2`nGtclJMl6abrcjGZkTz9!&Pba~i~{6jwG8w#vJ2xxY+;7tVjBw3v!B82`IVjzJGG{8_K5VGF;;UFl+6#kdVDlz;FQ8^w-xhkS>@awc zX5bcuHHjMipd$~lZF*AJ;i(Fcg-(LV%3X3n={KhvhkdPdCk4UdTojNqBs$34gGhjI zXS{XUebykEaQLSjGJgW+DbtnYGp2{|Z;gnui*0so2WC=mxEQ=nDfv=7jL;)6$hkWu z<45T4jU+&7mNn}^cFE2+I|%%hAxxZH4FzmXN&Ffu2|&$`5#$WSen^ ztp;+K6RVKBg;7M;1DqF7oS_ra$(Z0CN-)_F770{rqeE90Uem!T@o1DmDJAX1-?_lX zB|=vR?ey%YW!SB3I4ipk`PH*SSd^b@Y#WmF%4N5dF^Gs`bM{j)M0o#W7}QX}1O3(( zWM7RjT#qyV5qe@%-`|EZK9r;r48{o9aXPW3KYq6ve^EX#M>E@7 z^V_;^KVW%$s>Jo?px(Q^H7l53oyjDneW<)?5t2Hj;>^&Yw)I|F`Qp2cv@^uK|3@&i$1gv_H zeirB>F=tA=C4Lp72Sq|>o{P-6tPhgdRE4$V0M44WGC3L>4$d)_oVULtx@TlkMu`a_ zhNASV0sT08`5A+OcZJa{9ymxU6eXD~;PA}G8x%x1hb}k9m>J^5-eB5FLYbVSMXC7x z6K__*VU#3Y6KP<>ZoT(OJerU)fN4*8!67;T(|1pwoPK`%{?Rlo!Slxu9zxaz3*hRp z6e_{I{5qb1y<)B`oJhE_h1#Uf=B4H_I#CSF2EB&P|AtSqLJ~g#yXFeU``db?i@`i;GnK6;g(vHMGSb(Vs6*mD3vFl~e6=7=N zakUXodW2mcSMIr0oz6KUF54FlNH8i!0qC1JCinep3fMDkuzLHevI*}^L06JzFNrGX zVvMC}tN$kFOhJ^VdjVwV4=5B`b8dUcAmJVeKp{K$_?7sl=pcxlUQ|diWW%jleORwT zc!(?82@N@kAZaqbhH}y$8!#;Zh;4Vow~^bbtO@xy3*>EGL(KBMWDmEjGsViI?dx?j z0ENDvm!IXKSMVdJ-@UZ%wa24^X{ZDH*7aL}ACd+jmZP62YTa=SvF|?e_vCALS@ptD z5SFa0W`K+z)$ttU3(5tW{xX7>``0p7k|cU~#iyvwZFc_V%IJ%7_{@L|-(I?k0%YIl zS1?lzK!#(BnjDcNAj5nl?y=0ZjM)w!S}pm<+lj9?P!P39Mu_vqYnqPIWn<=LitX=% z8$UhYy>`kTGB*k3A%$m@yUk6_-SQ6X}UAf=b^7;01MGELVSWx zUV%>ONOM~xS__#dzCQkn?ptVXU$yBNDkK@H3NmFHjF^N1G?Ox&(^B6rCA&)LT91^2r}w&D58D9=o!ki>mMh~zntJT>msbYrd$`Ie*s6$EY@AqB|&x^3w;QQ^+ ztnpBnSGJ0jP>qFDIUcAV)l}DDFUs4*);+rgx(14)+S>#Vi&w=1?fz>eH^`6CX56^)hr<( zeDmAZANmym=?FYS=+FH^782cYCpd-<*|x*$EfywIbS5Y8=zGPt3yZ;z0KE2nml5Y0 zFR(#%@71ZXww+c4?}_FMXvQkAXNGzdAP4gaQZ{oGUc3+68SN34cN;ILH|s+BIZa9A zf}FoWWPkj<9_DbJqxk^pIWcyw+HSp+eojI05K!+KAvYfScTl~|F%(WvJqDkuD>WGD z8>D?#Av}oCVbtZS>jY9LViMeYROH7{nUA+8^O(l@YfKPpVzd8>@S75gL8p_r=fr(G z9x_6}(pJE1OPI8GYyq=vc__E_%%LiI+M%m37CZzX)~rxd1B$&YtwSnu6`=7qW`nAFv;E#?e=K za$vIXF^7ePyhX|36T^dBmYw)~>;2~#5X5Ynt55KfJV31BMjsh}kqJr@p2l6`a(=DC zBZ>HK2r1S=AV~wX4@NvU^R?G3-42?KsABd+To{)7CRb`K)}oa}mU*fz7qZ6SLS;}= z%;2wGY9R~6NbO(kEQaOlxLF!uLTaEV zSNd3Bu?h=?J}2NYmdd%wQ3Q#i%qY!V!>%U>OJ(D}vz7JQ4(5XLO3a|q23ESV)Bw{m_*`D)l9RPZ?~O|009zf?uVybJ(F!EM zD`z57)^D_LBt++pCzQrfer%Fcev6J|elGJ!hQvIo7uVt3X%2WQhXDQr0l-mPNtL3$ z!`5gMsC+WOEmf7)O3gPYR#$FzLXU?J`t;@d*n(?tXdpLW;w(mK3^El!rB|=^ub#Hz zL%%%$807I2sRd%wc)tZHSHvQ&cJyeFpTnIC+0k1DnUoBudfy&Qw z%?iLJHZY}8yL$WGf1zy3A)e{iDo-RU65Rk`UK%+SmUhM}_9RADiGs#4a0ai*j*M{@+zSO(9ou9vfb?;9v0X%U(< z{I??F4|5{%M9x>4LMh)Xb}CW&)?|xMp=9Paqf4DEwKmGIx76p&?7vz* zMf%s!SBo62?9xiTRm-{p6@ub@P!hXVr~qQ#%BxqNqY%alF#sl5m0zP3$h&3&aOC4~ z^V~BvLVn}RgW5ioGsl8QwjdWD*iJ2?L<-&JZTS0gThShoNnb=bUmB*XIx9bm|6rpSHTsfLRFM8fmKAd7#0^NRAiB8CH|%~I=ART>rT;4kHMG5iXDuToDk zgFytmpZ)yI#v*>LQW1n`otL6{i7=7_G7N(?d;^$Xxp$+t-ySOs{YQqU4F|(5ne%}p$BMNhFiQS5*1i=5 zdRF~yNcyvIK^}auY)pv9`6~z&>h=EZ!PFNi)xPS`UzR+A^6`0dqlAV(>5`WpPa1j1 z+ov?a;D3gr2D|NKaiCOK+!gpIiN7Z^{A}nLxM==Q(&_yqscT76%#f#A;g?)8Een7o zU@?VGI#Bmp>RCk7^sj-k<7SNeJ=bbP5#@k?Z|un)g)Z6s)Xc}k`ZFGtb2d)J*rZKi zgl(0;T2?7R`$;wF?6^K`zc!&P6EKeGrIP*nwQ*RG=W+r|Dw%&tdqPcaL#}*iya7r# zAWq@4?B|y*gNAeAd9qijptq{r#&i0?-z#QTz66K=X>j1A zcw^fKlkZ$c>MtYK?g}GHK6o`8qQZNCr8NNc@hv}%Br|2kO+R>$7~VURMl?p{^x2}!k-OcZ$l4Gj3DE}(g(Cs9+>0T4|j;t)1^Qcl!M30Ff!Ca_Yw4ourt>? ze$fH~944b z()d(gMaYqkpzNQClS1}TtuF_b0iCMn1s_yr^dpRN9yeu&>iQ7CCUoL8gw^l3L@xh$ z@RGbkiv;UW>$y47D3wA}8Dri?Fnh$aXW}BC7?a$)|KZ`?s*D|&P>k-bo~6$@?LHKe zX?g(#9@391Hvl_n6Fwb&);JB7-yV`t7AUGS=!xM$PsT~V->>(x((tEt!zvFMxQ`Tk zmmdB=p9HH`>5j$nB%M%mb2ktcNDcBKU3KHOx(o2Q(<@)gZh*(%EZQGRQ7 zc{- zLo;8@(PvF6eeMgJUs>5q=&QwU8wDXDl%^r$3P8f+y!w*#zJY*rRPcrYB=PWtNiC=j zo$V*<#)n9U^F+?y9ZRcLGy9mvb3HSt=U*B|Ptst?YF`Ik^Up(%%>35b2IG7++@h1~ z?s9u4AAT^F+!rF#&juXU#!y0P1~AYiU?5`#N5^%Eox>x|syJEdU7TnEpK~!d~gpgz~_phm|Wp(e`W_p(f z=wW)_HqP0;O{^Gb zoI?O@F<@7WEV&v!Ys(IUogRe9T5!Sx?mzH8^Msu9RTQ}j=&#dJaTip8zcTv7UA=rr zBDVhoMVJio6>0)8*(^a@16T2MihLL-2y8$r=g`Kwr4_Z#c6h$`u61SiL;T^Zvdx>N9SDu!K{At@c0qm{<&R*7tzT&d#tiodBD~o%dW+ zZjy3fK`PkEAm5-4kmz#oQRR0byp$xCUXxXxIPQG)z5o1H?`xetU3`J-5c$vK%U1N*2OalKi z@Dz(=&3@06komvgrml%^+D(YRc(DPRKFw-3mTyspjF=vGW9Y2TQ-Dx=0S)bB;t=fV^ZQ+ zYWe0r_u^&WKXt071Y*kpb@KL(cV=&^;k^lL^#s&`Nh3+C+5+mNOjC60_d809?Zl7a zi)6n&>a&p2{MG#BSS_x`g9()!{%6X7z}ss5zUdaZ8;z1h>o(t%1e*Bq((ixjR7)SR;vL73sZ!$x^qhd7^E{yXsGIeos(`+%1lH9n#!P1stWaQe4_H2S=vk`sTN3R3e77N0xv4q` z&+fVLF2CLu4S)PFklBd|D7@zdGCR{tyo=;A_@2kml^Pa;2I_kCu-Xo`Zt2ANk_`O% z49Gc4?*<|Q=j^DUSY%9U9vkCL0#ZX)`f=2~4lH0G=ngie3kOP%@1%sTiu`?1iL^Qx zkuz>Xwyp-iPkrQ!jP)!RQ|FQYi- z`yZ|x3=?D&tD}v9rrrS;mAAxF=G8&xZ^rPiA_bgZ&`107v}%t`K9sNna)2a#C4~>X zcR$GSP+2%K1veam7sml(g=&)6ue+9d(SuLQKW1Z=dA1$dtGS3Yr-G^rVpv*o0jfJ+ zdY*UnF5x#Q;Uz-X)_kCdmY(azkb_f-B!hk%>4=$fPsdKW+{7OQ-FDIHC8f{S>juw# z$-s~5ltGrk3Q)a8nmzq6Wj<}bgz(kGom!snimX?o=0W^ZAR7~)o4Ajd4MTpd;LGZ%3hk&>eEwfq@& zQf4UbcIK+}UaTgb;1FWaZzsKV8ay?dwCV6#45X>c9o6th0ATPhWKK{w;V_qbLFwcW z>ProXL;lz6mYNtN|1eBvY}SgDZ5~^i@-%ux_kC=fZ`=(Ztw|HvbXxvwGf*}w=sx5c z_Fc?XR(3(b(?=zPpP~)_6ZCqq>)r!0$_yFgy8TyvC>*5Nk*P;W)Gk~`L*_p~KCH<@ zA=RPm7Z=ko&k+i4C-=WKKee#`4Q1nPb#gefn3<-*jfJ!{Eo(?u8h6v{$IZS5d}PFW z;n}wQ&qDT_@@H(fa5OpLj+govNRjhG&wG9Sye)1`c641&m2_r(La#yj4R_Y=Q=}kA zHS;z9P<;O#!d7c};g^?il3ilU-z;z|vHO@iCtwl1;tN$gj(!kX+X;U2KaI2px^lFb zXfig)*ac-$5 zCwWw-NA?gI|b*myJB!xIN{tKR|z7j`IY+$3|2%%T5f@4=sF|!k!jv% z?Dl_Lr$iclZ8%Voykh97hehlUeoz1qbK1$f-svzK@q@N&2t~=B+A4AG)suf>ep+*j zQPYng_E}%Qnf;7wTvp}~(4>T_Q@Bh02o&R3c={x;4?R9rcZ*iv-_f=xlvryNM_jGG z@Nn8^A^txxqJ_NcUH$D5KQ_hm<;)zYt;y#4Wd4acjo?NlDOpC`-Z{jd+a=PN8-}*h zDMjIQ*9xj`fo;m>PexL5Wz|tI>Ti?B%$A5?zAbKVv)eDS{-xq+O-^OcMaT8I3=eD@yfFiIrwm166hCn zAU{Kw7u?LHbMg)4twCGrWWAgnkr|lT*!F(dPgOLf$_WR*C<74O-Vd|kbb1oX`<%Jn zZHC<9!`7Z-2dn>hnF7*mi#LT=6|eV$`toWwDj=EWQM|K>tg1ODurn`?Dw%>x%b{C( zq*8Zp-~|D$=)M!0&Cznz-DwpQXD-semjE{n-t~bUi-?cwzOz|}Of*jgzTI}-{|B`& zzsLKi7igaQw}prm`Q3*4JYdceU!5{nKa+w`%TmFPV!?9E2;MM4V`B{#`vfI$zE`tF zHqEKZ@AV^02K>euPz3W#Bs;WWO=}Cta}d`GA;%S>n8AK^`mqzoswxgB6EW2{*^M=q z!#=s|-iiny{Vee!2cm`Q`7t(KxAvt)@hQYJ^dBRj(K6|&kt+k}wwu5Mg0&ExkfgVqRjZ~WJlKzG*~)0cE78Mj^htA zjsg&^EcyOj0BnjtCtwMMO8B#DXNa|sGEY?5K`EP-iCoWERTa2I z8$7rj)jkWmPo<{*lVaZ1A#H@Li}Fd7=qM&(tl^Efa;fhphv|1?s|^6kLc|5bLLqs6 zWOwL&v^*Lte2qyHgBTq|~JYp@~4`O(M1H55gk8hy-q z!HIdSSK2_OgUFb?&JwS_+ zkIZ}7I3=J5Z8Sbbohhu6!x#K7zhf}{P@Bn1CNq*bD0Og9yRi1G(q!%*mX`$lIk5&w zPBb<2l+VR_9^TmMmggPWZ@ zCqW%qFj>hs+asn5cjgZdR=^@J=SSZOtkC?mnUqeQ8`GMwk7IFe2GKBV@T z5T#oAXCtjgi&E(9G$*4H;e?-zkzS2RGz1!Twd>urDq2lJE6{bV20WF|?U_!mi4&S} zuwP&umDybNChF6c-QQJdEqGGAzt*25{Uj5Ry^e9py*|}4L7_T156Fx0jjc{gpU{eJ zm!AKZz&Ra0UBQt|rQpp${4a}J~lL#EsTecGJZgzUE# z5}VCtwDiq-~@MT)Nfl~0!)I-KN8-DnOb!~Uf1Qdh2xQnQ~3&Yzj6=AeO=;YpO9)i(oScf zc`Zn9t_ww+PIkea-A?F^@>BxN?@{#Ei~j_bx!>1?5AdC+FzhXnr$$0zNY$zfk^Zb^39VM@?+tpe&4_9#QwU$f z*6df;%52@yc$qpL*+17EzM`b%VJ&T}Tx;O6XGqAeyceOkUYIO4O>Nu{TsY0k4|MjW zMX9rR=<}2HaOJqDj(yYv-qi80eM~9&F`Z`(=L0_%3-&@hIAD;*P4*LkQ|t4%ZymL^ zd%p}#|3|M&wDTNJP)VF#MFkHx)xHxIpW*gbPES6lEYxgVx8Eiu^x5N>uhPH5tB^bO zk+wT_yuHDW`}1kjZ1dCa(>8e9bpAK1C0J}&xQ`Bt%YwLp&LKM3b7QYf-Ta?H{}6#g z7wJnvwmFwU2xC7Wb&TaGmU@o|ZLA5s^MgnziO?h8spQD6 z%YRg~=i?|;Oc#nOJY|+IX65uY=dB@6sm$)n;r445x-ceZAUY45WPe`kNNJT`{bhn_BSKzdUFOXVJh^ z<_Jgf2TF>I&tlQBV1<@R#2UL}7J!4F+48@H9J+%Z-ByGdWh`4HY~^Kt1F(|A%XX^A7wI_brL%*i;aQe1_PDyER_?$Eu5bm6&Ewy#Q~qk zvzU-PXnK0MZ($(NC++L@bsl_=l526!j9Hvy@4ag^=s7;tnp3F4 z2Y&1XbRnm8hG0Bq`I9zhr#(Ba<0?W$RKfuV`B{?GDN7)CIJZrq;&?RLDBO(J{Jfaz z(;P9|xQ*3kinreZb>3YlQVKVS1sP<%zNDCj;=8p*KwFxVo?K)K*`K|nh4#c_fnS{l z+q~MoCi1t0;r1TSlnHB0NNl#$H^MmnspC)GzJsCta>s$ksiN>vzSQE6+)%p37zYvb z+eo&g;6t=rtkUy_B5d*+tWADHlq`(kLTIoeztwr1!_nym4Z$oY`GMkfo3L`YOG$F@ zG^Hnd1Ibh8)!&HZ?(FLMDiM=%1K)Dsx(`=S_a&CwoHI4h2^RK<+TgFzl@UKW$Mx?K z5(LsmP95!P-&0<54IaH#R@&eY)HLw{5LcOGS3BRf)1WfEPb=8og4+A zedQ3c3=gQpQ>^Yi}ImmebuFUB^8~cLXXUEs^_{Kt4I|M)RExD>Z0yu}` zV@|xJn;$H~_c+U!?qb;j7K(48qGX#}YK%)K3yb1syc#&3;+;82sZ*I>0co2<=+;}x zop-XVZF~BdM97IQqA&#ArO5uQQR%L6WrX2KCmqvGAS&%qrBv4ZJhz8Q<4>rzbf3|} zGve&KyswLD*=L{{qn+~NQF=xxYP~$t9VwDTBN4uy!jedw$%jcCHMT$?x-%r_jGU(8 z`VjTtLsKjUOA8K1^cPyIZYmi#!RFifZAtP!o9dJ|-PyF!y@;sl8qi)befKoUG58## zUd`J7+~(*DU?9m595F)Iv$+bn2JG?R;h-;{tOWN5-VkmlGd={PcwKU+{hT72u=l*q zXn_H}P}eIuxWYleJAZF>-c2WbfxF~?pL^ImPkqoo5mK$!?f5nkUIgdHf1s|cekS*} z__zWP)SIauLvV62M<$^oeL_8Ie?F7NY&$SA5?WiLBrna`Tm#Oat*;EnA%D7aaz?QC z=~DMM+X?ei_-9wy!6DIOHJ2{B+U&o~y;NRTI|}nguQN1ytXTTlyIxyhgmGv}h(UGS z;|Jie7DkE}Xc!0wS@Ippdy^XvGdDKZjn+On&&))n0KR0is7@t@ko1>IDAD{t`prIh z>bqqOjs`Yvy4TgO3ddSi^1s8CIo{|KA&CSA!_~LaoIiQ#=2WKqfJi2hxxB|U0;^`d zE<9lwFtmqezIE~+zhAch*83#pvjrGSOx7gmT4e3$9^`dWHqT#8u8fUQP;q%8XBGfVK3VfEZ2>eg$+b^nI|^oDm* z6X-=Q8x`-b4Led+Na zsrrufMt|iKt(x4M>l#16-&pvG9a#lTjas*d1ULqkNafC2Pj{xXLrfFS=0YdMjV9*e7` zji{2ndu6K6{Pi2Q7>Bz5=_W$9nm^9exKWW*82RxRx5|1D`JK7XW}^N#x`ljhZ$RC0 z*>NO~ui50p;}WYiGOT{ib^ng!G%_VP5Q_?X;{=0Hi7ZLWTj}}yy1iAlQ3jtm*~%Ba zRUNTuW`=M2ALOe7@bg0@38=R6$1VfNuM%?}Bv$WTu)pOmxCTcowWqlo9Vx2D7!<9? zA3sx}^~F>~!U}e()>!y^;2hE2HL+D25WcukOCOl$CoeNDo$b+f-zMcgxWhE{z(uC> zL+RgVeDjm0ajQTI^yeC}t|2D{^{U#e-Ig$8dQ6;Q)XxC_h2%)0h!^Yn^TQqCEDF)l z#!uRQA91{JG5D~oIL!kv)6%1YA{LYEhTm}vI;EFe`P`}*u1>>>94?au(T+dH)dKm4 z_`q+Mfl*2eCwqt3jL8-EZmrq_)GG>QEuQ9Wk3bF)P1;(Z_^`Bhp0fin!Sa@t4^M%b z$udN#5|y)bGv~8Kd<+9PL%TQAyTF7EXfVD$V%DX+hNP?oG=)YZvz=#l zHBY>;qRy=ZAM@W)YDGNWnMdfey4ag>EzS~;A{}zGv)r#NX3E-}WMFV2|1%rgnHXXN zG+q-plcmI}Wvco3<(wx#A>IZgNH?b1TSm}$W}u>QpEjp({lsCY)IO9w896Fpc&W$u5b9nONPas!mnQD8C2-Xi@<|A^uvI7IX;+ zZU)7}42qR{N+Dsr3#I4geII!)RvvOM{y0-syB*fJk3uQ2Lc?##sV#;FZirkZXn@JF%(E@%2dG1!G?0Ia6YW0%8d*; zU*qW4xQ2xJ8}w8Ps0p0wvPUtdv$iQUmvdv-aU+wqc_W*h70H$oNGkRwvU}I0mmu38 zqPV3kdW<9O!djdp?2z%!83+%*fdw}+ojxR>103WEg%Tm z^yTB9*F=aFNuSP)$ZOET-0Rdje|R$XQa4BZ#kZsd#NS?F&UYuEvVo4)`u8$Yp@_YjOFE$UOV7J z&TENbTogY%S1MI>_FfiD!S>O zu*WRWeb=8fpqB4K%C7``ObGO-CVE0wGE=5C^jkRw!uh8;O37Tn@sV++{5d{T0$pPn zA>>HN=)miW$tJ5WgcTo$H(Ql`_&xK%@e&NS+%B{qa94T+E3%Ou&edQJ%A-(eL##mk zfal^ukase=Fmy06ccy=*(1yk+^NW2T$K#+iUk>91Ib=@JM$7Yt{9YEWonjUf?u>N$ zQHMK|-f8&OyiII38+XTz2}1+SUo6<_RK|sYFDQD@;zc--Ogwn70%og(Q@<>p?0UE1rS(Vq8Rx5c`R@Oc zS()$7dJ1Id?m?ZaD-B;IsDUvR0Oi_U6E`R)Usw3(L}!T*F0Z7`$ZgV`+{$d3YN3(av$BS4_#ygarDgE(L=qszaK=YN%97 zRyay5vUrY^D^fm1P?$G7&H!T$Nqno)1~0V#zYY(Vu5v#>Be*rj(oZ@i3F1LRP$NCe zfg6q9J1Wft?U*8dbFva=Sho~2KI_hTf}_KdtYQJ~AF)Yem_mt1Hb|2SL`o$IGV|y9 z;)#;cl=|DIog})6z31;fH+W;XolQWD$?KA0P9v-VLi)pU0NsmUI>c|#Egu)afvyX$ zLiH0snqkMlYtl${zTVUG54#`_zSjC9u z7yR3o@Q$6o;sd^dpXvEtbH$*LhQB~RAEY5_oM7+ZI<${^Yn!pmk$q6S{hi2X4IXo#r<;x;OrWH&fTDpiM^d0Az3AZ`0N4{b67|UnBxar&IDAE)<+O>?u|VGKh6xa z0xz&gX_Ol~_8K_21gSWrGW;O9SQUZ`XvS;f^VVJ$9F~}#zx|9W)8X9DfP-_K=Sbji zYrjt?SPC3mcEyR<&B5hY5A$KZgNraDPLU>aFjZM;rQK-qbD`Fge6{y89L?@;>uX=V!{omvTKpo-!@ za=hAy7ckS{RXaZ9$dd_}t16X`DexLN?LYSY1RwA;&P<{A!DBCb=a*V z|J&~KF#VJ|l7~RtQlF0Vd;Zy8_Vybf@@+(f>;w<)*Y%M3%dPd-~Uymib(>pu(+z7d;vl5=eBHqq9_C!r=Qr zjv&Sf!F?e7z=UP2IAnsOKnk*nLWk1dR3@0cAITrgdqdeScZYsZnKD&5z907#C_ZXc zv;h{1ou6>#t6xVvrd8?OPyPka=i9V{2&Dztl1;IC8t6_NbPD{yG>yH*I6fPytCEjB zN}4XVPmx;u8M3rGgjRalyesIE%c@_A`}+C+OW3W4cK~G~O1N_)gdjT4k`55^>Nv_qI?H)}`S(3U9AunI8q0*n?Yhjh z5J-Fhtam)Q=i`P_A%Yz@kve^b+<*jIsf@s4bb*8W3$di1#R9$CK%^6}P8!)kV{H7T zZ%2d5*sUmzp#wy^c1QXbH<1n+`u!uL9JYhgRV-YfmXx8ITT>Jr@eKI(ROk;NMI)Hhi z4f0a1vDW$VLy|ta7IN)`R3_Ay;C0t(S+zR2nPvCt7ZhwK@v(SjDE}SWJ7{d^>!I1K zOuGq8U4mhajc2C?=&_+HrX93`#rqx)YH-uwi@iLDv z3+`IvBaHmX2}`Xq!7vR546!s{VRC}cW8{4plwtA6DLM63NI!C3j~yKq0>rjwd_^o7 zp_}&iOEWr|Ny;a{iS4I%NqTuI8E?-;)UQ{A(Ww?Oz5F7WN?sID6I7D4eVoc>wsLvN-AEP3ETwTuM!0!z4|1A}V zKFEGV3pkIWU5Xtx+qtUZJ2qs9rz;o3ALk)AWwQ(Xh|INYJb`GHYz|+m*{%Ow_QcIt z7P}gFB!$h75nKBh|^Sh4~Vl>VEwovTp8cSk7IHsNDRAnbo&lM3WJE;KT~Y^2f*R z4q6Q{N5~E_ldEJirl@*%TlUIya#i2re>rSXS>pe*6gpN#pYa&f$=EQlYCz+HOOXxG z>HIAh^hPK1ch;#ptz{@%9YzU336_e;7*D$0*dyzs+iVLtv`IC^Kwc>6wJ@OQ!*zA^ z#y0CsrAoLnCI56m>r(CZdWTwhMaQ%^Uyr2!t(#|&_mhH_Faia?GV_sRYWe9a$Ad^9 z=Gm_!&ECX3l7R>J&0THgP@5$ZenMW!jW|@MS9YKDD;y13nu8+=Ry%qt*q#_u$8|Bv zf#i`8y0_7Sy3Fa#BcZ0c5A;vB>Zz;`f&FOQkjix{%|GL{#0|G@%K%4;m(GLDlzdJf zX{!Ys=`+KoKyuQHLXb#Aod2v%5NVy~6slkRm5(oJmxP3>`;V+bXQ!lTU*d?RQ`v zu|(DRCJU+#G5k_%3iXRB&sFCZ8QcBPQW8fZwqT6%j`YVJaEF-~#-^S`fcTEfN$+>; zuR?kOiBCr3{10H1Ma~aWxul-(XUI7H*@SW{IRzb^vGG1RMi$@bNxCq*EP(t%7wGdF z3Ofx9lcBuk)aWxb0fMz(+gNALNE9j+-Q)%WhXAZF1I6e@-IRvM7U^2+zw zjl6-gFnWo5@($EMTP>HL=w9X{*`dcUPgyz((^oL?O~yF1^GU~Bbgox4qMhq`Z4i8^ zzDfSby76q`3#Va2MK4kT>zk#(vEDXu1N6YfB2z>n-6-U8L}7#l0OdYcy4p>YI`oHL zDCVGjDvz?+*diR2u^@+|g`pGsRdHKBokJiJvVLXb(~8DBH=VfQ4wjA15IaGmtqn>AfmFLMwj?BOu8{<~|6 zdA`jAbWP(|A`oqJK>B^L97 zyRHf1`*X;a3*k~my$>Ag85hTbkFB4nx6Hg~Xt)wLG;v~(^9Lsgft>lBj&QjkV6HYl zZLEXNf_m%Wr+~R|4;F@R%;o<1aac0swTV$g#+{H@t9# zNnA%s)lo&=J>(GX&j`=?f{ZK1o%O{C_od@}Ap!QE0e17XX@_;dl_^TlKaTF&N~UXN zb^=3+LtPp-uKaV+N+Y0@$j^cTiOg&+YUT>?$-Y(CT%ostoBWf^TXjfY824t8?_ zN~`yIy(7t@N9FnL*g~65(}%s7MeYl91Or(aDh*IggaGr8{lIj=c`f~U3=hEp5+SVm z*Aq|S>|1eANZn`BguI(N3*q3fz%m2OpFO~%E`HCfI3$5z_bcg1 zx#q@Pd=2$inn}|fYF^rp_`2gLq=~yb?>#=i+|v)GH^7!}2wJWD-=PrlR$)6i;7lou zwQZ_cy{{~EOo21qKH3|&In&XwB-)~If0Lk)cyh(E$D4d5{<)L~|IV~?z>-j&6phBS zuVVa17-M)7V_Wu17c>vP=HG`}FC|0?$gwAHX79{D%xW?#lc7&$hG4Il*Gt4}y#mfO zeYWfF&6#%UJPmInzy$W*$fmsesDt0o^5{+E!2g|TUwzM!G2DHpV;td=F2utXl^8iH zLT-17%|;qE@_iUaF6(^y9KLTO4VH8^LAk z)_+Ic%iuvzRGO5Eb?)05^tr5Cg-@ygt|n?c^X?|ToY`%}litGXZXxN)dK(`y%FI3 zg4GQYV~1w-Bwn8*cbQtfrd?sndKrSr?v;Lx#3OkSi8I+L(6Nr=x&CxVLt{=O7_B4m z$B)0-)mvJy1YgQj*D_-Nncc}rSilPcFk#t@g)@R#BJQWf3t*ytuZ#Nz6X>{(Uj&|< z`f99pZ7A@!4}5Jwc>_Y-|ie&n^Wy3W#4y1$Jfd;nfN9dqUi-T&@yWkPaz!SNE`yM?2Ci=B3#<}J75NJK7j z#(!)NkGflR%anb-T1WADHsV?ti^v_QIz{>)JrvM3g)12>2` z$NbVnw)Nz&?~1?~;+b3~-TjwNC~Kgd=gk>9ADo*Ye=_jy0kaM?+)X!D zM~A((%f3}|E{5nwuA`0LpWv=Iw6=Wh%HU7<+x@8B;3R&)6b{?Ie{>c;R(V-j@X{QD z*hX53xT#&`nAbcXc-PzTR88##I`gWv;ewya3+BENZHivDRG9a=55S?0=+vcT|&2(C?E35_*^3d+$|B0!US)2#TQ61rY=VET|;( zDn+^l0*Vw1MN~kPARt9WM5I{g-A3;ucSGRyyXV~Rugf_J56MF&v-6wTncdkL#)DC3 zy3#0Xe~*>ThO7ZgDvqTKB?G_Q5@$^TOIEJ0cUcNh74*C6zSTSABHJmY^6VUf9-$*Hfe;X-=6qQ^CxSl>4%Wtv9bZIEogHw6nJXFHvLcqK{B=h8?{ zg#W92PUiz6D%FoftX{mqt#m$8)Ls7ZV5ce{z0E1GyOwK!sZRSrA^5RUkSqpY~H-Ds*)5|&A7S+1(# zpN-BO9qOr3IokH!KaBCmM~UN=v_8PM=5U}fr;RmWGpOUL+LA3c;bW6)4Lx~YPTNyX z^e1ubaVT$8R?^P#4#Cgi!x_qK*VqZfL_72Aj|$n+fchHdkcxI@eU-86D4iOuVSWB8 zWye4MJv3EM61;G$i9U|oX%#!oPTYg26B!Nl-n7z1uH_vlH-GHM`FC!!a#!&yK? zMEyI0$MjZ+hi(1I(35_@+D+cXDekv3l##FD4*W%YKqD`qY4@(Cqv{#8U+IvDHJsd3 zs!aP)2K6M3x5^FiAh(oJLPUzlb%%z436mOB2uJaylD*Pro@WG19Y74Ebm$?KU-npl z%q%^KNn)d~oZ5*=IMS_4EMpWAuZM?LaQRhl`?#@D4tSgb`}?(JSRL4ED=sN$*7a0R z3M}rgo{t%ndLXZj>fZk==v96RvV*(llI?$C>*{{ja^NDZifJC_we0$9YtI2(BoxEq z%N-X<2KlpVff0-3?`r6Uwd>tr)9-CL(+RzjtXK&+4i>dI_PsElxWU7E_!i&O-p@Y{ zJfw~^*za{MS-klZ?7cBP#y54h;=&CNshFcci`<{PX3_I*3MKFw0r}*)o!XTTwbbiz zw{G0+&1@ZE^}_R&Z7A03On4W>Ig;TZSUxR8^BtT1#PY@j8?-(Umg7_78fKR5^U)!J z;b>?gPRx>VFExnjH`O?hk05WR#kKYbEXGy?$frT;{S-w$Yuu)Fm|)((T#_J)DqW4J zFd%ey4q7tAEH=F71vto9^uQXaqc8soL`h0LXFJdJYkWFux|W9R!woe1)40;TN+wHH zcc)JQ`6LEhsI8b=%myuRfqa5uubiOBCuo*ChQ=1rxspGMJLznCQECyU#*BMHRYT-5 zA-Bz%PB}nqyNHTaNuD0rIyAZwp~5E+Re$QZHmX^oU#%FqTV~sC-zB4HU{XmN=J?iv z@A-F17=TGF7n%&%F{wwA%3zmrJ?n=on zzWU!auGb4#5Yj(?TPUa;pASzP^bMK=p92C^3@s+8uFdJM=A^GI`+*Jry0)wS94$EK?$ zS+lv58mA9@3$YVFIa(K9ZmB_orYzGMy?WXt51iL2z0H_e60!BbvJmhb_*GmE?l`Za zit<9Tw!VZ$(k36vwKp~XUL9hmp)M}yHz~s%Oc7}bIn-{o&xgfYPrAHoGOhPe?kT+D z+;@=U`yoQ?(4jATTZQ|HorcvQY)c<@EZc9nKE}2j2Ew+-&3XzuVOzq}<`XXtl){9d zt^h(5%;Rt7qO&86kPMq8eU~AZ=sI%f@#OuJaOoP2^CNG&{aL-B`qe4I7oF>j@<+cj z!UxNC`(>v0Fy+nog0%ys{BZBA55KG>WVg7X;lB9w;}jftRK{cD?GR63u0yz(4U-x< zdY=k7jvlc*G|^8^MiWic`N{c|y;0_BlZC_8n7G4(I1RpMfBOFFNpJ2mPHXes^TbW! zT8}t`px4Va^>c>-=Oais7Pm2U z3KTw0C|&-weW(y2aZL4ac{iPCYXD;vzv0VP*`;c~WxBZ24|m%-rQ53sJ`Di;B>Jd$ z*Bl-87B5=^{Jcw8cck#61e47L{2T`Lzi^_AZ%1Tr2LOJ4fU46vonT)5x*&o%)`~R((Kh)uyi_e((QPN#@>o!Roj@6B3Lhom1UA`(Ao?;@Iw%+7x<_! z@8Uqnq(B4UV4gI_XY;q|vVj*B=P9V754+iLy8+<3dw)-lHWhtO*xSvKy!N~`J{-6ry|L1b6_Z^C95p4bAER)TVzd7} z;3#=Je-LM*{+3C4jCmf8%Ok!Zy>JFOP6@BMt==}o$21ZVXl+MSZ_8!=a49qF0Yl5^v8q5X~Vm(q6 zuqm=1e`lL<3nfB-&8TMRirO;oYTV(vdx5Xs@rqMArdrHQtJGyHv)P-omo*g+Z;BKW zlVOm-=NxZ}MX)t{6k7r;LNKY8(LBvNs<`sGv=TJEg5AdYe*m#WjYiNp_&D-wR{mA2 zLoMM$M1k_9ft0D9pL4$lLK~^Nc*R?icRU2fS=(Viha)|m^zKIBCU4;=phNtch_Qs>jGyYfu?nEG0q6vD0y>vp2c=T~LYCbXI*v`NB`}3qbR1=~u~m}T z#OgMQ*`D2tjT#=c^0)%^d0`WAPzd?UDvnnds877dsZ5IcxHNV40rmO3#ic1MRrV?G z4eL}r1e&I9lVtRPnz|CZ6h&zGr4z%BZQu9+H|!O7F<_0!+H!9^fK9}yyPqYmO?`xV zIB6-X9k##1<#UwT{J8e@^qtJupf4;VkKSyK^)6S4r^jCdt~g0vjBzNx6EqbZMu004 z7Q)eY0j{*4RX?QTK$SgkvBC0`V3N5#GHLqM3ifF9U8EK4w?FeE8CdjE*aFHh#VJFBd>q0ujqHNvztc1)I5Sh7Uez~^mM2|1S#Rg2NXxdQgHPpUlEeO zADst_XO0nmA(eU^hTjAdYB3{AXsmY;eV>2&dDy3|_{DjrOVO4>uwM|K)+Q@Cr{wJ3 zISKEkDOL{SK)LPW{H?u)ZJ52HCMOSv*NoX8WeIcW9iE+12!T9!?e8?eg+UM)Z zYfXms^@}#ltsr9{?tMDN3Arpg`2K1J@0>Bo9C^Q*XW_R1Zk-x8NLnSuDuZJS5ms(W zB54=!s7kd#7*q3u zsZ?1NLoo!R6<1a0?R*Izw;poO9X!+Tw9+%f1!*oRtx3U$$VbYDpZ4clf=0kCVPRX0 z*FU}RXwyZd@?hu!A4pFB*4RrfyFRVv2dJ#!YR@>cY%Nt8f8Yb=2Cb@0p;DM1c3TQi z$=%ZBPQ7u)r{~$mEGP72nLUiq1Vq33HteM61V(EmeT?}w{mRi|4<;6Y`>9wOZVby_SUDhftWIJkQp(9?zkMx``(JVPLWqUznR}YySD?qIWUDh4MKxbC-f4{tzSy9 zb(%ot^`7FpGPj^P+kC$Vhh67VasB&Q`Gj}humbdp6VGDP2@G?DmDh1J*tg)c>7W{o`B%nEosr7w|b>GSD9_g^~gt4^Xr?<1)#tjMAXcMQB*|bSd$G# zMq~H{(U2i-NJHKxH{}XFsMgm8`_%`)i@(*c3q&#fIxK2Szxb2(gLp<%Dl2BYTnA6f zqA9(b=XZTR=$4wBxc0C7ihIMQt5=PG^8!&^Q(dyyvHYW~@gMSmDAKp&xRnR}Yi`Xy zUgm@}x0$zJWDSvv6%5<=mzx7Bbz#|C67N45++H_9RiJQN=+g|T%@undz^}XcO8LOE z-F)jeLf!c$fUoQen8!RaWUMLk<&4w&%}hH4aWwxGPXCH=aBSntawxU0;b(a>NOx)c zQ*M0&^knwic3r=>)Krk)adkh$2epwNMk(K5;oF^E+KC$l+_ymPL63Rx*^5!vDhdq9 z!)3+u^Zrg;nAZCCV*nT~5#lrY{-0V5+}w9TCAj0HtE4$sAasVguhBpY6?#ABHi(;k z4`~y7i>QF%wi*hliUKMP6N;>Mju&%nL^LGa z6e)#(r554>RCHKM_w$TL_PWkWhktEE!?Mo_1|O zCNJ#xwu#)>GHWWUFd#EUy5t+lm*Tfq-ara6N1X*x8Zq90MnlY4j4MkTFq_ z<(mU!&aM{A4YMqq7r6O>5s*QEN|2JL$wrv?8K!ZcUphA|Zd(F3HV$iL5XNh% zr&hw8Hkx}@#TtIUQv*QR;!HyvEOCp&*n$T@`LAjO1Wn1Xphogv4_W}HFRcb}H z)YJW7tNu@%!&9W!5+8$!Czv0%-@TWh%#Rb!$j!s0Fw}2mTY}-{JsC~`={qnC3fdyc zIg`<>e2>-%pjmLcXVchf`bx7W#|AXLj9ta<({pAIWIG-Cma_SK#Sde78i2s;xfj>n zseu%wj2mPlrfi(GYs9Wx5i=-4a#S>^!_r4mwhd3*2}FWM9bKey-9Z4g+u@U@0BR?f zUd{zvyVsD-CN_<5{Yd(QMMo>JT(x>?Xhu1h%Wsaq`V3(D(gXO@zaQp~anZE^O#jU( zwWMI$ijX9aw?okN3f;s_d@;MmdEtOI0;dS3{3$=7)4-V3>`%OzdI2xGF~4@Kw!4`5 z3StRXF^}D75N~}>JJdEHyakewsHMw65+s^leM1vi{+PpdeESoK-;K_2gZV{4&2(2r z2XeBd?R_!v8)B>#9IO3Aj4Ab5sEZnu2oqifGMbAzEzbg)fE%L~NcRInKk>c{Gk`Qn zA4z7h1HP=T`h4mSc9wYCUm-&aZ!5FaAG}X3oPCMpUBI0LyojE}{BJh+p)d$T z!b(O0c37TyexSEwS~6_Fkf8L95=M!u29PSWM*1T6O^4}~&t86AyP)BN>i`MKgY4I* z5p!rcj%xr3FErBAC`hn7U;E0u2pOD*{tS5)$H-;2V1{7B^q?F3v19#!og2E6xquz6 zCFdpP-qP~RT^Un|VLA-N&HDTr;dVE2#@?8Gc>ZQo#2qTBB&uksse=yhI~wez=iNa8 zOMgj`-GzbIstTEwjMJLfOEA$ohTon0&%Htrga8myK7r0Lv~)-PW-uM$veR5MLP7Q) z(YUrw6k#6@V%hYAiTD*W+F763DfN;~J-~OEo0iV_#-Az|AM^v8o))mJHJD^T@noj? zy|`5}dAmG_$#732?xVk}&1+CNYapEbOgCVu`MuZl!!r;LT>;(bH>JaN28V;LLnTNW zTu9UTL;icQt&B=r(0SmTH@F|}D{5Ka7p{63@ zyzp0t;cN!LKvvzTS5;p% zNixG1U?6t?SP}&TOv7v9Hbuyc^af`rRyz8{r_1#}VR$i6iSx`l;AhlO@AgXi1&TL6Xex8vR3G-d4*A63s0j1} zNQd&B%uqnsM=QUhjd>MaCgRdsRU z=X2jAtT=}&7%Ojmu>{IkbsyK}vIF{(hUSD?4@Y&~)^@Fh;rYOfbLtg&tnli5eLG{7 zzLZiU+pm4d<(Lpu7y-NR^lsC+0nNSi!0!^lm-f4fORGxJMBJWT-EY*s4`}~{TDmzU zYR-)al5p_FaILdLERC3HE!yP-KBx{7hJ=&rz; zFDVSsG1M}@*jp5g!W7W=f+c`-y)&67F4lOnCOiVxxj0|uz>amMGTUmnb-xD?`Aq!# zTJQ4jwrw0Qr72VaNTZUGUA)N(h;SI9ElC$DBMhE?cLzk^!ldO^P8MS6H(^SDatpT7 zE`?uUaZA3?JmODxKbFSJ0ZeMFUHu|ElUhW_{6|YWUwq2e7vicv|D7}A6S|DRDlBZ9vM~FVKE-kyrK{S_?hSy0W{7hQ8HF#KrGBl z@0J3N$Z;R0%d;1PL~&aR;liu_d+B<|PnH;50>Ri7$IF-it{K{>ZW*BWCO#FZJ9^)k z{cDI%Mx*N>@hh?ED8ofFyJyFdKsb|4|fbb%a)YlH4-Pm6(FP(ht8dkj$rEL@8cS&nN1U2R6w$1Y%ON-(H@=QvvZCDDyH? z#2OUZG^iS}SW^*`0o(BdvqH$?x8UtN2gFaiB)0q)CeJP3=42-XmBBWK zw*98MlG_<~izkZvGR+%XbJLzOuRw8#Q(X_VS!xDGjPCc+Bv7+o;1@3?rVo7cJqq01A8ww6+`I3GQ{qcj%RJ_~U zjTc{GvONlDJs~{_;DpQR``b(cS`9*s5QP@ES#1kX5pv`GP#Jb&i{Nz3X=I+1B7#9y zcmP{wQXrM^NOA&)oGzXfy5(ropNzZ*P(Ye5*JPNTL<;DOk!NML##qN{U@(U|FTQ0c zDjigp_5%jAWuhJ8#$-wl`uWx2NLkd^HPVZ%0FuHr00DWHLfta} z0=Td;Vo@^n#BhZo1pKleo#WiiFj4ov00Q|@3J)W*%3B#Ma{&Z?-seG6 zARx8*_EupJ=H9y8GINq(iFU$06(Z^JRyy_!a4hX60*DAHS z^Of1Y*PGtBc;e-?Qamgk1kD$D-`(2@np2~vUeN)a%tbqrOh>|l&nH2nr2Orf7V=oV z-JsdLc>%M&_-*-butLsXssJ!nv(QTZS>^azzWc8zuJ~`sj<0|Mzig9CbRP3|A$}qb z82zwYO}i9&Ck&`|DR7U3C-^9T8zJSxX34qJq7tiz{s0Qgi<`^kc?v!y2gCpcNz%${ zyn=A=_m_KTS@m#*OC$hZrS*dr?ZUmSw6~G~c)d#+btw@HkI~oad^_oIbjgd=Ms7X^lzS<>vKTY6Lx_ImZ@ogl^8s-{=roM<0{5GrN2GqIB$LJ*3Z$Mr z0O?@-+En2A2&j_DtOttcK(Y`tj6{OOv@Q&Z+zSJ3!66*E**u49egxm$Y)tupxzH}JqK z62J#SRp4*jSFj2KLBceEoaNIKb;I#|?1IDOf8_%2mOZLx3nyWTDL67kJov`S5Y2EZ zjy;h4l{3Ku3BmZ;D&R-KB?0sSA%L#y#_&@F@)tM-?%{^00?i2wIpDJhhrnwH9K=Ms z20I8YS&-n#mqrh~B~1PbC1T3pOM#6d2olhJno1yvWD-D*9%MuLm{bb_dq23ufsO{` zk5Q$~fxCc9SKvRpLM#|b*fCc!n@ZsG7$A6?xGVh~aOo-u{so4Ca;d)K$W*2Q55WX- z5Akc@!{GQq&?SQ~3;vw*JpDFn@+h*K!&EB<$#Ulacug5<(FDK3FyMoL6AR(Iz!N4^ zR~*QS+*%zEb&$oWjavXWKy3Iz@ZnIQy6#K8R1q#59uR=!V1|bhm|zeK3^JwycR7&n zJPSq}w?Sq`*9?aTFMy%IkS}oLcmMC}ofmfBCBFp~fZIsQI4t-D8G-vrZV(9;13rw5 zg$D_*@g2j%9phiSzfa=_|8$IZ4bDz>P(B3GhEq{f?%TN_4;Qp^MgHEDtDV=#f02K7 z-UD!i;56X>wqjvh02ov(0G4aah&5(q@D}+SD?2PvJ0MZVB>S=^O;O7ik4eU^9MuA+ zX?A{W@*=t55J3z)Ou)@Mq<~z!DDUn)<5}R4D;;>~gL`&=hQYxP+*R=S|NVerH26e3 z&^3qv&wxL{&0h&afu_#zod*O*LO4F()2CMeWoq!7IKvL^^ugtgCUGp#u$aCXXy7~8 zA@c1Q?bifg5{61_fk{{PGKpjW#a~=HI1sbNZ=wW!e zHozYQq&ghJQLW<=$f8Le90bygAmjJ_BU$j=<_n&BjKR})9q{zO{%HTN?|?Ttf*iqf zHTZgufSh}FZ^Z*)|IeR5L12W)u>XJj1pfbiz!rH#f>ps2P51^g_+^R*ZDT;8(x82LP}k;;Ix7ZhM{@`{N_^LZRgyx+saLA_iZN1+ZBk%PDD~f+*pr@AKrHD8b|yD3e{>gHv71p3T3l zIk%Nks3Z^hZ3=BGX^;b5rV0;X(CM}1Bl7^7P=n`YHZufK!d5Z%W)-!#dgfk~kdSyZ z)epl>OVYI}QaNywB;q6B4i;33AI$8yZb!yHNreSlGWuv>(}^M?h)A(diKB3g5X2Al z2$Q3PkgnQ`5)-(=sn%aZB_{%DV*T;tC}G}OB=yDOUeez@C%qsWjo1iZ5@X|oOH1@r zAB;fcCi7*DpRycj^GA;lEJsRArF1r&KOuZmO3>U9>K7+)3Ri{hWRex8rPqP(p|3uc z51@b44$m{ZATt9(9;>H!#|}Ku+6{LT#++=P0cMz!*%MI0yyRYq=mT&DwA?}Q=wQgL4=s^QjNV4(pb(F1-v&K>Ml|} zT;t{7PCYeP2_u+>@GvmGCrbtZsj1hNE3fUFNc=uDfRxZ<$#DuPzgMT7&R8-^>tl}) z{VU-={bp(k-~-n27SQi0@t2OMOTu954}057V?MUPEIpty``g!s(++26nI%MBQHON?no2EsDmb`hy}|}?{0-s zJgoD}Sv41P?eWW7ChJpI=%#xkqqg=inWPMLs=aa8RHTE8rv&*uNgydI!Iu53rWoo5M%J+Q_43HToxr z4J%+UZ4ir0G;BwvDF|=B zdu`~GPL4&6R2vvyWO!pfJ+}YG1Ics5B8(g}h^?P#^qKDXy@estr4Nl%4RgoY4J*1i zXap1a;44v@o{uu-xYS|KkboN+1=Y^X`}|#NTV30moAjb?uGauJbhzyo2H$jX!eNmS zJGG^Xr}JYJ`J&Rg{QNnRUtQZ&3ZE4KW+49T%^MUmplErD-RoC`ue(;WNR`Z|O!bSf zh~Y7*rn5LUg)ZtI&idGIYUIqG=JXs_iyh8>5gVzHzontWfHMgKY3#;t{zUr*!v{G# zoTqp&(v=0TvUh<=3c`EhkGE%kUn+Pj@sj(7K6pMC=>5V|ets3Z4M~+yJ_5Mgcf0Chpoc zjbs6SmOJm;^TU3}lA3}gbJt?4w_?{uRDm5`^`6iapTIqzn))l`?r!rLce%s>>VYja z7!7ouKaS+z4Tf4y?axsYNs3y@>gEZ#d)I~9eh_Husw={WqOE05yBq`M^w!YkcK(lcMXmgXAD61?WoYO&N=|VE7 zV10Bn>4I?Lvn|^cE1TZ--3RA9K;$(#St$D_?E>cWV&vN2V^uym zLQ#*eLxCh0lCyr&S8CL5>$=KP<{zg3GaH3^-lw()A|VZRz>L%Y_bxM4y+6M);7~bb+hLZ7&Lll(`Bsj zgqF56rAkM_d2Ac6F*mIjI{NX_#b;q~>Dz8#=6N^ymNN4sAx|}mWLfmn3lvItT;!si z><-9P+q^#Z@QRrJb8@;lkCpW=a~;rL+ z^2E)mMWxxqAImwxRWrkgGvxsY==8IrAfP4si%I)Pa+FoWJoXQ3I z8-SUQou`{9%rHFUcjYoQ&*9{ED}M5mdu&0Kibrx&UqpURboK=~G4h%D`UqfVeEseg zSNHMet0`1pDa?!rBr``xrta)h7RQ~8bJvbaQyy{S{R7Ha_hHX*17>Lbxp$eFX|NC- zxe`^>S7|Y+aZ4pfsXvLeYDnpgsN$OlGBb=mJs)p?nKTbH>3o&nf>@O=r!XTlXc&H6 zdv|*`VJ&vL6fk2P|6pZS&u(y23I~`8=zh>ZVTS+6?Gc6*(|&p3dZFjXc&#D!EN-FA zZ5hB!Gntu6%L5|)fSIxN_N{CQC;8LX6W{ij(Wm&0kV4!Dp3atBMN!6Gx=@qZP5clu zKj-c1e=kqxPeuciV|#nGkdkCx=<6Y9!{e5ohI4%(*e1vxIz zKD-#VR(yesx?W^Gg||n<0Xz7xiQ}@2XqrwXpB8fLV$RpCS2ptd#7>b>r}7p3trPGz zvcA1FmF#rL#@cNV@CL6SEz|u`iH+RPyMwy82^t$i;Pkd!mnbJ>O#5TsZ~{SL{qHC4 z*d2?*nePgOPO<)S&G}JuM=Jumg2i&ux6q_0fXVb%KU1cP9aG7rFnf}I8|T5!r^jlTAw_5j zYl>@N8O3v$Q6yvuKhFxh9_g>$T7)+nAM!(igu>3<{z{RMDstE^!}}oBQ#EOo-2T#g zMAty}vBC!L#1MDSRP!eIy{EY+2QlY!o$eBq?T_cq5bU zrh~I0zL#u!{LeMbg2VY=?+SgxGS|0oFSuI$LEspm4Qv22eOdF)aUtOMG(V@}lXzo( zIiO@VEvIWG9Gyr9yn}Vk9Lm6r2R-|MJM2w!^g_=FkMR{VlQ#?s$k*3XG<>ryZjuKs zO6JCUMLVYHi(!{Zwp3jCEo#NJ%+LiOpIWqbEj#KwrNLR6Ap7?m5HR?}x!+ot`0;uB zgbc8yBHzV1cP56L_Xv{J+I_+$uOHOn?kuuCrhQ7t8D6+PCHX`8LN!3!Cl6Kn8i2NM z>(s>7&=YrPQZCIHKy4htP>zq^mADKUrrniz(Pqh<{j8>Mu6%#=(~GB3Ym?R%IM^?0 z2IO`eZ1MS{jPK56p>1jm5GPgMh~4BkeM=?j$JKJnzN6#rU~UjayT0}Xb3^%J;#R=1 zI_)I^!*9`0g&Gbbw0CI2eP50WlWU&BO18lY7ddQ@zdOtbieX9JwtL5$&V&A0tPj+v zVLayXjvA#$RjJoiv@c?=6W(u3@}>A3%lYsY`bR!A;h+++};RCbjKjJq|Q!cI!FG`L)v5^WHbF zi9x|23kY*aK$esk=}BY_4RZz25M&G1763NH>063q-}%-w|7JDqd+@Fl|loCoMcn{deTOfrQv7)A%>!E>n#rVR)6 zBM^{ZkuChypD=s~SVF)+BgStHVRv?%RVw}#f*c?zj!Tt`uisEbTaiiHXc_Lpu`aVE zkwFW&|B=YX@#s6vhnw!BO_MK$Z5FV+A(4-zuxSsZ1Cq}=|I%P|*~OwS^n4fJJml6X~BmF%6fFiYPOjT^L=bvJZasN8Tz?Rj2 zCTFR2?PDkPaiqs7YtS*3?0?@^YG(l@DM~JeVIj+H?vQ3)+-#6J;T z*paDyfTjGuZwo0b)z?>;UicJ^;rpe_lT3Sihb70P&R0>K8Q*sk47^feHGW4G;W~XQN7|v1tusllLE^OORyhJ{uYA2-k^=K4L(cwE684TSI4fRdez|=B98Zt*gLgld=Sj4Sxp=#`WqtUj4&+r%SuE@14 z+NLwZO2$mPW%@?jxIFJwjyCaS9rUn2y}>QX9jgD9VG$8YO>2GYC&-JUDSuWgrHw4% zz{)~5&#|A>J@S$Z313MM^p=hw?-aH>uU(29#oZb^1{Xf|yo-nNWE2yIjTgDX z?9(E}DXy4f9@T{J7VCV_AN5F$lW0kX7^jrjx-EjM;hXeHa%<6!)4#LYvtgDUF1^_E z9S7ch{gq#I11G@QLkHhE!f3hg_!OjrKeH}EHO;T2-fC>&nE_q@%Dg}IEVbdK@!f0z zndjXYJ-#?g`!W4hGZqh03D+$u^bT_@D6S z@K9E;MB{!&if!!t1x(_iF=K^>+uGf@+npKEMz_$RVdA@^QSQ0pyR{Nz{#?g2@R{4# zD-pijJSm=XJgT7Q-eK8)l;VAkJ<(!2gNs?zn#q@!sXT%Hs8zs(zX}V5T@)a1A-RhG zS}P#uy^OKgy!NQciXZsA9||2C(!e)-d`=tn@;^%ZWeA4+uN|sG-?Wsf)hENE3qIeI zkp4%h-TkP)(3>;3-bK`;i>3Ja@&jju)=~Hds29qUATK)wi%_u?Ucg*k@?h_}=|$sB zC)E#fqyI3o(-;p7R#xBU-#aXxzQL*@6{677(2QuHw@NOJF6j2ymiR}BHpIaTDGHjU zE@h9ocnGmxw@jj$N8r7oQ0TB6nNq$Wn>3)*ur$UIn0z{Cj?VBK3ski%g*>O>Y^x4s zM9S*3gH=wc8iZBO^j(zj&nN+!y0 zz4I62{B>qpPy_nK*$0a+d2AWUc8K62G(-w)kL$l%XW5Db zy}o}zx>tb0HVa289kgeXz7tjohd*P`KVF)B8%{_j`9s)_Z&xv_nY$2|(mAPne8Dp@ zX2na!HcaRa>yq-)m8H3{e>|ml(m`5)r(ELX=0hH_!IufA`8lBzwA1jb?VK2@B}MXn zpE&2*c`$Rz(w<6+?A=sj^hOqVqn#D}LmYYhqG-!Fw?-o_`>0 z-?aJcW9y4^T525`iV{_6ur*mGK=@VC57GoEd6HN7ib44~7{Vh_Q0dt~Gl|6Y}5 zrw8-u(%X9SK}T8|!cQmkBouUvb#nY;DBi{zqX`&#z4&56C`9r6nq?htI|K@KjgXFC zBr{Y+t^FM^#JGfD2uydN$)XZ(GX&eE>WNF--(uaE>zMxK4kzgM=~CoMNb`aGHe=Wrq``dU1HQbF5T9LqnB*3Vfb zBLPQ}i!WyLtMzU12g0pBkvWkl39S5z6UH&Y*+fFwSq@L-%3M;uWucz0+Tjw4}f`?+7Kp;{=1`BjBo zViacWS&lr~_iBJaPV~4($-Fsh(?2be{Csm;6KGNCmcUl=-yEp|wrY7D;8B z+`*adSEH_cCL%)@Z4R|WL?yF}|BZ*?Q4kz@;F+%dnSZYvDC>pey(LUWev3!5tPa}5 z(IgkNh>6qv8#*0f%c^!8U);ro>_wsc<0>55>Z>y#=@~Q-Z!II&)uT>9IaS&-+5Fln zf!-^!j;aiMNFZ^75Diq5ePi)tP?wb$IRkVB>;{8MG#2;0udI~ZH{z!*HRaM)O?;GG z(0mU;^N(Kpm^oAj=pA0@TM-)dsJyKnXTCt8XND!yi}f$QL#Fq0OBwRBWmyr1U}6+{ zIk&B-0)o17D1{fMg1wyXJ2A|U+!xMw4N^4Hk6}tl=K43okNXLJsx~Tx)wShMW8G?7 z?zPp&bs%slAV*s0n*b=25v3$B@YYTT^LTNLnDRlt<{ZX70<vwZN-t|kC-I9( zdiu;co+11L#Z7}WeJKEnm@O5^r`eU?JgK`+4_aF#L6GJG07bjjn>1$t3J}Rxk>2`8 z@-gZy#K7>(02FmT_ijx8XCdeeK3$Z_Fy4}Vi1j)#n536hK)4r6GWgG_n1DiBrQro-}WzVk7}iNn0&2$8@h|%!f6E z4m7j9dQW4pNayd zXWkxWY;!5)$FHuBY;bLJ9$=yhMoCxFQ^> zkY*X}U4tsQ*Z!G_3@YJnYhWgH)^(AoS3kFH+&yUR3w3Rhs2~Y7fQW^wKA{Vi6VUd@ z^6rMAO4oO^-sToi8@DjR@pr(G^2cjTd(A+t6Kpm)ghkF-mH~sr9SgXp*CM|q#FStphyF8WCBo<=t}8AzbnTdqBGR9fO6RE zh38%zxPKXq+HDti;ieHj+R~GyHRsVE9ocd*ey{02+~`;TsZL@5D6QqB07oYQ)3ilr3#a(SZiqK@8#z#;J zu)ZOop4zTckDf1l#xH&B^8FHqF9Ph@tN-GsgsGWV(RPUH?1n68U^v=gzk1ajGKe=w z`!WFb?n|^#WdmFOHD9O%dnM42k@ZA)83Ya}L6{eBIUy&tY2j*%o&GPDkIgFWEQlku zRaTod38Br889oS@#QdXVad4QGBgPJ)o{N3}Epx=+9Jw)f$&^+|mAPa}!i|^1041=q z`4npsVHnP+om&M}v}2dimm7~pUUitp4^w!G0o_!N2&{|<)yfpMhv;RzbiQ_2VN_3a zI^-*E2zZyer>EZW08h-9*adGE>fuwbv`md+`mM7uA~V&%RZHIXK)b&Z@G(fNI8F%I8%1`!6F zq9hH0JN^I;E$d7vm>Kd3KVZhZo`j#BU}iN;?3EkFD2kUEzH#B`ap2__XWhTtQ-8ueczo4wZ?V)0habt&UyUIT!x5)7=qmJ1sFhxvDDE?vl z0p)NW{;zV-uf=@Yx$R1_V{SomWp$LzMD*x3JR*(TM{Xh1KS;pv3Hd~cjjSBR;Iy#U z&N8XRQGfH8W9{z?s2-(RCEnNJD0lYj^!@ZtNb8KKW?>+t7~*|Ia1dYJbu}qHYFrXY z2ltt59VDAAQ*6P|4Xs;jb7}HE;vsxcpo6Y%_mRe^0)8Bar!w&#p;V$@h;NR~+~D)Q z?X*^R^n!6iUG(Jp&+q>mI=1Hl&9a4H=%$r)3GZs%vUMXq9D!Dn)VyjdExqLF}xv(@7G0g z&8S`-=9{|;LR{4!&FP>FgY2jLi@3y#O{Uiz9~MJ_w65FE+CV})%hFeMfrQGYvgd?6 zT<46!%ZufqU=#s{DRC=gEsETt9KMRD6VE^65EtW{`yg}PzO^gsT)0jO`#;F(x!pc_ z3qVd{<1(A-=KA0_PY=d1}%CzWk2E5tAb}n3}en@ zi@7Lu+z$o}on4nzuQM=o%O3+iH%OKZJE7_YPD0bnIBFcn#}g)pP`f?0Rh14VkNQFk z&m?{;`1rXMY<_=pA#{A=KfLiYXuutSD`~XkEdZ)$+4zgiE`#%`sNt1>6JRaxX6>nn z6LzvF>Buk-qW>IKqGKG0r!WDKI#i!x`qX!SoGzsl#}BV6+hdN-(qd<{j(FJ6?VIAv ze9EJkLKAvdb9fc_Nhiu0D3p&xOEid zCt$CNHL44hwbqiuBu406@l59(rv0F$2)XS+%AH4JnYsI9t(^M$3q6g}YpExG8Nd4v zYzwVt;J?ARnarf1F?~HEKWzUH!5MWTmKw*S0Z?GUES}8SYh!s2|jr3@U?M1fGKh~@(tQ(QM z4x?s0jj&pi@uh1W|Bag+kI$ULy&g#ar?mxUc-~`k=C#~4^4Uc_D8qy7f7>w*1Q#1o z1%Ed-USA0dH>)UVO-m{a81v76865EU<#x$KJJfD+z(SDyVHWyL)Pyag#RakMVW02t z3#SDB@x(K&)?W{Jg0GlK3af9cL|uN)^8|AJOY+2Jf`aY9_V60EscT=C##f;Q@!kP+ z46i1&=*M{knm_tpx4#M!^NJ_#?%%8Z@wZ&H!7)l_TKeqa+;82~v7?+RL8DUtfESim zdJ!x?R9B((VJTZF-@ock1X4raNLp~J`8eDlIQE@ht;-^MX2TOhs`X6o+pxtXB4Tb=CCM>%}V4B{wPXdskZtvM%lSC;SC# zdUAR}OoBzoHE(P*yklPI+jpryBXrOL$s6(|7u8-T2_c(27jT0=YSX`AgysYu)N}P@ zZ-wM*#Tmzoh948)xRB8W+H>lH^iZ&!-_3HILrN~3nlaN#F?cF*SonM4dDFV_|1`L^ zMh&qDhBJMoSlV@n#Cqd8*awA#5jb(YYr{5JLu{wruE~`k(gZ*6I^C7kgVQ+W5P|V4 z@_4?Y#ASA*#aUpthI{*I-?TdU^K2Y%HH|@Urf{)9`nNh>H~%xRo)w+9$!B)?p^c+6F()x!-*Twki;%xAYGuP77lq}8X|A$lqrG-1?TDGr~5 z+|R?n`PS5JW-mvoo}*;kU%i%O!B$1RF+QVx>W(Ra=X2Y>xv@_Qp?&90Mvq8V?ak|+ z0(D)NvYye+au3f8tArA`lT+Rtda*cjUco>rgWTpLNefXVT7>j*#@fS2U4>xRi(Ne+ zXa$;Ed+}-KocsOBtJ27BL1fvWjJs2V2I1D|eVU3>pWH%3)Qh6l&8wOA>Y!e&Cq(rY z)AME(dVX`ZAS~QC_9o-P|DZ&x;n6Dw!X|sH7W|El(13F+wI`7j0=HS6LV%pVcEMHU zsC$hJOBar4l-pV0I!FAWuE2s9pGWs^u!{Bi3G6N+T2x+l6MM|eQ$P8P<0xkbE|(7- zHRC+_dCckBVQF&zrU4HmucalUO(D^e>b|*wU7#YSeT(D)x7qr314ya6PQUjxjV?mV zm|o05kEQShDQ@ej1SUH!ljVRWQfqX-&&<98Z&(M}*lIN5^Nu<&zK-v=Qw@(NJh(B{ z=sC0SZ}1!xpB|6|5rz#`2yV$Ov?_$UG>!rrwj8+4<5WFP^-BQl@somw4s+y$->YkR zH(SlXdM&b=c;-UB)GNi$cLkohgb3`N;unn-IrdnD|HSD>O~F1M;V?dz$aaf~e|&wh zk6Aek_`(wnsJ@FDunBfnwy{I@BxlT5avk)w)#;f648!-|iXV&gMywOY|B*>KgmkyvA!9_f#B0!rQj7;= z4v|y>XUOx1l#q@5xPN#yjcKdwn|*5(pNx1};~6di1=mG#Hd21tho-Cme@HGd}IUC0dxqgz1A}{r{ zQwsbhghOimmIS6KI?LBXaP8LB`?OMjC#!X2YV(cL6+O}g>GS%d@JWQtaHwVLvKoqZ zU+KIDg_-TE5iLdFVa9jFN_f7~lZN2M^>Bc81ECI)-L*hMUme*U7T2I7zWG^C65iAo_SsoBPeC4qK&m_ITpyEFXaaYv*c&m{E z`}xb<8?_g%N|4+SrrJ=;pjhkwv*ft?7;o^Hf_tU^MwMz}ZTx3xy2eMVI232UeuX&4 zl)Xhdg!})FsraCnK94D$t9c~8j&SZ!=!;s%O9zb7kVBRKHG1*A=A0l zEAnpDlW!VdbC|#Y(o#uf;V^h?TJrxW_6(tPZePW>=N7^Ld3Wio%5S%d>i*9h=oVbF z$A3p4dq3mHmySJMYf=$0FGEm;-1WgsGY4r$+pkMz7=Y&z%{cw_kPD*n1pAg`G2d7F z9tw`Z3?XMc_M`ZHaCDx`oCB3`50rS5YQs3MxbvSGWs%E85AU@)M{e5YdVKl&D!X=B ztfk?PNzlu~>JQfZsRhK7%lxzC|Bh~oyIk$zb&!f`M?6GfylPWo;y&a<&Q0b=Z|Y1T zaN!q0u3lk#vEr{hb)-=rZ4i>a4cu@ zbU(R~j9On!^2W&gcW$5aOj!)ybwh7w$*)x9m1X?U$j>o^vgdk{hX89Ou12E9{z@Lc z#3qUw&MA)DI<<|9mn3In+ui6|ivLPY>Td|)^r&{iqfpI4yrCZ=V2x3#s)!$Bn_R1+ zpqX3py%RXy8^LWya0Jz1OqsfpvLv^9%H^1%tck^8vb<*X2p$Fee zshoj!nnKq3<{wAGEJz?F)SJEI?WvBML{3xP%wxZBK9kxq(%>>5NwC0i%4f-+2;eb) zxwrhcDx=6w#`S2Jay-KA{G7%I;mcn=mYbPcjmF0 zZs+^l1n&ePH~cC*c|PoVTN*NI*B_n|RW7*P+y(xZ`W|{W%X{JM4wk`;N?xS%;|6h6wn zeHclpPJEA*9^yKS8~Fq5sj8S#hq6 zLrFS3l9ZV@buTXG+dn}iA~fv!fuMR0hw;uo5V~w;Q(_B)OmQe6iZoEP<&KB&44l-- zoO2)*lBMV~_lzr}3@)Rz_QWaX;#(tT9#h=mK3>c+tjbgK9mij1MLqG;%3Vgf+dk`O zB_IB?qX_*(&0+;fdHbC}yfvMP#>->Av?JV~W&?hF(Jce{!>#s6u)WpVyvX|_+7)b`_!KzvPXU>7FmfAEqOPr6^O_;BUVL7d=ll6OFbtt_#d zYW6SMakBSDCwD~3@~c>SHgd0NjbGz)MKuFYE6ab3E&sbCw5AllixHC88u`9BROu$! zbPy|vs;gt8#pzP)Nkw1&X+&I}>Ba7IPhg^n+M1OIZW)Lwht@y- zefO0lj1Ry>DYwmv@~*Qivvb{1R9E~?=Np-GGe??oBxxFwhQGJIx)S{9lRAd1VDohB zAz8o|O$q(6#lUjsT3wde&Ajb@rZn#5qV)0!em6sf*r88_@7lr7wmI&{Z8`+>>LXbE zA}gX40Y0)EI9sB*sfTQw*X^czJ}EQW!(Vu8%)Gow3#8ruB0k;8oc&(@+O|XLNv4^5 zHTh%xvbpJU+ka9zvzB!43!{TPb)Rr~bkBhH*Y>RlS&lE(9pS_kc-Y-jaT3*DuW|{> zmMV6Z&ILW9i$C%pY)Y#v@r-iWEPm$ya)tdAVCLO}XayhMAL&`b)g98ML6*IK?gh`oe z7RU3uTtWJ{B&_7tu%{#Pdti10wx5pY+OVwFPVkF>E30ow51Ok5J+Md0dEDcOD-Un_EVge@-5`d}XLEyrOM<4K3I(ZfW9^Nqcg80Nu#n9iBm;dL|% z0x3mP1=fIG*@urP+&ta+QHqc}x_eoHUfEuSbq>)dwH}g`;QvntH_|NCD&9SY9o=b5 zt`yM5sP4;soN`zxEABdX8(;y%Sy@S)L5C9=)_efT4Bx$n26dbG7LMc0_q#r#35g zYAGxL;(_*Fb$mEVq?HSry7Wi&CNJwgcS-4cW(d1+PyU%g=L-kit&(rU7|wE^qY2^f z5m|dA9Lu>|n{?PE3q6&}O>W9eYsNeB-Un2}qLx1==HL0HnsLjV{V{C&E~`9H@py4W z79pX3JnY)rj!o*MB{QPQH(RqemizYpqtxV=tWf=;8cxGi{tSbY0#x5MA&-Q7CPS&hQaD9o$g!4~3a-PTHZ+!}NP;`;qMlQb-0Zsb1V5L=Qgp zx%8Pg!;y6ymxZE|V*Xyw&ZDzdp4D&p*MDE25qwC`!25CaZzIXapfM(ew97u!0)1vi zGrLoV*KV9OkZt1qxPUJYVz18kHc-w?GeoNddih)+NrWAGE$I)J&0V zHW>Jx`FC{J(lh2?yby(Vzn9y>K&n0ky<6jrxI!bn>v;9pxb@lD!y>pF3Lh=rl4iR* z+O|UD9C0Odc%i%S=1PU47W!`J%t*SZ_SP&NpV zC%8yK0*oo0^ymn~gBf4U9Jy|I&e;ahOkD@aT!=Vp{f*iYCA2y#Kc@1heduG|T5QG4 zz2*JJo?(40y{bU@6Gh0*2+SjFDtF!qTu~vmnLSu1Fo+D={ZA3D$z(A`zfgmVyp+R- z+@%li{8Cv_gD-52595K?ixqxi_d(P*m{EZ_n?HLSa{9{Ux>y{>Bm0BG#bx6Xnj*2a zzat(mh{l5zJNe6kSlTlQ#rI7P=M64V{1Z={hh6FGdtK1*bTm#?37K5bri!!|N-foX z43Nnjc$P~RT?O0EM^O5&HDhq3A{$b01iO0OMyMVc-;cy2KTYqy{y>G#mx->i38{`D ziOR{ZMQ9dnj>Zp7ymy4U!JAp|(>+!@MbeHNXd&p;+?p_M+Ak7ZkM*B7j(5Cg7CsZ< zB(H;A`D9Mu|GTYnTT1F@6YMrc0(vbm?`kjIuGiWz(iP|)AJ7=TqV$d5Cyxf*s)gQX zIQ(j$zXDdBpDLTHul@OqkZwqHIvQRzN-CrDZIz5bV4X*<&Sp$ z6Himg$NoSjJ-9)F92t})IW;iId zw(6*5oGnZb;#q z!!{nlwWoL|S&iTE&r!}7Ij;zeNx99g^{h1L_N;9GV~74D;}a}9@p3fKvztrBgnPoU zM%dVaI1D6%rm~+wp3y&HQD4(&{A)27Go{WxE@&7g09#|s3U96S_vr9F@i~8Ht8_VO z=_*83wBxdLD}Ekbe(%_m`k&9amM+?_s{~qKHf-SOosl19xFVlJeK7fhG{HK+&GU~| z;XVdr&SOVQgk@fsVg8!=HfW9zMS$`bF?9|~{1N!=WV+0@mSCIu+I#0%?$lYI%UeCm z1iHMo|G2s4`r$$n;HEoHjvES&+`>E4tczEL4=rG>Qe&TC!Dp)$-ngQ&RW{rME%|KY^SLp6$!<)_iA*(!leFP_X$7d+sOsn@qGH{2|_elX?tRr z(i0DTVdoR4d3K)!=3sH}4lof&Y>xVh#_tK$X()fJJxShW+FbTr$p#6^42=ILuXH{l z@HCP>#o2zE9iiqB`3l zYHb&&JMV4sAi$N)k1vLc_5Z1dL&Oxb;qYxTQH&tRuBF)!quNJ#$Xj zfM%bk@Od8!8dvnLI)E_2YOqZjNeU9HKSxDTVx@i+B;=JOPzor4In!bFuJtGG4}YL{ z_Gmxish0=sf7IP8u^A6ID)6j&`i?op@xU}8>V=QA?e&vB8s)w*Lu;Honub9PAW zlg{fp8!mURd1pUG6G*HugHiP}keKyeGl7870D`SL=s64k6vH52_)ZB&W2j9Q@w30P-Hz&|LQX5()+=)1PpMygcj3neL*OS{H=l{a5$r7-_H$Ie7+ z=WcM0%hUN>^81e~6Kc61-~*gU0!Zx=_8c!dy>3;wNU*De^u_x|cqE;vSz?H-#o$*# z33>RY52h5FqmCQW%LY_TqYHIxE6%-tDm=V@eTF1Oo%a9EPr1pt7M$OUmQih#4iVA~ zUvmD;F-DaR0_%lH7p8)O!1UU zoG@%KyxcTMoWnBq{^%2(TKu{`GoptNR=|a#mfxwlN%F^QgMC2bc!H();+q?4ROdx@ zm^k`wpnMiKOtgN@9sQ?&LgjZIaY8{cW|m(-zB+B(Q0+T~Ff?}r0G(SAz(HI)cfL$0 z(-kGWlVxlH)oL4TY+z)xyr2bBLMB=gdAWeXOk8V?#lVb#FpwZt4y1GbSgXMZFd^L!V!LIphs zQ|j(9yzI_?)5lo=uSDwdFa;0L8l*96Fy@# zf$Rw}Jq^%=#FoJQljdy+qUbiBukjtl?NtGY zoH^1G?@N!~?GhAsep3B`Rl8(w$q`l{rffNKSd&BOnB%xlDrE5;a}OmSa$GOFnoEqK z1>}|hIfi(CZsX)yK<=U6?m^A=$3gPZH=Y#QCl_GD>MxG7U#W~*UkxmCjh1yjwtlO3 z22*wO%63>X5K;dHe)^w4L}q_fxzdT&3Y_`d2B@K_1Ace{E;eWgy6IP`HVxUVwwKCF z`ixipa9>b|lJ_PNKEQIQ!Y1&6TTW;%5L6v2{typxP!~}aWg&TWFmo0Tvui}=5d$a?duS|2sSi&d`RBPUQ3_%&3uaTR4PdOAi_zEQcQ!cso$jmyV}+qsk>w)T zfcp&ZnmaJo{2d#UvDtFx(J2<6vyg~P^R6vT+VX7Eu`mjNU5nta`1r;MHcfx}fPfzlNTWVQE6%TpqmIisjVSS!688Qm%hRm1w^{On_-xLr$ z7jJ>&2|#Q^a~oS`e&N0s&V4G8#g$+x2{`>_82c|-{Cu%3_Nc4J-ZLae+3tEhw@)Kt z64}<`xjC<__IM0HGTi7sR(C0}fpkacQI_qjM zqYV7QW!Ts^z< zn2UhfSo4_3WvJT(OGGF@km>9*_+c3!BDETPU(rSa5E@#-^RkCMdv*Q}K7P>VbCykqwBE^%>z=k8(4|HP2q zC#;9=sJ-;fa>lX{M3pjh|lDJFsKPstIA< zBU-tYE_l4l_(BcC+vl22+(TE%hr1mP7vW#yIAIPufLi~8O-F9Xa< z3y2DqS2KUSMGHF-XRF@$vRJJ&iXpA{f#FVOOLX|eymz}1=YZr55KVDEt-fqWl>@7o zLR6zdts81WKWin!j>8UyHS7&QD5#IR4#Ex}WESIqo~l%B|MVx`zAemz*OG?O5bR zAHD~|BQ)__7>}u&8YjRzJnZg9GN-FWp8l{Qs_9}NYPes`*cqdRnJ+!m0n3JNg=>1# zssrDgoBaI!gDav{w~r<%b?`0J8pZRLcQB7uS1+6|>&I3=GwTP-_PXkDqP7sTDAnb9 zWesEg=e=Ps#hdzX_K8&^Ke3%wj#WfTXcq2A1a0QUG+sLVjCA$!IS*C!=Hg|R6Js5l z9jw*iN($3hHToAZ;VysoHy_tOOPIu+);daTVKOlI3!^SSsRV>F!7)l_u2hqGH3_jg z4%65W+__Xw-s|=Eb;7t1*8(IJ@Pe{if$iF1<@!PfSk_fU7rcEDE2;TOk+B^&I~4Ol zsKA&)O^4~$Zr68={oJTTj3zIRo#==R5Ld()i)P$K_o_QE5u!EEAqg!zYSy$WXXAS+ zo1}x{xC*`hJ&3<0g~&z5#?X6mev3_+{1nMdjtA|2E9(4Wn1PK6$UaI6Wb4DFd*zZ~ z+5#bnS8p=g(B^@dAE?hKm7>I-QL~zw3S$~DA*l55!K=%U-ba~hm;R1>ANzEfrEY5R zv^c46MRmp?ymvy^yU~CI%ttjCON^k2c zZ5KOy1r6)y=hBVyz&*rOI^rrX0H3zA0=tP&gWjmX0zZ<5F_g25DdK4B3%=~IN-O`Gk(N9G8RW87mwCP ze__ii3I~iKA083;7*=JWwcbZ2W<`yy$HI5yXG&0=k8FezWz_A$#x)F@9ZcBV0tvrO_! zq6)z=E+k=RJ)Obe`tDa0Gpp_^hxr$8OxxMEXpS##6^l0c3w9AfuC8~bzkSFszjNpW z^joz+H1SC$n7Pr!Ftm`J(b)T`O@@GBNG3+}DdO#*y6pEJhueaCvh zy*!gC-ID|3n?bap9As;A9rG^##_*Fi%HIUW%9%+a*|%bS=5NcVCK3=yUo^PFP}9;Yps^i7I^7 za&yfGs=&X=Z&T%&hTIfiIXptDu?GZTY3b3Zd3`xoeMFGkvntVF`eLD&t>KeX%0!lw zwCO#g;K9E(luXDRrWP67F&rTB$}oRLA>5D@*pOK9xlhM7)Fjw_fB(Hc{II3+CCt|k ztmJ`fN8=Vu`&;&Ck1dVd>;#{pe_CTx3?BrElI1*TnMas>!S zw~yR%vOjRl2^T#Rs_WpUU*s80U6Mt*_aLTY*!o_R%wG(Q&*k@Xfu_;^AokkNE%19^ z+6FXD+j^1UMANKNQkIH=ri~veF|Mu75?qWl^2MZG8^HpaPgtBiv;1(qN`|QLC%JiF z--iWagyD7VNtaQ85F0-H#``azOJrEQPmUnfMYZIO&C3^LG+Yvae?zw1#5?hC&*P*v z-5%MYy7t6{*eBbOwoKdm=t{-6vEMP^v^;(g_u%GKkcy~gxZ;Db{L4EwONNe^L)j5kWn10P^vS` z!k0)zvca{`hqv>5t5-2x`J#ZA*X;sZ65YjB;Vxjc0=u(+Ll$#Y39hs zru#=ocoued*7!iW3#BGbG_$iw<-GMI{g;;%J}_z7tn}YAr7xSvd%aH=U(&4Scg=zW zdp~F)yATjv#^>S>4ot4|_w=9R3&HcF^maHnu-Uy(LH3z;|akFA5306^ahsPTaOzWn;Pmo)F=J` z^hnw4yy6o!HqLwLoCj<)Y_8swS4u;M?OOO^kj?1&(X)Nntvq)J6z`^WJ5(hdXAhu)H75$RuiighklT(9tMvomGxL#)cpZe;9l?DF{?tsPlHVh zDU9qFL(G>=uJj zNfX(|*>XM-t~EIt>fhf|-!Gwb<0c>K3_2Jo((?H2hpTQfK7Z5KF6gfE_kvVW@MtEb zcLzRyoNr+*bogf0iNbwtlPjqJ3fFv4BEnAlRcCgVHn0e@$T3E`ri5J+`PlnHOLrq| zXPx|q{K1{cfCQWI7iX$uF*z72abuJt1I?B7Q@jM~L*De7XM$9tcj}YRg~y{Gm1YC3 zDxK`xj=9p8maiIh(IVZgLF&WXTuA~yTvcE=keh)n$Pa<%D2)PZt@itPxZiZz6aSpz zs|}0?oR3IRDVS!=4ViDZP4?>kcBeas`JcO0ulCC3S!n*{9Iv|Z1fbp(HN0m})ccb+ zj!B24=olsD25DayuksBk^E*qJo0#Rw#~{Fd+L->t1I(+8ZnoD|UDM~%4z8AFf>+T& zIM6e4)AN48lYwRLj!VxTmlZNDTXMJcg%#f|43z12R>B(UBwg6?xn(8e1>`QhVsZ|} zWaD#xrX$MadfAL24U0a(+;0=*#lrbfup zNWgL77n|1oAJ9+j@?#>4_S$j^2lMRdDo6rj9V9u*p5@1jLqu*U^tg;g0FkVW0We3o8K_)p?YM7YJ)rBph$FJ$sU+sJHlzZtC4$#BPyd+SzMxS8RJ(q12H?GCX!V z7q-nfR^+nq%SJ16U`koRKHn_!BaTL4LpxX<%j>DF0keNm+lXiWEQ*TD1tgi>PzNal zhbG;=2^d(k5Zo|07E3`8ex+H5nlxd^xKPq?P^04;-MObtH{{ zuAl(uG!`zcf1%f$dBP^m*wlx<1XfCJ?gXj5F4>s1|3~X}I4jQiQ(DdsjQY+W<+k-< zXw#jrs44f*d){MqQ+Lsoi87*^iT60T;D%w}p&2 ziIGo+9=X7NkjW%gvJ?0|%FK4}1HmoLB8kF6hCX~`b+j90(N*(h#X7JaU_qw>`3Gd< zZOO$y91}xp5_l|*erHEqo!iZ)40&9?Use42Wsvxu&*`%i_tH0yrRj3zs!1;cdl-Hg zofj{%4sU-!O?R~bys0kSyLDGUbriu}5jOgep zr*AXaiykxQC-RSAjN{cdd>TWue_B5v+WsKe+wAk?a)R|VZ7`J%V#@@by1&^I`+DS# z204HR5UJyd)FSn$1YX8SlVo~Y70Gl^31bDwe$}ADmZmG|{0lQi?7-6A)LXO{fld~b zMi2$%-83ZmEVj>He|&=yg-p8iG}}M9ez%9GM~$(7a?1=|JpYfzP?^eNG@wy|)Pq0f zXPzWtdEUK*`Lo4;nDx0Idxctr<4(6Hvv@!#Nqn=1y*hpvv$g2<>fyED{VyIhNJPFR z7gAH6V+_y)<(}&Rh!=G13-raLm|az$ioOu?MjgkWBb{I~t3LHVjeD&ng!2q&0p{op zlfb)P57eF1^m~~6UgWx*VG!Y*DA+WwkVW(}O;B=;3EDfe)f81bp0S2ABykJhx9#!A z@An9eu=vBc>1Nu9(G% zIM@AmuwzXoA=WJ98ZLD1O#FbS|BdK0oby@fa$gBE$+4DnH%rR39Po7?P0bur-ASlD z)e>cgY3GHgq40+h^2R?L5iWjz6nw$>DqKhEq-KEYX(l;8ouXVUhZ9Qpin(uP_X27c zwjUoZzkjS}GelO~*R$|h7UhayH=xKA6EgbjZGarR1{DkebOqeAJkF?@sj584K#1bg zH}4WQn|@KI!G1pW!kRy)`66nODeJdM_o*@hZKKkr{VXyjvmmOOS#3U?`PxLVWZTvy zc2YcrX{{VHhCgL4{H;OKETtb~&tic~A%mT`d+`0Mcmerom%qhBA^!5R*s#a)6La!@ zxKb=~cmkZVNLNZVL@{`ltMDZj4$XI?9->vn(;1Up@;a=4m!T1rs54_87PtfGH(#s} z-6_ZL_zJf6PrdfIVx2v`GOjTaPmnnZj`{f`bQZ(c3RHmdpP^FsNz)=NT|hp9%i1sw z@{ww_EMf$47@(CaTQUQGC+l_GUlo`UU*k?-ftz%+2j~Q9oVnFEO3=N}DedqJcmw87 zoJt^1(6(F zO(FP-ziCJ(s^V(o@_Tc@cTicj?1r)BlO);gd{RnR+7oOZ{Vl04=|JR<- z)z_IOyRtHmnQ+|?Rsd^=^L^gS$E@92OOenAtTkXJ@EyE_IZgLpCSx#*Fm}jU!3lR@ z_LNkv5L`BwI2ZNoo!3cY3u6i`(qB1b-S_AAyNl+lU9;ccX-YuY`P;%a5Qqu8t)jBU}@!^N;&$P=% zicH}Mt7pdwTb=d>$B&Wg7nNby^N^Rs0U1Y;>;SGyZ>eY(tFYAF8W2039vng6VO2$T z$x`AKzv>=Zt{yER-w%qgxU@GLD?(hV`3W!c>pcH-e(lbTh+p{nH8R%&sm3qXD_*W< z(TJe56H3WB=~zm+jw|8sbcg~HWS#>`NY|xLd&iW9R#0CPjp6*Z0t1y==iYQaQ#rJ? zuB!NHU-^^~6e_?iSS1!l);7bwhZ?@8;z2W6t{e2!Pj4|lk-MOLHTCuDc*N;4+Umgk z>qtf}UF|Tx$B#(~qe6W%u{_1Lm=2n?N@h+XjIVKp_e2;TfV*uZeFmqEai`zHs3M*Y{Ks-iq| zdR%C&{l$FLPT?G|EXiAQcuF2)%G^;4Sz1;iR6?c9&+xLjf6g)405bWHI?^_8kN@EQ ziF@mvPEe=d1V_{3InRN?dHUQE20-Rz24kE} zK9-D=eGJW}`Y73^$68VGB)la|cZ2o2ySMw)+E0Ohl9K+M7a@l9KORoa2jKYWVWBrN!bQF)XUe|055E z{y-t(xD}Rq>M^f=vLKc3ecC*o1SX57PCqgnXqS5^y_H-O`1ER06UU4@B5UMOCEiq` zz z(-c)e_gB+1!dGAOPS2p`pWxuieH&5$>G3w>R!`k0AU(cYcs*Jq6yI-pv=y~Lc$Er~ zl%hk7^64Q8Y`IDg-odzuJ zBxprHGvJ^akjdMTRLp)_`$zqZj(|xl;hv?C$~&llKd3;(=xRxf^~O;;-Ejtqs79ti z0gwr7jhjjRPD^powh>E4&Sh}6pA(Q_KPNrWWx*s-iFAi^k}!;)T~bl-fmWPN0(QWN zDz@*tygJYY{{le=6={DVhGkjwcK<%M)G~(83tDpXX{(h5 zqkZLZ({d2Nl#q>&(knx-rlbSQ(VM(KW{qJaOa8%r9f1(5)rO4E6T+{{ft=XL)gR_T z1Cb30yXEO_EbD6xj!(~cnF|vvKUs+5W7U0dcv{b*p5k_T3sk|qhx3o>BLnt=HZrij zW4CwuV+TS3s|qq<#2+X{otrTX1ZAZZY<*)%TxB!8Opcu zZ?}ed%3U?E`m*OGDxp4==hmMdF-?97WyN0OT~rqlDjb@doGl}{0`qY z@~!^4Tkw=HWIoEpwEgcTp^$qR5W&br$yA!Tf(OH?=`g|P04o-rMA03!D1qy!Mfb@p z=&|cPigvB)p%|z9{REK;HR@WxvtJ+2?8ub`FDhNEe|XKrh2r*8wLg=tD#eERqXB1> zA7~nqkfxyjJ|Kk1`W%2Bw45svyNscsV4YDQgh7X6ZUb}XtXOrssOixc!z8hWOn}c6 z5q{O=lU>KH`UvBMx_UwO0O`Id_j+O?mRnt_F;#hKZ~Z4H=0&f5^%RFj)+LoBb0l_I zF2ED2Kfx1H=*0gL1-P<}!)2zmfCm)6A_82E<~kx|B96IQY?1~YNF{(Pc{R4Q5?P97 zY7{Aq1`25g>Eud|Fd7xDx-K;b?-;SLTN{>DDq1x8?g3Ag^0dW?bjHztAKoEm9)5tQ zAp+dHXOB2yG^X_dPd+1$80POY1D-4{=-wNQVcMNT#=NG$zEMo{RnQ*4 z|3>{f@5OU$%AA-$x+_0I5gPm(3GUKVvXS=`44=BdF@H~vIK(3qP&pq$J)ALdfnsvX z5PNcJj|JyFnXncVrPnzGs7xXw;bL}sy3d~L0xEmv7=B-{w|rmHU`J4oBUOQuJqTa; z2NGc{AQbv|iQ;aAo{}L+{8`K?Vk8k;o<|Iz52NstlOr0mH3kdkOM3XVPEUw0ac!iP*u zdGLBeufAMixF3yHpgu<2p$^Jg7kVy8m7|WAB+3V7`Wthx2DG(Y*l8&U3`oH_hq#hM z)VUaQh;QQCm9rD8sRBx3QWzgwu8uBpiSPX!`Ob_KN9-aU>||!Qc4HVbH-Cw+smew2 zG3R!nPwR2iOPjxx0hK$k%CA28Pyv9-qUHRSlg&%9CO&{=U0F}>}8T{+1n^Jty z)oxHJ-1(4lex;Hydl@($nZS~6#5F?q_W}+I7aEEM<}r9grdLMz(SITJ z=KL~qg)F&U7aBfkCn;6qMe=X}$3rn3;5?ojnrYSiRVO&<>xHioW3& z4)b1W^T_?HOAHDngfvIYMDrH|G|-6C3Hj<)!MtQZW0iM7kI|ZpPoV`DYn?dJ!oEpZ z8U{%kS3#qeDxe`hEH$c&al3(sa$hrd0P?p#{Nn!EspIF-?%o^D+J@2lpP_q|t3Dic3- zJFOoz;;#5T>_V9V)IkRO3LF4A!kL2jheGIf*Q`?vnT_ag!XgR>{dCYr_$hD2QOFL? ze%d;$P;;f{1qeq~#NJ<*%OShUQw9M}5G2u}zIIqn5-y&h1pQgs*wfmT8lP?2vc3r2 zdMXcq2ItKQ?kdeo%+>hq9}e&S(p$7PyBIP*%ubv zG;x6;i|(yy3GAd4rDXl*pPyqR?);5Hm13t}j_ zAI+NlF&!X=QWCvX8QNXdg%)O}fV9I{9`UCTLs7)v0S`AwyyO)m=RW)WI+UTQF%ZM2 z!E+=sKwiqyXjbAuQTQEq%i*3y9J$|%P)^(M)H+PPFb6A`4ul}|b?MQq&xD|0-O*II zfAYcy~ivP6g=pdiF+Nd-U%^mcFzwM zbb_DHQ;M1&6Sm}jI;}@EQqNf~i7W~QY3Yk2&R)Vn;EjuTCJIM&kKM;SCzU|)m^2+| z>fk|mS-@kNb)=`qCj_Dw=vxt<978%GaF%qOvBNv=CCMM0Ar34yHvSyZYkx1OmEj3r zV(`W7ud=HzMrS#|H5~5#Discne_k9}PQ@wSo+2Hp&b#ibBQ+5*WiYmkGBzQAQ4^e z(LA3+4*c%O8%A>+y}%M6U5g*7I=l}XHJG6(24@_%mJ)2iFiFVvJ0Q}qkGDzRrn)(L zi;+cs8?#-xQD)z2a}9Ocbb*_3MeL=e5ATDYkx`-|YS&nSfAOfZC&XSx49U zlN7}IG%Fh^=y3DUV3QbLX*~H~g|-+jndkz?w%D|wsWr7mGG@sPj;+sQa9-*RI5yeP z32p*|!0(6RVivmDPK9js4*ha;`-zpEr6eG??iHC->Qc=1w4D7LNyasd)jt{(AvXE&#WX~aHV_Qh>_(~CpB9e9YPJhtGH=>=?w(+ zz%&Xn!0o|TMuOvvcY!yk4>z%CExo+q<0R`;{q^9fe*XjSZ>f05$mx{ zSt{)pv!U_(EE8xG8SxmK-y_B<*JrD9PxJy+53|I_aNm>BqF0$<$!wYF3E=yVSEOUv z@#ouv7V+pltUV~t$gSO+Jon(?VPi>KBOWo~G`B8^7Z{1$Ol@2A;#D1Uf#r*5_UpGib$r3PQhF+F>1a}$?nZHWhaf0>p z(j8xXjHm(Z5>7Din%y9f17yva)Xnx8V=b-m#}~+YRKm<=zZ5HLr0O-x*WF{Bm}OFi z=!MU(UWmeYH`+jCH5LEcjIAWf&m!61q8^|8m$Cbm6$!Hup}JcyRv*GRh)$lTH?^+2 z0Cz$YLj!s>5ZXFNslc6>N6{zAe#E+yP#wFZ^P;6q;B`ut`IDjUi3p4?D-wiM8}^Q$ z;##i4g$-0Feg$a%)WkD=!2HJP(Ii_dss?r1mx^mFdaew(-E`Q%Q0GqE>^s?Z;CAI2 zE~z67v2K@?$6Y;v$z;0nD~wU^L3sqVJ&xL~#uaQdZKC@MX&tEBNs336;5c?op?3GG z%kOtr%q^Evs1sosr;ls8(CbL>_qixb$=AWW+8ReG;P2C-l44K(zF8wK?!2f+GtwTe zm^l!QDDB0K$$e^v>*e}>b19jlE~BY7mpmD@%6#Sq(^~QyMy(OiJGE0H?8;Loxpl{c zrUDSB3Ev6$ZC^gan3FGz3+?u;5BzGN1tGMrbQ3k$Hte*Q?;!ugV6PCBaIVT9PZURH z?~_-uCdWkXis-0~nZNj*hF(hrPud0fp>aWHXSia`NlGOM`JCycAeE=AwY3<%Uuwj@ zB)BfxS@{`!O|aKRL(FA1UAwhJObvd5+A}2mZ#x_odIiw?r(GyMZN;ipV15@l&9(b$ z<=VRWZDf|Q&A9vdvjjm5$Bhd-YRHbUFF; zvNc9A@ayAq@QQ5FcYXo;;^5cK+4xCMeqB5=g6a6zEAVsGZjg`pohzX6on5Y^oNKZk z`}(Mnv=`CwL4JgJKqh5PibhO`0-C!tLRI@fhW&3oHU70^AvpLVu?nuA-xhnboUjK! zzwXs>eDFuV8gl_aa_FA6gM6LAYFpnEx-bb)$=|5;xWwvL+fU$gkpdo8AQW%-9{fo2T?r<}fr9XK z;<3Zl&I^#?Rt*1m%P!-fb-oKr#;0s!^O%gehF&ZnV~(C=>M;8qqW?VE6~FinF6|Y&heN6eB8AjWZ=3T40;J8gc5YHE~vC3K4faG4kkr>owD|e zm6YjK*x-KBk$!RQwhH@cH;+Po!SfPEEn`m85t4STP)|Gqs=Szs^r?0K8qY z>tt7De@|xmiWDPMK!ifeiGk3#Npn@$Qin{Ac`Z{uR$?f`km3h%K`(Mn&RjOeA6M}- zt$1CDITWyPBYeu+Ew0PYYF`krfI(<4ov@(#IpH>70fkA#AKLyM-#u9YgN6YTF*yTh ze4LuuJI{9^l!P=)pWTh!5&7!sC!D!$(B*1n>qval20aKIOu*}J1`6$S)?_VD8 z!B%9bNSHne<`D%coTh*AoukkTKfVYoQimyq!Hv%?y&V}U|EH@HiMU;=2& zNDw`Xt0;9MYuu%m`QV^TIWJ^71;_i{*yqDK3-K_?;WM-GsP5lo_%eaQPq!ExW#tG8#^stW#Q}owyKY6JT5vi^M ze=S$oseFKwj!5up2L4*LF<$h>1X*wL&zw5+(<#;;&RccUae3-NIhG(WRG|L z3y_Fku(Z;NMB2?n9My8F>5n!UbbgNW=tVU!K^C=`F=RCn2*qvq(bWmA&R1ZPBqB32 z&sb_d?LmF}a`1E_WOK_4egBvnCydaaCD;ax%*T7b?^jGpi$(tgjMy{|3Y{==Q8ObX)DNiyW;E& zZBi+%-c|2ld>0( z4+bE}6fOXdL4wAUEzd+1mbWZrDpf-`D!Y3+zw4}J0bD6R)OUFlNBGihcJ6m4MJ$yL z!AekC8emmjlEI&9c#|dsY>;yUzvaXR1ABj8e2d?{!+*c((S455+UM09m|hKe)-efd zY`te+sckJxk8FkA!o@$6sQl;3J3#~(+~t92tekAVzT^EH>!(l5+3z_SRuhe^31Ads(_eB&DT9Nu@g!5J5sPXi%gCq(xY|yAh;A1OXL6xJyqe~>qTUVn!ct-!q+F_ z-uIT8T`=24PG2a6o2h|>YDWH_P8wet=i%1ZNGq~jREcTl;9!A-i8z=m<~kh0`ZwbV zIbI@8cVriX198FElxIQ6;h|n!brgF4r>>i%PMdUb=r3vi{3>*h39m@Pp=I0yjRhf4$>$I|Eb?7>b z9o#b!g1Z5%N^mcOYGbZJXN3Bds4nCOZ7hTSlK5V(2o(4u(6z~EAV6Wys|ATmjrsx= zaD$^-wTr+wz(Wl{C+M->zzn-$1b#fk1KtCAtc$QsVAX)96PLknhRHyIm|X}O@VpCr zAG%LGV<~tD8G~C!Km)3)HW*_NLJR|N3aSKQYMBlB%r&nKgJou3Uc*7V^z{4c;j|7e2g(pzF z5(7||N>LQ215Bu37vPtQfu|D5$z{2pi&d4MZqYMg-o)r~!TxKX`70 zq9f{e9r%r|IN%{Cy2U$jh6i|pz%1ZI(ZSjM?HY+$2Nn}h0jNPmhBP)y9)c8r63BwD z(Lr4V3mPb+4m_IpM#jVmJ_9~Sih5uKu7SV*ef&RHm{2dtfVWLZ6Hb5(9VP_$VGUl? z4PJ;$@DdO#;!PHBfq+P*z~@gw!eRv#)dHd)E2=&VpuYr)fMfv@>V2mVP+UMi0$2a% z+S$9$t^gUFx0DAj!9Y47bkYo+zzM-iM&QbA%9pb7jg9f0<+-2xWNUxLcV^ZOc7rzU zr+;zt6aEmi76g?2F1T=ZRS(6=|M}ze1G4e~;#5Ds=xPo~H2}B&(=XUV>GJ~UOAnPo zxri%99(8cYjsSLggJ5u|f#|xR;31$B1N=vB0hK{zS(Qe*QTIFf-z+10%m~2SzKYg?1K{w&>gG}tVP2WY4xvA?++}ueO&xcz%N-B zZO~9s0&m2`fDpLoZtgxwXZ_y2@lP*IoHc#NUY*<_)WH5Ih5EIya3Ez_sSFkXhsds| z_$+|PKp_jh1$F~^PYdq0Nx_{9s`dN-=imR|i----!Ulq_0ZrmG8T zy63L$_^A-^)lCK$ArC%)x{+I40v}pC5%(TKjoo6zh0_a0SPyQ3rxxg|1{s4OC{vH1 zw%7*$d5y3i9E1M^1>X0-KO~0j*~|2&FRL5joF>8%E}XsWdG<2X*{9F)QwM?P(KsBkCt)pj zFL`IKri7*ko^${wX0v0O1MS3INlcps-WWy$FU%_0&xGzT#r|Qs^kF$($|I0)_!`@z z_?3?T72%{mhO2_5Cr&Hb8v>5M6#_)5UM)+%_r{i+Jgu}w!4~@ZE|`@WIee?+k+PmN z2P|M#W@IBtLC?w*zQ6OptbByr!OBS{bAA!_#&p-~_3jfI+~W`EjW4P4<4Kxi|HxY% z)r<;!Ykq6Zq4XD)UYNNrjr(jDc%L0}z$`0mrvlV)c#4Q_{D^1t_e4=c)yaApP0fwM z%gb@JV<+_mu=}chmNZ&5dPqZYWQ6w^=sNQK#r*EB=7+T#1ib5lKd?Rpr}0PTc~*P6 zc^}Hu56hrB0fMT?4>5rTfDOU#yJpiME<&47qG7QKLnf5%Cuk6Ex)vlxSb|Rbh_rT2-f*PGFOuA3odjkp{D-R`l ziTv)M7ub8IQd=UXY$l-z`8788jxKCT2Y{%IvH`{ZX;g-{|7uwNz{Dn!pZHe(BmoD> z=LN{_yCHrmFDl>Xr1Yz11D@y4%+DTrEe!{+;o&q#@6voDtFr~<@Nwk0PRmtLcsxxH z1cFhf#NXEK6!OG6U;u*Qz0B)}7K|{o`UMDP7s-xe*0d%r+9R0?6|DV01cH^Yj}xsb zhJWycB(?k4JTuYQhA1Jm4btzZ|r4Npf(v6Rfj^BL^t`F=ucx#`%FB z>u&sMKh(+szXC0!LP+j;`SJPe|2SifqF4%bZ%XDVsJJ0Z8#~9hPy=$ zQ3uRQ)ay254f5sr{gJulKc0VOr$^4zWoFsrUDNnUTWq#5V;!59bUxpTAOm zFHU-vCXnTcfPDpr^in_ft*x;oroTLC1A67#`IjE8R|6f&TVRwNOLxN5c$TUv*X%G{ z4|~%VP(h{)!k#GRMmkpyggEvW1x&o|Ydv%0()B&l)NwI+M4K}I%Am~QKIZ*FjmHcr zP1R7_c&_i$0!gT|tJ|U_@sJCrU(3>N8+ieztE5zIaJvaFW4Txs#U?6q&003M9SooigJw2E9X#hYZdyfSgz~x#6 z8h{XozNGYR`~4<7qmfQxlq%^ujmi__{H8SW_s*1;wQ5zxVIk@Dg(Q(5-@TcY`sd!8 zyz_VKMlp%8u|L#5XWUH+#iWYP@6>1}4R#HpnbZI)xnfO!{f!;QtxvuSsPnTEb;D6O zHuSD{5Md7yC@(bdCs@IKrqj9YM%;a zMmT!((Imu*2@jm|Xbn5;U1{b)T{9ljNL(k#q`5qG1IuEjfes^wPlJsYx8q>zP6Kp+ zYqXzk=d8=!6+hYR8E!0!pObbUhnwH9T=5DMeH(ecF45)XhibKx?%3{kwtj*UhS=mt`Y>*&% z_ZnDpMb$n(aMdP0B9bA869oJI=$=;zfEm>zu@Qa9VhdsVYI#iN74+e+Z!<~M`lf6O z10jtHEt`j;^XhvI9VQ9^Nay`qwlV4IPV-RoM;` zx1iV5!{V3BG8v|X@Ss=69FUpfv(>6$i#!(GZtl}{y*)+;&mt|WvA@ZfvuDaLUQt66 zFw{wA)q+lk`oa8afvXBp1jfWDqIvA)6;pZ_N{9|S2>Ex<8U~{Jq`ABJ&f3I}up21g z(Vu*4hU>qx!zR8-!>CUxp6Oe7B$D|(I;(T?%;-+x|^xB&U|nqI0Qo+ zyZ{N1m=@Ag^zm?Y*jkH>{jQPAUdfCOG|VjnF_F6e{avo8$S(V@nS02?$M?Vhz4|qX z-fk+Cb-QdU@gJIB)LKgI%3 ziXHcZ9L>4A$8YC=Vjp|GcnPx9g+t0F14C0HG6&Fyr7O6bw~773nDq-bE^jQr$P+ z6v+7-6Sk4+(Z8B5W6MN>DiKEoAnw*0L7JYaI*SNBaWTmV3M(x=#HInIiw~t?4V&|} z90^Hya?Gc(H?2nzA8@MMZgKA03*X>f+2HEdrv||UEw{mmQ-8upwRzSfo>pYR%MyOk zWS?)c`z0XfKpJY`00|pf+JXFUtF(#tM!Z^1=lnA?$!%w>yTc@sQX1#sIB=i=o zZ(1@RDy*vfZYbhN3+!DhYwJjpio2SnOYmZe+13qYAPKe_djXtru+xs+yMJk3HroW+ zIs`cPZ5TE3f$sx6YA%Blk&pWHIAe(o$B^8tE)f| zcM(B#f@ky4HfhSu)Z|Gt-OHqY`I3t}!}4PrAP+`00uSrTb-N<4|KRAgr8bzK*a|J| zdm+6-#()odYt$^)HJaWo1}2YL!$V;kP5dyQA5ojAN~t+k?TdTF@h{kJzdUepBkNA) ztJbTOHJ88g%xxrGgU+U{`aCNCHuyPi7B8oiCSMFI(kRla{_WYN2^Gm|RV7>du6XdlzV1Cy7 zyAbTo8%i^wX&l?%6|%h350MWIqe8cE}*&!nLPhLv1WZH;+i|q?l)NRq-c` zX5J}ca7ZK(ym?MihqNG>SuXas6~jJ6;!NEWH*mNgss$uHJ3*18I+;2INHW+-cl4%A zkmHY_o9RN9Je z3{1Bqo{d)-2cQ=^P-!6k*`9({OKwGS-S0;W4Oaav0)!V-{l})|)$rWQOWPTy5Ca{1dl$iKG>qxni$Z-us*|a@Cs=fUuO4WWvhJ z>pyY=Qw(5H$I?g=8`Q|fl)pl=G=m5{pfWQ`%4e+jJeW`1kmfnJ8e}b4r7^*K1sBzx zjZkJe1S|DTm-4unUA1MpxiK`W>NW2pXR|8XXsiL8YYx>QxUtPACE27%hQ zFs5EustH-t;frAc>HmhUtZmsZM=)&FkSf?)@Aq6*e-!pW9rK07~ zC#p{dsSA|39!}X85hgJ$8O~M9G9$M!EsUiHrZ zH)vfyeG0bA#U}n^_yutTPrltJ`fE2-I_b4ppX3W{kdK&{m@y{~C@Mk)zr;Ui8)HE= zhGlWGb#gEJq5S1RpQy9ayY z;Jbl_vg1RVsLu~w^&BpggTj1Zx;3H?#a%cC;pf&NB?=D0S)hA~#!RXOJb5Bdc_w~J zZ&!Q*P714H?*RZ~LOk!n%KUTdw91r^=x=>vO74%He7=|JCqiZ=SC%uIHqRmNl0K^i zko(6EY1e%9IvfNo%0TBiOd~kc0_Z%)bw}{$HNeWF{(3w(-pyHhpV$Ym?URYfl8R(~ zj*HGzXUoz21uA#1fJ>RZzZ>#233spD*sd%O%xXK=y{-iMhH6c?@cyc$48uKR=|1+F z2hf5Tf)#N``k@S%raTOUq?$B{_j0^QuvsF%;30ZrF|s^2Bug)^7_9f#GMzO>ZB_j# zD8bX_C$+8PW^8O)me8IixwM}4-z1gsVxDaVOj7+IYo6Q#UocCms2rog0QLa-Ar7>h z`t1S-O3PJ{)P!Ax<)F0^H|Fojdmv=(t=Yu|YU+L}<7Ni!b;Zu`AaC?f! zd9AW6aHRa49&1&7S;=qko`XnhnH^Q;mp`)J-TT%_0}3dPBq4sn0YO5yw<_#Gl@4`>aN zdINPThRG@;$ax#ugC>dHpO2ydHzmg}ELst{mqSvcuZ%w#u@!f`TUT5s$L)P0W@?VJ$O8;CG zKQ*mGSiG8yTfR4O3)Cj8vesg41n-7pn%C3Nd?IcF6O{c_?Z%QiFsK#MTm9Uj?>qc)+k)9{@yGfsiLaZh|_5>vs?TR zhr(n(Y14HPBF-G^Lv8IG+3MPN2X(Z`hzFQ}a|*m4g#qV8%DpJCH5tDcv=GK(IN%o` z?_bxKZ6l%imtv4S(?Cm2&>mO=8?wu}|!uP~MD<{u3ji~Nin z7J4vAbH$wSSEGrfl%bK`Alt?xnPqVPge&V}N`et5PU=`aHvA!xq{N2il>ct`m}HAw zyzIi}>B2H*hOsEkew<^$%fIyV8y_kPrrS50Nifd&hTZ1%bDS#h>+u`uC&Q^^)@^hQ zx1*=6*5lo5h64~Cqtp@QXW^( zK5Xy!UU_J6qPQ<9ChKYI2f6^gx6|0_8XnxyA{6tyZQ@BG0XH@`jR&tfqviswt;)5( z$O5Ikm|B*VrUIJmr(H|3YJ8rD1|NPbVF78AHTKS70%?z&@KYCfFC3V{QZVeLq4?hz z&az~F7XNZ%XV@vNJRViyxy#MJG{q)p6TqS9>(zVtpR_}^x!SNY0`Sz0lbg*t`KKR* zJ4qGzHd9SJ+Rd73Oh$^3wfCi{lw{vl9MQoM^l~Q`bmi z!@FY`0ib0%OIv0zKA1<#j!pUOerc?fez;Aku^EZ%H530Hu9#dX8w7%QAdnFA#)XH= z;TPM2VUe0cSt|7_+S_u?+e`cZ#tB!O)cylR8oLMPT6;@+d6>qH2n^%76RFG+DJ%J~ zQP7A@3sdH!5lVqkG72F3^894|4Tddp+KV9XZD_T=@0k1VPYNF^Rt#L z;(N(zR*%17S6}7zsT)8>sTV#RLZi2nEEi056D~3E+tiTA9UmPR84eB#&;S|rvG?_& zM&t~Tkp-Sbd%AKgcf+>VQHiXhe{_d6>Dj@voJZ`eiK(i1_`Yk`^wL$Dcn^N*6FRSj ziqcjnjm?3`iHp-?PNN9C>;*{^6@xU^vT!T;q*wLGeesX(?Abs@_*bf0fsDp}0U2H1 zwPxKP*Tm|8GLSeEj*(>}Hl$}2P0a$iP18~h@eYhO3+_?qH!bhC>hlQv56;7&0DdEH zyjXv!SIVu9te?V>3YD+w6MugF@gQ&dw1$Wd&GAz(qt>k&`g(tL`t-o7^9{xfj1+P- z{UoDr@v(}|Zw(#&R4)3u!1+Ya$1+GwFTU>8nx&@|Rr=wfNkm&QSp^vTQ$2a*#MJst zq@VLS`(O84*q9cQ3CypyZ^cw7ZG&y;ke!GdqSRkthI^}x4duf6LZ2x$v7%rNNRnHN zCKP+)Oj~NFHLH|An73((W|MDu+kYrZ3FyyjBlN;`gD<7;eN7^4P27CRJ)b zDb87pM48-95aa89Oh(BEdC_tLE{~Y;ABs*pbxGOwRxLIl%g&Y5dKxn?zI1a{OSOfZ z_uWs|OuvKu!}4^ zki;P@jq>5Q7)-3`x-Kr+yT%vxyRO*s?hRacn#*dt36{>=Pw99{^ZbtWym&Gnn2`0i zO-nexev4qLa;WKW{3%gDsEPTzn=H1kzBw%;rzqcY`@5A$0hn zQ_ge8Mf3@|pLF5XF*Qs7zG-*~?u`j8t(^FXQ`V(-FSp2ele6EI81=FeXqBY05&WE4q@ zazt+dNwzzN{@y${J?G6Z!?;iP+eL$HbavBeb#R!EP9s^$I}RV+x{{-reDs}oZ600? zyU6I&D!%_Zg{9c>R7$v=YpysUF{K~c*2^|M*mg#eu>92y4h705E5!wYl%|T_z^H(f zHcvkAY5Z!hph*k5i^YV4fEhWI4Vr|G$XfW3qc#$>&>IOemsQ2P$LR4`+=p&AThGe* zF9~b0ajoGnyiRqQLXBKUMnj(rdc5aSuX-y5S*P;DbMGeQ*7Iu7MN|u-M()qDgJ6^+ zye>@u=dks-K0-vT1IjCNLe6wYpT+;BC<%n-n?Jo4f$5$8)@bCjTPEvHBv;kOE}TUD zo47sD2}Pddw@Mm8evHJX8*L3SWut8tT$ta-69EH%oifnI{J0M=@bx}pfHx1{iQF1F zVBlv^m7zYqm?oQ)(_|dxNwk!>ZMR3d!=ss0W7J@HulOYVe?y93BVLht%gy5%7)u2{PU84e5o@#| z_#tkzg71G<-u8dF@xr9oI=h*w3hjejz;b@u43uxliv~L(Zf|4^3nqyCX^plnSka6B1id3o0@ydy&m4hnjmk$=y3gnm@t>Z-Of85OflEW(wza0n>O+H zV%6};*Xwd9oL$WCy`e!U9G8x26H+EW3ZHma^1o;t!p_&opYL1pcfl+>CHSeC8Q??% z9J^ro;cKO?{@f5ZbaCQ$!{@_)kuzn5u7sJ-{Nyb&)h_W2!U0sx-xI)*mkJ_31rmX8 zz^sX!zOz0wd};+s-R_iI1#RitXb@$Qh)$!}r6e5;>4Yi!^TpVY~1zSrtt4VED9s+8t$b zzzL)&dVOVAg!OOuSM4NU39oCHyQRK^>LrTqPB)c-x^W;YjG0mc_~fSt@O7XTB>qQ? z4J1zHS+gU{k)5UL$8URa zzH^Oy@16U}z!5|$FO0>+ZZN54O&!`ubJ{dUt4>c@U;ozOJ}p4$T>Z}G%?dI#6 z)}tsBU~Ts6iQ$2Qe%qp79~59@98(U-m}4_v;5wa9JNMVVT@VW*k2A*&8y&;)5qcfy ztM_;6aN@0sbUBbb+cM@bE9NAJ-Rh9$L)Kt4yPoF#eaNXH#ezWUQ^}V!H;fQw z?(~XM6+(KRiUjUKq;k*WPJ4F|x~}$Tic88e9x{=K4>1SD?&t?vxk)Wc)NR$S0&Zy* z`4B1gQe$xB5)}%|qXn-w{+ZZHrCay;DYw?~Lr=LSMyTCQns>d{18{5R3WbCYvmd%Q z21juAc(Q_Uo6qC*re*3aCDNkVB%&XWUMjjp16BiOnUUhlgNESn*VS}H&jqa8yl6+; zd+i-+9h^QsOa|E+C_j-<-L0neRP+qkcdT$riiSosuw={|;Bh-P>`h&yXX(zd+KhJf zS%NXL$bIHNp<0(0B-UI4Vp}}pCAzk9Hvm24#(~qSYu90cRuS?w;0ShVSf`r^Li7o< zRDE6ns4~=Aozi0n6d6RKjhV6nqlW&{k?KGoBm#Xn8M^S?1^1sWZ}5o3^?A=`yp%Qm zFkACol?|uSwdnZkj7?r*0vIqc6>2rUJ`^~v6z-M>HYzlNhDSjy7pC3l9A`doMgt8{ z!O~|l1>XFwGzt9aEx+%N+hYqbnErZU8kN^{w=lEF-MT?>>SGgu!LmFGNA>(LaT@9q2IlNK za+9yOU6K09?$uCk$o7Z=5&wc9NJq!-EcnYt!&^hL_$gf@4)0ZX$mm}V<4<=kkR#!n zL;X)`f!XZ*A*bZr$PXW5li7e-v4v&x)#)*l!}Lc==AQYYVo94_ovT zO>4jf)`n?pt3$c;wbi(pmFSu6otdk0|F1`xU+?|g+Y%ljY2r!4O+Ln%E6(k4N6E)9 z$>Z1ufn6z#cn5Dfrg~#6k=tksbFL&=bGa~r+HlSq8dH=4^jre;kjg7{XzYCjQ}tsA ztI}0Mkk!u*?OnSSO?E5i&-lwdK5&iYw35d8@SH_ti!rGpLF#WBs6;GPv~iJ8g?1tX zQXp*m&P!JcW^PT<5&Zxu`o=0mIWYmD5l9Nbu^0*g>yqDUKk9eY4WbZazXs) zh1PAllRQUZb57S!a{`~~cFQnTFV_hpjoiM@#*Uzrz?RpmktrW0g)=dMfUheqQf(eY zUP2V;xt3d_x>ed&t*5epi8Bi6M$JjcdX(%Dp+pG{BC&gAK3V6`aMRo z5g?rJH+mEW;@}1-;pAMCBkHcU0K&nEf{cyDe;nV0$;h4UqsOGuom4rhIxJKV#PUXO z?Y_aha@l0#T0Zu^`OPok;BEX47 zV0Yo`D3Hr3oaTST&WzeQ<{fUx!(DYVxHQ_v7xUTeYqoK|%5R^vqfGTSiI@epD$&|1 zatC`Wkw4`%_47blXluFtNcxUBFmD4_PM&-LKGcF26ShGSZt#O2Id`#SFneVbIs{|? zWy-RR1W?@2M=}XSQ{W$j-9Ay5<`0(6mDXb@+?93)BXlIY@8@+rOT_qzi*QD9Of*Z2 z-TeV5;}vodd0iBQ$4w5l>hA$%yNQJJN9ie63W~D>Wn*aY;a);_sKAgQyX=?2a5}?v zew<{wLlqxXid66vcT1KYP*-K)m?udH{Bs;AAf3gN7j$-H-FnX^=Vk6eQT5Em=HMoubFn2;4_&(n#Flvc;|7y;YS~hwMp_XxK`R5{h61eqHScY+Gb|ZR z%1rT%Yd22$*hH#$``=nMM!%Uk)7F)u(J<8U=bYioLiL*hib&ttOn0Oy%G!}Vf7$7m zi|sn%Wdk?(Mx#$Fq5cIQvc$m1K-CkO`GmvUNB;#Tb-)U-d2omm?V?kQp z5Pbz`?qU1cE~q<`ej*#`O`Y_X#VlUx4;V&xdTo67)Nt)N(8{3O9Gz`zaY0tQ%k@iu z{mZxNitibZ&xtsU@AmZ1#TNMqh)^1&DW>%321Ky6>fLgs$#AXpInK097@fGZ>@Z-5O8s;4ZVFDY)AV%ljrsxo=ra zCx+$qvPfNC^YGxDg04zQ(EuO@6a`s7XeKFYjsOL(Wf3tbrK$||b@?Y~L&{0ay&aK4 zh_jU9=oj9x!(;?8i@;u-^74&)%c5~`kF9!A_)8r>shQDP;B?BUOVn`qePTn8`rJuj zZQbRN;oI#81MAIoL-|a2*5^Y*xoP>tT|Nr#5mleDZ?F`mgL5Z(Ru$`4^?D=+4>*0x z#&IOFIj=#y)`yfMl+Y!c%8<^^K6ReW{UA<1{L?;z9Bw(2J=(&gp?a^VDEcH@kB2Ct ze(wFxcL4~>?=*g zJNi!Au-+5GSNs&2{~~NTVFBqn`c*s_Zy80eXHe}vQkVYo08E$#zmdaW!eqPZMX<^& z4qw@Q9cQTaQf}q%-H_u~Ti)|Fr6TyBk5MJzozxlV#ZcUmCWBwS=l5&%`%(dh(LT+0 zPV&3|HsAW?n~`tdMO`d&B(1D1o>Np1Vp z?SbsvnR7clWV9E;;%Pro($~qL-O6>O_F`)+IWj%TaE-Y1EyxDhhj)4140He{lEY-8 zBcycvgo;52qAzjCBjfVB!*nY3r|FZty1KTZB0oCVeJNXxegwB)K02Sg4i(2#$#d1# zmVbv8F+Zg=DCqjbd!e6EJKO~?Ndp|cDhirw%#jxb^9lujubCoso)>2%Hxy!p6CW=J z8bqFYu~Rgj9!>=n3tz~^E1brfebbz+#r}s;wyn)K$Zlgl;apaaXE(?c{9Hw~>32-n zB$NeB07fZe+Dkq9$EZvlzl!70b-<_t-HB^5;##=NHm9SnU$nWt^bRJ~ul4D)k1r8> zrLhq@L+6~rZg;)IWxGFd7`#m36T=f`Ue5h^?)`WZWijPM2;h_(e^0R58K;b*Li#Q> zSW0Nan6ULSn0uSG{zZT^g_~E)BJipF^JZ-Y5&~Syv?2^!&q3IKi0og{XU*dn@)6G<_n(HAVaR>qnY{rT= zl}-l;*llg)YD2)SHZ-sh7eSRAbv6H9^sy_p%YsJ=e;c0Nm5skM?_(6qA^vMm-%fQM^%|N5oN0K=ur$%~p#kO)pRn3ekuOH;JX^!PE=L2KKar~@B26189+vmG8 zDB^;d0jn>Yg)bG#{p+;uNptenNvxuP^+A&P@_tKVnzcu~$A1Q^U#fk(U|ogiNk>Nn zPQJ6T5`sI}%6X}u-Ok9>WfJf!*#CQ&4&Ybz$xRcciy>qwjXvT)DEN9t7az*tZgTrg zp>4{Wgh}0p?Pj4X=@%mh3$<%T-n1<=oU8EQ^GA~O(Q~CPo_GZPG#DWV6%nFl4c~aC zBrd)MOXZj;<#0DAP8?8rlMTBnm%91V(waOaw1O#wpm2TrvlhqcgIs|k+7-V?b5iGY zvAlrDy;rR^b1+@9kCSok+{CwwN*zZiy-4C~`LiV<346OG&zF|_NPRAf?r0JON;<2H zSH1yF9@~;8hg%thC6W+Jvk*Y{;S$h?O&g~lm*#%sXQF%SDC3*&G5;|BmX*&bMW(Z_ z8@VHtO&)cwYR+?&fzq0ICOWJY0n<5HU1KGrJ8ovRoh*HPbv?iqll?r1{;NT3_XT;2 zP~j*4ipcO}2rpz!FafjMtUX>$fg|;q&(a%}6A5=0#1{3msk-G}f8+i8{k56)_S%06 z*I7@WZ+=TmLE<`1mY}0q0ROT6B=OI}S2C#-DhEK}W-<()c>#qx*#Qd2q^1;tMOCOA4FDcE-uJc;Vq^J%L=F`I47D(UUjMXM47<_EPbF5iNHWxm0E(t&-La zE7y{256WOqjoQ+I%Od9I%={C$ECfh>>H?`JJfwWHY!9K~;rc_v?U&-C=55^_as@4v zr{-;g`rWcqe_?@m2N9ot!u*Gq?$L;A=TJvq);m(Qa~0g%of9wxC~oaBN~{+siY+6q zGYz7kOgeU+j{>O46Itp7T28{h^~nR2koe&fvP->o8&NRmkRN;zjNukb6bQ>*q>QO#kGk$`=*3hPnFdW)a>KNb|jS7_V_OmXI_^8&tSf6IrFUb7u{r8t!>4 z&8(0ad8|_*pf-H33)9ch`fGo9>!TsLvzq!bWz=;9&K4O9k2XuLORg<6yfli|qBv*Z z*cW@katTmPON8@+orrhz=hJKS_3$90b;`*j=R zT=k9aneb{-|4&2t)hFs5WjR93KAShvALAd~ z;%qg;l^exy)OGt@K{|yl-)_bd5E-b?!cKlI?(X7(t(XI&w%MEiu}u{YN2`1sbkX&( z)s37b*sqZl_TqIWqdU?@2cxJ!L{5vh^fiM}OwaJ&MOr%AO|J*biF6Eiz6V_VrSWSh z&76DsKmXQ=+LObXH|`d;R{pbUx`VFcC>Eu~{d1#!FCtWr{WeQhoI?mT@_WN3662Xm zf$A?W>^_vi@aCjnS??FJOWR6ij#(#bYrho#c(0WgNzva1az3uPh*SOBV9~RdGYYN8%0$vNP9o0Xcc-yLSU0nl(qZ~VRAubT+JNko)Jw)2C zmtr#Tg3h34c6Pn3W0jNX{&DqxIK%-xQEB?j7!*JFOFG)5oTZb3OpX6UvTkh#h zDmhdIY@*&+p2juP_i)fV2>LL;NjW;d5=g$z^7ViDCZQnKz7UlgFWFuift`ZX{ox^` zdutDY1XeajB|Q7CK^XbU#zZiw_^hmoq~!NkQAfy_kj1s~A*@-%p4?eIu^2MyIvr;P z_gfrhFbRjO!--=V7Ag62Jz&$0NDRoYqT8qt$fh>xlLS@bsOH0WpmW{+1@nk%;AN|S9Rm-a^k}M@ai_f_uqC`>L@6dSo?7Xl)5A#SR)D3_5S&qL0Fstk2n(G zz2Brl%4aN{8?3VwXqv9^)Z0>@9qEp>zPTC^_ZC;-NV7jyfR8_^A>4(f^5V(nj{c+X z!(j2aG1=yC7H5Z##iMZJl5sjSj_Z>pVbwvWS3aLd98mfAK$^B#uJn<6I$3`x9DidW zH?rTU*qhCN`*cHyZfQz@IGFjY)?8=u>W$gT0ht*yR%vdK!T(0-i6X$YzVkMz- z3-+q_t-{tG><`V5W@4SE-(8z)d+S%0fp_V^)c#`Y4lzahjH8}!;Cmx{uRPhi3QH+J z3H+RWei;!z=J!K)ec|}5`%92imodmpBJP3tf(&0AotB~}!O{G3b!A=|YHwjP41Sxd zjST-eo~}ZMXmjnvPG9}E&ZnWCU-6`XA&ZiR@bg16DX5D zzaV`^P*B3&#{5VqZft+f;Xtb&ScyjaG2dld&23dKd~qI-ha(+N^5hA}=$fA4(N#|y$A9%O&SD$mJ- z-dZrLTz+TE<$dd!6pr?Z1dO0M+Q2WY_M9Z2+{*k6spbr-o+1lHIf1Pr)y#c_pTYGc z_ym3;$~%7=KArq9(J53q<7-~?q7vzDeV)gP?{?w}TZ3T3iU^h@ja)uDE2+lGM&a38 zjFv_70@=#8>(sx(iCDL$kN;CXa@!VlR!Taot3n)h@1BPl58U}#Gk<&QU5zIRT^VWx zXhn|`Cst}8p*+6NoI>IA6St{cmAC4_C66q|oVgsmrZ>PyJeb}S?*EKG z%|qBM!tX~yh%DizvsA6Eu7;Ijma6t>8wHTwL}!k5-WaVME;mNziWwy}a3{8?pSH&=lwuEI9Mb+O~9vu2jh~{#++!?)pS7 zS-!{o!avyjY;US*UcU;?sP#uNp5G4W@MAD`heTFnpJRR9EB@MSW^^Ckirk!!c%Nx=VSNzq4=_%4Q;PuL)P1e zY8UhFf%9kO4;a5jJS(rg55fT-+t!2Prk}NidpZaCHc@k)Fs@&TP(KI|hB9DG_471x zd1#dw+x%;w@wL90wHrg%B~4^_iztZo&*yWMh@q{c%yr^~nP-L*Nh;mT6rlH$)-v3g z8h3E~kpxON0hK^5i4a;yEIvJydS~rDh0KkKd61p%f<)p$0-Gy^rrPN=wTU=#-lZ8#@F})#?3N;vKtPD_g37?dLN<*S_*m< z()O(O^~0Rm3!EqE1MGFQVxX)>I%K4q4!=m0iLSq>j9q*kC#(F+YQ}R?G&}>x?54*z8D(`wCqVT=z&iVRAJ%ZC z6#=r=oOm0~lX2q9t0!*q6`;tBk??Cu4x+P@NXmHu*SB8V)J>+{xVPb+aVZRjvk-0G zdyaHpW$gE#FOLwv@$_IBmt!<4{MGI?6K#c7f0QOdBdvFO&;=>J?tuWY>$VoGJ!}B{DKG zJaWF3)>;%ccf%V>BafOR83adO08(o3k5o@G>=zR0q>cb-H%IxB_DU2HsOd3$JZoes z-@$;MJ(M|@*-Y>2inuS+3r_LjZZ^ZhT84|ykpkkkovTA=Grk`spWqx&-@eWKwoC-7 zC5+mLEPaSM5CB$fIoBh^n||K7#$rk8OqO%pw2oX+dh@z7z6=Jzq3TbiTh_RD#ZChU z0>jyYw~JKp>(v<<<+bsRqeUj7$C9^uMqTXHOi`OQLxne#bv5B16Qw^Ro929$IlDsr zF)~PCEXYNBu*Ct8O5#%VdEUE5Un6l?0!ZKV@78swqmkapytMgO3+#PzGBHK2=Sa%%Yy)Z(Qi60AQnSRT_loO`5GxA-Bot_NxF1236+{W7*>FYn;;L;F4)i$Fqu?$sC!|a%0%ILL?)`Pxl17$pi+K}Z>(MUMbDMuXdbG~09py>oiG^G1-g8s;TzRp6Ce^53^}0o+Am6XTzca649LcPibsFBYSe$dVqwBIQCK)MkD2W zTr3UBaot{)<#+>-p1Tzq+pD0FSeNJNh9PnQQnFv3(E9CD zq!lJ|e0sT4 zp*CM*>_t4EK6bDupu)UoIVXbMIQ#rtNDkE#vpS~ZyuWjqvn|Yy=*}z3yHAy_zQd(3 zvn)K~nOE_{Vbvk>-I$L&e*OJ<9%}14wk_FNla)f_#Yxr?YaZ4Eq4zDmxoI|VHVlj? zH5nTp;4uaKcC|@*>Y6D{ANFv+fhKPETh_H9voRQLIGt(fl^{m?z_X%dY?qUhO)KQI zqd2qdX1C}_h{NN=2y@b;cV67-Nfraks<6sAI=SmMGL#2e>%6Iy1(cn4@#{R^lUiU| z{skONHk?k^XBYQZ8G-gp`z$r|MC04B1MQzKg?af_zGKOXp_jXQmIcN&r#vk7OxD0Q zMAK1BXir!Z$#-CLGQ27(`Q#63v7?h5y$~mjk-M!PR=1+bWX+O)$pY_Z$Gl+4;~~re zZj^Bv3rl~RtVC|9+e#lQ-Y82r7@{SQJ!fC|K&MbE}>c%)OoPh4B9Nirq)RFA>{vfrvpP**sgh&V zuTY;de_gD)=mG7n<(P9l;bEW6z|(=t4#Fge9{)`!Xub;CIB2b#b7qTSuRR4|a`f-i z%wIEG2uOb2pCrU}!z_&Lv13esRD|zhJNnq!wCv9!X%qTTkr^AO;MyPqiHY9bkRGwmq^bVN9Md_dyyJ{fz-C9ZRfKIMq_kL zOxR@9|A5H{r0S+lu;^Vi|7PshOwSrP7(+aCcx+N!PNGwEM-cz zCos8nCv1kc4>7CB3CMq)xWtn&ER&ktKBa7?kmaodr6Z}W#h2zvtiy(q7_soi+y4U= z`l9AtN)!wAqeoxUEduFdod*wz7!GT7jY>NkPr=0NLbHn$VcjXkISmbeCj8jPyVsxZ z&=LPq%9dZgV`?zQd{zskvrKjT)ZcDcRJy&7zsCgbBDQ@DUZn zv^F}6?0hZkq&?g|EN+mGT`d72RkJ5$)LVvC=@ zlwh^;XJ@Zt=smhTv^V8l?UZZ!-}k~xRJq04$eYiHHf{X6uzpsckvP9>{s1Tet)n9> zIPrH^-~0b!@4MrvZ2!maV~?`4_sHH-DI9y0ttpwuD4a604=H<7ick?6vXYeSWP}P$ zkrAnoz5TBHK2}dXJ)gh7uix`}=s5Rvzpv|h@Avx}@3TAEEJ2jgnDJfTu1KGd0j=Bu zwP~Dx7Rl^Sl9TR6OTu7()T{BV(fE3vm|vbFbh<-;HYWDco5HH8D)K~`*lOJPCTl!8 z_Axm*i6_NKqsMKB7uyAmWc6)x3(H4(uQXB~h57L6BhiGr&!K7Far-K@I&K!ei=o*+ zhJ<2orbu>~duAQozkUt^WXE)&buRt0O@$%N<|OlKGJ^Vnu6!F)ExtPu!fy z-*-H@wXNJN_F7^n%}3;9H2VH(`=RS!dAf64GG5fkV@_LBU? zhodt$$%lB>>Xqq4O2+)mb>wB|X!vpP;kMw0orib{Pxox{g{;%jSKQJnQk5>I4^Pa< zs#@IUVp*PE6sz5rXp;%^h2Sa5{*-c5#0Rd*z^T0|E{5Z0-V3%D63b4G-+#P1r|Uy@ zj}O0)wHR?za3q3^X}tJ*du~`}mCo1ab7iwOl|xf$d9Xja#Bl4V7B9`+09Fdq$p=x? zNxX+H1};Bs8GmE@BL_BRFW+5}zIX=LHSYD5OGle#?+%H$R$_M&6#X_eo_-rVx9?_Q!(G1%<{{)ZdqM9 zqY$L<;tn8{otC_F1cp8H>-u185-40P|p(go(AM& zK?2JAQXSi>yHE%v^^>pJaR<(fW<9s9DPP>+jx0-}`!8?oCwq2n+vg@Gf@jQH%W^gp zL4lXvG)&Hzfbb|y-suVr{a$qE^y9JEdM;+~=F3W5(9E8=o}AmCf71yJ+3YMUajia8`=RB8Mc-V~h@W)jt*p3%WKI47^NewM(bVfEbM)JIs)G4S zuTbFb=W}~@uqz8|UD5m!ux>JQ-bSsCDg~S`xN_Rsv>`!UVvp`CmW72y_3E>!%~9}D zjM0f=g`-WVh}@pjfi+|3MT_?pL8vp~mLvP-3P}CQuK78_YjhLmF7B&xEG0E~tY}{A zTGC6R8{L#dv&kIwiZkaUXcIxmP`tl%pTSj&y(tX}q|4waS>v zaPP9_qMHNhCBovv+sSapgIh0mf7r|YTxnzXX=6=mr+e9Xu6wJyEypa*PzYc#!Csq` zx)`Y-2XQxF6A@SE^#mdT_ znG8~mFZ`f$l#il&2vlw6HnJ$ibc`or2;rC-rML&R%LF4YJyg?q$^IAF-hv+CL98fcs5PR=K^a zR$ZpKdI)bGV@QXH5-)9kb+B8-Nj10DDrxD`&m%uJbYR4dh9hB?MWh;|x%=!iuk_Jn zZMy+3pc^}4R;s`QC-0P4cX@bcvu7Sz2%oX9qRJW+*q1^LQCseRJuVzbW-fpT@2k(j zgU;lqNj{G`TkL)N=(Cb;YcnolW{Ps;z%5JQwuGIuGO*NZ{~WNoXl=XGxB=0N%jLv zYt}&Zws^Y@y=QXJ+rMDu;GSUu)0|G1_w+A$cL;1x9bSIjF50Yh5U6t*mRrf0fH29g z3`#2dJ$mnon?Le{90GirY4+jB)+$gJF$H~4Z;T~Ao76&5wHWyMxUNe}uGW^Rc)z^7 zqOW&eAyb3po1gqoMdQ_1hFYJziqa&Uh+*0BKXCkZ8DKSdDv!-c=~`=!gQ?W#_@1XC z03P-EN&u{aU(n zROx%2dYr%o^a)p3D{g|Dw{nvLZY&SpBkZ;!j~*nf>d08ue&QTrMWIfngZR-AZVQ*O zbv)!>&A#1xMy&GLQxs-~w_>SIxl z!95y+duQ5L@{?V0x?cs~bHyo0^(H4BR)S1dYAbU{Zc(YPrAZ;HTAp!sBaDF%EynQ&j!b&l$zY)=0$qS^}j|be%R`pJP5sQNmZ~h zhnr9$***4wr-#vbhmRZ0Lx!lh)ftZ42WZyxjqpfmr6=`MLG?IcBl$NY=Tp_=Uz{f$ z@LlD6$;Z_O&hB6aKJD6dj7$OZp*bnTwN6tf-hgk|oyy~F`TkIFGf_gz9DC3)1aGO! z#8(K#kG|v@Bt#RVA+f-5SCx>vNOCymxmSSI-nX~n{4-a`w_n|^L|?B!y%asR?5iH@ zw;vpi^^@|YYu(A_zYKRFUK+A0#k`G%iMITfnd5xraN1w-QRL;k<)j>Cghm3rGRs_Zl$HxLUIpWrF zui>|;1f8i=+?pQ+ZydgNxlyx>kk@uU)UrM|H>oJqPT5Bfq_wrdXluM^oMU# z=C69p-FH5A8r)K*GiagNdpn8H^gw0pN?&=9Uas7(2~_5c#cJMkX*^RA&Dusm;b0!+ zdNM;v{$hSLw+pDCR~kkgiCw*$%ogqfDx*me-X7?g3^;#OeY?L0q~?lq{(5?9I}dCJ zA})z$hzvsAudoHmFPt-pL_UQ1LAfiWIMTKxt1#pwHeDLnI#DHpvz#c?WZtvVCKw3o6bVI$L1AC063 z$51LPH?_Y#>L1%=K^A_}a{4S3@ptMR<<#AM6D2VjXF1Rp%E;J~5T{k&LncWNFviJ+ z>1n3e?E`WbMB@NstS(62dKi61B$TXM4lxi$k7mw`O8IT}MbsZ}P6N$7u{YtTF+k<=E6MwnX{Wi73$Z9+tr4_5{PhT$}{x{R$#4B)@|sXN~cN?F5BMEG)YK_d`VCIc45<3&Te zcHI1i*~k@H%kG+F_NxS*+c<@s7%~+3`YSeN>P2s+fXJ@Q-OJvyq%;~)PE7Y@0-(3u zmAw|Ul}I|N+-GUV5D+RQz;&6}gz%AWcyT{r)pv{4la=GCzPzi7;evMzfi1jLa0M z)mvOA0@YumdyG2<<{-nxu~i24OTx4~{74}bVQcqKgeXnXv@Drf6OO?kUM=a5wfx4*?hY%&U(%) z;vpLsbPA&5#$i!Gx9MruuB_yLGAOc4jiHdp?bf+fFpJK+nLEm3FuKWded9BQ`gy46 zk=O^7xs1FSUCa{3D0C~tg`R`c>7oUD#?pYNAiLbYz!prRnG{_4j1(t~M)7i#AD~^| z*3GMypT6vn-iziw$>%dm&9FaWlC!dRli$ugbrI-EVr{>@f?o7J!tmpVyaPN`06-|F~V# zwN`SKcQ>Dpy?p*-b2g?!=}LNesN|8h;!0&^Ys@F(PsXUK!;k{>MhO_#W7KupElIAp z^sn|^77?=J_ZebjfN@=&tb9Xq&P+Y5h#o$YtxSa6?aD9vSt6NQo;)9QCod(4+24+_ zo@_)U11iI%cliMAN+vPt)|kX%wIJN8G@Bv{` zhpPeB%NL{xBM$^o^%J7ESE1y7it`MBdx_T85s4Pe?u}MURig$4yo%VfC0lQ>e?B-s z4>7gBJ`Nk%&?nAwmyHQez0SY}HfYtklnt^B5#YpE@2r9iBCyNw?pjT50hm?(*P%{} z7MX&)q-&B&Pz#Dm>YEvw2Ccb%j?p{y;i*o-v%%jQqq1#2>T_jisML5r6NDr(a~`CF z%G(OIAFhgLlbB{#eqUM04~sNY%WEYDdlL;-sY@FGFQo1-JDdb~Vb^lm!ah?Hs-&XE zdQu!&ChkiuuN?2%RfdgB<sirnrGL z+JHA6LZFi$OXBmhCn=(`NG&c{tM^wxfd>YgUW3ewa3?*cf%4DLO(utLflij+ zR6fSCeLloVJA&WI#~=D8;9=_sxy%H+k<+2lz+%R1^60Vj4UX0pKAjf@#1y;ocB%gb zaYAT6wK_3w`^txvPWn>#lDD}70dK^!*xPq6-&ly;Npd6Gm;rDA1#Xq;Bd$1h;~WhA z>G=bKpNJe^MPGcRRIO|g*%uPyW&oW)8=O`I{v3nmgJMuT~z)`3v=H<*W9YN2Ow2OrbL1N{d{AeL3ND3N9)VVNyAL zQpxdd-<1VGnBSUtQB z2c;13TRwY;tLuy>^WTg31x2SFc2EoE6FCMp$7t=)3Y?AdAb);Q8Re&BFbY#9>Sytu zT?l1TR>*Y;rEOKN-Xy3Jvn1dEwTL44?|P-8;Z9<6mA_i_4vD@y06JNo%ouzaZF(|c zz0RIYqkS|qR7%7`e)>m~&CbB3s1Wjq;LT1-E*FnTBb{7cd3lhq`*l~<4#f2h8TgVw_Cp$(iHx8<>BOy4aFKEUlsk-1)>@*O^#ov?qN&=EyCNnSBGAY{`& z8v)S87Se`q4uPT=uGew2#v8Is2`7lnP#8?&|&b>`^ z#r1t{c-`|+;!GK1G9PTu2&>-SBFa*KZh&9j;S$*=FMpC>yIilUtY-W4yE7j#9m;;& zdWXH={{-1mYn}Kz{6?qHIrERF4EkAeU+F$&VS?o6W0wReKf(7h4~TVB2^%z_%5%8% z19i)*w9S~Kfqo&@uFA%ubm&BAi*)fR^uvuxu6h#W1g!Kj#mz+iX!b-FZ&EJ8JwEB4 zesDZ;y??(du$WFOtjlJUBr*L(PwR zgTf$+Fhyru0oAW-D`Q0Ox^ExbsnUAFXIg&86@&2pU3|SgHjq}^>loNv5?hGbgc=hn zv~r~fn%zfVv|UOogW8E9a>yGwj`;rcg=1@-R318!=_sM84t(3?p}@>1&g!oU)Q1=F zNb6*KJSvyWuWfYT#AuAtgwa_sd%5?%8%XOj43}*)JcS;bZ=Pr~VbES_si0+qJjo16 z_NaV9wmq+QG6jxtRARQOt4%5NeePwKd&O(S`^ zWp=rtFZz4cNUqczdsW-y{x3j})!*6PW_`T_H#2!;z+!P{yIN`wC(vW0hJt58JS?&9LEC24T_xGhLw>TBD5cnM{>fDiSB{M3 zbiz6B^ahwRxon?n`2l5uR(zIZYlspeY)+~X<3u4!?m}?#u2C-I2P!RzaLPdW@`}jm zp!y0LVxYt(ELN|Nm(m8#(5+v`Lbpfkd23vJZ|H?5e5s6WY(v+VubYf3<1P>7wZTg4 zC>hmDl{^&3Ft$ON^MEC{Lc1hTVk<*|RPYJNQdzbgyM;-GG6O`H!`lgV1kSI12HAot z6#Ixc4=?r3^}TpbQg8b&&x=<}E2+rObY63KAeb^z=N^A=oA~2+7-7+?3b!*ma8y$d z`z=-F(qm{IkWu2*=e=6 zs+k|2ODJnf?^LbE@AK+-e&kk+qek_ZIPHPb{%gaJ1$#$Aj5oT|SXel9daXMyHUYz` zYpwJmP~FPh>mJ}UsVOsFKSe>+uDDvWY;%#=$LjSnVtw4HJF)dGW>urgr%X0xb;9b% z=?meELc=_`tDs{zy^A9tU2k z_NbMlCHg>OI?J0;#K&+~mc7zg8x-i*Hz=+6iLyK`Dee7vv14x}fr0w~eVGSM=<~xD zFLghM4;7A|EBbDbhf-+oi3xn2h<@m0s+kLoFZ?(F=fDOi??lP6kqRvb)Ghm05G?1b z+#%qq>X<%95&1nkeEp)c`&rXZPv9)ZFDie$zT=|c`$_Uq1!$kGs9Lkj0Py}24(+?p zmD2$s9Pm!3_vbz-UZBnVefxkm`^r@iBtq|sBl#itCZkT&uDK^qLtBrbg%?&k5U&NetMzYdWt_A|tVC)eEhb3l&Uxo&!`5 zsd_^lBfJ;gI4wI8`*FwHO9la zmuC0E_ZOBK#J$Zk;4x!4?#TyuIU(}-y9eOz?_qS{zLi7z1ZusG6xRu=`aT2!p`@!d zH(=X22-SCDZ&lhJvE<&hc#sI?@K)jVxw%xbV={;dOYl5&&HO?b3AM5fftjbbbwmcb zh>uCNRHo#+CcJTBHek}pOLu#F(2D1hZyHfoRX?pNF|O_dTrKV{_mSv8oxNy{X_K## zZ+6VdzR0E%fG$l7w$eNgr;)+$0WVfejxljKH7+bwUa})yP=0}2e%}Q11}$9cw9vDBwntIq1oW1+il$e}4q5Rgdw-Qw5(wn2fSt<~+N%n# zukJ9!bx>=3&aZw{_;!FXIh}b-ko!lwO5D0I>WFuleoh0sjWU$^Rw;~wUUjs$ol7)Ub}a)IGjSn$YG|BdoBx-OVZbE|S~6?&qhcOj9ro5u&{ZOCmam18roWbc{Ro@SXJM-=+V6Vh zbX(3hI~ues)4%nERvXqOX5boza~8y#6s;ENfw669KLZ(mGN}FM>X%i|Q^3)nJ9ET8 zOkfZ)@4#j$OC9CjA#0}wTeOjf6eD>XD2zH`k|B&LtR}zcz( zlGL9#mugHXceV21>hY$aw}A{|C^+fxZgp>C2%L4$yPMFd3(RwFk9Oeo0<yjyxD0!v&RtF^hMe1#YmN+NVOs*GPLw+f1Dm|7S|WuhifR>VQPC5g!0iUTx1SO&Up*ah#( z3eyQ9_@R%TecRMt#I_e~!D*S+rMW4*3vD+4VHSIOXYRS06WkEA0CsC;rd(!v*Zo&E^i1d9I>yo)BwKYeq=ie=T>U zF!?%WH@N6Y@Yqn&i@heNa2F?-Cb(Km&y1j6>k>fjU>6x$6qF834B6jNwI7Hl(=^*x z15U=b<}C`;To7HH30bx(ErmaRsc1anQg7(KZ8b8qkyXW3bz~|iU%_kMP8f%G(P?1M z&B%1th2|vI%#?V`Ga&SH^!{V>v@3& z{bBEd30Cz<$2Q2ZtxbC*5|D#w{=oA6j)y5N9E=tySQ;Tng|Y_7h%upFVG946jQAhr zJ|L~M-wzTxLlJJyaJ?6Q8O}wY10bLn$VcUVbb9n0es6}YYBEooc#RD1>nf96xE)-OSS!{CVjZ3gQB+i$1IfNS+s-CB(H(awW02>nYTLg5;;>#YIcl|}xi`sSsVdEekR$Hp^$l`}mTWkYu%eA>(UBvOZLstt#p7!7D~zizQM^Q3a1~-L zkKl^C0VBL_SCVvEiy!2wsI1Vla;M~zJy)lAL0HANP`7)ZAzua%kI@^}PoDtsxUpnK zNVfa*6S}tRD>Tp?xF-dA_5xmZh-Rpdja}0vQ&vIb^-kkJmsF{AQJbunHh=dn_5Jbq z#9(?yT0=>U5=}D0M^c>pR5;c%Q&S1362Efwoj!nfZRTyr+H=jyc%Zv+WH7E!xG7f{ zSFhDx*7I$!?k28CI~lIW;aOMW`K=`5j+|Z=kCGS7e$@Oz7f6FG$v1IzfGU0!#+CI7 zj(|vp`NmzTFd+g^F7XVMImiw>s+or0ziO|k5-!FR!xj>tN+{TEFYeV?KPc>XYd($M zUZiX{zvj<`_k`8DsEe7}Dj9Qjq^AaeL)@scfBzWFSEK;6@c!>avIF z;L#VCJ3`#@=B6BO@YZ!1k@d}$+qhaJLmUjN)n2LW+x>}C z+dd+JXkdJPgSR-3f4==JO+Hh0nVgJybx+6ZXZJ@el+2eTDaR*jVSIJaPs;oOUqQhp zwAO78z5#q??KWGvrp8L4@0k$tP-g*s$s}o~6x6nXFIN+?Hrr=)1lJg(vTBci;<1p+ z!P0;E`bb-(@_@+B%uCg9H@E2}CI8UPyIZET6k_r4-8@-Gj~+fz+eEJK(Xq31a0y*! zk|fyvq;;bkx>8co2of|Q=3tzpp2t9c*L$4Z-IZsdtT!jlb){0~nxCV7Xb+3soUCg=%&b%*1Xa9i65;AV6qgvcHRm{%C*=|LNcHr6VT5b*7$S|(e!%?OL>167n($;9X!LjA?c{xZcwuiK5uYE z*U^D8g}*G@CacMgo(Sbp=>D0fZdSZvG&dfWewo(HzV`=%Gn*J#t^HA)6V3AH zWHA%MW=r4T@Y~kTnO9n4jSt8R(N@-1fsPp`SuiQAP;<1=-&Zk;aJ^CIYc@X8kO(s>BwL605(a81ZKAehs){hl=bo0l*b% z%eo6Dal`~Pd@q2ol5q!)<_2}a1r-UkSMILo;#}1PxM+gfiM)o5%1sU=SbmnEkTT`m z>`^C|c1h)$BV81IYuVFes@Unn`>?XNR+RiZZVXT90=^)(ydum6_=0of$g7N4F+oJzeMjZy)l##nFDDZ2 z*SKlDc#=#(GLgVk8|^!0=F@G&rwq(ONferPYAPy=`4dVs)kcO!xH#rSW)-5_u!u7mt$wL}HDg{zkpJd+Zxh#h@# zz;9c_U!zS~}uc9Z87xb{lBT2MRN=aFq3@XZ+S57zAg zzFFu(^3)qaN+M>>0^pmGKUZYVyH7@pzmdu{j8o7P7f(c*T^`$T|A{53Ouq_){v2nu z?~L3eU^tB%1cwc9Ng>_|OT_%t4bo>EXfC(%^!na--}gQFIbgQaH4{OsYs^NOMBGGK z`xY=8VbOV3!pQZDSSnxtyhyxF_sr*KI$C~_+n({b38>cukI_D{H;@JBG9j9^2&b6S ze*2^C!2;$h+mIh4-KmB}fAnpUw(>|IJw+WNOc6YTkYdOEtV)$*+~rbrQRUWKq0#Z+JF2Z%!#x z7F@llQ<=%W=K{!*8CE8&kYIv(YbO?UBr}BqY(IDjD)yoos!$~) zKv*4coQ&z&H{_0sqSeUh?tN-?{kV*^A_j$x!@|n_f&JEpD*wA8iZ3dv{h-Z!%0HZPMZP^ z7V>_}6Y12?=Wd8KmSz56tg;BoUOC1BZXVSknB_N^=E~c5nZMkk;X|uj;#FX$NgA-d}v!vsl%)?L`61-Z~eG z2-t@M4BhXo9QR3zExe-yvPe@{c`=qUtS9wp}&wDric9WmOR*R5~L)P9-~ z?|!1ZzpM1U3yiH99RUYjvYP9sr+c5*N2!Y?3?%0r!hSo}X{7X}visx;i&;ohHzz!( zvRVcIG;nsK(Aq_rz+tx!``yakq^FBN?8ENX(!qmzb7%spf6ArX8J&6The{ov&fyf+ z?gvzDE#kICAF?m}e4r85tBDNiIT?x`oBEd9ak_bNAsv@4Ji{%#YOKp54kwKji zcyK6Ju8(vNeGJ&+;hvCnF3Y|hUXr^0i1~Uu^C_#e^-gZjv_hu4O+UGYtoT z`tDdLuL?l7%!oK>FuK&qs_huFYJZZNFg?b7b^1ha3b zmq5&kFPz?P|2US3z0y&GC<=T7f%)K2Z~^u-9H?>*<$@XD3$X7f0KO|a{=2iFBZ`Txb+|L+xVr>1N(He$WEBl9{@ z_+hO5-qDqZFwZlqtD8Rsm+yjt%rJL+hN#;`!G|gnvArL0r#|uuMd&Y<@Jw=4ym|0w z!tnWW!ZV|R_J_}gAT<^i(2fp>9dG6|_=Mg!VRsc@z+L?OuLaz<{i%R^Hq2Y7;{yOb1q!w+0K#SNh{Jzz7yS)9g~X9>t0+qrK-qRC8p3-k;9uev{Kdkk zT}ZVx%c|}8$8q?_kiE4Gh-))rONYi|?b-`=Kj2Yelf(pY;;TcQMdB8ywQW0!mG zENx8=W*7u6H_rCBMi9P3H+-SXadDn_u9^S*N{{rYtTFE{>Hzrqi|I2u&TM<1%~gMj zth|Ax`^GPPbfl?jM#4Ai24{w#Q9pY_0!<6^z4a?$_=kR z#!^1emFT;NT!Yi;5#GiAj~Z{_{%z`~5zQunCv7?1I8l z_UTv7`xoW6*D2_%B>Pm~6(`Ui5p$cr?@8;ky%ok$ukoSF>dY*|t$`>a-daw_*ctS@ z6E?p%CS)-cl&9>Y@pvDaasKwKpd7c;ciP>S`%IM=Z{DhFp1lG*iA$=tFbV4V1MiD! z6%O1rxSKd&kw=-_Bt1K6dAL@33fV0OWBC0wOF5&Y_8h2!^JA=H0I^f?2%U$M8CBZj zdV7LX9PoGwWDZsFzu@z#z4qR@;j7^Pu&QsjJ&#J-_IBb9c@P!YUa?zvPp+h^|HgN`n4P8`#&o$%j-ONmdzG|p zs3cOn1>lJNx#Lq-;cYLfY3vV$cifboHePyKU3b}HiZ6BdN5)KKZBQdaxKl_;c5mSL zx3&a3284-XQe+J8My6D8-+GE9Ab{63K6Y!&TW*(WR>PE+v{o$3%g3|(K2TRScZiIA zvI8N;G1aSIZq~d`G+~xp`JS#_sGks+EukTN`Kd_69m;PLk#XR*PY_>Beb{w_ul=m) zmzL#AlDlKEFN&8IZ*1e5NDdeyvWCILUG*vF#U=>~t}ck((M7A#j?6g??K?F>G zg-~R1<3Uo&Wx^=KNIV!hnYdJT&kmP26fdk+Vop9wB-&rMl5TbQ2=@C)7>rozjUnrl zQiMmslBkD=A`?qu2+KC!ol))Y`H;!o6P}9DI~P@b+V`{uWsLLV$IFXGggty_ zQ$KUfVI0|}O{m-~xg2O8SpR*eDIQ0shGs0tUwT?~UZ9099|S@lFcR{yj5k*0=k}Yz z{iR0CUa5g&6uq&0W~wI>oe)M8Xm$+SMRMMIV&-yl!l4}qBf7e}yu83v&gkI6jI896 z4u5UXNg*cs$?Q8YdMu%W)xwE%X0~ccu}{iiAiN!xGDu<9CrtzC@WYoBM14nX5UGFm zV!5Q6uvT@9nh)OH3gp%QGTFV@9**+`BoT_!mZ9ZB!s-a%V?4U2UvB)zxBDe!17s^rIb8Kw( zcC}?f=wbMh)xPfxee4=7wu0}v3;fDs5ft~xytzM<|;iIz%iY1u8kaSEDXw!;DuA`V! z`@GJ{keIw%>CmC=zArHz)&ZmyJ(I-!S`r2?K#)w?U?T24rJMNDhWsVPccm_!iTfSV z`&-sDw4lr=rM&7F@FqxeBx%lkM;?wh`|wOLwqAK1GC1{JEIeaYoj z;myjIMmqaMF2=N$j2X`_3fSIk!8`_ovJUstV}+c|(jqXSqE8kP!MGe^{H=>*X2<*t zGqSxM@QxRINe$P~TbFn0UVcstK`Kn0UL=dl7BY9gQ1_ld-vhC~FyqG~UPKd*2jh?C zJtBC5rJLOh}zJ3N= zSm;-&uh2^((OE0fHTW6NKBu|!KHsK09T5{1wWbV-bf}NpJaSR%ytViCfd61_;Uli6 z#i3(fk2tinsNupn^$=rdu*F#vi~OVn#~7ZMeYJ@XwKy0($+bmFWq?KOqiS(+uT)rX zTN~_<2YSi)CcidXvY)rb{*UnSo^=x@K?sx)I71*Fmx#Mmx>C_ij z_PZ}nx_-hF|6L60O-tUiH0vfLT?vduK_1uZnnm#>L7}pcr_8abDUqFvV?UL?WDNdT zJ#7vYqKTMqfuMlp%}DKn5x>1Y_%Vs>7Qu~DU|!u7R{?mf_ zr^r_0OObE8IiOGV@7{=4_g3I}kc0k#*ia7lJnL0j1wBNgT4Nt~$vWLfpU%9q^4)le zd1xPPh4PzG+1So_2}!u_MZF-S7#Z_9m5D=GsgSkdDA&oI+WxB1@?F$=!tcSGPVasl zBGydK@9s^54IE#jf0&1RwQ)t7csRnvOT{pS#9HHZ&1dh2gn0YmDOJO9OLqv;)2Fsa ziaP>DNOmJXPvj0;yY}+!2~ip4lRL*O$GG3QC5zr3EkWoVRe1Yg)N@Lc`#u*M*PvWv z*{N<8f8dgdeaI*%VgsP$;v{f;C0W|VAcJj763QfFRJ+Ff7fn9;%rAkf_v&TX7Wpqc zdU9fN0h96)uLko?t@;w#vj_aWHQ|fC;k0A;;7Eu&Edj@hK~`1i#Lb}Z2S-O8wUV2j z8X3?VE`nVI5gPk0twhv#tMu>sB6V*KF+4TwLmK>zA&XJ)>H(Yyy&L)eK#;&@e0E@U=nSX(-8T7i*ekJbn?5r7)-iCseE)cI=roM&FiiHO_6;Uh zb8<%d6+E^Njn%4f2ql~|XT462hqCkYfz)s0JW0HVGm;(8#ZEP`)9fpx<8t_r@22Vq zL+QedtsKo@nmmDGN?e2T`Ah9S^Wpdi7giql_BSvV`K3ttv6sAl_8&0?r}xIvG@l@U ze3fLi*0{)>SYGObJA;c_s^_7+!1Y-^4@ly4qYy#{4zqYoPY{4OUo5tvXiYaBntQvD-NRt@&i26G0>*Tj z>V@FIhIqHvLXTS}?%5BIEmkC}NIrqpaRn}5Tk=KEpH;~k4#oUfLrp@v zRrLIRvcrDSa0P9EV19C!n2x9;Y6YYt6%Mtw(oZFeHNUYe_}X9t+A#&NrOLR0y@uIm z9)OK@cOqLt9F$t?QEQ2#WIZ9#Yr2^Ky043U+?c9V^4HycO)-+1QpKVG%Ayh0u)QH4 zhVtg-<)#ZL^PN}?PbYFblu7jHahE-04$;wZ0*J%TuN>|&pBSoI5I6YfY7>Z#yjlg*v-(R-pF8E0=CBCki|iKCV&Yd}gwr$s053x#SXYnM<``vb*hb&=*k` z>Eh`TFr(dA>Gr{U@L05N4e`t4P6WFg@^+%cLor$Yp*sqZ`J}J2FMnWGK5Obj6{)wc zu+D{oB2+TP??;#y7G<%L?cE5Jz#MAh(mf{>T<-ZeZNo!3|KW!!FDi^MCmP-W3uBkB zXf!X~Kt;;2&W$h#CzLN!Tsgu7YP4=Zd6>I9u=Kmxl=BZ?r|ozs#gBd{7^A|X?nfJ* zz|*L?Qew}IA#^*J9+~Vhvc3AU#aSae7JN6MjOAI}l}|G(ao*wYM1_aafBA<@Fe+?E zS#)~}9*WzG{Q7KrwBd)7N%1=B3Zt^c;UlBdzI|ug+6C@D!fWI2w$oA{zBn}J->ZxL z5rh|~ntXE&dFUm58Lg@lV!sD$K4^$|d?#HXipkv1z%{li5Vz&q5p@iKwSKklK^FN|(3d2KT>8?nfenfiPE>1_wHLM}q&QrHL&(FYS zjHCRqEX=<}(>`Bjj1FAC2gQl6LD9c;>?XurtGOGwM;*x0(!0kus-KRcAD`q^k9amU z+||;X+v7Ioybz>puMf+T;^UR`-6al=#mR(4I%~3|DraK~WpVt_B-3PoEpGyI@b39{ zf$X`;ha+7ph`Cr&k5PH(jrgBe3Fx7$gXNm=Eqw!9zu2MDSLj>hc)51;vWuj{sf&F= zf>&TN6F7gCc`cd|YJfXJWj=nlv6l@3SN}eF=*!H#5P5_N+!w~M81DbRqO*z4R+Qd0 zqZhF$tPXaixhQSDZ=15j6-)GZOxlpJJ;LsEh_a_VJ=sWQ?P6~PMff)i%)eemUc(PZ zjvjZ~e%^@zPi@&dEesk^qtDZIKcD~3U?K1{h)=%#Fz$MHqM_A}K*itDD+W8S#6@0A z3_B$!?UhB(d@pc%dz|#0@Ej7GJ)^rKa2tBX6v#J_gII8#y4IT)#sw+TdK6T~nHyrS zy&wu+cEWh#C-oel4>VBI`LWJ7GL^1F^9EdyuXwPl>0|Jgr@r zGA_&FGjd-6pwWcd3|;e*Ju1g7E=wioz0C{R&)3phA9)@~uM(gDhW0JrXsk@@wd9}2 zPxCw`Rz@PtFi5lklm-9){{alZS#Yo<2$^E6oTas}R!)!`Siyo<#Kggmgv1H(zp09r zl{4mq8WwvRV{53UhIMhnI$=&|X`VB2z&JTsm}p9PoH-5ZLjT7LhE}epEew&ia{txV z9`xwwVu!VG!`j$bxvux|pM%o#aJO>Dy1K2uAo5=wA%il}JckEBbxk#_D@MY= z`V_{-9pVIkYq;1ux?m(!YyfBlV~mrPyQ3$@7z?^`#Jc=@i-TAjd<%Fr^%oe2F-}+; zM|W?qc=?YfIxcSRj`r{zAf|slv)0GB8+f^3Tp`xq9;pI=r;!1=A*-*ybZ4!Gb#ijF z#T>!9I@y9fn*Zo?{qfrCEWbV1wsN&qad)?}ae#iCiZx&zR|7jcaH8^`V6`1>Z80to zSWEqN_NrEH7zkeN{bi8&nF;*!Yh%nACr5xsj4d(=H-K?d?=zU+p&A3G{2iah7-y_I zpcQ!b+W-w6yxkma+$wY1%mOX=g4D(5B~hVF~$u% zMbwiUGUb23U*|lGEevT*t?IbgV$LDl_t(~jPFCJdj&AM{yomj4O9);t#Tyi4mZmBS z`WP>Dj4fWo@tmt;2vPmB8KeomfrkQ%iG>Mb6(rXG-uSTgKmmTRK7%#UQgO9$z_`Pj zLv{;n&`!e>WO49w{p0)-gZKY`wS5qSxbdsvqKhqicv^88CBtKX;t8w|V@f{jpr>iS#fus-K?ygU|9j2VBqe6afQ7qL__>O+qIYUtj@uWOdNeMhzj_(hLGf+y2gvaue=NM z0K(FU2lpGi%~wo3tc^XKFm9WI!T%q9z)}H(0ols+7r=Ul4Iy}o*k77#VOc~+8Dd=R zu&&NlE;e|^hh+Ze_hF-CYv6*QTI}y{nL1)rT`^Xt)iE}XupfaKr@xF6VZ$vZ_b*Lh zkzH%~NABK4J3MtOZ*@mkpy`2=_eYl6Yz+&Kx-0gKfr}IHK#eh8z!P)(v#4!-$;kt6 z01<2bmtk9*IAFbWT-;r;CN>xsytV#Ya|9zAzzW#@=NR;{AW(3}04wkx2(dl{<_27l zH7@}6SpGHy*rFpI0PKkTt)Z%wlM`apF)rFb>A<1GUz#7Wa&-Sy-TntNnP6iIvU2S_^Jf%=bjFehzzIDZ*1FqMuNpe|kP-5n5*|KHmpwAv7JH^f>ZDq{1~n&I3U zSilkm8(RhZ2iWp&@p(6%;wQBwX4rTFe?W{89BZ%nU+WK%j@CvDe+TO@bw@ipM;i}V z=fm;MKc1=qo(2&Bi0u$3{~u2eV(qc&R_<2F5dZNEeiJxBa3J^3CmwF@Sm%v#!jt$% z3z!;sZ3_D`zdnSx|MAtP1R@q3ahG9~ZGCN{4H5-xAqqSSHwpN+)W1KHhG4E-!zJuy zVO-Z$>6)7Zycjs(IRv~r1Rq;Mg+I4Hg-OKX@dZ4Er!!4BR37=*Q^ zE7sZ2731lM^#DBTiE-NM-Tw=C9XA~pE7;}0Am;e5v$O_o$NvBl4A#KzAb^PXasLhy zaV1Q#@aX;<&DOBO0CpZfm;a$X(BR%CXMoa2V*4#2$-iP_vo)+T{yugUTW3d?|3(|k zUWhjMD>VFwfXHkKvi>|u{I`gZZ;4$0r7ge~^q(_P$5^>LxFPP`U&n}7JM#a97&RwH z;N5Ei|MVYnvFE?u#D^k>&e#G!{2%YauJGRm_iNl^2nTb}79Sh_0;oISsClcnf&7!Z zH|!oC13U`vkzZ35e{STuRp+cXS!XI>%U#`VfOx`*j$gs7slY8h{MySvj6i^9>tW-L z5b^g0cr$0^>TT-i4)P)J#{OSH8@f6=Z#>?jW7j%B+#MT0dblTJ9VG4Z4*H@?#>EYYs^@yT?bqIs*abL-uF#gy zU=0F(%3EyF+V=>}K%im^-r5q)tvy{=$QWCYZgX=7IXfc{D<{yqD#jal3$_tCL%Y?iCl)`)0rWO!jXh_$lC zdbqpcUCOO--5;B64UPWPU=0kMRQz?Uzx4J8D4TfNG_t=-$uCGb4De{X)j3!jko6%q zKxmjv@Ou8&fmj1cb9MhE1YHZ&Z2v$7YuF5#fSjYdiH$1;q%VJ;8E66kxVr*l1svhu zrOg_#B!3W9Ydo^nC;)N>f0_&8W8?KXoE`qhT#%=5g!MbaBae^(2as3Y%Gt{PmzZ)5 zS4b_<^~>T=uW;!g<1feTdiDuu=IHFkaOHbo@eWSOR{Z zq6xfneTARm4tF5BCB?9=h*(R~!;Mv1X&B4mW9#Hl#aA8BbM#ilH{u*37>+56P z9qqieKspp-3j_WGv*8;ec(FxRU$z7te}Dx;F?F;#jd9h(xVgdf-4ZSR(q0SrJa}fq z$BciN3%+l-A-)M5X8t=o5FNS#%>~OC(r`=k^)DT(dAPd5nht6HJMQt_mxfu8s= z;`s;hwf>Dhn@u#W9GyUqf3m!A7JtnN#B7bC*ATwJ%b9isD)Z5M!%(bZfx>3&lbBjx0SnI08T48Q7n#Nrzurs@QC_0kpPv1w0IAVYvT= zl(0hZum+1iARqiY@zz9V(}~gqYg|~bwRHcVW~Ji-d;kmvq$TVeT|p$Hhj9fG1P4gJ zw*C$BnyKHClg3YLtASR>*ja(l)xu)!(Ut+@?J<}Qk|72t#k#`&AO7oOR$g04``5OH z|F5+30FUCh;`kY2a3hHwn>en**l|dVEI<-SfQ^JCz@bIL7=vwDr#qxGr#ty18L-oP z@4ffldr$nO_n!Dm@6}Fsdi(unXK&w}_D)Bn@B4kTyYpt|P1)HuZ|0!Do`!ARI?{Z9 zrt+~FU>t|_#J84Qt@r<`gIObx!JwNz@d*f3M;%MD|yL)jGP3~qVGSQA9j8T~@G z$&!z~@4}+vVRFost#0ccL+?b@i&JteprBXaSgKpozjkM8u9mj1xLI|jC$o<3>O@sX z)a>tSwb4CTE>G{klF^S~?=@NR(Pb(#XER)q zEfsBmL~-T}Mbt{p>!$f8nxxewHq-0?EfyW2;KNhK#bq|eT@Kl#q2)X?jcw0!M54Ua zx!$7~E|`{)jUSZ7p25&zEXA2h$=MY_PQ&t+y zWmd1D)OPwQ7Sd@LKN}`O_PeHii*QS?|Hx#qEK^Ay-Tou2@wEY?0pv59BZ*z;#iGfY z+xR!)NcKx)y=t$|Y$V6ANhjz44Wm$7G8K*&**%uo!aW=Y%3-GV@)ohp=Z@EyFWKw_ zdO{PM#)}e}{iO6nerPu#?G8j)g^b;to;M4xal4pGmx_uu;~^H?F)~(SfmzOLt3$3y zYyHMTS$5cV9aInb6I5pJ!OOT8$m|~IajT2-^Sd3gdohMai}`R+Iro@d@1;uZ8LyP5 z<@ht-7$cb7UCtF|CU%tRd@~-cL^4{oj+AoQ%E+O>i)cmrDtPI5UCk?!L|a3hQKZVm zBZ}?$QMTQS(*;)YOh85xE2-wG6*covEb7j=anO-<_RM5xo4Znz3iUDRbIxUac(dC_ zVvS^a+-Emix}gxMqOoK4qI^#28(=0dAn$Fmz3yPjJOC&oKoIHq_#RZdY)WrL^=>%I(D<2ySlO?PJ=aam<);*O{tvS2E8|ni$C>H_++3zfI%^Zu zWStvxUzxr#7kkPTHkRwQlao=sMIZ=n#5$vR&nl2ebxhhTDRVk4oGzQo`Tu zdN(Q4x^`-WlBV5KEN4fGL9KPNKAytDbgr+O)HYEGeT@|@{mdy-n6-tT(w<%sGK|K4z}`+^*)fK8YD?*MCVPtB1I5 zJ`dgmG86tRDGu)@Egi|bV<%=hos}jvf!XS+O^{-HdNtj|sfu*dp|00Q(bnya`NoD2ar%e^i4(JfSozUvKa*N2yJx}2NKgIwG#0#( z2Q@l2In+PAJ3l#@udqQny<6L5o-~FTuqje zZ?(xf8#Y;I)W7BF;hhCs!T6K;c8 zCe#M8OqlW})G4>UVbZonNgI~Rgw;SNCZq;Bt%*+1;jPe2G31W;JO7Vd%bU%QGr7$y z0q?+ehP6A8V|>ugoxBtw^LxtJ1o4MvU6hWt`Fu11)r!bOlOL|?$#y@|a;uTM^4Ob` z(LCnXH0C^6GNE}}#dvp2oF+E}v;}3(*(CzW+2Os2XgcuvYFc#FJis&KEOgT)Ic9mR z7Vt`jvuGwqjHa!47a;9eapo2Tg6eC6-N*mHlCdrzzxjPDPmRMcefrJZhLq_i?F?jY z=b0*2ZDqe-a0kzfTX3*9UPEQ>B*s+P&*qth#{~)e;8*jWM2zV%=36~o%2T^6uRn03S^Ag9moWqij4lz*Lp?96JVwlA-g!UY9}9$%xc8y zF3`G&v{kQJ5p5(|Z*n}sXRmH9N5a%Qb%nDDnI=~`J%~2F(&?QeU$ffTjA)}}#unnu zs7;?QGh2~bMsw8usd@FM*Ippz{ucP_g@n4k3+VcIf4#_G>*J*B6F}Gc2J8AHe|@sQ z)*GX1O?$f5P}a5H0bT3u(Y4GaUF)sUwSI4{Yw4zI%?GirT)Gip@6}nl*XUAtYB}9& z>QY@bB$S6{Dvcfu0Lf^`N=7Xy8Ksv@3rI$7CmFp2lF@FCWYpuTzc&8j`xdU{$5a|Q z^_4~kYoyx>knAO(w31VsYyVpJ-5`BiK<(5Dy1x{pe;Y`DdBCLqYLNc=b*S`j2kGAd z(!Ud=|5}j#>p=QfQ&cdq1e|1E99s0;=;?P+M$+m2d^9&i4n^c{`}iJ3w{b399ohP@Q*!>ihsuod-d6 z9s<>Q52(&pg6ez#)Sjw?>buY1Urng?-4ANtEJ#Lewg|5A_tz4ty{`kc_b{lvuLrgF z2&lbtptNf1<6zX^-$JPJ)kX@(d^k?1@(ZByZvd5l2vlAXRNe%ryb`FqGN`;sP=>fgtL`uB0r4v&Wpcmk+@p9pK= zNw5x{3|;UP=!U1ldUzUafTzPocm`Ys&jgL(XTc_THuS)ApckGCo8ft&dOjaChF<^! z@IufSei3Yi7lX#|OF(1zrJynVGSC=)IjGHE0UE=v1dZWWfyVHwL1XwepfUVf&=`Il z?19(AmGB1G3vYz0;7za(-V9g6TVOxD6%N4L;2L;4Tnq1j>)@R*4DW*L;oUF-?}045 z7e?WIkc0O_9zFmE;e#*+AA)iCFcjb;a07f44#913I-Cz@z{mXk$Nl{$2$#Yq;hyj* zI1@e%_kz#BS@2mn8$Ji;z~|vy_yU{hWEW-roc1{e6($KLF|dLy+D-0_pu@klsH5>HSlX z-aiBB{c~u6Ux4)fB}ngIf%N`0Nblc(^u7b6o6z5#pzD>e7=G*Te@Cc#{T@`WKfnt3 zBitAM1owkK!zCaCRC#p668H<~{;$vqe}hZm@6ZPSfK~8MSPlPzHSlj}hyOqa{1-Yw zli^wggzE?w5OxvDyj3~M<9Olk7ZIx5#e^#N1VWX2BB9Ea0jx9|;AG+NPa%{ZO9-Wh z{x4(caW_Kgad$%LaVnwoIE_$x+=EbcKb>$r;TeR=Tb8uOgZg?QoayiNe-~&xoJFYd zAY)oG>Qm`+j=w*bP~+n~LXD5}2{k@i2sJ*I5o&x~K&bJtoKWNALPF(r5n&6V{+pF$ zgfhrgj?kaXZhJ2aTlXrH%gjoDFOyo&rNaWy|AeCZRfLk2Rjqm|Uj5MS?>h)p&rU+s tb1k9Lts_)AncGUIIOV(E-)|sPI$5c<{rdcUzmFdvR9e}o%2&jH{{slWW-kB$ literal 0 HcmV?d00001 From 7be330528b6d899823ef46545a4043854b3dd644 Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Sat, 8 Aug 2020 09:31:53 +0100 Subject: [PATCH 13/14] Final touches. (Bumps -> Intensive, adapt testing, commenting unused code for codecov) --- .../events/bump_detection/bump_analysis.py | 49 ++++++------------- carball/analysis/events/event_creator.py | 3 +- carball/tests/stats/bump_test.py | 4 +- 3 files changed, 20 insertions(+), 36 deletions(-) diff --git a/carball/analysis/events/bump_detection/bump_analysis.py b/carball/analysis/events/bump_detection/bump_analysis.py index f1c81699..501ff898 100644 --- a/carball/analysis/events/bump_detection/bump_analysis.py +++ b/carball/analysis/events/bump_detection/bump_analysis.py @@ -22,15 +22,13 @@ # Needs to be relatively high to account for two cars colliding 'diagonally': /\ MAX_BUMP_ALIGN_ANGLE = 60 -# Currently arbitrary: -MIN_BUMP_VELOCITY = 5000 - # Approx. half of goal height. # (could be used to discard all aerial contact as bumps, although rarely an aerial bump WAS, indeed, intended) AERIAL_BUMP_HEIGHT = 300 # TODO Post-bump analysis // Bump impact analysis. +# Could also try to analyse bump severity (analyse velocities?) class BumpAnalysis: def __init__(self, game: Game, proto_game: game_pb2): self.proto_game = proto_game @@ -148,7 +146,7 @@ def filter_bumps(data_frame, player_pair, players_close_frame_idxs): likely_bump = (frame_before_bump, attacker, victim) likely_bumps.append(likely_bump) - # NOT YET IMPLEMENTED: Check if interval is quite long - players may be in rule 1 :) or might be a scramble. + # NOT YET IMPLEMENTED (see bottom of class): # BumpAnalysis.analyse_prolonged_proximity(data_frame, interval, player_pair[0], player_pair[1]) return likely_bumps @@ -233,7 +231,7 @@ def determine_attacker_victim(p1_name, p2_name, p1_alignment, p2_alignment): the attacker/victim are ambiguous (T) or not (F). """ - if abs(p1_alignment) < MAX_BUMP_ALIGN_ANGLE or abs(p2_alignment) < MAX_BUMP_ALIGN_ANGLE: + if BumpAnalysis.is_bump_alignment([p1_alignment, p2_alignment]): # if abs(p1_alignment - p2_alignment) < 45: # # TODO Rework? This would indicate that the bump is ambiguous (no definite attacker/victim). # return p1_name, p2_name, True @@ -245,21 +243,11 @@ def determine_attacker_victim(p1_name, p2_name, p1_alignment, p2_alignment): # This is ambiguous - neither player had an attacking bump angle. return None, None, True - @staticmethod - def analyse_prolonged_proximity(data_frame, interval, p1_name, p2_name): - # TODO Redo this to do some proper analysis. - if len(interval) > 10: - print(" > Scramble between " + p1_name + " and " + p2_name) - # NOTE: Could try analysing immediate post-bump effects. - # elif len(interval) >= 5: - # frame_after_bump = interval[len(interval) - 1] - # p1_alignment_after = BumpAnalysis.get_player_bump_alignment(data_frame, frame_after_bump, - # p1_name, p2_name) - # p2_alignment_after = BumpAnalysis.get_player_bump_alignment(data_frame, frame_after_bump, - # p2_name, p1_name) - @staticmethod def is_aerial_bump(data_frame: pd.DataFrame, p1_name: str, p2_name: str, at_frame: int): + """ + Check if the contact was made mid-air. + """ p1_pos_z = data_frame[p1_name].pos_z.loc[at_frame] p2_pos_z = data_frame[p2_name].pos_z.loc[at_frame] if all(x > AERIAL_BUMP_HEIGHT for x in [p1_pos_z, p2_pos_z]): @@ -271,22 +259,17 @@ def is_aerial_bump(data_frame: pd.DataFrame, p1_name: str, p2_name: str, at_fram @staticmethod def is_bump_alignment(bump_angles): - # Check if all bump alignment angles in the first half of the interval are above MAX_BUMP_ALIGN_ANGLE. - if all(x > MAX_BUMP_ALIGN_ANGLE for x in bump_angles): + """ + Check if all bump alignment angles in the given list are above MAX_BUMP_ALIGN_ANGLE. + """ + if all(abs(x) > MAX_BUMP_ALIGN_ANGLE for x in bump_angles): return False else: return True - @staticmethod - def is_bump_velocity(data_frame: pd.DataFrame, p1_name: str, p2_name: str, at_frame: int): - p1_vel_mag = np.sqrt(data_frame[p1_name].vel_x.loc[at_frame] ** 2 + - data_frame[p1_name].vel_y.loc[at_frame] ** 2 + - data_frame[p1_name].vel_z.loc[at_frame] ** 2) - p2_vel_mag = np.sqrt(data_frame[p2_name].vel_x.loc[at_frame] ** 2 + - data_frame[p2_name].vel_y.loc[at_frame] ** 2 + - data_frame[p2_name].vel_z.loc[at_frame] ** 2) - # Check if initial player velocities are below MIN_BUMP_VELOCITY. - if all(x < MIN_BUMP_VELOCITY for x in [p1_vel_mag, p2_vel_mag]): - return False - else: - return True + # TO SATISFY CODECOV, this is commented out for now. + # @staticmethod + # def analyse_prolonged_proximity(data_frame, interval, p1_name, p2_name): + # # TODO Redo this to do some proper analysis. Rule 1? + # if len(interval) > 60: + # print("Rule 1?") diff --git a/carball/analysis/events/event_creator.py b/carball/analysis/events/event_creator.py index 3c27b6c4..5071dea6 100644 --- a/carball/analysis/events/event_creator.py +++ b/carball/analysis/events/event_creator.py @@ -39,13 +39,12 @@ def create_events(self, game: Game, proto_game: game_pb2.Game, player_map: Dict[ self.create_hit_events(game, proto_game, player_map, data_frame, kickoff_frames, first_touch_frames) self.calculate_kickoff_stats(game, proto_game, player_map, data_frame, kickoff_frames, first_touch_frames) self.calculate_ball_carries(game, proto_game, player_map, data_frame[goal_frames]) - self.create_bumps(game, proto_game, player_map, data_frame[goal_frames]) self.create_dropshot_events(game, proto_game, player_map) if calculate_intensive_events: self.calculate_hit_pressure(game, proto_game, data_frame) self.calculate_fifty_fifty(game, proto_game, data_frame) - # TODO (j-wass): calculate bumps + self.create_bumps(game, proto_game, player_map, data_frame) def calculate_fifty_fifty(self, game: Game, proto_game: game_pb2.Game, data_frame: pd.DataFrame): logger.info("Calculating 50/50s.") diff --git a/carball/tests/stats/bump_test.py b/carball/tests/stats/bump_test.py index 40982aa8..7c11ed77 100644 --- a/carball/tests/stats/bump_test.py +++ b/carball/tests/stats/bump_test.py @@ -13,4 +13,6 @@ def test(analysis: AnalysisManager): count_bumps += 1 assert count_bumps == 7 - run_analysis_test_on_replay(test, get_raw_replays()["7_BUMPS"], cache=replay_cache) + # Skip test cache since this test is calculating intensive events. + run_analysis_test_on_replay(test, get_raw_replays()["7_BUMPS"], + calculate_intensive_events=True) From 04044a178e9e3aa0b1139edfe6afc5c5b7edee5a Mon Sep 17 00:00:00 2001 From: DivvyCr Date: Sat, 8 Aug 2020 09:31:53 +0100 Subject: [PATCH 14/14] Final touches. (Bumps -> Intensive, adapt testing, commenting unused code for codecov) --- carball/tests/stats/demo_test.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/carball/tests/stats/demo_test.py b/carball/tests/stats/demo_test.py index 66f51f9a..3923082f 100644 --- a/carball/tests/stats/demo_test.py +++ b/carball/tests/stats/demo_test.py @@ -4,7 +4,7 @@ class Test_Demos: - def test_calculate_demos_correctly(self, replay_cache): + def test_calculate_demos_as_bumps_correctly(self, replay_cache): def test(analysis: AnalysisManager): proto_game = analysis.get_protobuf_data() count_demo_bumps = 0 @@ -13,4 +13,6 @@ def test(analysis: AnalysisManager): count_demo_bumps += 1 assert count_demo_bumps == 1 - run_analysis_test_on_replay(test, get_raw_replays()["1_DEMO"], cache=replay_cache) + # Skip test cache since this test is calculating intensive events. + run_analysis_test_on_replay(test, get_raw_replays()["1_DEMO"], + calculate_intensive_events=True)