From 9ad31f7398a970b6b6a89728fa0abf4608f3b004 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Mon, 24 Aug 2026 10:59:51 +0000 Subject: [PATCH 01/23] feat(pt): add charge density prediction support Add a grid-based charge density prediction task for the PyTorch backend: - add DensityFittingNet, DPDensityAtomicModel and GridDensityModel (fitting type "density", model type "grid_density") - add GridDensityLoss ("grid_density") for grid density training - support loading grid.npy/density.npy in the data system - support DeepEval/DeepPot inference with grid= input, returning density - support dp test for density models (DeepDensity and DensityTester) - add QM9 charge density training example under examples/density/ --- deepmd/infer/deep_density.py | 121 ++++ deepmd/infer/deep_pot.py | 5 + deepmd/infer/model_test/__init__.py | 9 + deepmd/infer/model_test/density.py | 93 +++ deepmd/pt/infer/deep_eval.py | 90 +++ deepmd/pt/loss/__init__.py | 4 + deepmd/pt/loss/charge.py | 137 ++++ deepmd/pt/model/atomic_model/__init__.py | 4 + .../atomic_model/density_atomic_model.py | 370 ++++++++++ deepmd/pt/model/model/__init__.py | 5 + deepmd/pt/model/model/density_model.py | 93 +++ deepmd/pt/model/model/make_density_model.py | 657 ++++++++++++++++++ deepmd/pt/model/task/__init__.py | 4 + deepmd/pt/model/task/density.py | 102 +++ deepmd/pt/train/training.py | 5 + deepmd/pt/train/wrapper.py | 7 + deepmd/pt/utils/stat.py | 2 + deepmd/utils/argcheck.py | 70 ++ deepmd/utils/data.py | 8 +- examples/density/README.md | 179 +++++ .../dataset/qm9/C7H15NO_train/set.000/box.npy | Bin 0 -> 10928 bytes .../qm9/C7H15NO_train/set.000/coord.npy | Bin 0 -> 86528 bytes .../qm9/C7H15NO_train/set.000/density.npy | Bin 0 -> 150128 bytes .../qm9/C7H15NO_train/set.000/grid.npy | Bin 0 -> 450128 bytes .../dataset/qm9/C7H15NO_train/type.raw | 24 + .../dataset/qm9/C7H15NO_train/type_map.raw | 9 + .../dataset/qm9/C7H15NO_val/set.000/box.npy | Bin 0 -> 2288 bytes .../dataset/qm9/C7H15NO_val/set.000/coord.npy | Bin 0 -> 17408 bytes .../qm9/C7H15NO_val/set.000/density.npy | Bin 0 -> 30128 bytes .../dataset/qm9/C7H15NO_val/set.000/grid.npy | Bin 0 -> 90128 bytes .../density/dataset/qm9/C7H15NO_val/type.raw | 24 + .../dataset/qm9/C7H15NO_val/type_map.raw | 9 + examples/density/dpa2/input.json | 117 ++++ examples/density/dpa3/input.json | 107 +++ examples/density/dptest_density_script.py | 185 +++++ 35 files changed, 2439 insertions(+), 1 deletion(-) create mode 100644 deepmd/infer/deep_density.py create mode 100644 deepmd/infer/model_test/density.py create mode 100644 deepmd/pt/loss/charge.py create mode 100644 deepmd/pt/model/atomic_model/density_atomic_model.py create mode 100644 deepmd/pt/model/model/density_model.py create mode 100644 deepmd/pt/model/model/make_density_model.py create mode 100644 deepmd/pt/model/task/density.py create mode 100644 examples/density/README.md create mode 100644 examples/density/dataset/qm9/C7H15NO_train/set.000/box.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_train/set.000/coord.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_train/set.000/density.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_train/set.000/grid.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_train/type.raw create mode 100644 examples/density/dataset/qm9/C7H15NO_train/type_map.raw create mode 100644 examples/density/dataset/qm9/C7H15NO_val/set.000/box.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_val/set.000/coord.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_val/set.000/density.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_val/set.000/grid.npy create mode 100644 examples/density/dataset/qm9/C7H15NO_val/type.raw create mode 100644 examples/density/dataset/qm9/C7H15NO_val/type_map.raw create mode 100644 examples/density/dpa2/input.json create mode 100644 examples/density/dpa3/input.json create mode 100644 examples/density/dptest_density_script.py diff --git a/deepmd/infer/deep_density.py b/deepmd/infer/deep_density.py new file mode 100644 index 0000000000..b0ab8baeae --- /dev/null +++ b/deepmd/infer/deep_density.py @@ -0,0 +1,121 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +from typing import ( + Any, +) + +import numpy as np + +from deepmd.dpmodel.output_def import ( + FittingOutputDef, + ModelOutputDef, + OutputVariableDef, +) + +from .deep_eval import ( + DeepEval, +) + + +class DeepDensity(DeepEval): + """Charge density evaluated on grid points. + + Parameters + ---------- + model_file : Path + The name of the frozen model file. + *args : list + Positional arguments. + auto_batch_size : bool or int or AutoBatchSize, default: True + If True, automatic batch size will be used. If int, it will be used + as the initial batch size. + neighbor_list : ase.neighborlist.NewPrimitiveNeighborList, optional + The ASE neighbor list class to produce the neighbor list. If None, the + neighbor list will be built natively in the model. + **kwargs : dict + Keyword arguments. + """ + + @property + def output_def(self) -> ModelOutputDef: + """Get the output definition of this model. + + The density is predicted on grid points rather than on atoms, but it + is declared with the same per-site output definition as the fitting + net of the model. + """ + return ModelOutputDef( + FittingOutputDef( + [ + OutputVariableDef( + "density", + [1], + reducible=True, + r_differentiable=True, + c_differentiable=True, + ), + ] + ) + ) + + def eval( + self, + coords: np.ndarray, + cells: np.ndarray | None, + atom_types: list[int] | np.ndarray, + grid: np.ndarray, + fparam: np.ndarray | None = None, + aparam: np.ndarray | None = None, + mixed_type: bool = False, + **kwargs: dict[str, Any], + ) -> np.ndarray: + """Evaluate the density on grid points. + + Parameters + ---------- + coords : np.ndarray + The coordinates of the atoms, in shape (nframes, natoms, 3). + cells : np.ndarray + The cell vectors of the system, in shape (nframes, 9). If the system + is not periodic, set it to None. + atom_types : list[int] or np.ndarray + The types of the atoms. If mixed_type is False, the shape is (natoms,); + otherwise, the shape is (nframes, natoms). + grid : np.ndarray + The coordinates of the grid points, in shape (nframes, ngrid, 3). + fparam : np.ndarray, optional + The frame parameters, by default None. + aparam : np.ndarray, optional + The atomic parameters, by default None. + mixed_type : bool, optional + Whether the atom_types is mixed type, by default False. + **kwargs : dict[str, Any] + Keyword arguments. + + Returns + ------- + density + The density on the grid points, in shape (nframes, ngrid). + """ + ( + coords, + cells, + atom_types, + fparam, + aparam, + nframes, + natoms, + ) = self._standard_input(coords, cells, atom_types, fparam, aparam, mixed_type) + results = self.deep_eval.eval( + coords, + cells, + atom_types, + False, + fparam=fparam, + aparam=aparam, + grid=np.array(grid), + **kwargs, + ) + return results["density"].reshape(nframes, -1) + + +__all__ = ["DeepDensity"] diff --git a/deepmd/infer/deep_pot.py b/deepmd/infer/deep_pot.py index ce23c5981b..5f17ca8d5d 100644 --- a/deepmd/infer/deep_pot.py +++ b/deepmd/infer/deep_pot.py @@ -212,6 +212,11 @@ def eval( aparam=aparam, **kwargs, ) + # TODO: if the grid is requested, we can directly return it without reshaping to energy, force and virial. We can also consider to return the grid in a separate key in the results dict, instead of reshaping it to energy, force and virial. + if "grid" in kwargs: + result = results["density"].reshape(nframes, -1) + return result + energy = results["energy_redu"].reshape(nframes, 1) force = results["energy_derv_r"].reshape(nframes, natoms, 3) virial = results["energy_derv_c_redu"].reshape(nframes, 9) diff --git a/deepmd/infer/model_test/__init__.py b/deepmd/infer/model_test/__init__.py index 4afd626d0e..1152c3141d 100644 --- a/deepmd/infer/model_test/__init__.py +++ b/deepmd/infer/model_test/__init__.py @@ -14,6 +14,9 @@ Any, ) +from deepmd.infer.deep_density import ( + DeepDensity, +) from deepmd.infer.deep_dipole import ( DeepDipole, ) @@ -36,6 +39,9 @@ save_txt_file, test_chunk_atoms, ) +from deepmd.infer.model_test.density import ( + DensityTester, +) from deepmd.infer.model_test.dos import ( DosTester, ) @@ -56,6 +62,7 @@ __all__ = [ "ChunkContext", + "DensityTester", "DipoleTester", "DosTester", "EnerTester", @@ -96,6 +103,8 @@ def build_tester(dp: Any, *, atomic: bool) -> ModelTester: return tester(dp, atomic=atomic) if isinstance(dp, DeepDOS): return DosTester(dp, atomic=atomic) + if isinstance(dp, DeepDensity): + return DensityTester(dp, atomic=atomic) if isinstance(dp, DeepProperty): return PropertyTester(dp, atomic=atomic) if isinstance(dp, DeepGlobalPolar): diff --git a/deepmd/infer/model_test/density.py b/deepmd/infer/model_test/density.py new file mode 100644 index 0000000000..7088513d69 --- /dev/null +++ b/deepmd/infer/model_test/density.py @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +"""Testing of models predicting charge density on grid points.""" + +from deepmd.infer.model_test.base import ( + ChunkContext, + ModelTester, + _write_per_frame_details, +) +from deepmd.utils.data import ( + DeepmdData, +) +from deepmd.utils.eval_metrics import ( + mae, + rmse, +) + +__all__ = ["DensityTester"] + + +class DensityTester(ModelTester): + """Test a model of charge density on grid points.""" + + report = ( + ("mae_density", "DENSITY MAE : {} units"), + ("rmse_density", "DENSITY RMSE : {} units"), + ) + + def add_data_requirements(self, data: DeepmdData) -> None: + """Declare the labels a density test consumes.""" + dp = self.dp + # The grid and the density are defined on grid points rather than on + # atoms, and their extent (ngrid) is not known until the data is + # loaded. They are declared "atomic" so the loader keeps the + # frame-major layout without reshaping to natoms; see the grid/density + # early return in DeepmdData._load_data. + data.add("grid", 3, atomic=True, must=True, high_prec=True) + data.add("density", 1, atomic=True, must=True, high_prec=True) + if dp.get_dim_fparam() > 0: + data.add( + "fparam", dp.get_dim_fparam(), atomic=False, must=True, high_prec=False + ) + if dp.get_dim_aparam() > 0: + data.add( + "aparam", dp.get_dim_aparam(), atomic=True, must=True, high_prec=False + ) + + def evaluate_chunk( + self, + data: DeepmdData, + test_data: dict, + context: ChunkContext, + ) -> dict[str, tuple[float, float]]: + """Evaluate one chunk of a density test.""" + dp = self.dp + mixed_type = data.mixed_type + nframes = test_data["box"].shape[0] + + coord = test_data["coord"].reshape([nframes, -1]) + box = test_data["box"] if data.pbc else None + if mixed_type: + atype = test_data["type"].reshape([nframes, -1]) + else: + atype = test_data["type"][0] + fparam = test_data["fparam"] if dp.get_dim_fparam() > 0 else None + aparam = test_data["aparam"] if dp.get_dim_aparam() > 0 else None + grid = test_data["grid"] + + prediction = dp.eval( + coord, + box, + atype, + grid, + fparam=fparam, + aparam=aparam, + mixed_type=mixed_type, + ).reshape(nframes, -1) + label = test_data["density"].reshape(nframes, -1) + + diff = prediction - label + errors: dict[str, tuple[float, float]] = { + "mae_density": (mae(diff), diff.size), + "rmse_density": (rmse(diff), diff.size), + } + + if context.detail_path is not None: + _write_per_frame_details( + context, + suffix="density", + reference=label, + prediction=prediction, + ) + + return errors diff --git a/deepmd/pt/infer/deep_eval.py b/deepmd/pt/infer/deep_eval.py index f468379565..3be21d409b 100644 --- a/deepmd/pt/infer/deep_eval.py +++ b/deepmd/pt/infer/deep_eval.py @@ -20,6 +20,9 @@ OutputVariableCategory, OutputVariableDef, ) +from deepmd.infer.deep_density import ( + DeepDensity, +) from deepmd.infer.deep_dipole import ( DeepDipole, ) @@ -440,6 +443,8 @@ def model_type(self) -> type["DeepEvalWrapper"]: return DeepWFC elif "population" in model_output_type: return DeepPopulation + elif "density" in model_output_type: + return DeepDensity elif self.get_var_name() in model_output_type: return DeepProperty else: @@ -552,6 +557,17 @@ def eval( coords, atom_types, len(atom_types.shape) > 1 ) request_defs = self._get_request_defs(atomic) + if "grid" in kwargs and kwargs["grid"] is not None: + out = self._eval_func(self._eval_model_density, numb_test, natoms)( + coords, + cells, + atom_types, + np.array(kwargs["grid"]), + fparam, + aparam, + request_defs, + ) + return {"density": out} if "spin" not in kwargs or kwargs["spin"] is None: out = self._eval_func(self._eval_model, numb_test, natoms)( coords, cells, atom_types, fparam, aparam, request_defs, charge_spin @@ -916,6 +932,80 @@ def _eval_model_spin( ) # this is kinda hacky return tuple(results) + def _eval_model_density( + self, + coords: np.ndarray, + cells: np.ndarray | None, + atom_types: np.ndarray, + grid: np.ndarray, + fparam: np.ndarray | None, + aparam: np.ndarray | None, + request_defs: list[OutputVariableDef], + ) -> tuple[np.ndarray, ...]: + model = self.dp.to(DEVICE) + + nframes = coords.shape[0] + if len(atom_types.shape) == 1: + natoms = len(atom_types) + atom_types = np.tile(atom_types, nframes).reshape(nframes, -1) + else: + natoms = len(atom_types[0]) + + coord_input = torch.tensor( + coords.reshape([nframes, natoms, 3]), + dtype=GLOBAL_PT_FLOAT_PRECISION, + device=DEVICE, + ) + type_input = torch.tensor(atom_types, dtype=torch.long, device=DEVICE) + grid_input = torch.tensor( + grid.reshape([nframes, -1, 3]), + dtype=GLOBAL_PT_FLOAT_PRECISION, + device=DEVICE, + ) + ngrid = grid_input.shape[1] + if cells is not None: + box_input = torch.tensor( + cells.reshape([nframes, 3, 3]), + dtype=GLOBAL_PT_FLOAT_PRECISION, + device=DEVICE, + ) + else: + box_input = None + if fparam is not None: + fparam_input = to_torch_tensor( + fparam.reshape(nframes, self.get_dim_fparam()) + ) + else: + fparam_input = None + if aparam is not None: + aparam_input = to_torch_tensor( + aparam.reshape(nframes, natoms, self.get_dim_aparam()) + ) + else: + aparam_input = None + + do_atomic_virial = any( + x.category == OutputVariableCategory.DERV_C_REDU for x in request_defs + ) + batch_output = model( + coord_input, + type_input, + grid=grid_input, + box=box_input, + do_atomic_virial=do_atomic_virial, + fparam=fparam_input, + aparam=aparam_input, + ) + if isinstance(batch_output, tuple): + batch_output = batch_output[0] + + results = [] + pt_name = "density" + density_shape = [nframes, ngrid] + out = batch_output[pt_name].reshape(density_shape).detach().cpu().numpy() + results.append(out) + return tuple(results) + def _get_output_shape( self, odef: OutputVariableDef, nframes: int, natoms: int ) -> list[int]: diff --git a/deepmd/pt/loss/__init__.py b/deepmd/pt/loss/__init__.py index 6e940e3eb9..b025f0af97 100644 --- a/deepmd/pt/loss/__init__.py +++ b/deepmd/pt/loss/__init__.py @@ -1,4 +1,7 @@ # SPDX-License-Identifier: LGPL-3.0-or-later +from .charge import ( + GridDensityLoss, +) from .denoise import ( DenoiseLoss, ) @@ -35,6 +38,7 @@ "EnergyHessianStdLoss", "EnergySpinLoss", "EnergyStdLoss", + "GridDensityLoss", "PopulationLoss", "PropertyLoss", "TaskLoss", diff --git a/deepmd/pt/loss/charge.py b/deepmd/pt/loss/charge.py new file mode 100644 index 0000000000..5199d2b00d --- /dev/null +++ b/deepmd/pt/loss/charge.py @@ -0,0 +1,137 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +from typing import ( + Any, +) + +import torch + +from deepmd.pt.loss.loss import ( + TaskLoss, +) +from deepmd.pt.utils import ( + env, +) +from deepmd.pt.utils.env import ( + GLOBAL_PT_FLOAT_PRECISION, +) +from deepmd.utils.data import ( + DataRequirementItem, +) + + +class GridDensityLoss(TaskLoss): + def __init__( + self, + starter_learning_rate: float = 1.0, + start_pref_d: float = 0.0, + limit_pref_d: float = 0.0, + inference: bool = False, + **kwargs: Any, + ) -> None: + r"""Construct a layer to compute loss on grid density. + + Parameters + ---------- + starter_learning_rate : float + The learning rate at the start of the training. + start_pref_d : float + The prefactor of charge density loss at the start of the training. + limit_pref_d : float + The prefactor of charge density loss at the end of the training. + inference : bool + If true, it will output all losses found in output, ignoring the pre-factors. + **kwargs + Other keyword arguments. + """ + super().__init__() + self.starter_learning_rate = starter_learning_rate + self.has_d = (start_pref_d != 0.0 and limit_pref_d != 0.0) or inference + + self.start_pref_d = start_pref_d + self.limit_pref_d = limit_pref_d + self.inference = inference + + def forward( + self, + input_dict: dict[str, torch.Tensor], + model: torch.nn.Module, + label: dict[str, torch.Tensor], + natoms: int, + learning_rate: float, + mae: bool = False, + ) -> tuple[dict[str, torch.Tensor], torch.Tensor, dict[str, torch.Tensor]]: + """Return loss on energy and force. + + Parameters + ---------- + input_dict : dict[str, torch.Tensor] + Model inputs. + model : torch.nn.Module + Model to be used to output the predictions. + label : dict[str, torch.Tensor] + Labels. + natoms : int + The local atom number. + + Returns + ------- + model_pred: dict[str, torch.Tensor] + Model predictions. + loss: torch.Tensor + Loss for model to minimize. + more_loss: dict[str, torch.Tensor] + Other losses for display. + """ + model_pred = model(**input_dict) + coef = learning_rate / self.starter_learning_rate + pref_d = self.limit_pref_d + (self.start_pref_d - self.limit_pref_d) * coef + + loss = torch.zeros(1, dtype=env.GLOBAL_PT_FLOAT_PRECISION, device=env.DEVICE)[0] + more_loss = {} + # more_loss['log_keys'] = [] # showed when validation on the fly + # more_loss['test_keys'] = [] # showed when doing dp test + atom_norm = 1.0 / natoms + if self.has_d and "density" in model_pred and "density" in label: + density_pred = model_pred["density"] + density_label = label["density"] + find_density = label.get("find_density", 0.0) + pref_d = pref_d * find_density + density_pred_reshape = density_pred.reshape(-1) + density_label_reshape = density_label.reshape(-1) + l2_density_loss = torch.square( + density_label_reshape - density_pred_reshape + ).mean() + rmse_d = l2_density_loss.sqrt() + more_loss["rmse_d"] = self.display_if_exist(rmse_d.detach(), find_density) + l1_density_loss = torch.abs( + density_label_reshape - density_pred_reshape + ).mean() + loss += (pref_d * l1_density_loss).to(GLOBAL_PT_FLOAT_PRECISION) + mae_d = l1_density_loss + more_loss["mae_d"] = self.display_if_exist(mae_d.detach(), find_density) + return model_pred, loss, more_loss + + @property + def label_requirement(self) -> list[DataRequirementItem]: + """Return data label requirements needed for this loss calculation.""" + label_requirement = [] + label_requirement.append( + DataRequirementItem( + "grid", + ndof=3, + atomic=True, # the grid is defined for each atom, so it is atomic + must=True, + high_prec=True, + ) + ) + if self.has_d: + label_requirement.append( + DataRequirementItem( + "density", + ndof=1, + atomic=True, + must=False, + high_prec=True, + ) + ) + return label_requirement diff --git a/deepmd/pt/model/atomic_model/__init__.py b/deepmd/pt/model/atomic_model/__init__.py index e343287cad..f1ec92eb84 100644 --- a/deepmd/pt/model/atomic_model/__init__.py +++ b/deepmd/pt/model/atomic_model/__init__.py @@ -17,6 +17,9 @@ from .base_atomic_model import ( BaseAtomicModel, ) +from .density_atomic_model import ( + DPDensityAtomicModel, +) from .dipole_atomic_model import ( DPDipoleAtomicModel, ) @@ -53,6 +56,7 @@ "BaseAtomicModel", "DPAtomicModel", "DPDOSAtomicModel", + "DPDensityAtomicModel", "DPDipoleAtomicModel", "DPEnergyAtomicModel", "DPPolarAtomicModel", diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py new file mode 100644 index 0000000000..bafb09bd31 --- /dev/null +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -0,0 +1,370 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +import logging +from collections.abc import ( + Callable, +) +from typing import ( + Any, +) + +import torch + +from deepmd.pt.model.descriptor.base_descriptor import ( + BaseDescriptor, +) +from deepmd.pt.model.task.density import ( + DensityFittingNet, +) +from deepmd.pt.utils import ( + env, +) +from deepmd.pt.utils.nlist import ( + build_directional_neighbor_list, + extend_input_and_build_neighbor_list, +) +from deepmd.utils.path import ( + DPPath, +) + +from .dp_atomic_model import ( + DPAtomicModel, +) + +log = logging.getLogger(__name__) + + +class DPDensityAtomicModel(DPAtomicModel): + def __init__( + self, + descriptor: BaseDescriptor, + fitting: DensityFittingNet, + type_map: list[str], + **kwargs: Any, + ) -> None: + assert isinstance(fitting, DensityFittingNet) + super().__init__(descriptor, fitting, type_map, **kwargs) + self.rcut = self.descriptor.get_rcut() + self.rcut_smth = self.descriptor.get_rcut_smth() + self.env_protection = self.descriptor.get_env_protection() + if self.env_protection == 0.0: + self.env_protection = 1e-6 + self.sel = self.descriptor.get_sel() + self.nnei = self.descriptor.get_nsel() + + wanted_shape = (1, self.nnei, 4) + mean = torch.zeros( + wanted_shape, dtype=env.GLOBAL_PT_FLOAT_PRECISION, device=env.DEVICE + ) + stddev = torch.ones( + wanted_shape, dtype=env.GLOBAL_PT_FLOAT_PRECISION, device=env.DEVICE + ) + self.register_buffer("mean", mean) + self.register_buffer("stddev", stddev) + + def forward_atomic( + self, + extended_coord: torch.Tensor, + extended_atype: torch.Tensor, + nlist: torch.Tensor, + mapping: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + comm_dict: dict[str, torch.Tensor] | None = None, + grid: torch.Tensor | None = None, + grid_type: torch.Tensor | None = None, + grid_nlist: torch.Tensor | None = None, + ) -> dict[str, torch.Tensor]: + """Return atomic prediction. + + Parameters + ---------- + extended_coord + coodinates in extended region + extended_atype + atomic type in extended region + nlist + neighbor list. nf x nloc x nsel + mapping + mapps the extended indices to local indices + fparam + frame parameter. nf x ndf + aparam + atomic parameter. nf x nloc x nda + + Returns + ------- + result_dict + the result dict, defined by the `FittingOutputDef`. + + """ + nframes, nloc, nnei = nlist.shape + atype = extended_atype[:, :nloc] + if self.do_grad_r() or self.do_grad_c(): + extended_coord.requires_grad_(True) + assert mapping is not None + assert grid is not None + assert grid_type is not None + assert grid_nlist is not None + bsz, ngrid, nnei = grid_nlist.shape + # nb x (ngrid+nall) x 3 + merged_coord = torch.cat([grid, extended_coord], dim=1) + + grid_atype = torch.ones( + [nframes, ngrid], device=extended_atype.device, dtype=extended_atype.dtype + ) * (self.descriptor.get_ntypes() - 1) + # nb x (ngrid+nall) + merged_atype = torch.cat([grid_atype, extended_atype], dim=1) + + # nb x ngrid + grid_nlist_mask = grid_nlist >= 0 + shifted_grid_nlist = torch.where(grid_nlist_mask, grid_nlist + ngrid, -1) + # nb x all + nlist_mask = nlist >= 0 + shifted_nlist = torch.where(nlist_mask, nlist + ngrid, -1) + # nb x (ngrid+nall) + merged_nlist = torch.cat([shifted_grid_nlist, shifted_nlist], dim=1) + + grid_mapping = torch.cat( + [ + torch.ones([nframes, 1], device=mapping.device, dtype=mapping.dtype) * i + for i in range(ngrid) + ], + dim=1, + ) + # nb x (ngrid+nall) + merged_mapping = torch.cat([grid_mapping, mapping + ngrid], dim=1) + + descriptor, rot_mat, g2, h2, sw = self.descriptor( + merged_coord, + merged_atype, + merged_nlist, + mapping=merged_mapping, + comm_dict=comm_dict, + ) + assert descriptor is not None + + ret = self.fitting_net( + descriptor[:, :ngrid, :], + torch.zeros( + [nframes, ngrid], device=grid_type.device, dtype=grid_type.dtype + ), + gr=rot_mat, + g2=g2, + h2=h2, + fparam=fparam, + aparam=aparam, + ) + return ret + + def forward_common_atomic( + self, + extended_coord: torch.Tensor, + extended_atype: torch.Tensor, + nlist: torch.Tensor, + mapping: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + comm_dict: dict[str, torch.Tensor] | None = None, + grid: torch.Tensor | None = None, + grid_type: torch.Tensor | None = None, + grid_nlist: torch.Tensor | None = None, + ) -> dict[str, torch.Tensor]: + """Common interface for atomic inference. + + This method accept extended coordinates, extended atom typs, neighbor list, + and predict the atomic contribution of the fit property. + + Parameters + ---------- + extended_coord + extended coodinates, shape: nf x (nall x 3) + extended_atype + extended atom typs, shape: nf x nall + for a type < 0 indicating the atomic is virtual. + nlist + neighbor list, shape: nf x nloc x nsel + mapping + extended to local index mapping, shape: nf x nall + fparam + frame parameters, shape: nf x dim_fparam + aparam + atomic parameter, shape: nf x nloc x dim_aparam + comm_dict + The data needed for communication for parallel inference. + + Returns + ------- + ret_dict + dict of output atomic properties. + should implement the definition of `fitting_output_def`. + ret_dict["mask"] of shape nf x nloc will be provided. + ret_dict["mask"][ff,ii] == 1 indicating the ii-th atom of the ff-th frame is real. + ret_dict["mask"][ff,ii] == 0 indicating the ii-th atom of the ff-th frame is virtual. + + """ + assert grid is not None + assert grid_type is not None + assert grid_nlist is not None + nframes, nloc, _ = nlist.shape + _, ngrid, _ = grid_nlist.shape + atype = extended_atype[:, :nloc] + + if self.pair_excl is not None: + pair_mask = self.pair_excl(nlist, extended_atype) + # exclude neighbors in the nlist + nlist = torch.where(pair_mask == 1, nlist, -1) + + ext_atom_mask = self.make_atom_mask(extended_atype) + ret_dict = self.forward_atomic( + extended_coord, + torch.where(ext_atom_mask, extended_atype, 0), + nlist, + mapping=mapping, + fparam=fparam, + aparam=aparam, + comm_dict=comm_dict, + grid=grid, + grid_type=grid_type, + grid_nlist=grid_nlist, + ) + ret_dict = self.apply_out_stat(ret_dict, grid_type) + + ext_grid_mask = self.make_atom_mask(grid_type) + + # nf x ngrid + grid_mask = torch.ones( + [nframes, ngrid], dtype=torch.int32, device=ext_atom_mask.device + ) + if self.atom_excl is not None: + grid_mask *= self.atom_excl(grid_type) + + for kk in ret_dict.keys(): + out_shape = ret_dict[kk].shape + out_shape2 = 1 + for ss in out_shape[2:]: + out_shape2 *= ss + ret_dict[kk] = ( + ret_dict[kk].reshape([out_shape[0], out_shape[1], out_shape2]) + * grid_mask[:, :, None] + ).view(out_shape) + ret_dict["mask"] = grid_mask + + return ret_dict + + def forward( + self, + extended_coord: torch.Tensor, + extended_atype: torch.Tensor, + nlist: torch.Tensor, + mapping: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + comm_dict: dict[str, torch.Tensor] | None = None, + ) -> dict[str, torch.Tensor]: + return self.forward_common_atomic( + extended_coord, + extended_atype, + nlist, + mapping=mapping, + fparam=fparam, + aparam=aparam, + comm_dict=comm_dict, + ) + + def _get_forward_wrapper_func( + self, + ) -> Callable[..., dict[str, torch.Tensor]]: + """Get a forward wrapper of the atomic model for output bias calculation.""" + + def model_forward( + coord: torch.Tensor, + atype: torch.Tensor, + box: torch.Tensor | None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + charge_spin: torch.Tensor | None = None, + spin: torch.Tensor | None = None, + grid: torch.Tensor | None = None, + ) -> dict[str, torch.Tensor]: + del charge_spin, spin + with torch.no_grad(): + ( + extended_coord, + extended_atype, + mapping, + nlist, + ) = extend_input_and_build_neighbor_list( + coord, + atype, + self.get_rcut(), + self.get_sel(), + mixed_types=self.mixed_types(), + box=box, + ) + assert grid is not None + grid_type = torch.zeros( + grid.shape[:-1], device=grid.device, dtype=atype.dtype + ) + grid_nlist = build_directional_neighbor_list( + grid, + grid_type, + extended_coord, + extended_atype, + self.get_rcut(), + self.get_sel(), + distinguish_types=(not self.mixed_types()), + ) + atomic_ret = self.forward_common_atomic( + extended_coord, + extended_atype, + nlist, + mapping=mapping, + fparam=fparam, + aparam=aparam, + grid=grid, + grid_type=grid_type, + grid_nlist=grid_nlist, + ) + return {kk: vv.detach() for kk, vv in atomic_ret.items()} + + return model_forward + + def change_out_bias( + self, + sample_merged: Callable[[], list[dict]] | list[dict], + stat_file_path: DPPath | None = None, + bias_adjust_mode: str = "change-by-statistic", + ) -> None: + """Change the output bias according to the input data and the pretrained model. + + For density models, this operation is skipped because the output is + grid-based rather than atomic-based, and the standard atomic bias + adjustment (change-by-statistic / set-by-statistic) does not apply. + The fitting net will adapt to the target dataset through normal + gradient descent during training. + """ + log.warning("change_out_bias is not supported for density models; skipping.") + + def compute_or_load_out_stat( + self, + merged: Callable[[], list[dict]] | list[dict], + stat_file_path: DPPath | None = None, + ) -> None: + """ + Compute the output statistics (e.g. energy bias) for the fitting net from packed data. + + Parameters + ---------- + merged : Union[Callable[[], list[dict]], list[dict]] + - list[dict]: A list of data samples from various data systems. + Each element, `merged[i]`, is a data dictionary containing `keys`: `torch.Tensor` + originating from the `i`-th data system. + - Callable[[], list[dict]]: A lazy function that returns data samples in the above format + only when needed. Since the sampling process can be slow and memory-intensive, + the lazy function helps by only sampling once. + stat_file_path : Optional[DPPath] + The path to the stat file. + + """ + log.warning("Not implemented yet for density out stat!") + pass diff --git a/deepmd/pt/model/model/__init__.py b/deepmd/pt/model/model/__init__.py index 18225dbdc8..2c3a8f2284 100644 --- a/deepmd/pt/model/model/__init__.py +++ b/deepmd/pt/model/model/__init__.py @@ -44,6 +44,9 @@ Spin, ) +from .density_model import ( + GridDensityModel, +) from .dipole_model import ( DipoleModel, ) @@ -459,6 +462,8 @@ def get_standard_model(model_params: dict) -> BaseModel: modelcls = DOSModel elif fitting_net_type in ["ener", "direct_force_ener"]: modelcls = EnergyModel + elif fitting_net_type == "density": + modelcls = GridDensityModel elif fitting_net_type == "property": modelcls = PropertyModel elif fitting_net_type == "population": diff --git a/deepmd/pt/model/model/density_model.py b/deepmd/pt/model/model/density_model.py new file mode 100644 index 0000000000..7c24f7bd05 --- /dev/null +++ b/deepmd/pt/model/model/density_model.py @@ -0,0 +1,93 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +from copy import ( + deepcopy, +) +from typing import ( + Any, +) + +import torch + +from deepmd.pt.model.atomic_model import ( + DPDensityAtomicModel, +) +from deepmd.pt.model.model.model import ( + BaseModel, +) + +from .dp_model import ( + DPModelCommon, +) +from .make_density_model import ( + make_density_model, +) + +DPDensityModel_ = make_density_model(DPDensityAtomicModel) + + +@BaseModel.register("grid_density") +class GridDensityModel(DPModelCommon, DPDensityModel_): + model_type = "grid_density" + + def __init__( + self, + *args: Any, + **kwargs: Any, + ) -> None: + DPModelCommon.__init__(self) + DPDensityModel_.__init__(self, *args, **kwargs) + + def translated_output_def(self) -> dict[str, Any]: + out_def_data = self.model_output_def().get_data() + output_def = { + "density": deepcopy(out_def_data["density"]), + } + if "mask" in out_def_data: + output_def["mask"] = deepcopy(out_def_data["mask"]) + return output_def + + @torch.jit.export + def has_grid(self) -> bool: + """Returns whether it has grid input and output.""" + return True + + def forward( + self, + coord: torch.Tensor, + atype: torch.Tensor, + grid: torch.Tensor, + box: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + do_atomic_virial: bool = False, + charge_spin: torch.Tensor | None = None, + ) -> dict[str, torch.Tensor]: + model_ret = self.forward_common( + coord, + atype, + grid, + box, + fparam=fparam, + aparam=aparam, + do_atomic_virial=do_atomic_virial, + ) + model_predict = {} + model_predict["density"] = model_ret["density"] + if "mask" in model_ret: + model_predict["mask"] = model_ret["mask"] + return model_predict + + @torch.jit.export + def forward_lower( + self, + extended_coord: torch.Tensor, + extended_atype: torch.Tensor, + nlist: torch.Tensor, + mapping: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + do_atomic_virial: bool = False, + comm_dict: dict[str, torch.Tensor] | None = None, + charge_spin: torch.Tensor | None = None, + ) -> None: + raise NotImplementedError diff --git a/deepmd/pt/model/model/make_density_model.py b/deepmd/pt/model/model/make_density_model.py new file mode 100644 index 0000000000..d7f50ccfa3 --- /dev/null +++ b/deepmd/pt/model/model/make_density_model.py @@ -0,0 +1,657 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +from collections.abc import ( + Callable, +) +from typing import ( + Any, + Optional, +) + +import torch + +from deepmd.dpmodel import ( + ModelOutputDef, +) +from deepmd.dpmodel.output_def import ( + FittingOutputDef, + OutputVariableCategory, + OutputVariableOperation, + check_operation_applied, +) +from deepmd.pt.model.atomic_model.base_atomic_model import ( + BaseAtomicModel, +) +from deepmd.pt.model.model.model import ( + BaseModel, +) +from deepmd.pt.model.model.transform_output import ( + communicate_extended_output, + fit_output_to_model_output, +) +from deepmd.pt.utils.env import ( + GLOBAL_PT_ENER_FLOAT_PRECISION, + GLOBAL_PT_FLOAT_PRECISION, + PRECISION_DICT, + RESERVED_PRECISION_DICT, +) +from deepmd.pt.utils.nlist import ( + build_directional_neighbor_list, + extend_input_and_build_neighbor_list, + nlist_distinguish_types, +) +from deepmd.utils.path import ( + DPPath, +) + + +def make_density_model(T_AtomicModel: type[BaseAtomicModel]) -> type[BaseModel]: + """Make a density model as a derived class of an atomic model. + + The model provide two interfaces. + + 1. the `forward_common_lower`, that takes extended coordinates, atyps and neighbor list, + and outputs the atomic and property and derivatives (if required) on the extended region. + + 2. the `forward_common`, that takes coordinates, atypes and cell and predicts + the atomic and reduced property, and derivatives (if required) on the local region. + + Parameters + ---------- + T_AtomicModel + The atomic model. + + Returns + ------- + CM + The model. + + """ + + class CM(BaseModel): + def __init__( + self, + *args: Any, + # underscore to prevent conflict with normal inputs + atomic_model_: T_AtomicModel | None = None, + **kwargs: Any, + ) -> None: + super().__init__(*args, **kwargs) + if atomic_model_ is not None: + self.atomic_model: T_AtomicModel = atomic_model_ + else: + self.atomic_model: T_AtomicModel = T_AtomicModel(*args, **kwargs) + self.precision_dict = PRECISION_DICT + self.reverse_precision_dict = RESERVED_PRECISION_DICT + self.global_pt_float_precision = GLOBAL_PT_FLOAT_PRECISION + self.global_pt_ener_float_precision = GLOBAL_PT_ENER_FLOAT_PRECISION + + def model_output_def(self) -> ModelOutputDef: + """Get the output def for the model.""" + return ModelOutputDef(self.atomic_output_def()) + + @torch.jit.export + def model_output_type(self) -> list[str]: + """Get the output type for the model.""" + output_def = self.model_output_def() + var_defs = output_def.var_defs + # jit: Comprehension ifs are not supported yet + # type hint is critical for JIT + vars: list[str] = [] + for kk, vv in var_defs.items(): + # .value is critical for JIT + if vv.category == OutputVariableCategory.OUT.value: + vars.append(kk) + return vars + + @torch.jit.export + def has_chg_spin_ebd(self) -> bool: + """Check if the model has charge spin embedding.""" + return self.atomic_model.has_chg_spin_ebd() + + @torch.jit.export + def get_dim_chg_spin(self) -> int: + """Get the dimension of charge_spin input.""" + return self.atomic_model.get_dim_chg_spin() + + @torch.jit.export + def has_default_chg_spin(self) -> bool: + """Check if the model has default charge_spin values.""" + return self.atomic_model.has_default_chg_spin() + + @torch.jit.export + def get_default_chg_spin(self) -> torch.Tensor | None: + """Get the default charge_spin values.""" + return self.atomic_model.get_default_chg_spin() + + # cannot use the name forward. torch script does not work + def forward_common( + self, + coord: torch.Tensor, + atype: torch.Tensor, + grid: torch.Tensor, + box: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + do_atomic_virial: bool = False, + charge_spin: torch.Tensor | None = None, + ) -> dict[str, torch.Tensor]: + """Return model prediction. + + Parameters + ---------- + coord + The coordinates of the atoms. + shape: nf x (nloc x 3) + atype + The type of atoms. shape: nf x nloc + coord + The coordinates of the grids. + shape: nf x (ngrid x 3) + box + The simulation box. shape: nf x 9 + fparam + frame parameter. nf x ndf + aparam + atomic parameter. nf x nloc x nda + do_atomic_virial + If calculate the atomic virial. + + Returns + ------- + ret_dict + The result dict of type dict[str,torch.Tensor]. + The keys are defined by the `ModelOutputDef`. + + """ + assert grid is not None + cc, gg, bb, fp, ap, input_prec = self.input_type_cast( + coord, grid, box=box, fparam=fparam, aparam=aparam + ) + del coord, grid, box, fparam, aparam + gg = gg.view(gg.shape[0], -1, 3) + ( + extended_coord, + extended_atype, + mapping, + nlist, + ) = extend_input_and_build_neighbor_list( + cc, + atype, + self.get_rcut(), + self.get_sel(), + mixed_types=self.mixed_types(), + box=bb, + ) + grid_type = torch.zeros( + gg.shape[0], gg.shape[1], device=gg.device, dtype=atype.dtype + ) + grid_nlist = build_directional_neighbor_list( + gg, + grid_type, + extended_coord, + extended_atype, + self.get_rcut(), + self.get_sel(), + distinguish_types=(not self.mixed_types()), + ) + model_predict_lower = self.forward_common_lower( + extended_coord, + extended_atype, + nlist, + grid=gg, + grid_type=grid_type, + grid_nlist=grid_nlist, + mapping=mapping, + do_atomic_virial=do_atomic_virial, + fparam=fp, + aparam=ap, + ) + model_predict = communicate_extended_output( + model_predict_lower, + self.model_output_def(), + mapping, + do_atomic_virial=do_atomic_virial, + ) + model_predict = self.output_type_cast(model_predict, input_prec) + return model_predict + + def get_out_bias(self) -> torch.Tensor: + return self.atomic_model.get_out_bias() + + def set_out_bias(self, out_bias: torch.Tensor) -> None: + self.atomic_model.set_out_bias(out_bias) + + def change_out_bias( + self, + merged: Callable[[], list[dict]] | list[dict], + bias_adjust_mode: str = "change-by-statistic", + ) -> None: + """Change the output bias of atomic model according to the input data and the pretrained model. + + Parameters + ---------- + merged : Union[Callable[[], list[dict]], list[dict]] + - list[dict]: A list of data samples from various data systems. + Each element, `merged[i]`, is a data dictionary containing `keys`: `torch.Tensor` + originating from the `i`-th data system. + - Callable[[], list[dict]]: A lazy function that returns data samples in the above format + only when needed. Since the sampling process can be slow and memory-intensive, + the lazy function helps by only sampling once. + bias_adjust_mode : str + The mode for changing output bias : ['change-by-statistic', 'set-by-statistic'] + 'change-by-statistic' : perform predictions on labels of target dataset, + and do least square on the errors to obtain the target shift as bias. + 'set-by-statistic' : directly use the statistic output bias in the target dataset. + """ + self.atomic_model.change_out_bias( + merged, + bias_adjust_mode=bias_adjust_mode, + ) + + def forward_common_lower( + self, + extended_coord: torch.Tensor, + extended_atype: torch.Tensor, + nlist: torch.Tensor, + grid: torch.Tensor, + grid_type: torch.Tensor, + grid_nlist: torch.Tensor, + mapping: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + charge_spin: torch.Tensor | None = None, + do_atomic_virial: bool = False, + comm_dict: dict[str, torch.Tensor] | None = None, + extra_nlist_sort: bool = False, + ) -> dict[str, torch.Tensor]: + """Return model prediction. Lower interface that takes + extended atomic coordinates and types, nlist, and mapping + as input, and returns the predictions on the extended region. + The predictions are not reduced. + + Parameters + ---------- + extended_coord + coodinates in extended region. nf x (nall x 3) + extended_atype + atomic type in extended region. nf x nall + nlist + neighbor list. nf x nloc x nsel. + mapping + mapps the extended indices to local indices. nf x nall. + fparam + frame parameter. nf x ndf + aparam + atomic parameter. nf x nloc x nda + do_atomic_virial + whether calculate atomic virial. + comm_dict + The data needed for communication for parallel inference. + extra_nlist_sort + whether to forcibly sort the nlist. + + Returns + ------- + result_dict + the result dict, defined by the `FittingOutputDef`. + + """ + nframes, nall = extended_atype.shape[:2] + extended_coord = extended_coord.view(nframes, -1, 3) + nlist = self.format_nlist( + extended_coord, extended_atype, nlist, extra_nlist_sort=extra_nlist_sort + ) + assert grid is not None + cc_ext, gg, _, fp, ap, input_prec = self.input_type_cast( + extended_coord, grid, fparam=fparam, aparam=aparam + ) + del extended_coord, grid, fparam, aparam + atomic_ret = self.atomic_model.forward_common_atomic( + cc_ext, + extended_atype, + nlist, + mapping=mapping, + fparam=fp, + aparam=ap, + comm_dict=comm_dict, + grid=gg, + grid_type=grid_type, + grid_nlist=grid_nlist, + ) + model_predict = fit_output_to_model_output( + atomic_ret, + self.atomic_output_def(), + cc_ext, + do_atomic_virial=do_atomic_virial, + create_graph=self.training, + ) + model_predict = self.output_type_cast(model_predict, input_prec) + return model_predict + + def input_type_cast( + self, + coord: torch.Tensor, + grid: torch.Tensor, + box: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + ) -> tuple[ + torch.Tensor, + torch.Tensor, + torch.Tensor | None, + torch.Tensor | None, + torch.Tensor | None, + str, + ]: + """Cast the input data to global float type.""" + input_prec = self.reverse_precision_dict[coord.dtype] + ### + ### type checking would not pass jit, convert to coord prec anyway + ### + # for vv, kk in zip([fparam, aparam], ["frame", "atomic"]): + # if vv is not None and self.reverse_precision_dict[vv.dtype] != input_prec: + # log.warning( + # f"type of {kk} parameter {self.reverse_precision_dict[vv.dtype]}" + # " does not match" + # f" that of the coordinate {input_prec}" + # ) + _lst: list[torch.Tensor | None] = [ + vv.to(coord.dtype) if vv is not None else None + for vv in [grid, box, fparam, aparam] + ] + grid, box, fparam, aparam = _lst + assert grid is not None + if ( + input_prec + == self.reverse_precision_dict[self.global_pt_float_precision] + ): + return coord, grid, box, fparam, aparam, input_prec + else: + pp = self.global_pt_float_precision + return ( + coord.to(pp), + grid.to(pp), + box.to(pp) if box is not None else None, + fparam.to(pp) if fparam is not None else None, + aparam.to(pp) if aparam is not None else None, + input_prec, + ) + + def output_type_cast( + self, + model_ret: dict[str, torch.Tensor], + input_prec: str, + ) -> dict[str, torch.Tensor]: + """Convert the model output to the input prec.""" + do_cast = ( + input_prec + != self.reverse_precision_dict[self.global_pt_float_precision] + ) + pp = self.precision_dict[input_prec] + odef = self.model_output_def() + for kk in odef.keys(): + if kk not in model_ret.keys(): + # do not return energy_derv_c if not do_atomic_virial + continue + if check_operation_applied(odef[kk], OutputVariableOperation.REDU): + model_ret[kk] = ( + model_ret[kk].to(self.global_pt_ener_float_precision) + if model_ret[kk] is not None + else None + ) + elif do_cast: + model_ret[kk] = ( + model_ret[kk].to(pp) if model_ret[kk] is not None else None + ) + return model_ret + + def format_nlist( + self, + extended_coord: torch.Tensor, + extended_atype: torch.Tensor, + nlist: torch.Tensor, + extra_nlist_sort: bool = False, + ) -> torch.Tensor: + """Format the neighbor list. + + 1. If the number of neighbors in the `nlist` is equal to sum(self.sel), + it does nothong + + 2. If the number of neighbors in the `nlist` is smaller than sum(self.sel), + the `nlist` is pad with -1. + + 3. If the number of neighbors in the `nlist` is larger than sum(self.sel), + the nearest sum(sel) neighbors will be preseved. + + Known limitations: + + In the case of not self.mixed_types, the nlist is always formatted. + May have side effact on the efficiency. + + Parameters + ---------- + extended_coord + coodinates in extended region. nf x nall x 3 + extended_atype + atomic type in extended region. nf x nall + nlist + neighbor list. nf x nloc x nsel + extra_nlist_sort + whether to forcibly sort the nlist. + + Returns + ------- + formated_nlist + the formated nlist. + + """ + mixed_types = self.mixed_types() + nlist = self._format_nlist( + extended_coord, + nlist, + sum(self.get_sel()), + extra_nlist_sort=extra_nlist_sort, + ) + if not mixed_types: + nlist = nlist_distinguish_types(nlist, extended_atype, self.get_sel()) + return nlist + + def _format_nlist( + self, + extended_coord: torch.Tensor, + nlist: torch.Tensor, + nnei: int, + extra_nlist_sort: bool = False, + ) -> torch.Tensor: + n_nf, n_nloc, n_nnei = nlist.shape + # nf x nall x 3 + extended_coord = extended_coord.view([n_nf, -1, 3]) + rcut = self.get_rcut() + + if n_nnei < nnei: + nlist = torch.cat( + [ + nlist, + -1 + * torch.ones( + [n_nf, n_nloc, nnei - n_nnei], + dtype=nlist.dtype, + device=nlist.device, + ), + ], + dim=-1, + ) + + if n_nnei > nnei or extra_nlist_sort: + n_nf, n_nloc, n_nnei = nlist.shape + m_real_nei = nlist >= 0 + nlist = torch.where(m_real_nei, nlist, 0) + # nf x nloc x 3 + coord0 = extended_coord[:, :n_nloc, :] + # nf x (nloc x nnei) x 3 + index = nlist.view(n_nf, n_nloc * n_nnei, 1).expand(-1, -1, 3) + coord1 = torch.gather(extended_coord, 1, index) + # nf x nloc x nnei x 3 + coord1 = coord1.view(n_nf, n_nloc, n_nnei, 3) + # nf x nloc x nnei + rr = torch.linalg.norm(coord0[:, :, None, :] - coord1, dim=-1) + rr = torch.where(m_real_nei, rr, float("inf")) + rr, nlist_mapping = torch.sort(rr, dim=-1) + nlist = torch.gather(nlist, 2, nlist_mapping) + nlist = torch.where(rr > rcut, -1, nlist) + nlist = nlist[..., :nnei] + else: # not extra_nlist_sort and n_nnei <= nnei: + pass # great! + assert nlist.shape[-1] == nnei + return nlist + + def do_grad_r( + self, + var_name: str | None = None, + ) -> bool: + """Tell if the output variable `var_name` is r_differentiable. + if var_name is None, returns if any of the variable is r_differentiable. + """ + return self.atomic_model.do_grad_r(var_name) + + def do_grad_c( + self, + var_name: str | None = None, + ) -> bool: + """Tell if the output variable `var_name` is c_differentiable. + if var_name is None, returns if any of the variable is c_differentiable. + """ + return self.atomic_model.do_grad_c(var_name) + + def change_type_map( + self, + type_map: list[str], + model_with_new_type_stat: Optional["CM"] = None, + ) -> None: + """Change the type related params to new ones, according to `type_map` and the original one in the model. + If there are new types in `type_map`, statistics will be updated accordingly to `model_with_new_type_stat` for these new types. + """ + self.atomic_model.change_type_map( + type_map=type_map, + model_with_new_type_stat=model_with_new_type_stat.atomic_model + if model_with_new_type_stat is not None + else None, + ) + + def serialize(self) -> dict: + return self.atomic_model.serialize() + + @classmethod + def deserialize(cls, data: dict) -> "CM": + return cls(atomic_model_=T_AtomicModel.deserialize(data)) + + @torch.jit.export + def get_dim_fparam(self) -> int: + """Get the number (dimension) of frame parameters of this atomic model.""" + return self.atomic_model.get_dim_fparam() + + @torch.jit.export + def get_dim_aparam(self) -> int: + """Get the number (dimension) of atomic parameters of this atomic model.""" + return self.atomic_model.get_dim_aparam() + + @torch.jit.export + def get_sel_type(self) -> list[int]: + """Get the selected atom types of this model. + + Only atoms with selected atom types have atomic contribution + to the result of the model. + If returning an empty list, all atom types are selected. + """ + return self.atomic_model.get_sel_type() + + @torch.jit.export + def is_aparam_nall(self) -> bool: + """Check whether the shape of atomic parameters is (nframes, nall, ndim). + + If False, the shape is (nframes, nloc, ndim). + """ + return self.atomic_model.is_aparam_nall() + + @torch.jit.export + def get_rcut(self) -> float: + """Get the cut-off radius.""" + return self.atomic_model.get_rcut() + + @torch.jit.export + def get_type_map(self) -> list[str]: + """Get the type map.""" + return self.atomic_model.get_type_map() + + @torch.jit.export + def get_nsel(self) -> int: + """Returns the total number of selected neighboring atoms in the cut-off radius.""" + return self.atomic_model.get_nsel() + + @torch.jit.export + def get_nnei(self) -> int: + """Returns the total number of selected neighboring atoms in the cut-off radius.""" + return self.atomic_model.get_nnei() + + def atomic_output_def(self) -> FittingOutputDef: + """Get the output def of the atomic model.""" + return self.atomic_model.atomic_output_def() + + def compute_or_load_stat( + self, + sampled_func: Callable[[], list[dict]] | list[dict], + stat_file_path: DPPath | None = None, + preset_observed_type: list[str] | None = None, + ) -> None: + """Compute or load the statistics.""" + return self.atomic_model.compute_or_load_stat( + sampled_func, + stat_file_path, + preset_observed_type=preset_observed_type, + ) + + def get_sel(self) -> list[int]: + """Returns the number of selected atoms for each type.""" + return self.atomic_model.get_sel() + + def mixed_types(self) -> bool: + """If true, the model + 1. assumes total number of atoms aligned across frames; + 2. uses a neighbor list that does not distinguish different atomic types. + + If false, the model + 1. assumes total number of atoms of each atom type aligned across frames; + 2. uses a neighbor list that distinguishes different atomic types. + + """ + return self.atomic_model.mixed_types() + + @torch.jit.export + def has_message_passing(self) -> bool: + """Returns whether the model has message passing.""" + return self.atomic_model.has_message_passing() + + def need_sorted_nlist_for_lower(self) -> bool: + """Returns whether the model needs sorted nlist when using `forward_lower`.""" + return self.atomic_model.need_sorted_nlist_for_lower() + + def forward( + self, + coord: torch.Tensor, + atype: torch.Tensor, + box: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + do_atomic_virial: bool = False, + ) -> dict[str, torch.Tensor]: + # directly call the forward_common method when no specific transform rule + return self.forward_common( + coord, + atype, + box, + fparam=fparam, + aparam=aparam, + do_atomic_virial=do_atomic_virial, + ) + + return CM diff --git a/deepmd/pt/model/task/__init__.py b/deepmd/pt/model/task/__init__.py index d5b10b6f08..bfc44f6365 100644 --- a/deepmd/pt/model/task/__init__.py +++ b/deepmd/pt/model/task/__init__.py @@ -5,6 +5,9 @@ from .denoise import ( DenoiseNet, ) +from .density import ( + DensityFittingNet, +) from .dipole import ( DipoleFittingNet, ) @@ -38,6 +41,7 @@ "BaseFitting", "DOSFittingNet", "DenoiseNet", + "DensityFittingNet", "DipoleFittingNet", "EnergyFittingNet", "EnergyFittingNetDirect", diff --git a/deepmd/pt/model/task/density.py b/deepmd/pt/model/task/density.py new file mode 100644 index 0000000000..49853ff05c --- /dev/null +++ b/deepmd/pt/model/task/density.py @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +import copy +import logging +from typing import ( + Any, +) + +import torch + +from deepmd.dpmodel import ( + FittingOutputDef, + OutputVariableDef, +) +from deepmd.pt.model.task.fitting import ( + Fitting, + GeneralFitting, +) +from deepmd.pt.model.task.invar_fitting import ( + InvarFitting, +) +from deepmd.pt.utils import ( + env, +) +from deepmd.pt.utils.env import ( + DEFAULT_PRECISION, +) +from deepmd.utils.version import ( + check_version_compatibility, +) + +dtype = env.GLOBAL_PT_FLOAT_PRECISION +device = env.DEVICE + +log = logging.getLogger(__name__) + + +@Fitting.register("density") +class DensityFittingNet(InvarFitting): + def __init__( + self, + ntypes: int, + dim_descrpt: int, + neuron: list[int] = [128, 128, 128], + bias_atom_e: torch.Tensor | None = None, + resnet_dt: bool = True, + numb_fparam: int = 0, + numb_aparam: int = 0, + activation_function: str = "tanh", + precision: str = DEFAULT_PRECISION, + mixed_types: bool = True, + seed: int | list[int] | None = None, + type_map: list[str] | None = None, + **kwargs: Any, + ) -> None: + super().__init__( + "density", + ntypes, + dim_descrpt, + 1, + neuron=neuron, + bias_atom_e=bias_atom_e, + resnet_dt=resnet_dt, + numb_fparam=numb_fparam, + numb_aparam=numb_aparam, + activation_function=activation_function, + precision=precision, + mixed_types=mixed_types, + seed=seed, + type_map=type_map, + **kwargs, + ) + + def output_def(self) -> FittingOutputDef: + return FittingOutputDef( + [ + OutputVariableDef( + self.var_name, + [self.dim_out], + reducible=False, + r_differentiable=False, + c_differentiable=False, + ), + ] + ) + + @classmethod + def deserialize(cls, data: dict) -> "GeneralFitting": + data = copy.deepcopy(data) + check_version_compatibility(data.pop("@version", 1), 2, 1) + data.pop("var_name") + data.pop("dim_out") + return super().deserialize(data) + + def serialize(self) -> dict: + """Serialize the fitting to dict.""" + return { + **super().serialize(), + "type": "density", + } + + # make jit happy with torch 2.0.0 + exclude_types: list[int] diff --git a/deepmd/pt/train/training.py b/deepmd/pt/train/training.py index 776bdece43..396f958413 100644 --- a/deepmd/pt/train/training.py +++ b/deepmd/pt/train/training.py @@ -47,6 +47,7 @@ DOSLoss, EnergySpinLoss, EnergyStdLoss, + GridDensityLoss, PopulationLoss, PropertyLoss, TaskLoss, @@ -2223,6 +2224,7 @@ def get_data( "coord", "atype", "spin", + "grid", "box", "fparam", "aparam", @@ -2497,6 +2499,9 @@ def get_loss( tensor_name = "polar" loss_params["tensor_name"] = tensor_name return TensorLoss(**loss_params) + elif loss_type == "grid_density": + loss_params["starter_learning_rate"] = start_lr + return GridDensityLoss(**loss_params) elif loss_type == "property": task_dim = _model.get_task_dim() var_name = _model.get_var_name() diff --git a/deepmd/pt/train/wrapper.py b/deepmd/pt/train/wrapper.py index b2e4d4f229..b543b559fa 100644 --- a/deepmd/pt/train/wrapper.py +++ b/deepmd/pt/train/wrapper.py @@ -163,6 +163,7 @@ def forward( coord: torch.Tensor, atype: torch.Tensor, spin: torch.Tensor | None = None, + grid: torch.Tensor | None = None, box: torch.Tensor | None = None, cur_lr: torch.Tensor | None = None, label: torch.Tensor | None = None, @@ -194,6 +195,12 @@ def forward( if has_spin: input_dict["spin"] = spin + has_grid = getattr(self.model[task_key], "has_grid", False) + if callable(has_grid): + has_grid = has_grid() + if has_grid: + input_dict["grid"] = grid + # A loss-free wrapper is a pure inference object, so parameters can be # treated as constants while coordinate gradients remain enabled. if self.inference_only: diff --git a/deepmd/pt/utils/stat.py b/deepmd/pt/utils/stat.py index 5b245d187b..faf7b6615d 100644 --- a/deepmd/pt/utils/stat.py +++ b/deepmd/pt/utils/stat.py @@ -310,6 +310,8 @@ def model_forward_auto_batch_size(*args: Any, **kwargs: Any) -> Any: "aparam": aparam, "charge_spin": charge_spin, } + if "grid" in system: + model_kwargs["grid"] = system["grid"] if spin is not None: model_kwargs["spin"] = spin sample_predict = model_forward_auto_batch_size( diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index f0132348f1..ed3f505617 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -2767,6 +2767,54 @@ def descrpt_variant_type_args(exclude_hybrid: bool = False) -> Variant: fitting_args_plugin = ArgsPlugin() +@fitting_args_plugin.register("density", doc=supported_backends("pt")) +def fitting_density() -> list[Argument]: + doc_numb_fparam = "The dimension of the frame parameter. If set to >0, file `fparam.npy` should be included to provided the input fparams." + doc_numb_aparam = "The dimension of the atomic parameter. If set to >0, file `aparam.npy` should be included to provided the input aparams." + doc_neuron = "The number of neurons in each hidden layers of the fitting net. When two hidden layers are of the same size, a skip connection is built." + doc_activation_function = f'The activation function in the fitting net. Supported activation functions are {list_to_doc(ACTIVATION_FN_DICT.keys())} Note that "gelu" denotes the custom operator version, and "gelu_tf" denotes the TF standard version. If you set "None" or "none" here, no activation function will be used.' + doc_precision = f"The precision of the fitting net parameters, supported options are {list_to_doc(PRECISION_DICT.keys())} Default follows the interface precision." + doc_resnet_dt = 'Whether to use a "Timestep" in the skip connection' + doc_trainable = "Whether the parameters in the fitting net are trainable. This option can be\n\n\ +- bool: True if all parameters of the fitting net are trainable, False otherwise.\n\n\ +- list of bool: Specifies if each layer is trainable. Since the fitting net is composed by hidden layers followed by a output layer, the length of this list should be equal to len(`neuron`)+1." + doc_rcond = "The condition number used to determine the inital density shift for each type of atoms. See `rcond` in :py:meth:`numpy.linalg.lstsq` for more details." + doc_seed = "Random seed for parameter initialization of the fitting net" + + return [ + Argument("numb_fparam", int, optional=True, default=0, doc=doc_numb_fparam), + Argument("numb_aparam", int, optional=True, default=0, doc=doc_numb_aparam), + Argument( + "neuron", + list[int], + optional=True, + default=[120, 120, 120], + alias=["n_neuron"], + doc=doc_neuron, + ), + Argument( + "activation_function", + str, + optional=True, + default="tanh", + doc=doc_activation_function, + ), + Argument("precision", str, optional=True, default="default", doc=doc_precision), + Argument("resnet_dt", bool, optional=True, default=True, doc=doc_resnet_dt), + Argument( + "trainable", + [list[bool], bool], + optional=True, + default=True, + doc=doc_trainable, + ), + Argument( + "rcond", [float, type(None)], optional=True, default=None, doc=doc_rcond + ), + Argument("seed", [int, None], optional=True, doc=doc_seed), + ] + + @fitting_args_plugin.register( "ener", doc=supported_backends("tf", "pt", "jax", "pd", "pt_expt", "tf2") + doc_ener, @@ -4855,6 +4903,28 @@ def loss_ener() -> list[Argument]: ] +@loss_args_plugin.register("grid_density", doc=supported_backends("pt")) +def loss_grid_density() -> list[Argument]: + doc_start_pref_d = start_pref("density", abbr="d") + doc_limit_pref_d = limit_pref("density") + return [ + Argument( + "start_pref_d", + [float, int], + optional=True, + default=1.00, + doc=doc_start_pref_d, + ), + Argument( + "limit_pref_d", + [float, int], + optional=True, + default=1.00, + doc=doc_limit_pref_d, + ), + ] + + @loss_args_plugin.register("dens", doc=supported_backends("pt")) def loss_dens() -> list[Argument]: doc_start_pref_e = start_pref("energy", abbr="e") diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index a232aab393..62f08a388f 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -706,9 +706,10 @@ def _shuffle_data(self, data: dict[str, Any]) -> dict[str, Any]: for kk in data: if ( isinstance(data[kk], np.ndarray) - and len(data[kk].shape) == 2 and data[kk].shape[0] == nframes and "find_" not in kk + # grid/density keep a frame-major 3D layout (nframes, ngrid, ...) + and (len(data[kk].shape) == 2 or kk in ("grid", "density")) ): ret[kk] = data[kk][idx] else: @@ -893,6 +894,9 @@ def _load_data( else: dtype = GLOBAL_NP_FLOAT_PRECISION path = self._get_data_path(set_name, key) + if key in ["grid", "density"] and path.is_file(): + data = path.load_numpy().astype(dtype) + return np.float32(1.0), data if path.is_file(): data = path.load_numpy().astype(dtype) try: # YWolfeee: deal with data shape error @@ -1048,6 +1052,8 @@ def _load_single_data( data = mmap_obj[frame_idx].copy().astype(dtype, copy=False) try: + if key in ("grid", "density"): + return np.float32(1.0), data if is_hessian: data = data.reshape(3 * natoms, 3 * natoms) num_chunks, chunk_size = len(idx_map), 3 diff --git a/examples/density/README.md b/examples/density/README.md new file mode 100644 index 0000000000..785fd8c300 --- /dev/null +++ b/examples/density/README.md @@ -0,0 +1,179 @@ +# Charge Density Prediction Example + +This example demonstrates how to train and evaluate a **charge density** model using DeePMD-kit with the PyTorch backend. + +The model predicts the charge density on a set of grid points (`grid`) for a given atomic configuration (`coord`, `atype`, `box`). + +______________________________________________________________________ + +## Directory Structure + +``` +. +├── dpa2/ # DPA-2 descriptor example +│ └── input.json +├── dpa3/ # DPA-3 descriptor example (recommended) +│ └── input.json +├── dataset/ +│ └── qm9/ +│ ├── C7H15NO_train/ # Training data (deepmd/npy format) +│ └── C7H15NO_val/ # Validation data (deepmd/npy format) +└── dptest_density_script.py # Standalone evaluation script (alternative to dp test) +``` + +______________________________________________________________________ + +## Data Format + +The training/validation data follows the standard **`deepmd/npy`** format, with two additional files in each `set.000/` directory: + +| File | Shape | Description | +| ----------------- | ----------------------- | ---------------------------------- | +| `coord.npy` | `[nframes, natoms * 3]` | Atomic coordinates | +| `box.npy` | `[nframes, 9]` | Simulation cell vectors | +| `type.raw` | `[natoms]` | Atom type indices | +| `type_map.raw` | `[ntypes]` | Type map (e.g., `C H N O ... X`) | +| **`grid.npy`** | `[nframes, ngrid, 3]` | **Grid point coordinates** | +| **`density.npy`** | `[nframes, ngrid, 1]` | **Charge density labels on grids** | + +> **Notes:** +> +> - `grid.npy` and `density.npy` are required for the density model. The number of grid points (`ngrid`) must match between `grid.npy` and `density.npy`, and is allowed to differ from `natoms`. +> - The **last entry of `type_map` is reserved as a virtual "grid point type"** (e.g. `X` in the example): internally, grid points are assigned this type when building the grid-to-atom neighbor list. Make sure your `type_map` contains one more entry than the real element types. + +______________________________________________________________________ + +## Training + +### 1. Choose a Configuration + +Two example configurations are provided: + +- **`dpa2/input.json`** — Uses the DPA-2 descriptor. +- **`dpa3/input.json`** — Uses the DPA-3 descriptor (recommended). + +Key settings in `input.json`: + +```json +{ + "model": { + "type_map": ["Li", "Ni", "Co", "Mn", "O", "C", "H", "N", "F", "X"], + "descriptor": { "type": "dpa3" }, + "fitting_net": { "type": "density", "neuron": [240, 240, 240] } + }, + "loss": { "type": "grid_density", "start_pref_d": 1, "limit_pref_d": 1 }, + "training": { + "training_data": { + "systems": ["../dataset/qm9/C7H15NO_train"], + "batch_size": "auto:128" + }, + "validation_data": { + "systems": ["../dataset/qm9/C7H15NO_val"], + "batch_size": 1, + "numb_btch": 3 + } + } +} +``` + +- The fitting net type is `"density"` and the loss type is `"grid_density"`. +- The model type `"grid_density"` is selected automatically from the fitting net type. + +### 2. Run Training + +```bash +cd dpa3 # or cd dpa2 +dp --pt train input.json +``` + +The training will output: + +- `model.ckpt-*.pt` — Model checkpoints +- `lcurve.out` — Training/validation loss curves (`mae_d` / `rmse_d` for density) +- `out.json` — Final training parameters + +### 3. Finetune from a Pretrained Model + +```bash +cd dpa3 +dp --pt train input.json --finetune model.ckpt-*.pt +``` + +> **Note:** For density models, `change_out_bias` (the energy-bias adjustment used in standard finetuning) is **automatically skipped** because density outputs are grid-based, not atomic-based. The descriptor weights are inherited, and the fitting net adapts via normal gradient descent. + +### 4. Freeze the Model + +Export a trained checkpoint into a frozen model for inference: + +```bash +cd dpa3 +dp --pt freeze +``` + +This reads `model.ckpt.pt` in the current directory and generates `frozen_model.pth`. + +______________________________________________________________________ + +## Testing / Evaluation + +### Option 1: `dp test` (recommended) + +`dp test` supports density models natively: + +```bash +cd dpa3 +dp --pt test -m frozen_model.pth -s ../dataset/qm9/C7H15NO_val -n 0 +``` + +- `-n 0` tests **all** frames; use a positive number to test only the first N frames. +- Add `--detail-file detail` to write per-frame `[label, prediction]` pairs to `detail.density.out.` (one file per frame, one line per grid point). +- Add `--shuffle-test --rand-seed 42` to test on a shuffled subset. + +Example output: + +``` +# testing system : ../dataset/qm9/C7H15NO_val +# number of test data : 30 +DENSITY MAE : x.xxxe+00 units +DENSITY RMSE : x.xxxe+00 units +``` + +### Option 2: Standalone script + +`dptest_density_script.py` evaluates a model and writes **one combined** `[prediction, label]` file (`result.d.out`), which is convenient for plotting: + +```bash +python dptest_density_script.py \ + dpa3/frozen_model.pth \ + dataset/qm9/C7H15NO_val \ + --ratio 1.0 \ + --output val_result.txt +``` + +| Argument | Description | +| ------------- | ------------------------------------------------------------------------- | +| `model` | Path to the frozen model file (`.pth`) | +| `data_dir` | Root directory of deepmd/npy datasets (searched recursively) | +| `--ratio` | Fraction of frames to randomly sample (default: `0.1`) | +| `--output` | If provided, save screen output to this file as well | +| `--pred-file` | File to save paired `[prediction, label]` array (default: `result.d.out`) | + +> **Note:** The script registers the `grid`/`density` dpdata types with a hard-coded grid count (`125`, matching this example). If your dataset uses a different `ngrid`, edit the `shape=(Axis.NFRAMES, 125, ...)` lines at the top of the script. + +### Option 3: Python interface + +```python +import numpy as np +from deepmd.infer import DeepEval + +dp = DeepEval("frozen_model.pth") # dispatched to DeepDensity automatically +density = dp.eval(coord, box, atype, grid=grid) # (nframes, ngrid) +``` + +______________________________________________________________________ + +## Notes + +- **Backend:** PyTorch only (`--pt`). Make sure DeePMD-kit is installed with PyTorch support. +- **Stat file:** `input.json` specifies `"stat_file": "./qm9_charge_density.hdf5"` for caching descriptor statistics; it is generated automatically on the first run. +- **Checkpoint vs. frozen model:** evaluation requires a frozen model (`.pth`). Freeze a checkpoint first with `dp --pt freeze`. diff --git a/examples/density/dataset/qm9/C7H15NO_train/set.000/box.npy b/examples/density/dataset/qm9/C7H15NO_train/set.000/box.npy new file mode 100644 index 0000000000000000000000000000000000000000..8d064b2261d7bc34cd79695e124ed67eeb9f05fc GIT binary patch literal 10928 zcmeH}F%AJi7)Dn~>jD!IL$U>h1W~L;M?|7f$;Qq`ft6j+h{7564z8k7ZYxT+z_c^A zQ7PVZ|4cH)m;dE`>3BAp%nQ!JIm$pK%UJe=?1vrc3K>T6KK8eZC=QgqANuP=eeRQ$ zzf+&N-fA~p(QUZmBz`=l={emzF2Zwi&i!>QmTT4A_d)i|oLj}?pYH*Z5BmdOHXCpO z7jOX=W&-pL`k1*Bdd3&{0$5y06mHxW$uKY@dduX7d9FH%EcRA!jR$s literal 0 HcmV?d00001 diff --git a/examples/density/dataset/qm9/C7H15NO_train/set.000/coord.npy b/examples/density/dataset/qm9/C7H15NO_train/set.000/coord.npy new file mode 100644 index 0000000000000000000000000000000000000000..4e5b579726efffa92e8944b1e5e66ce29ff12e31 GIT binary patch literal 86528 zcmeI*?Qc_c7{>87qZ_MkYrD2*TfmhNTDLV7l!rkuT#*Sgai(O!i3&Jr8+7b}l|e(< z7QkUfjK)A*8H+MWB#KNo@c~g`h{g#n*^CeubwDHx6`e>3OxUddg6~Yeeb@7*J;}*A zzw^8A`}*v9WO-R|h1s;x6!(R~(KYqH1s>nRNU_iF@kMIuH`G_wtgfvOh5tRiq;g#} zoID;~TUi%Qe!qLxoSA;lyn74$o<`4q`&eTq_u4`)IhEIv2tQMFm%e%Zv-Xt%LxtzF zU;Jr-OCzz}uGah<4QJQHXAc|7>+3Dr>T_zuzbUrpmQ!y!P8|KB$D!?|4OOeAxpcAm z#Nz>XrhfUgyRWe>TW8-ePLJKNY5KwDV*k!mnFE`*1zTNO{hQ@nTVJYL)*b5@m|@jE z&)z?yDTd;qH3y$QpQ-QH9=e@TGFgXD9e;K1q%^f(ODxR^r0K|xtp4(*49%MN@~6cO zQ{?hSs|zkTbfB$s{N}qB75>;Y)?=~B-IIU%g$kEG*)Xu*;q~aqQ`RC~$zgc=u}dzEW*j)wTb3)MqNKA_ zhB~%YWXxZjs~<+Z)6TRwR5r1A`yKn;ii|I`6#Sj1U8hEenr${+>hAry|7(|ehmwEx zNxMRY&)Pry%B?4o=To%Ft(mE@me)*Kdb_zP@Q`xV*I(+cU3sT`V@D^O5>9<-l$~h{ zI<&(-)MhrBbmj9^AEX*NdZ)oU9JrpMSmht(7nj-e(ZFB(N~)Zi{eaDT?mn|FM;`8o zM^ZF+Jie#;IkyG|C*Hp`F|o*7l528iX6Y@%-fnK6sz*ahH&%6~tKjUGlvk9cy78cD zZl`JLoU8XluG`f*rF>b}d+F+)v30sB`TKjGw}uaYo36p%cW!>H+^ocw?`&xgTEz9k z^~3eU{fGMx&o7=|tbbVluzqI!%=(%4FW$d+f9L(3{U7#!*gs_dko`mUpV@z=enI_$ z`WN*t>ZjCCsh?7Rr~Xd=2K^iK|Iq(K{}}ya^dHiHNdF=ItMsqZ|4jcg{qywCGk?MS z1@jlo?=Zi^{1@|I%nvd@$owhur_7%+zs&qH^Y6^Rlb=9-0{I){Z;;% z3pY<&yZ>8Pw0huWcd_o}XytBqan3Fv%+F0PASleiP5+qw|8?N{o0FV99NS06EWm*F znBX!aWuSSNDilubOkh#upp`96D(#sPWPB4ZqB!R-iZgarb<|LW@UPAI^*GyTM75u8 z-&Gq5e~?zFaq)s{*e}<^wM5|jEf{KHbbvC7`cB_&0t8>nJZL+`hxoS5;51z(kf#t8 z{%zU=1-{OSy6l^%O%*@mHWvjHme(Dc%&7npv&1faB?`WUH@x>5Jpo%fdvVg>5C$ZK z`>uOhz%Nl}3O4rw|gF}mr&G9`piRhyH_dv_V}%19be{^>@(U{>`GBIe{?s>#|Abk8hN!tyZE&jAD*7BVDDP>J?QPz9ki(D_$LK8X8_x}Qux;4+ngtUXQQnnHH)jhr>`^SlSEuGQQ{ zcehZ?D%+M3EdxBi&G>gqY!C(1dL6UK&;u{dzX@6WF|hjeqaY97z-4i-va1EEK+^t% zW07A4_AxU@LT#hKz-0Z$@7%la@>4Mxw!9#`n&i5f{r(vUzTyth9Y%wBB_NH zgiU3FVN$k_h*-;Vp0MqqTWZU7&4q8lhk3Hm+F%Olt?FOSGhacKcO~#;Ew$m=tnNp( z#MfZ2l^KI^s0hv61ALF$OQEfnV~(Rk5Q0C-2iHHdg+9C7klT)zLGQsPmlN50gxxwX zHoPbVeC63{LxyR{Y$Mlabo)B!?M|vuF3cmnn4=vsxYuKaRbC(T`RQDmxt$f zcKs#r=z#^lVWO7fJ`h(o5?-KRblx6`ST9O+r)RkW>;}gt<(!3%3JeM${`w?xn{n!wvJ+AE9bKDnILP0C#+{# z2_ocYKg5y#ggmFvQvZT1bbd$i^6f2aaCJ7)9PN>YT;Uhh0+>d?5?Y^oe|;8>P#u2Y zJhFq1Ni*3V)h-nIUqdpjlq*>E2MS%uXM`H3+tI7X1Q5D|o%QZ91@KGuI;#{p0*Q%L zX}j$-996%*dnXVB1c*G|FwUny$n}!J`qoG|XIDuiUkd{M8_)jKIa-6f_0!K%6K-Hu z5Tz{FHIF>+VWfX~rwO-1F|+#iZo@dSgPiFjVJM99iFxg@f<6@{zn9Kt1jV>*OP!+z zlwmVlaeIInICc^U7G55pn^P73q0xA-kn&@FUoR78lUar8k9J=7U^C!Bh0nkP|YbVGPD))x9zb{*Hh;s8DKH;*bwj7L$A9JCxlJ|e1& zCxcUR>_GS9J82xr#eeG4F3qoz1iw{h?$`v$LVcUE%H&OXc%oM5Hhxud$qlFt(pi21Pi-O4sNanEFzJwUSS4i55 z-hUchVcKkSaF>C#uw9k@o7W+l{8T6FMhBc};}s5&?85ieEqbkj`_MI-5>9Pw2}4h= zCjWJvhJ&C9xqoW$AW6%g2xme(G;nC6f@g0szFFUYjivip3n-4>;zXe-_o9rnR3@e%4UuoX>fl756TZJAE zv>$t>E;VaIEKTWbx7{Yf8tT{h9sB|w#oD!fO{W8@k8G5o3cXO38xZC2B?_YMVN=Ht z?IIfOp2gs7Gw^PxA;xqZLL3ine-L_D2(K=wSX!!t!w+ttV>Ql!S2Lrx3`Sg`!z{&l zk>D!)*!~o&U&#VjUq3od)mcNToHes41!NG%kF#ERhXKa9u!=h!N0C6*6Vk#LzflU! z&7m)s1!1L9ukiEhK!}vRCNtW#f}|E|oHZMDfP&Awx#AQXqCC2*da2hylW#pep@|sY zWVx3TjSM3EHlF9|oV+mX8^cJ6+XZCgL_15Dl;N=&x9=m7mAcS|*n zTtzu9A8yPhmB6UG>{IIXS{P9@>oY7lMc1ag{GR!;!C}enLW8?2>}mV3A8rkT)h6$7 z`nyN)4ZAJ$i03vu*LZNfqLUFCtJ@boz7zpX{2J0&7cU6D(u}EunFyl3#?nPp+aP;1 zHP%OSjMni@u{5NEfQgr<;V!i;6f2h3=?>ijMF>i4%*}!k;m_&eB)m`>o^AinO$21C zW<>FLU%=1ZM*VmX1(G=&LxNFxA0C>zB8at^T#+QI}MU)(Y8BI;f-dh?c>28{m%QhV7v z0I%zlYg#*2(AhBi>e*NUqn>PX#|LXFT?R=i*+9i#9=~}LN(82&N7XOTwbuR8RfOQ>f5`RH zbBTa^MJSG)>+FhN1*(*C;pqLmffgmyhkSmmA(NE+UNZl?<#Ri4VX_zLPw7^9j!#yag4fFF-MNZm|Akpj56L}U7 zJnGj5SScmpO!Zdq`#>R}4F<92Hf%5!CWnQ?6#!PULSGwY%g~p@q;wO8IiyQ`vlQP$ z88|(8R}}I}VM;uVb$xvd?y_6{M{&~uh%-rxudQ~&hlAH;8w&R)17lO0? zs65GBN$9(o>t**k6@0>MDc^;YL)Yxx&NG=ipz!PGONtgs*uzl}O(A22rUK2M&Z_L7 zZN511cxDYHKNS~Bo0Ek16>+pZ*6m=ENCvb_%y49B$fiv?jJEs?-wD0WfpZ3n-!Z3V zu=8vir?dBVYi!B*Rk`oVAnLVp+~0u@y7sG-csB)sOy-}G850HU-mc-U*X~ANX@a=I zl=uN={N@JE3t(x^{2<0-7Rs|cjtz3Q(VqHG@u{XrFch)07bAZT0-L40VND$1*F{X3 zRQ?%^Dz$%JX&wfLVq(jkJpphy<(Dz9jD{n(q7!nRLhwWrMUSUyz^xZM;iS3ZBJMP5 zwEw;WWfFd5T%u1wh(6ib{#$X&S4na=PP zn~R+uXABnH>;wsE2_R>aXqLpR3l@j(d{F*&hHj255@es>fnPraDTBOuK$3i^iX%M_ z%7g5^cIT^+~LR$I@MpZl(!S zabpD1mo<$poAsR_hxHkc#k|vNKcwDS5>k=Q)S4PDkJ8zQG2Bl$kOskrJ@KoYpOv`5!!S zBB!S)vVvtV=apzGL(a22+s30H@KQ~(QNfh~ z5!E8=h{-I7y0oA?mL&*d*@KbogC9_0nrJV+`Us*KK1w7b%mXH)Gd-SFS5Q+O;J@=4 z8%o#`6qwGqfXXSuKhVVnqs8&HHc&@bZhOtBJkUn=R?`|@15skG ze?2_+L9Xcy$MN1zxM^&Yu8H{-y= zbs#TJW_O_amM$i?Oa%!`9J8_0Tj=bCoo&Af2`s0lyi$x00M^XgQ4!wM5bkIB&Mw0b zd|ltlC(>-9D4Ys{i2w3I1y`YnKUfERs{Qy7i5t$JI8G8}VM&=VL&@}`iEkdv>1 z*gB#pP3u&r=>+RY-1s3rO2E3BF)!)p2&vcgPJV0J!6$-BsvAdtki5Pqb#jv5sqUQrs%p8MKS-6su!-pD zFNL@oh8i(mZD&HTvD?IhdVFF3CDj|@zq+7SJv!wQIe|VjtCN1;YzMIb!3Ja2Iz(gW z@obHz3T0X=H>()j0)r|GZ8P?M_~zsAx8U0e`g_Oc@p(`e%9)(~BzwM#E=kQiX`MPn z(?9Pgom^#v9iDeA(QC&o1YRPEgHdH*Y(j0$q)`jaqBn+>AMc`AYZJwkN&M*kp(&Ja zVOGA>Gk~Mr;weaOhG!%VcYFqXpzYn4>0XvCv>v0$DQ?RQIaflo9@ljto@^2&kI8YA zQ5c6?wZRO;wS*j}4un9pYe_XHv4U)QH+BC@&;h&!<XAok_gt@QU45JBu|=)E8eTJq^P*7QdZ-$LHVGyg}xq%n_m zZqxuIUxjru7k$A!EHoc4*Axs2J96LC)}aMPoqWDELJ0O+Fk__sf+CgO2K{N$AZs!M zdw1{-WawJ38tIOqLLA$~SebFKlwEk%|Jo9g^>DUt9&y0q-gJo@-0wl!-cz(`bIJYjOEVzStm#R5Dh0yCHM)-o zl;Bh-vW(2}6D+5Rdl`Md4Vx!Djp{a+;B0vJryu_;P>ORFCGyCF^1^cMX0-%pyb|jw zPk9WreSE|rGXmhAL73x07Y0c?cT5z2`vGRhE$!{!)NrF%=7u#k2I!{QRI+FvA~~^3 zYa*Em;OZHe%|~tyIDbrXuZ1uJ|F*@6<@#robsive^UEQ05;kF1=g5P3p13|{&0T2B zbjn~8NC%FuW}${57xB2&MI>!D7fO>7YzbAZ;r1W3`UY_Xc%RR1lD$X)p$Gb6LK~&9 z&vv6+@1l;DQ(^E|k6J(%Af(i*Ob*qK84;<(mtbVgPFvlA1j2F6brdSG!SRM4jT`F{a&mG4C1r%ypYZG!zS&N##qczwVX zR)X8F*Qjw`+yf=01X}va?}&xyn!piJ4x}29wVkob!3W|On-2~I;O4{8LF@DzFd8IQ z*%GA>0W2DAHz~Fd=TYPp2AXs9sDoF{zhwl%NVk{le-nZCAH(+}GzI9n;J}-jqY9Mc zF_0CaNB}3o@4m%~SV1ip&-IQdWw_eoqwtzE1Xj~|xYIQcQ5)mqje!C?XgT`UTUYrG znpkl2vg>kTPE5Y6&*lTf9MLumU({En!m4Y3ytWZ;eaCA#lXk@KI!vxAhXcLV{+(;y z-cYrE#U{Ix3Y;cZSmipr!7uYax)a}@Ncv)BLTeMnc--=M%-V!o>6=3|1?VaW~e ze^22{_;13=2}~$Y!M&~=KnbJ?4`Ye0G=e$Nn#;=sKOld_wJGN!4wEPRuqzjk|0k}4>%Yn1-kzi^U-cS#?zMMllAi$219yynu{{OHsXsPf#QG7z zjoqWKe#X#|ptidB)(Eg2^bWarzftsXotqG5F9g4Tve8sDfQAn4Wi6Z) z!B=jsWKokjh*ncAtxf%gkf1%oBlckUlhypw^T#*z(SPP>CTkcm%1B8Qa$S6Hau#cg zSEWdRi@#9Yb{;*;75LkXKMs;wb5&U!VsP@6tW0TS0;;B_J@Hjy;8~iqiq7C3Xx>$h zY4*eg=Mw+s+GBS(&N6j=Cozuj2yY!J(UODOr@b0&@(!5D*c9^)mjfm?%&**ZbKq)! z)uy(T3RwF_o9NfNQGu87tefZoB6fAexZ#cgyZMcHj{b9quOrR(FOwczO=Ps>H7G`Y zaZyG3k~_%u@S$>#lMP%C#_p+~B?V2cBf$?%=g4`d<2iSK6}q3B9Aa>xH{6WEj}8yc zh0}x^<1H=cPV-^lGgckpZ&Af~K1fWyZ?eR+5X zImPO;$a2a6gGAk2M2a^s6BziP1k*t8hX8p?S4~(+IQO`(yM^Ss6La+%x?qk-NoiUBC#N$=I{xzX zFk44)fpZw|4jPcmpl6$c116|kdJ`ab_c6zRh$5viu-;!g=j+a3J_ZzZ8rYUWVa) z*HQZce{huvSa&nffy3{>ksYUZv7d|x!`xx}IJs!kl&jC?>5qS%}A>`BVay3JT2gs-Xlgv;3hiX(9M^*;N zpy*GQ714jyDB%6;@i~=W!1B6e?0SqOq%o-zQN(ru&G17NPEt#_=j=f+JK~o~+&rm@JnB2RD46`216Kt=l6QEASfD`)>$x z-nZB6T62Q_hV(#ifiAG>SKi3vFudSy^|-zVOMo9pG)}bo6_kP+4~Q)%&`YXu62<{Z z;QEtBblsl@SdB1iaf_nC3KhB{2@XJ6`iV951$$C258ZO((h-7FXNU_UgoMCmDM(So2%CUSda}K5|!G{jm@D(vgCf% zp+6VTXI9lLl>xzYw-kPAE&wwFH}YR3g>j?HeG2^9U}X?05g;1|XQov<^#q?$!F-AV zpJop9a*h`+40J-!?N?PI?xyh7i?*lMCJi2JsLf+yKZT`eZP%Z6bP!<5mojvb&!tb& z1LcVGA#^w1(2(;0`ox`HY*C3obMgE4t#9WbKMAu;_)|R$?Q9ETb;`ns{D38AUOy}Z z{!H^t>qmYR<)!zVLV-7h3;4d=hqv>|cwP?TFg3dL>`}chr2S2biPs5)8MD7D)tt51b^ld$(}(mERt)D$!F-=t(y-LGniZJ|BiR@n$ICI457SN3c=9Ns;k%Y zwFK@|$ytb9)blaUAA-HV45Dod$E>Gf=}>kwUq;`e42G*$?5Jbv;c#GYLKTY;WVcuN zZfA)Ahlvp*n~n>lsu@km>n@;l9BXF(qYJJq={y!xrUTyan$RML0aV5uaEq3X8=gh| z%Ds{I3jPr#$wcI=p;{>x((;ilG*H6~#~@in{Cs~7kG<3IC*@gg4B z{CFmjjs&5;0xuz9O%-z7S*W9^7SQzF|Gt`C+D0yS3wZ*X1tD76pts{81FUIVm(q7g zg5WA$?o6CMsAbjhmQ9qvX|RkA0jB|2nsY{6(V+t?J3XSdM}jciQE60vYz$UwqSq4S z8c`Bwbz4ouS7ZcXQ#fteAn!KzUE1m`K$(BO`lD)8j6pMU7`u#ATUe{RFc_h$_pD_` zrwTp3ZTwySIz5E`_j})@vjMp(N=|u9G(h6J2g@%1j$xuw{cw4Y2z-OQ8thwUq2{_o zNoGa|m>R7RUmcqTi+lJw5sZ_&3p(`}to<%qi;8w$+#C+I2hHy-T-%CeNbglqfOq2z z5_|Ge5{;cAL0Nf|qedL~mhSEp{OcZ&ZmyV*cd`MgVJio>h&l8eUyh8b5`+5++Z;Xf zi%7!3FN0xM0QNE7wOO_LLUg`XkYlbjOwlq&ymd7InozDxkjH|5%H4A%>pIYBm8n9M zZ2(Ea!KH%XztPPKT%6Q*W?*=A)^l~B8P)p)km1HY2ZELksb4nOaI@#9;Iz3GD0S2& zO0@dG2Kyx2Pi+PG0QC=7Z!aQwiDq2)fT!@rTwLX=aW|yKR#@jUNJI6u2buBq9(vkt zXI1gK0Oj&&OcXI_UBo$qun$HP=!C|WvFl1H6#rLJYJ~9{RaJI8<9j3l!K@!d{xFv! zb;>t;PqaxvA%+iQb$bUHnLnRu*-b&QZ+LCULMG6bS=D>zByAAxV{-gq=>j3&)<4MW z*MPwHgv^N?$WXbu$fCfqLk$qEkn=T}biwo#1EroGtPZM0<1o@K#(7ivN+*nVM* zAtijHEaL+g_$I0G$SGP2(w;?j;u6GxJ8hXn>D6+ShTHfZv17oPu<{Lz5fo zzgS@a&uXd`tvVel-WyNJ)_e@H8_u_4xzg-n@`J;gN$8yvvV=`&6y8vKKyo zM&Hl(U*xobYr*%@SBg5AV;6le@F@k3p5~33E_4?vX=6 zHryhZy6+r+!P~BnlV=U;kn_K$rQ|?P$U(KS+u>XAoJ~KfP*fNw9el1?$zOt-V>hW5 zj9$atvBeK0Ed+4-joQO^a{ExRLh`v|gFY!T2*J=BLDBFfAEE=G|=w zSBqaUjGtcU_tbbz5)v#B-~V;FoAoka=E~l~q^Lkz1evzUkM2NJ#sG9YRReB;3L}9w zS&$`vaz>{+10*?B<89Tea60`*-2-UB*7%W$nH&-Dey~-S4j2Xr-p5T6mgF#$ipOmB z)CKgJq+jiie*|M$*}vZ~b0L)GN&3=F3E*y-E(p7^j@}Go{va!&1@@xKMi-rW^nF0@ zN83>)ECue3{^fLs@qu%lSG&a;&WN$<8zk|S&ZuSeQxdVvFE zI^O8(JgG(XvdT9&ZnnayLBb%daVIkT7{OVauLO*nPak}`l?%2xgmiy-*3jcQO5-go zCm@RmXue%T4|J8cW7$yxq{wfwaLHbW=bO@GcHij1GzAyO!zBkNySB)# zbYe)!64WW+??%QaolpBq?LdsZHH;~l1?<^p?XNrSA}J@6iZvb#aGP%|trFdX3Op?% zLic`jOzi=Z4W@v{$0nj|cMW7rtyxxGWuOlvcBM90f%UpePi;mkVx+YvN3R&*>VFf3 zcEJfyU*2i0)TRP>e!EM#4h_h+R3~*UBMvCMeDJ=AQ$zo=niTcNniu)2_iOEs1kluQ z(3J3~K{8q9RB^tnpq0lVnRda66^c$ci4>{et*g5hbSed(Nw_dZTsL5E*rrcq?@lUca~`+B=a-f0qpy_V>|bw^u1zmePO!5RQ&s>^#^HneSDpfgwy9&evTPVyu`q1ZQ5~#H3&hav(!~0zRRcAvH7|fF;3SjMqSEVBZ zUeSE;h3%t5`QLpw3C-SSzVrkzdux@{@AaamGL%(dv=5C7LVheKL~yTND8KlT6ZrnV z*Zz2L0_Jsb|8Za1t>ZXdX@lM+dryB1acG`mk{r2gHCW zlj)!3)G!QDF`otBSwUR=b165q?gOB2+*98k!TNUd!_d>4Ku>CP=R!Wa$n*Co<=AE5 zyUWIXR-1ansh$|};du~5aUrwIrx!em^Nvk$Yai7p#V9;@^9M@(LPSj~L_u0A>J>xT zU+|W4+DxdOLGhaYj(^?rLH42jun9BC1t$_>(H)UPZEG%mz2XD-)?Hy9s~rpa;j2Dn zIqvXa(W)VCpBZ!_IWPm)F@gRU(_z`Sba)%_-1VbID(c9vWEl4xh6A~0Z`LNK(Ax~X za}r@aXukLI)FEaGViMlP)n?TpTtk=bL1|rR)ZN7j|H%lFe`Tg@4YSee&jkAGt>chJ zKbz{R+lQv<3uez!4S_=c9qSPB6#Qk(Y&ySqpVxLPxBqC~1)nQ!N`qk~kkU=?kU01) zOu33n+jSfx=A@ezvnrpE0Y_R@@sbR1aIjy}m6}Da5#KrpQ?#JKD!ye);TH@GC#faz zvV)|v@-c>^EDY@8=krbcK%-KFO0!$+@XDdHgk+`-Y= z)$k5It}(=ln%G1dJ|X{gTp2d}eLNJ_>>*a~X$#-3SP7 zuTXw=-9-c2gEdCWTZm>mp#_)W5QP_9*2mW#L*drJu^L3oP}_oI-9TgwUY|dT(`M`< zW9@%h99Uss-YU;p7GwnE`KDLLKl8!b=+{WMB{EpPyf?(lU4if$oo0o$G9hD1CjM4@ z2g=gNz4ZDbu2=ky=^d(!1-Sx+!D^#L@OPT(deeXjo@>)I^`b&R&P}gUMR$Mi~hSiy{!KXw~7vX5fH^|mh^YG7|JA8RazKA(mdBkWBv6Y z(S0!HY>OIR@lts#555MP{GFeU zf)dd7c7)zH3Mhu!{wqTKV4G2^G|Y000|gn!T#tOHnv?W3yJWwt$Tl z=jy3x8E84s-^Q-L0lU?;U4%m?pmOCIQBuYrGH>vl&V0uVVjcSaRpuQihzBPi%9I#t zI68f7v%VuQ?YrHI7x^vtG*O=}J{eYUm$@l57g2Km-*<*alYqk^rjA!22ku4@g$&9L zz>#YhOwe+{yLu&_{u~=< z&^xk*=MO@<-}@_q6xGn`ec^Ic7CwJTXS4%O>G<5I{_S4)-bcSwd6O^tKh21*?RWrL zWQT&T03%E%yIi9z6$N$5XJPzy=Peo|$0tG$ykVEK*e2Za3TT8{MQ-l7fgMlEr0?P? z(tOSF^Vj4ZuvYf#SfAU3Z-f?@q74T~dR}epY8@tATTsau$Qwn>>K`b+=jeg_%%qC- z*K*{`S^JirtOpf7ox9s2M+Ilr>p^LzS76QO?F*+a91xjST#=2lhV9N6CMit~c;6P` z`7Butu$4*sJ3SL&{j)*dh7ulVj7BZ1O;y9Bt3%^7(=v*OKZpUG8mTQ3pGRi~<&s763Y zLML`#Fad}gx_IzgQ(pL}X9b;h7rbCv;#p5G58SPyGVU5F(4czl#ie*os3dZW_hAu& zyZ5+UO+6^VpHI0to}>!yas+h^zjFW?{Owe`Whn@Gqux6})P#(?Cc=G}vtae6wa*JD z2Iy?mZRYG#$7R8FC2)K=FRWu_Azm@e6eTJa}AJ%!}v!p{Z> zN}nXM2}%H&w36+SQ4U}v(&*lwGlee%Pej!7wV^#OJXPTXFFf+B!^oso1V$Z73^7W6 z_?>^2mv{0LZ5L{MyX18UTYNK8^x_LB*g0;M{Js^O$BNzFCejAW()UlorlVnAy25Je zLhn$Qer$c8%nH;cTdP@p2Vo;Q>bFokF04CJ77D1HA`Y)r>R7o$wC<^l)$iMmJo}_< zdwMZomO7m9_An{LbUmb5FK_`xX+}3}zYE`{mdwoPcLW5ymBwV3t4EbGtYvumvnWur zetGL2g0j!6&-n@SVRMMKD!E@B2nyOXDLXwNMT*wWH~j-5i;Z^Be1Cu*R=GUv30(t| z@n@?e(jgc6Y#mg$B)|ywu9_t8E+o)J^?jT!fOj&)?mD!>@QdC1x})(Xs(H>jSVmP3 zL|H8drdt3*pgkHAj{#05?37EP6^Q+Ol3aa%8r8Dhit70h2&rA~-gFyW_+GcFyyn@h zfi#}y`3Qjxl;dZR`%0RD%Y@F#?cHG@6#Xrd!1xul<(Krz?;66>&kH=ZGg6?*K(P^D zWeUo9X)@!LSYW%PB=Vl19bV?8Qil>;f)8IyY6F7RAYC{5^=3de(jn{kf=_tSe^^)G zi+}Ya)E7q5(d^G5_g~$@O5&F<`kOa>77&6_y5KKms19j(v-Cv=@BxhqeK-CQC6pc1 z4XT-WU(}BtafF}Rkfh9__c>P^vU~qPu_9XmST47O&8_OgtMmZzxYG-689H2WP!j|a zriybn=2JA_twOEFhYO@+ugaD`n}FPZ|E;teBtvcz@!EPf3Fri6$mWGy1B24cha8jb z2v>gy&n=4p2u1R>EOyjjp7p+g>LUf{k)}UB5)lHDVt4f$0Zg!+8Dd3#BnK1uZI{1_ z^ua?cYN#Rz1np48iQr{?(6XEDGpW;qgFjH*S@i}Hl6yBwr;&i$80obUybG@G;g^W5 zIYLYtLPryhrcWgm?xB1VLWHg4wrBlsax(p&x)@Eq-_{h z{VW2q-OQnkbQJg!caUnfRW8fvi37B7DV^S5`XXLo|CcP>afAvm zaVUwy&QQPVPsFx(5BPy#c(Zsd0x) z*63hK$1N10Sk+QnOb__2e%uULjL_=-J!;Hz6{#}phiMDQ088t$@vBcsA=u5Oy8h@w z*Yg@Rx|^8-vohV{2SHxo%44*Z<7f<)gz6kR<~XqT_lA|kiys$}-j zTURcq98!IcYibX5u?$wDdd?7dPL$sAaRK!T_Sp;evH?x*IfXvch=eRmecGZsDm}_NJ<+<+)U00`j^4jwy`gkkQoG~ zKjB=7djm}oyz#3&!zhU9Yi!H(1ac>ARr71EMfda84$M3|pdhwqZ&-^MGHdzuv2*MNZ*Z!xUu#q&ZpMeHHnyFxmtP_m?I{9&*ZT#CFZRX$wQ<|1 zqj;Ep%bG2_c?m-CrZb6E$Ur`hW@@q36pHVXF=jr?hu^Qp#^bQ((UJh>Y}|*7>xUa6 zviO+cP7mc%?aDhKnEk0#DeDkP3Kl)b3`&H3yM+R(-@C|1lDBUAC5 zom2jSAKa1pK(zitR&2Bt&1WdCZGL_+D{yaR-zD!j=2G) zmv?cx?o~nqn;iRajxr=uF|tO9*4mIa#4KuMI*liS;GFX~N z3uO8RMS62ci>@5rl^MXw8#lct^B+d%w(npP=}SDJhVB5 z8iT2~`hGnF=RZeQ*j^-HnnqyuwnPsseGa+{hc>~b@4TYQfgITPKc$K%UTK}H<&`0z zu7w2!Mv_1U8Ftk!e1vYWN#V)ZkbV9 z5)TGYS$fFXN4S76?_1?gT`RljC(p!I$Z3OXgt?^L?&XMxGxdy6n-VUoEK+{Dzl{7+ zXy@2yC*gU)t?z=C^01&Xc#nO70Q^Nw{)&7N2Hd21mmdZXV5~FRj^yhc3Xp65@xJ<7 z%PTz1SxNO3q~^6NEtMGn)T|#iMoh;ca_~N$H;)p?z2x+?`L}_n7#jNT4mv<# zU_6Xw6Y#QKod80u61;SwEmULs@EH3I0mSVVYb_`^z@MUOf1*PcNyi0!rN$?GHcT+}i>RFar#@7t)rl__6F?V9LsV<>B042_ zdX0fI8GS6fUd2`C3p^x*Pq`V3km4MjQsaMeAVMVK`i=i568QVbk)nJPHK!9{8kw3y zaNq5NCTkgZ;<7F)lV=7WaRnC07Y|XG0&B8uT?+(6hJSJQm`8abmyK}k+tD-el82;Z z3y{E-@+Y(G1j)B1wzcrcfR)34ZnCjU=$JN`Pwy=b;43Sq?NZD^73Fp>&9(rX&}Vh= zJ>&0NeD#PNupi z@at%NIhn2oMG>Z3_)RCG=AmA3HF9Y%D!Kl#>w;gk@5Y)$^Sy#-7%GY^_XZmxS$qL^ z72xPeBG!Cg3tSDv2AglIk!8^1PqpD9K<@Z*K7jEMeW7f5o`pUjX3_mTan{@L_vs_j zU=wAi#(1#)-VXyJv1abP{qYir_uP~_=ORJo_L*0;s3PnTZZaRUvw;=8q2sl8LoH+F ziG+F)yNJJ$`p}|J9$dTYUr0v%f~Kov*=)apf!aQZ)QNHvo-sRDa5fjA)+B;6hhiUC zYw^V|A|(K=Ca37$^L_L@H!3@fM*v7WKH1x8kwA|%-e?L726#x)U8Yih3LfVYp8O4O zz$lfcI*j87vYKa6dpW}fpCd`i3H-hst!JP)&nPEm9QPoY`O^x8;h&4nM$?UF~D0hF&byJ(^gkd=|= z-E9&~n9k;nZY`4se}kkZefhsA&u>Pi=~)M=lxFMlAXS6UlVI!S{s3|<+vV$IIU)DN z(@R-)xdpdum)HAS74$z+r6ArAyWqnPv9p(*C}^jBJ}rS7=w{ygEdDbDYRu&7k)>R) zW^=xj`UeA&w|__8vJQt1jq;>90@(}S^3EP!+J&!SO5HskK?-bN=F@IkJ%^jr?`{#q z%p<;F;)naGbEup95+0YI9OU5s6SiCfx-O4i6<6@3ulzzXMg_i&E6n`^uhaz!hvO&%BI{C1AGL zh`9a}J@6HJmW4%3AT>oj_2235z=Sj2u8}?l$_fJb!yT!B<|;=B|GlqpcB$C<6LSli zz5L|X5q1ii3g}V)QfmcwQVGVFHg5t&p-Zao@89V9&O4mWq9+h=v*^+4067dF>Hf0* zYy}SAKmS*qa34&5#x(vB6av3w8WR(44N%Jj`m$^;SfHo?HQhdqubpkOq1 zF<*%Q7GL%y+Fh>%jAiVmJ~0`%VLZ{aBQ<=Xf4+I|p9i4SO+>WsBm(t*-JWi>Q^;h; z1gqOr0Ulv1wJ++@gXHxPE_I(w#Df?AP`tbyQ8PMcxe*?qH{!ZugMzo9sf3Tslf4V^ z$@bm2^!fqF5C>?SB-Vha*s5 zAI8nH_sGbWolU~|mYrmUjAUp3WJJiw%uZ&qG9#pj?7bo*J0oO8(jYV5`~C~}o_o(Z z&-ZygkF>rKVG-m==tRB5@^+bZx$8T)zd&oRWzY2q6VzXpB-GV^i{9asX@|Y$fxc$P zb+n`gGu;Vt+RuZa+d;y(Ojimd*NfZtiygt}!B@9Gx7edf{~<;4 z(&~WLD_~iuI22h_1w4{}Ra;_P;V170{{(g^pgG^(AfvO3?EQXJg!SYCzfyS2kk|w= zuzyTkFm40*)hX&%<#2$y-o@R@nFrkJIXv+-NI~bxt%M(9w9x$$d%R?v(8wvBPZ~0S zHV+gz`yy~5nrBs#_CE$leSpis`FjNASE9H&T6xHF^79aFI|K#N1I=5GUBGtiOH1~Q z0GjS)(aSZqQ7w9w1MdVzOLJ_i+qn z+p1*RK(g~`y#l=dL6Lv6M_CIoO!cl@v%ZB33GsBZm*eY^My8_6O$86I$#N`C?fD45 z2ErH%)%wtxzYL!|D}N)R(w^lj=Z}!=K+E)Hnm-_0ZW{YSn*ea)jJ}Eqe?|HW*S_qi z=)>&c*L+#C9CSBJfF_^tZ8H{^F<8O;Z<$do&#TPc;5u87Z44@h`RobHQX);zWr(bq>#$&joO&rshB8%z$&pXtO1eAUrdUW8d6A1CQtjzwulQ2A(+A zYosy1K|w*PF!hcSEZ#qUI^LuU4c9*L<4>0%j#FkPb6O7gHMY2}T4DvY%Wi!}sl<>t z*W>T7{2m(3XI{^?UW6H<*_x7fN?`tVtW3aP8Cqw=BN&!PFdg}9ESeXDKG8N_oNj5T zdA?CPz|w&P;=6Q1trt<$znhKA4C$cfF-_QB{t~$RIQ`w8$-@hKyhfi;1t{;_G>V@y zgKh!$k8^9BpmlEUjc~g;a5(ZS-F(Ld%`!1p#3FdW71vYlN8B0U6-=p$T3vvTN?{+E zVyBQzA*ak4QjCl7+Nt-pr~pj&`&swUD#G7!y27u5o9GQgM0ZGlG|0r@LHh%>?ryRct&F2UAxTBBIf6?MMKbe#vt<%+o+s^M%ECuaduCD}G z4rbYTmiP)N);|7ZUvmvu9PJCTSdU;#k@8BT77_SAJx!S{y#zwkZJZF=i{itLEkvg)VPSV0o3qXg z{>Hz)2%hu&KGlUEk#3M3?cjNCAb0&6mi1!{+~@g`Y?{GAsuXW2dpU8>eK{%VBsiP z$0Lpph$Nym_3(Az%PnhGG^hlD)9oaJ>@U$KVKA|0k1&KRhD39n`2;<5r8DZBshNFArLGU3^Q@MIcGo&p;pZ z$vLbryS7}u0*<6x`tK?7VSFxVmnyCjPNi|AqPky0Vqvr*NgfXLh6k%U&ttHiEc6ZFZ05YrsJMwV&8EMR>PqhF{J74z=Fljaz%g52q8$ zRwpM9fV234cXR~ib8hB;NYbST>&dPD@V8j@j~&WTRKpqhm-0@&ui$JD&%~`&Iq+u|sQYkj3dYQ7!+jq&psTt(!jJcL zp$5Gn;=i&4Mvf1Ys~Q`@pQd0&B=sjMry0NPaLo{eDpvzc`tHEJRr)fYUQxi&VX3=Z zIfL-+xx9ophCzwoY0%jTM6m6ara6XU#GN?jFAPk}rMd(ybOVW8!> zLi0{t7W}gMwEiU=qQ$lZTq9Jqd`h88+!OU8I>3gBg1aV~E7 zD597Rx4oy+jsEJ2C1o{lBHf9HGwznB=x2&v+x{>a97x93jm#TB7cqJBLK82r6_%Wc zOwA&9QlGON*OnnHyt|l*J|8NH`;89R#-MF7xb0mp6&wn9+>brBgDW=nPshFpL0577 z??AVkuzlIRQs6=igvK9Tz42iZ>20!9GHsV&KD~>sIPVL=NLKD{|J^U>lp?*BHR&c? zyX!}Hx#ulBI<9uuBi=?&&y?0JR9J!2&6tx}H3HDhGoJ|HybOb$H2a?#(!l;hMVZ;q zUs#Z7J18bn1Eq@jyYhPGU?RBI2t~2575r6@lQ{zN&ILK&xqk)DM_PCrCYr+JoR*UT zkuLl?pP9*sM*~y?(O!k(F9J5m-OJ!f5EG>@fsLwb-K@i^P{)Gb zQc!jeXbOhsJ)a)I?u)|$*5F+n=yV@RV#s#E&O3N=ej6m%erPc}!nlv-w(;tM@t?sP@Cl^(mj~=_@^Kdr z1>oO7mj0({W6*AJ6KmTt26FO%)xxU_Xm-$Fv1HlQuyxt%_VzPS%e z9{IUL1M3BbGSmNnhf*fmu6hETc;{Rqir#^CD!=I3H91&&guCFO@&Xk(W$FAyvS9ad zD9fvo0rcW6h{C`2ptt^Oi1!T*e7c^Z@B_C9_8ng}v<^-pEy);`gj3 zNaL1$x?9l?BwKjh4ks`fRP)HyK4}d=qwzQ0*u-Ku`J8#g>uC)pxh2l$KRty5`uqJq zO@AYOkr1{ViWi7QEtk;mgbheEJ%k;MtRT7SlTIX8J8-4-FdllwA?HnVv1oNt2<4^7 zotUabZeGS~mn7E^MM$Rh71m0);qdn-t(FN8C5A0&$|S*<6aPc^ z0c<}FJT`B)1+$bGV!uNo2#rV@T;&LW-UVpdw#9|fiV?NQwn`MvE6^&8>E&O(@>6ZL za00%m*R$W`$LPvdK5q9uJ`5LjwAGam!|AC|&@IyvbV5V)W?+UG%Im^~e%RVV*KPqp z{r5?fD|)t$t!xB|)=u%RtA+xpR{65Y(`SgV%jFYu%mm;DO;=|thrz?D$msbBHqeTt zd&pE|4O4E%{{*mnfOb&by;l_DD1x4-btSSIMY*z9H9DMuCaXne%aC+n`caZAJ%#y! zm2TNQx;X`5#oEuQVYReuW zFYsn&{2}ti=CBU-F=`xB$cNefvgyMdAmss5K8({~t0G=D*S&z{u&gYW#|Yp)oywbL zY<+UIHc0Iy|3g1Kzl0|ZvVuB^w~>H17bs}l78@jNLubBuR9>XcgeqC*hi5cQ;kj+- zBU6Dun5DNQ{Z7~gl)bpLLfVWlFqbUU_KzH9kIL^ldtuzI)oj~uW4v&FtlmZFn+TMQ zih0z}7DC#}^V+X$m_87Fmp#eZ2s%jw6pS%tY%$!8u`vBIG%d~6Q640L>-JCpWn&&l z_+6dVHGdD9INPx(Rbs4R+|$hyg))Az(0k! zfkKp`W_`~c%*##%4s4jgXz0YR#H$6qdnE|$$_l~f7O`YwiUmw}@t1k z0oD&yPH5C@fXJhn*3>>2RH9_I<9G2OMnc>owVn#th0Wbj zQwcfMV+Y(G@?do$Ggyl0fH~)>kp4CeWICx|urMA$jH@^DZ2{w08M>V3cEs}K+824_ zsaOGL-M~Xd^)kbT7``;i^h=EbNuor(BIicR=d^o=g7fc73 ze-Oj+Ohk8i_gpD#LH1UIwOfk_gj`LK`%9VuYP?rfE4~H8@!aXNGwWEMD?g_$ViG&A zpPX;zbyvaoU5e^^l_SX3q$NP)X*GQGSiV#vGO5DO*;Wj98^eTN59Sj`YyiwZJ zSKv;LMYZqwQn0()CYkY37S6T>NceiD!99AK+mZ|~QT=Ck*1PxPA!m)F&#no(CtnFa ztiZS(Ddj#ty5g|+Xo*+j;^qmbkLP9bo{b}wcTaI&O56qE6vd2ZZd5QL5c=ZwQUbII zt%GBkPHGo8M69hqcJ4;it)hQMKA3cJpW zkTx*EIF{xExlUH>U*B88pa1Mhtqb^|w?Kg8wJz4eo3GZ)6id#oJ!qTv^`Eqw02{m>G6q*daL{jY=df0|j?TLzK-v3{<`F;s@% zX1u}60Zb#&p&BM*p#SH|cAf+RVb*%3A5FEOW^J^^C=>&hY~d+SIu~Ie<(+c=n=u3f ze?Mha-+`}I9@a_=127fNcv{t`040py2!5H*Bi@*)vQ=AoV6Nh*?fEzg^mtSju`Mi+ ztDI%2GHL?{L;I17IVWiBevmS9$Aum_?IJSUW^~zhy8pq-RZJgQNEA+%0JTd7o|2D- zQJYo_y)u?Nvuh8VwBMbAgSX*ieBzX#_ddHWqy7>^<(w6lBE|A2$nG`Q-)Ur1VzwtI z@DWrKqF!EkqXWv0y{>89$(I0fOApK9a03_*9u2~Y z#DN>i%YmsK$M9cM+-`}>4tnoYBH2tniR6Nz@e*?k#DthVu*LWyw<=^f-PHNv&I`Bp zZJti}z+Kqm_}daJs8i=_T8x0?_)j<0ih~j8?M&cGWjMg- z9@ULrEO(kY+p6&5dK3_@yn5$Z(~Rk)E3Z_{aUr?n^ZkvH8u(ZjEM?r?jBcdRn*aRC z4~(nik<9n-;9=isb8lQ5ddi>~cvg)Mw5!g~>+klX9R5)|SzZHB;9Mm+l){HJ9Yc&h zWDP7%#dJ10oxrlUpx{p@2Cr#My#4(-U^};wFSw)u7^>1PS<;AtnqDBU{)8BGoP->; zjlM&VqQEiGe+=$WGGeNUW0zr z!ml<;4SG;aT1#)ot^?%*4{NhDMnQ|$;?f(ARB+X+VYzxw6#}lt=r0;ipp%bE>1T0n zf`W|$&3@r9;NRk=T?qSu{=9bzn2VK$UYoL+s<(1rb5G{*+5rvpwb=GnZ)rfJ+pmVX zmVD?nr(0Yfb%6&0`az0nGGOlC^xmIM0nUGy*&wsOis`CJGk@FJ;HM8$%iltMP}^S@ zp;O*OK|daTG5Tf+E$v1onn$XjUS^-bwtEcX9gRO+WW-j@Ac%Nw}WpLVw#@g9tMY?I> zt?g%Zxw|Dm+c}QAz0TE=POjZq^^g$efBIHij-3HEJ{7*GvUT+KlIr466%8PI8KvhD zcOdg1O{pQz5+;LgUZ&gFMdD_Kmi{*;&_$)I*^Ud=kd#%Ln=5Yy^*Rw0K>{zJiQP@K z>98GyXGG1WUA2M5eS0{LAREbS%*#IP`-#?EIjG%3EP=LAm3}R465XZxj&JRa2eTTc z8GNI`Fbr>T8QIl=coeUoQ*)em+;`X^_DRNx*)^?XPy10&`f`?gdnQ1)?GKO|8V zV&mcyJUfK|Z};qjyB}-8N=$3CEpq_HFqJGj_(=eh?h>KB?h;beY?3%VrvSqYCLz>< zok*vreo85F0htS=h!IJt0)y0^m}lApY+ZlEjTzg9=PAV_qJCKJSm8`Vc-;kPHR!Tc zm@|Tn*o)rNN@pN!nbV%7SqppxyfWL5+dwt&tzGm>?0#>3!(>Tr8gYlE_NMlo0fH|V z99BK=1AoC|aXo@Sa2U>N{jK2+8?3x8gTl0c^H2`yRlS2aXTQ6wEhZ41`C>>u>=g0r z*4eeY4iTp*DCY^1-GA2MI;=H7~sfG-&o8IfuF&~-_H-Q@r9r*ipmj4??J^HmlHMf>c0z8TrmPy(!z>c#Fdz!yCmT#SVgFkx(ge_`c z{=?R1=ZGFLxvL%={>SufkN-9Vyi>*-__vNGDckyodDI|dT7E70I+mljZtgkxOby~M zI8UUN#UnQXx~wMiujowz$syBpJ7QE4p4;)Ug6*;u-ASwOFwm^(RNxi@r_RqNB^8?B z?OoLI{_jdNTjFu`D;7=4G%3 zrf@tQo#$4qQZT}~D1{$>4q7^yiJz(*L*2Q9()yc+DB*TR z`P7aU7#JqO{un8E4SM{I{6z_OrI#DlFfnkLjBU6`b$#ykRg+0GSNte08?dD5RoXtoDcbiD148?@mozf*iJCB~16{jpTh~)v&<+ z^z{Zh)>(E^#qu2o^*;Y`ioSuZJ2*}k%|xJI6U&G%lQ{u zZ(ej4Xg+6Tfe_*SzO1-W^wK`=bcf*qSc^CW6{%sq@$B4qvV}z~e{3valh%M3c#1>3 zM_S=TJCL$o2|>5)?}xWS`7s`4DgWH8J9aLxDWP(818b!;&JP{Sh@8%mXvY~3ZuR@d zH*U$pJ*kTU|0dMI7{0m34jrM-7F;$OoT4yo#IkkD+l6*vU4*AV|eR;jPRX!hD#j^ z61RTgWhez>@>eCN>zx4Mx33?`N&&mC)`_K611eV69b|Q?MTVg+ulX*A0nK;(Z=v2f zkW^19z46Zz(_I`!QdW&2OgfwH(>08HBbe4CS+|U22xug<{&b^oh*?*~?w|MF&HwAZ zjRQdyhPIru*nM>2x;M!sW4L0{&OF_q1|F5m5%`pn^mt8b=ui?qZwmf9i zB%m85lLAc*VIl5#Jg`qi{nBGF2$BXmKia=rMw0?KGra@jsDh+^T*mw-$|pP_{ZnZM zl=4pg?3Y7;mw0nKnBW22#e40d;VuCOUn?ybj@aPCAH(-8RZ>7d6ziMEWCX^lC7bVE zWkAgENXzl+2j>@+u)P=UnGd9PzV$ZN5*OW%tC_3EH$56%pza-1X3 zdUb@v7AV-RH)H%W9Mbw*1sN!k(%`mXp&>}ty%L)W>qSuvTEyofiPw3w#2u6pvYEC6?1nCy?YqaPRn2eW|W#7JkD1@ zER~LndbuARksmz>ro9UJT)!MQ?5co!D~V{HcMV4_`Mpe?S9$bOt8c z!r*T^{iOH)8WPH?xpQCS6pB@u<#2QV12w_p@}#3A$e(e{Y`Sv}hHd-5r-TfnP&;Oi zSo3v6HNCKQSV9Ee2UAb^walU6wcv}$bIVBUo!b7L3k%KRl{aK?{?GHWD3E>U&<~yq zqqk?;34q&7Q$F@SGx&y8ZH~_H0M|VAsoPn7xMosv@amij1f}*V;1m)9fqI9Lc32y* z?HRvC!~x*izOglv@&+~zJ)h!IV}8T~Po{u0fUS4+sb-O0;1n&ICM)w7#o$}0otmZq z{iAnQ+}>D@*T-rlQQ{3We0u!Uq5cp_E>4cD{lYi`PaocSpePQm)P}?vxWAFZm89&@ zPg&r3A*DEUS_34VJ*wCx5`g&Z#Mz~vF+j~`WSQS@10rHgZzm)IA*+EQ^%IRg;FxBK zELnEL$@-s+S^X|Vrmo*ZT&)Y_mlXdopQ(qjU*E@ttfGNHtd=`=92aVMtFOOU6oZS3 zoIk&Fu!H|ir*3gBP2j~(Avw!p2@lmjacyD#)f4(ZUre$HA?e}8hH*+tSVdpmqvOZX z@3yYihN~vP*|+&>3G>~4slMCRGr5g$-1~C%$2yVX)_H;7t*-FCvmL5QHjqY$_x9E2 z5Xf>RfN<)#}sI9Uvf3Z5YMk(QR3uj3E4B zZDMO;XE3-OCZZBw4U*sPKXa7HL=QFhOmnPhV5vZfI!km7F&8B#dg16pmZX1(OKb#W zwjN#jloSja_mfPgWXI95?_)8KISp6~6pLXY-NE!pz?pxP4v9&dn*T`e0sgs~GHnZO z$X`usPTXaJ#&t=e1T}5=;rKymu(be%58yeAgkzkH`#$N?&pVOh6+tyCjN6k(u4g~x z^9)^^4{z{nSVXE%%UCzH2%*DP@0zC?E(rOE_L3?2zzdQWjty+bNYr4px#2_siZ78| zop!>wS^9mc?=(K5FI!h@-bjl8%jbN@UYTOFJkDCsm1qZ{@6CP)xoX1jIjx+XTrn^k z<;!V$91Vf~xXKP;KG0`p;Cvux2<~yquYNJE!Dyb;59f+)@XI*u?Y}Mxv_YgqrzXRQ zTxlB5)0q{T4ZQ_e=C47JD%o(Ys0#=k)-4Rx(ZjP^VWV-3M|DDpcbj!614vAb?MiY~ zfMJ{Xt7^gvbni6XJ&t=6*pDMS%m0=jPTsEjb+zBn-|PCEDq{Zdv$CwPr4!@qj?M^c zYOf#<{ZSm+Dphc)?s}zI29PADNcFEDL6j`*4Tczm@v{uK)G4P?;-vAlHcfFj_I#~E z@c9raQI;MKB+~_HFtY5vjG!Moul63kvh{BRU zOL$sE7rdc7FybEhip?X|LRaR(Anq4S_%rOk`*eOVk~?M*%hO8hlwSz~?^v$9KR#bk z+hbN~`tC#&5}4?^-9rc}=NI$ki#dTxk0lm&%mXg1556<88Ai{esf{k((1Ui(D>{|d zkHM|gFHtTVyFdMNdGpLX4VmjL`m_eTK-mx0a+dvc;P80AZ|V{`41LQ9DpBu+d6mj{ z0ll=~DG~p+x%U``Re5uh-u;BtD81|SkGPVbPisv#N%@8 zZNRR|`$6m61tga!xjHHp21ieyB>K{2p{1@RXEr8BD7-59Fs6DH$Ci;E{m9XQF?FU@Kp}Okzq31Im*5Zy!8{ zgyF=;!pd&&`?vFjiwlfU5>@cqlWGu^40Y7@4;sUHmCN@o1@)pb;?6*)xi>I9T;PZy zTi~^=Qs4ob2z*Twt$BOj3X1;yNNF*iL3^p=J31QtKzh&O<_ea_iOf-8@D2TndQz^& zJM|?(z4a|xFHZ*O?im)xA5DSo{3F{R*nYL|I53~ua|x8BgSoEV@c<+6u@HDOiDY+w z^weQKtH;lbsnQx}QOduviO9%H@U>XjwQNcfXspexCnt-5j-!xQy2=`I+<6Mre)J#% zC3>4pn@UK|_aqwBasut1EQ(--i|{K=!jtQB1$;?<%9;3x5FT?sCJqT?z;de3Z6rtI zfH%hOa_SfrWEWg6?AMt@!a>IVTwA)Jv1YGX`fLsv;VaDT((8lQ_^(jC2`NzeEgg5z z*NJ@DLatnD83DWtG;J=AX(4BQX8w1V6PPPHcRZcegBb(Oukt5j(72*A%k=0MS|YsA zy*oUN)IY}j3v*|K5k8V@M@Ne&Nc!SurWrH%pq6(0E^P>9`Bqzh;qV1lpP=r?2{W)p zKm0X%VF(pk4cvP~D+HWL=lQHMvHOU&e9y)uE|5sHiaf@dK#a4*SI3>X;JwO)z@O!& za4>#z;ECoT`m9bW<@OWfLi-$lGPcFOAKXuu=m)lu1f6KY-o2~faNj=v53ef(GY^$m zvAM&ddpc1?pc@ngGqOD&=Z60pizlttXAsV2gkud|KI*cH@g9!EgR`y;Bl&FB@Y9{y zBH{Kj3Y;}%|8Ud-lE?Y8d+{@9MZkd&zhM{z@Rg(b627AHLdBnd%nShxQRNyL0q~bk zb2PrK1;6oAkAo_JJXZ3>MV4BykRCpsSiT8(4e^hUoG5_t!N6vCjt;zE5Ej4RYY3s? z;^J>H&dShE-h~M)FTinIl)%+f0+MwH_YYDJ5c?R;fg6V{1PW$-{&Rf|;Whi8p=J7o z1javp7jd)&8=I(YX>L0BmwP2I3G+)fWzDJZCv`#jZo z#ATC1u?g>oXBf{=J*@B>Q}Q>|XWo(35+VcayiL&$p4Os+|F#ClQ!3F@u{n3s;#_F{ zYR_gM$_@P`Yrixqi@*uD*T47gG}ud@d2u6g6VbTg_;A?DfG0t*sj_(pc<@ZQYs6ZB z*uN(%-6NAI3+_K!Ju3y%|5nxgAHT-lpN??$)gh!8(Ac`7N(V%Bw?;$8qhRUT<<~j8 zH{tJ_Bq#N`8bn(d&+@`v1xVY-DW8tF#UZzP1Ro*=3jO)pn^7=3mPFRs*+zY|k zosAN@b4WK}(JztyBbcvfbG>^-1tqjy@)4_#AY%Qw=^h6O^e~CK`-BRDhqQv#)QL4P z=88A;E_cCYji|_SHY@o3HpEHC0|#d6^@VKo&A{;z`DG>HLU`1e^gBqi4f)wTs%T!o zcplWZb>GusoH%9@51QwU;6tD2?3iT>K~=+JC;jg5lIYmkfb$G=JjgD$lRCsWvz+?) z{m+n*#IJ7!e*=MfrBv@`3+D4rzpgNlDGBZasV5Yq%gF7EBg2D&1en~{r*olt1*4(l zt zCYq#FMiiLhLV6clx!|SWwn?=aF$hfP6huj@K(&M)2%{*<<=9JP2Mgdxx4Vkx%(U_S58C( zER7+$M;ZHuw`x&-wP;4q*>qTXUlz8WgAeQ}!}Wg#Xy6QouROK`fwo!C6~96ss4`T} z!EaLr@$XcL>T=#Nom*hM6$;M0DRJA_Fk zPkP?sg0h!Z)+9%mA68#`hulQ~;|)zs>SH}W&JBLVrcH-P;BY5tGf@P(a-J{!KF0w# z4kcn=Ubdo&jqrL1c)c+9I*uNWBKHvk1%@CgC=N+WAG-dTLUKBE=gcRHEn z-mh0vW&~!?_4`3S=Y$%OuQBt>TW?#DK^R`7Vq6JGd>77MO&R2vYQX%!joS?Shywn#zh+%Z+J(O^Q3Lu%+FIA{M-r#0S>uWch@`!oH1W zzDqNVWmR8 zm5t9q^MjCGdxSWAtGE%R_k|v0KQW(QPOL*QRT+O0``3_;Tln58TN?C7|7Z1R?>cOo z`(`?lH)H&GqM?#BRnSiAe8Ew&jLv>CzvF;$iwGAhd))X^QAa-KE~{-3aPG#GHQEFN zeeLbBgkNXjvnM%U7Z=7YC7Y10b;gI{;DQa`OW)$gXXA>~k zJ$168CxiObe_eR4cu*x@?3wrVJm6#--ot6_M!Lq)Qo^AP2v)fjBJ=*C;2Y+8zBzV~ zYFTrh*Wdt|x$7@|HO&O%#2HkN^~Ko}n+X;KdBW&IpK9$rL9iMi-pqCVg#ri4^XcTy zL%@ZN)}P`(nrB4()Ss`9BMA7A$KDGNYHuO4f7cLn-aPhKxqhal)ynwJ!)Lz`%Y9{E zxo{I~Zb)paQuqfvzokkPpaJ+8+2gtTkOit0yb;hexX@wqWt*a$dx#r%LA z2H0ktcnNCIMy7sEo3S^vd)RjKU3dbabwcMa7-AfR9b5-;{9KeDE+=l?5r-AqN=lHvKhEdRm0M9Q%AJE9g^(9-7fhdVc^0}jd2Y(km|aPyr5HRmA;Ob2<6E;{OuYeaB;}u*3i@ddf3z}#b|L2E}yMld7SqY zCLDKuki2LGgBwpRWo;>-b&VrXB@J5_XXh>-oh60mGUN^CS~C&9#X05R)N|m%Pfh=^ zfK5R~PL3EHFz2I& zFx)*fz(Kd!hb};}*F<1p-7=gtcva$>{Rs%H%wAbfT7jzPfO-;1IGnE_a5Xp)gBQx3 zGZo^U0D^{iZgQF5|RI-P$5o`1>RY%bc=s&wzZk}WQi88ShCh4JN1Gi- zmO(-=I9hh*saA(I*`ecBOBT>bfAvb;u?vw~t9^Wg-Fve5FS!XT$U(V5+1P`k4@jhx zaM`>-2wJcEk_ZwiL6Ow2eN%EONF(=jf4_49ekVOSX!y?%KFV^-*qaQ3sUJFs^C?w7`J&M(1;PUI(=Vp2?gx2#fOT)NQ2zSQt5(?fqU?YjsgS+3EGJJMl!M6kZhC2?o zK&h8B{@!bhujbwI=r5iuB>VHqSCtCD#??{bhV!&wIj~AF>>Cg9|4EcBGgJYER<%v& z#Ya$dH6oRt0Lx!8)Y?vxIe=wEHCe{%7L;shB+q=a0*;@^t_gfqf=eY@qf`?|=zP3) zlZFK?h||(u;jivMM1H0zZ{9Q_`MyDhCh=>qtH5=G6yF1GdqwEkmvVzEdAo0l`xxBB z|N2spVjE>Meo8B&y#NO}-f`QiVX)}NLgUIeiyTb13>GB}AjC^)t}|2v)H-e^1;-r0 z&`N5T@i$YbkGSSyN_d1!U2Ho`iE*zu3KPA1&;J(VPGT9@glrUoTsfWTZh)xA^F7M? zI#d>wM=S&rs59MmQc%wr0yjb~Y7%?E+L%>{&qe}BUp{E|OfN*Yj?{)k!sUSTnd{5) zg`X&%Kfjk>DH}U)OR$tg-Gt5kx$hMQy`VsF-=50#5jd`$QF5c@fdZ3|09-K#AY%Gd zUoE(SXf|CNxoIa6-Nx#Bqjwmm`%p9Bty>L>WFl`;e9sMP3e1l;YSTefXE$9#|W z6Z+}U-xVb~3N4CHP`7G4(6)#@6Jj|o>!$_ zL^t^EFt7`1g+ZcGv+rxkB}9Jr!mo^2jCXL8XHC*~4bkM(a<`8RfOH2jlV{i>{IMUr z^raZ%YqKUFSPr(H z_`i9m^AU{%irjYR-az!5>;l}k4$!aIxijpB1?cv5!oPUATWE;rvs&giKDhRW*u|aw z7qEoI3c&I+SKQi1=46#(z{k7>FU0icOy>SoU`1uAw4o2RUpe&>J_^H`J?k{U&t zDLD^OA7^jpk7x5J_*N}m2Ct)E?hxdz#6 zKDa{SXb7iQvgU;dJD}a~-irYdQRqK%C!?nRicD5Ma?&vxj)JyxLVmC|- z_;#T+?lxq zTy{wi8~c0bPk<3nHaw<`jtBxyHx@O@Mn{Mx?0yr8opZl2M}KBIiG=gZvxBY5!f>Mc zQ)ygv7jcg--;~Ga2fQ1uMYB+kP)4fKN`e>cK2Ku`EY1e4Ri$H3%6qW3sI^@1WD)7p zazxL(GK7Z9E^}QK>R^b$i|k&0La&@ZuwANOLu10J%Op;?FrfQly!;iG&ye#A+7Jx^ z9oB?=xw>Ygsl4HM`YjiQ59P{JJA6WpPwE=3YlMT}wZF|&ns>oSS3qPXzaNeG(ryMw z2!K)ALFKM5F{Ds03S`IW0_)QoPim&?QQ98E;7jg3L@cze6%Zf^=jzDJM6a!(LHP&c zae3Zg)O3yNNVx(gUK~G`yuKp&W9>+%A)lo+jfR&GMWm1-&OQd$>mw- zA{*Fsl;$*@pGOu>ABCg(euIsG5B=w)vmk`*YhGn~gOBc?ef}U*X!>Hx@m|yeIyl0_ z2kAJ##m>S#%4G_2A3he5NtXeyDxI@G6rO`2745)U{|Y)joZS<-FoN{}UNB^eTtt~~ zo~enp--M8XfqQMwNPySJsF9a@9FB6vTns2=Kv;q9TGR`S2N5D8td5%u85f14MB z7-5p~byUxD~wY*G*4DD)=nqjRE4& zReCJCTxkU;%iP9QkN`HcO&C4O*P@6g z_Jz*%r5*6wT8})Mu>hm!qaXbr>Y>DCcY^!uBKqShprniNU~wDWOBXK#=eWt&zWK}O zl&Z5~T>l7J=VOgjc0v$j+8?7OTaHd`T;F;oU_Cet?a_1=ij-$5 zw4d2STQ<|g)_;QVP~u8k+;?yIo7XI-T&hmbB1@IQyV{y6w z=HlN@zG^Fj=jmLOh%YlttR^}!nZ!d8trVVRayD2`yx?J)U;?v z$Cm)!rUXSls3!()q5F=FVfmQP<@@C&JQl1sQ$U=r{|jm(?J9UO_79Qk{(YwvD+z>zT5A@)K7r*7Tg)HUU+Xs=ks6NT{sJ}=Z zC`0}1>!?nU;1=2KRm&A*vh_Hsn!*>F)++1{nB1}4l7~g0@i2&2I@V_{E5qxD-bS%Y z|D)(U+_`+)IBfsOmXW;)$zGNFvSpMJGO{XLr82TdWv|LCMMfEA&#dfC_8yT@Mnq)4 z&-({BIPiU*`@XKv=R6%@xlZWnB_2HZoQnAV66?Xurxhw|k(|)~GMrrfM=??~A5ofd zSAZ3bEE<{qI`oOLuv9Z@7haXSw`G*(qNtanMBzpaNT5Lt9i=oPOI1n6%YV|qOe?9O zIz<$4i@Rt(28^RBMF*+m09%NwZ=I9NpoeD{mY)viQ$co&!08436=d|Xd(^Ef2R#q# zscs_JMhR!F^l$|v;M?}It4gaJ;KMT0RL5frr(H&_$0^D1N~-vy{R=-JOeDGZ$4nF| zB<@$aOX9*=OFYF7S!Y0P{b@r)(*(w&ZgpIJSPCw0haNk*E}%PaIPWYPVtbsLpJK&3 zrO3DgUqk8rD(bDP)iW%W0Mo1_(PwXHpGm4NRkppA6RkZF4ND&{MEo)w1^>W)oN#gl`0?4h)$ic~%wFveW7%6rC1z(meX+dB zb>SrZC}UC3CTRYvaJT^~p|>aC!Xm3L0^o(l%f#KrwXQV&h_V;M--h;rQY%P=mGK-oZ3@X+`n$ z>W@QT-dn?{vmJ=MslbBi%N=;euzrO{jtqLk`gWQM^MH4S#;euaAGm1063t`pn;Ktn zJqr3i2!GV?QB<)VJWG8zoj)Ia zM!q!sqH9JzQT^`)50;T!<`voJ=l7AuIY#9qiZrO1_{kSMdW5=n`d(S;P=T?Rz(vx2 z8K}qcVKdiehlusFmMW>5K)P_TyW@E?tn_3VK956Sg4bZr5zYtqxYh8_ej5P#c|yEg zy#chd5PeNsP79uXx>)F#I11)X4ohqiuhESF_I`F@%*XS4wKZms5bX70RKwqvA*!ca z54S?oVUJ+zO^-SOydImJ`a7izI?vxS32+S{N}Kgfik}$gI{D@XM*#NqvQx*#Pt;(w za5^&T$2a6XF7fJh0Ksm#srGhkkHTJUo;N0*_BC ze_U%G!J+7Nfw~8~;1~EO$$-BYasHs=oh0}Rh-5ABOYeOcIKE9PkCz13FReXs?D~w- zDtVkl1`Xk!N~T-wq$C)s2V#itEr=j06`}eY3!Pj4G~ZzSid*6f3W^o~LH>C`u^4+R zzz}$+aVD(22P8N%@mM6iqdLJ+G4jNilQx?Bo?;lXyQ*S-1@7 zE(bozl=^{I@7^eH*x81>KwpgtEO+8lUCPR9#tmVKiHgNJ<8>bvZHHnvw}CD0AG^nU z%tuJd(aN^_0YyC%U!ywYfKy3({GH@iAVPD)ca2dHRvmiOUMx$%%h-_aLo!X+NN?=n z_2FviK&T2!6}EyKWU&XCFPpkyC!snZ_K(r(+*xu zXi2sG+5@!X9AO%aOHCmNL!#0E&adQ!UwI7KdtTE^PZc2k+h;e%R(tqG(82EiTNP#-y;pK( z5`l>Jff#D{1XgJ|8FJ6R=(|Tlv)An+6f}K}Mdm&i@bEin4ICcS;irYkX9Xq01w`Cz zM#}&i`Mtht78FoNIa%i65Di1+k8sK`&e4YZwYd(g*CJXfs{blQ1a?1n;Wd)&q4%ts zB66RnkT76KE z03`^7(n${MmS-D{Ya!&z4UWj>O3%70F-BnWFm4Z~DV8L-@~ zcsC{t0hwP3b2@5RFOj!%#c@j&KxpC8dm}!$Su>B@z;A(Z{vVBX;zh#rKOe3{%tPna zIU2=fS_|P;euNJHO(U^SrWZOg=Fsf2nvC%HPxPCp>U^-;L$GvdBLB|d0z`)A>@!*^ zVZXQi`AJp9X4zHI_f6{1Nqm7~^9PBy174;6XQeURfUdFJvDd z8>-`O10(#|dTEOlsG_3vBq(GMX?5h*WjD;DANOt**n7CZNngX*^L~7c-!NC^Y_fye zR)SxfpJXFVDiO2!bF)aqLC9M(cNryn+YLG4%R*e_M>%aQztd9L&Z6x0SEsOpj z(PX(h%o)Fs+`df&!6q>%kM$Ta_;AAbmB&s3OW3(h?bFh1t~>}^vVAO2Q3u73OV!2? znh}G~*FH0|MwGaqbP#iF049~K|6WY`!*S5-VoJ9UV&rDc2TGm9dZ2Pe6D5pwGg!H zBc~6y0<6;9$L7KATX6bd+jkT_QoHIsrwo1n5yrnwh=(ULk~94Bb`U5O&r$fR6yvqi zC`G5Ypw@`t!iOd4hX@oBg6g3a@u0p*i#axK%K4PP5eqJ#< zf)tx3>^p@2qCNcNxI^YZz#sOBoQzsTc^YW+fq5gkebzncQim60o)r3Z{`do#IST#w zg4kaE<{Or#Xd~!Jw^jHkT>%sVwVr3`@xhOyA;O|$0y| zTOiU&c!OSVZ8Au(Jpg}R8KzhE^swt%xpkDy2V4`0Re9yakfh%0WzItdKCN~*ySyWa zdb8uFV#;T@Q&qZEd`TJDDQwSw+h0Mx{*-OAY|SvrsAdt9ssVD$gt8h_|B&E+Psht5 z#et;3a{MskF*M##cq9=|0cYN2UbN{vMDqfv3nmh=5ON8BGN57vOe4!V%iWE^F>xZ_ zuCoB#Jy|X}K9GmsH=UDGxU#`RCf{0)ksBNg$ji?6-v!)*#trKE78o2^Ap9WK3LMvZ zU4DpB1OKBqnXGCucpKJgT5abGx{NMO)8VY}W8jx4q0vtbe}V_7zn&A9D9#5R@&rxI3)1jcXj#6M z1@nv4O5YTW%ZDnJ&?@@tL(nm4S9&S40hV0HJf%Wyz?|4?!?U&(mF!FsIv2eGbCm}U zfhjkkrdq71^;90DhjMw_v&5m`;_6N-=2dw6sqvUUNDqe67;LoGcERlHgL!WoL9m-C z`oi#~44Nldrxo8mg15KT%>(E#-ekW~C-=1>^hc)0`HE&b6dZgHd=-ETqCe_CyxAa! zH%IN>GGD);jC)T^afAfHaipJ{U#%3$MY+tT70Lt7S<3A^oOMJw#?Wwo%ns~(_?6;f ziqP}U<{$KOZ7>nRL(OsiFH*HFR9JQ`LJpTdQj_N2fb}9?wrDjbNUGv_#^NxBRCyEA zOj9MG-Rt&0Z2aK*-eyAjUMWN!COurH zKM(C~6sjTOYZ%x3El;0cJP;J`>280NfG(Y^jVlW@F!;x=l~|t&;sP(6Ev(x|kA~>T z@%5F#;@zfZZN3BO5g$E!aM*@^B+cnB>&_smjH@?2*0FQo;e1q+^fpp@Eb!zZI~^P( zrE-Wl#KGUW=pqLBbd;z;nLK(tg3kXf;5qYN88S)5%4xqRfqdd_{{!qrqduopWtRLN z3EJCl3P^rK{XZ_Vy3GiHs_(nA#kU(VKKsBodZz{y-!0_lCOU}D#-7+(jc!7qx|Qy` zo80i*0r!!gJ|hU!S$~^2;{wd7yPV%En}Pn}Xm@RI8JLsgiHq%80lQ0_lKCtz#I4je z51C_}?kb*i+e1mv+~L*?mCr;GLNU(Un`6j{Z>`Q(HXWY#Jo5074}*($w;U5>D&UG7 z{Q~5>LojQpl_uuQi z4r)e}>rcu_IJZ#V&dq54@jDO_){fh#Pz)Bx!*W|>?T!K3-Mj_p5(6T9m>~8`M>?4*9r@WdZMOzOq&WE zb}zg!4s(Q7+&}3%##BISDvJ257Z6!r!i>7B0+2h5ZF($T#P|btu?!1a;PLPay~HZ8mBae0t8+Z8y;SM3X-lj=FVHPL9xgyDd}(YpsHI)J{>&^ z_*c*Q&w8$+;gW-LPV%!5dQtqgVwEI_FQ~mIwkSj&%T90DCosS|v+xAtuodVH8)U77 z_5;@Z{I4gdvF;=DW|?|eY%{aPMNqq((T#W4S^0la%WOy$GS> zaGoQA$?}uHn4E`T=6%rDE>j9V)}&Z#1;KD`W7r2gbtug85XnmIM%Hrg9_zipfskrP zM$4-&(EM`a7(H7ryt6gEIJR&V?(utx6%rL9<3Dq`>`QpyBuFOIak~#GJ$LIJ#m-&s z{Ri!7BLnFC6VBIHYEIoMkrE;6R5Q>>N_Q29=od?gG3}z z;645f6+Br*1nHei#evvL+Lx#W-g(K5d~!zh{sQ!7Z`F zLOl5LV*TUaCwHOPRjWdYG7e0pZWVVGrocpNJA2SjCG=iQv3wc7h$h@_(VSnVfkpKP zo#we~=;VvQ^KJtc2vj*{qmT4}jhts^3kQ~vu$SdrPBNC;>d#!9!{!#oRzj(7uNT0= zBbRMGRDx>oWtg;FC86U5jz~4{bvUaz`AHb_7E6+K>2=rj1CjdYwDZ3oK#>2{Ghgzv zK%BFc`=TZ;RB-X)u_-PfM*65Q_ujkUhO?#mS)~M#wkWbj^*TdjllYm|K~ebh68-bK zA`LR^vb%E27C?y4di9Nn0eqqUbSV6vI51!1o$~sB??>Q>=vjLPR4%eh-0Z=)10|ea z4^#v&j?wp;*r{Gv@Yr_yr9Fs>S-$nUek%u&K33X+ne$NVFCRcDLkSxs3>4q+`G7j~ zgGF@6O}O!ylY~Zp2x23i2FTv<1BWmp6yQq_e}mRgBn=-#t+P;(wbjCOuY17PYua$P zC6l7}Dl4pRH~B<_ETSMb-Ok#xV&FuIY^!TIpmm#rHT_p1x*RK^sZmyf%>g`kjJ4Mw zJdmA&J^P64z5d9XV)qe?PJ)EW>EGzX#D#yXzUS)WTAwO*x}~BZufERM8G2x< zBKeurK8VCK{FW%Oe1lZg)uubsbdbImYG;|4jT|++ISo$^pB2<22RaHx(bY61AWtl$aWC3Imsn`X1374cITq)sogp(Mcrv;W zW){NO+{>naqp`5`>!#YZ%5y;9a>F2GdJp}GJQ*5z$OSMymH&)L3w9aTWuj}nR;Uzu|C_XqF|_vgdw?31WIt7|MEs{{rbWb>P_eS3Me&l`u9MfAYCXDbJr zvpnWLGdgY-17=G23ZXo2(1bLuWsX26&?wO2XllHG_M;1ezdxj)P{We)*=B4`Q02Or z^`{a3HE88J^2q{$s;*;+aT4lEL~V}81CZcb?6cUsf;>lLyx;lEqfo`t*9GM-VQj|8 z#6cAEq6F74Yn9SLPWMVyq<<0Cf2qRH2vY|>x(8Ts?FZ6j4I;lnd=uLnvXWd1DndUD zMX1E$c4644_>;$y9w=P<>A^qggYElv8cT^{;pKf2IXZGzNTA8Z)d+nEM5eg6W;|RW zGvIW3E2R;BXc#JS7t4U7s{ZMn4?*y6>PU*wp%gqzOCl74yD<;!1@?bSz92YTlqh>C z4O-_CMg-zsz<8_vwb`#-DBf?G=*WK_^^GjFFRU-2=c$vQabyl|VfneoXDo%_q+_#Y;$OP^4cl}&NlpsAI zq;GAv5?ubAn01rmK`MjI==T{h2xBB6%>3Jnv}HI>=-~{!VZgQNcj-U_ZCrZLeTqI? zxGFcSAy^3M1B^Oln}5GwO=&iW3O;1T}9HsywQ5(5>?m z+`ZYbyc5?G#hpf^@#N^Zz#TjyVt8Su(GI zgqCfh-t8^)CDCA+YwtRoJ8I%C=eP>05zb~8dN6K~&FSC2_BY_pO6h|p%sW?p2G5g0 z>?gt;gja-BaDkWOD@*?P5L{=R^{F&H1BWI`td#zK7+)p3Dd2z*%v#qymcQ>H_Fd)X z3(-+voq?-*kpBXng)17Y%4or#aIUk~bcOI=y3f_~9uI+(Eb`1bMT~p(@wawej4U{o z1boV7paIYJFPfLkUIJZx`@VlqG1$gLO7|DBgZ1Ul!kR4Mz|?GHLt`QcrIgu3n?p^A z8*{*LF^Yp_^2+$F%15AP`%*I*FB`Fo1uUpBvV+Ja^^FAeFUTRA>JcbDA3Xq<+y-xiL zobmuA^0~kYu4Q!Jn*1qWkpz6uGqd;QHwJ;Rh)o-gZji=Fe61_U2}~-ai~1^8!N7)L zmb&O1_};`zNVgt9Ud;)~^C!({cIz&w=7t#5-MC}VTkQp*S0-|)aesqpNKbs(9v4Us zmo+_{$9m|!+jML|4N)J{<9HV|`m?+q>)!f$V#3ZMz@^ zL{)5SGvG49VTz;4rZNL4sMSwjR}ICyLjGKi@za2t`P}xplN3ab8IE6#r3Pb@h*IAd zLm)vNAt|cZgc2(BUk87~JlmZ2X`@~2K%RXapGf>HERU--^#??NsOVC=v2i2pEUK4} zIR8MR{}swJu?E5L=y;{I(JlDHop+|@A?915D1OEy>jz&8677zDQG>Lzw04y~#+5U| zPy8v)0!#Jycl@0cp}^0LBk1-Ypcc8S{mA|lkvAw=>PNkTc&YliHI*D1F36A{!IbF|F;2eO%$icZx7 zK;&=BP>cLcp!f6r_oS~FJX$GdEem+9{46ivV&PjIC3op)L( za>YTOg4+1G!X8YlzyChKL>P@nN9g#djgcn z**4b|qCsq=>OT^hX7pG0GHKhBB}9wc(V)-G1hV=$#P8|nupXn3MlGK`6kFIR4?Pxw zo6N0a7H7}F?O2wz*!6wX$D%v2Dcl31uAgSU-XsO_QA3l?8groQvBMEIkbpq;LW{Qw z($H$D6F^?g0Q@oqjdEibL7dN%F#2q@z=A$}aG z0y+M|S^EzU%iB!B_8K#q#<>iKQ3}+cHwp zQ57JSP8Y9KY~HpjL?5z)M+@oMoEGnK5X2>B1nK8J0erIRy3N<0No}|m zl^?&oxe01lU7njD%(L{wk$yE-5M+_Pxv3a0#$gx^k-%F){gu7BBg<}3W;@7nF~|k1 z4$OqYKKcN+wc>kGwtN(S_5MaD9kxd=7y9pc<^ZyzKelu6@v(rmSQO4#D2OO8L z6rlLj*E9or>L7+&?c((M1=!8e6z$i@!n}KxPZjpwClBYzlv>t1=)% zB3WffI&^wi?|KPZwRocW`2L{o@~m4_f6u_bBEd&2VDQ-kHK{dXzlPj-%1!YruHxpLK4*GHSUPd7^P727D$?h4G1$Sf4_5{0mD5`V|`fHPq??ggQ^I zb++rk<2ADS)c$SA_HCUhJ{E#~|NhSvBE68!y71J60}s5ybKXyU6NTG9_za>ilf#Kx zH`h0V+fZn`f6gKMD+Ir6Sr6N{f`hmli>htA$l9gv-C*!7pj1q~?GbSi9wwiC`Po_m z#2s=5g0bGwoKD$(xzRAB4vBs1Ii5oTbH)?~fyzJ@$;%}W`5UDaOLm=4!ThA%VUHAj z=|Egj)@PQC5Ieug4c3VhLg2uK(qGs9qGZkaTN;md(M*O{-z|%2qZ%c!LgriAb(>OQ{eV`fKz6LTWEM@+9m^WTj zj2@471szfTTO9LI1t(gsX1x%3=%cROQ;Ws=C^cl|v*K>BO>>t>+h*KJsS?_tRh<&OZtmA>OSG!!*T?X7Ir3SYnm|d=OwqhatYF&>vGkT zrNg{iuxMKQ2zD)KzQ}mW!?ys5f0sI4vD`0dh?j>W1X&E}X7Pr?<>W8SQV)g@^=`5L z!`u%Lq{O-R)&aNvb3$1qxgi%eH$JpwHi?1u?fXeh+-3kK>BRg*?;!SEiM|rmdmt;% zzTYjmha6?>h?~ZWkfiZJPjt2&#Qe9(u+1@#R%Tx-^Io@t<$5iDzw;Ppntr4;Sf&Tn zZv-)Mk+egoxUNhCkqT6lEA_4io}ixW<@t06eeAtlmuy9156z0}8_6%3p?91p_c_@N z>^$Hymb)oZzY-VB5gr`^#(dp2n>ul50jv)rUlbvmr=8zCt8zfNcIJuw|G6jRWj^ye z<#%`An{c%LGPOdSS&tCEi!CCX?HnQYMgSBkg7(^ z^GII!raR1bY`lmHbLm`cZ4S{zy9DQ}&u@eFTnKd@mKPVw^$`{44}fsmknRwfIM~e1 zDT;02f)`B7=8tx~A>rVRV*U`;hdioaB)%;V1VqEJSyh=>|F^(Rh}#m>Hw}sDDT5OKZPh|_rds@!MayjHLqxtZNNRm{n5_3QMi1vW+CW_J?DgJ(_?-L zL5K8W$+_Dv(c-C`&J+y^)Eb=gK2177Mi+k;xs<#HL34(%7Cc#aV$af^(lv-4%xIoV z4ZRJ;>1+i0_H7Wx^)F^5-vZma`f|Uk9!BQ=r7JP7WMH(5k(2RP69~y><&BzuhCP+G zEMe|KRIpm9x!kaYy2d~GE3X`2o(>jW0nCr9K)9MkuyX;M-&BOYRGdN=gS9+LK2d@2 zz03r6y+pXHd@#f;GX^8+hP(Ya#i;p{Y_5dVWiX?OIV2<5N37M;(&`h!AXpX`OUthh z_Y;JUe6jh&6lqOik8ms4O8)XaGo}l7wZF4W3w6P-2J6NA@KZ#@NKB!YED9Uc8@$x? z)X*y|r~DA(#Vl{H%XoNWy_3A>Hs^$0z`TJtN^IaOIu3nTEh@JO_CBHcw|EU9tmPBi zn{s&&O*7Jw2v|fv)EC}4&5R;5wY#^n_iHt_SXN zw_wx1R&|N991+Fc3qQ5@1%|?e=nd2eNo^f(23~3b*9XT=EnGYJDqbUubg-WAzfDEj z<6d;7l<-WF?H}a3y_H538U-Y4R)0@^Wq}yobV&nQHHz8M-D1Z06+3e`{}dWLh9M@V z5rx&C5N;%=_24l+w5{p$Z0qJjJ4058N{9p`3er6wTKWo~`f8fjJ8R%Rr=#EB<9#3y zP$lZW@(U*Rjmb4#wK4A7(^8WcpHWet*5g3W5>V{_^mpvG2Yg7sP*6XL151P24{LOZ zARuB`=beo${5fQF+T!0r$32sE**C4Anz7DqsMH!_(Bir>Q8187*WKeCukMoK3;7r9Uy3cV7(LB(FjHL+hwpPZy-IK6n(qJoY&?y2)|1%xeTy zuRO5jeAs|4@i(|W!On-*Zco@{hx*hZ=_J6c_)`R8*k$&1mCCHk+Y0UBK zZ`~V`WZ_Whr(kDLfKzI+f^gF~?MS-sK;sV+>*jc@w|ms$D`EQy7GI8azL}r`PB9(= z4r&4H@BKUa#xfP)oJo)&6dpl8XFhZN{_PDsM{8Z`)e9)|y>Fz}tpX&ydrX&UrT~OO zj0N{z)F55QM|^Byq@WpK8mQsr18-vdFDa$6!Yi3A%Z%uHl+co~`L#71_BX1woAfab zlknWo(r*!Xeuk0GO0*umJM*!CZE*+j;Cgm$nmWNVy~K*LF-gctJ`OtH`2nfbIbPl% z;esW@1pI4x0wDdGsxkAg4Y2Of)92UA08^I@S^r5HI!W!+ultw;_L<}Tja8KO?U6hm zZ3PBVE}KS#@Xb?ndGKd;fDJC>FP$@B;h_P72f0d_k$;feI-OGpS30CC;}UwlV+OPH zpYq>Q)WBWV`AOrGE%g2VG@V?XCcKwR%Cy1q?SWN3mXY-hNU2(@(mB!;Tmrp}e=lG@ zr7vzlJJ`8Vj-<_g*ZeM!jhjp<^(?@;)L7%v>N;B0oFbyrszjA)w$e05R@nStfnL*% z7BD)QP$N5*$Ft((@G;m%0q%@stO4;L!0@n0P!8jJsV~NaHrPSFu*Ib}Nku^Ha6M^0 zv;o50IV<=7%%k{x!Pxg>qR_ugM|SdC86Fshzcj<65We4!_)X+&+#va0$@4OoceFf!(clZpx zGXiy9n|NgT7E;|YXxWt!1J3(O$#Pfd;kQ1XI%V@dc$2u}JWY0i`WcZB??jB38Cm)8 zEsYwe{^$E#zfcX*US%+!oC|`v`wbsenSCJmiLJ+rk^$7qRC^}sBoJQg;#e>Zu!8@v zAQO3)EL>E0p&@jA6>(iFYE$1LfP2-CEYD&bgS5wI^L-S5BjE?tQ;)c7z>K>#37%L2 zO;F_DAg4_8u~8n2NadmC_=l;9NV=|Z+_NG^2;G%^PSmuz*;dqXqDnGvch5As$B^N#(|IVy|r(^uRujiP>Kb3$xj&h z=10-Tdxp!`ESAtnWebNihbp*u8oPZ-O9aw@;>UOMu->Xm%Yz2X9FREu8EUl+;2B<0 zAI}*Mmhr?w0y`t)A+( zRGjc?7uK(Eu@H4L!~CtDg3GNZ)o4t{`EA#+IUFdGdwSy$!AWHA?DJ9%7*5IKp_`gV zQR%&JI9OHTJwE=MwSaGM6{om=izNk$~YonvKpuE0LMRLzyY ztS}hOH;0?{9VPeRCYWISrmw^n-4seo(3IQ7t>%5M9*Nc;|6EapkM`N;dARz}=k-^4 zFPm~;p7MNpy{9RbS7)6*!F-U^!XEs}h5F#jE|$gVVh#4O6;`F~Hn5%dtN&2~9^6l* ze&RqrhI~s@!i+CRK@^MXxcLhKpxx2zb(w5JguHooJj=y_Pj60(Nu?E%)}IxoJ}H6i zv>x%TcLV74zviop5ph6zf0iny75n{15PdjnXbt8$wmr?CpYwAKLIoJ*JkJ^k7 z0n>+pl@L43-!$u^`O*9gq|fCVJtDz4IVmjUpWom@)sVms?_3FG{Mf#U$sH6<32~$eh;vJJ0s_yNDU&qRY4=u8E~dC;b;~Q7vA2mz2*Kv0)iT; zPnylCKEy@ROYD4PvzSnU}ZNRXz-TKko5H4JPO3SRS3^$eSyI<>a zLhTv4KtrtGr=XG2D9@DyWG-(=FH0RlM!FA`91jOPmM-5}3EKiom0jK8$x`$)$m|Nk z!Z12J-Xs&Tv4hwYRf}79XyKIpq5Y>rP4E~zBJ?qc=vVq+;%BPIVvD$4;HVq#aM zFU!G=#PoD8Wi6=E#-E9B+D7y~l1>*o8=>rX{LA-!d#IdKK)&sB6Vjl2tTIL+1i5PQ zq@Ta%BGXGFr6-p7U?+V!LM_n%TxZlN0V%^drHDWkhk2Ni6D=oDRe;@-YQnj9w4f>U zNrBhX8@6_`Ba7G&INyz@+pZi$=ByDSJr}HDT|{Gl0pnHrKib<#|Bwqlcnzz?YYEtW zSuIS$k_KM;UQ}B7DFX2#k*~Y|v_WPSO(aX&bL^hvc2=Yp?A}>!dM?RO7dURnkb4*!!4_X=o;kL!FF1k;Do zN}u&3a^L(GDu!T?!@Jv5q|8)*!+21Z?jRjqzL$GC)`<(*C0At5yh{e+H8Y*S+m*0N zbj+Sg`V4+Q9?JeFF@V@(3gnj7iokAZ$W6>C1I`)QlUzB9pg&rT)IFr z2{+VQ`uPp!5%sJ3$6(|Rb|owv_j!rHrOkTiRhlW&)q^ML*MWoY`0IV5@eqFY;WXo=sKCu}MTR!v&3 zt;Z+9*P7zx%;i*ANuzC8AtHc(9M57tpVtD`3t449w3Fa5{}(FbLazE(r+5Dmed~oM zo%bqLFyHCnZ!RTE*(f;hlx8j4QUqQ1bN+XDkI=UZPZAHGrGw4lbu*&5FxV+h8oyhK z<&MwRvxEf>gxWOv4+&BONq`2k$NahaOU^^(g4zFoc+#5d z)0iPF^)U=eSFWQWpUbL5Dc_J(^=rk9-a;t8X4Q!w-GySO&)yW6zKqRxRr9T=t-&&1 z$*yfj1(a&&%oG{sQPDR?q918|&`ub~e2npyNVbAsF!+t3_E@n<`o2*poiLZr$8xCI zxNrYl{^KGOAQK}UH5I@Elhd0|MU{Rd-U-CrWTgPBmgk4&uKY$*+CDGzr1`NqSY}zt z$~CC0_jHwOmWTf?TGNfuGDG9mmCwJ6FGFw7LrMe2f5Lg6Gku!>g`T@L46Zlu;NxndH1Cfr`2C#Vr?c!NnlcvOx0t}@uk?%l z_#Y%e$D&BkEaMC`FZ|Ae8y%=Gfd=$3Z*%^mo{QK#Pr}k;FW#|+d zeO%+3dJz|HFrQfv(;lu=XVM+Y%0QM;pm!U#pYx`!c*DxC0JDZd}1@Zekje@k*+@K(P01{aoV zUG!m6Den=42TU^Mwf~qPJ}0)5QZoy&3H+v!X}kb!TSDp%Zdk8WjjtA!4r6_wK7U%u za-{w$(U9zb9<0U#)oh7Kp*F^g`UQ4wS`2zJDp0hB@*YbX_|PVSU(P@C*TSAavLJ=W zQZ0n#)Q=pjmN0(!FpJ^h=?*yY>bPDOu?8-*yMxF46ItK&^L*|51TO1xDupd6V!Vm? z;0AFlkI3x`Q)!yeWG7^$5mkZg8q|VU)LdX;Cm?Zta{>KJ$g+IYBmq9`Vltxg*}!o4 z-EKY69{M4$eCLXJ z7rj4% zltJcnl6`+250Ol2g3TUW_lc{f%+Evq+3oF~yN#%_L~#R> zB;bo^ccEDML--Z3{audrFH(yMIKZ>QgU(p8Xv>R*Kp&R-8z<-$7+ff+X}N<78!gJ8 zpKlMKp^sF*G$psNIr%XOQK=%v)9Y)^$&CeDAntzUe1!5o>6)E{6hra7x>5a$G@xu8 z5ftlag3V3ph4$WZfY$}8BU`0vNE!;{VShpnbK=hCHthn?s^QA)@wN(?qgU}>`dNtm z_K?SQRRXZ69(ttr66<5oil&)hIfV^cK}AanQ^>jNYjUK^0S=$CM5|N_VDeu}qbo-T zTE6|Ij!XIrid^8bo4UdP%Wi~LZp|cM)k!5AUrYcmi0!9#S7L#|S@E`)0|6M6SpN6= zUpHF1bK%W%$&0}G)IOGHM+C0_au01T?83PCTaHs%_2|y0yA9KmJ1Dk9^Se)oG1xQa zCB|XiGve~8ANFm^K%HZGAkaq-|K;nKzO2qc{VBSefnmg$N2=1SklqL!aLSn?a!3KU z_v!A(-7QF>@t%&K@r0&l3)J||uVL4%`u)(ED!8>TJ)}m&1JMFhS!q0xKs(p9L27sw zGHh6uKlC)i{$OG9`X(cYw(eZ2pO6Nw@YsjcI|Ye?*YH-m1(2F{$#5e4zE|1or) z;as+19L@*{S=lOkl}!ovWv65d+0sBoR%9i6l$E___TD=)g+$1UWUmO3J>KV&ua4t6 zp8s>-*Y*3IXD@aBs~*^Ho|Z{}zk%8d^c=c7y@1qzc~+GjV4BI7joA(t#Jxfz`7%Y| zsdAo+N@zOZY8SU#kHEr0@MrNE85}^ z^AIUL&5XEa3!$+7OgLW)YVRcwiu7bdeKQ>&uZ1$0*KxUcy{HhiKx+_iwaW)SVctWhn-AXhMcx3Ow?4$=7wF(aIgi#?_M5<4 zA8;v~njHoj_gq1oUNE{eDg80U<~J?iRmvu|390V|Sx06#UF?lELQZ z7Mq-}`_lH%ss@|wtgAM#c}CLw2suR=4T`01mK@L`S4sX(vJ{c^H4Z*5*N45t1dGca z`Y`)6xaE4t9%?16G$%J(0N>20%N$G6AT0$q(>Z>j(tGNop3-lyd8}G+otO+zE7bSA z>3sz0KegV98x$fJ4+!R^;sy=hs@MMwG@x70*b61O%h9itHkqG9S74}pOod(g3%2(N ze)NRe5+XHg*k&=_=4n9K^H9iujUQpkANWnc?)Qg#5g{h>9ysm>PfwYg;eDSb*+j=NHr-|c4 zicz-7qOLzxAxxMzJXv@t3Bw{`UOsDDu-f0)PxK`fwh1cuOQ~y-LwDo^(GxBh>1$eV zq0ED)y&v$dNG>8fm69p_T7SR`HxRiSHVt*wElGbbHzEqAw>TlYeqh|mm7(*P1`MX7 z-JX5UgdJgPzW;t}!QTfBJRVks2r;w$H>=k%E`YqSl`I0>3fIPW%+^3@ zQ&#Euh6+xP?ZaCx-~+9GQBS-vHPB0GF*dzs1*`h*(es}s(Yj*R66?)Ys4-0#mT?+G zv5wZWv~HNEdaQN#(tB%|cGdewAE*ceR~~Ox^L4{X#pjAs4@0e@`c1S_{ZesxonE#NXY4sU-QM@nwem@wN^{&4E^Sun1 zHpA-*+LR$Zqw=n7uQad*Y|(8q3V`fT_2s(9t!RxxH>`Uz97Oh}b0a=Cp*1)6&#n2? zz)W&`zQu?hR5itgE~;bsbwgv8J1pVAQvgNIr81yws1ePTScLKCX!KqlenX?QH%Koi zk094*y{USeB*^|7>Tsd=KH!O~EX(zML^s1Y?-{U+qqrg9eC+fO9p7Y+xPJTx`79Mw zFVx9m{^&fF-UEyiTbs{_d(jz=u4N4QRNjE-e-)VrT_Mfc0o!5i=IvzIsqKpgegaJ=UTJ*T~14${;ZKaAka7?w{p=93B?67PVJ zh}BG&db-`JjDGHr+bh=(esSE-HQziNX-vPgQfz$9{8GVCWhEFRn@50ZxzV1Ce zpj~OvNlHF|r}=EO$|@A_;;ypr@2*ye+jr{Om+C@~0|FFq-=sqdp_4Y=Y95+=WF>RC zAM@~zWq0DvZX`}}AT4jc0~$2S{?-d!1pg4yg-7~)n9m@~VY4>2q}Nak#)wp)9K5Q5L#G%av|!g!wqS(p7V>5J6i* zj;7h%IJ(XuQBo4K0ruq5+4i5^LG3M#I@i)~bat1{AqktyWZ~H_d`i6n4BaaQ&Cym+ z_w&p>?II1BR%cmsZKH(vOQz?ipZfsykE_EXjdZY+-`t*fV-vl8!VnovN(LJ?OH)Qz ze`bVYD$PAp35aI|EN^1m0OhJjH0lXt@c3qQxNa;v_-adrUg{-;KW~NS<~ZeBQak*~ z0rTfo#|u$E^>+l{jDGT$*6NVIs@lm{cn_GiT0fY@egMtudx|R)Rp4^z!=)$w=Fq{R zR3OGE4X(a1f`XXW760vo7N1!PoLmvswbncfaq&?0m&q&gdx zUcD9v*jD0xJsk!YYcq-lN#mfn}fhhrjosh68Oh*$G=__tV$ufIh^)>hJnezZ~fZQ!?} z`J~m6&sfj=RmTgQ(@R(%bu+5d8|!Ut<+@R}+iAeYtk|@u%Lb~bKIS2tV1jF-cPQT8 zO2as;QHsW41L%SYi_5#}akytPFR%C13r=da)Li=$A-0l!>48f+9JCq77*^51gOut! zNej^s>?M4WuZIAhw-4GEyDfu1+0;goR1ONY`#3tlH4m4$_to~?R)K}}k2(Rx4DyuE zOEZZ!2deH7%911@P&Bhq&N=b`nM(0TA2My=nMtc1%^MqF{$)(O-sJ=z&gW}=AJD}5 zOjmTbHasD{i~X5l-4xP~YBGEtw}V>CrVF^Qwj)oy|57t0HDJqlEVq>N8`KTfdo2(D zK+GI!Kr2e@ z^uLcwh>TDrjt!R^Udd!6k95qSZwwvI9Q)@%OzX$QZF+IY>Q~G-FsBDQK8IJ|=e{E% z!Xn=Sxlm}qJ-MOl9|VuaELt62(txU0sBm>~0TE={=Y*ZtRU;U$I{FMD1g!;ZBbEW*IR=c83l>; z=g&c%?7fHmM=}=(YsHVmdtl)Kp-ig{{G@0C=8W`CyF5$ z-_WWix8f(FzqMIbl=FIp`wSQ!R&J)FN{Fp;-ADKc~%fg{?=Z4PY`AqC?*&f zN3i#+7oTGn7n+q$rifzb1LH@zGAfs4`f z+FBMjw9?qyno0dbqXru^#lG)R@UGXs@WL`;^{szrdUgRtkU!o|_F)G6-ptP{e4_AD zk!~r>MG%te2>(4kAe0eJ{!sI`Fb`ax=hD!_KH8qN{g{)uiyW@34z|1Af}P2DL*9&T z==Nb_j80B~;*6w7);uW?{&@SA9(xFQwJ*OTLVwX@?K|1$Cn?YprjS;0RvE6u<7UaTm`OS`bS1(}yH-Y`j_WAf>5c~at4OdnV!ZOE?E=epQg_FNS zLdh{eX(S~kT;~j%1N^teM=;;!9~M{QU+$noocS=8K@X0aDHJ7{>3~JJ3q{Wfz#xvr zt$B=xC|~Uzkm<$_CM!p~nXlL&{l8aq^m?U`lRbT!?=g$S^#i=_@?U{>p^@0EV+#GM zcQq3?V1W3{<%a)!c9F-){x#QyIiz4G*S0jB0|UQaM0~^UNfL#oL7Bp)Kp1Lyk18?- zN{#5_w{kgzS*aEmf*)9ETEy@!$iU#{4&xsG23%}-Z&p9? z2+m6kicZc`!m(qD*Sp_l(ACg6wazev@*6vetdl=u9u`07RiFjmFG9wf1Y_`)V+GN& zR>FZwC!w-HCwk={>{y0Bimcjv-qI)=Ku^tgyL;9I@Ln%wXNt_Nc7gJ2CqP!p!kJ^H(IvY}OwL<$S9Kgb7{;}%! zWf*Wy;0$KnMnqHdUo9dq?@+djDLG*&kU00Kw+jUWF77n**U>aM>J_CYqRN0*rQHLY zLmn_;_e;+yY6@xn=RB%rR)>s6+~|9F?t?{#pt0iDJ;amm7Bree0Z&^+R0tZ zjM&S$ox^wp;c~6+)*YWygj4ngr_k;_kQOn%GXFvX)u+o(h(sTQOqI=E{zx>se3nO( z!j1+K&N=;T3B&k{LoAd5udc%{T>00bvLlG;*ovdxDh=MZUAwEyE)P%Y%uMZZk`ZHW zOztAl7f68^DeH7qJYP(AB0Wn%nwB4M!!6+tJ_Ave< z(!UvphJGl)4*c2kKO+T`E5@cdFR(nP;up75HzFWoW_jm$`WfB25hCWxC~(d_7{|g;jc-=#+z+HnYR4_*Y!64b?sPL>Glw_& zxV>kyM}XX{p149d9iF$8QXCeVzzeo%&3=k(Bq>EjXtjNSHg$q(&U;pi=#rnC+)^?oFo_>HgC;IfKs+eab`oy+>^gC+4vKYeQP6kG2V|~=8 z_n?L#Y|N;684(0Zt9+V5;4qdx{vlEUIBpvJGi~vM!Qqpa`LzRxhn32kiTgSfjaxUH zHuyp0DT(T}d!n!*Io4pu@)%@UzMWKj6aq^;q5s^BZ9$i}FktIHVNmp`Ts})Paq}~okbIZb*EZ$NkQj8%x$AlM3LE4LKih0EKdi#PH_;oX;NNdFQ9;Y<9L z6_uPYS$2{VXpV8V`>$0CY+yNYk%0F2y(x4o+S%Q!vW?V|)(^e3M1droh4r-q9Sqsc z{>?iWhBcdpYwUFbFxTmHzhkBbb$Fj%NoW5A%4~S|q&sN9MTgIiR%IBBVr`YmKd%voj-#QA{l(;vV|eADkGl{y9N)6&7LQn7V>Qw-n~#Ee_K7Y6QI&ipyL ze-SOw@g+*0XmB<2#M!SQz&L6HVr=4#=+g3C3eCQ0_@o#*>XDO;1ie3md3vok*WI3} zmdwO@{WB{yIG#CZpXbc>j`1W)K43mm>O=-DJ<>|Pca$JU+m1r{?-r=#%Bkk0c*3^S z$}_y?a-^a<>EU?U4ICXlKVglL1Pz`j>uj%fFt=QHZlEqfZwQ^9{Ad3h3{T7Y11^Tc zs7ag0RUQFwbRo;qVCR8rvXxy7Rj$DPz_9h+n< zZ(#r8JaLt*C=7-@c@m5aV8c|u{*cuZ2EKkJ7uU1~rt?Hxhgk20F7q;p=e!zaPNoEJ;E#{t_~(9v)K{b;P}>%h0fliV0pjyV6C{e8oI3i+kZz@om51lx;rO=bgOrinF+ za+W>KauMcb6oK2hVK& zua&1A`)-P?X+=l?x9$snvCt{Z7kA0dPt5~3KK%FlDb_DeB2U8~;o3&}p822hP21sj z%%fbw=Ic;n!nu9%H6wiZS-Wz_Z~(C=HD7V5wuKn$KI#Xw>+o@B{i&wp9k@j*LYZzu z0waPIX-1=pfY_fc@>=r1ULLh+%rPg-sI)#`jxvH@--3AjC8dEYpjB>3t`~iar?pYK zwFeqCX3tV?RKa!f`d`j{eTaUOHin|*FC1OO-DF9_1H)%4D&2qjP-sz922UnFRNYs2 zaQ_D`FsQF3;f>`X9M7o&%Nwl-MS4bXnaaZ5Il~RIh);+zYm(HK#t!cOPRC!MCxPqK zoN4D?bfW$lKkXMTS?EpJfKRQSGf;oOS?Kq47A~uq`sV$;068xg;_b!PQQzmdKEZEC z$c1y@<#(@YIM6Vla_)QtpY|1XLnx>O+A}DvOhxTx6MtbkSvT(q5X~! zZD4t?z$BAFN)V^lepnPC21_ODO=mD(s<|G8MAdXNB%e}0k<>Q_rfIq_>9$XR{KP_* z5!*AKy_dkFccB|ZoTKZGE<3A5P)m%PEx}xA*f&0 zlhC^N8{_d-O{p6RWBkFZTnku!@YgVBa`f3BNFsQ6?S)z*miy&pc#iq3>~u8(g!e{K zv`~bLzVHi3@i#JW=ClU4&91#10!bM9N2aGuL=E3>)7>)Ww}6}qNB2UfzbMHuzCV%e z1bKP7N_G7b0*#8MZ(aEBps$$MTEX!*+TVQkJW=Q)hGwP=n zpXmO8=Y3=2letOcad9 zw0_f%Td^$=cH7x~g24;qjK(W{*a$FwTT0?bZBmGrz{@Zkn?v>Pw}tcgD#64O4Hl?> z!Ol^O4s2_Epk06cSLop-sKGrZPc1t_-=F?HloFgpo>!*wYwjhX;hD=+bCzeor0J^l zmc~N}{!>BN!e0Po)wn#PoAPjMEf{bkauKb?c*^e>5rPi^AJwmzd`Qt{J9M3GfWbNP z(?Y#?=;D<^tInWWS8_&%p&H>CvrVw;) z!2|uFx_g(akX2xm72cd89EWG0kKS!UsvI7Q!#LR}S%>ip)!GAy@(=zRb#V#}iWUkD zM`C}E+TD`7|3L<~aK+CcVYucazwTv53o9EG1EhuJpwrfk=j|f}ar6TZt3;`x;BWod zZHZLW_(Y(IkP#oKY9tdq$CSbGMZSB>a4FId`D0{-^|{#mL4fu<<}tpw@Wo|K2;Q5v zlU2KEgW1+~&bzo;PIO8gdD zl_9q!<-PlZSh&|%QJ-|t1d2hK>Es?QJlCJrS^C5Ylp~_=`wO^$-1|0>05%tE*!Oub zIgjP$w5rTUbQOVeky|UipcIM{iGs!ld*DCufwZPw%xA6;POOw61oCh6SgW6?gE}1^ z?R;t`DF0|o;TUp({IbzLUJfoOr_QsNS+7DEO%h)*7W@5v$S5h3lMkt5k3!Z*-@>u; zx%YC+;?V5r;GR--fF>%gofsWF1mW7rqQUk`7&V*ywireZJH8epuRAG$(;(cehRgx; zpt9NaU+zJ7$&P8KiVmRn=vvNux&XkBSydl3Dgx1GO;g%e@ZtV1%Pw_EeW+8?D9=%% z1>*bJihH@>ALGI0{ZE&7 zngaoeDOAwUgg{W_{j}p{ZqSq_2q)~r0hzI%m-An+VmV+I>#wG?z)Y++DP1T6n^%p6 zbFelbkCiyqFTkwTTUM@8;~G05=IIZRozhFW{O8izhlsJ2i4C>Y5PBe9nPmYbSU z@QC#d4Ra+B_Ph1>{qSIOt<0&i50^V^j*s?*Bx}I%=@Zo%nd@-=pzWIam$QI>%llbo zfEkvvEmJx_oB-)*OS?*Q>u56g8D0*N7bppR65FeTo+q3@ao6c!uP^#Z6C6WrC4FeN>JEk$NjZ5I&Q7i>cysKNt zXW;hJml3>>E1NGbl(>b?tPlQ<n&C7^+OtfN1Yd!tIZbQUI zOVb1f@9 ze#w3cYz|Wr7Z2Wc$Jz~9F$eut5VWIw>Jn6xIAO`TSN1aVORMJ)k;QCTf5fxZKep#wf=0`3O`2p zcK`lXalQumPp^qyxEuh3Y>R|k5(2+lPQvtlxR95u=doJR0L}h{zwB&1V6ON}{Mq_G z6n9hhTku&zxSH@*Fo1FoJ;>PDthA0oj}zJxbKbhbSCOqBzcareF}1FtN7ljM)?UoM zh;Cq<;QeBMaz|*Df{^x$31G@2*${~F?4*A0s1a35!WuratP|Ep_~awiRYr0Jb}uqZ z^o|dqJIs5Zgb)93y?ncr+6Q_SX9;noLq$o#XkpllJndw)Cf2Ig0D zt$$nDRbU4T1h_f6l~mx3dvz;Os2ZJ+Qd^>Jku?DnmlC!~OS#kiFa~~#8x37&9KZ1eo zI_@_;r$|8UOv#mApVO~#Ldo)A z*+O*5BZCx3|JkSsh>8K(*~@t818N{Qr5~ge9tj;=@~vy3JIHGyKIV^-HMFcFQ^eej z{A@fr$88lri!lAN?pYjAD$qXN*dT<4>Ha^KN^F2{oUq|Xcm_5FZ$|Z z`*{_2Ul4jZkBEu%iSqQuka=w|XMWc_`Zi~qK9d}b-j;LG%VPP?kOvI-vORRL#7@?Go8LScnw7LE)4MEUIfijHjf-%5BR6^ ziR0Sbc~BU?Qj(eb4vcYhPGlq8;b*k?XvhUxuo3z9>IT_O@NaH%5v+;?+47Qyo9)>eS!pYsXy&0xr=)8BiZ76I9I%P1YQFa@c{eC6H z6@MNqb@~>V__%;GnL3Z%Qvg(3i#j!;f1zg5s|+o|R?smop6gSU458NN9=tP~hwFW^ z5%a&MK&Zd@m)T8R@ND*pT#~E)V9tbTsqb4;`-av1>!nihX2RHB=sE(~qQOg}oamua#ki~PCX=$n^ zRN?;J^KVaebAKHBc3Zy^+&O69G*pb ztbf=5Ma3ti=M!W=nDv}fS1=!ppR;zMA*)5lo%h4ShVMh-V{hCX>^c3{ewWqQN(#Hr zo4os4;|xpNSG=9;=9+IW(|20m!*aA8mk5d`v|(m6=wL_p5S6vx@yPpy?X6y=bK7e; zgFr;6>^LC_9QQIlXR^RNp)85{L{Tr`PQACee25-+`FGS5VH343<=02wvH8*X?9{Ty z=N8mv%wdJcuz-F9^6BS2W(5i#zLY}eMO4t#_QH(}A1-ay{S&eH*L)#1P@SXJ5{A=S z3dQ~=LB>YetpF`aCzM zORBwQ&;YrsW%l*Pci|EnUOExxLpb}0^V$_w2MFDcAGojl2a?17#8wr$g9JyU6vqcW zAU}0}%HBAG?)Kp+Kdq<4d_nhxcloAKaAmvGiDx_f7c=WBsB;EnO`GzX5-UK{O6J#{ zLUl;`&n2_NfCHFIUsC*m=e#T9-yB?S4k8H zi$n!sW&DH6`$$cY7G{@RqSkW=`f7A1o~QQeq!%p246}3p@rK7Q6Y_ZHasm0A z?N0yzqzxtBh`qG_N*-!Dv`7DqD8cTE=ki>H zEHGaDW0ybW0=}l{J#LrmA?#BJ%a*ts{MhEBU#t0tVtluK1BOLm{L!K;&;$c>Md7zl zetM9ZYp%k1MgfoLcNx{v??X&#cgcIHw-A#VV7F3H$1z7ts05Z!5i0bzRr|a_`!1TVGJrnE4 zZ%tk8I-196=?MPmSDHo+Pu?8eq&%oc;%1r4^*`BwCQ9^~*g-6~nYc!Naee_^s;xRk zSia7{CVs#iJFixp`UMQS3qrDTSSW^M2Pgao)dzm$aF0tquS;hi4a*-GX=&Vo*+AP! z^~wj(``U6i?uQHXn3#MD#`y7uYl|2m5WwpBeWP!a;&6>|_|vwRG7NPD7)++L0<9L_ z)fYoTFu9%`AOGM6{6_#!>+)iu5`~xeOlttiMjQJylNdb4ZDuHzv;(L7B@br)RpeK4 zgR;#2F}Mo8XcFVZc<%Ubbi;zWKrh23Ja9q`cweG((QP&`Of3K2q9hp@EL#nK*9(Bz zo8CERUp%*tlQGpgtnmDb>F`jrCS?lh1E2v?Rsc|_M2>0I=sd%a9LzlhY+8xxzddU#^h4i%HEKmJyU=%SzMTR zOc~n$w&J49lLVf$7uB0K$YJ5u)zpsFZcr^wrqex?1l{JH?ri^6*p^7L7m7MUxFv6X zk!p3I(U&gembW&bQv8Kp&fkA1J2?GpwB-&uTP#MrZ9M~7H$6UB7c8O2t!@w73~oWh zhpkC#x?-UC;k0z^pD0`k34O9mDhPM}*jPk7okEqIGWo^$wZOZolUMa*1pV#_uZyp& zK=%I9Z(h26M^3Gyq+SE!fFC$L)^_a;;EMDr`O=qR=c2>eq-t8&2>rcrZ{`F&h^Tt# zergR)dOh}R$7i8WCn$weg%Lz@?Eig15 z_5ZN%VmBw1S<~YMv=mp{tDq+hpY%OgD&jH_+ooy9nno!Q%e-o!$!SGS$+u3RY!tna z`pQvWC<Jdc>bU14UA|DFu!m(I9JENVgJyE6yT_FW(#OYYcHeH$uuBeLksAA_0TJkfiU z1g?4s$yZfqz^mY4gL)+m#JOrd(o6n_qPhozCdvoV=NO7NjQv{>;F-7o51$7ZBqAEf z<0XO8WIs$X_a0b$sr?)sU<>aw3doepPLY&xk)k9v_hukz_T08T2Ycu1oZd?}0&%v% zl_NSHpp)O7H5AT9uI5*{h3m#q7tJrdb3~X2uEG3@PxLKV?tRBD8oH0X*7Z3k%l~3I z|GC01KXgGZ(EU^xhXT?VaX#l2Vdo^T-wDN3qsYW5y|F?09_ZHHqi4Jn4+*&QHrg*c zAzD?FLfUl~Ej4N%36C#8ifmw642?AW%h1at4}AkKR9v+t+AW}14zAqjiGi{8LStW! zaL7u{d-h;68G;_+3a{R_fuw#kyFgbBJ{uvHH?!uEjMoMwYu!A$VOR3`L-1c9eMcj3 zXe2pIU4wG3$UBMUubtoigOUyu8XgMghSN zY7_Sdm?83<^Rz-E0~ot~r(k`Q4hs$A7gugwhd5usAwCT=AZ=HqSd*cIbN}pPe11wn z%RF09%GEazX68qdr<#WfC+j+zN_=5K+t%X03@Q*XkXUl)t^-#MW6DlnHOxKy+J2HGDDm;q_+2@Oib!W=XRd4`llJVD49Qk>K(snj9cu@Byb|?M zI5Hp<)GnIS=?@my!iZRB-9hPf<$p%zRN(rs>v!g(4G>C@Zu@Vo8*u1`M1RzA!sBZd zT9r?CVWu00UHq#AWa$)Kua?>et=0$&-ZL>UWX0EO>F5ZFD^yQwjxc_s-Jd2oyaXsB zqLZP@U58g^-acx_^1}KZA74zIebG5;qgh*7Ihb*gTm zX%#Ek|D@v}wCffvQMfjcmSP!;i^mA3Q8SWRH42;<8*c}Si$W~7Q;j(N0&;pE#Gb!$ z3vv=Ogb32J(ExMe4v#SzXmhT9vGlTqzWQ|{748yrCgWgWp=}jC*1Rq>qd4CDFiN`l zrUgH&KE#=z6`_VXe$D%vw$H)!t-zT2p#*fd%Q6k0(!=hnoWxrGa^!5l+j}os3pNWZ zPwu`LhIGGE{9h7Ds6BdAZiZbLk{d81L{cZj-0+Pc5A6Yw`JjM1>T1vooaO6h@)2&r zQo=!(Gg#^Nunv&cqXhTujJnl*bR{aslj5!$e57rjhLCgM*k1hHKLg{FNq!>kJg!2G z*4U$5#r!)qS7w(neuw>TW1-0QFzQzSr#73)3NHnd&y8X}vWH5n?}Q|EU{N%VwF;YO zpSl=`{P@&>{5BrqH(c_AGGl)CThv&-Tl$H5bvY@_t@_N>DA7QU!&s__R5M(h{Sg0r zst5J>C1LKLN8r-nSRD|w*!*rxsfv}M6tNj+s5E~H2b{GA<2fm84l|sW-ym)Yu1wC! z{DfU7h5pZ{PS*%v*3~8Wu{nl%-jKiK%BzQhq3g90sc*sUgv8M(YZ`qC#AUs7vjSbY zKUSAxaSVF_EaIW(`5};E5(S>yL{F<_g~P`pAc?KSytZr#Ms9VgwC_I!wi~z4%}gl6 zNm_lApZPp$q?!-?ph^KsCB=glb%OAIIea&bR1KE4R(8(J&Y=adDDv^#4vdffzUVgF zUx-#%W?PzKfXa)8&z~M(zG`jW)U~BPltxx=6M0Sn5`C@KUO8`pqM>t$`c)ygX)NNP zQ4j!K{djmkKJdYnz`2F;T}dboxJ9j5N(`zincQI(Y4A&BdH%*B9xR_th-*HFDT z82vqW8{;=il9gD=fL|Lr%(vx(3Tcf4@(^NpExPu#jd~q<-!o$kdCUzjYr9@%kw}BL z3{$LeHz&w(r}wI)WAm#ovOLQ#G(a;fgFf?4D`Kkr^)4;ud-Fm5%df9V`N6m>%2)pi zFt@b6QO)g{?jRFL56 zPrNsajuoDHTw1MbUSwOAkCRh@K1qgM_*#zn27rvpsR9&fJ8@Kb#K1RxXs~W}5RL!$ zG$y)o92z+;h+8>C!Ue0mB(iyS;JrE6(S1J#{#qt73${B$`Cjn&wd+Hu$E9<@+@lop z-xj)FHopidOpRB{loyd3jpy91>H*Rne>V9-`yqIyu3EJ#37W z;^$YfLO{TP)eBZT5SOS%Z#V~$7A2`?fS4g{mo2Rfy(qp@3+h?qNUbnd6Z0h;P6eFm(Wfe)Kb_}c>8vsz)@k{ z>RlAv`9fdkADRPdMo{dunU2<7?d6WoHlf?~wvxS*s^F$k$o)Iq9P;DN+2nstK|YUP z%Dpz!0BSCwm7L$$@8BP!h52Oykd`dF7*lTyxY-;Br3~1-Gj~;WXQK-lJ5Gxiq-`Rj z>}35ec0U-2@opu*^b?_$<%=GQCh#T~XW=21=OXqTAtcvZfJs50xacNH7`*J#pxh<| z4xQ&~;+gnCAb5G#yWk1n(y4Bz@_PU$KA%)c6Lv2CDkYJGanT4uc(W?7UW)ec`=1B2 zv=GVjXpr(-4SMvu_2+dZESJ>c%1_7Z29j6)a75J&O zY$Ub7$}nQ92{T%1Nr$^Pa8zR>p8`v$U{U0kJ~+*ry-9i)05;`zr3Tb?pnanHTDj*C zr9JQ@ONqCGEIrk^tSK${p3SlLqO%dD3QaXA1*=2R@s1nbyfk@4%MYnMvOhL>f5rF& zbuFpmpOM{hQu))P5iBns#Tp<*0D&E2DaOM0p)RFWb@zlDBG%UAu0GX(>+WJ5XE83R zvmKQm>oX0=Z(Q5*P>h4MQk!5yk1bTQu&Zb!5=d_4M34wS_%=xK0tLdoLBjCeJ-n z+CM?9YU{6$jz^%JmW{dm>lgHgXGY_sf(9z+um61Ne1L?vRLNKQ^3a{mSd$8`Pl(9m z3XX~QH`F?kGMhn74{@?4_M1(Z2UcopX+c#8E^p3m-Tk|ST22N+C8rONcGR7H(zr6j zdqh$lspAF9B`sEqyT74h!g5Fq+o#xQ?%>+5_Q7ZAx2qc%FFCA7G??Ul7~p#+{nA$B z0CVG0k#KDmX!ChoUl8vD7uV|og$QCmMP}DzK~w^Sx!oV{ieUY@QQ_%076f0FNJ}U3 zj?wtV+xF+9g`u0NMCcWklO>H88EMhAhvA8n2yXiuu>P{JBh2HR4EH_jg!X34`?*r3 z)HHY(OvfHk``Ld-p_UV$4o;`gJbv7hp$mJU+xXg#JV+J}3Ce~Edb@!U&*8pti7@nb z)WOBw5yac(PPWU&Zrcj(9cZ@NR9yj5^rTpZBN-nlbF8wFk|1%vVr-eH{C!g}Es zhVa8KIHQc!4RATPGx;xH0Qnzp72B9xpxL8B#4i!^eS%DsT|_a&ru&<+P0b?d`?)8Q z*nOSemZX2++I@ga3gRozzayN>ZVvn_PQY7|FZhDf0n8%!uk9OTz)Fwd!jyJ8+_>{L z=-NklDD0y$6_OiAf{q*8@#+uZbJwhdi?bB)=LXqa@caf`nZn#gyYdh}$Z{@nZs zLkn;m%2zCI;6r2N;=%+0KtqGCAU39f3C(whCFN{j7B<*y*I@~!F^2Yo2iW(EP3CM^ zLOmK~nftQQoB}e08tyVh>OdsPTJ^MK71cXyw-7ilqh_b=2&0=HQ62}G=|LUl>6F;) z6FgA@w%IWe)p&B4xfOVS_mLO8sRgOU{@;3w)KFGqy$jg5y z1u^~@neG`pJ_=a0-ZAOlyau*gmHlfw#gJ#msHa@T0?n7Z$c&F~0n5*eck;aD;FZ;S zH6>08IzvPgwZ^`IqPW}RiD+}7M>g{#m)l1a8)g3Iz*iDP{u)#nknY29oA90-Bi6gx z=M2ZW@(l6^3D_9f?cu(BHhy{4I@&+`%*p=rD!4XAUekEi4n8sM$C=jY{k> zB=Ee>B>&Wj3I%3Ef=96&WUp0rf1C}hW%ws9m0~^|=bE#L?*Gt8uR|jb8~vs`oDd-po@Glhj?^nY(HPXy!~MUh zd+GiEK!!-FgXSa$iaVA?bO`;xz4c*J+2KFLD9cYLEn){WSwBPbUu2+L)AY?jPPV{O z6}lbEHUth+LWj)W5ny=Hr$qCrD4c)wuUX`?ALv{CGqO}nMocQ!@2LF}0Iz(7U#kt{ z&-g5ef3Mm=EJ;2d>B0d}8#iap{Kpq!^rMO2I@4ge&2E**S_9a&h^^A;{)lp4=sKLc z`VMaXw`zHmVg%D;^1qj+#UNwr$^+9l1+eSill?TR3}3maUT6PVMjosQ(Fs`puXLey z8_$>p(nJ!aNXNV2jvqr<00ZWSyx`aw%0>mF{1L0=Q~waVb=%3KJwh-J8@#SO)c|E; zXB#B!alpFQEts7{73g^eKUlG1wEj;Hq6u3pd?gZGP74MznQ@88VFyfCt>0D)OWVcwyTs*?u&n17A5HReEnXsy~VmVo)%KWyPR$pDFg?P%z?S3niP|GT91 z6kQ^$O1&4W0j12_J6Rr|5sTx5?<2=x5J`Mu9+Pt&+BN^kzluHs4}{*yD}+7-Sz)Jn z4$4{RyKu1ae1jN>TsD_l82P}JWoY5RcpT+v@pqqYaD!h)X|p9wIAlvpuSZc|hb8TR z#TM={^qAU5%{@FHeL8>T!|RrG#86r-qe1-vs7lA3o$dcazw{O#-*x;A55CI?N`6ZL zM+2unxi7=9eeno^!sZ!B)lR*#)|rUfZp@iS_pYMv#DUW+)+{hXCVkUjk{2R0dBCj|YrxU1lB2TY$U`m1^UL2h-fWM zw@8WX9ifnjieyCDepW_yvUg_op4mIAY`ypW6Vi3vbI#}UJm7@GJY2}Ph}tWgw$&-S z5wBJF!}y1SV6RAWwe{;NwhwE4y32|6IY;UwC#gwc*&vZqGjI~^l2WT|X-YuIHz~2Y zd{1cqVm!-g%nDIve06~qwm@%wLhk)U6uO~VJ{SA$>6&2FQfr?>4#WB%MtIjiy-&Gc zFuWHDj!9aYOS!|e|I-Sgzp9|_tv3<)mj$@#n%76oSiznz>z4T{IlN3xRppOthsShJ z?}qEW0#E#!gR19LQ0|i{=#xzeFL%~{?Ts~|ivlp3^{ELgelEGx&?h5$-_5-qtvQtA zTg{vUWZ~-4Q|Fm1Lw~ zo#e8)6Hf{J-a7Nh))|`JKWxaKX@P;A?nZg7H{hHnVBMflhZq^#rt7!W;QpD%m+l!l z13k;+V;BBC)aDa0celR)CU^XW!*q_2x#dlZ>aXWv9Vay5{AETsN*N-NFS!kw~@mQ{};X6yIwWQ%nL0%eoTE*-EhMDN(<{=L1vsAQS=@OWDw|9 zT&r6_f08=5?{Q;3)OKl&?@8n6V!wvqK+rkhc^AT0(cuSKE591gZSBMQ!=y~!4wnPK&z#BGH&2jAN~e^J&=4}fGnYQwKZj`fp629X z{4^Zbt8GcN;ZWZmQhtV^4wdy?Z>ZAQK{wo9DNc0c0U=+U!)X;B_WY)2JLm_&o@wdE zm!3KFnp0fMY^wz}?u2-(hv&Xju@R)GX2uz#kRg_=$dg zQz-uCgAa8~v-kP8RsiSO`KjBcELg9}u1iT4K#|XK}kmQSbTdDxEuE_#I|{W zFBP8K(-Kt}*6pqMZ=f8pCXRo(dodi;$Xc(t&?~^FLpKVKsYNtdLad?oatyHv+exK- zzX%7X_JfyIu7fbK7tbEkE@}#<*!gIG594nydzQ1*B4>(-pYtC7&eYCH+UYE>KJ zY%-zw;`jip<>nnMU-CmzIk$4+Ar6>0Z?`I|9Uz>=PT@zA%V8bH$a+h{2TX)C?rnz$wWmF*IY8`mSQ)WMM6HTg$8jxAgr1D@XZ%TVDK&3 zAWtfSE7KGX_MX^%!$r%X1xRFY@s;yQ=k}mfzfY~2jT9<~xPBEqxsLIijE3~aBcY^_ zkmJb=9#pU8w6X^9z-r6$x{tQF@NWF^j=4xGq9{m-{S?|*?JaSiRFXj!rrAz7WPY+j zqox+xmSl%$bQF0latH`050^ii&mm*cJz62&TqHo_EXnPh0i@Lof^F-4D8Dw}yuz3X z7E4*X0&iY*pk9{ zp8?+OU9ys;-$NQ7$xZ@e2hqFDxe2u=ZonFO>EgStFd(?pg*Txs4;6gRIe@A+Sx!78G471fa@jJ)2@q)Z|J#dE{>x%r9vR-`2^o6{M$SA z(qTCNlOQv{F^s(PY>8DQhWDSVQVqU~Kw{8EN4k5*sHf`RClL`A2#*X;U9J>>qk|Dn zzORGG^UHgMn`J%lV5_8QrpN}YRzm|mkAxvM;u5j7FI`B%(e0`Erv{9V%$>;Lyp3Mc z3$Dt$(82Pnr5W2ZB;a=K_D{nNCqVSey)Apx7$@2CT0ZwWR9MaB-ymRtd)Ya)IOJ|% zXRlXjIsFqTKR+dyE>r_Pi?w+s?Qf7^@kM{eGY)m-{NAsA=>aQOhx(KF5|DSgl~fls zJIl1Y zr4mr^O5I~sC<%SRZE=))WeLkB&tr#~zM@XHo%b789f0)A(i^3R#PD5!wdlbrKBT4D zo5?w*!d`k6pGxW>yhw<6)$kh+=#~zGT`UgKLdmy7=0+Awhi31vjP258raa~0i+&M{#FYg8V@h!mwp;YPBW`TS${BI zj$pd5-46v|+<(t1yaoT=C=_LdKg!;kYYzs{4_6y% z3fW39dl=&RXrmQ9602pVEcSqyM}hNKMg&25q)s*-<9X#@zA^T7%ME2>)sFN-x|)7KFT_>F0T{ z?|J*+La9K|mxFUnNN} zkLoSz9ylFi-usXpBsAKIF2n=Mq7?$We_{C(x_9C1Z6>$pH)g^2#u!mKOA^u>dxCTQ zdKxGwk_Uz)93h%(eS5qUT=0W|K~dz$9Q3|xOS`l5pmT&AW*e{AU}n~lRT#Usy|BjB z$>RC|M;co7mQnM7Z$BW3_iYqS=f~pozL`c@iZyvWlq-PewoLgZpcss6y!=wj+~97& zf4P=X*Wq~cWoAW43}RnWW8E|!MHjO!YE>pop`s$@zWOQ^sMQpgN|=@dGg5QeU3TQ&8RV6&YJ`N4OKz*{3qZY(cG0*`x1J4E2{Vj`%&NU(NpfUDF}Z_r4i|w z2=7~BnEyQ+L^tt*6L)T!!09Q8VHIB;>>Uf5X~(j`;A>xYMag~G{DT`3=a2}u@7xiZ zwrqxGp@Xuum0>8|EKb#&Qif6YIlP*jPiWbBc}>f#6mFV}S=cNxLyb09fOPRQ7)~vb zwylo@HIhS@fWE7suHwNpHGdYOwxu5`+9pC%?%+d9{XuA>s4zc1as+;1WiVOM1GnBk zAA33xVJy!P7zsOtg0)D9^z z$ftauc%_dE>Xr8q{V_q!?H_vCVOU=}*;KF&_k0rMzb0q=zmM|)Q^AjP8an8DQ9*Oc z90dDp5*-|;f6%*|ctY4838bUDon!O;CFrb}#Qno^t-(px-&g3_0O4)%G=$Cn)+y>G zYr4Y_M_S=EeqkOQPTqM1Pm;snGF2w$)%#eV&FfxDog=t4EUkRFP=xe0oDCx#vyiM{ z^-zjs02tFcHtJSIfl^7+l^RwCP&6J0p44fA{3oAw38;Q*hKe#R2`iSuRfazA%`N=Xa@C7M^ki@KoW@L7|sMpDjCfA7VAT`M8b=-spO) z;b1+GOGM!wckkQ+t#Cq83af79>S-Y>?zDxvw|-{jNOd8Gi`(=g6J?;W9`$szmH<3E z%5q&rLt)aEx7HwQ2l73eS(hmzV59Fp`S+{pF!`=wQS6K?T#jb)e`Jc~z9LDKiVS_h zTOiK;J<}SBdB5*|6XTWYOs5#QW4x9Wj%T;$p&q3FoV|PT2OXr-5#Qs1d9>*~w!t&_ z0qDY>C@g{MPm(D|V@oW~&PuN@TjxDJdu6#XcU))0G;k`B>XdAP9{6iFXC zj&>*L&-DcHfGyqGq+1T3P`$v6Z?cXJ#xEeyc!=@4yN}+bzrg$wRng_w@}IxN`W4cQ z!+_;aEhG}Oa{JNKh#qhI&06^O!49vjb_UHw-h4*=j1|TiA{M>+ML>e{bF5{V15ES9 zF^yWQz|qa#Lu;9N#AaSo7d0siBsqEQzc|C-igc!FgB>#zrOH?D{F#I)qIOkBSz%b= z()2Q1GKPYUhtX$(=%7Y7!!%Cr5&UDQb8iWtgxJ@SP0Uz6$mpJo^`AG{aOvXBzyJa@ zFu{+Vk(S;^qa2IAD%1k7e2G2j1#S+s>q48J-Bl3(wsE#Rq8AeM@Pb=>vtUUyq_j*! z3=YD+svEh~f~xGqz!B*>%w-WyJm%npL;2!&yBi$vtK)k%RAYV8AX%|FCU>Z~F@pEj zju&V;2`DPm?}9T?>F~Q~Ey!=q;nheq2ZPY^65;uOC=6HExNjl|bi-DPUxhcqaVc)- zo^(F2e(0gNRgecM{y7#Mn1?x{4Sf>dHujfU{&7iUjXq;oXKkHM7czUh` zD!z_|M;*c69C-=B)FFeNHDU-6R^?orx~m13TkeZIF8qO1$mHcDB@Pj{Za6ecFhf?r ze|KuGMuV}%!hJoXUG$Fm_pA&9HYX1@K2XAXFe7bELI;z75mEfzn3Y6IU}2m6!`+JY zAh~zA?G)?L+u({Po3t(Hp^%m&9pgD5-B#)!rDuVu53jzy)qe;tj4mVur-=h;!<)kU zGlL-b!&Yz<#GqB5ptdwF4ka7RQ``TkLxU!?8bo0nfJ$Rx8LIAL^M2-d%vCwyknWl3 zA^3~*V>-JgP%ZQr7ZysEet?5BWLKCI{~~V@N7=%Zc+~j<$LpIM2V}n}`uT8k2F}~F z4v|D-9AElm;kPqXFsrSwh9_eQBrLsrO96xEm)EBe*_0w|FTePj@i+^q``WPl8~HK z1A^!KPXE<&gAui#|2uDeXjj@A#ZgH?^a}zHa+R_9O-WUZx7h;ZlOh}1gT6paLm$(V zmnHDuQkxfVbpukQiDVwz!E(3CC4EX25O{r12DWjWrPXvfL4vJO39^ zWEv`G+*n0v3=HP{9>OprB>mf!jSqeXYJ>_CeMi>E3TrevbLc_VxStVPLbAW?w5k?u zVQ>5ACZjwDm}t|g(@Vy|ryDQ2b~V+po^fAuUlPXIxmM3n>{)`&{^nJu)q4YkCYMR^ zte61T%kW&GPByejnnLmI3IT+h>pIAwMIz?Ii>8<_zw?VCT-7ao{0@AB_b&63l^1t=8ZjqZ16hp+QeYU%? zzP>Ig^NVS8J^gI|159Su?%SjAJr56pziUw^)4M?zN8cNJu|>$$QLrD&qJ}_6iSHH| zkAymT(y}9A794{ujzx0UQP$4H^X%kEAh!7P1lP+PxJvkIni=0?{~r7@-d0nnxi8>~ z-%^B#?PJ<&4hSI$Pr+>xw+l%Uh!)gJk_R5qom31pXp7A&hX!S9mS zt!H@$z_wthbM4G5A`;gm*DI+&fAP7H&-F);k==Y*jQRv(OCNm}q2`0#tlmG2Z)Z^X z5g|OJJ3wL#M;Z$ETtLmhq-rQn9a@S=?pDWLmO01whR|&Y542r%+Cu-e!FlQzk=eiK z;SSLeu9|`&L`T^A@7&RYbv&HMSsE9?x$KKOgU}y@!_a@wGe8Pw7LLov%wyqmii+!5 zI}-S?aV;=kKLDIdwXbLSWuQ~@Xl^;>7BsTQ-cz#?3?#>fi?q{2i1{ZMbIM%-SX1w~5S)5 zeov-u=6yp7|9Tr@{R+^BA|K1^d;i~~M7iqs7ePh2K5w*q0KDp{5le_pLiJl#d?s6- z)qAPG$ttvpL5q*n<_xb8_|eqe$>flM5x;)dHdZg#F+Tb(bSMUI2TX;xi5>&9i+TVpw1AtsnfAxu+i*N(wh$zi3m(Nd+xN zO%-A7ThRB*d+inB7CM`A`K$)M6UMb$m|gHm0wq8BVCQQ;(PTiM#Mn1Acx50qo>L$W zk6v9UvI?q37;36wDr*xB#o#>McsYPbuEM5mCVl zImeUvJ{*WIIhfk*KMU{jGf@+BF0?Fe{%4q60ta=X(RjzMaEH%{FyPNKaD37?G5ePv zy1ezD&-e|Y$a-U*j`_!MUQG>7a7K}~w<$A;D+`#j*x8t4oYYh*m&=ktLXf6$EOGmG zB=nm^;(Oov0Cj3i`+s#};B#St5F3=Su#;1%?R={jb}TVQ>Bn}LnVd2KGZc7|lgit-jLk=ab1KaUH% zF_{v!vSe5<=Am(f-43`1@>@u0lR>l|M|Ke&<}EOMnkL-C02b}99)6DE1~YF($@J_k zuyoDQ+~5}kokOaq&@UqJLslI?7*t*bcBTER$xcl(k z7S^k_WVhyxaE9^cigK&RkKwv)Z?FHXGN7pgNxlnzfz}2sM)%jCPa#y@ZLT)pbyZtq z`qFFA94NK*oLxr#s*Bbx6cH$5p*lYmyGQCc&-&BljH87!W-qR6eFTCF6TAZRYp6)U zL@=ZLGKgk0rvxhS!`)fiPznY*cx1#C_q0hI0vGt*E>?2`k6F&*Ew@VWJnyq)h4q94 zbT@=;LR~@PK)PC?tOzc6SSBZuKZn!23Kpv`$&gPdLKy6ZdDC}37Hm3f!t=1~hS;sU zV4r+mZa60a6n6VuMpN5Co^e3zt>_>c4etpiYN3LnSZ=A5s48F~JFi@?$qBwYJ&`d6 zlyK9Z&4;m99`mKB6A-hHgNS~trwt<+Mz?S3i6|h32*wfIbE#j^i)qvEQdgs3YAyIk zKxYx%TUDF4PG^JpN80_@o=|~fiD-1{mkJoZsX(>SPX?RqCEfd2FS2ULzr$Mb6cdF;eP-MRtk=DM;!199!wT=BCW4FRj?r$l4{g(xNO&b5DA-DSh}7e47{r!o z;X&xVMdF7I*j|F1V?GphSntj@I zZK+}T0Xc4K!ye$Skq?O%V7{E0_f(WwSU-?($^|}4Tqpvy!Mw;D*qx42 z=wnrg0p|OjzIuayMFV*9)Puh}P6K)Q%c_PgGB_{NZ8hC-5lW3_UOb^MMK3m_&A(w+ z`Q+V>G%swfxqaPx_YWgGkhyKuWuC@Df%f_{TiWgFshIq)p%VXrj>BB^l!OIHFw@u^ z;9_%g&krZ<3|a^tjQn?h99-YO)9mrHhD_<`Aere%_^mKv zKlPywu?>vY@nAj#)1AQ@Y&1cSuf^8xxuVFX}En6^Fd{@CtoT>r?ExbYXMP+-%;dQW_vCC zY>7_R8qSCG$Sv~4JTrKo*pSNNzl=JmI5fieN}wfk{C0;61DJl=^D@T#gh>lJB6TWQ z&o_B9MEBbi3cerU&G1?Zy7nc4&oc3V`fBrQT-k1P`-o{Me+A2{tl{OY4N5_blkK15 z7YXQjC~c4CEY`F7X!xZl3iBEYix@^PnuEE`*#OmB3K*}5T}l~ye@<%E4b26uq2B55 zPjLwkz)Vxw-!v`(g)bdMDPi|oGU8(!Klgp;ejKq;G9(LJI;)=P_wPePMz+Z8>{Tf4 zOZ#kc53V!AVie?bOqqw4g6rJZ- zUMo9%r#&3(Ux`rV`C#||$~um#>G_a#)up1!GZ}0)5_mU>#K6wC=T7RWEYz#y?) z!6kzF_B?7u*u}lHT6m=t^^9fx;D7rI)x2cQ|6z;^#jDD-W{1=;QtgO;WrzmcmCa20 ziU7u_?usf0^+3?nn9ObLyVjt>gfZ{i4%*hR9~}+61T)zk16l`6K&yN@NV&KMUj=Lw z-(41k>mI?1KPl;9N;$_wSepjwnhfN}T$j+pPPG;xHaeK3o+RD{Ya% zI}72JU6D}^24L`f@aCIa4nWHudGChIG?dpGcV}^Ez<#un5l_Gw5cXV zjytyCw4$7EaZ3Z^!G7@&{JxARw1O1L79Bxn%ru_k`!*W2JXMJ6ugCIksqtqn3&Zzm z|3SKtY{cZgMxe_%h9Vz*{Psf;2c|FnH=&!(4RMJ%gVVgu(CRa)&{-`8x&(JdUQxFq z?!dS&=M}!8)XYE`QG;A4PiCAX@WbX#{aYTg9kyUm%)hIpPz*u1@#9o8d60g=xl$ef z2iCur{Lgq{AL+l^!141sMne33k4~LcK~VDrZXo^)oE3}Yn=v{MX*gV*iTBn}otiTTjzA_o!8hK5^)H9p3jdL`MSY6mJC%Fk*fIe;i4vZw!wJzUFH zJK$}=2NSy9i(_+CpkGEV(QYCGk{8}b-E4mX+>&>rsfis~+9Fekc~&ehVB*FH4DUY(Ui!3#;gJ zj6+OX<@|yw63YJRi=(IR5b@~FCZVGx2yukm4Xlv@4tIrr(S-6qAM`TiLk=GpcdC}- z_m862HWzwYiG+dY(pQEXX1ZYZ=B-0HeIKx~KJ&fVssy?kAd-vq0fL8d1b9{6L)i1E z=IsZ5Ks$M1i8h>6CWiI3EdIzN@Hq46UUT^d;#>)~O;{`h{~;YM3ZL(g+d%mK3YHUA zDhu?uBY7DXGj^QT{V-1n>9YwL{zhOooz_*l90=?b7OVxgK(U?@(2ED2y0*NY{dFCH7Az*fnPnr=m)j=i|7&*(m_OIJ7Xj`01&iC=onlW+T@fxdmK?H6q3T_JQge3wd*16u5D!(>Adzql%_` zgXL4Fh*^F>Ir~{9YBjGC<7>h0TV&QwgtFVP!C#cmJckE{hmY8P37bM0ziHHq1zdQX zy4De@l8Yh!4L7-(IuQYP%tN`~hT!acAw`gr2f9Dcf1_BV1{ZM=^`Cq{V40HDj=E_J z)!Zc~UP-A3<9e&5gS}l~m7o)`%3nmw4611FKV7)BXzcP&P!>kK57X}-8bBRcM$K&l z9kBJfRd!2vALaP#lz0^1fS!y;IHuO8Xg>2811DsHamwA|n9s`~s6m%ci6?|nM71ZL zX^3OJf_ZACYcF9piJ~j{lnJ6=q&LS67{aOWpzX6ZWw@Zj6FN%V12ecePY0ujA%?j( zf8?SmeEV~qkovzXaN;lVu7m3keGQ__=~#aZRNVnO6UL-4z~J!dB~k{;Z`{+7A0;7$ z#LOz&h79wcov=UQ*g(JUJ4Ul@WWhf9NPk?XCM;0j9~m>C1Cy$;sLSjMkYKB2bSz2% zH7Xo>5)O?J#gnvn%XJ3cDSdqrIg|-Op~oykK4U<5GdF*8jvE*_>8SR%m0C@2qNy`Ja!>2ULCtYCyzMXuSboRoCh1#Z5ASxd`Gy7@2I|s8lFlPtjV#rd zm9yw~=r4f2cy9)hiy`TL?L^D13G!16z_L zwZL=T$Va;0#;$e_ZQ2k1HZS}OI9)1A$(ZjDl0*NfZIXaqbz^Pg^g61)7ezoDA_=#g zyncmrk%LYKscz=&*=nD{JxO_9daz7?LMe6$4>PfRH}LO%2PqL$vqjOHNce)`kKt|~ z*d7m+Oa9ys|9(}*@Lk)2zj5hh70x|~xtskanXU>bY_hj1uatpd*Svq^62=938*^$A zZ4NEdS;gV^jlk{ahr0^*OVGLLKOJAN_e!-~$~1B7f9USXe?eBIQt&zdeZjjJtfwHX zbZ`gjD^0R{UX}g2h-Pj0ODP%WP_xgt-z8j(J9+8G2lq`*FzQX4^28&=@{FAK1>^F8 zY?q8}W$ro*?u-b!-{AmU2^$k1BNmVzvZGC-<%Y<%hzTh@e7Jq3|3Gpy1@803oD~=s z0-As=aYtQT$N}U6mh4 z-t>w9OdTW=s*QzB|3$0Ux8J~d%Z&IRZLgt~Mkn-0eUH7%nuUR!E?1L0jLVQue-0F z2jg%K8u5c>w5y}0Z{EiVsrr3pQN;({TJ#fZ-_=Kl*Z)OTPg+o%#To z$%F2NRZNO;`)*nrvK;Jh6B5?J?`++Oh%j_?n-b$>d?|Z-!{Q7$&AG)pWBhB?AKe)@jI)6tDqPo+=ocyq zlPbCsJb;?CjO(OXSRt&rnRe=^p?a-RNSD%~9m>)@T5#O7vHjLFkuxQj=RU|TF)!H@ z)|iN>DH(7etc5OO^w9PpQPZdGt9f?DR=_a)6+z+>TlpenSE+*#iD z&@suvk2lX3{v`51Urf);BSuT8(a$9?8~%qv6Dj->IV)gMOL3s9QW-+F^c-a0h(feG z4bRH?EqGn``j}vP1w1!LqE{cq0wKGS@vq03;C#6N*W>L4Pz?xrd9Qj9eR~$dADgWL zIJyr{KUX-zJ0q!(db~%F=&OCBWIP|~-^wFS^LK&HBME!G%?T9D}len=20#Vf)~UNzl;)cpckiOk>oH6joClO75va%fQS;{?IH+ zcsUqsOVfyuIPTZI+m|q}g=;8Mk402lyZDM88|a30eqpJ#DDyYD@&UIX??oA(bk_Zw&_aZc4`kRJR9s37uJyKO{Df>NEvjv^K1VM znLzK-U@5GbLqy*70h9a+7_`j5bHaLdOnUmi$g;Vi_YG~I(a;YFSdmAP@4QBSo7DZ0tKQc{%zY2!-c-&Xy=yQb7GWXI7MV3oJMjk+Wj^p^&JQDJacxJ% zcDKUbC&YI2DpF6sBc=y`O|Evdpc@_}HGDSD!Inxp;y2c(WhxOfp!79>+wY&ub?qmh zPL`if@5Bdzh{WZC`usvAYC8JFV>|i2uoTR0vmR7XEd#|)PMy?k252q{doCHhh<5o} zu_xj@#I?MAdOV*FrR>r|fX%a}#Ka4Z-T7e9YNbi}aRq&plc3PnB?RU(T=lcLSpY4+ z-nl1{LQLM)^EVPwaOjr26!Q@usw155F#Ns_tMl$|^`T8@=(2)DO*Uh>MUbTnj;=+^Q4|E#hTlP|VEbtDtRd)}6=;$p zH39Q%oxr+sVmOT2j=Dg#g;w2#Tl%i#ASa^w;>sl)7%k!DAbMDfS~zW;-LYQzH1eI> zWFv>Al}a-v9w`{Cvo`F&y$&IRPHQ-PqCMpucB9!$L`%A`(KkhQs`=#ykKP$#F+?DYQ+q93X|Zus~B z>vJw297G~BG3M<+8ruc(V;QQcMWk>ztE!$rQjL~AB+$)DZz35nHBV(pU$9RQ_3&fU z0CT?;#)bFlU|m63V>z(}POWa7iWcp!Inr?2ghx>F zg?m9pDFG#Ys&>+Am_y{e*<$%jWnkmdD!^dAht8Uo8@!F~L_MRy&yDP8!QrUCHe5{* zcHOI0pL&B8t?|IL#{pu+Uk^Ip z^d6?JeBfZhxbuUw#dpneC(wxay+(@xdI;>+xhvC*{eO%kla!-Vl)NvN9=@vr`5E)< zr!knHr{w{Cb2t?c_V5Pwzs-SrFAfCzZWN*Jo4+~7y5~@sqQA#yl5voi2tOH~HG&sa zIE25r|03~&1N$lLu7t$W9ul0R1YE0{vTep;6oHq2T7}OD#FsU9V^Yt--Y190yd|SB zI&kshnTrKbymUy*^@#wUi$rQiP1K^BM}C0{vzUL2<|VfS)=xH!_~7A{UkjPJw89!+ zFh1L!+SBlS0G~_yL`xyka5`FC>D^F{CYXKIIUa7J^MnZodD92zyI5Q4B{CWi{r=yt zF6kn~S$J3YQ6V2Zp4G+sD0d8X70-gP*%qRDvt;ft5o5XKo1;<%E?~fQjpRO;4>;0= z8}TUjA}L+IKzxi>VHbQP9_U8}mEXoRXD=j!_8ZOhy|_HM+H>o$>3S99RtX8TF&0Dh z^{X^OQ~Ah>x45vfoepm5x3S(Pp@MCT`nUJbast~a>0PtHQnbs=)RCsC3PM&DatDvK z;GpbVbSP= zvk&lHo!it}PYv`_8}xRLR-t;ctN5-s7kpn$&^Gtyfxi~1e8-*}sAMeU$$3(3DC{QV z5oOv0_p4!Vey!<%U+KDda+QGszE3E+i^q5?=dH%(QCi(@(G zJ|1661z7VW+vm^BKx*|`yX{Fs=iZ?y_iD{sSOolJ~8+w_Fp^f?xNh{ohLX&-0>xYXB?8QxqF#4}J+4URf2z47i2^v$I$090bAkPBJgMPT_Di}C6ER>rr6uO1-iOpM{V6_ zAXGYd+C|-lmgfvoMsMbUTR+i5p1=fDWi02AI5~**i{Oj0q7?W}Fx~VV&H`o0jf2I% zpTV)edvwLf0lqzxl0AL7j5e7~`Lqq3fDCHNLnXN2&gN&Q4jT!K+fmn1y)RA4?7{tPLuuStGH7Ge2cw+ct*UeG99J%jVf0Gz~Z zu5;nkquz0T(y1kF;PZ7}8OQDq4eK*+5|t%DLA$p+@~b^uJB zYC$&mN1~_QAdG|+tn5>g)=UvpGgfpwfMfFILZJtg*wd$Xpkjm%T(72?2j1DieU023 zuB&gL;qlmsc&8}boBZi{+H3+JMf-?E=F`!5CRXdcN(d)^&zj79F@vB-8NCa8op6Ts z#?*xx9U!Z8;fj?RMwYI*+PD5)0=%7#<)Tv^$PcV|D?{fAQB%hGluC`rpvqfoJFEmT z4)Ref1v7x^VJsa^Ia`e$sdej&-~`yrt^DitI}dInrmnAUX2GEZe$7bbdD!O|!K2J% zg9!-&N$E$|fHp5SErWUk-MmTg%Wc*Zw$u@|J-P+n83}yS&+5@W7Krc`z zmni=z>iF$Io-6=r#!)Ycizmo?Zc><{`x4YmirrD^ zy8xj&wPd1X1&GsXie65L3Ah6m@U^~b!|Y>UC1bB%Kw4KCI*4C`V`!15>ERi;m7=jC z8-Oe0_g++X^1>0)8Bm+Y<@gGN^yk4RmIt!tIAtW5STMML`jsTf9b|A#%`|>b3oaE1 ze#{lef!NP(y)hV%)V|xbD)EFAu7|oC;%TqK2}kW}(=aKN(trA~Zb=MDda_-WYuA93 zEG(>CK>)g<_hacc&0v=KHV?-qW=Llkd(|tijDZZBMGvVPk+w|jmow8XAcxPiQ1)pE z*+;R**T_bIrm?6 zs(&RsPc0&_ik<;7HnC4UDw!aaee2upU)pd%uHPc{Y5*wQJ@+awdkV?Pss0+le7A4f z#ii5iuztmUDe1M7$FNUiCHWF(ANkWqvkob0gK}p!4be+RpkVf2**Ty9C1q`AGNNQ~ zSkl%oFYJP8y_G*(XCpyOX?E=1Zvhzi>FpM484o9sA(sbzSfFu|y?*!KISiCw97_N4 zs5-&&_1hjBXiYd?nUa_H4RwbX!zCTwl3ro zWx@S8lmd3Sb~HQBBtu^)mB1t6VT7k662x<*39^OB!x>mGuBCLm^K*=ANvB!)w68M| zJ`Z#Hrs;eK8veS3V&5g02~PUkkMR`fQa_8d%Qqq4w&ff*t~}`P73!z>oDVg7hS|)S zo#@iXOtsEjZ)oIty6cK@EYs9(6dXBjR$I7y`52blfGoVG8{hsnjg%C>RgaDT0u{B5 zC3K0jCgaMaUBkvhVA0_C>g`1WT}ndk{m2G3xu3U+G8qBad|>T=#Nl8iNEJ}8T>|$5 zJ*sX?h(p|)bCZ*?BA}B~l|WaEWrzd}ldXQ?z_Ri0%XvZqP>dtd^w6FjSPl2-f_!n3aW$O0cW1RI248x0{;|YQ$KKtf76}LTMEl;7N!^7 zsKM{G`+!?yn8bls37oRa#wu|(rnR-;;lA-JLyS( z?<<*t@srEuL%2nV=Hpi1#~6%bYPGBP*tG;4mXmU7gy+B^17G(6V-~s}Z9RYG`+1p) zWNuRWO4^#ZfF5TB*CFJ*p*&&k{u|BIx3-;)!?=Zb+Z_V9-Efm?y*o;X4s?eT)1HrG z_cj+fhv^U*2nbzcwt6oK$qJIpDTCi2(1|T3#`P|&C>v+?|Hls}SAVO3E;)E!cJdw< zEI_F*_=k=TXraB4KRt}@SM~ino;i%BDdMKKn zVBg7W`gsH=npg?HlqSHA_bPbqMt_KJ=|g1r@#e>!@!-KG|E$v)^G-G9-`-KqMe`55 zU#=@V17(lH+Scu}@ZG~e^oQIwYPS~rp4UVTwO6W?m1eLz!jo?onSWQKt#7W&mG4x* ze4kd5s9*`W^YxxeIp)0|RavchAymsJ8N)+%R$eqMu+ZpHQiQDW$bIT?OS^A|mqJU!6zSV20Q z^b-Uo1t{4ux&Kc~0etEkbb6B4jRc(QLK36@19PpB!}@ECU`%Zvji$@ss{VjxQ#uQP z|Gl|ilbXOkTM@P0*?|h{+3yy&l7r>f9(rX7e6UN-B~i-%hq(F6OWB+F;AW&u+>l*9 zw76X~ynmdE$bJ#8hxyc@3nQ#o9KSt>wyA=mj@Ms7ah!JN+kp&-f1k(<#pXy3UbhV& zmoLDO_br9`=Q|ik`@(a*q89l3U8e;T$e`tiNJ5O>4&tae_|RfX2~s-UwB@Gk@K12$ z?*Aw{&u}c?H;!vqh0GG!o9rE~QxvkYiLzyctg;d*ip*>&J1aXQdnBu$GLyYG*_;0N z|CM)+!*ks3=eo}G`~7@u&L@Blu_VdqO#{gE*bq<+bc1k~icku+Wke-5A6px?gopy| z45hm;KU>&uVfHc{5SA3xY+})dnh*LVs#q@T>fj#n5Y}J5Gqz4NeSaRgI*!yBrZd1< zYi5;c(*dM1-ZtOTr!aLm>Hlo3;q?HPkLR_2mMOzQ4!Mi3ue1XXS<1GbNa(;V6kIC5BKh zz4KN^>2R>gt{0!Nf_6VD^85UL3Wi#>R87O%b$O2x{;Oq<0As5+^sNQ55aJ(Yq`+nY zFA|B{_XqIca|`K`;1vQ$HsBE7EhYo9+onwwu5&1Y&#T#->;yTf(?0k-BLdp8HL=G+ zO{na%J?~wrDHQCId`ID~EL_nw`0vp;8(6FtjW@GGVl-gIi}6cF12Y59<3J^@Yab8MJOYxE zC+E%|p&zm3rKeq;pme|JVbsbqU|_8^*=1S;FWm6W9Iq!>4v@<90hZI(y60rVX1b1e z$+#Z9{9J*Z6AhVP-QGfqt5<@oRZF2Du7~}{&A({d`{&+B)Kl;!A1%+UT1T2QeOhBh zmKeYMSNTnI4d8sz=9KW(2KzsGgfCQwans5AzWH2=1qqoK&M{0%5X5SF+f@{R7?9ohRTQ zBrp&>#t-=HnhAc--=LO5v5H@fg5d3>cRAL)3-y-KGJPnnK}DCVi^6NV5V_`wetG*A z;wm?A`n2f=nt@>|xzKvC-)gP$xqS2c)Fb%%?bKUKH|4kxr>x0nThlVo&Z->GRG^f?;u3o zQD7-BhO~Gmx;{8Qn)oa%2Tw+4eI*5` z@_KFYR2jkYXSd_VMi96J3bmKiGQylB^S>t=WiYImS3RJ%iWCXhCSn5nkd%K`m3v)yx_|Uz2aOikVIL4_=*Gw^gDHYm&o1suv$Ap#=8d>v zV6!X;eugGb_KvXkC(B=vlRhP2W_bF51M4@G#t83Dx;=ni+ErRyUP7oSo{si0#_~pL znqtobuRIe0TBOS(aCD%3;G$o*Q^rkpgUxuJlk3eMw^(ZY?n(RJ?6Poi)tiTwW#rk z48H~90g+tmZ?eF#85pxv9RcTQ<%PCS(}C-m*0C0)3sQcp6h`MM3fF>{NdqZqz<-H^ z{M`9E#|Mfn_m_YYinGKkkyw49GT37#)Vjkv%&icK!@qzW$KG+_OV@X5Bl7c??4h+W~g1Fn?M zOurwQ!{{r&ptZvzdlw^=`x@_`3^tc^#VBaeo7%du>rRCzQmQ-T-!2^;6=gjSWvw*OLqDv7P#1&#A*(2 zf{4KAdH?iU81c5m7mCpan(UWiArF5dZow(M&0jl^d^NHpeaaYaxu1I^bNd_e%2c{! zZr%(@J)Pu>cHfcFR#PGi_bUi)!B_0MqYkWh8D~uH62dLgY&*ZKN#xQRPgHym3e%B~ zEAC*q_#5=9CG!|(sLUyHm~|)}E+5_%p{{rUHrWl%5JT*m<) z9~?5~k2E5N$Ol@}eEX0;HrCH*<%w<3Ex8_UmTxzQ3G zidw?CRL~NtuSC4IF0^u3e%Q{CQgE3c>#ICph%=(kLjpZlsMT00z($C$;c{vOyur08 zXp3Ni>ObAL$utkpwU}M@(XUv4+`=e`()$leA8lSa|Lp|?iVQxDCsTml>_uViIBc#I znE08x8rxT&^BHnWVT8x`x-7Ub51hfM9o6N29{6?K+z~+_0PiPj<*vzIgqQ#RX1Znb z0Y0Jh@fpt5=>5kbZ%6J&O zmG;&OJGV*Hyj7*vf+fsiEU>=>pEPs4|Xb%0lYucj$Ym{s~%b-H^}G0f}pZ}l${1_8~7L=RS3b9M5&{Z**a1Y_IQDtcokge=T~m*6r;7Zd{u3y zU!c@?ea>0#Eu$bTppU(0o%2a+T=amwFq~bf^i(un|5uoN_M&VfQHhGcA@!T)MCr zYz8}TpTRYmi$kFK4lek86T_=@fY}}Net&od_)km(XSIc4Y~7sVs;VpS$#<|TI}}3) zDV_5jm49eoSh2MG7c(rJa>vi~2te6lp+DO`Im9;wU7z=wK$3N|{>kmMpg|y;5Ul*%lg(;`jnNJMztCzYqSh6Xx^6h$Ky;ru;yxsvzo=z@d%%dY!E;I~&s zOe4Su>kkcC7gcTpgZA6;S|(DU|DjQBhH-5C_hBjRcP>b}zYrJTdj-|mW!l;;LZG1> zWOz?W3yxllt(59x`+AS7X)(P$=z#)>mjl+jA}WwSJykA*p0G2D$g$(8JGNgf zW8kiIoR5Q#aoRK_wb{@Rb$QDx7=g}Zu@=F-hdW%2t$&23qu?p! zAg@M#Eh02cv1e7h4n}gWIrF+~@R27+;)6yEh?eTM+{O0)GjycPMCEHpjwsUuhrAxK zpQB2s#lRwezN@YMNVLNHq4bU(?Pg$f`2{1joFdaJVV%$D#Az#xL%DbJmt6Xm)ac9Cn4pC)r& z`Z5#n*E+W8@q|Fq*;2>*A45QyRR26t!33%bFUE5U9Y^jZ@|>3gctG${O-7ZI0M_58 zX}zdy21AaGL_r7KaN;)P;f}M5`p&uYH72bglhHO6=j#YYIGx8x>=nVDDn0g$s1^K( zOVO(w5`&nDehSY3%=h|VoG(SRgVVua(L#9=Q8DDS;x%OWb<4q{iX+Bo!H3VkPfr)PC z|Bxw>T-azKmRldF&Tr?#d`AwId7UI0u=AX|<>MVD5PL!87^eLR<N(usbi*% z=U6YpG5Y@0?O)qqGA5&;G@J})Wqv#?NSH&^g5;?<2;!Eoigo;l{r}Z4KIgbXcLww|8tLmA?BLPxOpd9a z2;4fjXUn}E40G>R?XD%NVf*cZT>l60g}1>x z+%+w;Uj`niq%rKa{sh(`@jLi`;$U^ik%~2~2rP>?-v-_^gBgcCgU2g|VERJBQ&g1~ zS~qB)zoch@Hk0~uoNd_NeDA(nd+ITYQ@=8>_&E}o4NIx{X1*f65xcbM)TcnBt1k4d z10T3mNh>Nd+98T9KldHs5#lVkIGpoo5iR1$1X8~y21ZWY)uVn@D2D&G{DwPFHy&=A zIQap3?sLZuB_JQR<;jHTd$M>F+PJ6$jd)9=eOVu9%eW6|jP6bRjSBX}&J1^c6& z&C6g20>oXOn{`@H`kGO69GlCf{R|^|CF73uiH{?HUEM{mu51#$nb88nO*K&`P78=* zoBU6`0teLDWBX-wGoaJDQ210^6<%0RCx3B14}adxJ-|2k0(}rTX=oq=5}A)R#)*Ey z`Q`?rK4xopo&CDT*~|jy^^~tt37dkEZvIDtqZCA$NVL^ILIJD^9*Y(~r9e4Zt(sxu z29yj{tNqR}2SOlF+C9*MKDY8qylSS<_8w<`w$T{EtKu{CzmLI@(DwWc#djpV&GVwI zq#ezewEP}?xrLmWq8|D_(S#Kno4rdMEg-C0pIvCn4rZ!Bx47nRKsJ#IL&m+EFuP#7 zAfi`>%3dqSr|2QTmq_M~_^O2UN?1E>&&5K#_yu92!f6R16{~37vb!nUubb=33 z)S*9y&dOdnzU!{rJc4-M7{8#9!#pW*l%fA{2T+h7ef1g%9;A5*9XS+`!?JwOC;KJ#{O?V#wKOfQ< zd@yZA1r`_gN3Ag4NSCC;*!U$7pjI$S|EvKjUfTA-*z;fhlJ~V^jTz8Zr{sj0QbSZ| zOU$L`p3rh*@NId&6OgltaD9H-2;|9fj{SMnpox=C&LXgf%$#^0R9nQ`PJ!AhIn7VTmr%6)~zHt-IFi$zLy z-kw9NRz~Zi$C3cgk@d(catL^TfCopk`2L8{+wXeRaUt3mM3ddZ4*cy z&&U5HRE9>ez}IyXi|Fz6z5mKM{NbaV#?&lO!cGh^<6n||n5^PIrm`zSViE&N&9PWM z_>7Ba%*9S*GWU2vTyYBe?w$F;+j|+d#-_iKEaZaVU1L?#ceo&ZZvKSf=PZhTYBP3A za~oxKE0JAsBLKD9O^=UfTCscS2;IG#s?f7CD46tI9y)lRiYk9egYpEPB$GNj*g&GG zr$((v`8u_OVOl@LeBF{aWHf;;*LKcuk7saoW0E~sehE5%I?ag$>j4*qqfPm)F?csE zxpaHog9zH$lWe*L#4MFNvydVIabEFuseW3pxpAhcS)&dFY6@dME%l+~8adgQ)ALBx z^@$PoYKBm7wchGvf!$UKg+`43DxfCAd-tUU^yVM_8&UiPQyqK%DCgM0_C1NSc4$5v zlNs&Jm#3m3)9)Xi1eGG*tK}se66ZnaQ@yg6JRgvmwsADX9zcvx2(gij8g#Sot2pXs z!JR-zSrQxd7s0@Or&_lRvWEFP5 zdzyW*rP~6Yvu#zKrD=i=Q;W8(z8~oE2f;{fOL7oCY159%mw=!blvBU|D*}02aaxiy znD2?{&jDYS5;U87o#Whi1g2rn?wu_l0XLR>obo(rNM-&K$jdhjPu!T_=oAvdxQH3k z@v0!^WB4wSE;NiPHeBEP9;w2q>3k_(Q~?=O$$*=B_qtxR5eT;} zOX4v_!&o?jt9z$+-5R&%9h(eQP%LKfc~U-so`&wT&Aca*QWw^HpJ^PASY@dRQYCNehdK>BlL~ zSTC4PO2p579*nN@ee)Z|`06Kr-w}-^Ko+;@t(%yK@U@;aT)uXU&gVSaVZDF@X>tZ% zy@%UCl3LndgZ2qnK2R&o#O9+L|3q)g{Z#-JVI0p;*9}A%&dkhnT^1CmqmAy*q(d%_ zKlQUh2?$lW{UZ+ZpWLFFFSQf;fi9(K1^Mfqfg2|6ctmR{NRzPSo>z_;R0!!^&RC#_ z1mj7j%Xbx_)XO4@+xi^jq?1005jjS-_o?U?>_1IpO+1ed^M(3<|fcE{rc*-9+e?qxS(3@{d%R#zg~<=4kA z{fPJ=C+9lOU3MZU`S|y(8+SGEym0JQt(JlpANK{twbvm=nC;X0j4TxDUp0OpqYAur z-kYinbRgtltm>-n0Ffzs4{K9&AUKsZR_Q%6Bw2W{{!LE>8ylCc`^@4nN#7A3k3$WV z^W^b2%6Z_}(6vCiXbmFV$=r77(!jcJA;G20A8=2lO<5Ij!JB0I%99pr(D;{D`InCZ z2veWPs$J|w**DD??Uql`W|mg>g5m^{5{qeM(YXa1kH3N>Oyc< zoUEkqdJKFo?(}c>ybB+adWgSX?}2GQb2=B9B4leBV)zI1CxzWm^gX zko9dOxt5X)PfS!-6lJsEHU*j|UZwysQ7sdfo20PO)w^E)=`Z3SWq6k4@DjSH>9tK7 zE<%fWRW2zV6@;uZZQO7a1`jiDt&ep(Xwp|Q$niT4cqg6kYiseqIJ;@{X19RRP@aLTcdjtXJ1fqtaT{)%Ju3WMwu$nCr&@(6lpx$+Y3|NDcF^sq z|Clzjj3|EBOla!0qvv-*sOf(HM&s`a9@Y2uKnLGZ6yKyI;O)*(1n3h&BI!75pY{aO zJjtw<)!hT;V6}XzNJD=tjEvSl2|)BhTEUTg8d6DpN#=s_ zL(NvKNKQHQK;KEK&fsku@cH3Bt#o#RlXuqXmj7X14c~CVJEm1A!Q=|*hlhXQ(CFQC zYsGKmhIb(K0P|*TP>KIY>+FEThrT+hD=Copi1NQyp7Ss)d#j+UWFFn9b}wIw$9f5D zCQ?uP*HJYW-i95P|5Os)kMof`MumNReWCdt@S)0U$^grm652nZKg(tg51Fk-!nQE) zP1iY7b2at;xvNp43qNqkPI{&uvwh583A6izVU^=4QQN4d2h8}7upM{+|DeD z!{WQeQPFEy9>(DE+VkFWbT^rbwUq1tE~_ODeKitau1zMeiuo6-mP)H$oY zQV}R~NXk_v7l4xTRod*jVq`{3$JKoy9=LygJH)l(1|0jwwu!MONL02b+{Esm@5#ev zw0hqG5f!WJLV++`OPEs=8a;rnb${;F5d*LccU`O!D+Zkewl?qLNJ(T+6d`Sza7x{b(n(anMj8}~!-;#l8`Ph3si*(rW#y!mVCkjem z&r9fDG>4hG_FF_o6tdn8Cp!bqXJE(7^TsXOVvzdhW^;DT5F+;}uf9+c1E(W_A&%B| zR5^otMER%%t)!0a7{C#d@B4_uLH-q4zh8O4xSs_UQl8;Wt_r5`IX$ zjo|Y~OR9Ssn3pT>)1zs2Zcw-R6Gm~H7ov4VAOFqVLt3zATEA)sw5y+Lr0jk|ehy!x z6DmS|3V|1>x~@P+Z*@wP{5Db`eefyw^)>AII^Q%!xQQr&^EG%w9)dwagoyLp493?L z-_Uuo1r{fy4UJJ&a5-?b#t-we;FG^f|0N^~IEpyW?9HR#jCeKOWC`YrzpgcP^HdJb z2>!9O^OXc~ACC+p0vGJ3DwDW1C7i5gQaXr;!I(?Va(U_mXiR*<5wxIzy00^wIJqHk z`slj1vB5H`yCzd5{viPxmB~hCm1mHlR#@eRvMr>fnF~>v`NL4b^H)9DASXbS>?M-e4M+xJXiNn|+*~6jy(f$U)V`pzS zw!k>48mp=fzqLTRDH6B1ZytpbDENt;Swh##9;b^CngKn0%Gjd#u=-|L|^D;cguXKvEFkarOkp9C^P#I7| zRC!^bW>>+rnoI>A**SqGUF&GnaQ=s)T_IM6XW8Zegme2#Z&UdJ$&p`_ zY@G)1r~S1NED#63?YyU7E|9|8TW>`zZk)mPgz3W-T%^!pTX7UZxrH>cHOxJ9^Wj$Z zYyO@+Dk!a7p*ZPGM{iwEnw}9|hG;f<`pTs#h^b!U`+emGP$d}t%A&#cu5aUg$}FEi z0X>Cq?I0ZtPv6F4wTVs?`3wHF#K)1ZU4X{&*DJPwLqzr`$)NES8yso> z4Tw(4f~uw=nJ3e#@R_BNlIUm_Q78nwLz;hJt;9A>m_`bWgyRx-Ek8kIzh55y_;c`7 z?EAg=Z42XH%f}Dv#i4{W=c(5^n_!&zRD$!pGl;J3#{Ec?grIb9ul*Muz&l;1@=o$5 ztQ4w=#5rX{7(>9>NZv)%@@@E;spLNTC;G0v?ru0R6w_Be^<@C=n9&|J{0<~1Fj?ua zh|NoUMmQElNrC-wXto1!FDQ=inI&xy!Qn!e_;tQ#FuRyTy#H7QBB~W$kJrY--2!ed zMdf|u{)5eW-9#FAZ_7tujse6W>e=UJdxTD{?%!Gw%YgdsdUaL*V=!s@z@Rydaf)!p zZbfIxAnUb zhOE#Q+V6pdp_p6nSO8cm4}A0E(_!P(sXDIa0CM?70*ZO#5Q8Sidsh-kctlR8x~F*; zROHs=}T5iPD zo{%iYJk3|94;Nhg`87_fP*y~kTb>RTM5kXFsnOMk@cC`)mHzi|Zs(k(hkg~T$srbn zXm@zX9(^zSa0UBbc3I;#9!5N!=LlY5yw;iaA;T2u7K{f-5T3r}2v^(JledeWg1(4Y zF9kYA0|d`zllk!>nTMr1^UWb@9kldHD@umvQ>}&pa_Z0|v8Rel(ht+o0UUY7-oPx^ zdFo%04p~fElN}?IC_b0@=419g&|7_cNm=tZy6Cko)r$EaEKGFhEfOR^oG~W%x%*>y z7D*`mz7czmhPVIl)E5G>=M)2>RW)FdSe7XKOdEK)*l*V|hofFfo)ERyn8(7^%fI5Y z0~AOOpHZ;eL3>TP!j-vgU>@Y0;m#um40WNt62bwXy-oR6pAx%&yqe)`8pNKP+IMG^ zdZj@7Ec5rq{1*^vrHo}-abW+hLm7$QKV*F~MIe1r6;j7=-)HZyf}9HVF`NA@5O};M zR&MnN@zVw!u^!c}pM%x-2&8Ly0>gt0K;v3UU~n7fLz#mfK%Ne&VCm<~?g_*$=o$|e)ULiH?dd5{UYG66293}(T>pQU5axPsVTO63=mR)}5hd}ra_4S|?e`ve6 z@x$BN2VC)zMQdaIfHkCaHc-V9wCs|&OCEhdwmvD^GCDlKi7&>Lg88U;l&wiVRx84! z2^)WwR0HC_+0*WTsv+m0BlQ%*5!Q60a!eCWx){!@M^~=biDT%ca4QlM`i$RiH;VF03*4VR6!@+!HQ=Du832uPXO7 z8gxapV);D2B767TrE>p7czA}S_AI_L+;CR2t|8e#<{?IxZ~0(6D271ZYxN@Fa&26R zAa4YSyUlAm&*^}to!Awc10vu!VqeYe6@bAnCPi(PY~cL#E7!*|Au!}O%sN_LN7e)H zC}&@sqTp#6s-DIxfI}=pXMJA-)SnwgTeqYl|CeK=gH)S{XtT`7C2s?{98Fd09hRc~ zW<1oWk8x}9`hvSeCsDc-x447g43eas?bmdYfRir~S4FKWksZ5tZo@1IG&FDZb;L#i zUql0W^5iX0%?>wLG5(G{SC215vIxQX5}e7JX*2M7!A_LRZGqhb?k@C^OF`+KB^OOk z1!%Fnn-KR=65bS)Z`9D=0ng!pXp(|bbb9+#ssEca>_pCoh5z`0PIj}2E>3*{NqQfP zZE;2*Qww_g;1brKX_*=^k+pz}(RkmAtTmzjW3{XLsXyjzSgNu#ZG)mt+j-Y}SRc4^ zJl-%B2jr3_ufH!zM;)*Hn-(m%L2WhS+$AMXXrFypfV;DUzMY2Y6@IV++AUlnbFME) zRB}?)m*pGcNEFXxvzvhFmwnts$CR*PbdAw?ate*Iu~PC#I6lccPUJ4 z%F057_a9b1h9HQ7)B4!9`!FkcTu&q}4P#|zgYRJ+_d2%IS8wF;;qxaC7pV)cu>D)e zmC(gTaFCs}+kQqZ%dKN(_v+drTA{S{`-A1F1u_k-ho8~I-gd`-#_HrS$4iSymMlRb ziHU<&&q>EWgv-rV_LeM+ zpgWm3I+%A8%x~NODh<95QoHs9?=ZfjVZD#TGFNk+@0Cx6UlL$(PVE68Vj8NqnaJyu?-A-u;@k%IZ^Km?~D{QbU#rOfC zDi?@K4lls|ws$1AJvl_z$PqA9GXg5UnO~hn3TsF`f2g?`D(D(JSJY3zV?6d{6#oz! zV|j62V_y?$=kzbVFzG}b*Hm-FZ@FRT)W;?@^?D#_)fSxcEDdGx${lX|4Z=gObTfA> zw(=m_~9u*KhlM0EJgx%c40YIR3gIKOm6iA299tMklLl^o? zW#0Utft8Gxg2Y(tcT;)6pd~H_{yFO#&Jt{(t>1Ij4gIX(%6NwHhzXlRUTy#57t{@m z@98_(s7S%R^V$VIPHBk5zap)-GJr}G7UZ1v`Cy{Wq~Os!DQI4zzK@6H)2OI!e_MOC zkLE3LR7!OYA?D7+bD7q0q+ww>bN;3tNcH2#Gm8tryD}oSX{_Jk!Cs{18X^SC{6B;! z1xu0fgM*HbJu1*&YDUK*Aq%cTWI??Wq9FaJR%Kns5qrD0 z{rWpbh%q0je0}vh+!iQqR>k%|Lu{j2%vH~zlGy8c{zwYS(HqI{q|}8eL3y6F&8yHi z`RZkml?6N~O=3&hI7WLE+}-bHw-GKh(k*2ELk>wK-}@^jk+GzC)<@qg#Hw+rTas`B z`P8kBKQi`*3)+IVwKE0q#*S*c0-MK5=(R8qlwm$0@(To9G0M=+E~ZE zOAcDu;Y`~;IS|cQLf~Yyjw0O4EvN)F;NecB!SA!*(c1~ecVlVY=pS9{=z}CPcqeK8 zYg+jpd`d3ICBb|!wn|nGbnPRsQgf*0yqy6y@5V&R?Zu#sQ(@lgwi|>j%AUDE91Cp( zsu?@Nr-<9|MIeDXFU)>Ct$i|hf{yl{dB44>0eSEI2;AsR0gscv?y|fG z)=IA79lx-gt4*igMWtob?oy!2<}`x#pQxSs+mr)CP4eNjSjwjc7cnQ0a*0{!?umuT(@1ASR(T==z4j5E7ydsccHWoUj&8)7;_7vA0O zs=lNLp@$VH`}ZljWtV2^Ss4O?`bL~L#AG0tKu8_;xEtlYct0kUH-egW1Z?{jaX|FR z;&o!J2Ty`|X=Y$bBQ`-2IXW&>=i{f2=Hl@s#zROQA`W zCiUIyFK!wd#6F^%U(7*Mh2s8E*li#tme!VtT0)Xi#O_jVPQXNI;dR1o44V!$3FDuP z;Ejn)ve_4MQ17Qr7wuJnr;fGV5--SrQ@l8Vu=c#Hkg-7H3ql+43tM#e6qSakV(+TU zZH-7yQ1I5(qgv!(quu=^>@G|Pd7cx?#05>EyX`+#1RyOjOv(rA4-0Km-`eA`gQu0) zH}_jM_*2MoK?RbaRh-DH2Hy~9YSr%ue4T+JzKj8DY)>slCes(QJcRJS{m4xxJb|O< zLjmJoFfJQgBF)*1GW3n!XvmNLEc`TO>f{{fhT2iWi*Mr3gUH?YMJ)s7V0UiArREUh z;Z@!ECbKUDm-q(WL|^l)JMa*L7HoxX920|Q_Sk+y%k|W*AOs91m@E?-o|NPaQdlOHcrD~Z{*EoXB!h3{Y|DK zn%#zo@e)rWY!^`2(t`uqJzQ88DA1>2JwOkTx6(T%7T8F3bNPwg*ZjDZ`MB_Fk<7wt zc8idqyby<4MHn?5+MDG(@?TG0ILD+c7ccO@T-;ZO4C0x z7&RaK@&}&_>V_1i#y{gj0RB1Y%}i%_Dor0ZQvMkV>or>|=2k)f{gz#t{Xf*DcY*ib z;wC(E%2d$mAgVX}%6C0{{|ZpzQMu)Yu!C0Hhc6rte<6YAczhN%lW6Y0n&eo9a&(r_ z?O*P{LsY7sk~sIu3<5;hEt2wuVLtj!;kauNx~%Fh!&$$8sJv=9hdS@U+vm*I`-w$p zoUEGZD%P)VWss*;#=O|efvQ1yGR@%rp&BX=flYXd#sS@tc(Xau~#vKf>(%K{XL3+kvD0pqkih(DP}%)A?O;|JPVaw zpPPoyjlxyke!}n)$C7ejRyY7qplOs$4wwh!9oZv=VIxfq+xqYhM=!?I=P_9au}fV3OfgB$7E{MnF2qD zNAi~iTG$xlNR|nxM539uDz42h!}rwsqj5|aQmDqRZIictF&BiWu*R!KF0V+iE$(F?Vc89GFU{a@yK@g!3yHWn+gnN7(uHU z&HmzN_dsj?>Tkv`g79WQ01ol{P>mzr>rZGEQ4k4zV?(p>^YYux2}OC3UCWD)^}GYu z&qb!ryxc_B&-bXVU_8K}{=cE+7MCIUS8{^`cE0K!->h-TbAv81`VhMRzMwJwbxH=$ zNcf}ds@>ry4=*QK)MX46AU`FJ+vWBW`f3us&%$#bynQp{vNS@WCBO=o_n|oinbqC) z)~Z4iPQB}Ju>}QxJP_+^ya~c09lR#z)S-4vsEwO!1^)KL32QLpL1IcC{c}DykSX}` zQv1~fcw4;c1-ix%#V{3pi2XkE@kC~(qGt4GBf#ic#umy56uiQiBLL5S9WXo?Xom+f z{#(zV5P-Park~}nL9`^dCWzm29UlAn_AtmDpzl`dZxrRaQS4#or(UiWH1I=Uum5or zxZ!-1DWa-Dcz<~^xSdpCUG6W58~He59M?0>ycPxSSMlVGUgkm7G`(C*G*dnPU?w$P zpetx86!>3lNI~repKB>~6(NLvq<6dLO8t-gn_Di4oybF&eR{=c0v?b1ET*Yd!2Q>O z%$L^6U@h;q>H_&3tPKz)(?l16$r+RFNeLA=Q~2}=+ld^Izr>eeZa)WP`E2%2PI18^ zJ9%A~6yuoxs8ph4zf|v$r!(iKxsL93PU%woB7)E>VyJO@5%b+fZ?JHiz`EkVo_Y0U zSi!AObQoJgBb56B`nNscxjjFR+bcn!!OKEjSdY=m>|V4zxh5PfKiMFYhWqDi4S;#Vh#7P$O>1`D_`)TuZO!NR`!yLY8$Y43AA91qPG`jGv zm*VI0Lo!%1R$>v>y$S38M!3#w&Y-NO0dGaCZuFAO6xY+t6Sx8vcqKV!Adx~p-R)IA zq^de^PD)^&K?k`prj8S2)7f*K`E?&Us==GdBsPU_9{eRHG>kw?l~#V!#1R~*@}iIQ zuss{?p~1VeJ+M-LjU@4PA`*ILDB8~+3ND*5KOO}RKqhrxOxi<~T=Jzp9f$DeP1cF0SB#aias6|*!HI{7hxoP!JF?$;WKPO^ef4bA?6 zdnD*Q#usi#(Sjr|%?@6zBDkW%&TJAojn=~6x3#UuL(W{tIlKjoFJS+AVYxsZmhW4%%#az=%b47hcV z-P0{e7FKUE$|T>(0n%U8_!}b!poo`|^OIH_gn7RyuhnD(6WY6f{Is>6TyNr+eQ;~^Ol1Y!> z6?pfaZ=ZMl4(QC4H7Gov0`@ky&%Wy~pvHgPra%5G;?97GNQ?`G`|wkD-}pWF{b=m$ z_3|=!F#AXI@^2E@Q}ZGWuJ^=pTvT}{lXcrH~7IwgAx39D|w?NiF;N}Oo8 zyJ}dwKvjrn?cTV#UG#;zPP2`eV+{zCp&Vi0v4Qt%9EaX-Zo%(v!})h_{Nd`wUX2g; ze6aJGRN$n?ec(3wll&Q70Q}K@!uJd0@Y0md1h-&qpxQ(4F7nMc5Re^l5 zLo-|ODJXX5rq5K!z&n|9i{I{O0)8oD$db4=klo3dg~#nCP`l~=NFZqX%B<({UF}`u1b(U=pEz# zYX+Q|`*Oujv&f8Ca9y5A6z<%$KjHME0!zgZ=W3ljMAEF-m>TyL0tNNI7)4;_8%NUy zt6j{aW_+Z~s;dHGvUDbF_XZJ5*Ga;*X9?!x%2?YM69mJ5M8ldCDiAALvs9uf2pz;4 zA{IGsp*MA;jPn8qL?v6Rv}UZM;fN$PL9Lr$*ljE%a)}?9ekRznqI7UbDTxkrWQT8$ zj}FAxap3e^alzxNw~!;|`_0R(64B_jYQ=}JL3m@gqg4zktY6i?QX)xvXU>z z*0XTw>=_FfcKMJXOJD?2!Lt5Z<^Qnzlk`Eg!vHe<=xB81CL^?zKUG;``vNzb^xY#G z`Vr2CWAD3a%xmSetv+tsf!=+=p_hy)N8bZp%kl_S!}h_{lW)OXAotap-I0VE<3KgF zr8~AGo;m)14CfaS0jVQBL+Tc2F1Y?A^O;4pH@twJ zlIGI`d3~7Qy1=_bcmce=Jlr}aEQN+|6fxJA&d5sFi+A_+%^)T3$B(Z@b3ns;{OFrl zkGeJ5ucdu02~l+<<5HiohYo2@vWigw>^)fjvWKq?J@50mB<+p^;X3j-t>km4v_*zX zoBSJ!_mY>4aw&rD_)%K{<|d>!gR`tFT!tp4CzhxL&qG`n&5riX6_hn}W&h}VH&RUt zH5cXRLp=IVM)dCVB5{(+P!{am)nv6J_-AGl8g8zLFP$j{($!uAOBR1%Vzl?m%^`w; zJ`FMMtQ~Z!+34FS-;XZdueUxP^n%gzqs-OD?RCB(?h)10G%#C{);Zi|1`qlVSQg3B zvEGX=;}6Oi%%ga9Ii%zw6n<0tC{3&mc{ZvAIfkoPhtGf~SKjaVLoRHIy zUT!nQN-h}37q1{%iJhLOs^f5zo`^r|XcS>UN;GbH19111k{Gkuz$`;NuJ&R8oU$xD zlkuED#Scp2Wj~mLr`IRP(?g77nj7;YReK4M`tp6SaH>VwLTwKxG+5vloBHpFQD)40 znxOHTehQI&@jYmo-9$fw-j5B_RUvE)c9hd$u7 z&)%zb=j_k?z zg_TCa+TX0MVE4854($pa+&4IEKUCX9+C%TYG{?}uVBST|#V185u*X&UVO%ll(lh(O z;?E2;OD@El^DLk*8}UGW@C{N*y{090!2=``m(SfCxdy4b!nM`B+X#O>Y;}!}0*H2A zC;8xT!jJohTAayrpsrfxE!|WBEFqEF+f%C0Mp4~N^<)4!sM@WboM3qrVsa5SZ*MS& zIA5K7tpgc8?-t73+D7dHhq9d+dFYv!*u)UtJs@gO(_$tz1ZMB8NL*GONcwk>9TKYo zFBH1XMA%0_S2z0UuucwI4;K!gx!wvUEB?5zYG0$am}|9VcRN6ZW!+}5XC6@|N&X-Y z)r8dEc#lZteE6-J;#iYVi^j*~cNyLjz~0QKHX2Ke*A(jzO5jEeS5*bYd~311o`G$J zWBxnTwy{(6TWAPr&|K%g8xRP{k=~pv_Xm1*aW*=UXc>OhR(7FBFW_rPIA)cXh5Bnn z0_!DFAQxe2PO!uYaZ45Cb@2|sAYW4~{EZ1R-thy^V}2Mt35(I3-$hZ@fArFGXkbNq zuy%vF8Qq>5BZAlS2B$GE zv&TKFbw~V`5DL;xW79I=;k_07pS>HWr708Ux`Lp}8MWjiQd)}zb1$I_9965AxA(cC;;sWgioDcfLY{XRu z6uZIB-fnJiX{oz{;6@W-GFN^ke3*lAY#-^~HIl<}|J@wkTZ}-iUnBbZIwedhL|?CR zSwa^^^>7v>sY<;E2LK1{uobr)w}=MWJi#&;j{h z&pr4XatXWNEedRIUIb%*7i|MOWnkBf6;C@`38z~Op7@k~%p5m@B&Z>pST1Udr^yCx)ji0{2kG z2uR!}JInQo5E86r{e*;4fg;mubgo|oPLud!x_;b(!3VV>U$LI^kI2s92zTWJte2bLg%sKe{rC^g^`ek$52#WU|TFhGQ0iBzS zo}E|BK#1n!9htMZ;1!fV!8~aS)+Z0mhoT9=#Yyv9$xtWilC3Mc(z}K3#<}1z{J7CP z*{GFb5j2Ie)Z=7E(4cLIT(*m!n$4P5-4$6n`KPUfKEf4xqJ_) zlKW35rRcR7a1;rlv!3D}?FMIH z(OZOvtj`uo^~2WQytoN@>}TZ^RdHeYT6f{wSUot(WD$rqm_he@6qSOzjlpYS0ZDt?a_KZex4x{3 zEwy01vM;)k1IqA@WKMQ~4$E0nM`(Q8J_rAamwXOZ+Ce{#yY6TPPJvlB-h@w+6>Q7& z4Ksy3hyUK3=6$_z4$AKG#cA8#20U(>%7(8z7-vlIj=zm5a2g+%ZI24H+z90g%z;I9?kV$yRRK(;hk62b-u=_jT9E)sypiinU& zK?F2#N8Tu`X#f|2BtIgH9r#6~^gT_?6F}^WwZ#W^*t+{c^g3e_d~2C>UUnyIiG1}S z$O`LY{Bx(o^>{V_8D)F8c*Q@V&gdX$K}H(rW_}FB%PgR~72FSJ%E*8t-W&(NFc+LH z(xiAuFo7wuxgvvn{%=r3*Hx`7DR&qR@zjiSUk?b53| z#@HMWs|P9qc(sT0#DFMIA`VazgL&h`?-U+sngqzu@nxc?t1FvKD3Q!8cA0 zZD7zV&&C<=4bBCb%!<{DSYF24jPl_E`oSz&8+`5?TIiRtWa0mSR&m2?O+{RxZX=iV zav3%c>ykW42%-gjfid3kPCJlOe@xJGKN+geyilW1BLV&Om{v;db~NJVHqCWi3Gzx_ zdC*19HeYx_k28OQK>MQ!iO4WHSSe@DJI1s@Q%+Ohw|O2=h|qO-?~eyG3GAjU_wIq# zgIf$07bRi8M$owZ(jCYT%`^2M#qt(hy2~8QYlv-KC-UI&Ji;A)D)0Gm1bAm`Rg*O0aos)}!blcfu-oA{NUe!$tyrhqoTz zBY6rRvQ%5=UfhMN_w}S>1OVRZn|mc*BZO%gKmMw|9IVIf^?a8;1kx_>Jd%7=i3SDV zY=rw(!*0zs0V~5gDoP7TmzP^c(@v5$x}hDYOk^bc@BQy6#l61K{S3Ars81VtsDuMw zb-N!{2401s%0vO99tX(dU^Yp7vxq*%xt=YGrvf@R@tOVayU4S&=JyMlQ}pU;hV>$! z5-jCe7vf=g5lw1>3cL0K#JOdgA3pva9JzO!lb=e#yKUpYfxP!YxuEv`qzdNCHYxj6 zGns~QA1!s>=AZlb;QW5ytF(4XSlM&Gt}1XAC?lF<*M@^3pzTS{N+k){eOS~f9C`(> zPSPqC@A`niW%-CFNf*KGNagDz89!(!*W{{XT|t8}%zMk9zM;kbt?#k;Q!q&sqGhHh z16SV1SE*!wN9^0&%mSmdAQ{PKA9yteUiaH^Jdb~ad8UVXj4@RQCs+{XkiB zUAY;37KqNn<+On`dYM=a>G}@0Jwc=7O&SP!E2)2 zJi&??G&&SLoD?bu7OaMS!Bf@nx7+B-Rf8}%Q&L87)aDBU7akXqEAxWiL*I<3v=TLFX20J3WWj22 zC|l$)Yn)||nI0H8a&K*)>95<>EtG2z}@5uFqh}xg47LfH}to3!MEOP?x_Wt=_>2wBJ5%strrD2n@toPV!>@ zBAF{vT;5eEQ;{Opy^k31tW!fDkvl=Ex^7L%kG@>bL2YWB9#$g0 z(0r@f)V`JhNG;WJG!3ZXA7@=n54In;&>ZS^lro3Lk8}3wQ&PdaSSqbW;|R#zY9#49 zq5b<$-d+@(6lg#I_uQ^->Bl?bJfqs=&9umQUk3J={|rR?E-+fa)Ln z=gQw~LkrW%cVt@Hz%)?cUc#y$nB4ySOD2^KZojsv#z(b~yz0BfTQQIBJ65;fcfSeo z!dxO%Woa;QWtjUGEh~)8;rvq<%mF(OSMlc#=Yb`-)|ya@8dh3wGXAv1a=u}zTL%P@ z;Nh;lKU|A>Oop_y>~QTs!d)&VW**CTw0us}xHp9)&Yq?7`z{U&$~WXKyc0m~iLXy} zuru6Hv_I15#(GCZ-=DBhC8EB0Fsg`=g$Jf4!4dQ~V9qN-5uc?H=yJ0iw2W6ktdHB- z?6WvXm3W`xsuMze;aiKhWMg1(2iaSiD8Xljzse`(HR$$#+COf8`T$=8LM-iZ?n12n z_sC1B*FYV2tfjb^37Q!723U%sV6NIZWL;DghC?PtYSc*~gMWT9ziS`;%lmxyxz;91 zkt_MpX2u4h+e&Ny(e?mSS5F%kB?t5bHfact`#=%(tew=;Oms%aB{&@?9Vy7&Bw=S< zLw{!$c6Be1f_*eP_Q!Y}oOo~E>-8ByR#K3V55_Oyf0551n2~`TjGS>ypD}{+N*%q= zza13%MJ)N36chBmy>J|kd8NBX+~`Dy+fk@oe`8Jt=6gS%p}Tap5Zz{c#^h|u4sVY{ zO@Blz!^vICq`uh`)U?Ail5HRXZl@JeBxYV9(;ZYZhm#NW;?g=)TNvlmA-KqrwE%R4 zUuYM2=b@?hx6?l4+yPeE{9@A+KA8FYO;{&r1u0LZ4Pggc*ST`T;I9#i!G z^TTqW-%2xl7{Zs4-}FPhu(=v|<#l1i81p>gUAeZ4&k_PQQ8a|%eS_f5Y`olx_ZpTM zC~+H}_`@f?;NU6jcNOunt55*zM@uhURUrLNhk4N^34ENXAb&F8va=;4*mV27y4NKQ zb&)ZIR&2x&8Dq)yUR?_7b(Uv_mv5rp%%&seGg`1IEMoY=y%{;+R|I#5*FZ*^(Pr1_ z5L&|RzxfRFMmGjsZ8)Sq2kGVR-xcfs0~$3pFW#AVh?QF9p-9Jh2*OVuW=to7r+42K z=JJxl;2P5yhuS`B(o&@1z;}SdOnM%4e+``-u{R$2)q`GHl$&g5S%Z8!O?KV05# zI$zCV1nIuxuf2UWv0k)UKf47xmSfWQzA!(8LhBk?A(ITu6&}bPqtp>uw3#&S3TwEds5C5p@= zF7>1o>8*Bj6y^AQgwzz%XpidT>TjY)Z|R8sVYv$~s-Jq<`tFe3dDHlU4kJAK`D^Rt zr+hfvglgjt4DcVm@Q>suO=zeMFZ#!$3j9iEuT>RXhINJ+f_LM((6Q*LckwBL(|=cV z?qYM(KOAqv@-9rHD^w&?FTF7jn3Ot>4jBW;QD2tu5Ap-9{QCL&>^k_;?RoTHpBPM? zZvJs$QG%q(QkDVZSdhW_J3X$a29eyST|WrD;pgA%iE_Mrz)w_>x?S}S;h*cN?%3~z z&Zro7k&|S^#;+Ww5w8V_N>N{M8U>((LRqmW%pKm79qm0d+y#qtK_ep#6(|lWvOJtK zf$4EuLFdC(l%-_Aq_6G(Zr&N>pSmRBQ;?!AUUWWuYj3*tQ}hy;h4xBP84dzvXJ}MC zr5MBw@lT3un}UDtHDtGu2$d3rk!s#wLF+mT3pVj96X`y&qJ#?~(!8s1aF>JvF%eQlEMf>;(F_xKs7B)ZoR-o@Jlx4}<5aR~3#hIt-3g$x+Q% zb4KU<!8y(pQYisSlnkM6$qOj?XVT>; zzg3`rDYf*fOaLwiTvK;zr-l2scVGXl!GTn*vjJZ>381SBpD#_x6l55)3#cQyK(_AW z9ezd|qOS||Fnfaw4_^mdO!-e59B3piIXmFMFJ_$uH;k|KE%~Kp_IDQ$=A0uV*7wCY zSze*0G%R2)D^?Y7#|*x6y&_E#uz>S0z0dLk#mqS7H1<~`@^%%6(*9M1ucpe_qP2_6e{(gyJ(xz_E^ImPRnh=^Xwa30 zu|qKQT(9B6`sY8*UQC@U1L+@Ks_EGC)3TP6JK>TtEM^nPiO6AI%5V}HvwC?bxtSrh zafSnkUQZsB?NI>xCe=#5Fb6DXw{URtH^aa-*^%orLr5~#ImeIP14JwIPeU<3#Xj-S zZGSE&uvJx!IIg1shplkc#=sWvo}H<=s#*rZh4LE_Eq*}m%K2MS#sVG(G(MIvHGmfd zej}H%XyK5WT%|=z8EysI@v4aPfK1_>6=$>wB+xSE)oIc|edF^~zZQP@$i?l(dIk?H zga2f4*5J3ybv*jqakUO`gdU&Y_sYj|$WuP=BD&GP3NhQ=3x>dLhI@9C0pnjQ^*h*L zJ$U_h<_*aq)#$SbBdyq1N*LSrQQx`b4Zy-j$dlL#ms?w%95}I_dPq?j?%ogtJEX%b z=0k7%wVh49kPF45__!VX%c!%vK0TNw8|xp0H++0{~q~h!I2O$gg8R5@|^fj zC3^{ER#O@6oRxt>soau3L>}JK-6723m;uf35eB(S8W3k@YOCA8U0%fSp>JGZ4@DZNIw=j?7OhOML1 zWCp*tQEuR~-4Op=;UBtJZigR-dl8O9Ki0bjV7`;+G+$LmH(=qISRBB(OVfMdNgTwA zu)(i+Ii8drtPb^y`!1aaNtKFKx^X&y(MCUd=^@l}cRa1!lmR?BgGFs>YT>I-Z`SvE ze4tbg79D0!g7i0YSw4RGi0Eq$*J!{WBrYZ%#Ej)&c>Dzy^p2;2ZC2NS*6$ge=P)@)4HOiP z6o)EQp+7)pq;ggXgw)jbRZRDxLqzl2{w+(mYADOme7+l9Ptt!uPsRs*I%sX~!vj$4 zTBnhHf)6kEa)aK^^Z#XMp_tnAW+C9M=jxXV5(_pzC`9)B8cJo(n zGB)=LBlV4slEVDh+m#_a?||PVGlZ2i1RiL=a;H`=fYtY=wtKpMpuGxJaV2=5VVY_` zV7ZUp-YfN*8yrOq4Am;SW-dTv+w<(H+7qz1S~|8F%0-_y6i0dQTR@tgD>b373ef%e z5Rl!d2PDrrgA6eaz&-jKu4Hqxa3kxR(}K1cbh*c9_`fg#ZO4huVk$`}vFyQnL`Z?< zKB{@5d9TBxkl9E2`or1-xzT=% z(7_+k?a%iUx&7!FZPpitmtL|Y>u)(h@N?KzL2*`iq}}0}LXrVFeQlo}KQBQNg`XaVhHI>N1Oql!uSYyQKIl%8)9p9zOqK5mAgs9*!1wpefamu(VZtpsJk= z{vE*v9IJyHcs(Z&7FJu03IEZpVI`QS!*2fg^SbL+PCcKPDse9c|a7}>hQ-eSeHuq&@mQlKPUjZ7+ zB#wVP@_>|ZC28x=e4v!N7^;EsuWR=5Xt@59g<#S2P5;+tA#HW)J`Tw&=4mRO81p5C z#=snP`+^c^Q#wn+lb(Ruq?L*EK(g8f1`DZpRS((D5TCi{u%at{#E z5}LN?y$2orCyTryzmbn1VPDX0JyNVs*`UHajeG`~$GWvWD3$Scj6z``+|2fN=p4EZ za(qVd-_Ko!spQLP6yL^Bs)L}Q)Kz>49i#2}7cWx;Sh*0>mxOV^OYz{cFK^PIx8mWiaPDoC8$4uo$>}O&Ou8mUWBI~irtroG zj$#mdc_{pyuM;Ts)x|IQZo{NY^PI$uYtZ&b%22+c0GXAxJeE>a0tG?dvm$C4kV$)M zt5-(>DtmN9j?>4$X2>>NTC9H#&1W6Y?+{~zsKq0bOl`7@`{bPvxUyE{DAEh^k91)X?PyKl#C7e;TGt0);QHf! zb_p(s_6Wx3ET9QYe3-`gAJ~5#c6#0M7q;dSpC=nu(%d?UkLvDnlz;68j{bLZAu(6N(K1lmYOoHF{EF>=x*z zvv?J7cY?rG$Xo zKQV@W^Is1^;LHR2zsK9)d^g9M47h-*^Fu>d)Bwyp&dVbqkpmc$CqeTTsUV-@F2w zPOV|+_~#>gD>ecCc#N=Lj%I{$#+LK^pE2M0mihXJ|3W}V^nJ(Bj5N^hQrihVeusGe z;F)vI6{3N!f%>5z^s)2q%Td(wCh9=j({CvLBFCSUWKp&2sC$)Ml_W9*%fCY1*5Euc zX_@AmUf)1*#@3cUu|5Q|kPg{REN@s5(twIO_aV)E1c#hN9jw#!n>3TzfZsp$==`l9 zxZPT$m_dZ~r4K{}BOThHcs7T0{fHNw1eS%G*Y3e9m)rbNAL!tbOK)rz>l=9T{`K1| z2ST_$nR|y5<6y7MrttG+(}Mgh#*na*5xDS5A%}c`RQ7;K63*5i5v1-B3o$KOqNG7fDk@R6Ye`qaX|j2>)Zvl zE_lvR!jUEK3;FbOitB}Efr+ipwpQdF_}9MH<&#Q*uH*i@k(AtU={DWG+5XHFKmrZ!22T!Ec$B*9Ct(DAbUqtw4D?+o z2B|Ne4I{8}vJw2OZ6UdOSX|AYj|^&D1fxZqrbZVl7FI5^AvR`+R?BmD7p5dJbV zftF{^O&VHZUJOa!}b$dX-Qky zB;WxrZj9KHrwWXec2gFkEoAVlA`9OQ+rysM;bEF>ZIc3 zS~R4!D3EwxuEoa4j*H~R54f@#GIz`}2qc*isX0ADpsYpb*e5rG9#8CC^?0<2xJ6DY zA(0CjU0;hU*c3wIkyp1@Y&9^1K4IGE!uU?J_X2xW4^evDU2Vtg5oAs?IVg1S54~w9 z)XiNZhmfr4)i5V=rMD@0e4MeAa71g+JsNQp2xBi(lQ=yCN71YU3F!zpPx#?9qUky$ zn5A=vktJh&HntxFEtp@and4W7c@U)D!*y_ZK96EH|JzZxIRyEEB;S&@iXo%&AU)IW z39=UY=-E@D0i_aw?#ekP;O9?BT+_3R3?@Z-s~R6dNk^uxk^O75A1Wa_k!%PGH(IMW zrt?8mO#ktCsu~m&R1RG}V1VvRdaoF0554lHK!m)xbGaN4X~!blbl-?mCrc`P8EGS4?rt_5g0rp_%QBL-%+UBAfC zeZV+7dQ$!EtZ*1@RXA&^-N0c}8 z|AFtdtmTii%~0h|*ydTZ4L@U3e)?{ZL%g6@#eBgEI!7(PZK4thoMt#VB|mnN)bsXw zBePKWtY?1N^fn$`@3l~ThL?;AJo*>)SL7h!L2HA7Wjy>ioo7m%9R%B4EwVCmLXZ_r z`#8hV2yfktEgFVHAP?WDc_4iesWXiGf4mOx&n2vcNmds+d5Co1a};Bq*CNrBe|4Cr z;MPlqLNDNd{I&aZ>@HY7ceaVE_r~rauQz5teMY!DpLxk+wh(X5pcKdBLF9a8K5x8n&p84t-zSuX()ZkWotx&bh8KlS-pVN(VVtqp~Dm;N=gopzD z1Z09-r|l7avd7mHHFotx1vkw2A;55|cjU0LsC$GkQf4&tYcr%*+rc-_qQEQGpN z{x#pJKq?k2o(Y%OK&dsol}d~h-WCd85GC2e_KnrzQqMC0|2nmG^nNF3_PCdte@%rc zt#pDYmb=({b?=+Ldtq=Kw&&YfCyJeGcKYE0=YTF?a{j*&Y|o$PaH!K%4ZZG$oX5%9 z@H4{sjUQzl9Ppl5t@X7Bx<&VIrKekn{ovBxt`H75o+h`uWfZ~B4GFty18Z!bMRpu9d3I11I@cR}$ruKIoL7;&tq0sGD`(6l+Y#NN3AU*zgifXJ z@j|qXsN`geTyT;aa{Du6*B1Z4k^|L!s&hr)F!wpf`ffI~-!T>4DX&9@be>P#mXhG6 z-|4c`)J>3*SN-R6jR+2J#lKaF{0FRA@B9Qz`jMt3{lN`2Hfa4-)L4B;2PzrWjrWD< z;YoqTN3YjMp#5PkFs^zEX!ZzxpUGtdo`E{uftCZLlG}IW&x8l>PUxa&gSXJ5+YHt2 zjf{}Tca|k0Rsvk83V4P1HK1*UC0rN#-bvj}7HdvvfNc87TV4ZoNU+OEq&9gCagy(U zKT#rtM%If5{xUxi?Ln@I_?<6E=XV%k_t-j8;i+Sr!+KOxmDv*)Z;is$C!0I#-W4c~ z%DL!uuMb=^?Qz$qevJ~j?lMk43WPv>m8+JH2vq9t^7N}*hj*=RTpRQ}P{Cf59DkJ* zd@0u#cu4YqPWr+4^Oy>-k#HpC|8O2e3-RwQFg`^#J1uBs6fOBFY&qm^?!CC9mr8b7kkbY>cp=cKbb0<~{ zRZa~ks}=vDc1t1nZHSXrU898S(kx#*v_&ChCMCpxzZSXky~S0MvcY)0AIhRt(@~nk z7I7QKsSfuwe^2EY52q|61$BIXP|4n$mANV-M9Mryj+UbccmJ4i`~b^I@DuH1p43Cd zbm$|Q_v%10GMU!zkpSY$b!=ZI#i2B=DfG-oQBbxFaLu6og$ll0m3o{tjKqQ%Bk$7k zg4vhh&%s?AD81`oX0Nakt{k@j;lr<%UOq2vGP1i-?}*1nUkI#Zt#$%_og*otU-*HDit7f$<^m!u%-%{?yavIDrT zee`ksStLmM1dqpl{EZ6aeIMoDCW6&c-;U~!IPl*74jsFeCE%@z?ehvQA^w)_)VHLL z&^V_0sn6U9kWAa;)pUB;iG0`Xt($|qlZD8CeqBVAD#l-nDP~ci^!0kzurrWn_Twl3 zzYCa5*jEZ}q{H(kCXuJbaUh^a+9ZSJ>Q88U^6^$Q;q3P7u<#;%$Xw4KsP?)C3~Y|4QpnEkKInbWhV`eUW$+fAVb52x%}4$%CXqSw-)p%FNQ*h+Nr&Zu^4aZQ+TIL> zO8r|xCd+mhpYC#2yOJTqkSz$6R9B+7M41-m2m@f6X)3SG!Z<&aI4|&JpM$!L>V+`O zziCq|kMCCq`HoxRLk zY4eB`-{#~&3>K`-m~XyyssUNIOdP1fDS+X~^;}}3GFTk0sND?OM9;cEokj+Rz{U!m zq}pl;)aCh(&`+H+(cL`1Ho#*fG znnpjKrSlTW%|NCG{ks&*Hy~8Y+$g!Sj}AP2lulc(fX2Otb~V8l;h$@m9COPUdagaL zvM8erf0H{>eB>&j(^l!-wVg6Z;ZeMj(E1MG^G6Gl)hU#uX>sf4_zzg%ywff5l&wX? zAaQAE4a*z8bR=l`WCNLX52=$ihyYiR`?sB!I(QOxT~Lr%L9<2gdsHOxz<(&V=4&<` zP+#%8#v;%L!UrYERTWe)uSHU_xeY*I$4@A4aUJ@`69^mU-Xh|LNrtG`wZLt^b=!0q z7d&vjbrdfgf&&39oAW>_nBiJWQKb^YZfpc^oaJ3Os}>v*J^ld8)#{q9{v1H<&r{b7 z7Q10>OWG&pEXH*iZTgj>`vaM)mpdtp)j-;ySZA!T5Hub5C92b2gCN=`eJM?U!87&! zwo>ypDpoJ|WsrXfogdRLD4&x51!`zMx32GfWf1CF7X0G75d3ykh-=t6L7Q!7jmCR_!TZmI*Z3q_ zQIbIK#0Xn7SO{A?nbszQh3xksjq*>}9-erT=;uwSalh|5VZMUQKYNMy6{-T=fXc}S zq5w!Frg##tUys$pmpwLimQ?$+1lJ^O%gKV88#@K40bf@nEp7i+f!#56T-3DGOd` zz!TA8=RP_S&~Y&@`p@MXI;+VT^6uL(Y}V6-gy>-$$>7Q{Jh|6k&3wwhjJJe#h~pAT zC5O<~N!bG%tiKw(M*YkoB_7LT4r^L0tH9`mBYoCyu8`_6|BNd6KXAD^N#F3084Ocr zy>8>4gQc}l@0Sdick^ee6P5x)5$9eCc=IsBA3L?#2m*O1YFlK)y`m1R`4$dMSWhPC zVdC5ozb|m#7Qd9?eIG6v4y{Qktbo;pfCdI1elWOu`>ExAFw{(Kra#wxj*gG2&B%6X z-~(w4OKh`QsD?&}iIQ*T&x88pRv;vPUpas{qc) zZ$D8mTOz|sxz#As>T0Ag-VUOp__E`a{2r;$XxbZSZlP@%x1tauGawpwDYH_s1(~H& z_aUPVG@d4L$M7*D4lMUV-vz4) z3w@|@`y0NzrYU6fFFd&}#Q?^EXybP)C%m*Fh$|YeLKE_oAH~10!Z+Kc!V`XP^~)N);;Xp5R@pab5}I z0$#x%U?x(;18wo7f)Cc17vm{XF%X~u&VJ%|X?U06)Ss*4Ll7(B{ zrVfAFPV<)0u2b&vqRI)H+LpK~>}3jD8VSwVU;}CV`SxqtcL*Kh^&PKqs6h0Up*)Kl zJka2tH0*W08@|XtYI{~+0&Dg(32#4Xz=eUr;^Pm|aN`xlUyg5)uxjeY91~Z%MOyC_aVIkS*4$?dhh@cfe2WlLGb%su= zaJK5iYH?i!dd2!Ss%{yp zcma$)p7|u0dXGmu=*)c8yZ?@wyR&d3*9&0vo>RS=yr7t zEq5|05L0@0SD)4tG;4bPI1Uw{-obAdE;it_Xp%RfHl0n>-LAWGhRz&7&md*|cRSL4 zOt&_}jPdU%!<$;341Il}k`)?*SI`*qt3$faUbHcZpt zCd(!Hc+Wt%_R7eG?Y|~iC{{5iG`-{!{jcLMGKk==`uF&_ z$Bv*a)cGYk{R!y1wgKz0FdfZ7>GsUw9g!6?sI{OB|s{UBeE;tZ`-;cbZ7IMPw znGf^iukS*-+0&1y>*rvHb1KTW9y>S6*?d1^xjA`5b+b{g0AS_$EUiOn4J>mVEmqkn zC}6^c+Ta2q6gv5&X|rQo|M1AtbN4AB(=7czW6amCbIM)LlC^<~ipH<+M9w31P5!U8 zbh}8$`j`F(7fzVTNFi&9p@te)U~N_*27==+WvNUrQP}IH+SKRI;mMf}qVwEdkaCUc zd}hW9@Q8GE_r0J7t{&GShaZ2C;WYbJENdN9Ij0c)d^wMl)OJ|Z`skon{(`7Pf*m}; z;XL{wMGLzlwSUiWb^=fLu5)s>I2a|cbe|hDh00;$71uv0@KwhD>75Eoh|(gauj^|< zmpWw~+18!G$kKPUDd94(^M52Eb@zj6&BMmAR0aq%`=vSU$^vxVOReO_Tj+OKaX0lc z#+R*bk|8ef25&hp&CX+z8s{_sKe!{SG>j*oykIhnLC0}pDu35a#~R?r_gx4!yZTo`F9 zqM=y&gI>2+&(2|eSv}{l*_}uIutBGI1#8&Dh1}uw7q1VIk(&d(XR0BP>X~n8KDq#3 zKilgl@(Kf6u+rnHYiWpV|Jf-sS-vcVokA9ptRKY%W^|{S< zAUyV#IG66%ff6f-UYs`;ha9FA@>g$2K{*qL;@LelC=&d1@8!fgy!*ZvZ@amKigI2n zbKN6`{Yn$Ghxw1r_`Pu!u`YlPXU-2>%+=_J^)2;P;~L1L((1U(mk+gc#C{?N>WP+=hV7vkzlki0UkPNo|LNq!`YslQSoq2bP+q_Qcz z9ef>jY$gYnI@-RFp!IeI&6#}ock2kEJ^MLc&GXhIvffH&y|AYRsNT%)a#b8GJ73JMVN8bBXO?nD z(K*n&Yarj8&E8wO@jACW=rEtwj`Oc6=?%t(Oy)e$4-beH)Lewbwgq*B`Ef5srUhREWeCEf zm|=c3h5lJtoo2hPqQD(5z2HM``0wkBCqHs5VC#Hva0fv-#6PWDI!l}jp09i&yL4?~ z)XZ>`_gD(t11@6{93?P{lOI&jS_kphuOn0(UO}VQ{cO6omVjt4j?u5kLWjpZvy`hS z94`M0vzv{EtQ&;y*Bk_(hu6pV$;f+{iLqNU?Y<2babm(96?9URIEM>h;pkslg+Gl3}!#T_{>L0I$Vatki?gEwOIw!AWGAnQPLvy1>= zNp&|kLNT@)i3d;Jzr&&cZFaape2Ek2;GMlOE29#$TH({A;4(p|7gI_?^a41iPy|x! zrC=Tij%M-&5x^V6J5mx6f&Wo-9{yOqZ5X#RvbQp_C3_^}I>{!RGLn_uFCt`%GEzbm zQdVRoR7Up7-m8J^UC7?={r(5f$Mf8->psT!prK>@Ff9HB;`?c0rKYw}1a%7j?&n#= z&Ke=EYB_+acAl9xq&lLL-eLD46Qat8|U8zCf>_e z55%#(GCmfWe=QBDqH+9Rx3C1rB+NV;1uY0H7;V>mECGrSbQU*S)=|ib+(63Q0$P4q zM*n9^6R1;Hb}TM%g9F_}EL%t~>bXIA9ATOR*m7snszV`sxDbx7%Sa8?W(3v|LuH6; zc#2?-%M?m}a{Y3>hwU+NHHlsC-$SX!UvWR|YC*ti3a+_d1yXupt@TGx32yZmOov3T zp!4`mzIOjjqNTGxO&I^WmA_P0c?jswM%xgx$m_{!XaE?CuikZ%bb|U2 z?#u3MeNei+-FA+W62cPS;j=su1H#%k4ys6N`255i!x-Lv)r;H{21(!4lJ6v zfLrppUO%x#WOY3r1_m5sAFkOM+tBzK_&nWcZ@O&;^JVCEd zIQ2SxjUb5M{wfXK9BMihXUOqYhSPz97gAb}0r_UV=>v7<4_j57Wn|j;NJ{BzH(F4P4SVkX8IcsYm&O*W zLgRA(6sPHBaNc3rBEV}#BvkSQlC?^ZMzH?yY&`>LichPYW2{Dx+0KdV5&x~#AJ%4V zvuy*pR|4r*9(;u+=`poiHCUecYfQMLoDKX*`E&1zMmMsz(6E)a!t%@{7FY>08Dz9| z;#60SAhx^ajxc2idDj!^#BGiDN7(e!qa*e1aZo!A(e&HC^0(sS@j*dW1e%_s9B8u~847Bt!9_tkL7o zYA|fuGPFY>1;Kwu-M*8&MX}e8jG|o|k+;(>`Dk`ClzAAZT$M`)r@68;Mhgcw{T%Sk(IoZ1ucX#Citct_=ONHJfYjE+_ZyRGTHxEjebN{kZDweSy{tZKj|Vw%B@e^dl)=ie=L~V?bx7we zDA^1uLJDLZ9?sW;fkiI0@AEMO@NA7ahK$U>(fNR&xPd|xRgqK0Zc+_9Z6BQPpA*Hn z>|LW_R-ci@yPkgiwr23DsQtR;jss6-{U%RL=|Qt|-ARfd6>2BAlk;ObQD^&aJ2h`C zZ$xTTJ!?9P{JxUG%ROb_ZkH8$buk?H)8p?&jQW9*f}1U?X$CrJ+;H@6cZV4FRUy~u zEbJcl$yYA242>$pE@*}c_(=^eu zwmj_Mlz1^ybs%xLBd6|IS$IO%t$^j>#gung)e^@;a=+Dp>F0`2(}}*nadU zp2jGPX7D~K5caj$MDx4j6*_BJZ(F|CTk%#EHQRWKN zD)x+;@KJ3o^;s2K#}j@y#fj?}c&Q5YCSrourneDJx1*XP#=+5`VlZcC!m45y9a&iM z{eWO%WqxJ~>!aeK^D)Czutt!4*}kO_9zWnYj+pa?7(HnfYBd2UNaMfUK=2uy=l)fS zVlhRDu#m+D?=Ix^kZV*f=opP_k&+x4ih)NHJ=IupC=7c}(^|#;hxGtkiO4+PLP%== z{Zve!Sr74UGuoR$aajNV|!uHV<0gvk_$K9 zPMO`=?M4RpiW|ZvB2bU#$Qp3_G8|Mflh8VPf-Fbwml-BqSQ7bORR78cwEDRj%iH~d z`HPbY^?WNbG=76GAXfn@1fpG&w~gUqdddPNsU)oOk;H$WKMNUS-5iwjS`gN}f%DKS z4fzvki15&!gVpgzTN_98knQ@LuDqika75CHt^K#qvF)Xm|7I>g%9GxyP16gITRG_D zlTeRtCv)ifmF$5A+qqHPb9X_##q6o`C>1Q6|COmnPYDls-?7Bt?14APgO1O6Nbs#Q zBEt6DxZMgBoGvs26J0<}ViynOcdXPu$G8T(gOx3J1}NZ#zV6-r`{J-nP=@^zy2<~Foya!IpY>S-GiN8dfrpZhaezM^W=+*J-j=&hTHV$Ar$*;kR7#r zMxpnv-YPzG2`*HoOzIK+gpabf6+D9GAt~uFukX`kuqT=vxD`hP0lx+=Q!PFP%ddak z?xI8Zx0vL;nBD;7OqwB{;cme6^x@7!Z-00mM?Uec)e7A3a7AKpQenh{&*DiQACz70 zyCXq*g1-G9Qh0F>5wAZ!m}Ol-&ur(zb1#@dt(eX7_UkSXcOWplorxfgzBqL_8y_x< zA9e5fOM~N+TN0rd@AuOF#GR08YK*TOx#;nN5j;|Nd2TVJ!GE#%c{Z3ojn&_cxUl!V z#=q9Z4-NN`0Qu^IYYxWu^Y(a59{&pN+w)L(>+T};)ZJXUAph9z)08BL0^4>Hw1MJ!nZ;*9L`s-ZS1u8c@5mwR<-y73t~z zb6K7Yg1e=BSqhfZh(Jf1Z(~Cedhj~P!!bSddzb_JOY=-LlXfx7ALGMJO<6Cqh_yoe zzy;E2jB_ma&rqnf9ou_$sC*M}IE|i@s@mzPeFrD``K<`dC%=?G|8;U~6iIOCWVlro zpu1GobN|I)dH< z6vu@Fvh4ncQ7;iEy>G`#Ew*!W-1?JmWd~&>zh$DEIYzH(*HR-X_25aFqIy%_Gazh# zV&7iM0ODMX%fAcDAlmTx(#JiF`|apb`oL)($!ti3#zra?T!D~h{J*)H;>U)r8OD|@*em6K8vtDaIaMPpqGGSMSYU{)(V91@xm(S z4iV3no;Vpx0$@-w%F|PBMY(Jucj(%j;UuNfnL@!7xQe3;hSXMS?NYZoFuPw z_D~U)lofUl25lgn(!coPoxjL`$tNyBRte1fm6V5zWWeBo6=NR8L48`_Fz9N^2*+p0 zWCC)1A-QFzyD)hNSw7(U60jH#jAn^nxrDx>n1qBMU0$VND609wZ95YkeQsB1?#cvp zz4Eh1q8X5uw_B%k_9b}fjquA5=m3*IFU6|c4A9?aC3Xyz13i*}O z%VKL+2>5xS__y=;pDwI-@R?3UC`1hMrej+s>Zzgkb(qXjgBZk!gvHyD79;zS%zm!- zX23AJexGFMCTu)^^D&f~3vvw9=`x>T9HV_Dr7c@=(Bn|(#vP&t&th}4qo4#BmEjhP zJo*5PN_YM+d_My-IHh&*nfUP7*8?hKQ? zSkwfDiNWRJPHvDn$`B+jBLSkHF}lV4*j_G`|AE?TC5%_!oG`=Z2WPdsv$s!vqS9a9 z*Q}!mp~vg;`XqfDC>>R8yWG-%tg8&GgGpnkxn8unCm;{w7Rwe~WAz6vij5Kuvg<(n zTf5Ia@NccRQH=NDrJv~i6K?#K_AT^qSq4sIynv)8ZSq=mC(v3ajq52Kpg^rn@sH7U zU=S#_%E1<;cc=9o+Uw2eS=Kc3)-zD@H=2KjDSQVMfJ|^F}7*X%pv%HyXmP zo{#gNdrINK+gs?W_dXJC>7_Qpd~sDDqic=N#ewy+b#5`oJh~~HKGVd)58dxa?74{S zp&>Z>KE*F}=;h~L&APgQHr7HOQ0HZ#Cr@T>O&ZmrYY9Jir|Q&z$SUS>|8HZcQynmU zzCsSB>orzoHVR-j!D|N|1D>G8o^eiq1Ro6Ue3hNs<%YiVE>GI! z3LxTp#Qg&243H!+W#s(r2Kn^@p`x+UK;FlmWK$Le_AdtKBh~^Sq%tx`Oi>h^LQ^m2 zSYrRba;bh9D#bv47^x9+Tp*my^tvQ`*bN+8Q-7(8cA=)?ioI0&3~E-a_4Nfn-s%8o9ynXGAG_x(u1@a+_Mu}P|1M$>~% ztHTlq%X1N(>QUkxD;MNDB(oHdQGuG3Tr~;fLnx`fXD|0x35q->s?CT;L0V_{ej>RD zrYHET-&RY38->NU7#=EsF5TwuYQkb9X(>IEkM*j&gpG`6P5)x~8oL3uB|-R4wMhL_ zttj-()kWLXF~Nbpgr2U(6kIJ?2+u1SMpbfulbG_!Kxj2Bwg;yTDBdd7@m}zSXDnS= zvE%GOd#l#fqMH0q=d-D#0~HSU9*uu-P+?Yzcar zV>1B;*vqz*>L#FdP|SCj^BBgWom1J#HW6H_dj4e%2izS|OFWS+9HuI`5o5dP7qvRC zCSiM_;*I<$?V31(jj!zLv$b< zCIzpq^OUwjDf%0FZoHD$0PC~=Cvq0!#BJX(w|tXo2bm8wUcA4;UuVtIS@iVQWw`NP zxkkZz9NSKEIqB~CgP!hb7VCJ|qZYFh-|aI*&>(#jJ$3K_-kvoc^who&6mCENkSp|~ z{i+WG`Hinp?=mq3Pd*;3*pbjSrBK4#Y@U;Q%m~{*uyk3*xSZsZtQG_$t;lOyTWRs> zS6ChH9jsKl0%cQ;_wGH)h8Lby;f@xW$lQc~=L1hT+;sisS|Vu;PDF40m1xUgpOip; z1{Kx$7P0dukgPPFfyF!`eDw>rL6U(?<^p>)%Aa%~ z)T*Y3)-k^Jca0H%`%T$oeBe8h7pEuoV56KI~Oe6 znhwL3uYz=6jYkXCOYAD|KAm5;g2zksCB@R7&>+hBuSA&|5K9dy`SL7MGe z2fP10m7I~*%B3#8YTK$1Znc z<||UrI$9D8$NV7ycPWeC1u{_P*~C-mp9w5$ByFKl0uXAaN#a092yNDp*C^TKfG&W{ z&X4vNaw!=bRbI`7@l1}=l|@@HmNp3S=)pKpZ9l$_c$}gSDW#w5M3rGhtd|U7K3=uQ z(}&yBjc9#i^j(LrCdiKnM7(1nf|Y{A*~$_lSdGo6(+XsnszW{Q_`&qtYF@Tj2zXT5rAX`7L4Q4O53`*G(0l4HybKhD zYKF*%c397~#oaHx)NT+}lrgLqvNa$@&auN~jxQ)3x$#u(|6Gn$W>mnBku2 zCKdd<8~&F#;ta5~CV`22FN9dP|t}l*s zD&QQYEJujoDn9Z_-Q}p#X3@n!GLvV(j- zogalhBTSYrG978EgLqDcJUjU>^ujmu_T23((D3;oKwu;X-!7A>UY^MX+S!Memt?RU zq!itK_WVE)xW3&#wKa!&yWjN*417Valip-pI}L#|U80s2^A@ zQG?FM${a%pZpaFM64zx7hE3w`!s0Au5PL^^GJE|Se7qzXrZIgUx+-pI z6Ti9vN9I+ex3T=0-)5eh#WzK0JXN1AVq(H}n%<02alJ+vOXi>WB!>}ad^O!fVH=FT zh`QciSB%2yI)4d;i-OIHA`_#Q2XN|Xzh%^Rf?Nu1@}i|*2oi?(2y<_M=gi`bGyR27 zGHFW}8A=716t{T`Pa1TbA~%2VJp;~rmBR@Nl(753!mgpo0xULL*_1Sypw!=M06u1d zyhTA!==T~V>$iK8h?NFtWL}*lvTdNgg^W}2z;i%evTClvg6YSiJ8Mx3hFC9$PIX?& z8B*Kt>Xhx{fX05ty|OPFP$>udy(-0UtRJ>oEBqaXn}+<}Xa7Q~fnVdt=#P-Lld`|W zcS$gO-dasqVFZ!Ri3GS>osg-BYu1}B3BLbI))W1;fS;jq*fQ-V_%%MZ#48E}|Lbhu zp6D$jmdAB;udzIE5W^k01sWl6jaJwy=zIykO!GqmbZ@}>#I`Fx&gMY8!Knkihd2Bv zdA+Rjoeqj_BC~q9Tybfmj8CwUa;v20-hD`Dn4EarIS(x1?@}s>7Le$*S5f>} z{>n*>O9*PQsa%m`?2CxNi6XD~z0L}IC zfYqURC_Hyxvx7elE);Z7{nu)OTB#&n9Ekg?dmP20#QV&mer}ynx>OX1HjpEQAgC17QWv&I)NKKol03klgCRN>pk zu%g}$>|BrI`O~+MhAVweL;nKQNt6CqJFf!&5yTvNS?&NetL$&2$PGLv-$%;yW5NIH zkV0xoA0oc^v*aX!6}%M(gDuliP)F$KiF#xoJiZ{LOvL2}8*d(&y_vAU{DmByevG?& zXRO0YIQs))o%amm?AC|X?2w_AbS&3)`@r_p0o(EM*-h{KMgU<;pD10&HW8lLN%n;Z zBlw~wA+hH`2yR<%NA1o#z+cx6iBNxxXQe=ed;7f;sCH^@3EOR=k5hxqmNU43pYIbf zbv6~Oq$0BCIfqkBEMq0 zWF{_d%oay*nUC|9L>vwr{_yr3tO$eK&FqH0HOEMc8b@Xu%Zqqv9}k?`yh0TWEj`DT zWzaPAB+UooiL7mukh}LpfkAwE=SDz0#*t4BRnx`+1^SFtxvS0K8xyiN%vXqTinmM1 z_yPXlc3I9`)PQp~uU@YhVN>^K1j%v(7eUWjrPED<4FZTnHkj}IK?=uK4Mgv-zTd+| zQR!cDV3}s9>|yi`Z1UaT_TX$Ixz*so!1^lm)n2#2>>dU5)&x5(vG*Ys&Oq<$)F+@n zQDrbnTumtaOTs&$ zth2BwqNOi&J04UUu2_DVD@W?XO&iQp_F(4W{b%}%Exex=x7F?Eh1<^!6n#!cV9(0w znuLBCvhbIr@vTooH%eT$zc1=x9QTl*1ojUQ=4(_Xb*c&6rxGrVQf8p}^pg8-$yIPU zJENaFF#{!jbB;;9bU@T;d(oa|16dZ32^ZWrLY2`3r2qY;!FsNY4)nv7V9Raff4b}q zXG<1sD__O|OK*SNv*`aoJiA{gY_1tSVwt)1BAB&q-m2uc?He{2UoU?2gO(J&6c6L; zcpJju0+NiM*+af#Hydx)UxvZSocsqD&SJZgl*T4&5g;EktkNl{2cK3aBrRxGQJ`E& zRo==WTJ$sGhj4AtE2AA9^%p#^7BZhLSE zeH^{NCDIiN2BDg%gvU4GIpyn#zWOetnGxQ56Vpwfzd0_8BzK4K1MA}Yn0=t&vmMZU z?g4eIj-j+AKG6Sfz&~G;0|e%|9}&;Z0B6GwqmE8&S23f$Iix)YK0Y&=`94AmnL@WU zGs-6rk9HHe+?+CqXYe`xlH5Y65$O|QjVy4ub;4cB{|SVv5{=D=2*67%riJo~FN|K8 z9p%kxLf?NmIJb7ofv0JFDbD^s^lsfVz=Z88T#{5jWzbo|_GBmuwV17;_^I*H=eKy6 zZi;)p?dBa&y8Wo$dr%Q%`QN9j28YA;#5IRSsa=$wOGh?^e-F}X)o<4_u!Bfc$8F}G zF!-6LR6tD9j>LLCCkR+oBTJdixUa$MFecVP-6D4t?w3@Vic|eTT7^w!PR}gh#<`=b zNd$VZ^*rFGQ}900vUD9;lHEqzBc2-`y$`{9%QENw+Yg9V4QE^}Jp|mM7g8>ts{#!# zc}o)P`LXpC=qnf%hF2t&LM#*G(9KxEH%>~SXj3cX`1I{0T6K#zbXTB*f@cj@EFO$l z-ucC0CdPp-CSj>%x#8U)gGBREl2l1Pq__*vDs(k^0iH z{gDF&@WzPA84yLmd%M@D|KTb}yD#;=xeT5Jz&4IdEOSGCo1W3>{QidaT$zp!lrd6{>bW zxcKPX7TY=%#?k3jbsGo)%_;q8!mbSyn4e6zJP*lSCfqSe&D1}p3 zaYFAVu=yJb{rXL;c;i3TF5=ccB-CDjTY55$<|I0o9&&j?bd>w#QpH91?AP8Fkdud| z_ntIc;UqybBNB3;PXLWz*0J7U zI%aWP^XA%-WA+^_?YMZD({c_7a*XdmEpQh%{|v_UF2*tQ zZ#0F2_(i9?%JSfN`N|4W|9R}O4dLxxc>O%Zbq|sZ*Q4{x2oYDb_ zPk5o}HnG6@#i^a5HVZmgmo~qg4kElRy56xlMM#QIZk&9viioaSKiQy^ge?z3xBDh# zaP9ZUci)9&0Jn&Gvx<`hmWdj_6PrlG!z^CkI0lRlsnDqK<(n|LCMJDzAdrVFQc>-N zngO(uoF|)ruMV-rd-oa!g5jfI&&y95f6$-#kNUAc_tCI!1>ziIfPp5DHg1k@XlpK* z)O_j-iZ;R%u#G%GQ^#&giA3V?h||>?CqEQ)S*<2i+<4&4K?sop2`=oN*Oj>!?h2{9 zi?N&JHz2#E4Aa23cTG=?A60R26=Td-UvaAvuw&! zxR)`FhKHQ*a32u?1;LsJ6?GsatxzMp4vm73k2o2n7QC?IL;P|Qh`1h|JpbTL>k>B}& z()Tz5S5stRS@qK%iR~|F(0Wa7ryvWTEQvbb8xO+kg&8(=A3k`dXYXLt9|JwUeJsMs zq)_uMV*6Q^Bz&ACxYHym1uD-zaud_80QE(2)vh;_FsgMcRxso;Jl^$T_Td~s-WTh` zSujpZgkei%YY;7TMKAPpQ*uLu*HOXk$64r?Lt&q(Z~#m)8fdZMUx47(p8QPwSAglF z>z#Jr&v2M?AV0k;h3TH-kr6sLfTuBcWr6)EaBM_U41P~WceK{|bx&M~(hey)1IZwyV6NGz8KW`bBk#Q3xiw(mGD$*ua|A>x*~!@-rP z45@eqGhRj_(0Dn@Yx3+5;7cOgH;`>bPPo)9?N#Jh9$`%K!TmMlczKldWGond;@NsE z2(`iP&a)JX$C7aEA{7sN+dQBsuS-w3w~^#C21>uL>*$&M?YtzOLLf3;%KX%uTbrsU z%dfaIh^{dSj@0_}ArDzKJL?!;uraVSKgpU$9C4I&LXNCZGjoNQhZqM&JxY??Ds3PQ zhxX+U#<1_3X){!B2slTjjfEy{(9js^r(z~PyUvv);fwuh);T-`W zWT2iQQg{KrfoZ|ndA=Aw*y{FyoE$tXHDFY|#}5@zed#w1If3S`L)jI&%b-DQy0Cv- z4?7A1pQ?ku*KXgQAtvmVf^NjK~%&o z&{=Bu0V8D3zhivlC}ZD!dcD%wMT80Apvvn@YA{!?W9MpAJZg>XJA)*F*yAVZSE4HE+Ke z#q$T4KKWdVlq`ft#3RaqO8E6>#p6CSpZ4SNel7vL8|oZz!X-k@mUqvgNb4tzhIwF_b-ffjv{l8^O=0K;JAul^Wz zGbPE${xf}@L9W0b+kP9EzgU>J_EZzHTvr{dFyE~7x=s03mJswzebo;X?T75)U`E!l zMWBA?w0;`7fzFqLCEf>&16gj?vs8=mFU|K^Q{6{^bL?NUcJBqCt}P@yFq}pW$I2%z z@d%#$)y{M$^#cQrjTH-RJ9vI?yX&9&Aj}3HedNRV6Dxegu{UR%kk4z+p>vyL@VoWB zkGakj7}wzCvJz*4<2>Bg!olt6ujSe^Qy)L@!xeXG<=lqjvIM^C@jehBX1$m+g}r}% zdL+HN$OL3k&c0f8O=!DbHEJ=`6IAE5c1p4&fS*e=K;7mGEdTVsTUWpcx5r2v48*!n zp^=y@PY4dE$>dXwBs3#GmO{33hO!V^cX)KH_6b?K)OTGG%0PcFUOuV8_-Qo;`oD?C zZ-e;DOXNh3*Wd~6n@|m$JQ!Wlx&1`R1E|=7sbq1KVBdND#4nl}wCnMHPwMkPvT8?= zyv`=FN$HBqOKUL4Eqjvf751vI{CaPOYq_SLM z#{-q@dH*_YB2Z%@)7HeE7ZcK*sID`+5OU)k(^Wi0=%AN=bSFC$vPSUn7z2NzdO}qN zMXMj^GF_BfaPw2>X5UZ9{iX#WmyK?ea?k=H1{rBF>Vlj^!S@#0_V8J@!s#WwK8Tbk zcpARG3(C|H_vzZxq5ZOQ-0&|mpmQ4ebb)meRS;6<PC+;eN%qTXQkckoAF|+s3qMME z?mU041_Iv|8g>^CkP+Wac9AMGxI9du*7nQ?u6jRSFldj4-R^$UlQ2bSxt9L+sPF>l zhjaw%NA#kgPc^kl}@k_;bKBuJQkceI9x_ldm@#AHoYqBYo0ZJmK$I1L9PVR!{5J-LCeRm^34}|=*r5v zlS-YAhQAEHTI>6R9GK6tPCmQ@rXOxI7=SCxh466ZSJ1=CkWTUXm=tU_KX2suausw^ z>c*JCKGr0Yp5HkQ!ko*iG;I9_Rk)h0PXRg)a)h#D5WvG85c4O zG={eXC~*%F?=ZzXW%)xGXqVHDI&4QCOvmm#TdGhtP@fioi}}mZb48V|udtj`=;uBy zOg~(W+^*hu2gdJ%7PYm;&@y=`*VRo{2nz90IzHwFQVRtZz8{~V?kOoNZ_PExaw>G3 zOjm~CJe`^o_a~4SzRlQEGLByT=gH72^Z?ZU{$>_(OaRe+uLsFd*%0tld%M?E60Q{7 zNs6S@hSz}%&1R3EzYWP=eY_59 ziV@%5OJ;)2p-fO{SQh&6P_m=)yEe8Derjn_nTReuILtA-0-((_v5PS?*eC}tq zfS6yNevh?_0qP8Qr>AmEFz3&zKpZa)L35VT{L8I~hQxwuLY)F;(`$Mx&kmp>YWtrN z1c&ga<|6~Xm^%D>9B(&3e;sU-WTe^GsA0LUeL++M^SLYgT|6p!VCG(Om!jbiVwdkO z^4Y-j^Z91mXLTv)i?oH7_yP$`p4*zfs|#=;Xh^u+O9evkMwkM_v7JqunSs#wVYEV8 z9`P>l8>)LbE7!UC4dJW&USx<-hgC&?@@dy5)YHD8tUGuW7#(wnw0+pHbFN%@tB@O% zWM61Yuu6d`elP+)JKr4g)CAdplk%*$VY*Q%#;@xoG{o|AV#iOc)-uO_j2+0jZHR7R8qlz}mO} zj6+`unq@pHNjYx7y))u;7BlrAH1u4iL*f#MaMAzQk#!#=n*F@_wwICD@n8ZuyC$F) zx8h1R6=DD8`O!F5bEq3gYnI7}f_9s3-6?OFU`zconadbw+wtq;Jw{l3bb3CD zk`xk(6dX5yWxyJ?7g>7F5IE#<6KOI2T^=bRpI`S1VtTdA(CL|jY^WZrWjr>8bZah$ z9J(5`b-ptD=wt|ul;1a2RT@QpM=y*7*S>=1KU>1A%hTveMJQ{Xq6N&Zq`lGb#ev!l z*W&3>W?&b}%9zuohFgapXU(5Zpf+C7z;9knVEItSg|0pw#NG&N=SIz<1^Tf68tP0z zu=3`0{>AseD186z^7~?#DCjt~iyRR6gXKhB=M%cJb@<@H zV@Y(4_d>((?5+BvGYQ#&Q!E?&>)fKFVK37rwr0EXI+B z^}AX48C_dwERg-iHIrO)lJJXpbIJfT@3AyxgpZ<>2mIoB@>oyDQMmR-Mm-FhQ~dmD z(~CmI=65uXM1hst^rFaHZYbg6^%ho)13N+@(hsT9;OXIlSGa41?Wt8K^6C8nt?*TC zE;=RnEME3vX^0zyE*MEa8vFn@8nukF-2~8DQ&b;!w;FvSz3<@X76GcsU-Pd!ibMJR zGj?uF>=51Dsdk=Z60)aOISx)jp{;_h=3jm>T2hW_ZX$XE?_C|c&+oLNzCt2nhJs-v zuI-m|w95e%V!N@8R{Q8;;4(hL0Waj;rbxW=66>D_WhHYzn?vW@KM-=`uc8AJed(eE zKXAM&vAoe6izH$tTHI93;9O48zxc&z6m2&@H24zRK|K6Du!QA8_6Zn<*Ht1QyhBc9 zf({3O?q-PnD_M-QcI`?~20m1TTB~%#Z=!0tM4pIkH;BNGy1LzjonPB;xd(5agDA_L zACL99z)t&S$5N>#oJq-iZozB`#VUw8f+%C7-y!@mB!qiN(F zBw+FN_gyeCT{8^E3&VOD>lF`T_`vaBYvg8iGaPS5^?&c>hMJVz2SeC7X2+aCaO_u) z*lklU**vC%YpwUEYwhE)eH}rk)AemsnnQ|bGQ$Hx?v+FWO>VIGfxjU>#sUk30j7s`v`^uMKF3}Ih0pE`GJA)I%AylLAv5VE2Y8RCBlQze3wEv|YX*KsHs zkrn}hkL%uu@-{*gn?1Ym$8vBic$5GAj5g-$D^-1xZ$NK8v4~ojHzS_abK*(^Q7}h! zdoyt5E$SXo?0Ejz8S@(sKHSf4L`4mXXRCrKpq*-VUlP+l&4is51xXd5v&yV8;42dt zf3K`>Fw=m$NzS)cz9<5{cbYP_0VAl8}G7ZMP_)!YH1r%kbgy;{fm{+tOEICSdjPnN<+9<++85Q2rj zm?+EZUNq4DDUbvg2l$T#7gmmT(Of~ehL|fqNY_0%cX(e37=1ia4u9DIu4P+|=UrUz z2~_nr$|Hc>@_NpyRA-=Znlt+@O9FLlT-jXImms(^^}jb*zI7`9SHchx7ciasxl^Is z2m~TXP%g+9h-`x5t)se8N!3v{`!sexX;vj;6U2P4WP3e3HSBxvxTDQ!J`4p%X+DA2 zJ?_dAn_K4l3J|t3o<>}J1L7G4cAE$Vz~TCv_A#eQSo?*dmN(A9hNK>@;=n6Jg_b_Q zaFqwI$GS$>@oM42asQhWdO=8h8yOt(8y~iq6ZNG2;=o5GGqcI|MP!ICTw$$s0|w7c z8dOaRff6tAnP-i{@OvWRs3rFl(X$Xd(tU&nT;};})e`xDb4_LYhC?$rM5QcUUoJ&w znEIF6(B?A-4r_ z`c2Yv8GF;PtP+7{K=Ghg-G=6wuaL zas6j2Gt_dnX~ZD;Ib}BjhLyS4p2gUW&o?+ERI@mCq!=AKLDaO-pAGc>8ht z$le&3d2tT2cDS%SYsB=6mufI*CUa&3{}$BK3>P1KN&vAjF5WdK%x5D%x$r`d2AJi| z#V&c71HBa#rrZ<rbI4zbiNb+XX5e ze@4b?IS8%t^cS>EeW5PyQl98195`B0#(8#{4Po_L`_`XT;I{I{N5jM&U@htn4U_+e zJRP5BZd1tv?MH5x+8J@^P&G(w&Ob#oM((^XiFQG{JGLjLiWm}UlB(Eq5KJj7Ej&xV z2J=dvPJL!gFc^u=)x=3dc(Lyy8@#KG@zE3rQUZ%n`&mwcHbGhFkZ1J!Ww?V*QnKgn zU0Xn3@JF_u_?y5ke!Ty6saueox@S+YWC_=}JMooIRe_x()8$U?3|dI4d3IeQ2(li% zWL*5jesh+Z|!%7oetnDO6Ri}Wi2yWjSx^=o#xNPR`1=TsLY z@c;G)MBRjr^`l3AA4ZU|wwht7$tw_Qz@<>@kpbj&ODOtcBN}D1QeJaeL1|S@)sMqI zqHl>0li9+>!H7BHym$EllDx&9LXznQTU=@{PVcrrS<7?Ma@=@0sK)Cv!^1ByC3)8L?>@GsBP-43| ze)-=yI7gIKo8;gF@vg2Pc!k!Hi|oq*d{zxGzOSO>+!O}A*^lx43D3Yib7?m7sBrk2 zReW9H7D?Uf3NM|Z_vvu;ZadDm0gPAdMet+bvjzlH^r!iqXM;)y9cim#Jm^N-t#ka- zh%GFe3sbPr&LFF3Z{%NC`u8n{i=GHPFPw>CXYNIWo~-ddFYCd6no!w*J~wdu8}HiX zB!xRkpH$Lu2!Urlw37YO0t%Ox-yVu3g+JGcDDOWlg)p4g!XppV!SaA`?s|g{$QrE; z<9`^zcnHzd@`YjW-)c_!vQZt{i+FuTK(+~;wLSlaQ(_1O^lKJ*H9i8x;J?gFn9ue6 z{P@#kncslpxTgKvQ3nd%DC2hu-3J=6)uX$U7-x(D*`5}>0j&lpqJUeuKtAaHBdmi2 zDsCM}Z1b$6w(Fl{T=#E+l%`l1O|Zt5xb+ zh~l4?)RJidg6=cduH)W=zR|EVhP<-C_xDWD z=sz6Dy)tsvV9pZ8s^aUMj@_Z_wfDbqEa$?|6!5-jQw@m!vsE2(2!N*rhtUzA~gz5bYD}Cb)@os-IGb$*-DE-4cHA4%U zS$Jv#IX{uDJiq-=0yDH-_o4OsZ3vs`2Uin^;=uR*yK{%5|EuUc9D#hhFl=T-+4Co> zj3|5a9FkQjJCclS5y^;1qU;euMr0=;d+)N7y|Z_A2=Tq&-(bAYIp@Bw3%ef#iyBDO z_aY~slye4HZc4d6=ZD;eEl31)qr7{P;Q2BBhs|IToY73sIe4*ytZh_#Fb60wYpoK< z&k|tor(8bz*r#Ai9AJ0rHy<2Ra%3~V7=*-IEz+Ga9H28_9-O$Z2`rqZ+Bz;H=;MB5 z$tx`iNT%A$U>9sfR4yJWPoqi^XUDLuwPq8Nv9I`6AZ87gP2bb!RWu=@qBz{<>Q_X8 zpMCC^R0|T_qNi>VSw+Ey4Z|VjxWGmKt!hVE6zX@b9_Y^dL%>Q@g3itlbhaRmiDUmC zQfFsjQZ3s=m+3y0!B#E`CT$9dsmMaIi|0Nr1u%lzx_D;&`%6%AXZFeV+B9-mruYQ@ ze_>{bme6{X9DYtc%G5|aKuQH?dCz@jg5Idj(6waD2P(lB%VK+sI2BX*tm5UNIYi>a zdlG+WDYVlvSd2m{vQ{oQujzozii2uUyaMgJj6M@yeF%5eK91G3-2(gB|7>br9U(kF z8^Lh8PmudKKS`tY4qUns{zaq)U!GBbf&bfYPw4X7^yC`&1J6_?-se#P5Is4dbh$W+ z0;YeLP3?7~tke6i$F{#fG~-N1hRGx>c+0t{y2(IvKTYY&d{eMe{ZhnsYX-63+Nv<) z%S6{3g7%IXI$^Q8reu^5>pw8<>SbcSDQ@xUrcWjcFx_8x&tUKYFdStcas2y)gl;4a zjiul~9-lzC->d8J3x7X)>wy)ho~tS)ur~yYkP|Hnj92^UG=7TQNEDL99}$v@tHG4q z9E$qo34Z4tS17TQ>3L z0X!P`HrKgzitepa2op$NglP5&ld;KFWGEdHm1~UoOI}t66D_tO`Hs=SvyY^JS`SAT zK?*whZfvkm1aMMVoxt^d4!H&A)d%+4!48Gw(^)?o@ENyNPT;qND{fQdg6|U0ofoX* z6$d6T;2@fGBMacprI_3$PeDkdq;I6){SU|-fAhw?wgGEmD(T=G=U|aES%sLr86{A; zzwI-_d@tl9{W%$YAe@$;Cto-Q9xtgm@b|J|yIjJI?WH0Rxd`fM$lV7YYw?i&JMYo! zBX!c{i(AmV_+(H6wo&cXGCBPkEax$!`|gQeMrbq;d{M^_GyRE_1IIJ_oUs1cpW%-N zi_*~dF>lG-!W6C+kI1(QXuw#p6CcHUQz(}&!ZD@A=DOfvrxjH}SPgRiYHt1)(X~n`mgE}w`1broUwwCc%SYI+ZzrWR|a8C(W;_aj@pIX7^nyDfbCV;*GBcM1jXrov~6 zv&^`dcf)Qd!g&2a6Vk2!ORd1>n2TCm8DriD=v8N_vEp$;c&|Jsv}Q+DqQ6GEP4E{bFefePAh_J(Z%;618LFCK6WQan_X?w?bF%LyBVLsKe1XSKL} zajpndBB!_RZ*IWJ-s^(tG&T@wCRby_RmMCoxJm&jy3l;nw1FpG56I%xSbG$CyNYH=TOAGh6xS_HK_5R zNY*&z0@~u@y}BBV(U7fh15p`mHPt^y z=xE&VldhKqoUA>rm!Oe@En06`qK6Bpy0ywBXhs9#+}#RG6HicQTlz}5s2Us#AO7s| z#d@kkdP89!7P0+AMPdROH>~n!q)S*~IRSl{E@DlLOMPsA`|^1_xIHrOmKtsd`ndfz zREo>69R&3+F0etga?j(|Pn*_%&o>e7KDB86f7lgL6&7<^Q%(lj8Ym z?4N9z_yaPQaZ`5(rD07kia(>z9_C|s!rA@51KQsYO#hYx(%#qKsvNmN0LQ1;-*JaX zxc_yNhNLhU{5kAsm*_#q`N=ybG-6Q7IQ#eAwLi!?^YWc*ywN}|&$!tOt;p@a>NAqE z{U|@#xa3Ug7-F8)Q*v?rfEHwC8S*1iVDFG+xc1Qke8w3!mDj@fm)~xj8cRB2UMp!; zQOi~ka$mGDHo1=FAC3=x>=}b+eRf>^vjVtBz`rSpdCC2@6YsOyyn>XBg#@~+ztCxs z5yGiw2qAI|1D}KFLFVHl(lY;R*q)nmYPD<_#jmo}{29^(M{XY7$XDwae<-eowWSde zIx#=8>AnO{D>(;dodERMx5a7pRe(JY@w;GiarTgB%~Ee1eC-~fm-%J{wFM4lP5l>O zlB)Ol)gRd0kM0|LbeMy3dRKD+<^jrl^7y@;2^rkDp+Bd2WgorL2;KIRZH8E84xbjA zUF@9_!@6iZi{__QZ{K?80btj8~rcbs4 zw;AAC*XFly2+);KImnp;FHc5fYE6GL@qZ~AXYj!<)X}mV-jO&wySMm z!TI2$`rr}r_3`-0Pf7%zh&OGuc(>6xywN2Cb2?zxI?3rvqy<+4;-yPvU646w5--d( z0+j4B-DC2efMZM8Sb9nUv~zBcV-HyQ%PHVsLkixS$bF2iMbX`?h4U!7!sxutoMZ+7w;p{V-1jRUh#zr_o@&5pVGT?Dba1kQ~ui+&`nF)~(+`8+DUy##S@v4C&G_dDb^aj-+Fp1gZ@ z2FtboN_cIe0eD>!gGnWAXw7gq8UJ(`_(*==h$y`Yw)+gP-B$%cJk7V-FC<{w{Ivwl05^DXJ|KzIyq)g&62JpQ=lAjKD;j zReEf{0-R9NpKYW00+CsVOfooF4@={+Pl*Ia^k(}Z3`N==g;%CwMaZ5S4 zXz_&pEbDK~Q*l9O4dbWzv~;NPn_LFxaJy+&EFbpq9|7?o);D%gkm8j+NdTih{*-gV zETGsK?znf>2gZVXNaUY%fM%u(2}i2Lr=?C9_0NAjSPsFigk@D9-5b~$`Siut*>#lj(94A#dp{J&dM0G{EIYw{BXsJQxk zK|28l9)4l0DR|8RgpZ?i&taZ7GXJszp42no)bNOP`Nslc8etxNi2ns7{=O|Ha})*# zcCA6V<`s1PM`q9MR7nU?BTu&8!202f*bC+EL+F>e653Ct0`81v@*|OSkn^#qUhncN zkUSVICB1$b>WT=H4~f3Q1&a{~AYue^PgVu}rd3e;Yw<`dhzU}*0wZ;^D^ZF`uop}H zbs%}3d^ONd3Hn;k;88>|VSQpsO4dtEkkPEvV<~$U@Kd$Uc96QjXPO455mq;h_enbU zhe->@dz@r~V-8UP|8J&iegsfy`hEQFbHMtmG|lIZFF^Gf&)w+5GBA=98{KVjgzs@j zC24qtV7oqj`YbdYdg;kqM%`|M@oU}sva6UseG;GOOHc!rJD{4JI>7RIHLXfKMK?g6 zr{RN1Cm95-_JqnZ4WsFsZ|?qjs|zh_EVRv|GB6N+p69tx2Rc$*_!D|*A4JLp7v@eM zz|Ym`Jwl-i&~?Av7|EK#z@L&8va=fSRKH2t=S3up-ybBWdbE#Psb1Icw{k+rtNKu# zA!pEi)<|@jyc#YXe*SpzL=ql7>h1EgpM)3WX;jL*#-L=qkR+p!1Nh%OoKaM7?OU>6 zm#kt4;c2J;>_UAvh_+u(aiWTa;S@gB^^3V6wZ$AkcCQqPMF~}oOr#<2uFUiF>ewC4 zPm?_ynytorRNlbtI?c3U1jw2eMlePZ1#*=M>ek_6ps1vU{C3Lo=w&W zddM}T>v))sdKgBO60KArdAHm5#<)9lSsX8tJSavA%}e*UmLkDVr9&v|>@s{>dya?u z0}r-cqVwi{4ghNa4$j@S|DdMG)S*H3r1rabUtj9t0h&vl7)ev|f*6g$*3QSj(aE!o zC=%U2NORY|E8_l5GSI63wnVS(2*S!&y0>m^q3t`8Z=#PKAgfS{tu62h z2(Iq`HVi*P6OE+?FB2X?MT2}YJLwRRh*+DQO+Q9XcMqde1BGB_>749rM=9KJCRO?7 zj^#Xkn0b4}qQ?soS})kkkRkM`5t4mtc?i<;T_X2l_mSon*{#VWA@Hu2 z{X3~n3RFg~>;jvYk)sMB*J&&jlvp{f#0ytI8e@fK->(RGBPl`_8hR6?>EBiplw$sf zZmEAI-!(w;LAhH%-4pP*U3$G68 zs6p;lx1ZjwIHXbK-MU~+2KAZ-J(6Bhn3wuG4|T>PcvUTXz975;Sf3N}^27>)7SZ0t zz~U!Zk6e~~0?QHh(T+2!ib_LF=7B`1HZwGQN*BKKoF2=&nlt7@&wJ? zC`_Lz+XJV&JZA#r!yfTt+RFbqp03tqi%9K)}dAB3`6YHeQ<$REt;@*%nE&>~(%nml) zVc=BqEOp{D6%4=Bl6h!y7k06lATEm&gz*~pW6)WQAJqOwj)VjVeNsZM`jbFHr_}Ax z@Fiq-A)hHxO%*bvIiudZ&IPy0vQhz(C!j4+WL7eA zLwC=%;*sPSSd7wN+gAwz9iInR?lWJ5ItC&d7Q+ZhZR$+f!}ie7TYOX$$$6 z|M%%tJs(7fDK{nuiotolJYFBda`Z6KnpO8@J+d1jJoj<57mB5JeB0Mr;klSj;6K81 zaJ78Rv{z#fc@to(xI{-dRTEInU+F-RS1O9s>M9V9FoU%TcF#*85|O;99|_(Q%tRCH z@nB>yr=?xAh=@NO=6XHYMzYgmpKCB~mYAzUONq`qm=WQaeXDbd_LGMG(U{w$Dbb_0%LKcux;F$ZMxeLk6&|6$F+=n}h&7qT#hbH)xY&|g%vqK&b0~T{2$uySw*DqOOlN?& z@D{~%RU?o$zxwvkwNdoFoO+zd?*vs}YkRed?b%AFE+mB}|$N`H5hv8^;6}R6ST)Ak^jc_>~sqvOv*FI`ecMAS#Jcc0M@-IPb>i3ZRf=SfHlc!kyN2`Cv~|3(&fE~ivcC7|D(C9N%;dnl4!^@scL zG7_Jy+fn!r+k@DRvnIYK2TN8pN1%(P-l=z9g&bPA!$=`TP@1Zznn3qPUY`&Q=}?7NLG9Tflgd@Q*9ca#37d?$KU z(>Ar!DFQfB%eRu~X@GDm)bP)H2Pokv>V8qQj-<~A1UO^khDc}3cXnF`5a%+di z7$-d-sz=}wp%Ro+>u=0x9iRZ*OKtJ@uy=Z4w5ju)8n{np$Mg!{1vBEub`A#;P(}Um zz4!M4WS1R__wuv_l~Br8Szvd7W?#3-Zpn|3af7S)P<#rmN_-f+0>x+uh@D@gOFng4C5pv4aU z^_m?%WM>BN#N-u6nP_ya#Lbm`R2ldr69RBZT;YSUZ~7-QCm89>2)OZno3zsZ zANp>Gr%>0Hhy3#v+`nCyhuzb$)3qc^i02_^`G(EM2cj)DGt6V?S4e?T%{VXkk&GE# z6#b6&=Zu$W-L*kAN%1x-!!;Q28sN*qxbsOV8-jtA&4A^XX+OzR!I}D_Zvm0%VDLTr zpHJ-x^4=^@V;on4MInOQ?DbgQ=@AvhtD1S}`_~g?bXOEk4b2DiNNz&`)yH2nwg+hN znsCj3eM!LB98(k%Sb(aHvfA}x<@_CTEUo~j&%MWc9g#licmFTnmkPr3k z0wiRiDEa;16s{3>55nyB1zu8sMIx;`GHmkC;f z;(vw?|4gsLm50|{2pi*&R`6JxWc&yUv-|FKSXu@iZ)H_K6coU;((|6u3e1;vY^eA> zxd#QGbE`T*@8Qc;I-5Tje@%VA+1(@13*I)kTFy9i!2m&K^F6mRbjc}YeK;56JVrMq zIqGv@`(a<3H$TULlD;0l8oEFm-;jq$5C?87Ts^3hl!fHa?d!*q2*O-QnODBB!zRPd z3tQBP(jIkNQoAUCPA!j&=yflMI@lHYp~(U#gPY_jo!X#s@UZ80_Af*lzj11jiQSvr zZ8G<(_o2MT#lE5n!Gj=Np%mvBIIZ?uQqq`%@WHbc(Iy^H!5ggZqRRlY_jk>Biq%1{ z;mXYW(I%K}6*s$Wtpp`(%9;+=C5W78T$@gt1;%eby{*Q~1n2WmoY22%L|st#1ozh> z%5(l2!s0rPPGf5yJa$Zhf|sVhvp+<_cU$c(hfZp6eaAZd;@L1%a>dt5DEFfqQ$wj= z9VKAQJMZDI==&f})YzA=o&+E86(j`1Pf`65u?JzJA!Ja8RUeW^fk?pDW(uMq^yAZm zdGn`z@Z`>8TM2?m#6UaEL*;f7aD8Wauw0TJOi9j?}_P; z&>?PdcDzLgY_UAB?!Q)r{L#{IK_fcKZz)by<2m|HZM{fZ_i@(gL1tlj`^<1}B5at+FBF##il@L#8) z)DHJg6#LMA^fBKkrE>VMvG4944*T{mPp&q0gZ*q41L@HW$Wt zE_r$aUHm^!^J}~?U$7*EXXFU=QrD&?M+ZOK-Z@fq!@wrGVB4vAW-tTxj_A<73zuc#XDZ@Xa!akVQHI*e3)~<0 zdJ6uSVYx7eWTE0pAnb08wX;1z^AViWx`A|{KmQD!-Gelr__{Fw>`Y%+Z zFuktvB@ZNrCf=NX%me&5Zn+x|7LX`oqg&^YI0TKvXG<7efZhh%2V*6bNYJpPxtSS3 zoAUM>Ze0KYavbmS>!p|g)Punp^I$xX=5pG7901+N0>@`)bwN#G*RU5bZaW=KvE(a9 zpp{&cF~!693l)FXYcbF5#*BZ)u;4s)Cv2Nv$el)hQ%s|MIo)hHZXlMOb|y*G3!dk`6SXe;3u4Z`IL%mpeo}lM+Xq!b;Qr+F>7gogu{jzZ zd))=My8kX6JrIL1vfSQLd{-FU#mlq}JV5f9&gFkqQXy1IT$GafW)?xf)%t4D<6Zg2wwe^qBKWZ- zl<${J0fA2h+zQXPqoAyG>yF}iq#(JoQ%=_gl5NXtugJf^v>J}UMtChK2R5E@E^&q@ zPE!B*RM|pj+lH-m!aV$&ar;m5!WoeBSbuyeauZ!qiA-sGC<{ZG_|)t%C+O@f|Jz-| z5p+aII`fNw7H(xF;jI6Ciyk)?OH3WThSetzUetNv!qNrqRJoHHl;1v|y^8(Z->lsH zk13!T^ESO|5n#xKngXj1&6zq+8?Hu=^iQ<-a4k#8ISSP{`8IxC>Q6oV^>@nIY6UNR{8~0PUKGxi6;O z0pl5yX#DC3IG`F5e*6Di5`kMD)5}hXCH1-bHAEGfJG=!ausn;5t@E>j{8tc)^D&nw zDii2)ZPJpZZbYCi;kvhn)tBDjtzD8-Ihu97)Q#o)4hpAjz0GGLL*&MT%}eo&qs> zlPjB#GqHWR)H&zZy~z7hNvg*l7o<1R$(}JvM0;N5r3b1bbh${?`UJ6PnPnnDXS}NH!X|rA(zFCIL+Blr#RW*FVB3XWcxv;DKw^vxzAzIMCHKq0gnBlwfYwv66Dxb~tB<`e ztlE-Vap^E#S?n8Hhi%jxa2r=-dl(9ON1_#On?v%?w)p%*7SOrwY1h6v0?)*o7Z-Ir zK&*|d(SxlTZsaahe`CS=K4?EtTa_M?M~sh_h8Gaw^2!w}tiO?SAtE&w`~B+Vwk&^_ zHjLUe!XHE#mx3)*{4lAI9PEDM?GzgLiWr0VH_5H3K;zVt72lT>yW={Ue9#bub05WJ z5lsuC+UYHEl$HeHw@szaFR@;Rwv~X3+96_7mgmQ5egfRq$1PYnK zw``MWvnuqcfp+R`&^|gm<<@lJDFZV4uznmYH=%VZf^&^`9r4TV%7r8>GkoNcUUVMKrCvMJEkFr|-PVus@sLDO7P4zO}uVpE|?1G_m*_D+T>B+X>s zap^1*$iFm~vlX*~mod;o5d04$y*6o@^hGd#Pga<9zcR@ElH&Zx@E+@#M^GrT>w$r& ziEl*QcO+-eF>MmEh4LKU&d>hE{8-j9A1{R_!-zm`M4ks8c-n8X=!aW^(?R?Vmi#$H z<`6&KisjMsYy>QBnqqg{umKyxHx$5_KpQnnzmAT~WlJ8O!#u3d&$;kk+lPsE`b0q* zcX*aN^PZe_0n(kzzsN3cBKk}j6W_8~q*7qVyDCTzRJ#%vJW6rFi`hmOFJT19o7s=J z$2NhSn#$vZHZ0#qv2$g4XaQMX=GK%xR)^O2`ocESQm~Z$@I0A51%&C9j^7Vhfj1*( z<^26O(7#c3LFKa#L20G|C&=OwoD)}OALXKlT>|EZ`7=4_oR8R?P;?s{QfD>HbPL1r zCF)mgVhPY9HO^{*y_;@L@!kY%4_+Lcr@6?BuzqP8At4!KGv@bti^4`&&)%zu1;S4{zSBSVkoq)Xk77CrJYG~iDp4{4qN^7)uX9F0`IM8* zv+e~j7{AusnsN zTV2^E-qQrG3BMC5QO1{N z50<{%ak9p8%eQ#cL@5jefxTI&8<-^FwA68y#-FJ{j;(`dJ zbsv&Eun5erR)!vxJ95oBPoXUJnqIHW9x}{1B7a8T3_ViEd%emt=!=T_S0l|bpg#6I zpUqr}Dp);Df~rV>Lho{u(t>b~PScc(wECu*~ zrIb4oi?s?sBTomqp~MV@rLL;4h@@-Lnu~JPUk3KA(&QoCPTlL*X0?ePEUv&!d|z zfQv8QbeEejLhmYR0sUQWna2B7P zqdvr8l&M(WoPtabg*-&UV?aoNJb>>>BqS?6pCjl|25S}L#+C#!kj(y;epW&Rge*T6 zHSPAG<*l%XIFGHtz#;U-D^`r#EOcgL8m9zdZFBB(;Q$o+(YYeBH{e3cS`wFm3VgmP z+5Q}V5AIW)O)|{*iy}y(nH0D!pn~tWT@IGV88lzi!Rc9q9HQc__V*t^a>HHp(ydI0 zX0FzIdtVb~NuLaoe<1|#=-UbDzl*WFvsFNZRevqXD?i3?*BHQGS$=ze!V{idHQv$S8lZtm*KUS`twZRB zwkjkQqJ}VZlj^t9@E-`t6Pgti>_ubV^h&pE6o7{?XZPngHKfjOOn#DL0Iq1Ev5Nw| zNL{f$Yigzk$hGiltUb5UmGc%&%Af+FvJ~SwVw@1sIP&R3Q7N3@uxb5uUq^57Ub@yZ z6Typ5yOLeoLuhwNL}sT@1%j5A@5|ZXLYOZ4F#GH#r20|qyE2%=_mQ#LXcmkgla<_h zUc3zU6#rwEWW>JDH62*1W7|7l~hXj&e!klT{1{=*DJU%YX z(UUI&{ig$r|50VZ4?_Eag`|9#+n6)29lr?b1~=#5H*Z6pwrP+QF%M9;eC2elkp=Rl z!NO_NKB#laKiaiB0X35C1ph^hWBAzrxp_J@EaBpM3VywfWlS9JhszG3T<3cqr!B>x zKS#^@&$d5kvquyPjS53h>ZW5?N-B!0@GmqhrvoaI{I7EEcCbXb8WXIsh4xQLZG}e! zA#~R_^2mR=_79abapl4x`oejaPar@PXlo7lCumIIEoGX-%3V$9h^*>o{rUjjU#5NY z?6Dst$i}zNPBKG>y5a))Mjq&?iZzqVWWw(+4iB{dnPB-I7c$ZAUgUpym1u4k5A%w( zuaEid!_ejX8;2f-@Kq?`cb~&0IPCMmcf#hS57SpZesDiR%%9?LFUt&}0!vf2y0lzK zkH2tJbutzlI&m75RRd<0`OTI8+*6JqH`V>D8)L89_hvYk!?4$p-VpzwxK9rh&!_fj1-6SfS(H zu`5w(GtmD!@1xlE7fpLt&cD=)2CCyeg?Y>)LDWqBRN*|v57oaZIY5o&qBsn7cAwdR z`a$>fw$BjqKAw_g43LNWa7p0C=TP`{PRdKFPZ~sWn%a{v-`52i+6I57G8F!1vh+n3 z1sF%nzdA?f1SE5QLZp)^U>nNVb%A{b%U%8(i?w_T*-@367i!YsI{A2+6JIxK$+|@N zB3m1%jl+ZL%Fj)%&>Q zm*qSdLyVb;RVph?KQWD*pdFd-i6zwt9&Iv^u&;mau4m zNB$l1Vxk<#ksa14eAk55B0rRkP1{1AFU8)EHH`1^REd>(FA0^k{dwe`^b53UOX;0c z7f{e6=bBq`kD#exsO8{UD@60BHPT~z@0k(G;VTTIsGUn{5r$M@q*TI{o0L)wD5~DrZUA1#V=4>Heq{NcwoLAn6H@Ay(=>7R5TVue zzxTe5z}e$c#O^5x9|L*FX;^7N-A77ZW`_f8l;1lU@Ml5A6Z3)9N&>hXpHHWK{~bVK zJI?lfaVQuxu%nr-N9)CXF&i;M5Ytdp_TeNKZN1;jZm;EnS0o0d%_+~|wN6PX^$%V+ zt(jn(lIMl>&fN<&p8g=vFt57C?+(J&=Idm;MIhdvlWb+73o2v3CawjVz(V%WWgqcF%tLAyhe(N)cmJ%nFmrG!|+(5do zTKj0QXtIE#$N;nxd(U>Yn?V@+rJuNkJ{SjK`rW_WBeHj+aa$Ak)_+P&Lp+YGmEYl}YfH$e%7`pR;~m??W`&zPa~8Q0@=9h>@MWPN*Q0r}mB|X+Dq) z`PW>$Vg`wS#|;I$$?6R4Ht}y_`Dm>e0zL^>Gpq$EP@#>qiX|Y$|2SXGj1)zspfZj{tnd9seXT zY@skmHY?_hW|S>L{Jsk7t5j(6T(2r`0Q~@FiMS8CP@wu@l`wc6R<#G5^o;8<4~X2J z=+z#yn!~MHp>zgtMkCM3FOQ>)ALeJN)3x~6q z_h-1|lBXLb>@u)XO4L!pn}bGiGW7-Y*w389aNiMPBqQltCgxzs?3JQc3oZ<^{;vJt z`58T5k7Q@Yok1$@UWFd|eh_ZoG8k1L4d+x|3Kqrk!rmIb1bePAym|QBo(#(wY{ck$ zTaMzu@8+o(61ogj-+J}TO1vucFA?3sjs1zdTbTGM`L08>m|dafvISMb{{3NO$*fig~-~PrhURGL9b9NCb(G=h~x$5EH8Uv?AQl6q9?ySQnG{A(&mk%Y|M*iFt|2< zMhVVTr=>})Od?|CA8$WAzy;2y)h$vtiJ`Z6883<=7Ub=pw!Ee(gSVebjU02Zdsh(s zZP8(Q_{f(O7x1(U1c}cb{?!-&L!s@;-py;!FIay;_GbhHQ(hQg+13GuNi?E zuYvfIt0Gjh+A$^O7J?p4&y2I26{u(!2F7Y`L3fo;2%iiIBoq_J0waLlI?JR02$@r zx3@4){PK2vLB+dTRAaAC@*s=%Cs_>S8zylhW?syj{Rk|Flld+3#|0i~P znaLb3XkD6AW?_LMzGR)w=za9!`FZIApQ~_jNprV0YZG-IlF$+n4S==B9j8|8_l$*G zVf`7?HcW8UpUNvML&v8SYwgN1B)u8c>dj}5@v(^2HTf~WU7tgePl6N}66Dvm{8)hT zzaGVoX_!xWXZ;0*(L${Xt24b*Q}90!TPdi1UebvS{YN886|w#1lQ_&cK?OX1Mkzy0C#WQtTR`!)2#C%x>rL?x zg0QNNMF^uD2-($gREqsYQCDP&t(N}zs0PTciLD*U*;Ix;| zkkO5KZ?sc_R3{iAV$&#CDTEr^KP$c~!Sc&F-u}BuZkgc7-Y%2fw2kI+PF8TrY@sdV z>5;QO4KT(Gly1KM{qMKCT^qlA?PK3C({KFobH3s`pE%dQ_v4@S_FJz% z-H)~ZUUBp*?w|VgmHtl0r1#(hiuAD#Tb8~*wQ zo83SD=nFsbrJsDV|Edq}dG1rMJ>7rs{eS1k&%f+?_loy#{?(uD8}C2uwcq*C&;8Ve zKJ%IF-#YPCKlkN7HT#VBzxknm|LFO(ef{74{(twMU-8Nl{X75DC;j?Ye&cfgg1g`Q z%HR9qL;c4d{O;u3Lq}^qUpDjOKlQo)$Ep4&fBy>}`mX1l>QDWfZ@6*r?m|DcJoEaG zo}Vi@{Kz|=|A#;NX=nS$VQ>Gszy7~o`p@6G(*N4V&7(i_C)52WyyL^K{-Yn--#`1~ z-}I%sf8%VE!@+w0EC2d=#}59$t}2SD)w)Jbdm=zxcOL_P_K4GcP>;6*o#gH~;A? z*VcdNWdA$UbAR!IKRn&$bF#hvWcP)4_x$X?`oGWA^D_tLCVu4cv;7O-JaPZ)zvy`X z?H?ZhJFj}tbf0UPA*WLcj4}I4D zp4>j?=s)=GPxyn={jT4A+nc_4W}|z~r=EM?E2m~kKHvVzH-7UMonI+?`0>T}KKXC{ z*>eBB=l|{3{PX|kM3c|)l5@sc>z;biD}MS5?wstu?fisG8xy7XfAK@FzqIzYg`Rwj|Kf-L z^1uJ*|9HK7{}=w{qyO_Gi~Z!c{*$xcGO@e#&d%wV9e&$Oe&Vlx>my73D<*#BlVAM2 zxn|Fc{b#-Q$6odi&z@~^*zWSXce`Ky{jdGWZ(h9Aec8|d!I%7p|9HHA^=I8#`bV1! zWw(*@-S+-M)7SoHhg1Epzx7i#{`4nqbo_}uf68xv(&gX3d8*I+?|0w!@SDH)Z9hET z|F7@)(1(}5X}SLo|J%_&eA$1QEPG(L=HvbIH?Lj!!&h#1OCP^_>aD+XqS@OM9Y6Z; zgP(iH!t)o)KEHqK1@HLD!^?ff8EbOm7q`0D&(-ct-~FrWU-MH3`pEf6y}xn&-H$)= z(4O+&{a^n1FaN-oY<2PXBmHlkc>dyx-@4epy5p@BFUk!P^sk#=lTFOb+lc;~#GL`Jm&cw_pD7rM1_e zDL;(AFZcKV>0^6e_O^5V+0XlXKmAG9k2Qb1+69N7D!h8pyDq-xi~rzQ*_HXn4)1jE zIe5OS=XbG(}(JJ=YDbi z-@fGk+!?pwm^c`{uXY*#TpMSp#ji6>{;S=${MnEG(o?6|1A9Bvzw%SwefsblR{D&y z-9--T9UNmPdA{A`e6ve@JkyWb=hpk)_RAZ;d9Lsw@qMw)bGtkEt`{Hv z`!8B<^O-Ch7VpGaxbd=o@>k#W(BD7Rvj_7JUd=T;JX-cc4&)|&@jLMdZsRR*();43 zco#g`?C=4+MLc4k;Xj+jXJVhLop{R5_bh$=XJ7rkV@(dL&EKbc^M~{C_vyl)-}%jV zy!OA{Ki=?jx$H3SPxSD?_~aiPJ5_#{=ZE{1_y4Eoed~`e^xyZt{MgG^-hQ}$=ZAjp z6~BFLvBlqe9e)vj|IrKI@U?&U$>ZfOdH-<#(ih%+?=Sq1mHzpkxctz^*LUJfnSEI{>V7-=?nkFx9Oc({<;;#Hsd_M^pn^IemLpON!y#X<2AZ{#nL=X@JyzS-5j@~`04z7cynQu6$@ zOCNpYvmaXM@i+6wlfU)r*Z$idJvh~ef9~zQj|bvE>@DAWw&Is~3TN<7@{zB}%aXsG zt~@J#@o2~I#M$t`W5wU_1bzhn;nlmp_tn4l+Reol$8UARcKe`|iMxCGsr)7W zHQ9Lk;a>g%hkY*`%lFDJW-G4=Pg^J)^FF&}|8O$+v)Fj-SmkB>nmjYkShI)8%4^6W zxOb}g#YU6EvEp^~8~eZ4W&UFgpZ8XNF=`L|LL9^!@j!76AAkeV`{kC0;-$MQ|Ha$k zz%Y-UtNg|D*I)nq*Zs-sjy2Nnw*2LK@k9RZyJA;!6))rq>=qA^?*x}l z_HYT0`qZy|%intW*A3(*pAt8dr|d6W60hN5^u;eWJ9U!8HF$Nm@y{!r`QuCS2=j@Y z2X!Gl1b;}po2z(1FX30adU!rupP8t-kUT=(Cw`F+o|bv;>+!whk4r5tc(m28j#s|s zch$S(5$Y=BtPX(ZM9%li@6=D!bL5Gc&+XyRJ?=R!INuU>}sREf1^u$ zKiI$VyT0@%{^3iPdiacg(o6CtdSC0}M|-L+hvygv&WKad%kdV!wz|mSXv3e`kv#Ec zt5;lWdG}@~Z&JU4Czk#Zs?M2*>b{*wux`&!?(xmiRK;lep@JYOMql5px3$LJeI4m#7JSTeb z0zM?}A8GOQVyDjOcYT-qI`ZFLbw6=DI6q%;);M^D-&HS#8}di|nS9iL)FnRrfj|3K zFaO}t;vsK-=XXE#<;yFT2dR^c;s$@`N4^W5&~N7Xpp#FTzqn?e#))6gmmJ{maGray z<6rnBy~8EA&ABe-$2>Vf<>`O!+tJGNT=ZEw{l z)i>l9@R?t*e|m>+a4F9>8ZNDM|Mup09Qpp2AFI0DXx#LB;xe8=$TNKGPStyZ zZ)a*8^$pL-S=}HwGt=X@!T;3`j^Us951veq;*RHVp8VmeJlb>lZ|1Y!spohfj^P!< zd}#;wpI(=_P<7+cx@G)*vDGWox9@i1viL|}@LW7)M|pmw<6q)6-0-{jm3R$T|7N~= zz7yZsiMTI*iL=%(#8dSg{F6P$&Nn*vhW~pGm-xFl!Y{m!Kj0hiN<4yB))zb%H`!aB zZ+3V^H7Sss?X>BmBt&lTfDyA$zQ}5{vsbye}K=yy@`fzvps#`&%R3> zG!8w+&L^v0L63R9R(uuj71ziO|EEWOgs;kv;xAX*y4az@Rk#g*@N;%3Zz5;*rVcOO zdCpGMd)bxmq8HP7QzdhfJ7se3>eQ)@f^`l#zdf;fBiX3*=x-C2R9B=1e z@EOnHU+gouakuJA(aTs52goPubSuq1_w@2p@|WkT_u_TpkvbCjtMia&=DA$*w9ZQo z!IQ~a{|#@St#xqoBX9A}Cth5y`ZZohp3&n{&wt?zdq_TVu<8Jr&uT}H z<`4fP|LJGQ-}lCTcGWtXx`+HO^SRg!`@40+TWwu$to6N|=;66}(hGYK-{0^_|8>`Y zfA(V2%l?u23nTU}RO;!5>71n2j*{Q6SWE7%Xc>sP_I z#Ut~yP6Yqu#j&^T##fJ2ewy*eibokI_Vb|f#Q5D>)tw@rLoH7ktNb@{aIWI1_=Sha zqs2jax_WiyIp6X}^`g_&&j2^@H*o=O7#}ZsWGCT!dt04$Pt|YZzpEWyM?Ul}&tebeFE7YE*Qy^$|KX^g zsw2sZ*v!@U_8A;LQ~eUw%hdhwH+tlE!~E)M<=y-= z^I53=rRaCItrJ*R}pS6zO zW9L_j4_FVv_sEUEM=y6f>-FKchiW~S-Rd(TXL&LHKwt6~5WzRNnPcq%_KAO5Hw5`P?P>v}WQ_k!m~ zFY`V7iJe<-U8uT&dWiSnhVLbRd0G5xuKLf#adi*=E-%pc3xD`KToU)?jt>X(2sv6Dm9r%Es4lzdHGqeprPk3C-f%&CJd z*ZO1pVyyT-dmF_`afDv*1o2wlEsl_nd^YyHRO`sG!>z(w>x{-HPdG^q>MHWnyuaP- zg}mp4*F*CYW!au8OG1~# z14NJaYTb?A;S79$^YA%#uCIHl_B-$+y^F z2D@s1g!m4hlP}Cxd|_9?AAL$!I_sY7+So-2RHC-HXm znb_M}$A8(adBR~hAbyGO>=O=q9{EgGzX!a{_~W(TL>{fK%YVfw`BD7$sp{Y65B59w z-MoLj`k6D%M(20oFkA|bEmR&YzI(3UL;nN*Bi_L=I3N3*?agmAAJ2T&YJJoD@L8S< zXVi5g=ke-eBsX;DlK^qEBds~tY({rJV6T4#p?>MiUO z?(rA=M0}LL@C*8tf643fe0TMY^J{*D&!{`WE5FN6=`r6mU-bbv%-+Ohb|vn|9_Fhr zT|8p9_&NMf9N$;{*u#15WYh0cRVSg}(Kv;dM!yHEUs@g^UuK7X*K@p1TvLzIzfHgL zBlrXV69;!yp9A}$cXGC#KFp););fs#jQRurvM#`X)g|H=JN>V1U!?CYJ6Hpz(cqV;`Uy;L=TE~%p#cnsc(K;&o^j+j&p2pYb4{zZrJTy;n!8q*G zIuSg_2Vy_>T3)c;;YDx&ZxJ8WjeS>e=4z*3kv!!E{8U`dJSS=&MC5s_R~zpD>_tj9yth4>?U z6HnPQJYf&w3;b7?!2i{6)!(e+Bn}>_zGCv^kLHg*@E87T9Qc!YZnX8mlhvP`aZc2J z|NQQQcCNx^>(kg>ee&ebZso1wpty{$;!*Tvo_LWuEx#royoKIDRiI3u!y0Q2> zEQdk;2cFZfJd3}?er|Ne(a%7?c(}L*hhvA6RcDqLs1M*9cstzVkMWnyl0Q3FCy^iV zN4N?f$Wxs}f7j^mX8spz-@WP{KwPDlRaq23kyU$1>1!H4N~PROyUE8-Qy{Z|{ExQ}<)mxrI@8=k|l@apM0H^z6V ztE(sAb>afK`7V4_o)SB`-mzPC1K&%(><8ZBGxCx6-CFgH=XaN?|CSx9x4=X3UHpyx z&(--k_z8T&L-M`XY8^K7xz*~xPgLIvyJc_qYV^3)@h|xlJCX0?yVh$RpPiF4K7fbE z&i7Wm%ltFWcBdZYd-)5V46n!`Joaqu+hPyH_H(%QkHf3*+l>}q#;eaQ&nIjD4u8Ze z;Kr!^%Zn55&eb_5;<&mc-aG7H)+INqKJR_@X}wRJjlPbyylGFJyAphxZFP?Wt>15d z^;?Ql!C_pa1B8atO4;Q8+>z5GZV&-WfHIh!Z^9L0y|<$PzJ@(%08qwyub zyWQbe;RAT-y~?lUckG$p;UVEejN5D?qvRh{YUw()oxVpa4&LLZG7@@)mQ0Ner=w^_PN;N-Aap7Cu^NT z{R;j>&d&FkE?x>JgL})BALY9))Hx)0RP?f1eT=@>Jn?6F5WCf{!r%E_CH~64GSBf=pP8F_!0iVe&7%JN6t6voB??gocFud*T^$` z;6de^^qY8ktJM>ptaFOw?~&);>N7MSJQF{R9FEog4t|R7#qTzn{p@S|#hjaWxYlRc zzxY1PhbL;iLw$ywXP(FF97TFmXOJJ^&+4v;*VDyM;$LIcw=8dpe)re913tj6#Lf8E zR;|CoNph2)vJ-I-ABbJ;t9=&m5dIrK@|?HWPRp(>i+js&yr!VpsPvMy7=94(J z(e@n-)~CGBFVung#c&)yR_C!;x56JX&Umj5If{GY8eAoxQ9h=w4tLeBjPJX|FLoaJ z49=^B!~B%r$?sxUv(;ahaZc5_G4z#qeW1=G!ehNpFY06FPdgU6G>sqU)-Kq0e;ko*uxJ+O4$PQDl*j?+h;+p)0 z{m`#^MaH?(=_6&&co95jpLi)e6le7xvQK*9k8sbrA)Xe0UoN?^2XQLDd$iV%;C#Mo zrp_7WFK|PCM?UgFc!=M^6Z%Sh<9_Y8RA<9W z2lfeP;Hvdjan^T{0~`?d;g2{KJ9qBiWb60XTX8(|zgK{EWh&eez634HK=zH6=3 zd8X@JN_K9&nB4GccF4~8SH@qebGhkP-B0`#NBFxqo9{YP=T6``d4HqwVtVmi>RR|M zUJ<)m?W|)a?(AuGl>>FYpZJdd$iI9q9LVn;t^S|jEHpUY)Gp67S(R-dQ! z4)ND~_)+YCw)TkxH)d-eMB?M&I`0cFB4@lye2o2H?eqny>*jYCs^6a7j{2kd!$UlT zpQ?+(4R#`b5E8fK~Rtwkp1v!XQ;<$Jn zIZV}gmGWr#pq`xZ=iB$Y%d7*Es>FLl1leB=ekQc%%-4SNL9bPA{3ygVs;ATIW1i zH_!JzsQzTn)q%x#>oWL{@ng?73m@1U+%vxT2siTldON?)Igm5eFEPrm#Fxn7c5(bZF!lzUi}mA6~FLF^#S&b|KMHlgg=Ud@C~nn1L{a{m|xJBdOJK6 zABXew<+78=XRgk@j2;hE{gxcWP5CMPk`Fs%|Ll#v;3T}t_uj3(7kUq$-{0)~@j5@B zU8$eo?fjJesBf63bv?WYZpZJ=wfudu*1_Sk@x_J6bEEb{nLmCjzL-zmU#oK`=$Ab8 zKNvs$`&c`VYpU^|r8@Udev$FltM8XQ^L(|lE?|85_;6kKL8pEtkHddr4;R|GAIs0E z59sd|AERIM9OXq5buUcD-#OQ?-4h}2CTDpZyM=G?5RO?-VgK}EKJn8NE&pAseMbDq z`1~&NKUIC3>_^;TKX_5(yjFaYUzx8R|3ie`$3=lzwc8yi3JoUHX$buG9A4 z?&f!6x3@;}l-W9eTYUh(VkhihJi@!;?-Nzmiv0}gRK81{P2ATfk1zRMIL5E>Kz{1| zJh#v5L5n-v=t5063bE4oI zJIwf-wNIQ~jq*>wFAmD5GR{`@VftP9FW#kYZ~pR4=Uzr%8`Uo~jOX*!rzBsCzZ|K3 ztm@D5N_7T$l-FB7!sqcoIODs>0p6OA@AX`KQK!oDOLe}VzS-FMc=dbadso|eN)y#j z;=AAg92<^DQ*}N+9J4M@&Kc)=_1)!rk2K!6vp&%F1Ntud$~>>M^-A?~eV)5opTlz9 z-vK}63-A_yQ0FoKzu8YGdwC*x%6Hg5TpG4R=k%U!-?iQDv6`xWHhGQj!UKb2*IGQ9 zt9xzmPdowt5y!26u|xTqdE)u>2q)!V>;Vo$ZjaV}`8=2J+^Ie#_8@P?)6562z{lW^ z_@a*Fxi}IzIG=g3?q!oVS;vv5FU#ChwLG7{92v=7W`lB)IH?g)?d`k@Emc+ z@6t>3IM?cX?m=+=_R(6$;lFSaUyWWaR)2_m-*f8)ng3MTRpv84a_;v`tt*kgxFb)L z*N_kU<#*yKy~xWlj{CnR>zt+NcPBo#dpYr8JWZbi-o+pBQu!tv%XjUZzw`7xn9FUw z<8<*ra)2k^&-|TNxxen;lo#i_>=VD$i96;gFB`6tFBP79A3qUi@m2hm9m2`XbE)PJ zH`u@YRKDhYaRG0UFUT+8TkLaR-M0l-#TW6H{3GWpBXLbVZL7{>Cr|hQf8_ht-y{Ex z>KjoXQ-8qg;6v@KJVB4q@Jtin7{Qh_9-91 zpXmjE5Pyg3>gTKOE#Hqn9%}i*g?6v&nI7-O_wXzDAH7^?@%LQCYdD|$^k~_MycO=n zKDS#QI#K)Y^b3Ut-fD7Nt$ru*i(kZlms;LBsFzwNqF?b>-e(;4Chlkc(}iPrg72ai zxDk6>f5v{FJYOw*$oJ0IeNwUiGj$FC-U|=q1@aF5PVeMTkFk>{>O5QT!*lta_+mc8 zdC-|!50dw(4|qTJe7)>Me8j_p&rjBUG z_>cUQob~zhQ}(7lFAri@))`~BJNMJHa~IXm)!W5c^@{Mi+qI5h9Pf+o@=bPvpW_>O zzES4{hWCzD9yH3M@O*k7?!%et@pkoCb|tRmceh(zWu>hHy61Z59`bhIw|EVQ@we!G zkatIqgY%u>F!|%Xcq87M`sab_FOnari{g{?i~svxe>XmT(Jy_8?|8EMZSdr&+OL=I z8uZ!9ukiPnfEV#Q{>~2ZTXup^@(cFK-{lv1?mp<{;sf#*>lFMHF3I=V3HgYR`Q77nU!i&h z`!S#BWwZ93#oqYo6D?oZuKmAoJM)=q`SN)6&$E+^bE(cPVdwleyn1)#r~0GVt#}&V zGPsvYe8G#v$9(UtT8~gy!S_bvCO*uM=q2)bQ1`j>FZxpdhfC%;EYF!<{SXfyu48Z4 zdC`8C+|<*8hxYp)DE>)q?2!H7z2+nC59@2I&Y{JNBDcZ*T;D66ip$~=`;p&8Ut@K? zO6IfO;YD~$p4%UBug-apSF%rWM;(kGi5HRQ?%G!#emGuz_~aw*#||H_{5m}6bnQE! z$Be(wvlICyIm2i3fn)rUpGH3F70b2mW}f6JZ^El1hrxbT{D*wx%lJcZa;46-5C`#U zcn=T75x+}5^kV*S1AmD9OxF6i^;7mK-esQW>Rc4(KaeNAm`~mxuY8al!hzt@N^cze zlO2-3c&d(+ajw=mIrJ!xfG6@hUJq3}^bnVB7ht})W-}w6| zUy@(TYa+Mpc7DRuR{xnUo@xGg{%GA*-2?vfQ~lNC0B5Y@*sn@%;=4L3zQIrV3qCVC zANIx{)yX3V>jn3#--aIPD{;X+gIm>yraqJL2lda)XIJHA@&fi2y{y-Lni+qp_KV@q z?Ado^KC^wEyWeVWt1Is0lTX*Zr|Ujn@tu8&v+NxIC(q#OOy&FdmAumU!TBSN|6Hhb z5P64wczThS#U5_7bCp-?9$q+xuc{C0lN8@$C%0Sud9iq}{>}r4Y>n7gKwEMiKs@{%I%4cK$yX*W+ zI3TZN=j@gp!VUQ>zG__+PQtzD_d@koizE0R9Ohr1<3HkW#+j?Waq^FT?-tKd=O+jG zBfXF_yOOuUCH{^F!bAQAZ{zPL>wH4vt22nR>|9+Do*SQE$kQWF_n$tfef{iKy+XY= zayVM|$HCk1Onqw)s&82xZxr{~xwsr&ad@OpZ(rT>p6|Nb@L^`8u64Q2SrV`LwY-Bo z@o;>D-QhXxTz(#BH{`jWUQ?psGzkBwjN zEh0o=JkI)pyft>~Ug^6XeD=L?CBJ*TXNQSL?ipWd{Mq@~cRF!F+$2x+ zhv;i(zwg^#^{UfH2K~~;4^9sHh2)Q($F8o|{hsX8cZvJzuHqNJqet==$N8_kmHfp8 zayC!vjN%bKhHqq^OVzK)uh~D|g75JcddWDCmOa2RaYWvi`P(0{-qyj7*8V$omGLh& zJ~meOdXo>{<-6n~>?(deQ*m>&j$uCJ53k5m9Yg-eK8Nd#lXah(ILHo%^>w9V&;HJ? z{5yWV)~N%qH*o~-B7gD7IPeqB<6Zmdf ze%0YK{$}l8ga7o-FT`bfmREY89(@-akY`zE$^4z~z1a3kUTx zQt@5i-LM|_)_z;~!=CxCbqDw+?~w1%BRk|TDZny0)V?=RLm6#2;0*+2c_ zY4F^9#CLe>yMjyO?R%H%zHEF_zU+I4>mlP+$FuG!Ua0d#@3(9J0y*F<@JBra{==*2 z#lCFoWml^2Yk2(awtv?8=83wWn&082cr1BFJ{#44ZvOPbfAzP(8F-lS-EY2C=dvd5 zobTX(e2x8+GaR57dgrI)BVOS7_vT=HDMJzkCf$6wYv{DGZ^hu}Z^>OM#D zR2;xZ+ z{jb+O!sG*IVh<1Mdm^8E)jx(m=x1Oj{Ej?>pO?$d!!wUnACx#Qzw^DZXMMsOjSn2D z^-wqlx5Yuc!aAKkhxpyuS~r&$<5!vIZ1LOJzkL~J>%21f#?Jk2;`oi?^ZYLJ+^oJP zafH8!`|=lYB=&4y{Cw@pV4vhB9`OtD)O_F!yi&Kv>(q11(|4Iaxv4|KL%d7g0f#e= z`^S&f`ae#zhDpYeeyQF&aU9R_=}hNUA%&v@iaU{Tpq2j z;&pfhdy^-^TR0rOi&MAj96$UA{-jRw%>IAhB@W^_@J&7_UWhyVH{&nWy(D?={;&Bu z2PxyP);al+&y#ijt#uReT|5#OB8TZ(XNk)=BXq zao_vwKkqNs`u^~D&G)`5xG`IK1pg)f;L=JDeMXSgRXgU@)H z-(}DAD=y#z>dfpa<4+dOuygVhudR=e2VQ5rGInyc&LNjC3gG>qji41-{q&`9iAp0`CamX58-JG?Og8Vx<>}?k-z#aoMGqu zWwef=t}9;Tch{=V0e_Z%$!AA-CY~dolIP;3`Q0b#Tvj~CdJ2CR7x2}@{fUM@=lbBl zvFewG!?B+m6(7T&m#VHMpXD$7f_(5m_AhS|-|>g&QT=MGlkZz63SMp2xn7BP_v@bG z=y9s@mtlOk(}_FzuC;c4#rale-dF2WCsQ{RGkf%kf@J{Gy1 z>ctWHAicw3IG_(Fzk93rym7=ka^R2bP5z~RCErm$Q718udSLA5Se*+2uk@L~XY;pS zhHr}ti7la(LIYt*&8&tKTNxXd4Y7dwQL;ze+E zq3#V2Ud_~f@$7b3UspTv!uLiFgLB>Gk9mHoc!GG12gaT!d*iTM@=@Q0|Ke=?akl&g zFXF%YVdSUq3XYK*yCNU)gZ-`SFXT9p`#(@u+&)r&Ag){72oEo)HagBemL-~vN0%zc4 z^gCEr%KQ37=h}MHYVCs%kBlEZs(Z{;JoR1bPQEKRv$yGG&=;iMj;CdwW6kg88m{i_ zSAO`--}|;7o~!;tdXW#pbL(jMBzwj`y|2zGAIWzet-esWM~`@BADgcG+TcIG z#`o|s_~v`zXXO8&gErC~& z=SH2wlkvA}zdT;2ev6lqGyX3g;W^?993W416?(*T@I$z#&Z*u`kLn3{0(rt2c5c5C zKN26=Gu{Fx6K7|uA4c4P8|)(TO{cHC}h%8SClnkbgx!w>sa8=bJx%!hhuv;x+xM*QsNOQ_=f+ z+s}2ccrRXOohZM%uhviD0DqD1h^Mi)9X`_5+4(ix7LV}r*pL0-%MGv2SKqk29-fQW z@*{R7E|UYjn2&kNTj2xz*9XPFCCBsg=Z z?1UcuZv1F}o$tY()s69II1o8ok9Oa|vD#mW2f`Wi=U>Lh6Y$K)`9bj+^Y>hwg?s!O z4#OY(Eq0=AKUH<4#K+T(ACA{KDj9!gf8h6j#;*03ogF!^@?yKcW2Mefp)d77>ow#* z+HWcEvu=w|inG>>>5IR}qtz3{5%RIl#csuyVfpWB=P8|Ob;}2x_y`BoN#uPQ|4i{5 z_$;omPyQ=D;v4aowK}(uy}>1RB_AKHJLUQ1c5lwHTDO&t#I82$-T`%E@`pdxU*I03tMQYJZ{25a-5(J@9h~ckKf_yg zqCTnqMlbnYeSN#?oRd6Xt$jVQht1me%HPR{om)RrfAC!14R7P8SL(ht`2~K(kKiYK zz#r_RQD+OjP1U|XxJu5(!9VdFxB*u^$BX!*_~?82k>6#v><4ZHA5JwKyHMvj;D_Qk zdyBpX`&;3p-^EYD4+rOR!&SHhKjk&#fIq+=JT2clUv-|?)z~xkS%{CpjeD)ne}C~? zxC#fzC;aC`?H`YwueUr@9bl{SQ21b+yuZ=%tc^Oy9{=R;zBh6h&7%i-E__oTkcZ-v z;vG5T+xU!lK@R*KPRd(jS2NXLA%A4g`j_w){-_RS9P4Q8gdg#Db!KumNAO^1dhPJU4z3xh?hVLEeYA7#}ZU=km?q&s?38Pmla1 z^1M;&N|Ezwol^}z*(ZCJ2a&&cq0Yna@Y}?Z#oAXJoEh8?$j|DgL|^z2|SOT?3}-Q>7$Q)_CpJm-^nld9h}E&#ou9nxl!k=())0}<9?z+ zynx&0!>`$)c#3c1f$HkRI6PVVj^U?x%}&TuToyOsPxQD`=YG1bvf1`!+^lnG`J-|0 zMs|fKzzzAY=kzP?B)-hl{aJ9H9OND5Im&PK_2Cuat0$^2f}P_V#>e;gDgMkJ*e$)o zH#iXa%+x)<{Eoc^PcD`{#7?$5d`x^~|Gt;L;3|G4zOZxafbtRcK+fWnaWbDHy}B#> zR8J76=zZ93x9j{Fc_RD71Nn>j$4>M;9;*Fo;x&D#lURRG|HkRUA8`t=Gk)ahTbwff}M2iO&Ug}12pj^a5y z!Q0_EJ7LfAAoVMGv^qS$pvU0J{W|v*pQkT;3E$wS_^00uo~S46uKUr%ugK?Q^$+lu z;Di01gL9An<~o~u>QA&j?VWR5AN=m*+(U!&55*DqW?fHx3Ev1#+Anjv?roGWWSj$) z*VC`OPkneepWUwe;^j5$0iMGj{(`6BS8yzLJ6-*C!}fN({ElAoy<6?v&KtF^8hyF{ zap(S(r|%6P+=mYLGX8qY6VLW|k^BPgWuEFn2dmx!XTm3^df%l!V_k;d#crRdb6wO2 z;3quHckP^ae*N8#Kl0F?I%gnud${G@&S$$`=VRmT`L4A(2ZJB+clM8;53grU_wpA! zK^=x&`QFTPy!vd_b;UvRQ6HdR>qPui9n5^lP28t1JQm)Dw=5Um4j<6}=3WW=yxdcX ze-8R-&BynOv-~~w;~t-xc0bqgS~v85`24Y2*Au_s68(CP|KN@4SMWhyH{bhYJ6~wB z&bi9(&ewfm>J@puQ!o3-Uw&ll!%tM*fIsH>Y~AN2UXZ7H9UQanss1VNX8-0d&f=5a z&wK{wbgA!I*B0;8&G7ulVX|;F^^nJ^zZ&miSNK@we|u!V{P`B&A9VT?*e5;?KgG@1 z`Q19Nz|v?ua_pHOg`eMVcD3B@&AC(kif~>W z&+iV__0%!=Dc+(!03Xz6_!l|L<08-ThBMddo<2M$dc0Eh&oAU_`pxuNiSOhrUJv8& z{m%H2|9tJg#uM-;bu;!1$K-4HUU>LS+t)C-FI7G+j>CVr5j;Fu_ic%5>|dUhd2ZMG zAby_b8@1j#nis%Zd6xI(7xG8`o8O&j_P^Hp>gTF{68~MT^OoV5crltU$T!vV#k<(a zo#NHx?0x==SF5+sulgar2j7Ny#dht7C1>`4Kf_P{ncuzejQg1QSM19921hDB(yux; zd73}JW6#zj#B1xz8Q*<6hpOKUPgciJhcSQnhOcIvo%>Utj+?s+Pxv)n2T#N=@@Jp) z0^j^DzGNK=4wxsNmgf`I|BScGo8SPxjpysjV*m0@@)wWbvvtY5KUH!QPx%Ww@m!w? zJXcrD_m0*1`F- zk?-@<_`AGdw(?(c!}Iy0yb14Be}>!U6Wlml_fW+CH`_kni*@cgJi&*_*>n6HuOJ8O zTKS%75X8^;W!59FgC_$zfhM`;2;*@5Pt!H255QJ6O08zq?%bJq3TR6fcck-EREh zY~wTbU$3{ka-;60B_H*===Vm8Yy9g<-TM66Ek z=>;Fi^X1x?1kV#M&NLjjTk9tBUpVP~eP855U;6OX+2B7Mj(i6DP1uj|@zvO~e$Lqz z_iwcIapxiIZucGBuX-$8Quk1wB!BBo@GbM--Rjcrh1{<7JN}Y*F;Vj8*LWcQ44>g@ z;^~p3!PY<7U#6dWQpYRv_M?IDv`4@jt z$Ch`nAN2?P%6G{-)P;ua`Dm}6JY2`yXzQn^+IhAUbuN%PRepD@t=F%V-o;aSkhpCB zoj5B`G>-g*f3b5oW1e`9d<5SMULC5w(CGa}!)N@fE4T-?bzr&|2AZYaMxEf^XJ#{S$Ip2>RoW&_~B!_dU=+-7_Wd= zk^iHO=Ul5k5a(==KR(G{$S3*r**fni?@zXSWM(VA<5!XY&V7&FpZ9Nh*gmO=TF1wW z;8^@_wfI1AW1-Fq!k6G7dxHb)S-h5?;;Z5|{t5r{yOVXUd*(ma%U=?AmaA@qKai*R zMQ-GY53B#sqdXMeCNJBmZ*BbYwU2$nu38_-`;%3F#?Rq^?@8YDc)RcKaP7bFcXeR) zgWtj#^2AHYjs4>->P7IGe8h2l7+(2a@znRym;55~->!QW@D{jgy^J35LwfX_-{C*L zSKXffs>A2~h3Z3w&+5|rOP&?^Z&sZO4*OlW!EQZQpN|~IYM;J31D;IIaEyHp^Z8?? zU${M*=fVwgGd_9Br!xMtF4xgIG=y#+{CBzg~7e3?A-b+eFfjvi&rP^?5esA zJ5l!#kMN4TKU4K^dQ^wOH}E?05g$kE_QQ6y(E5mG3LhfpjfS@iE$$rX{jR#V^-w%Y z{XBBsDxRheU_Nk9or=G(TQ~qu#OwIujjBK3)zR-#-SZW_-)i@6EELbgbJUUWx{PzW z?vquw!H40tI-YzS-@|jnU%1V$JtsHzfJfn7aE3h1QyeEZ^$qoBd@}DZ)Ol#^5KfA- zd4F%kS$u>1`3oK>UaNb=-;Y#XT^!-R@)X|%H}E3)7rqT=;DmT*T}Ivn$JF;S&UCFi zM?T{ffAhWW#lBQ{D?cUA;Qy)WL*_4Vl|9SLo zKI4a;n-711x1%_g@ekBKFSrptwx{*U+-m(WlPw?FSucOz8$W&Pj}BEousj-GksH0! z3;qcY=}{bnKm3lI$pNmCC%X`5BRBnK`>HQ!l&_j6d!t8srx*A`p6VF#9p44dBj>^X zP4*vrJKp4crR|4uU%B&(uGYEq;*P!rJQ@CoU-ApMp^q2NkSAVYK6!tw);q!nF4y|9 zI4%!@=kQY;#ET-gtvc_K+}N9W!V~zM`D|2QC7x`(1AoKotUuzn`P~cUzwFBR>Spi_ z-tr^$6FigLo|BOyT#Ad5BU-MfzRH@!`ZFp;=cL- z{f^EjK!vwygUPm;gi`Ac z%;3P?E_kx1c(QnepW}7p&#v$#@d7`Gw|Eh}f=lt2i*+speeo~6F?hbyNA|9Z@A=|C zI9BKBMUR6zf95$|{WjzYxA7VE_TboRCr`(3#VLFe&cL@}J#JJz7EhyheuN+5x9~0U zS*d$n#oyTZ^*SfV@5&?ik$R5z*+a&$A3=Yq^Sjoo&sJR``21Ae`$PWXAo~xPbOZXwbQ`h2;_`mvU;>fO^{YTD&K3@8Y-sfvQE;!&G!@JclA^zf%{7&5oUd4Z} zR^O@oonORHZ`3-P=aG*(?Vfg?)neTf4TtFqKU7EJFZ9k|u>u&39AJ*>5o8UHnMV|bZJy?g5*Ju7$ z>Rv_tW8xrtke`aP^0M$=>-)EgAHqFyjvlYnIX2>2Pq%_L~@Ayk>{K3;&_t@R|EH&&X}Ag){W!PFe%M3s|9s(L^yR+$6ICyQd(rPi z)t})NUYhTks`~`x3-T29BYzY(@tnwivKL3x4d6cVh*^+~}Y5tk# z6Ll|``gZhkrmbUc6ppDY!fkQHcd^^(@m44P%5!}$9Fqr$kHMw=t)G9Z?uUXu>`?rL z8|2UL%#%H+uLciiTD@zr@_K%RuktVRiTtK1gmkTaU zwsi-6l4Erbg1QH};Vt}>-{Aw%`$UhY#jfV-+#dXpzZ)M8vuFH}oZ*r>n|whX04}Nf zu^->-`Dk4Z4`=_8^L*WJ#m@0V_2>A-Slth<-hxNL?cm$J>L(X>^huI~d>KE)--hM9 zzxs=;U%*vyR{SzPyUOz;b>3b0j6R&T)`u`&I3GEz);+)UPCn)-UdOLb)VkiNzUVjd zyxH=Uty+J?!!!OyXM8*%ayV7%V$tKZ>UWJC2L15-4xY;+9{b767udaTw-NDJ|eYN_I*j1j-*ZPILUfgFt`fb!<=tbU5zi?81q`v|`WS?** z-*uqkzUSnrJ`mh{Q2dIYTAzihnF?~-4zD{(ybGgPzs`bMYeMT(9%J*_-cG$A%}ttHV8c!XI@! zJWakM4$6yT|ATdNc!lrD*Tffk5vMZF<5l05fAQbQf2D_S8Rtx|o&ZnOlj)b-$kVzi zJH&6{7(2m>@_f6_#j<|Np2balmE;c(*<0j%v-&XOr`y$^?|1bR;xnV)1>f>~=bqko z-u#V^Kj(Pu3uX^^3;FY};q}eQ76+|g%UkbM-)!vaeuq!O6Zs<^lDO<%^>elF1E0au z?5iEM2YCdZZ2ovPz3Yp^>%=4R0zZj-=38Iuy;}D)PdKAa0-x1U;mj~T&$YhUN1J>O z)V@DVUHiTd^yDT_ zXIJb{T_w1&RO=w(7yc~ns59^*b`A&B4a7-t*7))u^2f)#&yQk1M{9qC^-$yEX_3Q? zPMr<^!5i5RzLEHHz4jSd$2T9ipqnGCoY&b+_3&DUcgCl-1~`Bx9Z$@ei6NF zR39mx>AT=b{C!{b5Bu+0t3RBqb8hiub{jeP-Tl?iDUY)*mfs!R=bQPvH*K-*A7nq#`%J6D z?C{g4`++yBjxJsg%NZ}4u6?g?jDNvx@jCuKTRd5u6(9Kv`{eKZF>;uE#{KVja^lxU z)xC`$dpK2j5T1#D28Rz-9SKj!e6H8I3g(mVS}(qV591H`d4Bgm^;fIsd#>(n{TGjA z|A}8KwSR$s;oIyXIDet)X5`6#jUPMQtaIJ@HJ*TnkiYzny~eMXYh4>3kSEG#%^wb{ zD~fmUQyoCO@Voi0N2^YShsWPfR9=Z+!Li6;tM)(AySygy+*SQ)>ObNs{sV{2pZ|)F za4+w#we^%6RcC<1#;13Amgo2k`{AeX%J+)z!K6*3+E}_F5X4&#>XG%i~Yk5 z_{o3O0q_|-IrEt;e=!a|ko?a6va{8yc^DwKmD>p^MwE6$gm#Q+xa19 z>RcmwiC?>qc)RZTrT5^~VEqyPoofd7fV_U~-eJsp|^ zc+0`s|ISY2YjBL5;g5bi^*45vczwQupXA_s@pgV4z0cOV9{u8z>H~0Fel1^9#|U0c zJ!4%M4&bZ!8~({Y*;~GMr5D%iyZ65D#ed+fcqIQ7XML|YB3{D{b+%z%x8BZUnW_Ap zJ-|KjG4?ZE>*?wq?3~?_r}y){?&qDZz5?GBJ?<_!z%g+_K4`szJ;QnZKg-5A7!E<#>>mB5bhv38f2rgxw`fX;5&yVUIu4bGAbw7@Jk$4CHgP-ed zz3EmbUsjJD)uVbNeW{a^^C++8FYJ(hGtcE-T#nq<>Yif$4rjcNp9eRl+kVM|ZQs_( zIzJ)y?A+S*+V?7tfY0pT_sU=Jf%w-hobRj&*FoT>XPqObdvSHg4lNiT_mSDHV%*Z$F#NAIovf#_?Y@W=PE|IBlv z>Y~GOaIVftW>@q$%zNi*{`95p6#SX0eaCpUc#0<&Kln3IaX<6F)_BEW{hHh&hq+qU zHa@!z&Y!CD0P%VF7I`jJUK9K|SM_k~4)SR4%dh1%>_QS2vT7 zsFUCo)~C!LZp4q4s&3EUjl=#Em+!RmMwaWm9rZo>B?mm;_p0BjM~(6meU*5c_$B_z zEAQF-qLn(=njG{4(4+iRo!@-eEq;zq!hi9R9?gfJ#$U#&AKQ1~ zhod|kPQtNa9yQtHIqXyXf^Xy*xlNTGtsC+e@gn?RJ$btJ9m_k^W6g(ssz2}-buj#s ze9Yf-{7qbd8{{w??~c@cQskyi68q5~GFJOf*)tx_e&7{+R)-M>*^j!PcxN1Z+qzri zKUViykb}4h&m#xxTvw{j0H66+-d`y@p%*+5FO~0D=M{hXd-S_e=f3*hJRh9jC_ajJ z#uqQ}0r|4`$$^~dg*?R<-^JeKM;T|X#i@aQ<)PxZ`9#jk?H+{X+BX+Fd8#8H^NBwm zD!mNH@d3Z0FYC_1!;2liuwE%&Hh(;vzTk%bw0!Ss?f1mD@qgcCoZyvu{;j$fBlCIC z>X0YfJj?fmNbI=9yR*?Hpc;NH6Y?#_OvAA0?zwYLrS1$ciH|E(v=mov|e z*4KBt>NBx7{9(P$Jy54oZ{ZhkLw$ptz*})aoho`iS@Ak{J5hZUv8&D6-zrY2ci}DK z6#J(y^NAjJ*LmRj*zps3kA7#{dAa+0|3AIsUHB@y9j?!;wRPwDw$8Gr>LmIS@h&_W zp6J6-ujY^VIXRP?=iv#fRZoCp}h}b9mk3Fn+8E1cw=feT-tE<47*x{fL zACI!HD)Tv7_p+&X4a<49$MI={>F#H@FDT~Zmqw_JNUbLo$qI#>`H!`d0wu2 zxHA8%O}{(mn?AihJ2?M8{hi+#f-1a8=wSfAxI&#dFxLz6JC5T>fPo{J}ae{4{>z`)2ut`B>MG$I*M{Gq`sQ zPh+?63jZ-r<0M}`R_C(9PyWsh@y|S;uf7`o#je;1InWC`PafeupvgLKoE*F#zrNRr zU+@-=83+FfUOn0J$HiK2#c$bL=C8iJIg)4XEji$0@L%7)`ltGT@IPM>=bwGNgFSs3?^tiDwZTgk(h`;nJ zzQB{wIOTo&`mJZdXZzFf>iFGi!%64ZEcfcG;<$AmdY31PkHhtoi8^P`eE5<1)1!Jw z@}sG`hfdzdk223e|G9WQ93R)(dis%({Xy%s&JLFnFUEWG!4qO97i<4Z?Bsfr&qmuX zzpu_=BTsS`m!rp>^Q~GRGJWX}wEsHeAE~;1{Od~jk#Xdq;Wgk7I}8X7KZT1B<{zqjBsKSUds$ANH>^JwGk`efqx0l|Hz%r}hi*3we`x?Yrbn z<~bbiE><6xxQxfDC(E1iz1uA>yISXjM4l&Vy_g-s)yQ*KFD?W(2J6V=sjiNf%CG62 z9O%*bp34*Q(#UhQ&Xa*xo|C_Nqx?GdKV9p;^dkP^QF*@IcXYnEeF+ZBM`9<3S{-$Ft%u5+GXKqvzq3QU4$cg( z_g(DdoA`{pEVz2E{4{aodW}y$>;doM?|J`7+jq9F_2F#Sy*c80^tjgQY)9I9;#|Y| zxjK(!IF7H>dNe*vkK`ur%lNCUFL6+xVOQ{w95N1EnrijBkiU4%kKmp->$`j}-ix0ne(i1jQQkG*+co+}R(uRZ5q z)`P4A%A@fa_$j^^Kk~U+`{mh#@qYw-@gZ}c@;br1829Cp|FC-_gsAKa6Y`CRFOC;DOLs-IAv zh)>cxf5Cgj{n+iJbU+^OHkzcc`QT;~F>y5We)Os=ALeBb&@FH@9Oa6@?ifhCC^Gx-tWInf^ z;n#_4Q_tWz<`cP1^x}@+mEQ$#2m5r?ZTMs2`=J_N+>y`5fA{y~rmo0t;Vt`-M~lmF zkNn{+IjARxf8MKeqR82L1UrP!;vGDPV{lcSU;I)R^}XVb`M?dl#rLuw`0shX>p`;< z>#95FBE97YzwXk{?BH6fU&+(qGkJ#RuQZ;vTI0wo`H}oc9;B~eluxRsiOb>_dnSK& zJ6y*Y;4r_V-`L6J;fC)GXR3BKX{D0VCVihi%R{-xQfTZ(J^3on%i(L1}1U+-;s zz5DX)mpN2%LA=BB@o@ML=RKGI@^^eyy>=N;6J{LU&lV(BRsgjJ91dAzG!iWABj8UDX)P) z@J;=kpOPo}!8bfJac#ct@AJLluR7!?&hu-(JDj&}w|>jpZQXq5{-stQR<9eD!*rcj zmibIpKMY*L!^Lagg%_#s;UV%$xG|bvs3Wll^<@6eALDn<9X(d}d(w-#jk+A(7`s)^ zJo=2jadBLph)2;ooD?tU3%`vWF0{V={nbCC?g8h6OZPfFD)JobN8?fOcDweg;(_Fh zZ{Tn2DSmXa`g7=u9r6o(LDs*lPw^wTB(D^I@pF7${sM3L7hFxen`!kr=hC}}db93t zqF;E6C$mp-!;|q(a)Xl@XQui#;YsAV*70k0%TCxc-pfAC$M3?E_{;J$>LKzAzss(M z>#Ns0yv29r{n=V~fCI7TlU09?Ue4CNcyJ!CX6NdD^r(JI4tc(NWSws3Jn0wSeeW;) zkCnRLjs5dG0I%bB zcvQyUsC9Nc2d{`c-G{r;;Vl_|tm>Sx2mRZN)z_ik9)7Z?^?__wUKzXH*Ytb0&eMpT zor8D3?tfG_8tzIwal&x5aCAXrAh9dA`>2*1@?q<|E#zFTs<@`9YnN zV;z<~M=wjYUqBxVT!km%xb@A%3+G5I*SQenOm49&_lgeIP3TKJ6(8BBI4+I^Kabb> zDw+RMsDPO=tj34=5 zuf7QRwK%B$ljqhQmYSW5@9sMuYjw+&$}i-1@%Qn%hf&@t4(f|g=i%?ee(|8@8GpZ7 z>m#wZLv7uBU~lk{9K=obOuv4YJ@a?Gh@FhehraMGcA`!$j;g9@U{KC8NvElFCRef3fSDvnJFW%uZ{6e0KzggE{&&l6U z*Zy?#hv(v;_zO4S13mz^@d|M~^51CjLVe&`M-KcQuZD-}Z}L8R(H9{f_r2`gJk`&| z9rY9SA9Wb=&-?pZKi*jJI(AF%z8C+&ui#j|*L|86c_Lid;g32Ay{JD#Zu51Ypn1v%&2u=9qj&cU*!Oy*`u5?8x*va!ejji9peL#y z0DjWDyp>+?N#6_S)d9p8_>=Ei8;Q%0)j57}Ab6_}{BrG&HV%E^lk!3JeDZ-~c)Rb_ zzY%}g-RdDH8?H{*`6qawbp$+9TsBX2q1fSS7k@uk{X*&(-VZ++^e5m0_$_(!FFXWp z%V*^^!+x>Y`Vv=a-w@oxD~uD~GEseH;x+l;U3q`I?q`Yo?HAard{EwsFOBBEiOWY? z-RV-@V~ej^r&jM3$KjQH3jd5e4_7`YA6E|%PxYVY{rk^2w>(t`)b9D;NH37z2atm*Z!K5Ex)^1`?C3$c*@_0apP$9`2?@7x4iOV z-FwA;$VZ-qmu5a!>YO*<%g%!vn{EA3pYvL+8}f_cc=33hcdCBEf5j=h!n&C6;z#T= z-!`=@99IsAMgR+tNxFtjmlphhi{8(cwpwgUj3hV3;$xz#urc7 zKflZTuh)Ie;we5bj5AYp9vc0^Tl29#0{`V-{1gvSkA?H(NssbM_+y^pi~Nfo>C5-3 z*X8+2;Vpg}`P{4f&fqydiHC>JPZi$~ALYyBfG@Fgd6WDi<6o_NqTvSK68W5N>p_oJ z-NtjcN1pg9zfhkcAATBpyWiHq2j|%E3*+l6z^~K?@a@QXyUyjnm)Ji%q(^#@@8|uA zk^1dyk4KRkzfe!Wui#;q&6MJcT{OTfABxBp>0Y!IPc)>6d3- z|IzbvwJ(6bWIng*Tt52sK77U}<V(!S z@rT&?**gD9yda;%HS0&$+dkZrEl=Om?u)tKv48deXXG#B42R*TJeNP>b^J(tu`Vg! zp?7@P@5V3IJ2;P*;`teWwe=saRG*%FP+U_dVL$K_js?%pwDsBPvd4_SvrqBEFZjGK z{K_-!zVEr(_nr8qFMX-%|FNs7b`H$#;@jkJ{`@!N?Cd9ex<7Ed?w=L!?rWBJ_+9ga!aO0`kw<~Uvr{85) z@(b}!Trht;Q#_?Fc*0-cXWrkrcjpBkc=nf$A8Yye;lgcx$FA^Cyd7UMPk0i1J63+3 zaoo=$FI%m3N&FxFTK#`NujB<8XRG3}x{&$6D|I&G%g5Dk@rr!!VvirH7r_U0LVUwMxP0%?iaYGV`}mkT zp7;)j)dBd0`I8Snl8ZnsyXY;$U|JkZDm?!&`N5JbmUuox@ILFd?jMu7s?>^D$WA2HwkMeNIM;_sKt=Gs0#UtO#e(=xu^_f}^5>I0f7pgxw^EqF2Km5Tw zgWJa&?rnAChX2D`^`-dxMD5oO&W|-*9j|pF_Mpz`cY|Yxs_sOd>g{-S-oMb+b02N; zTyJr9q56^JP4qij|BN3^_T(c@kw1TA2khVZGtuutor_2><{4bwU+2=x`>ZRmbADu9 zNjwccT<_Qq+<*`2zpT|t zgTKLZ@)4JVx4Y_G3w%Hv$@t>STHULThqE7c=sCUMMdGG>5FUzacwol4Rr{UIN4$<* zT`63}+wop;#C-5r_|H$(QSo+oqOKKr&R5^2{#$ujes{i?FUuF`OJ3=_@aM$SLv?Np zT$Km0e{m^)vEL7dr$Ou2wsg(`Yw27p6WB~ zUwwoBiEG9uPk4e4!+HK?p82k;Re!@9@sRNL!_`+DzZk21K<3X*#ASI??D?@eUorM@ zs`XjzoFDzWZ+p`h&&(HZ6gS0X?~^}2HGjM-dU5W${cH1W{MAkzSI<#jVu#V!M%5MB z)$s3*)xARWXr95nsouH(9Ke^%6R+S$-WO-#r}ZPak?*}#_w&k+j@!2WH>uB<2Ih$dmoRb8-s~ zOx5`edH-}<-#k)vcy)&0{N>t*1vfJOTIC(|9=|(K=SRVRbx89JPdiupEZAXiW1_7K z?5a9p{AjDrMd6R~U-OLp4DPSY^CzkwKJ(eG^&`AdT)+>>AAVY|@qXqrUi?3Pu~@u? zUf47Ir$_m_yaQgb6Ym=b4vWA1LOw!n@?!NIIEJ^dAN4f(ySSzwK%DZs#=)=5U;QNZ zuwD0L@e6e=?`NF7b)Ew}$6GS~iRwo(PUNt^_8~_8_8*-p-YAX-52tHCqdEp&gzw4Y z#2tE1yql^0ww~vA2lx6}FQYH`<~e&~hwKx+ksJHZ`}4IfMqlC%JW=nmuM^JmcfSkI z<+FLdTKfdWDR?znSAgw{c%xArwTkamEh1%B- z=kY`Qgq`5Y8E3Ng)v{;&A#z@C_IYRI{M$i&hCKPBd{*D7{DnQxJ3Ch&mTyKcONF=m z6c1;Ia0YM0lk;7Jens&J{_{tAj~HzdE-oZ)s7G8It&R@b?)CWf2 zXNTmk9+L6hC$ie=!{e>qb+4m$aZMcYUF0DD6@TF>-o?(v7kI_rhxy*sI@dbmT(A2J z;J^3tT{}Fl?N1riyLJ40?_BXuaSETo6Vw^xmGU_Gi@1!R%d_xv&*7DEKe&W6S zH+HylZr0-4-~6*bdZ73N`@v7(kGdbeZ9c{^|IFuNrwWc%7RE2lzYOw*H7Gz(ew3=ZVY5YrR0c zfQQ5UYPGxY)FI)gdIFqRr!o${r#=S%)oq6TXsq`6vIqVmFT)Svq;)jwM0lM%6h6Q!&-t}^ zMh?4MJ@8cRZ)I=BQP=WZ-T^*j4cVM&)1PTIPA6&J)19)bZddzCq6H z9AAa!;;A@=Z^&!>E;+Mvek4Asx5V!TeecoBeANTRi`dD%mUj&Ho2bw8J8~vZ{29Kn z2XPb6S7(#A=DGV}57l~;@!13Wgb(4pPj>R?yuWiU(bMN{&D1&nNkL&^3Y*kbiKuwtqx8O$H(cqpN?J0r|2>EJXQNZ*$JMII6K{o zN4_`t-Ic2Qk+b@I;^v{^0qP|DF5|4#elFj|PxHH%>O5ZahcozC#&JIO$>KS1fWMFr z{lYhVPu#~R;f#2vA3$Da9h{%yvDRzM-}|F}gjZyq52~L5-ilxNNuCeR$tQofEkEK% zaFzYUkIuGpMQ&IBEu7>p))C-y=6SFA*M;go#4Grbyqn#^Pj!AcqrSne#4o%z{<2a1 z3G51<@H=wmkK!zR#zW`@Uy6Kg70>s(;x##oJL04K1^$p5e1M7)RTADJNR}WV6(wY6%4qMLi%=275C}OCW(zD?KGW$)Fje6U49w zhzZhPkVytGK(x3u6K)BE6gNRnni2{K8-%JOVsorxREdv#J@zU8?PIq5yuatu-fl)E zeg6FJ_gn9?p7pHt-qh>F3(w`_>MHrJYvup6v)1`9IH!N;E8|O_&<}av`HkCMr$^_A z@A4Y_iI>!2#25OOUZuCg&x?B?zsA$gWB%*@z|XU>PS5)4^JBaYdyg0%V>fv&ztf-K z?Oweb#R>9$wv2S#7zvArwp8xB=`Kjxg z#7*-i@TLx&ykKk8|F3nw9y`;G;kRFActbqZ&){=W?;Q8J(?9GceucMRbscZ);GV?S zT_5guRD+z}Vj|LeU6M>}+axBx#H z_oEqm8n5LzGU-F}Q}B#GwZm?na+1UT%*dMXieJglCe~cG@k*B~XdnPVC z9P2LJ_qRCb;APR1F>g{la59tlR>$~#3Z>!(bwe&|m68jv?)a&RI zbz1%v-n%o-$5`AmJ=QnU?P-5;j>A}|r=Q{@{t>6}L)v*ZQ$JLc;3dS3oQPtu>-7f+3QaJ4vB=biQ~e|Mk20D!=<>7Q0RBB-xD)SzbpWKi%$mS@KZd8{BR;U&6z9&-Z40-Iwv8 z^#?dHUoT&Sx3u%H`x*6cH$AUOM0P|IrDHbIQi~sOjgku9Hb#GwomFcl2=L z$nH1!Ab<2->Hodnmm#lQj;EJ;4g-BfPs*E&WANa9qVv7y(fAs7^|bWU{@jC+w{DF2 z)9Kt8e&l_4V+Xv455;}Di2mUh;kQ#g@5uPVk2)=WFn=eH6JNwH_@uY-vv{g5=XYa& z^B2#?{`UuC9^rcPDSiaE;uOA(J#upWNxXO7Teh_(6P( zF5POp7GLO!#Dx=Gm!chdk3Hqx`f0q(Tg9H%_wIJxh<4~Dyd)0dXL$!*t^afsUX9({ zUv{ZHX}scJkB2^Y5A0FTdsnYkPr(0low%IeJ?_3sIMg5ORrEi0oAz5J-Z^jcUF(hV zJN68ocYA+Fc=E>Z)0fo`cwU_$?JxFof6c${wC*kL$nSiwcp6=_H}^d6?=&BYemL1Y zT3nzT)t$mW*Q!J4RXWyq@prmN9_Kl`(V6^9UTMB5?SJb1^7t3u;wy1VT+4Xvj`@O1 zW1sJr&ZDWfEc?-B=Ks?Q)&H#tT3$EZ+-I%Tu@91H6qaWZcc35B8 zXY``$@wDT+!rOP7kK;XdgDZFlKTP|()icebi7#|f@OHcF`Snvf;wC*TFSCAz{=pCG z1LkwtlMau+*k}E*`X4|0Ugs_FN9`v+I??s~_($D_P7WTXdtK!h`K~YH{KJhAPq$Xq zr)^h{c^|IyhklSZu>+mJPw@jD6Q>fduXX)x#&NobE`GFFxAm3xF3-(hr$1N6e&nCO z(O2S~`h&Vt{BeKm@A$rTmGtv$zn6{*4($hVAHl-U|JGkTdH7czbls`<;hfH)tLdoZ zBOkl3%DiOkc6sRM8(k-$zJ#~apSAA)ivPatd=0#b*WyliX1b5tx}A*UVe8Lu3!l~} z#6Iu4&q7?oZ^7-xTwO)|Ji7Y3>LPi%IubpG-{}N+rW5E@-|Kn$d9U}au)n;IuE2Zp zO8Sa_@fUdqeCm(5Ab-IR@NC`$p7Z=@?3cXtO+J`$d^~XYW(Gg-;JffG-6cQ855`5E zS)N6Ask@3tcnqK8F?EB)$LW43x>`HpxV$O-eA)HM;(~sP@7nRZ^dX(VUoyVi-A@sG z9*lD)uk;*OaVLIpw&&fc&-*TR^SgKh9<)ObWL&mKJ!+%4#Sgvt{A9lkhvCnbWFUhC)i}&G{u1LJTGR}u_-?aN2Z}@evZd28(Ua2`8982a}8m{&@dlXCMB8XO?m3UV|UU{N~mip4k}>$anCJdXev?$IKrYUpR+D{uMjiU%7we zM98II@HI7<+yg z`<15i8^kqwfKH$r;Td1SfAFwB(@%Ktz2XI)r{An=lJAHY;-L5OlKF1D&Cbz#C%Vr_ zd^GOC)%mW+P~V6S`F_;%&ou6_uwI27g3l*CKSce_II<@@ z2mg=9`{zg9;LLp4zh3v8J#~rr%jK2%qsL=?v~S(C11ur@*v}7zJ{*A|L`te$G^^WUL*dp)%_;&5xj)Q_%EEZKR*gTPwN)c z6@$Z%%@g?-y(B)$@8Ds%E+mgW)qQPv0M4y{$ao#h@TWQwy%#)hj(M(6y~hFX@gsFS zx=a3|4y+!+p24AcsQV+nT9i=B6RehB-kqb~P<(gSoI{RxN0AODLN z>?Z!oi`gyX`?h(g_+=iSJ>@BQ9$%>+h9|$2_u$#M(3$KXKRTX?oA_MaK)m2D)>-L4 zozI@(y`N{|j(klVTwaf%?zho;raG#AX1wn7en56MF4|9juJ*nX``_hj<^k~o{ll+4 zXV384QO_ZY{09abMQpTm8oy>Hz7_?XI^8zu8~&!>H@tZM_Z->3{wR|L}|_#WnMo;#d4} zy4O|zy^lZDX@kQzqn@BY=jZg5dfl>Le;)OX7c1)|4?ABY&Z?`^z2fq6UFe|u-Pn`A zBwx7R^K9vS^#u7cJtJ<~|Dylm8h#L8*qN^8@Ayi6mHxMGA>(2lsq?O%wSFakF>k(# zAO0&Jl(*t}@h*0-PW9~Y-y0(@-tIhm@O-uBLB%gljQn>Rm$bh=?0I|K!?HLpc-*6> zt_A1fBOROmOy}){A5M<*k@kAd9zVkK>W~?)vn%IpY_!g-&ck2CaqZB1^oh9Od)bY@ z;~Dx&yzrdfi~WD;z9)QQ+|5(-3%UhPUHqBTn{7Pg4;JE9$wJ$!V|LgPRJmp{}Uz0zIoAMO8Q5~3Gh@FqSU!Kl~H{&Rd)A@J|9`FFY zN9TKv|HFG%t4po#5;x_Q;w&77uReGGweg}q`KfpTpYTk-!4;n2*ZJPZGkTAHvkt_# zt23mXqk+$9e~0>;dJEi&7jOvY@?Z0q-cNt5li%$<1@dvYRUe?w*&#SN?*6!CzB(A| zu@|`hx^DSW*UzgX!83ghKjH;GrY~>D;;ZFxKOF1ZPgc+1ANoYySl%Zt!!tj{ z&*}`~FMW$YwX@v+oiXouXXwwZp2NUj*q=TRt{!$iSAI%|sK2d_BfikjeDBk7Ue@KV zi=!L)5xpUg%Q)^f55;fRSHl&4qeJ-1vi@<-_O)S$AICWxdp(~=T+8pe7wKy69nSOh z*45=B?40ktH~0P8F)rd=-d~*a{A|n)KpT-aDP|qeJMT zynns(^6L5Wi;NdPb>7rQ&({?<#ldC0bgT7bdR}}{@1jfPzv3EP;W0Wvd{i&x?{Fet z7GLloUZQ{C)4ZqmW49A?^pjXNHO zTRboB(?xhd9X|G)>K@{NCDK{&i+<+{F>~rDdLZI^)-LMRe4`(4Pl` zC%1b(lK$g|_{D?fYxJsiw6DHLM~Q22mG>8Qka2DdKJnc9vGdj5FPU+C)O#((i)H&C z_5M5K&OXcaqBmn+ey8)l@~P;P_nqgJ-=#k_F5;w1Nw=V;=lVnmsK1z{`|soexV)=VOQUo%PWgv)j~+4(ZMP8`A8>XYKNcpAGs9QCgIt=Ea~>|nfn7rnvX^Sh^;*T|#sfOrIN zba=+s{^)1p+`MUi2k+7O_>Gec|K$dHD|iQlB>;!JgiS2RKpp3l4voX~*xz zZfpHs{*M3oi})M6sq;+hxWWVW0lloB(vyC7wg2W%;h+80hvmP%R~#{pbh~&bj?35h zQS|MnneU=+eOK(TU7d+ny-$zHYw%n8|E}je^I!dkfAtM^$a8fS_azpkQz;;Hx&JMUHp!h`;+8!V64dhfG~o!uL9xApwsZL{-w zcnlAyS9qTM?$ekT`>ydW-}|WkLO<)LI+8lGIL@!}ygbP7nvatYnum>@4`%8l_>Et~ z4<0bTAP?n_bV$B;s$0_Y>`xEVZ`K27-*~AX(v!=)f!FiC@N1z8U;4&f^^CQ>8yYjXLN1F`xUa=he&a=xRIzhjefHbG!K(J%ERe zyE=oqG~N@ZyDId{Kd_rf^Ke6Y% zo|nS!^hbUHSNSgW@co{%q29H;E^fE?l)(f4qU+#UeiWQIx98lL587=0qJ4H&hl$R2 z&(5@dn_u8(_|cAh+;`DG+Gij72j1XcoxykM55K0{=>a+!FPRS#7w8!}A>(_eaSEU0 z{oS71lXmWo{a=rpr_(>-$zRXtOn68;N4=jVb~viP$V1hy;Kz62NjML`-R^y$)^FhN zRUT$fdV`(mYI?@H2zpW+ryuyQ{>azZnLmmz`mbO3pZ>vP;eo}zh0}lc&;RAWu-!U2 zz0H5=4e>&|>hN$#SIfWXCF?h=s}V=E?|t@>r~58>vG^O_cs%&<^4M4Pr1ca1Uyf6! z=KPU;^apO`kNn7bC-$NLjhFt*$JJ@ovCWg3*Tw^B|LWKWy3>7X`L4C0TQ+*02|uEj z=w9_k{+{1G(R+gEI`7ll#xechX#PlN!Yv(w2cmPfS|_0s=%{?xm#*JdSIIcK|NX&O z*Lr2-#ox{0$+(Cka1K}24aTpXvvjHRNA$CNM7;A{y+xiSzKA>G0^LQ=;7Poc_g{|q z`@H*(>1X}KZ}>L;d#?9`_%3x4`kZdmPJVa2`wq-MswdEC_(UB{-iP7uxZD>d+T*y&G>~pPQJEkXS#*n=12U?b2yj3 zz;o=d-#Q8XljjFre`vlEZ-;+Q4E=eh^)b3G`r&i$FT)$+o!^xgglF8(WuLzLo{qae zPJ9V(?{?nD_^LC*6@AMN*7NvX{w^QXfAKy2Tp#O}ueSbX{f0Oze&J94h$r!(_S4S~ zzO0edNo*r}JaY3vY~d z4hOwQOx{7Ci<@+2+Hro}dhZRV>+odS*=*iHchMVom3`PvKaD%Pv8VX8%D3vkX@9@@ zsd=vD_cMn%s3v6eJ=31+x7o+yY=(tFYt^wg*W5{;-)-0_BlECUHBQ_ z$~)A%tRIF$dd&RJ@_g&9o;$J3pU1t|2|uVCn3pvFh$rz6f1$(WgZRh$;vGGVSJi*y zW%4P!LHCB=_J$sw&K-q^jMvScmnd%%N7Rep!FP$v8Q-byXP$)~z$aJV{|Kk~2W#+~lVz^nK$@4s#xChZ@L z{iN@DuD?JvFai0Y`pLcor6#46YbDfbh~vL>K^)OK91kXo9HDvQ{KUD^oF>T z_uYGYVw|%yonxS0E&hsY@P?n^#P8C*@`ZfY=Wo_a)93PfafE*M96zgT`FH*+PKhJ= z-U}liIotdAj4vL8^XQEa_2Yck?#MgNj{Ps|jm!94yfeP=FK>c#_~+N+f_^T?i)kN0 z>~^{Pt;8d7N<2y(&z4JYyP#IUr+m5=?8e@@8T~!i#z&ne4{sBSLcT}e(L@j>j~A9eHVZ6Tpdh2 zGG69G>HqX|y*f}mL_g_`<@&>!uJ6T%_=Jw46Y_jIhbQkJ4qdl6H*jzB_x|*eeTY{( z|BLs6t7knAjbH00-N^6gpM2NxOx*di?f-n7=XtIBtmz7MEqaNcrvJw?cBWhK1Kt+* z=>+;Y&ktt&QNABt{kH3HJm)X+$BfJU&R_d3yoVpy8IQ>e#HnS!TOaEHf8F)u_&@l0 z-*e>PP5fg2Jij$p=aI+3bNp`d6Z}B`XS@z(@|yV3&)?iT7Qf!?KAPC)cGoegV~8*C z3D58b|Hd)nvc9qoa#O1((?@?v=(oCnWOdJd#K+H>^^bp!PfcE)?b+jI_pe)rVq z=h}$B`#nb`IN9uT@AD&dJo*g};Nj?^cU|WOpZX(?XS}Yp9_zc*A@lxW_vxrtu)p`! zk>pwGc;cG*4t9of&*`qTbFKM;{5pP0Z@=z2a`bTGk^7R4dmiAj-<>SpmU&5C>uL8Z zt>&TPue=7Ysvl-t4y&)^L3k#3*zI|4{4RR((wq*=`)|j3p7Y%&2v^~a6Xj=qYFzMG z+FzTCgZfXW(IN6&e8tZ68$D^f_-X93(fpB};gfynD|xPZkvxSS#&7Jv-{Cp<-|D#^ zzE>VCF0dzkrOu{5#wEDDSN)vtRp+!`;$hG2q$lYI^FDYRA8LnA5I5;Ycz|>B{;}J% zj!T|s9w+ucRXo6<`7gYU|M3qy`(FMi|AL>`XRqhZ$vYCSpN@NB?8m>|^Dx;t@4uU^ z;?20TPk#4@))nzEJMee)BK8blJ#YKsKK-^_e^zf?oE!UfAL!+=&gwzW6Hu3fTe=i} z)Oqk^bj6+8KX(4qItg8Ee#iInJNTr-`Cat+jn-|{Lo!}p#=Pgl&Lj9;_=$b2Z~4%5 zfZ|v1|J__3WZoPDom?J7XNFf_&b%-0Fz&(6Vf9;d^~av`BTnI4bpW_hH>T6z zA>U;`@2%FK#b5C*{`kE0qGg>k<+J8J)k&81=V9yB?5WNvAH=J{=i^adTAW+__y5wr z@Gt$Zk5%UP@FnAa~ z^Zrk*kI^}?&!wJ+%&)B@!iVx!c=NsTO>sZ`Fx@K+S9mWt-Z1)&*cU31?$7vA>XU6zF6Nj^6osh{^U*XQ^x1wEMCQv z>R{@h^i2AHYNbBxd|KPqt1aF3Z!+@8gHy>R@JGMty^w z@rmDs|9tQ3nYbe_P_Iyz@Lb#%2l0vcqCeu7=kil=-}lNx*+<<;JyV{D2j~qrp|`_J zmsfcHX3qnkGI^xvzw&QyR^x>@82^3T`wi)KaYjCCev1Fny}p-z;77~6 zbguIP@=E+1zkW38Y&U!EapKO!@_hP#V&o&2x_*p36R)RxDAa$%N8gM8*;AgVeeq8J zJ-44xeb4x&o%^k02S4w+pUXT>c;o!A!_GLj=T`G^`ilMKzwFFz>Cax*b>L?@VKpwu zPt}v@EAfKP!B_k=eDz@_uZMHY4D^;{5%wpNKB?98a=?d=+{6#(pSLx5&-t#Lir2l7E?gx22)>Aou^4&M{FYvR96LFs&=8y0!&+=Wd=iAwG z-EVO|$8Y{u|HYsCCmxRP-S4>>;*LCpuEqoWdesj4>36lSzNc;(o?PtT8tb3cA;ksl z_%3;({7YO2KV0nn7k-3K*ulIZ`^%5yv*EF4BmaHf`7AtuZ?%I@)Jx?% z8Ta+-7W!FSi_Sb6>(-w1+)nvU>JK-2-a`8MrstNV{e$icqbvBMIyv4mZ_aM&obZ58 z@Gbt4htd^vEPkd3tVc56fq$$^kxvCz2Q&SY|EB++#=76@b9n)NmY=eNJSFzr>plxS z8T%a1;75PNHTu?giC^#u|8OWj&2#s;{JQ6v$cyp3|7Tp%&sRN13t!O{vCp*5ihd67 zz3cv$^z(7^S$2?Ds;d~^@X0S-hY5$C>!&({-^CB&Z0vbBzSq4ByFCvUZ?glPuP!P+ z!dvvxm669?Xxxb%_Io}|?6%nVva$XD{-yuzR@Z0ZVZ4V2@Qm-ucpZ1YKmA5;_%1k% zeVn_pIM?%6zx%tluI{zYh9~Kt_^JDmr}de1BY$TfeCv1lUEX(3_hR4mfAi=5+rRp+ z?lq4K|J)k!)cHBjI)BZc;pg|=kBJY}C6@X2<5*9-SXccuUQg%G2cM_AE=7OLo5%;v zYw*+Hb8Swyv%k8uynt>A-Zpx!oxCPEx!(AQm-Juz>I}x6PWC>2;P2_r`Z$;J%CP5d zamc^qeRLW;g&*t>+NqwA5At_9M1HNGcvzi8oD#p}FMc=e>HNLA~(W~LHyFD+I z&QvFqKZ;Z0i*-%%xY%bpcXt_AJ0tIY-}5B#cJSc-$|p1Nk#3=j;DP>E2hbny!x0@c4i0lH1k%*9pA#a`mp#5&+>Qtkp5d& z^QAnW-@ViI8+0;0k-xwXK8FYTQ2rP@O!v$1Uv`s^hnMzyeiuGZ`*-L3Aa>jBJ-@~a zKUj~UzMA*fdk$6jWTSRgpO1gpr}n<*_{rn66P(=Zy2sdadu6@BcOzfepIHw~uP*2B z>VCVO_m_9bFW^Mpw5kWxixR)qn_n0gaWMUSJQE-Jd)hzh`Z0VJ{Gac={|L{|MqW$H(Ye+x2hwlYQ7zormACr*VfL{(@($>o8vohvL3GG~Jkfnd8JFX655>h1e-B%yGVg%rmvMeP&V4;G za68Q((TDO={6JTyor9J0w-3kqlaIwGJcy^U&wBMIym_wfO^3@9`L%kc{@@e%;dl7N zbNqu3<)?T<+<~`c{&D{8z4EO*j$bGKzV7)XvD?n@-{YQtBK`)q(>SsZ9I6}pUOGSc zU!8B-?D`OT$#=0ozl(i#=kQ=2InSr_nSB@h7?+Hf`{}NC{VIJZf5#{C0(w&2o^Drv zRyW2c@?!chetoj>5^>BDgf1E?L-Fabk z9`n4`GwVNp51(9VKElp;0Kd@*8JC0R-SNBKu9Jro_FUx|c9W;`Bm61vg9mvB-cJ9& zj5^7Q;$Qxi{_MA&NteR2`FeT}-uy0|lX02!hP;&@se7b9SG&H2UbP-T9W{2F>ecci z_N34G3!E(T+j{Fo>K^dJKI%5&g>_l#PI>>?Shse1&Ti~1zjMwQJ&5g4L-@>b&rC*hepoyXTs^#9`C({XOCe2SfY7hR_gOb5ahK8$@%%;8Eu zeJ`At|HW7G2zp8VL|uq((I3y{FZfMdgBQAmzr%m@Nn!Ky4v+K{6apc-V29t1#jAqU!R`KE8!~R_3Q4}fJ5UhPKAGd>H1i9 zh<#r7TtRh-@Yqq;Ig1P8NN~G3>MC!>Jk;)79U$>*v+F46H~FJ_U~s$DIK~d*g?yPV z#h?7bc*)1%$2^^Qx*G4`B>g-&M{OV!W5mo9=Ie2Z7% zUwnjzWj*<2#{T9F@fH5ZtH}o!^W1;$^*{Ot=cf83oajGZg6Htn)|jtZtL{pF&i0%f z`D1wOLh~JU1NjAh^SkNKwEsmsjUQbZdgE5>1MFbF7@xoof1zjKS^jI>gOl~@D7@!) z#S46^9+EitYK9MEw@W=gN8XLk&7+Bf@Wu|}0^Q}i;40rcohz;`Y97RVX#C|#_aosw zaSES{o5okZW4=IrKtJIP4#hP*AkP&~J;%@T8up~a#Z&r_PGbkWWWG`!sty3>^s~65 zPNGgOUlt#IFI`9f!#O=8UWmWx|5RV{zW5F&`h&;J-_glc^-c^sUJJ9vy9rvK>*{iIvM8<%=6fq6`ESv^YL$Da5Z zzeR`a_1re`F28%cat`x!p0j>NZ#?LIot|r-ZdtaQdnNX}-xJ={&CrwLID!x5 zgLECglc(Tqd9gZt+W)Tm9OZrVlK#j$;7Yy|`yBQh8|{nl;wHc5r^baIz@PYpU;7)J zn6I4Hg~C7k@TQ;gGCBkg;~8-ZuIP~1=Vs5(5eM;b>~qj_alJ2o z#m?64-01#0@kl(4U!3YXDDeWn(e1{aozu>}IiB}j_#CgogYlw==@Wi!y!fNI7JIIB zy}kbEKRX-8RljBj`YraE&U^R0@J4sBGyjsOs4J>__+5D-{xm-o-2T$Mm3|Q4#mCs~ zRO|odHPm6`kK%jme|6}|i8uH!9j^U6f82SWeD87ZX=Q)<)_19A@)!F8;N17-{b`?t zaTnL*%d7e@?L6zc5j;#^;ZMA(KkB#gMD+wZDtMdjm%&%T+m)eL_g3oj(|we1E+5yQ z@aLoEBkZ<{li+7>-*z>6CtKmmJ z8=Rb8iL+O_9+Lgj&idGAu{dA$-}tW&|CRs1d3xu@ev{9=hmH>6r^cNQNk6ZT^@N{$ zz6$?}pWf?wc=Ju_40ttqU~};Bv=2gEQGTILYrNV0{XCq}?eZOYDE#nuykQ*03wD#I#QwX*6`quLs5{Z& z>fv}sJ8&hwuygd}-dJC8ZrtO%(fG~|#+S~Q*Q7uDoyVsi^8B#t7-NSQjXQ8FU*LD) zw_9EB1SfcyZlt5wfsWNrJiz|?gEx#9T*b}@GxGw*U4PX1+0D9NIF$F{2XzVY8ZU@P z>S^-v@RI!|?^=J;j(Dp7>LKD|`hQd&mcQfSw11}ix$v9%B!7=Rf9}1I_=+9qD0U8h zPIMhRy+KFC&d1#soPHkm9^u5bJDqR!J|4?Bp6>cXb%5C6b^95=zBY8!=`o+a-*rU% zPF_sUg!eY)>};ImS>mZW2400jd4c*Ndm49qrEV#oGVbc7>Xvi@9)nxsNax6#=pwq* zci}fWjZVO0>IUqV?|s^RG3rRss}JUMS8(`ZCQlS+@nLW>t!GI8561kg`*dD+zYlxk zD|m|?w#wV^DSyO!Y2UimQ{Bh0jH`p0ILQ8R9=uKb>UZ;e(qrr#{7?7D$W!o}@1gVM zk9Z7jmvzY5p3|sKC|`hwv~zOQ)jy1LRQ8J7RbIj~@MFB_M)5*^YTZTNpYC^}8{sE$ z>Tb_hp`$YHzwUYI@;h-~JI2?18UDnFvCsXUZ;bcw44mk{xQUdR~6#IX;9pg);H(Ct52q#_3mf%zIh_?NIl2z!mV+U#~H`yjqQ;KJs$H5N3BQUVSH;oiw>uY z#QDj|9JYdShqOt&CGZ$&O!NV|HZ!B@tn@*kNAon6Yq>;+S#9pJ9rG9;g-%c zF8opbg#M9d1#h3b?w4+nFKAyo%k{%AJzo@_;YXcTUL%jd^XikU@6!*7*X~=N*6G2& zJbHOv=|<0^mXByZd^OFd!!x{@zoQ#H&$#fHsSYn+;Jg7C8qdUTZ#yq0P6cn9bM+9vD}JfNu%~*dIHI1A_P4vAPMy{~8os3~ z=o$I}zZrLW)jUP)yw~-g@DHE-I`&-ae$V{whvw1v(>wxx&i5Y9*n$3}WAS|Kc45AZ zpVwplMV1y-Qcv#*VUGb>v?lLaZy(;`gUY7T_ zx^Dtb@W1@m{84!0bMsv7&Pb;`%f=_lMmAKaH4(v=hyfgKUnudcbU%$KTqe_8kgn% z{4&=0|GMYp#tzSVuf1^;XXy}pi)ZK}{a?Ha{CTzK;K8AI z4d<)4HUBP7iOcHJ)?KJm$*mA}iQ;gg-sFRLSor{V3(ozIOur}Jmn z*}C`O>Q&DfGe4+5;*ND4?5S?EYB%~v9vy#qIQp~5hrgZ|y4HOtct$+pck!2(-3P}n zj2FF;_MdgXp1L@+*7KCKPshd%PiFiM&eNX{z5kBg@N@96)_Owhu$T`S`8d9!C&foPA#qCnezNPh z?%JEDc437ne7puF}ndvM125U zbqjrtulS34xaa!AU*Ko8ef&@Fv8OnK|BWwu(joXwz90O5U%!Co@bhNxqlX9Wh&$@N z{4w}E9_Qpds6F*F?KqeCxchwN1?o<8k>|nrQPc;XiI2V`cE__0N;#GMB zy@4lV|AUdg-0FR){3Z5ZpR1FL7xBl_JzrFQA%5{+zboI#_ipvvMfy$NM^Dndp8H+? z5`A)}`(@1c!MXaL{up=m;iqZm`rP=c=g_Ngl6E%6I*RGsOFTe_%RAJ&V&_NWoRFI zZ0EVu@q&k=?wjVP_$2Y@-Hc8UFA`rammkFU_}yO5m-8IIv4i>son#zW`JDdA`2N^) z4DbV8NB_`u>SnRS)!~mO4V zT^tdwm&fI}_dd{L>RS1(FFpSsKH)@OZ+$QQpZImV>jv2eZ^M=E(tkP)57P;FRXgwr zSFz`t&OfT>;KTf`bB*ry{z~}A&+>8KMUTZ_K6RZZKg#$zNA%e^M{7EFn$Co0{N}m1 zhHvS#@YTt#zmj+0ZS_*$6+2izbG7Tw>3R7Aex?VEV}AGTm=9X-{5715gR%e1&Ub4c zAF3PRZT{1upS=a_d8@5HIJbD?z`{>!gde>XUP-1?07*(c+B*!V8qv1j7!BF`A} zQ`$E!;x(MJkNOgwneTcr6Q|^H;!F7R&d@E>{1HA;SHy?%Uwj_FI9cANLxS7Wy-(9T z9e$2|*18TEpBu0E(f2cT1LNYk@5S4}!;{wc_|dAapflq~FM2Nt9O9+qI~PaYe!5rJ z^YG`Lu@2-y>*4A)^mF|B!&qPRc6I(JjW2e(+u5Lhv))cSdhV zSDf#8bn>j=aJTDZj0-%_X?R%P9o!ytA2)ldW5_Sk&-*-qLsO-rf@uB#opW-9GrhkHydt)AdZ%#j}bJ7F&mL2#DzY7kxdVi~U!GGmJa6&hV zBkW*5g7@>g?;7{%h4{9( zqDvRLd#pRsKHSn9@*4gHCwPxN=~eBB%j!Au2=;^%@ymGy@Em@4Kk6Yr&G5N;yE=gO z*`FQ6cRD%v`7%=%GA`;@vGdj5mw|`9kB9LgyV0@uIqiHYKd?`}cX6)d*SKK6>i+1@ zg;Bq{H1e9CdTuS=@V)Gl=dZioRs6*#^tSpxzgEYVcZjF(KJa4i;;^1^1 zGMuP4rax1?C4T*B*ug%FGd)*OT~0n5d#eB68TL7|QpdR8b;7apan}O`569hq4L|a0 z@h<&*)%j?=fzK1Kt#iKD`5NmG_ys)Ulk{i5_nNW4xB#DN|A(3Q$nWqB{D`M?4!`5? za7cd!=iAi@;Th*~9nA9nM$f&}PH_8ZCa;u7z#$&PpY#SC`d#)>XUOws<2?`zu-*ImtMB#<6*bG>WA>&=UI4f zZOkWL=s5}IRWpu<-PgcR)yee}PV^HF)wQ%k$I1)n3VBw>@l@+MvHx1n`${|OJ=auT zzZ%!fJL5NcPrX;&3IEG0@dp3GhvJL8K;FH|SMZFN5`Wjbz6H-GuQ}EAV|1zd3|_+X z@T@;+XS;QE^H%&tJ9xl%MW5`oUSa--{f#@GNt`;}^*{I=4z(}8HoovFA7OvIp&rPd z8OPhL@2R7z7m1tr(EN+Khk9V_cDd^t%}3K|@Mhft-NldS9QF(kTR9y>RS3QFA&G+O#Fs_%tzB{?2!24ocS+3Z-JkRv+5h-QNC-j zU-q|t>p%L{e-}v>D zv5#QAc2n1aL;MNn?9boDS#bex!wFrN=j!&~_1+Wu1b*;=h|c4?O*U*?b{0WW%d>{QEoWGr!--i?W znSY5dd4GG32l9Ns=Msy{`YG2ss*D=xq-p5Pwwb)^|`oVln_~G2#_ligK6Fq~k)D4U;f1xMo z!@PfGoI7-5%*UPSJ{Ninuf}fct=qGY{uoDok@wvTw%GSF?&0EJ;su_}`|jbrU!5$E zNdA7dan1P3>y58^Mf_sQqvZwcv&=J(yPg()yss|7p5lo44*bT>##bJJ$FxJg(RJdT zypkTK)6_j;=R4h>%Wmc=@IM}))9^VzqSN5nc)^djneRH?duHhq`Bd-9f)*zLS0JEWh#bYG8rA$ES-xW=Avh5uu>$2}JdZrRiO#xec8 z*L@k{k?#}V@w5K3zc`4`^*`-j?fEBg?z#D5`Imeu{e0H*7L1qt9pB>T^yhZ%k53X8 zocFR-9q74!rk$0&P(D4cuaa8=Ys*_fGZ9BH&%)8bt@hAJp$IT~-3+f4J=gruka;Nhesax)j`t6m@KblA8UwE7U z(yQU6%UutX?>d~B2ZUQZNl)V8wDU{v?^8#m_t-&RO#f#bA9sBwKZS=?z7m(|H~xqZ z=`s4;_~HS$;-~sAPt5P0XkN)a^6|9urF8>3DthKZ_Y31a@dBUVdHq@TFXt{^>iNd> zzxUw^znMp%)8tvcEA~0t`4{t0vGbR2&Mi@g!H4uGzmTu_F7KV~bqt=mv^V^+| z5P$J1{^57(9(a#Fp=bDA+L6z0bw3(A&~JHvT4w^!sefLctEb@;c+T%SFKeUgvds4x z7y1*^ThhP2EzQ!q4Kk_zMs4#vkPu{44ET={f{) zRy?w9S)7trhR>&U+P*7(bg|dHoZ1sM|wXSPQe~vq!!v1*1c*(Q;u6hw& z;d|j({1O-FO#P<^)Gg_UjQh==D^91SpX<#-&2xF*_~v)F=Hje4g0J9H-r;%LKb-kq zd5ZC+=kY&1nRYgYznqw>OVELMLw@007rKHDj6ZI6o{>Gndr#}{@*3a8-!txX@3YqZ ztg95?;at2+`zHoJOy}*$XVux_UyqBc@W6CGk-VP%#OH8A_xdjQk9}T_bv3t#{@fk= zLw7sB2`BPmbq_idKN$D$^SN=JfEL!C&B9|Jgwtl%L9j;LSXy_=|tEA3wd@d#}`i^*{YQ=(#lJv-mH3@+0;X z?_#&TQ9n7^^P;_P-e26I_v8`yir%23*k8R-ynw^}u5%vNn+M5v*e(8kwd8k>W5Fd&Q@L5`>Q+_T;1$>GWs8WyV`m? zT$xwZ4n33ScbdP)-`|e&BCgNj+3F5B$J6JZK-E(+}dKdarhjZ*=u>?|bDJ;xZni1L;Zlq=$`*@8yr; zviI>M{3pLYG1iBCX?*~X(e1{CovjPvFTvHxIs3>L#CJU7clibT1Se}fXZFk-$c3zyT_fP%vzx%)ZkGFa*pZJn-xiIJN%X;!-&x576#T~ek$HhL+yZ_zz z;!odeT?*ZvI?4H-Q)e966aT=2-<4kkw@(HSpXhoRIQL!ZB;nO-^+$0ndcb_s+fjF& z=4<$!{%c>n(7yaMxOz6$Wo>sKy}U;LNEi9u^yg#iSNu*L%y^ksl8?g=+^Q#JT;7-G z;elV^w>;md{`XuRSbT}!StoF@`^dy2eu^g(FW%4C8K0#6y_Njy$%W%miZZnQ2dJbpsGu3(UJl#bvCGIco@%!pu?kBp@^Ze-(`BD7+rx9n( zn@{&Fs5jE{>PYFobB51Uhx2Q?NPPwmr*663`FH(P4}mNGs2y=rd^f)AY~1D7^bh?k zKZ0lbAK{UMmd_P-nR5pM^6K6am-IuiY(ees<>XJ>gXeM{%lhj6|c z7mN$s8ejH@pWu9_`$@%dcFymv4}ZBa^0nicyau1+$=K)msFxniFRv% znQ=ehsm3*VF8_ja^$<80H}Q;dq_60I{RwYh>v;}zVA|R1zHB^`aj`FZw|bJ!!9VOE zZ(=ubA@9E)<9>GN-px7vEnmau;)QsvzAditYxb1)(UZneeMYrQvQJ>AYfj0--@_nun0AMLp3<>E>6amGs=glBry?}*FvjCvIN)9vt|eqQXo>dSiL z>DZ@ydgQZbyZ%j{g16<5>JQ?SetBQqWH;|;T_ z`$;SY#xUn;WvJY-|&q7&@K9zaeO}ZMJ~<{80T82ohMzF1<(A# zd~Vu#&~<35{Zy}J=lI=b_gB*4biVpI{s|u3$NjeR*TLtbp0f%+>HmvSXS>_`krM}h z=s7v?>3iV>&%>ekh$q7*husgmY6tk&e|l_L=WKMp0N#!sFb{sN=Vz+hz)#}xaK6%`8aq)xk71z@Kv+g^P@B3c*A^6$qIvIJr-&KE* zH{r4L^YmPOCVqXk@s6F+W>{HLD>W4+Cp>U@4GpNg*gWz-)obX^u5OV^1<<`>j$Vz*CS53Ej}{x8s^;efBqwcv2n_obPtNFXN&PcHDC*jf=W2KT7`lyz5Ji zmw2ar^N;F6@=f;9zHyP)^Dpys_)Y(#+b@oK>AT*0B`>2t`D5&Gs`V;!Y%uxpEo*>Cg1V9+QEmb?U>I^|4($^CEbGG z*k>94hh1L^=h3&fhW`IF_ETnL_D&ESW>$XnG(!Vfz`PabvOckp&J<1cg+{L@`JP@39mKWZT;1|n^SwU9e%_389?q`ZhyHQIqtkQW z%OB}XJV3v(gS<&Sgr1>qwUco_==#s}=TY~o=KZ~%ix}L#UpW{3YU2yN$DV0_z4sJ^ z2W}4jJZ?MmYTB3oJ}eKX|2Nx?dJBG|)66^5UFsEdi1;h+gg4HN`q;c=^yVK zM|E0!i+|MFC>%Jbej;$U=pBP7a7|+1xG9K=9|5xnuwD+&kd-4?im~p=| zbn@rc8N^Nbi2N?`(Y+a!=)>J{uh35Cx%dU$0-xcBwa$a9 zTP9E08~N<}?vuq!@;>W!@OH*`tMi!o-pf4?7C*xe{e~Zw>m+Z7{=_HFSNYQUIPptd zGmj%bf=~9ud+OElM}DgQLr>E4>IU+f^#A*w%jA7=C*v}mM`T?e`>XTd8SzDY=fC`v z-PG~$B%IS5tN2vkNIQo;XU{zE^7HMklN2w4|Hb;+qo1z*C;!)Ut~EUKYjGAo(3$*^ zzlZ04XdS?Ksh{{Rd8_Y@ZokldOzPE%3)|I8{D|Jh8;P5@yKYMVjf*%15570{Ip}&V zydf^j>*eqA2)rs^Fb``UN;~v0U7dcqM{lq7;ks-GW!?XZF;8{^fVYi#)fk z`*_Uv?au9Mpf~W3{4vizwceiR4@Vro-hI>blDbFivsmBo$M^r}^>1%>y&1pLPyQwD z!=b!MUJ3v71H9#Z=d8Z$IhLNot^VjIeGUf4WN@%(&BU!IgUoe(L>G>P2uRPlQ|T!*lHUYSgzsRL>iC>l5fA{3DK=kBDyk z^^9J{|MaKd6%Xmm_~TyhQMH~Sc3bax9T}JP)|dD@{UAS8&&m5oqi(a=^PKUp_@aJ= zKgB`uH+kIs=6Auvw0;%-={NO<^nbteS>^@A)7XD!Ze4^ph5ywb)Pd=F`Jg&g+Bw@g zgM0^{uv@I+qcpJarf9osgAN&w}p6vXHydIv-FB@kJ&`9Gue9@^bx}N!aX%RG<#@(lVuwd7`)99p{*k}Ht$7Xcojuj-*q>+U`(E`ZxJ}%g?x}}! zyq(`Y=zMo@KCQ==AMr2s8Gb6SR3DaSsmoc%7(86=I*N?%kFCeX4(oIN7hGMa&Xh0s zcf1Fm;(osOQ|q+q=lF`B#*dDAUX6N%yo25FgZScm>0Y?y*YF0n;m>zte&_z2ee(Xn z%DJx-pICoryyQ*c)n`2im0pE^@rZrcKhGEEjF0_Cc$MAwue>8V8G*SZf;+_z4Ho#`=k zB=!t`rh9?uXX_dAU57p2Pyb_Q`$ix4oEEtD7oWp3eZ?>2cX*Y5(K+GC%U#D9zPd8! zFV=M!$Jpn%^Xc#)Uho(3ls)D3>S=TZ{-JxtHP7jU#I;-9&kN^pMfb9UdeJgI&DX3~ zU->S06Q_cQ?>he&{@)tsFKx_Mc_4cAMDJ^ho$oX*!+GqpKGu`m>%KPlge!F+dQzNC zJD##ysQaQ3tp%>X|=|eLyeA^P6+LM<0rV8JBBapJ`r?K3C5% zUnZ`pk9n^D_yo_uL!RF*|BE|#K!1$8_)ZV_-n8?n>(%K}`)lY-JQh3eRNty!$=C2C zoXgANM?0fV@_gh+ue;8NJ>?ht!uR6sv_IYVho9*#^>h7E|5TsMxKI0ud@q0G*WwYs zfLr4W=kiVUB6)}Sm3Vird3v57cm5HN;o;crX?Y{x`>g9I)GNfP*k^6v?Zwcs(|OLp z!*uQteN|o@>s!RT*x|7Eou&Ql&YPHbrdRQmI4)`=)hS=>?&w+s}`I@=}{EM^dBzVko@g?mn z=4t-qSAX+&HV=9)lHbKA`V;#<9_MqO=(#c0m8l!E4}7lHY5BW#!ih&;I-i(+THpSn z>kW(}{uFocZQ{bat_S9K#wEYIH}G?+>-_0?bUg6@zneL)Hr%Bp5}XBb$_vW2lzBD;&|G>*t}9cl6IcX@Gu^b zkIUc17xiAaRez(S)PK|~;&)SifKSwU@U3>1$MH??VU!=O;+!6a&*1Gz^_w^)zcasV zzQA*K7VkW_4ul`^7kYyqsW161x=wrvkDc#%VxIF~Jc&=}4StbvdE9d(@B>}MU*Io$=;xCK1{qjG4^@qQ4z3VgKBserraX9dBs`aSg;Y06*F^=KA zY5$J;0R6y^)M4Or`MaihVeumUalY%v?g#g~;upW8=jlWCG!KR6&6kO%_{#XkZck=( zly=mG($2MUzPfWl_Q(FmojIMRz9deCe@^r~Sn-0s5|4~89_Ekw$=_p##X8ZkPoJO0 z?>4)h3je?}|BBuA=IT!PoPA>d_3oe2ANrP_)c@H3<4im3pw8(zKb3dmXF4|hyf^Bo z-;Mn1eD}lB^K=(|%dgc*(*L6wU1#10Kd29=U-2(>U^rAapu57))4kPjB7UVmKaITL zR@Ytg3%uudUGaoRM!oUxz~8F_7QKz5qeVl*42c6E{*jhXPc+6-eaTnL*U-UU$XWbOP^ITpg z-ia6ZL7X+d{4xDM?megQ!|wEz_r+gzq&$B%^7oTHPs6z50r(7lcE`Sq?asHRorj&@ zG+#h(!%4pDxb^)U`RDH;(Wb zp5JJ_MV(52=xTTqzw{rU(BbN(^4!?%udE+4ynr8iNxg{u z#VPZ2!R>y>*Zczf_}+}yUV|9)o}5?svnhKX$#Vd}LKu z$Rp?(c#i+x?s_?KGkCi@^2+U=pDB*VU$*Kmp0hJQ4PQMO=b+y0z5x75N738(C%XNY zu8+kJ;+=89Gr`-@sLxy(^B3!Lb@GhMQTLB~PG`a=+^T!#+TlvE7H%!`HSN|)A-Ttv0ruCk12kw^0{{C-t_ZeoG0+9 zc@UkfegdEHjQ@>qaJV<>tB2)V?chUxm+_tM=UQ!_zV$x*(C6@gSLN4mmG}3mx9PXo z?e$n!|EA~v@JD=-_AmB)82VrSu3qGK@sD*Kv5)h+UXD8L+tz*c6Mi!8Pr4ot&-h*V z#H(q4z4Lc?AkP=)^c?-27ys~YY>ss-2Qz$5hoqge)ercA9>aUS3oqdf_7`X2Q2X?x z{E>c;r(2f-=e~;_#8YwB`|_#a_OSQOc^_Zl8GdSgUGRUV>-p7b#m&T*wVvzZeeLr{ z`5oOQPKmSp+B!^elOCWy)o18cJV1wQAD^o$hG)KveQG~;U#EIP;>G2jhbHdl`JIs; zUFo?2{8!$W{@8D|-E-dju5qXL@De{_e>h}kd`rLO{iid!dU-vMdx)lUbon*>^CP^< z&hRPj^9%E6bZ_G9t#8g9(jPjF4(AWr_g(M<|9B>N{?hY=jXS@l_vljg!F%e->Rsy9 z^qc4STwV!>@F3p7TgL0C=ePUbjPKQ+hshsc^fN5d7P3@^kqo{dqm+ zBaUbCNA(%_5x?MHeF;9{5TAIC=fx>;mOb&F{7ZlG-2I8yd!7=Us6T6m9>4?gGIbAr zD!&e|-e^2ZesQ|@kHd*^j2%wYPcvQzt>?%$>2URPx)INaFZ@(JoSwvQ_&Is*!`3bR zZu&EwSHG$&;2*BM&mZ%AxBI!oS^k12>15+5uF-E9_m{nIg8k`Oej%UD^Xc9hzl(p^ z!SBjL`J?Cjo*%&{9I`Wi(Y}2X@To4enlIp`^yhQevCAXmDe7r>63?g?`CaX#Klg@C zIO_Uj^ODPcw=w2}&aAAT|7C_}=zsP|`!Bms#JESNP3I5rJ3ONA z-|x=-KL0gdcnKcDxA%uGRX?2eHNy{HHC~Aq&N+Y9b5_~GJY(#9r{_zE zo=^84AM*(O$h;n1#NXL1-@CP<-(K{*2zX-$dHr%d=XUR<#aH>RbGznn<)`8l|Dylt5PWO?i{79=@fd#aT)a>Zp-bUh`x)P(p5u}4 z(*K{v{M1_K#pHMND*Ia}z<=3+Ux<(Jsg9)H2p{S>@+mq&U27Ge+KJuncE4NjJnf65 zAMlboGd-E-U&g%cm!2ahPYj>D?fQY(`F8hjMqiyC^V%P4H+)X#&}s5({vMvcFzOHL z+vWjJcAnZfgyGvKo#&+k;VOK1vh#!NDbI~AbE^ar1tckrCvFi(MhTGmf@c*>;{bjr^ zcYY`Rw|?(tbs#^L7mKIt=DYIza_=2BF6x}(wf@jo^aC9gdmeY+nQ>uH`WfDq^R)-P zZ0>g&exyBqrI-P6{nWt?^^M!K8DX@XZLY`>^_g||{iB{wm3Y0?^S;=Poz;=VQ+iU|lyB1E(dTzMUlUy2={ZrpD>!*v z-pli&p2HtMTCAh}dVj>l?t?Z@C;plrr#E8%tJM$r-u0gEEg#JLpGN$>*LC~B+q8~_ z?#;Mg?fP@Nh@RJf{x0szPvv*Pm2(tN_Pz}IFnoA&)DL%iZ!i6$?nx`|`xZ(;o&-7U%6Pt)qLu^6W^Qn_q)!Mzu+F}^I83x?)BXF(jo8`JTKNW{mXy-U;FJx_q&g8HNL=)`P{^#lRd}M`_@g#>%C96 z(>ZX6KjlHoe(j$6bKMUWyPfI!dHBrp>myz~@4eFE2){57j%Vme^#}blUh1pM^=kJp zz8dqwJ7fOq#mFPpdmbA6i#zxSj^JP1H170{hS!_mn*J@=KL z%J<>N`ULu19QR%7QNg)-`)2Q>q@UHD)Ccgq?^^bkgW5s8!aSh51U+fI)YIT!y@E~< z_q8KlsPD!8&gZ|>I7`>z!{y(d&W#iwqi;7xUB&r+Cwo3Qp24e$JFi<0pr9UUTE zTYV;|Dt2IO-2Pd!Nn` zf7KP~#??GMII*t&xcA$pKQCwU6nP@Q)_-+W`jB7C)8X86@zJ^q^$qQ-8{>KNt-;TW zu3M%9&FhITcn03&_3|chQywASX-7Q=Kd^)P4}5xG9TJ}D$&BNN-e-jOVz+zUC#!wq zOJ7Atooe0(|Kcxxpp$)X+JDl0`tT<27H9LjUwZz$JY^Nn8Lx-moZl{v)067P)=$zi z;AvWgSA=Inn!7jSD-(ANNN6@Wgx-hx`KG@Sb|9`kQ(wf05VY0s2t; z_)UF-4q*S-ZLRkehM(ULe%|jraq`O8!T#twV}HcSu|DC!h*O_hM`8zYlRfjhk9!`k z@4`R)G2`;7=Ul;Ucw=|ewcd8V9*@CW@cC%W2OW(4jMuu(91k0JbtnD;S9Ci*VFz~B zPxVss$oK@`ray05=Z7EpHC>e7o$^zDr=7%w*Uhui|DBcl&=0%bnElyp6<7Sidj4g- zdTLI0u|wKfA3AWc5B%#s*7eTQ!IivB|Jj*7q&MK1E`n#eQQX9zc#IB7e-3*7C!VqH zCHd6nfwy-v{;Q7Rec!e0j~hL&BYb|p>o&vxYu~KT^c?>u4nF9)py|(@Q6GEI{8yby z9Hb9ppXaSJ%YV%a-~o81yTp;ae}2?Y4rj~rQ#X6QP{wh8oZoV;^`BKdz@fOn&Un(i zfP4+!jJxp_N9ZLwK|GDWY*nxFFZoW!>!{~7$;-seW&Lx#_qX!vjQgcIdm1k|*Z;(2 z^P88NKdNugIpVlDWnKwxw2m`yPfZPelOh8d$GUs zIxf!TP4as2!nmkwvA;SAoU7}?TgGL&H&fmx|1!^FeC3JqqdY&=eeUcm4)P2ARG&}( zug>{EolJ&d#I0(Q)VR%k`GMv99%Xek=|K7_c9_oj#OLOZg15&r{iLt>1^&$Q zmm~fjjymvz=2P-bdP#j-9xdO|KK|r);o+^W*Y&>o5Bul4E_Pp){7Bp}Uh0ag`kxNL z|KdB`=6mV+#d_cW?63bbZ~yl@<9rP3L!1ZucAUF%ulsH3VRcS;lMlizUV@Y0VXO57 z`X3IBukXb(bPIc?|A#YmW_FXG(%~8RXXRUd${+K)-_Q6(@`9}qPmi0g;mM5Gm=$4{KYyYb)LMxJI3ov<0*TJ3;4nF@ZP5pU%neS zyx;Zt@)|so_h0mUR5~Gcd((B@>?4o%UE(8tlPBU6aWnS$(mELb4X%#I{?L1!Pscye z4_B%u^Zvoi{EIwM9z~UVSNx)L65n6<{tj^*eu6jm1g)1pGhXXsJ`1h?`j{SlXa7hSsSclHxGN725p6FrY5?K~?^tRsRSc|>&4 z>FW95{NmurmyH*RFZX&b1U@i7Mdx@f-r+a#g>F$Vg$MB~_WwNcU-5Li`HS}Hc6P>Z z@X3#iBYVor)F-Wr4sZN0es`KL<45V|ls_h3JQ?pF4}Lq>`7(G5p1`yt*N4tO-}QCkd&cEb&lNO(=X=G|#EXsI z!ziALn{=IV=cn`r|AhzhM0hgzzt?jW*g^e}E`<~8J@o(2u7~V*Ue)}*by@TwzU4>x z-f4aTZhbGD>pxuwKk|3=RqHO|M~ihLU-t>VE)K;tx-R2&ruv-z!H3KIcCYJ=SMiYe zdurtAw|mZ{x(eM6SJ4&s8^6+@v(-!DTH?{Q>R#($;otb?d+&9glzuag^pbVd;s^04Rj^CNkvb`sYv%*B_C?{W7P(m&eA19Sqv2#-A;diZho#l-%{Gx{WU+w6Q9 z{*h0?gZ^tjzx!dd|7`5jnfAGuA4&iByG{>I=r{QS9MV7W-}l{5M32Eq@Vq;xKYcIU zdXGK%qxy;XMF%eDSub0MCd+?D+q9-v#qedDffobPhq`seC= z_|$*#6#m6=c^~}K`QjQoWLy^a$o>7bfBJX-*^N;@T<`pg_VrWybOk%F=D+$GJ-^re z2>6_irB~Gxg6C^J-y_dAI=|AG_kSYLtv@r-#W^D^|gecW(v9N}C%%JaiJdyx)Z%I!B!<-*uw*GSI8?5%oa& zR^3eerK8k!;XyyG4++1SpIw|o{58H$^CM~hOV3A=_oW@@OYgRx5T4m?9!+<#Cw(O! z(T;k8`YK(mUV)#3lY{Pi7r*EnIK(sB2_6n-eiskq`Qo0~KREr%@Bj8r@eFU?X9v6? z&q{xeyMIvLDz4Fo!Sk&VXAj1?_pfJk1$?GI`#m?O!%;|m&K^h<{Rs}8 zYjL~zg?8vwbuD#ic*6ty6#m&i&!_u<)J*w&d;cQvYf9m*Z zA8)IN(3$zJyPb!{1J)1VSNVu`d@uXxzxFe^-rb%Hs-5t|_hX&LrLN!3 z`$s)TT0W>=2XFAHpPthj?6a&Jr~7l`UoWdm@fG{vv3%Fb`f2QcJj3(+LOnr!z&PSJ z@x^>x?C@&LQ#`5eQlIxeotE#K>Zo*`{Lb%sUmXLF!6*GsrLeJ~JymDFpylP%4k4}G_PqNi>io|7gc=(B)e>^i!WL#Etg8CKx zMxV>$@SA?ZVaCzDa`#&Ip!dA5{y_i4e=ql547?G(J+8j-y?MUa=kT|G@9Dv>Zuk5{ zcw;v_6FdJf_Rl^W>#xp^b-br*w~XV{&Lhw*;%w?R7Y0AP?L04g(zo;*o{xRjt0(a% zJF`FikN4v5&&N5XbjbVO8;%F?p*$tee;W09_jpe0sr)WoN0+jj{@}6L`BL|-tH;uT z;;i@ik$9(GL7(tz<14?Dzw`Ix1$V~1x<9vW!;g|LTy7rfxp@=zjQtn$!N2wI{p0`X z|Gc-dPwlwp5AeUV^P&5j@Bm)Txa@qhUIm{-zrE~!qWH!B3}2=F?}n~B)&8)X{>v}K zm$Y**)_pDRCHjj0O9NLY$2oGBTOW?!J?J^`?Blt-KwgR8@FCqr--?^~3O>UR_SwB0 z>zS{Nb(pVv?+pHt4~oD1R2=lZ>U-iB-q3%~#Wj3I4~Qe`0OtGPE$v_L{6*~fVn*i# zp9f=J-hB|$x)=IWd|9m<&@HQRQ{6^9O8?(>o+!V2)O$#MZ`%KE@Z^`y9i# z82q0&wbT9n>O$&Q@^16*_=^4E!T0jhjMrx8HNqQPUH_1FoEz_ckmGTV`rYBzH<~YN zUmYxd^rZD({-w?%{>uBrk^JsK&xe=K!ZV!b{m)$=DDLBPIMKd&Qub8WTITuvk?(BQ zufvn>iP-NtDEYX$qWXz?KK>NH_?`TVKZ-l_hP>PO>L)&o{y#g;t3OfQqK>3L^1j&f zc;-2L(nab;{864F9vPS5e696W{SkNMU#ocbyZ9Loug>d<7jO%oa00jDxVRZ!dOPNE z&UYW5c`m=J9lD*rt7oR2wXQ#;Pv~2933d}V)p&YGE)hRkoCET={^H5Qzw%(z<<2)A$+P79-WPxIo;*~(rjCJ! z=}h@G{V)ESKh=MHs}93Hbe+6X{H2rgUDG-}`bU3)=PSM60e{jn`s01^l>PA!{NP)D z8voku`egosKdl#{2jn}xOaH}9{2q4%G{|0>Vpx7hQ2*Egn}^`4hSXIih$AJwVwA^)Yf*-ae`4~rN0 zklz^>c7sFji+AbI!`6$I`j-+b>@*XQFmamTp(U4G;_9c3R1Jg5uBZu_l! zo5#nK@J!#*Me@GbVWaET=o58aaUB1M7jTt!R_{4IoEb0mXF5lIB!84w;xY3$@~pIT zs^_to=d#`m|HE_qdVQ{aJkRgMYdH6uo>YIp!{Rl+rmx^fKh>k~44iweeRyL}d5zzt zL(J2u514=SUA~vy_`5m)o~I}I5&OWE`8)Q6tLUziJ(q(XQ2!CX=#cdPUGIeno~>6o z({prvm;T@x>kz^lpPOHp2Mo`vH(s5~?_!@b==mGQ5zgg(vFGBRpa0?C{%iloFK4??(Dw$1uV?fv|AHUw$bYqi zH|Wpw=UnS){KdG7*LYHX4G*dRY;@g1>~J{l4Y%Ix?zmU?V&`+y&yU@=D-WVW;3t0Z zruV$~E(l7%jLUTH(CU1&c$)Xmc0D0p zl1GSZvD=;2oy0GCIQ@LqbAi;I#3Q)EOTp*PoK80G;!gU1Fz&58({aQP@%O7;|E52Q zn+u)s^?tOsqYnIj)YX6LJ;-pS|KhUoN__v=drqBmVjZbEIbMoA4_kl6!|JrgE8lh0 zIw3v0{9Rvqu2=fGHK!->OvdHenBQES2Q$_+=?^=Yr!YUR&dL79g}>9W>OA7|GXLKg z_1N1z&j;V~)75d8uZ3rhX7U~V#A9?CeqPp}dp-Y(ZecgPhtJ_5xSHmP)DzNA=a-&n zTnIm(?mf};A^wyv$Ro@T(uew=_80TC1BY~-e$u_{uYG>xef+E)^Nh=N8|y1h&gnpS z2!2lWT)WtRcbs>0ZSd#X+Rk;d{lGynopHg7FW% zK}X3G@n?A8N$qT19DdMG`G`6jJj-9iUwDJ7@W9RL6Zr*w;(c+Mzp!)0*S#M5z4sG- z*g5=gx%?j;VjtO=o>ve&Zw=kGKNEM@L0yHu!f(+JCp#ap9DlD4{J$FKJ)Y}%ee^K< zTc4ljH#)y&{(ZGh6~4OK{pR?Gzc2IT4`ZFl^Tt{8*V;E;c$nYmkGipWJ$7I>@m*dY zKi%(okJY>;Jhpm%)W@;!7Plk7=v(~bNw-+NFUuKs|Z;gBDx8}K7Mpbktos$=U9{lm`cPU24bb3D#9n%0G? z2QK5}WAQ*g$b-~xGrp&WE?pb@CO-GxTXr_S@|ujxSU+`G)Gu>;DcGPpOc73UO zf^`@1$Ho03dz-)ar;oO~epNl(IEv%qg8D=3v)}vXg4;{g?egNZzgE1#zdTfYS@mCa z9^=AK#eKSWIgU){3CPRfko|*`t=5gjM|RG4P50^GCGlFm#-8ep{FIIoXT`yc*G~8E ztj<%@b*t;gl6U{udLw(np*Y13iC@k)d(k{JytLVK!{`L>(*yiVz7HqH3y+CM^e`PB zJAXfTa;N7s^1JlYxjp|MU3V8^XZEFsT~g_*)RO8;Dyh`^C`m9dU=qR*a$(Flxrrer zF(EL4#Bnmd7zTs!2jtQQ-#HBSO&o}GHP}fU<0J+L5{h8sn=n%hGa)TIP=;9T7OhEv z+SO`ROaJOtOF8J-zvu9twyz3a9qo6&>*HC^T6^uizieMq#(Ca*-^eF&yWF@VE~xY1 zVdNb9KP|6T2Z(-Obl4IT9+X={8s;}`j7e*{_OYa?d+KxV<)eBJ^(yqC(-YBt&izTS=GCF!V~e- zd#pP|zi-EWjm@sZMqh8*uf;Fq>F_6bc)jOEix-jGdiChN=7aBvBjPpO&iKd8TN6i? z`!30iJ*)G055G`vWS`^^oWIp`_1QT*fwyp2osiz)FnnXrczfo5G^6*};j7*+gD2;^ z4!bU(j>OKxpMNaxg+Fjfy$&Cao$Pl#&VH`=(VMOt!eMofsh_U3-)5D^!bx)WU3exO z7T@t(`oe$Y%hpZQou+)uevRurCqH&BUwhZ{uhd21y!qw3UXT8bi(L<5x9U9VIs7Yn zIUef^Z`yZr|lOK_T^~%_x`{|yxAAo%1FZ>tIvnzZ?o)x=V?|x_cmDlqx_Ro(Z z|L@zknK*KFtlurqrQyHg3%`q~4gbvto@AbjKH!nRvuF8TaK^sHjUngn zMqY5Za=*qw`xx;YyaJvWKl3^4J?!#C`5ig?uHeId`!LB<9RrVwog9qwQg(XoAOD4i z@RObM-}uGWoF2&;Udf9y|Km|-`=NCn^-pox`1lXK;9c~tK87!aC){b=f#+~L_Pjp$ z@Q1N}`cwP#=$HNE_h&QlMcx5l-~f5jySmV79tVfvHXfMg&w75cx}4|ucILBJJ`eZs z6Mh;z+3r0W;zH!P(S0}a%E;~Aki*Bp-(C(Lax(bFh1Lhud&S4qeu?1Eqvj*xd**-K z@#Ud-uY3eP(3iNtzv6e|)UtmpIPk9d8oxFlIIsVfoYm9#9UP|LjC0g_Z~W!3=hngj z^7p+{+&(ORT9327CXZGxQuoFa@W9~qFM5BOyj5NwzOlRq0Uk#0k4B&K!?FJUy8Eig zUp{O7LYy+s*wuxxum4)>gwf-z_9co_;w-!s*Z8}>9eh4<>g(d6dXD-bf5Feyz198T z27mEfToYf|A^E6Rs1LI@_7MEJU;dD~zl^#^;^w8+Iq`P+DgR=Jv7fWS z57)+hj{5^wkGucT{PCQ8?{U|gIVA#jGy0M zZ~b5XOE3Hp{}D&%eTr{K?Z3i9GS0txKP)_fpW-;&z;CU`@kj5)2iQ4#ARm5>AL^G- z*OF)XF7*dE%zyEDI2N4$vgiE+STng2=m*_jXiX8jir5w9b+ zow>St>}RX{x$uYBiG1pQ_od43@U&??;ftAdbAHX<_#<5Mz3fCCBY1Mw^YqxKbsv6_ zc{=Cqcm{v?UB=n_*?Eb0sd=(n{3PGC)Aa@T1JB{7{2hNI2e{3TqW5!See-?S1=LIN zLp&CK(hI)C@8B)FlE?91&*l4Ym3_hob=2U}(WvKqJMLlsV&o}n-B+ldqkh6K%pV`X z+r=Gnv+iu3;to5+kHsDF&N#7?wem@Lf~Tq5!-0I);@psrzrDWmOBZ{NmUs={_!m2* zFY9#bwCZ*2B;WOFzL_kQfYv&{de=2PCw9`FivQTok$k9&>>KZT!oto(u;f=ipNFYychE56{Xo<|Pn zyHCV=5WJP=8bAE!e)G^(zQGRVziTY96Lmj+>bvl8b#J@{FOo0dQSvf&!VVMHF7}*H?=?^I zj2vFJ4xH!PJ%{6PPluoE0Ukz=hrM?a zpHWYckML7^;lKFg6o-H8K8xV|M)S(({j2t;i3|8J+-B!+!#LLE^S#b3S)Ruz4~4_x z#ngW8x9*hrEY5X4{`;@~*`I&ic%=RyP6f9Ydir$E#!>q>*qb~$zdz|ZKL5q@@kZYT zpVjx|YjB4A!z*sj$;UblzYVUwXq_KEh->P=;<$0dFW+mP>Ne_=c!lrfNBjlfi+m1R zpN}1GR&Mc^AIAFW#@Oe(tXsl!c?9_c&u`4xiF`bM^kUQj_M0!@X>dtiVE*_sx$z_X zSzd|v!T~r#Zg4<6UG;18XXnPJH~Eoy#*YrVZ&!R_SK?{peBASYra1X{)_@X#Bp{W zJX!98CWnl(yiY3cebjx^aqA99-^+L-Z-7-;#}jw z!`TCzj9;8JZ^hdqpN+Y?jeOI4)se*I{Qji*K7S`4_1MVMxfaWN1Jx_YM_mqYQJ>+z z@EmTC1Kxsn8OJ>Hy~pj#%6Dz`yc#$IKlvB?k+;U4m*-kc=l`ttqv;RFSH(MVT%2NW z!QqQzzr6D$zU;YS;vl`SA97F+iQFFcUR`l2_^`ac(sT9<@8OTQW<3J`RA-H4!Jxx{`GO#)n3o%k-umDFGhWG*%u+t z3O<}`pLyhYtLNLOkBKAd3~&I?hco!Ylm{-(WBSy;vD5Pg*#kL8U*C**F8LeW!~ZkR zv*I3p8@swc#(&%M&Dd>t+J5^&;Z^i_ID;p65q^S)sAuBavH!Ey17n}^h`sjd!5Q+A zr}IZ~7M{=x`>}4w{^5f>9WRQVpSG_++<|ZE%<4J(g`di2@ol&bPconDgI7Nv>ylTy z&&7I~dCFU-`Tp`;Wq1{TztD4R=*v2_JW-sDUS5uV_4hsJfW9)%`@L5;`aSD8tLksT ztGnG#O%9pQlh%Rx9Y1AnkvcKYQPa65ML zrsu5Ull%*R7Wes)I39g{H_n@SFxF+BRQ_;){m3_cFFqq)h=cq>-PrmU`&ZA&eC#ti z*Y$L9HgWlN`&ZQoBv1jo*^7*XikYxN9gFi3#5oi3P zv0rSb{fg`pZnG=)Lq4l^E00*^Y3v;DB{zJGoy$kmoy0Y~(eLHC{GFYPU+ggQKb*TK$DcsSgPz7AWr zHy!Wg;91femyf5RNb$ur|pikg^&--GB;wk>4J{){_H`Zrwm9NqxJETWE0Uu@$ zRp0iu_u$qU`FMZ)@vFFD_FYlViu^;}M@t^j5E&Ndag%98l_(0@*IFq;X z3pgWBR3B3(Bv0e;7r24<%75{5dX%4f9(gYJ#o*icq`0p>BX8AD4*&Cft$lP;e_7t6 zpuWU@%u_y_ah~=(QvNQk;oIyPe`62uE#u#8Ug^8o8~y;FGydJKQ)HYa&mn)fWE}Ej z51y;@`@R0p*xP!~h2X#O3-@AQsXg-}`+`#{~=F2oIOwNZGXhI+ueVSH0pdf_kP2ss-kICiP$X0TIoHV*q|&*G8%5wGxE zJ}W+khd&zUa_d|BX`CamHO^T*>^C;OWkj3pL=6p@Q^;mq*{DbqG%@^|g${g?FFYt$* zME`KIKR(^nmi=k$oP6?K8?84cpS{yQ z2kQdjIQ`b$1^;T zeE1Q4P4oA);zoY|sOLVZPs%IdEjhyt_y8xx1@^pJuYeokc>MIB_ajW>!a>hzj2@Tw zqKcdBO3n96T-j|KW(gXWc(* z9DG$=GtYe2^8PRD0&qrt2RGzp)-my0cI7#L)ZeauhCh-g93W@@DDLBL@;LI3U%Z{k zQ-XU>=IouF$b-b${gw@_p&Sg6?|Ua*GZo066$hzGTw;Cs#BT2JQqIWrR++53=fevnZI%17(N{PJZZl) z|H4c0F7tt7{3UpJ+Vw2@g4_HE|B2q0ecJdc-p)_ih3~>|$zPq2zsQTtM}LC(us8Zr zr;_K&$E~yA`EZ^+t2<>r$Ab@?wf|6@HBa+b|6zyp&M&6(T*ULy$Ih?4*SbS~|9SU4 zsW+Nu^msTUANbE6;5NG@H+e_!=VJS`#Zz%pUkcpF_v(AZuimsjJo0oe!?m8@3;)GU zyceF6fAZG1y>|>A#-4wg;q&ki4o41WwNL(H9gy7AhcnMF22WVVK|D=;GQ4PK4iD)| zoi^`19_OnZmG99@=6Q3j{)UG{4wvWZ?ZL5+?GLwZ0w?7!(eHlORpB8#i9FpSe^i{5 zm-)STA%5Z2;w;>Y{hu{Y3GO+s<7AwJblUSd*}3>4E@Yhb=BIE5KC3h1`JR)5xWgXA z7x{(!NF4?bF@N^V-qiW&k)Pt*aGPCaoWpTn+qJoRl)4bS#iPVcekzZi>Tz?<-y^r( zaSzMYm3sK{+!%Ff^$ZN6zxs{w8TgD3z+bq5p9kO8+7E-rX8f0h_lAG{^fhkpC92}!Qs=Mw?JR`0Da*b^0nZ`^HKl#FjL3l?~&*6Sl|D$ z`x@{=c@sbK`{?Dt91nrd{7zgjA9BNEjV~Wmmll`d1HZt#)Gg&x@CpvVNp@wu!#v4Z z9Dy5|zxB$uEB&ALLEr8ASLATkJkk8&B)npu=9%|ip5y2I3*O>mco$wIpJG4ihr!S5 z-ESECx!r!V@UFGi0lZh-fqQT)`dapTz^i=kLC*=4=c*giFTeJ^;f*(Yej|RhS|4L4 z;uqeP_b$&NB!~R|dgG?}ix;Uo@jG_qy>Qk1*)4w&$JK}B3+x{+62J1jS9;zB{K0$W z_2P&)g$JtZM!%0nUFBBo4R7>bcss?b&)VOTaTe$JUVHaferxTUm2(2mH;%|t#09v) zFXTbuMf7rE+-q=JdoX`|TfD&Qd@nv6xxE_aAKq&JAsi$B*#DE!_xNDkGqT%zsql9C zWpBRAbMZyKARh5A`M7!F{~71X$T#2j9uVWmQ}DOM$IIQ&)Sy@-{ddx zNB3sF=ss)fFY=r)fd(Vyf|FUliE+sB}-#Vl^8$PDqKILzl zT^FDiamsw`pOSZrU-G!f**zWmtq0;Q{Kb3m>frP8Tv>W#=i<0^aQPQJj6Gi*>+&yp z53)KB{v&Ud$LSM;18|9c)rb0N$VBrhxk1E@ti%w6ZniD=6g3sANb9#=i=w=96pQJ z@(VZsH{f>g_VI|z_uCI3U!eE+^=9|W(3kZK^Oi5mJMbTN9{;^N=6_s$#op`}Q!m;W zeY5wP|4!Fgc6#2g`dh|%GlQ#<^UhcoIA}jc^tjjO_!S-^PVukc^To0MbZhSS;u^nZ zZ{j{bWmoDI>L=?d~h)5`kqTF=K*ABKl`ulbM$K`${ye0E_J!3z{ zhpSV2KCGQbUpGfy@TSkj5xmrV*dhCbd*Yxvfcl~OEq`av@G$Z8u;=8nA95C_)R%lO zo{;(M&f%Ln0DZ;ZcSe86Nzb1lPxJA6dA)TL@g@H9dYpH(*K=;g9rmwY3J>AAdEyVg zOT3du@K5XKlsIOygqo;_)CxY2D^g)k>~xMBZ0rkukmp8 z9DWr1Ki~ZecoBYXp8NveFpl{|4maCR$lg3>C&^nk%R}V3c#$}0{_w&vb z2HCARYu(VghWLoLTi3vQ)!E2jTo4DvQ+Z18^ZM|+r(-^gy7piH(_bF`=KJm=wk|;L z@|Vo#R{Mg)N9!i=Uw$3^z8dQ+Co}yU@Y8(AO?-^qULJURw|!HI7pJ|qB6es$^|P*b z$oJU;e3PeSp2x*cc&IL6Jw;p-r|@|=6T5oez9apO`j@P8u|qf?z5F=Nybm@zzpIs+ar=D8pB~wrxGdkC;=^(GKk{Gk z-TIn1?z>`dJKc99-mzPK8tQ@cW&ZKgi#;FA_mabE{*F(|)1!C&^Do;U3y1kB|FTX2 zALJM6@UhR&N1WPeUnM!?6;r!9=|1%6_xlldK9*O*ZFQmG?XB+P6Yuae^=kGH&*2Gv zh*yY5p3~Rrb9Dgzg%`nRaYTH_m)PyJ-{ahn&(~xB#rcsx9uI!II9G0*Yh?c7d-U?Q z>$&QCv7eLnk$SIqA&!%$yd!qL-hG6#7A}|AHgSm7k|e? z#B1Lx?u6HE_Iy8iiu@w}d%pK>;8($U=jYt$edzQRoL~IEi~sAt{_p%7J7ay}W%GJ* zF#hY_J^XeNuRirPZFL=LidVa>Gq1)Y`nCQ`U$Lvb&QrW#S8%}d=w+vIovt z9&UKA`hdEMxTgNVKIM<01 zZl4H$SLb2p;uqY5Kk^#!5sy{poZ{g|&!vQi;u;>F?>*@G0I}PHu@30Gpp(%bd$s$v zrh5FT_YaDL*0u3!aUTy?FCu^WyL=X&SF9QsmMR~N!p<*oPz+*2QjeeSd#E1rsv{8#*C zS9lTJ2+zFM`W_snUp$R`BF~Sb-_O1C*PF*hFPGcj1t+JxR2_clFZfT!f7Jf}%yXmr zI^~c2&ivsdzwo{6Fwehe-G*QAFL{|fg509VS2KE#e6BYRiof_X{ES~b>wUrSP23Eh zf6()(=tZ1`OX47&9KF09eDD0Q&!h5lyoCho9Lc#`)n)}=;%Y8?5FyfV17HS{H4*zG;k;!EUk)_Z%|6`n@Fd9QQE z9=4v0SA;k27vJa|kHR0|l{n6S*{67+A3%IGK3;*h&a_4v9Ws32@mTNPpY!+l-QM7VZ@Z7lJdI;M)`j7Z@yP){ zl-J1XGk@nW?3Ne76LFc}`F-s0%bq7J--&+j_gp@9m3c1CH~qao{O|t<|M`Q)FT6rt zApYV}?0=PC(WCmCd;w4Pd-}z@BDXiA|7WxPA-*eixZD1G@sa(j!{DXt**ZeTf6+Y7 z_eKuR8~>(#r|cG_ZtzGJwGSEyg9@oRSL_v~MP zcyMO3=K#xJ@ZsqFS^12*W%TlTtiK!;|M{Ky$1j%W=m!6n=aax;cmikCwcw%k3-h<$ zy}I7VAH~_|_fhL|>|Y+u9{9ERMK5qbo~!T6cg0Q?{BCkC!NyppyE|~teUbJfKP>N( z|H>oqaCl{&>?$~ar{lvP^HfiRhrWxS zS}%aN{3Y+zNBw5hT_3crLXYeg&cI3aCA=l?ebqW=?Abkc_eMY7jrLJT4(FS9@C)`y z4sb(#HF0pQ`^fU%>s{|wpOH8DJ-+8T`^PicmAVREWIlMBJc2!tC)^7T+-u&1ud+|; z!s4$yo!{m6k9*F!egJV3pZDH8R}XPM%(L!S!uQy-IyU`^gX|=7I2rbEqxVXXf9&eG z{LuF%Ubts-abC;cdj7Y6_4gO&Wc<-T`rrM^!G7;mfw$z$uHZ8{nNs>eT-qda0k9{#0dp@3Z2l(cDSM7=(SK|?0iZ{kDc1GXq#oiCj z@5B*&j9%pF^vkcUYrskPul~=@`6)S=C)`l?5Rcfux(XZ#(nji*zL>Sr;OjKe;UX5aDW_QKh{S!M_hQ){x|hr{zVSH3$GLJ z{a$>O$I%PiCLeka4&NT@fE#nXI=|OP{l0Y@@1w_zv&_H5qp4q<%&a@G|M<&t|B*N) zF2IdEf7A0l)Xn%Wo+eJ|OPTVG^J9JCVfzd-|E=z)3!l-aebRog%=2T<|0g&63jc?P z){DtW-Aw$YNBBU_zL$Q*anH#!{BVEh>-orQcDr7X@gH`*$$A#vf`5`f+_Qd)zrhoE z0XreL@Y{>6JF$QEBfj8);x#`NfB6Mmg_G)a@H27nQSX<@{2#TSM?EBZ{I2IZrXS$( zh~wu+9sA12r;ggk%U|d#<2aAvUe5vJzx1eH0YB*-Z&%l4pW;;Je=_3WtM20yH^r~m z+qdJKggZTlR=xut^f|y=b`twsD<8;vpAUcBZGAYneb{|=)3|fJ>qqRt@5NL0oOtwg z*Zc4*_9iaSFL}kTmh0N=4GtS0A7)pcPkGMG-d`h+NE|<{Uneds&fgjL>A>xL*V))d zb7zdRTYScI$U)wxZV-L#cYQ=1Mm>#u@W565vcvGqy|G{EN%xVdCuIJwX7VO+ik$I1 z?}b17i=9Mn=i6sUAM8im$1C6)eaR!t2S0?9U#k?D^S@okVWy64waw|tkp>9F@};Jwyg@bJv%QuiUU z^Ni!(=jUB75Kr03YTaoy-xT-BKXTjec?kG}{4sud(6|g&^L)McC+e4@clInF5%0uV zc1u3^9^RYrkGkJheUg0WQ9Xy9-}YVBkKnd^%Jbmu zhu({19DZb;;t2U9-tCY3wQmTxcH} zyTyyFzZ-`f7uv!446Kh0l!#9Q$H==b?dJ)b?Rqw1?6&)}rG#Ix?tQlG>Jk{7(~ zJ>%>l{A7E?h2?&z@Tgm3UHfeGAMQ0?$F6P{pEFPET#tJ1Qsi(nlg|bp4%)wpPr`@k zcfB6(J?wqf(aTq3f7a)7au-iC{@$ox?X(`1?|svK7Wg^5GJp9UoYc38cdgUB%nj)$Q7C=6Td}$@mdF!8iCR9)ichpTw_+J&!`Z$uIDE zb_JL4RX7Z{#cOd&om^gQp4P3{d47MT_cy^w_K%0a+sOIrnfDq;eKPVn?7hk2QSf}D z>;8HE!x-m9&jBL`brrZYjUyjd&iQ;bc=G+h!#^K>bbp+0vo-3&>TExZxc|22f_iV} zf6)7brt?1;>$y8~`W3&_tKlvDRG&=#vg}8)A5dJ2JfF2MCAf6G>!EmBA$D_Pg{;MvU-=A+kfV?%oKkE6(`Zx0Ya3-&jkBeWipY`?) zlBaw*a$7H+;M?#P4;L@uUrW0sw~TYpb!U7DuYkwlEkBgM$v5#9Ji$ES5?&fRS)42M zsbAu=uIu@I#=q7+cKJKL6#uIO?nj<)N8Gv4^Qif|`mH#nZjgB{?=7`% zrGBDcOT7huP(K$>#ZBwl)=k85a^NrgOMc<^>PvW(dThpj+dD3tckmFnO8)9R`t!v*b_+M~I(lKxk;9d)^Qr^*y?BZj z;f>z6vC-ByHv0HwPe@^QI z@5lb5*WK4f&g$gsmYs{&_!avR@A#3r?kZ2i=gkL>(PQl7`KS+n+rCrymhZLC@pjKY z7k{JQ*X2=gn0?B3lA&g=WBd8OauMf%Aj=Yy4g z%PU>?q+j(k{FD8}Pw(~|Y5Yz8%g*!s^X?;H&-x$WA^#Fz_!oW%Kf`ZdkG|H;*5%YW z@i+K`kEsiZBkC3M3v$Lk@jB!1N9zv8f%Czu8)JR{QSVjf7wj2dRo68R+~cQkgTITL z>|dP1qtwa8J2@U9E{XXgyndiseV-A1v+`90~ z-Usoo@;h+>Udiv+6pHmnf}HV2^WiV_r5=^>pU=XR&voB~c7u&i=`hoZ+@O%RcEj-*vs~t#~rtB`@PIvBTrm!PFal zm-?GL6ihA_f`1=o+)p|)9|tAYpdr2o2PsPK9hqwM(kmuc^TYRf55kWFMDAB zc&vO@{%bzuV;t{=KX6Q5K#y=K_U62cjh+u5IWN~?@nP?Uw;AWjoZTkw+-e+zZ|qZC zR^NtK`lI64i*sj2|A{(}@8Z|yPw#$jp6UtgpPgquU(CdDa`rs-e6#!R$w$30_Fx~} ztKMg7{at+ze&+Xkg@Cx{V&*Xa_x1T}2DNn>F`8z(Dan8DK zNDlH-au6SVm+uvi*uVI`YPWFA_p0+7$M4}Jf5Zc=>&d&t9r)?@zLz}Vx##97FTfk| zUU3?alK-+R>oV{`-T~*?k9r6{#fRyIUx>fq6_@7t82iU3^Swti?~Q*w9scsJIHsPU zuEKuEUmUTYl)b?{^NF2rHt)lWtP{!i@$D&Zbl&N;QTLW7uJ^nJcF2CbSG_Ucd$w{; z?3LzyelI^|pT0{Ri9Ij-yCSzY-G6~Mk{g~M+<4o2?%<@lD|{no{t`KSGuE{)k38#R z>t?HUetDU?obkm+xF=r7JK#h7_h2SJRR_p(_Z-wD4r^BEkT z;?Le(95IeK!tdauxT7u_p75yk6aHcx@jdhTvg?(`frt18zm+fG8}bYMgq?`X@J(C` zKD=pt1`fbm^^Nf4C%vywpKbi&wCC)>4g3mU65oT{=jY<4xRCKLl&{84PRF|B)q~e`AhWrjMo$`~{?MpF^Ix4#gzkT0+QF4nP zeeAgw;u`swzvt|Y-0&rSG4-R9t`nIL{0vUs?0o^&5#)F9Gw=O=CT_+Kk9&{2_yw2X zq46VU=kC65eZV>_+=zUfn{;XPGwjum@GJJCUL+2Rr}!isfE(tiPGubgu9CC5U;KTo z=Lu(=2R*k+{*JeZFXFYlTVA7{yqeeZ7wajB<2EvEBGc~4u4+O zQRz`U68H1_cRhDHc4a@*tC80{8}<3+`TX>bZ{yGOrEZY-?hkuA?Y&6+!hFbq-@ySm zChp*M@+th&d-MC(%{SpB`M?c%nLJ&*j$U?09dfsQ8t@rU#skgY__4#?-g^lD^S#%5 z{}lVd>)4g?)gk3~#@9y;x7kVJ^@sMs=J{7$cksQzfy3s@`0CU?tw&sK{d|>g;~V6F zhwvBkq!;hSPuM4%frpXvUiW$7IpoYw@qBeQJSyWKwSUHQex3Pz*}M-9tnyFmv+_## z@40%cIw~9>Pxi_0qTgG+?|?n4Q%&pk%f36jT3m>H4rk5_g17KFddCws2j9lqUyb_e zX5%|twZ0tu|ImKC)w(qQqIdff^*PWl{)vZ?kN5)r#dmtg|K)?^nfGpub;h+hJj4^G z@$195-^6()&u8))>m9L&oz|J@5q`2;e#+kX(G(}&_g+za8}E|O!fm+cxjc*f zYlzq64A1cd_`?pZN63rSWAW`gf7x@M;kJ4*-0)sJ4R2&u@HzH&d8Lo^<=`i8dhem} zr{i4jx*!4u@hxiKd?w1$g z5Ace;c@A&!>eOM*4L{nhCk{><|96` zLpb0$9>uPLC)OkE?|U=$4Othy-F=SaBmTy(FL(d1dK5p3U+7c4)&0xnqwfp;uygfT z@ev-kIi z@5Ft$6uF(v_+7r&evR$kYY7JuPZ#$pk8_rMZ|v&u{cx%{*V6m-eYY{BhSG)%Vy5KlQzlk9#g|_r5mshhzHC z*kSa3*gj$FcjC3UOg{XY-sM63i+=Hw%#%OfX@7p=&f@;maqkI#k6xDN@SDH<4nHA( zekwj%N6Yi0u0!D)a58dx^s{q^;IO_9ekbox_kf4$9{Jw82&aCf7bFuqqtY3Jq@5RrpzrZ*AKi{=HA7+YI_q)GOT;mt&W_kXs`yI$91eVHe_f`|M9KEu6?^StY= z;ye7YeoYSICcIKF!XMOyGX7rAeS+tnd#`xP9>g{Hrv8aP_%8mK_`AIC+qxKg!#C)Q z-s7hadoGsxo;(*nF;9BOx2r_tlN?$-`JTZdY%Gs>sL zW#23Bz-RCQ-<$dGcE3Qz*&g%1+;b{|Kl`IUVXOU(>}ML+uJ=3v_LKJ>_1;W=2glUe z-~;=Qe!m=jM4vZ*v`&gw_%6KEI-`0;?C0sghg+RLTxCDvNaXOOe9!#lYvNtv?0)e_ zzplKGzVIB+oy)|o*poU#?DJL6t6>jtDgJwB;M-Qu+kxBp-nFq0V$mNl&NVeYKN1(< zGdoOtzd7>X<^68a%i7q_^<-{+8Sf3=ZjF7u+jHL~Z&KIQC!nq_9!1WFJztu9R^=SK z+HPL~+*5yxpKf&DnR+AMr4Da=d0Fgjzw^#~&c=R|r{g@>AG#leov0hA+egknmXE1B zvD@I@;Yz;~eeM5@$HFW47XJB*t_$ErcqzZ8ugK?Z&%Goczh}?%9zDM9`Re=>Ud6w@ z9)0HPbMX;x^j`ch`c;QN?s+xpGx`0Co<9@$oORuk|Kd^b8LnD?$vDe8k~$=QoB99L zx*t2t_dXsx;ZpN`an1b2LF35d^4>RHuf!+m9j}(BL|?n@(tf-$WxxHK1{#f%MQJl{m>VCRwscQ>NDnPe>(rAcQ{}joW9_B;?(1w|4+`= zPvL;^)!Wr4*&%+8AI8pK_WmPytL`N3;M@Auga7ugU7pJm#Rd7YIK>|Lg}4Kk*aN@F zcU@{67f;1IxFp|K&os}-?c3q+7kZyKKb05AQ^Fh1MnBK1aZlFb{-^)>&;DC){_h99 zXGgz*JS*RItM}xRkM+Lj6;=KK;@QJK?|ZfxW>2`4=9DZ>Vp?&d--`1aI$lzX|`M zFZRZN@iFg(&*Xz2#@=4^UJQPk=j!B72fw{g9*$S2WAm@r+vZrubZ^(ou^;es+#htI z`xC9-!CUc~zw-(k!sIqk+#4z)^v_a2RN@^6iGz}@EK;l0cIDfl~kCLeJ*-@C*s&*7Wz3NC%u zbLWDGw+0V%zq7i~>-HzZRrr9v!;9{G#{piu;wndQRkgp?X)B z5Rb$!b}o*3*5}r#{a(FS z+`*Uf-o55c_#6FrFT2X`*Sp>=4-yxwUnCyA8+qB;;A!_({ODTmc~KwpUirBCgXj3X z@uRO7UGJk`@)3{37x*l`;Jt8_{NX%1N#3{9I%mdt)jZMo;*>gr=js{yKU-$_;!B_dIIHk@5Z`qrACi(DF_=8ug8<2BwezQDZ9g@DpS$s11cG~qRai4wC zm$;@*0$1Uu`fa}VZTqEzx9i=PA%2kqd(QKN!CSVwe&qM+2J|T3WM>)Yu=@zCi)H@L z+Am~2dA`f-z|^Am-G+tUwm6!fHT393&XFER_+}>8|O`(@3{>bXSu$nKERLI z51v2{cpCe`1I?3s@QuWm^FKQuOdJ${;TZcDr_^W2IeIys@w-*rQ{NN6*eAQfe=^SE zT=Q|iYH;9mhL1&G$D?26cGqR{{IKVD`MtPceK~s3_xrv)UwvD>OS}`u*}1&QbNMy? zL;mE0SDTM`DlUuTcp97+@6>7WeDzgwOPsng&PiC_%MAD6gSv-xZE?*!^@HKD@=f@o z&Tszk$2vQ{8b8|UeJk==I71G8FW*sjVxQtQoDl~zpUt_t6W*mS3m=%qh0ER7L!RPb z?D@07)4uL~9P$EqNH6kJ{+@A;ezwkqKd>v~kaOgzAN#A`|cl^;b8`gWH0t>EYK9rXwPB`=HpU+wvIcq6-o zZ}J*^Mtvjk{mtkf+iQJHeNTN}y#-Hz=j7vi&C`2*uYM9ZFHVWG>^AdxQGOfw?3LHa z2h|zqEB3$Ozn{*9c+>NuJ%?lbD0cXK)VJ5#PdMdQ%X^}&*RT`wmrv#S+twN2UY;-d zj6c==ZZwa;fABGJT>b)ojL%N;-u0fZmFI^u{)KPDPwTDXDcpdEk;BIsy^w!?@BG`t z8C=DCW9Rqh>_2g2uj?j>Q|HGyqMvm?rum3#@LXJjGm+cN>QQ{rFTt+pE4ccx`)ct| z_{Prh$;6|F&2#1B_!z&#C*d|6ho;LNScIpeQ&os>KypDV4m;4}Jm-~;~eIk|;DTx|a>UdKL-KgF@*kr#aE zzD~R-^L*NUvgC}X<$Le-TzB~b`Nz(WdLBMI^u5!%pL4D4U%NPGZ?W6=J#X1Mj`>&z z2~KWx|G4?6AHs8S7VgDP+&jFyhbZG;>pgMsP~JqI;<7q9yR}Xve!&g#ar#|X=i;FF zE573o)&=l7af*M*)8%Wyb9KD^QI}qy+>U1K4Syz2c?!L&d+_~rskS6UYINf}eO4Ij9GkXWsj5`!VwS=KrGiU5a=38~lVb^e)eZ5Bi$a<;3Oi*w4qh z^N-{HHRox+@415Um-8b}c{S=t`|b0DlXxi{z}v+;`+%$`s=x7xDD?5=N!SmqNlHZ!Ad=QSoPyQ}% zjeO3^Gh??0Gk$>|M$XS?{0`qBPw_X;7w6-C>f7J%y=?df`+ zIQ72wgNR4uCjNRJJY23%$?N5b>{I@0KKxO<5cly_^?5u2ufPN0Fh5e4CLeK=oW&9G zE_vMJ@@;WVeI~!ZJJyBo&BaanQh&q4#cOp@ycCY%b=G&pYx;%%>R{x<9`I6my85Iz z6}`J>cC+WeM?O34Z#0hI7@*3arW)9*U$y}kHA z@c(l2N8__w^=jW0`5ccr(%r5P%CqPNF2Q+x(l~yH=fHXIB{w*b_a4oBFMh~w;itII z-}C%p&sP*j)ZgT5#$nI$GT&vMz6);4f8kQ_;l)h8&u;lCdyD@r?{QXVHom+&xVJoK zAoIL2^2Ec|Y2iG(&3oUE^`!5FOKh8o@*NWeB1Lj@dS9Nzl*;3sqczj?4R8n=jCn=d$?4b!CT-D z9Fs?|lh`MDI)CZ?%({a**fgFl*P-CHx*Xh2z2!pl@yL1mXMH|!057#(AU@)6@Q0tl z`RM(@9M1c9d=H-L*<_{m@Urz=;9Jg;rz8^ckJl6eRv>%Lq`Iq10 z8|v+FUY?8p;C18^e|a$C%SP`_ARqc-pZF^LQRm@zctz&_vfl-l;19WpU+ggY`f=dc z`5~XZ#u2#0PW&D(#jAreYdxpP{KFeRjJoK#Q6IkCeJfL*e9}CN9pFFePVz){#m?n@ z!GZPO$H%Vne0lD%-{ZsTB*9Pp!zaBz8V+ZiT=Fe{F#dC2DuMm?fviMX5F7W$qhfW?x3!s4k<3U?7n-M7ujKFQ?fln!6hjaNLo+D00Zkvt2tMS6`Gf(HGT*0I$w*q8apgXDMeAbM1X z!PC^+>7D!|2l?Gj_X!#Y|B1aV?>nCIpRapg6^a-&LV533JwFHDPUW*)@56uatIXg1KFf6_{+RizFP+W!3qM-L zZFtB|*cG|ayEtn;?2X>@y~jO=Ej;sJMsD(bewy#yDF5{P_{-Pr%gTJ*SNMI;k+AL$ zPw?LO`=iz?)K&0`#HsUxXF8wx<=C%uzvqux-%0)F-RKX$I44i>h#btv@7alZ0^X%= zBmO2%UGI9L_og0V|Mf}hcf*|@kN~q?~Q%l@47$!rcWUD|Jht!%Q*a<-SQXl z)OsI$lP9w0$jAAF_q$(Me2L!IyRK@S*!j2JFB!i+*S<=;CBHu${lJgA{$d<_K>bi% z-S?_{zz22LeD8PNzm|FKjlTE$JqJ&oOYe9HUKBZ;^t@1c3SJsLt~Fj*f5|wP%iE3P z_w;TY`km%eC&fwi7V#)?`D)KKRp*SpUXOl;n~g7iPrq?z^{!@zvM$N_$vFs z56Dy9n4O5@c!D~xcn7!1KX&_5>xbf$c_zLraN_vyzxro?erxW%$p4mJU6-zg+1Wm@>BT64#OW_b{`fyCueyvzsvkL8}A~Y zMI87e@Bhx<`xnkbd)NL$^@nLZJ*dCSqhsg#RUVIc^uGOa=9%w0-+k_p&yQn&`l65N zlOMevb&PLk{5|u0-gB|kEBxN~@)!1*=SMU1#2Yi8-LCJGXY668=i~7U^)Y!0IVUgM zZ@(Wot9QYFcFRuqOYnBdht=)r-8`+Q!%1}j_8i`F+HQrz$IK16;bKk|T;xF4hw;BIQ9CUu~v+9w5smF@H@)~i0fAPEE!)eb& z7hlA$#K+Sazl+>1x8IV#)2#o_|{S)GsZ z)$!QB`QTmba5Y}Xf1RK9UF(qYHSsI+xzqZsxD$CEkNX0)yAGT0-EI9`Toy<0D|svX zv3?bL{G<=eF_pX?}NO;MLyB`R$jxFMhiIwLSRH zhp}(#cGqk8UF5ml=j@z*)stgyXXF09wVsztFXV=&1qT-Q+5X4>?SJz4uRiR)5B7k! zME>~L#)ud1x=)9{t6N%Ejeei@e2ghxEzV!~bgusKOubZ}hP*!h_;K_t=u3Y$Q@5Ym zv-;a{@Be~J){oS?;DES;Uj@%Eb)O@i1|Q%L++aWKHaKu@u8tuuW^epO-tE1{fiw7g z{9>_ReZ;%y_h9U=IqJSSzlZbkAo+s$3-{tLFB?y%JY>E63J%b3-XY#^3WSy4;8=2fj{DJ#>WHcSKJqu@e?>B&a!j-1fGbek=sH0WIR`& zi9Np&u=Ki^s}0 z@u=X^`|@ObOx=LL!zK8DXX2}H9#4=L;~}v_`(XMn5xOB_@mP`89X@CpyHj^H`HtIN?ZoQDH>@3Zb(VOMa>dn4zA zp4+BwiRZI(aSE@K?~7CXF7jWl%hRv;D_)C_>@D;EcJPo3WBu#uoISvEW4aEw-g7?5!F%Jsk9w{({;xhM zzsBFpC-}LnZ~MJ?O<(K~KZL`{fA7w%FIZ2B{GH43qIe~a>o;T1cn&_G9%w${T@PEI zAvbYfT~u6%UM_Z>MO@4GF7w~a^QikM;g$SRU-7D)lbi1~PxfGakbUO&NA0UwwNLq7 z^4aA%z1|yMvDJIDV^@oF%KzbC`}KeP;qu&j;lH{!JckeBwK$mHf8YB-_^G(h@8Ay{ z5HH~T6gS>>e*qpszjzCN#lOTaxQa)~_cP9E@sl27{}<-?Bz^JI*vXyVvw-J|NBmB_ z@V#(PK7#j>8+@jB{>XpTk*ss!Gx|d^{x@BZ;9uke9}}RX{^7xCq zn;fjO;3s%a{O;6e_!N$t@RUr3OD>d^FJ;=u&e0h z=^SqqU(|=mVfuUblAMlw>V5aKz&-I@zKLJ)7xKZY;RF6mo~w8pd-$ULsQd!H8J}Ir z$Jsyp^j>i=^4XiKx5I(xYiq8a2~YeUE{U_w!5}xdVV?3Sei8j%Za*zKt5?L|?>CR8 zU-Qg-_U7U&zDMuY>)8W*)-MrUy50J4=6SbuTK*zlz$G{{t%F_u*?OqDvAR9{AqVk2 z-*uz%&-{@gHPZs@-J~pzn}L;kM4u8pZ#Oc(TzX4r|s&*e?=yEiL!s!Of6STBPo)<=w^PL*-iT6dNAk+XU=d%$zl&D5RPRlawx z{aSEU+-INsl%3_@!F@1J)anV<4IevvxQde2F~=lQ#S9{d@ez~|ubhwi`2eBO@x z@*XtbQBP+7!PN^rPr&+%=j6kW*q8V&uE|Hp!8rJpdFq3b-vu|;+V>m%zUqE~;P9=1 z4@Wb0OU~?{f64pki`;x~5_lt`F8KK&<6@fz=?7xmJNbJq1}`M7wrsu$yn`{6l{ z2e0_p`Zj(m&PG1xMt$I?_I>$YI2=29Hu&mtpKRjn`MLQ=FHd^zoOK6r79Ohi;(_W9 z>`KI6UeCclSo>Yw@t#Ldj-O7C5beLfoNcXztq7B7+)!*joYX3s?Z$y8^oZx=drx{ELiD)VbHyXiF!U z{4RX;V&@Y%yl$VNI0g5tcjNQ&NAW%ObNI9K=)^U8S07Lx^Idovx#3alM0~d{EFY(@ z#PQ?Vbe>!7KUY5_H+Tpi@TJ)Q^`0M|?>*mhU&S4DjPT6;+P`_iL--6o#TU=vCmv${ zZ~#7tKl&uE_5L02o$`tg-8To9;JJDT z+>kHGudNg1yB@WEC9e4{{28vU&YwMa&cE{9`6Lg=y3EtThxeL~hwH+qPkz>Q9C?j(1ob7n6hFad#8dBuhj^g6iuESEk$mj$i2M&` zzAJKDANk|g?PpN8QRm?=;wgJrl{0%-oj*KO7lM=g8XmHLkKZO7M%X`f~dR)dk{6s!T4%V;L>)@fd z%-(`~AAi;-%zhH5-gn&%p5tTc)v*(K^hWPjWhdsD-@j~sk#!S!jkts7tokXOBu_Yi z*Wn5B3-c!*e1QFX4nNrye~EsV>-E8_d##hx3m!|J@GbVg-*Z&hKOPHb{GL3mv#3Ym z3FL{diq})zcs~02&hELqk1p7;bU;d`knYiZv0VxAuj7%z|+`I?Bw;p=gU3Uj(@==a>mcqVZ>{725}9} zTZa?&;ydV3Eo$v9n z`x({ctQX+P@r!SpM~H*I%lz4o`~pv7hw-~Nqu+b0{XFU?k=ys9ul2Zfx!A+|*1`3Y zOn<-L{sH;BdZ0Q9zm|_={uk!rskozV96Y=>>QuYkm%(2mhxM)>iBoVX`Z}G_m;5of zcXjkN-RwDO_$NMT-9+D!yhFUktAqbr9S3hz9}Z9Ztn+7|ng3b+6dsDF(bv=NZ#92% z!%NvY`wU*~b-yjX;kkGk+}kbx;qUl{?+X8X(fd-#Q$2*;!g=*5d?VvL9_KbJ&z)lr z^r$`~-l=!7XLcygl0Q3-{V(sM%=pe*IO=&#k^iOQBz&IEXRq}Ha^R2TAHRDvCr|Md ze$op$!@cP7UGLLTj};%`ZS-|G_Q9PF+&DLI{)_gxiObdp)d%Ep;)uLny)ok-jlBLt z`{LBG{a&8Pzoz{2u;-}om*Ca8_KmCG;vw=H_8&Xn>HWp{AwFPTRsAsE`?%*Ck+b@e zI$`YLe$QQ(SF)?j=kiz|JQ@2&FZVt^WAHzY0>jmtJ-G)D$jeC4Pwtt&_T4#a7aE#u`KjR#XKGL00 z?_Jyn@auo+pZ`lL% zJP00&r}7SVt8QRE>I|N%8>@55_x)bpil;@+_G7;9xfAr5_uiYcAACFS-5T-eX4l== zRq~6I_Vvk6%}0Hbo%1_!N4^hN`E_vq>+S~+&Nv@?v*$mvH~7rI$R{{?T%HC$&BwYV zzAX;2LpY2V!8iWJuA-Nno_ECG$zL5T<9sptX)hGtk#WnH8`0$Xvj4z*J&yoN7T)x9k`GtHf+YA&_dXu| ze%ph8e%XB-YkBYIb36xbB)(ki zIXv=5yfl7y*z?uNnIFYYj=G?aS)#C2Y_$n#;@s@o$yosX#V=p@HgX-4;~vi*f+h^b!7GfSFJnq z7dQrg@D_DT&+!&{VxGG<)4f8Ed(Mn?0sJA~b=><3Bj=Oh?~i(K1zb|EmgmYB#C`UF z?`3@V@GkEal}AkTYv;-DmWT64@{xDMp7+Xc;R(D_e-H=p1o(hw$_uO?k$?1fVXWs~ z={-L9iF{D~n?G8IweBNtG9US7=D*(l9D0F=_$S;G$EUdZvUwK1k>9%qaKSIeK6iaD zc%5|+@zHzfH{%?S{nX3-0_2(bAN5?9)qKuBfAYQy_wOMI2$`(-Y*m0 zc&+DPSU)0XyjOhmd$^%53$K8;_%J*)4qhkT!8i6s?|3pf%a6omDAvoc%>^&w38+v_7EE^Se=}TAup{C*eH)jOW8K@?VX=@DMJ+0qYw4NE}oz z!p|e;gPzl?-tN2bRrtmp=mjpx-{GXXC3_R^f^W}TuZx{8?m_&tzxAyB|9GtV;}85u zoQmCU6tBcVdAE7Szx0jY?|tidQE=&P&((zg@Do13XL!X=<)`tx7u_!=KJv%uILkhK z_zAb!v+?EQ@<)1%JumO;iJaHkSD$!&r*@ioUT9x8yM+&U0zPbAkNt~xk;BLC>x|tx zNAzGO?&tabSeO64=QgOTd#`!Q2k{?x8#$cy9AI|HKKYS60sLzf6@;h?C8{sYa$4)Nw{TcuK9Dimfcm=-}zu+E!WQXK~ z@5w`hOP9KT4L-+Cj=NuS8kb-6d@A2dFYr0Pf8M%^K7`2OP46*JT)Wcz9dFc^0{8GS zyh~k|UyIjpUR{elzyUmyJ>dVb!{s@m@)vm-d&~S^%+%$`UtUJ<@@Vr^cg=jBw{Gb< zd>}XRLL9_s?kGXCQGX8-T}FaOH*_KC4Ka>IY% z1AflG#C`Tpk9dxJhhM{CaYtW=b$mQfyu+j7zlYubYki0P;1AYc;0#<+ug>%J_HDvR zd|19fFZ`F^(Ytx#&xxnoT}OjgbHr#y=-44y{mhulc-~mCtiWC!X@!eeZxHEDaL^(_=CJ&J^~N%B{+cRs4GT3 zi*>0__uf8e{}q4aUvPjN)Ng|)i+=6D_55%D>hIrfpJ(*@s`8W{$*=QWH+w#i;L1a6o=9;oiEF3sM=7x^jNP-o6K_q%>A zUdP_fdQLBSlaKexyED%9o~Hqq%AHOaP+%w zv~Pi3t@1H?QC!RXANIT^`5>Mjy?<=~OzdQ{d0*za z+%GJ?P=8teYc4eJqdB2AK3iE{9 z;3>ZitWa0(eEv)`R#dJ>rwYVBi@+`lXC*m#gDf+cugIAb;=5yBb^VM&~YwQ$u`)T1DdkFq~ z9CbGLZS8lz2|25C!b9;we8e}bui;nn6nTxhsCdUOf*U6zUN7!-zxM90{MOnxJ%<^8 z;}_zN{So=DwXq-PV)y&Rer|T3jyey&!++E_d@nu12kVvWlbyqV`M$VsJ>7aMyT#Ms zm3XR-&5y`4dOsfL*zC8T4W9EOda)j%KAG{CJW&1IbMld&nkWC2*TYY^DgVv$*R7A? z^ZY1&y*=X2*E9Jnd*&DNqiKEVR{OHVM|Mu{{6$_sp7f~iR6N4>)LX&_Ud-@4yaMi# zGk^5n*xQTtm%`ONe_C86FXQ7O90+v_{ObgO;5 z@^Ny&)28FU={=a_kn#7sj}@Mio9~T&Z?&$=uGB5nRq%Q8#BcFx@f{8%u6Xg!5}MgI2bZ*-knUKu$!A55R&xt{Z2y#qeu1FP{)9F+IL4RXV`+0Qh-IIs0) z`AKj<-{$p!ZwJk%$P;guN8nN7CSFP}>{Hx{T`lgb{Ivdie$=0<$0&#&a^IcedP5A;~e0oT9i zuIrf({4q}An*RUq+h>^P>W~NRbCdtd*J5w>k$v8H2bba(SLg5vAI6jMd3ujM9E@|x zz8H1j7h`?otUO#CWQWuFoR!DoA;IC#=H4rRfvf71)(gxtc56NBUHh5&Z}{iq;)(o- zJ>VhYKEELU%>QVtFT5Xp;EVp?Q70rHc8HJRpYjNDz#sT2eTfUfu`4~dioc5s>dE{_ zol~45pYVzg;~bc+-p@;(^2gK@tRuXe@h{Km(fCuIaJ~D{aquTt1*) zN)EA~TRnGLK1=@MHG9Kj@weFLdi!kQt@%d|%l$HVl>7p(Gk@!<;cq*0`7E6G9B)?- zVQ-m_KDU?MS2E=l?}~@{F8i<7YtP9aH@Z$o?|6tj1#dAQJREP#^Y7c=zWTksYn7j~ zAGn(L?)UsCb=_5a%RFy%A0=Lj@8Jn>l-%HeIshI^U+OdRLHUll3cJOt`3w2TAMq%> zOTCNT#*Y^FTb}&)-~QGw-7em%SF?Y1sJ>@il3(ME>{)z|{k&;k9~^_{a8Dfx9vYv1 z>C5=O%X|G^T`2MT!wheP8=22q>z2MtT!?+TFXMUpxY!lkz_+LQ*D_AATXkl6mb`#` zd>4FxGx7*}iQQVqdDeT2{2otG_mEHFKk`;~7(2Pp{kg^o{$HHaJDg|d;s`&&$IMgS zq^@N?^iB@)ba+Bv^eZmN(vi+B8vJbf=*wN3$t#Rd4u4%Ok=6@A4% z_nJqr|L_g_8qRu-ih6a%f7Nq?@e1R^x5S;hUB8&V_o(O6zyaTjf69086aJ-dQ@nr! z^56XaaQMruvA^cp*#C96`E}&Byf2A=iJNek9|aFDw4V@;87FqQ-SZQ~qp5wajd=HL z#NVUAGq>A+PS5Jq)+6#=2Qxe~cD~#FBlr^gWY6mV;^{OmTkkrE=e|qbM!dk=;SxVJ zPq@UM#Z7jOci~rgzCPEdm$>=7d|SL==jJcpjJ-W>3POE>^^1wNMGb8 z-myct5x-vMmG&>-IdB7Ck~hHt_zcJR`!pUc`hY*(SMp}`8@wI;UCsx))%{=5%Y){d zz8B9_zv3_EDeg?`=iBZ3f)8-aI8%IB$nmfL=`Rm|bGc3m2jscr3!N9F%9t-_=*e5pgH{@TmL2Grn^Mwp$;T zU(t25vm^eBFj5B`9E>igpF zbaWnqk|d$jUF%bJY>8A&sX1IKlI4&^aa8BjKAFXB(90$@@2do?uoN_ zsl1zC<1O-8a)3*49=^#V;0Bybys$3tVJ1FiK8LMWzzzAJc;S1Kzi*9o$nR*WX443HFI+1uJj*EAAtau6^@H%)BIV^a=SQk?lg}3-QIfobB8}@Ut z^%?O(oqxLSzt{6>jDuI`J58K=SAOEX^ukV}->1Fz4X&~WbvE|td*KrQRo4{<`5k$( zXYy3%R0p2&UiV@w>XHNJ%^%+KM|eVy><6zCN90-7`|t$(L4GvV*Te3k^c+602mIE0 zfj-9A`9aUul@H1nyf<~E8$Fkd-py0|3eGIga}!5mZ+r9biqA(~V!iA5!ISen?Z__4#wl@EOxN8HDA;5mFtzH_Pj&=W7#%iH+{yb9lQub+Ox8{K!De0*`g=s4Hc z_sWmR0Y0;Tye0B<&dkg9bK+y>ANlX}JQ;SyU#!csEB3E{k{`hbai3nuCph5#(>uLq zhyAk?a^sKIWz=JX13N4GYj%1*4?U{8l8^kzJjpZjzcu{VIcd*F{dRf3IeasYc#Uts zEB=UgS^vdz$SwMM(R0t(5BtYs@eTQmd?x!k6y!9B=aUUh_#@yW6}q^I4n=v$^vJfB66UeAK0nyFP-a zu@iWuP8+@4>pBSg%%L3&AKY8UUw(%l!he1$zGwbNgE!vjc@e$~ ze`arZto)RH!dvz%4&uZ13Ff^w%B%4fb%|--cd_R)^NZl#e&Y*2qIYuO&(;~^znech z=Maw-PyIi930|>J@d%H~{M7-rS|_yLBp$Kb=y7pQ(x-cA7w1W>@J#$R_VBWO-I>q+ zh*OJt`v3FGfATMV_jJzA^<~9A&svv|H{s{uUALRJvY+6?{gE#}oa2r36?>3hJgC3m zx8fK1$UE3uzDpm=&7buTt84KiIImtRezC*I=WW-=Bj>Z8_cG;a7u&ChXYy;jk-xAL ze#d{wCpi4D>q_K_M~PGP!taca|G>BCYp*y7myE+t;UvAsejfH79CZdf(|5^_;0%8! zPwTCj&$7=GuJXIg|Hjb!wSi;Hb8^%@#Buo}KcZi8Q#_5_uFciYKYMV>di9%mf!j(u7e@O$;@*x|GK9l41M@-lJ9 ze5@nz7kW_-;dlRXzc}r=zR~aT=+nE}`}OjCac{%ekI8=GNB7E$)NSB4o(3o32L59l z&)EYzi9NiTStrf>HwOQA?(wn@3g4L8gZ&GeW4&yx^*ZvDr@-5MuXPIR-FvOu<8|^2 zdc=Rk>wMRbJ+CSL{;oWY9N>>SzdXhICjNmcH| zxEUNcZl6_f@~7V4tv*aI>{&eWJmVb92CK$%2VQZ_Mz`K53*ih zp6t_n@ap)rx|VzA7w5i=eU$Qj@d$ro|8SUH(UsDMXhH=&hL9}K4wp zKE!MGjK8fuXD8~<^dj%b{O|YvT)YUsrI*P6Vf{kg3=f9`na_)H@9Jjjz5F8eknQr% z;KR{u8n3_a`T6vv4i>$C*7Nh>Ilg4QDgO9V*XhJ%ddxiEbiD?D(?4LI^b2prQ}H74 z_oQ(_9E8Jo8s3W!m{08O!W<6Mqx{SIg}xyC$Nb|*Z+bowJ|I3?55gB4zdx#$Qdw!I<0o;Zs z@;LcI^zwZ0>SbL{Ug>+;IX{*E;&mDS`W!BakMK&~CoTv7?c;FH;pI8IA~$wre7qE2 zRUe2P4XxyvTQ{yW;=qD$(QTtzXfj_#6ANzhH4s=HK}KAN=!Q-t9SE>fgQpD^EW=cf}i9@FZe_7{Bi4hndf3X=MR4I z8?O)kf41%=M9=J74|_=^l~ig;b~)(w;so@BhRz)D)x-$ z$kXL1#zVj6MLzIBy&4XS<5T-T>OL|!hCdrW-i{Zk|G;^DfcR44__eMRiBtFtoPk$( zulKWO@g?$+mmQQh!dveTF70+d2))BM`~m*s?aTJhkF3i~{qf$&TlagO27AlwN zaE!hAuIKEE9wUc4UDr?t=BM6+@4-X$Px%)=<=6BgUbA!W;a_+K-tPDM$HW(PhP+?A z+ZpSvciP9|yW*+u@-O+9_+q|!{;BKT^a5A?o;)+owXSo)jmY86IDhi;+6mLmcG4{4082^kMQN{4@GmobQ_P?6ls6A6l=$w)DN z-a0=2WzXzi-5ZVtH+FkIC%jU>^&ax!r|d!87w^O)>%Zb%HAMxw_%6sGx_~``>Eh(^!2j&lsN7=9t#igfA-IQ1?-Tbu z_g#3N=bNMd*8bwVqtETA>lE~o`7ZV=!6o*CCyUqOJARe-toA(Q*ophrANGEE{jqQ( z-(Bz@>x`+NY!BQ!p0Us9_i)A@#3S~vj^RD<&HAkTEB5BTBn(#fi zgy)MR#~@m#8-I~6Ti1x)KIl4^xMuv~l=sW8V<(Gq!o@qd zA?|p8o%o5(`)cKh@I<`@ zUWupdL0+bQf=^~%zs;M1x9%Zb9eoa0hy9#&Upf5A@7G)3=GW#WuOuIMh;Qr9@gDM5 zpM;a*qkM`S@GkbCZo_{5;`iTeKO}tfp7`T#`{?i#eiyktZ+%Q$^IdYrTkym1C4IK% z=OlgE4|TuxBkuEed^_)7nXBWme{mBIXZ$zXCy5t@KU|u39$)$^F0^is=O>Q5>UlMA z01q*Kd=d`xqu}aZ&qtLBxm_W?BuBTFW^P|T0W?*!k+Oo@j@I_w>Mwk zg-h&~UBO#^fsf&b@W=1PoxFc%uKyPQ!4raScY02gxL{u5vhm|@k^jLA-pYg2{osam zkb*`5A82v58hAj`~v>tCy~!V_mAM8a5CS$(S2cXm0zg)$uICOaVK(H9rpjr zsITgOTQC2CZ*bW7*;{b(#i&yqk9`>%b8#(p^`_@)(j$M2Jv?37XT8z&L3~D@g}1On z_~v=y(ap|_og^-=c6|qal27L4e7u+4XC%I}L->&2ua}py6Z|Un{Bp$QZ^|3xYjEEB z7eB%u*tvXG{Q=)rr-gg+=*Zzh^E-ZFJp9o(=}}$F`{4sV&)>yy_^F75WFvCCL2|O3CGoJH)qW}HB{G0#xr?v7WI0N^rsp}9(#M6zgqs0!tANu{!{wVcf^6_1I#Fxa!=w+{cnDCaLdXKsa`S2rpi9FBGuN?bU z=$+l-V^f^jX+NiRF5?$BBmcGLvv5-VKX!Yo^<;SjecN4o~py$U&XwLeI^P-nT~o?X5Xp$IfG)KaKk8@l2jhUzzXWIL~%_ zNng9&PeeZED{qay-uGO6`Ca10hn^=KyZzMrQso`|CHB1Dd>;-3$F8*h(|qBoI2B%f ztNqOEhhNY;z9DWJC;az*JO}>_@7nJwZc8C|@OXjO?;P{1aY@Q*eHo zN4#&{nEb_4a?_t9@3w9tZ^a+PHS1h>5&NIw>LQ=zN93uFCl1O}*j3`}$B`#)cRvxm z!%udFSEze(JjYM;L&hJU_1t52YaJiYw4TCl@p*ApUdcZ3F8*a5ft|w*bwc$xRdvv z&8$!5`J1j=@h|=k=cD(hjr;1}vuT*i>%%HgA`w;WP3PuKy{Kubz59{;j>%8COpZ(Ln_K#nl@5g=cr+@tS|IWSf{B`*u z{s2GmUiBs8#H;a~WBW_xcgATw3;)6Y=@%Z7|5Pv6n>XRx@GAat(0iaV-xuv$i#!jy?-Gv1zrJlh ztvpVAF)uiSk3}!5b9oRvVJGHmeINd0UMnMy*c$pGx9__Dl)m6L9LM+6|KYQIhu+}{ z999>y9s$RKhaY=COZ0VNtRKA?^}wG-{&>`WNZ+0Mi+am`i z7r#iHU97{3Yj`aCH%@g(d4akyKQ&JEeDz!YPVe$Wei#4xZt#b@y*D|}H%H!mFzW5+ zeSW|DAOFAq^Y;(S-;4+UB!Bf8JZs(G8h<(L{So4|brANzkKh$~ z;xp>W8P8eI5yB_)`_-NUqmE}idbxh0A13LJDx`8&sTzj;$|c%^uSw~#;iz-Mt5&ySs)w2#-k_^I!z+rZmA-)((B-CO*XcfdXT zHt*lA91dNzWSAs@7x^wrqAmZU(N^HE56}BqBcEY?-=YIe&$<=1(>-@Jz1ic|USR{LA< zkkt3~dv3ORk$j5(!aaOIUdAujKVE0O4-WHFai5*2zeS#p>hF2~-PUd7#p);Iqpr)} zeHRXpk9moAnb-5Kqj|r0Cl3|J$$=fJUy0**7rlFqC+GRovES{+nAgP-_a6^@UewRo zLvZ8k5s!AduFW3Uo497(lil)n`VvR*g!t)t_fvb1I4j>2r}(4#SmgY&=di&g@nSiS zlbiJpb#n2JAHg5>Lw+Hy@uT4FdHr$lv5a%O@fS~>=8vDoc{QK9|0VKS+$*QgA@VtB ze-xfM&5suMkHmgXyH3O&)Q$02@=1KZIrRHxCXSPXx>M}dd9e59>^$$^Xg@&g_Fd2S zh(GQ%-!%T{@lN>h5Nc?4Iy#G?yDdYukPy8a!_}6OJ zE9FOiAH84bJ$m`>FXOzv8?9r=N8lB{%6`zVb5l7Ig{uoN*r1U&sOe=u2VG;tPA$ z=QEAt)@RqpzS?u%@a4Yd^zvo}Z&#&plc!I0P z|}8c zo_eG4z!UjMp0A94<{RDb#!vD8%yZ!;|UwAUS#p~q7`~ps@&*0mhi{t9v z@>x8A{NWXQFizv=N9_2_c{eXTCx8;N6>HX^4;*>l{UMa4N3;Hy~ zS^tg?_`COzk9p}k^<17v&Qp7HF6*MNUS0;T;5>T{e*Vz<0KTC=mVSc+uZG<^f9bG& z7yOsLBA>OMYbUP7u1XmA{2%^%Kf9H;(mQ;ZuDjjs zdBu_EmBttLWBifBh4NB*G~eKx^8oKPpTfiW1sve-@`8-tzLovnOJbcuoHZUeiT`9g zi~I8MRqG($BfbPDAGQxry=YoLS?_){&&6^4HgR)v^bPKJ{|Nq!hxmQ)c60Ee^}#cr zbYG$Pg8!(i@T16Wao&-6=^G&*@4;8`?Zn^3xr>p*Y0ncAH_21JAg{D;C~k^(aLn`g z>36+gn5r50?-?op-x&VL4e661z z&)@+6@_unp{|~*8KY8Z&M}sHqx8E#y?tbvqp2J|i(bxU*2YH7)MI8Vi6CdS?{L#7z zKA-Wdj{U9cqtAb#_xOeTZQXx*wY*whDPF|ye(m}Q9^yH_R$pTO_z8bkhavwdFFNlp zx%3bJ@?ZTcJHua&dwzm?UEbrIy-&TT#&hv2@89nJ3w9;{RUe4oE&8sfdii0dE|KSp z{UGvU@fx0!KYb;>Z}+}Pd?0qUSm#xTk-x}8@$KN%gXRnJK0G$_eb#f^JXgo?e*P<8 zfG2pJb-H}_bm`p7jqYcMxA-|6$or4Gk5AnRo|7BC&5zg{d|)TyIC)O_*lzbx>UWY~ z7!Tg7P9<-`6Xf0YUE-5?GJljuWSo0FS10!Ns`ognTZ%96Sse-f;8%D{wLA)M!O!{Wa$JBLaC&M|%%Dg!9HDf5hL!WqAaAz#HYEd44$j`ncz(i97NIJPmF{K1W?o&wCEKE^mE} zob&tVt?TCZ=jSzkId|ew_bHHb^m1daKhrqHeeY){{0@$Z`}n{5hWDrs#16Mw_h4`G zLF2*Gd>3zF=j>UZlK4n3p5r0-C%HuqTfN5O6RCa6`YxIgj|# zKY6qJtYe?`?wCpY@y_s#95~hHu8{_w>sS)s69Fbw4~1ALhSsfWF|NxGdgfzK3Jq$M)bk zhs9?+oL%9`Q~!P3duj2a*wtF`E%D+*&tb@SPkLVip2=V2#gW7Dj2&iPC+)M+*QZ`e zU-BCKN4yhH#jn`;$JTqvAAe4r;r8GUYvm8>9{4u=5UT|M%7P=8N8>%OO*p7#Q`jZ?nQ zuf1P9iX0Z_M5zPA=iuaO?{juls zdr?0Bll7gybgB1Wz#0BU4(bw9-tPWu_q8qhLwr}NKu{#+d%FN$C2 zd*A4O7I@1qj8lH34k_=zTgX#>8oYfq^Ih_hcf@`+M*ZZ&%zHAg*CQ^w_wY&OA3S;0 zbEW(q&cFfo4`<*r`-j`=67qWaCjP@OVke6}Lv=zpllQOmKKJ0*&E_?5(m2HzcAjy5 zo;hDjoeCe;?`>Ux{aYVVcfw0O$Gh+o@dCe6pCKRlj(Vp2beg|7uk4rV*LV55cqE_l zoZPI-sJqI`mh&d{F7YmQyFO?4?3sUM{BOtkD%V?Y#1r5c`Lh%LC0@v1*uUrMOYCQv zf0CQ{72N*N{f6>!a!|(>UyR56_#>W-?@j%8v2Vq`VEUzZaUXuNE9)}&8@tVTp8RHC z5`Q6Qa#M#CFT}wq4sW+VO&%(*gu|KFqCZgFPh9@7=P0r_aR>fbkCVsY1L2eJ+9w>p z`@Z!|IEmllpWYLk`L=P^cjZU;1O4J}_yZo!zhZ|6J!g-;*(d!j^JMlG|2i#B=DRoB zALu>uh0OQzz}xeFu5tg4_uyT4LU_o>p8H3S_$~a2o$U19L-7vZPJDda^*eDY@4w%^ zqiMa@c|`h(S6a8HcQ^_6s=z9deGU+{$evj=%!^y1vqoz^WQ|2H%Fg8U^s?SA{m;B)Z&YR|!Ahk4KQ_6f^p z@fm#Hc=G$z_W76>o-gl?{P)Ty@pwGj_5+r+0FO=kcRk?Wbiw z>OA~HJrG{8H~uT%RR3Xb^vf@-E5*My%g4ko_$gkq6Zi=?;B(%8Z{&T>ujcQY%?HKV z=w)&Lf;@sf%Ujj=)RFKIb^@Q_o4AAL#P1gMM!1Uiibwn+@BdsJjy<1@ei-Km9=47L zZ_SJS%L~Y#eb75z!B53a{;NJ9e#rYI( z7whtPnmk%PT>ce3?#$sB`^3j$C+qEh2yVP*E>Ex&FSKkGIqQmgw>6j2^|!>3H1dvfcfC{3!YUS0mrtZ+|#^2u^OdpCsdV@5Y^; zD;0Zq)cTUTlm3K^=SuY@U&i;u1><24@)Y$nc_n$`^L{VyTV5}Nlki#HiQS6hk@MN$ z8=u>E5xaFR#GBqXM?U;SzM1%YtLyS`+wU`;m*f82{o*IR@E16yeiFNV(|!+mQ@-o` zpGUP@ab#+5i+f4P0S{z{){E5%;a=o(-tTqkZ~TKl`m^n>Z^8#WGw*raet^t(u|HZq z5}bK4V?X!?zT`dlt#u!9M4l4AIBMRS_rDx^d^nefS}%YPhqD$!%^ql9qWt_2XA>*yS1N4o&_K9 zsNn5(&y6uoyes(mUH4zJTX`;iCH_VZhh5)>lk7_TGB5TSIlS(@4{*RZ={ zQ@`Gr!+-TyyxRELGn^N%$vJkoJNk=GX6oK~?*7xy<9?rCM_u|+@jrfXzxR96ySM-! zFrrKC4b;{OYvqll??r59d={z0mW2;0)YQC&9E`6hHuNu%nSb^e>jP^ z;~~>Hbu{eoQrFqxD*q*4dh~aG2lsqezoIuTXlsp3e zRJVcW@^N^M@4*N4pUms?*k`vm56ye>{zW}!ireeG_k=&H56Gw3n>eWd0S@5pZ~z|0 zAGb#yVgK6Q?yC}y;IQwqfAcb5ew}$e@A^@G|G9M`am~6LT=E`yhk415*daV&C*IE< z_%%CZ5AqaolYNqp-{TwXJo7rgfBFyqkALmoTfIH!kLvdFcYSpE{bJpXo%pVK`Mo-i zd{7*ROH+Se+=D|eaSJ3mri^_*YBRXitg`9k}^)nn-qZ^u93p1dr2{Hf>FWc*KB58-$6Tz(z9x-)p= z(O93gU*K-{1Hu{nR$a?`5>M~8Pfy)m+!tT)aDJrT0Ui>?=+SwDC*2Rr&aE%=JNahjwLkdbg*hIQ z@jo8>Ixn}+M7}KU;32WAZ+kz5_$Y4TE#g9O`+9kWxQR!>6Fi?E`7XZ}m&jB7LH#rK z<{Y!_IX|^d;oJlHm-lD^^EPXXJ?$_t*=A;J-;7ptdFx3`h|Pqh;>+X zA$&u8i9FqRyg#R3awa!86a5~Ka}gK&WxPi`QlE@o7X9$z7hJNwmiI62sj*%Vy~nFhi~K^oU~l3Sz6ZC(LH3q$9yCukp7`C<-Z#p>)RTi_cUmVQ zXZ6qJ`NpqTyWdk@Ag@Ur*&DdzzMhk@zx#gsWY` zymbfo9lyRm_6@yi-wyra)p&mL^u_uwKlL8|Ydt07`L6x0>|b7=IJMFJx$2O35r3cZ zDE<7mM&Hy*`#hufpQlH0KlZRP7hmvv_OFkHU+@?6n!aao{vkWTi=wZ+xw@8m3tYmB)Sbeg zFSn00_VBUmHS(Rmx$0o%rB2KK*%khr_kZfSj^r%g!2`ve=;g)e ze|X#bdBuzHhevbxuWk?L$v^tK+P=!z^TCXM@qB*7PSjiAs(8e%>e9voZ{-W> za_Z-agNHr0*7`zlZ@cwId_dnjK4bjk09WIWJM9~X&#|9x+NZ~U%$J`;K4$|5I zUVCz&FZk>^ob((&^n3Q{IlIMg1^1?Pb@!d^xBoxmywW~)d{Q3AZoEglV{gH+m%Wz?|1>Xk4DnIi$E)F( z@lW->-+q96*EucMN1gC???>hr@RlFZFT924a2sw!p4(lY%I`n)90qYM<9}HEU#{S^H#n>~-0{KXwOsg6Mo?3Nt(3p>P@ z^7~ISev!C&yZeCfG5{hd9j8{kFx?)iS--~I0I{lUTFd%% z@{#S|^pC+AdSRdZnqI^syi1&tC#pN;J$HM)7JeQ)S?hCtDvrZdRpRLAgseiXaC z(RKN${hT$P(mT6VPlG?!N4y{ZVQ1tJd9E~$@GpLmdA%My3eVqJ>c?0c>$6|CuiJOL zUpxw4ope7}-oHKk;?mOj`3GHZm1n8X!w28NSB+mhg)?w6ICIo`rZ|GnsQ*}Zi#*SI zo`$*#yEU(T_j%9xQHP-yxXMqBGvl$J@vELkEl*_U{0puI$F8()iC4g9`8z*_KjJm~ zk*Dx4@*!6|3h&DM_lj?L2>)eo@+0d<>i^=Jyk14+Mgxvh`-_O_s6>Dqt)06g=@Lb&n zPU6+%pw6H!1ozlKdD4^jWSqxiUG-M;+de3$*pf7Nf*m*C#AzVIUa zMEyjaA%3^sbNr_K;aTs+Rwt1!vrp@!{DOSo06r!^5+Bu**|U0%ddt*qk4OFUWABB; zm++Rz?WFxh@Ep#ohrnm`TmFj=zyba!j^G<`)i}LBc(U5QGVwxum&f7%@Gx?F*z>83 z6Mo9e*c-X2KZvvJCvrP2Ug1UZ2=6x@JdOPu51ydE+I+o7{E9qp_54+J1MbEOBcb(kCQ}{zZ`~u#}7w}~E2_Nu1aXHVQ z4f|Xl`{jS=yy zuWo?1$VbGB*x~i=SC!XH{cF*$4#)5obrS1$Q#*XxebeHmJTZL3y-wFg{`-CVD)EQN z=cMQR(XYA$|MGk59r%(wbQ$;HWZr+){)#+*I}-=lxp>4c@Gg0}d65sEuWsx)-hz+m zuZGVV&!WE$Zom_HoP5W;*r)xc>`=VMd({u&q;)H}N{`kH*g4)M?yw(t$dBMazWaHc z-?%@{!~drF6o1F};DhxYejU4YUghFG0`WI|V0%t4#z~&)*yJ1>+wD2S>WYc8TisvA zkNBxNr}{7+#SZnMcHZ-K_a{c4i~bFHedM;=`vTy9p06*R zSG?KtH`p!v^d7jOeuAIqyU;I6@5U*=g8sJ_zzx(zmX?B;tz0Mof(gce2&MtLu);+2|h$_ z?|PoRbzy$Qzr+Re&GYs0EBb|3`R?INy*l=Avvoy$Mjbf6KP#V9SA;*l%iiE29Kg5b z5pV;Zh`-_pf0xHazX!GR=X^efaX(yyv+6rQ(h{8~$ee_&L9$NAVP| z_8iZd%1yrTuyq@Dt8RcV$vfaJ{Ey$Aj(C0AeHQp({NkwlaOp)p6??Fc>_Y81a=SY2 zg}>JQyyAj-Al`_#`z{`3oUxOG_OFTy@_lhI<2fGdl?OBNTD=AC!GG~9_;9{2;>-Ri z=a+6a9@(#C{ZzdLf0O@;3$c^Wt%t;}zU{rYneX{N(s8c4dMQ389>FCz!%z7y{tP$r z-HrB*n-`vA-61$|sr^XtuScyP=DUk}nz(5l9PfhX>;ZoAJA7W8VsGN?6t50?9xuKZ z`J4><+!*T!=lkRT4?|tkYDgebr^L;c%sfszx))w z<+*+#=jYfL$6~D{+>5tZS&x$d~a?cp?v_7rcU; z@hCXV-{phkPw#jseROrC!H7Gnb9F`hgnZZ`zcx%hbUg#Y!!mrdl;7sOq*gjZw3~|Bl;WNG=AEDpa z$)YcdKdSrj_vm+f^igc|+;VYNUV{&Nzj{UVb-C+7;srU-d*uJ7_tA*^;!*tfLi1~R z1fEF_>KndmUh-CQfDiO5AI$hyyHA{*>tm5W;??*(xrtx=&hO!5zAJyc+WsZH4$g$X zeds;~b|NmYfBZT6dRCr*zu`sr9-Lw4c!<8u;Q!)0BK!o8g7fjyA9^mIx@F#fzx|ft z3qB@J;Y+bY=WhKxgSUCU*}jqJaj*PM{H4dp?P#{l$H*b`TC6LXFF)lka176Z^WrT3 zlHci5Qb&qkyy!X4>Sl0By$dhO_!sxastaYlFMEDq?D_UM|6y~~jlXN(BU}wWthYaq z9pbV0vpAdIAI$jg^t*@c>lSC>r1|FkH@ct5IH!2E-t(^It>P5BC1?F_{9QbSC(+~S z$cuN2v+4lwQ$CpYZ}$}!d@M^pW4-9TRZQdatkH4R_e-DnaH#{nF z$3D|apa{-uMyzz#rjT^mx#E zGC9QFE{*%Pz8?Lh`U7{n|0sFZHaD4R9wIZ$l1C)K0v?n$|-MgU($oIuj+dD*T6mg&cD>b#1Zo6 z@B9>RAs_J$pJXTEMez1b&jBFM$a!z@%&n1!Zgrm&dzRPGBl{tLdd*S3^ZTbg-%lMo z@;~YM!0Z;T!Uy#k@4+|J8{rs#hllVVFJf1j*W2y~&-fSTsIwF6J5%{z>pfHKN1ey- z<%z~AF0cprl6nh13AckMHG@IoNS=aEvQK&uU-I44?nje% zC!T&)erw$93O^(VyjOiD&kxI!<>}Gm=TSGi(mn?~KXO~^z23&79)b_E&y44+d?WL^ zG3uF%_sGleUN{zgz3;tO)&b!gToo^jGxB`jIud^*A3V@=_8_khZg0=wLvUla_4euW z1#b+l+NXb^>lf<4#_#?7k-bI!8$I`O%CAm){-L-`Zg7Bq(PPGQG{d*`9hqbU33WISu5{_mdOPu*_|AK;a^2`Aw#d-fb}l)w9K=5?q0 zs>CDquWn$yiG8vM{wu!_ztlZ^7Y|ooBDXw$-g8}imtV)l~z4 zt*g)%93y|Y7rE{B9Bh0Bj`0h5S>p2MIOpokjQvdOU?=TcR?lH4l_CNKby`CfLxjc*C(WAV8zsPIUTktV@v0f9u{y6$|@AaGnxMaP9 zU9lhWRQ@O)$+O5Gzv9>Qjz@{(`Mvw>F0_tezQ!X@kx${_=B3UCpXHV0%+kvf`97R4{cO*>k15}MHR^0P=kg|YoA2tgTKkQ?;nm^}+*aqINA*MT!uaug@5%G^ z(MR#T`{vZ!@iF-Y{fdv)v(&Hn9lvIW;VoBt-z(k~f8Q-%A|G~WUhEwHn3uYucqGoo zuYYR)A>JOGk+EJB~qrc*$eQwqt z`LFj!U+eAnz;F4H_&9xjbJV@HXoJCAyfkotytAf6EXx!!sa`%&Lkr-FNM%y`6c zdAc}mUhLd+Je++_-}AQnbnyAu|Aq1>`40T#*LWs77x&@6co#VzjJ|#SiYwi3?)`WI zIqQpNpX4Skz!`Zuxv8JT9!`564qTn)Uu*5d=hyOm>tDX>Ise7S=r_D;cf_Of^O$~j z@HhXre{^|{C#w&OQ?ciR?o%Uw^Mc!O55LX$?~Q$JH+pWc@!&&|+q2e}@C`Voejc9i zWA}Hc`(->Uzd27&+?m#Y-p=s<@Qn}M=WE>xzm-ShX?PUgtFEh#CvIBLjUQcWywEpg zJmhBl>P7GqUllhq-z%fu{%Z6UZ~o@|2k)0(!#(^>9Z7vS@#SIft&ZH@wjYnZnJ+#t z0m-q;TwD<4s(;-~UlJR$hMJ7=HbAY7vNjOYCP z>2VHB?DOYQA2>gsc-&Kl&*b-KJwKnFOKpd1`%Y*PJ@@H4-E&Nd)3g_X8{yP2=Ijpr`RDDmL68m(2_hHX1mq)-ixQ#c; z%ixT8u{XR+p12%m^)ccV`~^OXFR{1J?F-^xneS@*YQ%SSGj%Qg!jH@s-@s2YFLjK^ z-Ir&a-oqZEul=rj8b5!@I3M-=Ro^8C>mA+`J6!BXlXt*>e4CxeFBbP;A#3)z)py7ml(M@r9o*&v&`575{qK z_05du(+uC9+R2@sV{g93FFvw2-wiI^D$kU!g}1zJ|G#>a@yNU3-ZH;3-~9giSRZu$ z>W%U-dRJeCSNL=6_PFsk`n@pfgqzKa;}`F{PHLR|#e49#$ZfG-Kwph{;fM4G_tZV| z{=M$Eg}3U`@H5Z18rSgHzqw?LWbMg_7VsE#HU2TlI<>EYT`9l2km+lKQ zFL4u35Etadi5E|MuK`>Q?ro0mK5V>`|FRSHPj-tJsbla9ycEuu7dyn~#Sw8({33t2 zA?{D}(3f4`2|g_LZ{h>;Fa8U+%`4x1+kJNNqs4xfeD}>b5B661FgchPzcVj5X1?U? z91?bAy&&)TzWbf^A6hS%`s2yiH@DLBQuvFy5IgbR@0 zir4HpdVDq3!7mK_Iq3Oy>Y2gw7v0A}{>B;mdDe4N^_k?mZ`%*x_wkqAfrr=TiL>|H zzXWGI$D^W`jrP5>bMwN(@e|{OpX^qBDSq^*{dMAzxXd2N(Recclb-hufAapVu^;N* zIL~dfaol+F{Fy@fX}&NGRAcUrfR7kH0x=J~^c^PhWlQUy3>O{{o}v?ckYez9=BV6P~T%${0k41 zx5_V~ul4qsu>U+i>%E!5|5rVCf`5q%@RpzAx8ewX2)Cn`7u`oDuVg>+Q1~p*jhqj= z4~snE7dgkSo^<~g+`uQ{p8kLDfhQT~Vm~IHgE!*g`~pw#UG|_3$)1`L5+KN-)@WBqHl@mD@hp4Lay0q{C;pC8eqID!x3A+g)j8Qd0kmU$HZhR4#o`ai#5 z|M)F@&U`o97i~Ovg*tYg|J40c?ACk80Zyv_83o&UVJ&q)7<`aE98ZZn>n zT`v=-V$W-19qM}fi^$EoA-jz|Y_?v6pQzi%@2)hDw$4t!=8MUizW?Ch!n;j@R+`yyscZzw%vv4G;5s{K`7r_1+&LUeK?&!;i$@ z@RRM4r#u{Z_;&0^-fnz>5Aa9+t{!4u)3~rU@{!xUmkJ;D-N@nl?w7$ogXfpZd+D8> zt6PdA@r%n{FUD8tF@AK=`~L6*c)N@<_!xT-mm|;T<2|>UcZ;XSiARZ>;w(RsPepFW zGwWH=?}OGw6F1jKUVLrTJyz?dc&Yv+{*rMX^*%Crv3i<1r}_Z>lIL_hH+z1F_^uBG z-;4i#)4CttC{B?-9AoFp{+QoeFBY#C=k~)NI2n81tbD{ZcA_s@T+@FdU&9Z@_l)PX z`y=oHatm(1Xq`bl6RyH%7;& zPL5k26Hm$0`fTLAIb|vrT7yL2)etxgm@Bh{B zSN?nvFEXC5yB|}0mp{TEaaO%T-2?vU1GIi8Pr<{3OYcX&=$l#Od87A|sE6Qt(>(F{ zs1IBl{L1~mAG(h~Tw`zeZT#`d=(o8(>P73rp6~VkO?7zqiLc^a{D^$!)cf7Sg;&zkqKb9RMis%z1g{!IKl_IbPetnq(*lE1?f zdVw2o53b51$df;M?)}lrM)?Vz5Iw$be-}HH&#G^TYx))8iTV#dX8d{otFf=-anEaI z|LQ92N8byak$3P%&m)Hi%?t1WdWUc7QPHn+41O8*`MLI=e0gVXUgT^&3lB8k@ci$( zpDW{(U!V0H`27CO;6EQ{cxn9i;qb@%J>MA4#6GVUhxw7`=F8sT546yyEZSIqO}&=8yUPY42;0C*r-< zk?~J)4W7$S;S9f1pMekT!Fv7l`Ma4q!?M2kFFCLWa%2DUEOB$1zc>%!WCnl49eR)7-j zyWMS^C4YGezwrCS<;(4N!gD<5kK()MneUzU8;Co`>AU#GGCr_3b$GlQ4$vb%g){o8 zVz<}*TM{?$0k;CGg%;eDv z9Don(jh!1Oek*S!ANCVDoS&1jx$`go@SlIv`#a2wJ@`F;hbM5G|B4rIPd!lGSRApw zhBuloJ+gCl;`fPDKaKraR~vt=_vvF%&&0#oKR$rZM8EG^pO2p&*8b&>#?SuAM}8VS zf7<=g`gzn#*#q2A5Al9@u09!m+^l`Vt7&|{-F@8TZ(i1eyhpw!e}oVChWE?6t&_^* z_$hg^fBY8S$~)+h9pYnozw-*-&)BWJJMwf7>BG^tw$gQh=<#6mKcAmNbLk)c<-ht@ zcFIe=2QQ*``B&B@FSc$Lzdq{zHS&pH>~_C=SLeaDv?@8XX~t>^H^%=fT)L~w6otP5|n51*YIXXNmF#%|Snm+b)#s~^G> ze&;#8z}w)`_R!-uT|Z?%>Y{L1yu+*I1@IqFBY$yF-v~a;ZkOK!m-t=AZ-40hv3@5X zyx4UCIH?YRhxjg>#}m|7`J?zAy*zAxrZ}ZeX#DVs{jg8`VTwPeji-2^amrsJhn1dB z1qbkf@TI$>KCn}MLXYwY_7=Tt4ZHfW_shUBbpUY8DL%lj{XX`5 z(DUK(cI$M;&kpT-f>-d9oaLwLLi8n%gR5|IYM;k5?~lITwr&P*@pf^9zQ_mPfLF1H z&*g9U4Ed--Mh@#;cg}mBRFBrj<Fdz1B_6@0#GMagpU6(nZ;U)od%kG=;(hOp6_29d?cwj|_dkuigTGAk z=ojs`k9^*Y^9SxU&WbO~^{YJJox?qK81s@BkSBk%f5$kjYlzoyAn$h`!i(OsLto;i z_{*>1&(u!N*XzFIYp+`0CI|KgC-EOR89zNg_wKuY@pu1?zqHqQ3ODdNa+dFi@9L$Q zuk*>}*T*BTaj)Fd8F}JGi6i@Cz2IT{ljXUY*Q44AJ&K!nk^D&ASllsRI3GJXZXb^P zC31Mx^K28Z7w0PEyE}9I0{_hO=QH*L_wXw?&rZZs{x09id+fKpGy1C^_gv!e&j;gt z!u{5J#p~d}_3ry12Y618v8!)t|MA}!tJ)_Z{F@{3;7iOBfmDz_}517fn^WySzIQE*pGY6Z?tZo@qe80FZPMQ(SQ6` zedcPo3k7dun$({DCd5<^(hshH^3_jfMI<@bL*BR$Y*X6}Qc<%k? z1^@B1=<%fI7r_C%Q9O-2cUv#wFY;D#mfX|_%8s63(lWtB1r-FN}K)tOxCO-HKkU zFYp)mA3WJ>|DL$dFT@?VO)vUt^i`(rceC|;bq0JXa(L2y4}6=yvqQXy{P9xx3qMs? z4{luU{&e!eGp*B^ulxe;`MrE9<9svvW*-%oeHZUyC-g2aWB+iTpYj*$U+U!IJDwcA zcdO^V8V}s#zj&!WlYIAn`&(kSi}R?}?IVZp+c#o7;tm{$9bW3aQPcX~ljik#ey4pV z-j8p~Bg7HB4i3O={0Be5XYgBgnCDw_^JRzPHC_aN;$QALI_$kC>WbmR&IjIW-tGOy zBQD@k;yby?%j6f<1=xvr3J3Chedx=1!WX(PCid{%;9c*>IHB8MgADQ-0wXv`R-x!FL~gc!BT9ci@Kc>kERP;#B7Qtow!S)1lwk!;P^{@o5HE z>6hQZCAb~?-0!{;@k0E9ht`AC!|`D}3eLbQaWnFrsm=Ws*3#y>q@o>$~{ zG$UttmEZr|b5X=8@hf`{{fd@l2dG{_upyy(e1S5eGBh_13B2 zEgYjSe2*TMjy_x?3?S8`VGlGo(K zK=k=U@9KE(+s}+AlYic0|K{Rc5&5G!VaC7P^Q*;Ke!;)Q5%D7S;2hnvaWCqP5x<;Q zyx)4o6jy&8aeSxeOsd1g{vXcar+6f8;!*q*FQQ-mE>7{g%fE(hAyxaKkg#3P`bq4$jZiGKv>iWKXoc+_UI1B&D4L-<&f&=@l zcd;MuF&=&j5BZ(A;P>){=zX!TGvj~S^Tzdy#;(rBy)$>4f5Un9!=BkK9?P%!i}X0m3@7=Q{LcUPe)+z2w~TXRoPX~A`u)xa@6tD-uClz2#va%q`-$CJ z?>OqYui|)qZ~yP3t|PM_I7XiG2=bR#>T6=3k;87|b;h$l^48Vn5%in)pLRVCKFIIz zCGSz!;xFXyIUcJX6*=sUc(gdTkl(>uc<8&a^UdDx93FC~`myfj{qhTTh3CspgTt3w zxAA`ZQr|Nk^QCwA&z|vKdcl|QPxZs_r3*`Z(*9iMik!4xSA8b$-x>SUuZ;TY*X2v> z(7GGEO1%4VoVWJ2=QqOt=>2qtr>Q&T`NQHQy{rH5-^}+;&z;Jc#msvNlJ|({6A(`)P`|Tr#N976hE>9E(?JLRn-Gi{zcqA_i4_WMUF@E`@@xVj= z5=JSR3~{JZZlKzN)S+e>7ipQF<{Rc8KkHrJ=kMk# zpTa}iDk3+LtIaK^rg*z=?I*@`dnKJi+n7?L(fhle*MTRnL-;T5SWk=}9rgai*wyFJXLzyqKjJx= z*Te2Vwf=<%Mqk^5*WK!QefYEYzzufAFT@LcK)iz|a6WdmQ#@g}cof`-e?45f2lJro z1^798hGYB!Zs2?D5U#RM_?Gy%-+kihwBC=mkOLmhPVltYn{)D=XSmb;D|K&imVK%l z%YP%!-GO_~3EAzsr~HE4-O*#KFfcXziZt;_H(QIzS#*m zz;pJAzu{MYZ#~-h#ox&7X7586H}T2nYrXv^;wk*pKZ$S9qxG`9|3U8sBOiEuKcSJ%fr%C(-0Mb7*^`aP}P>T}C`+{^j7;};k30prB~tyAD>_?7&c z-^mN`AO1^U{5^j3b^GDrx%fy9^vGYlUmYOvG+9wWSp_*S0f)e9qZlq z+o!=_#3}q1FH(=9Lyc%Aqr^!>;gZdR78-Kh$hyR(^)1I5B9;Ge>Kh+=PU-%Nekf*p0_k0(Bga3)w zH@nY$DxZ_)W%887ovY2e@hf>2T=M>m=XLu=GS2gJy8p?a{HOo!)>(PA@8V11CO>7* z<}1&_-{3zSlSfBii?}Agz$@65_mdACR;T4hvA2^^Kl!%%PxIaHy8qq##c_IJC+fiX zwmuN?PJL2*gk$ujPNM!0IV|og5JLQx74iAqU&U#L@bv^G1 z4qO`RO=s<^hhyRtf8lrdn>-F~hzsyg{1PAi9?q)|uuuHTIAe!LV}0#<>&fB^`(!`r zKl~BC!5{I9-{I}-D)zbCa~`I4d)9NUr}%ld`_}n;>|t%rU-JG(?SG5kz36^zzt6n( z%j>M~u%EpDUhTnr@d4vkm(X{b=ZDQt@gnh;zO3Kn_XoWvF81)S`(;wE_;rRK%J1aY zo*RG0b7_u8#edJ&r~lET|M}Iw^JtvceRIg?<*0j{%-BQpYhTs<=4JAQ;NHjK@6WnU z0UzSm&$@pZF2N1skDV;ePsS_g3$KuO#6F)7JUM8+7Y@s7)YaLcJX9S|9l&_<-A_Xf zhojG7y?wBFCjY{F^W7hcZ}cc`inDOcyx56+LHsfvyeNAAYR->*H}6^O?|`4|P(C}2 zJ1=@KdHBZtkzX&yFTPtZwvLcE%TCT(mx!Hg%;gK>8eRcU*n>DFj>~J{68;bz*zb7- z(c{7Bles$1>HVhngZq8te>Uotx98*ux5+c|xzfHb@y_qbfxqA(dH;F+_)CA_$B}nm zEKkUMSLfDo;4r+*bA#!H-Ddpmr?}9# zknesN`ImdaPKMu|^&DpSpbiE%;4S?|kH_7oY+V??%6M+I4+>tfPwS83KE12oiZ5_4 za`@bPox+RuM?Uqm^=9~~PKE!+9u8;A@j~5Ie1|jBy5dIf`_RvCzUp}7gP+JB@dWl9 zKfTxehT>!7x!ZI8!xMIU-VS?^kBfuim-n+b{;pq$zUUV&<@fKpFIAl|zhCdUaCk!O zZMFHn`UW}E7k(ALJ3pWIOWfS5U*tWDa|rS0eD|Q|uc~*!VS1O3vp0F7-&@zlhclkN zo-?M7A^)OB_{KirOrC$!d=~Fr#$od{PWS`IqL0dw2-HBY*K--IbkNCt{!SJ8=PDl~+dZ+pSmV2Y?%RLgesc&-YWmQU_-L@GZEi zet6n_B3VbcIplV+=UiEr7vJUG_&>d~TY6{z^d(;7&+&^FU1#xoaZOzXua3U1whk@#`Ot?q-MNBI;x;VIp zH(eV%aB)8cd{B>-XUT(tOIsa3{FJX5C;V4GXIK14Jj(M|?W2IV`R?WNNp&9iKAchq z&b*F$Zh-tqJxBb7lllG0xZm8p_WG{z_Onqh{b}%l>y1b7+4$*K-y=I0f8j8kfj{yQ zco=;6ZtO2uoLi+nWBl-ty}>28k?&ru-o+zvlRwI9*a^FGZb0<=rsoL3|H$)F?ceXk zck6nwhokNn!#DJsv0L?Rb$)h*SI18uwtvif@K5=XbusY^PVzhX4t%yBjbFgADgJDA zpDcXy-N^0L=&!rf`vurr^s>@(mFWwA@E-D9ju2$OD zil3{O;tA>-_(SmLxc6-0Mff(k$v2~~qj8U_{Y@v;JN?32{6T!5`lJ5*S7RULdh;^; z4NkIWa$|4g39r~EJ|_ICT?BA++SQ{cSk@-Olc*Wi_S?fupzGv9;O zXYdF4BYm+ecy7Lt=UUI7nd1M)fy1}Eex%+K`?=fuU-%3EQisvk1oz-)?C{r~8!X;s zoG0VF)+_Ck;V*b>>~?qT3qD&q=j62e4)hP;ljI}5%Pa8~b^;&pI&zNu_j-Ol{=?4s zsd$9{;8*mBUx`!ffxXc?|78zw)pz-IoI;H=}}w= zzq;M?prSAGU##!IdFvG7pgQ)loZ(n-(T5V-&SYfkCFdQ>q4=sjrJQv4(~@F+KoPEKl$$BKB?vP9rz$Fye|gkRXL%h2{zQ-JY|nb{mG_Ga!R?(ne2CqipW8d`4GFHk z=)H3MblJ|$hrh&b&(C-Ja-Zx@?+3vTjh{dABjb;qZ#BQbOVt6qUp@u*VpnH9|CW3r z=V#rgfN%5D_~VDxz2qI@thh$+!PRR$|4=-_hmAAe-5%%9xbJDPFMz$lJ@&)zvYz<3 zcxb-*yYPAMv7XLP`JMU77xfgXiV<+nEYxDT~rPdALje3i`Cb)NN;QwCF zCuCRRk@3iv$zh61i+eQm|C1X(mA~Ns^cerT*7_mbfVcd}Jml~48u-kw#SuJTUqR;e zuIHKaYw<{Z(s# ^tw8!mi-I`Qn-KEOMq7@`RIleyhCK`{5Efum?C}-Dm2*Tf;u> z)1==IBfmRnzasm`bAn?R+Gj}4=9T$w_C5%_6h8^RT^#(}xeeb8JpVk_XV=Giy?xDx z#Q}2WzxWtFDev=~p7>qtbEWH3(eL}2`V3qZr{FFBiky#np1(NddGvLoe1m@Re06|4 zKVR2cy0@MEz)ADsN3rLx=6EJNhhy>!buDt3e)nYT&wbnTWAok9A^(Hc!^sbRS_j1c z%}ZQ>pKwxLg8gJ(Cp`z=`1w1W=Z|n0e~`Dbx8UmM(I;@JbqT+h7ccv}c!$@~<22qK z_S^<_iTL~Co_cv79!Oqzro0dTm%pfckSD*uLt=*)i_h$Hc^yq17=M7P@?v#P_#=PB z^W`;>=acTUz>A_U`(eeSqxK0$?^|Hnh$DDu;^z6jkbm}1|Jpx(d2`hBKaTaglcjS- zj@s`BZ`HNnBtB-m`jIl$!Rw;#2Sg5H<)7o(VVnKK6guemQ>1@6@+FhcmIm>#c|2WBAf?JzN|YcdYwZ=YqG^9rT&R zuUAK3+;;spesR6`r$i1{8uv4=v!25&-{&v#N`4Bj=n;<+U+^*ZPcQH-_V!?`vp*W= z>B;NYire0kxNvXO6W)z_#mnKRS9;!N@PDJ{+lw#iWBiU@{GOc2VQN=*dylhxN<4-C z){*%aK93*5tK=yc+mDBzOxFvpHD8GTuC`y19>qI;5qo&hen|6Dr)9VDdioNtGq1XbkofH0$o4l1>$;*t>x+Fd;C*S__JOAvhJYXtKO*Znmoxtp2#oYRq*iY()k!?JtqoJz~9v2#VPuQw~^cF z;M-sKekkMA4?u44S^SmPz@_kQeX8G%c)iy1OyrO3P<#{@#0!3{?g0<=J<^xFn4iik zjos;$Pp^PtA+m;8o=Iq~{qLzxm3i)EUf6T^HWw{db0b-H-XaIDj|ucYFrF zlBcU5;#c@2|INH!_q=8P6}{hXUj#Yl{nr}@#i?byVlV8FJ&>p8@{Y*iaO_jNP`t7( zrcQ|OMLsWj@4R`DzrJpIw{ELG8T>!)IWzD9KC=hnyiPu_1IZ{pE6BOi2b&-wjBfBV1wkG}h#R(k&w+=f5mJHLik z;(|CR?#Peu8N3dz;sY7~ht^eMZ`)(P%vU2{woY`t&*gXOwBkO!zz29s4zW+`0_$Ua z_E!C!pYmUMMDmxN=0WhE|KjcH9{3(T!U1ugUx>^2xp<178&Bf$~~oaB<|zZ^nKE`_ztmzX1Lwu8D(iAUJcY=dY^og%3RX&AK-G;Yaky-r%Zy zjlZxr{sqtFDZXpI;-Gw)z2&>-_pyIjr?}SphNi!F&h~HjgW$bzgPpKLc`lyJFW|6o z!gGAvd&mb4;7f2oe#(zLk9^MeV|}@w>%!m_4~P8SU-@It*A*Y(N$ls@3~sO=ddd4w zdk-3WhHvVPdH%HfhTyaJ@Kb&f{=YfSnY_2u=jPnJyJP>(O7EreU2#WVz%Td_dBPv{ z5Ov+?YjH1z_zowbC6;#_Nd&wJE)*g2dOzwjb>P7d<)_{HP)yNb&h|7!O`iAQh}|KX?n*LdKY zdQSZP{J!B!f8!tg(VuPiJXPy)8Nc(xcgOi%`|W#-Jum8Sk^hBpfBlX6JNtxJk;7tt ziv9s|=D(TO=E(PN_q-Z;T;kM)KDQn%KV=W>Q=W^jvVZGYk5+WcoBSyA+NeEb zJm>cSjrBV`4L;*(>OA--eR&@Iah}8H!LJT`4)%1t_;@BCA?M6@XY3RCWyap>=}Y z{`Pv~b?o!i@UK_hFNP1WPdwartp`O82VK_=&$%^t;G^!#;HUgcKZAM~++)xB*6=I# zp#INa@c-DuYR|1QPIVi2rJl@gW1suYzkHY9kwe~pG$RN3oqWN2*hBPq+BoYu|JBba zU-16SYk%(dcq4nGFSw28tHYCndX9J+J#KYnD5ew_cXHF&=B5KekN zuyK-S^!Tv-0Q`ubW;~029)2Ni8V`PMJa`?RBcH{GOJ;JNj2d>Ed@U)0-w8S(dZ^+KNX4u9}r`I>r*ypbLwlzh51FgY4Y-Bo~`UXPnQAhj@rM1s~{&y8_`uZ-l|4KfhE+Ox>9w(2G=O%tR7iF#eW_T1_ji27=eTe){y<(bo zZ_W7y{)0!sZE=J>L~g6C8^GJ}!yiXJ`>^pP&+Q-l(DT{k3$ai4((bhmDGtJ0_Jb#g z`|ugA$~*Gim9c(z*mJo(&wO8X-JIRx3Ge|9sPD;}@F;Ojot*s`KmHILIBdSp&gDV; z(Y)wAc=&zKJ0*X97ri_m^~Tk%U*|nPkM*z35jVHn&lx#vj((eu?L)w?#GQ=)`Z#~! z;@~ZB8-L-OzEkxF{F%M+qkMN^C*-WIE6>H>$VYvQe5^09+t|s|=JlxqZ+4wjTnMh} z|9{(ieAqeuCNGO$zwUkkaX-(u+pl8XgrDMLaFrg#Q~5YMWaq(?tBt?xB>Z-*>nZ9~ zaKn47A4UE*TMvZu_<;JMx~04(^Ln$pN0jpNwa{_m9U8zaHxmTkW^cytca@3jfuM z;IQ=q@q!)V3G9=c)hmosJvnldU+njuIC&x*&iIc zGC0Xk*%dqCN5R{d?H~S&`S$4yj>%uxPv*PdeO}Wz_1(z#U$vhT&ft6O2jAvj-m|=3 z#vb4p9%WrA{(GVII(0(zZS`LGOm6s$y0`uW_HUg05$>^b^?Y%YJ$sHn!=-%pUC;MW zufqf7*TyM-jGgG)IU4@;W6zy49)96HvBUM=&!Yb%c6+P)=*1(?6PKTKzr1*dcZH|v zZ``Zh;`#K&4#{8Mp$@OU=lABT-zMWfY+X)V!%xUry;^=`y#T(!XLUS&0pH}y(|WA^ zLHB#ku)G7$G%xtTuJYZ*ejoU3JnCuu%X{Dweoim^PTdB-5|51Edtz6w#=UZP#yx9m z?aznXIU*Y@-!af6gSz4I2Awo-2LxUy&rcyMZ9KL@vk3e`Z3_MajFaD{ZHE$B(A~L zyvKbCC%p%Re$5MBiFfAZxjZZHKfibDmf!TsQzho0l- zJ@QTQI=olk*Mb*`v-GI$fzOEJ@DOh_9=w8lsIHunW4zN$p*-!j#ch2AOcI*4T=NS8cwv;z* zx1Jz>kK7*hzUJV-TF-06ulO&2Ox#)YiA8SfgD3pdduQPM6yGlNJW~0c`UyRd`)a1~LjU3OanAYTz5skr-ANpT5A58!48OzE z*rE8s?=s(uJx^X9p}yqz>;eAs3+p)Q@c4lG8y@KQ_!zy&Pw^r=3J(l^u9pA6H~5VA zst0ELcZMDp`%=kGeJnV660g92_#?T& zfBvifAl~7DejmHCFZ){0)hB0m&hPU3MgKhek=MkoK8$?-yVl#;xxCMJ`2{-{AITH` zN1m4kFI{aNK)m+*=>2*3Tcr-U(|p7@BcB&DIIM1*_ne>q_ravm(1^vMt{x^qYiMl_uY`Qe2V|dJJ_fES{(rX z<6YK~gJWNhJ}Z6TUk`lVZCwjLkNiE?=YP`s$jBehgy-Tu9?MRGhwd4_-MG&l#IGqn ze;)Pfwbn)9>i=KY9V|z6T~Po9S^W&?pfF1xAKwL?b^Vx ztL`Vqv)0StA-)qYncsu%XIuAw^%=M%ucV9UYIq3$@wK>SH}wts;?&<7dM+Me&s_hi^)Y%+ zT_X0mGk5WhB=h2N?(7{5A&Bt$be$5v>&wu`3UN0}0#?h1RhZINr#C*{?;+@`*H_<e z3HSP47&?dFuKQK+^HKYA!cX(a&*^+|2S4c(^%MM<=g#KV%kXu6UmU6%@k-^_e% zb$_z`mWjuEL${v}exXuGV$L*e*<8OK2AI3TE zPwm5lU(^BUWasqN+xY{(ia#IpJd5~+w|Ef$vX61nrLptb;dEZ!j_+)q)gPujyWDp; z>J{)a^SJu10ec#cx)wdjZ!?b{$M>^t_Z(~Nzcc3dM(Y6f&%;%IBHqnQ=G}MG9`~G1 z#(CVnKcw zW%UX=O8#Zu@vM42eix7O8u+F@04LcW9^xZ$jd$>fbJOrP*MF*=`9B@VAJnPn=kVa0 zey5mUsgtNb(DQiEyyyCj_N|S7{-^7t>e#W{&&^NajJyD^(Ou$2eo9}3PxXUZeFvHT zfqVQ%-j{L8cRseCy!o}yf&NMSF2BF~&%gcU{NGRJ@&a{T^-{P2Pv{MGZ}=%*@UMA? zS9C1B;d;+?o;rSVe#rmh4@dQL{+ZwR+W!-d@x!U!Tb-X(mxeQ*YaZ?6qHp1w@x;!n zb1ry`>k1F?IJ`}~oQ&^8+mHQXth0YR^3BEA2l#N# zujC8zwTx%gw^=<055i}-rw#yT_$_^_P6$8gO!Gybh&y!;{LT;IaO`v5erS2_Z=+Ae zPWukAkL%@q@$<{B8>;IDH{P~yCp^sc%l!nSPXgYD1MCQw_(`6-(fUu~^nTA<;Wcq> zy&%6|A3Ae;E+1UiMQ}+z0w=w%dN}=w-`$`6;Wj-G-qZ*9sQWAA_4G{aFl&EHya3PX zE_tGHvRm%+u60iQ$PejcI2?bQwGZ>u57kK)-S@&i=2x6rM^itszd{^^Pp|bmGS(U4 zBwTX6-}xbX@>|b^pYWd@;{T^ThY0`WS<^Ur(sdKh6&LVU-i=>^^SfPFVrTef9|fM0 z7vRU>*nZci_?5VpzsM`CXPGblAYV|I#_z5dNBE1b!$`&8f~bq4;%{`@WP<=o=# z-1XtjhuzO+-h;PS-3KL)7LUdWe=^QDU6*$~JW)@>*W%s!4t&FR?3uW@)9)hjTXu_` zw|j2a`_l9AAN|et>i^<`?xHK`O!=()tDnFz{*RCH+|~ZT=)Es{9!;K0w}@YU4o}!q zJ%oKS&hL9(48E}&zw*9#ME!^UgsbvI>%3E4eK7Kc-MP5QI4}FX81~QoAGJST;{B@p zXuTC~7-#(RLC>48KODe2;uOEf4!<1Iz5I&(@g2TU_sD&2H4jyXq~M~7ccmZ&gX}CnVsPeo}v@@GrpipgTtF$ zXMz8C1fRm~jDOL7v+_rHg)ht_e1^mPP@KlEPTDs~J&m4$|Ly}f;Ho@Ao^D?75uSBE zE4Xy6eJ{nk`~vRLZ*-u1IlR2tzMAIUeek&b{Or%3^e{V%M|dTVU}yf8_kB@)61%DIrl#r>(qNa4OA zo(axB8|PA=wokSDn-~6!2j$Up2pqFcA>X0*@P6KR_1)6M@4c};{;JN~eyTsHGvs~Gx*iP&@GqUrZ{vq2ht}QjNbIoe zdo=bNvok&okAE0_PTuw$6Mv&0T#p~+FP>{(jXW;Duhz}s1{_d_G%s*Ky(@Tl(Y`Tw z0WZTh`)cUe={TKFS*;7>M|HxCb20iR-Rt+5GR}wn&bvB;x-R~j&ey%MpYVS5u=~S3 zaU_p}WBgEj!7KF{{tVCAhrW&9e%bM}k9m|Q(vAF_-+Ev6hfC8u!gmU`x*m!j_AIa}8+i!lNk9loCGPko-Z+HWm> zxZKA-`f&0G`W$bnBjvp|s(<32>V7|Voz(TY|DyfATyK3%{)@lZ$NFjf@aE7tAG*(q zU$HZskq^R8_NUu({Z9Kl<2Ci+;M@Dw0q9kEiuqlygLy9eq_@SX`BDcHUvwrr8>hOH zdE z|Nf{SKCBMppV7(J2cFo6a5?Pxxc#Hxv-_Jb{-DkP|M81);=AapA9~IRf8~Amx-VK@ zKgGj~?!%m}SDyEr0(~|0lh-|m7`$5b7gYyi2YNtU@CW>bufM@rU@yM!y4Y-sPux z?yTz<@}StkcRKE^eGlc$sJC2o{Z9TH{LvR;RvoyWFR-)y74X4(`5m6q+xS9#-hKFq z{3!8$bJR;eH6Juid=&ioqBzWM;wAUL-hIVz5-zC&!*lC>>PzeVD=xwpn~g_!Vn2y` zo%}TOyZMLnGKrUE-ahnC^w_(;FaK0Wf)8{BJYfg%!k+w1y~X&|L)0JQSLZ#y7Tnux zzDY;nS-2;UGhg&W@aNa+CG)OcftSONFGjs?`MuEp{`%d|i`Dl{=qNg09?H-0V8*}G z{wMt3egk$;pMmrA41F$s@iH9(C;7SO;%oXL`1wuwSDr{eBrfju`*FGcw0*+qH1%qE zeV)7gZtCCvb@bPN+-g1|Z&fF8e||1s;3uxfzv`>-%I}%SjjpHDX?TQgTpvIEDNZxL zOaK0yzh7_vVY(MSh*SO}Uf5Zl#Si&E9V)}`SKfse|-Q#1wXDS}eV|3~5u6G!J#-l%;?;ZS99SBd@ zA8wdO`$+vBfBw39OkDzQ(?xmitludUUzy)OcOS2~kYCU<;)`xEU;4|5_xQu*&`Zx- zKf#0i&G>WuqIKG7938hWoP0stiAR2{E|Ga$eplo({=aWO+xW@BIEVFBziVmU;U_(o z`8w#iQ938{`(xMp;0*p{ANs-daDzTKesv-9#h=wB_?0>XepjzBesRRk{8k=KFX34@ z89(0|Jo~ikT>J{}v#0eV&&B)jEx#X)e&F|;2f+clQQc3zL*II?`Z=5lPo4E#t$h*n jm~rA4^`HFyq36ihO@5v6U$y>ESI8@K|Kpy2mtX%5gBNxz literal 0 HcmV?d00001 diff --git a/examples/density/dataset/qm9/C7H15NO_train/type.raw b/examples/density/dataset/qm9/C7H15NO_train/type.raw new file mode 100644 index 0000000000..c46e48ed0a --- /dev/null +++ b/examples/density/dataset/qm9/C7H15NO_train/type.raw @@ -0,0 +1,24 @@ +5 +5 +5 +5 +5 +5 +5 +4 +7 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 +6 diff --git a/examples/density/dataset/qm9/C7H15NO_train/type_map.raw b/examples/density/dataset/qm9/C7H15NO_train/type_map.raw new file mode 100644 index 0000000000..36c071bf5b --- /dev/null +++ b/examples/density/dataset/qm9/C7H15NO_train/type_map.raw @@ -0,0 +1,9 @@ +Li +Ni +Co +Mn +O +C +H +N +F diff --git a/examples/density/dataset/qm9/C7H15NO_val/set.000/box.npy b/examples/density/dataset/qm9/C7H15NO_val/set.000/box.npy new file mode 100644 index 0000000000000000000000000000000000000000..2299ac43d95289816da6876c83888c5c6b88b351 GIT binary patch literal 2288 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%o2099snmP)#3giN=pvK9$50)u7FyH|9{vYQQR#U+#?|AjaRfe-l4x{E^ c55Upz8BIT<`3o~|jOL5cd@-6YMqa)E0642=EC2ui literal 0 HcmV?d00001 diff --git a/examples/density/dataset/qm9/C7H15NO_val/set.000/coord.npy b/examples/density/dataset/qm9/C7H15NO_val/set.000/coord.npy new file mode 100644 index 0000000000000000000000000000000000000000..832913a48de0ea5e075779e2841c8ede0436a20b GIT binary patch literal 17408 zcmeI4{Yz6(9LDd^X|B|}x$UZ0F2pT$EXz_0!-ujm$e2jko0ho^%Xgfz{_znQ+ACSj2{GJDOxpc^i}2$7!-^Oc2j5|r7`s@4kI8L2RZ=H>{!-tOm*#^03tX3Z znuXVuf?(xQJMdIFMe0%s_I%|Jm37#mB&nsU$6J7ES>+GC4F{tp{>r{#C%jI$HtQHR z4~?CV&Ia1rqhivu(N$%Sro+zNQTdKo7IgAKaFz!oa(%MTdl4>{)y)06!H4hLI&%Y` zg|xx5>sYh|_cMEHMRFOM_6qzk=8k)#!toty4io8HH~6-A;{Egh^UFG)$u;e+fq5+I zYztPIRGvuB=kv{@j#HiE0|hLLPxY-Ix}QtXI$-_T-9l)54+!r(lVX>3K7I$K@V7IRoMW7EwIE-$ z32x}<4wt6JEP%q?JdZJn@sx|`D^rVbSUFI}V;GD*j=gQix#D`3U{Ez>14G>RsE?5> z?)Lnw4oehc#adQA6u`r%ZgZ7UXM^5H#`5GtQuOp%Zp~OMq4F>{M(pH_%bc)+SFsS= zG#j%MYaHOypKEgl&Pbb6BW2be3s+7o)lCUe>Jb%Lchdp&-i2O__50;V1lq=z4(R=M zG-rDh52oB#to?dEX#LRoq4h)i5A8p6e$n|w^$*oQR6kSwO!YJMU(|n5|4#io=|80Z zkbX$|A?b&tKa>7U{ss9LMgA%Ir{tfK|4#lp`g{?R@s$JWkj+|Rw3&hGP74?kL)eV-Wef#R=z&} z!uS5|zJ9tN_v1XybzaZc>%?j4Yib)~Vt8Tra9P{9KXBucWag5#73bn(=CXBm^Ki3r zvT$~@w)x+=lGP)3n~QUIdn*^4i+Ao@H~E+ag+zGxnEjale-DAP*Ao8fpgSaW*k>hj zG3cT=q|)egxGf9;Oth4V5}CbOdBMJ>kMD4GleZcz;!Wvj`%ug(is}ni`qcruN&?^o@XJYtX;x<0s=@1 zZ|hS|`-^CX%N$#MHK5A3f+Q)v2GMY4y3lwG!{tHGNqTHD=z6VwT}iqG{rB>*6!j

M3IrTh* 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 Ko_}rUiQ#{B!{A&1 diff --git a/examples/density/dataset/qm9/C7H15NO_val/set.000/grid.npy b/examples/density/dataset/qm9/C7H15NO_val/set.000/grid.npy index 961264ac8b09ae0d7e9093ab4600b194fccd7f67..493c2a9867a67b4242d4e4404ac7f07a7d7dd55f 100644 GIT binary patch literal 7628 zcmbW+`|nqE9S3j(MJ|c~-qS>(k;z09Vwrr-`{RWO7nTc|;f>;^3sJxn9Mc&h!n~k{ zhNx4VSHz*9PKAa=7%rTtc?~d0Su7^g#AvWykJsmO`UB#p!`b<~&+GlXyry) zAO7h4eLDQI!?pd#PniDmY5h;_)Bm)IgZmHY(|_XBX)~scyZqv*)5cG5fB3jxOrH?< zr%xVt#f13(w}uSpbIQ;m#}DW;yU+jmuiL6=%ggd}M^)XHj4KOgtt~IiIjp(ljvmd; zje8o)&)rz|pL}Tb^!+Q!DW@IK{H$xo=9`PYQT9E0TeWijh%&bGrt%MaHhB9{Z&DC{#H&lIl^=x*1eN;K;qOI;Xp84#!^4?|l#(O81KdkK8 z9NOc`vTnw;W##-=8&{O*wD<&vjn zmCg@#YCiVUqne%X?UdKCm(u;x8O44*V_)ig>hlie!kJH(DL1_3z19Ac7d7nho|BHv z`bVGqQTb}XoYHN{N7bI6%`4kFc5Plbb6|DMnmzHZ6U(Z8JEH#a)s(XjE|+YX6nnh7 zOga0m(joo@CYAjLwprU(1NQaXsCiA^htJdZ4=Qt}G_yANyf<`gdFHc+s?CkVbNwM} zwg!fKV(;_Il~;6cF8%WP+S(Y6cF~(l3W5 zN5Olg&I^w{qB(b;1Dn&&d!yX8_noq$@7Kzki|#KwcAr{K93S&1+m= zvgOm_`S*r?PzKHaO>!EVX$)H3nSLtk&<|amxU_%Pj~7^N8NRc?ZO85x%cjjQl=V9v zj=gUzgLl4>TEg`O%a+(ya|-Z~s(7;t9hewtT-faw+`nv|xheE>c&HpDn)d9Atjo>1EO8-3K{^xfd6W0$_J72st*QYVK zO?~2{tP@r(U42oycJJ8i+iM{o#t2c(6IVt0^iXCzW57Av3~A_9;`zfbiShR?M3~x%7fp$ zV|Qu{Rx~eL_>`WfJ~2-H$=5w6Jy_^p4Y&vmH+jdk=eK{du;#j&`R$Em<0HS%-%da8 z#|77X#Do7{@J7L1)L*^2yjSGOi1Mdb9xMkf-y2!?O6C>M!e0)+ig&E}!koLy{EpjG zOZLkna1Kl=_1ITnk{I&ctnYo5nA~^VOUcWJXZ2P?7nX~Azg_H6hPZ#gRUMk%yK>Cf>^pe8 zVA)Z;){v`F^DvsHXEh8u^^3d?E*d;e&pe{n_^sZ7UtTz+-*1zn*n34+o`C;2D|O zY3P3G3;T^4GUs6jANgQke5BvCJzmk0ceOdH+?P4>N1Y2EIkVuJ4sosic9v$Jjh-02 zdr+=p?{w&0fmP-V&(7WFmNpj$26u-RIKyB4`o0>~Fz)^Lvk$^V&4F#`?fUfEQ=ea7 zb1lP%nI&Et{$$j4Rc06O(?9RaG(DQ0^>p}quiT>_I?)&Gowm&no|m_J7VlUG4j*6o zaKSZxtq%uvwq}44q4_GR z=M&i|OL>sLWRd#ifcoXX?2=dX&v&#W8$Az0J%}D$2W}PLh2|^0QV(@ahjosHZY%ic z#bychyIy?T<+(n6j@or}Vk^gJl5XLT3mU8QoCe@_=DMH!Z-(*Ps5xc~vtMiO(zEn; zeLVD#*;{9{WV^Q`;k4QuipPlb=FGoHJQuGCq{ zd>Ux&{p!>b+yc)AkLxLN&zdwUTX2U*UchziJ@di7WHLR_D!=R3>X$|CTZ3QJDH~=u5w0IKfmLh_T;2~)Sfvj_|qGY z z=umH!8??bY_{9Ye@)UmbYqO|&;N}^6FmHDma(vF}dP+MFQxAMf8+cIQm%s2XTU_hcelIgy^Yh^7 ztuM#<;8GPY4 zxQ={#IdR}4T=0~=@QZiJJ@xQDuDwg&l;?14%}z(A=5dM(n84FIyr~{J*}{KAgZ`aO zD^UH1jN@Q&F@@57fo^jm(cd#*Er zv!ra1nG0fnq1DWDdo$qSy1IT^^-SEaaLteO;CX$4Up#L%FatX)=_#SZ ztY7X0=6ROq3pnG*+^(NS{dmkX5g*YuUdA8sT5;Z#b#lgDvvh0C!xB$=;A=SRS?wH)v+DDSl}z^Dw!gCGI;-JUYl%G`5gIR?oG|`wd=O0GV^(XmelOMkwux+ zG8Px+kj%Z{*E}GHVaum=FQ&0JwvE6)Ylb=AaqJgEj5D-UHaJ>azUy=7Yk6S}46I)86s! zy`iOsz0j=;H=mmsXh5%|RXV3b-sf4ffpr3h1~2oq=W*n0u4dTQdNVKaBi{X%24ssq zXeKwy!GR`aa?Po|sHc^CBXXXxcX>irbk4J8V6&pWtY63qJ=8aZcvqgwVA#&6{02qC z)|d0`9+4SE&-hZaed!~-iT8FkCMGgRZota9Mz+9N4Xy8f&gKKFI`iv3uJ5ZKR#AWI zfu8M=kE|IwspuB|>hwJSI*-r{4C`-Vvc2wWbY(7*jj`YS?q`mb+i-)qEUbM>w=%8H zZQfS{ztga@58j;zUDGE&;!!=mJIMjhJEy=w4f>_At1Bx9Y~ zWo%%cXFao`JhAt9W*F{ZqMw?Vp!RA9POi+tVlB zlp3Hzc`j#g&1NUOvSy z{AIfwkk4?AjLP?_!G3WePcom=QzIMnEUWp8-{~-(&v)tk4czjKKv(rSD=^IG7<^SaV_&{SYG+Yt8comFSoGmnKQQDBoBE+4ZeHOjCqycttr!-r_@Y)IPwjO zUud3I=}_O)M{wGne`vU29&3FA92tAezj^VC9+CY8r}WnDO~W!Lqu2Er|dzf?dg8u^NVY=r4 literal 90128 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 DeepmdData: data.add("coord", 3, atomic=True, must=True) data.add("box", 9, atomic=False, must=True) data.add("type", 1, atomic=True, must=True) - data.add("grid", 3, atomic=True, must=must, high_prec=True) - data.add("density", 1, atomic=True, must=must, high_prec=True) + data.add( + "grid", + 3, + atomic=False, + must=must, + high_prec=True, + special_shape="frame_major", + ) + data.add( + "density", + 1, + atomic=False, + must=must, + high_prec=True, + special_shape="frame_major", + ) return data def test_load_set_frame_major(self) -> None: @@ -114,6 +128,19 @@ def test_missing_file_optional(self) -> None: frame = data.get_single_frame(0, 0) self.assertEqual(frame["find_density"], 0.0) + def test_property_named_density_not_hijacked(self) -> None: + # a user property named "density" without a special_shape declaration + # must load through the ordinary path, not the frame-major branch + self.set_data("density", np.zeros((NFRAMES, 2), dtype=np.float32)) + data = DeepmdData(str(self.root)) + data.add("coord", 3, atomic=True, must=True) + data.add("box", 9, atomic=False, must=True) + data.add("type", 1, atomic=True, must=True) + data.add("density", 2, atomic=False, must=True) + loaded = data._load_set(self.set_dir) + self.assertEqual(loaded["find_density"], 1.0) + self.assertEqual(loaded["density"].shape, (NFRAMES, 2)) + if __name__ == "__main__": unittest.main() diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index f53d3c8e9a..4879bd2a11 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -1,5 +1,6 @@ # SPDX-License-Identifier: LGPL-3.0-or-later import os +import shutil import tempfile import unittest from copy import ( @@ -27,10 +28,12 @@ ) model_density = { - "type_map": ["O", "H"], + # the last entry is the reserved grid point type; its sel is 0 because + # grid points are never neighbors, only centers + "type_map": ["O", "H", "X"], "descriptor": { "type": "se_e2_a", - "sel": [8, 8], + "sel": [8, 8, 0], "rcut_smth": 0.50, "rcut": 4.00, "neuron": [8, 16], @@ -69,7 +72,7 @@ def setUpClass(cls) -> None: np.save(set_dir / "grid.npy", rng.random((cls.nframes, cls.ngrid, 3)) * 8.0) np.save(set_dir / "density.npy", rng.random((cls.nframes, cls.ngrid, 1))) np.savetxt(cls.system / "type.raw", [0, 0, 1, 1, 1], fmt="%d") - np.savetxt(cls.system / "type_map.raw", ["O", "H"], fmt="%s") + np.savetxt(cls.system / "type_map.raw", ["O", "H", "X"], fmt="%s") cls.config = { "model": deepcopy(model_density), @@ -121,10 +124,94 @@ def tearDownClass(cls) -> None: os.unlink(cls.model_path) cls.tmpdir.cleanup() + def test_change_out_bias_noop(self) -> None: + # fine-tuning calls the model-level change_out_bias, whose default + # change-by-statistic mode would run the grid-less stat wrapper; + # for density models it must be a no-op instead + model = self.torch_model + bias_before = model.atomic_model.out_bias.detach().clone() + model.change_out_bias(self.input_dict) + model.change_out_bias(self.input_dict, bias_adjust_mode="set-by-statistic") + torch.testing.assert_close(model.atomic_model.out_bias, bias_before) + + def test_atom_excl_does_not_mask_grid(self) -> None: + # grid points carry the reserved type X; excluding a real atom type + # must not zero the density predictions (it would if grid_type were 0) + model = self.torch_model + model.atomic_model.reinit_atom_exclude([0]) + try: + input_dict = { + kk: vv.clone() if isinstance(vv, torch.Tensor) else vv + for kk, vv in self.input_dict.items() + } + out = model(**input_dict) + self.assertFalse(bool((out["density"] == 0).all())) + finally: + model.atomic_model.reinit_atom_exclude([]) + def test_model_type_dispatch(self) -> None: dp = DeepEval(self.model_path) self.assertIsInstance(dp, DeepDensity) + def _run_training(self, config: dict, workdir: str) -> None: + """Run a few real training steps (checkpoints land in workdir).""" + cwd = os.getcwd() + os.chdir(workdir) + try: + trainer = get_trainer(normalize(deepcopy(config))) + trainer.run() + finally: + os.chdir(cwd) + self.assertTrue(os.path.exists(os.path.join(workdir, "model.ckpt.pt"))) + + def _training_config( + self, system: Path, start: float = 1.0, limit: float = 1.0 + ) -> dict: + config = deepcopy(self.config) + config["training"]["training_data"]["systems"] = [str(system)] + config["training"]["validation_data"]["systems"] = [str(system)] + config["training"]["training_data"]["batch_size"] = 2 + config["training"]["validation_data"]["batch_size"] = 2 + config["training"]["numb_steps"] = 3 + config["loss"]["start_pref_d"] = start + config["loss"]["limit_pref_d"] = limit + return config + + def test_training_steps(self) -> None: + # exercises GridDensityLoss.forward on the main path + workdir = tempfile.mkdtemp(dir=self.tmpdir.name) + self._run_training(self._training_config(self.system), workdir) + + def test_training_without_density_label(self) -> None: + # density.npy absent with must=False: the find_density == 0 branch + # must skip the residual but keep the graph connected + system = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "system" + shutil.copytree(self.system, system) + (system / "set.000" / "density.npy").unlink() + workdir = tempfile.mkdtemp(dir=self.tmpdir.name) + self._run_training(self._training_config(system), workdir) + + def test_training_zero_prefactor(self) -> None: + # start_pref_d = limit_pref_d = 0 disables the density term; + # backward() must still work on the graph-connected zero loss + workdir = tempfile.mkdtemp(dir=self.tmpdir.name) + self._run_training( + self._training_config(self.system, start=0.0, limit=0.0), workdir + ) + + def test_grid_type_statistics(self) -> None: + # the reserved grid type X gets real input statistics from the + # injected grid samples, not the descriptor's placeholder defaults + descriptor = self.torch_model.atomic_model.descriptor + dstd = descriptor.sea["dstd"].detach().cpu().numpy() + self.assertEqual(dstd.shape[0], 3) + self.assertTrue(np.isfinite(dstd).all()) + # placeholder default is 0.1; real statistics differ from it + self.assertFalse( + np.allclose(dstd[-1], 0.1, atol=1e-3), + f"grid type still has placeholder statistics: {dstd[-1]}", + ) + def test_eval_shape(self) -> None: dp = DeepDensity(self.model_path) set_dir = self.system / "set.000" @@ -135,6 +222,17 @@ def test_eval_shape(self) -> None: out = dp.eval(coord, box, atype, grid=grid) self.assertEqual(out.shape, (2, self.ngrid)) + def test_eval_requires_grid(self) -> None: + # evaluating a density model without grid must fail with a clear + # error instead of a bare KeyError on the output name table + dp = DeepDensity(self.model_path) + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:2] + box = np.load(set_dir / "box.npy")[:2] + atype = np.loadtxt(self.system / "type.raw", dtype=int) + with self.assertRaisesRegex(ValueError, "grid is required"): + dp.deep_eval.eval(coord, box, atype) + def test_eval_no_auto_batch(self) -> None: # auto_batch_size=False bypasses execute_all's single-tuple unwrapping; # the density result must still be normalized to a bare ndarray From 3aef44c66aacf0cf479acb7a22f8712bb1899cc9 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Mon, 14 Sep 2026 10:05:06 +0000 Subject: [PATCH 09/23] docs: add density fitting guide and align argcheck and example configs - fitting_density no longer advertises numb_aparam (grid rows have no per-atom parameters) or rcond (the per-type output shift is disabled); expose default_fparam and dim_case_embd like the sibling fittings - add doc/model/train-fitting-density.md and register it in index.rst - register examples/density/{dpa2,dpa3}/input.json in test_examples.py - modernise the example configs (drop warmup_steps, move opt_type into the optimizer section) --- deepmd/utils/argcheck.py | 26 ++++++++--- doc/model/index.rst | 1 + doc/model/train-fitting-density.md | 69 ++++++++++++++++++++++++++++ examples/density/dpa2/input.json | 1 - examples/density/dpa3/input.json | 5 +- source/tests/common/test_examples.py | 2 + 6 files changed, 95 insertions(+), 9 deletions(-) create mode 100644 doc/model/train-fitting-density.md diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index 51f3a713d8..b94e49303c 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -2770,7 +2770,8 @@ def descrpt_variant_type_args(exclude_hybrid: bool = False) -> Variant: @fitting_args_plugin.register("density", doc=supported_backends("pt")) def fitting_density() -> list[Argument]: doc_numb_fparam = "The dimension of the frame parameter. If set to >0, file `fparam.npy` should be included to provided the input fparams." - doc_numb_aparam = "The dimension of the atomic parameter. If set to >0, file `aparam.npy` should be included to provided the input aparams." + doc_default_fparam = "The default frame parameter. If set, when `fparam.npy` files are not included in the data system, this value will be used as the default value for the frame parameter in the fitting net." + doc_dim_case_embd = "The dimension of the case embedding embedding. When training or fine-tuning a multitask model with case embedding embeddings, this number should be set to the number of model branches." doc_neuron = "The number of neurons in each hidden layers of the fitting net. When two hidden layers are of the same size, a skip connection is built." doc_activation_function = f'The activation function in the fitting net. Supported activation functions are {list_to_doc(ACTIVATION_FN_DICT.keys())} Note that "gelu" denotes the custom operator version, and "gelu_tf" denotes the TF standard version. If you set "None" or "none" here, no activation function will be used.' doc_precision = f"The precision of the fitting net parameters, supported options are {list_to_doc(PRECISION_DICT.keys())} Default follows the interface precision." @@ -2778,12 +2779,28 @@ def fitting_density() -> list[Argument]: doc_trainable = "Whether the parameters in the fitting net are trainable. This option can be\n\n\ - bool: True if all parameters of the fitting net are trainable, False otherwise.\n\n\ - list of bool: Specifies if each layer is trainable. Since the fitting net is composed by hidden layers followed by a output layer, the length of this list should be equal to len(`neuron`)+1." - doc_rcond = "The condition number used to determine the inital density shift for each type of atoms. See `rcond` in :py:meth:`numpy.linalg.lstsq` for more details." doc_seed = "Random seed for parameter initialization of the fitting net" + # numb_aparam is deliberately not advertised: the fitting consumes + # grid-point descriptor rows, which have no per-atom parameters. + # rcond is deliberately not advertised: the per-type output shift it + # would control is disabled for density models. return [ Argument("numb_fparam", int, optional=True, default=0, doc=doc_numb_fparam), - Argument("numb_aparam", int, optional=True, default=0, doc=doc_numb_aparam), + Argument( + "default_fparam", + list[float], + optional=True, + default=None, + doc=doc_default_fparam, + ), + Argument( + "dim_case_embd", + int, + optional=True, + default=0, + doc=doc_dim_case_embd, + ), Argument( "neuron", list[int], @@ -2808,9 +2825,6 @@ def fitting_density() -> list[Argument]: default=True, doc=doc_trainable, ), - Argument( - "rcond", [float, type(None)], optional=True, default=None, doc=doc_rcond - ), Argument("seed", [int, None], optional=True, doc=doc_seed), ] diff --git a/doc/model/index.rst b/doc/model/index.rst index d08b932059..a3b445eb8f 100644 --- a/doc/model/index.rst +++ b/doc/model/index.rst @@ -21,6 +21,7 @@ Model train-fitting-tensor train-fitting-dos train-fitting-property + train-fitting-density train-se-e2-a-tebd train-se-a-mask train-se-e3-tebd diff --git a/doc/model/train-fitting-density.md b/doc/model/train-fitting-density.md new file mode 100644 index 0000000000..5fc3d90db4 --- /dev/null +++ b/doc/model/train-fitting-density.md @@ -0,0 +1,69 @@ +# Fit charge density on grid points {{ pytorch_icon }} + +> [!NOTE] +> **Supported backends**: PyTorch-TorchScript {{ pytorch_icon }} + +Here we present an API to the grid density model, which predicts the charge density on a set of grid points for a given atomic configuration. + +A complete example can be found in + +```bash +$deepmd_source_dir/examples/density/ +``` + +with DPA-2 and DPA-3 configurations, a small QM9 dataset, and a README describing the data format in detail. Note that **the data provided along with the examples are of limited amount, and should not be used to train a production model.** + +## Data format + +The training/validation data follows the standard `deepmd/npy` format, with two additional files in each `set.000/` directory: + +- `grid.npy` of shape `[nframes, ngrid, 3]`: the coordinates of the grid points; +- `density.npy` of shape `[nframes, ngrid, 1]`: the charge density labels on the grid points. + +The number of grid points `ngrid` may differ from the number of atoms. The last entry of `type_map` is reserved as a virtual "grid point type": internally, grid points are assigned this type when building the grid-to-atom neighbor list, so `type_map` must contain one more entry than the real element types. For descriptors with a per-type `sel` list (e.g. `se_e2_a`), set its last entry to 0, since grid points are only centers, never neighbors. + +It is recommended to set a positive `env_protection` in the descriptor configuration (e.g. `"env_protection": 0.1`). Grid points may legitimately coincide with atoms, and the default `env_protection = 0.0` would let the `1/r` terms in the environment matrix produce `NaN` densities. If `env_protection` is not set for a density model, it is automatically set to `1e-6` with a warning. + +## The fitting network + +The {ref}`fitting_net ` section tells DP which fitting net to use. + +The JSON of `density` type should be provided like + +```json + "fitting_net" : { + "type": "density", + "neuron": [120,120,120], + "resnet_dt": true, + "seed": 1 + }, +``` + +- `type` specifies which type of fitting net should be used. It should be `density`. +- The rest arguments have the same meaning as they do in `ener` mode. `numb_aparam` is not supported, because the fitting net consumes the descriptor rows of the grid points, which have no per-atom parameters. + +## Loss + +The grid density model is trained with the `grid_density` loss, which minimises the squared error between the predicted and the reference densities on all grid points, consistent with the other losses in the package: + +```json + "loss" : { + "type": "grid_density", + "start_pref_d": 1.0, + "limit_pref_d": 1.0 + }, +``` + +- {ref}`type ` should be written as `grid_density`. +- `start_pref_d` and `limit_pref_d` specify the weight of the density loss at the start and at the end of the training. If both are set to 0, the density label is not required and the term is skipped. Systems without a `density.npy` file are also skipped (with `find_density = 0`) when the label is optional. + +## Evaluation + +`dp test` evaluates the model on a system containing `grid.npy` and `density.npy` and reports the MAE and RMSE of the density. For programmatic access, `DeepEval` dispatches density models to `DeepDensity`, whose `eval` takes the grid coordinates and returns the density on the grid points: + +```python +from deepmd.infer import DeepEval + +dp = DeepEval("model.pth") +density = dp.eval(coord, box, atype, grid=grid) # (nframes, ngrid) +``` diff --git a/examples/density/dpa2/input.json b/examples/density/dpa2/input.json index c570fce61b..c25fa42d2c 100644 --- a/examples/density/dpa2/input.json +++ b/examples/density/dpa2/input.json @@ -107,7 +107,6 @@ "_comment": "that's all" }, "numb_steps": 200, - "warmup_steps": 0, "gradient_max_norm": 5.0, "seed": 10, "disp_file": "lcurve.out", diff --git a/examples/density/dpa3/input.json b/examples/density/dpa3/input.json index 0ee1270fae..f23f5c6978 100644 --- a/examples/density/dpa3/input.json +++ b/examples/density/dpa3/input.json @@ -94,14 +94,15 @@ "_comment": "that's all" }, "numb_steps": 100, - "warmup_steps": 0, "gradient_max_norm": 5.0, "seed": 10, "max_ckpt_keep": 100, - "opt_type": "AdamW", "disp_file": "lcurve.out", "disp_freq": 100, "save_freq": 10000, "_comment": "that's all" + }, + "optimizer": { + "type": "AdamW" } } diff --git a/source/tests/common/test_examples.py b/source/tests/common/test_examples.py index 470df3cc59..f0bbbf0f3c 100644 --- a/source/tests/common/test_examples.py +++ b/source/tests/common/test_examples.py @@ -76,6 +76,8 @@ p_examples / "hessian" / "single_task" / "input.json", p_examples / "water" / "se_e2_a" / "input_torch_num_epoch.json", p_examples / "lmdb_downsample_data" / "input_lmdb.json", + p_examples / "density" / "dpa2" / "input.json", + p_examples / "density" / "dpa3" / "input.json", ) input_files_multi = ( From 9d98f656ffa050f44a8e92c46dc9ed6e2261ed3f Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Wed, 16 Sep 2026 13:46:35 +0000 Subject: [PATCH 10/23] fix(pt): address review on density signatures, statistics cache, and defaults - keep every base parameter in the base positional order in forward_common/forward_common_lower/forward, appending the grid parameters at the end; pass charge_spin through GridDensityModel.forward - patch the grid-type statistics row in every descriptor block (repinit/repformers/repinit_three_body), excluding grid-grid pairs from the injected stat pass so mixed-type descriptors see the same grid-to-atom neighbor population as the forward pass - run the injected pass only when the grid-type statistics are missing (stat-file fast path) and write the patched row back to the cache - default env_protection to 1e-6 at normalization time so the built model, the recorded def script, and later loads all agree - add tests for the stat cache round trip, the dpa2 blocks, and the env_protection default --- .../atomic_model/density_atomic_model.py | 165 ++++++++++++++---- deepmd/pt/model/model/__init__.py | 9 - deepmd/pt/model/model/density_model.py | 4 +- deepmd/pt/model/model/make_density_model.py | 16 +- deepmd/utils/argcheck.py | 30 ++++ source/tests/pt/test_dp_test_density.py | 105 +++++++++++ 6 files changed, 284 insertions(+), 45 deletions(-) diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index d6df8e6f1c..54e6e4d14f 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -7,8 +7,12 @@ Any, ) +import numpy as np import torch +from deepmd.dpmodel.utils.env_mat_stat import ( + EnvMatStatSe, +) from deepmd.pt.model.descriptor.base_descriptor import ( BaseDescriptor, ) @@ -374,44 +378,70 @@ def compute_or_load_stat( grid type, and only the grid-type row of the statistics is taken from it; the real types keep their clean statistics from the standard pass. + + The injected pass only runs when the grid-type statistics are + missing (no cache, or a cache whose grid-type row has zero + samples), so the stat-file fast path still applies; when a stat + file is used, the patched grid-type row is written back to disk so + that the file and the in-memory statistics agree. """ - sampled = sampled_func() if callable(sampled_func) else sampled_func - grid_davg = None - grid_dstd = None - if any("grid" in sample for sample in sampled): - try: - self.descriptor.compute_input_stats(self._inject_grid_samples(sampled)) - davg, dstd = self._descriptor_stat_tensors() - grid_davg = davg[-1].detach().clone() - grid_dstd = dstd[-1].detach().clone() - except (TypeError, KeyError) as err: + sampled = None + grid_stats = None + if self._grid_stat_missing(stat_file_path): + sampled = sampled_func() if callable(sampled_func) else sampled_func + if any("grid" in sample for sample in sampled): + try: + self.descriptor.compute_input_stats( + self._inject_grid_samples(sampled) + ) + grid_stats = [ + ( + block["davg"][-1].detach().clone(), + block["dstd"][-1].detach().clone(), + ) + for block in self._descriptor_stat_blocks() + ] + except (TypeError, KeyError) as err: + log.warning( + "Cannot compute input statistics for the grid type (%s); " + "falling back to the descriptor defaults.", + err, + ) + else: log.warning( - "Cannot compute input statistics for the grid type (%s); " - "falling back to the descriptor defaults.", - err, + "No grid data in the sampled frames; the grid type gets the " + "descriptor's default input statistics." ) - else: - log.warning( - "No grid data in the sampled frames; the grid type gets the " - "descriptor's default input statistics." - ) super().compute_or_load_stat( - lambda: sampled, + (lambda: sampled) if sampled is not None else sampled_func, stat_file_path, compute_or_load_out_stat=compute_or_load_out_stat, preset_observed_type=preset_observed_type, ) - if grid_davg is not None: - davg, dstd = self._descriptor_stat_tensors() - davg[-1] = grid_davg.to(device=davg.device, dtype=davg.dtype) - dstd[-1] = grid_dstd.to(device=dstd.device, dtype=dstd.dtype) - - def _descriptor_stat_tensors(self) -> tuple[torch.Tensor, torch.Tensor]: - """Access the (davg, dstd) statistics tensors of the descriptor block.""" + if grid_stats is not None: + for block, (grid_davg, grid_dstd) in zip( + self._descriptor_stat_blocks(), grid_stats, strict=True + ): + davg = block["davg"] + dstd = block["dstd"] + davg[-1] = grid_davg.to(device=davg.device, dtype=davg.dtype) + dstd[-1] = grid_dstd.to(device=dstd.device, dtype=dstd.dtype) + if stat_file_path is not None: + self._write_back_grid_stat(stat_file_path, grid_stats) + + def _descriptor_stat_blocks(self) -> list: + """Collect every descriptor block that carries davg/dstd statistics. + + Descriptors such as DPA-2 carry several blocks (repinit, repformers, + repinit_three_body), each with its own statistics; the grid-type row + must be patched in all of them, not just the first one found. + """ try: - return self.descriptor["davg"], self.descriptor["dstd"] + self.descriptor["davg"] + return [self.descriptor] except (TypeError, KeyError): pass + blocks = [] for attr in ( "sea", "ser", @@ -422,23 +452,92 @@ def _descriptor_stat_tensors(self) -> tuple[torch.Tensor, torch.Tensor]: "repformers", "repflow", "repflows", + "repinit_three_body", ): block = getattr(self.descriptor, attr, None) if block is None: continue try: - return block["davg"], block["dstd"] + block["davg"] + blocks.append(block) except (TypeError, KeyError): continue - raise KeyError("davg/dstd not accessible on this descriptor") + if not blocks: + raise KeyError("davg/dstd not accessible on this descriptor") + return blocks + + def _stat_cache_root(self, stat_file_path: DPPath) -> DPPath: + """Apply the same type_map subdirectory as the parent's stat path.""" + if self.type_map is not None: + stat_file_path = stat_file_path / " ".join(self.type_map) + return stat_file_path + + def _grid_stat_missing(self, stat_file_path: DPPath | None) -> bool: + """Tell whether the grid-type input statistics still need computing. + + True when there is no complete stat cache, or when the cache is + complete but its grid-type row has zero samples (placeholder + statistics saved by an older run). + """ + if stat_file_path is None: + return True + stat_file_path = self._stat_cache_root(stat_file_path) + grid_type = self.descriptor.get_ntypes() - 1 + for block in self._descriptor_stat_blocks(): + env_stat = EnvMatStatSe(block) + cache = stat_file_path / env_stat.get_hash() + keys = env_stat.get_stat_keys() + if not cache.is_dir() or any(not (cache / kk).is_file() for kk in keys): + return True + # number of samples of the grid-type row; zero means placeholder + if float((cache / f"r_{grid_type}").load_numpy()[0]) == 0.0: + return True + return False + + def _write_back_grid_stat( + self, + stat_file_path: DPPath, + grid_stats: list[tuple[torch.Tensor, torch.Tensor]], + ) -> None: + """Write the patched grid-type row back to the stat cache files. + + The cache stores raw sums (number, sum, squared_sum) per stat key; + a single sample reproduces the patched mean and stddev exactly. + """ + grid_type = self.descriptor.get_ntypes() - 1 + stat_file_path = self._stat_cache_root(stat_file_path) + for block, (grid_davg, grid_dstd) in zip( + self._descriptor_stat_blocks(), grid_stats, strict=True + ): + env_stat = EnvMatStatSe(block) + cache = stat_file_path / env_stat.get_hash() + if not cache.is_dir(): + continue + davg_np = grid_davg.detach().cpu().numpy() + dstd_np = grid_dstd.detach().cpu().numpy() + mean_r = float(davg_np[0, 0]) + std_r = float(dstd_np[0, 0]) + (cache / f"r_{grid_type}").save_numpy( + np.array([1.0, mean_r, std_r**2 + mean_r**2]) + ) + if dstd_np.shape[-1] == 4: + std_a = float(dstd_np[0, 1]) + (cache / f"a_{grid_type}").save_numpy(np.array([1.0, 0.0, std_a**2])) def _inject_grid_samples(self, sampled: list[dict]) -> list[dict]: """Append the grid points of each sample as pseudo-atoms of the reserved grid type, so the descriptor input statistics get real samples for it. Neighbor lists are rebuilt by the stat machinery, so only ``coord`` and ``atype`` need to be extended. + + Grid-grid pairs are excluded from the injected neighbor lists so + that the grid-type statistics are computed over grid-to-atom + pairs, matching the directional neighbor list of the forward pass + (a no-op for per-type-sel descriptors with ``sel[-1] == 0``, but + required for mixed-type descriptors with a scalar sel). """ ntypes = self.descriptor.get_ntypes() + grid_type = ntypes - 1 injected = [] for sample in sampled: grid = sample.get("grid") @@ -459,13 +558,19 @@ def _inject_grid_samples(self, sampled: list[dict]) -> list[dict]: atype, torch.full( (nframes, ngrid), - ntypes - 1, + grid_type, dtype=atype.dtype, device=atype.device, ), ], dim=1, ) + pair_exclude_types = [ + tuple(pair) for pair in sample.get("pair_exclude_types", []) + ] + if (grid_type, grid_type) not in pair_exclude_types: + pair_exclude_types.append((grid_type, grid_type)) + sample["pair_exclude_types"] = pair_exclude_types injected.append(sample) return injected diff --git a/deepmd/pt/model/model/__init__.py b/deepmd/pt/model/model/__init__.py index 6dfaac1af4..43ab5453a0 100644 --- a/deepmd/pt/model/model/__init__.py +++ b/deepmd/pt/model/model/__init__.py @@ -445,15 +445,6 @@ def get_standard_model(model_params: dict) -> BaseModel: ) model_params_old = model_params model_params = copy.deepcopy(model_params) - if model_params.get("fitting_net", {}).get("type") == "density": - descriptor_params = model_params.get("descriptor", {}) - if descriptor_params.get("env_protection", 0.0) == 0.0: - log.warning( - "env_protection is 0.0 for a density model; grid points " - "coincident with atoms would produce NaN densities. " - "Setting env_protection to 1e-6." - ) - descriptor_params["env_protection"] = 1e-6 ntypes = len(model_params["type_map"]) descriptor, fitting, fitting_net_type = _get_standard_model_components( model_params, ntypes diff --git a/deepmd/pt/model/model/density_model.py b/deepmd/pt/model/model/density_model.py index 48d263c60a..54b35267c9 100644 --- a/deepmd/pt/model/model/density_model.py +++ b/deepmd/pt/model/model/density_model.py @@ -55,13 +55,14 @@ def forward( self, coord: torch.Tensor, atype: torch.Tensor, - grid: torch.Tensor, box: torch.Tensor | None = None, fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, do_atomic_virial: bool = False, charge_spin: torch.Tensor | None = None, + grid: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: + assert grid is not None model_ret = self.forward_common( coord, atype, @@ -69,6 +70,7 @@ def forward( fparam=fparam, aparam=aparam, do_atomic_virial=do_atomic_virial, + charge_spin=charge_spin, grid=grid, ) model_predict = {} diff --git a/deepmd/pt/model/model/make_density_model.py b/deepmd/pt/model/model/make_density_model.py index aadf1b3abf..14b21965a4 100644 --- a/deepmd/pt/model/model/make_density_model.py +++ b/deepmd/pt/model/model/make_density_model.py @@ -65,14 +65,16 @@ def forward_common( fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, do_atomic_virial: bool = False, + coord_corr_for_virial: torch.Tensor | None = None, charge_spin: torch.Tensor | None = None, grid: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: """Return model prediction. - Same positional order as the base ``forward_common``; the - density-specific ``grid`` is appended at the end and is - required for this model. + The base parameters keep the base positional order (including + ``coord_corr_for_virial``, which is accepted and ignored since + density has no virial correction); the density-specific + ``grid`` is appended at the end and is required for this model. Parameters ---------- @@ -100,6 +102,7 @@ def forward_common( The keys are defined by the `ModelOutputDef`. """ + del coord_corr_for_virial assert grid is not None cc, gg, bb, fp, ap, input_prec = self._input_type_cast( coord, box=box, fparam=fparam, aparam=aparam, grid=grid @@ -170,10 +173,11 @@ def forward_common_lower( mapping: torch.Tensor | None = None, fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, - charge_spin: torch.Tensor | None = None, do_atomic_virial: bool = False, comm_dict: dict[str, torch.Tensor] | None = None, extra_nlist_sort: bool = False, + extended_coord_corr: torch.Tensor | None = None, + charge_spin: torch.Tensor | None = None, grid: torch.Tensor | None = None, grid_type: torch.Tensor | None = None, grid_nlist: torch.Tensor | None = None, @@ -183,7 +187,8 @@ def forward_common_lower( grid inputs as input, and returns the predictions on the grid points. The predictions are not reduced. - Same positional order as the base ``forward_common_lower``; the + The base parameters keep the base positional order (including + ``extended_coord_corr``, which is accepted and ignored); the density-specific grid parameters are appended at the end and are required for this model. @@ -221,6 +226,7 @@ def forward_common_lower( the result dict, defined by the `FittingOutputDef`. """ + del extended_coord_corr nframes, nall = extended_atype.shape[:2] extended_coord = extended_coord.view(nframes, -1, 3) nlist = self.format_nlist( diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index b94e49303c..332ab67091 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -6615,6 +6615,35 @@ def validate_no_multitask_lora(data: dict[str, Any], multi_task: bool = False) - ) +def _apply_density_env_protection_default(data: dict[str, Any]) -> None: + """Default env_protection to 1e-6 for density models. + + Applied at normalization time so that the recorded model_def_script and + the built model agree on this field. Grid points may legitimately + coincide with atoms, and the default 0.0 would let the 1/r terms in the + environment matrix produce NaN densities. + """ + + def _fix(model: dict[str, Any]) -> None: + if ( + model.get("fitting_net", {}).get("type") == "density" + and model.get("descriptor", {}).get("env_protection", 0.0) == 0.0 + ): + log.warning( + "env_protection is 0.0 for a density model; grid points " + "coincident with atoms would produce NaN densities. " + "Setting env_protection to 1e-6." + ) + model.setdefault("descriptor", {})["env_protection"] = 1e-6 + + model = data.get("model", {}) + if "model_dict" in model: + for sub_model in model["model_dict"].values(): + _fix(sub_model) + else: + _fix(model) + + def normalize( data: dict[str, Any], multi_task: bool = False, *, check: bool = True ) -> dict[str, Any]: @@ -6626,6 +6655,7 @@ def normalize( validate_full_validation_config(data, multi_task=multi_task) _check_dpa3_chg_spin_migration(data) validate_no_multitask_lora(data, multi_task=multi_task) + _apply_density_env_protection_default(data) return data diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index 4879bd2a11..563e517656 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -1,4 +1,5 @@ # SPDX-License-Identifier: LGPL-3.0-or-later +import json import os import shutil import tempfile @@ -26,6 +27,9 @@ from deepmd.utils.argcheck import ( normalize, ) +from deepmd.utils.path import ( + DPPath, +) model_density = { # the last entry is the reserved grid point type; its sel is 0 because @@ -199,6 +203,49 @@ def test_training_zero_prefactor(self) -> None: self._training_config(self.system, start=0.0, limit=0.0), workdir ) + def test_env_protection_default(self) -> None: + # a density model built without an explicit env_protection gets + # 1e-6 by default (with a warning), and the recorded def script + # agrees with the built model + config = deepcopy(self.config) + config["model"]["descriptor"].pop("env_protection") + trainer = get_trainer(normalize(config)) + descriptor = trainer.model.atomic_model.descriptor + self.assertEqual(descriptor.get_env_protection(), 1e-6) + recorded = json.loads(trainer.model.model_def_script) + self.assertEqual(recorded["descriptor"]["env_protection"], 1e-6) + + def test_stat_file_grid_row_writeback(self) -> None: + # the patched grid-type row is written back to the stat cache, and a + # complete cache then takes the fast path without the injected pass + stat_dir = DPPath(tempfile.mkdtemp(dir=self.tmpdir.name), "w") + atomic_model = self.torch_model.atomic_model + + def sampler() -> list: + return [dict(self.input_dict)] + + atomic_model.compute_or_load_stat(sampler, stat_file_path=stat_dir) + grid_type = len(self.config["model"]["type_map"]) - 1 + r_x = list(stat_dir.rglob(f"r_{grid_type}")) + self.assertTrue(r_x, "no grid-type stat item written to the cache") + for path in r_x: + self.assertNotEqual( + float(path.load_numpy()[0]), + 0.0, + f"{path} still holds zero samples (placeholder row)", + ) + # second call with the complete cache: the injected pass must not run + original_inject = atomic_model._inject_grid_samples + + def boom(_sampled: list) -> list: + raise AssertionError("injected pass should not run on a complete cache") + + atomic_model._inject_grid_samples = boom # type: ignore[method-assign] + try: + atomic_model.compute_or_load_stat(sampler, stat_file_path=stat_dir) + finally: + atomic_model._inject_grid_samples = original_inject # type: ignore[method-assign] + def test_grid_type_statistics(self) -> None: # the reserved grid type X gets real input statistics from the # injected grid samples, not the descriptor's placeholder defaults @@ -212,6 +259,64 @@ def test_grid_type_statistics(self) -> None: f"grid type still has placeholder statistics: {dstd[-1]}", ) + def test_grid_type_statistics_dpa2(self) -> None: + # DPA-2 carries several stat blocks (repinit, repformers, + # repinit_three_body); the grid-type row must be patched in all of + # them, not just the first one + config = deepcopy(self.config) + config["model"]["descriptor"] = { + "type": "dpa2", + "repinit": { + "tebd_dim": 4, + "rcut": 4.0, + "rcut_smth": 0.5, + "nsel": 16, + "neuron": [8, 16], + "axis_neuron": 4, + "activation_function": "tanh", + "use_three_body": True, + "three_body_sel": 8, + "three_body_rcut": 2.0, + "three_body_rcut_smth": 1.0, + }, + "repformer": { + "rcut": 2.0, + "rcut_smth": 1.5, + "nsel": 8, + "nlayers": 2, + "g1_dim": 16, + "g2_dim": 8, + "attn2_hidden": 8, + "attn2_nhead": 2, + "attn1_hidden": 16, + "attn1_nhead": 2, + "axis_neuron": 4, + }, + "env_protection": 1e-6, + "seed": 1, + } + trainer = get_trainer(normalize(config)) + descriptor = trainer.model.atomic_model.descriptor + for name in ("repinit", "repformers", "repinit_three_body"): + block = getattr(descriptor, name) + dstd = block["dstd"].detach().cpu().numpy() + self.assertTrue(np.isfinite(dstd).all(), name) + self.assertFalse( + np.allclose(dstd[-1], 0.1, atol=1e-3), + f"{name} still has placeholder statistics for the grid type", + ) + # the reserved grid type X gets real input statistics from the + # injected grid samples, not the descriptor's placeholder defaults + descriptor = self.torch_model.atomic_model.descriptor + dstd = descriptor.sea["dstd"].detach().cpu().numpy() + self.assertEqual(dstd.shape[0], 3) + self.assertTrue(np.isfinite(dstd).all()) + # placeholder default is 0.1; real statistics differ from it + self.assertFalse( + np.allclose(dstd[-1], 0.1, atol=1e-3), + f"grid type still has placeholder statistics: {dstd[-1]}", + ) + def test_eval_shape(self) -> None: dp = DeepDensity(self.model_path) set_dir = self.system / "set.000" From aa566fb6a702fe9db646b301cf98aa4e6fe14e27 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Fri, 18 Sep 2026 05:45:54 +0000 Subject: [PATCH 11/23] fix(pt): address review round on density dispatch, loss, exclusions, and eval - dispatch density models by the has_grid capability instead of the output name, so a property named density is not hijacked - mask the density loss residual by the grid mask, reduce per frame, and declare the label mandatory (it is the only supervision signal) - honour pair_exclude_types in the injected stat pass and in the directional grid-to-atom forward list; discover descriptor stat blocks by walking the module tree (hybrids and future descriptors included) - default and enforce env_protection for density models, recursing into hybrid sub-descriptors - normalise the eval grid to (nframes, ngrid, 3) before auto batching, and state the actual deployment support (Python inference; no C++/LAMMPS yet) - add tests for all of the above (28 in the density suite) --- deepmd/infer/deep_density.py | 26 +- deepmd/pt/infer/deep_eval.py | 15 +- deepmd/pt/loss/charge.py | 36 ++- .../atomic_model/density_atomic_model.py | 104 +++++--- deepmd/utils/argcheck.py | 27 +- doc/model/train-fitting-density.md | 6 + examples/density/README.md | 1 + source/tests/pt/test_dp_test_density.py | 244 +++++++++++++++++- 8 files changed, 402 insertions(+), 57 deletions(-) diff --git a/deepmd/infer/deep_density.py b/deepmd/infer/deep_density.py index 5f42e9c20c..79e8d32c1b 100644 --- a/deepmd/infer/deep_density.py +++ b/deepmd/infer/deep_density.py @@ -112,10 +112,34 @@ def eval( False, fparam=fparam, aparam=aparam, - grid=np.array(grid), + grid=self._standard_grid(grid, nframes), **kwargs, ) return results["density"].reshape(nframes, -1) + @staticmethod + def _standard_grid(grid: np.ndarray, nframes: int) -> np.ndarray: + """Normalise the grid coordinates to ``(nframes, ngrid, 3)``. + + The auto batcher slices every argument with ``ndim > 1`` along axis + 0, so a natural single-frame ``(ngrid, 3)`` input would silently be + truncated to one grid point; carry the frame dimension explicitly. + """ + arr = np.asarray(grid) + if arr.ndim == 2: + if nframes != 1: + raise ValueError( + f"grid of shape {arr.shape} is ambiguous for {nframes} " + "frames; pass grid with shape (nframes, ngrid, 3)" + ) + arr = arr[None, ...] + if arr.ndim != 3 or arr.shape[-1] != 3: + raise ValueError( + f"grid must have shape (nframes, ngrid, 3), got {arr.shape}" + ) + if arr.shape[0] != nframes: + raise ValueError(f"grid has {arr.shape[0]} frames but coord has {nframes}") + return arr + __all__ = ["DeepDensity"] diff --git a/deepmd/pt/infer/deep_eval.py b/deepmd/pt/infer/deep_eval.py index 6eb708f5ea..e254590211 100644 --- a/deepmd/pt/infer/deep_eval.py +++ b/deepmd/pt/infer/deep_eval.py @@ -443,13 +443,26 @@ def model_type(self) -> type["DeepEvalWrapper"]: return DeepWFC elif "population" in model_output_type: return DeepPopulation - elif "density" in model_output_type: + elif "density" in model_output_type and self._model_has_grid( + self.dp.model["Default"] + ): + # key on the grid capability rather than the output name, so a + # property fitting with property_name "density" still dispatches + # to DeepProperty below return DeepDensity elif self.get_var_name() in model_output_type: return DeepProperty else: raise RuntimeError("Unknown model type") + @staticmethod + def _model_has_grid(model: Any) -> bool: + has_grid = getattr(model, "has_grid", None) + try: + return bool(has_grid()) if callable(has_grid) else False + except Exception: + return False + def get_sel_type(self) -> list[int]: """Get the selected atom types of this model. diff --git a/deepmd/pt/loss/charge.py b/deepmd/pt/loss/charge.py index 411232466e..d1e35be6fb 100644 --- a/deepmd/pt/loss/charge.py +++ b/deepmd/pt/loss/charge.py @@ -30,6 +30,10 @@ def __init__( ) -> None: r"""Construct a layer to compute loss on grid density. + The residual is masked by the grid-point mask (excluded points do + not contribute) and reduced per frame before averaging over the + batch, consistent with the other losses in the package. + Parameters ---------- starter_learning_rate : float @@ -104,16 +108,28 @@ def forward( return model_pred, loss, more_loss density_label = label["density"] pref_d = pref_d * find_density - density_pred_reshape = density_pred.reshape(-1) - density_label_reshape = density_label.reshape(-1) - l2_density_loss = torch.square( - density_label_reshape - density_pred_reshape - ).mean() + # mask out excluded grid points (the atomic model zeroes them + # and returns the mask) and reduce per frame, consistent with + # the other losses in the package, so that frames with larger + # grids do not dominate the batch + mask = model_pred.get("mask", None) + nframes = density_pred.shape[0] + if mask is None: + mask_f = torch.ones( + density_pred.shape[:2], + dtype=density_pred.dtype, + device=density_pred.device, + ) + else: + mask_f = mask.reshape(density_pred.shape[:2]).to(density_pred.dtype) + mask_sum = mask_f.sum(dim=-1).clamp(min=1.0) + residual = ( + density_label.reshape(nframes, -1) - density_pred.reshape(nframes, -1) + ) * mask_f + l2_density_loss = torch.square(residual).sum(dim=-1).div(mask_sum).mean() rmse_d = l2_density_loss.sqrt() more_loss["rmse_d"] = self.display_if_exist(rmse_d.detach(), find_density) - l1_density_loss = torch.abs( - density_label_reshape - density_pred_reshape - ).mean() + l1_density_loss = residual.abs().sum(dim=-1).div(mask_sum).mean() mae_d = l1_density_loss # minimise the squared error, consistent with every other loss # in the package; the absolute error is only for display @@ -136,12 +152,14 @@ def label_requirement(self) -> list[DataRequirementItem]: """ label_requirement = [] if self.has_d: + # the density label is the only supervision signal of this model: + # a missing file must abort training, not silently optimise nothing label_requirement.append( DataRequirementItem( "density", ndof=1, atomic=False, - must=False, + must=True, high_prec=True, special_shape="frame_major", ) diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index 54e6e4d14f..2de773daa9 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -16,6 +16,9 @@ from deepmd.pt.model.descriptor.base_descriptor import ( BaseDescriptor, ) +from deepmd.pt.model.descriptor.descriptor import ( + DescriptorBlock, +) from deepmd.pt.model.task.density import ( DensityFittingNet, ) @@ -55,9 +58,9 @@ def __init__( if self.descriptor.get_env_protection() == 0.0: log.warning( "The descriptor env_protection is 0.0; grid points coincident " - "with atoms would produce NaN densities. Set a positive " - "env_protection in the descriptor configuration." + "with atoms would produce NaN densities. Setting it to 1e-6." ) + self._set_descriptor_env_protection(1e-6) self.sel = self.descriptor.get_sel() self.nnei = self.descriptor.get_nsel() @@ -143,6 +146,10 @@ def forward_atomic( # nb x (ngrid+nall) merged_mapping = torch.cat([grid_mapping, mapping + ngrid], dim=1) + # the descriptor evaluates the environment of every merged point; + # the atom rows are computed and discarded (only the grid rows feed + # the fitting net), which is inherent to evaluating the merged + # grid+atom system in one call descriptor, rot_mat, g2, h2, _sw = self.descriptor( merged_coord, merged_atype, @@ -225,6 +232,27 @@ def forward_common_atomic( pair_mask = self.pair_excl(nlist, extended_atype) # exclude neighbors in the nlist nlist = torch.where(pair_mask == 1, nlist, -1) + # the directional grid-to-atom list: every center is the grid + # type, so exclusions involving the grid type drop the neighbor + reserved_type = self.descriptor.get_ntypes() - 1 + if any( + reserved_type in pair for pair in self.pair_excl.get_exclude_types() + ): + nall = extended_atype.shape[1] + nsel = grid_nlist.shape[-1] + virtual_type = self.pair_excl.ntypes * torch.ones( + [nframes, 1], + dtype=extended_atype.dtype, + device=extended_atype.device, + ) + ae = torch.cat([extended_atype, virtual_type], dim=-1) + index = torch.where(grid_nlist == -1, nall, grid_nlist).view( + nframes, ngrid * nsel + ) + type_j = torch.gather(ae, 1, index) + type_ij = reserved_type * (self.pair_excl.ntypes + 1) + type_j + grid_mask = self.pair_excl.type_mask[type_ij].view(nframes, ngrid, nsel) + grid_nlist = torch.where(grid_mask == 1, grid_nlist, -1) ext_atom_mask = self.make_atom_mask(extended_atype) ret_dict = self.forward_atomic( @@ -391,8 +419,11 @@ def compute_or_load_stat( sampled = sampled_func() if callable(sampled_func) else sampled_func if any("grid" in sample for sample in sampled): try: + # run the wrapped sampler first so the injected pass sees + # the same pair_exclude_types as the standard pass + wrapped = self._make_wrapped_sampler(lambda: sampled) self.descriptor.compute_input_stats( - self._inject_grid_samples(sampled) + self._inject_grid_samples(wrapped()) ) grid_stats = [ ( @@ -432,39 +463,45 @@ def compute_or_load_stat( def _descriptor_stat_blocks(self) -> list: """Collect every descriptor block that carries davg/dstd statistics. - Descriptors such as DPA-2 carry several blocks (repinit, repformers, - repinit_three_body), each with its own statistics; the grid-type row - must be patched in all of them, not just the first one found. + Descriptors such as DPA-2 and hybrids carry several blocks, each with + its own statistics; the grid-type row must be patched in all of them. + The blocks are discovered by walking the module tree (via + ``named_modules``) and probing the statistics item protocol, so no + per-descriptor attribute list is needed. """ - try: - self.descriptor["davg"] - return [self.descriptor] - except (TypeError, KeyError): - pass blocks = [] - for attr in ( - "sea", - "ser", - "seat", - "se_atten", - "se_ttebd", - "repinit", - "repformers", - "repflow", - "repflows", - "repinit_three_body", - ): - block = getattr(self.descriptor, attr, None) - if block is None: + for _name, module in self.descriptor.named_modules(): + # filter networks etc. also implement __getitem__ with unrelated + # semantics, so only descriptor-level modules are probed for the + # statistics item protocol (some descriptors, e.g. se_r, carry + # the statistics on the descriptor itself) + if not isinstance(module, (BaseDescriptor, DescriptorBlock)): continue try: - block["davg"] - blocks.append(block) + module["davg"] + module["dstd"] except (TypeError, KeyError): continue - if not blocks: - raise KeyError("davg/dstd not accessible on this descriptor") - return blocks + blocks.append(module) + if blocks: + return blocks + try: + self.descriptor["davg"] + self.descriptor["dstd"] + return [self.descriptor] + except (TypeError, KeyError): + pass + raise KeyError("davg/dstd not accessible on this descriptor") + + def _set_descriptor_env_protection(self, value: float) -> None: + """Set env_protection on every descriptor block, hybrids included. + + Wrapper-level fields, if any, are derived from the blocks; the whole + module tree is walked so no per-descriptor attribute list is needed. + """ + for _name, module in self.descriptor.named_modules(): + if hasattr(module, "env_protection"): + module.env_protection = value def _stat_cache_root(self, stat_file_path: DPPath) -> DPPath: """Apply the same type_map subdirectory as the parent's stat path.""" @@ -481,9 +518,14 @@ def _grid_stat_missing(self, stat_file_path: DPPath | None) -> bool: """ if stat_file_path is None: return True + try: + blocks = self._descriptor_stat_blocks() + except KeyError: + # no accessible statistics: let the injected pass soft-fail below + return True stat_file_path = self._stat_cache_root(stat_file_path) grid_type = self.descriptor.get_ntypes() - 1 - for block in self._descriptor_stat_blocks(): + for block in blocks: env_stat = EnvMatStatSe(block) cache = stat_file_path / env_stat.get_hash() keys = env_stat.get_stat_keys() diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index 50f4a1c2e9..736f1b1d5e 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -6642,16 +6642,23 @@ def _apply_density_env_protection_default(data: dict[str, Any]) -> None: """ def _fix(model: dict[str, Any]) -> None: - if ( - model.get("fitting_net", {}).get("type") == "density" - and model.get("descriptor", {}).get("env_protection", 0.0) == 0.0 - ): - log.warning( - "env_protection is 0.0 for a density model; grid points " - "coincident with atoms would produce NaN densities. " - "Setting env_protection to 1e-6." - ) - model.setdefault("descriptor", {})["env_protection"] = 1e-6 + if model.get("fitting_net", {}).get("type") != "density": + return + descriptor = model.get("descriptor", {}) + # a hybrid descriptor has no top-level env_protection; each + # sub-descriptor carries its own + if descriptor.get("type") == "hybrid": + sub_descriptors = descriptor.get("list", []) + else: + sub_descriptors = [descriptor] + for sub in sub_descriptors: + if sub.get("env_protection", 0.0) == 0.0: + log.warning( + "env_protection is 0.0 for a density model; grid points " + "coincident with atoms would produce NaN densities. " + "Setting env_protection to 1e-6." + ) + sub["env_protection"] = 1e-6 model = data.get("model", {}) if "model_dict" in model: diff --git a/doc/model/train-fitting-density.md b/doc/model/train-fitting-density.md index 5fc3d90db4..20aab082ac 100644 --- a/doc/model/train-fitting-density.md +++ b/doc/model/train-fitting-density.md @@ -2,6 +2,12 @@ > [!NOTE] > **Supported backends**: PyTorch-TorchScript {{ pytorch_icon }} +> +> Training and evaluation are supported in Python (`dp train`, `dp test`, +> and the `DeepEval`/`DeepDensity` interfaces). C++/LAMMPS inference is +> **not** supported yet: the model's `forward_lower` interface is not +> implemented for density models. See the multi-backend tracking issue for +> the planned dpmodel implementation and backend wrappers. Here we present an API to the grid density model, which predicts the charge density on a set of grid points for a given atomic configuration. diff --git a/examples/density/README.md b/examples/density/README.md index c3156997bc..144f419fd9 100644 --- a/examples/density/README.md +++ b/examples/density/README.md @@ -204,5 +204,6 @@ ______________________________________________________________________ ## Notes - **Backend:** PyTorch only (`--pt`). Make sure DeePMD-kit is installed with PyTorch support. +- **Deployment scope:** Python inference only (`dp test`, `DeepEval`/`DeepDensity`, and the standalone script). C++/LAMMPS inference is not supported yet (`forward_lower` is not implemented for density models). - **Stat file:** `input.json` specifies `"stat_file": "./qm9_charge_density.hdf5"` for caching descriptor statistics; it is generated automatically on the first run. - **Checkpoint vs. frozen model:** evaluation requires a frozen model (`.pth`). Freeze a checkpoint first with `dp --pt freeze`. diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index 563e517656..d064aa4336 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -21,6 +21,21 @@ from deepmd.infer.deep_eval import ( DeepEval, ) +from deepmd.pt.model.atomic_model.density_atomic_model import ( + DPDensityAtomicModel, +) +from deepmd.pt.model.descriptor.hybrid import ( + DescrptHybrid, +) +from deepmd.pt.model.descriptor.se_a import ( + DescrptSeA, +) +from deepmd.pt.model.descriptor.se_r import ( + DescrptSeR, +) +from deepmd.pt.model.task.density import ( + DensityFittingNet, +) from deepmd.pt.entrypoints.main import ( get_trainer, ) @@ -138,6 +153,23 @@ def test_change_out_bias_noop(self) -> None: model.change_out_bias(self.input_dict, bias_adjust_mode="set-by-statistic") torch.testing.assert_close(model.atomic_model.out_bias, bias_before) + def test_pair_excl_involving_grid_type_applies_in_forward(self) -> None: + # exclusions involving the grid type must drop the neighbor in the + # directional grid-to-atom list too, not just in the atom nlist + model = self.torch_model + grid_type = len(self.config["model"]["type_map"]) - 1 + input_dict = { + kk: vv.clone() if isinstance(vv, torch.Tensor) else vv + for kk, vv in self.input_dict.items() + } + model.atomic_model.reinit_pair_exclude([(0, grid_type)]) + try: + out_excl = model(**input_dict)["density"] + finally: + model.atomic_model.reinit_pair_exclude([]) + out_none = model(**input_dict)["density"] + self.assertFalse(torch.allclose(out_excl, out_none)) + def test_atom_excl_does_not_mask_grid(self) -> None: # grid points carry the reserved type X; excluding a real atom type # must not zero the density predictions (it would if grid_type were 0) @@ -153,6 +185,37 @@ def test_atom_excl_does_not_mask_grid(self) -> None: finally: model.atomic_model.reinit_atom_exclude([]) + def test_property_named_density_dispatches_to_property(self) -> None: + # the dispatch keys on the grid capability, not the output name, so + # a property fitting with property_name "density" is not hijacked + from deepmd.infer.deep_property import ( + DeepProperty, + ) + from deepmd.pt.model.model.property_model import ( + PropertyModel, + ) + from deepmd.pt.model.task.property import ( + PropertyFittingNet, + ) + + descriptor = DescrptSeA(rcut=4.0, rcut_smth=0.5, sel=[8, 8]) + fitting = PropertyFittingNet( + descriptor.get_ntypes(), + descriptor.get_dim_out(), + "density", + neuron=[8, 8], + ) + model = PropertyModel(descriptor, fitting, type_map=["O", "H"]) + fd, path = tempfile.mkstemp(suffix=".pth") + os.close(fd) + try: + with torch.device("cpu"): + torch.jit.save(torch.jit.script(model), path) + dp = DeepEval(path) + self.assertIsInstance(dp, DeepProperty) + finally: + os.unlink(path) + def test_model_type_dispatch(self) -> None: dp = DeepEval(self.model_path) self.assertIsInstance(dp, DeepDensity) @@ -181,19 +244,114 @@ def _training_config( config["loss"]["limit_pref_d"] = limit return config + def test_eval_single_frame_grid_2d(self) -> None: + # a natural single-frame grid of shape (ngrid, 3) must be carried + # through with its frame dimension, not sliced to one grid point + dp = DeepDensity(self.model_path) + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:1] + box = np.load(set_dir / "box.npy")[:1] + grid = np.load(set_dir / "grid.npy")[0] # (ngrid, 3): no frame dim + atype = np.loadtxt(self.system / "type.raw", dtype=int) + out = dp.eval(coord, box, atype, grid=grid) + self.assertEqual(out.shape, (1, self.ngrid)) + + def test_eval_grid_frame_mismatch(self) -> None: + dp = DeepDensity(self.model_path) + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:2] + box = np.load(set_dir / "box.npy")[:2] + grid = np.load(set_dir / "grid.npy")[:1] # fewer frames than coord + atype = np.loadtxt(self.system / "type.raw", dtype=int) + with self.assertRaisesRegex(ValueError, "frames"): + dp.eval(coord, box, atype, grid=grid) + + def test_fitting_rejects_aparam(self) -> None: + # grid descriptor rows have no per-atom parameters + descriptor = DescrptSeA(rcut=4.0, rcut_smth=0.5, sel=[8, 8, 0]) + with self.assertRaisesRegex(ValueError, "aparam"): + DensityFittingNet( + descriptor.get_ntypes(), + descriptor.get_dim_out(), + numb_aparam=2, + ) + + def test_loss_inference_mode(self) -> None: + # inference=True reports the metrics even with zero prefactors + from deepmd.pt.loss.charge import ( + GridDensityLoss, + ) + from deepmd.pt.utils import ( + env, + ) + + loss_fn = GridDensityLoss(inference=True) + + class FakeModel(torch.nn.Module): + def forward(self, **kwargs): + return { + "density": torch.tensor([[[2.0], [4.0]]], device=env.DEVICE), + "mask": torch.tensor( + [[1, 1]], dtype=torch.int32, device=env.DEVICE + ), + } + + label = { + "density": torch.tensor([[[1.0], [2.0]]], device=env.DEVICE), + "find_density": 1.0, + } + _, loss, more_loss = loss_fn({}, FakeModel(), label, 1, 1.0) + self.assertIn("rmse_d", more_loss) + self.assertIn("mae_d", more_loss) + self.assertAlmostEqual(more_loss["rmse_d"].item(), ((1.0 + 4.0) / 2) ** 0.5) + + def test_loss_masks_excluded_grid_points(self) -> None: + # excluded grid points (mask == 0) must not contribute to the + # residual, which is normalised by the per-frame mask sum + from deepmd.pt.loss.charge import ( + GridDensityLoss, + ) + from deepmd.pt.utils import ( + env, + ) + + loss_fn = GridDensityLoss(start_pref_d=1.0, limit_pref_d=1.0) + + class FakeModel(torch.nn.Module): + def forward(self, **kwargs): + return { + "density": torch.tensor( + [[[1.0], [2.0], [3.0], [4.0]]], device=env.DEVICE + ), + "mask": torch.tensor( + [[1, 1, 0, 0]], dtype=torch.int32, device=env.DEVICE + ), + } + + label = { + "density": torch.tensor( + [[[1.0], [1.0], [100.0], [100.0]]], device=env.DEVICE + ), + "find_density": 1.0, + } + _, loss, more_loss = loss_fn({}, FakeModel(), label, 1, 1.0) + # only the two unmasked points count: (0^2 + 1^2) / 2 + self.assertAlmostEqual(loss.item(), 0.5) + self.assertAlmostEqual(more_loss["rmse_d"].item(), 0.5**0.5) + def test_training_steps(self) -> None: # exercises GridDensityLoss.forward on the main path workdir = tempfile.mkdtemp(dir=self.tmpdir.name) self._run_training(self._training_config(self.system), workdir) - def test_training_without_density_label(self) -> None: - # density.npy absent with must=False: the find_density == 0 branch - # must skip the residual but keep the graph connected + def test_training_requires_density_label(self) -> None: + # density is the only supervision signal: a missing density.npy must + # abort training instead of silently optimising nothing system = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "system" shutil.copytree(self.system, system) (system / "set.000" / "density.npy").unlink() - workdir = tempfile.mkdtemp(dir=self.tmpdir.name) - self._run_training(self._training_config(system), workdir) + with self.assertRaisesRegex(RuntimeError, "not found"): + get_trainer(normalize(self._training_config(system))) def test_training_zero_prefactor(self) -> None: # start_pref_d = limit_pref_d = 0 disables the density term; @@ -215,6 +373,82 @@ def test_env_protection_default(self) -> None: recorded = json.loads(trainer.model.model_def_script) self.assertEqual(recorded["descriptor"]["env_protection"], 1e-6) + def test_hybrid_descriptor_stat_blocks(self) -> None: + # hybrid descriptors keep their blocks in descrpt_list: the block + # discovery must walk the module tree instead of a hard-coded + # attribute list, and a stat file must not abort the run + descriptor = DescrptHybrid( + [ + DescrptSeA(rcut=4.0, rcut_smth=0.5, sel=[8, 8, 0]), + DescrptSeR(rcut=2.0, rcut_smth=1.0, sel=[4, 4, 0]), + ] + ) + fitting = DensityFittingNet(descriptor.get_ntypes(), descriptor.get_dim_out()) + model = DPDensityAtomicModel(descriptor, fitting, type_map=["O", "H", "X"]) + blocks = model._descriptor_stat_blocks() + self.assertEqual(len(blocks), 2) + # a stat file must take the soft-failure path, not abort + stat_dir = DPPath(tempfile.mkdtemp(dir=self.tmpdir.name), "w") + + def sampler() -> list: + return [dict(self.input_dict)] + + model.compute_or_load_stat(sampler, stat_file_path=stat_dir) + + def test_env_protection_enforced_at_model_level(self) -> None: + # models constructed directly with env_protection == 0.0 get the + # guard set on the descriptor block, not just a warning + descriptor = DescrptSeA( + rcut=4.0, rcut_smth=0.5, sel=[8, 8, 0], env_protection=0.0 + ) + fitting = DensityFittingNet(descriptor.get_ntypes(), descriptor.get_dim_out()) + model = DPDensityAtomicModel(descriptor, fitting, type_map=["O", "H", "X"]) + self.assertEqual(model.descriptor.get_env_protection(), 1e-6) + + def test_env_protection_hybrid(self) -> None: + # hybrid descriptors have no top-level env_protection: the default + # must reach every sub-descriptor + config = deepcopy(self.config) + descriptor = config["model"].pop("descriptor") + config["model"]["descriptor"] = {"type": "hybrid", "list": [descriptor]} + normalized = normalize(config) + self.assertEqual( + normalized["model"]["descriptor"]["list"][0]["env_protection"], + 1e-6, + ) + + def test_injected_pass_honors_pair_exclude_types(self) -> None: + # the injected stat pass must see the model's pair_exclude_types, + # which are only written by the wrapped sampler + atomic_model = self.torch_model.atomic_model + atomic_model.reinit_pair_exclude([(0, 1)]) + seen: list = [] + original = atomic_model.descriptor.compute_input_stats + + def spy(merged, path=None): + samples = merged() if callable(merged) else merged + seen.extend(samples) + original(merged, path) + + atomic_model.descriptor.compute_input_stats = spy # type: ignore[method-assign] + try: + + def sampler() -> list: + return [dict(self.input_dict)] + + atomic_model.compute_or_load_stat(sampler, stat_file_path=None) + finally: + atomic_model.descriptor.compute_input_stats = original # type: ignore[method-assign] + atomic_model.reinit_pair_exclude([]) + # injected samples carry the grid pseudo-atoms (more rows than atoms) + natoms = len(np.loadtxt(self.system / "type.raw", dtype=int)) + injected = [s for s in seen if s["atype"].shape[1] > natoms and "grid" in s] + self.assertTrue(injected, "no injected samples reached the descriptor") + for sample in injected: + excluded = [tuple(pair) for pair in sample["pair_exclude_types"]] + self.assertIn((0, 1), excluded, "model exclusions not honoured") + self.assertIn((2, 2), excluded, "grid-grid pairs not excluded") + def test_stat_file_grid_row_writeback(self) -> None: # the patched grid-type row is written back to the stat cache, and a # complete cache then takes the fast path without the injected pass From b75d3837b9a8d803f408cd005dc51ecd98cdf409 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 18 Sep 2026 05:47:04 +0000 Subject: [PATCH 12/23] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- source/tests/pt/test_dp_test_density.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index d064aa4336..4286aa94c7 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -21,6 +21,9 @@ from deepmd.infer.deep_eval import ( DeepEval, ) +from deepmd.pt.entrypoints.main import ( + get_trainer, +) from deepmd.pt.model.atomic_model.density_atomic_model import ( DPDensityAtomicModel, ) @@ -36,9 +39,6 @@ from deepmd.pt.model.task.density import ( DensityFittingNet, ) -from deepmd.pt.entrypoints.main import ( - get_trainer, -) from deepmd.utils.argcheck import ( normalize, ) From 6145ae110bce0da3bdaa17bf560c1ac12e6dd225 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Wed, 23 Sep 2026 03:04:46 +0000 Subject: [PATCH 13/23] fix(pt): close review round on density eval, statistics, and loader checks - gate the eval grid guard on has_grid, so a property named density stays evaluable after the dispatch fix; extend the mirror test to actually call eval - use max(natoms, ngrid) as the auto-batch proxy in the stat pass too - validate the trailing dimension of frame_major data against ndof, and fail mixed batches with a clear message on ragged extents - make the hybrid env_protection test a real regression (pop the sub-descriptor value so the default branch is what is asserted) - reject a real element in the reserved grid-type slot at construction - add GridDensityLoss serialize/deserialize, remove the now-dead find_density==0 branch, fix the loss docstring, and link issue #6029 from the no-op guards - tighten _model_has_grid to AttributeError and state the 1e-6 default rationale - add tests for all of the above --- deepmd/pt/infer/deep_eval.py | 6 ++- deepmd/pt/loss/charge.py | 49 ++++++++++++++---- .../atomic_model/density_atomic_model.py | 32 ++++++------ deepmd/pt/utils/stat.py | 10 +++- deepmd/utils/argcheck.py | 5 +- deepmd/utils/data.py | 12 +++++ deepmd/utils/data_system.py | 9 ++++ .../common/test_deepmd_data_grid_density.py | 50 +++++++++++++++++++ source/tests/pt/test_dp_test_density.py | 35 +++++++++++++ 9 files changed, 180 insertions(+), 28 deletions(-) diff --git a/deepmd/pt/infer/deep_eval.py b/deepmd/pt/infer/deep_eval.py index e254590211..c57530f9c6 100644 --- a/deepmd/pt/infer/deep_eval.py +++ b/deepmd/pt/infer/deep_eval.py @@ -460,7 +460,7 @@ def _model_has_grid(model: Any) -> bool: has_grid = getattr(model, "has_grid", None) try: return bool(has_grid()) if callable(has_grid) else False - except Exception: + except AttributeError: return False def get_sel_type(self) -> list[int]: @@ -592,7 +592,9 @@ def eval( if isinstance(out, tuple): (out,) = out return {"density": out} - if "density" in self.output_def.var_defs: + if "density" in self.output_def.var_defs and self._model_has_grid( + self.dp.model["Default"] + ): raise ValueError( "grid is required to evaluate a density model; " "pass grid=... with shape (nframes, ngrid, 3)" diff --git a/deepmd/pt/loss/charge.py b/deepmd/pt/loss/charge.py index d1e35be6fb..f593f303a3 100644 --- a/deepmd/pt/loss/charge.py +++ b/deepmd/pt/loss/charge.py @@ -17,6 +17,9 @@ from deepmd.utils.data import ( DataRequirementItem, ) +from deepmd.utils.version import ( + check_version_compatibility, +) class GridDensityLoss(TaskLoss): @@ -95,17 +98,8 @@ def forward( # more_loss['log_keys'] = [] # showed when validation on the fly # more_loss['test_keys'] = [] # showed when doing dp test if self.has_d and "density" in model_pred and "density" in label: - find_density = label.get("find_density", 0.0) + find_density = label.get("find_density", 1.0) density_pred = model_pred["density"] - if find_density == 0: - # density label is absent: the loader fills an atom-shaped - # default tensor, which cannot be subtracted from the - # grid-point prediction; skip the residual but keep the - # graph connected for backward - loss = loss + (density_pred.sum() * 0.0).to(GLOBAL_PT_FLOAT_PRECISION) - more_loss["rmse_d"] = torch.nan - more_loss["mae_d"] = torch.nan - return model_pred, loss, more_loss density_label = label["density"] pref_d = pref_d * find_density # mask out excluded grid points (the atomic model zeroes them @@ -143,6 +137,41 @@ def forward( ) return model_pred, loss, more_loss + def serialize(self) -> dict: + """Serialize the loss module. + + Returns + ------- + dict + The serialized loss module + """ + return { + "@class": "GridDensityLoss", + "@version": 1, + "starter_learning_rate": self.starter_learning_rate, + "start_pref_d": self.start_pref_d, + "limit_pref_d": self.limit_pref_d, + } + + @classmethod + def deserialize(cls, data: dict) -> "TaskLoss": + """Deserialize the loss module. + + Parameters + ---------- + data : dict + The serialized loss module + + Returns + ------- + TaskLoss + The deserialized loss module + """ + data = data.copy() + check_version_compatibility(data.pop("@version"), 1, 1) + data.pop("@class") + return cls(**data) + @property def label_requirement(self) -> list[DataRequirementItem]: """Return data label requirements needed for this loss calculation. diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index 2de773daa9..c8ff100b11 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -32,6 +32,9 @@ from deepmd.pt.utils.region import ( normalize_coord, ) +from deepmd.utils.model_preset import ( + PERIODIC_TABLE, +) from deepmd.utils.path import ( DPPath, ) @@ -55,6 +58,13 @@ def __init__( super().__init__(descriptor, fitting, type_map, **kwargs) self.rcut = self.descriptor.get_rcut() self.rcut_smth = self.descriptor.get_rcut_smth() + if type_map and type_map[-1] in PERIODIC_TABLE: + raise ValueError( + "the last entry of type_map must be a reserved grid type " + "for a density model, but got the real element " + f"{type_map[-1]!r}; append a non-element placeholder " + '(e.g. "X") at the end of type_map' + ) if self.descriptor.get_env_protection() == 0.0: log.warning( "The descriptor env_protection is 0.0; grid points coincident " @@ -385,6 +395,9 @@ def change_out_bias( adjustment (change-by-statistic / set-by-statistic) does not apply. The fitting net will adapt to the target dataset through normal gradient descent during training. + + This guard stays until output-stat support is designed for grid + models; tracked in https://github.com/deepmodeling/deepmd-kit/issues/6029. """ log.warning("change_out_bias is not supported for density models; skipping.") @@ -621,20 +634,11 @@ def compute_or_load_out_stat( merged: Callable[[], list[dict]] | list[dict], stat_file_path: DPPath | None = None, ) -> None: - """ - Compute the output statistics (e.g. energy bias) for the fitting net from packed data. - - Parameters - ---------- - merged : Union[Callable[[], list[dict]], list[dict]] - - list[dict]: A list of data samples from various data systems. - Each element, `merged[i]`, is a data dictionary containing `keys`: `torch.Tensor` - originating from the `i`-th data system. - - Callable[[], list[dict]]: A lazy function that returns data samples in the above format - only when needed. Since the sampling process can be slow and memory-intensive, - the lazy function helps by only sampling once. - stat_file_path : Optional[DPPath] - The path to the stat file. + """Compute the output statistics for the fitting net. + Not implemented for density models: the output lives on grid points, + so per-type atomic output statistics do not apply. This guard stays + until output-stat support is designed for grid models; tracked in + https://github.com/deepmodeling/deepmd-kit/issues/6029. """ log.warning("Not implemented yet for density out stat!") diff --git a/deepmd/pt/utils/stat.py b/deepmd/pt/utils/stat.py index 465dcba792..f34f85e0a7 100644 --- a/deepmd/pt/utils/stat.py +++ b/deepmd/pt/utils/stat.py @@ -411,11 +411,19 @@ def _compute_model_predict( charge_spin = system.get("charge_spin", None) spin = system.get("model_spin", system.get("spin", None)) + size_proxy = system["atype"].shape[-1] + if "grid" in system: + # the directional neighbor list is dense in ngrid x nall, so the + # batching size proxy must account for the grid extent + grid = system["grid"] + ngrid = grid.shape[-2] if grid.ndim >= 3 else grid.shape[-1] // 3 + size_proxy = max(size_proxy, ngrid) + def model_forward_auto_batch_size(*args: Any, **kwargs: Any) -> Any: return auto_batch_size.execute_all( model_forward, nframes, - system["atype"].shape[-1], + size_proxy, *args, **kwargs, ) diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index 736f1b1d5e..f9182b3d40 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -6638,7 +6638,10 @@ def _apply_density_env_protection_default(data: dict[str, Any]) -> None: Applied at normalization time so that the recorded model_def_script and the built model agree on this field. Grid points may legitimately coincide with atoms, and the default 0.0 would let the 1/r terms in the - environment matrix produce NaN densities. + environment matrix produce NaN densities. 1e-6 is chosen as the minimal + perturbation that keeps those terms finite (order 1e6 at exact + coincidence) without shifting normal environments measurably; users can + still set any positive value (e.g. 0.1) explicitly. """ def _fix(model: dict[str, Any]) -> None: diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index b464e4bcda..1116d0647b 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -915,6 +915,12 @@ def _load_data( f"The frame count of data {key} in {set_name} is " f"{data.shape[0]}, which doesn't match the set's nframes {nframes}" ) + if data.shape[-1] % ndof_ != 0: + raise ValueError( + f"The data {key} in {set_name} has trailing dimension " + f"{data.shape[-1]}, which is not a multiple of the " + f"declared ndof {ndof_}" + ) return np.float32(1.0), data if path.is_file(): data = path.load_numpy().astype(dtype) @@ -1087,6 +1093,12 @@ def _load_single_data( f"{mmap_obj.shape[0]}, which doesn't match the set's " f"nframes {set_nframes}" ) + if mmap_obj.shape[-1] % ndof != 0: + raise ValueError( + f"The data {key} in {set_dir} has trailing dimension " + f"{mmap_obj.shape[-1]}, which is not a multiple of the " + f"declared ndof {ndof}" + ) # corner case: single frame. frame-major arrays always carry a # leading frame dimension (validated above), so no expansion is needed. diff --git a/deepmd/utils/data_system.py b/deepmd/utils/data_system.py index cea270bd37..5d56bf16b0 100644 --- a/deepmd/utils/data_system.py +++ b/deepmd/utils/data_system.py @@ -579,6 +579,15 @@ def _merge_batch_data(self, batch_data: list[dict]) -> dict: ) b_data[kk] = merged.reshape(len(batch_data), -1) elif not vv["atomic"]: + if vv.get("special_shape") == "frame_major": + extents = {bb[kk].shape[1:] for bb in batch_data} + if len(extents) > 1: + raise ValueError( + f"The frame-major data {kk} has inconsistent " + f"extents {sorted(extents)} across systems; " + "mixed batching requires the same extent in " + "every system" + ) b_data[kk] = np.concatenate([bb[kk] for bb in batch_data], axis=0) else: b_data[kk] = np.zeros( diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index 0b45a20d63..fe06a6ef7a 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -128,6 +128,56 @@ def test_missing_file_optional(self) -> None: frame = data.get_single_frame(0, 0) self.assertEqual(frame["find_density"], 0.0) + def test_ndof_mismatch(self) -> None: + # a grid file whose width is not a multiple of ndof must be rejected + self.set_data("grid", np.zeros((NFRAMES, NGRID, 4), dtype=np.float32)) + with self.assertRaisesRegex(ValueError, "ndof"): + self.build_data()._load_set(self.set_dir) + with self.assertRaisesRegex(ValueError, "ndof"): + self.build_data().get_single_frame(0, 0) + + def test_ragged_mixed_batch_clear_error(self) -> None: + # mixed batching across systems with different ngrid must fail with + # a clear message instead of a raw numpy shape error + from deepmd.utils.data_system import ( + DeepmdDataSystem, + ) + + class StubDS(DeepmdDataSystem): + def __init__(self) -> None: + pass + + def get_ntypes(self) -> int: + return 2 + + def get_data_dict(self, idx: int) -> dict: + return { + "density": { + "atomic": False, + "special_shape": "frame_major", + "ndof": 1, + } + } + + batch_data = [ + { + "type": np.zeros((1, 3), dtype=np.int32), + "natoms_vec": np.array([3, 3, 1, 1], dtype=np.int32), + "default_mesh": np.zeros(9), + "density": np.zeros((1, 5), dtype=np.float32), + "find_density": 1.0, + }, + { + "type": np.zeros((1, 3), dtype=np.int32), + "natoms_vec": np.array([3, 3, 1, 1], dtype=np.int32), + "default_mesh": np.zeros(9), + "density": np.zeros((1, 6), dtype=np.float32), + "find_density": 1.0, + }, + ] + with self.assertRaisesRegex(ValueError, "extent"): + StubDS()._merge_batch_data(batch_data) + def test_property_named_density_not_hijacked(self) -> None: # a user property named "density" without a special_shape declaration # must load through the ordinary path, not the frame-major branch diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index d064aa4336..a8b06bd129 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -213,6 +213,14 @@ def test_property_named_density_dispatches_to_property(self) -> None: torch.jit.save(torch.jit.script(model), path) dp = DeepEval(path) self.assertIsInstance(dp, DeepProperty) + # the property must stay evaluable: the eval guard keys on the + # grid capability, not the output-variable name + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:2] + box = np.load(set_dir / "box.npy")[:2] + atype = np.loadtxt(self.system / "type.raw", dtype=int) + result = dp.eval(coord, box, atype) + self.assertEqual(result[0].shape[0], 2) finally: os.unlink(path) @@ -276,6 +284,20 @@ def test_fitting_rejects_aparam(self) -> None: numb_aparam=2, ) + def test_loss_serialization(self) -> None: + # GridDensityLoss round-trips through serialize/deserialize + from deepmd.pt.loss.charge import ( + GridDensityLoss, + ) + + loss_fn = GridDensityLoss( + starter_learning_rate=0.001, start_pref_d=2.0, limit_pref_d=0.5 + ) + data = loss_fn.serialize() + self.assertEqual(data["@class"], "GridDensityLoss") + restored = GridDensityLoss.deserialize(data) + self.assertEqual(restored.serialize(), data) + def test_loss_inference_mode(self) -> None: # inference=True reports the metrics even with zero prefactors from deepmd.pt.loss.charge import ( @@ -395,6 +417,16 @@ def sampler() -> list: model.compute_or_load_stat(sampler, stat_file_path=stat_dir) + def test_grid_type_requires_reserved_slot(self) -> None: + # a real element in the reserved slot must be rejected, not + # silently used as the grid type + descriptor = DescrptSeA(rcut=4.0, rcut_smth=0.5, sel=[8, 8]) + fitting = DensityFittingNet(descriptor.get_ntypes(), descriptor.get_dim_out()) + with self.assertRaisesRegex(ValueError, "reserved grid type"): + DPDensityAtomicModel(descriptor, fitting, type_map=["O", "H"]) + # non-element reserved slot is accepted (all other tests use X) + DPDensityAtomicModel(descriptor, fitting, type_map=["O", "X"]) + def test_env_protection_enforced_at_model_level(self) -> None: # models constructed directly with env_protection == 0.0 get the # guard set on the descriptor block, not just a warning @@ -410,6 +442,9 @@ def test_env_protection_hybrid(self) -> None: # must reach every sub-descriptor config = deepcopy(self.config) descriptor = config["model"].pop("descriptor") + # the sub-descriptor must not carry an explicit value: the asserted + # 1e-6 has to be an effect of the default, not of the input config + descriptor.pop("env_protection", None) config["model"]["descriptor"] = {"type": "hybrid", "list": [descriptor]} normalized = normalize(config) self.assertEqual( From e23e953db10ba98b43d1ed51f17af23822a6e5da Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Wed, 23 Sep 2026 03:30:37 +0000 Subject: [PATCH 14/23] test: avoid subclass __init__ bypass flagged by CodeQL in data test double --- source/tests/common/test_deepmd_data_grid_density.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index fe06a6ef7a..84a2ca96ee 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -176,7 +176,7 @@ def get_data_dict(self, idx: int) -> dict: }, ] with self.assertRaisesRegex(ValueError, "extent"): - StubDS()._merge_batch_data(batch_data) + StubDS.__new__(StubDS)._merge_batch_data(batch_data) def test_property_named_density_not_hijacked(self) -> None: # a user property named "density" without a special_shape declaration From bbbcec8b58aa8d106200b5f8195be160d4953fc7 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Wed, 23 Sep 2026 08:14:42 +0000 Subject: [PATCH 15/23] test: avoid subclass __init__ bypass flagged by CodeQL in data test double --- source/tests/common/test_deepmd_data_grid_density.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index 84a2ca96ee..f23d8107e9 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -144,8 +144,7 @@ def test_ragged_mixed_batch_clear_error(self) -> None: ) class StubDS(DeepmdDataSystem): - def __init__(self) -> None: - pass + """Test double: instantiated via __new__ to skip the heavy init.""" def get_ntypes(self) -> int: return 2 From 4f83b590a3147bccf82d1e8ba4254c9baf630648 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Wed, 23 Sep 2026 08:25:02 +0000 Subject: [PATCH 16/23] fix(data): require exact ndof for 3D frame_major arrays A 3D (nframes, npoints, ndof) array now requires the trailing dimension to equal the declared ndof exactly; the flattened (nframes, npoints*ndof) layout keeps the divisibility check. Previously a divisible-but-wrong width (e.g. 6 for ndof 3) passed and downstream view(..., -1, 3) silently doubled the interpreted grid-point count. --- deepmd/utils/data.py | 20 +++++++++++++++++-- .../common/test_deepmd_data_grid_density.py | 18 +++++++++++++---- 2 files changed, 32 insertions(+), 6 deletions(-) diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index 1116d0647b..0c9c85a784 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -915,7 +915,16 @@ def _load_data( f"The frame count of data {key} in {set_name} is " f"{data.shape[0]}, which doesn't match the set's nframes {nframes}" ) - if data.shape[-1] % ndof_ != 0: + if data.ndim >= 3: + # (nframes, npoints, ndof): trailing dim must be exactly ndof + if data.shape[-1] != ndof_: + raise ValueError( + f"The data {key} in {set_name} has trailing dimension " + f"{data.shape[-1]}, which doesn't match the declared " + f"ndof {ndof_}" + ) + elif data.shape[-1] % ndof_ != 0: + # (nframes, npoints*ndof) flattened: width must be a multiple raise ValueError( f"The data {key} in {set_name} has trailing dimension " f"{data.shape[-1]}, which is not a multiple of the " @@ -1093,7 +1102,14 @@ def _load_single_data( f"{mmap_obj.shape[0]}, which doesn't match the set's " f"nframes {set_nframes}" ) - if mmap_obj.shape[-1] % ndof != 0: + if mmap_obj.ndim >= 3: + if mmap_obj.shape[-1] != ndof: + raise ValueError( + f"The data {key} in {set_dir} has trailing dimension " + f"{mmap_obj.shape[-1]}, which doesn't match the declared " + f"ndof {ndof}" + ) + elif mmap_obj.shape[-1] % ndof != 0: raise ValueError( f"The data {key} in {set_dir} has trailing dimension " f"{mmap_obj.shape[-1]}, which is not a multiple of the " diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index f23d8107e9..a7e36e25c4 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -129,12 +129,22 @@ def test_missing_file_optional(self) -> None: self.assertEqual(frame["find_density"], 0.0) def test_ndof_mismatch(self) -> None: - # a grid file whose width is not a multiple of ndof must be rejected - self.set_data("grid", np.zeros((NFRAMES, NGRID, 4), dtype=np.float32)) + # 3D layout: trailing dim must be exactly ndof (a divisible-but-wrong + # width like 6 would silently double ngrid downstream) + for width in (4, 6): + self.set_data("grid", np.zeros((NFRAMES, NGRID, width), dtype=np.float32)) + with self.assertRaisesRegex(ValueError, "ndof"): + self.build_data()._load_set(self.set_dir) + with self.assertRaisesRegex(ValueError, "ndof"): + self.build_data().get_single_frame(0, 0) + # flattened layout: width must be a multiple of ndof + self.set_data("grid", np.zeros((NFRAMES, NGRID * 3 + 1), dtype=np.float32)) with self.assertRaisesRegex(ValueError, "ndof"): self.build_data()._load_set(self.set_dir) - with self.assertRaisesRegex(ValueError, "ndof"): - self.build_data().get_single_frame(0, 0) + # correct flattened layout passes + self.set_data("grid", np.zeros((NFRAMES, NGRID * 3), dtype=np.float32)) + loaded = self.build_data()._load_set(self.set_dir) + self.assertEqual(loaded["find_grid"], 1.0) def test_ragged_mixed_batch_clear_error(self) -> None: # mixed batching across systems with different ngrid must fail with From 3e7c25964b011faeaa43adb2fe7f251538b3562b Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Sat, 3 Oct 2026 09:13:51 +0000 Subject: [PATCH 17/23] fix(pt): align density data layout, forward charge_spin, and loader cross-checks - ship the example data in the documented (nframes, npoints, ndof) layout so the data, the docs, and the inference validation agree - cross-check the extents of frame-major keys in _load_set: a grid and density pair with different npoints now fails with a clear message - forward charge_spin through the density atomic model into the descriptor instead of silently discarding it - remove the never-read mean/stddev buffers (they rode into state_dict and broke restarts with a different sel), and fix the loss docstring - document the stat-proxy grid handling as future out-stat support, note that _eval_model_density ignores request_defs by design, and state that an explicit env_protection 0.0 is indistinguishable from the schema default --- deepmd/pt/infer/deep_eval.py | 4 ++++ deepmd/pt/loss/charge.py | 2 +- .../atomic_model/density_atomic_model.py | 21 ++++------------- deepmd/pt/utils/stat.py | 5 +++- deepmd/utils/argcheck.py | 4 +++- deepmd/utils/data.py | 22 ++++++++++++++++++ .../qm9/C7H15NO_train/set.000/density.npy | Bin 10128 -> 10128 bytes .../qm9/C7H15NO_train/set.000/grid.npy | Bin 30128 -> 30128 bytes .../qm9/C7H15NO_val/set.000/density.npy | Bin 2628 -> 2628 bytes .../dataset/qm9/C7H15NO_val/set.000/grid.npy | Bin 7628 -> 7628 bytes .../common/test_deepmd_data_grid_density.py | 6 +++++ 11 files changed, 45 insertions(+), 19 deletions(-) diff --git a/deepmd/pt/infer/deep_eval.py b/deepmd/pt/infer/deep_eval.py index c57530f9c6..f31ddb27ab 100644 --- a/deepmd/pt/infer/deep_eval.py +++ b/deepmd/pt/infer/deep_eval.py @@ -589,6 +589,10 @@ def eval( # _eval_model_density returns a 1-element tuple; execute_all unwraps # it when auto batching is enabled, but with auto_batch_size=False # the inner function is called directly and the tuple survives. + # request_defs is ignored on this path: the density output is a + # single fixed variable, so atomic=True returns the same dict as + # atomic=False. Kept for signature parity with the other + # _eval_model_* paths. if isinstance(out, tuple): (out,) = out return {"density": out} diff --git a/deepmd/pt/loss/charge.py b/deepmd/pt/loss/charge.py index f593f303a3..f16276d1d8 100644 --- a/deepmd/pt/loss/charge.py +++ b/deepmd/pt/loss/charge.py @@ -67,7 +67,7 @@ def forward( learning_rate: float, mae: bool = False, ) -> tuple[dict[str, torch.Tensor], torch.Tensor, dict[str, torch.Tensor]]: - """Return loss on energy and force. + """Return loss on grid density. Parameters ---------- diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index c8ff100b11..d046370528 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -22,9 +22,6 @@ from deepmd.pt.model.task.density import ( DensityFittingNet, ) -from deepmd.pt.utils import ( - env, -) from deepmd.pt.utils.nlist import ( build_directional_neighbor_list, extend_input_and_build_neighbor_list, @@ -74,16 +71,6 @@ def __init__( self.sel = self.descriptor.get_sel() self.nnei = self.descriptor.get_nsel() - wanted_shape = (1, self.nnei, 4) - mean = torch.zeros( - wanted_shape, dtype=env.GLOBAL_PT_FLOAT_PRECISION, device=env.DEVICE - ) - stddev = torch.ones( - wanted_shape, dtype=env.GLOBAL_PT_FLOAT_PRECISION, device=env.DEVICE - ) - self.register_buffer("mean", mean) - self.register_buffer("stddev", stddev) - def forward_atomic( self, extended_coord: torch.Tensor, @@ -122,7 +109,7 @@ def forward_atomic( the result dict, defined by the `FittingOutputDef`. """ - del charge_spin, return_atomic_feature + del return_atomic_feature nframes, _, _ = nlist.shape if self.do_grad_r() or self.do_grad_c(): extended_coord.requires_grad_(True) @@ -166,6 +153,7 @@ def forward_atomic( merged_nlist, mapping=merged_mapping, comm_dict=comm_dict, + charge_spin=charge_spin, ) assert descriptor is not None @@ -234,7 +222,6 @@ def forward_common_atomic( assert grid is not None assert grid_type is not None assert grid_nlist is not None - del charge_spin nframes, _, _ = nlist.shape _, ngrid, _ = grid_nlist.shape @@ -276,6 +263,7 @@ def forward_common_atomic( grid=grid, grid_type=grid_type, grid_nlist=grid_nlist, + charge_spin=charge_spin, ) ret_dict = self.apply_out_stat(ret_dict, grid_type) @@ -330,7 +318,7 @@ def model_forward( spin: torch.Tensor | None = None, grid: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: - del charge_spin, spin + del spin with torch.no_grad(): ( extended_coord, @@ -377,6 +365,7 @@ def model_forward( grid=grid, grid_type=grid_type, grid_nlist=grid_nlist, + charge_spin=charge_spin, ) return {kk: vv.detach() for kk, vv in atomic_ret.items()} diff --git a/deepmd/pt/utils/stat.py b/deepmd/pt/utils/stat.py index f34f85e0a7..28c1b7ae01 100644 --- a/deepmd/pt/utils/stat.py +++ b/deepmd/pt/utils/stat.py @@ -414,7 +414,10 @@ def _compute_model_predict( size_proxy = system["atype"].shape[-1] if "grid" in system: # the directional neighbor list is dense in ngrid x nall, so the - # batching size proxy must account for the grid extent + # batching size proxy must account for the grid extent. Note: no + # density model reaches this out-stat path today (out-stat is a + # documented no-op for grid models, see issue #6029), so this is + # for a future out-stat design grid = system["grid"] ngrid = grid.shape[-2] if grid.ndim >= 3 else grid.shape[-1] // 3 size_proxy = max(size_proxy, ngrid) diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index d8bc5a6fb9..e2e07a4e24 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -6660,7 +6660,9 @@ def _apply_density_env_protection_default(data: dict[str, Any]) -> None: environment matrix produce NaN densities. 1e-6 is chosen as the minimal perturbation that keeps those terms finite (order 1e6 at exact coincidence) without shifting normal environments measurably; users can - still set any positive value (e.g. 0.1) explicitly. + still set any positive value (e.g. 0.1) explicitly. An explicit + ``env_protection: 0.0`` cannot be distinguished from the schema default + (which normalizes to 0.0) and receives the same override with a warning. """ def _fix(model: dict[str, Any]) -> None: diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index 0c9c85a784..9e3f4ee1a8 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -811,6 +811,28 @@ def _load_set(self, set_name: DPPath) -> dict[str, Any]: np.reshape(tmp_in, [nframes, self.natoms, ndof]), axis=1 ) + # frame-major keys that share the same extent must agree on it: + # a grid/density pair with different npoints would only fail far + # downstream when the residual is formed + frame_major_extents = {} + for kk, vv in self.data_dict.items(): + if ( + vv.get("special_shape") == "frame_major" + and kk in data + and float(data.get("find_" + kk, 0.0)) == 1.0 + ): + arr = data[kk] + extent = arr.shape[-2] if arr.ndim >= 3 else arr.shape[-1] // vv["ndof"] + frame_major_extents[kk] = extent + if frame_major_extents: + extents = set(frame_major_extents.values()) + if len(extents) > 1: + raise ValueError( + f"The frame-major data in {set_name} have inconsistent " + f"extents {frame_major_extents}; grid and density labels " + "must share the same number of points" + ) + if self.mixed_type: # nframes x natoms atom_type_mix = self._load_type_mix(set_name) diff --git a/examples/density/dataset/qm9/C7H15NO_train/set.000/density.npy b/examples/density/dataset/qm9/C7H15NO_train/set.000/density.npy index 2343cb4659b14fe3b9a7aadda4bc18ce2284b5ea..24289af96359f61fc423e05954766883bdde1fd0 100644 GIT binary patch delta 24 fcmbQ>Kf!;33%ibjp{9;P?ZiO6i3w~Q>jl*TU`z*i delta 21 ccmbQ>Kf!;33yY?XLhZyry@?5&8|wwt0Z^3&`v3p{ diff --git a/examples/density/dataset/qm9/C7H15NO_train/set.000/grid.npy b/examples/density/dataset/qm9/C7H15NO_train/set.000/grid.npy index bc2ccd2daff6795ece843251edc5c4de7efa996d..fb95783aa9883a343362a3870c5d0dfada8e7587 100644 GIT binary patch delta 29 lcmdn+nsLKx#tDvGhDN433dWi`3bhjh^(H2;ZLBve1puA}3Hks4 delta 26 icmdn+nsLKx#tDw>#^$D)ItsND1N9~*aBi$OECm3FV+n!) diff --git a/examples/density/dataset/qm9/C7H15NO_val/set.000/density.npy b/examples/density/dataset/qm9/C7H15NO_val/set.000/density.npy index 1159a739ebe35917ac05ce342a904b7f53260a36..e0c673e4e27ccde6ec441d45711aa2ed2a788bf3 100644 GIT binary patch delta 24 gcmX>iaztc;GrNw0p{9;P?ZiO6i3#i*>yL5*0ARcb00000 delta 21 dcmX>iaztc;GmEBwRSbY5fQs diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index a7e36e25c4..bcf2892ac1 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -187,6 +187,12 @@ def get_data_dict(self, idx: int) -> dict: with self.assertRaisesRegex(ValueError, "extent"): StubDS.__new__(StubDS)._merge_batch_data(batch_data) + def test_grid_density_extent_mismatch(self) -> None: + # grid and density must carry the same number of points per frame + self.set_data("density", np.zeros((NFRAMES, NGRID + 2, 1), dtype=np.float32)) + with self.assertRaisesRegex(ValueError, "extents"): + self.build_data()._load_set(self.set_dir) + def test_property_named_density_not_hijacked(self) -> None: # a user property named "density" without a special_shape declaration # must load through the ordinary path, not the frame-major branch From 7a4c466bd23818ddbd0640445a5b1d977c32fe96 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Sat, 3 Oct 2026 09:38:48 +0000 Subject: [PATCH 18/23] fix(data): guard frame-major extents across sets and align the density doc - _load_test_set now rejects sets of one system whose frame-major keys disagree on the point extent, with a clear message instead of the raw numpy concatenate error - the density fitting guide no longer documents the optional-label mode that must=True forbids; it states density.npy is required --- deepmd/utils/data.py | 20 ++++++++++++++++++ doc/model/train-fitting-density.md | 2 +- .../common/test_deepmd_data_grid_density.py | 21 +++++++++++++++++++ 3 files changed, 42 insertions(+), 1 deletion(-) diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index 9e3f4ee1a8..7c3d5e7616 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -695,6 +695,26 @@ def _load_test_set(self, shuffle_test: bool) -> None: if "find_" in kk: self.test_set[kk] = test_sets[0][kk] else: + vv = self.data_dict.get(kk, {}) + if vv.get("special_shape") == "frame_major": + # sets of one system must agree on the frame-major extent: + # numpy would otherwise fail with a raw shape error + extents = { + ( + ss[kk].shape[-2] + if ss[kk].ndim >= 3 + else ss[kk].shape[-1] // vv["ndof"] + ) + for ss in test_sets + if float(ss.get("find_" + kk, 0.0)) == 1.0 + } + if len(extents) > 1: + raise ValueError( + f"The frame-major data {kk} has inconsistent " + f"extents {sorted(extents)} across the sets of " + "this system; every set must carry the same " + "number of points" + ) self.test_set[kk] = np.concatenate( [test_set[kk] for test_set in test_sets], axis=0 ) diff --git a/doc/model/train-fitting-density.md b/doc/model/train-fitting-density.md index 20aab082ac..56501a93f8 100644 --- a/doc/model/train-fitting-density.md +++ b/doc/model/train-fitting-density.md @@ -61,7 +61,7 @@ The grid density model is trained with the `grid_density` loss, which minimises ``` - {ref}`type ` should be written as `grid_density`. -- `start_pref_d` and `limit_pref_d` specify the weight of the density loss at the start and at the end of the training. If both are set to 0, the density label is not required and the term is skipped. Systems without a `density.npy` file are also skipped (with `find_density = 0`) when the label is optional. +- `start_pref_d` and `limit_pref_d` specify the weight of the density loss at the start and at the end of the training. If both are set to 0, the density term is skipped (and the graph is kept connected). Note that `density.npy` is **required** in every training and validation system — it is the model's only supervision signal, and a missing file aborts training at load time. ## Evaluation diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index bcf2892ac1..48b43433e9 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -193,6 +193,27 @@ def test_grid_density_extent_mismatch(self) -> None: with self.assertRaisesRegex(ValueError, "extents"): self.build_data()._load_set(self.set_dir) + def test_cross_set_extent_mismatch(self) -> None: + # two sets of one system must agree on the frame-major extent; + # numpy would otherwise fail with a raw shape error in get_test + set1 = self.root / "set.001" + set1.mkdir() + rng = np.random.default_rng(1) + np.save(set1 / "coord.npy", rng.random((NFRAMES, NATOMS * 3), dtype=np.float32)) + np.save( + set1 / "box.npy", + np.eye(3, dtype=np.float32).reshape(1, 9).repeat(NFRAMES, axis=0), + ) + np.save(set1 / "type.npy", np.zeros((NFRAMES, NATOMS), dtype=np.int32)) + np.save( + set1 / "grid.npy", rng.random((NFRAMES, NGRID + 3, 3), dtype=np.float32) + ) + np.save( + set1 / "density.npy", rng.random((NFRAMES, NGRID + 3, 1), dtype=np.float32) + ) + with self.assertRaisesRegex(ValueError, "extents"): + self.build_data().get_test() + def test_property_named_density_not_hijacked(self) -> None: # a user property named "density" without a special_shape declaration # must load through the ordinary path, not the frame-major branch From 094a19f5a1eb559c45411c9846c9d228b9e50fa4 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Tue, 13 Oct 2026 06:59:23 +0000 Subject: [PATCH 19/23] fix(pt): address density model review on serialization, charge_spin, and data checks - raise the density fitting @version cap to 5 to match GeneralFitting - register the grid density model as "density" too, so BaseModel.deserialize and dp convert-backend resolve it - forward charge_spin through the inference and dp test paths and fill default_chg_spin in the density atomic model forward - check grid/density extent agreement on the get_item_torch path - normalize the flattened grid layout in DensityTester and fix the Option 2 example script grid reshape - fill omitted hybrid sub-descriptor env_protection with the siblings' common explicit value - correct the forward_common_atomic mask docstring --- deepmd/infer/deep_density.py | 4 +- deepmd/infer/model_test/density.py | 19 +- deepmd/pt/infer/deep_eval.py | 7 + .../atomic_model/density_atomic_model.py | 15 +- deepmd/pt/model/model/density_model.py | 1 + deepmd/pt/model/task/density.py | 2 +- deepmd/utils/argcheck.py | 16 +- deepmd/utils/data.py | 22 ++ examples/density/dptest_density_script.py | 7 +- .../common/test_deepmd_data_grid_density.py | 10 + source/tests/pt/test_dp_test_density.py | 241 ++++++++++++++++++ 11 files changed, 331 insertions(+), 13 deletions(-) diff --git a/deepmd/infer/deep_density.py b/deepmd/infer/deep_density.py index 79e8d32c1b..700f6bc8bb 100644 --- a/deepmd/infer/deep_density.py +++ b/deepmd/infer/deep_density.py @@ -89,7 +89,9 @@ def eval( mixed_type : bool, optional Whether the atom_types is mixed type, by default False. **kwargs : dict[str, Any] - Keyword arguments. + Keyword arguments. ``charge_spin`` (nframes, 2) is forwarded to + models with charge spin embedding; when omitted, such models use + their ``default_chg_spin`` if set. Returns ------- diff --git a/deepmd/infer/model_test/density.py b/deepmd/infer/model_test/density.py index 14e5bf4603..27f3aa5d31 100644 --- a/deepmd/infer/model_test/density.py +++ b/deepmd/infer/model_test/density.py @@ -56,6 +56,14 @@ def add_data_requirements(self, data: DeepmdData) -> None: data.add( "aparam", dp.get_dim_aparam(), atomic=True, must=True, high_prec=False ) + if dp.has_chg_spin_ebd(): + data.add( + "charge_spin", + 2, + atomic=False, + must=not dp.has_default_chg_spin(), + high_prec=False, + ) def evaluate_chunk( self, @@ -76,7 +84,15 @@ def evaluate_chunk( atype = test_data["type"][0] fparam = test_data["fparam"] if dp.get_dim_fparam() > 0 else None aparam = test_data["aparam"] if dp.get_dim_aparam() > 0 else None - grid = test_data["grid"] + charge_spin = ( + test_data["charge_spin"] + if dp.has_chg_spin_ebd() and test_data.get("find_charge_spin", 0.0) != 0.0 + else None + ) + # the loader accepts both (nframes, ngrid, 3) and the flattened + # (nframes, ngrid*3) layout; DeepDensity.eval only accepts the + # former, so normalize here and keep one contract at the eval call + grid = test_data["grid"].reshape(nframes, -1, 3) prediction = dp.eval( coord, @@ -85,6 +101,7 @@ def evaluate_chunk( grid, fparam=fparam, aparam=aparam, + charge_spin=charge_spin, mixed_type=mixed_type, ).reshape(nframes, -1) label = test_data["density"].reshape(nframes, -1) diff --git a/deepmd/pt/infer/deep_eval.py b/deepmd/pt/infer/deep_eval.py index f31ddb27ab..5c88ba0049 100644 --- a/deepmd/pt/infer/deep_eval.py +++ b/deepmd/pt/infer/deep_eval.py @@ -585,6 +585,7 @@ def eval( fparam, aparam, self._get_request_defs(atomic), + charge_spin, ) # _eval_model_density returns a 1-element tuple; execute_all unwraps # it when auto batching is enabled, but with auto_batch_size=False @@ -977,6 +978,7 @@ def _eval_model_density( fparam: np.ndarray | None, aparam: np.ndarray | None, request_defs: list[OutputVariableDef], + charge_spin: np.ndarray | None, ) -> tuple[np.ndarray, ...]: model = self.dp.to(DEVICE) @@ -1019,6 +1021,10 @@ def _eval_model_density( ) else: aparam_input = None + if charge_spin is not None: + charge_spin_input = to_torch_tensor(charge_spin.reshape(nframes, 2)) + else: + charge_spin_input = None do_atomic_virial = any( x.category == OutputVariableCategory.DERV_C_REDU for x in request_defs @@ -1031,6 +1037,7 @@ def _eval_model_density( do_atomic_virial=do_atomic_virial, fparam=fparam_input, aparam=aparam_input, + charge_spin=charge_spin_input, ) if isinstance(batch_output, tuple): batch_output = batch_output[0] diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index d046370528..1ee7586145 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -117,6 +117,13 @@ def forward_atomic( assert grid is not None assert grid_type is not None assert grid_nlist is not None + # Handle default chg_spin if the descriptor supports it, the same + # way DPAtomicModel.forward_atomic does + if self.add_chg_spin_ebd and charge_spin is None: + default_cs_tensor = self.descriptor.get_default_chg_spin() + if default_cs_tensor is not None: + default_cs_tensor = default_cs_tensor.to(device=extended_coord.device) + charge_spin = torch.tile(default_cs_tensor.unsqueeze(0), [nframes, 1]) _, ngrid, _ = grid_nlist.shape # nb x (ngrid+nall) x 3 merged_coord = torch.cat([grid, extended_coord], dim=1) @@ -153,7 +160,7 @@ def forward_atomic( merged_nlist, mapping=merged_mapping, comm_dict=comm_dict, - charge_spin=charge_spin, + charge_spin=charge_spin if self.add_chg_spin_ebd else None, ) assert descriptor is not None @@ -214,9 +221,9 @@ def forward_common_atomic( ret_dict dict of output atomic properties. should implement the definition of `fitting_output_def`. - ret_dict["mask"] of shape nf x nloc will be provided. - ret_dict["mask"][ff,ii] == 1 indicating the ii-th atom of the ff-th frame is real. - ret_dict["mask"][ff,ii] == 0 indicating the ii-th atom of the ff-th frame is virtual. + ret_dict["mask"] of shape nf x ngrid will be provided. + ret_dict["mask"][ff,ii] == 1 indicating the ii-th grid point of the ff-th frame is included. + ret_dict["mask"][ff,ii] == 0 indicating the ii-th grid point of the ff-th frame is excluded. """ assert grid is not None diff --git a/deepmd/pt/model/model/density_model.py b/deepmd/pt/model/model/density_model.py index 54b35267c9..a319bf6cf5 100644 --- a/deepmd/pt/model/model/density_model.py +++ b/deepmd/pt/model/model/density_model.py @@ -25,6 +25,7 @@ DPDensityModel_ = make_density_model(DPDensityAtomicModel) +@BaseModel.register("density") @BaseModel.register("grid_density") class GridDensityModel(DPModelCommon, DPDensityModel_): model_type = "grid_density" diff --git a/deepmd/pt/model/task/density.py b/deepmd/pt/model/task/density.py index a382eb05be..5f386ef540 100644 --- a/deepmd/pt/model/task/density.py +++ b/deepmd/pt/model/task/density.py @@ -91,7 +91,7 @@ def output_def(self) -> FittingOutputDef: @classmethod def deserialize(cls, data: dict) -> "GeneralFitting": data = data.copy() - check_version_compatibility(data.pop("@version", 1), 4, 1) + check_version_compatibility(data.pop("@version", 1), 5, 1) data.pop("var_name") data.pop("dim_out") return super().deserialize(data) diff --git a/deepmd/utils/argcheck.py b/deepmd/utils/argcheck.py index df534d35f7..4e3c69eb03 100644 --- a/deepmd/utils/argcheck.py +++ b/deepmd/utils/argcheck.py @@ -6706,10 +6706,19 @@ def _fix(model: dict[str, Any]) -> None: if model.get("fitting_net", {}).get("type") != "density": return descriptor = model.get("descriptor", {}) + fill = 1e-6 # a hybrid descriptor has no top-level env_protection; each - # sub-descriptor carries its own + # sub-descriptor carries its own, and the model build requires all + # of them to agree. Filling each omitted sub-descriptor with 1e-6 + # while a sibling carries an explicit value (e.g. 0.1) would produce + # a mixed list that the build then rejects, so omitted entries take + # the siblings' common explicit value instead. if descriptor.get("type") == "hybrid": sub_descriptors = descriptor.get("list", []) + explicit = {sub.get("env_protection", 0.0) for sub in sub_descriptors} + explicit.discard(0.0) + if len(explicit) == 1: + fill = explicit.pop() else: sub_descriptors = [descriptor] for sub in sub_descriptors: @@ -6717,9 +6726,10 @@ def _fix(model: dict[str, Any]) -> None: log.warning( "env_protection is 0.0 for a density model; grid points " "coincident with atoms would produce NaN densities. " - "Setting env_protection to 1e-6." + "Setting env_protection to %s.", + fill, ) - sub["env_protection"] = 1e-6 + sub["env_protection"] = fill model = data.get("model", {}) if "model_dict" in model: diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index 7c3d5e7616..2893145c34 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -544,6 +544,28 @@ def get_single_frame(self, index: int, num_worker: int) -> dict: # 5. Standardize keys frame_data = {kk.replace("atomic", "atom"): vv for kk, vv in frame_data.items()} + # frame-major keys of one frame must agree on the point extent: a + # grid/density mismatch would otherwise broadcast silently (or fail + # with a raw size error) far downstream in the loss. The per-frame + # payload is (npoints, ndof) for a 3-D source array and (npoints*ndof,) + # for a flattened one. + frame_major_extents = {} + for kk, vv in self.data_dict.items(): + if ( + vv.get("special_shape") == "frame_major" + and kk in frame_data + and float(frame_data.get("find_" + kk, 0.0)) == 1.0 + ): + arr = frame_data[kk] + extent = arr.shape[-2] if arr.ndim >= 2 else arr.shape[-1] // vv["ndof"] + frame_major_extents[kk] = extent + if len(set(frame_major_extents.values())) > 1: + raise ValueError( + f"The frame-major data in {set_dir} have inconsistent " + f"extents {frame_major_extents}; grid and density labels " + "must share the same number of points" + ) + # 6. Reshape non-atomic data to match expected format [ndof]; # frame-major arrays keep their per-frame (npoints, ndof) layout for kk in self.data_dict.keys(): diff --git a/examples/density/dptest_density_script.py b/examples/density/dptest_density_script.py index cd9476b957..ff4bdf8472 100644 --- a/examples/density/dptest_density_script.py +++ b/examples/density/dptest_density_script.py @@ -4,7 +4,7 @@ Usage ----- -python test_density_new.py model.pt /path/to/data --ratio 0.1 --output result.txt +python dptest_density_script.py model.pt /path/to/data --ratio 0.1 --output result.txt """ import argparse @@ -47,7 +47,7 @@ def parse_args() -> argparse.Namespace: parser = argparse.ArgumentParser( - description="Evaluate charge-density DeepPot model." + description="Evaluate a charge-density model on deepmd/npy datasets." ) parser.add_argument("model", type=str, help="Path to the model file (.pt or .pth).") parser.add_argument( @@ -121,7 +121,8 @@ def evaluate( coord = s.data["coords"].reshape(len(s), -1) atype = list(s.data["atom_types"]) cell = s.data["cells"].reshape(len(s), -1) - grid = s.data["grid"].reshape(len(s), -1) + # DeepDensity.eval accepts only the (nframes, ngrid, 3) layout + grid = s.data["grid"].reshape(len(s), -1, 3) density_pred = dm.eval(coord, cell, atype, grid=grid) density_label = s.data["density"].reshape(len(s), -1) diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index 48b43433e9..b0c6c2bce4 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -193,6 +193,16 @@ def test_grid_density_extent_mismatch(self) -> None: with self.assertRaisesRegex(ValueError, "extents"): self.build_data()._load_set(self.set_dir) + def test_extent_mismatch_single_frame(self) -> None: + # the PT training path (get_item_torch -> get_single_frame) assembles + # each frame key by key; the extent cross-check must run there too, + # or a 1-point density broadcasts silently against the ngrid-point + # prediction in the loss + self.set_data("density", np.zeros((NFRAMES, 1, 1), dtype=np.float32)) + data = self.build_data() + with self.assertRaisesRegex(ValueError, "extents"): + data.get_item_torch(0) + def test_cross_set_extent_mismatch(self) -> None: # two sets of one system must agree on the frame-major extent; # numpy would otherwise fail with a raw shape error in get_test diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index 59f84962b6..adf87d7be5 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -36,6 +36,12 @@ from deepmd.pt.model.descriptor.se_r import ( DescrptSeR, ) +from deepmd.pt.model.model import ( + get_model, +) +from deepmd.pt.model.model.density_model import ( + GridDensityModel, +) from deepmd.pt.model.task.density import ( DensityFittingNet, ) @@ -284,6 +290,33 @@ def test_fitting_rejects_aparam(self) -> None: numb_aparam=2, ) + def test_fitting_model_serialization_roundtrip(self) -> None: + # GeneralFitting.serialize() emits @version 5; the density fitting + # and the whole model must round-trip through serialize/deserialize, + # which is what model freezing relies on. The model must go through + # BaseModel.deserialize, which dispatches on the serialized fitting + # type ("density") and is what dp convert-backend uses. + from deepmd.pt.model.model.model import ( + BaseModel, + ) + + fitting = self.torch_model.atomic_model.fitting_net + restored_fit = DensityFittingNet.deserialize(fitting.serialize()) + self._assert_state_dict_equal(fitting, restored_fit) + model = self.torch_model + restored_model = BaseModel.deserialize(model.serialize()) + self.assertIsInstance(restored_model, GridDensityModel) + self._assert_state_dict_equal(model, restored_model) + + def _assert_state_dict_equal( + self, module0: torch.nn.Module, module1: torch.nn.Module + ) -> None: + sd0 = module0.state_dict() + sd1 = module1.state_dict() + self.assertEqual(set(sd0), set(sd1)) + for key in sd0: + torch.testing.assert_close(sd0[key], sd1[key]) + def test_loss_serialization(self) -> None: # GridDensityLoss round-trips through serialize/deserialize from deepmd.pt.loss.charge import ( @@ -452,6 +485,25 @@ def test_env_protection_hybrid(self) -> None: 1e-6, ) + def test_env_protection_hybrid_common_explicit_value(self) -> None: + # a hybrid requires every sub-descriptor to share one env_protection; + # an omitted entry must take the siblings' explicit value, not 1e-6, + # or the model build would reject the mixed list + config = deepcopy(self.config) + descriptor = config["model"].pop("descriptor") + descriptor.pop("env_protection", None) + explicit = deepcopy(descriptor) + explicit["env_protection"] = 0.1 + config["model"]["descriptor"] = { + "type": "hybrid", + "list": [explicit, descriptor], + } + normalized = normalize(config) + values = [ + sub["env_protection"] for sub in normalized["model"]["descriptor"]["list"] + ] + self.assertEqual(values, [0.1, 0.1]) + def test_injected_pass_honors_pair_exclude_types(self) -> None: # the injected stat pass must see the model's pair_exclude_types, # which are only written by the wrapped sampler @@ -724,6 +776,195 @@ def test_dp_test_shuffle(self) -> None: for row in shuf_rows: self.assertIn(row, ref_rows) + def test_dp_test_flattened_grid(self) -> None: + # the loader also accepts a flattened (nframes, ngrid*3) grid; the + # tester must normalize it to the (nframes, ngrid, 3) contract that + # DeepDensity.eval expects, so both layouts give the same details + system = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "system" + shutil.copytree(self.system, system) + set_dir = system / "set.000" + grid3d = np.load(set_dir / "grid.npy") + np.save(set_dir / "grid.npy", grid3d.reshape(self.nframes, -1)) + detail_file = os.path.join(self.tmpdir.name, "detail_flat") + dp_test( + model=self.model_path, + system=str(system), + datafile=None, + numb_test=0, + rand_seed=None, + shuffle_test=False, + detail_file=detail_file, + atomic=False, + ) + coord = np.load(set_dir / "coord.npy") + box = np.load(set_dir / "box.npy") + atype = np.loadtxt(system / "type.raw", dtype=int) + ref = DeepDensity(self.model_path).eval(coord, box, atype, grid=grid3d) + for frame in range(self.nframes): + detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) + self.assertEqual(detail.shape, (self.ngrid, 2)) + np.testing.assert_allclose(detail[:, 1], ref[frame], rtol=1e-5, atol=1e-6) + + +model_density_dpa3_chg_spin = { + "type_map": ["O", "H", "X"], + "descriptor": { + "type": "dpa3", + "repflow": { + "n_dim": 8, + "e_dim": 6, + "a_dim": 4, + "nlayers": 1, + "e_rcut": 4.0, + "e_rcut_smth": 0.5, + "e_sel": 12, + "a_rcut": 3.5, + "a_rcut_smth": 0.5, + "a_sel": 8, + "axis_neuron": 4, + "update_angle": False, + }, + "env_protection": 1e-6, + "add_chg_spin_ebd": True, + "default_chg_spin": [1.0, 0.0], + "seed": 1, + }, + "fitting_net": { + "type": "density", + "neuron": [8, 8], + "seed": 1, + }, +} + + +class TestDPTestDensityChgSpin(unittest.TestCase): + """charge_spin forwarding on the density inference and dp test paths.""" + + @classmethod + def setUpClass(cls) -> None: + cls.tmpdir = tempfile.TemporaryDirectory() + root = Path(cls.tmpdir.name) + rng = np.random.default_rng(7) + cls.nframes, natoms, cls.ngrid = 4, 5, 8 + cls.system = root / "system" + set_dir = cls.system / "set.000" + set_dir.mkdir(parents=True) + np.save(set_dir / "coord.npy", rng.random((cls.nframes, natoms * 3)) * 8.0) + np.save( + set_dir / "box.npy", + np.tile(np.eye(3).reshape(-1) * 10.0, (cls.nframes, 1)), + ) + np.save(set_dir / "grid.npy", rng.random((cls.nframes, cls.ngrid, 3)) * 8.0) + np.save(set_dir / "density.npy", rng.random((cls.nframes, cls.ngrid, 1))) + # non-default charge/spin conditions, so forwarding has a visible effect + np.save(set_dir / "charge_spin.npy", np.tile([2.0, 1.0], (cls.nframes, 1))) + np.savetxt(cls.system / "type.raw", [0, 0, 1, 1, 1], fmt="%d") + np.savetxt(cls.system / "type_map.raw", ["O", "H", "X"], fmt="%s") + + model = get_model(deepcopy(model_density_dpa3_chg_spin)) + scripted = torch.jit.script(model) + tmp_fd, cls.model_path = tempfile.mkstemp(suffix=".pth") + os.close(tmp_fd) + torch.jit.save(scripted, cls.model_path) + + @classmethod + def tearDownClass(cls) -> None: + os.unlink(cls.model_path) + cls.tmpdir.cleanup() + + def _inputs(self) -> tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy") + box = np.load(set_dir / "box.npy") + grid = np.load(set_dir / "grid.npy") + atype = np.loadtxt(self.system / "type.raw", dtype=int) + return coord, box, grid, atype + + def test_eval_forwards_charge_spin(self) -> None: + dp = DeepDensity(self.model_path) + self.assertTrue(dp.has_chg_spin_ebd()) + self.assertTrue(dp.has_default_chg_spin()) + coord, box, grid, atype = self._inputs() + # without explicit charge_spin the model falls back to its default + out_default = dp.eval(coord, box, atype, grid=grid) + out_explicit_default = dp.eval( + coord, + box, + atype, + grid=grid, + charge_spin=np.tile([1.0, 0.0], (self.nframes, 1)), + ) + np.testing.assert_allclose( + out_default, out_explicit_default, rtol=1e-6, atol=1e-8 + ) + # a non-default condition must change the prediction: the value has + # to reach the descriptor, not be dropped on the eval path + out_other = dp.eval( + coord, + box, + atype, + grid=grid, + charge_spin=np.tile([2.0, 1.0], (self.nframes, 1)), + ) + self.assertFalse(np.allclose(out_default, out_other)) + + def test_dp_test_forwards_charge_spin(self) -> None: + # the system carries charge_spin.npy: the tester must load and + # forward it, so the details match an explicit eval with those values + detail_file = os.path.join(self.tmpdir.name, "detail_cs") + dp_test( + model=self.model_path, + system=str(self.system), + datafile=None, + numb_test=0, + rand_seed=None, + shuffle_test=False, + detail_file=detail_file, + atomic=False, + ) + coord, box, grid, atype = self._inputs() + dp = DeepDensity(self.model_path) + ref = dp.eval( + coord, + box, + atype, + grid=grid, + charge_spin=np.tile([2.0, 1.0], (self.nframes, 1)), + ) + ref_default = dp.eval(coord, box, atype, grid=grid) + self.assertFalse( + np.allclose(ref, ref_default), + "the test is vacuous: charge_spin has no effect on this model", + ) + for frame in range(self.nframes): + detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) + self.assertEqual(detail.shape, (self.ngrid, 2)) + np.testing.assert_allclose(detail[:, 1], ref[frame], rtol=1e-5, atol=1e-6) + + def test_dp_test_default_chg_spin_without_data(self) -> None: + # no charge_spin file: evaluation must fall back to the model's + # default_chg_spin instead of failing inside the descriptor + system = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "system" + shutil.copytree(self.system, system) + (system / "set.000" / "charge_spin.npy").unlink() + detail_file = os.path.join(self.tmpdir.name, "detail_cs_default") + dp_test( + model=self.model_path, + system=str(system), + datafile=None, + numb_test=0, + rand_seed=None, + shuffle_test=False, + detail_file=detail_file, + atomic=False, + ) + coord, box, grid, atype = self._inputs() + ref = DeepDensity(self.model_path).eval(coord, box, atype, grid=grid) + for frame in range(self.nframes): + detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) + self.assertEqual(detail.shape, (self.ngrid, 2)) + np.testing.assert_allclose(detail[:, 1], ref[frame], rtol=1e-5, atol=1e-6) + if __name__ == "__main__": unittest.main() From e9fb537b8a65bc8f0b3ad5db2ba877202a9d0568 Mon Sep 17 00:00:00 2001 From: Yuzhi Liu Date: Thu, 22 Oct 2026 11:23:38 +0800 Subject: [PATCH 20/23] fix(pt): address density model review feedback --- deepmd/infer/deep_density.py | 44 +- .../atomic_model/density_atomic_model.py | 41 +- deepmd/pt/model/model/make_density_model.py | 4 + deepmd/pt/train/wrapper.py | 2 +- deepmd/utils/data.py | 49 ++- doc/model/train-fitting-density.md | 21 +- examples/density/README.md | 17 +- examples/density/dptest_density_script.py | 85 ++-- .../common/test_deepmd_data_grid_density.py | 75 ++-- source/tests/pt/test_dp_test_density.py | 382 ++++++++++++------ source/tests/pt/test_wrapper.py | 13 +- 11 files changed, 516 insertions(+), 217 deletions(-) diff --git a/deepmd/infer/deep_density.py b/deepmd/infer/deep_density.py index 700f6bc8bb..b1655c45b6 100644 --- a/deepmd/infer/deep_density.py +++ b/deepmd/infer/deep_density.py @@ -66,7 +66,8 @@ def eval( fparam: np.ndarray | None = None, aparam: np.ndarray | None = None, mixed_type: bool = False, - **kwargs: dict[str, Any], + grid_batch_size: int | None = 4096, + **kwargs: Any, ) -> np.ndarray: """Evaluate the density on grid points. @@ -88,6 +89,10 @@ def eval( The atomic parameters, by default None. mixed_type : bool, optional Whether the atom_types is mixed type, by default False. + grid_batch_size : int or None, optional + Maximum number of grid points evaluated in one model call. Grid + chunks are concatenated in their original order. The default is + 4096; set to None to evaluate the full grid in one call. **kwargs : dict[str, Any] Keyword arguments. ``charge_spin`` (nframes, 2) is forwarded to models with charge spin embedding; when omitted, such models use @@ -107,17 +112,30 @@ def eval( nframes, _, ) = self._standard_input(coords, cells, atom_types, fparam, aparam, mixed_type) - results = self.deep_eval.eval( - coords, - cells, - atom_types, - False, - fparam=fparam, - aparam=aparam, - grid=self._standard_grid(grid, nframes), - **kwargs, - ) - return results["density"].reshape(nframes, -1) + grid = self._standard_grid(grid, nframes) + if grid_batch_size is not None and grid_batch_size <= 0: + raise ValueError("grid_batch_size must be positive or None") + if grid_batch_size is None or grid.shape[1] <= grid_batch_size: + grid_slices = (grid,) + else: + grid_slices = tuple( + grid[:, begin : begin + grid_batch_size] + for begin in range(0, grid.shape[1], grid_batch_size) + ) + density_chunks = [] + for grid_chunk in grid_slices: + results = self.deep_eval.eval( + coords, + cells, + atom_types, + False, + fparam=fparam, + aparam=aparam, + grid=grid_chunk, + **kwargs, + ) + density_chunks.append(results["density"].reshape(nframes, -1)) + return np.concatenate(density_chunks, axis=1) @staticmethod def _standard_grid(grid: np.ndarray, nframes: int) -> np.ndarray: @@ -141,6 +159,8 @@ def _standard_grid(grid: np.ndarray, nframes: int) -> np.ndarray: ) if arr.shape[0] != nframes: raise ValueError(f"grid has {arr.shape[0]} frames but coord has {nframes}") + if arr.shape[1] == 0: + raise ValueError("grid must contain at least one point per frame") return arr diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index 1ee7586145..32f8d625ef 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -102,6 +102,19 @@ def forward_atomic( frame parameter. nf x ndf aparam atomic parameter. nf x nloc x nda + comm_dict + Data needed for communication during parallel inference. + grid + Grid coordinates. nf x ngrid x 3. + grid_type + Reserved grid-point types. nf x ngrid. + grid_nlist + Directional grid-to-atom neighbor list. nf x ngrid x nsel. + charge_spin + Frame charge and spin conditions. nf x 2. + return_atomic_feature + Whether atomic features are requested. Density models do not + currently return them. Returns ------- @@ -215,6 +228,14 @@ def forward_common_atomic( atomic parameter, shape: nf x nloc x dim_aparam comm_dict The data needed for communication for parallel inference. + grid + Grid coordinates, shape: nf x ngrid x 3. + grid_type + Reserved grid-point types, shape: nf x ngrid. + grid_nlist + Directional grid-to-atom neighbor list, shape: nf x ngrid x nsel. + charge_spin + Frame charge and spin conditions, shape: nf x 2. Returns ------- @@ -466,8 +487,16 @@ def compute_or_load_stat( dstd = block["dstd"] davg[-1] = grid_davg.to(device=davg.device, dtype=davg.dtype) dstd[-1] = grid_dstd.to(device=dstd.device, dtype=dstd.dtype) - if stat_file_path is not None: + if ( + stat_file_path is not None + and getattr(stat_file_path, "mode", None) != "r" + ): self._write_back_grid_stat(stat_file_path, grid_stats) + elif stat_file_path is not None: + log.warning( + "Grid-type statistics were patched in memory but were not " + "written back because the statistics cache is read-only." + ) def _descriptor_stat_blocks(self) -> list: """Collect every descriptor block that carries davg/dstd statistics. @@ -540,9 +569,13 @@ def _grid_stat_missing(self, stat_file_path: DPPath | None) -> bool: keys = env_stat.get_stat_keys() if not cache.is_dir() or any(not (cache / kk).is_file() for kk in keys): return True - # number of samples of the grid-type row; zero means placeholder - if float((cache / f"r_{grid_type}").load_numpy()[0]) == 0.0: - return True + # Every component of the grid-type row must carry samples. In + # particular, a valid radial row must not hide a placeholder + # angular row left by an interrupted or legacy cache update. + suffix = f"_{grid_type}" + for key in keys: + if key.endswith(suffix) and float((cache / key).load_numpy()[0]) == 0.0: + return True return False def _write_back_grid_stat( diff --git a/deepmd/pt/model/model/make_density_model.py b/deepmd/pt/model/model/make_density_model.py index 14b21965a4..e2b4c4ee08 100644 --- a/deepmd/pt/model/model/make_density_model.py +++ b/deepmd/pt/model/model/make_density_model.py @@ -109,6 +109,8 @@ def forward_common( ) del coord, grid, box, fparam, aparam gg = gg.view(gg.shape[0], -1, 3) + if gg.shape[1] == 0: + raise ValueError("grid must contain at least one point per frame") if bb is not None: # wrap grid points into the primary cell: the atomic # coordinates are normalized and extended with ghosts, so @@ -235,6 +237,8 @@ def forward_common_lower( assert grid is not None assert grid_type is not None assert grid_nlist is not None + if grid.shape[1] == 0: + raise ValueError("grid must contain at least one point per frame") cc_ext, gg, _, fp, ap, input_prec = self._input_type_cast( extended_coord, grid=grid, fparam=fparam, aparam=aparam ) diff --git a/deepmd/pt/train/wrapper.py b/deepmd/pt/train/wrapper.py index b543b559fa..7d7308b0e9 100644 --- a/deepmd/pt/train/wrapper.py +++ b/deepmd/pt/train/wrapper.py @@ -163,7 +163,6 @@ def forward( coord: torch.Tensor, atype: torch.Tensor, spin: torch.Tensor | None = None, - grid: torch.Tensor | None = None, box: torch.Tensor | None = None, cur_lr: torch.Tensor | None = None, label: torch.Tensor | None = None, @@ -173,6 +172,7 @@ def forward( fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, charge_spin: torch.Tensor | None = None, + grid: torch.Tensor | None = None, ) -> tuple[Any, Any, Any]: if not self.multi_task: task_key = "Default" diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index cb5fb6f4bd..7b244dffd3 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -496,16 +496,19 @@ def iter_test( chunk_atoms: int, numb_test: float = float("inf"), ) -> Iterator[dict]: - """Yield the test data in chunks of at most ``chunk_atoms`` atoms. + """Yield test data in chunks bounded by ``chunk_atoms`` work units. The complete test system is materialized first, so chunking here bounds the evaluation batch and its predictions rather than source-data memory. + For ordinary systems one frame costs ``natoms`` work units. For + frame-major data such as density grids, the largest point extent also + contributes so grids with many more points than atoms remain bounded. Parameters ---------- chunk_atoms : int - Upper bound on the number of atoms per chunk. A chunk always - carries at least one frame, however many atoms it has. + Upper bound on the per-chunk work proxy. A chunk always carries at + least one frame, however many atoms or frame-major points it has. numb_test : float, optional Upper bound on the number of frames served. A non-finite bound serves the whole test set. @@ -520,7 +523,17 @@ def iter_test( total = int(self.test_set["type"].shape[0]) if np.isfinite(numb_test): total = min(total, int(numb_test)) - step = max(1, int(chunk_atoms) // max(1, self.natoms)) + frame_size = self.natoms + for key, requirement in self.data_dict.items(): + if requirement.get("special_shape") != "frame_major": + continue + value = self.test_set.get(key) + if not isinstance(value, np.ndarray) or value.ndim < 2: + continue + ndof = int(requirement["ndof"]) + extent = int(np.prod(value.shape[1:], dtype=np.int64)) // ndof + frame_size = max(frame_size, extent) + step = max(1, int(chunk_atoms) // max(1, frame_size)) for begin in range(0, total, step): idx = np.arange(begin, min(begin + step, total), dtype=np.int64) chunk = self._get_subdata(self.test_set, idx=idx) @@ -1091,10 +1104,11 @@ def _load_data( path = self._get_data_path(set_name, key) if special_shape == "frame_major" and path.is_file(): data = path.load_numpy().astype(dtype) - if data.ndim < 2: + if data.ndim not in (2, 3): raise ValueError( - f"The data {key} in {set_name} must have a leading frame " - f"dimension, but got shape {data.shape}" + f"The frame-major data {key} in {set_name} must have shape " + f"(nframes, npoints * ndof) or (nframes, npoints, ndof), " + f"but got {data.shape}" ) if data.shape[0] != nframes: raise ValueError( @@ -1116,6 +1130,12 @@ def _load_data( f"{data.shape[-1]}, which is not a multiple of the " f"declared ndof {ndof_}" ) + npoints = data.shape[1] if data.ndim == 3 else data.shape[1] // ndof_ + if npoints == 0: + raise ValueError( + f"The frame-major data {key} in {set_name} must contain " + "at least one point per frame" + ) return np.float32(1.0), data if path.is_file(): data = path.load_numpy().astype(dtype) @@ -1277,10 +1297,11 @@ def _load_single_data( # Validate frame-major layout before indexing, so that shuffling # cannot pair a structure with another frame's grid or density label. if vv.get("special_shape") == "frame_major": - if mmap_obj.ndim < 2: + if mmap_obj.ndim not in (2, 3): raise ValueError( - f"The data {key} in {set_dir} must have a leading frame " - f"dimension, but got shape {mmap_obj.shape}" + f"The frame-major data {key} in {set_dir} must have shape " + f"(nframes, npoints * ndof) or (nframes, npoints, ndof), " + f"but got {mmap_obj.shape}" ) if mmap_obj.shape[0] != set_nframes: raise ValueError( @@ -1301,6 +1322,14 @@ def _load_single_data( f"{mmap_obj.shape[-1]}, which is not a multiple of the " f"declared ndof {ndof}" ) + npoints = ( + mmap_obj.shape[1] if mmap_obj.ndim == 3 else mmap_obj.shape[1] // ndof + ) + if npoints == 0: + raise ValueError( + f"The frame-major data {key} in {set_dir} must contain " + "at least one point per frame" + ) # corner case: single frame. frame-major arrays always carry a # leading frame dimension (validated above), so no expansion is needed. diff --git a/doc/model/train-fitting-density.md b/doc/model/train-fitting-density.md index 56501a93f8..10fd86a2f1 100644 --- a/doc/model/train-fitting-density.md +++ b/doc/model/train-fitting-density.md @@ -28,6 +28,12 @@ The training/validation data follows the standard `deepmd/npy` format, with two The number of grid points `ngrid` may differ from the number of atoms. The last entry of `type_map` is reserved as a virtual "grid point type": internally, grid points are assigned this type when building the grid-to-atom neighbor list, so `type_map` must contain one more entry than the real element types. For descriptors with a per-type `sel` list (e.g. `se_e2_a`), set its last entry to 0, since grid points are only centers, never neighbors. +Every frame in one system must use the same positive `ngrid`; empty grids are +rejected. Python inference evaluates large grids in chunks of 4096 points by +default, which bounds the temporary directional-neighbor matrix. Pass +`grid_batch_size=None` to `DeepDensity.eval` only when evaluating the complete +grid in one call is known to fit in memory. + It is recommended to set a positive `env_protection` in the descriptor configuration (e.g. `"env_protection": 0.1`). Grid points may legitimately coincide with atoms, and the default `env_protection = 0.0` would let the `1/r` terms in the environment matrix produce `NaN` densities. If `env_protection` is not set for a density model, it is automatically set to `1e-6` with a warning. ## The fitting network @@ -61,7 +67,12 @@ The grid density model is trained with the `grid_density` loss, which minimises ``` - {ref}`type ` should be written as `grid_density`. -- `start_pref_d` and `limit_pref_d` specify the weight of the density loss at the start and at the end of the training. If both are set to 0, the density term is skipped (and the graph is kept connected). Note that `density.npy` is **required** in every training and validation system — it is the model's only supervision signal, and a missing file aborts training at load time. +- `start_pref_d` and `limit_pref_d` specify the weight of the density loss at the start and at the end of the training. If both are set to 0, the density term is skipped (and the graph is kept connected). When either prefactor is nonzero, `density.npy` is **required** in every training and validation system; when both are zero, the file is optional. + +The loss gives every grid point equal weight. Non-uniform quadrature weights, +integrated-charge constraints, and output non-negativity are not imposed by +this fitting type; datasets that need those properties must account for them +in their sampling or preprocessing. ## Evaluation @@ -71,5 +82,11 @@ The grid density model is trained with the `grid_density` loss, which minimises from deepmd.infer import DeepEval dp = DeepEval("model.pth") -density = dp.eval(coord, box, atype, grid=grid) # (nframes, ngrid) +density = dp.eval( + coord, + box, + atype, + grid=grid, + grid_batch_size=4096, +) # (nframes, ngrid) ``` diff --git a/examples/density/README.md b/examples/density/README.md index 144f419fd9..4808a135c4 100644 --- a/examples/density/README.md +++ b/examples/density/README.md @@ -32,14 +32,15 @@ The training/validation data follows the standard **`deepmd/npy`** format, with | `coord.npy` | `[nframes, natoms * 3]` | Atomic coordinates | | `box.npy` | `[nframes, 9]` | Simulation cell vectors | | `type.raw` | `[natoms]` | Atom type indices | -| `type_map.raw` | `[ntypes]` | Type map (e.g., `C H N O ... X`) | +| `type_map.raw` | `[ntypes]` | Real element types in this dataset | | **`grid.npy`** | `[nframes, ngrid, 3]` | **Grid point coordinates** | | **`density.npy`** | `[nframes, ngrid, 1]` | **Charge density labels on grids** | > **Notes:** > > - `grid.npy` and `density.npy` are required for the density model. The number of grid points (`ngrid`) must match between `grid.npy` and `density.npy`, and is allowed to differ from `natoms`. -> - The **last entry of `type_map` is reserved as a virtual "grid point type"** (e.g. `X` in the example): internally, grid points are assigned this type when building the grid-to-atom neighbor list. Make sure your `type_map` contains one more entry than the real element types. For descriptors with a per-type `sel` list (e.g. `se_e2_a`), set its **last entry to 0** (grid points are only centers, never neighbors); scalar `sel` descriptors such as DPA-2/DPA-3 need no change. The descriptor input statistics for the grid type are computed from the actual `grid.npy` data during training initialization. +> - The **last entry of the model configuration's `type_map` is reserved as a virtual "grid point type"** (e.g. `X` in the example): internally, grid points are assigned this type when building the grid-to-atom neighbor list. Make sure the model `type_map` contains one more entry than the real element types. `type_map.raw` may list only the real types actually present in that dataset, as the bundled example does. For descriptors with a per-type `sel` list (e.g. `se_e2_a`), set its **last entry to 0** (grid points are only centers, never neighbors); scalar `sel` descriptors such as DPA-2/DPA-3 need no change. The descriptor input statistics for the grid type are computed from the actual `grid.npy` data during training initialization. +> - Every frame in one system must contain the same positive number of grid points. Python inference chunks large grids into groups of 4096 points by default to limit temporary neighbor-list memory. > - **Always set a positive `env_protection`** in the descriptor configuration (e.g. `"env_protection": 0.1`, as in `dpa3/input.json`). Grid points may legitimately coincide with atoms, and the default `env_protection = 0.0` would let the `1/r` terms in the environment matrix produce `NaN` densities and poison the training gradients at such points. ______________________________________________________________________ @@ -187,7 +188,9 @@ python dptest_density_script.py \ | `--output` | If provided, save screen output to this file as well | | `--pred-file` | File to save paired `[prediction, label]` array (default: `result.d.out`) | -> **Note:** The script registers the `grid`/`density` dpdata types with a hard-coded grid count (`125`, matching this example). If your dataset uses a different `ngrid`, edit the `shape=(Axis.NFRAMES, 125, ...)` lines at the top of the script. +> **Note:** Each individual system must use one fixed `ngrid`, but different +> systems discovered by the script may use different grid extents. Large grids +> are evaluated in chunks by the Python inference interface. ### Option 3: Python interface @@ -196,7 +199,13 @@ import numpy as np from deepmd.infer import DeepEval dp = DeepEval("frozen_model.pth") # dispatched to DeepDensity automatically -density = dp.eval(coord, box, atype, grid=grid) # (nframes, ngrid) +density = dp.eval( + coord, + box, + atype, + grid=grid, + grid_batch_size=4096, +) # (nframes, ngrid) ``` ______________________________________________________________________ diff --git a/examples/density/dptest_density_script.py b/examples/density/dptest_density_script.py index ff4bdf8472..9dfc2d7351 100644 --- a/examples/density/dptest_density_script.py +++ b/examples/density/dptest_density_script.py @@ -14,35 +14,14 @@ import random import sys -import dpdata import numpy as np -from dpdata.data_type import ( - Axis, - DataType, -) -from tqdm import ( - tqdm, -) from deepmd.infer import ( DeepEval, ) - -# Register custom dpdata types for grid density -_GRID_DATA_TYPE = DataType( - "grid", - np.ndarray, - shape=(Axis.NFRAMES, 125, 3), - required=False, -) -_DENSITY_DATA_TYPE = DataType( - "density", - np.ndarray, - shape=(Axis.NFRAMES, 125, 1), - required=False, +from deepmd.utils.data import ( + DeepmdData, ) -dpdata.System.register_data_type(_GRID_DATA_TYPE) -dpdata.System.register_data_type(_DENSITY_DATA_TYPE) def parse_args() -> argparse.Namespace: @@ -98,6 +77,8 @@ def evaluate( model_path: str, data_dir: str, ratio: float ) -> tuple[np.ndarray, np.ndarray]: """Run inference and return (predictions, labels).""" + if not 0.0 < ratio <= 1.0: + raise ValueError(f"ratio must be in (0, 1], got {ratio}") # DeepEval dispatches density models to DeepDensity automatically. dm = DeepEval(model_path) type_map = dm.get_type_map() @@ -109,26 +90,52 @@ def evaluate( if not systems: raise RuntimeError(f"No deepmd/npy systems found under '{data_dir}'") - for f in tqdm(systems, desc="Systems"): + for f in systems: sys_name = os.path.dirname(f) - s = dpdata.System(sys_name, fmt="deepmd/npy", type_map=type_map) - - n_frames = len(s) + data = DeepmdData(sys_name, type_map=type_map) + data.add( + "grid", + 3, + atomic=False, + must=True, + high_prec=True, + special_shape="frame_major", + ) + data.add( + "density", + 1, + atomic=False, + must=True, + high_prec=True, + special_shape="frame_major", + ) + test_data = data.get_test() + + n_frames = test_data["coord"].shape[0] n_sample = max(1, math.floor(n_frames * ratio)) indices = random.sample(range(n_frames), n_sample) - s = s.sub_system(indices) - - coord = s.data["coords"].reshape(len(s), -1) - atype = list(s.data["atom_types"]) - cell = s.data["cells"].reshape(len(s), -1) - # DeepDensity.eval accepts only the (nframes, ngrid, 3) layout - grid = s.data["grid"].reshape(len(s), -1, 3) - - density_pred = dm.eval(coord, cell, atype, grid=grid) - density_label = s.data["density"].reshape(len(s), -1) - pred_list.append(density_pred) - label_list.append(density_label) + coord = test_data["coord"][indices].reshape(n_sample, -1) + if data.mixed_type: + atype = test_data["type"][indices].reshape(n_sample, -1) + else: + atype = test_data["type"][0] + cell = test_data["box"][indices] if data.pbc else None + grid = test_data["grid"][indices].reshape(n_sample, -1, 3) + + density_pred = dm.eval( + coord, + cell, + atype, + grid=grid, + mixed_type=data.mixed_type, + ) + density_label = test_data["density"][indices].reshape(n_sample, -1) + + # Flatten each system before concatenating so systems may carry + # different grid extents. + pred_list.append(density_pred.reshape(-1)) + label_list.append(density_label.reshape(-1)) sys.stdout.write(f" {sys_name:60s} frames={n_sample}/{n_frames}" + "\n") predictions = np.concatenate(pred_list) diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py index b0c6c2bce4..2af6404cab 100644 --- a/source/tests/common/test_deepmd_data_grid_density.py +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -88,6 +88,11 @@ def test_load_set_frame_major(self) -> None: self.assertEqual(loaded["grid"].shape, (NFRAMES, NGRID, 3)) self.assertEqual(loaded["density"].shape, (NFRAMES, NGRID, 1)) + def test_iter_test_uses_frame_major_extent_for_chunking(self) -> None: + data = self.build_data() + chunks = list(data.iter_test(chunk_atoms=NGRID * 2)) + self.assertEqual([chunk["box"].shape[0] for chunk in chunks], [2, 2]) + def test_single_frame(self) -> None: data = self.build_data() frame = data.get_single_frame(0, 0) @@ -96,27 +101,29 @@ def test_single_frame(self) -> None: self.assertEqual(frame["grid"].shape, (NGRID, 3)) self.assertEqual(frame["density"].shape, (NGRID, 1)) - def test_frame_count_mismatch_load_set(self) -> None: + def test_frame_count_mismatch(self) -> None: self.set_data("grid", np.zeros((NFRAMES - 1, NGRID, 3), dtype=np.float32)) - with self.assertRaisesRegex(ValueError, "frame count"): - self.build_data()._load_set(self.set_dir) - - def test_frame_count_mismatch_single_frame(self) -> None: - self.set_data("density", np.zeros((NFRAMES - 1, NGRID, 1), dtype=np.float32)) - with self.assertRaisesRegex(ValueError, "frame count"): - self.build_data().get_single_frame(0, 0) - - def test_missing_frame_dimension_load_set(self) -> None: + loaders = { + "set": lambda data: data._load_set(self.set_dir), + "single frame": lambda data: data.get_single_frame(0, 0), + } + for name, load in loaders.items(): + with self.subTest(loader=name): + with self.assertRaisesRegex(ValueError, "frame count"): + load(self.build_data()) + + def test_missing_frame_dimension(self) -> None: # stored without a leading frame dimension: rejected rather than # silently misaligned with the frames self.set_data("grid", np.zeros((NGRID, 3), dtype=np.float32)) - with self.assertRaisesRegex(ValueError, r"frame count|leading frame"): - self.build_data()._load_set(self.set_dir) - - def test_missing_frame_dimension_single_frame(self) -> None: - self.set_data("density", np.zeros((NGRID, 1), dtype=np.float32)) - with self.assertRaisesRegex(ValueError, r"frame count|leading frame"): - self.build_data().get_single_frame(0, 0) + loaders = { + "set": lambda data: data._load_set(self.set_dir), + "single frame": lambda data: data.get_single_frame(0, 0), + } + for name, load in loaders.items(): + with self.subTest(loader=name): + with self.assertRaisesRegex(ValueError, r"frame count|leading frame"): + load(self.build_data()) def test_missing_file_optional(self) -> None: # optional labels absent: the loader must not fail and must signal @@ -128,20 +135,26 @@ def test_missing_file_optional(self) -> None: frame = data.get_single_frame(0, 0) self.assertEqual(frame["find_density"], 0.0) - def test_ndof_mismatch(self) -> None: - # 3D layout: trailing dim must be exactly ndof (a divisible-but-wrong - # width like 6 would silently double ngrid downstream) - for width in (4, 6): - self.set_data("grid", np.zeros((NFRAMES, NGRID, width), dtype=np.float32)) - with self.assertRaisesRegex(ValueError, "ndof"): - self.build_data()._load_set(self.set_dir) - with self.assertRaisesRegex(ValueError, "ndof"): - self.build_data().get_single_frame(0, 0) - # flattened layout: width must be a multiple of ndof - self.set_data("grid", np.zeros((NFRAMES, NGRID * 3 + 1), dtype=np.float32)) - with self.assertRaisesRegex(ValueError, "ndof"): - self.build_data()._load_set(self.set_dir) - # correct flattened layout passes + def test_invalid_frame_major_layout(self) -> None: + invalid = ( + ("wrong trailing width", (NFRAMES, NGRID, 4), "ndof"), + ("divisible wrong width", (NFRAMES, NGRID, 6), "ndof"), + ("invalid flattened width", (NFRAMES, NGRID * 3 + 1), "ndof"), + ("empty", (NFRAMES, 0, 3), "at least one point"), + ("rank four", (NFRAMES, 1, NGRID, 3), "must have shape"), + ) + loaders = { + "set": lambda data: data._load_set(self.set_dir), + "single frame": lambda data: data.get_single_frame(0, 0), + } + for case, shape, message in invalid: + self.set_data("grid", np.zeros(shape, dtype=np.float32)) + for loader_name, load in loaders.items(): + with self.subTest(case=case, loader=loader_name): + with self.assertRaisesRegex(ValueError, message): + load(self.build_data()) + + # A correctly flattened frame-major array remains accepted. self.set_data("grid", np.zeros((NFRAMES, NGRID * 3), dtype=np.float32)) loaded = self.build_data()._load_set(self.set_dir) self.assertEqual(loaded["find_grid"], 1.0) diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index adf87d7be5..58dd4aa60e 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -10,6 +10,9 @@ from pathlib import ( Path, ) +from unittest.mock import ( + patch, +) import numpy as np import torch @@ -21,6 +24,9 @@ from deepmd.infer.deep_eval import ( DeepEval, ) +from deepmd.infer.model_test import ( + build_tester, +) from deepmd.pt.entrypoints.main import ( get_trainer, ) @@ -48,9 +54,16 @@ from deepmd.utils.argcheck import ( normalize, ) +from deepmd.utils.data import ( + DeepmdData, +) from deepmd.utils.path import ( DPPath, ) +from deepmd.utils.stat_file import ( + StatFileSpec, + open_stat_file, +) model_density = { # the last entry is the reserved grid point type; its sel is 0 because @@ -230,10 +243,6 @@ def test_property_named_density_dispatches_to_property(self) -> None: finally: os.unlink(path) - def test_model_type_dispatch(self) -> None: - dp = DeepEval(self.model_path) - self.assertIsInstance(dp, DeepDensity) - def _run_training(self, config: dict, workdir: str) -> None: """Run a few real training steps (checkpoints land in workdir).""" cwd = os.getcwd() @@ -270,15 +279,25 @@ def test_eval_single_frame_grid_2d(self) -> None: out = dp.eval(coord, box, atype, grid=grid) self.assertEqual(out.shape, (1, self.ngrid)) - def test_eval_grid_frame_mismatch(self) -> None: + def test_eval_rejects_invalid_grid_inputs(self) -> None: dp = DeepDensity(self.model_path) set_dir = self.system / "set.000" coord = np.load(set_dir / "coord.npy")[:2] box = np.load(set_dir / "box.npy")[:2] - grid = np.load(set_dir / "grid.npy")[:1] # fewer frames than coord + grid = np.load(set_dir / "grid.npy")[:2] atype = np.loadtxt(self.system / "type.raw", dtype=int) - with self.assertRaisesRegex(ValueError, "frames"): - dp.eval(coord, box, atype, grid=grid) + invalid = ( + ("frame mismatch", grid[:1], {}, "frames"), + ("ambiguous rank two", grid[0], {}, "ambiguous"), + ("wrong coordinate width", np.zeros((2, self.ngrid, 2)), {}, "shape"), + ("rank four", np.zeros((2, self.ngrid, 3, 1)), {}, "shape"), + ("empty", np.zeros((2, 0, 3)), {}, "at least one point"), + ("invalid batch size", grid, {"grid_batch_size": 0}, "grid_batch_size"), + ) + for case, invalid_grid, kwargs, message in invalid: + with self.subTest(case=case): + with self.assertRaisesRegex(ValueError, message): + dp.eval(coord, box, atype, grid=invalid_grid, **kwargs) def test_fitting_rejects_aparam(self) -> None: # grid descriptor rows have no per-atom parameters @@ -299,6 +318,9 @@ def test_fitting_model_serialization_roundtrip(self) -> None: from deepmd.pt.model.model.model import ( BaseModel, ) + from deepmd.pt.loss.charge import ( + GridDensityLoss, + ) fitting = self.torch_model.atomic_model.fitting_net restored_fit = DensityFittingNet.deserialize(fitting.serialize()) @@ -308,6 +330,14 @@ def test_fitting_model_serialization_roundtrip(self) -> None: self.assertIsInstance(restored_model, GridDensityModel) self._assert_state_dict_equal(model, restored_model) + loss_fn = GridDensityLoss( + starter_learning_rate=0.001, start_pref_d=2.0, limit_pref_d=0.5 + ) + data = loss_fn.serialize() + self.assertEqual(data["@class"], "GridDensityLoss") + restored_loss = GridDensityLoss.deserialize(data) + self.assertEqual(restored_loss.serialize(), data) + def _assert_state_dict_equal( self, module0: torch.nn.Module, module1: torch.nn.Module ) -> None: @@ -317,20 +347,6 @@ def _assert_state_dict_equal( for key in sd0: torch.testing.assert_close(sd0[key], sd1[key]) - def test_loss_serialization(self) -> None: - # GridDensityLoss round-trips through serialize/deserialize - from deepmd.pt.loss.charge import ( - GridDensityLoss, - ) - - loss_fn = GridDensityLoss( - starter_learning_rate=0.001, start_pref_d=2.0, limit_pref_d=0.5 - ) - data = loss_fn.serialize() - self.assertEqual(data["@class"], "GridDensityLoss") - restored = GridDensityLoss.deserialize(data) - self.assertEqual(restored.serialize(), data) - def test_loss_inference_mode(self) -> None: # inference=True reports the metrics even with zero prefactors from deepmd.pt.loss.charge import ( @@ -470,39 +486,32 @@ def test_env_protection_enforced_at_model_level(self) -> None: model = DPDensityAtomicModel(descriptor, fitting, type_map=["O", "H", "X"]) self.assertEqual(model.descriptor.get_env_protection(), 1e-6) - def test_env_protection_hybrid(self) -> None: - # hybrid descriptors have no top-level env_protection: the default - # must reach every sub-descriptor - config = deepcopy(self.config) - descriptor = config["model"].pop("descriptor") - # the sub-descriptor must not carry an explicit value: the asserted - # 1e-6 has to be an effect of the default, not of the input config - descriptor.pop("env_protection", None) - config["model"]["descriptor"] = {"type": "hybrid", "list": [descriptor]} - normalized = normalize(config) - self.assertEqual( - normalized["model"]["descriptor"]["list"][0]["env_protection"], - 1e-6, - ) - - def test_env_protection_hybrid_common_explicit_value(self) -> None: - # a hybrid requires every sub-descriptor to share one env_protection; - # an omitted entry must take the siblings' explicit value, not 1e-6, - # or the model build would reject the mixed list - config = deepcopy(self.config) - descriptor = config["model"].pop("descriptor") - descriptor.pop("env_protection", None) - explicit = deepcopy(descriptor) - explicit["env_protection"] = 0.1 - config["model"]["descriptor"] = { - "type": "hybrid", - "list": [explicit, descriptor], - } - normalized = normalize(config) - values = [ - sub["env_protection"] for sub in normalized["model"]["descriptor"]["list"] - ] - self.assertEqual(values, [0.1, 0.1]) + def test_env_protection_hybrid_defaults(self) -> None: + cases = ( + ("all omitted", [None], [1e-6]), + ("shared explicit value", [0.1, None], [0.1, 0.1]), + ) + for case, values, expected in cases: + config = deepcopy(self.config) + base = config["model"].pop("descriptor") + descriptors = [] + for value in values: + descriptor = deepcopy(base) + descriptor.pop("env_protection", None) + if value is not None: + descriptor["env_protection"] = value + descriptors.append(descriptor) + config["model"]["descriptor"] = { + "type": "hybrid", + "list": descriptors, + } + with self.subTest(case=case): + normalized = normalize(config) + actual = [ + sub["env_protection"] + for sub in normalized["model"]["descriptor"]["list"] + ] + self.assertEqual(actual, expected) def test_injected_pass_honors_pair_exclude_types(self) -> None: # the injected stat pass must see the model's pair_exclude_types, @@ -567,6 +576,53 @@ def boom(_sampled: list) -> list: finally: atomic_model._inject_grid_samples = original_inject # type: ignore[method-assign] + def test_stat_cache_rejects_zero_sample_angular_grid_row(self) -> None: + stat_dir = DPPath(tempfile.mkdtemp(dir=self.tmpdir.name), "w") + atomic_model = self.torch_model.atomic_model + + def sampler() -> list: + return [dict(self.input_dict)] + + atomic_model.compute_or_load_stat(sampler, stat_file_path=stat_dir) + grid_type = len(self.config["model"]["type_map"]) - 1 + angular_rows = list(stat_dir.rglob(f"a_{grid_type}")) + self.assertTrue(angular_rows, "no angular grid-type statistic in cache") + for path in angular_rows: + value = path.load_numpy() + value[0] = 0.0 + path.save_numpy(value) + + self.assertTrue(atomic_model._grid_stat_missing(stat_dir)) + + def test_read_only_stat_cache_patches_grid_row_in_memory(self) -> None: + # Older complete caches can contain a zero-sample placeholder for the + # reserved grid type. Read mode may patch that row in memory, but must + # never attempt the write-back that update mode performs. + stat_file = Path(self.tmpdir.name) / "density-stat.hdf5" + model = get_model(deepcopy(model_density)) + atomic_model = model.atomic_model + + def sampler() -> list: + return [dict(self.input_dict)] + + with open_stat_file(StatFileSpec(str(stat_file))) as update_path: + self.assertIsNotNone(update_path) + # The parent pass writes a complete cache with the ordinary + # zero-sample placeholder for the reserved grid type. + super(DPDensityAtomicModel, atomic_model).compute_or_load_stat( + sampler, update_path + ) + original = stat_file.read_bytes() + + with open_stat_file(StatFileSpec(str(stat_file), "read")) as read_path: + self.assertIsNotNone(read_path) + with self.assertLogs( + "deepmd.pt.model.atomic_model.density_atomic_model", level="WARNING" + ) as logs: + atomic_model.compute_or_load_stat(sampler, read_path) + self.assertIn("read-only", "\n".join(logs.output)) + self.assertEqual(stat_file.read_bytes(), original) + def test_grid_type_statistics(self) -> None: # the reserved grid type X gets real input statistics from the # injected grid samples, not the descriptor's placeholder defaults @@ -638,16 +694,6 @@ def test_grid_type_statistics_dpa2(self) -> None: f"grid type still has placeholder statistics: {dstd[-1]}", ) - def test_eval_shape(self) -> None: - dp = DeepDensity(self.model_path) - set_dir = self.system / "set.000" - coord = np.load(set_dir / "coord.npy")[:2] - box = np.load(set_dir / "box.npy")[:2] - grid = np.load(set_dir / "grid.npy")[:2] - atype = np.loadtxt(self.system / "type.raw", dtype=int) - out = dp.eval(coord, box, atype, grid=grid) - self.assertEqual(out.shape, (2, self.ngrid)) - def test_eval_requires_grid(self) -> None: # evaluating a density model without grid must fail with a clear # error instead of a bare KeyError on the output name table @@ -719,11 +765,73 @@ def test_grid_periodic_translation(self) -> None: out_shift = dp.eval(coord, box, atype, grid=grid + 2.0 * cell_vec[:, None, :]) np.testing.assert_allclose(out_shift, out, rtol=1e-5, atol=1e-5) - def test_dp_test(self) -> None: - detail_file = os.path.join(self.tmpdir.name, "detail") + def test_dp_test_without_detail_file(self) -> None: + dp = DeepDensity(self.model_path) + data = DeepmdData( + str(self.system), + set_prefix="set", + shuffle_test=False, + type_map=dp.get_type_map(), + sort_atoms=False, + ) + errors = build_tester(dp, atomic=False).run( + data, + str(self.system), + numb_test=self.nframes, + detail_file=None, + ) + self.assertEqual(set(errors), {"mae_density", "rmse_density"}) + + def test_dp_test_chunking_matches_whole_run(self) -> None: + def run(chunk_size: int, detail_file: str) -> dict: + dp = DeepDensity(self.model_path) + data = DeepmdData( + str(self.system), + set_prefix="set", + shuffle_test=False, + type_map=dp.get_type_map(), + sort_atoms=False, + ) + with patch.dict( + os.environ, {"DP_TEST_CHUNK_ATOMS": str(chunk_size)}, clear=False + ): + return build_tester(dp, atomic=False).run( + data, + str(self.system), + numb_test=self.nframes, + detail_file=detail_file, + ) + + whole_detail = os.path.join(self.tmpdir.name, "detail_whole") + chunk_detail = os.path.join(self.tmpdir.name, "detail_chunk") + whole = run(1_000_000, whole_detail) + chunked = run(self.ngrid, chunk_detail) + self.assertEqual(whole.keys(), chunked.keys()) + for key in whole: + np.testing.assert_allclose(whole[key], chunked[key]) + for frame in range(self.nframes): + np.testing.assert_allclose( + np.loadtxt(f"{whole_detail}.density.out.{frame}"), + np.loadtxt(f"{chunk_detail}.density.out.{frame}"), + ) + + def test_dp_test_mixed_type(self) -> None: + system = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "mixed-system" + shutil.copytree(self.system, system) + atom_types = np.array( + [ + [0, 0, 1, 1, 1], + [0, 1, 0, 1, 1], + [1, 0, 0, 1, 1], + [1, 1, 0, 0, 1], + ], + dtype=np.int32, + ) + np.save(system / "set.000" / "real_atom_types.npy", atom_types) + detail_file = os.path.join(self.tmpdir.name, "detail_mixed") dp_test( model=self.model_path, - system=str(self.system), + system=str(system), datafile=None, numb_test=0, rand_seed=None, @@ -731,10 +839,61 @@ def test_dp_test(self) -> None: detail_file=detail_file, atomic=False, ) - # one detail file per frame, each holding ngrid [label, pred] pairs + set_dir = system / "set.000" + ref = DeepDensity(self.model_path).eval( + np.load(set_dir / "coord.npy"), + np.load(set_dir / "box.npy"), + atom_types, + grid=np.load(set_dir / "grid.npy"), + mixed_type=True, + ) for frame in range(self.nframes): detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) - self.assertEqual(detail.shape, (self.ngrid, 2)) + np.testing.assert_allclose(detail[:, 1], ref[frame], rtol=1e-5, atol=1e-6) + + def test_dp_test_forwards_fparam(self) -> None: + params = deepcopy(model_density) + params["fitting_net"]["numb_fparam"] = 1 + model = get_model(params) + fd, model_path = tempfile.mkstemp(suffix=".pth") + os.close(fd) + system = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "fparam-system" + shutil.copytree(self.system, system) + fparam = np.arange(1, self.nframes + 1, dtype=np.float64).reshape(-1, 1) + np.save(system / "set.000" / "fparam.npy", fparam) + try: + torch.jit.save(torch.jit.script(model), model_path) + detail_file = os.path.join(self.tmpdir.name, "detail_fparam") + dp_test( + model=model_path, + system=str(system), + datafile=None, + numb_test=0, + rand_seed=None, + shuffle_test=False, + detail_file=detail_file, + atomic=False, + ) + set_dir = system / "set.000" + dp = DeepDensity(model_path) + args = ( + np.load(set_dir / "coord.npy"), + np.load(set_dir / "box.npy"), + np.loadtxt(system / "type.raw", dtype=int), + ) + grid = np.load(set_dir / "grid.npy") + ref = dp.eval(*args, grid=grid, fparam=fparam) + without_fparam_effect = dp.eval( + *args, grid=grid, fparam=np.zeros_like(fparam) + ) + self.assertFalse(np.allclose(ref, without_fparam_effect)) + for frame in range(self.nframes): + detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) + np.testing.assert_allclose( + detail[:, 1], ref[frame], rtol=1e-5, atol=1e-6 + ) + finally: + os.unlink(model_path) def test_dp_test_shuffle(self) -> None: # grid/density must be shuffled together with the frames: every @@ -908,62 +1067,59 @@ def test_eval_forwards_charge_spin(self) -> None: ) self.assertFalse(np.allclose(out_default, out_other)) - def test_dp_test_forwards_charge_spin(self) -> None: - # the system carries charge_spin.npy: the tester must load and - # forward it, so the details match an explicit eval with those values - detail_file = os.path.join(self.tmpdir.name, "detail_cs") - dp_test( - model=self.model_path, - system=str(self.system), - datafile=None, - numb_test=0, - rand_seed=None, - shuffle_test=False, - detail_file=detail_file, - atomic=False, - ) + def test_eval_grid_chunking_dpa3_matches_full_grid(self) -> None: coord, box, grid, atype = self._inputs() dp = DeepDensity(self.model_path) - ref = dp.eval( + + full = dp.eval(coord, box, atype, grid=grid, grid_batch_size=None) + chunked = dp.eval(coord, box, atype, grid=grid, grid_batch_size=3) + + np.testing.assert_allclose(chunked, full, rtol=1e-6, atol=1e-8) + + def test_dp_test_charge_spin_data_and_default(self) -> None: + coord, box, grid, atype = self._inputs() + dp = DeepDensity(self.model_path) + explicit_ref = dp.eval( coord, box, atype, grid=grid, charge_spin=np.tile([2.0, 1.0], (self.nframes, 1)), ) - ref_default = dp.eval(coord, box, atype, grid=grid) + default_ref = dp.eval(coord, box, atype, grid=grid) self.assertFalse( - np.allclose(ref, ref_default), + np.allclose(explicit_ref, default_ref), "the test is vacuous: charge_spin has no effect on this model", ) - for frame in range(self.nframes): - detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) - self.assertEqual(detail.shape, (self.ngrid, 2)) - np.testing.assert_allclose(detail[:, 1], ref[frame], rtol=1e-5, atol=1e-6) - def test_dp_test_default_chg_spin_without_data(self) -> None: - # no charge_spin file: evaluation must fall back to the model's - # default_chg_spin instead of failing inside the descriptor - system = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "system" - shutil.copytree(self.system, system) - (system / "set.000" / "charge_spin.npy").unlink() - detail_file = os.path.join(self.tmpdir.name, "detail_cs_default") - dp_test( - model=self.model_path, - system=str(system), - datafile=None, - numb_test=0, - rand_seed=None, - shuffle_test=False, - detail_file=detail_file, - atomic=False, + system_without_data = Path(tempfile.mkdtemp(dir=self.tmpdir.name)) / "system" + shutil.copytree(self.system, system_without_data) + (system_without_data / "set.000" / "charge_spin.npy").unlink() + cases = ( + ("explicit data", self.system, explicit_ref), + ("model default", system_without_data, default_ref), ) - coord, box, grid, atype = self._inputs() - ref = DeepDensity(self.model_path).eval(coord, box, atype, grid=grid) - for frame in range(self.nframes): - detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) - self.assertEqual(detail.shape, (self.ngrid, 2)) - np.testing.assert_allclose(detail[:, 1], ref[frame], rtol=1e-5, atol=1e-6) + for case, system, reference in cases: + detail_file = os.path.join(self.tmpdir.name, f"detail_cs_{case}") + with self.subTest(case=case): + dp_test( + model=self.model_path, + system=str(system), + datafile=None, + numb_test=0, + rand_seed=None, + shuffle_test=False, + detail_file=detail_file, + atomic=False, + ) + for frame in range(self.nframes): + detail = np.loadtxt( + f"{detail_file}.density.out.{frame}", skiprows=1 + ) + self.assertEqual(detail.shape, (self.ngrid, 2)) + np.testing.assert_allclose( + detail[:, 1], reference[frame], rtol=1e-5, atol=1e-6 + ) if __name__ == "__main__": diff --git a/source/tests/pt/test_wrapper.py b/source/tests/pt/test_wrapper.py index 9fd64bdb06..5d74ff7b1b 100644 --- a/source/tests/pt/test_wrapper.py +++ b/source/tests/pt/test_wrapper.py @@ -21,6 +21,7 @@ def __init__(self, *, fail_forward: bool = False) -> None: self.scale = torch.nn.Parameter(torch.ones((), device="cpu")) self.fail_forward = fail_forward self.last_requires_grad: tuple[bool, ...] | None = None + self.last_box: torch.Tensor | None = None def forward( self, @@ -32,7 +33,8 @@ def forward( aparam: torch.Tensor | None = None, charge_spin: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: - del atype, box, do_atomic_virial, fparam, aparam, charge_spin + del atype, do_atomic_virial, fparam, aparam, charge_spin + self.last_box = box self.last_requires_grad = tuple( param.requires_grad for param in self.parameters() ) @@ -131,6 +133,15 @@ def test_skip_loss_keeps_training_gradients(self) -> None: self.assertIsNotNone(model.linear.weight.grad) self.assertIsNotNone(model.scale.grad) + def test_positional_box_keeps_legacy_argument_order(self) -> None: + model = _LinearToyModel() + wrapper = ModelWrapper(model) + box = torch.eye(3, device="cpu").view(1, 3, 3).expand(2, -1, -1) + + wrapper(self.coord, self.atype, None, box) + + self.assertIs(model.last_box, box) + if __name__ == "__main__": unittest.main() From 7bf3e6d9cb96d0d8604c2eee19496373d7a2d28a Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 22 Oct 2026 03:25:10 +0000 Subject: [PATCH 21/23] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/density/README.md | 2 +- source/tests/pt/test_dp_test_density.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/density/README.md b/examples/density/README.md index 4808a135c4..3e24d9705e 100644 --- a/examples/density/README.md +++ b/examples/density/README.md @@ -32,7 +32,7 @@ The training/validation data follows the standard **`deepmd/npy`** format, with | `coord.npy` | `[nframes, natoms * 3]` | Atomic coordinates | | `box.npy` | `[nframes, 9]` | Simulation cell vectors | | `type.raw` | `[natoms]` | Atom type indices | -| `type_map.raw` | `[ntypes]` | Real element types in this dataset | +| `type_map.raw` | `[ntypes]` | Real element types in this dataset | | **`grid.npy`** | `[nframes, ngrid, 3]` | **Grid point coordinates** | | **`density.npy`** | `[nframes, ngrid, 1]` | **Charge density labels on grids** | diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index 58dd4aa60e..4d15b7b750 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -315,12 +315,12 @@ def test_fitting_model_serialization_roundtrip(self) -> None: # which is what model freezing relies on. The model must go through # BaseModel.deserialize, which dispatches on the serialized fitting # type ("density") and is what dp convert-backend uses. - from deepmd.pt.model.model.model import ( - BaseModel, - ) from deepmd.pt.loss.charge import ( GridDensityLoss, ) + from deepmd.pt.model.model.model import ( + BaseModel, + ) fitting = self.torch_model.atomic_model.fitting_net restored_fit = DensityFittingNet.deserialize(fitting.serialize()) From 9449d6e2defa0f5d9558891c04fab6214ae4f611 Mon Sep 17 00:00:00 2001 From: Yuzhi Liu Date: Thu, 22 Oct 2026 11:28:34 +0800 Subject: [PATCH 22/23] chore(docs): retrigger Read the Docs build From 94e0a1b64d40065fb3761cc3fc69cef558ba0ddc Mon Sep 17 00:00:00 2001 From: Yuzhi Liu Date: Thu, 22 Oct 2026 12:26:20 +0800 Subject: [PATCH 23/23] test(pt): avoid ambiguous parent stat call --- source/tests/pt/test_dp_test_density.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index 4d15b7b750..1dc2c6d575 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -33,6 +33,9 @@ from deepmd.pt.model.atomic_model.density_atomic_model import ( DPDensityAtomicModel, ) +from deepmd.pt.model.atomic_model.dp_atomic_model import ( + DPAtomicModel, +) from deepmd.pt.model.descriptor.hybrid import ( DescrptHybrid, ) @@ -609,9 +612,7 @@ def sampler() -> list: self.assertIsNotNone(update_path) # The parent pass writes a complete cache with the ordinary # zero-sample placeholder for the reserved grid type. - super(DPDensityAtomicModel, atomic_model).compute_or_load_stat( - sampler, update_path - ) + DPAtomicModel.compute_or_load_stat(atomic_model, sampler, update_path) original = stat_file.read_bytes() with open_stat_file(StatFileSpec(str(stat_file), "read")) as read_path:

M3IrTh* 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 Ko_}rUiQ#{B!{A&1 literal 0 HcmV?d00001 diff --git a/examples/density/dataset/qm9/C7H15NO_val/set.000/grid.npy b/examples/density/dataset/qm9/C7H15NO_val/set.000/grid.npy new file mode 100644 index 0000000000000000000000000000000000000000..961264ac8b09ae0d7e9093ab4600b194fccd7f67 GIT binary patch literal 90128 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 argparse.Namespace: + parser = argparse.ArgumentParser( + description="Evaluate charge-density DeepPot model." + ) + parser.add_argument("model", type=str, help="Path to the model file (.pt or .pth).") + parser.add_argument( + "data_dir", type=str, help="Root directory of deepmd/npy datasets." + ) + parser.add_argument( + "--ratio", + type=float, + default=0.1, + help="Fraction of frames to randomly sample from each system (default: 0.1).", + ) + parser.add_argument( + "--output", + "-o", + type=str, + default=None, + help="If provided, write screen output to this file as well.", + ) + parser.add_argument( + "--pred-file", + type=str, + default="result.d.out", + help="File to save paired [prediction, label] array (default: result.d.out).", + ) + return parser.parse_args() + + +class TeeLogger: + """Redirect stdout to both the terminal and a file.""" + + def __init__(self, filepath: str) -> None: + self.terminal = sys.stdout + self.log = open(filepath, "w") + + def write(self, message: str) -> None: + self.terminal.write(message) + self.log.write(message) + + def flush(self) -> None: + self.terminal.flush() + self.log.flush() + + def close(self) -> None: + self.log.close() + + +def evaluate( + model_path: str, data_dir: str, ratio: float +) -> tuple[np.ndarray, np.ndarray]: + """Run inference and return (predictions, labels).""" + dm = DeepPot(model_path) + type_map = dm.get_type_map() + + pred_list, label_list = [], [] + pattern = os.path.join(data_dir, "**/type.raw") + systems = glob.glob(pattern, recursive=True) + + if not systems: + raise RuntimeError(f"No deepmd/npy systems found under '{data_dir}'") + + for f in tqdm(systems, desc="Systems"): + sys_name = os.path.dirname(f) + s = dpdata.System(sys_name, fmt="deepmd/npy", type_map=type_map) + + n_frames = len(s) + n_sample = max(1, math.floor(n_frames * ratio)) + indices = random.sample(range(n_frames), n_sample) + s = s.sub_system(indices) + + coord = s.data["coords"].reshape(len(s), -1) + atype = list(s.data["atom_types"]) + cell = s.data["cells"].reshape(len(s), -1) + grid = s.data["grid"].reshape(len(s), -1) + + density_pred = dm.eval(coord, cell, atype, grid=grid) + density_label = s.data["density"].reshape(len(s), -1) + + pred_list.append(density_pred) + label_list.append(density_label) + sys.stdout.write(f" {sys_name:60s} frames={n_sample}/{n_frames}" + "\n") + + predictions = np.concatenate(pred_list) + labels = np.concatenate(label_list) + return predictions, labels + + +def print_summary(pred: np.ndarray, label: np.ndarray) -> None: + diff = pred - label + mae = np.mean(np.abs(diff)) + rmse = np.sqrt(np.mean(diff**2)) + label_mean_abs = np.mean(np.abs(label)) + label_std = np.std(label) + + sys.stdout.write("\n" + "=" * 60 + "\n") + sys.stdout.write("Summary" + "\n") + sys.stdout.write("=" * 60 + "\n") + sys.stdout.write(f" Number of grid points : {label.size}" + "\n") + sys.stdout.write(f" Label std : {label_std:.6e}" + "\n") + sys.stdout.write(f" RMSE : {rmse:.6e}" + "\n") + sys.stdout.write(f" MAE : {mae:.6e}" + "\n") + sys.stdout.write(f" Mean |label| : {label_mean_abs:.6e}" + "\n") + sys.stdout.write( + f" epsilon_MAE (MAE/Mean|label|) : {mae / label_mean_abs:.6e}" + "\n" + ) + sys.stdout.write("=" * 60 + "\n") + + +def main() -> None: + args = parse_args() + + if args.output: + tee = TeeLogger(args.output) + sys.stdout = tee + sys.stdout.write(f"[INFO] Screen output will also be saved to: {args.output}\n") + + sys.stdout.write(f"[INFO] Model : {args.model}" + "\n") + sys.stdout.write(f"[INFO] Data : {args.data_dir}" + "\n") + sys.stdout.write(f"[INFO] Ratio : {args.ratio}\n") + + pred, label = evaluate(args.model, args.data_dir, args.ratio) + + # Save paired predictions & labels + out_array = np.stack([pred.reshape(-1), label.reshape(-1)], axis=1) + np.savetxt(args.pred_file, out_array) + sys.stdout.write(f"\n[INFO] Paired [pred, label] saved to: {args.pred_file}" + "\n") + + print_summary(pred, label) + + if args.output: + tee.close() + sys.stdout = tee.terminal + + +if __name__ == "__main__": + main() From ba7ce7495b958110f4d43280edf32b02d0a2ebfa Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 25 Aug 2026 05:46:37 +0000 Subject: [PATCH 02/23] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- examples/density/README.md | 40 +++++- examples/density/dpa3/input.json | 206 +++++++++++++++---------------- 2 files changed, 137 insertions(+), 109 deletions(-) diff --git a/examples/density/README.md b/examples/density/README.md index 785fd8c300..f1ce4960df 100644 --- a/examples/density/README.md +++ b/examples/density/README.md @@ -57,18 +57,46 @@ Key settings in `input.json`: ```json { "model": { - "type_map": ["Li", "Ni", "Co", "Mn", "O", "C", "H", "N", "F", "X"], - "descriptor": { "type": "dpa3" }, - "fitting_net": { "type": "density", "neuron": [240, 240, 240] } + "type_map": [ + "Li", + "Ni", + "Co", + "Mn", + "O", + "C", + "H", + "N", + "F", + "X" + ], + "descriptor": { + "type": "dpa3" + }, + "fitting_net": { + "type": "density", + "neuron": [ + 240, + 240, + 240 + ] + } + }, + "loss": { + "type": "grid_density", + "start_pref_d": 1, + "limit_pref_d": 1 }, - "loss": { "type": "grid_density", "start_pref_d": 1, "limit_pref_d": 1 }, "training": { "training_data": { - "systems": ["../dataset/qm9/C7H15NO_train"], + "systems": [ + "../dataset/qm9/C7H15NO_train" + ], "batch_size": "auto:128" }, "validation_data": { - "systems": ["../dataset/qm9/C7H15NO_val"], + "systems": [ + "../dataset/qm9/C7H15NO_val" + ], "batch_size": 1, "numb_btch": 3 } diff --git a/examples/density/dpa3/input.json b/examples/density/dpa3/input.json index 5fa0d80ca5..0ee1270fae 100644 --- a/examples/density/dpa3/input.json +++ b/examples/density/dpa3/input.json @@ -1,107 +1,107 @@ { - "_comment": "that's all", - "model": { - "type_map": [ - "Li", - "Ni", - "Co", - "Mn", - "O", - "C", - "H", - "N", - "F", - "X" - ], - "descriptor": { - "type": "dpa3", - "repflow": { - "n_dim": 128, - "e_dim": 64, - "a_dim": 32, - "nlayers": 12, - "e_rcut": 6.0, - "e_rcut_smth": 5.3, - "e_sel": 120, - "a_rcut": 4.0, - "a_rcut_smth": 3.5, - "a_sel": 30, - "axis_neuron": 4, - "skip_stat": true, - "a_compress_rate": 1, - "a_compress_e_rate": 2, - "a_compress_use_split": true, - "update_angle": true, - "smooth_edge_update": true, - "use_dynamic_sel": true, - "sel_reduce_factor": 10.0, - "edge_use_dist": true, - "use_env_envelope": true, - "optim_update": true, - "update_style": "res_residual", - "update_residual": 0.1, - "update_residual_init": "const" - }, - "activation_function": "custom_silu:10.0", - "use_tebd_bias": false, - "env_protection": 0.1, - "precision": "float32", - "concat_output_tebd": false - }, - "fitting_net": { - "type": "density", - "neuron": [ - 240, - 240, - 240 - ], - "resnet_dt": true, - "seed": 1, - "precision": "float32", - "activation_function": "silu", - "_comment": " that's all" - }, - "_comment": " that's all" + "_comment": "that's all", + "model": { + "type_map": [ + "Li", + "Ni", + "Co", + "Mn", + "O", + "C", + "H", + "N", + "F", + "X" + ], + "descriptor": { + "type": "dpa3", + "repflow": { + "n_dim": 128, + "e_dim": 64, + "a_dim": 32, + "nlayers": 12, + "e_rcut": 6.0, + "e_rcut_smth": 5.3, + "e_sel": 120, + "a_rcut": 4.0, + "a_rcut_smth": 3.5, + "a_sel": 30, + "axis_neuron": 4, + "skip_stat": true, + "a_compress_rate": 1, + "a_compress_e_rate": 2, + "a_compress_use_split": true, + "update_angle": true, + "smooth_edge_update": true, + "use_dynamic_sel": true, + "sel_reduce_factor": 10.0, + "edge_use_dist": true, + "use_env_envelope": true, + "optim_update": true, + "update_style": "res_residual", + "update_residual": 0.1, + "update_residual_init": "const" + }, + "activation_function": "custom_silu:10.0", + "use_tebd_bias": false, + "env_protection": 0.1, + "precision": "float32", + "concat_output_tebd": false }, - "learning_rate": { - "type": "exp", - "decay_steps": 5000, - "start_lr": 0.001, - "stop_lr": 1e-05, - "_comment": "that's all" + "fitting_net": { + "type": "density", + "neuron": [ + 240, + 240, + 240 + ], + "resnet_dt": true, + "seed": 1, + "precision": "float32", + "activation_function": "silu", + "_comment": " that's all" }, - "loss": { - "type": "grid_density", - "start_pref_d": 1, - "limit_pref_d": 1, - "_comment": " that's all" + "_comment": " that's all" + }, + "learning_rate": { + "type": "exp", + "decay_steps": 5000, + "start_lr": 0.001, + "stop_lr": 1e-05, + "_comment": "that's all" + }, + "loss": { + "type": "grid_density", + "start_pref_d": 1, + "limit_pref_d": 1, + "_comment": " that's all" + }, + "training": { + "stat_file": "./qm9_charge_density.hdf5", + "training_data": { + "systems": [ + "../dataset/qm9/C7H15NO_train" + ], + "batch_size": "auto:128", + "_comment": "that's all" }, - "training": { - "stat_file": "./qm9_charge_density.hdf5", - "training_data": { - "systems": [ - "../dataset/qm9/C7H15NO_train" - ], - "batch_size": "auto:128", - "_comment": "that's all" - }, - "validation_data": { - "systems": [ - "../dataset/qm9/C7H15NO_val" - ], - "batch_size": 1, - "numb_btch": 3, - "_comment": "that's all" - }, - "numb_steps": 100, - "warmup_steps": 0, - "gradient_max_norm": 5.0, - "seed": 10, - "max_ckpt_keep": 100, - "opt_type": "AdamW", - "disp_file": "lcurve.out", - "disp_freq": 100, - "save_freq": 10000, - "_comment": "that's all" - } -} \ No newline at end of file + "validation_data": { + "systems": [ + "../dataset/qm9/C7H15NO_val" + ], + "batch_size": 1, + "numb_btch": 3, + "_comment": "that's all" + }, + "numb_steps": 100, + "warmup_steps": 0, + "gradient_max_norm": 5.0, + "seed": 10, + "max_ckpt_keep": 100, + "opt_type": "AdamW", + "disp_file": "lcurve.out", + "disp_freq": 100, + "save_freq": 10000, + "_comment": "that's all" + } +} From a2c294e48352e02d743d706fb94dfceb67a35d70 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Thu, 10 Sep 2026 06:29:12 +0000 Subject: [PATCH 03/23] ci: rerun checks From f6a514f03c42908d79c0ee8b46cd7df0cc75c95b Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Fri, 11 Sep 2026 05:07:32 +0000 Subject: [PATCH 04/23] fix(infer): remove type-incoherent grid branch from DeepPot.eval The grid early-return in DeepPot.eval returned a bare ndarray while the @overload declarations promise a tuple; density evaluation already has a proper, type-consistent entry via DeepEval dispatching to DeepDensity, so drop the branch and switch the example script to DeepEval. Also add the missing test coverage requested in review: - test(common): DeepmdData grid/density branches (frame-major loading, frame-count validation, optional-label downgrade) - test(pt): end-to-end dp test for density models --- deepmd/infer/deep_pot.py | 4 - examples/density/dptest_density_script.py | 5 +- .../common/test_deepmd_data_grid_density.py | 119 +++++++++++++ source/tests/pt/test_dp_test_density.py | 164 ++++++++++++++++++ 4 files changed, 286 insertions(+), 6 deletions(-) create mode 100644 source/tests/common/test_deepmd_data_grid_density.py create mode 100644 source/tests/pt/test_dp_test_density.py diff --git a/deepmd/infer/deep_pot.py b/deepmd/infer/deep_pot.py index a9c16ce9a0..96ef64a139 100644 --- a/deepmd/infer/deep_pot.py +++ b/deepmd/infer/deep_pot.py @@ -212,10 +212,6 @@ def eval( aparam=aparam, **kwargs, ) - # TODO: if the grid is requested, we can directly return it without reshaping to energy, force and virial. We can also consider to return the grid in a separate key in the results dict, instead of reshaping it to energy, force and virial. - if kwargs.get("grid") is not None: - result = results["density"].reshape(nframes, -1) - return result energy = results["energy_redu"].reshape(nframes, 1) force = results["energy_derv_r"].reshape(nframes, natoms, 3) diff --git a/examples/density/dptest_density_script.py b/examples/density/dptest_density_script.py index 7de198466a..cd9476b957 100644 --- a/examples/density/dptest_density_script.py +++ b/examples/density/dptest_density_script.py @@ -25,7 +25,7 @@ ) from deepmd.infer import ( - DeepPot, + DeepEval, ) # Register custom dpdata types for grid density @@ -98,7 +98,8 @@ def evaluate( model_path: str, data_dir: str, ratio: float ) -> tuple[np.ndarray, np.ndarray]: """Run inference and return (predictions, labels).""" - dm = DeepPot(model_path) + # DeepEval dispatches density models to DeepDensity automatically. + dm = DeepEval(model_path) type_map = dm.get_type_map() pred_list, label_list = [], [] diff --git a/source/tests/common/test_deepmd_data_grid_density.py b/source/tests/common/test_deepmd_data_grid_density.py new file mode 100644 index 0000000000..7ce3698fd2 --- /dev/null +++ b/source/tests/common/test_deepmd_data_grid_density.py @@ -0,0 +1,119 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +"""Tests for the frame-major grid/density branches in DeepmdData. + +These keys are loaded verbatim (no reshaping to natoms) and must carry a +leading frame dimension matching the set's frame count, so that shuffling +never pairs a structure with another frame's grid or density label. +""" + +import tempfile +import unittest +from pathlib import ( + Path, +) + +import numpy as np + +from deepmd.utils.data import ( + DeepmdData, +) + +NATOMS = 3 +NGRID = 5 +NFRAMES = 4 + + +class TestDeepmdDataGridDensity(unittest.TestCase): + def setUp(self) -> None: + self.tmpdir = tempfile.TemporaryDirectory() + self.root = Path(self.tmpdir.name) + self.set_dir = self.root / "set.000" + self.set_dir.mkdir() + rng = np.random.default_rng(42) + + np.savetxt(self.root / "type.raw", np.zeros(NATOMS, dtype=np.int32), fmt="%d") + np.save( + self.set_dir / "coord.npy", + rng.random((NFRAMES, NATOMS * 3), dtype=np.float32), + ) + np.save( + self.set_dir / "box.npy", + np.eye(3, dtype=np.float32).reshape(1, 9).repeat(NFRAMES, axis=0), + ) + np.save( + self.set_dir / "type.npy", + np.zeros((NFRAMES, NATOMS), dtype=np.int32), + ) + self.set_data("grid", rng.random((NFRAMES, NGRID, 3), dtype=np.float32)) + self.set_data("density", rng.random((NFRAMES, NGRID, 1), dtype=np.float32)) + + def tearDown(self) -> None: + self.tmpdir.cleanup() + + def set_data(self, key: str, arr: np.ndarray | None) -> None: + path = self.set_dir / f"{key}.npy" + if arr is None: + path.unlink(missing_ok=True) + else: + np.save(path, arr) + + def build_data(self, must: bool = True) -> DeepmdData: + data = DeepmdData(str(self.root)) + data.add("coord", 3, atomic=True, must=True) + data.add("box", 9, atomic=False, must=True) + data.add("type", 1, atomic=True, must=True) + data.add("grid", 3, atomic=True, must=must, high_prec=True) + data.add("density", 1, atomic=True, must=must, high_prec=True) + return data + + def test_load_set_frame_major(self) -> None: + data = self.build_data() + loaded = data._load_set(self.set_dir) + self.assertEqual(loaded["find_grid"], 1.0) + self.assertEqual(loaded["find_density"], 1.0) + self.assertEqual(loaded["grid"].shape, (NFRAMES, NGRID, 3)) + self.assertEqual(loaded["density"].shape, (NFRAMES, NGRID, 1)) + + def test_single_frame(self) -> None: + data = self.build_data() + frame = data.get_single_frame(0, 0) + self.assertEqual(frame["find_grid"], 1.0) + self.assertEqual(frame["find_density"], 1.0) + self.assertEqual(frame["grid"].shape, (NGRID, 3)) + self.assertEqual(frame["density"].shape, (NGRID, 1)) + + def test_frame_count_mismatch_load_set(self) -> None: + self.set_data("grid", np.zeros((NFRAMES - 1, NGRID, 3), dtype=np.float32)) + with self.assertRaisesRegex(ValueError, "frame count"): + self.build_data()._load_set(self.set_dir) + + def test_frame_count_mismatch_single_frame(self) -> None: + self.set_data("density", np.zeros((NFRAMES - 1, NGRID, 1), dtype=np.float32)) + with self.assertRaisesRegex(ValueError, "frame count"): + self.build_data().get_single_frame(0, 0) + + def test_missing_frame_dimension_load_set(self) -> None: + # stored without a leading frame dimension: rejected rather than + # silently misaligned with the frames + self.set_data("grid", np.zeros((NGRID, 3), dtype=np.float32)) + with self.assertRaisesRegex(ValueError, r"frame count|leading frame"): + self.build_data()._load_set(self.set_dir) + + def test_missing_frame_dimension_single_frame(self) -> None: + self.set_data("density", np.zeros((NGRID, 1), dtype=np.float32)) + with self.assertRaisesRegex(ValueError, r"frame count|leading frame"): + self.build_data().get_single_frame(0, 0) + + def test_missing_file_optional(self) -> None: + # optional labels absent: the loader must not fail and must signal + # find=0 so that downstream code can skip the residual + self.set_data("density", None) + data = self.build_data(must=False) + loaded = data._load_set(self.set_dir) + self.assertEqual(loaded["find_density"], 0.0) + frame = data.get_single_frame(0, 0) + self.assertEqual(frame["find_density"], 0.0) + + +if __name__ == "__main__": + unittest.main() diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py new file mode 100644 index 0000000000..da21fc68d2 --- /dev/null +++ b/source/tests/pt/test_dp_test_density.py @@ -0,0 +1,164 @@ +# SPDX-License-Identifier: LGPL-3.0-or-later +import os +import tempfile +import unittest +from copy import ( + deepcopy, +) +from pathlib import ( + Path, +) + +import numpy as np +import torch + +from deepmd.entrypoints.test import test as dp_test +from deepmd.infer.deep_density import ( + DeepDensity, +) +from deepmd.infer.deep_eval import ( + DeepEval, +) +from deepmd.pt.entrypoints.main import ( + get_trainer, +) +from deepmd.utils.argcheck import ( + normalize, +) + +model_density = { + "type_map": ["O", "H"], + "descriptor": { + "type": "se_e2_a", + "sel": [8, 8], + "rcut_smth": 0.50, + "rcut": 4.00, + "neuron": [8, 16], + "resnet_dt": False, + "axis_neuron": 4, + "seed": 1, + }, + "fitting_net": { + "type": "density", + "neuron": [8, 8], + "seed": 1, + }, +} + + +class TestDPTestDensity(unittest.TestCase): + @classmethod + def setUpClass(cls) -> None: + cls.tmpdir = tempfile.TemporaryDirectory() + root = Path(cls.tmpdir.name) + + # write a synthetic density system + rng = np.random.default_rng(42) + cls.nframes, natoms, cls.ngrid = 4, 5, 8 + cls.system = root / "system" + set_dir = cls.system / "set.000" + set_dir.mkdir(parents=True) + np.save(set_dir / "coord.npy", rng.random((cls.nframes, natoms * 3)) * 8.0) + np.save( + set_dir / "box.npy", + np.tile(np.eye(3).reshape(-1) * 10.0, (cls.nframes, 1)), + ) + np.save(set_dir / "grid.npy", rng.random((cls.nframes, cls.ngrid, 3)) * 8.0) + np.save(set_dir / "density.npy", rng.random((cls.nframes, cls.ngrid, 1))) + np.savetxt(cls.system / "type.raw", [0, 0, 1, 1, 1], fmt="%d") + np.savetxt(cls.system / "type_map.raw", ["O", "H"], fmt="%s") + + cls.config = { + "model": deepcopy(model_density), + "learning_rate": { + "type": "exp", + "start_lr": 0.001, + "stop_lr": 1e-8, + "decay_steps": 10, + }, + "optimizer": {"type": "Adam"}, + "loss": { + "type": "grid_density", + "start_pref_d": 1.0, + "limit_pref_d": 1.0, + }, + "training": { + "training_data": { + "systems": [str(cls.system)], + "batch_size": 1, + }, + "validation_data": { + "systems": [str(cls.system)], + "batch_size": 1, + }, + "numb_steps": 1, + "seed": 1, + "disp_file": os.devnull, + "save_freq": 100, + }, + } + + # build and freeze a tiny density model through the trainer path + trainer = get_trainer(normalize(deepcopy(cls.config))) + with torch.device("cpu"): + input_dict, _, _ = trainer.get_data(is_train=False) + # the density model takes grid instead of spin as the extra input + input_dict.pop("spin", None) + trainer.model(**input_dict) + model = torch.jit.script(trainer.model) + tmp_fd, cls.model_path = tempfile.mkstemp(suffix=".pth") + os.close(tmp_fd) + torch.jit.save(model, cls.model_path) + + @classmethod + def tearDownClass(cls) -> None: + os.unlink(cls.model_path) + cls.tmpdir.cleanup() + + def test_model_type_dispatch(self) -> None: + dp = DeepEval(self.model_path) + self.assertIsInstance(dp, DeepDensity) + + def test_eval_shape(self) -> None: + dp = DeepDensity(self.model_path) + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:2] + box = np.load(set_dir / "box.npy")[:2] + grid = np.load(set_dir / "grid.npy")[:2] + atype = np.loadtxt(self.system / "type.raw", dtype=int) + out = dp.eval(coord, box, atype, grid=grid) + self.assertEqual(out.shape, (2, self.ngrid)) + + def test_dp_test(self) -> None: + detail_file = os.path.join(self.tmpdir.name, "detail") + dp_test( + model=self.model_path, + system=str(self.system), + datafile=None, + numb_test=0, + rand_seed=None, + shuffle_test=False, + detail_file=detail_file, + atomic=False, + ) + # one detail file per frame, each holding ngrid [label, pred] pairs + for frame in range(self.nframes): + detail = np.loadtxt(f"{detail_file}.density.out.{frame}", skiprows=1) + self.assertEqual(detail.shape, (self.ngrid, 2)) + + def test_dp_test_shuffle(self) -> None: + # grid/density must be shuffled together with the frames + dp_test( + model=self.model_path, + system=str(self.system), + datafile=None, + numb_test=2, + rand_seed=42, + shuffle_test=True, + detail_file=None, + atomic=False, + ) + + +if __name__ == "__main__": + unittest.main() From 4ddc09724183e6b6f3474942604daec200526005 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Sun, 13 Sep 2026 04:28:29 +0000 Subject: [PATCH 05/23] fix(pt): harden density model evaluation and inputs - normalize the 1-element tuple returned by _eval_model_density so DeepDensity.eval works with auto_batch_size=False - replace the dead env_protection fallback in DPDensityAtomicModel with a warning, and document/configure positive env_protection for density models (grid points may coincide with atoms) - wrap grid coordinates into the primary cell before building the directional neighbor list so periodically equivalent grids give the same density - add regression tests covering both batching settings, grid-at-atom finiteness (predictions and gradients), and lattice-translation invariance --- deepmd/pt/infer/deep_eval.py | 5 ++ .../atomic_model/density_atomic_model.py | 16 ++++- deepmd/pt/model/model/make_density_model.py | 9 +++ examples/density/README.md | 1 + examples/density/dpa2/input.json | 3 +- source/tests/pt/test_dp_test_density.py | 66 +++++++++++++++++++ 6 files changed, 96 insertions(+), 4 deletions(-) diff --git a/deepmd/pt/infer/deep_eval.py b/deepmd/pt/infer/deep_eval.py index 3be21d409b..37cf0d58d0 100644 --- a/deepmd/pt/infer/deep_eval.py +++ b/deepmd/pt/infer/deep_eval.py @@ -567,6 +567,11 @@ def eval( aparam, request_defs, ) + # _eval_model_density returns a 1-element tuple; execute_all unwraps + # it when auto batching is enabled, but with auto_batch_size=False + # the inner function is called directly and the tuple survives. + if isinstance(out, tuple): + (out,) = out return {"density": out} if "spin" not in kwargs or kwargs["spin"] is None: out = self._eval_func(self._eval_model, numb_test, natoms)( diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index e9447de016..5a297e217c 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -22,6 +22,9 @@ build_directional_neighbor_list, extend_input_and_build_neighbor_list, ) +from deepmd.pt.utils.region import ( + normalize_coord, +) from deepmd.utils.path import ( DPPath, ) @@ -45,9 +48,12 @@ def __init__( super().__init__(descriptor, fitting, type_map, **kwargs) self.rcut = self.descriptor.get_rcut() self.rcut_smth = self.descriptor.get_rcut_smth() - self.env_protection = self.descriptor.get_env_protection() - if self.env_protection == 0.0: - self.env_protection = 1e-6 + if self.descriptor.get_env_protection() == 0.0: + log.warning( + "The descriptor env_protection is 0.0; grid points coincident " + "with atoms would produce NaN densities. Set a positive " + "env_protection in the descriptor configuration." + ) self.sel = self.descriptor.get_sel() self.nnei = self.descriptor.get_nsel() @@ -298,6 +304,10 @@ def model_forward( box=box, ) assert grid is not None + if box is not None: + # same wrapping convention as forward_common: grid points + # outside the primary cell are periodically equivalent + grid = normalize_coord(grid, box.reshape(box.shape[0], 3, 3)) grid_type = torch.zeros( grid.shape[:-1], device=grid.device, dtype=atype.dtype ) diff --git a/deepmd/pt/model/model/make_density_model.py b/deepmd/pt/model/model/make_density_model.py index 6fecb14aad..2b1ec659f7 100644 --- a/deepmd/pt/model/model/make_density_model.py +++ b/deepmd/pt/model/model/make_density_model.py @@ -39,6 +39,9 @@ extend_input_and_build_neighbor_list, nlist_distinguish_types, ) +from deepmd.pt.utils.region import ( + normalize_coord, +) from deepmd.utils.path import ( DPPath, ) @@ -169,6 +172,12 @@ def forward_common( ) del coord, grid, box, fparam, aparam gg = gg.view(gg.shape[0], -1, 3) + if bb is not None: + # wrap grid points into the primary cell: the atomic + # coordinates are normalized and extended with ghosts, so + # periodically equivalent grids outside the cell would + # otherwise lose their neighbors + gg = normalize_coord(gg, bb.view(bb.shape[0], 3, 3)) ( extended_coord, extended_atype, diff --git a/examples/density/README.md b/examples/density/README.md index f1ce4960df..7ea27e2b86 100644 --- a/examples/density/README.md +++ b/examples/density/README.md @@ -40,6 +40,7 @@ The training/validation data follows the standard **`deepmd/npy`** format, with > > - `grid.npy` and `density.npy` are required for the density model. The number of grid points (`ngrid`) must match between `grid.npy` and `density.npy`, and is allowed to differ from `natoms`. > - The **last entry of `type_map` is reserved as a virtual "grid point type"** (e.g. `X` in the example): internally, grid points are assigned this type when building the grid-to-atom neighbor list. Make sure your `type_map` contains one more entry than the real element types. +> - **Always set a positive `env_protection`** in the descriptor configuration (e.g. `"env_protection": 0.1`, as in `dpa3/input.json`). Grid points may legitimately coincide with atoms, and the default `env_protection = 0.0` would let the `1/r` terms in the environment matrix produce `NaN` densities and poison the training gradients at such points. ______________________________________________________________________ diff --git a/examples/density/dpa2/input.json b/examples/density/dpa2/input.json index 2454c9b26c..c570fce61b 100644 --- a/examples/density/dpa2/input.json +++ b/examples/density/dpa2/input.json @@ -60,7 +60,8 @@ "g1_out_mlp": true }, "precision": "float32", - "add_tebd_to_repinit_out": false + "add_tebd_to_repinit_out": false, + "env_protection": 0.1 }, "fitting_net": { "type": "density", diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index da21fc68d2..6bcedb1919 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -36,6 +36,9 @@ "neuron": [8, 16], "resnet_dt": False, "axis_neuron": 4, + # grid points may coincide with atoms; without protection the + # env matrix would divide by zero and produce NaN densities + "env_protection": 1e-6, "seed": 1, }, "fitting_net": { @@ -105,6 +108,9 @@ def setUpClass(cls) -> None: # the density model takes grid instead of spin as the extra input input_dict.pop("spin", None) trainer.model(**input_dict) + # keep the live torch model and a data sample for the gradient check + cls.torch_model = trainer.model + cls.input_dict = input_dict model = torch.jit.script(trainer.model) tmp_fd, cls.model_path = tempfile.mkstemp(suffix=".pth") os.close(tmp_fd) @@ -129,6 +135,66 @@ def test_eval_shape(self) -> None: out = dp.eval(coord, box, atype, grid=grid) self.assertEqual(out.shape, (2, self.ngrid)) + def test_eval_no_auto_batch(self) -> None: + # auto_batch_size=False bypasses execute_all's single-tuple unwrapping; + # the density result must still be normalized to a bare ndarray + dp = DeepDensity(self.model_path, auto_batch_size=False) + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:2] + box = np.load(set_dir / "box.npy")[:2] + grid = np.load(set_dir / "grid.npy")[:2] + atype = np.loadtxt(self.system / "type.raw", dtype=int) + out = dp.eval(coord, box, atype, grid=grid) + self.assertEqual(out.shape, (2, self.ngrid)) + # and match the default-batching result numerically + out_default = DeepDensity(self.model_path).eval(coord, box, atype, grid=grid) + np.testing.assert_allclose(out, out_default) + + def test_grid_at_atoms_finite(self) -> None: + # grid points coincident with atoms are legitimate inputs; with + # env_protection > 0 (set in the test config) the predictions and + # gradients must stay finite instead of turning NaN via 1/r terms + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:2] + box = np.load(set_dir / "box.npy")[:2] + atype = np.loadtxt(self.system / "type.raw", dtype=int) + grid_at_atoms = coord.reshape(coord.shape[0], -1, 3) + out = DeepDensity(self.model_path).eval(coord, box, atype, grid=grid_at_atoms) + self.assertTrue(np.isfinite(out).all()) + + # gradients wrt the grid input and all parameters stay finite + input_dict = { + kk: vv.clone() if isinstance(vv, torch.Tensor) else vv + for kk, vv in self.input_dict.items() + } + coord_t = input_dict["coord"] + grid_t = ( + coord_t.reshape(coord_t.shape[0], -1, 3).detach().clone().requires_grad_() + ) + input_dict["grid"] = grid_t + model_out = self.torch_model(**input_dict) + self.assertTrue(torch.isfinite(model_out["density"]).all()) + model_out["density"].sum().backward() + self.assertIsNotNone(grid_t.grad) + self.assertTrue(torch.isfinite(grid_t.grad).all()) + for param in self.torch_model.parameters(): + if param.grad is not None: + self.assertTrue(torch.isfinite(param.grad).all()) + + def test_grid_periodic_translation(self) -> None: + # grids shifted by integer cell vectors are periodically equivalent + # and must produce the same density as the wrapped originals + set_dir = self.system / "set.000" + coord = np.load(set_dir / "coord.npy")[:2] + box = np.load(set_dir / "box.npy")[:2] + grid = np.load(set_dir / "grid.npy")[:2] + atype = np.loadtxt(self.system / "type.raw", dtype=int) + dp = DeepDensity(self.model_path) + out = dp.eval(coord, box, atype, grid=grid) + cell_vec = box.reshape(box.shape[0], 3, 3)[:, 0] + out_shift = dp.eval(coord, box, atype, grid=grid + 2.0 * cell_vec[:, None, :]) + np.testing.assert_allclose(out_shift, out, rtol=1e-5, atol=1e-5) + def test_dp_test(self) -> None: detail_file = os.path.join(self.tmpdir.name, "detail") dp_test( From 83a753cc28263b85fe4b6676d4c4b58630de3404 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Sun, 13 Sep 2026 07:52:19 +0000 Subject: [PATCH 06/23] refactor(pt): derive density model from make_model and assert shuffle alignment - subclass the standard make_model CM and override only the grid-aware interfaces (forward_common, forward_common_lower, _input_type_cast, forward, forward_embedding), dropping ~330 duplicated lines - fix CM.forward passing box into the grid positional slot of forward_common - move the box to the grid device before normalize_coord (GPU training would otherwise fail with a device mismatch) - test_dp_test_shuffle now asserts every shuffled (label, pred) row matches the unshuffled reference --- .../atomic_model/density_atomic_model.py | 4 +- deepmd/pt/model/model/make_density_model.py | 441 ++---------------- source/tests/pt/test_dp_test_density.py | 31 +- 3 files changed, 83 insertions(+), 393 deletions(-) diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index 5a297e217c..c552118a08 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -307,7 +307,9 @@ def model_forward( if box is not None: # same wrapping convention as forward_common: grid points # outside the primary cell are periodically equivalent - grid = normalize_coord(grid, box.reshape(box.shape[0], 3, 3)) + grid = normalize_coord( + grid, box.to(grid.device).reshape(box.shape[0], 3, 3) + ) grid_type = torch.zeros( grid.shape[:-1], device=grid.device, dtype=atype.dtype ) diff --git a/deepmd/pt/model/model/make_density_model.py b/deepmd/pt/model/model/make_density_model.py index 2b1ec659f7..97cc1d285e 100644 --- a/deepmd/pt/model/model/make_density_model.py +++ b/deepmd/pt/model/model/make_density_model.py @@ -1,26 +1,12 @@ # SPDX-License-Identifier: LGPL-3.0-or-later -from collections.abc import ( - Callable, -) -from typing import ( - Any, - Optional, -) - import torch -from deepmd.dpmodel import ( - ModelOutputDef, -) -from deepmd.dpmodel.output_def import ( - FittingOutputDef, - OutputVariableCategory, - OutputVariableOperation, - check_operation_applied, -) from deepmd.pt.model.atomic_model.base_atomic_model import ( BaseAtomicModel, ) +from deepmd.pt.model.model.make_model import ( + make_model, +) from deepmd.pt.model.model.model import ( BaseModel, ) @@ -28,35 +14,28 @@ communicate_extended_output, fit_output_to_model_output, ) -from deepmd.pt.utils.env import ( - GLOBAL_PT_ENER_FLOAT_PRECISION, - GLOBAL_PT_FLOAT_PRECISION, - PRECISION_DICT, - RESERVED_PRECISION_DICT, -) from deepmd.pt.utils.nlist import ( build_directional_neighbor_list, extend_input_and_build_neighbor_list, - nlist_distinguish_types, ) from deepmd.pt.utils.region import ( normalize_coord, ) -from deepmd.utils.path import ( - DPPath, -) def make_density_model(T_AtomicModel: type[BaseAtomicModel]) -> type[BaseModel]: """Make a density model as a derived class of an atomic model. - The model provide two interfaces. + The model predicts a scalar density on grid points instead of atomic + energies. It is built by subclassing the standard model made by + `make_model` and overriding only the interfaces that differ: - 1. the `forward_common_lower`, that takes extended coordinates, atyps and neighbor list, - and outputs the atomic and property and derivatives (if required) on the extended region. + 1. the `forward_common_lower`, that takes extended coordinates, atypes, + neighbor list and the grid (with its type and directional neighbor list), + and outputs the density on the grid points; - 2. the `forward_common`, that takes coordinates, atypes and cell and predicts - the atomic and reduced property, and derivatives (if required) on the local region. + 2. the `forward_common`, that takes coordinates, atypes, cell and grid, + and predicts the density on the grid points. Parameters ---------- @@ -70,63 +49,7 @@ def make_density_model(T_AtomicModel: type[BaseAtomicModel]) -> type[BaseModel]: """ - class CM(BaseModel): - def __init__( - self, - *args: Any, - # underscore to prevent conflict with normal inputs - atomic_model_: T_AtomicModel | None = None, - **kwargs: Any, - ) -> None: - super().__init__(*args, **kwargs) - if atomic_model_ is not None: - self.atomic_model: T_AtomicModel = atomic_model_ - else: - self.atomic_model: T_AtomicModel = T_AtomicModel(*args, **kwargs) - self.precision_dict = PRECISION_DICT - self.reverse_precision_dict = RESERVED_PRECISION_DICT - self.global_pt_float_precision = GLOBAL_PT_FLOAT_PRECISION - self.global_pt_ener_float_precision = GLOBAL_PT_ENER_FLOAT_PRECISION - - def model_output_def(self) -> ModelOutputDef: - """Get the output def for the model.""" - return ModelOutputDef(self.atomic_output_def()) - - @torch.jit.export - def model_output_type(self) -> list[str]: - """Get the output type for the model.""" - output_def = self.model_output_def() - var_defs = output_def.var_defs - # jit: Comprehension ifs are not supported yet - # type hint is critical for JIT - vars: list[str] = [] - for kk, vv in var_defs.items(): - # .value is critical for JIT - if vv.category == OutputVariableCategory.OUT.value: - vars.append(kk) - return vars - - @torch.jit.export - def has_chg_spin_ebd(self) -> bool: - """Check if the model has charge spin embedding.""" - return self.atomic_model.has_chg_spin_ebd() - - @torch.jit.export - def get_dim_chg_spin(self) -> int: - """Get the dimension of charge_spin input.""" - return self.atomic_model.get_dim_chg_spin() - - @torch.jit.export - def has_default_chg_spin(self) -> bool: - """Check if the model has default charge_spin values.""" - return self.atomic_model.has_default_chg_spin() - - @torch.jit.export - def get_default_chg_spin(self) -> torch.Tensor | None: - """Get the default charge_spin values.""" - return self.atomic_model.get_default_chg_spin() - - # cannot use the name forward. torch script does not work + class CM(make_model(T_AtomicModel)): def forward_common( self, coord: torch.Tensor, @@ -147,7 +70,7 @@ def forward_common( shape: nf x (nloc x 3) atype The type of atoms. shape: nf x nloc - coord + grid The coordinates of the grids. shape: nf x (ngrid x 3) box @@ -167,7 +90,7 @@ def forward_common( """ assert grid is not None - cc, gg, bb, fp, ap, input_prec = self.input_type_cast( + cc, gg, bb, fp, ap, input_prec = self._input_type_cast( coord, grid, box=box, fparam=fparam, aparam=aparam ) del coord, grid, box, fparam, aparam @@ -177,7 +100,7 @@ def forward_common( # coordinates are normalized and extended with ghosts, so # periodically equivalent grids outside the cell would # otherwise lose their neighbors - gg = normalize_coord(gg, bb.view(bb.shape[0], 3, 3)) + gg = normalize_coord(gg, bb.to(gg.device).view(bb.shape[0], 3, 3)) ( extended_coord, extended_atype, @@ -214,6 +137,7 @@ def forward_common( do_atomic_virial=do_atomic_virial, fparam=fp, aparam=ap, + charge_spin=charge_spin, ) model_predict = communicate_extended_output( model_predict_lower, @@ -221,42 +145,9 @@ def forward_common( mapping, do_atomic_virial=do_atomic_virial, ) - model_predict = self.output_type_cast(model_predict, input_prec) + model_predict = self._output_type_cast(model_predict, input_prec) return model_predict - def get_out_bias(self) -> torch.Tensor: - return self.atomic_model.get_out_bias() - - def set_out_bias(self, out_bias: torch.Tensor) -> None: - self.atomic_model.set_out_bias(out_bias) - - def change_out_bias( - self, - merged: Callable[[], list[dict]] | list[dict], - bias_adjust_mode: str = "change-by-statistic", - ) -> None: - """Change the output bias of atomic model according to the input data and the pretrained model. - - Parameters - ---------- - merged : Union[Callable[[], list[dict]], list[dict]] - - list[dict]: A list of data samples from various data systems. - Each element, `merged[i]`, is a data dictionary containing `keys`: `torch.Tensor` - originating from the `i`-th data system. - - Callable[[], list[dict]]: A lazy function that returns data samples in the above format - only when needed. Since the sampling process can be slow and memory-intensive, - the lazy function helps by only sampling once. - bias_adjust_mode : str - The mode for changing output bias : ['change-by-statistic', 'set-by-statistic'] - 'change-by-statistic' : perform predictions on labels of target dataset, - and do least square on the errors to obtain the target shift as bias. - 'set-by-statistic' : directly use the statistic output bias in the target dataset. - """ - self.atomic_model.change_out_bias( - merged, - bias_adjust_mode=bias_adjust_mode, - ) - def forward_common_lower( self, extended_coord: torch.Tensor, @@ -274,9 +165,9 @@ def forward_common_lower( extra_nlist_sort: bool = False, ) -> dict[str, torch.Tensor]: """Return model prediction. Lower interface that takes - extended atomic coordinates and types, nlist, and mapping - as input, and returns the predictions on the extended region. - The predictions are not reduced. + extended atomic coordinates and types, nlist, mapping, and the + grid inputs as input, and returns the predictions on the grid + points. The predictions are not reduced. Parameters ---------- @@ -286,6 +177,13 @@ def forward_common_lower( atomic type in extended region. nf x nall nlist neighbor list. nf x nloc x nsel. + grid + grid coordinates. nf x ngrid x 3 + grid_type + type of the grid points. nf x ngrid + grid_nlist + directional neighbor list from grid points to atoms. + nf x ngrid x nsel mapping mapps the extended indices to local indices. nf x nall. fparam @@ -311,7 +209,7 @@ def forward_common_lower( extended_coord, extended_atype, nlist, extra_nlist_sort=extra_nlist_sort ) assert grid is not None - cc_ext, gg, _, fp, ap, input_prec = self.input_type_cast( + cc_ext, gg, _, fp, ap, input_prec = self._input_type_cast( extended_coord, grid, fparam=fparam, aparam=aparam ) del extended_coord, grid, fparam, aparam @@ -326,6 +224,7 @@ def forward_common_lower( grid=gg, grid_type=grid_type, grid_nlist=grid_nlist, + charge_spin=charge_spin, ) model_predict = fit_output_to_model_output( atomic_ret, @@ -334,10 +233,10 @@ def forward_common_lower( do_atomic_virial=do_atomic_virial, create_graph=self.training, ) - model_predict = self.output_type_cast(model_predict, input_prec) + model_predict = self._output_type_cast(model_predict, input_prec) return model_predict - def input_type_cast( + def _input_type_cast( self, coord: torch.Tensor, grid: torch.Tensor, @@ -378,281 +277,43 @@ def input_type_cast( input_prec, ) - def output_type_cast( - self, - model_ret: dict[str, torch.Tensor], - input_prec: str, - ) -> dict[str, torch.Tensor]: - """Convert the model output to the input prec.""" - do_cast = ( - input_prec - != self.reverse_precision_dict[self.global_pt_float_precision] - ) - pp = self.precision_dict[input_prec] - odef = self.model_output_def() - for kk in odef.keys(): - if kk not in model_ret.keys(): - # do not return energy_derv_c if not do_atomic_virial - continue - if check_operation_applied(odef[kk], OutputVariableOperation.REDU): - model_ret[kk] = ( - model_ret[kk].to(self.global_pt_ener_float_precision) - if model_ret[kk] is not None - else None - ) - elif do_cast: - model_ret[kk] = ( - model_ret[kk].to(pp) if model_ret[kk] is not None else None - ) - return model_ret - - def format_nlist( - self, - extended_coord: torch.Tensor, - extended_atype: torch.Tensor, - nlist: torch.Tensor, - extra_nlist_sort: bool = False, - ) -> torch.Tensor: - """Format the neighbor list. - - 1. If the number of neighbors in the `nlist` is equal to sum(self.sel), - it does nothong - - 2. If the number of neighbors in the `nlist` is smaller than sum(self.sel), - the `nlist` is pad with -1. - - 3. If the number of neighbors in the `nlist` is larger than sum(self.sel), - the nearest sum(sel) neighbors will be preseved. - - Known limitations: - - In the case of not self.mixed_types, the nlist is always formatted. - May have side effact on the efficiency. - - Parameters - ---------- - extended_coord - coodinates in extended region. nf x nall x 3 - extended_atype - atomic type in extended region. nf x nall - nlist - neighbor list. nf x nloc x nsel - extra_nlist_sort - whether to forcibly sort the nlist. - - Returns - ------- - formated_nlist - the formated nlist. - - """ - mixed_types = self.mixed_types() - nlist = self._format_nlist( - extended_coord, - nlist, - sum(self.get_sel()), - extra_nlist_sort=extra_nlist_sort, - ) - if not mixed_types: - nlist = nlist_distinguish_types(nlist, extended_atype, self.get_sel()) - return nlist - - def _format_nlist( - self, - extended_coord: torch.Tensor, - nlist: torch.Tensor, - nnei: int, - extra_nlist_sort: bool = False, - ) -> torch.Tensor: - n_nf, n_nloc, n_nnei = nlist.shape - # nf x nall x 3 - extended_coord = extended_coord.view([n_nf, -1, 3]) - rcut = self.get_rcut() - - if n_nnei < nnei: - nlist = torch.cat( - [ - nlist, - -1 - * torch.ones( - [n_nf, n_nloc, nnei - n_nnei], - dtype=nlist.dtype, - device=nlist.device, - ), - ], - dim=-1, - ) - - if n_nnei > nnei or extra_nlist_sort: - n_nf, n_nloc, n_nnei = nlist.shape - m_real_nei = nlist >= 0 - nlist = torch.where(m_real_nei, nlist, 0) - # nf x nloc x 3 - coord0 = extended_coord[:, :n_nloc, :] - # nf x (nloc x nnei) x 3 - index = nlist.view(n_nf, n_nloc * n_nnei, 1).expand(-1, -1, 3) - coord1 = torch.gather(extended_coord, 1, index) - # nf x nloc x nnei x 3 - coord1 = coord1.view(n_nf, n_nloc, n_nnei, 3) - # nf x nloc x nnei - rr = torch.linalg.norm(coord0[:, :, None, :] - coord1, dim=-1) - rr = torch.where(m_real_nei, rr, float("inf")) - rr, nlist_mapping = torch.sort(rr, dim=-1) - nlist = torch.gather(nlist, 2, nlist_mapping) - nlist = torch.where(rr > rcut, -1, nlist) - nlist = nlist[..., :nnei] - else: # not extra_nlist_sort and n_nnei <= nnei: - pass # great! - assert nlist.shape[-1] == nnei - return nlist - - def do_grad_r( - self, - var_name: str | None = None, - ) -> bool: - """Tell if the output variable `var_name` is r_differentiable. - if var_name is None, returns if any of the variable is r_differentiable. - """ - return self.atomic_model.do_grad_r(var_name) - - def do_grad_c( - self, - var_name: str | None = None, - ) -> bool: - """Tell if the output variable `var_name` is c_differentiable. - if var_name is None, returns if any of the variable is c_differentiable. - """ - return self.atomic_model.do_grad_c(var_name) - - def change_type_map( - self, - type_map: list[str], - model_with_new_type_stat: Optional["CM"] = None, - ) -> None: - """Change the type related params to new ones, according to `type_map` and the original one in the model. - If there are new types in `type_map`, statistics will be updated accordingly to `model_with_new_type_stat` for these new types. - """ - self.atomic_model.change_type_map( - type_map=type_map, - model_with_new_type_stat=model_with_new_type_stat.atomic_model - if model_with_new_type_stat is not None - else None, - ) - - def serialize(self) -> dict: - return self.atomic_model.serialize() - - @classmethod - def deserialize(cls, data: dict) -> "CM": - return cls(atomic_model_=T_AtomicModel.deserialize(data)) - - @torch.jit.export - def get_dim_fparam(self) -> int: - """Get the number (dimension) of frame parameters of this atomic model.""" - return self.atomic_model.get_dim_fparam() - - @torch.jit.export - def get_dim_aparam(self) -> int: - """Get the number (dimension) of atomic parameters of this atomic model.""" - return self.atomic_model.get_dim_aparam() - - @torch.jit.export - def get_sel_type(self) -> list[int]: - """Get the selected atom types of this model. - - Only atoms with selected atom types have atomic contribution - to the result of the model. - If returning an empty list, all atom types are selected. - """ - return self.atomic_model.get_sel_type() - - @torch.jit.export - def is_aparam_nall(self) -> bool: - """Check whether the shape of atomic parameters is (nframes, nall, ndim). - - If False, the shape is (nframes, nloc, ndim). - """ - return self.atomic_model.is_aparam_nall() - - @torch.jit.export - def get_rcut(self) -> float: - """Get the cut-off radius.""" - return self.atomic_model.get_rcut() - - @torch.jit.export - def get_type_map(self) -> list[str]: - """Get the type map.""" - return self.atomic_model.get_type_map() - - @torch.jit.export - def get_nsel(self) -> int: - """Returns the total number of selected neighboring atoms in the cut-off radius.""" - return self.atomic_model.get_nsel() - - @torch.jit.export - def get_nnei(self) -> int: - """Returns the total number of selected neighboring atoms in the cut-off radius.""" - return self.atomic_model.get_nnei() - - def atomic_output_def(self) -> FittingOutputDef: - """Get the output def of the atomic model.""" - return self.atomic_model.atomic_output_def() - - def compute_or_load_stat( - self, - sampled_func: Callable[[], list[dict]] | list[dict], - stat_file_path: DPPath | None = None, - preset_observed_type: list[str] | None = None, - ) -> None: - """Compute or load the statistics.""" - return self.atomic_model.compute_or_load_stat( - sampled_func, - stat_file_path, - preset_observed_type=preset_observed_type, - ) - - def get_sel(self) -> list[int]: - """Returns the number of selected atoms for each type.""" - return self.atomic_model.get_sel() - - def mixed_types(self) -> bool: - """If true, the model - 1. assumes total number of atoms aligned across frames; - 2. uses a neighbor list that does not distinguish different atomic types. - - If false, the model - 1. assumes total number of atoms of each atom type aligned across frames; - 2. uses a neighbor list that distinguishes different atomic types. - - """ - return self.atomic_model.mixed_types() - - @torch.jit.export - def has_message_passing(self) -> bool: - """Returns whether the model has message passing.""" - return self.atomic_model.has_message_passing() - - def need_sorted_nlist_for_lower(self) -> bool: - """Returns whether the model needs sorted nlist when using `forward_lower`.""" - return self.atomic_model.need_sorted_nlist_for_lower() - def forward( self, coord: torch.Tensor, atype: torch.Tensor, + grid: torch.Tensor, box: torch.Tensor | None = None, fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, do_atomic_virial: bool = False, + charge_spin: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: # directly call the forward_common method when no specific transform rule return self.forward_common( coord, atype, + grid, box, fparam=fparam, aparam=aparam, do_atomic_virial=do_atomic_virial, + charge_spin=charge_spin, + ) + + @torch.jit.export + def forward_embedding( + self, + coord: torch.Tensor, + atype: torch.Tensor, + box: torch.Tensor | None = None, + fparam: torch.Tensor | None = None, + aparam: torch.Tensor | None = None, + charge_spin: torch.Tensor | None = None, + ) -> dict[str, torch.Tensor]: + # the base implementation would call the grid-aware caster without + # a grid; density models do not support embedding extraction + raise NotImplementedError( + "forward_embedding is not supported for density models." ) return CM diff --git a/source/tests/pt/test_dp_test_density.py b/source/tests/pt/test_dp_test_density.py index 6bcedb1919..f53d3c8e9a 100644 --- a/source/tests/pt/test_dp_test_density.py +++ b/source/tests/pt/test_dp_test_density.py @@ -213,7 +213,27 @@ def test_dp_test(self) -> None: self.assertEqual(detail.shape, (self.ngrid, 2)) def test_dp_test_shuffle(self) -> None: - # grid/density must be shuffled together with the frames + # grid/density must be shuffled together with the frames: every + # (label, pred) row written by the shuffled run must match a row + # from the unshuffled reference run + detail_ref = os.path.join(self.tmpdir.name, "detail_ref") + dp_test( + model=self.model_path, + system=str(self.system), + datafile=None, + numb_test=0, + rand_seed=None, + shuffle_test=False, + detail_file=detail_ref, + atomic=False, + ) + ref_rows = set() + for frame in range(self.nframes): + detail = np.loadtxt(f"{detail_ref}.density.out.{frame}", skiprows=1) + for row in detail: + ref_rows.add(tuple(np.round(row, decimals=5))) + + detail_shuf = os.path.join(self.tmpdir.name, "detail_shuf") dp_test( model=self.model_path, system=str(self.system), @@ -221,9 +241,16 @@ def test_dp_test_shuffle(self) -> None: numb_test=2, rand_seed=42, shuffle_test=True, - detail_file=None, + detail_file=detail_shuf, atomic=False, ) + shuf_rows = [] + for frame in range(2): + detail = np.loadtxt(f"{detail_shuf}.density.out.{frame}", skiprows=1) + shuf_rows.extend(tuple(np.round(row, decimals=5)) for row in detail) + self.assertEqual(len(shuf_rows), 2 * self.ngrid) + for row in shuf_rows: + self.assertIn(row, ref_rows) if __name__ == "__main__": From e894ce80f3e8c00973967c6448ababf1a413dc18 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Sun, 13 Sep 2026 09:46:43 +0000 Subject: [PATCH 07/23] ci: rerun checks From d01f4593acee8451c92112f2f45e4571e7f959b6 Mon Sep 17 00:00:00 2001 From: yuzhibytedance Date: Mon, 14 Sep 2026 09:39:13 +0000 Subject: [PATCH 08/23] fix(pt): address review on density model interfaces, loss, data, and examples - unify the grid type on the reserved last type_map entry everywhere (descriptor, fitting, grid_type) and compute real input statistics for it by injecting grid points into the stat samples - declare grid/density with the loader's special_shape frame_major contract instead of key-name special cases; forward special_shape in pt/pd dataset loaders; grid is a model input declared via get_additional_data_requirement, not a loss label - minimise the squared error in GridDensityLoss like every other loss, and keep the graph connected when the density term is disabled - align density forward_common/forward_common_lower/_input_type_cast with the base positional order, appending grid parameters at the end - make change_out_bias a model-level no-op, give forward_lower a clear message, require grid in eval with a clear error, size the auto batch by max(natoms, ngrid), and replace the grid_mapping python loop with arange - warn and default env_protection to 1e-6 for density models - trim the example dataset to 20+5 frames in float32 (~59 KB) - add regression tests covering all of the above (14 pt + 8 common) --- deepmd/infer/model_test/density.py | 23 ++- deepmd/pd/utils/dataset.py | 1 + deepmd/pt/infer/deep_eval.py | 20 ++- deepmd/pt/loss/charge.py | 28 ++-- .../atomic_model/density_atomic_model.py | 140 ++++++++++++++++-- deepmd/pt/model/model/__init__.py | 12 ++ deepmd/pt/model/model/density_model.py | 6 +- deepmd/pt/model/model/make_density_model.py | 69 +++++++-- deepmd/pt/train/training.py | 16 ++ deepmd/pt/utils/dataset.py | 1 + deepmd/utils/data.py | 46 ++++-- examples/density/README.md | 2 +- .../dataset/qm9/C7H15NO_train/set.000/box.npy | Bin 10928 -> 848 bytes .../qm9/C7H15NO_train/set.000/coord.npy | Bin 86528 -> 5888 bytes .../qm9/C7H15NO_train/set.000/density.npy | Bin 150128 -> 10128 bytes .../qm9/C7H15NO_train/set.000/grid.npy | Bin 450128 -> 30128 bytes .../dataset/qm9/C7H15NO_val/set.000/box.npy | Bin 2288 -> 308 bytes .../dataset/qm9/C7H15NO_val/set.000/coord.npy | Bin 17408 -> 1568 bytes .../qm9/C7H15NO_val/set.000/density.npy | Bin 30128 -> 2628 bytes .../dataset/qm9/C7H15NO_val/set.000/grid.npy | Bin 90128 -> 7628 bytes .../common/test_deepmd_data_grid_density.py | 31 +++- source/tests/pt/test_dp_test_density.py | 104 ++++++++++++- 22 files changed, 429 insertions(+), 70 deletions(-) diff --git a/deepmd/infer/model_test/density.py b/deepmd/infer/model_test/density.py index 7088513d69..14e5bf4603 100644 --- a/deepmd/infer/model_test/density.py +++ b/deepmd/infer/model_test/density.py @@ -30,11 +30,24 @@ def add_data_requirements(self, data: DeepmdData) -> None: dp = self.dp # The grid and the density are defined on grid points rather than on # atoms, and their extent (ngrid) is not known until the data is - # loaded. They are declared "atomic" so the loader keeps the - # frame-major layout without reshaping to natoms; see the grid/density - # early return in DeepmdData._load_data. - data.add("grid", 3, atomic=True, must=True, high_prec=True) - data.add("density", 1, atomic=True, must=True, high_prec=True) + # loaded. They are declared frame-major so the loader keeps the + # (nframes, ngrid, ndof) layout without reshaping to natoms. + data.add( + "grid", + 3, + atomic=False, + must=True, + high_prec=True, + special_shape="frame_major", + ) + data.add( + "density", + 1, + atomic=False, + must=True, + high_prec=True, + special_shape="frame_major", + ) if dp.get_dim_fparam() > 0: data.add( "fparam", dp.get_dim_fparam(), atomic=False, must=True, high_prec=False diff --git a/deepmd/pd/utils/dataset.py b/deepmd/pd/utils/dataset.py index bd8a0bc91e..90a87edcf6 100644 --- a/deepmd/pd/utils/dataset.py +++ b/deepmd/pd/utils/dataset.py @@ -57,4 +57,5 @@ def add_data_requirement(self, data_requirement: list[DataRequirementItem]) -> N default=data_item["default"], dtype=data_item["dtype"], output_natoms_for_type_sel=data_item["output_natoms_for_type_sel"], + special_shape=getattr(data_item, "special_shape", None), ) diff --git a/deepmd/pt/infer/deep_eval.py b/deepmd/pt/infer/deep_eval.py index 37cf0d58d0..6eb708f5ea 100644 --- a/deepmd/pt/infer/deep_eval.py +++ b/deepmd/pt/infer/deep_eval.py @@ -556,16 +556,22 @@ def eval( natoms, numb_test = self._get_natoms_and_nframes( coords, atom_types, len(atom_types.shape) > 1 ) - request_defs = self._get_request_defs(atomic) if "grid" in kwargs and kwargs["grid"] is not None: - out = self._eval_func(self._eval_model_density, numb_test, natoms)( + grid_input = np.array(kwargs["grid"]) + # the directional neighbor list is dense in ngrid x nall, so the + # batching size proxy must account for the grid extent, not just + # the atom count + ngrid = grid_input.size // (numb_test * 3) + out = self._eval_func( + self._eval_model_density, numb_test, max(natoms, ngrid) + )( coords, cells, atom_types, - np.array(kwargs["grid"]), + grid_input, fparam, aparam, - request_defs, + self._get_request_defs(atomic), ) # _eval_model_density returns a 1-element tuple; execute_all unwraps # it when auto batching is enabled, but with auto_batch_size=False @@ -573,6 +579,12 @@ def eval( if isinstance(out, tuple): (out,) = out return {"density": out} + if "density" in self.output_def.var_defs: + raise ValueError( + "grid is required to evaluate a density model; " + "pass grid=... with shape (nframes, ngrid, 3)" + ) + request_defs = self._get_request_defs(atomic) if "spin" not in kwargs or kwargs["spin"] is None: out = self._eval_func(self._eval_model, numb_test, natoms)( coords, cells, atom_types, fparam, aparam, request_defs, charge_spin diff --git a/deepmd/pt/loss/charge.py b/deepmd/pt/loss/charge.py index 7c0b827a71..411232466e 100644 --- a/deepmd/pt/loss/charge.py +++ b/deepmd/pt/loss/charge.py @@ -114,32 +114,36 @@ def forward( l1_density_loss = torch.abs( density_label_reshape - density_pred_reshape ).mean() - loss += (pref_d * l1_density_loss).to(GLOBAL_PT_FLOAT_PRECISION) mae_d = l1_density_loss + # minimise the squared error, consistent with every other loss + # in the package; the absolute error is only for display + loss += (pref_d * l2_density_loss).to(GLOBAL_PT_FLOAT_PRECISION) more_loss["mae_d"] = self.display_if_exist(mae_d.detach(), find_density) + elif not self.inference and "density" in model_pred: + # the density term is disabled (zero prefactors), but the graph + # must stay connected so that backward() does not fail + loss = loss + (model_pred["density"].sum() * 0.0).to( + GLOBAL_PT_FLOAT_PRECISION + ) return model_pred, loss, more_loss @property def label_requirement(self) -> list[DataRequirementItem]: - """Return data label requirements needed for this loss calculation.""" + """Return data label requirements needed for this loss calculation. + + Only the density label is declared here; the grid is a model input + and is declared via ``get_additional_data_requirement``. + """ label_requirement = [] - label_requirement.append( - DataRequirementItem( - "grid", - ndof=3, - atomic=True, # the grid is defined for each atom, so it is atomic - must=True, - high_prec=True, - ) - ) if self.has_d: label_requirement.append( DataRequirementItem( "density", ndof=1, - atomic=True, + atomic=False, must=False, high_prec=True, + special_shape="frame_major", ) ) return label_requirement diff --git a/deepmd/pt/model/atomic_model/density_atomic_model.py b/deepmd/pt/model/atomic_model/density_atomic_model.py index c552118a08..d6df8e6f1c 100644 --- a/deepmd/pt/model/atomic_model/density_atomic_model.py +++ b/deepmd/pt/model/atomic_model/density_atomic_model.py @@ -132,13 +132,10 @@ def forward_atomic( # nb x (ngrid+nall) merged_nlist = torch.cat([shifted_grid_nlist, shifted_nlist], dim=1) - grid_mapping = torch.cat( - [ - torch.ones([nframes, 1], device=mapping.device, dtype=mapping.dtype) * i - for i in range(ngrid) - ], - dim=1, - ) + # nb x ngrid, row i is the grid index i + grid_mapping = torch.arange( + ngrid, device=mapping.device, dtype=mapping.dtype + ).expand(nframes, -1) # nb x (ngrid+nall) merged_mapping = torch.cat([grid_mapping, mapping + ngrid], dim=1) @@ -151,11 +148,14 @@ def forward_atomic( ) assert descriptor is not None + # the fitting net must see the same grid type as the descriptor: + # the reserved last entry of the type map + grid_ftype = torch.ones( + [nframes, ngrid], device=grid_type.device, dtype=grid_type.dtype + ) * (self.descriptor.get_ntypes() - 1) ret = self.fitting_net( descriptor[:, :ngrid, :], - torch.zeros( - [nframes, ngrid], device=grid_type.device, dtype=grid_type.dtype - ), + grid_ftype, gr=rot_mat, g2=g2, h2=h2, @@ -310,8 +310,11 @@ def model_forward( grid = normalize_coord( grid, box.to(grid.device).reshape(box.shape[0], 3, 3) ) - grid_type = torch.zeros( - grid.shape[:-1], device=grid.device, dtype=atype.dtype + grid_type = torch.full( + grid.shape[:-1], + self.descriptor.get_ntypes() - 1, + device=grid.device, + dtype=atype.dtype, ) grid_nlist = build_directional_neighbor_list( grid, @@ -353,6 +356,119 @@ def change_out_bias( """ log.warning("change_out_bias is not supported for density models; skipping.") + def compute_or_load_stat( + self, + sampled_func: Callable[[], list[dict]] | list[dict], + stat_file_path: DPPath | None = None, + compute_or_load_out_stat: bool = True, + preset_observed_type: list[str] | None = None, + ) -> None: + """Compute or load statistics, with real statistics for the grid type. + + The reserved grid type (``ntypes - 1``) has no real atoms in any + training system, so the standard pass yields zero samples for it + and falls back to placeholder statistics (mean 0, stddev 0.1), + which are then applied to exactly the rows that produce the + density output. When the sampled data provides grids, a second + pass is run with the grid points injected as pseudo-atoms of the + grid type, and only the grid-type row of the statistics is taken + from it; the real types keep their clean statistics from the + standard pass. + """ + sampled = sampled_func() if callable(sampled_func) else sampled_func + grid_davg = None + grid_dstd = None + if any("grid" in sample for sample in sampled): + try: + self.descriptor.compute_input_stats(self._inject_grid_samples(sampled)) + davg, dstd = self._descriptor_stat_tensors() + grid_davg = davg[-1].detach().clone() + grid_dstd = dstd[-1].detach().clone() + except (TypeError, KeyError) as err: + log.warning( + "Cannot compute input statistics for the grid type (%s); " + "falling back to the descriptor defaults.", + err, + ) + else: + log.warning( + "No grid data in the sampled frames; the grid type gets the " + "descriptor's default input statistics." + ) + super().compute_or_load_stat( + lambda: sampled, + stat_file_path, + compute_or_load_out_stat=compute_or_load_out_stat, + preset_observed_type=preset_observed_type, + ) + if grid_davg is not None: + davg, dstd = self._descriptor_stat_tensors() + davg[-1] = grid_davg.to(device=davg.device, dtype=davg.dtype) + dstd[-1] = grid_dstd.to(device=dstd.device, dtype=dstd.dtype) + + def _descriptor_stat_tensors(self) -> tuple[torch.Tensor, torch.Tensor]: + """Access the (davg, dstd) statistics tensors of the descriptor block.""" + try: + return self.descriptor["davg"], self.descriptor["dstd"] + except (TypeError, KeyError): + pass + for attr in ( + "sea", + "ser", + "seat", + "se_atten", + "se_ttebd", + "repinit", + "repformers", + "repflow", + "repflows", + ): + block = getattr(self.descriptor, attr, None) + if block is None: + continue + try: + return block["davg"], block["dstd"] + except (TypeError, KeyError): + continue + raise KeyError("davg/dstd not accessible on this descriptor") + + def _inject_grid_samples(self, sampled: list[dict]) -> list[dict]: + """Append the grid points of each sample as pseudo-atoms of the + reserved grid type, so the descriptor input statistics get real + samples for it. Neighbor lists are rebuilt by the stat machinery, + so only ``coord`` and ``atype`` need to be extended. + """ + ntypes = self.descriptor.get_ntypes() + injected = [] + for sample in sampled: + grid = sample.get("grid") + if grid is None: + injected.append(sample) + continue + sample = dict(sample) + coord = sample["coord"] + atype = sample["atype"] + nframes = atype.shape[0] + gg = grid.reshape(nframes, -1, 3).to(coord.dtype) + ngrid = gg.shape[1] + sample["coord"] = torch.cat( + [coord.reshape(nframes, -1, 3), gg], dim=1 + ).reshape(nframes, -1) + sample["atype"] = torch.cat( + [ + atype, + torch.full( + (nframes, ngrid), + ntypes - 1, + dtype=atype.dtype, + device=atype.device, + ), + ], + dim=1, + ) + injected.append(sample) + return injected + def compute_or_load_out_stat( self, merged: Callable[[], list[dict]] | list[dict], diff --git a/deepmd/pt/model/model/__init__.py b/deepmd/pt/model/model/__init__.py index 2c3a8f2284..6dfaac1af4 100644 --- a/deepmd/pt/model/model/__init__.py +++ b/deepmd/pt/model/model/__init__.py @@ -13,6 +13,7 @@ import copy import json +import logging from typing import ( Any, ) @@ -105,6 +106,8 @@ SpinModel, ) +log = logging.getLogger(__name__) + def _get_standard_model_components(model_params: dict, ntypes: int) -> tuple: if "type_embedding" in model_params: @@ -442,6 +445,15 @@ def get_standard_model(model_params: dict) -> BaseModel: ) model_params_old = model_params model_params = copy.deepcopy(model_params) + if model_params.get("fitting_net", {}).get("type") == "density": + descriptor_params = model_params.get("descriptor", {}) + if descriptor_params.get("env_protection", 0.0) == 0.0: + log.warning( + "env_protection is 0.0 for a density model; grid points " + "coincident with atoms would produce NaN densities. " + "Setting env_protection to 1e-6." + ) + descriptor_params["env_protection"] = 1e-6 ntypes = len(model_params["type_map"]) descriptor, fitting, fitting_net_type = _get_standard_model_components( model_params, ntypes diff --git a/deepmd/pt/model/model/density_model.py b/deepmd/pt/model/model/density_model.py index 7c24f7bd05..48d263c60a 100644 --- a/deepmd/pt/model/model/density_model.py +++ b/deepmd/pt/model/model/density_model.py @@ -65,11 +65,11 @@ def forward( model_ret = self.forward_common( coord, atype, - grid, - box, + box=box, fparam=fparam, aparam=aparam, do_atomic_virial=do_atomic_virial, + grid=grid, ) model_predict = {} model_predict["density"] = model_ret["density"] @@ -90,4 +90,4 @@ def forward_lower( comm_dict: dict[str, torch.Tensor] | None = None, charge_spin: torch.Tensor | None = None, ) -> None: - raise NotImplementedError + raise NotImplementedError("forward_lower is not supported for density models.") diff --git a/deepmd/pt/model/model/make_density_model.py b/deepmd/pt/model/model/make_density_model.py index 97cc1d285e..aadf1b3abf 100644 --- a/deepmd/pt/model/model/make_density_model.py +++ b/deepmd/pt/model/model/make_density_model.py @@ -1,4 +1,9 @@ # SPDX-License-Identifier: LGPL-3.0-or-later +import logging +from typing import ( + Any, +) + import torch from deepmd.pt.model.atomic_model.base_atomic_model import ( @@ -22,6 +27,8 @@ normalize_coord, ) +log = logging.getLogger(__name__) + def make_density_model(T_AtomicModel: type[BaseAtomicModel]) -> type[BaseModel]: """Make a density model as a derived class of an atomic model. @@ -54,15 +61,19 @@ def forward_common( self, coord: torch.Tensor, atype: torch.Tensor, - grid: torch.Tensor, box: torch.Tensor | None = None, fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, do_atomic_virial: bool = False, charge_spin: torch.Tensor | None = None, + grid: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: """Return model prediction. + Same positional order as the base ``forward_common``; the + density-specific ``grid`` is appended at the end and is + required for this model. + Parameters ---------- coord @@ -70,9 +81,6 @@ def forward_common( shape: nf x (nloc x 3) atype The type of atoms. shape: nf x nloc - grid - The coordinates of the grids. - shape: nf x (ngrid x 3) box The simulation box. shape: nf x 9 fparam @@ -81,6 +89,9 @@ def forward_common( atomic parameter. nf x nloc x nda do_atomic_virial If calculate the atomic virial. + grid + The coordinates of the grids. + shape: nf x (ngrid x 3) Returns ------- @@ -91,7 +102,7 @@ def forward_common( """ assert grid is not None cc, gg, bb, fp, ap, input_prec = self._input_type_cast( - coord, grid, box=box, fparam=fparam, aparam=aparam + coord, box=box, fparam=fparam, aparam=aparam, grid=grid ) del coord, grid, box, fparam, aparam gg = gg.view(gg.shape[0], -1, 3) @@ -114,8 +125,11 @@ def forward_common( mixed_types=self.mixed_types(), box=bb, ) - grid_type = torch.zeros( - gg.shape[0], gg.shape[1], device=gg.device, dtype=atype.dtype + grid_type = torch.full( + (gg.shape[0], gg.shape[1]), + self.atomic_model.descriptor.get_ntypes() - 1, + device=gg.device, + dtype=atype.dtype, ) grid_nlist = build_directional_neighbor_list( gg, @@ -153,9 +167,6 @@ def forward_common_lower( extended_coord: torch.Tensor, extended_atype: torch.Tensor, nlist: torch.Tensor, - grid: torch.Tensor, - grid_type: torch.Tensor, - grid_nlist: torch.Tensor, mapping: torch.Tensor | None = None, fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, @@ -163,12 +174,19 @@ def forward_common_lower( do_atomic_virial: bool = False, comm_dict: dict[str, torch.Tensor] | None = None, extra_nlist_sort: bool = False, + grid: torch.Tensor | None = None, + grid_type: torch.Tensor | None = None, + grid_nlist: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: """Return model prediction. Lower interface that takes extended atomic coordinates and types, nlist, mapping, and the grid inputs as input, and returns the predictions on the grid points. The predictions are not reduced. + Same positional order as the base ``forward_common_lower``; the + density-specific grid parameters are appended at the end and + are required for this model. + Parameters ---------- extended_coord @@ -209,8 +227,10 @@ def forward_common_lower( extended_coord, extended_atype, nlist, extra_nlist_sort=extra_nlist_sort ) assert grid is not None + assert grid_type is not None + assert grid_nlist is not None cc_ext, gg, _, fp, ap, input_prec = self._input_type_cast( - extended_coord, grid, fparam=fparam, aparam=aparam + extended_coord, grid=grid, fparam=fparam, aparam=aparam ) del extended_coord, grid, fparam, aparam atomic_ret = self.atomic_model.forward_common_atomic( @@ -239,10 +259,10 @@ def forward_common_lower( def _input_type_cast( self, coord: torch.Tensor, - grid: torch.Tensor, box: torch.Tensor | None = None, fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, + grid: torch.Tensor | None = None, ) -> tuple[ torch.Tensor, torch.Tensor, @@ -281,23 +301,24 @@ def forward( self, coord: torch.Tensor, atype: torch.Tensor, - grid: torch.Tensor, box: torch.Tensor | None = None, fparam: torch.Tensor | None = None, aparam: torch.Tensor | None = None, do_atomic_virial: bool = False, charge_spin: torch.Tensor | None = None, + grid: torch.Tensor | None = None, ) -> dict[str, torch.Tensor]: # directly call the forward_common method when no specific transform rule + assert grid is not None return self.forward_common( coord, atype, - grid, - box, + box=box, fparam=fparam, aparam=aparam, do_atomic_virial=do_atomic_virial, charge_spin=charge_spin, + grid=grid, ) @torch.jit.export @@ -316,4 +337,22 @@ def forward_embedding( "forward_embedding is not supported for density models." ) + def change_out_bias( + self, + merged: Any, + bias_adjust_mode: str = "change-by-statistic", + ) -> None: + """Change the output bias according to the input data. + + Not supported for density models: the output is defined on grid + points rather than atoms, so the standard bias adjustment (which + would run a grid-less forward through the stat wrapper) does not + apply. Overridden at the model level because the default + ``change-by-statistic`` mode never reaches the atomic-level + no-op. + """ + log.warning( + "change_out_bias is not supported for density models; skipping." + ) + return CM diff --git a/deepmd/pt/train/training.py b/deepmd/pt/train/training.py index 3d129328df..8e2327480a 100644 --- a/deepmd/pt/train/training.py +++ b/deepmd/pt/train/training.py @@ -2475,6 +2475,22 @@ def get_additional_data_requirement(_model: Any) -> list[DataRequirementItem]: ) ] additional_data_requirement += spin_requirement_items + has_grid = getattr(_model, "has_grid", False) + if callable(has_grid): + has_grid = has_grid() + if has_grid: + # the grid is a model input (like fparam/aparam), not a label; it is + # frame-major (nframes, ngrid, 3) and not per-atom + additional_data_requirement.append( + DataRequirementItem( + "grid", + ndof=3, + atomic=False, + must=True, + high_prec=True, + special_shape="frame_major", + ) + ) if _model.has_chg_spin_ebd(): has_default_cs = _model.has_default_chg_spin() cs_default = ( diff --git a/deepmd/pt/utils/dataset.py b/deepmd/pt/utils/dataset.py index 20a76a0e87..a46e213660 100644 --- a/deepmd/pt/utils/dataset.py +++ b/deepmd/pt/utils/dataset.py @@ -74,6 +74,7 @@ def add_data_requirement(self, data_requirement: list[DataRequirementItem]) -> N default=data_item["default"], dtype=data_item["dtype"], output_natoms_for_type_sel=data_item["output_natoms_for_type_sel"], + special_shape=getattr(data_item, "special_shape", None), ) def preload_and_modify_all_data_torch(self) -> None: diff --git a/deepmd/utils/data.py b/deepmd/utils/data.py index ab028e75a9..b464e4bcda 100644 --- a/deepmd/utils/data.py +++ b/deepmd/utils/data.py @@ -198,6 +198,9 @@ def add( special_shape : str, optional Name of a loader-defined non-standard shape contract. ``"hessian"`` stores one full-frame ``(3 * natoms) x (3 * natoms)`` matrix per frame. + ``"frame_major"`` stores one variable-length ``(npoints, ndof)`` + array per frame (e.g. grid/density), kept as a frame-major + ``(nframes, npoints, ndof)`` tensor without any natoms reshaping. """ # normalize key: "atomic_" prefix -> "atom_", same convention as _load_set output if key.startswith("atomic_"): @@ -541,12 +544,14 @@ def get_single_frame(self, index: int, num_worker: int) -> dict: # 5. Standardize keys frame_data = {kk.replace("atomic", "atom"): vv for kk, vv in frame_data.items()} - # 6. Reshape atomic data to match expected format [natoms, ndof] + # 6. Reshape non-atomic data to match expected format [ndof]; + # frame-major arrays keep their per-frame (npoints, ndof) layout for kk in self.data_dict.keys(): if ( "find_" not in kk and kk in frame_data and not self.data_dict[kk]["atomic"] + and self.data_dict[kk].get("special_shape") != "frame_major" ): frame_data[kk] = frame_data[kk].reshape(-1) frame_data["atype"] = frame_data["type"] @@ -708,8 +713,12 @@ def _shuffle_data(self, data: dict[str, Any]) -> dict[str, Any]: isinstance(data[kk], np.ndarray) and data[kk].shape[0] == nframes and "find_" not in kk - # grid/density keep a frame-major 3D layout (nframes, ngrid, ...) - and (len(data[kk].shape) == 2 or kk in ("grid", "density")) + # frame-major arrays (e.g. grid/density) keep their 3D layout + # (nframes, ngrid, ...) and shuffle along the frame axis + and ( + len(data[kk].shape) == 2 + or self.data_dict.get(kk, {}).get("special_shape") == "frame_major" + ) ): ret[kk] = data[kk][idx] else: @@ -894,7 +903,7 @@ def _load_data( else: dtype = GLOBAL_NP_FLOAT_PRECISION path = self._get_data_path(set_name, key) - if key in ["grid", "density"] and path.is_file(): + if special_shape == "frame_major" and path.is_file(): data = path.load_numpy().astype(dtype) if data.ndim < 2: raise ValueError( @@ -973,7 +982,12 @@ def _load_data( ndof = 9 * self.natoms * self.natoms elif atomic and type_sel is not None and not output_natoms_for_type_sel: ndof = ndof_ * natoms_sel - data = np.full([nframes, ndof], default, dtype=dtype) + if special_shape == "frame_major": + # frame extent is unknown without the file; keep an empty + # per-frame payload and rely on find=0 downstream + data = np.full([nframes, 0, ndof], default, dtype=dtype) + else: + data = np.full([nframes, ndof], default, dtype=dtype) if repeat != 1: data = np.repeat(data, repeat).reshape([nframes, -1]) return np.float32(0.0), data @@ -1038,6 +1052,10 @@ def _load_single_data( # Create a default array based on requirements if is_hessian: data = np.full([9 * natoms * natoms], vv["default"], dtype=dtype) + elif vv.get("special_shape") == "frame_major": + # frame extent is unknown without the file; an empty frame + # dimension is the honest shape and find=0 marks it absent + data = np.full([0, ndof], vv["default"], dtype=dtype) elif vv["atomic"]: if vv["type_sel"] is not None and not vv["output_natoms_for_type_sel"]: natoms = natoms_sel @@ -1055,10 +1073,9 @@ def _load_single_data( # For filesystem paths, use memmap for better performance mmap_obj = self._get_memmap(path) - # Validate frame-major layout of grid/density before indexing, - # so that shuffling cannot pair a structure with another frame's - # grid or density label. - if key in ("grid", "density"): + # Validate frame-major layout before indexing, so that shuffling + # cannot pair a structure with another frame's grid or density label. + if vv.get("special_shape") == "frame_major": if mmap_obj.ndim < 2: raise ValueError( f"The data {key} in {set_dir} must have a leading frame " @@ -1071,15 +1088,15 @@ def _load_single_data( f"nframes {set_nframes}" ) - # corner case: single frame. grid/density always carry a leading - # frame dimension (validated above), so no expansion is needed. - if set_nframes == 1 and key not in ("grid", "density"): + # corner case: single frame. frame-major arrays always carry a + # leading frame dimension (validated above), so no expansion is needed. + if set_nframes == 1 and vv.get("special_shape") != "frame_major": mmap_obj = mmap_obj[None, ...] # Slice the single frame and make an in-memory copy for modification data = mmap_obj[frame_idx].copy().astype(dtype, copy=False) try: - if key in ("grid", "density"): + if vv.get("special_shape") == "frame_major": return np.float32(1.0), data if is_hessian: data = data.reshape(3 * natoms, 3 * natoms) @@ -1234,6 +1251,9 @@ class DataRequirementItem: special_shape : str, optional Name of a loader-defined non-standard shape contract. ``"hessian"`` stores one full-frame ``(3 * natoms) x (3 * natoms)`` matrix per frame. + ``"frame_major"`` stores one variable-length ``(npoints, ndof)`` array + per frame (e.g. grid/density), kept frame-major without natoms + reshaping. source_policy : {"tracked", "default", "derived"}, optional How source availability affects the consumer. ``"tracked"`` keeps source presence in the ``find_*`` contract. ``"default"`` treats the diff --git a/examples/density/README.md b/examples/density/README.md index 7ea27e2b86..c3156997bc 100644 --- a/examples/density/README.md +++ b/examples/density/README.md @@ -39,7 +39,7 @@ The training/validation data follows the standard **`deepmd/npy`** format, with > **Notes:** > > - `grid.npy` and `density.npy` are required for the density model. The number of grid points (`ngrid`) must match between `grid.npy` and `density.npy`, and is allowed to differ from `natoms`. -> - The **last entry of `type_map` is reserved as a virtual "grid point type"** (e.g. `X` in the example): internally, grid points are assigned this type when building the grid-to-atom neighbor list. Make sure your `type_map` contains one more entry than the real element types. +> - The **last entry of `type_map` is reserved as a virtual "grid point type"** (e.g. `X` in the example): internally, grid points are assigned this type when building the grid-to-atom neighbor list. Make sure your `type_map` contains one more entry than the real element types. For descriptors with a per-type `sel` list (e.g. `se_e2_a`), set its **last entry to 0** (grid points are only centers, never neighbors); scalar `sel` descriptors such as DPA-2/DPA-3 need no change. The descriptor input statistics for the grid type are computed from the actual `grid.npy` data during training initialization. > - **Always set a positive `env_protection`** in the descriptor configuration (e.g. `"env_protection": 0.1`, as in `dpa3/input.json`). Grid points may legitimately coincide with atoms, and the default `env_protection = 0.0` would let the `1/r` terms in the environment matrix produce `NaN` densities and poison the training gradients at such points. ______________________________________________________________________ diff --git a/examples/density/dataset/qm9/C7H15NO_train/set.000/box.npy b/examples/density/dataset/qm9/C7H15NO_train/set.000/box.npy index 8d064b2261d7bc34cd79695e124ed67eeb9f05fc..37946ac645bcde9597b88a83300877841dfc9dc7 100644 GIT binary patch literal 848 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+l>qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I$72099snmP)#3giMVW^-0Y1|%@UKoNz{o+0Kqss<52qv3-Hi@}&S01{|S ALI3~& literal 10928 zcmeH}F%AJi7)Dn~>jD!IL$U>h1W~L;M?|7f$;Qq`ft6j+h{7564z8k7ZYxT+z_c^A zQ7PVZ|4cH)m;dE`>3BAp%nQ!JIm$pK%UJe=?1vrc3K>T6KK8eZC=QgqANuP=eeRQ$ zzf+&N-fA~p(QUZmBz`=l={emzF2Zwi&i!>QmTT4A_d)i|oLj}?pYH*Z5BmdOHXCpO z7jOX=W&-pL`k1*Bdd3&{0$5y06mHxW$uKY@dduX7d9FH%EcRA!jR$s diff --git a/examples/density/dataset/qm9/C7H15NO_train/set.000/coord.npy b/examples/density/dataset/qm9/C7H15NO_train/set.000/coord.npy index 4e5b579726efffa92e8944b1e5e66ce29ff12e31..7927d651638f90c5c90ffbaed1cb0f9610f15d53 100644 GIT binary patch literal 5888 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+l>qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I$7209AnMw&VbwF+bcF2(944&Kop9o`o0bog>@rGw|60}e}m?sMR@S?KWR z;c^GPX;U3ObFFkJ-dN!9u6ee@wd3s$Nr5H~EnaIJ_WPJQ^y&pVERf#eAj)0tP@v%C zuvO8*;ZT94!@N(~4#!qLcJLOQ?r@=9*I|ZkgG1V$RSr`P7#$h2t~*?4+T{@R^RL4R z`-Ki0Up6}&D*5Sf!G661Z{8^fSEgMKCnQffY}A|L5F@eG!Qj3I|W7Qx27{lN=ZhEOFT1GRc9Lfx*FS#{q}(jq(oK{Y?(4QHvcI z=W{yTHI{bBRo>$8?EioJ1qBrjycga$#BlpMY+$K!D0*%0V7R&8p?I#Z10zuX;<_>88X(fl=9{*0E-qxIKl{XW|M8Eqeqwhu?!&!hc|(f-$H|8%tf XK03ZJI{q^{J~ldjI68hv-uNm2Hr3nB literal 86528 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 literal 450128 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 diff --git a/examples/density/dataset/qm9/C7H15NO_val/set.000/box.npy b/examples/density/dataset/qm9/C7H15NO_val/set.000/box.npy index 2299ac43d95289816da6876c83888c5c6b88b351..05e520e22eb23c475be2f739f0466d5eaa92acc5 100644 GIT binary patch literal 308 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+l>qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= qXCxM+0{I%IItrGWItsN4WCJc{b5=(NBrwB35rxm5A?7&P)BphC=O?8A literal 2288 zcmbR27wQ`j$;eQ~P_3SlTAW;@Zl$1ZlV+i=qoAIaUsO_*m=~X4l#&V(cT3DEP6dh= zXCxM+0{I%o2099snmP)#3giN=pvK9$50)u7FyH|9{vYQQR#U+#?|AjaRfe-l4x{E^ c55Upz8BIT<`3o~|jOL5cd@-6YMqa)E0642=EC2ui diff --git a/examples/density/dataset/qm9/C7H15NO_val/set.000/coord.npy b/examples/density/dataset/qm9/C7H15NO_val/set.000/coord.npy index 832913a48de0ea5e075779e2841c8ede0436a20b..f6cea16e30f0db15419cf9768582791f6f18af02 100644 GIT binary patch literal 1568 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 literal 30128 zcmbT7_dk&D_s0?0*(2GTL}b%->`g{?R@s$JWkj+|Rw3&hGP74?kL)eV-Wef#R=z&} z!uS5|zJ9tN_v1XybzaZc>%?j4Yib)~Vt8Tra9P{9KXBucWag5#73bn(=CXBm^Ki3r zvT$~@w)x+=lGP)3n~QUIdn*^4i+Ao@H~E+ag+zGxnEjale-DAP*Ao8fpgSaW*k>hj zG3cT=q|)egxGf9;Oth4V5}CbOdBMJ>kMD4GleZcz;!Wvj`%ug(is}ni`qcruN&?^o@XJYtX;x<0s=@1 zZ|hS|`-^CX%N$#MHK5A3f+Q)v2GMY4y3lwG!{tHGNqTHD=z6VwT}iqG{rB>*6!j