From 71913a6988098d004a86e2ea7ca589ab98c71c32 Mon Sep 17 00:00:00 2001 From: <> Date: Sun, 31 Mar 2024 08:13:37 +0000 Subject: [PATCH] Deployed 2ca8d80 with MkDocs version: 1.5.3 --- .nojekyll | 0 404.html | 783 ++ analysis_aggregation/analysis_aggregation.md | 11 + analysis_aggregation/index.html | 1823 +++++ assests/logo.png | Bin 0 -> 255545 bytes assests/logo_white.png | Bin 0 -> 23245 bytes assests/workflow.png | Bin 0 -> 751576 bytes assests/xES_workflow.png | Bin 0 -> 484549 bytes assets/_mkdocstrings.css | 16 + assets/images/favicon.png | Bin 0 -> 1870 bytes assets/javascripts/bundle.bd41221c.min.js | 29 + assets/javascripts/bundle.bd41221c.min.js.map | 7 + assets/javascripts/lunr/min/lunr.ar.min.js | 1 + assets/javascripts/lunr/min/lunr.da.min.js | 18 + assets/javascripts/lunr/min/lunr.de.min.js | 18 + assets/javascripts/lunr/min/lunr.du.min.js | 18 + assets/javascripts/lunr/min/lunr.el.min.js | 1 + assets/javascripts/lunr/min/lunr.es.min.js | 18 + assets/javascripts/lunr/min/lunr.fi.min.js | 18 + assets/javascripts/lunr/min/lunr.fr.min.js | 18 + assets/javascripts/lunr/min/lunr.he.min.js | 1 + assets/javascripts/lunr/min/lunr.hi.min.js | 1 + assets/javascripts/lunr/min/lunr.hu.min.js | 18 + assets/javascripts/lunr/min/lunr.hy.min.js | 1 + assets/javascripts/lunr/min/lunr.it.min.js | 18 + assets/javascripts/lunr/min/lunr.ja.min.js | 1 + assets/javascripts/lunr/min/lunr.jp.min.js | 1 + assets/javascripts/lunr/min/lunr.kn.min.js | 1 + assets/javascripts/lunr/min/lunr.ko.min.js | 1 + assets/javascripts/lunr/min/lunr.multi.min.js | 1 + assets/javascripts/lunr/min/lunr.nl.min.js | 18 + assets/javascripts/lunr/min/lunr.no.min.js | 18 + assets/javascripts/lunr/min/lunr.pt.min.js | 18 + assets/javascripts/lunr/min/lunr.ro.min.js | 18 + assets/javascripts/lunr/min/lunr.ru.min.js | 18 + assets/javascripts/lunr/min/lunr.sa.min.js | 1 + .../lunr/min/lunr.stemmer.support.min.js | 1 + assets/javascripts/lunr/min/lunr.sv.min.js | 18 + assets/javascripts/lunr/min/lunr.ta.min.js | 1 + assets/javascripts/lunr/min/lunr.te.min.js | 1 + assets/javascripts/lunr/min/lunr.th.min.js | 1 + assets/javascripts/lunr/min/lunr.tr.min.js | 18 + assets/javascripts/lunr/min/lunr.vi.min.js | 1 + assets/javascripts/lunr/min/lunr.zh.min.js | 1 + assets/javascripts/lunr/tinyseg.js | 206 + assets/javascripts/lunr/wordcut.js | 6708 +++++++++++++++++ .../workers/search.b8dbb3d2.min.js | 42 + .../workers/search.b8dbb3d2.min.js.map | 7 + assets/stylesheets/main.7e359304.min.css | 1 + assets/stylesheets/main.7e359304.min.css.map | 1 + assets/stylesheets/palette.06af60db.min.css | 1 + .../stylesheets/palette.06af60db.min.css.map | 1 + changelog/changelog.md | 11 + changelog/index.html | 914 +++ contributing/contributing.md | 108 + contributing/index.html | 1137 +++ data_compatibility/data_compatibility.md | 13 + data_compatibility/index.html | 1392 ++++ data_converter/data_converter.md | 11 + data_converter/index.html | 1318 ++++ earthstat/earthstat.md | 4 + earthstat/index.html | 2448 ++++++ examples/intro/index.html | 2398 ++++++ examples/intro/intro.ipynb | 571 ++ examples/xES/index.html | 1887 +++++ examples/xES/xES.ipynb | 267 + faq/faq.md | 1 + faq/index.html | 849 +++ geo_data_processing/geo_data_processing.md | 16 + geo_data_processing/index.html | 1765 +++++ geo_meta_extractor/geo_meta_extractor.md | 14 + geo_meta_extractor/index.html | 1527 ++++ index.html | 1337 ++++ index.md | 114 + installation/index.html | 933 +++ installation/installation.md | 21 + objects.inv | Bin 0 -> 697 bytes overrides/main.html | 11 + search/search_index.json | 1 + sitemap.xml | 83 + sitemap.xml.gz | Bin 0 -> 359 bytes usage/main_usage/index.html | 1267 ++++ usage/main_usage/main_usage.md | 162 + usage/xES_usage/index.html | 1226 +++ usage/xES_usage/xES_usage.md | 125 + utils/index.html | 1307 ++++ utils/utils.md | 7 + 87 files changed, 33168 insertions(+) create mode 100644 .nojekyll create mode 100644 404.html create mode 100644 analysis_aggregation/analysis_aggregation.md create mode 100644 analysis_aggregation/index.html create mode 100644 assests/logo.png create mode 100644 assests/logo_white.png create mode 100644 assests/workflow.png create mode 100644 assests/xES_workflow.png create mode 100644 assets/_mkdocstrings.css create mode 100644 assets/images/favicon.png create mode 100644 assets/javascripts/bundle.bd41221c.min.js create mode 100644 assets/javascripts/bundle.bd41221c.min.js.map create mode 100644 assets/javascripts/lunr/min/lunr.ar.min.js create mode 100644 assets/javascripts/lunr/min/lunr.da.min.js create mode 100644 assets/javascripts/lunr/min/lunr.de.min.js create mode 100644 assets/javascripts/lunr/min/lunr.du.min.js create mode 100644 assets/javascripts/lunr/min/lunr.el.min.js create mode 100644 assets/javascripts/lunr/min/lunr.es.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.fr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.he.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hu.min.js create mode 100644 assets/javascripts/lunr/min/lunr.hy.min.js create mode 100644 assets/javascripts/lunr/min/lunr.it.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ja.min.js create mode 100644 assets/javascripts/lunr/min/lunr.jp.min.js create mode 100644 assets/javascripts/lunr/min/lunr.kn.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ko.min.js create mode 100644 assets/javascripts/lunr/min/lunr.multi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.nl.min.js create mode 100644 assets/javascripts/lunr/min/lunr.no.min.js create mode 100644 assets/javascripts/lunr/min/lunr.pt.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ro.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ru.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sa.min.js create mode 100644 assets/javascripts/lunr/min/lunr.stemmer.support.min.js create mode 100644 assets/javascripts/lunr/min/lunr.sv.min.js create mode 100644 assets/javascripts/lunr/min/lunr.ta.min.js create mode 100644 assets/javascripts/lunr/min/lunr.te.min.js create mode 100644 assets/javascripts/lunr/min/lunr.th.min.js create mode 100644 assets/javascripts/lunr/min/lunr.tr.min.js create mode 100644 assets/javascripts/lunr/min/lunr.vi.min.js create mode 100644 assets/javascripts/lunr/min/lunr.zh.min.js create mode 100644 assets/javascripts/lunr/tinyseg.js create mode 100644 assets/javascripts/lunr/wordcut.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js create mode 100644 assets/javascripts/workers/search.b8dbb3d2.min.js.map create mode 100644 assets/stylesheets/main.7e359304.min.css create mode 100644 assets/stylesheets/main.7e359304.min.css.map create mode 100644 assets/stylesheets/palette.06af60db.min.css create mode 100644 assets/stylesheets/palette.06af60db.min.css.map create mode 100644 changelog/changelog.md create mode 100644 changelog/index.html create mode 100644 contributing/contributing.md create mode 100644 contributing/index.html create mode 100644 data_compatibility/data_compatibility.md create mode 100644 data_compatibility/index.html create mode 100644 data_converter/data_converter.md create mode 100644 data_converter/index.html create mode 100644 earthstat/earthstat.md create mode 100644 earthstat/index.html create mode 100644 examples/intro/index.html create mode 100644 examples/intro/intro.ipynb create mode 100644 examples/xES/index.html create mode 100644 examples/xES/xES.ipynb create mode 100644 faq/faq.md create mode 100644 faq/index.html create mode 100644 geo_data_processing/geo_data_processing.md create mode 100644 geo_data_processing/index.html create mode 100644 geo_meta_extractor/geo_meta_extractor.md create mode 100644 geo_meta_extractor/index.html create mode 100644 index.html create mode 100644 index.md create mode 100644 installation/index.html create mode 100644 installation/installation.md create mode 100644 objects.inv create mode 100644 overrides/main.html create mode 100644 search/search_index.json create mode 100644 sitemap.xml create mode 100644 sitemap.xml.gz create mode 100644 usage/main_usage/index.html create mode 100644 usage/main_usage/main_usage.md create mode 100644 usage/xES_usage/index.html create mode 100644 usage/xES_usage/xES_usage.md create mode 100644 utils/index.html create mode 100644 utils/utils.md diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 0000000..e69de29 diff --git a/404.html b/404.html new file mode 100644 index 0000000..94f63f8 --- /dev/null +++ b/404.html @@ -0,0 +1,783 @@ + + + +
+ + + + + + + + + + + + + + + + + + +Insight into the earthstat.analysis_aggregation
module, which facilitates advanced data aggregation methods for geospatial analysis, enhancing efficiency and accuracy.
conAggregate(predictor_dir, shapefile_path, output_csv_path, mask_path=None, use_mask=False, invalid_values=None, calculation_mode='overall_mean', predictor_name='Value', all_touched=False)
+
+
+¶Aggregates raster values to polygons in a shapefile, optionally using a crop mask for weighted calculations.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
predictor_dir |
+ str |
+ Directory containing raster datasets. |
+ required | +
shapefile_path |
+ str |
+ Path to the shapefile with polygons for aggregation. |
+ required | +
output_csv_path |
+ str |
+ Path where the aggregated output CSV will be saved. |
+ required | +
crop_mask_path |
+ str |
+ Path to the crop mask raster, required if use_crop_mask is True. |
+ required | +
use_crop_mask |
+ bool |
+ Whether to use the crop mask for weighted aggregation. |
+ required | +
predictor_name |
+ str |
+ Column name for the aggregated values in the output CSV. |
+ 'Value' |
+
Exceptions:
+Type | +Description | +
---|---|
ValueError |
+ If use_crop_mask is True but crop_mask_path is not provided. |
+
Aggregates values from each raster within the specified directory to each polygon in the shapefile, +writing the results to a CSV file. If a crop mask is used, values are aggregated using weights from +the mask; otherwise, simple averaging is applied.
+ +earthstat/analysis_aggregation/aggregate_process.py
def conAggregate(
+
+ predictor_dir,
+ shapefile_path,
+ output_csv_path,
+ mask_path=None,
+ use_mask=False,
+ invalid_values=None,
+ calculation_mode="overall_mean",
+ predictor_name="Value",
+ all_touched=False
+):
+ """
+ Aggregates raster values to polygons in a shapefile, optionally using a crop mask for weighted calculations.
+
+ Args:
+ predictor_dir (str): Directory containing raster datasets.
+ shapefile_path (str): Path to the shapefile with polygons for aggregation.
+ output_csv_path (str): Path where the aggregated output CSV will be saved.
+ crop_mask_path (str, optional): Path to the crop mask raster, required if use_crop_mask is True.
+ use_crop_mask (bool): Whether to use the crop mask for weighted aggregation.
+ predictor_name (str): Column name for the aggregated values in the output CSV.
+
+ Raises:
+ ValueError: If use_crop_mask is True but crop_mask_path is not provided.
+
+ Aggregates values from each raster within the specified directory to each polygon in the shapefile,
+ writing the results to a CSV file. If a crop mask is used, values are aggregated using weights from
+ the mask; otherwise, simple averaging is applied.
+ """
+ predictor_paths = loadTiff(predictor_dir)
+ data_list = []
+
+ shape_file = gpd.read_file(shapefile_path)
+
+ if use_mask and not mask_path:
+ raise ValueError("Mask path must be provided if use_mask is True.")
+
+ for raster_path in tqdm(predictor_paths, desc="Processing rasters", unit="raster"):
+
+ # Directly call the processing function for each raster
+ data = process_and_aggregate_raster(
+
+ raster_path,
+ shape_file,
+ invalid_values,
+ use_mask,
+ mask_path,
+ calculation_mode,
+ predictor_name,
+ all_touched
+ )
+
+ data_list.extend(data)
+
+ df = pd.DataFrame(data_list)
+ df[predictor_name] = df[predictor_name].round(3)
+ df.to_csv(output_csv_path, index=False)
+
process_and_aggregate_raster(raster_path, shape_file, invalid_values=None, use_mask=False, mask_path=None, calculation_mode='overall_mean', predictor_name='Value', all_touched=False)
+
+
+¶Processes a single raster for aggregation into shapefile geometries.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
raster_path |
+ str |
+ Path to the raster file. |
+ required | +
shape_file |
+ GeoDataFrame |
+ Loaded shapefile for geometries. |
+ required | +
invalid_values |
+ list |
+ Values to consider as invalid in raster. |
+ None |
+
use_mask |
+ bool |
+ If True, uses an additional mask for calculations. |
+ False |
+
mask_path |
+ str |
+ Path to the mask file, required if use_mask is True. |
+ None |
+
calculation_mode |
+ str |
+ Mode of calculation ('overall_mean', 'weighted_mean', or 'filtered_mean'). |
+ 'overall_mean' |
+
predictor_name |
+ str |
+ Column name for the output data. |
+ 'Value' |
+
all_touched |
+ bool |
+ Consider all pixels that touch geometry for masking. |
+ False |
+
Returns:
+Type | +Description | +
---|---|
list |
+ Aggregated data for each geometry in the shapefile. |
+
earthstat/analysis_aggregation/aggregate_process.py
def process_and_aggregate_raster(
+
+ raster_path,
+ shape_file,
+ invalid_values=None,
+ use_mask=False,
+ mask_path=None,
+ calculation_mode="overall_mean",
+ predictor_name="Value",
+ all_touched=False
+):
+ """
+ Processes a single raster for aggregation into shapefile geometries.
+
+ Args:
+ raster_path (str): Path to the raster file.
+ shape_file (GeoDataFrame): Loaded shapefile for geometries.
+ invalid_values (list, optional): Values to consider as invalid in raster.
+ use_mask (bool): If True, uses an additional mask for calculations.
+ mask_path (str, optional): Path to the mask file, required if use_mask is True.
+ calculation_mode (str): Mode of calculation ('overall_mean', 'weighted_mean', or 'filtered_mean').
+ predictor_name (str): Column name for the output data.
+ all_touched (bool): Consider all pixels that touch geometry for masking.
+
+ Returns:
+ list: Aggregated data for each geometry in the shapefile.
+ """
+
+ file_name = os.path.basename(raster_path)
+ date_str = extractDateFromFilename(file_name)
+ aggregated_data = []
+
+ with rasterio.open(raster_path) as src:
+ no_data_value = src.nodata
+ geoms = [mapping(shape) for shape in shape_file.geometry]
+
+ mask_no_data_value = None
+ mask_src = None
+
+ if use_mask and mask_path:
+ mask_src = rasterio.open(mask_path)
+ mask_no_data_value = mask_src.nodata
+
+ for index, geom in enumerate(geoms):
+ geom_mask, geom_transform = mask(
+ src, [geom], crop=True, all_touched=all_touched)
+ geom_mask = geom_mask.astype('float32')
+ geom_mask[geom_mask == no_data_value] = np.nan
+
+ if invalid_values:
+ for invalid_value in invalid_values:
+ geom_mask[geom_mask == invalid_value] = np.nan
+
+ if use_mask and mask_path and mask_src:
+ crop_mask, _ = mask(
+ mask_src, [geom], crop=True, all_touched=all_touched)
+
+ if calculation_mode == "weighted_mean":
+ valid_mask = (crop_mask[0] != mask_no_data_value)
+ valid_data = geom_mask[0][valid_mask]
+ valid_weights = crop_mask[0][valid_mask]
+ mean_value = np.nansum(valid_data * valid_weights) / np.nansum(
+ valid_weights) if np.nansum(valid_weights) > 0 else np.nan
+
+ elif calculation_mode == "filtered_mean":
+ valid_mask = (crop_mask[0] != mask_no_data_value)
+ masked_data = geom_mask[0][valid_mask]
+ mean_value = np.nanmean(masked_data) if np.nansum(
+ masked_data) > 0 else np.nan
+
+ elif calculation_mode == "overall_mean" or not use_mask:
+ mean_value = np.nanmean(geom_mask)
+
+ new_row = {col: shape_file.iloc[index][col]
+ for col in shape_file.columns if col != 'geometry'}
+ new_row.update({'date': date_str, predictor_name: mean_value})
+ aggregated_data.append(new_row)
+
+ if mask_src:
+ mask_src.close()
+
+ return aggregated_data
+
parallelAggregate(predictor_dir, shapefile_path, output_csv_path, mask_path=None, use_mask=False, invalid_values=None, calculation_mode='overall_mean', predictor_name='Value', all_touched=False, max_workers=None)
+
+
+¶Aggregates raster data from a directory in parallel into shapefile geometries, optionally using a mask.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
predictor_dir |
+ str |
+ Directory containing raster datasets. |
+ required | +
shapefile_path |
+ str |
+ Path to the shapefile. |
+ required | +
output_csv_path |
+ str |
+ Path to save the aggregated CSV. |
+ required | +
mask_path |
+ str |
+ Path to the mask file, required if use_mask is True. |
+ None |
+
use_mask |
+ bool |
+ Use a mask for the aggregation process. |
+ False |
+
invalid_values |
+ list |
+ List of values to treat as invalid in the raster data. |
+ None |
+
calculation_mode |
+ str |
+ Determines how values are aggregated ('overall_mean', 'weighted_mean', or 'filtered_mean'). |
+ 'overall_mean' |
+
predictor_name |
+ str |
+ Name for the output predictor column. |
+ 'Value' |
+
all_touched |
+ bool |
+ Include all pixels touching geometry in the aggregation. |
+ False |
+
Exceptions:
+Type | +Description | +
---|---|
ValueError |
+ If use_mask is True and mask_path is not provided. |
+
Returns a CSV with aggregated data per shapefile geometry. Utilizes multiprocessing for efficiency.
+ +earthstat/analysis_aggregation/parallel_clip_aggregate.py
def parallelAggregate(
+
+ predictor_dir,
+ shapefile_path,
+ output_csv_path,
+ mask_path=None,
+ use_mask=False,
+ invalid_values=None,
+ calculation_mode="overall_mean",
+ predictor_name="Value",
+ all_touched=False,
+ max_workers=None
+
+):
+ """
+ Aggregates raster data from a directory in parallel into shapefile geometries, optionally using a mask.
+
+ Args:
+ predictor_dir (str): Directory containing raster datasets.
+ shapefile_path (str): Path to the shapefile.
+ output_csv_path (str): Path to save the aggregated CSV.
+ mask_path (str, optional): Path to the mask file, required if use_mask is True.
+ use_mask (bool): Use a mask for the aggregation process.
+ invalid_values (list, optional): List of values to treat as invalid in the raster data.
+ calculation_mode (str): Determines how values are aggregated ('overall_mean', 'weighted_mean', or 'filtered_mean').
+ predictor_name (str): Name for the output predictor column.
+ all_touched (bool): Include all pixels touching geometry in the aggregation.
+
+ Raises:
+ ValueError: If use_mask is True and mask_path is not provided.
+
+ Returns a CSV with aggregated data per shapefile geometry. Utilizes multiprocessing for efficiency.
+ """
+
+ if not max_workers:
+ max_workers = os.cpu_count() - 1 if os.cpu_count() > 1 else 1
+
+ predictor_paths = loadTiff(predictor_dir)
+ data_list = []
+
+ shape_file = gpd.read_file(shapefile_path)
+
+ if use_mask and not mask_path:
+ raise ValueError("Mask path must be provided if use_mask is True.")
+
+ with ProcessPoolExecutor(max_workers=max_workers) as executor:
+
+ futures = [
+
+ executor.submit(
+
+ process_and_aggregate_raster,
+ raster_path,
+ shape_file,
+ invalid_values,
+ use_mask,
+ mask_path,
+ calculation_mode,
+ predictor_name,
+ all_touched
+
+ ) for raster_path in predictor_paths
+ ]
+
+ for future in tqdm(as_completed(futures), total=len(futures), desc="Processing rasters", unit="raster"):
+ data_list.extend(future.result())
+
+ df = pd.DataFrame(data_list)
+ df[predictor_name] = df[predictor_name].round(3)
+ df.to_csv(output_csv_path, index=False)
+
process_and_aggregate_raster(raster_path, shape_file, invalid_values=None, use_mask=False, mask_path=None, calculation_mode='overall_mean', predictor_name='Value', all_touched=False)
+
+
+¶Processes a single raster for aggregation into shapefile geometries.
+ +Parameters:
+Name | +Type | +Description | +Default | +
---|---|---|---|
raster_path |
+ str |
+ Path to the raster file. |
+ required | +
shape_file |
+ GeoDataFrame |
+ Loaded shapefile for geometries. |
+ required | +
invalid_values |
+ list |
+ Values to consider as invalid in raster. |
+ None |
+
use_mask |
+ bool |
+ If True, uses an additional mask for calculations. |
+ False |
+
mask_path |
+ str |
+ Path to the mask file, required if use_mask is True. |
+ None |
+
calculation_mode |
+ str |
+ Mode of calculation ('overall_mean', 'weighted_mean', or 'filtered_mean'). |
+ 'overall_mean' |
+
predictor_name |
+ str |
+ Column name for the output data. |
+ 'Value' |
+
all_touched |
+ bool |
+ Consider all pixels that touch geometry for masking. |
+ False |
+
Returns:
+Type | +Description | +
---|---|
list |
+ Aggregated data for each geometry in the shapefile. |
+
earthstat/analysis_aggregation/parallel_clip_aggregate.py
def process_and_aggregate_raster(
+
+ raster_path,
+ shape_file,
+ invalid_values=None,
+ use_mask=False,
+ mask_path=None,
+ calculation_mode="overall_mean",
+ predictor_name="Value",
+ all_touched=False
+):
+ """
+ Processes a single raster for aggregation into shapefile geometries.
+
+ Args:
+ raster_path (str): Path to the raster file.
+ shape_file (GeoDataFrame): Loaded shapefile for geometries.
+ invalid_values (list, optional): Values to consider as invalid in raster.
+ use_mask (bool): If True, uses an additional mask for calculations.
+ mask_path (str, optional): Path to the mask file, required if use_mask is True.
+ calculation_mode (str): Mode of calculation ('overall_mean', 'weighted_mean', or 'filtered_mean').
+ predictor_name (str): Column name for the output data.
+ all_touched (bool): Consider all pixels that touch geometry for masking.
+
+ Returns:
+ list: Aggregated data for each geometry in the shapefile.
+ """
+ file_name = os.path.basename(raster_path)
+ date_str = extractDateFromFilename(file_name)
+ aggregated_data = []
+
+ with rasterio.open(raster_path) as src:
+ no_data_value = src.nodata
+ geoms = [mapping(shape) for shape in shape_file.geometry]
+
+ mask_no_data_value = None
+ mask_src = None
+
+ if use_mask and mask_path:
+ mask_src = rasterio.open(mask_path)
+ mask_no_data_value = mask_src.nodata
+
+ for index, geom in enumerate(geoms):
+ geom_mask, geom_transform = mask(
+ src, [geom], crop=True, all_touched=all_touched)
+ geom_mask = geom_mask.astype('float32')
+ geom_mask[geom_mask == no_data_value] = np.nan
+
+ if invalid_values:
+ for invalid_value in invalid_values:
+ geom_mask[geom_mask == invalid_value] = np.nan
+
+ if use_mask and mask_path and mask_src:
+ crop_mask, _ = mask(
+ mask_src, [geom], crop=True, all_touched=all_touched)
+
+ if calculation_mode == "weighted_mean":
+ valid_mask = (crop_mask[0] != mask_no_data_value)
+ valid_data = geom_mask[0][valid_mask]
+ valid_weights = crop_mask[0][valid_mask]
+ mean_value = np.nansum(valid_data * valid_weights) / np.nansum(
+ valid_weights) if np.nansum(valid_weights) > 0 else np.nan
+
+ elif calculation_mode == "filtered_mean":
+ valid_mask = (crop_mask[0] != mask_no_data_value)
+ masked_data = geom_mask[0][valid_mask]
+ mean_value = np.nanmean(masked_data) if np.nansum(
+ masked_data) > 0 else np.nan
+
+ elif calculation_mode == "overall_mean" or not use_mask:
+ mean_value = np.nanmean(geom_mask)
+
+ new_row = {col: shape_file.iloc[index][col]
+ for col in shape_file.columns if col != 'geometry'}
+ new_row.update({'date': date_str, predictor_name: mean_value})
+ aggregated_data.append(new_row)
+
+ if mask_src:
+ mask_src.close()
+
+ return aggregated_data
+
ic^Y`)=tym$0WC98!Kxnq zOU)**yXAPIFmQD*yvi 8k;A2Lq+C_mYCulJX1JGRu`1AqvsuXl9}LyVPgZ7qCrgnZ=kG^ z`RO9B@ini3slYH%*_twR2=O<+P}BgFz)C8VIYvT2AK!qyqM}}!jVMELlI}?YxDZ#s zDpP;Hf3-Kxk9&2W&)G5M)<>f%Lw_{%M 2HUY84j{Uek9%GD}widgK~R4ib%+O4e2yZ4LH$28_m>SCuy&5T5l8%fL-qm)TA z3qzNADT~u24wW4#n(jmITjzzX@!$PFSwI|rmoHq)C-sGx@itN57$Vy{Tz0R+*~kCF zYYKe{9jGq5?iMf0o2)KyRW=Add(e5$D8_G(vFa41N=?dsze*`{n*7n=wPO>%T|BuG z(n>HMk+Nfh0*>+j{dLP|i}F-163ZN1efl#^1stTBC)l8$+kMFD3D3W%1icyp?JD<* zN-3nk7}M$uwUG9A^2xEZ>sNsLvCR<3ofc+J9vGCAaDyZ{W2ExA)JUV^gMzY5hxhFf zn033%Sl`}xaD1@C >0QB? zZ;$ew2gJs^KVm(dSELt#QK!fB#6imal#7m?>BM|%f9QX`abnu7jxF@DNPjVr9SAR$ zhDZg^$*@Wi|CS*DSXb1pdR+ddHyDVD;Fx!#DZraOr*&BJps#t_7w6_c%;dY2=zGa~ zSj=7%=isU{brN4(_hs% 9n-)s`uUk5UbPUx;?@2ue dwJUWE?-IyprcvN`3{INOhAquLL)_JukPJS(4hROsa_;}AXQ`RiPX&4?Y0e1I zO3A?G_Bo|(SYTEo7O6*R6Y?k`D5AkuaHCogo{dbGnEZ*x(QPurGh8oWe$j;^3n~qf zl*%A~F{AQehy=&(Ce|(i6QuGzoJ}?Z<{zHkFuO6uIfK-QaNvkQvEdmk{ppNaplo_L zbyS%_9(1g~qCedtbY6e6Uq#c4=cKNXbmx4bYt#~diDX>gt(q_E9m2Mk@Id(Z{)gWC zxlPrgTCZ-;iX``hZ*wSZnuPvV$GPuE1c_SZp@O_gZhqr!^C0Z+M41{vC15Iu8t}t< ztU$q*WohA89jX`VC2mO)2JLt~aaEJ}g8nP06}1%%s5Ac_hWC^Z3>1M2O8F60VFPw# zluH9i96zlkLW5@T0S5{CoJ~~J0#j<|CN~Sn42A=T7`8e&BR?jI5KyCJJ~i;aIQ^%7 zGX3qhivZX&omlSNhuv|dK5Q}Iwtq>501I)QBJ(=eAvE=;D$R2*_xF82x(1BQ1&fsg zOH^73Ag7d5AEA}YLWqi)rH6?ui9EG_VLhhTz)Hk_DB;!!lt|YT&Tsp|UdJH;KBEuD zEr0pmk2@|*aN*IY9eu7Zu9uQMb@H9usJO&A&yLudWMjG{p_D@md@!@k0OB!sJ3U`;L#h3?nWPP(o5>C2=npNM=@`zqR!q7s7fhg^w*Xk z3E+Q6?#`2vkqCqZ#F2WTzbMG@s(L=e99l2 Jz1$X`d_F`Dk?*n`p)Wnvzl$~7*W4JY;H`BSWuV>aBt0NsQ#V$*wX5h zP&H8y;|<=uc|1jrLoW3F&uJlA tD7c5`KraWXZ+k2h=^H zKIJb9=JA}074WE3v{=U8>T^ml_%AWs^Qy8*;$xrR43uS#WdX7-^6CQ&GrJ7QiC=&S zOJ{I2u`w&&L XUVZq9U+2hyba{4co`bNof?6cx=c4ORS!PmW_<7i>_-i7 zr%s)&e*VZUAypncY+<2Lj2Q`|PYAvM>Qko3cyd*tPK4{pwQp@~cRd~jis&^oHKZ~- zeBkGG-rxA0#f`T)@8ct(!NlVxQlN^EsZvlx-ccPZl}HTLg*{6pZs0)rZjJJGVQV=d zr&>afOTp+tn_eebPurp=go5!6xkfeP&%WpTQ=8X|YxU-z!YlRd+K_z_ifEZ$0@40V zWxJ52z!lI?Y53j8G3$!EZYEt|QtrUZWR}VipPEfo7UAd0sG+WW%f*jCq8!Qu?luF> z(K-a2&9eC=LY@?2)?yA7pjh@iznE~y0=nP7$m`EgWzFpReA!h8RpU*1XWv*?tLgJj z=Ky~TJP8s!qHh@oUchZ4ypuiRZCPL?6Mz#BMhBD?u0`m_>v3(=M;TnUK85QptoM** z$$s4>fk)aa9Z*TDB|2y1yA0|0K5|g=CSv@>Q}E=>aDtO2-CLT6gp8cDLulyJxd?uz z f }ftxb_9k%mIa0BS41D>l+kQ>GjJ zIz)0rr&8sfA=L(&=*AU0E`KXbSmYvs<=VVVdBVRr#ULQpw ~~6A^xt|jc cqpe);!S`x?ar~>=bEW#&E&VMv cbAK~DEz_H{9{KW4 z`7r5u`+RZANPrc}_J>(vy+C0-uDYH )+*vLkC*ke#h}jg1U~)cSEI_rmwjeRh8*P&zHqg(fKZDLayU+aMM^ov z(Ggq27puciHhSfpfwnTSZ0?5H!&yq~1fxX8D0kQ*T6cGM0R-)q;V+m4s)ldoM(=R} zmZi2FILQJ80NKe398s}r`GDW%Dgsxn6b`;p{<+N+d2hYaWvbihDm{ShB;{uAT=a&A z-Q7C85fL)iG1fQ+ucQo*8r3RL8XaOnXhY>p9Lo&!l>0ZFdX3D*(5#u`teR31J)<)f z zK-t _XP4?!*fNqf#^nMl zEX @RI*tHSn{QQ*A$|BvRrc YN2@W<`)Ir3q_bzWof;KShQcm8XU2!1q0;{kC1zfMI_>m05s4%T$ptj~zUm_Loeo z%@F_>3`wC<%NSAc<(m-cP20wBo8sXA(WM|~R6}j7o>)`fd!n_cxSLm2v6wh&CLVXB z1W4&Nu|U?%G1o@X#cA8L+mA-y+@3iR8*XX&9^bJPsnZ=@h+yH$MXtbk_Dft??1JQ^ z?o~eT)};G2-LaUP2s;`(@1VRY{*RBrb!^Seylsu%IVBnAKYIGUqmC(-KKh?L!H>9E zkvAxP{@-cxR*~FL2i7<*grxW}*biLu`L5Qua+VUs<(4}{smp Zw3w*f+EjzC*bV21AH1!$Z}Z zznnKvFn3~VK0Yl7#be}t1_$4Wc=_ }2qjcH{+*~p$864_ylFRU}6s#e{k9wSN(Fas_fJDM{a3Fx5ciSB+N68@mA413sh zXLLrZQ^X|wJOBbhSafMj`yj#zEN6#F5Dk4sD(skHric>(vW(TCF5zY%)Xc*07}G)s zz*;BMiJd~V({y-ZbRZ~ssVWu8&N$$EBNCtp_-;=Tn4(a9rA`qVPLZHat@zFjVFv4L z6`C(h{wG>8Wu1EPe66zau&ea+JKV7@h;@RaKT=Qx!%?(Puu*{s#Mw+SLp6NQ`BYon zwV{#H)NNBwvO1kApXWrS)A`QsH8x5=`zNBj4XfrYm0(&N$-xg3{~v?Gn(Uf<(y8vr zmCy4gqkmW=Yf9gcURl@GB>fsR#8>&O*krbX-_b7=U`YOGzSY!g!J6hiSyW6jvW~2e zAM?f2#~;&m^_Ni%Vp9ip|D<@Xc+t?TcFZDCrCXAAblWs=_Dl^meoCZets{ gd73h1KrjYU@w)6ApMrfs3Sk *6{8YyksciSI3yTH5tp!W9y2#$jXEG8bCVmNJ`AsRc5pH`!LdZ z)-sx*G$H(ob(O24A4>UWI`*>qftNteaG(f;sjA7kI*M~Edl(b~`L@^f5u9>;v(YgX z0lLr=>Ao5(VxSR|iv~uLStPiHP`P6BC%caQNEW e#&G? z4Nsb{YH0Bmm1KIGDeOWeVHc>Z{LY8Le^akyG``-DmFCMZjD{hvs})CEM9WjK#UOQJ zwQA-_p};?TbU=-0T17u~t}vDuDuk`c{>g~g_poblR~_d^wL{v=*XErj3$?va5P`v| z^d&T$`dVG3Y_?$a#H`w00URwN7@Fa@qKhl53b=YLWY{1ydu6$7k=XrL@;Xd&VK )jx`_auBDL*GrQ2MXaZ!B5sp)ViRVV!qyFLYundADvcA)ijt z4@StZWGrn3`wtwRiHa%+#k|iBbj4eo+alaFsgs@^NXC-8uokq;@W|oWbj?0%L9pU? zx3m=-1@3{;xSTQ?Ctx#$g-7Ha5nq8?HSZ)h-cOp0qlx(Jv$kMBDD*In$|A_uV{Q1E zl{hMs=3CT}hlG-y5l~uIH>FT~dYD03Pd_|_QZEfFSe`LznhqtBn7Y-i^IAlnDXQT- zu`gl~E)P}=WbVf}as)!`*3Z5XxKM*@#C0nkV2DZ~D;^%hu7f+j&w6~E&)cmh?&%e^ zqbeKN8Ig{Q!C;k$e0p<8dz-7|<=5jRn_WqzMo;(ui0Is!diT?dW{I;dtnbR$<^C5b z@~)>(P@%M`O;5pe!#Bcn(zTv7X<;Vk$3YuL5q3+N3YxEOduVHD+)op^;u||&5eQsE z`xVrg`7B{WgWeOKvW%GqwoP_C#74bpLg&Qx2f6lHPQTeB^CN+YV679dEvwR(5+549 zG}9b=aA|de0&P~Ve3Rqn*;NHFlvChDTj0dV4*Dbky_)U)fSHWqoNRf}n+u&Dlu%R< zW7g|cMTtfkN9u`+_dD73+b(5q2s@KORFO59e^$fJQWy(b!Ec;S?T`6*p7iv-BHo;M zINun#czqK$#cZJ2i=<;}5qHA8XuIYLm)hy@zn!Bo?tT#VJ3XGNt)pf3jqUe`lywYA z;M$DG1t(z%k5x~kHKaHr=m~c MKkWKt}#5+??XV>NcLD?zUGA8cFS%&G--- zNmalTN1v^=Tf!HXjoNSA&Z=|fOGyk=ep8Ubg(VQ}28Ss!R`7~6DgCOfloNp^5K%}J zf<=))m9q>w^59s BQ``JQfXR>lEDg~qJH6El1Ioq?F~^N!~Ho|+0R>vFHhM#_)->R z1s`u= xW9ykY^FB8&z*v3{W-(3LG!&^8Rh^wb4)5AxVBXPQdaB;89kuSv0a!vZ=h zL$|3y{fuaGLjpl AVO+y z-mZd(M*bv=PovsnGKt-HkzYp#yb}18sY11A)D#`Qw8VXy6bZYT6u3!n_=t7%qjtj8 zeDi`MZ#`G)JVPcg>S&L-p-mo2@b)@hk-u5H$({86Ii h8R^YJIGngchp+qJT2Fy!Tg4Ij-zj kQ>gvGU#}x ztGbebmx6_u#RPf=v5Y&JBf0M$CHWZeqA*1VQ{>McZ853a8&2=SD^N0wyQI^(cVCxR zbcpE;QwW@}%?fp}40&a0x`2XLE0RVtFhcrZ0!QBwC_T$5qKYJ@+`ZPM$p;Z_Cry8d zaUuxSt46{x_6|RJ(?&PexNFUIOC(hWW5m5}T*bD0e{OhPrX?>H?uz!)EFCeD&CYv| zjJS&GdDMW4G%993XN&FhsD|z7Oa%yKSvBAEWpyL@_hINH5k8)lUI6hjZqTe$^P1PB zMa|SceZ^G9mDTn%j5$)}TCbnp?i!R;I(I2VW3X3aQZ5AB1iQKklSUT`pneZxO~W!Y z8HBJG^T }K&&LNp5;qDsbo1g8@UJz z%q*0H;hl@)myn}!5H{ICKxE#ni#s^nG)=xJ=Qw$j9W{z_EmFpSTF(Mc!Tw2;4g_@( zO7_1tog}E~$|k0F+}XJyA13V5xCC%b_Ycaj?Zay&z4222GPH*`Sveg0zMCxm3R}~$ z2OqkD8eT*~WdWfy> uzJKL%pbE*X|tw{ zi#P;w{pRsQ6wq(y4Bf#G_)`@0026O?>>gCf_TLRb(^dHxth{EiHIvnTUQ(zbPs~qV zs-X-`rq4{%h9v5e2vwm4Ol`I&{&tL3bxc5oKObgL1ULv$aJ;oS(N3MohpgGt?lc*> zUweEx8 u+mmbzBA7Y4C1H2?J{Ty4a-9zvwP3j|VBq_fHR( zmX@BA#)SiEb5xKO4qDTgGMCU@8%GbvF#g(MG$2}4iRHvh22f#Y({srphe!>8SqzqM z$gPw2cl&70)wbYu3`QM0pIArmFn=qdr<#0GdThIy+MN-9F>jBEDxN#I!Kzj#jKGS{ z6Falxb6g#YeOQ;Bi~jw@6#wb(Y2@r;?r%4~x;1G-J^={L-~810v+!~?Wx6OLM7X%$ z=vM*>umv=fUfB(|FF2#Cl7Q?6dgA0RH9#MU@Of6!EV6AQYaHc2aAWnh_13`sB
u?Q7HHiq9c?ZnBoIVn6-(y48^QGAJq#lZ)PuVSKuF(%a1K( z8UNZt0P56&GdO{aF>vcqiE(QB5J2*1F0iDs8AH9&Mkm5JhZsxd)*+S4LdP^EGN_pg zmS}tenyS+Bz*rL#c>~|wJE+to<4;xau&NC3NFXNUzd@cR^{Vb3c%#*;pn&ev nj^hRJM_co8 Gj7I?pA5^(U3v^ngO9vUG- z^I5>>naiQ zLAsxzeln3*7x3VtWa-PE>L%|H*Lzv;(FHTDLoP1!%0>jM$8YU({$BH-16X0k{bXyd zD1}r=Y{jy`P}I;PS9hF{p@wm76C_G)pmmQC+ss;~N~r*=>{}`ou|nZz?dysaI&A3I zFM|Em51X V3gY zOiXpsMpduY;0cx0{*hMCqOLXSs+XovF&kL|lUT?Nt^{)sXGN+vnQJlW NL#TAI!~{%~1CXDmB7d zP^lEIM7)JX?1LIB@(p+AFWN%+yFcJ9n6;_h(q~dZC3QuVssbmUyYHp~hNE!0`h`k= zl#{rl2BBnLRnm*+sb}6~cJ#!@z*XR`8jf1=y~2d k`&O_u2YliIl)TK``v`@vya%T>iWO`glZ8#0R~vcJK*DeA zk6JOiScFbYwd0wbS}oSuuJfcHzgR8~P{tusi#3dl&Z#%0+Ni|%xmuLrbgYF FaAC`s#%hE{kMP5*#hBSSswFO+uFT$|2ByLp(=> cTxHyCUJRy1XV#sYS$Q&*Kxcn{Ov;)zMTTip$XBF<8~{k*p};#x~xM z&PrL-t1ZGuLA}feqbr&LrW;!|70NJjBN%!uLt@E*#h0mKGu?+65$OW4y*rs)F-HDC ztN!ElC=|n){j2y0CPZ576mPUu ewN~&J4PzWRHT*v(!X69 n3QN)h^{jT`0{%bb z;=6+e0&g6z|7i%t>qJ+3#7#Lo!jeC3TeUgXy0=AmD{wf31k@^mlRF%t71)YFfw74F zF33fG$m&AHQLTrEw+$)jm}Eh~jhFPj=GO%DcSG=z6+=l@LgNC`fgN3{z`FP9kFCZf zJi4ISAVa!=r{k%hp1e-qlcfKRE)e;O`#bx?7P#* zF!a5QgQb0Z=j&H68vw8lFqj@3HPhY(D03M5RJIRFen^=96xO8ol|!!V9uC4w=g2A7 z2q_0g>@d0hx~eR`GKb@_M?F69o1gd(6mo-6fgfk1sfFx)aOBaU oB|sAeUz_W;XE3ivX4Axlo#!;)PElK? zHm0(Ao?*K?&iF!uR2K6s1DBJm@~&u%zHi?MRCKuf3-^C&C+cY`cPv7t50sQ&RypQ3 zn`@fCN(UwWD9EB_-yadecEW8QuplhB4jqxFohi5aL}^S_;#UWR!=e%^M&WxL!~87_ z<(u~QOoi;=QC;t9{E?13CD)7TkN)!89nOnqx(CN=0&)>Wsl9Kyl@9#Dcd^ Wr zHSRpX!cQR>Hq?BX=n=br$`}a;!VxGPg3dEmM{-ur&3gfv6=O96MU^ivgC!IC#VLx% z+c-=i%`yThGm5Kb_Nn)E7R!FT@i)1VGB)$N`-^y=!AvRIxXo*$#6vHEDR39?dTB(Y zLm7Y=V5)*{ QREtjz z_lqG>eMZOd)o#+_&~=-dY+N $tG@qE&aOQ5#Z(!lJTOV&8Rnvg%%v_*-7K=gPJA44Kw?vS&m?DcQi! zyn8A(gF6n~Xj2 1D}V7M{%9+*~r(+f64YGCG83P8EzRWzSCnXXh~yV*2#>G zeC{Sa0Ea?Dx12aBicM0|1qjr*I?7j1-hVFai cv= z=k0Zg&*H46IL8dC^=9@ecKAq>PS>&-mZ$&T0N$;aaCulI_sB;E0 R|e=NaaMb1Ah%V5sU)@ zA?DaJ_0WWr5?MyQ#FVNE3`lBP2}5*vF^HS|@Y{?kB~RYbolk2rVku8n@p%x$Ib3xu+YX`-UAq#4ft8XO-h_tYz1K9^{|O;t?DEH=Vk-4y^T( z!=2z{+GiMpwanZNkyTXJ;(h$#Ct{#@R| R-A;X9h3iMVFm=M z3H}%O|MX3vL)IbFNQ`)tk8&a>Lq0zR4r(X2rSlo0qvx!z)i<(Tcgv%4w2yc%Ji0~7 zZe!)?o$aV3xv HQ zUCCYljff)=(}Kf1cnr5LF*-529LIO<@A-kT_?ttw|HlI(Y!(zK5r}G2agS@r>Z`G1 zKs-Ro9{rsFjy>S!%VXAqf25rYqPLBtJ`L@6hdB9M7ozl!aq$@~`GqGpi`ab_r)|Z9 z%hwzBueZG >40_lhLub&c)w$UM#_X=Ovlxm?i6&zqwuT!`_=vRt9OS6x2BR8X zD!TNwRSppJuNx_&VitKs!X56HQl>CcsGyN%3CJwumQ_FHdDr}9Ag>8=Ppp{{mO3om zb 4^`Uc6?4PZs0l`X4+y)^(T|b^c`|_eUUu zo#GKorIngScmdmXD2DO-XlmyR@x_5k0J*CGDy&gl+1d=3BYuljy$b_xfIN|y{~(^< zo|171e-kzV44fX6BV%_PQ-3i1{fIT&`}dE3e4rvw>8E)gnkRO}^31h6w(20GAj==I zDEe3S^_e;^dYQQC5i5NCAE5^?o%IjllyK!&mTJMp1=7dEe~lr$b^**#H_3fd#1%t1 zvY`3>DRhfH3|O;J>RNeIfui3s`}1@C{u^Ut{>(tArh8POOaip%5*O|&)<(4J2nItV z#vJX-PH64LdA=3=?%(S_7*uX+>6;PyQ%mql@Vo`)1SC?A2_ zc|@7`qSq2wOp!EGN+}ndfTxEw089WE{A38LL})Ieq92IlBC5b$Xq#hZ)-GA@Gp~ov z=!d3Mz!n4+vLri+BDBAeg=}+Z(N&CX%F^O=6fz_^q5_Ks+V)(2y2~LzIhC0d6ho4P zGV2w?W{@u676g6P$v9CvKcyb!go95F(rs<4ohElXi*FayBX!+KtgD#iVS_&G+Og zc=|=;8I>1~I6)IsVG;~ZoE&u?v|mn1_}3fa1o`(uwSIEKC6Lj&Mc1WNl?U8OH;1Ch!xsbp8Lwzd@U_(i{CGJ9502blw2rc v zYG~8QX&(H7v{! an{X?S%eMSyr|2L5^Fv-(W@7#OuK)z-J#~!8;~L>&5%>xbQ@5)}^{G{MvrG=n75NA#0PR zm-nBaf`Gin9~Rd~2Ca;pH02=o-6zg2l?IPqWbV-(S3Wblk%h$;Bef$M?vnClOaKwF zrEi5%wt<@n-#-Zi_=zr*jw&+8@)21Ps9=bBHO}Z-G4ucNrlJlFqzLC63P_ZDJ!8CX zwD( oFV1Gii@X)QADWCNKOv+Avujb-=z-Y6v z6=4>? Ue~IkiDlw@W^|RSGuH5si;uN{Do@i~W+kJ$o{ylc zh3Z}63qRy_L%>WrG5XW`EOESCp$kuclET;q$=%ZD6f8-QMr#Zrjb%51%>X@-RKCT{ zS{DOWa;++A)!nVH|G!3mQHie@)hqsG_TVZ8XDR+Iox2jNecNmf ObMc^*g6J z3g?g`V31jLzHGBm6}fVdGm7}k{eWt16>HljDJ;5sJrP&;d!bpiG!d+v>qFd2oBNB8 zM %4n2ap ;(xZ#Q(9{3Ed2+hQ~zRH;>dxKd-O!%vFk#~Ev%hc?Q@ z$S8+8Qd0te=C2br`_Q+T#byCIr;v{*q+IlE`(B%G)3=Qo<)K~qH!){7w&aQHe{9{C zZQow($>K}0X)1hOt8XgvSlmsJ5p}9Na_i|C-7^A6qZYLAvR#GSwvi4ZDR+kN$3Y?0 zO#AJ46#y}s7hlcfXGI#h-Rxms`83Ok$;p``xBpi1D_vcA#uB-r5=!Q7+YP^3SrOa5 zS5z?WGdtrOEu5HZC&%i4CYH9N;`Pqu;e`M?BdW3xditk<)s=N%NwKk6D`KnlS`*^= zs}-ZY`y`bz*C@{YXOKBq6t*kQOkgSQF1Jb;r6hE@H+pGTFaAZ3P1hUaXNE+$8?{_y z6fWvzs%!O9g`4-$cmZtVQcR3xOi0{wr>Hjd7kRvI^H1-FC7!(7+HcZ;{9f$Zl(qI< ze22~lxxLVQl09857w`vyjB!$gl)LhQC0FI9hvgMQfoHdxh2BB}#*UOSm`M>=A(N E21c);;vhx#y;{z^Y)}FV7z0axhMu`NYD9nm0-DHG2-p^6e z=0G!z7M9EZVW(OSb!*Q6-hrtS(Q+^BD~;xP0=_LN1~0 zFEpvOq28ex9PL6DWemS`*=nKCeB+v f+KPrJl zR7(T2x;yIa@C)HZ#0I=j|6yvw8THbuvVLzc+(>vjTJ#dF=+8fc%n8@GO$_he=ccE~ zkaUg+%l`X6c2f}+vp6ZH6LR9<;LAVs!7z0)mESu1Yv@bA3s0 ak3?{Zy=E+Fs^;Ms^;Zs({IgtkQCW2kUcteM(+Ql$1=W%I)2ROK%XO-7 zN7c`_nZ!c%c5ti`cS5)!!HFz~;^o6y59__PEM9%)ALJ?~a0%u6FB=aRqP)DHE&d*A zh?2coYlx3W`k(oAT76JWKO)N{eokab`(wBJW3}dM!|KG`4>5>hXUoK&Kb-T%oLEX9 z!euo=Po63#d2YFGWQ4St$6LovcBxk3#qa!j;SCr?6L6dcIX(Zln~aY04yM9&3(N?e ztmO^L+`Llm&C|8|IH}s`$LCYDaW>dO3UEj21U&j~$t?M|>^?gi{;i)A;XM};&V{?~ zV^@S64+Z-sKf|g?!N9T?s0ID`-iz+J8Gh={P*Mi xmFsj6sx9H1{3Pv z6NibIIQ#Vw22KBPsd+dF)To;{m9mhOdamRz3>(?1Z%|old0Lz|6shb@BfvHi;35g! zZR^1S0ws@SHZ7<{1&ymuMo;33T4gYxO+8k8@}5J9&ySZZN=)6-KD|v|cI}i&oRN?( zy}e!P=QJ+}Xfz8L+xj-V=%WV(imG^lO_SB4gNeU7>|bZGTV<_*Jy%Q&gB}o96jTJ9 z&!#5#8!lL6Ux!(XNDo9gR#5e^iU&~RAva~_8l@oWe?m*C^yR24<#>ImQ2xEre_(!s zgcS$jfk;e7{) A>Q> zu>Ge3I5LqzcJ{Q^#z>d< =BsW#$Q={^!#emh k$vRhg6$~3#PWab+u9y0+V z(;QiAL 4wf^R4KKrDr>(_78G0XFoEJw_p6U+Wlbr; zDRb8A1&dh}kC7=y+5AKKZcOTNoMuYGrAn|RXy8m4wc^soARr Nh_egZtK`UKgv4{AZo`6cOwAPlN4;T|6T{z|*?wjN&>L TMz)| zIa#(=OTb-SO@ >34{4i_v+1@ZqSga_p>=s|^x z7o20RV=h)y+XmMzM;^Y`CB|^C##_9_Dyz3I{_S04p(FR1_NO5GvJsK*_UW;v;U70q z4^H# jU&ZuX_g=kJ7 1xVF!LqI+FXY~kk zMbG3H()*A8H+$vHSP@jtvQ)3CDP@vtM83kbU^-LgS6FiCw_saW0{jEr2Ww^bRHjvfcm8G7=){VKe z{*)YD{ gpU{Ff#vu z$B^A0 o@^cJ{s+Bq?z3RcY3%lNeHo03F)Q3pd=Y1Mf2^WN zqmmi@aV#mQh%s?b42m{&Q46>Xl(151o>R42cBY+VY?S1@a~sWK+$d$$Cv1D`!?05O zO#ZvwxZWrOSeLMm-e|JYSXR jSNNMI z8L{%D{gc)I>Df=^#VpB=pY_siu<$aenoC%T?I#6}OQYOp`#C#tz5YE@YsSWZ@0AqI z9u-txpE=aT#Kt9Fx8g-#tU2>uJPy5N^l<{yKJvQwG1GXvE}q4vt{v77vVE<7eWkH& z_|Lk5WppVGeFJBh69~PMqCn{jf~#9v!cYS;Ff0b|D02 z#LG)bmNs(Z(2{AEAIh!=zpReFr(2Da_Z)b4Ol5XVLW`#lUrXE1b9_}id)D9XZ{Bk+ zE;>FVBw@q9VH3MG%vSKEmHipBDpMJ4%qwwGNOt*|IyY4HM^2I>IIbQ(xN}uWfJCKl zWW=99Y(V2hb#_C2`h{0amdUnm#qY`I@Z @n8i&5QZyR;lBI#1tX6A u^#lAw9H;jt7 zAR1~B62N&iIQ>6byN^p{;-jV@^=iw%L*~Shxbvr~kemc*$M{Ss6?L|K8<>sJuul6` z?*Wa8B{OI!=#mpV7`X6BzRKnYp(!L1Tn3GYfV~cCy*rCE`Lf2d!ka5y>C!VAs)td` zp*$*tZA_iq$=uN?+6`aMJaA}Vd8HTKZ@Um!+bPgP$B`1Qh1Mq;5*I1a W=5IfDSM`#ZT()2Qg=>iv;ntS zJs~Z;HD80w6eFU6DN^ a$y`l5@@g>l?t6rJK%9Po L+oI1*p zLmvG1s{-Tw>5wu7;pjJ0a<{RDt6R~x!}mUc_J_}6TXd>`psubi!IY|R-~6B?Xtu|e z{U&sAJH1bLmZk?;Zl`8y?>zdBXlrHzM9VpX7XwjzIDqx2>?8=7F_FjiiMzy&ujJMq zeB>$0C+6bg&^^Ii#CQSMjqYV6NzINVZrP!^? (7H{nHL(Hd~r^r)q zU=}Rp)m=LT% ^)FvzM0ZDomB(ZQdWy;O{ExS@=kXm2878sKRUR^`R7Eo(Ak!}C0`uirO& z%E+GsfC`)3IPS;)=LKkJa193)3r30MyHRZsrk4504o`Dkss_9V?D|iA55 !YMdGk6N?OaL-*hTdas5vue$~K&hIMgFA44;y2vFg^LTyRjn2qq-PiDTS05I z61tCPYnat`YxeFU{{8T+sE1vk1%7!)*q1W0OsdbW7=j8lpE7H+5IB6geb$>~y 2%rxB2&L zSMhfVQO2>$oh8%c&`QmA^~KvHL`gT_CgnCwBZx`nwv-UUS-F&viZYfx*^pUda4F7# zh;@$BSg+SJA-0UE#&MJjdJJ<~a!Fy1*>7o>MzpmIUo?)fy|@s4lhEDMN{MjKQT=3ha#%go+fXU|zSqt)j)AoJx|r=y?G zV7<^TJ0+3-dKFRVY>Y1m&A`ZmS3km|&pt|MG^&$`!M o|^BTQLPUJ9$>h!pifi dGD^}pNY8mckC;*kaWsayYH`l}KT4~=5Bx$5apu@{ zT}M)&F)+Z=H+*q*7r+1A-^81{*HaOwGm$zeQH7b=TJ!jMa a*VMj61mDD?| pGgIp{gqC zuEob74UmGiYv~ppAqGMW^y9!{cZYr)=% bIu3dE4rbcT^@CjopVt~U{FCH#!$KlZ$ALHx;bGSM}+lu|8m3Xy8g;EBk3|d*N zsqj9cbwypbC=5OY4%bKDKDz1e#gx83kW|$+RBgjBjr7C7=q6|^=liQX;xF-!fARm| zH!nZHfFdb{CSro8PLiOe=d dzl+tJgm6AR_Dv#Hm z%UtDGAN&;_x%? 55s`!ncnjULj;9GfGFR}V)`aqL(`bJ~SH-`{*LlASplZeBO>iO_e zg7>6+eqN6k@!XP&Qc^JJz~ynxN_k?VaarZFUHZgnf1~H{Uif0g7C)whHii%aM@L84 zj8gins3{wR!Yi3oGt AH5CiMg8l@Bm2M4pcT?r%f zImx+vUxSw*$FA!*JUGA@n=`#MT8mZwYIP(Ixz^4cneA~`Q3!1}b0@11g@>UR)Fyb0 zH7u5k?Ca7?C}E6rog_@#s$y~zSFT>=%$YNyMD$@+C^k()UDa Qa_baddoD4 zippA9dmNtSU1zuwS8!LuKmXPLi{E(mLtJIVDTOt{>$#T6=5;??ZcpKPS~sqnnrq#A z@4cUe!+3er?KUame{#LZ5*dv85D3Nrit}9H-+c6!iDwd_c2sSR3xSmQ1MQ-{S8Mg3 z#Slp;ptV99E9!vY#R!SA7zo_!qBv8IZXy98#Ch@bAy79Ki1htHS9R>w3!)2jRZH{{ zr4xxnN|8j&O^e4GOWcC-qfWCOxT&l-WNvvdq!e=uy~Ngg=an&L7e$NW{{3+E!ddgY zxR$5&5~~No2UXPJt*H0|A;hn$Y-J>*a)UbDtby2!h;DWnI4-5tR+K6+1d+|37&Rpo zk6AzKlt}sSPDifBk%yjrg1D%e2s6h@DS4(@^^#RWI;vx{^`zDOvy$rrl1N@&zsr1+ zx~@qiLK1~fNQo|I^~4lK*`t&oEV*g0RyHLre~0U;$p^N1uD J~q11JuURw7r j%j{Qr8Mhtpy^r?`m0k?Z;l~e z4k3OLrEwuL=FzoQ5lqA^Yd-MN`xt!Sm9Kma4Hb!qBB1h-1EiZUCuX&fQa9&VoYpn# zhky8ofm1T=i&ifdk|HIi^%Oj9ZMn)3kL*9n{ZBuL--$$yP)$Wtk-Dz`Vhr&I2It>w zwSp96KHD@5gX}0uf+`%BMaC3C8&M_{$4Rwqn=j3S-Klx};-@*&>~L3g7UyLLJWd1T z``PTh5MxBwqWD1_?}H1HBJ=B!x@tG@b>2M|;#`cejw*hQPJA2aCxHDI<*hxf&voqq ze+c+mt#w`O+qcn_n~im@XPJMa5^s-y(mG$nuKzqqNv{%>ASTWTod4+gC#ZHhhBz|$ z33CDfiYY-RZQe>1Z 4C8b1FNVYME`)d^C zk+BkMp|rezbuC#y<2cfFqB<%~iuWF^E!8Zq7CU=mHUWgTl5tbN7Ou*A9EdTpyR*w` zy_( !LRI^=hy>FByn^2mn3+OKJvMm9kqNygDQX2)HN_kq3Ly<-T9 zjN8Ps>G0@~#m -CzDaBnjg+Q{FfyhUm`W>#sp2-$Jqc}G-^P}gn(&!wvvfxjo4_C75 z&!lmTvGavIrNrPiq;%&TwLb35QGAMYMnJ5o@fp<-L{iVP=xLgAXrgR5eDD}8&5ki5 zZFVutDjreq7^cb5bsgSs8Un3_Ft4>Dgow396odKS3;(5UJ65YB+P0 )_3+5zW0bzO0Ew4z&d)K!i5j#b~Ilw!HFgH}p- zC*w%hwoEy+v1E&FH#179(67h8tCae?i$(W%2$6oZqONO(VW2ZD=N4yp=8-3O`|IAs zw|(_D^Y-?&>>-AHjc#SMqeK}rf5uy%*Y>$#;j~$K9yOz^H~YoYM&;&pJ$29RHYz?Q ztg#Hv<10x%{ Ti*15VCAp>kUD0dl6T1 z`~&baz~4wIe*AaUZ#q38KM(7HaGwI+0{jSqsI>7W4ehlWm2KWbxXJSMd>R#yMms79 zDWY`6BkQO6#Q7(QjbhRP5HFLYHi^n9iF7&mfT?AtfAaW!$|yukOm4~q^QxE~GP-Ft zLQ65Bl0Np`E!Ooq^Lezbh4&FRlK*4=EXGJ;a`q`2hG}k!oO75wUP&<#g2$M8cBL(9 zoQ;x4P#$Bf*yS5b-FC!S+^XZehWMQ2W3)tT2+C851Fa96I1OWk9}}aXO3I?NV(15! z%LU%cT2!nKiu~JXE%N3RXqtw8-OnWAaU6-6R16xEo0Ni3rHmM9WALM=ZQK8Ib#(OK zjpO* dB@#vVuuEkprXm=%eBwHljzE+8tC@x zRQ2;B)$@@cZ|2m2qyiB!7g9RmiKNOgG4gW{{UXok1EwXU+G47j)oS?TyJznBNwoQ{ zY4nhEHmOoGl W6&$)dZl2WT@C>WT@c5tluX@PG5{wUW;);+Dyi@F2&W572dpXqJa z_POywHc%z2s@%#ssZ&I!NF`JSD&6pmyTYd~ohP*wqXBP}oVyvluvLYvDyn+p1ESKk zo2+867($?HTa=Rjx5myUi7`ZRb=B&c8;owTpv!!-Vdx3DsVEZS?JS{~8wY^H!^0U# zvDVJWjrglX@q!7Sp&yR@8G qHH)reXGc;R zyqleLzpJY2pFDf^jz3;TS#>Qc#@##5a_MNFNhe r-GNXlVS z#Kwq85tHdnMH6(gfq5~EKfh4xluY{q>ZVP~O`7LO5`vaeprMZ=XvGz-^6L-3kMrRQ zy%})9F}kS&{%YH{_r{doY_$QEXTS)2JdPu6*Ub%w*~;eFc9z|Sn~gDqJoYIwYGVvm z8=ATm!zrVg#tDrgx ~=dO?;)g_*mu3JVEMwzb4sR0d2=?$6lcGe84}+-!~%E~ zq^GWi%b&c%+ PnOGW0kWzMijii{cl@$y6t&3%;F(W6ovSMK{3FpK69D=At z@sr4i;)%oECc6UEO$VerPLjuvMnY@=f^&@1G!tS;YPJTjR+=M0RE=2S$3$H>Oq1Jq zr-YcvzJZj$xoK9`gqX0_uv)EV2isv7W|?#dG873>#$8R*5PV=9WS!DlOU_sbRCP_? zk25*8 +^-5ua5AUy=I{Fw`uX|9MahzCBj #pQL$+TaVWI|P6r|K< zg*$nM77WpxA}hC4g-m;js65Yd`L bbKfuUq(6_h z14;+FMe~N*sK29={?V#x@Af`0g@CCIrZya{R;WDg8OQNhLsDYhQ;e)vt7D|v@;f@4 zwyEs5U`&N`VRod{T2nO^hofiU!um1;1Iijfb97 !2B{!&Pn*6&$$nUz25IjET1oiz$U5l%>4~c0C93AyJ -qJ%X!;c=CehfXtFARlyU%>mqx}& z$d}1V9iRUlm^}~x y-prXbIe}z2i(DMDSt7`T=^1(wYV_-YK zM@nUDgv=p9$#aSgeqym$P}dFX^_sSA0cniJaX@P=mIhr%@PVqbIRsJ9$8L>b%qhvU z`X>pAIHrv1W =~JvANC&5?iD1B0Y~W%_A*iqyg;vo){x-+hn6lGjGP^ z*v;?h`~G!GsV9^+Ps%x>K|$R$91bfSfyqz2|9$W0p10n^*=mo`4_G6P-74LjG#m4q ze7fVhah)P6&$B$>Z*f<5BmY8`;RkIh4w?AC{sX-CvEOFBbf`uVqbDi8BP#t9&hXtq zYiwhvYeQXYnpzXwh>Dvz^s&d!>VRPwXuD2Kq%xvXthkR^Yuio35u-<&qJWU4E2_wP zToaPRnaB`FeA<|2$pR^-)3qQ^I6glIG6C<}@6dI;G %@>VEJM__KSh66opS|R& 01@by} zcX#L4QAoKZ->X>lmq5f~`dB2=W#n7gYCaZYEQ`gGVHk2ufF^`&FqxaY;>;UjoSQ?X z^{h}D$C0|O+27yKDj-AO_bivvH&2tB8@FkiSS*&`J$m;OK85d4#^93!4RuqoySt>S zG`h8{b`(GP&;JR({_IByww94yUe07Jd3+^2iMab0&CcTGU#E@AZPfE|8!Ql@N}vlG zkwjTwm13V2?|bHheE7)+IWiOVxgCZu5=eheS@RR4o4&5DDtv~2Q{GwiYe^L?aB|82 zaL(bqpKsRMJPS9RyYtQrrG{h9k!81LvMXlDF!0H$tVLPNlsp#?uQ2H#W^VfVT{sGH zH_dbYTY8MUf&T>f&w)E{`$ fwXOP19zyJR7_js?76o&do|jmG8e=tueXz zQA)Ay` %DAO6e#m7o3Cds!m^vNs$1&nEop#q{2K zdDp2t`4%ex6X^yC4{)uwvnT*m#)?ydO2dkttE~9dNB 94g_y(
eJ(U(>7%(?1#lqSe!+IR@yjRVOnbCS42Q_teeO&jnT{{zU zV~DivV&iX6&FG-AeMHhs2xCypDU$z5$cKL`{kci1}TJB#wu)ZOrD1cSD>P#WD)o zp1Z5(j0WcBDFUA~=$`<7`VG|^4{!bnp4Mlp9*p 7{H{hbmHs079oaKf iOP%#AVH5VmacwH36)T02`P6vFQ?43PAkz&sy=QcRPR zbax*)JUpCH8f}ck33$)$?k=nKn&o1_!NI{MzbI~k2X}V%m_|>xSj^4NFbo9mS!7Tlt0mO#pz)8h^CoW#u5CKjkq$3WMtQ+e`jR6si4o7 ``$@NdE z4T7`rO_7`2$7jz4AsE`3KXZ-J2r=`|1K;+Td*nqME1cE~s|Vx#OW@mpKM(PZyhPU+ zm4FyAwqlGPN8<7Id7d2(8Iq@uBjE-|p5j*Oa8{Gtth% 2=( zo2y8CO;+R?YmVKD^mg6%)U{mv1)Z?-@f4|T8AX+Rplf9v6-7~1Z5o~!6VoKwJ&VOc zI3zJ $Pqc^SFXRXx9_S_`7$G6J<+E+vo0dqPHu z$8qHFQ1&LydyKXCAWpP0@(E~NLE3nz^y@VT2M2UrH*eI+acHf%diAOp*Eu(5C8?Nb zt9myC|06MmA3uBcj#s;Bl6VAbsk)ZKX~4A_w`2I(-+nLu ?Np{l=AqR;=&w*Tk zcoX pS!~y !{vCy zBhNm~LFh>qnx;aXG($;xb9)|3XBm-zL`77#nq|8w3X%fM$Y;M^&!L~oogF6ckKKyN zW79N*7zMfUp3!@BMmdUHxFk4xFH&QzpDUks&Pn#yIHG3-PL(YK%rV7a(=^#lR^-;h zFkp?Pu4@S!%}r5V*Q{5otx=Wahyk*Js^kmMA3 z{>QAX-mzFLsVd8}&s>oA+&Lzd*n7jPc;Dln;3t3PpK_6jiJ0@FBz3tUEZd{QQnz=V z`NFGH)z1y;IVaC;Q8$J8U7D0hC)NyH;4;7Tz`x~*)u*w$4Py#K;@7uL`$Owt{YSJ? z)Rm>G#HKoCZGM8xpqDS= XZzmyCJ;^(&hbl@W@$n_Eh=zIjH-G-&z`D{xI-Y5PSUkGoKy%{JGRg zMJ61|7>@8fa`h>$#vW%Q@?W^-IH&weX(oUzj@7nTQ9S1N5mO|jqCyGtpCDtH5aRrD zbRLDOEHN(RQiYy59XhM{`a$w_q{*mqmX9DXVkGC;SuSTXt5RDd*b{G`Rwj=~HZth# zu~v+U<#I7MKQU&vkVHm@;YsZ9BiIZQC#oBiWvYuI;#d z AuE?+j5F_~Z0M@G z7By4TvA4IE`F;Uw?Yp#AuOEi~iInu?ySqEMK^n%vPnfzvcQsF4c!tNGd5o`k^E z?C07*naRQQ9OAD?A3k#4z*^X?BOKmB!M?AP18NsGA)H&w;q>WHT4&`EY-g^X6) zN|Zq<2~;{}n`tM}=#{NlA03rki+Pq^c5Oy$NI@*Qb5wiZuLbEaVm%#5q?qzfM@V&I z%p_1VL1FvIyY6}uuiyP5f=}4E6^E|%bL`5Gy aA>jLguK;Qg4# CSMUJWy!rymA(mdjbS zD28%!EZzqei*9cC>RM#Td%I^DN0-g&((KbzxOgg~L{(i$;(PQ=ZknIdjUG38c6N8^ z`yS^UJ3BiB?|;pC_oG%-Kil_fk} NFQ @6|?sl}3reASHql_tuc*ze;JDiz+?O#nF0p(j3Q;x@|~acqL8S z;Bq=?S!BgVy1~2B+*DNAL!da^?(XbLm|Dtik}*+dS!4+u3n66Yzhz33M8>Oz-EIei z!EAd7sOuvtz&sz`_K7(DekZnf<%*N?=J{s^xLc#&1WZ@Ml}}v_m-;)*sVL|(SsxGg zs|%ceg;MH|Ax+Ack((5NmoB1`2s#p!<)Nb|cxKq=C{3W#97>p!?0&C*Imwwb-VsB@ zR@H2p1`-5Vnv(fE-Flz|nV%w70Y*zyg>!CJ-8D@MnX}clt;l^dYEe}c(>RI6K{kpT zhCz_X>>%qy5F~=cI8HQmD~(b1E|HwDNZWNn)X#oQz)VivR^v@>Vwy(kTGoWVAH=v$ zso707<_%3jOsYyaIn1a`WO8|J(v}b+O;cyI#nHA6UEAU&S+5ErRP6ReKD?L-vt4%L zP8qE#J}%P~(D|Bm=FAz6j*b9D(+XKO_&~eph}oKdnx)-BGgCs=B6aTlV+& zX`1@=tJUhA<1k(Ay6&Sc1d>X`AOz;Ub7$$No-0=_@x+r)@MUlQQX+v`Re3$U@p*gd zUc0G+sNA&s_|?1D-1q56`M?vOz%&)R-IC5!H@n;CbzN67b{ma~{J$aqkEAF0jZc1n zi~cgpbGuBFr>)xexZv(pinnT|(K&l3knk!JQXnZc+ijPp_IY8`N)d@PZ94~x#TaPY zHoMJA)L{rR!ZF5*(x++WIka~pRaK)DtX69h*`k{yBcco;D{JV79&HS^vXX+TA}IxG zYZ(X6?qZit*VqJV hrks0Y zXQj?;%ogLu`L(z=Z*@HhW?o7egBDa#GI=W2>lL78FA$}TkXJ*%xrwT2LFKT*;KhB` zW;=X@m}-ok+pSOx;uJC}hS~eYSTjqLw{7OjcT#816KSx-D9#iTtb!?rB`U4*H#lLm zG*sn2C~@0$xlvI{9C4evks~ZIANd%R5@fd@2I@+ZpR1}8&lPKFn|4NW1XYnBLuqIv zXUN)$OP4Nl_Usu_N*o* 9>!i3NDc+V8d%)wD z(&fwN^l7v5V%9^`hmEo3ZISrBN%3C*ujd+T$>+LJNlJqG%Ish1MAQkdBR!G#KlTyU zCJ;;_sbX|?tw+BmiU*Vnxe~*%Ekq@4@jJ>*DRrz-iP?umDTOtK#47i9&Y_fWKcwNQ zW`nsxW}Tcg8`|h>02gqR%Z}5crgLs$%0449E>g3aPaBPQ(vVD}ASHd@1KCh6%BDyu zMT(K37rTRD7%--qM^ >2r-j7Dj5HpTQc%f-Tn7=H6`b%6Jd zs h{-n6(Il}+zs@ZwxiCZoYEQ_&C6#hWTAV)%x#izE zrmot$$%srP759=#_av3RD5-S$Qo3~hoIZEztMnq&$HV(tKSc{y bsnX=$@TRW&vzQVQ&1_VmBSA$* Cjq;s5Yzrw9&+ T2F-Oj(+ZR)h#B zan$xPO5 Ii4i64zS7B={!HX0-1{otw+2%pAmU_BHM?VfEC5CxPKEFj&d_yFWH1BPihNN`n z`9v1GyO^B?m)0x(&HMf>@A`@_;||WCNEoHjDsQ^f=9JEiXHW`B9QwkP=l 2x~X~e@LB%VN8gXthBv?Rb+q~=twg+O1;CwHT5q-e zD*6 !Ngu2tBDh-M@!ViTI?nR|qX@zrwekh~Gz^$%ue&c~sY^1f; z)J@GgHzak2Q=3LeU_h2Q$|9&>j%gREpg_k>UC+caiDs|1X1^j$?Ap8|n&aCm5=lG| zRGN*Vtg>ija4r&pBRbES#S(mCuh}6Ld+-}Tmz$=8El-urc;}jE%+|%|IX^D&x?G%= zsQ4yG_dpsirHfBpj2DJi=oif-^$V&V2=}RroIjToe>f@ra#DN?aP~&`x!p#kkVM6? zb(2GN{kp-qC0|Ga0hN);Ax#9Wc<|yQJh^|7*lPTZj&WN*T9A-!gfBn;b+W0RyV1$& zJ!1?hMq*-iRc#sx+5@spd?+a4#uU-W=%?7vPr+fd0XC`4z>K6CW9GkaQj=xL7fwc+ z$5jQD0pZt#5D0mEqq1{s$X+F4RtL6{wWfGAmC06778W&>Hd( m!->Ac1Ekn26@iO261O+S4hvnS4x|2?#JG0V}3(v Dg2%#vlt3iWu@vGbQkWR#&`g_b!HU5<;E5ar3&}q+I*wH>nf5Xr)fx zD^ ~zYX|P2p{ELKzrkR-F~A|6krmNS>3|@ zZ`P>D_%y0S(21Z8PmLFO^ukl bgcN%{YzJO-=Bk7$U*`{(dG5yBQ7f!Lz%!%i+;sCI;6G!#E#9(=_bv?6F?2XDPFD zZZ^2|KG3xb>Ku1ajPr&;2*YjLl9Y%FRBl*Ss} Qc8cLHl~dszHb`GF$U K*4C%Wi@9K3i(b7s 9e6Xaz7#K>zZ@=(=gcX(a-;gF`=GkW`LkN av@iFpB`eEGrq(bR|`skGy_^|rg6ktF_a52(zPuqso8VI7(0)Q zg-0^dHjR*Jb8LWunPcaDKpR>6O2ZK{Ck{4iVQH$Wx*~YFZ__k0@2 P^Bcu9=n z`O>!SoPS2r9IcK-WfDAhJUo*7Oir?ha`ut5g&J)w{V)h8(8p}+P-h;? zSV*>CtBqc0rGKlg>R!BX#9XjyT72*vj6EOv(0#n~%ihkO+Ci&;!OZ8&wUFd;=6xX` zD 4dw-Y~!>ik~eBC?0lFDeFeEQRjA>dUaRfe`(@aVIj zra$WWJ@>pFt3H1wYL4rNLf!a;kP~q5foK#fMm~7uL4Nt8zmDr7!A5*=uQay$p| TA@;(uZoJ%sYYaL81zNFK~w2SSMdFnf3)VD#CGzxD@aPF2^Gtc=D4BRU~LdvT2Ku z{oKb%Db44rpbTaAzu~Hcn7IwbyJYL{GM>>`TZtk@YkZK4o;7mOE#_!5 PNECmWD-%=1=aEKAl5p&U zG$g|?$iIU)yH;|+?)!n|a>+POI5*8iTWc*^iDX(lm+FkXB)k`2leUxKLZ2OT0h+p< z8>Vs`1z{<2=NKb(Q|D37L{*h>wtQTxRWI(hUV;XLj~Hz;@?}VI AniQ=eg&aFZZYUAJJp?$O%P_anwsG_@#_i1GJ=T9Wu}=fWyDkI@xjbgYM- z#hE4Rao|HAzK^%Q^Ub_cpJkfX7+cLv%C)p+<=gb~ldv4GVe 7o{9G zQ221;buwkLpEr`*^WjSm@C*0-3eBsQOv 7NAqM&KFS^+z3Yg>0 zXHsk)*+`%udAAY7d@cJQ6rPDvn;^5U>(IuqTCa#eZ8xE5TI<|c6gah+W7~Cp%=KE3 zmKY;iDU8+BRV~I*-e+f8OGt^Xl^v2;-A9sAVuOw0uAOrb%L24f7AcPJN@LuR56c2k zcBWeE7qd|*Ws&sdcK~lip)SRXS1zQBtGiCeK>$3MK4hNdnb!b+NTI%8DfJylgIC}9 zp3kk%Wup>-kOElEiiwXt{&7~;;|v57PwZN+_c%qdbM0jBgqjn_OW@sX51=(EL{cVW zO2}X}BN|2eUnIRKkSVHgIbw)1;@v_dV@$K6Pq=Mnew^ZCQZByU``PoT{9UQd&q}6G z@LtHSIpsM9kvgj^`AtAmOZE?WM6+H=IAL8&Hcn+X*+RwEU>HXfYEDyLuX_afF&Whm zpQde9;$b$ZEbnOv4BXk-!FxYD*%p(!)oM-Kwlg|13=)i3H+A-lkr7ql>KJ2ZB~aUS z9IcM1o1%tPvk_hhfx4+t%HW-6v0UILhsv8qrBvprG#Pc4&81R`aTr)E78q^6dUSr* zSo=Y1%%OJyrDbft9tQDq8CKl?;rsZqFMkJT&0e8!pEx7qHUIDP2MW0TT91yu{Zs!V z;}l3&p9F5HQMnhD6iOu&i3-CPpLr!;{JPih*prWQxLy$|#ppeC+wj!WPw|ak@)hh> z&1d`ty^tzt$TzARu9HgPfC ^vR#$=y_~2&*qNEZl zqvw#U%U3VYu9O8u83vIGR+Z#ujLxC0oa~WQxLwB%cydlu1t^jd=KtgbMJbAdn51cH zJJ}_P_kxB@s_U{lrAjiQ(MHcP^)9<*PUApj4bwE>qQ@G`VzGk>iZktk)-(c3Z^<8y zL7Usd*RA89F9_-uI4U=-Yd%6jS6&Z%1uDKlk=&(p;p(MyVR(hU`wLRa{9ycuzL=i5 z6P3P65x-B7z6Ztc26cw#xh{U@8 8;kt%{*_T_Wow3h5Ql2- za5(@_T&4T@_(Y0a){u?lxgfU1Qhpr8&R!HRUIrZHe*J*T4TZIqVI1ZL!Wc7;>BuH^ zb=@!&ucaIgI877F#R3p+2MQTGw{4E-$geM@+10nmv_p2Wozru(I;rn_DqAtRi8e=l zl+kzy5o@ft*5>!d7ztc$+J^P2r>d&?eXvH-pC>n=GSXF=OlvJ9#pEU`ThVnLXlXDD z(^j&T+`N&rwWaA=_74v*wnA(B?tUEiJn4g`st)^cWVu|Df;6x7PRrpq@QH^X;!EHD zPC9BVC*{b;&+n9kOQ~PRvSp> Vb1_u{(9 zfjc0o^qSz~54COko{-#Z#uh>#`jFZELgq5suwJib%loeF7{@_6`i!O+Qx?MwlfNJ; z!MprB7MnxJs*=L0#727@M|O92Sg+Tpyil0TW%1t4Y9DK>c_hAGud_34z>O0sFHCh^ ziDWtli`8|-Fpc;av3Z{CrU^B9?%KUenx%|vYb{C#AbUJ0S)7!@6kY-w0^sxEsLY?+ zd_lS4BiN|o9SPo|;CHLU>lCDm>B7|u>B4x|7f8eMJA6!?Pv`H5DSd-h{ApDBGmyR> zcoiu7LMGy$`9@{)i$#Tu%HMAt8C2k*E06Qk>Jp&>uQNucBP6--5fkbfqiQ)1HzS`- z6R;V_BsQegGWMzKdLCbBr8CDv;atq$0~rU2b$%iQ8Sl335| Ktmm4qdJzdw$Xpi@vX`I;E*%1X{6!SNU6Nm(#(V}s{O^(H4K{21Zdi5&7 z%eiE&%?MGNxp)T$2U)EnY18w#EE9*DR&suJclKB;7VPiu=S(9tqfWsm4h|1yzm|i8 z17b|vdB>gfLq9tP7c#D_!*J!wRkV_HY9Es{NXAgrHN!YzD)W`b=-qx8KiJgOp?3jt zEQwDZTUR`D`4XRc`f+~GTi=ZV%-pP$COIQ&Y *F6~GD50MN%4_~ zKf#~)+Ha+P2^zvBz^9a7#r1CTU)s{MlTQk(6cdpZBM -=FH z8K+4?3L)osRD_h9jhv>c5tqvncvgsDDUlZwM@r04tOAz1J9(!#5=is7$mZ10s%Z%+ zi2+?o^s5zZYq@jx44vvwAtO7vQ4x!BIg50HkV%upi$XpCdB0-{D68?&gJ$+vIeD8I zX8D%#RZF8lMYg?L3Yj-MjVn~FlS+3h(mPS<-BG1iqSACRUR+&H7si(>!t$X1u)fH% zcaYM%74c7L#rFdL0jSraXh1w1uJ@iNmB^8q*ZuFNrH_BV5*+^`-lR%%qDbhJh|yEo z29#zX^5FVYJib29paRioLP=RkSxu9apdz_xF3+Fx1tDb~TJa-M+T` L(v7KH#8}znblqZW3@wVS#X>?0wKlAW zkq{F*yL-eWs>0Q}r>dK5BxkZ6zuFK~m7!@`rpbxLL6Xlw8$-w*GgZ^d$jb$ct*Dz8 zmywZzv5nJ2)l{s9VMdeXb;@`u&Y!*J@MuN1To9ss)(IsdhRWvVV8flOtYv4p (?0%<8IAORWV-&_=s#Bm@H4co|@9m>CS` z*kj{uIAg<%v9SdM#s}H>80=Zh*u&U(0bvWq7)!=N47NZ9c@dUDAPb?E+FH8Rt=_A$ zsxtE}vD|I`_}z&2GApaHiq=xincF8$W_7+7FCt#Vy}#wVh=OqNQ7Fd|+I9CDW6V5+ z@cz8W7g{CTk`S=okxy&(4-UBR GVFwgqC) zCG4LfO<+0!@nj-YN}&~WohaN+CKJ}FH!fhe5`rja=2a |34rRPBf^QPb0b$>sOlO0%AgXFd{8?bFu6j5;z!LPg) z6@O=1RQWq?XWc3DE8R_P%^SKKX3m4Jh@efNzHQl?a k_Bc^7(UXLo**68BWX8-^o07*naR9X>Y z^D$vhda>qkVnRApq9(KH$ok2QAtK^+2iFe76cuTu^?f%|+UvxO9JE==B(q=Sm0)W6 zo~CWbIn;a4xpU`^edpdg(QQE`#*kPDnA8FrfXZ27C@q&uxsN>TojXTXh>2^PfW%c* zW3ucu3T9cB{c2QtWxc2ecYV*Q>p6enJP$qe5c}6I@kRH(l2R9=&|8c`#E8TF$EI_x z0P_rrR33WtDc<;3et^A;&!@Fwe0lE+pTqC_^4A@E-92|-;Ael~Kk~$b9|CS6Q2EL~ z|0j5UeI9KT2ALQjB|#xzbWSrj{JUR%FQJfXfNmXM{e`dLx$`^A6z-<-_$NkG;`$K) zlO_wJ6g}`5D}Lx5KhB}DJbLv>>e=M{-nqTM+N@XqlR{c9MP7)wQo70dzNah_%06v< z-;H#_EX!CPEvTwWR2;1pT##ZcZ+b6&7Qjf~0P{c$ztqNv+;j-6*6Sn+CF+yKXse!$ zz0E;OMH_=wdIazez}LR-scV^3o34@UF$BDK!V*dt6|tokHBRvf5!z**8G>~vAGt8Q zAc9mH7}yO;jV(8$HO@JTTnx}oK5tRQQx}RGerNHxWcf)9PnMZPIh24UT&J9aLi9nN z4ZKnjzZCHfy6Z~3q^`tE_Da0eU(k0yqky*`=|5yH`%8QK@u`=h;vWG1N8o=z#orC_ z1%ObxhU!xqcXFVj;$|)yOay%lgv{`SKjOZ}K8`B_t?N^uzG38ScCyhN*&f?~?m=8_ zsG6J%Xl`~wW81~21mP_E_1g?ovb ^#p4r(Wxhs z(Xeo++6?VoJ3jLw_%?WnSvy=$S>%bL5mQwa-Z`xE#{#86yJR?qzPG{@Y8ob!DKQA9 zBun$vx@nRyp0tICa!e{^%fs9$T{21L7K_Dro&ykC{EjpsNa8iArRp=CPVwHcSS~P$ z6(rSYsWjWZr|r7Y`>1I;w9*_NEfVHNq#Ne*xy;{-6~^SK0C`qO<;mJq6^mHsUK>KF zLkPdpbzM^xHF+jxmd-jZT)dl4KJ*~_*Dmq$FL)^>nN(AT^9{+hNsUu!lG%UefNMYU zu?P7lKl#(Bte_78Z+pJ@RWISIzT!)dy-q8|t6%kU-uw^#9&ihK2ygy>|2a>-<_&!1 zE53xFG`Sk0xqvbmYq~LGZ=xueX5Lfecb1-tN2)2eGvv{a>Gwd3<1!6D@t&XI!K2H} zp0$IC)19NPebWV{|Ew-bbaY7#vZu8@J3Bk{PNbYqIs~f($nrj*wPG@z$^$f+h_!js zq=#=g>Z=U>U#%578gW7`1ie3 5icveZ}BrvxFJ zlCrz*+MV{=;pa9>0+4=tGHo1`Ii2%FeZ$~K12e>E@5R7Z0S^N22Y&hf@WBrQk9y)k zrj2_Eue{^hL-+N+ZgOLGfae**D}dLB$QL8$v&V0O#d9Z*pdf0^epv9aCm!TlC%BC) zPnHz+cpY^BunvIM0k3eH9?J0gZT!@&jAq@C Pb!C+f;EDZInU1_ULGt1l1JI zS=Q@y64P_zyqYClFP&-Dt2Ih#nr2Oik@b2d^FWC7iFP~~K=!@N&2?2VnNC@+8rr5O zE3=I}L}#T{6ouV1o$Uzb&KTC~^?1#Vk*bo(GD3`hHZ$5)RrOb#cSn8SQ`Qwk%_I9y zvO6pJ#Si@|cbz-WH-5?Qr^aB|EYvz~D$?WkoZw7%9?;_YanEy}MF rLTU;`1_fG%ESFNe)5;!#V4;m&L8?+U(Ivb!_uNKI1CT;Px97(^RIBZ^f2?N zh+W6?_wF1qtpS&EyJ@h9Q!6^(;tU)BZ+qV_@+%+zF#6ntE6u8!OzSu8A0B;M_V^Rr z^Q^l#JUF7t472H!ysSAqI6@gC%8PwBmJQpsCDWRt!zJ_ioTh21>k5-+^r &scTR0;&acXKuZ=B)1(0qH9BD&P76}T z{Ur;5Q@__!CiU$_WT0@%?}0&!; _@rd*kNcAr9z@VSiGs9srtERf)ZZ^8(zo7L2ras%kSY4DFe&>&Q$lEFz O*4gi2Ai3*@sQrrt{9m=WqyEocE%tn$EK dThju@flIZr(CB(vF!vMh179jhcmwP$Dv3kD9#LZlx6jLs;_ z8fzWRTHZUE)MS}q-83whjbKh@JEPcTS(bR;2~brTAaHcFOmyT4F-CTG&m{-vg4J?K z@Ny58Wr>fP#o~yr>)73$qf{}Tx9tV97=r&c&=z=;(RoWQEX|^x(Dk1A^PkPXc<;Lb z_{J~!T52FVi!!pWk*hXT6p>)%nSfV$?z1m)@!~F*4;v=4a}-s{fB2R6({z@)ym4{k z%pk1#eJ`gY^3dat^6U5C$5po=PD?I_7580vn1A~7Kf{Ngco<&_ZI;IKd!PSu{^0L; z! pCxJR5F}u^ZZSNgUV7sAR8-`^ z9C#igBmV~AcLJ{gUJB~Dz|MZWRPM)1`F^~l_T#0vA1`rH-Ti3^Uha<{Q2RWY?ek={ z&y&0RJo)TPJo(b7;#Wi!|2tItqp0{N74Z)$6~9aoUx *scZ zlwtT7a3K&g&00C`yYxw}*d;ED*w7KL Km~OziTXOWuY!<*&Z5Xta2E$Hk?Kp?DZ98JRj4|kB!!hi<>pJ;dMPl7afD=Q& zWP=8a1ObD9Ti (xqvoAf+~RGG3?)UxZk2Bdm9fQSe7&T!p^ J$u#W{mg88Cl+kG3XSB=#sAQ@XibCXFj9vEnU}B zC0tKY6r#GV#9cag(R9iS2|{!_?nwd;52AKWvt}|A45n1Oi&SOlMoeE( dl!R60@JM`!xuciV9P-064~ zqcsOj!+YNQE9kr;5^;Uc=fCLlc-2c@eC)N6jeGK$r}c`z|E+XQiwcr)V?BkImcf(z zSMZr8PD>gq*4z4O!;k#ozsT=;@ykCWCwjZX0sZYxgel7`&@AX^$oY4deuE!**V{P= z4fDM@MV0^M*0tXkV^r;W#k4ND`}`g|(~1~`lDNCOOOqaKYb}#WMcWGQqb#HX(%U{o z?>dR3ZDm=(iYw^h0lT| 5u7K *{!^w-EIwM>r$fKWl;0hK-&=W{zdo07~EJ{U<(mIF5M3$VQB}VF5e^Jf5~k zfyZ>@Dd1XA906;f13FZ2>BF|Ic@-PO)C{TU6u<-tlFkEn1J4ccJXClda1U^Il)o1$ zitMIlgX1{$EYEoQJZjW&@1z{pxA%LuV|z6`|C8;>xG^#KEJ)I>RYT=PWwAd3Vbt zW!YhIJ9#Wa@P8|T%1|-cZVzqWZ^PfimM)9lDrgTapKaZi;7NKX-B^7He#5vkMLt%0 zhKi7!OLAEc$HBjYQ*cP)lR7IlqLT?otF<1zYzE7ZAwVgU1M+ZwS{cE-B|3JVgyH71 zInG(y-U(Ys$$7`HY2`ZS@CjSuy-RZUAq8GGRf?)q88WE_RgLr3;o$*gS&x9|7^7fZ z(y>Z4wG^$WAW4~sy%`bAD+*$e_X%!B(>6Umgt5KUH0xBkk?T}d6OIy&Fvf^aIGf>m z cb1`|7WiU_-%}LD-{|@t(4)je5fx_D!=*$1*FXE0 zc=h?uXA+?Z3O~qGo$}}u>K6SiK8NF|Y1w<(8;I0QCo_WYxUf6rt^eq6@ujc+!tr%) zdHcKhQ(yo4fLjPuUh{YUXS`8R7!KPtE(C&eOskp@la_#1s1V5meB;Z07vKGr|NR|N zP4OhXl-qry3Pd~s&l<%qAAXV_{1 %1=V@Ov)O9!$il6U-W#A z7FXGsPN<4ffUKkWmLGv$gF57pQ8?$wG$V#YG*g6@XA>)^$nw!B%Oqi=5H|Rdfx;Y8 z7Fbky>bHugPi`^{3hR=VLSBq5Ajymb!Jp+h-g$O+X0&ZHKIlW%mX*cm#WA?D=6Nns z`N<_!`^ZdJOswXMUhq<8)R>r~<8jk+rG&0|TKng;K;@Xu${CAXj9!cvVeEMy`
3q#{xWUD5}YL zUHiVr2Tz_H+qKrHg!M2cqiuzmV^bSwQ0wk{sq8pwaV{n^L{FY)Bd%na3;N!T(h9+c z#Do&o)u>XdGZqWMwg@AsVYON_o6U$J`8R3JIx%)e@UYHD`w&US6nR-E%^U&juGbyG zd#n>|qW2D$j#bob9oF`&nuc?Cog>!;ZQHEtqWm6f-QVt=CniBq6JW2XQ3q?fN3QVq z-t_(4Ti#6`rQI1~JavuL$fR&aG4XRg-ua$i OsJ!c=zs9>h{44y@6CY(s9Bt7}X3!DZbwgd0gmuT)eBtYO z)7Sn9ruuUaq>V@=<+PShJh@<{XWHX2$`J81zQr5G!yNMcZ+$b5wAYxO+oiSkPir0j z#^tM5F5L5+djM$HYmACas+{>O=i-Gua-+zU8G)*jjfq_SK*e1g9&y)Q=KzV!o$p0! z#XIKnIldQw*ladW7z>THeL|~yd~joxLu*Z@P0Gk5D_FG+ecv;iP0(7?tk%is%a7)7 zgQ{f+o>@H|1CSU4)`=Qzo=U0KN#-+@XY)KC6>E#4py@iY%!vMiHbfiIYsc?+&P#Z1 zeG!62M?Ef{9zV+Fk4ALEcXR@{I4DqVvm3Twclx;bQhPEGQYW5n9dA3tz3Kkh1S0_n zdxqcH`Z>lJVe9u3KR5rl_2B8c5u-mdSUGzi@tF0&_QLgaEfBVY5oK46Bb2vcQ_2 zPaJ%Thb})#Z@}dSufzEI>jQ}sBhhz52uXlVO!0<9VhCi1iog(fjQ7cjYd^eyaNmvT z^R<+Ob+$J Btk*y@t8nF?wV$eF&XRiik<21$i$KaP`(diGMaVE5IDNz zQoUL=OzP=~VHsLyRaN7?8{2GsZ!ualSBfHMwOk1(c)CN^b+m0Glw+gmy&I1)GsPHW zg%I$)9fK(AEYryprNomh&oZIZM~E@*`w;$eT}^&?y>4U RXP9dy V1M_%)LsP&yuc)F=x z%E`=60ZLp$J%Y1{I_F7N{N11aaUNJ+M(<4UKKzlgEWWoW@_Tl6cSj5I=mV4Kgb+Qe z)shPr&f~pJ>Xh 8}BJ!HdWK5@%@%=-Pk!4AEDe0^XHuNTmJY@-RS6B5`|5vmXgeE7n zxgk3X*3nx_XC0GjLcg+{-+2}qgNd65Xz(#P4KO> c0vg_Td}mK1NC5~>69cr(+8Q$ZV}E~Id*7V2LMC*B z!l_87Je`7%A3nq e!f+_{;+cab#vG#ltM@(&t7`K2V!@kvt zeaB 7a*7ic*TIuElXURcC~5Y$?kMh^Z2>kp&Q7uwYAUZ`1J!P-4KIIp;T+JFRJLFH#FB zaLY_43_+8Pbmg||Fj}M2;@ 1Iur{UK4_} zf b{%rq9_VhO+)a3`E1U? z!2!ky1%5W0NdQ#TBCuyNOqSC$BE(r$0`L``u84w3jPaE*#7jk4-nU+_rR9|uL vi|{aDS!S;|`BhUiFgC=k;Iu#r*T1dOKa)krf3h&!L)N ziV8v?9)1eAg`jJDF$hEs+7(w;M-U^^qGGq6GRaHsBr)Gx$EB#Gmy$B4q_x=+c#;MG z=;z Uu&|R}^`X0BLe;LtDnD_ZCG#QDmcrLZ$@l zX0)d3n{i pi*MZmnw%2lZwoC5gRz)R_+3PmgZWseFa5#@`ciQdh%8kZZ7?+b3my;Eh zvnnz-YpdMK=bsg3oOSg2X$C6(_95oS#y|@lb#P8hoS%-0iU_*Nm9XC7%8ZVT`>uSP zPaQl8Q$u5WOp#-~Ki0cHt)jAx0ckpWtkpWm-;b3AeZ9yVFy80tL~CigqA~<50gcy4 z^(ClOQQQ(pS1AY@^j6dcyQAXumBsC$vwUm=Z?gkK@Q7LIrix;%JyxX|m_sJZ(oZv1 zSEQ<% JyvN}O@lU?$wVr- z&iau( zlNly;jf;VUYX{Vmn!%kp%M8=$j4S*5fMz Amvty_Bslk)+^CTaiPQLn#-(t>#zMBKlA?o!2AWz=3sI3hN3M0rpoji z*6SuA#AR^?m{!wtGp^W~Pw`>R=fCI$WHAt&73x`0$a}WbBm1_asw+SYvXqt#Rk8{@ z1|&njd+4=JXQH>FRNRyuvkVd<9t3kz6gfs4l#Zhe|FqiB_r$SzJyNE%Qe&A`WV7Y} zWm&$#q&Q2Kf`kwwMV@5-lX=%rLUrCVoA2Tp%T6(+Y&EZc(W{um3=^dNb5@`N$15n? z|GpJG#Qz_t+ ?oiXSVfdnftZhHW!>jD+)6K(~KiD0Z*W =G66jTXSWw{rBlV#g+%i$Hl93NZJ?8_pWgP&XLDBT zwE*-_l9;x@xiKcA)v6jRvqtBl8=?*CW=&bwBUo3!`u#Y602Fnd3 Ifqvdn9aoEW3^f`oz7^QMyh1W0D4Tslrq@fje(HS8c$3Ch8Ptt zSIhCUgAbHt&1$_S8yuelBTf$(@3(ccrYa{RUQd#`DRoh@TrP<*QrGoZJy%+>x4S$3 z4J1&RO{XlE%`a)Cz8m u}A5Q%dB|kCx4B1{Q7(0+?2-k zuh2?;*K)OdL)Ud=b;;VdbU`w(DyukJE@`?BWlB2dX>4TwAVtkd >ZqU4t?jWsK}Q1e&g;=~~Hx zkOf5 U@# fVcs>SgDb)obr=>u;?V>ish_k4hCNlL^37fg7rY%78LbnTZOM7nr=jN6GA+^GReZ z8(DnPg0bm1QiVv1^RTs!7&a37!?n>yj8O-%N1L#9!*vQFNOGh%o zxA@?xtC|=f%Sx>EEEd8VD)J)9>z65Ts8I}V(m8onia}vkj%^ ZIX(uBuJMoT_OfWo|VL)$ntWm1SzHH zQ$?z28evq$h_#+PFPTkugnbn?SynKe&IvxyG<`a@DQ(-+wW3lxo6cFSnsgqDwh@!Y z<+8!(> 4VI{|bZUIqZ ze zNGvnB5G3g7JIX{a9$Z6#ltCnW^iq6$+}e$SMBn$L@LSU~0OFK7W^3Yz?476YdnQ#y z=XxHx^eE5TyFe8(>Z(M=<1L+`$3GzC2eGzcoCdbt9zz*;`2Eu@)tKv?fJ~e|WxSuU zMfw>qKGWxJl%b6dmjxmP53HZyp~I&r?wZjlH(DU*czPA(WMFc$v5k=$g5AOMMi?Y9 zQFRTrw<7a?3KIDk0M^p!F24C(oc+}=ddVxUe8cSZ+edl$FbAJ_&^`7Ke(7T${Ojw! z`7U2)x(y8~i%jbp+Z;Fi7y|L(_bkgt3al}DtZoSKTo^@pYUK<8SY4K^)@zYP&?X6~ zSq4U8jFGl&l6aXM?qG77&5Be>4HzxnWdN(y3Z;@jWfG{%tDNA)9eOgIqLpH~T#ihh z7$O11!L@6YWyx$h59KX7f39Y7bR)#cCzqIwDwSq}4v12&i?{ac*x XWxfs>T1%^3Xx5gUogD_c_R#+EDF`jZdMW?_AOJ~3K~ynFGBRLe2KQxv z`Fxft+J-Avt}vU;QY*}iZLkmmxn`WphKlsi3ToSS6wch;+r>GbSWJo#{MUw{4~`BF zze{WVcs-kPusA|H&vaI!>WUwG=TCFt>vs6E=f5NY-qfk}QL(ud@Y^$a{FbSxoF W_UD*ss9cT8q8jLER;mPuX`ony6H zQB7)emf>T>d$@M(h-x~=`oOAP6Jr=3{Ao3z$a13h*tWx3%eAXlM=cU##LYBnMei(= z$&~eag)$l!CAet%j=U_zcPDt1F|1lC)heSwD_rzg?@>mxY8vvYq))A+%w%{km7Upq zh6{muI;D3m0cbO>9v |c?&%I~G`6?oMLzoX4BN?yn~9M1@hzWMU-t*S#_Rp6uoRPrmGHzUPZ}U;MYTRg863QfCFO>yOFl z>w!}2!x)(4xd1iuJR{2lpOWXf1Tgk`S2Jx4%Y>n*s(Re#P@xnTU_AyKCx`7V!Ap=* zzc`=X0cod zy?6`EfAQi)+Ex^2^VFUm lXx~|Dg!PTo* zxp?vJl)-D9b+opnG?A(CyyCaLNFF4k32sB>%`$`ao+kO`D5Yq-HPh*A1i21C#h@fY zZ&JXcRWcV-8~J?iJXu;e%Oph{ViXLD$;5LcF|v9q=cIxkGmO6PDbmB#J3AVFp@d>s zmL&!`&H+4@Z81HzTQ!3ve6wtsPA7D>BUc(_HTgR76)%4smCcx#ic%YT=ZIP*O5g@y zcDq_U11J&%Y`c*zzftzTp_|6jumC6N%O}8@XC2>X8l$4Z=`FDBvE9Bn`P!!oraf!i zE=FabYYxAArD?Ey=<$#9*!l`>t+9nCdYAAULfIc2lq1K3UB*E9^x@<2?{gSK^ K6i`S|V znspGTV(&$tL~lvtXPIHOT907U5G1h}+>Dh{#2^)zZGfuDva!;nwHe)#mC~%1OR_v? zQVWi4Om4D_zH{`pAFDRPAj;%#37;l@HU?(}yRvEol bfR`@TPUsd|y%I*mcX!Y)-dsh`nR4nsXr*{J^*T zFWgN%s`8vRuNVev^k>!>sp+5N gjzvD+)=g_MN zT7C1*&dztP)}l cfVBIv#=krmA0fd)7DJNL#QTc?U*3 3(k)(xN`>LfrU0#!}Z5FONo*jA~iQ&wf^I!n{` zIP0nF874EBBy)dwcqsemd)94_&I()*O@_RzkQTf~YiY*>57B||0|$pktX2)d3&P)8 zPhC%OKA^QcXx4hVRt&@@lRBBj8G<%srGX;yi6 7Ah|Qh;dB?FT{*3=l!?