diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e0f7656
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,42 @@
+# Python
+__pycache__/
+*.py[cod]
+*.pyo
+*.pyd
+.Python
+*.egg-info/
+*.egg
+dist/
+build/
+
+# Virtual environment
+.venv/
+venv/
+env/
+
+# Pytest / coverage
+.pytest_cache/
+.coverage
+htmlcov/
+
+# Data files (large, transferred separately)
+data/*.parquet
+data/*.xlsx
+data/*.csv
+data/*.tif
+data/*.geojson
+
+# Pipeline cache and intermediate outputs
+cache/
+
+# Jupyter
+.ipynb_checkpoints/
+*.ipynb
+
+# OS
+.DS_Store
+Thumbs.db
+
+# IDE
+.vscode/settings.json
+.idea/
diff --git a/docs/study_boundary/study_area.gpkg b/docs/study_boundary/study_area.gpkg
new file mode 100644
index 0000000..b7b266a
Binary files /dev/null and b/docs/study_boundary/study_area.gpkg differ
diff --git a/scripts/ML_Stage-dependent_n_v2.ipynb b/scripts/ML_Stage-dependent_n_v2.ipynb
new file mode 100644
index 0000000..8796a63
--- /dev/null
+++ b/scripts/ML_Stage-dependent_n_v2.ipynb
@@ -0,0 +1,2351 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "id": "35c9b884",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:14.224455Z",
+ "iopub.status.busy": "2026-07-10T12:09:14.224455Z",
+ "iopub.status.idle": "2026-07-10T12:09:16.690647Z",
+ "shell.execute_reply": "2026-07-10T12:09:16.690647Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "\n",
+ "df_predictors = pd.read_csv(r\"E:\\SI\\Predictors\\Predictor for SRC adjustment factors across CONUS.txt\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "id": "af0b96de",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:16.690647Z",
+ "iopub.status.busy": "2026-07-10T12:09:16.690647Z",
+ "iopub.status.idle": "2026-07-10T12:09:16.719387Z",
+ "shell.execute_reply": "2026-07-10T12:09:16.718874Z"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Unnamed: 0 | \n",
+ " COMID | \n",
+ " TotDASqKM | \n",
+ " CAT_SILTAVE | \n",
+ " QE_cms | \n",
+ " D50_mm_ | \n",
+ " HydraulicRadius (m) | \n",
+ " Volume (m3) | \n",
+ " WetArea (m2) | \n",
+ " HYDRLCONDCAT | \n",
+ " WTDEPCAT | \n",
+ " PERMCAT | \n",
+ " StreamOrde | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 0 | \n",
+ " 721640 | \n",
+ " 3197.9700 | \n",
+ " 56.40 | \n",
+ " 57.948436 | \n",
+ " 0.380283 | \n",
+ " 15.857102 | \n",
+ " 8.987655e+06 | \n",
+ " 6678.264254 | \n",
+ " 0.2280 | \n",
+ " 106.017528 | \n",
+ " 8.547650 | \n",
+ " 5.0 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 1 | \n",
+ " 717072 | \n",
+ " 3199.7997 | \n",
+ " 58.18 | \n",
+ " 57.972096 | \n",
+ " 0.566348 | \n",
+ " 22.510113 | \n",
+ " 8.290905e+06 | \n",
+ " 9628.070417 | \n",
+ " 0.2280 | \n",
+ " 91.252273 | \n",
+ " 5.220708 | \n",
+ " 5.0 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 2 | \n",
+ " 717076 | \n",
+ " 3169.0890 | \n",
+ " 54.68 | \n",
+ " 48.713896 | \n",
+ " 0.519356 | \n",
+ " 16.320629 | \n",
+ " 8.725284e+06 | \n",
+ " 7572.361628 | \n",
+ " 0.2221 | \n",
+ " 120.284476 | \n",
+ " 11.762311 | \n",
+ " 5.0 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 3 | \n",
+ " 717082 | \n",
+ " 3101.7240 | \n",
+ " 58.57 | \n",
+ " 47.762792 | \n",
+ " 0.452027 | \n",
+ " 16.275332 | \n",
+ " 9.231961e+06 | \n",
+ " 6953.369666 | \n",
+ " 0.0057 | \n",
+ " 88.005448 | \n",
+ " 4.489126 | \n",
+ " 5.0 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 4 | \n",
+ " 718990 | \n",
+ " 3092.9895 | \n",
+ " 59.09 | \n",
+ " 47.644016 | \n",
+ " 0.566348 | \n",
+ " 17.402589 | \n",
+ " 4.761972e+06 | \n",
+ " 5712.860920 | \n",
+ " 0.0164 | \n",
+ " 83.660000 | \n",
+ " 3.510000 | \n",
+ " 5.0 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 2161049 | \n",
+ " 2190022 | \n",
+ " 22599701 | \n",
+ " 13.7547 | \n",
+ " 42.28 | \n",
+ " 0.000392 | \n",
+ " 0.393875 | \n",
+ " 25.298397 | \n",
+ " 1.152848e+07 | \n",
+ " 9225.329640 | \n",
+ " 118.9469 | \n",
+ " 154.380000 | \n",
+ " 18.110000 | \n",
+ " 1.0 | \n",
+ "
\n",
+ " \n",
+ " | 2161050 | \n",
+ " 2190023 | \n",
+ " 22599699 | \n",
+ " 3.9033 | \n",
+ " 42.28 | \n",
+ " 0.000084 | \n",
+ " 0.451528 | \n",
+ " 22.653490 | \n",
+ " 1.951305e+07 | \n",
+ " 15406.845152 | \n",
+ " 127.8264 | \n",
+ " 154.380000 | \n",
+ " 18.110000 | \n",
+ " 1.0 | \n",
+ "
\n",
+ " \n",
+ " | 2161051 | \n",
+ " 2190024 | \n",
+ " 22599697 | \n",
+ " 10.7127 | \n",
+ " 42.28 | \n",
+ " 0.000308 | \n",
+ " 0.393875 | \n",
+ " 25.298400 | \n",
+ " 3.787170e+06 | \n",
+ " 36118.856685 | \n",
+ " 127.8264 | \n",
+ " 154.380000 | \n",
+ " 18.110000 | \n",
+ " 1.0 | \n",
+ "
\n",
+ " \n",
+ " | 2161052 | \n",
+ " 2190026 | \n",
+ " 22594551 | \n",
+ " 15.5160 | \n",
+ " 30.78 | \n",
+ " 0.001176 | \n",
+ " 0.293480 | \n",
+ " 16.555852 | \n",
+ " 1.002763e+07 | \n",
+ " 7387.374976 | \n",
+ " 3.9932 | \n",
+ " 182.880000 | \n",
+ " 14.784311 | \n",
+ " 1.0 | \n",
+ "
\n",
+ " \n",
+ " | 2161053 | \n",
+ " 2190027 | \n",
+ " 24928641 | \n",
+ " 441.8973 | \n",
+ " 13.11 | \n",
+ " 0.047796 | \n",
+ " 1.527866 | \n",
+ " 14.330043 | \n",
+ " 5.986686e+07 | \n",
+ " 42021.268552 | \n",
+ " 127.8264 | \n",
+ " 180.510000 | \n",
+ " 35.630000 | \n",
+ " 4.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
2161054 rows × 13 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Unnamed: 0 COMID TotDASqKM CAT_SILTAVE QE_cms D50_mm_ \\\n",
+ "0 0 721640 3197.9700 56.40 57.948436 0.380283 \n",
+ "1 1 717072 3199.7997 58.18 57.972096 0.566348 \n",
+ "2 2 717076 3169.0890 54.68 48.713896 0.519356 \n",
+ "3 3 717082 3101.7240 58.57 47.762792 0.452027 \n",
+ "4 4 718990 3092.9895 59.09 47.644016 0.566348 \n",
+ "... ... ... ... ... ... ... \n",
+ "2161049 2190022 22599701 13.7547 42.28 0.000392 0.393875 \n",
+ "2161050 2190023 22599699 3.9033 42.28 0.000084 0.451528 \n",
+ "2161051 2190024 22599697 10.7127 42.28 0.000308 0.393875 \n",
+ "2161052 2190026 22594551 15.5160 30.78 0.001176 0.293480 \n",
+ "2161053 2190027 24928641 441.8973 13.11 0.047796 1.527866 \n",
+ "\n",
+ " HydraulicRadius (m) Volume (m3) WetArea (m2) HYDRLCONDCAT \\\n",
+ "0 15.857102 8.987655e+06 6678.264254 0.2280 \n",
+ "1 22.510113 8.290905e+06 9628.070417 0.2280 \n",
+ "2 16.320629 8.725284e+06 7572.361628 0.2221 \n",
+ "3 16.275332 9.231961e+06 6953.369666 0.0057 \n",
+ "4 17.402589 4.761972e+06 5712.860920 0.0164 \n",
+ "... ... ... ... ... \n",
+ "2161049 25.298397 1.152848e+07 9225.329640 118.9469 \n",
+ "2161050 22.653490 1.951305e+07 15406.845152 127.8264 \n",
+ "2161051 25.298400 3.787170e+06 36118.856685 127.8264 \n",
+ "2161052 16.555852 1.002763e+07 7387.374976 3.9932 \n",
+ "2161053 14.330043 5.986686e+07 42021.268552 127.8264 \n",
+ "\n",
+ " WTDEPCAT PERMCAT StreamOrde \n",
+ "0 106.017528 8.547650 5.0 \n",
+ "1 91.252273 5.220708 5.0 \n",
+ "2 120.284476 11.762311 5.0 \n",
+ "3 88.005448 4.489126 5.0 \n",
+ "4 83.660000 3.510000 5.0 \n",
+ "... ... ... ... \n",
+ "2161049 154.380000 18.110000 1.0 \n",
+ "2161050 154.380000 18.110000 1.0 \n",
+ "2161051 154.380000 18.110000 1.0 \n",
+ "2161052 182.880000 14.784311 1.0 \n",
+ "2161053 180.510000 35.630000 4.0 \n",
+ "\n",
+ "[2161054 rows x 13 columns]"
+ ]
+ },
+ "execution_count": 2,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# convert COMID to int\n",
+ "df_predictors['COMID'] = df_predictors['COMID'].astype(int)\n",
+ "df_predictors"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "id": "3a9ccdf6",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:16.722405Z",
+ "iopub.status.busy": "2026-07-10T12:09:16.721393Z",
+ "iopub.status.idle": "2026-07-10T12:09:16.731860Z",
+ "shell.execute_reply": "2026-07-10T12:09:16.731860Z"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "True"
+ ]
+ },
+ "execution_count": 3,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# Verify if the COMID is present in the dataframe\n",
+ "comid_to_check = 8755683\n",
+ "is_present = df_predictors['COMID'].isin([comid_to_check]).any()\n",
+ "is_present"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "id": "3f497bea",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:16.734885Z",
+ "iopub.status.busy": "2026-07-10T12:09:16.734885Z",
+ "iopub.status.idle": "2026-07-10T12:09:16.749188Z",
+ "shell.execute_reply": "2026-07-10T12:09:16.748427Z"
+ }
+ },
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " Unnamed: 0 | \n",
+ " COMID | \n",
+ " TotDASqKM | \n",
+ " CAT_SILTAVE | \n",
+ " QE_cms | \n",
+ " D50_mm_ | \n",
+ " HydraulicRadius (m) | \n",
+ " Volume (m3) | \n",
+ " WetArea (m2) | \n",
+ " HYDRLCONDCAT | \n",
+ " WTDEPCAT | \n",
+ " PERMCAT | \n",
+ " StreamOrde | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 161415 | \n",
+ " 163586 | \n",
+ " 8755683 | \n",
+ " 1.3176 | \n",
+ " 14.09 | \n",
+ " 0.017668 | \n",
+ " 0.382115 | \n",
+ " 21.036229 | \n",
+ " 1.585062e+07 | \n",
+ " 15449.24397 | \n",
+ " 3.9298 | \n",
+ " 138.22 | \n",
+ " 17.63 | \n",
+ " 1.0 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " Unnamed: 0 COMID TotDASqKM CAT_SILTAVE QE_cms D50_mm_ \\\n",
+ "161415 163586 8755683 1.3176 14.09 0.017668 0.382115 \n",
+ "\n",
+ " HydraulicRadius (m) Volume (m3) WetArea (m2) HYDRLCONDCAT \\\n",
+ "161415 21.036229 1.585062e+07 15449.24397 3.9298 \n",
+ "\n",
+ " WTDEPCAT PERMCAT StreamOrde \n",
+ "161415 138.22 17.63 1.0 "
+ ]
+ },
+ "execution_count": 4,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "df_predictors[df_predictors['COMID'].isin([comid_to_check])]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "extra-pred-md",
+ "metadata": {},
+ "source": [
+ "### Additional predictors — EVI (vegetation) + STATSGO (soil), CONUS-wide\n",
+ "\n",
+ "Seasonal EVI is a proxy for riparian/floodplain vegetation density, which physically\n",
+ "drives overbank Manning's n. STATSGO accumulated soil attributes (grain-size fractions,\n",
+ "organic matter, permeability, bulk density, rock depth) relate to channel-bed roughness.\n",
+ "Both are read directly from the zip files in `E:\\SI\\Predictors\\Additional` (pandas can\n",
+ "read a single-file zip without extracting) and merged onto `df_predictors` by COMID."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "id": "extra-pred-code",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:16.749689Z",
+ "iopub.status.busy": "2026-07-10T12:09:16.749689Z",
+ "iopub.status.idle": "2026-07-10T12:09:24.871519Z",
+ "shell.execute_reply": "2026-07-10T12:09:24.871519Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Masking -9999 NODATA sentinel in: {'EVI_JAS_2012': 487, 'EVI_JFM_2012': 488, 'EVI_OND_2011': 490, 'ACC_KFACT': 8520, 'ACC_KFACT_UP': 8520, 'ACC_NO10AVE': 8520, 'ACC_NO200AVE': 8520, 'ACC_NO4AVE': 8520, 'ACC_OM': 8520, 'ACC_PERMAVE': 8520, 'ACC_RFACT': 8520, 'ACC_ROCKDEP': 8520, 'ACC_BDAVE': 8520, 'ACC_AWCAVE': 8520, 'ACC_WTDEP': 8520}\n",
+ "Additional predictors loaded: ['EVI_JAS_2012', 'EVI_JFM_2012', 'EVI_OND_2011', 'ACC_KFACT', 'ACC_KFACT_UP', 'ACC_NO10AVE', 'ACC_NO200AVE', 'ACC_NO4AVE', 'ACC_OM', 'ACC_PERMAVE', 'ACC_RFACT', 'ACC_ROCKDEP', 'ACC_BDAVE', 'ACC_AWCAVE', 'ACC_WTDEP', 'HYDRLCOND_WS', 'PRECIP8110_WS', 'PRECIP8110_CAT']\n",
+ "df_extra: 2699864 COMIDs\n",
+ "df_predictors now has 31 columns, 2161054 rows\n",
+ "No suspicious sentinel-like values found in the original 11 predictor columns.\n"
+ ]
+ }
+ ],
+ "source": [
+ "from pathlib import Path\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "\n",
+ "EXTRA_DIR = Path(r\"E:\\SI\\Predictors\\Additional\")\n",
+ "\n",
+ "evi_files = {\n",
+ " \"JAS_2012\": \"EVI_JAS_2012_CONUS.zip\",\n",
+ " \"JFM_2012\": \"EVI_JFM_2012_CONUS.zip\",\n",
+ " \"OND_2011\": \"EVI_OND_2011_CONUS.zip\",\n",
+ "}\n",
+ "\n",
+ "df_extra = None\n",
+ "for tag, fname in evi_files.items():\n",
+ " d = pd.read_csv(EXTRA_DIR / fname, usecols=lambda c: c.startswith(\"COMID\") or c.startswith(\"CAT_EVI\"))\n",
+ " d = d.rename(columns={d.columns[1]: f\"EVI_{tag}\"})\n",
+ " df_extra = d if df_extra is None else df_extra.merge(d, on=\"COMID\", how=\"outer\")\n",
+ "\n",
+ "df_statsgo = pd.read_csv(EXTRA_DIR / \"STATSGO_LAYER_ACC_CONUS.zip\")\n",
+ "df_statsgo = df_statsgo.drop(columns=[\"ACC_NODATA\"], errors=\"ignore\")\n",
+ "df_extra = df_extra.merge(df_statsgo, on=\"COMID\", how=\"outer\")\n",
+ "\n",
+ "# StreamCat: hydraulic conductivity + 1981-2010 precip normals, watershed (ws)\n",
+ "# vs catchment-local (cat) variants, keyed by lowercase \"comid\".\n",
+ "# hydrlcondcat is dropped -- verified an EXACT duplicate of the HYDRLCONDCAT\n",
+ "# column already in the base predictor file (corr=1.0, max diff=0.0 across\n",
+ "# all 2.16M COMIDs); keeping both would silently double-weight one variable.\n",
+ "# hydrlcondws (corr=0.79 vs hydrlcondcat) and both precip8110 variants\n",
+ "# (corr=0.98 to each other, but neither exists anywhere else) are new signal.\n",
+ "df_hydrlcond = pd.read_csv(EXTRA_DIR / \"streamcat_hydrlcond_output.csv\")[[\"comid\", \"hydrlcondws\"]]\n",
+ "df_precip = pd.read_csv(EXTRA_DIR / \"streamcat_precip8110_output.csv\")\n",
+ "\n",
+ "df_streamcat = df_hydrlcond.merge(df_precip, on=\"comid\", how=\"outer\")\n",
+ "df_streamcat = df_streamcat.rename(columns={\n",
+ " \"comid\": \"COMID\", \"hydrlcondws\": \"HYDRLCOND_WS\",\n",
+ " \"precip8110ws\": \"PRECIP8110_WS\", \"precip8110cat\": \"PRECIP8110_CAT\",\n",
+ "})\n",
+ "df_extra = df_extra.merge(df_streamcat, on=\"COMID\", how=\"outer\")\n",
+ "\n",
+ "EXTRA_FEATURE_COLS = [c for c in df_extra.columns if c != \"COMID\"]\n",
+ "\n",
+ "# EVI/STATSGO/StreamCat all use -9999 as their NODATA sentinel (confirmed in\n",
+ "# the raw files for catchments with no coverage, e.g. coastline/ocean\n",
+ "# placeholders -- 0 hits in the two new StreamCat files, but checking anyway).\n",
+ "# Left as-is, a stray -9999 would be treated as a real extreme feature value\n",
+ "# by every model here (and would badly distort Ridge/Lasso's standardization),\n",
+ "# so mask it to NaN before it can reach training -- currently a no-op for our\n",
+ "# 99 gauges (checked directly), but a real guard once more HUCs/gauges are added.\n",
+ "sentinel_hits = (df_extra[EXTRA_FEATURE_COLS] == -9999).sum()\n",
+ "sentinel_hits = sentinel_hits[sentinel_hits > 0]\n",
+ "if len(sentinel_hits):\n",
+ " print(f\"Masking -9999 NODATA sentinel in: {sentinel_hits.to_dict()}\")\n",
+ "df_extra[EXTRA_FEATURE_COLS] = df_extra[EXTRA_FEATURE_COLS].replace(-9999, np.nan)\n",
+ "\n",
+ "print(f\"Additional predictors loaded: {EXTRA_FEATURE_COLS}\")\n",
+ "print(f\"df_extra: {len(df_extra)} COMIDs\")\n",
+ "\n",
+ "# fold into the main predictor table used downstream\n",
+ "df_predictors = df_predictors.merge(df_extra, on=\"COMID\", how=\"left\")\n",
+ "print(f\"df_predictors now has {df_predictors.shape[1]} columns, {len(df_predictors)} rows\")\n",
+ "\n",
+ "# defensive check on the ORIGINAL 11 predictor columns too -- different source\n",
+ "# file, unknown NODATA convention, but flag anything that looks like a sentinel\n",
+ "# rather than silently trusting it\n",
+ "orig_cols = [\"TotDASqKM\", \"CAT_SILTAVE\", \"QE_cms\", \"D50_mm_\", \"HydraulicRadius (m)\",\n",
+ " \"Volume (m3)\", \"WetArea (m2)\", \"HYDRLCONDCAT\", \"WTDEPCAT\", \"PERMCAT\", \"StreamOrde\"]\n",
+ "suspect = {c: int((df_predictors[c] <= -100).sum()) for c in orig_cols\n",
+ " if (df_predictors[c] <= -100).any()}\n",
+ "if suspect:\n",
+ " print(f\"\\u26a0 Suspiciously negative values (possible sentinel) in original predictors: {suspect}\")\n",
+ "else:\n",
+ " print(\"No suspicious sentinel-like values found in the original 11 predictor columns.\")"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "57e14c57",
+ "metadata": {},
+ "source": [
+ "# Stage-Dependent Manning's n — Calibration & XGBoost Regionalization\n",
+ "\n",
+ "**Goal:** Extract zone-specific Manning's n values written by s05 into calibrated SRC files, then train an XGBoost model to regionalize those values across ungauged CONUS reaches using watershed/channel predictors.\n",
+ "\n",
+ "**Workflow:**\n",
+ "\n",
+ "| Step | Cell | Disk needed? |\n",
+ "|------|------|-------------|\n",
+ "| Build `n_zones_summary.csv` from s05 outputs | Step 0 (`RECOMPUTE_SUMMARY = True`) | Yes — once |\n",
+ "| Load existing summary | Step 0 (`RECOMPUTE_SUMMARY = False`) | No |\n",
+ "| Merge with CONUS predictors + train XGBoost | Steps 1–2 | No |"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "4edef7fb",
+ "metadata": {},
+ "source": [
+ "### Step 0 — Build `n_zones_summary.csv` from s05 outputs\n",
+ "\n",
+ "Reads `zonal_n_applied` written by s05 directly from the calibrated SRC files. \n",
+ "Set `RECOMPUTE_SUMMARY = True` the first time (disk connected), then switch to `False`."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "id": "8d318cbb",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:24.871519Z",
+ "iopub.status.busy": "2026-07-10T12:09:24.871519Z",
+ "iopub.status.idle": "2026-07-10T12:09:25.040156Z",
+ "shell.execute_reply": "2026-07-10T12:09:25.040156Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "HUCs: ['03020101', '03020102', '03020103', '03020104', '03020201', '03020202', '03020203', '03020204', '03030001', '03030002', '03030003', '03030004', '03030005', '03030006', '03030007', '03040101', '03040102', '03040103', '03040104', '03040105', '03040201', '03040202', '03040203', '03040204', '03040206', '12010005', '12020003', '12020006', '12020007', '12040102', '12100201']\n",
+ "HUC 03020101: 5 calibrated gauge rows\n",
+ "HUC 03020102: 2 calibrated gauge rows\n",
+ "HUC 03020103: 2 calibrated gauge rows\n",
+ "HUC 03020104: ncalib_diagnostics.csv not found -- skipping\n",
+ "HUC 03020201: 17 calibrated gauge rows\n",
+ "HUC 03020202: 3 calibrated gauge rows\n",
+ "HUC 03020203: 3 calibrated gauge rows\n",
+ "HUC 03020204: ncalib_diagnostics.csv not found -- skipping\n",
+ "HUC 03030001: ncalib_diagnostics.csv not found -- skipping\n",
+ "HUC 03030002: 13 calibrated gauge rows\n",
+ "HUC 03030003: 5 calibrated gauge rows\n",
+ "HUC 03030004: 4 calibrated gauge rows\n",
+ "HUC 03030005: 2 calibrated gauge rows\n",
+ "HUC 03030006: 1 calibrated gauge rows\n",
+ "HUC 03030007: 1 calibrated gauge rows\n",
+ "HUC 03040101: 9 calibrated gauge rows\n",
+ "HUC 03040102: 3 calibrated gauge rows\n",
+ "HUC 03040103: 2 calibrated gauge rows\n",
+ "HUC 03040104: 2 calibrated gauge rows\n",
+ "HUC 03040105: 6 calibrated gauge rows\n",
+ "HUC 03040201: 7 calibrated gauge rows\n",
+ "HUC 03040202: 3 calibrated gauge rows\n",
+ "HUC 03040203: 6 calibrated gauge rows\n",
+ "HUC 03040204: 3 calibrated gauge rows\n",
+ "HUC 03040206: 3 calibrated gauge rows\n",
+ "HUC 12010005: 7 calibrated gauge rows\n",
+ "HUC 12020003: 3 calibrated gauge rows\n",
+ "HUC 12020006: 1 calibrated gauge rows\n",
+ "HUC 12020007: 1 calibrated gauge rows\n",
+ "HUC 12040102: 8 calibrated gauge rows\n",
+ "HUC 12100201: 6 calibrated gauge rows\n",
+ "\n",
+ "Masked 92 pinned zone-values (exactly at N_MIN=0.01 or N_MAX=0.3) to NaN\n",
+ "Saved 128 rows to E:\\SI\\n_zones_summary.csv\n",
+ "Disconnect the hard disk and set RECOMPUTE_SUMMARY = False for future runs.\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " HUC8 | \n",
+ " location_id | \n",
+ " feature_id | \n",
+ " HydroID | \n",
+ " levpa_id | \n",
+ " n_2yr | \n",
+ " n_5yr | \n",
+ " n_10yr | \n",
+ " n_25yr | \n",
+ " n_50yr | \n",
+ " h0_elev_m | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 03020101 | \n",
+ " 02082585 | \n",
+ " 8762349 | \n",
+ " 11580120 | \n",
+ " 3351000001 | \n",
+ " 0.0431 | \n",
+ " 0.0568 | \n",
+ " 0.0859 | \n",
+ " 0.0806 | \n",
+ " 0.0790 | \n",
+ " 16.716567 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 03020101 | \n",
+ " 02081500 | \n",
+ " 8760623 | \n",
+ " 11580034 | \n",
+ " 3351000001 | \n",
+ " 0.0397 | \n",
+ " 0.0442 | \n",
+ " 0.0570 | \n",
+ " 0.0702 | \n",
+ " NaN | \n",
+ " 87.558177 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 03020101 | \n",
+ " 02081747 | \n",
+ " 8759765 | \n",
+ " 11580063 | \n",
+ " 3351000001 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 0.2924 | \n",
+ " 54.337554 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 03020101 | \n",
+ " 02081942 | \n",
+ " 8764333 | \n",
+ " 11580095 | \n",
+ " 3351000001 | \n",
+ " 0.0648 | \n",
+ " 0.1745 | \n",
+ " 0.1539 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 39.630955 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 03020101 | \n",
+ " 0208250410 | \n",
+ " 8762653 | \n",
+ " 11580110 | \n",
+ " 3351000001 | \n",
+ " 0.0492 | \n",
+ " 0.1276 | \n",
+ " 0.1940 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 28.198384 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 123 | \n",
+ " 12100201 | \n",
+ " 08166200 | \n",
+ " 3585724 | \n",
+ " 25130054 | \n",
+ " 1619000001 | \n",
+ " 0.0347 | \n",
+ " 0.0456 | \n",
+ " 0.0611 | \n",
+ " 0.0723 | \n",
+ " 0.0677 | \n",
+ " 487.826177 | \n",
+ "
\n",
+ " \n",
+ " | 124 | \n",
+ " 12100201 | \n",
+ " 08165300 | \n",
+ " 3585678 | \n",
+ " 25130035 | \n",
+ " 1619000001 | \n",
+ " 0.0795 | \n",
+ " 0.0506 | \n",
+ " 0.0417 | \n",
+ " 0.0408 | \n",
+ " 0.0413 | \n",
+ " 548.985728 | \n",
+ "
\n",
+ " \n",
+ " | 125 | \n",
+ " 12100201 | \n",
+ " 08167500 | \n",
+ " 3589120 | \n",
+ " 25130151 | \n",
+ " 1619000001 | \n",
+ " 0.0344 | \n",
+ " 0.0475 | \n",
+ " 0.0564 | \n",
+ " 0.0425 | \n",
+ " NaN | \n",
+ " 289.201192 | \n",
+ "
\n",
+ " \n",
+ " | 126 | \n",
+ " 12100201 | \n",
+ " 08167200 | \n",
+ " 3589062 | \n",
+ " 25130115 | \n",
+ " 1619000001 | \n",
+ " 0.0238 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 350.567036 | \n",
+ "
\n",
+ " \n",
+ " | 127 | \n",
+ " 12100201 | \n",
+ " 08166000 | \n",
+ " 3585554 | \n",
+ " 25130018 | \n",
+ " 1619000014 | \n",
+ " NaN | \n",
+ " 0.0421 | \n",
+ " 0.0368 | \n",
+ " 0.0275 | \n",
+ " 0.0239 | \n",
+ " 524.543834 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
128 rows × 11 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " HUC8 location_id feature_id HydroID levpa_id n_2yr n_5yr \\\n",
+ "0 03020101 02082585 8762349 11580120 3351000001 0.0431 0.0568 \n",
+ "1 03020101 02081500 8760623 11580034 3351000001 0.0397 0.0442 \n",
+ "2 03020101 02081747 8759765 11580063 3351000001 NaN NaN \n",
+ "3 03020101 02081942 8764333 11580095 3351000001 0.0648 0.1745 \n",
+ "4 03020101 0208250410 8762653 11580110 3351000001 0.0492 0.1276 \n",
+ ".. ... ... ... ... ... ... ... \n",
+ "123 12100201 08166200 3585724 25130054 1619000001 0.0347 0.0456 \n",
+ "124 12100201 08165300 3585678 25130035 1619000001 0.0795 0.0506 \n",
+ "125 12100201 08167500 3589120 25130151 1619000001 0.0344 0.0475 \n",
+ "126 12100201 08167200 3589062 25130115 1619000001 0.0238 NaN \n",
+ "127 12100201 08166000 3585554 25130018 1619000014 NaN 0.0421 \n",
+ "\n",
+ " n_10yr n_25yr n_50yr h0_elev_m \n",
+ "0 0.0859 0.0806 0.0790 16.716567 \n",
+ "1 0.0570 0.0702 NaN 87.558177 \n",
+ "2 NaN NaN 0.2924 54.337554 \n",
+ "3 0.1539 NaN NaN 39.630955 \n",
+ "4 0.1940 NaN NaN 28.198384 \n",
+ ".. ... ... ... ... \n",
+ "123 0.0611 0.0723 0.0677 487.826177 \n",
+ "124 0.0417 0.0408 0.0413 548.985728 \n",
+ "125 0.0564 0.0425 NaN 289.201192 \n",
+ "126 NaN NaN NaN 350.567036 \n",
+ "127 0.0368 0.0275 0.0239 524.543834 \n",
+ "\n",
+ "[128 rows x 11 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "from pathlib import Path\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "\n",
+ "# ── Two data locations ───────────────────────────────────────────────────────────────────\n",
+ "ML_DIR = Path(r\"E:\\SI\") # HUC list, summary CSV\n",
+ "DISK_DIR = Path(r\"E:\\SI\\out\") # ncalib_diagnostics.csv per HUC (hard disk, needed only once)\n",
+ "OUT_DIR = Path(r\"E:\\SI\\out\\ML\") # summary CSV (saved to ML_DIR)\n",
+ "\n",
+ "HUC_LIST_PATH = ML_DIR / \"HUC.txt\"\n",
+ "SUMMARY_OUT = ML_DIR / \"n_zones_summary.csv\"\n",
+ "RECURRENCE_YEARS = [2, 5, 10, 25, 50]\n",
+ "\n",
+ "# Zone-n clip bounds from scripts/s05_ncalib_core.py (N_MIN/N_MAX) — any zone\n",
+ "# value sitting exactly on a bound is the optimizer pinned against the cap,\n",
+ "# not a real calibrated roughness, so it must not be used as an ML label.\n",
+ "N_MIN_BOUND = 0.010\n",
+ "N_MAX_BOUND = 0.300\n",
+ "\n",
+ "# ── Flag ───────────────────────────────────────────────────────────────────────────\n",
+ "RECOMPUTE_SUMMARY = True # True → read ncalib_diagnostics.csv from hard disk, save CSV to ML_DIR\n",
+ " # False → load existing n_zones_summary.csv from ML_DIR (no disk needed)\n",
+ "# ─────────────────────────────────────────────────────────────────────────────\n",
+ "\n",
+ "if RECOMPUTE_SUMMARY:\n",
+ " hucs = pd.read_csv(HUC_LIST_PATH, dtype=str)[\"HUC\"].tolist()\n",
+ " print(f\"HUCs: {hucs}\")\n",
+ "\n",
+ " n_cols = [f\"n_{yr}yr\" for yr in RECURRENCE_YEARS]\n",
+ " n_eff_cols = [f\"n_eff_{yr}yr\" for yr in RECURRENCE_YEARS]\n",
+ "\n",
+ " all_rows = []\n",
+ " total_pinned = 0\n",
+ " for huc8 in hucs:\n",
+ " diag_path = DISK_DIR / f\"HUC{huc8}\" / \"ncalib_diagnostics.csv\"\n",
+ " if not diag_path.exists():\n",
+ " print(f\"HUC {huc8}: ncalib_diagnostics.csv not found -- skipping\")\n",
+ " continue\n",
+ "\n",
+ " diag = pd.read_csv(\n",
+ " diag_path,\n",
+ " dtype={\"huc8\": str, \"branch\": str, \"location_id\": str},\n",
+ " )\n",
+ " diag = diag[diag[\"status\"] == \"calibrated\"].copy()\n",
+ " if diag.empty:\n",
+ " print(f\"HUC {huc8}: no calibrated rows -- skipping\")\n",
+ " continue\n",
+ "\n",
+ " diag[\"feature_id\"] = diag[\"feature_id\"].astype(int)\n",
+ " diag = diag.rename(columns={\n",
+ " \"huc8\": \"HUC8\", \"branch\": \"levpa_id\", \"hydroid\": \"HydroID\",\n",
+ " })\n",
+ "\n",
+ " # target = raw calibrated n (pre clip/monotonic-fix); drop the\n",
+ " # effective-n columns so n_{yr}yr keeps its original values\n",
+ " diag = diag.drop(columns=n_eff_cols, errors=\"ignore\")\n",
+ "\n",
+ " # mask pinned zone-values: a value sitting exactly on N_MIN/N_MAX\n",
+ " # means the optimizer hit its bound, not a physically meaningful n\n",
+ " pinned_mask = diag[n_cols].isin([N_MIN_BOUND, N_MAX_BOUND])\n",
+ " total_pinned += int(pinned_mask.to_numpy().sum())\n",
+ " diag[n_cols] = diag[n_cols].mask(pinned_mask)\n",
+ "\n",
+ " keep_cols = [\"HUC8\", \"location_id\", \"feature_id\", \"HydroID\", \"levpa_id\"] + n_cols + [\"h0_elev_m\"]\n",
+ " all_rows.append(diag[keep_cols])\n",
+ " print(f\"HUC {huc8}: {len(diag)} calibrated gauge rows\")\n",
+ "\n",
+ " df_n_zones = pd.concat(all_rows, ignore_index=True) if all_rows else pd.DataFrame()\n",
+ " df_n_zones.to_csv(SUMMARY_OUT, index=False)\n",
+ " print(f\"\\nMasked {total_pinned} pinned zone-values (exactly at N_MIN={N_MIN_BOUND} or N_MAX={N_MAX_BOUND}) to NaN\")\n",
+ " print(f\"Saved {len(df_n_zones)} rows to {SUMMARY_OUT}\")\n",
+ " print(\"Disconnect the hard disk and set RECOMPUTE_SUMMARY = False for future runs.\")\n",
+ "\n",
+ "else:\n",
+ " if not SUMMARY_OUT.exists():\n",
+ " raise FileNotFoundError(\n",
+ " f\"{SUMMARY_OUT} not found. Set RECOMPUTE_SUMMARY = True and re-run with hard disk connected.\"\n",
+ " )\n",
+ " df_n_zones = pd.read_csv(SUMMARY_OUT, dtype={\"location_id\": str, \"HUC8\": str})\n",
+ " print(f\"Loaded {len(df_n_zones)} rows from {SUMMARY_OUT}\")\n",
+ "\n",
+ "display(df_n_zones)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "own-geom-md",
+ "metadata": {},
+ "source": [
+ "### Step 0b — Zone-specific geometry from each gauge's own hydroTable\n",
+ "\n",
+ "Verified that `HydraulicRadius (m)` / `WetArea (m2)` / `Volume (m3)` in the CONUS\n",
+ "predictor file do **not** match this pipeline's own hydroTable geometry for the\n",
+ "same reach at any stage (checked 4 gauges directly — off by 30-95%, not even\n",
+ "proportional). That file is an independently-computed OWP CONUS product, not\n",
+ "this run's HAND geometry, so those three columns are replaced here with values\n",
+ "read directly from each gauge's own hydroTable, interpolated at the actual NWM\n",
+ "recurrence discharge for each zone — geometry now varies by zone instead of\n",
+ "being one static snapshot reused for all 5 targets.\n",
+ "\n",
+ "**Caveat:** this corrected geometry only exists where we've already run HAND\n",
+ "(i.e. for the calibrated gauges themselves) — there is no hydroTable for the\n",
+ "~2.16M ungauged CONUS reaches in the predictor file, so it can only be used\n",
+ "for the training/CV comparison below, not for the CONUS-wide prediction step\n",
+ "(which still needs the external predictor file's geometry, mismatch and all,\n",
+ "because it's the only geometry source that exists at that scale)."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "id": "own-geom-code",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:25.043161Z",
+ "iopub.status.busy": "2026-07-10T12:09:25.043161Z",
+ "iopub.status.idle": "2026-07-10T12:09:32.824267Z",
+ "shell.execute_reply": "2026-07-10T12:09:32.824267Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Computed zone-specific geometry for 101/128 gauges -> E:\\SI\\n_zones_geometry.csv\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " HUC8 | \n",
+ " location_id | \n",
+ " HydroID | \n",
+ " HydraulicRadius_2yr | \n",
+ " WetArea_2yr | \n",
+ " Volume_2yr | \n",
+ " HydraulicRadius_5yr | \n",
+ " WetArea_5yr | \n",
+ " Volume_5yr | \n",
+ " HydraulicRadius_10yr | \n",
+ " WetArea_10yr | \n",
+ " Volume_10yr | \n",
+ " HydraulicRadius_25yr | \n",
+ " WetArea_25yr | \n",
+ " Volume_25yr | \n",
+ " HydraulicRadius_50yr | \n",
+ " WetArea_50yr | \n",
+ " Volume_50yr | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 03020101 | \n",
+ " 02082585 | \n",
+ " 11580120 | \n",
+ " 1.167072 | \n",
+ " 50.990522 | \n",
+ " 8.115852e+04 | \n",
+ " 1.418776 | \n",
+ " 348.537192 | \n",
+ " 5.547455e+05 | \n",
+ " 1.741471 | \n",
+ " 552.469070 | \n",
+ " 8.793315e+05 | \n",
+ " 2.044470 | \n",
+ " 774.429525 | \n",
+ " 1.232613e+06 | \n",
+ " 2.190938 | \n",
+ " 930.891667 | \n",
+ " 1.481644e+06 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 03020101 | \n",
+ " 02081500 | \n",
+ " 11580034 | \n",
+ " 0.404090 | \n",
+ " 16.289114 | \n",
+ " 2.458493e+04 | \n",
+ " 1.511877 | \n",
+ " 94.594455 | \n",
+ " 1.427701e+05 | \n",
+ " 2.101477 | \n",
+ " 160.589392 | \n",
+ " 2.423753e+05 | \n",
+ " 2.802650 | \n",
+ " 255.163010 | \n",
+ " 3.851139e+05 | \n",
+ " 3.265005 | \n",
+ " 319.424570 | \n",
+ " 4.821029e+05 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 03020101 | \n",
+ " 02081747 | \n",
+ " 11580063 | \n",
+ " 2.014682 | \n",
+ " 1801.646463 | \n",
+ " 2.742128e+06 | \n",
+ " 2.590216 | \n",
+ " 2876.286156 | \n",
+ " 4.377742e+06 | \n",
+ " 2.840121 | \n",
+ " 3489.875885 | \n",
+ " 5.311633e+06 | \n",
+ " 3.043357 | \n",
+ " 4151.062176 | \n",
+ " 6.317967e+06 | \n",
+ " 3.170108 | \n",
+ " 4526.546801 | \n",
+ " 6.889459e+06 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 03020101 | \n",
+ " 02081942 | \n",
+ " 11580095 | \n",
+ " 1.169037 | \n",
+ " 333.595910 | \n",
+ " 5.047384e+05 | \n",
+ " 2.328504 | \n",
+ " 938.578949 | \n",
+ " 1.420092e+06 | \n",
+ " 2.812980 | \n",
+ " 1239.563996 | \n",
+ " 1.875489e+06 | \n",
+ " 3.231494 | \n",
+ " 1571.730354 | \n",
+ " 2.378065e+06 | \n",
+ " 3.499964 | \n",
+ " 1769.758274 | \n",
+ " 2.677685e+06 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 03020101 | \n",
+ " 0208250410 | \n",
+ " 11580110 | \n",
+ " 1.139647 | \n",
+ " 144.914535 | \n",
+ " 2.167333e+05 | \n",
+ " 2.103318 | \n",
+ " 393.934820 | \n",
+ " 5.891665e+05 | \n",
+ " 2.756742 | \n",
+ " 590.681361 | \n",
+ " 8.834195e+05 | \n",
+ " 3.346425 | \n",
+ " 792.470086 | \n",
+ " 1.185213e+06 | \n",
+ " 3.683909 | \n",
+ " 915.158483 | \n",
+ " 1.368706e+06 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 123 | \n",
+ " 12100201 | \n",
+ " 08166200 | \n",
+ " 25130054 | \n",
+ " 0.445704 | \n",
+ " 28.278761 | \n",
+ " 4.298455e+04 | \n",
+ " 1.058352 | \n",
+ " 129.667830 | \n",
+ " 1.970989e+05 | \n",
+ " 1.792117 | \n",
+ " 277.285330 | \n",
+ " 4.214819e+05 | \n",
+ " 3.226002 | \n",
+ " 577.506537 | \n",
+ " 8.778270e+05 | \n",
+ " 4.472492 | \n",
+ " 857.385272 | \n",
+ " 1.303251e+06 | \n",
+ "
\n",
+ " \n",
+ " | 124 | \n",
+ " 12100201 | \n",
+ " 08165300 | \n",
+ " 25130035 | \n",
+ " 0.456540 | \n",
+ " 24.998286 | \n",
+ " 3.749493e+04 | \n",
+ " 1.227516 | \n",
+ " 93.415626 | \n",
+ " 1.401141e+05 | \n",
+ " 1.781167 | \n",
+ " 183.073734 | \n",
+ " 2.745923e+05 | \n",
+ " 2.607748 | \n",
+ " 383.331095 | \n",
+ " 5.749583e+05 | \n",
+ " 3.281243 | \n",
+ " 619.040645 | \n",
+ " 9.284990e+05 | \n",
+ "
\n",
+ " \n",
+ " | 125 | \n",
+ " 12100201 | \n",
+ " 08167500 | \n",
+ " 25130151 | \n",
+ " 1.353361 | \n",
+ " 76.647073 | \n",
+ " 1.161414e+05 | \n",
+ " 3.667195 | \n",
+ " 369.204879 | \n",
+ " 5.594470e+05 | \n",
+ " 4.865419 | \n",
+ " 792.692532 | \n",
+ " 1.201147e+06 | \n",
+ " 4.102160 | \n",
+ " 1808.047023 | \n",
+ " 2.739689e+06 | \n",
+ " 4.197774 | \n",
+ " 2787.088584 | \n",
+ " 4.223206e+06 | \n",
+ "
\n",
+ " \n",
+ " | 126 | \n",
+ " 12100201 | \n",
+ " 08167200 | \n",
+ " 25130115 | \n",
+ " 0.804814 | \n",
+ " 24.136225 | \n",
+ " 3.621856e+04 | \n",
+ " 3.336709 | \n",
+ " 182.656353 | \n",
+ " 2.740922e+05 | \n",
+ " 4.589087 | \n",
+ " 406.840198 | \n",
+ " 6.105001e+05 | \n",
+ " 5.106773 | \n",
+ " 979.496306 | \n",
+ " 1.469822e+06 | \n",
+ " 5.196685 | \n",
+ " 1706.668773 | \n",
+ " 2.561009e+06 | \n",
+ "
\n",
+ " \n",
+ " | 127 | \n",
+ " 12100201 | \n",
+ " 08166000 | \n",
+ " 25130018 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 0.724572 | \n",
+ " 39.316969 | \n",
+ " 5.871783e+04 | \n",
+ " 1.442382 | \n",
+ " 99.871342 | \n",
+ " 1.491526e+05 | \n",
+ " 2.459820 | \n",
+ " 211.863871 | \n",
+ " 3.164076e+05 | \n",
+ " 3.229235 | \n",
+ " 349.374982 | \n",
+ " 5.217732e+05 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
128 rows × 18 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " HUC8 location_id HydroID HydraulicRadius_2yr WetArea_2yr \\\n",
+ "0 03020101 02082585 11580120 1.167072 50.990522 \n",
+ "1 03020101 02081500 11580034 0.404090 16.289114 \n",
+ "2 03020101 02081747 11580063 2.014682 1801.646463 \n",
+ "3 03020101 02081942 11580095 1.169037 333.595910 \n",
+ "4 03020101 0208250410 11580110 1.139647 144.914535 \n",
+ ".. ... ... ... ... ... \n",
+ "123 12100201 08166200 25130054 0.445704 28.278761 \n",
+ "124 12100201 08165300 25130035 0.456540 24.998286 \n",
+ "125 12100201 08167500 25130151 1.353361 76.647073 \n",
+ "126 12100201 08167200 25130115 0.804814 24.136225 \n",
+ "127 12100201 08166000 25130018 NaN NaN \n",
+ "\n",
+ " Volume_2yr HydraulicRadius_5yr WetArea_5yr Volume_5yr \\\n",
+ "0 8.115852e+04 1.418776 348.537192 5.547455e+05 \n",
+ "1 2.458493e+04 1.511877 94.594455 1.427701e+05 \n",
+ "2 2.742128e+06 2.590216 2876.286156 4.377742e+06 \n",
+ "3 5.047384e+05 2.328504 938.578949 1.420092e+06 \n",
+ "4 2.167333e+05 2.103318 393.934820 5.891665e+05 \n",
+ ".. ... ... ... ... \n",
+ "123 4.298455e+04 1.058352 129.667830 1.970989e+05 \n",
+ "124 3.749493e+04 1.227516 93.415626 1.401141e+05 \n",
+ "125 1.161414e+05 3.667195 369.204879 5.594470e+05 \n",
+ "126 3.621856e+04 3.336709 182.656353 2.740922e+05 \n",
+ "127 NaN 0.724572 39.316969 5.871783e+04 \n",
+ "\n",
+ " HydraulicRadius_10yr WetArea_10yr Volume_10yr HydraulicRadius_25yr \\\n",
+ "0 1.741471 552.469070 8.793315e+05 2.044470 \n",
+ "1 2.101477 160.589392 2.423753e+05 2.802650 \n",
+ "2 2.840121 3489.875885 5.311633e+06 3.043357 \n",
+ "3 2.812980 1239.563996 1.875489e+06 3.231494 \n",
+ "4 2.756742 590.681361 8.834195e+05 3.346425 \n",
+ ".. ... ... ... ... \n",
+ "123 1.792117 277.285330 4.214819e+05 3.226002 \n",
+ "124 1.781167 183.073734 2.745923e+05 2.607748 \n",
+ "125 4.865419 792.692532 1.201147e+06 4.102160 \n",
+ "126 4.589087 406.840198 6.105001e+05 5.106773 \n",
+ "127 1.442382 99.871342 1.491526e+05 2.459820 \n",
+ "\n",
+ " WetArea_25yr Volume_25yr HydraulicRadius_50yr WetArea_50yr \\\n",
+ "0 774.429525 1.232613e+06 2.190938 930.891667 \n",
+ "1 255.163010 3.851139e+05 3.265005 319.424570 \n",
+ "2 4151.062176 6.317967e+06 3.170108 4526.546801 \n",
+ "3 1571.730354 2.378065e+06 3.499964 1769.758274 \n",
+ "4 792.470086 1.185213e+06 3.683909 915.158483 \n",
+ ".. ... ... ... ... \n",
+ "123 577.506537 8.778270e+05 4.472492 857.385272 \n",
+ "124 383.331095 5.749583e+05 3.281243 619.040645 \n",
+ "125 1808.047023 2.739689e+06 4.197774 2787.088584 \n",
+ "126 979.496306 1.469822e+06 5.196685 1706.668773 \n",
+ "127 211.863871 3.164076e+05 3.229235 349.374982 \n",
+ "\n",
+ " Volume_50yr \n",
+ "0 1.481644e+06 \n",
+ "1 4.821029e+05 \n",
+ "2 6.889459e+06 \n",
+ "3 2.677685e+06 \n",
+ "4 1.368706e+06 \n",
+ ".. ... \n",
+ "123 1.303251e+06 \n",
+ "124 9.284990e+05 \n",
+ "125 4.223206e+06 \n",
+ "126 2.561009e+06 \n",
+ "127 5.217732e+05 \n",
+ "\n",
+ "[128 rows x 18 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "from pathlib import Path\n",
+ "\n",
+ "REPO_DATA_DIR = Path(r\"c:\\Users\\Ali\\OneDrive - CUNY\\Desktop\\SI\\fimbox_SI26\\data\")\n",
+ "GEOM_OUT = ML_DIR / \"n_zones_geometry.csv\"\n",
+ "GEOM_BASE_NAMES = [\"HydraulicRadius\", \"WetArea\", \"Volume\"]\n",
+ "GEOM_COLS_IN = [\"HydraulicRadius (m)\", \"WetArea (m2)\", \"Volume (m3)\"]\n",
+ "\n",
+ "if RECOMPUTE_SUMMARY:\n",
+ " recur = pd.read_parquet(REPO_DATA_DIR / \"nwm3_17C_recurrence_flows_cfs.parquet\")\n",
+ " for yr in RECURRENCE_YEARS:\n",
+ " recur[f\"Q_{yr}yr_cms\"] = recur[f\"{yr}_0_year_recurrence_flow_17C\"].astype(float) * 0.028317\n",
+ " recur[\"feature_id\"] = recur[\"feature_id\"].astype(\"Int64\")\n",
+ "\n",
+ " ht_cache: dict[tuple, pd.DataFrame] = {}\n",
+ "\n",
+ " def load_hydrotable(huc8: str, branch: str):\n",
+ " key = (huc8, branch)\n",
+ " if key not in ht_cache:\n",
+ " path = (DISK_DIR / f\"HUC{huc8}\" / \"watershed-data\" / \"branches\"\n",
+ " / branch / f\"hydroTable_{branch}.csv\")\n",
+ " ht_cache[key] = pd.read_csv(path, dtype={\"HydroID\": int}) if path.exists() else None\n",
+ " return ht_cache[key]\n",
+ "\n",
+ " geom_rows = []\n",
+ " for _, row in df_n_zones.iterrows():\n",
+ " feat_id = int(row[\"feature_id\"])\n",
+ " out = {\"HUC8\": row[\"HUC8\"], \"location_id\": row[\"location_id\"], \"HydroID\": row[\"HydroID\"]}\n",
+ " ht = load_hydrotable(row[\"HUC8\"], row[\"levpa_id\"])\n",
+ " if ht is not None:\n",
+ " hrow = ht[ht[\"HydroID\"] == row[\"HydroID\"]].sort_values(\"stage\")\n",
+ " feat_recur = recur[recur[\"feature_id\"] == feat_id]\n",
+ " if not hrow.empty and not feat_recur.empty:\n",
+ " q_arr = hrow[\"discharge_cms\"].values\n",
+ " for yr in RECURRENCE_YEARS:\n",
+ " Q_r = float(feat_recur[f\"Q_{yr}yr_cms\"].iloc[0])\n",
+ " if Q_r <= 0 or Q_r < q_arr.min() or Q_r > q_arr.max():\n",
+ " continue\n",
+ " for name, col_in in zip(GEOM_BASE_NAMES, GEOM_COLS_IN):\n",
+ " out[f\"{name}_{yr}yr\"] = float(np.interp(Q_r, q_arr, hrow[col_in].values))\n",
+ " geom_rows.append(out)\n",
+ "\n",
+ " df_geom = pd.DataFrame(geom_rows)\n",
+ " df_geom.to_csv(GEOM_OUT, index=False)\n",
+ " have = sum(f\"{GEOM_BASE_NAMES[0]}_2yr\" in r for r in geom_rows)\n",
+ " print(f\"Computed zone-specific geometry for {have}/{len(df_geom)} gauges -> {GEOM_OUT}\")\n",
+ "else:\n",
+ " if not GEOM_OUT.exists():\n",
+ " raise FileNotFoundError(\n",
+ " f\"{GEOM_OUT} not found. Set RECOMPUTE_SUMMARY = True and re-run with hard disk connected.\"\n",
+ " )\n",
+ " df_geom = pd.read_csv(GEOM_OUT, dtype={\"location_id\": str, \"HUC8\": str})\n",
+ " print(f\"Loaded zone-specific geometry for {len(df_geom)} gauges from {GEOM_OUT}\")\n",
+ "\n",
+ "display(df_geom)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "id": "4b055b09",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:32.827284Z",
+ "iopub.status.busy": "2026-07-10T12:09:32.827284Z",
+ "iopub.status.idle": "2026-07-10T12:09:33.475622Z",
+ "shell.execute_reply": "2026-07-10T12:09:33.475113Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Merged dataset: 125 rows | 125 unique gauges\n",
+ "26 base features (11 orig[-3 geom] + 18 EVI/STATSGO) + 3 zone-specific geometry features per target (or 3 static _EXT features for the comparison cell)\n",
+ "\n",
+ "Available targets (non-null counts):\n",
+ "n_2yr 83\n",
+ "n_5yr 82\n",
+ "n_10yr 82\n",
+ "n_25yr 73\n",
+ "n_50yr 64\n",
+ "h0_elev_m 122\n",
+ "\n",
+ "Zone-geometry coverage (non-null counts):\n",
+ "HydraulicRadius_2yr 98\n",
+ "WetArea_2yr 98\n",
+ "Volume_2yr 98\n",
+ "HydraulicRadius_5yr 111\n",
+ "WetArea_5yr 111\n",
+ "Volume_5yr 111\n",
+ "HydraulicRadius_10yr 117\n",
+ "WetArea_10yr 117\n",
+ "Volume_10yr 117\n",
+ "HydraulicRadius_25yr 122\n",
+ "WetArea_25yr 122\n",
+ "Volume_25yr 122\n",
+ "HydraulicRadius_50yr 125\n",
+ "WetArea_50yr 125\n",
+ "Volume_50yr 125\n"
+ ]
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " HUC8 | \n",
+ " location_id | \n",
+ " feature_id | \n",
+ " HydroID | \n",
+ " n_2yr | \n",
+ " n_5yr | \n",
+ " n_10yr | \n",
+ " n_25yr | \n",
+ " n_50yr | \n",
+ " h0_elev_m | \n",
+ " ... | \n",
+ " Volume_10yr | \n",
+ " HydraulicRadius_25yr | \n",
+ " WetArea_25yr | \n",
+ " Volume_25yr | \n",
+ " HydraulicRadius_50yr | \n",
+ " WetArea_50yr | \n",
+ " Volume_50yr | \n",
+ " HydraulicRadius_EXT | \n",
+ " WetArea_EXT | \n",
+ " Volume_EXT | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " | 0 | \n",
+ " 03020101 | \n",
+ " 02082585 | \n",
+ " 8762349 | \n",
+ " 11580120 | \n",
+ " 0.0431 | \n",
+ " 0.0568 | \n",
+ " 0.0859 | \n",
+ " 0.0806 | \n",
+ " 0.0790 | \n",
+ " 16.716567 | \n",
+ " ... | \n",
+ " 8.793315e+05 | \n",
+ " 2.044470 | \n",
+ " 774.429525 | \n",
+ " 1.232613e+06 | \n",
+ " 2.190938 | \n",
+ " 930.891667 | \n",
+ " 1.481644e+06 | \n",
+ " 15.963237 | \n",
+ " 17707.124134 | \n",
+ " 1.950516e+07 | \n",
+ "
\n",
+ " \n",
+ " | 1 | \n",
+ " 03020101 | \n",
+ " 02081500 | \n",
+ " 8760623 | \n",
+ " 11580034 | \n",
+ " 0.0397 | \n",
+ " 0.0442 | \n",
+ " 0.0570 | \n",
+ " 0.0702 | \n",
+ " NaN | \n",
+ " 87.558177 | \n",
+ " ... | \n",
+ " 2.423753e+05 | \n",
+ " 2.802650 | \n",
+ " 255.163010 | \n",
+ " 3.851139e+05 | \n",
+ " 3.265005 | \n",
+ " 319.424570 | \n",
+ " 4.821029e+05 | \n",
+ " 10.657803 | \n",
+ " 4470.893497 | \n",
+ " 4.590222e+06 | \n",
+ "
\n",
+ " \n",
+ " | 2 | \n",
+ " 03020101 | \n",
+ " 02081747 | \n",
+ " 8759765 | \n",
+ " 11580063 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 0.2924 | \n",
+ " 54.337554 | \n",
+ " ... | \n",
+ " 5.311633e+06 | \n",
+ " 3.043357 | \n",
+ " 4151.062176 | \n",
+ " 6.317967e+06 | \n",
+ " 3.170108 | \n",
+ " 4526.546801 | \n",
+ " 6.889459e+06 | \n",
+ " 19.857827 | \n",
+ " 4588.204166 | \n",
+ " 3.543259e+06 | \n",
+ "
\n",
+ " \n",
+ " | 3 | \n",
+ " 03020101 | \n",
+ " 02081942 | \n",
+ " 8764333 | \n",
+ " 11580095 | \n",
+ " 0.0648 | \n",
+ " 0.1745 | \n",
+ " 0.1539 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 39.630955 | \n",
+ " ... | \n",
+ " 1.875489e+06 | \n",
+ " 3.231494 | \n",
+ " 1571.730354 | \n",
+ " 2.378065e+06 | \n",
+ " 3.499964 | \n",
+ " 1769.758274 | \n",
+ " 2.677685e+06 | \n",
+ " 14.024038 | \n",
+ " 13877.278759 | \n",
+ " 1.673980e+07 | \n",
+ "
\n",
+ " \n",
+ " | 4 | \n",
+ " 03020101 | \n",
+ " 0208250410 | \n",
+ " 8762653 | \n",
+ " 11580110 | \n",
+ " 0.0492 | \n",
+ " 0.1276 | \n",
+ " 0.1940 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 28.198384 | \n",
+ " ... | \n",
+ " 8.834195e+05 | \n",
+ " 3.346425 | \n",
+ " 792.470086 | \n",
+ " 1.185213e+06 | \n",
+ " 3.683909 | \n",
+ " 915.158483 | \n",
+ " 1.368706e+06 | \n",
+ " 17.733277 | \n",
+ " 11892.497653 | \n",
+ " 1.355093e+07 | \n",
+ "
\n",
+ " \n",
+ " | ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " | 120 | \n",
+ " 12100201 | \n",
+ " 08166200 | \n",
+ " 3585724 | \n",
+ " 25130054 | \n",
+ " 0.0347 | \n",
+ " 0.0456 | \n",
+ " 0.0611 | \n",
+ " 0.0723 | \n",
+ " 0.0677 | \n",
+ " 487.826177 | \n",
+ " ... | \n",
+ " 4.214819e+05 | \n",
+ " 3.226002 | \n",
+ " 577.506537 | \n",
+ " 8.778270e+05 | \n",
+ " 4.472492 | \n",
+ " 857.385272 | \n",
+ " 1.303251e+06 | \n",
+ " 14.269674 | \n",
+ " 9572.389411 | \n",
+ " 1.260387e+07 | \n",
+ "
\n",
+ " \n",
+ " | 121 | \n",
+ " 12100201 | \n",
+ " 08165300 | \n",
+ " 3585678 | \n",
+ " 25130035 | \n",
+ " 0.0795 | \n",
+ " 0.0506 | \n",
+ " 0.0417 | \n",
+ " 0.0408 | \n",
+ " 0.0413 | \n",
+ " 548.985728 | \n",
+ " ... | \n",
+ " 2.745923e+05 | \n",
+ " 2.607748 | \n",
+ " 383.331095 | \n",
+ " 5.749583e+05 | \n",
+ " 3.281243 | \n",
+ " 619.040645 | \n",
+ " 9.284990e+05 | \n",
+ " 15.066716 | \n",
+ " 7603.500637 | \n",
+ " 1.118124e+07 | \n",
+ "
\n",
+ " \n",
+ " | 122 | \n",
+ " 12100201 | \n",
+ " 08167500 | \n",
+ " 3589120 | \n",
+ " 25130151 | \n",
+ " 0.0344 | \n",
+ " 0.0475 | \n",
+ " 0.0564 | \n",
+ " 0.0425 | \n",
+ " NaN | \n",
+ " 289.201192 | \n",
+ " ... | \n",
+ " 1.201147e+06 | \n",
+ " 4.102160 | \n",
+ " 1808.047023 | \n",
+ " 2.739689e+06 | \n",
+ " 4.197774 | \n",
+ " 2787.088584 | \n",
+ " 4.223206e+06 | \n",
+ " 11.393790 | \n",
+ " 7335.934065 | \n",
+ " 1.054989e+07 | \n",
+ "
\n",
+ " \n",
+ " | 123 | \n",
+ " 12100201 | \n",
+ " 08167200 | \n",
+ " 3589062 | \n",
+ " 25130115 | \n",
+ " 0.0238 | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " NaN | \n",
+ " 350.567036 | \n",
+ " ... | \n",
+ " 6.105001e+05 | \n",
+ " 5.106773 | \n",
+ " 979.496306 | \n",
+ " 1.469822e+06 | \n",
+ " 5.196685 | \n",
+ " 1706.668773 | \n",
+ " 2.561009e+06 | \n",
+ " 10.747225 | \n",
+ " 5511.734147 | \n",
+ " 8.244491e+06 | \n",
+ "
\n",
+ " \n",
+ " | 124 | \n",
+ " 12100201 | \n",
+ " 08166000 | \n",
+ " 3585554 | \n",
+ " 25130018 | \n",
+ " NaN | \n",
+ " 0.0421 | \n",
+ " 0.0368 | \n",
+ " 0.0275 | \n",
+ " 0.0239 | \n",
+ " 524.543834 | \n",
+ " ... | \n",
+ " 1.491526e+05 | \n",
+ " 2.459820 | \n",
+ " 211.863871 | \n",
+ " 3.164076e+05 | \n",
+ " 3.229235 | \n",
+ " 349.374982 | \n",
+ " 5.217732e+05 | \n",
+ " 14.760597 | \n",
+ " 7100.041168 | \n",
+ " 9.537194e+06 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
125 rows × 54 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " HUC8 location_id feature_id HydroID n_2yr n_5yr n_10yr \\\n",
+ "0 03020101 02082585 8762349 11580120 0.0431 0.0568 0.0859 \n",
+ "1 03020101 02081500 8760623 11580034 0.0397 0.0442 0.0570 \n",
+ "2 03020101 02081747 8759765 11580063 NaN NaN NaN \n",
+ "3 03020101 02081942 8764333 11580095 0.0648 0.1745 0.1539 \n",
+ "4 03020101 0208250410 8762653 11580110 0.0492 0.1276 0.1940 \n",
+ ".. ... ... ... ... ... ... ... \n",
+ "120 12100201 08166200 3585724 25130054 0.0347 0.0456 0.0611 \n",
+ "121 12100201 08165300 3585678 25130035 0.0795 0.0506 0.0417 \n",
+ "122 12100201 08167500 3589120 25130151 0.0344 0.0475 0.0564 \n",
+ "123 12100201 08167200 3589062 25130115 0.0238 NaN NaN \n",
+ "124 12100201 08166000 3585554 25130018 NaN 0.0421 0.0368 \n",
+ "\n",
+ " n_25yr n_50yr h0_elev_m ... Volume_10yr HydraulicRadius_25yr \\\n",
+ "0 0.0806 0.0790 16.716567 ... 8.793315e+05 2.044470 \n",
+ "1 0.0702 NaN 87.558177 ... 2.423753e+05 2.802650 \n",
+ "2 NaN 0.2924 54.337554 ... 5.311633e+06 3.043357 \n",
+ "3 NaN NaN 39.630955 ... 1.875489e+06 3.231494 \n",
+ "4 NaN NaN 28.198384 ... 8.834195e+05 3.346425 \n",
+ ".. ... ... ... ... ... ... \n",
+ "120 0.0723 0.0677 487.826177 ... 4.214819e+05 3.226002 \n",
+ "121 0.0408 0.0413 548.985728 ... 2.745923e+05 2.607748 \n",
+ "122 0.0425 NaN 289.201192 ... 1.201147e+06 4.102160 \n",
+ "123 NaN NaN 350.567036 ... 6.105001e+05 5.106773 \n",
+ "124 0.0275 0.0239 524.543834 ... 1.491526e+05 2.459820 \n",
+ "\n",
+ " WetArea_25yr Volume_25yr HydraulicRadius_50yr WetArea_50yr \\\n",
+ "0 774.429525 1.232613e+06 2.190938 930.891667 \n",
+ "1 255.163010 3.851139e+05 3.265005 319.424570 \n",
+ "2 4151.062176 6.317967e+06 3.170108 4526.546801 \n",
+ "3 1571.730354 2.378065e+06 3.499964 1769.758274 \n",
+ "4 792.470086 1.185213e+06 3.683909 915.158483 \n",
+ ".. ... ... ... ... \n",
+ "120 577.506537 8.778270e+05 4.472492 857.385272 \n",
+ "121 383.331095 5.749583e+05 3.281243 619.040645 \n",
+ "122 1808.047023 2.739689e+06 4.197774 2787.088584 \n",
+ "123 979.496306 1.469822e+06 5.196685 1706.668773 \n",
+ "124 211.863871 3.164076e+05 3.229235 349.374982 \n",
+ "\n",
+ " Volume_50yr HydraulicRadius_EXT WetArea_EXT Volume_EXT \n",
+ "0 1.481644e+06 15.963237 17707.124134 1.950516e+07 \n",
+ "1 4.821029e+05 10.657803 4470.893497 4.590222e+06 \n",
+ "2 6.889459e+06 19.857827 4588.204166 3.543259e+06 \n",
+ "3 2.677685e+06 14.024038 13877.278759 1.673980e+07 \n",
+ "4 1.368706e+06 17.733277 11892.497653 1.355093e+07 \n",
+ ".. ... ... ... ... \n",
+ "120 1.303251e+06 14.269674 9572.389411 1.260387e+07 \n",
+ "121 9.284990e+05 15.066716 7603.500637 1.118124e+07 \n",
+ "122 4.223206e+06 11.393790 7335.934065 1.054989e+07 \n",
+ "123 2.561009e+06 10.747225 5511.734147 8.244491e+06 \n",
+ "124 5.217732e+05 14.760597 7100.041168 9.537194e+06 \n",
+ "\n",
+ "[125 rows x 54 columns]"
+ ]
+ },
+ "execution_count": 8,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# ── Merge n-zones summary with CONUS predictor table + own-hydroTable geometry ──────\n",
+ "# df_n_zones, df_geom already in memory. df_predictors loaded earlier, extended\n",
+ "# with EVI + STATSGO. HydraulicRadius/WetArea/Volume come from df_geom (each\n",
+ "# gauge's own hydroTable, interpolated at that zone's recurrence discharge) —\n",
+ "# NOT from df_predictors, whose versions of those columns were verified not to\n",
+ "# match this pipeline's geometry for the same reach (see Step 0b markdown).\n",
+ "#\n",
+ "# The external file's geometry is kept too (renamed _EXT, not dropped) so a\n",
+ "# later cell can compare \"own hydroTable geometry\" vs \"external CONUS-wide\n",
+ "# geometry\" head to head on the exact same gauge set -- the external version\n",
+ "# is what a CONUS-deployable model would actually have to use.\n",
+ "\n",
+ "BASE_FEATURE_COLS = [\n",
+ " \"TotDASqKM\", \"CAT_SILTAVE\", \"QE_cms\", \"D50_mm_\",\n",
+ " \"HYDRLCONDCAT\", \"WTDEPCAT\", \"PERMCAT\", \"StreamOrde\",\n",
+ "] + EXTRA_FEATURE_COLS\n",
+ "TARGET_COLS = [\"n_2yr\", \"n_5yr\", \"n_10yr\", \"n_25yr\", \"n_50yr\", \"h0_elev_m\"]\n",
+ "GEOM_BASE_NAMES = [\"HydraulicRadius\", \"WetArea\", \"Volume\"]\n",
+ "EXT_GEOM_COLS = [\"HydraulicRadius (m)\", \"WetArea (m2)\", \"Volume (m3)\"]\n",
+ "EXT_GEOM_RENAME = {c: f\"{g}_EXT\" for c, g in zip(EXT_GEOM_COLS, GEOM_BASE_NAMES)}\n",
+ "\n",
+ "def feature_cols_for(zone: str) -> list[str]:\n",
+ " # h0_elev_m isn't zone-specific; use the 2yr geometry as a near-bankfull reference\n",
+ " yr = zone[len(\"n_\"):-len(\"yr\")] if zone.startswith(\"n_\") and zone.endswith(\"yr\") else \"2\"\n",
+ " return BASE_FEATURE_COLS + [f\"{g}_{yr}yr\" for g in GEOM_BASE_NAMES]\n",
+ "\n",
+ "EXT_FEATURE_COLS = BASE_FEATURE_COLS + [f\"{g}_EXT\" for g in GEOM_BASE_NAMES]\n",
+ "\n",
+ "df_predictors_join = df_predictors.drop(columns=[\"Unnamed: 0\"], errors=\"ignore\")\n",
+ "df_predictors_join = df_predictors_join.rename(columns=EXT_GEOM_RENAME)\n",
+ "\n",
+ "df_ml = (\n",
+ " df_n_zones\n",
+ " .merge(df_predictors_join, left_on=\"feature_id\", right_on=\"COMID\", how=\"inner\")\n",
+ " .merge(df_geom, on=[\"HUC8\", \"location_id\", \"HydroID\"], how=\"left\")\n",
+ ")\n",
+ "\n",
+ "print(f\"Merged dataset: {len(df_ml)} rows | {df_ml['location_id'].nunique()} unique gauges\")\n",
+ "print(f\"{len(BASE_FEATURE_COLS)} base features (11 orig[-3 geom] + {len(EXTRA_FEATURE_COLS)} EVI/STATSGO) \"\n",
+ " f\"+ 3 zone-specific geometry features per target (or 3 static _EXT features for the comparison cell)\")\n",
+ "print(f\"\\nAvailable targets (non-null counts):\")\n",
+ "print(df_ml[TARGET_COLS].notna().sum().to_string())\n",
+ "geom_cols_all = [f\"{g}_{yr}yr\" for yr in RECURRENCE_YEARS for g in GEOM_BASE_NAMES]\n",
+ "print(f\"\\nZone-geometry coverage (non-null counts):\")\n",
+ "print(df_ml[geom_cols_all].notna().sum().to_string())\n",
+ "df_ml[[\"HUC8\", \"location_id\", \"feature_id\", \"HydroID\"] + TARGET_COLS + BASE_FEATURE_COLS + geom_cols_all + EXT_FEATURE_COLS[-3:]]"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "id": "1482c656",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:33.477628Z",
+ "iopub.status.busy": "2026-07-10T12:09:33.477628Z",
+ "iopub.status.idle": "2026-07-10T12:09:38.779298Z",
+ "shell.execute_reply": "2026-07-10T12:09:38.779231Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "n_2yr: 83 training samples after dropping NaN (features: ['HydraulicRadius_2yr', 'WetArea_2yr', 'Volume_2yr'])\n",
+ "n_5yr: 82 training samples after dropping NaN (features: ['HydraulicRadius_5yr', 'WetArea_5yr', 'Volume_5yr'])\n",
+ "n_10yr: 82 training samples after dropping NaN (features: ['HydraulicRadius_10yr', 'WetArea_10yr', 'Volume_10yr'])\n",
+ "n_25yr: 73 training samples after dropping NaN (features: ['HydraulicRadius_25yr', 'WetArea_25yr', 'Volume_25yr'])\n",
+ "n_50yr: 64 training samples after dropping NaN (features: ['HydraulicRadius_50yr', 'WetArea_50yr', 'Volume_50yr'])\n",
+ "h0_elev_m: 96 training samples after dropping NaN (features: ['HydraulicRadius_2yr', 'WetArea_2yr', 'Volume_2yr'])\n",
+ "\n",
+ "Zone Mode n RMSE R²\n",
+ "-----------------------------------------------\n",
+ "n_2yr 5-fold CV 83 0.0496 0.236\n",
+ "n_5yr 5-fold CV 82 0.0600 0.140\n",
+ "n_10yr 5-fold CV 82 0.0596 0.227\n",
+ "n_25yr 5-fold CV 73 0.0540 0.007\n",
+ "n_50yr 5-fold CV 64 0.0605 0.039\n",
+ "h0_elev_m 5-fold CV 96 43.0438 0.789\n"
+ ]
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAACoIAAAHvCAYAAAB6sV9JAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdeVxP2f8H8Nenff+QVlshspe9hMpS9l12ImbM2DIYzDD2nbEOZqgwEzIaxjaWjL0sg0yWsaRsaQxRRAud3x/9ut9un0/1iVC8no/H5zHTuefec87t47479557jkIIIUBERERERERERERERERERERERERERMWO1oeuABERERERERERERERERERERERERERvRkOBCUiIiIiIiIiIiIiIiIiIiIiIiIiKqY4EJSIiIiIiIiIiIiIiIiIiIiIiIiIqJjiQFAiIiIiIiIiIiIiIiIiIiIiIiIiomKKA0GJiIiIiIiIiIiIiIiIiIiIiIiIiIopDgQlIiIiIiIiIiIiIiIiIiIiIiIiIiqmOBCUiIiIiIiIiIiIiIiIiIiIiIiIiKiY4kBQIiIiIiIiIiIiIiIiIiIiIiIiIqJiigNBiYiIiIiIiIiIiIiIiIiIiIiIiIiKKQ4EJSIiIiIiIqJP1oULF6CnpweFQgETExNER0fLtu/btw8KhQIKhQKWlpb4999/Zdv//fdfTJ8+Ha6urihVqhT09PRgbW2N2rVrY8iQIdi+fbssv729vXS8rI++vj7Kly+PHj164PTp0++8zQX19OlTTJs2DdOmTcP69es13s/X11elrdk/zs7O76zO2WXVfenSpe+lvLcVGxsrO08fm/Xr10u/k6dPn37o6hQ7Of9dDR48WCVPSEiILI+Njc0HqGn+1q9fL9Vx2rRp763crOsw5S3ntSivT2xs7IeuLhERERERERHRJ0/nQ1eAiIiIiIiIiOhDqVOnDr777jtMmTIFycnJGDBgAI4fPw4tLS0kJCTIBln9+OOPsLa2ln7euXMnBg4cqDKY7eHDh3j48CGioqKwZcsWPH/+PM86pKWl4e7du7h79y5+//13nDlz5r0NktTE06dPMX36dACAu7s7fH19P2yFCiir7nZ2dvD39/+wlSGsX78eR48eBZA5qLFEiRIftkLF3ObNm7Fw4UKUKlVKSluxYsUHrBF9anR1dWFsbPyhq0FERERERERE9MnjjKBERERERERE9EmbNGkSXFxcAADh4eFYsGABAODLL7/EgwcPAAADBw5E165dpX1OnTqFHj16SINAu3btirNnzyIlJQXJycmIjIzE4sWLUbNmzVzLPXz4MIQQuHfvHmrXrg0ASE9Px6ZNm95FMz+oqVOnQggh+0RGRn7oahWa9PR0vHr16kNXo0h7+fLlh67CRyklJQVr166Vfo6MjMTJkyc/YI005+vrK10P3ueMoPQ/eV277O3tVa7bWdduAwMDKd+SJUtgaWn5vqpMRERERERERES54EBQIiIiIiIiIvqkaWtrY+PGjTAyMgKQOWhx8uTJCAkJAQCUL18ey5cvl+0zfvx4pKWlAQA6d+6M0NBQ1K9fH/r6+jAyMoKTkxO++uornDp1Kt/yy5Qpg9atW0s/v3jxQrb92bNnmDJlCmrWrAkjIyMYGhqiRo0amDx5MpKSklSOd/jwYXTs2BFWVlbQ1dWFpaUl2rdvjz///FOWLz09Hd988w2qVasGQ0NDGBgYoEyZMmjRooU0o6Cvry8qVKgg7XP06FFpKWAPD49821YQv//+O7y9vVGqVCno6uqiTJkyGDBgAG7cuCHLd+zYMXTq1AmVKlWCUqmEjo4OLCws0KpVK+zYsUPKN23aNNnyz7dv35bqbm9vL8ujUChky94fOXJESs8+A2r2Zbl37NiBYcOGwdraGvr6+rh37x4A4Pnz55g+fTpq164NY2NjGBoaolatWpg3b570nXkT2Zdp9vDwwK5du+Dk5AQDAwM4OTlhz549yMjIwKJFi2Bvbw9TU1M0bdoU586dkx3Hw8NDOs7p06cxYMAAlCpVCkZGRmjZsiX+/vtvlbI1/U5lX+p76tSpWLBgARwcHKCjoyMtV541GygAVKhQQWVpaX9/fzRs2FA6r0ZGRnB0dIS/vz8ePXokKy9riW+FQoHr16+jS5cuUCqVsLS0RM+ePfHw4UOVtmzZsgWtWrWChYUF9PT0YGNjA29vb1y6dEnKk56ejqVLl6Jhw4YwNTWFvr4+HB0dMXHiRLX/5j6UrH+bq1evxuvXrwFAulZl/3eb07s6xzm/o/v374erqysMDQ1hb2+Pb775Bunp6VL+3JaGz/4djYiIwMCBA1GqVCmUKFECbdq0QXR0tKyOqampGD9+PGxtbWFoaIgmTZrgxIkTsuPkt3T57t274e7ujpIlS0JHRwelSpWCs7Mz/Pz88OTJkzz3zfm9X7ZsGRwdHaVrdXBwcJ77qzvXN2/eROfOnWFmZgZTU1N07dpVbRs0vW5qcu3SRGJiIrp164aUlBQAQL9+/TB8+HBZnvj4ePj7+6Ny5cowMDCAiYkJ6tati4ULF6pcA7Nfk8+ePYtWrVrB2NgYZcqUwbBhw1Rm1C4u/zaJiIiIiIiIiD4IQUREREREREREYuXKlQKA7KNQKMThw4dl+f777z+hUCikPKdOndK4DDs7O2m/rOPev39fODs7S+X9+eefsrIcHR1V6pX1cXR0FI8ePZLyL1++XFa3nG1ZsWKFlNff3z/X47q5uQkhhBg4cGCuedzd3fNsa/Z9p06dmmfeCRMm5FqOiYmJOHv2rJR3yZIlueYFIDZt2iSEEGLq1Km55rGzs1PJExQUJJVx+PBhKX3gwIFq22RhYSE7ZkxMjHj8+LGoXr16ruU2a9ZMpKam5nkuYmJiZPuoSzc3NxdaWlqyfDo6OqJr164qZVpYWIjExETpOO7u7tI2S0tLlfxmZmbi+vXrUv6CfKeCgoJyPT/Zt6n7xMTECCGEUCqVueapUaOGSEtLk8rL/u+pZMmSKvm9vLxk57Z///65Hnv79u1CCCFSUlJk5yjnp1q1aiIhISHP3+G7lP07OHPmTGFgYCAAiNDQUPHo0SPp54ULF0r5rK2tZcd4V+c4+3fUzMxM5TsKQMyZM0fKn/07kf0akf38qyuzWrVq4tWrV1L+zp07q+TR09MTVlZWKt8vdf766y+ho6OT6zm5ceNGnr+T7O1QV18A4uTJk/n9amXnWt2/zbJly8qu9wW5buZ37dJERkaG6NSpk7RfrVq1RHJysizPzZs3hbW1da71atKkiXj58qWUPyvd0NBQ6Ovrq+T/7LPPpLxF/d8mEREREREREdGHxhlBiYiIiIiIiIiQuRR8ixYtZGmjRo1SmfkyJiYGQgjp56xl3QFg8uTJ0gxnWZ81a9aoLc/T0xMKhQJlypSRlkmfOXMmPD09pTxTp07FtWvXAABeXl64d+8e7t+/j5YtWwIArl27hu+++w4AcO/ePYwbNw5CCOjo6GDbtm149uwZtm3bBm1tbQghMHbsWNy/fx8AcOjQIQCZMwfeu3cPKSkpiI2NxbZt29CtWzcAmTPdxcTESPVxd3eXlgc+cuSIRucVAKZPn65yXrJmAPzrr78wf/58AEDr1q0RGxuL1NRUHDp0CHp6enj+/Dm++OIL6VgeHh44dOgQ4uPjkZqaiuTkZOzatUvavmjRIgCZs31m/z3Z2dlJdc9vdkBNvHr1Cjt37sTz58/xzz//wMrKClOnTsWVK1cAACtXrkRSUhKePn2KUaNGAciczTT7Mt5vKiEhAbNnz0ZSUhJGjhwp1ee3337DsmXLkJiYiI4dOwIAHj16hL1796o9ToUKFXDr1i38+++/6NSpEwAgKSnpjb9T2T169AgLFy5EQkICHjx4gFatWkEIAXd3dylP1r8lIYQ0S+vq1avxzz//4OnTp0hPT8e9e/ekGXMvX76Mffv2qW2Lk5MT7t69K/0uAODAgQOIj48HAPz222/4+eefAQDGxsb45Zdf8PTpUzx48AAbNmxAmTJlAGT+3rJmLZ00aRIeP36M5ORk6Tt69epVzJkzJ9/f0ftgYWGBXr16AQBWrFiBtWvXIiUlBWXLlkXnzp1z3e9dnePskpKSMGbMGCQkJMhm6t2wYUOB2limTBn8888/uHfvHqpVqwYg83dw9uxZAJmz1WYdv0SJEjh8+DCePn2KSZMmqZ0RVp2jR49Ky6OHhIQgLS0NDx8+RHh4OL777juYmJhoXN+kpCRs3rwZiYmJ+Prrr6X0jRs3anwMAGjUqBHi4+MRGxsLFxcXAJn/HrOubwW9bman7tqliQULFuD3338HACiVSvz222/STNpZRo0ahX///RcAMGDAADx69AjXr1+Hk5MTAODEiRPSjNPZvXz5El26dMF///2HiIgI6OvrA8g8b1nX8eL0b5OIiIiIiIiI6EPgQFAiIiIiIiIiImQuyX779m1Z2tWrV1XyZR9cCGQOYCkskydPRkBAgPRz1qAbAFi4cCHKlCmD0qVLY+HChVL6zp07AQD79u2Tlt3t0KEDunXrBhMTE3Tr1g3t27cHAKSlpUmDvCpVqgQAuH//PqZPn46ffvoJ165dQ4sWLTBmzJhCa1N+sg8S27dvH+zt7aGvr48WLVpI7fnrr7+kJavLli2LXbt2wcPDAyVKlICxsTE6dOggHSNrIOa79tVXX6FDhw4wNjaGo6MjjIyMsH37dmn7iBEjYGZmhhIlSkjLdWe18W3Z2tri66+/hqmpKdq0aSOllylTBiNHjoSZmRnatm0rpec28HXmzJmoUKECrKyssGDBAin9wIEDUl0L8p3Krnnz5hg3bhxKliwJGxsbaaBlfgwNDTFixAg4ODjAwMAAZcuWlR0/t9/vsmXLULZsWTg6OqJp06Yqbc/+uxk/fjz69u0LpVIJGxsbDBgwAA0aNFDJN3fuXJQqVQrGxsaYMGGClF4Yv8PCkjXI+MiRI9J14YsvvoCOjk6u+7yrc5ydpaUl5s2bh5IlS6JTp04oVapUrnnzMnv2bDg6OqJMmTJqv9NZ31UAGDRoEDw8PKBUKvHdd9+hdOnSGpWRdS0EgB9++AHz58/HkSNHYGFhgenTp8PGxkbj+nbs2BG9evWCmZkZ+vfvr1JfTS1evBjW1taws7PD9OnTpfSs9hb0upmdumtXfo4cOYJvv/0WQOZy7hs3boSDg4Msz8uXL6X6KRQKLFu2DKVKlULlypWlgf/A/2JWdlpaWli1ahUsLCzg4uKCmjVrAgBSUlKkgaXF7d8mEREREREREdH7xoGgREREREREREQAxo0bh5s3bwLIHMQCZA66WbVqlSxfhQoVpO2AfLDorFmzIITAwIED8y3v8OHDEELg2bNnmDt3rpT+9ddfIyMjAwCkATBA5oyWWbJmT8yeJ7e8ueVfunQpmjRpgrS0NKxduxajRo2Ct7c3rKysMHbs2HzrXxBTp06VZn7M+mQNDMpe77w8fvwYGRkZaNGiBZYuXYp//vlH7SDclJSUN6pj9gG+WbMD5qVevXoqaZq0Rd3ArIKqWLEitLQyb+sZGhpK6fb29tJ3M2tGPSD3c5L9e5L9/xMSEvD69esCf6eyU3d+8rNt2zZ06dIFYWFhePToEV6/fq2SJ7eB11mzRQKZM35myWp79lkra9WqlWsdCuN36OvrqzIDrqafgsy0CwB16tSBm5sbgMzfm76+PoYOHZpr/nd5jrOrXLmybDBqVv7U1NR8WlSwMrP/LrJ/R7W0tFCuXDmNyujUqRPGjh0LIyMjHDt2DFOmTIGPjw+qVKmCevXqIS4urtDqq6nc/m1mzXJakOtmTgX9t/ngwQP06tVL+q5MnDhRmnE4u4SEBOnaqVQqUaJECWlbftcLGxsblCxZUvpZ3bl7X9dXIiIiIiIiIqLiigNBiYiIiIiIiOiTt3//fmkJdysrK+zZswe6uroAMmcPvHHjhpTX0tISjRs3ln5+26VoTUxMMGLECOnnhIQE/PfffwAAa2trKT37bKXZZ5fLypNb3tzy29nZ4fjx4/j3339x6NAhrF27Fg0bNkR6ejq+//57nDp1CgBkg17fhez1njt3rsqAUSEEMjIy4OjoiKioKPz999/SflFRUXj16hWSkpLeqGwDAwPp/1+8eCH9f9aA4Lyom0Uvqy0KhQJxcXFq2xIeHv5Gdc0ut9ke85oFUp3s35Ps/29ubg5tbe0Cf6eyy22Wwby+T8HBwdL/jx8/HklJSRBC4Kuvvsq9Ef8v699rbmVkn9Xx0qVLuR4ne1siIiLU/g4LMjDwfciaFRQAevXqBUtLy1zzvstznFteTfK/aZnZ23r37l3p/zMyMnDnzh2Ny1m0aBESEhJw9uxZbN26FcOHDwcAnD9/HjNmzCi0+moqt3+bWcu4F+S6mZMmM4BmefXqFXr27CkNwmzRogVmzZqlNq+5ubl0DUpMTERiYqK0Lb/rhSbfl+L4b5OIiIiIiIiI6H3iQFAiIiIiIiIi+qQ9efIEgwcPln7+6aef0KZNG0yZMgVA5gDBAQMGyGbOmz9/vjTgZe/evRg4cCAuX76M9PR0PHr0SOPZ2gDg+fPnWLlypfSzgYGBNJNa9lnXJkyYgLi4ODx48EC2FG5WntatW0NPTw8AsHv3buzYsQPJycnYvn079uzZAwDQ09ODt7c3AGDBggUIDg5GUlISXFxc4OPjAycnJ+m4WYOospZ0BjIHJD158kTjtmmic+fO0v8vWLAAu3fvRnJyMp4/f45Tp05h9OjR6Nq1KwD5QEdtbW2YmJggMTExz0FsWfV/9OgR7t+/L9uWfZa6P/74A69fv0ZcXBy+//77N2pLly5dAECaFfbq1atIT09HfHw8tm3bhtatW+Pnn39+o2O/C1OnTkVsbCz+++8/fP3111K6l5cXgIJ/pzSR/ft08eJF2Uys2X+/RkZG0NXVxfHjx7Fhw4Y3a2A2Wd8hAFi4cCG2bNmCpKQkPHz4EJs2bcLZs2cB/O93CADDhw/HuXPnkJqaisePH2Pv3r3o0aOHbAZfddavX692kJomHw8PjzdqW69evdCpUyeMGTMmz7zv8hx/CFnfVSDzvIeHhyMpKQnTp0/HgwcPNDrG0aNHMWfOHFy+fBn29vbo3Lmz7LpUkAGlheXrr7/Gv//+izt37mDq1KlSelZ7C3LdfBsTJkzA8ePHAQDlypXDli1bpNmIczI0NESrVq0AZF4Dx4wZg8ePHyM6Olo2mFbdbKKaKIx/m0REREREREREHzMOBCUiIiIiIiKiT9oXX3whzSLm6+uLTp06AQC++eYbuLi4AABOnTqFefPmSfu4ublh8+bNMDExAQBs3LgRNWvWhJ6eHiwtLbFv3758y/X09IRCoYCpqSkmTZokpY8aNUpa1nv69OmoXLkyAGDfvn0oU6YMSpcujQMHDgDIXH55+vTpAICyZcti/vz5AID09HR06dIFJiYm6Nq1q7Rc74IFC1C2bFkAmcve9+vXD5UrV4axsTGUSiXWrl0LADA1NUXTpk0BZM5YmrWUdmxsLMzNzaFQKKSl3d9W/fr1pfY/efIEHTp0gImJCUxNTeHq6orly5dLg0+rVq2KmjVrAgDi4uJQoUIFlCpVCseOHcv1+FmztyYnJ6Ns2bJQKBTw9fUFALRt2xYWFhYAgD179kCpVKJcuXJvPKvc9OnTUaNGDQDAwYMHUb16dejp6cHW1hY9evTA/v37kZGR8UbHfhfu3r2LChUqwMrKCr///jsAwMzMTBq0VdDvlCayz6bbuXNnaGlpSQNyu3fvLm2bPn06DA0N0axZM9ng0TfVpUsXDBgwAEDm4OvevXtDqVTC2toaffv2lQYJjxgxQhqMef78edSvXx8GBgawsLBAu3btsG3bNqSlpb11fQqTjo4ONm/ejB07dsgGc6vzLs/xh+Dh4SENinz8+DHc3NygVCoxd+5c2Wyhec3OeffuXXz77beoV68eLC0toaenJw1oBDKvE+/bX3/9BRsbG9jZ2UmzM5ctWxbjxo0DULDr5puKjIyUDYq/e/cuLC0toVAoVD7r168HACxbtkw670FBQbCwsICDgwMuXLgAAHB1dcXIkSPfqD7F8d8mEREREREREdH7xIGgRERERERERPTJCgkJQUhICACgfPnyWLZsmbRNW1sbP//8M4yNjQFkDprKGswCZA6ounr1KiZNmoS6devCzMwMurq6KFOmDOrXr48vvvgCf/zxh2y2UXW0tLRQsmRJNGvWDOvWrZMNOLW0tMTZs2fxzTffoHr16jAwMIC+vj6qVauGSZMm4ezZs9JARgDw9/fHwYMH0a5dO1hYWEBbWxulSpVC27ZtceDAAYwePVrK6+vri44dO8LOzg7GxsbQ1taGra0tunXrhuPHj8PW1lbK+/PPP8PDwwNKpfINz3Te5syZg927d6Nt27awtLSEjo4OLC0tUbduXYwZM0aa5U1bWxu7du1C586dUbJkSZiZmaFbt274888/cz32ihUr0KFDB7UD3czMzLBv3z40adIEJiYmMDY2xtChQ994dkRzc3OcPn0aM2fORJ06dWBsbAx9fX3Y2dmhVatWWLx4Mdq0afNGx34XduzYgUGDBsHc3ByGhoZo3rw5jh07Jg0+Bgr2ndLEl19+ieHDh6NMmTIqMwv27NkTa9asQZUqVaCvrw9HR0esXbsWvXv3LpT2btiwAZs2bUKLFi2kZaytrKzQqlUrODg4AAD09fVx8OBBrFixAq6urjAzM4Oenh7Kli2LZs2aYdasWRg4cGCh1OdDeNfn+EPYsmULxo4dC2tra+jr68PFxQUHDx6UBiQqFIo8B7rWq1cPQ4YMQa1atWBubg5tbW2YmprCxcUFP/30E0aMGPG+miI5efIkunbtClNTU5iYmKBz5844fvy4rB2aXjff1NOnTwu8T+XKlREZGYkRI0agUqVK0NPTg5GREZydnTF37lwcPnwYBgYGb1Sfj/3fJhERERERERHR21KI7OsvERERERERERER0UfLw8MDR48eBQDExMRIs3ESFVeRkZEwMjJClSpVAACvX79GQEAAPv/8cwCZMzifOHHiQ1ZRI/b29rh9+zaAzKXViYiIiIiIiIiICkLnQ1eAiIiIiIiIiIiIiOhN7NixA9OnT4eJiQlKliyJR48e4eXLlwCAkiVL4ocffvjANSQiIiIiIiIiInr3uDQ8ERERERERERERERVLjRs3RsuWLWFiYoL4+HgoFApUr14d/v7+iIqKgpOT04euIhERERERERER0TvHpeGJiIiIiIiIiIiIiIiIiIiIiIiIiIopzghKRERERERERERERERERERERERERFRMcSAoEREREREREREREREREREREREREVExxYGgRERERERERERERERERERERERERETFFAeCEhEREREREREREREREREREREREREVUxwISkRERERERERERERERERERERERERUTHEgKBERERERERERERERERERERERERFRMcWBoERERERERERERERERERERERERERExRQHghIRERERERERERERERERERERERERFVMcCEpEREREREREREREREREREREREREVExxICgRERERERERERERERERERERERERUTHFgaBERERERERERERERERERERERERERMUUB4ISERERERERERERERERERERERERERVTHAhKRERERERERERERERERERERERERFRMcSAoEREREREREREREREREREREREREVExxYGgRERERERERERERERERERERERERETFFAeCEhEREREREREREREREREREREREREVUxwISkRERERERERERERERERERERERERUTHEgKBERERERERERERERERERERERERFRMcWBoERERERERERERERERERERERERERExRQHghIREREREREREREREREREREREdEnx8PDA/7+/h+sfF9fX3Tu3PmDlU8fDw4EJaIiISEhASNHjoSjoyOMjIxQvnx5jBo1ComJiR+6akRERO+Nh4cHFAqF7NOrV68PXS0iIqJC99NPP8HDwwNmZmZQKBR4+vSpSp4nT56gf//+UCqVUCqV6N+/v9p8RERExY2m90Lt7e1V+ogTJ078QLUmIiIqPJrcB2WfkIiIiorU1FSMHDkSFhYWMDY2RseOHXHv3r0PXS0iFRwISkRFQlxcHOLi4rBo0SJERUVh/fr12LdvH/z8/N7quGlpaYVUQyIiovdj6NChePDggfT58ccf3+p4jIVERFQUvXjxAq1bt8Y333yTa54+ffogMjIS+/btw759+xAZGYn+/fu/Vbnp6elvtT8REVFhKMi90BkzZsj6iJMnT36rshkLiYioqMjvPij7hEREVFT4+/tj+/bt2LJlC06cOIHnz5+jffv2eP369YeuGpEMB4ISUaHy8PDAqFGj8PXXX8Pc3Bw2NjaYNm1avvvVrFkToaGh6NChAypVqoTmzZtj9uzZ2LVrF169egUAaN68OUaMGCHb7/Hjx9DX18eff/4JIPMt+VmzZsHX1xdKpRJDhw4t9DYSERHl5U1jYRYjIyPY2NhIH6VSKW1jLCQioqLkbWKev78/Jk6cCBcXF7Xbr169in379mHdunVwdXWFq6sr1q5di927d+PatWsQQsDBwQGLFi2S7Xfp0iVoaWkhOjoaAKBQKLBmzRp06tQJxsbGmDVr1lu1mYiIKLt3eS80i6mpqayPaGJiAgCMhURE9MG9y/ug7BMSEdH7lpGRoTamJSYmIiAgAIsXL0bLli1Rp04d/PLLL4iKikJYWJhGx75/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5EBQ+uCyprc2MzNjYCOiPHE6fPpYMRYSkaYYC+ljxDhIRJpiHKSPEeMgEWmKcZA+VoyFRKQpxkL6GDEOEpGmNImDeS8cT0RERERERERERERERERERERERERERRYHghIRERERERERERERERERERERERERFVMcCEpEREREREREREREREREREREREREVExxICgRERERERERERERERERERERERERUTHFgaBERERERERERERERERERERERERERMUUB4ISERERERERERERERERERERERERERVTHAhKRERERERERERERERERERERERERFRMcSAoEREREREREREREREREREREREREVExxYGgRERERERERERERERERERERERERETFFAeCEhEREREREREREREREREREREREREVUxwISkRERERERERERERERERERERERERUTHEgKBERERERERERERERERERERERERFRMcWBoERERPRO2dvbY+nSpR+6GkREREREREREREREREREREQfJZ0PXYHCFB4ejqZNm6JVq1bYt2+fbFtaWhqWLl2K4OBg3LhxA0ZGRnB0dMSQIUPQr18/6OrqAgDi4+Mxe/Zs7NmzB/fv34eVlRWcnZ3h7++PFi1a5FsHe3t7+Pv7w9/fHwAghMC4cePw008/4ffff0fz5s3h4eGBo0ePquybnp4OHZ3MX8lnn32GgIAABAcHo1evXip5b968idmzZ+PgwYP477//ULp0abi4uGDs2LG4dOkSBg0alGc9Dx8+DA8Pj1y3T5s2DTt27EBkZKQs/enTpyhZsqS0f2xsLCpUqCBtL1GiBGrVqoWZM2fC3d09zzrk1H31TegamBRoHyIqnvaMrvKhq0Aa6tChA16+fImwsDCVbREREWjcuDHOnTuHunXrfoDaFS6FQqGStnr1agwbNuy91YGxkOjTwVj47hWV/uHt27cREREBFxcXKd3f3x+RkZE4cuSIlJaQkIAZM2Zgx44diIuLQ6lSpdC6dWtMnz4d5cuXl/IdO3YMCxcuxLlz5/DgwQNs374dnTt3lpUrhMD06dPx008/4cmTJ2jUqBF++OEH1KhRQ6WOc+bMwZQpUzB79mxMnDgRABAaGgofHx/ExMTIys5StWpVeHl5Yfny5bn2bz///HOsWbMm33OUHeMg0aeDcbDw+fr6YsOGDSrpnp6e+Pvvv+Hv74/JkyerbJ87dy4WL16MuLg4bNq0Cf7+/nj69KlGZb58+RLz5s3Dli1bEBsbC1NTU3h4eGD69OmymDNt2jRMnz5dJTZERkaiTp06iImJgb29vcp9RhMTE5QvXx4eHh7w9/dH5cqVNarXb7/9htWrVyMyMhKpqamoUaMGpk2bBm9vb1m+0NBQTJkyBdHR0ahUqRJmz56NLl26SNs1ibm//fYbfvzxR5w7dw6PHz/GhQsX4OzsrFE9c2IcJPq0MBa+O0WpLwgABgYGsLOzg5+fH8aNG6dyD3LDhg344YcfcPnyZWhpaaFOnTr4+uuv0b59e1k+IQTWrl2LgIAAXL58GTo6OnBwcEC/fv3w2WefwcjISO2zvePHj6NDhw7o378/li9fjg0bNkjPELW0tGBmZoYqVaqgXbt2GD16NJRKpbRvbn9feHt7S+c2e1sNDQ1RsWJFjBw5Ep9//nm+5yknxkKiTwfj4LvDOMg4SERF37uMgx/VjKCBgYEYOXIkTpw4gTt37kjpaWlp8Pb2xrx58/DZZ58hPDwcZ86cwfDhw7FixQpcvnwZABAbG4t69erhzz//xIIFCxAVFYV9+/bB09MTw4cPL3B9Xr9+DT8/P2zcuBF//vknmjdvLm0bOnQoHjx4IPtkDQJ98eIFQkJCMH78eAQEBKgc96+//kK9evVw/fp1/Pjjj7hy5Qq2b9+OqlWrYuzYsejZs6fsuK6urirlNW7cuMDtyUtYWBgePHiAo0ePwszMDG3btkVMTEyhlkFERO+fn58f/vzzT6kTk11gYCCcnZ0/ikGgWYKCgmTxcuDAgW91vPT09EKqGRERFVRR6R8aGBhgwoQJeeZJSEiAi4sLwsLCsGrVKty8eRMhISGIjo5GgwYNcOvWLSlvcnIynJycsHLlylyPt2DBAnz//fdYuXIlzp49CxsbG7Rq1QrPnj1TyRsUFISvv/4agYGBUlrHjh1RqlQptTc6T548iWvXrsHPz09KU9e/XbBgQZ5tJiKiwte6dWuV63FoaCj69euH9evXQwihsk9QUBD69+8PPT29ApWVmpqKli1bIjAwEDNnzsT169exd+9evH79Go0aNcKpU6dk+Q0MDBAQEIDr16/ne+ys+4wXL17EnDlzcPXqVTg5OeHQoUMa1e3YsWNo1aoV9u7di3PnzsHT0xMdOnTAhQsXpDwRERHo2bMn+vfvj4sXL6J///7w8fHB6dOnpTyaxNzk5GS4ublh3rx5GtWNiIjevaLSF5wxYwYePHiAq1evYty4cfjmm2/w008/yfKMGzcOn3/+OXx8fHDx4kWcOXMGTZs2RadOnVTiT//+/eHv749OnTrh8OHDiIyMxJQpU/D777/jwIEDauuwZ88eeHt7Y/To0VixYoU0+MbMzAwPHjzAvXv3EB4ejs8++wwbN26Es7Mz4uLiZMdQ9/fF5s2b1bb177//RufOnTFs2DCEhIRofK6IiKjwMA7+D+MgEX2KPpoZQZOTk7F161acPXsW8fHxWL9+Pb777jsAwNKlS3Hs2DH89ddfqFOnjrRPxYoV0aNHD6SlpQEAvvzySygUCpw5cwbGxsZSvho1amDw4MEFqk9qaip69+6Ns2fP4tixY6hWrZpsu5GREWxsbNTu++uvv6J69eqYNGkSbG1tERsbC3t7ewCZbzr4+vqicuXKOH78OLS0/jeW19nZGaNHj4ahoSEMDQ2ldD09vTzLKwylSpWCjY0NbGxs8OOPP6Js2bI4cODAG73pQERERUf79u1hZWWF9evXY+rUqVJ61ksLc+bMQWhoKL777jvcvHkTtra2GDlyJMaOHav2eFkzvGSfJSXnbNNHjhyBp6cn9u3bh4kTJ+Kff/6Bq6srtmzZgnPnzuGrr77C/fv30a5dOwQEBMDIyAhAZoxcuHAh1qxZgwcPHqBKlSqYMmUKunfvrnF7S5QooTZeJicnw9bWFoGBgbLj7dq1C7169UJ8fDweP36MChUqICQkBKtWrcKpU6ewevXqfGfpJiKiwleU+oeff/45Vq9ejb1796Jt27Zq83z77beIi4vDzZs3pThUvnx57N+/H5UrV8bw4cPxxx9/AADatGmDNm3a5FqeEAJLly7Ft99+i65duwLIfLPe2toamzZtkvXRjh49ipcvX2LGjBnYuHEjjh07hmbNmkFXVxf9+/fH+vXrMXnyZNmb+oGBgahXrx6cnJyktHfd3yQiIs3o6+urvR77+flh2bJlOHbsmGwFn+PHj+PGjRuywf2aWrp0KSIiInDhwgUpJtjZ2SE0NBSNGjWCn58fLl26JMUQR0dHWFlZYfLkydi6dWuex866zwhkxucOHTqgRYsW8PPzQ3R0NLS1tfOtW3Zz5szB77//jl27dkmxf+nSpWjVqhUmTZoEAJg0aRKOHj2KpUuXSg/18ou5QObDSCCzr0tERB9eUeoLmpqaSvFsyJAhWL16tey52alTp7B48WIsX74cI0eOlPabPXs2UlJS8NVXX6FTp04oV64ctm7diuDgYOzYsQOdOnWS8trb26Njx45ISkpSKX/Tpk0YNGgQFi5ciFGjRsm2KRQKqW62traoVq0aOnTogBo1auDrr7/GL7/8IuXN7e+L3No6a9YsbN26FTt27EDPnj01Pl9ERPT2GAf/h3GQiD5VH82MoCEhIXB0dISjoyP69euHoKAg6S334OBgtGzZUhbQsujq6sLY2BgJCQnYt28fhg8fLgtoWUqUKKFxXZ4/f4527drh8uXLOHnypMog0PwEBASgX79+UCqVaNu2LYKCgqRtkZGRuHz5MsaOHSsbBPom9XxXsgbkcBY0IqLiT0dHBwMGDFCZPebXX39FWloaXF1d4ePjg169eiEqKgrTpk3DlClTsH79+rcue9q0aVi5ciXCw8Nx9+5d+Pj4YOnSpdi0aRP27NmDgwcPYsWKFVL+yZMnIygoCKtXr8bly5cxZswY9OvXT+1ytbkZMWIELCws0KBBA6xZswYZGRkAAGNjY/Tq1UsWk4HM2XO6d+8OU1NTKW3ChAkYNWoUrl69qrL0IBERvR9FqX9ob2+PYcOGYdKkSVJcyS4jIwNbtmxB3759VW4qGhoa4ssvv8T+/fuRkJCgUXkxMTGIj4+Hl5eXlKavrw93d3eEh4fL8gYEBKB3797Q1dVF7969ZStS+Pn54datW7I4mnUz+U0GDBER0YdTq1YtNGjQQKU/ExgYiIYNG6JmzZoFPuamTZvQqlUr2YsBQObSemPGjMGVK1dw8eJF2bZ58+YhNDQUZ8+eLVBZWlpaGD16NG7fvo1z584VuK4ZGRl49uwZzM3NpbSIiAhZrAQyl/fLGSuJiKh4KUp9wSxCCBw5cgRXr16VltwFgM2bN8PExETthCpjx45Feno6QkNDpbo7OjrKBr9kUSgUsmVsAeCHH37AoEGDEBAQoDL4JTdWVlbo27cvdu7cidevXxekiSoMDAz4jJCI6ANgHMzEOEhEn7KPZiBo1uBJIHN65ufPn0vLBd24cQNVq1bNc/+bN29CCJFvPk3MnDkTkZGROH78OMqXL682z6pVq2BiYiJ9smZOu3HjBk6dOiW9HZAVoLMeGN64cQMACqWe70JycjImTZoEbW1t2QwD2aWmpiIpKUn2ISKiomvw4MGIjY3FkSNHpLTAwEB07doV33//PVq0aIEpU6agSpUq8PX1xYgRI7Bw4cK3LnfWrFlwc3NDnTp14Ofnh6NHj2L16tWoU6cOmjZtiu7du+Pw4cMAMuPP999/j8DAQHh7e6NixYrw9fVFv3798OOPP2pU3syZM/Hrr78iLCwMvXr1wtixYzFnzhxp+5AhQ7B//35pWYhHjx5h9+7dKm9A+vv7o2vXrqhQoQJKly6ttizGQiKid6so9Q+BzJcVYmJiEBwcrLLtv//+w9OnT3N9gbBatWoQQuDmzZsalRUfHw8AsLa2lqVbW1tL2wAgKSlJWi4YyOx7btu2TYpJ1atXR6NGjWSDhrZu3YrXr1+jd+/esmPn7N+amJioXVY+C+MgEdG7sXv3bpXr8cyZMwFk9uu2bduG58+fA8h8kf3XX39948H9169fzzN2ZeXJrm7duvDx8cHEiRMLXF5WTH6TmTcXL16M5ORk+Pj4SGnx8fH5xsp3hXGQiOjdKUp9wQkTJsDExAT6+vrw9PSEEEI2GOX69euoVKkS9PT0VPYtXbo0lEqlFEtv3LgBR0dHjcq9evUqRowYgdWrV0vnQlNVq1bFs2fP8PjxYyktr78vcnr16hXWr1+PqKgotGjRItdyGAuJiN4NxkHGQSKij2Ig6LVr13DmzBn06tULQObsZT179kRgYCCAzLcMsi9lp07WmxD55dOEl5cXkpOTZYNHcurbty8iIyOlT9YyRAEBAfD29oaFhQUAoG3btkhOTkZYWFih17MwNW7cGCYmJjA1NcWuXbuwfv161KpVS23euXPnQqlUSp9y5cq959oSEVFBVK1aFY0bN5bianR0NI4fP47Bgwfj6tWrcHNzk+V3c3PDjRs33vqNudq1a0v/b21tDSMjI1SsWFGW9vDhQwDAlStXkJKSglatWsk6Yxs3bkR0dLRG5U2ePBmurq5wdnbG2LFjMWPGDNmA1oYNG6JGjRrYuHEjAODnn39G+fLl0axZM9lx6tevn29ZjIVERO9OUesfAoClpSXGjRuH7777TlpmSVNvWpec+XO2e9OmTahYsaI0k5uzszMqVqyILVu2SHn8/Pywbds2PHv2DMD/XgTJ+fZ/zv5tZGQkunTpkmvdGAeJiN4NT09Plevx8OHDAQC9e/dGRkYGQkJCAGTOFCOEkOJlYcords2aNQvHjx/HgQMHCu2Yedm8eTOmTZuGkJAQWFlZybblFyvfFcZBIqJ3o6j1BcePH4/IyEgcPXoUnp6e+Pbbb9G4cWON989e34LEqLJly6Ju3bpYsGABHjx4UKA6q2t/Xn9fZMka7GNoaIjhw4dj/Pjxamd4y8JYSERU+BgHMzEOEtGn7qMYCBoQEIBXr16hTJky0NHRgY6ODlavXo3ffvsNT548QZUqVXD16tU8j1G5cmUoFIp882miRYsW2LlzJ3766SeMHDlSbR6lUgkHBwfpY2FhgdevX2Pjxo3Ys2eP1A4jIyMkJCRIS/RVqVIFAAqlnnkxMzNDYmKiSvrTp0+l+mcXEhKCixcv4r///sP9+/fzfLti0qRJSExMlD53794t1LoTEVHh8/PzQ2hoKJKSkhAUFAQ7Ozu0aNFCbecr+xLyOWlpaankyW15hOxLRCgUCtnPWWlZM2Zn/XfPnj2yztiVK1ewbdu2ArT0f1xcXJCUlIR///1XShsyZIg0M1pQUBAGDRqk0n51y2XkxFhIRPTuFLX+YZavvvoKL1++xKpVq2TplpaWKFGiBK5cuaJ2v3/++QcKhQKVKlXSqJys5eVzzmj28OFD2cxngYGBuHz5snSOdHR0cPnyZdny8L169YJCoUBISAhu3ryJEydOqJ05Lmf/1sHBAWZmZrnWkXGQiOjdMDY2VrkeZy2HrlQq0b17d1l/pnv37nler/NSpUqVPGMXkBlPc6pUqRKGDh2KiRMn5tl3zCkrJleoUEHjfUJCQuDn54etW7eiZcuWsm02Njb5xsp3hXGQiOjdKGp9QQsLCzg4OMDV1RWhoaFYsmSJNOkLkBlLo6Oj1b4sGBcXh6SkJCmWalL3LKampggLC4OpqSk8PDyk1Y00cfXqVZiZmaFUqVJSWl5/X2TJGuxz+/ZtPH/+HAsWLJDuA6vDWEhEVPgYBzMxDhLRp67YDwR99eoVNm7ciMWLF8sGfly8eBF2dnYIDg5Gnz59EBYWhgsXLqjdPzk5Gebm5vD29sYPP/yA5ORklXxZAyA11apVK+zevRuBgYEYPny4Rjc29+7di2fPnuHChQuytvz666/YsWMHHj9+DGdnZ1SvXh2LFy+WBr28TT1zU7VqVdy7d0/lhujZs2ehpaUFBwcHWXq5cuVQqVIlWVDMjb6+PszMzGQfIiIq2nx8fKCtrY1NmzZhw4YN0gDI6tWr48SJE7K84eHhqFKlCrS1tVWOY2lpCQCyt/AiIyPfun7Vq1eHvr4+7ty5o9Ihe9M36S5cuAADAwPZrGf9+vXDnTt3sHz5cly+fBkDBw58o2MzFhIRvRtFtX8IACYmJpgyZQpmz54tW+5HS0sLPj4+2LRpk0r/K2vgqLe3t8oNxtxUqFABNjY2OHjwoJSWlpaGo0ePSm/dR0VF4a+//sKRI0dk5+nYsWM4e/YsLl26BCDzxmmPHj0QFBSEwMBAVKxYER4eHgVue06Mg0REH4afnx9OnjyJ3bt34+TJk2+8LDyQ+bJAWFgYLl68KEvPyMjAkiVLUL16dWnW6Zy+++47XL9+XTYLdV4yMjKwfPlyVKhQAXXq1NFon82bN8PX1xebNm1Cu3btVLa7urrKYiUAHDhwoEAz1LwpxkEiosJXlPuCAFCyZEmMHDkS48aNk54X9urVC8+fP8ePP/6okn/RokXQ1dVFt27dAAB9+vTB9evX8fvvv6vkFUKoTOxSsmRJhIWFoWTJkvDw8MD9+/fzrePDhw+xadMmdO7cOc/BK+pkDfYpXbq0RjO2MRYSERUuxkHGQSKiLMV+IOju3bvx5MkT+Pn5oWbNmrJP9+7dERAQAH9/f7i5uaFFixb44YcfcPHiRdy6dQtbt25Fo0aNcOPGDQDAqlWr8Pr1azRs2BChoaG4ceMGrl69iuXLl8PV1bXAdWvevDn27NmDDRs2aDQYNCAgAO3atYOTk5OsHd26dYOlpSV++eUXKBQKBAUF4fr162jWrBn27t2LW7du4e+//8bs2bPRqVOnNzqPOXl5eaFatWro1asXTp48iZiYGPz+++8YN24chg0bBlNT00Iph4iIigcTExP07NkT33zzDeLi4uDr6wsAGDt2LA4dOoSZM2fi+vXr2LBhA1auXIlx48apPY6hoSFcXFwwb948XLlyBceOHcPkyZPfun6mpqYYN24cxowZgw0bNiA6OhoXLlzADz/8gA0bNuS7/65du7B27VpcunQJ0dHRWLduHb799lt89tln0NfXl/KVLFkSXbt2xfjx4+Hl5YWyZcu+dd2JiKjwFOX+IQB89tlnUCqV2Lx5syx99uzZsLGxQatWrfDHH3/g7t27OHbsGLy9vZGeno4ffvhByvv8+XPpZi4AxMTEIDIyEnfu3AGQOWO2v78/5syZg+3bt+PSpUvw9fWFkZER+vTpAyCz79mwYUM0a9ZMdo6aNGkCV1dX2aygfn5+CA8Px+rVqzF48GC1NzNfvHiB+Ph42efJkydvdI6IiOjNpaamqlyPHz16JG13d3eHg4MDBgwYAAcHBzRr1uyNyxozZgwaNmyIDh064Ndff8WdO3dw9uxZdOvWDVevXkVAQECuD8Csra3x1VdfYfny5Wq3P378GPHx8bh16xZ27tyJli1b4syZMwgICFD7wmFOmzdvxoABA7B48WK4uLhI5yL7w8HRo0fjwIEDmD9/Pv755x/Mnz8fYWFh8Pf3l/LkF3MBICEhQVqNAshcjjEyMlLl5Q4iInq3inpfEACGDx+Oa9euITQ0FEDmSwmjR4/G+PHjsXjxYkRHR+Off/7B5MmTsWzZMixevFh6wd3Hxwc9e/ZE7969MXfuXPz111+4ffs2du/ejZYtW+Lw4cMq5SmVShw4cAAWFhbw8PDAvXv3pG1CCMTHx+PBgwe4evUqAgMD0bhxYyiVSsybN092nPz+viAiog+PcZBxkIhIIoq59u3bi7Zt26rddu7cOQFAnDt3TqSkpIi5c+eKWrVqCQMDA2Fubi7c3NzE+vXrRXp6urRPXFycGD58uLCzsxN6enqiTJkyomPHjuLw4cMa1cfOzk4sWbJElnb06FFhYmIiPv/8c5GRkSHc3d3F6NGjZXni4+OFjo6O2Lp1q9rjjhw5UtSqVUv6+dq1a2LAgAGidOnSQk9PT9jZ2YnevXuL8+fPq+yrrjxNPHjwQAwaNEjY2dkJQ0NDUbVqVTFjxgyRkpIi5YmJiREAxIULFwp8/CyJiYkCgEhMTHzjYxDRx43XiaIhPDxcABBeXl6y9G3btonq1asLXV1dUb58ebFw4ULZ9pyx8cqVK8LFxUUYGhoKZ2dnceDAAQFAirWHDx8WAMSTJ0+kfYKCgoRSqZQdd+rUqcLJyUn6OSMjQyxbtkw4OjoKXV1dYWlpKby9vcXRo0fzbdsff/whnJ2dhYmJiTAyMhI1a9YUS5culf2NkOXQoUMCgErMfpuYyO84EeWH1wnNFIf+4aZNmwQA4e7uLkv/77//xMiRI0W5cuWEjo6OsLa2FgMHDhS3b9+W5cuKkzk/AwcOlPJkZGSIqVOnChsbG6Gvry+aNWsmoqKihBBCpKamilKlSokFCxaorfPixYuFhYWFSE1NldIcHR2FlpaWuHv3rkp+d3d3tfXx9vbW6BwJwe83EeWP14n8DRw4UO312NHRUZZvzpw5AoCYM2eOyjHU9bvykpycLCZPniwcHByErq6uMDc3F926dZNiTpacfTchhEhKShIWFhYCgIiJiRFC/K9PlfUxMjIS1apVE19++aW4ceOGxvXKLTZlj5VCCPHrr79K/ceqVauK0NBQ2XZNYm5QUJDaPFOnTtW4vvx+E1F+eJ3IX3HoCwohxNChQ0WNGjXE69evpbSAgABRv359YWhoKIyMjESTJk3Ezp07VfZ9/fq1WL16tWjQoIEwMjISZmZmol69emLZsmXixYsXQojcY66bm5uoVKmSuHPnjix2KRQKoVQqRcOGDcWMGTNUvmOa/H2RW1sLgt9xIsoPrxN5YxxkHCSij1tBrhMKITRYs5zoHUpKSoJSqURiYiKnvSYitXidoKIkODgYo0ePRlxcHPT09ArlmPyOE1F+eJ2gjxm/30SUH14n6GPG7zcR5YfXCfrY8TtORPnhdYI+Zvx+E1F+CnKd0HlPdSLKV/fVN6FrYPKhq0FF1J7RVT50FYjoE/fixQvExMRg7ty5+PzzzwttEGh2jIVEb49/M9D7ZG9vD39/f9kysvTmGAeJ8sYYV3zFxsaiQoUKuHDhApydnd9rWUeOHIGnpyeePHmCEiVKvNOy8+Pr64unT59ix44dAAAPDw84Oztj6dKlH7ReRQXjIBVXjE+UH8bBTIyD+WMsJCoYxmCijwvjIH3MGLPeH60PXYH3zdfXFwqFQuXTvHlzWFhYYNasWWr3mzt3LkxNTWFiYgIDAwMoFAqYmJhInxo1aqjdb/369Wo7l+Hh4dDW1kbr1q3V7hcaGopGjRpBqVTC1NQUNWrUwNixYzVq42+//YZWrVrB0tISZmZmcHV1xf79+2V5atSoAUNDQ2hpaUGhUEBLSwuGhoYwMTFBcHAwAODYsWPo0KEDSpcuDYVCIXVOs6Snp2PChAmoVasWjI2NUbp0aQwYMABxcXEa1ZOIiIquvOJUWloaFixYACcnJxgZGcHCwgJubm4ICgpCenq6lC8+Ph4jR45ExYoVoa+vj3LlyqFDhw44dOhQvuX36tULbdq0kaX98ccfUCgUmDJliix95syZKF26NKZNm6Y2xmf/GBsbQ09PT5ZmYGCAZs2aYenSpUhNTZUd28PDQ7ZvzZo1cfnyZcTHx0t5sh/L1NQU9evXx2+//abReSYiog+nQ4cOaNmypdptERERUCgUOH/+fK77BwcH486dO5gwYYKsb5hX//BDGT16NOrVqwd9ff1cH7xGRUXB3d0dhoaGKFOmDGbMmAEuIEJEnxpfX1907txZJf3IkSNQKBR4+vTpe6/T22rcuDEePHgApVKpUf6c9061tLSgq6sri3NZ9w7f1m+//YaZM2cWeL8aNWqoxN686paQkICRI0fC0dERRkZGKF++PEaNGoXExERZPnt7e5U+5MSJE9+4fURExQ3joDwO6ujooHz58vjiiy/w5MkTKU9wcHCucaggfcE3jYNvIvs9zqxPr169ZHmePHmC/v37Q6lUQqlUon///sXyd05ERG8vr2eEGzZsgL6+PrS1taWYoq2tDQMDA1SvXl3KVxSfEcbGxsry6ejowMLCQqNnhNk/w4YNk/LwGSERFTWf5IygrVu3RlBQkCxNX18f06dPx/r16/Htt99CoVDItgcFBWHAgAEYM2YMQkNDMWvWLFy4cEHarqurW6A6BAYGYuTIkVi3bh3u3LmD8uXLS9vCwsLQq1cvzJkzBx07doRCocCVK1c0CopA5gDOVq1aYc6cOShRogSCgoLQoUMHnD59GnXq1AGQGRB79OiBr776Cq1atcLBgwexdOlS/Pzzz/D29gYAJCcnw8nJCYMGDUK3bt1Uynnx4gXOnz+PKVOmwMnJCU+ePIG/vz86duyIv/76q0Dng4iIipbc4lRaWhq8vb1x8eJFzJw5E25ubjAzM8OpU6ewaNEi1KlTB87OzoiNjYWbmxtKlCiBBQsWoHbt2khPT8f+/fsxfPhw/PPPP3mW7+npiXHjxuHVq1fQ0cn8c+XIkSMoV64cDh8+LMub9Wb/uHHjZJ2vBg0a4LPPPsPQoUPx6NEjPHv2DObm5vjhhx/wxx9/YOPGjcjIyEB6ejqioqIwa9Ys/Pzzzzhy5AhMTU2l4wwdOhQzZsyQlWlkZCT7OSgoCK1bt8bTp0+xcOFC9OjRAydOnICrq2vBTz4REb0Xfn5+6Nq1K27fvg07OzvZtsDAQDg7O6Nu3bq57t+xY0fY2trC19cXgwYNkm0raP/wXRNCYPDgwTh9+jT+/vtvle1JSUlo1aoVPD09cfbsWVy/fh2+vr4wNjbW+IVEdWW+fv1aiuNERJS7d3nN1NPTg42NTYH2ad26NWbMmIGUlBTcvHkTkyZNQv369aUZy6ytrQulbubm5m+03969e2UvIWanrm5xcXGIi4vDokWLUL16ddy+fRvDhg1DXFwctm3bJss7Y8YMDB06VPrZxOTtZmNJT08vcn8XEBEVNUUxDgYFBeHVq1e4cuUKBg8ejKdPn2Lz5s0AMvuCjRo1UrtvQa75bxoH31TOe5yGhoay7X369MG9e/ewb98+AMBnn32G/v37Y9euXW9cJuMgEVHxlNczwnXr1sHAwABjxoxB3bp1YWJigsjISAQEBGDhwoUAUOSeEWaxtLQEkPlyYVhYGDIyMvD48WMcOXKEzwiJ6KPxyc0ICmQO+rSxsZF9SpYsCT8/P0RHR+PYsWOy/MePH8eNGzfwxRdfwMHBAdbW1tDW1oaDg4P0yfngMC/JycnYunUrvvjiC7Rv3x7r16+Xbd+9ezeaNGmC8ePHw9HREVWqVEHnzp2xYsUKjY6/dOlSfP3112jQoAEqV66MOXPmoHLlyrLOWkhICLy8vLBo0SJ4e3tj0aJFaNmyJUJDQ6XA1qZNG8yaNQtdu3ZVW45SqcTBgwfh4+MDR0dHuLi4YMWKFTh37hzu3Lmj8fkgIqKiJa84tXTpUhw7dgyHDh3C8OHD4ezsjIoVK6JPnz44ffo0KleuDAD48ssvoVAocObMGXTv3h1VqlRBjRo18NVXX+HUqVP51sHT0xPPnz+XvVhw5MgRTJw4EWfPnsWLFy8AZHY6IyIi4OnpCRMTE1ls19bWhqmpKWxsbFCzZk24urrC0dER5ubmMDY2hqurK9zc3ODh4YGRI0fi6NGjuHTpEubPny+ri5GRkcrfDWZmZrI8JUqUgI2NDapWrYo1a9bAwMAAO3fufNNfARERvQft27eHlZWVSn/sxYsXCAkJgZ+fH0JDQ1GjRg3o6+vD3t4eixcvlvKZmppCV1cXlpaWcHBwgI6ODipXroznz59L/cOnT59CoVDgyJEjAP43k87+/ftRp04dGBoaonnz5nj48CH++OMPVKtWDWZmZujdu7cU64DMB6MLFixAxYoVYWhoCCcnJ5WBK3lZvnw5hg8fjooVK6rdHhwcjJSUFKxfvx41a9ZE165d8c033+D777+HEAKxsbHQ0tJSeeFvxYoVsLOzgxBC1rb69etDX18fx48f17iORETFQXJyMszMzFSuwbt27YKxsTGePXsGADhz5gzq1KkDAwMD1K9fX/YyOYBcr5nR0dHo1KkTrK2tYWJiggYNGiAsLEy2r7pVe0qUKKESz3KWlX1Gr5MnT8Ld3R1GRkYoWbIkvL29ZTOd6evro0GDBmjatCkGDRqEvn37IiIiQroPamRkBD8/P1SoUAGGhoZwdHTEsmXLZOW+fv0aX331FUqUKIFSpUrh66+/Vplp2sPDA/7+/hq3LS0tDSNGjICLiwtq1qyJli1b4tdff5Xdo83+wC5LzZo1ERoaig4dOqBSpUpo3rw5Zs+ejV27duHVq1eyvFl9yKxP1kBQIQQcHBywaNEiWf5Lly5BS0sL0dHRUhvWrFmDTp06wdjYONfVp4iIiqNPKQ7a2NigbNmy8PLyQs+ePXHgwAFpu5GREebOnYtWrVqhVq1aaNeuHfbs2SN7Vvgu46CtrS0MDAxgb2+PuXPnqm23OjnvcWafJfXq1avYt28f1q1bB1dXV7i6umLt2rXYvXs3rl27xjhIRPQJye8ZYXh4OI4cOYJp06ahY8eOaN68Ob766itERkbC3d0dQNF7Rpg9DQB0dHRgY2OD0qVLo1atWnxGSEQflU9yIGhuatWqhQYNGqjMFhoYGIiGDRuiZs2ahVJOSEgIHB0d4ejoiH79+iEoKEjWAbSxscHly5dx6dKlQikvIyNDmgUtS0REBLy8vGT5vL29ER4e/lZlJSYmQqFQoESJErnmSU1NRVJSkuxDRERFR15xKjg4GC1btpRmmM5OV1cXxsbGSEhIwL59+zB8+HAYGxur5MsrRmSpUqUKSpcuLb3Z9+zZM5w/fx49evRApUqVcPLkSQDAqVOn8PLlS3h6er5FizNVrVoVbdq0eeslG3R1daGjo5PrDDUAYyERUVGgo6ODAQMGYP369bL+2K+//oq0tDS4urrCx8cHvXr1QlRUFKZNm4YpU6bk+oCxIKZNm4aVK1ciPDwcd+/ehY+PD5YuXYpNmzZhz549OHjwoOxFwMmTJyMoKAirV6/G5cuXMWbMGPTr1w9Hjx5967oAmf1Dd3d36OvrS2ne3t6Ii4tDbGws7O3t0bJlS5W+clBQkLR0Ypavv/4ac+fOxdWrV1G7dm215TEOElFxZWxsjF69eqm9Hnbv3h2mpqZITk5G+/bt4ejoiHPnzmHatGkYN26c2uPlvGY+f/4cbdu2RVhYGC5cuABvb2906NChUF+4joyMRIsWLVCjRg1ERETgxIkT6NChA16/fq02/61bt7Bv3z7ZbF4ZGRkoW7Ystm7diitXruC7777DN998g61bt0p5Fi9ejMDAQAQEBODEiRNISEjA9u3b36ruy5cvx86dO7F161Zcu3YNv/zyC+zt7d/oWImJiTAzM1OZfW7+/PkoVaoUnJ2dMXv2bKSlpQHIHNgyePBgtfeNmzZtikqVKklpU6dORadOnRAVFYXBgwerlM04SETFFeNgpuIaB4ODg2FhYYEaNWpg3Lhx0sBdILNPqFQqZTOduri4QKlUIjw8vFDjIMBYSERUlPEZIZ8RElHx9kkOBN29ezdMTExkn5kzZwIABg8ejG3btuH58+cAgOfPn+PXX3+Fn59foZUfEBCAfv36AchcYuL58+eyZd9HjhyJBg0aoFatWrC3t0evXr0QGBiI1NTUNypv8eLFSE5Oho+Pj5QWHx+vslSStbU14uPj36gMAEhJScHEiRPRp08flbcgsps7dy6USqX0KVeu3BuXSUREhS+vOHXjxg1UrVo1z/1v3rwJIUS++fLj4eEhzaB2/PhxVKlSBZaWlnB3d5fNrFauXDnZzca3UbVqVcTGxsrSVq1apfJ3w4YNG9Tun5qailmzZiEpKQktWrTItRzGQiKiomHw4MGIjY2V4gqQ+SCra9eu+P7779GiRQtMmTIFVapUga+vL0aMGCEtcfQ2Zs2aBTc3N9SpUwd+fn44evQoVq9ejTp16qBp06bo3r27dKMzOTkZ33//PQIDA+Ht7Y2KFSvC19cX/fr1w48//vjWdQFy7x9mbQOAIUOGYPPmzVK/9OLFi4iMjMSgQYNk+82YMQOtWrVCpUqVUKpUKbXlMQ4SUVGm7r5hmzZtpO1DhgzB/v37ERcXBwB49OgRdu/eLQ10CA4OxuvXrxEYGIgaNWqgffv2GD9+vNqycl4znZyc8Pnnn6NWrVqoXLkyZs2ahYoVKxbqTCILFixA/fr1sWrVKjg5OaFGjRoYMWIELCwsVM6BoaEhKlWqhCtXrmDChAnSdl1dXUyfPh0NGjRAhQoV0LdvX/j6+soGwCxduhSTJk1Ct27dUK1aNaxZs0Y289ibuHPnDipXrowmTZrAzs4OTZo0Qe/evQt8nMePH2PmzJn4/PPPZemjR4/Gli1bcPjwYYwYMQJLly7Fl19+KW0fNGgQrl27hjNnzgDIXO72l19+URnk0qdPHwwePBgVK1ZUu4oU4yARFWWMgx9nHOzbty82b96MI0eOYMqUKQgNDZWtBhgfHw8rKyuV/aysrKQ+YWHFQYCxkIioKOMzwlhZGp8RElFx80kOBPX09ERkZKTsM3z4cABA7969kZGRgZCQEACZbzwIIdCrV69CKTurk5R1PB0dHfTs2ROBgYFSHmNjY+zZswc3b97E5MmTYWJigrFjx6Jhw4ay5QE1sXnzZkybNg0hISEqnbjss7YAmUsc5UzTVHp6Onr16oWMjAysWrUqz7yTJk1CYmKi9Ll79+4blUlERIUvvzilSazIejPwTWNKFk9PT5w8eRLp6ek4cuQIPDw8AEClk9e8efO3Kic7de3r27evyt8NXbp0keXp3bs3TExMYGRkhO+//x6LFi2S3STPibGQiKhoqFq1Kho3bizFuejoaBw/fhyDBw/G1atX4ebmJsvv5uaGGzdu5DpbjKayz5RpbW0NIyMj2bLt1tbWePjwIQDgypUrSElJQatWrWQ3HDdu3Cgtv1cY1PUPs6d37twZOjo60iw2gYGB8PT0VJmBpn79+vmWxThIREWZuvuG69atk7Y3bNgQNWrUwMaNGwEAP//8M8qXL49mzZoByFxa1cnJCUZGRtI+rq6uasvKec1MTk7G119/jerVq6NEiRIwMTHBP//8805mQstL1jk4ffo0Ro4cCW9vb4wcOVKWZ82aNahfvz4sLS1hYmKCtWvXSvVMTEzEgwcPZO3W0dHRKEbkxdfXF5GRkXB0dMSoUaNky/RqKikpCe3atUP16tUxdepU2bYxY8bA3d0dtWvXxpAhQ7BmzRoEBATg8ePHAABbW1u0a9dO+rth9+7dSElJQY8ePWTHya+djINEVJQxDn6ccXDo0KFo2bIlatasiV69emHbtm0ICwvD+fPnpTzq7uVmv1daWHEQYCwkIiqq+IyQzwiJqPjTyT/Lx8fY2BgODg5qtymVSnTv3h1BQUHw8/OTlrTIa4bLgggICMCrV69QpkwZKU0IAV1dXTx58gQlS5aU0itVqoRKlSphyJAh+Pbbb1GlShWEhISozLiSm5CQEPj5+eHXX39Fy5YtZdtsbGxUZv98+PChyiwwmkhPT4ePjw9iYmLw559/5nuu9PX1ZUsOEhFR0ZFfnKpSpQquXr2a5zEqV64MhUKBq1evonPnzm9cF09PTyQnJ+Ps2bM4fPiwNHuAu7s7BgwYgISEBERERGDgwIFvXEZOV69eRYUKFWRpSqUy178bsixZsgQtW7aEmZmZ2rfnc2IsJCIqOvz8/DBixAj88MMPCAoKgp2dHVq0aKH2xl/2JeRz0tLSUsmT2xJA2ZcVVCgUsp+z0jIyMgBA+u+ePXtk8RlAocWS3PqHwP9mBtXT00P//v0RFBSErl27YtOmTVi6dKnKsdQt+ZQT4yARFWXq7hveu3dP9vOQIUOwcuVKTJw4EUFBQRg0aJAUM/KKFerKym78+PHYv38/Fi1aBAcHBxgaGqJ79+7S8uRAZozIWUZeS87lZGhoqFG9ss7B8uXL4enpienTp0srKm3duhVjxozB4sWL4erqClNTUyxcuBCnT5/WuB7q5Ne2unXrIiYmBn/88QfCwsLg4+ODli1bYtu2bRod/9mzZ2jdujVMTEywfft2lfibk4uLC4DMGW2yZrkeMmQI+vfvjyVLliAoKAg9e/aUDXYC8o+FjINEVJQxDn68cTC7unXrQldXFzdu3EDdunVhY2ODf//9VyXff//9J3tuWBhxEGAsJCIqqviMkM8Iiaj4+yRnBM2Pn58fTp48id27d+PkyZOFtiz8q1evsHHjRixevFj2xsDFixdhZ2eH4ODgXPe1t7eHkZERkpOTNSpr8+bN8PX1xaZNm9CuXTuV7a6urjh48KAs7cCBA2jcuHGB2pQ1CPTGjRsICwvLdek/IiIq+jSJU3369EFYWBguXLigdv/k5GSYm5vD29sbP/zwg9q49fTpU43qU6lSJZQrVw47d+5EZGQk3N3dAWS+fW5vb4/FixcjJSUFnp6eb9XuLP/88w/27duHbt26FXhfGxsbODg4aNTBIyKiosXHxwfa2trYtGkTNmzYID3ErF69Ok6cOCHLGx4ejipVqkBbW1vlOJaWlgCABw8eSGmRkZFvXb/q1atDX18fd+7cgYODg+xTWMsGubq64tixY7IHrAcOHEDp0qVlM34OGTIEYWFhWLVqFdLT02VLCRIRfUr69euHO3fuYPny5bh8+bLswVP16tVx8eJFvHz5Uko7deqURsc9fvw4fH190aVLF9SqVQs2NjYqy9JZWlrKYs2NGzcKtIJQ7dq1pWX9NDV16lQsWrRIWgb4+PHjaNy4Mb788kvUqVMHDg4OslmqlUolbG1tZe1+9eoVzp07l2c5mrTNzMwMPXv2xNq1axESEoLQ0FAkJCTk24akpCR4eXlBT08PO3fuhIGBQb77ZPV7bW1tpbS2bdvC2NgYq1evxh9//KGyHC4R0aeAcbD4xcGcLl++jPT0dCnGubq6IjExUVr2HQBOnz6NxMRE2XNDxkEioo8XnxHyGSERfRw+yRlBU1NTVWY70dHRgYWFBYDMtwgcHBwwYMAAODg4SEtavK3du3fjyZMn8PPzg1KplG3r3r07AgICMGLECEybNg0vXrxA27ZtYWdnh6dPn2L58uVIT09Hq1at8i1n8+bNGDBgAJYtWwYXFxeprYaGhlK5o0ePRrNmzTB//nx06tQJv//+O8LCwmQPOp8/f46bN29KP8fExCAyMhLm5uYoX748Xr16he7du+P8+fPYvXs3Xr9+LZVlbm4OPT29tz5nRET0/mgSp06dOoU9e/agRYsWmDlzJpo0aQJTU1P89ddfmD9/PgICAuDs7IxVq1ahcePGaNiwIWbMmIHatWvj1atXOHjwIFavXp3vG4NZPD09sWrVKjg4OMjePnd3d8eKFStQsWJFlC9fvsBtffXqFeLj45GRkYHHjx/jyJEjmDVrFpydnaW3CrO8ePFC5e8GfX192SzeRERUfJmYmKBnz5745ptvkJiYCF9fXwDA2LFj0aBBA8ycORM9e/ZEREQEVq5ciVWrVqk9jqGhIVxcXDBv3jzY29vj0aNHmDx58lvXz9TUFOPGjcOYMWOQkZGBJk2aICkpCeHh4TAxMdHorfebN2/i+fPniI+Px8uXL6UBqtWrV4eenh769OmD6dOnw9fXF9988w1u3LiBOXPm4LvvvpPNilqtWjW4uLhgwoQJGDx4sEaz6RARfYxKliyJrl27Yvz48fDy8kLZsmWlbX369MG3334LPz8/TJ48GbGxsVi0aJFGx3VwcMBvv/2GDh06QKFQYMqUKdLM0FmaN2+OlStXwsXFBRkZGZgwYUK+M1tmN2nSJNSqVQtffvklhg0bBj09PRw+fBg9evSQ7o3m5OHhgRo1amDOnDlYuXIlHBwcsHHjRuzfvx8VKlTAzz//jLNnz8pmThk9ejTmzZuHypUro1q1avj+++/zfeCXX9uWLFkCW1tbODs7Q0tLC7/++itsbGxQokSJPI/77NkzeHl54cWLF/jll1+QlJSEpKQkAJmDbrS1tREREYFTp07B09MTSqUSZ8+exZgxY9CxY0dZn1NbWxu+vr6YNGkSHBwccl3umIjoY8Y4WLziYHR0NIKDg9G2bVtYWFjgypUrGDt2LOrUqQM3NzcAmX291q1bY+jQofjxxx8BAJ999hnat28PR0dH6ViMg0REHy8+I+QzQiL6SIhPzMCBAwUAlY+jo6Ms35w5cwQAMWfOHJVjBAUFCaVSqVF5AQEBolSpUkIIIdq3by/atm2rNt+5c+cEAHHu3Dnx559/im7duoly5coJPT09YW1tLVq3bi2OHz+uUZnu7u5q2zhw4EBZvl9//VU4OjoKXV1dUbVqVREaGirbfvjw4TyPExMTo3Y7AHH48GGN6iqEEImJiQKASExM1HgfIvq08Drxfmgap1JSUsTcuXNFrVq1hIGBgTA3Nxdubm5i/fr1Ij09XdonLi5ODB8+XNjZ2Qk9PT1RpkwZ0bFjxwLFiKCgIAFADBs2TJb+888/CwDCz88v133t7OzEkiVLVNKnTp0qxSttbW1hbm4umjRpIpYsWSJSUlJkeXOLqd7e3lIeAGL79u0at0kdfseJKD+8Trxb4eHhAoDw8vKSpW/btk1Ur15d6OrqivLly4uFCxfKtueMNVeuXBEuLi7C0NBQODs7iwMHDsj6R1l9rCdPnkj7qOtfTp06VTg5OUk/Z2RkiGXLlkn9N0tLS+Ht7S2OHj2qUftyi2cxMTFSnr///ls0bdpU6OvrCxsbGzFt2jSRkZGhcqyAgAABQJw5c0aWrq5tmuL3m4jy876uEwMHDhSdOnVSSVd3jTt06JAAILZu3aqSPyIiQjg5OQk9PT3h7OwsQkNDBQBx4cKFXI8nROa9Nk9PT2FoaCjKlSsnVq5cKdzd3cXo0aOlPPfv3xde/8fencfVtP3/A3+d5uE0iJLubZAmZcgUFSqiPhJuqCikzPPsmjNkyHjNLp1TKMp4jSEaUKauQiWhZCizUCi1f3/0O/vb7pzqRO51eT8fj/P4fFp77bXX2fc89ttaew3duzOqqqqMqakpc+LECUZDQ4MRCoVsGTVdKy4ujrGzs2MUFRUZTU1NxsXFhT1e1T0IDw9nFBQUmNzcXObjx4+Mn58fo6GhwWhqajKjR49mfv/9d07sKikpYSZOnMioq6szmpqazJQpU5jBgwdzyq7td/vzzz8Za2trRlVVlVFXV2e6du3K/P3332J1rayqPs6KsTA5OZlp3749o6GhwSgpKTHm5ubMggULmMLCQrHy7t27xwBggoODxY59SfuQ4iAhpCYUByeyeSgO1j4O5ubmMp07d2a0tLQYBQUFpkmTJsyECROYly9fcvK9fPmS8fHxYdTU1Bg1NTXGx8dHYvuuruMgw1AsJITUjJ4T3x69I6R3hISQ71dtnhM8hmEYqUeNklqrV68elJSUONs5EK63b99CQ0MDBQUFUFdX/7erQwj5DtFzgvzo6DdOCKkJPSfI9yIoKAh79+7FzZs366xM+n0TQmryPT4nwsPDMXHiRDx58oR2xfnJXLx4EY6Ojnj06BFnVZov9T3+vgkh35fv8TlBcfDnVddxEPg+f+OEkO8LPSfIj4x+34SQmtTmOfFTbg0vLXd3d3z48AExMTFix5KSkmBnZ4fk5GS0bt1a7HhRURFu376N9+/fo0WLFv9Edb9Yamoqli9fjgsXLuDFixcwMjLCqFGjMHHixH+0Hv223IW8Ev8fvSb5P8cnmv3bVSCE1KHExER06tQJ3bp1Q3R0NOdYcXEx1q1bh/DwcGRlZUFFRQXm5uYYNmwYfH192S2H8vPzERQUhOPHj+Px48fQ0dGBtbU1Jk2ahK5du9ZYByMjIzx48ABJSUno0KEDmz5p0iSkpKQgLi6OTXv16hUWLVqEw4cP48mTJ6hfvz5cXV2xcOFCzrYOCQkJWLlyJZKTk5GXl4dDhw6hT58+nOsyDIOFCxfizz//xOvXr9G+fXts2rQJVlZWYnVcunQp5s2bh6CgIPz+++8AgAMHDsDT0xPZ2dkSt5SwsLBA9+7dsX79ejg6OiI+Pl4sz8iRI7F169Ya71FlFAsJqT36Nwz53vj5+SEsLAwAICcnBy0tLbRo0QIDBgyAn58fZGRkAEBiDPHy8sLevXvZv1+/fo0JEybgyJEjAIBevXphw4YNNW799y28f/8eGRkZ2LBhAxYvXvxNrkFx8OdEz3HyX1NUVITs7GwsW7YMI0eOrPPBL5XjiL6+Pjw8PLBw4UI8f/6cs+2suro6mjZtijlz5sDd3Z1NDw0NxdChQ8XKVlRUxMePH9m/pWnzGRkZYdKkSZg0aRL794MHDwAAysrKMDY2xvjx4zFy5Ei23PDwcAQHByMrKwsaGhpwdXXFqlWrUL9+fQBAWloa5s+fj+TkZDx48ABr165lyxep67ZfVa5fv46lS5ciISEBBQUFMDAwgIODA6ZPnw4zM+7zydnZGefOnUPr1q3h6emJDx8+gMfjVVv+ggULEBgYKFVdKA6S7xnFayLyreNgXfqe+kcByXFTmphd8d8GsrKy0NPTg5ubG5YuXcrZllZ0rT179sDb25tTnpWVFdLT0yEUCuHn58c5Jm3/6KdPn/Dw4UPMmzcPysrKCAoKqvP+UYqF5EdCsZP8276nOEjvCaVDcbBu0POX/Oxk/u0KfM8CAgJw7tw5tpFWkUAggLW1NQYNGgQ+ny/20dHRQZs2baCgoIDu3bvXab2srKwkXpPP5yM8PLzW5SUnJ0NbWxu7d+9GWloa5syZg1mzZmHjxo1fVc+SkpKvOp8QQsiXEwgEGD9+PC5cuIDc3Fw2vbi4GC4uLli+fDlGjBiBxMREXLlyBWPHjsWGDRuQlpYGAMjJyUGbNm1w7tw5BAcH4+bNm4iOjoaTkxPGjh0rdT2UlJQwc+ZMsfSnT59y4leDBg2wYcMGPH36FEZGRoiMjMS9e/fQrl073L9/nz2vsLAQLVu2rDZGBQcHY82aNdi4cSOuXr0KXV1ddOvWDe/evRPLKxQKMWPGDAgEAjatV69eqF+/PtvBWtHFixeRmZmJgIAANm348OHIy8vjfIKDg6W+R4QQQn48rq6uyMvLQ05ODk6ePAknJydMnDgRPXv2xOfPn9l8lWPItm3bOOUMHDgQKSkpiI6ORnR0NFJSUjBo0CBOnlGjRlXZPhw1alSdfadx48ahY8eOcHBwgL+/f52VSwgh/zXBwcGwtrZGw4YNMWvWrG9yDVEcuX//PpYsWYLNmzdj2rRp7PGYmBjk5eXh8uXLsLGxQd++fXHr1i1OGerq6mLtlIp9nF/T5lu0aBHy8vJw48YN9OnTB6NGjUJkZCQA4MKFCxg8eDACAgKQlpaGffv24erVqxg2bBh7flFREYyNjbF8+XLo6upKvEZt2n6enp7g8Xi4ePEimjdvzomF1Q0KPXbsGDp06IBPnz4hPDwcGRkZ2LVrFzQ0NDBv3jxO3tzcXFy4cIG9d8HBwdDX1+fc36lTp8LKyoqTVvG/GyGE/Aj+iThYV76X/tHq4iZQc8wGuG3MHTt24OjRoxgzZgyA8gkYfD4fubm54PF48PX15cTBS5cuIT8/H6qqqhLrJ23/6J49e2Bubo7Hjx/j3bt31D9KCCHfue8lDkp6T3j79m2cP39e4ntChmFw9+5dek9ICCFfiAaCVqNnz57Q0dFBaGgoJ72oqAiRkZEICAjA+PHj0ahRIxQXF0NDQwPjx49HSkoKUlJS8PbtW2hra7ONq5ycHPB4PKSkpLBlvXnzBjwej53tEBcXBx6Ph1OnTqFVq1ZQVlZGly5d8OzZM5w8eRJNmzbFgwcP4OjoiKSkJPZa169fx5gxYzBnzhwoKyujZcuW2L9/v1Tf09/fH+vXr4eDgwOMjY3h6+uLoUOH4uDBgwDKg6m6urpYeUePHoWqqirevXvHfreoqCg4OjpCSUkJu3fv/rIbTwgh5KsUFhYiKioKo0ePRs+ePTlxbN26dUhISMDZs2cxduxYWFtbw9jYGAMHDsTly5dhamoKABgzZgx4PB6uXLmCfv36wczMDFZWVpgyZQouXbokdV1GjhyJS5cu4cSJE5z0+vXrszGsV69eUFJSwoULF3Dz5k2cOXMGnTt3xqlTpyAvL89pUP7vf//DkiVL4OHhIfF6DMNg3bp1mDNnDjw8PNCsWTOEhYWhqKgIERERnLzx8fH48OEDFi1ahMLCQiQkJAAA5OXlMWjQIISGhoJhGM45AoEAbdq0QcuWLdk0FRUV6Orqcj60dQMhhPzcFBUVoauri19++QWtW7fG7Nmz8ddff+HkyZOcuFw5hmhoaLDHMjIyEB0djR07dsDW1ha2trbYvn07jh07hszMTDbfokWL2Jha8bNt2zZs27at2raluro6BgwYgKKiIrY8R0dHjB8/HpMmTUK9evXQsGFD/Pnnn9i0aRMGDhyIEydOwMzMDCdPnvxH7iUhhHxvAgMDUVJSgrNnz4LP/zYrdYjiiL6+PgYOHAgfHx8cPnyYPV6/fn3o6urCwsICQUFBKCkpQWxsLKcMHo8n1k6puH3r17T51NTUoKurCxMTEyxZsgSmpqZs/S5dugQjIyNMmDABjRs3RseOHTFy5Ehcu3aNPb9du3ZYuXIlvL29oaioKPEatWn7LV68GDdu3EBqaipUVVUxc+ZMNh5WbouKFBUVYejQoejRoweOHDkCZ2dnNG7cGO3bt8eqVavEJmcIhUL89ttvSE9PR3FxMTQ1NSErK8u5v3w+H3JycmJphBDyI/kn4mBd+J76R6uLm0DNMRv4v38b/Prrr+jevTu8vLxw+vRpAOWDVVJSUtCoUSOMGDECsrKyOHnyJBsHBQIBfHx8ICcnvklkbfpH/fz8UFpaio4dO1L/KCGEfOe+pzgo6T2hsbEx2rZtK/E9YUJCAgwMDOg9ISGEfCEaCFoNOTk5DB48WOwBv2/fPhQXF8PW1hZjx47F4MGDcevWLQQFBeGPP/7AhQsXYGJiAjU1tS++dmBgIDZu3IjExEQ8fPgQnp6eWLduHSIiInDy5Ek2WJqYmMDExAShoaE4evQotm3bhrS0NEyePBm+vr4Sl6GWRkFBAbS0tAAAqqqq8Pb2hlAo5OQRCoXo168f53vOnDkTEyZMQEZGBlxcXCSW/enTJ7x9+5bzIYQQUnciIyNhbm4Oc3Nz+Pr6QigUsnEsPDwczs7OaNWqldh58vLyUFVVxatXrxAdHY2xY8dKnClem+1ojYyMMGrUKMyaNQtlZWVsupycHExMTGBsbIyTJ09i0KBBsLW1hYmJCQwNDQGUb5c0ZswYnDp1Cq9evZLqetnZ2cjPz+esxq2oqAgHBwckJiZy8oaEhGDAgAGQl5fHgAEDEBISwh4LCAjA/fv3OXFU1HCuOMvvS1EsJISQn0+XLl3QsmVLdsIdUB6XGzRoACsrK0ybNo0zKz0pKQkaGhpo3749m9ahQwdoaGhwYpqOjg7bLqz4+eWXXwBU37Y8fvw4zpw5gw0bNnDqGhYWhgYNGuDKlSsYP348Ro8ejf79+8POzg5///03XFxcMGjQIM4A0tqgOEgIIbWjrKwsceedkpISbN++HQDYrfukUZdtPqB8hRdR/ezs7PDo0SOcOHECDMPg6dOn2L9/P9zc3GpVZk0qtv3U1NRgYmICS0tLdOnSBXfv3mXjoah9WdmpU6fw4sULzJgxQ+LxiveAYRgIhUL4+vrCwsICZmZmiIqK+uK6UxwkhJBv73vqH62sYtz8Evfv30d0dDQb+0VxUF5eHhYWFnB1dUV8fDxMTEygra2NyMjIKnd1+Lf6RykWEkLIt/U9xUFJ7wkVFBSgrKws8T1hxTbcj/qekOIgIeRbooGgNfD390dOTg67YidQPsrfw8MDa9asQdeuXTFv3jyYmZnBz88P48aNw8qVK7/6ukuWLIG9vT1atWqFgIAAxMfHY8uWLWjVqhU6deqEfv36sTP9CwsLsWbNGggEAri4uMDY2Bh+fn7w9fUVm70ujaSkJERFRWHkyJFs2rBhw3Dq1Ck8efIEAPDixQscO3ZMrPE4adIkeHh4oHHjxtDT05NY/rJly6ChocF+9PX1a11HQgghVQsJCYGvry+A8m2D3r9/j7NnzwIAsrKyYGFhUe35d+/eBcMwNeaT1ty5c5GdnY3w8HCxY8+fP8ebN2/QtGlTiec2bdqU3QZCGvn5+QAgNmu+YcOG7DEAePv2LQ4cOMDeJ19fX+zfv59tbFlaWqJ9+/acSRBRUVEoLS3FgAEDOGVv3rxZbCteSdtFVESxkBBCfk4WFhbIyckBAPj4+GDPnj2Ii4vDvHnzcODAAc5M9vz8fOjo6IiVoaOjw4lpNalN21KkZcuWmDt3LkxNTTFr1iwoKyujQYMGGD58OExNTTF//ny8fPkSN27c+KL7QHGQEEKkd+XKFURERKBr165smp2dHfh8PpSUlDB16lQYGRnB09OTc15BQYFYO0X0Iqyu2nyfP39GaGgobt68ydbPzs4O4eHh8PLygoKCAnR1daGpqSk26eBrSdv2q0pWVhYASHUPYmJiUFRUxE569/X15bwgrC2Kg4QQ8u19b/2jgOS4CVQfs0WOHTsGPp8PZWVlNGnSBOnp6WLb7Ir4+/uzC9zs378fTZo0gbW1tVi+f7N/lGIhIYR8W99bHKT3hFwUBwkh3xINBK2BhYUF7OzsIBAIAAD37t3D+fPn4e/vj4yMDNjb23Py29vbIysrC6WlpV913RYtWrD/v2HDhlBRUYGxsTEn7dmzZwCA9PR0fPz4Ed26deMEl507d+LevXu1um5aWhp69+6N+fPno1u3bmy6jY0NrKyssHPnTgDArl272CW5K2rbtm2N15g1axYKCgrYz8OHD2tVR0IIIVXLzMzElStX4O3tDaB85U0vLy82jjEMAx6PV20ZolmBNeWTlra2NqZNm4b58+ejuLi4Vud+aV0q56/8vSMiImBsbMxu3SDa+mLv3r1snoCAAOzfv59dnU00EaTyTEcfHx+x7Xh/++23autHsZAQQn5OFePR8OHD4ezsjGbNmsHb2xv79+9HTEwM/v77bza/pPgnTSyvqDZtS0nnyMrKon79+mjevDnnHABi50mL4iAhhFRPNNhDSUkJtra26Ny5M2cgZWRkJK5fv44jR47AxMQEO3bsYHf2EVFTUxNrp4heYH1tm2/mzJnsYJSxY8di+vTp7ITy9PR0TJgwAfPnz0dycjKio6ORnZ2NUaNGfdG1alJT268qlbf3q05ISAi8vLzYLXUHDBiAy5cvIzMzs3aV/f8oDhJCyLf1vfWPVhc3gepjtoiTkxNSUlJw+fJljB8/Hi4uLhg/frzE67m5ueH9+/dISEiAQCCocjXQf7N/lGIhIYR8O99bHAToPWFlFAcJId+S3L9dgf+CgIAAjBs3Dps2bYJQKIShoSG6du0qMUhW14koIyMjlqeq7R8qbufE4/HEtnfi8Xjs0tmi/z1+/Di7/Z+IoqJiTV+PlZ6eji5dumD48OGYO3eu2PFhw4Zh48aN+P333yEUCjF06FCx7y9pafDKFBUVa1UvQggh0gsJCcHnz5858YBhGMjLy+P169cwMzNDRkZGtWWYmpqCx+MhIyMDffr0qZN6TZkyBZs3b8bmzZs56dra2tDU1ER6errE827fvg0ej4cmTZpIdR1dXV0A5TP+GjVqxKY/e/aMM/tPIBAgLS2NfZEHlMfTkJAQjBgxAgDg7e2NyZMnIzIyEo6Ojrhw4QIWLVokdk0NDQ2YmJhIVT8RioWEEPJzysjIQOPGjSUea926NeTl5ZGVlYXWrVtDV1cXT58+Fcv3/PlzsRnt1alN21LSOZLOE7UDK58nLYqDhBBSPScnJ2zZsgXy8vLQ09Njn8GiVaX19fVhamoKU1NT8Pl89O3bF+np6ZyVpGVkZKpsp3xtm2/69Onw8/ODiooKGjVqxOkfXLZsGezt7TF9+nQA5ZMLVFVV0alTJyxZsoTTTvsa0rb9qmJmZgagvM1pa2tbZb5Xr17h8OHDKCkpwZYtW9j00tJSCAQCrFixotZ1pzhICCHf1vfWP1pd3ASqj9kiqqqqbJ7169fDyckJCxcuxOLFi8XyysnJYdCgQViwYAEuX76MQ4cOSSzz3+wfpVhICCHfzvcWB0XoPeH/oThICPmWaEVQKXh6ekJWVhYREREICwtjB0BaWlriwoULnLyJiYkwMzODrKysWDna2toAgLy8PDYtJSXlq+tnaWkJRUVF5ObmwsTEhPORdhnptLQ0ODk5YciQIQgKCpKYx9fXF7m5uVi/fj3S0tIwZMiQr647IYSQuvP582fs3LkTq1ev5sw6S01NhaGhIcLDwzFw4EDExMTg+vXrEs8vLCyElpYWXFxcsGnTJhQWForle/PmTa3rxufzMW/ePAQFBbHbKgDlHZ2enp6IiIgQ277vw4cP2Lx5M1xcXMRWt6lK48aNoaurizNnzrBpxcXFiI+Ph52dHQDg5s2buHbtGuLi4jj3KSEhAVevXsWtW7cAlM/G79+/P4RCIQQCAYyNjeHo6Fjr704IIYQAwLlz53Dz5k307dtX4vG0tDSUlJSwHZS2trYoKCjAlStX2DyXL19GQUEBG9MIIYT8mESDPQwNDcUG51fm4OCAZs2aVdmfJ8nXtvkaNGgAExMT6OnpiQ1mKSoqYifDi4j6SWuzCmdNpGn7Vad79+5o0KABgoODJR4X3YPw8HD8+uuvSE1N5bQf161bh7CwMHz+/LlOvg8hhJC68T32j1YXN7/UggULsGrVKjx58kTicX9/f8THx6N3796oV6+e2HHqHyWEkB/T9xgHReg9ISGE/DNoRVAp8Pl8eHl5Yfbs2SgoKICfnx8AYOrUqWjXrh0WL14MLy8vJCUlYePGjWKzGESUlZXRoUMHLF++HEZGRnjx4oXElTdrS01NDdOmTcPkyZNRVlaGjh074u3bt0hMTASfz69xwKZoEGj37t0xZcoUNsDKysqyg1cBoF69evDw8MD06dPRvXt3/Prrr19dd0IIIXXn2LFjeP36NQICAqChocE51q9fP4SEhODSpUs4fvw4unbtisWLF6Njx45QU1PDtWvXsGLFCoSEhMDa2hqbN2+GnZ0dbGxssGjRIrRo0QKfP3/GmTNnsGXLlhpnC0oyYsQIrF27Fnv27EH79u3Z9KCgIJw9exbdunVDcHAwmjVrhuzsbMydOxclJSXYtGkTm/f9+/e4e/cu+3d2djZSUlKgpaUFAwMD8Hg8TJo0CUuXLmVXyFm6dClUVFQwcOBAAOWzIW1sbNC5c2exOtra2iIkJARr164FUL4qeKdOnZCeno5p06ZJ7KwtKioSa5wqKipK7GQlhBDyc/j06RPy8/NRWlqKp0+fIjo6GsuWLUPPnj0xePBg3Lt3D+Hh4ejRowcaNGiA9PR0TJ06Fa1atYK9vT0AoGnTpnB1dcXw4cOxbds2AOWxtGfPnjA3N/83vx4hhJDvzNSpU9G/f3/MmDGDXfWFYRixdgoA6OjoQEZG5pu0+QDA3d0dw4cPx5YtW+Di4oK8vDxMmjQJNjY20NPTA1D+Ek602ktxcTEeP36MlJQU8Pl8dhWVumj7VUdVVRU7duxA//790atXL0yYMAEmJiZ48eIFoqKikJubi7179yIkJAT9+vVDs2bNOOcbGhpi5syZOH78OHr37v1F94oQQkjd+977RyWpKWZL4ujoCCsrKyxduhQbN24UO960aVO8ePECKioqEs+n/lFCCPkxfe9xkN4TEkLIP4AhUklMTGQAMN27d+ek79+/n7G0tGTk5eUZAwMDZuXKlZzjhoaGzNq1a9m/09PTmQ4dOjDKysqMtbU1c/r0aQYAExsbyzAMw8TGxjIAmNevX7PnCIVCRkNDg1PuggULmJYtW7J/l5WVMX/88Qdjbm7OyMvLM9ra2oyLiwsTHx9f43dbsGABA0DsY2hoKJb37NmzDAAmKiqKk56dnc0AYK5fv17j9SorKChgADAFBQW1PpcQ8nOg54R0evbsyfTo0UPiseTkZAYAk5yczHz8+JFZtmwZ07x5c0ZJSYnR0tJi7O3tmdDQUKakpIQ958mTJ8zYsWMZQ0NDRkFBgfnll1+YXr16sTGrJpVjIMMwTEREBAOAcXBw4KQ/f/6cGT9+PKOvr8/IyckxDRs2ZIYMGcI8ePCAk08UJyt/hgwZwuYpKytjFixYwOjq6jKKiopM586dmZs3bzIMwzCfPn1i6tevzwQHB0us8+rVq5kGDRownz59YtPMzc0ZGRkZ5uHDh2L5HRwcJNbHxcVFqnskQr9xQkhN6Dnx3zFkyBA2HsjJyTHa2tqMs7MzIxAImNLSUoZhGCY3N5fp3Lkzo6WlxSgoKDBNmjRhJkyYwLx8+ZJT1suXLxkfHx9GTU2NUVNTY3x8fDhtxep8advSwcGBmThxIiePpJgOgDl06JBUdakJ/b4JITX5mZ4TQ4YMYXr37i3xWFX9b2VlZYy5uTkzevRohmHKn/eS2ikAmLy8PPY8adp8lWOApJhQ2fr16xlLS0tGWVmZadSoEePj48M8evRI7HtU/lRsJ35t209aV69eZTw8PBhtbW1GUVGRMTExYUaMGMFkZWUx165dYwAwV65ckXiuu7s74+7uzv5dOaZK62f6fRNCvgw9J6T3X+gfrUiamF3Vvw3Cw8MZBQUFJjc3V6praWhoMEKh8LvsH6XfOCGkJvSckM5/IQ7Se0Jx9PsmhNSkNs8JHsPU4Z485IcXHh6OiRMn4smTJ1BQUKiTMt++fQsNDQ0UFBRAXV29TsokhPxY6DlBfnT0GyeE1ISeE+RHRr9vQkhN6DlBfmT0+yaE1ISeE+R7w+PxcOjQIfTp06dOyqPfOCGkJvScID8y+n0TQmpSm+cEbQ0vJUlLPFc0ZMgQhIaGVnt+5UZRaGgohg4dCgCQkZGBuro6zMzM4ObmhokTJ4ot1w0AS5cuxbx58xAUFITff/+dc6y0tBTBwcEICwvDgwcPoKysDDMzM4wcOZK9jjQcHR1hbW2NdevWsWkrV67E7Nmzoauri5EjR2LEiBEICwvDyJEjsXXrVs75Y8aMwZYtW2q8J5X123IX8kp8qfOT6h2faPZvV4EQQr7Iw4cPERgYiJMnT+LFixdo1KgR+vTpg/nz56N+/foAymNVfHy82LmS4tJ/CcVC8r2gf0eQH0FiYiI6deqEbt26ITo6mnOsuLgY69atQ3h4OLKysqCiogJzc3MMGzYMvr6+kJeXBwDk5+cjKCgIx48fx+PHj6GjowNra2tMmjQJXbt2rbEORkZGePDgAQBAWVkZxsbGGD9+PEaOHAmA2yasSFFRER8/fgQA+Pn5ISwsDAAgKysLPT09uLm5YenSpZzthUTX2rNnD7y9vTnlWVlZIT09HUKhEH5+fpxjktqYBw4cgKenJ7Kzs2FgYCBWPwsLC3Tv3h3r16+v05hMcfDnQXGGkJ9HxTgmJycHfX19eHh4YOHChXj+/DkaN24s8bykpCR06NBBLFbq6OjAxsYGy5cvh5WVldh1atNXWZs4LyleVozzkjg4OCAuLk6q+wRQHCTfJ4rZ5Gf27NkzzJs3DydPnsTTp09Rr149tGzZEoGBgbC1ta3zwZDfSmlpKdavXw+hUIg7d+5ASUkJtra2mDt3Luzt7f/t6nFQLCT/BIpt5HtWm/aTuro6mjZtijlz5sDd3Z1Nl6a/EZCuPWRkZIRJkyZh0qRJ7N/V9XUC5QuLBQcHIysrCxoaGnB1dcWqVavY93tpaWmYP38+kpOT8eDBA6xdu5YtXyQhIQErV65EcnIy8vLyJMZbhmGwcOFC/Pnnn3j9+jXat2+PTZs2cdqJNbl+/TqWLl2KhIQEFBQUwMDAAA4ODpg+fTrMzLjPiu7du+Ps2bO4ePEiOnTogJycnCrbsyILFixAYGCg1PWhOCiOntmE1J7Mv12B/4q8vDz2s27dOqirq3PS/vjjjy8qV1TOo0ePkJiYiBEjRmDnzp2wtrbGkydPxPILhULMmDEDAoFA7FhgYCDWrVuHxYsXIz09HbGxsRg+fDi2b98OPp8v8TNq1Kga67hgwQLMnj0bDMPAzMwMs2bNAgDo6+tj7969+PDhA5v348eP2LNnj8SXhYQQQn4c4eHhVcaW2jSyKrt//z7atm2LO3fuYM+ePbh79y62bt2Ks2fPwtbWFq9evWLzDh8+nBOL8/LyEBwcXBdfjxBCyA9AIBBg/PjxuHDhAnJzc9n04uJiuLi4YPny5RgxYgQSExNx5coVjB07Fhs2bEBaWhoAICcnB23atMG5c+cQHByMmzdvIjo6Gk5OThg7dqzU9Vi0aBHy8vJw48YN9OnTB6NGjUJkZCR7vHLbMi8vT2xQiaurK/Ly8pCTk4MdO3bg6NGjaNeuHSf+5ubmgsfjwdfXl9POu3TpEvLz86GqqiqxfpLamL169UL9+vXZjueKLl68iMzMTAQEBAAA7ty5Azk5OaioqHA+u3fvlqq9SQgh5McnimP379/HkiVLsHnzZkybNo09HhMTIxYL27Rpwx4XxconT57g+PHjKCwshJubG4qLiznXqdhXWbHNumXLFvB4PDbNysqq1nFeUry8evUqW98DBw4AADIzM9m0gwcP1vWtJIQQ8g/q27cvUlNTERYWhjt37uDIkSNwdHTk9E8OGDCg2v7RkpKSf6v6AMoHyXh7e2PRokWYMGECMjIyEB8fD319fTg6OuLw4cNVnvtv150QQn5W0rafLl++DBsbG/Tt2xe3bt3ilFFTf+PX9HuK+joXL16MO3fuYNSoUVBSUgKfz4eKigp8fX3x7NkzpKWlYd++fbh69SqGDRvGnl9UVARjY2MsX74curq6Eq9RWFiIli1bYuPGjVXWIzg4GGvWrMHGjRtx9epV6Orqolu3bnj37l219Rc5duwYOnTogE+fPiE8PBwZGRnYtWsXNDQ0MG/ePE7e3NxcJCUlYdy4cQgJCQFQ3v6seH+nTp0KKysrTlrF/26EEPJPoYGgUtLV1WU/Ghoa4PF4nLSIiAg0adIECgoKMDc3x65du9hzjYyMAAC//fYbeDwe+zcAtpxGjRqhadOmCAgIQGJiIt6/f48ZM2Zw6hAfH48PHz5g0aJFKCwsREJCAuf40aNHMWbMGPTv3x+NGzdGy5YtERAQgMOHDyMlJQUpKSlITEyEs7MzysrKoKysDF1dXTg6OorNsgDKG4jjx4/HH3/8gdjYWHz+/Blnz54Fn18+C6F169YwMDDgdGoePHgQ+vr6aNWq1VfecUIIId+zXr16sbGl8ufEiRNfXO7YsWOhoKCA06dPw8HBAQYGBvjf//6HmJgYPH78GHPmzGHzqqiocGKxrq6u1FsmPHr0CN7e3tDS0oKqqiratm2Ly5cvAyifWGFtbQ2BQAADAwPw+XyMHj2aXXlbV1cXOjo6CAoK4pQZGBgIAwMDKCoqQk9PDxMmTPji+0AIIeTrFBYWIioqCqNHj0bPnj05q3+tW7cOCQkJOHv2LMaOHQtra2sYGxtj4MCBuHz5MkxNTQGUrx7G4/Fw5coV9OvXD2ZmZrCyssKUKVNw6dIlqeuipqYGXV1dmJiYYMmSJTA1NeW8bKvcttTV1UXDhg05ZSgqKkJXVxe//vorunfvDi8vL7x8+ZITfxs1aoQRI0ZAVlaWMwtfIBDAx8cHcnLiG4JU1caUl5fHoEGDEBoaCoZhOOcIBAK0adMGLVu2BFDe3vXx8UFqairnk5KSgkWLFkl9nwghhPy4RHFMX18fAwcOhI+PDycW1q9fXywWilbnBrj9p23btsXkyZPx4MEDZGZmcq5Tsa9S1GZdtGgRzMzM0KVLF7i7u7Nt1trE+aripba2NltfLS0tAOUrllZOI4QQ8t/z5s0bXLhwAStWrICTkxMMDQ1hY2ODWbNmwc3NjX3P9/HjRxQWFkJDQwMpKSnw9/eHvr4+hgwZAmNjYygqKoJhGBQUFGDEiBHQ0dGBuro6unTpgtTUVPZ69+7dQ+/evdGwYUPw+Xy0a9cOMTExnDoZGRlhyZIlGDx4MPh8PgwNDfHXX3/h+fPn6N27N/h8Ppo3b45r166x50RFRWH//v3YuXMnhg0bxr47/PPPP9GrVy8MGzYMhYWFALh9ohXrnpWVhc6dO0NJSQmWlpY4c+aM2P16/PgxvLy8UK9ePdSvXx+9e/dGTk5O3f+HIYSQn4C07ScLCwsEBQWhpKQEsbGxnDJq6m/8mn5PUV/niBEjkJ6eDkNDQzg7OyMlJQUTJkyAvr4+Ll26hMaNG6Njx44YOXIkJza1a9cOK1euhLe3NxQVFSVe43//+x+WLFkCDw8PiccZhsG6deswZ84ceHh4oFmzZggLC0NRUREiIiJqusUoKirC0KFD0aNHDxw5cgTOzs5o3Lgx2rdvj1WrVmHbtm2c/EKhED179sTo0aMRGRmJwsJCyMrKcu4vn8+HnJycWBohhPzTaCBoHTh06BAmTpyIqVOn4tatW+xW7KKAe/XqVQDlASIvL4/9uyo6Ojrw8fHBkSNHUFpayqaHhIRgwIABkJeXx4ABA9jZBiK6uro4d+4cnj9/LlaeiYkJTExMsHXrViQnJ+Ovv/7CuXPnkJycjOTkZLE6fP78GYMGDcK+ffsQHx+Pjh07Sqzr0KFDIRQK2b8FAgH8/f2r/X6EEEL++9TU1NjYUvljaGj4RWW+evUKp06dwpgxY6CsrMw5pqurCx8fH0RGRooNSKmt9+/fw8HBAU+ePMGRI0eQmpqKGTNmoKysjM1z7949nDx5EtHR0dizZw8EAgHc3Nzw6NEjxMfHY8WKFZg7dy7bIN6/fz/Wrl2Lbdu2ISsrC4cPH0bz5s2/qp6EEEK+XGRkJMzNzWFubg5fX18IhUI2foSHh8PZ2Vni5DV5eXmoqqri1atXiI6OxtixYyWupKmpqfnFdVNSUvqqlVXu37+P6OhoKCoqcuKvvLw8LCws4OrqiuPHjwMo79SMjIysso1WXRszICAA9+/f52z7LhpgK1oNFAAUFBSgqakp8d8EOjo6X/w9CSGE/LiUlZW/OBa+efOGfbFXcbCoiKivUtRmPXHiBEaPHg0+nw91dXWYmJhATU2tVnG+pj5ZQgghPx7Ryp6HDx/Gp0+fxI5Xfu+XkpICExMTaGlp4eHDhzh37hwOHDiAlJQUAICbmxvy8/Nx4sQJJCcno3Xr1ujatSu7uuj79+/Ro0cPxMTE4Pr163BxcYG7uztndwsAWLt2Lezt7XH9+nW4ublh0KBBGDx4MHx9ffH333/DxMQEgwcPZtu/ERERMDMz42wZLDJ16lS8fPmSM7Dz7t27iIqKYuteVlYGDw8PyMrK4tKlS9i6dStmzpzJKaeoqAhOTk7g8/lISEjAhQsXwOfz4erqKrZ6NyGEkNqrqv1UUlKC7du3A5DcNqpKXfV7itpc6urqUFJSgomJCXr16oWnT58iLS0NDMPg6dOn2L9/P9zc3KSunzSys7ORn5+P7t27s2mKiopwcHBAYmJijeefOnUKL168EFuYTaTiPWAYBkKhEL6+vrCwsICZmRmioqK++jsQQsi3QgNB68CqVavg5+eHMWPGwMzMDFOmTIGHhwdWrVoFoHx2OFAeMHR1ddm/q2NhYYF3797h5cuXAIC3b9/iwIED8PX1BQD4+vpi//79ePv2LXvOmjVr8Pz5c+jq6qJFixYYNWoUTp48yR5///49QkJCsGrVKnTr1g3NmzdHWFgYZ7CpyPbt27Fv3z7ExcWxK71IMmjQIFy4cAE5OTl48OABLl68yNaxKp8+fcLbt285H0IIISQrKwsMw6Bp06YSjzdt2hSvX79mJzxs3rxZbNslSVvYVhYREYHnz5/j8OHD6NixI0xMTODp6QlbW1s2T1lZGQQCASwtLeHu7g4nJydkZmZi3bp1MDc3x9ChQ2Fubo64uDgA5dtC6OrqwtnZGQYGBrCxscHw4cOrrAPFQkII+bZCQkLYdomrqyvev3+Ps2fPAiiPNxYWFtWef/fuXTAMU2O+2vj8+TNCQ0Nx8+ZNdO3alU0vKCgQi2cVOzGB8q2K+Hw+lJWV0aRJE6Snp4u9fBPx9/dnV/Lcv38/mjRpAmtra7F8NbUxLS0t0b59e87Ev6ioKJSWlmLAgAGcsmobkykOEkLIz+vKlSuIiIjgxEI7OzuxOFKxv1IUK1VVVVGvXj3s3bsXvXr1khinpemrrE2cl6ZPtrYoDhJCyPdPTk4OoaGhCAsLg6amJuzt7TF79mzcuHEDQPXv/YqLi7Fr1y60atUKLVq0QGxsLG7evIl9+/ahbdu2MDU1xapVq6CpqYn9+/cDAFq2bImRI0eiefPmMDU1xZIlS2BsbIwjR45w6tWjRw+MHDkSpqammD9/Pt69e4d27dqhf//+MDMzw8yZM5GRkYGnT58CAO7cuVNtX6soT1V1P3v2LLtVrrW1NTp37oylS5dyytm7dy9kZGSwY8cONG/eHE2bNoVQKERubi7bd1oZxUJCCJFOde0nJSUlTJ06FUZGRvD09OScV11/Y131e0rq67Szs0N4eDi8vLygoKAAXV1daGpqYsOGDV91rcry8/MBQGxXpYYNG7LHqpOVlQUAUt2DmJgYFBUVwcXFBUB5m/BrJwdSHCSEfEs0ELQOZGRkwN7enpNmb2+PjIyMLy5TNFuPx+MBKB+0YmxszA7KFG1fuHfvXvYcS0tL3Lp1C5cuXcLQoUPx9OlTuLu7Y9iwYQDKVzcrLi7mDHTR0tKCubm52PU7duwIPp+PuXPn4vPnz1XWs0GDBnBzc0NYWBiEQiHc3NzQoEGDar/bsmXLoKGhwX709fWlvCuEEEJ+ZqLYqKCgAADw8fER25b+t99+q7GclJQUtGrVqtpt+oyMjKCmpsb+3bBhQ1haWkJGRoaT9uzZMwBA//798eHDBxgbG2P48OE4dOhQtfGTYiEhhHw7mZmZuHLlCry9vQGUv8Dz8vKCQCAAUB5PRO2sqlRuj32NmTNnsoM4x44di+nTp3O2bldTUxOLZxUHXwKAk5MTUlJScPnyZYwfPx4uLi4YP368xOu5ubnh/fv3SEhIqHbHBmnamAEBAdi/fz/evXsHoHwHCA8PD7GVAWobkykOEkLIz0U0oUFJSQm2trbo3Lkz50VgZGSkWByRlZVlj4tiZXJyMrZu3YomTZpg69atEq8lTV9lbeK8NPGytigOEkLIf0Pfvn3ZHYVcXFwQFxeH1q1bIzQ0tNrzDA0NOQNDk5OT8f79e9SvX58zICc7Oxv37t0DUL77wowZM2BpaQlNTU3w+Xzcvn1bbEXQFi1asP9fNPil4q5EojRRn6U0KsbDynXPyMiAgYEBfv31Vzat4jtG0fe7e/cu1NTU2O+mpaWFjx8/st+vMoqFhBBSNWnaT9evX8eRI0dgYmKCHTt2iL3vqq6/8Wv7Pavr60xPT8eECRMwf/58JCcnIzo6GtnZ2Rg1atQXXasmlb+DNP2+onzSCgkJgZeXF+Tk5AAAAwYMwOXLl5GZmVm7ylZAcZAQ8i3J/dsV+FF8aZCpSkZGBtTV1VG/fn0A5S/c0tLS2AADlK9WFhISghEjRrBpMjIyaNeuHdq1a4fJkydj9+7dGDRoEObMmVOrgNa8eXOsXr0azs7O8PT0RGRkZJVLivv7+2PcuHEAgE2bNtVY9qxZszBlyhT277dv31JwI4QQAhMTE/B4PKSnp6NPnz5ix2/fvg1tbW128ImGhgZMTExqfZ3K285LUjnm8Xg8iWmi7eT19fWRmZmJM2fOICYmBmPGjMHKlSsRHx8vMX5SLCSEkG8nJCQEnz9/xi+//MKmMQwDeXl5vH79GmZmZjVO2jM1NQWPx0NGRobEmFQb06dPh5+fH1RUVNCoUSOxdqKMjEyN8UxVVZXNs379ejg5OWHhwoVYvHixWF45OTkMGjQICxYswOXLl3Ho0CGJZUrTxvT29sbkyZMRGRkJR0dHXLhwAYsWLRIrq7YxmeIgIYT8XJycnLBlyxbIy8tDT0+PbSPl5OQAKG9PVRdHKsZKCwsL5Ofnw8vLCwkJCRLz19RXWZs4L22fbG1QHCSEkP8OJSUldOvWDd26dcP8+fMxbNgwLFiwAH5+flWeU3mb3bKyMjRq1Eji6piifs7p06fj1KlTWLVqFUxMTKCsrIx+/fqJba1esZ9R1LaUlCbqszQzM0N6errEeoraxaamplXWXdJ7xcpt2rKyMrRp0wbh4eFieavaIZFiISGEVE2a9pOpqSlMTU3B5/PRt29fpKenQ0dHhy2juv7Gr+33rK6vc9myZbC3t8f06dMBlE9gUFVVRadOnbBkyRI0atSo1teTRFdXF0D5yqAVy3z27JnYKqGSmJmZASh/71h5gkNFr169wuHDh1FSUoItW7aw6aWlpRAIBFixYsUX1Z/iICHkW6IVQetA06ZNceHCBU5aYmIiZ7sFeXl5iVuwS/Ls2TNERESgT58+kJGRwc2bN3Ht2jXExcVxZm0kJCTg6tWruHXrVpVlWVpaAiifTWhiYgJ5eXlcunSJPf769WvOtg8VWVtb49y5c7hw4QL69++PkpISiflcXV1RXFyM4uJidkns6igqKkJdXZ3zIYQQQurXr49u3bph8+bN+PDhA+dYfn4+wsPDq+1klVaLFi2QkpKCV69efXVZFSkrK6NXr15Yv3494uLikJSUhJs3b0rMS7GQEEK+jc+fP2Pnzp1YvXo1p+2UmpoKQ0NDhIeHY+DAgYiJicH169clnl9YWAgtLS24uLhg06ZNKCwsFMv35s0bqevUoEEDmJiYQE9Pr05WGAWABQsWYNWqVXjy5InE4/7+/oiPj0fv3r1Rr149sePStjHV1NTQv39/CIVCCAQCGBsbw9HR8avrT3GQEEJ+LqIJDYaGhlVONK+NyZMnIzU1tcrJDjX1VUob57+mT7Y6FAcJIeS/y9LSko0d0r73a926NfLz8yEnJwcTExPOR7Rq9fnz5+Hn54fffvsNzZs3h66uLjvg52t4e3sjKysLR48eFTu2evVqtj+2KpaWlsjNzeW0PZOSksS+X1ZWFnR0dMS+n4aGhsRyKRYSQkjVatN+cnBwQLNmzRAUFCR1+V/b71ldX2dRURFnZz0A7G4PtVm0rCaNGzeGrq4uzpw5w6YVFxcjPj4ednZ2NZ7fvXt3NGjQAMHBwRKPi+5BeHg4fv31V6SmpnLahOvWrUNYWFi1OwNWh+IgIeRbooGgdWD69OkIDQ3F1q1bkZWVhTVr1uDgwYOYNm0am8fIyAhnz55Ffn4+Xr9+zaYzDIP8/Hzk5eUhIyMDAoEAdnZ20NDQwPLlywGUr2hjY2ODzp07o1mzZuynY8eOsLW1RUhICACgX79+WLt2LS5fvowHDx4gLi4OY8eOhZmZGSwsLMDn8xEQEIDp06fj7NmzuHXrFvz8/MSCcUUtWrRAbGwskpKSJM4+BMqDd0ZGBjIyMjjbNhFCCCG1tXHjRnz69AkuLi5ISEjAw4cPER0djW7dusHMzAzz589n8xYVFSE/P5/zqRhjqzJgwADo6uqiT58+uHjxIu7fv48DBw6IdWLWRmhoKEJCQnDr1i3cv38fu3btgrKyMgwNDb+4TEIIIbV37NgxvH79GgEBAZy2U7NmzdCvXz+EhIRg0qRJsLe3R9euXbFp0yakpqbi/v37iIqKQvv27ZGVlQUA2Lx5M0pLS2FjY4MDBw4gKysLGRkZWL9+fbUzxWtL1Cas/BGt4CKJo6MjrKyssHTpUonHmzZtihcvXohtMS8ibRsTKN8ePjExEVu2bIG/v7/EwaxfGpMJIYQQAHj58qVYHPn48WOV+dXV1dkV2SS9TJSmr1KaOF+beEkIIeTH8vLlS3Tp0gW7d+/GjRs3kJ2djX379iE4OBi9e/cGUPV7v8qcnZ1ha2uLPn364NSpU8jJyUFiYiLmzp2La9euASjfKengwYPsRMaBAwdW2yaUlre3N3777TcMGTIEISEhyMnJwY0bNzBy5EgcOXIEO3bsEFsFtHLdzc3NMXjwYKSmpuL8+fOYM2cOJ4+Pjw8aNGiA3r174/z588jOzkZ8fDwmTpyIR48effV3IIQQUr2pU6di27ZtePz4MZtWU3/jt+r3dHd3x8GDB7Flyxbcv38fFy9exIQJE2BjYwM9PT0A5QM2RQMqi4uL8fjxY6SkpODu3btsOe/fv2fzAEB2djZSUlKQm5sLoHx16kmTJmHp0qU4dOgQO+5FRUUFAwcOrLGeqqqq2LFjB44fP45evXohJiYGOTk5uHbtGmbMmMFuZR8SEoJ+/fqJ9TP7+/vjzZs3OH78+BffK0II+WYYUmtCoZDR0NDgpG3evJkxNjZm5OXlGTMzM2bnzp2c40eOHGFMTEwYOTk5xtDQkC0HAAOA4fF4jIaGBmNjY8MsWrSIKSgoYBiGYT59+sTUr1+fCQ4OlliX1atXMw0aNGA+ffrE/Pnnn4yTkxOjra3NKCgoMAYGBoyfnx+Tk5PD5n/37h3j6+vLqKioMA0bNmSCg4MZBwcHZuLEiWyeyn8zDMOkpaUxurq6TM+ePZlPnz4xQ4YMYXr37l3lPerduzczZMiQau+jSEFBAQOA/c6EEFIZPSd+LtnZ2cyQIUOYhg0bMjwejwHAeHh4MIWFhWweBwcHNoZW/Li4uEh1jZycHKZv376Muro6o6KiwrRt25a5fPkywzAMs2DBAqZly5ac/JLiXsV4eejQIaZ9+/aMuro6o6qqynTo0IGJiYmR+jvTb5wQUhN6TkinZ8+eTI8ePSQeS05OZgAwycnJzMePH5lly5YxzZs3Z5SUlBgtLS3G3t6eCQ0NZUpKSthznjx5wowdO5YxNDRkFBQUmF9++YXp1asXExsbK1V9DA0NmbVr11Z5vGKbsPInLy+PYRjJMYhhGCY8PJxRUFBgcnNzpbqWhoYGIxQKa9XGFDE3N2dkZGSYhw8fiuX/2pjMMPT7JoTUjJ4T/13V9SFmZ2dXGQf37NnDMIzkfliGYZgHDx4wcnJyTGRkZI3XYRjJfZXVxfnaxsvY2FgGAPP69etq74ck9PsmhNSEnhP/vI8fPzK///4707p1a0ZDQ4NRUVFhzM3Nmblz5zJFRUUMw0h+7yepX5FhGObt27fM+PHjGT09PUZeXp7R19dnfHx82PZcdnY24+TkxCgrKzP6+vrMxo0bxd7VSWrzAWAOHTrE/i2KrdevX2fTSkpKmFWrVjFWVlaMoqIio66uzri4uDDnz5/nlFVV3TMzM5mOHTsyCgoKjJmZGRMdHS123by8PGbw4MFMgwYNGEVFRcbY2JgZPny41L9Z+o0TQmryszwnpGk/VXzGMwzDlJWVMebm5szo0aMZhpGuv5FhpOv3rBx7aup/ZBiGWb9+PWNpackoKyszjRo1Ynx8fJhHjx6JfY/KHwcHBzaPqH1V+VOxTVdWVsYsWLCA0dXVZRQVFZnOnTszN2/erLZulV29epXx8PBgtLW1GUVFRcbExIQZMWIEk5WVxVy7do0BwFy5ckXiue7u7oy7uzv7d1VxVBo/y++bEPLlavOc4DFMHa7BTP6THB0dYW1tjXXr1v0r13/79i00NDRQUFBAy14TQiSi58TPbcGCBVizZg1Onz5dpyuwfU/oN04IqQk9J8iPjH7fhJCa0HOC/Mjo900IqQk9J8iPjn7jhJCa0HOC/Mjo900IqUltnhPfxdbwOTk54PF47NLO/+S14uLiwOPx8ObNm29+7Zr4+fmhT58+7N+Ojo6YNGnSv1YfQggh5HuwcOFCrF+/HpcvX66TLZEIIYQQQgghhNQNIyOjf21yOSGEEEIIIYQQQggh5P/I1Sazn58f3rx5g8OHD3PS4+Li4OTkhNevX0NTU7MOq/ft2dnZIS8vDxoaGlLl9/PzQ1hYGABAVlYWenp6cHNzw9KlS1GvXr06rdvBgwchLy9fp2VK8vnzZ8TFxcHc3BwPHz5EgwYN0KdPHyxevFjq+1IX+m25C3kl/j92ve/Z8Ylm/3YVCCHkH5OYmIhOnTqhW7duiI6O5hwrLi7GunXrEB4ejqysLCxZsgTm5uYYNmwYfH192TiZn5+PoKAgHD9+HLm5uSgrK4OMjAzk5eUhKyvLltepUyecPHmyynosWbIESUlJ+PDhA0xNTeHn54dJkyZxyuDxeACApKQkdOjQgU3/9OkT9PT08OrVK8TGxsLR0bHW94JiIfkS9O8GQv4d4eHhGDlypMRjhoaGSEtL+6JyHz58iMDAQJw8eRIvXrxAo0aN0KdPH8yfPx/169cHUD5pMD4+XuzckSNHYuvWrV903e8BxcGfA8UtQr4f7u7u+PDhA2JiYsSOJSUlwc7ODsnJyWjduvW/ULu6k5qaiuXLl+PChQt48eIFjIyMMGrUKEycOJHNk5OTg8aNG4ude/LkSbi6uv4j9aQ4SKRBcZSQ/56K7xXl5OSgr68PDw8PLFy4EM+fP5cYf4D/63sMDQ3F0KFD2XQdHR3Y2Nhg+fLlsLKyEruOpHbhmDFjsGXLFgwZMgShoaFsesU+1cePH0NHRwfW1taYNGkSunbtyilj6dKlmDdvHoKCgvD7778DKJ8Q8uDBgyq/u4ODA+Li4qS6TwDFQvLlKD6SH0lNY3J27tyJUaNGITU1FSYmJuzxJ0+ewMrKCoGBgZg4cSLnGa2kpISGDRvCxsYGo0aNQpcuXdjzKreF1NXV0bRpU8yZMwfu7u5semhoKCZNmlTtAmvSxpXavI9TVFREZmYmDA0N2fQ+ffpAU1OTjWmVY62KigoKCwshJycHOTnukKiq+m29vb1RUFDAeYd48uRJ9OjRA3PnzsXixYvZ9MWLF2PLli148uQJAODAgQMIDg7G7du3UVZWBgMDA7i6umL16tVV3itJfsQ4SM9nQv55tRoI+m9hGAalpaViD+m6oKCgAF1d3Vqd4+rqCqFQiM+fPyM9PR3+/v548+YN9uzZU6d109LSqtPyqrJ161YsWLAAfn5+sLS0xIMHDzBq1Cg8efIE+/fv/+Jyi4uLoaCgUIc1JYQQ8iMSCAQYP348duzYgdzcXBgYGAAojyMuLi5ITU3F4sWLYW9vD3V1dVy6dAmrVq1Cq1atYG1tjZycHNjb20NTUxPBwcEwMDDAy5cvcf78eezduxenT59mr6WsrCyxDocOHYKnpyeGDh2K2NhYaGpqIiYmBjNmzMClS5cQFRXFDgAFAH19fQiFQs5A0EOHDoHP5+PVq1ff6E4RQgj5nvTq1Qvt27eXeOxLJ/Tdv38ftra2MDMzw549e9C4cWOkpaVh+vTpOHnyJC5dusS2E4cPH45FixZxzldRUfmi6xJCCPk5BQQEwMPDAw8ePOC8VAPK22nW1tb/+UGgAJCcnAxtbW3s3r0b+vr6SExMxIgRIyArK4tx48Zx8sbExHAG1XxN/+y37NMmhBDy3yJ6r1hSUoLz589j2LBhKCwsxMyZMwGIxx8A7ERAoHxQTmZmJhiGwePHjzFjxgy4ubnhzp07nPdw+vr62Lt3L9auXcv2g378+BF79uxh+1xFKveptmjRAiUlJTh16hTGjh2L27dvc/ILhULMmDEDAoGAHQh69epVlJaWAigf1NO3b19kZmay21XSO0JCCKl77u7uOHToEIYMGYLz589DRqZ8E+ARI0agVatWmDBhApt30aJFGD58OIqLi5GTk4Pdu3fD2dkZixcvxpw5czjlimLRmzdvsHnzZvTt2xd///03mjVrJlW9pI0rtX0fx+PxMH/+fHagZ1VEsba0tBT379/H4cOHsXXrVrRp0wbbtm1j22VV9ds6OTlh2rRp+Pz5M5s3Li4O+vr6iI2N5eQVDcoV3Tdvb28sXboUvXr1Ao/HQ3p6Os6ePSvVfSOEkLpWp1vDFxYWQl1dXWzw4NGjR6Gqqop3794BAK5cuYJWrVpBSUkJbdu2xfXr1zn5Rdu1nzp1Cm3btoWioiLOnz+Pe/fuoXfv3mjYsCH4fD7atWsnNmOdx+OJzY6oOBugMklbw1+8eBEODg5QUVFBvXr14OLigtevX7PHFRUVoauri19//RXdu3eHl5cXZ5BJaWkpAgIC0LhxYygrK8Pc3Bx//PEH57qlpaWYMmUKNDU1Ub9+fcyYMQMMw3DyVN4avqbvVlxcjHHjxqFRo0ZQUlKCkZERli1bJvF7V9SsWTMcOHAA7u7uaNKkCbp06YKgoCAcPXoUnz9/BgB06dJFrGP05cuXUFRUxLlz5wCUz/xbsmQJ/Pz8oKGhgeHDh9d4bUIIIT+3wsJCREVFYfTo0ejZsycnXq9btw4JCQk4e/Ysxo4dC2traxgbG2PgwIG4fPkyTE1NAZTPaOfxeLhy5Qr69esHGxsb/O9//8PSpUvx999/w8TEhP388ssvEuswfPhw9OrVC3/++Sesra1hZGSEYcOGISwsDPv370dUVBTnnCFDhmDv3r348OEDmyYQCDBkyJBvc6MIIYR8d9TU1DgxpuKn8mAaaY0dOxYKCgo4ffo0HBwcYGBggP/973+IiYnB48ePOR20Kioq0NXV5XxEL9tq8ujRI3h7e0NLSwuqqqpo27YtLl++DAAIDAyEtbU1BAIBDAwMwOfzMXr0aJSWliI4OBi6urrQ0dFBUFAQp8zAwEAYGBhAUVERenp6nE5nQggh36eePXtCR0dHrN+0qKgIkZGRCAgIwIEDB2BlZQVFRUUYGRlVu6JJTk4OeDweUlJS2LQ3b96Ax+Oxq4FV7Pdt1aoVlJWV0aVLFzx79gwnT55E06ZNoa6ujgEDBqCoqIgth2EYBAcHw9jYGMrKymjZsqXUE9j9/f2xfv16ODg4wNjYGL6+vhg6dCgOHjwolrd+/fqc2CoawJKTkwMZGRlcu3aNk3/Dhg0wNDQEwzBV9mkTQgghoveK+vr6GDhwIHx8fDjv+yrHH11dXc5AFR6PB11dXTRq1Aht27bF5MmT8eDBA2RmZnKu07p1axgYGHBi3MGDB6Gvr49WrVpx8lbuUzUzM4OVlRWmTJmCS5cucfLGx8fjw4cPWLRoEQoLC5GQkAAA0NbWZusrmjyho6MjlkYIIaRubdu2DXfv3sWaNWsAlK/Wef78eQiFQs4gSjU1Nejq6sLAwACdO3fGn3/+iXnz5mH+/PliMUQUiywsLBAUFISSkhKxAZDVkSaufMn7uPHjx2P37t24efNmtdcXxdpffvkFnTp1wurVq3H06FEkJCTgwoULNfbbOjk54f3795w2X1xcHH7//XdcvXqVbZ8WFxcjKSmJHQh67NgxdOzYEdOnT4e5uTnMzMzQp08fbNiwQep7RwghdalOB4KqqqrC29sbQqGQky4UCtGvXz+oqamhsLAQPXv2hLm5OZKTkxEYGIhp06ZJLG/GjBlYtmwZMjIy0KJFC7x//x49evRATEwMrl+/DhcXF7i7uyM3N7fOvkNKSgq6du0KKysrJCUl4cKFC3B3d2dntFV2//59REdHcxpkZWVl+PXXXxEVFYX09HTMnz8fs2fP5gSt1atXQyAQICQkBBcuXMCrV69w6NChr6r7+vXrceTIEURFRSEzMxO7d++GkZHRF5VVUFAAdXV1drbDsGHDEBERgU+fPrF5wsPDoaenxwY5AFi5ciWaNWuG5ORkzJs3T2LZnz59wtu3bzkfQgghP6fIyEiYm5vD3Nwcvr6+EAqF7MSI8PBwODs7i3VSAuUz9lRVVfHq1StER0dj7NixUFVVFcunqalZYx1Onz6Nly9fSvz3iLu7O7sqW0Vt2rRB48aNceDAAQDl2/gmJCRg0KBB0nxtioWEEELEvHr1CqdOncKYMWPEVrDW1dWFj48PIiMjxSYQ1tb79+/h4OCAJ0+e4MiRI0hNTcWMGTNQVlbG5rl37x5OnjyJ6Oho7NmzBwKBAG5ubnj06BHi4+OxYsUKzJ07l+3E3b9/P9auXYtt27YhKysLhw8fRvPmzausA8VBQgj5PsjJyWHw4MEIDQ3lxJd9+/ahuLgYtra28PT0hLe3N27evInAwEDMmzevygn3tREYGIiNGzciMTERDx8+hKenJ9atW4eIiAgcP34cZ86c4bw4mzt3LoRCIbZs2YK0tDRMnjwZvr6+iI+P/6LrFxQUSByc0qtXL+jo6MDe3p4z0NTIyAjOzs4S+739/Pw4L1sr92lXRnGQEEKIsrIySkpKvujcN2/eICIiAoDkVc2GDh3KiVcCgQD+/v6cPLXtUw0JCcGAAQMgLy+PAQMGICQk5IvqLkKxkBBCvo62tja2bduGefPm4cyZM5g8eTL++OMPqSanT5w4EQzD4K+//pJ4vKSkBNu3bwcg/a5H0saVL3kfZ2dnh549e2LWrFlS1aWiLl26oGXLlhInAVZmZmYGPT09dvDru3fv8Pfff6N///5o0qQJLl68CAC4dOkSPnz4wI6R0dXVRVpaGm7duiV1vSgOEkK+pVrvS3Ps2DHw+XxOWsVBksOGDYOdnR2ePHkCPT09vHjxAseOHcOZM2cAlA/qKC0thUAggIqKCqysrPDo0SOMHj1a7FqLFi1Ct27d2L/r16+Pli1bsn8vWbIEhw4dwpEjR8RWq/xSwcHBaNu2LTZv3symVd6OQXQPSktL8fHjRwBgZ1sA5QFx4cKF7N+NGzdGYmIioqKi4OnpCaB8lbNZs2ahb9++AMq3Zz916tRX1T03Nxempqbo2LEjeDzeF69C8/LlSyxevBgjR45k0/r27Yvx48fjr7/+Yr+DpI7OLl26VDmwV2TZsmWc+0MIIeTnFRISAl9fXwDl2za8f/8eZ8+ehbOzM7KysuDo6Fjt+Xfv3gXDMLCwsPjiOty5cwcA0LRpU4nHLSws2DwVDR06FAKBgB3A2qNHD2hra0t1TYqFhBBCKsvKygLDMFXGo6ZNm+L169d4/vw5AGDz5s3YsWMHJ8+mTZtqXJ06IiICz58/x9WrV9kBMCYmJpw8ZWVlEAgEUFNTg6WlJZycnJCZmYkTJ05ARkYG5ubmWLFiBeLi4tChQwfk5uZCV1cXzs7OkJeXh4GBAWxsbKqsA8VBQgj5fvj7+2PlypWcre0EAgE8PDywZs0adO3alZ3sbWZmhvT0dKxcuRJ+fn5fdd0lS5bA3t4eQPkW9bNmzcK9e/dgbGwMAOjXrx9iY2Mxc+ZMFBYWYs2aNTh37hxsbW0BAMbGxrhw4QK2bdsGBweHWl07KSkJUVFROH78OJvG5/OxZs0a2NvbQ0ZGBkeOHIGXlxfCwsLYNuuwYcMwatQorFmzBoqKikhNTUVKSorYS8XKfdqVURwkhJCf25UrVxAREYGuXbuyaXZ2duzWviIFBQWQlZVl/z+fzwfDMOyKZL169ZLYJzpo0CDMmjWLXan74sWL2Lt3L7s6N1C7PtW3b9/iwIEDSExMBAD4+vrC3t4eGzZskHpXisooFhJCSPVqGpMDAH369IGnpydcXV3Rs2dPqdtoWlpa0NHRQU5ODiddFIs+fPiAsrIyGBkZseNCaiJtXPnS93HLli1DixYtcP78eXTq1EmqOlUs88aNG1LldXR0RFxcHGbNmoXz58/DzMwM2tracHBwQFxcHLp168ZuF9+kSRMA5SuWnj9/Hs2bN4ehoSE6dOiA7t27w8fHB4qKihKvQ3GQEPIt1XpFUCcnJ6SkpHA+FV8+2djYwMrKCjt37gQA7Nq1i11qGgAyMjLQsmVLqKiosOeIOvAqa9u2LefvwsJCzJgxA5aWltDU1ASfz8ft27e/yYqg1RHdg8uXL2P8+PFwcXHB+PHjOXm2bt2Ktm3bQltbG3w+H9u3b2frWVBQgLy8PM73lpOTE/u+teXn54eUlBSYm5tjwoQJnO3qpfX27Vu4ubnB0tISCxYsYNMVFRXh6+sLgUAAoPw+paamiv2DQprvMGvWLBQUFLCfhw8f1rqehBBC/vsyMzNx5coVeHt7AyiPhV5eXmysYRiGM9lAEtGqNTXlk0ZVK6xVVQ9fX18kJSXh/v37CA0NFZtZXx2KhYQQQmpLFKdEW9T6+PiItc1/++23GstJSUlBq1atqt2iz8jICGpqauzfDRs2hKWlJefFZMOGDfHs2TMAQP/+/fHhwwcYGxtj+PDhOHToED5//lxl+RQHCSHk+2FhYQE7Ozu2HXbv3j2cP38e/v7+yMjIYAdritjb2yMrK6vK3ZOkVXGlzIYNG0JFRYUdBCpKE8WZ9PR0fPz4Ed26dQOfz2c/O3fuxL1792p13bS0NPTu3Rvz58/nDNZs0KABJk+eDBsbG7Rt2xaLFi3CmDFjEBwczObp06cP5OTk2F2dBAIBnJycxHZkqql/lOIgIYT8fEQDepSUlGBra4vOnTtzVr6OjIwUa9+JBoEC5Vv7pqSkIDk5GVu3bkWTJk2wdetWiddq0KAB3NzcEBYWBqFQCDc3NzRo0ICTpzZ9qhERETA2NmYX6rG2toaxsTH27t1b6/sgQrGQEEKqV9OYHJF58+ahrKysyp1aqyLpvVdkZCSuX7+OI0eOwMTEBDt27Ki2/7ByeYD07+pq+z7O0tISgwcPxsyZM6UqX5oyJXFycsLFixdRUlKCuLg4drEa0UBQoHy7+C5durDnqKqq4vjx47h79y7mzp0LPp+PqVOnwsbGhp28URnFQULIt1TrFUFVVVXFVgt59OgR5+9hw4Zh48aN+P333yEUCjF06FD24VqbbewqLxs9ffp0nDp1CqtWrYKJiQmUlZXRr18/FBcXs3l4PJ7YNWqzvULlLfiqqpfoHqxfvx5OTk5YuHAhFi9eDACIiorC5MmTsXr1atja2kJNTQ0rV67E5cuXpa6HJDV9t9atWyM7OxsnT55ETEwMPD094ezszNnGqDrv3r2Dq6sr+Hw+Dh06JLbU97Bhw2BtbY1Hjx5BIBCga9euYquOSlrquzJFRcUqZz8QQgj5eYSEhODz58/45Zdf2DSGYSAvL4/Xr1/DzMwMGRkZ1ZZhamoKHo+HjIwM9OnT54vqYWZmBqB8soqdnZ3Y8du3b8PS0lIsvX79+ujZsycCAgLw8eNH/O9//8O7d++kuibFQkIIIZWZmJiAx+MhPT1dYky7ffs2tLW12a2UNDQ0xNrm0pCmzVu5Lcjj8SSmibaT19fXR2ZmJs6cOYOYmBiMGTMGK1euRHx8vMQtpCgOEkLI9yUgIADjxo3Dpk2bIBQKYWhoiK5du0p8YVZd365owkDFPFX1y1aMDzXFGdH/Hj9+nNN+BFCreJKeno4uXbpg+PDhmDt3bo35O3TowHnZqqCggEGDBkEoFMLDwwMRERFYt26d2Hk19Y9SHCSEkJ+Pk5MTtmzZAnl5eejp6bFxT7Qam76+frXtOxkZGfa4hYUF8vPz4eXlhYSEBIn5/f392Z0UN23aJHa8Nn2qAoEAaWlpkJP7v1fKZWVlCAkJwYgRI6o9tyoUCwkhpHrSjMkBwD6bKz6ja/Ly5Us8f/4cjRs35qTr6+vD1NQUpqam4PP56Nu3L9LT06Gjo1NjmdLGlS99HwcACxcuhJmZGQ4fPlxjfSrKyMgQ+65VcXJyQmFhIa5evYrY2FhMnz4dQPlA0MGDB+PVq1dISkqSuCNTkyZN0KRJEwwbNgxz5syBmZkZIiMjMXToULG8FAcJId9SrVcElYavry9yc3Oxfv16pKWlcR6ElpaWSE1NxYcPH9i0S5cuSVXu+fPn4efnh99++w3NmzeHrq6u2JLV2trayMvLY//OysqqcqS9JC1atMDZs2elzg8ACxYswKpVq/DkyRO2nnZ2dhgzZgxatWoFExMTzux0DQ0NNGrUiPO9P3/+jOTk5GqvI813U1dXh5eXF7Zv347IyEgcOHAAr169qvE7vH37Ft27d4eCggKOHDkCJSUlsTzNmzdH27ZtsX37dkRERNRq5TNCCCGkos+fP2Pnzp1YvXo1Z0ZjamoqDA0NER4ejoEDByImJgbXr1+XeH5hYSG0tLTg4uKCTZs2obCwUCzfmzdvaqxL9+7doaWlhdWrV4sdO3LkCLKysjBgwACJ5/r7+yMuLg6DBw/mzNInhBBCaqt+/fro1q0bNm/ezGkvA0B+fj7Cw8O/ehteoLzNm5KSIlU7sTaUlZXRq1cvrF+/HnFxcUhKSsLNmzfr9BqEEEK+DU9PT8jKyiIiIgJhYWHspH5LS0tcuHCBkzcxMRFmZmYS2z/a2toAwOm/TElJ+er6WVpaQlFREbm5uTAxMeF89PX1pSojLS0NTk5OGDJkCIKCgqQ65/r162jUqBEnbdiwYYiJicHmzZtRUlICDw+PWn8fQgghPx/RgB5DQ0OJk+Vqa/LkyUhNTWVXqa7M1dUVxcXFKC4uhouLi9hxaftUb968iWvXriEuLo7Th5uQkICrV6/i1q1bX/1dCCGE/LP++OMPyMjIVDtg08HBAc2aNZO67SRtXPma93H6+voYN24cZs+eLfUOFefOncPNmzfRt29fqfI3adIE+vr6OHLkCFJSUuDg4AAAaNSoEYyMjLB69Wp8/PgRTk5O1ZZjZGQEFRUVifeCEEK+tVqvCCqNevXqwcPDA9OnT0f37t3x66+/sscGDhyIOXPmICAgAHPnzkVOTg5WrVolVbkmJiY4ePAg3N3dwePx2KWuK+rSpQs2btyIDh06oKysDDNnzqxVo2rWrFlo3rw5xowZg1GjRkFBQQGxsbHo37+/2NYJIo6OjrCyssLSpUuxceNGmJiYYOfOnTh16hQaN26MXbt24erVq5yZBhMnTsTy5cthamqKpk2bYs2aNTUOVqnpu61duxaNGjWCtbU1ZGRksG/fPujq6rIrxlTl3bt36N69O4qKirB79268ffsWb9++BVDegVuxY3fYsGEYN24cVFRUpNp2kBBCCJHk2LFjeP36NQICAqChocE51q9fP4SEhODSpUs4fvw4unbtisWLF6Njx45QU1PDtWvXsGLFCoSEhMDa2hqbN2+GnZ0dbGxssGjRIrRo0QKfP3/GmTNnsGXLlhpXFVVVVcW2bdvg7e2NESNGYNy4cVBXV8fZs2cxffp09OvXD56enhLPdXV1xfPnz6Gurl5n94YQQsjPa+PGjbCzs4OLiwuWLFmCxo0bIy0tDdOnT4eZmRnmz5/P5i0qKkJ+fj7nfEVFRdSrV6/aawwYMABLly5Fnz59sGzZMjRq1AjXr1+Hnp4ebG1tv6jeoaGhKC0tRfv27aGiooJdu3ZBWVlZbAcJQggh3yc+nw8vLy/Mnj0bBQUF7MSDqVOnol27dli8eDG8vLyQlJSEjRs3YvPmzRLLUVZWRocOHbB8+XIYGRnhxYsXUq28WRM1NTVMmzYNkydPRllZGTp27Ii3b98iMTERfD5f4mosFYkGgXbv3h1Tpkxh46esrCw7eDUsLAzy8vJo1aoVZGRkcPToUaxfvx4rVqzglNW0aVN06NABM2fOhL+/v1QrbRNCCCE1efnypVj7TlNTU+KiLUD5ojDDhg3DggUL0KdPH7EVvGVlZdk+0aomr0vTpxoSEgIbGxt07txZ7HxbW1uEhIRg7dq1X/KVCSGE/APevXuH/Px8lJSUIDs7G7t378aOHTuwbNmyGncamjp1Kvr3748ZM2awOzOUlpaKTfZTUFCApaWlVHHla97HAeVjebZv347s7Gx4eXlxjn369An5+fkoLS3F06dPER0djWXLlqFnz54YPHiw1PfMyckJmzdvhomJCRo2bMimOzg4YMOGDTA2NoaBgQGbHhgYiKKiIvTo0QOGhoZ48+YN1q9fj5KSEnTr1k3q6xJCSF35JgNBgfIthSStGsnn83H06FGMGjUKrVq1gqWlJVasWCHVKPy1a9fC398fdnZ2aNCgAWbOnMkOWBRZvXo1hg4dis6dO0NPTw9//PFHjSttVmRmZobTp09j9uzZsLGxgbKyMtq3b1/lzAORKVOmYOjQoZg5cyZGjRqFlJQUeHl5gcfjYcCAARgzZgxOnjzJ5p86dSry8vLg5+cHGRkZ+Pv747fffkNBQUGV16jpu/H5fKxYsQJZWVmQlZVFu3btcOLECXZbpqokJyez29ZXDvjZ2dkwMjJi/x4wYAAmTZqEgQMHVtkA/VL7R5vQQBpCCPlJhISEwNnZWWwQKAD07dsXS5cuRVpaGs6cOYO1a9di27ZtmDZtGlRUVNC0aVNMmDABzZo1AwA0btwYf//9N4KCgtj4qq2tjTZt2mDLli1S1adfv36IjY3F0qVL0blzZ3z48AEmJiaYM2cOJk2aJNaZKsLj8aqcKPIlKBYSQsjPzdTUFFevXkVgYCA8PT3x7NkzMAwDDw8P7Nq1CyoqKmze7du3Y/v27ZzzXVxcEB0dXe01FBQUcPr0aUydOhU9evTA58+fYWlpKXG7QGlpampi+fLlmDJlCkpLS9G8eXMcPXoU9evXr1U5FAcJIeTfExAQgJCQEHTv3p19qdW6dWtERUVh/vz5WLx4MRo1aoRFixZVu0K1QCCAv78/2rZtC3NzcwQHB6N79+5fXb/FixdDR0cHy5Ytw/3796GpqYnWrVtj9uzZNZ67b98+PH/+HOHh4QgPD2fTDQ0NObtNLVmyBA8ePICsrCzMzMwgEAjg6+srVl5AQAASExPrfLckioOEEPLzcnZ2Fkvbs2cPvL29qzxn4sSJWL9+Pfbt2ydx0ExNMaWmPtXi4mLs3r0bM2fOlHh+3759sWzZMqxYsQIKCgo1fEPpUCwkhJC6NX/+fMyfPx8KCgrQ1dVFhw4dcPbs2RpXtASAnj17wsjICEFBQexkwPfv36NVq1acfKJ2lbTv6r70fRxQvvLozJkzJbYDo6Oj0ahRI8jJyaFevXpo2bIl1q9fjyFDhtQ4XqYiJycn7Ny5E46Ojpx0BwcH7NixQyzmOjg4YNOmTRg8eDCePn2KevXqoVWrVjh9+jTMzc2lvi5AcZAQUjd4DMMw36Lg8PBwTJw4EU+ePKmzBgD59z18+BBGRka4evUqWrduXSdlvn37FhoaGigoKKDARgiRiJ4T5HvD4/Fw6NCharfOqA36jRNCakLPiZ/XggULsGbNGpw+ffqLV+z83tHvmxBSE3pOkO9JUFAQ9u7di5s3b9ZJefT7JoTUhJ4T3y8jIyNMmjQJkyZN+rer8p9Gv3FCSE3oOUF+ZPT7JoTUpDbPiTpfEbSoqAjZ2dlYtmwZRo4c+d0MAvXz80NYWJhYupOTE27cuIFJkyZJ3Kpo2bJlWL16NZ48eYKIiAhMmjSpxi3cgfKt8SrmDQ0NxdChQ8Xybd++HcOGDWOPW1hYiG1hGxUVBS8vL7FZ6lU5ePAgtmzZgpSUFHz69AlWVlYIDAyEi4sLJ9+BAwcwb9483Lt3D02aNEFQUBBnu/eEhASsXLkSycnJyMvLw59//onY2Fh06NABrVu3RklJCebOnYsTJ07g/v370NDQgLOzM5YvXw49Pb0a61lZvy13Ia/Er/V5/zXHJ5r921UghBCpPHv2DPPmzcPJkyfZWWwtW7ZEYGAgbG1t63ww5LdSWlqK9evXQygU4s6dO1BSUoKtrS3mzp0Le3v7f7t6HD9LLCRfh/4tQch/S8W2qJycHPT19eHh4YGFCxfi+fPnaNy4scTzkpKS0KFDBzRu3Bjv37+HnZ0dAEBHRwc2NjZYvnw5rKysxK4zcuRIbN26lVPWmDFjsGXLFgwZMgShoaFsen5+PoKCgnD8+HE8fvwYOjo6sLa2xqRJk9C1a1dOGUuXLsW8efMQFBSE33//HUD5S88HDx5U+d0dHBwQFxcn9b2iOPjjoFhFyJfz8/PDmzdvcPjwYU56XFwcuzLJqFGjkJqaytnZ58mTJ2wf4MSJEznPaCUlJTRs2BA2NjYYNWoUunTpwp4nWrlFRF1dHU2bNsWcOXPg7u7Oplfu65RE2riSmJiIJUuWICkpCR8+fICpqSn8/PwwadIkzva1PB4PioqKyMzMhKGhIZvep08faGpqsjGtcqzV0tJCixYtMGDAAHY3ppp4e3ujoKCAs6PTyZMn0aNHD8ydOxeLFy/G+/fvkZGRgeXLl3PqeeDAAQQHB+P27dsoKyuDgYEBXF1dsXr16hqvWxHFwZ8bxU5C/nnu7u748OEDYmJixI4lJSXBzs4OycnJdbYoyr9J0upqW7ZswahRo9i/b968iXHjxuHKlSvQ0tLCyJEjMW/evGpXZqtrFAsJQDGRkK+RmJiITp06oVu3bmK7BhUXF2PdunUIDw9HVlYWVFRUYG5ujmHDhsHX1xfy8vIAatdfKEnlSRIMw2DatGn4888/8ddff6FLly5wdHREfHy82LklJSWQkysfwjRixAiEhIQgPDxc4grZd+/eRVBQEM6cOYPnz59DT08PHTp0wNSpU3Hr1i2JY3Mqio2NFVv1s6LAwEAcPnwYKSkpnPQ3b96gXr167PmV29Samppo3rw5Fi9eDAcHh2rrUNn3FgfpeUzIf5P0ayBLKTg4GNbW1mjYsCFmzZpV18V/FVdXV+Tl5XE+Bw4cgK+vL0JDQyFpcVShUIhBgwbVyYBWdXV1sev7+Piwx1VVVfHs2TMkJSVxzhMIBOyWTNJISEhAt27dcOLECSQnJ0NbWxuurq5QUVEBn88Hn8+HiooK+vXrh5cvXyI1NRWDBg2Cp6cnu0U8ABQWFqJly5bYuHEjgPJgm5yczL5ULCoqwt9//4158+bh77//xsGDB3Hnzh306tXra24TIYSQ70Tfvn2RmpqKsLAw3LlzB0eOHIGjoyNevXoldRklJSXfsIY1YxgGdnZ2mDJlCu7cuQNZWVkUFxcjJiYGHTt2rDa+/tt1J4QQ8uMQtUXv37+PJUuWYPPmzZg2bRp7PCYmRqyt2KZNG/a4qC355MkTHD9+HIWFhXBzc0NxcTHnOvr6+ggNDWXbfaLPli1bwOPxOC84c3Jy0KZNG5w7dw7BwcG4efMmoqOj4eTkhLFjx4p9B6FQiBkzZkAgELBpV69e5bStASAzM5NNO3jwYJ3dQ0IIIeXc3d3h4uKCIUOGoKysjE0fMWIEWrVqhQkTJrBpixYtQl5eHjIzM7Fz505oamrC2dkZQUFBYuWKYtHly5dhY2ODvn374tatW1LXS9q4cujQITg4OODXX39FbGwsbt++jYkTJyIoKAje3t5i/bM8Hg/z58+v9tpJSUmQlZWFiooKFBQU8O7dOyQkJCAgIABGRkb4/PlzjfV3cnLChQsXOHnj4uKgr6+P2NhYAMC4cePQsWNHqKio4H//+x9737y9vdGvXz9cuXIFycnJCAoKEovRhBBCvj8BAQE4d+6cxMltAoEA1tbWP8QgUBGhUMhpcw4ZMoQ99vbtW3Tr1g16enq4evUqNmzYgFWrVmHNmjVffD2GYaSKwYQQQuqOQCDA+PHjceHCBeTm5rLpxcXFcHFxwfLlyzFixAgkJibiypUrGDt2LDZs2IC0tDQAte8vrElpaSkCAgKwc+dOnDt3jjMpcfjw4WL9oaJBoEVFRYiMjMT06dMREhIiVu61a9fQpk0b3LlzB9u2bUN6ejoOHToECwsLTJ06FV5eXpxybW1t4eTkBBUVFfbTs2dPtu+04mT7LyVqU8fHx0NdXR09evRAdnb2V5dLCCG1VecDQQMDA1FSUoKzZ8+Cz/9+RqsDgKKiInR1dTmfevXqISAgAPfu3UNCQgIn//nz55GVlYWAgIA6uT6PxxO7vrKyMntcTk4OAwcO5LxYe/ToEeLi4jBw4ECpr7Nu3TrMmDED7dq1g6mpKcLDw2FiYoLhw4cjJSUFKSkpcHR0RKdOnXDlyhVYWFhg1qxZ6Nq1K9atW8eW87///Q9LliyBh4cHgPKO2szMTDRv3hwAoKGhgTNnzsDT0xPm5ubo0KEDNmzYgOTkZM4/LAghhPz3vHnzBhcuXMCKFSvg5OQEQ0ND2NjYYNasWXBzc4ORkREA4LfffgOPx2P/DgwMhLW1NQQCAYyNjaGoqAiGYVBQUIARI0ZAR0cH6urq6NKlC1JTU9nr3bt3D71790bDhg3B5/PRrl07sdn4RkZGWLJkCQYPHgw+nw9DQ0P89ddfeP78OXr37g0+n4/mzZvj2rVr7DlRUVG4cuUKtm7dilu3biE1NRU3btxARkYGunfvjnfv3qGwsLDaumdlZaFz585QUlKCpaUlzpw5I3a/Hj9+DC8vL9SrVw/169dH7969pVrFmxBCyM9B1BbV19fHwIED4ePjw1nprX79+mJtRdEsfOD/2pKNGjVC27ZtMXnyZDx48ACZmZmc67Ru3RrGxsZYuHAh2/ZbtGgRzMzM0KVLF87W8mPGjAGPx8OVK1fQr18/mJmZwcrKClOmTMGlS5c45cbHx+PDhw9YtGgRCgsL2baztrY2W18tLS0A5SuWVk4jhBBSt7Zt24a7d++ygzNCQ0Nx/vx5CIVCzqpdampq0NXVhYGBATp37ow///wT8+bNw/z588ViiCgWWVhYICgoCCUlJewASGlIE1cKCwsxfPhw9OrVC3/++Sesra1hZGSEYcOGISwsDPv370dUVBSn3PHjx2P37t3VbsNubW0NR0dHpKamsm2+tLQ07Ny5Ew8fPuSshl0VJycnvH//ntOejIuLw++//46rV6+iqKgIoaGhePfuHd69e8euhHPs2DF07NgR06dPh7m5OczMzNCnTx9s2LBB6ntHCCHk39GzZ0/o6OiIxQnR4JOAgAAcOHAAVlZWUFRUhJGRUbWrPefk5IDH43FWDnvz5g14PB67U0JcXBx4PB5OnTqFVq1aQVlZGV26dMGzZ89w8uRJNG3aFOrq6hgwYACKiorYchiGQXBwMIyNjaGsrIyWLVti//79tfq+mpqaVb6fDA8Px8ePHxEaGopmzZrBw8MDs2fPxpo1a8AwDHJyciAjI8OJkwCwYcMGGBoagmEYzndr27YtFBUVcf78+VrVkRBCyJcrLCxEVFQURo8ejZ49e3Li27p165CQkICzZ89i7NixsLa2hrGxMQYOHIjLly/D1NQUQO36C2vy6dMn9O/fH2fOnEFCQgLatWvHOa6ioiLWHyqyb98+WFpaYtasWbh48SLnfRvDMPDz84OpqSnOnz8PNzc3NGnSBNbW1liwYAH++usvKCsrc8pVUFCAhYUF22ZMTU1l+05TUlJw4sSJ2t/wSkRt6hYtWmDbtm0oKirC6dOnv7pcQgiprTofCPpf1Lx5c7Rr1w5CoZCTLhAIYGNjg2bNmv1jdQkICEBkZCTbwAsNDYWrqysaNmz4xWWqqqri06dPMDU1hYmJCUxMTHDr1i389ttvnG2VXFxckJiY+FX1LygoAI/Hg6am5leVQwgh5N8lmgV3+PBhfPr0Sez41atXAfzfTHLR30D5dgxRUVE4cOAA2/Hp5uaG/Px8drXq1q1bo2vXruzqou/fv0ePHj0QExOD69evw8XFBe7u7mITC9auXQt7e3tcv34dbm5uGDRoEAYPHgxfX1/8/fffMDExweDBg9lVZCIiImBmZoaRI0eyMVD0WbBgAd68ecMZ2Fm57mVlZfDw8ICsrCwuXbqErVu3YubMmZw6FRUVwcnJCXw+HwkJCbhw4QL4fD5cXV1pFRhCCCESKSsrf/HK02/evEFERAQAcAaLigwfPhwnT55k492JEycwevRo8Pl8qKqqAgBevXqF6OhojB07lk2rqHJ7LiQkBAMGDIC8vDwGDBggcSY+IYSQf462tja2bduGefPm4cyZM5g8eTL++OMPTj9fVSZOnAiGYfDXX39JPF5SUoLt27cDkBxnJJE2rpw+fRovX77krIot4u7uDjMzM+zZs4eTbmdnh549e1a785SysjL4fL5Ym2/QoEFo2bKlVCtUm5mZQU9Pjx38+u7dO/z999/o378/mjRpgosXLwIALl26hA8fPsDJyQkAoKuri7S0tFqtnkoIIeT7ICcnh8GDB4vtGLhv3z4UFxfD1tYWnp6e8Pb2xs2bNxEYGIh58+ZJNcGgJoGBgdi4cSMSExPx8OFDeHp6Yt26dYiIiMDx48dx5swZzqSCuXPnQigUYsuWLUhLS8PkyZPh6+srcVvdqowbNw4NGjRAu3btsHXrVs7K4klJSXBwcICioiKb5uLigidPniAnJwdGRkZwdnYWe48qFArh5+fHmYgyY8YMLFu2DBkZGWjRosWX3B5CCCFfIDIyEubm5jA3N4evry+EQiEb38LDw+Hs7IxWrVqJnScvLw9VVdVa9xdW5/3793Bzc0NaWhouXryIpk2b1uq7hISEwNfXFxoaGujRowcn/qSkpCAtLQ1Tp06FjIz4cKeq6qmgoCDWZhR9pGlL14aKigoA2nmQEPLv+KkGgh47dkxsi7zFixcDAPz9/bF//368f/8eQHlw2rdvX52tBgqUD5KseO2KsxpErK2t0aRJE+zfvx8MwyA0NBT+/v5fdd3Vq1ejsLAQnp6ebFp+fr7Y4NKGDRsiPz//i6/z8eNH/P777xg4cCDU1dWrzPfp0ye8ffuW8yGEEPJ9kZOTQ2hoKMLCwqCpqQl7e3vMnj0bN27cAFD+4hH4v5nkor+B8i0mdu3ahVatWqFFixaIjY3FzZs3sW/fPrRt2xampqZYtWoVNDU12ZnrLVu2xMiRI9G8eXOYmppiyZIlMDY2xpEjRzj16tGjB0aOHAlTU1PMnz8f7969Q7t27dC/f3+YmZlh5syZyMjIwNOnTwEAd+7cqbKBKUq/c+dOlXU/e/YsMjIysGvXLlhbW6Nz585YunQpp5y9e/dCRkYGO3bsQPPmzdG0aVMIhULk5uays/0ro1hICCE/rytXriAiIoJdSQwoH+RSua1aWlrKHhe1JVVVVVGvXj3s3bsXvXr1goWFhVj5gwYNwoULF5CTk4MHDx7g4sWL8PX15eS5e/cuGIaReH5lb9++xYEDB9gyfH19sX///q+KXRQHCSGkepL6MEVbkYv06dMHnp6ecHV1RefOneHn5ydV2VpaWtDR0RHbwUAUi5SUlDB16lQYGRlx+hKrI21cEbW9qmqjWVhYcNpnIsuWLUN0dPQXrSpmYWEh9W4Njo6ObBvu/PnzMDMzg7a2NhwcHDgruenr66NJkyYAylcsbdeuHZo3bw4jIyN4e3tDIBBInFApQnGQEEK+H/7+/sjJyeH04QkEAnh4eGDNmjXo2rUr5s2bBzMzM/j5+WHcuHFYuXLlV193yZIlsLe3R6tWrRAQEID4+Hhs2bIFrVq1QqdOndCvXz92ckJhYSHWrFkDgUAAFxcXGBsbw8/PD76+vti2bZtU11u8eDH27duHmJgYeHt7Y+rUqZw+zqreGYqOAcCwYcOwZ88eNsaJVlMbOnQo57xFixahW7duaNKkCerXry+xPhQLCSGk7okGTwKAq6sr3r9/j7NnzwIAsrKyamyv1aa/sCaLFy9GSkoKzp8/DwMDA4l5Nm/ezGnzTp06la3rpUuX4OXlBQDsoFbRBIasrCwAqJN6fguFhYWYNWsWZGVl4eDgIDEPxUFCyLf0Uw0EdXJy4izxnJKSgrFjxwIABgwYgLKyMkRGRgIonzHBMAy8vb3r7Ppqamqca1e1+qa/vz+EQiHi4+PZFdK+1J49exAYGIjIyEjo6OhwjlWcoQeUL6NdOU1aJSUl8Pb2RllZGTZv3lxt3mXLlkFDQ4P96Ovrf9E1CSGEfFt9+/bFkydPcOTIEbi4uCAuLg6tW7eucda7oaEhZ2BocnIy3r9/j/r163MaddnZ2bh37x6A8obRjBkzYGlpCU1NTfD5fNy+fVtsRdCKs8hFnZHNmzcXS3v27JnU37Ni7Ktc94yMDBgYGODXX39l0ypuqyv6fnfv3oWamhr73bS0tPDx40f2+1VGsZAQQn4uogE9SkpKsLW1RefOnTmru0RGRoq1VWVlZdnjorZkcnIytm7diiZNmmDr1q0Sr9WgQQO4ubkhLCwMQqEQbm5uaNCgASePaDUAadp/ERERMDY2RsuWLQGA3Tpq7969tb4PIhQHCSGkepL6MHfs2CGWb968eSgrK8O8efNqVb6kPsDIyEhcv34dR44cgYmJCXbs2AEtLS2pywOkiysV80tTLwCwtLTE4MGDxXZnkPZa0tbLyckJFy9eRElJCeLi4uDo6AgAYgNBu3Tpwp6jqqqK48eP4+7du5g7dy77AtPGxoazpW9FFAcJIeT7YWFhATs7OwgEAgDAvXv3cP78efj7+yMjIwP29vac/Pb29sjKyuJM3PsSlfs4VVRUYGxszEkT9W+mp6fj48eP6NatG6dvdefOnVX2PVY2d+5c2NrawtraGlOnTsWiRYvEBrRKemdYMb1Pnz6Qk5PDoUOHAJQPmHVycoKRkRHnvLZt29ZYH4qFhBBStzIzM3HlyhV2bIucnBy8vLzY+CZNu6i27brqdO/eHYWFhWILq1Tk4+PDafOKdoEICQmBi4sL25/Zo0cPFBYWIiYmps7rWZdEkyvV1NRw9OhRhIaGct5fVkRxkBDyLcn92xX4J6mqqsLExETiMQ0NDfTr1w9CoRABAQEQCoXo169ftStb1paMjEyV16/Ix8cHM2bMQGBgIAYPHgw5uS/7zxQZGYmAgADs27cPzs7OnGO6urpiq38+e/bsi7agLykpgaenJ7Kzs3Hu3Lka79msWbMwZcoU9u+3b99ScCOEkO+UkpISunXrhm7dumH+/PkYNmwYFixYUO1qM5W3jCgrK0OjRo0kro4p2qJh+vTpOHXqFFatWgUTExMoKyujX79+YlurV9yaUNTIk5QmmhloZmaG9PR0ifXMyMgAAJiamlZZd0kvKCs3LsvKytCmTRuEh4eL5a04qLQiioWEEPJzcXJywpYtWyAvLw89PT02dolWKNPX16+2rVixLWlhYYH8/Hx4eXkhISFBYn5/f3+MGzcOALBp0yax46ampuDxeMjIyECfPn2qrbtAIEBaWhqnXVpWVoaQkBCMGDGi2nOrQnGQEEKqJ6kP89GjR2L5RM/m2vQdvnz5Es+fP0fjxo056fr6+jA1NYWpqSn4fD769u2L9PR0sYnlkkgbV8zMzACUt8Xs7OzEjt++fRuWlpYSz124cCHMzMxw+PDhGutTUUZGhth3rYqTkxMKCwtx9epVxMbGYvr06QDKB4IOHjwYr169QlJSEoYMGSJ2bpMmTdCkSRMMGzYMc+bMgZmZGSIjI8VWSQMoDhJCyPcmICAA48aNw6ZNmyAUCmFoaIiuXbtKHDRT1WQGAOz2tBXzVLUlbOX+zIp/i9JE/Zui/z1+/Dh++eUXTr6KW7nXRocOHfD27Vs8ffoUDRs2rPKdIfB/E+8VFBQwaNAgCIVCeHh4ICIiAuvWrRMrW9J2wpVRLCSEkLoVEhKCz58/c+IEwzCQl5fH69evYWZmxr4Tq0pt+gtr0rVrV0yYMAG9e/dGaWkpZ0K8iIaGhli7t7S0FDt37kR+fj6nnVtaWoqQkBB0796d0660trb+qnpWR11dHQUFBWLpb968YetfUWRkJLvYTVUrYotQHCSEfEs/1YqgNQkICMDFixdx7NgxXLx4sU63ha8NLS0t9OrVC/Hx8V+8LfyePXvg5+eHiIgIuLm5iR23tbXFmTNnOGmnT5+W2AlbHdEg0KysLMTExNQY1IDyhqm6ujrnQwgh5L/B0tIShYWFAMo7LKWZ/d66dWu20WZiYsL5iGb0nT9/Hn5+fvjtt9/QvHlz6OrqSr19X3W8vb2RlZWFo0ePih1bvXo16tevj27dulV5vqWlJXJzc/HkyRM2LSkpSez7ZWVlQUdHR+z7VW4IilAsJISQn4toQI+hoaHYC74vMXnyZKSmprIrsVTm6uqK4uJiFBcXw8XFRey4lpYWXFxcsGnTJjauVyTq0Lx58yauXbuGuLg4zgz9hIQEXL16Fbdu3fqi+lMcJISQf88ff/wBGRmZal/sOTg4oFmzZggKCpKqTGnjSvfu3aGlpYXVq1eL5Tly5AiysrIwYMAAidfQ19fHuHHjMHv2bKlXYTt37hxu3ryJvn37SpW/SZMm0NfXx5EjR5CSksJu49eoUSMYGRlh9erV+PjxI5ycnKotx8jICCoqKhLvBUBxkBBCvjeenp6QlZVFREQEwsLCMHToUPB4PFhaWuLChQucvImJiTAzM+Ps4CAimhCel5fHpqWkpHx1/SwtLaGoqIjc3FyxvscvHTRy/fp1KCkpsZP0bW1tkZCQwJmUf/r0aejp6XFW/Bw2bBhiYmKwefNmlJSUwMPD44uuT7GQEELqzufPn7Fz506sXr2a03+XmpoKQ0NDhIeHY+DAgYiJicH169clnl9YWCh1u05a3bp1w7FjxyAQCDB27NhqJ1OInDhxAu/evcP169c532Xfvn04fPgwXr58CWtra1haWmL16tXsZImvqWdVLCws8OjRI7GJElevXpW4AJy+vj6aNGlC42UIIf+6n2og6KdPn5Cfn8/5vHjxgj3u4OAAExMTDB48GCYmJujcufO/VtfQ0FC8ePECFhYWtT53z549GDx4MFavXo0OHTqw37XijIWJEyfi9OnTWLFiBW7fvo0VK1YgJiYGkyZNYvO8f/+eDa4AkJ2djZSUFHab3s+fP6Nfv364du0awsPDUVpayl6r8gpuhBBC/ltevnyJLl26YPfu3bhx4ways7Oxb98+BAcHo3fv3gDKX26dPXsW+fn5eP36dZVlOTs7w9bWFn369MGpU6eQk5ODxMREzJ07F9euXQMAmJiY4ODBg2zjdODAgRIbcLXl7e2N3377DUOGDEFISAhycnJw48YNjBw5EkeOHMGOHTuqnaXu7OwMc3NzDB48GKmpqTh//jzmzJnDyePj44MGDRqgd+/eOH/+PLKzsxEfH4+JEydKXLWHEEIIqezly5dibdWPHz9WmV9dXZ1dpVtSJ6qsrCwyMjKQkZEh8QUlAGzevBmlpaWwsbHBgQMHkJWVhYyMDKxfvx62trYAylcTsLGxQefOndGsWTP207FjR9ja2iIkJKRubgAhhJBv4t27d8jPz8fDhw+RkJCAESNGYMmSJQgKCqpx16KpU6di27ZtePz4MZtWWloqtmW9aAcGaeKKqqoqtm3bhr/++gsjRozAjRs3kJOTg5CQEPj5+aFfv37w9PSssk6zZs3CkydP2C0BKxL1+z5+/Bh///03li5dit69e6Nnz54YPHiw1PfMyckJmzdvhomJCWfnJAcHB2zYsAHGxsYwMDBg0wMDAzFjxgzExcUhOzsb169f/G++VQABAABJREFUh7+/P0pKSqqddEgIIeT7wefz4eXlhdmzZ+PJkyfsTkhTp07F2bNnsXjxYty5cwdhYWHYuHEjpk2bJrEcZWVldOjQAcuXL0d6ejoSEhIwd+7cr66fmpoapk2bhsmTJyMsLAz37t3D9evXsWnTJoSFhdV4/tGjR7F9+3bcunUL9+7dw44dOzBnzhyMGDGCXVF04MCBUFRUhJ+fH27duoVDhw5h6dKlmDJlCmdV1KZNm6JDhw6YOXMmBgwYAGVl5a/+foQQQr7OsWPH8Pr1awQEBHD675o1a4Z+/fohJCQEkyZNgr29Pbp27YpNmzYhNTUV9+/fR1RUFNq3b4+srCwA0rXraqNLly44fvw4wsLCpBoMGhISAjc3N7Rs2ZLzPfr27QttbW3s3r0bPB4PQqEQd+7cQefOnXHixAncv38fN27cQFBQEPsO82t1794dTZs2hbe3Ny5evIjs7Gz89ddfmDZtGkaNGgU1NbU6uQ4hhNQ55icxZMgQBoDYx9zcnJNv6dKlDABm6dKlYmUIhUJGQ0NDquuFhIQw9evXl/rcmo6vXbuWMTQ0lOraDg4OEr/rkCFDOPn27dvHmJubM/Ly8oyFhQVz4MABzvHY2Nhqy8nOzpZ4HAATGxsrVV0ZhmEKCgoYAExBQYHU5xBCfi70nPjnffz4kfn999+Z1q1bMxoaGoyKigpjbm7OzJ07lykqKmIYhmGOHDnCmJiYMHJycmyMWrBgAdOyZUux8t6+fcuMHz+e0dPTY+Tl5Rl9fX3Gx8eHyc3NZRimPKY4OTkxysrKjL6+PrNx40bGwcGBmThxIluGoaEhs3btWk65AJhDhw6xf4ti0/Xr19m0kpISZtWqVYyVlRWjqKjIqKurMy4uLsz58+c5ZVVV98zMTKZjx46MgoICY2ZmxkRHR4tdNy8vjxk8eDDToEEDRlFRkTE2NmaGDx8u9W+WfuOEkJrQc+K/a8iQIUzv3r0lHquuTbVnzx6GYapuKz548ICRk5NjIiMja7wOwzBM7969xdqET548YcaOHcsYGhoyCgoKzC+//ML06tWLiY2NZT59+sTUr1+fCQ4Ollje6tWrmQYNGjCfPn1iGOb/2o+vX7+u9n5IQr9vQkhNfqbnRFXPc0nPWUntHxFDQ0M2pigoKDAGBgaMp6cnc+7cOU6+qsooKytjzM3NmdGjRzMMUx6PJMWriv2V1cWVihISEhhXV1dGQ0ODUVBQYCwtLZlVq1Yxnz9/5uSr3O5imP/ru60Y0yr2+8rJyTHa2tqMs7MzIxAImNLSUrF7Ux3R9xw1ahQnfdeuXQwAJiAggJN+7tw5pm/fvoy+vj6joKDANGzYkHF1dRVrb1bnZ/p9E0K+DD0nvr3ExEQGANO9e3dO+v79+xlLS0tGXl6eMTAwYFauXMk5Xrm/Mj09nenQoQOjrKzMWFtbM6dPn+a8M5MUzyW1+Sr3U5aVlTF//PEH+05PW1ubcXFxYeLj42v8bidPnmSsra0ZPp/PqKioMM2aNWPWrVvHlJSUcPLduHGD6dSpE6OoqMjo6uoygYGBTFlZmVh5ISEhDADmypUrnHRqExJCviV6TlStZ8+eTI8ePSQeS05OZgAwycnJzMePH5lly5YxzZs3Z5SUlBgtLS3G3t6eCQ0N5cQEadt1VZH0Li8+Pp7h8/nMyJEjmbKyMrH3fwzDMPn5+YycnBwTFRUlsdzx48czzZs3Z//OzMxkBg8ezOjp6TEKCgqMoaEhM2DAAObvv/8WO1fS9aSRl5fHDB06lDE0NGSUlZUZCwsLZtGiRczHjx/ZPNW1y6VFv29CSE1q85zgMYwUazCTWlu+fDl27979xVvl/Uzevn0LDQ0NFBQU0LLXhBCJ6DlBfnT0GyeE1ISeE+RHRr9vQkhN6DlBfmT0+yaE1ISeE+R7EhQUhL179+LmzZt1Vib9xgkhNaHnBPmR0e+bEFKT2jwn5P6hOv00ioqKcPv2bQiFQvzvf//7t6vzn9Jvy13IK/H/7Wp8leMTzf7tKhBCCPkP+xFiIakb9G8KQsjPiOLg94viEiGEfHsUB388FD8JIT+S9+/fIyMjAxs2bMDixYu/yTUoFv73UKwjhJC682/FQXqWE/Jjkfm3K1AVPz8/9OnTRyw9Li4OPB4Pu3btgqqqKu7evcs5/uTJE9SrVw9//PEHAMDIyAg8Hg88Hg/KysowMjKCp6cnzp07xzkvJyeHzcfj8aChoYEOHTrg6NGjnHyhoaHQ1NSElZUV+Hy+2EdHRwdt2rRBWVkZDh06BEVFRejr68Pd3R1nz57llJWYmIgePXqgXr16UFJSQvPmzbF69WqUlpZy8vF4PCgpKeHBgwcAwF5bTk4O8vLy7LXl5eXZ+svLy6Nhw4bo1q0bBAIBysrKxO7l9evX0b9/fzRs2BBKSkowMzPD8OHDcefOHbG83bt3h6ysLC5duiTxfkn6BAYGSvgvSwgh5L+opme+n59fjecfPnyYkxYaGsqeLysri3r16qF9+/ZYtGgRCgoKJJazdOlSyMrKYvny5WLHSktLsWzZMlhYWEBZWRlaWlro0KEDhEJhrb6ro6MjJk2axEn7448/oKioiIiICADl/07h8XgYNWqU2PljxoyR6p4QQgj59yQmJkJWVhaurq5ix4qLixEcHIyWLVtCRUUFDRo0gL29PYRCIUpKSth8+fn5GD9+PIyNjatt99WkqtjWqFEjrFixgpM2c+ZM8Hg8sWt07doVAwcOrPV3qOpePH36FPLy8ti9e7fEOo8cORItWrQAAAQGBkr8t4GFhUWt7gMhhJC68z3Eucp9shYWFli5ciUkbU4VFhYGGxsbqKqqQk1NDZ07d8axY8fE8jEMgz///BPt27cHn8+HpqYm2rZti3Xr1qGoqAhAeVyytrbmnHf+/HmoqKhAQUEBfD4fSkpKnJglKytbZVtU1Par/Kl4byt+VxUVFTRr1gzbtm2T6j4RQgj5/kgbAyW15SrGBEkfR0fHGq9//fp19OzZEzo6OlBSUoKRkRG8vLzw4sULAP/3fi4lJQUA4OPjw8YgSe8Lq/qIREREQFZWltPPmZycDB6PhwsXLrBp48aNQ8eOHeHg4IB9+/ahV69eAKSLlYQQQr5cxeesvLw8jI2NMW3aNBQWFtZqjIukZ7WSkhInX00xMDw8HDIyMlBUVGRjjoyMTI3tofDwcLYN2qhRIwwdOhQvX75kj6elpaFv375sHF23bp3YfUhISIC7uzv09PQkvnMEytuMgYGB0NPTg7KyMhwdHZGWlibxvlYe7yMvLw85OTnw+XyEh4cDAE6ePAkej4d58+Zxzl28eDH09PTYvw8cOID27dtDQ0MDampqsLKywtSpUyVelxBCvrXvdiBoTdzd3eHi4oIhQ4ZwBjmOGDECrVq1woQJE9i0RYsWIS8vD5mZmdi5cyc0NTXh7OyMoKAgsXJjYmKQl5eHy5cvw8bGBn379pW4vfuJEyeQkpIi9jl27Bh0dXWhoKCA1atX4+bNm4iOjoaTkxPGjh3Lnn/o0CE4ODjg119/RWxsLG7fvo2JEyciKCgI3t7eYp2iPB4P8+fP51zb0dER7u7u7LXd3d3h7OyMvLw85OTk4OTJk3BycsLEiRPRs2dPfP78mS3v2LFj6NChAz59+oTw8HBkZGRg165d0NDQEAtkubm5SEpKwrhx4xASEgIA0NfXR15eHvuZOnUqrKysOGnTpk2rzX9SQggh37GKz/d169ZBXV2dkyaagFFbonIePXqExMREjBgxAjt37oS1tTWePHkill8oFGLGjBkQCARixwIDA7Fu3TosXrwY6enpiI2NxfDhw/H69esvqpvIggULMGvWLBw6dIgzyEZfXx979+7Fhw8f2LSPHz9iz549MDAw+KprEkII+bYEAgHGjx+PCxcuIDc3l00vLi6Gi4sLli9fjhEjRiAxMRFXrlzB2LFjsWHDBrbjMCcnB23atMG5c+cQHBxcZbtPGlXFNkdHR8TGxnLS4uLioK+vz0kvLi5GUlISnJycavUdqrsXDRs2hJubm8TJFB8+fMDevXsREBDAplVuC+bl5XFeGBJCCPlnfS9xTtQnm5GRgWnTpmH27Nn4888/OXmmTZuGkSNHwtPTE6mpqbhy5Qo6deqE3r17Y+PGjZy8gwYNwqRJk9C7d2/ExsYiJSUF8+bNw19//YXTp09LrMPx48fh4uKCCRMmID09HSkpKVi4cCH4fD4SExNx8eJFnDp1qtq2qKurq1ic27Nnj8TveuPGDfTp0wejRo1CZGSk1PeKEELI96E2MVBSW+7q1atsrDhw4AAAIDMzk007ePBgtdd/9uwZnJ2d0aBBA5w6dQoZGRkQCARo1KgRO+mhssmTJwMA9u7dy74vvHLlChITE3Hz5k3k5eWx9a0Yy0QEAgFmzJiBvXv3stdo06YNWrZsyWkThoaG4tOnT1i1ahXOnj3LaRNKEysJIYR8OdFz9v79+1iyZAk2b97MGYshzRiXyu/18vLy2IXIAOliYK9evf4fe3ceT1X+/wH8RZbssl5KxEUpqaYUmmQiCtW3KIUw0qbSRvsybRpDadXMZKtICxptahRRFBmaFpWKVqppIZT18/vD456f415cLdMyn+fjcR+P7ud8zjmfc7qP8/b5nM8CDQ0NLFy4kIk5Ghoa8PPzQ3Z2tsD60Pnz5zF58mR4e3vj+vXrOHToEHJycjBlyhTm3FVVVdDV1cXGjRvB4XAE3oPKykqYmJjw1RObCgoKwqZNm7B9+3bk5OSAw+HAxsYGb9684cvbvL/PypUrISkpicuXLzODHQS1xfLSeW2xKSkpcHFxgZOTE7Kzs5Gbm4v169ejpqamxXJSFEV9Sl/10vC//vorevXqhU2bNmHhwoWIiopCRkYG/v77b9ZoNjk5OSZgdO3aFUOGDIGGhgZWrlwJJycnGBoaMnmVlZXB4XDA4XCwfv16bNu2DampqejVqxfr3Nra2gLLNGfOHHTo0AHZ2dmQkZFh0nv27Ikff/wRQGOQ8vHxwahRo1iNn1OmTIG6ujpGjRqFgwcPYsKECcy22bNnIyQkBAsXLoSxsTEAQFZWFvLy8uByuQAag3dDQwNzrZ07d0a/fv0waNAgDBs2DFFRUZgyZQqqqqrg5eWFkSNHIjExkTlHt27dMHDgQLx+/Zp1TZGRkXBwcMCMGTNgamqK0NBQyMjIsIIwb4bSlgIzRVEU9XVr+nxXUFCAiIgIKy0sLAzBwcF4+PAhunXrhuXLl8Pd3R1A40h4APjf//4HoDGGFhcXAwDrOBoaGujRowccHR3Rs2dPBAQEsGYiO3fuHN6+fYs1a9Zgz549SE9Px5AhQ5jtR48excyZM+Hs7MykmZiYsK6jsrISM2bMQEJCAuTk5LBw4UIcPXoUffr04RthSAjBnDlzsHfvXpw+fRqDBw9mbe/Xrx/u3buHhIQEuLq6AgASEhKgpaUFXV1doe8tRVEU9e+qrKzEwYMHkZOTg9LSUkRFRTGD7kJDQ5Geno7Lly+jb9++zD66urpwdnZmGvB4sz+3Vu8TRmuxzcrKCgsWLEBdXR3ExMTw5s0b5OXlITQ0lJmhGgAuXbqEt2/fMo2Pwl5DW/fC29sbo0ePRnFxMRPLAeDw4cN49+4d3NzcmDRaF6QoivpyfElxrmmb7JQpUxAWFobTp09j2rRpAICLFy8iJCQEW7duxezZs5n91q9fj3fv3mH+/PkYPXo0tLS0cPDgQcTExODIkSMYPXo0k1dHRwejRo1CeXk53/ljY2Ph5eWFX375hTVpgLq6Ojp06AAzMzNW/pbqopKSkm3GuabXum7dOhw8eBBHjhxhte9SFEVRXz5hY2BLdTlVVVUmj5KSEgBATU0NioqKQp0/MzMT5eXl2L17N8TEGl/hduvWDT/88EOL+6ioqABofP/Je18oiKKiIl88Ky4uRmZmJuLj45GamorDhw9j8uTJABrrhEuXLsXWrVtZ9yIqKgqqqqqwt7dn0oSJlRRFUdT7a/qcnTRpElJTU3HkyBEsWrQIgHB9XJq/12tOmBgoJycHcXFxqKqqMjFHXFwcOjo6GDBgAAD++tDFixeho6PD1Mm6deuGadOmISgoiDnHgAEDmP0XL14ssHwjRozAiBEjWiw/IQShoaFYtmwZxo4dC6Bx9Ql1dXXExsYy9VCe5v19JkyYgJUrV+L169fMSkdpaWlYvHgx5s2bh6qqKkhLSzOD8rdu3QqgcQK2wYMHw9/fnzmWgYGBwNWPKYqi/g1f7YygAKCqqopff/0VK1aswJ9//ol58+Zhy5YtLXbSbMrPzw+EEPzxxx8Ct9fW1uL3338H0Bi8hPHy5UskJyfD19eXFRx5eBW906dP48WLFwJnzHR0dISBgQHfSDlzc3M4ODhgyZIlQpWlqR9++AEmJibMSMNTp07hn3/+QUBAgMD8TSukhBBERkbCzc0N3bt3h4GBAQ4ePNjuMjRVXV2N8vJy1oeiKIr6eiUmJsLPzw8LFizAtWvXMG3aNHh5eTEj5HJycgD8/6hz3veWqKmpwdXVFUlJSaivr2fSw8PDMXHiRIiLi2PixInMLNU8HA4HZ8+exfPnz1s8tr+/P1JTU5GYmIjTp08jLS0Nubm5fPnq6urg7u6OQ4cO4dy5c3ydQHm8vLxYI+MjIiKEejFKYyFFUdTnc+DAARgaGsLQ0BBubm6IjIxkVmSIiYmBtbU1q3MMj7i4OGRkZISu9wmjtdhmZWWFiooKJm5mZGTAwMAATk5OyMnJYWZqSU1NRZcuXZjGV2GuQZh7MXLkSHA4HERFRbGOERERgTFjxkBZWVno62yOxkGKoqhP50uKczyEEKSlpaGgoIDVzrp//37IysryvZADgAULFqC2tpaZTS0mJgaGhoasTqA8vCUQm9qxYwe8vLwQHh7O6gTampbqou+jY8eOqK2tFbiNxkGKoqgvU3tiYFvtlO+Lw+Ggrq4OiYmJfCsHfgoRERGwt7eHgoIC3NzcWNfh6uqK2tpaHDp0iEkjhCAqKgoeHh5MR9X3QWMhRVHUh5GSkhJY33ifPi5A+2KgMJrWh8zNzfHo0SOcOHEChBA8ffoUhw8fZg0o+BiKiopQWlqK4cOHM2mSkpKwtLREZmZmm/sbGBhAU1OTebf55s0b/PXXX3B2doaenh4uXLgAoHFAY9NB+RwOB9evXxe4ynBLaBykKOpT+qI7gh47dgyysrKsT/Ne/mPGjMH48eNhZ2eHIUOGwNPTU6hjKykpQU1NjZmRjMfc3ByysrLo2LEjFixYAB0dHYwfP16oY965cweEEGaEQEtu374NAOjRo4fA7d27d2fyNBUYGIjk5GRkZGQIVZ7mx+Rda2FhIZPWlpSUFFRVVcHW1hYA+CqC7yMwMBAKCgrMR0tL64OOR1EURX1ewcHB8PT0xMyZM2FgYID58+dj7NixCA4OBgBmJDxv1HnTkfEt6d69O968eYMXL14AAMrLyxEfH8/MPubm5obDhw+zKkebNm3C8+fPweFw0Lt3b0yfPh0nT55ktldUVCA8PBzBwcGwsbGBsbExoqOjBb7g+/3333Ho0CGkpaXxzSralLu7O86fP4/i4mLcv38fFy5cYM2Q1hIaCymKoj6f8PBw5lltZ2eHiooKnDlzBkBjXamtepKw9b62tBXb9PX10blzZ6SlpQFoHIFuaWkJNTU16OrqMo2PTZciEvYaeFq7Fx06dMDkyZMRFRXFvIAsKirCuXPnWEsAAsDVq1f56u5Nl3dqjsZBiqKoT+dLiXMAsGjRIsjKykJSUhJWVlbMqgs8t2/fhp6eHiQkJPj21dTUhIKCAtNGWlhYyFrVqTUFBQWYNWsWwsLChKqfNdW8LgoIbqNeu3atwP3r6uoQFRWFq1evYtiwYQLz0DhIURT1ZRI2BgrTTvm+Bg0ahKVLl2LSpElQUVHBiBEj8Msvv+Dp06cffOzmGhoaEBUVxVyHi4sLsrKycOfOHQCN71HHjBnDGgSflpaGe/fu8Q2Eb0+sBGgspCiK+hDZ2dmIjY1l1TeE6eNSVlbG96zmdZr8WPVAQfUhc3NzxMTEYMKECZCQkACHw4GioiK2bdv2QedqrrS0FEDjChBNqaurM9vaMnToUKYtljcoX1VVFZaWlqw2Wi0tLejp6QFoXNl3wIABMDY2ho6ODlxcXBAREYHq6uoWz0PjIEVRn9IX3RHUysoK+fn5rM/u3bv58q1YsQINDQ1YsWJFu45PCGEtIQ80jprPy8tDUlISuFwudu/ezSzfIMzxAPAds638wpQLAIyMjDB58mRmiu/2aHrM9owiDA8Px4QJE5iRfRMnTsSlS5dw69atdpeBZ8mSJSgrK2M+Dx8+fO9jURRFUZ9fQUEBLCwsWGkWFhYoKCh472M2j6mxsbHQ1dVlOmX26dMHurq6iIuLY/YxMjLCtWvXcPHiRXh5eeHp06dwdHRkOqLcvXsXNTU1rOX/lJSUBL5MHDx4MGRlZbF8+XLU1dW1WE4VFRXY29sjOjoakZGRsLe3Z5Zjag2NhRRFUZ/HrVu3kJ2dDRcXFwCNS5pPmDABERERAFquizXV3npfS4SJbU0bH9PS0jB06FAAYBofq6urcfHiRdYygcJcA9D2vQAalwK8f/8+zp49C6BxtpguXbrA2tqadSxDQ0O+uvv69etbPDeNgxRFUZ/GlxTngMYVGfLz83Hu3DlYWVlh2bJlMDc3F3r/5u2ZwpapS5cu6NevH4KCglBSUtKuMgu6fkFt1L6+vqz9eJ1epaSk4OvrC39/f4EznQI0DlIURX2phI2BwtTlPsT69etRWlqKXbt2wcjICLt27UL37t1x9erVj3J8ntOnT6OyspKZgEdFRQXDhw/nqxOmp6cznUMjIiJgYWHB154qTKxsisZCiqKo9uF1uO/YsSPMzMwwZMgQVkdKYfq4yMnJ8T2reZ39P7Qe2Fp96MaNG5gzZw5WrlyJ3NxcJCcno6ioCNOnT3+vc7Wl+TW0py5pZWWFCxcuoLa2VmBbLNDYRtu0LVZGRgbHjx/HnTt3sHz5csjKymLBggUwNTVlVnRqjsZBiqI+pfeft/9fICMjwyxvx/Po0SO+fLxOiu1ZhuDFixd4/vw5unXrxkrX0tKCvr4+9PX1ISsri3HjxuHGjRtQU1Nr85j6+voQERFBQUEBxowZ02I+AwMDAI0dZwQ1ft68eRNGRkYC9/3pp59gYGCAI0eOtFmepgoKCphr5Z3/5s2brM4wzb18+RJHjhxBbW0twsLCmPT6+npERETg559/blcZeCQlJSEpKfle+1IURVFfpg+pWAlSUFAAeXl5ZtnZiIgIXL9+nRXrGxoaEB4ejqlTpzJpoqKiGDBgAAYMGIB58+Zh3759cHd3x7Jly9o1EMLY2BghISGwtrbG+PHjceDAgRaX0fjxxx8xa9YsAI3LDwqDxkKKoqjPIzw8HHV1dejcuTOTRgiBuLg4Xr16BQMDgzYHMghb72uLMLHNysoKfn5+ePHiBfLy8jBkyBAAjY2P27Ztw/Dhw1lLEQEQ6hqAtu9Fp06doK+vj++//x6RkZGwsrJCdHQ0vLy8ICrKHlMqISHBV3dvDY2DFEVRn8aXFOeAxg4lXC4XXC4X8fHx4HK5GDRoEDOgwMDAAOfPn0dNTQ3frKBPnjxBeXk59PX1mbzCDjaUk5NDSkoKhg8fjqFDhyI1NRWamppC7du8LgoIbqNuzt/fH56enpCWloaGhkar9WEaBymKor5MwsZAYdspP4SysjKcnZ3h7OyMwMBA9O3bF8HBwYiOjv4oxwcar+Ply5eQlpZm0hoaGpCXl4e1a9eiQ4cOsLa2hra2NqKiohAQEICEhARs376d71jCxMqmaCykKIpqHysrK4SFhUFcXByamprM+yreirDC9HERFRVt8Vn9ofXA1upDgYGBsLCwgL+/PwCgd+/ekJGRwffff49169ZBQ0Oj3ecThMPhAGicGbTpMZ89e8Y3S2hLrKysUFlZiZycHKSmpjJltrS0xOTJk/Hy5UtkZWXBw8ODb189PT3o6elhypQpWLZsGQwMDHDgwAF4eXnx5aVxkKKoT+mLnhH0U9qyZQtERUVbDWSWlpbo1atXqzOZNKWkpARbW1vs2LEDlZWVfNtfv34NABg+fDiUlJQQEhLClycpKQmFhYWYOHGiwHNoaWlh1qxZWLp0qcClbAU5e/Ysrl69inHjxjHnV1FRQVBQkMD8vHLGxMSgS5cuuHLlCmtkSGhoKKKjo1udIY2iKIr67+jRowfOnz/PSsvMzESPHj2Y7+Li4kLHrWfPniE2NhZjxoyBqKgorl69isuXLyMtLY0Vj9LT05GTk4Nr1661eCzewIrKykpwuVyIi4vj4sWLzPZXr14xSw0216dPH5w9exbnz5+Hs7MzamtrBeazs7NDTU0NampqYGtrK9Q1UhRFUf++uro67NmzByEhIax4cuXKFWhrayMmJgaTJk1CSkoK8vLyBO5fWVkpdL2vNcLGNl7j46ZNm6Cvr880WlpaWuLy5cs4fvw4unXrBm1tbebYwlyDMPeCx9vbGwkJCYiPj8ejR48ENl5SFEVRn9+XFOcE6dSpE2bPno2FCxcyg/RcXFxQUVGBX3/9lS9/cHAwxMXFmfbMSZMm4fbt2/jjjz/48hJCUFZWxne+lJQUdOrUCUOHDsXjx4/bLGPzumh78Dq9ampqfpTZVCmKoqh/nzAx8EPaKd+XhIQE9PT0BJbpfb148QJ//PEH4uLi+GaHq6iowMmTJwE0Dv738vJCdHQ0YmNjISoqyrfUMEVRFPXp8Trca2trtzhpCU97+7gAwvdzaUlr9aGqqiq++lWHDh0AtG8l27Z069YNHA4Hf/75J5NWU1ODc+fOCb0yhZ6eHrS0tJCUlIT8/HxYWloCADQ0NKCjo4OQkBC8e/eONShfEB0dHUhLS3/U2E1RFCWsL3pG0I/lzZs3KC0tRW1tLYqKirBv3z7s3r0bgYGBbY5QW7BgAZydnREQEMCMpq+vr0d+fj4rn4SEBIyMjLBz506Ym5vD1NQUa9asQe/evVFXV4c///wTYWFhKCgogIyMDH799Ve4uLhg6tSpmDVrFuTl5XHmzBn4+/vDycmp1YrUkiVL8Pvvv6OoqAgTJkxgbauurkZpaSnq6+vx9OlTJCcnIzAwEA4ODpg8eTKAxj8Udu/eDWdnZ4waNQpz5swBl8vFP//8g4MHD+LBgweIi4tDeHg4nJyc0KtXL9Y5tLW1sWjRIhw/fhyjR48W9r+BoiiK+kb5+/tj/Pjx6NevH4YNG4ajR48iISEBKSkpTB4dHR2cOXMGFhYWkJSURKdOnQA0VvJKS0tBCMHr16+RlZWFDRs2QEFBARs3bgTQOKuNqakpMwtaU2ZmZggPD8fmzZvh5OQECwsLmJubg8PhoKioCEuWLIGBgQG6d+8OMTExeHt7w9/fH8rKylBXV8eyZctafcHXu3dvpKam4ocffoCTkxMOHTrEN1NNhw4dmJlpeJVXiqIo6stz7NgxvHr1Ct7e3lBQUGBtc3JyQnh4OC5evIjjx49j2LBhWLt2LQYPHgw5OTlcvnwZP//8M8LDw9GnTx+h6n2tETa26erqomvXrti2bRtcXV2ZPJqamtDW1sauXbvg7OzM2n/u3LltXkNxcXGb94I327WzszPmzJmDadOmYdiwYdDR0eErc11dHUpLS1lpIiIiQo+2pyiKoj7clxTnWuLr64uff/4Z8fHxcHJygpmZGfz8/ODv74+amhqMGTMGtbW12LdvH7Zs2YLQ0FBoaWkBAMaPH4/ExERMnDgRK1asgI2NDVRVVXH16lVs3rwZs2fP5hvwr6CggNOnT8POzo6ZGbRLly4AhKuL8vDaW5sSExODiorKe90HiqIo6svVVgy0tbUVqi73vo4dO4a4uDi4uLjAwMAAhBAcPXoUJ06cYJbvbcmtW7f40oyMjPjaMgFg7969zKyjzdtGHRwcEB4eDgcHBwCAl5cX1qxZg6VLl8LFxQUyMjJ8x6OxkqIo6ssiqI8Lrw7UnJqaGkRFRT9ZPdDR0RE+Pj5MHC0pKcHcuXNhamrKrNxQU1ODGzduMP9+/Pgx8vPzISsry/TnqaiowJ07d5jjFhUVIT8/H0pKSujatStEREQwd+5cbNiwgZkddcOGDZCWlsakSZOELq+VlRV27twJLpfLatvkrdDEa6/lWb16NaqqqjBy5Ehoa2vj9evX2Lp1K2pra2FjY/Ne94yiKOqDkC+Uh4cHGT16NF96amoqAUBevXrFpBUVFREAJC8vjy+/trY2AUAAEAkJCdK1a1cyfvx4cvbsWVa+lo7R0NBADA0NyYwZMwghhERGRjLHa/rR1tZm9nny5Anx9fUl2traREJCgnTu3JmMGjWKpKamso6dnp5O7OzsiIKCApGQkCBGRkYkODiY1NXVsfIBIImJiay0DRs2EADEw8ODdc945RETEyOqqqrE2tqaREREkPr6er57k5OTQ8aOHUtUVVWJpKQk4XK5ZOrUqaSwsJBcvnyZACDZ2dl8+xFCiKOjI3F0dGS+r1q1ipiYmAjM25aysjICgJSVlb3X/hRFffvoc+LLEhkZSRQUFFhpO3fuJLq6ukRcXJwYGBiQPXv2sLYnJSURLpdLxMTEmJjZNKaKiIgQBQUFYmpqStasWcP8X1dXVxNlZWUSFBQksCwhISFERUWFVFdXk99++41YWVkRVVVVJuZ7enqS4uJiJv+bN2+Im5sbkZaWJurq6iQoKIhYWloSPz8/Jk/z74QQcv36dcLhcIiDgwOprq5u8e8UntGjR7NidFvob5yiqLbQ58SHc3BwICNHjhS4LTc3lwAgubm55N27dyQwMJAYGxuTjh07EiUlJWJhYUGioqJIbW0ts4+w9b7m2hPbCPn/el5cXBwrn7e3NwFA9u7dy3eMtq5B2HvBM3XqVAKAxMbG8uVftWqVwDqypKRkq/ehKfr7piiqLfQ50bYvJc7xaGtrk82bN/Ol+/j4kJ49e7LaKsPDw0n//v2JlJQUkZaWJoMHDyZJSUl8+9bX15OwsDAyYMAAIi0tTeTl5cl3331HtmzZQqqqqgghgtsoy8vLiYWFBdHT0yMPHjwQqi7K07S9tenH0NCwzWsVFv19UxTVFvqc+He1FANPnTrVrrqcoPeZbbl79y7x8fEhBgYGREpKiigqKpIBAwaQyMhIJk/z95m874I+RUVFhBD+94zGxsZk5syZAssQHx9PxMTESGlpKZM2fPhwAoBkZmby5RcmVraF/sYpimrLf/k50dr7qA/t4wKAlJSUMPsJUw9sXv8Rpj60detWYmRkRKSkpIiGhgZxdXUljx494ruO5h9LS0smDy+uNv80fRfX0NBAVq1aRTgcDpGUlCRDhgwhV69ebbVszfHu1fTp01npe/fuJQCIt7c3K/3s2bNk3LhxREtLi0hISBB1dXViZ2dHMjIyhD7nf/n3TVGUcNrznBAh5CPOt0xR76G8vBwKCgooKyuDvLz85y4ORVFfIPqcoD6loUOHok+fPggNDf1sZaC/cYqi2kKfE9S3jP6+KYpqC31OUN8y+vumKKot9DlBfevob5yiqLbQ5wT1LaO/b4qi2tKe58R/Ymn4f5Onpyeio6MBNC57oKSkhN69e2PixInw9PRkllgYOnQozp07x9p3woQJiIuLY76/evUKc+bMQVJSEgBg1KhR2LZtGxQVFf+di/mXOYXdgXhH2c9djHY77mfwuYtAUdR/UGZmJr7//nvY2NggOTmZta2mpgahoaGIiYlBYWEhpKWlYWhoiClTpsDNzQ3i4uIAgNLSUqxfvx7Hjx/H48ePoaamhj59+mDu3LkYNmxYm2XQ0dHB/fv3kZWVhUGDBjHpc+fORX5+PtLS0pi0ly9fYs2aNThy5AiePHkCZWVl2NnZ4aeffmItoRAYGIiEhATcvHkTUlJSMDc3x88//wxDQ0MmDyEEP/30E3777Te8evUKAwcOxI4dO9CzZ08mT3V1NRYuXIj9+/fj7du3GDZsGHbu3MksA9jU7du3ce7cOQwaNAguLi4AgJCQEKxZswYlJSWQlpZm5X/37h04HA5WrlyJ+fPnM/ehucDAQCxevLjN+9jU1xoLqY+L/m1BUe+naV2sKSsrK/z999+YO3culi9fzrc9MDAQISEhePLkCWJjYzF37ly8fv1aqHO+ffsWGzduRFxcHIqLiyEnJ4ehQ4fip59+YsWl1atX46effsK0adOwa9cuJj0/Px99+/ZFUVERdHR0UFxcjG7dujHbZWVl0bVrVwwdOhRz586Fvr6+UOVKSEhAWFgY8vPzUV1djZ49e2L16tWwtbVl5YuPj8eKFStw9+5d6OnpYf369fjf//7HbE9PT8cvv/yC3NxclJSUIDExkW/Z3YSEBPz666/Izc3FixcvkJeXhz59+ghVzuZoHPz4aEyhqK9f87ZGLS0tjB07Fj/99BOeP3/Oihvy8vLo0aMHli1bBkdHRyY9KioKXl5efMeWlJTEu3fvmO/C1BF1dHQwd+5czJ07l/nOqw9JSUlBV1cXs2fPxrRp05jjxsTEICgoCIWFhVBQUICdnR2Cg4OhrKwMALh+/TpWrlyJ3Nxc3L9/H5s3b2aOzyNMTBKmrtgSFxcXlJWV4eTJk0zayZMnMXLkSCxfvhxr165l0teuXYuwsDA8efIEQGM8DQoKws2bN9HQ0ICuXbvCzs4OISEhbZ63KRoHv0w0llLUt+tbbV9tKjAwEEuXLoWfn5/AQfCxsbFwd3eHj48PU1fNzc1F//79kZGRgcGDB/PtY2trC0lJSSQlJbVYD7e1teW7p8KgsfDLRGMhRX27aCz8smLh54iD9BlPUd8e0c9dgG+RnZ0dSkpKUFxcjJMnT8LKygp+fn5wcHBAXV0dk8/HxwclJSXM59dff2UdZ9KkScjPz0dycjKSk5ORn58Pd3f3f/tyKIqiqC9QREQEZs+ejfPnz+PBgwdMek1NDWxtbbFx40ZMnToVmZmZyM7Ohq+vL7Zt24br168DAIqLi/Hdd9/h7NmzCAoKwtWrV5GcnAwrKyv4+voKXY6OHTti0aJFreZ5+fIlBg0ahJSUFOzcuRN37tzBgQMHcPfuXQwYMAD37t1j8p47dw6+vr64ePEi/vzzT9TV1WH48OGorKxk8gQFBWHTpk3Yvn07cnJywOFwYGNjgzdv3jB55s6di8TERMTFxeH8+fOoqKiAg4MD6uvrWWWrqqrCs2fP8N133yE8PJxJnzx5Mt6+fYv4+Hi+64mPj0dVVRUrJvM6jTb9zJ49W+j7SFEURX0cvLpY0098fDzc3NwQFRUFQQtiREZGwt3dHRISEu06V3V1NaytrREREYG1a9fi9u3bOHHiBOrr6/Hdd99BWloasrKykJWVxYYNGwAAv/76q1CdOVNSUlBSUoIrV65gw4YNKCgogImJCc6cOSNU2dLT02FjY4MTJ04gNzcXVlZWcHR0RF5eHpMnKysLEyZMgLu7O65cuQJ3d3eMHz8ely5dYvJUVlbCxMQE27dvb/FclZWVsLCwwMaNG4UqG0VRFNV+vPh27949rFu3Djt37sTChQuZ7by4cenSJZiammLcuHG4du0a6xjy8vJ8MbLpgLb21BFzc3OZGPfgwQNISEhAWloaIiIiePr0KaZPn44DBw4AAM6fP4/JkyfD29sb169fx6FDh5CTk4MpU6Ywx6uqqoKuri42btwIDocj8B4IE5OEqSu2xMrKCufPn2e13aalpUFLSwupqamsvGlpabCysgLQeO9dXFzg5OSE7Oxs5ObmYv369aipqWnznBRFUdTn9TnaV2NiYpgYyoujAGBhYdHqwIX2tK/y5OTk4LfffkPv3r1bvQcBAQGIi4tDVVUVAOC7776DiYkJIiMj+fI/fPgQKSkp8Pb2ZtIE1cP379/f4jkpiqKoL8e3+q6Rp2ksvHnzJisG8z6TJ0+GkpISjYUURX0z6Iygn4CkpCTTaNm5c2f069cPgwYNwrBhwxAVFcU0dEpLS7fYuFlQUIDk5GRcvHgRAwcOBAD8/vvvMDMzw61bt1gzownCa5BMTk7G4sWLcfPmTZiZmSEuLg65ubmYP38+Hj9+DHt7e4SHhzOznQ0dOhTGxsbo0KEDoqOjISEhgbVr18LV1RWzZs3C4cOHoaamhu3bt2PEiBEf65ZRFEVR7VBZWYmDBw8iJycHpaWliIqKwsqVKwEAoaGhSE9Px+XLl9G3b19mH11dXTg7OzMvo2bOnAkRERFkZ2dDRkaGydezZ0/8+OOPQpdl2rRpCAsLw4kTJzBy5EiBeZYtW4YnT57gzp07TNzr2rUrTp06BX19ffj6+jKzrjQfHRcZGQk1NTXk5uZiyJAhIIQgNDQUy5Ytw9ixYwEA0dHRUFdXR2xsLKZNm4aysjKEh4dj7969sLa2BgDs27cPWlpaSElJYc2GdujQIQwYMADJycnQ0NBAcXExdHR0oKqqCkdHR0RERPANwoiIiMCoUaOgqqrKpMnJybUY0ymKoqh/T9O6WFPe3t7YsmUL0tPTYWlpyaRnZGSgsLCQ1XAnrNDQUGRlZSEvLw8mJiYAAG1tbcTHx6N///548+YNTpw4AREREWzduhV//vknlJWVoaCg0OaxlZWVmevQ1dWFo6Mjhg0bBm9vb9y9excdOnRos2xNbdiwAX/88QeOHj3K/H0QGhoKGxsbLFmyBACwZMkSnDt3DqGhoUxD5YgRI9qs9/HiZHFxcZvXRVEURb2fpvFt0qRJSE1NxZEjR5gXZby4weFwsH79emzbtg2pqano1asXcwwREZFW6yztqSP27NkTq1atAgBYWlrC09OTmXFUXFwcNjY2OHLkCCZMmICLFy9CR0cHc+bMAQB069YN06ZNQ1BQEHO8AQMGYMCAAQDQ4qoKbcUkYeqKrbGyskJFRQUuX77MzEKTlpaGxYsXY968eaiqqoK0tDRqamqQlZWFrVu3AgCOHTuGwYMHw9/fnzmWgYEB32ylFEVR1Jflc7Wvjho1innnBzTGURsbG8TGxrJiSXPtaV8FgIqKCri6uuL333/HunXrBB6zuLgYmZmZiI+PR2pqKg4fPozJkycDaKxDL126FFu3bmVdW1RUFFRVVWFvb8+ktVQPpyiKor5s3/K7RoA/Furq6vINLHz06BHs7Oxw9uxZ+Pj40FhIUdQ3gc4I+i/54YcfYGJigoSEBCYtJiYGKioq6NmzJxYuXMganZ6VlQUFBQVWhXDQoEFQUFBAZmam0OddvXo1tm/fjszMTDx8+BDjx49HaGgoYmNjcfz4cfz555/Ytm0ba5/o6GioqKggOzsbs2fPxowZM+Ds7Axzc3P89ddfsLW1hbu7OzMior2qq6tRXl7O+lAURVHCO3DgAAwNDWFoaAg3NzdERkYyM5zFxMTA2tqaVTHjERcXh4yMDF6+fInk5GT4+vqyKi88ioqKQpdFR0cH06dPx5IlS9DQ0MC3vaGhAXFxcXB1deWrBElJSWHmzJk4deoUXr58KfD4ZWVlAAAlJSUAQFFREUpLSzF8+HAmj6SkJCwtLZn4mJubi9raWlYeTU1N9OrViy+GhoeHw83NDQoKChg5ciRrdJ+3tzfOnTuHoqIiJq24uBipqanv1WGoKRoLKYqi/l3GxsYYMGAA3yjuiIgImJqasjrKCCs2NhY2NjZMJ1AeUVFRLFy4EHfu3EFlZSW4XC6UlJQgKSmJrVu3Ijk5GTk5Oe06l6ioKPz8/HD//n3k5ua2u6wNDQ148+YNE0+Bxjpn01gJNC5Z1J765vuicZCiKOrDSElJoba2li+9trYWv//+OwAwy/QJo711xI4dO4LL5YLL5UJcXByqqqrMd21tbXTs2JEpn7m5OR49eoQTJ06AEIKnT5/i8OHDrJdmH4MwdcXWGBgYQFNTk5n9882bN/jrr7/g7OwMPT09XLhwAQBw8eJFvH37lpkRlMPh4Pr163wzsLaGxkGKoqjP73O1r8rJyTExkxdH+/TpgxkzZmDz5s0frX3V19cX9vb2zCB5QSIiImBvbw8FBQW4ubmxVktydXVFbW0tDh06xKQRQhAVFQUPDw+IiX3YPEM0FlIURX1+3/q7xuaxUEJCghWDuVwuzp49C0dHRxgbG/+rsZDGQYqiPiXaEfRf1L17d2aWFFdXV+zfvx9paWlYsWIF4uPjmdHqAFBaWgo1NTW+Y6ipqaG0tFToc65btw4WFhbo27cv06ElLCwMffv2xffffw8nJye+5Y1MTEywfPly6OvrY8mSJZCSkoKKigp8fHygr6+PlStX4sWLF/j777/f6z4EBgZCQUGB+Whpab3XcSiKov6reJ0XgcblBioqKpilYgsLC9G9e/dW979z5w4IIW3mE9by5ctRVFSEmJgYvm3Pnz/H69ev0aNHD4H79ujRA4QQ3Llzh28bIQTz58/H4MGDmQ46vBiorq7Oyquurs5sKy0thYSEBDp16tRiHqDxXl28eBETJkwAAKaiy6tk2traQlNTE1FRUcw+kZGR0NTU5Os4s2jRIr7lJNLS0gReM0BjIUVR1Kdy7Ngxvufx2rVrAQA//vgjDh8+jIqKCgCNo8IPHTr03p37b9++3Wp84+Vpql+/fhg/fnyLs521hhe332fmzZCQEFRWVmL8+PFMWmlpaavx9FOicZCiKOr9ZWdnIzY2FsOGDWPSzM3NISsri44dO2LBggXQ0dFhPfOBxkF2zWMkr17zseqIdXV1iIqKwtWrV5nymZubIyYmBhMmTICEhAQ4HA4UFRX5BqZ/KGHqim0ZOnQoU4/LyMiAgYEBVFVVYWlpyaTzlovX09MDAMyePRsDBgyAsbExdHR04OLigoiICFRXV7d4HhoHKYqiPr9vuX01Li4Of/31FwIDA1s8X0NDA6Kioph74OLigqysLOYYSkpKGDNmDGswZVpaGu7du8c3w1tr9fCW0FhIURT1+dFY+PliIY2DFEV9SrQj6L+IEAIREREAgI+PD6ytrdGrVy+4uLjg8OHDSElJwV9//cXk5+Vt6RjC6N27N/NvdXV1SEtLQ1dXl5X27NmzFvfp0KEDlJWVYWxszNoHAN9+wlqyZAnKysqYz8OHD9/rOBRFUf9Ft27dQnZ2NlxcXAAAYmJimDBhAiIiIgAIFyd4I/raE09ao6qqioULF2LlypXMchDCaq0ss2bNwt9//80sT9tU8/zCXnfTPOHh4bC1tYWKigoAYOTIkaisrERKSgqAxhjo4eGBqKgoNDQ0gBCC6OhoeHp68i3J6+/vj/z8fNan6azezdFYSFEU9WlYWVnxPY99fX0BABMnTkRDQwMOHDgAoHHUOyGEiakfU2vxbd26dcjIyMDp06c/2jFbs3//fqxevRoHDhzgG2z4PvH0Y6BxkKIoqn14L5U6duwIMzMzDBkyhNWR8sCBA8jLy0NSUhK4XC52797NmgUaaJyBrHmM5L3Q+tA6Im9gnJSUFHx9feHv788sxX7jxg3MmTMHK1euRG5uLpKTk1FUVITp06e/17na8iGxzcrKChcuXEBtbS3S0tIwdOhQAODrCPrDDz8w+8jIyOD48eO4c+cOli9fDllZWSxYsACmpqYtrqZE4yBFUdTn9S23rz58+BB+fn7Yt28fOnbs2OI+p0+fRmVlJUaMGAEAUFFRwfDhw5l7ADSulpSens50iImIiICFhQUMDQ1Zx2qtHt4SGgspiqI+LxoLP28spHGQoqhP6cPm7qfapaCgAN26dRO4rV+/fhAXF0dhYSH69esHDoeDp0+f8uV7/vw538j21jRdBkpERIRvWSgRERG+6bUF5Wl+HAACp+UWhqSkJCQlJd9rX4qiqP+68PBw1NXVoXPnzkwaIQTi4uJ49eoVDAwMUFBQ0Oox9PX1ISIigoKCAowZM+ajlGv+/PnYuXMndu7cyUpXVVWFoqIibty4IXC/mzdvQkREhJlNhWf27NlISkpCeno6unTpwqTzlnwoLS2FhoYGk/7s2TMmPnI4HNTU1ODVq1esWUGfPXsGc3NzAEB9fT327NmD0tJS1vIN9fX1CA8PZ2bG+fHHHxEYGIizZ88CAB48eAAvLy++61BRUQGXy23jLv0/GgspiqI+DRkZmRafxwoKCnByckJkZCS8vb0RGRkJJycnyMvLv9e5DAwMWo1vQGPMbU5PTw8+Pj5YvHgxa7mhtvDie0t1SkEOHDgAb29vHDp0iG9JQA6HwzdDWtN4+inROEhRFNU+VlZWCAsLg7i4ODQ1NZl2Ot4s0VpaWtDX14e+vj5kZWUxbtw43LhxgzUAQFRUtMUY+aF1RH9/f3h6ekJaWhoaGhqsF4GBgYGwsLCAv78/gMYB6DIyMvj++++xbt06Vr3uQwhTV2yLlZUVKisrkZOTg9TUVKbMlpaWmDx5Ml6+fImsrCx4eHjw7aunpwc9PT1MmTIFy5Ytg4GBAQ4cOCCw/kjjIEVR1Of1Lbevpqen49mzZ/juu++Y7fX19UhPT8f27dtRXV2NDh06ICIiAi9fvoS0tDSTr6GhAXl5eVi7di06dOgAa2traGtrIyoqCgEBAUhISMD27dv5zt9aPbwlNBZSFEV9XjQWft5YSOMgRVGfEp0R9F9y9uxZXL16FePGjRO4/fr166itrWUaKs3MzFBWVobs7Gwmz6VLl1BWVsZ0YqEoiqL+W+rq6rBnzx6EhISwRpVduXIF2traiImJwaRJk5CSkoK8vDyB+1dWVkJJSQm2trbYsWMHKisr+fK9fv263WWTlZXFihUrsH79epSXlzPpoqKiGD9+PGJjY/k6m7x9+xY7d+6Era0tM1sNIQSzZs1CQkICzp49y9fZpVu3buBwOPjzzz+ZtJqaGpw7d46Jj9999x3ExcVZeUpKSnDt2jUmz4kTJ/DmzRvk5eWx7uWhQ4dw5MgRvHjxAkDjyzxLS0tERkYiIiICQ4cO5eu0SlEURX09vL29ceHCBRw7dgwXLlx472XhgcblglJSUnDlyhVWekNDAzZv3gwjIyOYmJgI3HflypW4ffs24uLihDpXQ0MDtm7dim7duqFv375C7bN//354enoiNjYW9vb2fNvNzMxYsRJoHAlP65sURVFfHt5LJW1tbb4B3M1ZWlqiV69eWL9+vdDH/9A6Im9gnKamJt9sMFVVVRAVZTdB81ZY4M3a8jEIU1dsi56eHrS0tJCUlIT8/HxYWloCADQ0NKCjo4OQkBC8e/cOVlZWrR5HR0cH0tLSAu8lRVEU9Xl96+2rw4YNw9WrV1nX1r9/f7i6uiI/Px8dOnTAixcv8McffyAuLo5v9rKKigqcPHkSQOOkMF5eXoiOjkZsbCxTDoqiKOrrRmMhjYUURX3baEfQT6C6uhqlpaV4/Pgx/vrrL2zYsAGjR4+Gg4MDJk+ejLt372LNmjW4fPkyiouLceLECTg7O6Nv376wsLAAAPTo0QN2dnbw8fHBxYsXcfHiRfj4+MDBwYFvqmmKoijqv+HYsWN49eoVvL290atXL9bHyckJ4eHhmDt3LiwsLDBs2DDs2LEDV65cwb1793Dw4EEMHDgQhYWFAICdO3eivr4epqamiI+PR2FhIQoKCrB161aYmZm9V/mmTp0KBQUFvqXc169fDw6HAxsbG5w8eRIPHz5Eeno6bG1tUVtbix07djB5fX19sW/fPsTGxkJOTg6lpaUoLS3F27dvATRWuubOnYsNGzYgMTER165dY2aemTRpEoDGGd+8vb2xYMECnDlzBnl5eXBzc4OxsTEzG1p4eDjs7e1hYmLCuo/jxo2Dqqoq9u3bx5TJ29sbCQkJSExMbLHD0Js3b5iy8j5NK6kURVHUv4NXF2v6+eeff5jtlpaW4HK5mDx5MrhcLoYMGfLe55o3bx5MTU3h6OiIQ4cO4cGDB8jJycG4ceNQUFCA8PDwFpdGUldXx/z587F161aB21+8eIHS0lLcu3cPSUlJsLa2RnZ2NsLDw5nOM63Zv38/Jk+ejJCQEAwaNIi5F2VlZUwePz8/nD59Gj///DNu3ryJn3/+GSkpKZg7dy6Tp6KigmkEBYCioiLk5+fjwYMHTJ6XL18iPz+fGZF/69Yt5Ofn8zXKUhRFUf+eBQsW4Ndff8Xjx4+ZNEIIX4wsLS1lVvz5FHVEAHB0dERCQgLCwsJw7949XLhwAXPmzIGpqSk0NTUBNHbY5MWbmpoaPH78GPn5+czye0DbMUmYuqIwrKyssHPnTnC5XNZMopaWlti2bRt0dXXRtWtXJn316tUICAhAWloaioqKkJeXhx9//BG1tbWwsbF57/tGURRFfRrfevuqnJwc33XJyMhAWVkZvXr1AgDs3bsXysrKcHZ2ZuXr3bs3HBwcWCtXeHl54cmTJ1i6dClcXFwgIyPDV+a26uEURVHUl4XGQhoLKYr6xhHqo/Lw8CAACAAiJiZGVFVVibW1NYmIiCD19fWEEEIePHhAhgwZQpSUlIiEhATR09Mjc+bMIS9evGAd68WLF8TV1ZXIyckROTk54urqSl69eiVUOVJTUwkAVv7IyEiioKDAyrdq1SpiYmLCfLe0tCR+fn6sPNra2mTz5s2sNAAkMTFRqLK0paysjAAgZWVlH+V4FEV9e+hzopGDgwMZOXKkwG25ubkEAMnNzSXv3r0jgYGBxNjYmHTs2JEoKSkRCwsLEhUVRWpra5l9njx5Qnx9fYm2tjaRkJAgnTt3JqNGjSKpqalClUdQfIiNjSUAiKWlJSv9+fPnZPbs2URLS4uIiYkRdXV14uHhQe7fv8/Kx4uhzT+RkZFMnoaGBrJq1SrC4XCIpKQkGTJkCLl69SrrOG/fviWzZs0iSkpKREpKijg4OJAHDx4QQggpLS0lYmJi5ODBgwKva/bs2cTY2Jj5XlVVRRQUFIiCggKpqqoSeB8ElXnatGlt3UIG/Y1TFNUW+pxoW9O6WNOPoaEhK9+GDRsIALJhwwa+YwiqM7WmsrKSLF++nHC5XCIuLk6UlJTIuHHj+OJS83oXIYSUl5cTFRUVAoAUFRURQggpKipilV1aWpr06NGDzJw5kxQWFgpdLktLS4H3wsPDg5Xv0KFDxNDQkIiLi5Pu3buT+Ph41nZevbK140RGRgrMs2rVKqHLS3/fFEW15b/8nPDw8CCjR48WuI0XN/Ly8ljpDQ0NxNDQkMyYMYMQ0vKzGgApKSlh9hOmjti8HiioXtjc1q1biZGREZGSkiIaGhrE1dWVPHr0iO86mn+a1iuFiUnC1BXbwrtX06dPZ6Xv3buXACDe3t6s9LNnz5Jx48YRLS0tIiEhQdTV1YmdnR3JyMgQ+pz/5d83RVHCoc+Jj+e/0L7aXPP3fsbGxmTmzJkC88bHxxMxMTFSWlrKpA0fPpwAIJmZmXz5ha2Ht4X+ximKagt9Tnw8NBZ+ebGQ/r4pimpLe54TIoR8xDV4KOo9lJeXQ0FBAWVlZZCXl//cxaEo6gtEnxPUt47+ximKagt9TlDfMvr7piiqLfQ5QX3L6O+boqi20OcE9a2jv3GKotpCnxPUt4z+vimKakt7nhNi/1KZviqlpaVYv349jh8/jsePH0NNTQ19+vTB3LlzMWzYMCbfhg0bsGLFCqxfvx6LFy8GAOjo6OD+/fstHtvS0hJpaWmtnj8vLw8rVqxAdnY2ysvLweFwMHDgQOzYsQMqKiooLi5Gt27dkJeXhz59+vB9BwBPT09ER0e3eh5eH+DY2Fi4u7vDx8cHu3btAgDk5uaif//+yMjIwODBg/n2tbW1haSkJJKSklo8l62tLZKTk1stQ1NOYXcg3lFW6PxfguN+Bp+7CBRFfWOaPlPFxMSgpaWFsWPH4qeffsLz58/RrVs3Jq+8vDx69OiBZcuWwdHRkUmPioqCl5cX37ElJSXx7t075rsw8U5HRwdz585lloltGuekpKSgq6uL2bNnY9q0acxxY2JiEBQUhMLCQigoKMDOzg7BwcFQVlYGAFy/fh0rV65Ebm4u7t+/j82bN7OWoQWA9PR0/PLLL8jNzUVJSQkSExMxZswYVh5CCH766Sf89ttvePXqFRMre/bsKfT9zsvLw4YNG5Ceno6ysjJ07doVlpaW8Pf3h4EB+xk/fPhwnDlzBhcuXMCgQYOY+NuaVatWYfXq1UKX52uMhVT70b8fKOrr09IS7zweHh6Iiopqdf/msaxpvBYVFYW8vDwMDAxgb28PPz8/KCgo8B1HUB2Up76+HkFBQYiOjsb9+/chJSUFAwMDTJs2TeDfBS0ZOnQo+vTpg9DQUCZty5YtCAgIQGRkJCZNmsT8vTJt2jSmDskzc+ZMhIWFtXlPBKFx8OOi8YaiqK/Vw4cPsXr1apw8eRL//PMPNDQ0MGbMGKxcuZKpVw4dOhTnzp3j21dQbPpa0Dj4edG4SVFfBk9PT7x+/RpHjhxhpaelpcHKygp79uzB9OnTceXKFXC5XGb7kydP0LNnT6xevRp+fn6sNsyOHTtCXV0dpqammD59On744Qdmv+bte621t86dOxevX79usezCvlvMzMzEunXrkJWVhbdv30JfXx+enp6YO3cuOnTowOQTERGBpKQkbt26BW1tbSZ9zJgxUFRUZOpbzduTlZSU0Lt3b0ycOBGenp4QFRVt8767uLigrKwMJ0+eZNJOnjyJkSNHYvny5Vi7di2TvnbtWoSFheHJkycAgPj4eAQFBeHmzZtoaGhA165dYWdnh5CQkDbP2xyNhZ8XjYUURbUkMzMT33//PWxsbPj6f9TU1CA0NBQxMTEoLCyEtLQ0DA0NMWXKFLi5uUFcXByA8HGyJU1ju6ioKNTV1TFixAgEBwejU6dOAP7/7wWgMY7KyclBV1cXNjY2mDdvHjQ0NPiO+6X0lQH+nThIn/UU9e1r+6///5ji4mJ89913OHv2LIKCgnD16lUkJyfDysoKvr6+rLyRkZEICAhAREQEk5aTk4OSkhKUlJQgPj4eAHDr1i0mLSEhodXzP3v2DNbW1lBRUcGpU6dQUFCAiIgIaGhooKqqipXX3NwcsrKyTIcX3vfp06djy5YtzDlLSkqY8jZPA4CIiAgEBAQgLi6OOcd3330HExMTREZG8pXx4cOHSElJgbe3N6ZPn46YmBh06NAB0tLSrI+gQEpRFEW1zc7ODiUlJbh37x7WrVuHnTt3YuHChcz2lJQUlJSU4NKlSzA1NcW4ceNw7do11jHk5eVZz/ySkhLWQIW24l1MTAxkZWXx4MEDLFq0CLKyssx3VVVVlJSU4O+//8aYMWMwffp0HDhwAABw/vx5TJ48Gd7e3rh+/ToOHTqEnJwcTJkyhTl3VVUVdHV1sXHjRnA4HIH3oLKyEiYmJti+fXuL9ykoKAibNm3C9u3bkZOTAw6HAxsbG7x580ao+3zs2DEMGjQI1dXViImJQUFBAfbu3QsFBQWsWLGClffBgwfIysrCrFmzEB4eDgDQ0tJi3d8FCxagZ8+erLSm/28URVHU16Vnz55M/Gtaz5GQkICUlBTreb9ly5b3OgcvXj969AiZmZmYOnUq9uzZgz59+jAv1Zri1UFXrVrFlI33kZKSwrJlyzB8+HDcuHEDqamp8PHxwatXrz7oPqxatQpLlixBYmIiJk2axKRraWkhLi4Ob9++ZdLevXuH/fv3o2vXrh90ToqiKOq/6969e+jfvz9u376N/fv3486dO9i1axfOnDkDMzMzvHz5ksnr4+PDV+8NCgoSeFxeHVfQpz2DCSmKoqjPy9HREba2tvDw8EBDQwOTPnXqVPTt2xdz5sxh0tasWYOSkhLcunULe/bsgaKiIqytrbF+/Xq+4wrT3toaQW2ts2bNwunTp2FjY8Oqt1lYWCArKwupqam4efMm/Pz8sH79eri4uKD5Io4iIiJYuXJlm+fntScXFxfj5MmTsLKygp+fHxwcHFBXV9fm/lZWVjh//jwrb1paGrS0tJCamsrK27STTUpKClxcXODk5ITs7Gzk5uZi/fr1qKmpEea2URRFUV+JiIgIzJ49G+fPn8eDBw+Y9JqaGtja2mLjxo2YOnUqMjMzkZ2dDV9fX2zbtg2//PILZGVlISMjA01NTezYsQNPnjyBmJgYJCUlBfbBaQ0vtj948AAxMTFIT09nxX6eW7du4cmTJ8jJycGiRYuQkpKCXr164erVqwKv7X37yvDw4nDTz/79+4W+LoqiqI+JzgjazMyZMyEiIoLs7GzIyMgw6T179sSPP/7IfD937hzevn2LNWvWYM+ePUhPT8eQIUOgqqrK5FFSUgIAqKmpQVFRUajzZ2Zmory8HLt374aYWON/T7du3VgjFHni4uJgZGSER48ewcrKivkuLy8PBQUFvhlkFBUV+TrcFBcXIzMzE/Hx8UhNTcXhw4cxefJkAIC3tzeWLl2KrVu3su5FVFQUVFVVYW9vDzMzMzx79gzl5eV8o+3ptNUURVHvR1JSknleT5o0CampqThy5AgWLVoEAFBWVgaHwwGHw8H69euxbds2pKamolevXswxREREWuxkCbQd7zp06ICBAwfC0tISnp6ezExilpaW8Pb2Zo69bt06HDx4EEeOHMGECRNw8eJF6OjoMBWvbt26Ydq0aayXcQMGDMCAAQMAgG82M54RI0ZgxIgRLZafEILQ0FAsW7YMY8eOBQBER0dDXV0dsbGxrBlKBamqqoKXlxdGjhyJxMREJr1bt24YOHAg3+j+yMhIODg4YMaMGTA1NUVoaChkZGRY91hWVhZiYmKt3neKoijq63HixAnU1tbypcfHx2PDhg2s531YWBiCg4Px8OFDdOvWDcuXL4e7uzuAxtHqAPC///0PAKCtrY3i4mIA7HitoaGBHj16wNHRET179kRAQAD27dvHnKNpHTQiIgKbN2+Gqakps93R0RE2NjZYv3495OTkAAAmJiassldWVmLGjBlISEiAnJwcFi5ciKNHj/LNAAo0xto5c+Zg7969OH36NN/o9379+uHevXtISEiAq6srACAhIQFaWlrQ1dUV6h5TFEVRVHO+vr6QkJDA6dOnISUlBQDo2rUr+vbtCz09PSxbtgxhYWEAAGlpaaHrX6NGjcLAgQOZ7yUlJdi4cSPOnz/PdD7dsWMHBg4ciNWrV+PIkSOYM2cOVq9ejZcvX8Ld3R3bt29HSEgINm3ahIaGBvj5+WHZsmXMMVevXo2IiAg8ffoUysrKcHJywtatWz/i3aEoiqIA4Ndff0WvXr2wadMmLFy4EFFRUcjIyMDff//NWs1BTk6OiRNdu3bFkCFDoKGhgZUrV8LJyQmGhoZMXmHaW1sjqK115syZGDduHMrLyyEvL4+qqipYWlpiyJAh+O2335hZPqdMmQJ1dXWMGjUKBw8exIQJE5jjzp49GyEhIVi4cCGMjY1bPH/T9uTOnTujX79+GDRoEIYNG4aoqCjWIH1BrKysUFFRgcuXL2PQoEEAGjt8Ll68GPPmzUNVVRWkpaVRU1ODrKwsJr4dO3YMgwcPhr+/P3MsAwMDvpWdKIqiqK9XZWUlDh48iJycHJSWliIqKooZpBAaGor09HRcvnwZffv2ZfbR1dWFs7MzXrx4gfHjx8Pb2xu3bt3C6dOnIS0tDQAQFxeHtrY2qw9OW5rG9s6dO2Py5MmIi4vjy8frn8PhcGBgYIDRo0ejb9++mDFjBs6fP8/k+9C+MjxN4zBFUdTnRmcEbeLly5dITk6Gr68v62HO07QzZ3h4OCZOnAhxcXFMnDiRmR3sQ3E4HNTV1SExMZFv5F9zXbt2BZfLZV4s8r6rqakJfb6IiAjY29tDQUEBbm5urOtwdXVFbW0tDh06xKQRQhAVFQUPDw+IiYlBTU0N8vLykJWVBZfLZX3aUw6KoiiqZVJSUgI7otTW1uL3338HAGZpBWEIE+/k5OTA5XIhLi4OVVVV5tkuLi7ODHTg6dixI1M+c3NzPHr0CCdOnAAhBE+fPsXhw4dZFaKPoaioCKWlpRg+fDiTJikpCUtLS2RmZra5/6lTp/DPP/8gICBA4PamMZ8QgsjISLi5uaF79+4wMDDAwYMHP/gaKIqiqC+btrY2Xx2Hy+VCXV2d9XIxMTERfn5+WLBgAa5du8Ysxc6bNSUnJwfA/6/QwPveEjU1Nbi6uiIpKQn19fVMetM6qLu7O06dOsUql7a2Nq5cuYJ37961eGx/f3+kpqYiMTERp0+fRlpaGnJzc/ny1dXVwd3dHYcOHcK5c+cELoEEAF5eXqyR8REREe1qvKUoiqKopl6+fIlTp05h5syZTCdQHg6HA1dXVxw4cKDNNlNBeHVcLpcLDocDT09PvHnzBsePH8fVq1cREBDAmlnu7t27OHnyJJKTk7F//36mDfXRo0c4d+4cfv75ZyxfvhwXL14EABw+fBibN2/Gr7/+isLCQhw5cqTVDjsURVHU+1NVVcWvv/6KFStW4M8//8S8efOwZcsW1vLpLfHz8wMhBH/88YfA7e/T3tpSWysv9vTr1w9cLhd3797F69evsXr1ar6yOjo6wsDAgG/2MHNzczg4OGDJkiVClaWpH374ASYmJm2uVAg0dt7U1NRk6rFv3rzBX3/9BWdnZ+jp6eHChQsAgIsXL+Lt27fMjKAcDgfXr19v1+ypFEVR1NflwIEDMDQ0hKGhIdzc3BAZGcnUyWJiYmBtbc3qBMojLi4ODocDJSUlZGRkwM/PD71792a1ZQIQekK15h4/foxjx46xBvy1REpKCtOnT8eFCxfw7NkzJv1D+8pQFEV9iWhH0Cbu3LkDQgi6d+/ear7y8nLEx8fDzc0NAODm5obDhw+jvLz8g8swaNAgLF26FJMmTYKKigpGjBiBX375BU+fPv3gYzfX0NCAqKgo5jpcXFyQlZWFO3fuAGic0XTMmDGsF3tpaWm4d+8e38u9Y8eO8S2rtHbtWoHnra6uRnl5OetDURRFCZadnY3Y2FgMGzaMSTM3N4esrCw6duyIBQsWQEdHB+PHj2ftV1ZWxvdc5nWaFDbetaWurg5RUVG4evUqUz5zc3PExMRgwoQJkJCQAIfDgaKiIrZt2/ZB52qutLQUAKCurs5KV1dXZ7a1prCwEACEugcpKSmoqqqCra0tAPBVBt8HjYUURVHfjuDgYHh6emLmzJkwMDDA/PnzMXbsWAQHBwMAs2oEbxR601UkWtK9e3e8efMGL168ACBcHXTTpk14/vw5OBwOevfujenTp+PkyZPM9oqKCoSHhyM4OBg2NjYwNjZGdHQ0q7Mpz++//45Dhw4hLS2Nb1bRptzd3XH+/HkUFxfj/v37uHDhAlPG1tA4SFEURQlSWFgIQgh69OghcHuPHj3w6tUrPH/+HACwc+dOvnpvdHR0m+eJjY3F8+fPceTIEQwePBhcLhfjx4+HmZkZk6ehoQEREREwMjKCo6MjrKyscOvWLYSGhsLQ0BBeXl4wNDREWloaAODBgwfgcDiwtrZG165dYWpqCh8fH4Hnp3GQoiiqdYLeNzVfOWjMmDEYP3487OzsMGTIEHh6egp1bCUlJaipqTGrNPAI097aEmHbWm/fvg0ALca57t27M3maCgwMRHJyMjIyMoQqT/NjNr/WlgwdOpSJaxkZGTAwMICqqiosLS2ZdN5y8Xp6egAaZywdMGAAjI2NoaOjAxcXF0RERKC6urrVc9FYSFEU9fUIDw9n2vvs7OxQUVGBM2fOAGisw7UV/z7WO0kAWLRoEWRlZSElJYUuXbpAREQEmzZtEmpf3vl5cfFz9ZUBaBykKOrToh1Bm+CNXGg6u4sgsbGx0NXVZV6I9enTB7q6ugKnnX4f69evR2lpKXbt2gUjIyPs2rUL3bt3x9WrVz/K8XlOnz6NyspKpgKtoqKC4cOHIyIigsnj7e2N9PR0JuBFRETAwsKCtWQG0LhsRH5+Puvj6+sr8LyBgYHM0vUKCgrQ0tL6qNdFURT1teNVGDp27AgzMzMMGTKE1ZHywIEDyMvLQ1JSErhcLnbv3s03S6ecnBzfc5lXWRE23rWkaUXL19cX/v7+zFLsN27cwJw5c7By5Urk5uYiOTkZRUVFmD59+nudqy3Nr4EQItR1tWcGmfDwcEyYMIEZ3Tdx4kRcunQJt27dal9hm6CxkKIo6ttRUFAACwsLVpqFhQUKCgre+5jNY7UwdVAjIyNcu3YNFy9ehJeXF54+fQpHR0dmCcC7d++ipqaG1clFSUmJr24HAIMHD4asrCyWL1+Ourq6FsupoqICe3t7REdHIzIyEvb29lBRUWnz+mgcpCiKot4HLz5KSEgAaJyhpXm993//+1+bx8nPz0ffvn356tFN6ejoQE5Ojvmurq4OIyMjiIqKstJ4s8k4Ozvj7du30NXVhY+PDxITE1uMoTQOUhRFtU7Q+6bdu3fz5VuxYgUaGhqwYsWKdh1fUPuhMO2trR0PEL6ttaV2yZbaNY2MjDB58mQsWrRIqOMLc0xBrKyscOHCBdTW1iItLQ1Dhw4FAL6OoD/88AOzj4yMDI4fP447d+5g+fLlkJWVxYIFC2BqaoqqqqoWz0VjIUVR1Nfh1q1byM7OhouLCwBATEwMEyZMYPqTCBNnPvSdZFP+/v7Iz8/H33//zXRGtbe3FzjQva1yfK6+MgCNgxRFfVq0I2gT+vr6EBERafOFXUREBK5fvw4xMTHmc/369Y+2PDwAKCsrw9nZGSEhISgoKICmpiYzo8zHEhERgZcvX0JaWpq5jhMnTrBmhbG2toa2tjaioqJQXl6OhIQEeHt78x1LRkaGb8nElirJS5YsQVlZGfN5+PDhR70uiqKorx2vwnDr1i28e/cOCQkJUFNTY7ZraWlBX18f9vb22L17NyZMmMBaygAAREVF+Z7LnTt3BiB8vGsJr6J1//59VFRUICgoiHkZFhgYCAsLC/j7+6N3796wtbXFzp07ERERgZKSkve8I/w4HA4A8M3++ezZM75ZQgUxMDAAANy8ebPVfC9fvsSRI0ewc+dOJlZ27twZdXV1rMpge9FYSFEU9W1534EJLSkoKIC8vDyUlZUBCF8HFRUVxYABAzBv3jwkJiYiKioK4eHhKCoqatcgCGNjY5w5cwZpaWkYP348amtrW8z7448/IioqCtHR0UIvC0/jIEVRFCUIl8uFiIgIbty4IXD7zZs3oaqqyiwdqKCgwFfvlZeXb/M8zZedF6T5csAiIiIC03jLyWtpaeHWrVvYsWMHpKSkMHPmTAwZMkRgDKVxkKIoqnWC3jfx2jWb4g3abs/SrC9evMDz58/RrVs3Vrow7a0tEbatldce2VK+mzdvQl9fX+C2n376CXl5eThy5IhQZeIpKCjgu9aWWFlZobKyEjk5OUhNTYWlpSWAxo6gOTk5ePnyJbKysphl4ZvS09PDlClTsHv3bvz111+4ceMGDhw40OK5aCykKIr6OoSHh6Ourg6dO3dm2iTDwsKQkJCAV69ewcDAoM3496HvJJtSUVEBl8uFvr4+fvjhB4SGhiIzMxOpqalt7ss7v46ODoDP11cGoHGQoqhPi3YEbUJJSQm2trbYsWMHKisr+ba/fv0aV69exeXLl5GWlsbq0Z+eno6cnBxcu3bto5dLQkICenp6Asv0vl68eIE//vgDcXFxfKMTKioqmCUERURE4OXlhejoaMTGxkJUVFTo5TBaIikpCXl5edaHoiiK+n+8CoO2tjbfi6bmLC0t0atXL6xfv17o4wsT71rDq2hpamrydXKpqqpizZACAB06dADQvlk429KtWzdwOBz8+eefTFpNTQ3OnTsHc3PzNvcfPnw4VFRUEBQUJHA77x7ExMSgS5cuuHLlCitWhoaGIjo6utVZ0lpDYyFFUdS3o0ePHjh//jwrLTMzk7Xcn7i4uFAj04HGQQ2xsbEYM2YMREVFP6gOamRkBACorKwEl8uFuLg4Ll68yGx/9eqVwKUHgcZZR8+ePYvz58/D2dm5xc6gdnZ2qKmpQU1NDWxtbYW6RhoHKYqiKEGUlZVhY2ODnTt34u3bt6xtpaWliImJEXrp39b07t0b+fn5ePny5QcfqykpKSmMGjUKW7duRVpaGrKysgSu8ETjIEVR1OezZcsWiIqKYsyYMS3maW97q7BtrcOHD4eSkhJCQkL48iQlJaGwsBATJ04UeA4tLS3MmjULS5cuFbpuefbsWVy9ehXjxo0TKr+enh60tLSQlJSE/Px8piOohoYGdHR0EBISgnfv3gnsCNqUjo4OpKWlW32nSWMhRVHUl6+urg579uxBSEgIq03yypUr0NbWRkxMDCZNmoSUlBTk5eUJ3L+ysvKD30m2hvf+sXn9sbm3b9/it99+w5AhQ6CqqvpZ+8oANA5SFPVpCT9M7j9i586dMDc3h6mpKdasWYPevXujrq4Of/75J8LCwmBrawtTU1MMGTKEb18zMzOEh4dj8+bN733+Y8eOIS4uDi4uLjAwMAAhBEePHsWJEyeYJX1bImiJWiMjI2a5pKb27t3LzDravMOOg4MDwsPD4eDgAADw8vLCmjVrsHTpUri4uEBGRobveNXV1XyzsomJiQm1LCBFURT1YRYsWABnZ2cEBAQwo+MJIXzPZQBQU1ODqKhom/HufUfmOTo6wsfHh4mZJSUlmDt3LkxNTaGpqQmgscMmb4aXmpoaPH78GPn5+ZCVlQWXywUAVFRUMEstAEBRURHy8/OhpKSErl27QkREBHPnzsWGDRugr68PfX19bNiwAdLS0pg0aVKb5ZSRkcHu3bvh7OyMUaNGYc6cOeByufjnn39w8OBBPHjwAHFxcQgPD4eTkxN69erF2l9bWxuLFi3C8ePHMXr06Pe6VxRFUdS3wd/fH+PHj0e/fv0wbNgwHD16FAkJCUhJSWHy6Ojo4MyZM7CwsICkpCQ6deoE4P/jNSEEr1+/RlZWFjZs2AAFBQVs3LgRQOPIe2HqoE5OTrCwsIC5uTk4HA6KioqwZMkSGBgYoHv37hATE4O3tzf8/f2hrKwMdXV1LFu2jK8+2FTv3r2RmpqKH374AU5OTjh06BBf/bJDhw7M3w28xleKoiiKel/bt2+Hubk5bG1tsW7dOnTr1g3Xr1+Hv78/DAwMsHLlSiZvVVUVX723aZxtycSJE7FhwwaMGTMGgYGB0NDQQF5eHjQ1NWFmZvZe5Y6KikJ9fT0GDhwIaWlp7N27F1JSUtDW1n6v41EURVEf7s2bNygtLUVtbS2Kioqwb98+7N69G4GBgUwbZEsEtbfW19cjPz+flU9CQgJGRkZCtbXKyMjg119/hYuLC6ZOnYpZs2ZBXl4eZ86cgb+/P5ycnFrtXLJkyRL8/vvvKCoqwoQJE1jbeO/o6uvr8fTpUyQnJyMwMBAODg6YPHmy0PfMysoKO3fuBJfLZa26ZGlpiW3btkFXVxddu3Zl0levXo2qqiqMHDkS2traeP36NbZu3Yra2lrY2NgIfV6Koijqy3Ps2DG8evUK3t7eUFBQYG1zcnJCeHg4Ll68iOPHj2PYsGFYu3YtBg8eDDk5OVy+fBk///wzwsPD0adPn4/2TpIX2wkhePjwIQICAqCiosI3QcyzZ8/w7t07vHnzBrm5uQgKCsI///yDhIQEALSvDEVR3zhC8Xny5Anx9fUl2traREJCgnTu3JmMGjWKnDp1iigrK5OgoCCB+4WEhBAVFRVSXV1NCCEkNTWVACCvXr0S+tx3794lPj4+xMDAgEhJSRFFRUUyYMAAEhkZyeQpKioiAEheXh7ru6BPUVERIYQQACQxMZE5hrGxMZk5c6bAMsTHxxMxMTFSWlrKpA0fPpwAIJmZmXz5PTw8BJ7b0NBQqGsuKysjAEhZWZlQ+SmK+u/5Lz0nPDw8yOjRowVua/7852loaCCGhoZkxowZhBBCIiMjW4wLJSUlzH4txbvU1FQmj7a2Ntm8eXOL3wXZunUrMTIyIlJSUkRDQ4O4urqSR48e8V1H84+lpSWThxdDm388PDxY171q1SrC4XCIpKQkGTJkCLl69WqrZWsuJyeHjB07lqiqqhJJSUnC5XLJ1KlTSWFhIbl8+TIBQLKzswXu6+joSBwdHZnvq1atIiYmJu06P89/6TdOUdT7oc+JL0dkZCRRUFBgpe3cuZPo6uoScXFxYmBgQPbs2cPanpSURLhcLhETEyPa2trMcXjxTUREhCgoKBBTU1OyZs0a5v+5urpa6Drob7/9RqysrIiqqiqRkJAgXbt2JZ6enqS4uJjJ/+bNG+Lm5kakpaWJuro6CQoKIpaWlsTPz4/J0/w7IYRcv36dcDgc4uDgQKqrq1v9e4UQQkaPHs2K2W2hv2+KotpCnxP/LUVFRcTDw4Ooq6sTERERAoCMHTuWVFZWMnksLS0F1hltbW2FOkdxcTEZN24ckZeXJ9LS0qR///7k0qVLhBDBdTtBsa9pzExMTCQDBw4k8vLyREZGhgwaNIikpKQIVRb6+6Yoqi3/pedES3UNQe/bWmorJaSxDZMXG3j1o/Hjx5OzZ8+y8n1oeyuvfkeIcG2thBCSnp5O7OzsiIKCApGQkCBGRkYkODiY1NXVsfI1f69HCCEbNmzgayNt+o5OTEyMqKqqEmtraxIREUHq6+v57k1reNc5ffp0VvrevXsJAOLt7c1KP3v2LBk3bhzR0tIiEhISRF1dndjZ2ZGMjIx2nfe/9BunKOr90OfEv8/BwYGMHDlS4Lbc3FwCgOTm5pJ3796RwMBAYmxsTDp27EiUlJSIhYUFiYqKIrW1tcw+wsbJljSN7QCIqqoqGTlyJCuGN323KCIiQuTk5IiJiQnx9/dnvR/9kvrKEEJ/3xRFta09zwkRQj7iOq0U9R7Ky8uhoKCAsrIyOu01RVEC0ecE9a2jv3GKotpCnxPUpzJ06FD06dMHoaGhn60M9PdNUVRb6HPiv23VqlXYtGkTTp8+/d4zdn7J6O+boqi20OcE9a2jv3GKotpCnxPUt4z+vimKakt7nhMtrwFHUS0QERHBkSNHPncxKIqiKIqiKIr6ChQXF0NERIRvCb1/41xpaWkQERHB69evP/m52+Lp6YkxY8Yw34cOHYq5c+d+tvJQFEVR1Nfip59+wtatW3Hp0iU0NDR87uJQFEVRFEVRFEVRFEVR1BdJ7HMX4Ev17NkzrFixAidPnsTTp0/RqVMnmJiYYPXq1TAzM4OIiAgSExNZL/KEERMTg2nTpgncpq2tjevXr3+E0v+/+vp6bN26FZGRkbh9+zY6duwIMzMzLF++HBYWFh/1XB/KKewOxDvKfu5iCOW4n8HnLgJFUdRXw9PTE9HR0QAAMTExaGlpYezYsfjpp5/w/PlzdOvWTeB+WVlZGDRoEKKiouDl5cWkq6mpwdTUFBs3bkTPnj35zjNt2jR8//33rHhbXV2Nuro6iImJwcDAgIm3paWlWL9+PY4fP47Hjx9DTU0Nffr0wdy5czFs2DBWeTZs2IAVK1Zg/fr1WLx4MQBAR0cH9+/fb/HaLS0tkZaWJvS9+ppiIdU+9G8H6mvg6emJ169f8w36SktLg5WVFV69egVFRcXPUrb3ZW5ujpKSEigoKAiVv2nM6tChAzQ1NWFvb48NGzagU6dOH7VsCQkJEBcX/6jHbMlvv/2G2NhY/PXXX3jz5o3A/8tXr15hzpw5SEpKAgCMGjUK27Zt+1f/z2kcbB2NJRRF/VuErSd9qjpSXl4eVqxYgezsbJSXl4PD4WDgwIHYsWMHREVFUVxcjG7duiEvLw99+vTh+75hwwasWrUKdXV1rZ6Ht1BWbGws3N3d4ePjg127dgEAcnNz0b9/f2RkZGDw4MF8+9ra2kJSUhJJSUmsvx+a50lOTm61DE3ROPjvonGVoqj2EBERaXW7h4cHoqKiWt2/+TvFpm2eoqKikJeXh4GBAezt7eHn5yewHiso9vLU19cjKCgI0dHRuH//PqSkpGBgYIBp06ZBQkJC6HeTglaN2LJlCwICAhAZGYlJkyax2mF5sZNn5syZCAsLa/OeCEJj4edBYyJFUe2RmZmJ77//HjY2Nnz1nZqaGoSGhiImJgaFhYWQlpaGoaEhpkyZAjc3N6YttHmdU1ZWFmVlZRAXF0eHDh1YxxTUh6ZpvbNjx47Q1taGt7c3Fi5cyMRsXj2xOVdXV+zbtw8A8PbtW2hqakJERASPHz+GlJQUX/74+Hhs27YNeXl5qK+vh66uLpycnDBr1iyMHTsW586da/FeaWtro7i4uI07+v8+RRykz3iK+u+hHUFbMG7cONTW1iI6Ohq6urp4+vQpzpw5g5cvXwp9jNraWr4Xe6NGjcLAgQMF5v/YLwEJIXBxcUFKSgp++eUXDBs2DOXl5dixYweGDh2KQ4cOtdiRVVDZKYqiKOp92dnZITIyErW1tcjIyMCUKVNQWVmJRYsWAQBSUlJYnToBQFlZmfm3vLw8bt26BUIIHj9+jICAANjb2+P27duQkJBg8mlpaSEuLg5r1qxhZoOrrq6GmZkZZGVlMWjQIGzevBlAYyXQwsICioqKCAoKQu/evVFbW4tTp07B19cXN2/eZJUnMjISAQEBiIiIYBpac3JyUF9fD6Cx8jtu3DjcunWLmZK9adkoiqIowQghqK+vh5jYx6+eSkhIgMPhtGsfXsyqq6vDjRs38OOPP+L169fYv3//Ry2bkpLSRz1ea6qqqmBnZwc7OzssWbKEtY3XGWfEiBF49OgR04A7depUuLu74+jRo+99XlqvpCiK+vq0p570KepIz549g7W1NRwdHXHq1CkoKiqiqKgISUlJqKqqEuoapk+fjhEjRuDdu3dMmrm5OTZu3Ijhw4dDQ0ODlT8iIgIBAQEICwvDpk2bIC0tje+++w4mJiaIjIzk6wj68OFDpKSkICEhgUnj/f3QlKSkpFDlpSiKor58JSUlzL8PHDiAlStX4tatW0yaoI4jwmja5vn69WtkZmYiMDAQkZGRuHDhAjQ1NVn5BcVentWrV+O3337D9u3b0b9/f5SXl+Py5ct49eoVfHx83vvd5KpVq/DLL78gMTERI0eOZNJ57bCbN29mrv/du3fYv38/unbt+j63g6IoivoKREREYPbs2di9ezcePHjAPPNrampga2uLK1euYO3atbCwsIC8vDwuXryI4OBg9O3blxnI17zOyZucIC4uDqdPn2adr6U4tWbNGvj4+ODdu3dISUnBjBkzIC8vzzfwofn7x6YxOz4+Hr169QIhBAkJCXB1dWXtu2zZMvz888+YN28eNmzYAE1NTRQWFmLXrl3Yu3cvEhISUFNTA6Cxnmhqaso6X/NOrRRFUf8GujS8AK9fv8b58+fx888/w8rKCtra2jA1NcWSJUtgb28PHR0dAMD//vc/iIiIMN9Xr16NPn36ICIiArq6upCUlAQhBGVlZZg6dSrU1NTQuXNnTJ06FZWVleByueByuRAREcGCBQtgamoKWVlZDBgwACkpKawy6ejoYN26dZg8eTJkZWWhra2NP/74A8+fP8fo0aMhKysLY2NjXL58mdnn4MGDOHz4MPbs2YMpU6agW7duMDExwW+//YZRo0YxnXBaK3thYSGGDBmCjh07wsjICH/++Sff/Xr8+DEmTJiATp06QVlZGaNHj27XyAaKoijq2ycpKQkOhwMtLS1MmjQJrq6urBnnlJWVweFwWJ+mlTsRERFwOBxoaGigf//+mDdvHu7fv89qcAWAfv36oWvXrvjzzz+ZOHvlyhXo6OjA1NQU8vLy0NbWBtA4Ol1ERATZ2dlwcnKCgYEBevbsifnz5+PixYus4547dw5v377FmjVrUFlZifT0dACAqqoqU15ehx41NTW+NIqiqG9BZWUl5OXlcfjwYVb60aNHISMjgzdv3gAAsrOz0bdvX3Ts2BH9+/dHXl4eKz9vufZTp06hf//+kJSUREZGBu7evYvRo0dDXV29xXqRiIgI34ylioqKLc4yImhp+AsXLsDS0hLS0tLo1KkTbG1t8erVK2Y7L2Z16dIFw4cPx4QJE1gNkPX19fD29ka3bt0gJSUFQ0NDbNmyhXXe+vp6zJ8/H4qKilBWVkZAQAAz6xhP86Xh27q2mpoazJo1CxoaGujYsSN0dHQQGBgo8Lqbmzt3LhYvXoxBgwYJ3F5QUIDk5GTs3r0bZmZmMDMzw++//45jx44xLyW5XC6Cg4NZ+127dg2ioqK4e/cucw27du3C6NGjISMjg3Xr1glVPoqiKOrLIWw96VPVkTIzM1FeXo7du3ejb9++6NatG3744QeEhoYK3alESUkJffv2ZWKamZkZAMDQ0BB9+/ZlygI0dnzNzMzE4sWL0b17d9bfOd7e3jh48CDTfsoTFRUFVVVV2NvbM2m8vx+afj72bOIURVHU59P0+a6goMC0VfI+sbGx0NPTg4SEBAwNDbF3715m35beKQLsNs8ePXrA29sbmZmZqKioQEBAAKsMLcVenqNHj2LmzJlwdnZm3gd6e3tj/vz5kJOTA5fLhYaGBtasWYM+ffrg+++/xx9//AEPDw9W3ZSHEILZs2djy5YtOH36NKsTKPD/7bBNB0YkJCRAS0sLffv2fc87TVEURX3JKisrcfDgQcyYMQMODg6sNtnQ0FCkp6fjzJkz8PX1RZ8+faCrq4tJkybh0qVL0NfXByC4zmlqaooNGzbgr7/+Yt7t8T68d3rNycnJgcPhQEdHB1OmTEHv3r35OpEC/O8fm864HR4eDjc3N7i5uSE8PJy1X3Z2NjZs2ICQkBD88ssvMDc3h46ODmxsbBAfHw8PDw8oKSkxx1VVVeU7Hy+Noijq30Q7ggogKysLWVlZHDlyBNXV1Xzbc3JyADSOvCspKWG+A8CdO3dw8OBBxMfHMzOR2dvbo7S0FCdOnEBubi769euHYcOGMbOLVlRUYOTIkUhJSUFeXh5sbW3h6OiIBw8esM67efNmWFhYIC8vD/b29nB3d8fkyZPh5ubGBMXJkyezljUyMDCAo6Mj3zUsWLAAL168YHXsbF72hoYGjB07Fh06dMDFixexa9cuZuY2nqqqKlhZWUFWVhbp6ek4f/48ZGVlYWdnx4x+aK66uhrl5eWsD0VRFPXfIiUlhdra2vfa9/Xr14iNjQUgeCSgl5cXayaWiIgI/Pjjj6w8L1++RHJyMnx9fSEjI8N3jObL4IaHh2PixIkQFxfHxIkT+SqE7UVjIUVRXyMZGRm4uLjwzXYVGRkJJycnyMnJobKyEg4ODjA0NERubi5Wr16NhQsXCjxeQEAAAgMDUVBQgN69ewtdL/oQ+fn5GDZsGHr27ImsrCycP38ejo6OzMxlzd27dw/JycmseNPQ0IAuXbrg4MGDuHHjBlauXImlS5fi4MGDTJ6QkBBEREQgPDwc58+fx8uXL5GYmPhBZd+6dSuSkpJw8OBB3Lp1C/v27WO9QPwQWVlZUFBQYM0QM2jQICgoKCAzMxMiIiL48ccf+f7vIyIi8P3330NPT49JW7VqFUaPHo2rV6/yxV8eGgcpiqK+TO2pJ33sOhIPh8NBXV0dEhMT+QZRfAoRERGwt7eHgoIC38s/V1dX1NbW4tChQ0waIQRRUVHw8PB479nMaRykKIr6tiQmJsLPzw8LFizAtWvXMG3aNHh5eSE1NRVA6+8UBVFTU4OrqyuSkpJYddW2Yi+Hw8HZs2fx/PnzFo/t7++P1NRUJCYm4vTp00hLS0Nubi5fvrq6Ori7u+PQoUM4d+4c3+zYPMK0wwpCYyFFUdTX6cCBAzA0NIShoSHc3NwQGRnJ1NtiYmJgbW0tcDCAuLg4ZGRk2v1uThiEEKSlpaGgoKBdKxPdvXsXWVlZGD9+PMaPH4/MzEzcu3eP2R4TEwNZWVnMnDlT4P7vU1YeGgcpivqUaEdQAcTExBAVFYXo6GgoKirCwsICS5cuxd9//w0ATM99RUVFvp78NTU12Lt3L/r27YvevXsjNTUVV69exaFDh9C/f3/o6+sjODgYioqKzAhzExMTTJs2DcbGxtDX18e6deugq6uLpKQkVrlGjhyJadOmQV9fHytXrsSbN28wYMAAODs7w8DAAIsWLUJBQQGePn0KALh9+zZ69Ogh8Bp56bdv326x7GfOnEFBQQH27t2LPn36YMiQIdiwYQPrOHFxcRAVFcXu3bthbGyMHj16IDIyEg8ePGCWGGwuMDAQCgoKzEdLS0vY/xqKoijqG5CdnY3Y2FgMGzaMSTM3N2cGYvA+TRs6y8rKICsrCxkZGXTq1AlxcXEYNWoUunfvznd8d3d3nD9/HsXFxbh//z4uXLgANzc3Vp47d+6AECJw/+bKy8sRHx/PHMPNzQ2HDx/+oIoZjYUURX2pjh07xvc8HjFiBLN9ypQpOHXqFJ48eQIA+Oeff3Ds2DHmRU9MTAzq6+sRERGBnj17wsHBAf7+/gLPtWbNGtjY2EBPTw/KyspC14s+RFBQEPr374+dO3fCxMQEPXv2xKxZs6CiosJ3D6SkpKCnp4cbN26wBsSJi4vjp59+woABA9CtWze4urrC09OT1RE0NDQUS5Yswbhx49CjRw/s2rWLNdr8fTx48AD6+voYPHgwtLW1MXjwYEycOPGDjslTWloKNTU1vnQ1NTWUlpYCaHzBd+vWLWRnZwNoXPZ93759fC/5Jk2ahB9//BG6urotjtincZCiKOrLJGw96VPUkXgGDRqEpUuXYtKkSVBRUcGIESPwyy+/MO2dH1NDQwOioqKY63BxcUFWVhbu3LkDoHFm0TFjxrA6uKSlpeHevXt88U/Q31Br164VeF4aBymKor4twcHB8PT0xMyZM2FgYID58+dj7NixzIoKrb1TbEn37t3x5s0bvHjxAoBwsXfTpk14/vw5OBwOevfujenTp+PkyZPM9oqKCoSHhyM4OBg2NjYwNjZGdHS0wIGRv//+Ow4dOoS0tDSYmJi0WE5h2mEFobGQoijq68SbQRMA7OzsUFFRgTNnzgAACgsL26xLtufdXFsWLVoEWVlZSEpKwsrKCoQQzJkzhy9f8/ePvNWrIiIiMGLECHTq1AlKSkqws7NDREQEs19hYSF0dXXb1blUWDQOUhT1KdGOoC0YN24cnjx5gqSkJNja2iItLQ39+vVrcclBHm1tbVYlLjc3FxUVFVBWVmYFmKKiImb5vMrKSgQEBMDIyAiKioqQlZXFzZs3+Wa+6d27N/NvdXV1AICxsTFf2rNnz4S+ThERkRbLXlBQgK5du6JLly5MGm8ppabXd+fOHcjJyTHXpqSkhHfv3jHX19ySJUtQVlbGfB4+fCh0eSmKoqivE++lWMeOHWFmZoYhQ4Zg27ZtzPYDBw4gPz+f9enQoQOzXU5ODvn5+cjNzcWuXbugp6eHXbt2CTyXiooK7O3tER0djcjISNjb27M6+ABgRig2jYMtiY2Nha6uLtPoyVvOIi4urt33gYfGQoqivlRWVlZ8z+Pdu3cz201NTdGzZ0/s2bMHALB371507doVQ4YMAdBYhzAxMYG0tDSzT/M6BE///v1Z34WtF30I3oygreHdg0uXLmH27NmwtbXF7NmzWXl27dqF/v37Q1VVFbKysvj999+ZcpaVlaGkpIR13WJiYnzX216enp7Iz8+HoaEh5syZI3Cpow8hKCYSQph0DQ0N2NvbMw2ix44dw7t37+Ds7MzaR5jrpHGQoijqyyRsPelT1JGaWr9+PUpLS7Fr1y4YGRlh165d6N69O65evfpRjs9z+vRpVFZWMoNeVFRUMHz4cNbLP29vb6SnpzOdQyMiImBhYQFDQ0PWsQT9DeXr6yvwvDQOUhRFfVsKCgpgYWHBSrOwsEBBQcF7H7N5TBYm9hoZGeHatWu4ePEivLy88PTpUzg6OmLKlCkAGmc+q6mpYdVVlZSU+GIaAAwePBiysrJYvnw56urqWiynMO2wgtBYSFEU9fXhDRB3cXEB0NjeOWHCBKb+1LQdsSXteTfXFn9/f+Tn5+PcuXOwsrLCsmXLYG5uzpev+ftHIyMj1NfXIzo6mjV4wc3NjTVAQpjreV80DlIU9Sm93/o1/xEdO3aEjY0NbGxssHLlSkyZMgWrVq2Cp6dni/s0n8K6oaEBGhoaAmfH5E0X7e/vj1OnTiE4OBhcLhdSUlJwcnLiW1q96WgDXtARlNbQ0AAAMDAwwI0bNwSWk1cB1dfXb7HsgpZfah7sGhoa8N133yEmJoYvb0ujGiUlJSEpKSlwG0VRFPVtsrKyQlhYGMTFxaGpqcnEr+LiYgCAlpYWuFxui/uLiooy27t3747S0lJMmDAB6enpAvP/+OOPmDVrFgBgx44dfNv19fUhIiKCgoICjBkzptWyR0RE4Pr166xl/xoaGhAeHo6pU6e2um9LaCykKOpLJSMjw/c8fvToEev7lClTsH37dixevBiRkZHw8vJi6gntWcK1ef1DmHqRiIgI3zlqa2uFPqeUlJRQ5eLdg61bt8LKygo//fQTM6vXwYMHMW/ePISEhMDMzAxycnL45ZdfcOnSJaHLIUhb19avXz8UFRXh5MmTSElJwfjx42Ftbc2sNPEhOByOwJnWnj9/zgw4BBr/793d3bF582ZERkZiwoQJrE6/AP//qyA0DlIURX2ZhK0nfYo6UnPKyspwdnaGs7MzAgMD0bdvXwQHByM6OvqjHB9ovI6XL1+yYllDQwPy8vKwdu1adOjQAdbW1tDW1kZUVBQCAgKQkJCA7du38x1L0N9QLaFxkKIo6tvT/N3Zh3YeKSgogLy8PJSVlQEIH3tFRUUxYMAADBgwAPPmzcO+ffvg7u6OZcuWtau+bmxsjJCQEFhbW2P8+PE4cOBAizOitdUOKwiNhRRFUV+f8PBw1NXVoXPnzkwaIQTi4uJ49eoVDAwM2hwE0Z53c21RUVEBl8sFl8tFfHw8uFwuBg0aBGtra1Y+Qe8fT5w4gcePH2PChAms9Pr6epw+fRojRoyAgYEBzp8/j9ra2o8+KyiNgxRFfUp0RtB2MDIyQmVlJYDGDpiClktorl+/figtLYWYmBgTiHgf3qi4jIwMeHp64n//+x+MjY3B4XCYjjEfwsXFBYWFhTh69CjftpCQECgrK8PGxqbF/Y2MjPDgwQNm2UcAyMrK4ru+wsJCqKmp8V3fhy59SFEURX07eC/FtLW1P0qFad68ebhy5QoSExMFbrezs0NNTQ1qampga2vLt11JSQm2trbYsWMHE9ubev36NQDg6tWruHz5MtLS0lgjBtPT05GTk4Nr16598LVQFEV9bdzc3PDgwQNs3boV169fh4eHB7PNyMgIV65cwdu3b5m0ixcvCnVcYepFqqqqKCkpYb4XFhaiqqpK6LL37t2bWa5IWKtWrUJwcDBTL8rIyIC5uTlmzpyJvn37gsvlslZDUFBQgIaGBuu66+rqkJub2+p5hLk2eXl5TJgwAb///jsOHDiA+Ph4vHz5sl3XI4iZmRnKysqYZd8B4NKlSygrK2ONpB85ciRkZGQQFhaGkydP8i2LS1EURX3dhKknfY46koSEBPT09ASW6X29ePECf/zxB+Li4vhm8qyoqGCW0hUREYGXlxeio6MRGxsLUVFRjB8//qOVg6Ioivr69ejRA+fPn2elZWZmokePHsx3Yd8pAo2r/sXGxmLMmDEQFRX9oNhrZGQEoHEFDi6XC3FxcVZd9dWrV7h9+7bAffv06YOzZ8/i/PnzcHZ2bnEQZlvtsBRFUdTXr66uDnv27EFISAgrFl25cgXa2tqIiYnBpEmTkJKSwiy93nz/yspKod/NtVenTp0we/ZsLFy4UKiBD+Hh4XBxceGrC7q6uiI8PBwAMGnSJFRUVGDnzp0Cj/G+ZaUoivrUaEdQAV68eIEffvgB+/btw99//42ioiIcOnQIQUFBGD16NABAR0cHZ86cQWlpKV69etXisaytrWFmZoYxY8bg1KlTKC4uRmZmJpYvX47Lly8DALhcLhISEphgOWnSJGZWzw/h4uKC//3vf/Dw8EB4eDiKi4vx999/Y9q0aUhKSsLu3btbna3F2toahoaGmDx5Mq5cuYKMjAwsW7aMlcfV1RUqKioYPXo0MjIyUFRUhHPnzsHPz49v5iCKoiiKasmLFy9QWlrK+rx7967F/PLy8sxM3YIqdR06dEBBQQEKCgpYS8w3tXPnTtTX18PU1BTx8fEoLCxEQUEBtm7dyiyRFB4eDlNTUwwZMgS9evViPoMHD4aZmRlTIaQoivov6dSpE8aOHQt/f38MHz4cXbp0YbZNmjQJoqKi8Pb2xo0bN3DixAkEBwcLdVxh6kU//PADtm/fjr/++guXL1/G9OnT2zXAYMmSJcjJycHMmTPx999/4+bNmwgLC8M///zT4j5Dhw5Fz549sWHDBqacly9fxqlTp3D79m2sWLECOTk5rH38/PywceNGJCYm4ubNm5g5c2abjYNtXdvmzZsRFxeHmzdv4vbt2zh06BA4HA6z0kRrSktLkZ+fzyxre/XqVeTn5zOdSHv06AE7Ozv4+Pjg4sWLuHjxInx8fODg4MBaJrBDhw7w9PTEkiVLwOVyWUsKUhRFUd+GtupJn7qOdOzYMbi5ueHYsWO4ffs2bt26heDgYJw4cYJpl23JrVu3+F7kNV9xiWfv3r3MrKNNr6N3795wcHBgXYeXlxeePHmCpUuXwsXFRWB7anV1NV+dtrW/LyiKoqhvh7+/P6KiorBr1y4UFhZi06ZNSEhIwMKFC5k8Lb1TJISgtLQUJSUlKCgoQEREBMzNzaGgoICNGzcCEL590snJCZs3b8alS5dw//59pKWlwdfXFwYGBujevTtkZWXh7e0Nf39/nDlzBteuXYOnpydERVt+Vdy7d2+kpqYiKytL4EqGgHDtsBRFUdTX7dixY3j16hW8vb1ZsahXr15wcnJCeHg45s6dCwsLCwwbNgw7duzAlStXcO/ePRw8eBADBw5EYWEhAOHezb0PX19f3Lp1C/Hx8a3me/78OY4ePQoPDw++a/Hw8EBSUhKeP3+OgQMHIiAgAAsWLEBAQACysrJw//59nDlzBs7Ozh91tQqKoqiPilB83r17RxYvXkz69etHFBQUiLS0NDE0NCTLly8nVVVVhBBCkpKSCJfLJWJiYkRbW5sQQsiqVauIiYkJ3/HKy8vJ7NmziaamJhEXFydaWlrE1dWVPHjwgBBCSFFREbGysiJSUlJES0uLbN++nVhaWhI/Pz/mGNra2mTz5s2s4wIgiYmJzPeioiICgOTl5TFptbW1JDg4mPTs2ZNISkoSeXl5YmtrSzIyMljHaqnst27dIoMHDyYSEhLEwMCAJCcn8523pKSETJ48maioqBBJSUmiq6tLfHx8SFlZWZv3mhBCysrKCACh81MU9d9DnxNfNw8PDzJ69GiB23ixS9Bn//79hBBCIiMjiYKCAt++9+/fJ2JiYuTAgQNtnocQQkaPHk08PDxYaU+ePCG+vr5EW1ubSEhIkM6dO5NRo0aR1NRUUl1dTZSVlUlQUJDA44WEhBAVFRVSXV1NCCEkNTWVACCvXr1q9X4IQn/jFEW15d94TrT0HBX0fDtz5gwBQA4ePMiXPysri5iYmBAJCQnSp08fEh8fz6qntPS8FKZe9PjxYzJ8+HAiIyND9PX1yYkTJ4iCggKJjIxkjtHWudLS0oi5uTmRlJQkioqKxNbWltne0j2IiYkhEhIS5MGDB+Tdu3fE09OTKCgoEEVFRTJjxgyyePFiVn2qtraW+Pn5EXl5eaKoqEjmz59PJk+ezDp2e6/tt99+I3369CEyMjJEXl6eDBs2jPz11198ZRVk1apVAmMt79iEEPLixQvi6upK5OTkiJycHHF1dRUY0+7evUsACIyPzeuKwqJxkKKottDnxL+rpXrSqVOnPnkd6e7du8THx4cYGBgQKSkpoqioSAYMGMCKWc3jfWv1yqKiIkIIf4wyNjYmM2fOFFiG+Ph4IiYmRkpLS5m04cOHEwAkMzOTL7+Hh4fAcxsaGgp1zfT3TVFUW+hz4ssiqK1y586dRFdXl4iLixMDAwOyZ88e1nZB7xQjIyOZmCEiIkIUFBSIqakpWbNmDfN/3Z72yd9++41YWVkRVVVVIiEhQbp27Uo8PT1JcXExk//NmzfEzc2NSEtLE3V1dRIUFMRXN23+nRBCrl+/TjgcDnFwcCDV1dXv1Q7bGvobpyiqLfQ58Xk5ODiQkSNHCtyWm5tLAJDc3Fzy7t07EhgYSIyNjUnHjh2JkpISsbCwIFFRUaS2tpbZp7V3c8IQ1HeGEEJ8fHxIz549SX19vcC+M4QQEhwcTBQVFUlNTQ3f/rW1tURJSYmEhIQwaQcOHCBDhgwhcnJyREZGhvTu3ZusWbNGYNu2oPMJg/6+KYpqS3ueEyKECDE3MkV9QuXl5VBQUEBZWRnk5eU/d3EoivoC0ecE9a2jv3GKotrypT0nYmJi4OfnhydPnkBCQuJzF4f6F124cAFDhw7Fo0ePoK6u/lGO+aX9vimK+vLQ5wT1LaO/b4qi2kKfE9SnNHToUPTp0wehoaGfrQz0N05RVFvoc4L6ltHfN0VRbWnPc0LsXyoTJaSHDx9i9erVOHnyJP755x9oaGhgzJgxWLlyJZSVlQE0VsrOnTvHt++0adOwa9euf7vIH41T2B2Id5T93MUQ6LifwecuAkVRlNAyMzPx/fffw8bGBsnJyaxtNTU1CA0NRUxMDAoLCyEtLQ1DQ0NMmTIFbm5uzBK0paWlWL9+PY4fP47Hjx9DTU0Nffr0wdy5czFs2LA2y6Cjo4P79+8DADp27AhtbW14e3tj4cKFEBERYeWNjo7Gjh07cP36dYiKiqJv374ICAiAg4MDKx8hBL///jvCw8Nx/fp1iImJgcvlws3NDVOnToW0tDRWr16NI0eOID8/n9kvIyMDjo6OcHd3x9atWxEdHQ0vLy8AgKioKOTl5WFgYAB7e3v4+flBQUGB2dfT01Pg8g62trbMvW16rVJSUtDV1cXs2bMxbdq0Nu9Tc19yLKQEo38jUP81VVVVKCoqQmBgIKZNm/af6QT6pcVWUVFRqKurY8SIEQgODkanTp0AAGlpabCysgIAiIiIQE5ODrq6urCxscG8efOgoaHBd9zY2Fi4u7vDx8eHqU/m5uaif//+yMjIwODBgwE0Lnn78OFDrFixAioqKvDx8UFSUpJQsVJYNA42orGFoqgvUfN6XHMeHh6Iiopqdf/ExESMGTOGSYuKihK6bsazYcMGrFixAuvXr8fixYtZ2+rr6xEUFITo6Gjcv38fUlJSMDAwwLRp05jzCENQh5gtW7YgICAAkZGRmDRpEhP/BLXHzpw5E2FhYW3ek+ZoHPw0aFylKKq5L6F+x9NSXNPQ0MDcuXOxaNEiJm3RokUICgpCSkoK6xzDhg2Duro6YmNj23UNvHtx7tw5FBUVMXHv6dOn6NKlCyIjI+Hm5sZX5mnTpiErKwt///03Vq9ejZ9++okvj6GhIW7evCn0feChsfDfQ+MjRVHva9euXfD398erV68gJtbY3aiiogKdOnXCoEGDkJGRweTNyMjAkCFD2jxmZGQkdHR0hG7XFCb+NO1TIyEhAW1tbXh6emLRokXo0KEDAOHeO/I8evQIurq60NXVZc7RUjmaKioqgo6OTpv3APj4cZA+6ynqv0n0cxeA+n/37t1D//79cfv2bezfvx937tzBrl27cObMGZiZmeHly5dMXh8fH5SUlLA+QUFBn7H0FEVR1JciIiICs2fPxvnz5/HgwQMmvaamBra2tti4cSOmTp2KzMxMZGdnw9fXF9u2bcP169cBAMXFxfjuu+9w9uxZBAUF4erVq0hOToaVlRV8fX2FLseaNWtQUlKCgoICLFy4EEuXLsVvv/3GyrNw4UJMmzYN48ePx5UrV5CdnY3vv/8eo0ePxvbt21l53d3dMXfuXIwePRqpqanIz8/HihUr8Mcff+D06dMCy3D8+HHY2trCz88P27ZtY15eysvLo6SkBI8ePUJmZiamTp2KPXv2oE+fPnjy5AnrGHZ2dnwxd//+/QKv9e+//8aYMWMwffp0HDhwQOh7RVEU9bUICgpCnz59oK6ujiVLlnzu4vxrvrTY+uDBA8TExCA9PR2Ojo6QlZWFrKwsRowYAQCQlpaGlJQU1NTUsGjRIqSkpKBXr164evWqwGsLCAhAXFwcqqqqAADfffcdTExMEBkZyeTbv38/DA0N8fz5czx9+hTe3t7MNmFiJUVRFPV1a/qMDw0NZepUvM+WLVuEOk5MTAwTt6ZPnw6gMW517NgRysrKrdbNgMYXhAEBAYiIiODbtnr1aoSGhmLt2rW4ceMGUlNT4ePjg1evXn3Qta9atQpLlixBYmIiJk2axKRraWkhLi4Ob9++ZdLevXuH/fv3o2vXrh90ToqiKOrT+VLqd0DLcW3o0KFITU1lpaWlpUFLS4uVXlNTg6ysLKbjjLDX0PRedO7cGU+ePGHuhbq6Ouzt7Vn1QZ63b98iLi6OVR/s2bMnX33w/Pnz7boPFEVR1NfDysoKFRUVuHz5MpOWkZEBDoeDnJwcpn0RaIxdHA6HFSPGjx/P15Y4YcIEZp9ffvkFUlJSqKurQ0FBAUJCQqCpqQlpaWn07NmTySdM/OH1qbl16xbmzJmD5cuXIzg4mNnenveOUVFRGD9+PKqqqnDhwgUAje84m56/S5cuTPst76OlpfVxbjxFUZSQ6IygXxBfX19ISEjg9OnTkJKSAgB07doVffv2hZ6eHpYtW4awsDAAjQ2kHA7nvc7z6NEjLFy4EKdPn0Z1dTV69OiBHTt2YODAgcxManPmzMHq1avx8uVLuLu7Y/v27QgJCcGmTZvQ0NAAPz8/LFu2jDnm6tWrERERgadPn0JZWRlOTk7YunXrh98UiqIoql0qKytx8OBB5OTkoLS0FFFRUVi5ciUAIDQ0FOnp6bh8+TL69u3L7KOrqwtnZ2fU1NQAaJy9REREBNnZ2ZCRkWHy9ezZEz/++KPQZZGTk2Ni1ZQpUxAWFobTp08zM2VevHgRISEh2Lp1K2bPns3st379erx79w7z58/H6NGjoaWlhYMHDyImJgZHjhzB6NGjmbw6OjoYNWoUysvL+c4fGxsLLy8v/PLLL5gzZw5rm4iICFM2DQ0N9OjRA46OjujZsycCAgKwb98+Jq+kpGSbMbfpta5btw4HDx7EkSNHWJVXiqKob8Hq1auxevXqz12Mf9WXGls7d+6MyZMnIyYmhpkJ+9KlS3Bzc0NGRgbk5eUhLi4ObW1tjB49Gn379sWMGTNYDaLFxcXIzMxEfHw8UlNTcfjwYUyePBkA4O3tjaVLl2Lr1q2QkZGBp6cnPD09sXbtWuzYsQP29vbMcYSJlRRFUdTXrelzXkFBgVWnAoCwsDAEBwfj4cOH6NatG5YvXw53d3cAYGY/+d///gcA0NTUxLlz5xAfH49169YhLy8PAJi41VLd7Ny5c3j79i3WrFmDPXv2ID09nTW7zNGjRzFz5kw4OzszaSYmJqzrqKysxIwZM5CQkAA5OTksXLgQR48eFbgkLiEEc+bMwd69e3H69Glmlmyefv364d69e0hISICrqysAICEhAVpaWtDV1W3X/aUoiqL+HV9S/a61uGZlZYUFCxagrq4OYmJiePPmDfLy8hAaGsrM/Ak01gHfvn3LdAQV9hqa34tVq1ax7oW3tzdGjx6N4uJi1ixmhw8fxrt371gzhYqJidH6IEVR1H+IoaEhNDU1kZaWhkGDBgFo7PDJ60yZmZkJa2trJn3YsGGsOCElJYXq6uoWY8eECRNYK0m8e/cOo0aNQqdOnZCQkMCkCxN/mvapmTVrFv744w8cOXIEixYtatd7R0IIIiMjsXPnTnTp0gXh4eGwsLBgBjnydOjQgdV+S1EU9TnQGUG/EC9fvsSpU6cwc+ZMphMoD4fDgaurKw4cOABCyAedp6KiApaWlnjy5AmSkpJw5coVBAQEoKGhgclz9+5dnDx5EsnJydi/fz8iIiJgb2+PR48e4dy5c/j555+xfPlyXLx4EUBjxW/z5s349ddfUVhYiCNHjsDY2PiDyklRFEW9nwMHDsDQ0BCGhoZwc3NDZGQkEztiYmJgbW3NagTkERcXh4yMDF6+fInk5GT4+vqyGjJ5FBUV210mQgjS0tJQUFDAWnpo//79kJWVFbiE+oIFC1BbW4v4+Him7IaGhqzKGI+IiAjfkoE7duyAl5cXwsPD+TqBtkRNTQ2urq5ISkpCfX19ey6RT8eOHVFbW/tBx6AoiqK+DF9ibAWAx48f49ixYzA3NweXywWXy0Xnzp0BNL7k43K50NbWBtDYwDp9+nRcuHABz549Y47Bq+spKCjAzc0N4eHhzDZXV1fU1tbi0KFDTBohBFFRUfDw8GCWfqIoiqKoxMRE+Pn5YcGCBbh27RqzFDtvxrKcnBwAjbOelZSUID8/H1wuF+rq6ujQoQMTx3hxq6W6WXh4OCZOnAhxcXFMnDiRFbeAxjbUs2fP4vnz5y2W1d/fH6mpqUhMTMTp06eRlpaG3Nxcvnx1dXVwd3fHoUOHcO7cOb5OoDxeXl6sGdMiIiLa1QmIoiiK+nd9SfW71uIab7Y1XgzNyMiAgYEBnJycWLOtpaamokuXLuByuUJfgzD3YuTIkeBwOIiKimIdIyIiAmPGjIGysrLQ10lRFEV9e5rPXJ2amoqhQ4fC0tKSSW8+a7Ww5OTkmDoil8tFr169MGfOHPz11198/WjaS0pKinl31573jqmpqaiqqoK1tTXc3d1x8OBBvHnz5oPKQlEU9anQjqBfiMLCQhBC0KNHD4Hbe/TogVevXjENmTt37mRGGPA+0dHRbZ4nNjYWz58/x5EjRzB48GBwuVyMHz8eZmZmTJ6GhgZERETAyMgIjo6OsLKywq1btxAaGgpDQ0N4eXnB0NAQaWlpAIAHDx6Aw+HA2toaXbt2hampKXx8fFosQ3V1NcrLy1kfiqIo6uMIDw9nRmTb2dmhoqICZ86cAdAYa7p3797q/nfu3AEhpM18wli0aBFkZWUhKSkJKysrZjYVntu3b0NPTw8SEhJ8+2pqakJBQQG3b99mym5oaCjUeQsKCjBr1iyEhYWxRqcLo3v37njz5g1evHjBpB07dowv5q5du1bg/nV1dYiKisLVq1cxbNiwFs9DYyFFUdTX40uMrVJSUujSpQtERESwadMmofblnb+4uBhAY70vKiqKuTYXFxdkZWXhzp07AAAlJSWMGTOG1bklLS0N9+7d4+vg0p5YCdA4SFEU9a0JDg6Gp6cnZs6cCQMDA8yfPx9jx479P/buPC7H7P8f+OvWpk206JZUKpWSsu/VbcvOzFhCFIUZMRoj+27Ix2g0lhjmrpgpFWUYQ0x0a2MkRQihMFONGVIqWs/vj35d3y73Xd1ZY97Px+P+o3Od65xz3e7H9XbOda5zuC339PT0AFRPjhEKhdzf9Xm5b1ZYWIjIyEgubrm6uuLw4cO8GPLdd9/hn3/+gVAoROfOnfH555/j5MmT3PGioiKIxWJs3boVQ4YMga2tLfbv3y/zRcB9+/bh0KFDkEgkUquK1jZt2jQkJCQgOzsb9+/fR2JiYoP9UIqDhBDy/jSV/l1Dca1Dhw5o27Yt9xxOIpHA0dERrVu3hqmpKbclrUQi4U2wkecaatT3XSgoKGD69OkIDg7mJodmZWXh3LlzvG3hASA9PV2qP+jp6Vlv3RQLCSHkw+bk5ITExERUVFRwq1Y7ODjA0dGRi10XLlzgrVr9Ol4e1wQaF3+qqqoQHR2NU6dOcc/uGvPcUSwWw8XFBQoKCrCxsYG5uTnCw8Nf+XooDhJC3iaaCPqBqOlo1UyWmTp1KtLS0nifmu2V6pOWloYuXbpAW1u7zjwmJibQ1NTk/tbX14e1tTWaNWvGS6tZSWbChAl4/vw5TE1NMWvWLBw5cgQVFRV1lu/r6wstLS3u065duwbbTQghpGG3bt3CxYsX4eLiAqB6W4RJkyYhMDAQQHUsEQgE9ZZRE28ayicPHx8fpKWl4dy5cxCJRFixYgX69u0r9/m12ytP22sYGhqia9eu2LJlC3JzcxvVZlnXLxKJpGKul5cX77zaE3O8vLzg4+Mjc6XTGhQLCSHkw9BUY+vVq1e5B3QjR46UayXrl9tx+vRpFBcXY/jw4QAAXV1dDB06lLs2oHo7wLi4OG5yaGBgIPr16yc1SCpPrKyN4iAhhHxcMjIy0K9fP15av379kJGR8cplvhy3QkNDYWpqyk3KtLe3h6mpKcLCwrhzrK2tce3aNVy4cAEzZszA33//jdGjR3MPA+/evYuysjLeC/Ha2toyH/71798fGhoaWLlyZb3jnLq6uhg5ciT279+PoKAgjBw5Erq6uvVeG8VBQgh5P5pS/06euObk5MSbCOrk5AQA3CSb0tJSXLhwAQMHDuS1T562NfRdANX9wfv37+Ps2bMAqvuDhoaG3Ha/NSwtLaX6gxs3bqy3foqFhBDyYROJRCguLkZycjK3anXr1q3h6OiI5ORkFBcXQyKRwMjICKampq9dn6z4K0/8qVlcrXnz5hgzZgxcXV2xZs0arkx5YubTp08RFRXFe+HP1dWVFzMbi+IgIeRtor3cmghzc3MIBALcuHED48aNkzp+8+ZN6OnpcdtKaGlpcVs9NIY8y2XX3rYXqA6ostJqtpNv164dbt26hd9//x0xMTGYO3cuvv32W5w7d07qPABYtmwZFi5cyP1dWFhIwY0QQt4AsViMiooKbltYoLojo6SkhPz8fFhYWDT4IK5Dhw4QCATIyMiQGY8aQ1dXl9u6ITIyEubm5ujduzc3WGhhYYGEhASUlZVJrQqak5ODwsJCdOjQgcsr70NETU1NxMTEYOjQodz2FAYGBnKdm5GRgRYtWvC2N1JXV28w5vr4+MDd3R1qampo06ZNg51HioWEEPJhaKqxtaZcf39/9OnTB7GxsVIP415W004TExMA1Q/xnjx5AjU1NS5PVVUVUlNTsWHDBigoKGDw4MEwNjZGcHAwFi9ejKioKOzcuVOqbHliZW0UBwkh5OPzch+oMS/zyfJy3ywwMBDXr1+HouL/DWdXVVVBLBZj9uzZXFqzZs3Qo0cP9OjRA1999RV+/vlnTJs2DStWrOAeHsrD1tYWfn5+GDx4MCZOnIjw8HCZ45wAMHPmTMybNw8AsGvXrgbLpjhICCHvR1Pq38kT10QiERYsWIDHjx9zK60B1RNBd+zYgaFDh0qttCbvGGpD30WrVq3QoUMHDBgwAEFBQRCJRNi/fz9mzJjBWzQGqF7AprHPKykWEkLIh83c3ByGhoaIjY1Ffn4+HB0dAQBCoRDt27dHYmIiYmNjeS8rvI6XxzUB+eLP1KlTsWLFCqioqMDAwAAKCgrcMXljZmhoKF68eIFevXpxaYwxVFVV4caNG7C2tm7k1VAcJIS8XbQiaBOho6ODIUOGICAgAM+fP+cdy8vLQ0hICNzd3V+7ns6dOyMtLQ1Pnjx57bJqU1VVxZgxY7B9+3ZIJBKcP38e6enpMvOqqKigRYsWvA8hhJDXU1FRgQMHDsDPz4/39tuVK1dgbGyMkJAQTJkyBTExMUhNTZV5fnFxMbS1teHs7Ixdu3ahuLhYKt/Tp09fqX2tWrXC/PnzsWjRIu7hm4uLC4qKivDDDz9I5d+6dSuUlJTw2WefAQCmTJmC27dv4+jRo1J5GWMoKCiQqi8mJgatWrWCk5MT/vrrrwbb+OjRI4SGhmLcuHFSA5oNqZmYY2BgINfDToqFhBDS9DX12AqAG7x8uQ/5sufPn2Pv3r1wcHCAnp4eHj9+jKNHjyIsLEzqzfmioiJuG12BQIAZM2Zg//79CA0NRbNmzTBx4sRXbm8NioOEEPJx6dixIxISEnhpSUlJ6NixI/e3kpKSXCtYA9J9s/T0dFy6dAkSiYQXs+Li4pCcnIxr167VWVbNQ7ni4mKYm5tDSUkJFy5c4I7n5+fj9u3bMs+1t7fH2bNnkZCQgAkTJqC8vFxmvmHDhqGsrAxlZWVwdnZu8PooDhJCyLvXlPp38sa1mtXWvvvuO3To0AH6+voAqieCXrp0Cb/99hvat28PY2Njrmx5rkGe76KGh4cHoqKiEBkZiT///BMzZsxo8PrkQbGQEEI+fCKRCBKJhLdqNVAdp06dOoULFy68kW3hXx7XbIyaxdXatWvHmwQKyP/cUSwW4+uvv5aKmSKR6JVXBaU4SAh5m2giaBOyc+dOlJaWwtnZGXFxcXj48CGio6MxZMgQWFhYYPXq1VzekpIS5OXl8T75+fkN1jF58mQIhUKMGzcOiYmJuHfvHiIjI3H+/PlXbndwcDDEYjGuXbuGe/fu4aeffoKqqiqv80kIIeTtOn78OPLz8+Hh4YFOnTrxPuPHj4dYLIa3tzf69euHQYMGYdeuXbhy5Qru3buHiIgI9OrVC5mZmQCqt0qorKxEz549ERkZiczMTGRkZGD79u28LfQay8vLC7du3UJkZCQAoE+fPliwYAF8fHzg5+eHu3fv4ubNm1i5ciW+//57+Pn5cW/ATZw4EZMmTcLkyZPh6+uLS5cu4f79+zh+/DgGDx6M2NhYqfq0tLRw+vRp6OrqwsnJCX/++Sd3jDGGvLw85ObmIiMjA4GBgejbty+0tLSwefNmXjmlpaVSMffff/995e+BEELIh6EpxtZnz55x8evixYvw8fGBrq4u+vbty8v36NEj5OXlITMzE2FhYejXrx/+/fdf7N69GwDw008/QUdHBxMmTOBdV+fOnTFq1CiIxWKurBkzZiAnJwfLly+Hi4sL1NXVpdpFsZIQQv7bfHx8EBwcjD179iAzMxPfffcdoqKisGjRIi6PiYkJzpw5IzWGKU/fTCwWo2fPnnBwcODFrf79+6NPnz5c3Bo/fjy2bduGP/74A/fv34dEIoGXlxcsLCxgZWUFDQ0NeHh4wMfHB2fOnMG1a9fg7u5e74uAnTt3RmxsLM6fP4/x48ejrKxMKo+CggIyMjKQkZEh9XCREEJI09CU+nfyxjVTU1MYGRlhx44d3EprAGBgYABjY2Ps2bNHaoKNPNcgz3dRY8KECVBSUsKcOXMwaNAg3kpsNSoqKqT6g3///fer/DMRQgj5gIhEIiQkJCAtLY0XpxwdHbFv3z68ePHilSaCNjSuWeN14488zx3T0tJw+fJleHp6SsXMyZMn48CBA3W+MEgIIe8NI01KVlYWc3NzY/r6+kwgEDAA7NNPP2XFxcVcHkdHRwZA6uPs7CxXHdnZ2eyzzz5jLVq0YGpqaqx79+7sjz/+YIwxtmbNGmZnZ8fL7+bmxsaOHctLc3R0ZAsWLGCMMXbkyBHWq1cv1qJFC6aurs569+7NYmJi5L7mgoICBoAVFBTIfQ4h5L+F7hMNGzVqFBsxYoTMYykpKQwAS0lJYS9evGC+vr7M1taWNW/enGlra7N+/fqx4OBgVl5ezp2Tk5PDvLy8mLGxMVNWVmZt27ZlY8aMYbGxsXK1x9jYmG3btk0qfdasWczGxoZVVlZyaWKxmHXv3p2pqqoyNTU11r9/f3bs2DGpcysrK9nu3btZjx49mJqaGmvRogXr1q0b+/7771lJSQljTHYcKywsZP369WNmZmbswYMHLCgoiIudAoGAaWlpsZ49e7L169dL/cbc3NxkxlxLS8sGr7Ux6DdOCGkI3SfevaYYW2vHIj09PTZixAiWmprK5YmNjeXFOE1NTWZnZ8d8fHxYbm4ul8/W1pbNnTtXZj2RkZFMUVGR5eXlcWlDhw5lAFhSUpJUfnliZUPo900IaQjdJ5qWoKAgpqWlxUsLCAhgpqamTElJiVlYWLADBw7wjh87doyZm5szRUVFZmxszJXTUN+stLSU6ejosC1btshsi5+fH9PV1WWlpaVs7969TCQSMT09PaasrMyMjIyYu7s7y87O5vI/e/aMubq6MjU1Naavr8+2bNnCG+dkjEn9zRhj169fZ0KhkI0aNYqVlpbKHC+tbezYsczNza3e77EG/b4JIQ2h+8Trayr9u8bENcb+r78VFhbGy+fh4cEAsJ9++kmqjIauQd7vosbs2bMZABYaGiqVf82aNTL7gyoqKvV+Dy+j3zghpCF0n2h6srKyGABmZWXFS3/48CEDwMzMzGSeV1dfSt5xTcbkiz+y+nUva+i547x585i1tbXMcx89esQUFBRYZGQkl/aqzwvp900IaUhj7hMCxv7//qykSVqzZg2+++47nD59+rVWYWvKCgsLoaWlhYKCAlr2mhAiE90nyMeOfuOEkIbQfYJ8zOj3TQhpCN0nyNvk5OQEe3t7+Pv7v5f66fdNCGkI3SfIx45+44SQhtB9gnzM6PdNCGlIY+4Tiu+oTeQVrVu3DiYmJvjjjz/Qq1evercq+tCN330HSs013nczAAC/LbB4300ghPzHZGdno3379khNTYW9vf07rUsikUAkEiE/Px8tW7Z8q3U3xN3dHU+fPsUvv/wC4P0/kHvXmlIsJPKh/zMQQsib81+MgxRHCCGE1PgvxsE3iWIqIYR8+CgWvl0UKwkhpGl7k3GQ7vmE/Hd9vLMK35I9e/ZAU1MTFRUVXFpRURGUlJQwYMAAXt74+HgIBIIGP8HBwZBIJNzfzZo1g5aWFrp06YLFixdj2LBh8Pb25iaBrl27VmY5VlZW2LRpEzQ0NKCgoMA71qxZM1hYWKCyspJrH2MMe/fuRa9evaChoYGWLVuie/fu8Pf3R0lJCe9a/vzzTygrK8PKyopLq6sdtT/Z2dlv4V+BEELeH3d3d4wbN04qveY+/vTp03feptfVt29f5ObmQktLS678Dg4OUjFGSUkJGhoasLGxeaNti4qKwoYNG95omXVxcnKSimMuLi7vpG5CCCEfjqSkJCgoKGDYsGFSx8rKyrBlyxbY2dlBTU0Nurq66NevH4KCglBeXs7ly8vLw/z582FqagoVFRXo6OhAUVERqqqq0NDQ4H1kxVYTExPeSxKMMXz99dfQ1NTE2bNnAciOawKBgNeXnT17NhQUFBAWFibzWu/cuYMZM2bA0NAQKioqaN++PSZPnoxLly4hODi4wf6gRCJ5xW+ZEEJIU/Y2YmG7du0wevRonDlzRq42vMlYeO7cOdy6dUtmPRQLCSHkw/W+4lVISAjXn2vWrBkEAgHU1NR4/Ttvb284OTnxznvy5Am8vb1hYmICZWVltGnTBjNmzMCDBw94+eLi4jB69GgYGBhAIBBwL9TXxhjD2rVrYWBgAFVVVTg5OeH69esy27tp0yYoKChg8+bNXFpkZCQUFBSk6q5hZWWFL7/8EkDd8fbzzz+v8zsihBBCamsKfcyadowYMQKtWrVC8+bNYWtrCz8/P94cGwBcrLtw4QIvvbS0FDo6OtQXJIS8VzQRtJFEIhGKiopw6dIlLi0+Ph5CoRDJycm8CZQSiQRCoRC5ubncZ+LEiRg2bBgvbdKkSdw5t27dQk5ODpKTk7FkyRLExMSgU6dOSE9P57XDxsaGV0Zubi4SEhLw+eefIy0tDd27d8fEiRORlJSE2NhYrFq1CpmZmdi6dStXxrRp0+Dt7Y2xY8ciNjYWaWlpWLVqFY4ePYrTp0/z6gsODsbEiRNRUlKCxMREAMCiRYt49RsaGmL9+vW8tHbt2r3R758QQv6rGGO8h1VvkrKyMoRCIQQCgVz527VrhwEDBiApKQlxcXEQi8XQ0dGBk5MTTpw48Ubbpq2tDU1NzTdaZn1mzZrFi2M//PDDa5VXVlb2hlpGCCGkqQgMDMT8+fORkJDAeyhWVlYGZ2dnbN68GbNnz0ZSUhIuXrwILy8v7Nixg3volp2djW7duuHs2bPYsmUL0tPTcfLkSSxevBht2rRBWloa79NQbK2srISHhwcOHDiAs2fPYuDAgdyxl+Nabm4uFBWrNwYpKSlBeHg4fHx8IBaLpcq9dOkSunXrhtu3b+OHH37AjRs3cOTIEVhZWeHrr7/GpEmTeOX26dNHqr6+ffu+ia+cEEJIE/M2YmF0dDREIhG8vLwa3Z7XjYVLliyR2d+mWEgIIR+29xWvxowZw/Xn2rRpA2VlZXTq1Kne/t2TJ0/Qu3dvxMTEICAgAHfu3EF4eDju3r2LHj164N69e1ze4uJi2NnZYefOnXW2YcuWLfjuu++wc+dOJCcnQygUYsiQIXj27JlU3qCgICxevBiBgYG8a9DR0cH+/ful8icmJuLWrVvw8PDg0mTF2y1bttTZPkIIIaS2ptDHPHLkCBwdHWFoaIjY2FjcvHkTCxYswMaNG+Hi4gLGGC9/u3btEBQUJFWGhgatbE0Ieb9oa/hGsrS0hIGBASQSCXr37g2gesJnzWTKpKQkDB48mEsfNGgQhEIhd76qqipKS0t5abW1bt0aLVu2hFAohIWFBcaOHYsuXbrgiy++QEJCApdPUVGxzjK0tbWhqqqKNm3aoE+fPgCq38hLSkrCL7/8giVLliAiIgIhISH45ZdfMHbsWO5cExMTjBkzBoWFhVwaYwxBQUEICAiAoaEhxGIx+vXrx73RWENBQQGampp1tosQQv4LiouLYWRkhMDAQIwfP55L//XXX+Hi4oK8vDxoamri4sWLmDNnDjIyMtCpUyesWLGCV07Ndu3R0dFYsWIFrl69ilOnTsHIyAgLFy7EhQsXUFxcjI4dO8LX15eLPUD1m2hHjhzhrVzasmVL+Pv7w93dXarNsraGT0xMxPLly5GcnAwVFRX07NkTYWFhaNWqFZSUlKCtrc3FmAEDBuDatWsIDg6GsbExgOoHcbNnz8bZs2eRl5cHIyMjzJ07FwsWLODqrayshI+PDwIDA6GgoAAPDw+pjtTLW8M3dG1lZWVYuHAhIiMjkZ+fD6FQiDlz5mDZsmVy/fupqanVGccGDhwIa2tr3iDr48ePYWBggJMnT2LgwIEwMTGBp6cn7ty5w7VT1oApIYSQD1NxcTEiIiKQnJyMvLw8BAcHY/Xq1QAAf39/xMXF4dKlS+jSpQt3jqmpKSZMmMC9HDB37lwIBAJcvHgR6urqXL6ePXti8eLFXCyWR2lpKSZPnozk5GTExcWhY8eOvOP1xbVDhw7B2toay5YtQ5s2bZCdnQ0TExMA1X1Ad3d3dOjQAfHx8dzuFABgb2+PBQsWQFVVFaqqqly6srJyvfURQgj5OLzNWGhjY4OZM2c2qj0UCwkhhMjyPuOVpqYm92K7kpISvvjiC+zevRu3b9/GiBEjZJ6zYsUK5OTk4M6dO1wcMTIywqlTp9ChQwd4eXnh5MmTAIDhw4dj+PDhddbPGIO/vz9WrFiBTz/9FACwf/9+6OvrIzQ0FHPmzOHynjt3Ds+fP8f69etx4MABxMXFwcHBAUpKSpg2bRqCg4OxcuVK3gICgYGB6NatG+zs7Lg0in+EEEJeVVPoYxYXF2PWrFkYM2YM9u7dy6V7enpCX18fY8aMQUREBG+BNzc3N2zfvh3+/v5cvzAwMBBubm7vbKdDQgiRhVYEfQVOTk6IjY3l/o6NjYWTkxMcHR259LKyMpw/fx4ikei16lJVVcXnn3+OxMREPHr06LXLqlkeOyQkBJaWlrxJoDUEAgFve+DY2FiUlJRg8ODBmDZtGiIiImS+NSiv0tJSFBYW8j6EEPKxUFdXh4uLi9RbYEFBQRg/fjw0NTVRXFyMUaNGwdLSEikpKVi7di0WLVoks7zFixfD19cXGRkZ6Ny5M4qKijBixAjExMQgNTUVzs7OGD16dJ3b9LyKtLQ0DBo0CDY2Njh//jwSEhIwevRoqa0Paty7dw/R0dFQUlLi0qqqqmBoaIiIiAjcuHEDq1evxvLlyxEREcHl8fPzQ2BgIMRiMRISEvDkyRMcOXLktdq+fft2HDt2DBEREbh16xZ+/vln7kGePEJCQqCrqwsbGxssWrSIF+88PT0RGhqK0tJSXn4DAwNevP/222/RqVMnpKSkYNWqVTLroVhICCEfpvDwcFhaWsLS0hKurq4ICgriXmIICQnB4MGDeYOSNZSUlKCuro4nT54gOjoaXl5evEHJGo2ZBFpUVISRI0fi+vXrSExMlJr40hCxWAxXV1doaWlhxIgRvP+7pKWl4fr16/j66695E19epZ2yUBwkhJAPF8XCxrfzZRQHCSHk7WtK8crExASff/45li1bhqqqKqnjVVVVCAsLw9SpU6UmU6qqqmLu3Lk4deoUnjx5Ild9WVlZyMvLw9ChQ7k0FRUVODo6IikpiZdXLBZj8uTJUFJSwuTJk3m7RXh4eODevXs4d+4cl1YzWaf2aqCvgmIhIYSQGk0hZp8+fRqPHz+W+ax29OjRsLCwwMGDB3np3bp1Q/v27REZGQkAePjwIeLi4jBt2rQG66M4SAh5m2gi6CtwcnJCYmIiKioq8OzZM6SmpsLBwQGOjo6QSCQAgAsXLuD58+evPREUAKysrABUL2ldIz09nVuRs+bj6ekp8/yqqipER0fj1KlTGDRoEAAgMzMTlpaWctUvFovh4uICBQUF2NjYwNzcHOHh4a98Pb6+vtDS0uI+tH08IeRDc/z4cal7cO23sD09PXHq1Cnk5OQAAP79918cP36ce+ssJCQElZWVCAwMhI2NDUaNGgUfHx+Zda1fvx5DhgyBmZkZdHR0YGdnhzlz5sDW1hYdOnTAN998A1NTUxw7duyNXd+WLVvQvXt3BAQEwM7ODjY2Npg3bx50dXWlvgNVVVWYmZnhxo0bWLJkCXdcSUkJ69atQ48ePdC+fXtMnToV7u7uvImg/v7+WLZsGT777DN07NgRe/bs4b2I8CoePHiADh06oH///jA2Nkb//v0xefJkuc6dOnUqDh48CIlEglWrViEyMpJ7ax4APvvsMwgEAhw9epRLCwoKgru7O++t+IEDB2LRokUwNzeHubm5zLooFhJCyIepZsIIAAwbNgxFRUU4c+YMgOo+Vk3frS537twBY6zBfPLYsGED0tLSEB8fDyMjI5l5AgICeP9f+frrr7m2XrhwgXuLvWaQteahZGZmJgC8kXbKQnGQEEI+XBQLXx/FQUIIefuaUrwCgJUrVyIrKwshISFSx/755x88ffq0zhcaOnbsCMYY7ty5I1ddeXl5AAB9fX1eur6+PncMAAoLCxEZGcl9T66urjh8+DA3GcXa2hq9evXivSgRERGByspKqfHWl+OthoZGvbskUSwkhBBSoynE7Nu3bwNAnbHYysqKy1PbjBkzEBgYCKD6eeGIESOgp6fXYH0UBwkhbxNNBH0FIpEIxcXFSE5ORnx8PCwsLNC6dWs4OjoiOTkZxcXFkEgkMDIygqmp6WvXV/PGQ+1JJpaWlkhLS+N9Nm7cyDuvpuPVvHlzjBkzBq6urlizZg1XZu3y6vL06VNERUVxwReo7gzWBLRXsWzZMhQUFHCfhw8fvnJZhBDyPohEIql78I8//sgd79mzJ2xsbHDgwAEAwE8//QQjIyM4ODgAADIyMmBnZwc1NTXunJpt1l/WvXt33t/FxcVYvHgxrK2t0bJlS2hoaODmzZtvZUXQ+tR8B3/88Qfmz58PZ2dnzJ8/n5dnz5496N69O/T09KChoYF9+/Zx7SwoKEBubi7vuhUVFaWut7Hc3d2RlpYGS0tLfPnllzh9+rTc586aNQuDBw9Gp06d4OLigsOHDyMmJgaXL18GUP3mfO0YmJaWhitXrsDd3Z1XjjzXQLGQEEI+PLdu3cLFixfh4uICoDpuTZo0iYsL8vSxZPXtXtXQoUNRXFyMTZs21Zln6tSpvP+vLFu2DED1AKuzszP3kseIESNQXFyMmJiYN95OWSgOEkLIh4li4ZtBcZAQQt6uphavAEBPTw+LFi3C6tWruW1s5fWqbXk5/8vXHRoaClNTU26Ld3t7e5iamiIsLIzL4+HhgcOHD3O7JgUGBuLTTz+VWl3t5XiblpaGTz75pM62USwkhBACNL2YXVOWrHRZ5bu6uuL8+fO4d+8egoOD5dqGHqA4SAh5uxTfdwM+RObm5jA0NERsbCzy8/Ph6OgIABAKhWjfvj0SExMRGxuLgQMHvpH6MjIyAIC3ta2ysnKdq4zVmDp1KlasWAEVFRUYGBhAQUGBO2ZhYcGVW5/Q0FC8ePECvXr14tIYY6iqqsKNGzdgbW3dyKupnkijoqLS6PMIIaSpUFdXl7oH//nnn7y/PT09sXPnTixduhRBQUGYMWMG10moqyNRV121+fj44NSpU9i6dSvMzc2hqqqK8ePH8wYQBQKBVB3l5eVy16mqqipXu2q+g+3bt0MkEmHdunXYsGEDgOq3w7/66iv4+fmhT58+0NTUxLfffos//vhD7nbI0tC1de3aFVlZWTh58iRiYmIwceJEDB48GIcPH250XV27doWSkhIyMzPRtWtXANX/rvb29vjzzz8RGBiIQYMGwdjYmHeerK0nXkaxkBBCPjxisRgVFRVo27Ytl8YYg5KSEvLz8+XqY3Xo0AECgQAZGRkYN27ca7Vn0KBB+PLLLzF27FhUVlZix44dUnm0tLSk/s9SWVmJAwcOIC8vD4qKirx0sViMoUOHwsLCAkB1X9Te3v612ikLxUFCCPkwUSx8MygOEkLI29XU4lWNhQsXIiAgAAEBAbx0PT09tGzZEjdu3JB53s2bNyEQCGBmZiZXPTXby+fl5aFNmzZc+qNHj3irhAYGBuL69eu8WFhVVQWxWIzZs2cDAFxcXPDVV18hPDwcTk5OSEhIwPr166XqlBVv60OxkBBCCNB0Ynbt/l/fvn2ljt+8eVPmvBgdHR2MGjUKHh4eePHiBYYPH869PFEfioOEkLeJVgR9RSKRCBKJBBKJBE5OTly6o6MjTp06hQsXLryRbeGfP3+OvXv3wsHBQa5lpGur6Xi1a9eONwkUAKZMmYLbt2/ztretwRhDQUEBgOrg+/XXX/Pe4rty5QpEItFrrQpKCCEfO1dXVzx48ADbt2/H9evX4ebmxh2ztrbGlStX8Pz5cy7twoULcpUbHx8Pd3d3fPLJJ7C1tYVQKER2djYvj56eHnJzc7m/MzMzUVJSInfbO3fuzG27IK81a9Zg69atyMnJ4drZt29fzJ07F126dIG5uTnu3r3L5dfS0kKbNm14111RUYGUlJR665Hn2lq0aIFJkyZh3759CA8PR2RkJJ48edKo6wGA69evo7y8nDdgamtri+7du2Pfvn0IDQ2V++0+QgghH7aKigocOHAAfn5+Un0jY2NjhISEYMqUKYiJiUFqaqrM84uLi6GtrQ1nZ2fs2rULxcXFUvmePn3aqHYNGTIEx48fR2BgILy8vOR62eTEiRN49uwZUlNTeddy6NAh/PLLL3j8+DHs7e1hbW0NPz8/bovc12knIYSQDx/FwtdrJyGEkHejqcYrANDQ0MCqVauwceNGbvt1AGjWrBkmTpyI0NBQ3tbtQPUzwoCAADg7O0NbW1uuetq3bw+hUIjff/+dSysrK8O5c+e4yS3p6em4dOkSJBIJ73uKi4tDcnIyrl27BgDQ1NTEhAkTEBQUhMDAQJiamvKeiRJCCCGvqinF7KFDh0JbWxt+fn5Sx44dO4bMzExMnjxZ5rkzZ86ERCLB9OnTpebkEELI+0ATQV+RSCRCQkIC0tLSuBVBgeqJoPv27cOLFy9eaSLoo0ePkJeXh8zMTISFhaFfv374999/sXv3bl6+iooK5OXl8T5///233PVMnDgRkyZNwuTJk+Hr64tLly7h/v37OH78OAYPHozY2FikpaXh8uXL8PT0RKdOnXifyZMn48CBA41aYY4QQv5LWrVqhU8//RQ+Pj4YOnQoDA0NuWNTpkxBs2bN4OHhgRs3buDEiRPYunWrXOWam5sjKiqK6wxNmTJF6qHUwIEDsXPnTly+fBmXLl3C559/DiUlJbnbvmzZMiQnJ2Pu3Lm4evUqbt68id27d+Pff/+t8xwnJyfY2NhwW/KZm5vj0qVLOHXqFG7fvo1Vq1YhOTmZd86CBQuwefNmHDlyBDdv3sTcuXMb7JA1dG3btm1DWFgYbt68idu3b+PQoUMQCoVS2xW97O7du1i/fj0uXbqE7OxsnDhxAhMmTECXLl3Qr18/Xl5PT09s3rwZlZWV9W5xRAgh5ONx/Phx5Ofnw8PDQ6pvNH78eIjFYnh7e6Nfv34YNGgQdu3ahStXruDevXuIiIhAr169kJmZCQAICAhAZWUlevbsicjISGRmZiIjIwPbt29Hnz59Gt22gQMH4rfffsP+/fvlmgAjFosxcuRI2NnZ8a7js88+g56eHn7++WcIBAIEBQXh9u3bcHBwwIkTJ3Dv3j1cvXoVGzduxNixY1/peySEEPLholhIsZAQQj4ETTleAcDs2bOhpaWFgwcP8tI3btwIoVCIIUOG4OTJk3j48CHi4uLg7OyM8vJy7Nq1i8tbVFTETZYBgKysLKSlpeHBgwcAqndU8vb2xqZNm3DkyBFcu3YN7u7uUFNTw5QpUwBUx8KePXvCwcGB9x31798fffr0gVgs5urz8PBAUlISdu/ejZkzZ8rcGrekpETqmWV+fv4rfUeEEEL+G5pSzFZXV8cPP/yAo0ePYvbs2bh69Sqys7MhFovh7u6O8ePHY+LEiTLPHTZsGP755x+ZK2YTQsh7wcgrycrKYgCYlZUVL/3hw4cMADMzM5N5npubGxs7dqxUemxsLAPAADCBQMA0NTWZnZ0d8/HxYbm5uby8a9as4fLW/qioqHB5HB0d2YIFC+q9hsrKSrZ7927Wo0cPpqamxlq0aMG6devGvv/+e1ZSUsLmzZvHrK2tZZ776NEjpqCgwCIjI7k0Y2Njtm3btnrrlKWgoIABYAUFBY0+lxDy39CU7hMN3cfz8/O5tDNnzjAALCIiQir/+fPnmZ2dHVNWVmb29vYsMjKSAWCpqal1lsdYdfwRiURMVVWVtWvXju3cuVPqnv/XX3+xoUOHMnV1ddahQwd24sQJpqWlxYKCgrgyGqpLIpGwvn37MhUVFdayZUvm7OzMHa/rOwgJCWHKysrswYMH7MWLF8zd3Z1paWmxli1bsi+++IItXbqU2dnZcfnLy8vZggULWIsWLVjLli3ZwoUL2fTp03llN/ba9u7dy+zt7Zm6ujpr0aIFGzRoELt8+bJUW1/24MED5uDgwLS1tZmysjIzMzNjX375JXv8+LFU3mfPnjE1NTU2d+5cqWMUCwkhbwvdJ96vUaNGsREjRsg8lpKSwgCwlJQU9uLFC+br68tsbW1Z8+bNmba2NuvXrx8LDg5m5eXl3Dk5OTnMy8uLGRsbM2VlZda2bVs2ZswYFhsbK1d7ZMWbc+fOMQ0NDTZnzhxWVVUls0+Yl5fHFBUVZf7fhDHG5s+fz2xtbbm/b926xaZPn84MDAyYsrIyMzY2ZpMnT5YZW+Xpg9aFft+EkIbQfeL9o1j49mIh/b4JIQ2h+4T8PoR4FRoaygAwR0dHXvo///zD5s+fz9q1a8cUFRWZvr4+c3NzY/fv3+flq/08sfbHzc2Ny1NVVcXWrFnDhEIhU1FRYQ4ODiw9PZ0xxlhpaSnT0dFhW7ZskdlmPz8/pqury0pLS7k0S0tL1qxZM/bw4UOp/I6OjjLb4+zsLNd3xBj9xgkhDaP7xMenqcVsxhiLi4tjw4YNY1paWkxZWZlZW1uzrVu3soqKCl4+AOzIkSMyy8jPz2cAGlUv/b4JIQ1pzH1CwJgc++UQ8hYVFhZCS0sLBQUFaNGixftuDiGkCfpQ7xMhISFYsGABcnJyoKys/L6bQ96Qhw8fwsTEBMnJyejatesbKfND/Y0TQt4duk+Qjxn9vgkhDaH7BPmY0e+bENIQuk+Qjx39xgkhDfnY7xPZ2dlo3749UlNTYW9v/07rkkgkEIlEyM/Pb3B3vbfN3d0dT58+xS+//AKgejdCe3t7+Pv7v9d2vW0f+++bEPL6GnOfUHxHbfpoJCUlYcCAARgyZAiio6N5x8rKyuDv74+QkBBkZmZCTU0NlpaW8PT0hKurK7d1bV5eHjZu3IjffvsNf/31F1q3bg17e3t4e3tj0KBBDbbBxMQE9+/fBwA0b94cxsbG8PDwwKJFi7gtGWoC+MumTp2Kn3/+GQDw/PlzGBgYQCAQ4K+//oKqqqpU/sjISOzYsQOpqamorKyEqakpxo8fj3nz5uHTTz/FuXPn6mynsbExsrOzG7yeGuN334FScw25878tvy2weN9NIIR84EpKSpCVlQVfX1/MmTPng58E2tRiX7NmzaCvr4/hw4dj69ataNWqFQBwnVWgegskTU1NmJqaYsiQIfjqq6/Qpk0bqXJDQ0Mxbdo0zJo1C3v27AEApKSkoHv37oiPj0f//v25vOXl5cjNzUWvXr2gpaWFrl27wt3dHfv375cq19nZWeq7kkdTiYVEfvT/BkL+e5paXKQ+4YeLYggh5EO0Z88e+Pj4ID8/H4qK1UPLRUVFaNWqFXr37o34+Hgub3x8PBwcHBosMygoCCYmJnL359auXYt169ZJlWNpaYmbN28CqH5gWBOjlJWVYWxsDHd3dyxZsgQKCgoAAMYY9u3bB7FYjOvXr0NRURHm5uZwdXXF7NmzoaamxpX9559/wtTUFKamplwddbWjtqysLJiYmDT4HQD/vTj4plA8JeS/qSn1y86fP4/evXtz6d7e3khLS4NEIuHSnjx5gvXr1+OXX35BTk4OdHR0MGzYMKxbtw5GRkZcPl9fX0RFReHmzZtQVVVF37598b///Q+WlpZcHsYY1q1bh7179yI/Px+9evXCrl27YGNjw+UpLS3FokWLcPDgQTx//hyDBg1CQEAADA0Npa5j9uzZEIvFCAkJgYuLCwDAz88P69evR25uLi8eAsCLFy8gFAqxevVqLFy4kNc/rc3X1xdLly5t8HusjWLh66O4SMjb9fJExRpNaTJlY/Xt2xe5ubnQ0tKSK3/t52IKCgowMDDAyJEjsWnTJu553ZsSFRXFxe236cmTJ1izZg1Onz6Nhw8fQldXF+PGjcOGDRvk/l7ehNeJg3T/J4TUaPa+G/ChCQwMxPz585GQkIAHDx5w6WVlZXB2dsbmzZsxe/ZsJCUl4eLFi/Dy8sKOHTtw/fp1ANUP47p164azZ89iy5YtSE9PR3R0NEQiEby8vORuR00HLCMjA4sWLcLy5cuxd+9eqXwxMTHIzc3lPrt27eKORUZGolOnTrC2tkZUVJTUuStWrMCkSZPQo0cPnDx5EteuXYOfnx+uXLmCn376CVFRUVy5Fy9elKovOTlZ7ushhJCPyZYtW2Bvbw99fX0sW7bsfTfntTW12PfgwQOEhIQgLi4OX375pVS+W7duIScnB8nJyViyZAliYmLQoUMHqKmpQUNDg/eZPn06tLW1ERYWhpKSEgBAt27dYGdnh6CgIF65iYmJMDY2Rl5eHtasWcOlDxs2jBdrc3NzcfDgwUZ9x4QQQj4cbzsuhoSESMWrmk/tB3vUJySEEPI+iEQiFBUV4dKlS1xafHw8hEIhkpOTuX4VUP0wVCgU8uLQxIkTpfpQkyZN4s65desWduzYgYqKCmRkZMDPzw8GBgZcf64mFtrY2Ej1wxISEnhtnTVrFnJzc3Hr1i18+eWXWLlyJbZu3codnzZtGry9vTF27FjExsYiLS0Nq1atwtGjR3H69GleWcHBwZg4cSJKSkqQmJgIAFi0aBGvfkNDQy4+13zatWv35r58QgghnKYwXllUVAQA6NevH6/fFhAQwOsLPXnyBL1790ZMTAwCAgJw584dhIeH4+7du+jRowfu3bvH5T137hy8vLxw4cIF/P7776ioqMDQoUNRXFzM5dmyZQu+++477Ny5E8nJyRAKhRgyZAiePXvG5fH29saRI0cQFhaGhIQEFBUVYdSoUaisrORdQ0lJCcLDw+Hj4wOxWMylT58+Hc+fP0dkZKTUdUdGRqKkpATTpk3j0l6Of7m5uZg/f75c3yMhhJCGMcZQUVHxVspWVlaGUCjkXi6XR02fLjs7Gz/++CN+/fVXzJ079423TVtbG5qamq9dTkPjrTk5OcjJycHWrVuRnp6O4OBgREdHw8PD47XqLSsre+22E0JIY9GKoI1QXFyMiIgIJCcnIy8vD8HBwVi9ejUAwN/fH3Fxcbh06RK6dOnCnWNqaooJEyZwN/m5c+dCIBDg4sWLUFdX5/LZ2Nhg5syZcrdFU1MTQqEQAODp6Yndu3fj9OnTmDNnDi+fjo4Ol+9lYrEYrq6uYIxBLBZj6tSp3LGLFy9i06ZN8Pf3x4IFC7h0ExMTDBkyBE+fPuW9zfLixYsG6yOEkP+KtWvXYu3ate+7GW9EU419bdu2xfTp0xEWFiaVr3Xr1mjZsiWEQiEsLCwwduxY2NnZQVNTE+Hh4Vy+P//8E8OGDcPZs2cxa9YsHD58GNOnTwcAeHh4YPny5di+fTvXZicnJ6xfvx67du3iDQirqKhQ7COEkP+IdxEXFRQU0KtXL5n1134DnvqEhBBC3gdLS0sYGBhAIpFwq59JJBJuMmVSUhIGDx7MpQ8aNIgXF1RVVVFaWlpnrGjdujWmT58OZ2dnANXxZcyYMWjVqhXCw8OhpKSEoKAgKCoqNhhv1NTUuDzz5s3D0aNH8csvv2DJkiWIiIhASEgIfvnlF4wdO5Y7x8TEBGPGjEFhYSGXxhhDUFAQt5KaWCzmTfqpoaCgwIvPhBBC3o6mMl6ppqaGUaNGITQ0FP7+/nBycgIAfPPNN9zq0UD1C3Y5OTm4c+cOFyOMjIxw6tQpdOjQAV5eXjh58iQASK1uGhQUhNatWyMlJQUODg5gjMHf3x8rVqzAp59+CgDYv38/9PX1ERoaijlz5qCgoABisRg//fQTF5N//vlntGvXDjExMVyMBYBDhw7B2toay5YtQ5s2bZCdnQ0TExPo6elh9OjRCAwM5E34BKon4Y4ZMwZ6enpcGsU/QgipVlxcDCMjIwQGBmL8+PFc+q+//goXFxfk5eVBU1MTFy9exJw5c5CRkYFOnTphxYoVvHJqVhiNjo7GihUrcPXqVZw6dQpGRkZYuHAhLly4gOLiYnTs2BG+vr7c/R6o3mHhyJEjGDduHJfWsmVL+Pv7w93dXarNslYzTUxMxPLly5GcnAwVFRX07NkTYWFh3IqftZ+LGRoaYtKkSQgODubKrKysxOzZs3H27Fnk5eXByMgIc+fO5Y0xVlZWwsfHB4GBgVBQUICHhwcYY7y2vbw1fEPXVlZWhoULFyIyMhL5+fkQCoWYM2cO5s2bV+94q7GxMe/lBzMzM2zcuBGurq6oqKiAoqIiBg4cCGtra+zcuZPL9/jxYxgYGODkyZMYOHAgTExM4OnpiTt37nDtlLWrICGEvE20ImgjhIeHw9LSEpaWlnB1dUVQUBAXjEJCQjB48GBex7KGkpIS1NXV8eTJE0RHR8PLy4vXsazxKsuEM8YgkUiQkZHRqGWx7969i/Pnz2PixImYOHEikpKSeG8d1rwVUdebG6+zpHlpaSkKCwt5H0IIIU1TU4x9APDXX3/h+PHjdXbcalNVVcXcuXNx+fJltGjRAubm5jA3N8fZs2cxevRo2NrawtXVlffW+9SpU1FeXo5Dhw5xaYwxBAcHw83NjdsC8VVRLCSEkA/Tu4iLmpqaXKx6+WNsbCx1DvUJCSGEvGtOTk6IjY3l/o6NjYWTkxMcHR259LKyMpw/f57b7r0xasfCTp064csvv+T6c7JiobxUVVVRXl4OoDrOWVpa8iaB1hAIBLzt/2JjY1FSUoLBgwdj2rRpiIiI4K261lgUBwkh5PU0lfHKZs2awd7eHl988QV27NgBU1NTmJubo2XLlmjevDkAoKqqCmFhYZg6darURMmaMctTp07hyZMnMusoKCgAUL0iGgBkZWUhLy8PQ4cO5fKoqKjA0dERSUlJAICUlBSUl5fz8hgYGKBTp05cnho1LwdqaWlhxIgRvB2SPDw8cO7cOWRlZXFp2dnZiI2Nfe0V0igWEkI+Vurq6nBxcZHacS4oKAjjx4+HpqYmiouLMWrUKFhaWiIlJQVr167FokWLZJa3ePFi+Pr6IiMjA507d0ZRURFGjBiBmJgYpKamwtnZGaNHj+atjv260tLSMGjQINjY2OD8+fNISEjA6NGjpVaVrnHv3j1ER0fzxiWrqqpgaGiIiIgI3LhxA6tXr8by5csRERHB5fHz80NgYCDEYjESEhLw5MkTHDly5LXavn37dhw7dgwRERG4desWfv75Z5iYmDR6vBWojsEtWrTgngd6enoiNDQUpaWlXJ6QkBAYGBjw+r3ffvstOnXqhJSUFKxatUpm2RQHCSFvE00EbYSaDhFQvdx1UVERzpw5AwDIzMyElZVVveffuXMHjLEG88ljyZIl0NDQgIqKCkQiERhjMrfH7du3L29p69TUVADVb+wNHz4crVq1gra2NoYNG4bAwEDuvMzMTJiamjbqQaK8fH19oaWlxX1oiyRCCGm6mmLsU1VVhaGhIQQCAb777ju5zq2pPzs7G0B1JzQ4OJi7NhcXF5w/fx537twBUD24Om7cOF5nXSKR4N69e1KrAhw/flxqK4kNGzbU2x6KhYQQ8mFqinGR+oSEEELeNScnJyQmJqKiogLPnj1DamoqHBwc4OjoCIlEAgC4cOECnj9//koTQV/2cn8OANLT06X6YZ6enjLPr6qqQnR0NE6dOoVBgwYBqI5zlpaWctUvFovh4uICBQUF2NjYwNzcnLfbRGNRHCSEkNfTlPplALBy5UpkZWUhJCRE6tg///yDp0+fomPHjjLP7dixIxhj3JhkbYwxLFy4EP3790enTp0AAHl5eQAAfX19Xl59fX3uWF5eHpSVlblV22TlAaq/qwsXLmDSpEkAwE2qraqqAgA4OzvDwMCAt8JbUFAQDAwMeJNMgf/rn9b+1PyfQBaKhYSQD5msZ0LDhw/njnt6euLUqVPIyckBAPz77784fvw492wpJCQElZWVCAwMhI2NDUaNGgUfHx+Zda1fvx5DhgyBmZkZdHR0YGdnhzlz5sDW1hYdOnTAN998A1NTUxw7duyNXd+WLVvQvXt3BAQEwM7ODjY2Npg3bx50dXWlvgNVVVWYmZnhxo0bWLJkCXdcSUkJ69atQ48ePdC+fXtMnToV7u7uvImg/v7+WLZsGT777DN07NgRe/bs4b2Q9yoePHiADh06oH///jA2Nkb//v0xefLkRpfz+PFjbNiwgbfz0meffQaBQICjR49yaUFBQXB3d4dAIODSBg4ciEWLFnETTWWhOEgIeZtoIqicbt26hYsXL8LFxQUAoKioiEmTJnEPyhhjvBu8LDVvJDaUTx4+Pj5IS0vDuXPnIBKJsGLFCvTt21cqX3h4ONLS0riPtbU1KisrsX//fq6jDFR38Pbv38+9ySHP9byqZcuWoaCggPs8fPjwrdRDCCHk9TTV2Hf16lVucHfkyJF1voVYXztOnz6N4uJirnOuq6uLoUOH8ibAeHh4IC4ujhuIDQwMRL9+/aQeFopEIl6sTUtL420dLwvFQkII+fA01bhIfUJCCCHvmkgkQnFxMZKTkxEfHw8LCwu0bt0ajo6OSE5ORnFxMSQSCYyMjGBqavra9cmKn5aWllL9sI0bN/LOCwgIgIaGBpo3b44xY8bA1dUVa9as4cqUJ849ffoUUVFRUjGzdt+xsSgOEkLIq2tq/TIA0NPTw6JFi7B69Wpu63l51deWefPm4erVqzh48KDUsZfzy3vdtfOIxWI4OztzE3tGjBiB4uJixMTEAAAUFBTg5uaG4OBgVFVVgTGG/fv3w93dHQoKCryya/qntT/17eREsZAQ8iGT9Uzoxx9/5I737NkTNjY2OHDgAADgp59+gpGRERwcHAAAGRkZsLOzg5qaGndOnz59ZNbVvXt33t/FxcVYvHgxrK2t0bJlS2hoaODmzZtvZUXQ+tR8B3/88Qfmz58PZ2dnzJ8/n5dnz5496N69O/T09KChoYF9+/Zx7SwoKEBubi7vuhUVFaWut7Hc3d2RlpYGS0tLfPnllzh9+nSjyygsLMTIkSNhbW3N9R+B6hW4a/cF09LScOXKFbi7u/POl+caKA4SQt6m19vX9D9ELBajoqICbdu25dIYY1BSUkJ+fj4sLCyQkZFRbxkdOnSAQCBARkYGxo0b91rt0dXV5d4iiIyMhLm5OXr37o3Bgwfz8rVr107qTYMTJ07gr7/+4t7yq1FZWYnTp09j+PDhsLCwQEJCAsrLy9/4CjAqKipQUVF5o2USQgh585pq7Ksp19/fH3369EFsbKxU/HtZTTtNTEwAVE/qfPLkCa+jXVVVhdTUVGzYsAEKCgoYPHgwjI2NERwcjMWLFyMqKgo7d+6UKltdXb3Ot/rqQrGQEEI+PE01LlKfkBBCyLtmbm4OQ0NDxMbGIj8/H46OjgAAoVCI9u3bIzExEbGxsRg4cOAbqe/l/hwAKCsrN9gPmzp1KlasWAEVFRUYGBjwJq3IE7cBIDQ0FC9evOBNZmGMoaqqCjdu3IC1tXUjr4biICGEvI6m1i+rsXDhQgQEBCAgIICXrqenh5YtW+LGjRsyz7t58yYEAgHMzMx46fPnz8exY8cQFxcHQ0NDLr1me/m8vDy0adOGS3/06BG3SqhQKERZWRny8/N5q4I+evSIe3mwsrISBw4cQF5eHrflbU26WCzmVvycOXMmfH19cfbsWQDVK63NmDFD6jpqj9vKg2IhIeRDJuuZ0J9//sn729PTEzt37sTSpUsRFBSEGTNmcJPxa14CkLeu2nx8fHDq1Cls3boV5ubmUFVVxfjx43kvIggEAqk6ysvL5a5TVVVVrnbVfAfbt2+HSCTCunXruN3yIiIi8NVXX8HPzw99+vSBpqYmvv32W/zxxx9yt0OWhq6ta9euyMrKwsmTJxETE4OJEydi8ODBOHz4sFzlP3v2DMOGDYOGhgaOHDkiNSbq6ekJe3t7/PnnnwgMDMSgQYOktpZ/+d9MFoqDhJC3iVYElUNFRQUOHDgAPz8/3psdV65cgbGxMUJCQjBlyhTExMRw2+y9fH5xcTG0tbXh7OyMXbt2obi4WCrf06dPX6l9rVq1wvz587Fo0SK5/uNQs53Ry2+qTJ06FWKxGAAwZcoUFBUVSXVaX7ethBBCPgxNPfYB4B7iPX/+vN58z58/x969e+Hg4AA9PT08fvwYR48eRVhYmFQsLCoqwsmTJwFUdyhnzJiB/fv3IzQ0FM2aNcPEiRNfub2EEEI+XE09LlKfkBBCyLsmEokgkUggkUjg5OTEpTs6OuLUqVO4cOHCG9kW/uX+XGNoaWnB3Nwc7dq1k1q5bMqUKbh9+zZvW78ajDEUFBQAqI6ZX3/9tVT8F4lEr7UqKCGEkMZryv0yDQ0NrFq1Chs3bkRhYSGXXjOeGBoaytuWHaiOcQEBAXB2doa2tjaA6hg0b948REVF4ezZs2jfvj3vnPbt20MoFOL333/n0srKynDu3Dlukme3bt2gpKTEy5Obm4tr165xeU6cOIFnz54hNTWV910eOnQIv/zyCx4/fgwAMDMzg6OjI4KCghAYGAgnJyepSauEEEKkubq64sGDB9i+fTuuX78ONzc37pi1tTWuXLnCe7Z14cIFucqNj4+Hu7s7PvnkE9ja2kIoFCI7O5uXR09PD7m5udzfmZmZKCkpkbvtnTt35nblk9eaNWuwdetW5OTkcO3s27cv5s6diy5dusDc3Bx3797l8mtpaaFNmza8666oqEBKSkq99chzbS1atMCkSZOwb98+hIeHIzIyEk+ePGnwGgoLCzF06FAoKyvj2LFjaN68uVQeW1tbdO/eHfv27UNoaChmzpzZYLmEEPKu0URQORw/fhz5+fnw8PBAp06deJ/x48dDLBbD29sb/fr1w6BBg7Br1y5cuXIF9+7dQ0REBHr16oXMzEwA1VsSVVZWomfPnoiMjERmZiYyMjKwffv2Opf8loeXlxdu3bqFyMjIevP9888/+PXXX+Hm5iZ1LW5ubjh27Bj++ecf9OrVC4sXL8bXX3+NxYsX4/z587h//z7OnDmDCRMmYP/+/a/cVkIIIU1fU4x9z549Q15eHnJzc3Hx4kX4+PhAV1dXahvcR48eIS8vD5mZmQgLC0O/fv3w77//Yvfu3QCqt+HQ0dHBhAkTeNfVuXNnjBo1ipsAAwAzZsxATk4Oli9fDhcXF5lv8pWWliIvL4/3+ffff1/layeEENJENcW4+DLqExJCCHmXRCIREhISkJaWxq0IClRPBN23bx9evHjxShNBG+rP1aioqJDqh/39999y1zNx4kRMmjQJkydPhq+vLy5duoT79+/j+PHjGDx4MGJjY5GWlobLly/D09NTKmZOnjwZBw4caNTKOoQQQl5PU++XzZ49G1paWlJbuW/cuBFCoRBDhgzByZMn8fDhQ8TFxcHZ2Rnl5eXYtWsXl9fLyws///wzQkNDoampycW4mslCAoEA3t7e2LRpE44cOYJr167B3d0dampqmDJlCoDqyTUeHh74+uuvcebMGaSmpsLV1RW2trbcDhJisRgjR46EnZ0d73v87LPPoKenh59//plrk4eHB6KionDkyBF4eHjIvPaacdvan9oTYgkh5L+mVatW+PTTT+Hj44OhQ4fyVneeMmUKmjVrBg8PD9y4cQMnTpzA1q1b5SrX3NwcUVFR3IsQU6ZMQVVVFS/PwIEDsXPnTly+fBmXLl3C559/3qjdfpYtW4bk5GTMnTsXV69exc2bN7F79+56n3s5OTnBxsYGmzZt4tp56dIlnDp1Crdv38aqVauQnJzMO2fBggXYvHkzjhw5gps3b2Lu3LkNvozR0LVt27YNYWFhuHnzJm7fvo1Dhw5BKBSiZcuW9Zb77NkzDB06FMXFxRCLxSgsLOTiWWVlJS+vp6cnNm/ejMrKSnzyySf1lksIIe8FIw0aNWoUGzFihMxjKSkpDABLSUlhL168YL6+vszW1pY1b96caWtrs379+rHg4GBWXl7OnZOTk8O8vLyYsbExU1ZWZm3btmVjxoxhsbGxcrXH2NiYbdu2TSp91qxZzMbGhlVWVrKsrCwGgKWmpvLybN26lbVs2ZKVlZVJnV9eXs60tbWZn58flxYeHs4cHByYpqYmU1dXZ507d2br169n+fn5vHPrqk8eBQUFDAArKCho9LmEkP8Guk+8e00x9gHgPnp6emzEiBG8uBMbG8sdFwgETFNTk9nZ2TEfHx+Wm5vL5bO1tWVz586VWU9kZCRTVFRkeXl5XNrQoUMZAJaUlCSV383Njdeumo+lpaVc11WDfuOEkIbQfeL9aopxkfqEhJD/ErpPND01930rKyte+sOHDxkAZmZmJvM8Nzc3NnbsWKl0eftzjDG2Zs0amf0wFRUVLo+joyNbsGBBvddQWVnJdu/ezXr06MHU1NRYixYtWLdu3dj333/PSkpK2Lx585i1tbXMcx89esQUFBRYZGQkl1ZXfG4I/b4JIQ2h+0S1D6FfFhoaygAwR0dHXvo///zD5s+fz9q1a8cUFRWZvr4+c3NzY/fv3+flkxXfALCgoCAuT1VVFVuzZg0TCoVMRUWFOTg4sPT0dF45z58/Z/PmzWPa2tpMVVWVjRo1ij148IAxxlheXh5TVFRkERERMq9r/vz5zNbWlvu7pKSEaWlpMS0tLVZSUiLze5DV5jlz5jT0FXLoN04IaUhTuU801J+pPV525swZBkDm/fb8+fPMzs6OKSsrM3t7exYZGckbV5NVHmPV/TCRSMRUVVVZu3bt2M6dO6X6Pn/99RcbOnQoU1dXZx06dGAnTpxgWlpaXCx5eQxPVl0SiYT17duXqaiosJYtWzJnZ2fueF3fQUhICFNWVmYPHjxgL168YO7u7kxLS4u1bNmSffHFF2zp0qXMzs6Oy19eXs4WLFjAWrRowVq2bMkWLlzIpk+fziu7sde2d+9eZm9vz9TV1VmLFi3YoEGD2OXLl6Xa+rLa/dGXP1lZWby8z549Y2pqajKfM1KfkBDytjTmPiFgTI594wh5iwoLC6GlpYWCggK0aNHifTeHENIE0X2CfOzoN04IaQjdJ8jHjH7fhJCG0H2CfMzo900IaQjdJ8jHjn7jhJCGfIj3iZCQECxYsAA5OTlQVlZ+380hb8jDhw9hYmKC5ORkdO3a9Y2U+SH+vgkh71Zj7hOK76hN71xSUhIGDBiAIUOGIDo6mnesrKwM/v7+CAkJQWZmJtTU1GBpaQlPT0+4urpyy0fn5eVh48aN+O233/DXX3+hdevWsLe3h7e3NwYNGtRgG0xMTHD//n2cP38evXv35tK9vb2RlpYGiUTCpT158gTr16/HL7/8gpycHOjo6GDYsGFYt24djIyMuHxxcXH49ttvkZKSgtzcXBw5cgTjxo3j1csYw7p167B3717k5+ejV69e2LVrF2xsbKTauGnTJqxatQobN27E0qVLAQCRkZGYOHEisrKyeHXXsLKywtChQ7F9+3Y4OTnh3LlzUnnmzJmDPXv2NPgd1TZ+9x0oNddo1Dlvwm8LLN55nYQQ0pTs2bMHPj4+yM/Ph6Ji9X8NioqK0KpVK/Tu3Rvx8fFc3vj4eDg4OODWrVuwsKj7/hkcHAxvb+86t3EIDQ3FtGnTMGvWrEbHi7dl7dq1WLduHS9NX18feXl576wN7ysWEvr/ACHk/8jbD5TVl6rpA9bF0dGR1w+UJTU1FatWrcLFixdRWFgIoVDI9el0dXWRnZ2N9u3bIzU1Ffb29lJ/A4C7u3uDW7fXvBMqKyanpKSge/fuiI+PR//+/aXOdXZ2hoqKCo4dO1ZnXc7OzlJ98Yb8V+IgxRxCyLvQlMZGAUBVVRWmpqaYP38+5syZA6C63zhjxgyp81RUVPDixQsA/JimoKAAAwMDjBw5Eps2bUKrVq2k6jp48CBcXFx45dnY2ODGjRsICgqCu7s77xiNjX5YKIYSQt6V9x1HXVxcUFBQgJMnT3JpJ0+exIgRI7By5Ups2LCBS9+wYQN2796N2bNnS41tviwrKwvBwcFcPgUFBbRs2RLW1tb49NNP8cUXX0BFRYXLL0+cEwgEXLqGhgYsLS2xfPlyfPrpp/W2RRaKhf+HYh4hH66SkhJkZWXB19cXc+bM+Sgmgda+18vi5uaG4ODges9/eV5L7f5gs2bN0KJFC1hYWGDkyJFYsGABtLS0pMqR1X+rUVlZiS1btmD//v24f/8+VFVVYWFhgTlz5sjsd9bFyckJ9vb28Pf359K+//57+Pj4YOvWrbhw4QJ0dHTQrVs3mf2+uXPnYvfu3Q1+J7K8ahykmEEIqa3Z+27A2xIYGIj58+cjISEBDx484NLLysrg7OyMzZs3Y/bs2UhKSsLFixfh5eWFHTt24Pr16wCA7OxsdOvWDWfPnsWWLVuQnp6O6OhoiEQieHl5yd2O5s2bY8mSJfXmefLkCXr37o2YmBhMmDABSkpKKCgowIEDB2BiYgJ1dXVoaGjAxsYGxcXFsLOzw86dO+ssb8uWLfjuu++wc+dOJCcnQygUYsiQIXj27JlU3qCgICxevBiBgYFc2pgxY6CjoyPzYV5iYiJu3boFDw8PLm3WrFnIzc3lfbZs2SLP10MIIaQJEIlEKCoqwqVLl7i0+Ph4CIVCJCcno6SkhEuXSCQwMDCodxKoPAIDA7F48WKEhYUhMDAQGhoaMj82NjaorKxEVVXVa9UnLxsbG148S09Pf63yysrK3lDLCCGEvAuN6QfK6kslJydzMSQyMhIAcOvWLS4tKiqq3vofPXqEAQMG4NSpUygqKoKCggL+/vtvHDlyBMbGxjJf7pPl+++/58Wzmva+nAbwY3JNzO/WrRvs7OwQFBQkVfbDhw8RExPD6xMOGzZMqk948OBBudpKCCHk7WgqY6Pr169Hbm4url69inHjxuHzzz9HeHg4d7xFixZSMeTllypq4kx2djZ+/PFH/Prrr5g7d65UXe3atZOKXRcuXEBeXh7U1dVlto/GRgkhhMiyfPlyKCgo4NSpU9wzuppPq1at3nocFYlESEhIQEVFBZcmkUjQrl07xMbG8vJKJBKIRCIsWrSIF4sMDQ25OFzzadeuHYD/GwN98OABYmNjMWHCBPj6+qJv375SzxLliXM1/c3k5GTY2dlhwoQJOH/+/Ct994QQ8qHbsmUL7O3toa+vj2XLlr3v5rwRtWOAv7+/VD/u+++/f6Vya8r5888/kZSUhNmzZ+PAgQOwt7dHTk6OVH5Z/bcaa9euhb+/PzZs2IAbN24gNjYWs2bNQn5+PkJCQup9DlmfNWvWYNmyZVi/fj0WLFiAlJQU9OnTB+3atUNYWBieP3/O5X3x4gUOHjwo84VCQgh5Vz7KiaDFxcWIiIjAF198gVGjRvFm2vv7+yMuLg5nzpyBl5cX7O3tYWpqiilTpuCPP/5Ahw4dAFTP1BcIBLh48SLGjx8PCwsL2NjYYOHChbhw4YLcbZkzZw4uXLiAEydO1JlnxYoVyMnJQUxMDFavXo0rV67g6tWruHLlClq3bo1u3bohLS0NJ06cwPDhw/HNN9/U+SYdYwz+/v5YsWIFPv30U3Tq1An79+9HSUkJQkNDeXnPnTuH58+fY/369SguLkZcXBwAQElJCdOmTUNwcDC3SkyNwMBA7qFgDTU1NQiFQt6HlqwmhJAPh6WlJQwMDHgrlEkkEowdOxZmZmZISkripYtEIpSVlWHx4sVo27Yt1NXV0atXL+58iUSCGTNmoKCgAAKBAAKBAGvXruXKyM7ORlJSEpYuXQorKyuUl5cjLS2N+6xatQoCgQDfffcdysrKoKKigvv379dbJwA8fvwYkydPhqGhIdTU1GBra9voSSiKioq8eKanp8cdW79+PWxtbaXO6datG1avXg2gerWacePGwdfX941MmCWEEPJuydsPrKsvpaenx8UQbW1tAEDr1q2l0uqSlJSEFy9eID09nesTpqen48aNG7hy5Uq9/cratLS0ePEMAFq2bCmV9nJMPnz4MFeGh4cHIiIiUFxczCs7ODgYenp6GDlyJJemoqIi1SesvUobIYSQd6spjY1qampCKBTC3Nwc33zzDTp06IBffvmFOy4QCKRiiL6+Pq+MmjhjaGiIoUOHYtKkSTh9+rRUXVOnTsW5c+fw8OFDLi0wMBBTp07ldr+ojcZGCSGEyFJcXIyUlBQcP34cI0aMgKenJzduOXfuXDx//vytx1FZL+5LJBIsXbqU9+J+WVkZzp8/D5FIBA0NDV4sUlBQ4OJw7TTg/8ZADQwMYGtri/nz5+PcuXO4du0a/ve///HaIk+cq+lvWllZYc+ePWjevDmOHTv2Wv8OhBDyoVq7di3Ky8tx5swZaGh8HKsc144BWlpaUv240NBQmJmZQVlZGZaWlvjpp5+4c01MTAAAn3zyCQQCAfc38H/9wTZt2qBjx47w8PBAUlISioqKsHjxYl4b6uq/1ah5YXDChAlo37497Ozs4OHhgYULF2LMmDFIS0tDUlISBg8ejKqqKqiqqmL+/PnQ1NSEt7e31DUzxjB//nx8//33OH36NJYuXQrGGG7duoVWrVqha9euMDIy4r34HxUVhXbt2qFLly6v/6UTQsgr+igngoaHh8PS0hKWlpZwdXVFUFAQN2gXEhKCwYMHy7z5KikpQV1dHU+ePEF0dDS8vLxkvi3esmVLudtiYmKCzz//HMuWLZO5mllVVRXCwsIwdepUCIVCaGpqwtzcHObm5ujUqRO+/PJLJCQkQFtbG8bGxg3Wl5WVhby8PAwdOpRLU1FRgaOjI28iDwCIxWJMnjwZSkpKmDx5MsRiMXfMw8MD9+7d4235UDOIXPuNd0IIIR8HJycn3tvksbGxcHJygqOjI5dee2BxxowZSExMRFhYGK5evYoJEyZg2LBhyMzMRN++faXeCFy0aBFXdmBgIEaOHAktLS24uroiNDSUi33m5ubQ19dHaWkp9u/fj/379+P69eto3bp1vXUC1W/adevWDcePH8e1a9cwe/ZsTJs2DX/88Yfc30NmZiYMDAzQvn17uLi44N69e9yxmTNn4saNG0hOTubSrl69itTUVN72gmfOnEFGRgZ+//13HD9+vNH/FoQQQt6PxvQD6+tLvQ6hUIjKykqkp6fDzMyMFx/Nzc3l6hM2xssxufZ1TJ06FeXl5Th06BCXxhhDcHAw3NzcZE6oIYQQ0jQ0pbHRlzVv3hzl5eWvfP69e/cQHR3Nbbtbm76+PpydnbmVPEtKShAeHo6ZM2fKLIvGRgkhhMgSHh4OKysrDB06FF988QWOHTvG9c9OnTqFIUOGvPU4amFhAQMDA25c9tmzZ7h8+TImTJgAMzMzJCYmAqhe+fr58+cQiUSvd9EArKysMHz48AZ3smiIkpISFBUVXyveE0II+XAcOXIECxYswNdff41r165xW7HXxLCaZ2q1V4+uT+vWrTF16lQcO3YMlZWVXHpD47FCoRBnz57FP//8I1VmzRycPXv2ICUlBUePHsXZs2dx7do1bjXv2ioqKjBt2jQcOnQI586dQ//+/WW2dcaMGbxdKQIDA+vsfxJCyLvyUU4EFYvFcHV1BVC9dVBRURHOnDkDoHqCh5WVVb3n37lzB4yxBvPJa+XKlcjKykJISIjUsX/++QdPnz5Fx44dZZ7bsWNHMMZw584duerKy8sDAKk35/X19bljAFBYWIjIyEjue3J1dcXhw4dRWFgIALC2tkavXr14gSsiIgKVlZWYPHkyr+yAgACpJbRlbZ1Uo7S0FIWFhbwPIYSQ98vJyQmJiYmoqKjAs2fPkJqaCgcHBzg6OnKrbtYMLDo5OeHgwYM4dOgQBgwYADMzMyxatAj9+/dHUFAQlJWVpd4IrHnrsaqqCsHBwVz8cXFxwfnz56XiXHl5OQICAtC3b19YWloiLy+v3joBoG3btli0aBH3Jv78+fPh7OzMm8BSn169euHAgQM4deoU9u3bh7y8PPTt2xePHz8GABgaGsLZ2ZkXG4OCguDo6AhTU1MuTV1dHT/++CNsbGzQqVMnmXVRLCSEkKZH3n5gQ32p19G7d28sX74cU6ZMga6uLoYPH45vv/0Wf//992uX/bKGYrK2tjbGjRvHi3sSiQT37t2TGtA8fvy4VJ9ww4YNddZNcZAQQt6upjY2ClQ/SAsODkZ6ejoGDRrEpRcUFEjFkNovuAP/F2dUVVVhZmaGGzduYMmSJTLrmTlzJreS5+HDh2FmZgZ7e3upfDQ2SgghpC5NJY46OTlx47Lx8fGwsLCAnp4eb7y2Zrt4MzOz16qrhpWVFbKzs3lpjYlzpaWl+Oabb1BYWMiL97LyUSwkhJCPw9atW+Hu7o65c+fCwsICCxcuxKeffoqtW7cCALfzXs3q0bV34quLlZUVnj17xj2fk2c89rvvvsM///wDoVCIzp074/PPP8fJkye540VFRRCLxdi6dSuGDBkCW1tb7N+/nzfZtMa+fftw6NAhSCQS3m4QL5s2bRoSEhKQnZ2N+/fvIzExkWtjfSgOEkLepo9uIuitW7dw8eJFuLi4AKje3mDSpEkIDAwEUL2CiUAgqLeMmjfkG8onLz09PSxatAirV69GWVlZo8591ba8nP/l6w4NDYWpqSkXuGomzYSFhXF5PDw8cPjwYTx79gxA9RsMn376qdTbilOnTuVt6ZuWloZPPvmkzrb5+vpCS0uL+7Rr165R10YIIeTNE4lEKC4uRnJyMjew2Lp1azg6OiI5ORnFxcWQSCQwMjLC5cuXwRiDhYUFbwDw3LlzuHv3br31nD59GsXFxRg+fDgAQFdXF0OHDuXidA1lZWV07tyZ+1ueOisrK7Fx40Z07twZOjo60NDQwOnTp/HgwQO5voPhw4fjs88+g62tLQYPHozffvsNAHgDm7NmzcLBgwfx4sULlJeXIyQkRGoyjK2tLZSVleuti2IhIYQ0PfL2veTpS72OjRs3Ii8vD3v27IG1tTX27NkDKysrpKenv5Hya8gTkz08PBAXF8dNDg0MDES/fv1gaWnJK0skEkn1Cb28vOqsm+IgIYS8PU1tbHTJkiXcJE4vLy/4+Phgzpw53HFNTU2pGFJ78iXwf3Hmjz/+4F74mz9/vsz6Ro4ciaKiIsTFxdW7GguNjRJCCJGlKcVRkUiExMRElJeXQyKRwMnJCQCkJoIOHDjwteqpTdb1yRPnJk+eDA0NDaipqeG7777D1q1bub6mLBQLCSHk45GRkYF+/frx0vr164eMjIxXLvPlWCpP/83a2hrXrl3DhQsXMGPGDPz9998YPXo0PD09AQB3795FWVkZ+vTpw52jra0tNc4JAP3794eGhgZWrlyJioqKOtupq6uLkSNHYv/+/QgKCsLIkSOhq6vb4PVRHCSEvE0f3URQsViMiooKtG3bFoqKilBUVMTu3bsRFRWF/Px8WFhYNBh0OnToAIFA8FrB6WULFy7E8+fPERAQwEvX09NDy5YtcePGDZnn3bx5EwKBQO63+YRCIQDwVv8EgEePHvFWCQ0MDMT169e570hRURHXr1/nLaHt4uICgUCA8PBw3LlzBwkJCTK3PtLS0pLasrBFixZ1tnHZsmUoKCjgPg8fPpTr2gghhLw95ubmMDQ0RGxsLGJjY+Ho6AigOq60b98eiYmJiI2NxcCBA1FVVQUFBQWkpKTwBgAzMjLw/fff11tPYGAgnjx5AjU1NS7+nDhxQuqtO1VVVd6gozx1+vn5Ydu2bVi8eDHOnj2LtLQ0ODs7N/oljBrq6uqwtbXltp4HgNGjR0NFRQVHjhzBr7/+itLSUnz22WdS5zWEYiEhhDQ98vYD5elLvS4dHR1MmDABfn5+yMjIgIGBAfcW/ZsiT0wePHgwjI2NERwcjMLCQkRFRcnsE6qrq0v1CbW1teusm+IgIYS8PU1tbNTHxwdpaWm4f/8+ioqKsGXLFjRr9n9D0s2aNZOKIW3btuWVURNnOnfujO3bt6O0tBTr1q2TWZ+ioiKmTZuGNWvW4I8//sDUqVNl5qOxUUIIIbI0pTha+8X92uO1NS/uP3nyBOfPn38j28LXyMjIQPv27Xlp8sS5bdu2IS0tDbm5uXjy5Am+/vrreuuhWEgIIR+XhhYpa6yMjAy0aNECOjo6AOQfj23WrBl69OiBr776CkeOHEFwcDDEYjGysrK4yaXysLW1xZkzZyCRSDBx4kSUl5fXmbdmV4r9+/fLvS08xUFCyNuk+L4b8CZVVFTgwIED8PPzk9pC6LPPPkNISAimTJmC5cuXIzU1FV26dJE6v7S0FNra2nB2dsauXbvw5ZdfSk3oePr0qdSb3w3R0NDAqlWrsHbtWowePZpLb9asGSZOnIiQkBCsX7+em8gJgJs46uzsXO9DtNrat28PoVCI33//nbu+srIynDt3Dv/73/8AAOnp6bh06RIkEgmv3KdPn8LBwQHXrl1Dp06doKmpiQkTJiAoKAj37t2Dqakp98bh61BRUYGKisprl0MIIeTNEolEkEgkyM/Ph4+PD5fu6OiIU6dOcW/RdenSBZWVlXj06BEGDBggsyxlZWWp7RQeP36Mo0ePIiwsDDY2Nlx6VVUVBgwYgJMnT2LUqFEyy5Onzvj4eIwdO5bbdqGqqgqZmZno2LFjo76HGqWlpcjIyODVp6ioCDc3NwQFBUFFRQUuLi5QU1NrdNkUCwkhpOmRpx/48OFDufpSb5KysjLMzMxQXFz8xsqUNyYLBALMmDEDP/74IwwNDbn+6+uiOEgIIW9HUxwb1dXVhbm5+Wtd18vWrFmD4cOH44svvoCBgYHU8ZkzZ2Lr1q2YNGkSWrVqJXWcxkYJIYTI0tTiqJmZGdq1a4djx44hLS2Nmwjapk0bmJiYwM/PDy9evHhjE0Fv3ryJ6OhoLFu2rNHnCoXCRsV7ioWEEPLx6NixIxISEjB9+nQuLSkpifdsTklJSeYW7LI8evQIoaGhGDduHJo1ayZ3/00Wa2trAEBxcTHMzc2hpKSECxcuwMjICACQn5+P27dvczG2Nnt7e5w9exaDBw/GhAkTcOjQISgpKUnlGzZsGLcgjbOzs1zXSHGQEPI2fVQTQY8fP478/Hx4eHhAS0uLd2z8+PEQi8W4cOECfvvtNwwaNAgbNmxA//79oampiUuXLuF///sfxGIx7O3tERAQgL59+6Jnz55Yv349OnfujIqKCvz+++/YvXv3K73JN3v2bGzbtg0HDx5Er169uPSNGzfizJkzGDJkCLZs2YJOnTohKysLK1euRHl5OXbt2sXlLSoq4rblA4CsrCykpaVBW1sbRkZGEAgE8Pb2xqZNm9ChQwd06NABmzZtgpqaGqZMmQKg+o3Gnj17wsHBQaqNffr0gVgsxrZt2wBUb4E0YMAA3LhxA4sWLZL55kZJSYnUCqQqKioyB1oJIYQ0XSKRCF5eXigvL+d1ehwdHfHFF19wA4vt2rXD1KlTMX36dPj5+aFLly74999/cfbsWdja2mLEiBEwMTFBUVERzpw5Azs7O6ipqeGnn37iVjirvQIMAIwaNQpisbjOiaAWFhYN1mlubo7IyEgkJSWhVatW+O6775CXlyf3RNBFixZh9OjRMDIywqNHj/DNN9+gsLAQbm5uvHyenp5cmYmJiY35igkhhDRxDfUDnZ2d5e5LvYrjx48jLCwMLi4usLCwAGMMv/76K06cOCG1Te7Lbt26JZVmbW0NZWVlqfTGxOQZM2Zg/fr1WL58OVxcXGSufF1aWirVJ1RUVJRrKyRCCCFvTlMfG5WFMSYVQwCgdevWUjGqhpOTE2xsbLBp0ybs3LlT6njHjh3x77//1vnSHo2NEkIIkaUpxlGRSISAgACYm5vzdv1zdHTEjh07YGpqyk1maYyKigrk5eWhqqoKjx8/hkQiwTfffAN7e3veAgEAxTlCCCH18/HxwcSJE9G1a1cMGjQIv/76K6KiohATE8PlMTExwZkzZ9CvXz9eDKnpDzLG8PTpU5w/fx6bNm2ClpYWNm/eDED+/tv48ePRr18/9O3bF0KhEFlZWVi2bBksLCxgZWUFRUVFeHh4wMfHBzo6OtDX18eKFSvq7HcCQOfOnbndEsePH49Dhw5JjbUqKChwcV1BQeG1v09CCHlt7CMyatQoNmLECJnHUlJSGACWkpLCXrx4wXx9fZmtrS1r3rw509bWZv369WPBwcGsvLycOycnJ4d5eXkxY2NjpqyszNq2bcvGjBnDYmNj5WqPsbEx27ZtGy8tNDSUAWCOjo689H/++YfNnz+ftWvXjikqKjJ9fX3m5ubG7t+/z8sXGxvLAEh93NzcuDxVVVVszZo1TCgUMhUVFebg4MDS09MZY4yVlpYyHR0dtmXLFplt9vPzY7q6uqy0tJRLs7S0ZM2aNWMPHz6Uyu/o6CizPc7OznJ9R4wxVlBQwACwgoICuc8hhPy30H3i3cjKymIAmJWVFS/94cOHDAAzMzPj0srKytjq1auZiYkJU1JSYkKhkH3yySfs6tWrXJ7PP/+c6ejoMABszZo1zNbWls2dO1dm3ZGRkUxRUZHl5eWxoKAgpqWlJZWnoTofP37Mxo4dyzQ0NFjr1q3ZypUr2fTp09nYsWPluv5JkyaxNm3aMCUlJWZgYMA+/fRTdv36dZl5BwwYwKytraXS3dzc5K6vNvqNE0IaQveJd6eufuCpU6ca1Zeq6bvl5+fLXffdu3fZrFmzmIWFBVNVVWUtW7ZkPXr0YEFBQVyemnidmprK+1vWJysrizHGGAB25MgRrgx5Y3KNoUOHMgAsKSlJKr+bm5vMui0tLeW+bvp9E0IaQvcJ+XwIY6O1BQUF1RnDcnNzGWN197FCQkKYsrIye/DggVx1aWlpsaCgIBobJYR8kOg+8W40tTjK2P/Fys8//5yX/tNPPzEAzMPDo85z64qNa9as4eKVgoIC09bWZv3792fbtm1jL1684OWVJ8693N98FfQbJ4Q0hO4TTYesZ3gBAQHM1NSUKSkpMQsLC3bgwAHe8WPHjjFzc3OmqKjIjI2NuXJq4opAIGBaWlqsZ8+ebP369dy/c2P6b3v37mUikYjp6ekxZWVlZmRkxNzd3Vl2djaX/9mzZ8zV1ZWpqakxfX19tmXLFubo6MgWLFjA5Xn5b8YYu379OhMKhWzUqFGstLS0wWeBY8eO5c3faQj9vgkhDWnMfULAGGOvOZeUkNdSWFgILS0tFBQUoEWLFu+7OYSQJojuE6QpYYzBysoKc+bMwcKFC99ImfQbJ4Q0hO4T5GNGv29CSEPoPkE+ZvT7JoQ0hO4T5GNHv3FCSEPoPkHeFicnJ9jb28Pf3/+9tYF+34SQhjTmPvFRbQ1PCCGEEPI2PXr0CD/99BP++usvzJgx4303hxBCCCGEEEIIIYQQQgghhBBCCCHk45kI6u7ujv3790uli0QiXL16Fd7e3li5cqXUcV9fX/j5+SEnJwehoaHw9vbG06dPG6wvJCQEc+bMQVlZGSoqKlCzsKqCggJMTExw584dLu/atWuxbt06zJkzB3v27OHS09LS0KVLF2RlZcHExATZ2dlo3749d1xDQwNGRkZwcnKCt7c3OnToINd3ERUVhd27dyMtLQ2lpaWwsbHB2rVr4ezszMsXGRmJVatW4e7duzAzM8PGjRvxySefcMfj4uLw7bffIiUlBbm5uThy5AjGjRsnVdcPP/yAlJQUPH78GKmpqbC3t5ernS8bv/sOlJprvNK58vhtgcVbK5sQQj4meXl52LhxI3777Tf89ddfaN26Nezt7eHt7Y1BgwZx+TZt2oRVq1Zh48aNWLp0KQDAxMQE9+/fr7NsR0dHSCSSeutPTU3FqlWrcPHiRRQWFkIoFKJXr17YtWsXdHV1uXhZE3Ne/huo+/8FtamrqwMAKioqUFZWhtmzZ3NxOiUlBd27d0d8fDz69+/PnaOvrw9dXV2YmprCzc0Nx44dq7MuZ2dnREdH19uGl73tWEjqRv9PIITIa8+ePfDx8UF+fj4UFau71EVFRWjVqhV69+6N+Ph4Lm98fDwcHBwaLFNFRQVCoZCLoQKBAJqamjA1NcWQIUPw1VdfoU2bNlz+mj7myywtLXHz5k0A1W+znzt3DgCgrKwMY2NjuLu7Y8mSJVBQUABQvcr1vn37IBaLcf36dSgqKsLc3Byurq6YPXs21NTUuLL//PNPmJqawtTUlKujrnbUVtPflcd/JQ5SzCGEvA9veuy0ZmxUFmNjY/j4+PDGWYODg2W+TLdv3z54enpyx62srJCRkcHLExERgUmTJsHY2BjZ2dkNXuu7GhstLy/HypUrceLECdy7dw9aWloYPHgwNm/eDAMDgwbb+bL/ShysC8VHQsjb9q6fIwYHB8sVC1VUVKCoqIiKigqUlpZCWVkZpaWlvDwUC/97KC4SQt6W9x0PayQlJWHAgAEYMmSIzGdpkZGR2LJlC27evImqqioYGRlh2LBh8PPza7DOxsTB5ORkxMfH4/Tp0x9sHKSYQQiprdn7bsCbNGzYMOTm5vI+kZGRcHV1RXBwMDdZs7agoCBMmzYNysrKjarL2dkZFhYW0NHRgb+/PyQSCQ4fPgyRSIScnBxcuHCBl7958+YQi8W4fft2g2XHxMQgNzcXV65cwaZNm5CRkQE7OzucOXNGrrbFxcVhyJAhOHHiBFJSUiASiTB69GikppGrtE0AAQAASURBVKZyec6fP49JkyZh2rRpuHLlCqZNm4aJEyfijz/+4PIUFxfDzs4OO3furLOu4uJi9OvXD5s3b5arbYQQQpq27OxsdOvWDWfPnsWWLVuQnp6O6OhoiEQieHl58fIGBQVh8eLFCAwM5NKSk5N5MRgAbt26xaVFRUXVW/+jR48wePBg6Orq4tSpU8jIyEBgYCDatGmDkpISua/j+++/5/1/AAA2b96MpKQk7pOWloa0tDR07doVPj4+CAsL4+ro1q0b7OzsEBQUxCuXMYbLly/j+vXr8PDw4NJl/R/k4MGDcreXEELIh0MkEqGoqAiXLl3i0uLj4yEUCpGcnMyLVxKJBEKhkIsNmZmZGD58OAYMGMCLSZcuXeL6VLdu3UJOTg6Sk5OxZMkSxMTEoFOnTkhPT+e1w8bGRir2JCQk8PLMmjULubm5uHXrFr788kusXLkSW7du5Y5PmzYN3t7eGDt2LGJjY5GWloZVq1bh6NGjOH36NK+s4OBgTJw4ESUlJUhMTAQALFq0iFe/oaEh1q9fz0tr167dm/niCSGEvLY3OXY6ZswYrk/18ufEiRMy62/RooVU/VOnTuWOq6ur49GjRzh//jzvvMDAQBgZGcl9ne9qbLSkpASXL1/GqlWrcPnyZURFReH27dsYM2aM3G0lhBDybr3L54iy1MTCzMxMXn8wLS0N69atg6qqKlRVVSkWEkIIeavedzwEqmPb/PnzkZCQgAcPHvCOxcTEwMXFBePHj8fFixeRkpKCjRs3oqysTK6yGxMHV65cievXr1McJIR8ND6aFUGB/1tF5WUeHh74/vvvERcXB0dHRy49Pj4emZmZvIkc8hKLxUhLS0Nqairs7Oy49E8++QS9evWCh4cHrl27BoFAAKB6ZZbWrVtj5cqViIiIqLdsHR0d7jpMTU0xevRoDBo0CB4eHrh79y63ektd/P39eX9v2rQJR48exa+//oouXbpweYYMGYJly5YBAJYtW4Zz587B39+fm7gyfPhwDB8+vN66pk2bBgByvYFICCGk6Zs7dy4EAgEuXrzIrZgJVE82mTlzJvf3uXPn8Pz5c6xfvx4HDhxAXFwcHBwcoKenx+XR1tYGALRu3RotW7aUq/6kpCQUFhbixx9/5FZZa9++PQYOHNio69DS0oKWlhYvzdLSEn369OGlZWdnIy0tDSdPnsS5c+dw+PBhTJ8+HUD1/x+WL1+O7du3876L4OBg6OnpYeTIkVxaXf8HIYQQ8vGxtLSEgYEBJBIJevfuDaB6wmfNZMqkpCQMHjyYSx80aBAvRrRu3RrKyspSMenff//ljrds2RJCoRAWFhYYO3YsunTpgi+++II30VNRUbHB2KOmpsblmTdvHo4ePYpffvkFS5YsQUREBEJCQvDLL79g7Nix3DkmJiYYM2YMCgsLuTTGGIKCghAQEABDQ0OIxWL069cPGhoa0ND4v7fUFRQUoKmpSTGREEKaqDc5dqqpqQlNTc1G1S8QCOqNEYqKipgyZQoCAwO5OPnnn39CIpHgq6++kvtlu3c1NqqlpYXff/+dl7Zjxw707NkTDx48aNSEHUIIIe/Gu3yOKEvtWGhubs47pq+vD2VlZUybNo1iISGEkLfqfcfD4uJiREREIDk5GXl5eQgODsbq1au548ePH0f//v3h4+PDpVlYWEjtXlsXioOEkP+yj2pF0LrY2tqiR48eUqt6BQYGomfPnujUqVOjywwNDcWQIUN4k0ABoFmzZvjqq69w48YNXLlyhXds8+bN3PLSjdGsWTMsWLAA9+/fR0pKSqPbWlVVhWfPnnETcoDqNxyGDh3Ky+fs7IykpKRGl99YpaWlKCws5H0IIYS8f0+ePEF0dDS8vLx4Ex9r1J7MKRaLMXnyZCgpKWHy5MkQi8VvpA1CoRAVFRU4cuSIzDcO37TAwECMHDkSWlpacHV15V3H1KlTUV5ejkOHDnFpjDEEBwfDzc2Nm6j6KigWEkLIh83JyQmxsbHc37GxsXBycoKjoyOXXlZWhvPnz0MkEr1WXaqqqvj888+RmJiIR48evXZZ5eXlAICQkBBYWlryJoHWEAgEvBcqYmNjUVJSgsGDB2PatGmIiIjAs2fPXrkdFAcJIaRpeRtjp6/Kw8MD4eHh3ArbwcHBGDZsGPT19V+5zHc5NlpQUACBQFDvy5AUBwkhpOmhWFiNYiEhhPy3vat4GB4eDktLS1haWsLV1RVBQUG8Z4JCoRDXr1/HtWvX3kh9FAcJIf8lH9VE0OPHj3MrktR8NmzYAACYOXMmDh8+jKKiIgBAUVERDh069MpvLdy+fRsdO3aUeawm/eVt4Lt27YqJEydi6dKlja7PysoKwKutvOnn54fi4mJMnDiRS8vLy5PqNOrr6yMvL6/R5TeWr68vt1KblpYWbRVICCFNxJ07d8AY42JOXQoLC7ktIgDA1dUVhw8ffiMdld69e2P58uWYMmUKdHV1MXz4cHz77bf4+++/X7vsl1VVVSE4OJi7DhcXF5w/fx537twBUL2i6bhx43gdXolEgnv37vFWRwXq/z+ILBQLCSHkw+bk5ITExERUVFTg2bNnSE1NhYODAxwdHSGRSAAAFy5cwPPnz197Iigguz+Ynp4uFXs8PT1lnl9VVYXo6GicOnUKgwYNAgBkZmbC0tJSrvrFYjFcXFygoKAAGxsbmJubIzw8/JWvh+IgIYS8H+9y7FSWgoICXt2yVqCxt7eHmZkZDh8+zL2I93L/q7He1djoixcvsHTpUkyZMgUtWrSoMx/FQUIIeX8oFlIsJIQQ8v7joVgs5p7NDRs2DEVFRThz5gx3fP78+ejRowdsbW1hYmICFxcXBAYGorS09JXqozhICPkv+agmgopEIqSlpfE+Xl5eAIDJkyejqqqKe1gVHh4OxhhcXFzeeDtq3lao2Ra+tm+++Qbx8fE4ffr0GyuzPgcPHsTatWsRHh6O1q1b8469XBZjrNHlv4ply5ahoKCA+zx8+PCt10kIIaRh8saa0NBQmJqacqti29vbw9TUFGFhYW+kHRs3bkReXh727NkDa2tr7NmzB1ZWVkhPT38j5dc4ffo0iouLuW0ddHV1MXToUAQGBnJ5PDw8EBcXx00ODQwMRL9+/aQmztT3fxBZKBYSQsiHTSQSobi4GMnJyYiPj4eFhQVat24NR0dHJCcno7i4GBKJBEZGRjA1NX3t+mTFaEtLS6nYs3HjRt55AQEB0NDQQPPmzTFmzBi4urpizZo1XJny9P+ePn2KqKgobnAWqH4JpHa8bCyKg4QQ8n6877FTTU1NXt11rbQyc+ZMBAUF4dy5cygqKsKIESNeuc53NTZaXl4OFxcXVFVVISAgoN68FAcJIeT9oVhIsZAQQsj7jYe3bt3CxYsXufIUFRUxadIk3lijuro6fvvtN9y5cwcrV66EhoYGvv76a/Ts2ZNbMVteFAcJIf81r76naROkrq4Oc3Nzmce0tLQwfvx4BAUFwcPDA0FBQRg/fny9M/HrY2FhgRs3bsg8dvPmTQBAhw4dpI6ZmZlh1qxZWLp0aaO20c3IyAAAtG/fXu5zwsPD4eHhgUOHDmHw4MG8Y0KhUOpthkePHr3W1hLyUlFRgYqKyluvhxBCSON06NABAoEAGRkZGDduXJ35AgMDcf36dd7W6FVVVRCLxZg9e/YbaYuOjg4mTJiACRMmwNfXF126dMHWrVuxf//+N1I+UH0dT548gZqaGpdWVVWF1NRUbNiwAQoKChg8eDCMjY0RHByMxYsXIyoqCjt37pQqq77/g8hCsZAQQj5s5ubmMDQ0RGxsLPLz8+Ho6Aigup/Vvn17JCYmIjY2FgMHDnwj9dX0B01MTLg0ZWXlBmPP1KlTsWLFCqioqMDAwAAKCgrcMQsLC67c+oSGhuLFixfo1asXl8YYQ1VVFW7cuAFra+tGXg3FQUIIeV/e5dipLM2aNZOr3zR16lQsXrwYa9euxfTp03l9z8Z4V2Oj5eXlmDhxIrKysnD27NkGvzOKg4QQ8v5QLPw/FAsJIeS/633GQ7FYjIqKCrRt25ZLY4xBSUkJ+fn5aNWqFZduZmYGMzMzeHp6YsWKFbCwsEB4eDhmzJghV10UBwkh/0Uf1YqgDfHw8EBiYiKOHz+OxMTE11q+2sXFBTExMbhy5QovvaqqCtu2bYO1tTW3UtrLVq9ejdu3b8u9clpVVRW2b9+O9u3bo0uXLnKdc/DgQbi7uyM0NBQjR46UOt6nTx/8/vvvvLTTp0+jb9++cpVPCCHk46OtrQ1nZ2fs2rULxcXFUsefPn2K9PR0XLp0CRKJhPemYFxcHJKTk3Ht2rU33i5lZWWYmZnJbNOrevz4MY4ePYqwsDCptx6Liopw8uRJANVvA86YMQP79+9HaGgomjVrxts6ghBCyH+XSCSCRCKBRCKBk5MTl+7o6IhTp07hwoULb2Rb+OfPn2Pv3r1wcHCAnp5eo87V0tKCubk52rVrx5sECgBTpkzB7du3cfToUanzGGMoKCgAUD04+/XXX/Ni5ZUrVyASiV5rVVBCCCFNz5scO30d2traGDNmDM6dO/fKW+G+q7HRmgd+mZmZiImJgY6Oziu1lxBCSNNAsZBiISGEkLcXDysqKnDgwAH4+flJjTUaGxsjJCSkznNNTEygpqYm97NCioOEkP+qj2pF0NLSUqlZ+4qKitDV1QVQ/UDO3Nwc06dPh7m5ORwcHF65rq+++gpHjx7F6NGj4efnh169euHvv//Gpk2bkJGRgZiYmDqXjdbX18fChQvx7bffyjz++PFj5OXloaSkBNeuXYO/vz8uXryI3377TerhnSwHDx7E9OnT8f3336N3797cd6KqqgotLS0AwIIFC+Dg4ID//e9/GDt2LI4ePYqYmBgkJCRw5RQVFXFb4QJAVlYW0tLSoK2tDSMjIwDAkydP8ODBA+Tk5ACoXsobqH6DQigUNthWQgghTUtAQAD69u2Lnj17Yv369ejcuTMqKirw+++/Y/fu3XB2dkbPnj1lxtA+ffpALBZj27Ztr1z/8ePHERYWBhcXF1hYWIAxhl9//RUnTpxAUFBQvefWxKDarK2toaysLJX+008/cauONmvGfy9m1KhREIvFGDVqFABgxowZWL9+PZYvXw4XFxeoq6tLldfQ/0EIIYR8fEQiEby8vFBeXs6tCApU9zu/+OILvHjx4pUmgj569AgvXrzAs2fPkJKSgi1btuDff/9FVFQUL19FRYVU7BEIBHK/tT5x4kQcOXIEkydPxqpVqzBkyBDo6ekhPT0d27Ztw/z582FiYoLLly8jJCQEVlZWvPMnT56MFStWwNfXF0pKSo2+TkIIIe/euxw7fV3BwcEICAh4pYdo72pstKKiAuPHj8fly5dx/PhxVFZWcnVpa2vL7IsSQgh5vygWUiwkhBDy/uLh8ePHkZ+fDw8PDy4e1Rg/fjzEYjHmzZuHtWvXoqSkBCNGjICxsTGePn2K7du3o7y8HEOGDGmwHoqDhJD/NPaRcHNzYwCkPpaWlrx8mzZtYgDYpk2bpMoICgpiWlpactdZXFzMVq5cyczNzZmSkhLT1tZmn332GUtPT+flW7NmDbOzs+OlFRYWMl1dXQaAZWVlMcYYy8rK4rVdTU2NdezYkc2dO5dlZmbK3S5HR0eZ34Wbmxsv36FDh5ilpSVTUlJiVlZWLDIyknc8Nja2wXKCgoJk5lmzZo3c7S0oKGAAWEFBgdznEEL+W+g+8W7l5OQwLy8vZmxszJSVlVnbtm3ZmDFj2KlTp5iOjg7bsmWLzPP8/PyYrq4uKy0tZYz9XxzJz8+Xu+67d++yWbNmMQsLC6aqqspatmzJevTowYKCgrg8NfEyNTWV97esT02MBcCOHDnClWFra8vmzp0rsw2RkZFMUVGR5eXlcWlDhw5lAFhSUpJUfnn/D1If+o0TQhpC94mmpyb+WFlZ8dIfPnzIADAzMzOZ57m5ubGxY8dKpdfufwkEAqapqcns7OyYj48Py83N5eVds2aNzNijoqLC5XF0dGQLFiyo9xoqKyvZ7t27WY8ePZiamhpr0aIF69atG/v+++9ZSUkJmzdvHrO2tpZ57qNHj5iCggKvH2lsbMy2bdtWb52y0O+bENIQuk+8vnc9dioWi5mOjo7c5zZ0fNu2bczY2Fiuut/V2Gh9fdHY2Fi52soY/b4JIQ2j+8SbQbGQYiEh5MNF94k3533Gw1GjRrERI0bIzJeSksIAsJSUFHb27Fn22WefsXbt2jFlZWWmr6/Phg0bxuLj4+Wqk+IgIeRj05j7hIAxxkDIe1RYWAgtLS0UFBSgRYsW77s5hJAmiO4T5GNHv3FCSEPoPkE+ZvT7JoQ0hO4TH57Nmzfj559/xrVr1953U5o8+n0TQhpC94kPE8VC+dFvnBDSELpPfLgoHjaMft+EkIY05j7xUW0N/yr27NkDHx8f5OfnQ1Gx+usoKipCq1at0Lt3b8THx3N54+Pj4eDggFu3bsHCwqLOMoODg+Ht7Y2nT5/KPB4aGopp06Zh1qxZ2LNnzxu9nlfl6+uLqKgo3Lx5E6qqqujbty/+97//wdLS8p21YfzuO1BqrvFWyv5tQd3/XoQQQuSXlJSEAQMGYMiQIYiOjuYdKysrg7+/P0JCQpCZmQk1NTVYWlrC09MTrq6u3LaxeXl52LhxI3777Tf89ddfaN26Nezt7eHt7Y1BgwY12AYTExPcv38fANC8eXMYGxvDw8MDixYtgkAgAABkZ2ejffv2UudOnToVP//8MwDg+fPnMDAwgEAgwF9//QVVVVWp/JGRkdixYwdSU1NRWVkJU1NTjB8/HvPmzcOnn36Kc+fO1dlOY2NjZGdnN3g9tb3NWEhko/8jEEKagqYQX2va8c033+D8+fN4/vw5OnToAHd3d3h7e0NBQYHLVxNvz58/j969e3PppaWlMDAwwJMnTxAbGwsnJ6dGfQ8fexykmEMIedfex7hnUFAQPDw80KJFC7i7u7/Jy3ll8ox7uru7Y//+/bzzevXqhQsXLryzdn7scbAuFB8JIR8bV1dXhISEAKjuO+nr66Nz586YPHky3N3d0axZMwCAk5OT1NjipEmTEBYWxv2dn5+PL7/8EseOHQMAjBkzBjt27EDLli3fzcW8Y//VWCgLxUdCSH2awlhizbO6l8cHvb29kZaWhhMnTuDmzZsICgqCSCSCt7c3fvnlF+Tk5EBHRwfDhg3DunXrYGRkxJ0rT9+NMYZ169Zh7969yM/PR69evbBr1y7Y2NhweUpLS7Fo0SIcPHgQz58/x6BBgxAQEABDQ0Op65g9ezbEYjFCQkLg4uICAPDz88P69euRm5sLNTU1Xv4XL15AKBRi9erVWLhwIe+ZZW2+vr5YunRpg99jbY2JgxQnCCF1afa+G/C+iUQiFBUV4dKlS1xazSBoQkICNDQ0uM/gwYMhEAiQnJz8WnUGBgZi8eLFCAsLQ0lJSb15KysrUVVVxUuzsbHhtav2p6Zz2Vjnzp2Dl5cXLly4gN9//x0VFRUYOnQoiouLX6k8oPo/GYQQQj4ugYGBmD9/PhISEvDgwQMuvaysDM7Ozti8eTNmz56NpKQkXLx4EV5eXtixYweuX78OAPD394eBgQF27dqFnJwcKCoq4vHjxzh9+jRGjBghdztqOmAZGRlYtGgRli9fjr1790rli4mJQW5uLvfZtWsXdywyMhKdOnWCtbU1oqKipM5dsWIFJk2ahB49euDkyZO4du0a/Pz8cOXKFfz000+Iioriyr148aJUfa/7/wVCCCH/Ha8bX7Ozs9GtWzecPXsWW7ZsQXp6OqKjoyESieDl5SVXG44cOQJHR0cYGhoiNjYWN2/exIIFC7Bx40a4uLjg5c1E2rVrh6CgIKkyNDTooR0hhDQVdY17CoVCJCcn88YlJRIJDAwM6p0EWltd45OzZs0CYwwlJSVYtGhRvWXIGvd8nbrrGhuVd9xz2LBhvP7jiRMnGt222mhslBBCPm51xaPw8HAAwOjRo3H16lWcPHkSIpEICxYswKhRo1BRUcGVMWvWLF7s+eGHH3h1TJkyBWlpaYiOjkZ0dDTS0tIwbdq0t/KckBBCyIejKYwlAtWLtQwaNIgXhwICAhAfH4/WrVujW7du6NixI37//XfExMQgICAAd+7cQXh4OO7evYsePXrg3r17XHny9N22bNmCDRs2ID8/HwKBAImJibC1teXFQW9vbxw5cgRhYWFISEhAUVERRo0ahcrKSl77S0pKEB4eDh8fH4jFYi59+vTpeP78OSIjI6WuOTIyEiUlJZg2bRqXVvPMsvZn/vz5cn+PhBDyJv3nJ4JaWlrCwMAAEomES5NIJJg8eTLMzc2xa9cupKWlIS0tDV27dsXo0aMxbNgwLF68GG3btoW6ujp69erFnS+RSDBjxgwUFBRAIBBAIBBg7dq1XNnZ2dlISkrC0qVLYWVlhcOHD/PaExwcjJYtW+L48eOwtraGiooK7t+/j7KyMq7Oe/fuwczMDD/88APXtprVVnx8fKCmpgZbW1scPHhQ7u8hOjoa7u7usLGxgZ2dHYKCgvDgwQOkpKQAqA5etra2Uud169YNq1evBlD95vy4cePg6+vbqIFjQgghH4bi4mJERETgiy++wKhRoxAcHMwd8/f3R1xcHM6cOQMvLy/Y29vD1NQUU6ZMwR9//IEOHToAAE6cOIHWrVsjLS0N165dw5UrV3D16lVcv369URMnNTU1IRQKYWJiAk9PT3Tu3BmnT5+WyqejowOhUMh9tLS0uGNisRiurq5wdXXldfAA4OLFi9i0aRP8/Pzw7bffom/fvjAxMcGQIUMQGRkJNzc3aGtrc+Xq6elJ1VeTRgghhNTnTcTXuXPnQiAQ4OLFixg/fjwsLCxgY2ODhQsXyrWSWXFxMWbNmoUxY8Zg7969sLe352Ls/v37cfjwYURERPDOcXNzQ1hYGJ4/f86lBQYGws3N7c18MYQQQl5bXeOeY8eOhZmZGZKSknjpIpGINwZZ37jnjRs3UFxcjJkzZ3Ljk8ePH4eioiIePnyIrl274uzZs7z2yDPu+XKdAPD48WNMnjwZhoaGUFNTQ0VFBTZs2MDVW/szZswYqe+hoXHPGioqKrz+o7a2Nnds5syZGDVqFC9/RUUFhEIhAgMDAVSv7DZv3jwsXLgQurq6GDJkSKP+vQghhHxYTpw4ITMWjR49GiNGjMCxY8fQqVMndO3aFcuXL8fRo0dx8uRJXp9PTU2tzrHLjIwMREdH48cff0SfPn3Qp08f7Nu3D8ePH8eOHTtk1l07FkokEggEApw6dQpdunSBqqoqBg4ciEePHuHkyZPo2LEjWrRogcmTJ/NeDnFycsL8+fPh7e2NVq1aQV9fH3v37kVxcTFmzJgBTU1NmJmZ4eTJk+/suyaEEPJ/msJYYo05c+agvLwc/v7+XByaMmUKunfvjrS0NBQWFqJNmzb4+++/ERMTgxEjRsDIyAgODg44deoUlJSUeBNPG+q7Mcbg7+8PHx8fpKen4+rVq7hy5QrU1dWxZMkSpKWlwdHREWKxGH5+fhg8eDC6dOmCn3/+Genp6YiJieG1/9ChQ7C2tsayZcuQmJjI7fKnp6eH0aNHc3292gIDAzFmzBjeM8CaZ5a1P+rq6nJ/j4QQ8ib95yeCAtWdmtjYWO7v2NhYjBkzBkOGDMHt27dhbm4OIyMjXLlyBWPGjMGXX36JxMREhIWF4erVq5gwYQKGDRuGzMxM9O3bF/7+/mjRogU327/22++BgYEYOXIktLS0ZE48AarfPPD19cWPP/6I69evo3Xr1pgxYwZX57Vr1zBt2jR4eHiAMQZzc3MYGBjAyckJJ06cwLVr1zB79mxMmzYNf/zxxyt9JwUFBQDADXjOnDkTN27c4E3SuXr1KlJTU3nbPJ05cwYZGRn4/fffcfz48VeqmxBCSNMUHh4OS0tLWFpawtXVFUFBQdzqYCEhIVyH6mVKSkpQV1fHkydPEBMTgwULFqBz584wNzfnfTp37tzoNjHGIJFIkJGRwW1nIY+7d+/i/PnzmDhxIiZOnIikpCTeW4chISHQ0NDA3LlzZZ7/sW6/RAgh5N17E/E1OjoaXl5eMgcY5YlZp0+fxuPHj2Wu3DZ69GhYWFhIvWjYrVs3tG/fnnsz/uHDh4iLi+O9DU8IIeT9kzXu6eTkBEdHRy69rKwM58+fh0gk4o1ByjPuuWnTJq5Pd/bsWYwePRqGhoavPO75cp1A9dZ73bp1w/Hjx3Ht2jXMmzcPPj4+ePz4sVS/UlNTs8Hv5OVxzxoSiQStW7eGhYUFZs2ahUePHnHHPD09ER0djdzcXC7txIkTKCoqwsSJE7m0/fv3Q1FREYmJiVKruhFCCPm4GBsbS8Wh/8fencfVmP7/A3+lTeuhXaRUKktijC1LZSu7GVu0IdkSDTGM7BI+Go0lY2bOOVkqIYyxhGixhKTGTkYNQw2TREXr9fuj37m/3c6pTmTEvJ+Px3k8nOu+7vu+7tt53O+u674WS0tLaGtry2yn7Nu3L+zs7HgrE0VEREBPTw/t2rVDQEAAXr16xW1LTk6GQCBAt27duLTu3btDIBDgzz//lHluWbFw+fLl2LJlCy5cuIBHjx5h7NixCA0NRWRkJI4ePYpTp05h8+bNvH127NgBPT09XL58GX5+fpgxYwbGjBkDe3t7XL16Fc7OzvDw8Kh11UNCCCH1ryG0JUqYmZlhxowZ2Lx5M8zNzWFpaYkmTZpATU0NlpaW0NDQwJ49e+Dm5gYjIyPevmpqapg5cyZOnDiB58+fyzz+23W3zMxM5OTkYNy4cVzca9u2Lfr27Yv79+/D0tIS9+7dQ2lpKQYOHMgdx9jYGO3bt+cNhgT+b8IYgUCAwYMH81Y/8vb2RmJiIjIzM7m0rKwsxMfHw9vbW+57RAgh/zbqCIrKBtHz58+jrKwMr169QlpaGvr06QMHBwdu9PnFixfx+vVrODo6IioqCvv27UPv3r1hYWGBgIAA9OrVC2KxGCoqKhAIBFBQUOB6+0uWxquoqEB4eDjc3d0BAK6urkhOTsb9+/d55SktLUVYWBjs7e1hbW2NnJycGs8JAM2bN0dAQAA3qsPPzw/Ozs7Yt29fne8HYwxz585Fr1690L59ewBAixYt4OzszAt+YrEYDg4OMDc359I0NDTwyy+/oF27dty+bysuLsbLly95H0IIIQ2fpEIEVC6ZV1BQgNOnTwMAMjIyYGNjU+P+9+/fB2Os1nzy+Pbbb6GpqQlVVVU4OTmBMYbZs2dL5bO3t+ctSZGWlgagcmDGoEGD0LRpU+jo6MDFxYU3si8jIwPm5uZ16lxaFxQLCSGESDSE+Hrv3j0AQJs2bWRut7Gx4fJUNWnSJC5+isViDB48WK4ZsSkOEkLIv4faPflktXsCwKBBgxAREYEzZ84gJCQEKSkp6Nu3L4qLiwGAK++uXbu4fcRiMcaMGcPdAwCwtLTE+vXrYW1tXW1spjhICCH/XTY2NtxsY25uboiKikJCQgKWLFmCmJgYfP3111zenJwcGBgYSB3DwMAAOTk5cp9z9erV6NmzJzp16sR1atm2bRs6deqE3r17Y/To0bxBIwBgZ2eHwMBAtG7dGosWLYKamhr09PTg4+OD1q1bY+nSpcjNzcW1a9fe6T5QLCSEkHfXENoSqwoMDERmZiYiIiKktj179gwvXryots2xTZs2YIxJ1RsB2XU3SfwzNDTk5TU0NOS25eTkQEVFBU2bNq02D1B5ry5evIhx48YBANeptqKiAgDg7OwMY2Nj3oyrYrEYxsbGvE6mwP+9s6z6qbrKxdsoDhJCPiTqCArAyckJhYWFSElJwdmzZ2FlZQUDAwM4ODggJSUFhYWFSEhIQMuWLXH16lUwxmBlZcV7kCcmJuKPP/6o8TwnT55EYWEhBg0aBADQ09PDwIEDpaaUVlFR4c2KJs85y8vLERQUhA4dOkBXVxeampo4efIkHj58WOf7MWvWLFy7dk1qxhcfHx9ERUXhzZs3KC0tRUREBCZPnszLY2trCxUVlRqPHxwcDIFAwH1MTEzqXEZCCCH/rrt37+Ly5ctwdXUFACgpKWHcuHFcDGOMQUFBocZjSEYk1pZPHvPnz0d6ejoSExPh5OSExYsXw97eXipfdHQ0b2mktm3bory8HDt27OAqykBlBW/Hjh0oLy+X+3reB8VCQgghQMOLr5JjyUqXdXx3d3ckJyfjwYMHCA8Pl6ofVofiICGE/Huo3ZOvunbPcePGYciQIWjfvj2GDRuG48eP4969ezh69CiXZ8qUKVzn1KdPn+Lo0aNSse/LL7+stQwUBwkh5L+rat3Kx8cH/fv3R/v27eHq6or9+/cjLi4OV69e5fLLqofVtd2yatw1NDSEuro6b4IXQ0ND3izYb++jqKgIXV1d2Nra8vYBILWfvCgWEkLIu2lobYlA5TLqAQEBWLp0KUpKSuq0b01lqa7uJiu/vNddNY9QKISzszP09PQAAIMHD0ZhYSG3fLyioiK8vLwQHh6OiooKMMawY8cOTJw4EYqKirxjS95ZVv1UndH7bRQHCSEfktLHLkBDYGlpiRYtWiA+Ph55eXlwcHAAABgZGaFVq1Y4f/484uPj0bdvX1RUVEBRURGpqalSD/iqo79lEYlEeP78OdTV1bm0iooKpKWlYdWqVdzx1NTUeEFInnOGhIRg48aNCA0Nha2tLTQ0NODv71/nYOvn54fDhw8jKSkJLVq04G0bNmwYVFVVcfDgQaiqqqK4uBijRo3i5ZE1ffjbFi1ahLlz53LfX758ScGNEEIaOKFQiLKyMjRv3pxLY4xBWVkZeXl5sLKywu3bt2s8RuvWraGgoIDbt29j5MiR71UePT09btmHmJgYWFpaonv37ujfvz8vn4mJCSwtLXlpx44dw+PHj7lRfhLl5eU4efIkBg0aBCsrK5w7dw6lpaUfZFZQioWEEEKAhhNfraysAAC3b9+WObDizp07aNu2rVS6rq4uhg4dCm9vb7x58waDBg3iLWVYHYqDhBDy76F2z/9TU7vn25o1awZTU1NueXoA8PT0xMKFC5GcnIzk5GSYmZmhd+/evP2obZQQQkhNbt++jVatWsnc9sUXX0BZWRkZGRn44osvYGRkhL///lsq37Nnz6RmQqtJ1bZNBQUFqbZOBQUFbvYzWfvI2k8Sy9/eT14UCwkh5N00lLbEt82dOxdhYWEICwvjpevr66NJkya4deuWzP3u3LkDBQUFWFhY8NKrq7tJlpfPyclBs2bNuPSnT59ysdHIyAglJSXIy8vjzQr69OlTrt2zvLwcO3fuRE5ODpSU/q/LVHl5OYRCITfj5+TJkxEcHIwzZ84AAB4+fIhJkyZJXYfknaW8KA4SQj4kmhH0/3NyckJCQgISEhLg6OjIpTs4OODEiRO4ePEinJyc0KlTJ5SXl+Pp06dcBxTJRxJ4VFRUuBnFJHJzc/Hrr79iz549UqMBCgoKcPz48WrLJs85z549ixEjRsDd3R12dnYwNzfnNVTWhjGGWbNm4cCBAzhz5ozMiqiSkhK8vLwgFoshFovh6urKa9yVl6qqKrS1tXkfQgghDVdZWRl27tyJkJAQXvz6/fffYWpqioiICEyYMAFxcXHc0utv719YWAgdHR04Oztj69atKCwslMr34sWLdypf06ZN4efnh4CAgGpnMqtKKBTC1dVVKh67ublBKBQCACZMmICCggKpSuv7llWCYiEhhJCGFF8HDhwIHR0dhISESG07fPgwMjIyMH78eJn7Tp48GQkJCfD09JTqwFMdioOEEPLvonbP2ts935abm4tHjx7xXi7q6upi5MiRXNuorBeA8qA4SAgh/01nzpzB9evXpSZYkbh58yZKS0u52NOjRw/k5+fj8uXLXJ5Lly4hPz9f5gC+TwnFQkIIqbuG1Jb4Nk1NTSxZsgRBQUG8Zc4bNWqEsWPHIjIykrcsOwC8fv0aYWFhcHZ2ho6ODoDa626tWrWCkZERTp06xaWVlJQgMTGRi42dO3eGsrIyL092djZu3LjB5Tl27BhevXqFtLQ03r3ct28fDh06hNzcXACAhYUFHBwcIBaLIRKJ4OjoKNVp9V1QHCSEfEg0I+j/5+TkBF9fX5SWlnIj44HKBtEZM2bgzZs3cHJygomJCdzc3ODp6YmQkBB06tQJ//zzD86cOQNbW1sMHjwYZmZmKCgowOnTp2FnZwd1dXXs2rULurq6GDNmDBo14ve/HTp0KIRCIYYOHSqzbFZWVrWeUzIj2oULF9C0aVN8//33yMnJQZs2beS6fl9fX0RGRuLXX3+FlpYWF4gFAgHU1NS4fFOmTOGOef78+TrdY0IIIZ+mI0eOIC8vD97e3hAIBLxto0ePhlAoxMWLF3H06FH069cPq1atQq9evaClpYUrV65g3bp1EAqF6NixI8LCwmBvb4+uXbti5cqV6NChA8rKynDq1Cls27at1pGK1fH19cW6desQExOD0aNHV5vv2bNn+O2333D48GG0b9+et83LywtDhgzBs2fP0K1bNyxYsADz5s3D48eP8dVXX8HY2Bj379/Hjz/+iF69emHOnDnvVFZCCCEEaFjxVUNDA9u3b4erqyumTp2KWbNmQVtbG6dPn8b8+fMxevRojB07Vua+Li4uePbsGTVYEkJIA0btnjW3exYUFGD58uUYNWoUmjVrhqysLHz33XfQ09PDV199xTvWlClTMHToUJSXl8PLy6su/w2EEEL+Q4qLi5GTk4Py8nL8/fffiI2NRXBwMIYOHQpPT0/88ccfiIiIwODBg6Gnp4dbt25h3rx56NSpE3r27AkAaNOmDVxcXODj44Pt27cDAKZOnYqhQ4fC2tr6Y14eIYSQj6AhtSXKMnXqVGzcuBFRUVG8ZdGDgoJw+vRpDBgwAOvXr0f79u2RmZmJwMBAlJaWYuvWrVze2upuCgoK8Pf3x5o1a9C6dWu0bt0aa9asgbq6OiZMmMDl9fb2xrx586CrqwsdHR0EBATA1taWW1VQKBRiyJAhsLOz411Du3bt4O/vj927d3PvAL29veHj4wMA+OWXX2Re+6tXr6Q6uqqrq1N7KSHk42CEMcZYZmYmA8BsbGx46Y8ePWIAmIWFBZdWUlLCli5dyszMzJiysjIzMjJiX331Fbt27RqXZ/r06UxXV5cBYMuWLWO2trZs5syZMs8dExPDlJSUWE5ODhOLxUwgEEjlqe2cubm5bMSIEUxTU5MZGBiwwMBA5unpyUaMGCHX9QOQ+RGLxVJ5e/fuzdq2bSuV7uXlJff5qsrPz2cAWH5+fp33JYT8N9Bz4uMaOnQoGzx4sMxtqampDABLTU1lb968YcHBwczW1pY1btyY6ejosJ49e7Lw8HBWWlrK7fPkyRPm6+vLTE1NmYqKCmvevDkbPnw4i4+Pl6s8pqambOPGjVLpPj4+rF27dqy8vJyL62lpabw8GzZsYE2aNGElJSVS+5eWljIdHR0WEhLCpUVHR7M+ffowLS0tpqGhwTp06MBWrlzJ8vLyePtWdz550W+cEFIbek58fhpafGWMsaSkJObi4sIEAgFTUVFhbdu2ZRs2bGBlZWW8fADYwYMHZR4jLy+PAajTeen3TQipDT0n3g+1e9bc7llUVMQGDhzI9PX1mbKyMmvZsiXz8vJiDx8+lDpWRUUFMzU1lRnDHRwc2Jw5c+QqU1X0+yaE1IaeE58WLy8vLtYoKSkxfX191r9/fyYSiVh5eTljjLGHDx+yPn36MB0dHaaiosIsLCzY7NmzWW5uLu9Yubm5zM3NjWlpaTEtLS3m5uYm1S5Znfj4eAaAl19WLF62bBmzs7PjvsuKZ7LaY2uqF9YV/cYJIbWh50TDa0uUFRsiIyMZAObg4MBLf/bsGfPz82MmJiZMSUmJGRoaMi8vL/bnn3/y8snTZ6WiooItW7aMGRkZMVVVVdanTx92/fp13nFev37NZs2axXR0dJiamhobOnQoV7/LyclhSkpKbO/evTKvy8/Pj9na2nLfi4qKmEAgYAKBgBUVFcm8D7LKPG3atNpuIYd+34SQ2tTlOaHAmBxrqBLy/zHGYGNjg2nTpmHu3Ln1csyXL19CIBAgPz+fRkUQQmSi5wT53NFvnBBSG3pOkM8Z/b4JIbWh5wRpKIqKimBsbAyRSISvv/66Xo5Jv29CSG3oOUE+d/QbJ4TUhp4T5HNGv29CSG3q8pygpeGJ3J4+fYpdu3bh8ePHmDRpUr0ff/S2+1BurFnvxz06x6rej0kIIYR8CB8qFpJK9DcBIYQ0bJ9zHKQYRAghn7aKigrk5OQgJCQEAoEAw4cPr/dzfM5xsDoUHwkhhFT1X4yFVVFcJISQ/zZ54iDFCkJIbRp97AIQ4MKFC1BUVISLi4vUtpKSEqxfvx52dnZQV1eHnp4eevbsCbFYjNLSUi5fTk4O/Pz8YG5uDlVVVZiYmGDYsGE4ffo0Hj58CE1NzWo/Dx8+5MoxePBgNG3aFI0bN4atrS1CQkJQXl4OADA0NMTatWtRWFgIHR0dXLx4kVfW4uJi6OrqQkFBAQkJCR/uhhFCCHkvEydOhIKCgtSnb9++0NPTw+rVq2XuFxwcDD09PZSUlCA8PBxNmjSR63zV5ZUV/yIiIrj4pKamBkVFRa58jRs3xrx58+Q654EDBzBgwADo6+tDW1sbPXr0wIkTJ6TyxcTEoG3btlBVVUXbtm1x8OBB3vakpCQMGzYMxsbGUFBQwKFDh3jbS0tL8e2338LW1hYaGhowNjaGp6cnnjx5Ilc5CSGEfFg//vgjtLS0UFZWxqUVFBRAWVkZvXv35uU9e/YsFBQUcO/evRqPWVsMjIyMhKKiIqZPn/5eZa9PS5YsgZKSEho1agQFBQWoqalx8bZdu3YAKld/WL58OYyNjaGmpgZHR0fcvHnzI5ecEELIp6hqnVNZWRmGhoYYMGAARCIRKioquHyOjo5S9VJXV1fesfLy8uDh4QGBQACBQAAPDw+8ePGC2y5vu+f7evjwIZo3b469e/dCJBJBSYnmVyCEkH/D2zHF3NwcAQEBKCwsRFZWFi+GCAQCdO/eHb/99hvvGOHh4TLbQhs3bszLV9N7NgkzMzOEhobyvkuOp66ujvbt22P79u2840ZERHDv+Jo1a4ZJkyYhNzeX237z5k2MGjWKO1bV40vIaqOcPn26VNxTUVFBo0aNoKSkVKc6naurKwYNGsRLO378OBQUFLBkyRJe+qpVq2BsbMx9HzhwIK8Nt1GjRlBRUYGmpmaDqhcTQsh/zfv0QZG8q9PQ0OBii+QZr6WlxYuNNaktTsoTo6v+LaCkpISWLVtixowZyMvLk3muPXv2SJWjXbt2UFBQQHh4uNS2NWvWQFFREWvXruXSYmJioKioWG190sbGBrNnzwYgu16roKBAMZAQ8tFQR9AGQCQSwc/PD+fOneMFk5KSEjg7O2Pt2rWYOnUqLly4gMuXL8PX1xebN2/mKnBZWVno3Lkzzpw5g/Xr1+P69euIjY2Fk5MTfH19YWxsjPT09Go/xsbGOHjwIBwcHNCiRQvEx8fjzp07mDNnDoKCguDq6grGGBhjePbsGQDAxMQEYrGYdx0HDx6EpuZ/d6QeIYR8SlxcXJCdnc37xMTEwN3dHeHh4WCMSe0jFovh4eEBFRWVeimDrPg3fPhwpKenY+vWrSgtLUVAQABOnDiBkydPYtOmTSgpKZHr2ElJSRgwYACOHTuG1NRUODk5YdiwYUhLS+PyJCcnY9y4cfDw8MDvv/8ODw8PjB07FpcuXeLyFBYWws7ODlu2bJF5nqKiIly9ehVLlizB1atXceDAAdy7d++DzA5DCCGk7pycnFBQUIArV65waWfPnoWRkRFSUlJQVFTEpSckJMDY2BhWVu83qlokEmHBggXYs2cP7/iylJeX8zrEfCgdO3bE1KlTsXnzZgDA999/z9UHjx07BgBYv349vv/+e2zZsgUpKSkwMjLCgAED8OrVq3c+r7xxmxBCyOdHUufMysrC8ePH4eTkhDlz5mDo0KG8ARo+Pj68eunbnWcmTJiA9PR0xMbGIjY2Funp6fDw8OC2y9PuWR/MzMzAGMOjR4/Qr1+/ejkmIYQQ+UhiyoMHD7B69WqEhYUhICCA2x4XF4fs7GxcunQJXbt2xahRo3Djxg3eMbS1taXaQv/8809ue23v2WqycuVKZGdn49q1axg5ciSmT5+O6OhoAMC5c+fg6ekJb29v3Lx5E/v27UNKSgqmTJnC7V9UVARzc3OsXbsWRkZGMs8hq41y5cqVvJg3Y8YMqKioYPPmzTh9+nSd6nROTk44d+4cL0YnJCTAxMQE8fHxvLwJCQlwcnICUHnvz5w5w2vD3bp1K8aNG4f09HSsXLmy1nMTQgj5MN6nD8rw4cNx5MgRaGpqwtTUFD/88ANOnjyJo0ePYs6cObXGxqpqipNA7TEa4Ncvf/nlF/z222+YOXOm1Llk9WG5ePEicnJyoKGhIbN8YrEYCxYsgEgk4tKGDx8OXV1d7NixQyr/+fPncffuXXh7e3Npb9drs7OzsX79evluECGE1DMauvyRFRYWYu/evUhJSUFOTg7Cw8OxdOlSAEBoaCiSkpJw5coVdOrUidvH3NwcY8aM4V6qzZw5EwoKCrh8+TIvgLVr1w6TJ0+GkpISLC0tayyDj48Phg8fjp9++olLnzJlCgwNDTF8+HDs3bsX48aN47Z5eXlh06ZNCA0NhZqaGoDKPya8vLywatWq+rk5hBBCPhhVVVWZDYve3t744YcfkJSUBAcHBy797NmzyMjI4FVs3kd18U9LSwtaWlrYsmULevfujXXr1r3T8d8eOb9mzRr8+uuv+O2337iYGhoaigEDBmDRokUAgEWLFiExMRGhoaGIiooCAAwaNEhqNHxVAoEAp06d4qVt3rwZXbt2xcOHD9GyZct3Kj8hhJD6YW1tDWNjYyQkJKB79+4AKl9ajRgxAvHx8bhw4QL69+/PpTs5OaGkpASBgYGIiIjAixcv0L59e6xbtw6Ojo5ISEjApEmTAAAKCgoAgGXLlmH58uUAKl8eXrhwATExMYiPj8f+/fvh6enJlSc8PBz+/v7YvXs3FixYgHv37iEjIwPNmzev9pwAkJubi1mzZuHs2bN4/vw5LCws8N1332H8+PFy3YdRo0Zh1KhRAIBZs2ahWbNmvDoiYwyhoaFYvHgxvv76awDAjh07YGhoiMjISEybNg2TJ0/G06dPceTIEW6/srIytGjRAmvWrMHkyZPh6OiI9u3bQ0VFBTt37kS7du2QmJhY1/82Qgghn4Gqdc7mzZvjiy++QPfu3dGvXz+Eh4dzHWDU1dWr7fRy+/ZtxMbG4uLFi+jWrRsA4Oeff0aPHj1w9+5dWFtb19jumZCQgNatWyM2NhYLFy7EnTt30KNHD+zZswepqamYO3cuHj9+jCFDhkAoFEJdXR1A5Ywutra2UFRUxI4dO6CiooJVq1bBzc0Ns2bNwv79+2FgYIAtW7bUWF8khBBSP6rGlAkTJiA+Ph6HDh3Ct99+CwDQ1dWFkZERjIyMEBQUhM2bNyM+Ph7t27fnjqGgoFBtvAFqf89WEy0tLe7Yq1evxt69e3Ho0CGMGzcOFy9ehJmZGTdrWKtWrTBt2jRe55AuXbqgS5cuAICFCxfKPIesNkoDAwMYGBgAqKzT7d69G0uWLOE653Tv3p1Xp6tJ1UGUVevOCxcuxDfffIOioiKoq6ujpKQEycnJ2LRpEwDgyJEjUm24AwYMwIwZM2o8HyGEkA/rffugaGhoYP369VBWVkZ6ejovNg4aNIg3IKM2NcVJoPYYDfD/FmjRogXGjRsnc3ZPNzc3bNy4EY8ePYKJiQmAyj4sbm5u2Llzp1T+xMREvH79GitXrsTOnTuRlJSEPn36QFlZGR4eHggPD0dgYCDXDiw5XufOnWFnZ8el1VSvJYSQfxvNCPqRRUdHw9raGtbW1nB3d4dYLOZmYYuIiED//v15AVhCWVkZGhoaeP78OWJjY+Hr6ytzFIM8y/aePHkSubm5MgP2sGHDYGVlxXWIkejcuTNatWqFmJgYAMCjR4+QlJTEG5FfneLiYrx8+ZL3IYQQ0jDY2tqiS5cuUiPmRCIRunbtymtAfR81xT8AMDIyws2bN6VG77+riooKvHr1Cjo6OlxacnIyBg4cyMvn7OyMCxcuvNe58vPzoaCgUGMMplhICCH/HkdHR94MJvHx8XB0dISDgwOXLnmZ5eTkhEmTJuH8+fPYs2cPrl27hjFjxsDFxQUZGRmwt7dHaGgob6R61XqUSCTCkCFDIBAI4O7uDqFQKFWeoqIiBAcH45dffsHNmzdhYGBQ4zkB4M2bN+jcuTOOHDmCGzduYOrUqfDw8ODNYv0+MjMzkZOTw4uLqqqqcHBw4OLilClTEBsbi+zsbC7PsWPHUFBQgLFjx3JpO3bsgJKSEs6fPy81q5sExUFCCPlv6tu3L+zs7HDgwAEuLSIiAnp6emjXrh0CAgJ4s5YlJydDIBBwnUCByk4tAoGgTvW25cuXY8uWLbhw4QIePXqEsWPHIjQ0FJGRkTh69ChOnTrFzZotsWPHDujp6eHy5cvw8/PDjBkzMGbMGNjb2+Pq1atwdnaGh4dHrbN/y0JxkBBC3o+amhpKS0ul0ktLS/Hzzz8DqHyHJq/6eM9WVePGjbny2dvb46+//sKxY8fAGMPff/+N/fv3Y8iQIXU6Zm3kqdPVxMrKCsbGxlwd+dWrV7h69SrGjBkDCwsLnD9/HkDlrGqvX7/mZgR91zZcioWEEPJhNYQ+KNWpGiffxYMHDxAbGysz1hsaGsLZ2ZmbybOoqAjR0dHVDuoQCoUYP348lJWVMX78eF5brre3Nx48eMAb5C7pYPu+k+ZQHCSEfEjUEfQjEwqFcHd3B1A5pXVBQQFOnz4NAMjIyICNjU2N+9+/fx+MsVrz1eTevXsAgDZt2sjcbmNjw+WpatKkSdwU2WKxGIMHD4a+vn6t5wsODoZAIOA+ktEYhBBC/j2SJR2qfiQzOk+ePBn79+9HQUEBAKCgoAD79u2rt9lAgZrjHwD4+fmhS5cusLW1hZmZGVxdXSESiVBcXPxO5wsJCUFhYSGvo0pOTg4MDQ15+QwNDZGTk/NO5wAqO+osXLgQEyZMgLa2drX5KBYSQsi/x9HREefPn0dZWRlevXqFtLQ09OnTBw4ODkhISADwfy+zHB0dERUVhX379qF3796wsLBAQEAAevXqBbFYDBUVFQgEAm6kupGRETQ1NQFUDjoIDw/n4purqyuSk5Nx//59XnlKS0sRFhYGe3t7WFtbIycnp8ZzApUzqQUEBKBjx44wNzeHn58fnJ2dsW/fvnq5R5LYV1NclJR3165d3HaxWIwxY8Zw9wAALC0tsX79elhbW1dbT6U4SAgh/102NjbIysoCUDlbS1RUFBISErBkyRLExMRwM1MDlfFJMtNZVQYGBnWqt61evRo9e/ZEp06d4O3tjcTERGzbtg2dOnVC7969MXr0aKllb+3s7BAYGIjWrVtj0aJFUFNTg56eHnx8fNC6dWssXboUubm5uHbtWp3vAcVBQgh5d5cvX0ZkZCT69evHpdnb20NTUxONGzfGvHnzYGZmxmsDBCoHbr/dFirpNFkf79mAyhUTwsPDcf36da589vb2iIiIwLhx46CiogIjIyM0adJEagDC+5KnTlcbySoYQOXqUFZWVtDX1+fVnSXLxVtYWAB49zZcioWEEPJhNYQ+KG+TFSeBmmO0hOSdppqaGiwsLHDr1i1uZvC3TZ48GeHh4WCMYf/+/bCwsEDHjh2l8r18+RIxMTHcfXJ3d8f+/fu5Tplt27ZFt27deBPn7N27F+Xl5VKrNIWFhUldg6xl5SUoDhJCPiTqCPoR3b17F5cvX4arqysAQElJCePGjeM6VzLGeNNMyyIZuVFbPnlUnYnt7XRZx3d3d0dycjIePHiA8PDwWpfHkFi0aBHy8/O5z6NHj96r3IQQQurOyckJ6enpvI9k2aDx48ejoqIC0dHRACpHDjLGuHj1vmqLfwCgoaGBo0eP4v79+wgMDISmpibmzZuHrl271nnGlaioKCxfvhzR0dFSLxHfjm/yxN7qlJaWwtXVFRUVFQgLC6sxL8VCQgj59zg5OaGwsBApKSncyywDAwM4ODggJSUFhYWFSEhIQMuWLXH16lUwxmBlZcVruEtMTMQff/xR43lOnjyJwsJCbrk+PT09DBw4kBffAEBFRQUdOnTgvstzzvLycgQFBaFDhw7Q1dWFpqYmTp48iYcPH9brvaotLk6ZMoVr/Hz69CmOHj0qVQ/88ssvaz0PxUFCCPnvqhpbfHx80L9/f7Rv3x6urq7Yv38/4uLicPXqVS6/rPpZXettVeOuoaEh1NXVYW5uzkt7+vRptfsoKipCV1cXtra2vH0ASO0nD4qDhBBSN5LOH40bN0aPHj3Qp08fXkfK6OhopKWl4fDhw7C0tMQvv/zCWxUIqFyW9u22UEnd5n3fs3377bdc5xRfX1/Mnz+fW4r91q1bmD17NpYuXYrU1FTExsYiMzMT06dPf6dz1eZ92jqdnJxw/vx5lJaWIiEhAY6OjgAg1RG0b9++3D7v2oZLsZAQQj6chtYHpaY4CdQcoyUk7zQvXbrEDZD38/OTeb4hQ4agoKAASUlJEIlE1fZhiYyMhLm5ObfEu2QA/p49e7g83t7e2L9/P7dyhUgkwtdffy01I6qbm5vUNXz11VfV3hOKg4SQD0npYxfgv0woFKKsrAzNmzfn0hhjUFZWRl5eHqysrHD79u0aj9G6dWsoKCjg9u3bGDly5DuVw8rKCgBw+/Zt2NvbS22/c+cO2rZtK5Wuq6uLoUOHwtvbG2/evMGgQYN4yzdVR1VVFaqqqu9UVkIIIfVDQ0MDlpaWMrcJBAKMHj0aYrEY3t7eEIvFGD16dI0zXNZFbfGvadOmXLqFhQUsLCwwZcoULF68GFZWVoiOjsakSZPkOld0dDS8vb2xb98+9O/fn7fNyMhIakT806dPpUbOy6O0tBRjx45FZmYmzpw5U+u9olhICCH/HktLS7Ro0QLx8fHIy8uDg4MDgMo40KpVK5w/fx7x8fHo27cvKioqoKioiNTUVCgqKvKOU3XWS1lEIhGeP38OdXV1Lq2iogJpaWlYtWoVdzw1NTVeI6o85wwJCcHGjRsRGhoKW1tbaGhowN/fHyUlJe9+Y6owMjICUDmLTLNmzbj0t+Oip6cnFi5ciOTkZCQnJ8PMzAy9e/fmHUvWclFvozhICCH/Xbdv30arVq1kbvviiy+grKyMjIwMfPHFFzAyMsLff/8tle/Zs2d1qrdVXTJQQUFBaglBBQUFVFRUVLuPrP0ksfzt/eRBcZAQQurGyckJ27Ztg7KyMoyNjbnnsWSGaRMTE7Ru3RqtW7eGpqYmRo0ahVu3bvEGhDdq1KjattD3fc82f/58TJw4Eerq6mjWrBmvvhccHIyePXti/vz5ACoHGmhoaKB3795YvXo1r/71PuSt09Wk6iDK+Ph4rswODg7w9PTE8+fPkZycDC8vL6l969qGS7GQEEI+nIbSB0WipjgJ1ByjJaq+09y0aROcnJywYsUKbqXDqpSUlODh4YFly5bh0qVLOHjwoMxjikQi3Lx5E0pK/9dlqqKiAkKhEFOnTgVQueLTN998g+joaDg6OuLcuXNYuXKl1LEEAkGt11AVxUFCyIdEM4J+JGVlZdi5cydCQkJ4IwN+//13mJqaIiIiAhMmTEBcXBzS0tJk7l9YWAgdHR04Oztj69atKCwslMr34sWLWssycOBA6OjoICQkRGrb4cOHkZGRITW9tcTkyZORkJAAT09PqZeWhBBCPl3e3t44f/48jhw5gvPnz9fbsvDyxL/qmJmZQV1dXWa8kyUqKgoTJ05EZGQkhgwZIrW9R48eOHXqFC/t5MmTMgdF1ETSCTQjIwNxcXHQ1dWt0/6EEEI+PCcnJyQkJPBmNQEqX2idOHECFy9ehJOTEzp16oTy8nI8ffoUlpaWvI/kxZqKigrKy8t5x8/NzcWvv/6KPXv2SI3+LigowPHjx6stmzznPHv2LEaMGAF3d3fY2dnB3NwcGRkZ9XZ/WrVqBSMjI15cLCkpQWJiIi8u6urqYuTIkRCLxRCLxXIPzCCEEEIA4MyZM7h+/TpGjRolc/vNmzdRWlrKdWDp0aMH8vPzcfnyZS7PpUuXkJ+fX+d6GyGEkE+XpPOHqampVEf9tzk4OKB9+/YICgqS+/jv+55NT08PlpaWMDY2lurcUlRUhEaN+K9iJe/Sqlul713IW6eriYWFBUxMTHD48GGkp6dzgyibNWsGMzMzhISE4M2bN3BycqrxOHVtwyWEEFJ/GlIfFIma4uS7WrZsGTZs2IAnT57I3D558mQkJiZixIgRvMlnJK5fv44rV64gISGBd5+SkpKQkpKCGzduAKicrXTMmDEQi8UQiUQwNzfntS0TQkhDRDOCfiRHjhxBXl4evL29IRAIeNtGjx4NoVCIixcv4ujRo+jXrx9WrVqFXr16QUtLC1euXMG6desgFArRsWNHhIWFwd7eHl27dsXKlSvRoUMHlJWV4dSpU9i2bVutIzo0NDSwfft2uLq6YurUqZg1axa0tbVx+vRpzJ8/H6NHj8bYsWNl7uvi4oJnz57V2yxxhBBC/h3FxcVSs2EqKSlBT08PQGWjqaWlJTw9PWFpaYk+ffrUy3nliX+zZs3C8uXLUVRUhMGDB8PU1BQvXrzApk2bUFpaigEDBtR6nqioKHh6euKHH35A9+7duWtVU1Pjzjtnzhz06dMH69atw4gRI/Drr78iLi4O586d445TUFCA+/fvc98zMzORnp4OHR0dtGzZEmVlZRg9ejSuXr2KI0eOoLy8nDuXjo4OVFRU3vueEUIIeX9OTk7w9fVFaWkp9zILqIx3M2bM4F5mmZiYwM3NDZ6enggJCUGnTp3wzz//4MyZM7C1tcXgwYNhZmaGgoICnD59GnZ2dlBXV8euXbugq6uLMWPGSL3kGzp0KIRCIYYOHSqzbFZWVrWe09LSEjExMbhw4QKaNm2K77//Hjk5OWjTpo1c119bPFNQUIC/vz/WrFnDzaSzZs0aqKurY8KECbxjTZkyBUOHDkV5ebnMmWAIIYQQ4P/qnOXl5fj7778RGxuL4OBgDB06FJ6envjjjz8QERGBwYMHQ09PD7du3cK8efPQqVMn9OzZEwDQpk0buLi4wMfHB9u3bwcATJ06FUOHDoW1tfXHvDxCCCEN2Lx58zBmzBgsWLCAmw2NMSbVFgoABgYGaNSo0Xu/Z6vOsGHD4OPjg23btsHZ2RnZ2dnw9/dH165dYWxsDKCyw+atW7e4fz9+/Bjp6enQ1NTkZherzzpdTZycnBAWFgZLS0veTKIODg7YvHkzzM3N0bJlSy79fdtwCSGE1K+G1AdFXrXFaFkcHR3Rrl07rFmzBlu2bJHa3qZNG/zzzz+8lZuqEgqF6Nq1q8x3nz169IBQKMTGjRsBVE6c07t3b9y6dQsBAQEyO7MWFRVJXYOqqqrMTqiEEPLBMfJRDB06lA0ePFjmttTUVAaApaamsjdv3rDg4GBma2vLGjduzHR0dFjPnj1ZeHg4Ky0t5fZ58uQJ8/X1ZaampkxFRYU1b96cDR8+nMXHx8tdpqSkJObi4sIEAgFTUVFhbdu2ZRs2bGBlZWW8fADYwYMHZR4jLy+PAajTefPz8xkAlp+fL/c+hJD/FnpO1C8vLy8GQOpjbW3Ny7dmzRoGgK1Zs0bqGGKxmAkEArnOJxQKma6uLmNM/vh35swZNmrUKGZiYsJUVFSYoaEhc3FxYWfPnpXrnA4ODjKv0cvLi5dv3759zNramikrKzMbGxsWExPD2x4fH1/jcTIzM2Vup1hICKlv9Jx4P5LntY2NDS/90aNHDACzsLDg0kpKStjSpUuZmZkZU1ZWZkZGRuyrr75i165d4/JMnz6d6erqMgBs2bJlzNbWls2cOVPmuWNiYpiSkhLLycmpNn7Wds7c3Fw2YsQIpqmpyQwMDFhgYCDz9PRkI0aMkOv6a4tnjDFWUVHBli1bxoyMjJiqqirr06cPu379utSxKioqmKmpqcx47uDgwObMmSNXmaqi3zchpDb0nPi0VK1zKikpMX19fda/f38mEolYeXk5Y4yxhw8fsj59+jAdHR2moqLCLCws2OzZs1lubi7vWLm5uczNzY1paWkxLS0t5ubmxvLy8uQqhyT+Vc0vKxYvW7aM2dnZcd9lxTNTU1O2ceNGXlpNbaR1Qb9vQkht/svPCS8vr2rrPZJ6XlpaGi+9oqKCWVtbsxkzZjDGKp/91bXfZWdnc/vJ857t7XggKz68bdOmTaxt27ZMTU2NNWvWjLm5ubG//vpL6jre/jg4OHB56rNOVxPJvZo+fTovfdeuXQwA8/b25qW/bxuuxH/5N04IkQ89J+TT0Pqg1BYn5YnR1f0tEBERwVRUVNjDhw/lOpdAIGBisZgVFxczXV1dtn79epn5QkJCmJ6eHisuLubSrK2tWaNGjdijR4+k8lf3PtLZ2bnasryNft+EkNrU5TmhwFg9rj1AyDt4+fIlBAIB8vPzaWZRQohM9Jz4tK1duxa7d+/mllIg0ug3TgipDT0nSENRVFQEY2NjiEQifP311/VyTPp9E0JqQ88J8jmj3zchpDb0nCCfO/qNE0JqQ88J8jmj3zchpDZ1eU58tkvDX7hwAb1798aAAQMQGxvL21ZSUoLQ0FBEREQgIyMD6urqsLa2xpQpU+Du7g5lZWUAQE5ODoKCgnD06FE8fvwYBgYG6NixI/z9/dGvX79ay2BmZoY///wTQOVStObm5vDz88O0adMAAOHh4Zg0aZLUfqqqqnjz5g0AYOLEidixYwcAQFFREcbGxhgyZAjWrFnDm0pacq6oqCi4urryjteuXTvcunULYrEYEydO5G1bs2YNlixZgqCgICxcuBAAEBMTg7FjxyIzM5O3xIOEjY0NBg4ciE2bNsHR0RGJiYlSeaZNm4Yff/yx1ntU1eht96HcWLNO+8jj6Byrej8mIYQ0dA0hDrZs2RKPHj0CUBnD2rdvT3GwFh8qFpJK9DcBIUReHzuOurq6Ij8/H8ePH+fSjh8/jsGDByMwMBCrVq3i0letWoVt27Zh6tSpWLFiRY3HzczMRHh4OJdPUVERTZo0Qdu2bfH1119jxowZUFVV5fJXF+c0NTUxfPhwAOAth6SpqQlra2t8991379RJ9HONgxR/CCGkZh877lYtx+rVq5GcnIzXr1+jdevWmDhxIvz9/aGoqMjlk8S+5ORkdO/enUsvLi6GsbExnj9/jvj4eDg6OtbpPnxOcZBiHyGkIava3liVk5MTrl27Bn9/fwQGBkptDw4ORkhICJ48eYLIyEj4+/vjxYsXtZ4vPDxcZt6a4h9Q2Ua5fv163LlzBxUVFWjZsiVcXFwQEhJS6zkPHDiAbdu2IT09HcXFxWjXrh2WL18OZ2dnqXMsWbIEf/zxBywsLBAUFISvvvqK256UlIT//e9/SE1NRXZ2Ng4ePIiRI0dy20tLSxEYGIhjx47hwYMHEAgE6N+/P9auXQtjY+Nay/m2zykWvguKn4QQAjx69AjLly/H8ePH8c8//6BZs2YYOXIkli5dCl1dXQDVt1m+67u5hqKmOEgxghAir0YfuwAfikgkgp+fH86dO4eHDx9y6SUlJXB2dsbatWsxdepUXLhwAZcvX4avry82b96MmzdvAgCysrLQuXNnnDlzBuvXr8f169cRGxsLJycn+Pr6yl2OlStXIjs7G9euXcPIkSMxffp0REdHc9u1tbWRnZ3N+0g6j0q4uLggOzsbWVlZ+OWXX/Dbb79h5syZUucyMTGBWCzmpV28eJE73vTp06Gpqcn7rFixAgsWLIBIJOL2GT58OHR1dWVWhM+fP4+7d+/C29ubS/Px8ZG6hvXr18t9jwghhNS/fzMOtmvXTiq+aGpq4q+//gIADBs2DBcvXqzXOGhmZsY718OHD6GgoAB3d3dERERw+168eBE5OTnQ0NCQeZ/EYjHFQUIIIVI+dn3SyckJ586dQ1lZGZeWkJAAExMTxMfH8/LGxsbi2bNn2LBhA9TV1bmPgoICVFRUkJKSwsUnExMTAJWxOzs7Gw8fPkR8fDzGjBmD4OBg2Nvb49WrV7zjS+Lc5cuXAQDGxsaIiIiAktL/jSsVi8XIzs5GSkoK7OzsMGbMGCQnJ9fxrhNCCPmvete4O378eGhqakJDQwPGxsbYunUrnjx5AiUlJfTo0aNO7bgHDx6Eg4MDWrRogfj4eNy5cwdz5sxBUFAQXF1d8faiWlXbYSVtrgKBAHl5eQCAQYMGQVNTE9OnT6+nu0QIIaQ+Sdobq35iYmLg7u6O8PBwqec+UFnv8fDwgIqKSr2Uobr4BwBxcXFwdXXF6NGjcfnyZaSmpiIoKAglJSVyHTspKQkDBgzAsWPHkJqaCn19fbi4uEBdXZ1rT1VXV8fo0aORm5uL33//HR4eHhg7diwuXbrEHaewsBB2dnbYsmWLzPMUFRXh6tWrWLJkCa5evYoDBw7g3r173MBBQgghn6+IiAiZ7wY1NTXRrl27dzrmgwcP8OWXX+LevXuIiorC/fv38eOPP+L06dPo0aMHnj9/zuWld3OEECLbZzkjaGFhIfbu3YuUlBTk5OQgPDwcS5cuBQCEhoYiKSkJV65cQadOnbh9zM3NMWbMGK4SNXPmTCgoKODy5cu8ziPt2rXD5MmT5S6LlpYWjIyMAACrV6/G3r17cejQIYwbNw5A5QhyyfbqqKqqcnlatGiBcePGITw8XCqfm5sbNm7ciEePHnEv+EQiEdcpJjAwEKNGjeLyX7p0CfPmzcPKlSuxc+dOJCUloU+fPlBWVoaHhwfCw8MRGBjIm+FFJBKhc+fOsLOz49LU1dVrvQZCCCH/nn87Dh47dgylpaVS5XBwcICfnx830+aXX35Zb3FQKBQiPT2dd65hw4ZBLBbjiy++4NJFIhHc3Nywc+dOqeMmJibi9evXFAcJIYTwNIT6pJOTEwoKCnDlyhVuprGEhAQsXLgQ33zzDYqKiqCuro6SkhJcvXoVK1aswNixY3nHcHBwwMSJE9GxY0dep00AUFJS4mKXsbExbG1tMWDAANjZ2WHdunVYvXo1l1cS54yMjGS+DAWAJk2acHl+/PFH7NmzB4cPH0aPHj1qvVZCCCH/be8Td//66y+sXbsW3t7euHv3Lk6ePAl1dXUAlYMODQwM5Iq7hYWF8PHxwfDhw/HTTz9x6VOmTIGhoSGGDx+OvXv3cvVYAPDy8sKmTZsQGhqKlStXIiAggIu7W7duxS+//IJu3brRsn6EENJAVW1vrMrb2xs//PADkpKS4ODgwKWfPXsWGRkZvMHh76Om+AcAR44cQa9evTB//nwuzcrKijcbZ01CQ0N53yMiIvDFF19g8ODB8PPzAwDMnj0bBQUF2LVrF0xNTbFo0SIkJiYiNDQUUVFRACoHNgwaNKja8wgEApw6dYqXtnnzZnTt2hUPHz6UudoSIYSQz8Pw4cPRrVs3mdskKzfUla+vL1RUVHDy5EmoqakBqFx9sFOnTrCwsMDixYuxbds2AO/3bu6vv/5CQEAATp48ieLiYrRp0wZbt25Ft27dsHz5chw6dAizZ8/G8uXL8fz5c3h4eGDLli0ICQnB999/j4qKCsyZMweLFy/mjrl8+XKIRCL8/fff0NXVxejRo7Fp06Z3Kh8hhLyPz3JG0OjoaFhbW8Pa2hru7u4Qi8XcC6uIiAj079+f13gooaysDA0NDTx//hyxsbHw9fWVOYNYkyZN3rlsjRs3ltlZRl4PHjxAbGyszOBpaGgIZ2dnbgazoqIiREdHY/r06VBUVIShoSEsLS25z4kTJ+Dh4QFlZWWMHz8eQqGQO5a3tzcePHjAm1JbUjF934pucXExXr58yfsQQgipP/92HDQ1NeXFF8lHWVkZjRs35uWtrzjYuHFjqXPZ2NjAxcUFMTExAP4vDlb34k8oFGL8+PH/ehwEKBYSQkhD1hDqk1ZWVjA2NuZm/3z16hWuXr2KMWPGwMLCAufPnwdQOfP1mzdvMG7cOJlxWF9fX6oTaHVsbGwwaNAgHDhwQK781VFWVoaSklKN8Z7iICGEEIn3ibutWrWCjo4Ozp49izlz5qBDhw5cHDQwMAAgX9w9efIkcnNzERAQILVt2LBhsLKy4jrESHTu3BmtWrVCTEwMDAwMoKqqiitXrmDOnDkAgObNm/PKURXFQUIIabhsbW3RpUsXqdX3RCIRunbtivbt29fLeWqKfwBgZGSEmzdv4saNG/VyPg0NDRQXF6N169ZcrLxx4wa++uormJqacvmcnZ1x4cKF9zpXfn4+FBQUaozBFAsJIeTTp6WlJfPdoKWlJS+2yOv58+c4ceIEZs6cyXUClTAyMoKbmxuio6OrHagur4KCAjg4OODJkyc4fPgwfv/9dyxYsAAVFRVcnj/++APHjx9HbGwsoqKiIBKJMGTIEPz1119ITEzEunXrEBgYiIsXLwIA9u/fj40bN2L79u3IyMjAoUOHYGtrW20ZKA4SQj6kz7IjqFAohLu7O4DK5R0KCgpw+vRpAEBGRgZsbGxq3P/+/ftgjNWary7KysoQHh6O69evo1+/flx6fn6+1FTZAwcO5O175MgRaGpqQk1NDRYWFrh16xa+/fZbmeeZPHkyt2zF/v37YWFhgY4dO0rle/nyJbfMBQC4u7tj//79XJBp27YtunXrxqvs7t27F+Xl5Rg/fjzvWGFhYVLXIGs5XYng4GAIBALuI5m9lBBCSP2gONiw4yBAsZAQQhqyhhJHHR0dkZCQAKBy9hkrKyvo6+vDwcGBS5csF29hYfFe55KwsbFBVlYWL60uca64uBirV6/Gy5cvefH+bRQHCSGESDSEuHvv3j0AQJs2bWRut7Gx4fJUNWnSJIhEIgCVywUPHjwY+vr6tZ6P4iAhhHx8kvbGqp9Vq1YBqGxf3L9/PwoKCgBUdhjZt29fvc0GCtQc/wDAz88PXbp0ga2tLczMzODq6gqRSITi4uJ3Ol9ISAgKCwt5K0nk5OTA0NCQl8/Q0BA5OTnvdA4AePPmDRYuXIgJEybUOCs2xUJCCCFvy8jIAGOs2npZmzZtkJeXh2fPngF4t3dzABAZGYlnz57h0KFD6NWrFywtLTF27FjeykYVFRUQiURo27Ythg0bBicnJ9y9exehoaGwtrbGpEmTYG1tzbXRPnz4EEZGRujfvz9atmyJrl27wsfHp9oyUBwkhHxIn11H0Lt37+Ly5ctwdXUFULnk3bhx47hGOcYYb4lXWSSjCGrLJ49vv/2W67zi6+uL+fPnY9q0adx2LS0tpKen8z5vjzR0cnJCeno6Ll26BD8/Pzg7O3NLN7xtyJAhKCgoQFJSEkQiUbWzoEVGRsLc3Jxb2rZjx44wNzfHnj17uDze3t7Yv38/Xr16BaByxOPXX38tNYrPzc1N6hq++uqrau/JokWLkJ+fz30ePXpU/Q0khBBSJxQHG34cBCgWEkJIQ9WQ4qiTkxPOnz+P0tJSJCQkwNHREQCkOoL27dv3vc5TlazrkyfOjR8/HpqamlBXV8f333+PDRs21Lh8IMVBQgghQMOKu1WPJStd1vHd3d2RnJyMBw8eIDw8XK5l6AGKg4QQ0hBI2hurfnx9fQFU1m8qKioQHR0NANzsY5J49b5qi39A5QyeR48exf379xEYGAhNTU3MmzcPXbt2RVFRUZ3OFxUVheXLlyM6Olpqpuq345s8sbc6paWlcHV1RUVFBcLCwmrMS7GQEEJIXUnqayoqKgDe7d0cAKSnp6NTp07Q0dGpNo+ZmRm0tLS474aGhmjbti0aNWrES3v69CkAYMyYMXj9+jXMzc3h4+ODgwcPoqysrNrjUxwkhHxI8q0R9wkRCoUoKytD8+bNuTTGGJSVlZGXlwcrKyvcvn27xmO0bt0aCgoKuH37NkaOHPle5Zk/fz4mTpwIdXV1NGvWTKoC1ahRI1haWtZ4DA0NDS7Ppk2b4OTkhBUrVnCjE6tSUlKCh4cHli1bhkuXLuHgwYMyjykSiXDz5k3eMoEVFRUQCoWYOnUqAMDV1RXffPMNoqOj4ejoiHPnzmHlypVSxxIIBLVeQ1WqqqpQVVWVOz8hhBD5URxs+HEQoFhICCENVUOKo05OTigsLERKSgri4+Mxf/58AJUdQT09PfH8+XMkJyfDy8vrnc/xttu3b6NVq1a8NHni3MaNG9G/f39oa2vLXAL3bRQHCSGEAA0n7lpZWQGojIP29vZS2+/cuYO2bdtKpevq6mLo0KHw9vbGmzdvMGjQIG4gYU0oDhJCyMdXtb3xbQKBAKNHj4ZYLIa3tzfEYjFGjx5d4wyXdVFb/GvatCmXbmFhAQsLC0yZMgWLFy+GlZUVoqOjMWnSJLnOFR0dDW9vb+zbtw/9+/fnbTMyMpKa/fPp06dSs4TKo7S0FGPHjkVmZibOnDlT672iWEgIIeRtlpaWUFBQwK1bt2TW7e7cuQN9fX1uspZ3eTcHQGrZeVmUlZV53xUUFGSmSZaTNzExwd27d3Hq1CnExcVh5syZ+N///ofExESp/QCKg4SQD+uzmhG0rKwMO3fuREhICK/n/++//w5TU1NERERgwoQJiIuLQ1pamsz9CwsLoaOjA2dnZ2zduhWFhYVS+V68eCF3mfT09GBpaQljY+N6GZkOAMuWLcOGDRvw5MkTmdsnT56MxMREjBgxgldhlLh+/TquXLmChIQE3n1KSkpCSkoKbty4AaBylrYxY8ZALBZDJBLB3Nycm4WGEEJIw0NxsBLFQUIIIe+iocVRCwsLmJiY4PDhw0hPT4eDgwMAoFmzZjAzM0NISAjevHkDJyen97puiTt37iA2NhajRo2q875GRkawtLSUqxMoIYQQAjSsuDtw4EDo6OggJCREatvhw4eRkZGB8ePHy9x38uTJSEhIgKenJxQVFWu/cEIIIZ8Eb29vnD9/HkeOHMH58+frbVl4eeJfdczMzKCuri4z3skSFRWFiRMnIjIyEkOGDJHa3qNHD5w6dYqXdvLkSZmDImoi6QSakZGBuLg46Orq1ml/QgghBKgcaDdgwACEhYXh9evXvG05OTmIiIjAxIkT3/s8HTp0QHp6Op4/f/7ex6pKTU0Nw4cPx6ZNm5CQkIDk5GRcv369Xs9BCCHy+KxmBD1y5Ajy8vLg7e0NgUDA2zZ69GgIhUJcvHgRR48eRb9+/bBq1Sr06tULWlpauHLlCtatWwehUIiOHTsiLCwM9vb26Nq1K1auXIkOHTqgrKwMp06dwrZt22odjS4vxpjUiDsAMDAw4E0tXZWjoyPatWuHNWvWYMuWLVLb27Rpg3/++Qfq6uoy9xcKhejatSv69Okjta1Hjx4QCoXYuHEjgMrKbu/evXHr1i0EBATI7MRTVFQkdQ2qqqoyO98QQgj5cCgOVqI4SAgh5F00xDjq5OSEsLAwWFpa8mZlcXBwwObNm2Fubo6WLVvW+VrLysqQk5ODiooK5ObmIiEhAatXr0bHjh25mUclKM4RQgj5EBpS3NXQ0MD27dvh6uqKqVOnYtasWdDW1sbp06cxf/58jB49GmPHjpW5r4uLC549e1Zvs8QRQgj5dxQXF0vVc5SUlKCnpwegss5laWkJT09PWFpaymxHfBfyxL9Zs2Zh+fLlKCoqwuDBg2FqaooXL15g06ZNKC0txYABA2o9T1RUFDw9PfHDDz+ge/fu3LWqqalx550zZw769OmDdevWYcSIEfj1118RFxeHc+fOcccpKCjA/fv3ue+ZmZlIT0+Hjo4OWrZsibKyMowePRpXr17FkSNHUF5ezp1LR0eHW76XEEIIkceWLVtgb28PZ2dnrF69Gq1atcLNmzcxf/58WFlZYenSpVzed22zHD9+PNasWYORI0ciODgYzZo1Q1paGoyNjdGjR493Knd4eDjKy8vRrVs3qKurY9euXVBTU4Opqek7HY8QQt4L+4wMHTqUDR48WOa21NRUBoClpqayN2/esODgYGZra8saN27MdHR0WM+ePVl4eDgrLS3l9nny5Anz9fVlpqamTEVFhTVv3pwNHz6cxcfHy1UeU1NTtnHjxmq3i8ViBkDmJzs7mzHGmJeXFxsxYoTUvhEREUxFRYU9fPhQrnMJBAImFotZcXEx09XVZevXr5eZLyQkhOnp6bHi4mIuzdramjVq1Ig9evRIKr+Dg4PM8js7O1dblrfl5+czACw/P1/ufQgh/y30nJAPxcHqz9WQ4yBj9BsnhNSOnhMfXkOLo4z9X6ycPn06L33Xrl0MAPP29q523+pi47Jly7h4paioyHR0dFivXr3Yxo0b2Zs3b3h55YlzANjBgwflviZZ6PdNCKkNPSc+Pw0x7iYlJTEXFxcmEAiYiooKa9u2LduwYQMrKyvj5asp9uXl5TEAdTov/b4JIbWh50T98vLyklnPsba25uVbs2YNA8DWrFkjdQyxWMwEAoFc5xMKhUxXV5cxJn/8O3PmDBs1ahQzMTFhKioqzNDQkLm4uLCzZ8/Kdc7q6nJeXl68fPv27WPW1tZMWVmZ2djYsJiYGN72+Pj4Go+TmZlZbfsuxUJCSH2i58R/R2ZmJvPy8mKGhoZMQUGBAWBff/01Kyws5PK877u5rKwsNmrUKKatrc3U1dXZl19+yS5dusQYq2w7tbOz4+WX9a7SwcGBzZkzhzHG2MGDB1m3bt2YtrY209DQYN27d2dxcXFyXzP9vgkhtanLc0KBMcbeof8oIfXm5cuXEAgEyM/Pp9HzhBCZ6DlBPnf0GyeE1IaeE+RzRr9vQkht6DlBPmf0+yaE1IaeE5+2tWvXYvfu3bhx48bHLkqDRb9xQkht6Dnx37Vs2TJ8//33OHny5DvP2NnQ0e+bEFKbujwnGvzS8BMnTsSOHTsAVC7LYGJigq+//horVqzAs2fP0KpVKy6vtrY22rRpg8WLF2PYsGFcenh4OCZNmiR1bFVVVbx584b7npOTg6CgIBw9ehSPHz+GgYEBOnbsCH9/f/Tr1w8AYGZmBn9/f/j7+3Pf//zzTwCVSyqYm5vDz88P06ZN444bERGB9evXIyMjAwKBAC4uLtiwYQN0dXUBADdv3sTSpUuRmpqKP//8Exs3buSOL5GUlIT//e9/SE1NRXZ2Ng4ePIiRI0fy8jDGsGLFCvz000/Iy8tDt27dsHXrVrRr167W++zq6or8/HwcP36cSzt+/DgGDx6MwMBArFq1iktftWoVtm3bhidPngAAYmJisH79ety5cwcVFRVo2bIlXFxcEBISUut5qxq97T6UG2vWaZ+qjs6xeud9CSHkv+jChQvo3bs3BgwYgNjYWN62kpIShIaGIiIiAhkZGVBXV4e1tTWmTJkCd3d3KCsrA5AvdtZEEkeTk5PRvXt3Lt3f3x/p6elISEjg0p4/f46VK1fi0KFDePLkCXR1deHi4oIVK1ZUuyxucHAwvvvuO8yZMwehoaFS2yMjI+Hh4QEfHx/8+OOPAIDU1FR8+eWXOHv2LHr16iW1j7OzM1RVVXH48GHe3ylv53n7nsrjfWPhfx39LUAIqUl1z2wnJydcu3YN/v7+CAwMlNoeHByMkJAQPHnyBJGRkfD398eLFy9qPV94eDgvb3X10p9//hlTpkzhttvY2EgtYbt3716MGzcOpqamyMrKqvXcBw4cwLZt25Ceno7i4mK0a9cOy5cvh7OzMy9fTEwMlixZgj/++AMWFhYICgrCV199xW2vrR5aWlqKwMBAHDt2DA8ePIBAIED//v2xdu1aGBsb11rOt32OcZBiEyHkQ/hc63LBwcE4cOAA7ty5AzU1Ndjb22PdunWwtrbm8sjT/llcXIyAgABERUXh9evX6NevH8LCwtCiRQup65g6dSqEQiEiIiLg6uoKAAgJCcHKlSuRnZ0NdXV1Xv43b97AyMgIS5cuxdy5c3ltw1UFBwdj4cKFtd7Hqj71OEgxjxDysTWU+Ch5h1hUVITbt29j/fr1KCgowJkzZ9C3b184OjoiMTFRat/S0lIoKVW+tpUVn6q6f/8+goKCcOrUKTx79gzGxsbo3r075s2bhxs3bsise1YVHx8PR0fHarcvX74chw4dQnp6Oi/9xYsXaNq0Kbd/VlYW7z1tkyZNYGtri1WrVsHBwaHGMsjyqcfCd0UxlBDyMf3444+YP38+8vLyuDhUUFCApk2bonv37jh79iyX9+zZs+jTpw/u3r0LK6vqn11vt4u+Tda7ueqsWLECZmZmuHTpErp164ZGjRrV/SLlIE999EOrKQ5SrCCEyOvDPCXrmYuLC7Kzs/HgwQOsXr0aYWFhCAgI4LbHxcUhOzsbly5dQteuXTFq1CipkXXa2trIzs7mfao20mVlZaFz5844c+YM1q9fj+vXryM2NhZOTk7w9fWVKlNERAQ0NTXx8OFDqKioQF1dHQoKCrh37x6mT5+O6OhoAMC5c+fg6ekJb29v3Lx5E/v27UNKSgqmTJnCHauoqAjm5uZYu3YtjIyMZN6DwsJC2NnZYcuWLdXep/Xr1+P777/Hli1bkJKSAiMjIwwYMACvXr2q9R47OTnh3LlzKCsr49ISEhJgYmKC+Ph4Xt6EhAQ4OTkBqLz3rq6uGD16NC5fvozU1FQEBQWhpKSk1nMSQgj5uEQiEfz8/HDu3Dk8fPiQSy8pKYGzszPWrl2LqVOn4sKFC7h8+TJ8fX2xefNm3Lx5ExEREdDQ0ICxsTG2bt2KJ0+eQElJCbm5uUhJSZEZO6vTuHFjfPvttzXmef78Obp37464uDiEhYXh/v37iI6Oxh9//IEuXbrgwYMHUvukpKTgp59+QocOHWq8BwsWLMCePXtQVFQEAOjcuTPs7OwgFoul8j969AhxcXHw9vbm0iR/p1T9REVFyXv5hBBC/kWyntkxMTFwd3dHeHg4ZC2YIRaL4eHhARUVlfc+v6ReumXLFqirq0NdXR3+/v7Q1NTE9OnTAQAZGRlITk7m7ScSiaod9CBLUlISBgwYgGPHjiE1NRVOTk4YNmwY0tLSuDzJyckYN24cPDw88Pvvv8PDwwNjx47FpUuXuDy11UOLiopw9epVLFmyBFevXsWBAwdw7949DB8+vC63hRBCSB29T10OqHs7aHXquy6XmJgIX19fXLx4EadOnUJZWRkGDhyIwsJCLo887Z/+/v44ePAg9uzZg3PnzuH+/fswNTWFpqam1EcoFGL+/PkQCoXc/p6ennj9+jViYmKkricmJgZFRUXw8PDg0iSdRqt+/Pz85L6PhBBC6sfHio/t2rXj4srDhw/x7bffQlNTEwYGBvjyyy9RWFiIY8eOoW/fvtw+Pj4+UrFD0vmmqKgI0dHRUvFJ4sqVK7C2tsbOnTuRm5sLJSUl/P3334iJiUG3bt3AGOMdt0ePHlLns7e3r6/bDuD/3tMmJiZCW1sbgwcPRmZmZr2egxBCyIfh5OSEgoICXLlyhUs7e/YsjIyMkJKSwr07Ayr7iRgbG9fYCVQest7NVae8vBxeXl7w9/eXqxPomjVrZNb9NDU1MWjQoGr3k6c+WlfUZ4YQ8jE0+BlBgcqZOyUdJCdMmID4+HgcOnSIa2jU1dWFkZERjIyMEBQUhM2bNyM+Ph7t27fnjqGgoFBtJ0sAmDlzJhQUFHD58mVoaGhw6e3atcPkyZOl8g8fPhzdunWDg4MDJk6cyBtdN2DAABw6dAjjxo3DxYsXYWZmhtmzZwMAWrVqhWnTpmH9+vVc/i5duqBLly4AUO1I8UGDBtUYmBhjCA0NxeLFi/H1118DAHbs2AFDQ0NERkbyZiiVpWqAl4ziT0hIwMKFC/HNN9+gqKgI6urqKCkpQXJyMjZt2gQAOHLkCHr16oX58+dzx7KyspKarZQQQkjDUlhYiL179yIlJQU5OTkIDw/H0qVLAQChoaFISkrClStX0KlTJ24fc3NzjBkzBiUlJbCwsMBPP/2Eu3fv4uTJk7xZUpSVlSEQCOQuy7Rp07Bt2zYcO3YMgwcPlpln8eLFePLkCe7fv8/F85YtW+LEiRNo3bo1fH19ebNaFxQUwM3NDT///DNWr14t85hZWVm4cOECYmJiEB8fj/3798PT0xMA4O3tje+++w6bNm3i/V0QHh4OfX19DBkyhEur+ncKIYSQhq26Z7a3tzd++OEHJCUl8WYtOXv2LDIyMngDAN6HpF7q6ekpc3bO1atX4+uvv4ZIJOKWOvrrr7+QkJCAb775Ru6BBm/Pgr1mzRr8+uuv+O2337jYHhoaigEDBmDRokUAgEWLFiExMRGhoaHceWqrhwoEApw6dYqXtnnzZnTt2hUPHz6sU+dVQggh8nnfuhxQ93bQ6tR3Xe7t2dvEYjEMDAyQmpqKPn36yNX+mZ+fD6FQiF27dqF///4AgEOHDsHGxgabN29G7969ueMfOHAAe/bswaJFi9CsWTNkZWXBzMwM+vr6GDZsGEQiEa/DJ1D5wnL48OHQ19fn0rS0tKhOSAghH9nHjI/Hjh1DaWkpAHDvDN3c3ODv74+bN28iLi4Obdq04e2jrq5ebezYt28f2rZtKxWfgMp3gRMnTkTbtm0RExMj1SHm5cuXaN26NbS0tLg0yWQ2HzJWVX1Pu337drRo0QInT56s9d0kIYSQj8/a2hrGxsZISEjg9RMZMWIE4uPjceHCBa5uJZkwrKSkBIGBgYiIiMCLFy/Qvn17rFu3Do6OjkhISOD6zigoKACoXN59+fLlAGp+Nwf832yiu3fvxoIFC3Dv3j1kZGSgefPm1Z4TAHJzczFr1iwkJiairKwMLVu2xIwZM3grCaupqVV7H2qrj65cuRL79u3D9evXefk6d+6MIUOGYOXKlZg4cSJevHiBbt26YfPmzVBRUZFrdSdCCKlPn8SMoG9TU1PjKlVVlZaW4ueffwYAbhkHeTx//hyxsbHw9fXlVe4kmjRpIpWmpaUFS0tLKCsrQ19fH5aWltxHS0uLK5+9vT3++usvHDt2DIwx/P3339i/fz+vA0l9yMzMRE5ODgYOHMilqaqqwsHBARcuXKh1fysrKxgbG3Ozf7569QpXr17FmDFjYGFhgfPnzwMALl68iNevX3MzghoZGeHmzZtSM7ASQghp2KKjo2FtbQ1ra2u4u7tDLBZzs6BFRESgf//+vIZRCWVlZWhoaKC0tBRnz57FnDlz0KFDB14cNDU1lRk7q2NmZobp06dj0aJFqKiokNpeUVGBPXv2wM3NTarBUk1NDTNnzsSJEyfw/PlzLt3X1xdDhgzhKqeyiEQiDBkyBAKBAO7u7rwR9m5ubigtLcW+ffu4NMYYwsPD4eXlxY3QJ4QQ8nmwtbVFly5dpGaDFolE6Nq1K2+QYX2Q1CerfgwNDaGoqIhvvvkG0dHR3Gj48PBwuLi4wNDQ8J3PV1FRgVevXkFHR4dLS05O5tUfAcDZ2Vmu+mNN8vPzoaCgUKe/BQghhMjvfety79IOWp0PUZerKj8/HwC4+CVP+2dqaipKS0t5eaysrGBra4usrCxe7D1y5Ai8vb0hEAgwePBg3t8B3t7eSExM5M1mlpWVhfj4+HobIEIIIaT+fMz4aGpqysUWZWVlqKmpYfbs2fjzzz+RnJws1Qm0NkKhEO7u7jLjU3p6Om7evInvvvsOVlZWUvXKL774gtcJ9GOQTBgg6z0uIYSQhsnR0ZG3Smx8fDwcHR3h4ODApUsmDHNycsKkSZNw/vx57NmzB9euXcOYMWPg4uKCjIwM2NvbIzQ0lLdib9XVfmt6NydRVFSE4OBg/PLLL7h58yYMDAxqPCcAvHnzBp07d8axY8dw69Yt+Pn5Yf78+cjNzeXiZPPmzeW+J2/XRydPnoxbt24hJSWFy3Pt2jWkpaVh4sSJXNrp06dx+/ZtnDp1CkeOHJH7fIQQUl8+uY6gly9fRmRkJPr168el2dvbQ1NTE40bN8a8efNgZmaGsWPH8vbLz8+XmvpZ0iB4//59MMZgY2PzXmUrKytDeHg4rl+/zpXP3t4eERERGDduHFRUVGBkZIQmTZpg8+bN73Wut+Xk5ACA1MtBQ0NDblttJCM0gMqZb6ysrKCvrw8HBwcuXbJcvIWFBQDAz88PXbp0ga2tLczMzODq6gqRSITi4uJqz1NcXIyXL1/yPoQQQv5dkgZFoHKZ3IKCApw+fRpA5ZK0tcXE+oqdEoGBgcjMzERERITUtmfPnuHFixfVNpq2adMGjDHcv38fALBnzx5cvXoVwcHB1Z6voqIC4eHh3D1wdXVFcnIydwwdHR2MHDmS19CakJCABw8eSM0AcOTIEam/MVatWlXj9VIsJISQj6OmZ/bkyZOxf/9+FBQUAKicXXrfvn312tnj7XqprBlZOnbsCAsLC+zfv58bhFCX2dlkCQkJQWFhIa+enJOT8171R1nevHmDhQsXYsKECdDW1q42H8VBQgh5d59zXa4qxhjmzp2LXr16cQMy5Gn/zMnJgYqKCpo2bVptHqDyXl28eBHjxo0DAK7TkKRDq7OzM4yNjREeHs7tIxaLYWxsLDWQQrIEcNWPpC1VFoqDhBBS/xpSfFy1ahXS09Nx9uzZaldJCAsL48WNefPmcWWtKT5JOrvUVxyvb4WFhVi0aBEUFRV5q228jWIhIYQ0LI6Ojjh//jzKysrw6tUrpKWloU+fPrx+IpIJwxwdHREVFYV9+/ahd+/esLCwQEBAAHr16gWxWAwVFRUIBAJuZSQjIyNoamoCqP3dnERpaSnCwsJgb28Pa2tr5OTk1HhOAGjevDkCAgLQsWNHmJubw8/PD87OzrwJX+Qlqz7aokULODs7894bisViODg4wNzcnEvT0NDAL7/8gnbt2lU7uQDFQULIh/RJdASVvKxr3LgxevTogT59+vA6UkZHRyMtLQ2HDx+GpaUlfvnlF95MJ0DljCvp6em8j+QhLRkVKJmauq4kjX1qamrw9fXF/PnzueUObt26hdmzZ2Pp0qVITU1FbGwsMjMzMX369Hc6V23evgbGmNzX5eTkhPPnz6O0tBQJCQncNNpvdwTt27cvt4+GhgaOHj2K+/fvIzAwkKuwdu3alZvB5m3BwcEQCATcx8TEpO4XSggh5J3dvXsXly9fhqurKwBASUkJ48aNg0gkAiBf7Hjf2Pk2fX19BAQEYOnSpdxyTPKqWpZHjx5hzpw52L17Nxo3blztPidPnkRhYSG33K2enh4GDhzI3QOgcgaYpKQkrgIqEonQs2dPWFtb847l5OQk9TeGr69vjWWmWEgIIR9HTc/s8ePHo6KiAtHR0QAq65mMMS5e1oe366XVzb45efJkiMViJCYmoqCgoNrlduURFRWF5cuXIzo6GgYGBrxt71N/fFtpaSlcXV1RUVGBsLCwGvNSHCSEkHfzOdfl3jZr1ixcu3YNUVFRUtveJX69nUcoFMLZ2Rl6enoAgMGDB6OwsBBxcXEAAEVFRXh5eSE8PBwVFRVgjGHHjh2YOHEiFBUVeceeP3++1N8X3bp1q7YsFAcJIaR+NbT4OHDgQBQWFmLNmjXV5nFzc+PFjUWLFgGoPT7VdxyvL5IJe7S0tPDbb78hPDwctra21eanWEgIIQ2Lk5MTCgsLkZKSwk0YZmBgAAcHB6SkpKCwsBAJCQlo2bIlrl69CsYYrKyseIMaEhMT8ccff9R4HnnezQGAiooKOnTowH2X55zl5eUICgpChw4doKurC01NTZw8eRIPHz6s8/2orj7q4+ODqKgovHnzBqWlpYiIiJAawG9rawsVFZUaj09xkBDyIX0S65o6OTlh27ZtUFZWhrGxMbfse1ZWFgDAxMQErVu3RuvWraGpqYlRo0bh1q1bvJdcjRo1gqWlpczjt27dGgoKCrh9+zZGjhxZ5/LNnz8fEydOhLq6Opo1a8argAUHB6Nnz56YP38+AKBDhw7Q0NBA7969sXr1ajRr1qzO55NFMpNMTk4O75hPnz6VewnBqgE+Pj6eK7ODgwM8PT3x/PlzJCcnw8vLS2pfCwsLWFhYYMqUKVi8eDGsrKwQHR2NSZMmSeVdtGgR5s6dy31/+fIlBTdCCPkXCYVClJWV8ZZAYIxBWVkZeXl5sLKywu3bt2s8xvvGTlnmzp2LsLAwqc4j+vr6aNKkCW7duiVzvzt37kBBQQEWFhZISkrC06dP0blzZ257eXk5kpKSsGXLFhQXF0NRUREikQjPnz/nlioCKkcipqWlYdWqVVBUVET//v1hamqK8PBwLFiwAAcOHMCWLVukzq+hoVHt3xjVoVhICCEfR03PbIFAgNGjR0MsFsPb2xtisRijR4+ucWbLuqqpXlqVm5sbFixYgOXLl8PT0xNKSu9WdY+Ojoa3tzf27duH/v3787YZGRlJzf5Zl/pjVaWlpRg7diwyMzNx5syZWu8ZxUFCCHk3n3Ndrio/Pz8cPnwYSUlJaNGiBZcuT/unkZERSkpKkJeXx5sV9OnTp7C3twdQWUfcuXMncnJyeDG2vLwcQqGQm/Fz8uTJCA4OxpkzZwAADx8+lNnWqaenV6c6IcVBQgipXw0tPvbr1w+zZ8/GiBEjUF5eLnOFQIFAIBU75IlPVlZWAIDbt2+jY8eO71XOmmhra3NL4lb14sULrvxVRUdHo23btmjSpAl0dXVrPT7FQkIIaVgsLS3RokULxMfHIy8vj5vV2cjICK1atcL58+cRHx+Pvn37oqKiAoqKikhNTZUaJCeZ+bM68rybAwA1NTVenxt5zhkSEoKNGzciNDQUtra20NDQgL+/f50HLFZXHwWAYcOGQVVVFQcPHoSqqiqKi4sxatQoXh4NDY1az0FxkBDyIX0SM4JKXtaZmppynUCr4+DggPbt2yMoKEju4+vo6MDZ2Rlbt25FYWGh1HZJxaY6ksY+Y2NjqVF4RUVFaNSIf5slwUkycq8+tGrVCkZGRjh16hSXVlJSgsTERK6RszYWFhYwMTHB4cOHkZ6ezgX4Zs2awczMDCEhIXjz5g2cnJxqPI6ZmRnU1dVl3ksAUFVVhba2Nu9DCCHk31FWVoadO3ciJCSEN+r8999/h6mpKSIiIjBhwgTExcUhLS1N5v6FhYXvHTtl0dTUxJIlSxAUFMRbBqFRo0YYO3YsIiMjpTqsvH79GmFhYXB2doaOjg769euH69ev867tyy+/5EbZKyoqIjc3F7/++iv27NkjNWtLQUEBjh8/DqByZP2kSZOwY8cOREZGcuWoDxQLCSGkYfL29sb58+dx5MgRnD9/vl6Xha8LHR0dDB8+HImJie+8LHxUVBQmTpyIyMhIDBkyRGp7jx49ePVHoHJUvrz1RwlJJ9CMjAzExcXJ9dKP4iAhhNTd516XAyrbSmfNmoUDBw7gzJkzaNWqFW8fedo/O3fuDGVlZV6e7Oxs3Lhxg8tz7NgxbrnDqvdy3759OHToEHJzcwFUtpU6ODhALBZDJBLB0dFRqtPqu6A4SAgh9aehxscBAwbgyJEjEIlE8PX1let9oDzxqWPHjmjbti1CQkK45eLfp5zVsbGxwV9//SUVv1NSUmQOcDQxMYGFhYVc9UGAYiEhhDRETk5OSEhI4K0cC1T2vzlx4gQuXrwIJycndOrUCeXl5Xj69CksLS15H8ngPRUVFZSXl/OOL++7OVnkOefZs2cxYsQIuLu7w87ODubm5sjIyJD7+murjwKVs457eXlBLBZDLBbD1dWV16lVXhQHCSEf0ifREbSu5s2bh+3bt+Px48dcGmMMOTk5Uh9JRSksLAzl5eXo2rUrYmJikJGRgdu3b2PTpk3o0aPHO5dl2LBhOHDgALZt24YHDx7g/PnzmD17Nrp27QpjY2MAlQ2WkiBXUlKCx48fIz09nVuKFgAKCgq4PACQmZmJ9PR0biprBQUF+Pv7Y82aNTh48CBu3LjBzVI6YcIEucvr5OSEsLAwWFpa8maCcXBwwObNm2Fubo6WLVty6cuXL8eCBQuQkJCAzMxMpKWlYfLkySgtLcWAAQPe+b4RQgj5MI4cOYK8vDx4e3ujffv2vM/o0aMhFArh7++Pnj17ol+/fti6dSt+//13PHjwAHv37kW3bt24itOHiJ1Tp06FQCCQWm4hKCgIRkZGGDBgAI4fP45Hjx4hKSkJzs7OKC0txdatWwFULrn79nVpaGhAV1cX7du3BwDs2rULurq6GDNmDC9fhw4dMHToUAiFQu68kyZNwpMnT/Ddd9/B1dVV5ki+4uJiqb8v/vnnn3e6fkIIIR9Wbc9sBwcHWFpawtPTE5aWlujTp89HK2t4eDj++ecf2NjY1HnfqKgoeHp6IiQkBN27d+euteqMLnPmzMHJkyexbt063LlzB+vWrUNcXBz8/f25PLXVQ8vKyjB69GhcuXIFERERKC8v585V19H2hBBCava51+UAwNfXF7t370ZkZCS0tLS4mPL69WsA8rV/CgQCeHt7Y968eTh9+jTS0tLg7u4OW1tbbnZsoVCIIUOGwM7OjncfR40aBX19fezevZsrk7e3Nw4cOICDBw9WO0Dk1atXUn9fVO0QSwgh5MNpyPGxb9++OHr0KHbs2CFXZ1B54pOCggLEYjHu3buHPn364NixY3jw4AGuXbuGoKAgjBgx4p3u49sGDhyINm3awNXVFefPn0dmZiZ+/fVXBAQEYPr06dDS0qqX8xBCCGk4nJyccO7cOd6EYUBle+nPP//MTRhmZWUFNzc3eHp64sCBA8jMzERKSgrWrVuHY8eOAaicOKygoACnT5/GP//8g6Kiojq9m3ubPOe0tLTEqVOncOHCBdy+fRvTpk2TGtBQk9rqoxJTpkzBmTNncPz48XcewE8IIR8Ua+C8vLzYiBEjZG7LzMxkAFhaWhovvaKigllbW7MZM2YwxhgTi8UMgMxPdnY2t9+TJ0+Yr68vMzU1ZSoqKqx58+Zs+PDhLD4+nstjamrKNm7cWO13WTZt2sTatm3L1NTUWLNmzZibmxv766+/pK7j7Y+DgwOXJz4+XmYeLy8v3nUvW7aMGRkZMVVVVdanTx92/fr1Gsv2Nsm9mj59Oi99165dDADz9vbmpZ85c4aNGjWKmZiYMBUVFWZoaMhcXFzY2bNn5T5nfn4+A8Dy8/PrVFZCyH8HPSfqz9ChQ9ngwYNlbktNTWUAWGpqKnvz5g0LDg5mtra2rHHjxkxHR4f17NmThYeHs9LSUm4feWJnTWTF0cjISKk4yBhjz549Y35+fszExIQpKSkxQ0ND5uXlxf78888az+Hg4MDmzJnDfbe1tWUzZ86UmTcmJoYpKSmxnJwcLm3gwIEMALtw4YJUfi8vL5nx2drauuYLfwv9xgkhtaHnxPuT95m9Zs0aBoCtWbNG6hhisZgJBAK5zicUCpmurq7c+9a2fePGjczU1FSuczs4ONRaf2SMsX379jFra2umrKzMbGxsWExMDG97bfXQ6uqyAOT+W4Ax+n0TQmpHz4n/Rl2uupgiFou5PPK0f75+/ZrNmjWL6ejoMDU1NTZ06FD28OFDxhhjOTk5TElJie3du1fmdfn5+TFbW1vue1FRERMIBEwgELCioiKZ90FWmadNm1bbLeTQ75sQUht6TlTvU4iPiYmJTFNTk02bNo1VVFRItVUyVvf4dPfuXebp6cmMjY2ZiooKMzU1ZePHj2dXr16V2lfW+eSRnZ3NJk2axExNTZmamhqzsbFhK1euZG/evOHyVPeetq7oN04IqQ09Jz48yTPdxsaGl/7o0SMGgFlYWHBpJSUlbOnSpczMzIwpKyszIyMj9tVXX7Fr165xeaZPn850dXUZALZs2TK5381V10Za2zlzc3PZiBEjmKamJjMwMGCBgYHM09Oz2r5Gb5OnPirRu3dv1rZtW6n0mvo21YR+34SQ2tTlOaHAWD2uT07IO3j58iUEAgHy8/Np2mtCiEz0nCCfO/qNE0JqQ8+JT8/atWuxe/du3Lhx42MXpcGj3zchpDb0nCCfM/p9E0JqQ88J8rmj3zghpDb0nCANBWMMNjY2mDZtGubOnVsvx6TfNyGkNnV5Tij9S2UihBBCCCGEEEI+e0VFRbhz5w7EYjEGDRr0sYtDCCGEEEIIIYQQQggh5D09ffoUu3btwuPHjzFp0qSPXRxCCJHpk+wIeuHCBfTu3RsDBgxAbGwsb1tJSQlCQ0MRERGBjIwMqKurw9raGlOmTIG7uzuUlZUBADk5OQgKCsLRo0fx+PFjGBgYoGPHjvD390e/fv1qLYOZmRn+/PNPJCcno3v37ly6v78/0tPTkZCQwKU9f/4cK1euxKFDh/DkyRPo6urCxcUFK1asQMuWLbl8wcHBOHDgAO7cuQM1NTXY29tj3bp1sLa25vIwxrBixQr89NNPyMvLQ7du3bB161a0a9eOy1NcXIyAgABERUXh9evX6NevHwYMGIBFixZJXUdxcTHKysoQFRUFV1dXAEBISAhWrlyJ7OxsqKur8/K/efMGRkZGWLp0KebOncvdh7cFBwdj4cKFtd7HqkZvuw/lxppy5z86x6pOxyeEEPLvmDhxInbs2MF9V1BQQKNGjaCkpAQlpco/PUxNTaGvr4/ExETevuPGjcOePXu473l5eZg9ezYOHz4MABg+fDg2b96MJk2afPgL+QjqGgtJJfqbgBBS1b9VX2zXrp3MuhAAFBYWAgDu3buH7du3w9TUFN7e3ggICICCggIv744dO7B161bcvHkTjRo1QqdOnbBgwQIMHTqUl48xhp9//hlCoRApKSlgjHHxVVLukpISNGvWjFeus2fPYtiwYfDw8MCmTZuwY8cOrqGyUaNG0NbWhpWVFYYMGYI5c+ZAIBBw+74d0yWcnZ25e1u1TqimpgZzc3P4+flh2rRpNf03yfSpx0GKR4SQz0VERATvOV5RUYHXr19DUVER1tbWuHnzJrft326LBSrjl6GhIQYNGoQNGzagadOmAICEhAQ4OTkBqKyHamlpwdzcHAMGDMA333yDZs2aSR03MjISHh4e8PHxwY8//ggASE1NxZdffomzZ8+iV69eUvs4OztDVVUVhw8flitWyutTjoMUAwkh/wVvx8eqTE1NefHxfTx69AjLly/H8ePH8c8//6BZs2YYOXIkli5dCl1dXQCAo6OjVLsqAEybNo2LZzWpqT67fft2uLm5vd9FvKNPORbWBcVNQkhDJm/dbc2aNViyZAmCgoK4fiHV9R2RcHBw4PWjkSUtLQ1LlizB5cuX8fLlSxgZGXF9YvT09JCVlYVWrVohLS0NHTt2lPoOVN+mWZWGhgYAoKysDCUlJZg6dWqtdUJDQ0Po6enB3NwcXl5e/0qdkGIGIaSuPsmOoCKRCH5+fvjll1/w8OFDrjNlSUkJnJ2d8fvvv2PVqlXo2bMntLW1cfHiRWzYsAGdOnXigkHPnj3RpEkTrF+/Hh06dEBpaSlOnDgBX19f3LlzR65yNG7cGN9++63MypbE8+fP0b17d6ioqCAsLAzt27dHVlYWAgMD0aVLFyQnJ8Pc3BwAkJiYCF9fX3Tp0gVlZWVYvHgxBg4ciFu3bnGBaP369fj+++8RHh4OKysrrF69GgMGDMDdu3ehpaUFoLIz6m+//YY9e/ZAV1cX8+bNw08//YTU1FQoKipyZXv9+jXs7e3h7u4OoVDIdQT19PTEokWLEBMTAw8PD971xMTEoKioiJe+cuVK+Pj48PJJykIIIeS/ycXFBZs3b0ZOTg5yc3ORlJSEH3/8EZ07d8b27duhpqYGLy8v+Pj4YOXKldx+ampqvONMmDABf/31F1dZmjp1Kjw8PPDbb7/9q9dDCCHk0/Fv1RePHTuG0tJSmWXo27cvfHx84OPjgzdv3iAuLg4zZsyAtrY278VhQEAAtmzZgtWrV2PkyJEoLS3F7t27MWLECPzwww+YNWsWl9fDwwMHDhxAYGAgFi9eDG1tbW7m0YkTJ2LAgAHYtGkT4uPjuX2OHj2KMWPGYP78+VixYgWXrq2tjbt374IxhhcvXuDChQsIDg6GWCzG+fPnYWxszOV1cXGBWCzmXZ+qqirvu6ROWFBQgPDwcEyfPh1NmjTBuHHj6vrfRwghpAEYPnw4unXrxn3/7rvvoK6ujr179+Lnn3/m0v/ttlhJvCkvL8e9e/cwdepUzJ49G7t27eLlu3v3LrS1tfHy5UtcvXoV69evh1AoREJCAmxtbXl5RSIRFixYgG3btuH777+Huro6OnfuDDs7O4jFYqmOoI8ePUJcXBwOHDjApckTKwkhhHz63o6PVUkGPryvBw8eoEePHrCyskJUVBRatWqFmzdvYv78+Th+/DguXrwIHR0dAJBqVwUgNblLdWqqzxoaGr7fRRBCCPlk1aXuJhaLsWDBAohEIq4jaEpKCsrLywFUDtYfNWoUVz8DABUVlRrP//TpU/Tv3x/Dhg3DiRMn0KRJE2RmZuLw4cMoKiqS+zp++OEHrF27lvverFkzrF27Fn369OHS9PX1AVT2jenduze2b99ea52QMYZHjx7BzMwMq1at4tKpTkgIaUg+uY6ghYWF2Lt3L1JSUpCTk4Pw8HAsXboUABAaGoqkpCRcuXIFnTp14vYxNzfHmDFjUFJSAgCYOXMmFBQUcPnyZa6DJVA5Am7y5Mlyl2XatGnYtm0bjh07hsGDB8vMs3jxYjx58gT379+HkZERAKBly5Y4ceIEWrduDV9fXxw/fhwApEYEiMViGBgYIDU1FX369AFjDKGhoVi8eDG+/vprAJWzxxgaGiIyMhLTpk1Dfn4+hEIhdu3ahf79+wMAdu/eDRMTE2RlZcHZ2Zk7/o4dO9C+fXusXbsWzZo1Q1ZWFszMzKCvr49hw4ZBJBJJdQQViUQYPnw4FxiByk6fkmsjhBBCgMoKjqWlJSwtLQEAI0aMwJAhQ9CvXz+cO3cOU6ZMAVDZOFldDLl9+zZiY2Nx8eJFrpH1559/Ro8ePXD37l3ejNmySGaDiY2NxcKFC3Hnzh306NEDe/bsQWpqKubOnYvHjx9jyJAhEAqFXEOpo6MjbG1toaioiB07dkBFRQWrVq2Cm5sbZs2ahf3798PAwABbtmyhJX8JIaSB+Tfri6amptWWo1GjRrx60pQpU7Bt2zacPHmS6wh68eJFhISEYNOmTfDz8+P2DQoKwps3bzB37lyMGDECJiYm2Lt3LyIiInDo0CGMGDGCy+vo6Ihp06bh5cuXEAgE0NHR4Qb/RUZGYtKkSfjf//6H2bNn88qnoKDAla1Zs2Zo06YNhg0bhnbt2mHBggXYvXs3l1dVVbXW+l7Va129ejX27t2LQ4cOUUdQQgj5RGlpaXGDvAsLCxEbG4uUlBRucIO9vT2Af78ttmq8ad68OTw9PXkrSkgYGBigSZMmMDIygpWVFUaMGIFOnTphxowZOHfuHJcvKysLFy5cQExMDOLj47F//354enoCALy9vfHdd99h06ZNvDKHh4dDX18fQ4YM4dLkiZWEEEI+fVXj44fi6+sLFRUVnDx5khsw37JlS3Tq1AkWFhZYvHgxtm3bBqDmdtXaKCoq4ttvv8XJkydRXFyMNm3aYOvWrejWrRuWL1+OQ4cOYfbs2Vi+fDmeP38ODw8PbNmyBSEhIfj+++9RUVGBOXPmYPHixdwxly9fDpFIhL///hu6uroYPXo0Nm3a9P43hRBCyL9G3rpbYmIiXr9+jZUrV2Lnzp1ISkpCnz59eH1IJAMXJPUzeVy4cAEvX77EL7/8wq0w2KpVK/Tt27dO1yEQCHirHgGAtbU1evTowUvLyspCeno6jh8/jsTERKoTEkI+C40+dgHqKjo6GtbW1rC2toa7uzvEYjEYYwAql2Xo378/r+FRQllZGRoaGnj+/DliY2Ph6+vLe2BL1GWpWTMzM0yfPh2LFi1CRUWF1PaKigrs2bMHbm5uUg9+NTU1zJw5EydOnMDz589lHj8/Px/A/wXJzMxM5OTkYODAgVweVVVVODg44MKFCwAqp6kuLS3l5TE2Nkb79u25PBJCoRDu7u4QCAQYPHgwb5SCt7c3EhMTkZmZyaVlZWUhPj4e3t7ect2f6hQXF+Ply5e8DyGEkM9f3759YWdnx5s5JSIiAnp6emjXrh0CAgLw6tUrbltycjIEAgFvpH337t0hEAikYlpNli9fji1btuDChQt49OgRxo4di9DQUERGRuLo0aM4deoUNm/ezNtnx44d0NPTw+XLl+Hn54cZM2ZgzJgxsLe3x9WrV+Hs7AwPD486jUCsimIhIYR8GA2pvijBGENCQgJu377NmyUmKioKmpqaMpcWnDdvHkpLSxETE8OV3dramtcJVEJBQUGqYXPr1q2YNGkShEKhVCfQ6hgYGMDNzQ2HDx/mRu6/q8aNG1c7uwxAcZAQQj4lDTG2AsDjx49x5MiRamdmq0pNTQ3Tp0/H+fPn8fTpUy5dJBJhyJAhEAgE3IpJEm5ubigtLcW+ffu4NMYYwsPD4eXlxb2UfBcUBwkhhMjy/PlznDhxAjNnzpRaNcnIyAhubm6Ijo7m4vC7KigogIODA548eYLDhw/j999/x4IFC3jvOf/44w8cP34csbGxiIqK4mLmX3/9hcTERKxbtw6BgYG4ePEiAGD//v3YuHEjtm/fjoyMDBw6dEhqFu6qKBYSQkjDU5e6m1AoxPjx46GsrIzx48fz6lLvw8jICGVlZTh48OB7xzt5UJ2QEPI5+uQ6gko6LwKVUywXFBTg9OnTAICMjAzY2NjUuP/9+/fBGKs1n7wCAwORmZmJiIgIqW3Pnj3Dixcv0KZNG5n7tmnTBowx3L9/X2obYwxz585Fr1690L59ewBATk4OAOllGQwNDbltOTk5UFFRQdOmTavNA1Teq4sXL3IztEgaciUVPWdnZxgbGyM8PJzbRywWw9jYmNfJFAC+/fZbaGpq8j4JCQkyrxkAgoODuVEYAoEAJiYm1eYlhBDyebGxsUFWVhaAykpUVFQUEhISsGTJEsTExHAzXgOVMc3AwEDqGAYGBryYVpvVq1ejZ8+e6NSpEzfQYdu2bejUqRN69+6N0aNH85bRBQA7OzsEBgaidevWWLRoEdTU1KCnpwcfHx+0bt0aS5cuRW5uLq5du/ZO94FiISGEfBgNqb4oqSepqqrCyckJjDFep8x79+7BwsJC5pJIxsbGEAgEuHfvHlf22mbClrh9+zZmzZqFbdu2cfdCXjY2Nnj16hVyc3O5tCNHjkjV96oufVRVWVkZwsPDcf36dfTr16/a81AcJISQT0dDjK1qampo0aIFFBQU8P3338u1r+T8kvpoRUUFwsPDuWtzdXVFcnIy106ro6ODkSNH8gbOJyQk4MGDB1KzmNYlVgIUBwkhhMiWkZEBxliN7xTz8vLw7NkzAEBYWJhU/NmxY0et54mMjMSzZ89w6NAh9OrVC5aWlhg7dixvlrSKigqIRCK0bdsWw4YNg5OTE+7evYvQ0FBYW1tj0qRJsLa25t4FPnz4EEZGRujfvz9atmyJrl27wsfHp9oyUCwkhJCGR96628uXLxETE8PVpdzd3bF///566czYvXt3fPfdd5gwYQL09PQwaNAg/O9//8Pff//93sd+G9UJCSGfq0+qI+jdu3dx+fJluLq6AgCUlJQwbtw4iEQiAJWdJxUUFGo8hmTkQG355KWvr4+AgAAsXbqUW+5IXjWVZdasWbh27RqioqKktr2dX97rrppHKBTC2dkZenp6AIDBgwejsLAQcXFxACqXhfDy8kJ4eDgqKirAGMOOHTswceJEbqlBifnz5yM9PZ33qWk0/qJFi5Cfn899Hj16VGPZCSGEfD6qxiMfHx/0798f7du3h6urK/bv34+4uDhcvXqVyy8rvskT96rq0KED929DQ0Ooq6vD3Nycl1Z1Vpi391FUVISuri5vFLtkUMbb+8mLYiEhhNS/hlZflNSTEhMT4eTkhMWLF3NL6cqjannrEvtatGiBL774AuvXr0d2dnadyizr+p2cnKTqe76+vrz9qnbM8fX1xfz582XOdCpBcZAQQj4NDTW2Xrt2jeuMOmTIELlmsn67HCdPnkRhYSEGDRoEANDT08PAgQO5awMqV0xKSkriXgSKRCL07NlTanCGPLGyKoqDhBBC3oUklkkGE7q5uUnFn6+++qrW46Snp6NTp07caoSymJmZQUtLi/tuaGiItm3bolGjRrw0SdvomDFj8Pr1a5ibm8PHxwcHDx5EWVlZtcenWEgIIQ2PvHW3yMhImJubw87ODgDQsWNHmJubY8+ePfVSjqCgIOTk5ODHH39E27Zt8eOPP8LGxgbXr1+vl+NLUJ2QEPK5evf5ij8CoVCIsrIyNG/enEtjjEFZWRl5eXmwsrLC7du3azxG69atoaCggNu3b2PkyJH1Uq65c+ciLCwMYWFhvHR9fX00adIEt27dkrnfnTt3oKCgAAsLC166n58fDh8+jKSkJLRo0YJLlywvn5OTg2bNmnHpT58+5TqkGBkZoaSkBHl5ebxZQZ8+fcq9dCwvL8fOnTuRk5PDm7K6vLwcQqGQm/Fz8uTJCA4OxpkzZwBUjuibNGmS1HXo6enB0tKylrv0f1RVVaGqqip3fkIIIZ+P27dvo1WrVjK3ffHFF1BWVkZGRga++OILGBkZyRzl9+zZM6nZsWtSdRleBQUF3ndJWtWlj97eR9Z+korw2/vJi2IhIYTUv4ZWX5TUkywtLRETEwNLS0t0794d/fv3BwBYWVnh3LlzKCkpkZoV9MmTJ3j58iVat27N5a2t7BJaWlqIi4vDwIED4ejoiPj4eBgbG8u17+3bt6GtrQ1dXV0uTUNDo9b63vz58zFx4kSoq6ujWbNmtTYYUxwkhJBPQ0ONrZLjhoaGokePHoiPj+fia3Uk5TQzMwNQ+QLv+fPnUFdX5/JUVFQgLS0Nq1atgqKiIvr37w9TU1OEh4djwYIFOHDgALZs2SJ1bHliZVUUBwkhhMhiaWkJBQUF3Lp1S2bMvHPnDvfeEQAEAkGd4o/E28vOy1Jb26gkTdI2amJigrt37+LUqVOIi4vDzJkz8b///Q+JiYlS+wEUCwkhpCGSt+4mEolw8+ZNXj+TiooKCIVCTJ06tV7KoqurizFjxmDMmDEIDg5Gp06dsGHDBrlmvpYX1QkJIZ+rT2ZG0LKyMuzcuRMhISG8nvS///47TE1NERERgQkTJiAuLg5paWky9y8sLISOjg6cnZ2xdetWFBYWSuV78eJFncumqamJJUuWICgoiDfldaNGjTB27FhERkZKLWH7+vVrhIWFwdnZmRt1xxjDrFmzcODAAZw5c0aqo0yrVq1gZGSEU6dOcWklJSVITEzkOnl27twZysrKvDzZ2dm4ceMGl+fYsWN49eoV0tLSePdy3759OHToELcMoIWFBRwcHCAWiyESieDo6CjVaZUQQgiR15kzZ3D9+nWMGjVK5vabN2+itLSUG+zQo0cP5Ofn4/Lly1yeS5cuIT8/v04zqhFCCPn8NeT6IgA0bdoUfn5+CAgI4EbXu7q6oqCgANu3b5fKv2HDBigrK3Mxc8KECbh37x5+/fVXqbyMMeTn50udLy4uDk2bNoWjoyMeP35caxmfPn2KyMhIjBw5kjfLizwkHXOMjY3rbfUNQgghH1dDj60AuFWLXr9+XWO+169f46effkKfPn2gr6+P3Nxc/Prrr9izZ4/UrC0FBQU4fvw4gMoOLpMmTcKOHTsQGRnJtfUSQgghH4Kuri4GDBiAsLAwqdiWk5ODiIgITJw48b3P06FDB6Snp+P58+fvfayq1NTUMHz4cGzatAkJCQlITk6u99nbCCGEfDjy1N2uX7+OK1euICEhgVePSkpKQkpKCm7cuFHv5VJRUYGFhYXMMr0rqhMSQj5nn0xH0CNHjiAvLw/e3t5o37497zN69GgIhUL4+/ujZ8+e6NevH7Zu3Yrff/8dDx48wN69e9GtWzdkZGQAAMLCwlBeXo6uXbsiJiYGGRkZuH37NjZt2oQePXq8U/mmTp0KgUAgtZR7UFAQjIyMMGDAABw/fhyPHj1CUlISnJ2dUVpaiq1bt3J5fX19sXv3bkRGRkJLSws5OTnIycnhKnwKCgrw9/fHmjVrcPDgQdy4cYObdWXChAkAKkcAent7Y968eTh9+jTS0tLg7u4OW1tbbmS8UCjEkCFDYGdnx7uPo0aNgr6+Pnbv3s2VydvbGwcOHMDBgwfh7e0t89pfvXrFlVXyqdohlhBCyH9PcXExcnJy8PjxY1y9ehVr1qzBiBEjMHToUHh6euKPP/7AypUrceXKFWRlZeHYsWMYM2YMOnXqhJ49ewIA2rRpAxcXF/j4+ODixYu4ePEifHx8MHToUKllFwghhPy3NfT6IlBZ37t79y5iYmIAVA54mDNnDubPn4+QkBD88ccfuHPnDgIDA/HDDz8gJCQEJiYmAICxY8di3LhxGD9+PIKDg3HlyhX8+eefOHLkCPr374/4+Hip8wkEApw8eRJ6enpwdHTEX3/9xW1jjCEnJwfZ2dm4ffs2RCIR7O3tIRAIsHbtWt5xJDG96ueff/555/tACCHk09AQY6ukDTI7OxuXL1/G/PnzoaenJzVQ8OnTp8jJyUFGRgb27NmDnj174p9//sG2bdsAALt27eJmmKl6XR06dMDQoUMhFAq5Y02aNAlPnjzBd999B1dXV2hoaEiVi2IlIYSQ+rJlyxYUFxfD2dkZSUlJePToEWJjYzFgwABYWVlh6dKlXN6ioiKp+JOXl1frOcaPHw8jIyOMHDkS58+fx4MHDxATE4Pk5OR3Lnd4eDiEQiFu3LiBBw8eYNeuXVBTU4Opqek7H5MQQsi/r7a6m1AoRNeuXdGnTx9eXapXr17c9vdx5MgRuLu748iRI7h37x7u3r2LDRs24NixYxgxYkSN+969e1eqU2dJSYnMvFQnJIR81tgnYujQoWzw4MEyt6WmpjIALDU1lb1584YFBwczW1tb1rhxY6ajo8N69uzJwsPDWWlpKbfPkydPmK+vLzM1NWUqKiqsefPmbPjw4Sw+Pl6u8piamrKNGzfy0iIjIxkA5uDgwEt/9uwZ8/PzYyYmJkxJSYkZGhoyLy8v9ueff/LyAZD5EYvFXJ6Kigq2bNkyZmRkxFRVVVmfPn3Y9evXecd5/fo1mzVrFtPR0WFqamps6NCh7OHDh4wxxnJycpiSkhLbu3evzOvy8/Njtra23PeioiImEAiYQCBgRUVFMu+DrDJPmzattlvIyc/PZwBYfn6+3PsQQv5b6DnxafHy8uLigZKSEtPX12f9+/dnIpGIlZeXM8YYe/jwIevTpw/T0dFhKioqzMLCgs2ePZvl5ubyjpWbm8vc3NyYlpYW09LSYm5ubiwvL0+ucsTHxzMAvPxisZgJBAJevmXLljE7Ozvuu4ODA5szZw4vj6y4D4AdPHhQrrLUhn7jhJDa0HOiZp9CfZExxnx8fFi7du24eMgYY0KhkH355ZdMTU2Nqaurs169erHDhw9L7VteXs62bdvGunTpwtTV1Zm2tjbr3Lkz++GHH7i62tsxjTHGXr58yXr27MksLCzYw4cPmVgs5uK0goICEwgErGvXrmzlypVSv6+qMb3qx9rautZrrQv6fRNCakPPiX9fQ4ytVWORvr4+Gzx4MEtLS+PySOqAkhinpaXF7Ozs2Pz581l2djaXz9bWls2cOVPmeWJiYpiSkhLLycnh0gYOHMgAsAsXLkjllydW1oZ+34SQ2tBz4r8lMzOTeXl5MUNDQ6agoMAAsK+//poVFhZyeRwcHGTGH2dnZ7nOkZWVxUaNGsW0tbWZuro6+/LLL9mlS5cYY7LrlV5eXmzEiBG8tKptqAcPHmTdunVj2traTENDg3Xv3p3FxcXJfc30GyeE1IaeE/+e6upuJ06cYLq6umz9+vUy9wsJCWF6enqsuLiYMSb7HV1t/vjjD+bj48OsrKyYmpoaa9KkCevSpQuvv0xmZiYDwNUFJd9lfTIzMxlj0u/zqE5ICPnU1OU5ocDY/1+XjpCP5OXLlxAIBMjPz4e2tvbHLg4hpAGi5wT53NFvnBBSG3pOkM8Z/b4JIbWh5wT5nNHvmxBSG3pO/LctW7YM33//PU6ePPleq1Q0ZPQbJ4TUhp4T5HNGv29CSG3q8pxQ+pfK9J81ceJE7NixAwCgpKQEExMTfP3111ixYgWePXuGVq1aydwvOTkZ3bt3R3h4OCZNmsSlGxgYoGvXrli7di3atWsndZ5p06bhxx9/5B1r5syZ2LZtG7y8vBAeHs6l5+TkICgoCEePHsXjx49hYGCAjh07wt/fH/369eMdY82aNViyZAmCgoKwcOFCAICZmRn+/PPPaq/dwcEBCQkJct0nABi97T6UG2vy0o7OsZJ7f0II+a+rGnOqcnJywrVr1+Dv74/AwECp7cHBwQgJCcGTJ08QGRkJf39/vHjxQq5zvn79GmvXrsWePXuQlZUFLS0tODo6YsWKFbw4tXz5cqxYsUIqTqWnp6NTp07IzMyEmZkZsrKyeLFRU1MTLVu2hKOjI/z9/dG6dWu5ynXgwAFs27YN6enpKC4uRrt27bB8+XI4Ozvz8sXExGDJkiX4448/YGFhgaCgIHz11Vfc9qSkJPzvf/9DamoqsrOzcfDgQYwcOVLqXNu3b0dqaipyc3ORlpaGjh07ylXOt8mKhUQ2+huBkP+GutSntLW10aZNGyxevBjDhg3j0t+uU0moqqrizZs33Hd56kdmZmbw9/eHv78/911SJ1JTU4O5uTn8/Pwwbdo07rgRERFYv349MjIyIBAI4OLigg0bNkBXVxcAcPPmTSxduhSpqan4888/sXHjRu74EvLEI8YYVqz4f+zde1hN2f8H8He63wmVSOkuEmMkmSlRSiq+IxUlUYyZUCaXcb9WxkwzuWUMp2KUQm5TNEQ3FSWVW8hMYagx4xIVXffvj56zf+3OqU5h3D6v59nPTGuvvdY623n256y1915rLX755Rc8efIEw4cPx/bt2znxuDXu7u6oqKjAyZMn2bSTJ0/CwcEBK1aswPr169n09evXY8eOHXjw4AGApli6adMm3LhxA42Njejbty/s7e0RGhrabr0tvW9xkGIRIeRjlJWVhc8//xy2trZISkri7KutrUVYWBiio6NRXFwMOTk5GBoawtfXF56enpCUlATQsTFJYZrHXxkZGWhpacHHxwcLFy6EmJgYAAj0Lfk8PDywb98+AE39WQ0NDYiJieH+/fuQlZUVyB8fH4+tW7ciPz8fDQ0N0NHRgYuLC+bOnYsvvvgCaWlprbZTS0sLpaWl7X4evnc5DlLMI4S8r37++WcsWrQIT548gYRE0y3RyspKdOvWDebm5sjIyGDzZmRkwNLSEjdv3oSBQevXvaioqDbHT2NiYjBt2jTMmjVL4H5dZ6xduxba2tq4cOEChg8fji5dunS4DP7YbHNqamooLy9n/36VPuXr8i7HwteJ4ioh5EPWcjxXRUUFgwYNwpQpU+Dt7c3GsVGjRgn0p9zc3BAbG8v+/eTJE8yfPx/Hjx8HADg7O2Pr1q3o2rXrf/Nh/mMt4yDFC0JIZ3S8t/ARiI6OhoKCgtCtMx0ee3t7lJWV4c8//8SGDRsQHh6OhQsXsvuTk5NRVlbG2YYOHcruV1JSQllZGR48eIDExERUVVVh/PjxqK2t5dSjqamJ2NhYvHjxgk17+fIl9u/fj759+3LylpaWYujQoTh79iw2bdqEK1euICkpCdbW1vDz8xP4DJGRkVi8eDEiIiLYtNzcXLa98fHxAICbN2+yaYcPH+7wuSKEEPJq+DGn+RYfHw9PT09ERUVB2ETgkZGRmDZtGqSkpDpUV01NDWxsbBAREYH169fj1q1bOHHiBBoaGjB8+HCcP3+ek19GRgY8Hg+3bt1qt2x+bCwsLERwcDCKiopgamqKM2fOsHnmzJnTarxevXo1bG1tceLECeTl5cHa2hpOTk7Iz89nj8/OzoabmxumTZuGwsJCTJs2Da6urrhw4QKbp6qqCqampti2bVurbd22bRtSU1NRWVkJALCwsGDbMWfOHJHPJyGEEOFE7U9duHABZmZmmDRpEq5evcopg9+nar41f6mtI/2jvLw89jp/9+5dSElJQU5ODmJiYvj7778xZ84cxMXFAQDOnTsHLy8v+Pj44Nq1azh48CByc3Ph6+vLllddXQ0dHR1s3LgR6urqQs+BKPFo06ZN+PHHH7Ft2zbk5uZCXV0dtra2eP78ebvn2NraGufOnUN9fT2blpqaCk1NTaSkpHDypqamwtraGkDTuXd3d4eLiwtycnKQl5eHoKAggb4qIYSQD0dERATmzZuHc+fO4e7du2x6bW0t7OzssHHjRsyePRtZWVnIycmBn58ftm7dimvXrgEQHnPnzp2LU6dOwdbWVuSx2HXr1qGsrAxFRUVYuHAhli1bhl9++UUgX8tx1+3bt7P74uPjMXDgQBgbGwsdx1y+fDnc3NwwbNgwnDx5ElevXkVoaCgKCwvx66+/4vDhw2y5OTk5AvXl5ua+0rkmhBDy6qytrVFZWYmLFy+yaRkZGVBXV0dubi6qq6vZ9NTUVGhoaLT5EKgoIiIisHjxYsTGxnLKF6ahoQGNjY3tljljxgwEBASI9BBocHCwQDwNDg5Gly5dYG1tzcapK1eucI57lT5la6hvSAghHyf+eG5paSlOnjwJa2tr+Pv7Y8iQIWxsysjIgISEBOTk5CAnJwcDAwPs3LmTU87UqVNRUFCApKQkJCUloaCgANOmTXtLn4oQQt4PNCOoEM7Ozhg+fLjQffw31ztCWlqavaE3depUpKSk4OjRo1iyZAkAoHv37q3e8AMAMTExdn+vXr2wYMECODs74+bNmzAxMWHzffLJJ/jzzz9x+PBheHh4AGiapUxTUxM6OjqcMr/++muIiYkhJycH8vLybPqAAQMwc+ZMTt60tDS8ePEC69atw969e5Geng5LS0v07NmTzaOiogKgacbSD/UNDEIIeR80jznN+fj4YPPmzUhPT4eVlRWbnpGRgeLiYvj4+HS4rrCwMGRnZyM/Px+mpqYAmmY8iY+Px/Dhw+Hj44OrV6+yM7IYGhpCVVUVK1aswIEDB9osu3ls1NHRgZOTE8aMGQMfHx/88ccfEBcXx7p16zgPAjWnpKQEVVVV9u/g4GAcO3YMv/32G4YMGcK239bWFkuXLgUALF26FGlpaQgLC8P+/fsBAOPGjcO4cePabGtsbCyePXuGv/76C9bW1oiNjYWxsTHbDkIIIa9G1P6Uuro6goKCsHXrVqSkpGDgwIFsGc37VMJ0pH80YMAArF69GkDTKgje3t7sjKOSkpKwtbXF0aNH4ebmhvPnz0NbWxvz588HAPTr1w9ffvklNm3axJY3bNgwDBs2DADY1Rdaai8eMQyDsLAwLF++HF988QUAYM+ePVBTU0NMTAxnhlJhmt8cNTc3B9B0E/Tbb7/FggULUF1dDTk5OdTW1iI7OxtbtmwBACQkJOCzzz7DokWL2LIMDAwEZislhBDyYaiqqsKBAweQm5uL8vJyREVFYdWqVQCa+lfp6em4ePEi2+cCmvpzkydPZh8EERZzv/76a0yaNAnPnj0T6EO1NharqKjIxnZfX1/s2LEDp06dEoh5bY278ng8eHp6gmEY8Hg8djwVAHJychAcHIywsDD4+/uz6dra2rC1tcXTp085Y6D8WcbbG+clhBDy3zI0NISGhgZSU1M5fZ0JEyYgJSUFWVlZsLGxYdOtra1RW1uLFStWIDo6Gk+fPsXAgQPx3XffYdSoUUhNTWX7f/wxz9WrV2PNmjUAml54yMrKQnx8PFJSUnDo0CF4eXmx7eHPJrpv3z4sXrwYt27dQnFxMXr37t1qnQDw6NEjzJ07FxkZGXj8+DF0dXWxbNkyTJkyReAzz5kzB66urpy0LVu24PTp0/j111+FxilR+pQzZ87Ew4cPkZCQwB5XX1+PPn36IDg4GDNnzsSoUaMwcOBASElJYe/evRgwYECbs2cTQgj5MDUfz+3duzc++eQTmJubY8yYMQgKCoKrqys8PDzQv39/diVDSUlJKCsrs2UUFRUhKSkJ58+fZ5/d2bVrF0aMGIGbN2/C0NCwzTbw43pSUhK+/fZb3LhxAyNGjEBsbCzy8vLwzTff4P79+xg/fjx4PB7k5OQANM1UamJiAnFxcezZswdSUlJYv349PDw8MHfuXBw6dAiqqqrYtm1bu/cPCSHkbaAZQYVQVFSEnp6e0E1LS+uVy5eVlUVdXV2njn369CliYmIACB8InTFjBiIjI9m/IyIiBG5cPn78GElJSfDz8+Pc5ORr+SAnj8fDlClTICkpiSlTpoDH43Wq7YQQQt4eExMTDBs2jBMjgKY4YWZmxnlYRlQxMTGwtbVlHwLl69KlCxYsWIDr16+jsLCQs2/jxo2Ij4/v8MwoXbp0gb+/P+7cuYO8vDwATS8ftBavmz8ECgCNjY14/vw5++IC0DQj6NixYzn57OzskJWV1aG28duhra0NAOjbt2+r7SCEEPLqWutP1dXVYdeuXQA69gJfR/tHMjIy7HVeUlISPXv25PQXZWRk2PZZWFjgr7/+wokTJ8AwDP7++28cOnQI48eP78Anbl9JSQnKy8s5cU1aWhpWVlYixTUDAwNoaGiws38+f/4cly5dwuTJk6Grq4vMzEwAwPnz5/HixQt2RlB1dXVcu3ZNYAZWQgghH6a4uDgYGhrC0NAQnp6eiIyMZFediI6Oho2NDechUD5JSUnIy8u3GnP5Y7GffPJJh8diGYZBamoqioqKOhT///jjD2RnZ8PV1RWurq7IysrCn3/+ye7nrxj19ddfCz2eXoQnhJD3x6hRozgrHaSkpGDUqFGwsrJi0/kvvVlbW2PGjBnIzMxEbGwsLl++jMmTJ8Pe3h7FxcWwsLBAWFgYZ9WJ5i+qR0REYPz48VBWVoanp6fQ+2nV1dUICQnB7t27ce3aNaiqqrZZJ9D0wsHQoUORkJCAq1evYvbs2Zg2bRpnZSM+FRUVgXiqoqKCu3fvYtiwYejXrx/c3d05cU+UPqWvry+SkpJQVlbG5jlx4gQqKys5D57u2bMHEhISyMzMFJjZjRBCyMdr9OjRMDU1xblz56CnpwdZWVkkJibC3NwcEyZMwNatWzmzUGdnZ0NZWZkzgZu5uTmUlZU7dB9vzZo12LZtG7KysnDv3j24uroiLCwMMTExSExMxOnTp7F161bOMXv27EGPHj2Qk5ODefPm4auvvsLkyZNhYWGBS5cuwc7ODtOmTWt35m9CCHkb6EHQ/1hOTg5iYmIwZswYNq35ErL8raGhgd1fUVEBBQUFyMvLo1u3boiNjYWzszOMjIwEyp82bRrOnTuH0tJS3LlzB5mZmfD09OTkuX37NhiGEXp8S8+ePWOXFAYAT09PHDp0CM+ePevsKUBNTQ2ePXvG2QghhLweCQkJAjFl/fr1AICZM2fi0KFD7BLmlZWVOHjwYKdmAwWAW7duoX///kL38dNbLgP/ySefwNXVtdUZz9rCj1ulpaUdPjY0NBRVVVWcQcny8nKoqalx8qmpqaG8vLzD5XcUxUJCCOmctvpTMjIyCAwMhLa2tsDsJ/w+VfONf4OrI/2jttTX1yMqKgpXrlxh22dhYYHo6Gi4ublBSkoK6urq6Nq1q8Dg4qvix65XiWv82W2AphnDDQwM0LNnT1hZWbHp/OXidXV1AQDz5s3DsGHDYGJiAm1tbbi7uyMiIgI1NTVt1kVxkBBC3k/8GTSBpqX+KisrcebMGQBAcXFxu7H0dcVcAFiyZAkUFBQgLS0Na2trMAzDzsDdXMtx1/z8fABND+qMGzcO3bp1g4qKCuzt7REREcEeV1xcDB0dnU6tDtUeioOEEPLfGjVqFDIzM1FfX4/nz58jPz8flpaWnL4O/6W3UaNGYf/+/Th48CA+//xz6OrqYuHChfjss88QGRkJKSkpKCsrs6tOqKurQ0FBAUDTi+hRUVFsrHR3d0d2djZu377NaU9dXR3Cw8NhYWEBQ0NDlJeXt1kn0DSb2sKFCzF48GDo6Ohg3rx5sLOzw8GDB0U6B8OHD8fevXvx+++/Y9euXSgvL4eFhQUePXoEQLQ+Jb+9v/76K7s/MjISkydPZs8BAOjp6WHTpk0wNDRsNeZTLCSEkI+TkZERe4/Pw8MD+/fvR2pqKlauXIn4+Hh2VmqgKTYJm2xFVVW1Q/fxNmzYgJEjR2LIkCHw8fFBWloaduzYgSFDhuDzzz+Hi4sL54URADA1NcWKFSugr6+PpUuXQlZWFj169MCsWbOgr6+PVatW4dGjR7h8+XKnzgPFQULIm0QPgv4H+A/lyMjIYMSIEbC0tOTc+IuLi0NBQQFnExcXZ/crKiqioKAAeXl5+Pnnn6Grq4uff/5ZaF09evTA+PHjsWfPHkRGRmL8+PHo0aMHJw//TX3+shVtiYmJgY6ODjvbG7+TGRsb2+HzwBcSEgJlZWV209TU7HRZhBBCuKytrQViip+fHwBgypQpaGxsRFxcHICm+MMwDNzd3V97O9qKNRs2bEBGRgZOnTr12spsy/79+7FmzRrExcUJdBpblsUwTIfL7wyKhYQQIjpR+lP5+fk4fvw49PT0sHv3bs4M0MD/96mab/wbap2NL3z8B1FkZWXh5+eHRYsWscvSXr9+HfPnz8eqVauQl5eHpKQklJSUYM6cOZ2qqz2vEtesra2RmZmJuro6pKamsksQtnwQdPTo0ewx8vLySExMxO3bt7FixQooKCggMDAQZmZmbb4RT3GQEELePzdv3kROTg7bf5SQkICbmxv78KQoMedVY25zixYtQkFBAdLS0mBtbY3ly5fDwsJCIF/LcVdjY2M0NDRgz549nJfnPT09sWfPHvbl/DfZN6Q4SAgh/y1ra2tUVVUhNzeXfelNVVUVVlZWyM3NRVVVFVJTU9G3b19cunQJDMPAwMCA8yJBWloa/vjjjzbrOXXqFKqqqthlYnv06IGxY8dyXjQAACkpKQwaNIj9W5Q6GxoaEBQUhEGDBqF79+5QUFDAqVOncPfuXZHOwbhx4zBp0iSYmJjAxsYGiYmJAJpmPGuuvT6lr68v25d++PAhEhMTBVYl/PTTT9ttD8VCQgj5ODWPK7NmzYKNjQ0GDhwId3d3HDp0CMnJybh06RKbX1ifrKN9teYxV01NDXJyctDR0eGkPXz4sNVjxMXF0b17d5iYmHCOASBwnKgoDhJC3iSJt92Aj4G1tTV27NgBSUlJaGhosG+S89920NTUhJ6eXqvHd+nShd1vZGSE8vJyuLm5IT09XWj+mTNnYu7cuQCA7du3C+zX19eHmJgYioqKMHHixDbbHhERgWvXrkFC4v+/Ko2NjeDxeJg9e3abx7Zm6dKl+Oabb9i/nz17RsGNEEJeE3l5+VZjirKyMlxcXBAZGQkfHx9ERkbCxcUFSkpKnarLwMAA169fF7rvxo0bAJpiTku6urqYNWsWvv32W6HLI7WmqKgIANCvXz+Rj4mLi4OPjw8OHjwIGxsbzj51dXWBtwYfPnwo8Ob7m0CxkBBCRCdKf0pfXx/6+vpQUFDApEmTcP36dc7D/837VC11pH8kzKJFi+Dt7Q05OTn06tWLMxAZEhKCkSNHYtGiRQCaBhHl5eXx+eefY8OGDejVq1eH6xNGXV0dQNOb8s3L7Ehca35zNCUlhW2zlZUVvLy88PjxY2RnZ2P69OkCx+rq6kJXVxe+vr5Yvnw5DAwMEBcXhxkzZgiti+IgIYS8f3g8Hurr69G7d282jWEYSEpK4smTJzAwMGD7bK151ZjbXI8ePdjlbuPj46Gnpwdzc3OBfp+wcdcTJ07g/v37cHNz46Q3NDTg1KlTGDduHAwMDHDu3DnU1dW99llBKQ4SQsh/S09PD3369EFKSgqePHkCKysrAE39qH79+iEzMxMpKSkYPXo0GhsbIS4ujry8PM6ELQA4s14KExERgcePH0NOTo5Na2xsRH5+PtavX8+WJysry+k3ilJnaGgofvrpJ4SFhcHExATy8vIICAhAbW1tp86JvLw8TExM2KXnRe1Tenl54dtvv0V2djays7Ohra2Nzz//XKDs9lAsJISQj1NRUVGr9/g++eQTSEpKori4GJ988gnU1dXx999/C+T7559/OnQfr3l/TkxMTKB/JyYmhsbGxlaPEXYcP463PE5UFAcJIW8SzQj6H+A/lKOlpfVaBg4XLFiAwsJCHDlyROh+e3t71NbWora2FnZ2dgL7VVRUYGdnh+3bt6Oqqkpg/9OnTwEAV65cwcWLF5Gamsp5cz49PR25ubm4evVqp9ovLS0NJSUlzkYIIeS/4ePjg8zMTCQkJCAzM7PTy8IDTcsbJScno7CwkJPe2NiIn376CcbGxuyM0i2tWrUKt27dEnmG6cbGRmzZsgX9+vXDkCFDRDpm//798Pb2RkxMDMaPHy+wf8SIETh9+jQn7dSpU0JnkXndKBYSQojoOtKfsrKywsCBAxEUFCRy+aL2j1rDfxBFQ0ND4G306upqdOnC7Xbzb+zxZ0V7Hfr16wd1dXVOXKutrUVaWprIcU1XVxeampo4fvw4CgoK2JujvXr1gra2NkJDQ/Hy5UtYW1u3WY62tjbk5OSEnks+ioOEEPJ+qa+vx969exEaGsoZIywsLISWlhaio6MxdepUJCcns0uvtzy+qqrqlWNua7p164Z58+Zh4cKFIsVXHo8Hd3d3gdnCPTw82JcVp06disrKSoSHhwsto7NtBSgOEkLI22BtbY3U1FTO6gdAUx/y999/x/nz52FtbY0hQ4agoaEBDx8+ZF844G/8hyWlpKTYGaT5Hj16hGPHjiE2NlYgvlRWVuLkyZOttk2UOjMyMjBhwgR4enrC1NQUOjo67EOcnVFTU4OioiL2oU9R+5Tdu3fHxIkTERkZicjIyFZf/msPxUJCCPn4nD17FleuXMGkSZOE7r927Rrq6urY2DRixAhUVFQgJyeHzXPhwgVUVFT8J/fx3iSKg4SQN4lmBH0HPHr0SGBGsq5du0JGRkZofiUlJfj6+mL16tWYOHGiwM1GcXFx9g38lm8P8oWHh8PCwgJmZmZYt24dBg0ahPr6epw+fRo7duxAUVEReDwezMzMYGlpKXD8iBEjwOPx8NNPP3XmIxNCCHlDampqBGKKhIQEevToAaBpcFNPTw9eXl7Q09MTeo0X1YIFC3Ds2DE4OTkhNDQUw4cPx99//43g4GAUFRUhOTm51eUZ1NTU8M033+D7778Xup8fG6urq3H16lWEhYUhJycHiYmJrca25vbv3w8vLy9s3rwZ5ubm7DmRlZWFsrIyAMDf3x+Wlpb47rvvMGHCBBw7dgzJyck4d+4cW05lZSVu377N/l1SUoKCggKoqKigb9++AIDHjx/j7t27ePDgAYCmJROBpjfp+YO1hBBC/juBgYGYPHkyFi9ezM5axjCMQHwEAFVVVXTp0kWk/lFnODk5YdasWdixYwfs7OxQVlaGgIAAmJmZQUNDA0DTzTX+DNu1tbW4f/8+CgoKoKCgwM5g1l48EhMTQ0BAAIKDg9nZUYODgyEnJ4epU6eK3F5ra2uEh4dDT0+P82a9lZUVtm7dCh0dHTb+AcCaNWtQXV0NBwcHaGlp4enTp9iyZQvq6upga2vbqXNGCCHk3ZOQkIAnT57Ax8eH7U/xubi4gMfj4fz580hMTMSYMWOwfv16fPbZZ1BUVMTFixfx3XffgcfjYfDgwW8s5vr5+eG7775DfHw8XFxcWs33zz//4LfffsPx48cxcOBAzr7p06dj/Pjx+OeffzB8+HAsXrwYgYGBuH//Pv73v/9BQ0MDt2/fxs8//4zPPvsM/v7+nWorIYSQ/561tTX8/PxQV1fHvvQGNPV1vvrqK/alN01NTXh4eMDLywuhoaEYMmQI/v33X5w9exYmJiZwcHCAtrY2KisrcebMGZiamkJOTg6//vorunfvjsmTJwu8DOjo6AgejwdHR0ehbTMwMGi3Tv4M2FlZWejWrRt+/PFHlJeXo3///iJ9/oULF8LJyQl9+/bFw4cPsWHDBjx79oxd8aEjfUpfX184OjqioaFB6IoRhBBCCP9eZUNDA/7++28kJSUhJCQEjo6O8PLywh9//IHo6Gg4ODigR48euH79OgIDAzFkyBCMHDkSANC/f3/Y29tj1qxZ2LlzJwBg9uzZcHR0hKGh4dv8eIQQ8m5jyBs1ffp0ZsKECUL3lZSUMACEbvv372cYhmEiIyMZZWVlgWPv3LnDSEhIMHFxce3WwzAMM2HCBGb69OmctAcPHjB+fn6MlpYWIyUlxfTu3ZtxdnZmUlJSmJqaGqZ79+7Mpk2bhJYXGhrK9OjRg6mpqWEYhmFSUlIYAMyTJ0/aPB/CVFRUMACYioqKDh9LCPk40HVCNNOnTxcaUwwNDTn5goODGQBMcHCwQBmtxZ3WVFVVMStWrGD09PQYSUlJRkVFhZk0aRJz5coVTr7Vq1czpqamnLRnz54xPXr0YAAwJSUlDMMIxkY5OTmmf//+zNdff80UFxeL3C4rKyuh56JlLDx48CBjaGjISEpKMkZGRkx8fDxnPz++tVVOZGSk0DyrV68Wub30HSeEtOdjvU6I0p/Kz8/npDc2NjKGhobMV199xTBM69dpAExZWRl7XFv9Iz4tLS3mp59+avVvYbZs2cIYGxszsrKyTK9evRgPDw/mr7/+EvgcLTcrKys2jyjxqLGxkVm9ejWjrq7OSEtLM5aWlgLxuD38czVnzhxO+q+//soAYHx8fDjpZ8+eZSZNmsRoamoyUlJSjJqaGmNvb89kZGR0qN6P9ftNCBEdXSfeLkdHR8bBwUHovry8PAYAk5eXx7x8+ZIJCQlhTExMGBkZGUZFRYUZOXIkExUVxdTV1bHHiBJz29Ja/J01axYzYMAApqGhodXfCT/88APTtWtXpra2VuD4uro6RkVFhQkNDWXT4uLiGEtLS0ZRUZGRl5dnBg0axKxbt05gDLS1+kRB329CSHvoOvHq+NdpIyMjTvq9e/cYAIyuri6bVltby6xatYrR1tZmJCUlGXV1deZ///sfc/nyZTbPnDlzmO7du7NjgCYmJszXX38ttO74+HhGQkKCKS8vb3Xstb06Hz16xEyYMIFRUFBgVFVVmRUrVjBeXl5t3hdszs3NjenVqxcjKSnJaGhoMF988QVz7do1Th5R+5SNjY2MlpaW0N8GVlZWjL+/v0htao6+44SQ9tB14v3R/F6lhIQE07NnT8bGxoaJiIhgGhoaGIZhmLt37zKWlpaMiooKIyUlxejq6jLz589nHj16xCnr0aNHjIeHB6OoqMgoKioyHh4eIj+PIuz5FWFxuOX9S2GxTFgfFABz5MgRkdrSHvp+E0La05HrhBjDvMb16AjphGfPnkFZWRkVFRU07TUhRCi6TpAPHX3HCSHtoesE+ZDR95sQ0h66TpAPGX2/CSHtoesEeZdUV1dDQ0MDERER+OKLL15LmfQdJ4S0h64T5ENG329CSHs6cp2gpeHJO8Nlx21Iyihw0hL9Dd5SawghhJD/nrBYSLjotwEhhHy43vU4SDGIEELIm/SuxEGKd4QQQoRpbGxEeXk5QkNDoaysDGdn59dex7sSC18niquEkM7y9vbG06dPcfToUU56amoqrK2tsXfvXsyZMweFhYXQ09Nj9z948AADBgzAmjVr4O/vD21tbdy5cwcAICMjAzU1NZiZmWHOnDkYPXo0e1xpaSn69evH/q2kpIT+/ftj+fLlcHJyYtOjoqIQEBCAp0+fttr28vJyBAUFITExEffv34eqqioGDx6MgIAAjBkzhs2XlZWFDRs2IDs7Gy9evIC+vj68vb0REBAAcXFxNp+YmBikpaVx8+ZNaGlpsekTJ05E165dERUVxZ6zPXv2AAAkJCSgoqKCQYMGYcqUKfD29kaXLl047czPz0dwcDDS09NRUVGBvn37wsrKCosWLYKBAff6PXbsWJw5cwaZmZkwNzcXOF/CrF69GmvWrGkzT3Mt4yDFEEJIZ3RpP8t/y9vbGxMnThRIT01NhZiYGH799VfIy8vj9u3bnP0PHjxAt27dsHnzZgCAtrY2xMTEICYmBllZWWhra8PV1RVnz57lHFdaWsrmExMTg7KyMszNzfHbb79x8kVFRaFr165ttr28vBzz5s2Djo4OpKWloampCScnJ5w5c4aTLysrCw4ODujWrRtkZGRgYmKC0NBQNDQ0cPKJiYlBRkaGDcx8EydOhLe3N+ec8dsvKSkJNTU12NraIiIiAo2NjW22mc/d3R3jxo3jpJ08eRJiYmJYuXIlJ339+vXQ0NBg/46Pj8fw4cOhrKwMRUVFDBgwAIGBgSLVSwgh5L/TPF4030aPHo0ePXpgw4YNnPwDBgyAgoICpKWlISYmBgUFBcjIyEBMTAzR0dHt1tcydkZFRQmtf/fu3Zz9/fv3FyjrwIEDEBMTg7a2Nqdtwrbo6GgcPnwYtra26NmzJ5SUlDBixAj8/vvvAuXGx8fD2NgY0tLSMDY2xpEjRzj709PT4eTkBA0NDYiJiQl0uOvq6rBkyRKYmJhAXl4eGhoa8PLywoMHD9o9P4QQQt6OjsZDvpCQEPTo0QO1tbUi9Q/5WsublZUFcXFx2NvbCz3uVfpZLeOgvr4+ZGVlBWKmrKwspKWlKQ4SQsgHoq3YUltbi02bNsHU1BRycnLo0aMHRo4cicjISNTV1bH5RB3fbI22tjbCwsLYvxmGQWBgIBQVFdlx2VGjRgmNxfX19YiOjoaCggIkJSXZsVF+3BowYABb7u3btzFjxgz06dMH0tLS6NevH6ZMmYKLFy+22vdsvqWmprb5OdasWYPBgwcLpD99+pRzfMux5W7dusHS0hJpaWkinS9CCCHvn3ct3t69excKCgqQkpJi74kqKChAXFy81XjLN3v2bIiLiyM2NlZoPc3jrYyMDHr37o0dO3ZgyZIl2Ldv3yvHW0IIIZ3n5OQEOzs7TJ8+nfNMyOzZszFkyBDMnz+fTVu3bh3Kyspw8+ZN7N27F127doWNjQ2CgoIEyk1OTkZZWRkuXLgAMzMzTJo0CVevXhW5XaWlpRg6dCjOnj2LTZs24cqVK0hKSoK1tTX8/PzYfEeOHIGVlRX69OmDlJQU3LhxA/7+/ggKCoK7uztaLmwsJiaGVatWsX/PmTMHCQkJbB+Sf39QXFwc06ZNQ2lpKU6ePAlra2v4+/vD0dGREwMTEhJgbm6OmpoaREdHo6ioCL/++iuUlZUFno+5e/cusrOzMXfuXPB4PACApqYmysrKMG3aNMjJyUFSUhJdunSBnJwcu927d0/k80YIIa/LO/cgaHs+9oDWGnt7e5SVlbUb0FpjbW2Nc+fOcfKmpqZCU1MTKSkpnLz8t0yApvPm7u4OFxcX5OTkIC8vD0FBQaitrW23TkIIIf89frxovsXHx8PT0xNRUVGcOHTixAkUFBSgV69e8Pb2RkFBAdauXQsFBYVOv/GtpKQkUL+Hhwe7X15eHg8fPkR2djbnuIiICPTt21egbcI2Z2dnpKenw9bWFidOnEBeXh6sra3h5OSE/Px8tozs7Gy4ublh2rRpKCwsxLRp0+Dq6ooLFy6weaqqqmBqaopt27YJ/TzV1dW4dOkSVq5ciUuXLuHw4cO4devWG3kjnhBCyOvTkXjIFxkZiWnTpkFKSuq1tCEiIgLz5s3DuXPncPfuXc6+V+1ntYyDzs7O7MM1/HgZGRmJ2tpa+Pv7UxwkhJAPRGuxpba2FnZ2dti4cSNmz56NrKws5OTkwM/PD1u3bsW1a9cAiD6+KaqGhgb4+Phg7969OHv2LGe2mVmzZgnEYgkJCTg7OyM7OxsyMjKYPXs2hg4dysauEydOAAAuXryIoUOH4tatW9i5cyeuX7+OI0eOwMjICIGBgXBzc+OUO2LECIH6LCwsXvFsc/HHltPS0qCkpAQHBweUlJS81joIIYS8G961eKumpgZ7e3soKCggPj4eV65cQUFBAT799FO4urri3r17AvEWaOrPxcXFYdGiRexDLc21jLdFRUXIz8/HkiVLEBcX91biLSGEEK6dO3fi9u3b+PHHHwE0vZCekZGByMhIiImJsfkUFRWhrq6Ovn37wtLSEr/88gtWrlyJVatW4ebNm5wyu3fvDnV1dRgZGSEoKAh1dXUCz4u05euvv4aYmBhycnLg4uICAwMDDBgwAN988w3Onz8PoGnMcdasWXB2dsYvv/yCwYMHQ1tbG76+vtizZw8OHTqEAwcOcMqdN28e9u3bhytXrgBoehZo1KhRcHJyYvuMTk5OGDVqFH744Qf07t0bn3zyCZYtW4Zjx47h5MmT7Myh1dXVmDFjBhwcHHD8+HHY2NigX79+GD58OH744Qfs3LmTU3dkZCQcHR3x1VdfIS4uDlVVVRAXF4e6ujp++OEHFBYWYs6cOTAwMEBhYSG7hYSEiHzeCCHkdXkvl4bfuXMnBg4ciB9//BELFy5kA9rly5eFBjQAbFDr1asXVq1aBRcXFxgaGrJ5+QFNXV0dQUFB2Lp1K1JSUjBw4ECR2tQ8oMnLy7PpAwYMwMyZMwEIBjQ+X19fqKmpwdnZGQcOHICbmxu7b968eQgNDcXChQthYmLSav3S0tLsZ+UHNXNzc4wZMwZRUVHw9fVts/3W1taorKzExYsXYW5uDqDpgc9vv/0WCxYsQHV1NeTk5FBbW4vs7Gxs2bIFQNObEp999hkWLVrElmVgYCB0VldCCCFvX/N40ZyPjw82b96M9PR0WFlZAQC0tLSQkZGBO3fuIDAwEHp6elBTU4O4uDgUFRU7Vb+YmJjQ+vkkJCQwdepUREREYMSIEQCAv/76C6mpqViwYAH279/Ptq0tzWegAYDg4GAcO3YMv/32G4YMGcLmsbW1xdKlSwEAS5cuRVpaGsLCwth6xo0bJzBjdnPKyso4ffo0J23r1q0wMzPD3bt3OQ+vEkIIeXd0JB4CQEZGBoqLi+Hj4/Na6q+qqsKBAweQm5uL8vJyREVFcV4AfNV+Vss4GBoaiqSkJBQWFmLChAkAgOXLl2Ps2LHYtGkTAIqDhBDyvmsrtoSFhSE9PR0XL15k+0MAoKOjg8mTJ7MvGogyvimqmpoaTJkyBbm5uUhPTxdY+UFOTk5oLFZUVMSlS5cwcOBAbNq0Cb169YKEhAS7OgTDMPD29oa+vj4yMjI4S/sNHjwY/v7+kJWVhaysLJsuJSXVan2vS/Ox5Z07d6JPnz44deoUvvzyyzdWJyGEkP/euxxvMzMzOfFWVlYWvXr1Qp8+fYQee/DgQRgbG2Pp0qXo1asXSktL3/l4SwghhKtnz57YuXMnpkyZAlNTUyxYsACbN29u9x4aAPj7+2P9+vU4duwYFi9eLLC/rq4Ou3btAgBISkqK1J7Hjx8jKSkJQUFBnBjHx1816dSpU3j06BEWLlwokMfJyQkGBgbYv38/57kZCwsL3Lx5E0uXLkVCQgJUVVWhoKAAJSUl6OnpAWiajKaxsRGqqqqcMkePHg1TU1McPnwYvr6++P333/Hvv/8K/dzN2wk0xcTIyEhs374dRkZGMDAwwIEDBzBjxgwAgKqqKlRVVaGiogJpaWm2LYQQ8ra8dzOCAv8f0FauXInTp093OKAxDINjx44J3f8qAc3Pz++1BLTmLCws4OjoyD6k0hHNA1p7DAwMoKGhwb7N8fz5c1y6dAmTJ0+Grq4uMjMzAQDnz5/Hixcv2BlB1dXVce3atQ7NnlpTU4Nnz55xNkIIIW+XiYkJhg0bhsjISE56REQEzMzMRH4x4nXw8fFBXFwcqqurATS9wWhvbw81NbVOl9nY2Ijnz59DRUWFTcvOzsbYsWM5+ezs7JCVldXpegCgoqICYmJibS4ZTLGQEELeTf9VPIyLi4OhoSEMDQ3h6emJyMhIziyknelntYXiICGEfPjaii3R0dGwsbHhPJTCJykpCXl5eZHHN0VRWVmJ8ePH49q1awIPpYiCx+PB09MTysrKcHBw4MTlgoICXLt2DYGBgZyHUjrTzjdFTk4OADhLADdHcZAQQt5fFG873k5hKBYSQohoEhIS2GXP+VvLl7YnTpwIV1dX2Nvbw9LSEt7e3iKVraKiAlVVVZSWlnLSLSwsoKCgABkZGQQGBkJbWxuurq4ilXn79m0wDAMjI6M28926dQsAWo1dRkZGbJ7mQkJCkJSUhIyMDJHa07JM/mctLi5m09qTnJyM6upq2NnZAQA8PT2FzqTdERQHCSFv0jv5ICgFNK7XFdDaM2rUKKSmpgJomvHGwMAAPXv2hJWVFZvOXy5eV1cXQNOMpcOGDYOJiQm0tbXh7u6OiIgI1NTUtFpPSEgIlJWV2U1TU7PDn4sQQkjnCIux69evBwDMnDkThw4dQmVlJYCmwcSDBw++ttnPgKaHQ5rXLewN8cGDB0NXVxeHDh0CwzCIiorq8NvwLYWGhqKqqooT28vLywUeLlVTU0N5eXmn63n58iW+/fZbTJ06FUpKSq3mo1hICCFv19uOh/wbbkDTMvWVlZU4c+YMu78z/ay2UBwkhJAPX1uxpbi4uN1xS1HHN0Wxfv16FBQUICMjo9XZocPDwzlxODAwkG3r+fPn2Zlf+A/ZNDY2svsB0W7YvQ1VVVVYunQpxMXFObOLN0dxkBBC3l8Ub18PioWEECIaa2trdtlz/rZ7926BfCtXrkRjYyNWrlzZofIZhuGsuAs0vfSQn5+P48ePQ09PD7t37+a8XN5eeQAEymwvvyjtAgBjY2N4eXlhyZIlIpXfWpmt1SsMj8eDm5sbJCSaFlueMmUKLly4gJs3b3a4DXwUBwkhb9I7+SAoBTSu1xXQ2mNtbY3MzEzU1dUhNTUVo0aNAgCBB0FHjx7NHiMvL4/ExETcvn0bK1asYDuSZmZm7ExuLS1duhQVFRXsdu/evQ5/LkIIIZ0jLMb6+fkBaOq8NDY2Ii4uDkBTbGQYBu7u7q+tfkVFRU7drc06NnPmTERGRiItLQ2VlZVwcHDodJ379+/HmjVrEBcXJ7AcRMsY2ZG42VJdXR3c3d3R2NiI8PDwNvNSLCSEkLfrbcbDmzdvIicnhy1PQkICbm5uiIiIYPN0pp/VGoqDhBDy4Wsvtohyfe/o+GZbxo4di6qqKgQHB7eax8PDgxOH+ash8Xg82NnZoUePHgAABwcHVFVVITk5+bW383XiTzKgqKiI3377DVFRUTAxMRGal+IgIYS8nyjevj4UCwkhRDTy8vLQ09PjbL179xbIx39Ikf9fUTx69Aj//PMP+vXrx0nX1NSEvr4+xo8fj927d8PNzQ0PHz4UqUx9fX2IiYmhqKiozXwGBgYA0Gq+GzduQF9fX+i+tWvXIj8/H0ePHhWpTXxFRUXsZ+XXf+PGjTaPefz4MY4ePYrw8HBISEhAQkICvXv3Rn19PWcst6MoDhJC3iTRI8F/iB/Qmvvrr78E8r2JgKavrw8FBQVMmjQJ169fF7hRJkzzgDZx4sRW8zUPaBYWFgL7b9y4AWNjY6HHrl27FgYGBq8U0NpjbW2Nqqoq5ObmIiUlBYsWLQLQ9CCol5cXHj9+jOzsbEyfPl3gWF1dXejq6sLX1xfLly+HgYEB4uLiMGPGDIG80tLSkJaW7tDnIIQQ8noIi7F8ysrKcHFxQWRkJHx8fBAZGQkXF5c2Z/TqqC5durRaf3MeHh5YvHgx1qxZAy8vrw7F+ubi4uLg4+ODgwcPwsbGhrNPXV1dYNazhw8fdmoJ+rq6Ori6uqKkpARnz55t95xRLCSEkLfrbcZDHo+H+vp6zqAtwzCQlJTEkydP0K1bNza9I/0sYSgOEkLIx6G92GJgYNDujThRxzdFMWbMGMyfPx8TJkxAQ0MDtm7dKpBHWVlZIBY3NDRg7969KC8v5/QBGxoawOPxMHbsWM746uDBg1+pnW1RUlJCRUWFQPrTp0/Z9jcXFxcHY2NjdO3aFd27d2+zbIqDhBDyfqJ4+/pQLCSEkLdv8+bN6NKlS5vxyMrKCgMHDkRQUBA2b97cbpkqKiqws7PD9u3bMX/+fMjLy3P2P336FF27dsXYsWOhoqKC0NBQgedmjh8/juLiYnb1ppY0NTUxd+5cLFu2jF3Ftj1nz57FlStXsGDBAgBNL1P06NEDmzZtwpEjRwTy89sZHR2NPn36CDyjc+bMGYSEhCAoKKhT9y8pDhJC3qR3ckbQN6mjAU0UzQNaVVWVwH7+AGHzgNYSP6BNmTJFaB3NA1pDQ4NI7eIHtEmTJomUX1dXF5qamjh+/DgKCgrY5Yt69eoFbW1thIaG4uXLl7C2tm6zHG1tbcjJyQk9F4QQQt5tPj4+yMzMREJCAjIzM1/rMrgdoaKiAmdnZ6SlpXV6Wfj9+/fD29sbMTExGD9+vMD+ESNG4PTp05y0U6dOCX1Zoy38h1+Ki4uRnJzc7k0/Qggh7743FQ/r6+uxd+9ehIaGcmZlKSwshJaWFqKjo1s9tqP9LIqDhBDycRAltkydOhXJycnIz88XenxVVZXI45uisrW1RUJCAiIiIuDn5yfS0nsnTpzA8+fPkZ+fz/ksBw8exNGjR/Ho0SMMHjwYxsbGCA0NZZevfZV2tsbIyAh//fWXwEsTubm5Ql9w1NTUhK6uLsVBQgj5QFG8fbV2EkIIebueP3+O8vJy3Lt3D+np6Zg9ezY2bNiAoKCgdidvCQwMxM6dO3H//n02raGhQWC1pevXrwMAwsPD0dDQADMzM8THx6O4uBhFRUXYsmULRowYAaDpJf2dO3fi2LFjmD17Ni5fvozS0lLweDx4e3vDxcUFrq6urbZp6dKlePDgATuTdXM1NTUoLy/H/fv3cenSJQQHB2PChAlwdHSEl5cXW//u3buRmJgIZ2dnJCcno7S0FBcvXsTixYsxZ84cAE0vgbi4uGDgwIGcbebMmXj69CkSExM79g9BCCH/gXdyRtDXhR/Q6urqUFJSgn379mH37t0ICQkRKaBNnjwZixcvZt/u4we05qSkpGBsbIzw8HBYWFjAzMwM69atw6BBg1BfX4/Tp09jx44dKCoqYgOau7s7Zs+ejblz50JJSQlnzpzBokWLRApou3btQklJCdzc3Dj7+AGtoaEBf//9N5KSkhASEsIJaKKwtrZGeHg49PT0ODPBWFlZYevWrdDR0UHfvn3Z9DVr1qC6uhoODg7Q0tLC06dPsWXLFtTV1cHW1lbkegkhhPw3+PGiOQkJCXYZICsrK+jp6cHLywt6enqwtLR8G80EAERFRSE8PLxTN9L2798PLy8vbN68Gebm5uxnlpWVZWdu8ff3h6WlJb777jtMmDABx44dQ3JyMs6dO8eWU1lZidu3b7N/l5SUoKCgACoqKujbty/q6+vh4uKCS5cuISEhAQ0NDWxdKioqkJKSepVTQAgh5A15W/EwISEBT548gY+Pj8BMYi4uLuDxeJg7d+4r97MoDhJCyMdDlNhy/vx5JCYmYsyYMVi/fj0+++wzKCoq4uLFi/juu+/A4/EwePBgkcY3O2L06NFITEyEo6MjGIbB9u3b21xilsfjYfz48TA1NeWkDxgwAAEBAdi3bx/8/f0RGRkJGxsbWFpaYtmyZTAyMkJlZSV+++03nDp1CmlpaR1qpzBjx45F//794e7ujqCgIGhoaODy5ctYuHAh5syZA0VFxVeugxBCyPuD4u2bibeEEEL+G6tWrcKqVasgJSUFdXV1mJub48yZM+1OAAYAjo6O0NbWRlBQEMLDwwE0jRkOGTKEk09LSwulpaXo168fLl26hKCgIAQGBqKsrAw9e/bE0KFDsWPHDja/i4sLUlJSEBwcDEtLS7x48QJ6enpYvnw5AgIC2oxlKioqWLJkCZYtWyawLykpCb169YKEhAS6desGU1NTbNmyBdOnT0eXLv8/T96ECROQlZWFkJAQTJ06Fc+ePYOmpiZGjx6NDRs2IC8vD4WFhdi1a5dAHYqKihg7dix4PB4mTJjQ7jkkhJD/FPOOmT59OjNhwgSB9JSUFAYA8+TJEzatpKSEAcDk5+cL5NfS0mIAMAAYKSkppm/fvoyrqytz9uxZTr7WymhsbGQMDQ2Zr776imEYhomMjGTLa75paWmxxzx48IDx8/NjtLS0GCkpKaZ3796Ms7Mzk5KSwik7PT2dsbe3Z5SVlRkpKSnG2NiY+eGHH5j6+npOPgDMkSNHOGnBwcEMAGb69Omcc8Zvj4SEBNOzZ0/GxsaGiYiIYBoaGgTOTVv4n3POnDmc9F9//ZUBwPj4+HDSz549y0yaNInR1NRkpKSkGDU1Ncbe3p7JyMgQuc6KigoGAFNRUdGhthJCPh50nXg9mseL5puhoSEnHz/WBAcHC5QRGRnJKCsri1Qfj8djunfvLvKx7e3/6aefOHG3LVZWVkI/a/P4yTAMc/DgQcbQ0JCRlJRkjIyMmPj4eM5+/u+P1srh/44QtrWM/22h7zghpD10nXh93mY8dHR0ZBwcHITmy8vLYwAweXl5r9zPojhICPnQ0HWidaLGlpcvXzIhISGMiYkJIyMjw6ioqDAjR45koqKimLq6OvYYUcc3W6OlpcX89NNPnLS0tDRGQUGB+fLLL5nGxkbGysqK8ff35+QpLy9nJCQkmAMHDggtd968eYyJiQn7982bNxkvLy9GQ0ODkZKSYrS0tJgpU6Ywly5dEjhWWH2iKCsrY2bMmMFoaWkxsrKyjJGREbNu3Trm5cuXbJ62xqdFRd9vQkh76Drx9lG8fXPxlmHoO04IaR9dJ8iHjL7fhJD2dOQ6IcYwIqwTQMgb9OzZMygrK6OiogJKSkpvuzmEkHcQXSfeTxs3bsS+fftw9erVt92Udx59xwkh7aHrxPuL4mH76PtNCGkPXSfIh4y+34SQ9tB1gnzo6DtOCGkPXSfIh4y+34SQ9nTkOvFBLw3/umRlZeHzzz+Hra0tkpKSOPtqa2sRFhaG6OhoFBcXQ05ODoaGhvD19YWnpyckJSUBAOXl5QgKCkJiYiLu378PVVVVDB48GAEBARgzZky7bdDW1sadO3cAAF26dIGamhrGjRuHH374Ad26dQMApKamstN3i4mJQVFRETo6OrC1tcWCBQvQq1cvgXJjYmIwbdo0zJo1Cz///DMAIC8vD59++ikyMjLw2WefCRxjZ2cHaWlpHD9+HN7e3tizZ4/QPC3PVXtcdtyGpIwC+3eiv0GHjieEEPLm/fzzz1i0aBGePHkCCYmmnxGVlZXo1q0bzM3NkZGRgerqaty4cQPh4eG4d+9em8s3AEBkZCS0tbVFjmFr1qzB2rVrBcoxNDTEjRs3AACjRo1ilyeSkpKClpYWvL29sWTJEoiLiwMAGIbBrl27wOPxcO3aNUhISEBPTw+enp6YPXs25OTk2LL/+usv6OjoQEdHh62jtXY0V1JSAm1t7TbzNNcyFpL/R78LCCHteVf6bQEBAQgICEB1dTWKioqwadMmVFZW4uzZsxg9ejQnRjVXV1fHxtbZs2eDx+MhOjoa7u7uAnlv376NoKAgnD59Gv/88w80NDRgbm6OwMBAXL16FTNmzGiznSkpKRg1alSr+9esWYOjR4+ioKCAk/706VN069aNPZ6/3BNf165dYWJigvXr18PKyqrNNgjzrsdBikWEkA/NuxI779y5g+zsbJibm7PpAQEBKCgoQGpqKpv2+PFjrFu3DkePHsWDBw/QvXt32NvbY+3atejbt6/Q8kNCQrBs2TL4+/sjLCxMYP+7PDb6plFcI4S8i5pfVyUkJKCpqYkvvvgCa9euxT///MPpfygpKaF///5Yvnw5nJyc2PSoqCihfSJpaWm8fPmS/VuUGNa8j8f/m3+vTlZWFjo6Opg3bx6+/PJLttzo6Ghs2rQJxcXFUFZWhr29PX744Qd0794dAHDt2jWsWrUKeXl5uHPnDn766Se2fL709HR8//33yMvLQ1lZGY4cOYKJEydy8jAMg7Vr1+KXX37BkydPMHz4cGzfvh0DBgwQ+Xzn5+cjODgY6enpqKioQN++fWFlZYVFixbBwIAbJ8aOHYszZ84gMzMT5ubmAv1BYVavXo01a9aI3J53vU/YFoqrhBAiXEdie3P8PmLLuK6qqgozMzNs3LiRE/P49Xz55Zds347v66+/xo4dOzB9+nRERUWx6R3pzwYHB2PlypUICgrCt99+C4D7u0AYKysrTp+2Pfw4SDGFEPIqurztBrwPIiIiMG/ePJw7dw53795l02tra2FnZ4eNGzdi9uzZyMrKQk5ODvz8/LB161Zcu3YNAFBaWoqhQ4fi7Nmz2LRpE65cuYKkpCRYW1vDz89P5HasW7cOZWVluHv3LqKjo5Geno758+cL5Lt58yYePHiA3NxcLFmyBMnJydDX14ecnBwUFBQ4m5eXF1RUVBAbG4vq6moAwNChQ2FqaorIyEiBsu/du4fk5GT4+Piwafb29igrK+Ns+/fvF/lzEUIIeX9YW1ujsrISFy9exIABA6CgoICePXuioaEB586dg4KCAlRVVTF06FAoKSlBVVWVEx9cXV0F4oabmxtbvrAYNnDgQFy5coXTDmlpacjJyXG2e/fuQUFBAdHR0QCAWbNmoaysDDdv3sT8+fOxYsUK/PDDD2wZ06ZNQ0BAACZMmICUlBQUFBRg5cqVOHbsGE6dOsWpLyoqCq6urqiurkZmZiYAYOHChZzP0adPHzZW8zdNTc039U9BCCGkhbfVb+PHQwUFBdy9exdLlixh4+Gnn36KqqoqnDhxAqNHj2aP4ceo5hv/IdDq6mrExcVh0aJF4PF4AvVdvHgRhoaG2Lt3Lx49egQJCQn8/fffiI+Px/Dhw8EwDKfcESNGCNRnYWHxuk47ACA5ORllZWVIS0uDkpISHBwcUFJS8lrrIIQQ8vp1NHYOHjwYvr6+UFZWhoKCAuTl5aGhoYHt27ejrq6u02OeMjIyWLJkSZt5Hj9+DHNzcyQnJyM8PBy3b99GXFwc/vjjDwwbNgx//vmnwDG5ubn45ZdfMGjQIIF9/Pjt5eUFcXFx7Ny5k43nN27coLFRQgh5i/jX1T///BMbNmxAeHg4Fi5cyO7n9z8uXLgAMzMzTJo0SWAFBiUlJYFrc/MHNV7lvh1//O/y5cuYOHEi5syZg7i4OADAuXPn4OXlBR8fH1y7dg0HDx5Ebm4ufH192eOrq6uho6ODjRs3Ql1dXaD86Oho2NnZ4ffff8eTJ08AAFOmTIGCggLngZdNmzbhxx9/xLZt25Cbmwt1dXXY2tri+fPnIp3nhIQEmJubo6amBtHR0SgqKsKvv/4KZWVlrFy5kpP37t27yM7Oxty5c9l+qqamJuf8BgYGYsCAAZy05v9uhBBCPl6ixvbm29ChQ9n9/Lj+4MEDJCYmoqqqCuPHj0dtbS2nHk1NTcTGxuLFixds2suXL7F//36Blwc7+lsgMjISixcvRkREBJuWm5vLtjc+Ph5A031Oftrhw4df7cQRQkgn0Iyg7aiqqsKBAweQm5uL8vJyREVFYdWqVQCAsLAwpKen4+LFixgyZAh7jI6ODiZPnswGnq+//hpiYmLIycmBvLw8m2/AgAGYOXOmyG1RVFRkO4W9e/eGl5cXYmNjBfKpqqqia9euUFdXh4GBASZMmABTU1MoKiqynVGgaXYze3t7nD17FrNmzcKhQ4fg5eUFAPDx8cGyZcuwZcsWTpujoqLQs2dPjB8/nk2TlpYW2lklhBDy4TE0NISGhgZSU1Nx4sQJ1NXVYdOmTaiursaFCxewYsUKjBw5Empqapg4cSIGDx7MiRGysrKoqalpNW4Ii2FDhgzBV199hXPnzrH5dHR0cPz4caFlqKmpYdeuXZCTk2PrmTt3Lo4dO4ajR49iyZIlOHDgAKKjo3H06FFMmDCBPVZbWxvOzs549uwZm8YwDCIjIxEeHo4+ffqAx+Nh5MiR7E1CPnFxcU6sJoQQ8t95m/02fjwEmt7y9vb2hoeHBwICAnDt2jUkJyejf//+nGOax6iWDh48CGNjYyxduhS9evVCaWkpO7s0wzDw9vaGsbEx4uPj0aUL993OZ8+eQV9fH4qKimyalJRUm/W9Dt27d4e6ujrU1dWxc+dO9OnTB6dOneLMikMIIeTd0pnYuXHjRsydOxd1dXWQk5ODj48Pbt68iVOnTkFZWRlaWloAOj7m+eWXX2LHjh04ceIEHBwchOZZvnw5Hjx4gNu3b7MxrW/fvvj999+hr68PPz8/nDx5ks1fWVkJDw8P7Nq1Cxs2bBAo78SJEygpKYG9vT2ys7MxY8YMeHh44H//+x/U1NTw+PFjGhslhJC3pPl1derUqUhJSWHH9ABu/yMoKAhbt25FSkoKBg4cyJYhJibW5rX5Ve7bNR//27BhAw4cOICjR4/Czc0N58+fh7a2NjuJS79+/fDll19i06ZN7PHDhg3DsGHDAICdUaw5Z2dnzkvx+vr6+PHHH2Fra8vOyM0wDMLCwrB8+XJ88cUXAIA9e/ZATU0NMTEx7fbFqqurMWPGDDg4OODIkSNser9+/TB8+HA8ffqUkz8yMhKOjo746quvYGZmhrCwMMjLy3POsYKCAiQkJCgmEkIIESBqbG9N87jeq1cvLFiwAM7Ozrh58yZMTEzYfJ988gn+/PNPHD58GB4eHgCAw4cPQ1NTEzo6OpwyO/JbIC0tDS9evMC6deuwd+9epKenw9LSEj179mTzqKioAPj/+5yEEPK20Iyg7YiLi4OhoSEMDQ3h6emJyMhIMAwDoOmtPBsbG86AKJ+kpCTk5eXx+PFjJCUlwc/PjxNA+DobBO7fv4+EhAQMHz683byysrL4+uuvcenSJSgpKUFPTw96eno4e/YsnJycYGJiAk9PT85sMx4eHqirq8PBgwfZNIZhEBUVhenTp7Oz1XRGTU0Nnj17xtkIIYS8P0aNGoWUlBRoaWlBT08PBQUFmDhxImxtbXHr1i3o6elBWloa2dnZ7HLvnSUrK4s5c+YgMzMTDx8+ZNOlpKTYeNZya/7wS8uy+A/qREdHw9DQkPMQKJ+YmBiUlZXZv1NSUlBdXQ0bGxtMmzYNBw4cEPnN+tZQLCSEkNfrbfbb+PFQT08PkpKSkJWVxfz589llbls+BNoeHo8HT09PKCsrw8HBgTMbWUFBAa5du4Zly5bBwMBAIAZ+8sknrcbB/4qcnBwAsDFXGIqDhBDy9nUmdioqKqJ///4YNGgQVFRUkJGRAX9/fwwaNIh9CJSvI2Oe2tramDNnDpYuXYrGxkaB/Y2NjYiNjYWHh4fAzUH+uOfvv/+Ox48fs+l+fn4YP348bGxshNappaXFjo0OGTIEvr6+SEhIYPuUNDZKCCHvjuZjes3V1dVh165dAMA+ICmK133fTkZGhm2fhYUF/vrrL5w4cQIMw+Dvv//GoUOHOC8QtEdRUZHTzwOaHnrR09Nj421JSQnKy8sxduxY9jhpaWlYWVkhKyur3Tp+//13/Pvvv1i8eLHQ/c3PAf8leU9PTxgZGcHAwAAHDhwQ+fMIQ7GQEEI+bq3FdlE8ffoUMTExAITH/xkzZnDGUyMiIgQe7OzobwEej4cpU6ZAUlISU6ZMEbqKU0dQHCSEvEn0IGg7+DfhgKYpqysrK3HmzBkAQHFxMYyMjNo8/vbt22AYpt18ouAvMSgrK4s+ffpATEwMP/74o0jH8usvLS0F0DSAGhUVxX42d3d3ZGdn4/bt2wCa3liYOHEiJ0impqbizz//FAiUCQkJAkvOr1+/vtW2hISEQFlZmd1o2VxCCHm/jBo1CpmZmaivr8fz58+Rn58PS0tLWFlZITU1FQBw/vx5vHjx4pUfBAUEYxgAXLlyRSD2NF9iqbnGxkYkJSXh999/x5gxYwA0xXBDQ0OR6ufxeHB3d4e4uDgGDBgAPT09zgzbnUGxkBBCXq93qd+2fv16FBQUICMjQ2DJIb7w8HBODAsMDGTbev78ebi5uQEA+2AO/6GY4uJiAHgt7XwTqqqqsHTpUoiLi8PKyqrVfBQHCSHk7XuXYicArFixAiUlJYiOjhbY988//+Dp06etvlzRv39/MAzDjmvGxsbi0qVLCAkJabU+GhslhJD3Q05ODmJiYtgxPaDpYUsFBQXIyMggMDAQ2tracHV15RxXUVEhcG3mPzT5umJYfX09oqKicOXKFbZ9FhYWiI6OhpubG6SkpKCuro6uXbti69atr1RXS+Xl5QCaVkZqTk1Njd3Xlo70LZOTk1FdXQ07OzsAEJhYpjMoFhJCyMerrdjefGtoaGD38+O6vLw8unXrhtjYWDg7OwuNY9OmTcO5c+dQWlqKO3fuIDMzk+338XXkt8CzZ88QHx/PluHp6YlDhw690sObFAcJIW8SPQjahps3byInJwfu7u4AAAkJCbi5uSEiIgJA01twYmJibZbBf5O+vXyiWLRoEQoKCnD58mV2YHb8+PGcIChqO06dOoWqqiqMGzcOANCjRw+MHTuW/WxA0/Lw6enp7ABoREQERo4cKfDgjLW1NQoKCjibn59fq21ZunQpKioq2O3evXsdOAuEEELeNmtra1RVVSE3NxcZGRkwMDCAqqoqrKyskJubi6qqKqSmpqJv374CSy10hrBYamhoKBB7goKCOMfxH7KRkZGBs7MzPD09sXr1arZMUWLz06dPcfjwYU4n0dPTkxMvO4NiISGEvD7vWr9t7NixqKqqQnBwcKt5PDw8ODFs6dKlAJoeyrGzs0OPHj0AAA4ODqiqqkJycvJrb+frxB+sVVRUxG+//YaoqCjOskwtURwkhJC3612LnQDQs2dPLFy4EKtWrUJtbW2Hjm3elnv37sHf3x/79u2DjIxMq8fQ2CghhLy7+A/Yy8jIYMSIEbC0tOQ8SBkXF4f8/HwcP34cenp62L17N7scK5+ioqLAtZn/cP+rxrDmk7b4+flh0aJF7FLs169fx/z587Fq1Srk5eUhKSkJJSUlmDNnTqfqak/LzyDqmCf/HIiCx+PBzc2NnQ17ypQpuHDhAm7evNmxxjZDsZAQQj4uosT2lnFbXFyc3c+P63l5efj555+hq6uLn3/+WWhdPXr0wPjx47Fnzx5ERkZi/Pjx7FgrX0d+C8TExEBHRwempqYAgMGDB0NHRwexsbEdPg98FAcJIW9S59ew+QjweDzU19ejd+/ebBrDMJCUlMSTJ09gYGCAoqKiNsvQ19eHmJgYioqKMHHixFdqT48ePdhlIPT19REWFoYRI0YgJSWl1WWO+Pjt1NbWBtA0cPn48WN22T6g6U34/Px8rF+/HuLi4rCxsYGWlhaioqKwePFiHD58GNu2bRMoW15enm2XKKSlpSEtLS1yfkIIIe8WPT099OnTBykpKXjy5Ak745e6ujr69euHzMxMpKSkYPTo0a+lvpYxDPj/peHb4uHhgeXLl0NaWhoaGhqcTqMoMRxo6uC9fPkSw4cPZ9MYhkFjYyOuX78OY2PjDn6aJhQLCSHk9XnX+m1jxozB/PnzMWHCBDQ0NAid+UVZWVkgjjU0NGDv3r0oLy/nLDfb0NAAHo+HsWPHwsDAAEBTbBw8ePArtbMtSkpKqKioEEh/+vQp2/7m4uLiYGxsjK5du6J79+7tlk9xkBBC3q53LXbyffPNNwgPD0d4eDgnvWfPnujatSuuX78u9LgbN25ATEwMurq6SE9Px8OHDzF06FB2f0NDA9LT07Ft2zbU1NRAXFycxkYJIeQdZm1tjR07dkBSUhIaGhrssq/81YI0NTWhr68PfX19KCgoYNKkSbh+/TpUVVXZMrp06dLqtflVY9iiRYvg7e0NOTk59OrVi/MQSUhICEaOHIlFixYBAAYNGgR5eXl8/vnn2LBhA3r16tXh+oRRV1cH0DQzaPMyHz58KDBLqDD8vuWNGzcwYsSIVvM9fvwYR48eRV1dHXbs2MGmNzQ0ICIiAt99912n2k+xkBBCPi6ixPa2+lTN47qRkRHKy8vh5uaG9PR0oflnzpyJuXPnAgC2b98usL8jvwUiIiJw7do1znhtY2MjeDweZs+e3eaxraE4SAh5k2hG0FbU19dj7969CA0N5bx5UFhYCC0tLURHR2Pq1KlITk5Gfn6+0OOrqqqgoqICOzs7bN++HVVVVQL5+DfSOoP/QMuLFy/azPfixQv88ssvsLS0RM+ePfHo0SMcO3YMsbGxAm9WVFZW4uTJkwCa3oCYMWMG9uzZg5iYGHTp0kVgeQ1CCCEfJ2tra6SmpiI1NRWjRo1i062srPD777/j/Pnzr2VZ+JYxrCP4D9loampyHgIFgKlTp+LWrVs4duyYwHEMw7APv/B4PAQGBgr8FrC2tn7lWUEJIYS8une132Zra4uEhARERETAz89PpNlWTpw4gefPnyM/P5/zWQ4ePIijR4/i0aNHGDx4MIyNjREaGsouF/8q7WyNkZER/vrrL4ElBXNzc4XeUNXU1ISurq5ID4ESQgh5u97V2AkACgoKWLlyJYKCgjjL7PHHJGNiYgRi04sXLxAeHg47OzuoqKhgzJgxuHLlCuezffrpp+xs3OLi4jQ2Sggh7zj+A/ZaWlrsgyKtsbKywsCBAwVWCmrLq8Yw/qQtGhoaAjOJVVdXo0sX7q1X/rhkR2bhbE+/fv2grq6O06dPs2m1tbVIS0uDhYVFu8ePHTsWPXr0wKZNm4Tu55+D6Oho9OnTB4WFhZx4GRYWhj179qC+vv61fB5CCCEfto7EdlEsWLAAhYWFOHLkiND99vb2qK2tRW1tLezs7AT2i/pb4MqVK7h48SJSU1M5cTA9PR25ubm4evXqK38WQgh53ehB0FYkJCTgyZMn8PHxwcCBAzmbi4sLeDweAgICMHLkSIwZMwbbt29HYWEh/vzzTxw4cADDhw9HcXExgKalaRsaGmBmZob4+HgUFxejqKgIW7ZsafNNu5aeP3+O8vJylJWVIScnB4sWLUKPHj0EOnUPHz5EeXk5iouLERsbi5EjR+Lff/9l39b79ddf0b17d0yePJnzuQYNGgRHR0fweDy2rBkzZuDBgwdYtmwZ3N3dIS8vL9CumpoalJeXc7Z///23M6edEELIe8La2hrnzp1DQUEBOyMo0DT4umvXLrx8+bJTD4K2F8P46uvrBWLP33//LXI9rq6ucHNzw5QpUxASEoKLFy/izp07SEhIgI2NDVJSUlBQUIBLly7B19dX4LfAlClTsHfvXtTV1XX4MxJCCHl93sV+G9/o0aORmJiIPXv2iPQwKI/Hw/jx42Fqasr5HJMmTULPnj2xb98+iImJITIyErdu3YKlpSVOnDiBP//8E5cvX0ZQUBAmTJjQqfPY0tixY9G/f3+4u7sjMzMTJSUlOHbsGBYuXIg5c+ZAUVHxtdRDCCHkv/cux04AmD17NpSVlbF//35OelBQENTV1WFra4uTJ0/i3r17SE9Ph52dHerq6thZXhQVFQU+l7y8PLp3746BAwcCoLFRQgj50AQGBmLnzp24f/8+m8YwjMC1uby8nH2h7k3EMABwcnLC4cOHsWPHDvz555/IzMzE/PnzYWZmBg0NDQBND2zyHySpra3F/fv3UVBQgNu3b7PlVFZWsnkAoKSkBAUFBbh79y6AppcVAgICEBwcjCNHjuDq1avsLKVTp05tt53y8vLYvXs3EhMT4ezsjOTkZJSWluLixYtYvHgxu5Q9j8eDi4uLQGydOXMmnj59isTExE6fK0IIIYTv0aNHAjH75cuXreZXUlKCr68vVq9eLXTMVVxcHEVFRSgqKhKYKIZPlN8CPB4PZmZmsLS05MTBzz77DCNGjOD0HQkh5J3BEKEcHR0ZBwcHofvy8vIYAExeXh7z8uVLJiQkhDExMWFkZGQYFRUVZuTIkUxUVBRTV1fHHvPgwQPGz8+P0dLSYqSkpJjevXszzs7OTEpKikjt0dLSYgCwW8+ePRkHBwcmPz+fzZOSksLuFxMTYxQVFRlTU1Nm0aJFTFlZGZvPxMSE+frrr4XWEx8fz0hISDDl5eVs2tixYxkATFZWlkD+6dOnc9rF3wwNDUX6XAzDMBUVFQwApqKiQuRjCCEfF7pOvHtKSkoYAIyRkREn/d69ewwARldXV+hx06dPZyZMmCCQLmoMYxiGWb16tdDYIy0tzeaxsrJi/P392/wMDQ0NzI4dO5hhw4YxcnJyjJKSEjN06FBm8+bNTHV1NTN37lzG2NhY6LEPHz5kxMXFmfj4eDZNS0uL+emnn9qsszX0HSeEtIeuE8K9i/22lrEgLS2NUVBQYL788kumsbFRaIwqLy9nJCQkmAMHDggtd968eYyJiQn7982bNxkvLy9GQ0ODkZKSYrS0tJgpU6Ywly5dEjhWlJgoTFlZGTNjxgxGS0uLkZWVZYyMjJh169YxL1++ZPPwfw8075d2Bn2/CSHtoevE6/M+xM6YmBgGAGNlZcVJ/+eff5h58+YxmpqajISEBKOmpsZMnz6duXPnTpt1tIyFNDZKCHnffEzXidbGDhmm9f5HY2MjY2hoyHz11VcMwzBMZGSk0GszAM44oygxrGWcEmX8b8uWLYyxsTEjKyvL9OrVi/Hw8GD++usvgc/Rcmse95qPlTbfpk+fzvncq1evZtTV1RlpaWnG0tKSuXLlSpttayk3N5f54osvmJ49ezLS0tKMnp4eM3v2bKa4uJi5ePEiA4DJyckReqyTkxPj5OTE/r169WrG1NS0Q/XzfUzfcUJI59B14v0lSmwXtu3fv59hmKa4rqysLHDsnTt3GAkJCSYuLq7dehiGYSZMmMCJowzT9m+Bmpoapnv37symTZuElhcaGsr06NGDqampYRjm/2P3kydP2jwfwtD3mxDSno5cJ8QY5jWuRUBIJzx79gzKysqoqKiAkpLS224OIeQdRNcJ8qGj7zghpD10nSAfMvp+E0LaQ9cJ8iGj7zchpD10nSAfOvqOE0LaQ9cJ8iGj7zchpD0duU5I/EdteidlZWXh888/h62tLZKSkjj7amtrERYWhujoaBQXF0NOTg6Ghobw9fWFp6cnJCUlAQDl5eUICgpCYmIi7t+/D1VVVQwePBgBAQEYM2ZMu23Q1tbGnTt3kJ2dDXNzczY9ICAABQUFSE1NZdMeP36MdevW4ejRo3jw4AG6d+8Oe3t7rF27Fn379hVafkhICJYtWwZ/f3+EhYUJ7I+JicG0adMwa9Ys/PzzzwCAvLw8fPrpp8jIyMBnn30mcIydnR2kpaVx/PhxeHt7Y8+ePULztDyn7XHZcRuSMgrs34n+Bh06nhBCPjTe3t54+vQpjh49yklPTU2FtbU19u7dizlz5qCwsBB6enrs/gcPHmDAgAFYs2YN/P392VgDADIyMlBTU4OZmRnmzJmD0aNHs8eVlpaiX79+7N9KSkro378/li9fDicnJzY9KioKAQEBePr0aattFzU+ZmVlYcOGDcjOzsaLFy+gr68Pb29vBAQEcJZrEBMTg7S0NG7evAktLS02feLEiejatSuioqLYc8aPSxISElBRUcG9TglfAAC9lElEQVSgQYMwZcoUeHt7o0uXLpx25ufnIzg4GOnp6aioqEDfvn1hZWWFRYsWwcCAG4fGjh2LM2fOIDMzE+bm5gLnS5jVq1djzZo1beZprmUsfB9QvCaEvA0fal8uJCQEhw8fxo0bNyArKwsLCwt89913MDQ0ZPMwDIO1a9fil19+wZMnTzB8+HBs374dAwYMYPPU1NRg4cKF2L9/P168eIExY8YgPDwcffr0Efgcs2fPBo/HQ3R0NNzd3QEAoaGhWLduHcrKyiAnJ8fJ//LlS6irq2PVqlX45ptvOL8zmgsJCcG3337b7nls7l2NgxTrCCEfktbG8qytrXH58mUEBARgxYoVAvtDQkIQGhqKBw8eICYmpt0+IV9r/ce2YjkAxMfHY9OmTbhx4wYaGxvRt29f2NvbIzQ0tN06+UvyFhQUoKamhu0f29nZCdSxcuVK/PHHH9DV1UVQUBD+97//sfvT09Px/fffIy8vD2VlZThy5AgmTpzI7q+rq8OKFStw4sQJ/Pnnn1BWVoaNjQ02btzILv/bEf9VHKS4Rgh5X9DYKI2Nvi8othJC3gdvuy8YFRWFGTNmCOTbtWsXfH192f1GRkYoKiri5Dlw4ADc3NygpaWF0tLSdut+n/uEp5Z80uHjCCGkuS7tZ/lwRUREYN68eTh37hzu3r3LptfW1sLOzg4bN27E7NmzkZWVhZycHPj5+WHr1q24du0agKZO4dChQ3H27Fls2rQJV65cQVJSEqytreHn5ydyOyQlJTFy5EgoKCiwW3h4ODIyMtibeY8fP4a5uTmSk5MRHh6O27dvIy4uDn/88QeGDRuGP//8U6Dc3Nxc/PLLLxg0aFCb52Dx4sWIjY1FdXU1AGDo0KEwNTVFZGSkQP579+4hOTkZPj4+bJq9vT3Kyso42/79+0X+/IQQQjrHyckJdnZ2mD59OhobG9n02bNnY8iQIZg/fz6bxn+Y4+bNm9i7dy+6du0KGxsbBAUFCZSbnJyMsrIyXLhwAWZmZpg0aRKuXr0qcrtEjY9HjhyBlZUV+vTpg5SUFNy4cQP+/v4ICgqCu7s7Wk5aLiYmhlWrVrVbPz8ulZaW4uTJk7C2toa/vz8cHR1RX1/P5ktISIC5uTlqamoQHR2NoqIi/Prrr1BWVsbKlSs5Zd69exfZ2dmYO3cueDweAEBTU5MT+wIDAzFgwABO2sKFC0U+b4QQQkT3Nvpy0dHRnD4bv96RI0dyHsJsqSN9ubS0NPj5+eH8+fM4ffo06uvrMXbsWFRVVbF5Nm3ahB9//BHbtm1Dbm4u1NXVYWtri+fPn7N5AgICcOTIEcTGxuLcuXOorKyEo6MjGhoaAAADBgxgP8euXbsgLi4OT09PKCgoIDo6Gl5eXnjx4gXi4+MFPk98fDyqq6sxbdo0No3/O6P5Nm/evDb/DQkhhLw9wsby4uPj4enpiaioKIG+GABERkZi2rRpkJKSErme6OhozJkzBxUVFZwYqqCggPHjxwuN5UBTn9Td3R0uLi7IyclBXl4egoKCUFtbK1K96enpsLW1xYkTJ5CXlwdra2s4OTkhPz+fzZOdnQ03NzdMmzYNhYWFmDZtGlxdXXHhwgU2T1VVFUxNTbFt2zah9VRXV+PSpUtYuXIlLl26hMOHD+PWrVtwdnYW+RwRQgjpPBobFc7e3h7btm2DlJQUnj9/jvT0dPj4+EBKSgoKCgps/5XGRgkh5OPzX/UFW6OkpCRQv4eHB7tfXl4eDx8+RHZ2Nue4iIiIVidGE4b6hISQj9lHOyNoVVUVDhw4gNzcXJSXlyMqKortQIWFhSE9PR0XL17EkCFD2GN0dHQwefJkdtDx66+/hpiYGHJyciAvL8/mGzBgAGbOnClyW3x9fbF7926EhYVh1KhRAIANGzagqKgIBw4cAAAsX74cDx48wO3bt6Gurg4A6Nu3L37//Xfo6+vDz88PJ0+eZMusrKyEh4cHdu3ahQ0bNgitt7S0FFlZWYiPj0dKSgoOHToELy8vAICPjw+WLVuGLVu2cD5bVFQUevbsifHjx7Np0tLSbJsIIYT8t3bu3ImBAwfixx9/xMKFCxEVFYWMjAxcvnwZYmJibD5FRUVO/LC0tESvXr2watUquLi4cGYa6969O9TV1aGuro6goCBs3boVKSkpGDhwoEhtEiU+VlVVYdasWXB2dsYvv/zC5vH19YWamhqcnZ3ZN/z45s2bh9DQUCxcuBAmJiat1t88LvXu3RuffPIJzM3NMWbMGERFRcHX1xfV1dWYMWMGHBwccOTIEfbYfv36Yfjw4QJvM0ZGRsLR0RFfffUVzMzMEBYWBnl5eU78U1BQgISEBMVEQgh5w95WX87Z2RnDhw9n/7aysoKtrS1iYmKwaNGiVtvbkb5cyxnRIiMjoaqqiry8PFhaWoJhGISFhWH58uX44osvAAB79uyBmpoaYmJi8OWXX6KiogI8Hg+//vorbGxsAAD79u2DpqYmkpOTYWdnhxMnTqCurg6HDx/G/v37ERERgREjRiAhIQFDhw6FoqIinJycEBERwXngE2gaeHV2dkbPnj3ZtOa/MwghhLz7WhvL8/HxwebNm5Geng4rKys2PSMjA8XFxZwXw0Xh7OyMtWvXYsOGDZwbbtXV1bCwsMBXX30lEMuBpgdTPvvsM058NTAw4My80paWqyIFBwfj2LFj+O2339jfB2FhYbC1tcXSpUsBAEuXLkVaWhrCwsLYF9zHjRuHcePGtVqPsrIyTp8+zUnbunUrzMzMcPfu3Q7dqCSEENI5NDYqSFpaGl5eXpxZz7Kzs+Hl5YVly5bBw8ODxkYJIeQj9V/1BVsjJibWZpyQkJDA1KlT2bFKAPjrr7+QmpqKBQsWiDwZGfUJCSEfs492RtC4uDgYGhrC0NAQnp6eiIyMZN9wiI6Oho2NDefGIZ+kpCTk5eXx+PFjJCUlwc/Pj9OR4+vatavIbTEwMMBXX32FrVu3QkdHB3p6eujatStkZWWhpaWFxsZGxMbGwsPDQyAwysrK4uuvv8bvv/+Ox48fs+l+fn4YP348e+NPmIiICIwfPx7Kysrw9PRk3+IDAA8PD9TV1eHgwYNsGsMwiIqKwvTp0yEh8dE+Q0wIIe+Unj17YufOnVi5ciVOnz6NBQsWYPPmzZwlglrj7+8PhmFw7Ngxofvr6uqwa9cuAGCX0W2PqPHx1KlTePTokdC3wp2cnGBgYCDQobOwsICjoyPbKeuI0aNHw9TUFIcPHwYA/P777/j333+xePFiofmbx3GGYRAZGQlPT08YGRnBwMCAfVGDEELIf+9t9eUUFRWhp6fHbpKSkhg8eDC++uor/PTTT5wZaPg605drrqKiAgCgoqICACgpKUF5eTnGjh3L5pGWloaVlRWysrIAAHl5eairq+Pk0dDQwMCBA9k8Wlpa0NPTQ0JCAnx9fTFkyBA4OjoiJSUFioqKAJoGgNPS0lBSUsKWU1paipSUlNc2+EsIIeTdYmJigmHDhgmsEhQREQEzMzORH4DhU1RUhJqaGsTFxTkx9OLFi+jfv7/QWA4A6urquHbtWodmX2tLY2Mjnj9/zsZToOmBmOaxEgDs7OzYWNlZFRUVEBMT69DYMCGEkM6jsVHhWvZfp02bBlNTU5w7dw5aWlo0NkoIIYTjdfcFX4WPjw/i4uLY1WyjoqJgb28PNTW1TpdJfUJCyMfko30QlMfjwdPTE0DTFNiVlZU4c+YMAKC4uBhGRkZtHn/79m0wDNNuPlGtWLECJSUliI6OFtj3zz//4OnTp+jfv7/QY/v37w+GYXD79m0AQGxsLC5duoSQkJBW62tsbERUVBR7Dtzd3ZGdnc2WoaKigokTJ3KCfWpqKv7880+BGXISEhIElndav359q3XX1NTg2bNnnI0QQohwwq6xLd8+mzhxIlxdXWFvbw9LS0t4e3uLVLaKigpUVVVRWlrKSbewsICCggJkZGQQGBgIbW1tuLq6ilSmqPHx1q1bANBqbDMyMmLzNBcSEoKkpCRkZGSI1J6WZfI/a3FxMZvWnuTkZFRXV7Nv0bd8eaIzKBYSQkjnfch9ueYYhsE333yDzz77jB1sLS8vBwCBgU81NTV2X3l5OaSkpNCtW7dW8wBN5+r8+fPsDDP8B3H4D7Ta2dlBQ0MDUVFR7DGRkZHQ0NAQGCRdsmSJwO+V1NRUoZ8ZoDhICCFvW1tjeTNnzsShQ4dQWVkJoGnVoYMHD77WlwDaiuVA04xnw4YNg4mJCbS1teHu7o6IiAjU1NR0qr7Q0FBUVVVx+rXl5eVtxtPOePnyJb799ltMnToVSkpKreajOEgIIaKjsVEuGhslhBDyKt52X7CiooJTt7DZQQcPHgxdXV0cOnSInaisI6vxCkN9QkLIx+SjfBD05s2byMnJgbu7O4CmKabd3NwQEREBoOmGW/MlI4Thv6XeXj5R9ezZEwsXLsSqVavY5QpF1bwt9+7dg7+/P/bt2wcZGZlWjzl16hSqqqrYDnOPHj0wduxY9hwATW9bpKenszclIyIiMHLkSM4SGQBgbW2NgoICzubn59dq3SEhIVBWVmY3TU3NDn1eQgj5mAi7xu7evVsg38qVK9HY2IiVK1d2qHxhMS8uLg75+fk4fvw49PT0sHv3bs5bcu2VB4geH5vP+tJeuwDA2NgYXl5eWLJkiUjlt1Zma/UKw+Px4Obmxs6GPWXKFFy4cAE3b97scBv4KBYSQkjnfMh9uZbmzp2Ly5cvC13yqGV+UT938zw8Hg92dnbo0aMHAMDBwQFVVVVITk4GAIiLi2P69OmIiopCY2MjGIbBnj174O3tDXFxcU7ZixYtEvi9Mnz48FbbQnGQEELerrbG8qZMmYLGxkbExcUBaOofMgzDxt5X1V4sBwB5eXkkJibi9u3bWLFiBRQUFBAYGAgzMzN2VhhR7d+/H2vWrEFcXBxUVVU5+zoTT1tTV1cHd3d3NDY2Ijw8vM28FAcJIUR0NDbKRWOjhBBCXsXb7AsCTTNWN6+7tdk3Z86cicjISKSlpaGyshIODg6drpP6hISQj81H+SAoj8dDfX09evfuDQkJCUhISGDHjh04fPgwnjx5AgMDAxQVFbVZhr6+PsTExNrN1xHffPMNXrx4IRAYevbsia5du+L69etCj7tx4wbExMSgq6uLvLw8PHz4EEOHDmU/W1paGrZs2QIJCQk0NDQAaHqo8/Hjx5CTk2PznThxAnv27GHz2NjYQEtLC1FRUXj27BkOHz4s9I0PeXl5zhITenp6bXaKly5dioqKCna7d+9eZ08ZIYR88IRdY3v37i2Qjz8Qx/+vKB49eoR//vkH/fr146RrampCX18f48ePx+7du+Hm5oaHDx+KVKao8dHAwAAAWs1348YN6OvrC923du1a5Ofn4+jRoyK1ia+oqIj9rPz6b9y40eYxjx8/xtGjRxEeHs7Gy969e6O+vp5zo7KjKBYSQkjnfMh9uebmzZuH48ePIyUlBX369GHT+W/Jt3wz/eHDh+wb7Orq6qitrcWTJ09azdPQ0IC9e/ciMTGRPY9ycnJ4/PgxZ2aXmTNn4t69ezh79izOnDmDu3fvYsaMGQKfo0ePHgK/V2RlZVs9XxQHCSHk7WprLE9ZWRkuLi7sKkGRkZFwcXFpczaTjmgvljenq6sLX19f7N69G5cuXcL169fZm5KiiIuLg4+PDw4cOAAbGxvOPnV19TbjaUfU1dXB1dUVJSUlOH36dLvniuIgIYSIjsZGBdHYKCGEkM56m31BAOjSpQunbh0dHaH5PDw8cP78eaxZswZeXl4diu/NUZ+QEPIx+ugeBK2vr8fevXsRGhrKedugsLAQWlpaiI6OxtSpU5GcnIz8/Hyhx1dVVUFFRQV2dnbYvn07qqqqBPI9ffq0w21TUFDAypUrERQUxJn+uUuXLnB1dUVMTIxAMOLfbLSzs4OKigrGjBmDK1eucD7bp59+Cg8PDxQUFEBcXByPHj3CsWPHEBsbK/DGR2VlJU6ePAmg6Q2IGTNmYM+ePYiJiWHb8aqkpaWhpKTE2QghhPz3Nm/ejC5dumDixImt5rGyssLAgQMRFBQkUpmixsexY8dCRUUFoaGhAnmOHz+O4uJiTJkyRWgdmpqamDt3LpYtW8a+vNCes2fP4sqVK5g0aRJbf48ePbBp0yah+fntjI6ORp8+fVBYWMiJl2FhYdizZw/q6+tFqr8lioWEENJxH3pfDmh663zu3Lk4fPgwzp49K3BDsl+/flBXV8fp06fZtNraWqSlpcHCwgIAMHToUEhKSnLylJWV4erVq2yeEydO4Pnz58jPz+ecy4MHD+Lo0aN49OgRgKYHcKysrBAZGYmIiAiMGjVK4KHVzqA4SAgh7zYfHx9kZmYiISEBmZmZr20pQFFieWu0tbUhJycnNHYLs3//fnh7eyMmJgbjx48X2D9ixAhOrASaVlDix0pR8W/4FRcXIzk5Gd27d2/3GIqDhBDybqCxURobJYQQwvWm+oIdpaKiAmdnZ6SlpXV6WXjqExJCPlade3T+PZaQkIAnT57Ax8cHysrKnH0uLi7g8Xg4f/48EhMTMWbMGKxfvx6fffYZFBUVcfHiRXz33Xfg8XgYPHgwwsPDYWFhATMzM6xbtw6DBg1CfX09Tp8+jR07dnRqhpnZs2fjp59+wv79+zlL6QUFBeHMmTOwtbXFpk2bMHDgQJSUlGDFihWoq6vD9u3bATRNpz1w4EBOmfLy8ujevTub/uuvv6J79+6YPHkyunThPgvs6OgIHo8HR0dHAMCMGTOwbt06LFu2DO7u7pCXlxdoc01NjcBNTQkJCXaJQUIIIW/f8+fPUV5ejrq6OpSUlGDfvn3YvXs3QkJCoKen1+axgYGBmDx5MhYvXsy+cd/Q0ICCggJOPikpKRgbG4sUH+Xl5bFz5064u7tj9uzZmDt3LpSUlHDmzBksWrQILi4ubb58sHTpUuzatQslJSVwc3Pj7OPHpYaGBvz9999ISkpCSEgIHB0d4eXlBaApNu7evRuTJ0+Gs7Mz5s+fDz09Pfz77784cOAA7t69i9jYWPB4PLi4uAjEVi0tLSxZsgSJiYmYMGGCqP8MhBBCXsGH3pcDAD8/P8TExODYsWNQVFRk+1nKysqQlZWFmJgYAgICEBwcDH19fejr6yM4OBhycnKYOnUqm9fHxweBgYHo3r07VFRUsHDhQpiYmLBvvvN4PIwfPx6mpqaczzBgwAAEBARg37598Pf3B9A0ADxr1iwAELoEI/D/vzOak5OTo0FMQgh5R7U3lmdlZQU9PT14eXlBT08PlpaWr6VeUWL53LlzsWbNGlRXV8PBwQFaWlp4+vQptmzZgrq6Otja2rZbz/79++Hl5YXNmzfD3Nyc/ayysrJsvf7+/rC0tMR3332HCRMm4NixY0hOTsa5c+fYciorK3H79m3275KSEhQUFEBFRQV9+/ZFfX09XFxccOnSJSQkJKChoYGtS0VFBVJSUq98zgghhLweNDZKY6OEEELeXl+wM6KiohAeHi7Sg5UtUZ+QEPJRYz4yjo6OjIODg9B9eXl5DAAmLy+PefnyJRMSEsKYmJgwMjIyjIqKCjNy5EgmKiqKqaurY4958OAB4+fnx2hpaTFSUlJM7969GWdnZyYlJUWk9mhpaTE//fQTJy0mJoYBwFhZWXHS//nnH2bevHmMpqYmIyEhwaipqTHTp09n7ty502YdVlZWjL+/P/u3iYkJ8/XXXwvNGx8fz0hISDDl5eVs2tixYxkATFZWlkD+6dOnMwAENkNDw7Y/eDMVFRUMAKaiokLkYwghH5eP9Toxffp0ZsKECQLpKSkpDADmyZMnbFpJSQkDgMnPzxfIr6WlxV6fpaSkmL59+zKurq7M2bNnOflaK6OxsZExNDRkvvrqK4ZhGCYyMlLotV9LS4s9RtT4mJ6eztjb2zPKysqMlJQUY2xszPzwww9MfX09Jx8A5siRI5y04OBgBgAzffp0zjnjt0dCQoLp2bMnY2Njw0RERDANDQ0C5yY3N5f54osvmJ49ezLS0tKMnp4eM3v2bKa4uJi5ePEiA4DJyckROI5hGMbJyYlxcnJi/169ejVjamoqNG97PtbvOCFEdHSd+Dj6csLiKwAmMjKSzdPY2MisXr2aUVdXZ6SlpRlLS0vmypUrnHJevHjBzJ07l1FRUWFkZWUZR0dH5u7duwzDMEx5eTkjISHBHDhwQOjnmjdvHmNiYsL+XV1dzSgrKzPKyspMdXW10PMgrM1ffvlle6eQRd9vQkh76Drx+og6lsfvbwUHBwuUERkZySgrK4tUH4/HY7p3784wjOix/OzZs8ykSZMYTU1NRkpKilFTU2Ps7e2ZjIwMkeq0srIS+hmb9x0ZhmEOHjzIGBoaMpKSkoyRkRETHx/P2c/ve7dWDr8PLWwT9fcEw9D3mxDSvo/1OkFjo/+PxkYJIR87uk68urfZFxTl2Pb2//TTT5xY2xbqExJCPjQduU6IMQzDCH9ElJD/xrNnz6CsrIyKigqaMYYQIhRdJ8iHjr7jhJD20HWCfMjo+00IaQ9dJ95fGzduxL59+3D16tW33ZR3Fn2/CSHtoesE+dDRd5wQ0h66Trx/qC8oOvp+E0La05HrRJc29xJCCCGEEEIIIYQQQgghHVBdXY1Lly4hMjISNjY2b7s5hBBCCCGEEEL+Ay37gtra2ggLC3vbzSKEkI+GxNtuwLsqKysLn3/+OWxtbZGUlMTZV1tbi7CwMERHR6O4uBhycnIwNDSEr68vPD09ISkpCQDYvn07FixYgPr6ejAMAzExMXTp0gWSkpLQ0dHBtWvXWq3f3d0dFRUVOHnyJJt28uRJODg4YMWKFVi/fj2bvn79euzYsQOzZ8/G2rVr2/xcJSUliIqKYvOJi4uja9euMDY2xhdffIGvvvoK0tLSbP5Ro0YhLS1NoJwvv/wSP//8MwBATEyMTVdQUIChoSGWLVuGL774os22tOSy4zYkZRSQ6G/QoeMIIYQ0eR2xq7y8HEFBQUhMTMT9+/ehqqqKwYMHIyAgAGPGjGm3Ddra2ggICEBAQAAAgGEYLFy4EL/88guOHTuG0aNHtxpb6urqICHR9NNk9uzZ4PF4iI6Ohru7u0De27dvIygoCKdPn8Y///wDDQ0NmJubIzAwEFevXsWMGTPabGdKSgpGjRrV6v41a9bg6NGjKCgo4KQ/ffoU3bp1Y48vLS1Fv3792P1du3aFiYkJ1q9fDysrqzbbIAw/Fr7rKFYTQt4Ub29vPH36FEePHuWkp6amwtraGnv37sWcOXNQWFgIPT09dv+DBw8wYMAArFmzBv7+/tDW1sadO3cAADIyMlBTU4OZmRnmzJmD0aNHs8e1vI4rKSmhf//+GDlyJHbu3Mmm19fXo6amBvLy8tDS0hLalxM1hmZlZWHDhg3Izs7GixcvoK+vD29vbwQEBEBcXJzNJyYmBmlpady8eRNaWlps+sSJE9G1a1dERUWx52zPnj0AAAkJCaioqGDQoEGYMmUKvL290aVL++9/dqb/+eDBAwBAfHw8Nm3ahBs3bqCxsRF9+/aFvb09QkND2623pXcxDlLMI4R8rETtX165cgUMw7Bjnvw+HQBUVVVBT08PR44cwY4dOzrUv2wrNvXo0QMvXrxg0+vq6tj+ZF1dXZvlvg9jo68LxTBCyMemed+oOWtra1y+fBkBAQFYsWKFwP6QkBCEhobiwYMHiImJQUBAAJ4+fSpSnS9evMDGjRsRGxuL0tJSKCoqYtSoUVi7di0GDBjA5luzZg3Wrl3LiR8AUFBQgCFDhqCkpATa2toCfVQFBQX07dsXo0aNQkBAAPT19UVq1+HDh7Fjxw4UFBSgpqaG7S/b2dlx8sXHx2PlypX4448/oKuri6CgIPzvf/9j96enp+P7779HXl4eysrKcOTIEUycOFGgrp07dyIvLw+PHj1Cfn4+Bg8eLFI7W3rX+oQUSwkhHzsnJye8ePECycnJAvt0dHRQUlICWVlZgfHHqqoqTJ48GatWrRIY530dBgwYwI79trRz5054eHh0qLzCwkJs3LgR586dw7///gttbW3MmTMH/v7+r6O5InPZcRunlnzyn9ZJCPnw0IygrYiIiMC8efNw7tw53L17l02vra2FnZ0dNm7ciNmzZyMrKws5OTnw8/PD1q1b2RuCpaWl2LBhA7S0tLB582acOnUKiYmJWLx4MXr16oUTJ060Wb+1tTXOnTuH+vp6Ni01NRWamppISUnh5OXfFF24cCHKysrYrU+fPli3bh0nTVNTE0BTcCwrK8Pdu3eRkpKCyZMnIyQkBBYWFnj+/Dmn/FmzZnHKKCsrw6ZNmzh5IiMjUVZWhtzcXJiammLy5MnIzs7u+IknhBDSaa8jdg0dOhRnz57Fpk2bcOXKFSQlJcHa2hp+fn4dbk9DQwN8fHywd+9enD17lvPgjbDYwr9hWF1djbi4OCxatAg8Hk+g3IsXL2Lo0KG4desWdu7cievXr+PIkSMwMjJCYGAg3NzcOOWOGDFCoD4LC4sOf562JCcno6ysDGlpaVBSUoKDgwNKSkpeax2EEEKaBh/t7Owwffp0NDY2sumzZ8/GkCFDMH/+fDaN3xe6efMm9u7di65du8LGxgZBQUEC5fKv4xcuXICZmRm2bNmCAwcOoKCgAAUFBVi7di0UFBRQUFAgtC8nagw9cuQIrKys0KdPH6SkpODGjRvw9/dHUFAQ3N3dwTAMp1wxMTGsWrWq3fNib2+PsrIylJaW4uTJk7C2toa/vz8cHR05fcrWdKb/yT9v7u7ucHFxQU5ODvLy8hAUFITa2tp26ySEEPJuE7V/mZCQgDNnzuD777+Hrq4uYmJiUFBQgISEBKirq0NKSgqhoaEd7l+2FZu0tLTYGF1QUIBPPvkEjo6OyM3NRXFxMY2NEkLIR4zfN2q+xcfHw9PTE1FRUQJ9LqDpGj5t2jRISUl1qK6amhrY2NggIiIC69evx61bt3DixAk0NDRg+PDhOH/+PCe/jIwMeDwebt261W7Z/D5qYWEhgoODUVRUBFNTU5w5c0aktqWnp8PW1hYnTpxAXl4erK2t4eTkhPz8fDZPdnY23NzcMG3aNBQWFmLatGlwdXXFhQsX2DxVVVUwNTXFtm3bWq2rqqoKI0eOxMaNG0VqGyGEkPeHj48Pzp49K/ShSzMzM/Tv3x+XL1/m9M8KCgrw7NkzHDhwACoqKm+kXSdOnBCok785Ozt3uLy8vDz07NkT+/btw7Vr17B8+XIsXbq0zfgnivZeVCSEkDeBZgQVoqqqCgcOHEBubi7Ky8sRFRXF3nwLCwtDeno6Ll68iCFDhrDH6OjoYPLkyewNr6+//hri4uIoKCiAvLw8m2/cuHFYvHgxunbt2mYbrK2tUVlZiYsXL8Lc3BxA02Dnt99+iwULFqC6uhpycnKora1FdnY2tmzZAgUFBSgo/P+bcuLi4lBUVIS6urpA+RISEmy6hoYGTExMYGtrC1NTU3z33XfYsGEDm1dOTk5oGc117doV6urqUFdXx88//4zY2FgcP34cI0aMaPM4Qgghr8fril1iYmLIycnhxK4BAwZg5syZHWpPTU0NpkyZgtzcXKSnp6N///6c/W3FloMHD8LY2BhLly5Fr169UFpaCm1tbQBNM4x6e3tDX18fGRkZnLcMBw8eDH9/f8jKykJWVpZNl5KSEimWvYru3buzcXDnzp3o06cPTp06hS+//PKN1UkIIR+rnTt3YuDAgfjxxx+xcOFCREVFISMjA5cvX+bMyNW8L9S3b19YWlqiV69eWLVqFVxcXGBoaMjmbX4dDwoKwtatW/HHH3/AwcEBAKCmpgZxcXHOLKTNiRJDq6qqMGvWLDg7O+OXX35h8/j6+kJNTQ3Ozs44cOAA3Nzc2H3z5s1DaGgoFi5cCBMTk1bPibS0NPtZe/fujU8++QTm5uYYM2YMoqKi4Ovr2+Y57Uz/EwASEhLw2WefYdGiRWxZBgYGAjPEEEIIeb90pn85evRozJs3D7W1tZCXl8f8+fMhLi7e6f5le7FJQ0ODjU2FhYXYsmULTE1NOWXQ2CghhHx8mveNmvPx8cHmzZuRnp7OWcUnIyMDxcXF8PHx6XBdYWFhyM7ORn5+PhuDtLS0EB8fj+HDh8PHxwdXr15l+6mGhoZQVVXFihUrcODAgTbL5vdRgaYxXCcnJ4wZMwY+Pj74448/OKtJtNa25oKDg3Hs2DH89ttvbPwOCwuDra0tli5dCgBYunQp0tLSEBYWhv379wNouqc5bty4NuuaNm0agKYXJAkhhHxYHB0doaqqiqioKKxevZpNr66uxokTJxAcHIzCwkKsWrUKt2/fRq9evTBv3jwEBgYKLY8/83Xz2aNbrsTHfwk9KSkJ3377LW7cuIERI0YgNjYWeXl5+Oabb3D//n2MHz8ePB4PcnJyAJruH37//ff4+eefUVZWBgMDA6xcuRIuLi7tfs6WfVQdHR1kZ2fj8OHDmDt3LqqqqtCrVy9ERERwyvvtt9/g7u6O8vJyPHr0CP369UNcXBzCw8Nx/vx57Nixo90VDAkh5HWjGUGFiIuLg6GhIQwNDeHp6YnIyEj2LcHo6GjY2NhwBjr5JCUlIS8vj8ePHyMpKQl+fn6cgU6+9h4CBZpunmloaLCzrzx//hyXLl3C5MmToauri8zMTADA+fPn8eLFC3ZGlldhZGSEcePG4fDhw69UDn8ZqNbecKipqcGzZ884GyGEkFfzLsQuvsrKSowfPx7Xrl1DZmamwEOg7eHxePD09ISysjIcHBwQGRnJ7isoKMC1a9cQGBgodKnbjrTzTeF3Ott6049iISGEdF7Pnj2xc+dOrFy5EqdPn8aCBQuwefNmzvLprfH39wfDMDh27JjQ/XV1ddi1axeAphgpClFj6KlTp/Do0SMsXLhQII+TkxMMDAzYm218FhYWcHR0ZG/MdcTo0aNhamoqUv+us/1PdXV1XLt2DVevXu1Q2ygOEkLIu+1d6F/S2CghhJDXycTEBMOGDeOMMwJNM2CbmZlh4MCBHS4zJiaGfYmguS5dumDBggW4fv06CgsLOfs2btyI+Ph45ObmdqiuLl26wN/fH3fu3EFeXl6H29rY2Ijnz59zZmbLzs7G2LFjOfns7OyQlZXV4fI7imIhIYS8HyQkJODl5SUwq/bBgwdRW1uLESNGwNXVFe7u7rhy5QrWrFmDlStXIioq6pXrXrNmDbZt24asrCzcu3cPrq6uCAsLQ0xMDBITE3H69Gls3bqVzb9ixQpERkZix44duHbtGhYsWABPT0+kpaV1qv6Kigo2bsrLy8Pd3V3gd0RkZCRcXFygqKjIpi1ZsgTz589HUVER7OzshJZNcZAQ8ibRg6BC8B9AAZqWkaisrGSXWyguLoaRkVGbx9++fRsMw7Sbrz38Nx6AprcSDQwM0LNnT1hZWbHp/CWRdHV1X6kuPiMjI4G39sLDw9nZRvnbnj17hB5fU1ODDRs24NmzZxgzZozQPCEhIVBWVmY3/pJMhBBCOu9diV0AsH79ehQUFCAjIwN9+/YVmqdlbOG/HVhcXIzz58+zs6Hxbzryl/8tLi4GgNfSzjehqqoKS5cuhbi4OGd2gZYoFhJCSOsSEhIE+h8tZyCZOHEiXF1dYW9vD0tLS3h7e4tUtoqKClRVVQX6PBYWFlBQUICMjAwCAwOhra0NV1dXkcoUNYbyl/9r7QUJIyMjoUsEhoSEICkpCRkZGSK1p2WZos7K0pn+57x58zBs2DCYmJhAW1sb7u7uiIiIQE1NTZt1URwkhJB327vSv6SxUUIIIR0lrD+5fv16AE2zfR06dAiVlZUAml5mP3jwYKdmAwWa+nit9e/46S37eJ988glcXV3x7bffdrg+flztzMyboaGhqKqq4vRzy8vLoaamxsmnpqaG8vLyDpffURQLCSHk/TFz5kyUlpayfTCg6UWKL774Aj/++CPGjBmDlStXwsDAAN7e3pg7dy6+//77V653w4YNGDlyJIYMGQIfHx+kpaVhx44dGDJkCD7//HO4uLiwLw5WVVXhxx9/REREBOzs7KCjowNvb294enpi586dHa47OzsbBw4c4Kz65+vri99//x0PHjwAAPz7779ISEgQmE00ICAAX3zxBfr16wcNDQ2h5VMcJIS8SfQgaAs3b95ETk4O3N3dATS95eDm5oaIiAgATVNKN19uUBj+2xDt5WuPtbU1MjMzUVdXh9TUVIwaNQoABAY7R48e/Ur1NCfs83l4eKCgoICz/e9//+PkmTJlChQUFCAnJ4cff/wRP/zwQ6vLRSxduhQVFRXsdu/evdfWfkII+Ri9S7ELAMaOHYuqqioEBwe3mqdlbOHPdMbj8WBnZ4cePXoAABwcHFBVVYXk5OTX3s7Xif8AkaKiIn777TdERUW1uYQvxUJCCGmdtbW1QP9j9+7dAvlWrlyJxsZGrFy5skPlC4uLcXFxyM/Px/Hjx6Gnp4fdu3dzZkpprzxA9NjU/O359toFAMbGxvDy8sKSJUtEKl+UMoXpTP9TXl4eiYmJuH37NlasWMG+3GFmZobq6upW66I4SAgh7653qX9JY6OEEEI6Slh/0s/PD0DTtbqxsRFxcXEAmvqBDMOwMe91aisWbtiwARkZGTh16tRrK7Mt+/fvx5o1axAXFwdVVVXOvpZldaQP+SooFhJCyPvDyMgIFhYWbJ/wjz/+QEZGBmbOnImioiKMHDmSk3/kyJEoLi5GQ0PDK9U7aNAg9v/V1NQgJycHHR0dTtrDhw8BANevX8fLly9ha2vLeRlk7969+OOPPzpU77Vr1zBhwgSsWrUKtra2bLqZmRkGDBiAvXv3AgB+/fVX9O3bF5aWlpzjP/3003broDhICHmTJN52A941PB4P9fX16N27N5vGMAwkJSXx5MkTGBgYoKioqM0y9PX1ISYmhqKiIkycOLHTbbG2tkZVVRVyc3ORkpKCRYsWAWga7PTy8sLjx4+RnZ2N6dOnd7qOloqKitCvXz9OmrKyMvT09No87qeffoKNjQ2UlJQEOpItSUtLQ1pa+pXbSgghpMm7FLsAYMyYMZg/fz4mTJiAhoYGztIMfMJiS0NDA/bu3Yvy8nJISEhw0nk8HsaOHQsDAwMATfFq8ODBr9TOtigpKaGiokIg/enTp2z7m4uLi4OxsTG6du2K7t27t1s+xUJCCGmdvLy8QIz466+/BPLxY0XzmNGeR48e4Z9//hHo82hqakJfXx/6+vpQUFDApEmTcP369Xb7NoDoMbR5DLOwsBDYf+PGDRgbGws9du3atTAwMMDRo0fbbU9zwvp3rXmV/qeuri50dXXh6+uL5cuXw8DAAHFxcZgxY4bQuigOEkLIu+td6l/S2CghhJCOEtaf5FNWVoaLiwsiIyPh4+PDLueqpKTUqboMDAxw/fp1oftu3LgBoCkmtqSrq4tZs2bh22+/BY/HE7k+fvwVtY8HNI1Z+vj44ODBg7CxseHsU1dXF5j98+HDhwKzhL4JFAsJIeT94uPjg7lz52L79u2IjIyElpYWxowZI/QFgtZeggeALl26COSpq6sTmldSUpL9fzExMc7f/DT+aoL8/yYmJnL6sgA6FG+uX7+O0aNHY9asWVixYoXAfl9fX2zbtg3ffvstIiMjMWPGDIHPLy8v3249FAcJIW8SzQjaTH19Pfbu3YvQ0FDO24KFhYXQ0tJCdHQ0pk6diuTkZOTn5ws9vqqqCioqKrCzs8P27dtRVVUlkI//EEl7dHV1oampiePHj6OgoIBdYrZXr17Q1tZGaGgoXr58CWtr61f63Hw3btxAUlISJk2a1OFj1dXVoaenJ9KNUkIIIa/Puxa7+GxtbZGQkICIiAj4+fm12fHjO3HiBJ4/f478/HzOZzl48CCOHj2KR48eYfDgwTA2NkZoaCjbsXuVdrbGyMgIf/31l8BgaG5uLrp06SIwoMxfilCUh0AJIYS8PZs3b0aXLl3afCjFysoKAwcORFBQkEhlihpDx44dCxUVFYSGhgrkOX78OIqLizFlyhShdWhqamLu3LlYtmyZyG/Tnz17FleuXBG5f/e6+p/a2tqQk5MTei7I/7F353FVVP//wF9X9k0UURFFEFkU9ywVMYFcMPdvbrhjuBUpFi6Vpn5cyzRNU1tkUcMdNVNTQ8ENTVRQU1RM0EzIcgEBZT2/P/jdieFe4KIgXHg9H4951D1z5sw5c6/z5pw5M0NEVLlVtv4lx0aJiKis+fr64vTp09i/fz9Onz79wq+FBwBvb2+Eh4fj0qVLsvS8vDysXLkSLi4uaNOmjdpt586di5s3b2Lbtm0a7SsvLw+rV69GkyZN0K5dO4222bp1K3x8fLBlyxb06dNHZb2rqyt+/fVXWdqRI0fU3rhIRETV29ChQ6Gjo4MtW7Zg48aN0gRIFxcXnDp1SpY3KioKTk5O0NHRUSmnbt26AICkpCQpLTY29qXr5+LiAgMDA9y9excODg6yRdPXrl+9ehWenp4YO3ZskePCo0aNwt27d7F69WpcvXq1TG9KJCIqK3wiaAH79+/H48eP4evrq/Kkr8GDByMwMBBnz57FgQMH0K1bNyxcuBBdunSBmZkZzp8/jy+++AKBgYFo27Yt1q1bh86dO6NDhw5YsGABWrdujZycHPz6669Yv359iXfOK3l6emLdunVwcHCQ3YXn7u6ONWvWwN7eHo0bNy51W3NycpCcnIy8vDw8fPgQkZGRWLRoEdq2bSvdXa+UkZGhMhHGwMAAtWvXLvV+iYiobFXG2KX01ltv4cCBA+jbty+EEFi7dm2xrxYKDAxEnz59VAZIW7RogWnTpuHHH3+Ev78/goOD0b17d3Tt2hWffvopmjVrhrS0NPz88884cuQIjh8/Xqp6qtOzZ080b94c3t7eWLx4MaytrXH58mVMnz4dkydPhpmZ2Uvvg4iIytfTp0+RnJyM7OxsJCQk4Mcff8SGDRuwdOnSEp/qFRAQgCFDhmDmzJnSXeS5ubkqA5P6+vpwcXHRKIaamJjgu+++g7e3NyZOnIgPPvgANWvWxNGjRzFjxgwMHjwYQ4cOLbJOn3zyCX744QckJCRg2LBhsnWZmZlITk5Gbm4u/v77bxw6dAhLly5F3759MWbMGI2PWWn7n/Pnz0dGRgZ69+4NW1tbPHnyBKtXr0Z2drbs1UlERKQdKmP/kmOjRERUGsq+UUG6urqwtLQEkB8/HBwcMGbMGDg4OKi8zrU0PvzwQ/z000/o168fVqxYgY4dO+Lvv//GkiVLEBcXh/Dw8CLHQuvXr4+PPvoIX375pdr1Dx8+RHJyMjIyMvD7779j1apVOHfuHA4cOKB2Yk1hW7duxZgxY/D111+jU6dO0jExMjKSYry/vz+6du2KL774AgMGDMBPP/2E8PBw2YSetLQ03Lp1S/qckJCA2NhYWFhYSPH30aNHuHv3Lu7fvw8AuHHjBoD8mySsrKxKrCsREVV+pqamGDZsGD799FOkpKTAx8cHQP4Y6htvvIGFCxdi2LBhOHPmDL755husW7dObTlGRkbo1KkTPv/8c9jZ2eHff/9V++TN0jIzM8P06dPx4YcfIi8vD126dEFqaiqioqJgampa4oRN5STQnj174qOPPpLipo6OjjR5FQBq166Nd955BzNmzEDPnj3RqFGjl647EVGZEyTp27ev6N27t9p1Fy5cEADEhQsXxPPnz8XSpUtFq1athKGhobCwsBBubm4iJCREZGdnS9vcv39f+Pn5CVtbW6Gvry8aNmwo+vfvLyIiIjSuU3BwsAAgJk+eLEvfvHmzACB8fX2L3NbW1lasXLlSJX3evHkCgAAgdHR0hIWFhejSpYtYuXKleP78uSyvu7u7lLfg4uXlJeUBIPbs2aNxmwpLSUkRAERKSsoLl0FEVRvPE0WrbLFLXew5fvy4MDU1FZMmTRJ5eXnC3d1d+Pv7y/IkJycLXV1dsWPHDrXlTpkyRbRq1Ur6fOPGDTFmzBhhbW0t9PX1ha2trRg+fLi4ePGiyrbq9qeJpKQkMW7cOGFrayuMjIxEs2bNxIIFC2SxMiEhQQAQMTExpS6/IP7Giagk1eU8MXbsWDFgwACV9IiICAFAPH78WEor7hxsa2sr9V309fVF48aNxdChQ8WxY8dk+YoqIy8vTzg7O4v33ntPCPFfv6zwYmtrK22jaQw9ceKE6NWrlzA3Nxf6+vrCxcVFLF++XOTk5MjyqetnLVmyRAAQY8eOlR0zZX10dXVF3bp1Rffu3UVQUJDIzc1VOTbFKW3/89ixY2LQoEHCxsZG6Ovri/r164tevXqJkydPlmq/1eX3TUQvjueJV6Oy9S+F4NgoEZEQPE9oqmDfqODi7Owsy6fsVy1ZskSljODgYGFubq7xPtPT08WcOXOEg4OD0NPTExYWFmLQoEHiypUrsnzz5s0Tbdq0kaWlpqYKS0tLAUAkJCQIIf7royoXY2Nj0bx5c/H++++L+Ph4jetVVPwq2JcUQoidO3cKZ2dnoaenJ5o1aybCwsJk65V98eLKKaq/PG/ePI3ry984EZWE54mKFxUVJQCInj17ytJ37dolXFxchJ6enmjcuLH48ssvZesL98uuXbsmOnXqJIyMjETbtm3FkSNHBACpn6huHFhdfC4cW/Py8sTXX38txbW6desKLy8vcfz48RLbVrCPWNTYr9LRo0cFAJXrmS9zvZC/byIqSWnOEwohNHhXK1E5Sk1Nhbm5OVJSUlCzZs2Krg4RVUI8T1BVx984EZWE5wmqTBQKBfbs2YOBAweWSXn8fRNRSXieoKqMv28iKgnPE1TV8TdORCXheYIqi9DQUIwaNQo7duzAkCFDyqRM/r6JqCSlOU9Uy1fDR0VF4c0330SPHj1w6NAh2bqsrCysWrUKoaGhiI+Ph7GxMZydnTF+/HiMGjUKenp6AIDk5GQsXrwYBw4cwF9//YV69eqhbdu2mDZtGrp166ZxXZYsWYLPPvsMixcvxscffyylN2jQANOmTcOsWbOktFmzZmHZsmUIDw+X7aNbt26oX78+tmzZUqo2FHUs/v77bzRq1AjBwcEYNWqUSp0nTZqEM2fO4PLly5g/fz7+97//qeRxdnbG9evXNT4OADB4/S0cmfVaqbYhIqrqfHx8sHHjRgD5rzGysbHBO++8g//973/4559/0KRJEylvzZo10bx5c8yePRv9+vWT0kNCQjBu3DiVsg0MDPD8+XPpsyaxzc7ODtOmTcO0adOkz3fu3AGQ/0oHe3t7TJkyBZMmTZLKDQ0NxbJlyxAfHw9zc3P06tULy5cvR506dQDkv3Jh7ty5uHDhAu7cuYOVK1dK5SudOHECX375JS5cuICkpCS1k0+EEPjf//6H77//Ho8fP0bHjh2xdu1atGjRosTj7O3tjZSUFPzyyy9S2i+//ILevXtjzpw5WLhwoZS+cOFCrF+/XnrdUVhYGJYtW4br168jLy8PjRs3Rq9evbBixYoS91vY4PW3oGdoWurtXoUD/k4VXQUiolfqwYMH+Oyzz/DLL7/g77//Ru3atdGmTRvMnz8frq6uZT4Zsrzk5uZi9erVCA4Oxs2bN2FoaAhXV1fMmTMHbm5uFV09mcoSBxnziKiq49ho5R0bLSkOMkYREVVNlSU2R0VFYdGiRThz5gyePXsGR0dH+Pj4YNq0abJX0itfeX/mzBl06tRJSs/MzIS1tTUePXqEiIgIeHh4lOo4VFSfkPGViEgVx0blMjIykJCQgKVLlwKArF9ZVjhfhojKQo2KrkBFCAoKwpQpU3Dq1CncvXtXSs/KyoKXlxc+//xzTJw4EVFRUTh37hz8/PywZs0aXL16FQCQmJiI9u3b49ixY1i2bBmuXLmCQ4cOwdPTE35+fhrVITQ0FKamppgzZw50dHTw6aefwtTUFKampmjRogU8PDwQEREh2yYyMhI2Njay9KysLJw5cwaenp6lakNxx6J+/fro06cPgoODVer97NkzbNu2Db6+vlJaixYtkJSUJFtOnTql0XEgIqKS9erVC0lJSbh9+zYWLVqEdevWYfr06dL68PBwJCUl4bfffkOHDh0waNAg/P7777IyatasqXKuVk7gBDSLbaGhobh79y5mzZolxay7d+9CX18fTk5OuHz5MgYOHIjJkydj+/btAIBTp05hzJgx8PX1xdWrV7Fz505ER0dj/Pjx0r4zMjJgb2+Pzz//HFZWVmqPQXp6Otq0aYNvvvmmyOO0bNkyfPXVV/jmm28QHR0NKysr9OjRA0+fPlXJ26JFC6kNpqam2Lt3Lw4dOgRTU1OEhoYCUB93lenKuBseHg5vb28MHjwY586dw4ULF7B48WJkZWUVWU8iItIOgwYNwqVLl7Bx40bcvHkT+/btg4eHBx49eqRxGdnZ2eVYw5IJIeDt7Y05c+bg5s2b0NHRQVZWFsLDw9GlSxcYGRkVecNERdediIjKD8dGiz8WHBslIiJAdfyw4KIcPywrpY3Nd+7cwfjx42Fubg5TU1OYmJjA2toaa9euRb9+/V4oNu/Zswfu7u5o1KgRIiIicP36dfj7+2Px4sXw9vZG4RdM2tjYqMTKPXv2wNS04m/uIyKil1eVxkY//vjjIsdGJ0+erHbbwnVftmwZ2rZti/r167+KqhMRvbBq90TQ9PR07NixA9HR0UhOTkZISAjmzp0LAFi1ahVOnDiB8+fPo127dtI29vb2GDJkiDSp4/3334dCocC5c+dgYmIi5WvRogXeffddjerRv39/AEBAQIB0V9zKlSvRoUMH6Onp4fDhwwgICEBOTg50dXXx9OlTxMTEYNWqVdLd7QDw22+/4dmzZ9Jgp6ZtKOlY+Pr6YsCAAUhMTISdnZ20za5du/D8+XPZ3fC6urpFTtwhIqKXZ2BgIJ1nR4wYgYiICOzdu1d6MkqdOnVgZWUFKysrLF68GGvWrEFERARatmwplaFQKIo9V2sS2/r3748GDRrAx8dHesKou7s7fHx8MHHiRNja2mLRokXYsWMH9u7di2HDhuHs2bOws7PD1KlTAQBNmjTBpEmTsGzZMmkfb7zxBt544w0AkD0BpqC3334bb7/9dpH1F0Jg1apVmD17Nt555x0AwMaNG6WnwhR8QikAHDx4UNaJS0hIQM+ePREcHIxevXoByL/I+PHHH+PDDz9ERkYGjI2NpYuMq1evBgDs378fXbp0wYwZM6SynJycKv0dkEREVLwnT57g1KlTiIyMhLu7OwDA1tYWHTp0AACpj/R///d/0rrExETMnz8fe/fuxdSpU7Fo0SIkJiYiNzcXqampmDFjBvbu3Yvnz5/j9ddfx8qVK9GmTRsAwB9//IGPPvoIZ8+eRXp6Opo3b46lS5eie/fuUp3s7Owwfvx43Lx5E7t370adOnWwevVqdO7cGePHj8fRo0fRpEkTBAcH4/XXXwcA7NixA7t27cK2bdvQvn17WRv9/Pxw7tw57Nq1CwCKrPutW7fg6+uLc+fOwd7eHl9//bXK8frrr7/w0Ucf4ciRI6hRowa6dOmCr7/+WtaXJCKiyoFjoxwbJSIizRQePyyoLCeBvEhsPn36NDIyMpCdnQ1jY2P4+vrixo0bOHLkCJo0aQIzMzMAmsfm9PR0TJgwAf3798f3338vpY8fPx7169dH//79sWPHDgwbNkxaN3bsWKxevRqrVq2CkZERgPwJrWPHjpW9XYmIiLRPVRsb3bRpE1xdXWVtVI6NKq+1ajI26ujoiI8//hjHjh2TlcWxUSKqTKrdE0G3b98OZ2dnODs7Y9SoUQgODpbuYgsNDUX37t1lnSklPT09mJiY4NGjRzh06BD8/PxkA51KtWrV0qgeZmZmOHz4MEaPHo3mzZtj9OjROHz4MBwcHGBrawtPT0+kpaUhOjoaAHDy5Ek4OTlh8ODBiI6ORkZGBgAgIiICjRo1goODg8Zt0ORY9O7dG1ZWVggJCZGVERQUhIEDB0qv8yUiolfPyMhI7SBkdnY2fvjhBwCleyWBprHNzMwMenp6qFu3LhwcHODg4CB9trW1lfIbGhpK9evcuTPu3buHgwcPQgiBv//+G7t27UKfPn1K0+QSJSQkIDk5GT179pTSDAwM4O7ujqioKJX8tra2UhscHBzQo0cPWFtb49atWzAzM8PTp09x8eJFDBkyBE2bNsXp06cBAGfPnpVdZLSyssLVq1dVnsBKRETareATozMzM1XWK/tpwcHBSEpKkj4DwK1bt7Bjxw6EhYUhNjYWANCnTx8kJyfj4MGDuHDhAl577TV069ZNuoM+LS0NvXv3Rnh4OGJiYuDl5YV+/frJngQDACtXroSbmxtiYmLQp08fjB49GmPGjMGoUaNw8eJFODg4YMyYMVK/bsuWLXBycsKwYcNkcc/BwQHz5s3DkydPcOPGjSLrnpeXh3feeQc6Ojo4e/Ysvv32W9kreoH8J3t7enrC1NQUJ06cwKlTp2BqaopevXrxCdlERJUQx0Y5NkpERJopPH5YcFFOtCwLLxKbbW1t0bx5c7Ru3RoWFhY4efIk/P390bp1a5W6aRKbjxw5gocPH8reQqXUr18/ODk5YevWrbL09u3bo0mTJggLCwMA/Pnnnzhx4gRGjx5dmuYTEVElVNXGRkePHl3k2OilS5eKrDvHRolIG1W7iaCBgYHSHdu9evVCWloajh49CgCIj49Hs2bNit3+1q1bEEKUmK8kqampCAsLk+oyatQo7Nq1C6mpqQAAR0dHNGzYEJGRkQAg3W1Rr1492NvbSxNSCr6eVtM2KBV3LHR0dDBmzBiEhIRIgTIhIQHHjx+XvfoIAK5cuaLyWoyCr/wtLDMzE6mpqbKFiIg0c+7cOWzZsgXdunWT0jp37gxTU1MYGhoiICAAdnZ2GDp0qGy7lJQUlXO1ctJkWcW2nJwchISE4MqVK1L9OnfujNDQUAwbNgz6+vqwsrJCrVq1sGbNmpfaV2HJyckAVO/Gr1+/vrSuJB4eHlLcVV5krFu3Ltzd3WXx2MbGBk2bNgUATJkyBW+88QZatWoFOzs7eHt7IygoSG3HuCDGQiKiyk1XVxchISHYuHEjatWqBTc3N3z66ae4fPkyAKBu3boA8i+oWVlZSZ+B/Ff3bd68Ge3atUPr1q0RERGBK1euYOfOnXj99dfh6OiI5cuXo1atWtLTONu0aYNJkyahVatWcHR0xKJFi2Bvb499+/bJ6tW7d29MmjQJjo6OmDt3Lp4+fYo33ngDQ4YMgZOTE2bNmoW4uDj8/fffAICbN2+iefPmatuoTL9582aRdT969Cji4uKwefNmtG3bFl27dsWSJUtk5Wzbtg01atTAhg0b0KpVKzRv3hzBwcG4e/euFD8LYxwkIqo4HBv9D8dGiYioMqgMsVnZLyyq/9isWTNZ31Fp3LhxCAoKApA/Gah3796y/nFRGAuJiCo3jo1ybJSItFe1mgh648YNnDt3Dt7e3gDyA9iwYcOkTooQAgqFotgylAN/JeUryZYtW2Bvby897rpt27awt7fHtm3bpDwFJ6RERkbCw8MDAKQJKZmZmTh79izeeustWf00qVtJxwLIfwXSnTt3pEdbBwUFoVGjRrJHcAOAs7MzYmNjZcvixYuL3PfSpUthbm4uLTY2NiXWl4ioOtu/f7800dPV1RVdu3aVTaTcvn07YmJisG/fPjg4OGDDhg2wsLCQlWFmZqZyrg4ODgbw8rFt1qxZMDU1hZGREfz8/DBjxgzpVezXrl3D1KlTMXfuXFy4cAGHDh1CQkICJk+e/EL7KknhNmgaFwHA09MTp0+fRnZ2ttq4C+TH44Jx18TEBAcOHMCtW7cwZ84cmJqaIiAgAB06dJCeUKMOYyERUeU3aNAg3L9/H/v27YOXlxciIyPx2muvqTwZrDBbW1vZ4OeFCxeQlpaGOnXqyCaIJCQk4I8//gCQ/xq+mTNnwsXFBbVq1YKpqSmuX7+uctd769atpf9X3vzQqlUrlbQHDx5o3M6CcbJw3ePi4tC4cWM0atRISiv8GqULFy5IT9RWts3CwgLPnz+X2lcY4yARUcXg2Oh/ODZKRESVQWWKzQXLUpeurvxRo0bhzJkzuH37NkJCQjR6DT3AWEhEpA04NsqxUSLSTroVXYFXKTAwEDk5OWjYsKGUJoSAnp4eHj9+DCcnJ8TFxRVbhqOjIxQKBeLi4jBw4MAXrktQUBCuXr0KXd3/voK8vDwEBgZi4sSJAPInpPj7++Phw4eIiYlB165dAeQPdq5ZswY9e/aUvZ4WgEZtAEo+FrVr14ajoyPefPNNBAcHw9PTExs3bsS4ceNQo4Z8/rC+vr70+iVNfPLJJ/joo4+kz6mpqQxuRETF8PT0xPr166Gnpwdra2vpte+JiYkAABsbGzg6OsLR0RGmpqYYNGgQrl27hnr16kll1KhRo8hz9cvGthkzZsDHxwfGxsZo0KCBrNO0dOlSuLm5YcaMGQDyO2kmJiZ48803sWjRIjRo0KDU+1PHysoKQP6TQQuW+eDBA5WnhBbF09MT6enpiI6ORkREhFRnd3d3jBkzBo8ePcKZM2cwduxYlW2bNm2Kpk2bYvz48Zg9ezacnJywfft2jBs3Tu2+GAuJiLSDoaEhevTogR49emDu3LkYP3485s2bBx8fnyK3Kfya3Ly8PDRo0EDtHeDKV/TNmDEDhw8fxvLly+Hg4AAjIyMMHjxY5fVByr8BgP8GKdWl5eXlAcjvH167dk1tPZX9RkdHxyLrru4iYOGLf3l5eWjfvj1CQ0NV8hb1JBjGQSKiisGx0f9wbJSIiCqDyhKbnZycAOT3Ezt37qyy/vr163BxcVFJr1OnDvr27QtfX188f/4cb7/9Np4+fVri/hgLiYi0A8dGOTZKRNqn2jwRNCcnB5s2bcKKFStkd2dfunQJtra2CA0NxYgRIxAeHo6YmBi126enp8PCwgJeXl5Yu3Yt0tPTVfI9efKkxLpcuXIF58+fR2RkpKwuJ06cQHR0NH7//XcA/01I+eqrr+Do6ChNZHF3d8f58+dx4MABNGnSBLa2tlLZmrRBk2Oh5Ovri927dyMsLAz37t0rckJLaRgYGKBmzZqyhYiIimZiYgIHBwfY2trKOjTquLu7o2XLlsU+faSwl41tlpaWcHBwgLW1tUoHKCMjQ+UimY6ODoCi7zB/EU2aNIGVlRV+/fVXKS0rKwvHjx9XO3ipTtOmTWFjY4N9+/YhNjYW7u7uAIAGDRrAzs4OK1aswPPnz2UXGdWxs7ODsbGx2mOpxFhIRKSdXFxcpPO7np4ecnNzS9zmtddeQ3JyMnR1deHg4CBbLC0tAQAnT56Ej48P/u///g+tWrWClZWVdMPHy/D29kZ8fDx+/vlnlXUrVqxAnTp10KNHjyK3d3Fxwd27d3H//n0p7cyZMyrti4+PR7169VTaZ25urrZcxkEiolePY6McGyUiosqlMsXmnj17wsLCAitWrFBZt2/fPsTHx2P48OFqt3333XcRGRmJMWPGSOO+JWEsJCLSThwb5dgoEVV+1WYi6P79+/H48WP4+vqiZcuWsmXw4MEIDAzEtGnT4Obmhm7dumHt2rW4dOkSbt++jR07dqBjx46Ij48HAKxbtw65ubno0KEDwsLCEB8fj7i4OKxevVrlUdDqBAYGokOHDujatausHl26dIGrqysCAwMBAPb29mjcuDHWrFkjTUYBAGtra9ja2uLbb79VmYyiSRs0ORZKQ4YMgZ6eHiZNmoRu3brBzs5OpT05OTlITk6WLX///feLfE1ERFQGAgIC8N133+Gvv/6S0oQQKufq5ORk6a64l41tRenXrx92796N9evX4/bt2zh9+jSmTp2KDh06wNraGkD+hE3lQGdWVhb++usvxMbG4tatW1I5aWlpUh4ASEhIQGxsrPRaCIVCgWnTpmHJkiXYs2cPfv/9d+kppSNGjNC4vp6enli3bh0cHBxkTxJVPnFGGZuV5s+fj5kzZyIyMhIJCQmIiYnBu+++i+zs7GI7j0REVLk9fPgQb731Fn788UdcvnwZCQkJ2LlzJ5YtW4YBAwYAyJ/4f/ToUSQnJ+Px48dFltW9e3e4urpi4MCBOHz4MBITExEVFYU5c+bg/PnzAAAHBwfs3r1buug3YsQIKUa/DG9vb/zf//0fxo4di8DAQCQmJuLy5cuYNGkS9u3bhw0bNqjc6V647s7OzhgzZgwuXbqEkydPYvbs2bI8I0eOhKWlJQYMGICTJ08iISEBx48fh7+/P+7du/fSbSAiorLBsVGOjRIRUeVSmWKziYkJvvvuO/z000+YOHEiLl++jMTERAQGBsLHxweDBw/G0KFD1W7bq1cv/PPPP1iwYEGZHh8iIqo4HBv9r+4cGyUirSOqib59+4revXurXXfhwgUBQFy4cEE8f/5cLF26VLRq1UoYGhoKCwsL4ebmJkJCQkR2dra0zf3794Wfn5+wtbUV+vr6omHDhqJ///4iIiKi2HpkZmaKOnXqiGXLlqldv2LFCmFpaSkyMzOFEEKMHTtWABDbtm2T5fP19RUAxObNm1XKKKkNmh4LpYkTJwoAYsuWLSr5582bJwCoLAYGBsUeh4JSUlIEAJGSkqLxNkRUvVTn88TYsWPFgAED1K5LSEgQAERMTIwsPS8vTzg7O4v33ntPCCFEcHCw2nM1AJGUlCRtp0lss7W1FStXrizyszqrV68WLi4uwsjISDRo0ECMHDlS3Lt3T6UdhRd3d3cpT0REhNo8Y8eOlbV73rx5wsrKShgYGIiuXbuKK1euFFu3wpTHavLkybL0zZs3CwDC19dXln7s2DExaNAgYWNjI/T19UX9+vVFr169xMmTJ0u13+r8GycizfA88Wo9f/5cfPzxx+K1114T5ubmwtjYWDg7O4s5c+aIjIwMIYQQ+/btEw4ODkJXV1fY2toKIfL7R23atFEpLzU1VUyZMkVYW1sLPT09YWNjI0aOHCnu3r0rhMiPhZ6ensLIyEjY2NiIb775Rri7uwt/f3+pDHUxF4DYs2eP9Fnd3wbZ2dli+fLlokWLFsLAwEDUrFlTeHl5qcSqoup+48YN0aVLF6Gvry+cnJzEoUOHVPablJQkxowZIywtLYWBgYGwt7cXEyZM0Pj3yt83EZWE54mXx7FRjo0SkfbieaJqqiyxuaATJ06IXr16CXNzc6Gvry9cXFzE8uXLRU5Ojixf4T5hQY8fPxYASrVf/saJqCQ8T7xaHBv9D8dGiagyKM15QiFEGb6XlegFpKamwtzcHCkpKXzsNRGpxfMEVXX8jRNRSXieoKqMv28iKgnPE1SV8fdNRCXheYKqOv7GiagkPE9QVcbfNxGVpDTnCd1XVCciIiIiKsHg9begZ2habuUf8Hcqt7KJiMqaj48Pnjx5gr1798rSIyMj4enpiU2bNmHy5Mm4dOkSHBwcpPX3799HixYtMH/+fPj7+8POzg537twBABgaGqJ+/fro0KEDJk+ejLfeekvaLjExEU2aNJE+16xZE82bN8fs2bPRr18/KT0kJATTpk3DkydPiqx7cnIyFi9ejAMHDuCvv/5CvXr10LZtW0ybNg3dunWT8kVFRWHRokU4c+YMnj17BkdHR/j4+GDatGnQ0dGR8ikUChgYGODGjRuwtbWV0gcOHIhatWohJCREOmYbN24EAOjq6sLCwgKtW7fG8OHD4ePjgxo1asjqGRMTgyVLluDEiRNISUlB48aN4e7ujhkzZsDJSR4zevbsiaNHj+L06dPo1KmTyvFSZ968eZg/f36xeQoqizjIWEdEVQljYfWKheriIOMaERFVJ6XpEzJGEhFRVTN4/S0cmfVaRVeDiLRcjZKzaJeoqCjo6OigV69eKuuysrKwbNkytGnTBsbGxrC0tISbmxuCg4ORnZ0t5UtOTsaUKVNgb28PAwMD2NjYoF+/fjh69KhGdbC0tIRCoZCWGjVqwMDAAKampmjRooUs78aNG9GhQweYmJjAzMwMXbt2xf79+1XKFELg+++/R8eOHWFqaopatWrh9ddfx6pVq5CRkQEAmD9/Ptq2bSvb7uTJk6hVqxamTJkCIQRCQkKkeuno6KB27dro2LEjFixYgJSUFNm2Pj4+snYol4LH1s7OTko3NjZGy5Yt8d1332l0nIiISJWPjw8GDhyokh4ZGQmFQoHNmzfDxMQEt27dkq2/f/8+ateuja+//hqA/PxsZGQEOzs7DB06FMeOHZNtl5iYKDvHm5ubo1OnTvj5559l+UJCQlCrVq1i665p/IyKikLv3r1Ru3ZtGBoaolWrVlixYgVyc3Nl+RQKBQwNDaULlkoDBw6Ej4+P7Jgp66+np4f69eujR48eCAoKQl5eHgAgNDQUpqamapcWLVrA29sbb7/9tmw/v/zyCxQKBT777DNZ+sKFC2FtbS19DgsLQ8eOHWFubg4zMzO0aNECAQEBxR4rIiJ6ef369YOXlxfGjh0rne8BYOLEiWjXrh2mTp0qpS1YsABJSUm4ceMGNm3ahFq1aqF79+5YvHixSrnh4eFISkrCb7/9hg4dOmDQoEH4/fffNa5XYmIi2rdvj2PHjmHZsmW4cuUKDh06BE9PT/j5+Un59uzZA3d3dzRq1AgRERG4fv06/P39sXjxYnh7e6PwyzsUCgXmzp1b4v579eqFpKQkJCYm4pdffoGnpyf8/f3Rt29f5OTkSPn279+PTp06ITMzE6GhoYiLi8PmzZthbm6uEvvu3r2LM2fO4IMPPkBgYCAAwMbGBklJSdISEBCAFi1ayNKmT5+u8XEjIqLSq6yxcNWqVbC2tsbatWtx//596Orq4uHDhzhy5Ah69+4t5WMsJCIibVMZrkEWHvdt1qwZvvzyS1ncLDzmW3DstOC4qPJa4bNnz9TuKywsDB4eHjA3N4epqSlat26NBQsW4NGjR/Dw8FC7D+ViZ2dXuoNLRESvTGWIZ0pLliyBjo4OPv/8c1l6gwYN8MUXX8jSZs2aBYVCobKPbt26YcSIEaVuQ1HH4u+//4aenh5+/PFHtXWeNGkSWrduDSB/jo66ONisWbNSHQciorJS5Z4IGhQUhClTpmDDhg24e/cuGjduDCD/ZO/l5YVLly5h4cKFcHNzQ82aNXH27FksX74c7dq1Q9u2bZGYmAg3NzfUqlULy5YtQ+vWrZGdnY3Dhw/Dz88P169fL7EOxsbGGDVqFIYNG4bMzExERUVh7ty5mDNnDsaMGSPlmz59Or755hssWrQIAwcORHZ2Nn788UcMGDAAX3/9NT744AMp7+jRo7F7927MmTMH33zzDerWrYtLly5h1apVsLOzUztp6MCBAxgyZAhmzJiB//3vf1J6zZo1cePGDQgh8OTJE0RFRWHp0qUIDg7G6dOnZZNbevXqheDgYFm5BgYGss8LFizAhAkTkJaWhpCQEEyePBm1atXCsGHDSjxWRERUOv369cOePXswduxYnDx5UnqaSVEX+iZMmICsrCwkJibixx9/RPfu3bFw4ULMnj1bVm54eDhatGiBJ0+eYN26dRg0aBAuXryIli1balQvTePnnj17MHToUIwbNw4RERGoVasWwsPDMXPmTJw9exY7duyAQqGQylVe6FM+0aUoyniVm5uLv//+G4cOHYK/vz927dqFffv2oX///ujYsaPabfX09HDo0CFMnz4dOTk50NXN//MoMjISNjY2iIiIkOVXPn1Hedy8vb2xZMkS9O/fHwqFAteuXSt1R5eIiF7Md999h5YtW+Krr77C9OnTERISgpMnT+Ly5cuyeGJmZgYrKysAQOPGjdG1a1c0aNAAc+fOxeDBg+Hs7CzlrVOnDqysrGBlZYXFixdjzZo1iIiI0Dgmvv/++1AoFDh37hxMTEyk9BYtWuDdd98FAKSnp2PChAno378/vv/+eynP+PHjUb9+ffTv3x87duyQ9ammTJmCFStWYPr06WjVqlWR+zcwMJDa2rBhQ7z22mvo1KkTunXrhpCQEIwfPx4ZGRkYN24cevfujT179kjbNmnSBB07dlR5wltwcDD69u2L9957Dx06dMCqVatgYmIi7QcATE1NoaurK0sjIqLyVxlj4cGDB1GvXj0cOXIExsbGsnXKG9oZC4mISBtVhmuQwH/jvs+fP0d4eDjee+891KxZE5MmTZLlU475pqWl4Z9//oGhoSHMzMwAAD/99BO2bt0KANi9ezdGjhwp23b27Nn44osv8OGHH2LJkiWwtrZGfHw8vv32W2zevBm7d+9GVlYWAODPP/9Ehw4dpP0BkD3Zm4iIKpfKEs+A/L7WzJkzERQUhI8//lhK9/DwQEREBGbNmiWlFbxup3zTRFZWFs6cOSM9KEfTNhR3LOrXr48+ffogODgYo0aNktX32bNn2LZtGxYsWCCltWjRAuHh4bJ8ymuNRESvWpU6+6Snp2PHjh2Ijo5GcnIyQkJCpLvEV61ahRMnTuD8+fNo166dtI29vT2GDBkidVY0uWhXkho1asDOzg6urq4A8oNUWFgYYmNjpbvJz549ixUrVmD16tWYMmWKtO3ixYvx/PlzfPTRRxgwYABsbGywY8cOhIaGYu/evRgwYICU187ODv3790dqaqpKHbZs2YJx48bhyy+/lE0KAvIn1SgHJBs0aIDmzZujX79+aNGiBWbOnCm7s6HgwGlRCg4kL1q0CDt27MDevXs5EZSIqJxUxgt92jDpRTnIqY6npyfS0tJw/vx5dOrUCUB+h/Ljjz/Ghx9+iIyMDBgbG0sdytWrVwPIf4JMly5dMGPGDKksJycntTdoEBFR2atbty6+++47DB8+HG3atMGHH36Ir7/+WvbK2KL4+/tj4cKF+OmnnzBz5kyV9dnZ2fjhhx8A5N80oIlHjx7h0KFDWLx4sSweKimfrn3kyBE8fPhQ7VPC+vXrBycnJ2zdulUWEzt37owbN27gk08+UfsWieK89dZbaNOmDXbv3o3x48fj8OHD+Pfff9W2u2A9gfy3UwQHB2Pt2rVo1qwZnJycsGPHDowbN65UdSAiovJRGWNheHg4Fi9eLD0hRR3GQiIi0jaV5RokIB/3HT9+PNavX48jR46oTARVjvkCgIODg2zd/v37MWHCBAghEBgYKJsIeu7cOSxZsgSrVq2Cv7+/lG5nZ4cePXrgyZMnslj5/Plzlf0REVHlVJni2fHjx/Hs2TMsWLAAmzZtwokTJ9C1a1cA+dftAgICpAe4PH36FDExMVi1ahW2bNkilfHbb7/h2bNn0gNcNG1DScfC19cXAwYMQGJiouwp17t27cLz589lE0R5QyARVSZV6tXw27dvh7OzM5ydnTFq1CgEBwdLr0IIDQ1F9+7dZSd7JT09PZiYmEgX7fz8/Iq9aFcaQghERkYiLi5ONmC6detWmJqaqnTKACAgIADZ2dkICwuT6u7s7CybBKqkfI1vQWvXrsW4ceMQGBioMgm0KPXq1cPIkSOxb98+lVfzlpahoaHKI7ULyszMRGpqqmwhIiLNKS/0ffbZZ/j1119LfaFPCIGffvpJ7fqXmfRSUvzU9EJfQZ07d0bfvn3xySefaFSXggpe6CuJk5MTrK2tpad/Pn36FBcvXsSQIUPQtGlTnD59GkD+jRwFO5RWVla4evVqqV6TCDAWEhFpav/+/bLX1pmamuLtt9+W5Rk4cCCGDh2KXr16oWvXrvDx8dGobAsLC9SrVw+JiYmy9M6dO8PU1BSGhoYICAiAnZ0dhg4dqlGZt27dghCixFf/3Lx5EwDQvHlzteubNWsm5Slo6dKlOHToEE6ePKlRfQqXqWxrfHy8lFaS8PBwZGRkwMvLCwAwatQo6ZW4L4pxkIhIc4yFclUhFjIOEhFpJ226BlmSP/74A2fOnMHQoUMxdOhQREVF4fbt29L60NBQmJqa4v3331e7/YvUtSDGQiKiilOZ4llgYCCGDx8OPT09DB8+XNbPUj7AJTo6GgBw8uRJODk5YfDgwYiOjpbeNhEREYFGjRpJNzxo0gZNjkXv3r1hZWWFkJAQWRlBQUEYOHAg6tSpo3E7C2McJKLyVKUmggYGBkoz73v16oW0tDTp1azx8fElDuxpOlCpiVmzZsHU1BQGBgbw9PSEEEI2KfPmzZto2rQp9PX1Vba1traGubm5NNgZHx8ve2pbceLi4vDBBx9g/fr1Ko+pLkmzZs3w9OlTPHz4UEpTN9i8cOFCtdvn5OQgJCQEV65ckR7Frc7SpUthbm4uLTY2NqWqJxFRVccLfXJldaGvJB4eHoiMjATwX4eybt26cHd3l9KVr51o2rQpgPwnlr7xxhto1aoV7Ozs4O3tjaCgIGRmZha7L8ZCIiLNeHp6IjY2VrZs2LBBJd9nn32GvLw86Q0MmhJCyJ6mDeQPAMbExGDfvn1wcHDAhg0bYGFhoXF5AFTKLCm/JvUCABcXF4wZM0b2SiRNFSyzqP2qExgYiGHDhkmvMxo+fDh+++033Lhxo9R1UGIcJCLSHGOhXFWIhYyDRETaSZuuQSopx3yVS0xMDID8SSxvv/02ateuDQsLC/Tq1QtBQUHSdvHx8bC3ty/V5NLSYCwkIqo4lSWepaamIiwsTKrLqFGjsGvXLmlSpKOjIxo2bCi7Pufu7o569erB3t5eeoBLZGSk9PAWTdugVNyx0NHRwZgxYxASEiL1HxMSEnD8+HH4+vrKyrly5YrKdd3x48cXuV/GQSIqT1VmIuiNGzdw7tw5eHt7A8h//PKwYcOkjktRg4cFlXagsjgzZsxAbGwsjh8/Dk9PT8yePRudO3fWePvCA5Oa1qlRo0Z47bXXsGzZMiQlJZWqzurar26w2c/PT7adssNpZGQEPz8/zJgxQ+2TTpU++eQTpKSkSMuff/5ZqnoSEVV1vNAnV1YX+kri6emJ06dPIzs7G5GRkfDw8AAAlYmgb731lrSNiYkJDhw4gFu3bmHOnDkwNTVFQEAAOnToIN2NqA5jIRGRZkxMTODg4CBbGjZsqJJPOTFD+V9NPHz4EP/88w+aNGkiS7exsYGjoyP69OmDDRs2YNiwYXjw4IFGZTo6OkKhUCAuLq7YfE5OTgBQZL7r16/D0dFR7br//e9/iImJwd69ezWqk1JcXJzUVuX+r1+/Xuw2jx49wt69e7Fu3Tro6upCV1cXDRs2RE5OjuwiYWkxDhIRaY6xUJW2x0LGQSIi7aOt1yC3b98uG2N2cXFBbm4uNm7cKHuYzKhRo7Bx40bpjYGlGVN9EYyFREQVozLFsy1btsDe3h5t2rQBALRt2xb29vbYtm2blKfgA1zUXbfLzMzE2bNnZdftNI1hJR0LIP/18Hfu3MGxY8cA5N9I0ahRI3Tv3l1WlrOzs8p13cWLFxe5b8ZBIipPVWYiaGBgIHJyctCwYUNpUG79+vXYvXs3Hj9+DCcnpxIHIDUdqNSEpaUlHBwc4OrqirCwMKxcuRLh4eHSeicnJ/zxxx/IyspS2fb+/ftITU2VBjs1qbuSmZkZwsPDYWZmBg8PD9y/f1/jOsfFxaFmzZqyx1irG2wuPDFI2eG8c+cO0tLSsGzZMtSoUfRPy8DAADVr1pQtRET0H17oU1UWF/pK4unpifT0dERHRyMiIgLu7u4A8juU0dHRePToEc6cOSO7s1CpadOmGD9+PDZs2ICLFy/i2rVr2L59e5H7YiwkIqp4X3/9NWrUqIGBAwcWmcfd3R0tW7YsduCuIAsLC3h5eWHt2rVIT09XWf/kyRMAQM+ePWFhYYEVK1ao5Nm3bx/i4+MxfPhwtfuwsbHBBx98gE8//VS6SFeSY8eO4cqVKxg0aJC0f0tLSyxbtkxtfmU9Q0ND0ahRI1y6dEk2kLlq1Sps3LgROTk5Gu2/MMZBIqLKgbGwYmIh4yARkfbRtmuQSjY2NrIxZgMDAxw+fBh//fWX9LRrXV1deHt74969ezhy5AiA/65hZmdnv3Rd1WEsJCKqGJUpngUFBeHq1atSPXR1dXH16lWV18OfPn0aDx8+RExMDLp27Qogv58aERGBs2fP4tmzZ7LrdprOrSnpWCjb+uabbyI4OBh5eXnYuHEjxo0bpzIXRl9fX+W6bv369YvcN+MgEZWnKjERNCcnB5s2bcKKFStkA3KXLl2Cra0tQkNDMWLECISHh0uvPSi8fXp6usYDlaVVu3ZtTJkyBdOnT5fukPD29kZaWhq+++47lfzLly+Hnp6eNDA5YsQI3Lx5Ez/99JNKXiEEUlJSVPYXHh6O2rVrw8PDA3/99VeJdXzw4AG2bNmCgQMHFjuJUx1lh9Pa2rpc7xAkIqKXV50v9JWkadOmsLGxwb59+xAbGytNBG3QoAHs7OywYsUKPH/+XO1E0ILs7OxgbGys9lgQEVHFePr0KZKTk/Hnn3/ixIkTmDhxIhYtWoTFixfDwcGh2G0DAgLw3XffyfpVubm5Knd5X7t2DQCwbt065ObmokOHDggLC0N8fDzi4uKwevVquLq6Asi/6eO7777DTz/9hIkTJ+Ly5ctITExEYGAgfHx8MHjwYAwdOrTIOn3yySe4f/++2gt9mZmZSE5Oxl9//YWLFy9iyZIlGDBgAPr27YsxY8ZI+9+wYQMOHDiA/v37Izw8HImJiTh//jxmzpyJyZMnA8gfEB08eDBatmwpW9599108efIEBw4cKN0XQUREFYaxkLGQiIhejDZegyxOYGAgvL29VeL4yJEjpck3I0aMQFpaGtatW6e2jBetKxERVZzKFM+uXLmC8+fPIzIyUlaXEydOIDo6Gr///juA/x7g8tVXX8HR0VGaXOnu7o7z58/jwIEDaNKkCWxtbaWyNWmDJsdCydfXF7t370ZYWBju3buHcePGldg+IqKKVCUmgu7fvx+PHz+Gr6+vyqDc4MGDERgYiGnTpsHNzQ3dunXD2rVrcenSJdy+fRs7duxAx44dER8fD0CzgcoX4efnhxs3biAsLAwA4OrqCn9/f8yYMQMrVqzAH3/8gevXr2POnDn4+uuvsWLFCtjY2AAAhg4dimHDhmH48OFYunQpzp8/jzt37mD//v3o3r07IiIiVPZnbm6OI0eOwNLSEh4eHrh37560TgiB5ORkJCUlIS4uDkFBQejcuTPMzc3x+eefy8pRDpwWXP79998XPg5ERPTq8EKf/EKfJjw9PbFu3TqVu/Xc3d2xZs0a2Nvbo3HjxlL6/PnzMXPmTERGRiIhIQExMTF49913kZ2djR49emi8XyIiKl9z585FgwYN4ODggNGjRyMlJQVHjx7FrFmzSty2b9++sLOzk90gkZaWhnbt2smW3r17AwCaNGmCixcvwtPTEwEBAWjZsiV69OiBo0ePYv369VIZgwcPRkREBP7880907doVzs7O+OqrrzB79mxs27at2JvsLCwsMGvWLDx//lxl3aFDh6SbGHr16oWIiAisXr0aP/30E3R0dKR8AwYMQFRUFPT09DBixAg0a9YMw4cPR0pKChYtWoQLFy7g0qVLam+oMDMzQ8+ePWV36BMRUeXGWMhYSEREL0Ybr0EW5Z9//sHPP/+MsWPHqrRl7Nix2LdvH/755x907NgRM2fOREBAAGbOnIkzZ87gzp07OHr0KIYMGYKNGze+cF2JiKhiVKZ4FhgYiA4dOqBr166yenTp0gWurq5SP0t5TW7NmjXSw1sAwNraGra2tvj2229VHt6iSRs0ORZKQ4YMgZ6eHiZNmoRu3brBzs5OpT05OTkqc2r+/vvvF/maiIhenqgC+vbtK3r37q123YULFwQAceHCBfH8+XOxdOlS0apVK2FoaCgsLCyEm5ubCAkJEdnZ2dI29+/fF35+fsLW1lbo6+uLhg0biv79+4uIiAiN6mNraytWrlypkj5hwgTRokULkZubK6UFBgaK119/XRgZGQljY2PRpUsXsW/fPpVtc3Nzxfr168Ubb7whjI2NRc2aNUX79u3F119/LTIyMoQQQsybN0+0adNGtl1qaqpwc3MTTZs2FXfv3hXBwcECgAAgFAqFMDc3Fx06dBALFiwQKSkpsm3Hjh0r5S24ODs7l9jW0khJSREAVPZPRKRUnc4TY8eOFQMGDFBJj4iIEADE48ePpbSEhAQBQMTExKjkt7W1lc7b+vr6onHjxmLo0KHi2LFjsnxFlZGXlyecnZ3Fe++9J4QQsvhRcLG1tZW20TR+njhxQvTq1UuYm5sLfX194eLiIpYvXy5ycnJk+QCIPXv2yNKWLFkiAIixY8fKjpmyPrq6uqJu3bqie/fuIigoSBZzNaFs5+TJk2XpmzdvFgCEr6+vLP3YsWNi0KBBwsbGRujr64v69euLXr16iZMnT5Zqv9XpN05EL4bnCarK+PsmopLwPEFVGX/fRFQSnicqljZegyxqzHf58uWiVq1aIisrS2X77OxsYWFhIVasWCGlbd++XXTt2lWYmZkJExMT0bp1a7FgwQLZGLUQxY9Ta4K/cSIqCc8TL6+yxLPMzExRp04dsWzZMrXrV6xYISwtLUVmZqYQ4r9rgNu2bZPl8/X1FQDE5s2bVcooqQ2aHguliRMnCgBiy5YtKvnnzZun9vqpgYFBscehIP6+iagkpTlPKITQ4D0BROUoNTUV5ubmSElJQc2aNSu6OkRUCfE8QVUdf+NEVBKeJ6gq4++biErC8wRVZfx9E1FJeJ6gqo6/cSIqCc8TVJXx901EJSnNeaJKvBr+VYqKioKOjg569eqlsi4rKwvLli1DmzZtYGxsDEtLS7i5uSE4OBjZ2dlSvuTkZEyZMgX29vYwMDCAjY0N+vXrh6NHj2pUBzs7O6xatUr6LIRAQEAAzMzMcOzYMQCAh4cHFAqFypKTkyNtN3HiROjo6GDbtm1q93Pr1i2MGzcOjRo1goGBAZo0aYLhw4fj/PnzCAkJUVt+wSUyMlKj9hARkXZhLCy/WDh4/S30+fpmmS1ERFS8yhLTFAoFzp49K0ufNm0aPDw8ZGmPHj3CtGnTYGdnB319fTRo0ADjxo3D3bt3iyx/6dKlUCgUmDZtmtr1W7ZsgY6ODiZPniylXbhwAQqFAqdOnVK7jZeXF/r37w8A8PHxURsD1R3TkpRFHCQionxVNcadOHEC/fr1g7W1NRQKBfbu3auyXyEE5s+fD2traxgZGcHDwwNXr15VW8clS5ZAR0cHn3/+uZQWFhYGHR2dIuNrs2bNMHXqVABF9zsLxlUiItJulSmmKhQK6OjowNraGr6+vnj8+LGUJzIyUspTo0YNmJubo127dpg5cyaSkpLUlluZ+oNERPRyijonv/XWW7C0tMSiRYvUbrd06VJYWloiKysLISEhqFWrlsb7fPbsGebNmwdnZ2cYGBjA0tISgwcPVul/zZ8/X20/KTY2FgqFAomJiQCAxMREWd3NzMzQokUL+Pn5Sa+l18Tu3bvRo0cP1K1bFzVr1oSrqysOHz6ski8sLAwuLi4wMDCAi4sL9uzZI1uvSf9z9+7d8PLygqWlJRQKBWJjYzWuZ2GD19964W2JiJQ4EbSUPv30U+jo6ODw4cMwMTGBqamptNSuXRuff/45Jk6ciKioKJw7dw5+fn5Ys2aNFOwSExPRvn17HDt2DMuWLcOVK1dw6NAheHp6ws/Pr9T1yc3Nha+vLzZt2oRjx47hrbfektZNmDABSUlJskVXVxcAkJGRge3bt2PGjBkIDAxUKff8+fNo3749bt68ie+++w7Xrl3Dnj170KxZMwQEBGDYsGGycl1dXVX217lz5xc8ykREVJkFBQVhypQpOHXqlOzCWFZWFry8vCplLPzmm29gbGwMY2Nj1KpVS4rdP/zwA2rXrs1YSERUTVWWmGZoaIhZs2YVm+fRo0fo1KkTwsPDsW7dOty6dQvbt2/HH3/8gTfeeAO3b99W2SY6Ohrff/89WrduXewxmDlzJrZt24aMjAwAQPv27dGmTRsEBwer5P/zzz8RHh4OX19fKa1Xr14qfc+tW7dq2nwiIioHVTXGpaeno02bNvjmm2+KLG/ZsmX46quv8M033yA6OhpWVlbo0aMHnj59qpI3ODgYM2fORFBQkJTWv39/1KlTBxs3blTJf/r0ady4cUMWB9WNwS5btqzYNhMRkfZ4lTE1NDRUdt1Rudy9exd169ZFUlIS7t69i9DQUJw4cUK6MaGgGzdu4P79+4iOjsasWbMQHh6Oli1b4sqVK2rbxv4gEVHVoe6cHBYWhlGjRiEkJATqXhYcHByM0aNHQ19fv1T7yszMRPfu3REUFISFCxfi5s2bOHjwIHJzc9G+fXsYGxtLcWzJkiUAgO+++w6Ojo4llh0eHo6kpCRcunQJS5YsQVxcHNq0aaPxDRQnTpxAjx49cPDgQVy4cAGenp7o168fYmJipDxnzpzBsGHDMHr0aFy6dAmjR4/G0KFD8dtvv0l5NOl/pqenw83NTXZzIRFRRdKt6Apok/T0dFy4cAH79+/H119/DQcHB0yZMgUA8P3332P58uU4deoU2rVrJ21jb2+PIUOGICsrCwDw/vvvQ6FQ4Ny5czAxMZHytWjRAu+++26p6pOZmYnhw4cjOjoaJ06cQPPmzWXrjY2NYWVlpXbbnTt3wsXFBZ988gkaNGiAxMRE2NnZAci/a97HxweOjo44efIkatT4b75w27Zt4e/vDyMjIxgZGUnp+vr6xe6PiIiqhvT0dOzYsQPR0dFITk5GSEgI5s6dCwBYtWoVTpw4gfPnz1e6WDhmzBh4eXnJ1u3evRtbt27Fpk2b0LFjR8ZCIqJqpjLFtEmTJmH9+vU4ePAgevfurTbP7Nmzcf/+fdy6dUuKNY0bN8bhw4fh6OgIPz8//PLLL1L+tLQ0jBw5Ej/88EORd/wnJiYiKioKYWFhiIiIwK5duzBmzBgAgK+vLz799FOsXr1a1raQkBDUrVsXffr0kdIMDAwY/4iIKpGqHOPefvttvP3220XuTwiBVatWYfbs2XjnnXcAABs3bkT9+vWxZcsWTJo0Scp7/PhxPHv2DAsWLMCmTZtw4sQJdO3aFXp6ehg9ejRCQkIwZ84cKBQKaZugoCBpgowS+4FERFXXq46p/fv3R8eOHVXq4e7uDl9fXyneNGzYEGPGjFH7lqN69eqhVq1asLKygpOTEwYMGIB27drhvffekz3lk/1BIqKqp6hzsq+vL77++mucOHEC7u7uUvrJkycRHx8vm+CvqVWrVuHMmTOIiYmR+ke2trYICwvD66+/jqdPn+LgwYNQKBRYvXo1fv31V9SpUwfm5uYlll2nTh2pHfb29ujXrx+6desGX19f/PHHH9DR0SmxbgUtWbIEP/30E37++WcpZq9atQo9evTAJ598AgD45JNPcPz4caxatUq6oaGk/icAjB49GgCkp5oSEVU0PhG0FLZv345mzZqhZ8+eeO+997Bv3z40bdoUDg4OOHz4MHr06CHr7Cnp6enBxMQEjx49wqFDh+Dn5yfrOCmV5jHbaWlp6NOnD65evYrTp0+rTHwpSWBgIEaNGgVzc3P07t1bdmdfbGwsrl69ioCAANnElxeppzqZmZlITU2VLUREpB22b98OZ2dnODs7Y9SoUQgODpbuIAwNDUX37t0rZSw0MzODg4ODbNm/fz/Gjx+PVq1aMRYSEVVDlSmm2dnZYfLkyfjkk0+Ql5ensj4vLw/btm3DyJEjVQZzjYyM8P777+Pw4cN49OiRlO7n54c+ffqge/fuRe43KCgIffr0gbm5OUaNGiV7QvbIkSORnZ2NnTt3SmlCCISEhGDs2LHS2yZeBOMgEVH5quoxrjgJCQlITk5Gz549pTQDAwO4u7sjKipKljcwMBDDhw+Hnp4ehg8fLouDvr6+uH37No4fPy6lKScDvchF0oIYB4mItMerjqnqxjAdHBygp6cHCwsLKd9ff/2F/fv3q500WpiRkREmT56M06dP48GDB1J6RfUHAcZCIqJXrVWrVnjjjTdUnvYcFBSEDh06oGXLlqUuc8uWLejRo4fsJjkAqFGjBqZPn45bt24hPT0dDg4OsLCwgIGBAVavXo1Dhw4hOjq6VPuqUaMG/P39cefOHVy4cKHUdc3Ly8PTp09lsfTMmTOyfiMAeHl5qfQbywPjIBGVJ04ELQXl5Ekg/7HaaWlp0uOn4+Pj0axZs2K3v3XrFoQQJebTxMKFCxEbG4uTJ0+icePGavOsW7dO9uqIgIAAqa5nz57FsGHDAEDqvCoHY+Pj4wGgTOqpztKlS2Fubi4tNjY25bIfIiIqe4yFZYOxkIio4lWmmAYAc+bMQUJCAkJDQ1XW/fPPP3jy5EmRNz00b94cQgjcunULALBt2zZcvHgRS5cuLXJ/eXl5CAkJkY6Bt7c3zpw5I5VhYWGBgQMHygaIIyMjcfv2bZWn1uzfv1/l1YULFy4sct+Mg0RE5asqx7iSJCcnAwDq168vS69fv760DgBSU1OlVyQC+X3CXbt2SRfgXFxc0LFjR1kc3LFjB3JzczF8+HBZ2YX7naampmpfK6/EOEhEpD0qU0ydNWsWTE1NYWRkhEaNGkGhUOCrr77SaFvl/pVPK6vI/iDAWEhEVF6KOye/++672LVrF9LS0gDkP2xl586dL3yj282bN4vtxynzFPTaa69h6NCh+Pjjj0u9v8KxrDRWrFiB9PR0DB06VEpLTk4usd9YXhgHiag8cSKohm7cuIFz587B29sbAKCrq4thw4YhKCgIQP6dcAVfE6SO8i7BkvJpomfPnkhPT8eSJUuKzDNy5EjExsZKi/Kx1oGBgfDy8oKlpSUAoHfv3khPT0d4eHiZ11OdTz75BCkpKdLy559/lst+iIiobDEWlh3GQiKiilXZYhoA1K1bF9OnT8fcuXOlVwhqqmBd/vzzT/j7++PHH3+EoaFhkdscOXIE6enp0uuNLC0t0bNnT+kYAPlPQztx4oR0MTAoKAhubm5wdnaWleXp6SmLt7GxsfDz8yty34yDRETlpyrHuNIonL9wu7ds2QJ7e3vp6TVt27aFvb297BW7vr6+2LVrF54+fQogPw6+8847Kk9vK9zvjI2Nxf/93/8VWTfGQSIi7VDZYuqMGTMQGxuLy5cvS5NR+/Tpg9zc3BK3LVyPiuwPAoyFRETlpbhz8vDhw5GXl4ft27cDyH/qtRBCinNlqbj4t2jRIpw8eRJHjhwpszKLs3XrVsyfPx/bt29HvXr1ZOtK6jeWF8ZBIipPL/fs/mokMDAQOTk5aNiwoZQmhICenh4eP34MJycnxMXFFVuGo6MjFAoF4uLiMHDgwJeqT7du3TB16lQMGDAAubm5WLNmjUoec3NzODg4yNJyc3OxadMmJCcny17dkJubi8DAQPTs2RNOTk4AgLi4OLRt2/al6qmOgYEBDAwMyrxcIiIqX4yFZYexkIioYlW2mKb00UcfYd26dVi3bp0svW7duqhVqxauXbumdrvr169DoVCgadOmOHHiBB48eID27dtL63Nzc3HixAl88803yMzMhI6ODoKCgvDo0SMYGxtL+fLy8hATE4OFCxdCR0cH3bt3h62tLUJCQjBz5kzs3r0b33zzjcr+TUxMVOJtcRgHiYjKT1WOcZpQvl4+OTkZDRo0kNIfPHgge9pLUFAQrl69KusT5uXlITAwEBMnTgSQ/3S0Dz/8ENu3b4eHhwdOnTqFBQsWqOxTXb+zOIyDRETaobLFVEtLSyneODo6YtWqVXB1dUVERAS6d+9e7LbKetrZ2QFAhfYHAcZCIqLyUtw52dzcHIMHD0ZwcDB8fX0RHByMwYMHo2bNmi+0Lycnp2L7cUB+vCqsadOmmDBhAj7++GMEBgZqvD9lLGvSpInG22zfvh2+vr7YuXOnSqy0srJSefpn4X5jeWEcJKLyxCeCaiAnJwebNm3CihUrZHdPXLp0Cba2tggNDcWIESMQHh6OmJgYtdunp6fDwsICXl5eWLt2LdLT01XyPXnypFT16tGjB/bv34+goCD4+flJd0EU5+DBg3j69CliYmJkbdm5cyf27t2Lhw8fom3btnBxccGKFSukV+S+TD2JiEj7MRa+XD2JiKjyqKwxDQBMTU3x2WefYfHixdKraQGgRo0aGDp0KLZs2aIyQPns2TOsW7cOXl5esLCwQLdu3XDlyhVZ215//XXpaWU6Ojp4+PAhfvrpJ2zbtk3lKQFpaWn45ZdfAOTfFT9u3Dhs3LgRW7ZskepBRESVU1WPcZpo0qQJrKys8Ouvv0ppWVlZOH78ODp37gwAuHLlCs6fP4/IyEjZcTpx4gSio6Px+++/AwDMzMwwZMgQBAcHIygoCPb29vDw8Ch124mISPtU5piqpKOjAyA/Xhbn2bNn+P7779G1a1fUrVuX/UEiomrM19cXp0+fxv79+3H69OkXfi08kH/jXHh4OC5duiRLz8vLw8qVK+Hi4iK9gaGwuXPn4ubNm7I3MhQnLy8Pq1evRpMmTdCuXTuNttm6dSt8fHywZcsW9OnTR2W9q6urrN8I5D8xW9lvJCLSVpwIqoH9+/fj8ePH8PX1RcuWLWXL4MGDERgYiGnTpsHNzQ3dunXD2rVrcenSJdy+fRs7duxAx44dER8fDwBYt24dcnNz0aFDB4SFhSE+Ph5xcXFYvXo1XF1dS123t956CwcOHMDGjRs1mgATGBiIPn36oE2bNrJ2DBo0CHXr1sWPP/4IhUKB4OBg3Lx5E127dsXBgwdx+/ZtXL58GYsXL8aAAQNe6DgSEZH2YixkLCQiqioqc0wDgIkTJ8Lc3Bxbt26VpS9evBhWVlbo0aMHfvnlF/z55584ceIEvLy8kJ2djbVr1wLIn7RSuF0mJiaoU6cOWrZsCQDYvHkz6tSpgyFDhsjytW7dGn379pXdjT9u3Djcv38fn376Kby9vWFiYqJS58zMTCQnJ8uWf//994XaT0REL66qxzgASEtLkyarAEBCQgJiY2Nx9+5dAPmTVqZNm4YlS5Zgz549+P333+Hj4wNjY2OMGDECQH6fsEOHDujatavsGHXp0gWurq6yOOjr64uoqCisX78e7777rtrXBGZkZKjEwcePH7/QMSIiosqhMsbUp0+fIjk5GUlJSTh37hxmzJgBS0tLlQkrDx48QHJyMuLj47Ft2za4ubnh33//xfr16wGwP0hEVJWVdE52d3eHg4MDxowZAwcHB3Tt2vWF9/Xhhx+iQ4cO6NevH3bu3Im7d+8iOjoagwYNQlxcHAIDA4t8zXr9+vXx0UcfYfXq1WrXP3z4EMnJybh9+zb27duH7t2749y5cwgMDJRuhCjO1q1bMWbMGKxYsQKdOnWSjkVKSoqUx9/fH0eOHMEXX3yB69ev44svvkB4eDimTZsm5Smp/wkAjx49QmxsrPR01Bs3biA2NlblRkcioldGUIn69u0revfurXbdhQsXBABx4cIF8fz5c7F06VLRqlUrYWhoKCwsLISbm5sICQkR2dnZ0jb3798Xfn5+wtbWVujr64uGDRuK/v37i4iICI3qY2trK1auXClLO378uDA1NRWTJk0SeXl5wt3dXfj7+8vyJCcnC11dXbFjxw615U6ZMkW0atVK+nzjxg0xZswYYW1tLfT19YWtra0YPny4uHjxosq26vanqZSUFAFApKSkvND2RFT18TxR8RgLGQuJqGLxPFF2tCGmbdmyRQAQ7u7usvR//vlHTJkyRdjY2AhdXV1Rv359MXbsWHHnzp1i91E4RrVq1Uq8//77avOGhYUJXV1dkZycLKX17NlTABBRUVEq+ceOHSsAqCzOzs7FN7wA/r6JqCQ8T2imOsS4iIgItXFn7NixUp68vDwxb948YWVlJQwMDETXrl3FlStXhBBCZGZmijp16ohly5aprfOKFSuEpaWlyMzMlNKcnZ1FjRo1xJ9//qmS393dXW19vLy8NDpGQvD3TUQl43ni1auMMbVgnKlbt67o3bu3iImJkfIUjJEKhUKYmZmJNm3aiBkzZoikpCQpX2XrDwrB3zgRlYzniZJpek5esmSJACCWLFmiUkZwcLAwNzfXeJ/p6elizpw5wsHBQejp6QkLCwsxaNAgqf+lNG/ePNGmTRtZWmpqqrC0tBQAREJCghBCiISEBFndjY2NRfPmzcX7778v4uPjNa5XUf20gv1GIYTYuXOncHZ2Fnp6eqJZs2YiLCxMtl6T/mdwcLDaPPPmzdO4vvx9E1FJSnOeUAihwTtUicpRamoqzM3NkZKSgpo1a1Z0dYioEuJ5gqo6/saJqCQ8T1BVxt83EZWE5wmqTBQKBfbs2YOBAweWSXn8fRNRSXieoKqOv3EiKgnPE1SV8fdNRCUpzXmi0r0a3sfHBwqFAgqFAnp6erC3t8f06dORnp6OxMREaZ1CoYC5uTk6deqEn3/+WVZGSEiILJ9yMTQ0lOVLTk7GlClTYG9vDwMDA9jY2KBfv344evSolMfOzg6rVq2SfVaWZ2xsjJYtW+K7776TlRsaGoo2bdrA2NgYDRo0wLhx4/Dw4UNp/dWrVzFo0CCprILlK504cQL9+vWDtbU1FAoF9u7dq5JHCIH58+fD2toaRkZG8PDwwNWrV0txtIGYmBgMGTIE9evXh6GhIZycnDBhwgTcvHlTJW/Pnj2ho6ODs2fPAoDK96FumT9/fqnqQ0RE5S8qKgo6Ojro1auXyrqsrCwsW7ZMimOWlpZwc3NDcHAwsrOzpXyaxFBNLFmyBDo6Ovj8889l6Q0aNMAXX3whS5s1axYUCoXKPrp16ya94q80bSjqWPz999/Q09PDjz/+qLbOkyZNQuvWrQEA8+fPVxv/mjVrVqrjQERE+dgfzFdd+4OD199Cn69vlnohIqKy9+DBA0yaNAmNGzeGgYEBrKys4OXlhTNnzgBAkfGpssnNzcXKlSvRunVrGBoaolatWnj77bdx+vTpiq4aERFpoW+//RZmZmbIycmR0tLS0qCnp4c333xTlvfkyZMl9pkUCgVCQkIQGRkpfa5RowbMzc3Rrl07zJw5E0lJSbJyNRmP9PDwkNINDAzg5OSEJUuWIDc3V8ojhMD333+Pjh07wtTUFLVq1cLrr7+OVatWISMjQ7bPe/fuQV9fX7aPoupRcElMTCyLw05ERJVIZbjGWHjMVgiBgIAAmJmZ4dixYwDksbDgUjCGT5w4ETo6Oti2bZva/dy6dQvjxo1Do0aNYGBggCZNmmD48OE4f/58kWPQBZfIyEiN2kNEVJYq3URQAOjVqxeSkpJw+/ZtLFq0COvWrcP06dOl9eHh4UhKSsJvv/2GDh06YNCgQfj9999lZdSsWRNJSUmy5c6dO9L6xMREtG/fHseOHcOyZctw5coVHDp0CJ6envDz8yu2fgsWLEBSUhIuX76MgQMHYvLkydi+fTsA4NSpUxgzZgx8fX1x9epV7Ny5E9HR0Rg/fry0fUZGBuzt7fH555/DyspKVnZoaChMTU3h5eWFw4cP4/HjxwCA4cOHo0WLFrK8y5Ytw1dffYVvvvkG0dHRsLKyQo8ePfD06VONjvP+/fvRqVMnZGZmIjQ0FHFxcdi8eTPMzc3x2WefyfLevXsXZ86cwQcffIDAwEAAgI2Njez4BgQEoEWLFrK0gt8bERFVDkFBQZgyZQpOnTqFu3fvSulZWVnw8vLC559/jokTJyIqKgrnzp2Dn58f1qxZI00ueZkYWlhwcDBmzpyJoKAgKS00NBT//vsvZs+eDVNTU2lZvnw5dHV1ERERIavzmTNn4OnpWao2FHcs6tevjz59+iA4OFilvs+ePcO2bdvg6+srpRWOfUlJSTh16lSpjgMREf2nKvUHJ0yYgE2bNqF+/fpSPHvjjTfw888/IycnR6U/qJSeno42bdrgm2++KbIe7A8SEVF5GjRoEC5duoSNGzfi5s2b2LdvHzw8PPDo0SMpz/Dhw2V9NuWiHMMsfCPeqyaEgLe3NxYsWICpU6ciLi4Ox48fh42NDTw8PIqdyFrRdSciosrJ09MTaWlpOH/+vJR28uRJWFlZITo6WjaBMjIyElZWVrI+0tChQ6U+r3IRQuDtt98GABgbG8PIyAg5OTmIi4vDmjVr0LJlS1y5ckVWD03GIydMmICkpCTcuHEDU6dOxZw5c7B8+XJp/ejRozFt2jQMGDAAERERiI2NxWeffYaffvoJR44ckZUVEhKCoUOHIiMjQ7qZYvr06bL9N2rUSOovKxcbG5uyOfBERPTKtWjRQm1/z93dHT169KjQa4z379/HrFmzpDrp6+vjq6++Qm5uruwGCmUsLLjo6uoCyJ+zs337dsyYMUMa7yzo/PnzaN++PW7evInvvvsO165dw549e9CsWTMEBARg2LBhsnJdXV1V9te5c+eX+QqIiF5MOb6i/oWMHTtWDBgwQJY2fvx4YWVlJRISEgQAERMTI61LTU0VAMTq1aultODgYGFubl7sft5++23RsGFDkZaWprLu8ePH0v/b2tqKlStXFvlZCCEcHR2Ft7e3EEKIL7/8Utjb28vWr169WjRq1EhtPQqXl5qaKuLj42ULALFu3TqRmJgo5cvLyxNWVlbi888/l9KeP38uzM3Nxbffflts24UQIj09XVhaWoqBAweqXV/wGAghxPz584W3t7eIi4sTZmZmao/bvHnzRJs2bUrcd2EpKSkCgEhJSSn1tkRUPfA8UXbS0tKEmZmZuH79uhg2bJj43//+J6374osvRI0aNcTFixdVtsvKypLO/ZrG0JJERkaKhg0biqysLGFtbS2OHz8uhMiPhQsXLhTGxsYiLi5OxMfHi5iYGKGrqysWLFgg3NzcpDJOnDghAIj4+PhStaGkY7Fv3z6hUChEQkKCrIxNmzYJfX198e+//wohXjz2FcbfOBGVpLqcJ6pafzA1NVV89tlnwsrKSqWfl5iYqLa8wgCIPXv2yNKqUn9QiP9+3z0+vyB6r7pR6oWIqr7qEgcri8ePHwsAIjIyUu16W1tbAUBarK2tRXx8vJgyZYpo1qyZ+OKLL0STJk2EQqEQeXl54smTJ2LChAmibt26wszMTHh6eorY2FipvFu3bon+/fuLevXqCRMTE/H666+LX3/9VWWfCxcuFKNHjxYmJiaicePGYu/eveLBgweif//+wsTERLRs2VJER0dL22zbtk0AEPv27VNpwzvvvCPq1KkjxTRlHAsMDJTV/ebNm+LNN98UBgYGonnz5uLIkSMqsfnevXti6NCholatWsLCwkL0799fpS9ZHP6+iagkPE9ULtbW1mLp0qXS55kzZwo/Pz/h4uIii19vvfWWGDlypGxbdX3e1NRU8eOPPwoA4sKFC7J+4/Xr14Wzs7NsPFSTvpe7u7vw9/eXpXXv3l106tRJCCHE9u3bBQCxd+9elW2VsbvgZ3t7e3Ho0CExa9YsMW7cOLX71KR/WxT+xomoJDxPvHqJiYkq45mXLl0SJiYm4vz58xV6jbFhw4bi008/FVevXhU9evQQVlZW4pdffhHx8fEiNTVVCKE+FhYUEhIiOnXqJJ48eSKMjIxkfbi8vDzRokUL0b59e5Gbm6tRPUvaX3H4+yaikpTmPFEpnwhamJGRkdq7sLOzs/HDDz8AAPT09DQu79GjRzh06BD8/PxgYmKisr5WrVqlqp+hoaFUv86dO+PevXs4ePAghBD4+++/sWvXLvTp00ejsszMzODg4CBbgPxX5Nra2kr5EhISkJycjJ49e0ppBgYGcHd3R1RUVIn7OXz4MP7991/MnDlT7fqCx0AIgeDgYIwaNQrNmjWDk5MTduzYoVF7iIioctm+fTucnZ3h7OyMUaNGITg4GEIIAPlP4uzevTvatWunsp2enh5MTEzKNIYGBgZi+PDh0NPTw/Dhw6U77szMzDBs2DBkZGTg8ePHcHBwwP379+Hs7IxJkybJ7q6PiIhAo0aNpHipSRs0ORa9e/eGlZUVQkJCZGUEBQVh4MCBqFOnjsbtJCKil6PN/cGMjAwcP34cAwYMUOnnFezflRb7g0REVJ6UT1XZu3cvMjMzVdZHR0cDyH/DQ1JSEmJjY+Hg4AALCwv8+eefOHbsGMLCwhAbGwsA6NOnD5KTk3Hw4EFcuHABr732Grp16yY9XTQtLQ29e/dGeHg4YmJi4OXlhX79+smeLgMAK1euhJubG2JiYtCnTx+MHj0aY8aMwahRo3Dx4kU4ODhgzJgxUr9uy5YtcHJyQr9+/VTaEBAQgIcPH+LXX3+V0m7duoUdO3ZIdc/Ly8M777wDHR0dnD17Ft9++y1mzZolKycjIwOenp4wNTXFiRMncOrUKZiamqJXr17Iysp68S+BiIgqLQ8PD9kbiyIiIuDh4QF3d3cpvfBbjIpjZmaGhg0bAgDs7e1l/UZnZ2dMnjwZp0+fxoMHD16q3gX71qGhoXB2dsaAAQNU8ikUCpibm8val5GRge7du2P06NHYsWOHxm+iICIi7WVra6synnn+/Hk0b94c7du3r9BrjLq6ujAyMsLUqVNx584d/Pbbb+jVqxccHBxgZmamURmBgYEYNWoUzM3N0bt3b9lbAmNjY3H16lUEBASgRg3VKVWlHT8mInqVKv1E0HPnzmHLli3o1q2blNa5c2eYmprC0NAQAQEBsLOzw9ChQ2XbpaSkqDymWnmR7NatWxBCoFmzZi9Vt5ycHISEhODKlStS/Tp37ozQ0FAMGzYM+vr6sLKyQq1atbBmzZqX2ldhycnJAPJfX1tQ/fr1pXXFiY+PBwCNjkF4eDgyMjLg5eUFABg1apTax2NrKjMzE6mpqbKFiIheDWXHBsh/9W5aWhqOHj0KID82lBQXyiqGpqamIiwsTKrLqFGjsGvXLikmODo6omHDhoiMjASQ/yold3d31KtXD/b29tIriCIjI2UDqpq0Qam4Y6Gjo4MxY8YgJCRE6sQmJCTg+PHjstfCA8CVK1dU/uYYP358sftmLCQi0gz7g+ppc38QYBwkIqrsdHV1ERISgo0bN6JWrVpwc3PDp59+isuXLwMA6tatCyD/4peVlZX0Gcif+LJ582a0a9cOrVu3RkREBK5cuYKdO3fi9ddfh6OjI5YvX45atWph165dAIA2bdpg0qRJaNWqFRwdHbFo0SLY29tj3759snr17t0bkyZNgqOjI+bOnYunT5/ijTfewJAhQ+Dk5IRZs2YhLi4Of//9NwDg5s2baN68udo2KtNv3rxZZN2PHj2KuLg4bN68GW3btkXXrl2xZMkSWTnbtm1DjRo1sGHDBrRq1QrNmzdHcHAw7t69K/VnC2McJCLSbh4eHjh9+jRycnLw9OlTxMTEoGvXrnB3d5fO/WfPnsWzZ880mghaEmW/LTExUUorzXhkXl4eDh06hMOHD0t91/j4eDg7O2u0/8DAQHh7e0NHRwctWrSAg4MDtm/f/lJtYiwkItJOleUaIwAsXLgQsbGxOHnyJBo3bqw2z7p162SxMiAgQKrr2bNnMWzYMACQJrXm5eVJ6wHNxk5fBOMgEZWnSjkRdP/+/dKFPVdXV3Tt2lV24Wz79u2IiYnBvn374ODggA0bNsDCwkJWhpmZGWJjY2WLcha/ckKHQqF4ofrNmjULpqamMDIygp+fH2bMmIFJkyYBAK5du4apU6di7ty5uHDhAg4dOoSEhARMnjz5hfZVksJtEEJo1C7lMdBEYGAghg0bBl1dXQDA8OHD8dtvv+HGjRulq+z/t3TpUpibm0uLjY3NC5VDRESlc+PGDZw7dw7e3t4A8i/uDRs2DEFBQQA0iyEvG0OVtmzZAnt7e7Rp0wYA0LZtW9jb22Pbtm1SHg8PD9lEUA8PDwCQBlUzMzNx9uxZvPXWW7L6aVK3ko4FAPj6+uLOnTs4duwYgPyngTZq1Ajdu3eXleXs7KzyN8fixYuL3T9jIRFR0dgf1Jw29gcBxkEiIm0waNAg3L9/H/v27YOXlxciIyPx2muvqbw1oTBbW1vZxNALFy4gLS0NderUkV2AS0hIwB9//AEASE9Px8yZM+Hi4oJatWrB1NQU169fV3kiaOvWraX/V94M0apVK5W00jwxrWDcLFz3uLg4NG7cGI0aNZLSXF1dZdtfuHABt27dgpmZmdQ2CwsLPH/+XGpfYYyDRETazdPTE+np6YiOjsbJkyfh5OSEevXqwd3dHdHR0UhPT0dkZCQaN24Me3v7l96fuj6sJuORyskvhoaG6N+/P0aNGoV58+ZJZWrSd3zy5Al2794tTfoB8ifLFBxDfRGMhURE2qcyXWMEgJ49eyI9PV3lZr2CRo4cKYuVn3zyCYD88U4vLy9YWloCyL/pMD09HeHh4WVeT3UYB4moPOlWdAXU8fT0xPr166Gnpwdra2vpNX/Ku91sbGzg6OgIR0dHmJqaYtCgQbh27Rrq1asnlVGjRg3pNbGFOTo6QqFQIC4uDgMHDix1/WbMmAEfHx8YGxujQYMGsgCwdOlSuLm5YcaMGQDyByhNTEzw5ptvYtGiRWjQoEGp96eOlZUVgPwnwRQs88GDBypPhVHHyckJAHD9+nWVAcyCHj16hL179yI7Oxvr16+X0nNzcxEUFIQvvvii1HX/5JNP8NFHH0mfU1NTGdyIiF6BwMBA5OTkSK8aAvI7M3p6enj8+DGcnJwQFxdXbBkvG0OVgoKCcPXqVWlSCZB/d3pgYCAmTpwIIP/vAX9/fzx8+FC6sx7Inwi6Zs0a9OzZU+XOek3aAJR8LGrXrg1HR0e8+eabCA4OhqenJzZu3Ihx48apvAZCX1+/yL85isJYSERUNPYHS6bN/UGAcZCISFsYGhqiR48e6NGjB+bOnYvx48dj3rx58PHxKXKbwq/3y8vLQ4MGDdQ+HVP5Or0ZM2bg8OHDWL58ORwcHGBkZITBgwervFpd+TcB8N8FOXVpyqe4ODk54dq1a2rrqew3Ojo6Fll3dTdOFL4QmJeXh/bt2yM0NFQlb8FJpQUxDhIRaTcHBwc0atQIERERePz4Mdzd3QHk99OaNGmC06dPIyIiQnbz+stQxiw7OzspTZPxyJEjR2L27NkwMDCAtbU1dHR0pHWajqFu2bIFz58/R8eOHaU0IQTy8vJw7do1uLi4lLI1+RgLiYi0T2W6xggA3bp1w9SpUzFgwADk5uaqfSOTubm5SrzMzc3Fpk2bkJycLLtGmZubi8DAQPTs2VMaO42Li0Pbtm1fqp7qMA4SUXmqlE8ENTExgYODA2xtbWWDeeq4u7ujZcuWJT55qyALCwt4eXlh7dq1SE9PV1n/5MmTYre3tLSEg4MDrK2tVQb/MjIyVCaIKDtXpXnqSkmaNGkCKysr/Prrr1JaVlYWjh8/js6dO5e4fc+ePWFpaYlly5apXa88BqGhoWjUqBEuXboku1ti1apV2LhxI3JyckpddwMDA9SsWVO2EBFR+crJycGmTZuwYsUK2fn80qVLsLW1RWhoKEaMGIHw8HDExMSo3T49Pf2lYyiQ/+qi8+fPIzIyUlaXEydOIDo6Gr///juA/+6u/+qrr+Do6ChNbHF3d8f58+dx4MABNGnSBLa2tlLZmrRBk2Oh5Ovri927dyMsLAz37t3DuHHjSmyfJhgLiYiKxv5gybS5PwgwDhIRaSsXFxcpdurp6SE3N7fEbV577TXpApuDg4NsUT595eTJk/Dx8cH//d//oVWrVrCyspK9/vZFeXt7Iz4+Hj///LPKuhUrVqBOnTro0aNHkdu7uLjg7t27uH//vpR25swZlfbFx8ejXr16Ku0zNzdXWy7jIBGR9vP09ERkZKTsLUZAfh/18OHDOHv2bJm8Fv7Zs2f4/vvv0bVr1yJvMCiKcvKLjY2NbBIokD+GevPmTfz0008q2wkhkJKSAiB/0k9AQIDKGKqnp+dLPRWUsZCISLtUpmuMBfXo0QP79+9HUFAQ/Pz8NBp/PXjwIJ4+fYqYmBhZW3bu3Im9e/fi4cOHaNu2LVxcXLBixQrpRsOXqWdhjINEVJ4q5UTQ0goICMB3332Hv/76S0oTQiA5OVllUZ6o161bh9zcXHTo0AFhYWGIj49HXFwcVq9eXewTUUrSr18/7N69G+vXr8ft27dx+vRpTJ06FR06dIC1tTWA/At0yoCSlZWFv/76C7Gxsbh165ZUTlpampQHABISEhAbGyu9EkmhUGDatGlYsmQJ9uzZg99//116Ks2IESNKrKeJiQk2bNiAAwcOoH///ggPD0diYiLOnz+PmTNnSq8uDAwMxODBg9GyZUvZ8u677+LJkyc4cODACx8rIiJ6dfbv34/Hjx/D19dX5Zw+ePBgBAYGYtq0aXBzc0O3bt2wdu1aXLp0Cbdv38aOHTvQsWNHxMfHA3j5GBoYGIgOHTqga9eusnp06dIFrq6uCAwMBADY29ujcePGWLNmjXRnPQBYW1vD1tYW3377rcqAqiZt0ORYKA0ZMgR6enqYNGkSunXrJrvzXiknJ0fl742///77Rb4mIiJ6AewPsj9IRERl6+HDh3jrrbfw448/4vLly0hISMDOnTuxbNkyDBgwAED+U8mOHj2K5ORkPH78uMiyunfvDldXVwwcOBCHDx9GYmIioqKiMGfOHJw/fx5A/pPVdu/eLV1IHDFihNqLbaXl7e2N//u//8PYsWMRGBiIxMREXL58GZMmTcK+ffuwYcMGlaeAFq67s7MzxowZg0uXLuHkyZOYPXu2LM/IkSNhaWmJAQMG4OTJk0hISMDx48fh7++Pe/fuvXQbiIiocvL09MSpU6cQGxsrG7d0d3fHDz/8gOfPn7/QRNAHDx4gOTkZ8fHx2LZtG9zc3PDvv//K3tAAvPx45NChQzFs2DAMHz4cS5cuxfnz53Hnzh3s378f3bt3R0REBGJjY3Hx4kWMHz9epU84fPhwbNq0CdnZ2aVuIxERaZ/KdI2xsLfeegsHDhzAxo0bNZoMGhgYiD59+qBNmzaydgwaNAh169bFjz/+CIVCgeDgYNy8eRNdu3bFwYMHcfv2bVy+fBmLFy+W+sVERJWSqGTGjh0rBgwYoHZdQkKCACBiYmJk6Xl5ecLZ2Vm89957QgghgoODBQC1S1JSkrTd/fv3hZ+fn7C1tRX6+vqiYcOGon///iIiIkLKY2trK1auXFnkZ3VWr14tXFxchJGRkWjQoIEYOXKkuHfvnko7Ci/u7u5SnoiICLV5xo4dK2v3vHnzhJWVlTAwMBBdu3YVV65cKbZuhUVHR4t33nlH1K1bVxgYGAgHBwcxceJEER8fL86fPy8AiHPnzqndtl+/fqJfv37S53nz5ok2bdqUav9CCJGSkiIAiJSUlFJvS0TVA88TL69v376id+/eatdduHBBABAXLlwQz58/F0uXLhWtWrUShoaGwsLCQri5uYmQkBCRnZ0tbaNJDFUnMzNT1KlTRyxbtkzt+hUrVghLS0uRmZkphMj/uwCA2LZtmyyfr6+vACA2b96sUkZJbdD0WChNnDhRABBbtmxRyT9v3jy18drAwKDY41AYf+NEVJLqcp5gfzBfdeoPClF9ft9E9OJ4nni1nj9/Lj7++GPx2muvCXNzc2FsbCycnZ3FnDlzREZGhhBCiH379gkHBwehq6srbG1thRBFx4LU1FQxZcoUYW1tLfT09ISNjY0YOXKkuHv3rhAiPzZ6enoKIyMjYWNjI7755hvh7u4u/P39pTLUxWAAYs+ePdJndX8rZGdni+XLl4sWLVoIAwMDUbNmTeHl5SVOnjwpK6uout+4cUN06dJF6OvrCycnJ3Ho0CGV/SYlJYkxY8YIS0tLYWBgIOzt7cWECRM0/r3y901EJeF5ovJRxpxmzZrJ0v/8808BQDRt2lTtdkX1eQv2ARUKhTAzMxNt2rQRM2bMkPVjhdBsPLJwHFUnNzdXrF+/XrzxxhvC2NhY1KxZU7Rv3158/fXXIiMjQ3zwwQfCxcVF7bYPHjwQOjo6IiwsTErTpL9cFP7GiagkPE9UrMpyjVFJXcw5fvy4MDU1FZMmTRJ5eXlqY2FycrLQ1dUVO3bsUFvulClTRKtWraTPN27cEGPGjBHW1tZCX19f2NraiuHDh4uLFy+qbKtJ7C0Kf99EVJLSnCcUQpTh++mIXkBqairMzc2RkpLCx14TkVo8T1BVx984EZWE5wmqyvj7JqKS8DxBVRl/30RUEp4nqKrjb5yISsLzBFVl/H0TUUlKc56oEq+GJyIiIiIiIiIiIiIiIiIiIiIiIiKqjjgRtIoKDQ2Fqamp2qVFixYVXT0iIqrCGIOIiIgqFmMxERERERERERERaRuOaxIRvRzdiq4AlY/+/fujY8eOatfp6em94toQEVF1whhERERUsRiLiYiIiIiIiIiISNtwXJOI6OVwImgVZWZmBjMzs4quBhERVUOMQURERBWLsZiIiIiIiIiIiIi0Dcc1iYheDl8NT0RERERERERERERERERERERERESkpTgRlIiIiIiIiIiIiIiIiIiIiIiIiIhIS3EiKBERERERERERERERERERERERERGRluJEUCIiIiIiIiIiIiIiIiIiIiIiIiIiLcWJoEREREREREREREREREREREREREREWooTQYmIiIiIiIiIiIiIiIiIiIiIiIiItBQnghIRERERERERERERERERERERERERaSlOBCUiIiIiIiIiIiIiIiIiIiIiIiIi0lKc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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAACVUAAAGMCAYAAADQ/tCMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAAEAAElEQVR4nOzdd1gUV9sG8BuBpQkIooKKiIItdjSKxhZFNMbeErtBo7G3RIm+ERvYRY3dCJooErvGrq8NsSKWxG5UUMFKVSnC+f6Yj3l33QUWBHbR+3dde7k7e+bMM7vLPO7OM+cYCCEEiIiIiIiIiIiIiIiIiIiIiIiICABQRNcBEBERERERERERERERERERERER6RMWVRERERERERERERERERERERERESlhURUREREREREREREREREREREREZESFlUREREREREREREREREREREREREpYVEVERERERERERERERERERERERGREhZVERERERERERERERERERERERERKWFRFRERERERERERERERERERERERkRIWVRERERERERERERERERERERERESlhURUREREREREREREREREREREREZESFlURERERERERERERFZAJEyagYsWKMDU1RalSpTBixAikpqbqOiwiIiIiIiIieg+LqoiIiIiI6KPg4+MDAwMDtZuVlRXc3d2xcuVKpKenF3hcAwYMkGM5fvy4vDxjWfny5XPcZ2xsLHx8fODj44PAwMA8i/V95cuXl+PUR3v27EHnzp1RpkwZmJiYwNraGnXr1sXkyZMRHR2t1r558+by/jx48KDgA9ZTOXmfAwMDVf6+XFxc1P6uHj9+DGNjY5V2N2/ezK/wc+3BgwdyfM2bNy+w7WYcE5SPB/pk2rRpMDAwQKlSpfDmzRsAunutCiPlXJQfx+dDhw6hcePGKFasmLydnTt3Zrrd48ePy/ni8uXLeR6PPrpw4QK8vLxQqVIlWFhYoGjRoqhcuTL69euHw4cPAwBcXV3l12vfvn0a++nbt6/cZtq0aVluU9P/P8zNzfHZZ59h0qRJiIuLU2n/+PFj/Pjjjzh06BDc3NywbNkyrFu3Ltt9e/bsGfr164fSpUvDyMgIBgYG6NSpk3YvDOUZTf+fKMjj5IMHD+S/6507d6o9n9n/PfPT8OHDYWBggCpVqrBAkIiIiIiIPipGug6AiIiI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",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# ── XGBoost: one model per zone ────────────────────────────────────────────────────\n",
+ "#\n",
+ "# Each zone now uses its OWN feature set via feature_cols_for(zone): the base\n",
+ "# CONUS predictors (unchanged) plus that zone's HydraulicRadius/WetArea/Volume\n",
+ "# pulled from the gauge's own hydroTable at the zone's recurrence discharge\n",
+ "# (Step 0b) instead of the external file's mismatched static geometry.\n",
+ "#\n",
+ "# n per zone is only 54-68 gauges, so evaluation is k-fold CV throughout (not\n",
+ "# a single train/test split — see prior discussion on why that was unstable).\n",
+ "#\n",
+ "# NOTE: the CONUS-wide prediction step from earlier versions is dropped here —\n",
+ "# it needs zone-specific geometry for ~2.16M ungauged COMIDs, which only\n",
+ "# exists where we've already run HAND (i.e. for these gauges themselves).\n",
+ "# This cell is now a training/CV diagnostic only, not a deployable regionalizer.\n",
+ "\n",
+ "from xgboost import XGBRegressor\n",
+ "from sklearn.model_selection import KFold, cross_val_score\n",
+ "from sklearn.metrics import mean_squared_error, r2_score\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "\n",
+ "XGB_PARAMS = dict(\n",
+ " n_estimators=200,\n",
+ " max_depth=3,\n",
+ " learning_rate=0.05,\n",
+ " subsample=0.8,\n",
+ " colsample_bytree=0.8,\n",
+ " min_child_weight=3,\n",
+ " reg_alpha=0.5,\n",
+ " reg_lambda=1.0,\n",
+ " random_state=42,\n",
+ " n_jobs=-1,\n",
+ ")\n",
+ "CV_FOLDS = 5\n",
+ "\n",
+ "zone_data = {}\n",
+ "zone_features = {}\n",
+ "for zone in TARGET_COLS:\n",
+ " cols = feature_cols_for(zone)\n",
+ " df_zone = df_ml[cols + [zone]].dropna()\n",
+ " zone_data[zone] = df_zone\n",
+ " zone_features[zone] = cols\n",
+ " print(f\"{zone}: {len(df_zone)} training samples after dropping NaN (features: {cols[-3:]})\")\n",
+ "\n",
+ "if max(len(d) for d in zone_data.values()) < 3:\n",
+ " print(\"⚠ Too few samples — add more HUCs to HUC.txt and re-run.\")\n",
+ "else:\n",
+ " models = {}\n",
+ " metrics = {}\n",
+ " Xs = {}\n",
+ " ys = {}\n",
+ "\n",
+ " for zone in TARGET_COLS:\n",
+ " df_zone = zone_data[zone]\n",
+ " cols = zone_features[zone]\n",
+ " X = df_zone[cols].values\n",
+ " y = df_zone[zone].values\n",
+ " n_samples = len(df_zone)\n",
+ " Xs[zone] = X\n",
+ " ys[zone] = y\n",
+ "\n",
+ " if n_samples < 3:\n",
+ " print(f\"⚠ {zone}: too few samples ({n_samples}) — skipping\")\n",
+ " continue\n",
+ "\n",
+ " xgb = XGBRegressor(**XGB_PARAMS)\n",
+ " cv = KFold(n_splits=min(n_samples, CV_FOLDS), shuffle=True, random_state=42)\n",
+ " neg_mse = cross_val_score(xgb, X, y, cv=cv, scoring=\"neg_mean_squared_error\")\n",
+ " r2_cv = cross_val_score(xgb, X, y, cv=cv, scoring=\"r2\")\n",
+ " rmse = float(np.sqrt(-neg_mse.mean()))\n",
+ " r2 = float(r2_cv.mean())\n",
+ " xgb.fit(X, y) # refit on full data for feature importance\n",
+ " metrics[zone] = {\"RMSE\": rmse, \"R2\": r2, \"mode\": f\"{cv.get_n_splits()}-fold CV\", \"n\": n_samples}\n",
+ "\n",
+ " models[zone] = xgb\n",
+ "\n",
+ " # ── Print metrics table ──────────────────────────────────────────────────────────\n",
+ " print(f\"\\n{'Zone':<10}{'Mode':<14}{'n':>5}{'RMSE':>8}{'R²':>8}\")\n",
+ " print(\"-\" * 47)\n",
+ " for zone, m in metrics.items():\n",
+ " print(f\"{zone:<10}{m['mode']:<14}{m['n']:>5}{m['RMSE']:>8.4f}{m['R2']:>8.3f}\")\n",
+ "\n",
+ " trained_zones = list(models.keys())\n",
+ "\n",
+ " # ── Feature importance per zone ──────────────────────────────────────────────────\n",
+ " fig, axes = plt.subplots(\n",
+ " 1, len(trained_zones),\n",
+ " figsize=(4.5 * len(trained_zones), 5),\n",
+ " sharey=False,\n",
+ " )\n",
+ " if len(trained_zones) == 1:\n",
+ " axes = [axes]\n",
+ " for ax, zone in zip(axes, trained_zones):\n",
+ " cols = zone_features[zone]\n",
+ " imp = models[zone].feature_importances_\n",
+ " order = np.argsort(imp)\n",
+ " ax.barh([cols[i] for i in order], imp[order], color=\"#4a90d9\")\n",
+ " ax.set_title(f\"{zone}\\nRMSE={metrics[zone]['RMSE']:.4f} R²={metrics[zone]['R2']:.3f}\",\n",
+ " fontsize=10)\n",
+ " ax.set_xlabel(\"Importance (gain)\")\n",
+ " fig.suptitle(\"XGBoost Feature Importance — Manning's n per Zone\",\n",
+ " fontweight=\"bold\", fontsize=12)\n",
+ " plt.tight_layout()\n",
+ " plt.show()\n",
+ "\n",
+ " # ── Predicted vs observed (full-data refit, in-sample) ───────────────────────────\n",
+ " fig, axes = plt.subplots(\n",
+ " 1, len(trained_zones),\n",
+ " figsize=(4 * len(trained_zones), 4),\n",
+ " )\n",
+ " if len(trained_zones) == 1:\n",
+ " axes = [axes]\n",
+ " for ax, zone in zip(axes, trained_zones):\n",
+ " y = ys[zone]\n",
+ " y_hat = models[zone].predict(Xs[zone])\n",
+ " ax.scatter(y, y_hat, alpha=0.75, s=40, edgecolors=\"k\", linewidths=0.4)\n",
+ " lo, hi = min(y.min(), y_hat.min()), max(y.max(), y_hat.max())\n",
+ " ax.plot([lo, hi], [lo, hi], \"r--\", lw=1.2)\n",
+ " ax.set_xlabel(\"Observed n\")\n",
+ " ax.set_ylabel(\"Predicted n (in-sample)\")\n",
+ " ax.set_title(f\"{zone} CV R²={metrics[zone]['R2']:.3f}\", fontsize=10)\n",
+ " fig.suptitle(\"Predicted vs Observed Manning's n (in-sample fit; see CV R² for generalization)\",\n",
+ " fontweight=\"bold\", fontsize=12)\n",
+ " plt.tight_layout()\n",
+ " plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "id": "b17a2c40",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:38.780922Z",
+ "iopub.status.busy": "2026-07-10T12:09:38.780922Z",
+ "iopub.status.idle": "2026-07-10T12:09:59.232991Z",
+ "shell.execute_reply": "2026-07-10T12:09:59.232991Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Zone Model n RMSE R²\n",
+ "---------------------------------------\n",
+ "n_2yr XGB 83 0.0496 0.236\n",
+ " Ridge 83 0.0444 0.305\n",
+ " Lasso 83 0.0468 0.232\n",
+ " RF 83 0.0500 0.164\n",
+ "\n",
+ "n_5yr XGB 82 0.0600 0.140\n",
+ " Ridge 82 0.0597 0.115\n",
+ " Lasso 82 0.0653 -0.173\n",
+ " RF 82 0.0583 0.193\n",
+ "\n",
+ "n_10yr XGB 82 0.0596 0.227\n",
+ " Ridge 82 0.0582 0.255\n",
+ " Lasso 82 0.0627 0.107\n",
+ " RF 82 0.0588 0.239\n",
+ "\n",
+ "n_25yr XGB 73 0.0540 0.007\n",
+ " Ridge 73 0.0460 0.223\n",
+ " Lasso 73 0.0497 0.096\n",
+ " RF 73 0.0499 0.130\n",
+ "\n",
+ "n_50yr XGB 64 0.0605 0.039\n",
+ " Ridge 64 0.0567 0.166\n",
+ " Lasso 64 0.0541 0.252\n",
+ " RF 64 0.0577 0.145\n",
+ "\n",
+ "h0_elev_m XGB 96 43.0438 0.789\n",
+ " Ridge 96 57.9015 0.661\n",
+ " Lasso 96 52.1395 0.729\n",
+ " RF 96 55.8144 0.683\n",
+ "\n",
+ "Lasso non-zero coefficients (standardized) by zone:\n",
+ " n_2yr: alpha=0.005623 [('D50_mm_', -0.0004), ('HYDRLCONDCAT', -0.0013), ('WTDEPCAT', 0.0006), ('StreamOrde', -0.0159), ('ACC_OM', -0.0052), ('ACC_RFACT', 0.0031), ('ACC_AWCAVE', 0.0018), ('HYDRLCOND_WS', 0.0095), ('HydraulicRadius_2yr', 0.012), ('WetArea_2yr', 0.0044), ('Volume_2yr', 0.0198)]\n",
+ " n_5yr: alpha=0.001778 [('TotDASqKM', -0.0089), ('CAT_SILTAVE', -0.0122), ('D50_mm_', -0.0001), ('HYDRLCONDCAT', 0.0089), ('WTDEPCAT', 0.001), ('StreamOrde', -0.0238), ('EVI_JAS_2012', 0.0029), ('EVI_OND_2011', -0.0001), ('ACC_NO10AVE', 0.0243), ('ACC_NO200AVE', 0.0131), ('ACC_RFACT', 0.0098), ('ACC_WTDEP', 0.0255), ('HydraulicRadius_5yr', 0.0117), ('WetArea_5yr', 0.014), ('Volume_5yr', 0.0224)]\n",
+ " n_10yr: alpha=0.01778 [('Volume_10yr', 0.0098)]\n",
+ " n_25yr: alpha=0.01 [('TotDASqKM', -0.0006), ('CAT_SILTAVE', -0.0095), ('EVI_JAS_2012', 0.0016), ('EVI_JFM_2012', 0.0022), ('EVI_OND_2011', 0.0), ('Volume_25yr', 0.0166)]\n",
+ " n_50yr: alpha=0.005623 [('TotDASqKM', -0.0013), ('CAT_SILTAVE', -0.0058), ('WTDEPCAT', 0.0007), ('EVI_JAS_2012', 0.0035), ('WetArea_50yr', 0.0005), ('Volume_50yr', 0.0293)]\n",
+ " h0_elev_m: alpha=3.162 [('TotDASqKM', -8.9482), ('CAT_SILTAVE', 5.6873), ('D50_mm_', 18.2592), ('WTDEPCAT', 0.9641), ('PERMCAT', -3.6327), ('StreamOrde', -24.4894), ('ACC_OM', 24.622), ('ACC_RFACT', -10.1031), ('ACC_ROCKDEP', -45.8253), ('ACC_WTDEP', 27.9893)]\n",
+ "\n",
+ "Random Forest feature importances by zone:\n",
+ " n_2yr: top features [('Volume_2yr', 0.265), ('WetArea_2yr', 0.132), ('QE_cms', 0.104), ('TotDASqKM', 0.089)]\n",
+ " n_5yr: top features [('Volume_5yr', 0.271), ('WetArea_5yr', 0.113), ('TotDASqKM', 0.081), ('QE_cms', 0.071)]\n",
+ " n_10yr: top features [('Volume_10yr', 0.303), ('WetArea_10yr', 0.09), ('D50_mm_', 0.066), ('QE_cms', 0.056)]\n",
+ " n_25yr: top features [('Volume_25yr', 0.196), ('CAT_SILTAVE', 0.1), ('ACC_NO4AVE', 0.092), ('WetArea_25yr', 0.066)]\n",
+ " n_50yr: top features [('Volume_50yr', 0.282), ('WetArea_50yr', 0.133), ('ACC_NO4AVE', 0.072), ('CAT_SILTAVE', 0.044)]\n",
+ " h0_elev_m: top features [('ACC_WTDEP', 0.332), ('HYDRLCOND_WS', 0.099), ('ACC_NO10AVE', 0.094), ('ACC_ROCKDEP', 0.07)]\n"
+ ]
+ }
+ ],
+ "source": [
+ "# ── Simpler models: Ridge / Lasso / Random Forest ─────────────────────────────────\n",
+ "#\n",
+ "# Same per-zone feature set as the XGBoost cell above (feature_cols_for(zone),\n",
+ "# own-hydroTable geometry). 54-68 gauges per zone with ~19 features is thin\n",
+ "# for a flexible non-linear model; Ridge/Lasso are lower-variance at this N,\n",
+ "# and Lasso's surviving coefficients double as a feature-selection check.\n",
+ "\n",
+ "from sklearn.linear_model import RidgeCV, LassoCV\n",
+ "from sklearn.ensemble import RandomForestRegressor\n",
+ "from sklearn.pipeline import make_pipeline\n",
+ "from sklearn.preprocessing import StandardScaler\n",
+ "from sklearn.model_selection import KFold, cross_val_score\n",
+ "\n",
+ "ALPHAS = np.logspace(-3, 3, 25)\n",
+ "RF_PARAMS = dict(\n",
+ " n_estimators=300,\n",
+ " max_depth=4,\n",
+ " min_samples_leaf=3,\n",
+ " max_features=0.6,\n",
+ " random_state=42,\n",
+ " n_jobs=-1,\n",
+ ")\n",
+ "OTHER_MODELS = {\n",
+ " \"Ridge\": lambda: make_pipeline(StandardScaler(), RidgeCV(alphas=ALPHAS)),\n",
+ " \"Lasso\": lambda: make_pipeline(StandardScaler(), LassoCV(alphas=ALPHAS, max_iter=20000, random_state=42)),\n",
+ " \"RF\": lambda: RandomForestRegressor(**RF_PARAMS),\n",
+ "}\n",
+ "\n",
+ "other_metrics = {}\n",
+ "other_fitted = {}\n",
+ "for zone in TARGET_COLS:\n",
+ " df_zone = zone_data[zone]\n",
+ " cols = zone_features[zone]\n",
+ " X = df_zone[cols].values\n",
+ " y = df_zone[zone].values\n",
+ " n_samples = len(df_zone)\n",
+ " if n_samples < 3:\n",
+ " continue\n",
+ " cv = KFold(n_splits=min(n_samples, CV_FOLDS), shuffle=True, random_state=42)\n",
+ " for name, make_model in OTHER_MODELS.items():\n",
+ " model = make_model()\n",
+ " neg_mse = cross_val_score(model, X, y, cv=cv, scoring=\"neg_mean_squared_error\")\n",
+ " r2_cv = cross_val_score(model, X, y, cv=cv, scoring=\"r2\")\n",
+ " rmse = float(np.sqrt(-neg_mse.mean()))\n",
+ " r2 = float(r2_cv.mean())\n",
+ " model.fit(X, y) # refit on full data for coefficients / importances\n",
+ " other_metrics[(zone, name)] = {\"RMSE\": rmse, \"R2\": r2, \"n\": n_samples}\n",
+ " other_fitted[(zone, name)] = model\n",
+ "\n",
+ "# ── Comparison table: XGBoost vs Ridge vs Lasso vs RF ─────────────────────────────\n",
+ "print(f\"{'Zone':<10}{'Model':<8}{'n':>5}{'RMSE':>8}{'R²':>8}\")\n",
+ "print(\"-\" * 39)\n",
+ "for zone in TARGET_COLS:\n",
+ " if zone not in metrics:\n",
+ " continue\n",
+ " print(f\"{zone:<10}{'XGB':<8}{metrics[zone]['n']:>5}{metrics[zone]['RMSE']:>8.4f}{metrics[zone]['R2']:>8.3f}\")\n",
+ " for name in OTHER_MODELS:\n",
+ " m = other_metrics.get((zone, name))\n",
+ " if m:\n",
+ " print(f\"{'':<10}{name:<8}{m['n']:>5}{m['RMSE']:>8.4f}{m['R2']:>8.3f}\")\n",
+ " print()\n",
+ "\n",
+ "# ── Lasso coefficients (which predictors survive shrinkage) ──────────────────────\n",
+ "print(\"Lasso non-zero coefficients (standardized) by zone:\")\n",
+ "for zone in TARGET_COLS:\n",
+ " pipe = other_fitted.get((zone, \"Lasso\"))\n",
+ " if pipe is None:\n",
+ " continue\n",
+ " lasso = pipe.named_steps[\"lassocv\"]\n",
+ " cols = zone_features[zone]\n",
+ " nz = [(f, round(float(c), 4)) for f, c in zip(cols, lasso.coef_) if abs(c) > 1e-6]\n",
+ " print(f\" {zone}: alpha={lasso.alpha_:.4g} {nz if nz else '(all coefficients shrunk to 0)'}\")\n",
+ "\n",
+ "# ── RF feature importances ────────────────────────────────────────────────────────\n",
+ "print(\"\\nRandom Forest feature importances by zone:\")\n",
+ "for zone in TARGET_COLS:\n",
+ " rf = other_fitted.get((zone, \"RF\"))\n",
+ " if rf is None:\n",
+ " continue\n",
+ " cols = zone_features[zone]\n",
+ " order = np.argsort(rf.feature_importances_)[::-1]\n",
+ " top = [(cols[i], round(float(rf.feature_importances_[i]), 3)) for i in order[:4]]\n",
+ " print(f\" {zone}: top features {top}\")"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "id": "6a203e88",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:59.235016Z",
+ "iopub.status.busy": "2026-07-10T12:09:59.235016Z",
+ "iopub.status.idle": "2026-07-10T12:09:59.237630Z",
+ "shell.execute_reply": "2026-07-10T12:09:59.237630Z"
+ }
+ },
+ "outputs": [],
+ "source": [
+ "# CONUS-wide prediction is not produced in this version: the corrected\n",
+ "# HydraulicRadius/WetArea/Volume features only exist where we already have a\n",
+ "# hydroTable (i.e. for the calibrated gauges), not for the ~2.16M ungauged\n",
+ "# CONUS reaches in the predictor file. Deploying a regionalizer would need\n",
+ "# either (a) accepting the external file's mismatched geometry again for\n",
+ "# CONUS-scale prediction, or (b) computing HAND geometry ourselves at CONUS\n",
+ "# scale — both bigger decisions than this notebook should make silently."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "geom-compare-md",
+ "metadata": {},
+ "source": [
+ "### Geometry source comparison: own hydroTable (zone-specific) vs external CONUS file (static)\n",
+ "\n",
+ "Same 125-gauge dataset, same models, same CV setup -- only the\n",
+ "HydraulicRadius/WetArea/Volume features differ: zone-specific values from\n",
+ "each gauge's own hydroTable (what we've been using) vs the external CONUS\n",
+ "predictor file's static values (verified earlier not to match this\n",
+ "pipeline's geometry for the same reach, but the only version available for\n",
+ "ungauged reaches). This isolates how much of the improvement came from more\n",
+ "gauges vs. from fixing the geometry mismatch, and shows what a genuinely\n",
+ "CONUS-deployable model's performance ceiling looks like with today's data."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "id": "geom-compare-code",
+ "metadata": {
+ "execution": {
+ "iopub.execute_input": "2026-07-10T12:09:59.239634Z",
+ "iopub.status.busy": "2026-07-10T12:09:59.239634Z",
+ "iopub.status.idle": "2026-07-10T12:10:09.813504Z",
+ "shell.execute_reply": "2026-07-10T12:10:09.813504Z"
+ }
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Zone Model n OwnGeom R² ExtGeom R²\n",
+ "-----------------------------------------------\n",
+ "n_2yr XGB 83/83 0.236 -0.274\n",
+ " Ridge 0.305 -0.262\n",
+ " Lasso 0.232 -0.172\n",
+ " RF 0.164 -0.601\n",
+ "\n",
+ "n_5yr XGB 82/82 0.140 -0.027\n",
+ " Ridge 0.115 -0.049\n",
+ " Lasso -0.173 0.018\n",
+ " RF 0.193 -0.074\n",
+ "\n",
+ "n_10yr XGB 82/82 0.227 0.069\n",
+ " Ridge 0.255 -0.074\n",
+ " Lasso 0.107 -0.054\n",
+ " RF 0.239 -0.035\n",
+ "\n",
+ "n_25yr XGB 73/73 0.007 -0.045\n",
+ " Ridge 0.223 -0.195\n",
+ " Lasso 0.096 -0.165\n",
+ " RF 0.130 0.005\n",
+ "\n",
+ "n_50yr XGB 64/64 0.039 -0.092\n",
+ " Ridge 0.166 -0.553\n",
+ " Lasso 0.252 -0.158\n",
+ " RF 0.145 -0.089\n",
+ "\n",
+ "h0_elev_m XGB 96/122 0.789 0.881\n",
+ " Ridge 0.661 0.712\n",
+ " Lasso 0.729 0.715\n",
+ " RF 0.683 0.815\n",
+ "\n"
+ ]
+ }
+ ],
+ "source": [
+ "from sklearn.model_selection import KFold, cross_val_score\n",
+ "\n",
+ "ext_metrics = {}\n",
+ "for zone in TARGET_COLS:\n",
+ " df_zone = df_ml[EXT_FEATURE_COLS + [zone]].dropna()\n",
+ " X = df_zone[EXT_FEATURE_COLS].values\n",
+ " y = df_zone[zone].values\n",
+ " n_samples = len(df_zone)\n",
+ " if n_samples < 3:\n",
+ " continue\n",
+ " cv = KFold(n_splits=min(n_samples, CV_FOLDS), shuffle=True, random_state=42)\n",
+ "\n",
+ " row = {\"n\": n_samples}\n",
+ " xgb = XGBRegressor(**XGB_PARAMS)\n",
+ " row[\"XGB\"] = float(cross_val_score(xgb, X, y, cv=cv, scoring=\"r2\").mean())\n",
+ " for name, make_model in OTHER_MODELS.items():\n",
+ " model = make_model()\n",
+ " row[name] = float(cross_val_score(model, X, y, cv=cv, scoring=\"r2\").mean())\n",
+ " ext_metrics[zone] = row\n",
+ "\n",
+ "print(f\"{'Zone':<10}{'Model':<8}{'n':>5}{'OwnGeom R²':>12}{'ExtGeom R²':>12}\")\n",
+ "print(\"-\" * 47)\n",
+ "for zone in TARGET_COLS:\n",
+ " if zone not in ext_metrics:\n",
+ " continue\n",
+ " own_n = metrics[zone][\"n\"]\n",
+ " ext_n = ext_metrics[zone][\"n\"]\n",
+ " print(f\"{zone:<10}{'XGB':<8}{f'{own_n}/{ext_n}':>5}{metrics[zone]['R2']:>12.3f}{ext_metrics[zone]['XGB']:>12.3f}\")\n",
+ " for name in OTHER_MODELS:\n",
+ " own_r2 = other_metrics.get((zone, name), {}).get(\"R2\")\n",
+ " ext_r2 = ext_metrics[zone].get(name)\n",
+ " own_s = f\"{own_r2:.3f}\" if own_r2 is not None else \" n/a\"\n",
+ " ext_s = f\"{ext_r2:.3f}\" if ext_r2 is not None else \" n/a\"\n",
+ " print(f\"{'':<10}{name:<8}{'':>5}{own_s:>12}{ext_s:>12}\")\n",
+ " print()"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "si_ML",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
diff --git a/scripts/README.md b/scripts/README.md
new file mode 100644
index 0000000..b0a6f63
--- /dev/null
+++ b/scripts/README.md
@@ -0,0 +1,59 @@
+# FIMbox pipeline scripts
+
+Run everything with `.venv\Scripts\python.exe scripts/.py` **from the
+repo root** (several scripts resolve `data/` and other paths relative to the
+working directory).
+
+## 1. Pipeline run order
+
+| # | Script | What it does |
+|---|---|---|
+| 0 | `s00_study_boundary.py` | Builds the study-area boundary from `data/study_area.xlsx` (run once) |
+| 1 | `s01_download_dem_fast.py` | Downloads the 10 m 3DEP DEM for the study area |
+| 2 | `s02_stage1_all_hucs.py` | Stage 1 — data download, per HUC8 |
+| 3 | `s03_stage2_all_hucs.py` | Stage 2 — HAND processing, produces SRCs + hydroTables per branch |
+| 3b | `s03b_fix_nonmonotonic_srcs.py` | **Run right after s03.** Forces every rating curve monotone (raster artifacts from HAND geometry can otherwise make discharge dip with rising stage). Fixed ~3,000 curves study-wide in the last full run. |
+| 4 | `s04_usgs_gage_crosswalk_all_hucs.py` | Crosswalks USGS gauges onto branches/HydroIDs; writes `usgs_elev_table.csv` per HUC |
+| 5 | `s05d_calibrate_B3_wedge_continuity.py` | **Manning's n calibration — the production method.** See §2. |
+| 6 | `s06_stage3_all_hucs.py` | Streamflow / feature-ID extraction for a forecast event |
+| 7 | `s07_stage4_all_hucs.py` | **Ablation baseline only** — OWP's own channel/overbank calibration. Overwrites the B3 hydroTables. Do not run this in the main sequence; only run it (on a restored baseline) when producing the L0/L1/L2 comparison arms against B3. |
+| 8 | `s08_stage5_all_hucs.py` | FIM generation — inundation depth/extent rasters |
+
+## 2. Calibration — how n is calibrated and why B3 was chosen
+
+- **`s05_ncalib_core.py`** — the shared engine. Not run directly; everything
+ below imports it. Handles the starting-point match (datum/bathymetry
+ correction), conveyance smoothing, and both n-application schemes
+ (whole-section and incremental).
+- **`s05d_calibrate_B3_wedge_continuity.py`** — **the method actually applied
+ in production.** Continuity-wedge starting-point match + incremental
+ (slice) n application. Writes both n definitions to every calibrated
+ hydroTable: `zonal_n_applied`/`n_{yr}yr` (slice n — drives `discharge_cms`,
+ what FIM consumes) and `whole_section_n`/`n_eff_{yr}yr` (an independently
+ calibrated whole-section curve, `discharge_cms_wholesection`, kept for
+ comparison with OWP's 0.06/0.12 defaults — not used by FIM).
+- **`s05a`/`s05b`/`s05c`** (methods A, B1, B2) — the three *rejected*
+ starting-point corrections. Kept only so the method comparison is
+ reproducible — **do not use for production runs.**
+- **`s05e_evaluate_methods.py`** — reruns A/B1/B2/B3 offline (reads baseline
+ backups, writes nothing to the pipeline) and produces the evidence for
+ choosing B3. Output: `E:/SI/out/calibration_analysis/method_evaluation/`.
+- **`s05f_evaluate_schemes.py`** — same idea for whole-section vs incremental
+ n application; justifies the incremental choice. Output:
+ `E:/SI/out/calibration_analysis/scheme_evaluation/`.
+- Full narrative + evidence: `docs/method_decision_deck.pptx`.
+
+## 3. Analysis & export
+
+| Script | Produces | Output folder |
+|---|---|---|
+| `plot_v2_diagnostics.py` | Datum-gap, clip-rate, n-profile, anchor-residual, hold-out validation, and starting-point figures + one RC panel per calibrated gauge | `E:/SI/out/calibration_analysis/v2_diagnostics/` |
+| `plot_calibration_analysis.py` | Study-area aggregate plots (n distributions, Q scatter, coverage, metrics) + per-branch RC plots | `E:/SI/out/calibration_analysis/` and `E:/SI/out/HUC{huc8}/src_plots/` |
+| `plot_src_ensemble.py` | SRC ensemble comparisons (side-by-side, overlaid, normalized) across all calibrated gauges | `E:/SI/out/calibration_analysis/` |
+| `export_rc_panels_and_videos.py` | Consolidates all per-gauge RC panels into one folder in three annotation variants (slice n / whole-section n / both), plus a slideshow video per variant | `E:/SI/out/calibration_analysis/rc_panels_export/` |
+
+## `legacy/`
+
+Retired scripts from earlier phases of the project (single-HUC prototypes,
+the old monolithic calibration script, earlier plotting tools) — kept for
+history, not maintained. See `legacy/README.md` for what superseded each one.
diff --git a/scripts/export_rc_panels_and_videos.py b/scripts/export_rc_panels_and_videos.py
new file mode 100644
index 0000000..8f12b77
--- /dev/null
+++ b/scripts/export_rc_panels_and_videos.py
@@ -0,0 +1,197 @@
+"""
+Consolidate per-gauge RC panels into one export folder and render them as
+slideshow videos — three variants of the SAME calibrated curve, differing
+only in which n definition is annotated in the title:
+
+ slice/ annotated with slice n (applied, incremental scheme)
+ wholesection/ annotated with whole-section n (effective, back-computed)
+ both/ annotated with both definitions stacked
+
+Outputs (one consolidated location):
+ E:/SI/out/calibration_analysis/rc_panels_export/
+ slice/{NNN}_{huc8}_{loc}.png
+ wholesection/{NNN}_{huc8}_{loc}.png
+ both/{NNN}_{huc8}_{loc}.png
+ video_slice_n.mp4
+ video_wholesection_n.mp4
+ video_both_n.mp4
+
+Reuses the data-assembly logic from plot_v2_diagnostics.py (same anchors,
+same baseline/calibrated hydroTable curves) — only the panel's annotation
+and output path differ. Panels are numbered in a fixed (huc8, location_id)
+sort order so the three videos show gauges in the same sequence.
+
+Run AFTER plot_v2_diagnostics.py (needs ncalib_diagnostics.csv per HUC):
+ .venv\\Scripts\\python.exe scripts/export_rc_panels_and_videos.py
+"""
+from __future__ import annotations
+
+import logging
+from pathlib import Path
+
+import matplotlib as mpl
+mpl.use("Agg") # headless backend — TkAgg default is ~10-20x slower for batch savefig
+
+import imageio.v2 as imageio
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+
+import plot_v2_diagnostics as v2 # reuse load_shared / load_diagnostics / gauge_records
+
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans", "font.size": 10.5,
+ "axes.labelsize": 12, "axes.titlesize": 10.5, "axes.titleweight": "bold",
+ "axes.spines.top": False, "axes.spines.right": False,
+ "axes.grid": True, "grid.alpha": 0.20, "grid.linestyle": ":",
+ "legend.fontsize": 9.5, "legend.framealpha": 0.92, "figure.dpi": 140,
+})
+
+C_ORIG, C_CALIB, C_OBS = "#2471a3", "#c0392b", "#111111"
+C_WSEC = "#7f8c8d" # whole-section curve — same gray as the scheme evaluation
+RY = v2.RECURRENCE_YEARS
+
+EXPORT_DIR = Path("E:/SI/out/calibration_analysis/rc_panels_export")
+VARIANTS = ("slice", "wholesection", "both")
+FPS = 10
+HOLD_SECONDS = 1.5
+
+
+def n_line(d: pd.Series, col_prefix: str) -> str:
+ return " ".join(f"n({yr}) = {d[f'{col_prefix}_{yr}yr']:.3f}"
+ for yr in RY if pd.notna(d.get(f"{col_prefix}_{yr}yr")))
+
+
+def draw_panel(g: dict, anchors: list, s_o: pd.DataFrame, s_c: pd.DataFrame,
+ grc: pd.DataFrame, variant: str) -> plt.Figure:
+ fig, ax = plt.subplots(figsize=(9.5, 6.6), constrained_layout=True)
+
+ h_max = max(a[1] for a in anchors) * 1.6
+ q_max = max(a[2] for a in anchors) * 1.8
+
+ for i, (yr, h_r, _) in enumerate(anchors):
+ ax.axhspan(0 if i == 0 else anchors[i - 1][1], h_r,
+ color="#187E86", alpha=0.045 if i % 2 == 0 else 0.09)
+ if not grc.empty:
+ ax.plot(grc["flow_cms"], grc["hand"], color=C_OBS, lw=2.0,
+ label="USGS observed RC", zorder=5)
+ ax.plot(s_o["Discharge (m3s-1)"], s_o["Stage"], color=C_ORIG, lw=1.8,
+ label="Baseline SRC (n = 0.06)", zorder=4)
+
+ # The two calibrated curves are genuinely different objects: the slice
+ # (incremental) curve is what FIM consumes; the whole-section curve is an
+ # independently calibrated diagnostic (discharge_cms_wholesection column).
+ has_wsec = ("discharge_cms_wholesection" in s_c.columns
+ and s_c["discharge_cms_wholesection"].notna().any())
+ if variant in ("slice", "both"):
+ ax.plot(s_c["Discharge (m3s-1)"], s_c["Stage"], color=C_CALIB, lw=2.6,
+ ls="--", label="Calibrated SRC — slice n (applied)", zorder=6)
+ if variant in ("wholesection", "both") and has_wsec:
+ ax.plot(s_c["discharge_cms_wholesection"], s_c["Stage"], color=C_WSEC,
+ lw=2.2, ls="-.", label="Calibrated SRC — whole-section n",
+ zorder=5)
+ elif variant == "wholesection" and not has_wsec:
+ # single-anchor / all-pinned gauges: the two schemes coincide
+ ax.plot(s_c["Discharge (m3s-1)"], s_c["Stage"], color=C_WSEC, lw=2.2,
+ ls="-.", label="Calibrated SRC — whole-section n (= slice)",
+ zorder=5)
+ for yr, h_r, Q_r in anchors:
+ ax.scatter([Q_r], [h_r], s=52, color=C_CALIB, edgecolors="white",
+ linewidths=1.4, zorder=8)
+ ax.annotate(f"{yr}-yr", (Q_r, h_r), textcoords="offset points",
+ xytext=(7, -3), fontsize=8.5, color=C_CALIB, fontweight="bold")
+
+ d = g["diag"]
+ mode_txt = {"wedge_continuity": f"continuity wedge δ = {d['delta_m']:.2f} m",
+ "wedge_topwidth": f"TopWidth wedge δ = {d['delta_m']:.2f} m",
+ "q0_offset": f"baseflow offset Q₀ = {d['q0_cms']:.1f} m³/s"}.get(
+ d["mode"], d["mode"])
+
+ if variant == "slice":
+ n_txt = "Slice n (applied): " + n_line(d, "n")
+ elif variant == "wholesection":
+ n_txt = "Whole-section n (effective): " + n_line(d, "n_eff")
+ else: # both
+ n_txt = ("Slice n: " + n_line(d, "n") + "\n" +
+ "Whole-section n: " + n_line(d, "n_eff"))
+
+ ax.set_title(f"Gauge {g['location_id']} · HydroID {g['hydroid']} · "
+ f"HUC {g['huc8']}\n{mode_txt}\n{n_txt}", fontsize=9.5)
+ ax.set_xlim(0, q_max)
+ ax.set_ylim(0, h_max)
+ ax.set_xlabel("Discharge (m³/s)")
+ ax.set_ylabel("HAND stage (m)")
+ ax.legend(loc="lower right")
+ return fig
+
+
+def main():
+ for v in VARIANTS:
+ (EXPORT_DIR / v).mkdir(parents=True, exist_ok=True)
+
+ hucs = [str(int(c)).zfill(8)
+ for c in pd.read_excel(v2.EXCEL_PATH)[v2.HUC_CODE_COL]]
+ rc, recur = v2.load_shared()
+ diag = v2.load_diagnostics(hucs)
+ records = sorted(v2.gauge_records(diag, rc, recur),
+ key=lambda r: (r[0]["huc8"], r[0]["location_id"]))
+ log.info("Rendering %d gauges × %d variants", len(records), len(VARIANTS))
+
+ paths = {v: [] for v in VARIANTS}
+ for i, (g, anchors, s_o, s_c, grc) in enumerate(records, 1):
+ fname = f"{i:03d}_{g['huc8']}_{g['location_id']}.png"
+ for variant in VARIANTS:
+ fig = draw_panel(g, anchors, s_o, s_c, grc, variant)
+ out = EXPORT_DIR / variant / fname
+ fig.savefig(out, dpi=140, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ paths[variant].append(out)
+ if i % 20 == 0:
+ log.info(" %d/%d gauges rendered", i, len(records))
+ log.info("Rendered %d gauges → %s", len(records), EXPORT_DIR)
+
+ labels = {"slice": "Slice n (applied, incremental scheme)",
+ "wholesection": "Whole-section n (effective)",
+ "both": "Both n definitions"}
+ for variant in VARIANTS:
+ make_video(paths[variant], EXPORT_DIR / f"video_{variant}_n.mp4",
+ labels[variant])
+
+
+def make_video(png_paths: list[Path], out_path: Path, label: str) -> None:
+ if not png_paths:
+ log.warning("No frames for %s — skipping video", out_path.name)
+ return
+ frames = [imageio.imread(p) for p in png_paths]
+ h, w = frames[0].shape[:2]
+ # matplotlib bbox_inches='tight' can vary output pixel size slightly per
+ # panel — pad/crop every frame to a common canvas so the video encoder
+ # gets a constant frame size.
+ canvas_h = max(f.shape[0] for f in frames)
+ canvas_w = max(f.shape[1] for f in frames)
+ canvas_h += canvas_h % 2 # even dimensions for the video codec
+ canvas_w += canvas_w % 2
+
+ hold_frames = max(1, round(FPS * HOLD_SECONDS))
+ writer = imageio.get_writer(str(out_path), fps=FPS, codec="libx264",
+ quality=8, macro_block_size=None)
+ for f in frames:
+ padded = np.full((canvas_h, canvas_w, 3), 255, dtype=np.uint8)
+ fh, fw = f.shape[:2]
+ rgb = f[..., :3] if f.shape[-1] == 4 else f
+ padded[:fh, :fw] = rgb
+ for _ in range(hold_frames):
+ writer.append_data(padded)
+ writer.close()
+ log.info("Saved video (%s, %d gauges, %.0fs): %s",
+ label, len(png_paths), len(png_paths) * HOLD_SECONDS, out_path)
+
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/README.md b/scripts/legacy/README.md
new file mode 100644
index 0000000..c9913be
--- /dev/null
+++ b/scripts/legacy/README.md
@@ -0,0 +1,26 @@
+# Legacy scripts
+
+These files are retired — kept for history only, not maintained, and not
+part of the active pipeline. Each is superseded by a file in `scripts/`
+(see `../README.md` for the active set):
+
+| Legacy file | Superseded by |
+|---|---|
+| `s01_download_dem.py` | `s01_download_dem_fast.py` (reads AOI window from cloud-optimized GeoTIFFs directly — ~8x faster, no national VRT parse) |
+| `s02_stage1_single_huc.py` | `s02_stage1_all_hucs.py` |
+| `s03_stage2_single_huc.py` | `s03_stage2_all_hucs.py` |
+| `s04_usgs_gage_crosswalk.py` | `s04_usgs_gage_crosswalk_all_hucs.py` |
+| `s05_calibrate_n_recurrence.py` | `s05_ncalib_core.py` + `s05a`–`s05d` |
+| `s05_revert_uncalibrated_srcs.py` | Not needed — fixed a failure mode (trunk-branch averaging propagating onto ungauged reaches) that cannot occur under the new pipeline, which only ever touches gauged HydroIDs. Was hardcoded to one HUC (`03020102`) and the pre-correction `D:/SI/out` drive path. |
+| `s06_stage3_single_huc.py` | `s06_stage3_all_hucs.py` |
+| `s07_stage4_single_huc.py` | `s07_stage4_all_hucs.py` |
+| `s08_stage5_single_huc.py` | `s08_stage5_all_hucs.py` |
+| `plot_calibration_slides.py` | The method-decision deck (`docs/method_decision_deck.pptx`) and `plot_v2_diagnostics.py` |
+| `plot_src_calibration.py`, `plot_src_calibration_inset.py`, `plot_srcs.py` | `plot_v2_diagnostics.py`, `export_rc_panels_and_videos.py` |
+| `plot_workflow_chart.py` | — (superseded by the pipeline order documented in `../README.md`) |
+| `open_parquet.py` | Scratch one-liner; use `pandas.read_parquet` directly |
+
+`scripts/s05_calibrate_n_recurrence_all_hucs.py` (the old monolithic v2
+calibration script) is not moved here — it has local uncommitted edits that
+are intentionally being kept out of git history. It is also fully superseded
+by `s05_ncalib_core.py` + `s05a`–`s05d`.
diff --git a/scripts/legacy/open_parquet.py b/scripts/legacy/open_parquet.py
new file mode 100644
index 0000000..a58bc10
--- /dev/null
+++ b/scripts/legacy/open_parquet.py
@@ -0,0 +1,4 @@
+# impport parquet
+import pyarrow.parquet as pq
+table = pq.read_table(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\usgs_rating_curves.parquet")
+print(table)
\ No newline at end of file
diff --git a/scripts/legacy/plot_calibration_slides.py b/scripts/legacy/plot_calibration_slides.py
new file mode 100644
index 0000000..8ef3227
--- /dev/null
+++ b/scripts/legacy/plot_calibration_slides.py
@@ -0,0 +1,749 @@
+"""
+PPT-ready technical slide deck for the FIMbox calibration pipeline.
+
+Slides:
+ 01 — Branch Processing: What is a Branch?
+ 02 — Reference Frame Reconciliation: USGS RC vs SRC
+ 03 — Our Calibration: Manning's n Back-Calculation (s05)
+ 04 — Main Repo Calibration: Discharge Correction Coefficient (Stage 4)
+ 05 — Side-by-Side Comparison Table
+ 06 — The Collision: What Happens When Stage 4 Runs
+ 07 — Items Needing Attention Before Stage 5
+
+Run:
+ .venv\\Scripts\\python.exe scripts/plot_calibration_slides.py
+"""
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+import matplotlib.patches as mpatches
+from matplotlib.patches import FancyBboxPatch
+
+mpl.rcParams["font.family"] = "DejaVu Sans"
+
+SAVE_TO = Path("D:/SI/out/HUC03020102/src_plots/slides")
+
+# ── Palette ───────────────────────────────────────────────────────────────────
+C_NAVY = "#1b4f72"
+C_DBLUE = "#1a5276"
+C_ORANGE = "#a04000"
+C_GREEN = "#1a6b3c"
+C_TEAL = "#0e6655"
+C_PURPLE = "#6c3483"
+C_WARN = "#922b21"
+C_AMBER = "#7d6608"
+C_GRAY = "#566573"
+C_BG = "#f4f6f7"
+C_PLAIN = "#0b3d5e" # plain-language box header
+C_TECH = "#3b0f5e" # technical box header
+C_STRIPE = "#d5d8dc" # table stripe
+
+W, H = 16, 9 # figure size in inches (16:9)
+
+
+# ── Low-level helpers ─────────────────────────────────────────────────────────
+
+def new_slide():
+ fig, ax = plt.subplots(figsize=(W, H))
+ ax.set_xlim(0, W)
+ ax.set_ylim(0, H)
+ ax.axis("off")
+ fig.patch.set_facecolor(C_BG)
+ ax.set_facecolor(C_BG)
+ return fig, ax
+
+
+def header_bar(ax, title, subtitle="", slide_n=""):
+ ax.add_patch(FancyBboxPatch(
+ (0, H - 1.15), W, 1.15,
+ boxstyle="square,pad=0", facecolor=C_NAVY,
+ edgecolor="none", zorder=3,
+ ))
+ ax.text(0.30, H - 0.50, title,
+ ha="left", va="center", fontsize=16, fontweight="bold",
+ color="white", zorder=4)
+ if subtitle:
+ ax.text(0.30, H - 0.88, subtitle,
+ ha="left", va="center", fontsize=9.5, color="#a9cce3", zorder=4)
+ if slide_n:
+ ax.text(W - 0.25, H - 0.60, slide_n,
+ ha="right", va="center", fontsize=9, color="#aaaaaa", zorder=4)
+
+
+def content_box(ax, x, y, w, h, box_title, lines, header_color,
+ bg="#e8ecef", title_fs=11, body_fs=9.5, line_gap=1.6):
+ ax.add_patch(FancyBboxPatch(
+ (x, y), w, h,
+ boxstyle="round,pad=0.10", facecolor=bg,
+ edgecolor="white", linewidth=1.8, zorder=3,
+ ))
+ # coloured left accent strip
+ ax.add_patch(FancyBboxPatch(
+ (x, y), 0.12, h,
+ boxstyle="square,pad=0", facecolor=header_color,
+ edgecolor="none", zorder=4,
+ ))
+ ax.text(x + 0.22, y + h - 0.30, box_title,
+ ha="left", va="top", fontsize=title_fs, fontweight="bold",
+ color=header_color, zorder=5)
+ ax.text(x + 0.22, y + h - 0.62, "\n".join(lines),
+ ha="left", va="top", fontsize=body_fs,
+ color="#1a1a1a", linespacing=line_gap, zorder=5)
+
+
+def footnote(ax, text, y=0.18):
+ ax.text(W / 2, y, text,
+ ha="center", va="center", fontsize=8.5, color="#555",
+ style="italic", zorder=4)
+
+
+def divider(ax, y, x0=0.25, x1=None):
+ ax.plot([x0, x1 or W - 0.25], [y, y],
+ color="#b2bec3", lw=0.8, ls="--", zorder=2)
+
+
+def save_slide(fig, name):
+ SAVE_TO.mkdir(parents=True, exist_ok=True)
+ out = SAVE_TO / name
+ fig.savefig(out, dpi=180, bbox_inches="tight", facecolor=C_BG)
+ plt.close(fig)
+ print(f" Saved: {out.name}")
+
+
+# ── Slide 01 — Branch Processing ──────────────────────────────────────────────
+
+def slide_01():
+ fig, ax = new_slide()
+ header_bar(ax,
+ "Branch Processing — How a HUC8 is Split Into Workable Units",
+ subtitle="Level-path derivation from NWM stream network topology",
+ slide_n="01 / 07")
+
+ content_box(ax, 0.25, 1.05, 7.35, 6.55,
+ "Plain Language",
+ [
+ "A branch = one river corridor.",
+ "Starting where a tributary joins the main river,",
+ "running all the way up to the tributary's headwater.",
+ "",
+ "HUC 03020102 has 17 branches:",
+ " Branch 0 — whole-basin trunk (processed first)",
+ " 3351000014–3351000029 — 16 individual stream corridors",
+ "",
+ "Each branch is processed independently:",
+ " its own DEM clip, HAND raster, and rating curve table.",
+ "",
+ "Why split at all?",
+ " Memory: a full-basin HAND raster is too large to compute",
+ " in one pass. Branches let us parallelize and tile.",
+ ],
+ C_PLAIN, bg="#e8f4fc", body_fs=10.0, line_gap=1.55)
+
+ content_box(ax, 7.90, 1.05, 7.85, 6.55,
+ "Technical Detail (branch_derivation.py)",
+ [
+ "Input: NWM streams for the HUC",
+ " → filter: drop stream orders 1 & 2 (line 137)",
+ " → result: only order ≥ 3 tributaries remain",
+ "",
+ "_assign_levelpaths() (lines 704–803):",
+ " 1. Find all network outlets (no downstream reach)",
+ " 2. Walk upstream from each outlet",
+ " 3. At each confluence — pick ONE upstream reach",
+ " to continue the same level path:",
+ " → highest stream order wins",
+ " → tie: largest arbolate sum; then reach ID",
+ " 4. All other upstream tributaries at that junction",
+ " → start a NEW level path (new branch ID)",
+ "",
+ "Branch IDs are synthetic (e.g. 3351000014 = first 4 chars",
+ "of NWM reach ID + sequential suffix)",
+ "",
+ "_remove_branches_without_catchments() (line 806):",
+ " Drops any branch with zero NWM catchment polygons",
+ " → prevents empty-DEM crashes downstream",
+ ],
+ C_TECH, bg="#f3eafd", body_fs=9.2, line_gap=1.50)
+
+ ax.add_patch(FancyBboxPatch(
+ (0.25, 0.18), 15.50, 0.72,
+ boxstyle="round,pad=0.08", facecolor=C_TEAL,
+ edgecolor="none", linewidth=0, zorder=3,
+ ))
+ ax.text(8.0, 0.54,
+ "HUC 03020102: 17 branches = 1 trunk (Branch 0) + 16 level-path branches "
+ "(3351000014 → 3351000029)",
+ ha="center", va="center", fontsize=10.5, fontweight="bold",
+ color="white", zorder=4)
+
+ save_slide(fig, "slide_01_branch_processing.png")
+
+
+# ── Slide 02 — Reference Frame Reconciliation ─────────────────────────────────
+
+def slide_02():
+ fig, ax = new_slide()
+ header_bar(ax,
+ "Reference Frame Reconciliation — USGS RC vs Synthetic RC (SRC)",
+ subtitle="Converting absolute NAVD88 elevation to HAND (height above thalweg)",
+ slide_n="02 / 07")
+
+ content_box(ax, 0.25, 4.30, 7.35, 3.40,
+ "Plain Language",
+ [
+ "USGS gauges report water-surface elevation in feet",
+ "above sea level (NAVD88 datum).",
+ "",
+ "Our Synthetic Rating Curves use a different reference:",
+ "height above the riverbed (HAND stage).",
+ "",
+ "To compare them we subtract the riverbed elevation",
+ "(sampled from the DEM at the snapped gauge location).",
+ "",
+ "The SRC has only discrete 1-foot stage steps, so we",
+ 'find the "closest row" rather than an exact match.',
+ ],
+ C_PLAIN, bg="#e8f4fc", body_fs=10.0, line_gap=1.60)
+
+ content_box(ax, 0.25, 1.05, 7.35, 3.00,
+ "Technical Detail (s05_calibrate_n_recurrence.py lines 95–194)",
+ [
+ "Unit conversion (lines 95–100):",
+ " rc['flow_cms'] = rc['flow'] / 35.3147 # cfs → m³/s",
+ " rc['elev_m'] = rc['elevation_navd88'] / 3.28084 # ft → m",
+ "",
+ "Reference conversion (lines 154–155):",
+ " elev_r = np.interp(Q_r, gage_rc['flow_cms'],",
+ " gage_rc['elev_m']) # NAVD88 water surface (m)",
+ " hand_r = elev_r − dem_adj_elevation_m # → HAND stage",
+ "",
+ "Nearest-neighbour SRC lookup (line 192):",
+ " idx = (hdf['Stage'] − hand_r).abs().idxmin()",
+ " row = hdf.loc[idx] # → A, R geometry at that stage",
+ ],
+ C_TECH, bg="#f3eafd", body_fs=9.0, line_gap=1.55)
+
+ # ── Diagram ────────────────────────────────────────────────────────────────
+ dx = 9.80
+ bx = dx # left edge of diagram area
+ # Ground / thalweg line
+ ax.plot([bx, bx + 5.8], [3.00, 3.00], color="#7d6608", lw=2.5, zorder=4)
+ ax.text(bx + 5.85, 3.00, "Thalweg / riverbed", va="center", fontsize=9, color="#7d6608")
+ # NAVD88 datum
+ ax.plot([bx, bx + 5.8], [1.45, 1.45], color="#566573", lw=1.5, ls="--", zorder=4)
+ ax.text(bx + 5.85, 1.45, "NAVD88 datum", va="center", fontsize=9, color="#566573")
+ # Water surface
+ ax.plot([bx, bx + 5.8], [5.50, 5.50], color="#2980b9", lw=2.5, zorder=4)
+ ax.text(bx + 5.85, 5.50, "Water surface", va="center", fontsize=9, color="#2980b9")
+
+ # Arrow: NAVD88 → thalweg (dem_adj_elevation_m)
+ cx = bx + 1.2
+ ax.annotate("", xy=(cx, 3.00), xytext=(cx, 1.45),
+ arrowprops=dict(arrowstyle="<->", color=C_ORANGE, lw=1.8), zorder=5)
+ ax.text(cx - 0.12, 2.22, "dem_adj_elevation_m\n(thalweg elev, from DEM)",
+ ha="right", va="center", fontsize=8.5, color=C_ORANGE)
+
+ # Arrow: thalweg → water surface (HAND stage)
+ cx2 = bx + 2.8
+ ax.annotate("", xy=(cx2, 5.50), xytext=(cx2, 3.00),
+ arrowprops=dict(arrowstyle="<->", color=C_GREEN, lw=2.2), zorder=5)
+ ax.text(cx2 + 0.12, 4.25, "HAND stage = hand_r\n(what SRC Stage column uses)",
+ ha="left", va="center", fontsize=8.5, color=C_GREEN)
+
+ # Arrow: NAVD88 → water surface (elev_m from USGS RC)
+ cx3 = bx + 4.4
+ ax.annotate("", xy=(cx3, 5.50), xytext=(cx3, 1.45),
+ arrowprops=dict(arrowstyle="<->", color=C_NAVY, lw=2.2), zorder=5)
+ ax.text(cx3 + 0.12, 3.47, "elev_r (NAVD88 water surface)\n(what USGS RC reports)",
+ ha="left", va="center", fontsize=8.5, color=C_NAVY)
+
+ # Equation box
+ ax.add_patch(FancyBboxPatch(
+ (bx - 0.10, 5.80), 5.90, 0.75,
+ boxstyle="round,pad=0.08", facecolor="#fdfefe",
+ edgecolor="#aab7b8", linewidth=1.2, zorder=3,
+ ))
+ ax.text(bx + 2.85, 6.18,
+ "hand_r = elev_r − dem_adj_elevation_m",
+ ha="center", va="center", fontsize=11, fontweight="bold",
+ color=C_NAVY, zorder=5,
+ fontfamily="monospace")
+
+ ax.add_patch(FancyBboxPatch(
+ (0.25, 0.18), 15.50, 0.60,
+ boxstyle="round,pad=0.08", facecolor="#eaecee",
+ edgecolor="#aab7b8", linewidth=0.8, zorder=2,
+ ))
+ ax.text(W / 2, 0.48,
+ "dem_adj_elevation_m comes from usgs_elev_table.csv"
+ " — DEM elevation sampled at the snapped gauge point during the USGS Crosswalk step (s04)",
+ ha="center", va="center", fontsize=8.8, color="#444", style="italic", zorder=3)
+
+ save_slide(fig, "slide_02_reference_frames.png")
+
+
+# ── Slide 03 — Our Calibration ────────────────────────────────────────────────
+
+def slide_03():
+ fig, ax = new_slide()
+ header_bar(ax,
+ "Our Calibration — Manning's n Back-Calculation",
+ subtitle="s05_calibrate_n_recurrence.py | direct algebraic inversion at 5 NWM recurrence points",
+ slide_n="03 / 07")
+
+ content_box(ax, 0.25, 3.80, 7.35, 3.95,
+ "Plain Language",
+ [
+ "We ask: at each of 5 flood levels (2, 5, 10, 25, 50-year",
+ "recurrence), what roughness value n makes the SRC predict",
+ "the same flow as the USGS gauge?",
+ "",
+ "Result: 6 zones — one per recurrence interval boundary,",
+ "plus everything above the 50-yr level.",
+ "Each zone gets its own constant n value.",
+ "",
+ "Only 2 of 17 branches get this treatment:",
+ " → those with a USGS gauge AND an observed rating curve.",
+ "",
+ "The same n is applied uniformly to every reach (HydroID)",
+ "on that branch within each zone.",
+ ],
+ C_PLAIN, bg="#e8f4fc", body_fs=10.0, line_gap=1.60)
+
+ content_box(ax, 0.25, 1.05, 7.35, 2.50,
+ "Technical Detail",
+ [
+ "Manning's equation (inverse): n = A · R^(2/3) · S^(1/2) / Q",
+ "",
+ "At each recurrence flow Q_r (2, 5, 10, 25, 50 yr):",
+ " 1. Interpolate USGS RC → elev_r (NAVD88 water surface)",
+ " 2. Convert: hand_r = elev_r − dem_adj_elevation_m (HAND stage)",
+ " 3. Nearest-neighbour SRC lookup → get A, R for that stage",
+ " 4. n_zone = A·R^(2/3)·sqrt(SLOPE) / Q_r clipped to [0.01, 0.30]",
+ " 5. Recompute Q: Discharge = A·R^(2/3)·sqrt(SLOPE) / n_zone",
+ " → for every HydroID × every Stage row in that zone",
+ "Writes ManningN + Discharge (m3s-1) → src_full_crosswalked_{bid}.csv",
+ "Does NOT touch: default_ManningN, default_SLOPE, hydroTable_{bid}.csv",
+ ],
+ C_TECH, bg="#f3eafd", body_fs=9.2, line_gap=1.52)
+
+ # ── Zone diagram ──────────────────────────────────────────────────────────
+ zx = 8.10
+ zy_base = 1.05
+ zone_h = 6.30 / 6 # 6 zones stacked in 6.30 inches
+ zone_labels = ["Zone 1\n< 2yr", "Zone 2\n2–5yr", "Zone 3\n5–10yr",
+ "Zone 4\n10–25yr", "Zone 5\n25–50yr", "Zone 6\n> 50yr"]
+ n_14 = [0.065, 0.049, 0.039, 0.016, 0.011, 0.011]
+ n_23 = [0.090, 0.083, 0.044, 0.024, 0.011, 0.011]
+ zone_cols = ["#aed6f1", "#a9dfbf", "#fad7a0", "#f9e79f", "#f1948a", "#d2b4de"]
+
+ for i in range(6):
+ by = zy_base + i * zone_h
+ col = zone_cols[i]
+ ax.add_patch(FancyBboxPatch(
+ (zx, by), 7.65, zone_h - 0.04,
+ boxstyle="square,pad=0", facecolor=col,
+ edgecolor="#cccccc", linewidth=0.6, alpha=0.55, zorder=3,
+ ))
+ # Zone label
+ ax.text(zx + 0.12, by + zone_h / 2 - 0.02, zone_labels[i],
+ ha="left", va="center", fontsize=8, color="#333",
+ fontweight="bold", zorder=4, linespacing=1.3)
+ # n values for branch 14
+ ax.text(zx + 2.85, by + zone_h / 2 - 0.02, f"n = {n_14[i]:.3f}",
+ ha="center", va="center", fontsize=9.5, color=C_NAVY,
+ fontweight="bold", zorder=4)
+ # n values for branch 23
+ ax.text(zx + 5.85, by + zone_h / 2 - 0.02, f"n = {n_23[i]:.3f}",
+ ha="center", va="center", fontsize=9.5, color=C_ORANGE,
+ fontweight="bold", zorder=4)
+
+ # Column headers
+ ax.text(zx + 2.85, zy_base + 6 * zone_h + 0.22,
+ "Branch 3351000014\n(Gauge 02083000)",
+ ha="center", va="bottom", fontsize=9, color=C_NAVY, fontweight="bold",
+ linespacing=1.4, zorder=4)
+ ax.text(zx + 5.85, zy_base + 6 * zone_h + 0.22,
+ "Branch 3351000023\n(Gauge 02082950)",
+ ha="center", va="bottom", fontsize=9, color=C_ORANGE, fontweight="bold",
+ linespacing=1.4, zorder=4)
+
+ # Jump annotation for Branch 23
+ ax.annotate(
+ "8.2× jump\n(non-monotonic SRC risk)",
+ xy=(zx + 5.85, zy_base + zone_h + 0.03),
+ xytext=(zx + 7.30, zy_base + zone_h * 1.5),
+ fontsize=8, color=C_WARN, fontweight="bold",
+ arrowprops=dict(arrowstyle="->", color=C_WARN, lw=1.2),
+ ha="left", va="center", zorder=6,
+ )
+
+ save_slide(fig, "slide_03_our_calibration.png")
+
+
+# ── Slide 04 — Main Repo Calibration ─────────────────────────────────────────
+
+def slide_04():
+ fig, ax = new_slide()
+ header_bar(ax,
+ "Main Repo Calibration — Discharge Correction Coefficient (Stage 4)",
+ subtitle="src_calibrate.py / src_optimization.py | empirical scalar correction per HydroID",
+ slide_n="04 / 07")
+
+ content_box(ax, 0.25, 3.75, 7.35, 4.00,
+ "Plain Language",
+ [
+ "The main pipeline's question:",
+ " Is the SRC's predicted flow too high or too low",
+ " compared to the gauge? Apply a single multiplier.",
+ "",
+ "Unlike our approach, this does NOT recompute n.",
+ "It just scales the existing discharge curve up or down",
+ "by one factor per stream segment (HydroID).",
+ "",
+ "The correction is then spread to nearby un-gauged",
+ "segments within 8 km by network tracing.",
+ "",
+ "It runs AFTER several other adjustments:",
+ " bathymetry → bankfull → channel/overbank subdivision",
+ " → nonmonotonic fix → USGS rating calibration (← here)",
+ "",
+ "So it calibrates an already-modified curve, not the",
+ "raw Stage 2 SRC that our script worked on.",
+ ],
+ C_PLAIN, bg="#e8f4fc", body_fs=9.8, line_gap=1.55)
+
+ content_box(ax, 0.25, 1.05, 7.35, 2.45,
+ "Technical Detail (src_optimization.py)",
+ [
+ "1. _build_usgs_database: match USGS RC to each NWM recurrence flow",
+ " → (hand, Q_obs) pairs at each recurrence interval",
+ "2. For each pair: find nearest hydroTable row → get Q_src",
+ " calb_coef = Q_src / Q_obs (per HydroID, per interval)",
+ "3. Per HydroID: calb_coef_final = median(calb_coef over all intervals)",
+ " → ONE scalar per HydroID, not stage-varying",
+ "4. Q_new(h) = Q_old(h) / calb_coef_final for ALL stage rows",
+ "5. Network propagation: _trace_network ± 8 km (same stream order)",
+ " group_manningn_calc: running-mean coef downstream 8 km",
+ "6. Writes: hydroTable_{bid}.csv (discharge_cms, calb_coef_usgs)",
+ " Gated: src_adjust_usgs=True AND src_subdiv_toggle=True",
+ ],
+ C_TECH, bg="#f3eafd", body_fs=9.2, line_gap=1.52)
+
+ # ── Propagation diagram ───────────────────────────────────────────────────
+ px = 8.10
+ py_base = 1.40
+ # River network sketch
+ # Main reach (horizontal) ─────────────────────
+ ax.annotate("", xy=(px + 6.80, py_base + 2.40),
+ xytext=(px, py_base + 2.40),
+ arrowprops=dict(arrowstyle="-|>", color="#2980b9", lw=2.0), zorder=4)
+ # Tributary
+ ax.annotate("", xy=(px + 3.60, py_base + 2.40),
+ xytext=(px + 2.20, py_base + 4.20),
+ arrowprops=dict(arrowstyle="-|>", color="#2980b9", lw=1.5), zorder=4)
+
+ # Gauge HydroID (orange fill)
+ gx, gy = px + 3.60, py_base + 2.40
+ ax.add_patch(plt.Circle((gx, gy), 0.28, color=C_ORANGE, zorder=5))
+ ax.text(gx, gy + 0.55, "Gauge\nHydroID", ha="center", va="bottom",
+ fontsize=8, color=C_ORANGE, fontweight="bold", linespacing=1.3)
+
+ # Traced reaches (±8 km fill)
+ for dx, label in [(px + 1.8, "−8 km"), (px + 5.4, "+8 km")]:
+ ax.add_patch(plt.Circle((dx, py_base + 2.40), 0.20, color=C_NAVY,
+ alpha=0.55, zorder=5))
+ ax.text(dx, py_base + 1.85, label, ha="center", fontsize=8,
+ color=C_NAVY, fontweight="bold")
+
+ # Downstream propagation arrows
+ for ddx in [px + 5.4, px + 6.8]:
+ ax.add_patch(plt.Circle((ddx, py_base + 2.40), 0.15,
+ color=C_TEAL, alpha=0.55, zorder=5))
+ ax.text(px + 6.10, py_base + 1.50,
+ "group mean coef\ncarried ≤ 8 km\ndownstream",
+ ha="center", va="top", fontsize=8, color=C_TEAL, linespacing=1.4)
+
+ # Legend
+ for col, lbl, yx in [
+ (C_ORANGE, "Direct gauge HydroID", py_base + 5.10),
+ (C_NAVY, "Traced neighborhood (±8 km, same order)", py_base + 4.65),
+ (C_TEAL, "Downstream group carry (≤ 8 km)", py_base + 4.20),
+ ]:
+ ax.add_patch(plt.Circle((px + 0.22, yx), 0.12, color=col, zorder=5))
+ ax.text(px + 0.45, yx, lbl, va="center", fontsize=9, color="#222")
+
+ ax.text(px + 3.60, py_base + 6.10,
+ "One scalar coefficient per HydroID — applied uniformly across the full discharge curve",
+ ha="center", fontsize=9.5, fontweight="bold", color=C_NAVY)
+
+ save_slide(fig, "slide_04_main_repo_calibration.png")
+
+
+# ── Slide 05 — Comparison Table ───────────────────────────────────────────────
+
+def slide_05():
+ fig, ax = new_slide()
+ header_bar(ax,
+ "Calibration Methods — Side-by-Side Comparison",
+ subtitle="Both use the same USGS rating curves and NWM recurrence flows — but produce discharge differently",
+ slide_n="05 / 07")
+
+ rows = [
+ ("Method",
+ "Manning's n back-calculation\n(algebraic inversion)",
+ "Discharge correction coefficient\n(empirical scalar)"),
+ ("What changes",
+ "ManningN per zone → Q fully\nrecomputed from geometry",
+ "Q_old × (1 / coef), n unchanged,\ncurve shape preserved"),
+ ("Discharge output",
+ "Stage-varying (different n per zone\n→ different curve shape per zone)",
+ "Single multiplier per HydroID\n(uniform shift up or down)"),
+ ("Spatial scope",
+ "All HydroIDs on the gauged branch\n(uniform within each zone)",
+ "Gauge HydroID ± 8 km network trace\n+ downstream group carry"),
+ ("Baseline curve",
+ "Raw SRC from Stage 2\n(src_full_crosswalked_{bid}.csv)",
+ "Post-subdivision hydroTable\n(bankfull + bathy + subdiv already applied)"),
+ ("Output file",
+ "src_full_crosswalked_{bid}.csv\n(ManningN + Discharge (m3s-1))",
+ "hydroTable_{bid}.csv\n(discharge_cms + calb_coef_usgs)"),
+ ("Branches affected",
+ "2 of 17 (gauged with RC data only)\n3351000014, 3351000023",
+ "Up to all 17 via network propagation\n(any HydroID within 8 km of a gauge)"),
+ ("Handles ungauged HydroIDs",
+ "No — only directly gauged branches",
+ "Yes — network propagation and\nfeature_id-level mean fallback"),
+ ("Run order in pipeline",
+ "s05 — runs before Stage 4",
+ "Stage 4 — runs after s05;\ncalibration_rerun=True resets first"),
+ ]
+
+ col_w = [3.40, 5.70, 5.70]
+ col_x = [0.30, 3.90, 9.80]
+ row_h = 0.61
+ y_start = 7.55
+
+ hdr_colors = ["#2c3e50", C_NAVY, C_ORANGE]
+ hdr_labels = ["Aspect", "Our Script (s05)", "Main Repo (Stage 4 / UsgsRatingCalibrator)"]
+ alt_bgs = ["#dce4ec", "#e8f4fc", "#fef5e7"]
+ base_bgs = ["#eaeff4", "#f0f7fd", "#fdf3e3"]
+
+ for ci, (lbl, cw, cx) in enumerate(zip(hdr_labels, col_w, col_x)):
+ ax.add_patch(FancyBboxPatch(
+ (cx, y_start), cw, 0.58,
+ boxstyle="square,pad=0", facecolor=hdr_colors[ci],
+ edgecolor="none", zorder=3,
+ ))
+ ax.text(cx + cw / 2, y_start + 0.29, lbl,
+ ha="center", va="center", fontsize=10.5, fontweight="bold",
+ color="white", zorder=4)
+
+ for ri, row_data in enumerate(rows):
+ ry = y_start - (ri + 1) * row_h
+ bg_set = alt_bgs if ri % 2 == 0 else base_bgs
+ for ci, (cell, cw, cx) in enumerate(zip(row_data, col_w, col_x)):
+ ax.add_patch(FancyBboxPatch(
+ (cx, ry), cw, row_h - 0.03,
+ boxstyle="square,pad=0", facecolor=bg_set[ci],
+ edgecolor="#d5d8dc", linewidth=0.6, zorder=3,
+ ))
+ ax.text(cx + 0.12, ry + row_h / 2, cell,
+ ha="left", va="center", fontsize=8.5,
+ color="#1a1a1a", linespacing=1.35, zorder=4)
+
+ footnote(ax,
+ "Both methods draw on the same source data (usgs_rating_curves.parquet + "
+ "nwm3_17C_recurrence_flows_cfs.parquet) — they differ in HOW they apply the information.",
+ y=0.25)
+ save_slide(fig, "slide_05_comparison_table.png")
+
+
+# ── Slide 06 — The Collision ──────────────────────────────────────────────────
+
+def slide_06():
+ fig, ax = new_slide()
+ header_bar(ax,
+ "Critical Issue — Calibration Collision When Stage 4 Runs",
+ subtitle="calibration_rerun=True in s07_stage4_single_huc.py triggers HydroTableReset, "
+ "which erases s05 edits",
+ slide_n="06 / 07")
+
+ content_box(ax, 0.25, 4.05, 7.35, 3.65,
+ "Plain Language",
+ [
+ "Stage 4 is currently configured to RESET everything",
+ "back to defaults before it runs its own calibration.",
+ "",
+ "The reset reads 'default_ManningN' and 'default_SLOPE'",
+ "— the original, untouched values from Stage 2.",
+ "",
+ "Our s05 script only wrote to 'ManningN' and",
+ "'Discharge (m3s-1)' — it never updated the default_ columns.",
+ "",
+ "So the reset has no way to know we calibrated those values.",
+ "It just overwrites them silently.",
+ "",
+ "Result: if Stage 4 runs, our n-calibration is gone.",
+ "Whoever runs last wins.",
+ ],
+ C_PLAIN, bg="#fef9e7", body_fs=10.0, line_gap=1.55)
+
+ content_box(ax, 0.25, 1.05, 7.35, 2.75,
+ "Technical Detail (reset.py lines 77–169)",
+ [
+ "HydroTableReset._reset_one() reads:",
+ " src_base_{bid}.csv + full['default_SLOPE']",
+ " + full['default_ManningN']",
+ "Then recomputes:",
+ " Q = A·R^(2/3)·sqrt(default_SLOPE) / default_ManningN",
+ "Then overwrites in src_full_crosswalked_{bid}.csv:",
+ " ManningN ← default_ManningN",
+ " Discharge (m3s-1) ← recomputed Q",
+ "",
+ "s05 writes ONLY: ManningN, Discharge (m3s-1)",
+ "s05 NEVER writes: default_ManningN, default_SLOPE",
+ "→ reset has no memory that s05 ran; it reverts blindly",
+ ],
+ C_TECH, bg="#fce4e4", body_fs=9.2, line_gap=1.52)
+
+ # ── Flow diagram ──────────────────────────────────────────────────────────
+ fx = 8.10
+ steps = [
+ (fx + 3.7, 7.40, "s05 runs", C_TEAL,
+ "Writes calibrated n\nto src_full_crosswalked_*.csv"),
+ (fx + 3.7, 5.75, "Stage 4 starts\n(calibration_rerun=True)", C_WARN,
+ "s07_stage4_single_huc.py line 46"),
+ (fx + 3.7, 4.05, "HydroTableReset fires\n(pipeline.py line 145)", C_WARN,
+ "Reads default_ManningN / default_SLOPE\n→ rewrites ManningN + Discharge\n→ s05 work ERASED"),
+ (fx + 3.7, 2.20, "Stage 4 calibration runs", C_NAVY,
+ "UsgsRatingCalibrator applies\nits own coef to the reset baseline"),
+ ]
+ for sx, sy, title, col, note in steps:
+ ax.add_patch(FancyBboxPatch(
+ (sx - 2.60, sy - 0.38), 5.20, 0.82,
+ boxstyle="round,pad=0.10", facecolor=col,
+ edgecolor="white", linewidth=1.5, alpha=0.88, zorder=4,
+ ))
+ ax.text(sx, sy + 0.04, title,
+ ha="center", va="center", fontsize=9.5, fontweight="bold",
+ color="white", zorder=5, linespacing=1.25)
+ ax.text(sx + 2.75, sy, note,
+ ha="left", va="center", fontsize=8, color="#333",
+ linespacing=1.35, zorder=5)
+
+ # Arrows between steps
+ for i in range(len(steps) - 1):
+ _, y1, _, _, _ = steps[i]
+ _, y2, _, _, _ = steps[i + 1]
+ ax.annotate("", xy=(steps[i+1][0], y2 + 0.44),
+ xytext=(steps[i][0], y1 - 0.38),
+ arrowprops=dict(arrowstyle="-|>", color="#555", lw=1.5), zorder=3)
+
+ # Three resolution options — side-by-side boxes (full width, bottom strip)
+ opt_data = [
+ (C_WARN, "Option A (not recommended)",
+ "Set calibration_rerun=False",
+ "Skip the reset so Stage 4 stacks on top of s05.\nMethods compound in an uncontrolled way."),
+ (C_AMBER, "Option B (surgical)",
+ "Disable src_adjust_usgs for gauged branches",
+ "Main repo applies bankfull/subdiv/bathy only.\ns05 n-calibration is the final word on gauged branches."),
+ (C_GREEN, "Option C (safest)",
+ "Copy s05 n into default_ManningN before Stage 4",
+ "Makes s05 the new baseline so the reset preserves\nour work and Stage 4 calibrates on top of it."),
+ ]
+ bw = (W - 0.50) / 3 # box width per option
+ for oi, (col, tag, title, body) in enumerate(opt_data):
+ ox = 0.25 + oi * (bw + 0.02)
+ ax.add_patch(FancyBboxPatch(
+ (ox, 0.18), bw, 0.95,
+ boxstyle="round,pad=0.08", facecolor=col,
+ edgecolor="white", linewidth=1.2, alpha=0.90, zorder=3,
+ ))
+ ax.text(ox + 0.15, 0.99, tag,
+ ha="left", va="top", fontsize=8.2, color="white",
+ fontweight="bold", zorder=4)
+ ax.text(ox + 0.15, 0.76, title,
+ ha="left", va="top", fontsize=9.5, color="white",
+ fontweight="bold", zorder=4)
+ ax.text(ox + 0.15, 0.55, body,
+ ha="left", va="top", fontsize=8.0, color="#f0f0f0",
+ linespacing=1.40, zorder=4)
+
+ save_slide(fig, "slide_06_collision.png")
+
+
+# ── Slide 07 — Items Needing Attention ────────────────────────────────────────
+
+def slide_07():
+ fig, ax = new_slide()
+ header_bar(ax,
+ "Items Needing Attention Before Stage 5 (FIM Generation)",
+ subtitle="HUC 03020102 | Checklist of open issues, risks, and design decisions",
+ slide_n="07 / 07")
+
+ items = [
+ (C_WARN, "CRITICAL — Calibration Collision",
+ "Stage 4 (s07) is hardcoded with calibration_rerun=True.\n"
+ "HydroTableReset will silently overwrite s05's ManningN / Discharge back to defaults.\n"
+ "Decision needed before Stage 4 runs on this HUC (or any of the 24 HUCs)."),
+
+ (C_ORANGE, "SRC Discontinuity — Branch 3351000023",
+ "n jumps 8.2× at the 2-yr zone boundary (0.011 → 0.090).\n"
+ "This creates a non-monotonic section in the calibrated SRC: discharge decreases with rising stage.\n"
+ "Risk: Stage 3–5 inundation mapping may invert the stage–discharge relationship at that level."),
+
+ (C_AMBER, "Gauged Branches With No Rating Curve Data",
+ "Branches 3351000015 (Gauge 02083410) and 3351000026 (Gauge 02082835)\n"
+ "have USGS gauges crosswalked but no rating curve rows in usgs_rating_curves.parquet.\n"
+ "Neither s05 nor Stage 4's UsgsRatingCalibrator can calibrate them → default n=0.06 applies."),
+
+ (C_GRAY, "15 Ungauged Branches — Default n Only",
+ "Branches 3351000015–3351000029 (excluding 14 & 23) run on global default n = 0.06 (channel)\n"
+ "and n = 0.12 (overbank) from mannings_global_optz.parquet.\n"
+ "ML-based n regionalization is future work — not blocking Stage 5, but limits FIM accuracy."),
+
+ (C_PURPLE, "Scale — 24 HUCs Not Yet Tested",
+ "The full pipeline (including Stage 4) has only been validated on HUC 03020102.\n"
+ "Before running s07_stage4_all_hucs.py across all 24, confirm collision handling\n"
+ "and that all HUCs have Stage 2 outputs (branches/ + hydroTable + src_full_crosswalked)."),
+ ]
+
+ item_h = 1.28
+ y0 = 7.60
+ for i, (col, title, body) in enumerate(items):
+ iy = y0 - i * (item_h + 0.04)
+ ax.add_patch(FancyBboxPatch(
+ (0.25, iy - item_h), 15.50, item_h,
+ boxstyle="round,pad=0.08", facecolor="#ffffff",
+ edgecolor=col, linewidth=2.0, zorder=3,
+ ))
+ # left accent
+ ax.add_patch(FancyBboxPatch(
+ (0.25, iy - item_h), 0.18, item_h,
+ boxstyle="square,pad=0", facecolor=col,
+ edgecolor="none", zorder=4,
+ ))
+ ax.text(0.55, iy - 0.30, title,
+ ha="left", va="top", fontsize=10.5, fontweight="bold",
+ color=col, zorder=5)
+ ax.text(0.55, iy - 0.62, body,
+ ha="left", va="top", fontsize=9.0, color="#222",
+ linespacing=1.50, zorder=5)
+
+ save_slide(fig, "slide_07_items_attention.png")
+
+
+# ── Main ──────────────────────────────────────────────────────────────────────
+
+if __name__ == "__main__":
+ print(f"Saving slides to: {SAVE_TO}")
+ slide_01()
+ slide_02()
+ slide_03()
+ slide_04()
+ slide_05()
+ slide_06()
+ slide_07()
+ print(f"\nDone — {SAVE_TO}")
diff --git a/scripts/legacy/plot_src_calibration.py b/scripts/legacy/plot_src_calibration.py
new file mode 100644
index 0000000..e452c41
--- /dev/null
+++ b/scripts/legacy/plot_src_calibration.py
@@ -0,0 +1,330 @@
+"""
+Publication / PPT-ready calibration comparison plots.
+
+Each subplot shows:
+ • Coloured horizontal bands — the 6 piecewise-n zones
+ • White box label (right) — zone range + calibrated Manning's n
+ • Blue (thick) — original SRC for the gauged HydroID
+ • Red (thick) — calibrated SRC for the same HydroID
+ • Green dashed — USGS rating curve in HAND coordinates
+ • Diamond + straight arrow — NWM recurrence-Q points (cascade-staggered)
+ • Grey step curve (top axis) — Manning's n as a function of HAND stage
+
+x-axis: USGS RC Q at 1.5 × h_50yr (~100-yr view)
+y-axis: 1.5 × h_50yr HAND stage
+Top x-axis: Manning's n (step function across zones, semi-transparent)
+
+HAND stage = height above thalweg (dem.tif elevation sampled at snapped gauge).
+
+Run:
+ .venv\\Scripts\\python.exe scripts/plot_src_calibration.py
+"""
+from __future__ import annotations
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+import matplotlib.ticker as mticker
+import numpy as np
+import pandas as pd
+
+# ── Publication style ─────────────────────────────────────────────
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans",
+ "font.size": 11,
+ "axes.labelsize": 13,
+ "axes.titlesize": 12,
+ "xtick.labelsize": 11,
+ "ytick.labelsize": 11,
+ "legend.fontsize": 10.5,
+ "legend.framealpha": 0.93,
+ "legend.edgecolor": "#cccccc",
+ "axes.spines.top": False,
+ "axes.spines.right": False,
+ "axes.grid": True,
+ "grid.alpha": 0.28,
+ "grid.linestyle": ":",
+})
+
+# ── CONFIG ────────────────────────────────────────────────────────
+HUC8 = "03020102"
+OUT_DIR = Path("D:/SI/out")
+DATA_DIR = Path("data")
+# ─────────────────────────────────────────────────────────────────
+
+AOI_ROOT = OUT_DIR / f"HUC{HUC8}"
+WATERSHED = AOI_ROOT / "watershed-data"
+BRANCHES = WATERSHED / "branches"
+SAVE_TO = AOI_ROOT / "src_plots"
+
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+
+ZONE_COLOURS = ["#aed6f1", "#a9dfbf", "#fad7a0", "#f9e79f", "#f1948a", "#d2b4de"]
+ZONE_ALPHA = 0.40
+
+
+# ── Loaders ───────────────────────────────────────────────────────
+
+def load_data():
+ elev = pd.read_csv(
+ AOI_ROOT / "usgs_elev_table.csv",
+ dtype={"location_id": str, "feature_id": "Int64"},
+ )
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["flow_cms"] = rc["flow"].astype(float) / 35.3147
+ rc["elev_m"] = rc["elevation_navd88"].astype(float) / 3.28084
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr in RECURRENCE_YEARS:
+ recur[f"Q_{yr}yr_cms"] = (
+ recur[f"{yr}_0_year_recurrence_flow_17C"].astype(float) * 0.028317
+ )
+ return elev, rc, recur
+
+
+def load_src(bid: str, original: bool) -> pd.DataFrame:
+ branch_dir = BRANCHES / bid
+ fname = f"src_full_crosswalked_{bid}"
+ path = branch_dir / (fname + (".pre_n_calib.csv" if original else ".csv"))
+ if original and not path.exists():
+ path = branch_dir / f"{fname}.csv"
+ return pd.read_csv(path, low_memory=False)
+
+
+def find_calibrated_branches() -> list[str]:
+ return [
+ bd.name for bd in sorted(BRANCHES.iterdir())
+ if bd.is_dir()
+ and (bd / f"src_full_crosswalked_{bd.name}.pre_n_calib.csv").exists()
+ ]
+
+
+# ── Zone helpers ──────────────────────────────────────────────────
+
+def zone_pts(loc_id, feature_id, dem_adj_m, rc_all, recur):
+ loc = loc_id.zfill(8)
+ grc = rc_all[rc_all["location_id"] == loc].sort_values("flow_cms")
+ if grc.empty:
+ return []
+ feat = recur[recur["feature_id"] == feature_id]
+ if feat.empty:
+ return []
+ pts = []
+ for yr in RECURRENCE_YEARS:
+ Q = float(feat[f"Q_{yr}yr_cms"].iloc[0])
+ if Q < grc["flow_cms"].min() or Q > grc["flow_cms"].max():
+ continue
+ elev = float(np.interp(Q, grc["flow_cms"].values, grc["elev_m"].values))
+ h = elev - dem_adj_m
+ if h > 0:
+ pts.append((yr, h, Q))
+ return sorted(pts, key=lambda x: x[0])
+
+
+def back_calc_n(hydroid, src_df, zp):
+ hdf = src_df[src_df["HydroID"] == hydroid].sort_values("Stage")
+ if hdf.empty:
+ return {}
+ slope = float(hdf["SLOPE"].iloc[0])
+ if slope <= 0:
+ return {}
+ out = {}
+ for yr, h, Q in zp:
+ idx = (hdf["Stage"] - h).abs().idxmin()
+ row = hdf.loc[idx]
+ A = float(row.get("WetArea (m2)", 0.0))
+ R = float(row.get("HydraulicRadius (m)", 0.0))
+ if A > 0 and R > 0 and Q > 0:
+ out[yr] = float(np.clip(A * (R ** (2 / 3)) * slope**0.5 / Q, 0.01, 0.30))
+ return out
+
+
+# ── n-step function for secondary axis ───────────────────────────
+
+def n_step_curve(zp, n_dict, y_max):
+ """
+ Returns (n_vals, h_vals) describing a horizontal step function:
+ n is constant within each zone, steps at zone boundaries.
+ Suitable for plotting on a twiny() axis (n on x, HAND on y).
+ """
+ yrs = [yr for yr, _, _ in zp]
+ n_arr = [n_dict.get(yr, 0.06) for yr in yrs]
+ n_arr.append(n_dict.get(yrs[-1], 0.06) if yrs else 0.06) # >50yr zone
+
+ h_brk = [0.0] + [h for _, h, _ in zp]
+ if h_brk[-1] < y_max:
+ h_brk.append(y_max)
+
+ nx, hy = [], []
+ for i, (h_lo, h_hi) in enumerate(zip(h_brk[:-1], h_brk[1:])):
+ n_v = n_arr[i]
+ nx.extend([n_v, n_v])
+ hy.extend([h_lo, h_hi])
+ if i < len(h_brk) - 2: # horizontal jump at zone boundary
+ nx.append(n_arr[i + 1])
+ hy.append(h_hi)
+
+ return nx, hy
+
+
+# ── Main subplot drawing ──────────────────────────────────────────
+
+def draw_gauge(ax, bid, loc_id, hydroid, feature_id, dem_adj_m,
+ src_orig, src_calib, rc_all, recur, branch_avg):
+
+ zp = zone_pts(loc_id, feature_id, dem_adj_m, rc_all, recur)
+ n_dict = back_calc_n(hydroid, src_orig, zp)
+
+ loc_pad = loc_id.zfill(8)
+ grc = rc_all[rc_all["location_id"] == loc_pad].sort_values("flow_cms").copy()
+ grc["hand"] = grc["elev_m"] - dem_adj_m
+ grc = grc[grc["hand"] > 0]
+
+ # ── Axis limits (~100-yr view) ──
+ h_max_yr = max((h for _, h, _ in zp), default=5.0)
+ y_max = max(h_max_yr * 1.50, 3.0)
+
+ target_elev = dem_adj_m + y_max
+ rc_raw = rc_all[rc_all["location_id"] == loc_pad].sort_values("elev_m")
+ rc_below = rc_raw[rc_raw["elev_m"] <= target_elev]
+ rc_q_max = float(rc_below["flow_cms"].max()) if not rc_below.empty else 0.0
+ x_max = max(rc_q_max, max((Q for _, _, Q in zp), default=50) * 1.4) * 1.08
+
+ go_h = src_orig[src_orig["HydroID"] == hydroid].sort_values("Stage")
+ gc_h = src_calib[src_calib["HydroID"] == hydroid].sort_values("Stage")
+
+ # ── Zone shading ──
+ h_edges = [0.0] + [h for _, h, _ in zp]
+ if h_edges[-1] < y_max:
+ h_edges.append(y_max)
+
+ for i, (h_lo, h_hi) in enumerate(zip(h_edges[:-1], h_edges[1:])):
+ col = ZONE_COLOURS[min(i, len(ZONE_COLOURS) - 1)]
+ ax.axhspan(h_lo, min(h_hi, y_max), color=col, alpha=0.28, zorder=0, lw=0)
+
+ # ── Zone transition lines + return period labels (right-aligned, staggered) ──
+ min_lbl_sep = y_max * 0.07
+ prev_lbl_h = -1.0
+ for yr, h, _ in zp:
+ ax.axhline(h, color="#777", ls=":", lw=1.0, alpha=0.75, zorder=1)
+ lh = max(h, prev_lbl_h + min_lbl_sep)
+ lh = min(lh, y_max * 0.96)
+ ax.text(x_max * 0.988, lh, f"{yr} yr",
+ ha="right", va="bottom", fontsize=9.0, color="#555",
+ fontweight="bold", zorder=10)
+ prev_lbl_h = lh
+
+ # ── USGS RC — solid dark reference line ──
+ if not grc.empty:
+ rc_plt = grc[grc["hand"] <= y_max * 1.02]
+ ax.plot(rc_plt["flow_cms"], rc_plt["hand"],
+ color="#222222", lw=2.8, ls="-", zorder=5,
+ label=f"USGS RC")
+
+ # ── Recurrence markers — small circles on USGS RC, no text ──
+ for _, h, Q in zp:
+ ax.scatter(Q, h, color="#222222", s=50, zorder=8, marker="o",
+ edgecolors="white", linewidths=0.9)
+
+ # ── SRC curves — original thin solid, calibrated thick dashed ──
+ if not go_h.empty:
+ ax.plot(go_h["Discharge (m3s-1)"], go_h["Stage"],
+ color="#2471a3", lw=1.8, ls="-", zorder=4,
+ label=f"Original SRC")
+ if not gc_h.empty:
+ ax.plot(gc_h["Discharge (m3s-1)"], gc_h["Stage"],
+ color="#c0392b", lw=3.0, ls="--", zorder=5,
+ label="Calibrated SRC")
+ # Legend proxy for recurrence markers
+ ax.scatter([], [], color="#222222", s=50, marker="o",
+ edgecolors="white", linewidths=0.9,
+ label="Recurrence interval")
+
+ # ── Secondary top x-axis: Manning's n step function ──
+ ax_n = ax.twiny()
+ nx, hy = n_step_curve(zp, n_dict, y_max)
+ ax_n.plot(nx, hy, color="#444", alpha=0.38, lw=2.2, ls="-", zorder=3)
+ ax_n.fill_betweenx(hy, 0, nx, color="#888", alpha=0.07, zorder=2)
+
+ all_n = [v for v in n_dict.values() if v is not None]
+ n_ax_max = max(max(all_n) * 1.45, 0.35) if all_n else 0.40
+ ax_n.set_xlim(0, n_ax_max)
+ ax_n.set_xlabel("Manning's n →", fontsize=10, color="#555", labelpad=5)
+ ax_n.tick_params(axis="x", colors="#666", labelsize=9)
+ # Make sure the top spine is drawn (overriding the rcParam default)
+ for sp in ["right", "left", "bottom"]:
+ ax_n.spines[sp].set_visible(False)
+ ax_n.spines["top"].set_visible(True)
+ ax_n.spines["top"].set_color("#aaa")
+ ax_n.spines["top"].set_linewidth(0.9)
+
+ # ── Main axis cosmetics ──
+ ax.set_xlim(0, x_max)
+ ax.set_ylim(0, y_max)
+ ax.set_xlabel("Discharge (m³/s)", labelpad=8)
+ ax.set_ylabel("Stage (m) [height above thalweg]", labelpad=8)
+ ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f"{x:,.0f}"))
+
+ title = f"Branch {bid} · Gauge {loc_id} · HydroID {hydroid}"
+ if branch_avg:
+ title += "\n(branch 0 : branch-wide average n of both gauges applied)"
+ ax.set_title(title, fontweight="bold", pad=28) # pad leaves room for top axis
+ ax.legend(loc="upper left")
+
+
+# ── Main ──────────────────────────────────────────────────────────
+
+def main():
+ SAVE_TO.mkdir(parents=True, exist_ok=True)
+ elev, rc_all, recur = load_data()
+
+ for bid in find_calibrated_branches():
+ branch_gauges = elev[elev["levpa_id"].astype(str) == str(bid)].copy()
+ branch_gauges = branch_gauges[
+ branch_gauges["location_id"].apply(
+ lambda loc: not rc_all[rc_all["location_id"] == str(loc).zfill(8)].empty
+ )
+ ]
+ if branch_gauges.empty:
+ print(f"Branch {bid}: no RC data — skip")
+ continue
+
+ src_orig = load_src(bid, original=True)
+ src_calib = load_src(bid, original=False)
+ n_g = len(branch_gauges)
+
+ fig, axes = plt.subplots(
+ 1, n_g,
+ figsize=(11 * n_g, 8.5),
+ squeeze=False,
+ constrained_layout=True,
+ )
+
+ for col, (_, g) in enumerate(branch_gauges.iterrows()):
+ draw_gauge(
+ axes[0, col], bid,
+ str(g["location_id"]),
+ int(g["HydroID"]),
+ int(g["feature_id"]),
+ float(g["dem_adj_elevation"]),
+ src_orig, src_calib, rc_all, recur,
+ branch_avg=(bid == "0"),
+ )
+
+ n_reaches = src_orig["HydroID"].nunique()
+ fig.suptitle(
+ f"Manning's n Recurrence Calibration Branch {bid} HUC8 {HUC8}\n"
+ f"{n_reaches} reaches · {n_g} USGS gauge(s) · "
+ f"x-axis: ~100-yr discharge · top axis: n vs HAND stage",
+ fontsize=12, fontweight="bold",
+ )
+
+ out = SAVE_TO / f"src_calib_branch_{bid}.png"
+ fig.savefig(out, dpi=200, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ print(f" Saved: {out}")
+
+ print(f"\nDone -> {SAVE_TO}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/plot_src_calibration_inset.py b/scripts/legacy/plot_src_calibration_inset.py
new file mode 100644
index 0000000..a051d9a
--- /dev/null
+++ b/scripts/legacy/plot_src_calibration_inset.py
@@ -0,0 +1,461 @@
+"""
+Calibration comparison plots — variant with bottom-right inset for n vs HAND stage.
+
+Identical to plot_src_calibration.py except:
+ • No secondary top x-axis (twiny).
+ • Bottom-right inset axes showing Manning's n as a step function vs HAND stage,
+ with the same zone colouring as the main plot.
+
+Outputs saved as src_calib_inset_branch_{bid}.png (distinct from the top-axis variant).
+
+Run:
+ .venv\\Scripts\\python.exe scripts/plot_src_calibration_inset.py
+"""
+from __future__ import annotations
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+import matplotlib.ticker as mticker
+import numpy as np
+import pandas as pd
+
+# ── Publication style ─────────────────────────────────────────────
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans",
+ "font.size": 11,
+ "axes.labelsize": 13,
+ "axes.titlesize": 12,
+ "xtick.labelsize": 11,
+ "ytick.labelsize": 11,
+ "legend.fontsize": 10.5,
+ "legend.framealpha": 0.93,
+ "legend.edgecolor": "#cccccc",
+ "axes.spines.top": False,
+ "axes.spines.right": False,
+ "axes.grid": True,
+ "grid.alpha": 0.28,
+ "grid.linestyle": ":",
+})
+
+# ── CONFIG ────────────────────────────────────────────────────────
+HUC8 = "03020102"
+OUT_DIR = Path("D:/SI/out")
+DATA_DIR = Path("data")
+# ─────────────────────────────────────────────────────────────────
+
+AOI_ROOT = OUT_DIR / f"HUC{HUC8}"
+WATERSHED = AOI_ROOT / "watershed-data"
+BRANCHES = WATERSHED / "branches"
+SAVE_TO = AOI_ROOT / "src_plots"
+
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+
+ZONE_COLOURS = ["#aed6f1", "#a9dfbf", "#fad7a0", "#f9e79f", "#f1948a", "#d2b4de"]
+ZONE_ALPHA = 0.40
+
+
+# ── Loaders ───────────────────────────────────────────────────────
+
+def load_data():
+ elev = pd.read_csv(
+ AOI_ROOT / "usgs_elev_table.csv",
+ dtype={"location_id": str, "feature_id": "Int64"},
+ )
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["flow_cms"] = rc["flow"].astype(float) / 35.3147
+ rc["elev_m"] = rc["elevation_navd88"].astype(float) / 3.28084
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr in RECURRENCE_YEARS:
+ recur[f"Q_{yr}yr_cms"] = (
+ recur[f"{yr}_0_year_recurrence_flow_17C"].astype(float) * 0.028317
+ )
+ return elev, rc, recur
+
+
+def load_src(bid: str, original: bool) -> pd.DataFrame:
+ branch_dir = BRANCHES / bid
+ fname = f"src_full_crosswalked_{bid}"
+ path = branch_dir / (fname + (".pre_n_calib.csv" if original else ".csv"))
+ if original and not path.exists():
+ path = branch_dir / f"{fname}.csv"
+ return pd.read_csv(path, low_memory=False)
+
+
+def find_calibrated_branches() -> list[str]:
+ return [
+ bd.name for bd in sorted(BRANCHES.iterdir())
+ if bd.is_dir()
+ and (bd / f"src_full_crosswalked_{bd.name}.pre_n_calib.csv").exists()
+ ]
+
+
+# ── Zone helpers ──────────────────────────────────────────────────
+
+def zone_pts(loc_id, feature_id, dem_adj_m, rc_all, recur):
+ loc = loc_id.zfill(8)
+ grc = rc_all[rc_all["location_id"] == loc].sort_values("flow_cms")
+ if grc.empty:
+ return []
+ feat = recur[recur["feature_id"] == feature_id]
+ if feat.empty:
+ return []
+ pts = []
+ for yr in RECURRENCE_YEARS:
+ Q = float(feat[f"Q_{yr}yr_cms"].iloc[0])
+ if Q < grc["flow_cms"].min() or Q > grc["flow_cms"].max():
+ continue
+ elev = float(np.interp(Q, grc["flow_cms"].values, grc["elev_m"].values))
+ h = elev - dem_adj_m
+ if h > 0:
+ pts.append((yr, h, Q))
+ return sorted(pts, key=lambda x: x[0])
+
+
+def back_calc_n(hydroid, src_df, zp):
+ hdf = src_df[src_df["HydroID"] == hydroid].sort_values("Stage")
+ if hdf.empty:
+ return {}
+ slope = float(hdf["SLOPE"].iloc[0])
+ if slope <= 0:
+ return {}
+ out = {}
+ for yr, h, Q in zp:
+ idx = (hdf["Stage"] - h).abs().idxmin()
+ row = hdf.loc[idx]
+ A = float(row.get("WetArea (m2)", 0.0))
+ R = float(row.get("HydraulicRadius (m)", 0.0))
+ if A > 0 and R > 0 and Q > 0:
+ out[yr] = float(np.clip(A * (R ** (2 / 3)) * slope**0.5 / Q, 0.01, 0.30))
+ return out
+
+
+def _src_q_at_h(h, src_hid):
+ if src_hid.empty:
+ return 0.0
+ return float(np.interp(
+ h, src_hid["Stage"].values, src_hid["Discharge (m3s-1)"].values,
+ left=0.0, right=float(src_hid["Discharge (m3s-1)"].max()),
+ ))
+
+
+def n_step_curve(zp, n_dict, y_max):
+ """(n_vals, h_vals) for a horizontal step function: n on x, HAND stage on y."""
+ yrs = [yr for yr, _, _ in zp]
+ n_arr = [n_dict.get(yr, 0.06) for yr in yrs]
+ n_arr.append(n_dict.get(yrs[-1], 0.06) if yrs else 0.06)
+
+ h_brk = [0.0] + [h for _, h, _ in zp]
+ if h_brk[-1] < y_max:
+ h_brk.append(y_max)
+
+ nx, hy = [], []
+ for i, (h_lo, h_hi) in enumerate(zip(h_brk[:-1], h_brk[1:])):
+ n_v = n_arr[i]
+ nx.extend([n_v, n_v])
+ hy.extend([h_lo, h_hi])
+ if i < len(h_brk) - 2:
+ nx.append(n_arr[i + 1])
+ hy.append(h_hi)
+
+ return nx, hy
+
+
+# ── Bottom-right inset: n vs HAND stage ───────────────────────────
+
+def draw_n_inset(ax, zp, n_dict, y_max):
+ """
+ Adds a small inset in the bottom-right corner of ax showing Manning's n
+ as a piecewise step function vs HAND stage. Zone colours match the main plot.
+ The bottom-right corner is typically empty in a stage-discharge plot because
+ discharge increases with stage, leaving high-Q / low-h space unused.
+ """
+ inset = ax.inset_axes([0.68, 0.04, 0.27, 0.33]) # [x0, y0, w, h] in axes fraction
+
+ yrs = [yr for yr, _, _ in zp]
+ h_brk = [0.0] + [h for _, h, _ in zp]
+ if h_brk[-1] < y_max:
+ h_brk.append(y_max)
+ n_arr = [n_dict.get(yr, 0.06) for yr in yrs]
+ n_arr.append(n_dict.get(yrs[-1], 0.06) if yrs else 0.06)
+
+ all_n = [v for v in n_arr if v is not None]
+ if not all_n:
+ return
+
+ n_lo = 0.0
+ n_hi = max(all_n) * 1.45
+
+ # ── Zone-coloured horizontal bands ──
+ for i, (h_lo, h_hi) in enumerate(zip(h_brk[:-1], h_brk[1:])):
+ col = ZONE_COLOURS[min(i, len(ZONE_COLOURS) - 1)]
+ h_hi_c = min(h_hi, y_max)
+ inset.axhspan(h_lo, h_hi_c, color=col, alpha=0.55, lw=0, zorder=0)
+
+ # ── Step function line ──
+ nx, hy = n_step_curve(zp, n_dict, y_max)
+ inset.plot(nx, hy, color="#1a1a1a", lw=2.4, zorder=4, solid_capstyle="butt")
+
+ # ── n value label centred in each zone band ──
+ for i, (h_lo, h_hi) in enumerate(zip(h_brk[:-1], h_brk[1:])):
+ n_v = n_arr[i]
+ h_mid = (h_lo + min(h_hi, y_max)) / 2
+ if h_mid <= y_max and n_v is not None:
+ # Place text just to the right of the step line, near the right edge
+ txt_x = n_v + (n_hi - n_v) * 0.20
+ txt_x = min(txt_x, n_hi * 0.95)
+ inset.text(
+ txt_x, h_mid, f"{n_v:.3f}",
+ ha="left", va="center", fontsize=7.5,
+ color="#1a1a1a", fontweight="bold",
+ )
+
+ # ── Zone boundary dotted lines ──
+ for _, h, _ in zp:
+ inset.axhline(h, color="#888", ls=":", lw=0.8, alpha=0.7, zorder=2)
+
+ # ── Axes cosmetics ──
+ inset.set_xlim(n_lo, n_hi)
+ inset.set_ylim(0, y_max)
+ inset.set_xlabel("Manning's n", fontsize=8.5, labelpad=3, color="#333")
+ inset.set_ylabel("h (m)", fontsize=8.5, labelpad=3, color="#333")
+ inset.tick_params(labelsize=7.5, colors="#555", length=3)
+ inset.xaxis.set_major_locator(mticker.MaxNLocator(3, prune="both"))
+ inset.yaxis.set_major_locator(mticker.MaxNLocator(4, prune="both"))
+ inset.set_title("n vs stage", fontsize=8.5, pad=4, color="#333",
+ fontweight="bold")
+
+ # White semi-transparent background so it floats above main plot
+ inset.patch.set_facecolor("white")
+ inset.patch.set_alpha(0.88)
+ for sp in ["top", "right"]:
+ inset.spines[sp].set_visible(False)
+ for sp in ["bottom", "left"]:
+ inset.spines[sp].set_color("#999")
+ inset.spines[sp].set_linewidth(0.8)
+ inset.grid(True, alpha=0.18, color="#aaa", linestyle=":")
+
+ # Thin border box around the whole inset
+ for sp in inset.spines.values():
+ sp.set_linewidth(0.8)
+
+
+# ── Main subplot drawing ──────────────────────────────────────────
+
+def draw_gauge(ax, bid, loc_id, hydroid, feature_id, dem_adj_m,
+ src_orig, src_calib, rc_all, recur, branch_avg):
+
+ zp = zone_pts(loc_id, feature_id, dem_adj_m, rc_all, recur)
+ n_dict = back_calc_n(hydroid, src_orig, zp)
+
+ loc_pad = loc_id.zfill(8)
+ grc = rc_all[rc_all["location_id"] == loc_pad].sort_values("flow_cms").copy()
+ grc["hand"] = grc["elev_m"] - dem_adj_m
+ grc = grc[grc["hand"] > 0]
+
+ # ── Axis limits (~100-yr view) ──
+ h_max_yr = max((h for _, h, _ in zp), default=5.0)
+ y_max = max(h_max_yr * 1.50, 3.0)
+
+ target_elev = dem_adj_m + y_max
+ rc_raw = rc_all[rc_all["location_id"] == loc_pad].sort_values("elev_m")
+ rc_below = rc_raw[rc_raw["elev_m"] <= target_elev]
+ rc_q_max = float(rc_below["flow_cms"].max()) if not rc_below.empty else 0.0
+ x_max = max(rc_q_max, max((Q for _, _, Q in zp), default=50) * 1.4) * 1.08
+
+ go_h = src_orig[src_orig["HydroID"] == hydroid].sort_values("Stage")
+ gc_h = src_calib[src_calib["HydroID"] == hydroid].sort_values("Stage")
+
+ # ── Zone shading + right-side labels ──
+ yrs_list = [yr for yr, _, _ in zp]
+ h_edges = [0.0] + [h for _, h, _ in zp]
+ if h_edges[-1] < y_max:
+ h_edges.append(y_max)
+
+ prev = 0
+ zone_labels = []
+ for yr in yrs_list:
+ zone_labels.append(f"{prev}-{yr} yr")
+ prev = yr
+ zone_labels.append(f"> {prev} yr")
+
+ n_per_zone = [n_dict.get(yr) for yr in yrs_list]
+ n_per_zone.append(n_dict.get(yrs_list[-1]) if yrs_list else None)
+
+ # Inset occupies axes fraction [0.68, 0.04, 0.27, 0.33]:
+ # x: 0.68–0.95 of x_max y: 0.04–0.37 of y_max
+ # Lower zone labels are placed LEFT of the inset; upper zone labels go right
+ # and are staggered into two columns when they stack too close vertically.
+ INSET_Y_TOP = 0.37 # inset top edge as fraction of y_max
+ INSET_X_LEFT = 0.68 # inset left edge as fraction of x_max
+
+ prev_upper_h = -1.0 # last placed upper-zone label h_mid
+ stagger_right = True # alternates column when upper labels are compressed
+
+ for i, (h_lo, h_hi) in enumerate(zip(h_edges[:-1], h_edges[1:])):
+ h_hi_c = min(h_hi, y_max)
+ col = ZONE_COLOURS[min(i, len(ZONE_COLOURS) - 1)]
+ ax.axhspan(h_lo, h_hi_c, color=col, alpha=ZONE_ALPHA, zorder=0, lw=0)
+
+ h_mid = (h_lo + h_hi_c) / 2
+ q_max_src = max(_src_q_at_h(h_mid, go_h), _src_q_at_h(h_mid, gc_h))
+
+ if h_mid < INSET_Y_TOP * y_max:
+ # Lower zone: keep label LEFT of inset so they never overlap
+ lx = float(np.clip(
+ max(q_max_src * 2.0, x_max * 0.26),
+ q_max_src * 1.4,
+ INSET_X_LEFT * x_max * 0.86, # cap well below inset left edge
+ ))
+ prev_upper_h = -1.0 # reset upper stagger when we re-enter lower zones
+ stagger_right = True
+ else:
+ # Upper zone: right side, stagger into two columns when compressed
+ if prev_upper_h > 0 and abs(h_mid - prev_upper_h) < 0.12 * y_max:
+ if stagger_right:
+ lx = float(np.clip(max(q_max_src * 1.25, x_max * 0.74),
+ 0, x_max * 0.95))
+ stagger_right = False
+ else:
+ lx = float(np.clip(max(q_max_src * 1.25, x_max * 0.55),
+ 0, x_max * 0.73))
+ stagger_right = True
+ else:
+ lx = float(np.clip(max(q_max_src * 1.25, x_max * 0.65),
+ 0, x_max * 0.95))
+ stagger_right = True # next close label starts in right column
+ prev_upper_h = h_mid
+
+ n_v = n_per_zone[i]
+ lbl = zone_labels[i] + (f"\nn = {n_v:.3f}" if n_v is not None else "")
+ ax.text(lx, h_mid, lbl,
+ ha="center", va="center", fontsize=9.5, color="#222",
+ bbox=dict(boxstyle="round,pad=0.35", fc="white",
+ ec=col, linewidth=1.4, alpha=0.95),
+ zorder=9)
+
+ for _, h, _ in zp:
+ ax.axhline(h, color="#888", ls=":", lw=0.9, alpha=0.60, zorder=1)
+
+ # ── USGS RC ──
+ if not grc.empty:
+ rc_plt = grc[grc["hand"] <= y_max * 1.02]
+ ax.plot(rc_plt["flow_cms"], rc_plt["hand"],
+ color="#1a7a4a", lw=2.5, ls="--", zorder=5,
+ label=f"USGS RC (gauge {loc_id})")
+
+ # ── Recurrence markers — cascade stagger to prevent label overlap ──
+ MIN_SEP_FRAC = 0.09
+ label_ys = []
+
+ for yr, h, Q in zp:
+ ly = h
+ while any(abs(ly - py) < MIN_SEP_FRAC * y_max for py in label_ys):
+ ly += MIN_SEP_FRAC * y_max * 0.55
+ ly = min(ly, y_max * 0.97)
+ label_ys.append(ly)
+
+ ax.scatter(Q, h, color="#1a7a4a", s=110, zorder=7, marker="D")
+
+ lx = Q + x_max * 0.04
+ needs_arrow = abs(ly - h) > y_max * 0.04
+
+ if needs_arrow:
+ ax.annotate(
+ f"{yr} yr",
+ xy=(Q, h),
+ xytext=(lx, ly),
+ arrowprops=dict(arrowstyle="->", color="#1a7a4a",
+ lw=0.85, connectionstyle="arc3,rad=0.0"),
+ fontsize=9.5, color="#1a7a4a", fontweight="bold",
+ ha="left", va="center", zorder=8,
+ )
+ else:
+ ax.text(lx, ly, f"{yr} yr",
+ fontsize=9.5, color="#1a7a4a", fontweight="bold",
+ ha="left", va="center", zorder=8)
+
+ # ── SRC curves ──
+ if not go_h.empty:
+ ax.plot(go_h["Discharge (m3s-1)"], go_h["Stage"],
+ color="#2471a3", lw=3.0, zorder=4,
+ label=f"Original SRC (HydroID {hydroid})")
+ if not gc_h.empty:
+ ax.plot(gc_h["Discharge (m3s-1)"], gc_h["Stage"],
+ color="#c0392b", lw=3.0, zorder=4,
+ label="Calibrated SRC")
+
+ # ── Bottom-right inset: n vs HAND stage ──
+ draw_n_inset(ax, zp, n_dict, y_max)
+
+ # ── Main axis cosmetics ──
+ ax.set_xlim(0, x_max)
+ ax.set_ylim(0, y_max)
+ ax.set_xlabel("Discharge (m3/s)", labelpad=8)
+ ax.set_ylabel("HAND Stage (m) [height above thalweg]", labelpad=8)
+ ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f"{x:,.0f}"))
+
+ title = f"Branch {bid} - Gauge {loc_id} - HydroID {hydroid}"
+ if branch_avg:
+ title += "\n(branch 0 : branch-wide average n of both gauges applied)"
+ ax.set_title(title, fontweight="bold", pad=10)
+ ax.legend(loc="upper left")
+
+
+# ── Main ──────────────────────────────────────────────────────────
+
+def main():
+ SAVE_TO.mkdir(parents=True, exist_ok=True)
+ elev, rc_all, recur = load_data()
+
+ for bid in find_calibrated_branches():
+ branch_gauges = elev[elev["levpa_id"].astype(str) == str(bid)].copy()
+ branch_gauges = branch_gauges[
+ branch_gauges["location_id"].apply(
+ lambda loc: not rc_all[rc_all["location_id"] == str(loc).zfill(8)].empty
+ )
+ ]
+ if branch_gauges.empty:
+ print(f"Branch {bid}: no RC data - skip")
+ continue
+
+ src_orig = load_src(bid, original=True)
+ src_calib = load_src(bid, original=False)
+ n_g = len(branch_gauges)
+
+ fig, axes = plt.subplots(
+ 1, n_g,
+ figsize=(11 * n_g, 8.5),
+ squeeze=False,
+ constrained_layout=True,
+ )
+
+ for col, (_, g) in enumerate(branch_gauges.iterrows()):
+ draw_gauge(
+ axes[0, col], bid,
+ str(g["location_id"]),
+ int(g["HydroID"]),
+ int(g["feature_id"]),
+ float(g["dem_adj_elevation"]),
+ src_orig, src_calib, rc_all, recur,
+ branch_avg=(bid == "0"),
+ )
+
+ n_reaches = src_orig["HydroID"].nunique()
+ fig.suptitle(
+ f"Manning's n Recurrence Calibration Branch {bid} HUC8 {HUC8}\n"
+ f"{n_reaches} reaches - {n_g} USGS gauge(s) - "
+ f"x-axis: ~100-yr discharge - inset: n vs HAND stage",
+ fontsize=12, fontweight="bold",
+ )
+
+ out = SAVE_TO / f"src_calib_inset_branch_{bid}.png"
+ fig.savefig(out, dpi=200, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ print(f" Saved: {out}")
+
+ print(f"\nDone -> {SAVE_TO}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/plot_srcs.py b/scripts/legacy/plot_srcs.py
new file mode 100644
index 0000000..7fd2af6
--- /dev/null
+++ b/scripts/legacy/plot_srcs.py
@@ -0,0 +1,168 @@
+"""
+Plot Synthetic Rating Curves (SRCs) for a single HUC8 after Stage 2.
+
+Reads all hydroTable_*.csv files from every branch, then produces two figures:
+ 1. Overview — all SRCs on one axes, colored by Strahler order
+ 2. Branch grid — one subplot per branch showing individual reach SRCs
+
+Run:
+ .venv\\Scripts\\python.exe scripts/plot_srcs.py
+"""
+from pathlib import Path
+import pandas as pd
+import matplotlib.pyplot as plt
+import matplotlib.colors as mcolors
+import numpy as np
+
+# ── CONFIG ────────────────────────────────────────────────────────
+HUC8 = "03020102"
+OUT_DIR = Path("D:/SI/out")
+SAVE_TO = Path("D:/SI/out") / f"HUC{HUC8}" / "src_plots"
+# ─────────────────────────────────────────────────────────────────
+
+WATERSHED = OUT_DIR / f"HUC{HUC8}" / "watershed-data"
+BRANCHES = WATERSHED / "branches"
+
+
+def load_all_hydrotables() -> pd.DataFrame:
+ frames = []
+ for branch_dir in sorted(BRANCHES.iterdir()):
+ if not branch_dir.is_dir():
+ continue
+ branch_id = branch_dir.name
+ htable = branch_dir / f"hydroTable_{branch_id}.csv"
+ if not htable.exists():
+ continue
+ df = pd.read_csv(htable, dtype={"feature_id": str})
+ df["branch_id"] = branch_id
+ frames.append(df)
+ if not frames:
+ raise FileNotFoundError(f"No hydroTable CSVs found under {BRANCHES}")
+ return pd.concat(frames, ignore_index=True)
+
+
+def _order_cmap(orders):
+ max_order = max(orders) if orders else 5
+ cmap = plt.colormaps["plasma_r"].resampled(max_order)
+ return {o: mcolors.to_hex(cmap(o / max_order)) for o in range(1, max_order + 1)}
+
+
+def plot_overview(df: pd.DataFrame, save_to: Path) -> None:
+ """All SRCs on one axes, colored by Strahler stream order."""
+ fig, ax = plt.subplots(figsize=(10, 7))
+
+ orders = sorted(df["order_"].dropna().unique().astype(int))
+ colors = _order_cmap(orders)
+
+ for order in orders:
+ subset = df[df["order_"] == order]
+ for _, grp in subset.groupby("HydroID"):
+ grp_s = grp.sort_values("stage")
+ ax.plot(
+ grp_s["discharge_cms"],
+ grp_s["stage"],
+ color=colors[order],
+ alpha=0.25,
+ linewidth=0.7,
+ )
+
+ # Legend — one proxy per order
+ handles = [
+ plt.Line2D([0], [0], color=colors[o], linewidth=1.5, label=f"Order {o}")
+ for o in orders
+ ]
+ ax.legend(handles=handles, title="Strahler Order", loc="upper left", fontsize=8)
+
+ ax.set_xlabel("Discharge (m³/s)", fontsize=11)
+ ax.set_ylabel("Stage (m)", fontsize=11)
+ ax.set_title(f"Synthetic Rating Curves — HUC8 {HUC8}\n"
+ f"({df['HydroID'].nunique()} reaches across "
+ f"{df['branch_id'].nunique()} branches)",
+ fontsize=12)
+ ax.set_xlim(left=0)
+ ax.set_ylim(bottom=0)
+ ax.grid(True, alpha=0.3)
+ fig.tight_layout()
+
+ out = save_to / "src_overview.png"
+ fig.savefig(out, dpi=150)
+ plt.close(fig)
+ print(f"Saved: {out}")
+
+
+def plot_branch_grid(df: pd.DataFrame, save_to: Path) -> None:
+ """One subplot per branch, each reach as a separate line."""
+ branches = sorted(df["branch_id"].unique())
+ n = len(branches)
+ ncols = 4
+ nrows = int(np.ceil(n / ncols))
+
+ fig, axes = plt.subplots(nrows, ncols, figsize=(ncols * 4, nrows * 3.5),
+ sharex=False, sharey=False)
+ axes_flat = np.array(axes).flatten()
+
+ orders_global = sorted(df["order_"].dropna().unique().astype(int))
+ colors = _order_cmap(orders_global)
+
+ for i, branch_id in enumerate(branches):
+ ax = axes_flat[i]
+ bdf = df[df["branch_id"] == branch_id]
+
+ for order in orders_global:
+ subset = bdf[bdf["order_"] == order]
+ for _, grp in subset.groupby("HydroID"):
+ grp_s = grp.sort_values("stage")
+ ax.plot(
+ grp_s["discharge_cms"],
+ grp_s["stage"],
+ color=colors[order],
+ alpha=0.5,
+ linewidth=0.9,
+ )
+
+ ax.set_title(f"Branch {branch_id}\n({bdf['HydroID'].nunique()} reaches)",
+ fontsize=7)
+ ax.set_xlabel("Q (m³/s)", fontsize=7)
+ ax.set_ylabel("Stage (m)", fontsize=7)
+ ax.tick_params(labelsize=6)
+ ax.set_xlim(left=0)
+ ax.set_ylim(bottom=0)
+ ax.grid(True, alpha=0.3)
+
+ # Hide unused subplots
+ for j in range(i + 1, len(axes_flat)):
+ axes_flat[j].set_visible(False)
+
+ # Shared legend at the bottom
+ handles = [
+ plt.Line2D([0], [0], color=colors[o], linewidth=1.5, label=f"Order {o}")
+ for o in orders_global
+ ]
+ fig.legend(handles=handles, title="Strahler Order",
+ loc="lower right", ncol=len(orders_global), fontsize=8)
+
+ fig.suptitle(f"SRCs by Branch — HUC8 {HUC8}", fontsize=13, y=1.01)
+ fig.tight_layout()
+
+ out = save_to / "src_by_branch.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight")
+ plt.close(fig)
+ print(f"Saved: {out}")
+
+
+def main():
+ SAVE_TO.mkdir(parents=True, exist_ok=True)
+
+ print(f"Loading hydroTables from {BRANCHES} ...")
+ df = load_all_hydrotables()
+ print(f" {len(df):,} rows | {df['HydroID'].nunique()} reaches | "
+ f"{df['branch_id'].nunique()} branches")
+
+ plot_overview(df, SAVE_TO)
+ plot_branch_grid(df, SAVE_TO)
+
+ print("\nDone. Plots saved to:", SAVE_TO)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/plot_workflow_chart.py b/scripts/legacy/plot_workflow_chart.py
new file mode 100644
index 0000000..2d720cf
--- /dev/null
+++ b/scripts/legacy/plot_workflow_chart.py
@@ -0,0 +1,240 @@
+"""
+PPT-ready workflow chart for the FIMbox calibration pipeline.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/plot_workflow_chart.py
+"""
+from pathlib import Path
+from matplotlib.patches import FancyBboxPatch
+import matplotlib.pyplot as plt
+import matplotlib as mpl
+
+mpl.rcParams["font.family"] = "DejaVu Sans"
+
+SAVE_TO = Path("D:/SI/out/HUC03020102/src_plots")
+
+# ── Color palette ─────────────────────────────────────────────────
+C_PIPE = "#1b4f72" # dark navy — OWP pipeline stages
+C_CUSTOM = "#a04000" # burnt orange — custom scripts (our work)
+C_DATA = "#1a6b3c" # dark green — external data sources
+C_OUT = "#0e6655" # teal — calibrated outputs
+C_FUTURE = "#717d7e" # gray — future steps
+C_ML = "#6c3483" # purple — ML future step
+BG = "#f0f3f4" # background
+
+
+# ── Helpers ───────────────────────────────────────────────────────
+
+def draw_box(ax, cx, cy, w, h, lines, color, tc="white",
+ fs=9.5, future=False):
+ lx, by = cx - w / 2, cy - h / 2
+ fc = "#c8cacb" if future else color
+ ls = "--" if future else "-"
+ lw = 1.2 if future else 2.0
+ ec = "#aaa" if future else "white"
+ tc_use = "#666" if future else tc
+
+ ax.add_patch(FancyBboxPatch(
+ (lx, by), w, h,
+ boxstyle="round,pad=0.13",
+ facecolor=fc, edgecolor=ec,
+ linewidth=lw, linestyle=ls, zorder=3,
+ ))
+ ax.text(cx, cy, "\n".join(lines),
+ ha="center", va="center", fontsize=fs,
+ color=tc_use, fontweight="bold",
+ multialignment="center", linespacing=1.45,
+ zorder=4)
+
+
+def arrow(ax, x1, y1, x2, y2, color="#444", lw=2.0, rad=0.0):
+ ax.annotate("", xy=(x2, y2), xytext=(x1, y1),
+ arrowprops=dict(
+ arrowstyle="-|>", color=color,
+ lw=lw, mutation_scale=14,
+ connectionstyle=f"arc3,rad={rad}",
+ ),
+ zorder=5, annotation_clip=False)
+
+
+def legend_entry(ax, cx, cy, w, h, color, label, future=False):
+ fc = "#c8cacb" if future else color
+ ax.add_patch(FancyBboxPatch(
+ (cx - w/2, cy - h/2), w, h,
+ boxstyle="round,pad=0.06",
+ facecolor=fc, edgecolor="white",
+ linewidth=1.0, linestyle="--" if future else "-",
+ zorder=3,
+ ))
+ ax.text(cx + w/2 + 0.15, cy, label,
+ ha="left", va="center", fontsize=8.5,
+ color="#222", zorder=4)
+
+
+# ── Figure ────────────────────────────────────────────────────────
+
+fig, ax = plt.subplots(figsize=(17, 11))
+ax.set_xlim(0, 17)
+ax.set_ylim(0, 11)
+ax.axis("off")
+fig.patch.set_facecolor(BG)
+ax.set_facecolor(BG)
+
+MX = 8.7 # main pipeline x-center
+BW = 5.6 # main box width
+
+# ── Title ─────────────────────────────────────────────────────────
+
+ax.text(MX, 10.7,
+ "FIMbox Manning's n Calibration Pipeline",
+ ha="center", va="center", fontsize=15,
+ fontweight="bold", color="#111")
+ax.text(MX, 10.35,
+ "NOAA OWP HAND-FIM Testbed | NC/SC Coastal Study Area | 24 HUC8s",
+ ha="center", va="center", fontsize=10, color="#555")
+
+# ── Main pipeline boxes ───────────────────────────────────────────
+
+# 1. Study area
+draw_box(ax, MX, 9.55, BW, 0.62,
+ ["Study Area Definition",
+ "24 HUC8s | NC / SC Coast (HUC2 = 03) | Test HUC8: 03020102"],
+ C_PIPE)
+
+# 2. Stage 1
+draw_box(ax, MX, 8.60, BW, 0.65,
+ ["Stage 1 - Input Data Acquisition",
+ "NWM streams WBD boundaries DEM NHD flowlines"],
+ C_PIPE)
+
+# 3. Stage 2
+draw_box(ax, MX, 7.38, BW, 0.90,
+ ["Stage 2 - HAND-FIM Preprocessing (OWP FIMbox)",
+ "17 branches (1 trunk + 16 level-path branches)",
+ "HAND rasters | Synthetic Rating Curves (SRCs) per HydroID"],
+ C_PIPE)
+
+# 4. USGS Crosswalk
+draw_box(ax, MX, 5.93, BW, 0.90,
+ ["USGS Gage Crosswalk",
+ "Download gauges | Assign to NWM branches",
+ "Snap to thalweg | Extract HAND-stage elevation"],
+ C_CUSTOM)
+
+# 5. n Calibration
+draw_box(ax, MX, 4.48, BW, 0.90,
+ ["Manning's n Calibration",
+ "Back-calculate n at 6 recurrence-interval zones (2, 5, 10, 25, 50, >50 yr)",
+ "Piecewise n applied to directly calibrated branches only"],
+ C_CUSTOM)
+
+# 6a. Calibrated branches (left branch)
+draw_box(ax, 4.5, 3.00, 4.6, 0.82,
+ ["Calibrated Branches (2 of 17)",
+ "Branch 3351000014 | Gauge 02083000",
+ "Branch 3351000023 | Gauge 02082950"],
+ C_OUT)
+
+# 6b. Ungauged (right branch — future)
+draw_box(ax, 13.2, 3.00, 4.6, 0.82,
+ ["Ungauged Branches (15 of 17)",
+ "ML-based n Regionalization",
+ "(future work)"],
+ C_ML, future=True)
+
+# 7. Validation plots
+draw_box(ax, 4.5, 1.72, 4.6, 0.82,
+ ["Calibration Validation Plots",
+ "Orig. SRC vs Calibrated SRC vs USGS RC",
+ "Manning's n variation with HAND stage"],
+ C_CUSTOM)
+
+# 8. Future pipeline bar
+draw_box(ax, 8.7, 0.55, 14.0, 0.60,
+ ["Stage 3: Streamflow Mapping Stage 4: FIM Calibration Stage 5: FIM Generation (Flood Inundation Maps)"],
+ C_FUTURE, future=True)
+
+# ── External data source boxes ────────────────────────────────────
+
+# USGS gauge network → Crosswalk
+draw_box(ax, 15.2, 5.93, 2.9, 0.62,
+ ["USGS Gauge Network",
+ "ArcGIS Online API"],
+ C_DATA, fs=8.8)
+
+# USGS RC + NWM Recurrence → Calibration
+draw_box(ax, 15.2, 4.48, 2.9, 0.82,
+ ["USGS Rating Curves",
+ "usgs_rating_curves.parquet",
+ "NWM Recurrence Flows (2-50 yr)"],
+ C_DATA, fs=8.5)
+
+# ── Arrows ────────────────────────────────────────────────────────
+
+PIPE_COL = "#1b4f72"
+
+# Main vertical flow
+arrow(ax, MX, 9.24, MX, 8.93) # Study → Stage1
+arrow(ax, MX, 8.28, MX, 7.83) # Stage1 → Stage2
+arrow(ax, MX, 6.93, MX, 6.38) # Stage2 → Crosswalk
+arrow(ax, MX, 5.48, MX, 4.93) # Crosswalk → Calibration
+
+# Calibration → split
+arrow(ax, 7.0, 4.03, 5.0, 3.42, color="#0e6655") # → Calibrated
+arrow(ax, 10.4, 4.03, 12.6, 3.42, color=C_ML) # → Ungauged
+
+# Calibrated → Validation
+arrow(ax, 4.5, 2.59, 4.5, 2.13, color="#0e6655")
+
+# Validation → Future
+arrow(ax, 5.8, 1.31, 7.5, 0.85, color="#777", lw=1.5)
+
+# Data inputs (horizontal)
+arrow(ax, 13.75, 5.93, 11.51, 5.93, color=C_DATA, lw=1.6) # gauges → crosswalk
+arrow(ax, 13.75, 4.48, 11.51, 4.48, color=C_DATA, lw=1.6) # RC+NWM → calibration
+
+# ── "Future Work" separator line ──────────────────────────────────
+
+ax.plot([1.0, 16.0], [1.18, 1.18],
+ color="#aaa", lw=1.2, ls="--", zorder=2)
+ax.text(16.1, 1.18, "Future", ha="left", va="center",
+ fontsize=8.5, color="#777", fontstyle="italic")
+
+# ── Legend (upper-left, clear of all boxes) ──────────────────────
+
+items = [
+ (C_PIPE, "OWP FIMbox Pipeline Stage (completed)", False),
+ (C_CUSTOM, "Custom Script (this project)", False),
+ (C_DATA, "External Data Source", False),
+ (C_OUT, "Calibrated Output", False),
+ (C_ML, "Future - ML Regionalization", True),
+ (C_FUTURE, "Future - Pipeline Continuation", True),
+]
+
+lx0, ly0, dy = 0.55, 8.60, 0.50
+
+# subtle background panel
+n_items = len(items)
+panel_h = dy * n_items + 0.15
+panel_y = ly0 - panel_h + 0.38
+ax.add_patch(FancyBboxPatch(
+ (0.18, panel_y - 0.10), 4.55, panel_h + 0.55,
+ boxstyle="round,pad=0.08",
+ facecolor="white", edgecolor="#ccc",
+ linewidth=0.9, alpha=0.82, zorder=2,
+))
+
+ax.text(0.40, ly0 + 0.38, "Legend", ha="left", va="center",
+ fontsize=9.5, fontweight="bold", color="#333", zorder=5)
+
+for i, (col, lbl, fut) in enumerate(items):
+ ly = ly0 - i * dy
+ legend_entry(ax, lx0 + 0.22, ly, 0.44, 0.30, col, lbl, future=fut)
+
+fig.tight_layout(pad=0.3)
+
+out = SAVE_TO / "workflow_chart.png"
+SAVE_TO.mkdir(parents=True, exist_ok=True)
+fig.savefig(out, dpi=200, bbox_inches="tight", facecolor=BG)
+plt.close(fig)
+print(f"Saved: {out}")
diff --git a/scripts/legacy/s01_download_dem.py b/scripts/legacy/s01_download_dem.py
new file mode 100644
index 0000000..fc3013b
--- /dev/null
+++ b/scripts/legacy/s01_download_dem.py
@@ -0,0 +1,96 @@
+"""
+Download 10m 3DEP DEM per HUC8, save each tile to disk, then merge.
+This avoids the in-memory OOM that happens when merging all tiles at once
+for a large (24 HUC) study area.
+
+Run ONCE before test_getallinputdata.py, then pass the output path via dem= in the test.
+"""
+from pathlib import Path
+
+import pandas as pd
+import geopandas as gpd
+import py3dep
+from rasterio.merge import merge as rio_merge
+
+# ── EDIT THESE ────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+HUC_CODES = [] # leave empty to use ALL rows; or e.g. [3020102, 3020103]
+EPSG = 5070 # CONUS Albers — matches the rest of the fimbox pipeline
+RESOLUTION = 10 # metres
+# ──────────────────────────────────────────────────────────────────
+
+TEMP_DIR = Path("E:/SI/out/study_area/watershed-data/dem_tiles")
+OUT_DEM = Path("E:/SI/out/study_area/watershed-data/3dep_dem_10m.tif")
+
+from fimbox.preprocessing.download_data.utils import HUC8Finder
+
+
+def _download_huc(huc8: str, finder: HUC8Finder) -> Path | None:
+ tile_path = TEMP_DIR / f"dem_{huc8}.tif"
+ if tile_path.exists():
+ print(f" {huc8}: tile already on disk — skipping download")
+ return tile_path
+
+ print(f" {huc8}: fetching boundary …")
+ try:
+ gdf = finder.from_huc8(huc8)
+ except ValueError:
+ print(f" {huc8}: WARNING — not found in service, skipping")
+ return None
+
+ geom = gdf.to_crs(epsg=4326).union_all()
+
+ print(f" {huc8}: downloading 3DEP 10m …")
+ dem = py3dep.get_dem(geom, resolution=RESOLUTION, crs=4326)
+
+ print(f" {huc8}: reprojecting to EPSG:{EPSG} …")
+ dem = dem.rio.reproject(f"EPSG:{EPSG}")
+ dem = dem.where(dem > -90000, -999999)
+ dem.rio.write_nodata(-999999, inplace=True)
+ dem.rio.to_raster(
+ str(tile_path),
+ driver="GTiff", compress="lzw", tiled=True,
+ blockxsize=256, blockysize=256,
+ )
+ print(f" {huc8}: saved → {tile_path}")
+ return tile_path
+
+
+def main():
+ TEMP_DIR.mkdir(parents=True, exist_ok=True)
+ OUT_DEM.parent.mkdir(parents=True, exist_ok=True)
+
+ df = pd.read_excel(EXCEL_PATH)
+ print(f"Loaded {len(df)} rows from Excel")
+
+ if HUC_CODES:
+ df = df[df[HUC_CODE_COL].isin(HUC_CODES)]
+ print(f"Filtered to {len(df)} rows")
+
+ finder = HUC8Finder()
+ tile_paths = []
+ for code in df[HUC_CODE_COL]:
+ huc8 = str(int(code)).zfill(8)
+ path = _download_huc(huc8, finder)
+ if path is not None:
+ tile_paths.append(path)
+
+ if not tile_paths:
+ raise RuntimeError("No tiles downloaded — nothing to merge.")
+
+ print(f"\nMerging {len(tile_paths)} tiles to {OUT_DEM} …")
+ rio_merge(
+ [str(p) for p in tile_paths],
+ method="first",
+ dst_path=str(OUT_DEM),
+ )
+
+ print(f"\nDone. Merged DEM → {OUT_DEM}")
+ print("\nNext step: in tests/test_getallinputdata.py add:")
+ print(f' dem=Path("{OUT_DEM}"),')
+ print("to the getAllInputData() call.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s02_stage1_single_huc.py b/scripts/legacy/s02_stage1_single_huc.py
new file mode 100644
index 0000000..808844a
--- /dev/null
+++ b/scripts/legacy/s02_stage1_single_huc.py
@@ -0,0 +1,65 @@
+"""
+Stage 1 — Data Download for a SINGLE HUC8.
+Use this to test one HUC before running run_stage1_download.py on all 24.
+
+Set HUC8 below and run:
+ .venv\\Scripts\\python.exe scripts/run_single_huc_stage1.py
+"""
+import logging
+import traceback
+from pathlib import Path
+
+# ── SET THIS ──────────────────────────────────────────────────────
+HUC8 = "03020102"
+# ─────────────────────────────────────────────────────────────────
+
+DEM_TILES_DIR = Path("D:/SI/out/study_area/watershed-data/dem_tiles")
+OUT_DIR = Path("D:/SI/out")
+IDENTIFIER = "nwmmr"
+BUFFER_M = 5000
+TASK_LOG = Path("D:/SI/out/stage1_status.txt")
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage1 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def main():
+ import fimbox
+
+ dem_path = DEM_TILES_DIR / f"dem_{HUC8}.tif"
+ if not dem_path.exists():
+ log.error(f"DEM tile not found: {dem_path}")
+ return
+
+ log.info(f"Stage 1 — HUC8: {HUC8}")
+ try:
+ pp = fimbox.getAllInputData(
+ huc8=HUC8,
+ out_dir=str(OUT_DIR),
+ buffer_m=BUFFER_M,
+ headwater_buffer_cells=8,
+ get_flowlines=True,
+ get_catchments=True,
+ resolution="medium",
+ identifier=IDENTIFIER,
+ dem=dem_path,
+ )
+ pp.run()
+ _log_result(HUC8, "PASS")
+ log.info(f"PASS → {OUT_DIR / f'HUC{HUC8}'}")
+ except Exception:
+ err = traceback.format_exc()
+ _log_result(HUC8, "FAIL", err.splitlines()[-1])
+ log.error(f"FAIL:\n{err}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s03_stage2_single_huc.py b/scripts/legacy/s03_stage2_single_huc.py
new file mode 100644
index 0000000..4efb051
--- /dev/null
+++ b/scripts/legacy/s03_stage2_single_huc.py
@@ -0,0 +1,107 @@
+"""
+Stage 2 — HAND Processing for a SINGLE HUC8.
+Use this to test one HUC before running run_stage2_hand.py on all 24.
+
+Prerequisite: Stage 1 must have completed for this HUC.
+
+Set HUC8 below and run:
+ .venv\\Scripts\\python.exe scripts/run_single_huc_stage2.py
+"""
+import logging
+import traceback
+from pathlib import Path
+
+# ── SET THIS ──────────────────────────────────────────────────────
+HUC8 = "03020102"
+# ─────────────────────────────────────────────────────────────────
+
+OUT_DIR = Path("D:/SI/out")
+IDENTIFIER = "nwmmr"
+CONFIG_DIR = Path("config")
+TASK_LOG = Path("D:/SI/out/stage2_status.txt")
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage2 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def main():
+ from fimbox import AOIProcessingConfig, BranchDerivation, calculate_allbranches
+ from fimbox._dask import _resolve_n_workers
+
+ aoi_dir = OUT_DIR / f"HUC{HUC8}" / "watershed-data"
+ if not aoi_dir.exists():
+ log.error(f"watershed-data not found — run Stage 1 first: {aoi_dir}")
+ return
+
+ def _opt(p: Path):
+ return p if p.exists() else None
+
+ log.info(f"Stage 2 — HUC8: {HUC8}")
+ try:
+ BranchDerivation(
+ out_dir=aoi_dir,
+ branch_id_attribute="levpa_id",
+ reach_id_attribute="ID",
+ branch_buffer_distance_meters=7000.0,
+ ).run()
+
+ cfg = AOIProcessingConfig(
+ aoi_dir=aoi_dir,
+ branch_list_path=aoi_dir / "branch_ids.lst",
+ dem_path=aoi_dir / "dem.tif",
+ streams_gpkg=aoi_dir / f"{IDENTIFIER}_subset_streams.gpkg",
+ boundary_gpkg=aoi_dir / "wbd_buffered.gpkg",
+ bridge_elev_diff_path=_opt(aoi_dir / "bridge_elev_diff.tif"),
+ levee_gpkg_path=_opt(aoi_dir / "3d_nld_subset_levees_burned.gpkg"),
+ headwaters_gpkg=_opt(aoi_dir / f"{IDENTIFIER}_headwater_points_subset.gpkg"),
+ levelpaths_extended_gpkg=_opt(
+ aoi_dir / f"{IDENTIFIER}_subset_streams_levelPaths_extended.gpkg"
+ ),
+ agree_buffer_m=15.0,
+ agree_smooth_drop=10.0,
+ agree_sharp_drop=1000.0,
+ cost_distance_tolerance=50.0,
+ lateral_elevation_threshold=10,
+ max_split_distance_m=1500.0,
+ slope_min=0.0001,
+ lakes_buffer_dist_m=100.0,
+ mannings_n=0.06,
+ stage_min_m=0.0,
+ stage_interval_m=0.3048,
+ stage_max_m=25.2984,
+ min_catchment_area=0.25,
+ min_stream_length=0.5,
+ crosswalk_max_distance_m=100.0,
+ src_slope_source="iris_sword",
+ iris_slope_csv=None,
+ hfab_slope_column=None,
+ n_workers=_resolve_n_workers(),
+ keep_failed_branches=True,
+ delete_deny_list=True,
+ )
+
+ calculate_allbranches(
+ cfg,
+ run_branch_zero=True,
+ delete_deny_list=True,
+ deny_unit_list=CONFIG_DIR / "deny_unit.lst",
+ branch_ids_csv=aoi_dir / "branch_ids.csv",
+ )
+ _log_result(HUC8, "PASS")
+ log.info("PASS")
+ except Exception:
+ err = traceback.format_exc()
+ _log_result(HUC8, "FAIL", err.splitlines()[-1])
+ log.error(f"FAIL:\n{err}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s04_usgs_gage_crosswalk.py b/scripts/legacy/s04_usgs_gage_crosswalk.py
new file mode 100644
index 0000000..64b3365
--- /dev/null
+++ b/scripts/legacy/s04_usgs_gage_crosswalk.py
@@ -0,0 +1,216 @@
+"""
+USGS Gage Crosswalk for a single HUC8.
+Implements steps C20, C21, C22 from the repo (currently commented-out in tests).
+
+Steps:
+ C20 Download USGS gauge points within the HUC8 boundary from ArcGIS Online
+ C21 Assign each gauge to a NWM level path (branch ID)
+ C22 Per-branch: snap gauges to thalweg, sample DEM to get dem_adj_elevation
+ CON Consolidate all per-branch usgs_elev_table.csv into one at AOI root
+ (required by Stage 4 UsgsRatingCalibrator and the n-calibration script)
+
+Prerequisite: Stage 2 must have completed (all branch directories must exist).
+
+Run:
+ .venv\\Scripts\\python.exe scripts/run_usgs_gage_crosswalk.py
+"""
+import logging
+import traceback
+from pathlib import Path
+
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+HUC8 = "03020102"
+OUT_DIR = Path("D:/SI/out")
+# ─────────────────────────────────────────────────────────────────
+
+IDENTIFIER = "nwmmr"
+AOI_ROOT = OUT_DIR / f"HUC{HUC8}"
+WATERSHED = AOI_ROOT / "watershed-data"
+BRANCHES = WATERSHED / "branches"
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def step_c20_download_gages() -> Path:
+ """Download USGS gauge points within the HUC8 boundary."""
+ from fimbox import DownloadUSGSGages
+
+ out_path = WATERSHED / "usgs_gages.gpkg"
+ if out_path.exists():
+ log.info("C20 SKIP (exists): %s", out_path.name)
+ return out_path
+
+ boundary_gpkg = WATERSHED / "wbd.gpkg"
+ if not boundary_gpkg.exists():
+ raise FileNotFoundError(f"HUC boundary not found: {boundary_gpkg}")
+
+ log.info("C20: Downloading USGS gages for HUC8 %s …", HUC8)
+ gdf = DownloadUSGSGages(out_sr=5070, n_workers=8).download(
+ boundary=str(boundary_gpkg),
+ aoi_id=HUC8,
+ out_dir=WATERSHED,
+ out_name="usgs_gages.gpkg",
+ )
+ if gdf.empty:
+ raise RuntimeError(f"No USGS gages found for HUC8 {HUC8}")
+
+ log.info("C20 PASS: %d gages --> %s", len(gdf), out_path.name)
+ return out_path
+
+
+def step_c21_assign_to_branches(usgs_gages_gpkg: Path) -> tuple[Path, Path]:
+ """Tag every gauge with a feature_id + levpa_id (branch ID)."""
+ from fimbox import assign_gages_to_branches
+
+ out_aoi = WATERSHED / "usgs_subset_gages.gpkg"
+ out_bzero = WATERSHED / f"usgs_subset_gages_0.gpkg"
+
+ if out_aoi.exists() and out_bzero.exists():
+ log.info("C21 SKIP (exists): %s + %s", out_aoi.name, out_bzero.name)
+ return out_aoi, out_bzero
+
+ levelpaths_gpkg = WATERSHED / f"{IDENTIFIER}_subset_streams_levelPaths.gpkg"
+ if not levelpaths_gpkg.exists():
+ raise FileNotFoundError(f"Level-paths gpkg not found: {levelpaths_gpkg}")
+
+ log.info("C21: Assigning gages to branches …")
+ result = assign_gages_to_branches(
+ usgs_gages_gpkg=usgs_gages_gpkg,
+ nwm_streams_levelpaths_gpkg=levelpaths_gpkg,
+ aoi_id=HUC8,
+ out_dir=WATERSHED,
+ aoi_filter_column="aoi_id",
+ branch_zero_id="0",
+ )
+ if result is None:
+ raise RuntimeError("No gages could be assigned to branches")
+
+ log.info("C21 PASS: %d gages assigned", len(result.aoi_gages))
+ return result.aoi_gages_path, result.branch_zero_gages_path
+
+
+def step_c22_per_branch_crosswalk(aoi_gages_gpkg: Path, bzero_gages_gpkg: Path) -> None:
+ """
+ Snap gauges to the DEM thalweg in every branch; writes usgs_elev_table.csv per branch.
+
+ Stage 2 (HAND) cleans up per-branch DEMs after use. The shared
+ ``watershed-data/dem.tif`` covers the full AOI and is used as both the
+ raw-elevation and thalweg-elevation raster. The small bias this introduces
+ (thalweg-conditioned DEM is slightly lower at channels) is acceptable when
+ the goal is to correct only gauged SRCs.
+ """
+ from fimbox import run_branch_crosswalk
+
+ # Shared DEM — covers entire watershed, used for all branches.
+ shared_dem = WATERSHED / "dem.tif"
+ if not shared_dem.exists():
+ raise FileNotFoundError(f"Shared DEM not found: {shared_dem}")
+
+ # Identify which branches actually contain gauges to avoid unnecessary work.
+ import geopandas as gpd
+ aoi_gages = gpd.read_file(aoi_gages_gpkg)
+ gauged_branch_ids = set(aoi_gages["levpa_id"].dropna().astype(str).unique())
+ # Branch zero always gets a pass.
+ gauged_branch_ids.add("0")
+ log.info("C22: branches with gauges = %s", sorted(gauged_branch_ids))
+
+ branch_dirs = sorted(d for d in BRANCHES.iterdir() if d.is_dir())
+ if not branch_dirs:
+ raise FileNotFoundError(f"No branch directories under {BRANCHES}")
+
+ for branch_dir in branch_dirs:
+ bid = branch_dir.name
+ if bid not in gauged_branch_ids:
+ log.debug("C22 SKIP branch %s (no gauges)", bid)
+ continue
+
+ out_table = branch_dir / "usgs_elev_table.csv"
+ if out_table.exists():
+ log.info("C22 SKIP branch %s (exists)", bid)
+ continue
+
+ # Branch zero uses the dedicated branch-zero gage set (levpa_id="0")
+ gages_gpkg = bzero_gages_gpkg if bid == "0" else aoi_gages_gpkg
+
+ catchments_gpkg = branch_dir / (
+ f"gw_catchments_reaches_filtered_addedAttributes_crosswalked_{bid}.gpkg"
+ )
+ flows_gpkg = branch_dir / (
+ f"demDerived_reaches_split_filtered_addedAttributes_crosswalked_{bid}.gpkg"
+ )
+
+ missing = [p for p in (catchments_gpkg, flows_gpkg) if not p.exists()]
+ if missing:
+ log.warning("C22 SKIP branch %s — missing: %s", bid,
+ ", ".join(p.name for p in missing))
+ continue
+
+ # Use per-branch dem if it survived cleanup; otherwise fall back to the shared DEM.
+ branch_dem = branch_dir / f"dem_{bid}.tif"
+ dem_path = branch_dem if branch_dem.exists() else shared_dem
+
+ log.info("C22: crosswalk branch %s (dem=%s) …", bid, dem_path.name)
+ try:
+ out = run_branch_crosswalk(
+ aoi_gages_gpkg=gages_gpkg,
+ branch_catchments_gpkg=catchments_gpkg,
+ branch_flows_gpkg=flows_gpkg,
+ dem_path=dem_path,
+ dem_thalweg_path=dem_path, # shared DEM doubles as thalweg DEM
+ branch_id=bid,
+ out_dir=branch_dir,
+ )
+ written = [p for p in out.values() if p is not None]
+ if written:
+ log.info(" branch %s OK: %s", bid, ", ".join(p.name for p in written))
+ else:
+ log.info(" branch %s: no gages intersected catchments", bid)
+ except Exception:
+ log.error(" branch %s FAIL:\n%s", bid, traceback.format_exc())
+
+
+def step_con_consolidate() -> Path:
+ """
+ Merge all per-branch usgs_elev_table.csv files into one at the AOI root.
+ Stage 4 UsgsRatingCalibrator and the n-calibration script both read from
+ aoi_root/usgs_elev_table.csv.
+ """
+ out_path = AOI_ROOT / "usgs_elev_table.csv"
+
+ frames = []
+ for branch_dir in sorted(d for d in BRANCHES.iterdir() if d.is_dir()):
+ t = branch_dir / "usgs_elev_table.csv"
+ if t.exists():
+ df = pd.read_csv(t, dtype={"location_id": str})
+ df["levpa_id"] = branch_dir.name
+ frames.append(df)
+
+ if not frames:
+ log.warning("CON: no per-branch usgs_elev_table.csv found — no gauges in HUC?")
+ return out_path
+
+ consolidated = pd.concat(frames, ignore_index=True)
+ consolidated = consolidated.drop_duplicates(subset=["location_id", "HydroID"])
+ consolidated.to_csv(out_path, index=False)
+ log.info("CON PASS: %d gage rows --> %s", len(consolidated), out_path)
+ return out_path
+
+
+def main():
+ log.info("=== USGS Gage Crosswalk — HUC8 %s ===", HUC8)
+
+ usgs_gages_gpkg = step_c20_download_gages()
+ aoi_gages_gpkg, bzero_gages_gpkg = step_c21_assign_to_branches(usgs_gages_gpkg)
+ step_c22_per_branch_crosswalk(aoi_gages_gpkg, bzero_gages_gpkg)
+ elev_table = step_con_consolidate()
+
+ log.info("=== Done. usgs_elev_table.csv --> %s ===", elev_table)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s05_calibrate_n_recurrence.py b/scripts/legacy/s05_calibrate_n_recurrence.py
new file mode 100644
index 0000000..d7a0f7c
--- /dev/null
+++ b/scripts/legacy/s05_calibrate_n_recurrence.py
@@ -0,0 +1,460 @@
+"""
+Post-Stage-2 Manning's n calibration using USGS rating curves at NWM recurrence stages.
+
+Concept
+-------
+For each USGS gauge in the HUC8, the NWM supplies 5 recurrence-interval flows
+(2yr, 5yr, 10yr, 25yr, 50yr in cfs). The USGS rating curve maps each of those
+flows to an absolute water-surface elevation, which we convert to a HAND stage
+using the thalweg DEM elevation sampled at the gauge point.
+
+Those 5 HAND stages become 6 depth zones:
+
+ Zone 1 : 0 < h <= h_2yr
+ Zone 2 : h_2yr < h <= h_5yr
+ Zone 3 : h_5yr < h <= h_10yr
+ Zone 4 : h_10yr < h <= h_25yr
+ Zone 5 : h_25yr < h <= h_50yr
+ Zone 6 : h > h_50yr (same n as Zone 5)
+
+For each zone boundary h_r, Manning's equation is inverted against the SRC
+hydraulic geometry at that stage to back-calculate n:
+
+ n_r = A(h_r) . R(h_r)^(2/3) . sqrt(S) / Q_r
+
+where Q_r is the NWM recurrence flow and A, R, S come from the SRC table.
+
+The calibrated n values are then applied piecewise to recompute discharge at
+every stage in the SRC, replacing the original constant n=0.06 baseline.
+
+Scope
+-----
+Only "directly calibrated" branches are processed:
+ - Non-trunk branches (levpa_id != "0")
+ - That have at least one USGS gauge with available rating-curve data
+
+Branch 0 (the watershed trunk) and all ungauged branches are intentionally
+left unchanged. Ungauged branches will be handled by a separate ML-based
+regionalisation step.
+
+Prerequisite
+------------
+run_usgs_gage_crosswalk.py must have run and produced
+ D:/SI/out/HUC03020102/usgs_elev_table.csv
+
+Run
+---
+ .venv\\Scripts\\python.exe scripts/calibrate_n_recurrence.py
+"""
+from __future__ import annotations
+
+import logging
+import shutil
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+HUC8 = "03020102"
+OUT_DIR = Path("D:/SI/out")
+DATA_DIR = Path("data")
+
+# Physical bounds for back-calculated n (Chow 1959 range).
+N_MIN = 0.010 # very smooth concrete
+N_MAX = 0.300 # dense brush / floodplain forest
+# ─────────────────────────────────────────────────────────────────
+
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+RECUR_COLS = {yr: f"{yr}_0_year_recurrence_flow_17C" for yr in RECURRENCE_YEARS}
+
+AOI_ROOT = OUT_DIR / f"HUC{HUC8}"
+WATERSHED = AOI_ROOT / "watershed-data"
+BRANCHES = WATERSHED / "branches"
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+# ── Data loading ──────────────────────────────────────────────────
+
+def load_inputs() -> tuple[pd.DataFrame, pd.DataFrame, pd.DataFrame]:
+ """Load the three external tables needed for calibration."""
+ elev_path = AOI_ROOT / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ raise FileNotFoundError(
+ f"usgs_elev_table.csv not found at {elev_path}\n"
+ "Run scripts/run_usgs_gage_crosswalk.py first."
+ )
+
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ log.info("usgs_elev_table: %d rows", len(elev))
+
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["location_id"] = rc["location_id"].astype(str)
+ rc["flow_cms"] = rc["flow"] / 35.3147 # cfs → m³/s
+ rc["elev_m"] = rc["elevation_navd88"] / 3.28084 # ft NAVD88 → m
+ log.info("USGS rating curves: %d rows, %d gauges",
+ len(rc), rc["location_id"].nunique())
+
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr, col in RECUR_COLS.items():
+ recur[f"Q_{yr}yr_cms"] = recur[col].astype(float) * 0.028317 # cfs → m³/s
+ recur["feature_id"] = recur["feature_id"].astype("Int64")
+ log.info("NWM recurrence flows: %d feature_ids", len(recur))
+
+ return elev, rc, recur
+
+
+def load_src(branch_dir: Path, bid: str) -> pd.DataFrame | None:
+ """Load src_full_crosswalked CSV for a branch; return None if missing."""
+ p = branch_dir / f"src_full_crosswalked_{bid}.csv"
+ if not p.exists():
+ return None
+ df = pd.read_csv(p, dtype={"feature_id": str})
+ df["HydroID"] = df["HydroID"].astype(int)
+ return df
+
+
+# ── Zone boundary calculation ─────────────────────────────────────
+
+def compute_zone_boundaries(
+ location_id: str,
+ feature_id: int,
+ dem_adj_elevation_m: float,
+ rc: pd.DataFrame,
+ recur: pd.DataFrame,
+) -> dict[int, tuple[float, float]] | None:
+ """
+ Returns {recurrence_year: (hand_stage_m, target_Q_cms)} for each year.
+ Returns None when the gauge or feature_id has insufficient data.
+ """
+ # Rating curve file uses zero-padded 8-digit IDs (e.g. "02082950").
+ loc_padded = location_id.zfill(8)
+ gage_rc = rc[rc["location_id"] == loc_padded].copy()
+ if gage_rc.empty:
+ return None
+ gage_rc = gage_rc.sort_values("flow_cms").drop_duplicates("flow_cms")
+
+ feat_recur = recur[recur["feature_id"] == feature_id]
+ if feat_recur.empty:
+ return None
+
+ boundaries = {}
+ for yr in RECURRENCE_YEARS:
+ Q_r = float(feat_recur[f"Q_{yr}yr_cms"].iloc[0])
+ if Q_r <= 0:
+ continue
+
+ # Interpolate the USGS rating curve to find the absolute elevation at Q_r.
+ if Q_r < gage_rc["flow_cms"].min() or Q_r > gage_rc["flow_cms"].max():
+ continue # outside observed range — skip this recurrence
+ elev_r = float(np.interp(Q_r, gage_rc["flow_cms"], gage_rc["elev_m"]))
+ hand_r = elev_r - dem_adj_elevation_m
+
+ if hand_r <= 0:
+ log.debug(" gage %s yr=%d: HAND<0 (%.2fm) — skipping", location_id, yr, hand_r)
+ continue
+
+ boundaries[yr] = (hand_r, Q_r)
+
+ return boundaries if boundaries else None
+
+
+# ── Back-calculate n per zone ─────────────────────────────────────
+
+def calibrate_n_zones(
+ hydroid: int,
+ src: pd.DataFrame,
+ boundaries: dict[int, tuple[float, float]],
+) -> dict[int, float]:
+ """
+ Back-calculate Manning's n for each zone boundary.
+
+ At each recurrence stage h_r, solve:
+ n_r = A(h_r) · R(h_r)^(2/3) · √S / Q_r
+
+ Returns {recurrence_year: n_value} for successfully calibrated zones.
+ """
+ hdf = src[src["HydroID"] == hydroid].sort_values("Stage")
+ if hdf.empty:
+ return {}
+
+ # Use the subdivided discharge column if subdiv already ran; else Manning raw.
+ slope = hdf["SLOPE"].iloc[0]
+ if slope <= 0:
+ return {}
+
+ n_zones: dict[int, float] = {}
+ for yr, (h_r, Q_r) in sorted(boundaries.items()):
+ # Find the SRC row whose stage is closest to h_r.
+ idx = (hdf["Stage"] - h_r).abs().idxmin()
+ row = hdf.loc[idx]
+
+ A = float(row.get("WetArea (m2)", 0.0))
+ R = float(row.get("HydraulicRadius (m)", 0.0))
+
+ if A <= 0 or R <= 0 or Q_r <= 0:
+ continue
+
+ n_r = A * (R ** (2.0 / 3.0)) * (slope ** 0.5) / Q_r
+ n_r = float(np.clip(n_r, N_MIN, N_MAX))
+ n_zones[yr] = n_r
+ log.debug(" HydroID %d yr=%d h=%.2fm Q=%.1f cms n=%.4f",
+ hydroid, yr, h_r, Q_r, n_r)
+
+ return n_zones
+
+
+# ── Apply piecewise n to a full SRC ──────────────────────────────
+
+def apply_n_zones_to_src(
+ src: pd.DataFrame,
+ hydroid: int,
+ boundaries: dict[int, tuple[float, float]],
+ n_zones: dict[int, float],
+) -> pd.DataFrame:
+ """
+ Recompute discharge for one HydroID using piecewise n.
+
+ Zone lookup (sorted ascending by h_r):
+ Stage <= h_2yr → n_2yr
+ h_2yr < stage <= h_5yr → n_5yr
+ ...
+ stage > h_50yr → n of the highest available zone
+ """
+ hdf = src[src["HydroID"] == hydroid].copy()
+ if hdf.empty or not n_zones:
+ return src
+
+ slope = hdf["SLOPE"].iloc[0]
+ # Sorted zone boundaries: [(h_2yr, n_2yr), (h_5yr, n_5yr), ...]
+ sorted_zones = sorted(
+ ((h, n_zones[yr]) for yr, (h, _) in boundaries.items() if yr in n_zones),
+ key=lambda x: x[0],
+ )
+ if not sorted_zones:
+ return src
+
+ def _zone_n(stage_h: float) -> float:
+ for h_boundary, n_val in sorted_zones:
+ if stage_h <= h_boundary:
+ return n_val
+ return sorted_zones[-1][1] # above all boundaries → highest zone n
+
+ rows_mask = src["HydroID"] == hydroid
+
+ new_q = []
+ for _, row in hdf.iterrows():
+ h = float(row["Stage"])
+ if h == 0.0:
+ new_q.append(0.0)
+ continue
+ A = float(row.get("WetArea (m2)", 0.0))
+ R = float(row.get("HydraulicRadius (m)", 0.0))
+ n = _zone_n(h)
+ if A <= 0 or R <= 0 or slope <= 0:
+ new_q.append(float(row.get("Discharge (m3s-1)", 0.0)))
+ else:
+ new_q.append(A * (R ** (2.0 / 3.0)) * (slope ** 0.5) / n)
+
+ src.loc[rows_mask, "Discharge (m3s-1)"] = new_q
+ # Record the zone-n for the lowest recurrence year on each row (informational).
+ src.loc[rows_mask, "zonal_n_applied"] = [_zone_n(float(h))
+ for h in hdf["Stage"]]
+ return src
+
+
+# ── Propagation helpers ───────────────────────────────────────────
+
+def average_zones(
+ all_boundaries: list[dict[int, tuple[float, float]]],
+ all_n_zones: list[dict[int, float]],
+) -> tuple[dict[int, tuple[float, float]], dict[int, float]]:
+ """Average calibrated zone data across multiple gauges in a branch."""
+ # Average the HAND boundary stages and n values independently.
+ avg_boundaries: dict[int, list] = {}
+ avg_n: dict[int, list] = {}
+ for bounds, n_zones in zip(all_boundaries, all_n_zones):
+ for yr, (h, _) in bounds.items():
+ avg_boundaries.setdefault(yr, []).append(h)
+ for yr, n in n_zones.items():
+ avg_n.setdefault(yr, []).append(n)
+
+ merged_bounds = {yr: (float(np.mean(hs)), 0.0) for yr, hs in avg_boundaries.items()}
+ merged_n = {yr: float(np.mean(ns)) for yr, ns in avg_n.items()}
+ return merged_bounds, merged_n
+
+
+# ── Per-branch processing ─────────────────────────────────────────
+
+def process_branch(
+ bid: str,
+ branch_dir: Path,
+ elev: pd.DataFrame,
+ rc: pd.DataFrame,
+ recur: pd.DataFrame,
+) -> None:
+ """
+ Calibrate n for a directly calibrated branch and write back to the SRC +
+ hydroTable CSVs.
+
+ The gauge's calibrated n is applied to every HydroID in the branch.
+ If the branch somehow has multiple gauges with RC data, their zone n values
+ are averaged before propagation.
+ """
+ src = load_src(branch_dir, bid)
+ if src is None:
+ log.warning("Branch %s: src_full_crosswalked not found — skipping", bid)
+ return
+
+ ht_path = branch_dir / f"hydroTable_{bid}.csv"
+ if not ht_path.exists():
+ log.warning("Branch %s: hydroTable not found — skipping", bid)
+ return
+
+ branch_elev = elev[elev["levpa_id"].astype(str) == str(bid)]
+ log.info("Branch %s: %d gauge row(s)", bid, len(branch_elev))
+
+ all_bounds_list = []
+ all_n_list = []
+
+ for _, gage in branch_elev.iterrows():
+ loc_id = str(gage["location_id"])
+ hydroid = int(gage["HydroID"])
+ feat_id = int(gage["feature_id"]) if pd.notna(gage["feature_id"]) else -1
+ dem_adj = float(gage["dem_adj_elevation"])
+
+ if feat_id < 0:
+ log.warning(" Gauge %s: no feature_id — skipping", loc_id)
+ continue
+
+ bounds = compute_zone_boundaries(loc_id, feat_id, dem_adj, rc, recur)
+ if bounds is None:
+ log.warning(" Gauge %s: could not compute zone boundaries — skipping", loc_id)
+ continue
+
+ n_zones = calibrate_n_zones(hydroid, src, bounds)
+ if not n_zones:
+ log.warning(" Gauge %s HydroID %d: no valid n values — skipping", loc_id, hydroid)
+ continue
+
+ log.info(" Gauge %s HydroID %d: calibrated n = %s",
+ loc_id, hydroid,
+ {yr: f"{n:.4f}" for yr, n in sorted(n_zones.items())})
+
+ src = apply_n_zones_to_src(src, hydroid, bounds, n_zones)
+ all_bounds_list.append(bounds)
+ all_n_list.append(n_zones)
+
+ if not all_bounds_list:
+ log.warning("Branch %s: no valid gauge calibrations — SRC not modified", bid)
+ return
+
+ # Single gauge: use directly. Multiple gauges: average before propagation.
+ if len(all_bounds_list) == 1:
+ branch_bounds, branch_n = all_bounds_list[0], all_n_list[0]
+ else:
+ branch_bounds, branch_n = average_zones(all_bounds_list, all_n_list)
+
+ # Apply branch n to all HydroIDs not already individually calibrated.
+ calibrated_hids = {
+ int(gage["HydroID"])
+ for _, gage in branch_elev.iterrows()
+ if pd.notna(gage["feature_id"])
+ }
+ for hid in src["HydroID"].unique():
+ if hid not in calibrated_hids:
+ src = apply_n_zones_to_src(src, hid, branch_bounds, branch_n)
+
+ src_path = branch_dir / f"src_full_crosswalked_{bid}.csv"
+ _backup(src_path)
+ _safe_write_csv(src, src_path, bid)
+ _sync_hydrotable(ht_path, src, bid)
+
+ log.info("Branch %s: updated %d HydroIDs", bid, src["HydroID"].nunique())
+
+
+def _backup(path: Path) -> None:
+ """Copy to *.pre_n_calib.csv if backup doesn't already exist."""
+ backup = path.with_suffix(".pre_n_calib.csv")
+ if not backup.exists():
+ shutil.copy2(path, backup)
+
+
+def _safe_write_csv(df: pd.DataFrame, path: Path, bid: str) -> None:
+ """Write CSV via a temp file to avoid Windows file-lock errors."""
+ import os
+ tmp = path.with_suffix(".tmp.csv")
+ try:
+ df.to_csv(tmp, index=False)
+ os.replace(tmp, path) # atomic on same filesystem
+ except PermissionError as exc:
+ tmp.unlink(missing_ok=True)
+ raise PermissionError(
+ f"Branch {bid}: cannot write {path.name} — close it in any open "
+ f"application and re-run.\n ({exc})"
+ ) from exc
+
+
+def _sync_hydrotable(ht_path: Path, src: pd.DataFrame, bid: str) -> None:
+ """Push the updated discharge + zonal_n_applied from SRC into the hydroTable."""
+ _backup(ht_path)
+ ht = pd.read_csv(ht_path, low_memory=False)
+
+ pull = src[["HydroID", "Stage", "Discharge (m3s-1)"]].copy()
+ if "zonal_n_applied" in src.columns:
+ pull["zonal_n_applied"] = src["zonal_n_applied"]
+ pull = pull.rename(columns={"Stage": "stage", "Discharge (m3s-1)": "discharge_cms"})
+
+ ht["HydroID"] = ht["HydroID"].astype(int)
+ ht = ht.drop(columns=["discharge_cms", "zonal_n_applied"], errors="ignore")
+ ht = ht.merge(pull, on=["HydroID", "stage"], how="left")
+ ht["discharge_cms"] = ht["discharge_cms"].fillna(0.0)
+ ht.to_csv(ht_path, index=False)
+
+
+# ── Main ──────────────────────────────────────────────────────────
+
+def _get_directly_calibrated_branches(elev: pd.DataFrame, rc: pd.DataFrame) -> set[str]:
+ """
+ Returns branch IDs that qualify for direct calibration:
+ - levpa_id != "0" (not the watershed trunk)
+ - gauge has at least one entry in the USGS rating-curve parquet
+ """
+ rc_ids = set(rc["location_id"].astype(str).unique())
+ non_trunk = elev[elev["levpa_id"].astype(str) != "0"].copy()
+ non_trunk["has_rc"] = non_trunk["location_id"].apply(
+ lambda loc: str(loc).zfill(8) in rc_ids
+ )
+ return set(non_trunk[non_trunk["has_rc"]]["levpa_id"].astype(str).unique())
+
+
+def main():
+ log.info("=== n-Recurrence Calibration — HUC8 %s ===", HUC8)
+
+ elev, rc, recur = load_inputs()
+
+ directly_calibrated = _get_directly_calibrated_branches(elev, rc)
+ if not directly_calibrated:
+ log.warning("No directly calibrated branches found — nothing to do.")
+ return
+ log.info("Directly calibrated branches: %s", sorted(directly_calibrated))
+
+ branch_dirs = sorted(d for d in BRANCHES.iterdir() if d.is_dir())
+ for bdir in branch_dirs:
+ bid = bdir.name
+ if bid not in directly_calibrated:
+ log.debug("Branch %s: not directly calibrated — skip", bid)
+ continue
+ process_branch(bid, bdir, elev, rc, recur)
+
+ log.info("=== n-Recurrence Calibration complete ===")
+ log.info("Calibrated branches: %s", sorted(directly_calibrated))
+ log.info("Original SRCs backed up as *.pre_n_calib.csv")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s05_revert_uncalibrated_srcs.py b/scripts/legacy/s05_revert_uncalibrated_srcs.py
new file mode 100644
index 0000000..c7f8eb3
--- /dev/null
+++ b/scripts/legacy/s05_revert_uncalibrated_srcs.py
@@ -0,0 +1,88 @@
+"""
+Revert SRCs for branches that were not directly calibrated.
+
+"Directly calibrated" = a non-trunk branch (levpa_id != "0") that has exactly
+one USGS gauge with available rating-curve data. These are the only branches
+where n was back-calculated from real observations.
+
+All other modified branches (Branch 0 averaged, ungauged fallback) are restored
+from their .pre_n_calib.csv backup to the canonical SRC CSV, and the backup is
+deleted. After this script runs, .pre_n_calib.csv files exist ONLY for the
+truly calibrated branches, so find_calibrated_branches() and the plot script
+will automatically show only those.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/revert_uncalibrated_srcs.py
+"""
+import shutil
+from pathlib import Path
+
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+HUC8 = "03020102"
+OUT_DIR = Path("D:/SI/out")
+DATA_DIR = Path("data")
+# ─────────────────────────────────────────────────────────────────
+
+AOI_ROOT = OUT_DIR / f"HUC{HUC8}"
+WATERSHED = AOI_ROOT / "watershed-data"
+BRANCHES = WATERSHED / "branches"
+
+
+def get_directly_calibrated_branches() -> set[str]:
+ """
+ Returns branch IDs where n was individually back-calculated from a single
+ USGS gauge with rating-curve data. Excludes:
+ - Branch 0 (trunk; received an average of two gauges)
+ - Any branch whose gauge has no entry in usgs_rating_curves.parquet
+ """
+ elev = pd.read_csv(
+ AOI_ROOT / "usgs_elev_table.csv",
+ dtype={"location_id": str, "feature_id": "Int64"},
+ )
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc_ids = set(rc["location_id"].astype(str).unique())
+
+ non_trunk = elev[elev["levpa_id"].astype(str) != "0"].copy()
+ non_trunk["has_rc"] = non_trunk["location_id"].apply(
+ lambda loc: str(loc).zfill(8) in rc_ids
+ )
+ return set(non_trunk[non_trunk["has_rc"]]["levpa_id"].astype(str).unique())
+
+
+def main():
+ directly_calibrated = get_directly_calibrated_branches()
+ print(f"Directly calibrated branches (keeping): {sorted(directly_calibrated)}")
+ print()
+
+ reverted, kept, no_backup = [], [], []
+
+ for branch_dir in sorted(d for d in BRANCHES.iterdir() if d.is_dir()):
+ bid = branch_dir.name
+ backup = branch_dir / f"src_full_crosswalked_{bid}.pre_n_calib.csv"
+ main_csv = branch_dir / f"src_full_crosswalked_{bid}.csv"
+
+ if not backup.exists():
+ no_backup.append(bid)
+ continue
+
+ if bid in directly_calibrated:
+ kept.append(bid)
+ print(f" KEEP branch {bid} (directly calibrated, backup preserved)")
+ continue
+
+ # Restore original SRC from backup, remove backup
+ shutil.copy2(backup, main_csv)
+ backup.unlink()
+ reverted.append(bid)
+ print(f" REVERT branch {bid} -> original SRC restored, backup removed")
+
+ print()
+ print(f"Reverted : {len(reverted)} branch(es) -> {reverted}")
+ print(f"Kept : {len(kept)} branch(es) -> {kept}")
+ print(f"Untouched: {len(no_backup)} branch(es) (never modified)")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s06_stage3_single_huc.py b/scripts/legacy/s06_stage3_single_huc.py
new file mode 100644
index 0000000..824f849
--- /dev/null
+++ b/scripts/legacy/s06_stage3_single_huc.py
@@ -0,0 +1,64 @@
+"""
+Stage 3 — Feature IDs + Streamflow for a SINGLE HUC8.
+Use this to test one HUC before running run_stage3_streamflow.py on all 24.
+
+Prerequisite: Stage 2 must have completed for this HUC.
+
+Set HUC8 and EVENT_DATE below and run:
+ .venv\\Scripts\\python.exe scripts/run_single_huc_stage3.py
+"""
+import logging
+import traceback
+from pathlib import Path
+
+# ── SET THESE ─────────────────────────────────────────────────────
+HUC8 = "03020102"
+EVENT_DATE = "2020-10-10 21:00:00" # edit to your flood event
+# For a date range instead of a single event, uncomment and use:
+# START = "2016-10-05"
+# END = "2016-10-20"
+# ─────────────────────────────────────────────────────────────────
+
+OUT_DIR = Path("D:/SI/out")
+TASK_LOG = Path("D:/SI/out/stage3_status.txt")
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage3 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def main():
+ from fimbox import extract_feature_ids, getNWMretrospective
+
+ aoi_root = OUT_DIR / f"HUC{HUC8}"
+ if not aoi_root.exists():
+ log.error(f"AOI folder not found — run Stage 1 first: {aoi_root}")
+ return
+
+ log.info(f"Stage 3 — HUC8: {HUC8}")
+ try:
+ log.info(" Step 3a: extracting feature IDs …")
+ extract_feature_ids(aoi_root)
+
+ log.info(f" Step 3b: fetching NWM retrospective for {EVENT_DATE} …")
+ getNWMretrospective(aoi_root, date=EVENT_DATE)
+ # For a date range replace the line above with:
+ # getNWMretrospective(aoi_root, start=START, end=END)
+
+ _log_result(HUC8, "PASS")
+ log.info("PASS")
+ except Exception:
+ err = traceback.format_exc()
+ _log_result(HUC8, "FAIL", err.splitlines()[-1])
+ log.error(f"FAIL:\n{err}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s07_stage4_single_huc.py b/scripts/legacy/s07_stage4_single_huc.py
new file mode 100644
index 0000000..d21944a
--- /dev/null
+++ b/scripts/legacy/s07_stage4_single_huc.py
@@ -0,0 +1,84 @@
+"""
+Stage 4 — Calibration for a SINGLE HUC8.
+Use this to test one HUC before running run_stage4_calibration.py on all 24.
+
+Prerequisite: Stage 2 must have completed for this HUC.
+
+Set HUC8 below and run:
+ .venv\\Scripts\\python.exe scripts/run_single_huc_stage4.py
+"""
+import logging
+import traceback
+from pathlib import Path
+
+# ── SET THIS ──────────────────────────────────────────────────────
+HUC8 = "03020102"
+# ─────────────────────────────────────────────────────────────────
+
+OUT_DIR = Path("D:/SI/out")
+DATA_DIR = Path("data")
+TASK_LOG = Path("D:/SI/out/stage4_status.txt")
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage4 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def main():
+ from fimbox import run_calibration, CalibrationConfig
+ from fimbox._dask import _resolve_n_workers
+
+ aoi_root = OUT_DIR / f"HUC{HUC8}"
+ if not aoi_root.exists():
+ log.error(f"AOI folder not found — run Stage 1 first: {aoi_root}")
+ return
+
+ log.info(f"Stage 4 — HUC8: {HUC8}")
+ try:
+ cfg = CalibrationConfig(
+ calibration_rerun=True,
+ aggregate_pre=True,
+ thalweg_notches_adjustment=True,
+ longitudinal_filter=True,
+ bathymetry_adjust=True,
+ bathy_file_ehydro=DATA_DIR / "final_bathymetry_ehydro_ohrfc.gpkg",
+ src_bankfull_toggle=True,
+ bankfull_flows_file=DATA_DIR / "nwm3_high_water_threshold_cms.parquet",
+ include_branch_zero=True,
+ src_subdiv_toggle=True,
+ vmann_input_file=DATA_DIR / "mannings_global_optz.parquet",
+ default_channel_n=0.06,
+ default_overbank_n=0.12,
+ nonmonotonic_src_adjustment=True,
+ nonmonotonic_stream_order_min=4,
+ src_adjust_usgs=True,
+ usgs_rating_curve_csv=DATA_DIR / "usgs_rating_curves.parquet",
+ usgs_acceptable_gages=DATA_DIR / "acceptable_sites_for_rating_curves.parquet",
+ nwm_recur_file=DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet",
+ src_adjust_spatial=True,
+ calib_points_file=None,
+ manual_calb_toggle=True,
+ man_calb_file=None,
+ aggregate_post=True,
+ scan_logs=True,
+ job_branch_limit=_resolve_n_workers(),
+ skip_unimplemented=True,
+ )
+ run_calibration(aoi_root, cfg)
+ _log_result(HUC8, "PASS")
+ log.info("PASS")
+ except Exception:
+ err = traceback.format_exc()
+ _log_result(HUC8, "FAIL", err.splitlines()[-1])
+ log.error(f"FAIL:\n{err}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/legacy/s08_stage5_single_huc.py b/scripts/legacy/s08_stage5_single_huc.py
new file mode 100644
index 0000000..d4498a7
--- /dev/null
+++ b/scripts/legacy/s08_stage5_single_huc.py
@@ -0,0 +1,62 @@
+"""
+Stage 5 — FIM Generation for a SINGLE HUC8.
+Use this to test one HUC before running run_stage5_fim.py on all 24.
+
+Prerequisite: Stages 2 and 3 must have completed for this HUC
+(branches and discharge CSVs must exist).
+
+Set HUC8 below and run:
+ .venv\\Scripts\\python.exe scripts/run_single_huc_stage5.py
+"""
+import logging
+import traceback
+from pathlib import Path
+
+# ── SET THIS ──────────────────────────────────────────────────────
+HUC8 = "03020102"
+# ─────────────────────────────────────────────────────────────────
+
+OUT_DIR = Path("D:/SI/out")
+TASK_LOG = Path("D:/SI/out/stage5_status.txt")
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage5 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def main():
+ from fimbox import generateFIM
+ from fimbox._dask import _resolve_n_workers
+
+ aoi_root = OUT_DIR / f"HUC{HUC8}"
+ discharge_dir = aoi_root / "discharge-inputs"
+
+ if not aoi_root.exists():
+ log.error(f"AOI folder not found — run Stage 1 first: {aoi_root}")
+ return
+ if not discharge_dir.exists() or not list(discharge_dir.glob("*.csv")):
+ log.error(f"No discharge CSVs found — run Stage 3 first: {discharge_dir}")
+ return
+
+ log.info(f"Stage 5 — HUC8: {HUC8}")
+ try:
+ results = generateFIM(
+ aoi_root, n_workers=_resolve_n_workers(), depth=True
+ ).from_discharge_inputs()
+ _log_result(HUC8, "PASS")
+ log.info(f"PASS — {len(results)} FIM raster(s) → {aoi_root / 'fim-outputs'}")
+ except Exception:
+ err = traceback.format_exc()
+ _log_result(HUC8, "FAIL", err.splitlines()[-1])
+ log.error(f"FAIL:\n{err}")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/plot_calibration_analysis.py b/scripts/plot_calibration_analysis.py
new file mode 100644
index 0000000..24f29c2
--- /dev/null
+++ b/scripts/plot_calibration_analysis.py
@@ -0,0 +1,1247 @@
+"""
+Calibration analysis and visualization — full study area.
+
+Individual plots (E:/SI/out/HUC{huc8}/src_plots/):
+ rc_{huc8}_{bid}.png Rating curve comparison per calibrated branch
+
+Study-area aggregate (E:/SI/out/calibration_analysis/):
+ 01_n_profiles.png Manning's n vs HAND stage — all gauges overlaid
+ 02_q_scatter.png Q_orig vs Q_USGS / Q_calib vs Q_USGS (log scale)
+ 03_adj_ratio.png Q_calib / Q_orig by zone — violin plots
+ 04_n_by_zone.png Calibrated n distribution by zone — box plots
+ 05_coverage.png Calibrated vs total branches per HUC
+ 06_metrics.png NSE / KGE / PBIAS / RMSE before-vs-after scatter
+ 07_n_vs_slope.png Calibrated n vs channel slope by zone
+ 08_stage_shift.png HAND stage shift (Δh) at each recurrence flow
+ 09_n_direction.png Count/% of gauges where n increased vs decreased (stacked bar + table)
+ 10_src_ensemble_original.png All original SRCs overlaid with median + IQR band
+ 11_src_ensemble_calibrated.png All calibrated SRCs overlaid with median + IQR band
+ metrics_summary.csv Per-gauge tabular metrics
+
+Run:
+ .venv\\Scripts\\python.exe scripts/plot_calibration_analysis.py
+"""
+from __future__ import annotations
+
+import logging
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.patches as mpatches
+import matplotlib.pyplot as plt
+import matplotlib.ticker as mticker
+import numpy as np
+import pandas as pd
+from matplotlib.lines import Line2D
+
+# ── Style ─────────────────────────────────────────────────────────
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans",
+ "font.size": 10.5,
+ "axes.labelsize": 12,
+ "axes.titlesize": 11.5,
+ "axes.titleweight": "bold",
+ "axes.spines.top": False,
+ "axes.spines.right": False,
+ "axes.grid": True,
+ "grid.alpha": 0.22,
+ "grid.linestyle": ":",
+ "legend.fontsize": 9.5,
+ "legend.framealpha": 0.92,
+ "figure.dpi": 150,
+})
+
+# ── Palette ───────────────────────────────────────────────────────
+C_USGS = "#111111"
+C_ORIG = "#2471a3"
+C_CALIB = "#c0392b"
+C_NAVY = "#1b4f72"
+C_GRAY = "#7f8c8d"
+ZONE_CLR = ["#aed6f1", "#a9dfbf", "#fad7a0", "#f9e79f", "#f1948a", "#d2b4de"]
+GAUGE_PALETTE = [
+ "#e41a1c", "#377eb8", "#4daf4a", "#984ea3",
+ "#ff7f00", "#a65628", "#f781bf", "#999999",
+ "#1b9e77", "#d95f02", "#7570b3", "#e7298a",
+ "#66a61e", "#e6ab02", "#a6761d", "#666666",
+ "#8dd3c7", "#fb8072", "#80b1d3", "#fdb462",
+]
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+DATA_DIR = Path("data")
+SUMMARY_DIR = Path("E:/SI/out/calibration_analysis")
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+RECUR_COLS = {yr: f"{yr}_0_year_recurrence_flow_17C" for yr in RECURRENCE_YEARS}
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 1 — Metrics
+# ══════════════════════════════════════════════════════════════════
+
+def _nse(obs, sim):
+ d = np.sum((obs - obs.mean()) ** 2)
+ return float(1 - np.sum((sim - obs) ** 2) / d) if d > 0 else np.nan
+
+def _kge(obs, sim):
+ if obs.std() == 0 or sim.std() == 0:
+ return np.nan
+ r = np.corrcoef(obs, sim)[0, 1]
+ alpha = sim.std() / obs.std()
+ beta = sim.mean() / obs.mean() if obs.mean() != 0 else np.nan
+ return float(1 - np.sqrt((r - 1)**2 + (alpha - 1)**2 + (beta - 1)**2))
+
+def _pbias(obs, sim):
+ return float(100 * (sim - obs).sum() / obs.sum()) if obs.sum() != 0 else np.nan
+
+def _rmse(obs, sim):
+ return float(np.sqrt(((sim - obs) ** 2).mean()))
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 2 — Data helpers
+# ══════════════════════════════════════════════════════════════════
+
+def _load_shared_data():
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["location_id"] = rc["location_id"].astype(str)
+ rc["flow_cms"] = rc["flow"].astype(float) / 35.3147
+ rc["elev_m"] = rc["elevation_navd88"].astype(float) / 3.28084
+
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr, col in RECUR_COLS.items():
+ recur[f"Q_{yr}yr_cms"] = recur[col].astype(float) * 0.028317
+ recur["feature_id"] = recur["feature_id"].astype("Int64")
+ return rc, recur
+
+
+def _load_src(branch_dir: Path, bid: str, original: bool) -> pd.DataFrame | None:
+ """Rating curves from the hydroTable (calibration's single source of truth):
+ current file = calibrated, .pre_n_calib backup = baseline."""
+ suffix = ".pre_n_calib.csv" if original else ".csv"
+ p = branch_dir / f"hydroTable_{bid}{suffix}"
+ if not p.exists():
+ if original:
+ p = branch_dir / f"hydroTable_{bid}.csv"
+ if not p.exists():
+ return None
+ df = pd.read_csv(p, low_memory=False).rename(
+ columns={"stage": "Stage", "discharge_cms": "Discharge (m3s-1)"})
+ df["HydroID"] = df["HydroID"].astype(int)
+ return df
+
+
+def _zone_pts(loc_id, feat_id, dem_adj_m, rc, recur):
+ loc_pad = str(loc_id).zfill(8)
+ grc = rc[rc["location_id"] == loc_pad].sort_values("flow_cms").drop_duplicates("flow_cms")
+ if grc.empty:
+ return []
+ feat = recur[recur["feature_id"] == feat_id]
+ if feat.empty:
+ return []
+ pts = []
+ for yr in RECURRENCE_YEARS:
+ Q = float(feat[f"Q_{yr}yr_cms"].iloc[0])
+ if Q < grc["flow_cms"].min() or Q > grc["flow_cms"].max():
+ continue
+ elev = float(np.interp(Q, grc["flow_cms"].values, grc["elev_m"].values))
+ h = elev - dem_adj_m
+ if h > 0:
+ pts.append((yr, h, Q))
+ return sorted(pts, key=lambda x: x[0])
+
+
+def _n_step(zp, src_calib, hydroid, y_max):
+ """Return (n_vals, h_vals) step arrays for the Manning's n twin axis."""
+ hdf = src_calib[src_calib["HydroID"] == hydroid].sort_values("Stage")
+ if hdf.empty or "zonal_n_applied" not in hdf.columns:
+ return [], []
+ h_brk = [0.0] + [h for _, h, _ in zp]
+ if h_brk[-1] < y_max:
+ h_brk.append(y_max)
+ nx, hy = [], []
+ for i, (h_lo, h_hi) in enumerate(zip(h_brk[:-1], h_brk[1:])):
+ idx = (hdf["Stage"] - (h_lo + h_hi) / 2).abs().idxmin()
+ n_v = float(hdf.loc[idx, "zonal_n_applied"])
+ nx.extend([n_v, n_v])
+ hy.extend([h_lo, h_hi])
+ if i < len(h_brk) - 2:
+ nx.append(float(hdf.loc[
+ (hdf["Stage"] - h_brk[i+1]).abs().idxmin(), "zonal_n_applied"]))
+ hy.append(h_hi)
+ return nx, hy
+
+
+def _discover_calibrated(huc8: str, rc: pd.DataFrame, elev: pd.DataFrame):
+ """
+ Returns list of dicts with gauge info for gauges that were actually
+ calibrated. Source of truth is ncalib_diagnostics.csv (written by s05 v2,
+ status == "calibrated"); falls back to the v1 heuristic (.pre_n_calib.csv
+ backup exists) when the diagnostics file is absent.
+ """
+ branches_dir = OUT_DIR / f"HUC{huc8}" / "watershed-data" / "branches"
+ if not branches_dir.exists():
+ return []
+
+ # v2 path: exact per-gauge calibration record
+ diag_path = OUT_DIR / f"HUC{huc8}" / "ncalib_diagnostics.csv"
+ calibrated_keys: set[tuple[str, int]] | None = None
+ if diag_path.exists():
+ diag = pd.read_csv(diag_path, dtype={"location_id": str, "branch": str})
+ ok = diag[diag["status"] == "calibrated"]
+ calibrated_keys = set(zip(ok["location_id"].str.zfill(8),
+ ok["hydroid"].astype(int)))
+
+ rc_ids = set(rc["location_id"].astype(str))
+ results = []
+ for branch_dir in sorted(branches_dir.iterdir()):
+ if not branch_dir.is_dir():
+ continue
+ bid = branch_dir.name
+ if bid == "0":
+ continue
+ pre_exists = (branch_dir / f"hydroTable_{bid}.pre_n_calib.csv").exists()
+ if not pre_exists:
+ continue
+ branch_elev = elev[elev["levpa_id"].astype(str) == bid]
+ for _, gage in branch_elev.iterrows():
+ loc_id = str(gage["location_id"]).zfill(8)
+ if loc_id not in rc_ids:
+ continue
+ if pd.isna(gage.get("feature_id")):
+ continue
+ hydroid = int(gage["HydroID"])
+ if calibrated_keys is not None and (loc_id, hydroid) not in calibrated_keys:
+ continue
+ results.append({
+ "bid": bid,
+ "location_id": loc_id,
+ "hydroid": hydroid,
+ "feature_id": int(gage["feature_id"]),
+ "dem_adj_m": float(gage["dem_adj_elevation"]),
+ "branch_dir": branch_dir,
+ })
+ return results
+
+
+def _total_branches(huc8: str) -> int:
+ lst = OUT_DIR / f"HUC{huc8}" / "watershed-data" / "branch_ids.lst"
+ if not lst.exists():
+ return 0
+ lines = [l.strip() for l in lst.read_text().splitlines() if l.strip()]
+ return len(lines) + 1 # +1 for Branch Zero
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 3 — Individual RC plots
+# ══════════════════════════════════════════════════════════════════
+
+def _draw_rc_panel(ax, bid, loc_id, hydroid, feat_id, dem_adj_m,
+ src_orig, src_calib, rc, recur):
+ zp = _zone_pts(loc_id, feat_id, dem_adj_m, rc, recur)
+ if not zp:
+ return
+
+ loc_pad = str(loc_id).zfill(8)
+ grc = rc[rc["location_id"] == loc_pad].sort_values("flow_cms").copy()
+ grc["hand"] = grc["elev_m"] - dem_adj_m
+ grc = grc[grc["hand"] > 0]
+
+ h_max_zone = max(h for _, h, _ in zp)
+ y_max = max(h_max_zone * 1.5, 3.0)
+ rc_q_max = float(grc[grc["hand"] <= y_max * 1.05]["flow_cms"].max()) if not grc.empty else 0.0
+ x_max = max(rc_q_max, max(Q for _, _, Q in zp) * 1.4) * 1.08
+
+ # Zone shading
+ h_edges = [0.0] + [h for _, h, _ in zp]
+ if h_edges[-1] < y_max:
+ h_edges.append(y_max)
+ for i, (hlo, hhi) in enumerate(zip(h_edges[:-1], h_edges[1:])):
+ ax.axhspan(hlo, min(hhi, y_max), color=ZONE_CLR[min(i, 5)],
+ alpha=0.28, zorder=0, lw=0)
+
+ # Zone lines + labels
+ prev_lh = -1.0
+ min_sep = y_max * 0.07
+ for yr, h, _ in zp:
+ ax.axhline(h, color="#888", ls=":", lw=0.9, alpha=0.7, zorder=1)
+ lh = max(h, prev_lh + min_sep)
+ ax.text(x_max * 0.985, lh, f"{yr} yr",
+ ha="right", va="bottom", fontsize=8.5,
+ color="#555", fontweight="bold", zorder=10)
+ prev_lh = lh
+
+ # USGS RC
+ if not grc.empty:
+ rcp = grc[grc["hand"] <= y_max * 1.02]
+ ax.plot(rcp["flow_cms"], rcp["hand"],
+ color=C_USGS, lw=2.5, zorder=5, label="USGS Rating Curve")
+ for _, h, Q in zp:
+ ax.scatter(Q, h, color=C_USGS, s=55, zorder=9,
+ edgecolors="white", linewidths=0.8)
+
+ # SRC curves
+ s_o = src_orig[src_orig["HydroID"] == hydroid].sort_values("Stage")
+ s_c = src_calib[src_calib["HydroID"] == hydroid].sort_values("Stage")
+ if not s_o.empty:
+ ax.plot(s_o["Discharge (m3s-1)"], s_o["Stage"],
+ color=C_ORIG, lw=1.8, ls="-", zorder=4, label="Original SRC (n=0.06)")
+ if not s_c.empty:
+ ax.plot(s_c["Discharge (m3s-1)"], s_c["Stage"],
+ color=C_CALIB, lw=2.8, ls="--", zorder=6, label="Calibrated SRC")
+
+ # Per-zone n value labels inside each zone band
+ if not s_c.empty and "zonal_n_applied" in s_c.columns and zp:
+ h_brk = [0.0] + [h for _, h, _ in zp] + [y_max]
+ for i, (hlo, hhi) in enumerate(zip(h_brk[:-1], h_brk[1:])):
+ hlo_c, hhi_c = min(hlo, y_max), min(hhi, y_max)
+ if hhi_c <= hlo_c:
+ continue
+ mid_h = (hlo_c + hhi_c) / 2
+ idx = (s_c["Stage"] - mid_h).abs().idxmin()
+ n_val = float(s_c.loc[idx, "zonal_n_applied"])
+ ax.text(x_max * 0.015, mid_h, f"n = {n_val:.3f}",
+ ha="left", va="center", fontsize=8.5, color="#222",
+ fontweight="bold", zorder=12,
+ bbox=dict(boxstyle="round,pad=0.22", facecolor="white",
+ alpha=0.80, edgecolor="none"))
+ # Footer note explaining kinks
+ ax.text(0.5, -0.10,
+ "Kinks in calibrated SRC at zone boundaries are expected — Manning's n changes\n"
+ "abruptly between zones; the curve is continuous within each zone.",
+ transform=ax.transAxes, ha="center", va="top",
+ fontsize=8, color="#666", style="italic")
+
+ # Manning's n twin axis
+ ax_n = ax.twiny()
+ nx, hy = _n_step(zp, src_calib, hydroid, y_max)
+ if nx:
+ ax_n.plot(nx, hy, color="#444", alpha=0.4, lw=2.0, zorder=3)
+ ax_n.fill_betweenx(hy, 0, nx, color="#888", alpha=0.07, zorder=2)
+ n_vals = [v for v in nx if v > 0] if nx else [0.06]
+ ax_n.set_xlim(0, max(max(n_vals) * 1.5, 0.35))
+ ax_n.set_xlabel("Manning's n →", fontsize=9, color="#666", labelpad=4)
+ ax_n.tick_params(axis="x", colors="#777", labelsize=8)
+ for sp in ["right", "left", "bottom"]:
+ ax_n.spines[sp].set_visible(False)
+ ax_n.spines["top"].set_color("#aaa")
+
+ ax.set_xlim(0, x_max)
+ ax.set_ylim(0, y_max)
+ ax.set_xlabel("Discharge (m³/s)", labelpad=6)
+ ax.set_ylabel("HAND Stage (m above thalweg)", labelpad=6)
+ ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f"{x:,.0f}"))
+ ax.set_title(f"Gauge {loc_id} · HydroID {hydroid}", pad=26)
+ ax.legend(loc="upper left", fontsize=9)
+
+
+def plot_individual_branches(hucs, rc, recur):
+ log.info("=== Individual RC plots ===")
+ for huc8 in hucs:
+ elev_path = OUT_DIR / f"HUC{huc8}" / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ continue
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ gauges = _discover_calibrated(huc8, rc, elev)
+ if not gauges:
+ continue
+
+ # Group by branch
+ by_branch: dict[str, list] = {}
+ for g in gauges:
+ by_branch.setdefault(g["bid"], []).append(g)
+
+ save_dir = OUT_DIR / f"HUC{huc8}" / "src_plots"
+ save_dir.mkdir(parents=True, exist_ok=True)
+
+ for bid, gage_list in by_branch.items():
+ branch_dir = gage_list[0]["branch_dir"]
+ src_orig = _load_src(branch_dir, bid, original=True)
+ src_calib = _load_src(branch_dir, bid, original=False)
+ if src_orig is None or src_calib is None:
+ continue
+
+ n_g = len(gage_list)
+ fig, axes = plt.subplots(1, n_g, figsize=(12 * n_g, 8.5),
+ squeeze=False, constrained_layout=True)
+ for col, g in enumerate(gage_list):
+ _draw_rc_panel(axes[0, col], bid,
+ g["location_id"], g["hydroid"], g["feature_id"],
+ g["dem_adj_m"],
+ src_orig, src_calib, rc, recur)
+
+ fig.suptitle(
+ f"Manning's n Recurrence Calibration · "
+ f"HUC8 {huc8} · Branch {bid}",
+ fontsize=13, fontweight="bold", y=1.01,
+ )
+ out = save_dir / f"rc_{huc8}_{bid}.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 4 — Data aggregation loop
+# ══════════════════════════════════════════════════════════════════
+
+def collect_all_data(hucs, rc, recur):
+ """
+ Returns (master_df, metrics_df, zone_df, coverage_df).
+
+ master_df : one row per USGS RC data point (gauge × stage)
+ metrics_df : one row per gauge (NSE, KGE, PBIAS, RMSE before/after)
+ zone_df : one row per (gauge × zone) with calibrated n and stage shift
+ coverage_df : one row per HUC with total and calibrated branch counts
+ """
+ master_rows = []
+ metric_rows = []
+ zone_rows = []
+ coverage_rows = []
+
+ for huc8 in hucs:
+ elev_path = OUT_DIR / f"HUC{huc8}" / "usgs_elev_table.csv"
+ n_total = _total_branches(huc8)
+ if not elev_path.exists():
+ coverage_rows.append({"huc8": huc8, "total": n_total, "calibrated": 0})
+ continue
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ gauges = _discover_calibrated(huc8, rc, elev)
+ calibrated_bids = {g["bid"] for g in gauges}
+ coverage_rows.append({
+ "huc8": huc8,
+ "total": n_total,
+ "calibrated": len(calibrated_bids),
+ })
+ if not gauges:
+ continue
+
+ by_branch: dict[str, list] = {}
+ for g in gauges:
+ by_branch.setdefault(g["bid"], []).append(g)
+
+ for bid, gage_list in by_branch.items():
+ branch_dir = gage_list[0]["branch_dir"]
+ src_orig = _load_src(branch_dir, bid, original=True)
+ src_calib = _load_src(branch_dir, bid, original=False)
+ if src_orig is None or src_calib is None:
+ continue
+
+ for g in gage_list:
+ loc_id = g["location_id"]
+ hydroid = g["hydroid"]
+ feat_id = g["feature_id"]
+ dem_adj = g["dem_adj_m"]
+
+ zp = _zone_pts(loc_id, feat_id, dem_adj, rc, recur)
+ if not zp:
+ continue
+
+ # USGS RC in HAND space
+ loc_pad = str(loc_id).zfill(8)
+ grc = rc[rc["location_id"] == loc_pad].copy()
+ grc["hand"] = grc["elev_m"] - dem_adj
+ grc = grc[(grc["hand"] > 0)].sort_values("hand")
+ if grc.empty:
+ continue
+
+ s_o = src_orig[src_orig["HydroID"] == hydroid].sort_values("Stage")
+ s_c = src_calib[src_calib["HydroID"] == hydroid].sort_values("Stage")
+ if s_o.empty or s_c.empty:
+ continue
+
+ slope = float(s_o["SLOPE"].iloc[0])
+ src_max = float(s_o["Stage"].max())
+ valid = grc[grc["hand"] <= src_max * 1.05]
+
+ q_usgs = valid["flow_cms"].values
+ q_orig = np.interp(valid["hand"].values,
+ s_o["Stage"].values,
+ s_o["Discharge (m3s-1)"].values)
+ q_calib = np.interp(valid["hand"].values,
+ s_c["Stage"].values,
+ s_c["Discharge (m3s-1)"].values)
+
+ # Zone assignment
+ h_bounds = [0.0] + [h for _, h, _ in zp]
+ zones = np.searchsorted(h_bounds, valid["hand"].values, side="right")
+
+ # n_applied (from calibrated SRC if column present, else NaN)
+ if "zonal_n_applied" in s_c.columns:
+ n_app = np.interp(valid["hand"].values,
+ s_c["Stage"].values,
+ s_c["zonal_n_applied"].values)
+ else:
+ n_app = np.full(len(valid), np.nan)
+
+ # Master records
+ for i in range(len(valid)):
+ master_rows.append({
+ "huc8": huc8, "bid": bid,
+ "location_id": loc_id, "hydroid": hydroid,
+ "hand_m": float(valid["hand"].values[i]),
+ "q_usgs": float(q_usgs[i]),
+ "q_orig": float(q_orig[i]),
+ "q_calib": float(q_calib[i]),
+ "zone": int(zones[i]),
+ "n_applied": float(n_app[i]),
+ "slope": slope,
+ })
+
+ # Metrics
+ mask = (q_usgs > 0) & (q_orig > 0) & (q_calib > 0)
+ if mask.sum() >= 5:
+ m = {
+ "huc8": huc8, "bid": bid, "location_id": loc_id,
+ "hydroid": hydroid, "n_pts": int(mask.sum()),
+ "nse_orig": _nse(q_usgs[mask], q_orig[mask]),
+ "nse_calib": _nse(q_usgs[mask], q_calib[mask]),
+ "kge_orig": _kge(q_usgs[mask], q_orig[mask]),
+ "kge_calib": _kge(q_usgs[mask], q_calib[mask]),
+ "pbias_orig": _pbias(q_usgs[mask], q_orig[mask]),
+ "pbias_calib": _pbias(q_usgs[mask], q_calib[mask]),
+ "rmse_orig": _rmse(q_usgs[mask], q_orig[mask]),
+ "rmse_calib": _rmse(q_usgs[mask], q_calib[mask]),
+ }
+ metric_rows.append(m)
+
+ # Zone-level stats
+ h_sorted = sorted(zp, key=lambda x: x[0])
+ for z_idx, (yr, h_zone, Q_r) in enumerate(h_sorted, 1):
+ idx = (s_o["Stage"] - h_zone).abs().idxmin()
+ row_o = s_o.loc[idx]
+ idx_c = (s_c["Stage"] - h_zone).abs().idxmin()
+ # Use the actually-applied n (already clipped to N_MIN/N_MAX by s05)
+ if "zonal_n_applied" in s_c.columns:
+ n_zone = float(s_c.loc[idx_c, "zonal_n_applied"])
+ else:
+ A = float(row_o.get("WetArea (m2)", 0))
+ R = float(row_o.get("HydraulicRadius (m)", 0))
+ n_zone = float(A * (R ** (2/3)) * slope**0.5 / Q_r) if Q_r > 0 and A > 0 and R > 0 else np.nan
+
+ # Stage shift at Q_r (invert SRC)
+ qo = s_o["Discharge (m3s-1)"].values
+ ho = s_o["Stage"].values
+ qc = s_c["Discharge (m3s-1)"].values
+ hc = s_c["Stage"].values
+ # Only invert where Q is monotonically increasing
+ h_at_Qr_orig = float(np.interp(Q_r, qo, ho)) if Q_r <= qo.max() else np.nan
+ h_at_Qr_calib = float(np.interp(Q_r, qc, hc)) if Q_r <= qc.max() else np.nan
+ delta_h = h_at_Qr_calib - h_at_Qr_orig if not (np.isnan(h_at_Qr_orig) or np.isnan(h_at_Qr_calib)) else np.nan
+
+ zone_rows.append({
+ "huc8": huc8, "bid": bid, "location_id": loc_id,
+ "hydroid": hydroid, "recurrence_yr": yr,
+ "zone": z_idx, "h_zone": h_zone, "Q_r": Q_r,
+ "n_calibrated": n_zone, "slope": slope,
+ "h_at_Qr_orig": h_at_Qr_orig,
+ "h_at_Qr_calib": h_at_Qr_calib,
+ "delta_h": delta_h,
+ })
+
+ master_df = pd.DataFrame(master_rows)
+ metrics_df = pd.DataFrame(metric_rows)
+ zone_df = pd.DataFrame(zone_rows)
+ coverage_df = pd.DataFrame(coverage_rows)
+ return master_df, metrics_df, zone_df, coverage_df
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 5 — Aggregate plots
+# ══════════════════════════════════════════════════════════════════
+
+def _gauge_label(loc_id, huc8):
+ return f"{loc_id}\n({huc8})"
+
+
+def plot_01_n_profiles(zone_df: pd.DataFrame, out_dir: Path):
+ """Manning's n vs HAND stage — step-function for every gauge."""
+ gauges = zone_df[["location_id", "huc8"]].drop_duplicates()
+ if gauges.empty:
+ return
+
+ fig, ax = plt.subplots(figsize=(12, 7), constrained_layout=True)
+ legend_handles = []
+
+ for ci, (_, row) in enumerate(gauges.iterrows()):
+ loc_id = row["location_id"]
+ huc8 = row["huc8"]
+ gdf = zone_df[(zone_df["location_id"] == loc_id) &
+ (zone_df["huc8"] == huc8)].sort_values("zone")
+ if gdf.empty:
+ continue
+ col = GAUGE_PALETTE[ci % len(GAUGE_PALETTE)]
+
+ # Build step function: [(h_lo, h_hi, n)]
+ h_vals = [0.0] + gdf["h_zone"].tolist()
+ n_vals = gdf["n_calibrated"].tolist()
+ for i, (hlo, hhi) in enumerate(zip(h_vals[:-1], h_vals[1:])):
+ ax.plot([n_vals[i], n_vals[i]], [hlo, hhi],
+ color=col, lw=1.8, alpha=0.85, zorder=4)
+ if i < len(n_vals) - 1:
+ ax.plot([n_vals[i], n_vals[i + 1]], [hhi, hhi],
+ color=col, lw=1.8, alpha=0.85, zorder=4)
+ # Extend to 0 at bottom
+ ax.plot([n_vals[0], n_vals[0]], [0, h_vals[1]],
+ color=col, lw=1.8, alpha=0.85, zorder=4)
+ legend_handles.append(Line2D([0], [0], color=col, lw=2,
+ label=_gauge_label(loc_id, huc8)))
+
+ ax.axvline(0.06, color="#333", ls="--", lw=1.2, alpha=0.6, label="Default n = 0.06")
+ ax.axvline(0.12, color="#777", ls=":", lw=1.2, alpha=0.6, label="Overbank n = 0.12")
+ ax.set_xlabel("Manning's n", labelpad=8)
+ ax.set_ylabel("HAND Stage (m above thalweg)", labelpad=8)
+ ax.set_title("Calibrated Manning's n Profiles — All Gauges", pad=12)
+ ax.legend(handles=legend_handles + [
+ Line2D([0], [0], color="#333", ls="--", lw=1.2, label="Default n = 0.06"),
+ Line2D([0], [0], color="#777", ls=":", lw=1.2, label="Overbank n = 0.12"),
+ ], loc="upper right", fontsize=8.5, ncol=2)
+ # Clip x-axis to 95th percentile — suppresses outliers without losing the main distribution
+ all_n = zone_df["n_calibrated"].dropna().values
+ x_clip = float(np.percentile(all_n, 95)) * 1.2 if len(all_n) > 0 else 0.5
+ x_clip = max(x_clip, 0.4)
+ n_excl = int((all_n > x_clip).sum()) if len(all_n) > 0 else 0
+ ax.set_xlim(0, x_clip)
+ if n_excl > 0:
+ ax.text(0.98, 0.02,
+ f"Note: {n_excl} n value(s) > {x_clip:.2f} not shown (outliers)",
+ transform=ax.transAxes, ha="right", va="bottom",
+ fontsize=8.5, color="#777", style="italic")
+ out = out_dir / "01_n_profiles.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_02_q_scatter(master_df: pd.DataFrame, out_dir: Path):
+ """Q comparison scatter (log scale) — original vs calibrated vs USGS."""
+ if master_df.empty:
+ return
+ df = master_df[(master_df["q_usgs"] > 0) &
+ (master_df["q_orig"] > 0) &
+ (master_df["q_calib"] > 0)].copy()
+ df["zone"] = df["zone"].clip(1, 6)
+
+ zone_colors = {z: ZONE_CLR[z - 1] for z in range(1, 7)}
+ ec = "#333"
+
+ fig, axes = plt.subplots(1, 3, figsize=(17, 6), constrained_layout=True)
+ pairs = [
+ (axes[0], "q_orig", "q_usgs", "Original SRC vs USGS RC"),
+ (axes[1], "q_calib", "q_usgs", "Calibrated SRC vs USGS RC"),
+ (axes[2], "q_orig", "q_calib","Original SRC vs Calibrated SRC"),
+ ]
+ for ax, xcol, ycol, title in pairs:
+ x, y = df[xcol].values, df[ycol].values
+ colors = [zone_colors.get(z, "#ccc") for z in df["zone"]]
+ ax.scatter(x, y, c=colors, s=12, alpha=0.6, edgecolors="none", zorder=4)
+ lims = [min(x.min(), y.min()) * 0.9, max(x.max(), y.max()) * 1.1]
+ ax.plot(lims, lims, "k--", lw=1.0, alpha=0.5, zorder=3, label="1:1")
+ ax.set_xscale("log"); ax.set_yscale("log")
+ ax.set_xlim(lims); ax.set_ylim(lims)
+ ax.set_xlabel(xcol.replace("_", " ").replace("q ", "Q ") + " (m³/s)")
+ ax.set_ylabel(ycol.replace("_", " ").replace("q ", "Q ") + " (m³/s)")
+ ax.set_title(title)
+ ax.legend(loc="upper left", fontsize=9)
+
+ # Zone legend
+ patches = [mpatches.Patch(color=ZONE_CLR[i], label=f"Zone {i+1}")
+ for i in range(6)]
+ fig.legend(handles=patches, loc="lower center", ncol=6,
+ bbox_to_anchor=(0.5, -0.04), fontsize=9,
+ title="Zone", title_fontsize=9)
+ fig.suptitle("Discharge Comparison — All USGS RC Stages (log scale)", fontsize=13)
+ out = out_dir / "02_q_scatter.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_03_adj_ratio(master_df: pd.DataFrame, out_dir: Path):
+ """Q_calib / Q_orig by zone — violin + box plots."""
+ if master_df.empty:
+ return
+ df = master_df[(master_df["q_orig"] > 0) & (master_df["q_calib"] > 0)].copy()
+ df["ratio"] = df["q_calib"] / df["q_orig"]
+ df["zone"] = df["zone"].clip(1, 6)
+
+ fig, ax = plt.subplots(figsize=(11, 6), constrained_layout=True)
+ zone_labels = [f"Zone {z}" for z in range(1, 7)]
+ data_by_zone = [df[df["zone"] == z]["ratio"].dropna().values for z in range(1, 7)]
+
+ vp = ax.violinplot(data_by_zone, positions=range(1, 7),
+ showmedians=True, showextrema=False, widths=0.6)
+ for i, body in enumerate(vp["bodies"]):
+ body.set_facecolor(ZONE_CLR[i])
+ body.set_alpha(0.65)
+ vp["cmedians"].set_color("#111")
+ vp["cmedians"].set_linewidth(2)
+
+ # Overlay box
+ bp = ax.boxplot(data_by_zone, positions=range(1, 7),
+ widths=0.18, patch_artist=False,
+ medianprops=dict(color="#333", lw=0),
+ whiskerprops=dict(color="#555"),
+ capprops=dict(color="#555"),
+ flierprops=dict(marker=".", ms=3, color="#aaa"),
+ manage_ticks=False)
+
+ ax.axhline(1.0, color="#c0392b", lw=1.5, ls="--", alpha=0.8,
+ label="No change (ratio = 1)")
+ ax.set_xticks(range(1, 7))
+ ax.set_xticklabels([f"Zone {z}\n({len(d)} pts)" for z, d in
+ zip(range(1, 7), data_by_zone)])
+ ax.set_ylabel("Q_calibrated / Q_original")
+ ax.set_title("Discharge Adjustment Ratio by Zone\n"
+ "(ratio > 1 = calibration increased discharge; < 1 = decreased)")
+ ax.legend()
+ out = out_dir / "03_adj_ratio.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_04_n_by_zone(zone_df: pd.DataFrame, out_dir: Path):
+ """Calibrated n distribution by zone — box + strip."""
+ if zone_df.empty:
+ return
+ df = zone_df.dropna(subset=["n_calibrated"])
+
+ fig, ax = plt.subplots(figsize=(11, 6), constrained_layout=True)
+ data = [df[df["zone"] == z]["n_calibrated"].values for z in range(1, 6)]
+ labels = [f"Zone {z}\n({RECURRENCE_YEARS[z-1]} yr boundary)" for z in range(1, 6)]
+ n_pts = [len(d) for d in data]
+
+ bp = ax.boxplot(data, patch_artist=True,
+ medianprops=dict(color="#111", lw=2),
+ whiskerprops=dict(color="#555"),
+ capprops=dict(color="#555"),
+ flierprops=dict(marker="o", ms=5, alpha=0.5))
+ for patch, col in zip(bp["boxes"], ZONE_CLR[:5]):
+ patch.set_facecolor(col)
+ patch.set_alpha(0.7)
+
+ # Strip plot
+ rng = np.random.default_rng(42)
+ for z_idx, d in enumerate(data, 1):
+ jitter = rng.uniform(-0.12, 0.12, len(d))
+ ax.scatter(np.full(len(d), z_idx) + jitter, d,
+ color=ZONE_CLR[z_idx - 1], s=28, alpha=0.7,
+ edgecolors="#333", linewidths=0.5, zorder=5)
+
+ ax.axhline(0.06, color=C_NAVY, ls="--", lw=1.5, alpha=0.8, label="Default n = 0.06")
+ ax.axhline(0.12, color=C_GRAY, ls=":", lw=1.5, alpha=0.8, label="Overbank n = 0.12")
+ # Clip y-axis to 97th percentile — outlier protection
+ n_all = df["n_calibrated"].values
+ y_clip = float(np.percentile(n_all, 97)) * 1.15 if len(n_all) > 0 else 0.5
+ y_clip = max(y_clip, 0.4)
+ n_excl = int((n_all > y_clip).sum()) if len(n_all) > 0 else 0
+ ax.set_ylim(0, y_clip)
+ if n_excl > 0:
+ ax.text(0.98, 0.98,
+ f"Note: {n_excl} outlier(s) > {y_clip:.2f} not shown",
+ transform=ax.transAxes, ha="right", va="top",
+ fontsize=9, color="#777", style="italic")
+ ax.set_xticks(range(1, 6))
+ ax.set_xticklabels([f"{l}\n(n={n})" for l, n in zip(labels, n_pts)])
+ ax.set_ylabel("Calibrated Manning's n")
+ ax.set_title("Distribution of Calibrated Manning's n by Zone\n"
+ "(each point = one gauge; zone number = depth interval)")
+ ax.legend()
+ out = out_dir / "04_n_by_zone.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_05_coverage(coverage_df: pd.DataFrame, out_dir: Path):
+ """Calibrated vs total branches per HUC — horizontal stacked bar."""
+ if coverage_df.empty:
+ return
+ df = coverage_df.sort_values("huc8").reset_index(drop=True)
+ df["uncalibrated"] = df["total"] - df["calibrated"]
+
+ fig, ax = plt.subplots(figsize=(11, max(5, len(df) * 0.45 + 1.5)),
+ constrained_layout=True)
+ y = np.arange(len(df))
+ ax.barh(y, df["uncalibrated"], color="#d0d3d4", label="Uncalibrated")
+ ax.barh(y, df["calibrated"], color=C_CALIB, alpha=0.8,
+ left=df["uncalibrated"], label="Calibrated")
+
+ for i, row in df.iterrows():
+ if row["calibrated"] > 0:
+ ax.text(row["total"] + 0.15, i,
+ f"{row['calibrated']}/{row['total']}",
+ va="center", fontsize=9, color="#333")
+
+ ax.set_yticks(y)
+ ax.set_yticklabels(df["huc8"])
+ ax.set_xlabel("Number of Branches")
+ ax.set_ylabel("HUC8")
+ ax.set_title("Calibration Coverage per HUC\n"
+ f"(Total: {df['calibrated'].sum()} calibrated / "
+ f"{df['total'].sum()} branches across {len(df)} HUCs)")
+ ax.legend(loc="lower right")
+ out = out_dir / "05_coverage.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_06_metrics(metrics_df: pd.DataFrame, out_dir: Path):
+ """Before-vs-after metric scatter — one panel per metric."""
+ if metrics_df.empty:
+ return
+
+ fig, axes = plt.subplots(2, 2, figsize=(12, 10), constrained_layout=True)
+ pairs = [
+ (axes[0, 0], "nse_orig", "nse_calib", "NSE",
+ "higher is better", True),
+ (axes[0, 1], "kge_orig", "kge_calib", "KGE",
+ "higher is better", True),
+ (axes[1, 0], "pbias_orig", "pbias_calib", "Percent Bias (%)",
+ "closer to 0 is better", False),
+ (axes[1, 1], "rmse_orig", "rmse_calib", "RMSE (m³/s)",
+ "lower is better", False),
+ ]
+
+ for ax, xcol, ycol, label, note, higher_better in pairs:
+ x = metrics_df[xcol].values
+ y = metrics_df[ycol].values
+ valid = ~(np.isnan(x) | np.isnan(y))
+ x, y = x[valid], y[valid]
+ if len(x) == 0:
+ continue
+
+ lims = [min(x.min(), y.min()) - abs(min(x.min(), y.min())) * 0.05,
+ max(x.max(), y.max()) * 1.05]
+ ax.plot(lims, lims, "--", color="#aaa", lw=1.2, zorder=2, label="No change")
+
+ colors = []
+ for xi, yi in zip(x, y):
+ if higher_better:
+ colors.append("#27ae60" if yi > xi else "#c0392b")
+ else:
+ colors.append("#27ae60" if abs(yi) < abs(xi) else "#c0392b")
+
+ for xi, yi, c in zip(x, y, colors):
+ ax.annotate("", xy=(yi, xi), xytext=(xi, xi),
+ arrowprops=dict(arrowstyle="->", color=c, lw=1.0, alpha=0.4))
+ ax.scatter(x, x, marker="o", s=60, color="#555", zorder=5, label="Before")
+ ax.scatter(y, x, marker="D", s=60, color=colors, zorder=6, edgecolors="#333",
+ linewidths=0.6, label="After")
+
+ ax.set_xlim(lims); ax.set_ylim(lims)
+ ax.set_xlabel(f"{label} (before)")
+ ax.set_ylabel(f"{label} (after)")
+ ax.set_title(f"{label} — {note}")
+ ax.legend(fontsize=8.5)
+
+ n_imp = sum(1 for xi, yi in zip(x, y)
+ if (yi > xi if higher_better else abs(yi) < abs(xi)))
+ ax.text(0.03, 0.97, f"Improved: {n_imp}/{len(x)}",
+ transform=ax.transAxes, va="top", fontsize=9.5,
+ color="#27ae60", fontweight="bold")
+
+ fig.suptitle("Calibration Performance Metrics — Before vs After\n"
+ "(green arrow = improvement, red = degradation)", fontsize=13)
+ out = out_dir / "06_metrics.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_07_n_vs_slope(zone_df: pd.DataFrame, out_dir: Path):
+ """Calibrated n vs channel slope by zone — scatter + per-zone trend."""
+ df = zone_df.dropna(subset=["n_calibrated", "slope"])
+ df = df[df["slope"] > 0]
+ if df.empty:
+ return
+
+ fig, ax = plt.subplots(figsize=(11, 6.5), constrained_layout=True)
+ legend_handles = []
+ for z in range(1, 6):
+ sub = df[df["zone"] == z]
+ if sub.empty:
+ continue
+ col = ZONE_CLR[z - 1]
+ ax.scatter(sub["slope"], sub["n_calibrated"],
+ color=col, s=65, alpha=0.8,
+ edgecolors="#333", linewidths=0.6, zorder=5)
+ # Log-linear trend line
+ log_s = np.log10(sub["slope"].values)
+ n_v = sub["n_calibrated"].values
+ if len(sub) >= 3:
+ p = np.polyfit(log_s, n_v, 1)
+ s_rng = np.logspace(np.log10(sub["slope"].min()),
+ np.log10(sub["slope"].max()), 50)
+ ax.plot(s_rng, np.polyval(p, np.log10(s_rng)),
+ color=col, lw=1.8, ls="-", alpha=0.6, zorder=4)
+ legend_handles.append(
+ mpatches.Patch(color=col, alpha=0.8,
+ label=f"Zone {z} ({RECURRENCE_YEARS[z-1]} yr)"))
+
+ ax.set_xscale("log")
+ ax.set_xlabel("Channel Slope (IRIS-SWORD, m/m)", labelpad=8)
+ ax.set_ylabel("Calibrated Manning's n", labelpad=8)
+ ax.set_title("Manning's n vs Channel Slope by Zone\n"
+ "(line = log-linear trend per zone)", pad=10)
+ ax.legend(handles=legend_handles, loc="upper right")
+ out = out_dir / "07_n_vs_slope.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_08_stage_shift(zone_df: pd.DataFrame, out_dir: Path):
+ """HAND stage shift (Δh = h_calib - h_orig) at recurrence flows — box plot."""
+ df = zone_df.dropna(subset=["delta_h"])
+ if df.empty:
+ return
+
+ fig, ax = plt.subplots(figsize=(11, 6), constrained_layout=True)
+ yr_order = RECURRENCE_YEARS
+ data = [df[df["recurrence_yr"] == yr]["delta_h"].values for yr in yr_order]
+ n_pts = [len(d) for d in data]
+
+ bp = ax.boxplot(data, patch_artist=True,
+ medianprops=dict(color="#111", lw=2.2),
+ whiskerprops=dict(color="#555"),
+ capprops=dict(color="#555"),
+ flierprops=dict(marker="o", ms=5, alpha=0.5))
+ for patch, col in zip(bp["boxes"], ZONE_CLR[:5]):
+ patch.set_facecolor(col)
+ patch.set_alpha(0.7)
+
+ rng = np.random.default_rng(0)
+ for i, d in enumerate(data, 1):
+ jitter = rng.uniform(-0.14, 0.14, len(d))
+ ax.scatter(np.full(len(d), i) + jitter, d,
+ color=ZONE_CLR[i - 1], s=30, alpha=0.75,
+ edgecolors="#333", linewidths=0.5, zorder=5)
+
+ ax.axhline(0, color="#c0392b", ls="--", lw=1.5, alpha=0.8,
+ label="No change (Δh = 0)")
+ ax.set_xticks(range(1, 6))
+ ax.set_xticklabels([f"{yr} yr\n(n={n})" for yr, n in zip(yr_order, n_pts)])
+ ax.set_xlabel("Recurrence Interval")
+ ax.set_ylabel("HAND Stage Shift Δh (m)\n(positive = calibration raises flood stage)")
+ ax.set_title("Flood Stage Shift from Calibration at NWM Recurrence Flows\n"
+ "(impact on FIM extent: Δh > 0 means larger predicted inundation)")
+ ax.legend()
+ out = out_dir / "08_stage_shift.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def plot_09_n_direction(zone_df: pd.DataFrame, out_dir: Path):
+ """Stacked bar + table: how many gauges had n increase vs decrease from 0.06."""
+ df = zone_df.dropna(subset=["n_calibrated"]).copy()
+ tol = 0.005
+ df["direction"] = "No change"
+ df.loc[df["n_calibrated"] > 0.06 + tol, "direction"] = "Increased"
+ df.loc[df["n_calibrated"] < 0.06 - tol, "direction"] = "Decreased"
+
+ zones = list(range(1, 6))
+ yr_labels = [f"Zone {z}\n({RECURRENCE_YEARS[z-1]} yr)" for z in zones]
+ counts = {k: [] for k in ("Increased", "Decreased", "No change")}
+ for z in zones:
+ sub = df[df["zone"] == z]
+ for k in counts:
+ counts[k].append((sub["direction"] == k).sum())
+
+ fig = plt.figure(figsize=(13, 9), constrained_layout=False)
+ fig.subplots_adjust(top=0.91, bottom=0.30, left=0.08, right=0.96)
+ ax = fig.add_subplot(111)
+
+ x = np.arange(len(zones))
+ w = 0.52
+ c_inc = "#c0392b"
+ c_dec = "#2471a3"
+ c_none = "#bdc3c7"
+
+ b_inc = ax.bar(x, counts["Increased"], w, label="Increased (n > 0.06 + ε)", color=c_inc, alpha=0.85)
+ b_dec = ax.bar(x, counts["Decreased"], w, bottom=counts["Increased"],
+ label="Decreased (n < 0.06 − ε)", color=c_dec, alpha=0.85)
+ b_none = ax.bar(x, counts["No change"], w,
+ bottom=[i + d for i, d in zip(counts["Increased"], counts["Decreased"])],
+ label=f"No change (|n − 0.06| ≤ {tol})", color=c_none, alpha=0.75)
+
+ for i in range(len(zones)):
+ total = sum(v[i] for v in counts.values())
+ if total == 0:
+ continue
+ n_i = counts["Increased"][i]
+ n_d = counts["Decreased"][i]
+ n_s = counts["No change"][i]
+ if n_i > 0:
+ ax.text(i, n_i / 2, f"{n_i}\n({100*n_i/total:.0f}%)",
+ ha="center", va="center", fontsize=9.5, color="white", fontweight="bold")
+ if n_d > 0:
+ ax.text(i, n_i + n_d / 2, f"{n_d}\n({100*n_d/total:.0f}%)",
+ ha="center", va="center", fontsize=9.5, color="white", fontweight="bold")
+ if n_s > 2:
+ ax.text(i, n_i + n_d + n_s / 2, f"{n_s}\n({100*n_s/total:.0f}%)",
+ ha="center", va="center", fontsize=9, color="#444")
+
+ ax.set_xticks(x)
+ ax.set_xticklabels(yr_labels, fontsize=10.5)
+ ax.set_ylabel("Number of Gauges")
+ ax.set_title("Direction of Manning's n Change from Default (n = 0.06)\nby Calibration Zone",
+ pad=10)
+ ax.legend(loc="upper right", fontsize=9.5)
+
+ # Summary table below the chart
+ t_inc = sum(counts["Increased"])
+ t_dec = sum(counts["Decreased"])
+ t_none = sum(counts["No change"])
+ grand = t_inc + t_dec + t_none
+
+ totals = [sum(v[i] for v in counts.values()) for i in range(len(zones))]
+ pct = lambda n, t: f"{100*n/t:.0f}%" if t > 0 else "—"
+
+ col_lbl = [f"Zone {z}" for z in zones] + ["TOTAL"]
+ row_data = [
+ [str(counts["Increased"][i]) for i in range(5)] + [str(t_inc)],
+ [pct(counts["Increased"][i], totals[i]) for i in range(5)] + [pct(t_inc, grand)],
+ [str(counts["Decreased"][i]) for i in range(5)] + [str(t_dec)],
+ [pct(counts["Decreased"][i], totals[i]) for i in range(5)] + [pct(t_dec, grand)],
+ [str(counts["No change"][i]) for i in range(5)] + [str(t_none)],
+ [pct(counts["No change"][i], totals[i]) for i in range(5)] + [pct(t_none, grand)],
+ [str(t) for t in totals] + [str(grand)],
+ ]
+ row_lbl = ["n Increased", " % Increased",
+ "n Decreased", " % Decreased",
+ "No Change", " % No Change",
+ "TOTAL"]
+
+ ax_tab = fig.add_axes([0.05, 0.02, 0.91, 0.24])
+ ax_tab.axis("off")
+ tbl = ax_tab.table(cellText=row_data, rowLabels=row_lbl, colLabels=col_lbl,
+ loc="center", cellLoc="center")
+ tbl.auto_set_font_size(False)
+ tbl.set_fontsize(9.5)
+ tbl.scale(1, 1.35)
+ row_bg = {0: c_inc, 2: c_dec, 4: c_none}
+ for (r, c), cell in tbl.get_celld().items():
+ if r == 0:
+ cell.set_facecolor("#2c3e50")
+ cell.set_text_props(color="white", fontweight="bold")
+ elif (r - 1) in row_bg:
+ cell.set_facecolor(row_bg[r - 1])
+ cell.set_alpha(0.35)
+ cell.set_edgecolor("#ccc")
+
+ fig.suptitle("Manning's n Calibration Direction Analysis", fontsize=14, fontweight="bold")
+ out = out_dir / "09_n_direction.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info(" Saved: %s", out.name)
+
+
+def collect_src_curves(hucs, rc, recur):
+ """
+ Returns two parallel lists (orig_curves, calib_curves).
+ Each element: dict with keys huc8, bid, loc_id, q (ndarray), h (ndarray).
+ One entry per calibrated HydroID.
+ """
+ orig_curves, calib_curves = [], []
+ for huc8 in hucs:
+ elev_path = OUT_DIR / f"HUC{huc8}" / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ continue
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ gauges = _discover_calibrated(huc8, rc, elev)
+ if not gauges:
+ continue
+ by_branch: dict[str, list] = {}
+ for g in gauges:
+ by_branch.setdefault(g["bid"], []).append(g)
+ for bid, gage_list in by_branch.items():
+ branch_dir = gage_list[0]["branch_dir"]
+ src_o = _load_src(branch_dir, bid, original=True)
+ src_c = _load_src(branch_dir, bid, original=False)
+ if src_o is None or src_c is None:
+ continue
+ for g in gage_list:
+ hid = g["hydroid"]
+ s_o = src_o[src_o["HydroID"] == hid].sort_values("Stage")
+ s_c = src_c[src_c["HydroID"] == hid].sort_values("Stage")
+ if s_o.empty or s_c.empty:
+ continue
+ base = {"huc8": huc8, "bid": bid, "loc_id": g["location_id"]}
+ orig_curves.append({**base,
+ "q": s_o["Discharge (m3s-1)"].values.copy(),
+ "h": s_o["Stage"].values.copy()})
+ calib_curves.append({**base,
+ "q": s_c["Discharge (m3s-1)"].values.copy(),
+ "h": s_c["Stage"].values.copy()})
+ return orig_curves, calib_curves
+
+
+def _draw_src_ensemble(ax, curves, title, line_color,
+ shared_xlim=None, shared_ylim=None):
+ """Draw individual SRC ensemble with median and IQR band.
+
+ shared_xlim / shared_ylim: pass the same values to both original and
+ calibrated figures so the axes are directly comparable.
+ """
+ h_max = float(max(c["h"].max() for c in curves))
+ h_grid = np.linspace(0.01, h_max, 350)
+
+ # Interpolate each curve onto common h grid (Q as function of h)
+ q_mat = np.full((len(curves), len(h_grid)), np.nan)
+ for i, c in enumerate(curves):
+ q_mat[i] = np.interp(h_grid, c["h"], c["q"], left=np.nan, right=np.nan)
+
+ # Individual curves — slightly darker so they read against white background
+ for c in curves:
+ ax.plot(c["q"], c["h"], color="#777", lw=0.7, alpha=0.28, zorder=2)
+
+ # Percentile bands
+ with np.errstate(all="ignore"):
+ q_med = np.nanmedian(q_mat, axis=0)
+ q_p25 = np.nanpercentile(q_mat, 25, axis=0)
+ q_p75 = np.nanpercentile(q_mat, 75, axis=0)
+ q_p10 = np.nanpercentile(q_mat, 10, axis=0)
+ q_p90 = np.nanpercentile(q_mat, 90, axis=0)
+
+ ax.fill_betweenx(h_grid, q_p10, q_p90, color=line_color, alpha=0.13,
+ zorder=3, label="10th–90th %ile")
+ ax.fill_betweenx(h_grid, q_p25, q_p75, color=line_color, alpha=0.28,
+ zorder=4, label="IQR (25th–75th %ile)")
+ ax.plot(q_med, h_grid, color=line_color, lw=3.0, zorder=6, label="Median")
+
+ # Axes — use shared limits when provided so both plots are directly comparable
+ if shared_xlim is not None:
+ ax.set_xlim(0, shared_xlim)
+ else:
+ q_all = np.concatenate([c["q"] for c in curves])
+ ax.set_xlim(0, float(np.nanpercentile(q_all, 99)) * 1.05)
+ ax.set_ylim(0, shared_ylim if shared_ylim is not None else h_max)
+ ax.set_xlabel("Discharge (m³/s)", labelpad=8)
+ ax.set_ylabel("HAND Stage (m above thalweg)", labelpad=8)
+ ax.set_title(title, pad=10)
+ ax.legend(loc="upper left", fontsize=9.5)
+ ax.text(0.98, 0.02, f"n = {len(curves)} SRC curves",
+ transform=ax.transAxes, ha="right", va="bottom", fontsize=9.5, color="#555")
+ ax.xaxis.set_major_formatter(mticker.FuncFormatter(lambda x, _: f"{x:,.0f}"))
+
+
+def plot_src_overlay(orig_curves, calib_curves, out_dir: Path):
+ """Two figures: all original SRCs overlaid / all calibrated SRCs overlaid.
+
+ Both figures use the same x and y axis limits so ensemble shapes can be
+ compared directly side-by-side.
+ """
+ if not orig_curves:
+ return
+
+ # Compute shared scales from both ensembles combined
+ all_q = np.concatenate([c["q"] for c in orig_curves + calib_curves])
+ shared_xlim = float(np.nanpercentile(all_q, 99)) * 1.05
+ shared_ylim = float(max(c["h"].max() for c in orig_curves + calib_curves))
+
+ fig1, ax1 = plt.subplots(figsize=(12, 7.5), constrained_layout=True)
+ _draw_src_ensemble(ax1, orig_curves,
+ "All Original SRCs — Gauged Branches (pre-calibration, n = 0.06)",
+ C_ORIG, shared_xlim=shared_xlim, shared_ylim=shared_ylim)
+ fig1.suptitle("Synthetic Rating Curve Ensemble — Original", fontsize=13, fontweight="bold")
+ out1 = out_dir / "10_src_ensemble_original.png"
+ fig1.savefig(out1, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig1)
+ log.info(" Saved: %s", out1.name)
+
+ fig2, ax2 = plt.subplots(figsize=(12, 7.5), constrained_layout=True)
+ _draw_src_ensemble(ax2, calib_curves,
+ "All Calibrated SRCs — Gauged Branches (post-calibration)",
+ C_CALIB, shared_xlim=shared_xlim, shared_ylim=shared_ylim)
+ fig2.suptitle("Synthetic Rating Curve Ensemble — Calibrated", fontsize=13, fontweight="bold")
+ out2 = out_dir / "11_src_ensemble_calibrated.png"
+ fig2.savefig(out2, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig2)
+ log.info(" Saved: %s", out2.name)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 6 — Main
+# ══════════════════════════════════════════════════════════════════
+
+def main():
+ SUMMARY_DIR.mkdir(parents=True, exist_ok=True)
+
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ log.info("Study area: %d HUCs", len(hucs))
+
+ log.info("Loading shared tables …")
+ rc, recur = _load_shared_data()
+
+ # ── Individual RC plots ────────────────────────────────────────
+ plot_individual_branches(hucs, rc, recur)
+
+ # ── Collect aggregated data ────────────────────────────────────
+ log.info("Collecting data for aggregate plots …")
+ master_df, metrics_df, zone_df, coverage_df = collect_all_data(hucs, rc, recur)
+
+ n_gauges = metrics_df["location_id"].nunique() if not metrics_df.empty else 0
+ log.info(" %d calibrated gauge(s) with metrics", n_gauges)
+
+ # ── Aggregate plots ────────────────────────────────────────────
+ log.info("=== Aggregate plots ===")
+ plot_01_n_profiles(zone_df, SUMMARY_DIR)
+ plot_02_q_scatter(master_df, SUMMARY_DIR)
+ plot_03_adj_ratio(master_df, SUMMARY_DIR)
+ plot_04_n_by_zone(zone_df, SUMMARY_DIR)
+ plot_05_coverage(coverage_df, SUMMARY_DIR)
+ plot_06_metrics(metrics_df, SUMMARY_DIR)
+ plot_07_n_vs_slope(zone_df, SUMMARY_DIR)
+ plot_08_stage_shift(zone_df, SUMMARY_DIR)
+ plot_09_n_direction(zone_df, SUMMARY_DIR)
+
+ # ── SRC ensemble plots ─────────────────────────────────────────
+ log.info("Collecting SRC curves for ensemble plots …")
+ orig_curves, calib_curves = collect_src_curves(hucs, rc, recur)
+ log.info(" %d SRC curves collected", len(orig_curves))
+ plot_src_overlay(orig_curves, calib_curves, SUMMARY_DIR)
+
+ # ── Metrics summary CSV ────────────────────────────────────────
+ if not metrics_df.empty:
+ cols_order = [
+ "huc8", "bid", "location_id", "hydroid", "n_pts",
+ "nse_orig", "nse_calib", "kge_orig", "kge_calib",
+ "pbias_orig", "pbias_calib", "rmse_orig", "rmse_calib",
+ ]
+ metrics_df[cols_order].round(4).to_csv(
+ SUMMARY_DIR / "metrics_summary.csv", index=False
+ )
+ log.info(" Saved: metrics_summary.csv")
+
+ # Print summary
+ log.info("\n── Performance Summary ──────────────────────────────────")
+ for _, row in metrics_df.iterrows():
+ log.info(
+ " %-10s %-13s NSE %+.3f→%+.3f KGE %+.3f→%+.3f "
+ "PBIAS %+.1f%%→%+.1f%% RMSE %.1f→%.1f m³/s",
+ row["huc8"], row["location_id"],
+ row["nse_orig"], row["nse_calib"],
+ row["kge_orig"], row["kge_calib"],
+ row["pbias_orig"], row["pbias_calib"],
+ row["rmse_orig"], row["rmse_calib"],
+ )
+
+ log.info("\nAll outputs written to:")
+ log.info(" Individual plots → E:/SI/out/HUC{{huc8}}/src_plots/")
+ log.info(" Aggregate plots → %s", SUMMARY_DIR)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/plot_src_ensemble.py b/scripts/plot_src_ensemble.py
new file mode 100644
index 0000000..4553378
--- /dev/null
+++ b/scripts/plot_src_ensemble.py
@@ -0,0 +1,483 @@
+"""
+SRC ensemble plots — clean, physically informative version.
+
+Produces three figures in E:/SI/out/calibration_analysis/:
+
+ src_ensemble_sidebyside.png
+ Two panels side-by-side: original SRCs (left) and calibrated SRCs (right).
+ Individual gray spaghetti lines + bold colored median. Same axis limits
+ on both panels. No percentile bands.
+
+ src_ensemble_absolute.png
+ Both ensembles overlaid on the same axes (log x-scale).
+ Individual spaghetti lines (light) + bold study-area median per ensemble.
+
+ src_ensemble_normalized.png
+ Both ensembles normalized by each gauge's NWM 2-year recurrence flow
+ (Q / Q_2yr), removing the river-size effect.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/plot_src_ensemble.py
+"""
+from __future__ import annotations
+
+import logging
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+from matplotlib.lines import Line2D
+
+# ── Style ─────────────────────────────────────────────────────────
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans",
+ "font.size": 11,
+ "axes.labelsize": 13,
+ "axes.titlesize": 12,
+ "axes.titleweight": "bold",
+ "axes.spines.top": False,
+ "axes.spines.right": False,
+ "axes.grid": True,
+ "grid.alpha": 0.20,
+ "grid.linestyle": ":",
+ "legend.fontsize": 10,
+ "legend.framealpha": 0.92,
+ "figure.dpi": 150,
+})
+
+C_ORIG = "#2471a3" # blue — original SRC
+C_CALIB = "#c0392b" # red — calibrated SRC
+C_USGS = "#111111" # black — USGS observed RC
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+DATA_DIR = Path("data")
+SUMMARY_DIR = Path("E:/SI/out/calibration_analysis")
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+RECUR_COLS = {yr: f"{yr}_0_year_recurrence_flow_17C" for yr in RECURRENCE_YEARS}
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 1 — Data helpers
+# ══════════════════════════════════════════════════════════════════
+
+def _load_shared():
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["location_id"] = rc["location_id"].astype(str)
+ rc["flow_cms"] = rc["flow"].astype(float) / 35.3147
+ rc["elev_m"] = rc["elevation_navd88"].astype(float) / 3.28084
+
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr, col in RECUR_COLS.items():
+ recur[f"Q_{yr}yr_cms"] = recur[col].astype(float) * 0.028317
+ recur["feature_id"] = recur["feature_id"].astype("Int64")
+ return rc, recur
+
+
+def _load_src(branch_dir: Path, bid: str, original: bool) -> pd.DataFrame | None:
+ """Rating curves from the hydroTable (calibration's single source of truth):
+ current file = calibrated, .pre_n_calib backup = baseline."""
+ suffix = ".pre_n_calib.csv" if original else ".csv"
+ p = branch_dir / f"hydroTable_{bid}{suffix}"
+ if not p.exists() and original:
+ p = branch_dir / f"hydroTable_{bid}.csv"
+ if not p.exists():
+ return None
+ df = pd.read_csv(p, low_memory=False).rename(
+ columns={"stage": "Stage", "discharge_cms": "Discharge (m3s-1)"})
+ df["HydroID"] = df["HydroID"].astype(int)
+ return df
+
+
+def _discover_calibrated(huc8: str, rc: pd.DataFrame, elev: pd.DataFrame) -> list[dict]:
+ branches_dir = OUT_DIR / f"HUC{huc8}" / "watershed-data" / "branches"
+ if not branches_dir.exists():
+ return []
+
+ # v2 source of truth: per-gauge diagnostics written by s05 (status == calibrated).
+ diag_path = OUT_DIR / f"HUC{huc8}" / "ncalib_diagnostics.csv"
+ calibrated_keys = None
+ if diag_path.exists():
+ diag = pd.read_csv(diag_path, dtype={"location_id": str, "branch": str})
+ ok = diag[diag["status"] == "calibrated"]
+ calibrated_keys = set(zip(ok["location_id"].str.zfill(8),
+ ok["hydroid"].astype(int)))
+
+ rc_ids = set(rc["location_id"].astype(str))
+ results = []
+ for branch_dir in sorted(branches_dir.iterdir()):
+ if not branch_dir.is_dir():
+ continue
+ bid = branch_dir.name
+ if bid == "0":
+ continue
+ if not (branch_dir / f"hydroTable_{bid}.pre_n_calib.csv").exists():
+ continue
+ for _, gage in elev[elev["levpa_id"].astype(str) == bid].iterrows():
+ loc_id = str(gage["location_id"]).zfill(8)
+ if loc_id not in rc_ids or pd.isna(gage.get("feature_id")):
+ continue
+ hydroid = int(gage["HydroID"])
+ if calibrated_keys is not None and (loc_id, hydroid) not in calibrated_keys:
+ continue
+ results.append({
+ "bid": bid,
+ "location_id": loc_id,
+ "hydroid": hydroid,
+ "feature_id": int(gage["feature_id"]),
+ "dem_adj_m": float(gage["dem_adj_elevation"]),
+ "branch_dir": branch_dir,
+ })
+ return results
+
+
+def collect_curves(hucs: list[str], rc: pd.DataFrame, recur: pd.DataFrame):
+ """
+ Returns (orig, calib, usgs_rc) — three parallel lists of dicts:
+
+ q : ndarray discharge (m³/s)
+ h : ndarray HAND stage (m)
+ Q_2yr : float NWM 2-yr recurrence flow (m³/s) — normalization factor
+ """
+ orig, calib, usgs_rc = [], [], []
+
+ for huc8 in hucs:
+ elev_path = OUT_DIR / f"HUC{huc8}" / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ continue
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ gauges = _discover_calibrated(huc8, rc, elev)
+ if not gauges:
+ continue
+
+ by_branch: dict[str, list] = {}
+ for g in gauges:
+ by_branch.setdefault(g["bid"], []).append(g)
+
+ for bid, gage_list in by_branch.items():
+ bdir = gage_list[0]["branch_dir"]
+ src_o = _load_src(bdir, bid, original=True)
+ src_c = _load_src(bdir, bid, original=False)
+ if src_o is None or src_c is None:
+ continue
+
+ for g in gage_list:
+ feat = recur[recur["feature_id"] == g["feature_id"]]
+ if feat.empty:
+ continue
+ Q_2yr = float(feat["Q_2yr_cms"].iloc[0])
+ if Q_2yr <= 0:
+ continue
+
+ hid = g["hydroid"]
+ s_o = src_o[src_o["HydroID"] == hid].sort_values("Stage")
+ s_c = src_c[src_c["HydroID"] == hid].sort_values("Stage")
+ if s_o.empty or s_c.empty:
+ continue
+
+ base = {"Q_2yr": Q_2yr}
+ orig.append({**base,
+ "q": s_o["Discharge (m3s-1)"].values.copy(),
+ "h": s_o["Stage"].values.copy()})
+ calib.append({**base,
+ "q": s_c["Discharge (m3s-1)"].values.copy(),
+ "h": s_c["Stage"].values.copy()})
+
+ # USGS RC converted to HAND space
+ grc = rc[rc["location_id"] == g["location_id"]].copy()
+ grc["hand"] = grc["elev_m"] - g["dem_adj_m"]
+ grc = grc[grc["hand"] > 0].sort_values("hand")
+ if not grc.empty:
+ usgs_rc.append({**base,
+ "q": grc["flow_cms"].values.copy(),
+ "h": grc["hand"].values.copy()})
+
+ log.info(" %d SRC pairs | %d USGS RC sets", len(orig), len(usgs_rc))
+ return orig, calib, usgs_rc
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 2 — Ensemble median
+# ══════════════════════════════════════════════════════════════════
+
+def _median_on_grid(curves: list[dict], h_grid: np.ndarray,
+ normalized: bool) -> np.ndarray:
+ """
+ Interpolate each curve onto h_grid, return nanmedian across all curves.
+ If normalized=True, divide each curve's discharge by its Q_2yr first.
+ """
+ q_mat = np.full((len(curves), len(h_grid)), np.nan)
+ for i, c in enumerate(curves):
+ q = c["q"] / c["Q_2yr"] if normalized else c["q"]
+ valid = c["h"] > 0
+ if valid.sum() < 2:
+ continue
+ q_mat[i] = np.interp(h_grid, c["h"][valid], q[valid],
+ left=np.nan, right=np.nan)
+ return np.nanmedian(q_mat, axis=0)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 3 — Plot 1: Side-by-side panels (original | calibrated)
+# ══════════════════════════════════════════════════════════════════
+
+def plot_sidebyside(orig: list, calib: list, out_path: Path) -> None:
+ """
+ Two panels with the same axes: original SRCs on the left, calibrated on
+ the right. Individual curves are drawn in gray (neutral — each represents
+ a different-sized river) with a bold colored median. No percentile bands.
+ X-axis is clipped at the 98th percentile of discharge so the majority of
+ curves are visible without outliers dominating the scale.
+ """
+ # Shared axis limits from all curves combined
+ all_q = np.concatenate([c["q"] for c in orig + calib])
+ all_h = np.concatenate([c["h"] for c in orig + calib])
+ x_max = float(np.nanpercentile(all_q[all_q > 0], 98)) * 1.05
+ y_max = float(np.nanpercentile(all_h, 99)) * 1.05
+
+ h_grid = np.linspace(0.05, y_max, 600)
+ med_o = _median_on_grid(orig, h_grid, normalized=False)
+ med_c = _median_on_grid(calib, h_grid, normalized=False)
+
+ fig, axes = plt.subplots(1, 2, figsize=(16, 8),
+ sharey=True, constrained_layout=True)
+
+ panels = [
+ (axes[0], orig, med_o, C_ORIG, "Original SRCs (pre-calibration)"),
+ (axes[1], calib, med_c, C_CALIB, "Calibrated SRCs (post-calibration)"),
+ ]
+
+ for ax, curves, med, color, title in panels:
+ # Individual gray spaghetti
+ for c in curves:
+ mask = (c["q"] > 0) & (c["q"] <= x_max * 1.05)
+ ax.plot(c["q"][mask], c["h"][mask],
+ color="#777", lw=0.6, alpha=0.28, zorder=2)
+ # Median
+ valid = (med > 0) & (med <= x_max)
+ ax.plot(med[valid], h_grid[valid],
+ color=color, lw=3.0, zorder=6, label="Median")
+
+ ax.set_xlim(0, x_max)
+ ax.set_ylim(0, y_max)
+ ax.set_xlabel("Discharge (m³/s)", labelpad=8)
+ ax.set_title(f"{title}\n(n = {len(curves)} reaches)", pad=8)
+ ax.legend(loc="upper left", fontsize=10)
+ ax.xaxis.set_major_formatter(
+ plt.matplotlib.ticker.FuncFormatter(lambda x, _: f"{x:,.0f}")
+ )
+
+ axes[0].set_ylabel("HAND Stage (m above thalweg)", labelpad=8)
+
+ fig.suptitle("Synthetic Rating Curve Ensemble — Original vs Calibrated",
+ fontsize=13, fontweight="bold")
+
+ fig.savefig(out_path, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out_path.name)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 4 — Plot 2: Absolute, log x-scale
+# ══════════════════════════════════════════════════════════════════
+
+def plot_absolute(orig: list, calib: list, out_path: Path) -> None:
+ """
+ Original and calibrated SRCs on the same axes.
+
+ Log x-scale lets small creeks and large rivers coexist without the large
+ rivers dominating the entire visible area. No percentile bands — they
+ are not interpretable when river sizes span 3-4 orders of magnitude.
+ The median lines summarise the typical shift from calibration.
+ """
+ fig, ax = plt.subplots(figsize=(13, 8), constrained_layout=True)
+
+ # ── Individual spaghetti ──────────────────────────────────────
+ for c in orig:
+ mask = c["q"] > 0
+ ax.plot(c["q"][mask], c["h"][mask],
+ color=C_ORIG, lw=0.55, alpha=0.18, zorder=2)
+ for c in calib:
+ mask = c["q"] > 0
+ ax.plot(c["q"][mask], c["h"][mask],
+ color=C_CALIB, lw=0.55, alpha=0.18, zorder=2)
+
+ # ── Medians ───────────────────────────────────────────────────
+ h_max = float(max(c["h"].max() for c in orig + calib))
+ h_grid = np.linspace(0.05, h_max, 600)
+ med_o = _median_on_grid(orig, h_grid, normalized=False)
+ med_c = _median_on_grid(calib, h_grid, normalized=False)
+
+ ax.plot(med_o[med_o > 0], h_grid[med_o > 0],
+ color=C_ORIG, lw=3.0, zorder=6, label="Original — median")
+ ax.plot(med_c[med_c > 0], h_grid[med_c > 0],
+ color=C_CALIB, lw=3.0, ls="--", zorder=6, label="Calibrated — median")
+
+ # ── Axes ──────────────────────────────────────────────────────
+ q_pos = np.concatenate([c["q"][c["q"] > 0] for c in orig + calib])
+ ax.set_xscale("log")
+ ax.set_xlim(max(float(np.nanpercentile(q_pos, 0.5)), 0.1), None)
+ ax.set_ylim(0, h_max)
+ ax.set_xlabel("Discharge (m³/s) — log scale", labelpad=8)
+ ax.set_ylabel("HAND Stage (m above thalweg)", labelpad=8)
+ ax.set_title(
+ "SRC Ensemble — Original vs Calibrated\n"
+ f"n = {len(orig)} gauged HydroIDs | log x-scale so all river sizes are visible",
+ pad=10,
+ )
+
+ handles = [
+ Line2D([0], [0], color=C_ORIG, lw=3.0, label=f"Original — median (n = {len(orig)})"),
+ Line2D([0], [0], color=C_CALIB, lw=3.0, ls="--", label=f"Calibrated — median (n = {len(calib)})"),
+ Line2D([0], [0], color="#888", lw=0.8, alpha=0.5, label="Individual reaches"),
+ ]
+ ax.legend(handles=handles, loc="upper left")
+ ax.text(0.98, 0.02,
+ "Median shift LEFT → calibration raises stage for same discharge | "
+ "RIGHT → calibration lowers stage",
+ transform=ax.transAxes, ha="right", va="bottom",
+ fontsize=8.5, color="#666", style="italic")
+
+ fig.savefig(out_path, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out_path.name)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 5 — Plot 3: Normalized by Q_2yr
+# ══════════════════════════════════════════════════════════════════
+
+def plot_normalized(orig: list, calib: list, usgs_rc: list,
+ out_path: Path) -> None:
+ """
+ Discharge normalized by each gauge's NWM 2-yr recurrence flow.
+
+ Q / Q_2yr = 1.0 → 2-yr flood (common flood)
+ Q / Q_2yr = 2 → roughly 5-yr flood
+ Q / Q_2yr = 5 → roughly 25-yr flood
+
+ Removing river-size effect means the SHAPE of the SRC and the calibration
+ SHIFT are directly comparable across all reaches.
+
+ Key property: by construction, calibrated SRCs cross Q/Q_2yr = 1.0 at
+ exactly the HAND stage where the USGS RC hits the 2-yr NWM flow.
+ """
+ fig, ax = plt.subplots(figsize=(13, 8), constrained_layout=True)
+
+ # Reasonable x-axis limit: 98th %ile of normalized Q across all curves
+ all_qn = np.concatenate([c["q"] / c["Q_2yr"]
+ for c in orig + calib if c["Q_2yr"] > 0])
+ x_max = max(float(np.nanpercentile(all_qn[all_qn > 0], 98)) * 1.1, 6.0)
+
+ def _clip(q_norm, h):
+ mask = (q_norm > 0) & (q_norm <= x_max * 1.05) & (h > 0)
+ return q_norm[mask], h[mask]
+
+ # ── USGS RC (plotted first, behind SRC curves) ────────────────
+ for c in usgs_rc:
+ qn = c["q"] / c["Q_2yr"]
+ qn_c, h_c = _clip(qn, c["h"])
+ if len(h_c) < 2:
+ continue
+ ax.plot(qn_c, h_c, color=C_USGS, lw=0.8, alpha=0.15, zorder=1)
+
+ # ── Individual SRC curves ─────────────────────────────────────
+ for c in orig:
+ qn = c["q"] / c["Q_2yr"]
+ qn_c, h_c = _clip(qn, c["h"])
+ ax.plot(qn_c, h_c, color=C_ORIG, lw=0.55, alpha=0.18, zorder=2)
+ for c in calib:
+ qn = c["q"] / c["Q_2yr"]
+ qn_c, h_c = _clip(qn, c["h"])
+ ax.plot(qn_c, h_c, color=C_CALIB, lw=0.55, alpha=0.18, zorder=2)
+
+ # ── Medians ───────────────────────────────────────────────────
+ h_max = min(float(max(c["h"].max() for c in orig + calib)), 20.0)
+ h_grid = np.linspace(0.05, h_max, 600)
+ med_o = _median_on_grid(orig, h_grid, normalized=True)
+ med_c = _median_on_grid(calib, h_grid, normalized=True)
+
+ valid_o = (med_o > 0) & (med_o <= x_max)
+ valid_c = (med_c > 0) & (med_c <= x_max)
+ ax.plot(med_o[valid_o], h_grid[valid_o],
+ color=C_ORIG, lw=3.0, zorder=6, label="Original — median")
+ ax.plot(med_c[valid_c], h_grid[valid_c],
+ color=C_CALIB, lw=3.0, ls="--", zorder=6, label="Calibrated — median")
+
+ # ── Reference line at Q/Q_2yr = 1 ────────────────────────────
+ ax.axvline(1.0, color="#555", ls=":", lw=1.8, alpha=0.8, zorder=5)
+ ax.text(1.03, h_max * 0.97, "Q = Q₂ yr",
+ ha="left", va="top", fontsize=9.5, color="#555", style="italic")
+
+ # ── Axes ──────────────────────────────────────────────────────
+ ax.set_xlim(0, x_max)
+ ax.set_ylim(0, h_max)
+ ax.set_xlabel("Normalized Discharge Q / Q₂ᵧᵣ (dimensionless)", labelpad=8)
+ ax.set_ylabel("HAND Stage (m above thalweg)", labelpad=8)
+ ax.set_title(
+ "SRC Ensemble — Normalized by 2-Year Recurrence Flow\n"
+ "River-size effect removed · shape and calibration shift are directly comparable",
+ pad=10,
+ )
+
+ handles = [
+ Line2D([0], [0], color=C_ORIG, lw=3.0, label=f"Original SRC — median (n = {len(orig)})"),
+ Line2D([0], [0], color=C_CALIB, lw=3.0, ls="--", label=f"Calibrated SRC — median (n = {len(calib)})"),
+ Line2D([0], [0], color=C_USGS, lw=1.0, alpha=0.5, label=f"USGS observed RC (n = {len(usgs_rc)})"),
+ Line2D([0], [0], color="#888", lw=0.8, alpha=0.5, label="Individual reaches"),
+ ]
+ ax.legend(handles=handles, loc="upper left")
+ ax.text(0.98, 0.02,
+ "Calibrated SRCs cross Q/Q₂ᵧᵣ = 1.0 at the 2-yr HAND stage by construction",
+ transform=ax.transAxes, ha="right", va="bottom",
+ fontsize=8.5, color="#666", style="italic")
+
+ fig.savefig(out_path, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out_path.name)
+
+
+# ══════════════════════════════════════════════════════════════════
+# SECTION 6 — Main
+# ══════════════════════════════════════════════════════════════════
+
+def main():
+ SUMMARY_DIR.mkdir(parents=True, exist_ok=True)
+
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ log.info("Study area: %d HUCs", len(hucs))
+
+ log.info("Loading shared tables …")
+ rc, recur = _load_shared()
+
+ log.info("Collecting SRC curves …")
+ orig, calib, usgs_rc = collect_curves(hucs, rc, recur)
+
+ log.info("Plot 1 — side-by-side panels (original | calibrated) …")
+ plot_sidebyside(orig, calib,
+ SUMMARY_DIR / "src_ensemble_sidebyside.png")
+
+ log.info("Plot 2 — absolute ensemble overlaid (log scale) …")
+ plot_absolute(orig, calib,
+ SUMMARY_DIR / "src_ensemble_absolute.png")
+
+ log.info("Plot 3 — normalized ensemble (Q / Q_2yr) …")
+ plot_normalized(orig, calib, usgs_rc,
+ SUMMARY_DIR / "src_ensemble_normalized.png")
+
+ log.info("Done. Outputs → %s", SUMMARY_DIR)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/plot_v2_diagnostics.py b/scripts/plot_v2_diagnostics.py
new file mode 100644
index 0000000..9a7f330
--- /dev/null
+++ b/scripts/plot_v2_diagnostics.py
@@ -0,0 +1,559 @@
+"""
+Post-calibration diagnostics for s05 v2 (zone-n calibration).
+
+Consumes the per-gauge ncalib_diagnostics.csv files written by s05 v2 plus the
+calibrated / baseline SRCs, and produces figures that each answer one QC or
+science question:
+
+ v2_01_datum_gap.png How big is the lidar bathymetry deficit (δ), and how
+ good are the PZF fits? (CONUS-scaling metadata)
+ v2_02_clip_rate.png Acceptance test: % of n values pinned at the physical
+ bounds, per zone. v1 reference = 28.6% at N_MIN.
+ v2_03_n_profiles.png Hypothesis-shape figure: calibrated n vs recurrence
+ zone, per gauge + median. Does n vary with stage?
+ v2_04_anchor_residuals.png Does the calibrated SRC actually pass through its
+ anchors? (Nonzero only where n was clipped.)
+ v2_05_holdout_validation.png Split-sample test: error at observed RC points
+ BETWEEN anchors (not used in calibration),
+ original vs calibrated.
+ v2_06_starting_point.png Origin match: SRC discharge at HAND stage 0 vs the
+ observed baseflow at the DEM water-surface elevation.
+ v2_rc_panels/ One panel per gauge: observed RC, original SRC,
+ calibrated SRC, anchors, mode/δ annotation.
+
+Run AFTER s05 v2 (any subset of HUCs is fine — it plots whatever diagnostics exist):
+ .venv\\Scripts\\python.exe scripts/plot_v2_diagnostics.py
+"""
+from __future__ import annotations
+
+import logging
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+from matplotlib.lines import Line2D
+
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans", "font.size": 10.5,
+ "axes.labelsize": 12, "axes.titlesize": 11.5, "axes.titleweight": "bold",
+ "axes.spines.top": False, "axes.spines.right": False,
+ "axes.grid": True, "grid.alpha": 0.20, "grid.linestyle": ":",
+ "legend.fontsize": 9.5, "legend.framealpha": 0.92, "figure.dpi": 150,
+})
+
+C_ORIG = "#2471a3" # original SRC
+C_CALIB = "#c0392b" # calibrated SRC
+C_OBS = "#111111" # USGS observed
+C_GOOD = "#187E86"
+C_WARN = "#C08A2D"
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+DATA_DIR = Path("data")
+V2_DIR = Path("E:/SI/out/calibration_analysis/v2_diagnostics")
+
+N_MIN, N_MAX = 0.010, 0.300
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+RECUR_COLS = {yr: f"{yr}_0_year_recurrence_flow_17C" for yr in RECURRENCE_YEARS}
+V1_CLIP_LOW_PCT = 28.6 # v1 reference for the acceptance test
+ANCHOR_EXCLUDE_M = 0.35 # hold-out: exclude RC points this close to an anchor
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+# ══════════════════════════════════════════════════════════════════
+# Data assembly
+# ══════════════════════════════════════════════════════════════════
+
+def load_shared():
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["location_id"] = rc["location_id"].astype(str)
+ rc["flow_cms"] = rc["flow"].astype(float) / 35.3147
+ rc["elev_m"] = rc["elevation_navd88"].astype(float) / 3.28084
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr, col in RECUR_COLS.items():
+ recur[f"Q_{yr}yr_cms"] = recur[col].astype(float) * 0.028317
+ recur["feature_id"] = recur["feature_id"].astype("Int64")
+ return rc, recur
+
+
+def load_diagnostics(hucs: list[str]) -> pd.DataFrame:
+ frames = []
+ for huc8 in hucs:
+ p = OUT_DIR / f"HUC{huc8}" / "ncalib_diagnostics.csv"
+ if p.exists():
+ frames.append(pd.read_csv(p, dtype={"location_id": str, "branch": str}))
+ if not frames:
+ raise FileNotFoundError("No ncalib_diagnostics.csv found — run s05 v2 first.")
+ diag = pd.concat(frames, ignore_index=True)
+ diag["huc8"] = diag["huc8"].astype(str).str.zfill(8)
+ log.info("Diagnostics: %d gauge records (%d calibrated) across %d HUCs",
+ len(diag), (diag["status"] == "calibrated").sum(),
+ diag["huc8"].nunique())
+ return diag
+
+
+def anchor_table(g: dict, rc: pd.DataFrame, recur: pd.DataFrame) -> list[tuple]:
+ """[(yr, hand_stage, Q_r)] for one gauge — same math as s05."""
+ grc = rc[rc["location_id"] == g["location_id"]].sort_values("flow_cms")
+ grc = grc.drop_duplicates("flow_cms")
+ feat = recur[recur["feature_id"] == g["feature_id"]]
+ if grc.empty or feat.empty:
+ return []
+ out = []
+ for yr in RECURRENCE_YEARS:
+ Q_r = float(feat[f"Q_{yr}yr_cms"].iloc[0])
+ if Q_r <= 0 or not (grc["flow_cms"].min() <= Q_r <= grc["flow_cms"].max()):
+ continue
+ elev_r = float(np.interp(Q_r, grc["flow_cms"], grc["elev_m"]))
+ hand_r = elev_r - g["dem_adj_m"]
+ if hand_r > 0:
+ out.append((yr, hand_r, Q_r))
+ return out
+
+
+def gauge_records(diag: pd.DataFrame, rc: pd.DataFrame, recur: pd.DataFrame):
+ """
+ Yields, per calibrated gauge, everything the figures need:
+ diagnostics row, anchors, orig/calib SRC slices, observed RC in HAND space.
+ """
+ for huc8, sub in diag[diag["status"] == "calibrated"].groupby("huc8"):
+ elev_path = OUT_DIR / f"HUC{huc8}" / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ continue
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ elev["location_id"] = elev["location_id"].str.zfill(8)
+
+ for bid, brows in sub.groupby("branch"):
+ bdir = OUT_DIR / f"HUC{huc8}" / "watershed-data" / "branches" / str(bid)
+ # hydroTable is the calibration's single source of truth:
+ # current file = calibrated, .pre_n_calib backup = baseline.
+ src_c_p = bdir / f"hydroTable_{bid}.csv"
+ src_o_p = bdir / f"hydroTable_{bid}.pre_n_calib.csv"
+ if not (src_c_p.exists() and src_o_p.exists()):
+ continue
+ _ren = {"stage": "Stage", "discharge_cms": "Discharge (m3s-1)"}
+ src_c = pd.read_csv(src_c_p, low_memory=False).rename(columns=_ren)
+ src_o = pd.read_csv(src_o_p, low_memory=False).rename(columns=_ren)
+ src_c["HydroID"] = src_c["HydroID"].astype(int)
+ src_o["HydroID"] = src_o["HydroID"].astype(int)
+
+ for _, row in brows.iterrows():
+ loc = str(row["location_id"]).zfill(8)
+ erow = elev[(elev["location_id"] == loc) &
+ (elev["HydroID"] == row["hydroid"])]
+ if erow.empty:
+ continue
+ g = {
+ "huc8": huc8, "bid": str(bid),
+ "location_id": loc,
+ "hydroid": int(row["hydroid"]),
+ "feature_id": int(erow["feature_id"].iloc[0]),
+ "dem_adj_m": float(erow["dem_adj_elevation"].iloc[0]),
+ "diag": row,
+ }
+ anchors = anchor_table(g, rc, recur)
+ if not anchors:
+ continue
+ s_c = src_c[src_c["HydroID"] == g["hydroid"]].sort_values("Stage")
+ s_o = src_o[src_o["HydroID"] == g["hydroid"]].sort_values("Stage")
+ if s_c.empty or s_o.empty:
+ continue
+ grc = rc[rc["location_id"] == loc].copy()
+ grc["hand"] = grc["elev_m"] - g["dem_adj_m"]
+ grc = grc[grc["hand"] > 0].sort_values("hand")
+ yield g, anchors, s_o, s_c, grc
+
+
+# ══════════════════════════════════════════════════════════════════
+# Figures
+# ══════════════════════════════════════════════════════════════════
+
+def fig_datum_gap(diag: pd.DataFrame):
+ d = diag[diag["status"] == "calibrated"]
+ # mode names come from s05_ncalib_core.METHOD params; any wedge_* mode
+ # carries a PZF-derived delta.
+ is_wedge = d["mode"].astype(str).str.startswith(("wedge", "pzf"))
+ fig, axes = plt.subplots(1, 3, figsize=(15, 4.6), constrained_layout=True)
+
+ ax = axes[0]
+ dd = d[is_wedge]["delta_m"].dropna()
+ if len(dd):
+ ax.hist(dd, bins=24, color=C_GOOD, alpha=0.85, edgecolor="white")
+ ax.axvline(dd.median(), color="#111", lw=1.6, ls="--",
+ label=f"median δ = {dd.median():.2f} m")
+ ax.legend()
+ ax.set_xlabel("Datum gap δ (m of channel invisible to lidar)")
+ ax.set_ylabel("Gauges")
+ ax.set_title("Bathymetry deficit recovered from PZF fits")
+
+ ax = axes[1]
+ counts = d["mode"].value_counts()
+ labels = {"wedge_continuity": "continuity wedge\n(primary)",
+ "wedge_topwidth": "TopWidth wedge",
+ "datum_shift": "datum shift",
+ "q0_offset": "Q₀ offset\n(fallback)",
+ "none": "none"}
+ order = [m for m in labels if m in counts.index]
+ clrs = {m: (C_GOOD if m.startswith(("wedge", "pzf")) else
+ C_WARN if m == "q0_offset" else "#999") for m in order}
+ ax.bar(range(len(order)), [counts[m] for m in order],
+ color=[clrs[m] for m in order], width=0.55)
+ for i, m in enumerate(order):
+ ax.text(i, counts[m], f" {counts[m]}", ha="center", va="bottom",
+ fontsize=10, fontweight="bold")
+ ax.set_xticks(range(len(order)))
+ ax.set_xticklabels([labels[m] for m in order])
+ ax.set_ylabel("Gauges")
+ ax.set_title("Starting-point correction mode")
+
+ ax = axes[2]
+ dd = d[is_wedge]
+ if len(dd):
+ ax.scatter(dd["delta_m"], dd["pzf_b"], s=30, color=C_GOOD,
+ alpha=0.75, edgecolors="#333", linewidths=0.4)
+ ax.axhspan(1.3, 2.7, color=C_GOOD, alpha=0.08)
+ ax.text(0.98, 0.02, "shaded: typical natural-control range b ≈ 1.3–2.7",
+ transform=ax.transAxes, ha="right", va="bottom",
+ fontsize=8, color="#666", style="italic")
+ ax.set_xlabel("Datum gap δ (m)")
+ ax.set_ylabel("PZF power-law exponent b")
+ ax.set_title("Fit plausibility: δ vs hydraulic exponent")
+
+ out = V2_DIR / "v2_01_datum_gap.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out.name)
+
+
+def fig_clip_rate(diag: pd.DataFrame):
+ d = diag[diag["status"] == "calibrated"]
+ n_cols = [f"n_{yr}yr" for yr in RECURRENCE_YEARS]
+ lo_pct, hi_pct, n_tot = [], [], []
+ for c in n_cols:
+ v = d[c].dropna()
+ n_tot.append(len(v))
+ lo_pct.append(100 * (v <= N_MIN + 1e-6).mean() if len(v) else 0)
+ hi_pct.append(100 * (v >= N_MAX - 1e-6).mean() if len(v) else 0)
+
+ x = np.arange(len(RECURRENCE_YEARS))
+ fig, ax = plt.subplots(figsize=(10, 5.4), constrained_layout=True)
+ ax.bar(x - 0.18, lo_pct, 0.34, color=C_CALIB, alpha=0.85,
+ label=f"pinned at N_MIN = {N_MIN}")
+ ax.bar(x + 0.18, hi_pct, 0.34, color=C_WARN, alpha=0.85,
+ label=f"pinned at N_MAX = {N_MAX}")
+ for xi, (lp, nt) in enumerate(zip(lo_pct, n_tot)):
+ ax.text(xi - 0.18, lp, f"{lp:.0f}%", ha="center", va="bottom", fontsize=9)
+ ax.axhline(V1_CLIP_LOW_PCT, color="#555", lw=1.6, ls="--")
+ ax.text(len(x) - 0.5, V1_CLIP_LOW_PCT + 0.8,
+ f"v1 (no datum correction): {V1_CLIP_LOW_PCT}% at N_MIN",
+ ha="right", fontsize=9.5, color="#555")
+ ax.set_xticks(x)
+ ax.set_xticklabels([f"{yr}-yr zone\n(n={nt})" for yr, nt in
+ zip(RECURRENCE_YEARS, n_tot)])
+ ax.set_ylabel("% of calibrated n values at a physical bound")
+ ax.set_title("Acceptance test — bound saturation after datum/bathymetry correction\n"
+ "(a pinned n means the anchor was NOT honored; the site needs review)")
+ ax.legend()
+ out = V2_DIR / "v2_02_clip_rate.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out.name)
+
+
+def fig_n_profiles(diag: pd.DataFrame):
+ d = diag[diag["status"] == "calibrated"]
+ n_cols = [f"n_{yr}yr" for yr in RECURRENCE_YEARS]
+ x = np.arange(len(RECURRENCE_YEARS))
+
+ fig, axes = plt.subplots(1, 2, figsize=(14, 5.6), constrained_layout=True)
+
+ ax = axes[0]
+ mat = d[n_cols].to_numpy(float)
+ for row in mat:
+ ax.plot(x, row, color="#777", lw=0.8, alpha=0.35)
+ med = np.nanmedian(mat, axis=0)
+ ax.plot(x, med, color=C_CALIB, lw=3.2, marker="o", ms=7, zorder=6,
+ label="study-area median")
+ ax.axhline(0.06, color=C_ORIG, ls="--", lw=1.4, label="OWP default n = 0.06")
+ ax.set_xticks(x)
+ ax.set_xticklabels([f"{yr}-yr" for yr in RECURRENCE_YEARS])
+ ax.set_xlabel("Recurrence zone (deeper →)")
+ ax.set_ylabel("Calibrated Manning's n (slice/band roughness)")
+ ax.set_title("The hypothesis figure: n as a function of stage\n"
+ "(slice n = roughness of the flow added in each depth band; "
+ "one gray line per gauge)")
+ ax.legend()
+
+ ax = axes[1]
+ mat_norm = mat / mat[:, [0]]
+ for row in mat_norm:
+ ax.plot(x, row, color="#777", lw=0.8, alpha=0.35)
+ ax.plot(x, np.nanmedian(mat_norm, axis=0), color=C_CALIB, lw=3.2,
+ marker="o", ms=7, zorder=6, label="median")
+ ax.axhline(1.0, color="#555", ls=":", lw=1.4)
+ ax.set_xticks(x)
+ ax.set_xticklabels([f"{yr}-yr" for yr in RECURRENCE_YEARS])
+ ax.set_xlabel("Recurrence zone (deeper →)")
+ ax.set_ylabel("n / n(2-yr) — shape only")
+ ax.set_title("Same profiles, normalized by the 2-yr value\n"
+ "(below 1.0 = smoother with depth; above = overbank roughening)")
+ ax.legend()
+
+ out = V2_DIR / "v2_03_n_profiles.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out.name)
+
+
+def fig_anchor_residuals(records):
+ rows = []
+ for g, anchors, s_o, s_c, grc in records:
+ st = s_c["Stage"].to_numpy(float)
+ qc = s_c["Discharge (m3s-1)"].to_numpy(float)
+ for yr, h_r, Q_r in anchors:
+ q_at = float(np.interp(h_r, st, qc))
+ rows.append({"yr": yr, "resid_pct": 100 * (q_at - Q_r) / Q_r,
+ "clipped": (g["diag"]["n_clipped_low"] > 0 or
+ g["diag"]["n_clipped_high"] > 0)})
+ df = pd.DataFrame(rows)
+ if df.empty:
+ return df
+
+ fig, ax = plt.subplots(figsize=(10, 5.4), constrained_layout=True)
+ data, npts = [], []
+ for yr in RECURRENCE_YEARS:
+ v = df[df["yr"] == yr]["resid_pct"].to_numpy()
+ data.append(v)
+ npts.append(len(v))
+ bp = ax.boxplot(data, patch_artist=True, showfliers=False,
+ medianprops=dict(color="#111", lw=2))
+ for b in bp["boxes"]:
+ b.set(facecolor=C_GOOD, alpha=0.35)
+ for i, v in enumerate(data, 1):
+ if len(v):
+ ax.scatter(np.full(len(v), i) + np.random.uniform(-0.07, 0.07, len(v)),
+ v, s=22, color=C_GOOD, alpha=0.7,
+ edgecolors="#333", linewidths=0.4, zorder=5)
+ ax.axhline(0, color="#555", lw=1.4, ls="--")
+ ax.set_xticklabels([f"{yr}-yr\n(n={n})" for yr, n in zip(RECURRENCE_YEARS, npts)])
+ # Clip the view so pinned-n outliers don't flatten the distribution;
+ # annotate how many sit beyond the frame.
+ y_lo, y_hi = -60, 150
+ n_out = int((df["resid_pct"] > y_hi).sum() + (df["resid_pct"] < y_lo).sum())
+ ax.set_ylim(y_lo, y_hi)
+ if n_out:
+ ax.text(0.98, 0.98, f"{n_out} outlier anchor(s) beyond ±frame\n"
+ "(pinned-n / datum-offset gauges — see diagnostics)",
+ transform=ax.transAxes, ha="right", va="top",
+ fontsize=9, color="#777", style="italic")
+ ax.set_ylabel("Anchor residual (Q_SRC − Q_r) / Q_r ×100 [%]")
+ ax.set_title("Does the calibrated SRC pass through its anchors?\n"
+ "(nonzero residuals occur only where n hit a physical bound "
+ "or a transition band overlaps the anchor)")
+ out = V2_DIR / "v2_04_anchor_residuals.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out.name)
+ return df
+
+
+def fig_holdout(records):
+ """Observed RC points between anchors were never used in calibration —
+ error there is a genuine split-sample test."""
+ rows = []
+ for g, anchors, s_o, s_c, grc in records:
+ if len(anchors) < 2 or grc.empty:
+ continue
+ h_lo = anchors[0][1]
+ h_hi = anchors[-1][1]
+ anchor_h = np.array([a[1] for a in anchors])
+ pts = grc[(grc["hand"] > h_lo) & (grc["hand"] < h_hi)]
+ st_o = s_o["Stage"].to_numpy(float); q_o = s_o["Discharge (m3s-1)"].to_numpy(float)
+ st_c = s_c["Stage"].to_numpy(float); q_c = s_c["Discharge (m3s-1)"].to_numpy(float)
+ for _, p in pts.iterrows():
+ h, q_obs = float(p["hand"]), float(p["flow_cms"])
+ if q_obs <= 0 or np.min(np.abs(anchor_h - h)) < ANCHOR_EXCLUDE_M:
+ continue
+ rows.append({
+ "gauge": g["location_id"],
+ "err_orig": 100 * (float(np.interp(h, st_o, q_o)) - q_obs) / q_obs,
+ "err_calib": 100 * (float(np.interp(h, st_c, q_c)) - q_obs) / q_obs,
+ })
+ df = pd.DataFrame(rows)
+ if df.empty:
+ log.warning("Hold-out figure skipped — no between-anchor RC points found")
+ return df
+
+ per_g = df.groupby("gauge").agg(
+ mae_orig=("err_orig", lambda v: np.mean(np.abs(v))),
+ mae_calib=("err_calib", lambda v: np.mean(np.abs(v))),
+ n_pts=("err_orig", "size"),
+ ).reset_index()
+
+ fig, axes = plt.subplots(1, 2, figsize=(14, 5.8), constrained_layout=True)
+
+ ax = axes[0]
+ lim = float(np.nanpercentile(
+ np.concatenate([per_g["mae_orig"], per_g["mae_calib"]]), 98)) * 1.15
+ lim = max(lim, 20)
+ ax.scatter(per_g["mae_orig"], per_g["mae_calib"], s=34, color=C_CALIB,
+ alpha=0.75, edgecolors="#333", linewidths=0.4)
+ ax.plot([0, lim], [0, lim], color="#555", lw=1.3, ls="--")
+ ax.set_xlim(0, lim); ax.set_ylim(0, lim)
+ better = (per_g["mae_calib"] < per_g["mae_orig"]).mean() * 100
+ ax.text(0.03, 0.97, f"{better:.0f}% of gauges improved\n(points below the 1:1 line)",
+ transform=ax.transAxes, va="top", fontsize=10,
+ bbox=dict(boxstyle="round,pad=0.3", facecolor="white", alpha=0.85))
+ ax.set_xlabel("MAE at held-out RC points — ORIGINAL SRC [%]")
+ ax.set_ylabel("MAE at held-out RC points — CALIBRATED [%]")
+ ax.set_title("Split-sample test, per gauge\n"
+ "(observed points between anchors; never used in calibration)")
+
+ ax = axes[1]
+ bins = np.linspace(-100, 100, 41)
+ ax.hist(df["err_orig"].clip(-100, 100), bins=bins, color=C_ORIG, alpha=0.55,
+ label=f"original (median {df['err_orig'].median():+.0f}%)")
+ ax.hist(df["err_calib"].clip(-100, 100), bins=bins, color=C_CALIB, alpha=0.55,
+ label=f"calibrated (median {df['err_calib'].median():+.0f}%)")
+ ax.axvline(0, color="#333", lw=1.3)
+ ax.set_xlabel("Discharge error at held-out RC points [%] (clipped at ±100)")
+ ax.set_ylabel("RC points")
+ ax.set_title("Pooled error distribution — all held-out points")
+ ax.legend()
+
+ out = V2_DIR / "v2_05_holdout_validation.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out.name)
+ return df
+
+
+def fig_starting_point(records, rc: pd.DataFrame):
+ rows = []
+ for g, anchors, s_o, s_c, grc in records:
+ grc_all = rc[rc["location_id"] == g["location_id"]].sort_values("elev_m")
+ if grc_all.empty:
+ continue
+ q_obs0 = float(np.interp(g["dem_adj_m"],
+ grc_all["elev_m"], grc_all["flow_cms"]))
+ s0 = s_c[s_c["Stage"] == 0.0]
+ q_src0 = float(s0["Discharge (m3s-1)"].iloc[0]) if not s0.empty else np.nan
+ rows.append({"gauge": g["location_id"], "q_obs0": q_obs0, "q_src0": q_src0,
+ "mode": g["diag"]["mode"]})
+ df = pd.DataFrame(rows).dropna()
+ if df.empty:
+ return
+
+ fig, ax = plt.subplots(figsize=(7.4, 6.6), constrained_layout=True)
+ lim = max(df[["q_obs0", "q_src0"]].to_numpy().max() * 1.15, 1.0)
+ is_wedge = df["mode"].astype(str).str.startswith(("wedge", "pzf"))
+ for mask, clr, lbl in ((is_wedge, C_GOOD, "wedge (PZF δ)"),
+ (~is_wedge, C_WARN, "Q₀ offset / other")):
+ sub = df[mask]
+ if len(sub):
+ ax.scatter(sub["q_obs0"], sub["q_src0"], s=40, color=clr, alpha=0.8,
+ edgecolors="#333", linewidths=0.4, label=lbl)
+ ax.plot([0.1, lim], [0.1, lim], color="#555", lw=1.3, ls="--", label="1:1")
+ ax.set_xscale("log"); ax.set_yscale("log")
+ ax.set_xlim(0.1, lim); ax.set_ylim(0.1, lim)
+ ax.set_xlabel("Observed baseflow at DEM water-surface elevation (m³/s)")
+ ax.set_ylabel("Calibrated SRC discharge at HAND stage 0 (m³/s)")
+ ax.set_title("Do the curves now start in the same place?\n"
+ "(v1 forced every SRC to start at zero)")
+ ax.legend()
+ out = V2_DIR / "v2_06_starting_point.png"
+ fig.savefig(out, dpi=150, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ log.info("Saved: %s", out.name)
+
+
+def fig_rc_panels(records):
+ panel_dir = V2_DIR / "v2_rc_panels"
+ panel_dir.mkdir(parents=True, exist_ok=True)
+ n_done = 0
+ for g, anchors, s_o, s_c, grc in records:
+ fig, ax = plt.subplots(figsize=(9.5, 6.4), constrained_layout=True)
+
+ h_max = max(a[1] for a in anchors) * 1.6
+ q_max = max(a[2] for a in anchors) * 1.8
+
+ for i, (yr, h_r, _) in enumerate(anchors):
+ ax.axhspan(0 if i == 0 else anchors[i - 1][1], h_r,
+ color="#187E86", alpha=0.045 if i % 2 == 0 else 0.09)
+ if not grc.empty:
+ ax.plot(grc["flow_cms"], grc["hand"], color=C_OBS, lw=2.0,
+ label="USGS observed RC", zorder=5)
+ ax.plot(s_o["Discharge (m3s-1)"], s_o["Stage"], color=C_ORIG, lw=1.8,
+ label="Original SRC (n = 0.06)", zorder=4)
+ ax.plot(s_c["Discharge (m3s-1)"], s_c["Stage"], color=C_CALIB, lw=2.6,
+ ls="--", label="Calibrated SRC (v2)", zorder=6)
+ for yr, h_r, Q_r in anchors:
+ ax.scatter([Q_r], [h_r], s=52, color=C_CALIB, edgecolors="white",
+ linewidths=1.4, zorder=8)
+ ax.annotate(f"{yr}-yr", (Q_r, h_r), textcoords="offset points",
+ xytext=(7, -3), fontsize=8.5, color=C_CALIB,
+ fontweight="bold")
+
+ d = g["diag"]
+ mode_txt = {"pzf_wedge": f"PZF wedge δ = {d['delta_m']:.2f} m (r² = {d['pzf_r2']:.3f})",
+ "q0_offset": f"baseflow offset Q₀ = {d['q0_cms']:.1f} m³/s"}.get(
+ d["mode"], d["mode"])
+ n_txt = " ".join(f"n({yr}) = {d[f'n_{yr}yr']:.3f}"
+ for yr in RECURRENCE_YEARS
+ if pd.notna(d.get(f"n_{yr}yr")))
+ ax.set_title(f"Gauge {g['location_id']} · HydroID {g['hydroid']} · "
+ f"HUC {g['huc8']}\n{mode_txt}\n{n_txt}", fontsize=10)
+ ax.set_xlim(0, q_max)
+ ax.set_ylim(0, h_max)
+ ax.set_xlabel("Discharge (m³/s)")
+ ax.set_ylabel("HAND stage (m)")
+ ax.legend(loc="lower right")
+
+ out = panel_dir / f"{g['huc8']}_{g['location_id']}.png"
+ fig.savefig(out, dpi=140, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+ n_done += 1
+ log.info("Saved: %d RC panels → %s", n_done, panel_dir)
+
+
+# ══════════════════════════════════════════════════════════════════
+# Main
+# ══════════════════════════════════════════════════════════════════
+
+def main():
+ V2_DIR.mkdir(parents=True, exist_ok=True)
+ hucs = [str(int(c)).zfill(8)
+ for c in pd.read_excel(EXCEL_PATH)[HUC_CODE_COL]]
+
+ rc, recur = load_shared()
+ diag = load_diagnostics(hucs)
+
+ # Aggregate figures straight from diagnostics
+ fig_datum_gap(diag)
+ fig_clip_rate(diag)
+ fig_n_profiles(diag)
+
+ # Figures that need the SRC curves — assemble once, reuse
+ records = list(gauge_records(diag, rc, recur))
+ log.info("Gauge records with SRC + anchors: %d", len(records))
+ fig_anchor_residuals(records)
+ holdout = fig_holdout(records)
+ fig_starting_point(records, rc)
+ fig_rc_panels(records)
+
+ if not holdout.empty:
+ holdout.to_csv(V2_DIR / "holdout_errors.csv", index=False)
+ log.info("Done → %s", V2_DIR)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s00_study_boundary.py b/scripts/s00_study_boundary.py
new file mode 100644
index 0000000..3faf1a0
--- /dev/null
+++ b/scripts/s00_study_boundary.py
@@ -0,0 +1,66 @@
+from pathlib import Path
+import pandas as pd
+import geopandas as gpd
+from shapely import wkt
+
+# ── EDIT THESE ───────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+
+# "wkt" — use the wkt_geom column already in the Excel (requires knowing the CRS)
+# "service" — fetch boundaries by HUC_CODE from the USGS web service (no CRS needed)
+MODE = "service"
+
+# Used only when MODE = "wkt". Confirm the CRS with your data source.
+# Coordinate values ~1.5M–1.65M suggest EPSG:5070 (NAD83 Conus Albers).
+WKT_CRS = "EPSG:5069"
+
+# Optional: list specific HUC_CODE values to include.
+# Leave as [] to use ALL rows in the Excel.
+HUC_CODES = [] # e.g. [3020102, 3020103, 3020104]
+# ─────────────────────────────────────────────────────────────────
+
+OUT_PATH = Path("docs/study_boundary/study_area.gpkg")
+
+df = pd.read_excel(EXCEL_PATH)
+print(f"Loaded {len(df)} rows from Excel")
+
+if HUC_CODES:
+ df = df[df["HUC_CODE"].isin(HUC_CODES)]
+ print(f"Filtered to {len(df)} rows matching HUC_CODES")
+
+if MODE == "wkt":
+ # ── Option A: use WKT geometry already in the Excel ──────────
+ df["geometry"] = df["wkt_geom"].apply(wkt.loads)
+ gdf = gpd.GeoDataFrame(df, geometry="geometry", crs=WKT_CRS)
+
+elif MODE == "service":
+ # ── Option B: fetch boundaries from USGS web service ─────────
+ # HUC_CODE in the Excel may be 7-digit (e.g. 3020102); zero-pad to 8.
+ from fimbox import HUC8Finder
+ finder = HUC8Finder()
+ frames = []
+ skipped = []
+ for code in df["HUC_CODE"]:
+ huc8 = str(int(code)).zfill(8)
+ print(f" Fetching HUC8 {huc8} ...")
+ try:
+ frames.append(finder.from_huc8(huc8))
+ except ValueError:
+ print(f" WARNING: HUC8 {huc8} not found in service — skipping")
+ skipped.append(huc8)
+ if skipped:
+ print(f"\nSkipped {len(skipped)} HUC(s) not found in service: {skipped}")
+ gdf = pd.concat(frames, ignore_index=True)
+ gdf = gpd.GeoDataFrame(gdf, geometry="geometry")
+
+else:
+ raise ValueError(f"MODE must be 'wkt' or 'service', got {MODE!r}")
+
+dissolved = gdf.dissolve().reset_index(drop=True)[["geometry"]]
+# Simplify to reduce vertex count — the ArcGIS FeatureServer rejects
+# overly complex geometries as spatial filters (returns HTTP 400).
+dissolved["geometry"] = dissolved["geometry"].simplify(0.01, preserve_topology=True)
+
+OUT_PATH.parent.mkdir(parents=True, exist_ok=True)
+dissolved.to_file(OUT_PATH, driver="GPKG", index=False)
+print(f"Saved merged boundary ({len(df)} HUCs dissolved) --> {OUT_PATH}")
diff --git a/scripts/s01_download_dem_fast.py b/scripts/s01_download_dem_fast.py
new file mode 100644
index 0000000..0f352c3
--- /dev/null
+++ b/scripts/s01_download_dem_fast.py
@@ -0,0 +1,52 @@
+"""
+Download 10m 3DEP DEM for the full study area using fimbox.DEMProcessor.
+
+DEMProcessor reads directly from Planetary Computer COGs (cloud-optimised
+GeoTIFFs) — only the AOI window is fetched over HTTP, so there is no national
+VRT parsing and no per-tile OOM. It handles reprojection, hole-fill, and clip
+internally. ~8x faster than the py3dep tile-and-merge approach in
+s01_download_dem.py.
+
+Run ONCE before the main pipeline. Pass the output path via dem= in
+test_getallinputdata.py.
+
+Usage:
+ .venv\\Scripts\\python.exe scripts/s01_download_dem_fast.py
+"""
+from pathlib import Path
+
+import fimbox
+
+# ── CONFIG ────────────────────────────────────────────────────────
+BOUNDARY = Path("docs/study_boundary/study_area.gpkg")
+RESOLUTION = 10 # metres (1 / 3 / 10 / 30 — 10 m is nationwide)
+EPSG = 5070 # CONUS Albers — matches the rest of the pipeline
+OUT_DIR = Path("E:/SI/out/study_area/watershed-data")
+OUT_NAME = "3dep_dem_10m.tif"
+# ─────────────────────────────────────────────────────────────────
+
+
+def main():
+ OUT_DIR.mkdir(parents=True, exist_ok=True)
+
+ print(f"Boundary : {BOUNDARY}")
+ print(f"Resolution: {RESOLUTION} m")
+ print(f"Output : {OUT_DIR / OUT_NAME}")
+ print("Downloading …")
+
+ fimbox.DEMProcessor(
+ boundary=BOUNDARY,
+ output_dir=OUT_DIR,
+ resolution=RESOLUTION,
+ out_name=OUT_NAME,
+ epsg=EPSG,
+ )
+
+ out = OUT_DIR / OUT_NAME
+ print(f"\nDone → {out}")
+ print(f"\nNext step: pass this path as dem= in test_getallinputdata.py:")
+ print(f' dem=Path("{out}"),')
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s02_stage1_all_hucs.py b/scripts/s02_stage1_all_hucs.py
new file mode 100644
index 0000000..31cf897
--- /dev/null
+++ b/scripts/s02_stage1_all_hucs.py
@@ -0,0 +1,100 @@
+"""
+Stage 1 — Data Download for all HUC8s in the study area.
+Downloads NWM flowlines, catchments, levees, OSM roads, FEMA data.
+Uses pre-downloaded 10m DEM tiles from DEM_TILES_DIR.
+
+Progress is written to TASK_LOG after each HUC so a re-run skips completed ones.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/run_stage1_download.py
+"""
+import logging
+import traceback
+from pathlib import Path
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+DEM_TILES_DIR = Path("E:/SI/out/study_area/watershed-data/dem_tiles")
+OUT_DIR = Path("E:/SI/out")
+IDENTIFIER = "nwmmr"
+BUFFER_M = 5000
+TASK_LOG = Path("E:/SI/out/stage1_status.txt") # records pass/fail per HUC
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _load_done() -> set[str]:
+ """Return set of HUC8s already marked PASS in the task log."""
+ if not TASK_LOG.exists():
+ return set()
+ done = set()
+ for line in TASK_LOG.read_text().splitlines():
+ parts = line.strip().split()
+ if len(parts) == 3 and parts[2] == "PASS":
+ done.add(parts[1])
+ return done
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage1 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def run_huc(huc8: str) -> None:
+ import fimbox
+
+ dem_path = DEM_TILES_DIR / f"dem_{huc8}.tif"
+ if not dem_path.exists():
+ raise FileNotFoundError(f"DEM tile not found: {dem_path}")
+
+ pp = fimbox.getAllInputData(
+ huc8=huc8,
+ out_dir=str(OUT_DIR),
+ buffer_m=BUFFER_M,
+ headwater_buffer_cells=8,
+ get_flowlines=True,
+ get_catchments=True,
+ resolution="medium",
+ identifier=IDENTIFIER,
+ dem=dem_path,
+ )
+ pp.run()
+
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ done = _load_done()
+ remaining = [h for h in hucs if h not in done]
+
+ log.info(f"Stage 1: {len(hucs)} total | {len(done)} already done | {len(remaining)} to run")
+
+ passed, failed = list(done), []
+ for i, huc8 in enumerate(remaining, 1):
+ log.info(f" [{i}/{len(remaining)}] HUC8 = {huc8}")
+ try:
+ run_huc(huc8)
+ _log_result(huc8, "PASS")
+ passed.append(huc8)
+ log.info(f" [{huc8}] PASS → {OUT_DIR / f'HUC{huc8}'}")
+ except Exception:
+ err = traceback.format_exc().splitlines()[-1]
+ _log_result(huc8, "FAIL", err)
+ failed.append(huc8)
+ log.error(f" [{huc8}] FAIL: {err}")
+
+ log.info(f"\nStage 1 done. Passed: {len(passed)} Failed: {len(failed)}")
+ if failed:
+ log.warning(f"Failed HUCs: {failed}")
+ log.warning(f"Re-run this script to retry failures (edit TASK_LOG to remove their FAIL lines first).")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s03_stage2_all_hucs.py b/scripts/s03_stage2_all_hucs.py
new file mode 100644
index 0000000..ba6129a
--- /dev/null
+++ b/scripts/s03_stage2_all_hucs.py
@@ -0,0 +1,189 @@
+"""
+Stage 2 — HAND Processing for all HUC8s in the study area.
+Runs BranchDerivation then calculate_allbranches (DEM conditioning,
+HAND rasters, synthetic rating curves) for each HUC.
+
+Prerequisite: run_stage1_download.py must have completed for a HUC
+before this script processes it.
+
+Progress is written to TASK_LOG after each HUC so a re-run skips completed ones.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/run_stage2_hand.py
+"""
+import logging
+import time
+import traceback
+from datetime import datetime
+from pathlib import Path
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+IDENTIFIER = "nwmmr"
+TASK_LOG = Path("E:/SI/out/stage2_status.txt")
+CONFIG_DIR = Path("config") # deny lists live here
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _load_done() -> set[str]:
+ if not TASK_LOG.exists():
+ return set()
+ done = set()
+ for line in TASK_LOG.read_text().splitlines():
+ parts = line.strip().split()
+ if len(parts) >= 3 and parts[2] == "PASS":
+ done.add(parts[1])
+ return done
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage2 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def run_huc(huc8: str) -> None:
+ from fimbox import AOIProcessingConfig, BranchDerivation, calculate_allbranches
+ from fimbox._dask import _resolve_n_workers
+
+ aoi_dir = OUT_DIR / f"HUC{huc8}" / "watershed-data"
+ if not aoi_dir.exists():
+ raise FileNotFoundError(f"watershed-data not found — run Stage 1 first: {aoi_dir}")
+
+ def _opt(p: Path):
+ return p if p.exists() else None
+
+ # Step Z0: level paths + branch polygons
+ BranchDerivation(
+ out_dir=aoi_dir,
+ branch_id_attribute="levpa_id",
+ reach_id_attribute="ID",
+ branch_buffer_distance_meters=7000.0,
+ ).run()
+
+ # Steps Z1 + B: BranchZero (whole AOI) then all non-zero branches in parallel
+ cfg = AOIProcessingConfig(
+ aoi_dir=aoi_dir,
+ branch_list_path=aoi_dir / "branch_ids.lst",
+ dem_path=aoi_dir / "dem.tif",
+ streams_gpkg=aoi_dir / f"{IDENTIFIER}_subset_streams.gpkg",
+ boundary_gpkg=aoi_dir / "wbd_buffered.gpkg",
+ bridge_elev_diff_path=_opt(aoi_dir / "bridge_elev_diff.tif"),
+ levee_gpkg_path=_opt(aoi_dir / "3d_nld_subset_levees_burned.gpkg"),
+ headwaters_gpkg=_opt(aoi_dir / f"{IDENTIFIER}_headwater_points_subset.gpkg"),
+ levelpaths_extended_gpkg=_opt(
+ aoi_dir / f"{IDENTIFIER}_subset_streams_levelPaths_extended.gpkg"
+ ),
+ # AGREE DEM conditioning
+ agree_buffer_m=15.0,
+ agree_smooth_drop=10.0,
+ agree_sharp_drop=1000.0,
+ # HAND geometry
+ cost_distance_tolerance=50.0,
+ lateral_elevation_threshold=10,
+ max_split_distance_m=1500.0,
+ slope_min=0.0001,
+ lakes_buffer_dist_m=100.0,
+ # SRC
+ mannings_n=0.06,
+ stage_min_m=0.0,
+ stage_interval_m=0.3048,
+ stage_max_m=25.2984,
+ min_catchment_area=0.25,
+ min_stream_length=0.5,
+ crosswalk_max_distance_m=100.0,
+ src_slope_source="iris_sword",
+ iris_slope_csv=None,
+ hfab_slope_column=None,
+ # execution
+ n_workers=_resolve_n_workers(),
+ keep_failed_branches=True,
+ delete_deny_list=True,
+ )
+
+ calculate_allbranches(
+ cfg,
+ run_branch_zero=True,
+ delete_deny_list=True,
+ deny_unit_list=CONFIG_DIR / "deny_unit.lst",
+ branch_ids_csv=aoi_dir / "branch_ids.csv",
+ )
+
+
+def _fmt(seconds: float) -> str:
+ seconds = int(seconds)
+ h, rem = divmod(seconds, 3600)
+ m, s = divmod(rem, 60)
+ if h:
+ return f"{h}h {m:02d}m {s:02d}s"
+ if m:
+ return f"{m}m {s:02d}s"
+ return f"{s}s"
+
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ done = _load_done()
+ remaining = [h for h in hucs if h not in done]
+
+ log.info(f"Stage 2: {len(hucs)} total | {len(done)} already done | {len(remaining)} to run")
+ log.info(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+
+ batch_start = time.time()
+ huc_times: list[tuple[str, float, str]] = [] # (huc8, elapsed_s, status)
+ passed, failed = list(done), []
+
+ for i, huc8 in enumerate(remaining, 1):
+ huc_start = time.time()
+ log.info(f" [{i}/{len(remaining)}] HUC8 = {huc8} | "
+ f"batch elapsed: {_fmt(huc_start - batch_start)}")
+ try:
+ run_huc(huc8)
+ elapsed = time.time() - huc_start
+ _log_result(huc8, "PASS")
+ passed.append(huc8)
+ huc_times.append((huc8, elapsed, "PASS"))
+
+ # running average and ETA over completed HUCs
+ completed = [t for _, t, s in huc_times if s == "PASS"]
+ avg_s = sum(completed) / len(completed)
+ remaining_n = len(remaining) - i
+ eta_s = avg_s * remaining_n
+ log.info(f" [{huc8}] PASS | this HUC: {_fmt(elapsed)} | "
+ f"avg: {_fmt(avg_s)} | remaining: {remaining_n} | "
+ f"ETA: {_fmt(eta_s)}"
+ + (f" (~{datetime.fromtimestamp(time.time() + eta_s).strftime('%H:%M')})"
+ if remaining_n > 0 else " (last HUC)"))
+ except Exception:
+ elapsed = time.time() - huc_start
+ err = traceback.format_exc().splitlines()[-1]
+ _log_result(huc8, "FAIL", err)
+ failed.append(huc8)
+ huc_times.append((huc8, elapsed, "FAIL"))
+ log.error(f" [{huc8}] FAIL after {_fmt(elapsed)} | {err}")
+
+ total = time.time() - batch_start
+ log.info(f"\n{'─'*60}")
+ log.info(f"Stage 2 complete | total time: {_fmt(total)}")
+ log.info(f"Finished: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+ log.info(f"Passed: {len(passed)} | Failed: {len(failed)}")
+ if huc_times:
+ log.info(f"\nPer-HUC timing summary:")
+ for huc8, elapsed, status in huc_times:
+ log.info(f" {huc8} {status:4s} {_fmt(elapsed)}")
+ if failed:
+ log.warning(f"\nFailed HUCs: {failed}")
+ log.warning("Re-run this script to retry (FAIL lines are automatically retried).")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s03b_fix_nonmonotonic_srcs.py b/scripts/s03b_fix_nonmonotonic_srcs.py
new file mode 100644
index 0000000..36625fc
--- /dev/null
+++ b/scripts/s03b_fix_nonmonotonic_srcs.py
@@ -0,0 +1,138 @@
+"""
+Stage 3b — force monotone rating curves in every branch hydroTable.
+
+Why this exists
+---------------
+The stage-2 SRC computation assembles A(h)/R(h) cell-by-cell from the HAND
+raster, and raster artifacts (bridge decks, pit-fill seams) produce rating
+curves where discharge DECREASES with stage on ~7% of reaches. A non-monotone
+curve corrupts the flow→stage lookup in FIM generation (the inundator sorts by
+discharge before interpolating). This is a property of the deterministic
+stage-2 code, not a corrupted run — re-running stage 2 reproduces it — so the
+fix is a pipeline step, exactly as OWP treats it (their SrcNonmonotonic class).
+
+Why not fimbox's SrcNonmonotonic
+--------------------------------
+The ported OWP class requires the `bankfull_proxy` column written by
+SrcBankfull (part of the OWP stage-4 calibration chain) and silently no-ops
+without it. It also replays geometry columns. This script is the minimal,
+dependency-free equivalent: per (HydroID[, feature_id]) cumulative maximum on
+discharge_cms, hydroTable-only (the calibration's single source of truth).
+
+The fix is idempotent and preserves already-monotone curves exactly.
+
+Pipeline position: after stage 2 (s03) and BEFORE calibration (s05a–d), so the
+fixed state is what calibration backs up as baseline.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s03b_fix_nonmonotonic_srcs.py
+"""
+from __future__ import annotations
+
+import logging
+import os
+import time
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+TASK_LOG = Path("E:/SI/out/s03b_status.txt")
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def fix_hydrotable(ht_path: Path) -> tuple[int, int]:
+ """
+ Enforce non-decreasing discharge_cms with stage per rating curve.
+ Returns (curves_fixed, rows_changed); writes only when something changed.
+ """
+ ht = pd.read_csv(ht_path, low_memory=False)
+ if "discharge_cms" not in ht.columns or "stage" not in ht.columns:
+ return 0, 0
+
+ key = ["HydroID", "feature_id"] if "feature_id" in ht.columns else ["HydroID"]
+ ht = ht.drop_duplicates(subset=key + ["stage"], keep="first")
+ ht = ht.sort_values(key + ["stage"]).reset_index(drop=True)
+
+ before = ht["discharge_cms"].to_numpy(float)
+ # pandas cummax leaves NaN rows (e.g. lakes) as NaN and continues the
+ # running max across them — exactly the behavior we want.
+ ht["discharge_cms"] = ht.groupby(key)["discharge_cms"].cummax()
+ after = ht["discharge_cms"].to_numpy(float)
+
+ valid = ~(np.isnan(before) & np.isnan(after))
+ changed = valid & ~np.isclose(np.nan_to_num(before, nan=-1),
+ np.nan_to_num(after, nan=-1))
+ rows_changed = int(changed.sum())
+ if rows_changed == 0:
+ return 0, 0
+
+ curves_fixed = int(ht.loc[changed, "HydroID"].nunique())
+ tmp = ht_path.with_suffix(".tmp.csv")
+ ht.to_csv(tmp, index=False)
+ os.replace(tmp, ht_path)
+ return curves_fixed, rows_changed
+
+
+def run_huc(huc8: str) -> tuple[int, int, int]:
+ branches = OUT_DIR / f"HUC{huc8}" / "watershed-data" / "branches"
+ if not branches.exists():
+ raise FileNotFoundError(f"branches dir not found: {branches}")
+ n_branches = curves = rows = 0
+ for branch_dir in sorted(d for d in branches.iterdir() if d.is_dir()):
+ bid = branch_dir.name
+ ht_path = branch_dir / f"hydroTable_{bid}.csv"
+ if not ht_path.exists():
+ continue
+ c, r = fix_hydrotable(ht_path)
+ n_branches += 1
+ curves += c
+ rows += r
+ return n_branches, curves, rows
+
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+
+ done = set()
+ if TASK_LOG.exists():
+ done = {p[1] for line in TASK_LOG.read_text().splitlines()
+ if len(p := line.strip().split()) >= 3 and p[2] == "PASS"}
+ remaining = [h for h in hucs if h not in done]
+ log.info("s03b monotonicity fix: %d total | %d done | %d to run",
+ len(hucs), len(done), len(remaining))
+
+ t0 = time.time()
+ tot_curves = tot_rows = 0
+ for i, huc8 in enumerate(remaining, 1):
+ t = time.time()
+ try:
+ nb, c, r = run_huc(huc8)
+ except Exception as exc:
+ with TASK_LOG.open("a") as f:
+ f.write(f"s03b {huc8} FAIL {exc}\n")
+ log.error(" [%d/%d] %s FAIL: %s", i, len(remaining), huc8, exc)
+ continue
+ tot_curves += c
+ tot_rows += r
+ with TASK_LOG.open("a") as f:
+ f.write(f"s03b {huc8} PASS curves={c} rows={r}\n")
+ log.info(" [%d/%d] %s PASS | %d branches | %d curves fixed | %d rows | %.0fs",
+ i, len(remaining), huc8, nb, c, r, time.time() - t)
+
+ log.info("s03b complete in %.0fs | %d curves fixed | %d rows changed",
+ time.time() - t0, tot_curves, tot_rows)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s04_usgs_gage_crosswalk_all_hucs.py b/scripts/s04_usgs_gage_crosswalk_all_hucs.py
new file mode 100644
index 0000000..95c1d56
--- /dev/null
+++ b/scripts/s04_usgs_gage_crosswalk_all_hucs.py
@@ -0,0 +1,243 @@
+"""
+USGS Gage Crosswalk for all HUC8s in the study area.
+
+Steps per HUC:
+ C20 Download USGS gauge points within the HUC8 boundary from ArcGIS Online
+ C21 Assign each gauge to a NWM level path (branch ID)
+ C22 Per-branch: snap gauges to thalweg, sample DEM to get dem_adj_elevation
+ CON Consolidate all per-branch usgs_elev_table.csv into one at AOI root
+ (required by s05 n-calibration and Stage 4 UsgsRatingCalibrator)
+
+Prerequisite: s03_stage2_all_hucs.py must have completed for each HUC.
+
+Progress is written to TASK_LOG after each HUC so a re-run skips completed ones.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s04_usgs_gage_crosswalk_all_hucs.py
+"""
+import logging
+import time
+import traceback
+from datetime import datetime
+from pathlib import Path
+
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+IDENTIFIER = "nwmmr"
+TASK_LOG = Path("E:/SI/out/crosswalk_status.txt")
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _load_done() -> set[str]:
+ if not TASK_LOG.exists():
+ return set()
+ done = set()
+ for line in TASK_LOG.read_text().splitlines():
+ parts = line.strip().split()
+ if len(parts) >= 3 and parts[2] == "PASS":
+ done.add(parts[1])
+ return done
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"crosswalk {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def _fmt(seconds: float) -> str:
+ seconds = int(seconds)
+ h, rem = divmod(seconds, 3600)
+ m, s = divmod(rem, 60)
+ if h:
+ return f"{h}h {m:02d}m {s:02d}s"
+ if m:
+ return f"{m}m {s:02d}s"
+ return f"{s}s"
+
+
+def run_huc(huc8: str) -> None:
+ from fimbox import DownloadUSGSGages, assign_gages_to_branches, run_branch_crosswalk
+ import geopandas as gpd
+
+ aoi_root = OUT_DIR / f"HUC{huc8}"
+ watershed = aoi_root / "watershed-data"
+ branches = watershed / "branches"
+
+ if not watershed.exists():
+ raise FileNotFoundError(f"watershed-data not found — run Stage 2 first: {watershed}")
+
+ # ── C20: Download gages ──────────────────────────────────────────
+ usgs_gages_gpkg = watershed / "usgs_gages.gpkg"
+ if not usgs_gages_gpkg.exists():
+ boundary_gpkg = watershed / "wbd.gpkg"
+ if not boundary_gpkg.exists():
+ raise FileNotFoundError(f"HUC boundary not found: {boundary_gpkg}")
+ log.info(" C20: downloading USGS gages for HUC8 %s …", huc8)
+ gdf = DownloadUSGSGages(out_sr=5070, n_workers=8).download(
+ boundary=str(boundary_gpkg),
+ aoi_id=huc8,
+ out_dir=watershed,
+ out_name="usgs_gages.gpkg",
+ )
+ if gdf.empty:
+ raise RuntimeError(f"No USGS gages found for HUC8 {huc8}")
+ log.info(" C20 PASS: %d gages", len(gdf))
+ else:
+ log.info(" C20 SKIP (exists): usgs_gages.gpkg")
+
+ # ── C21: Assign to branches ──────────────────────────────────────
+ out_aoi = watershed / "usgs_subset_gages.gpkg"
+ out_bzero = watershed / "usgs_subset_gages_0.gpkg"
+ if not out_aoi.exists() or not out_bzero.exists():
+ levelpaths_gpkg = watershed / f"{IDENTIFIER}_subset_streams_levelPaths.gpkg"
+ if not levelpaths_gpkg.exists():
+ raise FileNotFoundError(f"Level-paths gpkg not found: {levelpaths_gpkg}")
+ log.info(" C21: assigning gages to branches …")
+ result = assign_gages_to_branches(
+ usgs_gages_gpkg=usgs_gages_gpkg,
+ nwm_streams_levelpaths_gpkg=levelpaths_gpkg,
+ aoi_id=huc8,
+ out_dir=watershed,
+ aoi_filter_column="aoi_id",
+ branch_zero_id="0",
+ )
+ if result is None:
+ raise RuntimeError("No gages could be assigned to branches")
+ log.info(" C21 PASS: %d gages assigned", len(result.aoi_gages))
+ else:
+ log.info(" C21 SKIP (exists): usgs_subset_gages.gpkg")
+
+ # ── C22: Per-branch crosswalk ────────────────────────────────────
+ aoi_gages_gdf = gpd.read_file(out_aoi)
+ gauged_bids = set(aoi_gages_gdf["levpa_id"].dropna().astype(str).unique()) | {"0"}
+ log.info(" C22: branches with gauges = %s", sorted(gauged_bids))
+
+ shared_dem = watershed / "dem.tif"
+ if not shared_dem.exists():
+ raise FileNotFoundError(f"Shared DEM not found: {shared_dem}")
+
+ for branch_dir in sorted(d for d in branches.iterdir() if d.is_dir()):
+ bid = branch_dir.name
+ if bid not in gauged_bids:
+ continue
+ out_table = branch_dir / "usgs_elev_table.csv"
+ if out_table.exists():
+ log.info(" C22 SKIP branch %s (exists)", bid)
+ continue
+ gages_gpkg = out_bzero if bid == "0" else out_aoi
+ catchments_gpkg = branch_dir / (
+ f"gw_catchments_reaches_filtered_addedAttributes_crosswalked_{bid}.gpkg"
+ )
+ flows_gpkg = branch_dir / (
+ f"demDerived_reaches_split_filtered_addedAttributes_crosswalked_{bid}.gpkg"
+ )
+ missing = [p for p in (catchments_gpkg, flows_gpkg) if not p.exists()]
+ if missing:
+ log.warning(" C22 SKIP branch %s — missing: %s", bid,
+ ", ".join(p.name for p in missing))
+ continue
+ branch_dem = branch_dir / f"dem_{bid}.tif"
+ dem_path = branch_dem if branch_dem.exists() else shared_dem
+ log.info(" C22: crosswalk branch %s (dem=%s) …", bid, dem_path.name)
+ try:
+ out = run_branch_crosswalk(
+ aoi_gages_gpkg=gages_gpkg,
+ branch_catchments_gpkg=catchments_gpkg,
+ branch_flows_gpkg=flows_gpkg,
+ dem_path=dem_path,
+ dem_thalweg_path=dem_path,
+ branch_id=bid,
+ out_dir=branch_dir,
+ )
+ written = [p for p in out.values() if p is not None]
+ log.info(" branch %s OK: %s", bid,
+ ", ".join(p.name for p in written) if written
+ else "no gages intersected catchments")
+ except Exception:
+ log.error(" branch %s FAIL:\n%s", bid, traceback.format_exc())
+
+ # ── CON: Consolidate ─────────────────────────────────────────────
+ frames = []
+ for branch_dir in sorted(d for d in branches.iterdir() if d.is_dir()):
+ t = branch_dir / "usgs_elev_table.csv"
+ if t.exists():
+ df = pd.read_csv(t, dtype={"location_id": str})
+ df["levpa_id"] = branch_dir.name
+ frames.append(df)
+ if frames:
+ out_path = aoi_root / "usgs_elev_table.csv"
+ consolidated = pd.concat(frames, ignore_index=True).drop_duplicates(
+ subset=["location_id", "HydroID"]
+ )
+ consolidated.to_csv(out_path, index=False)
+ log.info(" CON PASS: %d gage rows → usgs_elev_table.csv", len(consolidated))
+ else:
+ log.warning(" CON: no per-branch usgs_elev_table.csv found — no gauges in HUC?")
+
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ done = _load_done()
+ remaining = [h for h in hucs if h not in done]
+
+ log.info(f"Crosswalk: {len(hucs)} total | {len(done)} already done | {len(remaining)} to run")
+ log.info(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+
+ batch_start = time.time()
+ huc_times: list[tuple[str, float, str]] = []
+ passed, failed = list(done), []
+
+ for i, huc8 in enumerate(remaining, 1):
+ huc_start = time.time()
+ log.info(f" [{i}/{len(remaining)}] HUC8 = {huc8} | "
+ f"batch elapsed: {_fmt(huc_start - batch_start)}")
+ try:
+ run_huc(huc8)
+ elapsed = time.time() - huc_start
+ _log_result(huc8, "PASS")
+ passed.append(huc8)
+ huc_times.append((huc8, elapsed, "PASS"))
+ completed = [t for _, t, s in huc_times if s == "PASS"]
+ avg_s = sum(completed) / len(completed)
+ remaining_n = len(remaining) - i
+ eta_s = avg_s * remaining_n
+ log.info(f" [{huc8}] PASS | this HUC: {_fmt(elapsed)} | "
+ f"avg: {_fmt(avg_s)} | remaining: {remaining_n} | "
+ f"ETA: {_fmt(eta_s)}"
+ + (f" (~{datetime.fromtimestamp(time.time() + eta_s).strftime('%H:%M')})"
+ if remaining_n > 0 else " (last HUC)"))
+ except Exception:
+ elapsed = time.time() - huc_start
+ err = traceback.format_exc().splitlines()[-1]
+ _log_result(huc8, "FAIL", err)
+ failed.append(huc8)
+ huc_times.append((huc8, elapsed, "FAIL"))
+ log.error(f" [{huc8}] FAIL after {_fmt(elapsed)} | {err}")
+
+ total = time.time() - batch_start
+ log.info(f"\n{'─'*60}")
+ log.info(f"Crosswalk complete | total time: {_fmt(total)}")
+ log.info(f"Finished: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+ log.info(f"Passed: {len(passed)} | Failed: {len(failed)}")
+ if huc_times:
+ log.info(f"\nPer-HUC timing summary:")
+ for huc8, elapsed, status in huc_times:
+ log.info(f" {huc8} {status:4s} {_fmt(elapsed)}")
+ if failed:
+ log.warning(f"\nFailed HUCs: {failed}")
+ log.warning("Re-run this script to retry (FAIL lines are automatically retried).")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s05_calibrate_n_recurrence_all_hucs.py b/scripts/s05_calibrate_n_recurrence_all_hucs.py
new file mode 100644
index 0000000..625b647
--- /dev/null
+++ b/scripts/s05_calibrate_n_recurrence_all_hucs.py
@@ -0,0 +1,432 @@
+"""
+Manning's n calibration for all HUC8s using USGS rating curves at NWM recurrence stages.
+
+Concept
+-------
+For each gauged branch, NWM recurrence flows (2, 5, 10, 25, 50 yr) are interpolated
+through the USGS rating curve to HAND stage. Those 5 stage boundaries define 6 depth
+zones. Manning's n is back-calculated at each boundary:
+
+ n_r = A(h_r) · R(h_r)^(2/3) · √S / Q_r
+
+The calibrated n is then applied piecewise, recomputing discharge at every SRC stage row.
+All HydroIDs in a calibrated branch receive the same piecewise n structure.
+
+Scope
+-----
+Only non-trunk branches that have at least one USGS gauge with rating-curve data are
+processed. Branch 0 and ungauged branches are left unchanged.
+
+Prerequisite: s04_usgs_gage_crosswalk_all_hucs.py must have completed for each HUC
+(usgs_elev_table.csv must exist at the AOI root).
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s05_calibrate_n_recurrence_all_hucs.py
+"""
+from __future__ import annotations
+
+import logging
+import os
+import shutil
+import time
+import traceback
+from datetime import datetime
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+DATA_DIR = Path("data")
+TASK_LOG = Path("E:/SI/out/ncalib_status.txt")
+
+N_MIN = 0.010
+N_MAX = 0.300
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+RECUR_COLS = {yr: f"{yr}_0_year_recurrence_flow_17C" for yr in RECURRENCE_YEARS}
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+# ── Progress tracking ─────────────────────────────────────────────
+
+def _load_done() -> set[str]:
+ if not TASK_LOG.exists():
+ return set()
+ done = set()
+ for line in TASK_LOG.read_text().splitlines():
+ parts = line.strip().split()
+ if len(parts) >= 3 and parts[2] == "PASS":
+ done.add(parts[1])
+ return done
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"ncalib {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def _fmt(seconds: float) -> str:
+ seconds = int(seconds)
+ h, rem = divmod(seconds, 3600)
+ m, s = divmod(rem, 60)
+ if h:
+ return f"{h}h {m:02d}m {s:02d}s"
+ if m:
+ return f"{m}m {s:02d}s"
+ return f"{s}s"
+
+
+# ── Zone boundary calculation ─────────────────────────────────────
+
+def compute_zone_boundaries(
+ location_id: str,
+ feature_id: int,
+ dem_adj_m: float,
+ rc: pd.DataFrame,
+ recur: pd.DataFrame,
+) -> dict[int, tuple[float, float]] | None:
+ loc_padded = str(location_id).zfill(8)
+ gage_rc = rc[rc["location_id"] == loc_padded].copy()
+ if gage_rc.empty:
+ return None
+ gage_rc = gage_rc.sort_values("flow_cms").drop_duplicates("flow_cms")
+
+ feat_recur = recur[recur["feature_id"] == feature_id]
+ if feat_recur.empty:
+ return None
+
+ boundaries: dict[int, tuple[float, float]] = {}
+ for yr in RECURRENCE_YEARS:
+ Q_r = float(feat_recur[f"Q_{yr}yr_cms"].iloc[0])
+ if Q_r <= 0:
+ continue
+ if Q_r < gage_rc["flow_cms"].min() or Q_r > gage_rc["flow_cms"].max():
+ continue
+ elev_r = float(np.interp(Q_r, gage_rc["flow_cms"].values, gage_rc["elev_m"].values))
+ hand_r = elev_r - dem_adj_m
+ if hand_r <= 0:
+ log.debug(" gage %s yr=%d: HAND<0 (%.2fm) — skipping", location_id, yr, hand_r)
+ continue
+ boundaries[yr] = (hand_r, Q_r)
+
+ return boundaries if boundaries else None
+
+
+# ── Back-calculate n per zone ─────────────────────────────────────
+
+def calibrate_n_zones(
+ hydroid: int,
+ src: pd.DataFrame,
+ boundaries: dict[int, tuple[float, float]],
+) -> dict[int, float]:
+ hdf = src[src["HydroID"] == hydroid].sort_values("Stage")
+ if hdf.empty:
+ return {}
+ slope = float(hdf["SLOPE"].iloc[0])
+ if slope <= 0:
+ return {}
+
+ n_zones: dict[int, float] = {}
+ for yr, (h_r, Q_r) in sorted(boundaries.items()):
+ idx = (hdf["Stage"] - h_r).abs().idxmin()
+ row = hdf.loc[idx]
+ A = float(row.get("WetArea (m2)", 0.0))
+ R = float(row.get("HydraulicRadius (m)", 0.0))
+ if A <= 0 or R <= 0 or Q_r <= 0:
+ continue
+ n_r = A * (R ** (2.0 / 3.0)) * (slope ** 0.5) / Q_r
+ n_zones[yr] = float(np.clip(n_r, N_MIN, N_MAX))
+ log.debug(" HydroID %d yr=%d h=%.2fm Q=%.1f cms n=%.4f",
+ hydroid, yr, h_r, Q_r, n_zones[yr])
+
+ return n_zones
+
+
+# ── Apply piecewise n to a full SRC ──────────────────────────────
+
+def apply_n_zones_to_src(
+ src: pd.DataFrame,
+ hydroid: int,
+ boundaries: dict[int, tuple[float, float]],
+ n_zones: dict[int, float],
+) -> pd.DataFrame:
+ hdf = src[src["HydroID"] == hydroid].copy()
+ if hdf.empty or not n_zones:
+ return src
+ slope = float(hdf["SLOPE"].iloc[0])
+
+ sorted_zones = sorted(
+ ((h, n_zones[yr]) for yr, (h, _) in boundaries.items() if yr in n_zones),
+ key=lambda x: x[0],
+ )
+ if not sorted_zones:
+ return src
+
+ def _zone_n(stage_h: float) -> float:
+ for h_boundary, n_val in sorted_zones:
+ if stage_h <= h_boundary:
+ return n_val
+ return sorted_zones[-1][1]
+
+ rows_mask = src["HydroID"] == hydroid
+ new_q = []
+ for _, row in hdf.iterrows():
+ h = float(row["Stage"])
+ if h == 0.0:
+ new_q.append(0.0)
+ continue
+ A = float(row.get("WetArea (m2)", 0.0))
+ R = float(row.get("HydraulicRadius (m)", 0.0))
+ n = _zone_n(h)
+ if A <= 0 or R <= 0 or slope <= 0:
+ new_q.append(float(row.get("Discharge (m3s-1)", 0.0)))
+ else:
+ new_q.append(A * (R ** (2.0 / 3.0)) * (slope ** 0.5) / n)
+
+ src.loc[rows_mask, "Discharge (m3s-1)"] = new_q
+ src.loc[rows_mask, "zonal_n_applied"] = [_zone_n(float(h)) for h in hdf["Stage"]]
+ return src
+
+
+# ── Multi-gauge averaging ─────────────────────────────────────────
+
+def average_zones(
+ all_boundaries: list[dict[int, tuple[float, float]]],
+ all_n_zones: list[dict[int, float]],
+) -> tuple[dict[int, tuple[float, float]], dict[int, float]]:
+ avg_boundaries: dict[int, list] = {}
+ avg_n: dict[int, list] = {}
+ for bounds, n_zones in zip(all_boundaries, all_n_zones):
+ for yr, (h, _) in bounds.items():
+ avg_boundaries.setdefault(yr, []).append(h)
+ for yr, n in n_zones.items():
+ avg_n.setdefault(yr, []).append(n)
+ merged_bounds = {yr: (float(np.mean(hs)), 0.0) for yr, hs in avg_boundaries.items()}
+ merged_n = {yr: float(np.mean(ns)) for yr, ns in avg_n.items()}
+ return merged_bounds, merged_n
+
+
+# ── File I/O helpers ──────────────────────────────────────────────
+
+def _backup(path: Path) -> None:
+ backup = path.with_suffix(".pre_n_calib.csv")
+ if not backup.exists():
+ shutil.copy2(path, backup)
+
+
+def _safe_write_csv(df: pd.DataFrame, path: Path, bid: str) -> None:
+ tmp = path.with_suffix(".tmp.csv")
+ try:
+ df.to_csv(tmp, index=False)
+ os.replace(tmp, path)
+ except PermissionError as exc:
+ tmp.unlink(missing_ok=True)
+ raise PermissionError(
+ f"Branch {bid}: cannot write {path.name} — close it in any open application."
+ ) from exc
+
+
+def _sync_hydrotable(ht_path: Path, src: pd.DataFrame, bid: str) -> None:
+ _backup(ht_path)
+ ht = pd.read_csv(ht_path, low_memory=False)
+ pull = src[["HydroID", "Stage", "Discharge (m3s-1)"]].copy()
+ if "zonal_n_applied" in src.columns:
+ pull["zonal_n_applied"] = src["zonal_n_applied"]
+ pull = pull.rename(columns={"Stage": "stage", "Discharge (m3s-1)": "discharge_cms"})
+ ht["HydroID"] = ht["HydroID"].astype(int)
+ ht = ht.drop(columns=["discharge_cms", "zonal_n_applied"], errors="ignore")
+ ht = ht.merge(pull, on=["HydroID", "stage"], how="left")
+ ht["discharge_cms"] = ht["discharge_cms"].fillna(0.0)
+ ht.to_csv(ht_path, index=False)
+
+
+# ── Per-branch processing ─────────────────────────────────────────
+
+def process_branch(
+ bid: str,
+ branch_dir: Path,
+ elev: pd.DataFrame,
+ rc: pd.DataFrame,
+ recur: pd.DataFrame,
+) -> None:
+ src_path = branch_dir / f"src_full_crosswalked_{bid}.csv"
+ ht_path = branch_dir / f"hydroTable_{bid}.csv"
+
+ if not src_path.exists():
+ log.warning(" Branch %s: SRC not found — skip", bid)
+ return
+ if not ht_path.exists():
+ log.warning(" Branch %s: hydroTable not found — skip", bid)
+ return
+
+ src = pd.read_csv(src_path, dtype={"feature_id": str})
+ src["HydroID"] = src["HydroID"].astype(int)
+
+ branch_elev = elev[elev["levpa_id"].astype(str) == str(bid)]
+ log.info(" Branch %s: %d gauge row(s)", bid, len(branch_elev))
+
+ all_bounds_list: list[dict] = []
+ all_n_list: list[dict] = []
+ calibrated_hids: set[int] = set()
+
+ for _, gage in branch_elev.iterrows():
+ loc_id = str(gage["location_id"])
+ hydroid = int(gage["HydroID"])
+ feat_id = int(gage["feature_id"]) if pd.notna(gage["feature_id"]) else -1
+ dem_adj = float(gage["dem_adj_elevation"])
+
+ if feat_id < 0:
+ log.warning(" Gauge %s: no feature_id — skip", loc_id)
+ continue
+
+ bounds = compute_zone_boundaries(loc_id, feat_id, dem_adj, rc, recur)
+ if bounds is None:
+ log.warning(" Gauge %s: no zone boundaries — skip", loc_id)
+ continue
+
+ n_zones = calibrate_n_zones(hydroid, src, bounds)
+ if not n_zones:
+ log.warning(" Gauge %s HydroID %d: no valid n — skip", loc_id, hydroid)
+ continue
+
+ log.info(" Gauge %s HydroID %d: n = %s", loc_id, hydroid,
+ {yr: f"{n:.4f}" for yr, n in sorted(n_zones.items())})
+
+ src = apply_n_zones_to_src(src, hydroid, bounds, n_zones)
+ all_bounds_list.append(bounds)
+ all_n_list.append(n_zones)
+ calibrated_hids.add(hydroid)
+
+ if not all_bounds_list:
+ log.warning(" Branch %s: no valid gauge calibrations — SRC not modified", bid)
+ return
+
+ branch_bounds, branch_n = (
+ (all_bounds_list[0], all_n_list[0])
+ if len(all_bounds_list) == 1
+ else average_zones(all_bounds_list, all_n_list)
+ )
+
+ for hid in src["HydroID"].unique():
+ if hid not in calibrated_hids:
+ src = apply_n_zones_to_src(src, hid, branch_bounds, branch_n)
+
+ _backup(src_path)
+ _safe_write_csv(src, src_path, bid)
+ _sync_hydrotable(ht_path, src, bid)
+ log.info(" Branch %s: updated %d HydroIDs", bid, src["HydroID"].nunique())
+
+
+# ── Per-HUC entry point ───────────────────────────────────────────
+
+def run_huc(huc8: str, rc: pd.DataFrame, recur: pd.DataFrame) -> None:
+ aoi_root = OUT_DIR / f"HUC{huc8}"
+ branches = aoi_root / "watershed-data" / "branches"
+
+ elev_path = aoi_root / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ raise FileNotFoundError(
+ f"usgs_elev_table.csv not found — run s04 crosswalk first: {elev_path}"
+ )
+
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ log.info(" usgs_elev_table: %d rows", len(elev))
+
+ rc_ids = set(rc["location_id"].astype(str))
+ non_trunk = elev[elev["levpa_id"].astype(str) != "0"].copy()
+ non_trunk["has_rc"] = non_trunk["location_id"].apply(
+ lambda loc: str(loc).zfill(8) in rc_ids
+ )
+ directly_calibrated = set(non_trunk[non_trunk["has_rc"]]["levpa_id"].astype(str))
+
+ if not directly_calibrated:
+ log.info(" No directly calibrated branches for HUC %s — nothing to do", huc8)
+ return
+ log.info(" Calibrated branches: %s", sorted(directly_calibrated))
+
+ for branch_dir in sorted(d for d in branches.iterdir() if d.is_dir()):
+ bid = branch_dir.name
+ if bid in directly_calibrated:
+ process_branch(bid, branch_dir, elev, rc, recur)
+
+
+# ── Main ──────────────────────────────────────────────────────────
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ done = _load_done()
+ remaining = [h for h in hucs if h not in done]
+
+ log.info(f"n-Calibration: {len(hucs)} total | {len(done)} already done | {len(remaining)} to run")
+ log.info(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+
+ # Load shared tables once — identical for all HUCs
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["location_id"] = rc["location_id"].astype(str)
+ rc["flow_cms"] = rc["flow"].astype(float) / 35.3147
+ rc["elev_m"] = rc["elevation_navd88"].astype(float) / 3.28084
+ log.info(f"USGS rating curves: {len(rc)} rows, {rc['location_id'].nunique()} gauges")
+
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr, col in RECUR_COLS.items():
+ recur[f"Q_{yr}yr_cms"] = recur[col].astype(float) * 0.028317
+ recur["feature_id"] = recur["feature_id"].astype("Int64")
+ log.info(f"NWM recurrence flows: {len(recur)} feature_ids")
+
+ batch_start = time.time()
+ huc_times: list[tuple[str, float, str]] = []
+ passed, failed = list(done), []
+
+ for i, huc8 in enumerate(remaining, 1):
+ huc_start = time.time()
+ log.info(f" [{i}/{len(remaining)}] HUC8 = {huc8} | "
+ f"batch elapsed: {_fmt(huc_start - batch_start)}")
+ try:
+ run_huc(huc8, rc, recur)
+ elapsed = time.time() - huc_start
+ _log_result(huc8, "PASS")
+ passed.append(huc8)
+ huc_times.append((huc8, elapsed, "PASS"))
+ completed = [t for _, t, s in huc_times if s == "PASS"]
+ avg_s = sum(completed) / len(completed)
+ remaining_n = len(remaining) - i
+ eta_s = avg_s * remaining_n
+ log.info(f" [{huc8}] PASS | this HUC: {_fmt(elapsed)} | "
+ f"avg: {_fmt(avg_s)} | remaining: {remaining_n} | "
+ f"ETA: {_fmt(eta_s)}"
+ + (f" (~{datetime.fromtimestamp(time.time() + eta_s).strftime('%H:%M')})"
+ if remaining_n > 0 else " (last HUC)"))
+ except Exception:
+ elapsed = time.time() - huc_start
+ err = traceback.format_exc().splitlines()[-1]
+ _log_result(huc8, "FAIL", err)
+ failed.append(huc8)
+ huc_times.append((huc8, elapsed, "FAIL"))
+ log.error(f" [{huc8}] FAIL after {_fmt(elapsed)} | {err}")
+
+ total = time.time() - batch_start
+ log.info(f"\n{'─'*60}")
+ log.info(f"n-Calibration complete | total time: {_fmt(total)}")
+ log.info(f"Finished: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+ log.info(f"Passed: {len(passed)} | Failed: {len(failed)}")
+ if huc_times:
+ log.info(f"\nPer-HUC timing summary:")
+ for huc8, elapsed, status in huc_times:
+ log.info(f" {huc8} {status:4s} {_fmt(elapsed)}")
+ if failed:
+ log.warning(f"\nFailed HUCs: {failed}")
+ log.warning("Re-run this script to retry (FAIL lines are automatically retried).")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s05_ncalib_core.py b/scripts/s05_ncalib_core.py
new file mode 100644
index 0000000..bddcf91
--- /dev/null
+++ b/scripts/s05_ncalib_core.py
@@ -0,0 +1,740 @@
+"""
+Shared engine for zone-based Manning's n calibration — hydroTable edition.
+
+The hydroTable is the single source of truth: geometry (WetArea, HydraulicRadius,
+TopWidth, SLOPE) is READ from hydroTable_{bid}.csv and calibrated discharge +
+zonal_n_applied are WRITTEN back to it. src_full_crosswalked files are restored
+to baseline and no longer modified — the hydroTable is what FIM generation
+consumes, so calibration lives where the runtime looks.
+
+Four starting-point matching methods share this engine (see s05a–s05d):
+
+ A wedge_topwidth rectangular bathymetry wedge below HAND 0; depth δ from
+ the PZF power-law fit, width w0 from SRC TopWidth at the
+ lowest wet stages
+ B1 datum_shift no geometry change; the SRC is re-referenced to the RC
+ origin (anchors and applied discharge evaluated at h + δ)
+ B2 q0_offset no geometry change; observed baseflow Q0 added to the
+ SRC discharge (Garousi-Nejad et al. 2019)
+ B3 wedge_continuity wedge with depth δ from PZF and width solved from
+ hydraulic continuity so the excavated channel carries
+ exactly the observed baseflow:
+ w0 = Q0·n_ch / (δ^(5/3)·√S), n_ch = 0.05
+ capped to [1 m, TopWidth estimate]
+
+All methods share identical downstream machinery: n back-calculated at NWM
+recurrence anchors on smoothed conveyance, applied piecewise-constant per zone
+with ±1-row linear transitions, and a final cumulative-max monotone guarantee.
+
+Each method has its own status file (ncalib_status_{method}.txt); the per-gauge
+record goes to /ncalib_diagnostics.csv with a `method` column. Methods
+are mutually exclusive on disk — every run restores the hydroTable baseline
+first, so the diagnostics always describe the calibration currently applied.
+
+Run a method via its wrapper:
+ .venv\\Scripts\\python.exe scripts/s05d_calibrate_B3_wedge_continuity.py
+Justify the choice of method with:
+ .venv\\Scripts\\python.exe scripts/s05e_evaluate_methods.py
+"""
+from __future__ import annotations
+
+import logging
+import os
+import shutil
+import time
+import traceback
+from datetime import datetime
+from pathlib import Path
+
+import numpy as np
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+DATA_DIR = Path(__file__).resolve().parents[1] / "data" # repo-root data/, CWD-independent
+
+N_MIN = 0.010
+N_MAX = 0.300
+N_CH_CONTINUITY = 0.05 # assumed in-channel n for the continuity wedge width
+RECURRENCE_YEARS = [2, 5, 10, 25, 50]
+RECUR_COLS = {yr: f"{yr}_0_year_recurrence_flow_17C" for yr in RECURRENCE_YEARS}
+
+TRANS_W = 0.3048 # zone-boundary transition half-width (m; one row)
+
+# PZF power-law fit QC thresholds
+PZF_MIN_PTS = 6
+PZF_MAX_PTS = 12
+PZF_B_RANGE = (1.0, 5.0)
+PZF_MIN_R2 = 0.95
+PZF_DELTA_RNG = (0.05, 15.0)
+
+METHOD_LABELS = {
+ "A": "wedge_topwidth",
+ "B1": "datum_shift",
+ "B2": "q0_offset",
+ "B3": "wedge_continuity",
+}
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+# ══════════════════════════════════════════════════════════════════
+# Shared data loading
+# ══════════════════════════════════════════════════════════════════
+
+def load_shared() -> tuple[pd.DataFrame, pd.DataFrame]:
+ rc = pd.read_parquet(DATA_DIR / "usgs_rating_curves.parquet")
+ rc["location_id"] = rc["location_id"].astype(str)
+ rc["flow_cms"] = rc["flow"].astype(float) / 35.3147
+ rc["elev_m"] = rc["elevation_navd88"].astype(float) / 3.28084
+ recur = pd.read_parquet(DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet")
+ for yr, col in RECUR_COLS.items():
+ recur[f"Q_{yr}yr_cms"] = recur[col].astype(float) * 0.028317
+ recur["feature_id"] = recur["feature_id"].astype("Int64")
+ return rc, recur
+
+
+def study_hucs() -> list[str]:
+ df = pd.read_excel(EXCEL_PATH)
+ return [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+
+
+# ══════════════════════════════════════════════════════════════════
+# Starting-point observations: PZF fit and baseflow
+# ══════════════════════════════════════════════════════════════════
+
+def fit_pzf(gage_rc: pd.DataFrame, dem_adj_m: float) -> dict | None:
+ """
+ Fit Q = C·(elev − h0)^b to the lowest RC points via grid search on h0.
+ Returns datum gap δ = dem_adj − h0 and fit stats, or None on QC failure.
+ """
+ g = gage_rc.sort_values("elev_m").drop_duplicates("elev_m")
+ q = g["flow_cms"].to_numpy(float)
+ e = g["elev_m"].to_numpy(float)
+ pos = q > 0
+ q, e = q[pos], e[pos]
+ if len(q) < PZF_MIN_PTS:
+ return None
+
+ k = min(PZF_MAX_PTS, max(PZF_MIN_PTS, len(q) // 4))
+ q_lo, e_lo = q[:k], e[:k]
+ e_min = float(e_lo[0])
+
+ best = None # (r2, h0, b)
+ for h0 in np.linspace(e_min - 8.0, e_min - 0.02, 200):
+ x = np.log(e_lo - h0)
+ y = np.log(q_lo)
+ b, a = np.polyfit(x, y, 1)
+ if not (PZF_B_RANGE[0] <= b <= PZF_B_RANGE[1]):
+ continue
+ yhat = a + b * x
+ ss_res = float(((y - yhat) ** 2).sum())
+ ss_tot = float(((y - y.mean()) ** 2).sum())
+ r2 = 1.0 - ss_res / ss_tot if ss_tot > 0 else 0.0
+ if best is None or r2 > best[0]:
+ best = (r2, float(h0), float(b))
+
+ if best is None or best[0] < PZF_MIN_R2:
+ return None
+ r2, h0, b = best
+ delta = dem_adj_m - h0
+ if not (PZF_DELTA_RNG[0] <= delta <= PZF_DELTA_RNG[1]):
+ return None
+ return {"h0_elev_m": h0, "delta_m": delta, "b": b, "r2": r2}
+
+
+def baseflow_q0(gage_rc: pd.DataFrame, dem_adj_m: float) -> float:
+ """Observed flow at the DEM water-surface elevation."""
+ g = gage_rc.sort_values("elev_m").drop_duplicates("elev_m")
+ q = g["flow_cms"].to_numpy(float)
+ e = g["elev_m"].to_numpy(float)
+ if dem_adj_m <= e[0]:
+ return float(q[0])
+ return float(np.interp(dem_adj_m, e, q))
+
+
+# ══════════════════════════════════════════════════════════════════
+# Zone boundaries (anchors)
+# ══════════════════════════════════════════════════════════════════
+
+def compute_zone_boundaries(
+ location_id: str,
+ feature_id: int,
+ dem_adj_m: float,
+ rc: pd.DataFrame,
+ recur: pd.DataFrame,
+) -> dict[int, tuple[float, float]] | None:
+ loc_padded = str(location_id).zfill(8)
+ gage_rc = rc[rc["location_id"] == loc_padded].copy()
+ if gage_rc.empty:
+ return None
+ gage_rc = gage_rc.sort_values("flow_cms").drop_duplicates("flow_cms")
+
+ feat_recur = recur[recur["feature_id"] == feature_id]
+ if feat_recur.empty:
+ return None
+
+ boundaries: dict[int, tuple[float, float]] = {}
+ for yr in RECURRENCE_YEARS:
+ Q_r = float(feat_recur[f"Q_{yr}yr_cms"].iloc[0])
+ if Q_r <= 0:
+ continue
+ if Q_r < gage_rc["flow_cms"].min() or Q_r > gage_rc["flow_cms"].max():
+ continue
+ elev_r = float(np.interp(Q_r, gage_rc["flow_cms"].values, gage_rc["elev_m"].values))
+ hand_r = elev_r - dem_adj_m
+ if hand_r <= 0:
+ continue
+ boundaries[yr] = (hand_r, Q_r)
+
+ return boundaries if boundaries else None
+
+
+# ══════════════════════════════════════════════════════════════════
+# Geometry (hydroTable columns) + method parameterization
+# ══════════════════════════════════════════════════════════════════
+
+def build_geometry(hdf: pd.DataFrame, delta: float, w0: float
+ ) -> tuple[np.ndarray, np.ndarray]:
+ """
+ (stages, K_smooth) for one HydroID from hydroTable rows, stage-sorted.
+ Wedge (delta, w0) added below HAND 0 when both > 0:
+ A* = A + w0·δ, WP* = WP + 2δ (WP recovered as A/R)
+ K = A*·R*^(2/3), then rolling-median(3) + isotonic non-decreasing —
+ within-zone wiggles are raster artifacts, not hydraulics.
+ """
+ stages = hdf["stage"].to_numpy(float)
+ A = hdf["WetArea (m2)"].to_numpy(float)
+ R = hdf["HydraulicRadius (m)"].to_numpy(float)
+
+ with np.errstate(divide="ignore", invalid="ignore"):
+ WP = np.where(R > 0, A / R, 0.0)
+
+ if delta > 0 and w0 > 0:
+ A_adj = A + w0 * delta
+ WP_adj = np.where(WP > 0, WP + 2.0 * delta, w0 + 2.0 * delta)
+ R_adj = np.where(WP_adj > 0, A_adj / WP_adj, 0.0)
+ else:
+ A_adj, R_adj = A, R
+
+ K = A_adj * np.power(R_adj, 2.0 / 3.0, where=R_adj > 0,
+ out=np.zeros_like(R_adj))
+ K = pd.Series(K).rolling(3, center=True, min_periods=1).median().to_numpy()
+ K = np.maximum.accumulate(K)
+ return stages, K
+
+
+def wedge_width_topwidth(hdf: pd.DataFrame) -> float:
+ """Method-A width: median hydroTable TopWidth at the lowest wet stages."""
+ if "TopWidth (m)" in hdf.columns:
+ tw = hdf.loc[hdf["stage"] > 0, "TopWidth (m)"].to_numpy(float)
+ tw = tw[tw > 0]
+ if len(tw):
+ return float(np.median(tw[:3]))
+ wet = hdf[(hdf["stage"] > 0) & (hdf["WetArea (m2)"] > 0)]
+ if not wet.empty:
+ r = wet.iloc[0]
+ return float(r["WetArea (m2)"] / r["stage"])
+ return 0.0
+
+
+def wedge_width_continuity(Q0: float, delta: float, slope: float,
+ w0_cap: float) -> float:
+ """
+ Method-B3 width: size the wedge so the excavated rectangular channel
+ carries the observed baseflow at depth δ (wide-channel Manning):
+ Q0 = (1/n_ch)·(w0·δ)·δ^(2/3)·√S → w0 = Q0·n_ch / (δ^(5/3)·√S)
+ Capped to [1 m, TopWidth estimate] — the raster width is an upper bound.
+ """
+ if Q0 <= 0 or delta <= 0 or slope <= 0:
+ return 0.0
+ w0 = Q0 * N_CH_CONTINUITY / (delta ** (5.0 / 3.0) * slope ** 0.5)
+ return float(np.clip(w0, 1.0, max(w0_cap, 1.0)))
+
+
+def method_params(method: str, hdf: pd.DataFrame, slope: float,
+ pzf: dict | None, Q0: float) -> dict:
+ """
+ Resolve a method tag to concrete correction parameters.
+ Returns dict(mode, delta, w0, q_offset, shift).
+ Fallback for every method when its inputs are unavailable: q0_offset.
+ """
+ delta = pzf["delta_m"] if pzf else 0.0
+ w0_tw = wedge_width_topwidth(hdf)
+
+ if method == "A" and pzf and w0_tw > 0:
+ return dict(mode="wedge_topwidth", delta=delta, w0=w0_tw,
+ q_offset=0.0, shift=0.0)
+ if method == "B1" and pzf:
+ return dict(mode="datum_shift", delta=delta, w0=0.0,
+ q_offset=0.0, shift=delta)
+ if method == "B3" and pzf:
+ w0c = wedge_width_continuity(Q0, delta, slope, w0_tw)
+ if w0c > 0:
+ return dict(mode="wedge_continuity", delta=delta, w0=w0c,
+ q_offset=0.0, shift=0.0)
+ # B2 and all fallbacks
+ return dict(mode="q0_offset", delta=0.0, w0=0.0, q_offset=Q0, shift=0.0)
+
+
+# ══════════════════════════════════════════════════════════════════
+# Calibration math (shared by all methods)
+# ══════════════════════════════════════════════════════════════════
+
+def calibrate_n_zones(stages: np.ndarray, K: np.ndarray, slope: float,
+ boundaries: dict[int, tuple[float, float]],
+ q_offset: float, shift: float
+ ) -> tuple[dict[int, float], int, int]:
+ """
+ n_r = K(h_r + shift)·√S / (Q_r − q_offset), K interpolated to the exact
+ anchor stage. Returns (n per year, clipped_low, clipped_high).
+ """
+ n_zones: dict[int, float] = {}
+ clip_lo = clip_hi = 0
+ for yr, (h_r, Q_r) in sorted(boundaries.items()):
+ Q_eff = Q_r - q_offset
+ if Q_eff <= 0:
+ continue
+ K_r = float(np.interp(h_r + shift, stages, K))
+ if K_r <= 0 or slope <= 0:
+ continue
+ n_raw = K_r * (slope ** 0.5) / Q_eff
+ n_val = float(np.clip(n_raw, N_MIN, N_MAX))
+ clip_lo += int(n_raw < N_MIN)
+ clip_hi += int(n_raw > N_MAX)
+ n_zones[yr] = n_val
+ return n_zones, clip_lo, clip_hi
+
+
+# ══════════════════════════════════════════════════════════════════
+# INCREMENTAL (slice / divided-channel) scheme — alternative to the
+# whole-section scheme above. Each depth band keeps its own n and
+# discharge is the sum of slice contributions (Lotter composite):
+#
+# Q(h) = q_offset + √S · Σ_i [K(min(h,h_i)) − K(h_{i-1})] / n_i
+#
+# Rising water only ADDS conveyance with the new zone's n — the lower
+# flow is never re-rated — so Q(h) is continuous and monotone BY
+# CONSTRUCTION: no transition band, no cumulative-max guard needed.
+# n_i here means "roughness of the flow added between anchors i-1 and
+# i" (≈ true floodplain roughness for overbank zones), not the
+# effective whole-section value.
+# ══════════════════════════════════════════════════════════════════
+
+def calibrate_n_zones_incremental(
+ stages: np.ndarray, K: np.ndarray, slope: float,
+ boundaries: dict[int, tuple[float, float]], q_offset: float,
+) -> tuple[dict[int, float], int, int]:
+ """
+ Sequential back-calculation on conveyance/discharge INCREMENTS:
+ n_i = √S · (K_i − K_{i-1}) / (Q_i − Q_achieved_{i-1})
+ Uses the ACHIEVED cumulative discharge, so a clipped zone is
+ compensated by the zones above it. Returns (n per year, clip_lo, clip_hi).
+ """
+ n_zones: dict[int, float] = {}
+ clip_lo = clip_hi = 0
+ if slope <= 0:
+ return n_zones, 0, 0
+ rootS = slope ** 0.5
+ prev_K = 0.0
+ q_achieved = q_offset
+ for yr, (h_r, Q_r) in sorted(boundaries.items(), key=lambda kv: kv[1][0]):
+ K_r = float(np.interp(h_r, stages, K))
+ dK = K_r - prev_K
+ dQ = Q_r - q_achieved
+ if dK <= 0 or dQ <= 0:
+ continue # unusable increment — skip this anchor
+ n_raw = dK * rootS / dQ
+ n_val = float(np.clip(n_raw, N_MIN, N_MAX))
+ clip_lo += int(n_raw < N_MIN)
+ clip_hi += int(n_raw > N_MAX)
+ n_zones[yr] = n_val
+ q_achieved += dK * rootS / n_val
+ prev_K = K_r
+ return n_zones, clip_lo, clip_hi
+
+
+def discharge_incremental(
+ stages: np.ndarray, K: np.ndarray, slope: float,
+ boundaries: dict[int, tuple[float, float]],
+ n_zones: dict[int, float], q_offset: float,
+) -> tuple[np.ndarray, np.ndarray]:
+ """
+ Evaluate the slice-composite discharge on the stage grid.
+ Returns (q, n_applied) — n_applied is the zone n governing each row's
+ slice (constant per zone, no transitions).
+ """
+ items = sorted(((h, n_zones[yr]) for yr, (h, _) in boundaries.items()
+ if yr in n_zones), key=lambda x: x[0])
+ rootS = slope ** 0.5
+ if not items:
+ return np.zeros_like(stages), np.full_like(stages, np.nan)
+ h_b = np.array([h for h, _ in items])
+ n_b = np.array([n for _, n in items])
+ K_b = np.interp(h_b, stages, K)
+
+ # cumulative √S-scaled discharge at each slice top
+ dK = np.diff(np.concatenate([[0.0], K_b]))
+ q_at_tops = q_offset + rootS * np.cumsum(dK / n_b)
+
+ idx = np.searchsorted(h_b, stages) # slice index per row
+ idx_c = np.minimum(idx, len(items) - 1) # rows above last anchor use n_last
+ K_base = np.where(idx == 0, 0.0, K_b[np.maximum(idx - 1, 0)])
+ q_base = np.where(idx == 0, q_offset, q_at_tops[np.maximum(idx - 1, 0)])
+ q = q_base + rootS * (K - K_base) / n_b[idx_c]
+ return q, n_b[idx_c]
+
+
+def n_profile(stages: np.ndarray, boundaries: dict[int, tuple[float, float]],
+ n_zones: dict[int, float], shift: float = 0.0) -> np.ndarray:
+ """
+ n(h): constant within each zone, linear across ±TRANS_W at interior
+ boundaries (bands clamped so they never overlap). n_i applies to stages
+ ≤ h_i; above the last anchor n stays at n_last. `shift` moves the
+ boundaries for the datum-shift method.
+ """
+ items = sorted((h + shift, n_zones[yr])
+ for yr, (h, _) in boundaries.items() if yr in n_zones)
+ h_b = [h for h, _ in items]
+ n_b = [n for _, n in items]
+ m = len(items)
+ if m == 0:
+ return np.full_like(stages, np.nan)
+ if m == 1:
+ return np.full_like(stages, n_b[0])
+
+ xp: list[float] = []
+ fp: list[float] = []
+ for i in range(m - 1):
+ gap_lo = h_b[i] - (h_b[i - 1] if i > 0 else 0.0)
+ gap_hi = h_b[i + 1] - h_b[i]
+ w = max(min(TRANS_W, 0.4 * gap_lo, 0.4 * gap_hi), 1e-6)
+ xp += [h_b[i] - w, h_b[i] + w]
+ fp += [n_b[i], n_b[i + 1]]
+ return np.interp(stages, xp, fp)
+
+
+def _total_scheme_curve(stages: np.ndarray, K: np.ndarray, slope: float,
+ boundaries: dict[int, tuple[float, float]],
+ n_zones_total: dict[int, float], q_offset: float
+ ) -> tuple[np.ndarray, np.ndarray, int]:
+ """
+ Independently evaluate the TOTAL (whole-section) scheme's own curve:
+ n(h) constant per zone with ±TRANS_W transitions (n_profile), applied to
+ the WHOLE cross-section, then a cumulative-max monotone guard — the exact
+ method validated against "incremental" in s05e/s05f_evaluate_schemes.py.
+ This is a genuinely separate curve from the applied (incremental) one,
+ not a back-derivation from it. Returns (q_mono, n_arr, rows_fixed).
+ """
+ n_arr = n_profile(stages, boundaries, n_zones_total)
+ with np.errstate(divide="ignore", invalid="ignore"):
+ q = np.where(n_arr > 0, K * (slope ** 0.5) / n_arr, 0.0)
+ q = q + q_offset
+ q_mono = np.maximum.accumulate(q)
+ fixed = int((q_mono > q + 1e-9).sum())
+ return q_mono, n_arr, fixed
+
+
+def apply_to_hydroid(ht: pd.DataFrame, hydroid: int,
+ boundaries: dict[int, tuple[float, float]],
+ n_zones: dict[int, float], params: dict,
+ scheme: str = "incremental",
+ n_zones_total: dict[int, float] | None = None,
+ ) -> tuple[pd.DataFrame, int]:
+ """
+ Recompute discharge_cms for one HydroID under the chosen (applied) scheme,
+ AND independently compute the total-scheme curve for comparison/reporting.
+
+ incremental Q(h) = q_offset + √S·Σ slice contributions (continuous +
+ monotone by construction; n_zones are SLICE roughness) —
+ this is what's WRITTEN to discharge_cms (what FIM consumes).
+ total Q(h) = K(h)·√S / n(h) + q_offset with boundary transitions
+ + cumulative-max guard — a SEPARATE, independently
+ calibrated curve (n_zones_total), stored alongside for
+ comparison, never used by FIM generation.
+
+ Columns written:
+ discharge_cms the APPLIED scheme's curve (drives FIM)
+ zonal_n_applied the applied scheme's n per row (slice n)
+ discharge_cms_wholesection the total scheme's OWN curve (diagnostic only)
+ whole_section_n the total scheme's OWN n per row (matches
+ n_eff_{yr}yr in ncalib_diagnostics.csv)
+
+ Returns (ht, rows_fixed_by_monotone_guard) for the APPLIED scheme.
+ """
+ mask = ht["HydroID"] == hydroid
+ hdf = ht[mask].sort_values("stage")
+ slope = float(hdf["SLOPE"].iloc[0])
+ if slope <= 0 or not n_zones:
+ return ht, 0
+
+ stages, K = build_geometry(hdf, params["delta"], params["w0"])
+ qoff = params["q_offset"]
+
+ if scheme == "incremental":
+ q, n_arr = discharge_incremental(stages, K, slope, boundaries,
+ n_zones, qoff)
+ else:
+ shift = params["shift"]
+ stages_eval = stages + shift
+ K_eval = np.interp(stages_eval, stages, K) # flat beyond top row
+ n_arr = n_profile(stages_eval, boundaries, n_zones, shift=shift)
+ with np.errstate(divide="ignore", invalid="ignore"):
+ q = np.where(n_arr > 0, K_eval * (slope ** 0.5) / n_arr, 0.0)
+ q = q + qoff
+
+ q_mono = np.maximum.accumulate(q)
+ fixed = int((q_mono > q + 1e-9).sum())
+
+ order = hdf.index.to_numpy()
+ ht.loc[order, "discharge_cms"] = q_mono
+ ht.loc[order, "zonal_n_applied"] = n_arr
+
+ # Independent total-scheme curve — a genuine second curve, not a
+ # relabeling of the applied one. Skipped only if the applied scheme
+ # already IS total (nothing separate to compute) or n_zones_total is
+ # unavailable (e.g. total-scheme back-calc found no valid anchors).
+ if scheme != "total" and n_zones_total:
+ q_tot, n_tot_arr, _ = _total_scheme_curve(
+ stages, K, slope, boundaries, n_zones_total, qoff)
+ ht.loc[order, "discharge_cms_wholesection"] = q_tot
+ ht.loc[order, "whole_section_n"] = n_tot_arr
+ elif scheme == "total":
+ ht.loc[order, "discharge_cms_wholesection"] = q_mono
+ ht.loc[order, "whole_section_n"] = n_arr
+
+ return ht, fixed
+
+
+# ══════════════════════════════════════════════════════════════════
+# File I/O — hydroTable is the single write target
+# ══════════════════════════════════════════════════════════════════
+
+def _backup_or_restore(path: Path) -> None:
+ """First run: create .pre_n_calib backup. Rerun: restore from it."""
+ backup = path.with_suffix(".pre_n_calib.csv")
+ if backup.exists():
+ shutil.copy2(backup, path)
+ else:
+ shutil.copy2(path, backup)
+
+
+def _safe_write_csv(df: pd.DataFrame, path: Path, bid: str) -> None:
+ tmp = path.with_suffix(".tmp.csv")
+ try:
+ df.to_csv(tmp, index=False)
+ os.replace(tmp, path)
+ except PermissionError as exc:
+ tmp.unlink(missing_ok=True)
+ raise PermissionError(
+ f"Branch {bid}: cannot write {path.name} — close it in any open application."
+ ) from exc
+
+
+# ══════════════════════════════════════════════════════════════════
+# Per-branch / per-HUC / batch drivers
+# ══════════════════════════════════════════════════════════════════
+
+def process_branch(method: str, bid: str, branch_dir: Path,
+ elev: pd.DataFrame, rc: pd.DataFrame, recur: pd.DataFrame,
+ diagnostics: list[dict], huc8: str,
+ scheme: str = "incremental") -> None:
+ ht_path = branch_dir / f"hydroTable_{bid}.csv"
+ src_path = branch_dir / f"src_full_crosswalked_{bid}.csv"
+ if not ht_path.exists():
+ log.warning(" Branch %s: hydroTable not found — skip", bid)
+ return
+
+ # Restore baselines (idempotent). src_full is restored so it stays a
+ # clean baseline artifact, but it is never written again.
+ _backup_or_restore(ht_path)
+ if src_path.exists():
+ _backup_or_restore(src_path)
+
+ ht = pd.read_csv(ht_path, low_memory=False)
+ ht["HydroID"] = ht["HydroID"].astype(int)
+
+ branch_elev = elev[elev["levpa_id"].astype(str) == str(bid)]
+ log.info(" Branch %s: %d gauge row(s)", bid, len(branch_elev))
+
+ seen_hids: set[int] = set()
+ n_calibrated = 0
+
+ for _, gage in branch_elev.iterrows():
+ loc_id = str(gage["location_id"])
+ hydroid = int(gage["HydroID"])
+ feat_id = int(gage["feature_id"]) if pd.notna(gage["feature_id"]) else -1
+ dem_adj = float(gage["dem_adj_elevation"])
+
+ diag = {
+ "method": method, "scheme": scheme, "huc8": huc8, "branch": bid,
+ "hydroid": hydroid,
+ "location_id": loc_id.zfill(8), "feature_id": feat_id,
+ "mode": "none", "delta_m": np.nan, "h0_elev_m": np.nan,
+ "pzf_b": np.nan, "pzf_r2": np.nan, "w0_m": np.nan,
+ "q0_cms": np.nan, "n_clipped_low": 0, "n_clipped_high": 0,
+ "monotone_fixed_rows": 0, "status": "",
+ }
+ for yr in RECURRENCE_YEARS:
+ diag[f"n_{yr}yr"] = np.nan # applied scheme's n (slice n when incremental)
+ diag[f"n_eff_{yr}yr"] = np.nan # effective whole-section n (compatibility)
+
+ if feat_id < 0:
+ diag["status"] = "no_feature_id"; diagnostics.append(diag); continue
+ if hydroid in seen_hids:
+ diag["status"] = "hydroid_already_calibrated"; diagnostics.append(diag)
+ continue
+
+ gage_rc = rc[rc["location_id"] == loc_id.zfill(8)]
+ if gage_rc.empty:
+ diag["status"] = "no_rating_curve"; diagnostics.append(diag); continue
+
+ bounds = compute_zone_boundaries(loc_id, feat_id, dem_adj, rc, recur)
+ if bounds is None:
+ diag["status"] = "no_zone_boundaries"; diagnostics.append(diag); continue
+
+ hdf = ht[ht["HydroID"] == hydroid].sort_values("stage")
+ if hdf.empty:
+ diag["status"] = "hydroid_not_in_hydrotable"; diagnostics.append(diag)
+ continue
+ slope = float(hdf["SLOPE"].iloc[0])
+
+ pzf = fit_pzf(gage_rc, dem_adj)
+ Q0 = baseflow_q0(gage_rc, dem_adj)
+ params = method_params(method, hdf, slope, pzf, Q0)
+ diag.update(mode=params["mode"], delta_m=params["delta"],
+ w0_m=params["w0"], q0_cms=params["q_offset"])
+ if pzf and params["mode"] != "q0_offset":
+ diag.update(h0_elev_m=pzf["h0_elev_m"], pzf_b=pzf["b"],
+ pzf_r2=pzf["r2"])
+
+ stages, K = build_geometry(hdf, params["delta"], params["w0"])
+ if scheme == "incremental":
+ n_zones, clip_lo, clip_hi = calibrate_n_zones_incremental(
+ stages, K, slope, bounds, params["q_offset"])
+ else:
+ n_zones, clip_lo, clip_hi = calibrate_n_zones(
+ stages, K, slope, bounds, params["q_offset"], params["shift"])
+ if not n_zones:
+ diag["status"] = "no_valid_n"; diagnostics.append(diag)
+ log.warning(" Gauge %s HydroID %d: no valid n — skip", loc_id, hydroid)
+ continue
+
+ # Independent total-scheme (whole-section) back-calculation at the
+ # SAME anchors — computed BEFORE apply_to_hydroid so the hydroTable's
+ # discharge_cms_wholesection curve and this gauge's n_eff_{yr}yr are
+ # driven by the identical n_eff dict (no drift between the two).
+ n_eff, _, _ = calibrate_n_zones(
+ stages, K, slope, bounds, params["q_offset"], 0.0)
+
+ ht, fixed = apply_to_hydroid(ht, hydroid, bounds, n_zones, params,
+ scheme=scheme, n_zones_total=n_eff)
+
+ diag.update(n_clipped_low=clip_lo, n_clipped_high=clip_hi,
+ monotone_fixed_rows=fixed, status="calibrated")
+ for yr, n in n_zones.items():
+ diag[f"n_{yr}yr"] = round(n, 4)
+ for yr, n in n_eff.items():
+ diag[f"n_eff_{yr}yr"] = round(n, 4)
+ diagnostics.append(diag)
+ seen_hids.add(hydroid)
+ n_calibrated += 1
+
+ log.info(" Gauge %s HydroID %d [%s δ=%.2fm w0=%.1fm Q0=%.1f]: n = %s",
+ loc_id, hydroid, params["mode"], params["delta"],
+ params["w0"], params["q_offset"],
+ {yr: f"{n:.4f}" for yr, n in sorted(n_zones.items())})
+
+ if n_calibrated == 0:
+ log.warning(" Branch %s: no gauge calibrated — hydroTable left at baseline", bid)
+ return
+
+ _safe_write_csv(ht, ht_path, bid)
+ log.info(" Branch %s: calibrated %d gauged HydroID(s) in hydroTable", bid, n_calibrated)
+
+
+def run_huc(method: str, huc8: str, rc: pd.DataFrame, recur: pd.DataFrame,
+ scheme: str = "incremental") -> None:
+ aoi_root = OUT_DIR / f"HUC{huc8}"
+ branches = aoi_root / "watershed-data" / "branches"
+ elev_path = aoi_root / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ raise FileNotFoundError(
+ f"usgs_elev_table.csv not found — run s04 crosswalk first: {elev_path}")
+
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ rc_ids = set(rc["location_id"].astype(str))
+ non_trunk = elev[elev["levpa_id"].astype(str) != "0"].copy()
+ non_trunk["has_rc"] = non_trunk["location_id"].apply(
+ lambda loc: str(loc).zfill(8) in rc_ids)
+ gauged_branches = set(non_trunk[non_trunk["has_rc"]]["levpa_id"].astype(str))
+ if not gauged_branches:
+ log.info(" No gauged branches for HUC %s — nothing to do", huc8)
+ return
+
+ diagnostics: list[dict] = []
+ for branch_dir in sorted(d for d in branches.iterdir() if d.is_dir()):
+ if branch_dir.name in gauged_branches:
+ process_branch(method, branch_dir.name, branch_dir,
+ elev, rc, recur, diagnostics, huc8, scheme=scheme)
+
+ if diagnostics:
+ diag_path = aoi_root / "ncalib_diagnostics.csv"
+ pd.DataFrame(diagnostics).to_csv(diag_path, index=False)
+ n_ok = sum(1 for d in diagnostics if d["status"] == "calibrated")
+ log.info(" Diagnostics → %s (%d/%d gauges calibrated, method=%s, scheme=%s)",
+ diag_path.name, n_ok, len(diagnostics), method, scheme)
+
+
+def run_batch(method: str, scheme: str = "incremental") -> None:
+ """Run one calibration method across the whole study area.
+
+ scheme: "incremental" (slice composite — continuous/monotone by
+ construction, n = band roughness) or "total" (whole-section n with
+ boundary transitions). The status file is scheme-specific so switching
+ scheme forces a full rerun."""
+ if method not in METHOD_LABELS:
+ raise ValueError(f"unknown method {method!r} — one of {list(METHOD_LABELS)}")
+ if scheme not in ("incremental", "total"):
+ raise ValueError(f"unknown scheme {scheme!r}")
+ task_log = OUT_DIR / f"ncalib_status_{method}_{scheme}.txt"
+
+ def _done() -> set[str]:
+ if not task_log.exists():
+ return set()
+ return {p[1] for line in task_log.read_text().splitlines()
+ if len(p := line.strip().split()) >= 3 and p[2] == "PASS"}
+
+ hucs = study_hucs()
+ done = _done()
+ remaining = [h for h in hucs if h not in done]
+ log.info("n-Calibration method %s (%s) scheme=%s: %d total | %d done | %d to run",
+ method, METHOD_LABELS[method], scheme, len(hucs), len(done), len(remaining))
+
+ rc, recur = load_shared()
+ t0 = time.time()
+ failed = []
+ for i, huc8 in enumerate(remaining, 1):
+ t = time.time()
+ log.info(" [%d/%d] HUC8 = %s", i, len(remaining), huc8)
+ try:
+ run_huc(method, huc8, rc, recur, scheme=scheme)
+ with task_log.open("a") as f:
+ f.write(f"ncalib {huc8} PASS\n")
+ except Exception:
+ err = traceback.format_exc().splitlines()[-1]
+ with task_log.open("a") as f:
+ f.write(f"ncalib {huc8} FAIL {err}\n")
+ failed.append(huc8)
+ log.error(" [%s] FAIL | %s", huc8, err)
+ else:
+ log.info(" [%s] PASS | %.0fs", huc8, time.time() - t)
+
+ log.info("Method %s complete in %.0fs | failed: %s",
+ method, time.time() - t0, failed or "none")
diff --git a/scripts/s05a_calibrate_A_wedge_topwidth.py b/scripts/s05a_calibrate_A_wedge_topwidth.py
new file mode 100644
index 0000000..ba96e7c
--- /dev/null
+++ b/scripts/s05a_calibrate_A_wedge_topwidth.py
@@ -0,0 +1,16 @@
+"""
+Method A — bathymetry wedge with TopWidth-based width.
+
+Depth δ from the PZF power-law fit; width w0 = median hydroTable TopWidth at
+the lowest wet stages. Known weakness: in flat coastal terrain the lowest
+HAND increment spans floodplain, so w0 is often far wider than the channel and
+the wedge over-adds conveyance (n pins at N_MAX at ~35% of anchors — see
+s05e_evaluate_methods.py for the study-area comparison).
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s05a_calibrate_A_wedge_topwidth.py
+"""
+from s05_ncalib_core import run_batch
+
+if __name__ == "__main__":
+ run_batch("A")
diff --git a/scripts/s05b_calibrate_B1_datum_shift.py b/scripts/s05b_calibrate_B1_datum_shift.py
new file mode 100644
index 0000000..9412004
--- /dev/null
+++ b/scripts/s05b_calibrate_B1_datum_shift.py
@@ -0,0 +1,16 @@
+"""
+Method B1 — datum shift (no geometry modification).
+
+The SRC is re-referenced to the rating curve's origin: anchors and the applied
+discharge are evaluated at HAND stage h + δ, where δ is the PZF datum gap.
+Zero geometry parameters, but the SRC borrows floodplain-level widths for the
+submerged channel, which over-adds conveyance even more than method A
+(n pins at N_MAX at ~49% of anchors — see s05e_evaluate_methods.py).
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s05b_calibrate_B1_datum_shift.py
+"""
+from s05_ncalib_core import run_batch
+
+if __name__ == "__main__":
+ run_batch("B1")
diff --git a/scripts/s05c_calibrate_B2_q0_offset.py b/scripts/s05c_calibrate_B2_q0_offset.py
new file mode 100644
index 0000000..a222fbc
--- /dev/null
+++ b/scripts/s05c_calibrate_B2_q0_offset.py
@@ -0,0 +1,17 @@
+"""
+Method B2 — baseflow offset (no geometry modification).
+
+The observed baseflow at the DEM water-surface elevation (Q0, from the rating
+curve) is added to the SRC discharge: Q(h) = K(h)·√S/n(h) + Q0
+(Garousi-Nejad et al. 2019, WRR). Simple and robust — this is also the
+automatic fallback of every other method when the PZF fit fails QC — but it
+leaves the submerged-channel conveyance deficit in the geometry, so n absorbs
+it (~10% of anchors pin at N_MIN; see s05e_evaluate_methods.py).
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s05c_calibrate_B2_q0_offset.py
+"""
+from s05_ncalib_core import run_batch
+
+if __name__ == "__main__":
+ run_batch("B2")
diff --git a/scripts/s05d_calibrate_B3_wedge_continuity.py b/scripts/s05d_calibrate_B3_wedge_continuity.py
new file mode 100644
index 0000000..ef4d213
--- /dev/null
+++ b/scripts/s05d_calibrate_B3_wedge_continuity.py
@@ -0,0 +1,21 @@
+"""
+Method B3 — bathymetry wedge with hydraulic-continuity width. ** CHOSEN **
+
+Depth δ from the PZF power-law fit; width solved from Manning's equation so
+the excavated rectangular channel carries exactly the observed baseflow:
+
+ w0 = Q0 · n_ch / (δ^(5/3) · √S), n_ch = 0.05, capped by TopWidth
+
+Both origin observations (δ from the PZF fit, Q0 from the rating curve) are
+honored simultaneously, so the SRC starts at the observed baseflow by
+construction. Study-area evaluation (s05e_evaluate_methods.py): lowest bound
+saturation (9.4% at N_MAX / 2.6% at N_MIN), median calibrated n = 0.060, 76%
+of n within the 0.02–0.20 literature range, origin ratio 0.99.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s05d_calibrate_B3_wedge_continuity.py
+"""
+from s05_ncalib_core import run_batch
+
+if __name__ == "__main__":
+ run_batch("B3")
diff --git a/scripts/s05e_evaluate_methods.py b/scripts/s05e_evaluate_methods.py
new file mode 100644
index 0000000..bb525b1
--- /dev/null
+++ b/scripts/s05e_evaluate_methods.py
@@ -0,0 +1,290 @@
+"""
+Starting-point method evaluation — the justification for choosing B3.
+
+Runs all four calibration methods (A, B1, B2, B3 — see s05_ncalib_core.py)
+OFFLINE against identical inputs at every PZF-fittable gauge. Nothing on disk
+is modified: baseline geometry is read from the hydroTable .pre_n_calib backup
+(or the current file where no backup exists).
+
+Decision criteria
+-----------------
+All methods fix the curve fit about equally (n absorbs whatever the geometry
+correction gets wrong), so curve fit alone cannot pick a winner. The methods
+are scored on whether the calibrated n stays PHYSICAL — which is what the
+research hypothesis tests and what the future ML model trains on:
+
+ 1. bound saturation % of n pinned at N_MIN / N_MAX (pinned = the anchor
+ was NOT honored and the label is censored)
+ 2. literature range % of n within 0.02–0.20 (Chow 1959 natural channels)
+ 3. hold-out error median |error| at observed RC points BETWEEN anchors
+ (never used in calibration — a true split sample)
+ 4. origin match median Q_src(origin) / Q_obs(baseflow) — 1.0 is perfect
+
+Outputs → E:/SI/out/calibration_analysis/method_evaluation/
+ method_comparison.csv the full table
+ method_comparison.png the figure
+ and a printed verdict.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s05e_evaluate_methods.py
+"""
+from __future__ import annotations
+
+import logging
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+
+import s05_ncalib_core as core
+
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans", "font.size": 10.5,
+ "axes.titlesize": 11.5, "axes.titleweight": "bold",
+ "axes.spines.top": False, "axes.spines.right": False,
+ "axes.grid": True, "grid.alpha": 0.20, "grid.linestyle": ":",
+ "figure.dpi": 150,
+})
+
+EVAL_DIR = core.OUT_DIR / "calibration_analysis" / "method_evaluation"
+METHODS = ["A", "B1", "B2", "B3"]
+M_LABEL = {"A": "A · wedge (TopWidth w0)", "B1": "B1 · datum shift",
+ "B2": "B2 · Q0 offset", "B3": "B3 · wedge (continuity w0)"}
+M_CLR = {"A": "#7f8c8d", "B1": "#b0632e", "B2": "#2471a3", "B3": "#187E86"}
+ANCHOR_EXCL = 0.35
+LIT_RANGE = (0.02, 0.20)
+
+log = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+
+
+def _baseline_ht(branch_dir: Path, bid: str) -> pd.DataFrame | None:
+ """Baseline hydroTable — prefer the .pre_n_calib backup (pre-calibration)."""
+ p = branch_dir / f"hydroTable_{bid}.pre_n_calib.csv"
+ if not p.exists():
+ p = branch_dir / f"hydroTable_{bid}.csv"
+ if not p.exists():
+ return None
+ ht = pd.read_csv(p, low_memory=False)
+ ht["HydroID"] = ht["HydroID"].astype(int)
+ return ht
+
+
+def evaluate_gauge(method: str, hdf: pd.DataFrame, slope: float,
+ bounds: dict, pzf: dict | None, Q0: float,
+ grc_hand: list[tuple[float, float]]) -> dict | None:
+ """One method at one gauge: n values, clip counts, holdout errs, origin ratio."""
+ params = core.method_params(method, hdf, slope, pzf, Q0)
+ stages, K = core.build_geometry(hdf, params["delta"], params["w0"])
+ n_zones, clip_lo, clip_hi = core.calibrate_n_zones(
+ stages, K, slope, bounds, params["q_offset"], params["shift"])
+ if not n_zones:
+ return None
+
+ shift = params["shift"]
+ stages_eval = stages + shift
+ K_eval = np.interp(stages_eval, stages, K)
+ n_arr = core.n_profile(stages_eval, bounds, n_zones, shift=shift)
+ with np.errstate(divide="ignore", invalid="ignore"):
+ q = np.where(n_arr > 0, K_eval * (slope ** 0.5) / n_arr, 0.0)
+ q = np.maximum.accumulate(q + params["q_offset"])
+
+ ah = np.sort([h for h, _ in bounds.values()])
+ ho = []
+ for h_obs, q_obs in grc_hand:
+ if not (ah.min() < h_obs < ah.max()) or q_obs <= 0:
+ continue
+ if np.abs(ah - h_obs).min() < ANCHOR_EXCL:
+ continue
+ # evaluate the applied curve at the observed stage (already includes shift)
+ ho.append(100 * (float(np.interp(h_obs, stages, q)) - q_obs) / q_obs)
+
+ ratio = float(np.interp(0.0, stages, q)) / Q0 if Q0 > 0 else np.nan
+ return {"n_vals": list(n_zones.values()), "clip_lo": clip_lo,
+ "clip_hi": clip_hi, "holdout": ho, "ratio": ratio,
+ "mode": params["mode"]}
+
+
+def main():
+ EVAL_DIR.mkdir(parents=True, exist_ok=True)
+ rc, recur = core.load_shared()
+ hucs = core.study_hucs()
+
+ agg = {m: {"n": [], "lo": 0, "hi": 0, "ho": [], "ratio": []} for m in METHODS}
+ ho_orig_all = []
+ n_gauges = 0
+
+ for huc8 in hucs:
+ aoi = core.OUT_DIR / f"HUC{huc8}"
+ elev_path = aoi / "usgs_elev_table.csv"
+ if not elev_path.exists():
+ continue
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ elev["location_id"] = elev["location_id"].str.zfill(8)
+ rc_ids = set(rc["location_id"])
+
+ branches = aoi / "watershed-data" / "branches"
+ if not branches.exists():
+ continue
+ non_trunk = elev[elev["levpa_id"].astype(str) != "0"]
+ gauged_bids = set(
+ non_trunk[non_trunk["location_id"].isin(rc_ids)]["levpa_id"].astype(str))
+
+ for bid in sorted(gauged_bids):
+ bdir = branches / bid
+ ht = _baseline_ht(bdir, bid)
+ if ht is None:
+ continue
+ seen = set()
+ for _, gage in elev[elev["levpa_id"].astype(str) == bid].iterrows():
+ loc = str(gage["location_id"]).zfill(8)
+ if loc not in rc_ids or pd.isna(gage["feature_id"]):
+ continue
+ hydroid = int(gage["HydroID"])
+ if hydroid in seen:
+ continue
+ dem = float(gage["dem_adj_elevation"])
+ gage_rc = rc[rc["location_id"] == loc]
+ bounds = core.compute_zone_boundaries(
+ loc, int(gage["feature_id"]), dem, rc, recur)
+ if not bounds:
+ continue
+ hdf = ht[ht["HydroID"] == hydroid].sort_values("stage")
+ if hdf.empty:
+ continue
+ slope = float(hdf["SLOPE"].iloc[0])
+ if slope <= 0:
+ continue
+ pzf = core.fit_pzf(gage_rc, dem)
+ if pzf is None:
+ continue # compare methods only where all four apply
+ Q0 = core.baseflow_q0(gage_rc, dem)
+ grc = gage_rc.sort_values("flow_cms").drop_duplicates("flow_cms")
+ grc_hand = list(zip((grc["elev_m"] - dem).astype(float),
+ grc["flow_cms"].astype(float)))
+
+ # baseline (original SRC) holdout error, once per gauge
+ ah = np.sort([h for h, _ in bounds.values()])
+ st0 = hdf["stage"].to_numpy(float)
+ q0_curve = hdf["discharge_cms"].to_numpy(float)
+ for h_obs, q_obs in grc_hand:
+ if (ah.min() < h_obs < ah.max()) and q_obs > 0 \
+ and np.abs(ah - h_obs).min() >= ANCHOR_EXCL:
+ ho_orig_all.append(
+ 100 * (float(np.interp(h_obs, st0, q0_curve)) - q_obs) / q_obs)
+
+ ok = False
+ for m in METHODS:
+ out = evaluate_gauge(m, hdf, slope, bounds, pzf, Q0, grc_hand)
+ if out is None:
+ continue
+ a = agg[m]
+ a["n"] += out["n_vals"]
+ a["lo"] += out["clip_lo"]
+ a["hi"] += out["clip_hi"]
+ a["ho"] += out["holdout"]
+ if np.isfinite(out["ratio"]):
+ a["ratio"].append(out["ratio"])
+ ok = True
+ if ok:
+ seen.add(hydroid)
+ n_gauges += 1
+
+ # ── Table ─────────────────────────────────────────────────────
+ rows = []
+ for m in METHODS:
+ a = agg[m]
+ nv = np.array(a["n"]); ho = np.array(a["ho"])
+ rows.append({
+ "method": m, "label": M_LABEL[m],
+ "anchors": len(nv),
+ "pinned_at_NMAX_pct": round(100 * a["hi"] / max(len(nv), 1), 1),
+ "pinned_at_NMIN_pct": round(100 * a["lo"] / max(len(nv), 1), 1),
+ "median_n": round(float(np.median(nv)), 3),
+ "n_in_lit_range_pct": round(
+ 100 * ((nv >= LIT_RANGE[0]) & (nv <= LIT_RANGE[1])).mean(), 1),
+ "holdout_median_err_pct": round(float(np.median(ho)), 1),
+ "holdout_median_abs_err_pct": round(float(np.median(np.abs(ho))), 1),
+ "origin_ratio_median": round(float(np.median(a["ratio"])), 2),
+ })
+ table = pd.DataFrame(rows)
+ ho_o = np.array(ho_orig_all)
+ log.info("Gauges compared: %d | holdout points: %d | "
+ "ORIGINAL SRC median |err| %.1f%%",
+ n_gauges, len(agg["A"]["ho"]), np.median(np.abs(ho_o)))
+ print("\n" + table.to_string(index=False))
+
+ table.to_csv(EVAL_DIR / "method_comparison.csv", index=False)
+
+ # ── Figure ────────────────────────────────────────────────────
+ fig, axes = plt.subplots(1, 3, figsize=(15, 4.8), constrained_layout=True)
+ x = np.arange(len(METHODS))
+ clrs = [M_CLR[m] for m in METHODS]
+ short = [m for m in METHODS]
+
+ ax = axes[0]
+ ax.bar(x - 0.18, table["pinned_at_NMAX_pct"], 0.34, color=clrs, alpha=0.9,
+ label="at N_MAX")
+ ax.bar(x + 0.18, table["pinned_at_NMIN_pct"], 0.34, color=clrs, alpha=0.45,
+ label="at N_MIN")
+ for xi, (h, l) in enumerate(zip(table["pinned_at_NMAX_pct"],
+ table["pinned_at_NMIN_pct"])):
+ ax.text(xi - 0.18, h, f"{h:.0f}", ha="center", va="bottom", fontsize=9)
+ ax.text(xi + 0.18, l, f"{l:.0f}", ha="center", va="bottom", fontsize=9)
+ ax.set_xticks(x); ax.set_xticklabels(short)
+ ax.set_ylabel("% of n pinned at a bound")
+ ax.set_title("Bound saturation — lower is better\n(pinned n = censored label)")
+ ax.legend(fontsize=9)
+
+ ax = axes[1]
+ ax.bar(x, table["n_in_lit_range_pct"], 0.5, color=clrs, alpha=0.9)
+ for xi, v in enumerate(table["n_in_lit_range_pct"]):
+ ax.text(xi, v, f"{v:.0f}%", ha="center", va="bottom", fontsize=9.5)
+ ax.set_xticks(x); ax.set_xticklabels(short)
+ ax.set_ylabel("% of n in 0.02–0.20")
+ ax.set_title("Physical plausibility of calibrated n\n(Chow 1959 natural-channel range)")
+
+ ax = axes[2]
+ ax.bar(x - 0.18, table["holdout_median_abs_err_pct"], 0.34, color=clrs,
+ alpha=0.9, label="hold-out median |err| %")
+ ax.bar(x + 0.18, (table["origin_ratio_median"] - 1).abs() * 100, 0.34,
+ color=clrs, alpha=0.45, label="|origin ratio − 1| ×100")
+ for xi, v in enumerate(table["holdout_median_abs_err_pct"]):
+ ax.text(xi - 0.18, v, f"{v:.0f}", ha="center", va="bottom", fontsize=9)
+ ax.set_xticks(x); ax.set_xticklabels(short)
+ ax.set_title("Accuracy — hold-out fit and origin match\n(lower is better for both)")
+ ax.legend(fontsize=9)
+
+ fig.suptitle("Starting-point method evaluation — "
+ f"{n_gauges} gauges, identical anchors and machinery",
+ fontweight="bold")
+ fig.savefig(EVAL_DIR / "method_comparison.png", dpi=150,
+ bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+
+ # ── Verdict ───────────────────────────────────────────────────
+ best = table.sort_values(
+ ["pinned_at_NMAX_pct", "n_in_lit_range_pct"],
+ ascending=[True, False]).iloc[0]
+ print(f"""
+VERDICT
+-------
+All methods reduce the hold-out error from {np.median(np.abs(ho_o)):.0f}% (original SRC)
+to {table['holdout_median_abs_err_pct'].min():.0f}-{table['holdout_median_abs_err_pct'].max():.0f}% — curve fit alone cannot discriminate, because n absorbs
+whatever the geometry correction gets wrong. The discriminator is whether n
+stays PHYSICAL (uncensored labels for the hypothesis test and the ML stage):
+
+ chosen method: {best['method']} ({best['label']})
+ bound saturation {best['pinned_at_NMAX_pct']}% / {best['pinned_at_NMIN_pct']}% | median n {best['median_n']} |
+ {best['n_in_lit_range_pct']}% in literature range | origin ratio {best['origin_ratio_median']}
+
+Outputs: {EVAL_DIR}
+""")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s05f_evaluate_schemes.py b/scripts/s05f_evaluate_schemes.py
new file mode 100644
index 0000000..1d207cb
--- /dev/null
+++ b/scripts/s05f_evaluate_schemes.py
@@ -0,0 +1,304 @@
+"""
+Application-scheme evaluation: whole-section ("total") vs slice-composite
+("incremental") piecewise-constant n — both under method B3.
+
+OFFLINE — reads baseline hydroTable .pre_n_calib backups, writes NOTHING to
+the pipeline outputs. All results go to a separate folder:
+
+ E:/SI/out/calibration_analysis/scheme_evaluation/
+ scheme_comparison.csv summary metrics per scheme
+ per_gauge_schemes.csv per-gauge detail (n per zone, both schemes)
+ scheme_comparison.png pinning / hold-out / smoothness bars
+ n_semantics.png median n per zone — the interpretation shift
+ example_curves/*.png per-gauge overlays: observed RC + baseline +
+ total-scheme + incremental-scheme curves
+
+The two schemes
+---------------
+total n_i = √S·K(h_i)/Q_i applied to the WHOLE section within zone i
+ (± transition band + cumulative-max guard). n_i = effective
+ whole-section roughness at the anchor stage.
+incremental n_i = √S·ΔK_i/ΔQ_i applied to the depth SLICE between anchors
+ (Lotter/divided-channel composite). Continuous + monotone by
+ construction; n_i = roughness of the flow added in that band.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/s05f_evaluate_schemes.py
+"""
+from __future__ import annotations
+
+import logging
+from pathlib import Path
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+
+import s05_ncalib_core as core
+
+mpl.rcParams.update({
+ "font.family": "DejaVu Sans", "font.size": 10.5,
+ "axes.titlesize": 11.5, "axes.titleweight": "bold",
+ "axes.spines.top": False, "axes.spines.right": False,
+ "axes.grid": True, "grid.alpha": 0.20, "grid.linestyle": ":",
+ "figure.dpi": 150,
+})
+
+EVAL_DIR = core.OUT_DIR / "calibration_analysis" / "scheme_evaluation"
+RY = core.RECURRENCE_YEARS
+ANCHOR_EXCL = 0.35
+C_TOT, C_INC, C_OBS, C_BASE = "#7f8c8d", "#187E86", "#111111", "#2471a3"
+
+log = logging.getLogger(__name__)
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+
+
+def curve_total(stages, K, slope, bounds, n_zones, q_offset):
+ """Replicates the batch 'total' application: transitions + cummax."""
+ n_arr = core.n_profile(stages, bounds, n_zones)
+ with np.errstate(divide="ignore", invalid="ignore"):
+ q = np.where(n_arr > 0, K * (slope ** 0.5) / n_arr, 0.0) + q_offset
+ return np.maximum.accumulate(q), n_arr
+
+
+def smoothness(stages, q, bounds):
+ """(shelf_rows, max_jump_ratio) within the anchor span."""
+ ah = np.sort([h for h, _ in bounds.values()])
+ m = (stages >= ah.min()) & (stages <= ah.max() + 0.62)
+ qs = q[m]
+ if len(qs) < 3:
+ return 0, 1.0
+ dq = np.diff(qs)
+ shelves = int((dq <= 1e-9).sum())
+ pos = qs[:-1] > 0
+ ratio = float((qs[1:][pos] / qs[:-1][pos]).max()) if pos.any() else 1.0
+ return shelves, ratio
+
+
+def main():
+ EVAL_DIR.mkdir(parents=True, exist_ok=True)
+ (EVAL_DIR / "example_curves").mkdir(exist_ok=True)
+ rc, recur = core.load_shared()
+
+ agg = {s: {"n": [], "lo": 0, "hi": 0, "ho": [], "shelf": [], "jump": [],
+ "resid": []} for s in ("total", "incremental")}
+ per_zone = {s: {yr: [] for yr in RY} for s in ("total", "incremental")}
+ gauge_rows, examples = [], []
+ n_gauges = 0
+
+ for huc8 in core.study_hucs():
+ aoi = core.OUT_DIR / f"HUC{huc8}"
+ elev_path = aoi / "usgs_elev_table.csv"
+ branches = aoi / "watershed-data" / "branches"
+ if not elev_path.exists() or not branches.exists():
+ continue
+ elev = pd.read_csv(elev_path, dtype={"location_id": str, "feature_id": "Int64"})
+ elev["location_id"] = elev["location_id"].str.zfill(8)
+ rc_ids = set(rc["location_id"])
+ non_trunk = elev[elev["levpa_id"].astype(str) != "0"]
+ gauged_bids = set(
+ non_trunk[non_trunk["location_id"].isin(rc_ids)]["levpa_id"].astype(str))
+
+ for bid in sorted(gauged_bids):
+ bk = branches / bid / f"hydroTable_{bid}.pre_n_calib.csv"
+ if not bk.exists():
+ bk = branches / bid / f"hydroTable_{bid}.csv"
+ if not bk.exists():
+ continue
+ ht = pd.read_csv(bk, low_memory=False)
+ ht["HydroID"] = ht["HydroID"].astype(int)
+ seen = set()
+ for _, gage in elev[elev["levpa_id"].astype(str) == bid].iterrows():
+ loc = str(gage["location_id"]).zfill(8)
+ if loc not in rc_ids or pd.isna(gage["feature_id"]):
+ continue
+ hydroid = int(gage["HydroID"])
+ if hydroid in seen:
+ continue
+ dem = float(gage["dem_adj_elevation"])
+ gage_rc = rc[rc["location_id"] == loc]
+ bounds = core.compute_zone_boundaries(
+ loc, int(gage["feature_id"]), dem, rc, recur)
+ if not bounds or len(bounds) < 2:
+ continue
+ hdf = ht[ht["HydroID"] == hydroid].sort_values("stage")
+ if hdf.empty:
+ continue
+ slope = float(hdf["SLOPE"].iloc[0])
+ if slope <= 0:
+ continue
+ pzf = core.fit_pzf(gage_rc, dem)
+ if pzf is None:
+ continue
+ Q0 = core.baseflow_q0(gage_rc, dem)
+ params = core.method_params("B3", hdf, slope, pzf, Q0)
+ stages, K = core.build_geometry(hdf, params["delta"], params["w0"])
+ qoff = params["q_offset"]
+
+ nz_t, lo_t, hi_t = core.calibrate_n_zones(
+ stages, K, slope, bounds, qoff, 0.0)
+ nz_i, lo_i, hi_i = core.calibrate_n_zones_incremental(
+ stages, K, slope, bounds, qoff)
+ if not nz_t or not nz_i:
+ continue
+ q_t, _ = curve_total(stages, K, slope, bounds, nz_t, qoff)
+ q_i, _ = core.discharge_incremental(
+ stages, K, slope, bounds, nz_i, qoff)
+
+ grc = gage_rc.sort_values("flow_cms").drop_duplicates("flow_cms")
+ hand = (grc["elev_m"] - dem).to_numpy(float)
+ qobs = grc["flow_cms"].to_numpy(float)
+ ah = np.sort([h for h, _ in bounds.values()])
+
+ row = {"huc8": huc8, "location_id": loc, "hydroid": hydroid}
+ for tag, nz, lo, hi, q in (
+ ("total", nz_t, lo_t, hi_t, q_t),
+ ("incremental", nz_i, lo_i, hi_i, q_i)):
+ a = agg[tag]
+ a["n"] += list(nz.values())
+ a["lo"] += lo
+ a["hi"] += hi
+ for yr, n in nz.items():
+ per_zone[tag][yr].append(n)
+ row[f"n_{yr}yr_{tag[:3]}"] = round(n, 4)
+ sh, jp = smoothness(stages, q, bounds)
+ a["shelf"].append(sh)
+ a["jump"].append(jp)
+ for h_o, q_o in zip(hand, qobs):
+ if not (ah.min() < h_o < ah.max()) or q_o <= 0:
+ continue
+ if np.abs(ah - h_o).min() < ANCHOR_EXCL:
+ continue
+ a["ho"].append(
+ 100 * (float(np.interp(h_o, stages, q)) - q_o) / q_o)
+ for yr, (h_r, Q_r) in bounds.items():
+ a["resid"].append(
+ 100 * (float(np.interp(h_r, stages, q)) - Q_r) / Q_r)
+ gauge_rows.append(row)
+ seen.add(hydroid)
+ n_gauges += 1
+ sh_t, _ = smoothness(stages, q_t, bounds)
+ examples.append((sh_t, huc8, loc, hydroid, stages, q_t, q_i,
+ hdf["discharge_cms"].to_numpy(float),
+ hand, qobs, bounds))
+
+ # ── summary table ─────────────────────────────────────────────
+ rows = []
+ for s in ("total", "incremental"):
+ a = agg[s]
+ nv = np.array(a["n"]); ho = np.array(a["ho"]); rs = np.array(a["resid"])
+ rows.append({
+ "scheme": s, "anchors": len(nv),
+ "pinned_NMAX_pct": round(100 * a["hi"] / max(len(nv), 1), 1),
+ "pinned_NMIN_pct": round(100 * a["lo"] / max(len(nv), 1), 1),
+ "median_n": round(float(np.median(nv)), 3),
+ "n_in_lit_pct": round(100 * ((nv >= 0.02) & (nv <= 0.20)).mean(), 1),
+ "holdout_med_err_pct": round(float(np.median(ho)), 1),
+ "holdout_med_abs_err_pct": round(float(np.median(np.abs(ho))), 1),
+ "anchor_med_abs_resid_pct": round(float(np.median(np.abs(rs))), 2),
+ "gauges_with_shelves_pct": round(
+ 100 * (np.array(a["shelf"]) > 0).mean(), 1),
+ "median_shelf_rows": int(np.median(a["shelf"])),
+ "p90_max_jump_ratio": round(float(np.percentile(a["jump"], 90)), 2),
+ })
+ table = pd.DataFrame(rows)
+ print("\n" + table.to_string(index=False))
+ table.to_csv(EVAL_DIR / "scheme_comparison.csv", index=False)
+ pd.DataFrame(gauge_rows).to_csv(EVAL_DIR / "per_gauge_schemes.csv", index=False)
+
+ # ── figure 1: bars ────────────────────────────────────────────
+ fig, axes = plt.subplots(1, 3, figsize=(15, 4.8), constrained_layout=True)
+ x = np.arange(2); labels = ["total\n(whole-section)", "incremental\n(slice)"]
+ clrs = [C_TOT, C_INC]
+
+ ax = axes[0]
+ ax.bar(x - 0.18, table["pinned_NMAX_pct"], 0.34, color=clrs, alpha=0.9, label="at N_MAX")
+ ax.bar(x + 0.18, table["pinned_NMIN_pct"], 0.34, color=clrs, alpha=0.45, label="at N_MIN")
+ for xi in x:
+ ax.text(xi - 0.18, table["pinned_NMAX_pct"][xi], f"{table['pinned_NMAX_pct'][xi]:.0f}",
+ ha="center", va="bottom", fontsize=9.5)
+ ax.set_xticks(x); ax.set_xticklabels(labels)
+ ax.set_ylabel("% of n pinned at a bound"); ax.legend(fontsize=9)
+ ax.set_title("Bound saturation")
+
+ ax = axes[1]
+ ax.bar(x - 0.18, table["holdout_med_abs_err_pct"], 0.34, color=clrs, alpha=0.9,
+ label="hold-out median |err| %")
+ ax.bar(x + 0.18, table["anchor_med_abs_resid_pct"], 0.34, color=clrs, alpha=0.45,
+ label="anchor median |resid| %")
+ for xi in x:
+ ax.text(xi - 0.18, table["holdout_med_abs_err_pct"][xi],
+ f"{table['holdout_med_abs_err_pct'][xi]:.0f}", ha="center", va="bottom", fontsize=9.5)
+ ax.set_xticks(x); ax.set_xticklabels(labels); ax.legend(fontsize=9)
+ ax.set_title("Accuracy (lower = better)")
+
+ ax = axes[2]
+ ax.bar(x - 0.18, table["gauges_with_shelves_pct"], 0.34, color=clrs, alpha=0.9,
+ label="% gauges with flat shelves")
+ ax.bar(x + 0.18, (table["p90_max_jump_ratio"] - 1) * 100, 0.34, color=clrs, alpha=0.45,
+ label="p90 max row-jump (ratio−1)×100")
+ for xi in x:
+ ax.text(xi - 0.18, table["gauges_with_shelves_pct"][xi],
+ f"{table['gauges_with_shelves_pct'][xi]:.0f}", ha="center", va="bottom", fontsize=9.5)
+ ax.set_xticks(x); ax.set_xticklabels(labels); ax.legend(fontsize=9)
+ ax.set_title("Smoothness — shelves & jumps (lower = better)")
+
+ fig.suptitle(f"Application-scheme comparison under method B3 — {n_gauges} gauges",
+ fontweight="bold")
+ fig.savefig(EVAL_DIR / "scheme_comparison.png", dpi=150,
+ bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+
+ # ── figure 2: n semantics per zone ────────────────────────────
+ fig, ax = plt.subplots(figsize=(9, 5.4), constrained_layout=True)
+ xz = np.arange(len(RY))
+ for s, clr, mk in (("total", C_TOT, "o"), ("incremental", C_INC, "s")):
+ med = [np.median(per_zone[s][yr]) if per_zone[s][yr] else np.nan for yr in RY]
+ ax.plot(xz, med, color=clr, lw=2.6, marker=mk, ms=8,
+ label=f"{s} — median n per zone")
+ ax.axhline(0.06, color=C_BASE, ls="--", lw=1.3, label="OWP default 0.06")
+ ax.set_xticks(xz); ax.set_xticklabels([f"{yr}-yr" for yr in RY])
+ ax.set_ylabel("Median calibrated n")
+ ax.set_title("What n MEANS differs between schemes\n"
+ "total = effective whole-section n at the anchor; "
+ "incremental = roughness of the flow added in that depth band")
+ ax.legend()
+ fig.savefig(EVAL_DIR / "n_semantics.png", dpi=150,
+ bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+
+ # ── figure 3: example curves (worst-shelf gauges + a smooth one) ──
+ examples.sort(key=lambda e: -e[0])
+ picks = examples[:3] + [examples[-1]]
+ for sh_t, huc8, loc, hydroid, stages, q_t, q_i, q_b, hand, qobs, bounds in picks:
+ fig, ax = plt.subplots(figsize=(9.5, 6.2), constrained_layout=True)
+ h_max = max(h for h, _ in bounds.values()) * 1.5
+ q_max = max(Q for _, Q in bounds.values()) * 1.7
+ ok = hand > 0
+ ax.plot(qobs[ok], hand[ok], color=C_OBS, lw=2.0, label="USGS observed RC", zorder=5)
+ ax.plot(q_b, stages, color=C_BASE, lw=1.5, label="Baseline SRC (n = 0.06)", zorder=3)
+ ax.plot(q_t, stages, color=C_TOT, lw=2.2, label="total scheme (shelves possible)", zorder=4)
+ ax.plot(q_i, stages, color=C_INC, lw=2.6, ls="--",
+ label="incremental scheme (smooth by construction)", zorder=6)
+ for yr, (h_r, Q_r) in sorted(bounds.items()):
+ ax.scatter([Q_r], [h_r], s=50, color="#c0392b", edgecolors="white",
+ linewidths=1.3, zorder=8)
+ ax.annotate(f"{yr}-yr", (Q_r, h_r), textcoords="offset points",
+ xytext=(7, -3), fontsize=8.5, color="#c0392b", fontweight="bold")
+ ax.set_xlim(0, q_max); ax.set_ylim(0, h_max)
+ ax.set_xlabel("Discharge (m³/s)"); ax.set_ylabel("HAND stage (m)")
+ ax.set_title(f"Gauge {loc} · HydroID {hydroid} · HUC {huc8} "
+ f"({sh_t} shelf rows under total scheme)")
+ ax.legend(loc="lower right", fontsize=9)
+ fig.savefig(EVAL_DIR / "example_curves" / f"{huc8}_{loc}.png",
+ dpi=140, bbox_inches="tight", facecolor="white")
+ plt.close(fig)
+
+ log.info("Done → %s (%d gauges compared)", EVAL_DIR, n_gauges)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s06_stage3_all_hucs.py b/scripts/s06_stage3_all_hucs.py
new file mode 100644
index 0000000..8915566
--- /dev/null
+++ b/scripts/s06_stage3_all_hucs.py
@@ -0,0 +1,140 @@
+"""
+Stage 3 — Feature ID extraction + NWM retrospective streamflow for all HUC8s.
+
+Step 3a: extract_feature_ids → out//feature_id.csv
+Step 3b: getNWMretrospective → out//discharge-inputs/.csv
+
+Prerequisite: run_stage2_hand.py must have completed for a HUC.
+
+Progress is written to TASK_LOG after each HUC so a re-run skips completed ones.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/run_stage3_streamflow.py
+"""
+import logging
+import time
+import traceback
+from datetime import datetime
+from pathlib import Path
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+
+# NWM retrospective event — edit to your flood event of interest
+# Use "date" for a single instant, or set START + END for a continuous range.
+EVENT_DATE = "2020-10-10 21:00:00" # single event
+# START = "2016-10-05" # uncomment for range
+# END = "2016-10-20"
+
+TASK_LOG = Path("E:/SI/out/stage3_status.txt")
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _load_done() -> set[str]:
+ if not TASK_LOG.exists():
+ return set()
+ done = set()
+ for line in TASK_LOG.read_text().splitlines():
+ parts = line.strip().split()
+ if len(parts) >= 3 and parts[2] == "PASS":
+ done.add(parts[1])
+ return done
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage3 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def run_huc(huc8: str) -> None:
+ from fimbox import extract_feature_ids, getNWMretrospective
+
+ aoi_root = OUT_DIR / f"HUC{huc8}"
+ if not aoi_root.exists():
+ raise FileNotFoundError(f"AOI folder not found — run Stage 1 first: {aoi_root}")
+
+ # Step 3a: collect NWM feature IDs from all branch hydroTables
+ extract_feature_ids(aoi_root)
+
+ # Step 3b: pull NWM v3 retrospective streamflow for the event
+ getNWMretrospective(aoi_root, date=EVENT_DATE)
+ # For a date range, replace the line above with:
+ # getNWMretrospective(aoi_root, start=START, end=END)
+
+
+def _fmt(seconds: float) -> str:
+ seconds = int(seconds)
+ h, rem = divmod(seconds, 3600)
+ m, s = divmod(rem, 60)
+ if h:
+ return f"{h}h {m:02d}m {s:02d}s"
+ if m:
+ return f"{m}m {s:02d}s"
+ return f"{s}s"
+
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ done = _load_done()
+ remaining = [h for h in hucs if h not in done]
+
+ log.info(f"Stage 3: {len(hucs)} total | {len(done)} already done | {len(remaining)} to run")
+ log.info(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+
+ batch_start = time.time()
+ huc_times: list[tuple[str, float, str]] = []
+ passed, failed = list(done), []
+
+ for i, huc8 in enumerate(remaining, 1):
+ huc_start = time.time()
+ log.info(f" [{i}/{len(remaining)}] HUC8 = {huc8} | "
+ f"batch elapsed: {_fmt(huc_start - batch_start)}")
+ try:
+ run_huc(huc8)
+ elapsed = time.time() - huc_start
+ _log_result(huc8, "PASS")
+ passed.append(huc8)
+ huc_times.append((huc8, elapsed, "PASS"))
+ completed = [t for _, t, s in huc_times if s == "PASS"]
+ avg_s = sum(completed) / len(completed)
+ remaining_n = len(remaining) - i
+ eta_s = avg_s * remaining_n
+ log.info(f" [{huc8}] PASS | this HUC: {_fmt(elapsed)} | "
+ f"avg: {_fmt(avg_s)} | remaining: {remaining_n} | "
+ f"ETA: {_fmt(eta_s)}"
+ + (f" (~{datetime.fromtimestamp(time.time() + eta_s).strftime('%H:%M')})"
+ if remaining_n > 0 else " (last HUC)"))
+ except Exception:
+ elapsed = time.time() - huc_start
+ err = traceback.format_exc().splitlines()[-1]
+ _log_result(huc8, "FAIL", err)
+ failed.append(huc8)
+ huc_times.append((huc8, elapsed, "FAIL"))
+ log.error(f" [{huc8}] FAIL after {_fmt(elapsed)} | {err}")
+
+ total = time.time() - batch_start
+ log.info(f"\n{'─'*60}")
+ log.info(f"Stage 3 complete | total time: {_fmt(total)}")
+ log.info(f"Finished: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+ log.info(f"Passed: {len(passed)} | Failed: {len(failed)}")
+ if huc_times:
+ log.info(f"\nPer-HUC timing summary:")
+ for huc8, elapsed, status in huc_times:
+ log.info(f" {huc8} {status:4s} {_fmt(elapsed)}")
+ if failed:
+ log.warning(f"\nFailed HUCs: {failed}")
+ log.warning("Re-run this script to retry (FAIL lines are automatically retried).")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s07_stage4_all_hucs.py b/scripts/s07_stage4_all_hucs.py
new file mode 100644
index 0000000..66dc81e
--- /dev/null
+++ b/scripts/s07_stage4_all_hucs.py
@@ -0,0 +1,185 @@
+"""
+Stage 4 — Synthetic Rating Curve calibration for all HUC8s.
+
+Applies bankfull identification, channel/overbank subdivision, and USGS
+rating-curve calibration to the per-branch hydroTables produced by Stage 2.
+
+Prerequisite: run_stage2_hand.py must have completed for a HUC.
+
+Progress is written to TASK_LOG after each HUC so a re-run skips completed ones.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/run_stage4_calibration.py
+"""
+import logging
+import time
+import traceback
+from datetime import datetime
+from pathlib import Path
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+DATA_DIR = Path("data") # calibration tables shipped in the repo
+TASK_LOG = Path("E:/SI/out/stage4_status.txt")
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _load_done() -> set[str]:
+ if not TASK_LOG.exists():
+ return set()
+ done = set()
+ for line in TASK_LOG.read_text().splitlines():
+ parts = line.strip().split()
+ if len(parts) >= 3 and parts[2] == "PASS":
+ done.add(parts[1])
+ return done
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage4 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def run_huc(huc8: str) -> None:
+ from fimbox import run_calibration, CalibrationConfig
+ from fimbox._dask import _resolve_n_workers
+
+ aoi_root = OUT_DIR / f"HUC{huc8}"
+ if not aoi_root.exists():
+ raise FileNotFoundError(f"AOI folder not found — run Stage 1 first: {aoi_root}")
+
+ cfg = CalibrationConfig(
+ # reset — revert to uncalibrated baseline on re-runs
+ calibration_rerun=True,
+
+ # aggregate_pre — assemble usgs/ras2fim elev tables before adjustments
+ aggregate_pre=True,
+
+ # thalweg — remove thalweg-notch artifact rows, refill stage ladder
+ thalweg_notches_adjustment=True,
+
+ # longitudinal — smooth hydraulic geometry along reach chains
+ longitudinal_filter=True,
+
+ # bathymetry — add missing in-channel area below DEM (self-skips if no overlap)
+ bathymetry_adjust=True,
+ bathy_file_ehydro=DATA_DIR / "final_bathymetry_ehydro_ohrfc.gpkg",
+
+ # bankfull — identify bankfull stage in every branch SRC
+ src_bankfull_toggle=True,
+ bankfull_flows_file=DATA_DIR / "nwm3_high_water_threshold_cms.parquet",
+ include_branch_zero=True,
+
+ # subdiv — channel/overbank subdivision (needs vmann + bankfull on)
+ src_subdiv_toggle=True,
+ vmann_input_file=DATA_DIR / "mannings_global_optz.parquet",
+ default_channel_n=0.06,
+ default_overbank_n=0.12,
+
+ # nonmonotonic — force monotonic in-channel rating curves
+ nonmonotonic_src_adjustment=True,
+ nonmonotonic_stream_order_min=4,
+
+ # usgs — calibrate SRCs against USGS rating curves at NWM recurrence flows
+ src_adjust_usgs=True,
+ usgs_rating_curve_csv=DATA_DIR / "usgs_rating_curves.parquet",
+ usgs_acceptable_gages=DATA_DIR / "acceptable_sites_for_rating_curves.parquet",
+ nwm_recur_file=DATA_DIR / "nwm3_17C_recurrence_flows_cfs.parquet",
+
+ # spatial — self-skips when calib_points_file=None (no benchmark points yet)
+ src_adjust_spatial=True,
+ calib_points_file=None,
+
+ # manual — self-skips when man_calb_file=None
+ manual_calb_toggle=True,
+ man_calb_file=None,
+
+ # aggregate_post — publish htable + bridge + road to AOI root
+ aggregate_post=True,
+
+ # log scan — collect error/warning lines into per-AOI summary files
+ scan_logs=True,
+
+ # execution
+ job_branch_limit=_resolve_n_workers(),
+ skip_unimplemented=True,
+ )
+ run_calibration(aoi_root, cfg)
+
+
+def _fmt(seconds: float) -> str:
+ seconds = int(seconds)
+ h, rem = divmod(seconds, 3600)
+ m, s = divmod(rem, 60)
+ if h:
+ return f"{h}h {m:02d}m {s:02d}s"
+ if m:
+ return f"{m}m {s:02d}s"
+ return f"{s}s"
+
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ done = _load_done()
+ remaining = [h for h in hucs if h not in done]
+
+ log.info(f"Stage 4: {len(hucs)} total | {len(done)} already done | {len(remaining)} to run")
+ log.info(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+
+ batch_start = time.time()
+ huc_times: list[tuple[str, float, str]] = []
+ passed, failed = list(done), []
+
+ for i, huc8 in enumerate(remaining, 1):
+ huc_start = time.time()
+ log.info(f" [{i}/{len(remaining)}] HUC8 = {huc8} | "
+ f"batch elapsed: {_fmt(huc_start - batch_start)}")
+ try:
+ run_huc(huc8)
+ elapsed = time.time() - huc_start
+ _log_result(huc8, "PASS")
+ passed.append(huc8)
+ huc_times.append((huc8, elapsed, "PASS"))
+ completed = [t for _, t, s in huc_times if s == "PASS"]
+ avg_s = sum(completed) / len(completed)
+ remaining_n = len(remaining) - i
+ eta_s = avg_s * remaining_n
+ log.info(f" [{huc8}] PASS | this HUC: {_fmt(elapsed)} | "
+ f"avg: {_fmt(avg_s)} | remaining: {remaining_n} | "
+ f"ETA: {_fmt(eta_s)}"
+ + (f" (~{datetime.fromtimestamp(time.time() + eta_s).strftime('%H:%M')})"
+ if remaining_n > 0 else " (last HUC)"))
+ except Exception:
+ elapsed = time.time() - huc_start
+ err = traceback.format_exc().splitlines()[-1]
+ _log_result(huc8, "FAIL", err)
+ failed.append(huc8)
+ huc_times.append((huc8, elapsed, "FAIL"))
+ log.error(f" [{huc8}] FAIL after {_fmt(elapsed)} | {err}")
+
+ total = time.time() - batch_start
+ log.info(f"\n{'─'*60}")
+ log.info(f"Stage 4 complete | total time: {_fmt(total)}")
+ log.info(f"Finished: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+ log.info(f"Passed: {len(passed)} | Failed: {len(failed)}")
+ if huc_times:
+ log.info(f"\nPer-HUC timing summary:")
+ for huc8, elapsed, status in huc_times:
+ log.info(f" {huc8} {status:4s} {_fmt(elapsed)}")
+ if failed:
+ log.warning(f"\nFailed HUCs: {failed}")
+ log.warning("Re-run this script to retry (FAIL lines are automatically retried).")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/scripts/s08_stage5_all_hucs.py b/scripts/s08_stage5_all_hucs.py
new file mode 100644
index 0000000..aba93c3
--- /dev/null
+++ b/scripts/s08_stage5_all_hucs.py
@@ -0,0 +1,139 @@
+"""
+Stage 5 — FIM Generation for all HUC8s in the study area.
+
+Generates inundation extent + depth rasters for every discharge CSV
+found in out//discharge-inputs/.
+
+Prerequisite: run_stage3_streamflow.py must have completed for a HUC
+(discharge CSVs must exist before this script runs).
+
+Progress is written to TASK_LOG after each HUC so a re-run skips completed ones.
+
+Run:
+ .venv\\Scripts\\python.exe scripts/run_stage5_fim.py
+"""
+import logging
+import time
+import traceback
+from datetime import datetime
+from pathlib import Path
+import pandas as pd
+
+# ── CONFIG ────────────────────────────────────────────────────────
+EXCEL_PATH = Path(r"C:\Users\Ali\OneDrive - CUNY\Desktop\SI\fimbox_SI26\data\study_area.xlsx")
+HUC_CODE_COL = "HUC_CODE"
+OUT_DIR = Path("E:/SI/out")
+TASK_LOG = Path("E:/SI/out/stage5_status.txt")
+# ─────────────────────────────────────────────────────────────────
+
+logging.basicConfig(level=logging.INFO,
+ format="%(asctime)s [%(levelname)s] %(message)s",
+ datefmt="%H:%M:%S")
+log = logging.getLogger(__name__)
+
+
+def _load_done() -> set[str]:
+ if not TASK_LOG.exists():
+ return set()
+ done = set()
+ for line in TASK_LOG.read_text().splitlines():
+ parts = line.strip().split()
+ if len(parts) >= 3 and parts[2] == "PASS":
+ done.add(parts[1])
+ return done
+
+
+def _log_result(huc8: str, status: str, note: str = "") -> None:
+ TASK_LOG.parent.mkdir(parents=True, exist_ok=True)
+ with TASK_LOG.open("a") as f:
+ f.write(f"stage5 {huc8} {status}{(' ' + note) if note else ''}\n")
+
+
+def run_huc(huc8: str) -> None:
+ from fimbox import generateFIM
+ from fimbox._dask import _resolve_n_workers
+
+ aoi_root = OUT_DIR / f"HUC{huc8}"
+ discharge_dir = aoi_root / "discharge-inputs"
+
+ if not aoi_root.exists():
+ raise FileNotFoundError(f"AOI folder not found — run Stage 1 first: {aoi_root}")
+ if not discharge_dir.exists() or not list(discharge_dir.glob("*.csv")):
+ raise FileNotFoundError(
+ f"No discharge CSVs found — run Stage 3 (streamflow) first: {discharge_dir}"
+ )
+
+ results = generateFIM(
+ aoi_root, n_workers=_resolve_n_workers(), depth=True
+ ).from_discharge_inputs()
+
+ log.info(f" [{huc8}] {len(results)} FIM raster(s) written to {aoi_root / 'fim-outputs'}")
+
+
+def _fmt(seconds: float) -> str:
+ seconds = int(seconds)
+ h, rem = divmod(seconds, 3600)
+ m, s = divmod(rem, 60)
+ if h:
+ return f"{h}h {m:02d}m {s:02d}s"
+ if m:
+ return f"{m}m {s:02d}s"
+ return f"{s}s"
+
+
+def main():
+ df = pd.read_excel(EXCEL_PATH)
+ hucs = [str(int(c)).zfill(8) for c in df[HUC_CODE_COL]]
+ done = _load_done()
+ remaining = [h for h in hucs if h not in done]
+
+ log.info(f"Stage 5: {len(hucs)} total | {len(done)} already done | {len(remaining)} to run")
+ log.info(f"Started: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+
+ batch_start = time.time()
+ huc_times: list[tuple[str, float, str]] = []
+ passed, failed = list(done), []
+
+ for i, huc8 in enumerate(remaining, 1):
+ huc_start = time.time()
+ log.info(f" [{i}/{len(remaining)}] HUC8 = {huc8} | "
+ f"batch elapsed: {_fmt(huc_start - batch_start)}")
+ try:
+ run_huc(huc8)
+ elapsed = time.time() - huc_start
+ _log_result(huc8, "PASS")
+ passed.append(huc8)
+ huc_times.append((huc8, elapsed, "PASS"))
+ completed = [t for _, t, s in huc_times if s == "PASS"]
+ avg_s = sum(completed) / len(completed)
+ remaining_n = len(remaining) - i
+ eta_s = avg_s * remaining_n
+ log.info(f" [{huc8}] PASS | this HUC: {_fmt(elapsed)} | "
+ f"avg: {_fmt(avg_s)} | remaining: {remaining_n} | "
+ f"ETA: {_fmt(eta_s)}"
+ + (f" (~{datetime.fromtimestamp(time.time() + eta_s).strftime('%H:%M')})"
+ if remaining_n > 0 else " (last HUC)"))
+ except Exception:
+ elapsed = time.time() - huc_start
+ err = traceback.format_exc().splitlines()[-1]
+ _log_result(huc8, "FAIL", err)
+ failed.append(huc8)
+ huc_times.append((huc8, elapsed, "FAIL"))
+ log.error(f" [{huc8}] FAIL after {_fmt(elapsed)} | {err}")
+
+ total = time.time() - batch_start
+ log.info(f"\n{'─'*60}")
+ log.info(f"Stage 5 complete | total time: {_fmt(total)}")
+ log.info(f"Finished: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
+ log.info(f"Passed: {len(passed)} | Failed: {len(failed)}")
+ if huc_times:
+ log.info(f"\nPer-HUC timing summary:")
+ for huc8, elapsed, status in huc_times:
+ log.info(f" {huc8} {status:4s} {_fmt(elapsed)}")
+ if failed:
+ log.warning(f"\nFailed HUCs: {failed}")
+ log.warning("Re-run this script to retry (FAIL lines are automatically retried).")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/tests/test_getallinputdata.py b/tests/test_getallinputdata.py
index 4167bec..3c0136e 100644
--- a/tests/test_getallinputdata.py
+++ b/tests/test_getallinputdata.py
@@ -3,22 +3,29 @@
import fimbox
-test_boundary = Path("./docs/test_boundary/test_smallB.shp")
+# ── EDIT THIS for each HUC8 you want to process ──────────────────
+CURRENT_HUC8 = "03020102"
+DEM_TILES_DIR = Path("D:/SI/out/study_area/watershed-data/dem_tiles")
+# ─────────────────────────────────────────────────────────────────
+
+test_boundary = Path("./docs/study_boundary/study_area.gpkg")
test_huc8 = "08060202" # Yazoo River basin, MS
-# Combined preprocessing pipeline tests
-# Run full pipeline from a boundary shapefile
+# Run full pipeline for a single HUC8 using the pre-downloaded DEM tile.
+# Change CURRENT_HUC8 above and re-run for each HUC in your study area.
def test_preprocess_all_from_boundary():
+ dem_path = DEM_TILES_DIR / f"dem_{CURRENT_HUC8}.tif"
pp = fimbox.getAllInputData(
- boundary=test_boundary,
+ huc8=CURRENT_HUC8,
out_dir="../out",
- buffer_m=5000, # metres to buffer boundary for data downloads
- headwater_buffer_cells=8, # pixels to shrink buffer for headwater clip
- get_flowlines=True, # set False to use your own flowlines and corresponding catchments
- get_catchments=True, # set False to skip NWM catchments--> use
- resolution="medium", # "high" -> NHDPlus HR flowlines/catchments via pynhd; "medium" (default) -> NWM. Lakes always NWM.
- identifier="nwmmr", # filename prefix for ALL source files; flows download->processing. Default "nwm".
+ buffer_m=5000,
+ headwater_buffer_cells=8,
+ get_flowlines=True,
+ get_catchments=True,
+ resolution="medium",
+ identifier="nwmmr",
+ dem=dem_path, # use pre-downloaded 10m tile — skips 3DEP download
)
pp.run()