From 83922067e0f55282184562a1a9706dfab14edd88 Mon Sep 17 00:00:00 2001 From: Ren Jiyuan <47732381+nighood@users.noreply.github.com> Date: Tue, 23 Apr 2024 13:23:00 +0800 Subject: [PATCH] env(rjy): add ising model env (#782) * env(rjy): add ising model env * fix(rjy): modify ising for mean field RL * fix(rjy): try to fix reward problem * fix(rjy): fix the multi-agent reward * polish(rjy): fix dqn net init * polish(rjy): fix format * polish(rjy): norm eval_episode_return * polish(rjy): polish ising model env * fix(rjy): fix subprocess manager * fix(rjy): fixed reward compatibility * polish(rjy): polish according to comments * polish(rjy): add replay for ising * polish(rjy): and ising replay --- README.md | 5 +- ding/model/template/q_learning.py | 25 ++- ding/policy/common_utils.py | 13 +- ding/rl_utils/adder.py | 10 +- ding/rl_utils/td.py | 7 +- dizoo/ising_env/__init__.py | 0 dizoo/ising_env/config/ising_mfq_config.py | 68 +++++++ dizoo/ising_env/entry/ising_mfq_eval.py | 15 ++ dizoo/ising_env/envs/__init__.py | 1 + dizoo/ising_env/envs/ising_model/Ising.py | 114 ++++++++++++ dizoo/ising_env/envs/ising_model/__init__.py | 7 + .../envs/ising_model/multiagent/__init__.py | 0 .../envs/ising_model/multiagent/core.py | 131 +++++++++++++ .../ising_model/multiagent/environment.py | 117 ++++++++++++ dizoo/ising_env/envs/ising_model_env.py | 174 ++++++++++++++++++ dizoo/ising_env/envs/test_ising_model_env.py | 39 ++++ dizoo/ising_env/ising_env.gif | Bin 0 -> 146621 bytes 17 files changed, 707 insertions(+), 19 deletions(-) create mode 100644 dizoo/ising_env/__init__.py create mode 100644 dizoo/ising_env/config/ising_mfq_config.py create mode 100644 dizoo/ising_env/entry/ising_mfq_eval.py create mode 100644 dizoo/ising_env/envs/__init__.py create mode 100644 dizoo/ising_env/envs/ising_model/Ising.py create mode 100644 dizoo/ising_env/envs/ising_model/__init__.py create mode 100644 dizoo/ising_env/envs/ising_model/multiagent/__init__.py create mode 100644 dizoo/ising_env/envs/ising_model/multiagent/core.py create mode 100644 dizoo/ising_env/envs/ising_model/multiagent/environment.py create mode 100644 dizoo/ising_env/envs/ising_model_env.py create mode 100644 dizoo/ising_env/envs/test_ising_model_env.py create mode 100644 dizoo/ising_env/ising_env.gif diff --git a/README.md b/README.md index 1d98ca9624..b03ce4a092 100644 --- a/README.md +++ b/README.md @@ -276,7 +276,6 @@ P.S: The `.py` file in `Runnable Demo` can be found in `dizoo`
(Click to Collapse) - | No | Environment | Label | Visualization | Code and Doc Links | | :-: | :--------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :----------------------------------------------------------------------------------------------------: | :-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | | 1 | [Atari](https://github.com/openai/gym/tree/master/gym/envs/atari) | ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | ![original](./dizoo/atari/atari.gif) | [dizoo link](https://github.com/opendilab/DI-engine/tree/main/dizoo/atari/envs)
[env tutorial](https://di-engine-docs.readthedocs.io/en/latest/13_envs/atari.html)
[环境指南](https://di-engine-docs.readthedocs.io/zh_CN/latest/13_envs/atari_zh.html) | @@ -316,8 +315,8 @@ P.S: The `.py` file in `Runnable Demo` can be found in `dizoo` | 35 | [metadrive](https://github.com/metadriverse/metadrive) | ![continuous](https://img.shields.io/badge/-continous-green) | ![original](./dizoo/metadrive/metadrive_env.gif) | [dizoo link](https://github.com/opendilab/DI-engine/tree/main/dizoo/metadrive/env)
[环境指南](https://di-engine-docs.readthedocs.io/zh_CN/latest/13_envs/metadrive_zh.html) | | 36 | [cliffwalking](https://github.com/openai/gym/blob/master/gym/envs/toy_text/cliffwalking.py) | ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | ![original](./dizoo/cliffwalking/cliff_walking.gif) | [dizoo link](https://github.com/opendilab/DI-engine/tree/main/dizoo/cliffwalking/envs)
env tutorial
环境指南 | | 37 | [tabmwp](https://promptpg.github.io/explore.html) | ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | ![original](./dizoo/tabmwp/tabmwp.jpeg) | [dizoo link](https://github.com/opendilab/DI-engine/tree/main/dizoo/tabmwp)
env tutorial
环境指南 | -| 38 | [frozen_lake](https://gymnasium.farama.org/environments/toy_text/frozen_lake) | ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | ![original](./dizoo/frozen_lake/FrozenLake.gif) | [dizoo link](https://github.com/opendilab/DI-engine/tree/main/dizoo/frozen_lake)
env tutorial
环境指南 | - +| 38 | [frozen_lake](https://gymnasium.farama.org/environments/toy_text/frozen_lake) | ![discrete](https://img.shields.io/badge/-discrete-brightgreen) | ![original](./dizoo/frozen_lake/FrozenLake.gif) | [dizoo link](https://github.com/opendilab/DI-engine/tree/main/dizoo/frozen_lake)
env tutorial
环境指南 | +| 39 | [ising_model](https://github.com/mlii/mfrl/tree/master/examples/ising_model) | ![discrete](https://img.shields.io/badge/-discrete-brightgreen) ![marl](https://img.shields.io/badge/-MARL-yellow) | ![original](./dizoo/ising_env/ising_env.gif) | [dizoo link](https://github.com/opendilab/DI-engine/tree/main/dizoo/ising_env)
env tutorial
[环境指南](https://di-engine-docs.readthedocs.io/zh_CN/latest/13_envs/ising_model_zh.html) | ![discrete](https://img.shields.io/badge/-discrete-brightgreen) means discrete action space diff --git a/ding/model/template/q_learning.py b/ding/model/template/q_learning.py index ece076bd81..e7d6e7a395 100644 --- a/ding/model/template/q_learning.py +++ b/ding/model/template/q_learning.py @@ -26,16 +26,17 @@ class DQN(nn.Module): """ def __init__( - self, - obs_shape: Union[int, SequenceType], - action_shape: Union[int, SequenceType], - encoder_hidden_size_list: SequenceType = [128, 128, 64], - dueling: bool = True, - head_hidden_size: Optional[int] = None, - head_layer_num: int = 1, - activation: Optional[nn.Module] = nn.ReLU(), - norm_type: Optional[str] = None, - dropout: Optional[float] = None + self, + obs_shape: Union[int, SequenceType], + action_shape: Union[int, SequenceType], + encoder_hidden_size_list: SequenceType = [128, 128, 64], + dueling: bool = True, + head_hidden_size: Optional[int] = None, + head_layer_num: int = 1, + activation: Optional[nn.Module] = nn.ReLU(), + norm_type: Optional[str] = None, + dropout: Optional[float] = None, + init_bias: Optional[float] = None, ) -> None: """ Overview: @@ -55,6 +56,7 @@ def __init__( ``ding.torch_utils.fc_block`` for more details. you can choose one of ['BN', 'IN', 'SyncBN', 'LN'] - dropout (:obj:`Optional[float]`): The dropout rate of the dropout layer. \ if ``None`` then default disable dropout layer. + - init_bias (:obj:`Optional[float]`): The initial value of the last layer bias in the head network. \ """ super(DQN, self).__init__() # Squeeze data from tuple, list or dict to single object. For example, from (4, ) to 4 @@ -99,6 +101,9 @@ def __init__( norm_type=norm_type, dropout=dropout ) + if init_bias is not None and head_cls == DuelingHead: + # Zero the last layer bias of advantage head + self.head.A[-1][0].bias.data.fill_(init_bias) def forward(self, x: torch.Tensor) -> Dict: """ diff --git a/ding/policy/common_utils.py b/ding/policy/common_utils.py index de1d697152..6dee15d5e5 100644 --- a/ding/policy/common_utils.py +++ b/ding/policy/common_utils.py @@ -61,8 +61,17 @@ def default_preprocess_learn( reward = data['reward'] if len(reward.shape) == 1: reward = reward.unsqueeze(1) - # reward: (batch_size, nstep) -> (nstep, batch_size) - data['reward'] = reward.permute(1, 0).contiguous() + # single agent reward: (batch_size, nstep) -> (nstep, batch_size) + # multi-agent reward: (batch_size, agent_dim, nstep) -> (nstep, batch_size, agent_dim) + # Assuming 'reward' is a PyTorch tensor with shape (batch_size, nstep) or (batch_size, agent_dim, nstep) + if reward.ndim == 2: + # For a 2D tensor, simply transpose it to get (nstep, batch_size) + data['reward'] = reward.transpose(0, 1).contiguous() + elif reward.ndim == 3: + # For a 3D tensor, move the last dimension to the front to get (nstep, batch_size, agent_dim) + data['reward'] = reward.permute(2, 0, 1).contiguous() + else: + raise ValueError("The 'reward' tensor must be either 2D or 3D. Got shape: {}".format(reward.shape)) else: if data['reward'].dim() == 2 and data['reward'].shape[1] == 1: data['reward'] = data['reward'].squeeze(-1) diff --git a/ding/rl_utils/adder.py b/ding/rl_utils/adder.py index d6d650efd2..eea5f5f49f 100644 --- a/ding/rl_utils/adder.py +++ b/ding/rl_utils/adder.py @@ -122,7 +122,7 @@ def get_nstep_return_data( """ if nstep == 1: return data - fake_reward = torch.zeros(1) + fake_reward = torch.zeros_like(data[0]['reward']) next_obs_flag = 'next_obs' in data[0] for i in range(len(data) - nstep): # update keys ['next_obs', 'reward', 'done'] with their n-step value @@ -131,7 +131,10 @@ def get_nstep_return_data( if cum_reward: data[i]['reward'] = sum([data[i + j]['reward'] * (gamma ** j) for j in range(nstep)]) else: - data[i]['reward'] = torch.cat([data[i + j]['reward'] for j in range(nstep)]) + # data[i]['reward'].shape = (1) or (agent_num, 1) + # single agent env: shape (1) -> (n_step) + # multi-agent env: shape (agent_num, 1) -> (agent_num, n_step) + data[i]['reward'] = torch.cat([data[i + j]['reward'] for j in range(nstep)], dim=-1) data[i]['done'] = data[i + nstep - 1]['done'] if correct_terminate_gamma: data[i]['value_gamma'] = gamma ** nstep @@ -143,7 +146,8 @@ def get_nstep_return_data( else: data[i]['reward'] = torch.cat( [data[i + j]['reward'] - for j in range(len(data) - i)] + [fake_reward for _ in range(nstep - (len(data) - i))] + for j in range(len(data) - i)] + [fake_reward for _ in range(nstep - (len(data) - i))], + dim=-1 ) data[i]['done'] = data[-1]['done'] if correct_terminate_gamma: diff --git a/ding/rl_utils/td.py b/ding/rl_utils/td.py index 01a398f4ab..236b04e347 100644 --- a/ding/rl_utils/td.py +++ b/ding/rl_utils/td.py @@ -266,6 +266,8 @@ def nstep_return(data: namedtuple, gamma: Union[float, list], nstep: int, value_ if value_gamma is None: return_ = return_tmp + (gamma ** nstep) * next_value * (1 - done) else: + value_gamma = view_similar(value_gamma, next_value) + done = view_similar(done, next_value) return_ = return_tmp + value_gamma * next_value * (1 - done) elif isinstance(gamma, list): @@ -688,7 +690,10 @@ def q_nstep_td_error( if weight is None: weight = torch.ones_like(reward) - if len(action.shape) == 1: # single agent case + if len(action.shape) == 1 or len(action.shape) < len(q.shape): + # we need to unsqueeze action and q to make them have the same shape + # e.g. single agent case: action is [B, ] and q is [B, ] + # e.g. multi agent case: action is [B, agent_num] and q is [B, agent_num, action_shape] action = action.unsqueeze(-1) elif len(action.shape) > 1: # MARL case reward = reward.unsqueeze(-1) diff --git a/dizoo/ising_env/__init__.py b/dizoo/ising_env/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dizoo/ising_env/config/ising_mfq_config.py b/dizoo/ising_env/config/ising_mfq_config.py new file mode 100644 index 0000000000..bfe720c106 --- /dev/null +++ b/dizoo/ising_env/config/ising_mfq_config.py @@ -0,0 +1,68 @@ +from easydict import EasyDict +from ding.utils import set_pkg_seed + +obs_shape = 4 +action_shape = 2 +num_agents = 100 +dim_spin = 2 +agent_view_sight = 1 + +ising_mfq_config = dict( + exp_name='ising_mfq_seed0', + env=dict( + collector_env_num=8, + evaluator_env_num=8, + n_evaluator_episode=8, + num_agents=num_agents, + dim_spin=dim_spin, + agent_view_sight=agent_view_sight, + manager=dict(shared_memory=False, ), + ), + policy=dict( + cuda=True, + priority=False, + model=dict( + obs_shape=obs_shape + action_shape, # for we will concat the pre_action_prob into obs + action_shape=action_shape, + encoder_hidden_size_list=[128, 128, 512], + init_bias=0, + ), + nstep=3, + discount_factor=0.99, + learn=dict( + update_per_collect=10, + batch_size=32, + learning_rate=0.0001, + target_update_freq=500, + ), + collect=dict(n_sample=96, ), + eval=dict(evaluator=dict(eval_freq=1000, )), + other=dict( + eps=dict( + type='exp', + start=1., + end=0.05, + decay=250000, + ), + replay_buffer=dict(replay_buffer_size=100000, ), + ), + ), +) +ising_mfq_config = EasyDict(ising_mfq_config) +main_config = ising_mfq_config +ising_mfq_create_config = dict( + env=dict( + type='ising_model', + import_names=['dizoo.ising_env.envs.ising_model_env'], + ), + env_manager=dict(type='subprocess'), + policy=dict(type='dqn'), +) +ising_mfq_create_config = EasyDict(ising_mfq_create_config) +create_config = ising_mfq_create_config + +if __name__ == '__main__': + # or you can enter `ding -m serial -c ising_mfq_config.py -s 0` + from ding.entry import serial_pipeline + seed = 1 + serial_pipeline((main_config, create_config), seed=seed, max_env_step=5e4) diff --git a/dizoo/ising_env/entry/ising_mfq_eval.py b/dizoo/ising_env/entry/ising_mfq_eval.py new file mode 100644 index 0000000000..f688a003a7 --- /dev/null +++ b/dizoo/ising_env/entry/ising_mfq_eval.py @@ -0,0 +1,15 @@ +from dizoo.ising_env.config.ising_mfq_config import main_config, create_config +from ding.entry import eval + + +def main(): + main_config.env.collector_env_num = 1 + main_config.env.evaluator_env_num = 1 + main_config.env.n_evaluator_episode = 1 + ckpt_path = './ckpt_best.pth.tar' + replay_path = './replay_videos' + eval((main_config, create_config), seed=1, load_path=ckpt_path, replay_path=replay_path) + + +if __name__ == "__main__": + main() diff --git a/dizoo/ising_env/envs/__init__.py b/dizoo/ising_env/envs/__init__.py new file mode 100644 index 0000000000..81cae0e551 --- /dev/null +++ b/dizoo/ising_env/envs/__init__.py @@ -0,0 +1 @@ +from .ising_model_env import IsingModelEnv diff --git a/dizoo/ising_env/envs/ising_model/Ising.py b/dizoo/ising_env/envs/ising_model/Ising.py new file mode 100644 index 0000000000..02b8e2d3f6 --- /dev/null +++ b/dizoo/ising_env/envs/ising_model/Ising.py @@ -0,0 +1,114 @@ +import numpy as np + +from dizoo.ising_env.envs.ising_model.multiagent.core import IsingWorld, IsingAgent + + +class Scenario(): + + def _calc_mask(self, agent, shape_size): + # compute the neighbour mask for each agent + if agent.view_sight == -1: + # fully observed + agent.spin_mask += 1 + elif agent.view_sight == 0: + # observe itself + agent.spin_mask[agent.state.id] = 1 + elif agent.view_sight > 0: + # observe neighbours + delta = list(range(-int(agent.view_sight), int(agent.view_sight) + 1, 1)) + delta.remove(0) # agent itself is not counted as neighbour of itself + for dt in delta: + row = agent.state.p_pos[0] + col = agent.state.p_pos[1] + row_dt = row + dt + col_dt = col + dt + if row_dt in range(0, shape_size): + agent.spin_mask[agent.state.id + shape_size * dt] = 1 + if col_dt in range(0, shape_size): + agent.spin_mask[agent.state.id + dt] = 1 + + # the graph is cyclic, most left and most right are neighbours + if agent.state.p_pos[0] < agent.view_sight: + tar = shape_size - (np.array(range(0, int(agent.view_sight - agent.state.p_pos[0]), 1)) + 1) + tar = tar * shape_size + agent.state.p_pos[1] + agent.spin_mask[tar] = [1] * len(tar) + + if agent.state.p_pos[1] < agent.view_sight: + tar = shape_size - (np.array(range(0, int(agent.view_sight - agent.state.p_pos[1]), 1)) + 1) + tar = agent.state.p_pos[0] * shape_size + tar + agent.spin_mask[tar] = [1] * len(tar) + + if agent.state.p_pos[0] >= shape_size - agent.view_sight: + tar = np.array(range(0, int(agent.view_sight - (shape_size - 1 - agent.state.p_pos[0])), 1)) + tar = tar * shape_size + agent.state.p_pos[1] + agent.spin_mask[tar] = [1] * len(tar) + + if agent.state.p_pos[1] >= shape_size - agent.view_sight: + tar = np.array(range(0, int(agent.view_sight - (shape_size - 1 - agent.state.p_pos[1])), 1)) + tar = agent.state.p_pos[0] * shape_size + tar + agent.spin_mask[tar] = [1] * len(tar) + + def make_world(self, num_agents=100, agent_view=1): + world = IsingWorld() + world.agent_view_sight = agent_view + world.dim_spin = 2 + world.dim_pos = 2 + world.n_agents = num_agents + world.shape_size = int(np.ceil(np.power(num_agents, 1.0 / world.dim_pos))) + world.global_state = np.zeros((world.shape_size, ) * world.dim_pos) + # assume 0 external magnetic field + world.field = np.zeros((world.shape_size, ) * world.dim_pos) + + world.agents = [IsingAgent(view_sight=world.agent_view_sight) for i in range(num_agents)] + + # make initial conditions + self.reset_world(world) + + return world + + def reset_world(self, world): + + world_mat = np.array( + range(np.power(world.shape_size, world.dim_pos))). \ + reshape((world.shape_size,) * world.dim_pos) + # init agent state and global state + for i, agent in enumerate(world.agents): + agent.name = 'agent %d' % i + agent.color = np.array([0.35, 0.35, 0.85]) + agent.state.id = i + agent.state.p_pos = np.where(world_mat == i) + agent.state.spin = np.random.choice(world.dim_spin) + agent.spin_mask = np.zeros(world.n_agents) + + assert world.dim_pos == 2, "cyclic neighbour only support 2D now" + self._calc_mask(agent, world.shape_size) + world.global_state[agent.state.p_pos] = agent.state.spin + + n_ups = np.count_nonzero(world.global_state.flatten()) + n_downs = world.n_agents - n_ups + world.order_param = abs(n_ups - n_downs) / (world.n_agents + 0.0) + + def reward(self, agent, world): + # turn the state into -1/1 for easy computing + world.global_state[np.where(world.global_state == 0)] = -1 + + mask_display = agent.spin_mask.reshape((int(np.sqrt(world.n_agents)), -1)) + + local_reward = - 0.5 * world.global_state[agent.state.p_pos] \ + * np.sum(world.global_state.flatten() * agent.spin_mask) + + world.global_state[np.where(world.global_state == -1)] = 0 + return -local_reward + + def observation(self, agent, world): + # get positions of all entities in this agent's reference frame + # agent state is updated in the world.step() function already + # update the changes of the world + + # return the neighbour state + return world.global_state.flatten()[np.where(agent.spin_mask == 1)] + + def done(self, agent, world): + if world.order_param == 1.0: + return True + return False diff --git a/dizoo/ising_env/envs/ising_model/__init__.py b/dizoo/ising_env/envs/ising_model/__init__.py new file mode 100644 index 0000000000..9a4b6f71af --- /dev/null +++ b/dizoo/ising_env/envs/ising_model/__init__.py @@ -0,0 +1,7 @@ +import imp +import os.path as osp + + +def load(name): + pathname = osp.join(osp.dirname(__file__), name) + return imp.load_source('', pathname) diff --git a/dizoo/ising_env/envs/ising_model/multiagent/__init__.py b/dizoo/ising_env/envs/ising_model/multiagent/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/dizoo/ising_env/envs/ising_model/multiagent/core.py b/dizoo/ising_env/envs/ising_model/multiagent/core.py new file mode 100644 index 0000000000..b0da45e3a4 --- /dev/null +++ b/dizoo/ising_env/envs/ising_model/multiagent/core.py @@ -0,0 +1,131 @@ +import numpy as np + + +class IsingEntityState(object): + + def __init__(self): + self.id = None + self.p_pos = None + + +class IsingAgentState(IsingEntityState): + + def __init__(self): + super(IsingAgentState, self).__init__() + # up or down + self.spin = None + + +class IsingAction(object): + + def __init__(self): + # action + self.a = None + + +# properties and state of physical world entity +class IsingEntity(object): + + def __init__(self): + # name + self.name = '' + # properties: + self.size = 0.050 + # entity can move / be pushed + self.movable = False + # color + self.color = None + # state: position and spin + self.state = IsingEntityState() + + +class IsingAgent(IsingEntity): + + def __init__(self, view_sight=1): + super(IsingAgent, self).__init__() + # agents are movable by default + self.movable = False + # -1: observe the whole state, 0: itself, 1: neighbour of 1 unit + self.view_sight = view_sight + self.spin_mask = None # the mask for who is neighbours + # state + self.state = IsingAgentState() + self.state.spin_range = [0, 1] + # action + self.action = IsingAction() + self.action.a_range = [0, 1] + # script behavior to execute + self.action_callback = None + + +# multi-agent world +class IsingWorld(object): + + def __init__(self): + # list of agents and entities (can change at execution-time!) + self.agents = [] + self.n_agents = 1 + self.agent_view_sight = 1 + # position dimensionality + self.dim_pos = 2 + # state dimension + self.dim_spin = 2 + # color dimensionality + self.dim_color = 3 + # world size + self.shape_size = 1 + # ising specific + self.global_state = None # log all spins + self.moment = 1 + self.field = None # external magnetic field + self.temperature = .1 # Temperature (in units of energy) + self.interaction = 1 # Interaction (ferromagnetic if positive, + # antiferromagnetic if negative) + self.order_param = 1.0 + self.order_param_delta = 0.01 # log the change of order parameter for "done" + self.n_up = 0 + self.n_down = 0 + + # return all entities in the world + @property + def entities(self): + return self.agents + + # return all agents controllable by external policies + @property + def policy_agents(self): + return [agent for agent in self.agents if agent.action_callback is None] + + # return all agents controlled by world scripts, no use for now + @property + def scripted_agents(self): + return [agent for agent in self.agents if agent.action_callback is not None] + + # update state of the world + def step(self): + + # set actions for scripted agents, no use for now + for agent in self.scripted_agents: + agent.action = agent.action_callback(agent, self) + + # update agent state, and to the global_state + for agent in self.agents: + self.update_agent_state(agent) + self.global_state[agent.state.p_pos] = agent.state.spin + + # update the world's order parameters + self.n_up = np.count_nonzero(self.global_state.flatten()) + self.n_down = self.n_agents - self.n_up + order_param_old = self.order_param + self.order_param = abs(self.n_up - self.n_down) / (self.n_agents + 0.0) + # self.order_param_delta = (self.order_param - order_param_old) / + # order_param_old + + def update_agent_state(self, agent): + if agent.action.a == 0: + # agent.state.spin = agent.state.spin + agent.state.spin = 0 + else: + # print(agent.name + " change spin") + # agent.state.spin = 1.0 - agent.state.spin + agent.state.spin = 1 diff --git a/dizoo/ising_env/envs/ising_model/multiagent/environment.py b/dizoo/ising_env/envs/ising_model/multiagent/environment.py new file mode 100644 index 0000000000..81970e9723 --- /dev/null +++ b/dizoo/ising_env/envs/ising_model/multiagent/environment.py @@ -0,0 +1,117 @@ +import gym +from gym import spaces +import numpy as np + + +class IsingMultiAgentEnv(gym.Env): + metadata = {'render.modes': ['human', 'rgb_array']} + + def __init__( + self, + world, + reset_callback=None, + reward_callback=None, + observation_callback=None, + info_callback=None, + done_callback=None + ): + + self.world = world + self.agents = self.world.policy_agents + # number of controllable agents + self.n = len(world.policy_agents) + assert self.n == len(world.agents) + # scenario callbacks + self.reset_callback = reset_callback + self.reward_callback = reward_callback + self.observation_callback = observation_callback + self.info_callback = info_callback + self.done_callback = done_callback + # environment parameters + self.discrete_action_space = True + + # if true, every agent has the same reward + self.shared_reward = False + self.time = 0 + + # configure spaces + self.action_space = [] + self.observation_space = [] + + if self.discrete_action_space: + self.action_space.append(spaces.Discrete(self.world.dim_spin)) + else: + raise NotImplementedError("only discrete action is allowed") + + # observation space, called self-defined scenario.observation + # define the size of the observation here + # use the global state + mask + # self.observation_space.append(spaces.MultiBinary(self.n * 2)) + self.observation_space.append(spaces.MultiBinary(4 * self.world.agent_view_sight)) + + def _step(self, action_n): + "descend from gym.env, env.step() actually calls this step" + obs_n = [] + reward_n = [] + done_n = [] + self.agents = self.world.policy_agents + + display_action = action_n.reshape((int(np.sqrt(self.n)), -1)) + + # set action for each agent + for i, agent in enumerate(self.agents): + self._set_action(action_n[i], agent) + + # update the agent's new state and global state + # world(in core.py) is a part of env, created though examples' make_world + self.world.step() + + # observation, reward, done function are implemented in different examples + for agent in self.agents: + obs_n.append(self._get_obs(agent)) + reward_n.append(self._get_reward(agent)) + done_n.append(self._get_done(agent)) + + # all agents get total reward in cooperative case + reward = np.sum(reward_n) + if self.shared_reward: + reward_n = [reward] * self.n + + return obs_n, reward_n, done_n, self.world.order_param, \ + self.world.n_up, self.world.n_down + + def _reset(self): + # reset world, init agent state and global state + self.reset_callback(self.world) + # record observations for each agent + obs_n = [] + self.agents = self.world.policy_agents + for agent in self.agents: + obs_n.append(self._get_obs(agent)) + return obs_n + + # get observation for a particular agent + def _get_obs(self, agent): + if self.observation_callback is None: + return np.zeros(0) + # call the scenario's observation here + return self.observation_callback(agent, self.world) + + # get dones for a particular agent + def _get_done(self, agent): + if self.done_callback is None: + return False + # call the scenario's done here + return self.done_callback(agent, self.world) + + # get reward for a particular agent + def _get_reward(self, agent): + if self.reward_callback is None: + return 0.0 + # call the scenario's reward here + return self.reward_callback(agent, self.world) + + # set env action for a particular agent + def _set_action(self, action, agent): + agent.action.a = 0 if action <= 0 else 1 + assert len(action) == 1, "action dimenion error!" diff --git a/dizoo/ising_env/envs/ising_model_env.py b/dizoo/ising_env/envs/ising_model_env.py new file mode 100644 index 0000000000..70ccea9b59 --- /dev/null +++ b/dizoo/ising_env/envs/ising_model_env.py @@ -0,0 +1,174 @@ +from typing import Any, Optional +import copy +import os +import sys +import numpy as np +from numpy import dtype +import gym +import matplotlib.pyplot as plt +import imageio +from ding.envs import BaseEnv, BaseEnvTimestep +from ding.torch_utils import to_ndarray, to_list +from ding.utils import ENV_REGISTRY +from dizoo.ising_env.envs.ising_model.multiagent.environment import IsingMultiAgentEnv +import dizoo.ising_env.envs.ising_model as ising_model_ + + +@ENV_REGISTRY.register('ising_model') +class IsingModelEnv(BaseEnv): + """ + Overview: + Ising Model Environment for Multi-Agent Reinforcement Learning according to the paper: \ + [Mean Field Multi-Agent Reinforcement Learning](https://arxiv.org/abs/1802.05438). \ + The environment is a grid of agents, each of which can be in one of two states: \ + spin up or spin down. The agents interact with their neighbors according to the Ising model, \ + and the goal is to maximize the global order parameter, which is the average spin of all agents. \ + Details of the environment can be found in the \ + [DI-engine-Doc](https://di-engine-docs.readthedocs.io/zh-cn/latest/13_envs/index.html). + Interface: + `__init__`, `reset`, `close`, `seed`, `step`, `random_action`, `num_agents`, \ + `observation_space`, `action_space`, `reward_space`. + """ + + def __init__(self, cfg: dict) -> None: + self._cfg = cfg + self._init_flag = False + self._action_space = gym.spaces.Discrete(cfg.dim_spin) # default 2 + self._observation_space = gym.spaces.MultiBinary(4 * cfg.agent_view_sight) + self._reward_space = gym.spaces.Box(low=float("-inf"), high=float("inf"), shape=(1, ), dtype=np.float32) + self._replay_path = None + + def calculate_action_prob(self, actions): + num_action = self._action_space.n + N = actions.shape[0] # agent_num + # Convert actions to one_hot encoding + one_hot_actions = np.eye(num_action)[actions.flatten()] + action_prob = np.zeros((N, num_action)) + + for i in range(N): + # Select only the one_hot actions of agents visible to agent i + visible_actions = one_hot_actions[self._env.agents[i].spin_mask == 1] + if visible_actions.size > 0: + # Calculate the average of the one_hot encoding for visible agents only + action_prob[i] = visible_actions.mean(axis=0) + else: + # If no visible agents, action_prob remains zero for agent i + action_prob[i] = np.zeros(num_action) + + return action_prob + + def reset(self) -> np.ndarray: + if hasattr(self, '_seed') and hasattr(self, '_dynamic_seed') and self._dynamic_seed: + np_seed = 100 * np.random.randint(1, 1000) + self._cfg.seed = self._seed + np_seed + elif hasattr(self, '_seed'): + self._cfg.seed = self._seed + if not self._init_flag: + # self._env = MujocoMulti(env_args=self._cfg) + ising_model = ising_model_.load('Ising.py').Scenario() + self._env = IsingMultiAgentEnv( + world=ising_model.make_world(num_agents=self._cfg.num_agents, agent_view=1), + reset_callback=ising_model.reset_world, + reward_callback=ising_model.reward, + observation_callback=ising_model.observation, + done_callback=ising_model.done + ) + self._init_flag = True + obs = self._env._reset() + obs = np.stack(obs) + self.pre_action = np.zeros(self._cfg.num_agents, dtype=np.int32) + # consider the last global state as pre action prob + pre_action_prob = self.calculate_action_prob(self._env.world.global_state.flatten().astype(int)) + obs = np.concatenate([obs, pre_action_prob], axis=1) + obs = to_ndarray(obs).astype(np.float32) + self._eval_episode_return = 0 + self.cur_step = 0 + if self._replay_path is not None: + self._frames = [] + return obs + + def close(self) -> None: + if self._init_flag: + self._env.close() + self._init_flag = False + + def seed(self, seed: int, dynamic_seed: bool = True) -> None: + self._seed = seed + self._dynamic_seed = dynamic_seed + np.random.seed(self._seed) + + def step(self, action: np.ndarray) -> BaseEnvTimestep: + action = to_ndarray(action) + if len(action.shape) == 1: + action = np.expand_dims(action, axis=1) + obs, rew, done, order_param, ups, downs = self._env._step(action) + info = {"order_param": order_param, "ups": ups, "downs": downs, 'pre_action': self.pre_action} + pre_action_prob = self.calculate_action_prob(self.pre_action) + self.pre_action = action + obs = np.stack(obs) + obs = np.concatenate([obs, pre_action_prob], axis=1) + obs = to_ndarray(obs).astype(np.float32) + rew = np.stack(rew) + self._eval_episode_return += np.sum(rew) + self.cur_step += 1 + + if self._replay_path is not None: + # transform the action to a 2D grid. e.g. (100,) -> (10, 10) + action_matrix = action.reshape((int(np.sqrt(self._cfg.num_agents)), -1)) + self._frames.append(self.render(action_matrix, info)) + + done = done[0] # dones are the same for all agents + if done: + info['eval_episode_return'] = self._eval_episode_return / self.cur_step + if self._replay_path is not None: + path = os.path.join(self._replay_path, '{}_episode.gif'.format(self._save_replay_count)) + self.display_frames_as_gif(self._frames, path) + self._save_replay_count += 1 + return BaseEnvTimestep(obs, rew, done, info) + + def random_action(self) -> np.ndarray: + random_action = self.action_space.sample() + random_action = to_ndarray([random_action], dtype=np.int64) + return random_action + + def enable_save_replay(self, replay_path: Optional[str] = None) -> None: + if replay_path is None: + replay_path = './video' + self._replay_path = replay_path + if not os.path.exists(replay_path): + os.makedirs(replay_path) + self._save_replay_count = 0 + + def render(self, action_matrix, info) -> None: + fig, ax = plt.subplots(figsize=(5, 5)) + ax.imshow(action_matrix, cmap='gray', vmin=0, vmax=1, interpolation='none') + ax.set_title(f"Step {self.cur_step}: Order={info['order_param']}, Up={info['ups']}, Down={info['downs']}") + # save the figure to buffer + fig.canvas.draw() + image = np.frombuffer(fig.canvas.tostring_rgb(), dtype='uint8') + image = image.reshape(fig.canvas.get_width_height()[::-1] + (3,)) + plt.close(fig) + return image + + @staticmethod + def display_frames_as_gif(frames: list, output_path: str) -> None: + imageio.mimsave(output_path, frames, duration=50) + + @property + def num_agents(self) -> Any: + return self._env.n + + @property + def observation_space(self) -> gym.spaces.Space: + return self._env.observation_space[0] + + @property + def action_space(self) -> gym.spaces.Space: + return self._env.action_space[0] + + @property + def reward_space(self) -> gym.spaces.Space: + return self._reward_space + + def __repr__(self) -> str: + return "DI-engine Ising Model Env({})".format(self._cfg.env_id) diff --git a/dizoo/ising_env/envs/test_ising_model_env.py b/dizoo/ising_env/envs/test_ising_model_env.py new file mode 100644 index 0000000000..7211be8657 --- /dev/null +++ b/dizoo/ising_env/envs/test_ising_model_env.py @@ -0,0 +1,39 @@ +import pytest +import numpy as np +from dizoo.ising_env.envs import IsingModelEnv +from easydict import EasyDict + +num_agents = 100 + + +@pytest.mark.envtest +class TestIsingModelEnv: + + def test_ising(self): + env = IsingModelEnv(EasyDict({'num_agents': num_agents, 'dim_spin': 2, 'agent_view_sight': 1})) + env.seed(314, dynamic_seed=False) + assert env._seed == 314 + obs = env.reset() + assert obs.shape == (num_agents, 4 + 2) + for _ in range(5): + env.reset() + np.random.seed(314) + print('=' * 60) + for i in range(10): + # Both ``env.random_action()``, and utilizing ``np.random`` as well as action space, + # can generate legal random action. + if i < 5: + random_action = np.random.randint(0, env.action_space.n, size=(num_agents, 1)) + else: + random_action = np.array([env.action_space.sample() for _ in range(num_agents)]) + random_action = np.expand_dims(random_action, axis=1) + timestep = env.step(random_action) + print('timestep', timestep, '\n') + assert isinstance(timestep.obs, np.ndarray) + assert isinstance(timestep.done, bool) + assert timestep.obs.shape == (num_agents, 4 + 2) + assert timestep.reward.shape == (num_agents, 1) + assert timestep.reward[0] >= env.reward_space.low + assert timestep.reward[0] <= env.reward_space.high + print(env.observation_space, env.action_space, env.reward_space) + env.close() diff --git a/dizoo/ising_env/ising_env.gif b/dizoo/ising_env/ising_env.gif new file mode 100644 index 0000000000000000000000000000000000000000..e8a9fdcddc26c49fc0009bd35b8ee9fd8ae606a4 GIT binary patch literal 146621 zcmeFYC{9aQfSO zt#!`(FYI^EkMmn{&6!+d+~bjzmk|^)V?|~~zNtp~d(qR=GcYhPGBPqTF)=eUv#_wR zva+(Vv2k#4aB^~TadB~TbMx@<@bdEV@$vEV^9u+F2nq@c2?+@c3yX+|h>3}bi;I8y z^hrWO;`8Uv($dm0GBR>ii(O~zI;(qQc_k{R#8z=RaI3}Q&U%0*U-?=)YR0{ z($dk<(bd(})6>(}*EcdUGB!3gF)=YUH8nFc`}*~(xw*N8g@vW1rInSHwY9a4jg76X zt(~2ny}iAIgM*`^qmz@9i;Ih^tE-!vo4dQahlhu!r>D2Kx1XP%zrTM#KtNz%U~q77 zNJvO%Xea;x2n!2~h=>3JfglhlIyyQgCMGsEHZCqMAt50#F%bfRK%vm&Bs;cVh>e|}cy1Kgh`uc{3hQ`LmrlzLm z=H`}`me$tRwzf7H4A$P>-qF#~+1c6M-Tm#`x1OG!-rnB6zP|qc{(*sk@87=<4-b!x zjg60wPfScqPEJluP0h^A%+AjK{P}ZkZf<^leqmu@adB~JX=!C;Wp#CReSLjnW8>Ga zUz?koTU%S(+uOUlyL)?ka5#K_fB)d%;OOY+`1ttb1mgMm`JYGO|9=s1*D?v)ZkyNMs6cVl4)sOggq*`i9hAz0Cq%N0}htGp@!Rhd3y7_%*q7|`WvIGv3 zx_Z&u^$_M_$)5KZagfLtcqI8l?r7w|yib6|vxIOACbfk~&wBm@bT=%LA#`-3R3nyI zE!khubb&-jAF$2NBe00S2qwgE;_yn7<8KO1zj|*0!N%?(Y?63Yk|r5}&dM(|Lx5dX zPe7MVhE|+Z&8oI;&8tgZ{JD&CGXzx~yC|Fpg^wE*?PXgC5bAQ^AwyJeOSG5mLtivX z%v|Pz>f?*S49^SiL+i;0(pSI>qOAttg$XjtHu4af1DoQs*LDOY>0bx-OA|AG?n~!I z3KP-Nz3=G@luX9iFGkc1GTRl`4Q9aQN;Ibine>x5ld5Cpaacj&NuvR0yCZjM{Foj}8Mw z1`2ic7%K`8T6)I1gIXkWO76nlmq*+K8AKj`#yM0BoqGk}7&d+q*vNFRqnovN9pl&f zqBe#7hYC6?&m;={NyHUL@RP$VkYrB9-iU8T3Capxkal%sTq4j5Bv@vyKdv8_?^sJ% z&Wv7bo|a3`Zbq!Wm^LEV;3DoyT4yH|6Ij$)3FKclKwWS7Z8p?Fur0#ll(fleCML9H z&(htxW2q4Y*~PhYY}|_|41&Q!aoL-;iz{_o$9Icjj*3G5=M z^^aPk@%dEW^H}F_rntDX@{G=y=GF3boakPcGrr&P9R6w7q-#9B_xVhWb9d#>TKtQv zP5V=^2f-hw!uOMv&f+J9r}1#@#o65F?i-qy5tbTZn$(ro zM$~$ikN>6()K&OAK?Gs(_;5KxCanS{vZxQYELXi#FtUnIrKc;oIk6DV8*xl7_)^04 z1TV5`>2sNSU&LFuFJ|S2A1OOt@@}N`htuFl#v;|WV5{E5l`quClQ>6^TE5Yi9wH4# z1e6Hx-*H(+He_t@7K_=-%d5WfNZ)%=#%0r)haA%JeIe5bzTYMz6M4J70-*9E(<|_s=9N3qlTp0j5zTWM!L~ zs<%%&=i^K|eJRPM9LS;6G%NFs(am77t|}8z`>9kkzzft(q&I>h%fnw&N&ruYLqpuL zpNS-r$RTnOWSpir^P{7=eLu@=f<;za3*O^V$c5m%p4QpY=5PC5$Y#M*F`G-^S;^{X z>l($hws61Q?)l^7v3*7VK-t@M?$znoONE8AU5}!MDmKH}2VXFh=qZJdRXYX$0mJa|4z1d)#v`(XN&WjN2MFe(p*;(>&2m{py zp2~b%XmPEQQq>rtV#>GbaM!4OMb;<%+V5meE`UVlO;U~9{@1Tv!D?Sd(M^&D{Hr+Q z3(u8O_6?ta}j+;&Ula5+c?n7$#^`~DWp360m&JJJ_Q<#ysm#9@^L()sBu(q_zAp0*RNUja5gIqX<_!IDWc?0xc>-X?oO!cq{u!0DT|Zl2T15da z^DH!z5On#6i|dyggQ<6%ZEMfT-(k-`R}sm7Ph-(t57D1}Eh zEqF^*91k+j>X$dyTZ&_<9Y0PgudUBFL`E5Hop153x8$_e+Gn3q2j8yut=}}-c3Qb= zl+0jR^Qt1}xcE%!|5}t`=^0Zxa=xHkHm^P(K&?57AzuAhk9umv8BDyWFMs2VoQKLku<+B`i;SBJtPX-UYKyYhP>b7w*J-zQsSex}CsQ3)x+pJB&6l1Uf9cz@B|N>u1W7o?9PG zyqj_ZPwb;Q`TCB&xFE z`&H{F%;s-Tlo}uDD&T!ceYqfv$6gY-w%8Mc$y<2ix2OGW2Pqd+1%e<8PKxRtY;+_> z_)u_}wd6Bq$b5=_PU7ERU^F#O0sZvn#Bi#W0_=%}v9G&3PI zz(AcVpLc>zRIUKBvQW@eXf|e8{r4~)Mn^JNfO!HcNU_~37 zIq%4I>!|7P5lHX|7NV#g%<%VZF7%k5VN#yKi;)QB>&VGHbsY>ppqzX3uxG6f(9+s( zoirp=)~irJGjcKT0}vEP_7Qf&Z?p$IO$9z*ySi*e}x93C^V80$k87a|Z4 zrvaMxi47$K`FOiEq(!jkxMY?Eb=}65$#^)(`onc&CvBWkT4NFf<7~-d_ZGp!H{g1* z_5%if^*zQi|t(BKvTXuWgFIJXBXMHFzmGbOb6k9Ql(h zHOe*`v=os~oD^c4YOd!qJd|j=6l>3v=FODO4@%S`PxY`#$H0zB7XpV5`(}dD^vmMH z(u0JtQwx0K=?m}A06HA3MzYQmk0HYN^nN8SnOS0*K`x)7`@xiT;(IXj(psZx_ ztXkhF7qYMkrmR5kbZ!JwW&u;mPh8`_Bt=c3% z>gA&n2464`P@d5bmt_;_=aAgz)O+Wma)qET;uM%7mAb@#lTRwVgLcr%J=+$bsD*Aa zVBw#k5F(+zEKDJ6hji`RJ;@hxz#JLin0!-MB_ZfkAvmAz3+{!AerOk=X%+k_ComNx zsOmwACMbT(T-1aeoxYtb+aANJHY2{kz{LxQ>VokFQjbc&u`CNoos`@NkfPSU7e_6*1z zz+65fTONs1_!&bptUZwMHhnX(g6l522L{EoEBt0&%;)FeGm=GyBbK31QJPW7y;v@~ zSy3ln^|q`MX|%G%uOtbhDn%HQCsf#75l|^qnVca|Fj{4KP&Kb#vDQ}QwOn;!o4asd zz2#Tgt6g19YXzK4@OtWa45tUUFL`$LhJ+g{5hTtTW(z@6b; z4HHIJEW?SV%hA(Ab2oy7j zL{dLIG>TC+$*?q}=r>aPH)V zC8zcfmc5cQnBI1H59`Y8xPo=WvB1hjJkn#@zsJO(-8UzWr3bgy+jlf{_9j4a%cc>2 z?WmGnsQ#Vf53NhM&=vcxW4{ixf-V)7E_PqoEN=JSLq!azrFyhmGrF4()U{>SeR0_B zv2`L=wFvRV2(CffBC_sztP*(tDcfjubTh3M}Z$(PFSGp_})o~xc^^0UTHhWO5 z_R>7|zNPAW$4XpQz+43(Rz}wn%FnCj4BD}d-+%V8#8-Dx9w^99n<@48a)=;p!b=9xce|V_QdI7j)I}ZPpP8Ev$A4L#Yqt z-TW>*S|}#WcsRp;3Lpj+>&EWr3b+E8+5l{V#PaP$O7}&80*>`94v~C4kf2!@IoY6) zF0lbKfzf?&D1;MtmQ%=8zr0!Bl`2R|H(b_+*tWf-daA^kf|0zDOE8PLHQAtJ&H%cK zqb?Vr?KA4zUK*&t$XLkD5KBB z_Y29C?DmV(m`CBo-e23xixaGH?1~Fg?3jyjegCZ_5Pans%%vZ)DQsn0b`=h*3L`BP z&>gc1q_O!&DiZ47?N>0BkMd{2OQGPTD2wW{tq@lp+L(lvw?Z)$((949)kSm>oBf|Y zj1wN#3^im{wYEhb9<{Yb|F@hNZ0~AWIqkUMW~r^Y6c#2T+r!c9OId2~sP13uV>#<- zdA(ZJM2l6VfC@gNWRqGAdVexNl4YH2I6m_;Zj25F4jc zziJ#k;%Iu9Z^e*n;!QsjuY{ueXWllMT)*>1SAMpHISNrDwV&#Aco#~%ED@fI*k+#4C>d8mfW1Fy%Fnp8$XiPMz`=j&HLknq06$!L5(XW{nXye zjxl(=vx%vqLZ2fjUwZA>n*{OgVWuB@{!Do2O4{;>cXH|UPo=rt$Y}+%NfhuX-*4to zM%+)g)G9Yj*Kn}=PUP>=cpL#HX`ttykJmj>~}bnR*{EF2U=~ zswq}}OCNf-i8k1{;n4!ly3a;{{L0S;f+A^rQ{mRddD2S{M`W z3=avpC5Ej(Y`xjg{r=OaKE73?h(?}Kj*AEaj;DJ6t`#o#3tc@rI(F@yrND^b)^zkA z`)!(jK?PMvJ=8O)=tl`~1Vg3)GU@(-Sp$0vQhyG{=G9}Dz8cZ9!Uv~(&SxyV9g{p) zPU(I@&+X_dZ)n9GU-aIJ8~N^whF^VhX{;r`;@p@mjeDkzeF-1!{tvhN`lRflFO(y; z%FZV&+=DzB54_gm&9{?Z4|wu`RE!@)Fjd2qHS(oA z6vgcKRmCKeKp?2KbfB-AKKIW&k~O$!D$@`Ee3AF=%9>9!V>+_L143O~@|o{`CcH+o zL<#VYfo@bZA+jmw8jYE=S?DKE%Vg-O0VAbA`AEq4NKzFl{naqrS`*B=g$@vuCV$%lih?KQ`G2r8juBiO(r&4C z!o$Wo`lVL|@T#tTL>$-#XXyWoepOC|jYf{qhb-3gy7oxZN@eL@V}$=2EUYC*OM(Q{ z1R|rB+_IUYvT*DZ>a>t#9cf#~tQ`UVr7P-nSB+K6S9VTJHYt8yLbN-6W}etES*r1cLBx6sFCnMdcW+H zhYD3KydG=qW}e^@P^uiGp41&yK-6)DKAK+Yv!#DwucP3gGDpypH|x!F#b0G^y`xMY zM|(9(}3#gp4?F7<&+^op)sCE@Sj=){*M&oGhz^`%9C#3>TJMniR z=w7;dDL($5skv1qTi>&`@7$mos;v*}JKvtjS|Uz889V&=SD{gKA8Oyph&^1WE{ptR z*nrisjXUSye%})ksOc0D^H_MD9Yq@7I+odesl<{!i7YM*hE90mKRg^BpZLxvB0f`? ztnCZN`?bG0aixsO+;%VQXzB;MkvkimBIX`e%)vLP0*{Lk_#fvmCp~(2?$3ft+qVvl zyy&i}ySxR2?gwh_k_`eUExZHJgMawc>a6#Ef7w38U~)SnVt5|!48v6mx=t9Q9w-nO z*tU-MTIE1oYjl5vue^L*&=9-vjq1v7o_LtW%)R_R8FL*u#o($)lVgxbaM&ct1|#}qB}S12lWPiXYPNkC~}&Qsiwm+(R` zdOnU3C(>0aHr^R#NeEi1np?Jx|2(FbIAO4hH{n0JLN)k5y5dnFG_56&1e4@7mJQV= zxt?mU3IRGQGIA7B=q_mp_nw1rB7kI(knKOZf*Wu^>ML*?^g7i~u8dIh7QmH;#S0G_ zO!W~Y`$*>PPBtC(A7i2B6U5gRE(F)r@*x!ckFl7tqu2GE-Sb0~hMx}+iZ0^#|3bz! zMSWoKWRviiwhrG&36iz(Kp+Xa5dtHYy(6r#g2HsoT?KcgPMT~LZHi1@XCx|~J{Fo-BEdMpa$v#Va+=Fbn8FKCNy(v3+H3<-FK^OtA=^(}%182wuX)$4tLMK&g5!?9($>aa3DG5)wNx$yb2=*8jaWw{WDjmCNz z5b!###7B|SGj3PcXb`S?AP1h5i@1PC2k^%QM7d_90nadEyl*|U_ybl2A~oQ#&vNd_ z@|KS_z_weUyr9biSrj=#JSGT$O>XTm9ET?#`N}8JJH_j*Y$EAmBKzyat+E(0z1TUM z_#1d4!(AK>6C&{sV+e_NEH1fsK0F~u2ZG`YNNEKN>qUMfhjJ`|>E!{1-qB^4iR9R^ z{7g_6xezxm%QPJ@6)Z`WJd$(7H(NF^RnQB`I{8olq~dFDOrESDl)zjXw%wXM)hcC8 z9e_LDNRk`IeF*g}}D^(0KW{Y?#-<_mpEG z#F;4#T<$L^n>@T2)HagV4$279OUwYJh07&4wU!fB9l!%X;T+y$d&Q56v&WKFl|eC$v_|$g5r;aKQ<;iMh5-V50yt_X4i|EikCfQ)|<+Qp<}1?g&Ny zAA9lDuY{x`-pa1%Lt+$aFV2fRELWVAxA%#MSE7$}K2*k@RQcBNVs>MMFN zVfw-Uu@*50g~4_se5`a^cj1!yit>e_ z0%?VUgtl}sv&{76{I2M%*Gm<>!uj%d`EU4Kc0g7Aqq*M|Dp{DSXv?eEK2)RcSItor zj#U%_WvgKo5d4v>w<%(dd!)$c*o8>2O$ z!x{2LHA{9ilXlfr%r#{S#WTJYtrdCewspOr8m7I>R=WrS{~V&sI6TGL9pPFhOt7b2 zJrQO7)qVwaYduv*4U>P>NHL-wkEP+mSi>8USSy^yhW1LFj&fgEJ^x|d({jUGgT^?Y zdRzs6c7u8;kp?o##yX00j?AVniW%$6Bq{DS-|=oz8aZ1 zrT3qB6sxB7TR28rNZT7wmzuBJGjtzn)dX5bFk6KETP}nX75tk~Dl6}7L7DYAD~%1XR=>z#gE{zHrEUX7ieK;%lhHEtDlN0F+3`@B?X0%ekYW$m}od?A+RzK53bvBKz;lv0h3 zJ^l9hO4!O`P1r*X9l{URqgUI|0qd@8hq1uY47z^XRT@_&|9EJ(Q0)HZpB%!{y;|A5 zu2|9((_LcFIo;6}Sl)HQk~GRvYT(~}`{0D~u?Nkt2P2>di;A#ni@6R$tf8eP#P!z= z1mE36anttl`4xtpv-EPail}J|BNt(}h2Y(W@X+>2Dinotvr)LS39IP{PZv?aL*Ft2 zxM=%TD2l;W?C=71K{ef|WL<&$;_6@FD70a`5(9<@#iqiHHxP~o0C8%vUgn&hz;u{6 zS-6zoKgz)Iz61c^g!gfZ)awgQhjaQ2sOl2?FcbKVmWDzw$u-!hpv3Lp4Z1zQU$sUU z-A3?BlvzeD;{YqlLJPQAfA$5=*43M-(vpVz*@_}Sw0%X}wZ7fI3kW2_Y8=`XXl>>}J9F*$y|6kB zq`4p(bx?xRt{NIm;n=!*U2)u60VavWM@{A&s%oKMIceB-I;?4$7#!P|Ga%to#kH%$ zJ?T8}vv)4tJkdYx84W_iXh%t|+i5F%O;xXgMf{?!mq_RFMD|}n#Fldp)`w2$;5T{_ zwgE=yks1?8kwjHJovfeB=*Q+No59kCs>biMd5{F+4=!eaetu07 z@`}~&vo~Myn&;RxMEMpN?W^}^Rn05ZmyGs7}W*90&QV-2_bO@$LIs8Cf z5dvd^fXS_mBbzcV=nJ(dp7&pg5_Q=>+=Ii|+_&)D;eFJ0t`Y0zxiSD?ADh=Hh#!sa z<@Yo~Zj|X*h8KktTDtwI!zW<9#&?wEWgY3i{=^@3nElCs%YLG0aF%g+t-LxsB!#H= z_P2OTYq>S7z^)eg+<{H^!FEJe>?DeP>HP~4Upcu!t|aPMY$nCKk#{qnlRg@Lc&mgx zn$mL~)6hxBW~4XFdd;1>IQyH)F5yzc*rMNUjNL6*_n&9-YEmr>w@v6%cNMiCxYGF3LZ3fKYlp)4$@4@j~h3a_%@;z zq_AChU$o7Os;3?heVUg@WvMU=lSpgP%==SlE6E3&FO`M|P>GW(gzEEK^su}`eMg8Aq??Z^#wYZxvKj`KizHZ|Z`a5(V`2Cj z4b3a0N`A?1DOTI7f%jh?!RB>MEn2myc+B51>YvsD@lWg!Jsa6v=J%b&{!l-O*XAuU zv+jT$tsnQ?vR7+$vXv9&s6qU@*18a$nlB=iD|@3*)h(tYrFwsc;75*dg_6Y#}wq&{QgS<-ltPkx$e|_dl zxN3x6IA8qYWo?*q$8@#~StrKp3WH+*%@K>my0GKA@IZyFqUg47#7<70AiuAYfo;i| zj;?+hR9_t@GzWRuU1Q_z&8U9we^*ngi6^f5jfv_x?2O!?RGw+_vhrt{2!<Bu-@)Px;+3cebF|ab6lTS8@nsF(l((P zd6|LEZ!7KZH)SPeSMaUVx)^zRQr+nyS}0IW3cq-!c<_oOF<|E1X-2{D0DU#r(c!0# zyY!wG-XPnmeRFY@to~j0My@q`BOHUJ%j_08Xq-cIo^anXxJ3FRwxdJ8z$z<^ciouL zfdeUJ;oM0}qrneTk6{1#R!!#GrK-&@0wU{^+O4o9d*^+K!LMVnn~vu|xF;RePipqI z2K)&}U@OOJ{rY*S8J-#bE(FGx(pG_xJ+U=}sGI#~`M3E^Wg^&om;EOwEGwB(O_~%V z;rt8lFZ_~EeU@igZ5gCb({=p53?kg&l#H}H7Gz2+f@(;gdROQ5`P=84z&lX)0UkZM zJK_RP0xT*3+(1@%o}>B?_}l4k8fOfj0w_%%5A-V$-mGEsi!#h zHJG_za{f;9u?~r{GvKNm+%U{GF;FbvaqKHDn&TSp+r8(WEI=x@q7i@pKTHjzxi(y0~vbZNbjaA4hbw{kjsW?(RR znESlm`;5?2e_ntw*qzP=lUUm!-3G2lInPD~UEKr^mV~?)2zgN!_}kmAw#5XEF$m)} z$G>Sg2NE2!!3qY{V} z#cC7IVnu==)zx+y$-|1-_z=V4qmev#w?fu`4-i#?lz8o;*L*yp=U+er?iim&zo7N&E||lmH#YEe&W3=8}tHR!jXC-cGqBkEH6zK{?4Ys;whuFBX%Z^XLR#zWOKSs>qsVyDYF9<+2yO-PagTb95|F7F~Sr* z#uV|RJa!TmK8+2U6$+ml0WBa#!j{NmXymhcZ8KNO1Du9@=WP-<!98H`z<6=jbvQyTjTnr zEqhfiURRW#qI*>;gV7EVFuqLZYs3ZcXo>Dg=hk-y<_TIET!u*4(! z`2MmyMxp#&p<>;87fhi9gO(!q^!)cs8Lu;Ph;2(0%ME2IiWd2cj4BFE4vOqDiag=5 z-0gv;_eBnVxfaU_2qy{-U>iu4qRdveEC{3c-6J#(NUG$$EQ5dGolY*uqjAnHX`Q?D&nu zX%WOMiaz{msi>~0zT}M57hJSZ;sR;?lAT7T8=pi0U$soPP@%L4CPq#=9<)s2+E)gR zS_Z}|IC%_yMWn4@>~x4cqofq?MKp0Yx?$f=Q@wzH^NpJnrGMs9dhT6K>`EK>p)G;( z?_&l_GJvJ{!_qQg86B{!6LQ6egs3$v}74k{6K^uiFPS52S%PenB`mVKvHC zK;itzRYw#5;?ppG`lJ2GDnIY3NkVcm>!U$5FNG=JH!m!F~BaL@sn;N12Mt2sZ)FXa_E3XV~JIAJMt(k(Z$za;VG&-UH7ika9@|&Pd?oqQap3r?!>4dZfo#k z#Y(DbRe~O#yMx^x&)rqNbzRS9JwI<=te@sFFg+s^ggmfh9&tx~>yT%6(+)G0cUtJ# zDtC6pwfKcD&d{^x$m#j2DepH8X>WIaIN%M57M9TMC*qcbaN@^x9IZ4-3UHm50BiQe zgh0Ovxr;MG=%*Qmf2$Pui6Dw2oOZF>i;I-VC4|pmod87k8Bf{O;abD=Re75U2AA z$W%rYl!~n_F$K;*b6G%r$OkCMnYYkvBrW+D@C0ZWm?xjE*iw zfP`vOL2qZ7{Odm`5?KW=2!4H5`jqh{vEnZ&>M|+1@2f-pmBm{KYiQ1UypK>tdaF*0 z@gfaSD%!QJA`8L5d;bYN=GI1?8m1|zbOqJ=v8Pquu9)=UEZMzk`{NFLF3q$)V{x3G za_k<`Sn?;e2ko7K_11h{hFeu;CX3M~P}_5BF5b_P#bkqd@|!+a9cTF=#pXRH-#h;7 z=#Qn0={t)gyxQbmu{+1dtafn=G?q9zN%*IzDYAG*ztHg#xyIMFz&KIVyDJ8*$}0xfWYmuTeeF|?<6+DON=ido zrZiiyxsOT0wm{bob)B64ipg^YUptNyX9(%|ue%byKD3;=a6SjKZ(n`-;Z!4`BZt56 zC;10R*j+<79KI6Bo)0h@vxgf{F}*5n>#57;ij$5pkB`00*fEL}6&Pu+t~2tl+Sr%S8>Gr{OIhpq!6I^(S+nDs+GV&ymODRgVnu^Uhjs2Ow~+VV z8}MY6cXD!?FO9mjSZf=_^nEl@o5W8k$?Z_Ec>w!PnXS8<{EZF7S?gu1l zx+S0@H2SLhJZ`A{mH$}}ii68xKq>!T&YI9F4_?h1ZuUH@3&5#(ve%+o|%Xz2nklzaCuU9;4H)8T0s| zU;Q~pJZy-2-7$|H*@v5)laHs>2o9&t*_=Nsdx-P=4ePxXn)difQEl&9&p&$^cTT*) zw`=0QxBjXRm%-Et_3;5Sd%50^sV+ZXdH&7wAFPAdZhX-h<)%nO!%^mfK@4T)P7FYVyHAt_FzC_~2qcRzUJQTX6B!Tm2pR_ZzKTqSOWR=rr&>Ud zJP~qoM0NE4wPogWx?n|rmUGvUBkGfJK&eM|c5|vq12qnTQ~-|k^#81wvOY1`*WNjc zgh#LK{{?qb9KsB-)pD`@WJFK9{}=8ivEpid{5Ir>o@D+D?xy0_Z6YIIhvAXh{|D~i zY2ewks7*nlC;orKoqGJW4NwdV#J~mq7u+QTpz6iCmHGX=Nl0u4#|b8q>;oWVah1FN zgn9tM;qbKK#N6AU2%liOyD$nMeCdo)HiQX1UW)p(}N)BR3(6k9EAhV`rir}z~ z`T&YjUotja3hMTTa=U`WK-OmINpFV1%{R$C0;z#*DLNxb(n2Xvcv6W@xOf>*RF~ui zm=Z3OhHk4CDHQ$ES6A&WB4Z&f5}4+6m!frJ3r&4WnJ5}x0R1tXgps#AFRW_4u@{XS43R8|& zTBeUs`tg3~f;{kW-}3^LvsRunyRW(jgNC*xuUiK`3ng8Zr{&3K-(lxr-luPrE1}<~ zA`55M$mMOy=kD94VEbh$>!i`a^KR19oqDsRTtky23M9=6prHjdun-33?7#5m+*{Cc z7tDc^D@$8Qhf^p-5h|dNBcESrC{Z}D6C^&G%XLu5GFmwK_XKEkp^|=xY(>5zZBe>c zv2I4Oz5++lSLQMZF^aURkXm##r+u@w2e(8?X zZ)o{QTkH=(#tkC&-vHwGmgH^cw&#zrj1&HT-;+ERt05j~f4Ie%tYY1+-oVAn_ z>Ja}HB-rr*|D7lA)L9=P!~)40BFz=`^R915-T0@SPs!ph7#T6bI9)P`CHOR@JvAqm zao924xk+mt;qgfFjKmsTCeg%7SDI?gmExoxQc)#bp$Rx62?p)8kIS`)`&uN*IuwyQ zG=n+}|2nM9I-HI=)z|-vb^mkEVgG-yu1p3@gQNKm*8MG?t)dwfGra7WijtHM_RES= z{Fvm!V-t{YZ?G-?VqGMFqP(nb-p;<1E?r%MveZVc?^7#;xw5bc!~Uo~KKkFi^RS(; zL*aKB`{U|=rOulN&AC>Zw#~m%SgQWDJqFmb*KbAM&vsmb|5nZ`|5VOb>XfHd7uPH< zZL~XtfKL^?zknU6iuW9yVtlOi-~KCb?m~>#4a{;YoD2{{|3SSv9M)kZk52dyBmOwk zC^G}4>lkP4Pq%SU!x#51j?B@iHkOkYXOcVDh6j`9M2x%xIIkQpD&_D+f6b5x;MGj; z>9aNaX!=t%H|wq_ddz5evo+3}iXUGr8j#v~O_<11wv@X1S6{AV&IcYLR@)kW@Gkg> z9JQ|6y%B9&v&774SRXuRJKki$tiIh!5HR+c$3_lp-NF;9CaQ|<@ACbXZ4wAuw9&y6 z+{-uj_uEd^SZn`Pt}?-;oU!0^eN=z$)BzLP$+_F^PDS_+w?Rce9=7LpJ^sPNto0Xq|?X6?#M&Lz3e=VYUrqwy&?tB*U_;@=1 zEO0Zv@@5NdSp3hDh5rfeTcqdI9uyP~-)j~u1Qxs#U3e;l50-}!Vbyt5Y!UXhO7A}J zx}6~7ER@c0Wlwon($CW+@Qp+M3oaW83n8aS!S`l3c&&X@_fy&kjwUngV7Y;zV*+mCWPcZ)D@aw-h?s4mpHZI+fcD4mMeXo+WMwX0fun*~VekRw*9oz#p9_z2utfPX zrsAk9e*gJ}B`G|^8tdM-icdaR^{ z3EPv8qM`cq2Q|S@MsHoXS!dLv@h*2*4gPk*tMLIX7RB75Sj5@C%=FmVaJod4 z-Gx81QTd^Vud=a%Mv2V(B-yw-0=#Rt65$9r*$9eZj})#lQBNi{O5a(1TE2HuO3WH@ zqcf!?_|}dN%(C^%=4iH5%3Sfs60ga5UTKiHnJZ zSd7YTbs7pz-}&LOJl!AYj3U3TT0MGWc6zT8gT`OKZg^zSxhy-PpWN`SiB+9TMDB-J za%22um9j*~muZ~nrcB=BJXJ;2IgIG$QV+zjU2=t5&d7CBlcThya}2{GAgR^+yxK8T zaTRpb(v~60?)IT_b%&@0Hqp%DQCK;@ubx^t-*sZmQ)$#@)!I?G!|qehvi`@ZwQ-mF z(0f)farpkKG{BNWc6DqqZvLkA+|oXP7}un9*SlMPn?qmg)&$n4+T(xa9Ez8vsDABT zi93iD_(yLxJCeW83h&Gxb6o0$wQd#3U}c2jp;?*TZMUU#J+9*8W^c}EudQW0NaAq{ zC%37YJEbCqdfbfu;6+Kok7EoaZi`HMvca7vxkM2Z3_2_{d@4DlmzqTew8VnLwJ$~> zdxf?P+#6^&}4=6BdlGK`Kk zpBcVRe`2pnCZx30R#_e~9}fM*uZEXr#D{`(P(0I2U_XV zOyx0cQH#f?ooVb+|z3)EZe<{AE3${uh z7Pk<{kRCaFKPa+d93fD2l`ZAVld(=JhE4dCeGqwKu*UOVum*X;%5B4cDbPx=3>|SM z>wWuSPp0j~D}+w$H-q17+ihkD(IA(o2i0w!k+zYCxYN~hO6QvG>w3yBZdTt&O2O+c zV~0wvSwp&e1i=R5fhWhx@rHA6OoXP@hJI&bKJF-Lg)nR;Q=>N3BOe(PCUb9u$+La(+BGM4oeOPK>bdt61(Xo+pt@@ifyx<-Gd*9i_D?XfNtrIig#Cum<`C06?Mulm{cf$KSY4FLA zZ1;*K(Hxxa`Od$VYbzVkt$s8~c`QGVIPSv#d-T}&(1IcOw0AO~(ckzfw>9W&bK}o$ ztI1GNfOH*asS=JWqy?<}~YVAr+{h=K?Rj0lPXQbTu#f^;j5v~)`k-7s`_Dc#*I z-QC^YIn?kC#`Em&FT8vIgITj?%{uQhj!Vu?xA)QxuFIL3%?;G)Ami&|Xe|#9vf$a| zds$_MZr~*{q2d{5A@oScf z;SuHQ_7uqzz;1!VU?4^IXOsG@)djQDRa}RM1fuYU&(P)5qaaNbrDpi-?_ONlo;>Ux z4B1L=;Z1+HI=_fGe5kf~-{r}E@$aihzuL_Z*V4Gl+Z19V_3y*Tx6Id7JJJ_Q4RXPQ zH~sTCYWAW5`J!!kN3yHN+PRy6eWR=WAlU9m8-8?Ceh#=Qb-uE9>#p&!mIIS=xk?^m zlm5aNZsJN-Pq+NbtG!E=nA?4`uU3lRpACrD%nhf#lJ%WGOC5LMBH2T%|sO)K9>jE zlKa=j_?;u$TuuewP1=`~+uy~4n}i)zbwa$!gCB1@?sSDb6$Kw;hkWu1tp)~7iG%>Q zL$U3Hmwm$|v%^~S!?w1<#00|Lb%$LFhYRY2hx&%JA%zaaLV=CxZpFB&Xjj2M$RpS& z!eYTHUj-t%Az!!*9c}d^K0J*W&5jWEi$KbbR6~qx+loZ;i}cxykQR+1oKoTM4%cK? z5$}$eH;9t$j?BxB(h!aGL;^DTMIn$!DI!KO7)C3KMzg#E8jHs8ZAbfpV?I;FXg`fs zqlh-|j>gE2x#^0rFpRW%8jF(?t@1Qniy~6LJ1S_K#4b)dHZCr{CN6OrBd3(IARO?M zS%M?Xy#P*EMo5=QD;{sk-7}S{eg!t&l;E`R&?M8-(bHqnN`Or+y-KN(PpLVzBsuv! ztrYa_qV*ZH5?R5Xd>J%zD>UrzQY!*dZ121ZJ{chthZ!)tCkYsMiLjHy;;MZQ!2X%k zF|#xqpJB9*VLU6~VQ&fc_VA#agS}dQO0)AB`Bo-nDFD8bW9S(8xPPTbPNV10`h=YE zY4@pdsovWPJwW7zj|IE0$5#ei;sg$c&)7DfUyXlnCNpW%Gr^kib;SjHl9Ln5GXC%b z5DChVRisG0G#yniC7eMCf`G%O;<#th-e0HjzE1zhnJ(}pUC1F_BtBiNHeF&SUG(+; z9xngaA1?Saup%Yv4EYa)UwIU**u%r62P-pLkCGz207SWyh8kp)oBgXpNj--H14tz$ z=aQ$F#=kZ$s3!V1nQAl4sX>4S67^zZBC*r;-xQGB-& zwhJ#TATs^j#!HjUaFAZrFI1yl8`p*6Mfg&YZ@Npu!uBdPapZn-rc74O4 zsHKA}kfDL-A+2h9!c~%XT`IoS;S(Kb*+~4*mn=Yeme)b{ytcH5ia39y1sU6kv4?## z@kET9V6Cj5ca-`ppNmfN*iA~f;UH6{OhR*9DPh)nf?uQmd@@bujwL`drr%slH^TH{ zMmjC>!r!FRlx0RUkLGgztCi^`blze!>3qSdXrFDu4GDTN;m~TzKI^Hd23heVhE}bF z5=hyt$Lgcoug2RQ*ssO7(q3Y#@Qlk*9Xa%$|^tZ+A=waJqE1JtdcMcv$)QMh5fs%lJTMW zS?s>PgLWRn$+vqz9za}}Bgz^0$O+8%oD<9Ji_Q;JG(UbSgkdlv(~lnr$%2Mo+dL4h z)7IOzg!yu%!i*x*>9@)Gg#2Zegr#!tie?WceEcrW^|Xh4O{CEK1P&*NVXd^7-aGn`(FQlPT*Mgc-_+UzW%r?tXQQV@`Pzn(5xZt?p~7FyM3OZyE*NF|vrA zNO1d!jPUaj5|-N|Y+dG33K~;X{n@d;!m(D|Ey*46c<%l0QxTy#@u4S;e-a%D%Uv8;MLl`|;j%|ff38>b!aEQi6oM(e!$+a2D;GpE=EYge1M+~VeRlRp-0iXGqX>bTP)J3IX za6rB86~ydwf}=k;zpB_1wbp7gVNM@Tr@c>#22*jt7vV8)C-lu7N2>5=qS@YV70}dzOR{EUMMZW zQ3jh|tpNszCGe4{aG~Fkchct19(BGqJ6w9=o=yZGas-|FIe5IjYKso|)<%&^NO2qOSo4J6Ch2-I%A_ z3v&0cP0rU{hVnq$p;PxPD|e!I#@o^E@7O_;{2pzU7R7cJG)nHJ+8$Wv#>}`}tjJj8 z$euh9%ePaUv?50I?CylI9;0QR1jn8woknkB?YEe``T<@N*^Zt<-t1s6VzBoVv3H8L z7gM(P;3FSOa-TkaAJJG({4Q^;El=ewx1&|>WKSOz1D{@gU+rw4k6k{xTRv)CzLQzv zXP&-^lYqxa-cYGCfG@J|<7z;Fftyt}*b^CyhO2EM;uotAjsS!8^!*O`!C64?=_CJT zpnpu4-?vS_J%0cFEWb3cpLe$ZZmWNapnO6X*ggA2NEgVj`b8bNXAtN`6S>F7wSX#Q zzZ~$3)-I2q1_4E2|AN>Ty2SJUfaFP(hrtmG;1by(m5m&x*PBZLM(Kc@N!3AYwNVxTQjJ4_ zF!{g<{YWa{TRNZ|sJ^DFzJ(3IF?6g(qJ*JVR%C?jB8459H3~wtAfy=Af`Fz;l%H&Q zPVH>u2MBa09soBI5icE)Cq61qD>czbNoV&F`sVM;WM{_z zi5#GpPt$kuef)Q_3j*WCb_?rW{#EW{RJqj~VmsN4Z+G{~g8nI%4OzzTrOuM&8domi zbN%7JmiplBl=e}|?MUo&)b0KWAJVA~3-(UxhU)qcsOYna-9Hz?f>CZzX?PmKzydS^!W{*Y$pj9stj!N#9&hLCStCjir@o^c{j5i=K~2AF0X{8$;7IQ zOjz}FDEZ<|Ss$+__sNh@p1|2KJ+ObjPa;OudYtdj>wKcIu&rW*+nMGfLoq~cS6VNN zr()FT5uDuYx4M0sS@X^U+iAT?Qy6E(YBA_y!KrM&O4Z@0*C;KL!^QHFEfVQ(egFbD4&kC*`bgVk4-721?x!Fse#J}9H zmM!F3alSmbK1@uZz1{uvXyE3!2T0&})Hixizdt0La&uOvXx?x*^~n78V#(^>8M5}_ zgUi*{^G5sYJ)9<&nw8z|?X!BPdpPTfdjt{QFKESX$lT-bfG%E1 znqqehuPM>4iH2)TI*0l?&0A(rJ*q;e%bOR;NEr&v7#C(<2Oi&_TKKkj34HS|GhW`2 zgYa#1hgvg}XkD8bgyKvTdqQt+lu_`ITbCaXYjdJ%V#;>5dO+y?){TkylG)qPu#AXa zXGT~FM73}L=bhD2r^9C^qD7>#(h*KWA-HKH?$3o zo~YkoDw~clvXnJ$ztx*+p^!=fl_j!q06C3Q2W(`}5)R5mxmHE7BnM<{8li|pJU}He z*$XTGiP_CNsA!-1hO8F?iyzPPT2>k&<{#%I2E9idqIj@~;Yq>P7W4H`fRE0PH>TP6 zG&{o~VsdeW=Ri^Mo%RS=6o9KkAtHnFDdve>CQW~~7+dXV@QO7tGYz@4aqUQo8EM=C z)6Qp4l+khumT3N@?Azp?7wNSjxuPYx*Tw!X3OJ+k#Ex^9n~h$Sum(42A)L$C6wG*IQ5Qzk?VEbN_Afo5^uTnJxSA$SFFuKT42vLYy zW4f^m*SzBlb&f6C+W#8;XONzf{!(ag)$PdJri%7e)88YSbUVMy-lMSlgjE*1D~qY5 zVvR@jYw$R=&2i7lgOCa~b~2TET@~gYQP{7ho>;{JZOYO^z}wu~9GRQD%vi+zAEmTw zN3NYxvd^y##o27fi6oh_<Fd>-LWc%#w>QSN%C$U&YilLv4h1#^j480%GS44&>Z;OvarT6JU!kFBbop}QyT6?U0O z)OK7YLgGAkYLrYkz3so8I3Ms%=1DDrwak3k3Zl@@(=>uNLKWD{L>o;uzc}x{?X9lg zM6>Grb&HQDjZxvkwLn~zw+{W1D?4@moDgRrUu zh5|h==1|CcNHFxn0#`L3VU9>MacR+=rmKCuRjeDa6y{_2u%_FdM&$E`-%5Sk=l+7C z=-zX-;r@8?3tX43^QPrJn;X=}@d+{rxmtf_!Uk>24Gqa16W16;$qrS?y-vXmH`e-f zm&KKyEmF2SBT)7B(t#909p~%uSr|mDK{neg zdeiGwHNSipulAJHybhlVyM-z8NAoTlc6cAFE}vBr-$XWRi!LwyEqnVdUwmZnQo65n zmnYO6`GYaodSlJUamv~`8*JAF_9p|ADw+ftfL*7Iy;i}#TOe^h!36SeKVtb)Vl6Wa zyhFN_bFzIR$UT*H{nKDsMuvY@EJ%wqz!TZ7#vq_<%3b)Kf1QYb!Z#PTOm{QP$Qc%GOWl1R zNfbUZ3?d-_VB4`7=;SFw2SXFE{}2gW6A85j&_2;-6w+pLck1bM8UT_%(e`=}B;aq0+8}TEKMhT_3?wj&$|3|0m)?rb~q%B@!>_$CRT_j zE;5ax#j2-U8MR&IvM)@|p2jo_22@3g*Xcx9u&^Mzj_IzvI50*oDYzRkX(*D-`)~xc`Wp7FQFAKd0efO|EI5oed zhbm!qyN^se!J?FBvwm*?9jTzGmV%1Jx|@=wpiDwaxZi42hKWmdT**q@dP20R?R@e! z6VY~(HpuiMOC@EVdd#RQiB`fvm?`71(cD;-OuSa0C@n^=GoFI_$7f^*fB`HAzwK zlrovh?w17wbM>~D7bl=C3D-dusA2|w|AKci=NGLLxAON z(kr_z!JKghS0Tf%d}1JB)W%|R4-({e4F+9I!6Yb1+0PI;!$socOG1Jo7e&7EB8AF@ z>oCn}lf9+DdO8ITkJ0%`nZ(`$bor;bBWL?LQd~}#st7k+u$~tqi~JEH`_C}x%CBM7 zbL;OU5fHduSVegRB*YjLdZ?IC?oOZmZ^OjnUe>P$`zCR~M4Ql-U zog&XbPjuGzyaGe>ype(J%B1?ohGwmkQ%lgW^0tZs3t!IK#SP1vzPATgpPtP-V-3{E z=9@_+B+Shl;pDit9=vSA8*aD7sa|_rwAjYgan?9iA11i3aV>DSn*n6*Ryy6_Pe`=G)4%IoW?ZaA~w!WFsd9BQ>8y{Vq)HHIXOEFnck4&zsbCkW0e>M~EFeqI_gr`cZ_eohe> zwXI|}<7hDKd#mV*%Xf|_$+O+p{(7uT&nB0_+4xJ0z(h=@UXD$Yv7+5IxPj~<$KtJt z%wps;8N6*lQ?#MM{mcv%t4V3l{LV)LuEfC$7E$ys1&Xq?A#3Vq*~@r4)(Q4A?)#N> zNRnGUJ&p@j`Bi$uL5IrDcr}*?cE`}WFD}nihss$XKi{GCcp*70Bb%#c%$u62e0Z~h zDqUKd7G%LoS-(1$z}^Mraykz4y+u+;jt>YfQvn*sYjpPqFcxT4-r`=b%e~Dwt*iQIJ#@4212jkS z{?4&>3W}t>|I!Ts*$ojHcKOH+*}x6Oz~bqY8+w-;hJovIc6XS0{&GwBF2?=B)BO#u z-J47ITw7Bjko&Qs$AGN|ImDH++JjKUgBEOZjpMmH>A~E^z*A+uswcxVW%Hul6C12Y zZy>@^?e>mO?wts?sE8LHvg`8-8Odr6elVY)(l;(-Zyu11FtQiEh$U^OH*2=8tP-Dm ztg8mtn-6TQI3=Qs>#hR!QQNZC@ACP~?rPlSrOa++1@<)*G1SHtw1HUJiFmtLtGnWU zgmFmB9Yw(QO4bKRzFOp7o+3Ve*e1l?bBap#yTVC5peh1k8sqFsgO8yowTN{Cj z170*d5@0ilf*_>nN(Lwb+1ay^H^As#rGUhAfIE&BKtT(K70|>E@)jl^#9|mt1!SfJ z0)byi^uCh61PpG0LN`Ax5z(%B0E$V(%dG*ilPI6aFxZ3u%h~pcoA#bqbf+?O?91ZK zBob}b0A4a30X-ciEr;wZhkPJ80`Y@_?)L&nD`>Bg>$31UKGJfm#v!+dV;E*+;Lwts zN|!wA(pA@ctEC5M!f`5~cWTEWCjcOVI&!xzqHmx;COE%(^h4tu-c5OcW80{8RXHxzGGeSHxaq!k-cymo5Ke50QgO#gv}$-?enJ zLvH@KdftA`))%Ugmx8Ec9^U51YFf@qYE_Md~vK z67ri7g-v!JPMLKS{bZELZG9|FdE8n3YcgF;xmVq`vdhp#ot8h+g#5VPvX|L$CZ`uJ z?~QCfx4DDWpg+Rnv!U8XiSpX_Zwt<{sAx>Hhopq>%0@m3H=KwU!y0h~6l8NRa6 z?TN%&1b|ZQV@7)GNQxOj5?rQB%pJlP`65ryus);+EW_Ej!!5B#g`vGn_vC@KMntkO z0a%FM+_0gqkVqa@c<7gxYfs6ZgnA;UYhpl|z2u&m$CjO+|JxwpE%L#&SndwQeStBx z?Dw(!-HQNlWAdNTZ!tRujUJ}2+}yu1l`yTOPf3W`wghN6#ET$T3?`hg@DRw?d`-vR z&V*nY;89Qf?%9=afXHX<6%`UGdKB@mN=Wm_97`gdDI$nCVo|(l>C}ovfn{*=Q z{@z@M}m}CzA9C`>O45d zq{rnW1TFC*eEUx1i_DZiq(k;|i88ljChymorGfZAXO>U}7GAd(q62iS`y&-Fd&Az% z@jlfjZ8iAv(+>fzr@%*Y@5jp*Ujh8Ti+>JciSR{-+ zCckAq*4l0pb5=bS-kDwy3xt8$(oq?|y=MX{<6Ky_Xsi6)4)?6|c-bh=vZt^~rLf{* zlRJ;rZFeZ9+4+jSnqGI`aTBt%$y!~A{iH~iNm*mt24cU|hyCos9yiu=#lrU27Cv?Q zUylnR3Y0=6mtQ0naiq;#?}O5V%&Aw`mt#9R9+i4JqOK}if;zYP8T&r&X@8K3?V1KK z`uwP;Cf;Osl2I^;{$RXLb12g1UhfbJeEG4Vy>jBILR@zzHzSh^Ynq7c>)Y~bJSp%w2yGeHKEI6Oy%U}R;!br{>J;X7+y83 z{y?4(4+Kbl-m~USEJ+;fZ9*lWKgWB89Rs&Xl37z|(=@P+vZg33XLn!&wBI z-hJ{EibZ(#hF7px^4eTcwu&%c(~ZbB`N*%;$?1}3_w5{Es2s@>roiTORLJ|2^s29a z${XLa0XOr}P*At?h|A`i-X?VY|1Y7&9QM`0B$Xp-x2hqK%qDJ(&~r$_r*&ow|NbD z(DAax#xvI@-$U2S+la-jR-kJXj^?$Z^Ky*C!KG^vwrh~SIq|Vmqm>ISncNnc+oN$Y z>?t>eM+|9pZUw&XN48ki7qUg0?iKpt?+omNGsP&_U3NM={B_)4_`-_t?w5!jEaV;d2! zmtR-5d`>xEGeoiJzHpD)eLrb0kJj#DQiHbw+gHT!o*<3VrRtxB)>kP zfr(fJFF>cw7yoQk7I%$DnAZF-5&MmPFqNL;SWt^uC|*fzQupnQE}*i)8ivC1kYT_9 z_;8d6nVtz*j0F^YQ{S#o9|GHa>9p};WF$THVhvUXy^{au3N+paWjDWk;@>ug+-^~D56WI~oBBT(TI}8Y;sGJ5{Y;|Yw{Dhq%9}p+ z?pL+`A^dbyF175K*6uaJwx5#^+t2-4D%l3e44w@BZ^F;_gu|>|bd%zYUxc5!3(BLP zaW7Gi+k$?{)#4qhcFe`z%GEqf7T5X-vh2H)iMvAU{S z4Uj~%F?Dj?qf!ohBzR*z9EKHS-6%}gpDil&e9n5z@1vwmgRF*g?#LI{go+6TJG6sI zMPC}$DjiwVi|LWfx92k^AE+$n#;zsoW~~-!E}m7(^wHfOZLwfX!w0P^JP|= zQ3fFW0UxCDR>Ln7W!B4Ng0F_c%n#UBlC50qx6+NI9NN887IL<8sjlsIr9IJaQi}%F zEA}cUc^nR+fo(VYN%yq%wK>nt>$58eik$X-(j7V-0(t0o&b~>T^X#{46!G*-n-@8s zEIfPe0;vy?ZrtBUdG2_ZkxCv za;w4#Z!{q)_}lREe}BZJ-;B&^?h%wn*!~*)Go7Z`6>D#4^F6Fj=pX7qQoeK`Wk7`{ z75M3$){iVrWUN;Q(j>o@lyE@2kF+FEhVPG(osgSDMVf_pNQlna|6WuPz>0$KhW&F! zB_JAbn<>IcKJdk-EU}3j$my3eU_&Moe_$=XxN;S3KN3N80j&qh zp5#bp9F?VrTmgB5h=$y;GQK~-M)?RpiS%Y11EM>VOA}FkPJ$7AkZfKHt>+8}nXQ}R z&+7~G?+k{8Gk+)Jq2QCv9SNi@$RKy7kWi!?jjMfO$V!7EVwL+Tx-`%cgGP@k>J?^l zM!}Dd>!hFGeUwpc=)~&d zT^MHH5wpX!m+4L$35bbvbSK=`Tb>MTQ!7aRm-;gWNOMzcti&3hNN;SvX%r$dTGZYO%IDHM82Sa(g@LV{k2GqN^r)8D90<3U(5>A zI{H01`}sn2iBI!xX7*JNR-k7?wgBzy@1Alor9uLi^6+(K-iRcbmCB7;l@M#S8rO~n z>{8v*`zn)na%=N2BtqhFRU=a!or_B5;@tpUBUF;k?GdU50E^x1j;9zUEl0C~wE8D4 z9=%t<#nMx8$(ENJ%HB+YET~rOP54lHSAOc1``6WNFUT1D`9Le!#!Bt93xt8%ZE#ZI~E#97R@Yrwm1_H;jwDcrCo~W%8Gk z2{Fw+uEcEpD39?R#D}PfQ9NH*+lN<^Phd2JEUW4MD7*N)0J{rw2i*%B^^;ez@BT)x z>cwCCQkRKqpvGtC4cQV{R)CLpqOmf^=h?Ud=qCcocRtb?*!-Qcc3zN#xjtcjt6<)8 z0q)ab!)C#u=8B5l34XcVJ=&PV=1s%OK^4POmv8UVa28Mq*jtGUjeOYVmY$olwey); zIKsZe$%SfrD3{BzTNw@U+8k31P56o3J?i=qGek-m-zp*nZDYT@=G*cYD}Bz`O^(Ye zC-(!%C_r2(PZQY`IJucO>)EED-Bmyuo^=L6T-`d;_2?v(L|g*wr1E4c3;URob6M-|ZkJ;(z&l&|Q zbhRUciOgM+CaW%u>V%ND`k-k)*`7yp$JSO{X)O23L&Qq^sU7vr#?|)0eTip5`gemg zgUo|CZ!Ufa^URnWTFj*+U$|{JcT2ij&Z{Ux6ciJVmHQ!mfcuT!5QUS7dxzvN_t#T{ zjgqp^id=&4B^UFk8rVZKY;aS#GZ)#Tt zaiDNIAYD%pl%eQ^4R~Z=lr6+R;XyOw0gyZs_-qX*oIuGY#RwDxU?Urs3K@Gc(ym*= z&L#>fmkX*{|2bX2^uxG*!?>A@{K(@$5q|XoWMwGfW`AMPGC^=R>3KjLq0!v%Z5%GgR^9}pNB91HfJlK!70 z{BMzj25G!Jzj==^NhsDMlbLAiZ;+ns^B@Un|A9V6?NFveKQvInBq8O0O2Yi_P|CgH zq<<;_ZPBky%7%ns$^UQYV>x9()}YxgO*!%JLEVr2s#x2AgWB?7M4t-S6#~+_m|XG0 zhP2ne9n7v8$a^F6X2dM2hYD_qaSt|%5= zBtR6)?ng0m$K90A0x_#mE9R(s8KrMd`WPmusrxw-oR~_`&Tpv(KjOt>_C3R%KM)g} zy*@4GW4ogq79uLZZ>Z<`N}E?!~4&E$RG zqmAW53lH|}K3%%x72(4S4)J=*uzd9ijDZ~<;*Dgn{FD?_gVj^)z??6KWUj=0bzbBR z<(^YV=fP`~IAj4Joapm_(3RBX|Sskhdp zb$#0R8ofP+jv|x6k)uzCG6GyiokWpxRgy|LN;;OW#|#kZGZC{&V9m>5s}Us^#VSs$ z*COPkNE@(e%t$&|L*ZWSjrR8z6|6IscCj66a4-}_j9AIQlnQX zz!Y^oiJ!o~2TW<68lh}}IqN%Y_t82Hb2nR<3Pr}(Z;a-3#g9X&+Nj7(j7aMCO=0<- z`q-YxbmpXFN%NT=+!pIB=$;{#D~jB=nf}!8R7T?EakBFbV}4?9Q;$M(N3*Z#6D0)~ zWYY}fAGEK#KCAw`rrUYpp;9~fr&1fp#b%+WSodbz>@SOcVjthO><07Pg{|I?kj}8*apAhr z_HTLi?ul7r_qjP0?XcVXSfZ!gkUa~FS&fkFs^3__PqVX}r}bNc`!*C3i|=aBS_$>u zT=G(LA`(PZwA>4UA?gSLxp~Je`@ENM@-lu`yH#(93Cq^M(z5>+ zhSq?ccJ+hD8cY`7o>qNB1Ck$FJ}6BmFTllPb(vTV77MLMpDl1;-eWOc_X-`yyN4y& zSBM6@-dkNnJ;0kyivl=HA{=rU zY`Ul=yTz+YEdp`?4(o&0iKP@!2?~H+fUm6%sGkaGgakC>2DY#VwkZX6fC9Vzr#HR3 z{#*1WEI|Lr`A>lE@BpIQ+0Ft>p*&cSl-nZz0ir85qm+eNkn!99_D~C&Z7Ge4+g=)P z{mstx_sT-hpY4|y{W*f=n>S|bxR<}+bMyE9)i)~I@{z(_+6-cM_lMa0>Y!|YA@4A? z%ZD(O5{*6eps{j8{OIQ|3$p&2^XO;EYt)iPk_Tc#K9rN80Ly%jHVeOX#-eN4L&7qL zI7OnMn^HL7b1!{Jk7eI&qr_={>_A{yKFBK?TImwS^KkfJtBbILy6`|M7J?md^_*uD#Zg(g&s!ns%7;($Fn~LPtHP~WZyEv&RHelm}LI-%rWKKsi$sbdKLOLH@_6!7#q4v>G5_8>A@ zWib8B%NI}%yTbm!+}v7*a=5UoY>{ne;{Nl1ZzB&3>NbRzDn7PLqVWyZiv>_l=X+;{qf>0l7q zvoPn6FPsFS$`R{~WE_)+tg7qojq81-YQr<33Nt%`jI9S1SAL2XZbvi$&oEA=Z?KY?Zp zUc>f`cd1h?jOed|t*DogPjOASpbRaz)N84aYr2jc8Nyv{*GLzoyQPBFxYFt?$YiHg z6dEnJ4D#1Y_-cBoHW*{$B-R)vtNZjO7@+Z^bJ`4LHD($vWsnK#&D)Wh0nrPFs*p#x-2yDkA@6PnBzYXaX|W|A?J^L zN@`Rr{%Xj^)4RUq^^2Gc-YkX5}i{yk_P`jOW1biQ`2 z{yj$zU&d}!R%{9_U0jbg{!-j1w?1prm4|5Ismgl&=IbZGA@R=BABvDoAy<2maP|D? z=kwdVz7B&Kg;u$Xb34qP4t*5|mW4%gyW~h*!^V<^>5kMB+l}r4TG+3K><92}nB@bgJAg_zPw{T+I9PYoZht6@;N2{e2E z_H-EFEdT7lAudf_ul_mJvEu&Ds=hh|Nv&~{r{F|k7ShtE!G&A^9fZW=G+hilZ`|{} zr)>|oC#~7MIr#Bm>Co=kMVbE1l}*$7^~^mKGS~zS3D1?Upaim~^K-x}hYKo4+W-(D z#y>ORTBCtArBn^20D*Ks*M;&AmMtt>rpjg4oGTeh6*Dd$6Z%UP zC{oy^DaCQ7Iw<&KUk>kA@8OG?)E#-i67A`SMEkh%#;o!7Ark+cXy?zGSKQ#|7pMJ_ zlMPU#qn1uGiR1Qz;0KU#ISO?Lw)C?T7|mF$wD@I;Q*k%tY`kUfRVnIeF>1d_*$>7= zRU>}R!9=UUlL^%Fo)6Dy_CE@xs9KN2p7b$yiGNVb8I_TJV>7-)=2bCHWtv1Wu72uh zGZo+=$y%?S5|lk{6p~;&OZp6rteG^TThK?WZKTmf^s}mF*#vX%mwD%(#Zkx zt;(!m$AgT+0mrSz`vv=>7JVtF<0ygy2n$T#nyOE~$`(YlJhpvIErK}? z5@OCg*8Vi7g;xg=nu;3sYnc5yz0-yH?)8v0g2W4g8{E!!2r?noZ_>LUdO|1fWJ3K_ z)A5eCx`Y@R!(Sc~y?JOu91+^8H)LNVFgF2W&l;5hAB$* zS-De_(y00MNOs70Hq2#E12`o5*BP~2@^$I8o^s0&MFi&Wq0I$TP^9G_(~Mf{u>@F3 zR_T;QXsl+^RGsvHZ8RgFUlZeSui;Ehk4Rj81bpm$B9)mh8@vw{*ks>-C2bWxlysxo z!-IB3Vf;jn;*q58`)&K7|Hs~2{#Bv4+rCODAStPY(%s$N4br8A^;w+4sf1_r<;E?Db!a=NaQWMmo`0tmx<_!}zqUod{DL-y32PuhijS zPU>*X^?E$SKFU;QyOw#qUq9qK!=5w>r)=;) z*rAG*JnBzodbAHszRyaZntbU_Q+dbt#@HSt+^@m;{m zW5GZnTF$i5C|A|__?th8%G&*pI-YX?JN=rU=sBr?m=uLhC6DvtYVP=lu@72a zb-OCJ6jAo5%CthJ=%123z4dXEfZBlAW$V`%%J|B}5`3DBTuO?K!zT#NbA#ulO+IaIZCKSNq?oWCEj~I95bMk!RS)LXFbzGbj_s6O1%>uUOT4C z$(*~ozOAHJ(?f{EH2k4~OU?St=xy2gcj9{iEuHU^B@3rR>VQp#%b+P=jLJ;QU|yZw zH&fU)l|SONc#ZA9PZ%p-l$0PC0!~9`Tgq4_fu*}t)+iZ+ESIRfC#t{EpztZdp8HKk zyY#Z;2QA8k;>7x<1lM@q^fz%25!Iy3io!Xf(e)U#gv;!+nY^9DQ!D(-P|v<92L&ho zyby@_owO8k1(+iZtrb*zVM9d(LUDPnuaaE%G9pg1OZ`O2^7nMNXe<^yysIU>1Oq`} z9!RKdk^cpoG^*>dt?c~DuOz}!EoprtYuwKozc}P{NbK@s)AxQsvd##K>{rCs?gM3+ z=T-+yDn?zbtefg0P7CcVeHsq6&N-Ie8D2K8<{tU7mM)=&va~Vcb)~p+Enm}I>)tmU z#!i0OIBayRwdXlV?)*|+D}7z7OEjC2b+#?uF2=B5&XZPs2)}6*8$i6vt{4hM>u6sA?+y(E#G6l5gtcQznTf9)| z5x(d&ADVnS9(#M`gt>Le2I`fGk~rb=aaH4E)a2WJ>Wy z!n8zXCEM_%+3`eW5E5kZ7Gy2a>_68WW=4J6X^HpJ%2R-L1}rj<1=&2bn#a9ol~8Y) zk--s54+uI4K{|FzA@On{Ef}>`CGAZE)Lvq1CPQm=&lNgkK~Hvk;Sc)4s%L%$N7~2C zIuTpee55wsrS!Or9&EoemH-E<`*R%}GSu4)8>vkjq~A)i80%{(+t>2{>T`*Q{%`&4 z|LOI!f94P$c%T1+M5c8nSY%pfFf0b03UFNZZAiPzmp$#V>yf zAJclFO)o)HcQwO=9J&&qslTl9<%jj9^PwP0X;OD+foPFafWb+T#<*(1P6hgaWYbb0 z<+obJpQFfo!-=El#R>&b4cig?E}HeI;tF>n03$;V*20HA;G)@5T}*n?ztn3RTgRt> zzcHcejNnoMSa8v-C|8RK(PPmp&rP^B!QYD2mx~CA`*9HPV;T|vR2w0X!9UTtiZd@B& zq}|2kQjF+zd{O57V2@v&z)CxxM8<>evdAGRF}k%eE3`ZzF<)3bk<{|bSYfor=>ul80U4iPPrdY+V~ zSxF&2#@gRgVOvuCJ88-QS{Czo&TSA`YfwQ{&Z5-voE1z@$_Q;P!5s`%(0gPqi}%mj z-_@uHDX+^nICP5N)w)cIYCLYIHDBKiJM3WeoxvqOVF?@yfUS0v zBsOtHlA>RAjA)jUqLUkawfy2RstLWa*gKSV zz`i}ol-{}Il^%wdsvlZmNuz$g-T_K=r(rEcJ=!7k(XIJw1d-QHTHwTFOn?68cn@&I51TO|;BJ9Ed9U9t zq&Vi3Yn}TvZs79XI(eGPs4b&rXsCrTb)IZf_^^671fwjOuwjEkk>j&pqs=Wzfw4Gh z?dXvLQ#PsDwmc)vD0nm_U9n(Ow(M3MtZW^O zA(R2uTs0Y>s{;@h%}Fk>eyt2h)x+7i6AgK_MuSA(r>89-GYYPQYq}m#FSN$AuG(Zk zVjr>xo~GnYmWjC43`Gv;L^En_qq}jm4^r6TM9i(HVmMClHrj^R-w(VFUYK-=RnEYe z2mVT&pAwC+n=Eh{dONo;i=bs!qch)GjJ`1UTuY~HlM4vYnO|V;Qz==T@Bd`Du!N%N z(EiT#vxmz3%BO;rH${pkp}&g#xxYCKN-s=BzpSwqzP#3suhvgo)ZAXJcf^=*vB{G? z+a^4$p7NtQOK{`fW?U><9Co#=3}rjeT67pZO)@W&ZP@T!-1*F!n48PXlj&!EQr)V3 z6HQXNbqfM=1Umh?T|#QQic6(XuAv}RNY|AynTIR#RLW=k^sB&{n@sDtM}>1ZRmSyx zqI#gBkg?gVnZ@i;B0d-4I9Bl(hw~yv_VrPvZ*~U{uSq|uL=kZ0krf3{Ag2}^t;YD= z6P$OPWO-DH7DS>p`l77#>KV4`In1bO>wqP2t_XwdEcL- zV~{-~q=Sk?^)@(D-WWhH-n}ECUHTMAPL@zh?KXpy|J_YZ!z`sh9E%Rrj z77sen+LcXSJT^*P$ln4iFONu3moqHjH!W6G9ukwd4~fZY|DY-VkSqT%tbho%fGE{~ z7>9sw*(m?UDF5d?BSXLcP1ZP(KiJxTku~c7v9I<-*8GR9%|KxawzV~O{<5{rN?Lg+ z_sf3-qWL00M$>_9?TNR5swLl7KOak#EGP?e7Qwc5Il+^yT|zvcM_d2bs#@)>-3+i9 zCY0kLOWB-P1VvhJ-1u50|L7r0`7EzVor_)^&ktu;f*@JKvYSk>$G9gvsqdsWpb-AF zkLfF=bwAst)LuWwNr5js7JN-Eea5`dA)j&G~>;$hCSWPzA4cTpSQ-kK5E?wvsTwfl5%?8W? znq^;75cy&tYa!E8h$xVJH9}IxaXmyQq-N#2InZG<=@p{WmTRa??LuZU(0(Vkx8G?O z*o0U&Q#uH=+pqi@{N+IVaG-9Yi17?O6iW+UfNiI=xf|{#E$15UCp^0w8h*#rFf@*B zb3f*fZFYCTZK#8MwQSE@da|}j#lydyXYQKWQl)cxgWJn{npo9g{wwb)FaH;a@6}_j zk;rWk^5Zjp@T}Mxl*g7LxUi4lIX3Q)8*J2%Y>_7{rVUynh93drKO&CEHc7Co4zH1? zp8H}2Ex|Wn{%#}!;VeNSif6atw#fdC$msfqnE0c}l0C*9+hEeJn#f)I#Ob4wFhgOo z=+w=Fz7c#7vmz55$tfW=LrcS6yy6iOKen;SUmdNjuHh0muoT`)dnf<8lX1W@>}46@ zJ9@BFj;8R%!7RP^*>uN{xK+g0+Esko8W95J5$gn;Zo*E?ZaGi=s6EOIa&FI_8#Sxw zcg6;7P_VrrU8U%`dBl|5$D!-l7cr@->_gaDZ-6W41f`F=$0GwDdH%` zo)O>ssYr;D1N!|{BV*><#8+B!A}u2n6OuVMrTcPZ$X*mCYB-Z}8Mh2LcBCg=fSh4@ zPGLK3P85?tcZR&LNafsLm;cC0z!M;~YVeUrPeJs75hC0P3sA5Ludg!_M$eTG+9*uJ ztH2eLWUCK(zlvIP54=g?Cs^1sD$!q%-gsef`1Nuc}pflFhvG1>Hcm4 zy<&RQes5G*;4(#|Gi4CQe^cE&PgHkq_RQI5W!h4uLaR1LwWDp+R61lBoR(Y`gDv&4 zn(@%Kibrq;zuYRk;7jmlje81}S~w_(fS;5KDDe|o7vqF(PkK+FG_b|Q08pdacXRd{ zVatm=;-}Y#5WBP@V$g;G=gFkuxf4?x<>kzYR60nn7?wt;OJ<1*$$}-j zB8*E58Y|4Yl3vZ{?UZ~RD=4&xzpV%}vDch*iMOxVt!u_TuVdl{+7Eu!K6+tqwpsvm zG>)FXs6B6h%`0-*4}O{2+dfnf#`a)&_em?n{ahY zM=hPNy~r{`np7)ZCAz<$)FNW!lpZ0ErN?oe?&kOE_G=gVpc2Z}H^~JZEUqen)>6Xf zCsXZIU|ZXcYK>{7x(k_yA%YZVjd)kJTV{YRs*Yr-Px_6+3q&$|;n;OA7IvT#5GR~^ z4jjZ~w=;;@1jWr_d>+tZHw7#hD(qqyQgezq=V!3-H zE&lMCHe7Q|&-z`x2~napLp#i*VWQ|V6NpexUgQ6n_LOZ!skjoH4qy{bqNO(3YN$YW zL;uqe1P@=n-+Fd0^$+dmv3s`ty{~-zj8C=snJ`+sbLR`2(!c!awz6hSKn#5)`cnxf z;LDeJndvHxW$0IA?k}P(3Lr-BmxXDq$J@$SS^4M7c}3M~>_PTHlT;QY?`oGWPgq;@ zG7o)z?JprVVYd+?()cLOt)O&Pw=y?cgb>cHLcgr}2@(dGM~F_Z$%tG>D23?9U{0?K z_+Ez^4CsB|oZ4_!Hg30|*;4)*yTn0V?up&VnCq2ui`{F=z_jmMqe~<+(eI*O1oWwmKAI|oH+{4x?9Oc)aeslIG#mt zSn}h%7AbOA3Au1ymUd(7C5%6dGrWfo)^Tb-&^qP*oO575c)M_`O^~CmlxM~86Ji5u zq~KYuTmT2^n&kHpub%Njr;5lIJKi}m0O$`HixT7CKPHbRx$2cZo1jYkAV->kxU1Uh zH1RF{*I170YDH-Ub%M>27k)jgCbkB+5l{bD!F$v4&!&&&bGQKIm;kK}svEkhmy#;u zu}b3$Gw_`Bqxt+vknLE-T1h2b3ALiate*s2dQS%tiOK^dB(UbrlcAQduEuh#GHwT$ zCLx1gr5lSy1^)}dgbv*lTy}`fVcs~;H27FIv=NU+nWX?JFj*Vw-R z9$$RXzVi8q<*Uo)tFP+&*}>Q7o3BZ=ui2C@crDxF3i)5D_diGKg^Bz{%z*1OQ~vnQ zzloWcxBnsaz`iq>nBn;+F;n#O1?67x*T0Dw7I3-!&}WXv{>(y=y#2~K0nW$HpJ_YO zgPN`HV7Gbv!EN5|pggRPd4y%eYR)cpi<%zM>7K(T7}7av@!#66k%H>DZO~5QxE*WK z#Igg&o@=KAZ*W$wD+!!ntR+mQ+Lxf{jkoGOFNJ5Ur5)tT>1Hw2upS6o>9cN!zo*I> z6hN)B9&YamVj6lyy-zkQ^UKL*%vV7AJYP`}a6Vr08TWibvuUSd^rN5FΞ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 k0gwkk9sqd&v^r6CM!#AL$#o=l}o! literal 0 HcmV?d00001