Files
NewStock/main/train/UpdateRank.ipynb
2025-04-28 11:02:52 +08:00

1567 lines
191 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"cells": [
{
"cell_type": "code",
"id": "79a7758178bafdd3",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:10:25.019821Z",
"start_time": "2025-03-26T15:10:25.015412Z"
}
},
"source": [
"# %load_ext autoreload\n",
"# %autoreload 2\n",
"\n",
"import pandas as pd\n",
"import warnings\n",
"\n",
"warnings.filterwarnings(\"ignore\")\n",
"\n",
"pd.set_option('display.max_columns', None)\n"
],
"outputs": [],
"execution_count": 66
},
{
"cell_type": "code",
"id": "a79cafb06a7e0e43",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:11:40.164945Z",
"start_time": "2025-03-26T15:10:25.138896Z"
}
},
"source": [
"from code.utils.utils import read_and_merge_h5_data\n",
"\n",
"print('daily data')\n",
"df = read_and_merge_h5_data('../../data/daily_data.h5', key='daily_data',\n",
" columns=['ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'vol', 'pct_chg'],\n",
" df=None)\n",
"\n",
"print('daily basic')\n",
"df = read_and_merge_h5_data('../../data/daily_basic.h5', key='daily_basic',\n",
" columns=['ts_code', 'trade_date', 'turnover_rate', 'pe_ttm', 'circ_mv', 'volume_ratio',\n",
" 'is_st'], df=df, join='inner')\n",
"\n",
"print('stk limit')\n",
"df = read_and_merge_h5_data('../../data/stk_limit.h5', key='stk_limit',\n",
" columns=['ts_code', 'trade_date', 'pre_close', 'up_limit', 'down_limit'],\n",
" df=df)\n",
"print('money flow')\n",
"df = read_and_merge_h5_data('../../data/money_flow.h5', key='money_flow',\n",
" columns=['ts_code', 'trade_date', 'buy_sm_vol', 'sell_sm_vol', 'buy_lg_vol', 'sell_lg_vol',\n",
" 'buy_elg_vol', 'sell_elg_vol', 'net_mf_vol'],\n",
" df=df)\n",
"print('cyq perf')\n",
"df = read_and_merge_h5_data('../../data/cyq_perf.h5', key='cyq_perf',\n",
" columns=['ts_code', 'trade_date', 'his_low', 'his_high', 'cost_5pct', 'cost_15pct',\n",
" 'cost_50pct',\n",
" 'cost_85pct', 'cost_95pct', 'weight_avg', 'winner_rate'],\n",
" df=df)\n",
"print(df.info())"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"daily data\n",
"daily basic\n",
"inner merge on ['ts_code', 'trade_date']\n",
"stk limit\n",
"left merge on ['ts_code', 'trade_date']\n",
"money flow\n",
"left merge on ['ts_code', 'trade_date']\n",
"cyq perf\n",
"left merge on ['ts_code', 'trade_date']\n",
"<class 'pandas.core.frame.DataFrame'>\n",
"RangeIndex: 8450470 entries, 0 to 8450469\n",
"Data columns (total 31 columns):\n",
" # Column Dtype \n",
"--- ------ ----- \n",
" 0 ts_code object \n",
" 1 trade_date datetime64[ns]\n",
" 2 open float64 \n",
" 3 close float64 \n",
" 4 high float64 \n",
" 5 low float64 \n",
" 6 vol float64 \n",
" 7 pct_chg float64 \n",
" 8 turnover_rate float64 \n",
" 9 pe_ttm float64 \n",
" 10 circ_mv float64 \n",
" 11 volume_ratio float64 \n",
" 12 is_st bool \n",
" 13 up_limit float64 \n",
" 14 down_limit float64 \n",
" 15 buy_sm_vol float64 \n",
" 16 sell_sm_vol float64 \n",
" 17 buy_lg_vol float64 \n",
" 18 sell_lg_vol float64 \n",
" 19 buy_elg_vol float64 \n",
" 20 sell_elg_vol float64 \n",
" 21 net_mf_vol float64 \n",
" 22 his_low float64 \n",
" 23 his_high float64 \n",
" 24 cost_5pct float64 \n",
" 25 cost_15pct float64 \n",
" 26 cost_50pct float64 \n",
" 27 cost_85pct float64 \n",
" 28 cost_95pct float64 \n",
" 29 weight_avg float64 \n",
" 30 winner_rate float64 \n",
"dtypes: bool(1), datetime64[ns](1), float64(28), object(1)\n",
"memory usage: 1.9+ GB\n",
"None\n"
]
}
],
"execution_count": 67
},
{
"cell_type": "code",
"id": "cac01788dac10678",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:11:55.524829Z",
"start_time": "2025-03-26T15:11:41.366630Z"
}
},
"source": [
"print('industry')\n",
"industry_df = read_and_merge_h5_data('../../data/industry_data.h5', key='industry_data',\n",
" columns=['ts_code', 'l2_code', 'in_date'],\n",
" df=None, on=['ts_code'], join='left')\n",
"\n",
"\n",
"def merge_with_industry_data(df, industry_df):\n",
" # 确保日期字段是 datetime 类型\n",
" df['trade_date'] = pd.to_datetime(df['trade_date'])\n",
" industry_df['in_date'] = pd.to_datetime(industry_df['in_date'])\n",
"\n",
" # 对 industry_df 按 ts_code 和 in_date 排序\n",
" industry_df_sorted = industry_df.sort_values(['in_date', 'ts_code'])\n",
"\n",
" # 对原始 df 按 ts_code 和 trade_date 排序\n",
" df_sorted = df.sort_values(['trade_date', 'ts_code'])\n",
"\n",
" # 使用 merge_asof 进行向后合并\n",
" merged = pd.merge_asof(\n",
" df_sorted,\n",
" industry_df_sorted,\n",
" by='ts_code', # 按 ts_code 分组\n",
" left_on='trade_date',\n",
" right_on='in_date',\n",
" direction='backward'\n",
" )\n",
"\n",
" # 获取每个 ts_code 的最早 in_date 记录\n",
" min_in_date_per_ts = (industry_df_sorted\n",
" .groupby('ts_code')\n",
" .first()\n",
" .reset_index()[['ts_code', 'l2_code']])\n",
"\n",
" # 填充未匹配到的记录trade_date 早于所有 in_date 的情况)\n",
" merged['l2_code'] = merged['l2_code'].fillna(\n",
" merged['ts_code'].map(min_in_date_per_ts.set_index('ts_code')['l2_code'])\n",
" )\n",
"\n",
" # 保留需要的列并重置索引\n",
" result = merged.reset_index(drop=True)\n",
" return result\n",
"\n",
"\n",
"# 使用示例\n",
"df = merge_with_industry_data(df, industry_df)\n",
"# print(mdf[mdf['ts_code'] == '600751.SH'][['ts_code', 'trade_date', 'l2_code']])"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"industry\n"
]
}
],
"execution_count": 68
},
{
"cell_type": "code",
"id": "c4e9e1d31da6dba6",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:11:55.794514Z",
"start_time": "2025-03-26T15:11:55.600258Z"
}
},
"source": [
"def calculate_indicators(df):\n",
" \"\"\"\n",
" 计算四个指标当日涨跌幅、5日移动平均、RSI、MACD。\n",
" \"\"\"\n",
" df = df.sort_values('trade_date')\n",
" df['daily_return'] = (df['close'] - df['pre_close']) / df['pre_close'] * 100\n",
" # df['5_day_ma'] = df['close'].rolling(window=5).mean()\n",
" delta = df['close'].diff()\n",
" gain = delta.where(delta > 0, 0)\n",
" loss = -delta.where(delta < 0, 0)\n",
" avg_gain = gain.rolling(window=14).mean()\n",
" avg_loss = loss.rolling(window=14).mean()\n",
" rs = avg_gain / avg_loss\n",
" df['RSI'] = 100 - (100 / (1 + rs))\n",
"\n",
" # 计算MACD\n",
" ema12 = df['close'].ewm(span=12, adjust=False).mean()\n",
" ema26 = df['close'].ewm(span=26, adjust=False).mean()\n",
" df['MACD'] = ema12 - ema26\n",
" df['Signal_line'] = df['MACD'].ewm(span=9, adjust=False).mean()\n",
" df['MACD_hist'] = df['MACD'] - df['Signal_line']\n",
"\n",
" # 4. 情绪因子1市场上涨比例Up Ratio\n",
" df['up_ratio'] = df['daily_return'].apply(lambda x: 1 if x > 0 else 0)\n",
" df['up_ratio_20d'] = df['up_ratio'].rolling(window=20).mean() # 过去20天上涨比例\n",
"\n",
" # 5. 情绪因子2成交量变化率Volume Change Rate\n",
" df['volume_mean'] = df['vol'].rolling(window=20).mean() # 过去20天的平均成交量\n",
" df['volume_change_rate'] = (df['vol'] - df['volume_mean']) / df['volume_mean'] * 100 # 成交量变化率\n",
"\n",
" # 6. 情绪因子3波动率Volatility\n",
" df['volatility'] = df['daily_return'].rolling(window=20).std() # 过去20天的日收益率标准差\n",
"\n",
" # 7. 情绪因子4成交额变化率Amount Change Rate\n",
" df['amount_mean'] = df['amount'].rolling(window=20).mean() # 过去20天的平均成交额\n",
" df['amount_change_rate'] = (df['amount'] - df['amount_mean']) / df['amount_mean'] * 100 # 成交额变化率\n",
"\n",
" return df\n",
"\n",
"\n",
"def generate_index_indicators(h5_filename):\n",
" df = pd.read_hdf(h5_filename, key='index_data')\n",
" df['trade_date'] = pd.to_datetime(df['trade_date'], format='%Y%m%d')\n",
" df = df.sort_values('trade_date')\n",
"\n",
" # 计算每个ts_code的相关指标\n",
" df_indicators = []\n",
" for ts_code in df['ts_code'].unique():\n",
" df_index = df[df['ts_code'] == ts_code].copy()\n",
" df_index = calculate_indicators(df_index)\n",
" df_indicators.append(df_index)\n",
"\n",
" # 合并所有指数的结果\n",
" df_all_indicators = pd.concat(df_indicators, ignore_index=True)\n",
"\n",
" # 保留trade_date列并将同一天的数据按ts_code合并成一行\n",
" df_final = df_all_indicators.pivot_table(\n",
" index='trade_date',\n",
" columns='ts_code',\n",
" values=['daily_return', 'RSI', 'MACD', 'Signal_line',\n",
" 'MACD_hist', 'up_ratio_20d', 'volume_change_rate', 'volatility',\n",
" 'amount_change_rate', 'amount_mean'],\n",
" aggfunc='last'\n",
" )\n",
"\n",
" df_final.columns = [f\"{col[1]}_{col[0]}\" for col in df_final.columns]\n",
" df_final = df_final.reset_index()\n",
"\n",
" return df_final\n",
"\n",
"\n",
"# 使用函数\n",
"h5_filename = '../../data/index_data.h5'\n",
"index_data = generate_index_indicators(h5_filename)\n",
"index_data = index_data.dropna()\n"
],
"outputs": [],
"execution_count": 69
},
{
"cell_type": "code",
"id": "a735bc02ceb4d872",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:11:56.026392Z",
"start_time": "2025-03-26T15:11:55.984754Z"
}
},
"source": [
"import numpy as np\n",
"import talib\n",
"\n",
"\n",
"def get_rolling_factor(df):\n",
" old_columns = df.columns.tolist()[:]\n",
" # 按股票和日期排序\n",
" df = df.sort_values(by=['ts_code', 'trade_date'])\n",
" grouped = df.groupby('ts_code', group_keys=False)\n",
"\n",
" # df[\"gap_next_open\"] = (df[\"open\"].shift(-1) - df[\"close\"]) / df[\"close\"]\n",
"\n",
" df['return_skew'] = grouped['pct_chg'].rolling(window=5).skew().reset_index(0, drop=True)\n",
" df['return_kurtosis'] = grouped['pct_chg'].rolling(window=5).kurt().reset_index(0, drop=True)\n",
"\n",
" # 因子 1短期成交量变化率\n",
" df['volume_change_rate'] = (\n",
" grouped['vol'].rolling(window=2).mean() /\n",
" grouped['vol'].rolling(window=10).mean() - 1\n",
" ).reset_index(level=0, drop=True) # 确保索引对齐\n",
"\n",
" # 因子 2成交量突破信号\n",
" max_volume = grouped['vol'].rolling(window=5).max().reset_index(level=0, drop=True) # 确保索引对齐\n",
" df['cat_volume_breakout'] = (df['vol'] > max_volume)\n",
"\n",
" # 因子 3换手率均线偏离度\n",
" mean_turnover = grouped['turnover_rate'].rolling(window=3).mean().reset_index(level=0, drop=True)\n",
" std_turnover = grouped['turnover_rate'].rolling(window=3).std().reset_index(level=0, drop=True)\n",
" df['turnover_deviation'] = (df['turnover_rate'] - mean_turnover) / std_turnover\n",
"\n",
" # 因子 4换手率激增信号\n",
" df['cat_turnover_spike'] = (df['turnover_rate'] > mean_turnover + 2 * std_turnover)\n",
"\n",
" # 因子 5量比均值\n",
" df['avg_volume_ratio'] = grouped['volume_ratio'].rolling(window=3).mean().reset_index(level=0, drop=True)\n",
"\n",
" # 因子 6量比突破信号\n",
" max_volume_ratio = grouped['volume_ratio'].rolling(window=5).max().reset_index(level=0, drop=True)\n",
" df['cat_volume_ratio_breakout'] = (df['volume_ratio'] > max_volume_ratio)\n",
"\n",
" df['vol_spike'] = grouped.apply(\n",
" lambda x: pd.Series(x['vol'].rolling(20).mean(), index=x.index)\n",
" )\n",
" df['vol_std_5'] = df['vol'].pct_change().rolling(5).std()\n",
"\n",
" # 计算 ATR\n",
" df['atr_14'] = grouped.apply(\n",
" lambda x: pd.Series(talib.ATR(x['high'].values, x['low'].values, x['close'].values, timeperiod=14),\n",
" index=x.index)\n",
" )\n",
" df['atr_6'] = grouped.apply(\n",
" lambda x: pd.Series(talib.ATR(x['high'].values, x['low'].values, x['close'].values, timeperiod=6),\n",
" index=x.index)\n",
" )\n",
"\n",
" # 计算 OBV 及其均线\n",
" df['obv'] = grouped.apply(\n",
" lambda x: pd.Series(talib.OBV(x['close'].values, x['vol'].values), index=x.index)\n",
" )\n",
" df['maobv_6'] = grouped.apply(\n",
" lambda x: pd.Series(talib.SMA(x['obv'].values, timeperiod=6), index=x.index)\n",
" )\n",
"\n",
" df['rsi_3'] = grouped.apply(\n",
" lambda x: pd.Series(talib.RSI(x['close'].values, timeperiod=3), index=x.index)\n",
" )\n",
" df['rsi_6'] = grouped.apply(\n",
" lambda x: pd.Series(talib.RSI(x['close'].values, timeperiod=6), index=x.index)\n",
" )\n",
" df['rsi_9'] = grouped.apply(\n",
" lambda x: pd.Series(talib.RSI(x['close'].values, timeperiod=9), index=x.index)\n",
" )\n",
"\n",
" # 计算 return_10 和 return_20\n",
" df['return_5'] = grouped['close'].apply(lambda x: x / x.shift(5) - 1)\n",
" df['return_10'] = grouped['close'].apply(lambda x: x / x.shift(10) - 1)\n",
" df['return_20'] = grouped['close'].apply(lambda x: x / x.shift(20) - 1)\n",
"\n",
" # df['avg_close_5'] = grouped['close'].apply(lambda x: x.rolling(window=5).mean() / x)\n",
"\n",
" # 计算标准差指标\n",
" df['std_return_5'] = grouped['close'].apply(lambda x: x.pct_change().rolling(window=5).std())\n",
" df['std_return_15'] = grouped['close'].apply(lambda x: x.pct_change().rolling(window=15).std())\n",
" df['std_return_25'] = grouped['close'].apply(lambda x: x.pct_change().rolling(window=25).std())\n",
" df['std_return_90'] = grouped['close'].apply(lambda x: x.pct_change().rolling(window=90).std())\n",
" df['std_return_90_2'] = grouped['close'].apply(lambda x: x.shift(10).pct_change().rolling(window=90).std())\n",
"\n",
" # 计算 EMA 指标\n",
" df['_ema_5'] = grouped['close'].apply(\n",
" lambda x: pd.Series(talib.EMA(x.values, timeperiod=5), index=x.index)\n",
" )\n",
" df['_ema_13'] = grouped['close'].apply(\n",
" lambda x: pd.Series(talib.EMA(x.values, timeperiod=13), index=x.index)\n",
" )\n",
" df['_ema_20'] = grouped['close'].apply(\n",
" lambda x: pd.Series(talib.EMA(x.values, timeperiod=20), index=x.index)\n",
" )\n",
" df['_ema_60'] = grouped['close'].apply(\n",
" lambda x: pd.Series(talib.EMA(x.values, timeperiod=60), index=x.index)\n",
" )\n",
"\n",
" # 计算 act_factor1, act_factor2, act_factor3, act_factor4\n",
" df['act_factor1'] = grouped['_ema_5'].apply(\n",
" lambda x: np.arctan((x / x.shift(1) - 1) * 100) * 57.3 / 50\n",
" )\n",
" df['act_factor2'] = grouped['_ema_13'].apply(\n",
" lambda x: np.arctan((x / x.shift(1) - 1) * 100) * 57.3 / 40\n",
" )\n",
" df['act_factor3'] = grouped['_ema_20'].apply(\n",
" lambda x: np.arctan((x / x.shift(1) - 1) * 100) * 57.3 / 21\n",
" )\n",
" df['act_factor4'] = grouped['_ema_60'].apply(\n",
" lambda x: np.arctan((x / x.shift(1) - 1) * 100) * 57.3 / 10\n",
" )\n",
"\n",
" # 根据 trade_date 截面计算排名\n",
" df['rank_act_factor1'] = df.groupby('trade_date', group_keys=False)['act_factor1'].rank(ascending=False, pct=True)\n",
" df['rank_act_factor2'] = df.groupby('trade_date', group_keys=False)['act_factor2'].rank(ascending=False, pct=True)\n",
" df['rank_act_factor3'] = df.groupby('trade_date', group_keys=False)['act_factor3'].rank(ascending=False, pct=True)\n",
"\n",
" df['log(circ_mv)'] = np.log(df['circ_mv'])\n",
"\n",
" def rolling_covariance(x, y, window):\n",
" return x.rolling(window).cov(y)\n",
"\n",
" def delta(series, period):\n",
" return series.diff(period)\n",
"\n",
" def rank(series):\n",
" return series.rank(pct=True)\n",
"\n",
" def stddev(series, window):\n",
" return series.rolling(window).std()\n",
"\n",
" window_high_volume = 5\n",
" window_close_stddev = 20\n",
" period_delta = 5\n",
" df['cov'] = rolling_covariance(df['high'], df['vol'], window_high_volume)\n",
" df['delta_cov'] = delta(df['cov'], period_delta)\n",
" df['_rank_stddev'] = rank(stddev(df['close'], window_close_stddev))\n",
" df['alpha_22_improved'] = -1 * df['delta_cov'] * df['_rank_stddev']\n",
"\n",
" df['alpha_003'] = np.where(df['high'] != df['low'],\n",
" (df['close'] - df['open']) / (df['high'] - df['low']),\n",
" 0)\n",
"\n",
" df['alpha_007'] = grouped.apply(lambda x: x['close'].rolling(5).corr(x['vol'])).reset_index(level=0, drop=True)\n",
" df['alpha_007'] = df.groupby('trade_date', group_keys=False)['alpha_007'].rank(ascending=True, pct=True)\n",
"\n",
" df['alpha_013'] = grouped['close'].transform(lambda x: x.rolling(5).sum() - x.rolling(20).sum())\n",
" df['alpha_013'] = df.groupby('trade_date', group_keys=False)['alpha_013'].rank(ascending=True, pct=True)\n",
"\n",
" df['cat_up_limit'] = (df['close'] == df['up_limit']) # 是否涨停1表示涨停0表示未涨停\n",
" df['cat_down_limit'] = (df['close'] == df['down_limit']) # 是否跌停1表示跌停0表示未跌停\n",
" df['up_limit_count_10d'] = grouped['cat_up_limit'].rolling(window=10, min_periods=1).sum().reset_index(level=0,\n",
" drop=True)\n",
" df['down_limit_count_10d'] = grouped['cat_down_limit'].rolling(window=10, min_periods=1).sum().reset_index(level=0,\n",
" drop=True)\n",
"\n",
" # 3. 最近连续涨跌停天数\n",
" def calculate_consecutive_limits(series):\n",
" \"\"\"\n",
" 计算连续涨停/跌停天数。\n",
" \"\"\"\n",
" consecutive_up = series * (series.groupby((series != series.shift()).cumsum()).cumcount() + 1)\n",
" consecutive_down = series * (series.groupby((series != series.shift()).cumsum()).cumcount() + 1)\n",
" return consecutive_up, consecutive_down\n",
"\n",
" # 连续涨停天数\n",
" df['consecutive_up_limit'] = grouped['cat_up_limit'].apply(\n",
" lambda x: calculate_consecutive_limits(x)[0]\n",
" ).reset_index(level=0, drop=True)\n",
"\n",
" df['vol_break'] = np.where((df['close'] > df['cost_85pct']) & (df['volume_ratio'] > 2), 1, 0)\n",
"\n",
" df['weight_roc5'] = grouped['weight_avg'].apply(lambda x: x.pct_change(5))\n",
"\n",
" def rolling_corr(group):\n",
" roc_close = group['close'].pct_change()\n",
" roc_weight = group['weight_avg'].pct_change()\n",
" return roc_close.rolling(10).corr(roc_weight)\n",
"\n",
" df['price_cost_divergence'] = grouped.apply(rolling_corr)\n",
"\n",
" df['smallcap_concentration'] = (1 / df['circ_mv']) * (df['cost_85pct'] - df['cost_15pct'])\n",
"\n",
" # 16. 筹码稳定性指数 (20日波动率)\n",
" df['weight_std20'] = grouped['weight_avg'].apply(lambda x: x.rolling(20).std())\n",
" df['cost_stability'] = df['weight_std20'] / grouped['weight_avg'].transform(lambda x: x.rolling(20).mean())\n",
"\n",
" # 17. 成本区间突破标记\n",
" df['high_cost_break_days'] = grouped.apply(lambda g: g['close'].gt(g['cost_95pct']).rolling(5).sum())\n",
"\n",
" # 20. 筹码-流动性风险\n",
" df['liquidity_risk'] = (df['cost_95pct'] - df['cost_5pct']) * (\n",
" 1 / grouped['vol'].transform(lambda x: x.rolling(10).mean()))\n",
"\n",
" # 7. 市值波动率因子\n",
" df['turnover_std'] = grouped['turnover_rate'].rolling(window=20).std().reset_index(level=0, drop=True)\n",
" df['mv_volatility'] = grouped.apply(lambda x: x['turnover_std'] / x['circ_mv']).reset_index(level=0, drop=True)\n",
"\n",
" # 8. 市值成长性因子\n",
" df['volume_growth'] = grouped['vol'].pct_change(periods=20).reset_index(level=0, drop=True)\n",
" df['mv_growth'] = grouped.apply(lambda x: x['volume_growth'] / x['circ_mv']).reset_index(level=0, drop=True)\n",
"\n",
" df.drop(columns=['weight_std20'], inplace=True, errors='ignore')\n",
" new_columns = [col for col in df.columns.tolist()[:] if col not in old_columns]\n",
"\n",
" return df, new_columns\n",
"\n",
"\n",
"def get_simple_factor(df):\n",
" old_columns = df.columns.tolist()[:]\n",
" df = df.sort_values(by=['ts_code', 'trade_date'])\n",
"\n",
" alpha = 0.5\n",
" df['momentum_factor'] = df['volume_change_rate'] + alpha * df['turnover_deviation']\n",
" df['resonance_factor'] = df['volume_ratio'] * df['pct_chg']\n",
" df['log_close'] = np.log(df['close'])\n",
"\n",
" df['cat_vol_spike'] = df['vol'] > 2 * df['vol_spike']\n",
"\n",
" df['up'] = (df['high'] - df[['close', 'open']].max(axis=1)) / df['close']\n",
" df['down'] = (df[['close', 'open']].min(axis=1) - df['low']) / df['close']\n",
"\n",
" df['obv-maobv_6'] = df['obv'] - df['maobv_6']\n",
"\n",
" # 计算比值指标\n",
" df['std_return_5 / std_return_90'] = df['std_return_5'] / df['std_return_90']\n",
" df['std_return_5 / std_return_25'] = df['std_return_5'] / df['std_return_25']\n",
"\n",
" # 计算标准差差值\n",
" df['std_return_90 - std_return_90_2'] = df['std_return_90'] - df['std_return_90_2']\n",
"\n",
" df['cat_af1'] = df['act_factor1'] > 0\n",
" df['cat_af2'] = df['act_factor2'] > df['act_factor1']\n",
" df['cat_af3'] = df['act_factor3'] > df['act_factor2']\n",
" df['cat_af4'] = df['act_factor4'] > df['act_factor3']\n",
"\n",
" # 计算 act_factor5 和 act_factor6\n",
" df['act_factor5'] = df['act_factor1'] + df['act_factor2'] + df['act_factor3'] + df['act_factor4']\n",
" df['act_factor6'] = (df['act_factor1'] - df['act_factor2']) / np.sqrt(\n",
" df['act_factor1'] ** 2 + df['act_factor2'] ** 2)\n",
"\n",
" df['active_buy_volume_large'] = df['buy_lg_vol'] / df['net_mf_vol']\n",
" df['active_buy_volume_big'] = df['buy_elg_vol'] / df['net_mf_vol']\n",
" df['active_buy_volume_small'] = df['buy_sm_vol'] / df['net_mf_vol']\n",
"\n",
" df['buy_lg_vol_minus_sell_lg_vol'] = (df['buy_lg_vol'] - df['sell_lg_vol']) / df['net_mf_vol']\n",
" df['buy_elg_vol_minus_sell_elg_vol'] = (df['buy_elg_vol'] - df['sell_elg_vol']) / df['net_mf_vol']\n",
"\n",
" df['log(circ_mv)'] = np.log(df['circ_mv'])\n",
"\n",
" df['ctrl_strength'] = (df['cost_85pct'] - df['cost_15pct']) / (df['his_high'] - df['his_low'])\n",
"\n",
" df['low_cost_dev'] = (df['close'] - df['cost_5pct']) / (df['cost_50pct'] - df['cost_5pct'])\n",
"\n",
" df['asymmetry'] = (df['cost_95pct'] - df['cost_50pct']) / (df['cost_50pct'] - df['cost_5pct'])\n",
"\n",
" df['lock_factor'] = df['turnover_rate'] * (\n",
" 1 - (df['cost_95pct'] - df['cost_5pct']) / (df['his_high'] - df['his_low']))\n",
"\n",
" df['cat_vol_break'] = (df['close'] > df['cost_85pct']) & (df['volume_ratio'] > 2)\n",
"\n",
" df['cost_atr_adj'] = (df['cost_95pct'] - df['cost_5pct']) / df['atr_14']\n",
"\n",
" # 12. 小盘股筹码集中度\n",
" df['smallcap_concentration'] = (1 / df['circ_mv']) * (df['cost_85pct'] - df['cost_15pct'])\n",
"\n",
" df['cat_golden_resonance'] = ((df['close'] > df['weight_avg']) &\n",
" (df['volume_ratio'] > 1.5) &\n",
" (df['winner_rate'] > 0.7))\n",
"\n",
" df['mv_turnover_ratio'] = df['turnover_rate'] / df['circ_mv']\n",
"\n",
" df['mv_adjusted_volume'] = df['vol'] / df['circ_mv']\n",
"\n",
" df['mv_weighted_turnover'] = df['turnover_rate'] * (1 / df['circ_mv'])\n",
"\n",
" df['nonlinear_mv_volume'] = df['vol'] / df['circ_mv']\n",
"\n",
" df['mv_volume_ratio'] = df['volume_ratio'] / df['circ_mv']\n",
"\n",
" df['mv_momentum'] = df['turnover_rate'] * df['volume_ratio'] / df['circ_mv']\n",
"\n",
" drop_columns = [col for col in df.columns if col.startswith('_')]\n",
" df.drop(columns=drop_columns, inplace=True, errors='ignore')\n",
"\n",
" new_columns = [col for col in df.columns.tolist()[:] if col not in old_columns]\n",
" return df, new_columns\n"
],
"outputs": [],
"execution_count": 70
},
{
"cell_type": "code",
"id": "53f86ddc0677a6d7",
"metadata": {
"scrolled": true,
"ExecuteTime": {
"end_time": "2025-03-26T15:12:02.787850Z",
"start_time": "2025-03-26T15:11:56.035514Z"
}
},
"source": [
"from code.utils.factor import get_act_factor\n",
"\n",
"\n",
"def read_industry_data(h5_filename):\n",
" # 读取 H5 文件中所有的行业数据\n",
" industry_data = pd.read_hdf(h5_filename, key='sw_daily', columns=[\n",
" 'ts_code', 'trade_date', 'open', 'close', 'high', 'low', 'pe', 'pb', 'vol'\n",
" ]) # 假设 H5 文件的键是 'industry_data'\n",
" industry_data = industry_data.sort_values(by=['ts_code', 'trade_date'])\n",
" industry_data = industry_data.reindex()\n",
" industry_data['trade_date'] = pd.to_datetime(industry_data['trade_date'], format='%Y%m%d')\n",
"\n",
" grouped = industry_data.groupby('ts_code', group_keys=False)\n",
" industry_data['obv'] = grouped.apply(\n",
" lambda x: pd.Series(talib.OBV(x['close'].values, x['vol'].values), index=x.index)\n",
" )\n",
" industry_data['return_5'] = grouped['close'].apply(lambda x: x / x.shift(5) - 1)\n",
" industry_data['return_20'] = grouped['close'].apply(lambda x: x / x.shift(20) - 1)\n",
"\n",
" industry_data = get_act_factor(industry_data, cat=False)\n",
" industry_data = industry_data.sort_values(by=['trade_date', 'ts_code'])\n",
"\n",
" # # 计算每天每个 ts_code 的因子和当天所有 ts_code 的中位数的偏差\n",
" # factor_columns = ['obv', 'return_5', 'return_20', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4'] # 因子列\n",
" #\n",
" # for factor in factor_columns:\n",
" # if factor in industry_data.columns:\n",
" # # 计算每天每个 ts_code 的因子值与当天所有 ts_code 的中位数的偏差\n",
" # industry_data[f'{factor}_deviation'] = industry_data.groupby('trade_date')[factor].transform(\n",
" # lambda x: x - x.mean())\n",
"\n",
" industry_data['return_5_percentile'] = industry_data.groupby('trade_date')['return_5'].transform(\n",
" lambda x: x.rank(pct=True))\n",
" industry_data['return_20_percentile'] = industry_data.groupby('trade_date')['return_20'].transform(\n",
" lambda x: x.rank(pct=True))\n",
" industry_data = industry_data.drop(columns=['open', 'close', 'high', 'low', 'pe', 'pb', 'vol'])\n",
"\n",
" industry_data = industry_data.rename(\n",
" columns={col: f'industry_{col}' for col in industry_data.columns if col not in ['ts_code', 'trade_date']})\n",
"\n",
" industry_data = industry_data.rename(columns={'ts_code': 'cat_l2_code'})\n",
" return industry_data\n",
"\n",
"\n",
"industry_df = read_industry_data('../../data/sw_daily.h5')\n"
],
"outputs": [],
"execution_count": 71
},
{
"cell_type": "code",
"id": "dbe2fd8021b9417f",
"metadata": {
"scrolled": true,
"ExecuteTime": {
"end_time": "2025-03-26T15:12:02.870181Z",
"start_time": "2025-03-26T15:12:02.865559Z"
}
},
"source": [
"origin_columns = df.columns.tolist()\n",
"origin_columns = [col for col in origin_columns if\n",
" col not in ['turnover_rate', 'pe_ttm', 'volume_ratio', 'vol', 'pct_chg', 'l2_code', 'winner_rate']]\n",
"origin_columns = [col for col in origin_columns if col not in index_data.columns]\n",
"origin_columns = [col for col in origin_columns if 'cyq' not in col]\n",
"print(origin_columns)"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"['ts_code', 'open', 'close', 'high', 'low', 'circ_mv', 'is_st', 'up_limit', 'down_limit', 'buy_sm_vol', 'sell_sm_vol', 'buy_lg_vol', 'sell_lg_vol', 'buy_elg_vol', 'sell_elg_vol', 'net_mf_vol', 'his_low', 'his_high', 'cost_5pct', 'cost_15pct', 'cost_50pct', 'cost_85pct', 'cost_95pct', 'weight_avg', 'in_date']\n"
]
}
],
"execution_count": 72
},
{
"cell_type": "code",
"id": "92d84ce15a562ec6",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:14:41.756942Z",
"start_time": "2025-03-26T15:12:03.028028Z"
}
},
"source": [
"def filter_data(df):\n",
" # df = df.groupby('trade_date').apply(lambda x: x.nlargest(1000, 'act_factor1'))\n",
" df = df[~df['is_st']]\n",
" df = df[~df['ts_code'].str.endswith('BJ')]\n",
" df = df[~df['ts_code'].str.startswith('30')]\n",
" df = df[~df['ts_code'].str.startswith('68')]\n",
" df = df[~df['ts_code'].str.startswith('8')]\n",
" df = df[df['trade_date'] >= '20180101']\n",
" df = df.reset_index(drop=True)\n",
" return df\n",
"\n",
"\n",
"df = filter_data(df)\n",
"# df = get_technical_factor(df)\n",
"# df = get_act_factor(df)\n",
"# df = get_money_flow_factor(df)\n",
"# df = get_alpha_factor(df)\n",
"# df = get_limit_factor(df)\n",
"# df = get_cyp_perf_factor(df)\n",
"# df = get_mv_factors(df)\n",
"df, _ = get_rolling_factor(df)\n",
"df, _ = get_simple_factor(df)\n",
"# df = df.merge(industry_df, on=['l2_code', 'trade_date'], how='left')\n",
"df = df.rename(columns={'l2_code': 'cat_l2_code'})\n",
"# df = df.merge(index_data, on='trade_date', how='left')\n",
"\n",
"print(df.info())"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Index: 5102787 entries, 0 to 5102786\n",
"Columns: 122 entries, ts_code to mv_momentum\n",
"dtypes: bool(13), datetime64[ns](2), float64(103), int32(1), int64(1), object(2)\n",
"memory usage: 4.2+ GB\n",
"None\n"
]
}
],
"execution_count": 73
},
{
"cell_type": "code",
"id": "f4f16d63ad18d1bc",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:14:42.493112Z",
"start_time": "2025-03-26T15:14:42.475598Z"
}
},
"source": [
"from scipy.stats import ks_2samp, wasserstein_distance\n",
"\n",
"\n",
"def remove_shifted_features(train_data, test_data, feature_columns, ks_threshold=0.1, wasserstein_threshold=0.15,\n",
" importance_threshold=0.05):\n",
" dropped_features = []\n",
"\n",
" # **统计数据漂移**\n",
" numeric_columns = train_data.select_dtypes(include=['float64', 'int64']).columns\n",
" numeric_columns = [col for col in numeric_columns if col in feature_columns]\n",
" for feature in numeric_columns:\n",
" ks_stat, p_value = ks_2samp(train_data[feature], test_data[feature])\n",
" wasserstein_dist = wasserstein_distance(train_data[feature], test_data[feature])\n",
"\n",
" if p_value < ks_threshold or wasserstein_dist > wasserstein_threshold:\n",
" dropped_features.append(feature)\n",
"\n",
" print(f\"检测到 {len(dropped_features)} 个可能漂移的特征: {dropped_features}\")\n",
"\n",
" # **应用阈值进行最终筛选**\n",
" filtered_features = [f for f in feature_columns if f not in dropped_features]\n",
"\n",
" return filtered_features, dropped_features\n",
"\n"
],
"outputs": [],
"execution_count": 74
},
{
"cell_type": "code",
"id": "9d807cb2cde5d92c",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:14:42.825272Z",
"start_time": "2025-03-26T15:14:42.814210Z"
}
},
"source": [
"def create_deviation_within_dates(df, feature_columns):\n",
" groupby_col = 'cat_l2_code' # 使用 trade_date 进行分组\n",
" new_columns = {}\n",
" ret_feature_columns = feature_columns[:]\n",
"\n",
" # 自动选择所有数值型特征\n",
" num_features = [col for col in feature_columns if 'cat' not in col and 'index' not in col]\n",
"\n",
" # num_features = ['vol', 'pct_chg', 'turnover_rate', 'volume_ratio', 'cat_vol_spike', 'obv', 'maobv_6', 'return_5', 'return_10', 'return_20', 'std_return_5', 'std_return_15', 'std_return_90', 'std_return_90_2', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4', 'act_factor5', 'act_factor6', 'rank_act_factor1', 'rank_act_factor2', 'rank_act_factor3', 'active_buy_volume_large', 'active_buy_volume_big', 'active_buy_volume_small', 'alpha_022', 'alpha_003', 'alpha_007', 'alpha_013']\n",
" num_features = [col for col in num_features if 'cat' not in col and 'industry' not in col]\n",
" num_features = [col for col in num_features if 'limit' not in col]\n",
" num_features = [col for col in num_features if 'cyq' not in col]\n",
"\n",
" # 遍历所有数值型特征\n",
" for feature in num_features:\n",
" if feature == 'trade_date': # 不需要对 'trade_date' 计算偏差\n",
" continue\n",
"\n",
" # grouped_mean = df.groupby(['trade_date'])[feature].transform('mean')\n",
" # deviation_col_name = f'deviation_mean_{feature}'\n",
" # new_columns[deviation_col_name] = df[feature] - grouped_mean\n",
" # ret_feature_columns.append(deviation_col_name)\n",
"\n",
" grouped_mean = df.groupby(['trade_date', groupby_col])[feature].transform('mean')\n",
" deviation_col_name = f'deviation_mean_{feature}'\n",
" new_columns[deviation_col_name] = df[feature] - grouped_mean\n",
" ret_feature_columns.append(deviation_col_name)\n",
"\n",
" # 将新计算的偏差特征与原始 DataFrame 合并\n",
" df = pd.concat([df, pd.DataFrame(new_columns)], axis=1)\n",
"\n",
" # for feature in ['obv', 'return_20', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4']:\n",
" # df[f'deviation_industry_{feature}'] = df[feature] - df[f'industry_{feature}']\n",
"\n",
" return df, ret_feature_columns\n"
],
"outputs": [],
"execution_count": 75
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:14:44.049228Z",
"start_time": "2025-03-26T15:14:43.001080Z"
}
},
"cell_type": "code",
"source": [
"import pandas as pd\n",
"\n",
"\n",
"def remove_outliers_label_percentile(label: pd.Series, lower_percentile: float = 0.01, upper_percentile: float = 0.99,\n",
" log=True):\n",
" if not (0 <= lower_percentile < upper_percentile <= 1):\n",
" raise ValueError(\"Percentile values must satisfy 0 <= lower_percentile < upper_percentile <= 1.\")\n",
"\n",
" # Calculate lower and upper bounds based on percentiles\n",
" lower_bound = label.quantile(lower_percentile)\n",
" upper_bound = label.quantile(upper_percentile)\n",
"\n",
" # Filter out values outside the bounds\n",
" filtered_label = label[(label >= lower_bound) & (label <= upper_bound)]\n",
"\n",
" # Print the number of removed outliers\n",
" if log:\n",
" print(f\"Removed {len(label) - len(filtered_label)} outliers.\")\n",
" return filtered_label\n",
"\n",
"\n",
"def calculate_risk_adjusted_target(df, days=5):\n",
" df = df.sort_values(by=['ts_code', 'trade_date'])\n",
"\n",
" df['future_close'] = df.groupby('ts_code')['close'].shift(-days)\n",
" df['future_open'] = df.groupby('ts_code')['open'].shift(-1)\n",
" df['future_return'] = (df['future_close'] - df['future_open']) / df['future_open']\n",
"\n",
" df['future_volatility'] = df.groupby('ts_code')['future_return'].rolling(days, min_periods=1).std().reset_index(\n",
" level=0, drop=True)\n",
" sharpe_ratio = df['future_return'] * df['future_volatility']\n",
" sharpe_ratio.replace([np.inf, -np.inf], np.nan, inplace=True)\n",
"\n",
" return sharpe_ratio\n",
"\n",
"\n",
"def calculate_score(df, days=5, lambda_param=1.0):\n",
" def calculate_max_drawdown(prices):\n",
" peak = prices.iloc[0] # 初始化峰值\n",
" max_drawdown = 0 # 初始化最大回撤\n",
"\n",
" for price in prices:\n",
" if price > peak:\n",
" peak = price # 更新峰值\n",
" else:\n",
" drawdown = (peak - price) / peak # 计算当前回撤\n",
" max_drawdown = max(max_drawdown, drawdown) # 更新最大回撤\n",
"\n",
" return max_drawdown\n",
"\n",
" def compute_stock_score(stock_df):\n",
" stock_df = stock_df.sort_values(by=['trade_date'])\n",
" future_return = stock_df['future_return']\n",
" volatility = stock_df['close'].pct_change().rolling(days).std().shift(-days)\n",
" max_drawdown = stock_df['close'].rolling(days).apply(calculate_max_drawdown, raw=False).shift(-days)\n",
" score = future_return - lambda_param * max_drawdown\n",
"\n",
" return score\n",
"\n",
" scores = df.groupby('ts_code').apply(lambda x: compute_stock_score(x))\n",
" scores = scores.reset_index(level=0, drop=True)\n",
"\n",
" return scores\n",
"\n",
"\n",
"def remove_highly_correlated_features(df, feature_columns, threshold=0.9):\n",
" numeric_features = df[feature_columns].select_dtypes(include=[np.number]).columns.tolist()\n",
" if not numeric_features:\n",
" raise ValueError(\"No numeric features found in the provided data.\")\n",
"\n",
" corr_matrix = df[numeric_features].corr().abs()\n",
" upper = corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(bool))\n",
" to_drop = [column for column in upper.columns if any(upper[column] > threshold)]\n",
" remaining_features = [col for col in feature_columns if col not in to_drop\n",
" or 'act' in col or 'af' in col]\n",
" return remaining_features\n",
"\n",
"\n",
"import pandas as pd\n",
"\n",
"\n",
"def cross_sectional_standardization(df, features):\n",
" df_sorted = df.sort_values(by='trade_date') # 按时间排序\n",
" df_standardized = df_sorted.copy()\n",
"\n",
" for date in df_sorted['trade_date'].unique():\n",
" # 获取当前时间点的数据\n",
" current_data = df_standardized[df_standardized['trade_date'] == date]\n",
"\n",
" # 只对指定特征进行标准化\n",
" scaler = StandardScaler()\n",
" standardized_values = scaler.fit_transform(current_data[features])\n",
"\n",
" # 将标准化结果重新赋值回去\n",
" df_standardized.loc[df_standardized['trade_date'] == date, features] = standardized_values\n",
"\n",
" return df_standardized\n",
"\n",
"\n",
"import gc\n",
"\n",
"gc.collect()"
],
"id": "7ba833ee11a2f4cc",
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"execution_count": 76
},
{
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:14:44.297918Z",
"start_time": "2025-03-26T15:14:44.058234Z"
}
},
"cell_type": "code",
"source": "print(df[['ts_code', 'trade_date', 'act_factor1']].head())",
"id": "8491afd6ea37782",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" ts_code trade_date act_factor1\n",
"0 000001.SZ 2018-01-02 NaN\n",
"2536 000001.SZ 2018-01-03 NaN\n",
"5079 000001.SZ 2018-01-04 NaN\n",
"7623 000001.SZ 2018-01-05 NaN\n",
"10167 000001.SZ 2018-01-08 NaN\n"
]
}
],
"execution_count": 77
},
{
"cell_type": "code",
"id": "097356cb-1cd8-4947-b870-9414abfdb3d8",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:17:54.377205Z",
"start_time": "2025-03-26T15:14:44.467603Z"
}
},
"source": [
"days = 2\n",
"validation_days = 120\n",
"\n",
"import gc\n",
"\n",
"gc.collect()\n",
"\n",
"# df['future_return'] = df.groupby('ts_code', group_keys=False)['close'].apply(lambda x: x.shift(-days) / x - 1)\n",
"df['future_return'] = (df.groupby('ts_code')['close'].shift(-days) - df.groupby('ts_code')['open'].shift(-1)) / \\\n",
" df.groupby('ts_code')['open'].shift(-1)\n",
"df['future_volatility'] = (\n",
" df.groupby('ts_code')['future_return']\n",
" .transform(lambda x: x.rolling(days).std())\n",
")\n",
"\n",
"df['future_score'] = (\n",
" 0.7 * df['future_return'] +\n",
" 0.3 * df['future_volatility']\n",
")\n",
"\n",
"filter_index = df['future_return'].between(df['future_return'].quantile(0.01), df['future_return'].quantile(0.99))\n",
"filter_index = df['future_volatility'].between(df['future_volatility'].quantile(0.01),\n",
" df['future_volatility'].quantile(0.99)) | filter_index\n",
"\n",
"# df['label'] = df.groupby('trade_date', group_keys=False)['future_volatility'].transform(\n",
"# lambda x: pd.qcut(x, q=30, labels=False, duplicates='drop')\n",
"# )\n",
"\n",
"df['label'] = df.groupby('trade_date', group_keys=False)['future_score'].transform(\n",
" lambda x: pd.qcut(x, q=50, labels=False, duplicates='drop')\n",
")\n",
"\n",
"\n",
"# df['1_score'] = df.groupby('ts_code', group_keys=False)['future_score'].shift(days)\n",
"# df['2_score'] = df.groupby('ts_code', group_keys=False)['future_score'].shift(1 + days)\n",
"# df['3_score'] = df.groupby('ts_code', group_keys=False)['future_score'].shift(3 + days - 1)\n",
"\n",
"def symmetric_log_transform(values):\n",
" return np.sign(values) * np.log1p(np.abs(values))\n",
"\n",
"\n",
"train_data = df[filter_index & (df['trade_date'] <= '2023-01-01') & (df['trade_date'] >= '2000-01-01')]\n",
"test_data = df[filter_index & (df['trade_date'] >= '2023-01-01')]\n",
"\n",
"\n",
"def select_pre_zt_stocks_dynamic(stock_df):\n",
" # 排序数据\n",
" stock_df = stock_df.sort_values(by=['trade_date', 'ts_code'])\n",
"\n",
" # avg_vol_3 = stock_df.groupby('ts_code')['vol'].rolling(window=3).mean().reset_index(level=0, drop=True)\n",
" # avg_vol_5 = stock_df.groupby('ts_code')['vol'].rolling(window=5).mean().shift(3).reset_index(level=0, drop=True)\n",
"\n",
" # stock_df = stock_df[\n",
" # (stock_df['cat_up_limit'] == 1) |\n",
" # (stock_df['vol'] > vol_spike_multiplier * stock_df['vol_spike'])\n",
" # ]\n",
" # cd1 = stock_df[\"close\"] > stock_df[\"close\"].shift(1)\n",
"\n",
" # cd2 = stock_df[\"close\"] > stock_df[\"close\"].rolling(window=10).mean()\n",
" #\n",
" # cd3 = (avg_vol_3 > avg_vol_5 * 2)\n",
" #\n",
" # cd4 = stock_df['gap_next_open'] < 0\n",
"\n",
" # stock_df = stock_df[(cd2 & cd4) | cd3]\n",
" stock_df = stock_df.groupby('trade_date', group_keys=False).apply(\n",
" lambda x: x.nlargest(1000, 'return_20')\n",
" )\n",
"\n",
" return stock_df\n",
"\n",
"\n",
"# train_data = select_pre_zt_stocks_dynamic(train_data)\n",
"# test_data = select_pre_zt_stocks_dynamic(test_data)\n",
"\n",
"train_data, _ = get_simple_factor(train_data)\n",
"test_data, _ = get_simple_factor(test_data)\n",
"\n",
"# train_data['label'] = train_data.groupby('trade_date', group_keys=False)['future_score'].transform(\n",
"# lambda x: pd.qcut(x, q=50, labels=False, duplicates='drop')\n",
"# )\n",
"# test_data['label'] = test_data.groupby('trade_date', group_keys=False)['future_score'].transform(\n",
"# lambda x: pd.qcut(x, q=50, labels=False, duplicates='drop')\n",
"# )\n",
"\n",
"industry_df = industry_df.sort_values(by=['trade_date'])\n",
"index_data = index_data.sort_values(by=['trade_date'])\n",
"\n",
"train_data = train_data.merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left')\n",
"# train_data = train_data.merge(index_data, on='trade_date', how='left')\n",
"test_data = test_data.merge(industry_df, on=['cat_l2_code', 'trade_date'], how='left')\n",
"# test_data = test_data.merge(index_data, on='trade_date', how='left')\n",
"\n",
"train_data, test_data = train_data.replace([np.inf, -np.inf], np.nan), test_data.replace([np.inf, -np.inf], np.nan)\n",
"\n",
"# feature_columns_new = feature_columns[:]\n",
"# train_data, _ = create_deviation_within_dates(train_data, feature_columns)\n",
"# test_data, _ = create_deviation_within_dates(test_data, feature_columns)\n",
"\n",
"feature_columns = [col for col in train_data.columns if col in train_data.columns]\n",
"feature_columns = [col for col in feature_columns if col not in ['trade_date',\n",
" 'ts_code',\n",
" 'label']]\n",
"feature_columns = [col for col in feature_columns if 'future' not in col]\n",
"feature_columns = [col for col in feature_columns if 'label' not in col]\n",
"feature_columns = [col for col in feature_columns if 'score' not in col]\n",
"feature_columns = [col for col in feature_columns if 'gen' not in col]\n",
"feature_columns = [col for col in feature_columns if 'cat_l2_code' not in col]\n",
"feature_columns = [col for col in feature_columns if col not in origin_columns]\n",
"feature_columns = [col for col in feature_columns if not col.startswith('_')]\n",
"print(f'feature_columns size: {len(feature_columns)}')\n",
"\n",
"feature_columns, _ = remove_shifted_features(train_data[train_data['label'] == train_data['label'].max()],\n",
" test_data[test_data['label'] == test_data['label'].max()],\n",
" feature_columns)\n",
"\n",
"feature_columns = remove_highly_correlated_features(train_data[train_data['label'] == train_data['label'].max()],\n",
" feature_columns)\n",
"keep_columns = [col for col in train_data.columns if\n",
" col in feature_columns or col in ['ts_code', 'trade_date', 'label', 'future_return',\n",
" 'future_score', 'future_volatility']]\n",
"# train_data = train_data[keep_columns]\n",
"print(f'feature_columns: {feature_columns}')\n",
"\n",
"train_data = train_data.dropna(subset=feature_columns)\n",
"train_data = train_data.dropna(subset=['label'])\n",
"train_data = train_data.reset_index(drop=True)\n",
"\n",
"# print(test_data.tail())\n",
"test_data = test_data.dropna(subset=feature_columns)\n",
"# test_data = test_data.dropna(subset=['label'])\n",
"test_data = test_data.reset_index(drop=True)\n",
"\n",
"print(len(train_data))\n",
"print(f\"最小日期: {train_data['trade_date'].min().strftime('%Y-%m-%d')}\")\n",
"print(f\"最大日期: {train_data['trade_date'].max().strftime('%Y-%m-%d')}\")\n",
"print(len(test_data))\n",
"print(f\"最小日期: {test_data['trade_date'].min().strftime('%Y-%m-%d')}\")\n",
"print(f\"最大日期: {test_data['trade_date'].max().strftime('%Y-%m-%d')}\")\n",
"\n",
"cat_columns = [col for col in feature_columns if col.startswith('cat')]\n",
"for col in cat_columns:\n",
" train_data[col] = train_data[col].astype('category')\n",
" test_data[col] = test_data[col].astype('category')\n",
"\n",
"\n",
"\n",
"# feature_columns_new.remove('cat_l2_code')"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"feature_columns size: 112\n",
"检测到 18 个可能漂移的特征: ['vol', 'pct_chg', 'turnover_rate', 'vol_std_5', 'obv', 'log(circ_mv)', 'cov', 'delta_cov', 'alpha_22_improved', 'alpha_003', 'up_limit_count_10d', 'log_close', 'up', 'down', 'mv_turnover_ratio', 'mv_adjusted_volume', 'mv_weighted_turnover', 'nonlinear_mv_volume']\n",
"feature_columns: ['pe_ttm', 'volume_ratio', 'winner_rate', 'return_skew', 'return_kurtosis', 'volume_change_rate', 'cat_volume_breakout', 'turnover_deviation', 'cat_turnover_spike', 'avg_volume_ratio', 'cat_volume_ratio_breakout', 'vol_spike', 'atr_14', 'maobv_6', 'rsi_3', 'return_5', 'return_10', 'return_20', 'std_return_5', 'std_return_15', 'std_return_90', 'std_return_90_2', 'act_factor1', 'act_factor2', 'act_factor3', 'act_factor4', 'rank_act_factor1', 'rank_act_factor2', 'rank_act_factor3', 'alpha_007', 'alpha_013', 'cat_up_limit', 'cat_down_limit', 'down_limit_count_10d', 'consecutive_up_limit', 'vol_break', 'weight_roc5', 'smallcap_concentration', 'cost_stability', 'high_cost_break_days', 'liquidity_risk', 'turnover_std', 'mv_volatility', 'volume_growth', 'mv_growth', 'momentum_factor', 'resonance_factor', 'cat_vol_spike', 'obv-maobv_6', 'std_return_5 / std_return_90', 'std_return_5 / std_return_25', 'std_return_90 - std_return_90_2', 'cat_af1', 'cat_af2', 'cat_af3', 'cat_af4', 'act_factor5', 'act_factor6', 'active_buy_volume_large', 'active_buy_volume_big', 'active_buy_volume_small', 'buy_lg_vol_minus_sell_lg_vol', 'buy_elg_vol_minus_sell_elg_vol', 'ctrl_strength', 'low_cost_dev', 'asymmetry', 'lock_factor', 'cat_vol_break', 'cost_atr_adj', 'cat_golden_resonance', 'mv_volume_ratio', 'mv_momentum', 'industry_obv', 'industry_return_5', 'industry_return_20', 'industry__ema_5', 'industry_act_factor1', 'industry_act_factor2', 'industry_act_factor3', 'industry_act_factor4', 'industry_act_factor5', 'industry_act_factor6', 'industry_rank_act_factor1', 'industry_rank_act_factor2', 'industry_rank_act_factor3', 'industry_return_5_percentile', 'industry_return_20_percentile']\n",
"2543987\n",
"最小日期: 2018-06-04\n",
"最大日期: 2022-12-30\n",
"1234512\n",
"最小日期: 2023-01-03\n",
"最大日期: 2025-03-19\n"
]
}
],
"execution_count": 78
},
{
"cell_type": "code",
"id": "8f134d435f71e9e2",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:17:54.732350Z",
"start_time": "2025-03-26T15:17:54.705934Z"
}
},
"source": [
"from sklearn.preprocessing import StandardScaler\n",
"import lightgbm as lgb\n",
"import matplotlib.pyplot as plt\n",
"from sklearn.decomposition import PCA\n",
"\n",
"\n",
"def train_light_model(train_data_df, params, feature_columns, callbacks, evals,\n",
" print_feature_importance=True, num_boost_round=100,\n",
" validation_days=180, use_pca=False, split_date=None,\n",
" label_column='label'): # 新增参数validation_days\n",
" # 确保数据按时间排序\n",
" train_data_df = train_data_df.sort_values(by='trade_date')\n",
"\n",
" numeric_columns = train_data_df.select_dtypes(include=['float64', 'int64']).columns\n",
" numeric_columns = [col for col in numeric_columns if col in feature_columns]\n",
" # X_train.loc[:, numeric_columns] = scaler.fit_transform(X_train[numeric_columns])\n",
" # X_val.loc[:, numeric_columns] = scaler.transform(X_val[numeric_columns])\n",
" train_data_df = cross_sectional_standardization(train_data_df, numeric_columns)\n",
"\n",
" # 去除标签为空的样本\n",
" train_data_df = train_data_df.dropna(subset=[label_column])\n",
" print('原始训练集大小: ', len(train_data_df))\n",
"\n",
" # 按时间顺序划分训练集和验证集\n",
" if split_date is None:\n",
" all_dates = train_data_df['trade_date'].unique() # 获取所有唯一的 trade_date\n",
" split_date = all_dates[-validation_days] # 划分点为倒数第 validation_days 天\n",
" train_data_split = train_data_df[train_data_df['trade_date'] < split_date] # 训练集\n",
" val_data_split = train_data_df[train_data_df['trade_date'] >= split_date] # 验证集\n",
"\n",
" # 打印划分结果\n",
" print(f\"划分后的训练集大小: {len(train_data_split)}, 验证集大小: {len(val_data_split)}\")\n",
"\n",
" # 提取特征和标签\n",
" X_train = train_data_split[feature_columns]\n",
" y_train = train_data_split[label_column]\n",
"\n",
" X_val = val_data_split[feature_columns]\n",
" y_val = val_data_split[label_column]\n",
"\n",
" # 标准化数值特征\n",
" scaler = StandardScaler()\n",
"\n",
" # 计算每个 trade_date 内的样本数LTR 需要 group 信息)\n",
" train_groups = train_data_split.groupby('trade_date').size().tolist()\n",
" val_groups = val_data_split.groupby('trade_date').size().tolist()\n",
"\n",
" # 处理类别特征\n",
" categorical_feature = [col for col in feature_columns if 'cat' in col]\n",
"\n",
" pca = None\n",
" if use_pca:\n",
" pca = PCA(n_components=0.95) # 或指定 n_components=固定值(如 10\n",
" numeric_features = [col for col in feature_columns if col not in categorical_feature]\n",
" numeric_pca = pca.fit_transform(X_train[numeric_features])\n",
" X_train = pd.concat([pd.DataFrame(numeric_pca, index=X_train.index), X_train[categorical_feature]], axis=1)\n",
"\n",
" numeric_pca = pca.transform(X_val[numeric_features])\n",
" X_val = pd.concat([pd.DataFrame(numeric_pca, index=X_val.index), X_val[categorical_feature]], axis=1)\n",
"\n",
" # 计算权重(基于时间)\n",
" # trade_date = train_data_split['trade_date'] # 交易日期\n",
" # weights = (trade_date - trade_date.min()).dt.days / (trade_date.max() - trade_date.min()).days + 1\n",
" # weights = train_data_split.groupby('trade_date')['std_return_5'].transform(\n",
" # lambda x: x / x.mean()\n",
" # )\n",
" ud = sorted(train_data_split[\"trade_date\"].unique().tolist())\n",
" date_weights = {date: weight * weight for date, weight in zip(ud, np.linspace(1, 10, len(ud)))}\n",
" params['weight'] = train_data_split[\"trade_date\"].map(date_weights).tolist()\n",
"\n",
" print('feature_columns size: ', len(X_train.columns.tolist()))\n",
"\n",
" train_dataset = lgb.Dataset(\n",
" X_train, label=y_train, group=train_groups,\n",
" categorical_feature=categorical_feature\n",
" )\n",
"\n",
" # weights = val_data_split.groupby('trade_date')['std_return_5'].transform(\n",
" # lambda x: x / x.mean()\n",
" # )\n",
" val_dataset = lgb.Dataset(\n",
" X_val, label=y_val, group=val_groups,\n",
" categorical_feature=categorical_feature\n",
" )\n",
"\n",
" # 训练模型\n",
" # 显式创建 LGBMRanker 模型\n",
" model = lgb.train(\n",
" params, train_dataset, num_boost_round=num_boost_round,\n",
" valid_sets=[train_dataset, val_dataset], valid_names=['train', 'valid'],\n",
" callbacks=callbacks\n",
" )\n",
"\n",
" # 打印特征重要性(如果需要)\n",
" if print_feature_importance:\n",
" lgb.plot_metric(evals)\n",
" lgb.plot_importance(model, importance_type='split', max_num_features=20)\n",
" plt.show()\n",
"\n",
" return model, scaler, pca\n"
],
"outputs": [],
"execution_count": 79
},
{
"cell_type": "code",
"id": "beeb098799ecfa6a",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:21:10.639294Z",
"start_time": "2025-03-26T15:17:54.865846Z"
}
},
"source": [
"print('train data size: ', len(train_data))\n",
"\n",
"if 'gen_volatility' in feature_columns:\n",
" feature_columns.remove('gen_volatility')\n",
"\n",
"label_gain = list(range(len(train_data['label'].unique())))\n",
"label_gain = [gain * gain for gain in label_gain]\n",
"light_params = {\n",
" 'label_gain': label_gain,\n",
" 'objective': 'lambdarank',\n",
" 'metric': 'lambdarank',\n",
" 'learning_rate': 0.03,\n",
" 'num_leaves': 1024,\n",
" 'min_data_in_leaf': 512,\n",
" 'max_depth': 32,\n",
" 'max_bin': 1024,\n",
" 'feature_fraction': 0.7,\n",
" 'bagging_fraction': 1,\n",
" 'bagging_freq': 5,\n",
" 'lambda_l1': 0.15,\n",
" 'lambda_l2': 0.15,\n",
" # 'boosting': 'dart',\n",
" 'verbosity': -1,\n",
" 'extra_trees': True,\n",
" 'max_position': 5,\n",
" 'ndcg_at': 1,\n",
" 'seed': 7\n",
"}\n",
"evals = {}\n",
"\n",
"gc.collect()\n",
"\n",
"use_pca = False\n",
"feature_contri = [2 if feat.startswith('act_factor') else 1 for feat in feature_columns]\n",
"light_params['feature_contri'] = feature_contri\n",
"print(f'feature_contri: {feature_contri}')\n",
"model, scaler, pca = train_light_model(train_data.copy().dropna(subset=['label']),\n",
" light_params, feature_columns,\n",
" [lgb.log_evaluation(period=100),\n",
" lgb.callback.record_evaluation(evals),\n",
" lgb.early_stopping(50, first_metric_only=True)\n",
" ], evals,\n",
" num_boost_round=1000, validation_days=validation_days,\n",
" print_feature_importance=True, use_pca=use_pca)\n",
"\n",
"print('train data size: ', len(train_data))"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"train data size: 2543987\n",
"feature_contri: [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]\n",
"原始训练集大小: 2543987\n",
"划分后的训练集大小: 2262535, 验证集大小: 281452\n",
"feature_columns size: 87\n",
"Training until validation scores don't improve for 50 rounds\n",
"Early stopping, best iteration is:\n",
"[18]\ttrain's ndcg@1: 0.649301\tvalid's ndcg@1: 0.586988\n",
"Evaluated only: ndcg@1\n"
]
},
{
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAjcAAAHHCAYAAABDUnkqAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAewZJREFUeJzt3Xd4lFXax/HvpPdCKr33TigCKqIggqJYURAFFRVh1WV5Xbuiq7gWRFHBVRHXFcWKBUEBKaL03juEllBCOmkzz/vHIYGYQApJJpn8Ptc1V2aeecqZk2TmnnPuc47NsiwLERERERfh5uwCiIiIiJQlBTciIiLiUhTciIiIiEtRcCMiIiIuRcGNiIiIuBQFNyIiIuJSFNyIiIiIS1FwIyIiIi5FwY2IiIi4FAU3IsL06dOx2Wzs37+/3K7x/PPPY7PZqsx5nW3//v3YbDamT59equNtNhvPP/98mZZJpKpQcCNSgXKDCJvNxtKlSws8b1kWdevWxWazcd1115XqGu+9916pPxClZGbMmMGkSZOcXQwR+QsFNyJO4OPjw4wZMwpsX7x4MYcOHcLb27vU5y5NcDNs2DBOnz5N/fr1S31dZ3n66ac5ffq0U65dnsFN/fr1OX36NMOGDSvV8adPn+bpp58u41KJVA0KbkScYMCAAXz11Vfk5OTk2z5jxgxiYmKIjo6ukHKkpaUB4O7ujo+PT5Xq3sktu4eHBz4+Pk4uTdEyMjJwOBzF3t9ms+Hj44O7u3uprufj44OHh0epjhWp6hTciDjBHXfcwcmTJ5k3b17etqysLL7++muGDBlS6DEOh4NJkybRunVrfHx8iIqK4oEHHuDUqVN5+zRo0IAtW7awePHivO6vK664AjjbJbZ48WIeeughIiMjqVOnTr7n/ppzM2fOHHr16kVgYCBBQUF06dKl0Banv1q6dCldunTBx8eHxo0b8/777xfY50I5JX/NF8nNq9m6dStDhgwhNDSUSy+9NN9zfz1+zJgxzJo1izZt2uDt7U3r1q2ZO3dugWstWrSIzp075ytrcfJ4rrjiCmbPns2BAwfy6rpBgwZ557TZbHzxxRc8/fTT1K5dGz8/P5KTk0lISGDcuHG0bduWgIAAgoKC6N+/Pxs2bCiyfoYPH05AQACHDx9m0KBBBAQEEBERwbhx47Db7cWqw927dzN8+HBCQkIIDg5mxIgRpKen5zv29OnTPPzww4SHhxMYGMj111/P4cOHlccjVYbCehEnaNCgAd27d+fzzz+nf//+gAkkkpKSuP3223n77bcLHPPAAw8wffp0RowYwcMPP8y+fft45513WLduHX/88Qeenp5MmjSJv/3tbwQEBPDUU08BEBUVle88Dz30EBERETz77LN5rR+FmT59Ovfccw+tW7fmiSeeICQkhHXr1jF37tzzBmAAmzZt4uqrryYiIoLnn3+enJwcnnvuuQLlKI1bb72Vpk2b8vLLL2NZ1gX3Xbp0Kd9++y0PPfQQgYGBvP3229x8883ExsYSFhYGwLp167jmmmuoWbMm48ePx26388ILLxAREVFkWZ566imSkpI4dOgQb775JgABAQH59nnxxRfx8vJi3LhxZGZm4uXlxdatW5k1axa33norDRs2JD4+nvfff59evXqxdetWatWqdcHr2u12+vXrR7du3Xj99deZP38+b7zxBo0bN2bUqFFFlvu2226jYcOGTJgwgbVr1/Lhhx8SGRnJv//977x9hg8fzpdffsmwYcO45JJLWLx4Mddee22R5xapNCwRqTAff/yxBVirVq2y3nnnHSswMNBKT0+3LMuybr31Vqt3796WZVlW/fr1rWuvvTbvuN9//90CrM8++yzf+ebOnVtge+vWra1evXqd99qXXnqplZOTU+hz+/btsyzLshITE63AwECrW7du1unTp/Pt63A4LvgaBw0aZPn4+FgHDhzI27Z161bL3d3dOvctZ9++fRZgffzxxwXOAVjPPfdc3uPnnnvOAqw77rijwL65z/31eC8vL2v37t152zZs2GAB1uTJk/O2DRw40PLz87MOHz6ct23Xrl2Wh4dHgXMW5tprr7Xq169fYPvChQstwGrUqFHe7zdXRkaGZbfb823bt2+f5e3tbb3wwgv5tv21fu6++24LyLefZVlWx44drZiYmAJ1UFgd3nPPPfn2u/HGG62wsLC8x2vWrLEA69FHH8233/DhwwucU6SyUreUiJPcdtttnD59mp9++omUlBR++umn87aIfPXVVwQHB9O3b19OnDiRd4uJiSEgIICFCxcW+7ojR44sMo9j3rx5pKSk8PjjjxfIZ7lQd43dbueXX35h0KBB1KtXL297y5Yt6devX7HLeD4PPvhgsfft06cPjRs3znvcrl07goKC2Lt3b15Z58+fz6BBg/K1ljRp0iSvNe1i3X333fj6+ubb5u3tjZubW14ZTp48SUBAAM2bN2ft2rXFOu9f6+Gyyy7Le12lOfbkyZMkJycD5HXdPfTQQ/n2+9vf/las84tUBuqWEnGSiIgI+vTpw4wZM0hPT8dut3PLLbcUuu+uXbtISkoiMjKy0OePHTtW7Os2bNiwyH327NkDQJs2bYp9XoDjx49z+vRpmjZtWuC55s2b8/PPP5fofH9VnLLnOje4yhUaGpqXo3Ts2DFOnz5NkyZNCuxX2LbSKKy8DoeDt956i/fee499+/bly5XJ7S67EB8fnwLdZue+rqL8tV5CQ0MBOHXqFEFBQRw4cAA3N7cCZS+rOhGpCApuRJxoyJAhjBw5kri4OPr3709ISEih+zkcDiIjI/nss88Kfb44OSK5/tqS4CznawH6a2LsuUpS9vO1TllF5OqUpcLK+/LLL/PMM89wzz338OKLL1KjRg3c3Nx49NFHizWaqrSjp4o6viLrRaS8KbgRcaIbb7yRBx54gOXLlzNz5szz7te4cWPmz59Pz549i/yAL4vh3LndOZs3by7RN/aIiAh8fX3ZtWtXged27NiR73Fui0FiYmK+7QcOHChhaUsnMjISHx8fdu/eXeC5wrYVpjR1/fXXX9O7d28++uijfNsTExMJDw8v8fnKWv369XE4HOzbty9fC1xx60SkMlDOjYgTBQQEMGXKFJ5//nkGDhx43v1uu+027HY7L774YoHncnJy8gUI/v7+BQKGkrr66qsJDAxkwoQJZGRk5HvuQt/w3d3d6devH7NmzSI2NjZv+7Zt2/jll1/y7RsUFER4eDhLlizJt/299967qLIXl7u7O3369GHWrFkcOXIkb/vu3buZM2dOsc7h7+9PUlJSia/71zr86quvOHz4cInOU15yc6P++nuYPHmyM4ojUipquRFxsrvvvrvIfXr16sUDDzzAhAkTWL9+PVdffTWenp7s2rWLr776irfeeisvXycmJoYpU6bwr3/9iyZNmhAZGcmVV15ZojIFBQXx5ptvct9999GlS5e8uWU2bNhAeno6n3zyyXmPHT9+PHPnzuWyyy7joYceIicnh8mTJ9O6dWs2btyYb9/77ruPV155hfvuu4/OnTuzZMkSdu7cWaKyXoznn3+eX3/9lZ49ezJq1CjsdjvvvPMObdq0Yf369UUeHxMTw8yZMxk7dixdunQhICDggkEqwHXXXccLL7zAiBEj6NGjB5s2beKzzz6jUaNGZfSqLk5MTAw333wzkyZN4uTJk3lDwXN/L1VpokepvhTciFQRU6dOJSYmhvfff58nn3wSDw8PGjRowJ133knPnj3z9nv22Wc5cOAAr776KikpKfTq1avEwQ3AvffeS2RkJK+88govvvginp6etGjRgr///e8XPK5du3b88ssvjB07lmeffZY6deowfvx4jh49WiC4efbZZzl+/Dhff/01X375Jf3792fOnDnnTZwuazExMcyZM4dx48bxzDPPULduXV544QW2bdvG9u3bizz+oYceYv369Xz88ce8+eab1K9fv8jg5sknnyQtLY0ZM2Ywc+ZMOnXqxOzZs3n88cfL6mVdtP/+979ER0fz+eef891339GnTx9mzpxJ8+bNq8Rs0CI2S1lkIiL5DBo0iC1bthSaO1RdrV+/no4dO/K///2PoUOHOrs4IheknBsRqdb+uujmrl27+Pnnn/OWraiOCluIdNKkSbi5uXH55Zc7oUQiJaNuKRGp1ho1asTw4cNp1KgRBw4cYMqUKXh5efHYY485u2hO8+qrr7JmzRp69+6Nh4cHc+bMYc6cOdx///3UrVvX2cUTKZK6pUSkWhsxYgQLFy4kLi4Ob29vunfvzssvv0ynTp2cXTSnmTdvHuPHj2fr1q2kpqZSr149hg0bxlNPPaWVxqVKUHAjIiIiLkU5NyIiIuJSFNyIiIiIS6l2nacOh4MjR44QGBioyahERESqCMuySElJoVatWri5XbhtptoFN0eOHFG2v4iISBV18OBB6tSpc8F9ql1wExgYCMC+ffuoUaOGk0tTOWVnZ/Prr7/mTfEvBamOiqY6KprqqGiqo6JVlzpKTk6mbt26eZ/jF1LtgpvcrqjAwECCgoKcXJrKKTs7Gz8/P4KCglz6H+ViqI6KpjoqmuqoaKqjolW3OipOSokSikVERMSlKLgRERERl6LgRkRERFxKtcu5KS673U52drazi+EU2dnZeHh4kJGRgd1uL9U5PD09cXd3L+OSiYiIFE3BzV9YlkVcXByJiYnOLorTWJZFdHQ0Bw8evKi5gEJCQoiOjtZ8QiIiUqGcHty8++67vPbaa8TFxdG+fXsmT55M165dz7v/pEmTmDJlCrGxsYSHh3PLLbcwYcIE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1wf0nl2AszOaK9IXX3xheXt7W9OnT7e2bt1q3X///VZISIgVFxfn7KI5RUpKirVu3Tpr3bp1FmBNnDjRWrdunXXgwAHLsizrlVdesUJCQqzvv//e2rhxo3XDDTdYDRs2tE6fPu3kkleMUaNGWcHBwdaiRYuso0eP5t3S09Pz9nnwwQetevXqWb/99pu1evVqq3v37lb37t2dWOqK9fjjj1uLFy+29u3bZ23cuNF6/PHHLZvNZv3666+WZal+zufc0VKWpXr6xz/+YS1atMjat2+f9ccff1h9+vSxwsPDrWPHjlmWpfqxLMtauXKl5eHhYb300kvWrl27rM8++8zy8/Oz/ve//+XtU93fs89VrYIby7KsyZMnW/Xq1bO8vLysrl27WsuXL3d2kZxm4cKFFlDgdvfdd1uWZYYWPvPMM1ZUVJTl7e1tXXXVVdaOHTucW+gKVFjdANbHH3+ct8/p06ethx56yAoNDbX8/PysG2+80Tp69KjzCl3B7rnnHqt+/fqWl5eXFRERYV111VV5gY1lqX7O56/BTXWvp8GDB1s1a9a0vLy8rNq1a1uDBw+2du/enfd8da+fXD/++KPVpk0by9vb22rRooX1n//8J9/z1f09+1w2y7Is57QZiYiIiJS9apNzIyIiItWDghsRERFxKQpuRERExKUouBERERGXouBGREREXIqCGxEREXEpCm5ERETEpSi4EZFqoUGDBkyaNMnZxRCRCqDgRkTK3PDhwxk0aBAAV1xxBY8++miFXXv69OmEhIQU2L5q1Sruv//+CiuHiDiPh7MLICJSHFlZWXh5eZX6+IiIiDIsjYhUZmq5EZFyM3z4cBYvXsxbb72FzWbDZrOxf/9+ADZv3kz//v0JCAggKiqKYcOGceLEibxjr7jiCsaMGcOjjz5KeHg4/fr1A2DixIm0bdsWf39/6taty0MPPURqaioAixYtYsSIESQlJeVd7/nnnwcKdkvFxsZyww03EBAQQFBQELfddhvx8fF5zz///PN06NCBTz/9lAYNGhAcHMztt99OSkpK3j5ff/01bdu2xdfXl7CwMPr06UNaWlo51aaIFJeCGxEpN2+99Rbdu3dn5MiRHD16lKNHj1K3bl0SExO58sor6dixI6tXr2bu3LnEx8dz22235Tv+k08+wcvLiz/++IOpU6cC4Obmxttvv82WLVv45JNP+O2333jssccA6NGjB5MmTSIoKCjveuPGjStQLofDwQ033EBCQgKLFy9m3rx57N27l8GDB+fbb8+ePcyaNYuffvqJn376icWLF/PKK68AcPToUe644w7uuecetm3bxqJFi7jpppvQcn0izqduKREpN8HBwXh5eeHn50d0dHTe9nfeeYeOHTvy8ssv522bNm0adevWZefOnTRr1gyApk2b8uqrr+Y757n5Ow0aNOBf//oXDz74IO+99x5eXl4EBwdjs9nyXe+vFixYwKZNm9i3bx9169YF4L///S+tW7dm1apVdOnSBTBB0PTp0wkMDARg2LBhLFiwgJdeeomjR4+Sk5PDTTfdRP369QFo27btRdSWiJQVtdyISIXbsGEDCxcuJCAgIO/WokULwLSW5IqJiSlw7Pz587nqqquoXbs2gYGBDBs2jJMnT5Kenl7s62/bto26devmBTYArVq1IiQkhG3btuVta9CgQV5gA1CzZk2OHTsGQPv27bnqqqto27Ytt956Kx988AGnTp0qfiWISLlRcCMiFS41NZWBAweyfv36fLddu3Zx+eWX5+3n7++f77j9+/dz3XXX0a5dO7755hvWrFnDu+++C5iE47Lm6emZ77HNZsPhcADg7u7OvHnzmDNnDq1atWLy5Mk0b96cffv2lXk5RKRkFNyISLny8vLCbrfn29apUye2bNlCgwYNaNKkSb7bXwOac61ZswaHw8Ebb7zBJZdcQrNmzThy5EiR1/urli1bcvDgQQ4ePJi3bevWrSQmJtKqVativzabzUbPnj0ZP34869atw8vLi++++67Yx4tI+VBwIyLlqkGDBqxYsYL9+/dz4sQJHA4Ho0ePJiEhgTvuuINVq1axZ88efvnlF0aMGHHBwKRJkyZkZ2czefJk9u7dy6effpqXaHzu9VJTU1mwYAEnTpwotLuqT58+tG3blqFDh7J27VpWrlzJXXfdRa9evejcuXOxXteKFSt4+eWXWb16NbGxsXz77bccP36cli1blqyCRKTMKbgRkXI1btw43N3dadWqFREREcTGxlKrVi3++OMP7HY7V199NW3btuXRRx8lJCQEN7fzvy21b9+eiRMn8u9//5s2bdrw2WefMWHChHz79OjRgwcffJDBgwcTERFRICEZTIvL999/T2hoKJdffjl9+vShUaNGzJw5s9ivKygoiCVLljBgwACaNWvG008/zRtvvEH//v2LXzkiUi5slsYtioiIiAtRy42IiIi4FAU3IiIi4lIU3IiIiIhLUXAjIiIiLkXBjYiIiLgUBTciIiLiUhTciIiIiEtRcCMiIiIuRcGNiIiIuBQFNyIiIuJSFNyIiIiIS1FwIyIiIi7l/wGZhpzPsnMuWQAAAABJRU5ErkJggg=="
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"<Figure size 640x480 with 1 Axes>"
],
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAvoAAAHHCAYAAADOE/w7AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAA7+ZJREFUeJzs3XdYFFf78PHv0osUQRQwKKiI2LF3UVGwYA8WomDEGhJ7i4pgCYoNWzQxUezGJ5YUjYqFWGOLPTZQRI2JJSoiipR9//Blfq6AFFGUvT/XtRfMzJk59727sGfPnDmjUqvVaoQQQgghhBCFik5BByCEEEIIIYTIf9LQF0IIIYQQohCShr4QQgghhBCFkDT0hRBCCCGEKISkoS+EEEIIIUQhJA19IYQQQgghCiFp6AshhBBCCFEISUNfCCGEEEKIQkga+kIIIYQQQhRC0tAXQgghPgARERGoVCpiY2MLOhQhxAdCGvpCCCHeS+kN28weY8eOfSt1Hjp0iODgYB4+fPhWjq/NEhMTCQ4OJioqqqBDEUJr6BV0AEIIIcTrTJ48GScnJ411lStXfit1HTp0iJCQEPz9/bG0tHwrdeRVr1696N69O4aGhgUdSp4kJiYSEhICgLu7e8EGI4SWkIa+EEKI91rr1q2pVatWQYfxRp48eYKpqekbHUNXVxddXd18iujdSUtL4/nz5wUdhhBaSYbuCCGE+KD99ttvNG7cGFNTU8zMzGjbti3nz5/XKHPmzBn8/f0pU6YMRkZG2Nra8umnn3L//n2lTHBwMKNGjQLAyclJGSYUGxtLbGwsKpWKiIiIDPWrVCqCg4M1jqNSqfjrr7/o2bMnRYsWpVGjRsr21atXU7NmTYyNjbGysqJ79+7cuHEj2zwzG6Pv6OhIu3btiIqKolatWhgbG1OlShVleMymTZuoUqUKRkZG1KxZk5MnT2oc09/fnyJFinD16lU8PT0xNTXF3t6eyZMno1arNco+efKEESNG4ODggKGhIS4uLsyaNStDOZVKRWBgIGvWrKFSpUoYGhqyZMkSbGxsAAgJCVGe2/TnLSevz8vPbXR0tHLWxcLCgj59+pCYmJjhOVu9ejV16tTBxMSEokWL0qRJE3bu3KlRJifvHyE+VNKjL4QQ4r326NEj7t27p7GuWLFiAKxatQo/Pz88PT2ZMWMGiYmJLF68mEaNGnHy5EkcHR0BiIyM5OrVq/Tp0wdbW1vOnz/Pt99+y/nz5/njjz9QqVR07tyZy5cvs27dOubOnavUYWNjw927d3Md98cff4yzszNfffWV0hieNm0aEydOxMfHh4CAAO7evcuCBQto0qQJJ0+ezNNwoejoaHr27MmAAQP45JNPmDVrFt7e3ixZsoQvv/ySwYMHAxAaGoqPjw+XLl1CR+f/+vlSU1Px8vKiXr16hIWFsX37diZNmkRKSgqTJ08GQK1W0759e/bu3Uvfvn2pXr06O3bsYNSoUdy6dYu5c+dqxLRnzx42bNhAYGAgxYoVo1q1aixevJhBgwbRqVMnOnfuDEDVqlWBnL0+L/Px8cHJyYnQ0FD+/PNPvvvuO4oXL86MGTOUMiEhIQQHB9OgQQMmT56MgYEBR44cYc+ePbRq1QrI+ftHiA+WWgghhHgPLV++XA1k+lCr1erHjx+rLS0t1f369dPY759//lFbWFhorE9MTMxw/HXr1qkB9b59+5R1M2fOVAPqa9euaZS9du2aGlAvX748w3EA9aRJk5TlSZMmqQF1jx49NMrFxsaqdXV11dOmTdNYf/bsWbWenl6G9Vk9Hy/HVrp0aTWgPnTokLJux44dakBtbGysvn79urL+m2++UQPqvXv3Kuv8/PzUgPrzzz9X1qWlpanbtm2rNjAwUN+9e1etVqvVW7ZsUQPqqVOnasTUtWtXtUqlUkdHR2s8Hzo6Ourz589rlL17926G5ypdTl+f9Of2008/1SjbqVMntbW1tbJ85coVtY6OjrpTp07q1NRUjbJpaWlqtTp37x8hPlQydEcIIcR7bdGiRURGRmo84EUv8MOHD+nRowf37t1THrq6utStW5e9e/cqxzA2NlZ+f/bsGffu3aNevXoA/Pnnn28l7oEDB2osb9q0ibS0NHx8fDTitbW1xdnZWSPe3KhYsSL169dXluvWrQtA8+bNKVWqVIb1V69ezXCMwMBA5ff0oTfPnz9n165dAGzbtg1dXV2++OILjf1GjBiBWq3mt99+01jftGlTKlasmOMccvv6vPrcNm7cmPv37xMfHw/Ali1bSEtLIygoSOPsRXp+kLv3jxAfKhm6I4QQ4r1Wp06dTC/GvXLlCvCiQZsZc3Nz5ff//vuPkJAQ1q9fz507dzTKPXr0KB+j/T+vzhR05coV1Go1zs7OmZbX19fPUz0vN+YBLCwsAHBwcMh0/YMHDzTW6+joUKZMGY115cuXB1CuB7h+/Tr29vaYmZlplHN1dVW2v+zV3LOT29fn1ZyLFi0KvMjN3NycmJgYdHR0XvtlIzfvHyE+VNLQF0II8UFKS0sDXoyztrW1zbBdT+//PuJ8fHw4dOgQo0aNonr16hQpUoS0tDS8vLyU47zOq2PE06Wmpma5z8u91OnxqlQqfvvtt0xnzylSpEi2cWQmq5l4slqvfuXi2bfh1dyzk9vXJz9yy837R4gPlbyLhRBCfJDKli0LQPHixfHw8Miy3IMHD9i9ezchISEEBQUp69N7dF+WVYM+vcf41RtpvdqTnV28arUaJycnpcf8fZCWlsbVq1c1Yrp8+TKAcjFq6dKl2bVrF48fP9bo1b948aKyPTtZPbe5eX1yqmzZsqSlpfHXX39RvXr1LMtA9u8fIT5kMkZfCCHEB8nT0xNzc3O++uorkpOTM2xPnyknvff31d7e8PDwDPukz3X/aoPe3NycYsWKsW/fPo31X3/9dY7j7dy5M7q6uoSEhGSIRa1WZ5hK8l1auHChRiwLFy5EX1+fFi1aANCmTRtSU1M1ygHMnTsXlUpF69ats63DxMQEyPjc5ub1yamOHTuio6PD5MmTM5wRSK8np+8fIT5k0qMvhBDig2Rubs7ixYvp1asXNWrUoHv37tjY2BAXF8fWrVtp2LAhCxcuxNzcnCZNmhAWFkZycjIlS5Zk586dXLt2LcMxa9asCcD48ePp3r07+vr6eHt7Y2pqSkBAANOnTycgIIBatWqxb98+pec7J8qWLcvUqVMZN24csbGxdOzYETMzM65du8bmzZvp378/I0eOzLfnJ6eMjIzYvn07fn5+1K1bl99++42tW7fy5ZdfKnPfe3t706xZM8aPH09sbCzVqlVj586d/PTTTwwdOlTpHX8dY2NjKlasyA8//ED58uWxsrKicuXKVK5cOcevT06VK1eO8ePHM2XKFBo3bkznzp0xNDTk2LFj2NvbExoamuP3jxAftAKa7UcIIYR4rfTpJI8dO/bacnv37lV7enqqLSws1EZGRuqyZcuq/f391cePH1fK3Lx5U92pUye1paWl2sLCQv3xxx+r//7770yne5wyZYq6ZMmSah0dHY3pLBMTE9V9+/ZVW1hYqM3MzNQ+Pj7qO3fuZDm9ZvrUlK/auHGjulGjRmpTU1O1qampukKFCurPPvtMfenSpRw9H69Or9m2bdsMZQH1Z599prEufYrQmTNnKuv8/PzUpqam6piYGHWrVq3UJiYm6hIlSqgnTZqUYVrKx48fq4cNG6a2t7dX6+vrq52dndUzZ85Upqt8Xd3pDh06pK5Zs6bawMBA43nL6euT1XOb2XOjVqvVy5YtU7u5uakNDQ3VRYsWVTdt2lQdGRmpUSYn7x8hPlQqtfodXJUjhBBCiPeOv78/P/74IwkJCQUdihDiLZAx+kIIIYQQQhRC0tAXQgghhBCiEJKGvhBCCCGEEIWQjNEXQgghhBCiEJIefSGEEEIIIQohaegLIYQQQghRCMkNs4TQUmlpafz999+YmZlleWt6IYQQQrxf1Go1jx8/xt7eHh2d1/fZS0NfCC31999/4+DgUNBhCCGEECIPbty4wUcfffTaMtLQF0JLmZmZAXDt2jWsrKwKOJq3Lzk5mZ07d9KqVSv09fULOpy3Tpvy1aZcQfIt7LQpX23KFfIv3/j4eBwcHJTP8deRhr4QWip9uI6ZmRnm5uYFHM3bl5ycjImJCebm5lrzgaIt+WpTriD5FnbalK825Qr5n29Oht3KxbhCCCGEEEIUQtLQF0IIIYQQohCShr4QQgghhBCFkDT0hRBCCCGEKISkoS+EEEIIIUQhJA19IYQQQgghCiFp6AshhBBCCFEISUNfCCGEEEKIQkga+kIIIYQQQhRC0tAXQgghhBDiJfv27cPb2xt7e3tUKhVbtmzR2O7v749KpdJ4eHl5aZSZNm0aDRo0wMTEBEtLy3cX/EukoS/EB2DLli2UK1cOXV1dhg4dWtDhCCGEEIXakydPqFatGosWLcqyjJeXF7dv31Ye69at09j+/PlzPv74YwYNGvS2w82SXoHVLEQhFBwczJYtWzh16lS+HnfAgAH06dOHL774AjMzM6Kiopg7dy5Hjx4lPj4eZ2dnRo0aha+vb77WK4QQQmij1q1b07p169eWMTQ0xNbWNsvtISEhAERERORnaLkiPfpCvOcSEhK4c+cOnp6e2NvbY2ZmxqFDh6hatSobN27kzJkz9OnTh969e/Prr78WdLhCCCGEVoiKiqJ48eK4uLgwaNAg7t+/X9AhZSA9+kK8Ii0tjVmzZvHtt99y48YNSpQowYABAxg/fjxjxoxh8+bN3Lx5E1tbW3x9fQkKCkJfX5+IiAjl27tKpQJg+fLl+Pv7v7a+OXPmsHz5cq5evYqVlRXe3t6EhYVRpEgRoqKiaNasGQDNmzcHYO/evXz55ZcaxxgyZAg7d+5k06ZNtGvXLlf51g3dTYqeaa72+RAZ6qoJqwOVg3eQlKoq6HDeOm3KV5tyBcm3sNOmfN+XXGOnt831Pl5eXnTu3BknJydiYmL48ssvad26NYcPH0ZXV/ctRJk30tAX4hXjxo1j6dKlzJ07l0aNGnH79m0uXrwIgJmZGREREdjb23P27Fn69euHmZkZo0ePplu3bpw7d47t27eza9cuACwsLLKtT0dHh/nz5+Pk5MTVq1cZPHgwo0eP5uuvv6ZBgwZcunQJFxcXNm7cSIMGDbCyssr0OI8ePcLV1TXLepKSkkhKSlKW4+PjATDUUaOrq87x8/OhMtRRa/ws7LQpX23KFSTfwk6b8n1fck1OTs62TEpKika5Ll26KL9XqFABV1dXKlSowK5du5SOuXSpqaka9eSkvjeNN51KrVYX/neSEDn0+PFjbGxsWLhwIQEBAdmWnzVrFuvXr+f48eNA/ozR//HHHxk4cCD37t0D4OHDhxQtWpS9e/fi7u6e6T4bNmygV69e/Pnnn1SqVCnTMsHBwcoZh5etXbsWExOTPMcrhBBCFGYdO3Zk7Nix1KtX77Xlevfuja+vL56enhrrd+/ezffff8/atWvzJZ7ExER69uzJo0ePMDc3f21Z6dEX4iUXLlwgKSmJFi1aZLr9hx9+YP78+cTExJCQkEBKSkq2f2TZ2bVrF6GhoVy8eJH4+HhSUlJ49uwZiYmJOWqA7927lz59+rB06dIsG/nw4kzF8OHDleX4+HgcHBxo1qwZ1tbWb5TDhyA5OZnIyEhatmyJvr5+QYfz1mlTvtqUK0i+hZ025fsh5VqzZk3atGmT5fabN2/y+PFjPDw8MpS7d+8e+vr6tGzZMl/yTT8jnxPS0BfiJcbGxlluO3z4ML6+voSEhODp6YmFhQXr169n9uzZea4vNjaWdu3aMWjQIKZNm4aVlRUHDhygb9++PH/+PNuG/u+//463tzdz586ld+/ery1raGiIoaFhhvX6+vrv/T/Y/CT5Fl7alCtIvoWdNuX7PuaakJBAdHS0snzjxg3Onz+PlZUVVlZWhISE0KVLF2xtbYmJiWH06NGUK1eOtm3bKrnExcXx33//cevWLVJTUzl//jxXr14lKSnpjc6k5+a5koa+EC9xdnbG2NiY3bt3Zxi6c+jQIUqXLs348eOVddevX9coY2BgoIzFy4kTJ06QlpbG7Nmz0dF5MQnWhg0bcrRvVFQU7dq1Y8aMGfTv3z/HdQohhBDi9Y4fP65MhgEoZ8T9/PxYvHgxZ86cYcWKFTx8+BB7e3tatWrFlClTNDrUgoKCWLFihbJcp04dAKpUqYKHh8c7yUMa+kK8xMjIiDFjxjB69GgMDAxo2LAhd+/e5fz58zg7OxMXF8f69eupXbs2W7duZfPmzRr7Ozo6cu3aNU6dOsVHH32EmZlZpr3o6cqVK0dycjILFizA29ubgwcPsmTJkmzj3Lt3L+3atWPIkCF06dKFf/75B3jxRSOri3WFEEIIkTPu7u687jLWHTt2ZHuMiIgIjTn0k5OT2bZtG02bNs2PEHNE5tEX4hUTJ05kxIgRBAUF4erqSrdu3bhz5w7t27dn2LBhBAYGUr16dQ4dOsTEiRM19u3SpQteXl40a9YMGxubDHfJe1W1atWYM2cOM2bMoHLlyqxZs4bQ0NBsY1yxYgWJiYmEhoZiZ2enPDp37vxGuQshhBCi8JAefSFeoaOjw/jx4zWG6KQLCwsjLCxMY93QoUOV3w0NDfnxxx9zVd+wYcMYNmyYxrpevXopv1taWmboVXi1l0AIIYQQ4lXSoy+EEEIIIUQhJA19Id6iNWvWUKRIkUwfr5sKUwghhBDiTcnQHSHeovbt21O3bt1Mt71vU4kJIYQQonCRhr4Qb5GZmRlmZmYFHYYQQgghtJAM3RFCCCGEEKIQkoa+EB+ALVu2UK5cOXR1dTVm+RFCCCFE/ti3bx/e3t7Y29ujUqnYsmWLxnZ/f39UKpXGw8vLS6PMf//9h6+vL+bm5lhaWtK3b18SEhLeYRaapKEvRD4KDg6mevXq+X7cAQMG0LVrV27cuMGUKVM0tkVHR2NmZoalpWW+1yuEEEJoiydPnlCtWjUWLVqUZRkvLy9u376tPF69X46vry/nz58nMjKSX3/9lX379hXo3etljL4Q77mEhATu3LmDp6cn9vb2GtuSk5Pp0aMHjRs35tChQwUUoRBCCPHha926Na1bt35tGUNDQ2xtbTPdduHCBbZv386xY8eoVasWAAsWLKBNmzbMmjULGxubfI85O9KjL8Qr0tLSCAsLo1y5chgaGlKqVCmmTZsGwJgxYyhfvjwmJiaUKVOGiRMnkpycDLy4iVVISAinT59WTunl5KZWc+bMoUqVKpiamuLg4MDgwYOV03xRUVHKxbzNmzdHpVIRFRWl7DthwgQqVKiAj49P/j4JQgghhMggKiqK4sWL4+LiwqBBg7h//76y7fDhw1haWiqNfAAPDw90dHQ4cuRIQYQrPfpCvGrcuHEsXbqUuXPn0qhRI27fvs3FixeBF7PoREREYG9vz9mzZ+nXrx9mZmaMHj2abt26ce7cObZv386uXbsAsLCwyLY+HR0d5s+fj5OTE1evXmXw4MGMHj2ar7/+mgYNGnDp0iVcXFzYuHEjDRo0wMrKCoA9e/bwv//9j1OnTrFp06Zs60lKSiIpKUlZjo+PB6DJjF2k6Jvm+nn60BjqqJlSC2pO3k5Smqqgw3nrtClfbcoVJN/CTpvyLchczwV7ZlsmJSVF6cyDF4329u3b4+joyNWrV5k4cSJeXl7s378fXV1dbt26hY2NjcY+AFZWVty6dUtZ/+r23MrN/iq1Wq1+o9qEKEQeP36MjY0NCxcuJCAgINvys2bNYv369Rw/fhx4MUZ/y5YtnDp1Ks8x/PjjjwwcOJB79+4B8PDhQ4oWLcrevXtxd3cH4P79+7i5ubF69WqaNGlCREQEQ4cO5eHDh1keNzg4mJCQkAzr165di4mJSZ7jFUIIIQqbjh07MnbsWOrVq5dlmX/++YeBAwcSEhJCtWrV+N///sfevXv5+uuvNcr5+fnRvXv3bIcF5VRiYiI9e/bk0aNHmJubv7as9OgL8ZILFy6QlJREixYtMt3+ww8/MH/+fGJiYkhISCAlJSXbP7Ls7Nq1i9DQUC5evEh8fDwpKSk8e/aMxMTELBvg/fr1o2fPnjRp0iTH9YwbN47hw4cry/Hx8Tg4ODD1pA4p+rpvlMOH4EXPURoTj+sU+l4y0K58tSlXkHwLO23KtyBzzUmPfs2aNWnTps1ry0yYMIFixYrRpk0b7ty5w9atWzX2SUlJISEhgRYtWtCyZUsiIyNp2bLlG900M/2MfE5IQ1+IlxgbG2e57fDhw/j6+hISEoKnpycWFhasX7+e2bNn57m+2NhY2rVrx6BBg5g2bRpWVlYcOHCAvn378vz58ywb+nv27OHnn39m1qxZAKjVatLS0tDT0+Pbb7/l008/zbCPoaEhhoaGGdbvG+OBtbV1nnP4UCQnJ7Nt2zZOBHlpxV2JtSlfbcoVJN/CTpvyfd9z1dPTe21cN2/e5P79+3z00Ufo6+vTqFEjHj58yJkzZ6hZsyYAe/fuJS0tjYYNGyrH0tfXf6N8c7OvNPSFeImzszPGxsbs3r07w9CdQ4cOUbp0acaPH6+su379ukYZAwMDUlNTc1zfiRMnSEtLY/bs2ejovLg2fsOGDdnud/jwYY16fvrpJ2bMmMGhQ4coWbJkjusXQgghxAsJCQlER0cry9euXePUqVNYWVlhZWVFSEgIXbp0wdbWlpiYGEaPHk25cuXw9HxxdsDV1RUvLy/69evHkiVLSE5OJjAwkO7du2Nvb//GY/PzQhr6QrzEyMiIMWPGMHr0aAwMDGjYsCF3797l/PnzODs7ExcXx/r166lduzZbt25l8+bNGvs7Ojoq/xg++ugjzMzMMu1FT1euXDmSk5NZsGAB3t7eHDx4kCVLlmQbp6urq8by8ePH0dHRoXLlynlLXAghhNByx48fp1mzZspy+nBXPz8/Fi9ezJkzZ1ixYgUPHz7E3t6eVq1aMWXKFI3P+TVr1hAYGEiLFi3Q0dGhS5cuzJ8//53nkk4a+kK8YuLEiejp6REUFMTff/+NnZ0dAwcOpG/fvgwbNozAwECSkpJo27YtEydOJDg4WNm3S5cubNq0iWbNmvHw4UOWL1+Ov79/lnVVq1aNOXPmMGPGDMaNG0eTJk0IDQ2ld+/ebz9RIYQQQijc3d153Rw1O3bsyPYYVlZWrF27Nj/DeiPS0BfiFTo6OowfP15jiE66sLAwwsLCNNYNHTpU+d3Q0JAff/wxV/UNGzaMYcOGaazr1auX8rulpeVr//HAi9tyv+4LhRBCCCG0j9wwSwghhBBCiEJIGvpCvEVr1qyhSJEimT4qVapU0OEJIYQQohCToTtCvEXt27enbt26mW57H6cSE0IIIUThIQ19Id4iMzMzzMzMCjoMIYQQQmghGbojhBBCCCFEISQNfSGEEEIIUejs27cPb29v7O3tUalUbNmyJcuyAwcORKVSER4enmHb1q1bqVu3LsbGxhQtWpSOHTu+tZjzmzT0hXhHYmNjUalUnDp1qqBDEUIIIQq9J0+eUK1aNRYtWvTacps3b+aPP/7A3t4+w7aNGzfSq1cv+vTpw+nTpzl48CA9e/Z8WyHnOxmjLz547u7uVK9ePdNv4UIIIYTQTq1bt6Z169avLXPr1i0+//xzduzYQdu2bTW2paSkMGTIEGbOnEnfvn2V9RUrVnwr8b4N0qMv3mvPnz8vlHUJIYQQomClpaXRq1cvRo0alemU13/++Se3bt1CR0cHNzc37OzsaN26NefOnSuAaPNGevTFe8Xd3Z3KlSujp6fH6tWrqVKlCgsWLGDUqFHs378fU1NTWrVqxdy5cylWrBj+/v78/vvv/P7778ybNw+Aa9euERUVxdChQ3n48KFy7C1bttCpUyflLrPBwcFs2bKFwMBApk2bxvXr10lLS0OlUrF06VK2bt3Kjh07KFmyJLNnz6Z9+/bZxv/gwQMCAwPZuXMnCQkJfPTRR3z55Zf06dMnQ9nU1FT69evHoUOH2LlzJ6VKleKnn34iJCSEv/76C3t7e/z8/Bg/fjx6enqMHDmSixcv8uuvvwIQHh7OsGHD+O233/Dy8gKgXLlyjB07loCAgBw/53VDd5OiZ5rj8h8qQ101YXWgcvAOklJVBR3OW6dN+WpTriD5FnbalG9+5ho7vW32hV4xY8YM9PT0+OKLLzLdfvXqVeBFe2HOnDk4Ojoye/Zs3N3duXz5MlZWVm8U87sgDX3x3lmxYgWDBg3i4MGDPHz4kObNmxMQEMDcuXN5+vQpY8aMwcfHhz179jBv3jwuX75M5cqVmTx5MgA2NjY5ris6OpqNGzeyadMmdHV1lfUhISGEhYUxc+ZMFixYgK+vL9evX8/2j3rixIn89ddf/PbbbxQrVozo6GiePn2aoVxSUhI9evQgNjaW/fv3Y2Njw/79++nduzfz58+ncePGxMTE0L9/fwAmTZpE06ZN+e6770hNTUVXV5fff/+dYsWKERUVhZeXF7du3SImJgZ3d/dMY0tKSiIpKUlZjo+PB8BQR42urjrHz9mHylBHrfGzsNOmfLUpV5B8Czttyjc/c01OTs62TEpKilLuzz//ZN68eRw5coSUlBSlTGpqqlIm/Uz/2LFjlc6+b7/9FicnJ9avX0+/fv3yFGNOYs3JcXJCGvrivePs7ExYWBgAU6dOxc3Nja+++krZvmzZMhwcHLh8+TLly5fHwMAAExMTbG1tc13X8+fPWblyZYYvB/7+/vTo0QOAr776ivnz53P06FGl5zwrcXFxuLm5UatWLQAcHR0zlElISKBt27YkJSWxd+9eLCwsgBdfLsaOHYufnx8AZcqUYcqUKYwePZpJkybRuHFjHj9+zMmTJ6lZsyb79u1j1KhRyiwCUVFRlCxZknLlymUaW2hoKCEhIRnWT3BLw8Qk9bV5FSZTaqUVdAjvlDblq025guRb2GlTvvmR67Zt27Itc+LECeVmlT///DN37tyhTJkyyva0tDRGjx7NjBkzWLp0KXFxcQA8fPhQ4/hFixZl7969lCxZMk+xRkZG5mm/dImJiTkuKw198d6pWbOm8vvp06fZu3cvRYoUyVAuJiaG8uXLv1FdpUuXzvQMQNWqVZXfTU1NMTc3586dO9keb9CgQXTp0oU///yTVq1a0bFjRxo0aKBRpkePHnz00Ufs2bMHY2NjZX361fzTpk1T1qWmpvLs2TMSExOxtLSkWrVqREVFYWBggIGBAf3792fSpEkkJCTw+++/07Rp0yxjGzduHMOHD1eW4+PjcXBwYOpJHVL0dbPcr7Aw1FEzpVYaE4/rkJRWuE+Hg3blq025guRb2GlTvvmZ67lgz2zL1KxZkzZt2gBQt25dAgMDNba3a9eOnj174ufnh4uLC40aNWLq1KlYW1sr+yUnJ/Po0SOaN2+urMup5ORkIiMjadmypfKFIy/Sz8jnhDT0xXvH1PT/xosnJCTg7e3NjBkzMpSzs7PL8hg6OjrKWPx0mZ3qermul736B6hSqUhLy77HoXXr1ly/fp1t27YRGRlJixYt+Oyzz5g1a5ZSpk2bNqxevZrDhw/TvHlzZX1CQgIhISF07tw5w3GNjIyAF9cwREVFYWhoSNOmTbGyssLV1ZUDBw7w+++/M2LEiCxjMzQ0xNDQMMP6fWM8sLa2zja3D11ycjLbtm3jRJDXG/2D/VBoU77alCtIvoWdNuX7tnNNSEggOjpaWb5x4wbnz5/HysqKUqVKZRgJoK+vT8mSJalcuTIA1tbWDBw4kMmTJ+Po6Ejp0qWZOXMmAN27d89zzPr6+m+Ub272lYa+eK/VqFGDjRs34ujoiJ5e5m9XAwMDUlM1h57Y2Njw+PFjnjx5ojTm39X89TY2Nvj5+eHn50fjxo0ZNWqURkN/0KBBVK5cmfbt27N161alF75GjRpcunQpy6E3AE2bNmXZsmXo6ekpw4jc3d1Zt24dly9fznJ8vhBCCKFtjh8/TrNmzZTl9LPafn5+RERE5OgYM2fORE9Pj169evH06VPq1q3Lnj17KFq06NsIOd9JQ1+81z777DOWLl1Kjx49GD16NFZWVkRHR7N+/Xq+++47dHV1cXR05MiRI8TGxlKkSBGsrKyoW7cuJiYmfPnll3zxxRccOXIkx3/UbyIoKIiaNWtSqVIlkpKS+PXXX3F1dc1Q7vPPPyc1NZV27drx22+/0ahRI4KCgmjXrh2lSpWia9eu6OjocPr0ac6dO8fUqVMBaNKkCY8fP+bXX39l+vTpwIuGfteuXbGzs3vjoUxCCCFEYeHu7p7h7P7rxMbGZlinr6/PrFmzNDrsPiQyj754r9nb23Pw4EFSU1Np1aoVVapUYejQoVhaWqKj8+LtO3LkSHR1dalYsSI2NjbExcVhZWXF6tWr2bZtG1WqVGHdunUEBwe/9XgNDAwYN24cVatWpUmTJujq6rJ+/fpMyw4dOpSQkBDatGnDoUOH8PT05Ndff2Xnzp3Url2bevXqMXfuXEqXLq3sU7RoUapUqYKNjQ0VKlQAXjT+09LSXjs+XwghhBDaR6XOzVcdIUShER8fj4WFBffu3dOqMfpt2rQp9ONeQbvy1aZcQfIt7LQpX23KFfIv3/TP70ePHmFubv7astKjL4QQQgghRCEkDX0hcmHgwIEUKVIk08fAgQMLOjwhhBBCCIVcjCtELkyePJmRI0dmui2702dCCCGEEO+SNPSFyIXixYtTvHjxgg5DCCGEECJbMnRHCCGEEEKIQqhAG/ru7u4MHTq0IEN4rYiICCwtLQs6DA2Ojo6Eh4e/teMHBwdTvXr1t3b8d+nV1y8/c4uNjUWlUr2zm3DlhL+/Px07dizoMIQQQmRj3759eHt7Y29vj0qlYsuWLRrbDx8+TJs2bbC2tn7tZ036HdZNTU0xNzenSZMmPH369O0nID4Y0qMvNIwcOZLdu3cXdBhCCCFEofXkyROqVavGokWLMt3+7NkzGjRowIwZM7I8xuHDh/Hy8qJVq1YcPXqUY8eOERgYqNxjRgiQMfriFekzyAghhBDi7WjdujWtW7fOcnuzZs1o06YNt27dyrLMsGHD+OKLLxg7dqyyzsXFJV/jFB++Av/al5KSQmBgIBYWFhQrVoyJEycqtyvO7HSWpaUlERERADRv3pzAwECN7Xfv3sXAwCBHvdJJSUmMHDmSkiVLYmpqSt26dYmKinrtPlOnTqV48eKYmZkREBDA2LFjczQcZOfOnRgZGfHw4UON9UOGDKF58+bK8saNG6lUqRKGhoY4Ojoye/bsbI+dFZVKxTfffEO7du0wMTHB1dWVw4cPEx0djbu7O6ampjRo0ICYmBhln1eHt6QPB5k1axZ2dnZYW1vz2WefkZycrFHP616n58+fExgYiJ2dHUZGRpQuXZrQ0NBs41er1QQHB1OqVCkMDQ2xt7fniy++ULbn5fXLje+++w5XV1eMjIyoUKECX3/99WvL//zzzzg7O2NkZESzZs1YsWIFKpUqw2v+qvj4eIyNjfntt9801m/evBkzMzMSExMBOHv2LM2bN8fY2Bhra2v69+9PQkLCG+UohBDiw3Pnzh2OHDlC8eLFadCgASVKlKBp06YcOHCgoEMT75kC79FfsWIFffv25ejRoxw/fpz+/ftTqlQp+vXrl+2+AQEBBAYGMnv2bAwNDQFYvXo1JUuW1Gg8ZyUwMJC//vqL9evXY29vz+bNm/Hy8uLs2bM4OztnKL9mzRqmTZvG119/TcOGDVm/fj2zZ8/Gyckp27patGiBpaUlGzdupG/fvgCkpqbyww8/MG3aNABOnDiBj48PwcHBdOvWjUOHDjF48GCsra3x9/fPto7MTJkyhTlz5jBnzhzGjBlDz549KVOmDOPGjaNUqVJ8+umnBAYGZmhkvmzv3r3Y2dmxd+9eoqOj6datG9WrV8/RawQwf/58fv75ZzZs2ECpUqW4ceMGN27cyHa/jRs3MnfuXNavX0+lSpX4559/OH36tLI9t69fbqxZs4agoCAWLlyIm5sbJ0+epF+/fpiamuLn55eh/LVr1+jatStDhgwhICCAkydPZjkN56vMzc1p164da9eu1ejhWbNmDR07dsTExIQnT57g6elJ/fr1OXbsGHfu3FHe/+lfqPKqbuhuUvRM3+gYHwJDXTVhdaBy8A6SUlUFHc5bp035alOuIPl+iGKnt83X4129ehV40Tk3a9YsqlevzsqVK2nRogXnzp17489AUXgUeEPfwcGBuXPnolKpcHFx4ezZs8ydOzdHjcjOnTsTGBjITz/9hI+PD/DiAkx/f39Uqtf/M4iLi2P58uXExcVhb28PvBifvn37dpYvX85XX32VYZ8FCxbQt29f+vTpA0BQUBA7d+7MUa+qrq4u3bt3Z+3atUpDf/fu3Tx8+JAuXboAMGfOHFq0aMHEiRMBKF++PH/99RczZ87Mc0O/T58+ynMzZswY6tevz8SJE/H09ARenFFIzycrRYsWZeHChejq6lKhQgXatm3L7t27c9zQj4uLw9nZmUaNGqFSqShdunSO97O1tcXDwwN9fX1KlSpFnTp1lG25ff1yY9KkScyePZvOnTsD4OTkxF9//cU333yTaUP/m2++wcXFhZkzZwIvTp+eO3dO+RKXHV9fX3r16kViYiImJibEx8ezdetWNm/eDMDatWt59uwZK1euxNT0RaN84cKFeHt7M2PGDEqUKJFtHUlJSSQlJSnL8fHxABjqqNHVVecozg+ZoY5a42dhp035alOuIPl+iF4+C56ZlJQUpczLPzP7HV6cKYcXHZ6ffPIJAGFhYezatYulS5fm+LOnoL2ac2GXX/nmZv8Cb+jXq1dPo1Fev359Zs+eTWpqarb7GhkZ0atXL5YtW4aPjw9//vkn586d4+eff85237Nnz5Kamkr58uU11iclJWFtbZ3pPpcuXWLw4MEa6+rUqcOePXuyrQ9eNObq1avH33//jb29PWvWrKFt27bKzDAXLlygQ4cOGvs0bNiQ8PBwUlNT0dXVzVE9L6tatarye3pjsEqVKhrrnj17Rnx8fJY3fKpUqZJG3XZ2dpw9ezbHMfj7+9OyZUtcXFzw8vKiXbt2tGrVKtv9Pv74Y8LDwylTpgxeXl60adMGb29v9PT08vT65dSTJ0+IiYmhb9++Gl9mUlJSsLCwyHSfS5cuUbt2bY116V9KcqJNmzbo6+vz888/0717dzZu3Ii5uTkeHh7Ai/dGtWrVlEY+vHhvpKWlcenSpRw19ENDQwkJCcmwfoJbGiYm2f+9FRZTaqUVdAjvlDblq025guT7Idm2bdtrt584cQJ9fX2NdZGRkfz7778AHDhwgL///lvZlr7++fPnGse2sLDgyJEj2db3vomMjCzoEN6pN803fUhvThR4Q/91VCqVMl4/3avfYgICAqhevTo3b95k+fLlNG/ePEc9xgkJCejq6nLixIkMDei3dTFq7dq1KVu2LOvXr2fQoEFs3rz5jYddZOflfxzpX6gyW5eWlvU/0Ff/+ahUKo3y2b1ONWrU4Nq1a/z222/s2rULHx8fPDw8+PHHH18bu4ODA5cuXWLXrl1ERkYyePBgZs6cye+///5WX7/0MzRLly6lbt26Gtvy8mUrJwwMDOjatStr165Vzvx069YNPb38+xMdN24cw4cPV5bj4+NxcHCgWbNmb/zl6EOQnJxMZGQkLVu2zPCeLoy0KV9tyhUk38KoZs2atGnTBtDMN/1i3EaNGmlcP6dWqwkJCcHY2FjZD16cjfb09NRY9z7Thtf2ZfmVb/oZ+Zwo8Ib+kSNHNJb/+OMPnJ2d0dXVxcbGhtu3byvbrly5kuFbTJUqVahVqxZLly5l7dq1LFy4MEf1urm5kZqayp07d2jcuHGO9nFxceHYsWP07t1bWXfs2LEc7ZvO19eXNWvW8NFHH6Gjo0Pbtv83bs/V1ZWDBw9qlD948CDly5d/aw3M/JCT18nc3Jxu3brRrVs3unbtipeXF//99x9WVlavPbaxsTHe3t54e3vz2WefUaFCBc6ePZun1y+nSpQogb29PVevXsXX1zdH+7i4uGToQcnLe6Nly5acP3+ePXv2MHXqVGWbq6srERERPHnyROnVP3jwIDo6OjmeZcHQ0FC5luVl+vr6WvEPNp3kW3hpU64g+X7IEhISiI6OVpZv3LjB+fPnsbKyws7OjsePH3P+/Hnu3r0LvBiTr6+vj62tLba2tgCMGjWKSZMmUaNGDapXr86KFSu4dOkSGzdu/OCep8L02ubEm+abm30LvKEfFxfH8OHDGTBgAH/++ScLFixQZppp3rw5CxcupH79+qSmpjJmzJhMk0u/KNHU1JROnTrlqN7y5cvj6+tL7969mT17Nm5ubty9e5fdu3dTtWpVjQZ4us8//5x+/fpRq1YtGjRowA8//MCZM2coU6ZMjvP19fUlODiYadOm0bVrV42G14gRI6hduzZTpkyhW7duHD58mIULF2Y720tBy+51mjNnDnZ2dri5uaGjo8P//vc/bG1ts70ZWUREBKmpqdStWxcTExNWr16NsbExpUuXxtraOtevX26EhITwxRdfYGFhgZeXF0lJSRw/fpwHDx5o9IqnGzBggHLBc9++fTl16pRytia760XSNWnSBFtbW3x9fXFyctI4m+Dr68ukSZPw8/MjODiYu3fv8vnnn9OrV68cDdsRQgjx/jh+/DjNmjVTltM/V/z8/Fi6dClHjx6lV69eyvbu3bsDL3rsg4ODARg6dCjPnj1j2LBh/Pfff1SrVo3IyEjKli377hIR770Cn16zd+/ePH36lDp16vDZZ58xZMgQ+vfvD8Ds2bNxcHCgcePG9OzZk5EjR2JiYpLhGD169EBPT48ePXpgZGSU47qXL19O7969GTFiBC4uLnTs2JFjx45RqlSpTMv7+voybtw4Ro4cqQxH8ff3z1Wd5cqVo06dOpw5cyZDb3GNGjXYsGED69evp3LlygQFBTF58uQ8X4j7rmT3OpmZmREWFkatWrWoXbs2sbGxbNu2LdubelhaWrJ06VIaNmxI1apV2bVrF7/88osyzCS3r19uBAQE8N1337F8+XKqVKlC06ZNiYiIyHKGJScnJ3788Uc2bdpE1apVWbx4MePHjwfItBc9MyqVih49enD69OkM7w0TExN27NjBf//9R+3atenatSstWrTI8RksIYQQ7w93d3fUanWGR3oHUYsWLXj+/HmG7emN/HRjx47lxo0bPHnyhEOHDtGoUaN3n4x4r6nUrw6u/gDFxsZStmxZjh07Ro0aNd5p3S1btsTW1pZVq1a903rF+2/atGksWbIkR1OJFoT4+HgsLCy4d++e1ozR37Ztm3Lhc2GnTflqU64g+RZ22pSvNuUK+Zdv+uf3o0ePspxIJV2BD915E8nJydy/f58JEyZQr169t97IT0xMZMmSJXh6eqKrq8u6deuUC0WF+Prrr6lduzbW1tYcPHiQmTNnZrihmxBCCCHEu1LgQ3fexMGDB7Gzs+PYsWMsWbJEY9v+/fspUqRIlo+8UKlUbNu2jSZNmlCzZk1++eUXNm7cqEyB+Lr69u/f/8b5vmzNmjVZ1lWpUqV8rettKcgc3sZrdeXKFTp06EDFihWZMmUKI0aMUE6ztm7dOsv63nTOfyGEEEKIzHzQPfrpY9wyU6tWLU6dOpWv9RkbG7Nr164st7+uvpIlS+ZrLO3bt88w9WO6D+X0V0Hm8DZeq7lz5zJ37txMt3333Xc8ffo0023ZzTwkhBBCCJEXH3RD/3WMjY0pV67cO63zXdZnZmaGmZnZO6vvbSjIHN71eyO/v+gJIYQQQmTngx66I4QQQgghhMicNPSFEEIIId6hffv24e3tjb29PSqVii1btmhsP3z4MG3atMHa2hqVSpXlcNPDhw/TvHlzTE1NMTc3p0mTJlkOExXaSRr6QgghhBDv0JMnT6hWrRqLFi3KdPuzZ89o0KABM2bMyPIYhw8fxsvLi1atWnH06FGOHTtGYGBgtveoEdpF3g1C5JPY2NjX9rzkxqZNm2jVqlW2vTkAarWa1q1bZ9orJIQQ4v3TunVrpk6dSqdOnTLd3qxZMyZMmKDM6peZYcOG8cUXXzB27FgqVaqEi4sLPj4+Ob5Jo9AO0tAX4h17/vx5tmWePHlCo0aNXtubky48PByVSpUfoQkhhPgA3LlzhyNHjlC8eHEaNGhAiRIlaNq0KQcOHCjo0MR7ptDOuiPE27B9+3amTp3KuXPn0NXVpX79+sybN4+yZcvi5OQEgJubGwBNmzYlKioKf39/Hj58SO3atVm0aBGGhoZcu3bttfX06tULeHGW4HVOnTrF7NmzOX78OHZ2dnnKqW7oblL0TPO074fEUFdNWB2oHLyDpNTC/8VIm/LVplxB8v0QxU5vm6/Hu3r1KgDBwcHMmjWL6tWrs3LlSlq0aMG5c+dwdnbO1/rEh0sa+kLkwpMnTxg+fDhVq1YlISGBoKAgOnXqxKlTpzh69Ch16tRh165dVKpUCQMDA2W/3bt3Y25unq93UU5MTKRnz54sWrQIW1vbbMsnJSWRlJSkLMfHxwNgqKNGVzfz+1EUJoY6ao2fhZ025atNuYLk+yFKTk5+7faUlBSlzMs/M/sd/u/McEBAAJ988gkAYWFh7Nq1i6VLlzJt2rR8z+FteDXnwi6/8s3N/tLQFyIXunTporG8bNkybGxs+Ouvv7CxsQHA2to6Q8Pb1NSU7777TqPx/6aGDRtGgwYN6NChQ47Kh4aGEhISkmH9BLc0TExS8y2u992UWmkFHcI7pU35alOuIPl+SLZt2/ba7SdOnMhwo8jIyEj+/fdfAA4cOMDff/+tbEtf//z5c41jW1hYcOTIkWzre9/kZyfYh+BN801MTMxxWWnoC5ELV65cISgoiCNHjnDv3j3S0l588MTFxVGxYsUs96tSpUq+NvJ//vln9uzZw8mTJ3O8z7hx4xg+fLiyHB8fj4ODA1NP6pCir5tvsb2vDHXUTKmVxsTjOiSlfZin/3NDm/LVplxB8v0QnQv2fO32mjVr0qZNG+BFb21kZCQtW7bk1q1bADRq1Ijq1asr5dVqNSEhIRgbGyv7AUyaNAlPT0+Nde+zl3N99YtOYZRf+aafkc8JaegLkQve3t6ULl2apUuXYm9vT1paGpUrV872AltT0/wdA79nzx5iYmKwtLTUWN+lSxcaN25MVFRUhn0MDQ0znY1h3xgPrK2t8zW+91FycjLbtm3jRJCX1nygaEu+2pQrSL6FQUJCAtHR0cryjRs3OH/+PFZWVtjZ2fH48WPOnz/P3bt3gRdj8vX19bG1tVXOGI8aNYpJkyZRo0YNqlevzooVK7h06RIbN2784J4nfX39Dy7mN/Gm+eZmX2noC5FD9+/f59KlSyxdupTGjRsDaMxwkN5jn5r69ofBjB07loCAAI11VapUYe7cuXh7e7/1+oUQQuTd8ePHadasmbKcfrbVz8+PpUuXcvToUWVSBoDu3bsDL3rsg4ODARg6dCjPnj1j2LBh/Pfff1SrVo3IyEjKli377hIR7z1p6AuRQ0WLFsXa2ppvv/0WOzs74uLiGDt2rLK9ePHiGBsbs337dj766COMjIywsLDIU13//fcfcXFxypjMS5cuASi9OS/36rysVKlSyuw/Qggh3k/u7u6o1ZlfXJycnEyLFi2YPXt2tj23Y8eO1fgcEuJVMo++EDmko6PD+vXrOXHiBJUrV2bYsGHMnDlT2a6np8f8+fP55ptvsLe3z/FFspn5+eefcXNzo23bF1Oyde/eHTc3N5YsWfLGeQghhBBCO0iPvhC54OHhwV9//aWx7uVemYCAgAxDaiIiInJdj7+/P/7+/rnaJ6veISGEEEJoJ+nRF0IIIYQQohCShr4Q79j+/fspUqRIlg8hhBBCiPwgQ3eEeMdq1arFqVOnCjoMIYQQQhRy0tAX4h0zNjamXLlyBR2GEEIIIQo5GbojhBBCCCFEISQNfSGEEEIUCvv27cPb2xt7e3tUKhVbtmzR2K5WqwkKCsLOzg5jY2M8PDy4cuWKsj02Npa+ffvi5OSEsbExZcuWZdKkSdne/VyI95U09IXIZ+7u7gwdOvS1ZRwdHQkPD1eWX/5Aio2NRaVSyTh+IYTIpSdPnlCtWjUWLVqU6fawsDDmz5/PkiVLOHLkCKampnh6evLs2TMALl68SFpaGt988w3nz59n7ty5LFmyhC+//PJdpiFEvpEx+qLQCA4OZsuWLfnWQHZ0dGTo0KHZNtrz4tixY5iamma6zcHBgdu3b1OsWDEAoqKiaNasGQ8ePMDS0jLfYxFCiMKidevWtG7dOtNtarWa8PBwJkyYoNzQcOXKlZQoUYItW7bQvXt3vLy88PLyUvYpU6YMly5dYvHixcyaNeud5CBEfpIefSEKgI2NDSYmJplu09XVxdbWFj09+R4uhBD55dq1a/zzzz94eHgo6ywsLKhbty6HDx/Ocr9Hjx5hZWX1LkIUIt9JS0K8c2lpacyaNYtvv/2WGzduUKJECQYMGMD48eM5e/YsQ4YM4fDhw5iYmNClSxfmzJmjzC8fFRXF6NGjOX/+PPr6+lSqVIm1a9eyd+9eQkJCgBfDYACWL1/+2rvLqtVqQkJCWLZsGf/++y/W1tZ07dqV+fPn4+7uzvXr1xk2bBjDhg1Tyt+/f5/AwED27dvHgwcPKFu2LF9++SU9evTQOHZKSgqBgYGsWrUKfX19Bg0axOTJk5XYXne2IDY2FicnJ06ePImlpSXNmjUDoGjRogD4+fnRvHlzhg0bxt9//42hoaGyb8eOHTEzM2PVqlU5fj3qhu4mRS/zswuFiaGumrA6UDl4B0mpqoIO563Tpny1KVeQfF8WO71tjo/zzz//AFCiRAmN9SVKlFC2vSo6OpoFCxZIb774YElDX7xz48aNY+nSpcydO5dGjRpx+/ZtLl68yJMnT/D09KR+/focO3aMO3fuEBAQQGBgIBEREaSkpNCxY0f69evHunXreP78OUePHkWlUtGtWzfOnTvH9u3b2bVrF/Cip+Z1Nm7cyNy5c1m/fj2VKlXin3/+4fTp0wBs2rSJatWq0b9/f/r166fs8+zZM2rWrMmYMWMwNzdn69at9OrVi7Jly1KnTh2l3IoVK+jbty9Hjx7l+PHj9O/fn1KlSmkcKyccHBzYuHEjXbp04dKlS5ibm2NsbIyBgQFffPEFP//8Mx9//DEAd+7cYevWrezcuTPTYyUlJZGUlKQsx8fHA2Coo0ZXV52ruD5EhjpqjZ+FnTblq025guT7suTk5Nfum5KSopRJSUlR9nl5v7S0NFQqVYZj3bp1Cy8vL7p06YK/v3+2deWX9HreVX0FSZtyhfzLNzf7S0NfvFOPHz9m3rx5LFy4ED8/PwDKli1Lo0aNWLp0Kc+ePWPlypXK+PWFCxfi7e3NjBkz0NfX59GjR7Rr146yZcsC4Orqqhy7SJEi6OnpYWtrm6NY4uLisLW1xcPDA319fUqVKqU01q2srNDV1cXMzEzjeCVLlmTkyJHK8ueff86OHTvYsGGDRkPfwcGBuXPnolKpcHFx4ezZs8ydOzfXDX1dXV3llHHx4sU1xuj37NmT5cuXKw391atXU6pUKdzd3TM9VmhoqHLW42UT3NIwMUnNVVwfsim10go6hHdKm/LVplxB8gXYtm3ba/c5ceIE+vr6wP/16G/cuJEyZcooZS5evIiTk5PGsf777z8mTJhA+fLl8fb2zraetyEyMvKd11lQtClXePN8ExMTc1xWGvrinbpw4QJJSUm0aNEi023VqlXTuEi1YcOGpKWlcenSJZo0aYK/vz+enp60bNkSDw8PfHx8sLOzy1MsH3/8MeHh4ZQpUwYvLy/atGmDt7f3a8fGp6am8tVXX7FhwwZu3brF8+fPSUpKyjDevl69esowHYD69esze/ZsUlNT0dXVzVO8r+rXrx+1a9fm1q1blCxZkoiICPz9/TXqfdm4ceMYPny4shwfH4+DgwPNmjXD2to6X2J6nyUnJxMZGUnLli2VD/7CTJvy1aZcQfLNjZo1a9KmTRvgxfDL4OBgkpOTlXXx8fFER0czduxYZd2tW7do2bIljRo1YsWKFfn2PzuntOn11aZcIf/yTT8jnxPS0BfvlLGx8Rvtv3z5cr744gu2b9/ODz/8wIQJE4iMjKRevXq5PpaDgwOXLl1i165dREZGMnjwYGbOnMnvv/+e5R/gzJkzmTdvHuHh4VSpUgVTU1OGDh1aIHMsu7m5Ua1aNVauXEmrVq04f/48W7duzbK8oaGhxnj+dPr6+lrxDzad5Ft4aVOuIPlmJiEhgejoaGX5xo0bnD9/HisrK0qVKsXQoUMJDQ2lQoUKODk5MXHiROzt7enatSv6+vpKI7906dLMmTOHhw8fKsfK6dni/KJNr6825Qpvnm9u9pWGvninnJ2dMTY2Zvfu3QQEBGhsc3V1JSIigidPnii9+gcPHkRHRwcXFxelnJubG25ubowbN4769euzdu1a6tWrh4GBAampuRuCYmxsjLe3N97e3nz22WdUqFCBs2fPUqNGjUyPd/DgQTp06MAnn3wCvBjbefnyZSpWrKhR7siRIxrLf/zxB87OznnqGTIwMADINLeAgADCw8O5desWHh4eODg45Pr4QghRWBw/flyZwABQzmL6+fkRERHB6NGjefLkCf379+fhw4c0atSI7du3Y2RkBLwYUhEdHU10dDQfffSRxrHVau24JkIULjK9pninjIyMGDNmDKNHj2blypXExMTwxx9/8P333+Pr64uRkRF+fn6cO3eOvXv38vnnn9OrVy9KlCjBtWvXGDduHIcPH+b69evs3LmTK1euKOP0HR0duXbtGqdOneLevXsaF55mJiIigu+//55z585x9epVVq9ejbGxMaVLl1aOt2/fPm7dusW9e/eAF19UIiMjOXToEBcuXGDAgAH8+++/GY4dFxfH8OHDuXTpEuvWrWPBggUMGTIkT89Z6dKlUalU/Prrr9y9e5eEhARlW8+ePbl58yZLly7l008/zdPxhRCisHB3d0etVmd4REREAC9mZZs8eTL//PMPz549Y9euXZQvX17Z39/fP9P9pZEvPlTS0Bfv3MSJExkxYgRBQUG4urrSrVs37ty5g4mJCTt27OC///6jdu3adO3alRYtWrBw4UIATExMuHjxIl26dKF8+fL079+fzz77jAEDBgDQpUsXvLy8aNasGTY2Nqxbt+61cVhaWrJ06VIaNmxI1apV2bVrF7/88osyXn3y5MnExsZStmxZbGxsAJgwYQI1atTA09MTd3d3bG1t6dixY4Zj9+7dm6dPn1KnTh0+++wzhgwZQv/+/fP0fJUsWZKQkBDGjh1LiRIlCAwMVLZZWFjQpUsXihQpkmkcQgghhNBeMnRHvHM6OjqMHz+e8ePHZ9hWpUoV9uzZk+l+JUqUYPPmzVke19DQkB9//DHHcXTs2PG1jeN69eop022ms7KyYsuWLa89blRUlPL74sWLMy0TGxursfxyb5Gjo2OG3qOJEycyceLETI9169YtfH19Mx1/L4QQQgjtJQ19IT5QDx48ICoqiqioKL7++uuCDkcIIYQQ7xlp6ItCa82aNcqwnleVLl2a8+fPv+OI8pebmxsPHjxgxowZGhcrCyGEEEKANPRFIda+fXvq1q2b6bbCMI3Xq8N/hBBCCCFeJg19UWiZmZlhZmZW0GEIIYQQQhQImXVHCCGEEEKIQkga+uKti42NRaVScerUqYIORQghxAfg8ePHDB06lNKlS2Nubs6YMWM4fvy4sl2lUmX6mDlzZgFGLcT7Rxr6Is/8/f3fm7nbo6KiUKlUGrcrL0gvf0gZGxvToEEDjh07plFGrVYTFBSEnZ0dxsbGeHh4cOXKlRwdPzY2lr59++Lk5ISxsTFly5Zl0qRJPH/+/G2kI4QQ71RAQACRkZGsWrWKP//8k+rVq+Pl5cWtW7cAuH37tsZj2bJlqFQqunTpUsCRC/F+kYa+eK+p1WpSUlLeaZ3JyclvfIyXP6TOnj1Lq1at8PDwUD6kAMLCwpg/fz5LlizhyJEjmJqa4unpybNnz7I9/sWLF0lLS+Obb77h/PnzzJ07lyVLlvDll1++cexCCFGQnj59ysaNGwkLC6NJkyaUK1eOHj16ULZsWeXeJLa2thqPn376iWbNmlGmTJkCjl6I94s09EW2fvzxR6pUqYKxsTHW1tZ4eHgwatQoVqxYwU8//aScMk2/UdTRo0dxc3PDyMiIWrVqcfLkyRzXld4z/9tvv1GzZk0MDQ05cOAAaWlphIaGKj3Y1apVU26OFRsbS7NmzQAoWrQoKpUKf39/4MXNp8LDwzXqqF69OsHBwcqySqVi8eLFtG/fHlNTU6ZNm0ZwcDDVq1dn1apVODo6YmFhQffu3Xn8+HG2OWT2IRUcHEy5cuWUDym1Wk14eDgTJkygQ4cOVK1alZUrV/L3339ne0MuAC8vL5YvX06rVq0oU6YM7du3Z+TIkWzatCn7J1kIId5jKSkppKamYmRkpLHe2NiYAwcOZCj/77//snXrVvr27fuuQhTigyGz7ojXun37Nj169CAsLIxOnTrx+PFj9u/fT+/evYmLiyM+Pp7ly5cDL+4am5CQQLt27WjZsiWrV6/m2rVrDBkyJNf1jh07llmzZlGmTBmKFi1KaGgoq1evZsmSJTg7O7Nv3z4++eQTbGxsaNSoERs3bqRLly5cunQJc3NzjI2Nc1VfcHAw06dPJzw8HD09PZYtW0ZMTAxbtmzh119/5cGDB/j4+DB9+nSmTZv22mPl5EPq2rVr/PPPP3h4eCjbLSwsqFu3LocPH6Z79+65ih/g0aNHWFlZZbk9KSmJpKQkZTk+Ph6AJjN2kaJvmuv6PjSGOmqm1IKak7eTlKYq6HDeOm3KV5tyhcKX77lgT41lIyMj6tWrx+TJkylXrhxWVlZERUXxxx9/ULZs2QxnXZctW4aZmRne3t75cka2oKXnUBhyyY425Qr5l29u9peGvnit27dvk5KSQufOnSldujQAVapUAV40XJOSkrC1tVXKR0REkJaWxvfff4+RkRGVKlXi5s2bDBo0KFf1Tp48mZYtWwIvGqhfffUVu3bton79+gCUKVOGAwcO8M0339C0aVOlgVu8eHEsLS1znWfPnj3p06ePxrq0tDQiIiKUKTp79erF7t27s23om5mZUb9+faZMmYKrqyslSpRg3bp1HD58mHLlygHwzz//AFCiRAmNfUuUKKFsy43o6GgWLFjArFmzsiwTGhpKSEhIhvUT3NIwMUnNdZ0fqim10go6hHdKm/LVplyh8OS7bdu2DOv8/PxYuHAhjo6O6OjoULZsWRo3bkxMTEyG8osWLaJ+/frs2bPnXYX8TkRGRhZ0CO+MNuUKb55vYmJijstKQ1+8VrVq1WjRogVVqlTB09OTVq1a0bVrV4oWLZpp+QsXLlC1alWN3uz0xnlu1KpVS/k9OjqaxMREpeGf7vnz57i5ueX62NnVl87R0VFjHn47Ozvu3LmTo+OtWrWKTz/9lJIlS6Krq0uNGjXo0aMHJ06cyJd4X3br1i28vLz4+OOP6devX5blxo0bx/Dhw5Xl+Ph4HBwcmHpShxR93XyP633zohc0jYnHdQpFL2h2tClfbcoVCl++r/bop+vbty9Pnjzh/v37nDt3jlWrVmFiYkKbNm2UMgcOHODWrVts2bKFatWqvauQ36rk5GQiIyNp2bJlobi54+toU66Qf/mmn5HPCWnoi9fS1dUlMjKSQ4cOsXPnThYsWMD48eM5cuTIW63X1PT/hpIkJCQAsHXrVkqWLKlRztDQ8LXH0dHRQa1Wa6zL7JTXy/Wle/WPUKVSkZaWsx60smXL8vvvv/PkyRPi4+Oxs7OjW7duyoVi6WdB/v33X+zs7JT9/v33X6pXr56jOgD+/vtvmjVrRoMGDfj2229fW9bQ0DDT52vfGA+sra1zXOeHKjk5mW3btnEiyEtrPlC0JV9tyhW0K19LS0tMTU35448/2LVrF2FhYRo5r1ixgpo1a2baWfOh09fXL/SvbzptyhXePN/c7CsX44psqVQqGjZsSEhICCdPnsTAwIDNmzdjYGBAaqrmkA9XV1fOnDmjMXPMH3/88Ub1V6xYEUNDQ+Li4ihXrpzGw8HBAQADAwOADPHY2Nhw+/ZtZTk+Pp5r1669UTy5YWpqip2dHQ8ePGDHjh106NABACcnJ2xtbdm9e7dGbEeOHMnxGZBbt27h7u5OzZo1Wb58OTo68ucshCgcduzYwfbt27l27Rq7du1iwoQJuLi4aAyxjI+P53//+x8BAQEFGKkQ7zfp0RevdeTIEXbv3k2rVq0oXrw4R44c4e7du7i6uvLs2TN27NjBpUuXsLa2xsLCgp49ezJ+/Hj69evHuHHjiI2Nfe248ZwwMzNj5MiRDBs2jLS0NBo1asSjR484ePAg5ubm+Pn5Ubp0aVQqFb/++itt2rTB2NiYIkWK0Lx5cyIiIvD29sbS0pKgoCB0dd/+MJUdO3agVqtxcXEhOjqaUaNGUaFCBeVDSqVSMXToUKZOnYqzszNOTk5MnDgRe3v7HN2bIL2RX7p0aWbNmsXdu3eVbS9fMyGEEB+iR48eMW7cOG7evImVlRU1atRgxYoVGj2Z69evR61W06NHjwKMVIj3mzT0xWuZm5uzb98+wsPDiY+Pp3Tp0syePZvWrVtTq1YtoqKiqFWrFgkJCezduxd3d3d++eUXBg4ciJubGxUrVmTGjBlvfBOTKVOmYGNjQ2hoKFevXsXS0pIaNWoo88aXLFmSkJAQxo4dS58+fejduzcRERGMGzeOa9eu0a5dOywsLJgyZco76dF/9UOqS5cuTJs2TeNDavTo0Tx58oT+/fvz8OFDGjVqxPbt2zPM1pOZyMhIoqOjiY6O5qOPPtLY9upQJSGE+ND4+Pjg4+MD/N9QJQsLC40y/fv3p3///gURnhAfDJVaWgVCaKX4+HgsLCy4d++eVo3Rb9OmjVaMBdWmfLUpV5B8CzttylebcoX8yzf98/vRo0eYm5u/tqwM6hVCCCGEEKIQkoa+eKcGDhxIkSJFMn0MHDiwoMPLkbi4uCxzKFKkCHFxcW9cx1dffZXl8Vu3bp0PWQghhBCisJMx+uKdmjx5MiNHjsx0W3ann94X9vb2nDp16rXb39TAgQOV8amvyu1df4UQQgihnaShL96p4sWLU7x48YIO443o6ekpd7h9W6ysrJS7/QohhBBC5IUM3RFCCCGEEKIQkoa+EEIIIQrE48ePGTp0KKVLl8bY2JgGDRpw7NgxZbu/vz8GBgZ07NgRAwMDVCoVXl5eBRixEB8WaeiLQsvR0ZHw8PAcl4+NjUWlUr12/L0QQoj8ExAQQGRkJKtWreLs2bO0atUKDw8Pbt26pZTx9PRk+fLlxMXFcfv2bdatW1eAEQvxYZGGvii0jh07lu83U4mIiMDS0jJfj5lXKpUqw2P9+vUFHZYQQuTI06dP2bhxI2FhYTRp0oRy5coRHBxMuXLlWLx4sVLOwMCAokWLYmtri62tLUWLFi3AqIX4sMjFuKLQsrGxKegQMvX8+XMMDAzy5VjLly/XOI39vnwJEUKI7KSkpJCamprhbuDGxsYcOHBAWd63bx/79u2jePHitGjRgqlTp2rFTf6EyA/S0BfvjV9//ZVPPvmE+/fvo6ury6lTp3Bzc2PMmDFMnz4deHGa99mzZ6xevZoDBw4wbtw4jh8/TrFixejUqROhoaGYmpoCL4buDB06lKFDhwJw8eJFAgICOH78OGXKlGH+/Pm0bNmSzZs307FjRyWOq1evMmzYMI4cOYKzszNLliyhfv36REVF0adPH+BFbzrApEmTCA4Ofm1ejo6O9O3blytXrrBlyxY6d+5MREQEGzduJCgoiOjoaOzs7Pj8888ZMWKEsl9SUhJBQUGsXbuWO3fu4ODgwLhx4+jbt69SxtLSEltb2zd63uuG7iZFz/SNjvEhMNRVE1YHKgfvIClVVdDhvHXalK825Qofbr6x09tqLJuZmVG/fn2mTJmCq6srJUqUYN26dRw+fFiZ2czLy4v27dtz48YNSpYsSVBQEK1bt+bw4cPo6uoWRBpCfFCkoS/eG40bN+bx48ecPHmSWrVq8fvvv1OsWDGioqKUMr///jtjxowhJiYGLy8vpk6dyrJly7h79y6BgYEEBgayfPnyDMdOTU2lY8eOlCpViiNHjvD48WONRvXLxo8fz6xZs3B2dmb8+PH06NGD6OhoGjRoQHh4OEFBQVy6dAmAIkWK5Ci3WbNmERQUxKRJkwA4ceIEPj4+BAcH061bNw4dOsTgwYOxtrbG398fgN69e3P48GHmz59PtWrVuHbtGvfu3dM47meffUZAQABlypRh4MCB9OnTR/kS8qqkpCSSkpKU5fj4eAAMddTo6qpzlMeHzFBHrfGzsNOmfLUpV/hw801OTs6wbtmyZfTv35+SJUuiq6uLm5sb3bp1488//yQ5OZkuXbqQnJxMZGQkLVu2pEqVKlSoUIFdu3bRvHnzAsji7Ut/njJ7vgobbcoV8i/f3OyvUqvVH9Z/ClGo1axZkx49ejBy5Eg6depE7dq1CQkJ4f79+zx69IiPPvqIy5cvM2PGDHR1dfnmm2+UfQ8cOEDTpk158uQJRkZGGj3627dvx9vbmxs3big94Lt27dLo0Y+NjcXJyYnvvvtO6TX/66+/qFSpEhcuXKBChQpEREQwdOhQHj58mOOcHB0dcXNzY/Pmzco6X19f7t69y86dO5V1o0ePZuvWrZw/f57Lly/j4uJCZGQkHh4emR53ypQpNG/eHBMTE3bu3MmkSZMICwvjiy++yLR8cHAwISEhGdavXbsWExOTHOcjhBD57dmzZyQmJmJlZcXMmTN59uwZEydOzLRs79698fX1xdPT8x1HKcT7ITExkZ49e/Lo0aNsbzYqPfrivdK0aVOioqIYMWIE+/fvJzQ0lA0bNnDgwAH+++8/7O3tcXZ25vTp05w5c4Y1a9Yo+6rVatLS0rh27Rqurq4ax7106RIODg4aw1zq1KmTaQxVq1ZVfrezswPgzp07VKhQIc951apVS2P5woULdOjQQWNdw4YNCQ8PJzU1lVOnTqGrq0vTpk2zPObLH4Jubm48efKEmTNnZtnQHzduHMOHD1eW4+PjcXBwYOpJHVL0C/8pcEMdNVNqpTHxuA5JaR/OcIe80qZ8tSlX+HDzPRecfcP8wYMHnDt3jtDQUNq0aQOg0aP/77//8vjxYzw8PJTthc3L+err6xd0OG+VNuUK+Zdv+hn5nJCGvnivuLu7s2zZMk6fPo2+vj4VKlTA3d2dqKgoHjx4oDR8ExISGDBgQKaN2lKlSr1RDC//8aUPg0lLS3ujY6ZfN5BTxsbGua6jbt26TJkyhaSkJAwNDTNsNzQ0zHT9vjEeWnFhW3JyMtu2beNEkJfWfKBoS77alCsUrnx37NiBWq3GxcWF6OhoRo0aRYUKFQgICCApKYmQkBA6dOjAv//+y/79+/nyyy8pV64cbdu2/eBzz46+vn6hzzGdNuUKb55vbvaVhr54r6SP0587d67SqHd3d2f69Ok8ePBAGVdfo0YN/vrrL+WCrey4uLhw48YN/v33X0qUKAGgcVOWnDIwMCA1NTXX+73K1dWVgwcPaqw7ePAg5cuXR1dXlypVqpCWlsbvv/+e5dCdV506dYqiRYtm2pgXQoj30aNHjxg3bhw3b97EysqKLl26MG3aNPT19UlJSeHMmTOsWLGCBw8eULJkSVq1asWUKVPk/5wQOSQNffFeKVq0KFWrVmXNmjUsXLgQgCZNmuDj40NycrLS+B8zZgz16tUjMDCQgIAATE1N+euvv4iMjFT2e1nLli0pW7Ysfn5+hIWF8fjxYyZMmACQ5cWrmXF0dCQhIYHdu3dTrVo1TExM8jS+fcSIEdSuXZspU6bQrVs3Dh8+zMKFC/n666+Vevz8/Pj000+Vi3GvX7/OnTt38PHx4ZdffuHff/+lXr16GBkZERkZyVdffcXIkSNzHYsQQhQUHx8ffHx8Mt1mbGzMjh07lDMYbdq00apeXyHyg9wwS7x3mjZtSmpqKu7u7gBYWVlRsWJFbG1tcXFxAV6Mo//999+5fPkyjRs3xs3NjaCgIOzt7TM9pq6uLlu2bCEhIYHatWsTEBDA+PHjATLM4fw6DRo0YODAgXTr1g0bGxvCwsLylGONGjXYsGED69evp3LlygQFBTF58mRlxh2AxYsX07VrVwYPHkyFChXo168fT548AV6ctlu0aBH169enevXqfPPNN8yZM0eZ1UcIIYQQQnr0xXsnPDyc8PBwjXWnTp3KUK527doas9a8KjY2VmO5QoUKGjdhSR86kz78x9HRkVcnobK0tMywbvHixRp3bczOq3Gk69KlC126dMlyPyMjI+bMmcOcOXMybPPy8tK4UZYQQgghxKukoS+0xubNmylSpAjOzs5ER0czZMgQGjZsSNmyZQs6NCGEEEKIfCcNfaE1Hj9+zJgxY4iLi6NYsWJ4eHgwe/bsNzrm/v37ad26dZbbExIS3uj4QgghhBB5JQ19oTV69+5N79698/WYtWrVynRYkRBCCCFEQZOGvhBvwNjYOMdTfAohhBBCvEsy644QQgghhBCFkDT0RY74+/vTsWPH15Zxd3dn6NCh7yQeIYQQ+S81NZWJEyfi5OSEsbExZcuWZcqUKRlmH7tw4QLt27fHwsICU1NTateuTVxcXAFFLYTIijT0PzDBwcFUr169oMMQQghRCM2YMYPFixezcOFCLly4wIwZMwgLC2PBggVKmZiYGBo1akSFChWIiorizJkzTJw4MVf3JBFCvBsyRl8UGs+fP8fAwKCgwxBCiA/WoUOH6NChA23btgVe3F9k3bp1HD16VCkzfvx42rRpo3HDQJmmWIj3k/ToF4C0tDTCwsIoV64choaGlCpVimnTpgEwZswYypcvj4mJCWXKlGHixIkkJycDEBERQUhICKdPn0alUqFSqYiIiMi2vosXL9KoUSOMjIyoWLEiu3btQqVSsWXLFqXM2bNnad68OcbGxlhbW9O/f//XTg355MkTevfuTZEiRbCzs8t0msqkpCRGjhxJyZIlMTU1pW7dukRFRSnbIyIisLS0ZMeOHbi6ulKkSBG8vLy4fft2jp7H9OFE06ZNw97eXrlr7o0bN/Dx8cHS0hIrKys6dOigcdOqqKgo6tSpg6mpKZaWljRs2JDr168r2xcvXkzZsmUxMDDAxcWFVatWadSrUqn47rvv6NSpEyYmJjg7O/Pzzz8r21NTU+nbt69y6tvFxYV58+ZlGvusWbOws7PD2tqazz77THmt05+/MWPG4ODggKGhIeXKleP7779Xtp87d47WrVtTpEgRSpQoQa9evbh3716OnjshhMhMgwYN2L17N5cvXwbg9OnTHDhwQJlGOC0tja1bt1K+fHk8PT0pXrw4devW1fg8EUK8P6RHvwCMGzeOpUuXMnfuXBo1asTt27e5ePEiAGZmZkRERGBvb8/Zs2fp168fZmZmjB49mm7dunHu3Dm2b9/Orl27ALCwsHhtXampqXTs2JFSpUpx5MgRHj9+zIgRIzTKPHnyBE9PT+rXr8+xY8e4c+cOAQEBBAYGZvlFYtSoUfz+++/89NNPFC9enC+//JI///xTY1hRYGAgf/31F+vXr8fe3p7Nmzfj5eXF2bNncXZ2BiAxMZFZs2axatUqdHR0+OSTTxg5ciRr1qzJ0XO5e/duzM3NiYyMBCA5OVnJZf/+/ejp6TF16lS8vLw4c+YMOjo6dOzYkX79+rFu3TqeP3/O0aNHUalUwIubag0ZMoTw8HA8PDz49ddf6dOnDx999BHNmjVT6g0JCSEsLIyZM2eyYMECfH19uX79OlZWVqSlpfHRRx/xv//9D2traw4dOkT//v2xs7PDx8dHOcbevXuxs7Nj7969REdH061bN6pXr06/fv2AF9OBHj58mPnz51OtWjWuXbumNOQfPnxI8+bNCQgIYO7cuTx9+pQxY8bg4+PDnj17cvTcpasbupsUPdNc7fMhMtRVE1YHKgfvIClVVdDhvHXalK825Qr5m2/s9LYay2PHjiU+Pp4KFSqgq6tLamoq06ZNw9fXF4A7d+6QkJDA9OnTmTp1KjNmzGD79u107tyZvXv30rRp0zeKRwiRv/Ktof/w4UMsLS3z63CF1uPHj5k3bx4LFy7Ez88PeHHKs1GjRgBMmDBBKevo6MjIkSNZv349o0ePxtjYmCJFiqCnp4etrW2O6ouMjCQmJoaoqChln2nTptGyZUulzNq1a3n27BkrV67E1PRFg2/hwoV4e3szY8YMSpQooXHMhIQEvv/+e1avXk2LFi0AWLFiBR999JFSJi4ujuXLlxMXF4e9vT0AI0eOZPv27SxfvpyvvvoKeNEwX7JkiXLaNzAwkMmTJ+fw2QRTU1O+++47ZcjO6tWrSUtL47vvvlMa78uXL8fS0pKoqChq1arFo0ePaNeunVKnq6urcrxZs2bh7+/P4MGDARg+fDh//PEHs2bN0mjo+/v706NHDwC++uor5s+fz9GjR/Hy8kJfX5+QkBClrJOTE4cPH2bDhg0aDf2iRYuycOFCdHV1qVChAm3btmX37t3069ePy5cvs2HDBiIjI/Hw8ACgTJkyyr4LFy7Ezc1NeR4Bli1bhoODA5cvX6Z8+fIZnqukpCSSkpKU5fj4eAAMddTo6qozlC9sDHXUGj8LO23KV5tyhfzN9+WziAA//PADa9asYeXKlVSsWJHTp08zcuRIihcvTu/evZX/Id7e3gQGBgJQqVIlDhw4wNdff02DBg3eOKasYnw11sJKm/LVplwh//LNzf55aujPmDEDR0dHunXrBoCPjw8bN27E1taWbdu2Ua1atbwcVitcuHCBpKQkpYH8qh9++IH58+cTExNDQkICKSkpmJub57m+S5cu4eDgoPHFoE6dOhliqlatmtLIB2jYsCFpaWlcunQpQ0M/JiaG58+fU7duXWWdlZWVMnQGXgwFSk1NzdDgTEpKwtraWlk2MTHRGNtpZ2fHnTt3cpxflSpVNMblnz59mujoaMzMzDTKPXv2jJiYGFq1aoW/vz+enp60bNkSDw8PfHx8sLOzU56L/v37a+zbsGHDDENvqlatqvxuamqKubm5RtyLFi1i2bJlxMXF8fTpU54/f57hIupKlSqhq6urkfvZs2cBOHXqFLq6uln2jp0+fZq9e/dSpEiRDNtiYmIybeiHhoZqfAFJN8EtDROT1EzrKYym1Eor6BDeKW3KV5tyhfzJd9u2bRrLQ4cOpUuXLpiZmXHjxg2srKzw8vJi0qRJFCtWjOTkZHR1ddHV1dXY18DAgDNnzmQ4Xn5KP3OrLbQpX23KFd4838TExByXzVNDf8mSJcrQisjISCIjI/ntt9/YsGEDo0aNYufOnXk5rFYwNjbOctvhw4fx9fUlJCQET09PLCwsWL9+fabj3993CQkJ6OrqcuLECY3GLKDRONXX19fYplKpMkzj9jovfzlJr7dmzZqZDv2xsbEBXvTwf/HFF2zfvp0ffviBCRMmEBkZSb169XJcb2Zxp6W9+NBdv349I0eOZPbs2dSvXx8zMzNmzpzJkSNHcnyM171P0vNMP+PyqvQvLa8aN24cw4cPV5bj4+NxcHCgWbNmGl++Cqvk5GQiIyNp2bJlhue+MNKmfLUpV3i7+arVaqpUqUKbNm2UdWfPnuXo0aPKutq1awNolFm2bBnVqlXTWJdf5PUtvLQpV8i/fNPPyOdEnhr6//zzDw4ODgD8+uuv+Pj40KpVKxwdHTV6eUVGzs7OGBsbs3v3bgICAjS2HTp0iNKlSzN+/Hhl3csXicKLXpPU1Jz3vrq4uHDjxg3+/fdfpWf+2LFjGmVcXV2JiIjgyZMnSsP54MGD6OjoaPTSpytbtiz6+vocOXKEUqVKAfDgwQMuX76s9EC7ubmRmprKnTt3aNy4cY7jfVM1atTghx9+oHjx4q89E+Lm5oabmxvjxo2jfv36rF27lnr16uHq6srBgweVYVXw4rmoWLFijmM4ePAgDRo0UIb/wIte9tyoUqUKaWlp/P7778rQnZfVqFGDjRs34ujoiJ5ezv6MDQ0NMTQ0zLBeX19fK/7BppN8Cy9tyhXeTr7e3t5Mnz4dJycnKlWqxMmTJ5k3bx6ffvqpUlf6NWPu7u40a9aM7du3s3XrVqKiot7q8y+vb+GlTbnCm+ebm33zNOtO0aJFuXHjBgDbt29XGiJqtTpXjVBtZGRkxJgxYxg9ejQrV64kJiaGP/74g++//x5nZ2fi4uJYv349MTExzJ8/n82bN2vs7+joyLVr1zh16hT37t3TGHOdmZYtW1K2bFn8/Pw4c+YMBw8eVK4DSB/D7uvri5GREX5+fpw7d469e/fy+eef06tXrwzDduBFj3zfvn0ZNWoUe/bs4dy5c/j7+6Oj839vp/Lly+Pr60vv3r3ZtGkT165d4+jRo4SGhrJ169Y3fRqz5OvrS7FixejQoQP79+/n2rVrREVF8cUXX3Dz5k2uXbvGuHHjOHz4MNevX2fnzp1cuXJFGac/atQoIiIiWLx4MVeuXGHOnDls2rSJkSNH5jgGZ2dnjh8/zo4dO7h8+TITJ07M8OUqO46Ojvj5+fHpp5+yZcsWJY8NGzYA8Nlnn/Hff//Ro0cPjh07RkxMDDt27KBPnz7yNyiEyLMFCxbQtWtXBg8ejKurKyNHjmTAgAFMmTJFKdOpUyeWLFlCWFgYVapU4bvvvmPjxo3KtWZCiPdHnhr6nTt3pmfPnrRs2ZL79+8r026dPHmScuXK5WuAhdHEiRMZMWIEQUFBuLq60q1bN+7cuUP79u0ZNmwYgYGBVK9enUOHDjFx4kSNfbt06YKXlxfNmjXDxsaGdevWvbYuXV1dtmzZQkJCArVr1yYgIEA5Y5B+cxMTExN27NjBf//9R+3atenatSstWrRg4cKFWR535syZNG7cGG9vbzw8PGjUqBE1a9bUKLN8+XJ69+7NiBEjcHFxoWPHjhw7dkw5C/A2mJiYsG/fPkqVKkXnzp1xdXWlb9++PHv2DHNzc0xMTLh48SJdunShfPny9O/fn88++4wBAwYA0LFjR+bNm8esWbOoVKkS33zzDcuXL8fd3T3HMQwYMIDOnTvTrVs36taty/379zV693Nq8eLFygduhQoV6NevH0+ePAHA3t6egwcPkpqaSqtWrahSpQpDhw7F0tJS4wuXEELkhpmZGeHh4Vy/fp2nT58SExPD1KlTM9yj5NNPP+XKlSs8ffqUU6dO0aFDhwKKWAjxOip1bgZE/3/JycnMmzePGzdu4O/vj5ubGwBz587FzMwsw5AU8X45ePAgjRo1Ijo6Wm5yosXi4+OxsLDg3r17WjNGf9u2bbRp00YrThFrU77alCtIvoWdNuWrTblC/uWb/vn96NGjbCdsydMYfX19/UyHMgwbNiwvhxNv2ebNmylSpAjOzs5ER0czZMgQGjZsKI18IYQQQohCLM/n+FetWkWjRo2wt7dXLhgNDw/np59+yrfgRPbWrFlDkSJFMn1UqlQJeDF3/2effUaFChXw9/endu3aH8TrlFVeRYoUYf/+/QUdnhBCCCHEey1PPfqLFy8mKCiIoUOHMm3aNOXiP0tLS8LDw2Ws3jvUvn37LGc6Sj8t1Lt3b3r37v0uw8oXp06dynJbyZIl310gQgghhBAfoDw19BcsWMDSpUvp2LEj06dPV9bXqlUrV7OTiDdnZmaW4eZQhYVc2C2EEEIIkXd5Grpz7do15QLclxkaGiqzggghhBBCCCEKTp4a+k5OTpkOq9i+fbsyH7kQQggh3n+pqalMnDgRJycnjI2NKVu2LFOmTNG4S7m/vz8qlUrj4eXlVYBRCyFyIk9Dd4YPH85nn33Gs2fPUKvVHD16lHXr1hEaGsp3332X3zEK8U6pVCo2b95Mx44dX1suNjYWJycnTp48SfXq1d9JbC/z9/fn4cOHbNmy5Z3XLYQoPGbMmMHixYtZsWIFlSpV4vjx4/Tp0wcLCwu++OILpZyXlxfLly9XljO707YQ4v2Sp4Z+QEAAxsbGTJgwgcTERHr27Im9vT3z5s2je/fu+R2jEEIIId6SQ4cO0aFDB9q2bQu8uDP3unXrOHr0qEY5Q0NDbG1tCyJEIUQe5XroTkpKCitXrsTDw4MrV66QkJDAP//8w82bN+nbt+/biFGIQkOtVpOSklLQYQghhKJBgwbs3r2by5cvA3D69GkOHDig3PU+XVRUFMWLF8fFxYVBgwZx//79gghXCJELue7R19PTY+DAgVy4cAEAExMTTExM8j0wIfLi22+/JTg4mJs3b6Kj83/fYzt06IC1tTXLli1j8eLFzJo1ixs3buDk5MSECRPo1atXnuu8ePEigwcP5s8//6RcuXIsWrSIpk2bAi8+GJs1a8a2bduYMGECZ8+eZefOnTRp0oQZM2bw7bff8s8//1C+fHkmTpxI165dgRdjZvv378+ePXv4559/KFWqFIMHD2bIkCFZxnHs2DHatGnDyJEjGTNmTI7jrxu6mxQ90zzn/6Ew1FUTVgcqB+8gKVVV0OG8ddqUrzblCm+eb+z0thrLY8eOJT4+ngoVKqCrq0tqairTpk3D19dXKePl5UXnzp1xcnIiJiaGL7/8ktatW3P48GF0dXXfOCchxNuRp6E7derU4eTJk5QuXTq/4xHijXz88cd8/vnn7N27lxYtWgDw33//sX37drZt28bmzZsZMmQI4eHheHh48Ouvv9KnTx8++ugjmjVrlqc6R40aRXh4OBUrVmTOnDl4e3tz7do1rK2tlTJjx45l1qxZlClThqJFixIaGsrq1atZsmQJzs7O7Nu3j08++QQbGxuaNm1KWloaH330Ef/73/+wtrbm0KFD9O/fHzs7O3x8fDLEsGfPHjp37kxYWBj9+/fPNM6kpCSSkpKU5fj4eAAMddTo6qoz3acwMdRRa/ws7LQpX23KFd483+TkZI3lH374gTVr1rBy5UoqVqzI6dOnGTlyJMWLF1fuwdKlSxelfIUKFXB1daVChQrs2rWL5s2b5zGT3MX7atyFlTblq025Qv7lm5v9VeqXL6vPoQ0bNjBu3DiGDRtGzZo1MTXV7A2sWrVqbg8pRL7p2LEj1tbWfP/998CLXv6QkBBu3LhB48aNqVSpEt9++61S3sfHhydPnrB161Yg9xfjTp8+XelBT0lJwcnJic8//5zRo0crPfpbtmxRbiSXlJSElZUVu3bton79+srxAgICSExMZO3atZnWFxgYyD///MOPP/4I/N/FuH5+fvTu3ZvvvvuObt26ZRlvcHAwISEhGdavXbtWzsoJocX69u1Lly5daNOmjbJuw4YN/P777yxatCjL/Xr37o2vry+enp7vIkwhxP+Xfn3so0ePMDc3f23ZPPXop19w+/LV+CqVCrVajUqlUu6UK0RB8PX1pV+/fnz99dcYGhqyZs0aunfvjo6ODhcuXMjQ492wYUPmzZuX5/pebqzr6elRq1YtZWhbulq1aim/R0dHk5iYSMuWLTXKPH/+XOP+FIsWLWLZsmXExcXx9OlTnj9/nmF2nyNHjvDrr7/y448/ZvvFZNy4cQwfPlxZjo+Px8HBgakndUjRL/yn3g111EyplcbE4zokpWnB8A4tylebcoU3z/dcsGbDXK1WU6VKFY2G/tmzZzl69KjGupfdvHmTx48f4+HhkWWZ/JKcnExkZCQtW7ZU7vhemGlTvtqUK+Rfvuln5HMiTw39a9eu5WU3Id4Jb29v1Go1W7dupXbt2uzfv5+5c+cWaEwvn/VKSEgAYOvWrZQsWVKjXPp0devXr2fkyJHMnj2b+vXrY2ZmxsyZMzly5IhG+bJlyyrXHrRt2/a1/zgMDQ0znQ5v3xgPjWFGhVVycjLbtm3jRJCX1nygaEu+2pQr5H++3t7eTJ8+HScnJypVqsTJkyeZN28en376Kfr6+iQkJBASEkKXLl2wtbUlJiaG0aNHU65cuWz/7+QnfX19rXh902lTvtqUK7x5vrnZN08NfRmbL95nRkZGdO7cmTVr1hAdHY2Liws1atQAwNXVlYMHD+Ln56eUP3jwIBUrVsxzfX/88QdNmjQBXgzdOXHiBIGBgVmWr1ixIoaGhsTFxSkX7b7q4MGDNGjQgMGDByvrYmJiMpQrVqwYmzZtwt3dHR8fHzZs2KBV/yyFEG9uwYIFTJw4kcGDB3Pnzh3s7e0ZMGAAQUFBAOjq6nLmzBlWrFjBw4cPsbe3p1WrVkyZMkXm0hfiPZenhv7KlStfuz394h0hCoqvry/t2rXj/PnzfPLJJ8r6UaNG4ePjg5ubGx4eHvzyyy9s2rSJXbt25bmuRYsW4ezsjKurK3PnzuXBgwd8+umnWZY3MzNj5MiRDBs2jLS0NBo1asSjR484ePAg5ubm+Pn54ezszMqVK9mxYwdOTk6sWrWKY8eO4eTklOF4xYsXZ8+ePTRr1owePXqwfv169PTy9KcthNBCZmZmhIeHEx4enul2Y2NjduzY8W6DEkLkizy1Bl6d4i85OZnExEQMDAwwMTGRhr4ocM2bN8fKyopLly7Rs2dPZX3Hjh2ZN28es2bNYsiQITg5ObF8+XLc3d3zXNf06dOZPn06p06doly5cvz8888UK1bstftMmTIFGxsbQkNDuXr1KpaWltSoUYMvv/wSgAEDBnDy5Em6deuGSqWiR48eDB48mN9++y3T49na2rJnzx7c3d3x9fVl7dq1MuWdEEIIoeXy1NB/8OBBhnVXrlxh0KBBjBo16o2DEuJN6ejo8Pfff2e6bdCgQQwaNCjLfXM6EZWjo6NStkePHpmWcXd3z/R4KpWKIUOGZDkvvqGhIcuXL9e43TxAaGio8ntERITGNjs7Oy5dupSj2IUQQghR+OX6zrhZcXZ2Zvr06a+9oY8QQgghhBDi3ci3hj68mFowq15UIT40X331FUWKFMn08eqt4YUQQggh3jd5Grrz888/ayyr1Wpu377NwoULadiwYb4EJkRBGzhwYKZ3oYUXF6cJIYQQQrzP8tTQf/XGPCqVChsbG5o3b87s2bPzIy4hCpyVlRVWVlYFHYYQQgghRJ7kqaGflpaW33EIIYQQQggh8lGexuhPnjyZxMTEDOufPn3K5MmT3zgoIYQQQrw9qampTJw4EScnJ4yNjSlbtixTpkzJctaxgQMHolKpspxrXwjxfspTQz8kJISEhIQM6xMTEwkJCXnjoIQmd3d3hg4dmuf9Y2NjUalUnDp1Kt9iKswuXrxIvXr1MDIyonr16gUdjhBC5LsZM2awePFiFi5cyIULF5gxYwZhYWEsWLAgQ9nNmzfzxx9/YG9vXwCRCiHeRJ4a+mq1GpVKlWH96dOnZUzzW7Bp0yamTJlS0GEoIiIisLS0LOgwcsTf3z/DNSXZmTRpEqamply6dIndu3fnSxyOjo752hM2bdo0GjRogImJyQfzWggh3h+HDh2iQ4cOtG3bFkdHR7p27UqrVq04evSoRrlbt27x+eefs2bNGvT19QsoWiFEXuWqoV+0aFGsrKxQqVSUL19euVjRysoKCwsLWrZsmeUsJSLvrKysMDMzK+gwcu358+cFHUKexMTE0KhRI0qXLo21tXVBh6Mh/Tl9/vw5H3/88Wtv/CWEEFlp0KABu3fv5vLly8CLjroDBw5oTB2clpZGr169GDVqFJUqVSqoUIUQbyBXF+OGh4ejVqv59NNPCQkJwcLCQtlmYGCAo6Mj9evXz/cgtZ27uzvVq1cnPDwcR0dH+vfvT3R0NP/73/8oWrQoEyZMoH///kr5o0ePMmDAAC5cuEDlypUZP368xvEiIiIYOnQoDx8+VNZt2bKFTp06KeMzT58+zdChQzl+/DgqlQpnZ2e++eYbEhIS6NOnD4ByVmfSpEkEBwfj6OhI3759uXLlClu2bKFz587ExcVRsWJFFi5cqNR19+5dSpYsyW+//UaLFi1em/uqVauYN28ely5dwtTUlObNmxMeHk7x4sWVMufPn2fMmDHs27cPtVpN9erViYiIYNWqVaxYsUIj1r179+Lu7p5lfenlTpw4weTJk5XcxowZw+bNm7l58ya2trb4+voSFBSk0cP1yy+/MHnyZM6ePUuRIkVo3Lgxmzdvxt3dnevXrzNs2DCGDRsG/N/ddzdu3EhQUBDR0dHY2dnx+eefM2LECOWYmT2nERERyhC5V++Omxd1Q3eTomf6xsd53xnqqgmrA5WDd5CUmvGMZGGjTflqU66Qt3xjp7fVWB47dizx8fFUqFABXV1dUlNTmTZtGr6+vkqZGTNmoKenxxdffJGv8Qsh3p1cNfT9/PwAcHJyokGDBnIar4DMnj2bKVOm8OWXX/Ljjz8yaNAgmjZtiouLCwkJCbRr146WLVuyevVqrl27lqe7Ffv6+uLm5sbixYvR1dXl1KlT6Ovr06BBA8LDwwkKCuLSpUsAFClSRNlv1qxZBAUFMWnSJACOHDlCYGAgs2fPxtDQEIDVq1dTsmRJmjdvnm0cycnJTJkyBRcXF+7cucPw4cPx9/dn27ZtwIvTyk2aNMHd3Z09e/Zgbm7OwYMHSUlJYeTIkVy4cIH4+HiWL18OkO3Qstu3b+Ph4YGXlxcjR45UcjMzMyMiIgJ7e3vOnj1Lv379MDMzY/To0QBs3bqVTp06MX78eFauXMnz58+VGDdt2kS1atXo378//fr1U+o6ceIEPj4+BAcH061bNw4dOsTgwYOxtrbG398/y+c0r5KSkkhKSlKW4+PjATDUUaOrm/kFeIWJoY5a42dhp035alOukLd8k5OTNZZ/+OEH1qxZw8qVK6lYsSKnT59m5MiRFC9enN69e/Pnn38yb948jhw5QkpKirJfampqhmO9ben1vet6C4o25atNuUL+5Zub/fM0vWbTpk2V3589e5ZhiIa5uXleDityqE2bNgwePBiAMWPGMHfuXPbu3YuLiwtr164lLS2N77//HiMjIypVqsTNmzdzPcQjLi6OUaNGUaFCBQCcnZ2VbRYWFqhUKmxtbTPs17x5c40e6ZIlSxIYGMhPP/2kDOuKiIjA398/0+s8XvXpp58qv5cpU4b58+dTu3ZtEhISKFKkCIsWLcLCwoL169crXzzLly+v7GNsbExSUlKmsWbG1tYWPT09ihQporHPhAkTlN8dHR0ZOXIk69evVxr606ZNo3v37hoXo1erVg148eVCV1cXMzMzjWPOmTOHFi1aMHHiRCXuv/76i5kzZ2o09F99TvMqNDQ004vlJ7ilYWKS+sbH/1BMqaVd0wNrU77alCvkLt/0jod0Q4cOpUuXLpiZmXHjxg2srKzw8vJi0qRJFCtWjJ9//pk7d+5QpkwZZZ+0tDRGjx7NjBkzWLp0ab7lkVORkZHvvM6CpE35alOu8Ob5ZjbzZVby1NBPTExk9OjRbNiwgfv372fYnpqqPY2GglC1alXl9/QG9507dwC4cOECVatWxcjISCmTl+FUw4cPJyAggFWrVuHh4cHHH39M2bJls92vVq1aGstGRkb06tWLZcuW4ePjw59//sm5c+cy3F05KydOnCA4OJjTp0/z4MED5R4O6UOCTp06RePGjd/62aUffviB+fPnExMTQ0JCAikpKRpfaE+dOqXRW58TFy5coEOHDhrrGjZsSHh4OKmpqejq6gIZn9O8GjduHMOHD1eW4+PjcXBwoFmzZu/dtQhvQ3JyMpGRkbRs2VIrzkZqU77alCvkT75qtZoqVarQpk0bZd3Zs2c5evQobdq0oW7dugQGBmrs065dO3r27Imfnx8uLi5vlENuyOtbeGlTrpB/+aafkc+JPDX0R40axd69e1m8eDG9evVi0aJF3Lp1i2+++Ybp06fn5ZAiF159c6hUqlzdxExHRyfDXMmvngYKDg6mZ8+ebN26ld9++41Jkyaxfv16OnXq9Npjm5pmHOsdEBBA9erVuXnzJsuXL6d58+aULl062zifPHmCp6cnnp6erFmzBhsbG+Li4vD09FTOIhkbG2d7nDd1+PBhfH19CQkJwdPTUzmD8PJdoN9mHJk9p3lhaGioDJ96mb6+vlb8g00n+RZe2pQrvFm+3t7eTJ8+HScnJypVqsTJkyeZN28en376Kfr6+tja2mY4E6qvr0/JkiWpXLlyfoSfa/L6Fl7alCu8eb652TdP02v+8ssvfP3113Tp0gU9PT0aN27MhAkT+Oqrr1izZk1eDinyiaurK2fOnOHZs2fKuj/++EOjjI2NDY8fP+bJkyfKuszm2C9fvjzDhg1j586ddO7cWRnnbmBgkKuzNlWqVKFWrVosXbqUtWvXagzHeZ2LFy9y//59pk+fTuPGjalQoYJy5iJd1apV2b9/f5bj1XIba2YOHTpE6dKlGT9+PLVq1cLZ2Znr169niON1U3FmFoerqysHDx7UWHfw4EHKly+v9OYLIcTbsGDBArp27crgwYNxdXVl5MiRDBgw4L2aylkI8eby1ND/77//lHF75ubm/PfffwA0atSIffv25V90Itd69uyJSqWiX79+/PXXX2zbto1Zs2ZplKlbty4mJiZ8+eWXxMTEsHbtWo3ZW54+fUpgYCBRUVFcv36dgwcPcuzYMVxdXYEXY9QTEhLYvXs39+7dy9FYsYCAAKZPn45arc72rEC6UqVKYWBgwIIFC7h69So///xzhg+hwMBA4uPj6d69O8ePH+fKlSusWrVKuVDY0dGRM2fOcOnSJe7du5enC2CcnZ2Ji4tj/fr1xMTEMH/+fDZv3qxRZtKkSaxbt45JkyZx4cIFzp49y4wZM5Ttjo6O7Nu3j1u3bnHv3j0ARowYwe7du5kyZQqXL19mxYoVLFy4kJEjR2YbU1xcHKdOnSIuLo7U1FROnTrFqVOnMr2RnRBCvMrMzIzw8HCuX7/O06dPiYmJYerUqRgYGGS5T2xs7BvdvFEI8e7lqaFfpkwZrl27BkCFChXYsGED8KKnX27eU7CKFCnCL7/8wtmzZ3Fzc2P8+PEaDU54cXHo6tWr2bZtG1WqVGHdunUEBwcr23V1dbl//z69e/emfPny+Pj40Lp1a+VCzgYNGjBw4EC6deuGjY0NYWFh2cbVo0cP9PT06NGjh8b1A69jY2NDREQE//vf/6hYsSLTp0/P8KXF2tqaPXv2kJCQQNOmTalZsyZLly5VTmv169cPFxcXatWqhY2NTYYe9Jxo3749w4YNIzAwkOrVq3Po0CHlAtp07u7u/O9//+Pnn3+mevXqNG/eXOPGM5MnTyY2NpayZctiY2MDQI0aNdiwYQPr16+ncuXKBAUFMXnyZI0LcbMSFBSEm5sbkyZNIiEhATc3N9zc3Dh+/Hiu8xNCCCFE4aRSvzpYOwfmzp2Lrq4uX3zxBbt27cLb2xu1Wk1ycjJz5szJ03SOonBLb+QeO3aMGjVqFHQ4ghcX81hYWHDv3j2tuRh327ZttGnTRivGgmpTvtqUK0i+hZ025atNuUL+5Zv++f3o0aNsZ7rM08W46Tf9AfDw8ODixYucOHGCcuXKacwII0RycjL3799nwoQJ1KtXTxr5QgghhBDvSJ6G7rzs2bNnlC5dms6dO0sjX2Rw8OBB7OzsOHbsGEuWLNHYtn//fooUKZLl42346quvsqzv5Vu/CyGEEEJ86PLUo5+amspXX33FkiVL+Pfff7l8+TJlypRh4sSJODo60rdv3/yOU3yg3N3dM0zlma5WrVqZzvbzNg0cOFC5cder3sVUnUIIIYQQ70qeGvrTpk1jxYoVhIWFadwkqHLlyoSHh0tDX+SIsbEx5cqVe6d1WllZYWVl9U7rFEIIIYQoCHkaurNy5Uq+/fZbfH19Neb7rlatGhcvXsy34IQQQgghhBB5k6eG/q1btzLtiU1LS8vTPOVCvKnY2FhUKtU7HwokhBDvm9TUVCZOnIiTkxPGxsaULVuWKVOmaAyj3LRpE61atcLa2lr+dwpRiOWpoV+xYkX279+fYf2PP/6Im5vbGwclRDp/f386duxY0GEAEBUVhUql4uHDhwUdCgDBwcGoVCqNR4UKFQo6LCFEAZsxYwaLFy9m4cKFXLhwgRkzZhAWFsaCBQuUMk+ePKFRo0YZ7rMihChc8jRGPygoCD8/P27dukVaWhqbNm3i0qVLrFy5kl9//TW/YxTirVKr1aSmpqKnl6c/hzxJTk7OlzmDK1WqxK5du5Tld5mDEOL9dOjQITp06EDbtm2BF3fmXrduncZN/Hr16gW8OBsqhCi8ctWjf/XqVdRqNR06dOCXX35h165dmJqaEhQUxIULF/jll19o2bLl24pVFGI//vgjVapUwdjYGGtrazw8PBg1ahQrVqzgp59+Unqso6KiADh69Chubm4YGRlRq1YtTp48meO60nvmf/vtN2rWrImhoSEHDhwgLS2N0NBQ5XR3tWrV+PHHH4EXH4bNmjUDoGjRoqhUKuUOto6OjoSHh2vUUb16dY27DatUKhYvXkz79u0xNTVl2rRpBAcHU716dVatWoWjoyMWFhZ0796dx48f5zgXPT09bG1tlUexYsVyvK8QonBq0KABu3fv5vLlywCcPn2aAwcOyBTCQmihXHX/OTs7c/v2bYoXL07jxo2xsrLi7NmzlChR4m3FJ7TA7du36dGjB2FhYXTq1InHjx+zf/9+evfuTVxcHPHx8Sxfvhx4MWtOQkIC7dq1o2XLlqxevZpr167l6W7MY8eOZdasWZQpU4aiRYsSGhrK6tWrWbJkCc7Ozuzbt49PPvkEGxsbGjVqxMaNG+nSpQuXLl3C3Nw819NxBgcHM336dMLDw9HT02PZsmXExMSwZcsWfv31Vx48eICPjw/Tp09n2rRpOTrmlStXsLe3x8jIiPr16xMaGkqpUqUyLZuUlERSUpKyHB8fD0CTGbtI0TfNVS4fIkMdNVNqQc3J20lKUxV0OG+dNuWrTblCxnzPBXtqbB8xYgQPHjygQoUK6OrqkpqayuTJk/Hx8clwHV36cnJy8nt7jd3LMWoDbcpXm3KF/Ms3N/vnqqH/6nzov/32G0+ePMnNIYTI4Pbt26SkpNC5c2dKly4NQJUqVYAXU3AmJSVha2urlI+IiCAtLY3vv/8eIyMjKlWqxM2bNxk0aFCu6p08ebJyBiopKYmvvvqKXbt2Ub9+fQDKlCnDgQMH+Oabb2jatKkyLWfx4sWxtLTMdZ49e/akT58+GuvS0tKIiIjAzMwMeHE6fffu3Tlq6NetW5eIiAhcXFy4ffs2ISEhNG7cmHPnzinHe1loaCghISEZ1k9wS8PEJDXX+XyoptRKK+gQ3iltylebcoX/y3fbtm0a6/fv309ERATDhw/HwcGBa9euERYWxt27d2nevLlG2X///ReAAwcO8Pfff7+bwPMoMjKyoEN4p7QpX23KFd4838TExByXfaMBvVndCEmI3KhWrRotWrSgSpUqeHp60qpVK7p27UrRokUzLX/hwgWqVq2KkZGRsi69cZ4btWrVUn6Pjo4mMTExw9Cz58+f59sF5i/Xl87R0VGjUW5nZ8edO3dydLyXT8NXrVqVunXrUrp0aTZs2JDpvSzGjRvH8OHDleX4+HgcHByYelKHFH3dDOULmxe9oGlMPK6jRb2+2pGvNuUKGfN9tUc/MDCQoKAgjc6PokWLsnbtWmbNmqVRNn2MfqNGjahevfrbDj1PkpOTiYyMpGXLlvlybdP7Tpvy1aZcIf/yTT8jnxO5auinj5N+dZ0Qb0JXV5fIyEgOHTrEzp07WbBgAePHj+fIkSNvtV5T0/8brpKQkADA1q1bKVmypEY5Q0PD1x5HR0cnw5fezE6rvVxfulf/0FUqFWlpeeuVtLS0pHz58kRHR2e63dDQMNNc9o3xwNraOk91fkiSk5PZtu3/tXfnYVGV///Hn8Mqi4AiCBgCuaIgoqhfxQJXcE0zLXdzKRdy39A03MKN1Kw0NcGtrNxzRxR3ccUlFRUh0jC0VEQUkDm/P/wxH0dQIVFk5v24rrlkzrnPOe/XIDP3nHOfc7ZyYmKg3nyg6EtefcoKL86bnp6OsbGx1jwTExMURcnVPuf50+3fRMWhxsKkT3n1KSu8fN6CLFvgoTu9evXSdBYePnxI//79c3Vg1q1bV5DVCoFKpcLX1xdfX18mTpyIi4sL69evx8TEhOxs7WEl7u7urFixgocPH2r26h85cuSltl+tWjVMTU1JSkrCz88vzzYmJiYAueqxs7MjOTlZ8zw1NZWEhISXque/SEtLIz4+XnM1DSGEfmrTpg3Tpk2jfPnyVK9enVOnTvHVV1/Ru3dvTZt///2XpKQkzXCduLg4AM2J/UII3VCgjn7Pnj21nnfr1q1QixH6KSYmhqioKJo3b469vT0xMTHcvHkTd3d3Hj58yI4dO4iLi8PW1hZra2u6dOnC+PHj6devH8HBwSQmJuY6HF1QJUuWZOTIkQwbNgy1Wk3Dhg25e/cuBw8exMrKip49e+Li4oJKpWLz5s20bNkSMzMzLC0tady4MREREbRp0wYbGxsmTpyodcfoV2XkyJG0adMGFxcX/vrrL7744gsMDQ3p3LnzK9+2EOLNNX/+fCZMmMDAgQNJSUnBycmJTz/9lIkTJ2rabNq0SeucoY8++giAL774QuuKYUKI4q1AHf2cK58IUZisrKzYt28fc+fOJTU1FRcXF8LCwmjRogU+Pj5ER0fj4+NDWloae/bswd/fn99++43+/fvj7e1NtWrVmDFjBh06dHipOqZMmYKdnR2hoaFcvXoVGxsbatWqxbhx4wAoV64ckyZNYuzYsXz88cf06NGDiIgIgoODSUhIoHXr1lhbWzNlypTXskf/2rVrdO7cmX/++UdzZaAjR45gZ2f3yrcthHhzlSxZkrlz5+a67O+TevXqpblEsBBCd6kUOaNWCL2UmpqKtbU1t27d0qsx+i1bttSLsaD6lFefsoLk1XX6lFefskLh5c35/L579y5WVlbPbVugG2YJIYQQQgghigfp6Aud079/fywtLfN89O/fv6jLy5ekpKRnZrC0tCQpKamoSxRCCCHEG+6lrqMvxJto8uTJjBw5Ms95LzrE9aZwcnIiNjb2ufOFEEIIIZ5HOvpC59jb22Nvb1/UZbwUIyMjKlasWNRlCCGEEKIYk6E7QgghhBBC6CDp6AshhBBvGFdXV83d6J98DBo0SNPmyJEjNG7cGAsLC6ysrHj33Xd58OBBEVYthHjTSEdfiOeIjo5GpVJx586dV76tiIgIbGxsNM9DQkKoWbPmK9+uEOLNc+zYMZKTkzWPyMhIADp27AjAxYsXad26Nc2bN+fo0aMcO3aMoKAgDAzkY10I8T8yRl8UGyEhIWzYsOG5J6kWZx9++CEtW7Ys6jKEEG+Ap298N336dCpUqICfnx+PHj1i6dKlDBo0iLFjx2raVKlS5XWXKYR4w8lXfyHeEGZmZsX+JGIhROHLzMxk5cqV9O7dG5VKRUpKCpcuXcLe3p4GDRpQtmxZ/Pz8OHDgQFGXKoR4w8geffFaqdVqZs+ezaJFi/jzzz8pW7Ysn376KePHj2fMmDGsX7+ea9eu4eDgQNeuXZk4cSLGxsZEREQwadIkAFQqFQDh4eHPvYV7ly5dyM7O5ueff9ZMy8rKwtHRka+++ooePXqQkZHBqFGjWL16Nampqfj4+DBnzhzq1KlT4Gx//PEHQUFBHDhwgMzMTFxdXZk1axYtW7YkOjqaRo0asXnzZoKDg7l06RI1a9ZkyZIleHh4AI+H7gwdOvSZw4Ti4+Np1qwZLVu2ZP78+WRmZjJ+/Hh++ukn7ty5g4eHBzNmzMDf379AddcLjeKRkUWB8xY3poYKM+uCR8gOMrJVRV3OK6dPeXUha+L0Vs+ct2HDBu7cuaN5v0tISABgypQpzJ49m5o1a7J8+XKaNGnCuXPnqFSp0usoWQhRDEhHX7xWwcHBLF68mDlz5tCwYUOSk5O5ePEiACVLliQiIgInJyfOnj1Lv379KFmyJKNHj+bDDz/k3LlzbN++nV27dgFgbW393G117dqVjh07kpaWhqWlJQA7duwgPT2d9u3bAzB69GjWrl3LsmXLcHFxYebMmQQEBHDlyhVKly5doGyDBg0iMzOTffv2YWFhwfnz5zXbzTFq1CjmzZuHg4MD48aNo02bNly6dOmFt8I+c+YMAQEB9OnTh6lTpwIQFBTE+fPnWb16NU5OTqxfv57AwEDOnj2b5wd9RkYGGRkZmuepqakAmBooGBoqBcpaHJkaKFr/6jp9yqsLWbOysp45b8mSJQQEBGBnZ0dWVhaZmZkA9O7dm27dugEwc+ZMdu3axeLFi5k2bdprqfl1yXltnvca6RJ9yqtPWaHw8hZkeenoi9fm3r17zJs3j2+++YaePXsCUKFCBRo2bAjA559/rmnr6urKyJEjWb16NaNHj8bMzAxLS0uMjIxwcHDI1/YCAgKwsLBg/fr1dO/eHYAff/yRtm3bUrJkSe7fv8+CBQuIiIigRYsWACxevJjIyEh++OEHRo0aVaB8SUlJdOjQAU9PTwDefvvtXG2++OILmjVrBsCyZct46623WL9+PZ06dXrmeg8dOkTr1q0ZP348I0aM0GwrPDycpKQkzc2zRo4cyfbt2wkPD+fLL7/MtZ7Q0FDNUZEnfe6txtw8u0BZi7MpPuqiLuG10qe8xTnr1q1b85yekpJCVFQUY8aM0bT5+++/AXj06JHWctbW1sTExDxzXcVdzgnJ+kKf8upTVnj5vOnp6fluKx198dpcuHCBjIwMmjRpkuf8n3/+ma+//pr4+HjS0tJ49OjRS93J1sjIiE6dOrFq1Sq6d+/O/fv32bhxI6tXrwYeD4XJysrC19dXs4yxsTF169blwoULBd7e4MGDGTBgADt37qRp06Z06NCBGjVqaLWpX7++5ufSpUtTpUqV524rKSmJZs2aMW3aNIYOHaqZfvbsWbKzs6lcubJW+4yMDGxtbfNcV3BwMMOHD9c8T01NxdnZmamnDHhkbFiQqMWSqYHCFB81E44bkKEunsM7CkKf8upC1nMhAXlOnzx5Mvb29kyYMAEjo8cf2ZmZmQQHB2Nqaqp1Av8XX3xBQECAzp3Un5WVRWRkJM2aNXvh0U9doE959SkrFF7enCPy+SEdffHamJmZPXPe4cOH6dq1K5MmTSIgIABra2tWr15NWFjYS22za9eu+Pn5kZKSQmRkJGZmZgQGBr7UOp+lb9++BAQEsGXLFnbu3EloaChhYWF89tln/3mddnZ2ODk58dNPP9G7d2/NF5+0tDQMDQ05ceIEhobanfSnhwvlMDU1xdTUNNf0fWOaPvPLgS7Jyspi69atnJgYqDcfKPqSV1ezqtVqli9fTs+ePXO9f7Zr144FCxbg4+NDzZo1WbZsGXFxcaxdu1anXoMnGRsb62y2vOhTXn3KCi+ftyDLylV3xGtTqVIlzMzMiIqKyjXv0KFDuLi4MH78eHx8fKhUqRJ//PGHVhsTExOysws2xKRBgwY4Ozvz888/s2rVKjp27Kj5A6lQoQImJiYcPHhQ0z4rK4tjx45RrVq1/5AQnJ2d6d+/P+vWrWPEiBEsXrxYa/6RI0c0P9++fZtLly7h7u7+zPWZmZmxefNmSpQoQUBAAPfu3QPA29ub7OxsUlJSqFixotYjv0ObhBBvtl27dpGUlETv3r1zzWvbti2jR49m2LBheHl5ERUVRWRkJBUqVCiCSoUQbyrZoy9emxIlSjBmzBhGjx6NiYkJvr6+3Lx5k99//51KlSqRlJTE6tWrqVOnDlu2bGH9+vVay7u6upKQkEBsbCxvvfUWJUuWzHMP9dO6dOnCwoULuXTpEnv27NFMt7CwYMCAAYwaNYrSpUtTvnx5Zs6cSXp6On369ClwvqFDh9KiRQsqV67M7du32bNnT65O/OTJk7G1taVs2bKMHz+eMmXK0K5du+eu18LCgi1bttCiRQtatGjB9u3bqVy5Ml27dqVHjx6EhYXh7e3NzZs3iYqKokaNGrRq9ewreAghiofmzZujKM8+wXj06NGMHz/+NVYkhChuZI++eK0mTJjAiBEjmDhxIu7u7nz44YekpKTQtm1bhg0bRlBQEDVr1uTQoUNMmDBBa9kOHToQGBhIo0aNsLOz46effsrXNrt27cr58+cpV66c1nh8eHwTmg4dOtC9e3dq1arFlStX2LFjB6VKlSpwtuzsbAYNGoS7uzuBgYFUrlyZ7777Ltf2hgwZQu3atblx4wa//fYbJiYmL1y3paUl27ZtQ1EUWrVqxf379wkPD6dHjx6MGDGCKlWq0K5dO44dO0b58uULXLsQQgghdI9Ked7uAiFEoci5jv7t27exsbEp6nKAxyfzWFtbc+vWLb0ao9+yZUu9GAuqT3n1KStIXl2nT3n1KSsUXt6cz++7d+++8KIlskdfCCGEEEIIHSQdfVFsrVq1CktLyzwf1atXL/TttWjR4pnby+u69UIIIYQQRUlOxhXFVtu2balXr16e817FIcAlS5bw4MGDPOe96C66/v7+zz2pTgghhBCisElHXxRbJUuWpGTJkq9te+XKlXtt2xJCCCGEeFkydEcIIYQQQggdJB198cZLTExEpVIRGxtb1KUIIcR/4urqikqlyvUYNGgQ//77L5999hlVqlTBzMyM8uXLM3jwYO7evVvUZQshijnp6Isi06tXrxfeLOp1iY6ORqVScefOnaIuBYB9+/bRpk0bnJycUKlUbNiwIVebXr165eo0BAYGvv5ihRAvdOzYMZKTkzWPyMhIADp27Mhff/3FX3/9xezZszl37hwRERFs3779P924TwghniRj9IVOUxSF7OxsjIxe33/1rKyslz4Z+P79+3h5edG7d2/ef//9Z7YLDAwkPDxc8zw/dwoWQrx+dnZ2Ws+nT59OhQoV8PPzQ6VSsXbtWs28ChUqMG3aNLp168ajR49e6/uXEEK3yB598cqtWbMGT09PzMzMsLW1pWnTpowaNYply5axceNGzd7o6OhoAI4ePYq3tzclSpTAx8eHU6dO5XtbOXvmt23bRu3atTE1NeXAgQOo1WpCQ0Nxc3PDzMwMLy8v1qxZAzweGtSoUSMASpUqhUqlolevXsDjw+1z587V2kbNmjUJCQnRPFepVCxYsIC2bdtiYWHBtGnTCAkJoWbNmqxYsQJXV1esra356KOPuHfvXr5ytGjRgqlTp9K+ffvntjM1NcXBwUHz+C939BVCvF6ZmZmsXLmS3r17o1Kp8myTcyMc6eQLIV6GvIOIVyo5OZnOnTszc+ZM2rdvz71799i/fz89evQgKSmJ1NRUzR7p0qVLk5aWRuvWrWnWrBkrV64kISGBIUOGFHi7Y8eOZfbs2bz99tuUKlWK0NBQVq5cycKFC6lUqRL79u2jW7du2NnZ0bBhQ9auXUuHDh2Ii4vDysoKMzOzAm0vJCSE6dOnM3fuXIyMjFi6dCnx8fFs2LCBzZs3c/v2bTp16sT06dOZNm1agfM8S3R0NPb29pQqVYrGjRszderUAt/ltl5oFI+MLAqtpjeVqaHCzLrgEbKDjOy8O1e6RJ/yvolZE6e3eua8DRs2cOfOHc0OhafdunWLKVOm8Mknn7yi6oQQ+kI6+uKVSk5O5tGjR7z//vu4uLgA4OnpCYCZmRkZGRk4ODho2kdERKBWq/nhhx8oUaIE1atX59q1awwYMKBA2508eTLNmjUDICMjgy+//JJdu3ZRv359AN5++20OHDjA999/j5+fn+Y6+Pb29tjY2BQ4Z5cuXfj444+1pqnVaiIiIjSXAO3evTtRUVGF1tEPDAzk/fffx83Njfj4eMaNG0eLFi04fPgwhoaGudpnZGSQkZGheZ6amgqAqYGCoaHuX+Pf1EDR+lfX6VPeNzFrVlbWM+ctWbKEgIAA7OzscrVLTU2lZcuWuLu7M378+DzXkzPtedvQJZJXd+lTVii8vAVZXjr64pXy8vKiSZMmeHp6EhAQQPPmzfnggw+eOcTkwoUL1KhRgxIlSmim5XTOC8LHx0fz85UrV0hPT9d0/HNkZmbi7e1d4HW/aHs5XF1dta7z7+joSEpKSqFsD+Cjjz7S/Ozp6UmNGjWoUKEC0dHRNGnSJFf70NBQJk2alGv6595qzM2zC62uN90UH3VRl/Ba6VPeNynr1q1b85yekpJCVFQUY8aMydXmwYMHhISEYGpqSp8+fTQn7D7Li+brGsmru/QpK7x83vT09Hy3lY6+eKUMDQ2JjIzk0KFD7Ny5k/nz5zN+/HhiYmJe6XYtLP43FCUtLQ2ALVu25Lrp1YtOXjUwMMh1R9u8vkk/ub0cT5+Qq1KpUKtfXUfk7bffpkyZMly5ciXPjn5wcDDDhw/XPE9NTcXZ2ZlGjRoVeLhPcZSVlUVkZCTNmjV7JXdOftPoU97ilHXy5MnY29szYcIErfH3qamptGrVirJly7Jp0ybMzc2fuY7ilLcwSF7dpU9ZofDy5hyRzw/p6ItXTqVS4evri6+vLxMnTsTFxYX169djYmJCdrb2nmR3d3dWrFjBw4cPNXv1jxw58lLbr1atGqampiQlJeHn55dnGxMTE4Bc9djZ2ZGcnKx5npqaSkJCwkvV86pcu3aNf/75B0dHxzznm5qa5vnFxtjYWC/eYHNIXt31pmdVq9UsX76cnj17ap0HlNPJT09PZ9WqVTx48IAHDx4Aj9+D8hqKB29+3sImeXWXPmWFl89bkGWloy9eqZiYGKKiomjevDn29vbExMRw8+ZN3N3defjwITt27CAuLg5bW1usra3p0qUL48ePp1+/fgQHB5OYmMjs2bNfqoaSJUsycuRIhg0bhlqtpmHDhty9e5eDBw9iZWVFz549cXFxQaVSsXnzZlq2bImZmRmWlpY0btyYiIgI2rRpg42NDRMnTnzmh25hSktL48qVK5rnCQkJxMbGUrp0acqXL09aWhqTJk2iQ4cOODg4EB8fz+jRo6lYsSIBAQGvvD4hRMHt2rWLpKQkevfurTX95MmTmqOcFStW1JqXkJCAq6vr6ypRCKFjpKMvXikrKyv27dvH3LlzSU1NxcXFhbCwMFq0aIGPjw/R0dH4+PiQlpbGnj178Pf357fffqN///54e3tTrVo1ZsyYQYcOHV6qjilTpmBnZ0doaChXr17FxsaGWrVqMW7cOADKlSvHpEmTGDt2LB9//DE9evQgIiKC4OBgEhISaN26NdbW1kyZMuW17NE/fvy45pKfgGbITc+ePYmIiMDQ0JAzZ86wbNky7ty5g5OTE82bN2fKlClyLX0h3lDNmzfPNRQQwN/fP8/pQgjxslSKvLsIoZdSU1Oxtrbm1q1bejNGf+vWrbRs2VIvDhHrU159ygqSV9fpU159ygqFlzfn8zvnfhvPIzfMEkIIIYQQQgdJR18UK/3798fS0jLPR//+/Yu6vHxJSkp6ZgZLS0uSkpKKukQhhBBC6AAZoy+KlcmTJzNy5Mg8573o8NWbwsnJidjY2OfOF0IIIYR4WdLRF8WKvb099vb2RV3GSzEyMsp1ZQ0hhBBCiMImQ3eEEEIIIYTQQdLRF0IIIV4BV1dXVCpVrsegQYMAWLRoEf7+/lhZWaFSqbhz507RFiyE0DnS0ReikCUmJqJSqZ47Dl8IofuOHTtGcnKy5hEZGQlAx44dAUhPTycwMFBzPw8hhChs0tEXopg6fPgwjRs3xsLCAisrK959910ePHhQ1GUJIf4/Ozs7HBwcNI/NmzdToUIF/Pz8ABg6dChjx47l//7v/4q4UiGErpKOvhDF0OHDhwkMDKR58+YcPXqUY8eOERQUhIGB/EkL8SbKzMxk5cqV9O7dG5VKVdTlCCH0hFx1R+g0f39/PD09MTQ0ZNmyZZiYmDB16lS6dOlCUFAQa9asoWzZssyfP58WLVqQnZ3NJ598wu7du7lx4wbly5dn4MCBDBkyRLNOtVrN1KlTWbRoETdv3sTd3Z3p06cTGBiote2LFy8ycOBATp48ScWKFfn222/x8/NDrVZTvnx5xo8fz4ABAzTtT506Re3atUlISMDFxeW5uYYNG8bgwYMZO3asZlqVKlX+02tULzSKR0YW/2nZ4sTUUGFmXfAI2UFGtu53tPQp75uSNXF6q2fO27BhA3fu3KFXr16vryAhhN6Tjr7QecuWLWP06NEcPXqUn3/+mQEDBrB+/Xrat2/PuHHjmDNnDt27dycpKQljY2Peeustfv31V2xtbTl06BCffPIJjo6OdOrUCYB58+YRFhbG999/j7e3N0uXLqVt27b8/vvvVKpUSbPdUaNGMXfuXKpVq8ZXX31FmzZtSEhIwNbWls6dO/Pjjz9qdfRXrVqFr6/vCzv5KSkpxMTE0LVrVxo0aEB8fDxVq1Zl2rRpNGzY8JnLZWRkkJGRoXmempoKgKmBgqGh8p9e2+LE1EDR+lfX6VPeNyVrVlbWM+ctWbKEgIAA7OzscrV79OiRZvnnrePp7eSnrS6QvLpLn7JC4eUtyPIqRVF0/1NA6C1/f3+ys7PZv38/ANnZ2VhbW/P++++zfPlyAG7cuIGjoyOHDx/Oc6xsUFAQN27cYM2aNQCUK1eOQYMGaZ1AV7duXerUqcO3335LYmIibm5uTJ8+nTFjxgCPP8jd3Nz47LPPGD16NLGxsdSqVYvExETKly+v2cv/+eefv/AOv0eOHKF+/fqULl2a2bNnU7NmTZYvX853333HuXPntL5sPCkkJIRJkyblmv7jjz9ibm6ej1dTCPFfpKSk0L9/f8aMGUO9evVyzT979iwTJkxg5cqVWFpaFkGFQojiJD09nS5dunD37t0X3ixU9ugLnVejRg3Nz4aGhtja2uLp6amZVrZsWeDxhzHAt99+y9KlS0lKSuLBgwdkZmZSs2ZN4PFe8L/++gtfX1+tbfj6+nL69GmtafXr19f8bGRkhI+PDxcuXACgZs2auLu78+OPPzJ27Fj27t1LSkqK5mocz6NWqwH49NNP+fjjjwHw9vYmKiqKpUuXEhoamudywcHBDB8+XPM8NTUVZ2dnpp4y4JGx4Qu3W9yZGihM8VEz4bgBGWrdHsoC+pX3Tcl6LiQgz+mTJ0/G3t6eCRMmYGSU+2PXwuLx0LnmzZtjY2Pzwu1kZWURGRlJs2bNMDY2fqmaiwPJq7v0KSsUXt6cI/L5IR19ofOe/mNSqVRa03JOjFOr1axevZqRI0cSFhZG/fr1KVmyJLNmzSImJqbQ6+rataumo//jjz8SGBiIra3tC5dzdHQEoFq1alrT3d3dSUpKeuZypqammJqa5pq+b0zTfG23uMvKymLr1q2cmBioNx8o+pL3Tc6qVqtZvnw5PXv2xMzMTGvejRs3uHHjBomJicDj83pKlixJ+fLlKV269AvXbWxs/MblfZUkr+7Sp6zw8nkLsqxcokOIJxw8eJAGDRowcOBAvL29qVixIvHx8Zr5VlZWODk5cfDgwVzLPd3xPnLkiObnR48eceLECdzd3TXTunTpwrlz5zhx4gRr1qyha9eu+arR1dUVJycn4uLitKZfunTpheP7hRCv165du0hKSqJ379655i1cuBBvb2/69esHwLvvvou3tzebNm163WUKIXSU7NEX4gmVKlVi+fLl7NixAzc3N1asWMGxY8dwc3PTtBk1ahRffPEFFSpUoGbNmoSHhxMbG8uqVau01vXtt99SqVIl3N3dmTNnDrdv39b6sHd1daVBgwb06dOH7Oxs2rZtm68aVSqVpgYvLy9q1qzJsmXLuHjxouY8AiHEm6F58+Y861S4kJAQQkJCXm9BQgi9Ih19IZ7w6aefcurUKT788ENUKhWdO3dm4MCBbNu2TdNm8ODB3L17lxEjRpCSkkK1atXYtGlTrpNgp0+fzvTp04mNjaVixYps2rSJMmXKaLXp2rUrAwcOpEePHrkO6z/P0KFDefjwIcOGDePff//Fy8uLyMhIKlSo8HIvgBBCCCF0hnT0hU6Ljo7ONS1nPOyTntzjFh4eTnh4uNb8J09wNTAw4IsvvuCLL77Ic5uurq6a9XXu3Pm59Q0YMEDrEpsFMXbsWK3r6AshhBBCPEnG6AshhBBCCKGDpKMvxBtm1apVWFpa5vmoXr16UZcnhBBCiGJChu4I8YZp27ZtnjfVgYJdUksIIYQQ+k06+kK8YUqWLEnJkiWLugwhhBBCFHMydEcIIYQQQggdJB19IYQQ4iVdv36dbt26YWtri5mZGZ6enhw/flwz/++//6ZXr144OTlhbm5OYGAgly9fLsKKhRD6QDr6Qie4uroyd+7coi7jtYmOjkalUnHnzp2iLkUIvXf79m18fX0xNjZm27ZtnD9/nrCwMEqVKgU8vnxvu3btuHr1Khs3buTUqVO4uLjQtGlT7t+/X8TVCyF0mXT0xRspMTERlUpFbGzsa93um/iFwd/fn6FDhxZ1GUKIZ5gxYwbOzs6Eh4dTt25d3NzcaN68ueYGdpcvX+bIkSMsWLCAOnXqUKVKFRYsWMCDBw/46aefirh6IYQuk46+KNYyMzNf+zazs7NRq9WvfbtCiDfTpk2b8PHxoWPHjtjb2+Pt7c3ixYs18zMyMgAoUaKEZpqBgQGmpqYcOHDgtdcrhNAfctUdUaTUajWzZ89m0aJF/Pnnn5QtW5ZPP/2Uzz//HABvb28A/Pz8iI6OplevXty5c4c6derw7bffYmpqSkJCQr63pygKkyZNYunSpfz999/Y2trywQcf8PXXX+Pv788ff/zBsGHDGDZsmKZ9REQEQ4cOZfny5YwdO5ZLly5x5coVHB0dGT9+PD/99BN37tzBw8ODGTNm4O/vD6BZ7ueff2bo0KH8+eefNGzYkPDwcBwdHQF49OgRw4cPZ/ny5RgaGtK3b19u3LjB3bt32bBhA7169WLv3r3s3buXefPmAWjlPXHiBGPGjOH8+fPUrFmT8PBwqlSpUqDfQb3QKB4ZWRRomeLI1FBhZl3wCNlBRraqqMt55fQp7+vOmji9ldbzq1evsmDBAoYPH864ceM4duwYgwcPxsTEhJ49e1K1alXKly9PcHAw33//PRYWFsyZM4dr166RnJz8yusVQugv6eiLIhUcHMzixYuZM2cODRs2JDk5mYsXL3L06FHq1q3Lrl27qF69OiYmJpploqKisLKyIjIyssDbW7t2LXPmzGH16tVUr16dGzducPr0aQDWrVuHl5cXn3zyCf369dNaLj09nRkzZrBkyRJsbW2xt7cnKCiI8+fPs3r1apycnFi/fj2BgYGcPXuWSpUqaZabPXs2K1aswMDAgG7dujFy5EhWrVoFPD7kv2rVKsLDw3F3d2fevHls2LCBRo0aATBv3jwuXbqEh4cHkydPBsDOzo7ExEQAxo8fT1hYGHZ2dvTv35/evXtz8ODBPLNnZGRo9iwCpKamAmBqoGBoqBT4tSxuTA0UrX91nT7lfd1Zs7KytJ6r1Wpq167NpEmTAPDw8ODMmTMsWLCALl26APDLL7/wySefULp0aQwNDWnSpAmBgYEoipJrffndfkGXK64kr+7Sp6xQeHkLsrx09EWRuXfvHvPmzeObb76hZ8+eAFSoUIGGDRtqOrK2trY4ODhoLWdhYcGSJUu0Ov/5lZSUhIODA02bNsXY2Jjy5ctTt25dAM0HcMmSJXNtMysri++++w4vLy/NesLDw0lKSsLJyQmAkSNHsn37dsLDw/nyyy81yy1cuFAzVjcoKEjTYQeYP38+wcHBtG/fHoBvvvmGrVu3auZbW1tjYmKCubl5rpoApk2bhp+fHwBjx46lVatWPHz4UGuIQI7Q0FBNR+RJn3urMTfPzucrWPxN8dGvYVf6lPd1ZX3ybxTAxsYGS0tLremPHj3i8uXLWtMmT57M/fv3efToEdbW1owaNYqKFSvmWl9+/ZedHcWZ5NVd+pQVXj5venp6vttKR18UmQsXLpCRkUGTJk0KtJynp+d/6uQDdOzYkblz5/L2228TGBhIy5YtadOmDUZGz/9TMDExoUaNGprnZ8+eJTs7m8qVK2u1y8jIwNbWVvPc3Nxc08kHcHR0JCUlBYC7d+/y999/a75oABgaGlK7du18nwPwZE05w4FSUlIoX758rrbBwcEMHz5c8zw1NRVnZ2caNWqkVbOuysrKIjIykmbNmunFHYb1KW9RZ23cuDHXrl2jZcuWmmm7d++mcuXKWtOedPnyZeLj45k7dy7NmjUr0PaKOu/rJnl1lz5lhcLLm3NEPj+koy+KjJmZ2X9azsLiv48nd3Z2Ji4ujl27dhEZGcnAgQOZNWsWe/fufe4fnZmZGSrV/8b+pqWlYWhoyIkTJzA0NNRqa2lpqfn56XWqVCoUpfCGFzy5/pz6nvUlwdTUFFNT0zzXoQ9vsDkkr+4qqqwjRoygQYMGzJo1i06dOnH06FGWLFnCokWLNPX8+uuv2NnZUb58ec6ePcuQIUNo167dM78I5Ic+/W5B8uoyfcoKL5+3IMvKVXdEkalUqRJmZmZERUXlmpezxz47u/CHlJiZmdGmTRu+/vproqOjOXz4MGfPntVsNz/b9Pb2Jjs7m5SUFCpWrKj1yGuITV6sra0pW7Ysx44d00zLzs7m5MmTWu3yW5MQomjUqVOH9evX89NPP+Hh4cGUKVOYO3cuXbt21bRJTk6me/fuVK1alcGDB9O9e3e5tKYQ4pWTPfqiyJQoUYIxY8YwevRoTExM8PX15ebNm/z+++/07NkTMzMztm/fzltvvUWJEiWwtrZ+6W1GRESQnZ1NvXr1MDc3Z+XKlZiZmeHi4gI8vo7+vn37+OijjzA1NaVMmTJ5rqdy5cp07dqVHj16EBYWhre3Nzdv3iQqKooaNWrQqlWrPJd72meffUZoaCgVK1akatWqzJ8/n9u3b2sdPXB1dSUmJobExEQsLS0pXbr0S78OQojC1bp1a1q3bv3M+YMHD2bw4MGvsSIhhJA9+qKITZgwgREjRjBx4kTc3d358MMPSUlJwcjIiK+//prvv/8eJycn3nvvvULZno2NDYsXL8bX15caNWqwa9cufvvtN80Y9cmTJ5OYmEiFChWws7N77rrCw8Pp0aMHI0aMoEqVKrRr145jx47lOT7+WcaMGUPnzp3p0aMH9evXx9LSkoCAAK2TaUeOHImhoSHVqlXDzs6OpKSk/xZeCCGEEHpFpRTmgGEhxEtRq9W4u7vTqVMnpkyZ8kq3lZqairW1Nbdu3dKbk3G3bt1Ky5Yt9WIsqD7l1aesIHl1nT7l1aesUHh5cz6/7969i5WV1XPbytAdIYrQH3/8wc6dO/Hz8yMjI4NvvvmGhIQEzbW3hRBCCCH+Kxm6I3TKqlWrsLS0zPNRvXr1oi4vFwMDAyIiIqhTpw6+vr6cPXuWXbt24e7uXtSlCSGEEKKYkz36Qqe0bduWevXq5TnvTTws6Ozs/Mw72QohhBBCvAzp6AudUrJkSUqWLFnUZQghhBBCFDkZuiOEEEIIIYQO0uuOfmJiIiqVitjY2KIuRTyHv78/Q4cOLeoyhBCC69ev061bN2xtbTEzM8PT05Pjx49r5qtUqjwfs2bNKsKqhRD6Sic7+r169aJdu3ZFXQYA0dHRqFQq7ty5U9SlABASEpLrA6hq1aoFXo+bmxu7du36z3W8aa+Lq6src+fOLeoyNH755Rdq1qyJubk5Li4ueXYSoqOjqVWrFqamplSsWJGIiIjXX6gQeuT27dv4+vpibGzMtm3bOH/+PGFhYZQqVUrTJjk5WeuxdOlSVCoVHTp0KMLKhRD6Ssbo/0eKopCdnY2R0et7CbOysgrlhNLq1atrddILmuHMmTPcvn0bPz+/l67lVcvMzMTExKRYbW/btm107dqV+fPn07x5cy5cuEC/fv0wMzMjKCgIgISEBFq1akX//v1ZtWoVUVFR9O3bF0dHRwICAgojihDiKTNmzMDZ2Znw8HDNNDc3N602Dg4OWs83btxIo0aNePvtt19LjUII8aRivUd/zZo1eHp6YmZmhq2tLU2bNmXUqFEsW7aMjRs3avZYR0dHA3D06FG8vb0pUaIEPj4+nDp1Kt/bytkDvW3bNmrXro2pqSkHDhxArVYTGhqKm5sbZmZmeHl5sWbNGuDx0KBGjRoBUKpUKVQqFb169QLy3oNcs2ZNQkJCNM9VKhULFiygbdu2WFhYMG3aNEJCQqhZsyYrVqzA1dUVa2trPvroI+7du5fvLEZGRjg4OGgeZcqUyfey8PiDKzAw8IVfOv744w/atGlDqVKlsLCwoHr16mzduvW5r8v9+/fp0aMHlpaWODo6EhYWVqDaXF1dmTJlCj169MDKyopPPvkEgAMHDvDOO+9gZmaGs7MzgwcP5v79+8DjoUF//PEHw4YN0/yfATSv9ZPmzp2Lq6ur5nnO0aNp06bh5ORElSpVNEPC1q1bR6NGjTA3N8fLy4vDhw/nK8OKFSto164d/fv35+2336ZVq1YEBwczY8YMcu5vt3DhQtzc3AgLC8Pd3Z2goCA++OAD5syZU6DXSwiRf5s2bcLHx4eOHTtib2+Pt7c3ixcvfmb7v//+my1bttCnT5/XWKUQQvxPsd2jn5ycTOfOnZk5cybt27fn3r177N+/nx49epCUlERqaqpmr0vp0qVJS0ujdevWNGvWjJUrV5KQkMCQIUMKvN2xY8cye/Zs3n77bUqVKkVoaCgrV65k4cKFVKpUiX379tGtWzfs7Oxo2LAha9eupUOHDsTFxWFlZYWZmVmBthcSEsL06dOZO3cuRkZGLF26lPj4eDZs2MDmzZu5ffs2nTp1Yvr06UybNi1f67x8+TJOTk6UKFGC+vXrExoaSvny5fNd06ZNmxg+fPgL2w0aNIjMzEz27duHhYUF58+fx9LSEmdn52e+LqNGjWLv3r1s3LgRe3t7xo0bx8mTJ3N1uJ9n9uzZTJw4kS+++AKA+Ph4AgMDmTp1KkuXLuXmzZsEBQURFBREeHg469atw8vLi08++YR+/frlezs5oqKisLKyIjIyUmv6+PHjmT17NpUqVWL8+PF07tyZK1euvPAISkZGBubm5lrTzMzMuHbtGn/88Qeurq4cPnyYpk2barUJCAh47rkMGRkZZGRkaJ6npqYC8O6MXTwytshP1GLN1EBhig/UnrydDLWqqMt55fQp76vKei5E++jY1atXWbBgAUOGDGHUqFGcOHGCwYMHY2BgQI8ePXItv3TpUkqWLEmbNm3IysoqtLpy1lWY63yTSV7dpU9ZofDyFmT5Yt3Rf/ToEe+//z4uLi4AeHp6Ao87RRkZGVqHUCMiIlCr1fzwww+UKFGC6tWrc+3aNQYMGFCg7U6ePJlmzZoBjztOX375Jbt27aJ+/foAvP322xw4cIDvv/8ePz8/SpcuDYC9vT02NjYFztmlSxc+/vhjrWlqtZqIiAjNZSS7d+9OVFRUvjr69erVIyIigipVqpCcnMykSZN45513OHfuXL4uS3n9+nXOnDlDixYtXtg2KSmJDh06aH4vTx66zut1SUtL44cffmDlypU0adIEgGXLlvHWW2+9cFtPaty4MSNGjNA879u3L127dtV0gitVqsTXX3+Nn58fCxYsoHTp0hgaGlKyZMlch93zw8LCgiVLlmiG7CQmJgIwcuRIWrVqBcCkSZOoXr06V65ceeE5EQEBAQwbNoxevXrRqFEjrly5ojmykZycjKurKzdu3KBs2bJay5UtW5bU1FQePHiQ5xfK0NBQJk2alGv6595qzM2zC5y7uJrioy7qEl4rfcpb2Fm3bt2q9Tw7O5sKFSrQoEEDkpOTcXJyokmTJsyaNSvPI6Pffvst9evXZ/fu3YVaV46ndy7oOsmru/QpK7x83vT09Hy3LbYdfS8vL5o0aYKnpycBAQE0b96cDz74QOukqCdduHCBGjVqUKJECc20nM55Qfj4+Gh+vnLlCunp6ZqOf47MzEy8vb0LvO4XbS+Hq6urVqfc0dGRlJSUfK3vyQ56jRo1qFevHi4uLvzyyy/5Ory8adMmGjZsmK8vLYMHD2bAgAHs3LmTpk2b0qFDB2rUqPHM9vHx8WRmZmrd8Kp06dJUqVLlhdt60tOv2enTpzlz5gyrVq3STFMUBbVaTUJCwkvfhdbT0zPPcflPZnV0dAQgJSXlhR39fv36ER8fT+vWrcnKysLKyoohQ4YQEhKCgcF/H20XHBysdSQmNTUVZ2dnpp4y4JGx4X9eb3HxeK+vmgnHDXR+DzfoV95XlfXpPfpOTk40aNCAli1baqb9+eefhIaGak2Dx8MFr1+/zoYNG/Dy8iq0muDx3rzIyEiaNWv2Rt4IsLBJXt2lT1mh8PLmHJHPj2Lb0Tc0NCQyMpJDhw6xc+dO5s+fz/jx44mJiXml27Ww+N8Qh7S0NAC2bNlCuXLltNqZmpo+dz0GBgaa8dY58joU8+T2cjz9n0OlUqFW/7c9WTY2NlSuXJkrV67kq/2mTZto27Ztvtr27duXgIAAtmzZws6dOwkNDSUsLIzPPvvsP9WaX0+/ZmlpaXz66acMHjw4V9vnDVl6md8RaP+ecsb95+f3pFKpmDFjBl9++SU3btzAzs6OqKgo4H9HRRwcHPj777+1lvv777+fOzzM1NQ0z/+X+8Y0xdbW9oV1FXdZWVls3bqVExNffH6JLtCnvK8rq6+vL5cvX9baRnx8PC4uLrm2u2zZMmrXrp3nzprCYmxsrPO/2ydJXt2lT1nh5fMWZNlifTKuSqXC19eXSZMmcerUKUxMTFi/fj0mJiZkZ2sPRXB3d+fMmTM8fPhQM+3IkSMvtf1q1aphampKUlISFStW1Ho4OzsDaPb0Pl2PnZ0dycnJmuepqakkJCS8VD3/RVpaGvHx8Zo9zi9qu2fPHt577718r9/Z2Zn+/fuzbt06RowYoTlxLa/XpUKFChgbG2t9Wbt9+zaXLl3K9/byUqtWLc6fP5/rd1SxYkVNHXn9n7Gzs+PGjRtanf3Xec8FQ0NDypUrh4mJCT/99BP169fHzs4OeHw0KqfznyMyMvI/HaUSQuTPsGHDOHLkCF9++SVXrlzhxx9/ZNGiRQwaNEirXWpqKr/++it9+/YtokqFEOKxYtvRj4mJ4csvv+T48eMkJSWxbt06bt68ibu7O66urpw5c4a4uDhu3bpFVlYWXbp0QaVS0a9fP86fP8/WrVuZPXv2S9VQsmRJRo4cybBhw1i2bBnx8fGcPHmS+fPns2zZMgBcXFxQqVRs3ryZmzdvao4CNG7cmBUrVrB//37Onj1Lz549MTR89cMnRo4cyd69e0lMTOTQoUO0b98eQ0NDOnfu/MJlt2/fTuXKlbWuOvM8Q4cOZceOHSQkJHDy5En27NmjGSaT1+tiaWlJnz59GDVqFLt37+bcuXP06tXrpYarAIwZM4ZDhw4RFBREbGwsly9fZuPGjZpLVcLj4VD79u3j+vXr3Lp1C3h8NZ6bN28yc+ZM4uPj+fbbb9m2bdtL1ZIft27dYuHChVy8eJHY2FiGDBnCr7/+qnWVpv79+3P16lVGjx7NxYsX+e677/jll18YNmzYK69PCH1Vp04d1q9fz08//YSHhwdTpkxh7ty5dO3aVavd6tWrURQlX++rQgjxKhXbjr6VlRX79u2jZcuWVK5cmc8//5ywsDBatGhBv379qFKlCj4+PtjZ2XHw4EEsLS357bffOHv2LN7e3owfP54ZM2a8dB1TpkxhwoQJhIaG4u7uTmBgIFu2bNFcW7lcuXJMmjSJsWPHUrZsWU3nMjg4GD8/P1q3bk2rVq1o164dFSpUeOl6XuTatWt07tyZKlWq0KlTJ2xtbTly5IhmT/HzbNy4Md/DduDx3vpBgwZpXpfKlSvz3XffAc9+XWbNmsU777xDmzZtaNq0KQ0bNqR27dr/Lez/V6NGDfbu3culS5d455138Pb2ZuLEiTg5OWnaTJ48mcTERCpUqKB5Ldzd3fnuu+/49ttv8fLy4ujRo4wcOfKlasmvZcuW4ePjg6+vL7///jvR0dHUrVtXM9/NzY0tW7YQGRmJl5cXYWFhLFmyRK6hL8Qr1rp1a86ePcvDhw8197h42ieffEJ6ejrW1tZFUKEQQvyPSnl6ELIQeXj06BFly5Zl27ZtWh1OUXylpqZibW3NrVu39GqMfsuWLfViLKg+5dWnrCB5dZ0+5dWnrFB4eXM+v+/evYuVldVz2xbbPfri9fr3338ZNmwYderUKepShBBCCCFEPkhH///r378/lpaWeT769+9f1OXlS1JS0jMzWFpakpSU9NzlV61a9cxlGzVqxOeff665egw8vlTns9p/+eWXhZ5v//79z81XXLzu100IIYQQ+qnYXl6zsE2ePPmZ469fdFjkTeHk5PTcq8I8OSY9L23bttW6hv2T8jrEtGTJEh48eJBn+5wbYhUmHx+f13rVm1fldb9uQgghhNBP0tH//+zt7bG3ty/qMl6KkZERFStW/M/LlyxZMl93x83x9L0DXjUzM7OXyvemeN2vmxBCCCH0kwzdEUIIIYQQQgdJR18IIYR4juvXr9OtWzdsbW0xMzPD09OT48ePa7W5cOECbdu2xdraGgsLC+rUqfPC86KEEOJVk46+EP9Beno6HTp0wMrKCpVKxZ07d4q6JCHEK3D79m18fX0xNjZm27ZtnD9/nrCwMEqVKqVpEx8fT8OGDalatSrR0dGcOXOGCRMmUKJEiSKsXAghZIy+EP/JsmXL2L9/P4cOHaJMmTKFcmOcXr16cefOHTZs2PDyBQohCsWMGTNwdnYmPDxcMy3nhog5xo8fT8uWLZk5c6Zm2uu4AaIQQryI7NEXWjIzM4u6hGIhPj4ed3d3PDw8cHBw0LrsaFGT36EQhWfTpk34+PjQsWNH7O3t8fb2ZvHixZr5arWaLVu2ULlyZQICArC3t6devXryhV0I8UaQPfp6zt/fHw8PD4yMjFi5ciWenp7Mnz+fUaNGsX//fiwsLGjevDlz5syhTJkyAKxZs4ZJkyZx5coVzM3N8fb2ZuPGjVhYWKBWq5k6dSqLFi3i5s2buLu7M336dAIDAwFITEzEzc2NtWvXMn/+fGJiYqhUqRILFy6kfv36APzzzz8EBQWxb98+bt++TYUKFRg3bhydO3fWqrtGjRqUKFGCJUuWYGJiQv/+/QkJCdG0uXPnDmPGjGHDhg3cvXuXihUrMn36dFq3bg3AgQMHCA4O5vjx45QpU4b27dsTGhqKhYXFC1+zvXv3AqBSqfDz8yM6OpoVK1Ywb9484uLisLCwoHHjxsydO1frak6///47Y8aMYd++fSiKQs2aNYmIiGDFihUsW7ZMs06APXv24O/vz9mzZxkyZAiHDx/G3NycDh068NVXX2nuHZBzJKBOnTp8++23mJqakpCQkO//A/VCo3hk9PzMusDUUGFmXfAI2UFG9pvzxexV0ae8hZk1cXorredXr15lwYIFDB8+nHHjxnHs2DEGDx6MiYkJPXv2JCUlhbS0NKZPn87UqVOZMWMG27dv5/3332fPnj34+fm9VD1CCPEypKMvWLZsGQMGDODgwYPcuXOHxo0b07dvX+bMmcODBw8YM2YMnTp1Yvfu3SQnJ9O5c2dmzpxJ+/btuXfvHvv370dRFADmzZtHWFgY33//Pd7e3ixdupS2bdvy+++/U6lSJc02x48fz+zZs6lUqRLjx4+nc+fOXLlyBSMjIx4+fEjt2rUZM2YMVlZWbNmyhe7du1OhQgXq1q2rVffw4cOJiYnh8OHD9OrVC19fX5o1a4ZaraZFixbcu3ePlStXUqFCBc6fP4+hoSHweI98YGAgU6dOZenSpdy8eZOgoCCCgoK0DtHnZd26dYwdO5Zz586xbt06TExMgMe3tp4yZQpVqlQhJSWF4cOH06tXL7Zu3Qo8PqHv3Xffxd/fn927d2NlZcXBgwd59OgRI0eO5MKFC6Smpmq2X7p0ae7fv09AQAD169fn2LFjpKSk0LdvX4KCgoiIiNDUFBUVhZWVFZGRkc+sOyMjg4yMDM3z1NRUAEwNFAwNlRf+PynuTA0UrX91nT7lLcysWVlZWs/VajW1a9dm0qRJAHh4eHDmzBkWLFhAly5dNH9Tbdq0ISgoCIDq1atz4MABvvvuOxo0aPDSNT2rxqdr1VWSV3fpU1YovLwFWV6l5PTQhF7y9/cnNTWVkydPAjB16lT279/Pjh07NG2uXbuGs7MzcXFxpKWlUbt2bRITE3Fxccm1vnLlyjFo0CDGjRunmVa3bl3N3uacPfpLliyhT58+AJw/f57q1atz4cIFqlatmmedrVu3pmrVqsyePVtTd3Z2Nvv379faTuPGjZk+fTo7d+6kRYsWXLhwgcqVK+daX9++fTE0NOT777/XTDtw4AB+fn7cv3//hSfRDR06lNjYWKKjo5/Z5vjx49SpU4d79+5haWnJuHHjWL16NXFxcXnegCyvMfqLFy9mzJgx/Pnnn5ojDVu3bqVNmzb89ddflC1bll69erF9+3aSkpI0XzryEhISoumsPOnHH3/E3Nz8uXmF0Ff9+vXDy8tL04kH2LZtG7/++itLly4lKyuLjz76iA8//JBOnTpp2ixbtowLFy4wffr0oihbCKHD0tPT6dKlC3fv3n3hTV1lj76gdu3amp9Pnz7Nnj17NMNCnhQfH0/z5s1p0qQJnp6eBAQE0Lx5cz744ANKlSpFamoqf/31F76+vlrL+fr6cvr0aa1pNWrU0Pzs6OgIQEpKClWrViU7O5svv/ySX375hevXr5OZmUlGRkauzuiT68hZT0pKCgCxsbG89dZbeXbyc3KeOXOGVatWaaYpioJarSYhIQF3d/dnvl7PcuLECUJCQjh9+jS3b99GrVYDkJSURLVq1YiNjeWdd97Js5P/LBcuXMDLy0trOJGvry9qtZq4uDjKli0LgKen53M7+QDBwcEMHz5c8zw1NRVnZ2emnjLgkbFhQaIWS6YGClN81Ew4bkCGWreHsoB+5S3MrOdCArSeN27cmGvXrtGyZUvNtN27d1O5cmXNtDp16gBotVm6dCleXl5a0wpLVlYWkZGRNGvWrEDvJ8WV5NVd+pQVCi9vzhH5/JCOvtDqRKalpdGmTRtmzJiRq52joyOGhoZERkZy6NAhdu7cyfz58xk/fjwxMTHY2trme5tP/gfPGZOe0zGeNWsW8+bNY+7cuXh6emJhYcHQoUNznWT69B+JSqXSrMPMzOy5209LS+PTTz9l8ODBueaVL18+3zly5AyxCQgIYNWqVdjZ2ZGUlERAQICm7hfV9DJedF4BgKmpKaamprmm7xvTtEC/u+IqKyuLrVu3cmJioN58oOhL3leZdcSIETRo0IBZs2bRqVMnjh49ypIlS1i0aJFmW6NHj+bDDz/E39+fRo0asX37drZs2UJ0dPQrfe2NjY11/nf7JMmru/QpK7x83oIsK1fdEVpq1arF77//jqurKxUrVtR65HQmVSoVvr6+TJo0iVOnTmFiYsL69euxsrLCycmJgwcPaq3z4MGDVKtWLd81HDx4kPfee49u3brh5eXF22+/zaVLlwqUo0aNGly7du2Zy9WqVYvz58/nylixYsUX7hnPy8WLF/nnn3+YPn0677zzDlWrVtUcXXiypv379z9zbJ2JiQnZ2dla09zd3Tl9+jT379/XTDt48CAGBgZUqVKlwHUKIQqmTp06rF+/np9++gkPDw+mTJnC3Llz6dq1q6ZN+/btWbhwITNnzsTT05MlS5awdu1aGjZsWISVCyGEdPTFUwYNGsS///5L586dOXbsGPHx8ezYsYOPP/6Y7OxsYmJi+PLLLzl+/DhJSUmsW7dOc3UdgFGjRjFjxgx+/vln4uLiGDt2LLGxsQwZMiTfNVSqVElz1ODChQt8+umn/P333wXK4efnx7vvvkuHDh2IjIwkISGBbdu2sX37dgDGjBnDoUOHCAoKIjY2lsuXL7Nx40atcbgFUb58eUxMTJg/fz5Xr15l06ZNTJkyRatNUFAQqampfPTRRxw/fpzLly+zYsUK4uLiAHB1deXMmTPExcVx69YtsrKy6Nq1KyVKlKBnz56cO3eOPXv28Nlnn9G9e3fNsB0hxKvVunVrzp49y8OHD7lw4QL9+vXL1aZ3795cvnyZBw8eEBsby3vvvVcElQohhDbp6AstOXvks7Ozad68OZ6engwdOhQbGxsMDAywsrJi3759tGzZksqVK/P5558TFhZGixYtABg8eDDDhw9nxIgReHp6sn37djZt2qR1xZ0X+fzzz6lVqxYBAQH4+/vj4OBAu3btCpxl7dq11KlTh86dO1OtWjVGjx6t2WNeo0YN9u7dy6VLl3jnnXfw9vZm4sSJODk5FXg7AHZ2dkRERPDrr79SrVo1pk+frjlxOIetrS27d+8mLS0NPz8/ateuzeLFizWH4Pr160eVKlXw8fHBzs6OgwcPYm5uzo4dO/j333+pU6cOH3zwAU2aNOGbb775T3UKIYQQQn/IVXeE0FOpqalYW1tz69YtvRqj37JlS70YC6pPefUpK0heXadPefUpKxRe3pzP7/xcdUf26AshhBBCCKGDpKMvxFP279+PpaXlMx9CCCGEEMWBXF5TiKf4+PgQGxtb1GUIIYQQQrwU6egL8RQzMzMqVqxY1GUIIYQQQrwUGbojhBBCCCGEDpKOvhB5uHHjBs2aNcPCwgIbG5uiLkcI8Ypcv36dbt26YWtri5mZGZ6enhw/flwzPyQkhKpVq2JhYUGpUqVo2rQpMTExRVixEELkn3T0hc4LCQmhZs2aBVpmzpw5JCcnExsbW+C78j6Lv78/Q4cOLZR15Th8+DCNGzfGwsICKysr3n33XR48eFCo2xBCV92+fRtfX1+MjY3Ztm0b58+fJywsjFKlSmnaVK5cmW+++YazZ89y4MABXF1dad68OTdv3izCyoUQIn9kjL4QeYiPj6d27doFutHX65KZmYmJiQmHDx8mMDCQ4OBg5s+fj5GREadPn8bAQL6/C5EfM2bMwNnZmfDwcM00Nzc3rTZdunTRev7VV1/xww8/cObMGZo0afJa6hRCiP9KegSiWNi+fTsNGzbExsYGW1tbWrduTXx8vGb+tWvX6Ny5M6VLl8bCwgIfHx9iYmKIiIhg0qRJnD59GpVKhUqlIiIi4rnbcnV1Ze3atSxfvhyVSkWvXr2Axx/wnp6eWFhY4OzszMCBA0lLS9Na9uDBg/j7+2Nubk6pUqUICAjg9u3b9OrVi7179zJv3jxNHYmJiQDs3buXunXrYmpqiqOjI2PHjuXRo0eadfr7+xMUFMTQoUMpU6YMAQEBAAwbNozBgwczduxYqlevTpUqVejUqROmpqYv/4ILoQc2bdqEj48PHTt2xN7eHm9vbxYvXvzM9pmZmSxatAhra2u8vLxeY6VCCPHfyB59USzcv3+f4cOHU6NGDdLS0pg4cSLt27cnNjaW9PR0/Pz8KFeuHJs2bcLBwYGTJ0+iVqv58MMPOXfuHNu3b2fXrl0AWFtbP3dbx44do0ePHlhZWTFv3jzMzMwAMDAw4Ouvv8bNzY2rV68ycOBARo8ezXfffQdAbGwsTZo0oXfv3sybNw8jIyP27NlDdnY28+bN49KlS3h4eDB58mQA7OzsuH79Oi1btqRXr14sX76cixcv0q9fP0qUKEFISIimpmXLljFgwAAOHjwIQEpKCjExMXTt2pUGDRoQHx9P1apVmTZtGg0bNizQa1svNIpHRhYFWqY4MjVUmFkXPEJ2kJGtKupyXjl9ypvfrInTW2k9v3r1KgsWLGD48OGMGzeOY8eOMXjwYExMTOjZs6em3ebNm/noo49IT0/H0dGRyMhIypQp88ryCCFEYZGOvigWOnTooPV86dKl2NnZcf78eQ4dOsTNmzc5duwYpUuXBtC6PKalpSVGRkY4ODjka1t2dnaYmppiZmamtcyT4+tdXV2ZOnUq/fv313T0Z86ciY+Pj+Y5QPXq1TU/m5iYYG5urrXO7777DmdnZ7755htUKhVVq1blr7/+YsyYMUycOFEzDKdSpUrMnDlTs9yRI0eAx+cfzJ49m5o1a7J8+XKaNGnCuXPn8hxylJGRQUZGhuZ5amoqAKYGCoaGSr5em+LM1EDR+lfX6VPe/GbNysrSeq5Wq6lduzaTJk0CwMPDgzNnzrBgwQKtITsNGzbk2LFj/PPPP/zwww906tSJAwcOYG9vX8hJ8icnx9N5dJXk1V36lBUKL29BlpeOvigWLl++zMSJE4mJieHWrVuo1WoAkpKSiI2NxdvbW9PJf1V27dpFaGgoFy9eJDU1lUePHvHw4UPS09MxNzcnNjaWjh07FmidFy5coH79+qhU/9sL6evrS1paGteuXaN8+fIA1K5dW2u5nPyffvopH3/8MQDe3t5ERUWxdOlSQkNDc20rNDRU06F50ufeaszNswtUd3E2xUdd1CW8VvqU90VZt27dqvXcxsYGS0tLremPHj3i8uXLudrmaNeuHTt27GDs2LF88MEHL1/0S4iMjCzS7b9ukld36VNWePm86enp+W4rHX1RLLRp0wYXFxcWL16Mk5MTarUaDw8PMjMzNUNrXqXExERat27NgAEDmDZtGqVLl+bAgQP06dOHzMxMzM3NX2kdFhbaQ2scHR0BqFatmtZ0d3d3kpKS8lxHcHAww4cP1zxPTU3F2dmZRo0aYWtrW8gVv3mysrKIjIykWbNmGBsbF3U5r5w+5f2vWRs3bsy1a9do2bKlZtru3bupXLmy1rSnmZmZ4erq+tw2r5I+/W5B8uoyfcoKhZc354h8fkhHX7zx/vnnH+Li4li8eDHvvPMOAAcOHNDMr1GjBkuWLOHff//Nc6++iYkJ2dkvt8f6xIkTqNVqwsLCNMNpfvnlF602NWrUICoqKs+95s+qw93dnbVr16Ioimav/sGDBylZsiRvvfXWM+txdXXFycmJuLg4remXLl2iRYsWeS5jamqa54m6xsbGevEGm0Py6q6CZh0xYgQNGjRg1qxZdOrUiaNHj7JkyRIWLVqEsbEx9+/fZ9q0abRt2xZHR0du3brFt99+y/Xr1/noo4+K/HXVp98tSF5dpk9Z4eXzFmRZueqOeOOVKlUKW1tbFi1axJUrV9i9e7fWnunOnTvj4OBAu3btOHjwIFevXmXt2rUcPnwYeNwpTkhIIDY2llu3bmmNU8+vihUrkpWVxfz587l69SorVqxg4cKFWm2Cg4M5duwYAwcO5MyZM1y8eJEFCxZw69YtTR0xMTEkJiZqhh8NHDiQP//8k88++4yLFy+yceNGvvjiC4YPH/7cy2SqVCpGjRrF119/zZo1a7hy5QoTJkzg4sWL9OnTp8D5hNBHderUYf369fz00094eHgwZcoU5s6dS9euXQEwNDTk4sWLdOjQgcqVK9OmTRv++ecf9u/fr3X+jRBCvKmkoy/eeAYGBqxevZoTJ07g4eHBsGHDmDVrlma+iYkJO3fuxN7enpYtW+Lp6cn06dMxNDQEHp/IGxgYSKNGjbCzs+Onn34qcA1eXl589dVXzJgxAw8PD1atWpVrHHzlypXZuXMnp0+fpm7dutSvX5+NGzdiZPT4wNnIkSMxNDSkWrVq2NnZkZSURLly5di6dStHjx7Fy8uL/v3706dPHz7//PMX1jR06FCCg4MZNmwYXl5eREVFERkZSYUKFQqcTwh91bp1a86ePcvDhw+5cOEC/fr108wrUaIE69at4/r162RkZPDXX3+xceNG6tSpU4QVCyFE/snQHVEsNG3alPPnz2tNU5T/XWHDxcWFNWvW5LmsqanpM+c9y4YNG3JNGzZsGMOGDdOa1r17d63nfn5+mktgPq1y5cqaowxPL3P06NFn1hIdHf3MeWPHjmXs2LHPnC+EEEII/SV79IUQQgghhNBB0tEXemfVqlVYWlrm+ZBxt0IIIYTQFTJ0R+idtm3bUq9evTzn6dNZ/0IIIYTQbdLRF3qnZMmSlCxZsqjLEEIIIYR4pWTojhBCCCGEEDpIOvpCCCF03vXr1+nWrRu2traYmZnh6enJ8ePHNfPXrVtH8+bNsbW1RaVSERsbW3TFCiFEIZGOvhBCCJ12+/ZtfH19MTY2Ztu2bZw/f56wsDBKlSqlaXP//n0aNmzIjBkzirBSIYQoXDJGX4g3RHR0NI0aNeL27dvY2NgUdTlC6IwZM2bg7OxMeHi4Zpqbm5tWm5x7YiQmJr7O0oQQ4pWSPfpCFDOZmZlFXYIQxcqmTZvw8fGhY8eO2Nvb4+3tzeLFi4u6LCGEeOVkj754423fvp2pU6dy7tw5DA0NqV+/PvPmzaNChQpkZmYyfPhw1q5dy+3btylbtiz9+/cnODiY3r17k5KSwubNmzXrysrKoly5coSGhtKnTx/8/f3x9PTE0NCQZcuWYWJiwtSpU+nSpQtBQUGsWbOGsmXLMn/+fFq0aAH8b8/79u3bGTt2LBcvXqR+/fqsXr2aEydOMHz4cK5fv07r1q1ZsmQJ5ubmAKjVambMmMGiRYu4ceMGlStXZsKECXzwwQckJibSqFEjAM1wgp49exIREYG/vz8eHh4YGRmxcuVKPD09cXNze2G2/KoXGsUjI4uX/j296UwNFWbWBY+QHWRkq4q6nFdOn/I+nTVxeiut+VevXmXBggUMHz6ccePGcezYMQYPHoyJiQk9e/YsoqqFEOLVk46+eOPdv3+f4cOHU6NGDdLS0pg4cSLt27cnNjaWr7/+mk2bNvHLL79Qvnx5/vzzT/78808A+vbty7vvvktycjKOjo4AbN68mfT0dD788EPN+pctW8bo0aM5evQoP//8MwMGDGD9+vW0b9+ecePGMWfOHLp3705SUpKm0w4QEhLCN998g7m5OZ06daJTp06Ympry448/kpaWRvv27Zk/fz5jxowBIDQ0lJUrV7Jw4UIqVarEvn376NatG3Z2djRs2JC1a9fSoUMH4uLisLKywszMTKvGAQMGcPDgQQD++eeffGV7UkZGBhkZGZrnqampAJgaKBgaKi/9e3rTmRooWv/qOn3K+3TWrKwsrflqtZratWszadIkADw8PDhz5gwLFiygS5cuWm1zls3Kysq1njfFkzXqA8mru/QpKxRe3oIsr1IURfc/BYROuXXrFnZ2dpw9e5ZFixbx+++/s2vXLlSq3Hstq1evTs+ePRk9ejTw+GZZtra2mrG6/v7+ZGdns3//fgCys7Oxtrbm/fffZ/ny5QDcuHEDR0dHDh8+zP/93/9p9ujv2rWLJk2aADB9+nSCg4OJj4/n7bffBqB///4kJiayfft2MjIyKF26NLt27aJ+/fqa+vr27Ut6ejo//vjjM8fo+/v7k5qaysmTJwuU7WkhISGajs6TfvzxR60vMELomn79+uHl5UVQUJBm2rZt2/j1119ZunSpVtu///6bTz/9lK+++krztyyEEG+S9PR0unTpwt27d7GysnpuW9mjL954ly9fZuLEicTExHDr1i3UajUASUlJ9OrVi2bNmlGlShUCAwNp3bo1zZs31yzbt29fFi1axOjRo/n777/Ztm0bu3fv1lp/jRo1ND8bGhpia2uLp6enZlrZsmUBSElJeeZyZcuWxdzcXKtjULZsWY4ePQrAlStXSE9Pp1mzZlrryMzMxNvb+4WvQe3atXNNy0+2JwUHBzN8+HDN89TUVJydnZl6yoBHxoYvrKG4MzVQmOKjZsJxAzLUuj2UBfQr79NZz4UEaM1v3Lgx165do2XLlpppu3fvpnLlylrT4H8n4zZs2JCaNWu+6tL/k6ysLCIjI2nWrJle3M1b8uoufcoKhZc354h8fkhHX7zx2rRpg4uLC4sXL8bJyQm1Wo2HhweZmZnUqlWLhIQEtm3bxq5du+jUqRNNmzZlzZo1APTo0YOxY8dy+PBhDh06hJubG++8847W+p/+Y1OpVFrTco4U5HzByGu5p5fJmZazTFpaGgBbtmyhXLlyWu1MTU1f+BpYWOQeQ5+fbE9vJ69t7RvTFFtb2xfWUNxlZWWxdetWTkwM1JsPFH3J+6KsI0aMoEGDBsyaNYtOnTpx9OhRlixZwqJFizTt//33X5KSkvjrr7+Ax+P6jY2NcXBwwMHB4bXmyS9jY2Od/90+SfLqLn3KCi+ftyDLSkdfvNH++ecf4uLiWLx4saYTe+DAAa02VlZWfPjhh3z44Yd88MEHBAYG8u+//1K6dGlsbW1p164d4eHhHD58mI8//rgoYlCtWjVMTU1JSkrCz88vzzYmJibA4+FD+fGmZBPiTVenTh3Wr19PcHAwkydPxs3Njblz59K1a1dNm02bNmn9DX300UcAfPHFF4SEhLzukoUQolBIR1+80UqVKoWtrS2LFi3C0dGRpKQkxo4dq5n/1Vdf4ejoiLe3NwYGBvz66684ODhojXHv27cvrVu3Jjs7u8iusFGyZElGjhzJsGHDUKvVNGzYkLt373Lw4EGsrKzo2bMnLi4uqFQqNm/eTMuWLTEzM8PS0vK5630TsglRHLRu3ZrWrVs/c36vXr3o1avX6ytICCFeA+noizeagYEBq1evZvDgwXh4eFClShW+/vpr/P39gccd6JkzZ3L58mUMDQ2pU6cOW7duxcDgf7eIaNq0KY6OjlSvXh0nJ6ciSgJTpkzBzs6O0NBQrl69io2NDbVq1WLcuHEAlCtXjkmTJjF27Fg+/vhjevToQURExHPX+aZkE0IIIcSbRzr64o3XtGlTzp8/rzXtyYtF9evX77nL379/n9u3b+d5bfno6Ohc0/K6M+aT2/P39+fpi1XltTcwJCRE65C/SqViyJAhDBky5Jm1TpgwgQkTJrywxhzPyyaEEEII/SYdfaGz1Go1t27dIiwsDBsbG9q2bVvUJRUaXc4mhBBCiMIhHX2hs5KSknBzc+Ott94iIiICIyPd+e+uy9mEEEIIUTikdyB0lqura64hNrpCl7MJIYQQonAYvLiJEEIIIYQQoriRjr4QQgghhBA6SDr6QgghhBBC6CDp6AshhBBCCKGDpKMvhBBCCCGEDpKOvhBCCCGEEDpIOvpCCCGEEELoILmOvhB6Kuc6/Pfu3cPY2LiIq3n1srKySE9PJzU1VfLqGH3KCpJX1+lTXn3KCoWXNzU1FSBf99ORjr4Qeuqff/4BwM3NrYgrEUIIIURB3bt3D2tr6+e2kY6+EHqqdOnSACQlJb3wjUIXpKam4uzszJ9//omVlVVRl/PK6VNefcoKklfX6VNefcoKhZdXURTu3buHk5PTC9tKR18IPWVg8PgUHWtra714g81hZWUleXWUPmUFyavr9CmvPmWFwsmb3x10cjKuEEIIIYQQOkg6+kIIIYQQQugg6egLoadMTU354osvMDU1LepSXgvJq7v0KStIXl2nT3n1KSsUTV6Vkp9r8wghhBBCCCGKFdmjL4QQQgghhA6Sjr4QQgghhBA6SDr6QgghhBBC6CDp6AshhBBCCKGDpKMvhJ769ttvcXV1pUSJEtSrV4+jR48WdUkvLTQ0lDp16lCyZEns7e1p164dcXFxWm0ePnzIoEGDsLW1xdLSkg4dOvD3338XUcWFa/r06ahUKoYOHaqZpmt5r1+/Trdu3bC1tcXMzAxPT0+OHz+uma8oChMnTsTR0REzMzOaNm3K5cuXi7Di/yY7O5sJEybg5uaGmZkZFSpUYMqUKTx5/YzinHXfvn20adMGJycnVCoVGzZs0Jqfn2z//vsvXbt2xcrKChsbG/r06UNaWtprTJF/z8ublZXFmDFj8PT0xMLCAicnJ3r06MFff/2ltQ5dyfu0/v37o1KpmDt3rtb04pI3P1kvXLhA27Ztsba2xsLCgjp16pCUlKSZ/yrfp6WjL4Qe+vnnnxk+fDhffPEFJ0+exMvLi4CAAFJSUoq6tJeyd+9eBg0axJEjR4iMjCQrK4vmzZtz//59TZthw4bx22+/8euvv7J3717++usv3n///SKsunAcO3aM77//nho1amhN16W8t2/fxtfXF2NjY7Zt28b58+cJCwujVKlSmjYzZ87k66+/ZuHChcTExGBhYUFAQAAPHz4swsoLbsaMGSxYsIBvvvmGCxcuMGPGDGbOnMn8+fM1bYpz1vv37+Pl5cW3336b5/z8ZOvatSu///47kZGRbN68mX379vHJJ5+8rggF8ry86enpnDx5kgkTJnDy5EnWrVtHXFwcbdu21WqnK3mftH79eo4cOYKTk1OuecUl74uyxsfH07BhQ6pWrUp0dDRnzpxhwoQJlChRQtPmlb5PK0IIvVO3bl1l0KBBmufZ2dmKk5OTEhoaWoRVFb6UlBQFUPbu3asoiqLcuXNHMTY2Vn799VdNmwsXLiiAcvjw4aIq86Xdu3dPqVSpkhIZGan4+fkpQ4YMURRF9/KOGTNGadiw4TPnq9VqxcHBQZk1a5Zm2p07dxRTU1Plp59+eh0lFppWrVopvXv31pr2/vvvK127dlUURbeyAsr69es1z/OT7fz58wqgHDt2TNNm27ZtikqlUq5fv/7aav8vns6bl6NHjyqA8scffyiKopt5r127ppQrV045d+6c4uLiosyZM0czr7jmzSvrhx9+qHTr1u2Zy7zq92nZoy+EnsnMzOTEiRM0bdpUM83AwICmTZty+PDhIqys8N29exeA0qVLA3DixAmysrK0sletWpXy5csX6+yDBg2iVatWWrlA9/Ju2rQJHx8fOnbsiL29Pd7e3ixevFgzPyEhgRs3bmjltba2pl69esUub4MGDYiKiuLSpUsAnD59mgMHDtCiRQtAt7I+LT/ZDh8+jI2NDT4+Ppo2TZs2xcDAgJiYmNdec2G7e/cuKpUKGxsbQPfyqtVqunfvzqhRo6hevXqu+bqSV61Ws2XLFipXrkxAQAD29vbUq1dPa3jPq36flo6+EHrm1q1bZGdnU7ZsWa3pZcuW5caNG0VUVeFTq9UMHToUX19fPDw8ALhx4wYmJiaaD88cxTn76tWrOXnyJKGhobnm6Vreq1evsmDBAipVqsSOHTsYMGAAgwcPZtmyZQCaTLrwf3vs2LF89NFHVK1aFWNjY7y9vRk6dChdu3YFdCvr0/KT7caNG9jb22vNNzIyonTp0sU+/8OHDxkzZgydO3fGysoK0L28M2bMwMjIiMGDB+c5X1fypqSkkJaWxvTp0wkMDGTnzp20b9+e999/n7179wKv/n3a6KXXIIQQb6BBgwZx7tw5Dhw4UNSlvDJ//vknQ4YMITIyUmu8p65Sq9X4+Pjw5ZdfAuDt7c25c+dYuHAhPXv2LOLqCtcvv/zCqlWr+PHHH6levTqxsbEMHToUJycnncsq/icrK4tOnTqhKAoLFiwo6nJeiRMnTjBv3jxOnjyJSqUq6nJeKbVaDcB7773HsGHDAKhZsyaHDh1i4cKF+Pn5vfIaZI++EHqmTJkyGBoa5jqj/++//8bBwaGIqipcQUFBbN68mT179vDWW29ppjs4OJCZmcmdO3e02hfX7CdOnCAlJYVatWphZGSEkZERe/fu5euvv8bIyIiyZcvqVF5HR0eqVaumNc3d3V1z9YqcTLrwf3vUqFGavfqenp50796dYcOGaY7c6FLWp+Unm4ODQ66LBzx69Ih///232ObP6eT/8ccfREZGavbmg27l3b9/PykpKZQvX17zvvXHH38wYsQIXF1dAd3JW6ZMGYyMjF74vvUq36eloy+EnjExMaF27dpERUVppqnVaqKioqhfv34RVvbyFEUhKCiI9evXs3v3btzc3LTm165dG2NjY63scXFxJCUlFcvsTZo04ezZs8TGxmoePj4+dO3aVfOzLuX19fXNdbnUS5cu4eLiAoCbmxsODg5aeVNTU4mJiSl2edPT0zEw0P6INjQ01Owh1KWsT8tPtvr163Pnzh1OnDihabN7927UajX16tV77TW/rJxO/uXLl9m1axe2trZa83Upb/fu3Tlz5ozW+5aTkxOjRo1ix44dgO7kNTExoU6dOs9933rln0svfTqvEKLYWb16tWJqaqpEREQo58+fVz755BPFxsZGuXHjRlGX9lIGDBigWFtbK9HR0UpycrLmkZ6ermnTv39/pXz58sru3buV48ePK/Xr11fq169fhFUXrievuqMoupX36NGjipGRkTJt2jTl8uXLyqpVqxRzc3Nl5cqVmjbTp09XbGxslI0bNypnzpxR3nvvPcXNzU158OBBEVZecD179lTKlSunbN68WUlISFDWrVunlClTRhk9erSmTXHOeu/ePeXUqVPKqVOnFED56quvlFOnTmmuMpOfbIGBgYq3t7cSExOjHDhwQKlUqZLSuXPnoor0XM/Lm5mZqbRt21Z56623lNjYWK33royMDM06dCVvXp6+6o6iFJ+8L8q6bt06xdjYWFm0aJFy+fJlZf78+YqhoaGyf/9+zTpe5fu0dPSF0FPz589Xypcvr5iYmCh169ZVjhw5UtQlvTQgz0d4eLimzYMHD5SBAwcqpUqVUszNzZX27dsrycnJRVd0IXu6o69reX/77TfFw8NDMTU1VapWraosWrRIa75arVYmTJiglC1bVjE1NVWaNGmixMXFFVG1/11qaqoyZMgQpXz58kqJEiWUt99+Wxk/frxWx684Z92zZ0+ef6s9e/ZUFCV/2f755x+lc+fOiqWlpWJlZaV8/PHHyr1794ogzYs9L29CQsIz37v27NmjWYeu5M1LXh394pI3P1l/+OEHpWLFikqJEiUULy8vZcOGDVrreJXv0ypFeeI2e0IIIYQQQgidIGP0hRBCCCGE0EHS0RdCCCGEEEIHSUdfCCGEEEIIHSQdfSGEEEIIIXSQdPSFEEIIIYTQQdLRF0IIIYQQQgdJR18IIYQQQggdJB19IYQQohjx9/dn6NChRV2GEKIYkI6+EEIIndGrVy9UKlWux5UrVwpl/REREdjY2BTKuv6rdevWMWXKlCKt4Xmio6NRqVTcuXOnqEsRQu8ZFXUBQgghRGEKDAwkPDxca5qdnV0RVfNsWVlZGBsbF3i50qVLv4JqCkdWVlZRlyCEeILs0RdCCKFTTE1NcXBw0HoYGhoCsHHjRmrVqkWJEiV4++23mTRpEo8ePdIs+9VXX+Hp6YmFhQXOzs4MHDiQtLQ04PGe6o8//pi7d+9qjhSEhIQAoFKp2LBhg1YdNjY2REREAJCYmIhKpeLnn3/Gz8+PEiVKsGrVKgCWLFmCu7s7JUqUoGrVqnz33XfPzff00B1XV1emTp1Kjx49sLS0xMXFhU2bNnHz5k3ee+89LC0tqVGjBsePH9csk3NkYsOGDVSqVIkSJUoQEBDAn3/+qbWtBQsWUKFCBUxMTKhSpQorVqzQmq9SqViwYAFt27bFwsKCfv360ahRIwBKlSqFSqWiV69eAGzfvp2GDRtiY2ODra0trVu3Jj4+XrOunNdo3bp1NGrUCHNzc7y8vDh8+LDWNg8ePIi/vz/m5uaUKlWKgIAAbt++DYBarSY0NBQ3NzfMzMzw8vJizZo1z309hdBpihBCCKEjevbsqbz33nt5ztu3b59iZWWlREREKPHx8crOnTsVV1dXJSQkRNNmzpw5yu7du5WEhAQlKipKqVKlijJgwABFURQlIyNDmTt3rmJlZaUkJycrycnJyr179xRFURRAWb9+vdb2rK2tlfDwcEVRFCUhIUEBFFdXV2Xt2rXK1atXlb/++ktZuXKl4ujoqJm2du1apXTp0kpERMQzM/r5+SlDhgzRPHdxcVFKly6tLFy4ULl06ZIyYMAAxcrKSgkMDFR++eUXJS4uTmnXrp3i7u6uqNVqRVEUJTw8XDE2NlZ8fHyUQ4cOKcePH1fq1q2rNGjQQLPedevWKcbGxsq3336rxMXFKWFhYYqhoaGye/duTRtAsbe3V5YuXarEx8criYmJytq1axVAiYuLU5KTk5U7d+4oiqIoa9asUdauXatcvnxZOXXqlNKmTRvF09NTyc7O1nqNqlatqmzevFmJi4tTPvjgA8XFxUXJyspSFEVRTp06pZiamioDBgxQYmNjlXPnzinz589Xbt68qSiKokydOlWpWrWqsn37diU+Pl4JDw9XTE1Nlejo6Ge+nkLoMunoCyGE0Bk9e/ZUDA0NFQsLC83jgw8+UBRFUZo0aaJ8+eWXWu1XrFihODo6PnN9v/76q2Jra6t5Hh4erlhbW+dql9+O/ty5c7XaVKhQQfnxxx+1pk2ZMkWpX7/+M2vKq6PfrVs3zfPk5GQFUCZMmKCZdvjwYQVQkpOTNTkA5ciRI5o2Fy5cUAAlJiZGURRFadCggdKvXz+tbXfs2FFp2bKlVu6hQ4dqtdmzZ48CKLdv335mBkVRlJs3byqAcvbsWUVR/vcaLVmyRNPm999/VwDlwoULiqIoSufOnRVfX9881/fw4UPF3NxcOXTokNb0Pn36KJ07d35uLULoKhmjL4QQQqc0atSIBQsWaJ5bWFgAcPr0aQ4ePMi0adM087Kzs3n48CHp6emYm5uza9cuQkNDuXjxIqmpqTx69Ehr/svy8fHR/Hz//n3i4+Pp06cP/fr100x/9OgR1tbWBVpvjRo1ND+XLVsWAE9Pz1zTUlJScHBwAMDIyIg6depo2lStWhUbGxsuXLhA3bp1uXDhAp988onWdnx9fZk3b94zMz3P5cuXmThxIjExMdy6dQu1Wg1AUlISHh4eeWZxdHTU1F21alViY2Pp2LFjnuu/cuUK6enpNGvWTGt6ZmYm3t7e+apRCF0jHX0hhBA6xcLCgooVK+aanpaWxqRJk3j//fdzzStRogSJiYm0bt2aAQMGMG3aNEqXLs2BAwfo06cPmZmZz+3oq1QqFEXRmpbXiak5Xzpy6gFYvHgx9erV02qXc05Bfj15Uq9KpXrmtJzOdWF6MtPztGnTBhcXFxYvXoyTkxNqtRoPDw8yMzO12j2vbjMzs2euP+f13LJlC+XKldOaZ2pqmq8ahdA10tEXQgihF2rVqkVcXFyeXwIATpw4gVqtJiwsDAODx9eq+OWXX7TamJiYkJ2dnWtZOzs7kpOTNc8vX75Menr6c+spW7YsTk5OXL16la5duxY0zkt79OgRx48fp27dugDExcVx584d3N3dAXB3d+fgwYP07NlTs8zBgwepVq3ac9drYmICoPU6/fPPP8TFxbF48WLeeecdAA4cOFDgmmvUqEFUVBSTJk3KNa9atWqYmpqSlJSEn59fgdcthC6Sjr4QQgi9MHHiRFq3bk358uX54IMPMDAw4PTp05w7d46pU6dSsWJFsrKymD9/Pm3atOHgwYMsXLhQax2urq6kpaURFRWFl5cX5ubmmJub07hxY7755hvq169PdnY2Y8aMydelMydNmsTgwYOxtrYmMDCQjIwMjh8/zu3btxk+fPireimAx3vOP/vsM77++muMjIwICgri//7v/zQd/1GjRtGpUye8vb1p2rQpv/32G+vWrWPXrl3PXa+LiwsqlYrNmzfTsmVLzMzMKFWqFLa2tixatAhHR0eSkpIYO3ZsgWsODg7G09OTgQMH0r9/f0xMTNizZw8dO3akTJkyjBw5kmHDhqFWq2nYsCF3797l4MGDWFlZaX1hEUJfyOU1hRBC6IWAgAA2b97Mzp07qVOnDv/3f//HnDlzcHFxAcDLy4uvvvqKGTNm4OHhwapVqwgNDdVaR4MGDejfvz8ffvghdnZ2zJw5E4CwsDCcnZ1555136NKlCyNHjszXmP6+ffuyZMkSwsPD8fT0xM/Pj4iICNzc3Ar/BXiKubk5Y8aMoUuXLvj6+mJpacnPP/+smd+uXTvmzZvH7NmzqV69Ot9//z3h4eH4+/s/d73lypVj0qRJjB07lrJlyxIUFISBgQGrV6/mxIkTeHh4MGzYMGbNmlXgmitXrszOnTs5ffo0devWpX79+mzcuBEjo8f7LadMmcKECRMIDQ3F3d2dwMBAtmzZ8lpeTyHeRCrl6UGFQgghhNBpERERDB06VO5eK4SOkz36QgghhBBC6CDp6AshhBBCCKGDZOiOEEIIIYQQOkj26AshhBBCCKGDpKMvhBBCCCGEDpKOvhBCCCGEEDpIOvpCCCGEEELoIOnoCyGEEEIIoYOkoy+EEEIIIYQOko6+EEIIIYQQOkg6+kIIIYQQQugg6egLIYQQQgihg/4fXTIb0cZxR9cAAAAASUVORK5CYII="
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"train data size: 2543987\n"
]
}
],
"execution_count": 80
},
{
"cell_type": "code",
"id": "63235069-dc59-48fb-961a-e80373e41a61",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:21:10.902087Z",
"start_time": "2025-03-26T15:21:10.893389Z"
}
},
"source": [
"print('train data size: ', len(train_data))\n",
"\n",
"catboost_params = {\n",
" 'loss_function': 'QuerySoftMax', # 排序损失函数\n",
" 'custom_metric': ['NDCG', 'AverageGain:top=10'],\n",
" 'iterations': 5000, # 训练轮数\n",
" 'learning_rate': 0.05, # 学习率\n",
" 'depth': 10, # 树的深度,防止过拟合\n",
" # 'l2_leaf_reg': 10.0, # L2 正则化,提高泛化能力\n",
" # 'bagging_temperature': 1, # 降低过拟合\n",
" # 'subsample': 0.8, # 每轮随机 80% 样本\n",
" # 'colsample_bylevel': 0.8, # 每层 80% 特征\n",
" 'random_seed': 42, # 固定随机种子\n",
" 'verbose': 100, # 每 100 轮打印一次信息\n",
" 'early_stopping_rounds': 100, # 早停,防止过拟合\n",
" 'has_time': True, # 让模型知道数据有时间顺序\n",
" # 'task_type':\"GPU\",\n",
"}\n",
"\n",
"# model = train_catboost(train_data, test_data, feature_columns_new, catboost_params, plot=True)"
],
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"train data size: 2543987\n"
]
}
],
"execution_count": 81
},
{
"cell_type": "code",
"id": "5d1522a7538db91b",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:21:10.967045Z",
"start_time": "2025-03-26T15:21:10.950621Z"
}
},
"source": [
"from tqdm import tqdm\n",
"\n",
"\n",
"def incremental_training(test_data: pd.DataFrame,\n",
" model,\n",
" scaler,\n",
" days: int,\n",
" back_days: int,\n",
" feature_columns: list,\n",
" params: dict,\n",
" model_type: str = 'lightgbm',\n",
" times=10\n",
" ):\n",
" if model_type not in ['lightgbm', 'catboost']:\n",
" raise ValueError(\"model_type must be either 'lightgbm' or 'catboost'\")\n",
"\n",
" test_data = test_data.sort_values(by='trade_date')\n",
" scores = []\n",
" unique_trade_dates = sorted(test_data['trade_date'].unique())\n",
"\n",
" new_model = None\n",
" current_times = 0\n",
" for i in tqdm(range(0, len(unique_trade_dates))):\n",
" # Get the current window of trade dates\n",
" current_dates = [unique_trade_dates[i]]\n",
" window_data = test_data[test_data['trade_date'].isin(current_dates)]\n",
" X = window_data[feature_columns]\n",
"\n",
" if new_model is not None:\n",
" window_scores = new_model.predict(X, prediction_type='RawFormulaVal')\n",
" else:\n",
" window_scores = model.predict(X, prediction_type='RawFormulaVal')\n",
" scores.extend(window_scores)\n",
" current_times += 1\n",
"\n",
" if current_times % times == 0:\n",
" current_dates = unique_trade_dates[max(0, i - days - back_days):i + 1 - back_days]\n",
" window_data = test_data[test_data['trade_date'].isin(current_dates)]\n",
" X_train = window_data[feature_columns]\n",
" y_train = window_data['label'] # Assuming 'label' is what you're predicting\n",
"\n",
" # Incrementally train the model\n",
" if len(y_train.unique()) > 1:\n",
" if model_type == 'lightgbm':\n",
" categorical_feature = [i for i, col in enumerate(feature_columns) if col.startswith('cat')]\n",
" train_groups = window_data.groupby('trade_date').size().tolist()\n",
" train_data = lgb.Dataset(X_train, label=y_train, group=train_groups,\n",
" categorical_feature=categorical_feature)\n",
" new_model = lgb.train(params,\n",
" train_set=train_data,\n",
" num_boost_round=24,\n",
" init_model=model,\n",
" keep_training_booster=True)\n",
" # print(f\"Number of trees: {model.num_trees()}\")\n",
" elif model_type == 'catboost':\n",
" from catboost import Pool\n",
" train_data = Pool(data=X_train, label=y_train,\n",
" cat_features=[col for col in feature_columns if col.startswith('cat')])\n",
" # model.set_params(**params)\n",
" model.fit(train_data, init_model=model)\n",
" # else:\n",
" # print(current_dates)\n",
"\n",
" # Add the scores as a new 'score' column to the test_data\n",
" test_data['score'] = scores\n",
" return test_data"
],
"outputs": [],
"execution_count": 82
},
{
"cell_type": "code",
"id": "bbcc55a58ee063d6",
"metadata": {
"ExecuteTime": {
"end_time": "2025-03-26T15:42:15.991756Z",
"start_time": "2025-03-26T15:36:18.479450Z"
}
},
"source": [
"numeric_columns = test_data.select_dtypes(include=['float64', 'int64']).columns\n",
"numeric_columns = [col for col in numeric_columns if col in feature_columns]\n",
"td = cross_sectional_standardization(test_data, numeric_columns)\n",
"predictions_test = incremental_training(td, model, scaler, 180, days, feature_columns, light_params,\n",
" model_type='lightgbm', times=20)\n",
"predictions_test = predictions_test.loc[predictions_test.groupby('trade_date')['score'].idxmax()]\n",
"predictions_test[['trade_date', 'score', 'ts_code']].to_csv('predictions_test.tsv', index=False)"
],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"100%|██████████| 533/533 [05:13<00:00, 1.70it/s]\n"
]
}
],
"execution_count": 86
},
{
"cell_type": "code",
"id": "020c3e3b-388b-42aa-a089-895057230122",
"metadata": {
"editable": true,
"slideshow": {
"slide_type": ""
},
"tags": [],
"ExecuteTime": {
"end_time": "2025-03-26T15:34:41.558604Z",
"start_time": "2025-03-26T15:34:40.969894Z"
}
},
"source": "print(df[['ts_code', 'trade_date', 'act_factor1']].head())\n",
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
" ts_code trade_date act_factor1\n",
"0 000001.SZ 2018-01-02 NaN\n",
"2536 000001.SZ 2018-01-03 NaN\n",
"5079 000001.SZ 2018-01-04 NaN\n",
"7623 000001.SZ 2018-01-05 NaN\n",
"10167 000001.SZ 2018-01-08 NaN\n"
]
}
],
"execution_count": 84
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"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.11.11"
}
},
"nbformat": 4,
"nbformat_minor": 5
}