diff --git a/Scripts/__pycache__/generate_signals.cpython-312.pyc b/Scripts/__pycache__/generate_signals.cpython-312.pyc
index e9130ca09..63471cf8b 100644
Binary files a/Scripts/__pycache__/generate_signals.cpython-312.pyc and b/Scripts/__pycache__/generate_signals.cpython-312.pyc differ
diff --git a/Scripts/__pycache__/preprocess_daily.cpython-312.pyc b/Scripts/__pycache__/preprocess_daily.cpython-312.pyc
index e75b6935c..ee762f550 100644
Binary files a/Scripts/__pycache__/preprocess_daily.cpython-312.pyc and b/Scripts/__pycache__/preprocess_daily.cpython-312.pyc differ
diff --git a/Scripts/generate_signals.py b/Scripts/generate_signals.py
index ac266756a..53f17ee64 100644
--- a/Scripts/generate_signals.py
+++ b/Scripts/generate_signals.py
@@ -805,6 +805,7 @@ class SignalGenerator():
self.time52 = datetime.now()
self.make_tl_file()
self.time53 = datetime.now()
+ self.find_impropers()
# 5-1. 신호 파일의 시작 및 종료시각 설정
@@ -1112,11 +1113,11 @@ class SignalGenerator():
if __name__ == '__main__':
parser = argparse.ArgumentParser()
- parser.add_argument('-c','--config_name', dest='config_name', type=str, default='test_0721')
+ parser.add_argument('-c','--config_name', dest='config_name', type=str, default='test_0731')
parser.add_argument('-M','--month', dest='month', type=int, default=7)
- parser.add_argument('-D','--day', dest='day', type=int, default=22)
+ parser.add_argument('-D','--day', dest='day', type=int, default=31)
parser.add_argument('-H','--hour', dest='hour', type=int, default=9)
- parser.add_argument('-m','--minute', dest='minute', type=int, default=20)
+ parser.add_argument('-m','--minute', dest='minute', type=int, default=5)
args = parser.parse_args()
config_name = args.config_name
diff --git a/Scripts/preprocess_daily.py b/Scripts/preprocess_daily.py
index 22041c919..8b74f5e6e 100644
--- a/Scripts/preprocess_daily.py
+++ b/Scripts/preprocess_daily.py
@@ -1118,8 +1118,6 @@ class DailyPreprocessor():
self.match6 = self.match6.dropna(subset='state')
self.match6 = self.match6.reset_index(drop=True)
self.match6 = self.match6[['inter_no', 'node_id', 'phase_no', 'ring_type', 'move_no', 'inc_edge_id', 'out_edge_id', 'state', 'turn_type']]
- self.match6.to_csv(os.path.join(self.path_intermediates, 'match6.csv'))
- self.matching.to_csv(os.path.join(self.path_intermediates, 'matching.csv'), index=0)
print('2-4. 직진 및 좌회전(G)을 배정했습니다.')
@@ -1169,6 +1167,9 @@ class DailyPreprocessor():
# 2-6 기반파일 저장
def save_intermediates(self):
+ # match6, matching 저장
+ self.match6.to_csv(os.path.join(self.path_intermediates, 'match6.csv'))
+ self.matching.to_csv(os.path.join(self.path_intermediates, 'matching.csv'), index=0)
# 신호계획 저장
self.plan.to_csv(os.path.join(self.path_tables, 'plan.csv'), index=0)
diff --git a/analysis/0801_check_tll/1_all_red.ipynb b/analysis/0801_check_tll/1_all_red.ipynb
index 4e7c2d448..42b34802d 100644
--- a/analysis/0801_check_tll/1_all_red.ipynb
+++ b/analysis/0801_check_tll/1_all_red.ipynb
@@ -73,6 +73,59 @@
"self.get_intermediates()"
]
},
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "[436, 437, 438, 442, 443, 455, 456, 457, 458]"
+ ]
+ },
+ "execution_count": 5,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "self.inter_nos"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "40 gGGGgrrrrrgggggrrrrrrrgrrrr\n",
+ "41 grrrgGGrrrgggggrrrrrrrgrrrr\n",
+ "42 gGGGgrrrrrgggggrrrrrrrgrrrr\n",
+ "43 grrrgrrrrrgggggGGGGGrrgrrrr\n",
+ "44 grrrgrrrrrgggggrrrrrGGgrrrr\n",
+ "45 grrrgrrrrrgggggGGGGGrrgrrrr\n",
+ "46 grrrgrrrrrgggggrrrrrrrgrrrG\n",
+ "47 grrrgrrrrrgggggrrrrrrrgGGGr\n",
+ "48 grrrgrrGGrgggggrrrrrrrgrrrr\n",
+ "49 grrrgrrrrGgggggrrrrrrrgrrrr\n",
+ "50 grrrgrrGGrgggggrrrrrrrgrrrr\n",
+ "51 grrrgrrrrGgggggrrrrrrrgrrrr\n",
+ "Name: state, dtype: object"
+ ]
+ },
+ "execution_count": 6,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "m6 = self.match6[self.match6.node_id=='106332']\n",
+ "m6.state"
+ ]
+ },
{
"cell_type": "code",
"execution_count": 6,
diff --git a/analysis/0801_check_tll/3_check.ipynb b/analysis/0801_check_tll/3_check.ipynb
new file mode 100644
index 000000000..3e7e7872d
--- /dev/null
+++ b/analysis/0801_check_tll/3_check.ipynb
@@ -0,0 +1,250 @@
+{
+ "cells": [
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import os, sys, json, argparse, pickle\n",
+ "import sumolib, traci\n",
+ "from tqdm import tqdm\n",
+ "from datetime import datetime, timedelta\n",
+ "import pandas as pd\n",
+ "import numpy as np\n",
+ "import os, sys, copy, argparse, json, pickle\n",
+ "import sumolib, traci\n",
+ "from tqdm import tqdm\n",
+ "from datetime import datetime\n",
+ "\n",
+ "\n",
+ "path_root = os.path.dirname(os.path.dirname(os.path.abspath('.')))\n",
+ "path_scr = os.path.join(path_root, 'scripts')\n",
+ "sys.path.append(path_scr)\n",
+ "from preprocess_daily import DailyPreprocessor"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1. 데이터를 로드합니다.\n",
+ "1-1. 네트워크가 로드되었습니다.\n",
+ "1-2. 테이블들이 로드되었습니다.\n",
+ "1-5. 테이블을 표준화했습니다.\n",
+ "1-6. 주요 객체 (리스트, 딕셔너리)들을 저장했습니다.\n"
+ ]
+ }
+ ],
+ "source": [
+ "self = DailyPreprocessor(config_name='test_0731')\n",
+ "self.load_data()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "2. 중간산출물을 생성합니다.\n",
+ "2-1. 매칭 테이블들을 생성했습니다.\n",
+ "2-2. 초기화 신호가 지정되었습니다. (우회전 : g)\n",
+ "2-3. 유턴 인덱스 / 비보호좌회전 인덱스를 지정했습니다.\n",
+ "2-4. 직진 및 좌회전(G)을 배정했습니다.\n",
+ "2-5. 모든 현시에서 적색신호인 경우에 대한 처리 완료\n",
+ "2-6. node2num_cycles.json를 저장했습니다.\n"
+ ]
+ }
+ ],
+ "source": [
+ "self.get_intermediates()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 26,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "40 gGGGgrrrrrgggggrrrrrrrgrrrr\n",
+ "41 grrrgGGrrrgggggrrrrrrrgrrrr\n",
+ "42 gGGGgrrrrrgggggrrrrrrrgrrrr\n",
+ "43 grrrgrrrrrgggggGGGGGrrgrrrr\n",
+ "44 grrrgrrrrrgggggrrrrrGGgrrrr\n",
+ "45 grrrgrrrrrgggggGGGGGrrgrrrr\n",
+ "46 grrrgrrrrrgggggrrrrrrrgrrrG\n",
+ "47 grrrgrrrrrgggggrrrrrrrgGGGr\n",
+ "48 grrrgrrGGrgggggrrrrrrrgrrrr\n",
+ "49 grrrgrrrrGgggggrrrrrrrgrrrr\n",
+ "50 grrrgrrGGrgggggrrrrrrrgrrrr\n",
+ "51 grrrgrrrrGgggggrrrrrrrgrrrr\n",
+ "Name: state, dtype: object"
+ ]
+ },
+ "execution_count": 26,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "# match6 = pd.read_csv(os.path.join(path_root, 'test_0731', 'intermediates', 'match6.csv'), index_col=0)\n",
+ "m6 = self.match6[self.match6.node_id=='106332']\n",
+ "m6.state"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "1. 데이터를 준비합니다.\n",
+ "1-1. 네트워크가 로드되었습니다.\n",
+ "1-2. 테이블들이 로드되었습니다.\n",
+ "1-5. 필요한 보조 객체들이 모두 준비되었습니다.\n"
+ ]
+ }
+ ],
+ "source": [
+ "self = SignalGenerator(config_name='test_0731')\n",
+ "self.prepare_data()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "40 gGGGrrrrrrgrrgrrrrrrrrgrrrr\n",
+ "41 grrrrGGrrrgrrgrrrrrrrrgrrrr\n",
+ "42 gGGGrrrrrrgrrgrrrrrrrrgrrrr\n",
+ "43 grrrrrrrrrgrrgrGGGGGrrgrrrr\n",
+ "44 grrrrrrrrrgrrgrrrrrrGGgrrrr\n",
+ "45 grrrrrrrrrgrrgrGGGGGrrgrrrr\n",
+ "46 grrrrrrrrrgrrgrrrrrrrrgrrrG\n",
+ "47 grrrrrrrrrgrrgrrrrrrrrgGGGr\n",
+ "48 grrrrrrGGrgrrgrrrrrrrrgrrrr\n",
+ "49 grrrrrrrrGgrrgrrrrrrrrgrrrr\n",
+ "50 grrrrrrGGrgrrgrrrrrrrrgrrrr\n",
+ "51 grrrrrrrrGgrrgrrrrrrrrgrrrr\n",
+ "Name: state, dtype: object"
+ ]
+ },
+ "execution_count": 18,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "match6 = pd.read_csv(os.path.join(path_root, 'test_0731', 'intermediates', 'match6.csv'), index_col=0)\n",
+ "m6 = self.match6[self.match6.node_id=='106332']\n",
+ "m6.state"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "40 gGGGrrrrrrgrrgrrrrrrrrgrrrr\n",
+ "41 grrrrGGrrrgrrgrrrrrrrrgrrrr\n",
+ "42 gGGGrrrrrrgrrgrrrrrrrrgrrrr\n",
+ "43 grrrrrrrrrgrrgrGGGGGrrgrrrr\n",
+ "44 grrrrrrrrrgrrgrrrrrrGGgrrrr\n",
+ "45 grrrrrrrrrgrrgrGGGGGrrgrrrr\n",
+ "46 grrrrrrrrrgrrgrrrrrrrrgrrrG\n",
+ "47 grrrrrrrrrgrrgrrrrrrrrgGGGr\n",
+ "48 grrrrrrGGrgrrgrrrrrrrrgrrrr\n",
+ "49 grrrrrrrrGgrrgrrrrrrrrgrrrr\n",
+ "50 grrrrrrGGrgrrgrrrrrrrrgrrrr\n",
+ "51 grrrrrrrrGgrrgrrrrrrrrgrrrr\n",
+ "Name: state, dtype: object"
+ ]
+ },
+ "execution_count": 12,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "m6 = self.match6[self.match6.node_id=='106332']\n",
+ "m6.state"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/plain": [
+ "40 gGGGrrrrrrgrrgrrrrrrrrgrrrr\n",
+ "41 grrrrGGrrrgrrgrrrrrrrrgrrrr\n",
+ "42 gGGGrrrrrrgrrgrrrrrrrrgrrrr\n",
+ "43 grrrrrrrrrgrrgrGGGGGrrgrrrr\n",
+ "44 grrrrrrrrrgrrgrrrrrrGGgrrrr\n",
+ "45 grrrrrrrrrgrrgrGGGGGrrgrrrr\n",
+ "46 grrrrrrrrrgrrgrrrrrrrrgrrrG\n",
+ "47 grrrrrrrrrgrrgrrrrrrrrgGGGr\n",
+ "48 grrrrrrGGrgrrgrrrrrrrrgrrrr\n",
+ "49 grrrrrrrrGgrrgrrrrrrrrgrrrr\n",
+ "50 grrrrrrGGrgrrgrrrrrrrrgrrrr\n",
+ "51 grrrrrrrrGgrrgrrrrrrrrgrrrr\n",
+ "Name: state, dtype: object"
+ ]
+ },
+ "execution_count": 11,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "self.match6[self.match6.node_id=='106332'].state"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "siggen_env",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.12.4"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/test_0731/intermediates/match6.csv b/test_0731/intermediates/match6.csv
index 62df6f27b..ce6181bed 100644
--- a/test_0731/intermediates/match6.csv
+++ b/test_0731/intermediates/match6.csv
@@ -39,18 +39,18 @@
37,438,106350,3,B,3,513817,513811,grrGGGGrrrrr,straight
38,438,106350,4,A,7,513792,513816,gGrrrrrrrrrr,left
39,438,106350,4,B,4,513792,513816,gGrrrrrrrrrr,left
-40,442,106332,1,A,6,519824,513731,gGGGrrrrrrgrrgrrrrrrrrgrrrr,straight
-41,442,106332,1,B,1,519824,513726,grrrrGGrrrgrrgrrrrrrrrgrrrr,left
-42,442,106332,2,A,6,519824,513731,gGGGrrrrrrgrrgrrrrrrrrgrrrr,straight
-43,442,106332,2,B,2,513732,513728,grrrrrrrrrgrrgrGGGGGrrgrrrr,straight
-44,442,106332,3,A,5,513732,513729,grrrrrrrrrgrrgrrrrrrGGgrrrr,left
-45,442,106332,3,B,2,513732,513728,grrrrrrrrrgrrgrGGGGGrrgrrrr,straight
-46,442,106332,4,A,7,513730,513728,grrrrrrrrrgrrgrrrrrrrrgrrrG,left
-47,442,106332,4,B,4,513730,513726,grrrrrrrrrgrrgrrrrrrrrgGGGr,straight
-48,442,106332,5,A,8,513727,513729,grrrrrrGGrgrrgrrrrrrrrgrrrr,straight
-49,442,106332,5,B,3,513727,513731,grrrrrrrrGgrrgrrrrrrrrgrrrr,left
-50,442,106332,6,A,8,513727,513729,grrrrrrGGrgrrgrrrrrrrrgrrrr,straight
-51,442,106332,6,B,3,513727,513731,grrrrrrrrGgrrgrrrrrrrrgrrrr,left
+40,442,106332,1,A,6,519824,513731,gGGGgrrrrrgggggrrrrrrrgrrrr,straight
+41,442,106332,1,B,1,519824,513726,grrrgGGrrrgggggrrrrrrrgrrrr,left
+42,442,106332,2,A,6,519824,513731,gGGGgrrrrrgggggrrrrrrrgrrrr,straight
+43,442,106332,2,B,2,513732,513728,grrrgrrrrrgggggGGGGGrrgrrrr,straight
+44,442,106332,3,A,5,513732,513729,grrrgrrrrrgggggrrrrrGGgrrrr,left
+45,442,106332,3,B,2,513732,513728,grrrgrrrrrgggggGGGGGrrgrrrr,straight
+46,442,106332,4,A,7,513730,513728,grrrgrrrrrgggggrrrrrrrgrrrG,left
+47,442,106332,4,B,4,513730,513726,grrrgrrrrrgggggrrrrrrrgGGGr,straight
+48,442,106332,5,A,8,513727,513729,grrrgrrGGrgggggrrrrrrrgrrrr,straight
+49,442,106332,5,B,3,513727,513731,grrrgrrrrGgggggrrrrrrrgrrrr,left
+50,442,106332,6,A,8,513727,513729,grrrgrrGGrgggggrrrrrrrgrrrr,straight
+51,442,106332,6,B,3,513727,513731,grrrgrrrrGgggggrrrrrrrgrrrr,left
52,443,108769,1,A,6,516916,513863,gGGGGGrrrrrrgrr,straight
53,443,108769,1,B,2,513862,516917,grrrrrGGGGGrgrr,straight
54,443,108769,2,A,5,513862,518550,grrrrrrrrrrGgrr,left
@@ -111,7 +111,7 @@
109,457,109297,4,B,3,,,GGGGGGrr,left
110,457,109297,5,A,7,,,GGGGGGrr,left
111,457,109297,5,B,4,,,GGGGGGrr,straight
-112,458,106238,1,A,8,513193,513188,gGGGrgrrgrrrrgrr,straight
-113,458,106238,1,B,4,513189,513192,grrrrgrrgGGGrgrr,straight
-114,458,106238,2,A,17,,,grrrrgrrgrrrrgrr,
-115,458,106238,2,B,17,,,grrrrgrrgrrrrgrr,
+112,458,106238,1,A,8,513193,513188,gGGGgggggrrrgggg,straight
+113,458,106238,1,B,4,513189,513192,grrrgggggGGGgggg,straight
+114,458,106238,2,A,17,,,grrrgggggrrrgggg,
+115,458,106238,2,B,17,,,grrrgggggrrrgggg,
diff --git a/test_0731/intermediates/matching.csv b/test_0731/intermediates/matching.csv
index 4510109b5..a452376d2 100644
--- a/test_0731/intermediates/matching.csv
+++ b/test_0731/intermediates/matching.csv
@@ -47,22 +47,22 @@ inter_no,node_id,move_no,inc_edge_id,out_edge_id,state,turn_type
438,106350,14,513817,513811,grrGGGGrrrrr,straight
438,106350,15,513792,513816,gGrrrrrrrrrr,left
438,106350,16,513817,513793,grGrrrrrrrrr,straight
-442,106332,1,519824,513726,grrrrGGrrrgrrgrrrrrrrrgrrrr,left
-442,106332,2,513732,513728,grrrrrrrrrgrrgrGGGGGrrgrrrr,straight
-442,106332,3,513727,513731,grrrrrrrrGgrrgrrrrrrrrgrrrr,left
-442,106332,4,513730,513726,grrrrrrrrrgrrgrrrrrrrrgGGGr,straight
-442,106332,5,513732,513729,grrrrrrrrrgrrgrrrrrrGGgrrrr,left
-442,106332,6,519824,513731,gGGGrrrrrrgrrgrrrrrrrrgrrrr,straight
-442,106332,7,513730,513728,grrrrrrrrrgrrgrrrrrrrrgrrrG,left
-442,106332,8,513727,513729,grrrrrrGGrgrrgrrrrrrrrgrrrr,straight
-442,106332,9,519824,513726,grrrrGGrrrgrrgrrrrrrrrgrrrr,left
-442,106332,10,513732,513728,grrrrrrrrrgrrgrGGGGGrrgrrrr,straight
-442,106332,11,513727,513731,grrrrrrrrGgrrgrrrrrrrrgrrrr,left
-442,106332,12,513730,513726,grrrrrrrrrgrrgrrrrrrrrgGGGr,straight
-442,106332,13,513732,513729,grrrrrrrrrgrrgrrrrrrGGgrrrr,left
-442,106332,14,519824,513731,gGGGrrrrrrgrrgrrrrrrrrgrrrr,straight
-442,106332,15,513730,513728,grrrrrrrrrgrrgrrrrrrrrgrrrG,left
-442,106332,16,513727,513729,grrrrrrGGrgrrgrrrrrrrrgrrrr,straight
+442,106332,1,519824,513726,grrrgGGrrrgggggrrrrrrrgrrrr,left
+442,106332,2,513732,513728,grrrgrrrrrgggggGGGGGrrgrrrr,straight
+442,106332,3,513727,513731,grrrgrrrrGgggggrrrrrrrgrrrr,left
+442,106332,4,513730,513726,grrrgrrrrrgggggrrrrrrrgGGGr,straight
+442,106332,5,513732,513729,grrrgrrrrrgggggrrrrrGGgrrrr,left
+442,106332,6,519824,513731,gGGGgrrrrrgggggrrrrrrrgrrrr,straight
+442,106332,7,513730,513728,grrrgrrrrrgggggrrrrrrrgrrrG,left
+442,106332,8,513727,513729,grrrgrrGGrgggggrrrrrrrgrrrr,straight
+442,106332,9,519824,513726,grrrgGGrrrgggggrrrrrrrgrrrr,left
+442,106332,10,513732,513728,grrrgrrrrrgggggGGGGGrrgrrrr,straight
+442,106332,11,513727,513731,grrrgrrrrGgggggrrrrrrrgrrrr,left
+442,106332,12,513730,513726,grrrgrrrrrgggggrrrrrrrgGGGr,straight
+442,106332,13,513732,513729,grrrgrrrrrgggggrrrrrGGgrrrr,left
+442,106332,14,519824,513731,gGGGgrrrrrgggggrrrrrrrgrrrr,straight
+442,106332,15,513730,513728,grrrgrrrrrgggggrrrrrrrgrrrG,left
+442,106332,16,513727,513729,grrrgrrGGrgggggrrrrrrrgrrrr,straight
443,108769,1,516916,513863,gGGGGGrrrrrrgrr,straight
443,108769,2,513862,516917,grrrrrGGGGGrgrr,straight
443,108769,3,513862,518550,grrrrrrrrrrGgrr,left
diff --git a/test_0731/results/sn_1722384300.add.xml b/test_0731/results/sn_1722384300.add.xml
index 48b05fc06..fe50aa10d 100644
--- a/test_0731/results/sn_1722384300.add.xml
+++ b/test_0731/results/sn_1722384300.add.xml
@@ -64,29 +64,29 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+