From e10b8c2a3f6ee6b639dbb49ff6635d0657531d1e Mon Sep 17 00:00:00 2001
From: LYW <leeyeanwoo@diteam.co.kr>
Date: 목, 08 7월 2021 17:04:05 +0900
Subject: [PATCH] Ongoing60 #3486CF AOI Review Review History 프로그램 테스트 및 적용

---
 ReviewHistory/include/akSTL/akVector.h                                |   45 
 ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCheck.h         |   68 
 ReviewHistory/include/akSTL/backup/akInterpolation.h                  |   48 
 ReviewHistory/ReveiwHistory/MacroResultFile.cpp                       |  357 
 DitGlassRawMessenger/Extern/DitGlassRawStruct.h                       |  280 
 ReviewHistory/include/akGraph/akResource.h                            |   89 
 ReviewHistory/ReveiwHistory/akImageView.cpp                           |  497 
 ReviewHistory/ReveiwHistory/akFormationMap.cpp                        | 1190 ++
 ReviewHistory/ReveiwHistory/DitGlassRawClient.cpp                     |  223 
 ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellNumeric.h       |   26 
 ReviewHistory/include/akCore/akInterpolation.h                        |   48 
 ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.cpp                      | 3766 ++++++
 ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj                     |  268 
 ReviewHistory/ReveiwHistory/CustomizeReview.cpp                       |   84 
 ReviewHistory/include/akGraph/akDataVector2.h                         |   57 
 DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp         |   76 
 ReviewHistory/include/akSTL/akRectT.h                                 |  196 
 ReviewHistory/include/akSTL/akSTLLinker.h                             |   56 
 ReviewHistory/include/akCore/akLogger.h                               |   69 
 ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.cpp                    |  345 
 ReviewHistory/include/akSTL/akTrajectory.h                            |  170 
 ReviewHistory/include/akCore/akRandom.h                               |   23 
 ReviewHistory/ReveiwHistory/StackResultCSOT.h                         |   76 
 ReviewHistory/ReveiwHistory/InterfaceFTP.h                            |  100 
 ReviewHistory/ReveiwHistory/MacroResultFile.h                         |  231 
 ReviewHistory/include/akGraph/akColorTable.h                          |   58 
 ReviewHistory/include/akSTL/새 폴더/akMath.h                             |   30 
 ReviewHistory/include/akSTL/새 폴더/akWaypoint.h                         |   36 
 ReviewHistory/ReveiwHistory/akImageView.h                             |   99 
 ReviewHistory/include/akGraph/akColorSettingDlg.h                     |   59 
 ReviewHistory/include/akGraph/akDataBasic3.h                          |   42 
 ReviewHistory/ReveiwHistory/CHTrackerView.cpp                         |  124 
 ReviewHistory/include/akSTL/새 폴더/akTextExt.h                          |   16 
 ReviewHistory/include/akGridCtrl/testCtrl.h                           |   25 
 DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h           |   24 
 DitGlassRawMessenger/Extern/DitGlassRawClient.h                       |   10 
 ReviewHistory/ReveiwHistory/akWndArrange.h                            |   41 
 ReviewHistory/include/akCore/akTrajectoryModel.h                      |   66 
 ReviewHistory/include/akGraph/akRangeSettingTimeDlg.h                 |   50 
 ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp                  |  563 
 ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.h                      |    3 
 ReviewHistory/include/akSTL/akColor.h                                 |   23 
 ReviewHistory/include/akGridCtrl/GridCellCheck.h                      |   68 
 ReviewHistory/include/akCore/akFileUtil.h                             |   79 
 ReviewHistory/include/akGraph/akSelectDataDlg.h                       |   59 
 ReviewSystem/include/CHReviewResult/ReviewResult.h                    |   25 
 ReviewHistory/ReveiwHistory/akDefectFormation.cpp                     |   98 
 ReviewHistory/include/akCore/akString.h                               |  143 
 ReviewHistory/include/akGraph/akGraphLinker.h                         |   69 
 ReviewHistory/include/akCore/akStructPoint.h                          |   51 
 ReviewHistory/include/akSTL/새 폴더/akFileMgrAdv.h                       |   74 
 ReviewHistory/include/akGraph/akGraphBase.h                           |  312 
 ReviewHistory/include/akSTL/backup/akSyncObject.h                     |   33 
 ReviewHistory/include/akSTL/inl/akRectT.inl                           |  368 
 ReviewHistory/include/akCore/akStructRect.h                           |   59 
 ReviewHistory/include/akGraph/akDataBasic2.h                          |   47 
 ReviewHistory/include/akSTL/akVectorT.h                               |   50 
 ReviewHistory/ReveiwHistory/GlassRawDemo.h                            |   72 
 ReviewHistory/include/akSTL/새 폴더/akInterpolation.h                    |   48 
 ReviewHistory/include/akCore/akStructVector.h                         |  165 
 ReviewHistory/include/akSTL/backup/akTraceExt.h                       |   47 
 ReviewHistory/include/akCore/akText.h                                 |   48 
 ReviewHistory/include/akGridCtrl/NewCellTypes/GridURLCell.h           |   55 
 ReviewHistory/include/akSTL/akTrace.h                                 |   61 
 ReviewHistory/include/akSTL/inl/akVectorT.inl                         |  109 
 ReviewHistory/include/akGridCtrl/MemDC.h                              |  106 
 ReviewHistory/include/akSTL/backup/akFileMgrB.h                       |   40 
 ReviewHistory/include/akSTL/akPointT.h                                |   37 
 ReviewHistory/ReveiwHistory/GlassRawCPJT.cpp                          | 2279 ++++
 ReviewHistory/include/akGridCtrl/GridCellBase.h                       |  175 
 ReviewHistory/include/akGraph/akGraphStruct.h                         |  290 
 ReviewHistory/ReveiwHistory/stdafx.h                                  |   85 
 .gitignore                                                            |    4 
 ReviewHistory/include/akSTL/새 폴더/akMemory.h                           |   16 
 ReviewHistory/include/akCore/akColorStruct.h                          |  128 
 ReviewHistory/ReveiwHistory/AnaResultFile.h                           |   42 
 ReviewHistory/ReveiwHistory/GlassRawDemo.cpp                          | 1432 ++
 ReviewHistory/include/akGraph/khDataBase.h                            |   14 
 ReviewHistory/include/akSTL/backup/akColorStruct.h                    |  128 
 ReviewHistory/include/akSTL/새 폴더/akTraceExt.h                         |   47 
 ReviewHistory/include/akGraph/akDataBasic1.h                          |   26 
 ReviewSystem/ReviewSystem/DitGlassRawStruct.h                         |  280 
 ReviewHistory/ReveiwHistory/GlassRawCPJT.h                            |  134 
 ReviewHistory/include/akSTL/backup/akTextExt.h                        |   16 
 ReviewHistory/ReveiwHistory/akLoggerExt.h                             |   30 
 ReviewHistory/include/akCore/akFileDBHash.h                           |   72 
 ReviewHistory/include/akCore/akTextExt.h                              |   16 
 ReviewHistory/include/akCore/akStructColor.h                          |   23 
 ReviewHistory/include/akSTL/backup/akTrajectoryModel.h                |   66 
 ReviewHistory/include/akCore/akSyncObject.h                           |   33 
 ReviewHistory/include/akSTL/새 폴더/akString.h                           |  143 
 ReviewSystem/ReviewSystem/DitGlassRawClient.cpp                       |   13 
 ReviewHistory/ReveiwHistory/DitGlassRawServer.cpp                     |  183 
 ReviewHistory/include/akSTL/새 폴더/akRandom.h                           |   23 
 ReviewHistory/ReveiwHistory/DitGlassRawServer.h                       |   45 
 ReviewHistory/ReveiwHistory/GlassRawBase.cpp                          |  131 
 ReviewHistory/include/akSTL/backup/akWaypoint.h                       |   36 
 ReviewHistory/include/akGraph/akGraphBasic3.h                         |  104 
 ReviewHistory/include/akGraph/akSyncObject.h                          |   31 
 ReviewHistory/include/akGridCtrl/TitleTip.h                           |   87 
 ReviewHistory/include/akSTL/새 폴더/akColorStruct.h                      |  128 
 ReviewHistory/ReveiwHistory/akGridData.h                              |   97 
 ReviewHistory/include/akGraph/akPixel.h                               |   34 
 ReviewHistory/include/akGridCtrl/GridDropTarget.h                     |   82 
 ReviewHistory/include/akGridCtrl/InPlaceEdit.h                        |   83 
 ReviewHistory/include/akSTL/새 폴더/akFileUtil.h                         |   21 
 ReviewHistory/ReveiwHistory/GlassRawCSOT.h                            |   93 
 ReviewHistory/include/akSTL/새 폴더/akCoordinate.h                       |   28 
 ReviewHistory/include/akCore/akDE.h                                   |  123 
 ReviewHistory/include/akCore/akFileDB.h                               |   80 
 ReviewHistory/include/akGraph/akGraphUtil.h                           |   61 
 ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.h                        |  275 
 ReviewHistory/include/akCore/akFileMgrAdv.h                           |   74 
 ReviewHistory/include/akGraph/akRangeSettingDlg.h                     |   58 
 ReviewHistory/include/akGraph/akRaySettingDlg.h                       |   58 
 ReviewHistory/ReveiwHistory/PathSettingDlg.cpp                        |  297 
 ReviewHistory/include/akSTL/새 폴더/akMatrix.h                           |   36 
 ReviewHistory/include/akCore/akVector.h                               |   20 
 ReviewHistory/include/akSTL/akQueueCircle.h                           |  151 
 ReviewHistory/include/akGraph/akMemDC.h                               |   90 
 DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp |  120 
 ReviewHistory/ReveiwHistory/res/History.ico                           |    0 
 ReviewHistory/include/akSTL/backup/akString.h                         |  143 
 ReviewHistory/include/akCore/akTraceExt.h                             |   38 
 ReviewHistory/ReveiwHistory/AlignDlg.cpp                              |  515 
 ReviewHistory/ReveiwHistory/GlassRawCEC.cpp                           |   96 
 ReviewHistory/ReveiwHistory/x64/Debug/reveiwhistorydlg.obj.enc        |    0 
 ReviewHistory/ReveiwHistory/res/ReveiwHistory.ico                     |    0 
 ReviewHistory/include/akCore/akFileMgr.h                              |   80 
 ReviewHistory/include/akSTL/backup/akMemory.h                         |   16 
 ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj.filters             |  195 
 ReviewHistory/include/akSTL/backup/akFileMgr.h                        |   80 
 ReviewHistory/include/akSTL/새 폴더/akTrajectoryModel.h                  |   66 
 ReviewHistory/ReveiwHistory/DitGlassRawStruct.h                       |  745 +
 ReviewHistory/ReveiwHistory/GlassRawRTMS.cpp                          |  849 +
 ReviewHistory/ReveiwHistory/ReveiwHistory.h                           |   32 
 ReviewHistory/ReveiwHistory/akGridData.cpp                            |  478 
 ReviewHistory/ReviewHistory.sln                                       |   37 
 ReviewHistory/include/akGraph/akColorTableOption.h                    |   70 
 ReviewSystem/ReviewSystem/ReviewProcessor.h                           |    5 
 DitGlassRawMessenger/Extern/DitGlassRawClient.cpp                     |   13 
 ReviewHistory/ReveiwHistory/GlassRawCSOT.cpp                          | 1696 ++
 ReviewHistory/ReveiwHistory/DitGlassRawClient.h                       |   66 
 ReviewHistory/include/akSTL/backup/akRandom.h                         |   23 
 ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCombo.h         |  177 
 ReviewHistory/include/akGraph/akGraphMesh.h                           |  106 
 ReviewHistory/include/akGraph/akRangeSettingNormalDlg.h               |   56 
 ReviewHistory/include/akGraph/akDataMesh.h                            |   34 
 ReviewHistory/include/akSTL/새 폴더/akFileMgr.h                          |   80 
 ReviewHistory/ReveiwHistory/akIPCNetAOISystem.h                       |  139 
 ReviewHistory/ReveiwHistory/akWndArrange.cpp                          |   98 
 ReviewHistory/include/akCore/akTrace.h                                |   66 
 ReviewHistory/ReveiwHistory/akDefectFormation.h                       |  431 
 ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellDateTime.h      |   92 
 ReviewHistory/include/akSTL/backup/akText.h                           |   46 
 ReviewHistory/ReveiwHistory/CHTrackerView.h                           |   35 
 ReviewHistory/include/akCore/akDefine.h                               |   10 
 ReviewHistory/include/akSTL/backup/akMatrix.h                         |   36 
 ReviewHistory/include/akSTL/backup/akCoordinate.h                     |   28 
 ReviewHistory/include/akSTL/backup/akFileUtil.h                       |   21 
 ReviewHistory/include/akSTL/새 폴더/akText.h                             |   46 
 ReviewHistory/ReveiwHistory/targetver.h                               |    8 
 ReviewHistory/include/akGraph/akUnit.h                                |   37 
 ReviewHistory/include/akSTL/backup/akMath.h                           |   30 
 ReviewHistory/ReveiwHistory/CHRectTracker.h                           |   26 
 ReviewHistory/ReveiwHistory/res/ReveiwHistory.rc2                     |    0 
 ReviewHistory/ReveiwHistory/CHRectTracker.cpp                         |  316 
 ReviewHistory/include/akGridCtrl/CellRange.h                          |  148 
 ReviewHistory/ReveiwHistory/Singleton.h                               |   35 
 ReviewHistory/ReveiwHistory/GlassRawCEC.h                             |   26 
 ReviewHistory/include/akSTL/akRect.h                                  |  117 
 ReviewHistory/include/akSTL/새 폴더/akFileMgrB.h                         |   40 
 ReviewHistory/ReveiwHistory/GlassRawBase.h                            |   75 
 ReviewHistory/include/akCore/akTimeManager.h                          |   93 
 ReviewHistory/ReveiwHistory/resource.h                                |  102 
 ReviewHistory/include/akSTL/새 폴더/akSyncObject.h                       |   33 
 ReviewHistory/include/akSTL/새 폴더/akTimeManager.h                      |   93 
 ReviewHistory/ReveiwHistory/StackResultCPJT.h                         |   87 
 ReviewHistory/include/akSTL/akQueue.h                                 |  100 
 ReviewHistory/include/akSTL/backup/akTimeManager.h                    |   93 
 ReviewHistory/ReveiwHistory/CameraImageView.h                         |  139 
 ReviewHistory/include/akCore/akCoordinate.h                           |   28 
 ReviewHistory/ReveiwHistory/stdafx.cpp                                |  137 
 DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp            |   31 
 ReviewHistory/ReveiwHistory/ReveiwHistory.cpp                         |  106 
 ReviewHistory/include/akCore/akCoreLinker.h                           |   63 
 ReviewHistory/include/akCore/akFileMgrB.h                             |   40 
 ReviewHistory/ReveiwHistory/GlassRawRTMS.h                            |   48 
 ReviewHistory/ReveiwHistory/StackResultCSOT.cpp                       |  226 
 ReviewHistory/ReveiwHistory/StackResultCPJT.cpp                       |  337 
 ReviewHistory/include/akCore/akMath.h                                 |   37 
 DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.h              |   16 
 ReviewHistory/include/akGraph/akGraphImage.h                          |   84 
 ReviewHistory/include/akGraph/akDDSettingDlg.h                        |   67 
 ReviewHistory/ReveiwHistory/akIPCNetAOISystem.cpp                     |  189 
 ReviewHistory/ReveiwHistory/ReveiwHistory.rc                          |    0 
 ReviewHistory/include/akSTL/backup/akFileMgrAdv.h                     |   74 
 ReviewHistory/include/akCore/akMatrix.h                               |   36 
 ReviewHistory/ReveiwHistory/AlignDlg.h                                |   71 
 ReviewHistory/include/akCore/akWGS84.h                                |   22 
 ReviewHistory/include/akSTL/새 폴더/akWGS84.h                            |   22 
 ReviewHistory/ReveiwHistory/CustomizeReview.h                         |   65 
 ReviewHistory/include/akSTL/backup/akWGS84.h                          |   22 
 ReviewHistory/ReveiwHistory/aaa.txt                                   |    0 
 ReviewHistory/include/akGridCtrl/akGridCtrl.h                         |  925 +
 ReviewHistory/include/akGraph/akDataImage.h                           |   47 
 ReviewHistory/ReveiwHistory/AnaResultFile.cpp                         |  140 
 ReviewHistory/include/akGridCtrl/akGridCtrlLinker.h                   |   65 
 ReviewHistory/ReveiwHistory/InterfaceFTP.cpp                          |  389 
 ReviewHistory/include/akGraph/akGraphType2V.h                         |   72 
 ReviewHistory/include/akCore/akStruct.h                               |  134 
 ReviewHistory/include/akGridCtrl/GridCell.h                           |  143 
 ReviewSystem/ReviewSystem/DitGlassRawClient.h                         |   10 
 ReviewHistory/include/akSTL/akStruct.h                                |    8 
 ReviewHistory/include/akCore/akBit.h                                  |   57 
 ReviewHistory/include/akGraph/akGraphCodeJ.h                          |   90 
 ReviewHistory/include/akSTL/inl/akPointT.inl                          |   70 
 ReviewHistory/ReveiwHistory/akFormationMap.h                          |   65 
 ReviewHistory/ReveiwHistory/PathSettingDlg.h                          |   47 
 ReviewHistory/include/akCore/akDE2.h                                  |  123 
 ReviewSystem/ReviewSystem/ReviewProcessor.cpp                         |   10 
 ReviewHistory/ReveiwHistory/CameraImageView.cpp                       |  985 +
 ReviewHistory/ReveiwHistory/akLoggerExt.cpp                           |   40 
 ReviewHistory/include/akSTL/akPoint.h                                 |   48 
 ReviewHistory/include/akCore/akWaypoint.h                             |   36 
 ReviewHistory/include/akCore/akPathFileUtil.h                         |   24 
 DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp            |  274 
 227 files changed, 33,201 insertions(+), 785 deletions(-)

diff --git a/.gitignore b/.gitignore
index a87b361..3c46078 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,10 @@
 DitGlassRawMessenger/lib/
 DitGlassRawMessenger/Backup/
 
+ReviewHistory/.vs/
+ReviewHistory/bin/
+ReviewHistory/lib/
+
 *.sdf
 *.opensdf
 *.suo
diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp
index bf1c099..4f22cb1 100644
--- a/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp
+++ b/DitGlassRawMessenger/DitGlassRawMessenger/DitGlassRawMessengerDlg.cpp
@@ -1,5 +1,5 @@
 
-// DitGlassRawMessengerDlg.cpp : 구현 파일
+// DitGlassRawMessengerDlg.cpp : 占쏙옙占쏙옙 占쏙옙占쏙옙
 //
 
 #include "stdafx.h"
@@ -23,20 +23,20 @@
 #define GRID_TEXT_COLOR			RGB(255,255,255)
 #define GRID_ALARM_TEXT_COLOR	RGB(255,0,0)
 #define GRID_LINE_COLOR			GRID_FIX_COLOR
-// 응용 프로그램 정보에 사용되는 CAboutDlg 대화 상자입니다.
+// 占쏙옙占쏙옙 占쏙옙占싸그뤄옙 占쏙옙占쏙옙占쏙옙 占쏙옙占실댐옙 CAboutDlg 占쏙옙화 占쏙옙占쏙옙占쌉니댐옙.
 
 class CAboutDlg : public CDialog
 {
 public:
 	CAboutDlg();
 
-// 대화 상자 데이터입니다.
+// 占쏙옙화 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쌉니댐옙.
 	enum { IDD = IDD_ABOUTBOX };
 
 	protected:
-	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 占쏙옙占쏙옙占쌉니댐옙.
 
-// 구현입니다.
+// 占쏙옙占쏙옙占쌉니댐옙.
 protected:
 	DECLARE_MESSAGE_MAP()
 };
@@ -54,7 +54,7 @@
 END_MESSAGE_MAP()
 
 
-// CDitGlassRawMessengerDlg 대화 상자
+// CDitGlassRawMessengerDlg 占쏙옙화 占쏙옙占쏙옙
 
 
 
@@ -127,7 +127,7 @@
 	m_vecStrGridDefectHeader.push_back("CellY(mm)");
 	m_vecStrGridDefectHeader.push_back("ScrtRatio");
 	m_vecStrGridDefectHeader.push_back("Density");
-	//201207 CJH - Merge 여부 확인
+	//201207 CJH - Merge 占쏙옙占쏙옙 확占쏙옙
 	m_vecStrGridDefectHeader.push_back("MergeState");
 
 }
@@ -192,16 +192,16 @@
 	if (timestruct.tm_mon>11 || timestruct.tm_mon<0 )
 		ASSERT(FALSE);
 }
-// CDitGlassRawMessengerDlg 메시지 처리기
+// CDitGlassRawMessengerDlg 占쌨쏙옙占쏙옙 처占쏙옙占쏙옙
 
 BOOL CDitGlassRawMessengerDlg::OnInitDialog()
 {
 	CDialog::OnInitDialog();
 
 	DragAcceptFiles(TRUE);
-	// 시스템 메뉴에 "정보..." 메뉴 항목을 추가합니다.
+	// 占시쏙옙占쏙옙 占쌨댐옙占쏙옙 "占쏙옙占쏙옙..." 占쌨댐옙 占쌓몌옙占쏙옙 占쌩곤옙占쌌니댐옙.
 
-	// IDM_ABOUTBOX는 시스템 명령 범위에 있어야 합니다.
+	// IDM_ABOUTBOX占쏙옙 占시쏙옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙占쏙옙 占쌍억옙占� 占쌌니댐옙.
 	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
 	ASSERT(IDM_ABOUTBOX < 0xF000);
 
@@ -219,16 +219,16 @@
 		}
 	}
 
-	// 이 대화 상자의 아이콘을 설정합니다. 응용 프로그램의 주 창이 대화 상자가 아닐 경우에는
-	//  프레임워크가 이 작업을 자동으로 수행합니다.
-	SetIcon(m_hIcon, TRUE);			// 큰 아이콘을 설정합니다.
-	SetIcon(m_hIcon, FALSE);		// 작은 아이콘을 설정합니다.
+	// 占쏙옙 占쏙옙화 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쌌니댐옙. 占쏙옙占쏙옙 占쏙옙占싸그뤄옙占쏙옙 占쏙옙 창占쏙옙 占쏙옙화 占쏙옙占쌘곤옙 占싣댐옙 占쏙옙荑∽옙占�
+	//  占쏙옙占쏙옙占쌈울옙크占쏙옙 占쏙옙 占쌜억옙占쏙옙 占쌘듸옙占쏙옙占쏙옙 占쏙옙占쏙옙占쌌니댐옙.
+	SetIcon(m_hIcon, TRUE);			// 큰 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쌌니댐옙.
+	SetIcon(m_hIcon, FALSE);		// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쌌니댐옙.
 
-	//트레이아이콘 구성
+	//트占쏙옙占싱억옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	m_TrayIcon = FALSE;
 	ResTrayIcon();
 
-	//빌드 정보
+	//占쏙옙占� 占쏙옙占쏙옙
 	{
 		CString strBuild;
 		tm tmBuild;
@@ -237,7 +237,7 @@
 		SetDlgItemText(IDC_BUILDDATE, strBuild);
 	}
 
-	//설정파일 정보 읽어 오기 [김태현 2018/11/20]
+	//占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占싻억옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/20]
 	{
 		m_strConfigFile;
 		{
@@ -268,7 +268,7 @@
 		SetDlgItemText(IDC_EDIT_STACK_PARAM2, m_ConfigOption.m_strStackParam2);
 	}
 
-	//로그 관련 [김태현 2018/11/20]
+	//占싸깍옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/20]
 	{
 		CakFileUtil fileutil;
 		char strPath[256];
@@ -371,30 +371,30 @@
 
 	if(m_Server.CreateServer(m_ConfigOption.m_nMaxDataNumCell, m_ConfigOption.m_nMaxDataNumDefect) == FALSE)
 	{
-		AfxMessageBox("서버 생성 실패 종료 합니다.");
+		AfxMessageBox("占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쌌니댐옙.");
 		exit(0);
 	}
 
-	//현재값 적용 [김태현 2019/1/12]
+	//占쏙옙占썹값 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/1/12]
 	{
 		CDitGlassRawServer* pServer = (CDitGlassRawServer*) &m_Server;
 		CgrmGlassRawData* pRawDataBuffer = &m_GlassRawDataBuffer;
 		pRawDataBuffer->ImportGlassRaw(pServer->GetGlassRawInfo(), (char*)pServer->GetGlassData());
 	}
 	
-	//작업 쓰레드 생성 [김태현 2018/11/13]
+	//占쌜억옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/13]
 	{
 		_beginthread(threadMain, NULL, this);
 	}
 	
 	PostMessage(UM_GLASSRAW_CLIENTMESSAGE);
 
-	return TRUE;  // 포커스를 컨트롤에 설정하지 않으면 TRUE를 반환합니다.
+	return TRUE;  // 占쏙옙커占쏙옙占쏙옙 占쏙옙트占싼울옙 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 TRUE占쏙옙 占쏙옙환占쌌니댐옙.
 }
 
 void CDitGlassRawMessengerDlg::OnBnClickedOk()
 {
-	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
+	// TODO: 占쏙옙占썩에 占쏙옙트占쏙옙 占싯몌옙 처占쏙옙占쏙옙 占쌘드를 占쌩곤옙占쌌니댐옙.
 	OnOK();
 }
 
@@ -403,14 +403,14 @@
 {
 	NOTIFYICONDATA nid;
 	nid.cbSize = sizeof(nid);
-	nid.hWnd = m_hWnd; // 메인 윈도우 핸들
-	nid.uID = IDR_MAINFRAME; // 아이콘 리소스 ID
-	nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 플래그 설정
-	nid.uCallbackMessage = UM_TRAYICON_MSG; // 콜백메시지 설정
-	nid.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // 아이콘 로드
+	nid.hWnd = m_hWnd; // 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쌘듸옙
+	nid.uID = IDR_MAINFRAME; // 占쏙옙占쏙옙占쏙옙 占쏙옙占쌀쏙옙 ID
+	nid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // 占시뤄옙占쏙옙 占쏙옙占쏙옙
+	nid.uCallbackMessage = UM_TRAYICON_MSG; // 占쌥뱄옙聘占쏙옙占� 占쏙옙占쏙옙
+	nid.hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); // 占쏙옙占쏙옙占쏙옙 占싸듸옙
 
 	char strTitle[256];
-	GetWindowText(strTitle, sizeof(strTitle)); // 캡션바에 출력된 문자열 얻음
+	GetWindowText(strTitle, sizeof(strTitle)); // 캡占실바울옙 占쏙옙쨉占� 占쏙옙占쌘울옙 占쏙옙占쏙옙
 	lstrcpy(nid.szTip, strTitle);
 	Shell_NotifyIcon(NIM_ADD, &nid);
 	SendMessage(WM_SETICON, (WPARAM)TRUE, (LPARAM)nid.hIcon);
@@ -433,7 +433,7 @@
 		GetCursorPos(&pos);
 		{
 			HMENU hMenu = CreatePopupMenu();
-			AppendMenu(hMenu, MF_STRING, 0, "연구소2파트작품");
+			AppendMenu(hMenu, MF_STRING, 0, "占쏙옙占쏙옙占쏙옙2占쏙옙트占쏙옙품");
 			AppendMenu(hMenu, MF_STRING, WM_DESTROY, "Exit");
 			TrackPopupMenu(hMenu, TPM_LEFTALIGN | TPM_RIGHTBUTTON, pos.x, pos.y, 0, GetSafeHwnd(), NULL);
 		}
@@ -461,19 +461,19 @@
 	}
 }
 
-// 대화 상자에 최소화 단추를 추가할 경우 아이콘을 그리려면
-//  아래 코드가 필요합니다. 문서/뷰 모델을 사용하는 MFC 응용 프로그램의 경우에는
-//  프레임워크에서 이 작업을 자동으로 수행합니다.
+// 占쏙옙화 占쏙옙占쌘울옙 占쌍쇽옙화 占쏙옙占쌩몌옙 占쌩곤옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙占쏙옙占쏙옙 占쌓몌옙占쏙옙占쏙옙
+//  占싣뤄옙 占쌘드가 占십울옙占쌌니댐옙. 占쏙옙占쏙옙/占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙求占� MFC 占쏙옙占쏙옙 占쏙옙占싸그뤄옙占쏙옙 占쏙옙荑∽옙占�
+//  占쏙옙占쏙옙占쌈울옙크占쏙옙占쏙옙 占쏙옙 占쌜억옙占쏙옙 占쌘듸옙占쏙옙占쏙옙 占쏙옙占쏙옙占쌌니댐옙.
 
 void CDitGlassRawMessengerDlg::OnPaint()
 {
 	if (IsIconic())
 	{
-		CPaintDC dc(this); // 그리기를 위한 디바이스 컨텍스트
+		CPaintDC dc(this); // 占쌓몌옙占썩를 占쏙옙占쏙옙 占쏙옙占쏙옙決占� 占쏙옙占쌔쏙옙트
 
 		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
 
-		// 클라이언트 사각형에서 아이콘을 가운데에 맞춥니다.
+		// 클占쏙옙占싱억옙트 占썹각占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏘데占쏙옙 占쏙옙占쏙옙求占�.
 		int cxIcon = GetSystemMetrics(SM_CXICON);
 		int cyIcon = GetSystemMetrics(SM_CYICON);
 		CRect rect;
@@ -481,7 +481,7 @@
 		int x = (rect.Width() - cxIcon + 1) / 2;
 		int y = (rect.Height() - cyIcon + 1) / 2;
 
-		// 아이콘을 그립니다.
+		// 占쏙옙占쏙옙占쏙옙占쏙옙 占쌓몌옙占싹댐옙.
 		dc.DrawIcon(x, y, m_hIcon);
 	}
 	else
@@ -490,8 +490,8 @@
 	}
 }
 
-// 사용자가 최소화된 창을 끄는 동안에 커서가 표시되도록 시스템에서
-//  이 함수를 호출합니다.
+// 占쏙옙占쏙옙微占� 占쌍쇽옙화占쏙옙 창占쏙옙 占쏙옙占� 占쏙옙占싫울옙 커占쏙옙占쏙옙 표占시되듸옙占쏙옙 占시쏙옙占쌜울옙占쏙옙
+//  占쏙옙 占쌉쇽옙占쏙옙 호占쏙옙占쌌니댐옙.
 HCURSOR CDitGlassRawMessengerDlg::OnQueryDragIcon()
 {
 	return static_cast<HCURSOR>(m_hIcon);
@@ -501,15 +501,15 @@
 void CDitGlassRawMessengerDlg::OnDropFiles(HDROP hDropInfo)
 {
 	int nFiles;
-	char szPathName[MAX_PATH];  // 파일 경로면이 들어간다.
+	char szPathName[MAX_PATH];  // 占쏙옙占쏙옙 占쏙옙罐占쏙옙占� 占쏙옙載o옙占�.
 	CString strFileName;
 
-	// 드롭된 파일의 갯수
+	// 占쏙옙撻占� 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	nFiles = ::DragQueryFile( hDropInfo, 0xFFFFFFFF, szPathName, MAX_PATH );
 
-	for(int i = nFiles-1 ; i >= 0; i--)  //드롭된 파일 갯수만큼 루프를 돌면서 파일 경로를 메세지 박스로 출력
+	for(int i = nFiles-1 ; i >= 0; i--)  //占쏙옙撻占� 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙큼 占쏙옙占쏙옙占쏙옙 占쏙옙占썽서 占쏙옙占쏙옙 占쏙옙罐占� 占쌨쇽옙占쏙옙 占쌘쏙옙占쏙옙 占쏙옙占�
 	{
-		// 파일의 경로 얻어옴
+		// 占쏙옙占쏙옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙
 		::DragQueryFile(hDropInfo, i, szPathName, MAX_PATH);
 
 		SetDlgItemText(IDC_EDIT_RAWFILENAME, szPathName);
@@ -601,18 +601,18 @@
 
 	if(pRawInfo->m_nCommandIdxWrite != pRawInfo->m_nCommandIdxRead)
 	{
-		int nReadIdx = (pRawInfo->m_nCommandIdxRead+1)%COMMAND_MAXCOUNT; //현재는 읽은 마지막 포인트임으로 하나 증가시켜서 읽는다. [김태현 2018/11/13]
+		int nReadIdx = (pRawInfo->m_nCommandIdxRead+1)%COMMAND_MAXCOUNT; //占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙占쏙옙 占싹놂옙 占쏙옙占쏙옙占쏙옙占싼쇽옙 占싻는댐옙. [占쏙옙占쏙옙占쏙옙 2018/11/13]
 		_grmDitCommand::_grmCommand* pCommand = &pRawInfo->m_nCommandBuffer[nReadIdx];
 		AKLOG("Recv Command ID:%d(r%d/w%d)", pCommand->nCommand, nReadIdx, pRawInfo->m_nCommandIdxWrite);
 		pRawInfo->m_nCommandIdxRead = nReadIdx;
 
-		if(pCommand->nResult == -1) //명령 수행 전 [김태현 2018/11/13]
+		if(pCommand->nResult == -1) //占쏙옙占� 占쏙옙占쏙옙 占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/13]
 		{
 			pCommand->nResult = ProcessCommand( (emGlassRawCommand)pCommand->nCommand, pCommand->strParam );
 		}
 		else
 		{
-			//이미 처리 된거 [김태현 2018/11/13]
+			//占싱뱄옙 처占쏙옙 占싫곤옙 [占쏙옙占쏙옙占쏙옙 2018/11/13]
 		}
 
 		AKLOG("Recv Command ID:%d(r%d/w%d) Process End(Result:%d)", pCommand->nCommand, nReadIdx, pRawInfo->m_nCommandIdxWrite, pCommand->nResult);
@@ -658,7 +658,7 @@
 		{
 			nResult = m_pGlassRawMaker->SequenceInspectEnd(pRawDataBuffer);
 			pServer->GetGlassRawInfo()->m_ServerProcStep = APS_InspectEnd;
-			//Stack 정보를 공유메모리에 반영 하기 위한 Export
+			//Stack 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쌨모리울옙 占쌥울옙 占싹깍옙 占쏙옙占쏙옙 Export
 			//pRawDataBuffer->ExportGlassRaw(pServer->GetGlassRawInfo(), (char*)pServer->GetGlassData());
 			break;
 		}
@@ -677,7 +677,7 @@
 	case grcSequenceCustomReviewDataRead:
 		{
 			nResult = m_pGlassRawMaker->SequenceCustomizeReview(pRawDataBuffer);
-			////Customize Review를 위한 업데이트
+			////Customize Review占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙트
 			//{
 			//	memcpy(pServer->GetDefectData(0), pRawDataBuffer->GetDefectData(0), sizeof(_grmDefectData)*pServer->GetGlassRawInfo()->m_nDefectMaxDataNum);
 			//	memcpy(pServer->GetCellData(0), pRawDataBuffer->GetCellData(0), sizeof(_grmCellData)*pServer->GetGlassRawInfo()->m_nCellMaxDataNum);
@@ -707,6 +707,12 @@
 			nResult = m_pGlassRawMaker->ReadBinFile(pRawDataBuffer);
 			break;
 		}
+	case grcReviewWriteBIn:
+		{
+			nResult = m_pGlassRawMaker->ReviewWriteBin(pRawDataBuffer);
+			break;
+		}
+ 
 	}
 	
 	PostMessage(UM_GLASSRAW_CLIENTMESSAGE, nCmd);
@@ -771,14 +777,14 @@
 	
 	if(m_pGlassRawMaker) delete m_pGlassRawMaker;
 	
-	if(m_TrayIcon) // 현재 트레이 아이콘으로 설정되었는지 확인
+	if(m_TrayIcon) // 占쏙옙占쏙옙 트占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占실억옙占쏙옙占쏙옙 확占쏙옙
 	{
 		NOTIFYICONDATA nid;
 		nid.cbSize = sizeof(nid);
-		nid.hWnd = m_hWnd; // 메인 윈도우 핸들
+		nid.hWnd = m_hWnd; // 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쌘듸옙
 		nid.uID = IDR_MAINFRAME;
 
-		// 작업 표시줄(TaskBar)의 상태 영역에 아이콘을 삭제한다.
+		// 占쌜억옙 표占쏙옙占쏙옙(TaskBar)占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싼댐옙.
 		Shell_NotifyIcon(NIM_DELETE, &nid);
 	}
 
@@ -936,7 +942,7 @@
 
 BOOL CDitGlassRawMessengerDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
 {
-	// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
+	// TODO: 占쏙옙占썩에 특占쏙옙화占쏙옙 占쌘드를 占쌩곤옙 占쏙옙/占실댐옙 占썩본 클占쏙옙占쏙옙占쏙옙 호占쏙옙占쌌니댐옙.
 	if (m_gridCellInfo.GetSafeHwnd() && wParam == (WPARAM)m_gridCellInfo.GetDlgCtrlID())
 	{
 		*pResult = 1;
@@ -1258,7 +1264,7 @@
 					CString		str;
 					strItem = _T("          ");
 
-					// Panel x축, y축은 글라스와 반대 [6/9/2017 bhs]
+					// Panel x占쏙옙, y占쏙옙占쏙옙 占쌜라스울옙 占쌥댐옙 [6/9/2017 bhs]
 					if(1)//g_pBasic->GetScanCoordination() == SC_XCoord)
 						str.Format("% 5.3f", (double)pDefect->m_nUMCellX / 1000.0);
 					else
@@ -1281,7 +1287,7 @@
 					CString		str;
 					strItem = _T("          ");
 
-					// Panel x축, y축은 글라스와 반대 [6/9/2017 bhs]
+					// Panel x占쏙옙, y占쏙옙占쏙옙 占쌜라스울옙 占쌥댐옙 [6/9/2017 bhs]
 					if(1)//g_pBasic->GetScanCoordination() == SC_XCoord)
 						str.Format("% 5.3f", (double)pDefect->m_nUMCellY / 1000.0);
 					else
@@ -1433,7 +1439,7 @@
 
 void CDitGlassRawMessengerDlg::OnBnClickedBtnImportRaw()
 {
-	AKLOG("이기능은 가급적 필요가 있겠나.. 싶으네...");
+	AKLOG("占싱깍옙占쏙옙占� 占쏙옙占쏙옙占쏙옙 占십요가 占쌍겠놂옙.. 占쏙옙占쏙옙占쏙옙...");
 	PostMessage(UM_GLASSRAW_CLIENTMESSAGE);
 }
 
@@ -1568,13 +1574,13 @@
 
 	
 	
-		CString str = _T("All(*.*)|*.*|");	// 선택할 파일 종류
+		CString str = _T("All(*.*)|*.*|");	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 		CString File;
 		CString strFileList; 
 
 		CFileDialog dlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT, str, this);
 
-		const int c_cMaxFiles = 400 /*선택할 파일 숫자*/ ;	// 메모리 부족현상으로 확장 안해주면 몇개 못씀
+		const int c_cMaxFiles = 400 /*占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙*/ ;	// 占쌨몌옙 占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙 확占쏙옙 占쏙옙占쏙옙占쌍몌옙 占쏘개 占쏙옙占쏙옙
 		const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;
 		dlg.GetOFN().lpstrFile = strFileList.GetBuffer(c_cbBuffSize);
 		dlg.GetOFN().nMaxFile = c_cbBuffSize;
@@ -1585,7 +1591,7 @@
 		{
 			for(POSITION pos=dlg.GetStartPosition(); pos != NULL;)
 			{
-				// 전체삭제는 ResetContent
+				// 占쏙옙체占쏙옙占쏙옙占쏙옙 ResetContent
 				File = dlg.GetNextPathName(pos);
 
 
diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp
index 2b2092c..b8c7ebe 100644
--- a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp
+++ b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.cpp
@@ -98,3 +98,34 @@
 
 	return TRUE;
 }
+
+BOOL CGlassRawBase::ReviewWriteBin(CgrmGlassRawData* pData)
+{
+	CString strFileName;
+	strFileName.Format("D:\\DIT_ResultData\\RawBin\\%s", pData->GetGlassData()->m_strFileName);
+	FILE* pf = fopen(strFileName.GetBuffer(0), "wb");
+	if (pf)
+	{
+		fwrite(pData->GetMemInfo(), sizeof(_grmDitMemInfo), 1, pf);
+
+		fwrite(pData->GetGlassData(), pData->GetMemInfo()->m_nSizeOfGlassData, sizeof(char), pf);
+
+		for (int i = 0; i < pData->GetGlassData()->m_nCellNum; i++)
+		{
+			fwrite(pData->GetCellData(i), pData->GetMemInfo()->m_nSizeOfCellData, sizeof(char), pf);
+		}
+
+		for (int i = 0; i < pData->GetGlassData()->m_nDefectNum; i++)
+		{
+			fwrite(pData->GetDefectData(i), pData->GetMemInfo()->m_nSizeOfDefectData, sizeof(char), pf);
+		}
+
+		fclose(pf);
+	}
+	else
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
\ No newline at end of file
diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.h b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.h
index 68c99c0..2f46477 100644
--- a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.h
+++ b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawBase.h
@@ -3,13 +3,13 @@
 #include "DitGlassRawStruct.h"
 
 //////////////////////////////////////////////////////////////////////////
-// Recipe에서 Server와 Inspector가 공유하는 설정정보.
+// Recipe占쏙옙占쏙옙 Server占쏙옙 Inspector占쏙옙 占쏙옙占쏙옙占싹댐옙 占쏙옙占쏙옙占쏙옙占쏙옙.
 enum ThreadCount { Thread_1 = 0, Thread_2, Thread_4, Thread_6, Thread_8, Thread_11, Thread_12, Thread_22, Thread_24 };
 enum CameraType { CamType_Unknown = 0, CamType_Transfer, CamType_Reflex };
-enum ScanCoordinate { SC_XCoord = 0, SC_YCoord };					// 스캔방향. 결함 좌표 연산시 중요.
-enum ScanDirectionEng { SD_Right2Left = 0, SD_Left2Right };			// 작업자가 본 스캔 방향.
-enum ScanDirectionIns { SD_Forward = 0, SD_Backward, SD_Unknown };	// Glass 기준 Scan 방향.
-enum ScanType { ST_SingleScan = 0, ST_DualScan };				// SingleScan - 단방향, DualScan - 양방향
+enum ScanCoordinate { SC_XCoord = 0, SC_YCoord };					// 占쏙옙캔占쏙옙占쏙옙. 占쏙옙占쏙옙 占쏙옙표 占쏙옙占쏙옙占� 占쌩울옙.
+enum ScanDirectionEng { SD_Right2Left = 0, SD_Left2Right };			// 占쌜억옙占쌘곤옙 占쏙옙 占쏙옙캔 占쏙옙占쏙옙.
+enum ScanDirectionIns { SD_Forward = 0, SD_Backward, SD_Unknown };	// Glass 占쏙옙占쏙옙 Scan 占쏙옙占쏙옙.
+enum ScanType { ST_SingleScan = 0, ST_DualScan };				// SingleScan - 占쌤뱄옙占쏙옙, DualScan - 占쏙옙占쏙옙占�
 enum GlassDirection { GD_LeftTop = 0, GD_RightTop = 1, GD_LeftBottom = 10, GD_RightBottom = 11 };
 enum AcqMode { Acq_Unknown = 0, Acq_Grab, Acq_Snap, Acq_Matrox, Acq_Simul };
 enum FindBoundary { FB_NotFind = 0, FB_PitchMatching, FB_ManualMatching };
@@ -20,7 +20,7 @@
 enum DefectFiltering { Filtering_NO = 0, Filtering_CO, Filtering_Cutoff, Filtering_DXDY, Filtering_TD, Filtering_FALSE };		// Filtering_CO : Cosmic Ray FALSE
 enum ALIGN_MARK_CLASSIFY { eAMC_First = 0, eAMC_Second };
 //////////////////////////////////////////////////////////////////////////
-// Defect에 사용되는 타입들.
+// Defect占쏙옙 占쏙옙占실댐옙 타占쌉듸옙.
 enum SERVER_DefectType { DefectType_TBlack = 0, DefectType_TWhite, DefectType_RBlack, DefectType_RWhite, DefectType_BBlack, DefectType_BWhite, DefectType_Unknown };
 enum SERVER_DefectSizeType { SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
 enum SERVER_DefectJudgementType { JudgementType_OK = 0, JudgementType_TR, JudgementType_PR, JudgementType_UNKNOWN };
@@ -34,7 +34,7 @@
 enum ReKind { Re_Other, Re_TFE_CIRCLE, Re_PI_CONVEX, Re_PI_CONCAVE, Re_PI_1, Re_PI_2, Re_PI_3 };
 
 //choigudal jude fix 2012.03.07
-enum Judgement { Judge_OK = 0, Judge_RP, Judge_NG, Judge_TR, Judge_PR, Judge_PT, Judge_Review, Judge_RC, Judge_Size, Judge_VI, Judge_Rework, Judge_Unknown };//2016.07.13 LHS Judge_Size 추가
+enum Judgement { Judge_OK = 0, Judge_RP, Judge_NG, Judge_TR, Judge_PR, Judge_PT, Judge_Review, Judge_RC, Judge_Size, Judge_VI, Judge_Rework, Judge_Unknown };//2016.07.13 LHS Judge_Size 占쌩곤옙
 enum MAP16_DefectClass { CLASS_C1 = 1, CLASS_C2, CLASS_C3, CLASS_C4, CLASS_C5, CLASS_C6, CLASS_C7, CLASS_C8, CLASS_C9, CLASS_C10, CLASS_C11, CLASS_C12, CLASS_C13, CLASS_C14, CLASS_C15, CLASS_C16 };
 enum MAP16_SizeType { SIZE_SS = 0, SIZE_SM, SIZE_SL, SIZE_SOH, SIZE_IDX_MAX };
 enum MAP16_PeakType { PEEK_PS = 0, PEEK_PL, PEEK_PH, PEEK_POH, PEAK_IDX_MAX };
@@ -61,6 +61,8 @@
 	virtual BOOL WriteBinFile(CgrmGlassRawData* pData);
 	virtual BOOL ReadBinFile(CgrmGlassRawData* pData);
 
+	virtual BOOL ReviewWriteBin(CgrmGlassRawData* pData);
+
 	virtual BOOL WriteAOIFile(CgrmGlassRawData* pData){return TRUE;};
 	virtual BOOL ReadAOIFile(CgrmGlassRawData* pData){return TRUE;};
 
diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp
index f165cb9..4b6b6bb 100644
--- a/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp
+++ b/DitGlassRawMessenger/DitGlassRawMessenger/GlassRawCPJT.cpp
@@ -437,11 +437,11 @@
 	
 	strValue = "ITEM PANEL MODULETYPE MODULEID PROCESSID PRODUCTID STEPID PROD_TYPE BATCHID H_PANELID E_PANELID P_PANELID OPERID COMP_COUNT PPID GRADE CODE R_GRADE MAP_IMAGE L_TIME U_TIME S_TIME E_TIME T_DEFECT TR PR TB TW RB RW T_STACK MAX_AVG_GRAY MAX_PORTION OK_CELL RJ_CELL RW_CELL NR_CELL CSTID SLOT_NO JOB_END TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT BR_DEFECT IMG_COUNT RECIPE SHRINK RAW_CUT"; //53ea
 	strLine += strValue; strLine += "\n";
-	strValue = "ITEM SUBPANEL SUBPANELID COORD_X COORD_Y SIZE_X SIZE_Y GATELINE DATALINE GRADE CODE R_GRADE T_DEFECT TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT PRO_IMAGE AVG_GRAY_0 PORTION_0 AVG_GRAY_1 PORTION_1 AVG_GRAY_2 PORTION_2 AVG_GRAY_3 PORTION_3"; //30ea 21-05-12 Mura Data 異붽�
+	strValue = "ITEM SUBPANEL SUBPANELID COORD_X COORD_Y SIZE_X SIZE_Y GATELINE DATALINE GRADE CODE R_GRADE T_DEFECT TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT PRO_IMAGE AVG_GRAY_0 PORTION_0 CORNER_GRAY_0 AVG_AMP_0 FFT_VAR_0 FFT_VAH_0 FFT_VAQ_0 FFT_PK_0 AVG_GRAY_1 PORTION_1 CORNER_GRAY_1 AVG_AMP_1 FFT_VAR_1 FFT_VAH_1 FFT_VAQ_1 FFT_PK_1 AVG_GRAY_2 PORTION_2 CORNER_GRAY_2 AVG_AMP_2 FFT_VAR_2 FFT_VAH_2 FFT_VAQ_2 FFT_PK_2 AVG_GRAY_3 PORTION_3 CORNER_GRAY_3 AVG_AMP_3 FFT_VAR_3 FFT_VAH_3 FFT_VAQ_3 FFT_PK_3"; //54ea 21-06-21 Mura Data 異붽�
 	strLine += strValue; strLine += "\n";
 	//210405
 	//ITEM DEFECT ID DEF_NO COORD_X COORD_Y GATELINE DATALINE SIZE_S SIZE_W SIZE_L SIZE_H GRADE CODE STACK_FLAG STACK_COUNT STACK_STEP IMAGE_FILE DSC_CODE VC_CODE DCR_CODE DEFECT_SIZE REPEAT_DEFECT WSI_HEIGHT CS_HEIGHT C_GRADE GRAY_MIN GRAY_MAX GRAY_AVG GRAY_DEF WSI_IMAGE USE_CCDIMAGE SCAN_NUM CAM_POSITION CCD_NO R_GRAY_MIN R_GRAY_MAX R_GRAY_AVG SCAN_AI REVIEW_AI INS_MODE INS_CHANNEL COMPACTNESS THICKNESS MAJOR MINOR WSI_TYPE DEFECT_TYPE SHRINK
-	strValue = "ITEM DEFECT ID DEF_NO COORD_X COORD_Y GATELINE DATALINE SIZE_S SIZE_W SIZE_L SIZE_H GRADE CODE STACK_FLAG STACK_COUNT STACK_STEP IMAGE_FILE DSC_CODE VC_CODE DCR_CODE DEFECT_SIZE REPEAT_DEFECT WSI_HEIGHT CS_HEIGHT C_GRADE GRAY_MIN GRAY_MAX GRAY_AVG GRAY_DEF WSI_IMAGE USE_CCDIMAGE SCAN_NUM CAM_POSITION CCD_NO R_GRAY_MIN R_GRAY_MAX R_GRAY_AVG R_HEIGHT G_HEIGHT B_HEIGHT INS_CHANNEL COMPACTNESS THICKNESS MAJOR MINOR WSI_TYPE DEFECT_TYPE SHRINK"; //49ea    
+	strValue = "ITEM DEFECT ID DEF_NO COORD_X COORD_Y GATELINE DATALINE SIZE_S SIZE_W SIZE_L SIZE_H GRADE CODE STACK_FLAG STACK_COUNT STACK_STEP IMAGE_FILE DSC_CODE VC_CODE DCR_CODE DEFECT_SIZE REPEAT_DEFECT WSI_HEIGHT CS_HEIGHT C_GRADE GRAY_MIN GRAY_MAX GRAY_AVG GRAY_DEF WSI_IMAGE USE_CCDIMAGE SCAN_NUM CAM_POSITION CCD_NO R_GRAY_MIN R_GRAY_MAX R_GRAY_AVG R_HEIGHT G_HEIGHT B_HEIGHT INS_CHANNEL COMPACTNESS THICKNESS MAJOR MINOR WSI_TYPE DEFECT_TYPE SHRINK CLASS_CODE"; //50ea    
 	strLine += strValue;
 
 }
@@ -931,8 +931,69 @@
 	{
 		SPRINTRAW(12, "*");
 	}
+	
+	//kyh 0622
+	// 25 12 CORNER_GRAY_0
+	if (strlen(pCellData->m_strCorner_Gray_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
 
-	// 25 12  AVG_GRAY_1
+	// 26 12 AVG_AMP_0
+	if (strlen(pCellData->m_strAvgAmp_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 27 12 FFT_VAR_0
+	if (strlen(pCellData->m_strFFTVar_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 28 12 FFT_VAH_0
+	if (strlen(pCellData->m_strFFTVah_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 29 12 FFT_VAQ_0
+	if (strlen(pCellData->m_strFFTVaq_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 30 12 FFT_PK_0
+	if (strlen(pCellData->m_strFFTPK_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 31 12  AVG_GRAY_1
 	if (strlen(pCellData->m_strAvgGray_1))
 	{
 		SPRINTRAW(12, "%s", pCellData->m_strAvgGray_1);
@@ -941,7 +1002,7 @@
 	{
 		SPRINTRAW(12, "*");
 	}
-	// 26 12 PORTION_1
+	// 32 12 PORTION_1
 	if (strlen(pCellData->m_strPortion_1))
 	{
 		SPRINTRAW(12, "%s", pCellData->m_strPortion_1);
@@ -950,7 +1011,69 @@
 	{
 		SPRINTRAW(12, "*");
 	}
-	// 27 12  AVG_GRAY_2
+
+	//kyh 0622
+	// 33 12 CORNER_GRAY_1
+	if (strlen(pCellData->m_strCorner_Gray_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 34 12 AVG_AMP_1
+	if (strlen(pCellData->m_strAvgAmp_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 35 12 FFT_VAR_1
+	if (strlen(pCellData->m_strFFTVar_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 36 12 FFT_VAH_1
+	if (strlen(pCellData->m_strFFTVah_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 37 12 FFT_VAQ_1
+	if (strlen(pCellData->m_strFFTVaq_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 38 12 FFT_PK_1
+	if (strlen(pCellData->m_strFFTPK_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 39 12  AVG_GRAY_2
 	if (strlen(pCellData->m_strAvgGray_2))
 	{
 		SPRINTRAW(12, "%s", pCellData->m_strAvgGray_2);
@@ -959,7 +1082,7 @@
 	{
 		SPRINTRAW(12, "*");
 	}
-	// 28 12 PORTION_2
+	// 40 12 PORTION_2
 	if (strlen(pCellData->m_strPortion_2))
 	{
 		SPRINTRAW(12, "%s", pCellData->m_strPortion_2);
@@ -968,7 +1091,69 @@
 	{
 		SPRINTRAW(12, "*");
 	}
-	// 29 12  AVG_GRAY_3
+
+	//kyh 0622
+	// 41 12 CORNER_GRAY_2
+	if (strlen(pCellData->m_strCorner_Gray_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 42 12 AVG_AMP_2
+	if (strlen(pCellData->m_strAvgAmp_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 43 12 FFT_VAR_2
+	if (strlen(pCellData->m_strFFTVar_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 44 12 FFT_VAH_2
+	if (strlen(pCellData->m_strFFTVah_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 45 12 FFT_VAQ_2
+	if (strlen(pCellData->m_strFFTVaq_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 46 12 FFT_PK_2
+	if (strlen(pCellData->m_strFFTPK_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 47 12  AVG_GRAY_3
 	if (strlen(pCellData->m_strAvgGray_3))
 	{
 		SPRINTRAW(12, "%s", pCellData->m_strAvgGray_3);
@@ -977,10 +1162,71 @@
 	{
 		SPRINTRAW(12, "*");
 	}
-	// 30 12 PORTION_3
+	// 48 12 PORTION_3
 	if (strlen(pCellData->m_strPortion_3))
 	{
 		SPRINTRAW(12, "%s", pCellData->m_strPortion_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	//kyh 0622
+	// 49 12 CORNER_GRAY_3
+	if (strlen(pCellData->m_strCorner_Gray_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 50 12 AVG_AMP_3
+	if (strlen(pCellData->m_strAvgAmp_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 51 12 FFT_VAR_3
+	if (strlen(pCellData->m_strFFTVar_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 52 12 FFT_VAH_3
+	if (strlen(pCellData->m_strFFTVah_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 53 12 FFT_VAQ_3
+	if (strlen(pCellData->m_strFFTVaq_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 54 12 FFT_PK_3
+	if (strlen(pCellData->m_strFFTPK_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_3);
 	}
 	else
 	{
@@ -1170,6 +1416,7 @@
 			nValue = nValue << 1;
 	}
 	SPRINTRAW(12, "%04X", nValue);
+
 	// 22   12    DEFECT_SIZE	// Common 04 遺덈웾 �겕湲� (L,H,M,S)
 	if (pDefectData->m_DefectSizeType == SizeType_Small)
 	{
@@ -1389,6 +1636,17 @@
 	// 49	12	 Frame Shrink �젙蹂� 異붽�
 	SPRINTRAW(12, "%d", pDefectData->m_bShrinked);
 	
+	// 50   12    CLASS_NO		// Zone Classification NO
+	// Zone Data
+	nValue = 0;
+	for (int i = 15; i >= 0; i--)
+	{
+		if (pDefectData->m_sZoneClassPixelCount[i] > 0)
+			nValue += 1;
+		if (i > 0)
+			nValue = nValue << 1;
+	}
+	SPRINTRAW(12, "%04X", nValue);
 
 	SPRINTRAWEND;   //以묒슂!!! �젮 留덉�留됱뿉 瑗� �엳�뼱�빞�븿!!!(�궘�젣湲덉�) [源��깭�쁽2020/9/23]
 
diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp
index 3423e3d..a7caac2 100644
--- a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp
+++ b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.cpp
@@ -254,16 +254,47 @@
 			if (strlen(buffer) <= 0) continue;
 			paser.process(buffer, " ");
 			int nTokNum = paser.getTokNum();
-			if (nTokNum < 31) continue;
+			if (nTokNum < 52) continue; //kyh 31->52
 			MacroSubPanel.PRO_IMAGE = paser.getTokStr(20);
 			MacroSubPanel.AVG_GRAY_0 = paser.getTokStr(21);
 			MacroSubPanel.PORTION_0 = paser.getTokStr(22);
-			MacroSubPanel.AVG_GRAY_1 = paser.getTokStr(24);
-			MacroSubPanel.PORTION_1 = paser.getTokStr(25);
-			MacroSubPanel.AVG_GRAY_2 = paser.getTokStr(27);
-			MacroSubPanel.PORTION_2 = paser.getTokStr(28);
-			MacroSubPanel.AVG_GRAY_3 = paser.getTokStr(30);
-			MacroSubPanel.PORTION_3 = paser.getTokStr(31);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_0 = paser.getTokStr(23);
+			MacroSubPanel.AVG_AMP_0 = paser.getTokStr(24);
+			MacroSubPanel.FFT_VAR_0 = paser.getTokStr(25);
+			MacroSubPanel.FFT_VAH_0 = paser.getTokStr(26);
+			MacroSubPanel.FFT_VAQ_0 = paser.getTokStr(27);
+			MacroSubPanel.FFT_PK_0 = paser.getTokStr(28);
+
+			MacroSubPanel.AVG_GRAY_1 = paser.getTokStr(29);
+			MacroSubPanel.PORTION_1 = paser.getTokStr(30);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_1 = paser.getTokStr(31);
+			MacroSubPanel.AVG_AMP_1 = paser.getTokStr(32);
+			MacroSubPanel.FFT_VAR_1 = paser.getTokStr(33);
+			MacroSubPanel.FFT_VAH_1 = paser.getTokStr(34);
+			MacroSubPanel.FFT_VAQ_1 = paser.getTokStr(35);
+			MacroSubPanel.FFT_PK_1 = paser.getTokStr(36);
+
+			MacroSubPanel.AVG_GRAY_2 = paser.getTokStr(37);
+			MacroSubPanel.PORTION_2 = paser.getTokStr(38);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_2 = paser.getTokStr(39);
+			MacroSubPanel.AVG_AMP_2 = paser.getTokStr(40);
+			MacroSubPanel.FFT_VAR_2 = paser.getTokStr(41);
+			MacroSubPanel.FFT_VAH_2 = paser.getTokStr(42);
+			MacroSubPanel.FFT_VAQ_2 = paser.getTokStr(43);
+			MacroSubPanel.FFT_PK_2 = paser.getTokStr(44);
+
+			MacroSubPanel.AVG_GRAY_3 = paser.getTokStr(45);
+			MacroSubPanel.PORTION_3 = paser.getTokStr(46);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_3 = paser.getTokStr(47);
+			MacroSubPanel.AVG_AMP_3 = paser.getTokStr(48);
+			MacroSubPanel.FFT_VAR_3 = paser.getTokStr(49);
+			MacroSubPanel.FFT_VAH_3 = paser.getTokStr(50);
+			MacroSubPanel.FFT_VAQ_3 = paser.getTokStr(51);
+			MacroSubPanel.FFT_PK_3 = paser.getTokStr(52);
 
 			vecMacroSubPanel.push_back(MacroSubPanel);
 		}
@@ -280,12 +311,43 @@
 		strcpy(pGrmMura->m_strProImage, m_vecMacroSubPanel[i].PRO_IMAGE.GetBuffer(0));
 		strcpy(pGrmMura->m_strAvgGray_0, m_vecMacroSubPanel[i].AVG_GRAY_0.GetBuffer(0));
 		strcpy(pGrmMura->m_strPortion_0, m_vecMacroSubPanel[i].PORTION_0.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_0, m_vecMacroSubPanel[i].CORNER_GRAY_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_0, m_vecMacroSubPanel[i].AVG_AMP_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_0, m_vecMacroSubPanel[i].FFT_VAR_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_0, m_vecMacroSubPanel[i].FFT_VAH_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_0, m_vecMacroSubPanel[i].FFT_VAQ_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_0, m_vecMacroSubPanel[i].FFT_PK_0.GetBuffer(0));
+
 		strcpy(pGrmMura->m_strAvgGray_1, m_vecMacroSubPanel[i].AVG_GRAY_1.GetBuffer(0));
 		strcpy(pGrmMura->m_strPortion_1, m_vecMacroSubPanel[i].PORTION_1.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_1, m_vecMacroSubPanel[i].CORNER_GRAY_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_1, m_vecMacroSubPanel[i].AVG_AMP_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_1, m_vecMacroSubPanel[i].FFT_VAR_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_1, m_vecMacroSubPanel[i].FFT_VAH_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_1, m_vecMacroSubPanel[i].FFT_VAQ_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_1, m_vecMacroSubPanel[i].FFT_PK_1.GetBuffer(0));
+
 		strcpy(pGrmMura->m_strAvgGray_2, m_vecMacroSubPanel[i].AVG_GRAY_2.GetBuffer(0));
 		strcpy(pGrmMura->m_strPortion_2, m_vecMacroSubPanel[i].PORTION_2.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_2, m_vecMacroSubPanel[i].CORNER_GRAY_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_2, m_vecMacroSubPanel[i].AVG_AMP_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_2, m_vecMacroSubPanel[i].FFT_VAR_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_2, m_vecMacroSubPanel[i].FFT_VAH_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_2, m_vecMacroSubPanel[i].FFT_VAQ_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_2, m_vecMacroSubPanel[i].FFT_PK_2.GetBuffer(0));
+
 		strcpy(pGrmMura->m_strAvgGray_3, m_vecMacroSubPanel[i].AVG_GRAY_3.GetBuffer(0));
 		strcpy(pGrmMura->m_strPortion_3, m_vecMacroSubPanel[i].PORTION_3.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_3, m_vecMacroSubPanel[i].CORNER_GRAY_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_3, m_vecMacroSubPanel[i].AVG_AMP_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_3, m_vecMacroSubPanel[i].FFT_VAR_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_3, m_vecMacroSubPanel[i].FFT_VAH_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_3, m_vecMacroSubPanel[i].FFT_VAQ_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_3, m_vecMacroSubPanel[i].FFT_PK_3.GetBuffer(0));
 	}
 	strcpy(pShared->GetGlassData()->m_strMaxAvgGray, strMaxAvgGray.GetBuffer(0));
 	strcpy(pShared->GetGlassData()->m_strMaxPortion, strMaxPortion.GetBuffer(0));
diff --git a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h
index fdd2ee2..f746014 100644
--- a/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h
+++ b/DitGlassRawMessenger/DitGlassRawMessenger/MacroResultFile.h
@@ -127,12 +127,36 @@
 	CString	PRO_IMAGE;
 	CString	AVG_GRAY_0;  // 0 Scan 0 Model
 	CString	PORTION_0;
+	CString CORNER_GRAY_0; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_0;
+	CString FFT_VAR_0;
+	CString FFT_VAH_0;
+	CString FFT_VAQ_0;
+	CString FFT_PK_0; // kyh end
 	CString	AVG_GRAY_1; // 0 Scan 1 Model
 	CString	PORTION_1;
+	CString CORNER_GRAY_1; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_1;
+	CString FFT_VAR_1;
+	CString FFT_VAH_1;
+	CString FFT_VAQ_1;
+	CString FFT_PK_1; // kyh end
 	CString	AVG_GRAY_2; // 1 Scan 0 Model
 	CString	PORTION_2;
+	CString CORNER_GRAY_2; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_2;
+	CString FFT_VAR_2;
+	CString FFT_VAH_2;
+	CString FFT_VAQ_2;
+	CString FFT_PK_2; // kyh end
 	CString	AVG_GRAY_3; // 1 Scan 1 Model
 	CString	PORTION_3;
+	CString CORNER_GRAY_3; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_3;
+	CString FFT_VAR_3;
+	CString FFT_VAH_3;
+	CString FFT_VAQ_3;
+	CString FFT_PK_3; // kyh end
 };
 
 class CMacroResultFile
diff --git a/DitGlassRawMessenger/Extern/DitGlassRawClient.cpp b/DitGlassRawMessenger/Extern/DitGlassRawClient.cpp
index d72362f..c37e6e5 100644
--- a/DitGlassRawMessenger/Extern/DitGlassRawClient.cpp
+++ b/DitGlassRawMessenger/Extern/DitGlassRawClient.cpp
@@ -119,6 +119,11 @@
 	return SetCommand(grcReadBin);
 }
 
+BOOL CDitGlassRawClient::WriteReviewRawBinFile()
+{
+	return SetCommand(grcReviewWriteBIn);
+}
+
 BOOL CDitGlassRawClient::SetCommand( emGlassRawCommand nCmd )
 {
 	if(m_pGlassRawInfo == NULL) return FALSE;
@@ -127,14 +132,14 @@
 
 	int nCmdId = (m_pGlassRawInfo->m_nCommandIdxWrite+1) % COMMAND_MAXCOUNT;
 
-	if(m_pGlassRawInfo->m_nCommandIdxRead == nCmdId)//둘이 같다는것은 서큘러 버퍼가 한바퀴 돌았다는것!! [김태현 2018/11/12]
+	if(m_pGlassRawInfo->m_nCommandIdxRead == nCmdId)//占쏙옙占쏙옙 占쏙옙占쌕는곤옙占쏙옙 占쏙옙큘占쏙옙 占쏙옙占쌜곤옙 占싼뱄옙占쏙옙 占쏙옙占쌀다는곤옙!! [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	{
-		m_pGlassRawInfo->m_nCommandIdxRead++;//가장 오래된 명령 하나를 삭제한다. [김태현 2018/11/12]
+		m_pGlassRawInfo->m_nCommandIdxRead++;//占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占� 占싹놂옙占쏙옙 占쏙옙占쏙옙占싼댐옙. [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	}
 
 	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nCommand = (short)nCmd;
 	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].strParam;
-	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nResult = -1; //-1수행전, 0실패, 1성공 [김태현 2018/11/13]
+	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nResult = -1; //-1占쏙옙占쏙옙占쏙옙, 0占쏙옙占쏙옙, 1占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/13]
 
 
 	m_nLastCommandIdx = m_pGlassRawInfo->m_nCommandIdxWrite = nCmdId;
@@ -195,7 +200,7 @@
 void CDitGlassRawClient::RemoveReviewDefects()
 {
 	int nDefectNum = m_pGlassData->m_nDefectNum;
-	int nRightDefectNum = 0;//기준점 오른쪽에 위치한 결함 갯수
+	int nRightDefectNum = 0;//占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占십울옙 占쏙옙치占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	int nDefectDeleteNum = 0;
 	for(int i=nDefectNum-1; i>=0; i--)
 	{
diff --git a/DitGlassRawMessenger/Extern/DitGlassRawClient.h b/DitGlassRawMessenger/Extern/DitGlassRawClient.h
index ca3b45b..82a185a 100644
--- a/DitGlassRawMessenger/Extern/DitGlassRawClient.h
+++ b/DitGlassRawMessenger/Extern/DitGlassRawClient.h
@@ -22,7 +22,7 @@
 
 	BOOL SetReviewComtomize();
 
-	void RemoveReviewDefects();//AOI에서 생성한 디펙 정보를 제외하고, 리뷰에서 생성한 User 혹은 Reflow 결함을 제외한다.
+	void RemoveReviewDefects();//AOI占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싹곤옙, 占쏙옙占썰에占쏙옙 占쏙옙占쏙옙占쏙옙 User 혹占쏙옙 Reflow 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싼댐옙.
 
 	_grmDitMemInfo*	GetGlassMeminfo(){return (_grmDitMemInfo*)m_pGlassRawInfo;};
 	_grmGlassData*	GetGlassData(){return m_pGlassData;};
@@ -31,15 +31,17 @@
 	_grmDefectData*	GetDefectData(int nIndex){return &m_pDefectData[nIndex];};
 	_grmDefectData*	GetStackData(int nIndex) { return &m_pStackData[nIndex];};
 
-	//결과 파일 강제 쓰기 명령 [김태현 2018/11/12]
+	//占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占� [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	BOOL WriteAOIRawFile();
 
-	//결과파일 강제 바이너리 형태로 쓰기 [김태현 2018/11/12]
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占싱너몌옙 占쏙옙占승뤄옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	BOOL WriteAOIRawBinFile(); 
 
-	//결과파일 강제 바이너리 읽기 
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占싱너몌옙 占싻깍옙 
 	BOOL ReadAOIRawBinFile();
 
+	BOOL WriteReviewRawBinFile();
+
 protected:
 	BOOL ConnectGlassRawInfo();
 	BOOL ConnectGlassRawData();
diff --git a/DitGlassRawMessenger/Extern/DitGlassRawStruct.h b/DitGlassRawMessenger/Extern/DitGlassRawStruct.h
index 600196e..e84fb29 100644
--- a/DitGlassRawMessenger/Extern/DitGlassRawStruct.h
+++ b/DitGlassRawMessenger/Extern/DitGlassRawStruct.h
@@ -47,7 +47,7 @@
 		memset(this, 0, sizeof(_grmGlassData));
 	}
 
-	//Glass 정보
+	//Glass 占쏙옙占쏙옙
 	char m_strFileName[64];
 	char m_strPath[256];
 
@@ -56,12 +56,12 @@
 
 	int m_nOriginDirection;				//{ GD_LeftTop = 0, GD_RightTop = 1, GD_LeftBottom = 10, GD_RightBottom = 11 };
 	int m_nConerCutDirection;
-	int	m_nScanCoordinateY;				//여기가 0이면 일반, 1이면 Scan방향이 y축(즉 scan방향이 단축, offline 설비 같은)
+	int	m_nScanCoordinateY;				//占쏙옙占썩가 0占싱몌옙 占싹뱄옙, 1占싱몌옙 Scan占쏙옙占쏙옙占쏙옙 y占쏙옙(占쏙옙 scan占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙, offline 占쏙옙占쏙옙 占쏙옙占쏙옙)
 
 	int m_nGlassSizeWidth;
 	int m_nGlassSizeHeight;
 
-	//설비정보
+	//占쏙옙占쏙옙占쏙옙占쏙옙
 	char m_strLine[32];
 	char m_strEquipType[32];			
 	char m_strEquipID[32];				
@@ -74,7 +74,7 @@
 	CTime	m_tmReviewLoading;
 	CTime	m_tmReviewEnd;
 
-	//기본 물류정보
+	//占썩본 占쏙옙占쏙옙占쏙옙占쏙옙
 	char m_strGlassID[32];				//Glass ID
 	char m_strPPID[32];					
 	char m_strEPPID[32];				
@@ -91,7 +91,7 @@
 	char m_strVCRGlassID[32];
 
 
-	//결함 갯수 관리 변수
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	int			m_nDefectNumSizeSmall;
 	int			m_nDefectNumSizeMid;
 	int			m_nDefectNumSizeLarge;
@@ -126,14 +126,14 @@
 	int			m_nDefectNumStackSP;
 
 
-	//카메라/스캔 정보 [김태현 2018/12/5]
+	//카占쌨띰옙/占쏙옙캔 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
 	short		m_nCameraNum;
 	short		m_nScanNum;
 	unsigned char m_nGrayLevelAvg[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];		
 	unsigned char m_nGrayLevelMin[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];
 	unsigned char m_nGrayLevelMax[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];
 
-	//얼라인 정보 um[김태현 2018/12/10]
+	//占쏙옙占쏙옙占� 占쏙옙占쏙옙 um[占쏙옙占쏙옙占쏙옙 2018/12/10]
 	double	m_nAlignCcdTheta;
 	double	m_nAlignCcdShitftX;
 	double	m_nAlignCcdShitftY;
@@ -143,8 +143,11 @@
 	double	m_nAlignBasicTheta;
 	double	m_nAlignBasicShitftX;
 	double	m_nAlignBasicShitftY;
+	char	m_strAlignFirst[64];
+	char	m_strAlignSecond[64];
+// 	char	m_strAlignPath[256];
 
-	//CSOT용 물류 정보 [김태현 2018/12/5]
+	//CSOT占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
 	char m_strCassetteSequenceNo[16];
 	char m_strOwnerCode[16];			//2. OWNER_CODE
 	char m_strOwnerType[16];			//3. OWNER_TYPE
@@ -159,7 +162,7 @@
 	char m_strGroupID[16];				//14.GROUP_ID
 	char m_cAutoSampleFlag;				//15.AUTOSAMPLEFLAG
 
-	// CPRJ용 물류 정보
+	// CPRJ占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	char m_strProdType[3];
 	char m_strBatchID[13];
 	char m_strPairHPanelID[13];
@@ -185,17 +188,17 @@
 	BYTE m_nGlassDataBitSignal[4];
 	bool m_bJob_end;  
 
-	//201217 CJH - 찍은 Defect Review 개수
+	//201217 CJH - 占쏙옙占쏙옙 Defect Review 占쏙옙占쏙옙
 	int m_nReviewNum;
-	//201221 CJH - 파싱한 Stack 결과
+	//201221 CJH - 占식쏙옙占쏙옙 Stack 占쏙옙占�
 	int m_nStackNum;
 	BOOL m_bStackRead;
 
-	//210203 CJH - CutOff 대상 결함 수
+	//210203 CJH - CutOff 占쏙옙占� 占쏙옙占쏙옙 占쏙옙
 	int m_nCutOffDefectNum;
-	//210323 CJH - Server/Frame Shrink 정보 추가
+	//210323 CJH - Server/Frame Shrink 占쏙옙占쏙옙 占쌩곤옙
 	char m_strShrinked[6];
-	//210326 CJH - RAW 입력 Defect 수량 상한 사용여부
+	//210326 CJH - RAW 占쌉뤄옙 Defect 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙肉⑼옙占�
 	BOOL m_bRawCutoff;
 
 };
@@ -219,7 +222,7 @@
 	}
 	int getTotalDefectNum(){return m_nDefectNumTypeTB+m_nDefectNumTypeTW+m_nDefectNumTypeRB+m_nDefectNumTypeRW; };
 	int						m_nCellID;							//1. PANEL_ID
-	short					m_nModelIdx;				// 몇 번째 모델인가?
+	short					m_nModelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占싸곤옙?
 
 	char					m_strCellName[32];
 	int						m_rectCellLeft;
@@ -232,7 +235,7 @@
 	int						m_nJudgeGlade;
 
 
-	//결함 갯수 관리 변수
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	int			m_nDefectNumSizeSmall;
 	int			m_nDefectNumSizeMid;
 	int			m_nDefectNumSizeLarge;
@@ -256,12 +259,43 @@
 	char		m_strProImage[32];
 	char		m_strAvgGray_0[12];
 	char		m_strPortion_0[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_0[12];
+	char		m_strAvgAmp_0[12];
+	char		m_strFFTVar_0[12];
+	char		m_strFFTVah_0[12];
+	char		m_strFFTVaq_0[12];
+	char		m_strFFTPK_0[12];
+
 	char		m_strAvgGray_1[12];
 	char		m_strPortion_1[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_1[12];
+	char		m_strAvgAmp_1[12];
+	char		m_strFFTVar_1[12];
+	char		m_strFFTVah_1[12];
+	char		m_strFFTVaq_1[12];
+	char		m_strFFTPK_1[12];
+
 	char		m_strAvgGray_2[12];
 	char		m_strPortion_2[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_2[12];
+	char		m_strAvgAmp_2[12];
+	char		m_strFFTVar_2[12];
+	char		m_strFFTVah_2[12];
+	char		m_strFFTVaq_2[12];
+	char		m_strFFTPK_2[12];
+
 	char		m_strAvgGray_3[12];
 	char		m_strPortion_3[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_3[12];
+	char		m_strAvgAmp_3[12];
+	char		m_strFFTVar_3[12];
+	char		m_strFFTVah_3[12];
+	char		m_strFFTVaq_3[12];
+	char		m_strFFTPK_3[12];
 
 	int			m_nDefectNumJudgeOKWhite;
 	int			m_nDefectNumJudgeOKBlack;
@@ -274,17 +308,17 @@
 
 	int			m_nReflowResult[8];			// 0: Reflow X 1: Reflow OK 2: Reflow NG
 
-	// Filtering된 Stack별 수
+	// Filtering占쏙옙 Stack占쏙옙 占쏙옙
 	int			m_nDefectTDCount;
 	int			m_nDefectSDCount;
 	int			m_nDefectPDCount;
 	int			m_nDefectSPCount;
 
-	// Gate/Data 총 갯수
+	// Gate/Data 占쏙옙 占쏙옙占쏙옙
 	int			m_nGateNum;
 	int			m_nDataNum;
 
-	// 210129 CJH - Cell Origin 방향
+	// 210129 CJH - Cell Origin 占쏙옙占쏙옙
 	int			m_nCellXDir;
 	int			m_nCellYDir;
 };
@@ -297,26 +331,27 @@
 	}
 
 	//////////////////////////////////////////////////////////////////////////
-	//여기서 부터 리뷰 영역 [김태현 2019/1/19]
+	//占쏙옙占썩서 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/1/19]
 	ditRaw::ReviewPlanType			m_nPlanType	;	
 	int			m_nResultCode;  //0:None, 1:Success
-	int			m_nShotIndex; //리뷰 찍은 순번 [김태현 2018/12/5]
+	int			m_nShotIndex; //占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
 	int			m_nModuleIndex;
 	int			m_nMagnificIndex;
 	float		m_fManification;
 	float		m_fManificResoultion;
 	char		m_strRevImageName[256];
+	char		m_strRevImagePath[256];
 
 	//////////////////////////////////////////////////////////////////////////
-	// Measure 영역
+	// Measure 占쏙옙占쏙옙
 	int			m_nMeasure_Index;
 	int			m_nMeasure_ResultCode; //0:None, 1:Success
 	float		m_fMesure_ResultData[8];	// 0:Type, 1:ShiftX, 2:ShiftY
 
 	//////////////////////////////////////////////////////////////////////////
-	// WSI영역
+	// WSI占쏙옙占쏙옙
 	int			m_nWsi_ResultCode; //0:None, 1:Success
-	int			m_nWsi_Type;									// 함몰 / 돌기
+	int			m_nWsi_Type;									// 占쌉몌옙 / 占쏙옙占쏙옙
 	float		m_fWsi_ResultData[8];			// 0:Type, 1:Height(um), 2:Width
 	char		m_strWsi_2DImageFilename[256];
 	char		m_strWsi_3DImageFilename[256]; 
@@ -324,14 +359,14 @@
 	int			m_nWsi_pReflowResultData[8];
 	double		m_dWsi_DamDistance;
 
-	double		m_dWsiMmMotorX;								// WSI 모터 좌표 20180223 HJH
+	double		m_dWsiMmMotorX;								// WSI 占쏙옙占쏙옙 占쏙옙표 20180223 HJH
 	double		m_dWsiMmMotorY;
-	float		m_fWsiManification;							// WSI 배율
+	float		m_fWsiManification;							// WSI 占쏙옙占쏙옙
 
 	//////////////////////////////////////////////////////////////////////////
-	// Reflow 영역	
+	// Reflow 占쏙옙占쏙옙	
 	int			m_nReflow_Index;
-	int			m_nReflow_ResultCode; //0:None, // 검출한 Line의 개수. 3 미만 : DAM2 Reflow 판정, 4~5 : DAM1 Reflow 판정, 6 : no Reflow 판정 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
+	int			m_nReflow_ResultCode; //0:None, // 占쏙옙占쏙옙占쏙옙 Line占쏙옙 占쏙옙占쏙옙. 3 占싱몌옙 : DAM2 Reflow 占쏙옙占쏙옙, 4~5 : DAM1 Reflow 占쏙옙占쏙옙, 6 : no Reflow 占쏙옙占쏙옙 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
 	float		m_fReflow_LinePosData[8];	
 	int			m_nReflow_Side;
 	int			m_nReflow_InspectionMode;
@@ -347,107 +382,108 @@
 	short			m_nDefectID;
 	short			m_nCameraID;
 	short			m_nScanIdx;
-	//short			m_nDefectIdx;				// 카메라에서의 결함 인덱스
-	int				m_nDefectIdx;				// 카메라에서의 결함 인덱스 201207 CJH - 자릿 수 넘침. int형으로 변경
+	//short			m_nDefectIdx;				// 카占쌨라에쇽옙占쏙옙 占쏙옙占쏙옙 占싸듸옙占쏙옙
+	int				m_nDefectIdx;				// 카占쌨라에쇽옙占쏙옙 占쏙옙占쏙옙 占싸듸옙占쏙옙 201207 CJH - 占쌘몌옙 占쏙옙 占쏙옙침. int占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 
-	int				m_nPixelConv;				// pixel 단위 좌표
-	int				m_nPixelScan;				// pixel 단위 좌표
+	int				m_nPixelConv;				// pixel 占쏙옙占쏙옙 占쏙옙표
+	int				m_nPixelScan;				// pixel 占쏙옙占쏙옙 占쏙옙표
 
-	short							m_nPixelSize;				// 결함크기		---------------------------------PS
-	short/*SERVER_DefectType*/		m_DefectType;				// 결함 타입	---------------------------------DT
-	short/*SERVER_DefectSubType*/	m_DefectSubType;			// 결함의 판정상태.
-	short/*SERVER_DefectBDType*/	m_DefectBDType;				// 결함 타입 - Bright, Dark, Both
+	short							m_nPixelSize;				// 占쏙옙占쏙옙크占쏙옙		---------------------------------PS
+	short/*SERVER_DefectType*/		m_DefectType;				// 占쏙옙占쏙옙 타占쏙옙	---------------------------------DT
+	short/*SERVER_DefectSubType*/	m_DefectSubType;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+	short/*SERVER_DefectBDType*/	m_DefectBDType;				// 占쏙옙占쏙옙 타占쏙옙 - Bright, Dark, Both
 
-	short			m_sPixelWidth;				// 픽셀단위 결함 너비
-	short			m_sPixelHeight;				// 픽셀단위 결함 높이
-	short			m_nLevelSrcMin;				// 결함 밝기 Min	-----------------------------SN
-	short			m_nLevelSrcMax;				// 결함 밝기 Max	-----------------------------SX
-	short			m_nLevelSrcAvg;				// 결함 밝기 Avg	-----------------------------SA
-	short			m_nLevelRefMin;				// 비교대상 밝기 Min	-------------------------RN
-	short			m_nLevelRefMax;				// 비교대상 밝기 Max	-------------------------RX
-	short			m_nLevelRefAvg;				// 비교대상 밝기 Avg	-------------------------RA
-	short			m_nLevelDiffMin;			// 비교차 Min	---------------------------------DN
-	short			m_nLevelDiffMax;			// 비교차 Max	---------------------------------DX
-	short			m_nLevelDiffAvg;			// 비교차 Avg	---------------------------------DA
+	short			m_sPixelWidth;				// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占십븝옙
+	short			m_sPixelHeight;				// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	short			m_nLevelSrcMin;				// 占쏙옙占쏙옙 占쏙옙占� Min	-----------------------------SN
+	short			m_nLevelSrcMax;				// 占쏙옙占쏙옙 占쏙옙占� Max	-----------------------------SX
+	short			m_nLevelSrcAvg;				// 占쏙옙占쏙옙 占쏙옙占� Avg	-----------------------------SA
+	short			m_nLevelRefMin;				// 占쏟교댐옙占� 占쏙옙占� Min	-------------------------RN
+	short			m_nLevelRefMax;				// 占쏟교댐옙占� 占쏙옙占� Max	-------------------------RX
+	short			m_nLevelRefAvg;				// 占쏟교댐옙占� 占쏙옙占� Avg	-------------------------RA
+	short			m_nLevelDiffMin;			// 占쏙옙占쏙옙 Min	---------------------------------DN
+	short			m_nLevelDiffMax;			// 占쏙옙占쏙옙 Max	---------------------------------DX
+	short			m_nLevelDiffAvg;			// 占쏙옙占쏙옙 Avg	---------------------------------DA
 
-	int				m_nDefectRScale;			// 픽셀단위 결함 높이	-------------------------RS
-	short			m_sThreshold;				// 결함을 검출할 때의 Threshold
-	short			m_sThresholdAvg;			// 결함을 검출할 때의 Threshold AVG
-	short			m_sDefectPeak;				// 결함의 Peak.
-	short			m_sDefectLevel;				// (DiffAvg - Th) BOE 8G 요청사항
+	int				m_nDefectRScale;			// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙	-------------------------RS
+	short			m_sThreshold;				// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 Threshold
+	short			m_sThresholdAvg;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 Threshold AVG
+	short			m_sDefectPeak;				// 占쏙옙占쏙옙占쏙옙 Peak.
+	short			m_sDefectLevel;				// (DiffAvg - Th) BOE 8G 占쏙옙청占쏙옙占쏙옙
 
-	int				m_nPixelGlassStart;			// Glass 시작 픽셀
+	int				m_nPixelGlassStart;			// Glass 占쏙옙占쏙옙 占싫쇽옙
 	short			m_sDefectLoc;
 
-	short			m_sZonePixelCount[16];	// Zone별 결함 Pixel 수
-	short			m_sZoneValueMin[16];	// Zone별 결함 Min
-	short			m_sZoneValueMax[16];	// Zone별 결함 Max
-	short			m_sZoneValueAvg[16];	// Zone별 결함 Avg
+	short			m_sZoneClassPixelCount[16];
+	short			m_sZonePixelCount[16];	// Zone占쏙옙 占쏙옙占쏙옙 Pixel 占쏙옙
+	short			m_sZoneValueMin[16];	// Zone占쏙옙 占쏙옙占쏙옙 Min
+	short			m_sZoneValueMax[16];	// Zone占쏙옙 占쏙옙占쏙옙 Max
+	short			m_sZoneValueAvg[16];	// Zone占쏙옙 占쏙옙占쏙옙 Avg
 	short			m_sZonePixelPercent[16];	// --------------------------------------Z0~ZF
 
-	//210127 CJH - Zone별 Source Gray 입력
-	short			m_sZoneValueSrcMin[16];	// Zone별 Source Min
-	short			m_sZoneValueSrcMax[16];	// Zone별 Source Max
-	short			m_sZoneValueSrcAvg[16]; // Zone별 Source Avg
+	//210127 CJH - Zone占쏙옙 Source Gray 占쌉뤄옙
+	short			m_sZoneValueSrcMin[16];	// Zone占쏙옙 Source Min
+	short			m_sZoneValueSrcMax[16];	// Zone占쏙옙 Source Max
+	short			m_sZoneValueSrcAvg[16]; // Zone占쏙옙 Source Avg
 
-	int				m_nUMOriginX;				// um단위 x좌표 (원점기준)
-	int				m_nUMOriginY;				// um단위 y조표 (원점기준)
-	int				m_nUMCenterAlignX;			// um단위 X좌표 (Glass Center 기준, 얼라인보정 후)
-	int				m_nUMCenterAlignY;			// um단위 Y좌표 (Glass Center 기준, 얼라인보정 후)
-	int				m_nUMCenterX;				// um단위 X좌표 (Glass Center 기준, 얼라인보정 전)
-	int				m_nUMCenterY;				// um단위 Y좌표 (Glass Center 기준, 얼라인보정 전)
-	int				m_nUMSizeX;					// um단위 X 크기	-----------------------------UX
-	int				m_nUMSizeY;					// um단위 Y 크기	-----------------------------UY
-	int				m_nUMSize;					// um단위 크기.
-	CRect			m_RectUM;					// 디펙 센터 기준 사각형.
+	int				m_nUMOriginX;				// um占쏙옙占쏙옙 x占쏙옙표 (占쏙옙占쏙옙占쏙옙占쏙옙)
+	int				m_nUMOriginY;				// um占쏙옙占쏙옙 y占쏙옙표 (占쏙옙占쏙옙占쏙옙占쏙옙)
+	int				m_nUMCenterAlignX;			// um占쏙옙占쏙옙 X占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterAlignY;			// um占쏙옙占쏙옙 Y占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterX;				// um占쏙옙占쏙옙 X占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterY;				// um占쏙옙占쏙옙 Y占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMSizeX;					// um占쏙옙占쏙옙 X 크占쏙옙	-----------------------------UX
+	int				m_nUMSizeY;					// um占쏙옙占쏙옙 Y 크占쏙옙	-----------------------------UY
+	int				m_nUMSize;					// um占쏙옙占쏙옙 크占쏙옙.
+	CRect			m_RectUM;					// 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占썹각占쏙옙.
 
-	short/*SERVER_DefectSizeType*/	m_DefectSizeType;			// 결함 크기 종류enum SERVER_DefectSizeType		{ SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
-	short/*SERVER_DefectPeakType*/	m_DefectPeakType;			// Peak의 종류.
-	short/*Judgement*/				m_DefectJudgement;			// 결함 판정.
-	BOOL					m_bDefectCutoff;			// 컷 오프 디펙(TRUE= Cutoff, FALSE)
-	short/*MAP16_DefectClass*/		m_DefectClass;				// BOE Defect Class 16등분 구분
-	int				m_nPadRegionIdx;			// PAD 영역 인덱스
+	short/*SERVER_DefectSizeType*/	m_DefectSizeType;			// 占쏙옙占쏙옙 크占쏙옙 占쏙옙占쏙옙enum SERVER_DefectSizeType		{ SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
+	short/*SERVER_DefectPeakType*/	m_DefectPeakType;			// Peak占쏙옙 占쏙옙占쏙옙.
+	short/*Judgement*/				m_DefectJudgement;			// 占쏙옙占쏙옙 占쏙옙占쏙옙.
+	BOOL					m_bDefectCutoff;			// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙(TRUE= Cutoff, FALSE)
+	short/*MAP16_DefectClass*/		m_DefectClass;				// BOE Defect Class 16占쏙옙占� 占쏙옙占쏙옙
+	int				m_nPadRegionIdx;			// PAD 占쏙옙占쏙옙 占싸듸옙占쏙옙
 
-	int				m_nUMCellX;					// 셀 원점 기준 x 좌표
-	int				m_nUMCellY;					// 셀 원점 기준 y 좌표
-	short			m_nModelIdx;				// 몇 번째 모델인가?
-	short			m_nCellIdx;					// 몇번째 셀인가?
-	short			m_nCellGate;				// 셀별 Gate라인(얼라인 보정 전)
-	short			m_nCellData;				// 셀별 Data라인(얼라인 보정 전)
-	short			m_nCellGateAlign;			// 셀별 Gate라인(얼라인 보정 후)
-	short			m_nCellDataAlign;			// 셀별 Data라인(얼라인 보정 후)
+	int				m_nUMCellX;					// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 x 占쏙옙표
+	int				m_nUMCellY;					// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 y 占쏙옙표
+	short			m_nModelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占싸곤옙?
+	short			m_nCellIdx;					// 占쏙옙占승� 占쏙옙占싸곤옙?
+	short			m_nCellGate;				// 占쏙옙占쏙옙 Gate占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellData;				// 占쏙옙占쏙옙 Data占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellGateAlign;			// 占쏙옙占쏙옙 Gate占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellDataAlign;			// 占쏙옙占쏙옙 Data占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
 
-	int				m_nUMShotX;					// 샷 기준 X좌표
-	int				m_nUMShotY;					// 샷 기준 Y좌표
-	short			m_nMaskDefectIdx;			// 한 Glass에서 발견된 마스크결함 묶음의 인덱스.
-	short			m_nShotIdx;					// 노광샷 번호
-	short			m_nMatchShotCount;			// 동일한 마스크 결함의 수.
-	short			m_nMatchMaxSize;			// 동일한 마스크 중 가장 큰 결함의 크기.
+	int				m_nUMShotX;					// 占쏙옙 占쏙옙占쏙옙 X占쏙옙표
+	int				m_nUMShotY;					// 占쏙옙 占쏙옙占쏙옙 Y占쏙옙표
+	short			m_nMaskDefectIdx;			// 占쏙옙 Glass占쏙옙占쏙옙 占쌩견듸옙 占쏙옙占쏙옙크占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙.
+	short			m_nShotIdx;					// 占쎈광占쏙옙 占쏙옙호
+	short			m_nMatchShotCount;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙크 占쏙옙占쏙옙占쏙옙 占쏙옙.
+	short			m_nMatchMaxSize;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙크 占쏙옙 占쏙옙占쏙옙 큰 占쏙옙占쏙옙占쏙옙 크占쏙옙.
 
-	short			m_nRepeatCount;				// 연속결함발견위한 동일좌표 반복수
+	short			m_nRepeatCount;				// 占쏙옙占쌈곤옙占쌉발곤옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙표 占쌥븝옙占쏙옙
 	short			m_nMaskRepeatCount;
 	int				m_StackInfo;				// Stack Flag
-	BOOL			m_bRealStack;				// Stack 머지에 의한 TD(TRUE) 인지, 필터링에 의한 TD(FALSE)구분할 수 있다.
-	short			m_nStackStepCount;			// Stack 수
-	short			m_nStackColorIdx;			// Color를 선택하는 인덱스.
+	BOOL			m_bRealStack;				// Stack 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 TD(TRUE) 占쏙옙占쏙옙, 占쏙옙占싶몌옙占쏙옙 占쏙옙占쏙옙 TD(FALSE)占쏙옙占쏙옙占쏙옙 占쏙옙 占쌍댐옙.
+	short			m_nStackStepCount;			// Stack 占쏙옙
+	short			m_nStackColorIdx;			// Color占쏙옙 占쏙옙占쏙옙占싹댐옙 占싸듸옙占쏙옙.
 	//CString			m_strStackStep[CFDEFECT_STACKCOUNT];			// Stack Step.
-	char			m_strStackFirst[60];			// Stack Step. //201221 CJH - 최대 사이즈 60bytes
-	char			m_strUnitID[16];				// 유닛아이디
+	char			m_strStackFirst[60];			// Stack Step. //201221 CJH - 占쌍댐옙 占쏙옙占쏙옙占쏙옙 60bytes
+	char			m_strUnitID[16];				// 占쏙옙占쌍억옙占싱듸옙
 
-	int				m_ClassificationType;				// enum ClassificationType			{ ClassType_None= 0, ClassType_PI_Over= 1, ClassType_PI_Under= 2, ClassType_TFE_Circle= 3, ClassType_Bubble, ClassType_Scratch, ClassType_Particle}; Classification Type, PI나 TFE등 추가 분류  알고리즘 적용 결과.
-	int				m_nAtomWidth;				// TFE 핵 너비
-	int				m_nAtomHeight;				// TFE 핵 높이
-	short/*ReKind*/			m_DefectKind;				// 결함 종류
+	int				m_ClassificationType;				// enum ClassificationType			{ ClassType_None= 0, ClassType_PI_Over= 1, ClassType_PI_Under= 2, ClassType_TFE_Circle= 3, ClassType_Bubble, ClassType_Scratch, ClassType_Particle}; Classification Type, PI占쏙옙 TFE占쏙옙 占쌩곤옙 占싻뤄옙  占싯곤옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占�.
+	int				m_nAtomWidth;				// TFE 占쏙옙 占십븝옙
+	int				m_nAtomHeight;				// TFE 占쏙옙 占쏙옙占쏙옙
+	short/*ReKind*/			m_DefectKind;				// 占쏙옙占쏙옙 占쏙옙占쏙옙
 
 	char			m_strDefectCode[32];			// Defect Code
 	BOOL			m_bMergeState;				// Merge Status
 	char			m_strAoiImageName[256];			// Defect Image Name(CCD Image)
-	int				m_nDefectMerge;		// 현재 디펙의 머지 여부
+	int				m_nDefectMerge;		// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 
 
 	int				m_nPixelSizeOrigin;
 	int				m_nScratchRatio;
-	int				m_nDensity;			// 원형 결함 구분을 위한 밀도 [2017.8.2 bhs]
+	int				m_nDensity;			// 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占싻듸옙 [2017.8.2 bhs]
 
 	char			m_strDefectName[16];
 	char			m_strDefectType[16];
@@ -455,19 +491,27 @@
 	double			m_dScanResolution;
 	double			m_dConvResolution;
 
-	int				m_nAngle;					// 각도
-	int				m_nMajor;					// 장축 길이(Long)
-	int				m_nMinor;					// 단축 길이(Short)
-	int				m_nCompact;					// Blob 장축을 지름으로 하는 원의 넓이와 Blob 넓이의 비율
-	int				m_nThickness;				// Blob 넓이와 장축의 비율 (Area / Major)
+	int				m_nAngle;					// 占쏙옙占쏙옙
+	int				m_nMajor;					// 占쏙옙占쏙옙 占쏙옙占쏙옙(Long)
+	int				m_nMinor;					// 占쏙옙占쏙옙 占쏙옙占쏙옙(Short)
+	int				m_nCompact;					// Blob 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占싹댐옙 占쏙옙占쏙옙 占쏙옙占싱울옙 Blob 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
+	int				m_nThickness;				// Blob 占쏙옙占싱울옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 (Area / Major)
 	
-	short			m_nHliLevelIdx;				// 몇 번째 레벨(채널)인가?
-	int				m_nHliLayers;				// 해당결함에 포함된 레이어 bit처리
+	short			m_nHliLevelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占쏙옙(채占쏙옙)占싸곤옙?
+	int				m_nHliLayers;				// 占쌔댐옙占쏙옙篤占� 占쏙옙占쌉듸옙 占쏙옙占싱억옙 bit처占쏙옙
 
-	BOOL			m_bShrinked;				//210323 CJH - Frame Shrink 정보 추가
+	BOOL			m_bShrinked;				//210323 CJH - Frame Shrink 占쏙옙占쏙옙 占쌩곤옙
+
+	char			m_strAoiImagePath[255];
+	char			m_strReviewImagePath[255];
+
+	int				m_nAlignRectLeft;
+	int				m_nAlignRectTop;
+	int				m_nAlignRectBottom;
+	int				m_nAlignRectRight;
 
 
-	//리뷰 디펙 정보 [김태현 2019/1/19]
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/1/19]
 	_grmDefectReviewData m_ReviewDefect;
 };
 
@@ -491,6 +535,8 @@
 	grcWriteBin = 201,
 	grcReadBin = 202,
 
+	grcReviewWriteBIn = 301,
+
 	grcGlassRawCommand
 };
 
@@ -510,7 +556,7 @@
 
 struct _grmDitMemInfo
 {
-	//공유 메모리 생성할 공간 결정 [김태현 2018/11/12]
+	//占쏙옙占쏙옙 占쌨몌옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	size_t m_nGlassRawDataSize;
 	int m_nGlassMaxDataNum;
 	int m_nBlockMaxDataNum;
@@ -518,7 +564,7 @@
 	int m_nDefectMaxDataNum;
 	int m_nStackMaxDataNum;
 
-	//Char 기준 자료가 있는 시작 위치 [김태현 2018/11/12]
+	//Char 占쏙옙占쏙옙 占쌘료가 占쌍댐옙 占쏙옙占쏙옙 占쏙옙치 [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	int m_nGlassDataPoint;
 	int m_nBlockDataPoint;
 	int m_nCellDataPoint;
@@ -534,8 +580,8 @@
 struct _grmDitGlassRawInfo : public _grmDitMemInfo, public _grmDitCommand
 {
 	size_t m_nGlassLoadingCount;
-	emAOIProcStep m_ClientProcStep; //AOI, Review가 보낸 명령
-	emAOIProcStep m_ServerProcStep; //GlassRaw Messenger(Server)가 처리 완료 한 명령
+	emAOIProcStep m_ClientProcStep; //AOI, Review占쏙옙 占쏙옙占쏙옙 占쏙옙占�
+	emAOIProcStep m_ServerProcStep; //GlassRaw Messenger(Server)占쏙옙 처占쏙옙 占싹뤄옙 占쏙옙 占쏙옙占�
 };
 
 class CgrmGlassRawData
@@ -622,7 +668,7 @@
 	{
 		if(pInfo == NULL || pData == NULL) return FALSE;
 
-		if(1) //new type //메모리 총 공간 크기에 상관없이 
+		if(1) //new type //占쌨몌옙 占쏙옙 占쏙옙占쏙옙 크占썩에 占쏙옙占쏙옙占쏙옙占� 
 		{
 			//if(pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) return FALSE;
 
diff --git a/ReviewHistory/ReveiwHistory/AlignDlg.cpp b/ReviewHistory/ReveiwHistory/AlignDlg.cpp
new file mode 100644
index 0000000..479c1ec
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/AlignDlg.cpp
@@ -0,0 +1,515 @@
+癤�// DefectListDlg.cpp: 援ы쁽 �뙆�씪
+//
+
+#include "stdafx.h"
+#include "ReveiwHistory.h"
+#include "AlignDlg.h"
+#include "afxdialogex.h"
+#include <algorithm>
+#include <functional>
+
+// CFormtListDlg ���솕 �긽�옄
+
+IMPLEMENT_DYNAMIC(CAlignDlg, CDialog)
+
+enum { FORMLIST_POPUP_FORMALL = 15000, FORMLIST_POPUP_FORMSELECT, FORMLIST_POPUP_End };
+
+
+CAlignDlg::CAlignDlg(CWnd* pParent /*=nullptr*/)
+	: CDialog(IDD_DLG_ALIGN, pParent)
+{
+	m_pDefectFormation = NULL;
+	m_bAsending = FALSE;
+	m_nLastSortCol = 0;
+	m_nSelectedCol = 0;
+	m_nSelectedRow = 0;
+	m_nSelectedFormIdRclick = -1;
+}
+
+CAlignDlg::~CAlignDlg()
+{
+}
+
+void CAlignDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialog::DoDataExchange(pDX);
+}
+
+BOOL CAlignDlg::Create(CWnd * pParentWnd)
+{
+	return CDialog::Create(IDD, pParentWnd);
+}
+
+BOOL CAlignDlg::PreTranslateMessage(MSG * pMsg)
+{
+	if (pMsg->message == WM_KEYDOWN)
+	{
+		if (pMsg->wParam == VK_ESCAPE)
+		{
+			ShowWindow(SW_HIDE);
+
+			return TRUE;
+		}
+	}
+
+	return __super::PreTranslateMessage(pMsg);
+}
+
+void CAlignDlg::OnDestroy()
+{
+	CDialog::OnDestroy();
+}
+
+void CAlignDlg::OnShowWindow(BOOL bShow, UINT nStatus)
+{
+	__super::OnShowWindow(bShow, nStatus);
+
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	if (TRUE == bShow)
+	{
+	}
+}
+
+
+BEGIN_MESSAGE_MAP(CAlignDlg, CDialog)
+	ON_BN_CLICKED(IDOK, &CAlignDlg::OnBnClickedOk)
+	ON_CONTROL_RANGE(BN_CLICKED, FORMLIST_POPUP_FORMALL, FORMLIST_POPUP_End, OnPopupMenuFormList)
+	ON_WM_SIZE()
+END_MESSAGE_MAP()
+
+
+// CFormtListDlg 硫붿떆吏� 泥섎━湲�
+
+
+void CAlignDlg::OnBnClickedOk()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CDialog::OnOK();
+}
+
+
+BOOL CAlignDlg::OnInitDialog()
+{
+	CDialog::OnInitDialog();
+
+	// TODO:  �뿬湲곗뿉 異붽� 珥덇린�솕 �옉�뾽�쓣 異붽��빀�땲�떎.
+	
+	m_vecStrGridDefectHeader.push_back("           ");
+	m_vecStrGridDefectHeader.push_back("1st X Pos");
+	m_vecStrGridDefectHeader.push_back("1st Y Pos");
+	m_vecStrGridDefectHeader.push_back("2nd X Pos");
+	m_vecStrGridDefectHeader.push_back("2nd Y Pos");
+	   	 
+	CakGridCtrl* pGrid = &m_gridFormInfo;
+	{
+		std::vector<CString>* pVecHeader = &m_vecStrGridDefectHeader;
+
+		CRect rectGrid;
+		GetDlgItem(IDC_STATIC_GRID_ALIGN)->GetWindowRect(&rectGrid);
+		ScreenToClient(&rectGrid);
+		pGrid->Create(rectGrid, this, IDC_STATIC_GRID_ALIGN);
+
+
+		pGrid->GetDefaultCell(TRUE, FALSE)->SetBackClr(GRID_FIX_COLOR);
+		pGrid->GetDefaultCell(FALSE, TRUE)->SetBackClr(GRID_FIX_COLOR);
+		pGrid->GetDefaultCell(FALSE, FALSE)->SetBackClr(GRID_COLOR);
+		pGrid->SetFixedBkColor(GRID_FIX_COLOR);
+		pGrid->SetGridLines(GVL_BOTH);
+
+
+		pGrid->SetVirtualMode(TRUE);
+		pGrid->SetCallbackFunc(NULL, 0);
+		pGrid->AllowReorderColumn(FALSE); // implemented now only if m_bCallback
+		pGrid->EnableDragRowMode(FALSE);
+
+		pGrid->SetColumnCount((int)pVecHeader->size());
+		pGrid->SetDoubleBuffering(TRUE);
+		pGrid->SetRowCount(2);
+		pGrid->SetFixedRowCount(1);
+		pGrid->SetFixedColumnCount(0);
+
+		pGrid->SetEditable(FALSE);
+		pGrid->EnableSelection(TRUE);
+		pGrid->SetFixedRowSelection(TRUE);
+		pGrid->SetHeaderSort(FALSE);
+
+		// fill it up with stuff
+		pGrid->SetEditable(TRUE);
+		pGrid->EnableDragAndDrop(TRUE);
+
+
+		pGrid->AutoSize();
+		pGrid->Invalidate();
+	}
+
+	m_WndArrange.setParentWnd(this);
+	m_WndArrange.addChildWnd(&m_gridFormInfo, WA_RESIZE_WIDTH | WA_RESIZE_HEIGHT);
+
+	GetDlgItem(IDC_IMG_ALIGN1)->GetWindowRect(m_picture_rect);
+	GetDlgItem(IDC_IMG_ALIGN2)->GetWindowRect(m_picture_rect2);
+
+	ScreenToClient(m_picture_rect);
+	ScreenToClient(m_picture_rect2);
+
+	return TRUE;  // return TRUE unless you set the focus to a control
+				  // �삁�쇅: OCX �냽�꽦 �럹�씠吏��뒗 FALSE瑜� 諛섑솚�빐�빞 �빀�땲�떎.
+}
+
+
+BOOL CAlignDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
+{
+	// TODO: �뿬湲곗뿉 �듅�닔�솕�맂 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯 �겢�옒�뒪瑜� �샇異쒗빀�땲�떎.
+	if (m_gridFormInfo.GetSafeHwnd() && wParam == (WPARAM)m_gridFormInfo.GetDlgCtrlID())
+	{
+		*pResult = 1;
+		GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;
+		if (GVN_GETDISPINFO == pDispInfo->hdr.code)
+		{
+			getDispInfoDefect(pDispInfo->item.col, pDispInfo->item.row, &pDispInfo->item.strText);
+
+			return TRUE;
+		}
+		else if (NM_CLICK == pDispInfo->hdr.code)
+		{
+			if (pDispInfo->item.row == 0)
+			{
+				SortListDefect(pDispInfo->item.col);
+				m_gridFormInfo.Refresh();
+			}
+			else if (pDispInfo->item.row > 0)
+			{
+				if (pDispInfo->item.row <= m_vecSortForm.size())
+				{
+					int nFormID = m_vecSortForm[pDispInfo->item.row - 1]->m_nFormLabel;
+					GetParent()->PostMessage(UM_FORMLIST_FORMSELECT, nFormID);
+				}
+				
+			}
+			m_nSelectedCol = pDispInfo->item.col;
+		}
+		else if (NM_RCLICK == pDispInfo->hdr.code)
+		{
+			if (pDispInfo->item.row>0 && pDispInfo->item.row <= m_vecSortForm.size())
+			{
+				m_nSelectedFormIdRclick = m_vecSortForm[pDispInfo->item.row - 1]->m_nFormLabel;
+			}
+			else if (pDispInfo->item.row == 0)
+			{
+				m_nSelectedFormIdRclick = -1;
+			}
+			else
+			{
+				m_nSelectedFormIdRclick = -1;
+			}
+			
+			
+// 			{
+// 				CString strText;
+// 				CMenu menu;
+// 				VERIFY(menu.CreatePopupMenu());
+// 
+// 				menu.AppendMenu(MF_STRING, FORMLIST_POPUP_FORMALL, (LPCTSTR)"�쟾泥대낫湲�");
+// 
+// 				if (m_nSelectedFormIdRclick < 0)
+// 				{
+// 					
+// 				}
+// 				else if (m_nSelectedFormIdRclick >= 0)
+// 				{
+// 					strText.Format("Form%d 蹂닿린", m_nSelectedFormIdRclick);
+// 					menu.AppendMenu(MF_STRING, FORMLIST_POPUP_FORMSELECT, (LPCTSTR)strText);
+// 				}
+// 				
+// 
+// 				CPoint ptPoint;
+// 				GetCursorPos(&ptPoint);
+// 
+// 				menu.TrackPopupMenu(TPM_LEFTALIGN | TPM_LEFTBUTTON, ptPoint.x, ptPoint.y, this);
+// 				
+// 			}
+			
+		}
+		else if (GVN_ODCACHEHINT == pDispInfo->hdr.code)
+		{
+			GV_CACHEHINT *pCacheHint = (GV_CACHEHINT*)pDispInfo;
+		}
+	}
+	return CDialog::OnNotify(wParam, lParam, pResult);
+}
+
+void CAlignDlg::setFormShow(int nFormID, BOOL bEnsureVisible)
+{
+	const int nDefectCol = 1;
+
+	if (nFormID >= 0)
+	{
+		int iRow = m_nSelectedRow;//for (int iRow = 0; iRow < m_gridDefectInfo.GetRowCount(); iRow++)
+		{
+			for (int iCol = 0; iCol < m_gridFormInfo.GetColumnCount(); iCol++)
+			{
+				m_gridFormInfo.SetItemState(iRow, iCol, m_gridFormInfo.GetItemState(iRow, iCol) & ~GVIS_SELECTED /*& ~GVIS_FOCUSED*/);
+			}
+		}
+	}
+	for (int i = 0; i < m_vecSortForm.size(); i++)
+	{
+		if (m_vecSortForm[i]->m_nFormLabel == nFormID)
+		{
+			int iRow = i+1;
+			for (int iCol = 0; iCol < m_gridFormInfo.GetColumnCount(); iCol++)
+			{
+				m_gridFormInfo.SetItemState(iRow, iCol, LVIS_SELECTED);
+			}
+			m_nSelectedRow = iRow;
+			if (bEnsureVisible)
+			{
+				m_gridFormInfo.EnsureVisible(iRow, m_nSelectedCol);
+			}
+			break;
+		}
+	}
+
+	m_gridFormInfo.Invalidate();
+}
+
+void CAlignDlg::getDispInfoDefect(int nCol, int nRow, CString* pStrData)
+{
+	if (nRow < 0) return;
+
+	if (nRow == 0) //header
+	{
+		*pStrData = m_vecStrGridDefectHeader[nCol];
+	}
+	else
+	{
+		if (m_pDefectFormation == NULL) return;
+
+		int nDataIndex = nRow - 1;
+
+		if (nDataIndex >= m_vecSortForm.size()) return;
+
+		_akFormation* pForm = m_vecSortForm[nDataIndex];
+
+		if (pForm == NULL)
+			return;
+
+		CString		strItem;
+		BOOL		bPixel = FALSE;
+
+		
+		switch (nCol)
+		{
+		case 0: strItem.Format("%d", nRow); break;
+		case 1: strItem.Format("%d", pForm->m_nFormLabel); break;
+		case 2:
+		{
+			if (pForm->m_nFormJudge == 0) strItem = "";
+			else if (pForm->m_nFormJudge == 1) strItem = "�젣嫄�";
+		}break;
+		case 3: 
+		{
+			if (pForm->m_nFormType == 0) strItem = "ROUND";
+			else if (pForm->m_nFormType == 1) strItem = "LINE";
+		}break;
+		case 4: strItem.Format("%d", pForm->m_vecForms.size()); break;
+		case 5: strItem.Format("%d", pForm->m_nDefectNumS); break;
+		case 6: strItem.Format("%d", pForm->m_nDefectNumM); break;
+		case 7: strItem.Format("%d", pForm->m_nDefectNumL); break;
+
+		case 8: strItem.Format("%.3lf", pForm->m_dSizeAvg); break;
+		case 9: strItem.Format("%.3lf", pForm->m_dSizeStdDev); break;
+
+		case 10: strItem.Format("%d", pForm->m_nDefectNum1Px); break;
+		case 11: strItem.Format("%d", pForm->m_nDefectNumWhite); break;
+		case 12: strItem.Format("%d", pForm->m_nDefectNumBlack); break;
+		case 13: strItem.Format("%d", pForm->m_nDefectNum1PxWhite); break;
+
+		case 14: strItem.Format("%.0lf", 100.0* ((double)pForm->m_nDefectNum1Px /(double)pForm->m_vecForms.size())); break;
+		case 15: strItem.Format("%.0lf", 100.0* ((double)pForm->m_nDefectNumWhite / (double)pForm->m_vecForms.size())); break;
+		case 16: strItem.Format("%.0lf", 100.0* ((double)pForm->m_nDefectNumBlack / (double)pForm->m_vecForms.size())); break;
+		case 17: strItem.Format("%.0lf", 100.0* ((double)pForm->m_nDefectNum1PxWhite / (double)pForm->m_vecForms.size())); break;
+		
+		case 18: strItem.Format("%.3lf", pForm->m_dDiffStdDev); break;
+		case 19: strItem.Format("%.3lf", pForm->m_dDiffStdDevAbs); break;
+		}
+		
+
+
+		*pStrData = strItem;
+	}
+}
+
+void CAlignDlg::updateDefectInfo()
+{
+	if (m_pDefectFormation && m_pDefectDisplayOption)
+	{
+		int nFormType;
+		int nFormLabel;
+		m_vecSortForm.clear();
+		for (int i = 0; i < m_pDefectFormation->m_vecFormation.size(); i++)
+		{
+			nFormType = m_pDefectFormation->m_vecFormation[i].m_nFormType;
+			nFormLabel = i;
+						
+			if (nFormLabel >= 0)
+			{
+				nFormType = m_pDefectFormation->m_vecFormation[i].m_nFormType;
+			}
+
+			if (m_pDefectDisplayOption->m_bShowDefectNormal == FALSE)
+			{
+				if (nFormType < 0) continue;;
+			}
+			if (m_pDefectDisplayOption->m_bShowDefectGroupRound == FALSE)
+			{
+				if (nFormType == 0) continue;;
+			}
+			if (m_pDefectDisplayOption->m_bShowDefectGroupLine == FALSE)
+			{
+				if (nFormType == 1) continue;;
+			}
+			if (m_pDefectDisplayOption->m_nShowLabel >= 0)
+			{
+				if (nFormLabel != m_pDefectDisplayOption->m_nShowLabel) continue;;
+			}
+
+			m_vecSortForm.push_back(&m_pDefectFormation->m_vecFormation[i]);
+		}
+		if(m_nLastSortCol>0) SortListDefect(m_nLastSortCol);
+		m_gridFormInfo.SetRowCount(m_vecSortForm.size()+1);
+		m_gridFormInfo.Invalidate();
+	}
+}
+
+
+void CAlignDlg::OnSize(UINT nType, int cx, int cy)
+{
+	CDialog::OnSize(nType, cx, cy);
+
+	m_WndArrange.process(cx, cy);
+}
+
+void CAlignDlg::OnPopupMenuFormList(UINT nID)
+{
+	if (nID == FORMLIST_POPUP_FORMALL)
+	{
+		GetParent()->PostMessage(UM_FORMLIST_FORMSELECT, -1, 1);
+	}
+	else if(nID == FORMLIST_POPUP_FORMSELECT)
+	{
+		GetParent()->PostMessage(UM_FORMLIST_FORMSELECT, m_nSelectedFormIdRclick, 1);
+	}
+	
+}
+
+void CAlignDlg::SortListDefect(int nCol)
+{
+	if (nCol == 0)
+		return;
+
+	if (m_pDefectFormation == NULL) return;
+
+	m_bAsending = !m_bAsending;
+
+	{
+		_akFormation			*pForm;
+		std::vector< std::pair<CString, _akFormation*> > vecString;
+		std::vector< std::pair<double, _akFormation*> > vecValue;
+		CString strValue;
+		double dValue;
+
+		for (int i = 0; i < m_vecSortForm.size(); i++)
+		{
+			pForm = m_vecSortForm[i];
+
+			switch (nCol)
+			{
+			case 1: dValue = pForm->m_nFormLabel; break;
+			case 2: dValue = pForm->m_nFormJudge; break;
+			case 3:	dValue = pForm->m_nFormType; break;
+			case 4:	dValue = pForm->m_vecForms.size(); break;
+			case 5: dValue = pForm->m_nDefectNumS; break;
+			case 6: dValue = pForm->m_nDefectNumM; break;
+			case 7: dValue = pForm->m_nDefectNumL; break;
+			case 8: dValue = pForm->m_dSizeAvg; break;
+			case 9: dValue = pForm->m_dSizeStdDev; break;
+			case 10: dValue = pForm->m_nDefectNum1Px; break;
+			case 11: dValue = pForm->m_nDefectNumWhite; break;
+			case 12: dValue = pForm->m_nDefectNumBlack; break;
+			case 13: dValue = pForm->m_nDefectNum1PxWhite; break;
+
+			case 14: dValue = pForm->m_nDefectNum1Px; break;
+			case 15: dValue = pForm->m_nDefectNumWhite ; break;
+			case 16: dValue = pForm->m_nDefectNumBlack ; break;
+			case 17: dValue = pForm->m_nDefectNum1PxWhite ; break;
+
+			case 18: dValue = pForm->m_dDiffStdDev; break;
+			case 19: dValue = pForm->m_dDiffStdDevAbs; break;
+
+			}
+
+			if(strValue.IsEmpty() == FALSE) vecString.push_back(std::make_pair(strValue, pForm));
+			else vecValue.push_back(std::make_pair(dValue, pForm));
+		}
+
+		if (!vecString.empty())
+		{
+			if (m_bAsending == TRUE)
+				std::sort(vecString.begin(), vecString.end(), std::greater< std::pair<CString, _akFormation*> >());
+			else
+				std::sort(vecString.begin(), vecString.end(), std::less< std::pair<CString, _akFormation*> >());
+
+			m_vecSortForm.clear();
+			std::vector< std::pair<CString, _akFormation*> >::iterator itVec;
+			for (itVec = vecString.begin(); itVec != vecString.end(); ++itVec)
+			{
+				m_vecSortForm.push_back(itVec->second);
+			}
+		}
+		else//if (!vecString.empty())
+		{
+			if (m_bAsending == TRUE)
+				std::sort(vecValue.begin(), vecValue.end(), std::greater< std::pair<double, _akFormation*> >());
+			else
+				std::sort(vecValue.begin(), vecValue.end(), std::less< std::pair<double, _akFormation*> >());
+
+			m_vecSortForm.clear();
+			std::vector< std::pair<double, _akFormation*> >::iterator itVec;
+			for (itVec = vecValue.begin(); itVec != vecValue.end(); ++itVec)
+			{
+				m_vecSortForm.push_back(itVec->second);
+			}
+		}		
+	}
+	
+	m_nLastSortCol = nCol;
+}
+
+void CAlignDlg::DrawnoImage()
+{
+	CPaintDC dc(this);
+
+	m_AlignImage.Destroy();
+	m_AlignImage2.Destroy();
+
+	CString DeftectPath;
+	CFileStatus FileOn;
+	TCHAR chFilePath[256] = { 0, };
+	GetModuleFileName(NULL, chFilePath, 256);
+	CString strFolderPath(chFilePath);
+	strFolderPath = strFolderPath.Left(strFolderPath.ReverseFind('\\'));
+
+	strFolderPath = strFolderPath + "\\no-image.png";
+	m_AlignImage.Load(strFolderPath);
+	m_AlignImage2.Load(strFolderPath);
+
+	HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strFolderPath,
+		IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+	InvalidateRect(m_picture_rect, FALSE);
+	InvalidateRect(m_picture_rect2, FALSE);
+
+	dc.SetStretchBltMode(COLORONCOLOR);
+	m_AlignImage.Draw(dc, m_picture_rect);
+	m_AlignImage2.Draw(dc, m_picture_rect2); 
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/AlignDlg.h b/ReviewHistory/ReveiwHistory/AlignDlg.h
new file mode 100644
index 0000000..1384db3
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/AlignDlg.h
@@ -0,0 +1,71 @@
+癤�#pragma once
+
+
+// CFormtListDlg ���솕 �긽�옄
+#include "akGridCtrl/akGridCtrl.h"
+#include "akDefectFormation.h"
+#include "akWndArrange.h"
+#include "Singleton.h"
+
+#define UM_FORMLIST_FORMSELECT WM_USER+0x3101
+
+
+class CAlignDlg : public CDialog, public CSingleton< CAlignDlg >
+{
+	DECLARE_DYNAMIC(CAlignDlg)
+
+public:
+	CAlignDlg(CWnd* pParent = nullptr);   // �몴以� �깮�꽦�옄�엯�땲�떎.
+	virtual ~CAlignDlg();
+
+// ���솕 �긽�옄 �뜲�씠�꽣�엯�땲�떎.
+//#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DLG_ALIGN };
+//#endif
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 吏��썝�엯�땲�떎.
+
+	DECLARE_MESSAGE_MAP()
+
+public:
+	virtual BOOL Create(CWnd* pParentWnd = NULL);
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+	afx_msg void OnDestroy();
+	afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+
+	void setFormShow(int nDefectID, BOOL bEnsureVisible);
+	void getDispInfoDefect(int nCol, int nRow, CString* pStrData);
+	void updateDefectInfo();
+	void SortListDefect(int nCol);
+	void DrawnoImage();
+public:
+	CakGridCtrl m_gridFormInfo;
+	std::vector<CString> m_vecStrGridDefectHeader; 
+	//std::vector<int> m_vecGridColDataType;//0:string, 1:int, 2:double, 11:string to int, 12:string to double
+	akDefectFormation* m_pDefectFormation;
+	CakWndArrange		m_WndArrange;
+	std::vector<_akFormation*>	m_vecSortForm;
+	BOOL m_bAsending;
+	_DefectDisplayOption* m_pDefectDisplayOption;
+	int m_nLastSortCol;
+	int m_nSelectedCol;
+	int m_nSelectedRow;
+
+	CImage m_AlignImage;
+	CImage m_AlignImage2;
+
+	CRect m_picture_rect;
+	CRect m_picture_rect2;
+
+	int m_nSelectedFormIdRclick;
+public:
+	afx_msg void OnBnClickedOk();
+	virtual BOOL OnInitDialog();
+	virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	afx_msg void OnPopupMenuFormList(UINT nID);
+	
+};
+
diff --git a/ReviewHistory/ReveiwHistory/AnaResultFile.cpp b/ReviewHistory/ReveiwHistory/AnaResultFile.cpp
new file mode 100644
index 0000000..bc0cf34
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/AnaResultFile.cpp
@@ -0,0 +1,140 @@
+#include "StdAfx.h"
+#include "AnaResultFile.h"
+#include "akCore/akFileDB.h"
+#include "akLoggerExt.h"
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+CAnaResultFile::CAnaResultFile(void)
+{
+}
+
+CAnaResultFile::~CAnaResultFile(void)
+{
+}
+
+BOOL CAnaResultFile::MakeAnaFile(CgrmGlassRawData* pData)
+{
+	//return TRUE;
+
+	CString strFilePathName;
+	strFilePathName.Format("%s\\%sana", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName);
+
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if (pf == NULL)
+	{
+		AKLOG("MakeAOIFile Fail : [%s]", strFilePathName.GetBuffer(0));
+		return FALSE;
+	}
+
+	fprintf(pf, "%s\n", pData->GetGlassData()->m_strGlassID);
+	fprintf(pf, "m_strImageName, m_strDefectCode, UMCenterAlignX, UMCenterAlignY, m_nLevelSrcMin, m_nLevelSrcMax, m_nLevelSrcAvg, m_nLevelRefMin, m_nLevelRefMax, m_nLevelRefAvg, m_nLevelDiffMin, m_nLevelDiffMax, m_nLevelDiffAvg");
+	for (int i = 0; i < MAX_ZONE_NUM; i++) fprintf(pf, ",Zone%02d", i);
+	//210123 CJH - Zone별 min, max, avg 값 표기
+	for (int i = 0; i < MAX_ZONE_NUM; i++) fprintf(pf, ",ZoneDiffMin%02d", i);
+	for (int i = 0; i < MAX_ZONE_NUM; i++) fprintf(pf, ",ZoneDiffMax%02d", i);
+	for (int i = 0; i < MAX_ZONE_NUM; i++) fprintf(pf, ",ZoneDiffAvg%02d", i);
+	for (int i = 0; i < MAX_ZONE_NUM; i++) fprintf(pf, ",ZoneSrcMin%02d", i);
+	for (int i = 0; i < MAX_ZONE_NUM; i++) fprintf(pf, ",ZoneSrcMax%02d", i);
+	for (int i = 0; i < MAX_ZONE_NUM; i++) fprintf(pf, ",ZoneSrcAvg%02d", i);
+	fprintf(pf, ", m_sDefectPeak, m_nPixelSize, DefectType, UMSize, Density, ScrtRatio, MergeState, Angle, Major, Minor, Compact, Thickness");
+	fprintf(pf, "\n");
+
+	for (int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+	{
+		_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+		if (pData->GetGlassData()->m_nScanCoordinateY == 1) //분판설비의 경우 XY반전
+		{
+			fprintf(pf, "%s, %s, %.3lf, %.3lf, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+				pDefect->m_strAoiImageName, pDefect->m_strDefectCode, (double)pDefect->m_nUMCenterAlignY / 1000.0, (double)pDefect->m_nUMCenterAlignX / 1000.0,
+				pDefect->m_nLevelSrcMin, pDefect->m_nLevelSrcMax, pDefect->m_nLevelSrcAvg,
+				pDefect->m_nLevelRefMin, pDefect->m_nLevelRefMax, pDefect->m_nLevelRefAvg,
+				pDefect->m_nLevelDiffMin, pDefect->m_nLevelDiffMax, pDefect->m_nLevelDiffAvg);
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZonePixelCount[iz]);
+			}
+			//210123 CJH - Zone별 min, max, avg 값 표기
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueMin[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueMax[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueAvg[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueSrcMin[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueSrcMax[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueSrcAvg[iz]);
+			}
+			fprintf(pf, ",%d, %d, %d, %d, %d, %d, %d",
+				pDefect->m_sDefectPeak, pDefect->m_nPixelSize, pDefect->m_DefectType, (int)pDefect->m_nUMSize, pDefect->m_nDensity, pDefect->m_nScratchRatio, pDefect->m_bMergeState);
+
+			fprintf(pf, ", %d, %d, %d, %d, %d", pDefect->m_nAngle, pDefect->m_nMajor, pDefect->m_nMinor, pDefect->m_nCompact, pDefect->m_nThickness);
+
+			fprintf(pf, "\n");
+		}
+		else
+		{
+			fprintf(pf, "%s, %s, %.3lf, %.3lf, %d, %d, %d, %d, %d, %d, %d, %d, %d",
+				pDefect->m_strAoiImageName, pDefect->m_strDefectCode, (double)pDefect->m_nUMCenterAlignX / 1000.0, (double)pDefect->m_nUMCenterAlignY / 1000.0,
+				pDefect->m_nLevelSrcMin, pDefect->m_nLevelSrcMax, pDefect->m_nLevelSrcAvg,
+				pDefect->m_nLevelRefMin, pDefect->m_nLevelRefMax, pDefect->m_nLevelRefAvg,
+				pDefect->m_nLevelDiffMin, pDefect->m_nLevelDiffMax, pDefect->m_nLevelDiffAvg);
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZonePixelCount[iz]);
+			}
+			//210123 CJH - Zone별 min, max, avg 값 표기
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueMin[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueMax[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueAvg[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueSrcMin[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueSrcMax[iz]);
+			}
+			for (int iz = 0; iz < MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZoneValueSrcAvg[iz]);
+			}
+			fprintf(pf, ",%d, %d, %d, %d, %d, %d, %d",
+				pDefect->m_sDefectPeak, pDefect->m_nPixelSize, pDefect->m_DefectType, (int)pDefect->m_nUMSize, pDefect->m_nDensity, pDefect->m_nScratchRatio, pDefect->m_bMergeState);
+
+			fprintf(pf, ", %d, %d, %d, %d, %d", pDefect->m_nAngle, pDefect->m_nMajor, pDefect->m_nMinor, pDefect->m_nCompact, pDefect->m_nThickness);
+
+			fprintf(pf, "\n");
+		}
+	}
+	AKLOG("MakeAnaFile Complete %s", strFilePathName);
+	fclose(pf);
+
+	return TRUE;
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/AnaResultFile.h b/ReviewHistory/ReveiwHistory/AnaResultFile.h
new file mode 100644
index 0000000..78a5fb5
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/AnaResultFile.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include "DitGlassRawStruct.h"
+
+class CAnaResultFile
+{
+public:
+	CAnaResultFile(void);
+	virtual ~CAnaResultFile(void);
+
+public:
+	BOOL MakeAnaFile(CgrmGlassRawData* pData);
+
+
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ReviewHistory/ReveiwHistory/CHRectTracker.cpp b/ReviewHistory/ReveiwHistory/CHRectTracker.cpp
new file mode 100644
index 0000000..9a5da83
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CHRectTracker.cpp
@@ -0,0 +1,316 @@
+#include "StdAfx.h"
+#include "CHRectTracker.h"
+
+AFX_STATIC_DATA HCURSOR _afxCursors[10] = { 0, };
+AFX_STATIC_DATA HBRUSH _afxHatchBrush = 0;
+AFX_STATIC_DATA HPEN _afxBlackDottedPen = 0;
+AFX_STATIC_DATA int _afxHandleSize = 0;
+
+CCHRectTracker::CCHRectTracker(void)
+{
+}
+
+CCHRectTracker::CCHRectTracker(LPCRECT lpSrcRect, UINT nStyle)
+{
+	CRectTracker(lpSrcRect, nStyle);
+}
+
+CCHRectTracker::~CCHRectTracker(void)
+{
+}
+
+BOOL CCHRectTracker::TrackRubberBand(CWnd* pWnd, CPoint point, BOOL bAllowInvert)
+{
+	// simply call helper function to track from bottom right handle
+	m_bAllowInvert = bAllowInvert;
+	m_rect.SetRect(point.x, point.y, point.x, point.y);
+
+	return TrackHandle(hitBottomRight, pWnd, point, NULL);
+}
+
+BOOL CCHRectTracker::Track(CWnd* pWnd, CPoint point, BOOL bAllowInvert, CWnd* pWndClipTo)
+{
+	// perform hit testing on the handles
+	int nHandle = HitTestHandles(point);
+	if (nHandle < 0)
+	{
+		// didn't hit a handle, so just return FALSE
+		return FALSE;
+	}
+
+	// otherwise, call helper function to do the tracking
+	m_bAllowInvert = bAllowInvert;
+
+	return TrackHandle(nHandle, pWnd, point, pWndClipTo);
+}
+
+void CCHRectTracker::Draw(CDC* pDC) const
+{
+	// set initial DC state
+	VERIFY(pDC->SaveDC() != 0);
+#ifndef _AFX_NO_GDITRANSFORM_SUPPORT
+	pDC->SetMapMode(MM_TEXT);
+	pDC->SetViewportOrg(0, 0);
+	pDC->SetWindowOrg(0, 0);
+#endif // !_AFX_NO_GDITRANSFORM_SUPPORT
+	// get normalized rectangle
+	CRect rect = m_rect;
+	rect.NormalizeRect();
+
+	CPen* pOldPen = NULL;
+	CBrush* pOldBrush = NULL;
+	CGdiObject* pTemp;
+	int nOldROP;
+
+	CPen pen;
+	//pen.CreatePen(PS_DOT, 1, RGB(255,255,255));
+	pen.CreatePen(PS_DOT, 1, RGB(255,0,0));
+
+	rect.InflateRect(+1, +1);   // borders are one pixel outside
+
+	// draw lines
+	if ((m_nStyle & (dottedLine|solidLine)) != 0)
+	{
+		if (m_nStyle & dottedLine)
+			pOldPen = pDC->SelectObject(&pen);
+			//pOldPen = (CPen*)pDC->SelectStockObject(WHITE_PEN);
+		else
+			pOldPen = (CPen*)pDC->SelectStockObject(BLACK_PEN);
+		pOldBrush = (CBrush*)pDC->SelectStockObject(NULL_BRUSH);
+		nOldROP = pDC->SetROP2(R2_COPYPEN);
+	
+		// rect
+		pDC->Rectangle(rect.left, rect.top, rect.right, rect.bottom);
+
+		// cross line
+		if ((m_nStyle & (crossLine)) != 0)
+		{
+			pDC->MoveTo(rect.left+rect.Width()/2, rect.top);
+			pDC->LineTo(rect.left+rect.Width()/2, rect.bottom);
+			pDC->MoveTo(rect.left, rect.top+rect.Height()/2);
+			pDC->LineTo(rect.right, rect.top+rect.Height()/2);
+		}
+
+		// x line
+		if ((m_nStyle & (xLine)) != 0)
+		{
+			pDC->MoveTo(rect.left, rect.top);
+			pDC->LineTo(rect.right, rect.bottom);
+			pDC->MoveTo(rect.right, rect.top);
+			pDC->LineTo(rect.left, rect.bottom);
+		}
+
+		pDC->SetROP2(nOldROP);
+	}
+
+
+#ifndef _WIN32_WCE // unsupported win32 api call to UnrealizeObject
+	// if hatchBrush is going to be used, need to unrealize it
+	if ((m_nStyle & (hatchInside|hatchedBorder)) != 0)
+		UnrealizeObject(_afxHatchBrush);
+#endif // !_WIN32_WCE
+
+	// hatch inside
+	if ((m_nStyle & hatchInside) != 0)
+	{
+		pTemp = pDC->SelectStockObject(NULL_PEN);
+		if (pOldPen == NULL)
+			pOldPen = (CPen*)pTemp;
+		pTemp = pDC->SelectObject(CBrush::FromHandle(_afxHatchBrush));
+		if (pOldBrush == NULL)
+			pOldBrush = (CBrush*)pTemp;
+		pDC->SetBkMode(TRANSPARENT);
+		nOldROP = pDC->SetROP2(R2_MASKNOTPEN);
+		pDC->Rectangle(rect.left+1, rect.top+1, rect.right, rect.bottom);
+		pDC->SetROP2(nOldROP);
+	}
+
+	// draw hatched border
+	if ((m_nStyle & hatchedBorder) != 0)
+	{
+		pTemp = pDC->SelectObject(CBrush::FromHandle(_afxHatchBrush));
+		if (pOldBrush == NULL)
+			pOldBrush = (CBrush*)pTemp;
+		pDC->SetBkMode(OPAQUE);
+		CRect rectTrue;
+		GetTrueRect(&rectTrue);
+		pDC->PatBlt(rectTrue.left, rectTrue.top, rectTrue.Width(),
+			rect.top-rectTrue.top, 0x000F0001 /* Pn */);
+		pDC->PatBlt(rectTrue.left, rect.bottom,
+			rectTrue.Width(), rectTrue.bottom-rect.bottom, 0x000F0001 /* Pn */);
+		pDC->PatBlt(rectTrue.left, rect.top, rect.left-rectTrue.left,
+			rect.Height(), 0x000F0001 /* Pn */);
+		pDC->PatBlt(rect.right, rect.top, rectTrue.right-rect.right,
+			rect.Height(), 0x000F0001 /* Pn */);
+	}
+
+	// draw resize handles
+	if ((m_nStyle & (resizeInside|resizeOutside)) != 0)
+	{
+		UINT mask = GetHandleMask();
+		for (int i = 0; i < 8; ++i)
+		{
+			if (mask & (1<<i))
+			{
+				GetHandleRect((TrackerHit)i, &rect);
+				pDC->FillSolidRect(rect, RGB(255, 255, 255));
+			}
+		}
+	}
+
+	// cleanup pDC state
+	if (pOldPen != NULL)
+		pDC->SelectObject(pOldPen);
+	if (pOldBrush != NULL)
+		pDC->SelectObject(pOldBrush);
+	VERIFY(pDC->RestoreDC(-1));
+}
+
+BOOL CCHRectTracker::TrackHandle(int nHandle, CWnd* pWnd, CPoint point, CWnd* pWndClipTo)
+{
+	ASSERT(nHandle >= 0);
+	ASSERT(nHandle <= 8);   // handle 8 is inside the rect
+
+	// don't handle if capture already set
+	if (::GetCapture() != NULL)
+		return FALSE;
+
+	AfxLockTempMaps();  // protect maps while looping
+
+	ASSERT(!m_bFinalErase);
+
+	// save original width & height in pixels
+	int nWidth = m_rect.Width();
+	int nHeight = m_rect.Height();
+
+	// set capture to the window which received this message
+	pWnd->SetCapture();
+	ASSERT(pWnd == CWnd::GetCapture());
+	pWnd->UpdateWindow();
+	if (pWndClipTo != NULL)
+		pWndClipTo->UpdateWindow();
+	CRect rectSave = m_rect;
+
+	// find out what x/y coords we are supposed to modify
+	int *px, *py;
+	int xDiff, yDiff;
+	GetModifyPointers(nHandle, &px, &py, &xDiff, &yDiff);
+	xDiff = point.x - xDiff;
+	yDiff = point.y - yDiff;
+
+	// get DC for drawing
+	CDC* pDrawDC;
+	if (pWndClipTo != NULL)
+	{
+		// clip to arbitrary window by using adjusted Window DC
+		pDrawDC = pWndClipTo->GetDCEx(NULL, DCX_CACHE);
+	}
+	else
+	{
+		// otherwise, just use normal DC
+		pDrawDC = pWnd->GetDC();
+	}
+	ENSURE_VALID(pDrawDC);
+
+	CRect rectOld;
+	BOOL bMoved = FALSE;
+
+	// get messages until capture lost or cancelled/accepted
+	for (;;)
+	{
+		MSG msg;
+		VERIFY(::GetMessage(&msg, NULL, 0, 0));
+
+		if (CWnd::GetCapture() != pWnd)
+			break;
+
+		switch (msg.message)
+		{
+			// handle movement/accept messages
+		case WM_LBUTTONUP:
+			{
+				if (pWnd)
+					pWnd->SendMessage(WM_LBUTTONUP, static_cast<WPARAM>(0), MAKELPARAM(0, 0));
+			}
+		case WM_MOUSEMOVE:
+			rectOld = m_rect;
+			// handle resize cases (and part of move)
+			if (px != NULL)
+				*px = GET_X_LPARAM(msg.lParam) - xDiff;
+			if (py != NULL)
+				*py = GET_Y_LPARAM(msg.lParam) - yDiff;
+
+			// handle move case
+			if (nHandle == hitMiddle)
+			{
+				m_rect.right = m_rect.left + nWidth;
+				m_rect.bottom = m_rect.top + nHeight;
+			}
+			// allow caller to adjust the rectangle if necessary
+			AdjustRect(nHandle, &m_rect);
+
+			// only redraw and callback if the rect actually changed!
+			m_bFinalErase = (msg.message == WM_LBUTTONUP);
+			if (!rectOld.EqualRect(&m_rect) || m_bFinalErase)
+			{
+				if (bMoved)
+				{
+					m_bErase = TRUE;
+					DrawTrackerRect(&rectOld, pWndClipTo, pDrawDC, pWnd);
+				}
+				OnChangedRect(rectOld);
+				if (msg.message != WM_LBUTTONUP)
+					bMoved = TRUE;
+			}
+			if (m_bFinalErase)
+				goto ExitLoop;
+
+			if (!rectOld.EqualRect(&m_rect))
+			{
+				m_bErase = FALSE;
+				DrawTrackerRect(&m_rect, pWndClipTo, pDrawDC, pWnd);
+			}
+			break;
+
+			// handle cancel messages
+		case WM_KEYDOWN:
+			if (msg.wParam != VK_ESCAPE)
+				break;
+		case WM_RBUTTONDOWN:
+			if (bMoved)
+			{
+				m_bErase = m_bFinalErase = TRUE;
+				DrawTrackerRect(&m_rect, pWndClipTo, pDrawDC, pWnd);
+			}
+			m_rect = rectSave;
+			goto ExitLoop;
+
+		case WM_LBUTTONDBLCLK:
+			if (pWnd)
+				pWnd->SendMessage(WM_LBUTTONDBLCLK, static_cast<WPARAM>(0), MAKELPARAM(0, 0));
+			break;
+			// just dispatch rest of the messages
+		default:
+			DispatchMessage(&msg);
+			break;
+		}
+	}
+
+ExitLoop:
+	if (pWndClipTo != NULL)
+		pWndClipTo->ReleaseDC(pDrawDC);
+	else
+		pWnd->ReleaseDC(pDrawDC);
+	ReleaseCapture();
+
+	AfxUnlockTempMaps(FALSE);
+
+	// restore rect in case bMoved is still FALSE
+	if (!bMoved)
+		m_rect = rectSave;
+	m_bFinalErase = FALSE;
+	m_bErase = FALSE;
+
+	// return TRUE only if rect has changed
+	return !rectSave.EqualRect(&m_rect);
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/CHRectTracker.h b/ReviewHistory/ReveiwHistory/CHRectTracker.h
new file mode 100644
index 0000000..2a7d67b
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CHRectTracker.h
@@ -0,0 +1,26 @@
+#pragma once
+#include "afxext.h"
+
+
+enum CHStyleFlags
+{
+//	solidLine = 1, dottedLine = 2, hatchedBorder = 4,
+//	resizeInside = 8, resizeOutside = 16, hatchInside = 32,
+
+	crossLine = 64, xLine = 128,
+};
+
+
+class AFX_EXT_CLASS CCHRectTracker : public CRectTracker
+{
+public:
+	CCHRectTracker();
+	CCHRectTracker(LPCRECT lpSrcRect, UINT nStyle);
+	BOOL Track(CWnd* pWnd, CPoint point, BOOL bAllowInvert, CWnd* pWndClipTo=NULL);
+	BOOL TrackRubberBand(CWnd* pWnd, CPoint point, BOOL bAllowInvert);
+	void Draw(CDC* pDC) const;
+	virtual ~CCHRectTracker(void);
+
+protected:
+	BOOL TrackHandle(int nHandle, CWnd* pWnd, CPoint point, CWnd* pWndClipTo);
+};
diff --git a/ReviewHistory/ReveiwHistory/CHTrackerView.cpp b/ReviewHistory/ReveiwHistory/CHTrackerView.cpp
new file mode 100644
index 0000000..b8eabda
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CHTrackerView.cpp
@@ -0,0 +1,124 @@
+// CHTrackerView.cpp : 구현 파일입니다.
+//
+
+#include "stdafx.h"
+#include "CHTrackerView.h"
+#include "CHBufferDC.h"
+
+// CCHTrackerView
+
+IMPLEMENT_DYNAMIC(CCHTrackerView, CCHImageView)
+
+CCHTrackerView::CCHTrackerView() : CCHImageView()
+{
+	m_rectTracker.m_rect = CRect(0,0,0,0);
+	m_rectTracker.m_nStyle = CRectTracker::dottedLine | CRectTracker::resizeOutside;
+	m_rectTracker.m_sizeMin = CSize(8,8);
+	m_bDrawTracker = FALSE;
+}
+
+
+CCHTrackerView::CCHTrackerView(CWnd *pParentWnd) : CCHImageView(pParentWnd)
+{
+	m_rectTracker.m_rect = CRect(0,0,0,0);
+	m_rectTracker.m_nStyle = CRectTracker::dottedLine | CRectTracker::resizeOutside;
+	m_rectTracker.m_sizeMin = CSize(8,8);
+	m_bDrawTracker = FALSE;
+}
+
+CCHTrackerView::~CCHTrackerView()
+{
+
+}
+
+
+BEGIN_MESSAGE_MAP(CCHTrackerView, CCHImageView)
+	ON_WM_SETCURSOR()
+	ON_WM_PAINT()
+	ON_WM_LBUTTONDOWN()
+END_MESSAGE_MAP()
+
+
+
+// CCHTrackerView 메시지 처리기입니다.
+
+BOOL CCHTrackerView::GetTrackerRect(CRect& rtRect)
+{
+	if (m_rectTracker.m_rect.Width()<0 || m_rectTracker.m_rect.Height()<0)
+	{
+		return FALSE;
+	}
+
+	rtRect = m_rectTracker.m_rect;
+
+	return TRUE;
+}
+
+void CCHTrackerView::SetTrackerRect(const CRect& rtRect)
+{
+	m_rectTracker.m_rect = rtRect;
+	Invalidate(TRUE);
+}
+
+void CCHTrackerView::ClearTrackerRect()
+{
+	m_rectTracker.m_rect = CRect(0,0,0,0);
+	Invalidate(TRUE);
+}
+
+BOOL CCHTrackerView::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
+{
+	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
+	if (m_rectTracker.SetCursor(this, nHitTest))
+		return TRUE;
+
+	return CCHImageView::OnSetCursor(pWnd, nHitTest, message);
+}
+
+void CCHTrackerView::OnPaint()
+{
+
+	CCHBufferDC *pDC = new CCHBufferDC(this); // device context for painting
+
+	UpdateImageView(pDC);
+
+	m_rectTracker.m_rect.NormalizeRect();
+
+	if (m_rectTracker.m_rect.left>0 && m_rectTracker.m_rect.right<GetWidth())
+	{
+		if (m_rectTracker.m_rect.top>0 && m_rectTracker.m_rect.bottom<GetHeight())
+		{
+			m_rectTracker.Draw(pDC);
+		}
+	}
+
+	delete pDC;
+	
+}
+
+void CCHTrackerView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
+
+	if (m_pParentWnd==NULL || !GetImageExist()) return;
+
+	if (point.x > -1 && point.x < GetScaleWidth() &&
+		point.y > -1 && point.y < GetScaleHeight() )
+	{
+		if (m_rectTracker.HitTest(point) < 0)
+		{
+			// just to demonstrate CRectTracker::TrackRubberBand
+			if (m_rectTracker.TrackRubberBand(this, point, TRUE))
+			{
+				Invalidate();
+			}
+		}
+		else if (m_rectTracker.Track(this, point, TRUE))
+		{
+			Invalidate();
+		}
+	}
+
+	CCHImageView::OnLButtonDown(nFlags, point);
+}
+
diff --git a/ReviewHistory/ReveiwHistory/CHTrackerView.h b/ReviewHistory/ReveiwHistory/CHTrackerView.h
new file mode 100644
index 0000000..e83d077
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CHTrackerView.h
@@ -0,0 +1,35 @@
+#pragma once
+
+
+// CCHTrackerView
+#include "CHImageView.h"
+
+class AFX_EXT_CLASS CCHTrackerView : public CCHImageView
+{
+	DECLARE_DYNAMIC(CCHTrackerView)
+
+public:
+	CCHTrackerView();
+	CCHTrackerView(CWnd *pParentWnd);
+	virtual ~CCHTrackerView();
+
+	BOOL GetTrackerRect(CRect& rtRect);
+	void SetTrackerRect(const CRect& rtRect);
+	void ClearTrackerRect();
+
+protected:
+	// tracker
+	BOOL			m_bDrawTracker;
+	CPoint			m_ptTrackerStart;
+	CCHRectTracker	m_rectTracker;
+
+protected:
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+	afx_msg void OnPaint();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+};
+
+
diff --git a/ReviewHistory/ReveiwHistory/CameraImageView.cpp b/ReviewHistory/ReveiwHistory/CameraImageView.cpp
new file mode 100644
index 0000000..dc8370e
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CameraImageView.cpp
@@ -0,0 +1,985 @@
+癤�// CameraImageView.cpp : 援ы쁽 �뙆�씪�엯�땲�떎.
+//
+
+#include "stdafx.h"
+#include "ReveiwHistory.h"
+#include "CameraImageView.h"
+#include "CHImageControls/CHBufferDC.h"
+
+using namespace CHImageControls;
+// CDlgReviewCamera ���솕 �긽�옄�엯�땲�떎.
+
+// CCameraImageView
+
+IMPLEMENT_DYNAMIC(CCameraImageView, CWnd)
+
+CCameraImageView::CCameraImageView(CWnd *pParentWnd)
+{
+	m_strViewName	= _T("");
+	m_pParentWnd	= pParentWnd;
+
+	m_nHScroll		= 0;
+	m_nVScroll		= 0;
+
+	m_nMaxHScroll	= 0;
+	m_nMaxVScroll	= 0;
+	m_nDrawMode		= 0;
+
+	m_rtClientRect	= CRect(0,0,0,0);
+	m_bDrawCenterLine = FALSE;
+	m_bDrawRuler		= FALSE;
+	m_bDrawViewName = FALSE;
+	m_nViewBand		= BandTypeColor;
+	m_nDrawMode		= 1;
+
+	m_dWidthScale	= 1.0; 
+	m_dHeightScale	= 1.0;
+	m_nScaleWidth	= 0;
+	m_nScaleHeight	= 0;
+
+	m_dResolution	= 1.0; // um
+	m_dRulerGab		= 100.0; //um
+
+	m_pCIV2P		= NULL;
+
+	InitializeCriticalSection(&m_csImageData);
+
+}
+
+CCameraImageView::~CCameraImageView()
+{
+	DeleteCriticalSection(&m_csImageData);
+}
+
+// CCameraImageView 硫붿떆吏� 泥섎━湲곗엯�땲�떎.
+BEGIN_MESSAGE_MAP(CCameraImageView, CWnd)
+
+	ON_COMMAND(IDR_LOAD_IMAGE, &CCameraImageView::OnLoadImage)
+	ON_COMMAND(IDR_SAVE_IMAGE, &CCameraImageView::OnSaveImage)
+	ON_COMMAND(IDR_CENTER_LINE, &CCameraImageView::OnCenterLine)
+	ON_COMMAND(IDR_RULER, &CCameraImageView::OnRuler)
+	ON_COMMAND(IDR_VIEW_ORIGIN, &CCameraImageView::OnViewOrigin)
+	ON_COMMAND(IDR_VIEW_FIT, &CCameraImageView::OnViewFit)
+
+	ON_COMMAND(IDR_VIEW_COLOR, &CCameraImageView::OnViewColor)
+	ON_COMMAND(IDR_VIEW_GRAY,&CCameraImageView::OnViewGray)
+	ON_COMMAND(IDR_VIEW_RED, &CCameraImageView::OnViewRed)
+	ON_COMMAND(IDR_VIEW_GREEN, &CCameraImageView::OnViewGreen)
+	ON_COMMAND(IDR_VIEW_BLUE, &CCameraImageView::OnViewBlue)
+
+	ON_WM_PAINT()
+	ON_WM_MOUSEMOVE()
+	ON_WM_LBUTTONDOWN()
+	ON_WM_LBUTTONUP()
+	ON_WM_RBUTTONDOWN()
+	ON_WM_RBUTTONUP()
+	ON_WM_DESTROY()
+	ON_WM_HSCROLL()
+	ON_WM_VSCROLL()
+	ON_WM_LBUTTONDBLCLK()
+	ON_WM_RBUTTONDBLCLK()
+	ON_WM_CREATE()
+END_MESSAGE_MAP()
+
+
+// CCHImageView 硫붿떆吏� 泥섎━湲곗엯�땲�떎.
+void CCameraImageView::OnPaint()
+{
+	CCHBufferDC *pDC = new CCHBufferDC(this); // device context for painting
+
+	UpdateImageView(pDC);
+
+	delete pDC;
+}
+
+void CCameraImageView::UpdateImageView(CDC *pDC)
+{
+	CRect rtCurrentRect , rtSourceRect;
+	GetClientRect(rtCurrentRect);
+
+	//DrawText(CPoint(30, 30), RGB(255,255,0), _T("Defect Size"));
+
+	if (GetImageExist())
+	{
+		if (m_rtClientRect!=rtCurrentRect) SetDrawMode(m_nDrawMode);
+
+		int nSrcWidth = GetWidth();
+		int nSrcHeight = GetHeight();
+
+		int nWidth = int(double(nSrcWidth) * m_dWidthScale + 0.5);
+		int nHeight = int(double(nSrcHeight) * m_dHeightScale + 0.5);
+
+		if (m_nScaleWidth!=nWidth || m_nScaleHeight!=nHeight) 
+		{
+			SetDrawMode(m_nDrawMode);
+		}
+
+		switch(m_nDrawMode)
+		{
+		case 0:
+			pDC->SelectStockObject(GRAY_BRUSH);
+			pDC->Rectangle(rtCurrentRect);
+			ShowImage(pDC->m_hDC, 0, 0, rtCurrentRect.Width(), rtCurrentRect.Height(), m_nHScroll, m_nVScroll);
+			break;
+
+		case 1:
+			ShowImage(pDC->m_hDC, rtCurrentRect);
+			break;
+		}
+	}
+	else
+	{
+		pDC->SelectStockObject(GRAY_BRUSH);
+		pDC->Rectangle(rtCurrentRect);
+	}
+
+	if (m_bDrawCenterLine) DrawCenterLine(pDC);
+
+	if (m_bDrawRuler)	DrawRuler(pDC);
+
+	if (m_bDrawViewName) DrawViewName(pDC);
+
+}
+
+void CCameraImageView::OnMouseMove(UINT nFlags, CPoint point)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	if (m_pParentWnd==NULL) return;
+
+	CRect rect;
+	this->GetClientRect(rect);
+
+	point.x += m_nHScroll;
+	point.y += m_nVScroll;
+
+	if (point.x > 0 && point.x < this->GetScaleWidth()-1 &&
+		point.y > 0 && point.y < this->GetScaleHeight()-1 && nFlags == MK_LBUTTON)
+	{
+		m_pParentWnd->SendMessage(WM_MOUSEMOVE, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));
+	}
+
+	__super::OnMouseMove(nFlags, point);
+}
+
+void CCameraImageView::OnLButtonDown(UINT nFlags, CPoint point)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	if (m_pParentWnd==NULL) return;
+
+	CRect rect;
+	this->GetClientRect(rect);
+
+	point.x += m_nHScroll;
+	point.y += m_nVScroll;
+
+	if (point.x > 0 && point.x < this->GetScaleWidth()-1 &&
+		point.y > 0 && point.y < this->GetScaleHeight()-1 )
+	{
+		m_pParentWnd->SendMessage(WM_LBUTTONDOWN, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));
+	}
+
+	__super::OnLButtonDown(nFlags, point);
+}
+
+void CCameraImageView::OnLButtonUp(UINT nFlags, CPoint point)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	if (m_pParentWnd==NULL) return;
+
+	CRect rect;
+	this->GetClientRect(rect);
+
+	point.x += m_nHScroll;
+	point.y += m_nVScroll;
+
+	if (point.x > 0 && point.x < this->GetScaleWidth()-1 &&
+		point.y > 0 && point.y < this->GetScaleHeight()-1 )
+	{
+		m_pParentWnd->SendMessage(WM_LBUTTONUP, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));
+	}
+
+	__super::OnLButtonUp(nFlags, point);
+}
+
+void CCameraImageView::OnLButtonDblClk(UINT nFlags, CPoint point)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	if (m_pParentWnd==NULL) return;
+
+	point.x += m_nHScroll;
+	point.y += m_nVScroll;
+	m_pParentWnd->SendMessage(WM_LBUTTONDBLCLK, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));
+
+	__super::OnLButtonDblClk(nFlags, point);
+}
+
+void CCameraImageView::OnRButtonDown(UINT nFlags, CPoint point)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	CMenu menu;
+	CMenu popMenu;
+	menu.CreateMenu();  // 理쒖긽�쐞 堉덈� 硫붾돱
+	popMenu.CreatePopupMenu();  // �뙘�뾽硫붾돱
+	BOOL bAddMenu = FALSE;
+
+	popMenu.AppendMenu(MF_STRING, IDR_LOAD_IMAGE, _T("Load Image"));
+	popMenu.AppendMenu(MF_STRING, IDR_SAVE_IMAGE, _T("Save Image"));  // �깋�긽�쓽 �꽌釉뚮찓�돱 異붽�
+	popMenu.AppendMenu(MF_SEPARATOR);
+	popMenu.AppendMenu(MF_STRING, IDR_CENTER_LINE, _T("Center Line"));
+	popMenu.AppendMenu(MF_STRING, IDR_RULER, _T("Ruler"));
+	popMenu.AppendMenu(MF_SEPARATOR);
+	popMenu.AppendMenu(MF_STRING, IDR_VIEW_ORIGIN, _T("1:1 View"));
+	popMenu.AppendMenu(MF_STRING, IDR_VIEW_FIT, _T("Fit View"));  // �깋�긽�쓽 �꽌釉뚮찓�돱 異붽�
+	popMenu.AppendMenu(MF_SEPARATOR);
+	popMenu.AppendMenu(MF_STRING, IDR_VIEW_COLOR, _T("Color"));
+	popMenu.AppendMenu(MF_STRING, IDR_VIEW_GRAY, _T("Gray"));
+	popMenu.AppendMenu(MF_STRING, IDR_VIEW_RED, _T("Red"));
+	popMenu.AppendMenu(MF_STRING, IDR_VIEW_GREEN, _T("Green"));
+	popMenu.AppendMenu(MF_STRING, IDR_VIEW_BLUE, _T("Blue"));
+
+	// 硫붾돱 �긽�깭 泥섎━
+	if (m_bDrawCenterLine)
+	{
+		popMenu.CheckMenuItem(IDR_CENTER_LINE, MF_CHECKED);
+	}
+
+	if (m_bDrawRuler)
+	{
+		popMenu.CheckMenuItem(IDR_RULER, MF_CHECKED);
+	}
+
+
+	switch(m_nDrawMode)
+	{
+	case 0:
+		popMenu.CheckMenuItem(IDR_VIEW_ORIGIN, MF_CHECKED);
+		break;
+	case 1:
+		popMenu.CheckMenuItem(IDR_VIEW_FIT, MF_CHECKED);
+		break;
+	}
+
+	// 硫붾돱 �긽�깭 泥섎━
+	switch(m_nViewBand)
+	{
+	case BandTypeRed:
+		popMenu.CheckMenuItem(IDR_VIEW_RED, MF_CHECKED);
+		break;
+	case BandTypeGreen:
+		popMenu.CheckMenuItem(IDR_VIEW_GREEN, MF_CHECKED);
+		break;
+	case BandTypeBlue:
+		popMenu.CheckMenuItem(IDR_VIEW_BLUE, MF_CHECKED);
+		break;
+	case BandTypeGray:
+		popMenu.CheckMenuItem(IDR_VIEW_GRAY, MF_CHECKED);
+		break;
+	default:
+		popMenu.CheckMenuItem(IDR_VIEW_COLOR, MF_CHECKED);
+		break;
+	}
+
+	// 而⑦뀓�뒪�듃 硫붾돱 �샇異�
+	CRect rect;
+	GetWindowRect(rect);
+	int nX = rect.left + point.x; 
+	int nY = rect.top + point.y; 
+
+	popMenu.TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON, nX, nY, this);
+
+	if (m_pParentWnd==NULL) return;
+	point.x += m_nHScroll;
+	point.y += m_nVScroll;
+	m_pParentWnd->SendMessage(WM_RBUTTONDOWN, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));
+
+	__super::OnRButtonDown(nFlags, point);
+}
+
+void CCameraImageView::OnRButtonUp(UINT nFlags, CPoint point)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	if (m_pParentWnd==NULL) return;
+
+	point.x += m_nHScroll;
+	point.y += m_nVScroll;
+	m_pParentWnd->SendMessage(WM_RBUTTONUP, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));
+
+	__super::OnRButtonUp(nFlags, point);
+}
+
+void CCameraImageView::OnRButtonDblClk(UINT nFlags, CPoint point)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	if (m_pParentWnd==NULL) return;
+
+	point.x += m_nHScroll;
+	point.y += m_nVScroll;
+	m_pParentWnd->SendMessage(WM_RBUTTONDBLCLK, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));
+
+	__super::OnRButtonDblClk(nFlags, point);
+}
+
+
+void CCameraImageView::SetDrawCenterLine(BOOL bDraw)
+{
+	m_bDrawCenterLine = bDraw; 
+	Invalidate(TRUE);
+}
+
+void CCameraImageView::SetDrawRuler(BOOL bDraw)
+{
+	m_bDrawRuler = bDraw; 
+	Invalidate(TRUE);
+}
+
+void CCameraImageView::SetDrawMode(int nDrawMode)
+{ 
+	m_nDrawMode = nDrawMode; 
+
+	GetClientRect(m_rtClientRect);
+
+	m_nScaleWidth = GetScaleWidth();
+	m_nScaleHeight = GetScaleHeight();
+
+	switch(m_nDrawMode)
+	{
+	case 0:
+		if (m_rtClientRect.Width() >= m_nScaleWidth)
+		{
+			m_nMaxHScroll = 0;
+		}
+		else
+		{
+			m_nMaxHScroll = m_nScaleWidth - (m_rtClientRect.Width()+17);
+			if (m_nMaxHScroll < 0) 
+			{
+				m_nMaxHScroll = 0;
+			}
+			else
+			{
+				m_nMaxHScroll += 17;
+			}
+		}
+
+		if (m_rtClientRect.Height() >= m_nScaleHeight)
+		{
+			m_nMaxVScroll = 0;
+		}
+		else
+		{
+			m_nMaxVScroll = m_nScaleHeight - (m_rtClientRect.Height()+17);
+			if (m_nMaxVScroll < 0) 
+			{
+				m_nMaxVScroll = 0;
+			}
+			else
+			{
+				m_nMaxVScroll += 17;
+			}
+
+		}
+		break;
+
+	case 1:
+		m_nMaxHScroll = m_nMaxVScroll = 0;	
+		break;
+	}
+
+	m_nHScroll = m_nVScroll = 0;
+
+	SetScrollRange(SB_HORZ, 0, m_nMaxHScroll);
+	SetScrollRange(SB_VERT, 0, m_nMaxVScroll);	
+	SetScrollPos(SB_HORZ, m_nHScroll);
+	SetScrollPos(SB_VERT, m_nVScroll);
+
+}
+
+void CCameraImageView::DrawCenterLine(CDC *pDC)
+{
+	if (m_rtClientRect.Width()==0 || m_rtClientRect.Height()==0) return;
+
+	CRect rtDraw = m_rtClientRect;
+	if (m_nDrawMode==0)
+	{
+		rtDraw.right = GetWidth();
+		rtDraw.bottom = GetHeight();
+	}
+
+	rtDraw.left -= m_nHScroll;
+	rtDraw.top -= m_nVScroll;
+	rtDraw.right -= m_nHScroll;
+	rtDraw.bottom -= m_nVScroll;
+
+	CPen pen, *pPen=NULL;
+	pen.CreatePen(PS_SOLID, 2, RGB(255,0,0));
+	pDC->SelectObject(&pen);
+
+	//pDC->SelectStockObject(WHITE_PEN);
+
+	// center line
+	pDC->MoveTo( (rtDraw.Width()/2)-m_nHScroll,	0);
+	pDC->LineTo((rtDraw.Width()/2)-m_nHScroll,	rtDraw.Height());
+	pDC->MoveTo(0,					(rtDraw.Height()/2)-m_nVScroll);
+	pDC->LineTo(rtDraw.Width(),		(rtDraw.Height()/2)-m_nVScroll);
+}
+
+void CCameraImageView::DrawRuler(CDC *pDC)
+{
+	if (m_dRulerGab==0.0) return;
+
+	if (m_rtClientRect.Width()==0 || m_rtClientRect.Height()==0) return;
+
+	CRect rtDraw = m_rtClientRect;
+	if (m_nDrawMode==0)
+	{
+		rtDraw.right = GetWidth();
+		rtDraw.bottom = GetHeight();
+	}
+
+	rtDraw.left -= m_nHScroll;
+	rtDraw.top -= m_nVScroll;
+	rtDraw.right -= m_nHScroll;
+	rtDraw.bottom -= m_nVScroll;
+
+	pDC->SelectStockObject(WHITE_PEN);
+
+	CFont font;
+	VERIFY(font.CreateFont(
+		10,                        // nHeight
+		5,                         // nWidth
+		0,                         // nEscapement
+		0,                         // nOrientation
+		FW_NORMAL,                 // nWeight
+		FALSE,                     // bItalic
+		FALSE,                     // bUnderline
+		0,                         // cStrikeOut
+		ANSI_CHARSET,              // nCharSet
+		OUT_DEFAULT_PRECIS,        // nOutPrecision
+		CLIP_DEFAULT_PRECIS,       // nClipPrecision
+		DEFAULT_QUALITY,           // nQuality
+		DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
+		_T("Arial")));                 // lpszFacename
+
+	// Do something with the font just created...
+	CFont* def_font = pDC->SelectObject(&font);
+	pDC->SetTextColor(RGB(255,255,255));
+	pDC->SetBkMode(TRANSPARENT);
+
+	// ruler 
+	double dResX = m_dResolution / m_dWidthScale;
+	double dResY = m_dResolution / m_dHeightScale;
+	double dGabX = m_dRulerGab / dResX; // um
+	double dGabY = m_dRulerGab / dResY; // um
+
+	if (dGabX<=0.0 || dGabY<=0.0) return;
+
+	double dWidth = GetScaleWidth();
+	double dHeight = GetScaleHeight();
+
+	double dCenterX = rtDraw.Width()/2;
+	double dCenterY = rtDraw.Height()/2;
+
+	// x direction
+	CString strValue = _T("");
+	strValue.Format(_T("%.1lf um"), m_dRulerGab);
+	pDC->TextOut(-m_nHScroll+5, rtDraw.Height()/2-m_nVScroll+5, strValue);
+	for (double dPos=dCenterX; dPos>=0.0; dPos-=dGabX)
+	{
+		pDC->MoveTo((int)(dPos+0.5)-m_nHScroll, -m_nVScroll);
+		pDC->LineTo((int)(dPos+0.5)-m_nHScroll, -m_nVScroll+6);
+	}
+	for (double dPos=dCenterX+dGabX; dPos<dWidth; dPos+=dGabX)
+	{
+		pDC->MoveTo((int)(dPos+0.5)-m_nHScroll, -m_nVScroll);
+		pDC->LineTo((int)(dPos+0.5)-m_nHScroll, -m_nVScroll+6);
+	}
+
+	// y direction
+	strValue.Format(_T("%.1lf um"), m_dRulerGab);
+	pDC->TextOut(rtDraw.Width()/2-m_nHScroll+5, 5-m_nVScroll, strValue);
+	for (double dPos=dCenterY; dPos>0.0; dPos-=dGabY)
+	{
+		pDC->MoveTo(-m_nHScroll, (int)(dPos+0.5)-m_nVScroll);
+		pDC->LineTo(-m_nHScroll+6, (int)(dPos+0.5)-m_nVScroll);
+	}
+	for (double dPos=dCenterY+dGabY; dPos<dHeight; dPos+=dGabY)
+	{
+		pDC->MoveTo(-m_nHScroll, (int)(dPos+0.5)-m_nVScroll);
+		pDC->LineTo(-m_nHScroll+6, (int)(dPos+0.5)-m_nVScroll);
+	}
+}
+
+BOOL CCameraImageView::SetViewImage(CCHImageData* pImageData)
+{
+	if (pImageData==NULL) return FALSE;
+
+	if (!pImageData->GetImageExist()) return FALSE;
+
+	EnterCriticalSection(&m_csImageData);
+
+	this->CopyImageFrom(pImageData);
+
+	LeaveCriticalSection(&m_csImageData);
+
+	this->Invalidate(TRUE);
+
+	return TRUE;
+}
+
+BOOL CCameraImageView::SetOriginImage(CCHImageData* pImageData)
+{
+	if (pImageData==NULL) return FALSE;
+
+	if (!pImageData->GetImageExist()) return FALSE;
+
+	EnterCriticalSection(&m_csImageData);
+
+	m_OriginImage.CopyImageFrom(pImageData);
+
+	m_OriginImage.GetBandImage(m_nViewBand, this);
+
+	LeaveCriticalSection(&m_csImageData);
+
+	this->Invalidate(TRUE);
+
+	return TRUE;
+}
+
+BOOL CCameraImageView::SetOriginImage(int nWidth, int nHeight, int nChannels, int nWidthStep, const BYTE* pBuffer)
+{
+	if (nWidth<0 || nHeight<0 || nChannels<0 || pBuffer==NULL) return FALSE;
+
+	EnterCriticalSection(&m_csImageData);
+
+	if (nWidth!=m_OriginImage.GetWidth() || nHeight!=m_OriginImage.GetHeight() || nChannels!=m_OriginImage.GetChannels())
+	{
+		if (m_OriginImage.CreateImage(nWidth, nHeight, 8, nChannels)==FALSE) 
+		{
+			LeaveCriticalSection(&m_csImageData);
+			return FALSE;
+		}
+	}
+
+	memcpy(m_OriginImage.GetImageBuffer(), pBuffer, nWidthStep*nHeight);
+
+	if (nChannels==1) m_nViewBand = BandTypeGray;
+
+	BOOL bResult = m_OriginImage.GetBandImage(m_nViewBand, this);
+
+	LeaveCriticalSection(&m_csImageData);
+
+	return bResult;
+}
+
+
+BOOL CCameraImageView::GetViewImage(CCHImageData* pImageData)
+{
+	if (pImageData==NULL) return FALSE;
+
+	EnterCriticalSection(&m_csImageData);
+	
+	BOOL bReturn = this->CopyImageTo(pImageData);
+
+	LeaveCriticalSection(&m_csImageData);
+
+	return bReturn;
+}
+
+BOOL CCameraImageView::GetOriginImage(CCHImageData* pImageData)
+{
+	if (pImageData==NULL) return FALSE;
+
+	EnterCriticalSection(&m_csImageData);
+
+	BOOL bReturn = m_OriginImage.CopyImageTo(pImageData);
+
+	LeaveCriticalSection(&m_csImageData);
+
+	return TRUE;
+}
+
+void  CCameraImageView::DrawViewName(CDC *pDC)
+{
+	CFont font;
+	VERIFY(font.CreateFont(
+		20,                        // nHeight
+		10,                         // nWidth
+		0,                         // nEscapement
+		0,                         // nOrientation
+		FW_NORMAL,                 // nWeight
+		FALSE,                     // bItalic
+		FALSE,                     // bUnderline
+		0,                         // cStrikeOut
+		ANSI_CHARSET,              // nCharSet
+		OUT_DEFAULT_PRECIS,        // nOutPrecision
+		CLIP_DEFAULT_PRECIS,       // nClipPrecision
+		DEFAULT_QUALITY,           // nQuality
+		DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
+		_T("Arial")));                 // lpszFacename
+
+	// Do something with the font just created...
+	CFont* def_font = pDC->SelectObject(&font);
+	pDC->SetTextColor(RGB(255,255,255));
+	pDC->SetBkMode(TRANSPARENT);
+
+	int nStrLength = (m_strViewName.GetLength() * 10);
+
+	pDC->TextOut(m_rtClientRect.Width() - nStrLength - 30, 5, m_strViewName);
+	pDC->SelectObject(def_font);
+}
+
+int	CCameraImageView::GetScaleWidth()
+{
+	CRect rect;
+	int nWidth = GetWidth();
+
+	switch(m_nDrawMode)
+	{
+	case 0:
+		m_dWidthScale = 1.0;
+		return nWidth;
+
+	case 1:
+		GetClientRect(rect);
+		if (nWidth!=0)
+			m_dWidthScale = double(rect.Width()) / double(nWidth);
+		return int(double(nWidth) * m_dWidthScale + 0.5);
+	}
+
+	return 0;
+}
+
+int	CCameraImageView::GetScaleHeight()
+{ 
+	CRect rect;
+	int nHeight = GetHeight();
+
+	switch(m_nDrawMode)
+	{
+	case 0:
+		m_dHeightScale = 1.0;
+		return nHeight;
+
+	case 1:
+		GetClientRect(rect);
+		if (nHeight!=0)
+			m_dHeightScale = double(rect.Height()) / double(nHeight);
+		return int(double(nHeight) * m_dHeightScale + 0.5);
+	}
+
+	return 0;
+}
+
+int	CCameraImageView::GetHScrollPos(void)
+{ 
+	return m_nHScroll; 
+}
+
+int	CCameraImageView::GetVScrollPos(void)	
+{ 
+	return m_nVScroll; 
+}
+
+void CCameraImageView::SetViewName(const CString strViewName)
+{ 
+	m_strViewName = strViewName; 
+}
+
+void CCameraImageView::SetParentWnd(CWnd* pParentWnd)			
+{ 
+	m_pParentWnd = pParentWnd; 
+}
+
+BOOL CCameraImageView::LoadImage(const CString& strFilename)
+{
+	if (!CCHImageData::LoadImage(strFilename)) 
+	{
+		m_nHScroll = m_nVScroll = 0;
+		m_nMaxHScroll = m_nMaxVScroll = 0;
+		SetScrollRange(SB_HORZ, 0, m_nMaxHScroll);
+		SetScrollRange(SB_VERT, 0, m_nMaxVScroll);
+		SetScrollPos(SB_HORZ, m_nHScroll);
+		SetScrollPos(SB_VERT, m_nVScroll);
+		return FALSE;
+	}
+
+	SetDrawMode(m_nDrawMode);
+
+	return TRUE;
+}
+
+void CCameraImageView::OnDestroy()
+{
+	__super::OnDestroy();
+}
+
+void CCameraImageView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	switch (nSBCode)
+	{
+	case SB_LEFT:      // Scroll to far left.
+		break;
+	case SB_RIGHT:      // Scroll to far right.
+		break;
+	case SB_ENDSCROLL:   // End scroll.
+		break;
+	case SB_LINELEFT:      // Scroll left.
+		if (m_nHScroll > 0)
+			m_nHScroll--;
+		break;
+	case SB_LINERIGHT:   // Scroll right.
+		if (m_nHScroll < m_nMaxHScroll)
+			m_nHScroll++;
+		break;
+	case SB_PAGELEFT:    // Scroll one page left.
+		if (5 < m_nMaxHScroll / 256)
+			m_nHScroll -= 20;//m_nHScroll -= 5;
+		else
+			m_nHScroll -= 10;//m_nHScroll -= m_nMaxHScroll / 256;
+
+		if (m_nHScroll < 0)
+			m_nHScroll = 0;
+		break;
+	case SB_PAGERIGHT:      // Scroll one page right.
+		if (5 < m_nMaxHScroll / 256)
+			m_nHScroll += 20;//m_nHScroll += 5;
+		else
+			m_nHScroll += 10;//m_nHScroll += m_nMaxHScroll / 256;
+
+		if (m_nHScroll > m_nMaxHScroll)
+			m_nHScroll = m_nMaxHScroll;
+		break;
+	case SB_THUMBPOSITION: // Scroll to absolute position. nPos is the position
+		break;
+	case SB_THUMBTRACK:   // Drag scroll box to specified position. nPos is the
+		m_nHScroll = nPos;
+		break;
+	}
+
+	// Set the new position of the thumb (scroll box).
+	SetScrollPos(SB_HORZ, m_nHScroll);
+
+	Invalidate(FALSE);
+
+	__super::OnHScroll(nSBCode, nPos, pScrollBar);
+}
+
+void CCameraImageView::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	switch (nSBCode)
+	{
+	case SB_BOTTOM:			// Scroll to bottom. 
+		break;
+	case SB_ENDSCROLL:		// End scroll.
+		break;
+	case SB_LINEDOWN:		// Scroll one line down.
+		if (m_nVScroll < m_nMaxVScroll)
+			m_nVScroll++;
+		break;
+	case SB_LINEUP:			// Scroll one line up. 
+		if (m_nVScroll > 0)
+			m_nVScroll--;
+		break;
+	case SB_PAGEDOWN:		// Scroll one page down. 
+		if (5 < m_nMaxVScroll / 256)
+			m_nVScroll += 20;//m_nVScroll += 5;
+		else
+			m_nVScroll += 10;//m_nVScroll += (m_nMaxVScroll / 256);
+
+		if (m_nVScroll > m_nMaxVScroll)
+			m_nVScroll = m_nMaxVScroll;
+		break;
+	case SB_PAGEUP:			// Scroll one page up.
+		if (5 < m_nMaxVScroll / 256)
+			m_nVScroll -= 20;//m_nVScroll -= 5;
+		else
+			m_nVScroll -= 10;//m_nVScroll -= (m_nMaxVScroll / 256);
+
+		if (m_nVScroll < 0)
+			m_nVScroll = 0;
+		break;
+	case SB_THUMBPOSITION:	// Scroll to the absolute position. The current position is provided in nPos. 
+		break;
+	case SB_THUMBTRACK:		// Drag scroll box to specified position. The current position is provided in nPos. 
+		m_nVScroll = nPos;
+		break;
+	case SB_TOP:			// Scroll to top. 
+		break;
+	}
+
+	// Set the new position of the thumb (scroll box).
+	SetScrollPos(SB_VERT, m_nVScroll);
+
+	Invalidate(FALSE);
+
+	__super::OnVScroll(nSBCode, nPos, pScrollBar);
+}
+
+
+void CCameraImageView::OnLoadImage()
+{
+	//CString szFilter = _T("All Files(*.*)|*.*||");
+	CString szFilter = _T("BMP(*.bmp)|*.bmp| JPG(*.jpg)|*.jpg| All Files(*.*)|*.*||");
+
+	CString strPath;
+	CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter);
+	dlg.m_ofn.lpstrTitle = _T("Load Image");
+
+	if(dlg.DoModal() == IDOK)
+	{
+		if (m_OriginImage.LoadImage(dlg.GetPathName()))
+		{
+			if (m_nViewBand==4)
+			{
+				m_OriginImage.CopyImageTo(this);
+			}
+			else
+			{
+				m_OriginImage.GetBandImage(m_nViewBand, this);
+			}
+
+			Invalidate(TRUE);
+		}
+	}
+}
+
+void CCameraImageView::OnSaveImage()
+{
+	CString szFilter = _T("BMP(*.bmp)|*.bmp| JPG(*.jpg)|*.jpg| All Files(*.*)|*.*||");
+
+	CString strPath;
+	CFileDialog dlg(FALSE, szFilter, NULL, OFN_HIDEREADONLY, szFilter);
+	dlg.m_ofn.lpstrTitle = _T("Save Image");
+
+	if(dlg.DoModal() == IDOK)
+	{
+		if (SaveImage(dlg.GetPathName()))
+		{
+
+		}
+	}
+}
+
+void CCameraImageView::OnCenterLine()
+{
+	m_bDrawCenterLine = !m_bDrawCenterLine;
+	Invalidate(TRUE);
+}
+
+void CCameraImageView::OnRuler()
+{
+	m_bDrawRuler = !m_bDrawRuler;
+	Invalidate(TRUE);
+}
+
+void CCameraImageView::OnViewOrigin()
+{
+	m_nDrawMode = 0;
+
+	SetDrawMode(m_nDrawMode);
+	Invalidate(TRUE);
+}
+
+void CCameraImageView::OnViewFit()
+{
+	m_nDrawMode = 1;
+
+	SetDrawMode(m_nDrawMode);
+	Invalidate(TRUE);
+}
+
+void CCameraImageView::OnViewColor()
+{
+	if (m_OriginImage.GetChannels()==1)
+	{
+		m_nViewBand = BandTypeGray;
+		return;
+	}
+
+	if (m_nViewBand == BandTypeColor) return;
+
+	if (m_OriginImage.CopyImageTo(this))
+	{
+		m_nViewBand = BandTypeColor;
+		Invalidate(TRUE);
+	}
+}
+
+void CCameraImageView::OnViewGray()
+{
+	if (m_nViewBand == BandTypeGray) return;
+
+	if (m_OriginImage.GetBandImage(BandTypeGray, this))
+	{
+		m_nViewBand = BandTypeGray;
+		Invalidate(TRUE);
+	}
+}
+
+void CCameraImageView::OnViewRed()
+{
+	if (m_OriginImage.GetChannels()==1)
+	{
+		m_nViewBand = BandTypeGray;
+		return;
+	}
+
+	if (m_nViewBand == BandTypeRed) return;
+
+	if (m_OriginImage.GetBandImage(BandTypeRed, this))
+	{
+		m_nViewBand = BandTypeRed;
+		Invalidate(TRUE);
+	}
+}
+
+void CCameraImageView::OnViewGreen()
+{
+	if (m_OriginImage.GetChannels()==1)
+	{
+		m_nViewBand = BandTypeGray;
+		return;
+	}
+
+	if (m_nViewBand == BandTypeGreen) return;
+
+	if (m_OriginImage.GetBandImage(BandTypeGreen, this))
+	{
+		m_nViewBand = BandTypeGreen;
+		Invalidate(TRUE);
+	}
+}
+
+void CCameraImageView::OnViewBlue()
+{
+	if (m_OriginImage.GetChannels()==1)
+	{
+		m_nViewBand = BandTypeGray;
+		return;
+	}
+
+	if (m_nViewBand == BandTypeBlue) return;
+
+	if (m_OriginImage.GetBandImage(BandTypeBlue, this))
+	{
+		m_nViewBand = BandTypeBlue;
+		Invalidate(TRUE);
+	}
+}
+
+void CCameraImageView::SetResolution(double dRes)
+{
+	if (dRes<0.0) return;
+
+	m_dResolution = dRes;
+}
+
+void CCameraImageView::SetRulerGab(double dGab)
+{
+	if (dGab<0.0) return;
+
+	m_dRulerGab = dGab;
+}
+
diff --git a/ReviewHistory/ReveiwHistory/CameraImageView.h b/ReviewHistory/ReveiwHistory/CameraImageView.h
new file mode 100644
index 0000000..8bf8388
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CameraImageView.h
@@ -0,0 +1,139 @@
+癤�#pragma once
+
+#include "CHImageControls/CHImageData.h"
+
+#define IDR_LOAD_IMAGE		9000
+#define IDR_SAVE_IMAGE		9001
+#define IDR_ONLY_SAVE_IMAGE	9002
+
+#define IDR_CENTER_LINE		9100
+#define IDR_RULER			9101
+#define IDR_ROI_RECT		9102
+#define IDR_CLEAR_ROI_RECT	9103
+#define IDR_SAVE_ROI_RECT	9104
+	
+#define IDR_VIEW_ORIGIN		9200
+#define IDR_VIEW_FIT		9201
+
+#define IDR_VIEW_COLOR		9300
+#define IDR_VIEW_GRAY		9301
+#define IDR_VIEW_RED		9302
+#define IDR_VIEW_BLUE		9303
+#define IDR_VIEW_GREEN		9304
+
+
+// CDlgHistory ���솕 �긽�옄�엯�땲�떎.
+interface ICameraImageView2Parent
+{
+	virtual void CIV2P_GetImagePathName(CString& strFilename) = 0;
+	virtual void CIV2P_ManualSimulation(CCHImageData* pImageData) = 0;
+};
+
+class CCameraImageView : public CWnd, public CCHImageData
+{
+	DECLARE_DYNAMIC(CCameraImageView)
+
+public:
+	CCameraImageView(CWnd *pParentWnd);
+	virtual ~CCameraImageView();
+	void SetCIV2P(ICameraImageView2Parent* pCIV2P)		{ m_pCIV2P = pCIV2P; }
+
+	BOOL GetViewImage(CCHImageData* pImageData);
+	BOOL GetOriginImage(CCHImageData* pImageData);
+	BOOL SetViewImage(CCHImageData* pImageData);
+	BOOL SetOriginImage(CCHImageData* pImageData);
+	BOOL SetOriginImage(int nWidth, int nHeight, int nChannels, int nWidthStep, const BYTE* pBuffer);
+
+	// getter
+	int		GetScaleWidth(void);
+	int		GetScaleHeight(void);
+	int		GetHScrollPos(void);
+	int		GetVScrollPos(void);
+	double	GetWidthScale()		{ return m_dWidthScale; }
+	double	GetHeightScale()	{ return m_dHeightScale; }
+
+	// setter
+	void	SetDrawObject(BOOL bDraw);
+	void	SetDrawMode(int nDrawMode);
+	void	SetViewName(const CString strViewName);
+	void	SetParentWnd(CWnd* pParentWnd);
+	void	SetDrawCenterLine(BOOL bDraw);
+	void	SetDrawRuler(BOOL bDraw);
+
+	void	SetResolution(double dRes);
+	void	SetRulerGab(double dGab);
+
+	BOOL	LoadImage(const CString& strFilename);
+
+protected:
+	void	UpdateImageView(CDC *pDC);
+	void	DrawCenterLine(CDC *pDC);
+	void	DrawRuler(CDC *pDC);
+	void	DrawViewName(CDC *pDC);
+
+	ICameraImageView2Parent*	m_pCIV2P;
+
+	CRITICAL_SECTION	m_csImageData;
+	CWnd				*m_pParentWnd;
+	CString				m_strViewName;
+	CCHImageData		m_OriginImage;
+
+	// pre draw info
+	int			m_nViewBand;
+	CRect		m_rtClientRect;
+	int			m_nScaleWidth;
+	int			m_nScaleHeight;
+	double		m_dWidthScale; 
+	double		m_dHeightScale;
+
+	// Scroll Pos
+	int			m_nVScroll;
+	int			m_nHScroll;
+	// Max Scroll Pos
+	int			m_nMaxVScroll;
+	int			m_nMaxHScroll;
+
+	// image draw
+	int			m_nDrawMode;
+	BOOL		m_bDrawViewName;
+
+	BOOL		m_bDrawCenterLine;
+	BOOL		m_bDrawRuler;
+	double		m_dRulerGab;
+	double		m_dResolution;
+
+protected:
+	DECLARE_MESSAGE_MAP()
+	afx_msg void OnLoadImage();
+	afx_msg void OnSaveImage();
+	afx_msg void OnCenterLine();
+	afx_msg void OnRuler();
+	afx_msg void OnViewOrigin();
+	afx_msg void OnViewFit();
+	afx_msg void OnViewColor();
+	afx_msg void OnViewGray();
+	afx_msg void OnViewRed();
+	afx_msg void OnViewGreen();
+	afx_msg void OnViewBlue();
+	afx_msg void OnDestroy();
+	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+	afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+
+	afx_msg void OnPaint();
+
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+
+	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
+	afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
+	
+public:
+	
+};
+
+// typedef std::vector<CCameraImageView*>					VectorCameraImageView;
+// typedef std::vector<CCameraImageView*>::iterator		VectorCameraImageViewIt;
diff --git a/ReviewHistory/ReveiwHistory/CustomizeReview.cpp b/ReviewHistory/ReveiwHistory/CustomizeReview.cpp
new file mode 100644
index 0000000..8eb3b22
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CustomizeReview.cpp
@@ -0,0 +1,84 @@
+#include "StdAfx.h"
+#include "CustomizeReview.h"
+#include "akCore/akFileDB.h"
+#include "akGridData.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+#define CUSTOMIZE_RECIPE_PATH "C:\\DIT_Review\\Recipe"
+
+CCustomizeReview::CCustomizeReview(void)
+{
+	m_bReadSuccess = FALSE;
+}
+
+CCustomizeReview::~CCustomizeReview(void)
+{
+	m_vecCustomizeReview.clear();
+}
+
+BOOL CCustomizeReview::openFile( char* pRecipeName )
+{
+	m_bReadSuccess = FALSE;
+	m_nCustomizePlanType = 0;
+	m_vecCustomizeReview.clear();
+
+	CString strFileName;
+	{
+		CString strRecipeFileName;
+		strRecipeFileName.Format("%s\\%s.rcp", CUSTOMIZE_RECIPE_PATH, pRecipeName);
+		if(PathFileExists(strRecipeFileName))
+		{
+			strFileName.Format("%s\\%s.cri", CUSTOMIZE_RECIPE_PATH, pRecipeName);
+		}
+		else
+		{
+			strFileName.Format("%s\\%s.cri", CUSTOMIZE_RECIPE_PATH, "Default");
+		}
+	}
+	
+
+	char* pFileName = strFileName.GetBuffer(0);
+	FILE* pf = fopen(pFileName, "r");
+	
+	if(pf == NULL)
+		return FALSE;
+	
+	std::vector<_CustomizeReview> vecCustomizeReview;
+	_CustomizeReview CustomizeReviewData;
+	char buffer[1024];
+
+	char* pReadPoint = NULL;
+	char *pStr;
+
+	CakParser akParser;
+	pStr = fgets(buffer, 1024, pf);
+	m_nCustomizePlanType = atoi(pStr); //customize type
+	while(!feof(pf))
+	{
+		pStr = fgets(buffer, 1024, pf);
+		
+		if(strlen(buffer) <= 0 || pStr == NULL)
+			break;
+
+		akParser.process(pStr, " \r\n\t,^");
+		if(akParser.getTokNum() <= 0) break;
+
+		CustomizeReviewData.m_nCustomizeDefectType = atoi( akParser.getTokStr(0) );
+		CustomizeReviewData.m_dCustomizeDefectPosXmm = atof( akParser.getTokStr(1) );
+		CustomizeReviewData.m_dCustomizeDefectPosYmm = atof( akParser.getTokStr(2) );
+		CustomizeReviewData.m_nCustomizeParam1 = atoi( akParser.getTokStr(3) );
+		CustomizeReviewData.m_nCustomizeParam2 = atoi( akParser.getTokStr(4) );
+		vecCustomizeReview.push_back(CustomizeReviewData);
+	}
+
+	fclose(pf);
+
+	m_vecCustomizeReview = vecCustomizeReview;
+	m_bReadSuccess = TRUE;
+	return TRUE;
+}
diff --git a/ReviewHistory/ReveiwHistory/CustomizeReview.h b/ReviewHistory/ReveiwHistory/CustomizeReview.h
new file mode 100644
index 0000000..e898cd4
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/CustomizeReview.h
@@ -0,0 +1,65 @@
+#pragma once
+
+#include <vector>
+
+struct _CustomizeReview
+{
+	int		m_nCustomizeDefectType	;//0:Location(User, Fiexed) Review, 1:reflower, 2:Wsi			
+	double	m_dCustomizeDefectPosXmm;  //mm 단위 x 코너 좌표 [김태현 2019/1/17]
+	double	m_dCustomizeDefectPosYmm;  //mm 단위 y 코너 좌표
+	int		m_nCustomizeParam1	;
+	int		m_nCustomizeParam2	;
+};
+
+class CCustomizeReview
+{
+public:
+	CCustomizeReview(void);
+	virtual ~CCustomizeReview(void);
+
+public:
+	BOOL openFile(char* pRecipeName);
+	BOOL IsRead() { return m_bReadSuccess; }
+	int GetCustomizeReviewNum() { return (int)m_vecCustomizeReview.size();}
+	_CustomizeReview* GetCustomizeReivew(int i) { return &m_vecCustomizeReview[i]; }
+	int	GetCustomizeType(){return m_nCustomizePlanType;};
+public:
+	CString					m_strCustomizeReviewRecipePath;
+
+	DWORD					m_dwMacroReadTime;
+
+protected:
+	char* getParsingData(char* pBuf, int nLen, CString* pOutData);
+	char* getParsingData(char* pBuf, int nLen, int* pOutData);
+
+protected:
+	BOOL m_bReadSuccess;
+	int m_nCustomizePlanType;
+	std::vector<_CustomizeReview> m_vecCustomizeReview;
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ReviewHistory/ReveiwHistory/DitGlassRawClient.cpp b/ReviewHistory/ReveiwHistory/DitGlassRawClient.cpp
new file mode 100644
index 0000000..c37e6e5
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/DitGlassRawClient.cpp
@@ -0,0 +1,223 @@
+#include "StdAfx.h"
+#include "DitGlassRawClient.h"
+
+CDitGlassRawClient::CDitGlassRawClient(void)
+: m_mxCommandProcess(FALSE, MUTEX_RAWMESSENGER)
+{
+	m_hMapBasicInfo = NULL;
+	m_hMapGlassData = NULL;
+
+	m_pGlassRawInfo = NULL;
+	m_pGlassRawData = NULL;
+
+	m_nLastCommandIdx = -1;
+}
+
+CDitGlassRawClient::~CDitGlassRawClient(void)
+{
+	if (m_hMapBasicInfo!=NULL)
+	{
+		::UnmapViewOfFile(m_hMapBasicInfo);
+		m_pGlassRawInfo = NULL;
+	}
+
+	if (m_hMapGlassData!=NULL)
+	{
+		::UnmapViewOfFile(m_hMapGlassData);
+		m_pGlassRawData = NULL;
+	}
+}
+
+BOOL CDitGlassRawClient::ConnectServer()
+{
+	if(isConnect()) return TRUE;
+
+	if(ConnectGlassRawInfo() == FALSE)
+	{
+		return FALSE;
+	}
+
+	if(ConnectGlassRawData() == FALSE)
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOL CDitGlassRawClient::ConnectGlassRawInfo()
+{
+	if(m_hMapBasicInfo == NULL)
+	{
+		m_hMapBasicInfo = ::OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,SHAREDMEMNAME_BASICINFO);
+
+		if (m_hMapBasicInfo)
+		{
+			m_pGlassRawInfo = (_grmDitGlassRawInfo*)::MapViewOfFile(m_hMapBasicInfo, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(_grmDitGlassRawInfo));
+		}
+
+		if(m_hMapBasicInfo == NULL || m_pGlassRawInfo == NULL)
+		{
+			if (m_hMapBasicInfo!=NULL)
+			{
+				::UnmapViewOfFile(m_hMapBasicInfo);
+				m_pGlassRawInfo = NULL;
+			}
+			m_pGlassRawInfo = NULL;
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+BOOL CDitGlassRawClient::ConnectGlassRawData()
+{
+	SIZE_T nGlassRawSharedSize = m_pGlassRawInfo->m_nGlassRawDataSize;
+
+	if(m_hMapGlassData == NULL)
+	{
+		m_hMapGlassData = ::OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,SHAREDMEMNAME_GLASSDATA);
+
+		if (m_hMapGlassData)
+		{
+			m_pGlassRawData = (char*)::MapViewOfFile(m_hMapGlassData, FILE_MAP_ALL_ACCESS, 0, 0, nGlassRawSharedSize);
+		}
+
+		if(m_hMapGlassData == NULL || m_pGlassRawData == NULL)
+		{
+			if (m_hMapGlassData != NULL)
+			{
+				::UnmapViewOfFile(m_hMapGlassData);
+				m_pGlassRawData = NULL;
+			}
+			m_pGlassRawData = NULL;
+			return FALSE;
+		}
+	}
+	m_pGlassData  = (_grmGlassData*)&m_pGlassRawData[m_pGlassRawInfo->m_nGlassDataPoint];
+	m_pBlockData  = (_grmBlockData*)&m_pGlassRawData[m_pGlassRawInfo->m_nBlockDataPoint];
+	m_pCellData   = (_grmCellData*)&m_pGlassRawData[m_pGlassRawInfo->m_nCellDataPoint];
+	m_pDefectData = (_grmDefectData*)&m_pGlassRawData[m_pGlassRawInfo->m_nDefectDataPoint];
+	m_pStackData = (_grmDefectData*)&m_pGlassRawData[m_pGlassRawInfo->m_nStackDataPoint];
+
+	return TRUE;
+}
+
+BOOL CDitGlassRawClient::WriteAOIRawFile()
+{
+	return SetCommand(grcWriteRaw);
+}
+
+BOOL CDitGlassRawClient::WriteAOIRawBinFile()
+{
+	return SetCommand(grcWriteBin);
+}
+
+BOOL CDitGlassRawClient::ReadAOIRawBinFile()
+{
+	return SetCommand(grcReadBin);
+}
+
+BOOL CDitGlassRawClient::WriteReviewRawBinFile()
+{
+	return SetCommand(grcReviewWriteBIn);
+}
+
+BOOL CDitGlassRawClient::SetCommand( emGlassRawCommand nCmd )
+{
+	if(m_pGlassRawInfo == NULL) return FALSE;
+
+	m_mxCommandProcess.Lock();
+
+	int nCmdId = (m_pGlassRawInfo->m_nCommandIdxWrite+1) % COMMAND_MAXCOUNT;
+
+	if(m_pGlassRawInfo->m_nCommandIdxRead == nCmdId)//占쏙옙占쏙옙 占쏙옙占쌕는곤옙占쏙옙 占쏙옙큘占쏙옙 占쏙옙占쌜곤옙 占싼뱄옙占쏙옙 占쏙옙占쌀다는곤옙!! [占쏙옙占쏙옙占쏙옙 2018/11/12]
+	{
+		m_pGlassRawInfo->m_nCommandIdxRead++;//占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占� 占싹놂옙占쏙옙 占쏙옙占쏙옙占싼댐옙. [占쏙옙占쏙옙占쏙옙 2018/11/12]
+	}
+
+	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nCommand = (short)nCmd;
+	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].strParam;
+	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nResult = -1; //-1占쏙옙占쏙옙占쏙옙, 0占쏙옙占쏙옙, 1占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/13]
+
+
+	m_nLastCommandIdx = m_pGlassRawInfo->m_nCommandIdxWrite = nCmdId;
+
+	m_mxCommandProcess.Unlock();
+
+	return TRUE;
+}
+
+emAOIProcStep CDitGlassRawClient::GetProcessStep()
+{
+	if(isConnect() == FALSE) return APS_None;
+
+	if(m_pGlassRawInfo)
+	{
+		return m_pGlassRawInfo->m_ClientProcStep;
+	}
+
+	return APS_None;
+}
+
+BOOL CDitGlassRawClient::SetGlassLoading()
+{
+	if(isConnect() == FALSE) return FALSE;
+	m_pGlassRawInfo->m_ClientProcStep = APS_GlassLoading;
+	m_pGlassData->m_bStackRead = FALSE;
+	return SetCommand(grcSequenceGlassLoading);
+}
+
+BOOL CDitGlassRawClient::SetInspectEnd()
+{
+	if(isConnect() == FALSE) return FALSE;
+	m_pGlassRawInfo->m_ClientProcStep = APS_InspectEnd;
+	return SetCommand(grcSequenceInspectEnd);
+}
+
+BOOL CDitGlassRawClient::SetReviewStart()
+{
+	if(isConnect() == FALSE) return FALSE;
+	m_pGlassRawInfo->m_ClientProcStep = APS_ReviewStart;
+	return SetCommand(grcSequenceReviewStart);
+}
+
+BOOL CDitGlassRawClient::SetReviewEnd()
+{
+	if(isConnect() == FALSE) return FALSE;
+	m_pGlassRawInfo->m_ClientProcStep = APS_ReviewEnd;
+	return SetCommand(grcSequenceReviewEnd);
+}
+
+BOOL CDitGlassRawClient::SetReviewComtomize()
+{
+	if(isConnect() == FALSE) return FALSE;
+	m_pGlassRawInfo->m_ClientProcStep = APS_CustomReviewRead;
+	return SetCommand(grcSequenceCustomReviewDataRead);
+}
+
+void CDitGlassRawClient::RemoveReviewDefects()
+{
+	int nDefectNum = m_pGlassData->m_nDefectNum;
+	int nRightDefectNum = 0;//占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占십울옙 占쏙옙치占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	int nDefectDeleteNum = 0;
+	for(int i=nDefectNum-1; i>=0; i--)
+	{
+		if(m_pDefectData[i].m_ReviewDefect.m_nPlanType > 0 &&
+			m_pDefectData[i].m_ReviewDefect.m_nPlanType != 1000	)
+		{
+			nDefectDeleteNum++;
+			if(nRightDefectNum)
+			{
+				memcpy(&m_pDefectData[i], &m_pDefectData[i+1], sizeof(_grmDefectData)*nRightDefectNum);
+			}
+		}
+		else
+		{
+			nRightDefectNum++;
+		}
+	}
+
+	m_pGlassData->m_nDefectNum = nDefectNum-nDefectDeleteNum;
+}
diff --git a/ReviewHistory/ReveiwHistory/DitGlassRawClient.h b/ReviewHistory/ReveiwHistory/DitGlassRawClient.h
new file mode 100644
index 0000000..82a185a
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/DitGlassRawClient.h
@@ -0,0 +1,66 @@
+#pragma once
+
+#include "DitGlassRawStruct.h"
+
+class CDitGlassRawClient
+{
+public:
+	CDitGlassRawClient(void);
+	~CDitGlassRawClient(void);
+
+public:
+	BOOL ConnectServer();
+	BOOL isConnect(){return m_hMapBasicInfo == NULL || m_hMapGlassData == NULL ? FALSE : TRUE;};
+
+	emAOIProcStep GetProcessStep();
+
+	BOOL SetGlassLoading();
+	BOOL SetInspectEnd();
+
+	BOOL SetReviewStart();
+	BOOL SetReviewEnd();
+
+	BOOL SetReviewComtomize();
+
+	void RemoveReviewDefects();//AOI占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싹곤옙, 占쏙옙占썰에占쏙옙 占쏙옙占쏙옙占쏙옙 User 혹占쏙옙 Reflow 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싼댐옙.
+
+	_grmDitMemInfo*	GetGlassMeminfo(){return (_grmDitMemInfo*)m_pGlassRawInfo;};
+	_grmGlassData*	GetGlassData(){return m_pGlassData;};
+	_grmBlockData*		GetBlockData(){return m_pBlockData;};
+	_grmCellData*	GetCellData(int nIndex){return &m_pCellData[nIndex];};
+	_grmDefectData*	GetDefectData(int nIndex){return &m_pDefectData[nIndex];};
+	_grmDefectData*	GetStackData(int nIndex) { return &m_pStackData[nIndex];};
+
+	//占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占� [占쏙옙占쏙옙占쏙옙 2018/11/12]
+	BOOL WriteAOIRawFile();
+
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占싱너몌옙 占쏙옙占승뤄옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/12]
+	BOOL WriteAOIRawBinFile(); 
+
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占싱너몌옙 占싻깍옙 
+	BOOL ReadAOIRawBinFile();
+
+	BOOL WriteReviewRawBinFile();
+
+protected:
+	BOOL ConnectGlassRawInfo();
+	BOOL ConnectGlassRawData();
+	BOOL SetCommand(emGlassRawCommand nCmd);
+
+protected:
+	_grmGlassData*  m_pGlassData;
+	_grmBlockData*		m_pBlockData;
+	_grmCellData*   m_pCellData;
+	_grmDefectData* m_pDefectData;
+	_grmDefectData* m_pStackData;
+
+protected:
+	HANDLE		m_hMapBasicInfo;
+	HANDLE		m_hMapGlassData;
+	_grmDitGlassRawInfo* m_pGlassRawInfo;
+	char*		m_pGlassRawData;
+
+	CMutex		m_mxCommandProcess;
+	int			m_nLastCommandIdx;
+
+};
diff --git a/ReviewHistory/ReveiwHistory/DitGlassRawServer.cpp b/ReviewHistory/ReveiwHistory/DitGlassRawServer.cpp
new file mode 100644
index 0000000..85f4cab
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/DitGlassRawServer.cpp
@@ -0,0 +1,183 @@
+#include "StdAfx.h"
+#include "DitGlassRawServer.h"
+
+CDitGlassRawServer::CDitGlassRawServer(void)
+: m_mxCommandProcess(FALSE, MUTEX_RAWMESSENGER)
+{
+	m_hMapBasicInfo = NULL;
+	m_hMapGlassData = NULL;
+
+	m_pGlassRawInfo = NULL;
+	m_pGlassRawData = NULL;
+
+	m_nLastCommandIdx = -1;
+}
+
+CDitGlassRawServer::~CDitGlassRawServer(void)
+{
+	if (m_hMapBasicInfo!=NULL)
+	{
+		::UnmapViewOfFile(m_hMapBasicInfo);
+		m_pGlassRawInfo = NULL;
+	}
+
+	if (m_hMapGlassData!=NULL)
+	{
+		::UnmapViewOfFile(m_hMapGlassData);
+		m_pGlassRawData = NULL;
+	}
+}
+
+
+BOOL CDitGlassRawServer::CreateServer( int nCellNum /*= 100*/, int nDefectNum /*= 2000*/ )
+{
+	if(CreateGlassRawInfo() == FALSE)
+	{
+		return FALSE;
+	}
+
+
+	if(sizeof(_grmGlassData) != m_pGlassRawInfo->m_nSizeOfGlassData
+		|| sizeof(_grmBlockData) != m_pGlassRawInfo->m_nSizeOfBlockData
+		|| sizeof(_grmCellData) != m_pGlassRawInfo->m_nSizeOfCellData
+		|| sizeof(_grmDefectData) != m_pGlassRawInfo->m_nSizeOfDefectData
+		|| sizeof(_grmDefectData) != m_pGlassRawInfo->m_nSizeOfStackData)
+	{
+		return FALSE;
+	}
+
+	m_pGlassRawInfo->m_nGlassMaxDataNum = 1;
+	m_pGlassRawInfo->m_nBlockMaxDataNum = 1;
+	m_pGlassRawInfo->m_nCellMaxDataNum = nCellNum;
+	m_pGlassRawInfo->m_nDefectMaxDataNum = nDefectNum;
+	m_pGlassRawInfo->m_nStackMaxDataNum = nDefectNum;
+	
+	m_pGlassRawInfo->m_nGlassRawDataSize;
+	{
+		int nDataNum = 0;
+
+		m_pGlassRawInfo->m_nGlassDataPoint = nDataNum;
+		nDataNum += m_pGlassRawInfo->m_nSizeOfGlassData + m_pGlassRawInfo->m_nSizeOfGlassData%4;
+
+		m_pGlassRawInfo->m_nBlockDataPoint = nDataNum;
+		nDataNum += m_pGlassRawInfo->m_nSizeOfBlockData + m_pGlassRawInfo->m_nSizeOfBlockData%4;
+		
+		m_pGlassRawInfo->m_nCellDataPoint = nDataNum;
+		nDataNum += (m_pGlassRawInfo->m_nSizeOfCellData + m_pGlassRawInfo->m_nSizeOfCellData%4)*nCellNum;
+		
+		m_pGlassRawInfo->m_nDefectDataPoint = nDataNum;
+		nDataNum += (m_pGlassRawInfo->m_nSizeOfDefectData + m_pGlassRawInfo->m_nSizeOfDefectData%4)*nDefectNum;
+
+		m_pGlassRawInfo->m_nStackDataPoint = nDataNum;
+		nDataNum += (m_pGlassRawInfo->m_nSizeOfStackData + m_pGlassRawInfo->m_nSizeOfStackData % 4)*nDefectNum;
+		
+		m_pGlassRawInfo->m_nGlassRawDataSize = nDataNum;
+	}
+	
+
+	if(CreateGlassRawData() == FALSE)
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+
+BOOL CDitGlassRawServer::CreateGlassRawInfo()
+{
+	if(m_hMapBasicInfo == NULL)
+	{
+		BOOL bCreateMem = TRUE;
+
+		m_hMapBasicInfo = ::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE
+			, 0, sizeof(_grmDitGlassRawInfo), SHAREDMEMNAME_BASICINFO);
+
+		if (::GetLastError() == ERROR_ALREADY_EXISTS)
+		{
+			m_hMapBasicInfo = ::OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,SHAREDMEMNAME_BASICINFO);
+			bCreateMem = FALSE;
+		}
+
+		if (m_hMapBasicInfo)
+		{
+			m_pGlassRawInfo = (_grmDitGlassRawInfo*)::MapViewOfFile(m_hMapBasicInfo, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(_grmDitGlassRawInfo));
+		}
+
+		if(m_hMapBasicInfo == NULL || m_pGlassRawInfo == NULL)
+		{
+			if (m_hMapBasicInfo!=NULL)
+			{
+				::UnmapViewOfFile(m_hMapBasicInfo);
+				m_pGlassRawInfo = NULL;
+			}
+			m_pGlassRawInfo = NULL;
+			return FALSE;
+		}
+
+		//0으로 초기화
+		if(bCreateMem && m_pGlassRawInfo)
+		{
+			ZeroMemory(m_pGlassRawInfo,sizeof(_grmDitGlassRawInfo));
+			
+			m_pGlassRawInfo->m_nSizeOfGlassData  = sizeof(_grmGlassData) ;
+			m_pGlassRawInfo->m_nSizeOfBlockData =  sizeof(_grmBlockData);
+			m_pGlassRawInfo->m_nSizeOfCellData = sizeof(_grmCellData);
+			m_pGlassRawInfo->m_nSizeOfDefectData = sizeof(_grmDefectData);
+			m_pGlassRawInfo->m_nSizeOfStackData = sizeof(_grmDefectData);
+
+			int bytealign = m_pGlassRawInfo->m_nSizeOfGlassData%4;
+		}
+		
+	}
+
+	
+
+	return TRUE;
+}
+
+BOOL CDitGlassRawServer::CreateGlassRawData()
+{
+	int nGlassRawSharedSize = (int)(m_pGlassRawInfo->m_nGlassRawDataSize);
+
+	if(m_hMapGlassData == NULL)
+	{
+		BOOL bCreateMem = TRUE;
+
+		m_hMapGlassData = ::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE
+			, 0, nGlassRawSharedSize, SHAREDMEMNAME_GLASSDATA);
+
+		if (::GetLastError() == ERROR_ALREADY_EXISTS)
+		{
+			m_hMapGlassData = ::OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,SHAREDMEMNAME_GLASSDATA);
+			bCreateMem = FALSE;
+		}
+
+		if (m_hMapGlassData)
+		{
+			m_pGlassRawData = (char*)::MapViewOfFile(m_hMapGlassData, FILE_MAP_ALL_ACCESS, 0, 0, nGlassRawSharedSize);
+		}
+
+		if(m_hMapGlassData == NULL || m_pGlassRawData == NULL)
+		{
+			if (m_hMapGlassData != NULL)
+			{
+				::UnmapViewOfFile(m_hMapGlassData);
+				m_pGlassRawData = NULL;
+			}
+			m_pGlassRawData = NULL;
+			return FALSE;
+		}
+
+		//0으로 초기화
+		if(bCreateMem && m_pGlassRawData) ZeroMemory(m_pGlassRawData,sizeof(char)*nGlassRawSharedSize);
+	}
+	
+	m_pGlassData  = (_grmGlassData*)&m_pGlassRawData[m_pGlassRawInfo->m_nGlassDataPoint];
+	m_pBlockData  = (_grmBlockData*)&m_pGlassRawData[m_pGlassRawInfo->m_nBlockDataPoint];
+	m_pCellData   = (_grmCellData*)&m_pGlassRawData[m_pGlassRawInfo->m_nCellDataPoint];
+	m_pDefectData = (_grmDefectData*)&m_pGlassRawData[m_pGlassRawInfo->m_nDefectDataPoint];
+	m_pStackData = (_grmDefectData*)&m_pGlassRawData[m_pGlassRawInfo->m_nStackDataPoint];
+
+	return TRUE;
+}
diff --git a/ReviewHistory/ReveiwHistory/DitGlassRawServer.h b/ReviewHistory/ReveiwHistory/DitGlassRawServer.h
new file mode 100644
index 0000000..cda09f0
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/DitGlassRawServer.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include "DitGlassRawStruct.h"
+
+
+
+class CDitGlassRawServer
+{
+public:
+	CDitGlassRawServer(void);
+	~CDitGlassRawServer(void);
+
+public:
+	BOOL CreateServer(int nCellNum = 200, int nDefectNum = 12000);
+
+	_grmGlassData*	GetGlassData(){return m_pGlassData;};
+	_grmBlockData*		GetBlockData(){return m_pBlockData;};
+	_grmCellData*	GetCellData(int nIndex){return &m_pCellData[nIndex];};
+	_grmDefectData*	GetDefectData(int nIndex){return &m_pDefectData[nIndex];};
+	_grmDefectData*	GetStackData(int nIndex) { return &m_pStackData[nIndex]; };
+
+	_grmDitGlassRawInfo* GetGlassRawInfo(){return m_pGlassRawInfo;};
+
+protected:
+	BOOL CreateGlassRawInfo();
+	BOOL CreateGlassRawData();
+
+protected:
+	_grmGlassData*  m_pGlassData;
+	_grmBlockData*		m_pBlockData;
+	_grmCellData*   m_pCellData;
+	_grmDefectData* m_pDefectData;
+	_grmDefectData* m_pStackData;
+
+
+protected:
+	HANDLE		m_hMapBasicInfo;
+	HANDLE		m_hMapGlassData;
+	_grmDitGlassRawInfo* m_pGlassRawInfo;
+	char*		m_pGlassRawData;
+
+	CMutex		m_mxCommandProcess;
+	int			m_nLastCommandIdx;
+
+};
diff --git a/ReviewHistory/ReveiwHistory/DitGlassRawStruct.h b/ReviewHistory/ReveiwHistory/DitGlassRawStruct.h
new file mode 100644
index 0000000..e84fb29
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/DitGlassRawStruct.h
@@ -0,0 +1,745 @@
+#pragma once
+
+#define SHAREDMEMNAME_BASICINFO _T("DIT.GLASSRAWSYSTEM.SHAREDMEM.BASICINFO")
+#define SHAREDMEMNAME_GLASSDATA	_T("DIT.GLASRAWSYSTEM.SHAREDMEM.GLASSDATA")
+#define MUTEX_RAWMESSENGER		_T("MUTEX_RAWMESSENGER_IPC")
+
+#define COMMAND_MAXCOUNT 8
+
+#define RAWMESSENGER_MAXCAMNUM 30
+#define RAWMESSENGER_MAXSCANNUM 20
+
+#define MAX_ZONE_NUM 16
+
+namespace ditRaw
+{
+	enum ReviewPlanType
+	{
+		RPT_Review = 0,
+		RPT_User,
+		RTP_WSI,
+		RTP_PlanMeasure,
+		RTP_Reflow,
+		RTP_WsiReflow,
+		RTP_UserWsi,
+		RPT_AOICustom = 1000,
+	};
+};
+enum emAOIProcStep
+{
+	APS_None = 0,
+
+	//AOI
+	APS_GlassLoading, 
+	APS_InspectEnd,
+	//Review
+	APS_CustomReviewRead,
+	APS_ReviewStart,
+	APS_ReviewEnd,
+
+	RPS_StepNum
+};
+
+struct _grmGlassData
+{
+	void clear()
+	{
+		memset(this, 0, sizeof(_grmGlassData));
+	}
+
+	//Glass 占쏙옙占쏙옙
+	char m_strFileName[64];
+	char m_strPath[256];
+
+	int m_nCellNum;
+	int m_nDefectNum;
+
+	int m_nOriginDirection;				//{ GD_LeftTop = 0, GD_RightTop = 1, GD_LeftBottom = 10, GD_RightBottom = 11 };
+	int m_nConerCutDirection;
+	int	m_nScanCoordinateY;				//占쏙옙占썩가 0占싱몌옙 占싹뱄옙, 1占싱몌옙 Scan占쏙옙占쏙옙占쏙옙 y占쏙옙(占쏙옙 scan占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙, offline 占쏙옙占쏙옙 占쏙옙占쏙옙)
+
+	int m_nGlassSizeWidth;
+	int m_nGlassSizeHeight;
+
+	//占쏙옙占쏙옙占쏙옙占쏙옙
+	char m_strLine[32];
+	char m_strEquipType[32];			
+	char m_strEquipID[32];				
+	char m_strStepID[32];			
+	char m_strOperID[32];				
+
+	CTime	m_tmGlassLoading;			//3. START_TIME
+	CTime	m_tmInspectionStart;			//3. START_TIME
+	CTime	m_tmInspectionEND;			//4. END_TIME
+	CTime	m_tmReviewLoading;
+	CTime	m_tmReviewEnd;
+
+	//占썩본 占쏙옙占쏙옙占쏙옙占쏙옙
+	char m_strGlassID[32];				//Glass ID
+	char m_strPPID[32];					
+	char m_strEPPID[32];				
+	char m_strLotID[32];				//LOT_ID
+	char m_strSLotID[32];				//SLOT_ID
+	char m_strRecipeName[32];			//RECIPE_NAME								
+	char m_strGlassJudge[32];			//GLASS_JUDGE
+	char m_strGlassCode[32];			//Grade or Code
+	char m_strProductID[16];			//4. PRODUCT_ID
+
+	//VCR
+	int m_nVcrResultCode;
+	char m_strVCRResult[32];
+	char m_strVCRGlassID[32];
+
+
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	int			m_nDefectNumSizeSmall;
+	int			m_nDefectNumSizeMid;
+	int			m_nDefectNumSizeLarge;
+	int			m_nDefectNumSizeHuge;
+	int			m_nDefectNumSizeUltra;
+
+	int			m_nDefectNumLocActive;
+	int			m_nDefectNumLocPad;
+	int			m_nDefectNumLocCrack;
+	int			m_nDefectNumLocBM;
+
+	int			m_nDefectNumTypeTB;
+	int			m_nDefectNumTypeTW;
+	int			m_nDefectNumTypeRB;
+	int			m_nDefectNumTypeRW;
+	int			m_nDefectNumTypeMD;
+	int			m_nDefectNumTypeCD;
+	int			m_nDefectNumTypeMC;
+
+	int			m_nDefectNumJudgeOKWhite;
+	int			m_nDefectNumJudgeOKBlack;
+	int			m_nDefectNumJudgeNG;
+	int			m_nDefectNumJudgeRW;
+	int			m_nDefectNumJudgeRP;
+	int			m_nDefectNumJudgeRV;
+	int			m_nDefectNumJudgeTR;
+	int			m_nDefectNumJudgePR;
+
+	int			m_nDefectNumStackTD;
+	int			m_nDefectNumStackSD;
+	int			m_nDefectNumStackPD;
+	int			m_nDefectNumStackSP;
+
+
+	//카占쌨띰옙/占쏙옙캔 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
+	short		m_nCameraNum;
+	short		m_nScanNum;
+	unsigned char m_nGrayLevelAvg[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];		
+	unsigned char m_nGrayLevelMin[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];
+	unsigned char m_nGrayLevelMax[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];
+
+	//占쏙옙占쏙옙占� 占쏙옙占쏙옙 um[占쏙옙占쏙옙占쏙옙 2018/12/10]
+	double	m_nAlignCcdTheta;
+	double	m_nAlignCcdShitftX;
+	double	m_nAlignCcdShitftY;
+	double	m_nAlignPreTheta;
+	double	m_nAlignPreShitftX;
+	double	m_nAlignPreShitftY;
+	double	m_nAlignBasicTheta;
+	double	m_nAlignBasicShitftX;
+	double	m_nAlignBasicShitftY;
+	char	m_strAlignFirst[64];
+	char	m_strAlignSecond[64];
+// 	char	m_strAlignPath[256];
+
+	//CSOT占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
+	char m_strCassetteSequenceNo[16];
+	char m_strOwnerCode[16];			//2. OWNER_CODE
+	char m_strOwnerType[16];			//3. OWNER_TYPE
+
+	char m_strProcessID[21];			//5. PROCESS_ID
+	char m_strProductGroup[16];			//6. PRODUCT_GROUP
+	char m_strCSTID[16];				//8. CST_ID
+	char m_strPreProcessID[16];			//10.PRE_PROCESS_ID
+	char m_strPreEQPID[16];				//11.PRE_EQP_ID
+	char m_strPreChamerID[16];			//12.PRE_CHAMBER_ID
+	char m_strPreRecipeID[32];			//13.PRE_RECIPE_ID
+	char m_strGroupID[16];				//14.GROUP_ID
+	char m_cAutoSampleFlag;				//15.AUTOSAMPLEFLAG
+
+	// CPRJ占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	char m_strProdType[3];
+	char m_strBatchID[13];
+	char m_strPairHPanelID[13];
+	char m_strGlassThickNess[2];
+	char m_strCompCount[2];
+	char m_strGlassState[2];
+	char m_strInsFlag[2];
+	char m_strPanelPosition[2];
+	char m_strFlowHistory[2];
+	char m_strCount1[2];
+	char m_strCount2[2];
+
+	//Mura Data 0412 nwh
+	char m_strMaxAvgGray[12];
+	char m_strMaxPortion[12];
+
+
+     //1226NWH
+	char m_strReadingFlag[2]; 
+	BYTE m_nUniqueID[4];
+	int m_nSlot_No; 
+
+	BYTE m_nGlassDataBitSignal[4];
+	bool m_bJob_end;  
+
+	//201217 CJH - 占쏙옙占쏙옙 Defect Review 占쏙옙占쏙옙
+	int m_nReviewNum;
+	//201221 CJH - 占식쏙옙占쏙옙 Stack 占쏙옙占�
+	int m_nStackNum;
+	BOOL m_bStackRead;
+
+	//210203 CJH - CutOff 占쏙옙占� 占쏙옙占쏙옙 占쏙옙
+	int m_nCutOffDefectNum;
+	//210323 CJH - Server/Frame Shrink 占쏙옙占쏙옙 占쌩곤옙
+	char m_strShrinked[6];
+	//210326 CJH - RAW 占쌉뤄옙 Defect 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙肉⑼옙占�
+	BOOL m_bRawCutoff;
+
+};
+struct _grmBlockData
+{
+	void clear()
+	{
+		memset(this, 0, sizeof(_grmBlockData));
+	}
+	char m_strBlockID[16];				//1. BLOCK_ID
+	char m_cBlockJudgeAOI;				//2. BLOCK_JUDGE_AOI
+	char m_cBlockJudgeATS;				//4. BLOCK_JUDGE_ATS
+	char m_cBlockJudgeTEG;				//5. BLOCK_JUDGE_TEG
+	int m_nGlassIdDCR;					//22. GLASS_ID_DCR
+};
+struct _grmCellData
+{
+	void clear()
+	{
+		memset(this, 0, sizeof(_grmCellData));
+	}
+	int getTotalDefectNum(){return m_nDefectNumTypeTB+m_nDefectNumTypeTW+m_nDefectNumTypeRB+m_nDefectNumTypeRW; };
+	int						m_nCellID;							//1. PANEL_ID
+	short					m_nModelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占싸곤옙?
+
+	char					m_strCellName[32];
+	int						m_rectCellLeft;
+	int						m_rectCellTop;
+	int						m_rectCellRight;
+	int						m_rectCellBottom;
+
+	int/*Judgement*/		m_nJudgement;
+	int						m_nJudgeFlag;
+	int						m_nJudgeGlade;
+
+
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	int			m_nDefectNumSizeSmall;
+	int			m_nDefectNumSizeMid;
+	int			m_nDefectNumSizeLarge;
+	int			m_nDefectNumSizeHuge;
+	int			m_nDefectNumSizeUltra;
+
+	int			m_nDefectNumLocActive;
+	int			m_nDefectNumLocPad;
+	int			m_nDefectNumLocCrack;
+	int			m_nDefectNumLocBM;
+
+	int			m_nDefectNumTypeTB;
+	int			m_nDefectNumTypeTW;
+	int			m_nDefectNumTypeRB;
+	int			m_nDefectNumTypeRW;
+	int			m_nDefectNumTypeMD;
+	int			m_nDefectNumTypeCD;
+	int			m_nDefectNumTypeMC;
+
+	//Mura Data nwh 0404 
+	char		m_strProImage[32];
+	char		m_strAvgGray_0[12];
+	char		m_strPortion_0[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_0[12];
+	char		m_strAvgAmp_0[12];
+	char		m_strFFTVar_0[12];
+	char		m_strFFTVah_0[12];
+	char		m_strFFTVaq_0[12];
+	char		m_strFFTPK_0[12];
+
+	char		m_strAvgGray_1[12];
+	char		m_strPortion_1[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_1[12];
+	char		m_strAvgAmp_1[12];
+	char		m_strFFTVar_1[12];
+	char		m_strFFTVah_1[12];
+	char		m_strFFTVaq_1[12];
+	char		m_strFFTPK_1[12];
+
+	char		m_strAvgGray_2[12];
+	char		m_strPortion_2[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_2[12];
+	char		m_strAvgAmp_2[12];
+	char		m_strFFTVar_2[12];
+	char		m_strFFTVah_2[12];
+	char		m_strFFTVaq_2[12];
+	char		m_strFFTPK_2[12];
+
+	char		m_strAvgGray_3[12];
+	char		m_strPortion_3[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_3[12];
+	char		m_strAvgAmp_3[12];
+	char		m_strFFTVar_3[12];
+	char		m_strFFTVah_3[12];
+	char		m_strFFTVaq_3[12];
+	char		m_strFFTPK_3[12];
+
+	int			m_nDefectNumJudgeOKWhite;
+	int			m_nDefectNumJudgeOKBlack;
+	int			m_nDefectNumJudgeNG;
+	int			m_nDefectNumJudgeRW;
+	int			m_nDefectNumJudgeRP;
+	int			m_nDefectNumJudgeRV;
+	int			m_nDefectNumJudgeTR;
+	int			m_nDefectNumJudgePR;
+
+	int			m_nReflowResult[8];			// 0: Reflow X 1: Reflow OK 2: Reflow NG
+
+	// Filtering占쏙옙 Stack占쏙옙 占쏙옙
+	int			m_nDefectTDCount;
+	int			m_nDefectSDCount;
+	int			m_nDefectPDCount;
+	int			m_nDefectSPCount;
+
+	// Gate/Data 占쏙옙 占쏙옙占쏙옙
+	int			m_nGateNum;
+	int			m_nDataNum;
+
+	// 210129 CJH - Cell Origin 占쏙옙占쏙옙
+	int			m_nCellXDir;
+	int			m_nCellYDir;
+};
+
+struct _grmDefectReviewData
+{
+	void clear()
+	{
+		memset(this, 0, sizeof(_grmDefectReviewData));
+	}
+
+	//////////////////////////////////////////////////////////////////////////
+	//占쏙옙占썩서 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/1/19]
+	ditRaw::ReviewPlanType			m_nPlanType	;	
+	int			m_nResultCode;  //0:None, 1:Success
+	int			m_nShotIndex; //占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
+	int			m_nModuleIndex;
+	int			m_nMagnificIndex;
+	float		m_fManification;
+	float		m_fManificResoultion;
+	char		m_strRevImageName[256];
+	char		m_strRevImagePath[256];
+
+	//////////////////////////////////////////////////////////////////////////
+	// Measure 占쏙옙占쏙옙
+	int			m_nMeasure_Index;
+	int			m_nMeasure_ResultCode; //0:None, 1:Success
+	float		m_fMesure_ResultData[8];	// 0:Type, 1:ShiftX, 2:ShiftY
+
+	//////////////////////////////////////////////////////////////////////////
+	// WSI占쏙옙占쏙옙
+	int			m_nWsi_ResultCode; //0:None, 1:Success
+	int			m_nWsi_Type;									// 占쌉몌옙 / 占쏙옙占쏙옙
+	float		m_fWsi_ResultData[8];			// 0:Type, 1:Height(um), 2:Width
+	char		m_strWsi_2DImageFilename[256];
+	char		m_strWsi_3DImageFilename[256]; 
+	int			m_nWsiReflowPositionIndex;					// WsiReflowPositionIndex
+	int			m_nWsi_pReflowResultData[8];
+	double		m_dWsi_DamDistance;
+
+	double		m_dWsiMmMotorX;								// WSI 占쏙옙占쏙옙 占쏙옙표 20180223 HJH
+	double		m_dWsiMmMotorY;
+	float		m_fWsiManification;							// WSI 占쏙옙占쏙옙
+
+	//////////////////////////////////////////////////////////////////////////
+	// Reflow 占쏙옙占쏙옙	
+	int			m_nReflow_Index;
+	int			m_nReflow_ResultCode; //0:None, // 占쏙옙占쏙옙占쏙옙 Line占쏙옙 占쏙옙占쏙옙. 3 占싱몌옙 : DAM2 Reflow 占쏙옙占쏙옙, 4~5 : DAM1 Reflow 占쏙옙占쏙옙, 6 : no Reflow 占쏙옙占쏙옙 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
+	float		m_fReflow_LinePosData[8];	
+	int			m_nReflow_Side;
+	int			m_nReflow_InspectionMode;
+};
+
+struct _grmDefectData
+{
+	void clear()
+	{
+		memset(this, 0, sizeof(_grmDefectData));
+	}
+
+	short			m_nDefectID;
+	short			m_nCameraID;
+	short			m_nScanIdx;
+	//short			m_nDefectIdx;				// 카占쌨라에쇽옙占쏙옙 占쏙옙占쏙옙 占싸듸옙占쏙옙
+	int				m_nDefectIdx;				// 카占쌨라에쇽옙占쏙옙 占쏙옙占쏙옙 占싸듸옙占쏙옙 201207 CJH - 占쌘몌옙 占쏙옙 占쏙옙침. int占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
+
+	int				m_nPixelConv;				// pixel 占쏙옙占쏙옙 占쏙옙표
+	int				m_nPixelScan;				// pixel 占쏙옙占쏙옙 占쏙옙표
+
+	short							m_nPixelSize;				// 占쏙옙占쏙옙크占쏙옙		---------------------------------PS
+	short/*SERVER_DefectType*/		m_DefectType;				// 占쏙옙占쏙옙 타占쏙옙	---------------------------------DT
+	short/*SERVER_DefectSubType*/	m_DefectSubType;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+	short/*SERVER_DefectBDType*/	m_DefectBDType;				// 占쏙옙占쏙옙 타占쏙옙 - Bright, Dark, Both
+
+	short			m_sPixelWidth;				// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占십븝옙
+	short			m_sPixelHeight;				// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	short			m_nLevelSrcMin;				// 占쏙옙占쏙옙 占쏙옙占� Min	-----------------------------SN
+	short			m_nLevelSrcMax;				// 占쏙옙占쏙옙 占쏙옙占� Max	-----------------------------SX
+	short			m_nLevelSrcAvg;				// 占쏙옙占쏙옙 占쏙옙占� Avg	-----------------------------SA
+	short			m_nLevelRefMin;				// 占쏟교댐옙占� 占쏙옙占� Min	-------------------------RN
+	short			m_nLevelRefMax;				// 占쏟교댐옙占� 占쏙옙占� Max	-------------------------RX
+	short			m_nLevelRefAvg;				// 占쏟교댐옙占� 占쏙옙占� Avg	-------------------------RA
+	short			m_nLevelDiffMin;			// 占쏙옙占쏙옙 Min	---------------------------------DN
+	short			m_nLevelDiffMax;			// 占쏙옙占쏙옙 Max	---------------------------------DX
+	short			m_nLevelDiffAvg;			// 占쏙옙占쏙옙 Avg	---------------------------------DA
+
+	int				m_nDefectRScale;			// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙	-------------------------RS
+	short			m_sThreshold;				// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 Threshold
+	short			m_sThresholdAvg;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 Threshold AVG
+	short			m_sDefectPeak;				// 占쏙옙占쏙옙占쏙옙 Peak.
+	short			m_sDefectLevel;				// (DiffAvg - Th) BOE 8G 占쏙옙청占쏙옙占쏙옙
+
+	int				m_nPixelGlassStart;			// Glass 占쏙옙占쏙옙 占싫쇽옙
+	short			m_sDefectLoc;
+
+	short			m_sZoneClassPixelCount[16];
+	short			m_sZonePixelCount[16];	// Zone占쏙옙 占쏙옙占쏙옙 Pixel 占쏙옙
+	short			m_sZoneValueMin[16];	// Zone占쏙옙 占쏙옙占쏙옙 Min
+	short			m_sZoneValueMax[16];	// Zone占쏙옙 占쏙옙占쏙옙 Max
+	short			m_sZoneValueAvg[16];	// Zone占쏙옙 占쏙옙占쏙옙 Avg
+	short			m_sZonePixelPercent[16];	// --------------------------------------Z0~ZF
+
+	//210127 CJH - Zone占쏙옙 Source Gray 占쌉뤄옙
+	short			m_sZoneValueSrcMin[16];	// Zone占쏙옙 Source Min
+	short			m_sZoneValueSrcMax[16];	// Zone占쏙옙 Source Max
+	short			m_sZoneValueSrcAvg[16]; // Zone占쏙옙 Source Avg
+
+	int				m_nUMOriginX;				// um占쏙옙占쏙옙 x占쏙옙표 (占쏙옙占쏙옙占쏙옙占쏙옙)
+	int				m_nUMOriginY;				// um占쏙옙占쏙옙 y占쏙옙표 (占쏙옙占쏙옙占쏙옙占쏙옙)
+	int				m_nUMCenterAlignX;			// um占쏙옙占쏙옙 X占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterAlignY;			// um占쏙옙占쏙옙 Y占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterX;				// um占쏙옙占쏙옙 X占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterY;				// um占쏙옙占쏙옙 Y占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMSizeX;					// um占쏙옙占쏙옙 X 크占쏙옙	-----------------------------UX
+	int				m_nUMSizeY;					// um占쏙옙占쏙옙 Y 크占쏙옙	-----------------------------UY
+	int				m_nUMSize;					// um占쏙옙占쏙옙 크占쏙옙.
+	CRect			m_RectUM;					// 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占썹각占쏙옙.
+
+	short/*SERVER_DefectSizeType*/	m_DefectSizeType;			// 占쏙옙占쏙옙 크占쏙옙 占쏙옙占쏙옙enum SERVER_DefectSizeType		{ SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
+	short/*SERVER_DefectPeakType*/	m_DefectPeakType;			// Peak占쏙옙 占쏙옙占쏙옙.
+	short/*Judgement*/				m_DefectJudgement;			// 占쏙옙占쏙옙 占쏙옙占쏙옙.
+	BOOL					m_bDefectCutoff;			// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙(TRUE= Cutoff, FALSE)
+	short/*MAP16_DefectClass*/		m_DefectClass;				// BOE Defect Class 16占쏙옙占� 占쏙옙占쏙옙
+	int				m_nPadRegionIdx;			// PAD 占쏙옙占쏙옙 占싸듸옙占쏙옙
+
+	int				m_nUMCellX;					// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 x 占쏙옙표
+	int				m_nUMCellY;					// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 y 占쏙옙표
+	short			m_nModelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占싸곤옙?
+	short			m_nCellIdx;					// 占쏙옙占승� 占쏙옙占싸곤옙?
+	short			m_nCellGate;				// 占쏙옙占쏙옙 Gate占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellData;				// 占쏙옙占쏙옙 Data占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellGateAlign;			// 占쏙옙占쏙옙 Gate占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellDataAlign;			// 占쏙옙占쏙옙 Data占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+
+	int				m_nUMShotX;					// 占쏙옙 占쏙옙占쏙옙 X占쏙옙표
+	int				m_nUMShotY;					// 占쏙옙 占쏙옙占쏙옙 Y占쏙옙표
+	short			m_nMaskDefectIdx;			// 占쏙옙 Glass占쏙옙占쏙옙 占쌩견듸옙 占쏙옙占쏙옙크占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙.
+	short			m_nShotIdx;					// 占쎈광占쏙옙 占쏙옙호
+	short			m_nMatchShotCount;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙크 占쏙옙占쏙옙占쏙옙 占쏙옙.
+	short			m_nMatchMaxSize;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙크 占쏙옙 占쏙옙占쏙옙 큰 占쏙옙占쏙옙占쏙옙 크占쏙옙.
+
+	short			m_nRepeatCount;				// 占쏙옙占쌈곤옙占쌉발곤옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙표 占쌥븝옙占쏙옙
+	short			m_nMaskRepeatCount;
+	int				m_StackInfo;				// Stack Flag
+	BOOL			m_bRealStack;				// Stack 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 TD(TRUE) 占쏙옙占쏙옙, 占쏙옙占싶몌옙占쏙옙 占쏙옙占쏙옙 TD(FALSE)占쏙옙占쏙옙占쏙옙 占쏙옙 占쌍댐옙.
+	short			m_nStackStepCount;			// Stack 占쏙옙
+	short			m_nStackColorIdx;			// Color占쏙옙 占쏙옙占쏙옙占싹댐옙 占싸듸옙占쏙옙.
+	//CString			m_strStackStep[CFDEFECT_STACKCOUNT];			// Stack Step.
+	char			m_strStackFirst[60];			// Stack Step. //201221 CJH - 占쌍댐옙 占쏙옙占쏙옙占쏙옙 60bytes
+	char			m_strUnitID[16];				// 占쏙옙占쌍억옙占싱듸옙
+
+	int				m_ClassificationType;				// enum ClassificationType			{ ClassType_None= 0, ClassType_PI_Over= 1, ClassType_PI_Under= 2, ClassType_TFE_Circle= 3, ClassType_Bubble, ClassType_Scratch, ClassType_Particle}; Classification Type, PI占쏙옙 TFE占쏙옙 占쌩곤옙 占싻뤄옙  占싯곤옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占�.
+	int				m_nAtomWidth;				// TFE 占쏙옙 占십븝옙
+	int				m_nAtomHeight;				// TFE 占쏙옙 占쏙옙占쏙옙
+	short/*ReKind*/			m_DefectKind;				// 占쏙옙占쏙옙 占쏙옙占쏙옙
+
+	char			m_strDefectCode[32];			// Defect Code
+	BOOL			m_bMergeState;				// Merge Status
+	char			m_strAoiImageName[256];			// Defect Image Name(CCD Image)
+	int				m_nDefectMerge;		// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+
+
+	int				m_nPixelSizeOrigin;
+	int				m_nScratchRatio;
+	int				m_nDensity;			// 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占싻듸옙 [2017.8.2 bhs]
+
+	char			m_strDefectName[16];
+	char			m_strDefectType[16];
+
+	double			m_dScanResolution;
+	double			m_dConvResolution;
+
+	int				m_nAngle;					// 占쏙옙占쏙옙
+	int				m_nMajor;					// 占쏙옙占쏙옙 占쏙옙占쏙옙(Long)
+	int				m_nMinor;					// 占쏙옙占쏙옙 占쏙옙占쏙옙(Short)
+	int				m_nCompact;					// Blob 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占싹댐옙 占쏙옙占쏙옙 占쏙옙占싱울옙 Blob 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
+	int				m_nThickness;				// Blob 占쏙옙占싱울옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 (Area / Major)
+	
+	short			m_nHliLevelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占쏙옙(채占쏙옙)占싸곤옙?
+	int				m_nHliLayers;				// 占쌔댐옙占쏙옙篤占� 占쏙옙占쌉듸옙 占쏙옙占싱억옙 bit처占쏙옙
+
+	BOOL			m_bShrinked;				//210323 CJH - Frame Shrink 占쏙옙占쏙옙 占쌩곤옙
+
+	char			m_strAoiImagePath[255];
+	char			m_strReviewImagePath[255];
+
+	int				m_nAlignRectLeft;
+	int				m_nAlignRectTop;
+	int				m_nAlignRectBottom;
+	int				m_nAlignRectRight;
+
+
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/1/19]
+	_grmDefectReviewData m_ReviewDefect;
+};
+
+
+enum emGlassRawCommand
+{
+	grcNone = 0,
+
+	//AOI Sequence
+	grcSequenceGlassLoading = 1,
+	grcSequenceInspectEnd = 2,
+	//Review Sequence
+	grcSequenceReviewStart = 3,
+	grcSequenceReviewEnd = 4,
+
+	grcSequenceCustomReviewDataRead = 10,
+
+	grcWriteRaw = 101,
+	grcReadRaw = 102,
+
+	grcWriteBin = 201,
+	grcReadBin = 202,
+
+	grcReviewWriteBIn = 301,
+
+	grcGlassRawCommand
+};
+
+
+struct _grmDitCommand
+{
+	struct _grmCommand
+	{
+		int nCommand;
+		char strParam[256];
+		short nResult; 
+	};
+	short m_nCommandIdxWrite;
+	short m_nCommandIdxRead;
+	_grmCommand m_nCommandBuffer[COMMAND_MAXCOUNT]; 
+};
+
+struct _grmDitMemInfo
+{
+	//占쏙옙占쏙옙 占쌨몌옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/12]
+	size_t m_nGlassRawDataSize;
+	int m_nGlassMaxDataNum;
+	int m_nBlockMaxDataNum;
+	int m_nCellMaxDataNum;
+	int m_nDefectMaxDataNum;
+	int m_nStackMaxDataNum;
+
+	//Char 占쏙옙占쏙옙 占쌘료가 占쌍댐옙 占쏙옙占쏙옙 占쏙옙치 [占쏙옙占쏙옙占쏙옙 2018/11/12]
+	int m_nGlassDataPoint;
+	int m_nBlockDataPoint;
+	int m_nCellDataPoint;
+	int m_nDefectDataPoint;
+	int m_nStackDataPoint;
+
+	int m_nSizeOfGlassData;
+	int m_nSizeOfBlockData;
+	int m_nSizeOfCellData;
+	int m_nSizeOfDefectData;
+	int m_nSizeOfStackData;
+};
+struct _grmDitGlassRawInfo : public _grmDitMemInfo, public _grmDitCommand
+{
+	size_t m_nGlassLoadingCount;
+	emAOIProcStep m_ClientProcStep; //AOI, Review占쏙옙 占쏙옙占쏙옙 占쏙옙占�
+	emAOIProcStep m_ServerProcStep; //GlassRaw Messenger(Server)占쏙옙 처占쏙옙 占싹뤄옙 占쏙옙 占쏙옙占�
+};
+
+class CgrmGlassRawData
+{
+public:
+	CgrmGlassRawData()
+	{
+		m_pGlassRawData = NULL;
+		m_bRefAlloc = FALSE;
+	};
+
+	~CgrmGlassRawData()
+	{
+		clear();
+	};
+
+	void clear()
+	{
+		if(m_bRefAlloc) { m_pGlassRawData = NULL; return;}
+
+		if(m_pGlassRawData)
+		{
+			delete [] m_pGlassRawData;
+			m_pGlassRawData = NULL;
+		}
+	};
+	BOOL ImportGlassRaw(_grmDitMemInfo* pInfo, char* pData, bool bRefAlloc = false)
+	{
+		if(pInfo == NULL) return FALSE;
+
+		if(m_pGlassRawData && pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) clear(); 
+
+		if(m_pGlassRawData == NULL) m_pGlassRawData = new char[ pInfo->m_nGlassRawDataSize ];
+
+		m_MemInfo = *pInfo;
+
+		m_nGlassRawDataSize = pInfo->m_nGlassRawDataSize;
+
+		m_nGlassMaxDataNum  = pInfo->m_nGlassMaxDataNum ;
+		m_nBlockMaxDataNum	= pInfo->m_nBlockMaxDataNum	;
+		m_nCellMaxDataNum   = pInfo->m_nCellMaxDataNum  ;
+		m_nDefectMaxDataNum = pInfo->m_nDefectMaxDataNum;
+		m_nStackMaxDataNum	= pInfo->m_nStackMaxDataNum	;
+
+		m_nGlassDataPoint   = pInfo->m_nGlassDataPoint  ;
+		m_nBlockDataPoint	= pInfo->m_nBlockDataPoint	;
+		m_nCellDataPoint    = pInfo->m_nCellDataPoint   ;
+		m_nDefectDataPoint  = pInfo->m_nDefectDataPoint ;
+		m_nStackDataPoint   = pInfo->m_nStackDataPoint	;
+
+		m_nSizeOfGlassData  = pInfo->m_nSizeOfGlassData ;
+		m_nSizeOfBlockData	= pInfo->m_nBlockDataPoint	;
+		m_nSizeOfCellData   = pInfo->m_nSizeOfCellData  ;
+		m_nSizeOfDefectData = pInfo->m_nSizeOfDefectData;
+		m_nSizeOfStackData  = pInfo->m_nSizeOfStackData	;
+
+		if(bRefAlloc)
+		{
+			m_pGlassRawData = pData;
+		}
+		else
+		{
+			if(pData)
+			{
+				memcpy(m_pGlassRawData, pData, sizeof(char)*pInfo->m_nGlassRawDataSize);
+			}
+			else
+			{
+				memset(m_pGlassRawData, 0, sizeof(char)*pInfo->m_nGlassRawDataSize );
+			}
+		}
+
+
+		m_pGlassData  = (_grmGlassData*)&m_pGlassRawData[pInfo->m_nGlassDataPoint];
+		m_pBlockData		= (_grmBlockData*)&m_pGlassRawData[pInfo->m_nBlockDataPoint];
+		m_pCellData   = (_grmCellData*)&m_pGlassRawData[pInfo->m_nCellDataPoint];
+		m_pDefectData = (_grmDefectData*)&m_pGlassRawData[pInfo->m_nDefectDataPoint];
+		m_pStackData = (_grmDefectData*)&m_pGlassRawData[pInfo->m_nStackDataPoint];
+
+		m_bRefAlloc = bRefAlloc;
+		return TRUE;
+	};
+	BOOL ExportGlassRaw(_grmDitMemInfo* pInfo, char* pData)
+	{
+		if(pInfo == NULL || pData == NULL) return FALSE;
+
+		if(1) //new type //占쌨몌옙 占쏙옙 占쏙옙占쏙옙 크占썩에 占쏙옙占쏙옙占쏙옙占� 
+		{
+			//if(pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) return FALSE;
+
+			if(pInfo->m_nSizeOfGlassData  !=  m_MemInfo.m_nSizeOfGlassData)  return FALSE;
+			if(pInfo->m_nSizeOfBlockData  !=  m_MemInfo.m_nSizeOfBlockData)  return FALSE;
+			if(pInfo->m_nSizeOfCellData   !=  m_MemInfo.m_nSizeOfCellData)   return FALSE;
+			if(pInfo->m_nSizeOfDefectData !=  m_MemInfo.m_nSizeOfDefectData) return FALSE;
+			if(pInfo->m_nSizeOfStackData  !=  m_MemInfo.m_nSizeOfStackData)	 return FALSE;
+
+			if(pInfo->m_nCellMaxDataNum < m_pGlassData->m_nCellNum) return FALSE;
+			if(pInfo->m_nDefectMaxDataNum < m_pGlassData->m_nDefectNum) return FALSE;
+			if(pInfo->m_nStackMaxDataNum < m_pGlassData->m_nDefectNum) return FALSE;
+
+			memcpy(&pData[pInfo->m_nGlassDataPoint], m_pGlassData,	 pInfo->m_nSizeOfGlassData* 1);
+			memcpy(&pData[pInfo->m_nBlockDataPoint], m_pBlockData,	 pInfo->m_nSizeOfBlockData* 1);
+			memcpy(&pData[pInfo->m_nCellDataPoint], m_pCellData,	 pInfo->m_nSizeOfCellData*m_pGlassData->m_nCellNum);
+			memcpy(&pData[pInfo->m_nDefectDataPoint], m_pDefectData, pInfo->m_nSizeOfDefectData*m_pGlassData->m_nDefectNum);
+			memcpy(&pData[pInfo->m_nStackDataPoint], m_pStackData, pInfo->m_nSizeOfStackData*m_pGlassData->m_nDefectNum);
+		}
+		else //if() //type old 
+		{
+			if(pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) return FALSE;
+
+			if(pInfo->m_nSizeOfGlassData  !=  m_MemInfo.m_nSizeOfGlassData)  return FALSE;
+			if(pInfo->m_nSizeOfBlockData  !=  m_MemInfo.m_nSizeOfBlockData)  return FALSE;
+			if(pInfo->m_nSizeOfCellData   !=  m_MemInfo.m_nSizeOfCellData)   return FALSE;
+			if(pInfo->m_nSizeOfDefectData !=  m_MemInfo.m_nSizeOfDefectData) return FALSE;
+
+			memcpy(pData, m_pGlassRawData, sizeof(char)*pInfo->m_nGlassRawDataSize);
+		}
+
+
+		return TRUE;
+	};
+
+	_grmGlassData*	GetGlassData(){return m_pGlassData;};
+	_grmBlockData*	GetBlockData(int nIndex){return &m_pBlockData[nIndex];};
+	_grmCellData*	GetCellData(int nIndex){return &m_pCellData[nIndex];};
+	_grmDefectData*	GetDefectData(int nIndex){return &m_pDefectData[nIndex];};
+	_grmDitMemInfo* GetMemInfo(){return &m_MemInfo;};
+	_grmDefectData* GetStackData(int nIndex) { return &m_pStackData[nIndex]; };
+protected:
+	_grmDitMemInfo  m_MemInfo;
+	char* m_pGlassRawData;
+
+	_grmGlassData*  m_pGlassData;
+	_grmBlockData*	m_pBlockData;
+	_grmCellData*   m_pCellData;
+	_grmDefectData* m_pDefectData;
+	_grmDefectData*	m_pStackData;
+
+	size_t m_nGlassRawDataSize;
+
+	int m_nGlassMaxDataNum;
+	int m_nBlockMaxDataNum;
+	int m_nCellMaxDataNum;
+	int m_nDefectMaxDataNum;
+	int m_nStackMaxDataNum;
+
+	int m_nGlassDataPoint;
+	int m_nBlockDataPoint;
+	int m_nCellDataPoint;
+	int m_nDefectDataPoint;
+	int m_nStackDataPoint;
+
+	int m_nSizeOfGlassData;
+	int m_nSizeOfBlockData;
+	int m_nSizeOfCellData;
+	int m_nSizeOfDefectData;
+	int m_nSizeOfStackData;
+
+private:
+	bool m_bRefAlloc;
+};
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/GlassRawBase.cpp b/ReviewHistory/ReveiwHistory/GlassRawBase.cpp
new file mode 100644
index 0000000..b8c7ebe
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawBase.cpp
@@ -0,0 +1,131 @@
+#include "StdAfx.h"
+#include "GlassRawBase.h"
+
+#include "akLoggerExt.h"
+
+CGlassRawBase::CGlassRawBase(void)
+{
+}
+
+CGlassRawBase::~CGlassRawBase(void)
+{
+}
+
+BOOL CGlassRawBase::WriteBinFile( CgrmGlassRawData* pData )
+{
+	AKLOG("WriteBinFile Start");
+	CString strFileName;
+	strFileName.Format("%s\\%s", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName);
+	FILE* pf = fopen(strFileName.GetBuffer(0), "wb");
+	if(pf)
+	{
+		fwrite(pData->GetMemInfo(), sizeof(_grmDitMemInfo), 1, pf);
+
+		fwrite(pData->GetGlassData(), pData->GetMemInfo()->m_nSizeOfGlassData, sizeof(char), pf);
+		
+		for(int i=0; i<pData->GetGlassData()->m_nCellNum; i++)
+		{
+			fwrite(pData->GetCellData(i), pData->GetMemInfo()->m_nSizeOfCellData, sizeof(char), pf);
+		}
+
+		for(int i=0; i<pData->GetGlassData()->m_nDefectNum; i++)
+		{
+			fwrite(pData->GetDefectData(i), pData->GetMemInfo()->m_nSizeOfDefectData, sizeof(char), pf);
+		}
+
+		fclose(pf);
+	}
+	else
+	{
+		AKLOG("WriteBinFile Fail");
+		return FALSE;
+	}
+	AKLOG("WriteBinFile Finish");
+	return TRUE;
+}
+
+BOOL CGlassRawBase::ReadBinFile( CgrmGlassRawData* pData )
+{
+	CString strFileName;
+	strFileName.Format("%s\\%s", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName);
+	FILE* pf = fopen(strFileName.GetBuffer(0), "rb");
+	if(pf)
+	{
+		_grmDitMemInfo MemInfo;
+		fread(&MemInfo, sizeof(_grmDitMemInfo), 1, pf);
+
+		//pData->ImportGlassRaw(pData->GetMemInfo(), NULL);
+		BOOL bFileFormDiff = FALSE;
+		bFileFormDiff = FALSE;
+		{
+			if(pData->GetMemInfo()->m_nSizeOfGlassData  !=  MemInfo.m_nSizeOfGlassData)  bFileFormDiff |= TRUE;
+			if(pData->GetMemInfo()->m_nSizeOfBlockData  !=  MemInfo.m_nSizeOfBlockData)  bFileFormDiff |= TRUE;
+			if(pData->GetMemInfo()->m_nSizeOfCellData   !=  MemInfo.m_nSizeOfCellData)   bFileFormDiff |= TRUE;
+			if(pData->GetMemInfo()->m_nSizeOfDefectData !=  MemInfo.m_nSizeOfDefectData) bFileFormDiff |= TRUE;
+
+			//if(pData->m_nCellMaxDataNum < m_pGlassData->m_nCellNum) return FALSE;
+			//if(pData->m_nDefectMaxDataNum < m_pGlassData->m_nDefectNum) return FALSE;
+
+			if(bFileFormDiff) {fclose(pf); return FALSE;}
+		}
+
+		fread(pData->GetGlassData(), pData->GetMemInfo()->m_nSizeOfGlassData, sizeof(char), pf);
+
+		bFileFormDiff = FALSE;
+		{
+			if(pData->GetMemInfo()->m_nCellMaxDataNum < pData->GetGlassData()->m_nCellNum)		bFileFormDiff |= TRUE;
+			if(pData->GetMemInfo()->m_nDefectMaxDataNum < pData->GetGlassData()->m_nDefectNum)	bFileFormDiff |= TRUE;
+
+			if(bFileFormDiff) {fclose(pf); return FALSE;}
+		}
+
+		for(int i=0; i<pData->GetGlassData()->m_nCellNum; i++)
+		{
+			fread(pData->GetCellData(i), pData->GetMemInfo()->m_nSizeOfCellData, sizeof(char), pf);
+		}
+
+		for(int i=0; i<pData->GetGlassData()->m_nDefectNum; i++)
+		{
+			fread(pData->GetDefectData(i), pData->GetMemInfo()->m_nSizeOfDefectData, sizeof(char), pf);
+		}
+
+		fclose(pf);
+	}
+	else
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+BOOL CGlassRawBase::ReviewWriteBin(CgrmGlassRawData* pData)
+{
+	CString strFileName;
+	strFileName.Format("D:\\DIT_ResultData\\RawBin\\%s", pData->GetGlassData()->m_strFileName);
+	FILE* pf = fopen(strFileName.GetBuffer(0), "wb");
+	if (pf)
+	{
+		fwrite(pData->GetMemInfo(), sizeof(_grmDitMemInfo), 1, pf);
+
+		fwrite(pData->GetGlassData(), pData->GetMemInfo()->m_nSizeOfGlassData, sizeof(char), pf);
+
+		for (int i = 0; i < pData->GetGlassData()->m_nCellNum; i++)
+		{
+			fwrite(pData->GetCellData(i), pData->GetMemInfo()->m_nSizeOfCellData, sizeof(char), pf);
+		}
+
+		for (int i = 0; i < pData->GetGlassData()->m_nDefectNum; i++)
+		{
+			fwrite(pData->GetDefectData(i), pData->GetMemInfo()->m_nSizeOfDefectData, sizeof(char), pf);
+		}
+
+		fclose(pf);
+	}
+	else
+	{
+		return FALSE;
+	}
+
+	return TRUE;
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/GlassRawBase.h b/ReviewHistory/ReveiwHistory/GlassRawBase.h
new file mode 100644
index 0000000..2f46477
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawBase.h
@@ -0,0 +1,75 @@
+#pragma once
+
+#include "DitGlassRawStruct.h"
+
+//////////////////////////////////////////////////////////////////////////
+// Recipe占쏙옙占쏙옙 Server占쏙옙 Inspector占쏙옙 占쏙옙占쏙옙占싹댐옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+enum ThreadCount { Thread_1 = 0, Thread_2, Thread_4, Thread_6, Thread_8, Thread_11, Thread_12, Thread_22, Thread_24 };
+enum CameraType { CamType_Unknown = 0, CamType_Transfer, CamType_Reflex };
+enum ScanCoordinate { SC_XCoord = 0, SC_YCoord };					// 占쏙옙캔占쏙옙占쏙옙. 占쏙옙占쏙옙 占쏙옙표 占쏙옙占쏙옙占� 占쌩울옙.
+enum ScanDirectionEng { SD_Right2Left = 0, SD_Left2Right };			// 占쌜억옙占쌘곤옙 占쏙옙 占쏙옙캔 占쏙옙占쏙옙.
+enum ScanDirectionIns { SD_Forward = 0, SD_Backward, SD_Unknown };	// Glass 占쏙옙占쏙옙 Scan 占쏙옙占쏙옙.
+enum ScanType { ST_SingleScan = 0, ST_DualScan };				// SingleScan - 占쌤뱄옙占쏙옙, DualScan - 占쏙옙占쏙옙占�
+enum GlassDirection { GD_LeftTop = 0, GD_RightTop = 1, GD_LeftBottom = 10, GD_RightBottom = 11 };
+enum AcqMode { Acq_Unknown = 0, Acq_Grab, Acq_Snap, Acq_Matrox, Acq_Simul };
+enum FindBoundary { FB_NotFind = 0, FB_PitchMatching, FB_ManualMatching };
+enum InspectionMethod { IM_Convolution = 0, IM_HProjection, IM_VProjection, IM_ImageMatching };
+enum DefectLocation { DefectLoc_Pattern = 0, DefectLoc_Crack, DefectLoc_BM, DefectLoc_ASG, DefectLoc_PAD, DefectLoc_C2C, DefectLoc_EdgeLine, DefectLoc_Proj, DefectLoc_Chip, DefectLoc_Corner };
+enum CellLineType { CellLine_Gate = 0, CellLine_Data };
+enum XByXType { OneByOne = 0, TwoByTwo };
+enum DefectFiltering { Filtering_NO = 0, Filtering_CO, Filtering_Cutoff, Filtering_DXDY, Filtering_TD, Filtering_FALSE };		// Filtering_CO : Cosmic Ray FALSE
+enum ALIGN_MARK_CLASSIFY { eAMC_First = 0, eAMC_Second };
+//////////////////////////////////////////////////////////////////////////
+// Defect占쏙옙 占쏙옙占실댐옙 타占쌉듸옙.
+enum SERVER_DefectType { DefectType_TBlack = 0, DefectType_TWhite, DefectType_RBlack, DefectType_RWhite, DefectType_BBlack, DefectType_BWhite, DefectType_Unknown };
+enum SERVER_DefectSizeType { SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
+enum SERVER_DefectJudgementType { JudgementType_OK = 0, JudgementType_TR, JudgementType_PR, JudgementType_UNKNOWN };
+enum SERVER_DefectSubType { DefectSubType_Normal = 0, DefectSubType_MC, DefectSubType_Mask, DefectSubType_Common, DefectSubType_NoDefect };
+enum SERVER_DefectBDType { DefectBDType_Unknown = 0, DefectBDType_Bright = 1, DefectBDType_Dark = 2, DefectBDType_Both = 64, DefectBDType_Both_B = 65 };
+enum SERVER_DefectPeakType { PeakType_Unknown = 0, PeakType_Low, PeakType_Center, PeakType_High, PeakType_OverHigh };
+enum StackInfo { Stack_Unknown = 0, Stack_TD, Stack_SD, Stack_PD, Stack_SP, Stack_CD };		// lmk 2012.12.21 CD (A2E CurrentData)
+enum DefectShowOption { DefectShow_Type, DefectShow_StackFlag, DefectShow_StackStep, DefectShow_Size, DefectShow_Judgement, DefectShow_Code };
+
+enum ClassificationType { ClassType_None = 0, ClassType_PI_Over = 1, ClassType_PI_Under = 2, ClassType_TFE_Circle = 3, ClassType_Bubble, ClassType_Scratch, ClassType_Particle };
+enum ReKind { Re_Other, Re_TFE_CIRCLE, Re_PI_CONVEX, Re_PI_CONCAVE, Re_PI_1, Re_PI_2, Re_PI_3 };
+
+//choigudal jude fix 2012.03.07
+enum Judgement { Judge_OK = 0, Judge_RP, Judge_NG, Judge_TR, Judge_PR, Judge_PT, Judge_Review, Judge_RC, Judge_Size, Judge_VI, Judge_Rework, Judge_Unknown };//2016.07.13 LHS Judge_Size 占쌩곤옙
+enum MAP16_DefectClass { CLASS_C1 = 1, CLASS_C2, CLASS_C3, CLASS_C4, CLASS_C5, CLASS_C6, CLASS_C7, CLASS_C8, CLASS_C9, CLASS_C10, CLASS_C11, CLASS_C12, CLASS_C13, CLASS_C14, CLASS_C15, CLASS_C16 };
+enum MAP16_SizeType { SIZE_SS = 0, SIZE_SM, SIZE_SL, SIZE_SOH, SIZE_IDX_MAX };
+enum MAP16_PeakType { PEEK_PS = 0, PEEK_PL, PEEK_PH, PEEK_POH, PEAK_IDX_MAX };
+enum GlassCode_TSP { A_SET = 0, B_SET, C_SET, D_SET, MAX_SET };//2016.07.11 LHS
+enum DefectShape { CIRCLE = 0, LINE };//2016.07.13 LHS
+enum AAILightSource { TRANSLIGHT = 5, REFLIGHT, BACKLIGHT };//2016.07.12 LHS
+
+enum CAMTYPE { _eCT_Reflex = 0, _eCT_Transfer };
+
+class CGlassRawBase
+{
+public:
+	CGlassRawBase(void);
+	virtual ~CGlassRawBase(void);
+
+	static char* GetClassName(){return "Base";};
+
+	virtual BOOL SequenceGlassLoading(CgrmGlassRawData* pData){return TRUE;};
+	virtual BOOL SequenceInspectEnd(CgrmGlassRawData* pData){return TRUE;};
+	virtual BOOL SequenceReviewStart(CgrmGlassRawData* pData){return TRUE;};
+	virtual BOOL SequenceReviewEnd(CgrmGlassRawData* pData){return TRUE;};
+	virtual BOOL SequenceCustomizeReview(CgrmGlassRawData* pData){return TRUE;};
+
+	virtual BOOL WriteBinFile(CgrmGlassRawData* pData);
+	virtual BOOL ReadBinFile(CgrmGlassRawData* pData);
+
+	virtual BOOL ReviewWriteBin(CgrmGlassRawData* pData);
+
+	virtual BOOL WriteAOIFile(CgrmGlassRawData* pData){return TRUE;};
+	virtual BOOL ReadAOIFile(CgrmGlassRawData* pData){return TRUE;};
+
+	virtual BOOL SequenceFtpUpload(char* pRawFileName){return TRUE;};
+
+	virtual void NotifyUpdateOptionInfo(){};
+
+
+
+};
diff --git a/ReviewHistory/ReveiwHistory/GlassRawCEC.cpp b/ReviewHistory/ReveiwHistory/GlassRawCEC.cpp
new file mode 100644
index 0000000..f51188a
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawCEC.cpp
@@ -0,0 +1,96 @@
+#include "StdAfx.h"
+#include "GlassRawCEC.h"
+#include "akLoggerExt.h"
+
+CGlassRawCEC::CGlassRawCEC(void)
+{
+}
+
+CGlassRawCEC::~CGlassRawCEC(void)
+{
+}
+
+BOOL CGlassRawCEC::SequenceGlassLoading( CgrmGlassRawData* pData )
+{
+	//나중에 스택파일 읽기 처리도 여기서 하게 하면 좋을듯 [김태현 2018/11/14]
+	return TRUE;
+}
+
+BOOL CGlassRawCEC::SequenceInspectEnd( CgrmGlassRawData* pData )
+{
+	WriteAOIFile(pData);
+
+	return TRUE;
+}
+
+BOOL CGlassRawCEC::SequenceReviewStart( CgrmGlassRawData* pData )
+{
+	return TRUE;
+}
+
+BOOL CGlassRawCEC::SequenceReviewEnd( CgrmGlassRawData* pData )
+{
+	WriteAOIFile(pData);
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawCEC::WriteAOIFile( CgrmGlassRawData* pData )
+{
+	BOOL bResult = TRUE;
+
+	
+	bResult &= MakeAOIFile(pData);
+	bResult &= MakeAnaFile(pData);
+
+	AKLOG("WriteAOIFile Complete");
+	return TRUE;
+}
+
+BOOL CGlassRawCEC::MakeAOIFile( CgrmGlassRawData* pData )
+{
+	CString strFilePathName;
+	strFilePathName.Format("%s\\%s", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName);
+	
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if(pf == NULL) return FALSE;
+	
+	for(int iCell = 0; iCell < pData->GetGlassData()->m_nCellNum; iCell++)
+	{
+		_grmCellData* pCell = pData->GetCellData(iCell);
+
+		fprintCell(pf, pCell);
+	}
+
+	fprintf(pf, "<HEAD DEFECE> sdlkfjlsd sdlkflsdkjf sdlkfjslkdjf sldkfjsdf\n");
+	for(int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+	{
+		_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+
+		fprintDefect(pf, pDefect);
+	}
+
+	AKLOG("MakeAOIFile Complete");
+	fclose(pf);
+	return TRUE;
+}
+
+BOOL CGlassRawCEC::MakeAnaFile( CgrmGlassRawData* pData )
+{
+	CString strFilePathName;
+	strFilePathName.Format("%s\\%sana", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName);
+
+	AKLOG("MakeAnaFile Complete");
+	return TRUE;
+}
+
+void CGlassRawCEC::fprintDefect( FILE* pf, _grmDefectData* pData )
+{
+	//defect pos
+	fprintf(pf, "%d ", pData->m_nUMCenterAlignX);	//defect pos
+	
+	fprintf(pf, "%d ", pData->m_nUMCenterAlignX);
+
+	fprintf(pf, "\n");
+}
diff --git a/ReviewHistory/ReveiwHistory/GlassRawCEC.h b/ReviewHistory/ReveiwHistory/GlassRawCEC.h
new file mode 100644
index 0000000..41dfd07
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawCEC.h
@@ -0,0 +1,26 @@
+#pragma once
+
+#include "GlassRawBase.h"
+
+class CGlassRawCEC : public CGlassRawBase
+{
+public:
+	CGlassRawCEC(void);
+	~CGlassRawCEC(void);
+
+	static char* GetClassName(){return "CEC_PANDA";};
+
+	virtual BOOL SequenceGlassLoading(CgrmGlassRawData* pData);
+	virtual BOOL SequenceInspectEnd(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewStart(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewEnd(CgrmGlassRawData* pData);
+
+	virtual BOOL WriteAOIFile(CgrmGlassRawData* pData);
+	virtual BOOL ReadAOIFile(CgrmGlassRawData* pData){return TRUE;};
+
+	BOOL MakeAOIFile(CgrmGlassRawData* pData);
+	BOOL MakeAnaFile(CgrmGlassRawData* pData);
+
+	void fprintCell(FILE* pf, _grmCellData* pData){};
+	void fprintDefect(FILE* pf, _grmDefectData* pData);
+};
diff --git a/ReviewHistory/ReveiwHistory/GlassRawCPJT.cpp b/ReviewHistory/ReveiwHistory/GlassRawCPJT.cpp
new file mode 100644
index 0000000..4b6b6bb
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawCPJT.cpp
@@ -0,0 +1,2279 @@
+癤�#include "StdAfx.h"
+#include "GlassRawCPJT.h"
+#include "akLoggerExt.h"
+#include "MacroResultFile.h"
+#include "akCore/akFileUtil.h"
+#include "akGridData.h"
+
+//#include "AOIDefinitionType.h"
+//#include "AOIDefinition.h"
+ 
+#define LOCAL_INDEX_PATH			"D:\\DIT_ResultData\\Index\\"	  
+#define LOCAL_REV_IMAGE_PATH		"D:\\ResultData\\UploadImage\\" 
+#define LOCAL_AOI_IMAGE_PATH		"D:\\Image\\Defect\\" 
+#define LOCAL_MURA_IMAGE_PATH		"D:\\DIT_ResultData\\Mura\\IMG\\" 
+#define LOCAL_DEEP_PATH				"D:\\DIT_ResultData\\Deeplearning\\"
+
+#define LOCAL_RTMS_INFO_PATH		"D:\\RTMS_TEMP\\"
+
+#define LOCAL_RAWPATH_INFO_INI_PATH	"D:\\ResultData\\"
+#define RAWINFO_FILE_NAME			"RESULT_INFO.ini"
+
+#define LOCAL_AOIRAWDFS_PATH		"D:\\DIT_ResultData\\Raw"
+#define LOCAL_AOIRAWBIN_PATH		"D:\\DIT_ResultData\\RawBin"
+#define NETWORK_AOIRAWDFS_PATH		"\\\\126.100.100.1\\d\\DIT_ResultData\\Raw"
+#define NETWORK_AOIRAWBIN_PATH		"\\\\126.100.100.1\\d\\DIT_ResultData\\RawBin"
+
+#define NETWORK_AOIRAWFILE_SUB_PATH "\\\\126.100.100.1\\d\\Raw_im\\"
+#define NETWORK_AOI_IMAGE_PATH		"\\\\126.100.100.1\\d\\Image\\Defect\\" 
+//0404NWH
+#define NETWORK_MURARAW_PATH		"\\\\126.100.100.1\\d\\DIT_ResultData\\Mura\\RAW" //0405nwh
+#define NETWORK_MURA_IMAGE_PATH		"\\\\126.100.100.1\\d\\DIT_ResultData\\Mura\\IMG" //0405nwh
+
+char* g_pCellCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+void _TimeDelay(int delay)
+{
+	MSG		msg;
+	BOOL	fRst = FALSE;
+
+	clock_t lBlockTime = delay + clock();
+
+	while (lBlockTime > clock())
+	{
+		fRst = (BOOL)PeekMessage(&msg, NULL, 0, 0, PM_REMOVE);
+		if (fRst)
+		{
+			TranslateMessage(&msg);
+			DispatchMessage(&msg);
+		}
+		Sleep(10);
+	}
+}
+
+CGlassRawCPJT::CGlassRawCPJT(void)
+{
+	CreateDirectory("D:\\RTMS_Signal", NULL);
+	CreateDirectory(LOCAL_AOIRAWDFS_PATH, NULL);
+	CreateDirectory(LOCAL_AOIRAWBIN_PATH, NULL);
+	CreateDirectory("D:\\Raw_im", NULL);
+	m_MuraResultFile.readOptionFile("C:\\DIT_Review\\ReviewServerConfig\\MacroInfo.cfg");
+
+	m_GlassRawRTMS.SetMuraResult(&m_MuraResultFile);
+	m_nWriteRawDefectIdx = 1;
+	m_bReviewEndCheck = FALSE;
+}
+
+CGlassRawCPJT::~CGlassRawCPJT(void)
+{
+}
+
+BOOL CGlassRawCPJT::SequenceGlassLoading( CgrmGlassRawData* pData )
+{
+	//�뒪�깮湲곕뒫
+	if(m_StackResult.getStackUse())
+	{
+		//201218 CJH - Stack Download �떆�룄
+		SendMessageFTPDownloadStack(pData->GetGlassData());
+
+		m_StackResult.StackFileReadStart(pData->GetGlassData()->m_strGlassID);
+	}
+	
+
+	return TRUE;
+}
+
+BOOL CGlassRawCPJT::SequenceInspectEnd( CgrmGlassRawData* pData )
+{
+	m_bReviewEndCheck = FALSE;
+	//210128
+	m_tmReviewEnd = m_tmReviewStart = CTime::GetCurrentTime();
+	pData->GetGlassData()->m_tmReviewEnd = m_tmReviewEnd;      // Insp End �떆 Raw �뾽濡쒕뱶濡�, E_TIME, LD_TIME �엯�젰 [ 21-03-18 KJG ]
+	m_tmFileCreateTime = CTime::GetCurrentTime();
+
+	//�뿬湲곗뿉�꽌 �씪�씤蹂꾨줈 �뙆�씪紐�, �샊�� Path �쐞移� 寃곗젙�븯硫대맖. AOIServer �샊�� ReviewServer�뿉�꽌 �븞�빐�룄�맖 [源��깭�쁽2019/9/4]
+	pData->GetGlassData()->m_strFileName;
+	{
+		_grmGlassData* pGlassData = pData->GetGlassData();
+		CTime CurrTime = pGlassData->m_tmGlassLoading;
+		CString strTime=_T(""), strFileName=_T("");
+		strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+			
+			CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+		strFileName.Format("%s_%s_%s.bin", pGlassData->m_strGlassID, pGlassData->m_strStepID, strTime.GetBuffer(0));
+
+		strcpy(pData->GetGlassData()->m_strFileName, strFileName.GetBuffer(0));
+	}
+	strcpy(pData->GetGlassData()->m_strPath, LOCAL_AOIRAWBIN_PATH);
+
+	
+	if(!WriteBinFile(pData))
+		return FALSE;
+	
+	
+	if (1) ReadMuraFile(pData);
+
+	
+	if (WriteAOIFile(pData) == FALSE)
+		return FALSE;
+
+	// [C-PRJ] Image Upload Define - KHT (2020/11/19)
+	_TimeDelay(5000); // �씠誘몄� 蹂듭궗 �떆媛� ��湲�
+	//210218 CJH - 寃��궗 醫낅즺�떆 寃곌낵�뙆�씪 諛� CCD Image �뾽濡쒕뱶
+	SendMessageFTPUploadRaw(pData->GetGlassData());
+	SendMessageFTPUploadImage(pData->GetGlassData(), FTPCMD_AOI_IMAGE);
+	SendMessageFTPUploadImage(pData->GetGlassData(), FTPCMD_MURA_IMAGE);//0405nwh
+
+	return TRUE;
+}
+
+BOOL CGlassRawCPJT::SequenceReviewStart( CgrmGlassRawData* pData )
+{
+	//210128
+	m_tmReviewStart = m_tmReviewEnd = CTime::GetCurrentTime();
+
+	//�뿬湲곗뿉�꽌 �씪�씤蹂꾨줈 �뙆�씪紐�, �샊�� Path �쐞移� 寃곗젙�븯硫대맖. AOIServer �샊�� ReviewServer�뿉�꽌 �븞�빐�룄�맖 [源��깭�쁽2019/9/4]
+	pData->GetGlassData()->m_strFileName;
+	strcpy(pData->GetGlassData()->m_strPath, NETWORK_AOIRAWBIN_PATH);
+	
+	//strcpy(pData->GetGlassData()->m_strPath, LOCAL_AOIRAWBIN_PATH);
+
+	CString strFindFile;
+	int nCloseTime = 600*100000;//sec
+	int nReTryTime = 30;
+	{
+		CTime tmReviewLoading = CTime::GetCurrentTime();
+		CString strWild;
+		
+		strWild.Format("%s\\%s_%s_*.bin", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strGlassID,pData->GetGlassData()->m_strStepID);
+		CakFileUtil akFileFinder;
+		while(nReTryTime--)
+		{
+			akFileFinder.FindFile(strWild.GetBuffer(0), FALSE);
+			VECFINDDATA* pFindData = akFileFinder.getFindData();
+			int nFileNamePos = strlen(akFileFinder.getProcessPath());
+			std::map<LONGLONG, CString> mapSpanFileName;
+			for(int i=0; i<pFindData->size(); i++)
+			{
+				char* pFileName = &((*pFindData)[i]).name[nFileNamePos];
+				{
+					CakParser parser;
+					parser.process(pFileName, "_.");
+					if(parser.getTokNum() < 4) continue;
+
+					int nDataTime[8]={};
+					{
+						int nTokIndex=0;
+						const char* pGlassId = parser.getTokStr(nTokIndex++);
+						const char* pStepId = parser.getTokStr(nTokIndex++);
+						char* pDate = &pFileName[parser.getTokPos(nTokIndex++)];
+						char* pTime = &pFileName[parser.getTokPos(nTokIndex++)];
+
+						nDataTime[0] = (pDate[0]-'0')*1000 + (pDate[1]-'0')*100 + (pDate[2]-'0')*10+ (pDate[3]-'0')*1;
+						nDataTime[1] = (pDate[4]-'0')*10+ (pDate[5]-'0')*1;
+						nDataTime[2] = (pDate[6]-'0')*10+ (pDate[7]-'0')*1;
+						nDataTime[3] = (pTime[0]-'0')*10+ (pTime[1]-'0')*1;
+						nDataTime[4] = (pTime[2]-'0')*10+ (pTime[3]-'0')*1;
+						nDataTime[5] = (pTime[4]-'0')*10+ (pTime[5]-'0')*1;
+					}
+					
+					CTime tmTemp(nDataTime[0], nDataTime[1], nDataTime[2], nDataTime[3], nDataTime[4], nDataTime[5] );
+					CTimeSpan tmSpan = tmReviewLoading-tmTemp;
+					mapSpanFileName.insert(std::make_pair(tmSpan.GetTotalSeconds(), pFileName));
+				}
+			}
+
+			if(mapSpanFileName.empty() == FALSE)
+			{
+				if(mapSpanFileName.begin()->first < nCloseTime)
+				{
+					//媛��옣 理쒓렐 寃곌낵�뙆�씪 李얘린 �꽦怨� [源��깭�쁽 2019/7/17]
+					strFindFile = mapSpanFileName.begin()->second;
+					break;
+				}
+			}
+			akFileFinder.clear();
+			Sleep(100);
+		}
+	}
+
+	if(strFindFile.IsEmpty()) return FALSE;
+
+	strcpy(pData->GetGlassData()->m_strFileName, strFindFile.GetBuffer(0));
+
+
+	if(!ReadBinFile(pData))
+		return FALSE;
+
+	strcpy(pData->GetGlassData()->m_strPath, LOCAL_AOIRAWBIN_PATH);
+
+	pData->GetGlassData()->m_tmReviewLoading = m_tmReviewStart;
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawCPJT::SequenceReviewEnd( CgrmGlassRawData* pData )
+{ 
+	m_bReviewEndCheck = TRUE;
+	m_tmReviewEnd = m_tmReviewStart = CTime::GetCurrentTime();
+	m_tmFileCreateTime = CTime::GetCurrentTime();
+	pData->GetGlassData()->m_tmReviewEnd = m_tmReviewEnd;
+	
+	//�뿬湲곗뿉�꽌 �씪�씤蹂꾨줈 �뙆�씪紐�, �샊�� Path �쐞移� 寃곗젙�븯硫대맖. AOIServer �샊�� ReviewServer�뿉�꽌 �븞�빐�룄�맖 [源��깭�쁽2019/9/4]
+	pData->GetGlassData()->m_strFileName;
+	strcpy(pData->GetGlassData()->m_strPath, NETWORK_AOIRAWDFS_PATH);
+
+	if(1) ReadMuraFile(pData);
+
+  	if(WriteAOIFile(pData) == FALSE)
+  		return FALSE;
+
+	//210126 CJH - Review End�뿉�꽌留� RTMS 寃곌낵�뙆�씪 �깮�꽦�븯�룄濡� 蹂�寃�
+	if (m_GlassRawRTMS.WriteAOIFile(pData) == FALSE)
+		return FALSE;
+
+	if(1)
+	{
+		_grmGlassData* pGlassData = pData->GetGlassData();
+
+		SendMessageFTPUploadRaw(pGlassData);
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_AOI_IMAGE);
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_REVIEW_IMAGE);
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_MURA_IMAGE);//0405nwh
+
+	}
+	
+	
+
+	
+	return TRUE;
+}
+
+BOOL CGlassRawCPJT::SequenceFtpUpload(char* pRawFilePathName)
+{
+	// Manual Upload 湲곕뒫 [21-02-05 KJG]
+	CTime tmFileCreate;
+	_grmGlassData GlassData;
+	_grmGlassData* pGlassData = &GlassData;
+
+	//�젙蹂� �뼸�뼱�삤湲� [源��깭�쁽 2019/1/25]
+	char* pFileName = CakFileUtil::getFileName(pRawFilePathName);
+	char* pext = CakFileUtil::getFileExt(pRawFilePathName);
+
+	if (!strcmp(pext, "") == FALSE) return FALSE; // �솗�옣�옄媛� �뾾�쓬
+
+	CakParser parser;
+	FILE* pf = fopen(pRawFilePathName, "r");
+	if (pf)
+	{
+		CString strParse, strLDTime;		
+		char buffer[512];
+		fgets(buffer, 512, pf);
+		fgets(buffer, 512, pf);
+		fgets(buffer, 512, pf);
+		fgets(buffer, 512, pf);
+		parser.process(buffer, " ");
+
+		if (parser.getTokNum() < 20) return FALSE;
+		strParse = parser.getTokStr(0);
+		if (strParse != "DATA") return FALSE;
+		strParse = parser.getTokStr(1);
+		if (strParse != "PANEL") return FALSE;
+
+		strcpy(pGlassData->m_strProcessID, "");
+		strcpy(pGlassData->m_strProductID, "");
+		strcpy(pGlassData->m_strLotID, "");
+		strcpy(pGlassData->m_strStepID, "");
+		strcpy(pGlassData->m_strGlassID, "");
+
+		strcpy(pGlassData->m_strProcessID, parser.getTokStr(4));
+		strcpy(pGlassData->m_strProductID, parser.getTokStr(5));
+		strcpy(pGlassData->m_strLotID, parser.getTokStr(5));		   // C-PJT - m_strLotID = m_strProductID
+		strcpy(pGlassData->m_strStepID, parser.getTokStr(6));
+		strcpy(pGlassData->m_strGlassID, parser.getTokStr(9));
+		strLDTime = parser.getTokStr(19);
+
+		if (pGlassData->m_strProcessID == "" || pGlassData->m_strProductID == "" || pGlassData->m_strLotID == "" || pGlassData->m_strStepID == "" || pGlassData->m_strGlassID == "")
+		{
+			AKLOG("Manual Upload Fail : Parsing Data is Empty");
+			return FALSE;
+		}
+		int nYear = _ttoi(strLDTime.Left(4));
+		int nMon = _ttoi(strLDTime.Mid(4, 2));
+		int nDay = _ttoi(strLDTime.Mid(6, 2));
+		int nHour = _ttoi(strLDTime.Mid(8, 2));
+		int nMin = _ttoi(strLDTime.Mid(10, 2));
+		int nSec = _ttoi(strLDTime.Mid(12, 2));
+		pGlassData->m_tmGlassLoading = CTime(nYear, nMon, nDay, nHour, nMin, nSec);
+
+		m_tmFileCreateTime = CTime::GetCurrentTime();
+		strcpy(pGlassData->m_strPath, NETWORK_AOIRAWDFS_PATH);
+
+		SendMessageFTPUploadRaw(pGlassData);
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_AOI_IMAGE);
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_REVIEW_IMAGE);
+		AKLOG("Manual Success : %s File Send FTPUploader Command", pRawFilePathName);
+		
+	}
+	else
+	{
+		AKLOG("Manual Upload Fail : Can't Open File");
+		return FALSE;
+	}
+	
+	fclose(pf);
+
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawCPJT::WriteAOIFile( CgrmGlassRawData* pData )
+{
+	BOOL bResult = TRUE;
+	
+	bResult &= MakeAOIFile(pData);
+	
+	m_GlassRawAna.MakeAnaFile(pData);
+	//m_GlassRawRTMS.WriteAOIFile(pData);
+
+	AKLOG("WriteAOIFile Complete");
+	return bResult;
+}
+
+BOOL CGlassRawCPJT::MakeAOIFile( CgrmGlassRawData* pData )
+{
+	AKLOG("MakeAOIFile Start");
+	m_nWriteRawDefectIdx = 1;
+
+	_grmGlassData* pGlass = pData->GetGlassData();
+	CString strFilePathName;
+	CString strFileName;//�뙆�씪�깮�꽦 �떆媛� �븣臾몄뿉 �뿬湲곗꽌 �젙�솗�븯寃� �뙆�씪紐� �떎�떆 �젙�젙
+	{
+		//Glass �젙蹂�
+		CTime CurrTime = m_tmReviewEnd;
+		CString strTime;
+		strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+			CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+		strFileName.Format("%s", pGlass->m_strGlassID); // �떊湲곕� �봽濡� �슂泥� �솗�옣�옄 �궘�젣
+	}
+	
+	strFilePathName.Format("%s\\%s", pGlass->m_strPath, strFileName);//pGlass->m_strFileName);
+	//strFilePathName.Format("C:\\AOIServer\\NFS\\RAW\\%s", pData->GetGlassData()->m_strFileName);
+	
+	// 湲��씪�뒪 ID留� 議댁옱�븯�뿬 �옱寃��궗 �떆 �뙆�씪 �깮�꽦 �떎�뙣. �궘�젣�븳�떎
+	DeleteFile(strFilePathName);
+	//FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if(pf == NULL)
+	{
+		AKLOG("MakeAOIFile Fail : [%s]", strFilePathName.GetBuffer(0));
+		return FALSE;
+	}
+	
+	
+	
+	CString strBuffer;
+	CString strLine;
+
+	//////////////////////////////////////////////////////////////////////////
+	//HEDER ITEM
+	{
+		makeDataHeader(strLine, pGlass);
+		fprintf(pf, "%s\n", strLine.GetBuffer(0));
+	}
+
+
+	//////////////////////////////////////////////////////////////////////////
+	//GLASSDATA
+	{
+		makeDataGlass(strLine, pGlass);
+		fprintf(pf, "%s\n", strLine.GetBuffer(0));
+	}
+	
+	//////////////////////////////////////////////////////////////////////////
+	//CELL & DEFECT DATA
+	{
+		
+		//make
+		{
+			for (int iCell = 0; iCell < pData->GetGlassData()->m_nCellNum; iCell++)
+			{
+				_grmCellData* pCell = pData->GetCellData(iCell);
+				makeDataCell(strLine, pData, pCell);
+				fprintf(pf, "%s\n", strLine);
+
+				for (int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+				{
+					_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+					if (pDefect->m_nCellIdx != iCell) continue;
+					//210203 CJH - CutOff ���긽 寃곌낵�뙆�씪 �옉�꽦 �젣�쇅
+					if (pDefect->m_bDefectCutoff == TRUE) continue;
+
+					if (makeDataDefect(strLine, pData, pDefect))
+					{
+						fprintf(pf, "%s\n", strLine);
+					}
+				}
+
+			}
+		}
+	}
+	
+	
+
+
+	
+	AKLOG("MakeAOIFile Complete : [%s]", strFilePathName.GetBuffer(0));
+	fclose(pf);
+	return TRUE;
+}
+
+void CGlassRawCPJT::makeDataHeader( CString& strLine, _grmGlassData* pGlassData )
+{
+	strLine.Empty();
+	CString strValue;
+	
+	strValue = "ITEM PANEL MODULETYPE MODULEID PROCESSID PRODUCTID STEPID PROD_TYPE BATCHID H_PANELID E_PANELID P_PANELID OPERID COMP_COUNT PPID GRADE CODE R_GRADE MAP_IMAGE L_TIME U_TIME S_TIME E_TIME T_DEFECT TR PR TB TW RB RW T_STACK MAX_AVG_GRAY MAX_PORTION OK_CELL RJ_CELL RW_CELL NR_CELL CSTID SLOT_NO JOB_END TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT BR_DEFECT IMG_COUNT RECIPE SHRINK RAW_CUT"; //53ea
+	strLine += strValue; strLine += "\n";
+	strValue = "ITEM SUBPANEL SUBPANELID COORD_X COORD_Y SIZE_X SIZE_Y GATELINE DATALINE GRADE CODE R_GRADE T_DEFECT TD_DEFECT SD_DEFECT PD_DEFECT SP_DEFECT PAD_GATE PAD_DATA M_DEFECT C_DEFECT PRO_IMAGE AVG_GRAY_0 PORTION_0 CORNER_GRAY_0 AVG_AMP_0 FFT_VAR_0 FFT_VAH_0 FFT_VAQ_0 FFT_PK_0 AVG_GRAY_1 PORTION_1 CORNER_GRAY_1 AVG_AMP_1 FFT_VAR_1 FFT_VAH_1 FFT_VAQ_1 FFT_PK_1 AVG_GRAY_2 PORTION_2 CORNER_GRAY_2 AVG_AMP_2 FFT_VAR_2 FFT_VAH_2 FFT_VAQ_2 FFT_PK_2 AVG_GRAY_3 PORTION_3 CORNER_GRAY_3 AVG_AMP_3 FFT_VAR_3 FFT_VAH_3 FFT_VAQ_3 FFT_PK_3"; //54ea 21-06-21 Mura Data 異붽�
+	strLine += strValue; strLine += "\n";
+	//210405
+	//ITEM DEFECT ID DEF_NO COORD_X COORD_Y GATELINE DATALINE SIZE_S SIZE_W SIZE_L SIZE_H GRADE CODE STACK_FLAG STACK_COUNT STACK_STEP IMAGE_FILE DSC_CODE VC_CODE DCR_CODE DEFECT_SIZE REPEAT_DEFECT WSI_HEIGHT CS_HEIGHT C_GRADE GRAY_MIN GRAY_MAX GRAY_AVG GRAY_DEF WSI_IMAGE USE_CCDIMAGE SCAN_NUM CAM_POSITION CCD_NO R_GRAY_MIN R_GRAY_MAX R_GRAY_AVG SCAN_AI REVIEW_AI INS_MODE INS_CHANNEL COMPACTNESS THICKNESS MAJOR MINOR WSI_TYPE DEFECT_TYPE SHRINK
+	strValue = "ITEM DEFECT ID DEF_NO COORD_X COORD_Y GATELINE DATALINE SIZE_S SIZE_W SIZE_L SIZE_H GRADE CODE STACK_FLAG STACK_COUNT STACK_STEP IMAGE_FILE DSC_CODE VC_CODE DCR_CODE DEFECT_SIZE REPEAT_DEFECT WSI_HEIGHT CS_HEIGHT C_GRADE GRAY_MIN GRAY_MAX GRAY_AVG GRAY_DEF WSI_IMAGE USE_CCDIMAGE SCAN_NUM CAM_POSITION CCD_NO R_GRAY_MIN R_GRAY_MAX R_GRAY_AVG R_HEIGHT G_HEIGHT B_HEIGHT INS_CHANNEL COMPACTNESS THICKNESS MAJOR MINOR WSI_TYPE DEFECT_TYPE SHRINK CLASS_CODE"; //50ea    
+	strLine += strValue;
+
+}
+#define SPRINTRAWSTART char strItemValue[1024];int nItemValueLen, nItemValuePos = 0;memset(strItemValue, ' ', sizeof(char)*1024)
+#define SPRINTRAW(ITEMSIZE, fmt, ...) nItemValueLen = sprintf(strItemValue+nItemValuePos, fmt,##__VA_ARGS__); strItemValue[nItemValuePos+ nItemValueLen] = ' ';nItemValuePos+=ITEMSIZE+1
+#define SPRINTRAWEND strItemValue[nItemValuePos - 1] = 0; strLine = strItemValue
+void CGlassRawCPJT::makeDataGlass( CString& strLine, _grmGlassData* pGlassData )
+{
+	SPRINTRAWSTART;
+
+	CString strValue;
+	
+	/* PANEL ITEM	
+	01   4   ITEM			// ITEM Separator
+	02   5   PANEL			// PANEL Separator
+	03   5   MODULETYPE		// Module Type
+	04   27  MODULEID		// Module ID
+	05   20  PROCESSID		// ProcessID
+	06   20  PRODUCTID		// ProductID
+	07   10  STEPID			// StepID
+	08   2   PROD_TYPE		// Prod Type
+	09   12  BATCHID		// Batch ID
+	10   12  H_PANELID		// Host Panel ID
+	11   12  E_PANELID		// Panel ID Reading by VCR
+	12   12  P_PANELID		// Pair Panel ID
+	13   16  OPERID			// Perator ID or Module ID
+	14   3   COMP_COUNT		// Cell Count
+	15   16  PPID			// PPID (Recipe Name)
+	16   4   GRADE			// Grade (Judgement)
+	17   4   CODE			// Grade Code (Judgement Code)
+	18   4   R_GRADE		// Grade by Operator (Re-Judgement)
+	19   16  MAP_IMAGE		// Map Image File Name
+	20   14  L_TIME			// Cassette or Conveyor�뿉�꽌 OUT�맂 �떆媛�
+	21   14  U_TIME			// Cassette or Conveyor�뿉�꽌 IN�맂 �떆媛�
+	22   14  S_TIME			// Stage�뿉�꽌 寃��궗/怨꾩륫 �떆�옉�맂 �떆媛�
+	23   14  E_TIME			// Stage�뿉�꽌 寃��궗/怨꾩륫 醫낅즺�맂 �떆媛�
+	24   12   T_DEFECT		// Common Item 1 - Total Defect Count
+	25   12   TR         // Panel �젙蹂� 02
+	26   12   PR         // Panel �젙蹂� 03
+	27   12   TB         // Panel �젙蹂� 04
+	28   12   TW         // Panel �젙蹂� 05
+	29   12   RB         // Panel �젙蹂� 06
+	30   12   RW         // Panel �젙蹂� 07
+	31   12   T_STACK         // SD+SP �닔
+	32   12   BMDF		    // Panel �젙蹂� 09 -> 蹂�寃� MAX_AVG_GRAY 04/12
+	33   12   CJ			// Panel �젙蹂� 10 -> 蹂�寃� MAX_PORTION 04/12
+	34   12   OK_CELL		// OK Cell Count
+	35   12   RJ_CELL		// RJ Cell Count
+	36   12   RW_CELL		// RW Cell Count
+	37   12   NR_CELL		// NR Cell Count
+	38   12   MASK_CELL		// MASK Cell Count - CST ID
+	39   12   A_CELL			// �씠�긽 Cell Count - SLOT NO
+	40   12   P_CELL			// Pattern Shift Cell Count - JOB END
+	41   12   TD_DEFECT		// Total Defect Count -> TD Defect Count
+	42   12   SD_DEFECT		// SD Defect Count
+	43   12   PD_DEFECT		// PD Defect Count
+	44   12   SP_DEFECT		// SP Defect Count
+	45   12   PAD_GATE		// PAD Gate 遺덈웾 �닔
+	46   12   PAD_DATA		// PAD Data 遺덈웾 �닔
+	47   12   M_DEFECT		// MASK 遺덈웾 �닔
+	48   12   C_DEFECT		// COMMON 遺덈웾
+	49   12   BR_DEFECT		// SCRATCH 遺덈웾 �닔
+	50   12   CRACK			// Crack 遺덈웾 �닔 - Image 珥ъ긽 媛��닔
+	51   12   P_SHIFT			// Pattern Shift 遺덈웾 �닔 - �젅�떆�뵾 �씠由�
+	*/
+
+	//////////////////////////////////////////////////////////////////////////
+	// [源��깭�쁽2020/9/15]
+	// SPRINTRAW(�뜲�씠�꽣 �겕湲�, "VALUE");
+
+	// 01   4   ITEM			// ITEM Separator
+	SPRINTRAW(4, "DATA");
+	// 02   5   PANEL		// PANEL Separator	
+	SPRINTRAW(5, "PANEL");
+	// 03   5   MODULETYPE	// Module Type	
+	/*SPRINTRAW(5, "*");*/
+	if (strlen(pGlassData->m_strEquipID) == 0)
+	{
+		SPRINTRAW(5, "*");
+	}
+	else
+	{
+		CString temp = pGlassData->m_strEquipID;
+		SPRINTRAW(5, "%s", temp.Left(5));
+	}
+	// 04   27  MODULEID		// Module ID	
+	if (strlen(pGlassData->m_strOperID) == 0)
+	{
+		SPRINTRAW(27, "*");
+	}
+	else
+	{
+		SPRINTRAW(27, "%s", pGlassData->m_strOperID);
+	}
+	// 05   20  PROCESSID	// ProcessID	
+	if (strlen(pGlassData->m_strProcessID) == 0)
+	{
+		SPRINTRAW(20, "*");
+	}
+	else
+	{
+		SPRINTRAW(20, "%s", pGlassData->m_strProcessID);
+	}
+	// 06   20  PRODUCTID	// ProductID	
+	if (strlen(pGlassData->m_strProductID) == 0)
+	{
+		SPRINTRAW(20, "*");
+	}
+	else
+	{
+		SPRINTRAW(20, "%s", pGlassData->m_strProductID);
+	}
+	// 07   10  STEPID		// StepID
+	if (strlen(pGlassData->m_strStepID) == 0)
+	{
+		SPRINTRAW(10, "*");
+	}
+	else
+	{
+		SPRINTRAW(10, "%s", pGlassData->m_strStepID);
+	}
+	// 08   2   PROD_TYPE	// Prod Type	
+	if (strlen(pGlassData->m_strProdType) == 0)
+	{
+		SPRINTRAW(2, "*");
+	}
+	else
+	{
+		SPRINTRAW(2, "%s", pGlassData->m_strProdType);
+	}
+	// 09   12  BATCHID		// Batch ID	 - Glass ID �븵 6�옄由�
+	strValue = pGlassData->m_strGlassID;
+	SPRINTRAW(12, "%s", strValue.Left(6));
+	// 10   12  H_PANELID	// Host Panel ID	
+	if (strlen(pGlassData->m_strGlassID) == 0)
+	{
+		SPRINTRAW(12, "*");
+	}
+	else
+	{
+		SPRINTRAW(12, "%s", pGlassData->m_strGlassID);
+	}
+	// 11   12  E_PANELID	// Panel ID Reading by VCR	
+	if (strlen(pGlassData->m_strEPPID) == 0)
+	{
+		SPRINTRAW(12, "*");
+	}
+	else
+	{
+		SPRINTRAW(12, "%s", pGlassData->m_strEPPID);
+	}
+	// 12   12  P_PANELID	// Pair Panel ID	
+	if (strlen(pGlassData->m_strPairHPanelID) == 0)
+	{
+		SPRINTRAW(12, "*");
+	}
+	else
+	{
+		SPRINTRAW(12, "%s", pGlassData->m_strPairHPanelID);
+	}
+	// 13   16  OPERID		// Perator ID or Module ID	
+	if (strlen(pGlassData->m_strOperID) == 0)
+	{
+		SPRINTRAW(16, "*");
+	}
+	else
+	{
+		SPRINTRAW(16, "%s", pGlassData->m_strOperID);
+	}	
+	// 14   3   COMP_COUNT	// Cell Count	
+	SPRINTRAW(3, "%d", pGlassData->m_nCellNum);
+	// 15   16  PPID			// PPID (Recipe Name)	
+	if (strlen(pGlassData->m_strPPID) == 0)
+	{
+		SPRINTRAW(16, "*");
+	}
+	else
+	{
+		SPRINTRAW(16, "%s", pGlassData->m_strPPID);
+	}
+	// 16   4   GRADE		// Grade (Judgement)
+	if (strlen(pGlassData->m_strGlassJudge) == 0)
+	{
+		SPRINTRAW(4, "*");
+	}
+	else
+	{
+		SPRINTRAW(4, "%s", pGlassData->m_strGlassJudge);
+	}
+	// 17   4   CODE			// Grade Code (Judgement Code)
+	if (strlen(pGlassData->m_strGlassCode) == 0)
+	{
+		SPRINTRAW(4, "*");
+	}
+	else
+	{
+		SPRINTRAW(4, "%s", pGlassData->m_strGlassCode);
+	}
+	// 18   4   R_GRADE		// Grade by Operator (Re-Judgement)	
+	SPRINTRAW(4, "*");
+	// 19   16  MAP_IMAGE	// Map Image File Name	
+//	if (strlen(pGlassData->m_strFileName) == 0)
+//	{
+//		SPRINTRAW(16, "*");
+//	}
+//	else
+//	{
+//		SPRINTRAW(16, "%s", pGlassData->m_strFileName);
+//	}
+	SPRINTRAW(16, "map01.jpg"); //Defect Map �옄由우닔媛� 20�옄由ш� �꽆�뒗�떎..
+	// 20   14  L_TIME		// Cassette or Conveyor�뿉�꽌 OUT�맂 �떆媛�	
+	strValue.Format("%04d%02d%02d%02d%02d%02d"			// START_TIME
+		, pGlassData->m_tmGlassLoading.GetYear()
+		, pGlassData->m_tmGlassLoading.GetMonth()
+		, pGlassData->m_tmGlassLoading.GetDay()
+		, pGlassData->m_tmGlassLoading.GetHour()
+		, pGlassData->m_tmGlassLoading.GetMinute()
+		, pGlassData->m_tmGlassLoading.GetSecond());
+	SPRINTRAW(14, "%s", (LPSTR)(LPCTSTR)strValue);
+	// 21   14  U_TIME		// Cassette or Conveyor�뿉�꽌 IN�맂 �떆媛�	
+	strValue.Format("%04d%02d%02d%02d%02d%02d"			// E_TIME
+		, pGlassData->m_tmReviewEnd.GetYear()
+		, pGlassData->m_tmReviewEnd.GetMonth()
+		, pGlassData->m_tmReviewEnd.GetDay()
+		, pGlassData->m_tmReviewEnd.GetHour()
+		, pGlassData->m_tmReviewEnd.GetMinute()
+		, pGlassData->m_tmReviewEnd.GetSecond());
+	SPRINTRAW(14, "%s", (LPSTR)(LPCTSTR)strValue);
+	// 22   14  S_TIME		// Stage�뿉�꽌 寃��궗/怨꾩륫 �떆�옉�맂 �떆媛�	
+	strValue.Format("%04d%02d%02d%02d%02d%02d"			// START_TIME
+		, pGlassData->m_tmInspectionStart.GetYear()
+		, pGlassData->m_tmInspectionStart.GetMonth()
+		, pGlassData->m_tmInspectionStart.GetDay()
+		, pGlassData->m_tmInspectionStart.GetHour()
+		, pGlassData->m_tmInspectionStart.GetMinute()
+		, pGlassData->m_tmInspectionStart.GetSecond());
+	SPRINTRAW(14, "%s", (LPSTR)(LPCTSTR)strValue);
+	// 23   14  E_TIME		// Stage�뿉�꽌 寃��궗/怨꾩륫 醫낅즺�맂 �떆媛�
+	strValue.Format("%04d%02d%02d%02d%02d%02d"			// E_TIME
+		, pGlassData->m_tmReviewEnd.GetYear()
+		, pGlassData->m_tmReviewEnd.GetMonth()
+		, pGlassData->m_tmReviewEnd.GetDay()
+		, pGlassData->m_tmReviewEnd.GetHour()
+		, pGlassData->m_tmReviewEnd.GetMinute()
+		, pGlassData->m_tmReviewEnd.GetSecond());
+	SPRINTRAW(14, "%s", (LPSTR)(LPCTSTR)strValue);
+	// 24   6   T_DEFECT		// Common Item 1 - Total Defect Count	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNum - pGlassData->m_nCutOffDefectNum); //210203 CJH - Cutoff 寃고븿�� �쟾泥닿컻�닔�뿉�꽌 �젣�쇅�빐以��떎.
+	// 25   6   TR		// Panel �젙蹂� 02	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumJudgeTR);
+	// 26   6   PR		// Panel �젙蹂� 03	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumJudgePR);
+	// 27   6   TB		// Panel �젙蹂� 04	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumTypeTB);
+	// 28   6   TW		// Panel �젙蹂� 05	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumTypeTW);
+	// 29   6   RB		// Panel �젙蹂� 06	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumTypeRB);
+	// 30   6   RW		// Panel �젙蹂� 07	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumTypeRW);
+	// 31   6   T_STACK		// Panel �젙蹂� 08	SD+SP �닔 �엯�젰
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumStackSD + pGlassData->m_nDefectNumStackSP);
+	//32   6   BMDF	    // Panel �젙蹂� 09 -> 蹂�寃� MAX_AVG_GRAY 04/12 nwh
+	if (strlen(pGlassData->m_strMaxAvgGray) == 0)
+	{
+		SPRINTRAW(12, "*");
+	}
+	else
+	{
+		SPRINTRAW(12, "%s", pGlassData->m_strMaxAvgGray);
+	}	
+	// 33   6   CJ			// Panel �젙蹂� 10 -> 蹂�寃� MAX_PORTION  04/12 nwh
+	if (strlen(pGlassData->m_strMaxPortion) == 0)
+	{
+		SPRINTRAW(12, "*");
+	}
+	else
+	{
+		SPRINTRAW(12, "%s", pGlassData->m_strMaxPortion);
+	}
+	// 34   6   OK_CELL		// OK Cell Count	
+	SPRINTRAW(12, "*");
+	// 35   6   RJ_CELL		// RJ Cell Count	
+	SPRINTRAW(12, "*");
+	// 36   6   RW_CELL		// RW Cell Count	
+	SPRINTRAW(12, "*");
+	// 37   6   NR_CELL		// NR Cell Count	
+	SPRINTRAW(12, "*");
+	// 38   6   MASK_CELL		// MASK Cell Count	//201215 CJH - CSTID濡� 蹂�寃�
+	if (strlen(pGlassData->m_strCSTID) == 0)
+	{
+		SPRINTRAW(12, "*");
+	}
+	else
+	{
+		SPRINTRAW(12, "%s", pGlassData->m_strCSTID);
+	}	
+
+	SPRINTRAW(12, "%d", pGlassData->m_nSlot_No);    // SLot_No 異붽� [ 21-03-18 KJG ]
+
+	SPRINTRAW(12, "%d", pGlassData->m_bJob_end);    // Job_end 異붽� [ 21-03-18 KJG ]
+
+	// 41   6   TD_DEFECT		// TD Defect Count	-> �쁽怨듭젙�뿉�꽌 �굹�삩 紐⑤뱺 寃고븿 : Total - SD
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumStackTD);
+	// 42   6   SD_DEFECT		// SD Defect Count  -> TD 寃고븿�뿉�꽌 Stack 寃고븿�쓣 �젣�쇅�븳 寃고븿(�슦由� �꽕鍮꾩뿉�꽌 泥� 諛쒓껄�맂 寃고븿)	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumStackSD);
+	// 43   6   PD_DEFECT		// PD Defect Count	-> �쁽�옱 怨듭젙�뿉�꽌 寃�異쒕맂 �듅�젙 Partial 寃고븿(�궗�뼇�꽌 �긽�뿉�뒗 Zone�씠�씪 �릺�뼱�엳�쑝�굹 �떎吏덉쟻�쑝濡쒕뒗 Classfication�뿉 �넻怨쇰맂 寃고븿)
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumStackPD);
+	// 44   6   SP_DEFECT		// SP Defect Count	-> �쁽�옱 怨듭젙�뿉�꽌 寃�異쒕맂 �듅�젙 Partial 寃고븿 以�, �씠�쟾 怨듭젙�쓽 Partial 寃고븿�쓣 �젣�쇅�븳 寃고븿
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumStackSP);
+	// 45   6   PAD_GATE		// PAD Gate 遺덈웾 �닔	
+	SPRINTRAW(12, "*");
+	// 46   6   PAD_DATA		// PAD Data 遺덈웾 �닔	
+	SPRINTRAW(12, "*");
+	// 47   6   M_DEFECT		// MASK 遺덈웾 �닔	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumTypeMD);
+	// 48   6   C_DEFECT		// COMMON 遺덈웾	
+	SPRINTRAW(12, "%d", pGlassData->m_nDefectNumTypeCD);
+	// 49   6   S_DEFECT		// SCRATCH 遺덈웾 �닔	
+	SPRINTRAW(12, "*");
+	// 50   6   CRACK		// Crack 遺덈웾 �닔	//201217 CJH - Image 珥ъ긽 媛쒖닔濡� 蹂�寃�
+	//SPRINTRAW(12, "%d", pGlassData->m_nDefectNumLocCrack);
+	SPRINTRAW(12, "%d", pGlassData->m_nReviewNum);
+	// 51 6   P_SHIFT		// Pattern Shift 遺덈웾 �닔	//201217 CJH - Recipe濡� 蹂�寃�
+	if (strlen(pGlassData->m_strRecipeName) == 0)
+	{
+		SPRINTRAW(16, "*");
+	}
+	else if(strlen(pGlassData->m_strRecipeName) <= 16)
+	{
+		SPRINTRAW(16, "%s", pGlassData->m_strRecipeName);
+	}
+	else if (strlen(pGlassData->m_strRecipeName) > 16)
+	{
+		CString temp = pGlassData->m_strRecipeName;  // �젅�떆�뵾 17�옄由� �꽆�뼱媛�硫� DCOLL 諛쒖깮�쑝濡� �삁�쇅泥섎━ [ 21-06-02 KJG ]
+		temp = temp.Left(16);		
+		SPRINTRAW(16, "%s", temp.GetBuffer(0));
+	}
+
+	// 52	12	SHRINK		// Server or Frame Shrink �룞�옉 �뿬遺�
+	if (strlen(pGlassData->m_strShrinked) == 0)
+	{
+		SPRINTRAW(12, "*");
+	}
+	else
+	{
+		SPRINTRAW(12, "%s", pGlassData->m_strShrinked);
+	}
+	// 53	12	RAW_CUT		// RAW �엯�젰 Defect �닔�웾 �긽�븳 �궗�슜�뿬遺�
+	if (pGlassData->m_bRawCutoff)
+	{
+		SPRINTRAW(12, "USE");
+	}
+	else
+	{
+		SPRINTRAW(12, "UNUSE");
+	}
+
+	SPRINTRAWEND;   //以묒슂!!! �젮 留덉�留됱뿉 瑗� �엳�뼱�빞�븿!!!(�궘�젣湲덉�) [源��깭�쁽2020/9/23]
+}
+
+void CGlassRawCPJT::makeDataCell( CString& strLine, CgrmGlassRawData* pData, _grmCellData* pCellData )
+{
+	SPRINTRAWSTART;
+
+	/* SUBPanel ITEM
+	01 4  ITEM				// ITEM
+	02 8  SUBPANEL			// SUBPANEL
+	03 12 SUBPANELID		// Subpanel ID
+	04 7  COORD_X			// X Beginnign Coord
+	05 7  COORD_Y			// Y Beginning Coord
+	06 7  SIZE_X			// X-axis Size
+	07 7  SIZE_Y			// Y-axis Size
+	08 6  GATELINE			// GateLine
+	09 6  DATALINE			// DataLine
+	10 4  GRADE				// Grade (Judgement)
+	11 4  CODE				// Grade Code (Judgement)
+	12 4  R_GRADE			// Grade by Operator (Re-Judgement)
+	13 12  T_DEFECT			// Total Defect Count
+	14 12  TD_DEFECT		// TD Defect Count
+	15 12  SD_DEFECT		// SD Defect Count
+	16 12  PD_DEFECT		// PD Defect Count
+	17 12  SP_DEFECT		// SP Defect Coun
+	18 12  PAD_GATE			// PAD Gate Defect Count
+	19 12  PAD_DATA			// PAD Data Defect Count
+	20 12  M_DEFECT			// MASK Defect Count
+	21 12  C_DEFECT			// COMMON Defect Count
+	22 12  S_DEFECT			// SCRATCH Defect Count
+	23 12  CRACK				// CRACK Defect Count
+	24 12  P_SHIFT			// Pattern Shift Defect Count
+	*/
+
+	// 01 4  ITEM				// ITEM
+	SPRINTRAW(4, "DATA");
+	// 02 8  SUBPANEL			// SUBPANEL
+	SPRINTRAW(8, "SUBPANEL");
+	// 03 12 SUBPANELID			// Subpanel ID
+	//SPRINTRAW(12, "%d", pCellData->m_nCellID);
+	SPRINTRAW(12, "%s%c%c", pData->GetGlassData()->m_strGlassID, '0' + pCellData->m_nCellID / 36, g_pCellCode[pCellData->m_nCellID % 36]);
+	
+	// 湲��씪�뒪 �썝�젏 湲곗� Y醫뚰몴 諛섎� 
+	// 肄붾꼫而� 湲곗��쑝濡� 寃곌낵�뙆�씪 醫뚰몴媛� �깮�꽦�릺�뒗�뜲 怨좉컼�궗�뿉 紐낇솗�븳 �솗�씤 �븘�슂
+	// Server�뒗 紐⑤뱺 醫뚰몴瑜� 湲��씪�뒪 �썝�젏 湲곗��쑝濡� �븯�뒗�뜲 肄붾꼫而� 湲곗��씠 �릺�뼱�빞�븯�뒗吏� 遊먯빞�븿
+	// �� �쐞移섎뒗 湲��씪�뒪 �썝�젏, 醫뚰몴�뒗 肄붾꼫而�???
+	// 210129 CJH - �� �썝�젏 �쐞移섏뿉 �뵲�씪 醫뚰몴�쐞移� 蹂�寃� LeftTop(1,-1) RightTop(-1,-1) LeftBottom(1,1) RightBottom(-1,1)
+	if (pCellData->m_nCellXDir == 1)
+	{
+		// 04 7  COORD_X			// X Beginning Coord
+		SPRINTRAW(8, "%d", pCellData->m_rectCellLeft);
+	}
+	else
+	{
+		// 04 7  COORD_X			// X Beginning Coord
+		SPRINTRAW(8, "%d", pCellData->m_rectCellRight);
+	}	
+
+	if (pCellData->m_nCellYDir == 1)
+	{
+		// 05 7  COORD_Y			// Y Beginning Coord	//Top�쓣 �빐�빞 �젣��濡� 媛믪씠 �뱾�뼱媛�...Rect遺��꽣 �옒紐� �뱾�뼱媛��뒗�벏
+		SPRINTRAW(8, "%d", pCellData->m_rectCellTop * -1);
+	}
+	else
+	{
+		// 05 7  COORD_Y			// Y Beginning Coord
+		SPRINTRAW(8, "%d", pCellData->m_rectCellBottom * -1);
+	}
+	// 06 7  SIZE_X				// X-axis Size
+	SPRINTRAW(7, "%d", pCellData->m_rectCellRight - pCellData->m_rectCellLeft);
+	// 07 7  SIZE_Y				// Y-axis Size
+	SPRINTRAW(7, "%d", pCellData->m_rectCellBottom - pCellData->m_rectCellTop);
+	// 08 6  GATELINE			// 珥� GateLine �닔
+	SPRINTRAW(6, "%d", pCellData->m_nGateNum);
+	// 09 6  DATALINE			// 珥� DataLine �닔
+	SPRINTRAW(6, "%d", pCellData->m_nDataNum);
+	// 10 4  GRADE				// Grade (Judgement)
+	SPRINTRAW(4, "%s", GetDefectInfoToString(DMT_DefectJudge, pCellData->m_nJudgement));
+	
+	// 11 4  CODE				// Grade Code (Judgement)
+	SPRINTRAW(4, "OOOO");
+	// 12 4  R_GRADE			// Grade by Operator (Re-Judgement)
+	SPRINTRAW(4, "*");
+	// 13 6  T_DEFECT			// Total Defect Count
+	SPRINTRAW(12, "%d", pCellData->getTotalDefectNum());
+	// 14 6  TD_DEFECT			// TD Defect Count - total defect
+	SPRINTRAW(12, "%d", pCellData->m_nDefectTDCount);
+	// 15 6  SD_DEFECT			// SD Defect Count - stack defect 
+	SPRINTRAW(12, "%d", pCellData->m_nDefectSDCount);
+	// 16 6  PD_DEFECT			// PD Defect Count - partial defect
+	SPRINTRAW(12, "%d", pCellData->m_nDefectPDCount);
+	// 17 6  SP_DEFECT			// SP Defect Count - stack partial 
+	SPRINTRAW(12, "%d", pCellData->m_nDefectSPCount);
+	// 18 6  PAD_GATE			// PAD Gate Defect Count
+	SPRINTRAW(12, "*");
+	// 19 6  PAD_DATA			// PAD Data Defect Count
+	SPRINTRAW(12, "*");
+	// 20 6  M_DEFECT			// MASK Defect Count
+	SPRINTRAW(12, "%d", pCellData->m_nDefectNumTypeMD);
+	// 21 6  C_DEFECT			// COMMON Defect Count
+	SPRINTRAW(12, "%d", pCellData->m_nDefectNumTypeCD);
+
+	// 22 6  S_DEFECT  -> 22 6  PRO_IMAGE 蹂�寃�	 nwh0404	
+	if (strlen(pCellData->m_strProImage))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strProImage);
+	}
+	else
+	{
+		SPRINTRAW(12,"*");
+	}
+
+	// 23 12  AVG_GRAY_0
+	if (strlen(pCellData->m_strAvgGray_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgGray_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 24 12 PORTION_0
+	if (strlen(pCellData->m_strPortion_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strPortion_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	
+	//kyh 0622
+	// 25 12 CORNER_GRAY_0
+	if (strlen(pCellData->m_strCorner_Gray_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 26 12 AVG_AMP_0
+	if (strlen(pCellData->m_strAvgAmp_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 27 12 FFT_VAR_0
+	if (strlen(pCellData->m_strFFTVar_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 28 12 FFT_VAH_0
+	if (strlen(pCellData->m_strFFTVah_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 29 12 FFT_VAQ_0
+	if (strlen(pCellData->m_strFFTVaq_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 30 12 FFT_PK_0
+	if (strlen(pCellData->m_strFFTPK_0))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_0);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 31 12  AVG_GRAY_1
+	if (strlen(pCellData->m_strAvgGray_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgGray_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 32 12 PORTION_1
+	if (strlen(pCellData->m_strPortion_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strPortion_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	//kyh 0622
+	// 33 12 CORNER_GRAY_1
+	if (strlen(pCellData->m_strCorner_Gray_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 34 12 AVG_AMP_1
+	if (strlen(pCellData->m_strAvgAmp_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 35 12 FFT_VAR_1
+	if (strlen(pCellData->m_strFFTVar_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 36 12 FFT_VAH_1
+	if (strlen(pCellData->m_strFFTVah_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 37 12 FFT_VAQ_1
+	if (strlen(pCellData->m_strFFTVaq_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 38 12 FFT_PK_1
+	if (strlen(pCellData->m_strFFTPK_1))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_1);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 39 12  AVG_GRAY_2
+	if (strlen(pCellData->m_strAvgGray_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgGray_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 40 12 PORTION_2
+	if (strlen(pCellData->m_strPortion_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strPortion_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	//kyh 0622
+	// 41 12 CORNER_GRAY_2
+	if (strlen(pCellData->m_strCorner_Gray_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 42 12 AVG_AMP_2
+	if (strlen(pCellData->m_strAvgAmp_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 43 12 FFT_VAR_2
+	if (strlen(pCellData->m_strFFTVar_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 44 12 FFT_VAH_2
+	if (strlen(pCellData->m_strFFTVah_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 45 12 FFT_VAQ_2
+	if (strlen(pCellData->m_strFFTVaq_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 46 12 FFT_PK_2
+	if (strlen(pCellData->m_strFFTPK_2))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_2);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 47 12  AVG_GRAY_3
+	if (strlen(pCellData->m_strAvgGray_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgGray_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 48 12 PORTION_3
+	if (strlen(pCellData->m_strPortion_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strPortion_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	//kyh 0622
+	// 49 12 CORNER_GRAY_3
+	if (strlen(pCellData->m_strCorner_Gray_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strCorner_Gray_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 50 12 AVG_AMP_3
+	if (strlen(pCellData->m_strAvgAmp_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strAvgAmp_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 51 12 FFT_VAR_3
+	if (strlen(pCellData->m_strFFTVar_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVar_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 52 12 FFT_VAH_3
+	if (strlen(pCellData->m_strFFTVah_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVah_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 53 12 FFT_VAQ_3
+	if (strlen(pCellData->m_strFFTVaq_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTVaq_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 54 12 FFT_PK_3
+	if (strlen(pCellData->m_strFFTPK_3))
+	{
+		SPRINTRAW(12, "%s", pCellData->m_strFFTPK_3);
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	SPRINTRAWEND;   //以묒슂!!! �젮 留덉�留됱뿉 瑗� �엳�뼱�빞�븿!!!(�궘�젣湲덉�) [源��깭�쁽2020/9/23]
+}
+
+BOOL CGlassRawCPJT::makeDataDefect( CString& strLine, CgrmGlassRawData* pData, _grmDefectData* pDefectData )
+{
+	SPRINTRAWSTART;
+	CString		strItem;
+	/* DEFECT ITEM
+		// 01   4    ITEM			// ITEM
+		// 02   6    DEFECT			// DEFECT
+		// 03   12   ID				// Subpanel ID
+		// 04   5    DEF_NO			// Defect Number of Panel
+		// 05   7    COORD_X		// Defect Location from origin point X
+		// 06   7    COORD_Y		// Defect Location from origin point Y
+		// 07   6    GATELINE		// Defect Gateline
+		// 08   6    DATALINE		// Defect Dataline
+		// 09   4    SIZE_S			// Defect Size (Square)
+		// 10   4    SIZE_W			// Defect Size (Width)
+		// 11   4    SIZE_L			// Defect Size (Length)
+		// 12   4    SIZE_H			// Defect Size (Height)
+		// 13   4    GRADE			// Defect Grade
+		// 14   4    CODE			// Defect Code
+		// 15   2    STACK_FLAG		// Current Defect Flag
+		// 16   2    STACK_COUNT	// Count of Defect detected step
+		// 17   60   STACK_STEP		// Flow(Step) of defect detection
+		// 18   16   IMAGE_FILE		// Image file Name
+		// 19   12   DSC Code
+		// 20   12   Image 遺꾨쪟 Code
+		// 21   12   遺덈웾�씠 �쐞移섑븳 Zone No �엯�젰
+		// 22   12   遺덈웾 �겕湲� (L,H,M,S)
+		// 23   12   M/N/C/S/K/*
+		// 24   12   誘몄궗�슜
+		// 25   12   誘몄궗�슜
+		// 26   12   �쟾 STEP �뙋�젙 D/F �쑀臾�
+		// 27   12   Gray Min
+		// 28   12   Gray Max
+		// 29   12   Gray Average
+		// 30   12   Defect Peak
+		// 31   12   誘몄궗�슜
+		// 32   12   誘몄궗�슜
+		// 33   12   Scan 踰덊샇
+		// 34   12   Camera ID
+		// 35   12   誘몄궗�슜
+		// 36   12   R_SRC_MIN
+		// 37   12   R_SRC_MAX
+		// 38   12   R_SRC_AVG
+		// 39   12   Scan AI 遺꾨쪟寃곌낵
+		// 40   12   Review AI 遺꾨쪟寃곌낵
+		// 41   12   寃�異쒕え�뱶 (Dark or Bright)
+		// 42   12   寃�異쒖콈�꼸 RGB
+	*/
+
+	// 01   4    ITEM			// ITEM
+	SPRINTRAW(4, "DATA");
+	// 02   6    DEFECT			// DEFECT
+	SPRINTRAW(6, "DEFECT");
+	// 03   12   ID				// Subpanel ID
+	SPRINTRAW(12, "%s%c%c", pData->GetGlassData()->m_strGlassID, '0' + pDefectData->m_nCellIdx / 36, g_pCellCode[pDefectData->m_nCellIdx % 36]);
+	// 04   5    DEF_NO			// Defect Number of Panel
+	// RAW �뙆�씪�슜 Defect Index 
+	//SPRINTRAW(5, "%d", pDefectData->m_nDefectIdx);
+	SPRINTRAW(5, "%d", m_nWriteRawDefectIdx++);
+	// 05   8    COORD_X		// Defect Location from origin point X
+	SPRINTRAW(8, "%d", pDefectData->m_nUMCenterAlignX);
+	// 06   8    COORD_Y		// Defect Location from origin point Y
+	// �떊湲곕��봽濡� �슂泥� �엫�떆 �닔�젙 
+	SPRINTRAW(8, "%d", pDefectData->m_nUMCenterAlignY*-1);
+	// 07   6    GATELINE		// Defect Gateline
+	SPRINTRAW(6, "%d", pDefectData->m_nCellGate);
+	// 08   6    DATALINE		// Defect Dataline
+	SPRINTRAW(6, "%d", pDefectData->m_nCellData);
+	// 09   4    SIZE_S			// Defect Size (Square)
+	if (abs(pDefectData->m_nPixelSize) > 9999) {
+		SPRINTRAW(4, "%d",9999);
+	}
+	else
+	{
+		SPRINTRAW(4, "%d", pDefectData->m_nPixelSize);
+	}
+
+	// 10   4    SIZE_W			// Defect Size (Width)
+	if (abs(pDefectData->m_nUMSizeX) > 9999) {
+		SPRINTRAW(4, "%d", 9999);
+	}
+	else
+	{
+		
+		SPRINTRAW(4, "%d", pDefectData->m_nUMSizeX);
+	}
+
+	// 11   4    SIZE_L			// Defect Size (Length)
+	if (abs(pDefectData->m_nUMSizeY) > 9999) {
+		SPRINTRAW(4, "%d", 9999);
+	}
+	else
+	{
+		SPRINTRAW(4, "%d", pDefectData->m_nUMSizeY);
+	
+	}
+
+	// 12   4    SIZE_H			// Defect Size (Height)
+	if (abs(pDefectData->m_nDefectRScale) > 9999) {
+		SPRINTRAW(4, "%d", 9999);
+	}
+	else
+	{
+		strItem.Format("%d", pDefectData->m_nDefectRScale);
+		SPRINTRAW(4, "%.4s", strItem.GetBuffer(0));
+	}
+
+
+	// 13   4    GRADE			// Defect Grade
+	SPRINTRAW(4, "%s", GetDefectInfoToString(DMT_DefectJudge, pDefectData->m_DefectJudgement));
+	// 14   4    CODE			// Defect Code
+	if (strlen(pDefectData->m_strDefectCode))
+	{
+		SPRINTRAW(4, "%.4s", pDefectData->m_strDefectCode);
+	}
+	else
+	{
+		SPRINTRAW(4, "*");
+	}	
+	// 15   2    STACK_FLAG		// Current Defect Flag  //201221 CJH - TD/SD/PD/SP
+	if (pDefectData->m_StackInfo == Stack_Unknown)
+	{
+		SPRINTRAW(2, "%s", "UK");
+	}
+	else if (pDefectData->m_StackInfo == Stack_TD)
+	{
+		SPRINTRAW(2, "%s", "TD");
+	}
+	else if (pDefectData->m_StackInfo == Stack_SD)
+	{
+		SPRINTRAW(2, "%s", "SD");
+	}
+	else if (pDefectData->m_StackInfo == Stack_PD)
+	{
+		SPRINTRAW(2, "%s", "PD");
+	}
+	else if (pDefectData->m_StackInfo == Stack_SP)
+	{
+		SPRINTRAW(2, "%s", "SP");
+	}
+	else
+	{
+		SPRINTRAW(2, "*");
+	}
+	// 16   2    STACK_COUNT	// Count of Defect detected step
+	SPRINTRAW(2, "%2d", pDefectData->m_nStackStepCount);
+	// 17   60   STACK_STEP		// Flow(Step) of defect detection
+	if (strlen(pDefectData->m_strStackFirst))
+	{
+		SPRINTRAW(60, "%s", pDefectData->m_strStackFirst);
+	}
+	else
+	{
+		SPRINTRAW(60, "*");
+	}
+	// 18   16   IMAGE_FILE		// Image file Name
+	// 寃��궗 �씠誘몄� 誘몄궗�슜 
+	if (strlen(pDefectData->m_ReviewDefect.m_strRevImageName))
+	{
+		SPRINTRAW(16, "%s", pDefectData->m_ReviewDefect.m_strRevImageName);
+	}
+	else
+	{
+		SPRINTRAW(16, "*");
+	}
+	// 19   12    DSC_CODE		// Common 01 DSC Code
+	SPRINTRAW(12, "*");
+	// 20   12    VC_CODE		// Common 02 Image 遺꾨쪟 Code
+	SPRINTRAW(12, "*");
+	// 21   12    ZONE_NO		// Common 03 遺덈웾�씠 �쐞移섑븳 Zone No �엯�젰
+	// Zone Data
+	int nValue = 0;
+	for (int i = 15; i >= 0; i--)
+	{
+		if (pDefectData->m_sZonePixelCount[i] > 0)
+			nValue += 1;
+		if (i > 0)
+			nValue = nValue << 1;
+	}
+	SPRINTRAW(12, "%04X", nValue);
+
+	// 22   12    DEFECT_SIZE	// Common 04 遺덈웾 �겕湲� (L,H,M,S)
+	if (pDefectData->m_DefectSizeType == SizeType_Small)
+	{
+		SPRINTRAW(12, "S");
+	}
+	else if (pDefectData->m_DefectSizeType == SizeType_Mid)
+	{
+		SPRINTRAW(12, "M");
+	}
+	else if (pDefectData->m_DefectSizeType == SizeType_Large)
+	{
+		SPRINTRAW(12, "L");
+	}
+	else if (pDefectData->m_DefectSizeType == SizeType_Huge)
+	{
+		SPRINTRAW(12, "H");
+	}
+	else if (pDefectData->m_DefectSizeType == SizeType_Ultra)
+	{
+		SPRINTRAW(12, "U");
+	}
+	else
+	{
+		SPRINTRAW(12, "S");
+	}
+	//SizeType_Small
+	// 23   12    REPEAT_DEFECT	// Common 05 M/N/C/S/K/*
+	if (pDefectData->m_DefectSubType == DefectSubType_MC)
+	{
+		SPRINTRAW(12, "MC");
+	}
+	else if (pDefectData->m_DefectSubType == DefectSubType_Mask)
+	{
+		SPRINTRAW(12, "MD");
+	}
+	else if (pDefectData->m_DefectSubType == DefectSubType_Common)
+	{
+		SPRINTRAW(12, "CD");
+	}
+	else if (pDefectData->m_DefectSubType == DefectSubType_NoDefect)
+	{
+		SPRINTRAW(12, "NO");
+	}
+	else
+	{
+		SPRINTRAW(12, "N");
+	}
+	// 24   12    	// Common 06 誘몄궗�슜 -> WSI �넂�씠 湲곗엯  	
+	//m_nPlanType == ditRaw::RTP_WSI �씠嫄몃줈 鍮꾧탳�븯�땲源� 媛��걫 鍮꾧탳�븞�릺怨� �꽆�뼱媛� 210205
+	if (pDefectData->m_ReviewDefect.m_nWsi_Type == 2)
+	{
+		SPRINTRAW(12, "%.03lf", pDefectData->m_ReviewDefect.m_fWsi_ResultData[1]);
+		
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 25   12    	// Common 07 誘몄궗�슜 -> CS �넂�씠 湲곗엯 
+	if (pDefectData->m_ReviewDefect.m_nWsi_Type == 2)
+	{
+		SPRINTRAW(12, "%.03lf", pDefectData->m_ReviewDefect.m_fWsi_ResultData[3]);
+
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 26   12    	// Common 08 �쟾 STEP �뙋�젙 D/F �쑀臾� 
+	SPRINTRAW(12, "*");
+	// 27   12    GRAY_MIN		// Common 09 Gray Min
+	SPRINTRAW(12, "%d", pDefectData->m_nLevelSrcMin);
+	// 28   12    GRAY_MAX		// Common 10 Gray Max
+	SPRINTRAW(12, "%d", pDefectData->m_nLevelSrcMax);
+	// 29   12    GRAY_AVG		// Common 11 Gray Average
+	SPRINTRAW(12, "%d", pDefectData->m_nLevelSrcAvg);
+	// 30   12    GRAY_DEF		// Common 12 Defect Peak
+	if (static_cast<int>(pDefectData->m_sDefectPeak) == 0)
+	{
+		SPRINTRAW(12, "1");
+	}
+	else
+	{ 
+		SPRINTRAW(12, "%d", pDefectData->m_sDefectPeak);
+	}
+
+	// 31 NO USE -> WSI Image Name 
+	if (pDefectData->m_ReviewDefect.m_nWsi_Type == 2)
+	{
+		if (strlen(pDefectData->m_ReviewDefect.m_strWsi_3DImageFilename))
+		{
+		SPRINTRAW(12, "%s", pDefectData->m_ReviewDefect.m_strWsi_3DImageFilename);
+		}
+		else
+		{
+			SPRINTRAW(12, "*");
+		}
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 32 NO USE -> CCD Image �쑀臾�
+	if (strlen(pDefectData->m_strAoiImageName))
+	{
+		SPRINTRAW(12, "O");
+	}
+	else
+	{
+		SPRINTRAW(12, "X");
+	}
+	// 33   12    CAM_POSITION	// Common 15 Scan 踰덊샇
+	SPRINTRAW(12, "%d", pDefectData->m_nScanIdx);
+	// 34   12    CAM_POSITION	// Common 16 Camera ID
+	SPRINTRAW(12, "%d", pDefectData->m_nCameraID);
+	// 35   12    Defect Idx				// Common 25 Defect Idx
+	SPRINTRAW(12, "%d", pDefectData->m_nDefectIdx);
+	// 36   12    R_SRC_MIN		// Common 18 R_SRC_MIN
+	SPRINTRAW(12, "%d", pDefectData->m_nLevelRefMin);
+	// 37   12    R_SRC_MAX		// Common 19 R_SRC_MAX
+	SPRINTRAW(12, "%d", pDefectData->m_nLevelRefMax);
+	// 38   12    R_SRC_AVG		// Common 20 R_SRC_AVG
+	SPRINTRAW(12, "%d", pDefectData->m_nLevelRefAvg);
+	// 39   12    Scan AI 遺꾨쪟寃곌낵			// Common 21 怨좉컼�궗 �엯�젰==>>>> 0405蹂�寃폳SI R Height//210405
+	if (pDefectData->m_ReviewDefect.m_nWsi_Type == 2)
+	{
+		SPRINTRAW(12, "%.03lf", pDefectData->m_ReviewDefect.m_fWsi_ResultData[4]);
+
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 40   12    Review AI 遺꾨쪟寃곌낵		// Common 22 怨좉컼�궗 �엯�젰==>>>> 0405蹂�寃폳SI G Height//210405
+	if (pDefectData->m_ReviewDefect.m_nWsi_Type == 2)
+	{
+		SPRINTRAW(12, "%.03lf", pDefectData->m_ReviewDefect.m_fWsi_ResultData[5]);
+
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 41   12    寃�異쒕え�뱶 (Dark or Bright)	// Common 23 怨좉컼�궗 �엯�젰==>>>> 0405蹂�寃폳SI B Height//210405
+	if (pDefectData->m_ReviewDefect.m_nWsi_Type == 2)
+	{
+		SPRINTRAW(12, "%.03lf", pDefectData->m_ReviewDefect.m_fWsi_ResultData[6]);
+
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+	// 42   12    寃�異쒖콈�꼸 RGB				// Common 24 怨좉컼�궗 �엯�젰 
+	CString strData;  // 寃�異� 梨꾨꼸 異붽� ex) 0, 1, 2 [ 21-03-23 KJG ] 
+	int nLayers = pDefectData->m_nHliLayers;
+	strItem = _T("");
+	for (int i = 0; i < 8; i++)
+	{
+		if (nLayers & 1)
+		{
+			if (strItem.IsEmpty()) strData.Format("%d", i);
+			else strData.Format(",%d", i);
+			strItem += strData;
+		}
+		nLayers = nLayers >> 1;
+	}
+	SPRINTRAW(12, "%s", strItem);
+
+	// 43	12	  Compactness			//201215 CJH - 43~46 �떊洹� Defect Feature 寃곌낵�뙆�씪 異붽�
+	SPRINTRAW(12, "%d", pDefectData->m_nCompact);
+	// 44	12	  Thickness
+	SPRINTRAW(12, "%d", pDefectData->m_nThickness);
+	// 45	12	  Major
+	SPRINTRAW(12, "%d", pDefectData->m_nMajor);
+	// 46	12	  Minor
+	SPRINTRAW(12, "%d", pDefectData->m_nMinor);
+	// 47	12	  WSI Defect Type 0 normal 1 metal 2Huge 3diffuse 4 trashy
+	if (pDefectData->m_ReviewDefect.m_nWsi_Type == 2)
+	{
+		if (strlen(GetWsiDefectType(pDefectData->m_ReviewDefect.m_fWsi_ResultData[0])))
+		{
+		SPRINTRAW(12, "%s", GetWsiDefectType(pDefectData->m_ReviewDefect.m_fWsi_ResultData[0]));
+	        }
+	        else
+	        {
+		SPRINTRAW(12, "*");
+	        }
+	}
+	else
+	{
+		SPRINTRAW(12, "*");
+	}
+
+	// 48	12	Defect Type 異붽� [ 21-03-23 KJG ]
+	if (pDefectData->m_DefectType == DefectType_RBlack)
+	{
+		SPRINTRAW(12, "RB");
+	}
+	else if (pDefectData->m_DefectType == DefectType_RWhite)
+	{
+		SPRINTRAW(12, "RW");
+	}
+	else if (pDefectData->m_DefectType == DefectType_TBlack)
+	{
+		SPRINTRAW(12, "TB");
+	}
+	else if (pDefectData->m_DefectType == DefectType_TWhite)
+	{
+		SPRINTRAW(12, "TW");
+	}
+	else
+	{
+		SPRINTRAW(12, "UN");
+	}
+	
+	// 49	12	 Frame Shrink �젙蹂� 異붽�
+	SPRINTRAW(12, "%d", pDefectData->m_bShrinked);
+	
+	// 50   12    CLASS_NO		// Zone Classification NO
+	// Zone Data
+	nValue = 0;
+	for (int i = 15; i >= 0; i--)
+	{
+		if (pDefectData->m_sZoneClassPixelCount[i] > 0)
+			nValue += 1;
+		if (i > 0)
+			nValue = nValue << 1;
+	}
+	SPRINTRAW(12, "%04X", nValue);
+
+	SPRINTRAWEND;   //以묒슂!!! �젮 留덉�留됱뿉 瑗� �엳�뼱�빞�븿!!!(�궘�젣湲덉�) [源��깭�쁽2020/9/23]
+
+	return TRUE;
+}
+
+BOOL CGlassRawCPJT::ReadMuraFile( CgrmGlassRawData* pData )//0404nwh
+{
+	CString strMacroFilePath;
+	{
+		strMacroFilePath.Format("%s\\%s", NETWORK_MURARAW_PATH, pData->GetGlassData()->m_strGlassID);
+		
+		CFileFind FF;
+
+		if (FF.FindFile(strMacroFilePath))
+		{
+			FF.FindNextFile();
+			strMacroFilePath = FF.GetFilePath();
+			FF.Close();
+		}
+		else
+		{
+			AKLOG("Find Macro File Fail. [%s]", strMacroFilePath);
+			return FALSE;
+		}
+	}
+	////Mura Image Server �듅�젙 �뤃�뜑�뿉 ���옣
+	CString strMacroImageSrcPath;
+	CString strMacroImageTarPath;
+
+	strMacroImageSrcPath.Format("%s\\%s", NETWORK_MURA_IMAGE_PATH, pData->GetGlassData()->m_strGlassID);
+	strMacroImageTarPath.Format("%s\\%s\\MuraImage", NETWORK_AOI_IMAGE_PATH, pData->GetGlassData()->m_strGlassID); //�깮媛곸��빐蹂댁옄
+
+	//CreateDirectory("D:\\Image\\Defect\\Mura",NULL); �븞�빐�룄�맆嫄곌컳�쓬
+	if (strMacroImageSrcPath.IsEmpty() == FALSE)
+	{
+		AKLOG("Macro Image File Copy Start[%s]", strMacroImageTarPath);
+		CakFileUtil::CopyFolder(strMacroImageSrcPath.GetBuffer(0), strMacroImageTarPath.GetBuffer(0), FALSE);
+
+		if (m_bReviewEndCheck == TRUE)
+		{
+			CakFileUtil::DeleteFolder(strMacroImageSrcPath.GetBuffer(0), FALSE);
+		}
+		AKLOG("Macro Image File Copy End");
+	}
+
+	///Mura 寃곌낵�뙆�씪 �씫怨� �벐湲� �궘�젣
+	if (m_MuraResultFile.openFile_Mura(strMacroFilePath.GetBuffer(0)) == TRUE)
+	{
+		AKLOG("Macro File Read Success : %dItem", m_MuraResultFile.GetSubPanelNum());
+		if (m_bReviewEndCheck == TRUE)
+		{
+			DeleteFile(strMacroFilePath);
+		}
+	}
+	else
+	{
+		AKLOG("Macro File Read Fail[%s]", strMacroFilePath);
+		//DeleteFile(strMacroResultTargetPath); 
+		return FALSE;
+	}
+	return TRUE;
+}
+
+
+void CGlassRawCPJT::SendMessageFTPUploadRaw( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	char strRTMSFile[32] = {};
+	char strServerRawFileSubPath[256] = {};
+	char strServer_SubFileName[32] = {};
+
+	GetFormatDescription(FTPCMD_RAW, strServerFolder, strServerFile, strLocalFolder, pLocalFile, strRTMSFile, strServerRawFileSubPath, strServer_SubFileName,pGlassData); //taek 201211
+  
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SubFilePath,         strServerRawFileSubPath);
+	strcpy(upParam.m_strServer_SubFileName,         strServer_SubFileName);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	strcpy(upParam.m_strRTMS_FileName, ""); //taek 201211
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+	// [C-PRJ] Image Upload Define - KHT (2020/11/19)
+	upParam.m_nDataType									= CFTPCopyDataParam::FTPDataType_Raw;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 30000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+
+}
+
+void CGlassRawCPJT::SendMessageFTPDownloadStack( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	char strRTMSFile[32] = {};
+	char strServerRawFileSubPath[256] = {};
+	char strServer_SubFileName[256] = {};
+
+	GetFormatDescription(FTPCMD_STACK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, strRTMSFile, strServerRawFileSubPath, strServer_SubFileName,pGlassData);
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	strcpy(upParam.m_strRTMS_FileName, "");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_DownFile;
+	// [C-PRJ] Image Upload Define - KHT (2020/11/19)
+	upParam.m_nDataType									= CFTPCopyDataParam::FTPDataType_Stack;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CGlassRawCPJT::SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPDownloader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	//GetFormatDescription(FTPCMD_DATAFILE, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+	{
+		CString strGlassIDOrg = pGlassData->m_strGlassID; 
+		CString strGlassID = strGlassIDOrg.Left(12);
+		sprintf(strServerFolder, "%s", pGlassData->m_strCassetteSequenceNo);
+		sprintf(strServerFile, "%s.dat", strGlassID.GetBuffer(0));  
+		sprintf(strLocalFolder,  "D:\\DIT_ResultData\\DownloadData"); 
+		sprintf(pLocalFile,  "%s.dat", strGlassID.GetBuffer(0)); 
+	}
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_DownFile;
+	// [C-PRJ] Image Upload Define - KHT (2020/11/19)
+	upParam.m_nDataType = CFTPCopyDataParam::FTPDataType_Unknown;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CGlassRawCPJT::SendMessageFTPUploadImage( _grmGlassData* pGlassData, emFTPCommand sort)
+{  
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[32];// = "*.*";
+	char strLocalFolder[256] = {};
+	char strLocalFile[32];// = "*.*"; 
+	char strRTMSFile[256] = {}; //taek 201211
+	char strServerRawFileSubPath[256] = {};
+	char strServer_SubFileName[256] = {};
+
+	GetFormatDescription(sort, strServerFolder, strServerFile, strLocalFolder, strLocalFile, strRTMSFile, strServerRawFileSubPath, strServer_SubFileName,pGlassData); //taek 201211
+ 
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				strLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	strcpy(upParam.m_strRTMS_FileName, 				strRTMSFile); //taek 201211
+	upParam.m_nCreateSignalFile							= FALSE;
+	upParam.m_nSendResultCode							= FALSE;
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+	// [C-PRJ] Image Upload Define - KHT (2020/11/19)
+	upParam.m_nDataType									= CFTPCopyDataParam::FTPDataType_Image;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_ImageUpload; // FTP Uploader�뿉�꽌�뒗 援щ텇�릺�뼱 �엳吏� �븡�쓬!
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+  
+
+BOOL CGlassRawCPJT::SendMessageFTPUploadIndexFile( _grmGlassData* pGlassData )
+{  
+	if(pGlassData == NULL) 
+		return FALSE;
+
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return FALSE;
+
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	char strRTMSFile[32] = {};
+	char strServerRawFileSubPath[256];
+	char strServer_SubFileName[256] = {};
+
+	GetFormatDescription(FTPCMD_INDEX, strServerFolder, strServerFile, strLocalFolder, pLocalFile, strRTMSFile, strServerRawFileSubPath, strServer_SubFileName, pGlassData);
+
+
+	// 	if(0)//test 
+	// 	{
+	// 		sprintf(strServerFolder, "HDD1/DIT/TestC");
+	// 		ServerFile = "ftptestfile.txt";
+	// 
+	// 		sprintf(strLocalFolder, "D:");
+	// 		pLocalFile = "ftptestfile.txt";
+	// 	}
+
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	strcpy(upParam.m_strRTMS_FileName, "");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+	// [C-PRJ] Image Upload Define - KHT (2020/11/19)
+	upParam.m_nDataType									= CFTPCopyDataParam::FTPDataType_Index;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+	return TRUE;
+}
+
+void CGlassRawCPJT::GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, char* pRTMSFile, char* pServerFileSubPath, char* pServerFileSubName, _grmGlassData* pGlassData) //taek 201211
+{  
+	CString strGlassID = pGlassData->m_strGlassID;
+	//For test
+	//if (strlen(strGlassID) == 0) strGlassID = "HPANELID";
+
+	CString strGlassIDLevel6th = strGlassID.Left(6);
+	CString strGlassIDLevel5th = strGlassID.Left(5);
+	CString strGlassIDLevel8th = strGlassID.Left(8);
+	
+	CString strLotID = pGlassData->m_strLotID;
+	CString strStepID = pGlassData->m_strStepID;
+	CString strProcessID = pGlassData->m_strProcessID;
+	//For test
+	//if (strlen(strStepID) == 0) strStepID = "F11112";
+
+	strLotID.MakeLower();
+	strStepID.MakeLower();
+	strGlassID.MakeLower();
+	strGlassIDLevel6th.MakeLower();
+	strProcessID.MakeLower();
+
+	switch(sort)
+	{ 
+	case FTPCMD_AOI_IMAGE:
+		{
+			if(strGlassID.GetLength() > 6)
+				sprintf(pServerPath, "\\%s\\%s\\%s\\%s\\", strProcessID, strStepID, strGlassIDLevel6th, strGlassID);
+			else
+				sprintf(pServerPath, "\\%s\\%s\\%s\\", strProcessID, strStepID, strGlassIDLevel6th);
+
+			sprintf(pLocalPath, "%s%s", LOCAL_AOI_IMAGE_PATH, strGlassID.GetBuffer(0));  
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+		}
+		break;
+	case FTPCMD_REVIEW_IMAGE: 
+		{
+			CTime time = m_tmFileCreateTime;
+
+			CString strTime = NULL;
+			CString strInsEndTime = NULL;
+
+			strTime = pGlassData->m_tmGlassLoading.Format("%Y%m%d%H%M%S");
+			strInsEndTime = pGlassData->m_tmInspectionEND.Format("%Y%m%d%H%M%S");
+
+			if (strGlassID.GetLength() > 6)
+				sprintf(pServerPath, "\\%s\\%s\\%s\\%s\\", strProcessID, strStepID, strGlassIDLevel6th, strGlassID);
+			else
+				sprintf(pServerPath, "\\%s\\%s\\%s\\", strProcessID, strStepID, strGlassIDLevel6th);
+
+			sprintf(pLocalPath, "%s%s_%s", LOCAL_REV_IMAGE_PATH, strGlassID.GetBuffer(0), strTime);
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+            //Result ini 由щ럭 �씠誘몄� path 梨꾩슦湲�
+            CString strRawFilePathName = NULL;
+            CString strLine = NULL;
+			CString strPath = NULL;
+            strRawFilePathName += LOCAL_RAWPATH_INFO_INI_PATH;
+            strRawFilePathName += RAWINFO_FILE_NAME;
+            FILE* pf = fopen(strRawFilePathName.GetBuffer(0), "a");
+			if(pf != NULL)
+            {
+				strLine = pServerPath;
+				strPath = strLine.Left(strLine.GetLength() - 1);
+            	fprintf(pf, "IMGPATH= Z:\%s\n", strPath.GetBuffer(0));
+            	fprintf(pf, "DISK=FILESERVER\n");
+				fclose(pf);
+			}
+
+			//RTMS 寃곌낵 �뙆�씪 �뾽濡쒕뱶
+			CString strRTMSPathFileName = NULL;
+			CString strRTMSFileName = NULL;
+
+			strRTMSFileName.Format("%s#%s#%04d%02d%02d%02d%02d%02d.Signal", pGlassData->m_strEquipID, pGlassData->m_strProductID, time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond());
+
+			strRTMSPathFileName += LOCAL_RTMS_INFO_PATH;
+			strRTMSPathFileName += strRTMSFileName;
+
+			// 			strRTMSFileName = strRawFilePath.Left(strRawFilePath.GetLength()-1); //taek 留덉�留� 媛� 鍮쇨퀬 媛��졇�삤湲� test
+
+			FILE* pfile = fopen(strRTMSPathFileName.GetBuffer(0), "a");
+
+			sprintf(pRTMSFile, "%s", strRTMSPathFileName); //taek 201211
+
+			if (pfile != NULL)
+			{
+				fprintf(pfile, "MODULE_ID = %s\n", pGlassData->m_strEquipID);
+				fprintf(pfile, "PRODUCT_ID = %s\n", pGlassData->m_strProductID);
+				fprintf(pfile, "PROCESS_ID = %s\n", pGlassData->m_strProcessID);
+				fprintf(pfile, "STEP_ID = %s\n", pGlassData->m_strStepID);
+				fprintf(pfile, "PANEL_ID = %s\n", pGlassData->m_strGlassID);
+				fprintf(pfile, "RESULT = *\n");
+				fprintf(pfile, "REASON_CODE = *\n");
+				fprintf(pfile, "RDP_PATH_RAW = \\cfq1raw1cai1coi%s\n", GetRawFilePath());
+				fprintf(pfile, "RDP_PATH_IMAGE = \\cfq1img1cai1coi%s\n", strLine.Left(strLine.GetLength() - 1));
+				fprintf(pfile, "INSP_TIME = %s\n", strInsEndTime);
+				fclose(pfile);
+			}
+		}
+		break;
+	case FTPCMD_RAW:   
+		{
+			CTime time = m_tmFileCreateTime;
+			SetRawFilePath("");
+
+			CString strFileName;//�뙆�씪�깮�꽦 �떆媛� �븣臾몄뿉 �뿬湲곗꽌 �젙�솗�븯寃� �뙆�씪紐� �떎�떆 �젙�젙
+			{
+				//Glass �젙蹂�
+				CTime CurrTime = m_tmFileCreateTime;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				// �떆媛�, �솗�옣�옄 �뾾�빊 [11/20/2020 Server]
+				strFileName.Format("%s", pGlassData->m_strGlassID);
+				strFileName.MakeLower();
+			}
+			/*sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Data", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(),
+				strGlassIDLevel5th.GetBuffer(0),
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); */
+		
+			//if (strGlassID.GetLength() > 6)
+			//	sprintf(pServerPath, "\\%s\\%s\\%s\\%s\\", strLotID, strStepID, strGlassIDLevel6th, strGlassID);
+			//else
+				sprintf(pServerPath, "\\%s\\%s\\%s\\", strProcessID, strStepID, strGlassIDLevel6th);
+			
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+
+			CString strServerSubRawFilePath= NULL;
+			CString strServerSubRawFileName = NULL;
+			{
+				strServerSubRawFilePath += NETWORK_AOIRAWFILE_SUB_PATH;
+
+				CString strTime;
+				CTime CurrTime = m_tmFileCreateTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				// �떆媛�, �솗�옣�옄 �뾾�빊 [11/20/2020 Server]
+				strServerSubRawFileName.Format("\\%s_%s", pGlassData->m_strGlassID, strTime);
+				//strServerSubRawFilePath += strServerSubRawFileName;
+				BOOL bIsBDI = strcmp((pGlassData->m_strLine), _T("BDI")) == 0 ? TRUE : FALSE;  // BDI �씤 寃쎌슦 InspectorEnd �떆�뿉 SubFile �깮�꽦 [ 21-03-23 KJG ]
+				if (m_bReviewEndCheck || bIsBDI)  // InspectEnd �떆�뿉�뒗 SubFile 誘몄깮�꽦 蹂�寃� [ 21-03-18 KJG ] 
+				{
+					sprintf(pServerFileSubName, "%s", strServerSubRawFileName.GetBuffer(0));
+					sprintf(pServerFileSubPath, "%s", strServerSubRawFilePath.GetBuffer(0));
+				}
+				else
+				{
+					sprintf(pServerFileSubName, "%s", "");
+					sprintf(pServerFileSubPath, "%s", "");
+				}
+
+			}
+
+			//Result ini raw �뙆�씪�씠由�(path�룷�븿)write
+			CString strRawFilePathName = NULL;
+			CString strLine = NULL;
+			strRawFilePathName += LOCAL_RAWPATH_INFO_INI_PATH;
+			strRawFilePathName += RAWINFO_FILE_NAME;
+			FILE* pf = fopen(strRawFilePathName.GetBuffer(0), "w");
+			if(pf != NULL)
+			{
+				strLine = pServerPath + strFileName;
+				fprintf(pf, "[RESULT_PATH]\n");
+				fprintf(pf, "RAWPATH= X:\%s\n", strLine.GetBuffer(0));
+				SetRawFilePath(strLine.GetBuffer(0));
+				fprintf(pf, "SUMPATH= \n");
+				fclose(pf);
+			} 
+		}
+		break;
+	case FTPCMD_STACK:
+		{
+		//201218 CJH - Stack Download 寃쎈줈 �꽕�젙
+			sprintf(pServerPath, "\\stack\\%s\\%s\\%s", strProcessID,
+				strStepID, 
+				strGlassIDLevel6th.GetBuffer(0)); 
+
+			sprintf(pServerFile, "%s", 
+				strGlassID);
+
+			sprintf(pLocalPath, "%s", m_StackResult.getStackLocalPath()); 
+			sprintf(pLocalFile, "%s", strGlassID.GetBuffer(0)); 
+		}
+		break;
+		
+		case FTPCMD_MURA_IMAGE: //0404nwh
+		{	//
+			/*CTime time = m_tmFileCreateTime;
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+				
+							sprintf(pLocalPath, "%s%s", LOCAL_MURA_IMAGE_PATH, strGlassID.GetBuffer(0));
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");*/
+		
+			if (strGlassID.GetLength() > 6)
+				sprintf(pServerPath, "\\%s\\%s\\%s\\%s\\", strProcessID, strStepID, strGlassIDLevel6th, strGlassID);
+			else
+				sprintf(pServerPath, "\\%s\\%s\\%s\\", strProcessID, strStepID, strGlassIDLevel6th);
+
+			sprintf(pLocalPath, "%s%s", LOCAL_MURA_IMAGE_PATH, strGlassID.GetBuffer(0)); 
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*"); 
+		}
+		
+		break;
+	case FTPCMD_INDEX:
+		{
+			CTime time = m_tmFileCreateTime;
+			sprintf(pServerPath, "INDEX\\%s", pGlassData->m_strEquipID);
+			sprintf(pServerFile, "%04d%02d%02d_%s.csv", time.GetYear(), time.GetMonth(), time.GetDay(),	pGlassData->m_strStepID); 
+
+			sprintf(pLocalPath, "%s", LOCAL_INDEX_PATH); 
+			sprintf(pLocalFile, "%s", pServerFile); 
+		}
+		break;
+
+	case FTPCMD_LINK:   
+		{ 
+			CTime time = m_tmFileCreateTime;
+			CString strFileName;//�뙆�씪�깮�꽦 �떆媛� �븣臾몄뿉 �뿬湲곗꽌 �젙�솗�븯寃� �뙆�씪紐� �떎�떆 �젙�젙
+			{
+				//Glass �젙蹂�
+				CTime CurrTime = m_tmFileCreateTime;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				strFileName.Format("%s_%s_%s.csv", pGlassData->m_strOperID, pGlassData->m_strGlassID, strTime.GetBuffer(0));
+			}
+			sprintf(pServerPath, "%s\\%s\\%s\\%s\\%s", "LINK", pGlassData->m_strEquipID, 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+		}
+		break;
+	} 
+
+
+}
+ 
+
+
+CString CGlassRawCPJT::GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam)
+{  
+	CString sStr;
+	switch(nDefectInfoType)
+	{
+	case DMT_DefectJudge:// Judge
+		{
+			switch (nParam)
+			{
+			case Judge_OK:			sStr.Format("OK");
+				break;
+			case Judge_RP:			sStr.Format("RP");
+				break;
+			case Judge_NG:			sStr.Format("NG");
+				break;
+			case Judge_TR:			sStr.Format("TR");
+				break;
+			case Judge_PR:			sStr.Format("PR");
+				break;
+			case Judge_PT:			sStr.Format("PT");
+				break;
+			case Judge_Review:		sStr.Format("RV");
+				break;
+			case Judge_RC:			sStr.Format("RC");
+				break;
+			case Judge_Size:		sStr.Format("SZ");
+				break;
+			case Judge_VI:			sStr.Format("VI");
+				break;
+			case Judge_Rework:		sStr.Format("RW");
+				break;
+			case Judge_Unknown:		sStr.Format("OK");//sStr.Format("Unknown");	//Unknown�룄 �씪�떒 OK
+				break;
+			default:				sStr.Format("OK");//sStr.Format("Ets");		
+				break;
+			}
+		}
+		break;
+
+	case DMT_DefectSizeType: 
+		{
+			sStr = "S";
+			switch(nParam)
+			{
+				//case SizeType_Unknown:	 sStr.Format("U");	break; 
+			case 1/*SizeType_Small*/:	 sStr.Format("S");
+				break; 
+			case 2/*SizeType_Mid*/:		 sStr.Format("M");
+				break; 
+			case 3/*SizeType_Large*/:	 sStr.Format("L");
+				break; 
+			case 4/*SizeType_Huge*/:		 sStr.Format("O");
+				break;
+				//case SizeType_Ultra:	 sStr.Format("Ultra");		break;
+				//default:				 sStr.Format("Ets");		break;
+			}
+		}
+		break;
+
+
+	}
+	return sStr;
+}
+
+CString CGlassRawCPJT::GetWsiDefectType(int nType)
+{
+	CString strDefectType=_T("");
+	switch (nType)
+	{
+	case 0:		 strDefectType.Format("normal");
+		break;
+	case 1:		 strDefectType.Format("metal");
+		break;
+	case 2:		 strDefectType.Format("huge");
+		break;
+	case 3:		 strDefectType.Format("diffuse");
+		break;
+	case 4:		 strDefectType.Format("trashy");
+		break;
+	}
+	return strDefectType;
+}
+
diff --git a/ReviewHistory/ReveiwHistory/GlassRawCPJT.h b/ReviewHistory/ReveiwHistory/GlassRawCPJT.h
new file mode 100644
index 0000000..88b6901
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawCPJT.h
@@ -0,0 +1,134 @@
+#pragma once
+
+#include "GlassRawBase.h"
+#include "GlassRawRTMS.h"
+#include "StackResultCPJT.h"
+#include "AnaResultFile.h"
+#include "MacroResultFile.h"
+#include "CustomizeReview.h"
+#include "InterfaceFTP.h"
+
+class CGlassRawCPJT : public CGlassRawBase, public CInterfaceFTP
+{
+public:
+	enum emDefectMemberType
+	{
+		DMT_DefectJudge = 0,
+		DMT_DefectSizeType
+	}; 
+
+public:
+	CGlassRawCPJT(void);
+	~CGlassRawCPJT(void);
+
+	static char* GetClassName(){return "C-PJT";};
+
+	virtual BOOL SequenceGlassLoading(CgrmGlassRawData* pData);
+	virtual BOOL SequenceInspectEnd(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewStart(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewEnd(CgrmGlassRawData* pData);
+
+
+	virtual BOOL WriteAOIFile(CgrmGlassRawData* pData);
+	virtual BOOL ReadAOIFile(CgrmGlassRawData* pData){return TRUE;};
+
+	virtual BOOL SequenceFtpUpload(char* pRawFileName);
+
+	virtual void NotifyUpdateOptionInfo(){/*m_StackResult.readOptionFile();*/};
+
+
+protected:
+	
+	virtual void SendMessageFTPUploadRaw(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPDownloadStack(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPUploadImage(_grmGlassData* pGlassData, emFTPCommand sort); 
+	virtual BOOL SendMessageFTPUploadIndexFile(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData);
+	virtual void GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, char* pRTMSFile,char* pServerFileSubPath, char* pServerFileSubName,_grmGlassData* pGlassData);
+
+
+	BOOL ReadMuraFile(CgrmGlassRawData* pData);
+	BOOL MakeAOIFile(CgrmGlassRawData* pData);
+	
+	void SetRawFilePath(CString strPath) { m_strRawFilePath = strPath; }
+	CString GetRawFilePath() { return m_strRawFilePath; }
+
+	void makeDataHeader(CString& strLine, _grmGlassData* pGlassData);
+	void makeDataGlass(CString& strLine, _grmGlassData* pGlassData);
+	void makeDataCell(CString& strLine, CgrmGlassRawData* pData, _grmCellData* pCellData);
+	BOOL makeDataDefect(CString& strLine, CgrmGlassRawData* pData, _grmDefectData* pDefectData);
+ 
+	CString GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam);
+
+public:
+	void SetEquipType(int nType){m_nEquipType = nType;};
+	CString GetWsiDefectType(int nType);
+protected:
+
+protected:
+	int m_nEquipType; // 0:Inline, 1:Offline
+
+	CString m_strRawFilePath;
+
+	CAnaResultFile  m_GlassRawAna; //디펙분석용결과파일 [김태현2020/9/15]
+	CGlassRawRTMS	m_GlassRawRTMS;//RTMS용 결과파일 생성관리 [김태현 2018/12/5]
+	CMacroResultFile m_MuraResultFile; //무라용 결과파일 생성관리 [김태현 2018/12/5]
+
+	CStackResultCPJT m_StackResult;
+	BOOL	m_bReviewEndCheck;    // InspectEnd 시에 Raw_im 폴더에 SubFile 생성 안하기 위해 사용 [ 21-03-18 KJG ]
+	CTime	m_tmReviewStart;		
+	CTime	m_tmReviewEnd;		
+
+	int m_nWriteRawDefectIdx;
+};
+
+struct stCellData
+{
+	int iModel;
+	int ixCell, iyCell;
+	void SetIndex(int im, int ix, int iy)
+	{
+		iModel = im;
+		ixCell = ix;
+		iyCell = iy;
+	}
+	BOOL AddDefect(_grmDefectData* pDefect)
+	{
+		if (iModel == pDefect->m_nModelIdx)// edge crack은 포함안되게.. 모델이 패턴부인지 확인작업 줄이기.
+		{
+			m_Defects.push_back(pDefect);
+			return TRUE;
+		}
+		return FALSE;
+	}
+	_grmDefectData* GetDefect(int i) { return m_Defects[i]; }
+	int GetDefectCount() { return (int)m_Defects.size(); }
+	std::vector<_grmDefectData*> m_Defects;
+};
+struct stCellStorage
+{
+	stCellData *m_pCells;
+	int m_nCell;
+	stCellStorage(int n)
+	{
+		m_nCell = n;
+		m_pCells = new stCellData[n];
+	}
+	~stCellStorage()
+	{
+		delete[] m_pCells;
+	}
+	stCellData* GetCellData(int iCell)
+	{
+		return m_pCells + iCell;
+	}
+	BOOL AddDefect(_grmDefectData *pDefect)
+	{
+		if (pDefect->m_nCellIdx < 0)
+		{
+			return FALSE;
+		}
+		return GetCellData(pDefect->m_nCellIdx)->AddDefect(pDefect);
+	}
+	int GetCellCount() { return m_nCell; }
+};
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/GlassRawCSOT.cpp b/ReviewHistory/ReveiwHistory/GlassRawCSOT.cpp
new file mode 100644
index 0000000..c10d4fe
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawCSOT.cpp
@@ -0,0 +1,1696 @@
+#include "StdAfx.h"
+#include "GlassRawCSOT.h"
+#include "akLoggerExt.h"
+#include "MacroResultFile.h"
+#include "akCore/akFileUtil.h"
+#include "akGridData.h"
+
+//#include "AOIDefinitionType.h"
+//#include "AOIDefinition.h"
+ 
+#define	FTPCopyDataCmd_RawDownload		1
+#define	FTPCopyDataCmd_RawUpload			2
+#define	FTPCopyDataCmd_LotUpload			3
+#define	FTPCopyDataCmd_ImageUpload		4
+
+#define MAX_PATH_NUM				255
+#define MAX_FILE_NUM				100
+
+#define LOCAL_INDEX_PATH			"D:\\DIT_ResultData\\Index\\"	  
+#define LOCAL_REV_IMAGE_PATH		"D:\\ResultData\\Upload\\Image\\" 
+#define LOCAL_AOI_IMAGE_PATH		"D:\\Image\\Defect\\" 
+#define LOCAL_MURA_IMAGE_PATH		"D:\\DIT_ResultData\\Mura\\IMG\\" 
+#define LOCAL_DEEP_PATH				"D:\\DIT_ResultData\\Deeplearning\\"
+
+enum FTPProcessType { FTPProcessType_DownFile=0, FTPProcessType_UpFile, FTPProcessType_Count };
+class CFTPCopyDataParam
+{
+public:
+	CFTPCopyDataParam()				{ Reset(); }
+	virtual ~CFTPCopyDataParam()	{ Reset(); }
+	void Reset()
+	{
+		memset(this, 0, sizeof(CFTPCopyDataParam));
+		m_hSenderWnd = GetCurrentProcessWndHandle();
+	}
+
+	const HWND	GetSenderWnd() const						{ return m_hSenderWnd; }
+	void		SetSenderWnd(HWND hWnd)						{ m_hSenderWnd = hWnd; }
+
+public:
+	int		m_nProcessType;								// 프로세스 타입
+	int 	m_nCreateSignalFile;						// 시그널 파일 생성유무
+	int		m_bFirstPriority;							// 최상위 우선순위유무
+	int		m_nSendResultCode;							// 보낸 결과 코드
+
+	TCHAR	m_strServer_FolderName[MAX_PATH_NUM];		// 서버 경로명
+	TCHAR	m_strServer_FileName[MAX_FILE_NUM];			// 서버 파일명
+
+	TCHAR	m_strLocal_FolderName[MAX_PATH_NUM];		// 로컬 경로명
+	TCHAR	m_strLocal_FileName[MAX_FILE_NUM];			// 로컬 파일명
+
+	TCHAR	m_strServer_SignalFolderName[MAX_PATH_NUM];	// 서버 시그널 경로명
+	TCHAR	m_strServer_SignalFileName[MAX_FILE_NUM];	// 서버 시그널 파일명
+
+protected:
+	HWND	m_hSenderWnd;								// 보낸 프로그램 윈도우
+
+	static HWND GetCurrentProcessWndHandle()
+	{
+		DWORD dwPID = GetCurrentProcessId();
+		HWND hWnd = FindWindow(NULL, NULL);
+		while (hWnd != NULL)
+		{
+			if (GetParent(hWnd) == NULL){
+				DWORD dwProcId;
+				GetWindowThreadProcessId(hWnd, &dwProcId);
+				if (dwPID == dwProcId){
+					return hWnd;
+				}
+			}
+			hWnd = GetWindow(hWnd, GW_HWNDNEXT);
+		}
+		return NULL;
+	}
+};
+
+
+CGlassRawCSOT::CGlassRawCSOT(void)
+{
+	m_GlassRawRTMS.SetMuraResult(&m_MuraResultFile);
+}
+
+CGlassRawCSOT::~CGlassRawCSOT(void)
+{
+}
+
+BOOL CGlassRawCSOT::SequenceGlassLoading( CgrmGlassRawData* pData )
+{
+	if(m_StackResult.getStackUse())
+	{
+		SendMessageFTPDownloadStack(pData->GetGlassData()); //스택파일 다운 요청 [김태현 2019/1/12]
+		m_StackResult.StackFileReadStart(pData->GetGlassData()->m_strGlassID);
+	}
+
+	SendMessageFTPDownloadDataFile(pData->GetGlassData());
+	return TRUE;
+}
+
+BOOL CGlassRawCSOT::SequenceInspectEnd( CgrmGlassRawData* pData )
+{
+	m_tmReviewEnd = m_tmReviewStart = CTime::GetCurrentTime();
+
+
+	if(m_StackResult.getStackUse())
+	{
+		m_StackResult.StackFileReadStop();
+	}
+
+	ReadMuraFile(pData);
+	
+	if(0) //이제 end시점에 파일 생성하지 않음(파일시간때문에 두번 올라갈수잇음) [김태현 2019/1/15]
+	{
+		if(!WriteAOIFile(pData))
+			return FALSE;
+
+		SendMessageFTPUploadRaw(pData->GetGlassData());
+	}
+	
+	return TRUE;
+}
+
+BOOL CGlassRawCSOT::SequenceReviewStart( CgrmGlassRawData* pData )
+{
+	m_tmReviewStart = m_tmReviewEnd = CTime::GetCurrentTime();
+
+	SequenceCustomizeReview(pData);
+	
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawCSOT::SequenceCustomizeReview( CgrmGlassRawData* pData )
+{
+	_grmGlassData* pGlass = pData->GetGlassData();
+	/*
+	//이전 생성된 커스터 마이징 데이터 삭제
+	{
+		pGlass->m_nDefectNum;
+		for(int i=pGlass->m_nDefectNum-1; i>=0; i--)
+		{
+			if(pData->GetDefectData(i)->m_nCustomizeDefectType == 0
+				|| pData->GetDefectData(i)->m_nCustomizeDefectType == 1000)
+			{
+				pGlass->m_nDefectNum = i+1;
+				break;
+			}
+		}
+	}
+
+	//커스터마이즈 데이터 로드
+	{
+		if(m_CustomizeReview.openFile(pGlass->m_strRecipeName))
+		{
+			pGlass->m_nCustomizePlanType = m_CustomizeReview.GetCustomizeType();
+			int nCustomReviewNum = m_CustomizeReview.GetCustomizeReviewNum();
+
+			int nDefectStpoint = pGlass->m_nDefectNum;
+			if(pGlass->m_nCustomizePlanType == 2) nDefectStpoint = 0;
+			int nRealDefectIndex;
+			_grmDefectData* pGrmDefect;
+			_CustomizeReview* pCustomizeReview;
+			for(int i=0; i<nCustomReviewNum; i++)
+			{
+				nRealDefectIndex = nDefectStpoint+i;
+				pGrmDefect = pData->GetDefectData(nRealDefectIndex);
+				pCustomizeReview = m_CustomizeReview.GetCustomizeReivew(i);
+
+				pGrmDefect->m_nCustomizeDefectType	 = pCustomizeReview->m_nCustomizeDefectType;
+				pGrmDefect->m_dCustomizeDefectPosXmm = pCustomizeReview->m_dCustomizeDefectPosXmm;
+				pGrmDefect->m_dCustomizeDefectPosYmm = pCustomizeReview->m_dCustomizeDefectPosYmm;
+				pGrmDefect->m_nCustomizeParam1 = pCustomizeReview->m_nCustomizeParam1;
+				pGrmDefect->m_nCustomizeParam2 = pCustomizeReview->m_nCustomizeParam2;
+			}
+			pGlass->m_nDefectNum = nDefectStpoint+nCustomReviewNum;
+
+			pGlass->m_nCustomizeDataReadResult = 1;
+		}
+		else
+		{
+			pGlass->m_nCustomizeDataReadResult = 2;
+		}
+	}
+
+	if(pGlass->m_nCustomizeDataReadResult == 1) return TRUE;
+	*/
+
+	return FALSE;
+}
+
+
+BOOL CGlassRawCSOT::SequenceReviewEnd( CgrmGlassRawData* pData )
+{ 
+	m_tmReviewEnd = CTime::GetCurrentTime();
+
+	if(WriteAOIFile(pData) == FALSE)
+		return FALSE;
+
+	_grmGlassData* pGlassData = pData->GetGlassData();
+	SendMessageFTPUploadRaw(pGlassData);
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_REVIEW_IMAGE);
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_AOI_IMAGE); 
+	if(m_MuraResultFile.IsRead()) SendMessageFTPUploadImage(pGlassData, FTPCMD_MURA_IMAGE);
+	SendMessageFTPUploadLinkFile(pGlassData);
+
+	if(WriteIndexFile(pGlassData))
+	{
+		SendMessageFTPUploadIndexFile(pGlassData);
+	}
+	
+	return TRUE;
+}
+
+BOOL CGlassRawCSOT::SequenceFtpUpload( char* pRawFilePathName )
+{
+
+	CTime tmFileCreate; 
+	_grmGlassData GlassData;
+	_grmGlassData* pGlassData = &GlassData;
+
+	//정보 얻어오기 [김태현 2019/1/25]
+	{
+		//"D:\\DIT_ResultData\\Raw\\";
+		//6CCF01P7_HPANELID_20190125_002545.csv
+
+		char* pFileName = CakFileUtil::getFileName(pRawFilePathName);
+		char* pext = CakFileUtil::getFileExt(pRawFilePathName);
+
+		if(!strcmp(pext, "csv") == FALSE) return FALSE;
+
+		CakParser parser;
+		parser.process(pFileName, "_.");
+		if(parser.getTokNum() < 5) return FALSE;
+
+		strcpy(pGlassData->m_strOperID, parser.getTokStr(0));
+		strcpy(pGlassData->m_strGlassID, parser.getTokStr(1));
+		char* pDate = &pFileName[parser.getTokPos(2)];
+		char* pTime = &pFileName[parser.getTokPos(3)];
+		int nData[8]={};
+		nData[0] = (pDate[0]-'0')*1000 + (pDate[1]-'0')*100 + (pDate[2]-'0')*10+ (pDate[3]-'0')*1;
+		nData[1] = (pDate[4]-'0')*10+ (pDate[5]-'0')*1;
+		nData[2] = (pDate[6]-'0')*10+ (pDate[7]-'0')*1;
+		nData[3] = (pTime[0]-'0')*10+ (pTime[1]-'0')*1;
+		nData[4] = (pTime[2]-'0')*10+ (pTime[3]-'0')*1;
+		nData[5] = (pTime[4]-'0')*10+ (pTime[5]-'0')*1;
+
+		CTime tmTemp(nData[0], nData[1], nData[2], nData[3], nData[4], nData[5] );
+		tmFileCreate = tmTemp;
+
+		FILE* pf = fopen(pRawFilePathName, "r");
+		if(pf)
+		{
+			char buffer[512];
+			fgets(buffer, 512, pf);
+			if(buffer[0] != 'H') return FALSE;
+			fgets(buffer, 512, pf);
+			fgets(buffer, 512, pf);
+
+			fgets(buffer, 512, pf);buffer[strlen(buffer)-1] = 0;
+			strcpy(pGlassData->m_strEquipID, &buffer[strlen("EQUIP_TYPE:")]);
+
+			fgets(buffer, 512, pf);buffer[strlen(buffer)-1] = 0;
+			strcpy(pGlassData->m_strStepID, &buffer[strlen("EQUIP_ID:")]);
+		}
+		else
+		{
+			return FALSE;
+		}
+
+
+		CakFileUtil::getPath(pGlassData->m_strPath, 256, pRawFilePathName);
+
+	}
+
+
+
+	m_tmReviewEnd = m_tmReviewStart = tmFileCreate;
+
+ 
+	SendMessageFTPUploadRaw(pGlassData);
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_REVIEW_IMAGE);
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_AOI_IMAGE); 
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_MURA_IMAGE);//없으면 실패 하겠지
+	SendMessageFTPUploadLinkFile(pGlassData);
+
+	if(WriteIndexFile(pGlassData))
+	{
+		SendMessageFTPUploadIndexFile(pGlassData);
+	}
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawCSOT::WriteAOIFile( CgrmGlassRawData* pData )
+{
+	BOOL bResult = TRUE;
+	
+	bResult &= MakeAOIFile(pData);
+	bResult &= MakeAnaFile(pData);
+
+	m_GlassRawRTMS.WriteAOIFile(pData);
+
+	AKLOG("WriteAOIFile Complete");
+	return bResult;
+}
+
+BOOL CGlassRawCSOT::MakeAOIFile( CgrmGlassRawData* pData )
+{
+	_grmGlassData* pGlass = pData->GetGlassData();
+	CString strFilePathName;
+	CString strFileName;//파일생성 시간 때문에 여기서 정확하게 파일명 다시 정정
+	{
+		//Glass 정보
+		CTime CurrTime = m_tmReviewEnd;
+		CString strTime;
+		strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+			CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+		strFileName.Format("%s_%s_%s.csv", pGlass->m_strOperID, pGlass->m_strGlassID, strTime.GetBuffer(0));
+	}
+	
+	strFilePathName.Format("%s\\%s", pGlass->m_strPath, strFileName);//pGlass->m_strFileName);
+	//strFilePathName.Format("C:\\AOIServer\\NFS\\RAW\\%s", pData->GetGlassData()->m_strFileName);
+	
+	
+	//FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if(pf == NULL)
+	{
+		AKLOG("MakeAOIFile Fail : [%s]", strFilePathName.GetBuffer(0));
+		return FALSE;
+	}
+	
+	
+	
+	CString strBuffer;
+	CString strLine;
+
+	//////////////////////////////////////////////////////////////////////////
+	//HEDER
+	fprintf(pf, "HEADER_BEGIN\n");
+	{
+		makeDataHeader(strLine, pGlass);
+		fprintf(pf, "%s", strLine);
+	}
+	fprintf(pf, "HEADER_END\n\n");
+
+	//////////////////////////////////////////////////////////////////////////
+	//GLASS_DATA
+	fprintf(pf, "GLASS_DATA_BEGIN\n");
+	{
+		fprintf(pf, "GLASS_ID,OWNER_CODE,OWNER_TYPE,PRODUCT_ID,PROCESS_ID,PRODUCT_GROUP,LOT_ID,CST_ID,SLOT_ID,PRE_PROCESS_ID,PRE_EQP_ID,PRE_CHAMBER_ID,PRE_RECIPE_ID,GROUP_ID,AUTOSAMPLEFLAG\n");
+		
+		makeDataGlass(strLine, pGlass);
+		fprintf(pf, "%s\n", strLine);
+	}
+	fprintf(pf, "GLASS_DATA_END\n\n");
+
+	//////////////////////////////////////////////////////////////////////////
+	//EQP_GLASS_DATA
+	fprintf(pf, "EQP_GLASS_DATA_BEGIN\n");
+	{
+		fprintf(pf, "RECIPE_NO,RECIPE_NAME,START_TIME,END_TIME,TACT_TIME,GLASS_YIELD,TOTAL_PANEL_CNT,OK_PANEL,NG_PANEL,X1_PANEL,X2_PANEL,X3_PANEL,X4_PANEL,X5_PANEL,X6_PANEL,X7_PANEL,X8_PANEL,X9_PANEL,TT_DEFECT_CNT,S_SIZE_DEFECT_CNT,M_SIZE_DEFECT_CNT,L_SIZE_DEFECT_CNT,GLASS_ID_DCR,TT_MURA_CNT,POINT_MURA_CNT,LINE_MURA_CNT,AREA_MURA_CNT,POINT_1,POINT_2,POINT_3,POINT_4,POINT_5,GLASS_JUDGE,GLASS_GRADE\n");
+
+		makeDataEQPGlass(strLine, pData);
+		fprintf(pf, "%s\n", strLine);
+	}
+	fprintf(pf, "EQP_GLASS_DATA_END\n\n");
+
+	//////////////////////////////////////////////////////////////////////////
+	//BLOCK_SUMMARY
+	fprintf(pf, "BLOCK_SUMMARY_BEGIN\n");
+	{
+		fprintf(pf, "BLOCK_ID,BLOCK_JUDGE_AOI,BLOCK_JUDGE_MURA,BLOCK_JUDGE_ATS,BLOCK_JUDGE_TEG,TT_PANEL,OK_PANEL,NG_PANEL,X1_PANEL,X2_PANEL,X3_PANEL,X4_PANEL,X5_PANEL,X6_PANEL,X7_PANEL,X8_PANEL,X9_PANEL,TT_DEFECT_CNT,S_SIZE_DEFECT_CNT,M_SIZE_DEFECT_CNT,L_SIZE_DEFECT_CNT,TT_MURA_CNT,POINT_MURA_CNT,LINE_MURA_CNT,AREA_MURA_CNT,GLASS_ID_DCR,POINT_1,POINT_2,POINT_3,POINT_4,POINT_5\n");
+		
+		int nBlockNum = 1;
+		for(int i=0; i<nBlockNum; i++)
+		{
+			makeDataBlock(strLine, pData->GetBlockData(i));
+			fprintf(pf, "%s\n", strLine);
+		}
+	}
+	fprintf(pf, "BLOCK_SUMMARY_END\n\n");
+	
+	//////////////////////////////////////////////////////////////////////////
+	//PANEL_SUMMARY
+	fprintf(pf, "PANEL_SUMMARY_BEGIN\n");
+	{
+		fprintf(pf, "PANEL_ID,PANEL_JUDGE_AOI,PANEL_JUDGE_MURA,PANEL_JUDGE,TT_DEFECT,TT_MURA,PANEL_ID_2D,PANEL_FLAG,PANEL_GRADE,X_D,Y_D,X_A,Y_A,DELTA_X,DELTA_Y,OK_DEFECT,NG_DEFECT,X1_DEFECT,X2_DEFECT,X3_DEFECT,X4_DEFECT,X5_DEFECT,X6_DEFECT,X7_DEFECT,X8_DEFECT,X9_DEFECT,IJP1,IJP2,IJP3,IJP4,IJP5,IJP6,IJP7,IJP8,Mark1,Mark2,Mark3,Mark4,Mark5,Mark6,Mark7,Mark8\n");
+
+		for(int iCell = 0; iCell < pData->GetGlassData()->m_nCellNum; iCell++)
+		{
+			_grmCellData* pCell = pData->GetCellData(iCell);
+			makeDataCell(strLine, pData, pCell);	
+			fprintf(pf, "%s\n", strLine);
+		}
+	}
+	fprintf(pf, "PANEL_SUMMARY_END\n\n");
+	
+	//////////////////////////////////////////////////////////////////////////
+	//DEFECT_DATA
+	fprintf(pf, "DEFECT_DATA_BEGIN\n");
+	{
+		fprintf(pf, "PANEL_ID,DEFECT_NO1,DEFECT_NO2,UPDATE_TIME,STEP_1ST,RECIPE_1ST,STEP_CURRENT,RECIPE_CURRENT,GATE1,DATA1,");
+		fprintf(pf, "GATE2,DATA2,X1,Y1,X2,Y2,AOI_DEFECT_TYPE,AOI_GRAY_H,AOI_GRAY_L,AOI_GRAY_AVE,");
+		fprintf(pf, "AOI_DEFECT_AREA,AOI_DEFECT_LGT,AOI_DEFECT_WID,AOI_DEFECT_HGT,AOI_DEFECT_WIH,AOI_DEFECT_SIZE,DEFECT_PIX,MASK_DEFECT,REPEAT_DEFECT,DEFECT_IMAGE_DATA,");
+		fprintf(pf, "AOI_CCD_NO,AOI_REVIEW_NO,OP_ID_1ST,OP_ID_2ND,OP_ID_CURRENT,DEFECT_JUGDE_1ST,DEFECT_JUGDE_2ND,DEFECT_JUGDE_CURRENT,DEFECT_REASON1,DEFECT_REASON2,");
+		fprintf(pf, "DEFECT_REASON3,WSI_JUDGE,MURA_GRAY_H,MURA_GRAY_L,MURA_GRAY_AVE,MURA_AREA,MURA_LGT,MURA_WID,MURA_HGT,MURA_SIZE,");
+		fprintf(pf, "MURA_PIX,MURA_TYPE,MURA_JUDGE,MURA_GRADE,MURA_IMAGE_DATA,RSRV1,RSRV2,RSRV3,RSRV4,RSRV5,");
+		fprintf(pf, "RSRV6,RSRV7,RSRV8,RSRV9,FILE_NAME\n");
+
+		for(int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+		{
+			_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+			if(makeDataDefect(strLine, pData, pDefect))
+			{
+				fprintf(pf, "%s\n", strLine);
+			}
+		}
+		fprintf(pf, "DEFECT_DATA_END\n\n");
+	}
+	
+	
+	AKLOG("MakeAOIFile Complete : [%s]", strFilePathName.GetBuffer(0));
+	fclose(pf);
+	return TRUE;
+}
+
+BOOL CGlassRawCSOT::MakeAnaFile( CgrmGlassRawData* pData )
+{
+	return TRUE;
+
+	CString strFilePathName;
+	strFilePathName.Format("%s\\%sana", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName);
+
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if(pf == NULL)
+	{
+		AKLOG("MakeAOIFile Fail : [%s]", strFilePathName.GetBuffer(0));
+		return FALSE;
+	}
+
+	fprintf(pf, "%s\n", pData->GetGlassData()->m_strGlassID);
+	fprintf(pf, "m_strImageName, m_strDefectCode, UMCenterAlignX, UMCenterAlignY, m_nLevelSrcMin, m_nLevelSrcMax, m_nLevelSrcAvg, m_nLevelRefMin, m_nLevelRefMax, m_nLevelRefAvg, m_nLevelDiffMin, m_nLevelDiffMax, m_nLevelDiffAvg");
+	for(int i=0; i<MAX_ZONE_NUM; i++) fprintf(pf, ",Zone%02d", i);
+	fprintf(pf, ", m_sDefectPeak, m_nPixelSize, DefectType, UMSize, Density, ScrtRatio, MergeState");
+	fprintf(pf, "\n");
+
+	for(int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+	{
+		_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+		if(pData->GetGlassData()->m_nScanCoordinateY == 1) //분판설비의 경우 XY반전
+		{
+			fprintf(pf, "%s, %s, %.3lf, %.3lf, %d, %d, %d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_strAoiImageName, pDefect->m_strDefectCode, (double)pDefect->m_nUMCenterAlignY / 1000.0, (double)pDefect->m_nUMCenterAlignX / 1000.0,
+				pDefect->m_nLevelSrcMin, pDefect->m_nLevelSrcMax, pDefect->m_nLevelSrcAvg,
+				pDefect->m_nLevelRefMin, pDefect->m_nLevelRefMax, pDefect->m_nLevelRefAvg,
+				pDefect->m_nLevelDiffMin, pDefect->m_nLevelDiffMax, pDefect->m_nLevelDiffAvg);
+			for(int iz=0; iz<MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZonePixelCount[iz]);
+			}
+			fprintf(pf, ",%d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_sDefectPeak, pDefect->m_nPixelSize, pDefect->m_DefectType, pDefect->m_nUMSize, pDefect->m_nDensity, pDefect->m_nScratchRatio, pDefect->m_bMergeState);
+
+			fprintf(pf, ", %d, %d, %d, %d, %d", pDefect->m_nAngle, pDefect->m_nMajor, pDefect->m_nMinor, pDefect->m_nCompact, pDefect->m_nThickness);
+
+			fprintf(pf, "\n");
+		}
+		else
+		{
+			fprintf(pf, "%s, %s, %.3lf, %.3lf, %d, %d, %d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_strAoiImageName, pDefect->m_strDefectCode, (double)pDefect->m_nUMCenterAlignX / 1000.0, (double)pDefect->m_nUMCenterAlignY / 1000.0,
+				pDefect->m_nLevelSrcMin, pDefect->m_nLevelSrcMax, pDefect->m_nLevelSrcAvg,
+				pDefect->m_nLevelRefMin, pDefect->m_nLevelRefMax, pDefect->m_nLevelRefAvg,
+				pDefect->m_nLevelDiffMin, pDefect->m_nLevelDiffMax, pDefect->m_nLevelDiffAvg);
+			for(int iz=0; iz<MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZonePixelCount[iz]);
+			}
+			fprintf(pf, ",%d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_sDefectPeak, pDefect->m_nPixelSize, pDefect->m_DefectType, pDefect->m_nUMSize, pDefect->m_nDensity, pDefect->m_nScratchRatio, pDefect->m_bMergeState);
+
+			fprintf(pf, ", %d, %d, %d, %d, %d", pDefect->m_nAngle, pDefect->m_nMajor, pDefect->m_nMinor, pDefect->m_nCompact, pDefect->m_nThickness);
+
+			fprintf(pf, "\n");
+		}
+	}
+	AKLOG("MakeAnaFile Complete %s", strFilePathName);
+	fclose(pf);
+
+	return TRUE;
+}
+
+void CGlassRawCSOT::makeDataHeader( CString& strLine, _grmGlassData* pGlassData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	CString strCurDateTime;
+	{
+		CTime Time = m_tmReviewEnd;
+		strCurDateTime.Format("%04d/%02d/%02d_%d:%02d:%02d", 
+			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+			Time.GetHour(), Time.GetMinute(), Time.GetSecond());
+	} 
+	strValue.Format("FILE_VERSION:%.1lf\n", 1.0);
+	strLine += strValue;
+	strValue.Format("FILE_CREATED_TIME:%s\n", strCurDateTime);
+	strLine += strValue;
+	strValue.Format("EQUIP_TYPE:%s\n", pGlassData->m_strEquipID);
+	strLine += strValue;
+	strValue.Format("EQUIP_ID:%s\n", pGlassData->m_strStepID);
+	strLine += strValue;
+	strValue.Format("CONTENT:%s\n", _T("GLASS_DATA/EQP_GLASS_DATA/BLOCK_SUMMARY/PANEL_SUMMARY/DEFECT_DATA"));
+	strLine += strValue;
+}
+void CGlassRawCSOT::makeDataGlass( CString& strLine, _grmGlassData* pGlassData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ","; 
+	
+	//물류정보 파싱해서 가지고 오기 CString strProcessID, strProductID, strLotID, strSlotID;
+	{ 
+		std::map<CString, CString> mapTransData;
+
+		CString strTemp;
+		strTemp.Format("D:\\DIT_ResultData\\DownloadData\\%s.dat", pGlassData->m_strGlassID); 
+
+		FILE *pFile = fopen(strTemp.GetBuffer(0), "r");  
+		if(pFile)
+		{     
+			const int MAX_BUFFER	= 1024;
+			char buffer[MAX_BUFFER];   
+			CString strKey;
+			CString strValue;
+			char* pFlagPos;
+			char* pEndFlagPos;
+			char* pTest = "』";
+			while (fgets(buffer, MAX_BUFFER, pFile) != '\0')
+			{   
+				pFlagPos = strchr(buffer, '=');
+				
+				if(pFlagPos == NULL) continue;
+
+				if(pEndFlagPos = strchr(pFlagPos, -29)) //"』"끝에 있는 end문자열 제거
+					pEndFlagPos[0] = 0;
+
+				pFlagPos[0] = 0; // = 이걸 0으로 만들어서 Key, Value 분리
+
+				strKey = buffer;
+				strValue = &pFlagPos[1];
+
+				strValue.Remove(' ');//혹시 모를 공백 제거 [김태현 2019/1/31]
+
+				mapTransData.insert(std::make_pair(strKey, strValue));
+			}
+			fclose(pFile);
+		} 
+		
+
+		//GlassData에 값을 넣어줌 [김태현 2019/1/31]
+		strcpy(pGlassData->m_strSLotID, mapTransData["Slot_ID"].GetBuffer(0));
+		strcpy(pGlassData->m_strProductID, mapTransData["Product_ID"].GetBuffer(0));
+		strcpy(pGlassData->m_strProcessID, mapTransData["Process_ID"].GetBuffer(0));
+		strcpy(pGlassData->m_strLotID, mapTransData["Lot_ID"].GetBuffer(0));
+	}
+ 
+ 
+	strValue.Format("%s", pGlassData->m_strGlassID);	 	//1. Glass ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strOwnerCode);  	//2. OWNER_CODE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strOwnerType);  	//3. OWNER_TYPE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProductID);  	//4. PRODUCT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProcessID);  	//5. PROCESS_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProductGroup);  //6. PRODUCT_GROUP
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strLotID);  		//7. LOT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strCSTID);  		//8. CST_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strSLotID); 		//9.SLOT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProcessID);  //10.PRE_PROCESS_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strEquipID);		//11.PRE_EQP_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strPreChamerID);	//12.PRE_CHAMBER_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strPreRecipeID);	//13.PRE_RECIPE_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strGroupID);		//14.GROUP_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pGlassData->m_cAutoSampleFlag);  //15.AUTOSAMPLEFLAG
+	strLine += strValue;
+
+
+}
+
+void CGlassRawCSOT::makeDataEQPGlass( CString& strLine, CgrmGlassRawData* pData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	_grmGlassData *pGlassData = pData->GetGlassData();
+	CString strStartTime, strEndTime;
+	{
+		CTime Time;
+		Time = pGlassData->m_tmGlassLoading;
+		strStartTime.Format("%04d/%02d/%02d_%d:%02d:%02d", 
+			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+			Time.GetHour(), Time.GetMinute(), Time.GetSecond());
+		Time = pGlassData->m_tmInspectionEND;
+		strEndTime.Format("%04d/%02d/%02d_%d:%02d:%02d", 
+			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+			Time.GetHour(), Time.GetMinute(), Time.GetSecond());
+	}
+
+	strValue.Format("%s", pGlassData->m_strPPID);														//1. RECIPE_NO
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strRecipeName);													//2. RECIPE_NAME
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strStartTime);																//3. START_TIME
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strEndTime);																	//4. END_TIME
+	strLine += strValue+strDiv;
+	strValue.Format("%d", strEndTime - strStartTime);													//5. TACT_TIME
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0000");																		//6. GLASS_YIELD
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nCellNum);														//7. TOTAL_PANEL_CNT(CELL COUNT)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nDefectNumJudgeOKBlack+pGlassData->m_nDefectNumJudgeOKWhite);	//8. OK_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nDefectNumJudgeNG);												//9. NG_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//10. X1_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//11. X2_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//12. X3_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//13. X4_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//14. X5_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//15. X6_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//16. X7_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																	//17. X8_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nDefectNumSizeHuge);										//18. X9_PANEL(Count)	//190116 고객사가 키큰여자 여기에다가 ol갯수 적어 달라고 요청
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nDefectNum);													//19. TT_DEFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nDefectNumSizeSmall);											//20. S_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nDefectNumSizeMid);												//21. M_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nDefectNumSizeLarge);											//22. L_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "AAAA");																		//23. GLASS_ID_DCR
+	strLine += strValue+strDiv;
+	strValue.Format("%d", m_MuraResultFile.GetDefectNum());												//24. TT_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//25. POINT_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//26. LINE_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//27. AREA_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//28. POINT_1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//29. POINT_2
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//30. POINT_3
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//31. POINT_4
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 1);																			//32. POINT_5		
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strGlassJudge);													//33. GLASS_JUDGE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strGlassCode);													//34. GLASS_GRADE
+	strLine += strValue;
+	
+}
+
+void CGlassRawCSOT::makeDataBlock( CString& strLine, _grmBlockData* pBlockData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("%s", pBlockData->m_strBlockID);				//1. BLOCK_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pBlockData->m_cBlockJudgeAOI);			//2. BLOCK_JUDGE_AOI		
+	strLine += strValue+strDiv;
+	strValue.Format("%c", 'G');									//3. BLOCK_JUDGE_MURA
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pBlockData->m_cBlockJudgeATS);			//4. BLOCK_JUDGE_ATS		
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pBlockData->m_cBlockJudgeTEG);			//5. BLOCK_JUDGE_TEG		
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//6. TT_PANEL
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//7. OK_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//8. NG_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//9. X1_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//10. X2_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//11. X3_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//12. X4_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//13. X5_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//14. X6_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//15. X7_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//16. X8_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//17. X9_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//18. TT_DEFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//19. S_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//20. M_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//21. L_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//22. GLASS_ID_DCR
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//23. TT_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//24. POINT_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//25. LINE_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//26. AREA_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//27. POINT_1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//28. POINT_2
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//29. POINT_3
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//30. POINT_4
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//31. POINT_5
+	strLine += strValue;
+}
+
+
+void CGlassRawCSOT::makeDataCell( CString& strLine, CgrmGlassRawData* pData, _grmCellData* pCellData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	CString strJudgeCode = "O";
+	CString strLastCode = "O";
+	{
+		switch (pCellData->m_nJudgement)
+		{
+		case 0:		strJudgeCode = "G"; break;
+		case 2:		strJudgeCode = "N"; break;
+		case 10:	strJudgeCode = "O"; break;
+		case 1:		strJudgeCode = "O"; break;
+		case 6:		strJudgeCode = "O"; break;
+		case 7:		strJudgeCode = "O"; break;
+		}
+	}
+	strLastCode = strJudgeCode;
+
+	strValue.Format("%s%s", pData->GetGlassData()->m_strGlassID, pCellData->m_strCellName);													//1. PANEL_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strJudgeCode);																//2. PANEL_JUDGE_AOI
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "O");																			//3. PANEL_JUDGE_MURA
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strLastCode);																	//4. PANEL_JUDGE
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->getTotalDefectNum());												//5. tt_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", m_MuraResultFile.GetDefectNum(pCellData->m_nCellID));												//6. tt_MURA
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");																		//7. PANEL_ID_2D
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nJudgeFlag);														//8. PANEL_FLAG
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nJudgeGlade);													//9. PANEL_GRADE
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellLeft);													//10. X_D
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellTop);													//11. Y_D
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellRight-pCellData->m_rectCellLeft);						//12. X_A
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellBottom-pCellData->m_rectCellTop);						//13. Y_A
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//14. DELTA_X
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//15. DELTA_Y
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nDefectNumJudgeOKWhite + pCellData->m_nDefectNumJudgeOKBlack);	//16. OK_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nDefectNumJudgeNG);												//17. NG_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//18. X1_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//19. X2_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//20. X3_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//21. X4_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//22. X5_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//23. X6_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//24. X7_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//25. X8_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//26. X9_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//27. IJP1
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//28. IJP2
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//29. IJP3
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//30. IJP4
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//31. IJP5
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//32. IJP6
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//33. IJP7
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//34. IJP8
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//35. Mark1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//36. Mark2
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//37. Mark3
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//38. Mark4
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//39. Mark5
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//40. Mark6
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//41. Mark7
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//42. Mark8
+	strLine += strValue;
+
+}
+
+BOOL CGlassRawCSOT::makeDataDefect( CString& strLine, CgrmGlassRawData* pData, _grmDefectData* pDefectData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	_grmGlassData* pGlassData = pData->GetGlassData();
+	_grmCellData* pCellData = pData->GetCellData(pDefectData->m_nCellIdx);
+
+	if(pDefectData->m_ReviewDefect.m_nPlanType == 1000 //aoi결함
+		//pDefectData->m_ReviewDefect.m_nPlanType == 999 
+		) return FALSE;
+
+	CString strUpdateTime;
+	{
+		CTime Time = pGlassData->m_tmInspectionEND;
+		strUpdateTime.Format("%04d/%02d/%02d_%d:%02d:%02d", 
+			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+			Time.GetHour(), Time.GetMinute(), Time.GetSecond());
+
+// 		CTime Time = pGlassData->m_tmInspectionEND;
+// 		strUpdateTime.Format("%04d%02d%02d%02d%02d",
+// 			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+// 			Time.GetHour(), Time.GetMinute());
+	}
+	
+	CString strStepFirst;//첫번째 스택 [김태현 2018/12/5]
+	{
+		if(pDefectData->m_strStackFirst[0])
+		{
+			strStepFirst =pDefectData->m_strStackFirst;
+		}	
+		else
+		{
+			strStepFirst = pGlassData->m_strStepID;
+		}
+	}
+
+	strValue.Format("%s%s", pData->GetGlassData()->m_strGlassID, pCellData->m_strCellName);					//1. CELL ID
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nDefectID);				//2. DEFECT_NO1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nDefectID);				//3. DEFECT_NO2
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strUpdateTime);							//4. UPDATE_TIME
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strStepFirst);							//5. STEP_1ST
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strRecipeName);				//6. RECIPE_1ST
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strStepID);					//7. STEP_CURRENT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strRecipeName);				//8. RECIPE_CURRENT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellGate);				//9. GATE1, 셀별 Gate라인(얼라인 보정 전)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellData);				//10. DATA1, 셀별 Data라인(얼라인 보정 전)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellGateAlign);			//11. GATE2, 셀별 Gate라인(얼라인 보정 후)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellDataAlign);			//12. DATA2, 셀별 Data라인(얼라인 보정 후)
+	strLine += strValue+strDiv;
+
+
+
+	//_grmGlassData* pGlass = pData->GetGlassData(); 
+
+	
+
+	// x,y좌표 mm단위 소수점 세자리까지 표현 (고객사 요청) - 2019-01-30 HJH
+	if(pGlassData->m_nScanCoordinateY == 1) //분판설비의 경우 XY반전
+	{
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignY / 1000.0);			//13. X1, um단위 X좌표 (Glass Center 기준, 얼라인보정 후)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignX / 1000.0);			//14. Y1, um단위 Y좌표 (Glass Center 기준, 얼라인보정 후)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellY / 1000.0);					//15. X2, 셀 원점 기준 x 좌표
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellX / 1000.0);					//16. Y2, 셀 원점 기준 y 좌표
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_DefectType);				//17. AOI_DEFECT_TYPE, SERVER_DefectType
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMax);				//18. AOI_GRAY_H, 결함 밝기 Max			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMin);				//19. AOI_GRAY_L, 결함 밝기 Min			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcAvg);				//20. AOI_GRAY_AVE, 결함 밝기 Avg			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nPixelSize);				//21. AOI_DEFECT_AREA 			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nDefectRScale);			//22. AOI_DEFECT_LGT, 결함 길이				
+		strLine += strValue+strDiv;
+		strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectSizeType));				//23. AOI_DEFECT_WID , <- 190106 고객 담당자 요청 키큰여자	사이즈타입으로로 변경		
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_sPixelWidth);				//24. AOI_DEFECT_HGT		
+	}
+	else
+	{
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignX / 1000.0);			//13. X1, um단위 X좌표 (Glass Center 기준, 얼라인보정 후)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignY / 1000.0);			//14. Y1, um단위 Y좌표 (Glass Center 기준, 얼라인보정 후)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellX / 1000.0);					//15. X2, 셀 원점 기준 x 좌표
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellY / 1000.0);					//16. Y2, 셀 원점 기준 y 좌표
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_DefectType);				//17. AOI_DEFECT_TYPE, SERVER_DefectType
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMax);				//18. AOI_GRAY_H, 결함 밝기 Max			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMin);				//19. AOI_GRAY_L, 결함 밝기 Min			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcAvg);				//20. AOI_GRAY_AVE, 결함 밝기 Avg			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nPixelSize);				//21. AOI_DEFECT_AREA 			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nDefectRScale);			//22. AOI_DEFECT_LGT, 결함 길이				
+		strLine += strValue+strDiv;
+		strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectSizeType));				//23. AOI_DEFECT_WID, <- 190106 고객 담당자 요청 키큰여자	사이즈타입으로로 변경					
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_sPixelHeight);				//24. AOI_DEFECT_HGT		
+	}
+	
+	
+		
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_DefectSizeType);			//25. AOI_DEFECT_WIH, SERVER_DefectSizeType			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMSize);					//26. AOI_DEFECT_SIZE 			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nPixelSize);				//27. DEFECT_PIX 			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_DefectSubType == 2 ? 1:0);	//28. MASK_DEFECT, 한 Glass에서 발견된 마스크결함 묶음의 			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_DefectSubType == 3 ? 1:0);		//29. REPEAT_DEFECT, 연속결함발견위한 동일좌표 반복수			
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pDefectData->m_ReviewDefect.m_strRevImageName);			//30. DEFECT_IMAGE_DATA		
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nDefectIdx);				//31. AOI_CCD_NO  			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_ReviewDefect.m_nShotIndex);			//32. AOI_REVIEW_NO  				
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");									//33. OP_ID_1ST  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");									//34. OP_ID_2ND  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");									//35. OP_ID_CURRENT  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectJudgement));			//36. DEFECT_JUGDE_1ST  			
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "O");										//37. DEFECT_JUGDE_2ND  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectJudgement));			//38. DEFECT_JUGDE_CURRENT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A");										//39. DEFECT_REASON1  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A");										//40. DEFECT_REASON2 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A");										//41. DEFECT_REASON3 
+	strLine += strValue+strDiv;
+	strValue.Format("%.2lf", pDefectData->m_ReviewDefect.m_fWsi_ResultData[1]);//42. WSI_JUDGE 
+	strLine += strValue+strDiv;
+	//KMS - 20190128 MuraDefect 내용 추가
+	_MacroDefect* pMuraDefect = m_MuraResultFile.FindDefect(pDefectData->m_nUMCenterAlignX, pDefectData->m_nUMCenterAlignY);
+	_MacroDefect MuraDefect;
+	if(pMuraDefect) MuraDefect = *pMuraDefect;
+	strValue.Format("%d", MuraDefect.G_MAX);										//43. MURA_GRAY_H 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.G_MIN);										//44. MURA_GRAY_L 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.G_AVG);										//45. MURA_GRAY_AVE 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_S);										//46. MURA_AREA 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_L);										//47. MURA_LGT 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_W);										//48. MURA_WID  
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.COORD_Y1);										//49. MURA_HGT 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_S);										//50. MURA_SIZE 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.COORD_PX1);											//51. MURA_PIX 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.MAIN_TYPE.GetBuffer(0));									//52. MURA_TYPE 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.JUDGE.GetBuffer(0));										//53. MURA_JUDGE 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.SUB_TYPE.GetBuffer(0));										//54. MURA_GRADE 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.IMG_FILE_NAME.GetBuffer(0));								//55. MURA_IMAGE_DATA 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//56. RSRV1 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//57. RSRV2 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//58. RSRV3 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//59. RSRV4 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//60. RSRV5 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//61. RSRV6 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//62. RSRV7 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//63. RSRV8 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//64. RSRV9 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pDefectData->m_strAoiImageName);				//65. FILE_NAME 			
+	strLine += strValue;
+
+	return TRUE;
+}
+
+BOOL CGlassRawCSOT::ReadMuraFile( CgrmGlassRawData* pData )
+{
+ 	if(m_MuraResultFile.m_strServerResultRawPath.IsEmpty() == FALSE)//읽은 결과 파일 복사,삭제 태현[2017/3/29]
+ 	{
+		CString strMacroFilePath;
+		{
+			strMacroFilePath.Format("%s\\%s_*.dat", m_MuraResultFile.m_strMacroResultRawPath, pData->GetGlassData()->m_strGlassID);
+
+			CFileFind FF;
+
+			if (FF.FindFile(strMacroFilePath))
+			{
+				FF.FindNextFile();
+				strMacroFilePath = FF.GetFilePath();
+				FF.Close();
+			}
+			else
+			{
+				AKLOG("Find Macro File Fail. [%s]", strMacroFilePath);
+				return FALSE;
+			}
+		}
+		
+
+ 		CString strMacroResultTargetPath;
+ 		strMacroResultTargetPath.Format("%s\\%s.dat", m_MuraResultFile.m_strServerResultRawPath, pData->GetGlassData()->m_strGlassID);
+ 
+ 		if(TRUE == CopyFile(strMacroFilePath,strMacroResultTargetPath,FALSE))
+ 		{
+ 			if(m_MuraResultFile.openFile(strMacroResultTargetPath.GetBuffer(0)) == TRUE)
+ 			{
+ 				AKLOG("Macro File Read Success : %dItem", m_MuraResultFile.GetDefectNum());
+ 				//DeleteFile(strMacroResultTargetPath); //삭제는 hddspacectrl이 하는 것으로 통일
+ 			}
+ 			else
+ 			{
+ 				AKLOG("Macro File Read Fail[%s]", strMacroFilePath);
+ 				//DeleteFile(strMacroResultTargetPath); //삭제는 hddspacectrl이 하는 것으로 통일
+ 				return FALSE;
+ 			}
+ 		}
+ 	}
+ 
+	//무라 이미지 복사(ftp업로드를 위함) [김태현 2018/12/5]
+ 	if(m_MuraResultFile.m_strMacroResultImagePath.IsEmpty() == FALSE && m_MuraResultFile.m_strServerResultImagePath.IsEmpty() == FALSE)//이미지 파일 복사 태현[2017/3/29]
+ 	{
+ 		CString strMacroImageSrcPath;
+ 		CString strMacroImageTarPath;
+ 
+ 		strMacroImageSrcPath.Format("%s\\%s", m_MuraResultFile.m_strMacroResultImagePath, pData->GetGlassData()->m_strGlassID);
+ 		strMacroImageTarPath.Format("%s\\%s", m_MuraResultFile.m_strServerResultImagePath, pData->GetGlassData()->m_strGlassID);
+ 
+		AKLOG("Macro Image File Copy Start[%s]", strMacroImageTarPath);
+ 		CakFileUtil::CopyFolder(strMacroImageSrcPath.GetBuffer(0), strMacroImageTarPath.GetBuffer(0), FALSE);
+		AKLOG("Macro Image File Copy End");
+ 	}
+
+	return TRUE;
+}
+
+
+void CGlassRawCSOT::SendMessageFTPUploadLinkFile( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_LINK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+
+}
+ 
+void CGlassRawCSOT::SendMessageFTPUploadRaw( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_RAW, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+  
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+
+}
+
+void CGlassRawCSOT::SendMessageFTPDownloadStack( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_STACK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= FTPProcessType_DownFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CGlassRawCSOT::SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPDownloader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	//GetFormatDescription(FTPCMD_DATAFILE, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+	{
+		CString strGlassIDOrg = pGlassData->m_strGlassID; 
+		CString strGlassID = strGlassIDOrg.Left(12);
+		sprintf(strServerFolder, "%s", pGlassData->m_strCassetteSequenceNo);
+		sprintf(strServerFile, "%s.dat", strGlassID.GetBuffer(0));  
+		sprintf(strLocalFolder,  "D:\\DIT_ResultData\\DownloadData"); 
+		sprintf(pLocalFile,  "%s.dat", strGlassID.GetBuffer(0)); 
+	}
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= FTPProcessType_DownFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CGlassRawCSOT::SendMessageFTPUploadImage( _grmGlassData* pGlassData, emFTPCommand sort)
+{  
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+ 
+	char strServerFolder[256] = {};
+	char strServerFile[32];// = "*.*";
+	char strLocalFolder[256] = {};
+	char strLocalFile[32];// = "*.*"; 
+
+	GetFormatDescription(sort, strServerFolder, strServerFile, strLocalFolder, strLocalFile, pGlassData);
+   
+// 	if(0)//test 
+// 	{
+// 		sprintf(strServerFolder, "HDD1/DIT/TestC");
+// 	}
+ 
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				strLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;
+	upParam.m_nSendResultCode							= FALSE;
+	upParam.m_nProcessType								= FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = FTPCopyDataCmd_RawUpload; //<--요건 나중에 구분
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+  
+
+BOOL CGlassRawCSOT::SendMessageFTPUploadIndexFile( _grmGlassData* pGlassData )
+{  
+	if(pGlassData == NULL) 
+		return FALSE;
+
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return FALSE;
+
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	GetFormatDescription(FTPCMD_INDEX, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+
+	// 	if(0)//test 
+	// 	{
+	// 		sprintf(strServerFolder, "HDD1/DIT/TestC");
+	// 		ServerFile = "ftptestfile.txt";
+	// 
+	// 		sprintf(strLocalFolder, "D:");
+	// 		pLocalFile = "ftptestfile.txt";
+	// 	}
+
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+	return TRUE;
+}
+
+void CGlassRawCSOT::GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, _grmGlassData* pGlassData)
+{ 
+	
+	CString strGlassIDOrg = pGlassData->m_strGlassID; 
+	CString strGlassID = strGlassIDOrg.Left(12);
+	CString strGlassIDLevel5th = strGlassID.Left(5);
+	CString strGlassIDLevel8th = strGlassID.Left(8);
+ 
+	switch(sort)
+	{ 
+	case FTPCMD_AOI_IMAGE:
+		{
+			CTime time = m_tmReviewEnd;
+
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0));  
+			
+			sprintf(pLocalPath, "%s%s", LOCAL_AOI_IMAGE_PATH, strGlassID.GetBuffer(0));  
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+		}
+		break;
+	case FTPCMD_REVIEW_IMAGE: 
+		{
+			CTime time = m_tmReviewEnd;
+
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s%s", LOCAL_REV_IMAGE_PATH, strGlassID.GetBuffer(0));  
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+		}
+		break;
+	case FTPCMD_RAW:   
+		{
+			CTime time = m_tmReviewEnd;
+			CString strFileName;//파일생성 시간 때문에 여기서 정확하게 파일명 다시 정정
+			{
+				//Glass 정보
+				CTime CurrTime = m_tmReviewEnd;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				strFileName.Format("%s_%s_%s.csv", pGlassData->m_strOperID, pGlassData->m_strGlassID, strTime.GetBuffer(0));
+			}
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Data", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+			
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+		}
+		break;
+	case FTPCMD_STACK:
+		{
+			CTime time = pGlassData->m_tmGlassLoading;
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Data", m_StackResult.getStackEquipID(), time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			//가장 최근걸 찾아야 하나? [김태현 2019/1/12]
+			sprintf(pServerFile, "%s_%s_*.csv", 
+				m_StackResult.getStackOperID(), 
+				pGlassData->m_strGlassID); 
+
+			sprintf(pLocalPath, "%s", m_StackResult.getStackLocalPath()); 
+			sprintf(pLocalFile, "%s.txt", strGlassID.GetBuffer(0)); 
+		}
+		break;
+	case FTPCMD_MURA_IMAGE: 
+		{
+			CTime time = m_tmReviewEnd;
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s%s", LOCAL_MURA_IMAGE_PATH, strGlassID.GetBuffer(0)); 
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*"); 
+		}
+		break;
+	case FTPCMD_INDEX:
+		{
+			CTime time = m_tmReviewEnd;
+			sprintf(pServerPath, "INDEX\\%s", pGlassData->m_strEquipID);
+			sprintf(pServerFile, "%04d%02d%02d_%s.csv", time.GetYear(), time.GetMonth(), time.GetDay(),	pGlassData->m_strStepID); 
+
+			sprintf(pLocalPath, "%s", LOCAL_INDEX_PATH); 
+			sprintf(pLocalFile, "%s", pServerFile); 
+		}
+		break;
+
+	case FTPCMD_LINK:   
+		{ 
+			CTime time = m_tmReviewEnd;
+			CString strFileName;//파일생성 시간 때문에 여기서 정확하게 파일명 다시 정정
+			{
+				//Glass 정보
+				CTime CurrTime = m_tmReviewEnd;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				strFileName.Format("%s_%s_%s.csv", pGlassData->m_strOperID, pGlassData->m_strGlassID, strTime.GetBuffer(0));
+			}
+			sprintf(pServerPath, "%s\\%s\\%s\\%s\\%s", "LINK", pGlassData->m_strEquipID, 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+		}
+		break;
+	} 
+
+
+}
+ 
+
+BOOL CGlassRawCSOT::WriteIndexFile( _grmGlassData* pGlassData)
+{   
+	CTime time = CTime::GetCurrentTime();//m_tmReviewEnd;
+
+	CString strLocalIndexFileName;
+	strLocalIndexFileName.Format("%s\\%04d%02d%02d_%s.csv", LOCAL_INDEX_PATH,
+		time.GetYear(), time.GetMonth(), time.GetDay(),
+		pGlassData->m_strStepID);
+
+
+	if(!PathFileExists(strLocalIndexFileName))//처음생성되는 파일인지 체크 해서 헤더 라인 넣어줌
+	{
+		FILE* pFile = fopen(strLocalIndexFileName.GetBuffer(0), "w");
+		if(pFile)
+		{
+			fprintf(pFile, "Date_Time, Path\n");
+			fclose(pFile);
+		}
+	}
+
+
+	FILE* fp = fopen(strLocalIndexFileName.GetBuffer(0), "a");  
+	if(fp == NULL) 
+		return FALSE; 
+
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	CString strDate;
+	strDate.Format("%04d/%02d/%02d %02d:%02d:%02d", time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond());
+
+	char* pHomePath = "/EL";
+	//Review Image File
+	{
+		GetFormatDescription(FTPCMD_REVIEW_IMAGE, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData); 
+		CString strLocal_FindPath;
+		CString strServer_Path;
+		 
+		strLocal_FindPath.Format("%s\\*.*", strLocalFolder);
+		strServer_Path.Format("\\%s\\",strServerFolder);
+
+		CFileFind finder;
+		BOOL bFind = finder.FindFile(strLocal_FindPath);
+		strServer_Path.Replace('\\', '/');
+		while(bFind)
+		{ 
+			bFind = finder.FindNextFile();
+
+			if (finder.IsDots()) continue;
+			if (finder.IsDirectory()) continue;
+
+
+			fprintf(fp, "%s,%s%s%s\n", strDate, pHomePath, strServer_Path.GetBuffer(0), finder.GetFileName().GetBuffer(0));
+		}
+		finder.Close(); 
+	}
+	// Inspector Image
+	{
+		GetFormatDescription(FTPCMD_AOI_IMAGE, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData); 
+		CString strLocal_FindPath;
+		CString strServer_Path;
+
+		strLocal_FindPath.Format("%s\\*.*", strLocalFolder);
+		strServer_Path.Format("\\%s\\",strServerFolder);
+		
+		CFileFind finder;
+		BOOL bFind = finder.FindFile(strLocal_FindPath);
+		strServer_Path.Replace('\\', '/');
+		while(bFind)
+		{ 
+			bFind = finder.FindNextFile();
+
+			if (finder.IsDots()) continue;
+			if (finder.IsDirectory()) continue;
+
+
+			fprintf(fp, "%s,%s%s%s\n", strDate, pHomePath, strServer_Path.GetBuffer(0), finder.GetFileName().GetBuffer(0));
+		}
+		finder.Close(); 
+	}
+	// RAW
+	{
+ 		GetFormatDescription(FTPCMD_RAW, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+		CString strServerPath = strServerFolder;
+		strServerPath.Replace('\\', '/');
+		fprintf(fp, "%s,%s/%s/%s\n", strDate, pHomePath, strServerPath.GetBuffer(0), strServerFile);
+	}
+	if(m_MuraResultFile.IsRead())// MURA [김태현 2019/1/10]
+	{
+		GetFormatDescription(FTPCMD_MURA_IMAGE, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData); 
+		CString strLocal_FindPath;
+		CString strServer_Path;
+
+		strLocal_FindPath.Format("%s\\*.*", strLocalFolder);
+		strServer_Path.Format("\\%s\\",strServerFolder);
+
+		CFileFind finder;
+		BOOL bFind = finder.FindFile(strLocal_FindPath);
+		strServer_Path.Replace('\\', '/');
+		while(bFind)
+		{ 
+			bFind = finder.FindNextFile();
+
+			if (finder.IsDots()) continue;
+			if (finder.IsDirectory()) continue;
+
+
+			fprintf(fp, "%s,%s/%s%s\n", strDate, pHomePath, strServer_Path.GetBuffer(0), finder.GetFileName().GetBuffer(0));
+		}
+		finder.Close(); 
+	}
+
+	// Link File
+	{
+		GetFormatDescription(FTPCMD_LINK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+		CString strServerPath = strServerFolder;
+		strServerPath.Replace('\\', '/');
+		fprintf(fp, "%s,%s/%s/%s\n", strDate, pHomePath, strServerPath.GetBuffer(0), strServerFile);
+	}
+
+	// Index
+	{
+		GetFormatDescription(FTPCMD_INDEX, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);  
+		CString strServerPath = strServerFolder;
+		strServerPath.Replace('\\', '/');
+		fprintf(fp, "%s,%s/%s/%s\n", strDate, pHomePath, strServerPath.GetBuffer(0), strServerFile);
+	}
+
+
+	fclose(fp);
+	return TRUE;
+
+}
+
+CString CGlassRawCSOT::GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam)
+{  
+	CString sStr;
+	switch(nDefectInfoType)
+	{
+	case DMT_DefectJudge:// Judge
+		{
+			sStr = "O";
+			switch(nParam)
+			{
+			case 0:			sStr.Format("O");		
+				break;
+			}
+		}
+		break;
+
+	case DMT_DefectSizeType: 
+		{
+			sStr = "S";
+			switch(nParam)
+			{
+				//case SizeType_Unknown:	 sStr.Format("U");	break; 
+			case 1:	 sStr.Format("S");
+				break; 
+			case 2:		 sStr.Format("M");
+				break; 
+			case 3:	 sStr.Format("L");
+				break; 
+			case 4:		 sStr.Format("O");
+				break;
+			}
+		}
+		break;
+
+
+	}
+	return sStr;
+}
diff --git a/ReviewHistory/ReveiwHistory/GlassRawCSOT.h b/ReviewHistory/ReveiwHistory/GlassRawCSOT.h
new file mode 100644
index 0000000..ce9952f
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawCSOT.h
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "GlassRawBase.h"
+#include "GlassRawRTMS.h"
+#include "StackResultCSOT.h"
+#include "MacroResultFile.h"
+#include "CustomizeReview.h"
+
+enum emFTPCommand
+{	
+	FTPCMD_REVIEW_IMAGE		=0,
+	FTPCMD_RAW				,
+	FTPCMD_INDEX				,
+	FTPCMD_AOI_IMAGE			,
+	FTPCMD_MURA_RAW			,
+	FTPCMD_MURA_IMAGE			,
+	FTPCMD_STACK				,
+	FTPCMD_LINK				,
+	FILESORT_NUM
+};
+
+
+
+class CGlassRawCSOT : public CGlassRawBase
+{
+public:
+	enum emDefectMemberType
+	{
+		DMT_DefectJudge = 0,
+		DMT_DefectSizeType
+	}; 
+
+public:
+	CGlassRawCSOT(void);
+	~CGlassRawCSOT(void);
+
+	static char* GetClassName(){return "CSOT T4";};
+
+	virtual BOOL SequenceGlassLoading(CgrmGlassRawData* pData);
+	virtual BOOL SequenceInspectEnd(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewStart(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewEnd(CgrmGlassRawData* pData);
+	virtual BOOL SequenceCustomizeReview(CgrmGlassRawData* pData);
+
+	virtual BOOL WriteAOIFile(CgrmGlassRawData* pData);
+	virtual BOOL ReadAOIFile(CgrmGlassRawData* pData){return TRUE;};
+
+	virtual BOOL SequenceFtpUpload(char* pRawFileName);
+
+	virtual void NotifyUpdateOptionInfo(){m_StackResult.readOptionFile();};
+
+	
+	
+	void SendMessageFTPUploadRaw(_grmGlassData* pGlassData);
+	void SendMessageFTPDownloadStack(_grmGlassData* pGlassData);
+	void SendMessageFTPUploadImage(_grmGlassData* pGlassData, emFTPCommand sort); 
+	BOOL SendMessageFTPUploadIndexFile(_grmGlassData* pGlassData);
+	void SendMessageFTPUploadLinkFile(_grmGlassData* pGlassData);
+	void SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData);
+
+
+	BOOL ReadMuraFile(CgrmGlassRawData* pData);
+	BOOL MakeAOIFile(CgrmGlassRawData* pData);
+	BOOL MakeAnaFile(CgrmGlassRawData* pData);
+	BOOL WriteIndexFile(_grmGlassData* pGlassData);
+	
+	void makeDataHeader(CString& strLine, _grmGlassData* pGlassData);
+	void makeDataGlass(CString& strLine, _grmGlassData* pGlassData);
+	void makeDataEQPGlass(CString& strLine, CgrmGlassRawData* pData);
+	void makeDataBlock(CString& strLine, _grmBlockData* pBlockData);
+	void makeDataCell(CString& strLine, CgrmGlassRawData* pData, _grmCellData* pCellData);
+	BOOL makeDataDefect(CString& strLine, CgrmGlassRawData* pData, _grmDefectData* pDefectData);
+ 
+	void GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, _grmGlassData* pGlassData); 
+	CString GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam);
+ 
+
+public:
+	CMacroResultFile* GetmuraResultFile(){return &m_MuraResultFile;}	// RTMS에서 Mura 데이터 사용
+
+
+protected:
+	CGlassRawRTMS	m_GlassRawRTMS;//RTMS용 결과파일 생성관리 [김태현 2018/12/5]
+	CMacroResultFile m_MuraResultFile; //무라용 결과파일 생성관리 [김태현 2018/12/5]
+	CStackResultCSOT m_StackResult;
+	CCustomizeReview m_CustomizeReview;
+
+	CTime	m_tmReviewStart;		
+	CTime	m_tmReviewEnd;		
+};
+
+
+
diff --git a/ReviewHistory/ReveiwHistory/GlassRawDemo.cpp b/ReviewHistory/ReveiwHistory/GlassRawDemo.cpp
new file mode 100644
index 0000000..d7e5708
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawDemo.cpp
@@ -0,0 +1,1432 @@
+癤�#include "StdAfx.h"
+#include "GlassRawDemo.h"
+#include "akLoggerExt.h"
+#include "MacroResultFile.h"
+#include "akCore/akFileUtil.h"
+#include "akGridData.h"
+
+//#include "AOIDefinitionType.h"
+//#include "AOIDefinition.h"
+ 
+#define LOCAL_INDEX_PATH			"D:\\DIT_ResultData\\Index\\"	  
+#define LOCAL_REV_IMAGE_PATH		"D:\\ResultData\\Upload\\Image\\" 
+#define LOCAL_AOI_IMAGE_PATH		"D:\\Image\\Defect\\" 
+#define LOCAL_MURA_IMAGE_PATH		"D:\\DIT_ResultData\\Mura\\IMG\\" 
+#define LOCAL_DEEP_PATH				"D:\\DIT_ResultData\\Deeplearning\\"
+
+#define LOCAL_AOIRAWDFS_PATH		"D:\\DIT_ResultData\\Raw"
+#define LOCAL_AOIRAWBIN_PATH		"D:\\DIT_ResultData\\RawBin"
+#define NETWORK_AOIRAWDFS_PATH		"\\\\126.100.100.1\\d\\DIT_ResultData\\Raw"
+#define NETWORK_AOIRAWBIN_PATH		"\\\\126.100.100.1\\d\\DIT_ResultData\\RawBin"
+
+
+
+CGlassRawDemo::CGlassRawDemo(void)
+{
+	CreateDirectory(LOCAL_AOIRAWDFS_PATH, NULL);
+	CreateDirectory(LOCAL_AOIRAWBIN_PATH, NULL);
+	m_MuraResultFile.readOptionFile("C:\\DIT_Review\\ReviewServerConfig\\MacroInfo.cfg");
+
+	m_GlassRawRTMS.SetMuraResult(&m_MuraResultFile);
+}
+
+CGlassRawDemo::~CGlassRawDemo(void)
+{
+}
+
+BOOL CGlassRawDemo::SequenceGlassLoading( CgrmGlassRawData* pData )
+{
+	/* //�뒪�깮湲곕뒫
+	if(0)//m_StackResult.getStackUse())
+	{
+		SendMessageFTPDownloadDataFile(pData->GetGlassData(0));
+		if(IsUseDuglex(pData)) SendMessageFTPDownloadDataFile(pData->GetGlassData(1));
+
+		m_StackResult[0].StackFileReadStart(pData->GetGlassData(0)->m_strGlassID);
+		if(IsUseDuglex(pData)) m_StackResult[1].StackFileReadStart(pData->GetGlassData(1)->m_strGlassID);
+	}
+	*/
+
+	return TRUE;
+}
+
+BOOL CGlassRawDemo::SequenceInspectEnd( CgrmGlassRawData* pData )
+{
+	m_tmReviewEnd = m_tmReviewStart = CTime::GetCurrentTime();
+	m_tmFileCreateTime = CTime::GetCurrentTime();
+
+	//�뿬湲곗뿉�꽌 �씪�씤蹂꾨줈 �뙆�씪紐�, �샊�� Path �쐞移� 寃곗젙�븯硫대맖. AOIServer �샊�� ReviewServer�뿉�꽌 �븞�빐�룄�맖 [源��깭�쁽2019/9/4]
+	pData->GetGlassData()->m_strFileName;
+	{
+		_grmGlassData* pGlassData = pData->GetGlassData();
+		CTime CurrTime = pGlassData->m_tmGlassLoading;
+		CString strTime=_T(""), strFileName=_T("");
+		strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+			CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+		strFileName.Format("%s_%s.bin", pGlassData->m_strGlassID, strTime.GetBuffer(0));
+
+		strcpy(pData->GetGlassData()->m_strFileName, strFileName.GetBuffer(0));
+	}
+	strcpy(pData->GetGlassData()->m_strPath, LOCAL_AOIRAWBIN_PATH);
+
+	if(!WriteBinFile(pData))
+		return FALSE;
+	
+	return TRUE;
+}
+
+BOOL CGlassRawDemo::SequenceReviewStart( CgrmGlassRawData* pData )
+{
+	m_tmReviewStart = m_tmReviewEnd = CTime::GetCurrentTime();
+
+	//�뿬湲곗뿉�꽌 �씪�씤蹂꾨줈 �뙆�씪紐�, �샊�� Path �쐞移� 寃곗젙�븯硫대맖. AOIServer �샊�� ReviewServer�뿉�꽌 �븞�빐�룄�맖 [源��깭�쁽2019/9/4]
+	pData->GetGlassData()->m_strFileName;
+	strcpy(pData->GetGlassData()->m_strPath, NETWORK_AOIRAWBIN_PATH);
+	//strcpy(pData->GetGlassData()->m_strPath, LOCAL_AOIRAWBIN_PATH);
+
+	CString strFindFile;
+	int nCloseTime = 600*100000;//sec
+	int nReTryTime = 30;
+	{
+		CTime tmReviewLoading = CTime::GetCurrentTime();
+		CString strWild;
+		strWild.Format("%s\\%s_*.*", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strGlassID);
+		CakFileUtil akFileFinder;
+		while(nReTryTime--)
+		{
+			akFileFinder.FindFile(strWild.GetBuffer(0), FALSE);
+			VECFINDDATA* pFindData = akFileFinder.getFindData();
+			int nFileNamePos = strlen(akFileFinder.getProcessPath());
+			std::map<LONGLONG, CString> mapSpanFileName;
+			for(int i=0; i<pFindData->size(); i++)
+			{
+				char* pFileName = &((*pFindData)[i]).name[nFileNamePos];
+				{
+					CakParser parser;
+					parser.process(pFileName, "_.");
+					if(parser.getTokNum() < 4) continue;
+
+					int nDataTime[8]={};
+					{
+						int nTokIndex=0;
+						const char* pGlassId = parser.getTokStr(nTokIndex++);
+						char* pDate = &pFileName[parser.getTokPos(nTokIndex++)];
+						char* pTime = &pFileName[parser.getTokPos(nTokIndex++)];
+
+						nDataTime[0] = (pDate[0]-'0')*1000 + (pDate[1]-'0')*100 + (pDate[2]-'0')*10+ (pDate[3]-'0')*1;
+						nDataTime[1] = (pDate[4]-'0')*10+ (pDate[5]-'0')*1;
+						nDataTime[2] = (pDate[6]-'0')*10+ (pDate[7]-'0')*1;
+						nDataTime[3] = (pTime[0]-'0')*10+ (pTime[1]-'0')*1;
+						nDataTime[4] = (pTime[2]-'0')*10+ (pTime[3]-'0')*1;
+						nDataTime[5] = (pTime[4]-'0')*10+ (pTime[5]-'0')*1;
+					}
+					
+					CTime tmTemp(nDataTime[0], nDataTime[1], nDataTime[2], nDataTime[3], nDataTime[4], nDataTime[5] );
+					CTimeSpan tmSpan = tmReviewLoading-tmTemp;
+					mapSpanFileName.insert(std::make_pair(tmSpan.GetTotalSeconds(), pFileName));
+				}
+			}
+
+			if(mapSpanFileName.empty() == FALSE)
+			{
+				if(mapSpanFileName.begin()->first < nCloseTime)
+				{
+					//媛��옣 理쒓렐 寃곌낵�뙆�씪 李얘린 �꽦怨� [源��깭�쁽 2019/7/17]
+					strFindFile = mapSpanFileName.begin()->second;
+					break;
+				}
+			}
+			akFileFinder.clear();
+			Sleep(100);
+		}
+	}
+
+	if(strFindFile.IsEmpty()) return FALSE;
+
+	strcpy(pData->GetGlassData()->m_strFileName, strFindFile.GetBuffer(0));
+
+
+	if(!ReadBinFile(pData))
+		return FALSE;
+
+	strcpy(pData->GetGlassData()->m_strPath, LOCAL_AOIRAWBIN_PATH);
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawDemo::SequenceReviewEnd( CgrmGlassRawData* pData )
+{ 
+	m_tmReviewEnd = CTime::GetCurrentTime();
+	m_tmFileCreateTime = CTime::GetCurrentTime();
+	
+	//�뿬湲곗뿉�꽌 �씪�씤蹂꾨줈 �뙆�씪紐�, �샊�� Path �쐞移� 寃곗젙�븯硫대맖. AOIServer �샊�� ReviewServer�뿉�꽌 �븞�빐�룄�맖 [源��깭�쁽2019/9/4]
+	pData->GetGlassData()->m_strFileName;
+	strcpy(pData->GetGlassData()->m_strPath, NETWORK_AOIRAWDFS_PATH);
+
+	if(0) ReadMuraFile(pData);
+
+	if(WriteAOIFile(pData) == FALSE)
+		return FALSE;
+
+	if(0)
+	{
+		_grmGlassData* pGlassData = pData->GetGlassData();
+
+		SendMessageFTPUploadRaw(pGlassData);
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_REVIEW_IMAGE);
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_AOI_IMAGE); 
+		SendMessageFTPUploadImage(pGlassData, FTPCMD_MURA_IMAGE);
+		SendMessageFTPUploadLinkFile(pGlassData);
+
+	}
+	
+	
+
+	
+	return TRUE;
+}
+
+BOOL CGlassRawDemo::SequenceFtpUpload( char* pRawFilePathName )
+{
+
+	CTime tmFileCreate; 
+	_grmGlassData GlassData;
+	_grmGlassData* pGlassData = &GlassData;
+
+	//�젙蹂� �뼸�뼱�삤湲� [源��깭�쁽 2019/1/25]
+	{
+		//"D:\\DIT_ResultData\\Raw\\";
+		//6CCF01P7_HPANELID_20190125_002545.csv
+
+		char* pFileName = CakFileUtil::getFileName(pRawFilePathName);
+		char* pext = CakFileUtil::getFileExt(pRawFilePathName);
+
+		if(!strcmp(pext, "csv") == FALSE) return FALSE;
+
+		CakParser parser;
+		parser.process(pFileName, "_.");
+		if(parser.getTokNum() < 5) return FALSE;
+
+		strcpy(pGlassData->m_strOperID, parser.getTokStr(0));
+		strcpy(pGlassData->m_strGlassID, parser.getTokStr(1));
+		char* pDate = &pFileName[parser.getTokPos(2)];
+		char* pTime = &pFileName[parser.getTokPos(3)];
+		int nData[8]={};
+		nData[0] = (pDate[0]-'0')*1000 + (pDate[1]-'0')*100 + (pDate[2]-'0')*10+ (pDate[3]-'0')*1;
+		nData[1] = (pDate[4]-'0')*10+ (pDate[5]-'0')*1;
+		nData[2] = (pDate[6]-'0')*10+ (pDate[7]-'0')*1;
+		nData[3] = (pTime[0]-'0')*10+ (pTime[1]-'0')*1;
+		nData[4] = (pTime[2]-'0')*10+ (pTime[3]-'0')*1;
+		nData[5] = (pTime[4]-'0')*10+ (pTime[5]-'0')*1;
+
+		CTime tmTemp(nData[0], nData[1], nData[2], nData[3], nData[4], nData[5] );
+		tmFileCreate = tmTemp;
+
+		FILE* pf = fopen(pRawFilePathName, "r");
+		if(pf)
+		{
+			char buffer[512];
+			fgets(buffer, 512, pf);
+			if(buffer[0] != 'H') return FALSE;
+			fgets(buffer, 512, pf);
+			fgets(buffer, 512, pf);
+
+			fgets(buffer, 512, pf);buffer[strlen(buffer)-1] = 0;
+			strcpy(pGlassData->m_strEquipID, &buffer[strlen("EQUIP_TYPE:")]);
+
+			fgets(buffer, 512, pf);buffer[strlen(buffer)-1] = 0;
+			strcpy(pGlassData->m_strStepID, &buffer[strlen("EQUIP_ID:")]);
+		}
+		else
+		{
+			return FALSE;
+		}
+
+
+		CakFileUtil::getPath(pGlassData->m_strPath, 256, pRawFilePathName);
+
+	}
+
+
+
+	m_tmReviewEnd = m_tmReviewStart = tmFileCreate;
+
+ 
+	SendMessageFTPUploadRaw(pGlassData);
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_REVIEW_IMAGE);
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_AOI_IMAGE); 
+	SendMessageFTPUploadImage(pGlassData, FTPCMD_MURA_IMAGE);//�뾾�쑝硫� �떎�뙣 �븯寃좎�
+	SendMessageFTPUploadLinkFile(pGlassData);
+
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawDemo::WriteAOIFile( CgrmGlassRawData* pData )
+{
+	BOOL bResult = TRUE;
+	
+	bResult &= MakeAOIFile(pData);
+	bResult &= MakeAnaFile(pData);	
+	
+	m_GlassRawRTMS.WriteAOIFile(pData);
+
+	AKLOG("WriteAOIFile Complete");
+	return bResult;
+}
+
+BOOL CGlassRawDemo::MakeAOIFile( CgrmGlassRawData* pData )
+{
+	_grmGlassData* pGlass = pData->GetGlassData();
+	CString strFilePathName;
+	CString strFileName;//�뙆�씪�깮�꽦 �떆媛� �븣臾몄뿉 �뿬湲곗꽌 �젙�솗�븯寃� �뙆�씪紐� �떎�떆 �젙�젙
+	{
+		//Glass �젙蹂�
+		CTime CurrTime = m_tmReviewEnd;
+		CString strTime;
+		strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+			CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+		strFileName.Format("%s_%s.csv", pGlass->m_strGlassID, strTime);
+	}
+	
+	strFilePathName.Format("%s\\%s", pGlass->m_strPath, strFileName);//pGlass->m_strFileName);
+	//strFilePathName.Format("C:\\AOIServer\\NFS\\RAW\\%s", pData->GetGlassData()->m_strFileName);
+	
+	
+	//FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if(pf == NULL)
+	{
+		AKLOG("MakeAOIFile Fail : [%s]", strFilePathName.GetBuffer(0));
+		return FALSE;
+	}
+	
+	
+	
+	CString strBuffer;
+	CString strLine;
+
+	//////////////////////////////////////////////////////////////////////////
+	//HEDER
+	fprintf(pf, "HEADER_BEGIN\n");
+	{
+		makeDataHeader(strLine, pGlass);
+		fprintf(pf, "%s", strLine);
+	}
+	fprintf(pf, "HEADER_END\n\n");
+
+	//////////////////////////////////////////////////////////////////////////
+	//GLASS_DATA
+	fprintf(pf, "GLASS_DATA_BEGIN\n");
+	{
+		fprintf(pf, "GLASS_ID,OWNER_CODE,OWNER_TYPE,PRODUCT_ID,PROCESS_ID,PRODUCT_GROUP,LOT_ID,CST_ID,SLOT_ID,PRE_PROCESS_ID,PRE_EQP_ID,PRE_CHAMBER_ID,PRE_RECIPE_ID,GROUP_ID,AUTOSAMPLEFLAG\n");
+		
+		makeDataGlass(strLine, pGlass);
+		fprintf(pf, "%s\n", strLine);
+	}
+	fprintf(pf, "GLASS_DATA_END\n\n");
+
+	//////////////////////////////////////////////////////////////////////////
+	//BLOCK_SUMMARY
+	fprintf(pf, "BLOCK_SUMMARY_BEGIN\n");
+	{
+		fprintf(pf, "BLOCK_ID,BLOCK_JUDGE_AOI,BLOCK_JUDGE_MURA,BLOCK_JUDGE_ATS,BLOCK_JUDGE_TEG,TT_PANEL,OK_PANEL,NG_PANEL,X1_PANEL,X2_PANEL,X3_PANEL,X4_PANEL,X5_PANEL,X6_PANEL,X7_PANEL,X8_PANEL,X9_PANEL,TT_DEFECT_CNT,S_SIZE_DEFECT_CNT,M_SIZE_DEFECT_CNT,L_SIZE_DEFECT_CNT,TT_MURA_CNT,POINT_MURA_CNT,LINE_MURA_CNT,AREA_MURA_CNT,GLASS_ID_DCR,POINT_1,POINT_2,POINT_3,POINT_4,POINT_5\n");
+		
+		int nBlockNum = 1;
+		for(int i=0; i<nBlockNum; i++)
+		{
+			makeDataBlock(strLine, pData->GetBlockData(i));
+			fprintf(pf, "%s\n", strLine);
+		}
+	}
+	fprintf(pf, "BLOCK_SUMMARY_END\n\n");
+	
+	//////////////////////////////////////////////////////////////////////////
+	//PANEL_SUMMARY
+	fprintf(pf, "PANEL_SUMMARY_BEGIN\n");
+	{
+		fprintf(pf, "PANEL_ID,PANEL_JUDGE_AOI,PANEL_JUDGE_MURA,PANEL_JUDGE,TT_DEFECT,TT_MURA,PANEL_ID_2D,PANEL_FLAG,PANEL_GRADE,X_D,Y_D,X_A,Y_A,DELTA_X,DELTA_Y,OK_DEFECT,NG_DEFECT,X1_DEFECT,X2_DEFECT,X3_DEFECT,X4_DEFECT,X5_DEFECT,X6_DEFECT,X7_DEFECT,X8_DEFECT,X9_DEFECT,IJP1,IJP2,IJP3,IJP4,IJP5,IJP6,IJP7,IJP8,Mark1,Mark2,Mark3,Mark4,Mark5,Mark6,Mark7,Mark8\n");
+
+		for(int iCell = 0; iCell < pData->GetGlassData()->m_nCellNum; iCell++)
+		{
+			_grmCellData* pCell = pData->GetCellData(iCell);
+			makeDataCell(strLine, pData, pCell);	
+			fprintf(pf, "%s\n", strLine);
+		}
+	}
+	fprintf(pf, "PANEL_SUMMARY_END\n\n");
+	
+	//////////////////////////////////////////////////////////////////////////
+	//DEFECT_DATA
+	fprintf(pf, "DEFECT_DATA_BEGIN\n");
+	{
+		fprintf(pf, "PANEL_ID,DEFECT_NO1,DEFECT_NO2,UPDATE_TIME,STEP_1ST,RECIPE_1ST,STEP_CURRENT,RECIPE_CURRENT,GATE1,DATA1,");
+		fprintf(pf, "GATE2,DATA2,X1,Y1,X2,Y2,AOI_DEFECT_TYPE,AOI_GRAY_H,AOI_GRAY_L,AOI_GRAY_AVE,");
+		fprintf(pf, "AOI_DEFECT_AREA,AOI_DEFECT_LGT,AOI_DEFECT_WID,AOI_DEFECT_HGT,AOI_DEFECT_WIH,AOI_DEFECT_SIZE,DEFECT_PIX,MASK_DEFECT,REPEAT_DEFECT,DEFECT_IMAGE_DATA,");
+		fprintf(pf, "AOI_CCD_NO,AOI_REVIEW_NO,OP_ID_1ST,OP_ID_2ND,OP_ID_CURRENT,DEFECT_JUGDE_1ST,DEFECT_JUGDE_2ND,DEFECT_JUGDE_CURRENT,DEFECT_REASON1,DEFECT_REASON2,");
+		fprintf(pf, "DEFECT_REASON3,WSI_JUDGE,MURA_GRAY_H,MURA_GRAY_L,MURA_GRAY_AVE,MURA_AREA,MURA_LGT,MURA_WID,MURA_HGT,MURA_SIZE,");
+		fprintf(pf, "MURA_PIX,MURA_TYPE,MURA_JUDGE,MURA_GRADE,MURA_IMAGE_DATA,RSRV1,RSRV2,RSRV3,RSRV4,RSRV5,");
+		fprintf(pf, "RSRV6,RSRV7,RSRV8,RSRV9,FILE_NAME\n");
+
+		for(int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+		{
+			_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+			if(makeDataDefect(strLine, pData, pDefect))
+			{
+				fprintf(pf, "%s\n", strLine);
+			}
+		}
+		fprintf(pf, "DEFECT_DATA_END\n\n");
+	}
+	
+	
+	AKLOG("MakeAOIFile Complete : [%s]", strFilePathName.GetBuffer(0));
+	fclose(pf);
+	return TRUE;
+}
+
+BOOL CGlassRawDemo::MakeAnaFile( CgrmGlassRawData* pData )
+{
+	return TRUE;
+
+	CString strFilePathName;
+	strFilePathName.Format("%s\\%sana", pData->GetGlassData()->m_strPath, pData->GetGlassData()->m_strFileName);
+
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if(pf == NULL)
+	{
+		AKLOG("MakeAOIFile Fail : [%s]", strFilePathName.GetBuffer(0));
+		return FALSE;
+	}
+
+	fprintf(pf, "%s\n", pData->GetGlassData()->m_strGlassID);
+	fprintf(pf, "m_strImageName, m_strDefectCode, UMCenterAlignX, UMCenterAlignY, m_nLevelSrcMin, m_nLevelSrcMax, m_nLevelSrcAvg, m_nLevelRefMin, m_nLevelRefMax, m_nLevelRefAvg, m_nLevelDiffMin, m_nLevelDiffMax, m_nLevelDiffAvg");
+	for(int i=0; i<MAX_ZONE_NUM; i++) fprintf(pf, ",Zone%02d", i);
+	fprintf(pf, ", m_sDefectPeak, m_nPixelSize, DefectType, UMSize, Density, ScrtRatio, MergeState");
+	fprintf(pf, "\n");
+
+	for(int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+	{
+		_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+		if(pData->GetGlassData()->m_nScanCoordinateY == 1) //遺꾪뙋�꽕鍮꾩쓽 寃쎌슦 XY諛섏쟾
+		{
+			fprintf(pf, "%s, %s, %.3lf, %.3lf, %d, %d, %d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_strAoiImageName, pDefect->m_strDefectCode, (double)pDefect->m_nUMCenterAlignY / 1000.0, (double)pDefect->m_nUMCenterAlignX / 1000.0,
+				pDefect->m_nLevelSrcMin, pDefect->m_nLevelSrcMax, pDefect->m_nLevelSrcAvg,
+				pDefect->m_nLevelRefMin, pDefect->m_nLevelRefMax, pDefect->m_nLevelRefAvg,
+				pDefect->m_nLevelDiffMin, pDefect->m_nLevelDiffMax, pDefect->m_nLevelDiffAvg);
+			for(int iz=0; iz<MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZonePixelCount[iz]);
+			}
+			fprintf(pf, ",%d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_sDefectPeak, pDefect->m_nPixelSize, pDefect->m_DefectType, (int)pDefect->m_nUMSize, pDefect->m_nDensity, pDefect->m_nScratchRatio, pDefect->m_bMergeState);
+
+			fprintf(pf, ", %d, %d, %d, %d, %d", pDefect->m_nAngle, pDefect->m_nMajor, pDefect->m_nMinor, pDefect->m_nCompact, pDefect->m_nThickness);
+
+			fprintf(pf, "\n");
+		}
+		else
+		{
+			fprintf(pf, "%s, %s, %.3lf, %.3lf, %d, %d, %d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_strAoiImageName, pDefect->m_strDefectCode, (double)pDefect->m_nUMCenterAlignX / 1000.0, (double)pDefect->m_nUMCenterAlignY / 1000.0,
+				pDefect->m_nLevelSrcMin, pDefect->m_nLevelSrcMax, pDefect->m_nLevelSrcAvg,
+				pDefect->m_nLevelRefMin, pDefect->m_nLevelRefMax, pDefect->m_nLevelRefAvg,
+				pDefect->m_nLevelDiffMin, pDefect->m_nLevelDiffMax, pDefect->m_nLevelDiffAvg);
+			for(int iz=0; iz<MAX_ZONE_NUM; iz++)
+			{
+				fprintf(pf, ",%d", pDefect->m_sZonePixelCount[iz]);
+			}
+			fprintf(pf, ",%d, %d, %d, %d, %d, %d, %d", 
+				pDefect->m_sDefectPeak, pDefect->m_nPixelSize, pDefect->m_DefectType, (int)pDefect->m_nUMSize, pDefect->m_nDensity, pDefect->m_nScratchRatio, pDefect->m_bMergeState);
+
+			fprintf(pf, ", %d, %d, %d, %d, %d", pDefect->m_nAngle, pDefect->m_nMajor, pDefect->m_nMinor, pDefect->m_nCompact, pDefect->m_nThickness);
+
+			fprintf(pf, "\n");
+		}
+	}
+	AKLOG("MakeAnaFile Complete %s", strFilePathName);
+	fclose(pf);
+
+	return TRUE;
+}
+
+void CGlassRawDemo::makeDataHeader( CString& strLine, _grmGlassData* pGlassData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	CString strCurDateTime;
+	{
+		CTime Time = m_tmReviewEnd;
+		strCurDateTime.Format("%04d/%02d/%02d_%d:%02d:%02d", 
+			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+			Time.GetHour(), Time.GetMinute(), Time.GetSecond());
+	} 
+	strValue.Format("FILE_VERSION:%.1lf\n", 1.0);
+	strLine += strValue;
+	strValue.Format("FILE_CREATED_TIME:%s\n", strCurDateTime);
+	strLine += strValue;
+	strValue.Format("EQUIP_TYPE:%s\n", pGlassData->m_strEquipID);
+	strLine += strValue;
+	strValue.Format("EQUIP_ID:%s\n", pGlassData->m_strStepID);
+	strLine += strValue;
+	strValue.Format("CONTENT:%s\n", _T("GLASS_DATA/EQP_GLASS_DATA/BLOCK_SUMMARY/PANEL_SUMMARY/DEFECT_DATA"));
+	strLine += strValue;
+}
+void CGlassRawDemo::makeDataGlass( CString& strLine, _grmGlassData* pGlassData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ","; 
+	
+	//臾쇰쪟�젙蹂� �뙆�떛�빐�꽌 媛�吏�怨� �삤湲� CString strProcessID, strProductID, strLotID, strSlotID;
+	{ 
+		std::map<CString, CString> mapTransData;
+
+		CString strTemp;
+		strTemp.Format("D:\\DIT_ResultData\\DownloadData\\%s.dat", pGlassData->m_strGlassID); 
+
+		FILE *pFile = fopen(strTemp.GetBuffer(0), "r");  
+		if(pFile)
+		{     
+			const int MAX_BUFFER	= 1024;
+			char buffer[MAX_BUFFER];   
+			CString strKey;
+			CString strValue;
+			char* pFlagPos;
+			char* pEndFlagPos;
+			char* pTest = "��";
+			while (fgets(buffer, MAX_BUFFER, pFile) != '\0')
+			{   
+				pFlagPos = strchr(buffer, '=');
+				
+				if(pFlagPos == NULL) continue;
+
+				if(pEndFlagPos = strchr(pFlagPos, -29)) //"��"�걹�뿉 �엳�뒗 end臾몄옄�뿴 �젣嫄�
+					pEndFlagPos[0] = 0;
+
+				pFlagPos[0] = 0; // = �씠嫄� 0�쑝濡� 留뚮뱾�뼱�꽌 Key, Value 遺꾨━
+
+				strKey = buffer;
+				strValue = &pFlagPos[1];
+
+				strValue.Remove(' ');//�샊�떆 紐⑤�� 怨듬갚 �젣嫄� [源��깭�쁽 2019/1/31]
+
+				mapTransData.insert(std::make_pair(strKey, strValue));
+			}
+			fclose(pFile);
+		} 
+
+		//GlassData�뿉 媛믪쓣 �꽔�뼱以� [源��깭�쁽 2019/1/31]
+		strcpy(pGlassData->m_strSLotID, mapTransData["Slot_ID"].GetBuffer(0));
+		strcpy(pGlassData->m_strProductID, mapTransData["Product_ID"].GetBuffer(0));
+		strcpy(pGlassData->m_strProcessID, mapTransData["Process_ID"].GetBuffer(0));
+		strcpy(pGlassData->m_strLotID, mapTransData["Lot_ID"].GetBuffer(0));
+	}
+ 
+ 
+	strValue.Format("%s", pGlassData->m_strGlassID);	 	//1. Glass ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strOwnerCode);  	//2. OWNER_CODE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strOwnerType);  	//3. OWNER_TYPE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProductID);  	//4. PRODUCT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProcessID);  	//5. PROCESS_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProductGroup);  //6. PRODUCT_GROUP
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strLotID);  		//7. LOT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strCSTID);  		//8. CST_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strSLotID); 		//9.SLOT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProcessID);  //10.PRE_PROCESS_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strEquipID);		//11.PRE_EQP_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strPreChamerID);	//12.PRE_CHAMBER_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strPreRecipeID);	//13.PRE_RECIPE_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strGroupID);		//14.GROUP_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pGlassData->m_cAutoSampleFlag);  //15.AUTOSAMPLEFLAG
+	strLine += strValue;
+
+
+}
+
+void CGlassRawDemo::makeDataBlock( CString& strLine, _grmBlockData* pBlockData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("%s", pBlockData->m_strBlockID);				//1. BLOCK_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pBlockData->m_cBlockJudgeAOI);			//2. BLOCK_JUDGE_AOI		
+	strLine += strValue+strDiv;
+	strValue.Format("%c", 'G');									//3. BLOCK_JUDGE_MURA
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pBlockData->m_cBlockJudgeATS);			//4. BLOCK_JUDGE_ATS		
+	strLine += strValue+strDiv;
+	strValue.Format("%c", pBlockData->m_cBlockJudgeTEG);			//5. BLOCK_JUDGE_TEG		
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//6. TT_PANEL
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//7. OK_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//8. NG_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//9. X1_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//10. X2_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//11. X3_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//12. X4_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//13. X5_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//14. X6_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//15. X7_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//16. X8_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//17. X9_PANEL(Count)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//18. TT_DEFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//19. S_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//20. M_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//21. L_SIZE_DFECT_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//22. GLASS_ID_DCR
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//23. TT_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//24. POINT_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//25. LINE_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//26. AREA_MURA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//27. POINT_1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//28. POINT_2
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//29. POINT_3
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//30. POINT_4
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);										//31. POINT_5
+	strLine += strValue;
+}
+
+
+void CGlassRawDemo::makeDataCell( CString& strLine, CgrmGlassRawData* pData, _grmCellData* pCellData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	CString strJudgeCode = "O";
+	CString strLastCode = "O";
+	{
+		switch (pCellData->m_nJudgement)
+		{
+		case 0/*Judge_OK*/:		strJudgeCode = "G"; break;
+		case 2/*Judge_NG*/:		strJudgeCode = "N"; break;
+		case 10/*Judge_Rework*/:	strJudgeCode = "O"; break;
+		case 1/*Judge_RP*/:		strJudgeCode = "O"; break;
+		case 6/*Judge_Review*/:	strJudgeCode = "O"; break;
+		case 7/*Judge_RC*/:		strJudgeCode = "O"; break;
+		}
+	}
+	strLastCode = strJudgeCode;
+
+	strValue.Format("%s%s", pData->GetGlassData()->m_strGlassID, pCellData->m_strCellName);													//1. PANEL_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strJudgeCode);																//2. PANEL_JUDGE_AOI
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "O");																			//3. PANEL_JUDGE_MURA
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strLastCode);																	//4. PANEL_JUDGE
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->getTotalDefectNum());												//5. tt_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", m_MuraResultFile.GetDefectNum(pCellData->m_nCellID));												//6. tt_MURA
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");																		//7. PANEL_ID_2D
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nJudgeFlag);														//8. PANEL_FLAG
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nJudgeGlade);													//9. PANEL_GRADE
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellLeft);													//10. X_D
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellTop);													//11. Y_D
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellRight-pCellData->m_rectCellLeft);						//12. X_A
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellBottom-pCellData->m_rectCellTop);						//13. Y_A
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//14. DELTA_X
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//15. DELTA_Y
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nDefectNumJudgeOKWhite + pCellData->m_nDefectNumJudgeOKBlack);	//16. OK_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nDefectNumJudgeNG);												//17. NG_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//18. X1_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//19. X2_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//20. X3_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//21. X4_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//22. X5_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//23. X6_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//24. X7_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//25. X8_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//26. X9_DEFECT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//27. IJP1
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//28. IJP2
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//29. IJP3
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//30. IJP4
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//31. IJP5
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//32. IJP6
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//33. IJP7
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "0");																			//34. IJP8
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//35. Mark1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//36. Mark2
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//37. Mark3
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//38. Mark4
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//39. Mark5
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//40. Mark6
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//41. Mark7
+	strLine += strValue+strDiv;
+	strValue.Format("%d", 0);																			//42. Mark8
+	strLine += strValue;
+
+}
+
+BOOL CGlassRawDemo::makeDataDefect( CString& strLine, CgrmGlassRawData* pData, _grmDefectData* pDefectData )
+{
+	strLine.Empty();
+	CString strValue;
+	CString strDiv = ",";
+
+	_grmGlassData* pGlassData = pData->GetGlassData();
+	_grmCellData* pCellData = pData->GetCellData(pDefectData->m_nCellIdx);
+
+	if(pDefectData->m_ReviewDefect.m_nPlanType == 1000 //aoi寃고븿
+		//pDefectData->m_ReviewDefect.m_nPlanType == 999 
+		) return FALSE;
+
+	CString strUpdateTime;
+	{
+		CTime Time = pGlassData->m_tmInspectionEND;
+		strUpdateTime.Format("%04d/%02d/%02d_%d:%02d:%02d", 
+			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+			Time.GetHour(), Time.GetMinute(), Time.GetSecond());
+
+// 		CTime Time = pGlassData->m_tmInspectionEND;
+// 		strUpdateTime.Format("%04d%02d%02d%02d%02d",
+// 			Time.GetYear(), Time.GetMonth(), Time.GetDay(),
+// 			Time.GetHour(), Time.GetMinute());
+	}
+	
+	CString strStepFirst;//泥ル쾲吏� �뒪�깮 [源��깭�쁽 2018/12/5]
+	{
+		if(pDefectData->m_strStackFirst[0])
+		{
+			strStepFirst =pDefectData->m_strStackFirst;
+		}	
+		else
+		{
+			strStepFirst = pGlassData->m_strStepID;
+		}
+	}
+
+	strValue.Format("%s%s", pData->GetGlassData()->m_strGlassID, pCellData->m_strCellName);					//1. CELL ID
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nDefectID);				//2. DEFECT_NO1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nDefectID);				//3. DEFECT_NO2
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strUpdateTime);							//4. UPDATE_TIME
+	strLine += strValue+strDiv;
+	strValue.Format("%s", strStepFirst);							//5. STEP_1ST
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strRecipeName);				//6. RECIPE_1ST
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strStepID);					//7. STEP_CURRENT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strRecipeName);				//8. RECIPE_CURRENT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellGate);				//9. GATE1, ��蹂� Gate�씪�씤(�뼹�씪�씤 蹂댁젙 �쟾)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellData);				//10. DATA1, ��蹂� Data�씪�씤(�뼹�씪�씤 蹂댁젙 �쟾)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellGateAlign);			//11. GATE2, ��蹂� Gate�씪�씤(�뼹�씪�씤 蹂댁젙 �썑)
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellDataAlign);			//12. DATA2, ��蹂� Data�씪�씤(�뼹�씪�씤 蹂댁젙 �썑)
+	strLine += strValue+strDiv;
+
+
+
+	//_grmGlassData* pGlass = pData->GetGlassData(); 
+
+	
+
+	// x,y醫뚰몴 mm�떒�쐞 �냼�닔�젏 �꽭�옄由ш퉴吏� �몴�쁽 (怨좉컼�궗 �슂泥�) - 2019-01-30 HJH
+	if(pGlassData->m_nScanCoordinateY == 1) //遺꾪뙋�꽕鍮꾩쓽 寃쎌슦 XY諛섏쟾
+	{
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignY / 1000.0);			//13. X1, um�떒�쐞 X醫뚰몴 (Glass Center 湲곗�, �뼹�씪�씤蹂댁젙 �썑)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignX / 1000.0);			//14. Y1, um�떒�쐞 Y醫뚰몴 (Glass Center 湲곗�, �뼹�씪�씤蹂댁젙 �썑)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellY / 1000.0);					//15. X2, �� �썝�젏 湲곗� x 醫뚰몴
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellX / 1000.0);					//16. Y2, �� �썝�젏 湲곗� y 醫뚰몴
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_DefectType);				//17. AOI_DEFECT_TYPE, SERVER_DefectType
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMax);				//18. AOI_GRAY_H, 寃고븿 諛앷린 Max			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMin);				//19. AOI_GRAY_L, 寃고븿 諛앷린 Min			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcAvg);				//20. AOI_GRAY_AVE, 寃고븿 諛앷린 Avg			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nPixelSize);				//21. AOI_DEFECT_AREA 			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nDefectRScale);			//22. AOI_DEFECT_LGT, 寃고븿 湲몄씠				
+		strLine += strValue+strDiv;
+		strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectSizeType));				//23. AOI_DEFECT_WID , <- 190106 怨좉컼 �떞�떦�옄 �슂泥� �궎�겙�뿬�옄	�궗�씠利덊��엯�쑝濡쒕줈 蹂�寃�		
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_sPixelWidth);				//24. AOI_DEFECT_HGT		
+	}
+	else
+	{
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignX / 1000.0);			//13. X1, um�떒�쐞 X醫뚰몴 (Glass Center 湲곗�, �뼹�씪�씤蹂댁젙 �썑)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCenterAlignY / 1000.0);			//14. Y1, um�떒�쐞 Y醫뚰몴 (Glass Center 湲곗�, �뼹�씪�씤蹂댁젙 �썑)
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellX / 1000.0);					//15. X2, �� �썝�젏 湲곗� x 醫뚰몴
+		strLine += strValue+strDiv;
+		strValue.Format("%.3lf", pDefectData->m_nUMCellY / 1000.0);					//16. Y2, �� �썝�젏 湲곗� y 醫뚰몴
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_DefectType);				//17. AOI_DEFECT_TYPE, SERVER_DefectType
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMax);				//18. AOI_GRAY_H, 寃고븿 諛앷린 Max			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcMin);				//19. AOI_GRAY_L, 寃고븿 諛앷린 Min			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nLevelSrcAvg);				//20. AOI_GRAY_AVE, 寃고븿 諛앷린 Avg			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nPixelSize);				//21. AOI_DEFECT_AREA 			
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_nDefectRScale);			//22. AOI_DEFECT_LGT, 寃고븿 湲몄씠				
+		strLine += strValue+strDiv;
+		strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectSizeType));				//23. AOI_DEFECT_WID, <- 190106 怨좉컼 �떞�떦�옄 �슂泥� �궎�겙�뿬�옄	�궗�씠利덊��엯�쑝濡쒕줈 蹂�寃�					
+		strLine += strValue+strDiv;
+		strValue.Format("%d", pDefectData->m_sPixelHeight);				//24. AOI_DEFECT_HGT		
+	}
+	
+	
+		
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_DefectSizeType);			//25. AOI_DEFECT_WIH, SERVER_DefectSizeType			
+	strLine += strValue+strDiv;
+	strValue.Format("%.3f", pDefectData->m_nUMSize);					//26. AOI_DEFECT_SIZE 			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nPixelSize);				//27. DEFECT_PIX 			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_DefectSubType == 2 ? 1:0);	//28. MASK_DEFECT, �븳 Glass�뿉�꽌 諛쒓껄�맂 留덉뒪�겕寃고븿 臾띠쓬�쓽 			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_DefectSubType == 3 ? 1:0);		//29. REPEAT_DEFECT, �뿰�냽寃고븿諛쒓껄�쐞�븳 �룞�씪醫뚰몴 諛섎났�닔			
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pDefectData->m_ReviewDefect.m_strRevImageName);			//30. DEFECT_IMAGE_DATA		
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nDefectIdx);				//31. AOI_CCD_NO  			
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_ReviewDefect.m_nShotIndex);			//32. AOI_REVIEW_NO  				
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");									//33. OP_ID_1ST  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");									//34. OP_ID_2ND  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A*");									//35. OP_ID_CURRENT  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectJudgement));			//36. DEFECT_JUGDE_1ST  			
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "O");										//37. DEFECT_JUGDE_2ND  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", GetDefectInfoToString(DMT_DefectSizeType, pDefectData->m_DefectJudgement));			//38. DEFECT_JUGDE_CURRENT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A");										//39. DEFECT_REASON1  
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A");										//40. DEFECT_REASON2 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "A");										//41. DEFECT_REASON3 
+	strLine += strValue+strDiv;
+	strValue.Format("%.2lf", pDefectData->m_ReviewDefect.m_fWsi_ResultData[1]);//42. WSI_JUDGE 
+	strLine += strValue+strDiv;
+	//KMS - 20190128 MuraDefect �궡�슜 異붽�
+	_MacroDefect* pMuraDefect = m_MuraResultFile.FindDefect(pDefectData->m_nUMCenterAlignX, pDefectData->m_nUMCenterAlignY);
+	_MacroDefect MuraDefect;
+	if(pMuraDefect) MuraDefect = *pMuraDefect;
+	strValue.Format("%d", MuraDefect.G_MAX);										//43. MURA_GRAY_H 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.G_MIN);										//44. MURA_GRAY_L 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.G_AVG);										//45. MURA_GRAY_AVE 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_S);										//46. MURA_AREA 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_L);										//47. MURA_LGT 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_W);										//48. MURA_WID  
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.COORD_Y1);										//49. MURA_HGT 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.SIZE_S);										//50. MURA_SIZE 
+	strLine += strValue+strDiv;
+	strValue.Format("%d", MuraDefect.COORD_PX1);											//51. MURA_PIX 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.MAIN_TYPE.GetBuffer(0));									//52. MURA_TYPE 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.JUDGE.GetBuffer(0));										//53. MURA_JUDGE 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.SUB_TYPE.GetBuffer(0));										//54. MURA_GRADE 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", MuraDefect.IMG_FILE_NAME.GetBuffer(0));								//55. MURA_IMAGE_DATA 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//56. RSRV1 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//57. RSRV2 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//58. RSRV3 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//59. RSRV4 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//60. RSRV5 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//61. RSRV6 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//62. RSRV7 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//63. RSRV8 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "*");									//64. RSRV9 
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pDefectData->m_strAoiImageName);				//65. FILE_NAME 			
+	strLine += strValue;
+
+	return TRUE;
+}
+
+BOOL CGlassRawDemo::ReadMuraFile( CgrmGlassRawData* pData )
+{
+ 	if(m_MuraResultFile.m_strServerResultRawPath.IsEmpty() == FALSE)//�씫�� 寃곌낵 �뙆�씪 蹂듭궗,�궘�젣 �깭�쁽[2017/3/29]
+ 	{
+		CString strMacroFilePath;
+		{
+			strMacroFilePath.Format("%s\\%s_*.dat", m_MuraResultFile.m_strMacroResultRawPath, pData->GetGlassData()->m_strGlassID);
+
+			CFileFind FF;
+
+			if (FF.FindFile(strMacroFilePath))
+			{
+				FF.FindNextFile();
+				strMacroFilePath = FF.GetFilePath();
+				FF.Close();
+			}
+			else
+			{
+				AKLOG("Find Macro File Fail. [%s]", strMacroFilePath);
+				return FALSE;
+			}
+		}
+		
+
+ 		CString strMacroResultTargetPath;
+ 		strMacroResultTargetPath.Format("%s\\%s.dat", m_MuraResultFile.m_strServerResultRawPath, pData->GetGlassData()->m_strGlassID);
+ 
+ 		if(TRUE == CopyFile(strMacroFilePath,strMacroResultTargetPath,FALSE))
+ 		{
+ 			if(m_MuraResultFile.openFile(strMacroResultTargetPath.GetBuffer(0)) == TRUE)
+ 			{
+ 				AKLOG("Macro File Read Success : %dItem", m_MuraResultFile.GetDefectNum());
+ 				//DeleteFile(strMacroResultTargetPath); //�궘�젣�뒗 hddspacectrl�씠 �븯�뒗 寃껋쑝濡� �넻�씪
+ 			}
+ 			else
+ 			{
+ 				AKLOG("Macro File Read Fail[%s]", strMacroFilePath);
+ 				//DeleteFile(strMacroResultTargetPath); //�궘�젣�뒗 hddspacectrl�씠 �븯�뒗 寃껋쑝濡� �넻�씪
+ 				return FALSE;
+ 			}
+ 		}
+ 	}
+ 
+	//臾대씪 �씠誘몄� 蹂듭궗(ftp�뾽濡쒕뱶瑜� �쐞�븿) [源��깭�쁽 2018/12/5]
+ 	if(m_MuraResultFile.m_strMacroResultImagePath.IsEmpty() == FALSE && m_MuraResultFile.m_strServerResultImagePath.IsEmpty() == FALSE)//�씠誘몄� �뙆�씪 蹂듭궗 �깭�쁽[2017/3/29]
+ 	{
+ 		CString strMacroImageSrcPath;
+ 		CString strMacroImageTarPath;
+ 
+ 		strMacroImageSrcPath.Format("%s\\%s", m_MuraResultFile.m_strMacroResultImagePath, pData->GetGlassData()->m_strGlassID);
+ 		strMacroImageTarPath.Format("%s\\%s", m_MuraResultFile.m_strServerResultImagePath, pData->GetGlassData()->m_strGlassID);
+ 
+		AKLOG("Macro Image File Copy Start[%s]", strMacroImageTarPath);
+ 		CakFileUtil::CopyFolder(strMacroImageSrcPath.GetBuffer(0), strMacroImageTarPath.GetBuffer(0), FALSE);
+		AKLOG("Macro Image File Copy End");
+ 	}
+
+	return TRUE;
+}
+
+
+void CGlassRawDemo::SendMessageFTPUploadLinkFile( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_LINK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+
+}
+ 
+void CGlassRawDemo::SendMessageFTPUploadRaw( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_RAW, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+  
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+
+}
+
+void CGlassRawDemo::SendMessageFTPDownloadStack( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_STACK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_DownFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CGlassRawDemo::SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPDownloader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	//GetFormatDescription(FTPCMD_DATAFILE, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+	{
+		CString strGlassIDOrg = pGlassData->m_strGlassID; 
+		CString strGlassID = strGlassIDOrg.Left(12);
+		sprintf(strServerFolder, "%s", pGlassData->m_strCassetteSequenceNo);
+		sprintf(strServerFile, "%s.dat", strGlassID.GetBuffer(0));  
+		sprintf(strLocalFolder,  "D:\\DIT_ResultData\\DownloadData"); 
+		sprintf(pLocalFile,  "%s.dat", strGlassID.GetBuffer(0)); 
+	}
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_DownFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CGlassRawDemo::SendMessageFTPUploadImage( _grmGlassData* pGlassData, emFTPCommand sort)
+{  
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+ 
+	char strServerFolder[256] = {};
+	char strServerFile[32];// = "*.*";
+	char strLocalFolder[256] = {};
+	char strLocalFile[32];// = "*.*"; 
+
+	GetFormatDescription(sort, strServerFolder, strServerFile, strLocalFolder, strLocalFile, pGlassData);
+   
+// 	if(0)//test 
+// 	{
+// 		sprintf(strServerFolder, "HDD1/DIT/TestC");
+// 	}
+ 
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				strLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;
+	upParam.m_nSendResultCode							= FALSE;
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload; //<--�슂嫄� �굹以묒뿉 援щ텇
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+  
+
+BOOL CGlassRawDemo::SendMessageFTPUploadIndexFile( _grmGlassData* pGlassData )
+{  
+	if(pGlassData == NULL) 
+		return FALSE;
+
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return FALSE;
+
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	GetFormatDescription(FTPCMD_INDEX, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+
+	// 	if(0)//test 
+	// 	{
+	// 		sprintf(strServerFolder, "HDD1/DIT/TestC");
+	// 		ServerFile = "ftptestfile.txt";
+	// 
+	// 		sprintf(strLocalFolder, "D:");
+	// 		pLocalFile = "ftptestfile.txt";
+	// 	}
+
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+	return TRUE;
+}
+
+void CGlassRawDemo::GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, _grmGlassData* pGlassData)
+{ 
+	
+	CString strGlassIDOrg = pGlassData->m_strGlassID; 
+	CString strGlassID = strGlassIDOrg.Left(12);
+	CString strGlassIDLevel5th = strGlassID.Left(5);
+	CString strGlassIDLevel8th = strGlassID.Left(8);
+ 
+	switch(sort)
+	{ 
+	case FTPCMD_AOI_IMAGE:
+		{
+			CTime time = m_tmFileCreateTime;
+
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0));  
+			
+			sprintf(pLocalPath, "%s%s", LOCAL_AOI_IMAGE_PATH, strGlassID.GetBuffer(0));  
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+		}
+		break;
+	case FTPCMD_REVIEW_IMAGE: 
+		{
+			CTime time = m_tmFileCreateTime;
+
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s%s", LOCAL_REV_IMAGE_PATH, strGlassID.GetBuffer(0));  
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+		}
+		break;
+	case FTPCMD_RAW:   
+		{
+			CTime time = m_tmFileCreateTime;
+			CString strFileName;//�뙆�씪�깮�꽦 �떆媛� �븣臾몄뿉 �뿬湲곗꽌 �젙�솗�븯寃� �뙆�씪紐� �떎�떆 �젙�젙
+			{
+				//Glass �젙蹂�
+				CTime CurrTime = m_tmFileCreateTime;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				strFileName.Format("%s_%s_%s.csv", pGlassData->m_strOperID, pGlassData->m_strGlassID, strTime.GetBuffer(0));
+			}
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Data", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+			
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+		}
+		break;
+	case FTPCMD_STACK:
+		{
+// 			CTime time = pGlassData->m_tmGlassLoading;
+// 			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Data", m_StackResult.getStackEquipID(), time.GetYear(), time.GetMonth(), time.GetDay(), 
+// 				strGlassIDLevel5th.GetBuffer(0), 
+// 				strGlassIDLevel8th.GetBuffer(0),
+// 				strGlassID.GetBuffer(0)); 
+// 
+// 			//媛��옣 理쒓렐嫄� 李얠븘�빞 �븯�굹? [源��깭�쁽 2019/1/12]
+// 			sprintf(pServerFile, "%s_%s_*.csv", 
+// 				m_StackResult.getStackOperID(), 
+// 				pGlassData->m_strGlassID); 
+// 
+// 			sprintf(pLocalPath, "%s", m_StackResult.getStackLocalPath()); 
+// 			sprintf(pLocalFile, "%s.txt", strGlassID.GetBuffer(0)); 
+		}
+		break;
+	case FTPCMD_MURA_IMAGE: 
+		{
+			CTime time = m_tmFileCreateTime;
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s%s", LOCAL_MURA_IMAGE_PATH, strGlassID.GetBuffer(0)); 
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*"); 
+		}
+		break;
+	case FTPCMD_INDEX:
+		{
+			CTime time = m_tmFileCreateTime;
+			sprintf(pServerPath, "INDEX\\%s", pGlassData->m_strEquipID);
+			sprintf(pServerFile, "%04d%02d%02d_%s.csv", time.GetYear(), time.GetMonth(), time.GetDay(),	pGlassData->m_strStepID); 
+
+			sprintf(pLocalPath, "%s", LOCAL_INDEX_PATH); 
+			sprintf(pLocalFile, "%s", pServerFile); 
+		}
+		break;
+
+	case FTPCMD_LINK:   
+		{ 
+			CTime time = m_tmFileCreateTime;
+			CString strFileName;//�뙆�씪�깮�꽦 �떆媛� �븣臾몄뿉 �뿬湲곗꽌 �젙�솗�븯寃� �뙆�씪紐� �떎�떆 �젙�젙
+			{
+				//Glass �젙蹂�
+				CTime CurrTime = m_tmFileCreateTime;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				strFileName.Format("%s_%s_%s.csv", pGlassData->m_strOperID, pGlassData->m_strGlassID, strTime.GetBuffer(0));
+			}
+			sprintf(pServerPath, "%s\\%s\\%s\\%s\\%s", "LINK", pGlassData->m_strEquipID, 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+		}
+		break;
+	} 
+
+
+}
+ 
+
+
+CString CGlassRawDemo::GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam)
+{  
+	CString sStr;
+	switch(nDefectInfoType)
+	{
+	case DMT_DefectJudge:// Judge
+		{
+			switch(nParam)
+			{
+			case 0:			sStr.Format("O");		
+				break; 
+			default:				sStr.Format("O");//sStr.Format("Ets");		
+				break;
+			}
+		}
+		break;
+
+	case DMT_DefectSizeType: 
+		{
+			sStr = "S";
+			switch(nParam)
+			{
+				//case SizeType_Unknown:	 sStr.Format("U");	break; 
+			case 1/*SizeType_Small*/:	 sStr.Format("S");
+				break; 
+			case 2/*SizeType_Mid*/:		 sStr.Format("M");
+				break; 
+			case 3/*SizeType_Large*/:	 sStr.Format("L");
+				break; 
+			case 4/*SizeType_Huge*/:		 sStr.Format("O");
+				break;
+				//case SizeType_Ultra:	 sStr.Format("Ultra");		break;
+				//default:				 sStr.Format("Ets");		break;
+			}
+		}
+		break;
+
+
+	}
+	return sStr;
+}
diff --git a/ReviewHistory/ReveiwHistory/GlassRawDemo.h b/ReviewHistory/ReveiwHistory/GlassRawDemo.h
new file mode 100644
index 0000000..cadcbbf
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawDemo.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include "GlassRawBase.h"
+#include "GlassRawRTMS.h"
+//#include "StackResultCSOT.h"
+#include "MacroResultFile.h"
+#include "CustomizeReview.h"
+#include "InterfaceFTP.h"
+
+class CGlassRawDemo : public CGlassRawBase, public CInterfaceFTP
+{
+public:
+	enum emDefectMemberType
+	{
+		DMT_DefectJudge = 0,
+		DMT_DefectSizeType
+	}; 
+
+public:
+	CGlassRawDemo(void);
+	~CGlassRawDemo(void);
+
+	static char* GetClassName(){return "Demo#1";};
+
+	virtual BOOL SequenceGlassLoading(CgrmGlassRawData* pData);
+	virtual BOOL SequenceInspectEnd(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewStart(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewEnd(CgrmGlassRawData* pData);
+
+	virtual BOOL WriteAOIFile(CgrmGlassRawData* pData);
+	virtual BOOL ReadAOIFile(CgrmGlassRawData* pData){return TRUE;};
+
+	virtual BOOL SequenceFtpUpload(char* pRawFileName);
+
+	virtual void NotifyUpdateOptionInfo(){/*m_StackResult.readOptionFile();*/};
+
+	
+	
+	virtual void SendMessageFTPUploadRaw(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPDownloadStack(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPUploadImage(_grmGlassData* pGlassData, emFTPCommand sort); 
+	virtual BOOL SendMessageFTPUploadIndexFile(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPUploadLinkFile(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData);
+	virtual void GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, _grmGlassData* pGlassData); 
+
+
+	BOOL ReadMuraFile(CgrmGlassRawData* pData);
+	BOOL MakeAOIFile(CgrmGlassRawData* pData);
+	BOOL MakeAnaFile(CgrmGlassRawData* pData);
+	BOOL WriteIndexFile(_grmGlassData* pGlassData);
+	
+	void makeDataHeader(CString& strLine, _grmGlassData* pGlassData);
+	void makeDataGlass(CString& strLine, _grmGlassData* pGlassData);
+	void makeDataBlock(CString& strLine, _grmBlockData* pBlockData);
+	void makeDataCell(CString& strLine, CgrmGlassRawData* pData, _grmCellData* pCellData);
+	BOOL makeDataDefect(CString& strLine, CgrmGlassRawData* pData, _grmDefectData* pDefectData);
+ 
+	CString GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam);
+
+public:
+	void SetEquipType(int nType){m_nEquipType = nType;};
+
+protected:
+	int m_nEquipType; // 0:Inline, 1:Offline
+
+	CGlassRawRTMS	m_GlassRawRTMS;//RTMS용 결과파일 생성관리 [김태현 2018/12/5]
+	CMacroResultFile m_MuraResultFile; //무라용 결과파일 생성관리 [김태현 2018/12/5]
+	
+	CTime	m_tmReviewStart;		
+	CTime	m_tmReviewEnd;		
+};
diff --git a/ReviewHistory/ReveiwHistory/GlassRawRTMS.cpp b/ReviewHistory/ReveiwHistory/GlassRawRTMS.cpp
new file mode 100644
index 0000000..f286af8
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawRTMS.cpp
@@ -0,0 +1,849 @@
+#include "StdAfx.h"
+#include "GlassRawRTMS.h"
+#include "akLoggerExt.h"
+#include "GlassRawCSOT.h"
+#include "MacroResultFile.h"
+
+#define RTMSTEMPPATH _T("D:\\DitRtms\\Data\\TempFile\\")
+#define RTMSRAWPATH _T("D:\\DitRtms\\Data\\RawFile\\") 
+#define DEFECTPATH  _T("D:\\Image\\Defect")
+#define RTMSIMAGEPATH _T("D:\\DitRtms\\Data\\ReviewImage\\")
+
+char* g_pCellCode2 = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+
+//enum Judgement					{ Judge_OK = 0, Judge_RP, Judge_NG, Judge_TR, Judge_PR, Judge_PT, Judge_Review, Judge_RC, Judge_Size, Judge_VI, Judge_Rework, Judge_Unknown };//2016.07.13 LHS Judge_Size 추가
+//enum DefectLocation		{ DefectLoc_Pattern = 0, DefectLoc_Crack, DefectLoc_BM, DefectLoc_ASG, DefectLoc_PAD, DefectLoc_C2C, DefectLoc_EdgeLine, DefectLoc_Proj, DefectLoc_Chip, DefectLoc_Corner };
+//enum SERVER_DefectType			{ DefectType_TBlack = 0, DefectType_TWhite, DefectType_RBlack, DefectType_RWhite, DefectType_BBlack, DefectType_BWhite, DefectType_Unknown };
+//enum SERVER_DefectSubType		{ DefectSubType_Normal = 0, DefectSubType_MC, DefectSubType_Mask, DefectSubType_Common, DefectSubType_NoDefect };
+
+CGlassRawRTMS::CGlassRawRTMS(void)
+{
+}
+
+CGlassRawRTMS::~CGlassRawRTMS(void)
+{
+}
+
+BOOL CGlassRawRTMS::SequenceGlassLoading( CgrmGlassRawData* pData )
+{
+	return TRUE;
+}
+
+BOOL CGlassRawRTMS::SequenceInspectEnd( CgrmGlassRawData* pData )
+{
+	WriteAOIFile(pData);
+
+	return TRUE;
+}
+
+BOOL CGlassRawRTMS::SequenceReviewStart( CgrmGlassRawData* pData )
+{
+	return TRUE;
+}
+
+BOOL CGlassRawRTMS::SequenceReviewEnd( CgrmGlassRawData* pData )
+{
+	WriteAOIFile(pData);
+
+	return TRUE;
+}
+
+
+BOOL CGlassRawRTMS::WriteAOIFile( CgrmGlassRawData* pData )
+{
+	BOOL bResult = TRUE;
+
+	bResult &= MakeAOIPreProcessing(pData);
+	bResult &= MakeAOIFile(pData);
+	bResult &= CopyRTMSFiles(pData);
+
+	if(bResult)AKLOG("Write RTMS File Complete");
+	else AKLOG("Write RTMS File Fail");
+	return TRUE;
+}
+
+BOOL CGlassRawRTMS::MakeAOIFile( CgrmGlassRawData* pData )
+{
+	_grmGlassData* pGlass = pData->GetGlassData();
+
+	CString strFilePathName = m_strRTMSRAWFile;
+
+	FILE* pf = fopen(strFilePathName.GetBuffer(0), "w");
+	if(pf == NULL) return FALSE;
+
+
+
+	CString strLine;
+	//Glass
+	{
+		CString strItems = "ITEM,GLASSITEM,LOTITEM,LOT_ID,LOT_TYPE,STEP_ID,EQUIPMENT_ID,EQUIPMENT_UNIT,GLS_ID,SLOT_ID,GLS_JUDGE,GLS_GRADE,PRODUCT_ID,CASSETTE_ID,OPERATOR_ID,RECIPE_NAME,AUTO_MODE,PNL_ORIGIN,PROCESSING_TIME,START_TIME,END_TIME,CAMERA_CNT,SCAN_CNT,INSP_TACT, REVIEW_TACT, CIM_ONOFF,PROCESS_ID,PROD_TYPE,BATCHID,H_PANELID,E_PANELID,P_PANELID,COMP_COUNT,PPID";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+
+		makeDataGlass(strLine, pGlass);
+
+		fprintf(pf, "%s\n", strLine);
+	}
+	
+	//Cell
+	{												
+		CString strItems = "ITEM,CELLITEM,PANEL_ID,PANEL_GRADE,COORD_X,COORD_Y,CELL_SIZE_X,CELL_SIZE_Y,GATE_LINE,DATA_LINE,LAMP_GRAY_01,LAMP_GRAY_02,LAMP_GRAY_03,LAMP_GRAY_04";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+
+		for(int iCell = 0; iCell < pData->GetGlassData()->m_nCellNum; iCell++)
+		{
+			_grmCellData* pCell = pData->GetCellData(iCell);
+			makeDataCell(strLine, pGlass, pCell);		
+			fprintf(pf, "%s\n", strLine);
+		}
+		
+	}
+
+	//Defect
+	{																																																										// DEFECT_TYPE_3 빠짐								                                                                         // RTMS Defect 정보 추가 [ 21-03-08 KJG ]																																																																						
+		CString strItems = "ITEM,DEFITEM,POINT_NO,PANEL_ID,PR_X,PR_Y,PR_DATA,PR_GATE,SE_X,SE_Y,SE_DATA,SE_GATE,DEFECT_LAYER,DETECTED_AREA,DEFECT_SIZE_TYPE,DEFECT_SIZE_X,DEFECT_SIZE_Y,DEFECT_LENGTH,DEFECT_AREA,DEFECT_TYPE_1,DEFECT_TYPE_2,REPEAT_DEFECT,MASK_DEFECT,IMAGE_FILE1,IMAGE_FILE2,SCAN_NO,CAMERA_NO,RSCALE,SIZE_AREA,PEAK,REV_RESOLUTION,REV_CAMNUM,REV_MAG,DEFECT_CODE,DEFECT_GRADE,STACK_FLAG,STACK_COUNT,STACK_STEP,ZONE_NO,GRAY_MIN,GRAY_MAX,GRAY_AVG,R_GRAY_MIN,R_GRAY_MAX,R_GRAY_AVG";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+
+		for(int iDefect = 0; iDefect < pData->GetGlassData()->m_nDefectNum; iDefect++)
+		{
+			_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+			//210203 CJH - CutOff 대상 결과파일 작성 제외
+			if (pDefect->m_bDefectCutoff == TRUE) continue;
+
+			makeDataDefect(strLine, pData->GetGlassData(), pData->GetCellData(pDefect->m_nCellIdx), pDefect);
+			fprintf(pf, "%s\n", strLine);
+		}
+	}
+	
+	//Camera
+	{															
+		CString strItems = "ITEM,CAMERAITEM,SCAN_NO,CAMERA_NO,LAMP,MAX,AVG,MIN";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+
+		for(int iScan=0; iScan < pGlass->m_nScanNum; iScan++)
+		{
+			for(int iCam=0; iCam < pGlass->m_nCameraNum; iCam++)
+			{
+				makeDataCamera(strLine, pGlass, iCam, iScan);
+				fprintf(pf, "%s\n", strLine);
+			}
+		}	
+	}
+
+
+	//WSI									
+	{
+		CString strItems = "ITEM,WSIITEM,WSI_NO,TYPE,NAME,JUDGE,CELLID,COORD_X,COORD_Y,COORD_X2,COORD_Y2,IMG_FILE_2D,IMAGE_FILE_3D,WSI_RESOLUTION";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+
+		for(int iDefect = 0; iDefect < pGlass->m_nDefectNum; iDefect++)
+		{
+			_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+			if(pDefect->m_ReviewDefect.m_nWsi_Type == 2)
+			{
+				makeDataWSI(strLine, &pDefect->m_ReviewDefect);
+			fprintf(pf, "%s\n", strLine);
+		}
+		}
+	}	
+
+	//Mura
+	if(m_pMuraResultFile && m_pMuraResultFile->IsRead()) 
+	{
+		CString strItems = "ITEM,MURAITEM,DATE,TIME,DEFECTNO,RECIPE,GLASSID,CELLID,COORD_X1,COORD_Y1,COORD_PX1,COORD_PY1,NOMURA,SIZE_W,SIZE_L,SIZE_S,MAIN_TYPE,SUB_TYPE,PEAK,G_MIN,G_MAX,G_AVG,CAM,SCAN,PIXEL_PEAK,REGION,SIZE_T,PEAK_T,IMG_FILE_NAME";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+		
+		_MacroDefect* pMuraDefect;
+		int nSize = (int)m_pMuraResultFile->GetDefectNum();
+
+			for(int iMuraDefect=0; iMuraDefect < nSize; iMuraDefect++)
+			{
+				pMuraDefect =  m_pMuraResultFile->GetDefect(iMuraDefect);
+				makeMuraDefect(strLine, pMuraDefect);
+				fprintf(pf, "%s\n", strLine);
+			}
+
+	}
+
+	// Measure
+	if(0)
+	{
+		CString strItems = "ITEM,LOCITEM,MEASURE_NO,MEASURE_TYPE,MEASURE_NAME,CELL_ID,X_COORDINATE_1,Y_COORDINATE_1,X_COORDINATE_2,Y_COORDINATE_2,X_SHIFT,Y_SHIFT,IMAGENAME,SHIFTDIST,ACTIVETOSEALANT,SEALSIZE";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+
+		// 사용 안함
+	}
+
+	// User Review
+	{
+		CString strItems = "ITEM,USERREVITEM,USER_NO,PR_X,PR_Y,IMAGE_FILE_NAME,REV_RESOLUTION";
+		fprintf(pf, "%s\n", strItems.GetBuffer(0));
+
+		for(int iDefect = 0; iDefect < pGlass->m_nDefectNum; iDefect++)
+		{
+			_grmDefectData* pDefect = pData->GetDefectData(iDefect);
+			if(pDefect->m_ReviewDefect.m_nPlanType == ditRaw::RPT_User)
+			{
+				makeUserReview(strLine, &pDefect->m_ReviewDefect);
+			fprintf(pf, "%s\n", strLine);
+		}
+		}
+
+	}
+
+	fclose(pf);
+	return TRUE;
+}
+
+
+void CGlassRawRTMS::makeDataGlass( CString& strLine, _grmGlassData* pGlassData )
+{
+	strLine.Empty();
+
+	CString strValue;
+	CString strDiv = ",";
+	
+	strValue.Format("DATA");							// ITEM
+	strLine += strValue+strDiv;						 
+	strValue.Format("GLASSDATA");						// GLASSITEM
+	strLine += strValue+strDiv;
+	strValue.Format("LOTDATA");							// LOTITEM
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strLotID);		// LOT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("LOTTYPE");							// LOT_TYPE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strStepID);		// STEP_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strOperID);	// EQUIPMENT_ID		//210127 CJH - Equip ID <-> Oper ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strEquipID);	// EQUIPMENT_UNIT
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strGlassID);	// GLS_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strSLotID);		// SLOT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strGlassJudge);	// GLAS_JUDGE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strGlassCode);	//	GLS_GRADE or Glass Code		//**GRADE가 코드?
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strProductID);	// PRODUCDT_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strCSTID);		// CASSETTE_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strEPPID);		// OPERATOR_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pGlassData->m_strRecipeName);	// RECIPE_NAME
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "AUTO_MODE");					// AUTOMODE
+	strLine += strValue+strDiv;
+
+	if(pGlassData->m_nOriginDirection == 0)			strValue.Format("Left Top");		// PNL_ORIGIN
+	else if(pGlassData->m_nOriginDirection == 1)	strValue.Format("Right Top");
+	else if(pGlassData->m_nOriginDirection == 10)	strValue.Format("Left Bottom");
+	else											strValue.Format("Right Bottom");
+	strLine += strValue+strDiv;
+
+	strValue.Format("%s", "PROCESSING_TIME");			// PROCESSING_TIME
+	strLine += strValue+strDiv;
+	strValue.Format("%04d%02d%02d_%02d%02d%02d"			// START_TIME
+		,pGlassData->m_tmGlassLoading.GetYear()
+		,pGlassData->m_tmGlassLoading.GetMonth()
+		,pGlassData->m_tmGlassLoading.GetDay()
+		,pGlassData->m_tmGlassLoading.GetHour()
+		,pGlassData->m_tmGlassLoading.GetMinute()
+		,pGlassData->m_tmGlassLoading.GetSecond() );
+	strLine += strValue+strDiv;
+	strValue.Format("%04d%02d%02d_%02d%02d%02d"			// END_TIME
+		,pGlassData->m_tmInspectionEND.GetYear()
+		,pGlassData->m_tmInspectionEND.GetMonth()
+		,pGlassData->m_tmInspectionEND.GetDay()
+		,pGlassData->m_tmInspectionEND.GetHour()
+		,pGlassData->m_tmInspectionEND.GetMinute()
+		,pGlassData->m_tmInspectionEND.GetSecond() );
+	strLine += strValue+strDiv;
+
+	strValue.Format("%d", pGlassData->m_nCameraNum);	// CAMERA_CNT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nScanNum);		// SCAN_CNT
+	strLine += strValue+strDiv;
+
+	strValue.Format("%d", pGlassData->m_tmInspectionEND-pGlassData->m_tmGlassLoading);	// INSP_TACT
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_tmReviewEnd - pGlassData->m_tmReviewLoading);	// REVIEW_TACT
+	strLine += strValue + strDiv;
+
+	strValue.Format("%s", "CIM_ONOFF");
+	strLine += strValue + strDiv;											//	CIM_ONOFF -SM
+	//210128 CJH - RTMS SDC 물류데이터 추가
+	strValue.Format("%s", pGlassData->m_strProcessID);
+	strLine += strValue + strDiv;
+	strValue.Format("%s", pGlassData->m_strProdType);
+	strLine += strValue + strDiv;
+	CString strTemp;
+	strTemp = pGlassData->m_strGlassID;
+	strValue.Format("%s", strTemp.Left(6));
+	strLine += strValue + strDiv;
+	strValue.Format("%s", pGlassData->m_strGlassID);
+	strLine += strValue + strDiv;
+	strValue.Format("%s", pGlassData->m_strEPPID);
+	strLine += strValue + strDiv;
+	strValue.Format("%s", pGlassData->m_strPairHPanelID);
+	strLine += strValue + strDiv;
+	strValue.Format("%d", pGlassData->m_nCellNum);
+	strLine += strValue + strDiv;
+	strValue.Format("%s", pGlassData->m_strPPID);
+	strLine += strValue;
+
+}
+
+
+void CGlassRawRTMS::makeDataCell( CString& strLine, _grmGlassData* pGlassData, _grmCellData* pCellData )
+{
+	strLine.Empty();
+
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("DATA");						// ITEM
+	strLine += strValue+strDiv;
+	strValue.Format("CELLDATA");					// CELLITEM 
+	strLine += strValue+strDiv;
+	strValue.Format("%s",pCellData->m_strCellName);	// PANEL_ID
+	strLine += strValue+strDiv;
+	{
+		if(pCellData->m_nJudgement == Judge_OK) strValue = "Judge_OK";						// PANEL_GRADE										// PNL_GRADE
+		else if(pCellData->m_nJudgement == Judge_NG) strValue = "Judge_NG";
+		else if(pCellData->m_nJudgement == Judge_Rework) strValue = "Judge_Rework";
+		else if(pCellData->m_nJudgement == Judge_RP) strValue = "Judge_RP";
+		else if(pCellData->m_nJudgement == Judge_Review) strValue = "Judge_Review";
+		else if(pCellData->m_nJudgement == Judge_RC) strValue = "Judge_RC";		// 미처리
+		else if(pCellData->m_nJudgement == Judge_Size) strValue = "Judge_Size";	//skip
+		else if (pCellData->m_nJudgement == Judge_TR) strValue = "Judge_TR";
+		else if (pCellData->m_nJudgement == Judge_PR) strValue = "Judge_PR";
+		else strValue = "Judge_OK";										
+	}
+	strLine += strValue+strDiv;
+
+	strValue.Format("%d", pCellData->m_rectCellLeft);		// COORD_X
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellTop);		// COORD_Y
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellRight - pCellData->m_rectCellLeft);	// CELL_SIZE_X
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_rectCellBottom - pCellData->m_rectCellTop);	// CELL_SIZE_Y
+	strLine += strValue+strDiv;
+
+	strValue.Format("%d", pCellData->m_nGateNum); //	LN_GATE : Gate line 갯수
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pCellData->m_nDataNum); //	LN_DATA : Data line 갯수
+	strLine += strValue+strDiv;
+	
+	strValue.Format("LAMP_GRAY_01");	// LAMP_GRAY_01
+	strLine += strValue+strDiv;
+	strValue.Format("LAMP_GRAY_02");	// LAMP_GRAY_02
+	strLine += strValue+strDiv;
+	strValue.Format("LAMP_GRAY_03");	// LAMP_GRAY_03
+	strLine += strValue+strDiv;
+	strValue.Format("LAMP_GRAY_04");	// LAMP_GRAY_04
+	strLine += strValue+strDiv;
+	
+}
+
+void CGlassRawRTMS::makeDataDefect( CString& strLine, _grmGlassData* pGlassData, _grmCellData* pCellData, _grmDefectData* pDefectData )
+{
+	strLine.Empty();
+
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("DATA");							// ITEM
+	strLine += strValue+strDiv;
+	strValue.Format("DEFDATA");							// DEFITEM
+	strLine += strValue+strDiv;
+
+	strValue.Format("%d", pDefectData->m_nDefectID);	// POINT_NO
+	strLine += strValue+strDiv;
+	strValue.Format("%c%c", '0' + pDefectData->m_nCellIdx / 36, g_pCellCode2[pDefectData->m_nCellIdx % 36]);		// PANEL_ID
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMOriginX);	// PR_X
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMOriginY);	// PR_Y
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellData);	// PR_DATA
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellGate);	// PR_GATE
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMCenterAlignX);	// SE_X
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMCenterAlignY);	// SE_Y
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellData);		// SE_DATA
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCellGate);		// SE_GATE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "DEFECT_LAYER");					// DEFECT_LAYER
+	strLine += strValue+strDiv;
+	{
+		int m_nDefectedArea = pDefectData->m_sDefectLoc;	// DEFECTED_AREA												//	DETECTED_AREA
+		if(m_nDefectedArea == DefectLoc_Pattern)	strValue = "PATTERN";													
+		else if(m_nDefectedArea == DefectLoc_Crack)	strValue = "CRACK";
+		else if(m_nDefectedArea == DefectLoc_BM)	strValue = "BM";
+		else if(m_nDefectedArea == DefectLoc_ASG)	strValue = "ASG";
+		else if(m_nDefectedArea == DefectLoc_PAD)	strValue = "PAD";
+		else if(m_nDefectedArea == DefectLoc_C2C)	strValue = "C2C";
+		else if(m_nDefectedArea == DefectLoc_EdgeLine)	strValue = "EdgeLine";
+		else if(m_nDefectedArea == DefectLoc_Proj)		strValue = "Proj";
+		else if(m_nDefectedArea == DefectLoc_Chip)		strValue = "Chip";
+		else if(m_nDefectedArea == DefectLoc_Corner)	strValue = "Corner";
+		else strValue = "";
+	}
+	strLine += strValue+strDiv;
+	{
+		int m_nDefectSizeType = pDefectData->m_DefectSizeType;	// DEFECT_SIZE_TYPE										//	DEFECT_SIZE_TYPE
+		if(m_nDefectSizeType == 0)		strValue = "S";
+		else if(m_nDefectSizeType == 1)	strValue = "M";
+		else if(m_nDefectSizeType == 2)	strValue = "L";
+		else if(m_nDefectSizeType == 3)	strValue = "H";
+		else if(m_nDefectSizeType == 4)	strValue = "U";
+		else							strValue = "S";
+	}
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMSizeX);			// DEFECT_SZE_X
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMSizeY);			// DEFECT_SIZE_Y
+	strLine += strValue+strDiv; 
+	
+	//strValue.Format("%s", "DEFECT_LENGTH");	// DEFECT_LENGTH
+	double dUmRscale = pDefectData->m_nDefectRScale * pDefectData->m_dScanResolution;
+	strValue.Format("%.2lf", dUmRscale);	// DEFECT_LENGTH
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nPixelSize);		// DEFECT_AREA
+	strLine += strValue+strDiv;
+	{
+		int m_nDefectType1 = pDefectData->m_DefectBDType;	// DEFECT_TYPE_1 (B, W, Unknown)
+		if(m_nDefectType1==DefectType_TBlack || m_nDefectType1==DefectType_RBlack)			strValue = "B";
+		else if(m_nDefectType1==DefectType_TWhite || m_nDefectType1==DefectType_RWhite)		strValue = "W";
+		else																				strValue = "Unknown";
+	}
+	strLine += strValue+strDiv;
+	{
+		//	DEFECT_TYPE_2 (Normal / MC / Mask / Common / NoDefect)
+		int m_nDefectType2 = pDefectData->m_DefectSubType;									
+
+		if(m_nDefectType2 == DefectSubType_Normal)			strValue = "Normal";														
+		else if(m_nDefectType2 == DefectSubType_MC)			strValue = "MC";
+		else if(m_nDefectType2 == DefectSubType_Mask)		strValue = "Mask";
+		else if(m_nDefectType2 == DefectSubType_Common)		strValue = "Common";
+		else if(m_nDefectType2 == DefectSubType_NoDefect)	strValue = "NoDefect";						
+		else												strValue = "UN";
+
+	}
+	strLine += strValue+strDiv;
+
+	{	
+		if(pDefectData->m_DefectSubType == DefectSubType_Common)	strValue = "Y";		//	REPEAT_DEFECT
+		else														strValue = "N";
+	}
+	strLine += strValue+strDiv;
+	{
+		if(pDefectData->m_DefectSubType == DefectSubType_Mask)	strValue = "Y";			//	MASK_DEFECT
+		else													strValue = "N";
+	}
+	strLine += strValue+strDiv;
+
+	strValue.Format("%s", pDefectData->m_strAoiImageName);						// IMAGE_FILE1
+	strLine += strValue+strDiv;
+
+	strValue.Format("%s", pDefectData->m_ReviewDefect.m_strRevImageName);		// IMAGE_FILE2
+	strLine += strValue+strDiv;
+
+	strValue.Format("%d", pDefectData->m_nScanIdx);			// SCAN_NO
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nCameraID);		// CAMERA_NO
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nDefectRScale);	// RSCALE
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_nUMSize);			// SIZE_AREA
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pDefectData->m_sDefectPeak);		// PEAK
+	strLine += strValue+strDiv;
+
+	float fReviewResol = 0.1725; //20배 단배율 // 3.45/20
+	strValue.Format("%.4lf", fReviewResol);				// REV_RESOLUTION
+	strLine += strValue+strDiv;
+
+	//210128 CJH - RTMS Review 정보 추가
+	if (strlen(pDefectData->m_ReviewDefect.m_strRevImageName))
+	{
+		strValue.Format("%d", pDefectData->m_ReviewDefect.m_nModuleIndex);				// REV_Cam Number
+		strLine += strValue + strDiv;
+	}
+	else
+	{
+		strValue.Format("-1");
+		strLine += strValue + strDiv;
+	}
+	
+	strValue.Format("%d", 20);				// REV_Magnification
+	strLine += strValue + strDiv;
+
+	strValue.Format("%s", pDefectData->m_strDefectCode); 	// DEFECT_CODE, DEFECT_GRADE, STACK_FLAG, STACK_COUNT, STACK_STEP, ZONE_NO, GRAY_MIN, ...,R_SRC_AVG  추가 [ 21-03-08 KJG ] 			
+	strLine += strValue + strDiv; // DEFECT_CODE
+
+	strValue.Format("%s", GetDefectInfoToString(DMT_DefectJudge, pDefectData->m_DefectJudgement));	
+	strLine += strValue + strDiv; // DEFECT_GRADE		
+
+	int nStackFlag = pDefectData->m_StackInfo;							// STACK_FLAG														
+	if (nStackFlag == Stack_Unknown)			strValue = "UK";
+	else if (nStackFlag == Stack_TD)			strValue = "TD";
+	else if (nStackFlag == Stack_SD)			strValue = "SD";
+	else if (nStackFlag == Stack_PD)			strValue = "PD";
+	else if (nStackFlag == Stack_SP)			strValue = "SP";
+	else										strValue = "UK";
+
+	strLine += strValue + strDiv;  
+
+	strValue.Format("%2d", pDefectData->m_nStackStepCount);				// STACK_COUNT
+	strLine += strValue + strDiv;
+
+	if (strlen(pDefectData->m_strStackFirst))                          // STACK_STEP
+	{
+		strValue.Format("%s", pDefectData->m_strStackFirst);
+		strValue.Replace(',', '_');  // 열 구분자가 ',' 이므로 '_'로 변경 [ 21-03-15 KJG ] 
+		strLine += strValue + strDiv;
+	}
+	else
+	{
+		strValue.Format(" ");
+		strLine += strValue + strDiv;
+	}
+
+	int nValue = 0;                                                  // ZONE_NO
+	for (int i = 15; i >= 0; i--)
+	{
+		if (pDefectData->m_sZonePixelCount[i] > 0)
+			nValue += 1;
+		if (i > 0)
+			nValue = nValue << 1;
+	}
+	strValue.Format("%04X", nValue);
+	strLine += strValue + strDiv;
+	
+	strValue.Format("%d", pDefectData->m_nLevelSrcMin);				// GRAY_MIN
+	strLine += strValue + strDiv;
+
+	strValue.Format("%d", pDefectData->m_nLevelSrcMax);				// GRAY_MAX
+	strLine += strValue + strDiv;
+
+	strValue.Format("%d", pDefectData->m_nLevelSrcAvg);				// GRAY_AVG
+	strLine += strValue + strDiv;
+	
+	strValue.Format("%d", pDefectData->m_nLevelRefMin);				// R_SRC_MIN
+	strLine += strValue + strDiv;
+
+	strValue.Format("%d", pDefectData->m_nLevelRefMax);				// R_SRC_MAX
+	strLine += strValue + strDiv;
+
+	strValue.Format("%d", pDefectData->m_nLevelRefAvg);				// R_SRC_AVG
+	strLine += strValue + strDiv;
+
+}
+
+void CGlassRawRTMS::makeDataCamera( CString& strLine, _grmGlassData* pGlassData, int nCamIdx, int nScanIdx )
+{
+	strLine.Empty();
+
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("DATA");
+	strLine += strValue+strDiv;
+	strValue.Format("CAMERADATA");
+	strLine += strValue+strDiv;
+
+	strValue.Format("%d", nScanIdx);
+	strLine += strValue+strDiv;
+	strValue.Format("%d", nCamIdx);
+	strLine += strValue+strDiv;
+	strValue.Format("LAMP");
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nGrayLevelMax[pGlassData->m_nCameraNum*nScanIdx + nCamIdx]);
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nGrayLevelAvg[pGlassData->m_nCameraNum*nScanIdx + nCamIdx]);
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pGlassData->m_nGrayLevelMin[pGlassData->m_nCameraNum*nScanIdx + nCamIdx]);
+	strLine += strValue+strDiv;
+}
+
+void CGlassRawRTMS::makeDataWSI( CString& strLine, _grmDefectReviewData* pWSIData )
+{
+	strLine.Empty();
+
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("DATA");						// ITEM
+	strLine += strValue+strDiv;
+	strValue.Format("WSIDATA");					// USERREVITEM
+	strLine += strValue+strDiv;
+	strValue.Format("%s","USER_NO");			// USER_NO
+	strLine += strValue+strDiv;
+
+	// 주석 처리 부분 데이터 들어오면 쓸 것
+	//CString strWSIType;
+	//if (pWSIData->m_fWsi_ResultData[0] == 1)
+	//	strWSIType.Format("%s", "Positive");	// 돌기
+	//else if (pWSIData->m_fWsi_ResultData[0] == 0)
+	//	strWSIType.Format("%s", "Negative");	// 함몰
+	//else
+	//	strWSIType.Format("%s", "Flat");
+	//strValue.Format("%s",strWSIType);					// TYPE 
+
+	strValue.Format("%s","TYPE");					// TYPE
+
+	strLine += strValue+strDiv;
+	//strValue.Format("%d", pWSIData->m_nWsi_Type);		// WSI_NAME
+	strValue.Format("%s", "WSI_NAME");		// WSI_NAME
+
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "JUDGE");			// JUDGE
+	strLine += strValue+strDiv;
+	//strValue.Format("%d", pWSIData->m_fWsi_ResultData[2]);		// COORD_X??
+	strValue.Format("%s", "COORD_X");		// COORD_X??
+	strLine += strValue+strDiv;
+	//strValue.Format("%d", pWSIData->m_fWsi_ResultData[1]);		// COORD_Y??
+	strValue.Format("%s", "COORD_Y");		// COORD_Y??
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "COORD_X2");		// COORD_X2
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "COORD_Y2");		// COORD_Y2
+	strLine += strValue+strDiv;
+	//strValue.Format("%s", pWSIData->m_strWsi_2DImageFilename);		// IMAGE_FILE_2D
+	strValue.Format("%s", "IMAGE_FILE_2D");		// IMAGE_FILE_2D
+	strLine += strValue+strDiv;
+	//strValue.Format("%s", pWSIData->m_strWsi_3DImageFilename);		// IMAGE_FILE_3D
+	strValue.Format("%s", "IMAGE_FILE_3D");		// IMAGE_FILE_3D
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "WSI_RESOLUTION");		// WSI_RESOLUTION
+	strLine += strValue+strDiv;
+
+}
+
+void CGlassRawRTMS::makeMuraDefect( CString& strLine, _MacroDefect* pMuraData )
+{
+	strLine.Empty();
+
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("DATA");							// ITEM
+	strLine += strValue+strDiv;
+	strValue.Format("MURADATA");						// DEFITEM
+	strLine += strValue+strDiv;
+
+	CTime time = CTime::GetCurrentTime();
+	strValue.Format("%04d%02d%02d", time.GetYear(), time.GetMonth(), time.GetDay());		// DATE
+	strLine += strValue+strDiv;
+	strValue.Format("%02d%02d%02d", time.GetHour(), time.GetMinute(), time.GetSecond()); // TIME
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->DEFECTNO);	// DEFECTNO
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "RECIPE");			// RECIPE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "GLASSID");			// GLASSID
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pMuraData->CELLID);	// CELLID
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->COORD_X1);	// COORD_X1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->COORD_Y1);	// COORD_Y1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->COORD_PX1);// COORD_PX1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->COORD_PY1); // COORD_PY1
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->NOMURA);	// NOMURA
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->SIZE_W);	// SIZE_W
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->SIZE_L);	// SIZE_L
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->SIZE_S);	// SIZE_S
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pMuraData->MAIN_TYPE);	// MAIN_TYPE
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pMuraData->SUB_TYPE);	// SUB_TYPE
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->PEAK);		// PEAK
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->G_MIN);	// G_MIN
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->G_MAX);	// G_MAX
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->G_AVG);	// G_AVG
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->CAM);		// CAM
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->SCAN);		// SCAN
+	strLine += strValue+strDiv;
+	strValue.Format("%d", pMuraData->PIXEL_PEAK);	// PIXEL_PEAK
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pMuraData->REGION);	//REGION
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pMuraData->SIZE_T);	// SIZE_T
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pMuraData->PEAK_T);	// PEAK_T
+	strLine += strValue+strDiv;
+	strValue.Format("%s", pMuraData->IMG_FILE_NAME);	// IMG_FILE_NAME
+	strLine += strValue+strDiv;
+}
+
+void CGlassRawRTMS::makeUserReview( CString& strLine, _grmDefectReviewData* pUserReview )
+{
+	strLine.Empty();
+
+	CString strValue;
+	CString strDiv = ",";
+
+	strValue.Format("DATA");						// ITEM
+	strLine += strValue+strDiv;
+	strValue.Format("USERREVDATA");					// USERREVITEM
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "USER_NO");				// USER_NO
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "PR_X");					// PR_X
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "PR_Y");					// PR_Y
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "IMAGE_FILE_NAME");		// IMAGE_FILE_NAME
+	strLine += strValue+strDiv;
+	strValue.Format("%s", "REV_RESOLUTION");		// REV_RESOLUTION
+	strLine += strValue+strDiv;
+
+}
+
+BOOL CGlassRawRTMS::MakeAOIPreProcessing(CgrmGlassRawData* pData)
+{
+	_grmGlassData* pGlass = pData->GetGlassData();
+
+	// File Path
+	CTime CurrTime = CTime::GetCurrentTime();
+	CString strTime=_T(""), strRTMSRAWFile=_T("");;
+	strTime.Format(_T("%04d%02d%02d%02d%02d%02d"), CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+	char strTempPath2[100] = {0, }, strTempPath3[100] = {0, };
+
+	CString strLotID = pGlass->m_strGlassID;
+	CString strRtmsOperID = pGlass->m_strOperID;
+	CString strRtmsEqID = pGlass->m_strEquipID;
+	CString strHGlassid = pGlass->m_strGlassID;
+	CString strStepID = pGlass->m_strStepID;
+	strHGlassid.MakeUpper();
+	strTime.MakeUpper();
+
+	strRTMSRAWFile.Format(_T("%s_%s.csv"), strHGlassid, strTime);
+
+	//파일 생성될 곳 폴더 생성 [김태현 2018/12/5]
+	//210126 CJH - RTMS 경로 변경 (126.100.100.5\\RawFile/ReviewImage).RawFile은 루트에 결과파일을 올리고 ReviewImage에는 StepID\\GlassID 안에 데이터 업로드
+	{
+		//210126 CJH - 경로 폴더생성 위치 변경
+		CreateDirectory("D:\\DitRtms", NULL);
+		CreateDirectory("D:\\DitRtms\\Data", NULL);
+
+		BOOL bCreateOK = TRUE;
+		sprintf(strTempPath2, "\\\\126.100.100.5\\RawFile");
+		bCreateOK &= CreateDirectory(strTempPath2, NULL);
+
+		sprintf(strTempPath2, "\\\\126.100.100.5\\RawFile\\%s", strRTMSRAWFile);
+
+
+		sprintf(strTempPath3, "\\\\126.100.100.5\\ReviewImage");
+		bCreateOK &= CreateDirectory(strTempPath3, NULL);
+
+		sprintf(strTempPath3, "\\\\126.100.100.5\\ReviewImage\\%s", strStepID);
+		bCreateOK &= CreateDirectory(strTempPath3, NULL);
+
+		sprintf(strTempPath3, "\\\\126.100.100.5\\ReviewImage\\%s\\%s", strStepID,strHGlassid);
+		bCreateOK &= CreateDirectory(strTempPath3, NULL);
+
+		AKLOG("RTMS Folder Raw File Path Make : %s", strTempPath2);
+		AKLOG("RTMS Folder Img Path Make : %s", strTempPath3);
+		//if(bCreateOK)	AKLOG("RTMS Folder Create Success");
+		//else			AKLOG("RTMS Folder Create Fail");
+	}
+
+	DeleteFile((LPCTSTR)strTempPath2);
+
+	m_strRTMSRAWFile = strTempPath2;
+	m_strRTMSImageFile = strTempPath3;
+
+	return TRUE;
+}
+
+BOOL CGlassRawRTMS::CopyRTMSFiles( CgrmGlassRawData* pData )
+{
+	return TRUE;
+}
+
+CString CGlassRawRTMS::GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam)
+{
+	CString sStr;
+	switch (nDefectInfoType)
+	{
+	case DMT_DefectJudge:// Judge
+	{
+		switch (nParam)
+		{
+		case Judge_OK:			sStr.Format("OK");
+			break;
+		case Judge_RP:			sStr.Format("RP");
+			break;
+		case Judge_NG:			sStr.Format("NG");
+			break;
+		case Judge_TR:			sStr.Format("TR");
+			break;
+		case Judge_PR:			sStr.Format("PR");
+			break;
+		case Judge_PT:			sStr.Format("PT");
+			break;
+		case Judge_Review:		sStr.Format("RV");
+			break;
+		case Judge_RC:			sStr.Format("RC");
+			break;
+		case Judge_Size:		sStr.Format("SZ");
+			break;
+		case Judge_VI:			sStr.Format("VI");
+			break;
+		case Judge_Rework:		sStr.Format("RW");
+			break;
+		case Judge_Unknown:		sStr.Format("OK");//sStr.Format("Unknown");	//Unknown도 일단 OK
+			break;
+		default:				sStr.Format("OK");//sStr.Format("Ets");		
+			break;
+		}
+	}
+	break;
+
+	case DMT_DefectSizeType:
+	{
+		sStr = "S";
+		switch (nParam)
+		{
+			//case SizeType_Unknown:	 sStr.Format("U");	break; 
+		case 1/*SizeType_Small*/:	 sStr.Format("S");
+			break;
+		case 2/*SizeType_Mid*/:		 sStr.Format("M");
+			break;
+		case 3/*SizeType_Large*/:	 sStr.Format("L");
+			break;
+		case 4/*SizeType_Huge*/:		 sStr.Format("O");
+			break;
+			//case SizeType_Ultra:	 sStr.Format("Ultra");		break;
+			//default:				 sStr.Format("Ets");		break;
+		}
+	}
+	break;
+
+
+	}
+	return sStr;
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/GlassRawRTMS.h b/ReviewHistory/ReveiwHistory/GlassRawRTMS.h
new file mode 100644
index 0000000..38d4caa
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/GlassRawRTMS.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "GlassRawBase.h"
+#include "MacroResultFile.h"
+
+class CGlassRawRTMS : public CGlassRawBase
+{
+public:
+	enum emDefectMemberType
+	{
+		DMT_DefectJudge = 0,
+		DMT_DefectSizeType
+	};
+
+	CGlassRawRTMS(void);
+	~CGlassRawRTMS(void);
+
+	static char* GetClassName(){return "RTMS";};
+
+	virtual BOOL SequenceGlassLoading(CgrmGlassRawData* pData);
+	virtual BOOL SequenceInspectEnd(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewStart(CgrmGlassRawData* pData);
+	virtual BOOL SequenceReviewEnd(CgrmGlassRawData* pData);
+
+	virtual BOOL WriteAOIFile(CgrmGlassRawData* pData);
+	virtual BOOL ReadAOIFile(CgrmGlassRawData* pData){return TRUE;};
+
+	BOOL MakeAOIFile(CgrmGlassRawData* pData);
+	BOOL CopyRTMSFiles(CgrmGlassRawData* pData);
+	BOOL MakeAOIPreProcessing(CgrmGlassRawData* pData);
+		
+	void SetMuraResult(CMacroResultFile* pMuraResult){m_pMuraResultFile = pMuraResult;};
+protected:
+	void makeDataGlass(CString& strLine, _grmGlassData* pGlassData);
+	void makeDataCell(CString& strLine, _grmGlassData* pGlassData, _grmCellData* pCellData);
+	void makeDataDefect(CString& strLine, _grmGlassData* pGlassData, _grmCellData* pCellData, _grmDefectData* pDefectData);
+	void makeDataCamera(CString& strLine, _grmGlassData* pGlassData, int nCamIdx, int nScanIdx);
+	void makeMuraDefect(CString& strLine, _MacroDefect* pMuraData);
+	void makeDataWSI(CString& strLine, _grmDefectReviewData* pWSIData);
+	void makeUserReview(CString& strLine, _grmDefectReviewData* pUserReviewData);
+	CString GetDefectInfoToString(emDefectMemberType nDefectInfoType, int nParam);
+
+protected:
+	CString m_strRTMSRAWFile;
+	CString m_strRTMSImageFile;
+
+	CMacroResultFile* m_pMuraResultFile;
+};
diff --git a/ReviewHistory/ReveiwHistory/InterfaceFTP.cpp b/ReviewHistory/ReveiwHistory/InterfaceFTP.cpp
new file mode 100644
index 0000000..f78e901
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/InterfaceFTP.cpp
@@ -0,0 +1,389 @@
+#include "StdAfx.h"
+#include "InterfaceFTP.h"
+#include "akLoggerExt.h"
+#include "akCore/akFileUtil.h"
+
+#define LOCAL_INDEX_PATH			"D:\\DIT_ResultData\\Index\\"	  
+#define LOCAL_REV_IMAGE_PATH		"D:\\ResultData\\Upload\\Image\\" 
+#define LOCAL_AOI_IMAGE_PATH		"D:\\Image\\Defect\\" 
+#define LOCAL_MURA_IMAGE_PATH		"D:\\DIT_ResultData\\Mura\\IMG\\" 
+#define LOCAL_DEEP_PATH				"D:\\DIT_ResultData\\Deeplearning\\"
+
+CInterfaceFTP::CInterfaceFTP(void)
+{
+	
+}
+
+CInterfaceFTP::~CInterfaceFTP(void)
+{
+}
+
+
+void CInterfaceFTP::SendMessageFTPUploadLinkFile( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_LINK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+
+}
+ 
+void CInterfaceFTP::SendMessageFTPUploadRaw( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_RAW, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+  
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+
+}
+
+void CInterfaceFTP::SendMessageFTPDownloadStack( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+	GetFormatDescription(FTPCMD_STACK, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_DownFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CInterfaceFTP::SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData )
+{
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPDownloader");
+	if(hWnd == NULL) return;
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	//GetFormatDescription(FTPCMD_DATAFILE, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+	{
+		CString strGlassIDOrg = pGlassData->m_strGlassID; 
+		CString strGlassID = strGlassIDOrg.Left(12);
+		sprintf(strServerFolder, "%s", pGlassData->m_strCassetteSequenceNo);
+		sprintf(strServerFile, "%s.dat", strGlassID.GetBuffer(0));  
+		sprintf(strLocalFolder,  "D:\\DIT_ResultData\\DownloadData"); 
+		sprintf(pLocalFile,  "%s.dat", strGlassID.GetBuffer(0)); 
+	}
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_DownFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawDownload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+
+void CInterfaceFTP::SendMessageFTPUploadImage( _grmGlassData* pGlassData, emFTPCommand sort)
+{  
+	if(pGlassData == NULL) return;
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return;
+ 
+	char strServerFolder[256] = {};
+	char strServerFile[32];// = "*.*";
+	char strLocalFolder[256] = {};
+	char strLocalFile[32];// = "*.*"; 
+
+	GetFormatDescription(sort, strServerFolder, strServerFile, strLocalFolder, strLocalFile, pGlassData);
+   
+// 	if(0)//test 
+// 	{
+// 		sprintf(strServerFolder, "HDD1/DIT/TestC");
+// 	}
+ 
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				strLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;
+	upParam.m_nSendResultCode							= FALSE;
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload; //<--요건 나중에 구분
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+}
+  
+
+BOOL CInterfaceFTP::SendMessageFTPUploadIndexFile( _grmGlassData* pGlassData )
+{  
+	if(pGlassData == NULL) 
+		return FALSE;
+
+	HWND hWnd = ::FindWindow(NULL, "FTPUploader");
+	if(hWnd == NULL) return FALSE;
+
+
+	char strServerFolder[256] = {};
+	char strServerFile[256] = {};
+	char strLocalFolder[256] = {};
+	char pLocalFile[256] = {}; 
+
+	GetFormatDescription(FTPCMD_INDEX, strServerFolder, strServerFile, strLocalFolder, pLocalFile, pGlassData);
+
+
+	// 	if(0)//test 
+	// 	{
+	// 		sprintf(strServerFolder, "HDD1/DIT/TestC");
+	// 		ServerFile = "ftptestfile.txt";
+	// 
+	// 		sprintf(strLocalFolder, "D:");
+	// 		pLocalFile = "ftptestfile.txt";
+	// 	}
+
+
+	CFTPCopyDataParam upParam;
+	strcpy(upParam.m_strServer_FolderName,			strServerFolder);
+	strcpy(upParam.m_strServer_FileName,			strServerFile);
+	strcpy(upParam.m_strLocal_FolderName,			strLocalFolder);
+	strcpy(upParam.m_strLocal_FileName,				pLocalFile);
+	strcpy(upParam.m_strServer_SignalFolderName,	"");
+	strcpy(upParam.m_strServer_SignalFileName,		"");
+	upParam.m_nCreateSignalFile							= FALSE;//m_ctrlCreateSignal.GetCheck();
+	upParam.m_nSendResultCode							= FALSE;//m_ctrlResultAck.GetCheck();
+	upParam.m_nProcessType								= CFTPCopyDataParam::FTPProcessType_UpFile;
+
+	COPYDATASTRUCT cds;
+	cds.dwData = CFTPCopyDataParam::FTPCopyDataCmd_RawUpload;
+	cds.cbData = sizeof(CFTPCopyDataParam);
+	cds.lpData = &upParam;
+
+	DWORD dwReturn = 0;
+	if(SendMessageTimeout(hWnd, WM_COPYDATA, NULL, (LPARAM)&cds, SMTO_NORMAL, 20000, (PDWORD_PTR)(dwReturn)) == FALSE)
+	{
+	}
+	return TRUE;
+}
+
+void CInterfaceFTP::GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, _grmGlassData* pGlassData)
+{ 
+	
+	CString strGlassIDOrg = pGlassData->m_strGlassID; 
+	CString strGlassID = strGlassIDOrg.Left(12);
+	CString strGlassIDLevel5th = strGlassID.Left(5);
+	CString strGlassIDLevel8th = strGlassID.Left(8);
+ 
+	switch(sort)
+	{ 
+	case FTPCMD_AOI_IMAGE:
+		{
+			CTime time = m_tmFileCreateTime;
+
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0));  
+			
+			sprintf(pLocalPath, "%s%s", LOCAL_AOI_IMAGE_PATH, strGlassID.GetBuffer(0));  
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+		}
+		break;
+	case FTPCMD_REVIEW_IMAGE: 
+		{
+			CTime time = m_tmFileCreateTime;
+
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s%s", LOCAL_REV_IMAGE_PATH, strGlassID.GetBuffer(0));  
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*");
+		}
+		break;
+	case FTPCMD_RAW:   
+		{
+			CTime time = m_tmFileCreateTime;
+			CString strFileName;//파일생성 시간 때문에 여기서 정확하게 파일명 다시 정정
+			{
+				//Glass 정보
+				CTime CurrTime = m_tmFileCreateTime;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				strFileName.Format("%s_%s_%s.csv", pGlassData->m_strOperID, pGlassData->m_strGlassID, strTime.GetBuffer(0));
+			}
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Data", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+			
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+		}
+		break;
+	case FTPCMD_STACK:
+		{
+// 			CTime time = pGlassData->m_tmGlassLoading;
+// 			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Data", m_StackResult.getStackEquipID(), time.GetYear(), time.GetMonth(), time.GetDay(), 
+// 				strGlassIDLevel5th.GetBuffer(0), 
+// 				strGlassIDLevel8th.GetBuffer(0),
+// 				strGlassID.GetBuffer(0)); 
+// 
+// 			//가장 최근걸 찾아야 하나? [김태현 2019/1/12]
+// 			sprintf(pServerFile, "%s_%s_*.csv", 
+// 				m_StackResult.getStackOperID(), 
+// 				pGlassData->m_strGlassID); 
+// 
+// 			sprintf(pLocalPath, "%s", m_StackResult.getStackLocalPath()); 
+// 			sprintf(pLocalFile, "%s.txt", strGlassID.GetBuffer(0)); 
+		}
+		break;
+	case FTPCMD_MURA_IMAGE: 
+		{
+			CTime time = m_tmFileCreateTime;
+			sprintf(pServerPath, "%s\\%04d%02d%02d\\%s\\%s\\%s\\Image", pGlassData->m_strEquipID, time.GetYear(), time.GetMonth(), time.GetDay(), 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s%s", LOCAL_MURA_IMAGE_PATH, strGlassID.GetBuffer(0)); 
+			strcpy(pServerFile, "*.*");
+			strcpy(pLocalFile, "*.*"); 
+		}
+		break;
+	case FTPCMD_INDEX:
+		{
+			CTime time = m_tmFileCreateTime;
+			sprintf(pServerPath, "INDEX\\%s", pGlassData->m_strEquipID);
+			sprintf(pServerFile, "%04d%02d%02d_%s.csv", time.GetYear(), time.GetMonth(), time.GetDay(),	pGlassData->m_strStepID); 
+
+			sprintf(pLocalPath, "%s", LOCAL_INDEX_PATH); 
+			sprintf(pLocalFile, "%s", pServerFile); 
+		}
+		break;
+
+	case FTPCMD_LINK:   
+		{ 
+			CTime time = m_tmFileCreateTime;
+			CString strFileName;//파일생성 시간 때문에 여기서 정확하게 파일명 다시 정정
+			{
+				//Glass 정보
+				CTime CurrTime = m_tmFileCreateTime;
+				CString strTime;
+				strTime.Format(_T("%04d%02d%02d_%02d%02d%02d"),
+					CurrTime.GetYear(), CurrTime.GetMonth(), CurrTime.GetDay(), CurrTime.GetHour(), CurrTime.GetMinute(), CurrTime.GetSecond());
+				strFileName.Format("%s_%s_%s.csv", pGlassData->m_strOperID, pGlassData->m_strGlassID, strTime.GetBuffer(0));
+			}
+			sprintf(pServerPath, "%s\\%s\\%s\\%s\\%s", "LINK", pGlassData->m_strEquipID, 
+				strGlassIDLevel5th.GetBuffer(0), 
+				strGlassIDLevel8th.GetBuffer(0),
+				strGlassID.GetBuffer(0)); 
+
+			sprintf(pLocalPath, "%s", pGlassData->m_strPath);
+
+			sprintf(pServerFile, "%s", strFileName.GetBuffer(0)); 
+			sprintf(pLocalFile, "%s", strFileName.GetBuffer(0)); 
+		}
+		break;
+	} 
+
+
+}
+ 
diff --git a/ReviewHistory/ReveiwHistory/InterfaceFTP.h b/ReviewHistory/ReveiwHistory/InterfaceFTP.h
new file mode 100644
index 0000000..22d10e1
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/InterfaceFTP.h
@@ -0,0 +1,100 @@
+#pragma once
+
+#include "GlassRawBase.h"
+
+class CInterfaceFTP
+{
+public:
+	enum emFTPCommand
+	{	
+		FTPCMD_REVIEW_IMAGE		=0,
+		FTPCMD_RAW				,
+		FTPCMD_INDEX				,
+		FTPCMD_AOI_IMAGE			,
+		FTPCMD_MURA_RAW			,
+		FTPCMD_MURA_IMAGE			,
+		FTPCMD_STACK				,
+		FTPCMD_LINK				,
+		FTPCMD_End
+	};
+
+public:
+	CInterfaceFTP(void);
+	~CInterfaceFTP(void);
+
+	virtual void SendMessageFTPUploadRaw(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPDownloadStack(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPUploadImage(_grmGlassData* pGlassData, emFTPCommand sort); 
+	virtual BOOL SendMessageFTPUploadIndexFile(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPUploadLinkFile(_grmGlassData* pGlassData);
+	virtual void SendMessageFTPDownloadDataFile( _grmGlassData* pGlassData);
+
+	virtual void GetFormatDescription(emFTPCommand sort, char* pServerPath, char* pServerFile, char* pLocalPath, char* pLocalFile, _grmGlassData* pGlassData); 
+ 
+public:
+	CTime m_tmFileCreateTime;
+};
+
+class CFTPCopyDataParam
+{
+public:
+	enum FTPProcessType { FTPProcessType_DownFile=0, FTPProcessType_UpFile, FTPProcessType_Count };
+	enum FTPDataSize { FTPDataSize_MaxPathNum=255, FTPDataSize_MaxFileNum=100 };
+	enum FTPCopyDataCmd { FTPCopyDataCmd_RawDownload=1,  FTPCopyDataCmd_RawUpload, FTPCopyDataCmd_LotUpload, FTPCopyDataCmd_ImageUpload };
+	enum FTPDataType { FTPDataType_Unknown = 0, FTPDataType_Raw, FTPDataType_Image, FTPDataType_Stack, FTPDataType_Index };
+
+public:
+	CFTPCopyDataParam()				{ Reset(); }
+	virtual ~CFTPCopyDataParam()	{ Reset(); }
+	void Reset()
+	{
+		memset(this, 0, sizeof(CFTPCopyDataParam));
+		m_hSenderWnd = GetCurrentProcessWndHandle();
+	}
+
+	const HWND	GetSenderWnd() const						{ return m_hSenderWnd; }
+	void		SetSenderWnd(HWND hWnd)						{ m_hSenderWnd = hWnd; }
+
+public:
+	int		m_nProcessType;								// 프로세스 타입
+	int 	m_nCreateSignalFile;						// 시그널 파일 생성유무
+	int		m_bFirstPriority;							// 최상위 우선순위유무
+	int		m_nSendResultCode;							// 보낸 결과 코드
+	// [C-PRJ] Image Upload Define - KHT (2020/11/19)
+	int		m_nDataType;								// 데이터 타입
+
+	TCHAR	m_strServer_FolderName[FTPDataSize_MaxPathNum];		// 서버 경로명
+	TCHAR	m_strServer_FileName[FTPDataSize_MaxFileNum];			// 서버 파일명
+
+	TCHAR	m_strLocal_FolderName[FTPDataSize_MaxPathNum];		// 로컬 경로명
+	TCHAR	m_strLocal_FileName[FTPDataSize_MaxFileNum];			// 로컬 파일명
+
+	TCHAR	m_strServer_SignalFolderName[FTPDataSize_MaxPathNum];	// 서버 시그널 경로명
+	TCHAR	m_strServer_SignalFileName[FTPDataSize_MaxFileNum];	// 서버 시그널 파일명
+
+	TCHAR	m_strRTMS_FileName[FTPDataSize_MaxFileNum];
+
+	TCHAR   m_strServer_SubFileName[FTPDataSize_MaxFileNum];  // 서버 로컬 경로내에 추가 Raw 파일 생성 이름
+	TCHAR   m_strServer_SubFilePath[FTPDataSize_MaxFileNum];  // 서버 로컬 경로내에 추가 Raw 파일 생성 경로
+
+protected:
+	HWND	m_hSenderWnd;								// 보낸 프로그램 윈도우
+
+	static HWND GetCurrentProcessWndHandle()
+	{
+		DWORD dwPID = GetCurrentProcessId();
+		HWND hWnd = FindWindow(NULL, NULL);
+		while (hWnd != NULL)
+		{
+			if (GetParent(hWnd) == NULL){
+				DWORD dwProcId;
+				GetWindowThreadProcessId(hWnd, &dwProcId);
+				if (dwPID == dwProcId){
+					return hWnd;
+				}
+			}
+			hWnd = GetWindow(hWnd, GW_HWNDNEXT);
+		}
+		return NULL;
+	}
+};
diff --git a/ReviewHistory/ReveiwHistory/MacroResultFile.cpp b/ReviewHistory/ReveiwHistory/MacroResultFile.cpp
new file mode 100644
index 0000000..a7caac2
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/MacroResultFile.cpp
@@ -0,0 +1,357 @@
+#include "StdAfx.h"
+#include "MacroResultFile.h"
+#include "akCore/akFileDB.h"
+//0404nwh
+#include "akGridData.h"  
+#include <process.h>
+#include "DitGlassRawClient.h"
+#include "GlassRawBase.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+CMacroResultFile::CMacroResultFile(void)
+{
+	m_bReadSuccess = FALSE;
+	readOptionFile();
+}
+
+CMacroResultFile::~CMacroResultFile(void)
+{
+	m_vecMacroDefect.clear();
+}
+
+BOOL CMacroResultFile::openFile( char* pFileName )
+{
+	m_bReadSuccess = FALSE;
+	FILE* pf = fopen(pFileName, "r");
+
+	if(pf == NULL)
+		return FALSE;
+
+	std::vector<_MacroDefect> vecMacroDefect;
+	_MacroDefect MacroDefect;
+	char buffer[1024];
+
+	char* pReadPoint = NULL;
+	char *pStr;
+
+	while(!feof(pf))
+	{
+		pStr = fgets(buffer, 1024, pf);
+		
+		if(!strncmp(buffer, "ITEM,", 5)) continue;
+
+		
+		if(strlen(buffer) <= 0 || pStr == NULL)
+			break;
+		
+		if(!strncmp(buffer, "DATA,CELLDATA", 13))//파싱 태현[2017/3/29]
+		{
+			//무라 셀판정도 반영 해야 하나?
+		}
+		else if(!strncmp(buffer, "DATA,DEFECTDATA", 15))//파싱 태현[2017/3/29]
+		{
+			pReadPoint = buffer;
+			
+			pReadPoint = getParsingData(pReadPoint, 15, &MacroDefect.ITEM		);
+			pReadPoint = getParsingData(pReadPoint, 8,	&MacroDefect.DEFECTNO	);
+			pReadPoint = getParsingData(pReadPoint, 20, &MacroDefect.CELLID		);
+			pReadPoint = getParsingData(pReadPoint, 8, 	&MacroDefect.COORD_X1	);
+			pReadPoint = getParsingData(pReadPoint, 8, 	&MacroDefect.COORD_Y1	);
+			pReadPoint = getParsingData(pReadPoint, 9, 	&MacroDefect.COORD_PX1	);
+			pReadPoint = getParsingData(pReadPoint, 9, 	&MacroDefect.COORD_PY1	);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.NOMURA		);
+			pReadPoint = getParsingData(pReadPoint, 8, 	&MacroDefect.JUDGE		);
+			pReadPoint = getParsingData(pReadPoint, 8, 	&MacroDefect.SIZE_W		);
+			pReadPoint = getParsingData(pReadPoint, 8, 	&MacroDefect.SIZE_L		);
+			pReadPoint = getParsingData(pReadPoint, 15, &MacroDefect.SIZE_S		);
+			pReadPoint = getParsingData(pReadPoint, 15, &MacroDefect.MAIN_TYPE	);
+			pReadPoint = getParsingData(pReadPoint, 15, &MacroDefect.SUB_TYPE	);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.PEAK		);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.G_MIN		);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.G_MAX		);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.G_AVG		);
+			pReadPoint = getParsingData(pReadPoint, 3, 	&MacroDefect.CAM		);
+			pReadPoint = getParsingData(pReadPoint, 4, 	&MacroDefect.SCAN		);
+			pReadPoint = getParsingData(pReadPoint, 10, &MacroDefect.PIXEL_PEAK	);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.REGION		);
+			pReadPoint = getParsingData(pReadPoint, 8, 	&MacroDefect.MASK_T		);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.SIZE_T		);
+			pReadPoint = getParsingData(pReadPoint, 6, 	&MacroDefect.PEAK_T		);
+			pReadPoint = getParsingData(pReadPoint, 69, &MacroDefect.IMG_FILE_NAME);
+			MacroDefect.IMG_FILE_NAME = MacroDefect.IMG_FILE_NAME.Left(70);
+			MacroDefect.IMG_FILE_NAME.Remove(' ');
+
+			vecMacroDefect.push_back(MacroDefect);
+		}
+	}
+
+	fclose(pf);
+
+	m_vecMacroDefect = vecMacroDefect;
+	//빠른 찾기용 map 생성
+	{
+		m_mapFind.clear();
+		int nSize = m_vecMacroDefect.size();
+		for(int i=0; i<nSize; i++)
+		{
+			m_mapFind.insert(std::make_pair(m_vecMacroDefect[i].COORD_X1, &m_vecMacroDefect[i]));
+		}
+	}
+	m_bReadSuccess = TRUE;
+	return TRUE;
+}
+
+char* CMacroResultFile::getParsingData( char* pBuf, int nLen, CString* pOutData )
+{
+	for(int i=nLen-1; i>=0; i--)
+	{
+		if(pBuf[i] != ' ')
+		{
+			pBuf[i+1] = 0;
+			break;
+		}
+	}
+	*pOutData = pBuf;
+
+	return &pBuf[nLen+1]; //구분자 건너 뛰어서 다음 읽을 포인트 넘겨준다 태현[2017/3/29]
+}
+
+char* CMacroResultFile::getParsingData( char* pBuf, int nLen, int* pOutData )
+{
+	pBuf[nLen] = 0;
+
+	*pOutData = atoi(pBuf);
+
+	return &pBuf[nLen+1]; //구분자 건너 뛰어서 다음 읽을 포인트 넘겨준다 태현[2017/3/29]
+}
+
+BOOL CMacroResultFile::readOptionFile( char* pFileName /*= "C:\\AOIServer\\ConfigFile\\MacroInfo.cfg"*/ )
+{
+	CakFileDB fileDB;
+	fileDB.openfile(pFileName);
+	char strTemp[256]={};
+	fileDB.getItem("MACROPATH_ENABLE", &m_bMacroResultFile, 0);
+	fileDB.getItem("MACROPATH_RAW", strTemp, ""); m_strMacroResultRawPath= strTemp;
+	fileDB.getItem("MACROPATH_IMAGE", strTemp, ""); m_strMacroResultImagePath= strTemp;
+	fileDB.getItem("SERVERPATH_RAW", strTemp, ""); m_strServerResultRawPath= strTemp;
+	fileDB.getItem("SERVERPATH_IMAGE", strTemp, "");m_strServerResultImagePath = strTemp;
+	fileDB.getItem("MACRO_READ_TIME", (int*)&m_dwMacroReadTime, 3000);
+
+	return TRUE;
+}
+
+int CMacroResultFile::GetDefectNum( int iCell )
+{
+	int nSize = (int)m_vecMacroDefect.size();
+	int nDefectNum = 0;
+	for(int i=0; i<nSize; i++)
+	{
+		if(m_vecMacroDefect[i].CELLID == iCell)
+		{
+			nDefectNum++;
+		}
+	}
+
+	return nDefectNum;
+}
+
+int CMacroResultFile::GetSubPanelNum(int iCell) //0404nwh
+{
+	int nSize = (int)m_vecMacroSubPanel.size();
+	int nSubPanelNum = 0;
+	for (int i = 0; i < nSize; i++)
+	{
+		if (m_vecMacroSubPanel[i].PRO_IMAGE == iCell)
+		{
+			nSubPanelNum++;
+		}
+	}
+	return nSubPanelNum;
+}
+
+//KMS - 190125 MuraDefect 찾기
+_MacroDefect* CMacroResultFile::FindDefect( int nX, int nY ,int nFindRange)
+{
+	_MacroDefect *pMDefect = NULL;
+	
+	std::multimap<int,_MacroDefect*>::iterator itLowerBound;
+	std::multimap<int,_MacroDefect*>::iterator itUpperBound;
+	
+	itLowerBound = m_mapFind.lower_bound(nX - nFindRange);
+	itUpperBound = m_mapFind.upper_bound(nX + nFindRange);
+	
+	_MacroDefect *pMDefectMin = NULL;
+	int nMinDistance = nFindRange*nFindRange;
+	int nDistance;
+	for (itLowerBound; itLowerBound != itUpperBound; itLowerBound++)
+	{
+		pMDefect = static_cast<_MacroDefect*>(itLowerBound->second);
+		if(!pMDefect)	continue;
+
+		if(abs(nY - pMDefect->COORD_Y1) < nFindRange)
+		{
+			nDistance = ((nX - pMDefect->COORD_X1) * (nX - pMDefect->COORD_X1)) + ((nY - pMDefect->COORD_Y1) * (nY - pMDefect->COORD_Y1));
+			if(nDistance < nMinDistance)
+			{
+				nMinDistance = nDistance;
+				pMDefectMin = pMDefect;
+			}
+		}
+	}
+
+	return pMDefectMin;
+}
+
+BOOL CMacroResultFile::openFile_Mura(char* pFileName)//0404nwh
+{
+	m_bReadSuccess = FALSE;
+	FILE* pf = fopen(pFileName, "r");
+
+	if (pf == NULL)
+		return FALSE;
+
+	CDitGlassRawClient	GlassRawClient;
+	GlassRawClient.ConnectServer();
+	CDitGlassRawClient* pShared = &GlassRawClient;
+
+	_grmCellData* pGrmMura;
+
+	std::vector<_MacroSubPanel> vecMacroSubPanel;
+	_MacroSubPanel MacroSubPanel;
+	char buffer[1024];
+	char* pReadPoint = NULL;
+	char *pStr;
+
+	CString stranelData = "DATA PANEL";
+	CString strSubPanelData = "DATA SUBPANEL";
+	CString strMaxAvgGray, strMaxPortion;
+
+	while (!feof(pf))
+	{
+		pStr = fgets(buffer, 1024, pf);		
+		if (strlen(buffer) <= 0 || pStr == NULL)
+			break;
+		
+		if (!strncmp(buffer, stranelData, strlen(stranelData)))// 띄어쓰기 파싱
+		{
+			CakParser paser;
+			if (strlen(buffer) <= 0) continue;
+			paser.process(buffer, " ");
+			int nTokNum = paser.getTokNum();
+			if (nTokNum < 42) continue;
+			strMaxAvgGray = paser.getTokStr(41);
+			strMaxPortion = paser.getTokStr(42);
+		}
+
+		if (!strncmp(buffer, strSubPanelData, strlen(strSubPanelData)))// 띄어쓰기 파싱
+		{
+			CakParser paser;
+			if (strlen(buffer) <= 0) continue;
+			paser.process(buffer, " ");
+			int nTokNum = paser.getTokNum();
+			if (nTokNum < 52) continue; //kyh 31->52
+			MacroSubPanel.PRO_IMAGE = paser.getTokStr(20);
+			MacroSubPanel.AVG_GRAY_0 = paser.getTokStr(21);
+			MacroSubPanel.PORTION_0 = paser.getTokStr(22);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_0 = paser.getTokStr(23);
+			MacroSubPanel.AVG_AMP_0 = paser.getTokStr(24);
+			MacroSubPanel.FFT_VAR_0 = paser.getTokStr(25);
+			MacroSubPanel.FFT_VAH_0 = paser.getTokStr(26);
+			MacroSubPanel.FFT_VAQ_0 = paser.getTokStr(27);
+			MacroSubPanel.FFT_PK_0 = paser.getTokStr(28);
+
+			MacroSubPanel.AVG_GRAY_1 = paser.getTokStr(29);
+			MacroSubPanel.PORTION_1 = paser.getTokStr(30);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_1 = paser.getTokStr(31);
+			MacroSubPanel.AVG_AMP_1 = paser.getTokStr(32);
+			MacroSubPanel.FFT_VAR_1 = paser.getTokStr(33);
+			MacroSubPanel.FFT_VAH_1 = paser.getTokStr(34);
+			MacroSubPanel.FFT_VAQ_1 = paser.getTokStr(35);
+			MacroSubPanel.FFT_PK_1 = paser.getTokStr(36);
+
+			MacroSubPanel.AVG_GRAY_2 = paser.getTokStr(37);
+			MacroSubPanel.PORTION_2 = paser.getTokStr(38);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_2 = paser.getTokStr(39);
+			MacroSubPanel.AVG_AMP_2 = paser.getTokStr(40);
+			MacroSubPanel.FFT_VAR_2 = paser.getTokStr(41);
+			MacroSubPanel.FFT_VAH_2 = paser.getTokStr(42);
+			MacroSubPanel.FFT_VAQ_2 = paser.getTokStr(43);
+			MacroSubPanel.FFT_PK_2 = paser.getTokStr(44);
+
+			MacroSubPanel.AVG_GRAY_3 = paser.getTokStr(45);
+			MacroSubPanel.PORTION_3 = paser.getTokStr(46);
+			//kyh 추가
+			MacroSubPanel.CORNER_GRAY_3 = paser.getTokStr(47);
+			MacroSubPanel.AVG_AMP_3 = paser.getTokStr(48);
+			MacroSubPanel.FFT_VAR_3 = paser.getTokStr(49);
+			MacroSubPanel.FFT_VAH_3 = paser.getTokStr(50);
+			MacroSubPanel.FFT_VAQ_3 = paser.getTokStr(51);
+			MacroSubPanel.FFT_PK_3 = paser.getTokStr(52);
+
+			vecMacroSubPanel.push_back(MacroSubPanel);
+		}
+	}
+
+	fclose(pf);
+
+	m_vecMacroSubPanel = vecMacroSubPanel;
+
+	for (int i = 0; i < m_vecMacroSubPanel.size(); i++)
+	{
+		pGrmMura= pShared->GetCellData(i);
+		
+		strcpy(pGrmMura->m_strProImage, m_vecMacroSubPanel[i].PRO_IMAGE.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgGray_0, m_vecMacroSubPanel[i].AVG_GRAY_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strPortion_0, m_vecMacroSubPanel[i].PORTION_0.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_0, m_vecMacroSubPanel[i].CORNER_GRAY_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_0, m_vecMacroSubPanel[i].AVG_AMP_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_0, m_vecMacroSubPanel[i].FFT_VAR_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_0, m_vecMacroSubPanel[i].FFT_VAH_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_0, m_vecMacroSubPanel[i].FFT_VAQ_0.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_0, m_vecMacroSubPanel[i].FFT_PK_0.GetBuffer(0));
+
+		strcpy(pGrmMura->m_strAvgGray_1, m_vecMacroSubPanel[i].AVG_GRAY_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strPortion_1, m_vecMacroSubPanel[i].PORTION_1.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_1, m_vecMacroSubPanel[i].CORNER_GRAY_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_1, m_vecMacroSubPanel[i].AVG_AMP_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_1, m_vecMacroSubPanel[i].FFT_VAR_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_1, m_vecMacroSubPanel[i].FFT_VAH_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_1, m_vecMacroSubPanel[i].FFT_VAQ_1.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_1, m_vecMacroSubPanel[i].FFT_PK_1.GetBuffer(0));
+
+		strcpy(pGrmMura->m_strAvgGray_2, m_vecMacroSubPanel[i].AVG_GRAY_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strPortion_2, m_vecMacroSubPanel[i].PORTION_2.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_2, m_vecMacroSubPanel[i].CORNER_GRAY_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_2, m_vecMacroSubPanel[i].AVG_AMP_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_2, m_vecMacroSubPanel[i].FFT_VAR_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_2, m_vecMacroSubPanel[i].FFT_VAH_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_2, m_vecMacroSubPanel[i].FFT_VAQ_2.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_2, m_vecMacroSubPanel[i].FFT_PK_2.GetBuffer(0));
+
+		strcpy(pGrmMura->m_strAvgGray_3, m_vecMacroSubPanel[i].AVG_GRAY_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strPortion_3, m_vecMacroSubPanel[i].PORTION_3.GetBuffer(0));
+		//kyh 0622
+		strcpy(pGrmMura->m_strCorner_Gray_3, m_vecMacroSubPanel[i].CORNER_GRAY_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strAvgAmp_3, m_vecMacroSubPanel[i].AVG_AMP_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVar_3, m_vecMacroSubPanel[i].FFT_VAR_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVah_3, m_vecMacroSubPanel[i].FFT_VAH_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTVaq_3, m_vecMacroSubPanel[i].FFT_VAQ_3.GetBuffer(0));
+		strcpy(pGrmMura->m_strFFTPK_3, m_vecMacroSubPanel[i].FFT_PK_3.GetBuffer(0));
+	}
+	strcpy(pShared->GetGlassData()->m_strMaxAvgGray, strMaxAvgGray.GetBuffer(0));
+	strcpy(pShared->GetGlassData()->m_strMaxPortion, strMaxPortion.GetBuffer(0));
+
+	m_bReadSuccess = TRUE;
+	return TRUE;
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/MacroResultFile.h b/ReviewHistory/ReveiwHistory/MacroResultFile.h
new file mode 100644
index 0000000..f746014
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/MacroResultFile.h
@@ -0,0 +1,231 @@
+#pragma once
+
+#include <vector>
+#include <map>
+/*
+ITEM	NAME	SIZE	DESCRIPTION
+DATE	DATE	8	검사 종료 일자
+TIME	TIME	6	검사 종료 시간
+DEFECT NO	DEFECTNO	8	결함 번호
+RECIPE NAME	RECIPE	20	검사 레시피 이름
+GLASSID	GLASSID	15	기판 ID
+CELLID	CELLID	16	결함 위치 CELL ID
+COORD X	COORD_X1	8	X좌표(결함 중심 좌표, 단위 : um)
+COORD Y	COORD_Y1	8	Y좌표(결함 중심 좌표, 단위 : um)
+NOMURA	NOMURA	6	비결함 여부(1 - 비결함, 0 - 유효결함)
+WIDTH	SIZE_W	8	결함 너비(X 길이, 단위 : um)
+LENGTH	SIZE_L	8	결함 높이(Y 길이, 단위 : um)
+SQUARE	SIZE_S	15	결함 크기(면적, 단위 : um²)
+MAIN TYPE	MAIN_TYPE	15	결함 타입(Area, VLineB, HLineB, SpotB, SpotW, NonFilling, NFGroup, OrangePeel, VLineW, HLineW, VLineF, HLineF, Depo)
+SUB TYPE	SUB_TYPE	15	검출 타입(Normal, Common, Mask, CommonMask)
+PEAK	PEAK	6	결함 피크 정보(단위 : DN)
+MIN	G_MIN	6	결함 영역 최소 밝기(단위 : DN)
+MAX	G_MAX	6	결함 영역 최대 밝기(단위 : DN)
+AVERAGE	G_AVG	6	결함 영역 평균 밝기(단위 : DN)
+CAM NO	CAM	3	검출 카메라 Index
+SCAN NO	SCAN	4	검출 스캔 Index
+PIXEL PEAK	PIXEL_PEAK	10	결함 픽셀 피크 정보(단위 : DN)
+REGION TYPE	REGION	6	검출 영역(Active, Pad)
+SIZE TYPE	SIZE_T	6	크기 타입(Small, Medium, Large, Huge)
+PEAK TYPE	PEAK_T	6	피크 타입(Pale, Medium, Deep, Over)
+IMAGE FILE NAME	IMG_FILE_NAME	50	결함별 이미지 파일 이름(셀번호.결함번호_일시.jpg)
+*/
+/* CSOT T4 IJP Type
+ITEM			Start	Length
+ITEM,DEFECTDATA	0		15
+DEFECTNO		17		8
+CELLID			26		20
+COORD_X1		47		8
+COORD_Y1		56		8
+COORD_PX1		65		9
+COORD_PY1		75		9
+NOMURA			85		6
+JUDGE			92		8
+SIZE_W			101		8
+SIZE_L			110		8
+SIZE_S			119		15
+MAIN_TYPE		135		15
+SUB_TYPE		151		15
+PEAK			167		6
+G_MIN			174		6
+G_MAX			181		6
+G_AVG			188		6
+CAM				195		3
+SCAN			199		4
+PIXEL_PEAK		204		10
+REGION			215		6
+MASK_T			222		8
+SIZE_T			231		6
+PEAK_T			238		6
+IMG_FILE_NAME	245		69
+*/
+struct _MacroDefect
+{
+	CString ITEM			;			
+	int		DEFECTNO		;		
+	CString CELLID			;			
+	int 	COORD_X1		;		
+	int 	COORD_Y1		;		
+	int 	COORD_PX1		;		
+	int 	COORD_PY1		;		
+	int 	NOMURA			;			
+	CString JUDGE			;
+	int		SIZE_W			;
+	int		SIZE_L			;
+	int		SIZE_S			;
+	CString	MAIN_TYPE		;
+	CString	SUB_TYPE		;
+	int		PEAK			;
+	int		G_MIN			;
+	int		G_MAX			;
+	int		G_AVG			;
+	int		CAM				;
+	int		SCAN			;
+	int		PIXEL_PEAK		;
+	CString	REGION			;
+	CString	MASK_T			;
+	CString	SIZE_T			;
+	CString	PEAK_T			;
+	CString	IMG_FILE_NAME	;
+	
+	_MacroDefect()
+	{
+		ITEM			= "0";
+		DEFECTNO		= 0;
+		CELLID			= "0";
+		COORD_X1		= 0;
+		COORD_Y1		= 0;
+		COORD_PX1		= 0;
+		COORD_PY1		= 0;
+		NOMURA			= 0;
+		JUDGE			= "0";
+		SIZE_W			= 0;
+		SIZE_L			= 0;
+		SIZE_S			= 0;
+		MAIN_TYPE		= "0";
+		SUB_TYPE		= "0";
+		PEAK			= 0;
+		G_MIN			= 0;
+		G_MAX			= 0;
+		G_AVG			= 0;
+		CAM				= 0;
+		SCAN			= 0;
+		PIXEL_PEAK		= 0;
+		REGION			= "0";
+		MASK_T			= "0";
+		SIZE_T			= "0";
+		PEAK_T			= "0";
+		IMG_FILE_NAME	= "0";
+
+	}
+};
+
+
+///0404nwh
+struct _MacroSubPanel
+{
+	CString	PRO_IMAGE;
+	CString	AVG_GRAY_0;  // 0 Scan 0 Model
+	CString	PORTION_0;
+	CString CORNER_GRAY_0; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_0;
+	CString FFT_VAR_0;
+	CString FFT_VAH_0;
+	CString FFT_VAQ_0;
+	CString FFT_PK_0; // kyh end
+	CString	AVG_GRAY_1; // 0 Scan 1 Model
+	CString	PORTION_1;
+	CString CORNER_GRAY_1; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_1;
+	CString FFT_VAR_1;
+	CString FFT_VAH_1;
+	CString FFT_VAQ_1;
+	CString FFT_PK_1; // kyh end
+	CString	AVG_GRAY_2; // 1 Scan 0 Model
+	CString	PORTION_2;
+	CString CORNER_GRAY_2; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_2;
+	CString FFT_VAR_2;
+	CString FFT_VAH_2;
+	CString FFT_VAQ_2;
+	CString FFT_PK_2; // kyh end
+	CString	AVG_GRAY_3; // 1 Scan 1 Model
+	CString	PORTION_3;
+	CString CORNER_GRAY_3; // kyh 결과파일 포맷 수정
+	CString AVG_AMP_3;
+	CString FFT_VAR_3;
+	CString FFT_VAH_3;
+	CString FFT_VAQ_3;
+	CString FFT_PK_3; // kyh end
+};
+
+class CMacroResultFile
+{
+public:
+	CMacroResultFile(void);
+	virtual ~CMacroResultFile(void);
+
+public:
+	BOOL openFile(char* pFileName);
+	BOOL openFile_Mura(char* pFileName);//nwh0404
+
+	BOOL IsRead() { return m_bReadSuccess; }
+	int GetDefectNum() { return (int)m_vecMacroDefect.size();}
+	int GetDefectNum(int iCell) ;
+	_MacroDefect* GetDefect(int i) { return &m_vecMacroDefect[i]; }
+
+	/////////////////////////////////////0404nwh
+	int GetSubPanelNum() { return (int)m_vecMacroSubPanel.size(); }
+	int GetSubPanelNum(int iCell);
+	_MacroSubPanel* GetSubPanel(int i) { return &m_vecMacroSubPanel[i]; }
+	/////////////////////////////////////0404nwh
+	BOOL readOptionFile(char* pFileName = "C:\\AOIServer\\ConfigFile\\MacroInfo.cfg");
+
+	_MacroDefect* FindDefect(int nX, int nY, int nFindRange = 2000/*um*/);
+public:
+	BOOL					m_bMacroResultFile;//마크로 설비 결과파일 통합 여부 태현[2017/3/29]
+	CString					m_strMacroResultRawPath;
+	CString					m_strMacroResultImagePath;
+	CString					m_strServerResultRawPath;
+	CString					m_strServerResultImagePath;
+
+	DWORD					m_dwMacroReadTime;
+
+protected:
+	char* getParsingData(char* pBuf, int nLen, CString* pOutData);
+	char* getParsingData(char* pBuf, int nLen, int* pOutData);
+
+protected:
+	BOOL m_bReadSuccess;
+	std::vector<_MacroDefect> m_vecMacroDefect;
+	std::vector<_MacroSubPanel> m_vecMacroSubPanel; //0404nwh
+
+	std::multimap<int,_MacroDefect*> m_mapFind;
+
+};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ReviewHistory/ReveiwHistory/PathSettingDlg.cpp b/ReviewHistory/ReveiwHistory/PathSettingDlg.cpp
new file mode 100644
index 0000000..d5f7424
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/PathSettingDlg.cpp
@@ -0,0 +1,297 @@
+癤�// PathSettingDlg.cpp: 援ы쁽 �뙆�씪
+//
+
+#include "stdafx.h"
+#include "ReveiwHistory.h"
+#include "PathSettingDlg.h"
+#include "afxdialogex.h"
+
+#define PathSettingFilePath	( _T("PathSetting.ini") )
+// CPathSettingDlg ���솕 �긽�옄
+
+IMPLEMENT_DYNAMIC(CPathSettingDlg, CDialogEx)
+
+CPathSettingDlg::CPathSettingDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_DLG_PATH_SETTING, pParent)
+{
+	m_strBinPath.Empty();
+	m_strInspectorPath.Empty();
+	m_strReviewPath.Empty();
+	m_strAlignPath.Empty();
+}
+
+CPathSettingDlg::~CPathSettingDlg()
+{
+}
+
+void CPathSettingDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+
+BEGIN_MESSAGE_MAP(CPathSettingDlg, CDialogEx)
+	ON_BN_CLICKED(IDC_BTN_BIN_PATH, &CPathSettingDlg::OnBnClickedBtnBinPath)
+	ON_BN_CLICKED(IDC_BTN_INSPECTOR_PATH, &CPathSettingDlg::OnBnClickedBtnInspectorPath)
+	ON_BN_CLICKED(IDC_BTN_REVIEW_PATH, &CPathSettingDlg::OnBnClickedBtnReviewPath)
+	ON_BN_CLICKED(IDC_BTN_ALIGN_PATH, &CPathSettingDlg::OnBnClickedBtnAlignPath)
+	ON_BN_CLICKED(IDC_BTN_SAVE, &CPathSettingDlg::OnBnClickedBtnSave)
+	ON_BN_CLICKED(IDCANCEL, &CPathSettingDlg::OnBnClickedCancel)
+END_MESSAGE_MAP()
+
+
+// CPathSettingDlg 硫붿떆吏� 泥섎━湲�
+BOOL CPathSettingDlg::Create(CWnd* pParentWnd)
+{
+	return CDialogEx::Create(IDD, pParentWnd);
+}
+
+BOOL CPathSettingDlg::PreTranslateMessage(MSG* pMsg)
+{
+	// TODO: �뿬湲곗뿉 �듅�닔�솕�맂 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯 �겢�옒�뒪瑜� �샇異쒗빀�땲�떎.
+	if (pMsg->message == WM_KEYDOWN)
+	{
+		if (pMsg->wParam == VK_ESCAPE)
+		{
+			ShowWindow(SW_HIDE);
+
+			return TRUE;
+		}
+	}
+
+	return __super::PreTranslateMessage(pMsg);
+}
+
+void CPathSettingDlg::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+}
+
+void CPathSettingDlg::OnShowWindow(BOOL bShow, UINT nStatus)
+{
+	__super::OnShowWindow(bShow, nStatus);
+
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	if (TRUE == bShow)
+	{
+	}
+}
+
+void CPathSettingDlg::OnBnClickedBtnBinPath()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	ITEMIDLIST *pidlBrowse;
+	CString strPath;
+
+	BROWSEINFO BrInfo;
+
+	BrInfo.hwndOwner = GetSafeHwnd();
+	BrInfo.pidlRoot = NULL;
+
+	memset(&BrInfo, 0, sizeof(BrInfo));
+	BrInfo.lpszTitle = _T("Please select a folder that contains Bin files");
+	BrInfo.ulFlags = BIF_RETURNONLYFSDIRS;
+	pidlBrowse = SHBrowseForFolder(&BrInfo);
+	TCHAR szPathName[200];
+
+	::SHGetPathFromIDList(pidlBrowse, szPathName);
+
+	CString strTmpPath = (LPCTSTR)szPathName;
+	CFileFind finder;
+	BOOL bFindPath = finder.FindFile(strTmpPath);
+
+	if (bFindPath)
+	{
+		SetDlgItemText(IDC_EDIT_BIN_PATH, strTmpPath);
+	}
+
+	LOG(Dbg, _T("[PathSetting] Bin Path Setting"));
+}
+
+
+void CPathSettingDlg::OnBnClickedBtnInspectorPath()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	ITEMIDLIST *pidlBrowse;
+	CString strPath;
+
+	BROWSEINFO BrInfo;
+
+	BrInfo.hwndOwner = GetSafeHwnd();
+	BrInfo.pidlRoot = NULL;
+
+	memset(&BrInfo, 0, sizeof(BrInfo));
+	BrInfo.lpszTitle = _T("Please select a folder that contains Inspector Image files");
+	BrInfo.ulFlags = BIF_RETURNONLYFSDIRS;
+	pidlBrowse = SHBrowseForFolder(&BrInfo);
+	TCHAR szPathName[200];
+
+	::SHGetPathFromIDList(pidlBrowse, szPathName);
+
+	CString strTmpPath = (LPCTSTR)szPathName;
+	CFileFind finder;
+	BOOL bFindPath = finder.FindFile(strTmpPath);
+
+	if (bFindPath)
+	{
+		SetDlgItemText(IDC_EDIT_INSPECTOR_PATH, strTmpPath);
+	}
+
+	LOG(Dbg, _T("[PathSetting] Align Inspector Setting"));
+}
+
+
+void CPathSettingDlg::OnBnClickedBtnReviewPath()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	ITEMIDLIST *pidlBrowse;
+	CString strPath;
+
+	BROWSEINFO BrInfo;
+
+	BrInfo.hwndOwner = GetSafeHwnd();
+	BrInfo.pidlRoot = NULL;
+
+	memset(&BrInfo, 0, sizeof(BrInfo));
+	BrInfo.lpszTitle = _T("Please select a folder that contains Review Image files");
+	BrInfo.ulFlags = BIF_RETURNONLYFSDIRS;
+	pidlBrowse = SHBrowseForFolder(&BrInfo);
+	TCHAR szPathName[200];
+
+	::SHGetPathFromIDList(pidlBrowse, szPathName);
+
+	CString strTmpPath = (LPCTSTR)szPathName;
+	CFileFind finder;
+	BOOL bFindPath = finder.FindFile(strTmpPath);
+
+	if (bFindPath)
+	{
+		SetDlgItemText(IDC_EDIT_REVIEW_PATH, strTmpPath);
+	}
+	LOG(Dbg, _T("[PathSetting] Review Path Setting"));
+}
+
+
+void CPathSettingDlg::OnBnClickedBtnAlignPath()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	ITEMIDLIST *pidlBrowse;
+	CString strPath;
+
+	BROWSEINFO BrInfo;
+
+	BrInfo.hwndOwner = GetSafeHwnd();
+	BrInfo.pidlRoot = NULL;
+
+	memset(&BrInfo, 0, sizeof(BrInfo));
+	BrInfo.lpszTitle = _T("Please select a folder that contains Align Image files");
+	BrInfo.ulFlags = BIF_RETURNONLYFSDIRS;
+	pidlBrowse = SHBrowseForFolder(&BrInfo);
+	TCHAR szPathName[200];
+
+	::SHGetPathFromIDList(pidlBrowse, szPathName);
+
+	CString strTmpPath = (LPCTSTR)szPathName;
+	CFileFind finder;
+	BOOL bFindPath = finder.FindFile(strTmpPath);
+
+	if (bFindPath)
+	{
+		SetDlgItemText(IDC_EDIT_ALIGN_PATH, strTmpPath);
+	}
+
+	LOG(Dbg, _T("[PathSetting] Align Path Setting"));
+}
+
+
+void CPathSettingDlg::OnBnClickedBtnSave()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CString strFilePath;
+	strFilePath.Format("%s\\Config\\%s", GetExePath(), PathSettingFilePath);
+
+	GetDlgItemText(IDC_EDIT_ALIGN_PATH, m_strAlignPath);
+	INIWriteStr("Path", "Align", m_strAlignPath, strFilePath);
+	GetDlgItemText(IDC_EDIT_BIN_PATH, m_strBinPath);
+	INIWriteStr("Path", "Bin", m_strBinPath, strFilePath);
+	GetDlgItemText(IDC_EDIT_INSPECTOR_PATH, m_strInspectorPath);
+	INIWriteStr("Path", "Inspector", m_strInspectorPath, strFilePath);
+	GetDlgItemText(IDC_EDIT_REVIEW_PATH, m_strReviewPath);
+	INIWriteStr("Path", "Review", m_strReviewPath, strFilePath);
+
+	AfxMessageBox(_T("���옣 �릺�뿀�뒿�땲�떎"), MB_OK | MB_ICONWARNING);
+
+	LOG(Dbg, _T("[PathSetting] PathSetting Save"));
+
+	ShowWindow(SW_HIDE);
+}
+
+void CPathSettingDlg::OnBnClickedCancel()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CString strTemp;
+	strTemp.Format(_T(""));
+
+	if (m_strAlignPath == "")
+	{
+		m_strAlignPath.Format(_T("D:\\ResultData\\Align\\"));
+	}
+	if (m_strBinPath == "")
+	{
+		m_strBinPath.Format(_T("D:\\DIT_ResultData\\RawBin\\"));
+	}
+	if (m_strInspectorPath == "")
+	{
+		m_strInspectorPath.Format(_T("\\\\126.100.100.1\\D\\Image\\Defect\\"));
+	}
+	if (m_strReviewPath == "")
+	{
+		m_strReviewPath.Format(_T("D:\\ResultData\\UploadImage\\"));
+	}
+
+	SetDlgItemText(IDC_EDIT_ALIGN_PATH, m_strAlignPath);
+	SetDlgItemText(IDC_EDIT_BIN_PATH, m_strBinPath);
+	SetDlgItemText(IDC_EDIT_INSPECTOR_PATH, m_strInspectorPath);
+	SetDlgItemText(IDC_EDIT_REVIEW_PATH, m_strReviewPath);
+
+	LOG(Dbg, _T("[PathSetting] PathSetting Cancel"));
+
+	ShowWindow(SW_HIDE);
+}
+
+void CPathSettingDlg::PathSettingLoad()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CString strFilePath;
+	strFilePath.Format(_T("%s\\Config\\%s"), GetExePath(), PathSettingFilePath);
+
+	CString strAppName = _T("Path");
+	m_strAlignPath = INIReadStr(strAppName, _T("Align"), strFilePath);
+	m_strBinPath = INIReadStr(strAppName, _T("Bin"), strFilePath);
+	m_strInspectorPath = INIReadStr(strAppName, _T("Inspector"), strFilePath);
+	m_strReviewPath = INIReadStr(strAppName, _T("Review"), strFilePath);
+
+	if (m_strAlignPath == "")
+	{
+		m_strAlignPath.Format(_T("D:\\ResultData\\Align\\"));
+	}
+	if (m_strBinPath == "")
+	{
+		m_strBinPath.Format(_T("D:\\DIT_ResultData\\RawBin\\"));
+	}
+	if (m_strInspectorPath == "")
+	{
+		m_strInspectorPath.Format(_T("\\\\126.100.100.1\\D\\Image\\Defect\\"));
+	}
+	if (m_strReviewPath == "")
+	{
+		m_strReviewPath.Format(_T("D:\\ResultData\\UploadImage\\"));
+	}
+
+	SetDlgItemText(IDC_EDIT_ALIGN_PATH, m_strAlignPath);
+	SetDlgItemText(IDC_EDIT_BIN_PATH, m_strBinPath);
+	SetDlgItemText(IDC_EDIT_INSPECTOR_PATH, m_strInspectorPath);
+	SetDlgItemText(IDC_EDIT_REVIEW_PATH, m_strReviewPath);
+
+	LOG(Dbg, _T("[PathSetting] Start Review Path Setting Load"));
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/PathSettingDlg.h b/ReviewHistory/ReveiwHistory/PathSettingDlg.h
new file mode 100644
index 0000000..f502ff2
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/PathSettingDlg.h
@@ -0,0 +1,47 @@
+癤�#pragma once
+#include "Singleton.h"
+
+// CPathSettingDlg ���솕 �긽�옄
+
+class CPathSettingDlg : public CDialogEx, public CSingleton< CPathSettingDlg >
+{
+	DECLARE_DYNAMIC(CPathSettingDlg)
+
+public:
+	CPathSettingDlg(CWnd* pParent = nullptr);   // �몴以� �깮�꽦�옄�엯�땲�떎.
+	virtual ~CPathSettingDlg();
+
+// ���솕 �긽�옄 �뜲�씠�꽣�엯�땲�떎.
+
+	enum { IDD = IDD_DLG_PATH_SETTING };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 吏��썝�엯�땲�떎.
+
+	CString m_strBinPath;
+	CString m_strInspectorPath;
+	CString m_strReviewPath;
+	CString m_strAlignPath;
+
+	DECLARE_MESSAGE_MAP()
+
+public:
+	virtual BOOL Create(CWnd* pParentWnd = NULL);
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+	afx_msg void OnDestroy();
+	afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+public:
+	afx_msg void OnBnClickedBtnBinPath();
+	afx_msg void OnBnClickedBtnInspectorPath();
+	afx_msg void OnBnClickedBtnReviewPath();
+	afx_msg void OnBnClickedBtnAlignPath();
+	afx_msg void OnBnClickedBtnSave();
+	afx_msg void OnBnClickedCancel();
+
+	void PathSettingLoad();
+	CString GetBinPath() { return m_strBinPath; }
+	CString GetInspectorPath() { return m_strInspectorPath; }
+	CString GetReviewPath() { return m_strReviewPath; }
+	CString GetAlignPath() { return m_strAlignPath; }
+};
diff --git a/ReviewHistory/ReveiwHistory/ReveiwHistory.cpp b/ReviewHistory/ReveiwHistory/ReveiwHistory.cpp
new file mode 100644
index 0000000..87e331d
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/ReveiwHistory.cpp
@@ -0,0 +1,106 @@
+癤�
+// ReveiwHistory.cpp: �쓳�슜 �봽濡쒓렇�옩�뿉 ���븳 �겢�옒�뒪 �룞�옉�쓣 �젙�쓽�빀�땲�떎.
+//
+
+#include "stdafx.h"
+#include "ReveiwHistory.h"
+#include "ReveiwHistoryDlg.h"
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+
+// CReveiwHistoryApp
+
+BEGIN_MESSAGE_MAP(CReveiwHistoryApp, CWinApp)
+	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
+END_MESSAGE_MAP()
+
+
+// CReveiwHistoryApp �깮�꽦
+
+CReveiwHistoryApp::CReveiwHistoryApp()
+{
+	// �떎�떆 �떆�옉 愿�由ъ옄 吏��썝
+	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;
+
+	// TODO: �뿬湲곗뿉 �깮�꽦 肄붾뱶瑜� 異붽��빀�땲�떎.
+	// InitInstance�뿉 紐⑤뱺 以묒슂�븳 珥덇린�솕 �옉�뾽�쓣 諛곗튂�빀�땲�떎.
+}
+
+
+// �쑀�씪�븳 CReveiwHistoryApp 媛쒖껜�엯�땲�떎.
+
+CReveiwHistoryApp theApp;
+
+
+// CReveiwHistoryApp 珥덇린�솕
+
+BOOL CReveiwHistoryApp::InitInstance()
+{
+	// �쓳�슜 �봽濡쒓렇�옩 留ㅻ땲�럹�뒪�듃媛� ComCtl32.dll 踰꾩쟾 6 �씠�긽�쓣 �궗�슜�븯�뿬 鍮꾩<�뼹 �뒪���씪�쓣
+	// �궗�슜�븯�룄濡� 吏��젙�븯�뒗 寃쎌슦, Windows XP �긽�뿉�꽌 諛섎뱶�떆 InitCommonControlsEx()媛� �븘�슂�빀�땲�떎.
+	// InitCommonControlsEx()瑜� �궗�슜�븯吏� �븡�쑝硫� 李쎌쓣 留뚮뱾 �닔 �뾾�뒿�땲�떎.
+	INITCOMMONCONTROLSEX InitCtrls;
+	InitCtrls.dwSize = sizeof(InitCtrls);
+	// �쓳�슜 �봽濡쒓렇�옩�뿉�꽌 �궗�슜�븷 紐⑤뱺 怨듭슜 而⑦듃濡� �겢�옒�뒪瑜� �룷�븿�븯�룄濡�
+	// �씠 �빆紐⑹쓣 �꽕�젙�븯�떗�떆�삤.
+	InitCtrls.dwICC = ICC_WIN95_CLASSES;
+	InitCommonControlsEx(&InitCtrls);
+
+	CWinApp::InitInstance();
+
+
+	AfxEnableControlContainer();
+
+	// ���솕 �긽�옄�뿉 �끂 �듃由� 酉� �삉�뒗
+	// �끂 紐⑸줉 酉� 而⑦듃濡ㅼ씠 �룷�븿�릺�뼱 �엳�뒗 寃쎌슦 �끂 愿�由ъ옄瑜� 留뚮벊�땲�떎.
+	CShellManager *pShellManager = new CShellManager;
+
+	// MFC 而⑦듃濡ㅼ쓽 �뀒留덈�� �궗�슜�븯湲� �쐞�빐 "Windows �썝�삎" 鍮꾩<�뼹 愿�由ъ옄 �솢�꽦�솕
+	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));
+
+	// �몴以� 珥덇린�솕
+	// �씠�뱾 湲곕뒫�쓣 �궗�슜�븯吏� �븡怨� 理쒖쥌 �떎�뻾 �뙆�씪�쓽 �겕湲곕�� 以꾩씠�젮硫�
+	// �븘�옒�뿉�꽌 �븘�슂 �뾾�뒗 �듅�젙 珥덇린�솕
+	// 猷⑦떞�쓣 �젣嫄고빐�빞 �빀�땲�떎.
+	// �빐�떦 �꽕�젙�씠 ���옣�맂 �젅吏��뒪�듃由� �궎瑜� 蹂�寃쏀븯�떗�떆�삤.
+	// TODO: �씠 臾몄옄�뿴�쓣 �쉶�궗 �삉�뒗 議곗쭅�쓽 �씠由꾧낵 媛숈�
+	// �쟻�젅�븳 �궡�슜�쑝濡� �닔�젙�빐�빞 �빀�땲�떎.
+	SetRegistryKey(_T("濡쒖뺄 �쓳�슜 �봽濡쒓렇�옩 留덈쾿�궗�뿉�꽌 �깮�꽦�맂 �쓳�슜 �봽濡쒓렇�옩"));
+
+	CReveiwHistoryDlg dlg;
+	m_pMainWnd = &dlg;
+	INT_PTR nResponse = dlg.DoModal();
+	if (nResponse == IDOK)
+	{
+		// TODO: �뿬湲곗뿉 [�솗�씤]�쓣 �겢由��븯�뿬 ���솕 �긽�옄媛� �뾾�뼱吏� �븣 泥섎━�븷
+		//  肄붾뱶瑜� 諛곗튂�빀�땲�떎.
+	}
+	else if (nResponse == IDCANCEL)
+	{
+		// TODO: �뿬湲곗뿉 [痍⑥냼]瑜� �겢由��븯�뿬 ���솕 �긽�옄媛� �뾾�뼱吏� �븣 泥섎━�븷
+		//  肄붾뱶瑜� 諛곗튂�빀�땲�떎.
+	}
+	else if (nResponse == -1)
+	{
+		TRACE(traceAppMsg, 0, "寃쎄퀬: ���솕 �긽�옄瑜� 留뚮뱾吏� 紐삵뻽�쑝誘�濡� �쓳�슜 �봽濡쒓렇�옩�씠 �삁湲곗튂 �븡寃� 醫낅즺�맗�땲�떎.\n");
+		TRACE(traceAppMsg, 0, "寃쎄퀬: ���솕 �긽�옄�뿉�꽌 MFC 而⑦듃濡ㅼ쓣 �궗�슜�븯�뒗 寃쎌슦 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS瑜� �닔�뻾�븷 �닔 �뾾�뒿�땲�떎.\n");
+	}
+
+	// �쐞�뿉�꽌 留뚮뱺 �끂 愿�由ъ옄瑜� �궘�젣�빀�땲�떎.
+	if (pShellManager != nullptr)
+	{
+		delete pShellManager;
+	}
+
+#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
+	ControlBarCleanUp();
+#endif
+
+	// ���솕 �긽�옄媛� �떕�삍�쑝誘�濡� �쓳�슜 �봽濡쒓렇�옩�쓽 硫붿떆吏� �럩�봽瑜� �떆�옉�븯吏� �븡怨�  �쓳�슜 �봽濡쒓렇�옩�쓣 �걹�궪 �닔 �엳�룄濡� FALSE瑜�
+	// 諛섑솚�빀�땲�떎.
+	return FALSE;
+}
+
diff --git a/ReviewHistory/ReveiwHistory/ReveiwHistory.h b/ReviewHistory/ReveiwHistory/ReveiwHistory.h
new file mode 100644
index 0000000..226c23b
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/ReveiwHistory.h
@@ -0,0 +1,32 @@
+癤�
+// ReveiwHistory.h: PROJECT_NAME �쓳�슜 �봽濡쒓렇�옩�뿉 ���븳 二� �뿤�뜑 �뙆�씪�엯�땲�떎.
+//
+
+#pragma once
+
+#ifndef __AFXWIN_H__
+	#error "PCH�뿉 ���빐 �씠 �뙆�씪�쓣 �룷�븿�븯湲� �쟾�뿉 'stdafx.h'瑜� �룷�븿�빀�땲�떎."
+#endif
+
+#include "resource.h"		// 二� 湲고샇�엯�땲�떎.
+
+
+// CReveiwHistoryApp:
+// �씠 �겢�옒�뒪�쓽 援ы쁽�뿉 ���빐�꽌�뒗 ReveiwHistory.cpp�쓣(瑜�) 李몄“�븯�꽭�슂.
+//
+
+class CReveiwHistoryApp : public CWinApp
+{
+public:
+	CReveiwHistoryApp();
+
+// �옱�젙�쓽�엯�땲�떎.
+public:
+	virtual BOOL InitInstance();
+
+// 援ы쁽�엯�땲�떎.
+
+	DECLARE_MESSAGE_MAP()
+};
+
+extern CReveiwHistoryApp theApp;
diff --git a/ReviewHistory/ReveiwHistory/ReveiwHistory.rc b/ReviewHistory/ReveiwHistory/ReveiwHistory.rc
new file mode 100644
index 0000000..905b134
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/ReveiwHistory.rc
Binary files differ
diff --git a/ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj b/ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj
new file mode 100644
index 0000000..a0bb3d2
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj
@@ -0,0 +1,268 @@
+癤�<?xml version="1.0" encoding="utf-8"?>
+<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup Label="ProjectConfigurations">
+    <ProjectConfiguration Include="Debug|Win32">
+      <Configuration>Debug</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|Win32">
+      <Configuration>Release</Configuration>
+      <Platform>Win32</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Debug|x64">
+      <Configuration>Debug</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+    <ProjectConfiguration Include="Release|x64">
+      <Configuration>Release</Configuration>
+      <Platform>x64</Platform>
+    </ProjectConfiguration>
+  </ItemGroup>
+  <PropertyGroup Label="Globals">
+    <VCProjectVersion>15.0</VCProjectVersion>
+    <ProjectGuid>{FDD89A84-12C4-4024-8101-0E719E2BD9F6}</ProjectGuid>
+    <Keyword>MFCProj</Keyword>
+    <RootNamespace>DefectFromation</RootNamespace>
+    <WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
+    <ProjectName>ReviewHistroy</ProjectName>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>true</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
+    <ConfigurationType>Application</ConfigurationType>
+    <UseDebugLibraries>false</UseDebugLibraries>
+    <PlatformToolset>v141</PlatformToolset>
+    <WholeProgramOptimization>true</WholeProgramOptimization>
+    <CharacterSet>MultiByte</CharacterSet>
+    <UseOfMfc>Dynamic</UseOfMfc>
+  </PropertyGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
+  <ImportGroup Label="ExtensionSettings">
+  </ImportGroup>
+  <ImportGroup Label="Shared">
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
+  </ImportGroup>
+  <PropertyGroup Label="UserMacros" />
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <LinkIncremental>true</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <LinkIncremental>true</LinkIncremental>
+    <OutDir>$(SolutionDir)\bin\</OutDir>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <LinkIncremental>false</LinkIncremental>
+  </PropertyGroup>
+  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <LinkIncremental>false</LinkIncremental>
+    <OutDir>$(SolutionDir)\bin\</OutDir>
+  </PropertyGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0412</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <SDLCheck>false</SDLCheck>
+      <PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../include</AdditionalIncludeDirectories>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <AdditionalLibraryDirectories>../lib</AdditionalLibraryDirectories>
+      <AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0412</Culture>
+      <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>MaxSpeed</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>true</SDLCheck>
+      <PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0412</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
+    <ClCompile>
+      <PrecompiledHeader>Use</PrecompiledHeader>
+      <WarningLevel>Level3</WarningLevel>
+      <Optimization>Disabled</Optimization>
+      <FunctionLevelLinking>true</FunctionLevelLinking>
+      <IntrinsicFunctions>true</IntrinsicFunctions>
+      <SDLCheck>false</SDLCheck>
+      <PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>../include</AdditionalIncludeDirectories>
+      <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+      <WholeProgramOptimization>false</WholeProgramOptimization>
+    </ClCompile>
+    <Link>
+      <SubSystem>Windows</SubSystem>
+      <EnableCOMDATFolding>true</EnableCOMDATFolding>
+      <OptimizeReferences>true</OptimizeReferences>
+      <AdditionalLibraryDirectories>../lib</AdditionalLibraryDirectories>
+      <GenerateDebugInformation>true</GenerateDebugInformation>
+    </Link>
+    <Midl>
+      <MkTypLibCompatible>false</MkTypLibCompatible>
+      <ValidateAllParameters>true</ValidateAllParameters>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+    </Midl>
+    <ResourceCompile>
+      <Culture>0x0412</Culture>
+      <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
+      <AdditionalIncludeDirectories>$(IntDir);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
+    </ResourceCompile>
+  </ItemDefinitionGroup>
+  <ItemGroup>
+    <ClInclude Include="akDefectFormation.h" />
+    <ClInclude Include="akFormationMap.h" />
+    <ClInclude Include="akGridData.h" />
+    <ClInclude Include="akImageView.h" />
+    <ClInclude Include="akLoggerExt.h" />
+    <ClInclude Include="akWndArrange.h" />
+    <ClInclude Include="AnaResultFile.h" />
+    <ClInclude Include="CustomizeReview.h" />
+    <ClInclude Include="ReveiwHistory.h" />
+    <ClInclude Include="ReveiwHistoryDlg.h" />
+    <ClInclude Include="DitGlassRawClient.h" />
+    <ClInclude Include="DitGlassRawServer.h" />
+    <ClInclude Include="DitGlassRawStruct.h" />
+    <ClInclude Include="AlignDlg.h" />
+    <ClInclude Include="GlassRawBase.h" />
+    <ClInclude Include="GlassRawCPJT.h" />
+    <ClInclude Include="GlassRawCSOT.h" />
+    <ClInclude Include="GlassRawRTMS.h" />
+    <ClInclude Include="InterfaceFTP.h" />
+    <ClInclude Include="MacroResultFile.h" />
+    <ClInclude Include="PathSettingDlg.h" />
+    <ClInclude Include="Resource.h" />
+    <ClInclude Include="Singleton.h" />
+    <ClInclude Include="StackResultCPJT.h" />
+    <ClInclude Include="StackResultCSOT.h" />
+    <ClInclude Include="stdafx.h" />
+    <ClInclude Include="targetver.h" />
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="akDefectFormation.cpp" />
+    <ClCompile Include="akFormationMap.cpp" />
+    <ClCompile Include="akGridData.cpp" />
+    <ClCompile Include="akImageView.cpp" />
+    <ClCompile Include="akLoggerExt.cpp" />
+    <ClCompile Include="akWndArrange.cpp" />
+    <ClCompile Include="AnaResultFile.cpp" />
+    <ClCompile Include="CustomizeReview.cpp" />
+    <ClCompile Include="ReveiwHistory.cpp" />
+    <ClCompile Include="ReveiwHistoryDlg.cpp" />
+    <ClCompile Include="DitGlassRawClient.cpp" />
+    <ClCompile Include="DitGlassRawServer.cpp" />
+    <ClCompile Include="AlignDlg.cpp" />
+    <ClCompile Include="GlassRawBase.cpp" />
+    <ClCompile Include="GlassRawCPJT.cpp" />
+    <ClCompile Include="GlassRawCSOT.cpp" />
+    <ClCompile Include="GlassRawRTMS.cpp" />
+    <ClCompile Include="InterfaceFTP.cpp" />
+    <ClCompile Include="MacroResultFile.cpp" />
+    <ClCompile Include="PathSettingDlg.cpp" />
+    <ClCompile Include="StackResultCPJT.cpp" />
+    <ClCompile Include="StackResultCSOT.cpp" />
+    <ClCompile Include="stdafx.cpp">
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+      <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="ReveiwHistory.rc" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\ReveiwHistory.rc2" />
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\History.ico" />
+    <Image Include="res\ReveiwHistory.ico" />
+  </ItemGroup>
+  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
+  <ImportGroup Label="ExtensionTargets">
+  </ImportGroup>
+</Project>
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj.filters b/ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj.filters
new file mode 100644
index 0000000..2ef0608
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/ReveiwHistory.vcxproj.filters
@@ -0,0 +1,195 @@
+癤�<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <Filter Include="�냼�뒪 �뙆�씪">
+      <UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
+      <Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
+    </Filter>
+    <Filter Include="�뿤�뜑 �뙆�씪">
+      <UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
+      <Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
+    </Filter>
+    <Filter Include="由ъ냼�뒪 �뙆�씪">
+      <UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
+      <Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
+    </Filter>
+    <Filter Include="akSouce">
+      <UniqueIdentifier>{8497f531-1d33-464c-96c0-9008295743c2}</UniqueIdentifier>
+    </Filter>
+    <Filter Include="Extern">
+      <UniqueIdentifier>{412cecfa-9d77-42eb-b853-f276c16e9e82}</UniqueIdentifier>
+    </Filter>
+  </ItemGroup>
+  <ItemGroup>
+    <ClInclude Include="stdafx.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="targetver.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="Resource.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="PathSettingDlg.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="Singleton.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="akDefectFormation.h">
+      <Filter>akSouce</Filter>
+    </ClInclude>
+    <ClInclude Include="akFormationMap.h">
+      <Filter>akSouce</Filter>
+    </ClInclude>
+    <ClInclude Include="akGridData.h">
+      <Filter>akSouce</Filter>
+    </ClInclude>
+    <ClInclude Include="akLoggerExt.h">
+      <Filter>akSouce</Filter>
+    </ClInclude>
+    <ClInclude Include="akWndArrange.h">
+      <Filter>akSouce</Filter>
+    </ClInclude>
+    <ClInclude Include="DitGlassRawServer.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="DitGlassRawStruct.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="GlassRawBase.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="GlassRawCPJT.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="MacroResultFile.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="CustomizeReview.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="GlassRawRTMS.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="InterfaceFTP.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="StackResultCPJT.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="AnaResultFile.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="DitGlassRawClient.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="GlassRawCSOT.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="StackResultCSOT.h">
+      <Filter>Extern</Filter>
+    </ClInclude>
+    <ClInclude Include="ReveiwHistory.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="ReveiwHistoryDlg.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="AlignDlg.h">
+      <Filter>�뿤�뜑 �뙆�씪</Filter>
+    </ClInclude>
+    <ClInclude Include="akImageView.h">
+      <Filter>akSouce</Filter>
+    </ClInclude>
+  </ItemGroup>
+  <ItemGroup>
+    <ClCompile Include="stdafx.cpp">
+      <Filter>�냼�뒪 �뙆�씪</Filter>
+    </ClCompile>
+    <ClCompile Include="PathSettingDlg.cpp">
+      <Filter>�냼�뒪 �뙆�씪</Filter>
+    </ClCompile>
+    <ClCompile Include="akDefectFormation.cpp">
+      <Filter>akSouce</Filter>
+    </ClCompile>
+    <ClCompile Include="akFormationMap.cpp">
+      <Filter>akSouce</Filter>
+    </ClCompile>
+    <ClCompile Include="akGridData.cpp">
+      <Filter>akSouce</Filter>
+    </ClCompile>
+    <ClCompile Include="akLoggerExt.cpp">
+      <Filter>akSouce</Filter>
+    </ClCompile>
+    <ClCompile Include="akWndArrange.cpp">
+      <Filter>akSouce</Filter>
+    </ClCompile>
+    <ClCompile Include="DitGlassRawServer.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="GlassRawBase.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="GlassRawCPJT.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="MacroResultFile.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="CustomizeReview.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="GlassRawRTMS.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="InterfaceFTP.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="StackResultCPJT.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="AnaResultFile.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="DitGlassRawClient.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="GlassRawCSOT.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="StackResultCSOT.cpp">
+      <Filter>Extern</Filter>
+    </ClCompile>
+    <ClCompile Include="ReveiwHistory.cpp">
+      <Filter>�냼�뒪 �뙆�씪</Filter>
+    </ClCompile>
+    <ClCompile Include="ReveiwHistoryDlg.cpp">
+      <Filter>�냼�뒪 �뙆�씪</Filter>
+    </ClCompile>
+    <ClCompile Include="AlignDlg.cpp">
+      <Filter>�냼�뒪 �뙆�씪</Filter>
+    </ClCompile>
+    <ClCompile Include="akImageView.cpp">
+      <Filter>akSouce</Filter>
+    </ClCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <Image Include="res\ReveiwHistory.ico">
+      <Filter>由ъ냼�뒪 �뙆�씪</Filter>
+    </Image>
+    <Image Include="res\History.ico">
+      <Filter>由ъ냼�뒪 �뙆�씪</Filter>
+    </Image>
+  </ItemGroup>
+  <ItemGroup>
+    <ResourceCompile Include="ReveiwHistory.rc">
+      <Filter>由ъ냼�뒪 �뙆�씪</Filter>
+    </ResourceCompile>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="res\ReveiwHistory.rc2">
+      <Filter>由ъ냼�뒪 �뙆�씪</Filter>
+    </None>
+  </ItemGroup>
+</Project>
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.cpp b/ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.cpp
new file mode 100644
index 0000000..81b16e1
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.cpp
@@ -0,0 +1,3766 @@
+癤�
+// ReveiwHistoryDlg.cpp: 援ы쁽 �뙆�씪
+//
+
+#include "stdafx.h"
+#include "ReveiwHistory.h"
+#include "ReveiwHistoryDlg.h"
+#include "PathSettingDlg.h"
+#include "DitGlassRawStruct.h"
+#include "afxdialogex.h"
+#include "GlassRawCPJT.h"
+#include "akGridCtrl/GridCellCheck.h"
+#include "akImageView.h"
+#include <algorithm>
+
+#ifdef _DEBUG
+#define new DEBUG_NEW
+#endif
+
+// �쓳�슜 �봽濡쒓렇�옩 �젙蹂댁뿉 �궗�슜�릺�뒗 CAboutDlg ���솕 �긽�옄�엯�땲�떎.
+
+class CAboutDlg : public CDialogEx
+{
+public:
+	CAboutDlg();
+
+// ���솕 �긽�옄 �뜲�씠�꽣�엯�땲�떎.
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_ABOUTBOX };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 吏��썝�엯�땲�떎.
+
+// 援ы쁽�엯�땲�떎.
+protected:
+	DECLARE_MESSAGE_MAP()
+};
+
+CAboutDlg::CAboutDlg() : CDialogEx(IDD_ABOUTBOX)
+{
+}
+
+void CAboutDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+}
+
+BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
+END_MESSAGE_MAP()
+
+// CReveiwHistoryDlg ���솕 �긽�옄
+
+CReveiwHistoryDlg::CReveiwHistoryDlg(CWnd* pParent /*=nullptr*/)
+	: CDialogEx(IDD_DLG_REVIEWHISTORY, pParent)
+	, m_nFileCount(0)
+{
+	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
+
+	AddVecFileHeader();
+	AddVecGlassHeader();
+	AddVecDefectHeader();
+
+	m_nSelectedRow = 0;
+	m_nSelectedCol = 0;
+	m_nCount = 0;
+	m_nGlassSelect = 0;	
+	m_bDefectAll = false;
+	m_bFirst = false;
+	m_nSizeDefect = 0;
+	m_nSizeImage = 0;
+	m_nDefectCount = 0;
+	m_nImageCount = 0;
+	m_nCellCount = 0;
+	m_bAsending = FALSE;
+
+	for (int i = 0; i < 105; i++)
+	{
+		m_nSelectFile[i] = 0;
+		m_nDefectSize[i] = 0;
+		m_nCellSize[i] = 0;
+		m_nCellSizeTemp[i] = m_nCellSize[i];
+		m_nImageSize[i] = 0;
+	}
+}
+
+void CReveiwHistoryDlg::DoDataExchange(CDataExchange* pDX)
+{
+	CDialogEx::DoDataExchange(pDX);
+	DDX_Control(pDX, IDC_SLIDER_IMG, m_sldImg);
+	DDX_Control(pDX, IDC_EDIT_COUNT, m_ctrCount);
+	DDX_Control(pDX, IDC_CHK_All_DEFECT, m_chkAllDefect);
+	DDX_Control(pDX, IDC_CHK_REVIEW_DEFECT, m_chkReviewDefect);
+	DDX_Control(pDX, IDC_CHK_MUTI, m_chkMuti);
+	DDX_Control(pDX, IDC_CHK_SINGLE, m_chkSingle);
+	DDX_Control(pDX, IDC_STATIC_IMG_REVIEW, m_ctrReviewImage);
+	DDX_Text(pDX, IDC_EDIT_FILE_COUNT, m_nFileCount);
+	DDX_Control(pDX, IDC_EDIT_FILE_COUNT, m_ctlFileCount);
+	DDX_Control(pDX, IDC_PROGRESS_LOAD, m_ctlProgress);
+}
+
+BEGIN_MESSAGE_MAP(CReveiwHistoryDlg, CDialogEx)
+	ON_WM_SYSCOMMAND()
+	ON_WM_PAINT()
+	ON_WM_QUERYDRAGICON()
+	ON_WM_DESTROY()
+	ON_WM_SIZE()
+	ON_WM_HSCROLL()
+	ON_BN_CLICKED(IDC_BUTTON_MAPVIEW_FIT, &CReveiwHistoryDlg::OnBnClickedButtonMapviewFit)
+	ON_MESSAGE(UM_FORMMAP_DEFECTSELECT, OnMapDefectSelected)
+	ON_MESSAGE(UM_FORMMAP_DEFECTMOUSEOVER, OnMapDefectMouseOver)
+	ON_COMMAND(ID_OPTION_PATHSETTING, &CReveiwHistoryDlg::OnOptionPathsetting)
+	ON_COMMAND(ID_VIEW_ALLDEFECT, &CReveiwHistoryDlg::OnViewAlldefect)
+	ON_COMMAND(ID_VIEW_REVIEWDEFECT, &CReveiwHistoryDlg::OnViewReviewdefect)
+	ON_COMMAND(ID_ALIGN_VIEW, &CReveiwHistoryDlg::OnAlignView)
+	ON_BN_CLICKED(IDC_BTN_FIND_BIN, &CReveiwHistoryDlg::OnBnClickedBtnFindBin)
+	ON_EN_CHANGE(IDC_EDIT_COUNT, &CReveiwHistoryDlg::OnChangeEditCount)
+	ON_BN_CLICKED(IDC_BUTTON3, &CReveiwHistoryDlg::OnBnClickedButton3)
+	ON_BN_CLICKED(IDC_CHK_All_DEFECT, &CReveiwHistoryDlg::OnClickedChkAllDefect)
+	ON_BN_CLICKED(IDC_CHK_MUTI, &CReveiwHistoryDlg::OnClickedChkMuti)
+	ON_BN_CLICKED(IDC_CHK_REVIEW_DEFECT, &CReveiwHistoryDlg::OnClickedChkReviewDefect)
+	ON_BN_CLICKED(IDC_CHK_SINGLE, &CReveiwHistoryDlg::OnClickedChkSingle)
+	ON_EN_CHANGE(IDC_EDIT_FILE_COUNT, &CReveiwHistoryDlg::OnChangeEditFileCount)
+END_MESSAGE_MAP()
+
+// CReveiwHistoryDlg 硫붿떆吏� 泥섎━湲�
+
+BOOL CReveiwHistoryDlg::OnInitDialog()
+{
+	CDialogEx::OnInitDialog();
+
+	// �떆�뒪�뀥 硫붾돱�뿉 "�젙蹂�..." 硫붾돱 �빆紐⑹쓣 異붽��빀�땲�떎.
+
+	// IDM_ABOUTBOX�뒗 �떆�뒪�뀥 紐낅졊 踰붿쐞�뿉 �엳�뼱�빞 �빀�땲�떎.
+	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
+	ASSERT(IDM_ABOUTBOX < 0xF000);
+
+	CMenu* pSysMenu = GetSystemMenu(FALSE);
+	if (pSysMenu != nullptr)
+	{
+		BOOL bNameValid;
+		CString strAboutMenu;
+		bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
+		ASSERT(bNameValid);
+		if (!strAboutMenu.IsEmpty())
+		{
+			pSysMenu->AppendMenu(MF_SEPARATOR);
+			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
+		}
+	}
+
+	// �씠 ���솕 �긽�옄�쓽 �븘�씠肄섏쓣 �꽕�젙�빀�땲�떎.  �쓳�슜 �봽濡쒓렇�옩�쓽 二� 李쎌씠 ���솕 �긽�옄媛� �븘�땺 寃쎌슦�뿉�뒗
+	//  �봽�젅�엫�썙�겕媛� �씠 �옉�뾽�쓣 �옄�룞�쑝濡� �닔�뻾�빀�땲�떎.
+	SetIcon(m_hIcon, TRUE);			// �겙 �븘�씠肄섏쓣 �꽕�젙�빀�땲�떎.
+	SetIcon(m_hIcon, FALSE);		// �옉�� �븘�씠肄섏쓣 �꽕�젙�빀�땲�떎.
+
+	GetDlgItem(IDC_STATIC_FORMATIONMAP2)->GetWindowRect(m_picture_rect);
+	GetDlgItem(IDC_STATIC_IMG_INSPECTOR)->GetWindowRect(m_picture_rect2);
+
+	ScreenToClient(m_picture_rect);
+	ScreenToClient(m_picture_rect2);
+
+	GetDlgItem(IDC_STATIC_IMG_ALIGN1)->GetWindowRect(m_Align_rect);
+	GetDlgItem(IDC_STATIC_IMG_ALIGN2)->GetWindowRect(m_Align_rect2);
+
+	ScreenToClient(m_Align_rect);
+	ScreenToClient(m_Align_rect2);
+
+	m_ImageView.CreateGraph(this, m_picture_rect);
+	m_ImageView.SetAutoScale();
+
+
+	// TODO: �뿬湲곗뿉 異붽� 珥덇린�솕 �옉�뾽�쓣 異붽��빀�땲�떎.
+	if (1)
+	{
+		CRect rectTemp;
+		GetDlgItem(IDC_STATIC_FORMATIONMAP)->GetWindowRect(rectTemp);
+		ScreenToClient(rectTemp);
+
+		m_FormationMap.CreateGraph(this, rectTemp);
+	}
+
+	m_WndArrange.setParentWnd(this);
+	m_WndArrange.addChildWnd(&m_FormationMap, WA_RESIZE_WIDTH | WA_RESIZE_HEIGHT);
+
+	GetDlgItem(IDC_STATIC_FORMATIONMAP)->BringWindowToTop();
+
+	LOG(Dbg, _T("[Processe] Review History Start"));
+
+	CreateUserDirectory();
+	CreateUserClass();
+
+	InitGridReviewLIst(&m_gridReviewList, IDC_STATIC_GRID_GLASS);
+	InitGridDefectLIst(&m_gridDefectInfo, IDC_STATIC_GRID_DEFECT);
+	InitGridGlassLIst(&m_gridGlassInfo, IDC_STATIC_GRID_GLASS_INFO);
+
+	OnViewReviewdefect();
+
+	m_chkReviewDefect.SetCheck(TRUE);
+	m_chkSingle.SetCheck(TRUE);
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////
+	m_ConfigOption.m_nMaxDataNumCell = 200;
+	m_ConfigOption.m_nMaxDataNumDefect = 50000;
+
+	if (m_Server.CreateServer(m_ConfigOption.m_nMaxDataNumCell, m_ConfigOption.m_nMaxDataNumDefect) == FALSE)
+	{
+		LOG(Dbg, _T("[Processe]�꽌踰� �깮�꽦 �떎�뙣 醫낅즺 �빀�땲�떎."));
+		exit(0);
+	}
+
+	m_pGlassRawMaker = NULL;
+	m_ConfigOption.m_nSelectRawType = 3;
+	OnCbnSelchangeComboRawtype(); 
+//////////////////////////////////////////////////////////////////////////////////////////////////
+
+	SlideInit();	
+	Imagenoload();
+
+	m_ctlProgress.SetRange(0, 100);
+	m_ctlProgress.ShowWindow(FALSE);
+
+	return TRUE;  // �룷而ㅼ뒪瑜� 而⑦듃濡ㅼ뿉 �꽕�젙�븯吏� �븡�쑝硫� TRUE瑜� 諛섑솚�빀�땲�떎.
+}
+
+void CReveiwHistoryDlg::OnDestroy()
+{
+	CDialogEx::OnDestroy();
+
+	DestroyUserClass();
+
+	m_Filelistfont.DeleteObject();
+	m_Defectfont.DeleteObject();
+
+	LOG(Dbg, _T("[Processe] Review History End"));
+}
+
+void CReveiwHistoryDlg::OnSysCommand(UINT nID, LPARAM lParam)
+{
+	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
+	{
+		CAboutDlg dlgAbout;
+		dlgAbout.DoModal();
+	}
+	else
+	{
+		CDialogEx::OnSysCommand(nID, lParam);
+	}
+}
+
+// ���솕 �긽�옄�뿉 理쒖냼�솕 �떒異붾�� 異붽��븷 寃쎌슦 �븘�씠肄섏쓣 洹몃━�젮硫�
+//  �븘�옒 肄붾뱶媛� �븘�슂�빀�땲�떎.  臾몄꽌/酉� 紐⑤뜽�쓣 �궗�슜�븯�뒗 MFC �쓳�슜 �봽濡쒓렇�옩�쓽 寃쎌슦�뿉�뒗
+//  �봽�젅�엫�썙�겕�뿉�꽌 �씠 �옉�뾽�쓣 �옄�룞�쑝濡� �닔�뻾�빀�땲�떎.
+
+void CReveiwHistoryDlg::OnPaint()
+{
+	CPaintDC dc(this); // 洹몃━湲곕�� �쐞�븳 �뵒諛붿씠�뒪 而⑦뀓�뒪�듃�엯�땲�떎.
+
+	if (IsIconic())
+	{
+		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
+
+		// �겢�씪�씠�뼵�듃 �궗媛곹삎�뿉�꽌 �븘�씠肄섏쓣 媛��슫�뜲�뿉 留욎땅�땲�떎.
+		int cxIcon = GetSystemMetrics(SM_CXICON);
+		int cyIcon = GetSystemMetrics(SM_CYICON);
+		CRect rect;
+		GetClientRect(&rect);
+		int x = (rect.Width() - cxIcon + 1) / 2;
+		int y = (rect.Height() - cyIcon + 1) / 2;
+
+		// �븘�씠肄섏쓣 洹몃┰�땲�떎.
+		dc.DrawIcon(x, y, m_hIcon);
+	}
+	else
+	{	
+// 		if (!m_ReviewImage.IsNull())
+// 		{
+// 			dc.SetStretchBltMode(COLORONCOLOR);
+// 			// 洹몃┝�쓣 Picture Control �겕湲곕줈 �솕硫댁뿉 異쒕젰�븳�떎.
+// 			m_ReviewImage.Draw(dc, m_picture_rect);
+// 		}
+		if (!m_DefectImage.IsNull())
+		{
+			dc.SetStretchBltMode(COLORONCOLOR);
+			// 洹몃┝�쓣 Picture Control �겕湲곕줈 �솕硫댁뿉 異쒕젰�븳�떎.
+			m_DefectImage.Draw(dc, m_picture_rect2);
+		}
+
+		if (!m_AlignFirst.IsNull())
+		{
+			dc.SetStretchBltMode(COLORONCOLOR);
+			m_AlignFirst.Draw(dc, m_Align_rect);
+		}
+		if (!m_AlignSecend.IsNull())
+		{
+			dc.SetStretchBltMode(COLORONCOLOR);
+			m_AlignSecend.Draw(dc, m_Align_rect2);
+		}
+		CDialogEx::OnPaint();
+	}
+}
+
+// �궗�슜�옄媛� 理쒖냼�솕�맂 李쎌쓣 �걚�뒗 �룞�븞�뿉 而ㅼ꽌媛� �몴�떆�릺�룄濡� �떆�뒪�뀥�뿉�꽌
+//  �씠 �븿�닔瑜� �샇異쒗빀�땲�떎.
+HCURSOR CReveiwHistoryDlg::OnQueryDragIcon()
+{
+	return static_cast<HCURSOR>(m_hIcon);
+}
+
+BOOL CReveiwHistoryDlg::PreTranslateMessage(MSG * pMsg)
+{
+	POINT pt;
+	
+	pt.x = GET_X_LPARAM(pMsg->lParam);
+	pt.y = GET_Y_LPARAM(pMsg->lParam);
+	
+	switch (pMsg->message)
+	{
+		case WM_MOUSEHWHEEL:
+		{
+			
+		}
+		break;
+		case WM_MOUSEMOVE:
+		{
+	
+		}
+		break;
+		case WM_LBUTTONDOWN:
+		{
+
+// 			if (m_picture_rect.left < pt.x && m_picture_rect.right > pt.x && m_picture_rect.top < pt.y && m_picture_rect.bottom > pt.y)
+// 			{
+// 				if (m_pParentWnd == NULL || !GetImageExist()) return;
+// 
+// 				if (pt.x > -1 && pt.x < GetScaleWidth() &&
+// 					pt.y > -1 && pt.y < GetScaleHeight())
+// 				{
+// 					if (m_rectTracker.HitTest(pt) < 0)
+// 					{
+// 						// just to demonstrate CRectTracker::TrackRubberBand
+// 						if (m_rectTracker.TrackRubberBand(this, pt, TRUE))
+// 						{
+// 							Invalidate();
+// 						}
+// 					}
+// 					else if (m_rectTracker.Track(this, pt, TRUE))
+// 					{
+// 						Invalidate();
+// 					}
+// 				}
+// 
+// 				CRect rect;
+// 				this->GetClientRect(rect);
+// 
+// 				pt.x += m_nHScroll;
+// 				pt.y += m_nVScroll;
+// 				m_pParentWnd->SendMessage(WM_LBUTTONDOWN, static_cast<WPARAM>(nFlags), MAKELPARAM(pt.x, pt.y));
+//			}
+		}	
+		break;
+		case WM_LBUTTONUP:
+		{
+// 			int a = 1;
+// 			return 0;
+// 			if (m_picture_rect.left < pt.x && m_picture_rect.right > pt.x && m_picture_rect.top < pt.y && m_picture_rect.bottom > pt.y)
+// 			{
+// 				if (m_pParentWnd == NULL) return;
+// 
+// 				CRect rect;
+// 				this->GetClientRect(rect);
+// 
+// 				pt.x += m_nHScroll;
+// 				pt.y += m_nVScroll;
+// 				m_pParentWnd->SendMessage(WM_LBUTTONUP, static_cast<WPARAM>(nFlags), MAKELPARAM(pt.x, pt.y));
+// 
+// 				if (GetTrackerRect(m_rtROIRect))
+// 				{
+// 					m_sROIInfo.nWidthPixel = m_rtROIRect.Width();
+// 					m_sROIInfo.nHeightPixel = m_rtROIRect.Height();
+// 					m_sROIInfo.dDiagonalPixel = sqrt(double(m_sROIInfo.nWidthPixel*m_sROIInfo.nWidthPixel + m_sROIInfo.nHeightPixel*m_sROIInfo.nHeightPixel));
+// 
+// 					m_sROIInfo.dWidthRealUM = m_sROIInfo.nWidthPixel * (m_dResolution / m_dWidthScale);
+// 					m_sROIInfo.dHeightRealUM = m_sROIInfo.nHeightPixel * (m_dResolution / m_dHeightScale);
+// 					m_sROIInfo.dDiagonalRealUM = sqrt((m_sROIInfo.dWidthRealUM*m_sROIInfo.dWidthRealUM) + (m_sROIInfo.dHeightRealUM*m_sROIInfo.dHeightRealUM));
+// 
+// 					Invalidate(TRUE);
+// 				}
+//			}
+			//Drow �젙蹂대�� 蹂대궦�떎.
+		}
+ 		break;
+		case WM_KEYDOWN:
+		{
+			if (pMsg->wParam == VK_RETURN)
+				return TRUE;
+			else if (pMsg->wParam == VK_ESCAPE)
+				return TRUE;
+		}
+		break;
+	}
+
+	return __super::PreTranslateMessage(pMsg);
+}
+
+void CReveiwHistoryDlg::CreateUserDirectory()
+{
+	CString str;
+
+	str.Format(_T("%s\\Config\\"), GetExePath());
+	CreateDirectory(str, NULL);
+
+	str.Format(_T("%s\\Log\\"), GetExePath());
+	CreateDirectory(str, NULL);
+
+	LOG(Dbg, _T("[Processe] CreateUserDirectory"));
+}
+
+void CReveiwHistoryDlg::CreateUserClass()
+{
+	CPathSettingDlg::CreateClass();
+	CPathSettingDlg::GetMgr()->Create(this);
+	CPathSettingDlg::GetMgr()->PathSettingLoad();
+
+	CAlignDlg::CreateClass();
+	CAlignDlg::GetMgr()->Create(this);
+
+	akDefectFormation::CreateClass();
+
+	LOG(Dbg, _T("[Processe] CreateUserClass"));
+}
+
+void CReveiwHistoryDlg::DestroyUserClass()
+{
+	CPathSettingDlg::GetMgr()->DestroyWindow();
+	CPathSettingDlg::DestroyClass();
+
+	CAlignDlg::GetMgr()->DestroyWindow();
+	CAlignDlg::DestroyClass();
+
+	akDefectFormation::DestroyClass();
+
+	LOG(Dbg, _T("[Processe] DestroyUserClass"));
+}
+
+
+void CReveiwHistoryDlg::AddVecFileHeader()
+{
+	m_vecStrGridReviewHeader.push_back("   NO   ");
+	m_vecStrGridReviewHeader.push_back("         Time         ");
+	m_vecStrGridReviewHeader.push_back("�뿴湲�");
+	m_vecStrGridReviewHeader.push_back("PPID");
+	m_vecStrGridReviewHeader.push_back("GLASS ID");
+	m_vecStrGridReviewHeader.push_back("珥� 寃고븿 媛��닔");
+	m_vecStrGridReviewHeader.push_back("由щ럭 媛��닔");
+	m_vecStrGridReviewHeader.push_back("Judge");
+	m_vecStrGridReviewHeader.push_back("File Name");
+}
+void CReveiwHistoryDlg::AddVecGlassHeader()
+{
+	m_vecStrGridGlassHeader.push_back("No");
+	m_vecStrGridGlassHeader.push_back("PPID");
+	m_vecStrGridGlassHeader.push_back("Glass ID");
+	m_vecStrGridGlassHeader.push_back("珥� 寃고븿 媛��닔");
+	m_vecStrGridGlassHeader.push_back("由щ럭 寃고븿 媛��닔");
+	m_vecStrGridGlassHeader.push_back("Glass Judge");
+	m_vecStrGridGlassHeader.push_back("Lot ID");
+	m_vecStrGridGlassHeader.push_back("Slot ID");
+	m_vecStrGridGlassHeader.push_back("Slot Number");
+	m_vecStrGridGlassHeader.push_back("Cell Number");
+	m_vecStrGridGlassHeader.push_back("Glass Height");
+	m_vecStrGridGlassHeader.push_back("Glass Width");
+}
+void CReveiwHistoryDlg::AddVecDefectHeader()
+{
+	m_vecStrGridDefectHeader.push_back("No");
+	m_vecStrGridDefectHeader.push_back("Idx");
+	m_vecStrGridDefectHeader.push_back("Loc");
+	m_vecStrGridDefectHeader.push_back("Classification");
+	m_vecStrGridDefectHeader.push_back("Code");
+	m_vecStrGridDefectHeader.push_back("Type");
+	m_vecStrGridDefectHeader.push_back("SubType");
+	m_vecStrGridDefectHeader.push_back("Length");
+	m_vecStrGridDefectHeader.push_back("XSize(um)");
+	m_vecStrGridDefectHeader.push_back("YSize(um)");
+	m_vecStrGridDefectHeader.push_back("Area(um)");
+	m_vecStrGridDefectHeader.push_back("Zone");
+	m_vecStrGridDefectHeader.push_back("DMax");
+	m_vecStrGridDefectHeader.push_back("DMin");
+	m_vecStrGridDefectHeader.push_back("DAvg");
+	m_vecStrGridDefectHeader.push_back("Peak");
+	m_vecStrGridDefectHeader.push_back("Step");
+	m_vecStrGridDefectHeader.push_back("Cam");
+	m_vecStrGridDefectHeader.push_back("Scan");
+	m_vecStrGridDefectHeader.push_back("RMax");
+	m_vecStrGridDefectHeader.push_back("RMin");
+	m_vecStrGridDefectHeader.push_back("RAvg");
+	m_vecStrGridDefectHeader.push_back("Xpos(mm)");
+	m_vecStrGridDefectHeader.push_back("Ypos(mm)");
+	m_vecStrGridDefectHeader.push_back("CellX(mm)");
+	m_vecStrGridDefectHeader.push_back("CellY(mm)");
+	m_vecStrGridDefectHeader.push_back("ScrtRatio");
+	m_vecStrGridDefectHeader.push_back("Density");
+	m_vecStrGridDefectHeader.push_back("MergeState");
+}
+
+void CReveiwHistoryDlg::SlideInit()
+{
+	m_sldImg.SetRange(-1, -1);
+	m_sldImg.SetPos(-1);
+	m_sldImg.SetLineSize(3);
+	m_sldImg.SetPageSize(10);
+
+	int nPos = m_sldImg.GetPos();
+	CString strPos;
+	strPos.Format(_T("%d"), nPos);
+	m_ctrCount.SetWindowText(strPos);
+
+	CString strCount;
+	m_ctlFileCount.SetWindowText("100");
+	m_ctlFileCount.GetWindowText(strCount);
+
+	m_nFileCount = _ttoi(strCount);
+}
+
+void CReveiwHistoryDlg::InitGridReviewLIst(CakGridCtrl* pGrid, UINT nRectCtrlID)
+{
+	std::vector<CString>* pVecHeader = &m_vecStrGridReviewHeader;
+
+	CRect rectGrid;
+	GetDlgItem(nRectCtrlID)->GetWindowRect(&rectGrid);
+	ScreenToClient(&rectGrid);
+	pGrid->Create(rectGrid, this, nRectCtrlID);
+	pGrid->GetDefaultCell(TRUE, FALSE)->SetBackClr(GRID_FIX_COLOR);
+	pGrid->GetDefaultCell(FALSE, TRUE)->SetBackClr(GRID_FIX_COLOR);
+	pGrid->GetDefaultCell(FALSE, FALSE)->SetBackClr(GRID_COLOR);
+ 	pGrid->SetFixedBkColor(GRID_FIX_COLOR);
+ 	pGrid->SetGridLines(GVL_BOTH);
+
+	pGrid->SetVirtualMode(FALSE);
+ 	pGrid->SetCallbackFunc(NULL, 0);
+ 	pGrid->AllowReorderColumn(FALSE);
+ 	pGrid->EnableDragRowMode(FALSE);
+
+	pGrid->SetColumnCount((int)pVecHeader->size());
+	pGrid->SetDoubleBuffering(TRUE);
+	pGrid->SetRowCount(2);
+ 	pGrid->SetFixedRowCount(1);
+ 	pGrid->SetFixedColumnCount(0);
+
+ 	pGrid->SetEditable(FALSE);
+ 	pGrid->EnableSelection(TRUE);
+ 	pGrid->SetFixedRowSelection(TRUE);
+ 	pGrid->SetHeaderSort(FALSE);
+
+	// fill it up with stuff
+	pGrid->SetEditable(TRUE);
+	pGrid->EnableDragAndDrop(TRUE);
+
+	int nRowIdx, nColIdx, nRows, nCols, nFixRows, nFixCols;
+	CString strTemp;
+
+	GV_ITEM Item;
+	nRowIdx = 0;
+	nColIdx = 0;
+	Item.mask = GVIF_TEXT;
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("   No   "));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("         Time         "));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("�뿴湲�"));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("PPID"));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("GLASS ID"));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("珥� 寃고븿 媛��닔"));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("由щ럭 媛��닔"));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx;
+	Item.col = nColIdx++;
+	strTemp.Format(_T("Judge"));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = nRowIdx++;
+	Item.col = nColIdx;
+	strTemp.Format(_T("File Name"));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	Item.row = 1;
+	Item.col = 0;
+	strTemp.Format(_T(" "));
+	Item.strText = strTemp;
+	pGrid->SetItem(&Item);
+
+	pGrid->SetCellType(1, 0, RUNTIME_CLASS(CGridCellCheck));
+ 
+ 	pGrid->AutoSize();	
+	pGrid->Invalidate();
+
+	m_WndArrange.setParentWnd(this);
+	m_WndArrange.addChildWnd(&m_gridReviewList, WA_RESIZE_WIDTH | WA_RESIZE_HEIGHT);
+}
+
+void CReveiwHistoryDlg::InitGridGlassLIst(CakGridCtrl* pGrid, UINT nRectCtrlID)
+{
+	std::vector<CString>* pVecHeader = &m_vecStrGridGlassHeader;
+
+	CRect rectGrid;
+	GetDlgItem(nRectCtrlID)->GetWindowRect(&rectGrid);
+	ScreenToClient(&rectGrid);
+	pGrid->Create(rectGrid, this, nRectCtrlID);
+
+	pGrid->GetDefaultCell(TRUE, FALSE)->SetBackClr(GRID_FIX_COLOR);
+	pGrid->GetDefaultCell(FALSE, TRUE)->SetBackClr(GRID_FIX_COLOR);
+	pGrid->GetDefaultCell(FALSE, FALSE)->SetBackClr(GRID_COLOR);
+	pGrid->SetFixedBkColor(GRID_FIX_COLOR);
+	pGrid->SetGridLines(GVL_BOTH);
+
+	pGrid->SetVirtualMode(TRUE);
+	pGrid->SetCallbackFunc(NULL, 0);
+	pGrid->AllowReorderColumn(FALSE);
+	pGrid->EnableDragRowMode(FALSE);
+
+	pGrid->SetColumnCount((int)pVecHeader->size());
+	pGrid->SetDoubleBuffering(TRUE);
+	pGrid->SetRowCount(2);
+	pGrid->SetFixedRowCount(1);
+	pGrid->SetFixedColumnCount(0);
+
+	pGrid->SetEditable(FALSE);
+	pGrid->EnableSelection(TRUE);
+	pGrid->SetFixedRowSelection(TRUE);
+	pGrid->SetHeaderSort(FALSE);
+
+	// fill it up with stuff
+	pGrid->SetEditable(TRUE);
+	pGrid->EnableDragAndDrop(TRUE);
+
+	pGrid->AutoSize();
+	pGrid->Invalidate();
+
+	m_WndArrange.setParentWnd(this);
+	m_WndArrange.addChildWnd(&m_gridGlassInfo, WA_RESIZE_WIDTH | WA_RESIZE_HEIGHT);
+}
+
+void CReveiwHistoryDlg::InitGridDefectLIst(CakGridCtrl* pGrid, UINT nRectCtrlID)
+{
+	std::vector<CString>* pVecHeader = &m_vecStrGridDefectHeader;
+
+	CRect rectGrid;
+	GetDlgItem(nRectCtrlID)->GetWindowRect(&rectGrid);
+	ScreenToClient(&rectGrid);
+	pGrid->Create(rectGrid, this, nRectCtrlID);
+
+	pGrid->GetDefaultCell(TRUE, FALSE)->SetBackClr(GRID_FIX_COLOR);
+	pGrid->GetDefaultCell(FALSE, TRUE)->SetBackClr(GRID_FIX_COLOR);
+	pGrid->GetDefaultCell(FALSE, FALSE)->SetBackClr(GRID_COLOR);
+	pGrid->SetFixedBkColor(GRID_FIX_COLOR);
+	pGrid->SetGridLines(GVL_BOTH);
+
+	pGrid->SetVirtualMode(TRUE);
+	pGrid->SetCallbackFunc(NULL, 0);
+	pGrid->AllowReorderColumn(FALSE);
+	pGrid->EnableDragRowMode(FALSE);
+
+	pGrid->SetColumnCount((int)pVecHeader->size());
+	pGrid->SetDoubleBuffering(TRUE);
+	pGrid->SetRowCount(2);
+	pGrid->SetFixedRowCount(1);
+	pGrid->SetFixedColumnCount(0);
+
+	pGrid->SetEditable(FALSE);
+	pGrid->EnableSelection(TRUE);
+	pGrid->SetFixedRowSelection(TRUE);
+	pGrid->SetHeaderSort(FALSE);
+
+	// fill it up with stuff
+	pGrid->SetEditable(TRUE);
+	pGrid->EnableDragAndDrop(TRUE);
+
+	pGrid->AutoSize();
+	pGrid->Invalidate();
+
+	m_WndArrange.setParentWnd(this);
+	m_WndArrange.addChildWnd(&m_gridDefectInfo, WA_RESIZE_WIDTH | WA_RESIZE_HEIGHT);
+}
+
+BOOL CReveiwHistoryDlg::OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
+{
+	if (m_gridReviewList.GetSafeHwnd() && wParam == (WPARAM)m_gridReviewList.GetDlgCtrlID())
+	{
+		*pResult = 1;
+		GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;
+		if (GVN_GETDISPINFO == pDispInfo->hdr.code)
+		{
+			getDispInfoGlass(pDispInfo->item.col, pDispInfo->item.row, &pDispInfo->item.strText);
+
+			return TRUE;
+		}
+		else if (NM_CLICK == pDispInfo->hdr.code)
+		{
+			if (pDispInfo->item.row == 0)
+			{
+				m_gridReviewList.Refresh();
+			}
+			else if (pDispInfo->item.row > 0)
+			{
+				CGridCellCheck* pCellCheck = NULL;
+				pCellCheck = (CGridCellCheck*)m_gridReviewList.GetCell(pDispInfo->item.row, 0);
+				BOOL bMultiCheck = pCellCheck->GetCheck();
+			
+				if (m_nCount == pDispInfo->item.row)
+				{
+					if (m_chkSingle.GetCheck())
+					{
+						if (pCellCheck != NULL)
+						{
+							pCellCheck->SetCheck(FALSE);
+						}
+					}
+					else
+					{
+						if (pCellCheck != NULL)
+						{
+							pCellCheck->SetCheck(!bMultiCheck);
+						}
+					}
+					return TRUE;
+				}
+				m_nCount = pDispInfo->item.row;
+				m_nGlassSelect = pDispInfo->item.row;				
+
+				CGridCellCheck* pCellCheck2 = NULL;
+				pCellCheck2 = (CGridCellCheck*)m_gridReviewList.GetCell(m_nGlassSelect, 0);
+				BOOL bMultiCheck2 = pCellCheck->GetCheck();
+
+				if (m_chkSingle.GetCheck())
+				{
+					if (pCellCheck != NULL)
+					{
+						pCellCheck->SetCheck(FALSE);
+					}
+					GlassInfoRest();
+					BinFileOpen(pDispInfo->item.row);
+				}
+				else if(m_chkMuti.GetCheck())
+				{	
+					if (bMultiCheck2 == TRUE)
+					{
+// 						if (MultiSelectCheck(pDispInfo->item.row))
+// 						{
+						//if(pDispInfo->item.row)
+						bool bCheck = false;
+						for (int i = 0; i < 105; i++)
+						{
+							if (m_nSelectFile[i] == pDispInfo->item.row)
+							{
+								bCheck = true;
+							}
+						}
+						if (!bCheck)
+						{
+							InitSelectGlass(pDispInfo->item.row);
+ 							BinFileOpen(pDispInfo->item.row);
+						}
+/*						}*/
+					}
+					else if(bMultiCheck == FALSE)
+					{
+						MultiSelectCheck(pDispInfo->item.row);
+						SetScrollSetting();
+					}
+				}
+			}
+// 			if (!m_chkSingle.GetCheck())
+// 			{
+// 				for (int i = 0; i < MAX_COUNT + 1; i++)
+// 				{
+// 					for (int iCol = 0; iCol < m_gridReviewList.GetColumnCount(); iCol++)
+// 					{
+// 						m_gridReviewList.SetItemState(m_nSelectFile[i], iCol, LVIS_SELECTED);
+// 					}
+// 				}
+// 				m_gridReviewList.Invalidate();
+// 			}
+			m_nSelectedCol = pDispInfo->item.col;
+		}
+		else if (GVN_ODCACHEHINT == pDispInfo->hdr.code)
+		{
+			GV_CACHEHINT *pCacheHint = (GV_CACHEHINT*)pDispInfo;
+		}
+	}
+	else if (m_gridGlassInfo.GetSafeHwnd() && wParam == (WPARAM)m_gridGlassInfo.GetDlgCtrlID())
+	{
+		*pResult = 1;
+		GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;
+		if (GVN_GETDISPINFO == pDispInfo->hdr.code)
+		{
+			getDispInfoGlassInfo(pDispInfo->item.col, pDispInfo->item.row, &pDispInfo->item.strText);
+			return TRUE;
+		}
+		else if (NM_CLICK == pDispInfo->hdr.code)
+		{
+			//硫��떚 紐⑤뱶 �씪�븣 �꽑�깮�븳 �냸�쓽 cell 媛믪쓣 蹂댁뿬 以��떎
+			if (!m_chkSingle.GetCheck())
+			{
+				SelectCell(pDispInfo->item.row);
+			}
+		}
+
+		else if (GVN_ODCACHEHINT == pDispInfo->hdr.code)
+		{
+			GV_CACHEHINT *pCacheHint = (GV_CACHEHINT*)pDispInfo;
+		}
+	}
+	else if (m_gridDefectInfo.GetSafeHwnd() && wParam == (WPARAM)m_gridDefectInfo.GetDlgCtrlID())
+	{
+		*pResult = 1;
+		GV_DISPINFO *pDispInfo = (GV_DISPINFO*)lParam;
+		if (GVN_GETDISPINFO == pDispInfo->hdr.code)
+		{
+			getDispInfoDefect(pDispInfo->item.col, pDispInfo->item.row, &pDispInfo->item.strText);
+
+			return TRUE;
+		}
+		else if (NM_CLICK == pDispInfo->hdr.code)
+		{
+			if (pDispInfo->item.row == 0)
+			{
+				SortListDefect(pDispInfo->item.col);
+				m_gridDefectInfo.Refresh();
+			}
+			else if (pDispInfo->item.row > 0)
+			{
+				if (pDispInfo->item.row <= m_Formation.m_vecDefects.size())
+				{
+					_akDefect* pDefectInfo = &m_Formation.m_vecDefects[pDispInfo->item.row - 1];
+
+					m_FormationMap.setSelectDefect(pDefectInfo->m_nDefectID);
+					//ImageShow(pDefectInfo->m_nDefectID);
+					if (!m_bDefectAll)
+					{
+						ImageShow(pDispInfo->item.row - 1);
+					}
+					else
+					{
+						ImageShow(pDefectInfo->m_nDefectID);
+					}
+					//硫��떚 紐⑤뜽�씪 �븣�� �븘�땺 �븣 援щ텇�쓣 �븯�옄
+					//�젙�젹 �닚�꽌瑜� �궗�슜�옄媛� �썝�븯�뒗 �닚�쑝濡� �븯�옄
+					if (!m_bDefectAll)
+					{
+						m_sldImg.SetPos(pDispInfo->item.row - 1);
+						
+						int nPos = m_sldImg.GetPos();
+						CString strPos;
+						strPos.Format(_T("%d"), nPos);
+						m_ctrCount.SetWindowText(strPos);
+					}
+				}
+			}
+			m_nSelectedCol = pDispInfo->item.col;
+		}
+
+		else if (GVN_ODCACHEHINT == pDispInfo->hdr.code)
+		{
+			GV_CACHEHINT *pCacheHint = (GV_CACHEHINT*)pDispInfo;
+		}
+	}
+	
+	return CDialog::OnNotify(wParam, lParam, pResult);
+}
+
+void CReveiwHistoryDlg::getDispInfoGlass(int nCol, int nRow, CString* pStrData)
+{
+	if (nRow < 0) return;
+
+	if (nRow == 0)
+	{
+		*pStrData = m_vecStrGridReviewHeader[nCol];
+	}
+	else
+	{
+		CString  strItem;
+		int nDataIndex = nRow - 1;
+
+		if (nDataIndex >= m_vecStrGridReviewList.size()) return;
+
+		_akReviewHeader* pDefectInfo = &m_Formation.m_vecHeader[nRow - 1];
+
+		switch (nCol)
+		{
+		case  0: strItem.Format("%d", nRow); break;
+		case  1: strItem.Format("%s", pDefectInfo->m_strFileTime); break;
+		case  2: strItem.Format("%s", pDefectInfo->m_strLoading); break;
+		case  3: strItem.Format("%s", pDefectInfo->m_strPPID); break;	
+		case  4: strItem.Format("%s", pDefectInfo->m_strGlassID); break;	
+		case  5: strItem.Format("%d", pDefectInfo->m_nDefectIdx); break;
+		case  6: strItem.Format("%d", pDefectInfo->m_nReviewIdx); break;
+		case  7: strItem.Format("%s", pDefectInfo->m_strJudge); break;
+		case  8: strItem.Format("%s", pDefectInfo->m_strFileName); break;
+		}
+		*pStrData = strItem;
+	}
+}
+
+void CReveiwHistoryDlg::getDispInfoGlassInfo(int nCol, int nRow, CString* pStrData)
+{
+	if (nRow < 0) return;
+
+	if (nRow == 0) //header
+	{
+		*pStrData = m_vecStrGridGlassHeader[nCol];
+	}
+	else
+	{
+		CString  strItem;
+		int nDataIndex = nRow - 1;
+
+		if (nDataIndex >= m_Formation.m_vecGlassInfo.size()) return;
+
+		_akGlassInfo* pGlassInfo = &m_Formation.m_vecGlassInfo[nRow - 1];
+
+		if (pGlassInfo == NULL) return;
+
+		switch (nCol)
+		{
+		case  0: strItem.Format("%d", pGlassInfo->m_nGlassSelect); break;	//"No");
+		case  1: strItem.Format("%s", pGlassInfo->m_strPPID); break;	//"GlassID");
+		case  2: strItem.Format("%s", pGlassInfo->m_strGlassID); break;	//PPID
+		case  3: strItem.Format("%d", pGlassInfo->m_nDefectNum); break; //LOT ID
+		case  4: strItem.Format("%d", pGlassInfo->m_nReviewNum); break; //SLOT ID
+		case  5: strItem.Format("%s", pGlassInfo->m_strGlassJudge); break; //Glass Judge
+		case  6: strItem.Format("%s", pGlassInfo->m_strLotID); break; //SLOT NUMBER
+		case  7: strItem.Format("%s", pGlassInfo->m_strSLotID); break;	//Cell NUmber
+		case  8: strItem.Format("%d", pGlassInfo->m_nSlot_No); break; //Defect Count
+		case  9: strItem.Format("%d", pGlassInfo->m_nCellNum); break; //Glass size H
+		case  10: strItem.Format("%d", pGlassInfo->m_nGlassSizeHeight); break; //Glass Judge
+		case  11: strItem.Format("%d", pGlassInfo->m_nGlassSizeWidth); break; //Glass size W
+		}
+		*pStrData = strItem;
+	}
+}
+
+void CReveiwHistoryDlg::getDispInfoDefect(int nCol, int nRow, CString* pStrData)
+{
+	if (nRow < 0) return;
+
+	if (nRow == 0) //header
+	{
+		*pStrData = m_vecStrGridDefectHeader[nCol];
+	}
+	else
+	{
+		int nDataIndex = nRow - 1;
+		int iRow = m_nSelectedRow;
+
+		if (nDataIndex >= m_Formation.m_vecDefects.size())
+		{
+			return;
+		}
+
+		_akDefect* pDefectInfo = &m_Formation.m_vecDefects[nRow - 1];
+
+		if (pDefectInfo == NULL)
+			return;
+
+		CString  strItem;
+
+		switch (nCol)
+		{
+		case 0: strItem.Format("%d", nRow); break;
+		case 1: strItem.Format("%d", pDefectInfo->m_nDefectID); break;
+		case 2:
+		{
+			strItem = _T("");
+			if (pDefectInfo->m_sDefectLoc == DefectLoc_Pattern)
+				strItem = "Pat";
+			else if (pDefectInfo->m_sDefectLoc == DefectLoc_PAD)
+				strItem = "PAD";
+			else if (pDefectInfo->m_sDefectLoc == DefectLoc_C2C)
+				strItem = "C2C";
+			else if (pDefectInfo->m_sDefectLoc == DefectLoc_Crack)
+				strItem = "Crk";
+			else if (pDefectInfo->m_sDefectLoc == DefectLoc_ASG)
+				strItem = "ASG";
+			else if (pDefectInfo->m_sDefectLoc == DefectLoc_BM)
+				strItem = "BM";
+			else
+				strItem = "Pat";
+		}
+		break;
+		case 3:	strItem = pDefectInfo->m_strDefectType;	break;
+		case 4: strItem.Format("%s", pDefectInfo->m_strDefectCode); break;
+		case 5:
+		{
+			if (pDefectInfo->m_DefectType == DefectType_RBlack)
+				strItem.Format("RB");
+			else if (pDefectInfo->m_DefectType == DefectType_RWhite)
+				strItem.Format("RW");
+			else if (pDefectInfo->m_DefectType == DefectType_TBlack)
+				strItem.Format("TB");
+			else if (pDefectInfo->m_DefectType == DefectType_TWhite)
+				strItem.Format("TW");
+			else
+				strItem = "UN";
+		}
+		break;
+		case 6:
+		{
+			strItem = _T("");
+
+			if (pDefectInfo->m_DefectSubType == DefectSubType_MC)						// Common 05 M/N/C/S/K/*
+				strItem = "MC";
+			else if (pDefectInfo->m_DefectSubType == DefectSubType_Mask)
+				strItem = "MD";
+			else if (pDefectInfo->m_DefectSubType == DefectSubType_Common)
+				strItem = "CD";
+			else if (pDefectInfo->m_DefectSubType == DefectSubType_NoDefect)
+				strItem = "NO";
+			else
+				strItem = "N";
+		}
+		break;
+		case 7: strItem.Format("%d", pDefectInfo->m_nDefectRScale); break;
+		case 8:
+		{
+				strItem = _T("");
+				strItem.Format("% 7d", pDefectInfo->m_nUMSizeX);
+		}
+		break;
+		case 9:
+		{
+				strItem = _T("");
+				strItem.Format("% 7d", pDefectInfo->m_nUMSizeY);
+		}
+		break;
+		case 10:
+				strItem.Format("%d", pDefectInfo->m_nUMSize);
+			break;
+		case 11:
+		{
+			int nValue = 0;
+			for (int i = 105; i >= 0; i--)
+			{
+				if (pDefectInfo->m_sZonePixelCount[i] > 0)
+					nValue += 1;
+				if (i > 0)
+					nValue = nValue << 1;
+			}
+
+			strItem.Format("%04X", nValue);
+		}
+		break;
+		case 12: strItem.Format("%d", pDefectInfo->m_nLevelSrcMax); break;
+		case 13: strItem.Format("%d", pDefectInfo->m_nLevelSrcMin); break;
+		case 14: strItem.Format("%d", pDefectInfo->m_nLevelSrcAvg); break;
+		case 15: strItem.Format("%d", pDefectInfo->m_sDefectPeak); break;
+		case 16:
+		{
+			strItem.Format("%s", pDefectInfo->m_strStackFirst);
+		}
+		break;
+		case 17:
+		{
+			strItem = _T("");
+			strItem.Format("% 4d", pDefectInfo->m_nCameraID);
+		}
+		break;
+		case 18: strItem.Format("%d", pDefectInfo->m_nScanIdx); break;
+		case 19: strItem.Format("%d", pDefectInfo->m_nLevelRefMax); break;
+		case 20: strItem.Format("%d", pDefectInfo->m_nLevelRefMin); break;
+		case 21: strItem.Format("%d", pDefectInfo->m_nLevelRefAvg); break;
+		case 22:
+		{
+			CString		str;
+			strItem = _T("          ");
+			str.Format("%5.3f", (double)pDefectInfo->m_nUMCenterAlignX / 1000.0);
+			strItem.Insert(9 - str.GetLength(), str);
+			strItem.TrimRight(" ");
+		}
+		break;
+		case 23:
+		{
+			CString		str;
+			strItem = _T("          ");
+			str.Format("% 5.3f", (double)pDefectInfo->m_nUMCenterAlignY / 1000.0);
+			strItem.Insert(9 - str.GetLength(), str);
+			strItem.TrimRight(" ");
+		}
+		break;
+		case 24:
+		{
+			CString		str;
+			strItem = _T("          ");
+
+			// Panel x異�, y異뺤� 湲��씪�뒪�� 諛섎� [6/9/2017 bhs]
+			if (1)//g_pBasic->GetScanCoordination() == SC_XCoord)
+				str.Format("% 5.3f", (double)pDefectInfo->m_nUMCellX / 1000.0);
+			else
+				str.Format("% 5.3f", (double)pDefectInfo->m_nUMCellY / 1000.0);
+
+			strItem.Insert(9 - str.GetLength(), str);
+			strItem.TrimRight(" ");
+		}
+		break;
+		case 25:
+		{
+			CString		str;
+			strItem = _T("          ");
+
+			// Panel x異�, y異뺤� 湲��씪�뒪�� 諛섎� [6/9/2017 bhs]
+			if (1)//g_pBasic->GetScanCoordination() == SC_XCoord)
+				str.Format("% 5.3f", (double)pDefectInfo->m_nUMCellY / 1000.0);
+			else
+				str.Format("% 5.3f", (double)pDefectInfo->m_nUMCellX / 1000.0);
+
+			strItem.Insert(9 - str.GetLength(), str);
+			strItem.TrimRight(" ");
+		}
+		break;
+		case 26: strItem.Format("%d", pDefectInfo->m_nScratchRatio); break;
+		case 27: strItem.Format("%d", pDefectInfo->m_nDensity); break;
+		case 28: strItem.Format("%d", pDefectInfo->m_bMergeState); break;
+		}
+
+		*pStrData = strItem;
+	}
+}
+
+LRESULT CReveiwHistoryDlg::OnMapDefectSelected(WPARAM wParam, LPARAM lParam)
+{
+	int nSelectMode = static_cast<int>(lParam);
+	int nSelectDefect = static_cast<int>(wParam);
+
+	if (nSelectMode == 0)
+	{
+		setDefectShow(nSelectDefect, 1);
+		//ImageShow(nSelectDefect);
+
+		if (m_Formation.m_vecImage.size() < 0) return 0;
+
+		for (int i = 0; i < m_Formation.m_vecImage.size(); i++)
+		{
+			if (m_Formation.m_vecImage[i].m_nDefectID == nSelectDefect)
+			{
+				ImageShow(i);
+				break;
+			}
+		}
+
+		if (!m_bDefectAll)
+		{
+			m_sldImg.SetPos(m_nSelectedRow - 1);
+
+			int nPos = m_sldImg.GetPos();
+			CString strPos;
+			strPos.Format(_T("%d"), nPos);
+			m_ctrCount.SetWindowText(strPos);
+		}
+	}
+	else if (nSelectMode == 1)
+	{
+		CAlignDlg* lpDlg = CAlignDlg::GetMgr();
+		m_pDlgAlign->setFormShow(nSelectDefect, 1);
+	}
+
+	return 0;
+}
+
+LRESULT CReveiwHistoryDlg::OnListDefectSelected(WPARAM wParam, LPARAM lParam)
+{
+	int nSelectDefect = static_cast<int>(wParam);
+	int nMode = static_cast<int>(lParam);
+	
+	m_FormationMap.setSelectDefect(nSelectDefect);
+
+	return 0;
+}
+
+LRESULT CReveiwHistoryDlg::OnMapDefectMouseOver(WPARAM wParam, LPARAM lParam)
+{
+	int nSelectDefect = static_cast<int>(wParam);
+	int nMode = static_cast<int>(lParam);
+	
+	return 0;
+}
+
+void CReveiwHistoryDlg::OnBnClickedButtonMapviewFit()
+{
+	m_FormationMap.SetAutoScale();
+}
+
+void CReveiwHistoryDlg::OnSize(UINT nType, int cx, int cy)
+{
+	CDialogEx::OnSize(nType, cx, cy);
+
+	m_WndArrange.process(cx, cy);
+	m_FormationMap.SetAutoScale();	
+	m_ImageView.SetResize();
+}
+
+void CReveiwHistoryDlg::OnOptionPathsetting()
+{
+	// TODO: �뿬湲곗뿉 紐낅졊 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CPathSettingDlg::GetMgr()->PathSettingLoad();
+	CPathSettingDlg* lpDlg = CPathSettingDlg::GetMgr();
+	lpDlg->ShowWindow(SW_SHOW);
+
+	LOG(Dbg, _T("[Processe] PathSetting Click"));
+}
+
+
+void CReveiwHistoryDlg::OnViewAlldefect()
+{
+	// TODO: �뿬湲곗뿉 紐낅졊 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CMenu *hMenu = GetMenu();
+	if (hMenu->GetMenuState(ID_VIEW_ALLDEFECT, MF_BYCOMMAND) != MF_CHECKED)
+	{
+		hMenu->CheckMenuItem(ID_VIEW_ALLDEFECT, MF_CHECKED);
+		hMenu->CheckMenuItem(ID_VIEW_REVIEWDEFECT, MF_UNCHECKED);
+		m_bDefectAll = true;
+	}
+	else
+	{
+		hMenu->CheckMenuItem(ID_VIEW_REVIEWDEFECT, MF_CHECKED);
+		hMenu->CheckMenuItem(ID_VIEW_ALLDEFECT, MF_UNCHECKED);
+		m_bDefectAll = false;
+	}
+
+	if (m_chkSingle.GetCheck())
+	{
+		GlassInfoRest();
+		BinFileOpen(m_nCount);
+	}
+	else
+	{
+		for(int i=0; i< 105; i++)
+		{
+			int nSelect = m_nSelectFile[i];
+			BinFileOpen(nSelect);
+		}
+	}
+}
+
+
+void CReveiwHistoryDlg::OnViewReviewdefect()
+{
+	// TODO: �뿬湲곗뿉 紐낅졊 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CMenu *hMenu = GetMenu();
+	if (hMenu->GetMenuState(ID_VIEW_REVIEWDEFECT, MF_BYCOMMAND) != MF_CHECKED)
+	{
+		hMenu->CheckMenuItem(ID_VIEW_REVIEWDEFECT, MF_CHECKED);
+		hMenu->CheckMenuItem(ID_VIEW_ALLDEFECT, MF_UNCHECKED);
+		m_bDefectAll = false;
+	}
+	else
+	{
+		hMenu->CheckMenuItem(ID_VIEW_REVIEWDEFECT, MF_UNCHECKED);
+		hMenu->CheckMenuItem(ID_VIEW_ALLDEFECT, MF_CHECKED);
+		m_bDefectAll = true;
+	}
+
+	if (m_chkSingle.GetCheck())
+	{
+		GlassInfoRest();
+		BinFileOpen(m_nCount);
+	}
+	else
+	{
+		BinFileOpen(m_nCount);
+	}
+}
+
+void CReveiwHistoryDlg::OnAlignView()
+{
+	// TODO: �뿬湲곗뿉 紐낅졊 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CRect rectWindow;
+	GetClientRect(&rectWindow);
+	ClientToScreen(&rectWindow);
+
+	CAlignDlg* lpDlg = CAlignDlg::GetMgr();	
+
+	lpDlg->SetWindowPos(NULL, rectWindow.right + 5, rectWindow.top - 50, 0, 0, SWP_NOZORDER | SWP_NOSIZE);
+	lpDlg->ShowWindow(SW_SHOW);
+	lpDlg->DrawnoImage();
+}
+
+void CReveiwHistoryDlg::FileTime(CString strPath)
+{
+	HANDLE h_File = CreateFile(_T(strPath), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+
+	if (h_File != INVALID_HANDLE_VALUE)
+	{
+		//** create_time : �깮�꽦 �궇吏�, access_time : 留덉�留� �젒洹쇰궇吏�, write_time : 留덉�留� �닔�젙 �궇吏�
+		FILETIME create_time, access_time, write_time;
+		//** System Time 痍⑤뱷
+		GetFileTime(h_File, &create_time, &access_time, &write_time);
+
+		//** SystemTime�� UTC�삎�떇(Universal Time Coordinated)�씠湲� �븣臾몄뿉 洹몃깷 �궗�슜 遺덇��뒫
+		//** 吏��뿭�떆媛꾩쑝濡� 蹂�寃�(�씪諛섏쟻�씤 �떆媛� 怨꾩궛踰� 2015/11/09 21:18:35)
+		SYSTEMTIME write_system_time, write_local_time;
+		FileTimeToSystemTime(&write_time, &write_system_time);
+
+		//** write_local_time蹂��닔�뿉 蹂��솚�릺�뼱 ���옣�맖
+		//** ���옣�맂 �삎�깭�뒗 WORD�삎(short)
+		//** wYear, wMonth, wDay, wHour, wMinute, wSecond瑜� �솢�슜�븯�뿬 �궗�슜�븯硫� �맖
+		SystemTimeToTzSpecificLocalTime(NULL, &write_system_time, &write_local_time);
+
+		int nYear, nMonth, nDay, nHour, nMinute, nSecond;
+		nYear = write_local_time.wYear;
+		nMonth = write_local_time.wMonth;
+		nDay = write_local_time.wDay;
+		nHour = write_local_time.wHour;
+		nMinute = write_local_time.wMinute;
+		nSecond = write_local_time.wSecond;
+		CString strTime;
+		strTime.Format("%04d-%02d-%02d-%02d-%02d-%02d", nYear, nMonth, nDay, nHour, nMinute, nSecond);
+		
+		m_vecStrGridTimeList.push_back(strTime);
+	}
+}
+
+CgrmGlassRawData g_RawData;
+void CReveiwHistoryDlg::OpenFileHeader(CString strPath, CString strFullPath)
+{
+	if (strPath == "") return;
+	
+	CgrmGlassRawData* pRawData = &g_RawData;
+
+	if (m_vecStrGridReviewList.size() < 1) return;
+
+	CPathSettingDlg* pReivewSetting = CPathSettingDlg::GetMgr();
+	CString strBinPath;
+	strBinPath = pReivewSetting->GetBinPath();
+
+	pRawData->ImportGlassRaw(m_Server.GetGlassRawInfo(), NULL);
+
+	strcpy_s(pRawData->GetGlassData()->m_strFileName,64, strPath.GetBuffer());
+	strcpy_s(pRawData->GetGlassData()->m_strPath,256, strBinPath.GetBuffer());
+
+	BOOL bRetReadBin = m_pGlassRawMaker->ReadBinFile(pRawData);
+
+	m_Formation.AddDefectHeaderTemp();
+	_akReviewHeader* pDefectInfo = &m_Formation.m_vecHeaderTemp[m_Formation.m_vecHeaderTemp.size() - 1];
+
+	pDefectInfo->m_nReviewIdx = 0;
+	pDefectInfo->m_strFileTime = m_vecStrGridTimeList[m_Formation.m_vecHeaderTemp.size() - 1];
+	pDefectInfo->m_strFileName = m_vecStrGridReviewList[m_Formation.m_vecHeaderTemp.size() - 1];
+	pDefectInfo->m_strFilePath = strFullPath;
+
+	if (bRetReadBin == FALSE)
+	{
+		pDefectInfo->m_nDefectIdx = 0;
+		pDefectInfo->m_strGlassID = "";
+		pDefectInfo->m_strPPID = "";
+		pDefectInfo->m_nReviewIdx = 0;
+		pDefectInfo->m_strJudge = "";
+		pDefectInfo->m_strLoading = "X";
+
+		return;
+	}
+
+	pDefectInfo->m_strLoading = "O";
+
+	//pRawData->ExportGlassRaw(m_Server.GetGlassRawInfo(), (char*)m_Server.GetGlassData());
+
+	int nDataCount = pRawData->GetGlassData()->m_nDefectNum;
+
+	_grmDefectData* pDefect;
+	_grmGlassData* pGlass;
+
+	CString strTemp;
+	CString strReviewImageName;
+	for (int i = 0; i < pRawData->GetGlassData()->m_nDefectNum; i++)
+	{		
+		pDefect = pRawData->GetDefectData(i);//m_Server.GetDefectData(i);
+		pGlass = pRawData->GetGlassData(); //m_Server.GetGlassData();
+
+		pDefectInfo->m_nDefectIdx = pGlass->m_nDefectNum;
+		pDefectInfo->m_strGlassID = pGlass->m_strGlassID;
+		pDefectInfo->m_strPPID = pGlass->m_strPPID;
+		pDefectInfo->m_strJudge = pGlass->m_strGlassJudge;
+
+		
+		strReviewImageName = pDefect->m_ReviewDefect.m_strRevImageName;
+
+		if (strReviewImageName == "" || strReviewImageName == "*")
+		{
+			continue;
+		}
+		else
+		{
+			pDefectInfo->m_nReviewIdx = pDefectInfo->m_nReviewIdx + 1;
+		}
+	}
+}
+
+void CReveiwHistoryDlg::BinFileOpen(int nCount)
+{
+   	BOOL bNewFile = TRUE;
+	if (nCount < 1) return;
+
+	if (m_vecStrGridReviewPath.size() <= 0) return;
+
+	if (m_vecStrGridReviewPath[nCount-1] == m_strRawFilePath) bNewFile = FALSE;
+	
+	if (m_Formation.m_vecHeader.size() < 1) return;
+
+	CString strFileName = m_vecStrGridReviewList[nCount-1];
+	CPathSettingDlg* pReivewSetting = CPathSettingDlg::GetMgr();
+	CString strBinPath;
+	strBinPath = pReivewSetting->GetBinPath();
+
+	CgrmGlassRawData RawData;
+
+	RawData.ImportGlassRaw(m_Server.GetGlassRawInfo(), NULL);
+
+	strcpy(RawData.GetGlassData()->m_strFileName, strFileName.GetBuffer());
+	strcpy(RawData.GetGlassData()->m_strPath, strBinPath.GetBuffer());
+
+	BOOL bRetReadBin = m_pGlassRawMaker->ReadBinFile(&RawData);
+
+	CGridCellCheck* pCellCheck = NULL;
+	pCellCheck = (CGridCellCheck*)m_gridReviewList.GetCell(nCount, 0);
+
+	if (bRetReadBin == FALSE)
+	{
+		AfxMessageBox(_T("濡쒕뱶 �떎�뙣 �븯���뒿�땲�떎."), MB_OK | MB_ICONERROR);
+		m_FormationMap.SetAutoScale();
+		LOG(Dbg, _T("[Processe] File Open False"));
+		pCellCheck->SetCheck(FALSE);
+		Imagenoload();
+		return;
+	}
+
+	if (bNewFile && m_chkSingle.GetCheck())
+	{
+		m_FormationMap.m_vecCellRect.clear();
+		m_FormationMap.m_vecTempCellRect.clear();
+		m_FormationMap.clear();
+		m_Formation.Clear();
+		m_Formation.m_vecTempDefects.clear();
+		m_Formation.m_vecTempImage.clear();
+		SetScrollRest();
+	}
+	else if (bNewFile && !m_chkSingle.GetCheck())
+	{
+		if (m_bFirst)
+		{
+			m_bFirst = false;
+			m_FormationMap.m_vecCellRect.clear();
+		}
+		m_FormationMap.clear();
+		m_Formation.m_vecFormation.clear();
+		SetScrollRest();
+	}
+	else if (!bNewFile && !m_chkSingle.GetCheck())
+	{
+		m_FormationMap.clear();
+		m_Formation.m_vecFormation.clear();
+		SetScrollRest();
+	}
+	else
+	{
+		m_FormationMap.clear();
+		m_Formation.m_vecDefects.clear();
+		m_Formation.m_vecFormation.clear();
+		m_Formation.m_vecImage.clear();
+		SetScrollRest();
+	}
+
+	RawData.ExportGlassRaw(m_Server.GetGlassRawInfo(), (char*)m_Server.GetGlassData());
+
+	int nDataCount = RawData.GetGlassData()->m_nDefectNum;
+	int nCellCount = RawData.GetGlassData()->m_nCellNum;
+
+	m_strRawFilePath = m_vecStrGridReviewPath[nCount-1];
+
+	_grmGlassData* pGlass = m_Server.GetGlassData();
+
+	m_FormationMap.m_dGlassSizeWidth = pGlass->m_nGlassSizeWidth / 1000;
+	m_FormationMap.m_dGlassSizeHeight = pGlass->m_nGlassSizeHeight / 1000;
+
+	if (m_bDefectAll == false && m_chkSingle.GetCheck())
+	{
+		AddVecDataDefct(nDataCount);
+	}
+	else if (m_bDefectAll == false && !m_chkSingle.GetCheck())
+	{
+		if(m_Formation.m_vecTempDefects.size() > 0)
+		{ 
+			int nCount2;
+			nCount2 = MultiInsert(nCount, nDataCount);
+			if (nCount2 == -1)
+			{
+				AddVecDataDefct2(nDataCount);
+			}
+		}
+		else
+		{
+			AddVecDataDefct2(nDataCount);
+		}
+		/*AddVecDataDefct2(nDataCount, nCount);*/
+	}
+	else if (m_bDefectAll == true && !m_chkSingle.GetCheck())
+	{
+		if (m_Formation.m_vecTempDefects.size() > 0)
+		{
+			int nCount2;
+			nCount2 = MultiInsert(nCount, nDataCount);
+			if (nCount2 == -1)
+			{
+				AddVecDataDefectAll2(nDataCount);
+			}
+		}
+		else
+		{
+			AddVecDataDefectAll2(nDataCount);
+		}
+		/*AddVecDataDefectAll2(nDataCount, nCount);*/
+	}
+	else
+	{
+		AddVecDataDefectAll(nDataCount);
+	}
+
+	AddVecDataImage(nDataCount);
+	AddVecCellData(nCellCount);
+	AddVecGlassData(nCount);
+
+	AddVecDateSorting(nDataCount);
+	AddVecImageSorting(nDataCount);
+	AddVecCellSorting(nCellCount);
+
+	m_gridDefectInfo.SetRowCount(m_Formation.m_vecDefects.size() + 1);
+	m_gridDefectInfo.Invalidate();
+
+	m_gridGlassInfo.SetRowCount(m_Formation.m_vecGlassInfo.size() + 1);
+	m_gridGlassInfo.Invalidate();
+
+	int nDefectSize = 0;
+	int nImageSize = 0;
+	int nCellSize = 0;
+	int nNext = MAX_COUNT;
+
+	if (m_chkSingle.GetCheck())
+	{
+		m_nDefectSize[0] = GetDefectCount();//m_Formation.m_vecDefects.size();
+		m_nImageSize[0] = GetImageCount();//m_Formation.m_vecImage.size();
+		m_nCellSize[0] = GetCellCount();
+
+		m_nCellSizeTemp[0] = m_nCellSize[0];
+
+		m_nImageCount = 0;
+		m_nDefectCount = 0;
+		m_nCellCount = 0;
+	}
+	else
+	{
+
+		for (int i = 0; i <= MAX_COUNT; i++)
+		{
+			nDefectSize = GetDefectCount();
+			nImageSize = GetImageCount();
+			nCellSize = GetCellCount();
+
+			//1.媛믪쓣 �닚�꽌��濡� �꽔�뒗�떎
+			if (nDefectSize > 0 || nImageSize > 0 || nCellSize > 0)
+			{
+				if (m_nDefectSize[i] == 0 && m_nImageSize[i] == 0 && m_nCellSize[i] == 0)
+				{
+					m_nDefectSize[i] = GetDefectCount();//m_Formation.m_vecDefects.size();
+					m_nImageSize[i] = GetImageCount();//m_Formation.m_vecImage.size();
+					m_nCellSize[i] = GetCellCount();
+
+					m_nImageCount = 0;
+					m_nDefectCount = 0;
+					m_nCellCount = 0;
+					break;
+				}
+			}
+			//2.留덉�留� 媛믪씠硫� 2踰덉㎏媛� 泥ル쾲吏몃줈 �삱由� �썑 �꽔�뒗�떎.
+			if (nNext == i)
+			{
+				for (int j = 0; j < MAX_COUNT; j++)
+				{
+					m_nDefectSize[j] = m_nDefectSize[j + 1];
+					m_nImageSize[j] = m_nImageSize[j + 1];
+					m_nCellSize[j] = m_nCellSize[j + 1];
+					m_nCellSizeTemp[j] = m_nCellSize[j];
+				}
+				m_nDefectSize[i] = GetDefectCount();//m_Formation.m_vecDefects.size();
+				m_nImageSize[i] = GetImageCount();//m_Formation.m_vecImage.size();
+				m_nCellSize[i] = GetCellCount();
+
+				m_nCellSizeTemp[i] = m_nCellSize[i];
+
+				m_nImageCount = 0;
+				m_nDefectCount = 0;
+				m_nCellCount = 0;
+			}
+			//3.以묎컙�뿉 媛믪씠 鍮좎�硫� 以묎컙 踰덉㎏ 媛믪쓣 �삱由� �썑 �꽔�뒗�떎.
+
+
+			// 		if (i != 0) //i媛� 0 �씠 �븘�땲硫� count瑜� �넂�씤�떎.
+			// 		{
+			// 			nDefectSize += m_nDefectSize[i];
+			// 			nImageSize += m_nImageSize[i];
+			// 			nCellSize += m_nCellSize[i];
+			// 		}
+			// 		else if (i == 0 && m_nDefectSize[0] > 0) //i媛� 0�씤�뜲 �뵒�럺�씠 �엳�쑝硫� 移댁슫�꽣瑜� �넂�씤�떎.
+			// 		{
+			// 			nDefectSize += m_nDefectSize[i];
+			// 			nImageSize += m_nImageSize[i];
+			// 			nCellSize += m_nCellSize[i];
+			// 		}
+
+			// 		if (m_nDefectSize[0] == 0)
+			// 		{
+			// 			m_nDefectSize[i] = GetDefectCount();//m_Formation.m_vecDefects.size();
+			// 			m_nImageSize[i] = GetImageCount();//m_Formation.m_vecImage.size();
+			// 			m_nCellSize[i] = GetCellCount();
+			// 
+			// 			m_nImageCount = 0;
+			// 			m_nDefectCount = 0;
+			// 			m_nCellCount = 0;
+			// 			break;
+			// 		}
+			// 		else if(i != 0 && m_nDefectSize[i] == 0)
+			// 		{
+			// 			m_nDefectSize[i] = GetDefectCount(); //m_Formation.m_vecDefects.size() - nDefectSize;
+			// 			m_nImageSize[i] = GetImageCount(); //m_Formation.m_vecImage.size() - nImageSize;
+			// 			m_nCellSize[i] = GetCellCount();
+			// 
+			// 			m_nImageCount = 0;
+			// 			m_nDefectCount = 0;
+			// 			m_nCellCount = 0;
+			// 			break;
+			// 		}
+		}
+	}
+
+	m_FormationMap.m_pDefectFormation = &m_Formation;
+	m_DefectDisplayOption.m_nShowLabel = -1;
+	m_FormationMap.m_pDefectDisplayOption = &m_DefectDisplayOption;
+
+	CAlignDlg* lpDlg = CAlignDlg::GetMgr();
+	lpDlg->m_pDefectFormation = &m_Formation;
+	lpDlg->m_pDefectDisplayOption = &m_DefectDisplayOption;
+	
+	if(bNewFile) m_FormationMap.SetAutoScale();
+	else m_FormationMap.ReDraw(TRUE);
+
+	int nDefectNum = m_Server.GetGlassData()->m_nDefectNum;
+	int nNoneGroupDefect = m_Formation.m_vecImage.size();
+
+	if (m_Formation.m_vecImage.size() > 0)
+	{
+		SetScrollSetting();
+	}
+}
+
+void CReveiwHistoryDlg::OnCbnSelchangeComboRawtype()
+{
+	CGlassRawBase* pNewRawMaker = NULL;
+
+	pNewRawMaker = new CGlassRawCPJT;
+
+	if (m_pGlassRawMaker) delete m_pGlassRawMaker;
+
+	m_pGlassRawMaker = pNewRawMaker;
+
+	m_ConfigOption.m_nSelectRawType = 3;
+
+}
+
+void CReveiwHistoryDlg::OnBnClickedBtnFindBin()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	
+
+	m_vecStrGridReviewList.clear();
+	m_vecStrGridTimeList.clear();
+	m_vecStrGridReviewPath.clear();
+	m_Formation.m_vecHeader.clear();
+	m_FormationMap.clear();
+	m_Formation.Clear();
+	GlassInfoRest();
+
+// 	m_ProgressFile.ModifyStyle(0, PBS_MARQUEE);
+// 	m_ProgressFile.ShowWindow(TRUE);
+// 	pProgressBar->SetMarquee(TRUE, 30);
+
+	
+	CPathSettingDlg* pReivewSetting = CPathSettingDlg::GetMgr();
+	CString strBinPath;
+	strBinPath = pReivewSetting->GetBinPath();
+
+	if (strBinPath == "")
+	{
+		return;
+	}
+	strBinPath += _T("\\*.*");
+
+	CFileFind finder;
+	BOOL bWorking = finder.FindFile(strBinPath);
+
+// 	CakFileUtil akFile;
+// 	akFile.FindFile(strBinPath.GetBuffer());
+// 	VECFINDDATA* pVecFindData = akFile.getFindData();
+// 	
+// 	for (int i = 0; i < pVecFindData->size(); i++)
+// 	{
+// 		_DefectList akDefect;
+// 		m_vecStrDefectList.push_back(akDefect);
+// 		_DefectList* pDefectList = &m_vecStrDefectList[i];
+// 		
+// 		
+// 		TRACE("Craete Time : %d, %s \n", (*pVecFindData)[i].time_create, (*pVecFindData)[i].name);
+// 		pDefectList->m_nFileTime = (*pVecFindData)[i].time_create;
+// 		pDefectList->m_strFileName = (*pVecFindData)[i].name;
+// // 		m_vecStrGridReviewList.push_back((*pVecFindData)[i].name);
+// // 		m_vecStrGridTimeList.push_back((*pVecFindData)[i].time_create;
+// 		OpenFileHeader((*pVecFindData)[i].name);
+// 	}
+
+	
+
+	CString fileName;
+	CString DirName;
+	int nCount = 1;
+	m_ctlProgress.ShowWindow(TRUE);
+	int nPersent = 0;
+
+	while (bWorking)
+	{
+		m_ctlProgress.SetPos(nPersent);
+		nPersent++;
+
+		if (nPersent >= 100)
+		{
+			nPersent = 0;
+		}
+
+		//�떎�쓬 �뙆�씪 / �뤃�뜑 媛� 議댁옱�븯硫대떎硫� TRUE 諛섑솚
+		bWorking = finder.FindNextFile();
+		//�뙆�씪 �씪�븣
+		if (finder.IsArchived())
+		{
+			//�뙆�씪�쓽 �씠由�
+			CString _fileName = finder.GetFileName();
+
+			// �쁽�옱�뤃�뜑 �긽�쐞�뤃�뜑 �뜽�꽕�씪�뙆�씪�� �젣�쇅
+			if (_fileName == _T(".") ||
+				_fileName == _T("..") ||
+				_fileName == _T("Thumbs.db")) continue;
+
+			CString strFindName = ".bin";
+			CString strFileName, strFileName2;
+			strFileName = _fileName.Right(4); //bin �뙆�씪留�
+
+			if (strFileName.Compare(strFindName) == 0)
+			{
+				/*if(nCount > m_nFileCount) break; //count �뿬湲곗꽌 留먭퀬 �쟾泥� �뙆�씪�쓣 �떎 �씫�� �썑�뿉 �떎�떆 �냼�똿�븯�옄*/
+				m_vecStrGridReviewList.push_back(_fileName);
+				strFileName2 = strBinPath.Left(strBinPath.GetLength() - 3);
+				strFileName2 += _fileName;
+				m_vecStrGridReviewPath.push_back(strFileName2);
+				FileTime(strFileName2);
+				OpenFileHeader(_fileName, strFileName2);
+				/*nCount++;*/
+			}
+		}
+	}
+
+	//�뿬湲곗뿉�꽌 �옱 �냼�똿 �썑�뿉 �븘�슂�븳 留뚰겮留� �꽔�옄
+	{
+		//vec瑜� �젙�젹 �븳�떎.
+		SortFileList(1);
+		//媛��닔留뚰겮留� 蹂듭궗瑜� �븳�떎
+		//蹂듭궗�븳 寃껋쓣 �꽔�뒗�떎.
+		
+	}
+ 	CGridCellCheck* pCellCheck = NULL;
+// 
+// 	m_gridReviewList.SetCellType(1, 0, RUNTIME_CLASS(CGridCellCheck));
+// 
+ 	m_gridReviewList.SetRowCount(m_Formation.m_vecHeader.size() + 1);
+
+	{
+		GV_ITEM Item;
+		int nRowIdx = 0;
+		int nColIdx = 0;
+		CString strTemp;
+		Item.mask = GVIF_TEXT;
+
+		_akReviewHeader	*pReview = NULL;
+
+		for (int i = 0; i < m_Formation.m_vecHeader.size(); i++)
+		{
+			m_gridReviewList.SetCellType(i + 1, 0, RUNTIME_CLASS(CGridCellCheck));
+			
+// 			pCellCheck = (CGridCellCheck*)m_ctrlGridGlassList.GetCell(nRowIdx, nColIdx);
+// 			
+// 			pCellCheck->SetCheck();
+
+			nColIdx = 0;
+			pReview = &m_Formation.m_vecHeader[i];
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%d"), i + 1);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%s"), pReview->m_strFileTime);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%s"), pReview->m_strLoading);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%s"), pReview->m_strPPID);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%s"), pReview->m_strGlassID);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%d"), pReview->m_nDefectIdx);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%d"), pReview->m_nReviewIdx);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%s"), pReview->m_strJudge);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+
+			Item.row = i + 1;
+			Item.col = nColIdx++;
+			strTemp.Format(_T("%s"), pReview->m_strFileName);
+			Item.strText = strTemp;
+			m_gridReviewList.SetItem(&Item);
+		}
+
+	}
+	m_gridReviewList.Invalidate();
+
+	m_ctlProgress.ShowWindow(FALSE);
+}
+
+void CReveiwHistoryDlg::ShowProgressBar()
+{
+
+}
+
+void CReveiwHistoryDlg::setDefectShow(int nDefectID, BOOL bEnsureVisible)
+{
+	const int nDefectCol = 1;
+
+	if (nDefectID >= 0)
+	{
+		int sajfklwe;
+		sajfklwe = m_gridDefectInfo.GetColumnCount();
+		if (m_nSelectedRow > m_gridDefectInfo.GetColumnCount())
+		{
+			m_nSelectedRow = 0;
+		}
+
+		if(!m_bDefectAll)
+		{
+			if (m_nSelectedRow > m_Formation.m_vecImage.size())
+			{
+				m_nSelectedRow = 0;
+			}
+		}
+		int iRow = m_nSelectedRow;
+
+		for (int iCol = 0; iCol < m_gridDefectInfo.GetColumnCount(); iCol++)
+		{
+			m_gridDefectInfo.SetItemState(iRow, iCol, m_gridDefectInfo.GetItemState(iRow, iCol) & ~GVIS_SELECTED);
+		}
+	}
+
+	for (int i = 0; i < m_Formation.m_vecDefects.size(); i++)
+	{
+		_akDefect* pDefectInfo = &m_Formation.m_vecDefects[i];
+
+		if (pDefectInfo == NULL)
+			return;
+
+		if (pDefectInfo->m_nDefectID == nDefectID)
+		{
+			int iRow = i + 1;
+			for (int iCol = 0; iCol < m_gridDefectInfo.GetColumnCount(); iCol++)
+			{
+				m_gridDefectInfo.SetItemState(iRow, iCol, LVIS_SELECTED);
+			}
+			m_nSelectedRow = iRow;
+			if (bEnsureVisible)
+			{
+				m_gridDefectInfo.EnsureVisible(iRow, m_nSelectedCol);
+			}
+			break;
+		}
+	}
+
+	m_gridDefectInfo.Invalidate();
+}
+
+void CReveiwHistoryDlg::ImageShow(int nDefectID)
+{
+	CPaintDC dc(this);
+
+	if (nDefectID < 0) return;
+
+	m_DefectImage.Destroy();
+	m_ReviewImage.Destroy();
+
+	m_AlignFirst.Destroy();
+	m_AlignSecend.Destroy();
+
+	CString DeftectPath, DeftectPath2, AlignPath, AlignPath2;
+	CFileStatus FileOn;
+	TCHAR chFilePath[256] = { 0, };
+	GetModuleFileName(NULL, chFilePath, 256);
+	if (chFilePath == NULL || chFilePath == "") return;
+
+	CString strFolderPath(chFilePath);
+	strFolderPath = strFolderPath.Left(strFolderPath.ReverseFind('\\'));
+
+	strFolderPath = strFolderPath + "\\no-image.png";
+
+
+	//DefectData媛� 吏�湲� �꽑�깮�맂 DefectData瑜� 媛��졇 �삩�떎. �씠嫄� �닔�젙...
+
+// 	_grmDefectData* pDefect = m_Server.GetDefectData(nDefectID);
+// 	_grmGlassData* pGlass = m_Server.GetGlassData();
+	int nIndex = 0;
+	//�뵒�럺 �씤�뜳�뒪�� 媛숈� �냸�쓣 李얠븘�씪
+	for (int i = 0; i < m_Formation.m_vecImage.size(); i++)
+	{
+		_akReviewList* pImage = NULL;
+		pImage = &m_Formation.m_vecImage[i];
+
+		if (!m_bDefectAll)
+		{
+			nIndex = nDefectID;
+			break;
+		}
+		else
+		{
+			if (pImage->m_nDefectID == nDefectID)
+			{
+				nIndex = i;
+				break;
+			}
+		}
+	}
+	_akReviewList* pImageInfo = &m_Formation.m_vecImage[nIndex];
+	//紐� 踰덉㎏ �씤吏� �뜕吏꾨떎.
+
+	CString wekfjlwe = pImageInfo->m_strReviewImageName;
+	CString wjkflwe = pImageInfo->m_strAoiImageName;
+	CString jkefawlj = pImageInfo->m_strReviewImagePath;
+	//�빐�떦 count瑜� �샇異� �븳�떎.
+	//�뙆�씪 �씠誘몄�瑜� 遺덈윭 �삩�떎
+	//�몴�쁽�븳�떎.
+
+
+/*	if (pGlass == NULL) return;*/
+
+	//_akReviewList* pDfect2 = &m_Formation.m_vecImage[nDefectID];
+
+// 	CString wefjklwef;
+// 	wefjklwef = pDfect2->m_strRevewImageName;
+
+ 	CString strReviewImageName, strInspectorName, strReviewImagePath, strAlignName, strAlignName2;
+// 	strReviewImageName = pDefect->m_ReviewDefect.m_strRevImageName;
+// 	strInspectorName = pDefect->m_strAoiImageName;
+// 	strReviewImagePath = pDefect->m_ReviewDefect.m_strRevImagePath;
+
+/*	pDefect->m_ReviewDefect.m_strRevImagePath*/
+
+	strReviewImageName = wekfjlwe;
+	strInspectorName = wjkflwe;
+	strReviewImagePath = jkefawlj;
+	strAlignName = pImageInfo->m_strAlignFirst; //Glass 媛� 媛��졇���씪
+	strAlignName2 = pImageInfo->m_strAlignSecond;
+
+// 	strAlignName.Format(_T("1.jpg"));
+// 	strAlignName2.Format(_T("2.jpg"));
+
+	CString strReviewPath;
+	CString strInspectorPath;
+	CString strAlignPath;
+
+	CPathSettingDlg* lpDlg = CPathSettingDlg::GetMgr();
+	strInspectorPath = lpDlg->GetInspectorPath();
+	strReviewPath = lpDlg->GetReviewPath();
+	strAlignPath = lpDlg->GetAlignPath();
+
+	DeftectPath.Format(_T("%s\\%s\\%s"), strReviewPath, strReviewImagePath, strReviewImageName);
+	//DeftectPath2.Format(_T("%s\\%s"), strInspectorPath, strInspectorName);
+	if (strInspectorName == "*" || strInspectorName == "**" || strInspectorName == "***") strInspectorName = "";
+	DeftectPath2.Format(_T("%s\\%s\\%s"), strInspectorPath, pImageInfo->m_strGlassID, strReviewImageName);
+
+	AlignPath.Format(_T("%s\\%s\\%s"), strAlignPath, pImageInfo->m_strGlassID, strAlignName);
+	AlignPath2.Format(_T("%s\\%s\\%s"), strAlignPath, pImageInfo->m_strGlassID, strAlignName2);
+
+	if (CFile::GetStatus(DeftectPath, FileOn) && strReviewImageName != "") //�뙆�씪�씠 �엳�쓣 �븣
+	{
+		CString strTest;
+		strTest = DeftectPath;
+		strcpy(m_strConfigFile, strTest.GetBuffer(0));
+		m_ImageView.SetImageData(m_strConfigFile);
+		m_ImageView.ReDraw();
+// 		m_ReviewImage.Load(DeftectPath);
+// 		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), DeftectPath,
+// 			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+// 
+// 
+// 		InvalidateRect(m_picture_rect, FALSE);
+// 		dc.SetStretchBltMode(COLORONCOLOR);
+// 		m_ReviewImage.Draw(dc, m_picture_rect);
+	}
+	else
+	{
+		CString strTest;
+		strTest = strFolderPath;
+		strcpy(m_strConfigFile, strTest.GetBuffer(0));
+		m_ImageView.SetImageData(m_strConfigFile);
+		m_ImageView.ReDraw();
+
+// 		m_ReviewImage.Load(strFolderPath);
+// 		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strFolderPath,
+// 			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+// 
+// 		InvalidateRect(m_picture_rect, FALSE);
+// 		dc.SetStretchBltMode(COLORONCOLOR);
+// 		m_ReviewImage.Draw(dc, m_picture_rect);
+	}
+
+	if (CFile::GetStatus(DeftectPath2, FileOn) && strInspectorName != "") //�뙆�씪�씠 �엳�쓣 �븣
+	{
+		m_DefectImage.Load(DeftectPath2);
+		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), DeftectPath2,
+			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+
+		InvalidateRect(m_picture_rect2, FALSE);
+		dc.SetStretchBltMode(COLORONCOLOR);
+		m_DefectImage.Draw(dc, m_picture_rect2);
+	}
+	else
+	{
+		m_DefectImage.Load(strFolderPath);
+		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strFolderPath,
+			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+		InvalidateRect(m_picture_rect2, FALSE);
+		dc.SetStretchBltMode(COLORONCOLOR);
+		m_DefectImage.Draw(dc, m_picture_rect2);
+	}
+
+	if (CFile::GetStatus(AlignPath, FileOn) && strAlignName != "") //�뙆�씪�씠 �엳�쓣 �븣
+	{
+		m_AlignFirst.Load(AlignPath);
+		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), AlignPath,
+			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+
+		InvalidateRect(m_Align_rect, FALSE);
+		dc.SetStretchBltMode(COLORONCOLOR);
+		m_AlignFirst.Draw(dc, m_Align_rect);
+	}
+	else
+	{
+		m_AlignFirst.Load(strFolderPath);
+		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strFolderPath,
+			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+		InvalidateRect(m_Align_rect, FALSE);
+		dc.SetStretchBltMode(COLORONCOLOR);
+		m_AlignFirst.Draw(dc, m_Align_rect);
+	}
+
+	if (CFile::GetStatus(AlignPath2, FileOn) && strAlignName2 != "") //�뙆�씪�씠 �엳�쓣 �븣
+	{
+		m_AlignSecend.Load(AlignPath2);
+		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), AlignPath2,
+			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+
+		InvalidateRect(m_Align_rect2, FALSE);
+		dc.SetStretchBltMode(COLORONCOLOR);
+		m_AlignSecend.Draw(dc, m_Align_rect2);
+	}
+	else
+	{
+		m_AlignSecend.Load(strFolderPath);
+		HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strFolderPath,
+			IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+		InvalidateRect(m_Align_rect2, FALSE);
+		dc.SetStretchBltMode(COLORONCOLOR);
+		m_AlignSecend.Draw(dc, m_Align_rect2);
+	}
+}
+
+void CReveiwHistoryDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
+{
+	// TODO: �뿬湲곗뿉 硫붿떆吏� 泥섎━湲� 肄붾뱶瑜� 異붽� 諛�/�삉�뒗 湲곕낯媛믪쓣 �샇異쒗빀�땲�떎.
+	if (IDC_SLIDER_IMG == pScrollBar->GetDlgCtrlID())
+	{
+		int nCount = m_sldImg.GetPos();
+
+		CString strPos;
+		strPos.Format(_T("%d"), nCount);
+		m_ctrCount.SetWindowText(strPos);
+		
+		if (nCount > -1)
+		{
+			if (m_Formation.m_vecImage.size() <= 0)
+			{
+				SetScrollRest();
+				return;
+			}
+			_akReviewList* pImageInfo = &m_Formation.m_vecImage[nCount];
+
+			m_FormationMap.setSelectDefect(pImageInfo->m_nDefectID);
+			//ImageShow(pImageInfo->m_nDefectID);
+			setDefectShow(pImageInfo->m_nDefectID, 1);
+		}
+	}
+}
+
+
+void CReveiwHistoryDlg::OnChangeEditCount()
+{
+	// TODO:  RICHEDIT 而⑦듃濡ㅼ씤 寃쎌슦, �씠 而⑦듃濡ㅼ�
+	// CDialogEx::OnInitDialog() �븿�닔瑜� �옱吏��젙 
+	//�븯怨� 留덉뒪�겕�뿉 OR �뿰�궛�븯�뿬 �꽕�젙�맂 ENM_CHANGE �뵆�옒洹몃�� 吏��젙�븯�뿬 CRichEditCtrl().SetEventMask()瑜� �샇異쒗븯吏� �븡�쑝硫�
+	// �씠 �븣由� 硫붿떆吏�瑜� 蹂대궡吏� �븡�뒿�땲�떎.
+
+	// TODO:  �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+
+	CString strPos;
+	m_ctrCount.GetWindowText(strPos);
+
+	if (strPos == "") return;
+
+	int nPos = _ttoi(strPos);
+
+	if (nPos < -1)
+	{
+		m_ctrCount.SetWindowText(0);
+		nPos = 0;
+	}
+	else if (nPos > m_Formation.m_vecImage.size()-1)
+	{
+		nPos = m_Formation.m_vecImage.size() - 1;
+		CString strCount;
+		strCount.Format(_T("%d"),nPos);
+		m_ctrCount.SetWindowText(strCount);
+	}
+
+	m_sldImg.SetPos(nPos);
+
+	if (nPos > -1)
+	{
+		if (m_Formation.m_vecImage.size() <= 0)
+		{
+			SetScrollRest();
+			return;
+		}
+		_akReviewList* pImageInfo = &m_Formation.m_vecImage[nPos];
+
+		m_FormationMap.setSelectDefect(pImageInfo->m_nDefectID);
+		//ImageShow(pImageInfo->m_nDefectID/*nPos*/);
+		ImageShow(nPos);
+		setDefectShow(pImageInfo->m_nDefectID, 1);
+	}
+}
+
+void CReveiwHistoryDlg::SetScrollSetting()
+{
+	if (m_Formation.m_vecImage.size() <= 0) return;
+	_akReviewList* pImageInfo = &m_Formation.m_vecImage[m_Formation.m_vecImage.size() - 1];
+
+	int nMinRange = m_Formation.m_vecImage.size()*0.03, nMaxRange = m_Formation.m_vecImage.size()*0.1;
+
+	if (nMinRange <= 0) nMinRange = 1;
+	if (nMaxRange <= 0) nMaxRange = 1;
+
+	m_sldImg.SetRange(0, m_Formation.m_vecImage.size()-1); //踰붿쐞 �꽕�젙 理쒕� �씠誘몄� 媛��닔
+	m_sldImg.SetPos(0); //�쁽�옱 �룷吏��뀡
+	m_sldImg.SetLineSize(nMinRange); //�씠�룞�븷 踰붿쐞 3%
+	m_sldImg.SetPageSize(nMaxRange); //�럹�씠吏� �뾽�떎�슫 �씠�룞 踰붿쐞 踰붿쐞 10%
+
+	int nPos = m_sldImg.GetPos();
+	CString strPos;
+	strPos.Format(_T("%d"), nPos);
+	m_ctrCount.SetWindowText(strPos);
+}
+
+void CReveiwHistoryDlg::SetScrollRest()
+{
+	m_sldImg.SetRange(-1, -1);
+	m_sldImg.SetPos(-1);
+	m_sldImg.SetLineSize(3); 
+	m_sldImg.SetPageSize(10);
+
+	int nPos = m_sldImg.GetPos();
+	CString strPos;
+	strPos.Format(_T("%d"), nPos);
+	m_ctrCount.SetWindowText(strPos);
+}
+
+void CReveiwHistoryDlg::OnBnClickedButton3()
+{
+// 	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+// 	CPaintDC dc(this);
+// 	HDC hMemDC;
+// 
+// 	hMemDC = CreateCompatibleDC(dc);
+// 	
+// 	m_DefectImage.Destroy();
+// 
+// 	CString DeftectPath;
+// 	CFileStatus FileOn;
+// 	TCHAR chFilePath[256] = { 0, };
+// 	GetModuleFileName(NULL, chFilePath, 256);
+// 	CString strFolderPath(chFilePath);
+// 	strFolderPath = strFolderPath.Left(strFolderPath.ReverseFind('\\'));
+// 
+// 	strFolderPath = strFolderPath + "\\no-image.png";
+// 	m_DefectImage.Load(strFolderPath);
+// 
+// 	HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strFolderPath,
+// 		IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+// 
+// 	InvalidateRect(m_picture_rect, FALSE);
+// 
+// 	dc.SetStretchBltMode(COLORONCOLOR);
+// 	//StretchBlt(dc, 500, 400, 300, 200, hMemDC, 105, 105, 120, 123, SRCCOPY);
+// 	//m_DefectImage.StretchBlt(dc, 0, 0, 100, 100, SRCCOPY);
+// 	m_DefectImage.StretchBlt(dc, 0, 0, 500, 200, SRCCOPY);
+// 	m_DefectImage.Draw(dc, m_picture_rect);
+}
+
+
+void CReveiwHistoryDlg::OnClickedChkAllDefect()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	if (m_chkAllDefect.GetCheck())
+	{
+		if (IDYES == AfxMessageBox(_T("�젙�젹�븳 媛믪씠 紐⑤몢 珥덇린�솕 �맗�땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkAllDefect.SetCheck(TRUE);
+			m_chkReviewDefect.SetCheck(FALSE);
+			OnViewAlldefect();
+		}
+		else
+		{
+			m_chkAllDefect.SetCheck(FALSE);
+			m_chkReviewDefect.SetCheck(TRUE);
+		}		
+	}
+	else
+	{
+		if (IDYES == AfxMessageBox(_T("�젙�젹�븳 媛믪씠 紐⑤몢 珥덇린�솕 �맗�땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkAllDefect.SetCheck(FALSE);
+			m_chkReviewDefect.SetCheck(TRUE);
+			OnViewReviewdefect();
+		}
+		else
+		{
+			m_chkAllDefect.SetCheck(TRUE);
+			m_chkReviewDefect.SetCheck(FALSE);
+		}
+	}
+}
+
+void CReveiwHistoryDlg::OnClickedChkReviewDefect()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	if (m_chkReviewDefect.GetCheck())
+	{
+		if (IDYES == AfxMessageBox(_T("�젙�젹�븳 媛믪씠 紐⑤몢 珥덇린�솕 �맗�땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkAllDefect.SetCheck(FALSE);
+			m_chkReviewDefect.SetCheck(TRUE);
+			OnViewAlldefect();
+		}
+		else
+		{
+			m_chkAllDefect.SetCheck(TRUE);
+			m_chkReviewDefect.SetCheck(FALSE);
+		}
+	}
+	else
+	{
+		if (IDYES == AfxMessageBox(_T("�젙�젹�븳 媛믪씠 紐⑤몢 珥덇린�솕 �맗�땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkAllDefect.SetCheck(TRUE);
+			m_chkReviewDefect.SetCheck(FALSE);
+			OnViewReviewdefect();
+		}
+		else
+		{
+			m_chkAllDefect.SetCheck(FALSE);
+			m_chkReviewDefect.SetCheck(TRUE);
+		}
+	}
+}
+
+void CReveiwHistoryDlg::OnClickedChkMuti()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	if (m_chkMuti.GetCheck())
+	{
+		if (IDYES == AfxMessageBox(_T("�꽑�깮�븳 �빆紐� 紐⑤몢媛� 吏��썙 吏묐땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkSingle.SetCheck(FALSE);
+			m_chkMuti.SetCheck(TRUE);
+
+			GlassInfoRest();
+			for (int i = 0; i < 105; i++)
+			{
+				m_nSelectFile[i] = 0;
+				m_nDefectSize[i] = 0;
+				m_nCellSize[i] = 0;
+				m_nImageSize[i] = 0;
+				m_nCellSizeTemp[i] = m_nCellSize[i];
+			}
+			m_Formation.Clear();
+			m_bFirst = true;
+		}
+		else
+		{
+			m_chkSingle.SetCheck(TRUE);
+			m_chkMuti.SetCheck(FALSE);
+		}
+	}
+	else
+	{
+		if (IDYES == AfxMessageBox(_T("�꽑�깮�븳 �빆紐� 紐⑤몢媛� 吏��썙 吏묐땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkSingle.SetCheck(TRUE);
+			m_chkMuti.SetCheck(FALSE);
+			GlassInfoRest();
+		}
+		else
+		{
+			m_chkSingle.SetCheck(FALSE);
+			m_chkMuti.SetCheck(TRUE);
+			GlassInfoRest();
+			for (int i = 0; i < 105; i++)
+			{
+				m_nSelectFile[i] = 0;
+				m_nDefectSize[i] = 0;
+				m_nCellSize[i] = 0;
+				m_nImageSize[i] = 0;
+				m_nCellSizeTemp[i] = m_nCellSize[i];
+			}
+			m_Formation.Clear();
+		}
+	}
+}
+
+void CReveiwHistoryDlg::OnClickedChkSingle()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	if (m_chkSingle.GetCheck())
+	{
+		if (IDYES == AfxMessageBox(_T("�꽑�깮�븳 �빆紐� 紐⑤몢媛� 吏��썙 吏묐땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkMuti.SetCheck(FALSE);
+			m_chkSingle.SetCheck(TRUE);
+			GlassInfoRest();
+
+			int nRow = 0;
+			nRow = m_gridReviewList.GetRowCount();
+			for (int i = 1; i < nRow; i++)
+			{
+				CGridCellCheck* pCellCheck = NULL;
+				pCellCheck = (CGridCellCheck*)m_gridReviewList.GetCell(i, 0);
+				pCellCheck->SetCheck(FALSE);
+			}
+			m_gridReviewList.Refresh();
+		}
+		else
+		{
+			m_chkSingle.SetCheck(FALSE);
+			m_chkMuti.SetCheck(TRUE);
+			GlassInfoRest();
+			for (int i = 0; i < 105; i++)
+			{
+				m_nSelectFile[i] = 0;
+				m_nDefectSize[i] = 0;
+				m_nCellSize[i] = 0;
+				m_nImageSize[i] = 0;
+				m_nCellSizeTemp[i] = m_nCellSize[i];
+			}
+		}
+	}
+	else
+	{
+		if (IDYES == AfxMessageBox(_T("�꽑�깮�븳 �빆紐� 紐⑤몢媛� 吏��썙 吏묐땲�떎"), MB_YESNO | MB_ICONWARNING))
+		{
+			m_chkMuti.SetCheck(TRUE);
+			m_chkSingle.SetCheck(FALSE);
+			GlassInfoRest();
+			for (int i = 0; i < 105; i++)
+			{
+				m_nSelectFile[i] = 0;
+				m_nDefectSize[i] = 0;
+				m_nCellSize[i] = 0;
+				m_nImageSize[i] = 0;
+				m_nCellSizeTemp[i] = m_nCellSize[i];
+			}
+			m_bFirst = true;
+		}
+		else
+		{
+			m_chkMuti.SetCheck(FALSE);
+			m_chkSingle.SetCheck(TRUE);
+		}
+	}
+}
+
+void CReveiwHistoryDlg::Imagenoload()
+{
+	// TODO: �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CPaintDC dc(this);
+
+//	m_ReviewImage.Destroy();
+	m_DefectImage.Destroy();
+	m_AlignFirst.Destroy();
+	m_AlignSecend.Destroy();
+
+	CString DeftectPath;
+	CFileStatus FileOn;
+	TCHAR chFilePath[256] = { 0, };
+	GetModuleFileName(NULL, chFilePath, 256);
+	CString strFolderPath(chFilePath);
+	strFolderPath = strFolderPath.Left(strFolderPath.ReverseFind('\\'));
+
+	strFolderPath = strFolderPath + "\\no-image.png";
+
+	strcpy(m_strConfigFile, strFolderPath.GetBuffer(0));
+
+	m_ImageView.SetImageData(m_strConfigFile);
+//	m_ReviewImage.Load(strFolderPath);
+	m_DefectImage.Load(strFolderPath);
+	m_AlignFirst.Load(strFolderPath);
+	m_AlignSecend.Load(strFolderPath);
+
+	HBITMAP hBmp = (HBITMAP)::LoadImage(AfxGetInstanceHandle(), strFolderPath,
+		IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE | LR_CREATEDIBSECTION);
+
+//	InvalidateRect(m_picture_rect, FALSE);
+	InvalidateRect(m_picture_rect2, FALSE);
+	InvalidateRect(m_Align_rect, FALSE);
+	InvalidateRect(m_Align_rect2, FALSE);
+
+	dc.SetStretchBltMode(COLORONCOLOR);
+
+	m_ImageView.ReDraw();
+//	m_ReviewImage.Draw(dc, m_picture_rect);
+	m_DefectImage.Draw(dc, m_picture_rect2);
+	m_AlignFirst.Draw(dc, m_Align_rect);
+	m_AlignSecend.Draw(dc, m_Align_rect2);
+}
+
+void CReveiwHistoryDlg::OnChangeEditFileCount()
+{
+	// TODO:  RICHEDIT 而⑦듃濡ㅼ씤 寃쎌슦, �씠 而⑦듃濡ㅼ�
+	// CDialogEx::OnInitDialog() �븿�닔瑜� �옱吏��젙 
+	//�븯怨� 留덉뒪�겕�뿉 OR �뿰�궛�븯�뿬 �꽕�젙�맂 ENM_CHANGE �뵆�옒洹몃�� 吏��젙�븯�뿬 CRichEditCtrl().SetEventMask()瑜� �샇異쒗븯吏� �븡�쑝硫�
+	// �씠 �븣由� 硫붿떆吏�瑜� 蹂대궡吏� �븡�뒿�땲�떎.
+
+	// TODO:  �뿬湲곗뿉 而⑦듃濡� �븣由� 泥섎━湲� 肄붾뱶瑜� 異붽��빀�땲�떎.
+	CString strCount;
+	m_ctlFileCount.GetWindowText(strCount);
+	m_nFileCount = _ttoi(strCount);
+}
+
+BOOL CReveiwHistoryDlg::GetCheckFileLoad(int nCount)
+{
+	BOOL bNewFile = TRUE;
+	if (nCount == 0) return FALSE;
+
+	if (m_vecStrGridReviewPath.size() <= 0) return FALSE;
+
+	if (m_vecStrGridReviewPath[nCount - 1] == m_strRawFilePath) bNewFile = FALSE;
+
+	if (m_vecStrGridReviewList.size() < 1) return FALSE;
+
+	CString strFileName = m_vecStrGridReviewList[nCount - 1];
+	CPathSettingDlg* pReivewSetting = CPathSettingDlg::GetMgr();
+	CString strBinPath;
+	strBinPath = pReivewSetting->GetBinPath();
+
+	CgrmGlassRawData RawData;
+
+	RawData.ImportGlassRaw(m_Server.GetGlassRawInfo(), NULL);
+
+	strcpy(RawData.GetGlassData()->m_strFileName, strFileName.GetBuffer());
+	strcpy(RawData.GetGlassData()->m_strPath, strBinPath.GetBuffer());
+
+	BOOL bRetReadBin = m_pGlassRawMaker->ReadBinFile(&RawData);
+
+	if (bRetReadBin == FALSE)
+	{
+		m_FormationMap.SetAutoScale();
+		LOG(Dbg, _T("[Processe] File Open False"));
+		Imagenoload();
+		return FALSE;
+	}
+	return TRUE;
+}
+
+void CReveiwHistoryDlg::GlassInfoRest()
+{
+	m_Formation.m_vecGlassInfo.clear();
+
+	for (int i = 0; i < 105; i++)
+	{
+		m_nSelectFile[i] = 0;
+		m_nDefectSize[i] = 0;
+		m_nImageSize[i] = 0;
+	}
+	m_gridGlassInfo.SetRowCount(2);
+	m_gridGlassInfo.Invalidate();
+}
+
+BOOL CReveiwHistoryDlg::MultiSelectCheck(int nSelectCount)
+{
+	if (nSelectCount <= 0) return FALSE;
+
+	//if (m_Formation.m_vecGlassInfo.size() > MAX_COUNT) return FALSE;
+
+	int nDefectSize = 0;
+	int nImageSize = 0;
+	int nCellSize = 0;
+
+	for (int i = 0; i < MAX_COUNT+1; i++)
+	{
+		nDefectSize += m_nDefectSize[i];
+		nImageSize += m_nImageSize[i];
+		nCellSize += m_nCellSize[i];
+
+		if (nSelectCount == m_nSelectFile[i])
+		{
+			for (int j = 0; j < m_Formation.m_vecGlassInfo.size(); j++)
+			{
+				_akGlassInfo* pGlassInfo = &m_Formation.m_vecGlassInfo[j];
+
+				if (pGlassInfo->m_nGlassSelect == m_nSelectFile[i])
+				{
+					m_Formation.m_vecGlassInfo.erase(m_Formation.m_vecGlassInfo.begin() + j);
+
+ 					if (i == 0)
+					{
+						m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin(), m_Formation.m_vecDefects.begin() + m_nDefectSize[i]);
+						m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin(), m_Formation.m_vecImage.begin() + m_nImageSize[i]);
+						m_FormationMap.m_vecCellRect.erase(m_FormationMap.m_vecCellRect.begin(), m_FormationMap.m_vecCellRect.begin() + m_nCellSize[i]);
+						m_nCellSize[i] = 0;
+						m_nDefectSize[i] = 0;
+						m_nImageSize[i] = 0;
+					}
+					else if (i != 0 && m_nDefectSize[i] == 0)
+					{
+
+					}
+					else if (i != 0 && m_nDefectSize[i] > 0)
+					{
+						if (m_Formation.m_vecDefects.size() == nDefectSize)
+						{
+							m_Formation.m_vecDefects.clear();
+							//m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin(), m_Formation.m_vecDefects.begin() + m_nDefectSize[i]);
+						}
+// 						else
+// 						{
+// 							m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin() + nDefectSize-1, m_Formation.m_vecDefects.begin() + nDefectSize-1 + m_nDefectSize[i]);
+// 						}
+						if (m_Formation.m_vecImage.size() == nImageSize)
+						{
+							m_Formation.m_vecImage.clear();
+							//m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin(), m_Formation.m_vecImage.begin() + m_nImageSize[i]);
+						}
+// 						else
+// 						{
+// 							m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin() + nImageSize-1, m_Formation.m_vecImage.begin() + nImageSize-1 + m_nImageSize[i]);
+// 						}
+						if (m_FormationMap.m_vecCellRect.size() == nCellSize)
+						{
+							m_FormationMap.m_vecCellRect.clear();
+							//m_FormationMap.m_vecCellRect.erase(m_FormationMap.m_vecCellRect.begin(), m_FormationMap.m_vecCellRect.begin() + m_nCellSize[i]);
+						}
+// 						else
+// 						{
+// 							m_FormationMap.m_vecCellRect.erase(m_FormationMap.m_vecCellRect.begin() + nCellSize, m_FormationMap.m_vecCellRect.begin() + nCellSize + m_nCellSize[i]);
+// 						}
+
+						int nCellCount = 0;
+						int nDefectCount = 0;
+						int nImageCount = 0;
+
+/*						int nCount = 0;*/
+						int nCellCount2 = m_nCellSize[i];
+						int nDefectCount2 = m_nDefectSize[i];
+						int nImageCount2 = m_nImageSize[i];
+
+						int nCellCount3 = 0;
+						int nDefectCount3 = 0;
+						int nImageCount3 = 0;
+
+
+						m_nCellSize[i] = 0;
+						m_nDefectSize[i] = 0;
+						m_nImageSize[i] = 0;
+
+
+
+						for (int k = 0; k < MAX_COUNT; k++)
+						{
+// 							if (m_nCellSize[k] != 0)
+// 							{
+// 								nCount++;
+// 							}
+							nCellCount = m_nCellSize[k];
+							nDefectCount = m_nDefectSize[k];
+							nImageCount = m_nImageSize[k];
+
+							if (k == 0)
+							{
+								nCellCount3 = 0;
+								nDefectCount3 = 0;
+								nImageCount3 = 0;
+							}
+							else
+							{
+								nCellCount3 += m_nCellSize[k];
+								nDefectCount3 += m_nDefectSize[k];
+								nImageCount3 += m_nImageSize[k];
+							}
+						}
+		
+						m_Formation.m_vecDefects.clear();
+ 						for (int j = 0; j < nDefectSize - nDefectCount2; j++)
+						{
+							_akDefect *pDefectInfo = &m_Formation.m_vecTempDefects[j];
+							double dDefectPosX = pDefectInfo->m_nUMCenterAlignX / 1000.0;
+							double dDefectPosY = pDefectInfo->m_nUMCenterAlignY / 1000.0;
+
+							m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+							m_Formation.m_vecDefects[j] = m_Formation.m_vecTempDefects[j];
+							//�뵒�럺 �떆�옉 �겕湲� 留뚰겮留� 蹂듭궗 �븳�떎
+						}
+						if (m_nDefectSize[i + 1] != 0)
+						{
+							int nCount = m_Formation.m_vecDefects.size();
+							for (int j = 0; j < m_Formation.m_vecTempDefects.size() - nDefectSize; j++)
+							{
+								_akDefect *pDefectInfo = &m_Formation.m_vecTempDefects[nDefectSize + j];
+								double dDefectPosX = pDefectInfo->m_nUMCenterAlignX / 1000.0;
+								double dDefectPosY = pDefectInfo->m_nUMCenterAlignY / 1000.0;
+
+								m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+								m_Formation.m_vecDefects[nCount + j] = m_Formation.m_vecTempDefects[nDefectSize +j];
+							}
+						}
+
+						m_Formation.m_vecImage.clear();
+						for (int j = 0; j < nImageSize - nImageCount2; j++)
+						{
+							m_Formation.AddDefectImage();
+							m_Formation.m_vecImage[j] = m_Formation.m_vecTempImage[j];
+							//�뵒�럺 �떆�옉 �겕湲� 留뚰겮留� 蹂듭궗 �븳�떎
+						}
+						if (m_nImageSize[i + 1] != 0)
+						{
+							int nCount = m_Formation.m_vecImage.size();
+							for (int j = 0; j < m_Formation.m_vecTempImage.size() - nImageSize; j++)
+							{
+								m_Formation.AddDefectImage();
+								m_Formation.m_vecImage[nCount + j] = m_Formation.m_vecTempImage[nImageSize + j];
+							}
+						}
+
+						m_FormationMap.m_vecCellRect.clear();
+						for (int j = 0; j < nCellSize - nCellCount2; j++)
+						{
+							m_FormationMap.AddCell();
+							m_FormationMap.m_vecCellRect[j] = m_FormationMap.m_vecTempCellRect[j];
+							//�뵒�럺 �떆�옉 �겕湲� 留뚰겮留� 蹂듭궗 �븳�떎
+						}
+						
+						if (m_nCellSize[i + 1] != 0)
+						{
+							int nCount = m_FormationMap.m_vecCellRect.size();
+							for (int j = 0; j < m_FormationMap.m_vecTempCellRect.size() - nCellSize; j++)
+							{
+								m_FormationMap.AddCell();
+								m_FormationMap.m_vecCellRect[nCount + j] = m_FormationMap.m_vecTempCellRect[nCellSize + j];
+							}
+						}
+					}
+
+					m_nSelectFile[i] = 0;
+
+// 					for (int i = 0; i < MAX_COUNT + 1; i++)
+// 					{
+// 						for (int iCol = 0; iCol < m_gridReviewList.GetColumnCount(); iCol++)
+// 						{
+// 							m_gridReviewList.SetItemState(m_nSelectFile[i], iCol, LVIS_SELECTED);
+// 						}
+// 					}
+// 
+// 					m_gridReviewList.Invalidate();
+
+// 					int nSelect = i;
+// 					bool bMax = false;
+// 					for (nSelect; nSelect < MAX_COUNT; nSelect++)
+// 					{
+// 						m_nSelectFile[nSelect] = m_nSelectFile[nSelect + 1];
+// 						bMax = true;
+// 					}
+// 					if (bMax)
+// 					{
+// 						m_nSelectFile[nSelect] = 0;
+// 					}
+// 					m_nDefectSize[i] = 0;
+// 					m_nImageSize[i] = 0;
+/*					m_nCellSize[i] = 0;*/
+// 					for (j = 0; j < MAX_COUNT; j++)
+// 					{
+// 						if (i <= j)
+// 						{
+// 							m_nCellSize[j] = m_nCellSize[j + 1];
+// 						}
+// 					}
+					AddVecCellSorting(0);
+					AddVecDateSorting(0);
+					m_gridGlassInfo.SetRowCount(m_Formation.m_vecGlassInfo.size() + 1);
+					m_gridDefectInfo.SetRowCount(m_Formation.m_vecDefects.size() + 1);
+					m_FormationMap.ReDraw(TRUE);
+ 					return FALSE;
+				}
+			}
+		}
+	}
+
+	if (m_Formation.m_vecGlassInfo.size() >= MAX_COUNT + 1) // 1 base
+	{
+		m_Formation.m_vecGlassInfo.erase(m_Formation.m_vecGlassInfo.begin());
+
+		if (m_nDefectSize[0] != 0)
+		{
+			m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin(), m_Formation.m_vecDefects.begin() + m_nDefectSize[0]);
+		}
+		if (m_nImageSize[0] != 0)
+		{
+			m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin(), m_Formation.m_vecImage.begin() + m_nImageSize[0]);
+		}
+		if (m_nCellSize[0] != 0)
+		{
+			m_FormationMap.m_vecCellRect.erase(m_FormationMap.m_vecCellRect.begin(), m_FormationMap.m_vecCellRect.begin() + m_nCellSize[0]);
+		}
+	}
+	return TRUE;
+}
+
+int CReveiwHistoryDlg::MultiInsert(int nSelectCount, int nDataCount)
+{
+	if (nSelectCount <= 0) return FALSE;
+
+	//if (m_Formation.m_vecGlassInfo.size() > MAX_COUNT) return FALSE;
+
+	if (m_Formation.m_vecGlassInfo.size() >= MAX_COUNT+1) //1base
+	{
+		m_Formation.m_vecGlassInfo.erase(m_Formation.m_vecGlassInfo.begin());
+
+		if (m_nDefectSize[0] != 0)
+		{
+			m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin(), m_Formation.m_vecDefects.begin() + m_nDefectSize[0]);
+		}
+		if (m_nImageSize[0] != 0)
+		{
+			m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin(), m_Formation.m_vecImage.begin() + m_nImageSize[0]);
+		}
+		if (m_nCellSize[0] != 0)
+		{
+			m_FormationMap.m_vecCellRect.erase(m_FormationMap.m_vecCellRect.begin(), m_FormationMap.m_vecCellRect.begin() + m_nCellSize[0]);
+		}
+	}
+
+	int nDefectSize = 0;
+	int nImageSize = 0;
+	int nCellSize = 0;
+
+	for (int i = 0; i < MAX_COUNT; i++)
+	{
+		nDefectSize += m_nDefectSize[i];
+		nImageSize += m_nImageSize[i];
+		nCellSize += m_nCellSize[i];
+
+		if (nSelectCount == m_nSelectFile[i])
+		{
+			for (int j = 0; j < m_Formation.m_vecGlassInfo.size(); j++)
+			{
+				_akGlassInfo* pGlassInfo = &m_Formation.m_vecGlassInfo[j];
+
+				if (pGlassInfo->m_nGlassSelect == m_nSelectFile[i])
+				{
+					m_Formation.m_vecGlassInfo.erase(m_Formation.m_vecGlassInfo.begin() + j);
+					
+					if (i == 0)
+					{
+						m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin(), m_Formation.m_vecDefects.begin() + m_nDefectSize[i]);
+						m_Formation.m_vecDefects.clear();
+						m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin(), m_Formation.m_vecImage.begin() + m_nImageSize[i]);
+						m_Formation.m_vecImage.clear();
+						m_FormationMap.m_vecCellRect.erase(m_FormationMap.m_vecCellRect.begin(), m_FormationMap.m_vecCellRect.begin() + m_nCellSize[i]);
+
+						if (m_bDefectAll == false && !m_chkSingle.GetCheck())
+						{
+							AddVecDataDefct2(nDataCount/*, nCount*/);
+						}
+						else if (m_bDefectAll == true && !m_chkSingle.GetCheck())
+						{
+							AddVecDataDefectAll2(nDataCount/*, nCount*/);
+						}
+					}
+					else if (i != 0 && m_nDefectSize[i] == 0)
+					{
+						if (m_bDefectAll == false && !m_chkSingle.GetCheck())
+						{
+							AddVecDataDefct2(nDataCount/*, nCount*/);
+						}
+						else if (m_bDefectAll == true && !m_chkSingle.GetCheck())
+						{
+							AddVecDataDefectAll2(nDataCount/*, nCount*/);
+						}
+					}
+					else if (i != 0 && m_nDefectSize[i] > 0)
+					{
+						if (m_Formation.m_vecDefects.size() == nDefectSize)
+						{
+							m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin(), m_Formation.m_vecDefects.begin() + m_nDefectSize[i]);
+						}
+// 						else
+// 						{
+						Sleep(1);
+							//n媛� 源뚯�留� 蹂듭궗 �븳�떎. �겢由ъ뼱 �썑 �뿉 
+							m_Formation.m_vecDefects.clear();
+							for (int j = 0; j < nDefectSize-m_nDefectSize[i]; j++)
+							{
+								_akDefect *pDefectInfo = &m_Formation.m_vecTempDefects[j];
+								double dDefectPosX = pDefectInfo->m_nUMCenterAlignX / 1000.0;
+								double dDefectPosY = pDefectInfo->m_nUMCenterAlignY / 1000.0;
+
+								m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+								m_Formation.m_vecDefects[j] = m_Formation.m_vecTempDefects[j];
+								//�뵒�럺 �떆�옉 �겕湲� 留뚰겮留� 蹂듭궗 �븳�떎
+							}
+							//�깮�꽦�맂 �뵒�럺�쓣 異붽� �븳�떎
+							if (m_bDefectAll == false && !m_chkSingle.GetCheck())
+							{
+								AddVecDataDefct2(nDataCount/*, nCount*/);
+							}
+							else if (m_bDefectAll == true && !m_chkSingle.GetCheck())
+							{
+								AddVecDataDefectAll2(nDataCount/*, nCount*/);
+							}
+
+// 							Sleep(1);
+// 												
+// 							//異붽��븳 �뵒�럺 �뮘�뿉 遺숈뿬 �꽔�뒗�떎
+// 							if (m_nDefectSize[i + 1] != 0)
+// 							{
+// 								for (int j = 0; j < m_nDefectSize[i + 1]; j++)
+// 								{
+// 									int nCount = m_nDefectSize[i - 1];
+// 									_akDefect *pDefectInfo = &m_Formation.m_vecTempDefects[nDefectSize + j];
+// 									double dDefectPosX = pDefectInfo->m_nUMCenterAlignX / 1000.0;
+// 									double dDefectPosY = pDefectInfo->m_nUMCenterAlignY / 1000.0;
+// 
+// 									m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+// 									m_Formation.m_vecDefects[nCount + j] = m_Formation.m_vecTempDefects[nDefectSize + j];
+// 								}
+// 							}
+
+							Sleep(1);
+							m_Formation.m_vecImage.clear();
+							for (int j = 0; j < nImageSize - m_nImageSize[i]; j++)
+							{
+								m_Formation.AddDefectImage();
+								m_Formation.m_vecImage[j] = m_Formation.m_vecTempImage[j];
+								//�뵒�럺 �떆�옉 �겕湲� 留뚰겮留� 蹂듭궗 �븳�떎
+							}
+							if (m_nImageSize[i + 1] != 0)
+							{
+								int nSize = m_Formation.m_vecTempImage.size() - m_Formation.m_vecImage.size();
+								//�떆�옉 遺��꽣 �걹源뚯� 蹂듭궗瑜� �븳�떎
+								for (int j = 0; j < nSize; j++)
+								{
+									int nCount = m_nImageSize[i - 1];
+
+									m_Formation.AddDefectImage();
+									m_Formation.m_vecImage[nCount + j] = m_Formation.m_vecTempImage[nCount + j];
+								}
+							}
+
+							Sleep(1);
+  							m_FormationMap.m_vecCellRect.clear();
+							for (int j = 0; j < nCellSize - m_nCellSize[i]; j++)
+							{
+								m_FormationMap.AddCell();
+								m_FormationMap.m_vecCellRect[j] = m_FormationMap.m_vecTempCellRect[j];
+								//�뵒�럺 �떆�옉 �겕湲� 留뚰겮留� 蹂듭궗 �븳�떎
+							}
+							if (m_nCellSize[i + 1] != 0)
+							{
+								int nSize = m_FormationMap.m_vecTempCellRect.size() - m_FormationMap.m_vecCellRect.size();
+								for (int j = 0; j < nSize; j++)
+								{
+									int nCount = m_nCellSize[i - 1];
+
+									m_FormationMap.AddCell();
+									m_FormationMap.m_vecCellRect[nCount + j] = m_FormationMap.m_vecTempCellRect[nCount + j];
+									//m_FormationMap.m_vecCellRect[nCount + j] = m_FormationMap.m_vecTempCellRect[nCellSize + j];
+								}
+							}
+
+ 							//m_Formation.m_vecDefects.erase(m_Formation.m_vecDefects.begin() + nDefectSize, m_Formation.m_vecDefects.begin() + nDefectSize + m_nDefectSize[i]);
+
+// 						if (m_Formation.m_vecImage.size() == nImageSize)
+// 						{
+// 							m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin(), m_Formation.m_vecImage.begin() + m_nImageSize[i]);
+// 						}
+// 						else
+// 						{
+// 							m_Formation.m_vecImage.erase(m_Formation.m_vecImage.begin() + nImageSize, m_Formation.m_vecImage.begin() + nImageSize + m_nImageSize[i]);
+// 						}
+					}
+
+					//m_nSelectFile[i] = 0;
+					m_nDefectSize[i] = 0;
+					m_nImageSize[i] = 0;
+					m_nCellSize[i] = 0;
+// 					for (j = 0; j < MAX_COUNT; j++)
+// 					{
+// 						if (i <= j)
+// 						{
+// 							m_nCellSize[j] = m_nCellSize[j + 1];
+// 						}
+// 					}
+
+					if (m_Formation.m_vecGlassInfo.size() > 0)
+					{
+						m_gridGlassInfo.SetRowCount(m_Formation.m_vecGlassInfo.size() + 1);
+						m_gridDefectInfo.SetRowCount(m_Formation.m_vecDefects.size() + 1);
+						return i;
+					}
+					else
+					{
+						m_gridGlassInfo.SetRowCount(2);
+						m_gridDefectInfo.SetRowCount(2);
+						return i;
+					}
+					return i;					
+				}
+			}
+		}
+	}
+
+// 	if (m_bDefectAll == false && !m_chkSingle.GetCheck())
+// 	{
+// 		AddVecDataDefct2(nDataCount/*, nCount*/);
+// 	}
+// 	else if (m_bDefectAll == true && !m_chkSingle.GetCheck())
+// 	{
+// 		AddVecDataDefectAll2(nDataCount/*, nCount*/);
+// 	}
+	return -1;
+}
+
+void CReveiwHistoryDlg::InitSelectGlass(int nSelectCount)
+{
+	int nCountMax = MAX_COUNT+1;
+	bool bMax = false;
+	for (int i = 0; i < MAX_COUNT+1; i++)
+	{
+		if (nSelectCount != m_nSelectFile[i] && m_nSelectFile[i] == 0)
+		{
+			if (!GetCheckFileLoad(nSelectCount)) return;
+			m_nSelectFile[i] = nSelectCount;
+			bMax = true;
+			break;
+		}
+	}
+	if (!bMax)
+	{
+		for (int j = 0; j < MAX_COUNT; j++)
+		{
+			if (!GetCheckFileLoad(nSelectCount)) return;
+			m_nSelectFile[j] = m_nSelectFile[j + 1];
+		}
+		m_nSelectFile[MAX_COUNT] = nSelectCount;
+	}
+}
+
+void CReveiwHistoryDlg::AddVecDataImage(int nDataCount)
+{
+	for (int i = 0; i < nDataCount; i++)
+	{
+		_grmDefectData* pDefect = m_Server.GetDefectData(i);
+		_grmGlassData* pGlass = m_Server.GetGlassData();
+
+		CString strTemp;
+		int nInfoCount = 0;
+
+		CString strReviewImageName;
+		strReviewImageName = pDefect->m_ReviewDefect.m_strRevImageName;
+
+		if (strReviewImageName == "" || strReviewImageName == "*")
+		{
+			continue;
+		}
+		else
+		{
+			m_Formation.AddDefectImage();
+			SetImageCount();
+			_akReviewList* pImageInfo = &m_Formation.m_vecImage[m_Formation.m_vecImage.size() - 1];
+
+			pImageInfo->m_nDefectID = pDefect->m_nDefectID;
+			strcpy(pImageInfo->m_strAoiImageName, pDefect->m_strAoiImageName);
+			pImageInfo->m_nDefectIdx = pDefect->m_nDefectIdx;
+			pImageInfo->m_strReviewImageName = strReviewImageName;
+			
+			strcpy(pImageInfo->m_strAoiImagePath, pDefect->m_strAoiImagePath);
+			strcpy(pImageInfo->m_strReviewImagePath, pDefect->m_ReviewDefect.m_strRevImagePath);
+			strcpy(pImageInfo->m_strAlignFirst, pGlass->m_strAlignFirst);
+			strcpy(pImageInfo->m_strAlignSecond, pGlass->m_strAlignSecond);
+			pImageInfo->m_strGlassID = pGlass->m_strGlassID;
+		}
+	}
+}
+
+void CReveiwHistoryDlg::AddVecDataDefct(int nDataCount)
+{
+	for (int i = 0; i < nDataCount; i++)
+	{
+		_grmDefectData* pDefect = m_Server.GetDefectData(i);
+
+		int nInfoCount = 0;
+		
+		CString strReviewImageName;
+		strReviewImageName = pDefect->m_ReviewDefect.m_strRevImageName;
+
+		if (strReviewImageName == "" || strReviewImageName == "*")
+		{
+			continue;
+		}
+		else
+		{
+			double dDefectPosX = pDefect->m_nUMCenterAlignX / 1000.0;
+			double dDefectPosY = pDefect->m_nUMCenterAlignY / 1000.0;
+
+			m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+			SetDefectCount();
+			_akDefect* pDefectInfo = &m_Formation.m_vecDefects[m_Formation.m_vecDefects.size() - 1];
+
+			pDefectInfo->m_nDefectID = pDefect->m_nDefectID;
+			pDefectInfo->m_sDefectLoc = pDefect->m_sDefectLoc;
+			strcpy(pDefectInfo->m_strDefectType, pDefect->m_strDefectType);
+			strcpy(pDefectInfo->m_strDefectCode, pDefect->m_strDefectCode);
+			pDefectInfo->m_DefectType = pDefect->m_DefectType;
+			pDefectInfo->m_DefectSubType = pDefect->m_DefectSubType;
+			pDefectInfo->m_nDefectRScale = pDefect->m_nDefectRScale;
+			pDefectInfo->m_nUMSizeX = pDefect->m_nUMSizeX;
+			pDefectInfo->m_nUMSizeY = pDefect->m_nUMSizeY;
+			pDefectInfo->m_nUMSize = pDefect->m_nUMSize;
+			memcpy(pDefectInfo->m_sZonePixelCount, pDefect->m_sZonePixelCount, sizeof(pDefect->m_sZonePixelCount));
+			pDefectInfo->m_nLevelSrcMax = pDefect->m_nLevelSrcMax;
+			pDefectInfo->m_nLevelSrcMin = pDefect->m_nLevelSrcMin;
+			pDefectInfo->m_nLevelSrcAvg = pDefect->m_nLevelSrcAvg;
+			pDefectInfo->m_sDefectPeak = pDefect->m_sDefectPeak;
+			strcpy(pDefectInfo->m_strStackFirst, pDefect->m_strStackFirst);
+			pDefectInfo->m_nCameraID = pDefect->m_nCameraID;
+			pDefectInfo->m_nScanIdx = pDefect->m_nScanIdx;
+			pDefectInfo->m_nLevelRefMax = pDefect->m_nLevelRefMax;
+			pDefectInfo->m_nLevelRefMin = pDefect->m_nLevelRefMin;
+			pDefectInfo->m_nLevelRefAvg = pDefect->m_nLevelRefAvg;
+			pDefectInfo->m_nUMCenterAlignX = pDefect->m_nUMCenterAlignX;
+			pDefectInfo->m_nUMCenterAlignY = pDefect->m_nUMCenterAlignY;
+			pDefectInfo->m_nUMCellX = pDefect->m_nUMCellX;
+			pDefectInfo->m_nUMCellY = pDefect->m_nUMCellY;
+			pDefectInfo->m_nScratchRatio = pDefect->m_nScratchRatio;
+			pDefectInfo->m_nDensity = pDefect->m_nDensity;
+			pDefectInfo->m_bMergeState = pDefect->m_bMergeState;
+			pDefectInfo->m_nShotIdx = pDefect->m_ReviewDefect.m_nShotIndex;
+			pDefectInfo->m_nModelIdx = pDefect->m_ReviewDefect.m_nModuleIndex;
+
+			for (int j = 0; j < nInfoCount; j++) pDefectInfo->m_strInfos[j].Trim();
+		}
+	}
+}
+
+void CReveiwHistoryDlg::AddVecDataDefectAll(int nDataCount)
+{
+	for (int i = 0; i < nDataCount; i++)
+	{
+		_grmDefectData* pDefect = m_Server.GetDefectData(i);
+		int nInfoCount = 0;
+
+		double dDefectPosX = pDefect->m_nUMCenterAlignX / 1000.0;
+		double dDefectPosY = pDefect->m_nUMCenterAlignY / 1000.0;
+
+		m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+		SetDefectCount();
+		_akDefect* pDefectInfo = &m_Formation.m_vecDefects[m_Formation.m_vecDefects.size() - 1];
+
+		pDefectInfo->m_nDefectID = pDefect->m_nDefectID;
+		pDefectInfo->m_sDefectLoc = pDefect->m_sDefectLoc;
+		strcpy(pDefectInfo->m_strDefectType, pDefect->m_strDefectType);
+		strcpy(pDefectInfo->m_strDefectCode, pDefect->m_strDefectCode);
+		pDefectInfo->m_DefectType = pDefect->m_DefectType;
+		pDefectInfo->m_DefectSubType = pDefect->m_DefectSubType;
+		pDefectInfo->m_nDefectRScale = pDefect->m_nDefectRScale;
+		pDefectInfo->m_nUMSizeX = pDefect->m_nUMSizeX;
+		pDefectInfo->m_nUMSizeY = pDefect->m_nUMSizeY;
+		pDefectInfo->m_nUMSize = pDefect->m_nUMSize;
+		memcpy(pDefectInfo->m_sZonePixelCount, pDefect->m_sZonePixelCount, sizeof(pDefect->m_sZonePixelCount));
+		pDefectInfo->m_nLevelSrcMax = pDefect->m_nLevelSrcMax;
+		pDefectInfo->m_nLevelSrcMin = pDefect->m_nLevelSrcMin;
+		pDefectInfo->m_nLevelSrcAvg = pDefect->m_nLevelSrcAvg;
+		pDefectInfo->m_sDefectPeak = pDefect->m_sDefectPeak;
+		strcpy(pDefectInfo->m_strStackFirst, pDefect->m_strStackFirst);
+		pDefectInfo->m_nCameraID = pDefect->m_nCameraID;
+		pDefectInfo->m_nScanIdx = pDefect->m_nScanIdx;
+		pDefectInfo->m_nLevelRefMax = pDefect->m_nLevelRefMax;
+		pDefectInfo->m_nLevelRefMin = pDefect->m_nLevelRefMin;
+		pDefectInfo->m_nLevelRefAvg = pDefect->m_nLevelRefAvg;
+		pDefectInfo->m_nUMCenterAlignX = pDefect->m_nUMCenterAlignX;
+		pDefectInfo->m_nUMCenterAlignY = pDefect->m_nUMCenterAlignY;
+		pDefectInfo->m_nUMCellX = pDefect->m_nUMCellX;
+		pDefectInfo->m_nUMCellY = pDefect->m_nUMCellY;
+		pDefectInfo->m_nScratchRatio = pDefect->m_nScratchRatio;
+		pDefectInfo->m_nDensity = pDefect->m_nDensity;
+		pDefectInfo->m_bMergeState = pDefect->m_bMergeState;
+
+		CString strReviewImageName;
+		strReviewImageName = pDefect->m_ReviewDefect.m_strRevImageName;
+
+		if (strReviewImageName == "" || strReviewImageName == "*")
+		{
+			pDefectInfo->m_nShotIdx = -1;
+			pDefectInfo->m_nModelIdx = -1;
+		}
+		else
+		{
+			pDefectInfo->m_nShotIdx = pDefect->m_ReviewDefect.m_nShotIndex;
+			pDefectInfo->m_nModelIdx = pDefect->m_ReviewDefect.m_nModuleIndex;
+		}
+		
+
+		for (int j = 0; j < nInfoCount; j++) pDefectInfo->m_strInfos[j].Trim();
+	}
+}
+
+void CReveiwHistoryDlg::AddVecDataDefct2(int nDataCount/*, int nRawCount*/)
+{
+//	int nCount = MultiInsert(m_nCount, nDataCount);
+
+// 	if(nCount < 0) return;
+// 
+	for (int i = 0; i < nDataCount; i++)
+	{
+		_grmDefectData* pDefect = m_Server.GetDefectData(i);
+
+		int nInfoCount = 0;
+
+		CString strReviewImageName;
+		strReviewImageName = pDefect->m_ReviewDefect.m_strRevImageName;
+
+		if (strReviewImageName == "" || strReviewImageName == "*")
+		{
+			continue;
+		}
+		else
+		{
+			double dDefectPosX = pDefect->m_nUMCenterAlignX / 1000.0;
+			double dDefectPosY = pDefect->m_nUMCenterAlignY / 1000.0;
+
+			m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+			SetDefectCount();
+
+			_akDefect* pDefectInfo = NULL;
+
+// 			if (nCount == 0)
+// 			{
+				pDefectInfo = &m_Formation.m_vecDefects[m_Formation.m_vecDefects.size() - 1];
+// 			}
+// 			else
+// 			{
+// 				//以묎컙�뿉 媛� �궫�엯
+// 				pDefectInfo = &m_Formation.m_vecDefects[m_Formation.m_vecDefects.size() - 1];
+// 				//pDefectInfo = &m_Formation.m_vecDefects[nCount + i];
+// 			}
+
+			pDefectInfo->m_nDefectID = pDefect->m_nDefectID;
+			pDefectInfo->m_sDefectLoc = pDefect->m_sDefectLoc;
+			strcpy(pDefectInfo->m_strDefectType, pDefect->m_strDefectType);
+			strcpy(pDefectInfo->m_strDefectCode, pDefect->m_strDefectCode);
+			pDefectInfo->m_DefectType = pDefect->m_DefectType;
+			pDefectInfo->m_DefectSubType = pDefect->m_DefectSubType;
+			pDefectInfo->m_nDefectRScale = pDefect->m_nDefectRScale;
+			pDefectInfo->m_nUMSizeX = pDefect->m_nUMSizeX;
+			pDefectInfo->m_nUMSizeY = pDefect->m_nUMSizeY;
+			pDefectInfo->m_nUMSize = pDefect->m_nUMSize;
+			memcpy(pDefectInfo->m_sZonePixelCount, pDefect->m_sZonePixelCount, sizeof(pDefect->m_sZonePixelCount));
+			pDefectInfo->m_nLevelSrcMax = pDefect->m_nLevelSrcMax;
+			pDefectInfo->m_nLevelSrcMin = pDefect->m_nLevelSrcMin;
+			pDefectInfo->m_nLevelSrcAvg = pDefect->m_nLevelSrcAvg;
+			pDefectInfo->m_sDefectPeak = pDefect->m_sDefectPeak;
+			strcpy(pDefectInfo->m_strStackFirst, pDefect->m_strStackFirst);
+			pDefectInfo->m_nCameraID = pDefect->m_nCameraID;
+			pDefectInfo->m_nScanIdx = pDefect->m_nScanIdx;
+			pDefectInfo->m_nLevelRefMax = pDefect->m_nLevelRefMax;
+			pDefectInfo->m_nLevelRefMin = pDefect->m_nLevelRefMin;
+			pDefectInfo->m_nLevelRefAvg = pDefect->m_nLevelRefAvg;
+			pDefectInfo->m_nUMCenterAlignX = pDefect->m_nUMCenterAlignX;
+			pDefectInfo->m_nUMCenterAlignY = pDefect->m_nUMCenterAlignY;
+			pDefectInfo->m_nUMCellX = pDefect->m_nUMCellX;
+			pDefectInfo->m_nUMCellY = pDefect->m_nUMCellY;
+			pDefectInfo->m_nScratchRatio = pDefect->m_nScratchRatio;
+			pDefectInfo->m_nDensity = pDefect->m_nDensity;
+			pDefectInfo->m_bMergeState = pDefect->m_bMergeState;
+
+			for (int j = 0; j < nInfoCount; j++) pDefectInfo->m_strInfos[j].Trim();
+		}
+	}
+}
+
+void CReveiwHistoryDlg::AddVecDataDefectAll2(int nDataCount/*, int nRawCount*/)
+{
+	for (int i = 0; i < nDataCount; i++)
+	{
+		_grmDefectData* pDefect = m_Server.GetDefectData(i);
+
+		int nInfoCount = 0;
+
+		CString strReviewImageName;
+		strReviewImageName = pDefect->m_ReviewDefect.m_strRevImageName;
+
+		double dDefectPosX = pDefect->m_nUMCenterAlignX / 1000.0;
+		double dDefectPosY = pDefect->m_nUMCenterAlignY / 1000.0;
+
+		m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+		SetDefectCount();
+
+		_akDefect* pDefectInfo = NULL;
+
+		pDefectInfo = &m_Formation.m_vecDefects[m_Formation.m_vecDefects.size() - 1];
+
+		pDefectInfo->m_nDefectID = pDefect->m_nDefectID;
+		pDefectInfo->m_sDefectLoc = pDefect->m_sDefectLoc;
+		strcpy(pDefectInfo->m_strDefectType, pDefect->m_strDefectType);
+		strcpy(pDefectInfo->m_strDefectCode, pDefect->m_strDefectCode);
+		pDefectInfo->m_DefectType = pDefect->m_DefectType;
+		pDefectInfo->m_DefectSubType = pDefect->m_DefectSubType;
+		pDefectInfo->m_nDefectRScale = pDefect->m_nDefectRScale;
+		pDefectInfo->m_nUMSizeX = pDefect->m_nUMSizeX;
+		pDefectInfo->m_nUMSizeY = pDefect->m_nUMSizeY;
+		pDefectInfo->m_nUMSize = pDefect->m_nUMSize;
+		memcpy(pDefectInfo->m_sZonePixelCount, pDefect->m_sZonePixelCount, sizeof(pDefect->m_sZonePixelCount));
+		pDefectInfo->m_nLevelSrcMax = pDefect->m_nLevelSrcMax;
+		pDefectInfo->m_nLevelSrcMin = pDefect->m_nLevelSrcMin;
+		pDefectInfo->m_nLevelSrcAvg = pDefect->m_nLevelSrcAvg;
+		pDefectInfo->m_sDefectPeak = pDefect->m_sDefectPeak;
+		strcpy(pDefectInfo->m_strStackFirst, pDefect->m_strStackFirst);
+		pDefectInfo->m_nCameraID = pDefect->m_nCameraID;
+		pDefectInfo->m_nScanIdx = pDefect->m_nScanIdx;
+		pDefectInfo->m_nLevelRefMax = pDefect->m_nLevelRefMax;
+		pDefectInfo->m_nLevelRefMin = pDefect->m_nLevelRefMin;
+		pDefectInfo->m_nLevelRefAvg = pDefect->m_nLevelRefAvg;
+		pDefectInfo->m_nUMCenterAlignX = pDefect->m_nUMCenterAlignX;
+		pDefectInfo->m_nUMCenterAlignY = pDefect->m_nUMCenterAlignY;
+		pDefectInfo->m_nUMCellX = pDefect->m_nUMCellX;
+		pDefectInfo->m_nUMCellY = pDefect->m_nUMCellY;
+		pDefectInfo->m_nScratchRatio = pDefect->m_nScratchRatio;
+		pDefectInfo->m_nDensity = pDefect->m_nDensity;
+		pDefectInfo->m_bMergeState = pDefect->m_bMergeState;
+
+		for (int j = 0; j < nInfoCount; j++) pDefectInfo->m_strInfos[j].Trim();
+	}
+ 
+// 	for (int i = 0; i < nDataCount; i++)
+// 	{
+// 		_grmDefectData* pDefect = m_Server.GetDefectData(i);
+// 		int nInfoCount = 0;
+// 
+// 		double dDefectPosX = pDefect->m_nUMCenterAlignX / 1000.0;
+// 		double dDefectPosY = pDefect->m_nUMCenterAlignY / 1000.0;
+// 
+// 		m_Formation.AddDefect(dDefectPosX, dDefectPosY);
+// 		SetDefectCount();
+// 
+// 		_akDefect* pDefectInfo = NULL;
+// 
+// // 		if (nCount == 0)
+// // 		{
+// 			pDefectInfo = &m_Formation.m_vecDefects[m_Formation.m_vecDefects.size() - 1];
+// // 		}
+// // 		else
+// // 		{
+// // 			pDefectInfo = &m_Formation.m_vecDefects[nCount + i];
+// // 		}
+// 
+// 		//m_Formation.m_vecDefects.insert(m_Formation.m_vecDefects.begin() + 1400, pDefect->m_nDefectID);
+// 
+// 		pDefectInfo->m_nDefectID = pDefect->m_nDefectID;
+// 		pDefectInfo->m_sDefectLoc = pDefect->m_sDefectLoc;
+// 		strcpy(pDefectInfo->m_strDefectType, pDefect->m_strDefectType);
+// 		strcpy(pDefectInfo->m_strDefectCode, pDefect->m_strDefectCode);
+// 		pDefectInfo->m_DefectType = pDefect->m_DefectType;
+// 		pDefectInfo->m_DefectSubType = pDefect->m_DefectSubType;
+// 		pDefectInfo->m_nDefectRScale = pDefect->m_nDefectRScale;
+// 		pDefectInfo->m_nUMSizeX = pDefect->m_nUMSizeX;
+// 		pDefectInfo->m_nUMSizeY = pDefect->m_nUMSizeY;
+// 		pDefectInfo->m_nUMSize = pDefect->m_nUMSize;
+// 		memcpy(pDefectInfo->m_sZonePixelCount, pDefect->m_sZonePixelCount, sizeof(pDefect->m_sZonePixelCount));
+// 		pDefectInfo->m_nLevelSrcMax = pDefect->m_nLevelSrcMax;
+// 		pDefectInfo->m_nLevelSrcMin = pDefect->m_nLevelSrcMin;
+// 		pDefectInfo->m_nLevelSrcAvg = pDefect->m_nLevelSrcAvg;
+// 		pDefectInfo->m_sDefectPeak = pDefect->m_sDefectPeak;
+// 		strcpy(pDefectInfo->m_strStackFirst, pDefect->m_strStackFirst);
+// 		pDefectInfo->m_nCameraID = pDefect->m_nCameraID;
+// 		pDefectInfo->m_nScanIdx = pDefect->m_nScanIdx;
+// 		pDefectInfo->m_nLevelRefMax = pDefect->m_nLevelRefMax;
+// 		pDefectInfo->m_nLevelRefMin = pDefect->m_nLevelRefMin;
+// 		pDefectInfo->m_nLevelRefAvg = pDefect->m_nLevelRefAvg;
+// 		pDefectInfo->m_nUMCenterAlignX = pDefect->m_nUMCenterAlignX;
+// 		pDefectInfo->m_nUMCenterAlignY = pDefect->m_nUMCenterAlignY;
+// 		pDefectInfo->m_nUMCellX = pDefect->m_nUMCellX;
+// 		pDefectInfo->m_nUMCellY = pDefect->m_nUMCellY;
+// 		pDefectInfo->m_nScratchRatio = pDefect->m_nScratchRatio;
+// 		pDefectInfo->m_nDensity = pDefect->m_nDensity;
+// 		pDefectInfo->m_bMergeState = pDefect->m_bMergeState;
+// 
+// 		for (int j = 0; j < nInfoCount; j++) pDefectInfo->m_strInfos[j].Trim();
+// 	}
+}
+
+void CReveiwHistoryDlg::AddVecGlassData(int nCount)
+{
+	m_Formation.AddGlassInfo();
+
+	_grmGlassData* pGlass = m_Server.GetGlassData();
+	_akGlassInfo* pGlassInfo = &m_Formation.m_vecGlassInfo[m_Formation.m_vecGlassInfo.size() - 1];
+
+	pGlassInfo->m_nGlassSelect = nCount;
+	pGlassInfo->m_strPPID = pGlass->m_strPPID;
+	pGlassInfo->m_strGlassID = pGlass->m_strGlassID;
+	pGlassInfo->m_nDefectNum = pGlass->m_nDefectNum;
+	pGlassInfo->m_nReviewNum = GetImageCount();
+	pGlassInfo->m_strGlassJudge = pGlass->m_strGlassJudge;
+	pGlassInfo->m_strLotID = pGlass->m_strLotID;
+	pGlassInfo->m_strSLotID = pGlass->m_strSLotID;
+	pGlassInfo->m_nSlot_No = pGlass->m_nSlot_No;
+	pGlassInfo->m_nCellNum = pGlass->m_nCellNum;
+	pGlassInfo->m_nGlassSizeHeight = pGlass->m_nGlassSizeHeight;
+	pGlassInfo->m_nGlassSizeWidth = pGlass->m_nGlassSizeWidth;
+}
+
+void CReveiwHistoryDlg::AddVecCellData(int nCellCount)
+{
+	for (int i = 0; i < nCellCount; i++)
+	{
+		SetCellCount();
+		CakRectd rectCell;
+		_grmCellData* pCellData = m_Server.GetCellData(i);
+		rectCell.left = pCellData->m_rectCellLeft / 1000.0;
+		rectCell.top = pCellData->m_rectCellTop / 1000.0;
+		rectCell.right = pCellData->m_rectCellRight / 1000.0;
+		rectCell.bottom = pCellData->m_rectCellBottom / 1000.0;
+		m_FormationMap.m_vecCellRect.push_back(rectCell);
+	}
+}
+
+void CReveiwHistoryDlg::SortListDefect(int nCol)
+{
+	if (nCol == 0)
+		return;
+
+/*	if (m_pDefectFormation == NULL) return;*/
+
+ 	m_bAsending = !m_bAsending;
+
+	_akDefect			*pDefect;
+	std::vector< std::pair<CString, _akDefect*> > vecString;
+	std::vector< std::pair<double, _akDefect*> > vecValue;
+	CString strValue;
+	double dValue;
+	short sValue[16];
+
+	for (int i = 0; i < m_Formation.m_vecTempDefects.size(); i++)
+	{
+		pDefect = &m_Formation.m_vecTempDefects[i];
+
+		switch (nCol)
+		{
+		case 1: dValue = pDefect->m_nDefectID; break;
+		case 2:	dValue = pDefect->m_sDefectLoc; break;
+		case 3:	strValue = pDefect->m_strDefectType; break;
+		case 4: strValue = pDefect->m_strDefectCode; break;
+		case 5:	dValue = pDefect->m_DefectType; break;
+		case 6:	dValue = pDefect->m_DefectSubType; break;
+		case 7:	dValue = pDefect->m_nDefectRScale; break;
+		case 8:	dValue = pDefect->m_nUMSizeX; break;
+		case 9:	dValue = pDefect->m_nUMSizeY; break;
+		case 10:	dValue = pDefect->m_nUMSize; break;
+		//case 11:	memcpy(sValue, pDefect->m_sZonePixelCount, sizeof(pDefect->m_sZonePixelCount)); break;
+		case 12:	dValue = pDefect->m_nLevelSrcMax; break;
+		case 13:	dValue = pDefect->m_nLevelSrcMin; break;
+		case 14:	dValue = pDefect->m_nLevelSrcAvg; break;
+		case 15:	dValue = pDefect->m_sDefectPeak; break;
+		case 16:	strValue = pDefect->m_strStackFirst; break;
+		case 17:	dValue = pDefect->m_nCameraID; break;
+		case 18:	dValue = pDefect->m_nScanIdx; break;
+		case 19:	dValue = pDefect->m_nLevelRefMax; break;
+		case 20:	dValue = pDefect->m_nLevelRefMin; break;
+		case 21:	dValue = pDefect->m_nLevelRefAvg; break;
+		case 22:	dValue = pDefect->m_nUMCenterAlignX; break;
+		case 23:	dValue = pDefect->m_nUMCenterAlignY; break;
+		case 24:	dValue = pDefect->m_nUMCellX; break;
+		case 25:	dValue = pDefect->m_nUMCellY; break;
+		case 26:	dValue = pDefect->m_nScratchRatio; break;
+		case 27:	dValue = pDefect->m_nDensity; break;
+		case 28:	dValue = pDefect->m_bMergeState; break;
+		}
+
+		if (strValue.IsEmpty() == FALSE) vecString.push_back(std::make_pair(strValue, pDefect));
+		else vecValue.push_back(std::make_pair(dValue, pDefect));
+	}
+
+	if (!vecString.empty())
+	{
+		if (m_bAsending == TRUE) //�삤由� 李⑥닚
+			std::sort(vecString.begin(), vecString.end(), std::greater< std::pair<CString, _akDefect*> >());
+		else //�궡由� 李⑥닚
+			std::sort(vecString.begin(), vecString.end(), std::less< std::pair<CString, _akDefect*> >());
+
+		m_Formation.m_vecDefects.clear();
+		std::vector< std::pair<CString, _akDefect*> >::iterator itVec;
+
+		for (itVec = vecString.begin(); itVec != vecString.end(); ++itVec)
+		{
+			m_Formation.m_vecDefects.push_back(*itVec->second);
+		}
+	}
+	else//if (!vecString.empty())
+	{
+		if (m_bAsending == TRUE)
+			std::sort(vecValue.begin(), vecValue.end(), std::greater< std::pair<double, _akDefect*> >());
+		else
+			std::sort(vecValue.begin(), vecValue.end(), std::less< std::pair<double, _akDefect*> >());
+
+		m_Formation.m_vecDefects.clear();
+		std::vector< std::pair<double, _akDefect*> >::iterator itVec;			
+
+		for (itVec = vecValue.begin(); itVec != vecValue.end(); ++itVec)
+		{
+			m_Formation.m_vecDefects.push_back(*itVec->second);
+		}
+	}
+}
+
+void CReveiwHistoryDlg::AddVecDateSorting(int nDataCount)
+{
+	m_Formation.m_vecTempDefects.clear();
+
+	for (int i = 0; i < m_Formation.m_vecDefects.size(); i++)
+	{
+		_akDefect* pDefect = &m_Formation.m_vecDefects[i];
+		
+		double dDefectPosX = pDefect->m_nUMCenterAlignX / 1000.0;
+		double dDefectPosY = pDefect->m_nUMCenterAlignY / 1000.0;
+
+		m_Formation.AddDefectTemp(dDefectPosX, dDefectPosY);
+		_akDefect* pDefectInfo = &m_Formation.m_vecTempDefects[i];
+
+		pDefectInfo->m_nDefectID = pDefect->m_nDefectID;
+		pDefectInfo->m_sDefectLoc = pDefect->m_sDefectLoc;
+		strcpy(pDefectInfo->m_strDefectType, pDefect->m_strDefectType);
+		strcpy(pDefectInfo->m_strDefectCode, pDefect->m_strDefectCode);
+		pDefectInfo->m_DefectType = pDefect->m_DefectType;
+		pDefectInfo->m_DefectSubType = pDefect->m_DefectSubType;
+		pDefectInfo->m_nDefectRScale = pDefect->m_nDefectRScale;
+		pDefectInfo->m_nUMSizeX = pDefect->m_nUMSizeX;
+		pDefectInfo->m_nUMSizeY = pDefect->m_nUMSizeY;
+		pDefectInfo->m_nUMSize = pDefect->m_nUMSize;
+		memcpy(pDefectInfo->m_sZonePixelCount, pDefect->m_sZonePixelCount, sizeof(pDefect->m_sZonePixelCount));
+		pDefectInfo->m_nLevelSrcMax = pDefect->m_nLevelSrcMax;
+		pDefectInfo->m_nLevelSrcMin = pDefect->m_nLevelSrcMin;
+		pDefectInfo->m_nLevelSrcAvg = pDefect->m_nLevelSrcAvg;
+		pDefectInfo->m_sDefectPeak = pDefect->m_sDefectPeak;
+		strcpy(pDefectInfo->m_strStackFirst, pDefect->m_strStackFirst);
+		pDefectInfo->m_nCameraID = pDefect->m_nCameraID;
+		pDefectInfo->m_nScanIdx = pDefect->m_nScanIdx;
+		pDefectInfo->m_nLevelRefMax = pDefect->m_nLevelRefMax;
+		pDefectInfo->m_nLevelRefMin = pDefect->m_nLevelRefMin;
+		pDefectInfo->m_nLevelRefAvg = pDefect->m_nLevelRefAvg;
+		pDefectInfo->m_nUMCenterAlignX = pDefect->m_nUMCenterAlignX;
+		pDefectInfo->m_nUMCenterAlignY = pDefect->m_nUMCenterAlignY;
+		pDefectInfo->m_nUMCellX = pDefect->m_nUMCellX;
+		pDefectInfo->m_nUMCellY = pDefect->m_nUMCellY;
+		pDefectInfo->m_nScratchRatio = pDefect->m_nScratchRatio;
+		pDefectInfo->m_nDensity = pDefect->m_nDensity;
+		pDefectInfo->m_bMergeState = pDefect->m_bMergeState;
+	}
+}
+
+void CReveiwHistoryDlg::AddVecImageSorting(int nDataCount)
+{
+	m_Formation.m_vecTempImage.clear();
+
+	for (int i = 0; i < m_Formation.m_vecImage.size(); i++)
+	{
+		_akReviewList* pDefect = &m_Formation.m_vecImage[i];
+
+		m_Formation.AddDefectImageTemp();
+			
+		_akReviewList* pImageInfo = &m_Formation.m_vecTempImage[i];
+
+		pImageInfo->m_nDefectID = pDefect->m_nDefectID;
+		strcpy(pImageInfo->m_strAoiImageName, pDefect->m_strAoiImageName);
+		pImageInfo->m_nDefectIdx = pDefect->m_nDefectIdx;
+		pImageInfo->m_strReviewImageName = pDefect->m_strReviewImageName;
+
+		strcpy(pImageInfo->m_strAoiImagePath, pDefect->m_strAoiImagePath);
+		strcpy(pImageInfo->m_strReviewImagePath, pDefect->m_strReviewImagePath);
+
+		strcpy(pImageInfo->m_strAlignFirst, pDefect->m_strAlignFirst);
+		strcpy(pImageInfo->m_strAlignSecond, pDefect->m_strAlignSecond);
+	}
+}
+
+void CReveiwHistoryDlg::AddVecCellSorting(int nCellCount)
+{
+	m_FormationMap.m_vecTempCellRect.clear();
+
+	for (int i = 0; i < m_FormationMap.m_vecCellRect.size(); i++)
+	{
+		m_FormationMap.AddCellData();
+		m_FormationMap.m_vecTempCellRect[i] = m_FormationMap.m_vecCellRect[i];
+	}
+}
+
+void CReveiwHistoryDlg::SelectCell(int nDataCount)
+{
+	m_FormationMap.m_vecCellRect.clear();
+
+	if (nDataCount < 1) return;
+
+	int nCellCount = 0;
+	int nCount = 0;
+	int nCount2 = 0;
+	int nCount3 = 0;
+
+	if (nCount == nDataCount) return;	
+
+	if (m_Formation.m_vecGlassInfo.size() == 0) return;
+
+	_akGlassInfo* pGlass2 = &m_Formation.m_vecGlassInfo[nDataCount-1];
+
+	nCount2 = pGlass2->m_nCellNum;
+
+	for (int i = 0; i < nDataCount; i++)
+	{
+		if (i == 0)
+		{
+			nCount3 = 0;
+		}
+		else
+		{
+			_akGlassInfo* pGlass = &m_Formation.m_vecGlassInfo[i-1];
+			nCount3 += pGlass->m_nCellNum;
+		}
+	}
+
+	CakRectd rectCell;
+
+	if (m_FormationMap.m_vecTempCellRect.size() - 1 < nCount3) return;
+
+	for (int i = 0; i < nCount2; i++)
+	{
+		CakRectd* pCellData = &m_FormationMap.m_vecTempCellRect[nCount3 + i];
+		rectCell.left = pCellData->left;
+		rectCell.top = pCellData->top;
+		rectCell.right = pCellData->right;
+		rectCell.bottom = pCellData->bottom;
+		m_FormationMap.m_vecCellRect.push_back(rectCell);
+	}
+
+// 	for (int i = 0; i < MAX_COUNT+1; i++)
+// 	{
+// 		if (nCount == nDataCount) break;
+// 
+// 		if (m_nCellSize[i] != 0)
+// 		{
+// 			nCount++;
+// 		}
+// 		nCellCount = m_nCellSize[i];
+// 		nCount2 = i;
+// 
+// 		if (i == 0)
+// 		{
+// 			nCount3 = 0;
+// 		}
+// 		else
+// 		{
+// 			nCount3 += m_nCellSize[i-1];
+// 		}		
+// 	}
+		m_FormationMap.ReDraw(TRUE);
+}
+
+void CReveiwHistoryDlg::SortFileList(int nCol)
+{
+	if (nCol == 0)
+		return;
+
+	_akReviewHeader	*pReviewHeader;
+	std::vector< std::pair<CString, _akReviewHeader*> > vecString;
+	std::vector< std::pair<double, _akReviewHeader*> > vecValue;
+	CString strValue;
+	double dValue;
+	short sValue[16];
+
+	for (int i = 0; i < m_Formation.m_vecHeaderTemp.size(); i++)
+	{
+		pReviewHeader = &m_Formation.m_vecHeaderTemp[i];
+
+		switch (nCol)
+		{
+		case 1: strValue = pReviewHeader->m_strFileTime; break;
+		case 2:	strValue = pReviewHeader->m_strLoading; break;
+		case 3:	strValue = pReviewHeader->m_strPPID; break;
+		case 4: strValue = pReviewHeader->m_strGlassID; break;
+		case 5:	dValue = pReviewHeader->m_nDefectIdx; break;
+		case 6:	dValue = pReviewHeader->m_nReviewIdx; break;
+		case 7:	strValue = pReviewHeader->m_strJudge; break;
+		case 8:	strValue = pReviewHeader->m_strFileName; break;
+		}
+
+		if (strValue.IsEmpty() == FALSE) vecString.push_back(std::make_pair(strValue, pReviewHeader));
+		else vecValue.push_back(std::make_pair(dValue, pReviewHeader));
+	}
+
+	if (!vecString.empty())
+	{
+		std::sort(vecString.begin(), vecString.end(), std::greater< std::pair<CString, _akReviewHeader*> >());
+
+		m_Formation.m_vecHeader.clear();
+		std::vector< std::pair<CString, _akReviewHeader*> >::iterator itVec;
+		//	/*if(nCount > m_nFileCount) break; //count �뿬湲곗꽌 留먭퀬 �쟾泥� �뙆�씪�쓣 �떎 �씫�� �썑�뿉 �떎�떆 �냼�똿�븯�옄*/
+		int nCount = 1;
+		for (itVec = vecString.begin(); itVec != vecString.end(); ++itVec)
+		{
+			if(nCount > m_nFileCount) break;
+			m_Formation.m_vecHeader.push_back(*itVec->second);
+			nCount++;
+		}
+	}
+	else
+	{
+		std::sort(vecValue.begin(), vecValue.end(), std::greater< std::pair<double, _akReviewHeader*> >());
+		
+		m_Formation.m_vecHeader.clear();
+		std::vector< std::pair<double, _akReviewHeader*> >::iterator itVec;
+		int nCount = 1;
+		for (itVec = vecValue.begin(); itVec != vecValue.end(); ++itVec)
+		{
+			if (nCount > m_nFileCount) break;
+			m_Formation.m_vecHeader.push_back(*itVec->second);
+			nCount++;
+		}
+	}
+
+	_akReviewHeader	*pReview;
+	m_vecStrGridReviewPath.clear();
+	m_vecStrGridReviewList.clear();
+
+	GV_ITEM Item;
+	int nRowIdx = 0;
+	int nColIdx = 0;
+	CString strTemp;
+	Item.mask = GVIF_TEXT;
+
+	for(int i=0; i< m_Formation.m_vecHeader.size(); i++)
+	{ 
+		pReview = &m_Formation.m_vecHeader[i];
+		m_vecStrGridReviewPath.push_back(pReview->m_strFilePath);
+		m_vecStrGridReviewList.push_back(pReview->m_strFileName);
+	}
+	m_Formation.m_vecHeaderTemp.clear();
+}
diff --git a/ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.h b/ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.h
new file mode 100644
index 0000000..c7bcab0
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/ReveiwHistoryDlg.h
@@ -0,0 +1,275 @@
+癤�
+// ReveiwHistoryDlg.h: �뿤�뜑 �뙆�씪
+//
+
+#pragma once
+
+#include "akFormationMap.h"
+#include "akGridData.h"
+#include "AlignDlg.h"
+#include "akWndArrange.h"
+#include "DitGlassRawServer.h"
+#include "GlassRawBase.h"
+#include "akCore/akFileDB.h"
+#include "afxcmn.h"
+#include "akGridCtrl/akGridCtrl.h"
+#include "akImageView.h"
+//#include "CameraImageView.h"
+//#include "CHImageControls/CHRectTracker.h"
+
+
+#define MAX_COUNT	100
+
+struct _DefectList
+{
+	int				m_nFileTime;
+	CString			m_strFileName;
+	CString			m_strLoading;
+	CString			m_strGlassID;
+	CString			m_strPPID;
+	int				m_nReviewCount;
+	int				m_nAllCount;
+	CString			m_strJudge;
+};
+
+// CReveiwHistoryDlg ���솕 �긽�옄
+class CReveiwHistoryDlg : public CDialogEx
+{
+// �깮�꽦�엯�땲�떎.
+public:
+	CReveiwHistoryDlg(CWnd* pParent = nullptr);	// �몴以� �깮�꽦�옄�엯�땲�떎.
+
+// ���솕 �긽�옄 �뜲�씠�꽣�엯�땲�떎.
+#ifdef AFX_DESIGN_TIME
+	enum { IDD = IDD_DLG_REVIEWHISTORY };
+#endif
+
+	protected:
+	virtual void DoDataExchange(CDataExchange* pDX);	// DDX/DDV 吏��썝�엯�땲�떎.
+
+public:
+	CFont m_Filelistfont;
+	CFont m_Defectfont;
+
+	_DefectDisplayOption m_DefectDisplayOption;
+	CakFormationMap m_FormationMap;
+	akDefectFormation m_Formation;
+	CString m_strRawFilePath;
+	CakWndArrange		m_WndArrange;
+
+	CakImageView m_ImageView;
+
+	CAlignDlg* m_pDlgAlign;
+
+	CakGridCtrl m_gridMultiLIst;
+	std::vector<CString> m_vecStrGridMultiHeader;
+
+	CakGridCtrl m_gridReviewList;
+	std::vector<CString> m_vecStrGridReviewHeader;
+	std::vector<CString> m_vecStrGridReviewList;
+	std::vector<CString> m_vecStrGridReviewPath;
+	std::vector<CString> m_vecStrGridTimeList;
+	std::vector<_DefectList> m_vecStrDefectList;
+
+	CakGridCtrl m_gridDefectInfo;
+	std::vector<CString> m_vecStrGridDefectHeader;
+
+	CakGridCtrl m_gridGlassInfo;
+	std::vector<CString> m_vecStrGridGlassHeader;
+
+	std::vector<CString> m_vecStrReviewTemp;
+	std::vector<_akFormation*>	m_vecSortForm;
+
+	std::vector<_akDefect> m_vectest;
+
+	CImage m_DefectImage;
+	CImage m_ReviewImage;
+
+	CRect m_picture_rect;
+	CRect m_picture_rect2;
+
+	CImage m_AlignFirst;
+	CImage m_AlignSecend;
+
+	CRect m_Align_rect;
+	CRect m_Align_rect2;
+
+	CButton m_chkAllDefect;
+	CButton m_chkReviewDefect;
+	CButton m_chkMuti;
+	CButton m_chkSingle;
+
+	CSliderCtrl m_sldImg;
+	CEdit m_ctrCount;
+
+	CStatic m_ctrReviewImage;
+
+	CEdit m_ctlFileCount;
+
+	CProgressCtrl m_ctlProgress;
+
+	CakGridCtrl m_ctrlGridGlassList;
+
+	// tracker
+	BOOL			m_bDrawTracker;
+	CPoint			m_ptTrackerStart;
+	//CCHRectTracker	m_rectTracker;
+
+	// Scroll Pos
+	int			m_nVScroll;
+	int			m_nHScroll;
+	// Max Scroll Pos
+	int			m_nMaxVScroll;
+	int			m_nMaxHScroll;
+
+///////////////////////////////////////////////////////
+	CDitGlassRawServer m_Server;
+	CGlassRawBase* m_pGlassRawMaker;
+	CgrmGlassRawData m_GlassRawDataBuffer;
+///////////////////////////////////////////////////////
+
+	int m_nSelectedCol;
+	int m_nSelectedRow;
+
+	char m_strConfigFile[MAX_PATH];
+
+	bool m_bDefectAll;
+	bool m_bFirst;
+	int m_nCount;
+
+	int m_nGlassSelect;
+	int m_nFileCount;
+	int m_nSelectFile[105];
+	int m_nDefectSize[105];
+	int m_nCellSize[105];
+	int m_nCellSizeTemp[105];
+	int m_nImageSize[105];
+	int m_nSizeDefect;
+	int m_nSizeImage;
+	int m_nDefectCount;
+	int m_nImageCount;
+	int m_nCellCount;
+
+	BOOL m_bAsending;
+
+	struct _InitOption
+	{
+		int m_nMaxDataNumCell;
+		int m_nMaxDataNumDefect;
+
+		int m_nSelectRawType;
+
+		char m_strLogFilePath[256];
+
+		int  m_bUseStack;
+		char m_strStackLocalPath[256];
+		char m_strStackEquipID[32];
+		char m_strStackParam1[32];
+		char m_strStackParam2[32];
+	}m_ConfigOption;
+	
+// 援ы쁽�엯�땲�떎.
+protected:
+	HICON m_hIcon;
+
+	// �깮�꽦�맂 硫붿떆吏� 留� �븿�닔
+	virtual BOOL OnInitDialog();
+	afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
+	afx_msg void OnPaint();
+	afx_msg HCURSOR OnQueryDragIcon();
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+	DECLARE_MESSAGE_MAP()
+
+	void AddVecFileHeader();
+	void AddVecGlassHeader();
+	void AddVecDefectHeader();
+
+	void SlideInit();
+
+	void InitGridReviewLIst(CakGridCtrl* pGrid, UINT nRectCtrlID);
+	void InitGridGlassLIst(CakGridCtrl * pGrid, UINT nRectCtrlID);
+	void InitGridDefectLIst(CakGridCtrl* pGrid, UINT nRectCtrlID);
+	
+	void CreateUserDirectory();
+	void CreateUserClass();
+	void DestroyUserClass();
+
+	void getDispInfoGlass(int nCol, int nRow, CString* pStrData);
+	void getDispInfoGlassInfo(int nCol, int nRow, CString * pStrData);
+	void getDispInfoDefect(int nCol, int nRow, CString* pStrData);
+
+public:
+	afx_msg void OnBnClickedButtonMapviewFit();
+	afx_msg void OnDestroy();
+	afx_msg LRESULT OnMapDefectSelected(WPARAM wParam, LPARAM lParam);
+	afx_msg LRESULT OnMapDefectMouseOver(WPARAM wParam, LPARAM lParam);
+	afx_msg LRESULT OnListDefectSelected(WPARAM wParam, LPARAM lParam);
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+
+	afx_msg void OnOptionPathsetting();
+	afx_msg void OnViewAlldefect();
+	afx_msg void OnViewReviewdefect();
+	afx_msg void OnAlignView();
+	afx_msg void OnBnClickedBtnFindBin();
+	afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+	afx_msg void OnChangeEditCount();
+
+	afx_msg void OnClickedChkAllDefect();
+	afx_msg void OnClickedChkMuti();
+	afx_msg void OnClickedChkReviewDefect();
+	afx_msg void OnClickedChkSingle();
+	afx_msg void OnChangeEditFileCount();
+
+	afx_msg void OnBnClickedButton3();
+
+	virtual BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult);
+
+	void FileTime(CString strPath);
+	void OpenFileHeader(CString strPath, CString strFullPath);
+	void BinFileOpen(int nCount);
+	void OnCbnSelchangeComboRawtype();
+
+	
+	void ShowProgressBar();
+	void setDefectShow(int nDefectID, BOOL bEnsureVisible);
+	void ImageShow(int nDefectID);
+
+	void SetScrollSetting();
+	void SetScrollRest();
+
+	void Imagenoload();
+
+	BOOL GetCheckFileLoad(int nCount);
+
+	void GlassInfoRest();
+	BOOL MultiSelectCheck(int nSelectCount);
+	int MultiInsert(int nSelectCount, int nDataCount);
+	void InitSelectGlass(int nSelectCount);
+
+	void AddVecDataImage(int nDataCount);
+	void AddVecDataDefct(int nDataCount);
+	void AddVecDataDefectAll(int nDataCount);
+	void AddVecDataDefct2(int nDataCount/*, int nRawCount*/);
+	void AddVecDataDefectAll2(int nDataCount/*, int nRawCount*/);
+	void AddVecGlassData(int nCount);
+	void AddVecCellData(int nCellCount);
+	void AddVecDateSorting(int nDataCount);
+	void AddVecImageSorting(int nDataCount);
+	void AddVecCellSorting(int nCellCount);
+
+	void SelectCell(int nDataCount);
+
+	void SortFileList(int nCol);
+	void SortListDefect(int nCol);
+
+	void SetDefectCount() {	m_nDefectCount = m_nDefectCount + 1; }
+	int	GetDefectCount() { return m_nDefectCount; }
+
+	void SetImageCount() { m_nImageCount = m_nImageCount + 1; }
+	int	GetImageCount() { return m_nImageCount; }
+
+	void SetCellCount() { m_nCellCount = m_nCellCount + 1; }
+	int	GetCellCount() { return m_nCellCount; }
+
+};
diff --git a/ReviewHistory/ReveiwHistory/Singleton.h b/ReviewHistory/ReveiwHistory/Singleton.h
new file mode 100644
index 0000000..003088b
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/Singleton.h
@@ -0,0 +1,35 @@
+#pragma once
+
+template <typename T>
+class CSingleton
+{
+public:
+	CSingleton() {}
+	virtual ~CSingleton() {}
+
+	static void CreateClass()
+	{
+		if ( !m_pMgr )
+			m_pMgr = new T;
+	}
+
+	static void DestroyClass()
+	{
+		if ( m_pMgr )
+		{
+			delete m_pMgr;
+
+			m_pMgr = NULL;
+		}
+	}
+
+	static T* GetMgr()
+	{
+		return m_pMgr;
+	}
+
+private:
+	static T* m_pMgr;
+};
+
+template<typename T> T* CSingleton<T>::m_pMgr = NULL;
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/StackResultCPJT.cpp b/ReviewHistory/ReveiwHistory/StackResultCPJT.cpp
new file mode 100644
index 0000000..cc904f5
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/StackResultCPJT.cpp
@@ -0,0 +1,337 @@
+#include "StdAfx.h"
+#include "StackResultCPJT.h"
+#include "akLoggerExt.h"
+#include "akCore/akFileDB.h"
+#include <process.h>
+#include "DitGlassRawClient.h"
+#include "GlassRawBase.h"
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+CStackResultCPJT::CStackResultCPJT(void)
+{
+	m_nThreadStackFileReadFlag = 0;
+	m_strConfigFile;
+	{
+		GetModuleFileName(NULL, m_strConfigFile, MAX_PATH);
+		char* ext = CakFileUtil::getFileExt(m_strConfigFile);
+		strcpy(ext, "ini");
+	}
+
+	m_nProcessState = SPS_StateIdle;
+	readOptionFile();
+}
+
+CStackResultCPJT::~CStackResultCPJT(void)
+{
+	if(m_nThreadStackFileReadFlag == 1)
+	{
+		m_nThreadStackFileReadFlag = 2;
+		while(m_nThreadStackFileReadFlag != 0)
+		{
+			Sleep(1);
+		}
+	}
+
+	m_vecStackDefect.clear();
+}
+
+//201218 CJH - Stack File open
+BOOL CStackResultCPJT::openFile( char* pGlassID )
+{
+	CString strFileName;
+
+	CDitGlassRawClient	GlassRawClient;
+	GlassRawClient.ConnectServer();
+	CDitGlassRawClient* pShared = &GlassRawClient;
+	
+	_grmDefectData* pGrmStack;
+
+	strFileName.Format("%s\\%s", m_strLocalPath, pGlassID);
+
+	FILE* pf = fopen(strFileName.GetBuffer(0), "r");
+
+	if(pf == NULL)
+		return FALSE;
+
+	std::vector<_StackDefectCPJT> vecStackDefect;
+	_StackDefectCPJT StackDefect;
+	char buffer[2048];
+
+	char* pReadPoint = NULL;
+	char *pStr;
+	CString tempStr, strRight;
+
+	while(!feof(pf)) //Data 시작
+	{
+		pStr = fgets(buffer, 2048, pf);
+		
+		if(strncmp(buffer, "DATA", 4)) continue; //Data 시작
+
+		if(strlen(buffer) <= 0 || pStr == NULL)
+			break;
+
+		if(strncmp(buffer, "DATA DEFECT", 10)) continue; //Defect 찾아
+		
+		//Defect Stack Start
+		{
+			pReadPoint = buffer;
+			int temp;
+			
+			pReadPoint = getParsingData(pReadPoint, 11, &temp);
+			pReadPoint = getParsingData(pReadPoint, 12, &StackDefect.m_strCellName);
+			pReadPoint = getParsingData(pReadPoint, 5, &StackDefect.m_nDefectID);
+			pReadPoint = getParsingData(pReadPoint, 8, &StackDefect.m_nPosX);
+			pReadPoint = getParsingData(pReadPoint, 8, &StackDefect.m_nPosY);
+
+			pReadPoint = getParsingData(pReadPoint, 13, &temp);
+			pReadPoint = getParsingData(pReadPoint, 4, &StackDefect.m_nSize);
+			pReadPoint = getParsingData(pReadPoint, 4, &StackDefect.m_nUmSizeX);
+			pReadPoint = getParsingData(pReadPoint, 4, &StackDefect.m_nUmSizeY);
+			pReadPoint = getParsingData(pReadPoint, 4, &StackDefect.m_nDefectRScale);
+			pReadPoint = getParsingData(pReadPoint, 4, &StackDefect.m_strDefectGrade);
+			pReadPoint = getParsingData(pReadPoint, 4, &StackDefect.m_strDefectType);
+
+			//pReadPoint = getParsingData(pReadPoint, 47, &temp);
+			pReadPoint = getParsingData(pReadPoint, 2, &temp);
+			pReadPoint = getParsingData(pReadPoint, 2, &StackDefect.m_nStackCnt);
+			pReadPoint = getParsingData(pReadPoint, 60, &StackDefect.m_strStackStep);
+		
+			vecStackDefect.push_back(StackDefect);
+		}
+	}
+
+	//For Test
+	AKLOG("Read Stack Size : %d", vecStackDefect.size());
+
+	fclose(pf);
+
+	m_vecStackDefect = vecStackDefect;
+
+	for (int i = 0; i < m_vecStackDefect.size(); i++)
+	{
+		pGrmStack = pShared->GetStackData(i);
+		pGrmStack->clear();
+
+		//Cell ID로 idx 찾기
+		{
+			//char* g_pCellCode = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+			//'0' + pCellData->m_nCellID / 36, g_pCellCode[pCellData->m_nCellID % 36]
+			tempStr = m_vecStackDefect[i].m_strCellName.Right(2);
+			int nUpper = atoi(tempStr.Left(1));
+			nUpper *= 36;
+			
+			char ctemp[2];
+			strRight = tempStr.Right(1);
+			strcpy(ctemp, strRight);
+			int nLower = static_cast<int>(ctemp[0]);
+			if (48 <= nLower && nLower <= 57)
+				nLower = 43 /* 65+26+17 */ + nLower;
+			nLower -= 65;
+
+			pGrmStack->m_nCellIdx = nUpper + nLower;
+		}
+
+		pGrmStack->m_nDefectID = m_vecStackDefect[i].m_nDefectID;
+		pGrmStack->m_nUMCenterAlignX = m_vecStackDefect[i].m_nPosX;
+		pGrmStack->m_nUMCenterAlignY = (-1)*m_vecStackDefect[i].m_nPosY;
+		pGrmStack->m_nPixelSize = m_vecStackDefect[i].m_nSize;
+		pGrmStack->m_nUMSizeX = m_vecStackDefect[i].m_nUmSizeX;
+		pGrmStack->m_nUMSizeY = m_vecStackDefect[i].m_nUmSizeY;
+		pGrmStack->m_nDefectRScale = m_vecStackDefect[i].m_nDefectRScale;
+		//Judgement
+		{
+			m_vecStackDefect[i].m_strDefectGrade.TrimLeft(" ");
+			m_vecStackDefect[i].m_strDefectGrade.TrimRight(" ");
+			if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "OK")) pGrmStack->m_DefectJudgement = Judge_OK;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "RP")) pGrmStack->m_DefectJudgement = Judge_RP;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "NG")) pGrmStack->m_DefectJudgement = Judge_NG;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "TR")) pGrmStack->m_DefectJudgement = Judge_TR;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "PR")) pGrmStack->m_DefectJudgement = Judge_PR;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "PT")) pGrmStack->m_DefectJudgement = Judge_PT;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "RV")) pGrmStack->m_DefectJudgement = Judge_Review;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "RC")) pGrmStack->m_DefectJudgement = Judge_RC;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "SZ")) pGrmStack->m_DefectJudgement = Judge_Size;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "VI")) pGrmStack->m_DefectJudgement = Judge_VI;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "RW")) pGrmStack->m_DefectJudgement = Judge_Rework;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "UK")) pGrmStack->m_DefectJudgement = Judge_Unknown;
+			else /*if (!strcmp(m_vecStackDefect[i].m_strDefectGrade, "그외"))*/ pGrmStack->m_DefectJudgement = Judge_OK;
+		}
+		m_vecStackDefect[i].m_strDefectType.TrimLeft(" ");
+		m_vecStackDefect[i].m_strDefectType.TrimRight(" ");
+		//Defect Type
+		{
+			if (!strcmp(m_vecStackDefect[i].m_strDefectType, "RB")) pGrmStack->m_DefectType = DefectType_RBlack;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectType, "RW")) pGrmStack->m_DefectType = DefectType_RWhite;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectType, "TB")) pGrmStack->m_DefectType = DefectType_TBlack;
+			else if (!strcmp(m_vecStackDefect[i].m_strDefectType, "TW")) pGrmStack->m_DefectType = DefectType_TWhite;
+			else pGrmStack->m_DefectType = DefectType_Unknown;
+		}
+		pGrmStack->m_nStackStepCount = m_vecStackDefect[i].m_nStackCnt;
+		m_vecStackDefect[i].m_strStackStep.TrimLeft(" ");
+		m_vecStackDefect[i].m_strStackStep.TrimRight(" ");
+		strcpy(pGrmStack->m_strStackFirst, m_vecStackDefect[i].m_strStackStep.GetBuffer(0));
+	}
+
+	pShared->GetGlassData()->m_nStackNum = m_vecStackDefect.size();
+	pShared->GetGlassData()->m_bStackRead = TRUE;
+
+	AKLOG("Import Vector Size : %d", m_vecStackDefect.size());
+
+	return TRUE;
+}
+
+char* CStackResultCPJT::getParsingData( char* pBuf, int nLen, CString* pOutData )
+{
+	for(int i=nLen-1; i>=0; i--)
+	{
+		if(pBuf[i] != ' ')
+		{
+			pBuf[i+1] = 0;
+			break;
+		}
+	}
+	*pOutData = pBuf;
+
+	return &pBuf[nLen+1]; //구분자 건너 뛰어서 다음 읽을 포인트 넘겨준다 태현[2017/3/29]
+}
+
+char* CStackResultCPJT::getParsingData( char* pBuf, int nLen, int* pOutData )
+{
+	pBuf[nLen] = 0;
+
+	*pOutData = atoi(pBuf);
+
+	return &pBuf[nLen+1]; //구분자 건너 뛰어서 다음 읽을 포인트 넘겨준다 태현[2017/3/29]
+}
+
+BOOL CStackResultCPJT::readOptionFile( char* pFileName /*= "C:\\AOIServer\\ConfigFile\\MacroInfo.cfg"*/ )
+{
+	if(pFileName == NULL) pFileName = m_strConfigFile;
+
+	CakFileDB akFileDB;
+	akFileDB.openfile(pFileName);
+	
+	akFileDB.getItem("Stack_Use", &m_bStackUse, 0);
+	akFileDB.getItem("Stack_LocalPath", m_strLocalPath, "D:\\DIT_ResultData\\Stack");
+	akFileDB.getItem("Stack_EquipID", m_strEquipID, "qa6500f0r03");
+	akFileDB.getItem("Stack_Param1", m_strParam1, "");
+	
+
+	if(m_bStackUse && m_nThreadStackFileReadFlag == 0)//쓰레드 생성 [김태현 2019/1/12]
+	{
+		_beginthread(threadStackFileRead, NULL, this);
+	}
+	return TRUE;
+}
+
+void CStackResultCPJT::threadStackFileRead( void* pArg )
+{
+	CStackResultCPJT* pThis = (CStackResultCPJT*)pArg;
+
+	pThis->m_nThreadStackFileReadFlag = 1;
+	int nSleepTime = 1000;
+	int nReadFailCount = 0;
+	int nThreadCount=0;
+	CString strGlassID;
+
+// 	CDitGlassRawClient	GlassRawClient;
+// 	if(!GlassRawClient.ConnectServer()) return;
+// 	CDitGlassRawClient* pShared = &GlassRawClient;
+
+// 	pShared->GetGlassData()->m_bStackRead = FALSE;
+// 	pShared->GetGlassData()->m_nStackNum = 0;
+	
+	while(pThis->m_nThreadStackFileReadFlag==1)
+	{
+		if(pThis->m_nProcessState == SPS_CmdFileRead) //스택파일 읽기 수행 [김태현 2019/1/12]
+		{
+			strGlassID = pThis->m_strGlassID;
+			//For test
+			//strGlassID = "HPANELID";
+			pThis->m_nProcessState = SPS_StateFileRead;
+			nThreadCount = 0;
+			nReadFailCount = 0;
+
+			AKLOG("Stack File Read Start : %s\\%s", pThis->m_strLocalPath, strGlassID);
+
+			//210111 CJH - Stack Read Sleep
+			Sleep(3000);
+
+			while(pThis->m_nProcessState == SPS_StateFileRead && pThis->m_nThreadStackFileReadFlag==1)
+			{
+				if((nThreadCount++ % 20) != 0) //명령 수행을 빠르게 감지 위한 조치 [김태현 2019/1/12]
+				{
+					Sleep(50);
+					continue;
+				}
+
+				if(pThis->openFile(strGlassID.GetBuffer(0)) == TRUE)
+				{
+					pThis->m_nProcessState = SPS_ResultReadOK;
+					AKLOG("Stack File Read Complete ");
+					break;
+				}
+
+				nReadFailCount++;
+				AKLOG("Stack File Read Try : %d", nReadFailCount);
+
+				if(nReadFailCount>100)
+				{
+					pThis->m_nProcessState = SPS_ResultReadFail;
+					AKLOG("Stack File Read Fail ");
+					break;
+				}
+
+				Sleep(50);
+			}
+			if(pThis->m_nProcessState != SPS_ResultReadOK)
+			{
+				pThis->m_nProcessState = SPS_ResultReadFail;
+				AKLOG("Stack File Read Stop ");
+			}
+
+			
+		}
+		if(nReadFailCount)
+
+
+		Sleep(500);
+	}
+
+	pThis->m_nThreadStackFileReadFlag = 0;
+}
+
+BOOL CStackResultCPJT::StackFileReadStart( char* pGlassID )
+{
+	if(m_nThreadStackFileReadFlag == 0)//쓰레드 생성 [김태현 2019/1/12]
+	{
+		_beginthread(threadStackFileRead, NULL, this);
+	}
+
+	if(m_nProcessState == SPS_StateFileRead)
+	{
+		m_nProcessState = SPS_CmdFileStop;
+		while(m_nProcessState == SPS_CmdFileStop) Sleep(0);
+	}
+
+	m_strGlassID = pGlassID;
+	m_nProcessState = SPS_CmdFileRead;
+	
+	return TRUE;
+}
+
+BOOL CStackResultCPJT::StackFileReadStop( BOOL bWait/*=TRUE*/ )
+{
+	if(bWait == TRUE && m_nProcessState == SPS_StateFileRead)
+	{
+		m_nProcessState = SPS_CmdFileStop;
+		while(m_nProcessState == SPS_CmdFileStop) Sleep(0);
+	}
+
+	return TRUE;
+}
diff --git a/ReviewHistory/ReveiwHistory/StackResultCPJT.h b/ReviewHistory/ReveiwHistory/StackResultCPJT.h
new file mode 100644
index 0000000..80da903
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/StackResultCPJT.h
@@ -0,0 +1,87 @@
+#pragma once
+
+#include <vector>
+#include "akCore/akFileUtil.h"
+
+
+//enum Judgement { Judge_OK = 0, Judge_RP, Judge_NG, Judge_TR, Judge_PR, Judge_PT, Judge_Review, Judge_RC, Judge_Size, Judge_VI, Judge_Rework, Judge_Unknown };//2016.07.13 LHS Judge_Size 추가
+
+struct _StackDefectCPJT
+{
+	int	m_nDefectID			;
+	//char	m_strCellID[32]	;
+	CString m_strCellName	;
+	int		m_nPosX			;
+	int		m_nPosY			;
+	int		m_nSize			;
+	int		m_nUmSizeX		;
+	int		m_nUmSizeY		;
+	int		m_nDefectRScale	;
+	CString	m_strDefectGrade;
+	CString m_strDefectType ;
+	int		m_nStackCnt		;
+	CString m_strStackStep	;
+	//char	m_strJudge[16]	;
+	//char	m_strCode[16]	;
+};
+
+class CStackResultCPJT
+{
+public:
+	CStackResultCPJT(void);
+	virtual ~CStackResultCPJT(void);
+protected:
+	enum emStackProcessState
+	{
+		SPS_StateIdle = 0,
+		SPS_StateFileRead, //읽기 수행 중
+		SPS_ResultReadOK,
+		SPS_ResultReadFail,
+		SPS_CmdFileRead, //읽기 명령 수행
+		SPS_CmdFileStop, //읽기 명령 수행 중지
+
+		SPS_Num
+	};
+public:
+	void clear()
+	{
+		m_vecStackDefect.clear();
+	}
+
+	BOOL StackFileReadStart(char* pGlassID);
+	BOOL StackFileReadStop(BOOL bWait=TRUE);
+	BOOL IsRead() { return m_nProcessState == SPS_ResultReadOK?TRUE:FALSE; }
+
+	int GetDefectNum() { return (int)m_vecStackDefect.size();}
+	_StackDefectCPJT* GetDefect(int i) { return &m_vecStackDefect[i]; }
+	
+	BOOL readOptionFile(char* pFileName = NULL);
+
+	BOOL getStackUse(){return m_bStackUse;};
+	char* getStackEquipID(){return m_strEquipID;};
+	char* getStackOperID(){return m_strParam1;};
+	char* getStackLocalPath(){return m_strLocalPath;};
+protected:
+	BOOL openFile( char* pGlassID );
+
+	static void threadStackFileRead(void* pArg);
+	int	m_nThreadStackFileReadFlag;
+	
+protected:
+	char m_strConfigFile[MAX_PATH];
+	BOOL m_bStackUse;
+	char m_strLocalPath[MAX_PATH];
+	char m_strEquipID[32];
+	char m_strParam1[32]; //operid
+
+	emStackProcessState m_nProcessState;//-1:읽기실패,0:Idle, 1:읽기성공, 2:읽기시도(읽기중)
+	std::vector<_StackDefectCPJT> m_vecStackDefect;
+
+	CString	m_strGlassID;
+protected:
+	char* getParsingData(char* pBuf, int nLen, CString* pOutData);
+	char* getParsingData(char* pBuf, int nLen, int* pOutData);
+
+
+
+};
diff --git a/ReviewHistory/ReveiwHistory/StackResultCSOT.cpp b/ReviewHistory/ReveiwHistory/StackResultCSOT.cpp
new file mode 100644
index 0000000..0a26a55
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/StackResultCSOT.cpp
@@ -0,0 +1,226 @@
+#include "StdAfx.h"
+#include "StackResultCSOT.h"
+#include "akLoggerExt.h"
+#include "akCore/akFileDB.h"
+#include <process.h>
+
+#ifdef _DEBUG
+#undef THIS_FILE
+static char THIS_FILE[]=__FILE__;
+#define new DEBUG_NEW
+#endif
+
+CStackResultCSOT::CStackResultCSOT(void)
+{
+	m_nThreadStackFileReadFlag = 0;
+	m_strConfigFile;
+	{
+		GetModuleFileName(NULL, m_strConfigFile, MAX_PATH);
+		char* ext = CakFileUtil::getFileExt(m_strConfigFile);
+		strcpy(ext, "ini");
+	}
+
+	m_nProcessState = SPS_StateIdle;
+	readOptionFile();
+}
+
+CStackResultCSOT::~CStackResultCSOT(void)
+{
+	if(m_nThreadStackFileReadFlag == 1)
+	{
+		m_nThreadStackFileReadFlag = 2;
+		while(m_nThreadStackFileReadFlag != 0)
+		{
+			Sleep(1);
+		}
+	}
+
+	m_vecMacroDefect.clear();
+}
+
+BOOL CStackResultCSOT::openFile( char* pGlassID )
+{
+	CString strFileName;
+
+	strFileName.Format("%s\\%s.txt", m_strLocalPath, pGlassID);
+
+	FILE* pf = fopen(strFileName.GetBuffer(0), "r");
+
+	if(pf == NULL)
+		return FALSE;
+
+	std::vector<_StackDefect> vecMacroDefect;
+	_StackDefect MacroDefect;
+	char buffer[1024];
+
+	char* pReadPoint = NULL;
+	char *pStr;
+
+	while(!feof(pf))
+	{
+		pStr = fgets(buffer, 1024, pf);
+		
+		if(!strncmp(buffer, "ITEM,", 5)) continue;
+
+		
+		if(strlen(buffer) <= 0 || pStr == NULL)
+			break;
+		
+		if(!strncmp(buffer, "DATA,CELLDATA", 13))//파싱 태현[2017/3/29]
+		{
+			//무라 셀판정도 반영 해야 하나?
+		}
+		else if(!strncmp(buffer, "DATA,DEFECTDATA", 15))//파싱 태현[2017/3/29]
+		{
+			pReadPoint = buffer;
+			
+		
+
+			vecMacroDefect.push_back(MacroDefect);
+		}
+	}
+
+	fclose(pf);
+
+	m_vecMacroDefect = vecMacroDefect;
+	return TRUE;
+}
+
+char* CStackResultCSOT::getParsingData( char* pBuf, int nLen, CString* pOutData )
+{
+	for(int i=nLen-1; i>=0; i--)
+	{
+		if(pBuf[i] != ' ')
+		{
+			pBuf[i+1] = 0;
+			break;
+		}
+	}
+	*pOutData = pBuf;
+
+	return &pBuf[nLen+1]; //구분자 건너 뛰어서 다음 읽을 포인트 넘겨준다 태현[2017/3/29]
+}
+
+char* CStackResultCSOT::getParsingData( char* pBuf, int nLen, int* pOutData )
+{
+	pBuf[nLen] = 0;
+
+	*pOutData = atoi(pBuf);
+
+	return &pBuf[nLen+1]; //구분자 건너 뛰어서 다음 읽을 포인트 넘겨준다 태현[2017/3/29]
+}
+
+BOOL CStackResultCSOT::readOptionFile( char* pFileName /*= "C:\\AOIServer\\ConfigFile\\MacroInfo.cfg"*/ )
+{
+	if(pFileName == NULL) pFileName = m_strConfigFile;
+
+	CakFileDB akFileDB;
+	akFileDB.openfile(pFileName);
+	
+	akFileDB.getItem("Stack_Use", &m_bStackUse, 0);
+	akFileDB.getItem("Stack_LocalPath", m_strLocalPath, "D:\\DIT_ResultData\\Stack");
+	akFileDB.getItem("Stack_EquipID", m_strEquipID, "AAAAA");
+	akFileDB.getItem("Stack_Param1", m_strParam1, "");
+	
+
+	if(m_bStackUse && m_nThreadStackFileReadFlag == 0)//쓰레드 생성 [김태현 2019/1/12]
+	{
+		_beginthread(threadStackFileRead, NULL, this);
+	}
+	return TRUE;
+}
+
+void CStackResultCSOT::threadStackFileRead( void* pArg )
+{
+	CStackResultCSOT* pThis = (CStackResultCSOT*)pArg;
+
+	pThis->m_nThreadStackFileReadFlag = 1;
+	int nSleepTime = 1000;
+	int nReadFailCount = 0;
+	int nThreadCount=0;
+	CString strGlassID;
+	
+	while(pThis->m_nThreadStackFileReadFlag==1)
+	{
+		if(pThis->m_nProcessState == SPS_CmdFileRead) //스택파일 읽기 수행 [김태현 2019/1/12]
+		{
+			strGlassID = pThis->m_strGlassID;
+			pThis->m_nProcessState = SPS_StateFileRead;
+			nThreadCount = 0;
+			nReadFailCount = 0;
+
+			AKLOG("Stack File Read Start : %s\\%s.txt", pThis->m_strLocalPath, strGlassID);
+
+			while(pThis->m_nProcessState == SPS_StateFileRead && pThis->m_nThreadStackFileReadFlag==1)
+			{
+				if((nThreadCount++ % 20) != 0) //명령 수행을 빠르게 감지 위한 조치 [김태현 2019/1/12]
+				{
+					Sleep(50);
+					continue;
+				}
+
+				if(pThis->openFile(strGlassID.GetBuffer(0)) == TRUE)
+				{
+					pThis->m_nProcessState = SPS_ResultReadOK;
+					AKLOG("Stack File Read Complete ");
+					break;
+				}
+
+				nReadFailCount++;
+				AKLOG("Stack File Read Try : %d", nReadFailCount);
+
+				if(nReadFailCount>100)
+				{
+					pThis->m_nProcessState = SPS_ResultReadFail;
+					AKLOG("Stack File Read Fail ");
+					break;
+				}
+
+				Sleep(50);
+			}
+			if(pThis->m_nProcessState != SPS_ResultReadOK)
+			{
+				pThis->m_nProcessState = SPS_ResultReadFail;
+				AKLOG("Stack File Read Stop ");
+			}
+
+			
+		}
+		if(nReadFailCount)
+
+
+		Sleep(500);
+	}
+
+	pThis->m_nThreadStackFileReadFlag = 0;
+}
+
+BOOL CStackResultCSOT::StackFileReadStart( char* pGlassID )
+{
+	if(m_nThreadStackFileReadFlag == 0)//쓰레드 생성 [김태현 2019/1/12]
+	{
+		_beginthread(threadStackFileRead, NULL, this);
+	}
+
+	if(m_nProcessState == SPS_StateFileRead)
+	{
+		m_nProcessState = SPS_CmdFileStop;
+		while(m_nProcessState == SPS_CmdFileStop) Sleep(0);
+	}
+
+	m_strGlassID = pGlassID;
+	m_nProcessState = SPS_CmdFileRead;
+	
+	return TRUE;
+}
+
+BOOL CStackResultCSOT::StackFileReadStop( BOOL bWait/*=TRUE*/ )
+{
+	if(bWait == TRUE && m_nProcessState == SPS_StateFileRead)
+	{
+		m_nProcessState = SPS_CmdFileStop;
+		while(m_nProcessState == SPS_CmdFileStop) Sleep(0);
+	}
+
+	return TRUE;
+}
diff --git a/ReviewHistory/ReveiwHistory/StackResultCSOT.h b/ReviewHistory/ReveiwHistory/StackResultCSOT.h
new file mode 100644
index 0000000..a980e0b
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/StackResultCSOT.h
@@ -0,0 +1,76 @@
+#pragma once
+
+#include <vector>
+#include "akCore/akFileUtil.h"
+
+struct _StackDefect
+{
+	int		m_nDefectID		;
+	char	m_strCellID[32]	;
+	int		m_nPosX			;
+	int		m_nPosY			;
+	int		m_nSize			;
+	char	m_strJudge[16]	;
+	char	m_strCode[16]	;
+};
+
+class CStackResultCSOT
+{
+public:
+	CStackResultCSOT(void);
+	virtual ~CStackResultCSOT(void);
+protected:
+	enum emStackProcessState
+	{
+		SPS_StateIdle = 0,
+		SPS_StateFileRead, //읽기 수행 중
+		SPS_ResultReadOK,
+		SPS_ResultReadFail,
+		SPS_CmdFileRead, //읽기 명령 수행
+		SPS_CmdFileStop, //읽기 명령 수행 중지
+
+		SPS_Num
+	};
+public:
+	void clear()
+	{
+		m_vecMacroDefect.clear();
+	}
+
+	BOOL StackFileReadStart(char* pGlassID);
+	BOOL StackFileReadStop(BOOL bWait=TRUE);
+	BOOL IsRead() { return m_nProcessState == SPS_ResultReadOK?TRUE:FALSE; }
+
+	int GetDefectNum() { return (int)m_vecMacroDefect.size();}
+	_StackDefect* GetDefect(int i) { return &m_vecMacroDefect[i]; }
+	
+	BOOL readOptionFile(char* pFileName = NULL);
+
+	BOOL getStackUse(){return m_bStackUse;};
+	char* getStackEquipID(){return m_strEquipID;};
+	char* getStackOperID(){return m_strParam1;};
+	char* getStackLocalPath(){return m_strLocalPath;};
+protected:
+	BOOL openFile( char* pGlassID );
+
+	static void threadStackFileRead(void* pArg);
+	int	m_nThreadStackFileReadFlag;
+	
+protected:
+	char m_strConfigFile[MAX_PATH];
+	BOOL m_bStackUse;
+	char m_strLocalPath[MAX_PATH];
+	char m_strEquipID[32];
+	char m_strParam1[32]; //operid
+
+	emStackProcessState m_nProcessState;//-1:읽기실패,0:Idle, 1:읽기성공, 2:읽기시도(읽기중)
+	std::vector<_StackDefect> m_vecMacroDefect;
+
+	CString	m_strGlassID;
+protected:
+	char* getParsingData(char* pBuf, int nLen, CString* pOutData);
+	char* getParsingData(char* pBuf, int nLen, int* pOutData);
+
+
+
+};
diff --git a/ReviewHistory/ReveiwHistory/aaa.txt b/ReviewHistory/ReveiwHistory/aaa.txt
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/aaa.txt
diff --git a/ReviewHistory/ReveiwHistory/akDefectFormation.cpp b/ReviewHistory/ReveiwHistory/akDefectFormation.cpp
new file mode 100644
index 0000000..fb4f886
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akDefectFormation.cpp
@@ -0,0 +1,98 @@
+#include "stdafx.h"
+#include "akDefectFormation.h"
+#include "akSTL/akStruct.h"
+
+akDefectFormation::akDefectFormation()
+{
+}
+
+akDefectFormation::~akDefectFormation()
+{
+}
+
+void akDefectFormation::Clear()
+{
+	m_vecDefects.clear();
+	m_vecFormation.clear();
+	m_vecImage.clear();
+	m_vecGlassInfo.clear();
+}
+
+void akDefectFormation::AddDefect(double dPosX, double dPosY)
+{
+	_akDefect akDefect;
+	akDefect.dPositionX = dPosX;
+	akDefect.dPositionY = dPosY;
+	akDefect.nLabel = -1;
+	akDefect.nDefectID = -1;
+	akDefect.nFilter = 0;
+	akDefect.nSize = 0;
+	
+	m_vecDefects.push_back(akDefect);
+}
+
+void akDefectFormation::AddDefectTemp(double dPosX, double dPosY)
+{
+	_akDefect akDefect;
+	akDefect.dPositionX = dPosX;
+	akDefect.dPositionY = dPosY;
+	akDefect.nLabel = -1;
+	akDefect.nDefectID = -1;
+	akDefect.nFilter = 0;
+	akDefect.nSize = 0;
+
+	m_vecTempDefects.push_back(akDefect);
+}
+
+void akDefectFormation::AddDefect2()
+{
+	_akDefect akDefect;
+
+	m_vecPath1.push_back(akDefect);
+	m_vecPath2.push_back(akDefect);
+	m_vecPath3.push_back(akDefect);
+	m_vecPath4.push_back(akDefect);
+	m_vecPath5.push_back(akDefect);
+	m_vecPath6.push_back(akDefect);
+}
+
+void akDefectFormation::AddDefectImageTemp()
+{
+	_akReviewList akReviewList;
+	akReviewList.m_strReviewImageName = "";
+	m_vecTempImage.push_back(akReviewList);
+}
+
+void akDefectFormation::AddDefectImage()
+{
+	_akReviewList akReviewList;
+	akReviewList.m_strReviewImageName = "";
+	m_vecImage.push_back(akReviewList);
+}
+
+void akDefectFormation::AddGlassInfo()
+{
+	_akGlassInfo akGlassInfo;
+	akGlassInfo.m_nGlassSelect = -1;
+	akGlassInfo.m_strPPID = "";
+	akGlassInfo.m_strGlassID = "";
+	akGlassInfo.m_nDefectNum = -1;
+	akGlassInfo.m_nReviewNum = -1;
+	akGlassInfo.m_strGlassJudge = "";
+	akGlassInfo.m_strLotID = "";
+	akGlassInfo.m_strSLotID = "";
+	akGlassInfo.m_nSlot_No = -1;
+	akGlassInfo.m_nCellNum = -1;
+	akGlassInfo.m_nGlassSizeHeight = -1;
+	akGlassInfo.m_nGlassSizeWidth = -1;
+
+	m_vecGlassInfo.push_back(akGlassInfo);
+}
+
+void akDefectFormation::AddDefectHeaderTemp()
+{
+	_akReviewHeader akReviewHeader;
+	akReviewHeader.m_nDefectID = 0;
+
+	m_vecHeaderTemp.push_back(akReviewHeader);
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/akDefectFormation.h b/ReviewHistory/ReveiwHistory/akDefectFormation.h
new file mode 100644
index 0000000..56533b9
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akDefectFormation.h
@@ -0,0 +1,431 @@
+#pragma once
+
+#include <vector>
+#include "Singleton.h"
+
+struct _DefectDisplayOption //그냥 여기에 만들자..;; 해더 하나더 파기 귀찬..
+{
+	_DefectDisplayOption()
+	{
+		m_bShowDefectNormal = TRUE;
+		m_bShowDefectGroupRound = TRUE;
+		m_bShowDefectGroupLine = TRUE;
+		m_bShowNoFilteredDefect = FALSE;
+
+		m_nShowLabel = -1;
+		m_nShowSize = 0;
+	}
+	BOOL m_bShowDefectNormal;
+	BOOL m_bShowDefectGroupRound;
+	BOOL m_bShowDefectGroupLine;
+	BOOL m_bShowNoFilteredDefect;
+
+	int m_nShowLabel; // 0보다 작으면 모두 보기
+	int m_nShowSize; //해당값보다 작거나 같으면 제거
+};
+
+struct _akDefect
+{
+	int nDefectID;
+	double dPositionX;
+	double dPositionY;
+
+	int nLabel;
+	
+	int nSize; //
+	int nType;//0:black defect, 1:white defect
+
+	int nGraySrc;
+	int nGrayTar;
+	int nGrayDiff;
+
+	int nFilter;//1이면 제외
+	//("SIZE_S");
+	//("SIZE_W"); 
+   //("SIZE_L"); 
+   //("SIZE_H"); 
+   //("DEFECT_CODE"); 
+   //("DEF_AVG_1");
+   //("REF_AVG_1");
+   //("REF_GRAY_1");
+   //("MASK_DEFECT");
+   //("COMMON_DEFECT");
+   //("XY_RATIO");
+   //("CAM_NUM");
+   //("LAMP_VALUE");
+	CString m_strInfos[16];	
+
+	short			m_nDefectID;
+	short			m_nCameraID;
+	short			m_nScanIdx;
+	//short			m_nDefectIdx;				// 카메라에서의 결함 인덱스
+	int				m_nDefectIdx;				// 카메라에서의 결함 인덱스 201207 CJH - 자릿 수 넘침. int형으로 변경
+
+	int				m_nPixelConv;				// pixel 단위 좌표
+	int				m_nPixelScan;				// pixel 단위 좌표
+
+	short							m_nPixelSize;				// 결함크기		---------------------------------PS
+	short/*SERVER_DefectType*/		m_DefectType;				// 결함 타입	---------------------------------DT
+	short/*SERVER_DefectSubType*/	m_DefectSubType;			// 결함의 판정상태.
+	short/*SERVER_DefectBDType*/	m_DefectBDType;				// 결함 타입 - Bright, Dark, Both
+
+	short			m_sPixelWidth;				// 픽셀단위 결함 너비
+	short			m_sPixelHeight;				// 픽셀단위 결함 높이
+	short			m_nLevelSrcMin;				// 결함 밝기 Min	-----------------------------SN
+	short			m_nLevelSrcMax;				// 결함 밝기 Max	-----------------------------SX
+	short			m_nLevelSrcAvg;				// 결함 밝기 Avg	-----------------------------SA
+	short			m_nLevelRefMin;				// 비교대상 밝기 Min	-------------------------RN
+	short			m_nLevelRefMax;				// 비교대상 밝기 Max	-------------------------RX
+	short			m_nLevelRefAvg;				// 비교대상 밝기 Avg	-------------------------RA
+	short			m_nLevelDiffMin;			// 비교차 Min	---------------------------------DN
+	short			m_nLevelDiffMax;			// 비교차 Max	---------------------------------DX
+	short			m_nLevelDiffAvg;			// 비교차 Avg	---------------------------------DA
+
+	int				m_nDefectRScale;			// 픽셀단위 결함 높이	-------------------------RS
+	short			m_sThreshold;				// 결함을 검출할 때의 Threshold
+	short			m_sThresholdAvg;			// 결함을 검출할 때의 Threshold AVG
+	short			m_sDefectPeak;				// 결함의 Peak.
+	short			m_sDefectLevel;				// (DiffAvg - Th) BOE 8G 요청사항
+
+	int				m_nPixelGlassStart;			// Glass 시작 픽셀
+	short			m_sDefectLoc;
+
+	short			m_sZonePixelCount[16];	// Zone별 결함 Pixel 수
+	short			m_sZoneValueMin[16];	// Zone별 결함 Min
+	short			m_sZoneValueMax[16];	// Zone별 결함 Max
+	short			m_sZoneValueAvg[16];	// Zone별 결함 Avg
+	short			m_sZonePixelPercent[16];	// --------------------------------------Z0~ZF
+
+	//210127 CJH - Zone별 Source Gray 입력
+	short			m_sZoneValueSrcMin[16];	// Zone별 Source Min
+	short			m_sZoneValueSrcMax[16];	// Zone별 Source Max
+	short			m_sZoneValueSrcAvg[16]; // Zone별 Source Avg
+
+	int				m_nUMOriginX;				// um단위 x좌표 (원점기준)
+	int				m_nUMOriginY;				// um단위 y조표 (원점기준)
+	int				m_nUMCenterAlignX;			// um단위 X좌표 (Glass Center 기준, 얼라인보정 후)
+	int				m_nUMCenterAlignY;			// um단위 Y좌표 (Glass Center 기준, 얼라인보정 후)
+	int				m_nUMCenterX;				// um단위 X좌표 (Glass Center 기준, 얼라인보정 전)
+	int				m_nUMCenterY;				// um단위 Y좌표 (Glass Center 기준, 얼라인보정 전)
+	int				m_nUMSizeX;					// um단위 X 크기	-----------------------------UX
+	int				m_nUMSizeY;					// um단위 Y 크기	-----------------------------UY
+	int				m_nUMSize;					// um단위 크기.
+	CRect			m_RectUM;					// 디펙 센터 기준 사각형.
+
+	short/*SERVER_DefectSizeType*/	m_DefectSizeType;			// 결함 크기 종류enum SERVER_DefectSizeType		{ SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
+	short/*SERVER_DefectPeakType*/	m_DefectPeakType;			// Peak의 종류.
+	short/*Judgement*/				m_DefectJudgement;			// 결함 판정.
+	BOOL					m_bDefectCutoff;			// 컷 오프 디펙(TRUE= Cutoff, FALSE)
+	short/*MAP16_DefectClass*/		m_DefectClass;				// BOE Defect Class 16등분 구분
+	int				m_nPadRegionIdx;			// PAD 영역 인덱스
+
+	int				m_nUMCellX;					// 셀 원점 기준 x 좌표
+	int				m_nUMCellY;					// 셀 원점 기준 y 좌표
+	short			m_nModelIdx;				// 몇 번째 모델인가?
+	short			m_nCellIdx;					// 몇번째 셀인가?
+	short			m_nCellGate;				// 셀별 Gate라인(얼라인 보정 전)
+	short			m_nCellData;				// 셀별 Data라인(얼라인 보정 전)
+	short			m_nCellGateAlign;			// 셀별 Gate라인(얼라인 보정 후)
+	short			m_nCellDataAlign;			// 셀별 Data라인(얼라인 보정 후)
+
+	int				m_nUMShotX;					// 샷 기준 X좌표
+	int				m_nUMShotY;					// 샷 기준 Y좌표
+	short			m_nMaskDefectIdx;			// 한 Glass에서 발견된 마스크결함 묶음의 인덱스.
+	short			m_nShotIdx;					// 노광샷 번호
+	short			m_nMatchShotCount;			// 동일한 마스크 결함의 수.
+	short			m_nMatchMaxSize;			// 동일한 마스크 중 가장 큰 결함의 크기.
+
+	short			m_nRepeatCount;				// 연속결함발견위한 동일좌표 반복수
+	short			m_nMaskRepeatCount;
+	int				m_StackInfo;				// Stack Flag
+	BOOL			m_bRealStack;				// Stack 머지에 의한 TD(TRUE) 인지, 필터링에 의한 TD(FALSE)구분할 수 있다.
+	short			m_nStackStepCount;			// Stack 수
+	short			m_nStackColorIdx;			// Color를 선택하는 인덱스.
+	//CString			m_strStackStep[CFDEFECT_STACKCOUNT];			// Stack Step.
+	char			m_strStackFirst[60];			// Stack Step. //201221 CJH - 최대 사이즈 60bytes
+	char			m_strUnitID[16];				// 유닛아이디
+
+	int				m_ClassificationType;				// enum ClassificationType			{ ClassType_None= 0, ClassType_PI_Over= 1, ClassType_PI_Under= 2, ClassType_TFE_Circle= 3, ClassType_Bubble, ClassType_Scratch, ClassType_Particle}; Classification Type, PI나 TFE등 추가 분류  알고리즘 적용 결과.
+	int				m_nAtomWidth;				// TFE 핵 너비
+	int				m_nAtomHeight;				// TFE 핵 높이
+	short/*ReKind*/			m_DefectKind;				// 결함 종류
+
+	char			m_strDefectCode[32];			// Defect Code
+	BOOL			m_bMergeState;				// Merge Status
+	char			m_strAoiImageName[256];			// Defect Image Name(CCD Image)
+	CString			m_strReviewImageName;
+	int				m_nDefectMerge;		// 현재 디펙의 머지 여부
+
+	int				m_nPixelSizeOrigin;
+	int				m_nScratchRatio;
+	int				m_nDensity;			// 원형 결함 구분을 위한 밀도 [2017.8.2 bhs]
+
+	char			m_strDefectName[16];
+	char			m_strDefectType[16];
+
+	double			m_dScanResolution;
+	double			m_dConvResolution;
+
+	int				m_nAngle;					// 각도
+	int				m_nMajor;					// 장축 길이(Long)
+	int				m_nMinor;					// 단축 길이(Short)
+	int				m_nCompact;					// Blob 장축을 지름으로 하는 원의 넓이와 Blob 넓이의 비율
+	int				m_nThickness;				// Blob 넓이와 장축의 비율 (Area / Major)
+
+	short			m_nHliLevelIdx;				// 몇 번째 레벨(채널)인가?
+	int				m_nHliLayers;				// 해당결함에 포함된 레이어 bit처리
+
+	BOOL			m_bShrinked;				//210323 CJH - Frame Shrink 정보 추가
+};
+
+struct _akModule
+{
+	int				m_nModuleIndex;
+	int				m_nUMShotX;					// 샷 기준 X좌표
+	int				m_nUMShotY;					// 샷 기준 Y좌표
+	int				m_nShotIndex;
+};
+
+struct _akShort
+{
+	int				m_nUMShotX;					// 샷 기준 X좌표
+	int				m_nUMShotY;					// 샷 기준 Y좌표
+	int				m_nShotIndex;
+};
+
+struct _akReviewList
+{
+	short			m_nDefectID;
+	int				m_nDefectIdx;				// 카메라에서의 결함 인덱스 201207 CJH - 자릿 수 넘침. int형으로 변경
+	int				m_nReviewIdx;
+	char			m_strAoiImageName[256];			// Defect Image Name(CCD Image)
+	CString			m_strReviewImageName;
+	CString			m_strGlassID;
+	char			m_strAoiImagePath[256];
+	char			m_strReviewImagePath[256];
+	char			m_strAlignFirst[64];
+	char			m_strAlignSecond[64];
+
+	CString m_strInfos[16];
+};
+
+struct _akGlassInfo
+{
+	int				m_nGlassSelect;
+	CString			m_strPPID;
+	CString			m_strGlassID;
+	int				m_nDefectNum;
+	int				m_nReviewNum;
+	CString			m_strGlassJudge;
+	CString			m_strLotID;
+	CString			m_strSLotID;
+	int				m_nSlot_No;
+	int				m_nCellNum;
+	int				m_nGlassSizeHeight;
+	int				m_nGlassSizeWidth;
+
+	CString m_strInfos[16];
+};
+
+struct _akReviewHeader
+{
+	short			m_nDefectID;
+	int				m_nDefectIdx;
+	CString			m_strGlassID;
+	CString			m_strPPID;
+	int				m_nReviewIdx;
+	CString			m_strJudge;
+	CString			m_strFileTime;
+	CString			m_strFileName;
+	CString			m_strLoading;
+	CString			m_strFilePath;
+	
+	CString m_strInfos[16];
+};
+
+struct _akFormation
+{
+	_akFormation()
+	{
+		m_nFormLabel = -1;
+		m_nFormType = 0;
+		m_dRectLeft = 0;
+		m_dRectTop = 0;
+		m_dRectRight = 0;
+		m_dRectBottom = 0;
+	}
+	void MergeDefect(_akDefect* pDefect)
+	{
+		if (!m_vecForms.empty())
+		{
+			if(m_dRectLeft > pDefect->dPositionX) m_dRectLeft = pDefect->dPositionX;
+			if(m_dRectRight < pDefect->dPositionX) m_dRectRight = pDefect->dPositionX;
+			
+			if (m_dRectTop > pDefect->dPositionY) m_dRectTop = pDefect->dPositionY;
+			if (m_dRectBottom < pDefect->dPositionY) m_dRectBottom = pDefect->dPositionY;
+		}
+		else
+		{
+			m_dRectRight = m_dRectLeft = pDefect->dPositionX;
+			m_dRectTop = m_dRectBottom = pDefect->dPositionY;
+		}
+		m_vecForms.push_back(pDefect);
+	}
+	void AnalysisDefectInfo()
+	{
+		m_nDefectNumS=0;
+		m_nDefectNumM=0;
+		m_nDefectNumL=0;
+		m_nDefectNum1Px=0;
+		m_nDefectNumWhite=0;
+		m_nDefectNumBlack=0;
+		m_nDefectNum1PxWhite = 0;
+		m_dSizeAvg = 0;
+		m_dSizeStdDev = 0;
+		m_dDiffStdDev = 0;
+		m_dDiffStdDevAbs = 0;
+
+		double dDiffAvg=0;
+		double dDiffAvgAbs=0;
+
+		_akDefect* pDefect;
+		for (int i = 0; i < m_vecForms.size(); i++)
+		{
+			pDefect = m_vecForms[i];
+
+			if (pDefect->nSize >= 5) m_nDefectNumL++;
+			else if (pDefect->nSize >= 2) m_nDefectNumM++;
+			else if (pDefect->nSize >= 0) m_nDefectNumS++;
+
+			if (pDefect->nSize == 1) m_nDefectNum1Px++;
+
+			if (pDefect->nType == 1) m_nDefectNumWhite++;
+			else m_nDefectNumBlack++;
+
+			if (pDefect->nType == 1 && pDefect->nSize == 1) m_nDefectNum1PxWhite++;
+
+			m_dSizeAvg += (double)pDefect->nSize;
+			dDiffAvg += (double)pDefect->nGrayDiff;
+			dDiffAvgAbs += abs((double)pDefect->nGrayDiff);
+		}
+		m_dSizeAvg /= m_vecForms.size();
+		dDiffAvg /= m_vecForms.size();
+		dDiffAvgAbs /= m_vecForms.size();
+		
+		for (int i = 0; i < m_vecForms.size(); i++)
+		{
+			pDefect = m_vecForms[i];
+			double dDiff = m_dSizeAvg - m_vecForms[i]->nSize;
+			m_dSizeStdDev += dDiff * dDiff;
+
+			dDiff = dDiffAvg - m_vecForms[i]->nGrayDiff;
+			m_dDiffStdDev += dDiff * dDiff;
+
+			dDiff = dDiffAvgAbs - abs((double)pDefect->nGrayDiff);
+			m_dDiffStdDevAbs += dDiff * dDiff;
+		}
+		m_dSizeStdDev = sqrt(m_dSizeStdDev / (double)m_vecForms.size());
+		m_dDiffStdDev = sqrt(m_dDiffStdDev / (double)m_vecForms.size());
+		m_dDiffStdDevAbs = sqrt(m_dDiffStdDevAbs / (double)m_vecForms.size());
+
+		int nFilter = FALSE;
+		{
+			double d1PxRate = 100.0*((double)m_nDefectNum1Px / (double)m_vecForms.size());
+			double d1PxWhiteRate = 100.0*((double)m_nDefectNum1PxWhite/(double)m_vecForms.size());
+			
+
+			if (m_nFormType == 0 && d1PxWhiteRate > 50)
+			{
+				nFilter = TRUE;
+			}
+			if (m_nFormType == 1 && d1PxWhiteRate > 30)
+			{
+				nFilter = TRUE;
+			}
+			if (m_dSizeStdDev == 0)
+			{
+				nFilter = TRUE;
+			}
+			if(d1PxRate>50)
+			{
+				nFilter = TRUE;
+			}
+			
+		}
+		
+		if (nFilter)
+		{
+			for (int i = 0; i < m_vecForms.size(); i++)
+			{
+				pDefect = m_vecForms[i];
+				pDefect->nFilter = 1;
+			}
+		}
+
+		m_nFormJudge = nFilter;
+	}
+
+	std::vector<_akDefect*> m_vecForms;
+
+	int m_nFormJudge; //0:Normal, 1:Nodefect
+	int m_nFormLabel;
+	int m_nFormType; //-1:none, 0:round, 1:line
+	double m_dRectLeft;
+	double m_dRectTop;
+	double m_dRectRight;
+	double m_dRectBottom;
+
+	//분석 데이터들 [김태현2021/2/22]
+	double m_dSizeAvg;
+	double m_dSizeStdDev;
+	int m_nDefectNumS;
+	int m_nDefectNumM;
+	int m_nDefectNumL;
+	int m_nDefectNum1Px;
+	int m_nDefectNumWhite;
+	int m_nDefectNumBlack;
+	int m_nDefectNum1PxWhite;
+
+	double m_dDiffStdDev;		//그레이 차이 표준편차
+	double m_dDiffStdDevAbs;	//그레이 차이 절대값 표준편차
+};
+
+
+class akDefectFormation : public CSingleton< akDefectFormation >
+{
+public:
+	akDefectFormation();
+	virtual ~akDefectFormation();
+
+public:
+	void Clear();
+	void AddDefect(double dPosX, double dPosY);
+	void AddDefectTemp(double dPosX, double dPosY);
+	void AddDefect2();
+	void AddDefectImageTemp();
+	void AddDefectImage();
+	void AddGlassInfo();
+	void AddDefectHeaderTemp();
+
+public:
+	std::vector<_akDefect> m_vecDefects;
+	std::vector<_akDefect> m_vecTempDefects;
+	std::vector<_akFormation> m_vecFormation;
+	std::vector<_akReviewList> m_vecImage;
+	std::vector<_akReviewList> m_vecTempImage;
+	std::vector<_akReviewHeader> m_vecHeader;
+	std::vector<_akReviewHeader> m_vecHeaderTemp;
+	std::vector<_akGlassInfo> m_vecGlassInfo;
+
+	std::vector<_akDefect> m_vecPath1;
+	std::vector<_akDefect> m_vecPath2;
+	std::vector<_akDefect> m_vecPath3;
+	std::vector<_akDefect> m_vecPath4;
+	std::vector<_akDefect> m_vecPath5;
+	std::vector<_akDefect> m_vecPath6;
+
+public:
+	std::vector< std::vector<_akDefect > > m_vecMoudle;
+};
+
+
diff --git a/ReviewHistory/ReveiwHistory/akFormationMap.cpp b/ReviewHistory/ReveiwHistory/akFormationMap.cpp
new file mode 100644
index 0000000..323c097
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akFormationMap.cpp
@@ -0,0 +1,1190 @@
+#include "stdafx.h"
+#include "akFormationMap.h"
+
+
+CakFormationMap::CakFormationMap()
+{
+	{
+		CakGraphBase::setAK();
+		m_AxisX.m_Size = 80;
+		m_AxisX.m_TickGabStep = 1;
+		m_AxisX.m_MinorTickNum = 4;
+		m_AxisY.m_MinorTickNum = 4;
+		//m_AxisX.m_TickGabPixel = 30;
+		//m_AxisX.m_FontTick.DeleteObject();
+		//m_AxisX.m_FontTick.CreatePointFont(120, _T("Tahoma"));
+		//m_AxisX.SetRotateFont(&m_AxisX.m_FontTick, 270);
+		m_AxisY.SetRotateFont(&m_AxisY.m_FontTick, 90);
+		m_AxisY2.SetRotateFont(&m_AxisY2.m_FontTick, 270);
+		SetClossLine(false);
+		SetDragStyle(DS_All_HOR);
+		m_bGrid = false;
+
+		m_AxisY.m_TickGabPixel = 70;
+		m_AxisX.m_Size = 20;
+		m_AxisY.m_Size = 20;
+		m_AxisY2.m_Size = 20;
+		m_Title.m_Size = 20;
+
+		m_AxisX.m_strTitle = "";
+		m_AxisY.m_strTitle = "";
+		m_Title.m_strTitle = "  ";
+
+		m_MouseMoveInfo.m_nType = 0;
+	}
+
+	m_bShowCell = TRUE;
+
+
+	m_bShowGroupIndex = FALSE;
+	m_bShowGroupLine = TRUE;
+
+	m_pDefectFormation = NULL;
+	m_dGlassSizeWidth = 2500;
+	m_dGlassSizeHeight = 2300;
+
+	m_bShowDefectOutLine = TRUE;
+	m_bShowDefectColorType = FALSE;
+
+	m_pSelectedFormation = NULL;
+	m_pMouseOveredDefect = NULL;
+	m_pSelectedDefect = NULL;
+	m_pMouseOveredFormation = NULL;
+}
+
+
+CakFormationMap::~CakFormationMap()
+{
+}
+
+void CakFormationMap::RenderSeries(Graphics* grfx, CDC* pDC)
+{
+	renderGlass(pDC);
+	renderCell(pDC);
+
+	renderDefects(pDC);
+	renderDefectsPath(pDC);
+
+	renderFormations(pDC);
+}
+
+void CakFormationMap::SetAutoScale()
+{
+	CakGraphBasic3::SetAutoScale();
+
+	if (1)//글라스 크기 및 그리기 방향 결정 태현[2016/3/23]
+	{
+		double nGlassSizeX = m_dGlassSizeWidth;
+		double nGlassSizeY = m_dGlassSizeHeight;
+
+		double dWindowRate = (double)m_rectData.Width() / (double)m_rectData.Height();
+		double dValueRate = (double)nGlassSizeX / (double)nGlassSizeY;
+
+		if (dWindowRate < dValueRate)//가로풀 기준 태현[2016/3/25]
+		{
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = nGlassSizeX;
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = (float)nGlassSizeX*((float)m_rectData.Height() / (float)m_rectData.Width());
+			m_AxisY.SetRangePos(nGlassSizeY / 2);
+
+			
+		}
+		else //세로풀기준 태현[2016/3/25]
+		{
+
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = (float)nGlassSizeY*((float)m_rectData.Width() / (float)m_rectData.Height());
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = nGlassSizeY;
+
+			m_AxisX.SetRangePos(nGlassSizeX / 2);
+		}
+
+		//0,0이 중앙에 오도록 [김태현2021/2/16]
+		m_AxisX.SetRangePos(0);
+		m_AxisY.SetRangePos(0);
+	}
+}
+
+void CakFormationMap::SetResize()
+{
+	CakGraphBasic3::SetAutoScale();
+
+	if (1)//글라스 크기 및 그리기 방향 결정 태현[2016/3/23]
+	{
+		double nGlassSizeX = m_dGlassSizeWidth;
+		double nGlassSizeY = m_dGlassSizeHeight;
+
+		double dWindowRate = (double)m_rectData.Width() / (double)m_rectData.Height();
+		double dValueRate = (double)nGlassSizeX / (double)nGlassSizeY;
+
+		double dPosOldX = m_AxisX.m_RangeValueMin + m_AxisX.GetRangeValue()/2.0;
+		double dPosOldY = m_AxisY.m_RangeValueMin + m_AxisY.GetRangeValue() / 2.0;
+		if (dWindowRate < dValueRate)//가로풀 기준 태현[2016/3/25]
+		{
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = nGlassSizeX;
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = (float)nGlassSizeX*((float)m_rectData.Height() / (float)m_rectData.Width());
+			m_AxisY.SetRangePos(nGlassSizeY / 2);
+
+
+		}
+		else //세로풀기준 태현[2016/3/25]
+		{
+
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = (float)nGlassSizeY*((float)m_rectData.Width() / (float)m_rectData.Height());
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = nGlassSizeY;
+
+			m_AxisX.SetRangePos(nGlassSizeX / 2);
+		}
+
+		m_AxisX.SetRangePos(dPosOldX);
+		m_AxisY.SetRangePos(dPosOldY);
+	}
+}
+
+void CakFormationMap::OnMouseInput(akMouseEvent mouseevent, CPoint point)
+{
+	CakGraphBasic3::OnMouseInput(mouseevent, point);
+
+	switch (mouseevent)
+	{
+	case MouseMove:
+	{
+		m_pMouseOveredDefect = findDefect(GetValuePosDataX(point.x), GetValuePosDataY(point.y));
+		if(m_pMouseOveredDefect) GetParent()->PostMessage(UM_FORMMAP_DEFECTMOUSEOVER, m_pMouseOveredDefect->m_nDefectID);
+		//else GetParent()->PostMessage(UM_FORMMAP_DEFECTMOUSEOVER, m_pMouseOveredDefect->nDefectID);
+
+		m_pMouseOveredFormation = findFormation(GetValuePosDataX(point.x), GetValuePosDataY(point.y));
+		//if (m_pMouseOveredFormation)  GetParent()->PostMessage(UM_FORMMAP_FORMMOUSEOVER, m_pMouseOveredFormation->m_nFormLabel);
+		break;
+	}
+	case MouseLeftButtonDown:
+	{
+		m_pSelectedDefect = findDefect(GetValuePosDataX(point.x), GetValuePosDataY(point.y));
+		if (m_pSelectedDefect) GetParent()->PostMessage(UM_FORMMAP_DEFECTSELECT, m_pSelectedDefect->m_nDefectID, 0);
+
+		m_pSelectedFormation = findFormation(GetValuePosDataX(point.x), GetValuePosDataY(point.y));
+		if (m_pMouseOveredFormation)  GetParent()->PostMessage(UM_FORMMAP_DEFECTSELECT, m_pMouseOveredFormation->m_nFormLabel, 1);
+
+
+		break;
+	}
+	}
+}
+void CakFormationMap::OnKeyInput(int key, int mode)
+{
+	CakGraphBasic3::OnKeyInput(key, mode);
+
+	if (mode == 0) return;
+
+	switch (key)
+	{
+	case 'G':
+	{
+		m_bGrid = !m_bGrid;
+		ReDraw(true);
+		break;
+	}
+	}
+}
+_akDefect* CakFormationMap::findDefect(double nPosX, double nPosY)
+{
+	if (!m_pDefectFormation)
+		return NULL;
+
+	_akDefect* pDefect;
+	
+	double nInPosRage = 1;
+	nInPosRage =(abs(GetValuePosDataX(nInPosRage) - GetValuePosDataX(0)));
+	CakRectd rectMousePos;
+	rectMousePos.set(nPosX, nPosY, nPosX, nPosY);
+	rectMousePos.InflateRect(nInPosRage*3, nInPosRage*5, nInPosRage*5, nInPosRage*3);
+	
+	int nFormType;
+	int nFormLabel;
+
+	double dMinDistance;
+	_akDefect* pDefectMin = NULL;
+	//속도 신경안쓰고 구현;;기능이 우선이다~ [김태현2021/2/16]
+	for (int i = 0; i < m_pDefectFormation->m_vecDefects.size(); i++)
+	{
+		{
+			pDefect = &m_pDefectFormation->m_vecDefects[i];
+
+			nFormType = -1;
+			nFormLabel = m_pDefectFormation->m_vecDefects[i].nLabel;
+			
+			if (nFormLabel >= 0)
+			{
+				nFormType = m_pDefectFormation->m_vecFormation[nFormLabel].m_nFormType;
+			}
+
+			if (m_pDefectDisplayOption->m_nShowSize)
+			{
+				if (pDefect->nSize <= m_pDefectDisplayOption->m_nShowSize) continue;
+			}
+			if (m_pDefectDisplayOption->m_bShowDefectNormal == FALSE)
+			{
+				if (nFormType < 0) continue;;
+			}
+			if (m_pDefectDisplayOption->m_bShowDefectGroupRound == FALSE)
+			{
+				if (nFormType == 0) continue;;
+			}
+			if (m_pDefectDisplayOption->m_bShowDefectGroupLine == FALSE)
+			{
+				if (nFormType == 1) continue;;
+			}
+			if (m_pDefectDisplayOption->m_nShowLabel >= 0)
+			{
+				if (nFormLabel != m_pDefectDisplayOption->m_nShowLabel) continue;;
+			}
+		}
+		if (rectMousePos.getCheckAreaIn(m_pDefectFormation->m_vecDefects[i].dPositionX, m_pDefectFormation->m_vecDefects[i].dPositionY))
+		{
+			double dMinDistanceNew = 
+				(m_pDefectFormation->m_vecDefects[i].dPositionX - rectMousePos.getCenter()) * (m_pDefectFormation->m_vecDefects[i].dPositionX - rectMousePos.getCenter())
+				+ (m_pDefectFormation->m_vecDefects[i].dPositionY - rectMousePos.getVCenter()) * (m_pDefectFormation->m_vecDefects[i].dPositionY - rectMousePos.getVCenter())				;
+			if (pDefectMin)
+			{
+				if (dMinDistance < dMinDistanceNew)
+				{
+					pDefectMin = &m_pDefectFormation->m_vecDefects[i];
+					dMinDistance = dMinDistanceNew;
+				}
+			}
+			else
+			{
+				pDefectMin = &m_pDefectFormation->m_vecDefects[i];
+				dMinDistance = dMinDistanceNew;
+				break;
+			}
+			
+		}
+	}
+
+	return pDefectMin;
+}
+
+_akFormation* CakFormationMap::findFormation(double nPosX, double nPosY)
+{
+	if (!m_pDefectFormation)
+		return NULL;
+
+	_akFormation* pFormation = NULL;
+	_akFormation* pFormationRetrun = NULL;
+
+	CakRectd rectForm;
+
+	int nFormType;
+	int nFormLabel;
+
+	double dMinDistance;
+	//속도 신경안쓰고 구현;;기능이 우선이다~ [김태현2021/2/16]
+	for (int i = 0; i < m_pDefectFormation->m_vecFormation.size(); i++)
+	{
+		{
+			pFormation = &m_pDefectFormation->m_vecFormation[i];
+
+			nFormType = pFormation->m_nFormType;
+			nFormLabel = i;
+
+			if (nFormLabel >= 0)
+			{
+				nFormType = m_pDefectFormation->m_vecFormation[nFormLabel].m_nFormType;
+			}
+
+// 			if (m_pDefectDisplayOption->m_nShowSize)
+// 			{
+// 				if (pFormation->nSize <= m_pDefectDisplayOption->m_nShowSize) continue;
+// 			}
+			if (m_pDefectDisplayOption->m_bShowDefectNormal == FALSE)
+			{
+				if (nFormType < 0) continue;;
+			}
+			if (m_pDefectDisplayOption->m_bShowDefectGroupRound == FALSE)
+			{
+				if (nFormType == 0) continue;;
+			}
+			if (m_pDefectDisplayOption->m_bShowDefectGroupLine == FALSE)
+			{
+				if (nFormType == 1) continue;;
+			}
+			if (m_pDefectDisplayOption->m_nShowLabel >= 0)
+			{
+				if (nFormLabel != m_pDefectDisplayOption->m_nShowLabel) continue;;
+			}
+		}
+		
+		rectForm.set(
+			GetWindowPosX(pFormation->m_dRectLeft),
+			GetWindowPosY(pFormation->m_dRectTop),
+			GetWindowPosX(pFormation->m_dRectRight),
+			GetWindowPosY(pFormation->m_dRectBottom)
+		);
+
+		rectForm.NormalizeRect();
+		rectForm.InflateRect(4, 4, 5, 5);
+
+		if (rectForm.getCheckAreaIn(GetWindowPosX(nPosX), GetWindowPosY(nPosY)))
+		{
+			double dMinDistanceNew = min(abs(GetWindowPosX(nPosX) - rectForm.getCenter()), abs(GetWindowPosY(nPosY) - rectForm.getVCenter()));
+
+			if (pFormationRetrun)
+			{
+				if (dMinDistanceNew < dMinDistance)
+				{
+					pFormationRetrun = pFormation;
+					dMinDistance = dMinDistanceNew;
+				}
+				
+			}
+			else
+			{
+				pFormationRetrun = pFormation;
+				dMinDistance = dMinDistanceNew;
+			}
+			
+		}
+	}
+
+	return pFormationRetrun;
+}
+
+void CakFormationMap::setSelectDefect(int nDefectID)
+{
+	for (int i = 0; i < m_pDefectFormation->m_vecDefects.size(); i++)
+	{
+		if (m_pDefectFormation->m_vecDefects[i].m_nDefectID == nDefectID)
+		{
+			m_pSelectedDefect = &m_pDefectFormation->m_vecDefects[i];
+			break;
+		}
+	}
+	ReDraw(false);
+}
+
+void CakFormationMap::setSelectForm(int nFormID)
+{
+	for (int i = 0; i < m_pDefectFormation->m_vecFormation.size(); i++)
+	{
+		if (m_pDefectFormation->m_vecFormation[i].m_nFormLabel == nFormID)
+		{
+			m_pSelectedFormation = &m_pDefectFormation->m_vecFormation[i];
+			break;
+		}
+	}
+	ReDraw(false);
+}
+void CakFormationMap::renderGlass(CDC* pDC)
+{
+	double nGlassSizeX = m_dGlassSizeWidth;
+	double nGlassSizeY = m_dGlassSizeHeight;
+
+
+	CBrush BrushGlass, *pOldBrush;
+	BrushGlass.CreateSolidBrush(RGB(255,255,255));
+
+
+	CakRectd rectGlass;
+	rectGlass.set(0, 0, nGlassSizeX, nGlassSizeY);
+	rectGlass.MoveToXY(-nGlassSizeX / 2, -nGlassSizeY / 2);
+
+	//글라스 외각선 그리기 태현[2016/3/23]
+	{
+		pOldBrush = (CBrush*)pDC->SelectObject(&BrushGlass);
+		CPen pen;
+		pen.CreatePen(PS_SOLID, 1, RGB(64, 191, 79));
+		pDC->SelectObject(&pen);
+
+		pDC->MoveTo(GetWindowPosX(rectGlass.left), GetWindowPosY(rectGlass.top));
+		pDC->LineTo(GetWindowPosX(rectGlass.right), GetWindowPosY(rectGlass.top));
+		pDC->LineTo(GetWindowPosX(rectGlass.right), GetWindowPosY(rectGlass.bottom));
+		pDC->LineTo(GetWindowPosX(rectGlass.left), GetWindowPosY(rectGlass.bottom));
+		pDC->LineTo(GetWindowPosX(rectGlass.left), GetWindowPosY(rectGlass.top));
+
+		pDC->SelectObject(&pOldBrush);
+	}
+}
+
+void CakFormationMap::renderCell(CDC* pDC)
+{
+	if (m_vecCellRect.empty() || m_bShowCell == FALSE) return;
+
+	CBrush BrushGlass, *pOldBrush;
+	BrushGlass.CreateSolidBrush(RGB(225, 225, 225));
+
+	pOldBrush = (CBrush*)pDC->SelectObject(&BrushGlass);
+	CPen pen;
+	pen.CreatePen(PS_SOLID, 1, RGB(242, 104, 13));
+	pDC->SelectObject(&pen);
+
+	CakRectd rectCell;
+	//
+	for(int i=0; i<m_vecCellRect.size(); i++)
+	{
+		rectCell = m_vecCellRect[i];
+		
+
+		pDC->MoveTo(GetWindowPosX(rectCell.left), GetWindowPosY(rectCell.top));
+		pDC->LineTo(GetWindowPosX(rectCell.right), GetWindowPosY(rectCell.top));
+		pDC->LineTo(GetWindowPosX(rectCell.right), GetWindowPosY(rectCell.bottom));
+		pDC->LineTo(GetWindowPosX(rectCell.left), GetWindowPosY(rectCell.bottom));
+		pDC->LineTo(GetWindowPosX(rectCell.left), GetWindowPosY(rectCell.top));
+
+		
+	}
+
+	pDC->SelectObject(&pOldBrush);
+}
+
+void CakFormationMap::renderDefects(CDC* pDC)
+{
+	if (m_pDefectFormation == NULL) return;
+
+	CBrush BrushDefect, *pOldBrush;
+	CPen PenDefect, *pOldPen;
+	CBrush BrushRoundForm;
+	CBrush BrushLineForm;
+	CBrush BrushFiltered;
+	PenDefect.CreatePen(PS_SOLID, 1, RGB(50, 50, 50));
+	BrushDefect.CreateSolidBrush(RGB(96, 159, 255));
+
+	BrushRoundForm.CreateSolidBrush(RGB(234, 43, 36));
+	BrushLineForm.CreateSolidBrush(RGB(70, 161, 70));
+	BrushFiltered.CreateSolidBrush(RGB(200,200,200));
+	pOldPen = pDC->SelectObject(&PenDefect);
+	pOldBrush = pDC->SelectObject(&BrushDefect);
+
+	if(m_bShowDefectOutLine == FALSE) pDC->SelectStockObject(NULL_PEN);
+
+	CakRectd rectDefect;
+	rectDefect.set(0, 0, 5, 5);
+
+	for (int i = 0; i < m_pDefectFormation->m_vecDefects.size(); i++)
+	{
+		_akDefect* pDefect = &m_pDefectFormation->m_vecDefects[i];
+
+		rectDefect.set(GetWindowPosX(pDefect->dPositionX), GetWindowPosY(pDefect->dPositionY),
+			GetWindowPosX(pDefect->dPositionX), GetWindowPosY(pDefect->dPositionY));
+		rectDefect.InflateRect(3, 3, 3, 3);
+		
+		if (m_pDefectDisplayOption->m_nShowSize)
+		{
+			if(pDefect->nSize <= m_pDefectDisplayOption->m_nShowSize) continue;
+		}
+		if (m_pDefectDisplayOption->m_nShowLabel >= 0)
+		{
+			if(pDefect->nLabel != m_pDefectDisplayOption->m_nShowLabel) continue;
+		}
+		if (m_pDefectDisplayOption->m_bShowNoFilteredDefect == TRUE)
+		{
+			if (pDefect->nFilter == 1) continue;
+		}
+		if (pDefect->nLabel < 0)
+		{
+			if (m_pDefectDisplayOption->m_bShowDefectNormal)
+			{
+				pDC->SelectObject(&BrushDefect);
+				if (pDefect->nFilter == 1) pDC->SelectObject(&BrushFiltered);
+				pDC->Rectangle(rectDefect.left, rectDefect.top, rectDefect.right, rectDefect.bottom);
+				
+			}
+			
+		}
+		else
+		{
+			pDC->SelectObject(&BrushDefect);
+			int nFormType = 0;
+			nFormType = m_pDefectFormation->m_vecFormation[pDefect->nLabel].m_nFormType;
+			if (nFormType == 0) //일반군집 [김태현2021/2/16]
+			{
+				if (m_pDefectDisplayOption->m_bShowDefectGroupRound)
+				{
+					pDC->SelectObject(&BrushRoundForm);
+					if(m_bShowDefectColorType) pDC->SelectObject(&BrushDefect);
+					if(pDefect->nFilter==1) pDC->SelectObject(&BrushFiltered);
+					pDC->Rectangle(rectDefect.left, rectDefect.top, rectDefect.right, rectDefect.bottom);
+				}
+				
+			}
+			else if (nFormType == 1) //라인군입 [김태현2021/2/16]
+			{
+				if (m_pDefectDisplayOption->m_bShowDefectGroupLine)
+				{
+					pDC->SelectObject(&BrushLineForm);
+					if (m_bShowDefectColorType) pDC->SelectObject(&BrushDefect);
+					if (pDefect->nFilter == 1) pDC->SelectObject(&BrushFiltered);
+					pDC->Rectangle(rectDefect.left, rectDefect.top, rectDefect.right, rectDefect.bottom);
+				}
+				
+			}
+		}
+		
+	}
+
+	if (m_bShowGroupIndex)
+	{
+		CString strLabel;
+		pDC->SetTextColor(RGB(111, 0, 138));
+		pDC->SetTextAlign(TA_BASELINE | TA_CENTER);
+
+		for (int k = 0; k < m_pDefectFormation->m_vecFormation.size(); k++)
+		{
+			_akFormation* pFormation = &m_pDefectFormation->m_vecFormation[k];
+
+			for (int i = 0; i < pFormation->m_vecForms.size(); i++)
+			{
+				_akDefect* pDefect = pFormation->m_vecForms[i];
+				if (pDefect->nLabel >= 0)
+				{
+					strLabel.Format("%d", pDefect->nLabel);
+					pDC->TextOut(GetWindowPosX(pDefect->dPositionX), GetWindowPosY(pDefect->dPositionY), strLabel);
+				}
+			}
+		}
+		
+	}
+
+	pDC->SelectObject(pOldPen);
+	pDC->SelectObject(pOldBrush);
+
+}
+
+void CakFormationMap::renderDefectsPath(CDC* pDC)
+{
+	if (!m_pDefectFormation) return;
+	
+	if (m_pDefectFormation->m_vecDefects.size() == 0) return;
+
+	int nStartPosX, nStartPosY, nEndPosX, nEndPosY;
+
+	CPen pathPen;
+	CPen *pOldPen = NULL;
+
+	pathPen.CreatePen(PS_DOT, 1, RGB(0, 0, 255));
+
+	CakRectd rectDefectPath;
+
+	//전체에서 모듈 순서 확인 해서 정렬
+	//모듈 순서에서 short 순서에 따라 정렬
+	//순서대로 넣어 준다.
+	m_pDefectFormation->m_vecPath1.clear();
+	m_pDefectFormation->m_vecPath2.clear();
+	m_pDefectFormation->m_vecPath3.clear();
+	m_pDefectFormation->m_vecPath4.clear();
+	m_pDefectFormation->m_vecPath5.clear();
+	m_pDefectFormation->m_vecPath6.clear();
+
+	//short index 순서 대로 가져 오면 되는 거 아닌가?
+	//분류 작업을 해야 한다
+	for (int i = 0; i < m_pDefectFormation->m_vecDefects.size(); i++)
+	{
+		//1, 모듈 순서에 따라서 정렬 해 보자
+		_akDefect* pDefect = &m_pDefectFormation->m_vecDefects[i];
+		//_akDefect* pDefect1 = &m_pDefectFormation->m_vecPath1[i];
+		
+		if (pDefect->m_nModelIdx == 0)
+		{
+			m_pDefectFormation->m_vecPath1.push_back(m_pDefectFormation->m_vecDefects[i]);
+		}
+		else if (pDefect->m_nModelIdx == 1)
+		{
+			m_pDefectFormation->m_vecPath2.push_back(m_pDefectFormation->m_vecDefects[i]);
+		}
+		else if (pDefect->m_nModelIdx == 2)
+		{
+			m_pDefectFormation->m_vecPath3.push_back(m_pDefectFormation->m_vecDefects[i]);
+		}
+		else if (pDefect->m_nModelIdx == 3)
+		{
+			m_pDefectFormation->m_vecPath4.push_back(m_pDefectFormation->m_vecDefects[i]);
+		}
+		else if (pDefect->m_nModelIdx == 4)
+		{
+			m_pDefectFormation->m_vecPath5.push_back(m_pDefectFormation->m_vecDefects[i]);
+		}
+		else if (pDefect->m_nModelIdx == 5)
+		{
+			m_pDefectFormation->m_vecPath6.push_back(m_pDefectFormation->m_vecDefects[i]);
+		}
+	}
+
+	//분류 작업이 완료 되면 모듈 갯수 만큼 다시 sort 후 순서대로 그린다
+	int nS = 0, nS2 = 0, nS3 = 0, nS4 = 0, nS5=0, nS6 = 0;
+
+	bool bNext = false, bNext2 = false;
+
+	for (int i = 0; i < m_pDefectFormation->m_vecPath1.size(); i++)
+	{
+		//모듈에 들어 있는 값을 sort 하자
+		//sort한 것을 그린다.
+		bNext = false, bNext2 = false;
+		int nStart = -1, nEnd = -1;		
+		
+		for (int j = 0; j < m_pDefectFormation->m_vecPath1.size(); j++)
+		{
+			_akDefect* pDefect1 = &m_pDefectFormation->m_vecPath1[j];
+
+			if (pDefect1->m_nShotIdx == nS)
+			{
+				nStart = j;
+				bNext = true;
+			}
+			else if (pDefect1->m_nShotIdx == nS + 1)
+			{
+				nEnd = j;
+				bNext2 = true;
+			}
+			else if (bNext == true && bNext2 == true)
+			{
+				break;
+			}
+			else
+			{
+				continue;
+			}
+		}
+
+		if (bNext == true && bNext2 == true)
+		{
+			nS++;
+		}
+
+		if (nStart == -1) return;
+		if (nEnd == -1) nEnd = nStart;
+
+		_akDefect* pDefectStart = &m_pDefectFormation->m_vecPath1[nStart];
+		_akDefect* pDefectEnd = &m_pDefectFormation->m_vecPath1[nEnd];
+
+		pDC->MoveTo(GetWindowPosX(pDefectStart->dPositionX), GetWindowPosY(pDefectStart->dPositionY));
+		pDC->LineTo(GetWindowPosX(pDefectEnd->dPositionX), GetWindowPosY(pDefectEnd->dPositionY));
+	}
+
+	bool bNext3 = false, bNext4 = false;
+
+	for (int i = 0; i < m_pDefectFormation->m_vecPath2.size(); i++)
+	{
+		int nStart = -1, nEnd = -1;
+		bNext3 = false, bNext4 = false;
+
+		for (int j = 0; j < m_pDefectFormation->m_vecPath2.size(); j++)
+		{
+			_akDefect* pDefect2 = &m_pDefectFormation->m_vecPath2[j];
+
+			if (pDefect2->m_nShotIdx == nS2)
+			{
+				nStart = j;
+				bNext3 = true;
+			}
+			else if (pDefect2->m_nShotIdx == nS2 + 1)
+			{
+				nEnd = j;
+				bNext4 = true;
+			}
+			else if (bNext3 == true && bNext4 == true)
+			{
+				break;
+			}
+			else
+			{
+				continue;
+			}
+		}
+		
+		if (bNext3 == true && bNext4 == true)
+		{
+			nS2++;
+		}
+		if (nStart == -1) return;
+		if (nEnd == -1) nEnd = nStart;
+
+		_akDefect* pDefectStart = &m_pDefectFormation->m_vecPath2[nStart];
+		_akDefect* pDefectEnd = &m_pDefectFormation->m_vecPath2[nEnd];
+
+		pDC->MoveTo(GetWindowPosX(pDefectStart->dPositionX), GetWindowPosY(pDefectStart->dPositionY));
+		pDC->LineTo(GetWindowPosX(pDefectEnd->dPositionX), GetWindowPosY(pDefectEnd->dPositionY));
+	}
+
+	bool bNext5 = false, bNext6 = false;
+
+	for (int i = 0; i < m_pDefectFormation->m_vecPath3.size(); i++)
+	{
+		int nStart = -1, nEnd = -1;
+		bNext5 = false, bNext6 = false;
+
+		for (int j = 0; j < m_pDefectFormation->m_vecPath3.size(); j++)
+		{
+			_akDefect* pDefect3 = &m_pDefectFormation->m_vecPath3[j];
+
+			if (pDefect3->m_nShotIdx == nS3)
+			{
+				nStart = j;
+				bNext5 = true;
+			}
+			else if (pDefect3->m_nShotIdx == nS3 + 1)
+			{
+				nEnd = j;
+				bNext6 = true;
+			}
+			else if (bNext5 == true && bNext6 == true)
+			{
+				break;
+			}
+			else
+			{
+				continue;
+			}
+		}
+
+
+		//sort한 것을 그린다.
+		if (bNext5 == true && bNext6 == true)
+		{
+			nS3++;
+		}
+		if (nStart == -1) return;
+		if (nEnd == -1) nEnd = nStart;
+
+		_akDefect* pDefectStart = &m_pDefectFormation->m_vecPath3[nStart];
+		_akDefect* pDefectEnd = &m_pDefectFormation->m_vecPath3[nEnd];
+
+		pDC->MoveTo(GetWindowPosX(pDefectStart->dPositionX), GetWindowPosY(pDefectStart->dPositionY));
+		pDC->LineTo(GetWindowPosX(pDefectEnd->dPositionX), GetWindowPosY(pDefectEnd->dPositionY));
+	}
+
+	bool bNext7 = false, bNext8 = false;
+
+	for (int i = 0; i < m_pDefectFormation->m_vecPath4.size(); i++)
+	{
+		int nStart = -1, nEnd = -1;
+		bNext7 = false, bNext8 = false;
+		
+		for (int j = 0; j < m_pDefectFormation->m_vecPath4.size(); j++)
+		{
+			_akDefect* pDefect4 = &m_pDefectFormation->m_vecPath4[j];
+
+			if (pDefect4->m_nShotIdx == nS4)
+			{
+				nStart = j;
+				bNext7 = true;
+			}
+			else if (pDefect4->m_nShotIdx == nS4 + 1)
+			{
+				nEnd = j;
+				bNext8 = true;
+			}
+			else if (bNext7 == true && bNext8 == true)
+			{
+				break;
+			}
+			else
+			{
+				continue;
+			}
+		}
+
+		if (bNext7 == true && bNext8 == true)
+		{
+			nS4++;
+		}
+		if (nStart == -1) return;
+		if (nEnd == -1) nEnd = nStart;
+
+		_akDefect* pDefectStart = &m_pDefectFormation->m_vecPath4[nStart];
+		_akDefect* pDefectEnd = &m_pDefectFormation->m_vecPath4[nEnd];
+
+		pDC->MoveTo(GetWindowPosX(pDefectStart->dPositionX), GetWindowPosY(pDefectStart->dPositionY));
+		pDC->LineTo(GetWindowPosX(pDefectEnd->dPositionX), GetWindowPosY(pDefectEnd->dPositionY));
+	}
+
+	bool bNext9 = false, bNext10 = false;
+
+	for (int i = 0; i < m_pDefectFormation->m_vecPath5.size(); i++)
+	{
+		int nStart = -1, nEnd = -1;
+		bNext9 = false, bNext10 = false;
+		for (int j = 0; j < m_pDefectFormation->m_vecPath5.size(); j++)
+		{
+			_akDefect* pDefect5 = &m_pDefectFormation->m_vecPath5[j];
+
+			if (pDefect5->m_nShotIdx == nS5)
+			{
+				nStart = j;
+				bNext9 = true;
+			}
+			else if (pDefect5->m_nShotIdx == nS5 + 1)
+			{
+				nEnd = j;
+				bNext10 = true;
+			}
+			else if (bNext9 == true && bNext10 == true)
+			{
+				break;
+			}
+			else
+			{
+				continue;
+			}
+		}
+
+		if (bNext9 == true && bNext10 == true)
+		{
+			nS5++;
+		}
+		if (nStart == -1) return;
+		if (nEnd == -1) nEnd = nStart;
+
+		_akDefect* pDefectStart = &m_pDefectFormation->m_vecPath5[nStart];
+		_akDefect* pDefectEnd = &m_pDefectFormation->m_vecPath5[nEnd];
+
+		pDC->MoveTo(GetWindowPosX(pDefectStart->dPositionX), GetWindowPosY(pDefectStart->dPositionY));
+		pDC->LineTo(GetWindowPosX(pDefectEnd->dPositionX), GetWindowPosY(pDefectEnd->dPositionY));
+	}
+
+	bool bNext11 = false, bNext12 = false;
+
+	for (int i = 0; i < m_pDefectFormation->m_vecPath6.size(); i++)
+	{
+		int nStart = -1, nEnd = -1;
+		bNext11 = false, bNext12 = false;
+
+		for (int j = 0; j < m_pDefectFormation->m_vecPath6.size(); j++)
+		{
+			_akDefect* pDefect6 = &m_pDefectFormation->m_vecPath6[j];
+
+			if (pDefect6->m_nShotIdx == nS6)
+			{
+				nStart = j;
+				bNext11 = true;
+			}
+			else if (pDefect6->m_nShotIdx == nS6 + 1)
+			{
+				nEnd = j;
+				bNext12 = true;
+			}
+			else if (bNext11 == true && bNext12 == true)
+			{
+				break;
+			}
+			else
+			{
+				continue;
+			}
+		}
+
+		if (bNext11 == true && bNext12 == true)
+		{
+			nS6++;
+		}
+		if (nStart == -1) return;
+		if (nEnd == -1) nEnd = nStart;
+
+		_akDefect* pDefectStart = &m_pDefectFormation->m_vecPath6[nStart];
+		_akDefect* pDefectEnd = &m_pDefectFormation->m_vecPath6[nEnd];
+
+		pDC->MoveTo(GetWindowPosX(pDefectStart->dPositionX), GetWindowPosY(pDefectStart->dPositionY));
+		pDC->LineTo(GetWindowPosX(pDefectEnd->dPositionX), GetWindowPosY(pDefectEnd->dPositionY));
+	}
+
+/*		SortingtoMoudle();*/
+		
+/*		_akDefect* pDefect = &m_pDefectFormation->m_vecDefects[i];*/
+
+		//pDefect->m_nShotIdx 1 인것과 2인 것을 찾아서 1인 것은 start 2인것은 end 네?
+
+		//m_nshortidx 에 모듈이 먼지를 알아야 겠네? pDefect->m_nModelIdx 이걸로 알 수 있네?
+		//m_nShortidx 에 시작은 있고 끝이 없다면 종료
+
+// 		if (pDefect->m_nShotIdx == i)
+// 		{
+// 			pDC->MoveTo(GetWindowPosX(rectDefectPath.left), GetWindowPosY(rectDefectPath.top));
+// 			pDC->LineTo(GetWindowPosX(rectDefectPath.right), GetWindowPosY(rectDefectPath.top));
+// 
+// 			//pDC->MoveTo(nStartPosX, nStartPosY);
+// 			//pDC->LineTo(nEndPosX, nEndPosY);
+// 		}		
+//	}
+
+
+// 	for (constVectorReviewResultIt it = pVecReviewResult->begin(); it != pVecReviewResult->end(); it++)
+// 	{
+// 		const CReviewResult *pReviewResult = static_cast<const CReviewResult*>(&(*it));
+// 
+// 		constVectorSReviewResultIt itt;
+// 		constVectorSReviewResultIt ittEnd;
+// 		if (pReviewResult->GetSReviewResultCount() > 0)
+// 		{
+// 			itt = pReviewResult->m_vecSReviewResult.begin();
+// 			ittEnd = pReviewResult->m_vecSReviewResult.end();
+// 		}
+// 		else
+// 		{
+// 			continue;
+// 		}
+// 		const SReviewResult *pSReviewResult = static_cast<const SReviewResult*>(&(*itt));
+// 		int nDraw = FilterDefectPos(m_pDefectFilter, pSReviewResult);
+// 		if (nDraw < 0)
+// 		{
+// 			continue;
+// 		}
+// 
+// 		// select path pen
+// 		pOldPen = pDC->SelectObject(&pathPen);
+// 		for (constVectorSReviewResultIt its = pReviewResult->m_vecSReviewResult.begin(); its != pReviewResult->m_vecSReviewResult.end(); its++)
+// 		{
+// 			if (itt + 1 != ittEnd)
+// 			{
+// 				itt++;
+// 				nStartPosX = its->nUMOriginX;
+// 				nStartPosY = its->nUMOriginY;
+// 				nEndPosX = itt->nUMOriginX;
+// 				nEndPosY = itt->nUMOriginY;
+// 				TransformGlass2Map(nStartPosX, nStartPosY);
+// 				TransformGlass2Map(nEndPosX, nEndPosY);
+// 				//모터 좌표를 글라스 좌표로 변환 해야 함
+// 				pDC->MoveTo(nStartPosX, nStartPosY);
+// 				pDC->LineTo(nEndPosX, nEndPosY);
+// 			}
+// 		}
+// 	}
+
+	pDC->SelectObject(pOldPen);
+}
+
+void CakFormationMap::renderFormations(CDC* pDC)
+{
+	if (m_pDefectFormation == NULL) return;
+	if (m_bShowGroupLine == FALSE) return;
+
+	CPen PenDefect, *pOldPen;
+
+	CPen PenDefectLine;
+	PenDefect.CreatePen(PS_SOLID, 1, RGB(234, 43, 36));
+	PenDefectLine.CreatePen(PS_SOLID, 1, RGB(50, 153, 50));
+
+	pOldPen = pDC->SelectObject(&PenDefect);
+	pDC->SelectStockObject(NULL_BRUSH);
+
+	CakRectd rectForm;
+
+	for (int i = 0; i < m_pDefectFormation->m_vecFormation.size(); i++)
+	{
+		_akFormation* pForm = &m_pDefectFormation->m_vecFormation[i];
+
+		if (m_pDefectDisplayOption->m_nShowLabel >= 0)
+		{
+			if (i != m_pDefectDisplayOption->m_nShowLabel) continue;
+		}
+
+		rectForm.set(
+			GetWindowPosX(pForm->m_dRectLeft),
+			GetWindowPosY(pForm->m_dRectTop),
+			GetWindowPosX(pForm->m_dRectRight),
+			GetWindowPosY(pForm->m_dRectBottom)
+			);
+
+		rectForm.NormalizeRect();
+		rectForm.InflateRect(4, 4, 5, 5);
+
+		if (pForm->m_nFormType == 1) pDC->SelectObject(&PenDefectLine);
+		else pDC->SelectObject(&PenDefect);
+
+		pDC->Rectangle(rectForm.left, rectForm.top, rectForm.right, rectForm.bottom);
+
+	}
+
+	
+	
+
+	pDC->SelectObject(pOldPen);
+}
+
+void CakFormationMap::renderMouseoverInfos(CDC* pDC)
+{
+
+	pDC->SelectObject(m_AxisX.m_Font);
+	
+	if(m_pSelectedDefect)
+	{
+		_akDefect* pDefect = m_pSelectedDefect;
+
+		CakRectd rectDefect;
+		rectDefect.set(GetWindowPosX(pDefect->dPositionX), GetWindowPosY(pDefect->dPositionY),
+			GetWindowPosX(pDefect->dPositionX), GetWindowPosY(pDefect->dPositionY));
+		if(m_bShowDefectOutLine) rectDefect.InflateRect(5, 5, 5, 5);
+		else rectDefect.InflateRect(5, 5, 5-1, 5-1);
+
+		CPen PenDefect, *pOldPen;
+		PenDefect.CreatePen(PS_SOLID, 1, RGB(24, 24, 192));
+		pDC->SelectStockObject(NULL_BRUSH);
+		pOldPen = pDC->SelectObject(&PenDefect);
+
+		pDC->Rectangle(rectDefect.left, rectDefect.top, rectDefect.right, rectDefect.bottom);
+		rectDefect.InflateRect(-1,-1,-1,-1);
+		pDC->Rectangle(rectDefect.left, rectDefect.top, rectDefect.right, rectDefect.bottom);
+		
+
+
+		pDC->SelectObject(pOldPen);
+	}
+
+	if (m_pMouseOveredDefect)
+	{
+		_akDefect* pDefect = m_pMouseOveredDefect;
+
+		CakRectd rectDefect;
+		rectDefect.set(GetWindowPosX(pDefect->dPositionX), GetWindowPosY(pDefect->dPositionY),
+			GetWindowPosX(pDefect->dPositionX), GetWindowPosY(pDefect->dPositionY));
+		if (m_bShowDefectOutLine) rectDefect.InflateRect(5, 5, 5, 5);
+		else rectDefect.InflateRect(5, 5, 5 - 1, 5 - 1);
+
+		CPen PenDefect, *pOldPen;
+		PenDefect.CreatePen(PS_SOLID, 1, RGB(192, 24, 24));
+		pDC->SelectStockObject(NULL_BRUSH);
+		pOldPen = pDC->SelectObject(&PenDefect);
+
+		pDC->Rectangle(rectDefect.left, rectDefect.top, rectDefect.right, rectDefect.bottom);
+
+		pDC->SelectObject(pOldPen);
+
+		CString strDefectInfo;
+		COLORREF cl;
+		cl = RGB(39, 255, 39);
+
+		pDC->SetTextAlign(TA_LEFT | TA_BASELINE);
+		pDC->SetTextColor(cl);
+		strDefectInfo.Format("%d : %.3lf, %.3lf Cam: %d, SCan : %d", m_pMouseOveredDefect->m_nDefectID, m_pMouseOveredDefect->dPositionX, m_pMouseOveredDefect->dPositionY, m_pMouseOveredDefect->m_nCameraID, m_pMouseOveredDefect->m_nScanIdx);
+		pDC->TextOut(GetWindowPosX(m_pMouseOveredDefect->dPositionX)+5, GetWindowPosY(m_pMouseOveredDefect->dPositionY) - 7, strDefectInfo);
+
+	}
+	if (m_pSelectedFormation)
+	{
+		_akFormation* pFormation = m_pSelectedFormation;
+
+		int nFormLabel = -1;
+		if (pFormation && !pFormation->m_vecForms.empty())
+		{
+			nFormLabel = pFormation->m_vecForms[0]->nLabel;
+		}
+		CakRectd rectForm;
+
+		rectForm.set(
+			GetWindowPosX(pFormation->m_dRectLeft),
+			GetWindowPosY(pFormation->m_dRectTop),
+			GetWindowPosX(pFormation->m_dRectRight),
+			GetWindowPosY(pFormation->m_dRectBottom)
+		);
+
+		rectForm.NormalizeRect();
+		rectForm.InflateRect(4, 4, 5, 5);
+		rectForm.InflateRect(-1, -1, -1, -1);
+
+		CPen PenDefect, *pOldPen;
+		//PenDefect.CreatePen(PS_SOLID, 1, RGB(192, 192, 24));
+		
+		//if(pFormation->m_nFormType == 0) PenDefect.CreatePen(PS_DOT, 1, RGB(234, 43, 36));
+		//else if (pFormation->m_nFormType == 1) PenDefect.CreatePen(PS_DOT, 1, RGB(50, 153, 50));
+		
+		PenDefect.CreatePen(PS_DOT, 1, RGB(24, 24, 192));
+		pDC->SelectStockObject(NULL_BRUSH);
+		pOldPen = pDC->SelectObject(&PenDefect);
+
+		pDC->Rectangle(rectForm.left, rectForm.top, rectForm.right, rectForm.bottom);
+
+		//text
+		{
+			CString strDefectInfo;
+			pDC->SetTextAlign(TA_LEFT | TA_BOTTOM);
+			CString strFormType = "ROUND";
+			if (pFormation->m_nFormType == 1) strFormType = "LINE";
+
+			strDefectInfo.Format("FORM %d, %s", nFormLabel, strFormType);
+
+			pDC->SetBkMode(OPAQUE);
+			pDC->SetBkColor(RGB(0, 255, 0));
+			pDC->SetTextColor(RGB(0, 0, 0));
+			pDC->SelectObject(m_AxisX.m_Font);
+			pDC->TextOut(rectForm.left, rectForm.top, strDefectInfo);
+			pDC->SetBkMode(TRANSPARENT);
+		}
+	}
+	if (m_pMouseOveredFormation)
+	{
+		_akFormation* pFormation = m_pMouseOveredFormation;
+
+		int nFormLabel = -1;
+		if (pFormation && !pFormation->m_vecForms.empty())
+		{
+			nFormLabel = pFormation->m_vecForms[0]->nLabel;
+		}
+		CakRectd rectForm;
+	
+		rectForm.set(
+			GetWindowPosX(pFormation->m_dRectLeft),
+			GetWindowPosY(pFormation->m_dRectTop),
+			GetWindowPosX(pFormation->m_dRectRight),
+			GetWindowPosY(pFormation->m_dRectBottom)
+		);
+
+		rectForm.NormalizeRect();
+		rectForm.InflateRect(4, 4, 5, 5);
+		rectForm.InflateRect(1, 1, 1, 1);
+
+		CPen PenDefect, *pOldPen;
+		PenDefect.CreatePen(PS_SOLID, 1, RGB(192, 192, 24));
+		pDC->SelectStockObject(NULL_BRUSH);
+		pOldPen = pDC->SelectObject(&PenDefect);
+
+		pDC->Rectangle(rectForm.left, rectForm.top, rectForm.right, rectForm.bottom);
+
+		pDC->SelectObject(pOldPen);
+
+		CString strDefectInfo;
+		pDC->SetTextAlign(TA_LEFT | TA_BOTTOM);
+		CString strFormType = "ROUND";
+		if(pFormation->m_nFormType == 1) strFormType = "LINE";
+		
+		strDefectInfo.Format("FORM %d, %s", nFormLabel, strFormType);
+
+		pDC->SetBkMode(OPAQUE);
+		pDC->SetBkColor(RGB(0, 255, 0));
+		pDC->SetTextColor(RGB(0, 0, 0));
+		pDC->SelectObject(m_AxisX.m_Font);
+		pDC->TextOut(rectForm.left, rectForm.top, strDefectInfo);
+		pDC->SetBkMode(TRANSPARENT);
+
+	}
+}
+
+void CakFormationMap::AddCellData()
+{
+	CakRectd akCellTemp;
+	m_vecTempCellRect.push_back(akCellTemp);
+}
+
+void CakFormationMap::AddCell()
+{
+	CakRectd akCellTemp;
+	m_vecCellRect.push_back(akCellTemp);
+}
+
+void CakFormationMap::RenderEnd(Graphics* grfx, CDC* pDC)
+{
+
+	CRgn rgn;
+	CRect rectROI = CakRectToCRect(m_rectData);
+	rgn.CreateRectRgnIndirect(&rectROI);
+	pDC->SelectClipRgn(&rgn);
+
+	renderMouseoverInfos(pDC);
+
+	pDC->SelectClipRgn(NULL);
+
+	CakGraphBasic3::RenderEnd(grfx, pDC);
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/akFormationMap.h b/ReviewHistory/ReveiwHistory/akFormationMap.h
new file mode 100644
index 0000000..2312a97
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akFormationMap.h
@@ -0,0 +1,65 @@
+#pragma once
+
+#include "akGraph/akGraphBasic3.h"
+#include "akDefectFormation.h"
+
+#define UM_FORMMAP_DEFECTMOUSEOVER WM_USER+0x2001
+#define UM_FORMMAP_DEFECTSELECT WM_USER+0x2002
+
+class CakFormationMap : public CakGraphBasic3
+{
+public:
+	CakFormationMap();
+	virtual ~CakFormationMap();
+
+public:
+	void clear()
+	{
+		m_pMouseOveredFormation = NULL;
+		m_pSelectedFormation = NULL;
+		m_pMouseOveredDefect = NULL;
+		m_pSelectedDefect = NULL;
+	};
+	virtual void RenderEnd(Graphics* grfx, CDC* pDC);
+	virtual void RenderSeries(Graphics* grfx, CDC* pDC);
+	virtual void SetAutoScale();
+	virtual void SetResize();
+
+	virtual void OnKeyInput(int key, int mode);
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point);
+	_akDefect* findDefect(double nPosX, double nPosY);
+	_akFormation* findFormation(double nPosX, double nPosY);
+
+	void setSelectDefect(int nDefectID);
+	void setSelectForm(int nFormID);
+	void AddCellData();
+	void AddCell();
+public:
+	BOOL m_bShowCell;	
+
+	BOOL m_bShowGroupIndex;
+	BOOL m_bShowGroupLine;
+	
+	BOOL m_bShowDefectOutLine;
+	BOOL m_bShowDefectColorType;
+
+	double m_dGlassSizeWidth;
+	double m_dGlassSizeHeight;
+	std::vector<CakRectd> m_vecCellRect;
+	std::vector<CakRectd> m_vecTempCellRect;
+	akDefectFormation* m_pDefectFormation;
+	_DefectDisplayOption* m_pDefectDisplayOption;
+protected:
+	void renderGlass(CDC* pDC);
+	void renderCell(CDC* pDC);
+	void renderDefects(CDC* pDC);
+	void renderDefectsPath(CDC* pDC);
+	void renderFormations(CDC* pDC);
+	void renderMouseoverInfos(CDC* pDC);
+protected:
+	_akFormation* m_pMouseOveredFormation;
+	_akFormation* m_pSelectedFormation;
+	_akDefect* m_pMouseOveredDefect;
+	_akDefect* m_pSelectedDefect;
+};
+
diff --git a/ReviewHistory/ReveiwHistory/akGridData.cpp b/ReviewHistory/ReveiwHistory/akGridData.cpp
new file mode 100644
index 0000000..c2525e5
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akGridData.cpp
@@ -0,0 +1,478 @@
+#include "StdAfx.h"
+#include "akGridData.h"
+
+
+void CakParser::process( const char* pText, const char* pToken /*= " \r\n\t,^"*/ )
+{
+	//{
+		m_vecTokLen.clear();
+		m_vecTokPos.clear();
+	//}
+
+	m_pSrcText = pText;
+
+	unsigned int i_index;
+	unsigned int index;
+
+	unsigned int nTokenLen = (unsigned int)strlen(pToken);
+	unsigned int string_length = (unsigned int)strlen(pText);
+	unsigned char bitmask[32]={0}; //256가 bit masking을 사용하기 위해서.
+
+	//token 배열에 저장된 문자의 ascii index 위치에 masking을 한다.
+	for( i_index=0; i_index<nTokenLen; i_index++)
+		bitmask[ pToken[i_index] >> 3] |= (1 << ( pToken[i_index] & 7));
+
+
+	int nStartPoint=-1;
+	for( index=0; index<string_length; index++)
+	{
+		if( (bitmask[pText[index] >> 3]) & (1 << (pText[index] & 7)) ) //구분자 찾음 태현[2017/12/7]
+		{
+			if(nStartPoint != -1)
+			{
+				m_vecTokPos.push_back(nStartPoint);
+				m_vecTokLen.push_back(index-nStartPoint);
+				nStartPoint = -1;
+			}
+		}
+		else if(nStartPoint < 0) //구분자도 못찾고 시작도 안함
+		{
+			nStartPoint = index;
+		}
+
+	}
+	if(nStartPoint >= 0)
+	{
+		m_vecTokPos.push_back(nStartPoint);
+		m_vecTokLen.push_back(string_length-nStartPoint);
+	}
+
+};
+
+
+const char* CakParser::getTokStr( int nIndex )
+{
+	m_strTokBuffer.clear();
+	m_strTokBuffer.append(&m_pSrcText[m_vecTokPos[nIndex]], m_vecTokLen[nIndex]);
+	return m_strTokBuffer.c_str();		
+}
+
+bool CakParser::getTokStr( int nTokIndex, char* pBuf, int nLen )
+{
+	// NULL 값 고려
+	if(nLen-1 < m_vecTokLen[nTokIndex]) return false;
+
+	strncpy(pBuf, &m_pSrcText[m_vecTokPos[nTokIndex]], m_vecTokLen[nTokIndex]);
+	pBuf[m_vecTokLen[nTokIndex]] = 0;
+	
+	return true;	
+}
+
+CakTextMatrix::CakTextMatrix(void)
+{
+	m_nRowsNum = m_nColsNum = 0;
+
+	m_nIntervalLength = 0;
+	m_vecIntervalPos.clear();
+	
+	setDevideFlag();
+}
+
+CakTextMatrix::~CakTextMatrix(void)
+{
+}
+
+bool CakTextMatrix::ImportFile( char* pFileName )
+{
+	
+	FILE* pf = fopen(pFileName, "r");
+	if(pf)
+	{
+		CakParser parser;
+		setRowCount(0);
+		setColCount(100);
+
+
+		char buffer[2048]={};
+		
+		while (fgets(buffer, 2048, pf))
+		{
+			parser.process(buffer, ",\n");
+			
+			setRowCount(1, TRUE);
+			if(parser.getTokNum() > getColCount()) setColCount(parser.getTokNum());
+
+			int nTokenNum = parser.getTokNum();
+			int nRowIndex = getRowCount()-1;
+			for(int i=0; i<nTokenNum; i++)
+			{
+				setItemText(nRowIndex, i, parser.getTokStr(i));
+			}
+		}
+		
+		fclose(pf);
+
+		return true;
+	}
+
+	return false;
+}
+
+bool CakTextMatrix::ImportText( char* pText )
+{
+	if(pText == NULL) return false;
+	CakParser parserLine;
+	CakParser parserTok;
+	parserLine.process(pText, "\n");
+
+	char* pStrLineData;
+	char* pStrLineTock;
+	int nLineNum = parserLine.getTokNum();
+	setRowCount(nLineNum);
+	for(int i=0; i<nLineNum; i++)
+	{
+		pStrLineData = (char*)parserLine.getTokStr(i);
+		
+		parserTok.process(pStrLineData, m_strDevideFlag.c_str());
+		int nTockNum = parserTok.getTokNum();
+		setColCount(nTockNum);
+		for(int j=0; j<nTockNum; j++)
+		{
+			pStrLineTock = (char*)parserTok.getTokStr(j);
+			setItemText(i,j, pStrLineTock);
+		}
+	}
+
+	return true;
+}
+
+
+bool CakTextMatrix::AddRowData( char* pTextData )
+{
+	if(pTextData == NULL) return false;
+	
+	CakParser parserTok;
+	parserTok.process(pTextData, m_strDevideFlag.c_str());
+	
+	int nTockNum = parserTok.getTokNum();
+	
+	setColCount(nTockNum);
+	setRowCount(1, true);
+
+	int nRowIndex = getRowCount();
+	char* pStrTok;
+	
+	for(int j=0; j<nTockNum; j++)
+	{
+		pStrTok = (char*)parserTok.getTokStr(j);
+		setItemText(nRowIndex,j, pStrTok);
+	}
+
+	return true;
+}
+
+
+
+void CakTextMatrix::setDevideFlag( char* pFlag /*= " \r\n\t,"*/ )
+{
+	m_strDevideFlag = pFlag;
+
+	
+}
+
+void CakTextMatrix::setRowCount( int nNum/*=10*/, bool bIncrease /*= false*/ )
+{
+	int nIncreaseCount = 0;
+	
+	if(bIncrease) nIncreaseCount = nNum;
+	else nIncreaseCount = nNum - m_nRowsNum;
+
+
+	if(nIncreaseCount == 0) 
+	{
+		return ;
+	}
+	else if(nIncreaseCount > 0) //증가
+	{
+		for(int i=0; i<nIncreaseCount; i++)
+		{
+			m_vecCellData_Row.push_back(_akCell_Row());
+		}
+		setColCount(m_nColsNum);
+	}
+	else if(nIncreaseCount < 0) //감소
+	{
+		m_vecCellData_Row.erase(m_vecCellData_Row.end() + nIncreaseCount, m_vecCellData_Row.end());
+	}
+
+	m_nRowsNum += nIncreaseCount;
+}
+
+void CakTextMatrix::setColCount( int nNum/*=10*/, bool bIncrease /*= false*/ )
+{
+	if(bIncrease) m_nColsNum += nNum;
+	else m_nColsNum = nNum;
+
+	int nSize = (int)m_vecCellData_Row.size(); 
+
+	for(int i=0; i<nSize; i++)
+	{
+		std::vector<_akCellData>* pVecGridCellData = &m_vecCellData_Row[i].m_vecGridCellData;
+
+		int nIncreaseCount = 0;
+
+		if(bIncrease) nIncreaseCount = nNum;
+		else nIncreaseCount = m_nColsNum - (int)pVecGridCellData->size();
+
+		
+
+		if(nIncreaseCount == 0)
+		{
+			continue ;
+		}
+		else if(nIncreaseCount > 0) //증가
+		{
+			for(int a=0; a<nIncreaseCount; a++)
+			{
+				 pVecGridCellData->push_back(_akCellData());
+			}
+		}
+		else if(nIncreaseCount < 0) //감소
+		{
+			pVecGridCellData->erase(pVecGridCellData->end() + nIncreaseCount, pVecGridCellData->end());
+		}
+
+	}
+
+
+	
+	
+
+	return;
+}
+
+void CakTextMatrix::printOut()
+{
+	int nRowNum = getRowCount();
+	int nColNum = getColCount();
+
+	for(int y=0; y<nRowNum; y++)
+	{
+		for(int x=0; x<nColNum; x++)
+		{
+			//TRACE("%s", getItemText(x,y));
+			TRACE("(%02d,%02d)%s", x,y,getItemText(y,x));
+			if(x < nColNum-1) TRACE("\t");
+		}
+		TRACE("\n");
+	}
+}
+
+const char* CakTextMatrix::getItemText( int nRow, int nCol )
+{
+	//return m_vecCellItem[nRow*m_nColsNum + nCol]->m_strText.c_str();
+	return m_vecCellData_Row[nRow].m_vecGridCellData[nCol].m_strText.c_str();
+}
+
+void CakTextMatrix::setItemText( int nRow, int nCol,  const char* pText )
+{
+	if(pText != NULL)
+		//m_vecCellItem[nRow*m_nColsNum + nCol]->m_strText = pText;
+		m_vecCellData_Row[nRow].m_vecGridCellData[nCol].m_strText = pText;
+
+	
+}
+
+void CakTextMatrix::makeCellItemArray()
+{
+	return;//빠르게 접근할려고 만든건데; 데이터 확보 하는 과정에서 과부하 걸림
+	m_vecCellItem.clear();
+
+	int nRowNum = getRowCount();
+	int nColNum = getColCount();
+
+	for(int y=0; y<nRowNum; y++)
+	{
+		for(int x=0; x<nColNum; x++)
+		{
+			m_vecCellItem.push_back(&m_vecCellData_Row[y].m_vecGridCellData[x]);
+		}
+	}
+}
+
+int CakTextMatrix::getRowIndex( char* pTitle )
+{
+	for(int i=0; i<m_nRowsNum; i++)
+	{
+		if(m_vecCellItem[i*m_nColsNum + 0]->m_strText.compare(pTitle))
+		{
+			return i;
+		}
+	}
+
+	return -1;
+}
+int CakTextMatrix::getColIndex( char* pTitle )
+{
+	for(int i=0; i<m_nColsNum; i++)
+	{
+		if(m_vecCellItem[0*m_nColsNum + i]->m_strText.compare(pTitle))
+		{
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+bool CakTextMatrix::ExportFileInterval( char* pFileName, char* pIntervalRef )
+{
+	FILE* pf = fopen(pFileName, "w");
+	if(pf)
+	{
+		CakParser paserInterval;
+		paserInterval.process(pIntervalRef, " ");
+
+		const int nBufSize = 2048;
+		char buffer[nBufSize];
+		int nStrLen, nWritePoint;
+		const char* pStr;
+
+		int nRowNum = getRowCount();
+		int nColNum = getColCount();
+
+		for(int y=0; y<nRowNum; y++)
+		{
+			memset(buffer, ' ', sizeof(char)*nBufSize);
+			for(int x=0; x<nColNum; x++)
+			{
+				pStr = getItemText(y,x);
+				nStrLen = (int)strlen(pStr);
+				nWritePoint = paserInterval.getTokPos(x);
+				memcpy(&buffer[nWritePoint], pStr, sizeof(char)*nStrLen);
+				
+				if(nWritePoint > 0)
+				{
+					buffer[nWritePoint-1] = ' '; //바로 직전에 공백으로 표시
+				}
+			}
+			buffer[strlen(pIntervalRef)] = 0;
+			fprintf(pf, "%s", buffer);
+			if(y < nRowNum-1) fprintf(pf, "\n");
+		}
+
+		fclose(pf);
+		return true;
+	}
+
+	
+	return false;
+}
+
+bool CakTextMatrix::ExportFile( char* pFileName, char* pDevideFlag/*=","*/ )
+{
+	//한줄을 메모리에 적고 최종적으로 파일로 쓰는게 더 빠르겠지?? 태현[2017/12/7]
+	FILE* pf = fopen(pFileName, "w");
+	if(pf)
+	{
+		char buffer[2048]={};
+
+		int nRowNum = getRowCount();
+		int nColNum = getColCount();
+
+		for(int y=0; y<nRowNum; y++)
+		{
+			memset(buffer, 0, sizeof(char)*2048);
+			for(int x=0; x<nColNum; x++)
+			{
+				strcat(buffer, getItemText(y,x));
+				if(x < nColNum-1) strcat(buffer, pDevideFlag);
+			}
+			
+			if(y < nRowNum-1) strcat(buffer, "\n");
+			fprintf(pf, "%s", buffer);
+		}
+
+		fclose(pf);
+		return true;
+	}
+
+	return false;
+}
+bool CakTextMatrix::printLine( int nRowIndex, char* pBuf, int nLen, char* pDevideFlag/*=","*/ )
+{
+	int nRowNum = getRowCount();
+	int nColNum = getColCount();
+
+
+	if(nRowIndex < nRowNum)
+	{
+		memset(pBuf, 0, sizeof(char)*nLen);
+
+		for(int x=0; x<nColNum; x++)
+		{
+			strcat(pBuf, getItemText(nRowIndex,x));
+			if(x < nColNum-1) strcat(pBuf, pDevideFlag);
+		}
+
+		return true;
+	}
+
+
+	return false;
+}
+
+
+bool CakTextMatrix::printLineInterval( int nRowIndex, char* pBuf, int nLen )
+{
+	int nRowNum = getRowCount();
+
+	if(nRowIndex < nRowNum && m_nIntervalLength != 0)
+	{
+		int nColNum = getColCount();
+
+		int nStrLen, nWritePoint;
+		const char* pStr;
+		
+		memset(pBuf, ' ', sizeof(char)*nLen);
+		for(int x=0; x<nColNum; x++)
+		{
+			pStr = getItemText(nRowIndex,x);
+			nStrLen = (int)strlen(pStr);
+			nWritePoint = m_vecIntervalPos[x];
+			memcpy(&pBuf[nWritePoint], pStr, sizeof(char)*nStrLen);
+
+			if(nWritePoint > 0)
+			{
+				pBuf[nWritePoint-1] = ' '; //바로 직전에 공백으로 표시
+			}
+		}
+		pBuf[m_nIntervalLength] = 0;
+
+
+		return true;
+	}
+	
+	return false;
+}
+
+void CakTextMatrix::setIntervalRef( char* pIntervalRef )
+{
+	m_nIntervalLength = 0;
+	m_vecIntervalPos.clear();
+
+	if(pIntervalRef == NULL) return;
+	
+	CakParser paserInterval;
+	paserInterval.process(pIntervalRef, " ");
+
+	int nNum = paserInterval.getTokNum();
+	for(int i=0; i<nNum; i++)
+	{
+		m_vecIntervalPos.push_back(paserInterval.getTokPos(i));
+	}
+
+	m_nIntervalLength = (int)strlen(pIntervalRef);
+
+}
+
diff --git a/ReviewHistory/ReveiwHistory/akGridData.h b/ReviewHistory/ReveiwHistory/akGridData.h
new file mode 100644
index 0000000..91d4037
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akGridData.h
@@ -0,0 +1,97 @@
+#pragma once
+
+#include <vector>
+#include <string>
+
+class CakParser
+{
+public:
+	CakParser(void)
+	{
+		m_pSrcText = NULL;
+	};
+	virtual ~CakParser(void){};
+
+	void process(const char* pText, const char* pToken = " \r\n\t,^");
+	
+	const char* getTokStr(int nIndex);
+	bool getTokStr(int nTokIndex, char* pBuf, int nLen);
+	
+	int getTokNum(){return (int)m_vecTokPos.size();};
+	
+	int getTokPos(int nIndex){return m_vecTokPos[nIndex];};
+	int getTokLen(int nIndex){return m_vecTokLen[nIndex];};
+
+
+protected:
+	const char* m_pSrcText;
+	std::vector<int> m_vecTokPos;
+	std::vector<int> m_vecTokLen;
+	std::string m_strTokBuffer;
+};
+
+struct _akCellData 
+{
+	int nRow, nCol;
+
+	std::string m_strText;
+
+	
+};
+
+struct _akCell_Row
+{
+	std::vector<_akCellData> m_vecGridCellData;
+};
+
+class CakTextMatrix
+{
+public:
+	CakTextMatrix(void);
+	virtual ~CakTextMatrix(void);
+
+
+public:
+	bool ImportFile(char* pFileName); //파일에서 읽는 방식 태현[2018/4/18]
+	bool ImportText(char* pText); //여러줄의 데이터를 한번에 받는 방식.  태현[2018/4/18]
+
+	bool ExportFile(char* pFileName, char* pDevideFlag=",");
+	bool ExportFileInterval(char* pFileName, char* pIntervalRef);
+
+	void setDevideFlag(char* pFlag = " \r\n\t,^");
+	void setIntervalRef(char* pIntervalRef);
+public:
+	bool AddRowData(char* pTextData);
+	bool printLine(int nRowIndex, char* pBuf, int nLen, char* pDevideFlag=",");
+	bool printLineInterval(int nRowIndex, char* pBuf, int nLen);
+
+public:
+	void setRowCount(int nNum=10, bool bIncrease = false);
+	void setColCount(int nNum=10, bool bIncrease = false);
+	int getRowCount(){return m_nRowsNum;};
+	int getColCount(){return m_nColsNum;};
+
+	int getRowIndex(char* pTitle);
+	int getColIndex(char* pTitle);
+
+public:
+	void setItemText(int nRow, int nCol, const char* pText);
+	const char* getItemText(int nRow, int nCol);
+
+public:
+	virtual void printOut();//데이터 내용 Trace에 출력
+	
+protected:
+	void makeCellItemArray(); //데이터에 빠르게 접근하기 위한 전처리 태현[2017/12/6]
+
+
+protected:
+	std::string m_strDevideFlag;
+	std::vector<_akCell_Row> m_vecCellData_Row; //셀의 실제 정보를 관리
+	std::vector<_akCellData*> m_vecCellItem; //빠르게 접근하기 위해서 NxN형태의 Cell 자료의 포인트만 관리
+	int m_nRowsNum, m_nColsNum;
+
+	int m_nIntervalLength;
+	std::vector<int> m_vecIntervalPos;
+	
+};
diff --git a/ReviewHistory/ReveiwHistory/akIPCNetAOISystem.cpp b/ReviewHistory/ReveiwHistory/akIPCNetAOISystem.cpp
new file mode 100644
index 0000000..c963e99
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akIPCNetAOISystem.cpp
@@ -0,0 +1,189 @@
+#include "StdAfx.h"
+#include "akIPCNetAOISystem.h"
+#include <process.h>
+
+#define SHAREDMEMNAME "DIT.AOISYSTEM.SHAREDMEM"
+
+akIPCNetAOISystem::akIPCNetAOISystem(void)
+: m_mxSignalProcess(FALSE, _T("IPC_NETWORKSYSTEM_MUTEX"))
+{
+	m_pParent = NULL;
+	m_nThreadSignalFlag = 0;
+	m_pIPCAOISystem = NULL;
+	m_hMapIPCAOISystem = NULL;
+	
+	InitializeCriticalSection(&m_csSignalProcess);
+}
+
+akIPCNetAOISystem::~akIPCNetAOISystem(void)
+{
+	if(m_nThreadSignalFlag == 1) m_nThreadSignalFlag = 2;
+	while(m_nThreadSignalFlag != 0)
+	{
+		Sleep(0);
+	}
+
+	if (m_pIPCAOISystem!=NULL)
+	{
+		::UnmapViewOfFile(m_pIPCAOISystem);
+		m_pIPCAOISystem = NULL;
+	}
+
+	if (m_hMapIPCAOISystem != NULL)
+	{
+		::CloseHandle(m_hMapIPCAOISystem);
+		m_hMapIPCAOISystem = NULL;
+	}
+
+}
+
+bool akIPCNetAOISystem::Create( CWnd* pParent )
+{
+	if(m_pIPCAOISystem) return false;
+
+
+	BOOL bCreateSharedMem = FALSE;//공유메모리 생성 [김태현 2018/9/10]
+	{
+		BOOL bCreateMem = TRUE;
+
+		m_hMapIPCAOISystem = ::CreateFileMapping(INVALID_HANDLE_VALUE,NULL,PAGE_READWRITE
+			, 0, sizeof(_IPCAOISystem), SHAREDMEMNAME);
+
+		if (::GetLastError() == ERROR_ALREADY_EXISTS)
+		{
+			m_hMapIPCAOISystem = ::OpenFileMapping(FILE_MAP_ALL_ACCESS,FALSE,SHAREDMEMNAME);
+			bCreateMem = FALSE;
+		}
+
+		if (m_hMapIPCAOISystem)
+		{
+			m_pIPCAOISystem = (_IPCAOISystem*)::MapViewOfFile(m_hMapIPCAOISystem, FILE_MAP_ALL_ACCESS, 0, 0, sizeof(_IPCAOISystem));
+			if (m_pIPCAOISystem)
+			{
+				bCreateSharedMem = TRUE;
+			}
+		}
+		
+		//0으로 초기화
+		if(bCreateMem && m_pIPCAOISystem) ZeroMemory(m_pIPCAOISystem,sizeof(_IPCAOISystem));
+	}
+
+	if(bCreateSharedMem == FALSE) return false;
+
+	m_pParent = pParent;
+
+	_beginthread(threadSignal, NULL, this);
+
+	return true;
+}
+
+void akIPCNetAOISystem::threadSignal( void* arg )
+{
+	akIPCNetAOISystem* pThis = (akIPCNetAOISystem*)arg;
+
+	pThis->m_nThreadSignalFlag = 1;
+	pThis->processSignal();
+	pThis->m_nThreadSignalFlag = 0;
+}
+
+void akIPCNetAOISystem::processSignal()
+{
+	char m_nSignalPreAOI[INA_SIGNALNUM]={};
+	char m_nSignalCurAOI[INA_SIGNALNUM]={};
+	char m_nSignalPreReview[INA_SIGNALNUM]={};
+	char m_nSignalCurReview[INA_SIGNALNUM]={};
+
+	DWORD dwTickCount =0;
+
+	while(m_nThreadSignalFlag == 1)
+	{
+		dwTickCount = GetTickCount();
+
+		m_mxSignalProcess.Lock();
+		memcpy(m_nSignalCurAOI, getAOIProtocol()->m_nSignal, sizeof(char)*INA_SIGNALNUM);
+		memcpy(m_nSignalCurReview, getReviewProtocol()->m_nSignal, sizeof(char)*INA_SIGNALNUM);
+		m_mxSignalProcess.Unlock();
+		//Signal 감지 부분 [김태현 2018/9/10]
+		{
+			for(int i=0; i<INA_SIGNALNUM; i++)
+			{
+				if(m_nSignalCurAOI[i] == 1 && m_nSignalPreAOI[i] == 0)
+				{
+					RecvSignal(ST_AOI, i);
+				}
+			}
+			for(int i=0; i<INA_SIGNALNUM; i++)
+			{
+				if(m_nSignalCurReview[i] == 1 && m_nSignalPreReview[i] == 0)
+				{
+					RecvSignal(ST_Review, i);
+				}
+			}
+		}
+
+		//signal time off 처리 부분
+		{
+			EnterCriticalSection(&m_csSignalProcess);
+			for(int i=m_vecSignalTimeOff.size()-1; i>=0; i--)
+			{
+				if(m_vecSignalTimeOff[i].nTimeBitOff < dwTickCount)
+				{
+					*m_vecSignalTimeOff[i].pSignal = 0;
+					m_vecSignalTimeOff.erase(m_vecSignalTimeOff.begin()+i);
+				}
+				else if(*m_vecSignalTimeOff[i].pSignal == 0)
+				{
+					m_vecSignalTimeOff.erase(m_vecSignalTimeOff.begin()+i);
+				}
+			}
+			LeaveCriticalSection(&m_csSignalProcess);
+		}
+
+		memcpy(m_nSignalPreAOI, m_nSignalCurAOI, sizeof(char)*INA_SIGNALNUM);
+		memcpy(m_nSignalPreReview, m_nSignalCurReview, sizeof(char)*INA_SIGNALNUM);
+
+		Sleep(50);
+	}
+}
+
+bool akIPCNetAOISystem::SetSignal( emSystemType nSystemType, int nSignalIndex, int nTimeMS /*= 500*/ )
+{
+	char* pSignal = NULL;
+	if(nSystemType == ST_AOI)
+	{
+		pSignal = &getAOIProtocol()->m_nSignal[nSignalIndex];
+	}
+	else if(nSystemType == ST_Review)
+	{
+		pSignal = &getReviewProtocol()->m_nSignal[nSignalIndex];
+	}
+
+
+	EnterCriticalSection(&m_csSignalProcess);
+	for(int i=0; i<m_vecSignalTimeOff.size(); i++)
+	{
+		if(m_vecSignalTimeOff[i].pSignal == pSignal)
+		{
+			LeaveCriticalSection(&m_csSignalProcess);
+			return false;
+		}
+	}
+
+	_SignalTimerOff signaloff;
+	signaloff.pSignal = pSignal;
+	signaloff.nTimeBitOff = GetTickCount()+nTimeMS;
+	m_vecSignalTimeOff.push_back(signaloff);
+	LeaveCriticalSection(&m_csSignalProcess);
+
+	m_mxSignalProcess.Lock();
+	*pSignal = 1;
+	m_mxSignalProcess.Unlock();
+	
+	return true;
+}
+
+void akIPCNetAOISystem::RecvSignal( emSystemType nSystemType, int nSignal )
+{
+	if(m_pParent) m_pParent->PostMessage(UM_IPCNETAOISYSTEM, nSignal, (int)nSystemType);
+}
+
diff --git a/ReviewHistory/ReveiwHistory/akIPCNetAOISystem.h b/ReviewHistory/ReveiwHistory/akIPCNetAOISystem.h
new file mode 100644
index 0000000..686c71e
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akIPCNetAOISystem.h
@@ -0,0 +1,139 @@
+#pragma once
+
+#include <vector>
+
+#define INA_SIGNALNUM 32
+#define INA_MAXMODULENUM 4
+#define INA_MAXDEFECTNUM 1024
+
+
+//모든 좌표 데이터의 단위는 um [김태현 2018/9/10]
+
+//m_nSignal 의미 [김태현 2018/9/10]
+//Review가 AOI의 시그널을 감지 하기 위해서는 m_ProtocalAOI.m_nSignal 상태를 실시간 감지 하는 방식
+
+struct _ProtocolAOI
+{
+public:
+	_ProtocolAOI()
+	{
+		memset(m_nSignal, 0, sizeof(char)*INA_SIGNALNUM);
+
+	};
+public:
+	/*
+	Signal 저의
+	0 : GlassLoading
+	1 : ScanReady
+	2 : ScanStart
+	10 : ModuleMove
+	*/
+	char m_nSignal[INA_SIGNALNUM]; 
+
+public:
+	int m_nModuleMoveX; //글라스 좌표 [김태현 2018/9/10]
+	int m_nModuleMoveY;
+};
+
+
+struct _ProtocalReviewModlueData 
+{
+	//모듈 현재 좌표 [김태현 2018/9/10]
+	int m_nModuleGlassPosX;
+	int m_nModuleGlassPosY;
+
+	int m_nPlanDefectNum;	//리뷰할 결함 갯수 [김태현 2018/9/10]
+	int m_nReviewedDefectNum; //리뷰한 결함 갯수
+
+	//리뷰할 결함 위치 [김태현 2018/9/10]
+	int m_nPlanReviewPosX[INA_MAXDEFECTNUM];
+	int m_nPlanReviewPosY[INA_MAXDEFECTNUM];
+};
+
+struct _ProtocolReview
+{
+public:
+	_ProtocolReview()
+	{
+		memset(m_nSignal, 0, sizeof(char)*INA_SIGNALNUM);
+
+		m_nModuleNum = 0;
+		memset(m_ModuleData, 0, sizeof(_ProtocalReviewModlueData)*INA_MAXMODULENUM);
+	}
+public:
+	/*
+	Signal 정의
+	0 : GlassLoading
+	1 : GlassLoading Complete 
+	2 : Align Ready
+	3 : Align Complete
+	5 : ReviewEnd
+	
+	*/
+	char m_nSignal[INA_SIGNALNUM];
+
+	//Review Data Section
+public:
+	int m_nModuleNum;
+	_ProtocalReviewModlueData m_ModuleData[INA_MAXMODULENUM];
+};
+
+struct _IPCAOISystem 
+{
+public:
+	_ProtocolAOI	m_ProtocolAOI;
+	_ProtocolReview m_ProtocolReview;
+};
+
+
+
+
+#define UM_IPCNETAOISYSTEM WM_USER+0x1010
+class akIPCNetAOISystem
+{
+public:
+	akIPCNetAOISystem(void);
+	virtual ~akIPCNetAOISystem(void);
+
+public:
+	enum emSystemType
+	{
+		ST_AOI = 0,
+		ST_Review = 1
+	};
+public:
+	bool Create(CWnd* pParent);
+	//시그널이 살아 있으면 return 값이 false [김태현 2018/9/10]
+	bool SetSignal(emSystemType nSystemType, int nSignalIndex, int nTimeMS = 500);
+
+	virtual void RecvSignal(emSystemType nSystemType, int nSignal);
+
+	_ProtocolAOI* getAOIProtocol(){return m_pIPCAOISystem ? &m_pIPCAOISystem->m_ProtocolAOI : NULL;};
+	_ProtocolReview* getReviewProtocol(){return m_pIPCAOISystem ? &m_pIPCAOISystem->m_ProtocolReview : NULL;};
+protected:
+	static void threadSignal(void* arg);
+	void processSignal();
+
+protected:
+	struct _SignalTimerOff
+	{
+		_SignalTimerOff()
+		{
+			nTimeBitOff = 0;
+			pSignal = NULL;
+		}
+		DWORD nTimeBitOff; //종료 시간
+		char* pSignal;
+	};
+
+
+protected:
+	_IPCAOISystem* m_pIPCAOISystem;
+	int m_nThreadSignalFlag;
+	CRITICAL_SECTION m_csSignalProcess;
+	CMutex m_mxSignalProcess;
+	HANDLE		m_hMapIPCAOISystem;
+
+	CWnd*	m_pParent;// 메세지 전달 대상
+	std::vector<_SignalTimerOff> m_vecSignalTimeOff;
+};
diff --git a/ReviewHistory/ReveiwHistory/akImageView.cpp b/ReviewHistory/ReveiwHistory/akImageView.cpp
new file mode 100644
index 0000000..d8f6e8f
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akImageView.cpp
@@ -0,0 +1,497 @@
+#include "stdafx.h"
+#include "akImageView.h"
+#include "akGraph/akGraphUtil.h"
+
+CakImageView::CakImageView()
+{
+	SetReverseModeY(true);
+	{
+		CakGraphBase::setAK();
+		m_AxisX.m_Size = 80;
+		m_AxisX.m_TickGabStep = 1;
+		m_AxisX.m_MinorTickNum = 4;
+		m_AxisY.m_MinorTickNum = 4;
+		//m_AxisX.m_TickGabPixel = 30;
+		//m_AxisX.m_FontTick.DeleteObject();
+		//m_AxisX.m_FontTick.CreatePointFont(120, _T("Tahoma"));
+		//m_AxisX.SetRotateFont(&m_AxisX.m_FontTick, 270);
+		m_AxisY.SetRotateFont(&m_AxisY.m_FontTick, 90);
+		m_AxisY2.SetRotateFont(&m_AxisY2.m_FontTick, 270);
+		SetClossLine(false);
+		SetDragStyle(DS_All_HOR);
+		m_bGrid = false;
+
+		m_AxisY.m_TickGabPixel = 70;
+		m_AxisX.m_Size = 20;
+		m_AxisY.m_Size = 20;
+		m_AxisY2.m_Size = 20;
+		m_Title.m_Size = 20;
+
+		m_AxisX.m_strTitle = "";
+		m_AxisY.m_strTitle = "";
+		m_Title.m_strTitle = "  ";
+
+		m_MouseMoveInfo.m_nType = 0;
+	}
+}
+
+
+CakImageView::~CakImageView()
+{
+}
+
+void CakImageView::RenderSeries(Graphics* grfx, CDC* pDC)
+{
+	RenderImage(grfx, pDC);
+}
+
+void CakImageView::SetAutoScale()
+{
+	CakGraphBasic3::SetAutoScale();
+
+	if (1)//글라스 크기 및 그리기 방향 결정 태현[2016/3/23]
+	{
+		double nGlassSizeX = 2400;
+		double nGlassSizeY = 2048;
+
+		if (!m_vecImageData.empty())
+		{
+			nGlassSizeX = m_vecImageData[0]->m_Bits.bmWidth;
+			nGlassSizeY = m_vecImageData[0]->m_Bits.bmHeight;
+		}
+
+		double dWindowRate = (double)m_rectData.Width() / (double)m_rectData.Height();
+		double dValueRate = (double)nGlassSizeX / (double)nGlassSizeY;
+
+		if (dWindowRate < dValueRate)//가로풀 기준 태현[2016/3/25]
+		{
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = nGlassSizeX;
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = (float)nGlassSizeX*((float)m_rectData.Height() / (float)m_rectData.Width());
+			m_AxisY.SetRangePos(nGlassSizeY / 2);
+		}
+		else //세로풀기준 태현[2016/3/25]
+		{
+
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = (float)nGlassSizeY*((float)m_rectData.Width() / (float)m_rectData.Height());
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = nGlassSizeY;
+
+			m_AxisX.SetRangePos(nGlassSizeX / 2);
+		}
+
+		//0,0이 중앙에 오도록 [김태현2021/2/16]
+		m_AxisX.SetRangePos(0);
+		m_AxisY.SetRangePos(0);
+	}
+}
+
+void CakImageView::SetResize()
+{
+	double dPosOldX = m_AxisX.m_RangeValueMin + m_AxisX.GetRangeValue() / 2.0;
+	double dPosOldY = m_AxisY.m_RangeValueMin + m_AxisY.GetRangeValue() / 2.0;
+	CakGraphBasic3::SetAutoScale();
+
+	if (1)//글라스 크기 및 그리기 방향 결정 태현[2016/3/23]
+	{
+		double nGlassSizeX = 2400;
+		double nGlassSizeY = 2048;
+
+		if (!m_vecImageData.empty())
+		{
+			nGlassSizeX = m_vecImageData[0]->m_Bits.bmWidth;
+			nGlassSizeY = m_vecImageData[0]->m_Bits.bmHeight;
+		}
+
+		double dWindowRate = (double)m_rectData.Width() / (double)m_rectData.Height();
+		double dValueRate = (double)nGlassSizeX / (double)nGlassSizeY;
+
+		//double dPosOldX = m_AxisX.m_RangeValueMin + m_AxisX.GetRangeValue() / 2.0;
+		//double dPosOldY = m_AxisY.m_RangeValueMin + m_AxisY.GetRangeValue() / 2.0;
+		if (dWindowRate < dValueRate)//가로풀 기준 태현[2016/3/25]
+		{
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = nGlassSizeX;
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = (float)nGlassSizeX*((float)m_rectData.Height() / (float)m_rectData.Width());
+			m_AxisY.SetRangePos(nGlassSizeY / 2);
+
+
+		}
+		else //세로풀기준 태현[2016/3/25]
+		{
+
+			m_AxisX.m_RangeValueMin = 0;
+			m_AxisX.m_RangeValueMax = (float)nGlassSizeY*((float)m_rectData.Width() / (float)m_rectData.Height());
+			m_AxisY.m_RangeValueMin = 0;
+			m_AxisY.m_RangeValueMax = nGlassSizeY;
+
+			m_AxisX.SetRangePos(nGlassSizeX / 2);
+		}
+
+		m_AxisX.SetRangePos(dPosOldX);
+		m_AxisY.SetRangePos(dPosOldY);
+	}
+}
+
+void CakImageView::RenderImage(Graphics* grfx, CDC* pDC)
+{
+	if (m_vecImageData.empty()) return;
+
+	//pDC->SetStretchBltMode(HALFTONE); //<-- 최대 확대시 그리는 시간 과다 소요
+	pDC->SetStretchBltMode(COLORONCOLOR);// <--최대 확대시 이미지 표시 안됨
+
+
+	CRgn rgn;
+	rgn.CreateRectRgnIndirect(CakRectToCRect(m_rectData));
+	pDC->SelectClipRgn(&rgn);
+
+	CBitmap* pOldBitmap;
+	CDC BitmapDC;
+	BitmapDC.CreateCompatibleDC(pDC);
+
+	_DataImage2* pImageData;
+
+	double dAlignX, dAlignY;
+	for (int i = 0; i < m_vecImageData.size(); i++)
+	{
+		dAlignX = dAlignY = 0;
+
+		int x1, x2, y1, y2;
+		pImageData = m_vecImageData[i];
+		x1 = pImageData->m_nDrawPosX-dAlignX;
+		y1 = pImageData->m_nDrawPosY-dAlignY;
+		x2 = pImageData->m_nDrawPosX + pImageData->m_Bits.bmWidth;
+		y2 = pImageData->m_nDrawPosY + pImageData->m_Bits.bmHeight;
+
+
+		CakRect rectImage(x1, y1, x2, y2);
+
+
+		CakRect rectOutRangeTemp, rectOutRange;
+		rectOutRangeTemp.left = m_AxisX.m_RangeValueMin;
+		rectOutRangeTemp.right = ceil(m_AxisX.m_RangeValueMax);
+		rectOutRangeTemp.top = m_AxisY.m_RangeValueMin;
+		rectOutRangeTemp.bottom = ceil(m_AxisY.m_RangeValueMax);
+
+		if (rectOutRange.IntersectRect(&rectOutRangeTemp, &rectImage) == FALSE)
+		{
+			continue;
+		}
+
+		pOldBitmap = BitmapDC.SelectObject(&pImageData->m_Bitmap);
+
+		double dOnePixelX = (double)m_rectData.Width() / m_AxisX.GetRangeValue();
+		double dOnePixelY = (double)m_rectData.Height() / m_AxisY.GetRangeValue();
+
+		if (1)//dOnePixelX > 2 && dOnePixelY > 2)
+		{
+			CakRect rectDraw;
+			rectDraw.set(
+				GetWindowPosX(rectOutRange.left),
+				GetWindowPosY(rectOutRange.top),
+				GetWindowPosX(rectOutRange.right),
+				GetWindowPosY(rectOutRange.bottom)
+			);
+			CakRect rectImage;
+			rectImage.set(
+				rectOutRange.left - x1,
+				rectOutRange.top - y1,
+				rectOutRange.right - x1,
+				rectOutRange.bottom - y1
+			);
+
+			if (m_bReverseY == FALSE)
+			{
+				AKSWAP_INT(rectDraw.top, rectDraw.bottom);
+				rectImage.top = pImageData->m_Bits.bmHeight - rectOutRange.bottom + y1;
+				rectImage.bottom = rectImage.top + rectOutRange.getHeight();
+			}
+			if (m_bReverseX == TRUE)
+			{
+				AKSWAP_INT(rectDraw.left, rectDraw.right);
+				rectImage.left = pImageData->m_Bits.bmWidth - rectOutRange.right + x1;
+				rectImage.right = rectImage.left + rectOutRange.getWidth();
+			}
+
+
+			pDC->StretchBlt(rectDraw.left, rectDraw.top, rectDraw.Width(), rectDraw.Height(), &BitmapDC,
+				rectImage.left, rectImage.top,
+				rectImage.getWidth(), rectImage.getHeight(), SRCCOPY);
+
+		}
+		else
+		{
+			//좌표축 그대로 그릴때 [김태현 2018/12/10]
+			/*pDC->StretchBlt(GetWindowPosX(x1), GetWindowPosY(y1), GetWindowPosX(x2)-GetWindowPosX(x1),GetWindowPosY(y2)-GetWindowPosY(y1), &BitmapDC,
+				0, 0,
+				pImageData->m_Bits.bmWidth, pImageData->m_Bits.bmHeight, SRCCOPY);*/
+			pDC->StretchBlt(GetWindowPosX(x1), GetWindowPosY(y1), GetWindowPosX(x2) - GetWindowPosX(x1), GetWindowPosY(y2) - GetWindowPosY(y1), &BitmapDC,
+				0, 0,
+				pImageData->m_Bits.bmWidth, pImageData->m_Bits.bmHeight, SRCCOPY);
+		}
+
+
+		BitmapDC.SelectObject(pOldBitmap);
+		continue;
+
+	}
+
+	BitmapDC.DeleteDC();
+
+
+	if(m_vecImageData.empty() == FALSE)
+	{
+		
+		pImageData = m_vecImageData[0];
+		
+
+		double nGlassSizeX = pImageData->m_Bits.bmWidth;
+		double nGlassSizeY = pImageData->m_Bits.bmHeight;
+
+
+		CBrush BrushGlass, *pOldBrush;
+		BrushGlass.CreateSolidBrush(RGB(255, 255, 255));
+
+
+		CakRectd rectGlass;
+		rectGlass.set(0, 0, nGlassSizeX, nGlassSizeY);
+		rectGlass.MoveToXY(-nGlassSizeX / 2, -nGlassSizeY / 2);
+
+		//글라스 외각선 그리기 태현[2016/3/23]
+		{
+			pOldBrush = (CBrush*)pDC->SelectObject(&BrushGlass);
+			CPen pen;
+			pen.CreatePen(PS_SOLID, 1, RGB(64, 191, 79));
+			pDC->SelectObject(&pen);
+
+			pDC->MoveTo(GetWindowPosX(rectGlass.left), GetWindowPosY(rectGlass.top));
+			pDC->LineTo(GetWindowPosX(rectGlass.right), GetWindowPosY(rectGlass.top));
+			pDC->LineTo(GetWindowPosX(rectGlass.right), GetWindowPosY(rectGlass.bottom));
+			pDC->LineTo(GetWindowPosX(rectGlass.left), GetWindowPosY(rectGlass.bottom));
+			pDC->LineTo(GetWindowPosX(rectGlass.left), GetWindowPosY(rectGlass.top));
+
+			pDC->SelectObject(&pOldBrush);
+		}
+	}
+	pDC->SelectClipRgn(NULL);	
+
+	//DrawROIRect(pDC);
+}
+
+void CakImageView::OnMouseInput(akMouseEvent mouseevent, CPoint point)
+{
+	CakGraphBasic3::OnMouseInput(mouseevent, point);
+
+	switch (mouseevent)
+	{
+	case MouseMove:
+	{
+		break;
+	}
+	case MouseLeftButtonDown:
+	{
+		if (point.x > -1 && point.x < GetScaleWidth() &&
+			point.y > -1 && point.y < GetScaleHeight())
+		{
+// 			if (m_rectTracker.HitTest(point) < 0)
+// 			{
+// 				// just to demonstrate CRectTracker::TrackRubberBand
+// 				if (m_rectTracker.TrackRubberBand(this, point, TRUE))
+// 				{
+// 					Invalidate();
+// 				}
+// 			}
+// 			else if (m_rectTracker.Track(this, point, TRUE))
+// 			{
+// 				Invalidate();
+// 			}
+		}
+
+		CRect rect;
+		this->GetClientRect(rect);
+
+		point.x += m_nHScroll;
+		point.y += m_nVScroll;
+		/*m_pParentWnd->SendMessage(WM_LBUTTONDOWN, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));*/
+	}
+	break;
+	case MouseLeftButtonUp:
+	{
+		CRect rect;
+		this->GetClientRect(rect);
+
+		point.x += m_nHScroll;
+		point.y += m_nVScroll;
+	/*	m_pParentWnd->SendMessage(WM_LBUTTONUP, static_cast<WPARAM>(nFlags), MAKELPARAM(point.x, point.y));*/
+
+		if (GetTrackerRect(m_rtROIRect))
+		{
+			m_sROIInfo.nWidthPixel = m_rtROIRect.Width();
+			m_sROIInfo.nHeightPixel = m_rtROIRect.Height();
+			m_sROIInfo.dDiagonalPixel = sqrt(double(m_sROIInfo.nWidthPixel*m_sROIInfo.nWidthPixel + m_sROIInfo.nHeightPixel*m_sROIInfo.nHeightPixel));
+
+			m_sROIInfo.dWidthRealUM = m_sROIInfo.nWidthPixel * (m_dResolution / m_dWidthScale);
+			m_sROIInfo.dHeightRealUM = m_sROIInfo.nHeightPixel * (m_dResolution / m_dHeightScale);
+			m_sROIInfo.dDiagonalRealUM = sqrt((m_sROIInfo.dWidthRealUM*m_sROIInfo.dWidthRealUM) + (m_sROIInfo.dHeightRealUM*m_sROIInfo.dHeightRealUM));
+
+			Invalidate(TRUE);
+		}
+	}
+	break;
+	}
+}
+
+CakDataImage2::CakDataImage2(void)
+{
+}
+
+CakDataImage2::~CakDataImage2(void)
+{
+}
+
+int CakDataImage2::SetImageData(char* pFileName, int nImageIndex /*= 0*/)
+{
+	HBITMAP hBitmap = NULL;
+	hBitmap = (HBITMAP)LoadImage(NULL, pFileName, IMAGE_BITMAP, 0, 0,
+		LR_LOADFROMFILE | LR_CREATEDIBSECTION | LR_DEFAULTSIZE);
+
+	_DataImage2* pNewImage;
+
+	if (hBitmap)
+	{
+		pNewImage = new _DataImage2;
+
+		pNewImage->m_Bitmap.Attach(hBitmap);
+		pNewImage->m_Bitmap.GetBitmap(&pNewImage->m_Bits);
+		pNewImage->m_pBitmapData = (unsigned char*)pNewImage->m_Bits.bmBits;
+		pNewImage->m_nDrawPosX = -pNewImage->m_Bits.bmWidth / 2;
+		pNewImage->m_nDrawPosY = -pNewImage->m_Bits.bmHeight / 2;
+	}
+	else
+	{
+		CImage imgJPG;
+		HRESULT ret = imgJPG.Load(pFileName);
+		if (ret == S_OK)
+		{
+			pNewImage = new _DataImage2;
+			pNewImage->m_Bitmap.Attach(imgJPG.Detach());
+			pNewImage->m_Bitmap.GetBitmap(&pNewImage->m_Bits);
+			pNewImage->m_pBitmapData = (unsigned char*)pNewImage->m_Bits.bmBits;
+			pNewImage->m_nDrawPosX = -pNewImage->m_Bits.bmWidth / 2;
+			pNewImage->m_nDrawPosY = -pNewImage->m_Bits.bmHeight / 2;
+		}
+		else
+		{
+			return 0;
+		}
+	}	
+	
+	if (m_vecImageData.size() <= nImageIndex)
+	{
+		m_vecImageData.push_back(pNewImage);
+	}
+	else
+	{
+		_DataImage2* pDelImage = m_vecImageData[nImageIndex];
+		m_vecImageData[nImageIndex] = pNewImage;
+		pDelImage->m_Bitmap.DeleteObject();
+		delete pDelImage;
+	}
+	return 1;
+}
+
+int	CakDataImage2::GetScaleWidth()
+{
+	CRect rect;
+	int nWidth;
+
+	//GetClientRect(rect);
+	if (nWidth != 0)
+		m_dWidthScale = double(rect.Width()) / double(nWidth);
+	return int(double(nWidth) * m_dWidthScale + 0.5);
+}
+
+int	CakDataImage2::GetScaleHeight()
+{
+	CRect rect;
+	int nHeight;// = GetHeight();
+
+	//GetClientRect(rect);
+	if (nHeight != 0)
+		m_dHeightScale = double(rect.Height()) / double(nHeight);
+	return int(double(nHeight) * m_dHeightScale + 0.5);
+}
+
+BOOL CakDataImage2::GetTrackerRect(CRect& rtRect)
+{
+// 	if (m_rectTracker.m_rect.Width() < 0 || m_rectTracker.m_rect.Height() < 0)
+// 	{
+// 		return FALSE;
+// 	}
+// 
+// 	rtRect = m_rectTracker.m_rect;
+
+	return TRUE;
+}
+
+void CakDataImage2::DrawROIRect(CDC *pDC)
+{
+	if (m_rtROIRect.Width() == 0 || m_rtROIRect.Height() == 0) return;
+
+	// 	CPen pen, *pOldPen;
+	// 	pen.CreatePen(PS_DOT, 1, RGB(255,255,255));
+	// 	pOldPen = pDC->SelectObject(&pen);
+	// 	pDC->SelectStockObject(NULL_BRUSH);
+	// 
+	// 	pDC->Rectangle(m_rtROIRect);
+
+	CFont font;
+	VERIFY(font.CreateFont(
+		15,                        // nHeight
+		6,                         // nWidth
+		0,                         // nEscapement
+		0,                         // nOrientation
+		FW_NORMAL,                 // nWeight
+		FALSE,                     // bItalic
+		FALSE,                     // bUnderline
+		0,                         // cStrikeOut
+		ANSI_CHARSET,              // nCharSet
+		OUT_DEFAULT_PRECIS,        // nOutPrecision
+		CLIP_DEFAULT_PRECIS,       // nClipPrecision
+		DEFAULT_QUALITY,           // nQuality
+		DEFAULT_PITCH | FF_SWISS,  // nPitchAndFamily
+		_T("Arial")));                 // lpszFacename
+
+	// Do something with the font just created...
+	CFont* def_font = pDC->SelectObject(&font);
+	// 	pDC->SetTextColor(RGB(255,255,255));
+	// 	pDC->SetBkMode(TRANSPARENT);
+	pDC->SetTextColor(RGB(255, 255, 0));
+	pDC->SetBkColor(RGB(0, 0, 0));
+	pDC->SetBkMode(OPAQUE);
+
+	CString strValue = _T("");
+	strValue.Format(_T("[Region] %d, %d, %d, %d"), m_rtROIRect.left, m_rtROIRect.top, m_rtROIRect.right, m_rtROIRect.bottom);
+	pDC->TextOut(m_rtROIRect.right + 5, m_rtROIRect.top + 5, strValue);
+
+	strValue.Format(_T("[Width] %d pix, %.3lf um"), m_sROIInfo.nWidthPixel, m_sROIInfo.dWidthRealUM);
+	pDC->TextOut(m_rtROIRect.right + 5, m_rtROIRect.top + 25, strValue);
+
+	strValue.Format(_T("[Height] %d pix, %.3lf um"), m_sROIInfo.nHeightPixel, m_sROIInfo.dHeightRealUM);
+	pDC->TextOut(m_rtROIRect.right + 5, m_rtROIRect.top + 45, strValue);
+
+	strValue.Format(_T("[Diagonal] %.3lf pix, %.3lf um"), m_sROIInfo.dDiagonalPixel, m_sROIInfo.dDiagonalRealUM);
+	pDC->TextOut(m_rtROIRect.right + 5, m_rtROIRect.top + 65, strValue);
+
+	strValue.Format(_T("[Resol_X] %.6lf um/pixel"), (m_dResolution / m_dWidthScale));
+	pDC->TextOut(m_rtROIRect.right + 5, m_rtROIRect.top + 85, strValue);
+
+	strValue.Format(_T("[Resol_Y] %.6lf um/pixel"), (m_dResolution / m_dHeightScale));
+	pDC->TextOut(m_rtROIRect.right + 5, m_rtROIRect.top + 105, strValue);
+
+	pDC->SelectObject(def_font);
+
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/akImageView.h b/ReviewHistory/ReveiwHistory/akImageView.h
new file mode 100644
index 0000000..a0d266a
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akImageView.h
@@ -0,0 +1,99 @@
+#pragma once
+
+#include "akGraph/akGraphBasic3.h"
+#include <vector>
+
+struct SPixelInfo
+{
+	SPixelInfo()
+	{
+		nWidthPixel = 0;
+		nHeightPixel = 0;
+		dDiagonalPixel = 0;
+		dWidthRealUM = 0;
+		dHeightRealUM = 0;
+		dDiagonalRealUM = 0;
+	}
+	int		nWidthPixel;
+	int		nHeightPixel;
+	double	dDiagonalPixel;
+
+	double	dWidthRealUM;
+	double	dHeightRealUM;
+	double	dDiagonalRealUM;
+};
+
+class CakDataImage2
+{
+public:
+	CakDataImage2(void);
+	virtual ~CakDataImage2(void);
+
+	struct _DataImage2
+	{
+		_DataImage2()
+		{
+			m_nDrawPosX = m_nDrawPosY = 0;
+			m_nRoate = 0;
+			m_nDrawWidth = m_nDrawHeight = 0;
+
+			m_bReverseX = m_bReverseY = false;
+		}
+		CString m_strBitmapFilename;
+		CBitmap m_Bitmap;
+		BITMAP	m_Bits;
+
+		unsigned char* m_pBitmapData;
+
+		//그리기 정보 [김태현 2018/12/7]
+		int m_nProjectionType;
+		int m_nDrawPosX, m_nDrawPosY;
+		int m_nDrawWidth, m_nDrawHeight;
+		float m_nRoate;
+		bool m_bReverseX, m_bReverseY;
+	};
+
+public:
+	int SetImageData(char* pFileName, int nImageIndex = 0); //add가 아니면 0번 인덱스에 넣는다.
+	int GetScaleWidth();
+	int GetScaleHeight();
+	BOOL GetTrackerRect(CRect & rtRect);
+	void DrawROIRect(CDC * pDC);
+	int GetImageDataNum() { return m_vecImageData.size(); };
+public:
+	std::vector<_DataImage2*> m_vecImageData;
+
+	double		m_dWidthScale;
+	double		m_dHeightScale;
+	double		m_dResolution;
+
+	BOOL			m_bDrawTracker;
+	CPoint			m_ptTrackerStart;
+//	CCHRectTracker	m_rectTracker;
+
+	CRect			m_rtROIRect;
+	SPixelInfo		m_sROIInfo;
+
+	// Scroll Pos
+	int			m_nVScroll;
+	int			m_nHScroll;
+	// Max Scroll Pos
+	int			m_nMaxVScroll;
+	int			m_nMaxHScroll;
+};
+
+class CakImageView : public CakGraphBasic3, public CakDataImage2
+{
+public:
+	CakImageView();
+	virtual ~CakImageView();
+
+public:
+	virtual void RenderSeries(Graphics* grfx, CDC* pDC);
+
+	virtual void SetAutoScale();
+	virtual void SetResize();
+	virtual void RenderImage(Graphics* grfx, CDC* pDC);
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point);
+};
+
diff --git a/ReviewHistory/ReveiwHistory/akLoggerExt.cpp b/ReviewHistory/ReveiwHistory/akLoggerExt.cpp
new file mode 100644
index 0000000..a6723d5
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akLoggerExt.cpp
@@ -0,0 +1,40 @@
+#include "StdAfx.h"
+#include "akLoggerExt.h"
+
+CakLoggerExt CakLoggerExt::m_Instance;
+
+CakLoggerExt::CakLoggerExt( int nBufferSize /*= 200*/, int nStringLen /*= 512 */ )
+{
+	m_hParent = NULL;
+	m_bScrollAuto = TRUE;
+}
+
+CakLoggerExt::~CakLoggerExt(void)
+{
+}
+
+void CakLoggerExt::setLog( char* format, ... )
+{
+	char text[512]={};
+	va_list ap;
+	va_start(ap, format);
+	vsprintf(text, format, ap);
+	va_end(ap);
+	CakLogger::setLog(text);
+
+	if(m_hParent) PostMessage(m_hParent, UM_UPDATE_LOGGER, 0, 0);
+}
+
+void CakLoggerExt::LogFileOpen()
+{
+	char strFileName[256];
+	
+	SYSTEMTIME st;
+	GetLocalTime(&st);
+
+	sprintf(strFileName, "%s\\%02d%02d%02d\\%s_%02d%02d%02d.log", 
+		"C:\\DIT_LogData\\", st.wYear, st.wMonth, st.wDay, 
+		"logGlassRawMessenger", st.wYear, st.wMonth, st.wDay);
+
+	ShellExecute(NULL, "Open", "NotePad.exe", strFileName, "", SW_SHOW);
+}
diff --git a/ReviewHistory/ReveiwHistory/akLoggerExt.h b/ReviewHistory/ReveiwHistory/akLoggerExt.h
new file mode 100644
index 0000000..8aa2010
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akLoggerExt.h
@@ -0,0 +1,30 @@
+#pragma once
+
+#include "akCore/akLogger.h"
+
+#define _AKLOGGER
+
+
+#if defined _AKLOGGER
+#define AKLOG(fmt,...) CakLoggerExt::getInstance()->setLog(fmt,##__VA_ARGS__) 
+#else
+#define AKLOG(fmt,...)
+#endif
+
+#define UM_UPDATE_LOGGER WM_USER+0x2255
+
+class CakLoggerExt : public CakLogger
+{
+public:
+	CakLoggerExt(int nBufferSize = 200, int nStringLen = 512 );
+	virtual ~CakLoggerExt(void);
+
+	static CakLoggerExt *getInstance() {return &m_Instance;};	
+	virtual void setLog(char* format, ...);
+	void LogFileOpen();//NotePad로 열기
+public:
+	HWND m_hParent;
+	BOOL m_bScrollAuto;
+protected:
+	static CakLoggerExt m_Instance;
+};
diff --git a/ReviewHistory/ReveiwHistory/akWndArrange.cpp b/ReviewHistory/ReveiwHistory/akWndArrange.cpp
new file mode 100644
index 0000000..3593aa8
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akWndArrange.cpp
@@ -0,0 +1,98 @@
+#include "StdAfx.h"
+#include "akWndArrange.h"
+
+
+CakWndArrange::CakWndArrange(void)
+{
+	m_pWndParent = NULL;
+	m_rectOriginal.SetRect(0,0,0,0);
+}
+
+
+CakWndArrange::~CakWndArrange(void)
+{
+	clear();
+}
+
+void CakWndArrange::clear()
+{
+	m_vecWndChild.clear();
+}
+
+void CakWndArrange::setParentWnd( CWnd* pWnd )
+{
+	m_pWndParent = pWnd;
+	pWnd->GetClientRect(m_rectOriginal);
+}
+
+void CakWndArrange::addChildWnd( CWnd* pWnd, int nStyle )
+{
+	
+	_WndData data;
+	data.nStyle = nStyle;
+	data.hWnd = pWnd->GetSafeHwnd();
+
+	pWnd->GetWindowRect(&data.rectOrginal);
+	m_pWndParent->ScreenToClient(&data.rectOrginal);
+
+	m_vecWndChild.push_back(data);
+}
+
+void CakWndArrange::setChildStyle( CWnd* pWnd, int nStyle )
+{
+	HWND hWnd = pWnd->GetSafeHwnd();
+	for(int i=0; i<m_vecWndChild.size(); i++)
+	{
+		if(m_vecWndChild[i].hWnd == hWnd)
+		{
+			m_vecWndChild[i].nStyle = nStyle;
+		}
+	}
+}
+
+void CakWndArrange::process( int nWidth, int nHeight )
+{
+	if(nWidth*nHeight <= 0) return;
+	int nSize = m_vecWndChild.size();
+
+	_WndData WndChild;
+	CRect rectParentOrg = m_rectOriginal;
+	CRect rectNew;
+	for(int i=0; i<nSize; i++)
+	{
+		WndChild = m_vecWndChild[i];
+		
+		rectNew = WndChild.rectOrginal;
+		if(WA_RIGHTTOP & WndChild.nStyle)
+		{
+			rectNew.left = nWidth - ((rectParentOrg.right)-WndChild.rectOrginal.left);
+			rectNew.right = rectNew.left + WndChild.rectOrginal.Width();
+		}
+		else if(WA_LEFTBOTTOM & WndChild.nStyle)
+		{
+			rectNew.top = nHeight - ((rectParentOrg.bottom)-WndChild.rectOrginal.top);
+			rectNew.bottom = rectNew.top + WndChild.rectOrginal.Height();
+		}
+		else if(WA_RIGHTBOTTOM & WndChild.nStyle)
+		{
+			rectNew.left = nWidth - ((rectParentOrg.right)-WndChild.rectOrginal.left);
+			rectNew.right = rectNew.left + WndChild.rectOrginal.Width();
+		}
+		else if(WA_LEFTTOP & WndChild.nStyle)
+		{
+
+		}
+
+		if(WA_RESIZE_WIDTH & WndChild.nStyle)
+		{
+			rectNew.right += (nWidth-rectParentOrg.Width());
+		}
+		if(WA_RESIZE_HEIGHT & WndChild.nStyle)
+		{
+			rectNew.bottom += (nHeight-rectParentOrg.Height());
+		}
+		
+		MoveWindow(WndChild.hWnd, rectNew.left, rectNew.top, rectNew.Width(), rectNew.Height(), TRUE);
+	}
+
+}
diff --git a/ReviewHistory/ReveiwHistory/akWndArrange.h b/ReviewHistory/ReveiwHistory/akWndArrange.h
new file mode 100644
index 0000000..4ffca31
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/akWndArrange.h
@@ -0,0 +1,41 @@
+#pragma once
+
+//다이얼로그 크기변화에 따른 크기 위치 자동 지정   태현[2016/12/23]
+#include <vector>
+
+enum _POSSIZETYPE
+{
+	WA_LEFTTOP = 0x1,
+	WA_LEFTBOTTOM = 0x2,
+	WA_RIGHTTOP = 0x4,
+	WA_RIGHTBOTTOM = 0x8,
+	WA_RESIZE_WIDTH = 0x10,
+	WA_RESIZE_HEIGHT = 0x20,
+};
+
+class CakWndArrange
+{
+public:
+	CakWndArrange(void);
+	virtual ~CakWndArrange(void);
+
+protected:
+	struct _WndData 
+	{
+		HWND hWnd;
+		CRect rectOrginal;
+		int nStyle;
+	};
+
+public:
+	void clear();
+	void setParentWnd(CWnd* pWnd);
+	void addChildWnd(CWnd* pWnd, int nStyle);
+	void setChildStyle(CWnd* pWnd, int nStyle);
+	
+	void process(int nWidth, int nHeight);//void OnSize(UINT nType, int cx, int cy) 함수에서 호출
+protected:
+	CWnd* m_pWndParent;
+	CRect m_rectOriginal;
+	std::vector<_WndData> m_vecWndChild;
+};
diff --git a/ReviewHistory/ReveiwHistory/res/History.ico b/ReviewHistory/ReveiwHistory/res/History.ico
new file mode 100644
index 0000000..4bc9664
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/res/History.ico
Binary files differ
diff --git a/ReviewHistory/ReveiwHistory/res/ReveiwHistory.ico b/ReviewHistory/ReveiwHistory/res/ReveiwHistory.ico
new file mode 100644
index 0000000..d56fbcd
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/res/ReveiwHistory.ico
Binary files differ
diff --git a/ReviewHistory/ReveiwHistory/res/ReveiwHistory.rc2 b/ReviewHistory/ReveiwHistory/res/ReveiwHistory.rc2
new file mode 100644
index 0000000..d8e7531
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/res/ReveiwHistory.rc2
Binary files differ
diff --git a/ReviewHistory/ReveiwHistory/resource.h b/ReviewHistory/ReveiwHistory/resource.h
new file mode 100644
index 0000000..a06eef9
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/resource.h
@@ -0,0 +1,102 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++에서 생성한 포함 파일입니다.
+// ReveiwHistory.rc에서 사용되고 있습니다.
+//
+#define IDM_ABOUTBOX                    0x0010
+#define IDD_ABOUTBOX                    100
+#define IDS_ABOUTBOX                    101
+#define IDD_DLG_REVIEWHISTORY           102
+#define IDD_DIALOG_FORMLIST             104
+#define IDD_DLG_ALIGN                   104
+#define IDR_MAINFRAME                   128
+#define IDR_MENU1                       132
+#define IDD_DLG_PATH_SETTING            133
+#define IDB_SPLASH                      137
+#define IDI_ICON1                       149
+#define IDR_ICON1                       149
+#define IDC_BUTTON1                     1000
+#define IDC_PROCESS_RUN                 1000
+#define IDC_BTN_BIN_PATH                1000
+#define IDC_STATIC_FORMATIONMAP         1001
+#define IDC_EDIT_BIN_PATH               1001
+#define IDC_EDIT_RAWFILENAME            1002
+#define IDC_BTN_INSPECTOR_PATH          1002
+#define IDC_EDIT_GLASSWIDTH             1003
+#define IDC_EDIT_INSPECTOR_PATH         1003
+#define IDC_EDIT_GLASSHEIGHT            1004
+#define IDC_BTN_REVIEW_PATH             1004
+#define IDC_STATIC_FORMATIONMAP2        1004
+#define IDC_EDIT_RESULT_DEFECENUM       1005
+#define IDC_EDIT_REVIEW_PATH            1005
+#define IDC_EDIT_RESULT_GROUPROUND      1006
+#define IDC_BTN_ALIGN_PATH              1006
+#define IDC_EDIT_RESULT_GROUPLINE       1007
+#define IDC_EDIT_ALIGN_PATH             1007
+#define IDC_EDIT_RESULT_NONEGROUP       1008
+#define IDC_BTN_SAVE                    1008
+#define IDC_EDIT_FILE_COUNT             1008
+#define IDC_BUTTON_SHOWLABELTEXT        1009
+#define IDC_EDIT_MERGEX                 1010
+#define IDC_EDIT_MERGEY                 1011
+#define IDC_EDIT_MERGELIMIT             1012
+#define IDC_CHECK_SHOWGROUPLINE         1013
+#define IDC_CHECK_SHOWGROUPINDEX        1014
+#define IDC_CHECK_SHOWDEFECTNORMAL      1015
+#define IDC_CHECK_SHOWDEFECTROUND       1016
+#define IDC_CHECK_SHOWDEFECTLINE        1017
+#define IDC_EDIT_FORMLINE_LIMITHEIGHT   1018
+#define IDC_CHECK_RAWDATAXYFLIP         1019
+#define IDC_CHECK_SHOWDEFECTCOLORTYPE   1020
+#define IDC_CHECK_SHOWDEFECTOUTLINE     1021
+#define IDC_BUTTON_MAPVIEW_FIT          1022
+#define IDC_BTN_MAPVIEW_FIT             1022
+#define IDC_CHECK_SHOWCELL              1023
+#define IDC_BUTTON_SHOWDEFECTLIST       1024
+#define IDC_COMBO_SHOWLABEL             1025
+#define IDC_COMBO_SHOWSIZE              1026
+#define IDC_BUTTON2                     1026
+#define IDC_BTN_FIND_BIN                1026
+#define IDC_BUTTON_SHOWFORMLIST         1027
+#define IDC_CHECK_SHOWNOFILTEREDDEFECT  1028
+#define IDC_EDIT_RESULT_SUMMERY         1029
+#define IDC_RECT_GRIDDEFECT2            1030
+#define IDC_STATIC_GRID_GLASS           1030
+#define IDC_STATIC_GRID_ALIGN           1030
+#define IDC_COMBO_METHOD_LABEL          1031
+#define IDC_IMG_ALIGN1                  1031
+#define IDC_STATIC_GRID_DEFECT          1031
+#define IDC_IMG_ALIGN2                  1032
+#define IDC_STATIC_GRID_GLASS_INFO      1032
+#define IDC_STATIC_FILE_LIST            1033
+#define IDC_STATIC_DEFECT               1034
+#define IDC_STATIC_IMG_REVIEW           1035
+#define IDC_STATIC_IMG_INSPECTOR        1036
+#define IDC_STATIC_IMG_ALIGN1           1037
+#define IDC_STATIC_IMG_ALIGN2           1038
+#define IDC_SLIDER_IMG                  1039
+#define IDC_EDIT_COUNT                  1040
+#define IDC_CHK_All_DEFECT              1041
+#define IDC_CHK_REVIEW_DEFECT           1042
+#define IDC_BUTTON3                     1043
+#define IDC_CHK_MUTI                    1044
+#define IDC_CHK_SINGLE                  1045
+#define IDC_STATIC_DEFECT2              1046
+#define IDC_PROGRESS_FILE               1047
+#define IDC_PROGRESS1                   1048
+#define IDC_PROGRESS_LOAD               1048
+#define ID_OPTION_PATHSETTING           32771
+#define ID_VIEW_ALLDEFECT               32772
+#define ID_VIEW_REVIEWDEFECT            32773
+#define ID_ALIGN_ALIGNVIEW              32774
+#define ID_ALIGN_VIEW                   32775
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        150
+#define _APS_NEXT_COMMAND_VALUE         32776
+#define _APS_NEXT_CONTROL_VALUE         1054
+#define _APS_NEXT_SYMED_VALUE           104
+#endif
+#endif
diff --git a/ReviewHistory/ReveiwHistory/stdafx.cpp b/ReviewHistory/ReveiwHistory/stdafx.cpp
new file mode 100644
index 0000000..2c9e56f
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/stdafx.cpp
@@ -0,0 +1,137 @@
+癤�
+// stdafx.cpp : �몴以� �룷�븿 �뙆�씪留� �뱾�뼱 �엳�뒗 �냼�뒪 �뙆�씪�엯�땲�떎.
+// ReveiwHistory.pch�뒗 誘몃━ 而댄뙆�씪�맂 �뿤�뜑媛� �맗�땲�떎.
+// stdafx.obj�뿉�뒗 誘몃━ 而댄뙆�씪�맂 �삎�떇 �젙蹂닿� �룷�븿�맗�땲�떎.
+
+#include "stdafx.h"
+
+
+CCriticalSection g_criticalExe;
+CCriticalSection g_criticalLog;
+
+
+CString	GetExePath()
+{
+	g_criticalExe.Lock();
+
+	static TCHAR pBuf[256] = { 0, };
+
+	memset(pBuf, NULL, sizeof(pBuf));
+
+	if (AfxGetApp())
+		GetModuleFileName(AfxGetApp()->m_hInstance, pBuf, sizeof(pBuf));
+	else
+		GetModuleFileName(NULL, pBuf, sizeof(pBuf));
+
+	CString strFilePath;
+
+	strFilePath.Format(_T("%s"), pBuf);
+
+	strFilePath = strFilePath.Left(strFilePath.ReverseFind(_T('\\')));
+
+	g_criticalExe.Unlock();
+
+	return strFilePath.GetString();
+}
+
+void LOG(int nType, const char* fmt, ...)
+{
+	g_criticalLog.Lock();
+
+	static _TCHAR szLog[5096];
+
+	FILE*		fp = NULL;
+	CTime		tm = CTime::GetCurrentTime();
+	CString		strLog = _T("");
+	CString		strPath = _T("");
+	va_list		args;
+	SYSTEMTIME	cur_time;
+
+	if (fmt == NULL)
+	{
+		g_criticalLog.Unlock();
+
+		return;
+	}
+
+	ZeroMemory(szLog, 5096);
+	va_start(args, fmt);
+	wvsprintf(szLog, fmt, args);
+	va_end(args);
+
+	strPath.Format("%s\\Log\\%s", GetExePath(), tm.Format("%Y_%m_%d_%H.log").GetString());
+
+	fopen_s(&fp, (LPSTR)(LPCSTR)strPath, "a+");
+
+	GetLocalTime(&cur_time);
+
+	strLog.Format("%04d-%02d-%02d %02d:%02d:%02d:%03ld : ",
+		cur_time.wYear,
+		cur_time.wMonth,
+		cur_time.wDay,
+		cur_time.wHour,
+		cur_time.wMinute,
+		cur_time.wSecond,
+		cur_time.wMilliseconds);
+
+	if (fp != NULL)
+	{
+		switch (nType)
+		{
+		case Normal: strLog += _T("[NORMAL    ] : ");	break;
+		case Dbg: strLog += _T("[DEBUG     ] : ");	break;
+		case Operation: strLog += _T("[OPERATION ] : ");	break;
+		case Err: strLog += _T("[ERROR     ] : ");  break;
+		}
+
+		strLog += szLog;
+
+		fprintf(fp, "%s\r\n", (LPSTR)(LPCSTR)strLog);
+		fflush(fp);
+		fclose(fp);
+	}
+
+	g_criticalLog.Unlock();
+}
+
+void	INIWriteStr(CString strAppName, CString strKeyName, CString strValue, CString strFilePath)
+{
+	WritePrivateProfileString(strAppName, strKeyName, strValue, strFilePath);
+}
+
+CString	INIReadStr(CString strAppName, CString strKeyName, CString strFilePath)
+{
+	TCHAR szReturnString[1024] = { 0, };
+
+	memset(szReturnString, NULL, 1024);
+
+	GetPrivateProfileString(strAppName, strKeyName, _T(""), szReturnString, 1024, strFilePath);
+
+	CString str;
+
+	str.Format(_T("%s"), szReturnString);
+
+	return str;
+}
+
+void	INIWriteInt(CString strAppName, CString strKeyName, int nValue, CString strFilePath)
+{
+	CString str;
+
+	str.Format(_T("%d"), nValue);
+
+	WritePrivateProfileString(strAppName, strKeyName, str, strFilePath);
+}
+
+int		INIReadInt(CString strAppName, CString strKeyName, CString strFilePath)
+{
+	TCHAR szReturnString[1024] = { 0, };
+
+	memset(szReturnString, NULL, 1024);
+
+	GetPrivateProfileString(strAppName, strKeyName, _T(""), szReturnString, 1024, strFilePath);
+
+	int nRet = atoi(szReturnString);
+
+	return nRet;
+}
\ No newline at end of file
diff --git a/ReviewHistory/ReveiwHistory/stdafx.h b/ReviewHistory/ReveiwHistory/stdafx.h
new file mode 100644
index 0000000..b9827a1
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/stdafx.h
@@ -0,0 +1,85 @@
+癤�
+// stdafx.h : �옄二� �궗�슜�븯吏�留� �옄二� 蹂�寃쎈릺吏��뒗 �븡�뒗
+// �몴以� �떆�뒪�뀥 �룷�븿 �뙆�씪 諛� �봽濡쒖젥�듃 愿��젴 �룷�븿 �뙆�씪�씠 
+// �뱾�뼱 �엳�뒗 �룷�븿 �뙆�씪�엯�땲�떎.
+
+#pragma once
+
+#ifndef VC_EXTRALEAN
+#define VC_EXTRALEAN            // 嫄곗쓽 �궗�슜�릺吏� �븡�뒗 �궡�슜�� Windows �뿤�뜑�뿉�꽌 �젣�쇅�빀�땲�떎.
+#endif
+
+#include "targetver.h"
+
+#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS      // �씪遺� CString �깮�꽦�옄�뒗 紐낆떆�쟻�쑝濡� �꽑�뼵�맗�땲�떎.
+
+// MFC�쓽 怨듯넻 遺�遺꾧낵 臾댁떆 媛��뒫�븳 寃쎄퀬 硫붿떆吏��뿉 ���븳 �닲湲곌린瑜� �빐�젣�빀�땲�떎.
+#define _AFX_ALL_WARNINGS
+
+#include <afxwin.h>         // MFC �빑�떖 諛� �몴以� 援ъ꽦 �슂�냼�엯�땲�떎.
+#include <afxext.h>         // MFC �솗�옣�엯�땲�떎.
+
+
+#include <afxdisp.h>        // MFC �옄�룞�솕 �겢�옒�뒪�엯�땲�떎.
+
+
+
+#ifndef _AFX_NO_OLE_SUPPORT
+#include <afxdtctl.h>           // Internet Explorer 4 怨듭슜 而⑦듃濡ㅼ뿉 ���븳 MFC 吏��썝�엯�땲�떎.
+#endif
+#ifndef _AFX_NO_AFXCMN_SUPPORT
+#include <afxcmn.h>             // Windows 怨듭슜 而⑦듃濡ㅼ뿉 ���븳 MFC 吏��썝�엯�땲�떎.
+#endif // _AFX_NO_AFXCMN_SUPPORT
+
+#include <afxcontrolbars.h>     // MFC�쓽 由щ낯 諛� 而⑦듃濡� 留됰� 吏��썝
+#include <afxwin.h>
+#include <afxcontrolbars.h>
+#include <afxcontrolbars.h>
+#include <afxcontrolbars.h>
+#include <afxcontrolbars.h>
+#include <afxcontrolbars.h>
+
+
+
+
+
+
+
+
+
+#ifdef _UNICODE
+#if defined _M_IX86
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#elif defined _M_X64
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#else
+#pragma comment(linker,"/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")
+#endif
+#endif
+
+enum LogType
+{
+	Normal = 0,
+	Dbg,
+	Operation,
+	Err
+};
+
+#define GRID_FIX_COLOR			RGB(0,128,255)
+#define GRID_COLOR				RGB(242,242,242)
+#define GRID_TEXT_COLOR			RGB(255,255,255)
+#define GRID_ALARM_TEXT_COLOR	RGB(255,0,0)
+#define GRID_LINE_COLOR			GRID_FIX_COLOR
+
+extern CCriticalSection g_criticalExe;
+extern CCriticalSection g_criticalLog;
+
+CString	GetExePath();
+
+void	LOG(int nType, const char* fmt, ...);
+
+CString INIReadStr(CString strAppName, CString strKeyName, CString strFilePath);
+void	INIWriteStr(CString strAppName, CString strKeyName, CString strValue, CString strFilePath);
+
+int		INIReadInt(CString strAppName, CString strKeyName, CString strFilePath);
+void	INIWriteInt(CString strAppName, CString strKeyName, int nValue, CString strFilePath);
diff --git a/ReviewHistory/ReveiwHistory/targetver.h b/ReviewHistory/ReveiwHistory/targetver.h
new file mode 100644
index 0000000..4464219
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/targetver.h
@@ -0,0 +1,8 @@
+癤�#pragma once
+
+// SDKDDKVer.h瑜� �룷�븿�븯硫� 理쒓퀬 �닔以��쓽 媛��슜�꽦�쓣 媛�吏� Windows �뵆�옯�뤌�씠 �젙�쓽�맗�땲�떎.
+
+// �씠�쟾 Windows �뵆�옯�뤌�뿉 ���빐 �쓳�슜 �봽濡쒓렇�옩�쓣 鍮뚮뱶�븯�젮�뒗 寃쎌슦�뿉�뒗 SDKDDKVer.h瑜� �룷�븿�븯湲� �쟾�뿉
+// WinSDKVer.h瑜� �룷�븿�븯怨� _WIN32_WINNT 留ㅽ겕濡쒕�� 吏��썝�븯�젮�뒗 �뵆�옯�뤌�쑝濡� �꽕�젙�븯�떗�떆�삤.
+
+#include <SDKDDKVer.h>
diff --git a/ReviewHistory/ReveiwHistory/x64/Debug/reveiwhistorydlg.obj.enc b/ReviewHistory/ReveiwHistory/x64/Debug/reveiwhistorydlg.obj.enc
new file mode 100644
index 0000000..a4d3930
--- /dev/null
+++ b/ReviewHistory/ReveiwHistory/x64/Debug/reveiwhistorydlg.obj.enc
Binary files differ
diff --git a/ReviewHistory/ReviewHistory.sln b/ReviewHistory/ReviewHistory.sln
new file mode 100644
index 0000000..28a1f04
--- /dev/null
+++ b/ReviewHistory/ReviewHistory.sln
@@ -0,0 +1,37 @@
+癤�
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.28307.779
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ReviewHistroy", "ReveiwHistory\ReveiwHistory.vcxproj", "{FDD89A84-12C4-4024-8101-0E719E2BD9F6}"
+EndProject
+Global
+	GlobalSection(SolutionConfigurationPlatforms) = preSolution
+		Debug|x64 = Debug|x64
+		Debug|x86 = Debug|x86
+		Release|x64 = Release|x64
+		Release|x86 = Release|x86
+		Template|x64 = Template|x64
+		Template|x86 = Template|x86
+	EndGlobalSection
+	GlobalSection(ProjectConfigurationPlatforms) = postSolution
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Debug|x64.ActiveCfg = Debug|x64
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Debug|x64.Build.0 = Debug|x64
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Debug|x86.ActiveCfg = Debug|Win32
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Debug|x86.Build.0 = Debug|Win32
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Release|x64.ActiveCfg = Release|x64
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Release|x64.Build.0 = Release|x64
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Release|x86.ActiveCfg = Release|Win32
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Release|x86.Build.0 = Release|Win32
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Template|x64.ActiveCfg = Release|x64
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Template|x64.Build.0 = Release|x64
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Template|x86.ActiveCfg = Release|Win32
+		{FDD89A84-12C4-4024-8101-0E719E2BD9F6}.Template|x86.Build.0 = Release|Win32
+	EndGlobalSection
+	GlobalSection(SolutionProperties) = preSolution
+		HideSolutionNode = FALSE
+	EndGlobalSection
+	GlobalSection(ExtensibilityGlobals) = postSolution
+		SolutionGuid = {9EC23A79-F150-4305-894D-F8D9C663D1D2}
+	EndGlobalSection
+EndGlobal
diff --git a/ReviewHistory/include/akCore/akBit.h b/ReviewHistory/include/akCore/akBit.h
new file mode 100644
index 0000000..32c6701
--- /dev/null
+++ b/ReviewHistory/include/akCore/akBit.h
@@ -0,0 +1,57 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+
+//namespace akCore
+//{
+
+	class AKCORE_DLLSPEC CakBit
+	{
+	public:
+		CakBit(void);
+		CakBit(int nBit);
+		~CakBit(void);
+		
+
+		void setBit(int nBit);
+		void setBitFlag(int nBitIndex, bool bFlag);
+
+		int getBit();
+		bool getBitFlag(int nBitIndex);
+		
+
+	protected:
+		int m_nBit;
+
+	public:
+		//비트 체크(on되있으면 true 반환)
+		static int bitChk(int orig, int target)
+		{        
+			if(target<32 && (orig&(0x1 << target)))return 1;
+			else return 0;
+		}
+
+		//비트 온 
+		static int bitOn(int orig, int target)
+		{        
+			if(target<32)return orig|(0x1 << target);
+			else return orig;
+		}
+
+		//비트 오프  
+		static int bitOff(int orig, int target)
+		{        
+			if(target<32)return orig&(~(0x1 << target));
+			else return orig;
+		}
+
+		//비트 스위치
+		static int bitTurn(int orig, int target)   
+		{      
+			if(target<32)return orig^(0x1 << target);
+			else return orig;
+		}
+	};
+
+//};
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akColorStruct.h b/ReviewHistory/include/akCore/akColorStruct.h
new file mode 100644
index 0000000..dc1b73e
--- /dev/null
+++ b/ReviewHistory/include/akCore/akColorStruct.h
@@ -0,0 +1,128 @@
+#pragma once
+
+#include "khLinker.h"
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+namespace KimHeart
+{
+	struct KIMHEART_DLLSPEC khVector3d
+	{
+		double pos[3];
+
+		khVector3d();
+		khVector3d(double x,double y, double z);
+		inline void set(double x,double y, double z);
+		inline double x(){return pos[0];};
+		inline double y(){return pos[1];};
+		inline double z(){return pos[2];};
+
+		double& operator()(int index){return pos[index];};
+
+		inline khVector3d operator+(const khVector3d& vec3d);
+		inline khVector3d operator-(const khVector3d& vec3d);
+		inline khVector3d& operator=(const khVector3d& vec3d);
+		inline khVector3d& operator+=(const khVector3d& vec3d);
+		inline khVector3d& operator-=(const khVector3d& vec3d);
+		khVector3d operator*(float& a)
+		{
+			khVector3d returnval;
+
+			returnval.pos[0] = pos[0] * a;
+			returnval.pos[1] = pos[1] * a;
+			returnval.pos[2] = pos[2] * a;
+
+			return returnval;
+		};
+
+		khVector3d operator *(khVector3d &vec)
+		{
+			khVector3d vc;
+			vc.pos[0] = pos[1]*vec.pos[2] - pos[2]*vec.pos[1];
+			vc.pos[1] = pos[2]*vec.pos[0] - pos[0]*vec.pos[2];
+			vc.pos[2] = pos[0]*vec.pos[1] - pos[1]*vec.pos[0];
+			return vc;
+		}
+
+		float Dot(khVector3d vec)
+		{
+			return (float)(vec.pos[0] * pos[0] + vec.pos[1] * pos[1] + vec.pos[2] * pos[2]);
+		};
+		float Mag()
+		{
+			return (float)sqrt(pos[0]*pos[0]+pos[1]*pos[1]);
+		};
+		void Normalize()
+		{
+			float length;
+
+			//벡터의 길이를 계산한다.
+			length = (float)sqrt((pos[0]*pos[0]) + (pos[1]*pos[1]) +(pos[2]*pos[2]));
+			// 길이가 0에 가까운 벡터에게 절절한 값을 항당하여 프로그램이 폭주하지 않도록 한다.
+			if(length == 0.0f) length = 1.0f;
+
+			// 각 성분을 벡터의 길이로 나누면 단위 벡터가 된다.
+			pos[0] = pos[0] / length;
+			pos[1] = pos[1] / length;
+			pos[2] = pos[2] / length;
+
+		};
+	};
+
+	struct KIMHEART_DLLSPEC khVector2d
+	{
+		double pos[2];
+
+		khVector2d();
+		khVector2d(double x,double y);
+		inline void set(double x,double y);
+		inline double x(){return pos[0];};
+		inline double y(){return pos[1];};
+
+		double& operator()(int index){return pos[index];};
+
+		inline khVector2d operator+(const khVector2d& vec3d);
+		inline khVector2d operator-(const khVector2d& vec3d);
+		inline khVector2d& operator=(const khVector2d& vec3d);
+		inline khVector2d& operator+=(const khVector2d& vec3d);
+		inline khVector2d& operator-=(const khVector2d& vec3d);
+		
+	};
+
+	struct KIMHEART_DLLSPEC khColor4f
+	{
+		float color[4];
+
+		khColor4f();
+		khColor4f(float R, float G, float B, float A=0.0f);
+		void set(float R, float G, float B, float A=0.0f);
+		inline float R(){return color[0];};
+		inline float G(){return color[1];};
+		inline float B(){return color[2];};
+		inline float A(){return color[3];};
+		inline khColor4f& operator=(const khColor4f& ksgcolor);
+	};
+
+	struct KIMHEART_DLLSPEC khRect
+	{
+		double pos[4];
+
+		khRect();
+		khRect(double left, double top, double right, double bottom);
+		void set(double left, double top, double right, double bottom);
+		inline khRect& operator=(const khRect& rect);
+		inline double Left(){return pos[0];};
+		inline double Top(){return pos[1];};
+		inline double Right(){return pos[2];};
+		inline double Bottom(){return pos[3];};
+		inline double Width(){return pos[2]-pos[0];};
+		inline double Height(){return pos[3]-pos[1];};
+		inline void SetAlign(); //작은값이 왼쪽, 위, 큰값이 오른쪽 아래로 가게 한다.
+		inline bool CheckAreaIn(double x, double y); //사각형 영역에 x,y포인트가 있는지 검사
+		inline bool CheckWidthIn(double p1); //x포인트 가운데 점이 있는지 검사
+		inline bool CheckHeightIn(double p1); //y포인트 가운데 점이 있는지 검사
+
+
+	};
+};
diff --git a/ReviewHistory/include/akCore/akCoordinate.h b/ReviewHistory/include/akCore/akCoordinate.h
new file mode 100644
index 0000000..d6273e2
--- /dev/null
+++ b/ReviewHistory/include/akCore/akCoordinate.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+namespace akCore
+{
+
+	class AKCORE_DLLSPEC CakCoordinate
+	{
+	public:
+		CakCoordinate(void);
+		~CakCoordinate(void);
+
+		//Degree를 도분초로 변환
+		static double GetDMStoDgree(int  d, int  m, double  s);
+		//도분초를 Degree로 변환
+		static void GetDgreetoDMS(double degree, int* d, int* m, double* s);
+		//Degree값을 180방위 + 방향(W,E)로 변환
+		static void GetMakeDMS180(int degree, int* rDeg, char* rDir);
+		//Degree값을 90방위 + 방향(S,N)로 변환
+		static void GetMakeDMS90(int degree, int* rDeg, char* rDir);
+		//Degree값을 //-180~+180로 변환
+		static double GetMakeDegree180(double degree);
+		//Degree값을 //-90~+90로 변환
+		static double GetMakeDegree90(double degree);
+	};
+
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akCoreLinker.h b/ReviewHistory/include/akCore/akCoreLinker.h
new file mode 100644
index 0000000..f28ee9a
--- /dev/null
+++ b/ReviewHistory/include/akCore/akCoreLinker.h
@@ -0,0 +1,63 @@
+#pragma once
+
+#pragma warning(disable:4251)
+
+//inline void memset4byte(void* dest, const int data, const unsigned int count)
+//{
+//	__asm
+//	{
+//		mov edi, dest;
+//		mov ecx, count
+//		mov eax, data
+//		rep stosd
+//	};
+//};
+typedef unsigned int uint;
+typedef unsigned char byte;
+
+#ifdef _AKCORE_EXPORTS
+#define AKCORE_DLLSPEC    __declspec( dllexport )
+#else
+#define AKCORE_DLLSPEC    __declspec( dllimport )
+#endif
+
+
+
+#ifndef _AKCORE_EXPORTS
+	
+	#undef _AUTOLIBNAME
+	#undef _AKPROJECTNAME
+	#undef _AKVCVER
+	#undef _AKDEBUG
+
+	#define _AKPROJECTNAME "akCore"
+
+	#ifdef _DEBUG
+	#define _AKDEBUG "d"
+	#else
+	#define _AKDEBUG ""
+	#endif
+
+	#if(_MSC_VER < 1910)
+	#define _AKWINDOWSDK ""
+	#else
+	#define _AKWINDOWSDK "_WS10"
+	#endif   
+
+
+	#ifdef WIN64 
+	#define _AKX64 "_x64"
+	#elif _WIN64 
+	#define _AKX64 "_x64"
+	#else        
+	#define _AKX64 ""
+	#endif
+
+	#define _AUTOLIBNAME _AKPROJECTNAME""_AKDEBUG""_AKWINDOWSDK""_AKX64".lib"
+
+	// You may turn off this include message by defining _NOPSAUTOLIB
+	#ifndef _NOPSAUTOLIBMSG
+		#pragma message( ">>Kim Tae Hyun - akCore<< Will automatically link with " _AUTOLIBNAME )
+	#endif
+		#pragma comment(lib, _AUTOLIBNAME)
+#endif
diff --git a/ReviewHistory/include/akCore/akDE.h b/ReviewHistory/include/akCore/akDE.h
new file mode 100644
index 0000000..445c9e6
--- /dev/null
+++ b/ReviewHistory/include/akCore/akDE.h
@@ -0,0 +1,123 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+
+#define _USE_MATH_DEFINES
+
+#include <math.h>
+#include <windows.h>
+
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakDE {
+	public:
+		CakDE(void);
+		~CakDE(void);
+		// TODO: 여기에 메서드를 추가합니다.
+
+	public:
+		/**
+		* 함수명 : getMovingPostion
+		*		현제의 좌표로부터 속도와 시간만큼 움직였을때의 좌표 도출
+		* Parameters:
+		*		double* posX	//X좌표(결과값 반환)
+		*		double* posY	//Y좌표(결과값 반환)
+		*		double* posZ	//Z좌표(결과값 반환)
+		*		double heading	//Heading(0~360)
+		*		double pitch	//Pitch(0~360)
+		*		double velocity	//속도(m/s
+		*		unsigned int Framerate	//프레임(Hz)
+		* Returns:
+		*		정상적인 계산 완료시 True 반환
+		*/
+		bool getMovingPostion(double* posX,double* posY,double* posZ,double heading,double pitch, double velocity, unsigned int Framerate);
+		bool getNextPostion(double* posX,double* posY,double* posZ,double heading,double pitch, double velocity, double Dt);
+
+		/**
+		* 함수명 : getRotatePostion
+		*		현제 좌표로부터 Heading,Pitch방향으로 정해진 값만큼 움직였을때 좌표 도출
+		* Parameters:
+		*		double* posX	//X좌표(결과값 반환)
+		*		double* posY	//Y좌표(결과값 반환)
+		*		double* posZ	//Z좌표(결과값 반환)
+		*		double heading	//Heading(0~360)
+		*		double pitch	//Pitch(0~360)
+		*		double radius	//거리
+		* Returns:
+		*		정상적인 계산 완료시 True 반환
+		*/
+		bool getRotatePostion(double* posX, double* posY, double* posZ, double heading, double pitch, double radius);
+
+		/**
+		* 함수명 : getAngle3d
+		*		두 좌표가 이루는 각을 환산
+		* Parameters:
+		*		double x1		// 첫번째 좌표
+		*		double y1		// 첫번째 좌표
+		*		double z1		// 첫번째 좌표
+		*		double x2		// 두번째 좌표
+		*		double y2		// 두번째 좌표
+		*		double z2		// 두번째 좌표
+		*		double heading	//Heading(결과값 반환)
+		*		double pitch	//Pitch(결과값 반환)
+		* Returns:
+		*/
+		void getAngle3d(double x1, double y1, double z1, double x2, double y2, double z2, double* heading, double* pitch);
+
+		/**
+		* 함수명 : AngleClosing
+		*		두 각의 간격 크기
+		* Parameters:
+		*		double center		// 중심 각
+		*		double angle		// 회전 각
+		*		int option			// 0은 무조건 가까운쪽 각 
+		* Returns:
+		*		중심각과 회전각의 간격 반환
+		*/
+		double GetAngleClosing(double center, double angle, int option = 0);
+
+		/**
+		* 함수명 : GetAngle360
+		*		각을 0~360도 환산
+		* Parameters:
+		*		double angle		// 입력 각
+		* Returns:
+		*		0~360도로 환산된 각
+		*/
+		inline double GetAngle360(double angle);
+
+		/**
+		* 함수명 : GetAngle180
+		*		각을 -180~180도 환산
+		* Parameters:
+		*		double angle		// 입력 각
+		* Returns:
+		*		-180~180도로 환산된 각
+		*/
+		static inline double GetAngle180(double angle);
+
+
+
+		static void getRoate2d(double angle, double orgx,double orgy, double* x, double* y);
+
+		double distance3d(double x1, double y1, double z1, double x2, double y2, double z2);
+
+		void rotateposition3d(double x1,double y1, double z1, double* x2, double* y2, double* z2, double h, double p);
+
+		void axisrotate(  double* nx, double* ny, double* nz, 
+			double cx, double cy, double cz,
+			double tx, double ty, double tz,
+			double heading, double pitch, double roll  );
+
+		bool missilesim(double msx, double msy, double msz, double msh, double msp, double msah, double msap, double tgx, double tgy, double tgz, double velocty, double acceleration, int FrameRate);
+
+		inline static double getHeading(double x , double y);
+		
+		inline double RadianToDegree(double radian);
+		inline double DegreeToRadian(double degree);
+		inline bool GetCheckAngleRange(double p1, double stAngle, double endAngle);
+	private:
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akDE2.h b/ReviewHistory/include/akCore/akDE2.h
new file mode 100644
index 0000000..9612d37
--- /dev/null
+++ b/ReviewHistory/include/akCore/akDE2.h
@@ -0,0 +1,123 @@
+#pragma once
+
+
+#include "akLinker.h"
+
+#define _USE_MATH_DEFINES
+
+#include <math.h>
+#include <windows.h>
+
+
+namespace akCore
+{
+	class akCore_DLLSPEC CakDE {
+	public:
+		CakDE(void);
+		~CakDE(void);
+		// TODO: 여기에 메서드를 추가합니다.
+
+	public:
+		/**
+		* 함수명 : getMovingPostion
+		*		현제의 좌표로부터 속도와 시간만큼 움직였을때의 좌표 도출
+		* Parameters:
+		*		double* posX	//X좌표(결과값 반환)
+		*		double* posY	//Y좌표(결과값 반환)
+		*		double* posZ	//Z좌표(결과값 반환)
+		*		double heading	//Heading(0~360)
+		*		double pitch	//Pitch(0~360)
+		*		double velocity	//속도(m/s
+		*		unsigned int Framerate	//프레임(Hz)
+		* Returns:
+		*		정상적인 계산 완료시 True 반환
+		*/
+		bool getMovingPostion(double* posX,double* posY,double* posZ,double heading,double pitch, double velocity, unsigned int Framerate);
+		bool getNextPostion(double* posX,double* posY,double* posZ,double heading,double pitch, double velocity, double Dt);
+
+		/**
+		* 함수명 : getRotatePostion
+		*		현제 좌표로부터 Heading,Pitch방향으로 정해진 값만큼 움직였을때 좌표 도출
+		* Parameters:
+		*		double* posX	//X좌표(결과값 반환)
+		*		double* posY	//Y좌표(결과값 반환)
+		*		double* posZ	//Z좌표(결과값 반환)
+		*		double heading	//Heading(0~360)
+		*		double pitch	//Pitch(0~360)
+		*		double radius	//거리
+		* Returns:
+		*		정상적인 계산 완료시 True 반환
+		*/
+		bool getRotatePostion(double* posX, double* posY, double* posZ, double heading, double pitch, double radius);
+
+		/**
+		* 함수명 : getAngle3d
+		*		두 좌표가 이루는 각을 환산
+		* Parameters:
+		*		double x1		// 첫번째 좌표
+		*		double y1		// 첫번째 좌표
+		*		double z1		// 첫번째 좌표
+		*		double x2		// 두번째 좌표
+		*		double y2		// 두번째 좌표
+		*		double z2		// 두번째 좌표
+		*		double heading	//Heading(결과값 반환)
+		*		double pitch	//Pitch(결과값 반환)
+		* Returns:
+		*/
+		void getAngle3d(double x1, double y1, double z1, double x2, double y2, double z2, double* heading, double* pitch);
+
+		/**
+		* 함수명 : AngleClosing
+		*		두 각의 간격 크기
+		* Parameters:
+		*		double center		// 중심 각
+		*		double angle		// 회전 각
+		*		int option			// 0은 무조건 가까운쪽 각 
+		* Returns:
+		*		중심각과 회전각의 간격 반환
+		*/
+		double GetAngleClosing(double center, double angle, int option = 0);
+
+		/**
+		* 함수명 : GetAngle360
+		*		각을 0~360도 환산
+		* Parameters:
+		*		double angle		// 입력 각
+		* Returns:
+		*		0~360도로 환산된 각
+		*/
+		inline double GetAngle360(double angle);
+
+		/**
+		* 함수명 : GetAngle180
+		*		각을 -180~180도 환산
+		* Parameters:
+		*		double angle		// 입력 각
+		* Returns:
+		*		-180~180도로 환산된 각
+		*/
+		static inline double GetAngle180(double angle);
+
+
+
+		static void getRoate2d(double angle, double orgx,double orgy, double* x, double* y);
+
+		double distance3d(double x1, double y1, double z1, double x2, double y2, double z2);
+
+		void rotateposition3d(double x1,double y1, double z1, double* x2, double* y2, double* z2, double h, double p);
+
+		void axisrotate(  double* nx, double* ny, double* nz, 
+			double cx, double cy, double cz,
+			double tx, double ty, double tz,
+			double heading, double pitch, double roll  );
+
+		bool missilesim(double msx, double msy, double msz, double msh, double msp, double msah, double msap, double tgx, double tgy, double tgz, double velocty, double acceleration, int FrameRate);
+
+		inline static double getHeading(double x , double y);
+		
+		inline double RadianToDegree(double radian);
+		inline double DegreeToRadian(double degree);
+		inline bool GetCheckAngleRange(double p1, double stAngle, double endAngle);
+	private:
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akDefine.h b/ReviewHistory/include/akCore/akDefine.h
new file mode 100644
index 0000000..e885285
--- /dev/null
+++ b/ReviewHistory/include/akCore/akDefine.h
@@ -0,0 +1,10 @@
+#pragma once
+
+
+
+#define AK_SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
+#define AK_SAFE_DELETE_ARRAY(p)  { if(p) { delete [] (p);     (p)=NULL; } }
+
+#define AK_SAVE_DELETE_DIALOG(Dlg) { if(p) { delete (p);     (p)=NULL; } }
+
+#define AK_SWAP_DOUBLE(a,b) { double t=a; a=b; b=t; }
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akFileDB.h b/ReviewHistory/include/akCore/akFileDB.h
new file mode 100644
index 0000000..1bef2aa
--- /dev/null
+++ b/ReviewHistory/include/akCore/akFileDB.h
@@ -0,0 +1,80 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+#include <atlstr.h>
+#include <map>
+#include <vector>
+#include <Windows.h>
+
+//hash_map을 사용하는 경우
+//1. 많은 자료를 저장하고, 검색 속도가 빨라야 한다.
+//2. 너무 빈번하게 자료를 삽입, 삭제 하지 않는다. 
+#define ITEMSEP "_#" //구분자
+
+#define mapIDVal std::map<CString, CString>
+#define mapIDValIt mapIDVal::iterator
+
+
+
+class AKCORE_DLLSPEC CakFileDB
+{
+public:
+	CakFileDB(void);
+	~CakFileDB(void);
+
+	bool openfile(char* filename);
+	bool savefile(char* filename);
+	void clear();
+
+	void setWriteEnter(); //동기화 객체 시작
+	void setWriteRelease();  //동기화 객체 중지
+
+	//단일 데이터
+	void setItem(char* strKey, char* strVal);
+	void setItem(char* strKey, int nVal);
+	void setItem(char* strKey, float fVal);
+	void setItem(char* strKey, double dVal);
+	void setItem(char* strKey, long dVal);
+
+	void getItem(char* strKey, CString* strVal, char* strDefaultVal = "");
+	void getItem(char* strKey, char* strVal, char* strDefaultVal = "");
+	void getItem(char* strKey, int* nVal, int nDefaultVal = 0);
+	void getItem(char* strKey, float* fVal, float fDefaultVal = 0);
+	void getItem(char* strKey, double* dVal, double dDefaultVal = 0);
+	void getItem(char* strKey, long* dVal, long dDefaultVal = 0);
+	
+	char* getItemPoint(char* strKey);
+
+	//다중 데이터 관리
+	void setItemClear(char* strKey);
+	int  getItemNum(char* strKey);
+
+	void setItem(int nIndex, char* strKey, char* strVal);
+	void setItem(int nIndex, char* strKey, int nVal);
+	void setItem(int nIndex, char* strKey, float fVal);
+	void setItem(int nIndex, char* strKey, double dVal);
+	
+	void getItem(int nIndex, char* strKey, CString* strVal, char* strDefaultVal = "");
+	void getItem(int nIndex, char* strKey, char* strVal, char* strDefaultVal = "");
+	void getItem(int nIndex, char* strKey, int* nVal, int nDefaultVal = 0);
+	void getItem(int nIndex, char* strKey, float* fVal, float fDefaultVal = 0);
+	void getItem(int nIndex, char* strKey, double* dVal, double dDefaultVal = 0);
+	
+	char* getItemPoint(int nIndex, char* strKey);
+
+	
+
+
+	int deleteItem(char* strKey); //
+	int deleteItem(int nIndex); //
+	 
+	
+
+protected:
+	mapIDVal m_mapData;
+	std::vector<mapIDValIt> m_vecOrder;
+
+	CRITICAL_SECTION m_csAkFileDB;
+
+};
diff --git a/ReviewHistory/include/akCore/akFileDBHash.h b/ReviewHistory/include/akCore/akFileDBHash.h
new file mode 100644
index 0000000..20a690c
--- /dev/null
+++ b/ReviewHistory/include/akCore/akFileDBHash.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+#include <map>
+#include <hash_map>
+#include <string>
+#include <Windows.h>
+#include <atlstr.h>
+
+//hash_map을 사용하는 경우
+//1. 많은 자료를 저장하고, 검색 속도가 빨라야 한다.
+//2. 너무 빈번하게 자료를 삽입, 삭제 하지 않는다. 
+//3. key값으로 Cstring을 쓰지 못한다.(구분해서 클래스를 만든 이유!!)
+#define ITEMSEP "_#" //구분자
+
+
+
+//#define mapIDVal std::multimap<CString, CString>
+#define mapHash stdext::hash_map<std::string, std::string>
+#define mapHashIt mapHash::iterator
+
+class AKCORE_DLLSPEC CakFileDBHash
+{
+public:
+	CakFileDBHash(void);
+	~CakFileDBHash(void);
+	bool openfile(char* filename);
+	bool savefile(char* filename);
+	void clear();
+
+	void setWriteEnter(); //동기화 객체 시작
+	void setWriteRelease();  //동기화 객체 중지
+
+	//단일 데이터
+	void setItem(char* strKey, char* strVal);
+	void setItem(char* strKey, int nVal);
+	void setItem(char* strKey, float fVal);
+	void setItem(char* strKey, double dVal);
+
+	void getItem(char* strKey, CString* strVal, char* strDefaultVal = "");
+	void getItem(char* strKey, char* strVal, char* strDefaultVal = "");
+	void getItem(char* strKey, int* nVal, int nDefaultVal = 0);
+	void getItem(char* strKey, float* fVal, float fDefaultVal = 0);
+	void getItem(char* strKey, double* dVal, double dDefaultVal = 0);
+
+	char* getItemPoint(char* strKey);
+
+	//다중 데이터 관리
+	void setItemClear(char* strKey);
+	int  getItemNum(char* strKey);
+
+	void setItem(int nIndex, char* strKey, char* strVal);
+	void setItem(int nIndex, char* strKey, int nVal);
+	void setItem(int nIndex, char* strKey, float fVal);
+	void setItem(int nIndex, char* strKey, double dVal);
+
+	void getItem(int nIndex, char* strKey, CString* strVal, char* strDefaultVal = "");
+	void getItem(int nIndex, char* strKey, char* strVal, char* strDefaultVal = "");
+	void getItem(int nIndex, char* strKey, int* nVal, int nDefaultVal = 0);
+	void getItem(int nIndex, char* strKey, float* fVal, float fDefaultVal = 0);
+	void getItem(int nIndex, char* strKey, double* dVal, double dDefaultVal = 0);
+
+	char* getItemPoint(int nIndex, char* strKey);
+
+
+
+protected:
+	mapHash m_mapData;
+
+	CRITICAL_SECTION m_csAkFileDB;
+};
diff --git a/ReviewHistory/include/akCore/akFileMgr.h b/ReviewHistory/include/akCore/akFileMgr.h
new file mode 100644
index 0000000..9c50e5c
--- /dev/null
+++ b/ReviewHistory/include/akCore/akFileMgr.h
@@ -0,0 +1,80 @@
+#pragma once
+
+
+
+#include "akCoreLinker.h"
+#include <vector>
+
+struct AKCORE_DLLSPEC _Attribute
+{
+	_Attribute()
+	{
+		memset(Title		, 0, sizeof(char)*128);
+		memset(Attribute	, 0, sizeof(char)*128);
+		memset(Value		, 0, sizeof(char)*128);
+	}
+	char Title[128];
+	char Attribute[128];
+	char Value[128];
+};
+
+struct AKCORE_DLLSPEC _Title
+{
+	_Title(char* title)
+	{
+		strcpy(Title, title);
+	};
+	bool compare(char* title)
+	{
+		if(strcmp(title, Title) == 0 && strlen(title) == strlen(Title))
+		{
+			return true;
+		}
+		return false;
+	};
+	void clear()
+	{
+		memset(Title, 0, sizeof(char)*128);
+	};
+	char Title[128];
+};
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakFileMgr
+	{
+	public:
+		CakFileMgr(void);
+		~CakFileMgr(void);
+
+		//타이틀 설정(OpenFile()함수와 MakeFile()함수를 호출하면 타이틀셋팅은 Null이 된다)
+		void SetTitle(char* title);
+
+		//쓰기 관련
+		//타이틀을 정한다.
+		bool SetAttribute(char* Attribute, int value);
+		bool SetAttribute(char* Attribute, double value);
+		bool SetAttribute(char* Attribute, char* value);
+		bool SetAttribute(char* Attribute, float value);
+		//쓰기 버퍼에 저장된 데이터를 파일로 저장
+		bool MakeFile(char* filepath);
+		
+
+		//읽기 관련
+		//파일 열기(쓰기준비중이였다면 쓰기 버퍼는 초기화 된다)
+		bool OpenFile(char* filepath);
+		bool GetAttribute(char* Attribute, int& value);
+		bool GetAttribute(char* Attribute, double& value);
+		bool GetAttribute(char* Attribute, char* value);
+		bool GetAttribute(char* Attribute, float& value);
+		
+	private:
+		//빠른 찾기를 위해서 저장된 데이터 정렬
+		void DataSort();
+		char m_Title[128];
+		std::vector<_Attribute> m_data;
+
+		char* m_buffer;
+		int m_fastIndex;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akFileMgrAdv.h b/ReviewHistory/include/akCore/akFileMgrAdv.h
new file mode 100644
index 0000000..a0b54bc
--- /dev/null
+++ b/ReviewHistory/include/akCore/akFileMgrAdv.h
@@ -0,0 +1,74 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+#include <vector>
+
+//파일 구조
+//float version;
+//size_t structTotalSize;//구조체 총 크기
+//size_t structNum;//구조체 갯수
+//char rev[128]; //예약된 임시공간
+//size_t nSize[] 각각의 구조체 크기
+//void* pData //실제 데이터 저장 공간
+
+namespace akCore
+{
+	struct AKCORE_DLLSPEC _akFileMgrHeader
+	{
+		float version;
+
+		size_t structTotalSize;//구조체 총 크기
+		size_t structNum;//
+		char rev[128];
+	};
+
+	class AKCORE_DLLSPEC CakFileMgrAdv
+	{
+	public:
+		CakFileMgrAdv(void);
+		~CakFileMgrAdv(void);
+
+	public:
+		//파일 쓰기
+		bool writeFile(char* pFileName, float fVer=1.0);
+
+		//파일 읽기
+		//0은 실패 1은 정상
+		//10001 읽어올 구조체 크기가 파일보다 큼(struct size > file size)
+		//10002 읽어올 구조체 크기가 파일보다 큼(struct size > file size)
+		//10003 읽어올 구조체와 파일크기가 같음. 하지만 구조체 구성이 다름(struct size == file size)
+		int readFile(char* filepath, bool bErrorCheck = false);
+
+		//데이터/크기 수정(기존의 파일정보를 읽어서 새 데이터로 수정)
+		bool editFile(char* filepath, int nIndex, void* pData, size_t nSize);
+
+
+		//데이터/크기 초기화
+		void clear();
+		//데이터/크기 추가
+		void addDataSize(void* pData, size_t nSize);
+		//데이터/크기 수정
+		void setDataSize(int nIndex, void* pData, size_t nSize);
+
+		_akFileMgrHeader getFileHeaderInfo(char* pFileName);
+		
+	
+		
+		
+	private:
+		struct _datasize
+		{
+			_datasize(void* pData1, size_t nSize1)
+			{
+				pData = pData1;
+				nSize = nSize1;
+			}
+			void* pData;
+			size_t  nSize;
+		};
+		std::vector<_datasize> m_vecData;
+
+		
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akFileMgrB.h b/ReviewHistory/include/akCore/akFileMgrB.h
new file mode 100644
index 0000000..cab9409
--- /dev/null
+++ b/ReviewHistory/include/akCore/akFileMgrB.h
@@ -0,0 +1,40 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+#include <vector>
+
+
+
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakFileMgrB
+	{
+	public:
+		CakFileMgrB(void);
+		~CakFileMgrB(void);
+
+		//쓰기 관련
+		void SetDataSize(unsigned int HeadSize, unsigned int BodySize);
+		bool SetHead(void* head);
+		bool AddBody(void* body);
+		void ClearWriteBuffer(); //쓰기할려고 저장한 데이터 모두 삭제
+
+		//읽기 관련
+		void MakeFile(char* filepath);
+		bool OpenFile(char* filepath);
+		void* GetBodyData();
+		void* GetHeadData();
+		int MoveNext();
+		void ClearReadBuffer();
+
+	private:
+		int m_headSize, m_bodySize;
+		void* m_WriteHead;
+		std::vector<void*> m_vecWriteBody;
+		int m_readindex;
+		void* m_ReadHead;
+		std::vector<void*> m_vecReadBody;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akFileUtil.h b/ReviewHistory/include/akCore/akFileUtil.h
new file mode 100644
index 0000000..810f368
--- /dev/null
+++ b/ReviewHistory/include/akCore/akFileUtil.h
@@ -0,0 +1,79 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+
+#include <vector>
+#include <io.h>
+
+
+using namespace std;
+typedef vector<_finddatai64_t> VECFINDDATA;
+
+class AKCORE_DLLSPEC CakFileUtil
+{
+public:
+	CakFileUtil(void);
+	virtual ~CakFileUtil(void);
+
+	//분석결과 초기화
+	void clear();
+
+	//파일 찾기
+	void FindFile(char* pTargetPathName, bool bFindSubDir = true);
+	//파이 이름 변경
+	void RenameFile(char* pTargetPathName, char* pNewFileName, bool bFindSubDir = true);
+	void RenameFile(char* pTargetPathName, char* pFindWord, char* pReplaceWord, bool bFindSubDir = true);
+	//파일삭제
+	void DeleteFiles( char* pTargetPathName, bool bFindSubDir /*= true*/ );
+
+	//폴더 찾기
+	void FindFolder(char* pTargetPath, bool bFindSubDir = true);
+	//폴더 이름 변경
+	void RenameFolder(char* pTargetPath, char* pNewFolderName, bool bFindSubDir = true);
+	void RenameFolder(char* pTargetPath, char* pFindWord, char* pReplaceWord, bool bFindSubDir = true);
+	//폴더 삭제
+	static	void DeleteFolder( char* pTargetPath, bool bFindSubDir /*= true*/ );
+
+	//마지막 에러 정보
+	int getLastError(){return m_nLastError;};
+
+	//분석 결과 얻기
+	VECFINDDATA* getFindData(){return &m_vecFinds;};
+	int getFindSubDirCount(){return m_nFindSubCount;};
+	VECFINDDATA* getProcessData(){return &m_vecProcess;};
+	_finddatai64_t* getFindData(char* pName);
+	char* getProcessPath(){return m_nProcessPath;};
+
+	//폴더간 복사 태현[2016/4/5]
+	static int CopyFolder(char* strSrc, char* strDest, bool bSubDir = true);
+	static int MoveFolder(char* strSrc, char* strDest, bool bSubDir = true);
+
+	static void MakeDirectory(char* pPath);
+
+	//일반기능함수
+	static char* getFileName(char* pPathFileName);
+	static char* getFileExt(char* pPathFileName);
+	static void getPath(char* strDest, int nDestSize, const char* strSource);
+	static int getLastPath(char* strDest, int nDestSize, char* strSource);
+	static char* getLastPath(char* pPath);
+
+
+	//경로정리 변경(ex. ./aaa/bb/./bbb/../ -> ./aaa/bb/)
+	static void changeAbsolutePath(char* pPathFileName);
+
+	static int isNetworkPath(char* pPath);//네티워크 경로가 맞다면 끝부분 경로를 반환한다. 태현[2016/4/8]
+protected:
+	void FindFileSubDir(char* pTargetPath, char* pWildcard);
+	//void DeleteFolderSubDir(char* pTargetPath);
+	void makeAbPathWildcard(char* pTargetPath, char* pNewPath, int nNewPathSize, char* pWildcard, int nWildcardSize); //절대 경로 생성과 와일드 카드를 분리 하는 역할
+	void FindFolderSubDir(const char* pTargetPath, const char* pWildcard);
+	void makeAbPathWildcardFolder(char* pTargetPath, char* pNewPath, int nNewPathSize, char* pWildcard, int nWildcardSize); //절대 경로 생성과 와일드 카드를 분리 하는 역할(폴더로 구성되었을 경우)
+
+protected:
+	char m_nProcessPath[512];
+	VECFINDDATA m_vecFinds;
+	VECFINDDATA m_vecProcess;
+	int m_nLastError;
+	int m_nFindSubCount;
+};
diff --git a/ReviewHistory/include/akCore/akInterpolation.h b/ReviewHistory/include/akCore/akInterpolation.h
new file mode 100644
index 0000000..07c2a08
--- /dev/null
+++ b/ReviewHistory/include/akCore/akInterpolation.h
@@ -0,0 +1,48 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+#include <vector>
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakInterpolation
+	{
+	public:
+		struct _Data
+		{
+			_Data()
+			{
+				x = y = 0;
+			}
+			double x;
+			double y;
+		};
+
+	public:
+		CakInterpolation();
+		~CakInterpolation();
+
+		//폴리노미얼 데이터 생성(rate:데이터 간격)
+		void CaculationPolinomial(double min, double max, double rate);
+		//큐빅스플라인 데이터 생성(rate:점과 점사이의 데이터 갯수)
+		void CaculationCubicSpline(double rate);
+		//Linear(rate:점과 점사이의 데이터 갯수)
+		void CaculationLinear(int step);
+
+		void AddPoint(double x, double y);
+		inline void ClearPoint(){m_vecInterPoint.clear();};
+		
+		inline _Data GetData(int index);
+		inline int GetDataNum(){return (int)m_vecInterPoint.size();};
+
+		
+		
+		
+	protected:
+		std::vector<_Data> m_vecOrgPoint;
+		std::vector<_Data> m_vecInterPoint;
+	private:
+		void solveTridiag(double* khb, double* diag, double* khp, double* b, int n)	;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akLogger.h b/ReviewHistory/include/akCore/akLogger.h
new file mode 100644
index 0000000..7a4e5f8
--- /dev/null
+++ b/ReviewHistory/include/akCore/akLogger.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#include "akCoreLinker.h"
+#include <queue>
+#include <windows.h>
+#include "akSTL/akQueueCircle.h"
+
+class AKCORE_DLLSPEC CakLogger
+{
+public:
+	CakLogger(int nBufferSize = 200, int nStringLen = 512 );
+	virtual ~CakLogger(void);
+
+	struct _LoggerData 
+	{
+		unsigned int nIndex;
+		char nLevel;
+		char nSection;
+		//char strDate[16];
+		//char strTime[16];
+		SYSTEMTIME stTime;
+		char* pData;
+	};
+
+	//pFileName을 C:\AOIServer\Log\AOILog <- 여기 까지 기입, 그러면 뒤에 날자 붙이고 .log붙여서 파일명 완성 [김태현 2018/11/19]
+	virtual void setWriteFileMode(char* pFileName, int nIntervalWrite = 500);
+	//dit 로그 모드
+	virtual void setWriteFileMode2(char* pPathName, char* pFileName, int nIntervalWrite = 500);
+
+	//TRACE
+	virtual void setLog(char* format, ...);
+	virtual void getDateTime(char* pStrDate, char* pStrTime);
+	
+	virtual void setLogDataToFile(FILE* pf, _LoggerData* pData); //함수 호출전에 동기화 해야함. [김태현 2018/11/19]
+
+	void resetLogCount(BOOL bWaitWrite = TRUE);
+
+	_LoggerData* GetLogData(int nIdx); //가장 나중에 쓴 로그가 0번 [김태현 2018/11/19]
+	int GetLogDataNum(){return m_nLogCount<m_nLogBufferSize?m_nLogCount:m_nLogBufferSize;}; //가장 최근이 0 [김태현 2018/11/19]
+
+public:
+	int getBufferSize(){return m_nLogBufferSize;};
+	int getLogStringLen(){return m_nLogStringLen;};
+
+protected:
+	static void threadLogFileSave(void* pArg);
+	virtual void funcLogFileSave();
+	int m_nThreadFlag;
+	int m_nFileSaveIndex;
+
+protected:
+	int m_nLogBufferSize;
+	int m_nLogStringLen;
+	_LoggerData* m_pLogData;
+	
+	unsigned long m_nLogCount;
+	int m_nLogInputIndex; // [김태현 2018/11/19]
+	int m_nLogWriteIndex;
+
+
+	int m_nLogFileType; //0은 기존 모드, 1은 날자가 앞에 있는 모드
+	char m_strLogPathName[256];
+	char m_strLogFileName[256];
+	int m_nLogFileWriteInterval;
+
+
+	CRITICAL_SECTION	m_csTrace;
+	
+};
diff --git a/ReviewHistory/include/akCore/akMath.h b/ReviewHistory/include/akCore/akMath.h
new file mode 100644
index 0000000..886716a
--- /dev/null
+++ b/ReviewHistory/include/akCore/akMath.h
@@ -0,0 +1,37 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+#include "akStruct.h"
+
+
+namespace akCore
+{
+
+	class AKCORE_DLLSPEC CakMath
+	{
+	public:
+		CakMath(void);
+		~CakMath(void);
+
+	public:
+		//세점이 이루는 각도를 산출
+		double GetAngle3Point(double cX, double cY, double x1, double y1, double x2, double y2 );
+		//평면 폴리곤위에 점이 존재 하는지 검사
+		bool GetIsPointOnPolygon(akVector2d point, akVector2d* polygon, int length); 
+		//한 선위에 점이 있는지 검사
+		bool GetLineOnPoint(akVector3d point, akVector3d line1, akVector3d line2);
+		//2d 회전 좌표(중심점에서 
+		akVector2d GetRotatePosition(akVector2d center, akVector2d point1, double angle);
+
+		//두선의 교차점 구하기(교차점이 있으면 true 반환)
+		bool GetIntersectPoint(akVector2d a1, akVector2d a2, akVector2d b1, akVector2d b2, akVector2d* IP);
+
+		//사각형과 직선 교차점 구하기(교차점이 있으면 true 반환)
+		//bool GetIntersectRectLine(CakRectd rectSqure, CakPointd p1, CakPointd p2, CakPointd* pResult, int* pResultFaceID);
+		//사각형과 폴리곤의 교차점 구하기(교차점이 있으면 true 반환)
+		//bool GetIntersectRectPolygon(CakRectd rectSqure, CakPointd* pPolygon, int nPolygonNum, CakPointd* pResult, int* pResultNum);
+
+	};
+
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akMatrix.h b/ReviewHistory/include/akCore/akMatrix.h
new file mode 100644
index 0000000..460f543
--- /dev/null
+++ b/ReviewHistory/include/akCore/akMatrix.h
@@ -0,0 +1,36 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakMatrix4x4
+	{
+	public:
+		CakMatrix4x4(void);
+		~CakMatrix4x4(void);
+
+		inline bool MatrixClear();	//매트릭스 리셋
+		inline bool SetMatrix(double *matrix);	//매트릭스 세팅
+		inline bool SetRotateH(double H);	//회전 매트리릭스 곱셈
+		inline bool SetRotateP(double P);	//회전 매트리릭스 곱셈
+		inline bool SetRotateR(double R);	//회전 매트리릭스 곱셈
+		inline bool SetTransform(double x, double y, double z);	//이동 매트리릭스 곱셈
+		inline bool MakeResult(double* x, double* y, double* z);//매트릭스 적용 좌표값 산출
+		inline bool MakeResult(float* x, float* y, float* z);//매트릭스 적용 좌표값 산출
+		inline void MatrixPrint();	//현재 매트릭스 출력
+		inline CakMatrix4x4& operator=(const CakMatrix4x4& matrix);
+		inline CakMatrix4x4& operator*(const CakMatrix4x4& matrix);
+	protected:
+		inline bool Multiplication(double* matrix);	//현재 매트릭스에 입력값 곱셈
+
+	public:
+		double m_Matrix[16];
+
+		
+	private:
+		bool m_bSet;	//초기화가 되어있는지 확인
+
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akPathFileUtil.h b/ReviewHistory/include/akCore/akPathFileUtil.h
new file mode 100644
index 0000000..3f137c9
--- /dev/null
+++ b/ReviewHistory/include/akCore/akPathFileUtil.h
@@ -0,0 +1,24 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+//akAdvBackup에 if(PathFileExists(strFilePathName.GetBuffer()))등의 내용을 참고할것!! 태현[2016/2/17]
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC akPathFileUtil
+	{
+	public:
+		akPathFileUtil(void);
+		~akPathFileUtil(void);
+
+		static bool CopytoFile(char* srcfilename, char* cpyfilename);
+		//상대경로가 '/', '\\'로 시작하면 안됨(나중에 수정하도록 하자..API문제인듯)
+		static bool CopytoFolder(char* srcfilename, char* cpyFolder); 
+
+		//상대경로가 '/', '\\'로 시작하면 안됨, 와일드 카드 사용가능
+		static bool RemoveFile(char* filename);
+
+		static void CreateFolder(char* pFullPath); //상대경로는 안됨 태현[2016/2/15]
+	};
+}
diff --git a/ReviewHistory/include/akCore/akRandom.h b/ReviewHistory/include/akCore/akRandom.h
new file mode 100644
index 0000000..d4e42ee
--- /dev/null
+++ b/ReviewHistory/include/akCore/akRandom.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+namespace akCore
+{
+//#define GetRandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
+
+	class AKCORE_DLLSPEC CakRandom
+	{
+	public:
+		CakRandom(void);
+		~CakRandom(void);
+
+		//정규분포, Normal, 가우시안... (다 같은말)
+		double Gaussian(float stddev, float mean); //stddev:평균, mean:표준편차
+
+		static int GetRandom(int min, int max);
+		
+	private:
+		static int ms_randomseed;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akString.h b/ReviewHistory/include/akCore/akString.h
new file mode 100644
index 0000000..0415b25
--- /dev/null
+++ b/ReviewHistory/include/akCore/akString.h
@@ -0,0 +1,143 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+
+#include <iostream>
+#include <tchar.h>
+
+
+extern AKCORE_DLLSPEC wchar_t* m_pWstrTemp;
+AKCORE_DLLSPEC wchar_t* charToWchar(char* pstrSrc);
+
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakString
+	{
+	public:
+		CakString(void);
+		~CakString(void);
+
+	public:
+		//wstring ToWString(const char * in_val);
+		//string ToString(const wstring &in_val);
+
+		
+
+		//찾고자하는 문자의 위치를 반환해주는 함수(-1이 반환되면 찾지 못한것임, 찾았으면 1이상의 값을 반환)
+		static int StringFind(const char* str, const char* keyward);
+		
+
+		static inline std::wstring ToWString(const char * in_val)
+		{
+			std::wstring temp;
+			while (*in_val != '\0')
+				temp += *in_val++;
+			return temp;
+		}
+
+		static inline std::string ToString(const std::wstring &in_val)
+		{
+			std::string temp;
+			std::wstring::const_iterator b = in_val.begin();
+			const std::wstring::const_iterator e = in_val.end();
+			while (b != e)
+			{
+				temp += static_cast<char>(*b);
+				++b;
+			}
+			return temp;
+		}
+
+		static bool IsNumber(char* strSource);
+		static void StringReplace(char* strSource, char cSourceChar, char cDestChar);
+		static void StringReplace(char* strSource, char* strSourceString, char* strDestString);
+		static bool GetFullPathName(char* strDest, int nDestSize, const char* strSourceFront, const char* strSourceEnd);
+		static void GetPath(char* strDest, int nDestSize, const char* strSource);
+		static void GetName(char* strDest, int nDestSize, const char* strSource);
+		static bool GetExt(char* strDest, int nDestSize, const char* strSource);
+		static char* GetExt(const char* strSource);
+		static int Find(const char* strSource, char cChar);
+		static int Find(const char* strSource, char* strFindString);
+		static int ReverseFind(const char* strSource, char cChar);
+		static void MakeLower(char* strSource);
+		static void MakeUpper(char* strSource);
+		static bool Left(const char* strSource, char* strDest, int nDestLength, int nLeftCount);
+		static bool Mid(const char* strSource, char* strDest, int nDestLength, int nFirstIndex, int nCount = -1);
+		static bool Right(const char* strSource, char* strDest, int nDestLength, int nRightCount);
+		
+
+
+	private:
+		
+	};
+}
+
+
+//
+//void CksgFontMaker::DrawStringOverray(
+//									  GLfloat x, 
+//									  GLfloat y,  
+//									  int windowWidth,
+//									  int windowHeight,
+//									  char* s
+//									  ,...)
+//{
+//	// Draws the given text string at the given location.
+//
+//	char text[256]={};
+//	va_list ap;
+//	va_start(ap, s);
+//	vsprintf(text, s, ap);
+//	va_end(ap);
+//
+//	GLsizei len = GLsizei(strlen(text));
+//	if (text && len > 0) 
+//	{
+//		glPushMatrix();
+//		{
+//			glPushAttrib( GL_LIGHTING_BIT );
+//			glDisable(GL_LIGHTING);
+//			glMatrixMode(GL_PROJECTION);
+//			glPushMatrix();
+//			{
+//				glLoadIdentity();
+//				gluOrtho2D(0, windowWidth, 0,windowHeight);
+//
+//				glMatrixMode(GL_MODELVIEW);
+//
+//				glPushMatrix();
+//				{
+//					glLoadIdentity();
+//
+//
+//
+//
+//					glRasterPos2i(x, windowHeight+m_logfont.lfHeight-y);
+//
+//					glPushAttrib(GL_LIST_BIT);
+//					{
+//						glListBase(m_fontListBase);
+//						glCallLists(len, GL_UNSIGNED_BYTE, (const GLvoid*)text);
+//					} glPopAttrib();
+//
+//
+//				}glPopMatrix();
+//
+//				glMatrixMode(GL_PROJECTION);
+//
+//			}glPopMatrix();
+//
+//			glMatrixMode(GL_MODELVIEW);
+//
+//
+//			glPopAttrib();
+//			//glEnable(GL_DEPTH_TEST);
+//
+//		}glPopMatrix();
+//
+//
+//
+//	}
+//}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akStruct.h b/ReviewHistory/include/akCore/akStruct.h
new file mode 100644
index 0000000..df2eee0
--- /dev/null
+++ b/ReviewHistory/include/akCore/akStruct.h
@@ -0,0 +1,134 @@
+#pragma once
+
+#include "akCoreLinker.h"
+#include "akStructPoint.h"
+#include "akStructVector.h"
+//#include "akStructRect.h"
+//#include "akStructColor.h"
+
+
+
+//#define _USE_MATH_DEFINES
+//#include <math.h>
+//
+//namespace akCore
+//{
+//	struct AKCORE_DLLSPEC khVector3d
+//	{
+//		double pos[3];
+//
+//		khVector3d();
+//		khVector3d(double x,double y, double z);
+//		inline void set(double x,double y, double z);
+//		inline double x(){return pos[0];};
+//		inline double y(){return pos[1];};
+//		inline double z(){return pos[2];};
+//
+//		double& operator()(int index){return pos[index];};
+//
+//		inline khVector3d operator+(const khVector3d& vec3d);
+//		inline khVector3d operator-(const khVector3d& vec3d);
+//		inline khVector3d& operator=(const khVector3d& vec3d);
+//		inline khVector3d& operator+=(const khVector3d& vec3d);
+//		inline khVector3d& operator-=(const khVector3d& vec3d);
+//		khVector3d operator*(float& a)
+//		{
+//			khVector3d returnval;
+//
+//			returnval.pos[0] = pos[0] * a;
+//			returnval.pos[1] = pos[1] * a;
+//			returnval.pos[2] = pos[2] * a;
+//
+//			return returnval;
+//		};
+//
+//		khVector3d operator *(khVector3d &vec)
+//		{
+//			khVector3d vc;
+//			vc.pos[0] = pos[1]*vec.pos[2] - pos[2]*vec.pos[1];
+//			vc.pos[1] = pos[2]*vec.pos[0] - pos[0]*vec.pos[2];
+//			vc.pos[2] = pos[0]*vec.pos[1] - pos[1]*vec.pos[0];
+//			return vc;
+//		}
+//
+//		float Dot(khVector3d vec)
+//		{
+//			return (float)(vec.pos[0] * pos[0] + vec.pos[1] * pos[1] + vec.pos[2] * pos[2]);
+//		};
+//		float Mag()
+//		{
+//			return (float)sqrt(pos[0]*pos[0]+pos[1]*pos[1]);
+//		};
+//		void Normalize()
+//		{
+//			float length;
+//
+//			//벡터의 길이를 계산한다.
+//			length = (float)sqrt((pos[0]*pos[0]) + (pos[1]*pos[1]) +(pos[2]*pos[2]));
+//			// 길이가 0에 가까운 벡터에게 절절한 값을 항당하여 프로그램이 폭주하지 않도록 한다.
+//			if(length == 0.0f) length = 1.0f;
+//
+//			// 각 성분을 벡터의 길이로 나누면 단위 벡터가 된다.
+//			pos[0] = pos[0] / length;
+//			pos[1] = pos[1] / length;
+//			pos[2] = pos[2] / length;
+//
+//		};
+//	};
+//
+//	struct AKCORE_DLLSPEC khVector2d
+//	{
+//		double pos[2];
+//
+//		khVector2d();
+//		khVector2d(double x,double y);
+//		inline void set(double x,double y);
+//		inline double x(){return pos[0];};
+//		inline double y(){return pos[1];};
+//
+//		double& operator()(int index){return pos[index];};
+//
+//		inline khVector2d operator+(const khVector2d& vec3d);
+//		inline khVector2d operator-(const khVector2d& vec3d);
+//		inline khVector2d& operator=(const khVector2d& vec3d);
+//		inline khVector2d& operator+=(const khVector2d& vec3d);
+//		inline khVector2d& operator-=(const khVector2d& vec3d);
+//		
+//	};
+//
+//	struct AKCORE_DLLSPEC khColor4f
+//	{
+//		float color[4];
+//
+//		khColor4f();
+//		khColor4f(float R, float G, float B, float A=0.0f);
+//		void set(float R, float G, float B, float A=0.0f);
+//		inline float R(){return color[0];};
+//		inline float G(){return color[1];};
+//		inline float B(){return color[2];};
+//		inline float A(){return color[3];};
+//		inline khColor4f& operator=(const khColor4f& ksgcolor);
+//	};
+//
+//	struct AKCORE_DLLSPEC khRect
+//	{
+//		double pos[4];
+//
+//		khRect();
+//		khRect(double left, double top, double right, double bottom);
+//		void set(double left, double top, double right, double bottom);
+//		inline khRect& operator=(const khRect& rect);
+//		inline double Left(){return pos[0];};
+//		inline double Top(){return pos[1];};
+//		inline double Right(){return pos[2];};
+//		inline double Bottom(){return pos[3];};
+//		inline double Width(){return pos[2]-pos[0];};
+//		inline double Height(){return pos[3]-pos[1];};
+//		inline void SetAlign(); //작은값이 왼쪽, 위, 큰값이 오른쪽 아래로 가게 한다.
+//		inline bool CheckAreaIn(double x, double y); //사각형 영역에 x,y포인트가 있는지 검사
+//		inline bool CheckWidthIn(double p1); //x포인트 가운데 점이 있는지 검사
+//		inline bool CheCakeightIn(double p1); //y포인트 가운데 점이 있는지 검사
+//
+//
+//	};
+//};
diff --git a/ReviewHistory/include/akCore/akStructColor.h b/ReviewHistory/include/akCore/akStructColor.h
new file mode 100644
index 0000000..c892c17
--- /dev/null
+++ b/ReviewHistory/include/akCore/akStructColor.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC khColor4f
+	{
+	public:
+		khColor4f(void);
+		khColor4f(float R, float G, float B, float A=0.0f);
+		~khColor4f(void);
+
+
+		void set(float R, float G, float B, float A=0.0f);
+		inline khColor4f& operator=(const khColor4f& ksgcolor);
+
+	public:
+		float r,g,b,a;
+	};
+
+};
diff --git a/ReviewHistory/include/akCore/akStructPoint.h b/ReviewHistory/include/akCore/akStructPoint.h
new file mode 100644
index 0000000..e02888c
--- /dev/null
+++ b/ReviewHistory/include/akCore/akStructPoint.h
@@ -0,0 +1,51 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+
+namespace akCore
+{
+
+	class AKCORE_DLLSPEC khPoint
+	{
+	public:
+		khPoint(void)
+		{
+			X = Y = 0;
+		};
+
+		khPoint(const khPoint &point)
+		{
+			X = point.X;
+			Y = point.Y;
+		};
+		khPoint(int x,	int y)
+		{
+			X = x;
+			Y = y;
+		};
+
+		khPoint operator+(const khPoint& point) const
+		{
+			return khPoint(X + point.X,
+				Y + point.Y);
+		};
+
+		khPoint operator-(const khPoint& point) const
+		{
+			return khPoint(X - point.X,
+				Y - point.Y);
+		};
+
+		bool Equals(const khPoint& point)
+		{
+			return (X == point.X) && (Y == point.Y);
+		};
+
+	public:
+
+		long X;
+		long Y;
+	};
+
+};
diff --git a/ReviewHistory/include/akCore/akStructRect.h b/ReviewHistory/include/akCore/akStructRect.h
new file mode 100644
index 0000000..c8221eb
--- /dev/null
+++ b/ReviewHistory/include/akCore/akStructRect.h
@@ -0,0 +1,59 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC khRect
+	{
+	public:
+		khRect(void);
+		khRect(int l, int t, int r, int b);
+		virtual ~khRect(void);
+
+
+
+		void set(int l, int t, int r, int b);
+		khRect& operator=(const khRect& rect);
+		inline int getWidth(){return right-left;};
+		inline int getHeight(){return bottom-top;};
+		inline int getCenter(){return int(left+(right-left)/2.0);};
+		inline int getVCenter(){return int(top+(bottom-top)/2.0);};
+		void setAlign(); //작은값이 왼쪽, 위, 큰값이 오른쪽 아래로 가게 한다.
+		bool getCheckAreaIn(double x, double y); //사각형 영역에 x,y포인트가 있는지 검사
+		bool getCheckWidthIn(double p1); //x포인트 가운데 점이 있는지 검사
+		bool getCheCakeightIn(double p1); //y포인트 가운데 점이 있는지 검사
+
+
+	public:
+		int left, top, right, bottom;
+	};
+
+
+	class AKCORE_DLLSPEC khRect4d
+	{
+	public:
+		khRect4d(void);
+		khRect4d(double l, double t, double r, double b);
+		virtual ~khRect4d(void);
+
+
+
+		void set(double l, double t, double r, double b);
+		khRect4d& operator=(const khRect4d& rect);
+		inline double getWidth(){return right-left;};
+		inline double getHeight(){return bottom-top;};
+		inline double getCenter(){return left+(right-left)/2.0;};
+		inline double getVCenter(){return top+(bottom-top)/2.0;};
+		void setAlign(); //작은값이 왼쪽, 위, 큰값이 오른쪽 아래로 가게 한다.
+		bool getCheckAreaIn(double x, double y); //사각형 영역에 x,y포인트가 있는지 검사
+		bool getCheckWidthIn(double p1); //x포인트 가운데 점이 있는지 검사
+		bool getCheCakeightIn(double p1); //y포인트 가운데 점이 있는지 검사
+
+	public:
+		double left, top, right, bottom;
+	};
+
+
+};
diff --git a/ReviewHistory/include/akCore/akStructVector.h b/ReviewHistory/include/akCore/akStructVector.h
new file mode 100644
index 0000000..d769997
--- /dev/null
+++ b/ReviewHistory/include/akCore/akStructVector.h
@@ -0,0 +1,165 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+
+
+
+#define KHVECTOR_HEADER(akVector3d, double)									\
+class AKCORE_DLLSPEC akVector3d											\
+	{																		\
+	public:																	\
+																			\
+		akVector3d();														\
+		akVector3d(double px,double py, double pz);							\
+		inline void set(double px,double py, double pz);					\
+																			\
+		inline akVector3d operator+(const akVector3d& vec3d);				\
+		inline akVector3d operator-(const akVector3d& vec3d);				\
+		inline akVector3d& operator=(const akVector3d& vec3d);				\
+		inline akVector3d& operator+=(const akVector3d& vec3d);				\
+		inline akVector3d& operator-=(const akVector3d& vec3d);				\
+		akVector3d operator*(float& a)										\
+		{																	\
+			akVector3d returnval;											\
+																			\
+			returnval.x = x * a;											\
+			returnval.y = y * a;											\
+			returnval.z = z * a;											\
+																			\
+			return returnval;												\
+		};																	\
+																			\
+		akVector3d operator *(akVector3d &vec)								\
+		{																	\
+			akVector3d vc;													\
+			vc.x = y*vec.z - z*vec.y;										\
+			vc.y = z*vec.x - x*vec.z;										\
+			vc.z = x*vec.y - y*vec.x;										\
+			return vc;														\
+		}																	\
+																			\
+		double Dot(akVector3d vec)											\
+		{																	\
+			return (vec.x * x + vec.y * y + vec.z * z);						\
+		};																	\
+		double Mag()														\
+		{																	\
+			return sqrt(x*x+y*y);											\
+		};																	\
+		double getLength()													\
+		{																	\
+			return sqrt(x*x+y*y+z*z);										\
+		};																	\
+		void Normalize()													\
+		{																	\
+			double length;													\
+																			\
+			length = sqrt((x*x) + (y*y) +(z*z));							\
+			if(length == 0.0f) length = 1.0f;								\
+																			\
+			x = x / length;													\
+			y = y / length;													\
+			z = z / length;													\
+																			\
+		};																	\
+	public:																	\
+		double x,y,z;														\
+	};																		
+																			
+																			
+namespace akCore															
+{
+	class AKCORE_DLLSPEC akVector3d
+	{
+	public:
+
+		akVector3d();
+		akVector3d(double px,double py, double pz);
+		inline void set(double px,double py, double pz);
+		
+		inline akVector3d operator+(const akVector3d& vec3d);
+		inline akVector3d operator-(const akVector3d& vec3d);
+		inline akVector3d& operator=(const akVector3d& vec3d);
+		inline akVector3d& operator+=(const akVector3d& vec3d);
+		inline akVector3d& operator-=(const akVector3d& vec3d);
+		akVector3d operator*(float& a)
+		{
+			akVector3d returnval;
+
+			returnval.x = x * a;
+			returnval.y = y * a;
+			returnval.z = z * a;
+
+			return returnval;
+		};
+
+		akVector3d operator *(akVector3d &vec)
+		{
+			akVector3d vc;
+			vc.x = y*vec.z - z*vec.y;
+			vc.y = z*vec.x - x*vec.z;
+			vc.z = x*vec.y - y*vec.x;
+			return vc;
+		}
+
+		//내적
+		double Dot(akVector3d vec)
+		{
+			return (vec.x * x + vec.y * y + vec.z * z);
+		};
+		double Mag()
+		{
+			return sqrt(x*x+y*y);
+		};
+		double getLength()
+		{
+			return sqrt(x*x+y*y+z*z);
+		};
+		void Normalize()
+		{
+			double length;
+
+			//벡터의 길이를 계산한다.
+			length = sqrt((x*x) + (y*y) +(z*z));
+			// 길이가 0에 가까운 벡터에게 절절한 값을 항당하여 프로그램이 폭주하지 않도록 한다.
+			if(length == 0.0f) length = 1.0f;
+
+			// 각 성분을 벡터의 길이로 나누면 단위 벡터가 된다.
+			x = x / length;
+			y = y / length;
+			z = z / length;
+
+		};
+	public:
+		double x,y,z;
+	};
+
+	//////////////////////////////////////////////////////////////////////////
+	// khVector3f
+	KHVECTOR_HEADER(khVector3f, float)
+
+	//////////////////////////////////////////////////////////////////////////
+	//////////////////////////////////////////////////////////////////////////
+	class AKCORE_DLLSPEC akVector2d
+	{
+	public:
+		akVector2d();
+		akVector2d(double px,double py);
+		inline void set(double px,double py);
+
+
+		
+
+		inline akVector2d operator+(const akVector2d& vec3d);
+		inline akVector2d operator-(const akVector2d& vec3d);
+		inline akVector2d& operator=(const akVector2d& vec3d);
+		inline akVector2d& operator+=(const akVector2d& vec3d);
+		inline akVector2d& operator-=(const akVector2d& vec3d);
+	public:
+		double x,y,z;
+	};
+};
diff --git a/ReviewHistory/include/akCore/akSyncObject.h b/ReviewHistory/include/akCore/akSyncObject.h
new file mode 100644
index 0000000..9d9d73d
--- /dev/null
+++ b/ReviewHistory/include/akCore/akSyncObject.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakSyncObject
+	{
+	public:
+		CakSyncObject(void);
+		virtual ~CakSyncObject(void);
+
+	public:
+		//읽기 지정을 하였을때... 이미 어디서 쓰고 있다면.. 기다렸다가 다음을 수행한다.
+		//bWait = false 일경우.. 어딘가에서 쓰고 있다면 false를 반환하고 끝내버린다.
+		bool SetRead(bool bWait = true);  
+		//쓰기 지정을 하였을때... 이미 어디서 읽고 있다면.. 기다렸다가 다음을 수행한다.
+		bool SetWrite(bool bWait = true);
+		int SetReadRelease(); //현재 남아있는 읽기 카운트 반환
+		void SetWriteRelease();
+
+		int GetReadCount(){return m_nReadCount;}; //읽기 호출한 횟수 반환
+		bool GetWriteState(){return m_bWrite;}; //0이 될때까지 그리는 루틴은 무한 루프가 돈다.
+		
+
+	protected:
+		
+	private:
+		bool m_bWrite; 
+		int m_nReadCount;
+		
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akText.h b/ReviewHistory/include/akCore/akText.h
new file mode 100644
index 0000000..b9cacfa
--- /dev/null
+++ b/ReviewHistory/include/akCore/akText.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+class AKCORE_DLLSPEC CakText
+{
+public:
+	CakText(void);
+	virtual ~CakText(void);
+	
+	//////////////////////////////////////////////////////////////////////////
+	//시간 반환 함수
+	char* getTime();
+	char* getTime(char* pSeparator);
+	char* getTime(char* pSeparator1, char* pSeparator2, char* pSeparator3);
+
+	//////////////////////////////////////////////////////////////////////////
+	//날자 반환 함수
+	char* getDate();
+	char* getDate(char* pSeparator);
+	char* getDate(char* pSeparator1, char* pSeparator2, char* pSeparator3);
+	
+	//////////////////////////////////////////////////////////////////////////
+	//시스템 정보 반환
+	char* getModuleFileName(); //실행되는 파일 이름 반환
+	char* getCurrentDirectory(); //현재 작업 폴더 반환
+
+	char* getFormat(char* format, ...);
+	//////////////////////////////////////////////////////////////////////////
+	//버퍼 관리 함수
+	//내부적으로 많은 양의 크기를 요구하는 문자열의 경우
+	//자동으로 크기를 재 할당하므로 별도의 버퍼크기를 조절 하지 않아도 괜찮아요~
+public:
+	char* getBuffer(int index){return m_pBuffer[index];};
+	int getBufferSize(int index){return m_pBufferSize[index];};
+	int getBufferNum(){return m_nBufferNum;};
+	void setBufferSize(int nNum);
+public:
+	char* getBufferNew(int nSize);
+
+private:
+	char** m_pBuffer; //m_nBufferNum*m_nBuffersize
+	int* m_pBufferSize; //
+	int m_nBufferNum; //기본 버퍼갯수8개
+	int m_nBufferCurIndex;
+};
+
+
diff --git a/ReviewHistory/include/akCore/akTextExt.h b/ReviewHistory/include/akCore/akTextExt.h
new file mode 100644
index 0000000..92099f4
--- /dev/null
+++ b/ReviewHistory/include/akCore/akTextExt.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "akText.h"
+
+//응용1
+#define AKTEXT CakTextExt::getInstance()
+class AKCORE_DLLSPEC CakTextExt : public CakText
+{
+public:
+	CakTextExt(void){};
+	virtual ~CakTextExt(void){};
+
+	static CakText* getInstance(){return &m_akText;};
+private:
+	static CakText m_akText;
+};
diff --git a/ReviewHistory/include/akCore/akTimeManager.h b/ReviewHistory/include/akCore/akTimeManager.h
new file mode 100644
index 0000000..d007cc4
--- /dev/null
+++ b/ReviewHistory/include/akCore/akTimeManager.h
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "akCoreLinker.h"
+#include <Windows.h>
+
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakTimeManager
+	{
+	public:
+		enum PlayMode
+		{
+			Play,
+			Stop,
+			Pause,
+			Playing,
+			PlayEnd,
+			SettingTime
+		};
+	public:
+		CakTimeManager(void);
+		virtual ~CakTimeManager(void);
+
+		//시작 중지(구버전) //배속 적용 안받음
+		inline void SetBegin();
+		inline void SetEnd();
+		inline double GetRunTimeSec(); //시작시간 저장하고 종료시간까지의 타임(초단위)
+		inline double GetRunTimeMsec(); //시작시간 저장하고 종료시간까지의 타임(초단위)
+		inline double GetFrameRate();
+
+		//플레이바 기능(신버전)
+		void SetInit();//초기 설정으로 되돌림
+		virtual inline void SetPlay();
+		virtual inline void SetStop();
+		virtual inline void SetTime(int msec);
+		virtual inline void SetPause();
+		
+		
+		virtual inline double GetTime(int type=0); //0=Sec, 1=MSec
+		virtual inline void GetTime(int* h, int* m, int* s, int* ms);
+		virtual inline PlayMode GetPlayMode();
+		virtual inline void SetSpeedRate(double speedrate); //배속 설정(0보다 큰 실수 입력가능)
+		virtual inline double GetSpeedRate(); //배속 설정값 읽기
+
+	protected:
+		LARGE_INTEGER m_Frequency;
+		LARGE_INTEGER m_BeginTime;
+		LARGE_INTEGER m_Endtime;
+
+		double m_PauseTime;
+		double m_LastTime;
+		PlayMode m_PlayState;
+		double m_SpeedRate; //배속
+
+		//콜백 데이터 관리
+	public:
+		typedef void (*MsgCallbackFunc) (int msg, void*);
+		void setMsgCallbackFunc(MsgCallbackFunc userFunc, void* data = NULL)
+		{
+			m_msgCallbackFunc = userFunc;
+			m_MsgCallbackFuncData = data;
+		};
+	protected:
+		void* m_MsgCallbackFuncData;
+		MsgCallbackFunc m_msgCallbackFunc;
+		int m_nSyncObject;
+	};
+
+	class AKCORE_DLLSPEC CakTimeManagerAdv : public CakTimeManager
+	{
+	public:
+		CakTimeManagerAdv(void);
+		virtual ~CakTimeManagerAdv(void);
+
+	public:
+		virtual inline void SetPlay();
+		virtual inline void SetTime(int msec);
+		virtual inline void SetStop();
+	protected:
+		void setEnd();//플레이 시간이 최대 시간을 넘었을 경우 호출
+	public:
+		double m_timeMax;
+
+	public:
+		static void threadPlayer(void* arg);
+		int m_flagThreadPlayer;
+
+	private:
+		bool m_bPlaying;
+		
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akTrace.h b/ReviewHistory/include/akCore/akTrace.h
new file mode 100644
index 0000000..9c1a5c4
--- /dev/null
+++ b/ReviewHistory/include/akCore/akTrace.h
@@ -0,0 +1,66 @@
+#pragma once
+
+
+
+
+#include "akCoreLinker.h"
+#include <queue>
+#include <windows.h>
+#include "akSTL/akQueueCircle.h"
+
+class AKCORE_DLLSPEC CakTrace
+{
+public:
+	CakTrace(void);
+	virtual ~CakTrace(void);
+
+	enum Mode
+	{
+		TM_MEMORY = 0,
+		TM_FILE,
+		TM_BOTHMEMFILE
+	};
+	//0은 메모리에 데이터 관리 하는 모드, 1은 파일에 데이터를 관리 하는 모드, 2는 둘다
+	virtual void setMode(Mode nMode);
+
+	//TRACE
+	virtual void setTrace(char* format, ...);
+
+
+
+
+	//////////////////////////////////////////////////////////////////////////
+	//파일모드 일경우 사용 함수
+	//////////////////////////////////////////////////////////////////////////
+	
+	//저장할 파일 이름 지정
+	bool setTraceFileName(char* filename, bool bClear = true);
+
+
+
+
+	//////////////////////////////////////////////////////////////////////////
+	//메모리 모드 일경우 사용 함수
+	//////////////////////////////////////////////////////////////////////////
+	//저장공간 초기화
+	void clear(); 
+	//데이터 갯수 획득
+	int getTraceNum();
+	//저장된 데이터 획득
+	char* getTraceFront();
+	//젤 앞에 데이터를 획득하고 삭제
+	void getTracePop(char* pBuffer);
+	//메모리에 있는 데이터를 파일로 저장
+	void setWriteFile(char* filename, bool bAdd = true);
+	
+
+	
+
+protected:
+	Mode m_nMode;
+
+	std::queue<char*> m_vecTraceData;
+	char* m_pTraceFileName;
+	CRITICAL_SECTION	m_csTrace;
+	FILE* m_pf;
+};
diff --git a/ReviewHistory/include/akCore/akTraceExt.h b/ReviewHistory/include/akCore/akTraceExt.h
new file mode 100644
index 0000000..3de3a40
--- /dev/null
+++ b/ReviewHistory/include/akCore/akTraceExt.h
@@ -0,0 +1,38 @@
+#pragma once
+
+#define _AKTRACE
+
+#if defined _AKTRACE
+#define AKTRACEEXT(fmt,...) CakTraceExt::setTraceWithDateTime(fmt,##__VA_ARGS__) 
+#else
+#define AKTRACEEXT(fmt,...)
+#endif
+
+#if defined _AKTRACE
+#define AKTRACE(fmt,...) CakTraceExt::getInstance()->setTrace(fmt,##__VA_ARGS__) 
+#else
+#define AKTRACE(fmt,...)
+#endif
+
+
+#include "akTrace.h"
+
+
+class AKCORE_DLLSPEC CakTraceExt
+{
+protected:
+	CakTraceExt(void);
+	virtual ~CakTraceExt(void);
+
+public:
+	//////////////////////////////////////////////////////////////////////////
+	static CakTrace *getInstance() {return &m_Instance;};	
+	
+	static void setTraceWithDateTime(char* format, ...);
+	
+
+
+protected:
+	static CakTrace m_Instance;
+	
+};
diff --git a/ReviewHistory/include/akCore/akTrajectoryModel.h b/ReviewHistory/include/akCore/akTrajectoryModel.h
new file mode 100644
index 0000000..3e4c1af
--- /dev/null
+++ b/ReviewHistory/include/akCore/akTrajectoryModel.h
@@ -0,0 +1,66 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+#include "akStruct.h"
+#include "akDE.h"
+#include <vector>
+namespace akCore
+{
+	struct _Waypoint
+	{
+		double x;
+		double y;
+		double z;
+		double speed;
+	};
+
+	class AKCORE_DLLSPEC CakTrajcetoryModel
+	{
+	public:
+		CakTrajcetoryModel(void);
+		~CakTrajcetoryModel(void);
+
+	public:
+		virtual int calculate(float dTime); //더이상 계산할 경로점이 없을 경우 2를 반환
+		void setCurrentByWaypoint(int nWaypointIndex); //현재값을 경로점 기준으로 셋팅
+
+	
+
+	public:
+		//현재 값
+		akVector3d m_position; //위치
+		akVector3d m_rotate; //자세
+		double m_velocity; //속도
+		double m_acc;	//가속도
+		akVector3d m_rotateAcc; //각속도
+
+		//부여 받은 명령 설정
+		akVector3d m_TaskPosition;
+		double m_TaskVelocity;
+		double m_TaskAcc;
+
+		//객체 정보 관리
+		double mass; //무게
+		double maxSpeed; //최대 속도
+		double minSpeed; //최저 속도
+		double maxAcceleration; //가속도
+		double maxDeceleration; //감속도
+
+		akVector3d m_rotateVelRate;
+
+		//경로점 관리
+	public:
+		int m_nWaypointType; //0 마지막 경로점이면 끝낸다, 1경로점 순회, 2경로점 왕복
+		int m_nWaypointSet; //현재 설정된 경로점
+		std::vector<_Waypoint> m_vecWaypoint;
+
+
+	protected:
+		void getAngle3d(double x1, double y1, double z1, double x2, double y2, double z2, double* heading, double* pitch);
+		double getHeading(double x , double y);
+	protected:
+		CakDE m_movementmodel;
+	};
+
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akCore/akVector.h b/ReviewHistory/include/akCore/akVector.h
new file mode 100644
index 0000000..ec4fb48
--- /dev/null
+++ b/ReviewHistory/include/akCore/akVector.h
@@ -0,0 +1,20 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+
+namespace akCore
+{
+	template <class type> class AKCORE_DLLSPEC khVector
+	{
+	public:
+		khVector(void);
+		~khVector(void);
+
+	public:
+	private:
+		type* m_pDB;
+		
+	};
+
+}
diff --git a/ReviewHistory/include/akCore/akWGS84.h b/ReviewHistory/include/akCore/akWGS84.h
new file mode 100644
index 0000000..2016375
--- /dev/null
+++ b/ReviewHistory/include/akCore/akWGS84.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "akCoreLinker.h"
+
+class AKCORE_DLLSPEC CakWGS84
+{
+public:
+	CakWGS84(void);
+	~CakWGS84(void);
+
+	//- 중부원점: N38, E127
+	static void getPosition(double lat1 , double lon1 , double x , double y , double &lat2 , double &lon2);
+	static void getRange(double lat1 , double lon1 , double lat2 , double lon2 , double &x , double &y);
+
+	static void _TM2Bessel(double tm_x, double tm_y, double lonOrg, double latOrg, double *lon, double *lat);
+	static void _Bessel2TM(double lon, double lat, double lonOrg, double latOrg, double *tm_x, double *tm_y);
+	static void Bessel2TM (double alt, double lon, double lat, double lonOrg, double latOrg, double *tm_x, double *tm_y);
+
+	//태현추가
+	static double getBearing(double lon, double lat, double lonOrg, double latOrg);
+	static void getRangePosition(double bearing, double range, double lonOrg, double latOrg, double *lon, double *lat);
+};
diff --git a/ReviewHistory/include/akCore/akWaypoint.h b/ReviewHistory/include/akCore/akWaypoint.h
new file mode 100644
index 0000000..a430730
--- /dev/null
+++ b/ReviewHistory/include/akCore/akWaypoint.h
@@ -0,0 +1,36 @@
+#pragma once
+
+
+#include "akCoreLinker.h"
+#include "akStructVector.h"
+
+namespace akCore
+{
+	class AKCORE_DLLSPEC CakWaypoint
+	{
+	public:
+		CakWaypoint(void);
+		~CakWaypoint(void);
+
+	public:
+		void clear();
+		void pointAdd(akVector3d point);
+		void pointInsert(unsigned int index, akVector3d point);//범위를 넘어가면 젤 뒤에 추가
+		void pointDelete(unsigned int index);
+		
+		int size(){return m_nPointsNum;};
+		
+		akVector3d& operator [](unsigned int nindex){return m_pPoints[nindex];};
+		CakWaypoint& operator= (CakWaypoint& waypoint);
+
+	private:
+		void secureMemory();
+
+	private:
+		int m_nMakePoints; //확보 메모리 사이즈
+		int m_nPointsNum; //현재 입력된 Point 갯수
+		akVector3d* m_pPoints; //데이터 변수
+
+
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akGraph/akColorSettingDlg.h b/ReviewHistory/include/akGraph/akColorSettingDlg.h
new file mode 100644
index 0000000..4940ddd
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akColorSettingDlg.h
@@ -0,0 +1,59 @@
+#pragma once
+
+
+
+
+#include "akGraph/akGraphLinker.h"
+#include "akGraph/akResource.h"
+
+
+#define COLORSETTINGUPDATE WM_USER+0x109
+
+
+class CakColorSettingDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakColorSettingDlg)
+
+public:
+	CakColorSettingDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakColorSettingDlg();
+
+// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKCOLORSETTINGDLG };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+public:
+	void SetUpdateData(bool bToVariable); //true --> 변수로 저장, false-->다이얼로그에 표시
+	void SetTitle(char* strTitle);
+	void SetReverse(bool bReverse);
+public:
+	COLORREF m_Color;
+	int nDataIndex;
+public:
+	double m_RangeMin;
+	double m_RangeMax;
+	
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+	
+	int m_nID;
+private:
+	CString m_strTitle;
+	CWnd* m_pParent;
+	bool m_bReverse;//최대, 최소 반대로 설정
+
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+	
+	virtual BOOL OnInitDialog();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	virtual BOOL DestroyWindow();
+	
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+};
diff --git a/ReviewHistory/include/akGraph/akColorTable.h b/ReviewHistory/include/akGraph/akColorTable.h
new file mode 100644
index 0000000..7698288
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akColorTable.h
@@ -0,0 +1,58 @@
+#pragma once
+
+
+#include "akGraph/akGraphLinker.h"
+
+#include <iostream>
+#include <vector>
+
+
+
+
+
+
+
+
+class AFX_EXT_CLASS CakColorTable 
+{
+public:
+	CakColorTable(void);
+	~CakColorTable(void);
+
+public:
+	struct AFX_EXT_CLASS _COLOR_TABLE 
+	{
+		char name[255];
+		unsigned char R[64];
+		unsigned char G[64];
+		unsigned char B[64];
+	};
+
+
+
+
+	void setFile(char *file);
+	void setColorTable(int index , int level , float min , float max , float value , unsigned char &R , unsigned char &G , unsigned char &B , bool inverse);
+	void setColorTableSmooth(int index , int level , float min , float max , float value , unsigned char &R , unsigned char &G , unsigned char &B , bool inverse);
+
+	int  getTotalColorTable(void);
+	char *getColorName(int index);
+
+	void rendColorTableBar(CDC *dc , int x , int y , int width , int height , int index , int level , bool inverse , bool vertical);
+
+
+
+protected:
+
+private:
+
+
+public:
+	std::vector<_COLOR_TABLE> m_vecColorTable;
+
+protected:
+
+
+private:
+
+};
diff --git a/ReviewHistory/include/akGraph/akColorTableOption.h b/ReviewHistory/include/akGraph/akColorTableOption.h
new file mode 100644
index 0000000..08d8a61
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akColorTableOption.h
@@ -0,0 +1,70 @@
+#pragma once
+
+//#define IDD_AKCOLORTABLEOPTIONDLG 11000
+
+#include "akGraph/akResource.h"
+#include "akGraph/akGraphBase.h"
+#include "afxwin.h"
+
+// CakColorTableOptionDlg 대화 상자입니다.
+#define COLORTABLEOPTIONUPDATE WM_USER+0x100
+
+
+
+class CakColorTableOptionDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakColorTableOptionDlg)
+
+public:
+	CakColorTableOptionDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakColorTableOptionDlg();
+
+// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKCOLORTABLEOPTIONDLG };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+	virtual BOOL OnInitDialog();
+
+public:
+	void SetData(int index, int level, int min, int max, bool inverse, bool interpolation, bool colorauto);
+	
+public:
+	CWnd* m_pParent;
+
+	CComboBox	m_ctrlColorIndex;
+	CComboBox	m_ctrlColorLevel;
+	CButton		m_ctrlCheckInverse;
+	CButton		m_ctrlCheckInterpolation;
+	CEdit		m_ctrlEditMin;
+	CEdit		m_ctrlEditMax;
+	
+
+
+	int m_index;
+	int m_level;
+	int m_colorMin;
+	int m_colorMax;
+	BOOL m_colorInverse;
+	BOOL m_colorInterpolation;
+	BOOL m_colorAuto;
+	int m_colorMinAuto;
+	int m_colorMaxAuto;
+
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+	
+private:
+
+
+public:
+	afx_msg void OnBnClickedCancel();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	CButton m_ctrlColorAuto;
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+};
diff --git a/ReviewHistory/include/akGraph/akDDSettingDlg.h b/ReviewHistory/include/akGraph/akDDSettingDlg.h
new file mode 100644
index 0000000..997056c
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akDDSettingDlg.h
@@ -0,0 +1,67 @@
+#pragma once
+
+//#define IDD_AKCOLORTABLEOPTIONDLG 11000
+
+#include "akGraph/akResource.h"
+#include "akGraph/akGraphBase.h"
+#include "afxwin.h"
+
+// CakDDSettingDlg 대화 상자입니다.
+#define DDSETTINGUPDATE WM_USER+0x105
+
+
+
+class CakDDSettingDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakDDSettingDlg)
+
+public:
+	CakDDSettingDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakDDSettingDlg();
+
+// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKDDSETTINGDLG };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+	virtual BOOL OnInitDialog();
+
+public:
+	void SetUpdate();
+public:
+	CWnd* m_pParent;
+
+	CEdit		m_ctrlEditXMin;
+	CEdit		m_ctrlEditXMax;
+	CEdit		m_ctrlEditGraphDepth1;
+	CEdit		m_ctrlEditGraphDepth2;
+	CEdit		m_ctrlEditGraphDepth3;
+	CEdit		m_ctrlEditGraphDepth4;
+	CEdit		m_ctrlEditStd;
+	
+	double m_RangeXMin;
+	double m_RangeXMax;
+	int m_GraphDepth1;
+	int m_GraphDepth2;
+	int m_GraphDepth3;
+	int m_GraphDepth4;
+	int m_Standard;
+	double m_DetectPoint[4][4];
+	
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+
+private:
+
+
+public:
+	afx_msg void OnBnClickedCancel();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	CStatic m_ctrlDetectPoint[4][4];
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+};
diff --git a/ReviewHistory/include/akGraph/akDataBasic1.h b/ReviewHistory/include/akGraph/akDataBasic1.h
new file mode 100644
index 0000000..8bb7dac
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akDataBasic1.h
@@ -0,0 +1,26 @@
+#pragma once
+
+//시리즈가 하나이고 등간격 데이터 일 경우
+
+class AFX_EXT_CLASS CakDataBasic1
+{
+public:
+	CakDataBasic1(void);
+	~CakDataBasic1(void);
+
+
+
+public:
+
+	virtual void SetDataNum(int datanum);
+	int GetDataNum(){return m_dataNum;};
+	void SetData(int index, double value);
+
+	void SetHidden(bool enable, int startIndex, int endIndex);
+	
+protected:
+	int m_dataNum;
+public:
+	double *m_pData;
+	bool *m_pHidden;
+};
diff --git a/ReviewHistory/include/akGraph/akDataBasic2.h b/ReviewHistory/include/akGraph/akDataBasic2.h
new file mode 100644
index 0000000..aa9c3e0
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akDataBasic2.h
@@ -0,0 +1,47 @@
+#pragma once
+
+//시리즈가 하나만 있고 등간격 데이터가 아닐경우
+
+struct _DataBasic2
+{
+	_DataBasic2(double x1, double y1)
+	{
+		x = x1;
+		y = y1;
+	}
+	_DataBasic2()
+	{
+		x=y=0;
+	}
+	void set(double x1, double y1)
+	{
+		x = x1;
+		y = y1;
+	}
+	double x;
+	double y;
+};
+
+class AFX_EXT_CLASS CakDataBasic2
+{
+public:
+	CakDataBasic2(void);
+	~CakDataBasic2(void);
+
+public:
+	CakDataBasic2& operator=(CakDataBasic2& data);
+
+public:
+
+	virtual void SetDataNum(int datanum);
+	int GetDataNum(){return m_dataNum;};
+	void SetData(int index, double x, double y);
+
+	void SetHidden(bool enable, int startIndex, int endIndex);
+	
+protected:
+	int m_dataNum;
+public:
+	_DataBasic2 *m_pData;
+	bool *m_pHidden;
+};
diff --git a/ReviewHistory/include/akGraph/akDataBasic3.h b/ReviewHistory/include/akGraph/akDataBasic3.h
new file mode 100644
index 0000000..2257142
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akDataBasic3.h
@@ -0,0 +1,42 @@
+#pragma once
+
+//등간격 데이터가 아니고
+//데이터가 여러개 존재할경우
+
+#include "akGraph/akDataBasic2.h"
+#include "akGraph/akGraphStruct.h"
+
+class AFX_EXT_CLASS CakDataBasic3
+{
+public:
+	CakDataBasic3(void);
+	virtual ~CakDataBasic3(void);
+
+
+public:
+
+	virtual void SetSeriesNum(int subsetNum); //기존 데이터 초기화
+	//기존 데이터 해당 인덱스에 추가(인덱스가 0보다 작거나 생성된 Subset갯수보다 많으면 젤 뒤에 추가된다)
+	virtual void SetSeriesAdd(int index = -1); 
+	virtual bool SetSeriesDelete(int index); //해당 인덱스 삭제
+
+	int GetSeriesNum(){return m_SeriesNum;};
+
+	void SetSelectSeries(int index);
+	int GetSelectSeries(){return m_nSelectedSeriesindex;};
+
+	virtual void SetDataNum(int nDataNum);
+	virtual bool SetData(int index, double x, double y);
+
+	virtual void SetHidden(bool enable, int startIndex, int endIndex);
+
+	virtual void calculateMinMax(double* xmin, double* xmax, double* ymin, double* ymax);
+protected:
+	int m_SeriesNum;
+	int m_nSelectedSeriesindex;
+public:
+	CakDataBasic2 *m_pSeriesData;
+	bool *m_pSeriesHidden;
+	CSeries* m_pSeries;
+	CLegendOption m_LegendOption;
+};
diff --git a/ReviewHistory/include/akGraph/akDataImage.h b/ReviewHistory/include/akGraph/akDataImage.h
new file mode 100644
index 0000000..99fe52d
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akDataImage.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#include "akGraph/akGraphStruct.h"
+#include <vector>
+
+class AFX_EXT_CLASS CakDataImage
+{
+public:
+	CakDataImage(void);
+	virtual ~CakDataImage(void);
+
+	struct _DataImage
+	{
+		_DataImage()
+		{
+			m_nDrawPosX = m_nDrawPosY = 0;
+			m_nRoate = 0;
+			m_nDrawWidth = m_nDrawHeight = 0;
+
+			m_bReverseX = m_bReverseY = false;
+		}
+		CString m_strBitmapFilename;
+		CBitmap m_Bitmap;
+		BITMAP	m_Bits;
+
+		unsigned char* m_pBitmapData;
+
+		//그리기 정보 [김태현 2018/12/7]
+		int m_nProjectionType;
+		int m_nDrawPosX,m_nDrawPosY;
+		int m_nDrawWidth,m_nDrawHeight;
+		float m_nRoate;
+		bool m_bReverseX, m_bReverseY;
+	};
+
+public:
+	int SetImageData(char* pFileName, int nImageIndex = 0); //add가 아니면 0번 인덱스에 넣는다.
+	int AddImageData(char* pFileName); //add가 아니면 0번 인덱스에 넣는다.
+	_DataImage* GetImageData(int nImageIndex = 0);
+	int GetImageDataNum(){return m_vecImageData.size();};
+public:
+	virtual void calculateMinMax(double* xmin, double* xmax, double* ymin, double* ymax);
+protected:
+	
+public:
+	std::vector<_DataImage*> m_vecImageData;
+};
diff --git a/ReviewHistory/include/akGraph/akDataMesh.h b/ReviewHistory/include/akGraph/akDataMesh.h
new file mode 100644
index 0000000..8772e7e
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akDataMesh.h
@@ -0,0 +1,34 @@
+#pragma once
+
+//시리즈가 하나만 있고 등간격 데이터가 아닐경우
+
+
+class AFX_EXT_CLASS CakDataMesh
+{
+public:
+	CakDataMesh(void);
+	~CakDataMesh(void);
+
+public:
+	CakDataMesh& operator=(CakDataMesh& data);
+
+public:
+	virtual void SetDataNum(int sizex, int sizey);
+	virtual int GetDataNumX(){return m_dataNumX;};
+	virtual int GetDataNumY(){return m_dataNumY;};
+	
+	virtual void SetNoDataValue(double val){m_NoDataValue = val;};
+
+	virtual void SetDataValueX(double min, double max){m_DataValueXMin = min;m_DataValueXMax = max;};
+	virtual void SetDataValueY(double min, double max){m_DataValueYMin = min;m_DataValueYMax = max;};
+public:
+	double m_DataValueYMin, m_DataValueYMax;//  <<--중요함.. 들어온 데이터의 가로축 범위가 어딘지 셋팅해줘야됨.
+	double m_DataValueXMin, m_DataValueXMax;//  <<--중요함.. 들어온 데이터의 세로축 범위가 어딘지 셋팅해줘야됨.
+
+	double **m_pData;
+
+	double m_NoDataValue; //데이터가 없는 곳의 값 처리
+
+protected:
+	int m_dataNumX, m_dataNumY;
+};
diff --git a/ReviewHistory/include/akGraph/akDataVector2.h b/ReviewHistory/include/akGraph/akDataVector2.h
new file mode 100644
index 0000000..1f61337
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akDataVector2.h
@@ -0,0 +1,57 @@
+#pragma once
+
+#include <vector>
+#include "akGraphStruct.h"
+
+struct _DataVector2
+{
+	_DataVector2(double x1, double y1)
+	{
+		x = x1;
+		y = y1;
+		hidden = false;
+	}
+	_DataVector2()
+	{
+		x=y=0;
+		hidden = false;
+	}
+	void set(double x1, double y1)
+	{
+		x = x1;
+		y = y1;
+	}
+	double x;
+	double y;
+	bool hidden;
+};
+
+class AFX_EXT_CLASS CakDataVector2
+{
+public:
+	CakDataVector2(void);
+	~CakDataVector2(void);
+
+public:
+	CakDataVector2& operator=(CakDataVector2& data);
+
+public:
+
+	
+	int GetDataNum(){return int(m_vecData.size());};
+
+	virtual void Clear();
+	//지정 인덱스가 존재하지 않는다면 데이터변경을 하지 않는다.
+	virtual bool SetData(int index, double x, double y);
+	//인덱스가 현제 존재하는 데이터 범위를 벗어나면 젤끝에 추가한다. 
+	virtual void AddData(double x, double y, int index = -1); 
+
+	virtual void SetHidden(bool enable, int startIndex, int endIndex);
+	
+protected:
+	
+public:
+	std::vector<_DataVector2> m_vecData;
+	CSeries m_SeriesOption;
+	
+};
diff --git a/ReviewHistory/include/akGraph/akGraphBase.h b/ReviewHistory/include/akGraph/akGraphBase.h
new file mode 100644
index 0000000..2ace320
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphBase.h
@@ -0,0 +1,312 @@
+#pragma once
+
+#include "akGraph/akGraphLinker.h"
+
+#include "akGraph/akMemDC.h"
+#include "akGraph/akGraphStruct.h"
+#include "akGraph/akSyncObject.h"
+#include "akSTL/akStruct.h"
+
+
+// akGraphBase
+
+#define AKGRAPH_BUTTONDOWN WM_USER+0x1001
+#define AKGRAPH_MOUSEMOVE WM_USER+0x1002
+
+
+#include <process.h>
+class AFX_EXT_CLASS CakGraphThreadDraw;
+
+class AFX_EXT_CLASS  CakGraphBase :  public CWnd, public CakSyncObject
+{
+	DECLARE_DYNAMIC(CakGraphBase)
+
+public:
+	CakGraphBase();
+	virtual ~CakGraphBase();
+
+protected:
+	DECLARE_MESSAGE_MAP()
+
+
+	CakMouseState m_MouseState;
+
+
+public:
+	virtual BOOL CreateGraph(CWnd* pParent, CRect rect);
+	
+	virtual void RenderBegin(CDC* pDC, CRect rectDC);
+	virtual void RenderGrid(Graphics* grfx, CDC* pDC){};
+	virtual void RenderDataArea(Graphics* grfx, CDC* pDC); //데이터 영역 그리기
+	virtual void RenderSeries(Graphics* grfx, CDC* pDC){}; //데이터 선/바 그리기
+	virtual void RenderLegend(Graphics* grfx, CDC* pDC){}; //범례
+	virtual void RenderAxis(Graphics* grfx, CDC* pDC); //축 영역 그리기
+	virtual void RenderTitle(Graphics* grfx, CDC* pDC); //제목 영역 그리기
+	virtual void RenderLabel(Graphics* grfx, CDC* pDC){}; //해당 축에 틱그리기, 데이터 영역 외각선 그리기
+	virtual void RenderEnd(Graphics* grfx, CDC* pDC); //그리는 부분 마지막에 추가(Redraw false 할때도 그림)
+	virtual void RenderClossLine(CDC* pDC); //마우스 크로스 라인 그리기 [김태현 2018/9/7]
+	virtual void RenderMouseHoverInfo(CDC* pDC){}; //마우스 올려져 있을 경우 데이터표시 그리기 [김태현 2018/9/7]
+
+	virtual void RenderPerformance(Graphics* grfx, CDC* pDC); 
+	
+	virtual void GetRenderFrame(CDC* pDC, CRect rect);
+
+	virtual void ReDraw(bool bReDrawALL = true);
+	
+	virtual void SetAutoScale(){}; //이런건 기본적으로 있어야됨!!
+
+	virtual void SetTitle(char* titlename);
+	virtual char* GetTitle();
+	virtual void SetAxisXTitle(char* titlename){m_AxisX.m_strTitle = titlename;};
+	virtual void SetAxisYTitle(char* titlename){m_AxisY.m_strTitle = titlename;};
+
+	virtual void OnKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown //키보드 입력 이벤트 처리
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point); //마우스 입력 이벤트처리
+	virtual void MouseInput(CakMouseState mousestate){}; //마우스 상태처리
+	virtual void OnSystemKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown //키보드 입력 이벤트 처리
+
+	virtual void EnableThreadDrawMode(int nSleepTime = 30, int nSleepTimeMin = 1);//한번 키면 끝
+	void SetDragStyle(akDragStyle style){m_DragStyle = style;} ; //0은 끄기, 1은 양쪽모두, 2은 세로선만, 3는 가로선만
+	akDragStyle GetDragStyle(){return m_DragStyle;};
+	CPoint GetMousePos(){return m_MouseState.Point;};
+
+	void SetWindowSize(int x, int y, int width, int height, UINT flag = NULL, bool reDraw = true);
+	void SetWindowSize(int width, int height, UINT flag = NULL, bool reDraw = true);
+	void GetWindowSize(int* width, int* height);
+
+	inline CakRect GetDataArea(){return m_rectData;};
+	inline CakRect GetTitleArea(){return m_rectTitle;};
+	inline CakRect GetAxisXArea(){return m_rectAxisX;};
+	inline CakRect GetAxisYArea(){return m_rectAxisY;};
+
+	void SetTitleSize(int height);//타이틀바 세로축 크기
+	void SetAxisXSize(int height);//x축 세로 크기
+	void SetAxisYSize(int width);//y축 가로 크기
+
+	void SetSaveImage(char* strFilepathname); 
+
+	void SetClossLine(bool flag = true){m_bClossLine = flag;};
+
+	//마우스 제어 모드(0:우클릭 이동모드, 1:좌클릭 이동모드) [김태현 2018/8/22]
+	void SetMouseControlMode(int nType){m_nMouseControlMode = nType;};
+	inline void SetID(int nID);
+	inline int GetID();
+
+	virtual void FuncThreadDraw();
+protected:
+	virtual void CaculatorGraphSize();
+	virtual void getLbuttonDragPoint(int* px1, int* py1, int* px2, int* py2);
+
+	
+private:
+	
+
+public:
+	int m_nID;//메세지 보낼때 같이 보내주면서.. 인스턴스를 구분한다.
+
+	CAxis m_AxisX;
+	CAxis m_AxisY;
+	CAxis m_AxisY2;//오른쪽 y공간
+
+	CTitle m_Title;
+
+	CMouseMoveInfo m_MouseMoveInfo;//마우스 움직임에 따라 화면에 표시되는 내용
+
+	CakRectd m_AutoScaleMarginRate;//자동스케일 양옆 아래,위 여백 비율 설정
+	CakRect m_rectLabelAdjust;
+
+	bool m_bCheckDC; //올바른 DC인가 확인 절차를 생략할 것인지 여부
+
+	bool m_bClossLine;
+
+	int	 m_nMouseControlMode;
+
+	CakGraphThreadDraw* m_pThreadDraw;
+protected:
+	CWnd* m_pParent; //부모 윈도우 클래스
+
+	
+
+	//메모리 디씨~
+	CDC m_GraphDC; 
+	CBitmap m_GraphBitmap, *m_pGraphOldBitmap;
+	CRect m_rectGraphBitmap;
+
+	//그래프 다시 그려야 할때
+	bool m_bReRender; 
+	
+	//그리는 부분 영역 크기
+	int m_nWindowSizeWidth, m_nWindowSizeHeight;
+
+	//그리는 영역 각각의 크기(매번 CaculatorGraphSize() 함수에 의해 계산이 된다)
+	CakRect m_rectData; //순수하게 그래프 그리는 부분 영역
+	CakRect m_rectChartMargin; //데이터 그리는 부분 오른쪽 여백
+	CakRect m_rectAxisX;
+	CakRect m_rectAxisY;
+	CakRect m_rectTitle;
+
+	
+	CFont m_fontData; //데이터 폰트 
+
+	bool m_bRenderState;
+	bool m_bHover;
+
+public:
+	COLORREF m_colorBack; //배경색
+	COLORREF m_colorDataArea; //데이터 그리는부분 배경색
+protected:
+	akDragStyle m_DragStyle;
+private:
+	CFont m_fontWaterMake;
+	ULONG_PTR m_gdiplusToken; //GDI+ 토큰
+	CString m_strSaveFilePath;
+
+	//성능 체크 관련
+private:
+	int m_nShowPerformance;
+	int m_nTimeRenderTotal;
+	int m_nTimeRenderDraw1stBuffer;
+	int m_nTimeRenderDraw2ndBuffer;
+
+	int m_nTimeTempTotal;
+	int m_nTimeTempDraw1stBuffer;
+	int m_nTimeTempDraw2ndBuffer;
+	int m_nTimeRenderCount;
+
+	int m_nTimerRenderTotalMax;
+	int m_nTimerRenderTotalMin;
+	
+	
+	
+public:
+	static bool m_bAK;
+	static void setAK(){CakGraphBase::m_bAK = false;};
+	afx_msg void OnPaint();
+	afx_msg void OnSize(UINT nType, int cx, int cy);
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	
+	afx_msg void OnShowWindow(BOOL bShow, UINT nStatus);
+	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+
+	//int m_DataState;
+	//afx_msg void OnTimer(UINT nIDEvent);
+	afx_msg void OnTimer(UINT_PTR nIDEvent);
+};
+
+
+class AFX_EXT_CLASS CakGraphThreadDraw
+{
+public:
+	CakGraphThreadDraw()
+	{
+		m_bThreadDrawMode = FALSE;
+		m_bDrawByThread = FALSE;
+		m_nThreadDrawFlag = 0;
+		m_nThreadDrawSleepTimeMin = 1;
+		m_nThreadDrawSleepTime = 30;
+
+		InitializeCriticalSection(&m_csThreadDraw);
+	};
+	virtual ~CakGraphThreadDraw()
+	{
+		if(GetThreadDrawMode())
+		{
+			m_nThreadDrawFlag = 2;
+			int nReTryCount = 10;
+			while (m_nThreadDrawFlag != 0 && nReTryCount--)
+			{
+				Sleep(1);
+			}
+		}
+
+	};
+
+public:
+	virtual BOOL CreateThreadDraw(CakGraphBase* pBase)
+	{
+		if(pBase == NULL) return FALSE;
+
+		//if(GetThreadDrawMode())
+		{
+			m_nThreadDrawFlag = 1;
+			//_beginthread(threadThreadDraw, NULL, this);
+			AfxBeginThread(threadThreadDraw, this, NULL);
+			m_pGraphBase = pBase;
+			m_bDrawByThread = TRUE;
+		}
+		return TRUE;
+	}
+	void SetDrawByThread(BOOL bFlag){m_bDrawByThread = bFlag;};
+	void SetThreadDrawMode(BOOL bFlag){m_bThreadDrawMode = bFlag;};
+	BOOL GetThreadDrawMode(){return m_bThreadDrawMode;};
+	CRITICAL_SECTION* GetCriticalSection(){return &m_csThreadDraw;};
+	void SleepMsg(IN DWORD dwMilliseconds)  
+	{  
+		DWORD dwStart   = 0;  
+		MSG   msg       = {0,};  
+
+		dwStart  = GetTickCount();  
+		while (GetTickCount() - dwStart < dwMilliseconds)  
+		{  
+			while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))  
+			{  
+				TranslateMessage(&msg);  
+				DispatchMessage(&msg);  
+			}  
+
+			// Lower CPU Usage  
+			::Sleep(1);  
+		}  
+	}  
+
+public:
+	int m_nThreadDrawSleepTime;
+	int m_nThreadDrawSleepTimeMin;
+protected:
+	BOOL m_bThreadDrawMode;
+
+	//CDC m_ThreadDrawDC; 
+	//CBitmap m_ThreadDrawBitmap;
+	//CRect m_rectThreadDrawBitmap;
+	int m_nThreadDrawFlag;
+	BOOL m_bDrawByThread;
+
+	CRITICAL_SECTION m_csThreadDraw;
+	CakGraphBase* m_pGraphBase;
+
+	
+protected:
+	//static void threadThreadDraw(void* arg)
+	static UINT threadThreadDraw(LPVOID arg)
+	{
+		CakGraphThreadDraw* pThis = (CakGraphThreadDraw*)arg;
+		while (pThis->m_nThreadDrawFlag == 1)
+		{
+			DWORD	dwTimeStart = GetTickCount();
+			if(pThis->m_bDrawByThread)
+			{
+				pThis->m_bDrawByThread = FALSE;
+				pThis->funcThreadDraw();
+			}
+			else
+			{
+				
+			}
+
+			int nSleepTimeDynamic = pThis->m_nThreadDrawSleepTime-(GetTickCount()-dwTimeStart);
+			nSleepTimeDynamic = max(nSleepTimeDynamic, pThis->m_nThreadDrawSleepTimeMin);
+
+			nSleepTimeDynamic = pThis->m_nThreadDrawSleepTime;
+			Sleep(nSleepTimeDynamic);
+			//pThis->SleepMsg(nSleepTimeDynamic);
+		}
+		pThis->m_nThreadDrawFlag = 0;
+
+		return TRUE;
+	};
+
+	virtual void funcThreadDraw()
+	{
+		m_pGraphBase->FuncThreadDraw();
+	};
+};
diff --git a/ReviewHistory/include/akGraph/akGraphBasic3.h b/ReviewHistory/include/akGraph/akGraphBasic3.h
new file mode 100644
index 0000000..fb361fb
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphBasic3.h
@@ -0,0 +1,104 @@
+#pragma once
+
+#include "akGraph/akGraphBase.h"
+#include "akGraph/akDataBasic3.h"
+
+#include "akGraph/akRangeSettingNormalDlg.h"
+#include "akGraph/akRangeSettingTimeDlg.h"
+
+
+//class AFX_EXT_CLASS CakGraphType3 : public CakGraphULS
+class AFX_EXT_CLASS CakGraphBasic3 : public CakGraphBase , public CakDataBasic3
+{
+public:
+	CakGraphBasic3(void);
+	virtual ~CakGraphBasic3(void);
+
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL CreateGraph(CWnd* pParent, CRect rect);
+	
+	virtual void RenderGrid(Graphics* grfx, CDC* pDC);
+	virtual void RenderDataArea(Graphics* grfx, CDC* pDC); //데이터 영역 그리기
+	virtual void RenderSeries(Graphics* grfx, CDC* pDC); //데이터 선/바 그리기
+	virtual void RenderLegend(Graphics* grfx, CDC* pDC);
+	virtual void RenderAxis(Graphics* grfx, CDC* pDC); //축 영역 그리기
+	virtual void RenderTitle(Graphics* grfx, CDC* pDC); //제목 영역 그리기
+	virtual void RenderLabel(Graphics* grfx, CDC* pDC); //해당 축에 틱그리기, 데이터 영역 외각선 그리기
+	virtual void RenderMouseMoveInfo(Graphics* grfx, CDC* pDC);//마우스 움직일때 위치값 표시하는부분
+	virtual void RenderEnd(Graphics* grfx, CDC* pDC); //그리는 부분 마지막에 추가(Redraw false 할때도 그림)
+	
+	
+
+	virtual void OnKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point);
+	virtual void MouseInput(CakMouseState mousestate);
+
+	//데이터 클래스 동기화 객체 추가
+	virtual void SetSeriesNum(int subsetNum); //기존 데이터 초기화
+	virtual void SetSeriesAdd(int index = -1); 
+	virtual bool SetSeriesDelete(int index);
+	virtual void SetDataNum(int nDataNum);
+	//virtual bool SetData(int index, double x, double y); <--요녀석은 알아서 동기화 시키도록.. 성능!!
+	virtual void SetHidden(bool enable, int startIndex, int endIndex);
+
+	virtual void SetColorType(int nIndex);
+
+	inline int GetWindowPosX(double xvalue); //위치 값에 따른 윈도우 좌표
+	inline int GetWindowPosY(double yvalue); //위치 값에 따른 윈도우 좌표
+	inline double GetValuePosDataX(int xpos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+	inline double GetValuePosDataY(int ypos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+
+	void SetReverseModeX(bool flag); //x축 역방향 표시
+	bool GetReverseModeX(){return m_bReverseX;}; //x축 역방향 표시
+	void SetReverseModeY(bool flag); //y축 역방향 표시
+	bool GetReverseModeY(){return m_bReverseY;}; //y축 역방향 표시
+
+	
+	void SetClossLinePos(double x, double y);
+
+	virtual void SetAutoScale();
+
+	double getValueY(int nSeriesIndex, double xpos);
+	int getDataIndex(int nSeriesIndex, double xpos);
+	
+	LRESULT OnRangeSettingNormalUpdate(WPARAM wParam, LPARAM lParam);
+	LRESULT OnRangeSettingTimeUpdate(WPARAM wParam, LPARAM lParam);
+
+	
+protected:
+	
+	bool m_bGrid;
+	bool m_bReverseX;
+	bool m_bReverseY;
+	
+public:
+	CakRangeSettingNormalDlg* m_pRangeYSettingDlg;
+	CakRangeSettingNormalDlg* m_pRangeXSettingDlg;
+	bool m_bRangeYSetting;
+	bool m_bRangeXSetting;
+	bool m_bFastDrawAlg;
+	afx_msg void OnDestroy();
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+};
+
+
+//X축 값을 h/m/s/ms 표현이 가능하게
+class AFX_EXT_CLASS CakGraphType3Time : public CakGraphBasic3
+{
+public:
+
+public:
+	CakGraphType3Time(void){};
+	virtual ~CakGraphType3Time(void){};
+
+public:
+	virtual void RenderGrid(Graphics* grfx, CDC* pDC);
+	virtual void RenderLabel(Graphics* grfx, CDC* pDC); //해당 축에 틱그리기, 데이터 영역 외각선 그리기
+	virtual void RenderMouseMoveInfo(Graphics* grfx, CDC* pDC);
+	
+	void getTime(double timeval, int *hour, int *min, int *sec, float *msec);
+};
+
+
diff --git a/ReviewHistory/include/akGraph/akGraphCodeJ.h b/ReviewHistory/include/akGraph/akGraphCodeJ.h
new file mode 100644
index 0000000..27896e4
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphCodeJ.h
@@ -0,0 +1,90 @@
+#pragma once
+
+#include "akGraph/akGraphBase.h"
+#include "akGraph/akDataBasic1.h"
+#include "akGraph/akColorSettingDlg.h"
+#include <vector>
+
+class AFX_EXT_CLASS CakGraphCodeJ : public CakGraphBase, public CakDataBasic1
+{
+public:
+
+public:
+	CakGraphCodeJ(void);
+	virtual ~CakGraphCodeJ(void);
+
+public:
+	virtual	void RenderBegin( CDC* pDC, CRect rectDC );
+	virtual BOOL CreateGraph(CWnd* pParent, CRect rect);
+	virtual void RenderDataArea(Graphics* grfx, CDC* pDC); //데이터 영역 그리기
+
+	virtual void RenderAxis(Graphics* grfx, CDC* pDC); //
+	virtual void RenderLabel(Graphics* grfx, CDC* pDC); //
+	virtual void RenderTitle(Graphics* grfx, CDC* pDC);
+	virtual void RenderEnd(Graphics* grfx, CDC* pDC);
+
+	virtual void OnKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point);
+	virtual void MouseInput(CakMouseState mousestate);
+
+	inline int GetWindowPosX(double xvalue); //위치 값에 따른 윈도우 좌표
+	inline int GetWindowPosY(double yvalue); //위치 값에 따른 윈도우 좌표
+	inline double GetValuePosDataX(int xpos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+	inline double GetValuePosDataY(int ypos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+
+	virtual void SetAutoScale();
+	virtual void SetDataNum(int datanum);
+
+	virtual void ReDraw(bool bReDrawALL);
+
+	void SetHorMode(bool bFlag = true); //가로 모드
+
+	void SetCalculatorAvr();//값들의 평균을 화면에 표시
+	CString m_strAVR;
+
+	void SetAutoBarScale(int margin);
+	int m_nBarGab; //막대 그래프 사이의 간격
+	
+	void SetFullScreen(bool flag);
+	void SetFullMode(bool flag, int x, int y, int width, int height); //풀 모드 키고 끔.. 그리고 풀모드 싸이즈
+
+	void GraphType(int nType);
+
+	bool GetValuebyMousePos(int mousex, int mousey, int* index, double* val);
+
+private:
+	
+	
+protected:
+	bool m_bGrid;
+	CakColorSettingDlg* m_pColorSettingDlg;
+public:
+	bool m_bIntegerAxisX;
+	bool m_bIntegerAxisY;
+
+	bool m_bAVR;//화면에 평균값 표시 할 것인지에 대한 플레그
+	std::vector<double> m_vecProbabilityData; //이상이하확률계산데이터
+	int m_nBarWidth;
+
+
+	CakRect m_rectFullMode;
+	CakRect m_rectNormalMode;
+	
+	int m_nGraphType; //0은 바타입 선 타입 모두 표현, 1은 바타입만 표현
+	int m_nTextValueShowLevel; //그래프 위에 텍스트로 값 표시(-1은 표시 안함 0에서 3까지 소수 자리수 표현)
+
+	CString*  m_strAxisXText;
+	COLORREF* m_clrAxisXColor;
+	double m_avr;
+protected:
+	double m_nTimeline;
+	bool m_bFullScreen;
+	bool m_bFullMode;
+
+	bool m_bHorMode;
+
+public:
+	DECLARE_MESSAGE_MAP()
+	afx_msg void OnDestroy();
+	LRESULT OnColorSettingUpdate(WPARAM wParam, LPARAM lParam);
+};
diff --git a/ReviewHistory/include/akGraph/akGraphImage.h b/ReviewHistory/include/akGraph/akGraphImage.h
new file mode 100644
index 0000000..9482200
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphImage.h
@@ -0,0 +1,84 @@
+#pragma once
+
+#include "akGraph/akGraphBase.h"
+#include "akGraph/akDataImage.h"
+
+#include "akGraph/akRangeSettingNormalDlg.h"
+#include "akGraph/akRangeSettingTimeDlg.h"
+
+
+class AFX_EXT_CLASS CakGraphImage : public CakGraphBase , public CakDataImage
+{
+public:
+	CakGraphImage(void);
+	virtual ~CakGraphImage(void);
+
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL CreateGraph(CWnd* pParent, CRect rect);
+	
+	virtual void RenderGrid(Graphics* grfx, CDC* pDC);
+	virtual void RenderDataArea(Graphics* grfx, CDC* pDC); //데이터 영역 그리기
+	
+	
+	virtual void RenderAxis(Graphics* grfx, CDC* pDC); //축 영역 그리기
+	virtual void RenderTitle(Graphics* grfx, CDC* pDC); //제목 영역 그리기
+	virtual void RenderLabel(Graphics* grfx, CDC* pDC); //해당 축에 틱그리기, 데이터 영역 외각선 그리기
+	virtual void RenderMouseMoveInfo(Graphics* grfx, CDC* pDC);//마우스 움직일때 위치값 표시하는부분
+	virtual void RenderEnd(Graphics* grfx, CDC* pDC); //그리는 부분 마지막에 추가(Redraw false 할때도 그림)
+	
+	virtual void RenderImage(Graphics* grfx, CDC* pDC);
+	
+
+	virtual void OnKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point);
+	virtual void MouseInput(CakMouseState mousestate);
+
+
+	virtual void SetColorType(int nIndex);
+
+	inline int GetWindowPosX(double xvalue); //위치 값에 따른 윈도우 좌표
+	inline int GetWindowPosY(double yvalue); //위치 값에 따른 윈도우 좌표
+	inline double GetValuePosDataX(int xpos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+	inline double GetValuePosDataY(int ypos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+
+	double GetValuePosRangeX(int nValue){return abs(GetValuePosDataX(nValue)-GetValuePosDataX(0));};
+	double GetValuePosRangeY(int nValue){return abs(GetValuePosDataY(nValue)-GetValuePosDataY(0));};
+	int GetWindowPosRangeX(double dValue){return abs(GetWindowPosX(dValue)-GetWindowPosX(0));};
+	int GetWindowPosRangeY(double dValue){return abs(GetWindowPosY(dValue)-GetWindowPosY(0));};
+
+	void SetReverseModeX(bool flag); //x축 역방향 표시
+	bool GetReverseModeX(){return m_bReverseX;}; //x축 역방향 표시
+	void SetReverseModeY(bool flag); //y축 역방향 표시
+	bool GetReverseModeY(){return m_bReverseY;}; //y축 역방향 표시
+
+	
+	void SetClossLinePos(double x, double y);
+
+	virtual void SetAutoScale();
+
+	double getValueY(int nSeriesIndex, double xpos);
+	int getDataIndex(int nSeriesIndex, double xpos);
+	
+	LRESULT OnRangeSettingNormalUpdate(WPARAM wParam, LPARAM lParam);
+	LRESULT OnRangeSettingTimeUpdate(WPARAM wParam, LPARAM lParam);
+
+	
+protected:
+	
+	bool m_bGrid;
+	bool m_bReverseX;
+	bool m_bReverseY;
+	
+public:
+	CakRangeSettingNormalDlg* m_pRangeYSettingDlg;
+	CakRangeSettingNormalDlg* m_pRangeXSettingDlg;
+	bool m_bRangeYSetting;
+	bool m_bRangeXSetting;
+	bool m_bFastDrawAlg;
+	afx_msg void OnDestroy();
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+};
+
+
diff --git a/ReviewHistory/include/akGraph/akGraphLinker.h b/ReviewHistory/include/akGraph/akGraphLinker.h
new file mode 100644
index 0000000..08f5314
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphLinker.h
@@ -0,0 +1,69 @@
+#pragma once
+
+#include <afxext.h>         // MFC 익스텐션
+#include <afxwin.h> 
+
+#pragma comment(lib, "gdiplus.lib")
+#include <GdiPlus.h>
+using namespace Gdiplus;
+
+
+//#ifdef _akGraph
+//#include "resource.h"
+//#endif
+
+
+#ifndef _AKGRAPH_EXPORTS
+
+	#undef _AUTOLIBNAME
+	#undef _AKPROJECTNAME
+	#undef _AKVCVER
+	#undef _AKDEBUG
+
+	#define _AKPROJECTNAME "akGraph"
+	
+	#ifdef _DEBUG
+		#define _AKDEBUG "d"
+	#else
+		#define _AKDEBUG ""
+	#endif
+
+	#ifdef WIN64 
+		#define _AKX64 "_x64"
+	#elif _WIN64 
+		#define _AKX64 "_x64"
+	#else        
+		#define _AKX64 ""
+	#endif
+	
+	#if(_MSC_VER == 1200) //vs6.0
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER == 1300) //vs2003 vc7
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER == 1400) //vs2005 vc8
+		#define _AKVCVER "_vc8"
+	#elif(_MSC_VER == 1500) //vs2008 vc9
+		#define _AKVCVER "_vc9"
+	#elif(_MSC_VER == 1600) //vs2010
+		#define _AKVCVER "_vc10"
+	#elif(_MSC_VER == 1700) //vs2012
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER == 1800) //vs2013
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER >= 1910 && _MSC_VER < 1950) //vs2017 15.0
+		#define _AKVCVER "_vc15"
+	#else   
+		//#define _AKVCVER ""
+		#pragma message( "해당버전은 지원하지 않습니다. " _MSC_VER )
+		#error _MSC_VER 해당버전은 지원하지 않습니다.
+	#endif
+
+	#define _AUTOLIBNAME _AKPROJECTNAME""_AKDEBUG""_AKX64""_AKVCVER".lib"
+	
+	// You may turn off this include message by defining _NOPSAUTOLIB
+	#ifndef _NOPSAUTOLIBMSG
+	#pragma message( ">>Kim Tae Hyun - akGraph<< Will automatically link with " _AUTOLIBNAME )
+	#endif
+	#pragma comment(lib, _AUTOLIBNAME)
+#endif
+
diff --git a/ReviewHistory/include/akGraph/akGraphMesh.h b/ReviewHistory/include/akGraph/akGraphMesh.h
new file mode 100644
index 0000000..cffabc6
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphMesh.h
@@ -0,0 +1,106 @@
+#pragma once
+
+#include "akGraph/akGraphBase.h"
+#include "akGraph/akDataMesh.h"
+#include "akGraph/akColorTable.h"
+#include "akGraph/akColorTableOption.h"
+#include "akGraph/akRangeSettingNormalDlg.h"
+
+class AFX_EXT_CLASS CakGraphMesh : public CakGraphBase, public CakDataMesh
+{
+public:
+	CakGraphMesh(void);
+	virtual ~CakGraphMesh(void);
+
+public:
+	virtual BOOL CreateGraph(CWnd* pParent, CRect rect);
+
+	virtual void RenderDataArea(Graphics* grfx, CDC* pDC); //데이터 영역 그리기
+	virtual void RenderAxis(Graphics* grfx, CDC* pDC); //
+	virtual void RenderLabel(Graphics* grfx, CDC* pDC); //
+	virtual void RenderTitle(Graphics* grfx, CDC* pDC);
+	virtual void RenderEnd(Graphics* grfx, CDC* pDC);
+	virtual void RenderMouseHoverInfo(CDC* pDC);
+
+	virtual void OnKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point);
+	virtual void CaculatorGraphSize();
+
+	virtual void SetDataNum(int sizex, int sizey);
+
+	void SetReverseModeX(bool flag); //x축 역방향 표시
+	bool GetReverseModeX(){return m_bReverseX;}; //x축 역방향 표시
+	void SetReverseModeY(bool flag); //x축 역방향 표시
+	bool GetReverseModeY(){return m_bReverseY;}; //x축 역방향 표시
+
+	inline int GetWindowPosX(double xvalue); //위치 값에 따른 윈도우 좌표
+	inline int GetWindowPosY(double yvalue); //위치 값에 따른 윈도우 좌표
+	inline double GetValuePosDataX(int xpos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+	inline double GetValuePosDataY(int ypos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+
+	virtual void SetAutoScale();
+	
+	double GetDataValue(double posx, double posy);//
+	void CaculatorDataRange(double *min, double *max);
+
+	void SetColorTableFile(char* pFileName);
+	virtual BOOL ShowColorTableOptionDlg(CPoint point);
+protected:
+	
+protected:
+	bool m_bReverseX;
+	bool m_bReverseY;
+
+public:
+	double m_NoDataValue; //데이터가 없는 곳의 값 처리
+	
+
+	CakColorTableOptionDlg* m_pColorTableOption;
+	CakRangeSettingNormalDlg* m_pRangeXSettingDlg;
+	CakRangeSettingNormalDlg* m_pRangeYSettingDlg;
+
+	bool m_bRangeYSetting;
+	bool m_bRangeXSetting;
+
+	bool m_bDataMinAnti;
+	bool m_bDataMaxAnti;
+
+	CString m_strComment;//데이터 영역 우측 상단에 코멘트 표시
+protected:
+	CakColorTable m_ColorTable;
+	
+	//컬러테이블 관련
+public:
+	bool m_bColorBar;//색상바 표시 설정
+	bool m_bColorTableTickBar;
+	CakRect m_rectColorTablebar;
+	COLORREF m_ColorBarFontColor; //컬러바 폰트 컬러
+	int m_colorMin;
+	int m_colorMax;
+	int m_colorLevel;
+	int m_colorIndex;
+	bool m_colorInverse;
+	bool m_colorInterpolation;
+	bool m_colorAuto;
+	
+	
+public:
+	DECLARE_MESSAGE_MAP()
+	
+	afx_msg LRESULT OnColorTableOptionUpdate(WPARAM wParam, LPARAM lParam);
+
+	afx_msg LRESULT OnRangeSettingUpdate(WPARAM wParam, LPARAM lParam);
+	
+
+	
+protected:
+//	virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
+public:
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+//	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+
+
+	
+	
+};
diff --git a/ReviewHistory/include/akGraph/akGraphStruct.h b/ReviewHistory/include/akGraph/akGraphStruct.h
new file mode 100644
index 0000000..645672a
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphStruct.h
@@ -0,0 +1,290 @@
+#pragma once
+
+#include "akSTL/akRect.h"
+
+class AFX_EXT_CLASS CMaker
+{
+public:
+	CMaker()
+	{
+		m_nShape = 0;
+	};
+	~CMaker(){};
+
+public:
+	int m_nShape;
+
+};
+
+class AFX_EXT_CLASS CMouseMoveInfo
+{
+public:
+	CMouseMoveInfo()
+	{
+		m_bEnable = true;
+		m_font.CreatePointFont(90, _T("Tahoma"));
+		m_fontColor = RGB(255,255,255);
+		m_fontAlign = TA_RIGHT|TA_BASELINE;
+		m_nTypeNum = 2;
+		m_nType = 1;
+		m_nPositionType = 1;
+		
+		m_nPositionX = -10;
+		m_nPositionY = -10;
+
+	};
+	~CMouseMoveInfo(){};
+
+public:
+	bool m_bEnable;
+	int m_nType; //0마우스 위치값 표시, 1마우스 위치에 따른 데이터 값 표시
+	int m_nTypeNum;
+	CFont m_font; 
+	COLORREF m_fontColor;
+
+	int m_nPositionType; //0일때 아래 위치로 표시, 1일때 우측 하단
+	unsigned int m_fontAlign; //정렬
+	int m_nPositionX;//그리는 위치(나중에...)
+	int m_nPositionY;//그리는 위치(나중에...)
+};
+
+class AFX_EXT_CLASS CLegendOption
+{
+public:
+	CLegendOption()
+	{
+		m_bEnable = false;
+		m_font.CreatePointFont(90, _T("Tahoma"));
+		m_fontColor = RGB(0,0,0);
+		m_nType = 1;
+	};
+	~CLegendOption(){};
+
+public:
+	bool m_bEnable;
+	int m_nType; //-1:그리는 모양에 따라서 다르게, 0:선타입, 1:사각형, 2:동그라미
+	CFont m_font; 
+	COLORREF m_fontColor;
+	
+	int m_nPosition;//그리는 위치(나중에...)
+};
+
+class AFX_EXT_CLASS CSeries
+{
+public:
+	CSeries()
+	{
+		m_nType = 1;
+		for(int i=0; i<5; i++)
+		{
+			m_Color[i] = RGB(0,0,255);
+			m_nLineWidth[i] = 1;
+		}
+		memset(m_strLegend, 0, sizeof(char)*32);
+	};
+	~CSeries(){};
+
+public:
+	int m_nType; //1:선타입, 2:바타입, 3:믹스, 0:hide
+	int m_nLineWidth[5];
+	COLORREF m_Color[5];
+	char m_strLegend[32]; //제목
+
+
+};
+
+class AFX_EXT_CLASS CScroll
+{
+public:
+	CScroll()
+	{
+		m_nEnable = 0;
+		m_nSize = 25;
+
+		//m_bruScrollRect.CreateSolidBrush()
+		m_bSelected = false;
+	};
+
+public:
+	int m_nEnable; //0은 비사용, 1항상 사용, 2필요할때만 표시
+	int m_nSize; //표시 크기
+public:
+
+public:
+	double m_nScrollMin;
+	double m_nScrollMax;
+
+public:
+	CakRect m_rectScroll;
+	CakRect m_rectThumb;
+	bool m_bSelected;//마우스로 선택이 되었는지 체크 태현[2016/5/2]
+};
+
+class AFX_EXT_CLASS CAxis 
+{
+public:
+	CAxis()
+	{
+		m_RangeValueMin = 0;
+		m_RangeValueMax = 10;
+		m_Size = 50;
+		m_TickGabPixel = 50; 
+		m_TickGabStep = -1;
+		m_MinorTickNum = 3; 
+		m_FontTick.CreatePointFont(90, _T("Tahoma"));
+		m_strTitle = "Axis";
+		m_Font.CreatePointFont(90, _T("Tahoma"));
+		m_FontColor = RGB(0,0,0);
+		m_TickColor = RGB(0,0,0);
+		m_LabelColor = RGB(0,0,0);
+	}
+
+	void SetVerticalFont()
+	{
+		LOGFONT logfont; 
+		m_Font.GetLogFont(&logfont);
+		//logfont.lfHeight = 20;
+		logfont.lfEscapement = 900; 
+		m_Font.DeleteObject();
+		m_Font.CreateFontIndirect(&logfont);
+	}; //설정된 폰트를 세로로 바꾼다.
+
+	void SetRotateFont(CFont* pFont, int nDeg)
+	{
+		LOGFONT logfont; 
+		pFont->GetLogFont(&logfont);
+		//logfont.lfHeight = 20;
+		logfont.lfEscapement = nDeg*10; 
+		pFont->DeleteObject();
+		pFont->CreateFontIndirect(&logfont);
+	}; //설정된 폰트를 세로로 바꾼다.
+
+
+	inline double GetRangeValue()
+	{
+		return m_RangeValueMax - m_RangeValueMin;
+	}
+	inline void SetRangeMove(double dValue)//dValue만큼 움직임
+	{
+		m_RangeValueMin += dValue;
+		m_RangeValueMax += dValue;
+	}
+	inline void SetRangePos(double dValue)//해당 위치의 가운데로 이동
+	{
+		double dRangeHalf = GetRangeValue()/2.0;
+		m_RangeValueMin = dValue-dRangeHalf;
+		m_RangeValueMax = dValue+dRangeHalf;
+	}
+
+public:
+	double m_RangeValueMin; //데이터 범위
+	double m_RangeValueMax; //데이터 범위
+	int m_Size; //축 크기(x축은 세로크기, y축은 가로 크기)
+	
+	int m_TickGabPixel;	//라벨 & 틱이 표시되는 최소 픽셀 간격(라벨의 표시는 자동연산으로)
+	double m_TickGabStep;  //라벨과 틱이 표시되는 값의 간격
+	COLORREF m_TickColor;
+	int m_MinorTickNum;	//틱과 틱사이의 작은 틱 갯수
+	CFont m_FontTick; //폰트
+
+	CString m_strTitle; //제목
+
+	CFont m_Font; //폰트
+	COLORREF m_FontColor;
+	COLORREF m_LabelColor;
+	
+	CScroll m_Scroll;
+};
+
+class AFX_EXT_CLASS CTitle
+{
+public:
+	CTitle()
+	{
+		m_Size = 60;
+		m_strTitle = "Advance Kim Graph 2015";
+		m_Font.CreatePointFont(150, _T("맑은 고딕"));
+		m_FontColor = RGB(0,0,0);
+	}
+
+public:
+	CString m_strTitle;
+	int m_Size;
+	CFont m_Font; //폰트
+	COLORREF m_FontColor;
+};
+
+class AFX_EXT_CLASS CakMouseState
+{
+public:
+	CakMouseState()
+	{
+		bDragState = 0;
+		apply = false;
+		Point.SetPoint(0,0);
+		memset(MouseButtonState,0,sizeof(MouseButtonState));
+	}
+	inline void setPoint(CPoint pos)
+	{
+		//if(apply == true)
+		{
+			prePoint = Point;
+			Point = pos;
+			apply = false;
+		}
+		/*else
+		{
+		Point = pos;
+		}*/
+	}
+
+	bool apply;
+	CPoint Point; //현제 마우스 포인트
+	CPoint prePoint; //이전 마우스 포인트
+	CPoint stPointDrag;
+	bool MouseButtonState[10];
+	//마우스 드레그 관리 변수
+	int bDragState;//0:꺼짐 1:온 2:온->오프
+	CPoint ClickPointL;
+	CPoint ClickPointR;
+	CPoint DragEndPoint;//사각형이 그려진 부분 크기
+	
+};
+
+enum akMouseEvent
+{
+	MouseNone,
+	MouseMove,
+	MouseLeftButtonDown,
+	MouseLeftButtonUp,
+	MouseLeftButtonDoubleClick,
+	MouseMiddleButtonDown,
+	MouseMiddleButtonUp,
+	MouseMiddleButtonDoubleClick,
+	MouseRightButtonDown,
+	MouseRightButtonUp,
+	MouseRightButtonDoubleClick,
+	MouseWheelDown,
+	MouseWheelUp,
+	MouseLeftButtonDrag,
+	MouseRightButtonDrag
+};
+
+enum khMousetButtonState
+{
+	LEFTBUTTONDOWN,
+	RIGHTBUTTONDOWN,
+	WHEELUP,
+	WHEELDOWN
+};
+
+enum akDragStyle
+{
+	DS_None,	//없음
+	DS_All,		//모두
+	DS_All_VER,		//세로기준
+	DS_All_HOR,		//가로기준
+	DS_Vertical, //세로
+	DS_Horizontal,
+	DS_MAX
+};
diff --git a/ReviewHistory/include/akGraph/akGraphType2V.h b/ReviewHistory/include/akGraph/akGraphType2V.h
new file mode 100644
index 0000000..38a2923
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphType2V.h
@@ -0,0 +1,72 @@
+#pragma once
+
+#include "akGraph/akGraphBase.h"
+#include "akGraph/akDataVector2.h"
+
+#include "akGraph/akRangeSettingNormalDlg.h"
+#include "akGraph/akRangeSettingTimeDlg.h"
+
+//벡터 데이터를 쓰는 시리즈 한개뿐인 비등간격 데이터
+
+class AFX_EXT_CLASS CakGraphType2V : public CakGraphBase , public CakDataVector2
+{
+public:
+
+public:
+	CakGraphType2V(void);
+	virtual ~CakGraphType2V(void);
+
+
+	DECLARE_MESSAGE_MAP()
+public:
+	virtual BOOL CreateGraph(CWnd* pParent, CRect rect);
+	
+	virtual void RenderGrid(Graphics* grfx, CDC* pDC);
+	virtual void RenderDataArea(Graphics* grfx, CDC* pDC); //데이터 영역 그리기
+	virtual void RenderSeries(Graphics* grfx, CDC* pDC); //데이터 선/바 그리기
+	virtual void RenderAxis(Graphics* grfx, CDC* pDC); //축 영역 그리기
+	virtual void RenderTitle(Graphics* grfx, CDC* pDC); //제목 영역 그리기
+	virtual void RenderLabel(Graphics* grfx, CDC* pDC); //해당 축에 틱그리기, 데이터 영역 외각선 그리기
+	virtual void RenderEnd(Graphics* grfx, CDC* pDC); //그리는 부분 마지막에 추가(Redraw false 할때도 그림)
+
+	virtual void OnKeyInput(int key, int mode); //mode 0==keyup, mode 1==keydown
+	virtual void OnMouseInput(akMouseEvent mouseevent, CPoint point);
+	virtual void MouseInput(CakMouseState mousestate);
+
+	//데이터 클래스 동기화 객체 추가
+	virtual void Clear();
+	virtual bool SetData(int index, double x, double y); //들어있는 데이터 값 변경
+	virtual void AddData(double x, double y, int index = -1); //데이터 추가
+	virtual void SetHidden(bool enable, int startIndex, int endIndex);
+
+
+	inline int GetWindowPosX(double xvalue); //위치 값에 따른 윈도우 좌표
+	inline int GetWindowPosY(double yvalue); //위치 값에 따른 윈도우 좌표
+	inline double GetValuePosDataX(int xpos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+	inline double GetValuePosDataY(int ypos, bool dataArea = false); //윈도우 좌표에 따른 데이터 
+
+	void SetReverseModeX(bool flag); //x축 역방향 표시
+	bool GetReverseModeX(){return m_bReverseX;}; //x축 역방향 표시
+	void SetReverseModeY(bool flag); //y축 역방향 표시
+	bool GetReverseModeY(){return m_bReverseY;}; //y축 역방향 표시
+
+	void SetAxisXMode(bool flag){m_nAxisXMode = flag;};
+
+	virtual void SetAutoScale();
+
+	double GetYvalueByXposition(double xpos){return 0;};//미구현
+	
+	LRESULT OnRangeSettingNormalUpdate(WPARAM wParam, LPARAM lParam);
+	LRESULT OnRangeSettingTimeUpdate(WPARAM wParam, LPARAM lParam);
+
+
+private:
+	bool m_bGrid;
+	bool m_bReverseX;
+	bool m_bReverseY;
+	int m_nAxisXMode; //0:일반 모드, 1:초단위 시간표시, 2:ms단위 시간표시
+public:
+	CakRangeSettingNormalDlg* m_pRangeYSettingDlg;
+	CakRangeSettingNormalDlg* m_pRangeXSettingDlg;
+	afx_msg void OnDestroy();
+};
diff --git a/ReviewHistory/include/akGraph/akGraphUtil.h b/ReviewHistory/include/akGraph/akGraphUtil.h
new file mode 100644
index 0000000..c23daf9
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akGraphUtil.h
@@ -0,0 +1,61 @@
+#pragma once
+
+#include "akGraph/akGraphLinker.h"
+#include "akSTL/akStruct.h"
+
+
+
+#define AKSWAP_INT(a,b) { int t=a; a=b; b=t; }
+#define AKSWAP_DOUBLE(a,b) { double t=a; a=b; b=t; }
+#define AKSWAP_FLOAT(a,b) { float t=a; a=b; b=t; }
+
+class AFX_EXT_CLASS CakGraphUtil
+{
+public:
+	CakGraphUtil(void);
+	~CakGraphUtil(void);
+
+	static CakRect SetakRectAlign(CakRect rect); //왼쪽이 작은값 윗쪽이 작은값 순으로 바꾼다.
+	static bool GetCheckInArea(CakRect rect, double x, double y);//현재 영역안에 점이 있는지 검사
+	static bool GetCheckInArea(double x1, double y1, double x2, double y2, double x, double y);//현재 영역안에 점이 있는지 검사
+	static bool GetCheckInRangeX(CakRect rect, double x1); //한선상의 점이 해당 범위 안에 있는지 검사
+	static bool GetCheckInRangeY(CakRect rect, double y1); //한선상의 점이 해당 범위 안에 있는지 검사
+	static bool GetCheckInRange(double x1, double x2, double p1); //한선상의 점이 해당 범위 안에 있는지 검사
+	
+	static CRect akRectToCRect(CakRect rect);
+	
+	static BOOL GetEncCLSID(WCHAR *mime, CLSID *pClsid);
+
+	//DC를 받아서 이미지 파일로 제작(0:jpg, 1:bmp);
+	static bool MakeImageFile(CDC* pDC, char* filename, unsigned int imageformat=0);
+
+	static void CalculationTickPostionNormal(
+		double minval,				//최소값
+		double maxval,				//최대값
+		unsigned int length,					//윈도우 길이
+		unsigned int limitLength,			//최소 윈도우 길이
+		OUT double* tickgabval,		//값들의 간격
+		OUT int* decimal			//소수점이하자릿수
+		);			
+	static void CalculationTickPostionTime(
+		double minval,				//최소값
+		double maxval,				//최대값
+		unsigned int length,					//
+		unsigned int limitLength,			//
+		OUT double* tickgabval		//값들의 간격
+		);			
+	static void CalculationTickPostionMSecTime(
+		double minval,				
+		double maxval, 
+		unsigned int length, 
+		unsigned int limitLength, 
+		OUT double* tickgabval
+		);
+	static void CalculationTickPostionDegree(
+		double minval,
+		double maxval,
+		int length,
+		int limitLength, 
+		OUT double* tickgabval 
+		);
+};
diff --git a/ReviewHistory/include/akGraph/akMemDC.h b/ReviewHistory/include/akGraph/akMemDC.h
new file mode 100644
index 0000000..ff23d8e
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akMemDC.h
@@ -0,0 +1,90 @@
+
+#pragma once
+
+
+class CakMemDC : public CDC
+{
+public:
+
+	CakMemDC(CDC* pDC, CRect rectDC) : CDC()
+	{
+		ASSERT(pDC != NULL);
+
+		m_pDC = pDC;
+		m_pOldBitmap = NULL;
+		m_bMemDC = false;
+		m_hDC = NULL;
+		if(pDC == NULL)
+		{
+			CreateCompatibleDC(pDC);
+			return;
+		}
+
+#ifndef WCE_NO_PRINTING
+		m_bMemDC = !pDC->IsPrinting();
+#else
+		m_bMemDC = FALSE;
+#endif
+
+		if (m_bMemDC)    
+		{
+			//pDC->GetClipBox(&m_rect);
+			m_rect = rectDC;
+			CreateCompatibleDC(pDC);
+			m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
+			m_pOldBitmap = SelectObject(&m_bitmap);
+#ifndef _WIN32_WCE
+			//SetWindowOrg(m_rect.left, m_rect.top);
+			SetWindowOrg(0,0);
+#endif
+			FillSolidRect(m_rect, pDC->GetBkColor());
+		}
+		else   
+		{
+#ifndef WCE_NO_PRINTING
+			m_bPrinting = pDC->m_bPrinting;
+#endif
+			m_hDC       = pDC->m_hDC;
+			m_hAttribDC = pDC->m_hAttribDC;
+		}
+
+	}
+
+	virtual ~CakMemDC()
+	{
+		if (m_bMemDC)
+		{
+			m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.right, m_rect.bottom,
+				this, m_rect.left, m_rect.top, SRCCOPY);
+			
+
+			SelectObject(m_pOldBitmap);
+			//DeleteDC(); 
+			//m_bitmap.DeleteObject();
+			
+		}
+		else
+		{
+			m_hDC = m_hAttribDC = NULL;
+		}
+	}
+
+	CakMemDC* operator->()
+	{
+		return this;
+	}
+
+	operator CakMemDC*()
+	{
+		return this;
+	}
+
+private:
+	CBitmap  m_bitmap;      // Offscreen bitmap
+	CBitmap* m_pOldBitmap;  // bitmap originally found in CakMemDC
+	CDC*     m_pDC;         // Saves CDC passed in constructor
+	BOOL     m_bMemDC;      // TRUE if CDC really is a Memory DC.
+public:
+	CRect    m_rect;        // Rectangle of drawing area.
+}
+;
diff --git a/ReviewHistory/include/akGraph/akPixel.h b/ReviewHistory/include/akGraph/akPixel.h
new file mode 100644
index 0000000..4f92f9d
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akPixel.h
@@ -0,0 +1,34 @@
+#pragma once
+
+#include "akGraph/akGraphLinker.h"
+
+class AFX_EXT_CLASS CakPixel
+{
+public:
+	CakPixel(CDC* pSrc);
+	~CakPixel();
+	COLORREF GetPixel(int x, int y);
+	BYTE* GetPixelSrc(int x, int y);
+
+	LPVOID	GetBitmapBits(){return m_pBits;};
+	BITMAPINFO* GetBitmapInfo(){return m_pbmi;};
+
+protected:
+	CakPixel();
+	LPVOID m_pBits; 
+	int m_nBytePerLine;
+	BITMAPINFO* m_pbmi;
+	int m_nDepth;
+
+	COLORREF (CakPixel::*m_pGetPixel)(int x, int y);
+
+	COLORREF GetPixel8(int x, int y);
+
+	COLORREF GetPixel16(int x, int y);
+	COLORREF GetPixel24(int x, int y);
+	COLORREF GetPixel32(int x, int y);
+
+	COLORREF GetPixel16ByTable555(int x, int y);
+	COLORREF GetPixel16ByTable565(int x, int y);
+	COLORREF GetPixel32ByTable(int x, int y);
+};
\ No newline at end of file
diff --git a/ReviewHistory/include/akGraph/akRangeSettingDlg.h b/ReviewHistory/include/akGraph/akRangeSettingDlg.h
new file mode 100644
index 0000000..c7d34ff
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akRangeSettingDlg.h
@@ -0,0 +1,58 @@
+#pragma once
+
+//#define IDD_AKCOLORTABLEOPTIONDLG 11000
+
+#include "akGraph/akResource.h"
+#include "akGraph/akGraphBase.h"
+
+// CakRangeSettingDlg 대화 상자입니다.
+#define RANGESETTINGUPDATE WM_USER+0x101
+
+
+
+class CakRangeSettingDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakRangeSettingDlg)
+
+public:
+	CakRangeSettingDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakRangeSettingDlg();
+
+// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKRANGESETTINGDLG };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+	virtual BOOL OnInitDialog();
+
+public:
+	void SetUpdate();
+public:
+	CWnd* m_pParent;
+
+	CEdit		m_ctrlEditXMin;
+	CEdit		m_ctrlEditXMax;
+	CEdit		m_ctrlEditYMin;
+	CEdit		m_ctrlEditYMax;
+	
+	double m_RangeXMin;
+	double m_RangeXMax;
+	double m_RangeYMin;
+	double m_RangeYMax;
+
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+
+private:
+
+
+public:
+	afx_msg void OnBnClickedCancel();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+};
diff --git a/ReviewHistory/include/akGraph/akRangeSettingNormalDlg.h b/ReviewHistory/include/akGraph/akRangeSettingNormalDlg.h
new file mode 100644
index 0000000..86db602
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akRangeSettingNormalDlg.h
@@ -0,0 +1,56 @@
+#pragma once
+
+
+
+
+#include "akGraph/akGraphLinker.h"
+#include "akGraph/akResource.h"
+
+
+#define RANGESETTINGNORMALUPDATE WM_USER+0x106
+
+
+class CakRangeSettingNormalDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakRangeSettingNormalDlg)
+
+public:
+	CakRangeSettingNormalDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakRangeSettingNormalDlg();
+
+// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKRANGESETTINGDLG_NORMAL };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+public:
+	void SetUpdateData(bool bToVariable); //true --> 변수로 저장, false-->다이얼로그에 표시
+	void SetTitle(char* strTitle);
+	void SetReverse(bool bReverse);
+public:
+	double m_RangeMin;
+	double m_RangeMax;
+	
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+	
+	int m_nID;
+private:
+	CString m_strTitle;
+	CWnd* m_pParent;
+	bool m_bReverse;//최대, 최소 반대로 설정
+
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+	
+	virtual BOOL OnInitDialog();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	virtual BOOL DestroyWindow();
+	
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+};
diff --git a/ReviewHistory/include/akGraph/akRangeSettingTimeDlg.h b/ReviewHistory/include/akGraph/akRangeSettingTimeDlg.h
new file mode 100644
index 0000000..58b3e02
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akRangeSettingTimeDlg.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "akGraph/akGraphLinker.h"
+#include "akGraph/akResource.h"
+
+
+#define RANGESETTINGTIMEUPDATE WM_USER+0x107
+
+class CakRangeSettingTimeDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakRangeSettingTimeDlg)
+
+public:
+	CakRangeSettingTimeDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakRangeSettingTimeDlg();
+
+	// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKRANGESETTINGDLG_TIME };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+public:
+	void SetUpdateData(bool bToVariable); //true --> 변수로 저장, false-->다이얼로그에 표시
+	void SetTitle(char* strTitle);
+	void SetReverse(bool bReverse);
+public:
+	int m_RangeMin;
+	int m_RangeMax;
+
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+
+private:
+	CString m_strTitle;
+	CWnd* m_pParent;
+	bool m_bReverse;//최대, 최소 반대로 설정
+
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+
+	virtual BOOL OnInitDialog();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+	virtual BOOL DestroyWindow();
+
+};
diff --git a/ReviewHistory/include/akGraph/akRaySettingDlg.h b/ReviewHistory/include/akGraph/akRaySettingDlg.h
new file mode 100644
index 0000000..19b25fa
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akRaySettingDlg.h
@@ -0,0 +1,58 @@
+#pragma once
+
+//#define IDD_AKCOLORTABLEOPTIONDLG 11000
+
+#include "akGraph/akResource.h"
+#include "akGraph/akGraphBase.h"
+
+// CakRaySettingDlg 대화 상자입니다.
+#define RAYSETTINGUPDATE WM_USER+0x102
+
+
+
+class CakRaySettingDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakRaySettingDlg)
+
+public:
+	CakRaySettingDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakRaySettingDlg();
+
+// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKRAYESETTINGDLG };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+	virtual BOOL OnInitDialog();
+	void setFAIMS3Mode();
+public:
+	
+public:
+	CWnd* m_pParent;
+
+	void SetUpdate(); //현제 데이터를 화면에 전시
+
+	CEdit		m_ctrlRayNum;
+	CEdit		m_ctrlRayMin;
+	CEdit		m_ctrlRayMax;
+	
+	int m_RayNum;
+	int m_RayMin;
+	int m_RayMax;
+
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+	
+private:
+
+
+public:
+	afx_msg void OnBnClickedCancel();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+};
diff --git a/ReviewHistory/include/akGraph/akResource.h b/ReviewHistory/include/akGraph/akResource.h
new file mode 100644
index 0000000..e19c4ec
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akResource.h
@@ -0,0 +1,89 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by akGraph.rc
+//
+#define IDD_AKCOLORTABLEOPTIONDLG       11000
+#define IDC_CHECK_COLORINVERSE          11000
+#define IDC_CHECK_COLORINTERPOLATION    11001
+#define IDD_AKRANGESETTINGDLG           11001
+#define IDC_EDIT_COLORMIN               11002
+#define IDD_AKSELECTDATADLG             11002
+#define IDC_EDIT_COLORMAX               11003
+#define IDD_AKRAYESETTINGDLG            11003
+#define IDC_COMBO_COLORLEVEL            11004
+#define IDC_EDIT_COLORMIN2              11004
+#define IDC_EDIT_RANGEMINY              11004
+#define IDD_AKDDSETTINGDLG              11004
+#define IDC_COMBO_COLORINDEX            11005
+#define IDC_EDIT_COLORMAX2              11005
+#define IDC_AK_COMBO_DATA               11005
+#define IDC_EDIT_RANGEMAXY              11005
+#define IDC_EDIT_RAYNUM                 11006
+#define IDC_CHECK_COLORAUTORANGE        11006
+#define IDD_AKRANGESETTINGDLG_NORMAL    11007
+#define IDC_EDIT_RAYMIN                 11008
+#define IDC_EDIT_RAYMAX                 11009
+#define IDC_EDIT_RANGEMINX              11010
+#define IDC_EDIT_RANGEMAXX              11011
+#define IDC_SELECTDATA_COLOR1           11012
+#define IDC_EDIT_GRAPHDEPTH1            11012
+#define IDC_SELECTDATA_COLOR2           11013
+#define IDC_EDIT_GRAPHDEPTH2            11013
+#define IDC_EDIT_RANGEMAX               11013
+#define IDC_SELECTDATA_COLOR3           11014
+#define IDC_EDIT_GRAPHDEPTH3            11014
+#define IDC_EDIT_RANGEMIN               11014
+#define IDC_SELECTDATA_COLOR4           11015
+#define IDC_EDIT_RANGEMINX5             11015
+#define IDC_EDIT_GRAPHDEPTH4            11015
+#define IDC_AK_TITLE                    11015
+#define IDC_EDIT_DDSTD                  11016
+#define IDC_AK_CMT1                     11016
+#define IDC_AK_TITLE3                   11016
+#define IDD_RANGESETTINGTIMEDLG         11017
+#define IDD_AKRANGESETTINGDLG_TIME      11017
+#define IDC_AK_CMT2                     11017
+#define IDC_AK_TITLE2                   11017
+#define IDC_AK_CMT3                     11018
+#define IDC_DETECTPOINT1_1              11018
+#define IDD_AKCOLORSETTINGDLG           11018
+#define IDC_AK_CMT4                     11019
+#define IDC_DETECTPOINT2_1              11019
+#define IDC_DETECTPOINT3_1              11020
+#define IDC_DETECTPOINT4_1              11021
+#define IDC_AK_CMT3_3                   11022
+#define IDC_DETECTPOINT1_2              11023
+#define IDC_DETECTPOINT2_2              11024
+#define IDC_DETECTPOINT3_2              11025
+#define IDC_DETECTPOINT4_2              11026
+#define IDC_DETECTPOINT1_3              11027
+#define IDC_DETECTPOINT2_3              11028
+#define IDC_DETECTPOINT3_3              11029
+#define IDC_DETECTPOINT4_3              11030
+#define IDC_AK_CMT3_4                   11031
+#define IDC_AK_CMT3_5                   11032
+#define IDC_AK_CMT3_6                   11033
+#define IDC_AK_CMT3_7                   11034
+#define IDC_AK_CMT3_8                   11035
+#define IDC_AK_CMT3_9                   11036
+#define IDC_AK_CMT2_1                   11037
+#define IDC_AK_CMT3_1                   11038
+#define IDC_AK_CMT3_2                   11039
+#define IDC_AK_UNIT1                    11040
+#define IDC_AK_UNIT2                    11041
+#define IDC_AK_UNIT3                    11042
+#define IDC_AK_UNIT4                    11043
+#define IDC_EDIT_COLOR_R                11046
+#define IDC_EDIT_COLOR_G                11047
+#define IDC_EDIT_COLOR_B                11048
+
+// Next default values for new objects
+// 
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE        11001
+#define _APS_NEXT_COMMAND_VALUE         32771
+#define _APS_NEXT_CONTROL_VALUE         11048
+#define _APS_NEXT_SYMED_VALUE           11018
+#endif
+#endif
diff --git a/ReviewHistory/include/akGraph/akSelectDataDlg.h b/ReviewHistory/include/akGraph/akSelectDataDlg.h
new file mode 100644
index 0000000..268d316
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akSelectDataDlg.h
@@ -0,0 +1,59 @@
+#pragma once
+
+//#define IDD_AKCOLORTABLEOPTIONDLG 11000
+
+#include "akGraph/akResource.h"
+#include "akGraph/akGraphBase.h"
+
+// CakSelectDataDlg 대화 상자입니다.
+#define SELECTDATAUPDATE WM_USER+0x103
+
+
+
+class CakSelectDataDlg : public CDialog
+{
+	DECLARE_DYNAMIC(CakSelectDataDlg)
+
+public:
+	CakSelectDataDlg(CWnd* pParent = NULL);   // 표준 생성자입니다.
+	virtual ~CakSelectDataDlg();
+
+// 대화 상자 데이터입니다.
+	enum { IDD = IDD_AKSELECTDATADLG };
+
+protected:
+	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV 지원입니다.
+
+	DECLARE_MESSAGE_MAP()
+public:
+	afx_msg void OnBnClickedOk();
+	virtual BOOL OnInitDialog();
+
+public:
+	void SetUpdate();
+public:
+	CWnd* m_pParent;
+
+	CComboBox	m_ctrlSelectData;
+
+	COLORREF	m_SelectColor;
+	int m_selectData;
+	int m_selectedAxisY;
+	
+	CFont m_fontTitle, m_fontText;
+	CBrush m_bruTitle, m_bruText;
+
+private:
+
+
+public:
+	afx_msg void OnBnClickedCancel();
+	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+	afx_msg void OnBnClickedButton1();
+	afx_msg void OnBnClickedSelectdataColor1();
+	afx_msg void OnBnClickedSelectdataColor2();
+	afx_msg void OnBnClickedSelectdataColor3();
+	afx_msg void OnBnClickedSelectdataColor4();
+	afx_msg void OnPaint();
+	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
+};
diff --git a/ReviewHistory/include/akGraph/akSyncObject.h b/ReviewHistory/include/akGraph/akSyncObject.h
new file mode 100644
index 0000000..bd36270
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akSyncObject.h
@@ -0,0 +1,31 @@
+#pragma once
+
+
+
+
+class AFX_EXT_CLASS CakSyncObject
+{
+public:
+	CakSyncObject(void);
+	virtual ~CakSyncObject(void);
+
+public:
+	//읽기 지정을 하였을때... 이미 어디서 쓰고 있다면.. 기다렸다가 다음을 수행한다.
+	//bWait = false 일경우.. 어딘가에서 쓰고 있다면 false를 반환하고 끝내버린다.
+	bool SetRead(bool bWait = true);  
+	//쓰기 지정을 하였을때... 이미 어디서 읽고 있다면.. 기다렸다가 다음을 수행한다.
+	bool SetWrite(bool bWait = true);
+	int SetReadRelease(); //현재 남아있는 읽기 카운트 반환
+	void SetWriteRelease();
+
+	int GetReadCount(){return m_nReadCount;}; //읽기 호출한 횟수 반환
+	bool GetWriteState(){return m_bWrite;}; //0이 될때까지 그리는 루틴은 무한 루프가 돈다.
+	
+
+protected:
+	
+private:
+	bool m_bWrite; 
+	int m_nReadCount;
+	
+};
diff --git a/ReviewHistory/include/akGraph/akUnit.h b/ReviewHistory/include/akGraph/akUnit.h
new file mode 100644
index 0000000..4ad7abc
--- /dev/null
+++ b/ReviewHistory/include/akGraph/akUnit.h
@@ -0,0 +1,37 @@
+#pragma once
+
+
+// enum khUnitType
+// {
+// 	Distance,
+// 	Velocity,
+// 	Temp,
+// 	Weight
+// };
+
+enum akUnit
+{
+	km,m,kyd,ft
+};
+
+class CakUnit
+{
+public:
+	CakUnit(void);
+	virtual ~CakUnit(void);
+
+
+public:
+	//void SetUnitType(khUnitType type);
+	void SetDefaultUnit(int index, akUnit unit);
+	bool SetChangeUnit(int index, akUnit unit);
+
+public:
+	char* GetCurrentUnitString(int index);
+	char* GetUnitString(int index, akUnit unit);
+
+protected:
+	akUnit m_DefaultUnit[10];//기준 단위
+	akUnit m_ChangeUnit[10];//변경되는 단위
+
+};
diff --git a/ReviewHistory/include/akGraph/khDataBase.h b/ReviewHistory/include/akGraph/khDataBase.h
new file mode 100644
index 0000000..94d49a1
--- /dev/null
+++ b/ReviewHistory/include/akGraph/khDataBase.h
@@ -0,0 +1,14 @@
+#pragma once
+
+
+#include "akGraph/khSyncObject.h"
+
+class AFX_EXT_CLASS CkhDataBase
+{
+public:
+	CkhDataBase(void);
+	virtual ~CkhDataBase(void);
+
+public:
+	CkhSyncObject m_khSyncObject;
+};
diff --git a/ReviewHistory/include/akGridCtrl/CellRange.h b/ReviewHistory/include/akGridCtrl/CellRange.h
new file mode 100644
index 0000000..9d96b4b
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/CellRange.h
@@ -0,0 +1,148 @@
+///////////////////////////////////////////////////////////////////////
+// CellRange.h: header file
+//
+// MFC Grid Control - interface for the CCellRange class.
+//
+// Written by Chris Maunder <cmaunder@mail.com>
+// Copyright (c) 1998-2002. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.20+
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_)
+#define AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+// The code contained in this file is based on the original
+// WorldCom Grid control written by Joe Willcoxson,
+//      mailto:chinajoe@aol.com
+//      http://users.aol.com/chinajoe
+
+class CCellID
+{    
+// Attributes
+public:
+    int row, col;
+
+// Operations
+public:
+    explicit CCellID(int nRow = -1, int nCol = -1) : row(nRow), col(nCol) {}
+
+    int IsValid() const { return (row >= 0 && col >= 0); }
+    int operator==(const CCellID& rhs) const { return (row == rhs.row && col == rhs.col); }
+    int operator!=(const CCellID& rhs) const { return !operator==(rhs); }
+};
+
+class CCellRange
+{ 
+public:
+    
+    CCellRange(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1)
+    {
+        Set(nMinRow, nMinCol, nMaxRow, nMaxCol);
+    }
+
+    void Set(int nMinRow = -1, int nMinCol = -1, int nMaxRow = -1, int nMaxCol = -1);
+    
+    int  IsValid() const;
+    int  InRange(int row, int col) const;
+    int  InRange(const CCellID& cellID) const;
+    int  Count() { return (m_nMaxRow - m_nMinRow + 1) * (m_nMaxCol - m_nMinCol + 1); }
+    
+    CCellID  GetTopLeft() const;
+    CCellRange  Intersect(const CCellRange& rhs) const;
+    
+    int GetMinRow() const {return m_nMinRow;}
+    void SetMinRow(int minRow) {m_nMinRow = minRow;}
+    
+    int GetMinCol() const {return m_nMinCol;}
+    void SetMinCol(int minCol) {m_nMinCol = minCol;}
+    
+    int GetMaxRow() const {return m_nMaxRow;}
+    void SetMaxRow(int maxRow) {m_nMaxRow = maxRow;}
+    
+    int GetMaxCol() const {return m_nMaxCol;}
+    void SetMaxCol(int maxCol) {m_nMaxCol = maxCol;}
+
+    int GetRowSpan() const {return m_nMaxRow - m_nMinRow + 1;}
+    int GetColSpan() const {return m_nMaxCol - m_nMinCol + 1;}
+    
+    void operator=(const CCellRange& rhs);
+    int  operator==(const CCellRange& rhs);
+    int  operator!=(const CCellRange& rhs);
+    
+protected:
+    int m_nMinRow;
+    int m_nMinCol;
+    int m_nMaxRow;
+    int m_nMaxCol;
+};
+
+inline void CCellRange::Set(int minRow, int minCol, int maxRow, int maxCol)
+{
+     m_nMinRow = minRow;
+     m_nMinCol = minCol;
+     m_nMaxRow = maxRow;
+     m_nMaxCol = maxCol;
+}
+
+inline void CCellRange::operator=(const CCellRange& rhs)
+{
+    if (this != &rhs) Set(rhs.m_nMinRow, rhs.m_nMinCol, rhs.m_nMaxRow, rhs.m_nMaxCol);
+}
+
+inline int CCellRange::operator==(const CCellRange& rhs)
+{
+     return ((m_nMinRow == rhs.m_nMinRow) && (m_nMinCol == rhs.m_nMinCol) &&
+             (m_nMaxRow == rhs.m_nMaxRow) && (m_nMaxCol == rhs.m_nMaxCol));
+}
+
+inline int CCellRange::operator!=(const CCellRange& rhs)
+{
+     return !operator==(rhs);
+}
+
+inline int CCellRange::IsValid() const
+{
+     return (m_nMinRow >= 0 && m_nMinCol >= 0 && m_nMaxRow >= 0 && m_nMaxCol >= 0 &&
+             m_nMinRow <= m_nMaxRow && m_nMinCol <= m_nMaxCol);
+}
+
+inline int CCellRange::InRange(int row, int col) const
+{
+     return (row >= m_nMinRow && row <= m_nMaxRow && col >= m_nMinCol && col <= m_nMaxCol);
+}
+
+inline int CCellRange::InRange(const CCellID& cellID) const
+{
+     return InRange(cellID.row, cellID.col);
+}
+
+inline CCellID CCellRange::GetTopLeft() const
+{
+     return CCellID(m_nMinRow, m_nMinCol);
+}
+
+inline CCellRange CCellRange::Intersect(const CCellRange& rhs) const
+{
+     return CCellRange(max(m_nMinRow,rhs.m_nMinRow), max(m_nMinCol,rhs.m_nMinCol),
+                       min(m_nMaxRow,rhs.m_nMaxRow), min(m_nMaxCol,rhs.m_nMaxCol));
+}
+
+#endif // !defined(AFX_CELLRANGE_H__F86EF761_725A_11D1_ABBA_00A0243D1382__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/GridCell.h b/ReviewHistory/include/akGridCtrl/GridCell.h
new file mode 100644
index 0000000..335e6a6
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/GridCell.h
@@ -0,0 +1,143 @@
+/////////////////////////////////////////////////////////////////////////////
+// GridCell.h : header file
+//
+// MFC Grid Control - Grid cell class header file
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.20+
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
+#define AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+class CakGridCtrl;
+#include "GridCellBase.h"
+
+// Each cell contains one of these. Fields "row" and "column" are not stored since we
+// will usually have acces to them in other ways, and they are an extra 8 bytes per
+// cell that is probably unnecessary.
+
+class CGridCell : public CGridCellBase
+{
+    friend class CakGridCtrl;
+    DECLARE_DYNCREATE(CGridCell)
+
+// Construction/Destruction
+public:
+    CGridCell();
+    virtual ~CGridCell();
+
+// Attributes
+public:
+    void operator=(const CGridCell& cell);
+
+    virtual void  SetText(LPCTSTR szText)        { m_strText = szText;  }                       
+    virtual void  SetImage(int nImage)           { m_nImage = nImage;   }                        
+    virtual void  SetData(LPARAM lParam)         { m_lParam = lParam;   }      
+    virtual void  SetGrid(CakGridCtrl* pGrid)      { m_pGrid = pGrid;     }                          
+    // virtual void SetState(const DWORD nState);  -  use base class version   
+    virtual void  SetFormat(DWORD nFormat)       { m_nFormat = nFormat; }                      
+    virtual void  SetTextClr(COLORREF clr)       { m_crFgClr = clr;     }                          
+    virtual void  SetBackClr(COLORREF clr)       { m_crBkClr = clr;     }                          
+    virtual void  SetFont(const LOGFONT* plf);
+    virtual void  SetMargin(UINT nMargin)        { m_nMargin = nMargin; }
+    virtual CWnd* GetEditWnd() const             { return m_pEditWnd;   }
+    virtual void  SetCoords(int /*nRow*/, int /*nCol*/) {}  // don't need to know the row and
+                                                            // column for base implementation
+
+    virtual LPCTSTR     GetText() const             { return (m_strText.IsEmpty())? _T("") : LPCTSTR(m_strText); }
+    virtual int         GetImage() const            { return m_nImage;  }
+    virtual LPARAM      GetData() const             { return m_lParam;  }
+    virtual CakGridCtrl*  GetGrid() const             { return m_pGrid;   }
+    // virtual DWORD    GetState() const - use base class
+    virtual DWORD       GetFormat() const;
+    virtual COLORREF    GetTextClr() const          { return m_crFgClr; } // TODO: change to use default cell
+    virtual COLORREF    GetBackClr() const          { return m_crBkClr; }
+    virtual LOGFONT*    GetFont() const;
+    virtual CFont*      GetFontObject() const;
+    virtual UINT        GetMargin() const;
+
+    virtual BOOL        IsEditing() const           { return m_bEditing; }
+    virtual BOOL        IsDefaultFont() const       { return (m_plfFont == NULL); }
+    virtual void        Reset();
+
+// editing cells
+public:
+    virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
+    virtual void EndEdit();
+protected:
+    virtual void OnEndEdit();
+
+protected:
+    CString    m_strText;      // Cell text (or binary data if you wish...)
+    LPARAM     m_lParam;       // 32-bit value to associate with item
+    int        m_nImage;       // Index of the list view item뭩 icon
+    DWORD      m_nFormat;
+    COLORREF   m_crFgClr;
+    COLORREF   m_crBkClr;
+    LOGFONT*   m_plfFont;
+    UINT       m_nMargin;
+
+    BOOL       m_bEditing;     // Cell being edited?
+
+    CakGridCtrl* m_pGrid;        // Parent grid control
+    CWnd*      m_pEditWnd;
+};
+
+// This class is for storing grid default values. It's a little heavy weight, so
+// don't use it in bulk 
+class CGridDefaultCell : public CGridCell
+{
+    DECLARE_DYNCREATE(CGridDefaultCell)
+
+// Construction/Destruction
+public:
+    CGridDefaultCell();
+    virtual ~CGridDefaultCell();
+
+public:
+    virtual DWORD GetStyle() const                      { return m_dwStyle;      }
+    virtual void  SetStyle(DWORD dwStyle)               { m_dwStyle = dwStyle;   }
+    virtual int   GetWidth() const                      { return m_Size.cx;      }
+    virtual int   GetHeight() const                     { return m_Size.cy;      }
+    virtual void  SetWidth(int nWidth)                  { m_Size.cx = nWidth;    }
+    virtual void  SetHeight(int nHeight)                { m_Size.cy = nHeight;   }
+
+    // Disable these properties
+    virtual void     SetData(LPARAM /*lParam*/)             { ASSERT(FALSE);         }      
+    virtual void     SetState(DWORD /*nState*/)             { ASSERT(FALSE);         }
+    virtual DWORD    GetState() const                       { return CGridCell::GetState()|GVIS_READONLY; }
+    virtual void     SetCoords( int /*row*/, int /*col*/)   { ASSERT(FALSE);         }
+    virtual void     SetFont(const LOGFONT* /*plf*/);
+    virtual LOGFONT* GetFont() const;   
+    virtual CFont*   GetFontObject() const;
+
+protected:
+    CSize m_Size;       // Default Size
+    CFont m_Font;       // Cached font
+    DWORD m_dwStyle;    // Cell Style - unused
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GRIDCELL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/GridCellBase.h b/ReviewHistory/include/akGridCtrl/GridCellBase.h
new file mode 100644
index 0000000..0fb94d6
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/GridCellBase.h
@@ -0,0 +1,175 @@
+/////////////////////////////////////////////////////////////////////////////
+// GridCellBase.h : header file
+//
+// MFC Grid Control - Grid cell base class header file
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.22+
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
+#define AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+class CakGridCtrl;
+
+// Cell states
+#define GVIS_FOCUSED            0x0001
+#define GVIS_SELECTED           0x0002
+#define GVIS_DROPHILITED        0x0004
+#define GVIS_READONLY           0x0008
+#define GVIS_FIXED              0x0010
+#define GVIS_FIXEDROW           0x0020
+#define GVIS_FIXEDCOL           0x0040
+#define GVIS_MODIFIED           0x0080
+
+// Cell data mask
+#define GVIF_TEXT               LVIF_TEXT
+#define GVIF_IMAGE              LVIF_IMAGE
+#define GVIF_PARAM              LVIF_PARAM
+#define GVIF_STATE              LVIF_STATE
+#define GVIF_BKCLR              (GVIF_STATE<<1)
+#define GVIF_FGCLR              (GVIF_STATE<<2)
+#define GVIF_FORMAT             (GVIF_STATE<<3)
+#define GVIF_FONT               (GVIF_STATE<<4)
+#define GVIF_MARGIN             (GVIF_STATE<<5)
+#define GVIF_ALL                (GVIF_TEXT|GVIF_IMAGE|GVIF_PARAM|GVIF_STATE|GVIF_BKCLR|GVIF_FGCLR| \
+                                 GVIF_FORMAT|GVIF_FONT|GVIF_MARGIN)
+
+// Used for Get/SetItem calls.
+typedef struct _GV_ITEM {
+    int      row,col;     // Row and Column of item
+    UINT     mask;        // Mask for use in getting/setting cell data
+    UINT     nState;      // cell state (focus/hilighted etc)
+    DWORD    nFormat;     // Format of cell
+    int      iImage;      // index of the list view item뭩 icon
+    COLORREF crBkClr;     // Background colour (or CLR_DEFAULT)
+    COLORREF crFgClr;     // Forground colour (or CLR_DEFAULT)
+    LPARAM   lParam;      // 32-bit value to associate with item
+    LOGFONT  lfFont;      // Cell font
+    UINT     nMargin;     // Internal cell margin
+    CString  strText;     // Text in cell
+} GV_ITEM;
+
+
+// Each cell contains one of these. Fields "row" and "column" are not stored since we
+// will usually have acces to them in other ways, and they are an extra 8 bytes per
+// cell that is probably unnecessary.
+
+#define TRACEAK(fmt,...)
+//#define TRACEAK(fmt,...) TRACEAK(fmt,##__VA_ARGS__)
+
+class CGridCellBase : public CObject
+{
+    friend class CakGridCtrl;
+    DECLARE_DYNAMIC(CGridCellBase)
+
+// Construction/Destruction
+public:
+    CGridCellBase();
+    virtual ~CGridCellBase();
+
+// Attributes
+public:
+    virtual void SetText(LPCTSTR /* szText */)              = 0 ;
+    virtual void SetImage(int /* nImage */)                 = 0 ;
+    virtual void SetData(LPARAM /* lParam */)               = 0 ;
+    virtual void SetState(DWORD nState)                     { m_nState = nState; }
+    virtual void SetFormat(DWORD /* nFormat */)             = 0 ;
+    virtual void SetTextClr(COLORREF /* clr */)             = 0 ;
+    virtual void SetBackClr(COLORREF /* clr */)             = 0 ;
+    virtual void SetFont(const LOGFONT* /* plf */)          = 0 ;
+    virtual void SetMargin( UINT /* nMargin */)             = 0 ;
+    virtual void SetGrid(CakGridCtrl* /* pGrid */)            = 0 ;
+    virtual void SetCoords( int /* nRow */, int /* nCol */) = 0 ;
+
+    virtual LPCTSTR    GetText()       const                = 0 ;
+    virtual LPCTSTR    GetTipText()    const                { return GetText(); } // may override TitleTip return
+    virtual int        GetImage()      const                = 0 ;
+    virtual LPARAM     GetData()       const                = 0 ;
+    virtual DWORD      GetState()      const                { return m_nState;  }
+    virtual DWORD      GetFormat()     const                = 0 ;
+    virtual COLORREF   GetTextClr()    const                = 0 ;
+    virtual COLORREF   GetBackClr()    const                = 0 ;
+    virtual LOGFONT  * GetFont()       const                = 0 ;
+    virtual CFont    * GetFontObject() const                = 0 ;
+    virtual CakGridCtrl* GetGrid()       const                = 0 ;
+    virtual CWnd     * GetEditWnd()    const                = 0 ;
+    virtual UINT       GetMargin()     const                = 0 ;
+
+    virtual CGridCellBase* GetDefaultCell() const;
+
+    virtual BOOL IsDefaultFont()       const                = 0 ;
+    virtual BOOL IsEditing()           const                = 0 ;
+    virtual BOOL IsFocused()           const                { return (m_nState & GVIS_FOCUSED);  }
+    virtual BOOL IsFixed()             const                { return (m_nState & GVIS_FIXED);    }
+    virtual BOOL IsFixedCol()          const                { return (m_nState & GVIS_FIXEDCOL); }
+    virtual BOOL IsFixedRow()          const                { return (m_nState & GVIS_FIXEDROW); }
+    virtual BOOL IsSelected()          const                { return (m_nState & GVIS_SELECTED); }
+    virtual BOOL IsReadOnly()          const                { return (m_nState & GVIS_READONLY); }
+    virtual BOOL IsModified()          const                { return (m_nState & GVIS_MODIFIED); }
+    virtual BOOL IsDropHighlighted()   const                { return (m_nState & GVIS_DROPHILITED); }
+
+// Operators
+public:
+    virtual void operator=(const CGridCellBase& cell);
+
+// Operations
+public:
+    virtual void Reset();
+
+    virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
+    virtual BOOL GetTextRect( LPRECT pRect);    // i/o:  i=dims of cell rect; o=dims of text rect
+    virtual BOOL GetTipTextRect( LPRECT pRect) { return GetTextRect( pRect); }  // may override for btns, etc.
+    virtual CSize GetTextExtent(LPCTSTR str, CDC* pDC = NULL);
+    virtual CSize GetCellExtent(CDC* pDC);
+
+    // Editing
+    virtual BOOL Edit( int /* nRow */, int /* nCol */, CRect /* rect */, CPoint /* point */, 
+                       UINT /* nID */, UINT /* nChar */) { ASSERT( FALSE); return FALSE;}
+	virtual BOOL ValidateEdit(LPCTSTR str);
+    virtual void EndEdit() {}
+
+    // EFW - Added to print cells properly
+    virtual BOOL PrintCell(CDC* pDC, int nRow, int nCol, CRect rect);
+
+    // add additional protected grid members required of cells
+    LRESULT SendMessageToParent(int nRow, int nCol, int nMessage);
+
+protected:
+    virtual void OnEndEdit();
+    virtual void OnMouseEnter();
+    virtual void OnMouseOver();
+    virtual void OnMouseLeave();
+    virtual void OnClick( CPoint PointCellRelative);
+    virtual void OnClickDown( CPoint PointCellRelative);
+    virtual void OnRClick( CPoint PointCellRelative);
+    virtual void OnDblClick( CPoint PointCellRelative);
+    virtual BOOL OnSetCursor();
+
+protected:
+    DWORD    m_nState;      // Cell state (selected/focus etc)
+};
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GRIDCELLBASE_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/GridCellCheck.h b/ReviewHistory/include/akGridCtrl/GridCellCheck.h
new file mode 100644
index 0000000..baf5fcf
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/GridCellCheck.h
@@ -0,0 +1,68 @@
+#if !defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
+#define AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+/////////////////////////////////////////////////////////////////////////////
+// GridCellCheck.h : header file
+//
+// MFC Grid Control - Grid combo cell class header file
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.22+
+//
+//////////////////////////////////////////////////////////////////////
+
+
+#include "GridCell.h"
+
+
+class CGridCellCheck : public CGridCell
+{
+    friend class CakGridCtrl;
+    DECLARE_DYNCREATE(CGridCellCheck)
+
+public:
+    CGridCellCheck();
+
+public:
+	BOOL SetCheck(BOOL bChecked = TRUE);
+	BOOL GetCheck();
+
+// Operations
+	virtual CSize GetCellExtent(CDC* pDC);
+    virtual void OnClick( CPoint PointCellRelative);
+    virtual BOOL GetTextRect( LPRECT pRect);
+
+protected:
+	CRect GetCheckPlacement();
+
+    virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
+
+protected:
+    BOOL  m_bChecked;
+    CRect m_Rect;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/GridDropTarget.h b/ReviewHistory/include/akGridCtrl/GridDropTarget.h
new file mode 100644
index 0000000..4cc377f
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/GridDropTarget.h
@@ -0,0 +1,82 @@
+//////////////////////////////////////////////////////////////////////
+// GridDropTarget.h : header file
+//
+// MFC Grid Control - Drag/Drop target implementation
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.10+
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_)
+#define AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+
+#include <afxole.h>
+
+class CakGridCtrl;
+
+/////////////////////////////////////////////////////////////////////////////
+// CGridDropTarget command target
+
+class CGridDropTarget : public COleDropTarget
+{
+public:
+    CGridDropTarget();
+    virtual ~CGridDropTarget();
+
+// Attributes
+public:
+    CakGridCtrl* m_pGridCtrl;
+    BOOL       m_bRegistered;
+
+// Operations
+public:
+    BOOL Register(CakGridCtrl *pGridCtrl);
+    virtual void Revoke();
+
+    BOOL        OnDrop(CWnd* pWnd, COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
+    DROPEFFECT  OnDragEnter(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+    void        OnDragLeave(CWnd* pWnd);
+    DROPEFFECT  OnDragOver(CWnd* pWnd, COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+    DROPEFFECT  OnDragScroll(CWnd* pWnd, DWORD dwKeyState, CPoint point);
+
+// Overrides
+    // ClassWizard generated virtual function overrides
+    //{{AFX_VIRTUAL(CGridDropTarget)
+    //}}AFX_VIRTUAL
+
+// Implementation
+protected:
+
+    // Generated message map functions
+    //{{AFX_MSG(CGridDropTarget)
+    //}}AFX_MSG
+
+    DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GRIDDROPTARGET_H__5C610981_BD36_11D1_97CD_00A0243D1382__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/InPlaceEdit.h b/ReviewHistory/include/akGridCtrl/InPlaceEdit.h
new file mode 100644
index 0000000..62da970
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/InPlaceEdit.h
@@ -0,0 +1,83 @@
+//////////////////////////////////////////////////////////////////////
+// InPlaceEdit.h : header file
+//
+// MFC Grid Control - inplace editing class
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.10+
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)
+#define AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+class CInPlaceEdit : public CEdit
+{
+// Construction
+public:
+    CInPlaceEdit(CWnd* pParent, CRect& rect, DWORD dwStyle, UINT nID,
+                 int nRow, int nColumn, CString sInitText, UINT nFirstChar);
+
+// Attributes
+public:
+ 
+// Operations
+public:
+     void EndEdit();
+ 
+// Overrides
+     // ClassWizard generated virtual function overrides
+     //{{AFX_VIRTUAL(CInPlaceEdit)
+	public:
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	protected:
+	virtual void PostNcDestroy();
+	//}}AFX_VIRTUAL
+ 
+// Implementation
+public:
+     virtual ~CInPlaceEdit();
+ 
+// Generated message map functions
+protected:
+    //{{AFX_MSG(CInPlaceEdit)
+    afx_msg void OnKillFocus(CWnd* pNewWnd);
+    afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg UINT OnGetDlgCode();
+	//}}AFX_MSG
+    DECLARE_MESSAGE_MAP()
+
+private:
+    int     m_nRow;
+    int     m_nColumn;
+    CString m_sInitText;
+    UINT    m_nLastChar;
+    BOOL    m_bExitOnArrows;
+    CRect   m_Rect;
+};
+ 
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_INPLACEEDIT_H__ECD42821_16DF_11D1_992F_895E185F9C72__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/MemDC.h b/ReviewHistory/include/akGridCtrl/MemDC.h
new file mode 100644
index 0000000..5ae5099
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/MemDC.h
@@ -0,0 +1,106 @@
+#if !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
+#define AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+// MemDC.h : header file
+//
+
+//////////////////////////////////////////////////
+// CMemDC - memory DC
+//
+// Author: Keith Rule
+// Email:  keithr@europa.com
+// Copyright 1996-1997, Keith Rule
+//
+// You may freely use or modify this code provided this
+// Copyright is included in all derived versions.
+//
+// History - 10/3/97 Fixed scrolling bug.
+//                   Added print support.
+//           25 feb 98 - fixed minor assertion bug
+//
+// This class implements a memory Device Context
+
+class CMemDC : public CDC
+{
+public:
+
+    // constructor sets up the memory DC
+    CMemDC(CDC* pDC) : CDC()
+    {
+        ASSERT(pDC != NULL);
+
+        m_pDC = pDC;
+        m_pOldBitmap = NULL;
+#ifndef _WIN32_WCE_NO_PRINTING
+        m_bMemDC = !pDC->IsPrinting();
+#else
+        m_bMemDC = FALSE;
+#endif
+
+        if (m_bMemDC)    // Create a Memory DC
+        {
+            pDC->GetClipBox(&m_rect);
+            CreateCompatibleDC(pDC);
+            m_bitmap.CreateCompatibleBitmap(pDC, m_rect.Width(), m_rect.Height());
+            m_pOldBitmap = SelectObject(&m_bitmap);
+#ifndef _WIN32_WCE
+            SetWindowOrg(m_rect.left, m_rect.top);
+#endif
+            // EFW - Bug fix - Fill background in case the user has overridden
+            // WM_ERASEBKGND.  We end up with garbage otherwise.
+            // CJM - moved to fix a bug in the fix.
+            FillSolidRect(m_rect, pDC->GetBkColor());
+        }
+        else        // Make a copy of the relevent parts of the current DC for printing
+        {
+#if !defined(_WIN32_WCE) || ((_WIN32_WCE > 201) && !defined(_WIN32_WCE_NO_PRINTING))
+            m_bPrinting = pDC->m_bPrinting;
+#endif
+            m_hDC       = pDC->m_hDC;
+            m_hAttribDC = pDC->m_hAttribDC;
+        }
+
+    }
+
+    // Destructor copies the contents of the mem DC to the original DC
+    ~CMemDC()
+    {
+        if (m_bMemDC)
+        {
+            // Copy the offscreen bitmap onto the screen.
+            m_pDC->BitBlt(m_rect.left, m_rect.top, m_rect.Width(), m_rect.Height(),
+                          this, m_rect.left, m_rect.top, SRCCOPY);
+
+            //Swap back the original bitmap.
+            SelectObject(m_pOldBitmap);
+        } else {
+            // All we need to do is replace the DC with an illegal value,
+            // this keeps us from accidently deleting the handles associated with
+            // the CDC that was passed to the constructor.
+            m_hDC = m_hAttribDC = NULL;
+        }
+    }
+
+    // Allow usage as a pointer
+    CMemDC* operator->() {return this;}
+        
+    // Allow usage as a pointer
+    operator CMemDC*() {return this;}
+
+private:
+    CBitmap  m_bitmap;      // Offscreen bitmap
+    CBitmap* m_pOldBitmap;  // bitmap originally found in CMemDC
+    CDC*     m_pDC;         // Saves CDC passed in constructor
+    CRect    m_rect;        // Rectangle of drawing area.
+    BOOL     m_bMemDC;      // TRUE if CDC really is a Memory DC.
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_MEMDC_H__CA1D3541_7235_11D1_ABBA_00A0243D1382__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCheck.h b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCheck.h
new file mode 100644
index 0000000..e620cf8
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCheck.h
@@ -0,0 +1,68 @@
+#if !defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
+#define AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+/////////////////////////////////////////////////////////////////////////////
+// GridCellCheck.h : header file
+//
+// MFC Grid Control - Grid combo cell class header file
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.22+
+//
+//////////////////////////////////////////////////////////////////////
+
+
+#include "akGridCtrl/GridCell.h"
+
+
+class AFX_EXT_CLASS CGridCellCheck : public CGridCell
+{
+    friend class CakGridCtrl;
+    DECLARE_DYNCREATE(CGridCellCheck)
+
+public:
+    CGridCellCheck();
+
+public:
+	BOOL SetCheck(BOOL bChecked = TRUE);
+	BOOL GetCheck();
+
+// Operations
+	virtual CSize GetCellExtent(CDC* pDC);
+    virtual void OnClick( CPoint PointCellRelative);
+    virtual BOOL GetTextRect( LPRECT pRect);
+
+protected:
+	CRect GetCheckPlacement();
+
+    virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
+
+protected:
+    BOOL  m_bChecked;
+    CRect m_Rect;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GRIDCELLCHECK_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCombo.h b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCombo.h
new file mode 100644
index 0000000..7a1df74
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellCombo.h
@@ -0,0 +1,177 @@
+#if !defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
+#define AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+/////////////////////////////////////////////////////////////////////////////
+// GridCellCombo.h : header file
+//
+// MFC Grid Control - Grid combo cell class header file
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.10
+//
+//////////////////////////////////////////////////////////////////////
+
+
+#include "akGridCtrl/GridCell.h"
+
+
+class AFX_EXT_CLASS CGridCellCombo : public CGridCell
+{
+    friend class CakGridCtrl;
+    DECLARE_DYNCREATE(CGridCellCombo)
+
+public:
+    CGridCellCombo();
+
+// editing cells
+public:
+    virtual BOOL  Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
+    virtual CWnd* GetEditWnd() const;
+    virtual void  EndEdit();
+
+// Operations
+public:
+	virtual CSize GetCellExtent(CDC* pDC);
+
+// CGridCellCombo specific calls
+public:
+    void  SetOptions(const CStringArray& ar);
+    void  SetStyle(DWORD dwStyle)           { m_dwStyle = dwStyle; }
+    DWORD GetStyle()                        { return m_dwStyle;    }
+
+protected:
+    virtual BOOL Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
+
+    CStringArray m_Strings;
+    DWORD        m_dwStyle;
+};
+
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CComboEdit window
+
+#define IDC_COMBOEDIT 1001
+
+class CComboEdit : public CEdit
+{
+// Construction
+public:
+	CComboEdit();
+
+// Attributes
+public:
+
+// Operations
+public:
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CComboEdit)
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CComboEdit();
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CComboEdit)
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
+	//}}AFX_MSG
+
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// CInPlaceList window
+
+class CInPlaceList : public CComboBox
+{
+    friend class CComboEdit;
+
+// Construction
+public:
+	CInPlaceList(CWnd* pParent,         // parent
+                 CRect& rect,           // dimensions & location
+                 DWORD dwStyle,         // window/combobox style
+                 UINT nID,              // control ID
+                 int nRow, int nColumn, // row and column
+                 COLORREF crFore, COLORREF crBack,  // Foreground, background colour
+				 CStringArray& Items,   // Items in list
+                 CString sInitText,     // initial selection
+				 UINT nFirstChar);      // first character to pass to control
+
+// Attributes
+public:
+   CComboEdit m_edit;  // subclassed edit control
+
+// Operations
+public:
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CInPlaceList)
+	protected:
+	virtual void PostNcDestroy();
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CInPlaceList();
+    void EndEdit();
+
+protected:
+    int GetCorrectDropWidth();
+
+// Generated message map functions
+protected:
+	//{{AFX_MSG(CInPlaceList)
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg void OnDropdown();
+	afx_msg UINT OnGetDlgCode();
+	afx_msg HBRUSH CtlColor(CDC* pDC, UINT nCtlColor);
+	//}}AFX_MSG
+	//afx_msg void OnSelendOK();
+
+	DECLARE_MESSAGE_MAP()
+
+private:
+	int		 m_nNumLines;
+	CString  m_sInitText;
+	int		 m_nRow;
+	int		 m_nCol;
+ 	UINT     m_nLastChar; 
+	BOOL	 m_bExitOnArrows; 
+    COLORREF m_crForeClr, m_crBackClr;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GRIDCELLCOMBO_H__ECD42822_16DF_11D1_992F_895E185F9C72__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellDateTime.h b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellDateTime.h
new file mode 100644
index 0000000..828d4f6
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellDateTime.h
@@ -0,0 +1,92 @@
+// GridCellDateTime.h: interface for the CGridCellDateTime class.
+//
+// Provides the implementation for a datetime picker cell type of the
+// grid control.
+//
+// For use with CGridCtrl v2.22+
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_)
+#define AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "akGridCtrl/GridCell.h"
+#include "afxdtctl.h"	// for CDateTimeCtrl
+
+class AFX_EXT_CLASS CGridCellDateTime : public CGridCell
+{
+  friend class CakGridCtrl;
+  DECLARE_DYNCREATE(CGridCellDateTime)
+
+  CTime m_cTime;
+  DWORD m_dwStyle;
+
+public:
+	CGridCellDateTime();
+	CGridCellDateTime(DWORD dwStyle);
+	virtual ~CGridCellDateTime();
+    virtual CSize GetCellExtent(CDC* pDC);
+
+  // editing cells
+public:
+	void Init(DWORD dwStyle);
+	virtual BOOL  Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
+	virtual CWnd* GetEditWnd() const;
+	virtual void  EndEdit();
+
+
+	CTime* GetTime() {return &m_cTime;};
+	void   SetTime(CTime time);
+};
+
+class CInPlaceDateTime : public CDateTimeCtrl
+{
+// Construction
+public:
+	CInPlaceDateTime(CWnd* pParent,         // parent
+                   CRect& rect,           // dimensions & location
+                   DWORD dwStyle,         // window/combobox style
+                   UINT nID,              // control ID
+                   int nRow, int nColumn, // row and column
+                   COLORREF crFore, COLORREF crBack,  // Foreground, background colour
+                   CTime* pcTime,
+          		   UINT nFirstChar);      // first character to pass to control
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CInPlaceList)
+	protected:
+	virtual void PostNcDestroy();
+	//}}AFX_VIRTUAL
+
+// Implementation
+public:
+	virtual ~CInPlaceDateTime();
+    void EndEdit();
+
+// Generated message map functions
+protected:
+	//{{AFX_MSG(CInPlaceList)
+	afx_msg void OnKillFocus(CWnd* pNewWnd);
+	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg UINT OnGetDlgCode();
+	//}}AFX_MSG
+	//afx_msg void OnSelendOK();
+
+	DECLARE_MESSAGE_MAP()
+
+private:
+    CTime*   m_pcTime;
+	int		 m_nRow;
+	int		 m_nCol;
+ 	UINT     m_nLastChar; 
+	BOOL	 m_bExitOnArrows; 
+    COLORREF m_crForeClr, m_crBackClr;
+};
+
+#endif // !defined(AFX_DATETIMECELL_H__A0B7DA0A_0AFE_4D28_A00E_846C96D7507A__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellNumeric.h b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellNumeric.h
new file mode 100644
index 0000000..4b58de4
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridCellNumeric.h
@@ -0,0 +1,26 @@
+// GridCellNumeric.h: interface for the CGridCellNumeric class.
+//
+// Written by Andrew Truckle [ajtruckle@wsatkins.co.uk]
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_)
+#define AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "akGridCtrl/GridCell.h"//#include "../GridCtrl_src/GridCell.h"
+
+class AFX_EXT_CLASS CGridCellNumeric : public CGridCell
+{
+    DECLARE_DYNCREATE(CGridCellNumeric)
+
+public:
+    virtual BOOL Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
+    virtual void EndEdit();
+
+};
+
+#endif // !defined(AFX_GRIDINTEGERCELL_H__3479ED0D_B57D_4940_B83D_9E2296ED75B5__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/NewCellTypes/GridURLCell.h b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridURLCell.h
new file mode 100644
index 0000000..d1a9a98
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/NewCellTypes/GridURLCell.h
@@ -0,0 +1,55 @@
+// GridURLCell.h: interface for the CGridURLCell class.
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_)
+#define AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_
+
+#if _MSC_VER > 1000
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include "akGridCtrl/GridCell.h"
+
+typedef struct {
+    LPCTSTR szURLPrefix;
+    size_t  nLength;
+} URLStruct;
+
+
+
+class AFX_EXT_CLASS CGridURLCell : public CGridCell
+{
+    DECLARE_DYNCREATE(CGridURLCell)
+
+public:
+	CGridURLCell();
+	virtual ~CGridURLCell();
+
+    virtual BOOL     Draw(CDC* pDC, int nRow, int nCol, CRect rect, BOOL bEraseBkgnd = TRUE);
+    virtual BOOL     Edit(int nRow, int nCol, CRect rect, CPoint point, UINT nID, UINT nChar);
+    virtual LPCTSTR  GetTipText() { return NULL; }
+	void SetAutoLaunchUrl(BOOL bLaunch = TRUE) { m_bLaunchUrl = bLaunch;	}
+	BOOL GetAutoLaunchUrl() { return m_bLaunchUrl;	}
+
+protected:
+    virtual BOOL OnSetCursor();
+    virtual void OnClick(CPoint PointCellRelative);
+
+	BOOL HasUrl(CString str);
+    BOOL OverURL(CPoint& pt, CString& strURL);
+
+protected:
+#ifndef _WIN32_WCE
+    static HCURSOR g_hLinkCursor;		// Hyperlink mouse cursor
+	HCURSOR GetHandCursor();
+#endif
+    static URLStruct g_szURIprefixes[];
+
+protected:
+	COLORREF m_clrUrl;
+	BOOL     m_bLaunchUrl;
+    CRect    m_Rect;
+};
+
+#endif // !defined(AFX_GRIDURLCELL_H__9F4A50B4_D773_11D3_A439_F7E60631F563__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/TitleTip.h b/ReviewHistory/include/akGridCtrl/TitleTip.h
new file mode 100644
index 0000000..63d6d47
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/TitleTip.h
@@ -0,0 +1,87 @@
+/////////////////////////////////////////////////////////////////////////////
+// Titletip.h : header file
+//
+// MFC Grid Control - cell titletips
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.10+
+//
+//////////////////////////////////////////////////////////////////////
+
+#if !defined(AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_)
+#define AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#define TITLETIP_CLASSNAME _T("ZTitleTip")
+
+/////////////////////////////////////////////////////////////////////////////
+// CTitleTip window
+
+class CTitleTip : public CWnd
+{
+// Construction
+public:
+	CTitleTip();
+	virtual ~CTitleTip();
+	virtual BOOL Create( CWnd *pParentWnd);
+
+// Attributes
+public:
+    void SetParentWnd(CWnd* pParentWnd)  { m_pParentWnd = pParentWnd; }
+    CWnd* GetParentWnd()                 { return m_pParentWnd;       }
+
+// Operations
+public:
+	void Show(CRect rectTitle, LPCTSTR lpszTitleText, 
+              int xoffset = 0, LPRECT lpHoverRect = NULL, 
+              const LOGFONT* lpLogFont = NULL,
+              COLORREF crTextClr = CLR_DEFAULT, COLORREF crBackClr = CLR_DEFAULT);
+    void Hide();
+
+// Overrides
+	// ClassWizard generated virtual function overrides
+	//{{AFX_VIRTUAL(CTitleTip)
+	public:
+	virtual BOOL PreTranslateMessage(MSG* pMsg);
+	virtual BOOL DestroyWindow();
+	//}}AFX_VIRTUAL
+
+// Implementation
+protected:
+	CWnd  *m_pParentWnd;
+	CRect  m_rectTitle;
+    CRect  m_rectHover;
+    DWORD  m_dwLastLButtonDown;
+    DWORD  m_dwDblClickMsecs;
+    BOOL   m_bCreated;
+
+	// Generated message map functions
+protected:
+	//{{AFX_MSG(CTitleTip)
+	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+	//}}AFX_MSG
+	DECLARE_MESSAGE_MAP()
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_TITLETIP_H__C7165DA1_187F_11D1_992F_895E185F9C72__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/akGridCtrl.h b/ReviewHistory/include/akGridCtrl/akGridCtrl.h
new file mode 100644
index 0000000..472b7f4
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/akGridCtrl.h
@@ -0,0 +1,925 @@
+//
+//////////////////////////////////////////////////////////////////////////
+//이 모듈은 Chris Maunder가 제작한 것을 수정 보안한 그리드 컨트롤 입니다.
+//
+//
+/*
+사용방법
+1. 리소스 창에 커스텀 컨트롤 생성
+2. 생성한 커스텀컨트롤 -> 속성 -> Class에 akGridCtrl 입력
+3. CGridCtrl 클래스로 컨트롤 변수 등록
+*/
+
+/////////////////////////////////////////////////////////////////////////////
+// GridCtrl.h : header file
+//
+// MFC Grid Control - main header
+//
+// Written by Chris Maunder <chris@codeproject.com>
+// Copyright (c) 1998-2005. All Rights Reserved.
+//
+// This code may be used in compiled form in any way you desire. This
+// file may be redistributed unmodified by any means PROVIDING it is 
+// not sold for profit without the authors written consent, and 
+// providing that this notice and the authors name and all copyright 
+// notices remains intact. 
+//
+// An email letting me know how you are using it would be nice as well. 
+//
+// This file is provided "as is" with no expressed or implied warranty.
+// The author accepts no liability for any damage/loss of business that
+// this product may cause.
+//
+// For use with CGridCtrl v2.20+
+//
+//////////////////////////////////////////////////////////////////////
+
+
+#if !defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
+#define AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include "akGridCtrlLinker.h"
+#include "CellRange.h"
+#include "GridCell.h"
+#include <afxtempl.h>
+#include <vector>
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// Defines - these determine the features (and the final size) of the final code
+///////////////////////////////////////////////////////////////////////////////////
+
+//#define GRIDCONTROL_NO_TITLETIPS   // Do not use titletips for cells with large data
+//#define GRIDCONTROL_NO_DRAGDROP    // Do not use OLE drag and drop
+//#define GRIDCONTROL_NO_CLIPBOARD   // Do not use clipboard routines
+
+#ifdef _WIN32_WCE
+#   define GRIDCONTROL_NO_TITLETIPS   // Do not use titletips for cells with large data
+#   define GRIDCONTROL_NO_DRAGDROP    // Do not use OLE drag and drop
+#   define GRIDCONTROL_NO_CLIPBOARD   // Do not use clipboard routines
+#   define GRIDCONTROL_NO_PRINTING    // Do not use printing routines
+#   ifdef WCE_NO_PRINTING			  // Older versions of CE had different #def's
+#       define _WIN32_WCE_NO_PRINTING
+#   endif
+#   ifdef WCE_NO_CURSOR
+#       define _WIN32_WCE_NO_CURSOR
+#   endif
+#endif  // _WIN32_WCE
+
+// Use this as the classname when inserting this control as a custom control
+// in the MSVC++ dialog editor
+#define GRIDCTRL_CLASSNAME    _T("akGridCtrl")  // Window class name
+#define IDC_INPLACE_CONTROL   8                  // ID of inplace edit controls
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// Conditional includes
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef GRIDCONTROL_NO_TITLETIPS
+#   include "TitleTip.h"
+#endif
+
+#ifndef GRIDCONTROL_NO_DRAGDROP
+#   include "GridDropTarget.h"
+#   undef GRIDCONTROL_NO_CLIPBOARD     // Force clipboard functions on
+#endif
+
+#ifndef GRIDCONTROL_NO_CLIPBOARD
+#   include <afxole.h>
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// Helper functions
+///////////////////////////////////////////////////////////////////////////////////
+
+// Handy functions
+#define IsSHIFTpressed() ( (GetKeyState(VK_SHIFT) & (1 << (sizeof(SHORT)*8-1))) != 0   )
+#define IsCTRLpressed()  ( (GetKeyState(VK_CONTROL) & (1 << (sizeof(SHORT)*8-1))) != 0 )
+
+// Backwards compatibility for pre 2.20 grid versions
+#define DDX_GridControl(pDX, nIDC, rControl)  DDX_Control(pDX, nIDC, rControl)     
+
+
+///////////////////////////////////////////////////////////////////////////////////
+// Structures
+///////////////////////////////////////////////////////////////////////////////////
+
+// This structure sent to Grid's parent in a WM_NOTIFY message
+typedef struct AFX_EXT_CLASS tagNM_GRIDVIEW {
+    NMHDR hdr;
+    int   iRow;
+    int   iColumn;
+} NM_GRIDVIEW;
+
+// This is sent to the Grid from child in-place edit controls
+typedef struct AFX_EXT_CLASS tagGV_DISPINFO {
+    NMHDR   hdr;
+    GV_ITEM item;
+} GV_DISPINFO;
+
+// This is sent to the Grid from child in-place edit controls
+typedef struct AFX_EXT_CLASS tagGV_CACHEHINT {
+    NMHDR      hdr;
+    CCellRange range;
+} GV_CACHEHINT;
+
+// storage typedef for each row in the grid
+typedef CTypedPtrArray<CObArray, CGridCellBase*> GRID_ROW;
+
+// For virtual mode callback
+typedef BOOL (CALLBACK* GRIDCALLBACK)(GV_DISPINFO *, LPARAM);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////////
+
+// Grid line/scrollbar selection
+#define GVL_NONE                0L      // Neither
+#define GVL_HORZ                1L      // Horizontal line or scrollbar
+#define GVL_VERT                2L      // Vertical line or scrollbar
+#define GVL_BOTH                3L      // Both
+
+// Autosizing option
+#define GVS_DEFAULT             0
+#define GVS_HEADER              1       // Size using column fixed cells data only
+#define GVS_DATA                2       // Size using column non-fixed cells data only
+#define GVS_BOTH                3       // Size using column fixed and non-fixed
+
+// Cell Searching options
+#define GVNI_FOCUSED            0x0001
+#define GVNI_SELECTED           0x0002
+#define GVNI_DROPHILITED        0x0004
+#define GVNI_READONLY           0x0008
+#define GVNI_FIXED              0x0010
+#define GVNI_MODIFIED           0x0020
+
+#define GVNI_ABOVE              LVNI_ABOVE
+#define GVNI_BELOW              LVNI_BELOW
+#define GVNI_TOLEFT             LVNI_TOLEFT
+#define GVNI_TORIGHT            LVNI_TORIGHT
+#define GVNI_ALL                (LVNI_BELOW|LVNI_TORIGHT|LVNI_TOLEFT)
+#define GVNI_AREA               (LVNI_BELOW|LVNI_TORIGHT)
+
+// Hit test values (not yet implemented)
+#define GVHT_DATA               0x0000
+#define GVHT_TOPLEFT            0x0001
+#define GVHT_COLHDR             0x0002
+#define GVHT_ROWHDR             0x0004
+#define GVHT_COLSIZER           0x0008
+#define GVHT_ROWSIZER           0x0010
+#define GVHT_LEFT               0x0020
+#define GVHT_RIGHT              0x0040
+#define GVHT_ABOVE              0x0080
+#define GVHT_BELOW              0x0100
+
+// Messages sent to the grid's parent (More will be added in future)
+#define GVN_BEGINDRAG           LVN_BEGINDRAG        // LVN_FIRST-9
+#define GVN_BEGINLABELEDIT      LVN_BEGINLABELEDIT   // LVN_FIRST-5
+#define GVN_BEGINRDRAG          LVN_BEGINRDRAG
+#define GVN_COLUMNCLICK         LVN_COLUMNCLICK
+#define GVN_DELETEITEM          LVN_DELETEITEM
+#define GVN_ENDLABELEDIT        LVN_ENDLABELEDIT     // LVN_FIRST-6
+#define GVN_SELCHANGING         LVN_ITEMCHANGING
+#define GVN_SELCHANGED          LVN_ITEMCHANGED
+#define GVN_GETDISPINFO         LVN_GETDISPINFO 
+#define GVN_ODCACHEHINT         LVN_ODCACHEHINT 
+
+class CakGridCtrl;
+
+/////////////////////////////////////////////////////////////////////////////
+// CGridCtrl window
+
+typedef bool (*PVIRTUALCOMPARE)(int, int);
+
+class AFX_EXT_CLASS CakGridCtrl : public CWnd
+{
+    DECLARE_DYNCREATE(CakGridCtrl)
+    friend class CGridCell;
+    friend class CGridCellBase;
+
+// Construction
+public:
+    CakGridCtrl(int nRows = 0, int nCols = 0, int nFixedRows = 0, int nFixedCols = 0);
+
+    BOOL Create(const RECT& rect, CWnd* parent, UINT nID,
+                DWORD dwStyle = WS_CHILD | WS_BORDER | WS_TABSTOP | WS_VISIBLE);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Attributes
+///////////////////////////////////////////////////////////////////////////////////
+public:
+    int  GetRowCount() const                    { return m_nRows; }
+    int  GetColumnCount() const                 { return m_nCols; }
+    int  GetFixedRowCount() const               { return m_nFixedRows; }
+    int  GetFixedColumnCount() const            { return m_nFixedCols; }
+    BOOL SetRowCount(int nRows = 10);
+    BOOL SetColumnCount(int nCols = 10);
+    BOOL SetFixedRowCount(int nFixedRows = 1);
+    BOOL SetFixedColumnCount(int nFixedCols = 1);
+
+    int  GetRowHeight(int nRow) const;
+    BOOL SetRowHeight(int row, int height);
+    int  GetColumnWidth(int nCol) const;
+    BOOL SetColumnWidth(int col, int width);
+
+    BOOL GetCellOrigin(int nRow, int nCol, LPPOINT p);
+    BOOL GetCellOrigin(const CCellID& cell, LPPOINT p);
+    BOOL GetCellRect(int nRow, int nCol, LPRECT pRect);
+    BOOL GetCellRect(const CCellID& cell, LPRECT pRect);
+
+    BOOL GetTextRect(const CCellID& cell, LPRECT pRect);
+    BOOL GetTextRect(int nRow, int nCol, LPRECT pRect);
+
+    CCellID GetCellFromPt(CPoint point, BOOL bAllowFixedCellCheck = TRUE);
+
+    int  GetFixedRowHeight() const;
+    int  GetFixedColumnWidth() const;
+    long GetVirtualWidth() const;
+    long GetVirtualHeight() const;
+
+    CSize GetTextExtent(int nRow, int nCol, LPCTSTR str);
+    // EFW - Get extent of current text in cell
+    inline CSize GetCellTextExtent(int nRow, int nCol)  { return GetTextExtent(nRow, nCol, GetItemText(nRow,nCol)); }
+
+    void     SetGridBkColor(COLORREF clr)         { m_crGridBkColour = clr;           }
+    COLORREF GetGridBkColor() const               { return m_crGridBkColour;          }
+    void     SetGridLineColor(COLORREF clr)       { m_crGridLineColour = clr;         }
+    COLORREF GetGridLineColor() const             { return m_crGridLineColour;        }
+
+	void	 SetTitleTipBackClr(COLORREF clr = CLR_DEFAULT) { m_crTTipBackClr = clr;  }
+	COLORREF GetTitleTipBackClr()				            { return m_crTTipBackClr; }
+	void	 SetTitleTipTextClr(COLORREF clr = CLR_DEFAULT) { m_crTTipTextClr = clr;  }
+	COLORREF GetTitleTipTextClr()				            { return m_crTTipTextClr; }
+
+    // ***************************************************************************** //
+    // These have been deprecated. Use GetDefaultCell and then set the colors
+    void     SetTextColor(COLORREF clr)      { m_cellDefault.SetTextClr(clr);        }
+    COLORREF GetTextColor()                  { return m_cellDefault.GetTextClr();    }
+    void     SetTextBkColor(COLORREF clr)    { m_cellDefault.SetBackClr(clr);        }
+    COLORREF GetTextBkColor()                { return m_cellDefault.GetBackClr();    }
+    void     SetFixedTextColor(COLORREF clr) { m_cellFixedRowDef.SetTextClr(clr); 
+                                               m_cellFixedColDef.SetTextClr(clr); 
+                                               m_cellFixedRowColDef.SetTextClr(clr); }
+    COLORREF GetFixedTextColor() const       { return m_cellFixedRowDef.GetTextClr(); }
+    void     SetFixedBkColor(COLORREF clr)   { m_cellFixedRowDef.SetBackClr(clr); 
+                                               m_cellFixedColDef.SetBackClr(clr); 
+                                               m_cellFixedRowColDef.SetBackClr(clr); }
+    COLORREF GetFixedBkColor() const         { return m_cellFixedRowDef.GetBackClr(); }
+    void     SetGridColor(COLORREF clr)      { SetGridLineColor(clr);                }
+    COLORREF GetGridColor()                  { return GetGridLineColor();            }
+    void     SetBkColor(COLORREF clr)        { SetGridBkColor(clr);                  }
+    COLORREF GetBkColor()                    { return GetGridBkColor();              }
+
+    void     SetDefCellMargin( int nMargin)  { m_cellDefault.SetMargin(nMargin); 
+                                               m_cellFixedRowDef.SetMargin(nMargin); 
+                                               m_cellFixedColDef.SetMargin(nMargin); 
+                                               m_cellFixedRowColDef.SetMargin(nMargin); }
+    int      GetDefCellMargin() const        { return m_cellDefault.GetMargin();     }
+
+    int      GetDefCellHeight() const        { return m_cellDefault.GetHeight();     }
+    void     SetDefCellHeight(int nHeight)   { m_cellDefault.SetHeight(nHeight); 
+                                               m_cellFixedRowDef.SetHeight(nHeight); 
+                                               m_cellFixedColDef.SetHeight(nHeight); 
+                                               m_cellFixedRowColDef.SetHeight(nHeight); }
+    int      GetDefCellWidth() const         { return m_cellDefault.GetWidth();     }
+    void     SetDefCellWidth(int nWidth)     { m_cellDefault.SetWidth(nWidth); 
+                                               m_cellFixedRowDef.SetWidth(nWidth); 
+                                               m_cellFixedColDef.SetWidth(nWidth); 
+                                               m_cellFixedRowColDef.SetWidth(nWidth); }
+
+    // ***************************************************************************** //
+
+    int GetSelectedCount() const                  { return (int)m_SelectedCellMap.GetCount(); }
+
+    CCellID SetFocusCell(CCellID cell);
+    CCellID SetFocusCell(int nRow, int nCol);
+    CCellID GetFocusCell() const                  { return m_idCurrentCell;           }
+
+
+    void SetVirtualMode(BOOL bVirtual);
+    BOOL GetVirtualMode() const                   { return m_bVirtualMode;            }
+    void SetCallbackFunc(GRIDCALLBACK pCallback, 
+                         LPARAM lParam)           { m_pfnCallback = pCallback; m_lParam = lParam; }
+    GRIDCALLBACK GetCallbackFunc()                { return m_pfnCallback;             }
+
+
+    void SetImageList(CImageList* pList)          { m_pImageList = pList;             }
+    CImageList* GetImageList() const              { return m_pImageList;              }
+
+    void SetGridLines(int nWhichLines = GVL_BOTH);
+    int  GetGridLines() const                     { return m_nGridLines;              }
+    void SetEditable(BOOL bEditable = TRUE)       { m_bEditable = bEditable;          }
+    BOOL IsEditable() const                       { return m_bEditable;               }
+    void SetListMode(BOOL bEnableListMode = TRUE);
+    BOOL GetListMode() const                      { return m_bListMode;               }
+    void SetSingleRowSelection(BOOL bSing = TRUE) { m_bSingleRowSelection = bSing;    }
+    BOOL GetSingleRowSelection()                  { return m_bSingleRowSelection & m_bListMode; }
+    void SetSingleColSelection(BOOL bSing = TRUE) { m_bSingleColSelection = bSing;    }
+    BOOL GetSingleColSelection()                  { return m_bSingleColSelection;     }
+    void EnableSelection(BOOL bEnable = TRUE)     { ResetSelectedRange(); m_bEnableSelection = bEnable; ResetSelectedRange(); }
+    BOOL IsSelectable() const                     { return m_bEnableSelection;        }
+    void SetFixedColumnSelection(BOOL bSelect)    { m_bFixedColumnSelection = bSelect;}
+    BOOL GetFixedColumnSelection()                { return m_bFixedColumnSelection;   }
+    void SetFixedRowSelection(BOOL bSelect)       { m_bFixedRowSelection = bSelect;   }
+    BOOL GetFixedRowSelection()                   { return m_bFixedRowSelection;      }
+    void EnableDragAndDrop(BOOL bAllow = TRUE)    { m_bAllowDragAndDrop = bAllow;     }
+    BOOL GetDragAndDrop() const                   { return m_bAllowDragAndDrop;       }
+    void SetRowResize(BOOL bResize = TRUE)        { m_bAllowRowResize = bResize;      }
+    BOOL GetRowResize() const                     { return m_bAllowRowResize;         }
+    void SetColumnResize(BOOL bResize = TRUE)     { m_bAllowColumnResize = bResize;   }
+    BOOL GetColumnResize() const                  { return m_bAllowColumnResize;      }
+    void SetHeaderSort(BOOL bSortOnClick = TRUE)  { m_bSortOnClick = bSortOnClick;    }
+    BOOL GetHeaderSort() const                    { return m_bSortOnClick;            }
+    void SetHandleTabKey(BOOL bHandleTab = TRUE)  { m_bHandleTabKey = bHandleTab;     }
+    BOOL GetHandleTabKey() const                  { return m_bHandleTabKey;           }
+    void SetDoubleBuffering(BOOL bBuffer = TRUE)  { m_bDoubleBuffer = bBuffer;        }
+    BOOL GetDoubleBuffering() const               { return m_bDoubleBuffer;           }
+    void EnableTitleTips(BOOL bEnable = TRUE)     { m_bTitleTips = bEnable;           }
+    BOOL GetTitleTips()                           { return m_bTitleTips;              }
+    void SetSortColumn(int nCol);
+    int  GetSortColumn() const                    { return m_nSortColumn;             }
+    void SetSortAscending(BOOL bAscending)        { m_bAscending = bAscending;        }
+    BOOL GetSortAscending() const                 { return m_bAscending;              }
+    void SetTrackFocusCell(BOOL bTrack)           { m_bTrackFocusCell = bTrack;       }
+    BOOL GetTrackFocusCell()                      { return m_bTrackFocusCell;         }
+    void SetFrameFocusCell(BOOL bFrame)           { m_bFrameFocus = bFrame;           }
+    BOOL GetFrameFocusCell()                      { return m_bFrameFocus;             }
+    void SetAutoSizeStyle(int nStyle = GVS_BOTH)  { m_nAutoSizeColumnStyle = nStyle;  }
+    int  GetAutoSizeStyle()                       { return m_nAutoSizeColumnStyle; }
+
+    void EnableHiddenColUnhide(BOOL bEnable = TRUE){ m_bHiddenColUnhide = bEnable;    }
+    BOOL GetHiddenColUnhide()                     { return m_bHiddenColUnhide;        }
+    void EnableHiddenRowUnhide(BOOL bEnable = TRUE){ m_bHiddenRowUnhide = bEnable;    }
+    BOOL GetHiddenRowUnhide()                     { return m_bHiddenRowUnhide;        }
+
+    void EnableColumnHide(BOOL bEnable = TRUE)    { m_bAllowColHide = bEnable;        }
+    BOOL GetColumnHide()                          { return m_bAllowColHide;           }
+    void EnableRowHide(BOOL bEnable = TRUE)       { m_bAllowRowHide = bEnable;        }
+    BOOL GetRowHide()                             { return m_bAllowRowHide;           }
+
+///////////////////////////////////////////////////////////////////////////////////
+// default Grid cells. Use these for setting default values such as colors and fonts
+///////////////////////////////////////////////////////////////////////////////////
+public:
+    CGridCellBase* GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const;
+
+///////////////////////////////////////////////////////////////////////////////////
+// Grid cell Attributes
+///////////////////////////////////////////////////////////////////////////////////
+public:
+    CGridCellBase* GetCell(int nRow, int nCol) const;   // Get the actual cell!
+
+    void SetModified(BOOL bModified = TRUE, int nRow = -1, int nCol = -1);
+    BOOL GetModified(int nRow = -1, int nCol = -1);
+    BOOL IsCellFixed(int nRow, int nCol);
+
+    BOOL   SetItem(const GV_ITEM* pItem);
+    BOOL   GetItem(GV_ITEM* pItem);
+    BOOL   SetItemText(int nRow, int nCol, LPCTSTR str);
+    // The following was virtual. If you want to override, use 
+    //  CGridCellBase-derived class's GetText() to accomplish same thing
+    CString GetItemText(int nRow, int nCol) const;
+
+    // EFW - 06/13/99 - Added to support printf-style formatting codes.
+    // Also supports use with a string resource ID
+#if !defined(_WIN32_WCE) || (_WIN32_WCE >= 210)
+    BOOL   SetItemTextFmt(int nRow, int nCol, LPCTSTR szFmt, ...);
+    BOOL   SetItemTextFmtID(int nRow, int nCol, UINT nID, ...);
+#endif
+
+    BOOL   SetItemData(int nRow, int nCol, LPARAM lParam);
+    LPARAM GetItemData(int nRow, int nCol) const;
+    BOOL   SetItemImage(int nRow, int nCol, int iImage);
+    int    GetItemImage(int nRow, int nCol) const;
+    BOOL   SetItemState(int nRow, int nCol, UINT state);
+    UINT   GetItemState(int nRow, int nCol) const;
+    BOOL   SetItemFormat(int nRow, int nCol, UINT nFormat);
+    UINT   GetItemFormat(int nRow, int nCol) const;
+    BOOL   SetItemBkColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
+    COLORREF GetItemBkColour(int nRow, int nCol) const;
+    BOOL   SetItemFgColour(int nRow, int nCol, COLORREF cr = CLR_DEFAULT);
+    COLORREF GetItemFgColour(int nRow, int nCol) const;
+    BOOL SetItemFont(int nRow, int nCol, const LOGFONT* lf);
+    const LOGFONT* GetItemFont(int nRow, int nCol);
+
+    BOOL IsItemEditing(int nRow, int nCol);
+
+    BOOL SetCellType(int nRow, int nCol, CRuntimeClass* pRuntimeClass);
+    BOOL SetDefaultCellType( CRuntimeClass* pRuntimeClass);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Operations
+///////////////////////////////////////////////////////////////////////////////////
+public:
+    int  InsertColumn(LPCTSTR strHeading, UINT nFormat = DT_CENTER|DT_VCENTER|DT_SINGLELINE,
+                      int nColumn = -1);
+    int  InsertRow(LPCTSTR strHeading, int nRow = -1);
+    BOOL DeleteColumn(int nColumn);
+    BOOL DeleteRow(int nRow);
+    BOOL DeleteNonFixedRows();
+    BOOL DeleteAllItems();
+
+	void ClearCells(CCellRange Selection);
+
+    BOOL AutoSizeRow(int nRow, BOOL bResetScroll = TRUE);
+    BOOL AutoSizeColumn(int nCol, UINT nAutoSizeStyle = GVS_DEFAULT, BOOL bResetScroll = TRUE);
+    void AutoSizeRows();
+    void AutoSizeColumns(UINT nAutoSizeStyle = GVS_DEFAULT);
+    void AutoSize(UINT nAutoSizeStyle = GVS_DEFAULT);
+    void ExpandColumnsToFit(BOOL bExpandFixed = TRUE);
+    void ExpandLastColumn();
+    void ExpandRowsToFit(BOOL bExpandFixed = TRUE);
+    void ExpandToFit(BOOL bExpandFixed = TRUE);
+
+    void Refresh();
+    void AutoFill();   // Fill grid with blank cells
+
+    void EnsureVisible(CCellID &cell)       { EnsureVisible(cell.row, cell.col); }
+    void EnsureVisible(int nRow, int nCol);
+    BOOL IsCellVisible(int nRow, int nCol);
+    BOOL IsCellVisible(CCellID cell);
+    BOOL IsCellEditable(int nRow, int nCol) const;
+    BOOL IsCellEditable(CCellID &cell) const;
+    BOOL IsCellSelected(int nRow, int nCol) const;
+    BOOL IsCellSelected(CCellID &cell) const;
+
+    // SetRedraw stops/starts redraws on things like changing the # rows/columns
+    // and autosizing, but not for user-intervention such as resizes
+    void SetRedraw(BOOL bAllowDraw, BOOL bResetScrollBars = FALSE);
+    BOOL RedrawCell(int nRow, int nCol, CDC* pDC = NULL);
+    BOOL RedrawCell(const CCellID& cell, CDC* pDC = NULL);
+    BOOL RedrawRow(int row);
+    BOOL RedrawColumn(int col);
+
+#ifndef _WIN32_WCE
+    BOOL Save(LPCTSTR filename, TCHAR chSeparator = _T(','));
+    BOOL Load(LPCTSTR filename, TCHAR chSeparator = _T(','));
+#endif
+
+///////////////////////////////////////////////////////////////////////////////////
+// Cell Ranges
+///////////////////////////////////////////////////////////////////////////////////
+ public:
+    CCellRange GetCellRange() const;
+    CCellRange GetSelectedCellRange() const;
+    void SetSelectedRange(const CCellRange& Range, BOOL bForceRepaint = FALSE, BOOL bSelectCells = TRUE);
+    void SetSelectedRange(int nMinRow, int nMinCol, int nMaxRow, int nMaxCol,
+                          BOOL bForceRepaint = FALSE, BOOL bSelectCells = TRUE);
+    BOOL IsValid(int nRow, int nCol) const;
+    BOOL IsValid(const CCellID& cell) const;
+    BOOL IsValid(const CCellRange& range) const;
+
+///////////////////////////////////////////////////////////////////////////////////
+// Clipboard, drag and drop, and cut n' paste operations
+///////////////////////////////////////////////////////////////////////////////////
+#ifndef GRIDCONTROL_NO_CLIPBOARD
+    virtual void CutSelectedText();
+    virtual COleDataSource* CopyTextFromGrid();
+    virtual BOOL PasteTextToGrid(CCellID cell, COleDataObject* pDataObject, BOOL bSelectPastedCells=TRUE);
+#endif
+
+#ifndef GRIDCONTROL_NO_DRAGDROP
+ public:
+    virtual void OnBeginDrag();
+    virtual DROPEFFECT OnDragEnter(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+    virtual DROPEFFECT OnDragOver(COleDataObject* pDataObject, DWORD dwKeyState, CPoint point);
+    virtual void OnDragLeave();
+    virtual BOOL OnDrop(COleDataObject* pDataObject, DROPEFFECT dropEffect, CPoint point);
+#endif
+
+#ifndef GRIDCONTROL_NO_CLIPBOARD
+    virtual void OnEditCut();
+    virtual void OnEditCopy();
+    virtual void OnEditPaste();
+#endif
+    virtual void OnEditSelectAll();
+
+///////////////////////////////////////////////////////////////////////////////////
+// Misc.
+///////////////////////////////////////////////////////////////////////////////////
+public:
+    CCellID GetNextItem(CCellID& cell, int nFlags) const;
+
+	BOOL SortItems(int nCol, BOOL bAscending, LPARAM data = 0);
+    BOOL SortTextItems(int nCol, BOOL bAscending, LPARAM data = 0);
+    BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data = 0);
+
+	void SetCompareFunction(PFNLVCOMPARE pfnCompare);
+
+	// in-built sort functions
+	static int CALLBACK pfnCellTextCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+	static int CALLBACK pfnCellNumericCompare(LPARAM lParam1, LPARAM lParam2, LPARAM lParamSort);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Printing
+///////////////////////////////////////////////////////////////////////////////////
+#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
+public:
+    void Print(CPrintDialog* pPrntDialog = NULL);
+
+    // EFW - New printing support functions
+    void EnableWysiwygPrinting(BOOL bEnable = TRUE) { m_bWysiwygPrinting = bEnable;     }
+    BOOL GetWysiwygPrinting()                       { return m_bWysiwygPrinting;        }
+
+    void SetShadedPrintOut(BOOL bEnable = TRUE)     {   m_bShadedPrintOut = bEnable;    }
+    BOOL GetShadedPrintOut(void)                    {   return m_bShadedPrintOut;       }
+
+    // Use -1 to have it keep the existing value
+    void SetPrintMarginInfo(int nHeaderHeight, int nFooterHeight,
+        int nLeftMargin, int nRightMargin, int nTopMargin,
+        int nBottomMargin, int nGap);
+
+    void GetPrintMarginInfo(int &nHeaderHeight, int &nFooterHeight,
+        int &nLeftMargin, int &nRightMargin, int &nTopMargin,
+        int &nBottomMargin, int &nGap);
+
+///////////////////////////////////////////////////////////////////////////////////
+// Printing overrides for derived classes
+///////////////////////////////////////////////////////////////////////////////////
+public:
+    virtual void OnBeginPrinting(CDC *pDC, CPrintInfo *pInfo);
+    virtual void OnPrint(CDC *pDC, CPrintInfo *pInfo);
+    virtual void OnEndPrinting(CDC *pDC, CPrintInfo *pInfo);
+
+#endif // #if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
+
+// Implementation
+public:
+    virtual ~CakGridCtrl();
+
+	static BOOL RegisterWindowClass();
+protected:
+    
+    BOOL Initialise();
+    void SetupDefaultCells();
+
+    LRESULT SendMessageToParent(int nRow, int nCol, int nMessage) const;
+    LRESULT SendDisplayRequestToParent(GV_DISPINFO* pDisplayInfo) const;
+    LRESULT SendCacheHintToParent(const CCellRange& range) const;
+
+    BOOL InvalidateCellRect(const int row, const int col);
+    BOOL InvalidateCellRect(const CCellID& cell);
+    BOOL InvalidateCellRect(const CCellRange& cellRange);
+    void EraseBkgnd(CDC* pDC);
+
+    BOOL GetCellRangeRect(const CCellRange& cellRange, LPRECT lpRect);
+
+    BOOL SetCell(int nRow, int nCol, CGridCellBase* pCell);
+
+    int  SetMouseMode(int nMode) { int nOldMode = m_MouseMode; m_MouseMode = nMode; return nOldMode; }
+    int  GetMouseMode() const    { return m_MouseMode; }
+
+    BOOL MouseOverRowResizeArea(CPoint& point);
+    BOOL MouseOverColumnResizeArea(CPoint& point);
+
+    CCellID GetTopleftNonFixedCell(BOOL bForceRecalculation = FALSE);
+    CCellRange GetUnobstructedNonFixedCellRange(BOOL bForceRecalculation = FALSE);
+    CCellRange GetVisibleNonFixedCellRange(LPRECT pRect = NULL, BOOL bForceRecalculation = FALSE);
+    CCellRange GetVisibleFixedCellRange(LPRECT pRect = NULL, BOOL bForceRecalculation = FALSE);
+
+    BOOL IsVisibleVScroll() { return ( (m_nBarState & GVL_VERT) > 0); } 
+    BOOL IsVisibleHScroll() { return ( (m_nBarState & GVL_HORZ) > 0); }
+    void ResetSelectedRange();
+    void ResetScrollBars();
+    void EnableScrollBars(int nBar, BOOL bEnable = TRUE);
+    int  GetScrollPos32(int nBar, BOOL bGetTrackPos = FALSE);
+    BOOL SetScrollPos32(int nBar, int nPos, BOOL bRedraw = TRUE);
+
+    BOOL SortTextItems(int nCol, BOOL bAscending, int low, int high);
+    BOOL SortItems(PFNLVCOMPARE pfnCompare, int nCol, BOOL bAscending, LPARAM data,
+                   int low, int high);
+
+    CPoint GetPointClicked(int nRow, int nCol, const CPoint& point);
+
+	void ValidateAndModifyCellContents(int nRow, int nCol, LPCTSTR strText);
+
+// Overrrides
+    // ClassWizard generated virtual function overrides
+    //{{AFX_VIRTUAL(CGridCtrl)
+    protected:
+    virtual void PreSubclassWindow();
+    //}}AFX_VIRTUAL
+
+protected:
+#if !defined(_WIN32_WCE_NO_PRINTING) && !defined(GRIDCONTROL_NO_PRINTING)
+    // Printing
+	virtual void PrintFixedRowCells(int nStartColumn, int nStopColumn, int& row, CRect& rect,
+                                    CDC *pDC, BOOL& bFirst);
+    virtual void PrintColumnHeadings(CDC *pDC, CPrintInfo *pInfo);
+    virtual void PrintHeader(CDC *pDC, CPrintInfo *pInfo);
+    virtual void PrintFooter(CDC *pDC, CPrintInfo *pInfo);
+    virtual void PrintRowButtons(CDC *pDC, CPrintInfo* /*pInfo*/);
+#endif
+
+#ifndef GRIDCONTROL_NO_DRAGDROP
+    // Drag n' drop
+    virtual CImageList* CreateDragImage(CPoint *pHotSpot);    // no longer necessary
+#endif
+
+    // Mouse Clicks
+    virtual void  OnFixedColumnClick(CCellID& cell);
+    virtual void  OnFixedRowClick(CCellID& cell);
+
+    // Editing
+    virtual void  OnEditCell(int nRow, int nCol, CPoint point, UINT nChar);
+    virtual void  OnEndEditCell(int nRow, int nCol, CString str);
+	virtual BOOL  ValidateEdit(int nRow, int nCol, LPCTSTR str);
+    virtual void  EndEditing();
+
+    // Drawing
+    virtual void  OnDraw(CDC* pDC);
+
+    // CGridCellBase Creation and Cleanup
+    virtual CGridCellBase* CreateCell(int nRow, int nCol);
+    virtual void DestroyCell(int nRow, int nCol);
+
+// Attributes
+protected:
+    // General attributes
+    COLORREF    m_crFixedTextColour, m_crFixedBkColour;
+    COLORREF    m_crGridBkColour, m_crGridLineColour;
+    COLORREF    m_crWindowText, m_crWindowColour, m_cr3DFace,     // System colours
+                m_crShadow;
+    COLORREF    m_crTTipBackClr, m_crTTipTextClr;                 // Titletip colours - FNA
+    
+    BOOL        m_bVirtualMode;
+    LPARAM      m_lParam;                                           // lParam for callback
+    GRIDCALLBACK m_pfnCallback;                                     // The callback function
+
+    int         m_nGridLines;
+    BOOL        m_bEditable;
+    BOOL        m_bModified;
+    BOOL        m_bAllowDragAndDrop;
+    BOOL        m_bListMode;
+    BOOL        m_bSingleRowSelection;
+    BOOL        m_bSingleColSelection;
+    BOOL        m_bAllowDraw;
+    BOOL        m_bEnableSelection;
+    BOOL        m_bFixedRowSelection, m_bFixedColumnSelection;
+    BOOL        m_bSortOnClick;
+    BOOL        m_bHandleTabKey;
+    BOOL        m_bDoubleBuffer;
+    BOOL        m_bTitleTips;
+    int         m_nBarState;
+    BOOL        m_bWysiwygPrinting;
+    BOOL        m_bHiddenColUnhide, m_bHiddenRowUnhide;
+    BOOL        m_bAllowColHide, m_bAllowRowHide;
+    BOOL        m_bAutoSizeSkipColHdr;
+    BOOL        m_bTrackFocusCell;
+    BOOL        m_bFrameFocus;
+    UINT        m_nAutoSizeColumnStyle;
+
+    // Cell size details
+    int         m_nRows, m_nFixedRows, m_nCols, m_nFixedCols;
+    CUIntArray  m_arRowHeights, m_arColWidths;
+    int         m_nVScrollMax, m_nHScrollMax;
+
+    // Fonts and images
+    CRuntimeClass*   m_pRtcDefault; // determines kind of Grid Cell created by default
+    CGridDefaultCell m_cellDefault;  // "default" cell. Contains default colours, font etc.
+    CGridDefaultCell m_cellFixedColDef, m_cellFixedRowDef, m_cellFixedRowColDef;
+    CFont       m_PrinterFont;  // for the printer
+    CImageList* m_pImageList;
+
+    // Cell data
+    CTypedPtrArray<CObArray, GRID_ROW*> m_RowData;
+
+    // Mouse operations such as cell selection
+    int         m_MouseMode;
+    BOOL        m_bLMouseButtonDown, m_bRMouseButtonDown;
+    CPoint      m_LeftClickDownPoint, m_LastMousePoint;
+    CCellID     m_LeftClickDownCell, m_SelectionStartCell;
+    CCellID     m_idCurrentCell, m_idTopLeftCell;
+    INT_PTR     m_nTimerID;
+    int         m_nTimerInterval;
+    int         m_nResizeCaptureRange;
+    BOOL        m_bAllowRowResize, m_bAllowColumnResize;
+    int         m_nRowsPerWheelNotch;
+    CMap<DWORD,DWORD, CCellID, CCellID&> m_SelectedCellMap, m_PrevSelectedCellMap;
+
+#ifndef GRIDCONTROL_NO_TITLETIPS
+    CTitleTip   m_TitleTip;             // Title tips for cells
+#endif
+
+    // Drag and drop
+    CCellID     m_LastDragOverCell;
+#ifndef GRIDCONTROL_NO_DRAGDROP
+    CGridDropTarget m_DropTarget;       // OLE Drop target for the grid
+#endif
+
+    // Printing information
+    CSize       m_CharSize;
+    int         m_nPageHeight;
+    CSize       m_LogicalPageSize,      // Page size in gridctrl units.
+                m_PaperSize;            // Page size in device units.
+    // additional properties to support Wysiwyg printing
+    int         m_nPageWidth;
+    int         m_nPrintColumn;
+    int         m_nCurrPrintRow;
+    int         m_nNumPages;
+    int         m_nPageMultiplier;
+
+    // sorting
+    int          m_bAscending;
+    int          m_nSortColumn;
+	PFNLVCOMPARE m_pfnCompare;
+
+    // EFW - Added to support shaded/unshaded printout.  If true, colored
+    // cells will print as-is.  If false, all text prints as black on white.
+    BOOL        m_bShadedPrintOut;
+
+    // EFW - Added support for user-definable margins.  Top and bottom are in 
+    // lines.  Left, right, and gap are in characters (avg width is used).
+    int         m_nHeaderHeight, m_nFooterHeight, m_nLeftMargin,
+                m_nRightMargin, m_nTopMargin, m_nBottomMargin, m_nGap;
+
+protected:
+    void SelectAllCells();
+    void SelectColumns(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
+    void SelectRows(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
+    void SelectCells(CCellID currentCell, BOOL bForceRedraw=FALSE, BOOL bSelectCells=TRUE);
+    void OnSelecting(const CCellID& currentCell);
+
+    // Generated message map functions
+    //{{AFX_MSG(CGridCtrl)
+    afx_msg void OnPaint();
+    afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+    afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
+    afx_msg void OnSize(UINT nType, int cx, int cy);
+    afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
+    afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
+    afx_msg void OnMouseMove(UINT nFlags, CPoint point);
+    afx_msg void OnTimer(UINT_PTR nIDEvent);
+    afx_msg UINT OnGetDlgCode();
+    afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
+    afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
+    afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
+    afx_msg BOOL OnEraseBkgnd(CDC* pDC);
+    afx_msg void OnSysKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
+    afx_msg void OnUpdateEditSelectAll(CCmdUI* pCmdUI);
+    //}}AFX_MSG
+#ifndef _WIN32_WCE_NO_CURSOR
+    afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
+#endif
+#ifndef _WIN32_WCE
+    afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
+    afx_msg void OnRButtonUp(UINT nFlags, CPoint point);    // EFW - Added
+    afx_msg void OnSysColorChange();
+#endif
+#ifndef _WIN32_WCE_NO_CURSOR
+    afx_msg void OnCaptureChanged(CWnd *pWnd);
+#endif
+#ifndef GRIDCONTROL_NO_CLIPBOARD
+    afx_msg void OnUpdateEditCopy(CCmdUI* pCmdUI);
+    afx_msg void OnUpdateEditCut(CCmdUI* pCmdUI);
+    afx_msg void OnUpdateEditPaste(CCmdUI* pCmdUI);
+#endif
+#if (_MFC_VER >= 0x0421) || (_WIN32_WCE >= 210)
+    afx_msg void OnSettingChange(UINT uFlags, LPCTSTR lpszSection);
+#endif
+#if !defined(_WIN32_WCE) && (_MFC_VER >= 0x0421)
+    afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
+#endif
+    afx_msg LRESULT OnSetFont(WPARAM hFont, LPARAM lParam);
+    afx_msg LRESULT OnGetFont(WPARAM hFont, LPARAM lParam);
+    afx_msg LRESULT OnImeChar(WPARAM wCharCode, LPARAM lParam);
+    afx_msg void OnEndInPlaceEdit(NMHDR* pNMHDR, LRESULT* pResult);
+    DECLARE_MESSAGE_MAP()
+
+    enum eMouseModes { MOUSE_NOTHING, MOUSE_SELECT_ALL, MOUSE_SELECT_COL, MOUSE_SELECT_ROW,
+                       MOUSE_SELECT_CELLS, MOUSE_SCROLLING_CELLS,
+                       MOUSE_OVER_ROW_DIVIDE, MOUSE_SIZING_ROW,
+                       MOUSE_OVER_COL_DIVIDE, MOUSE_SIZING_COL,
+                       MOUSE_PREPARE_EDIT,
+#ifndef GRIDCONTROL_NO_DRAGDROP
+                       MOUSE_PREPARE_DRAG, MOUSE_DRAGGING
+#endif
+    };
+//      for sort in virtual mode, and column order, save and load layer
+public:
+	typedef std::vector<int> intlist;
+	void Reorder(int From, int To);
+	void SetVirtualCompare(PVIRTUALCOMPARE VirtualCompare) { m_pfnVirtualCompare = VirtualCompare;}
+	int m_CurCol;
+	void AllowReorderColumn(bool b=true) { m_AllowReorderColumn = b;}
+	void EnableDragRowMode(bool b=true) { m_bDragRowMode = b; if(b) EnableDragAndDrop(); } // to change row order
+	int GetLayer(int** pLayer); //  gives back the number of ints of the area (do not forget to delete *pLayer)
+	void SetLayer(int* pLayer); // coming from a previous GetLayer (ignored if not same number of column, or the same revision number)
+	void ForceQuitFocusOnTab(bool b=true) { m_QuitFocusOnTab = b;} // use only if GetParent() is a CDialog
+	void AllowSelectRowInFixedCol(bool b=true) { m_AllowSelectRowInFixedCol = b;} // 
+//    allow acces?
+	intlist m_arRowOrder, m_arColOrder;
+	static CakGridCtrl* m_This;
+protected:
+	virtual void AddSubVirtualRow(int Num, int Nb);
+	bool m_bDragRowMode;
+	int m_CurRow;
+private:
+	void ResetVirtualOrder();
+	PVIRTUALCOMPARE m_pfnVirtualCompare;
+	static bool NotVirtualCompare(int c1, int c2);
+	bool m_InDestructor;
+	bool m_AllowReorderColumn;
+	bool m_QuitFocusOnTab;
+	bool m_AllowSelectRowInFixedCol;
+
+};
+
+// Returns the default cell implementation for the given grid region
+inline CGridCellBase* CakGridCtrl::GetDefaultCell(BOOL bFixedRow, BOOL bFixedCol) const
+{ 
+    if (bFixedRow && bFixedCol) return (CGridCellBase*) &m_cellFixedRowColDef;
+    if (bFixedRow)              return (CGridCellBase*) &m_cellFixedRowDef;
+    if (bFixedCol)              return (CGridCellBase*) &m_cellFixedColDef;
+    return (CGridCellBase*) &m_cellDefault;
+}
+
+inline CGridCellBase* CakGridCtrl::GetCell(int nRow, int nCol) const
+{
+    if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols) 
+        return NULL;
+
+    if (GetVirtualMode())
+    {
+        CGridCellBase* pCell = GetDefaultCell(nRow < m_nFixedRows, nCol < m_nFixedCols);
+        static GV_DISPINFO gvdi;
+        gvdi.item.row     = nRow;
+        gvdi.item.col     = nCol;
+        gvdi.item.mask    = 0xFFFFFFFF;
+        gvdi.item.nState  = 0;
+        gvdi.item.nFormat = pCell->GetFormat();
+        gvdi.item.iImage  = pCell->GetImage();
+        gvdi.item.crBkClr = pCell->GetBackClr();
+        gvdi.item.crFgClr = pCell->GetTextClr();
+        gvdi.item.lParam  = pCell->GetData();
+        memcpy(&gvdi.item.lfFont, pCell->GetFont(), sizeof(LOGFONT));
+        gvdi.item.nMargin = pCell->GetMargin();
+        gvdi.item.strText.Empty();
+
+        // Fix the state bits
+        if (IsCellSelected(nRow, nCol))   gvdi.item.nState |= GVIS_SELECTED;
+        if (nRow < GetFixedRowCount())    gvdi.item.nState |= (GVIS_FIXED | GVIS_FIXEDROW);
+        if (nCol < GetFixedColumnCount()) gvdi.item.nState |= (GVIS_FIXED | GVIS_FIXEDCOL);
+        if (GetFocusCell() == CCellID(nRow, nCol)) gvdi.item.nState |= GVIS_FOCUSED;
+		if(!m_InDestructor)
+		{
+			gvdi.item.row = m_arRowOrder[nRow];
+			gvdi.item.col = m_arColOrder[nCol];
+
+			if (m_pfnCallback)
+				m_pfnCallback(&gvdi, m_lParam);
+			else
+				SendDisplayRequestToParent(&gvdi);
+			gvdi.item.row = nRow;        
+			gvdi.item.col = nCol;
+		}
+        static CGridCell cell;
+        cell.SetState(gvdi.item.nState);
+        cell.SetFormat(gvdi.item.nFormat);
+        cell.SetImage(gvdi.item.iImage);
+        cell.SetBackClr(gvdi.item.crBkClr);
+        cell.SetTextClr(gvdi.item.crFgClr);
+        cell.SetData(gvdi.item.lParam);
+        cell.SetFont(&(gvdi.item.lfFont));
+        cell.SetMargin(gvdi.item.nMargin);
+        cell.SetText(gvdi.item.strText);
+        cell.SetGrid((CakGridCtrl*)this);
+
+        return (CGridCellBase*) &cell;
+    }
+
+    GRID_ROW* pRow = m_RowData[nRow];
+    if (!pRow) return NULL;
+    return pRow->GetAt(m_arColOrder[nCol]);
+}
+
+inline BOOL CakGridCtrl::SetCell(int nRow, int nCol, CGridCellBase* pCell)
+{
+    if (GetVirtualMode())
+        return FALSE;
+
+    if (nRow < 0 || nRow >= m_nRows || nCol < 0 || nCol >= m_nCols) 
+        return FALSE;
+
+    GRID_ROW* pRow = m_RowData[nRow];
+    if (!pRow) return FALSE;
+
+    pCell->SetCoords( nRow, nCol); 
+    pRow->SetAt(nCol, pCell);
+
+    return TRUE;
+}
+
+/////////////////////////////////////////////////////////////////////////////
+
+//{{AFX_INSERT_LOCATION}}
+// Microsoft Developer Studio will insert additional declarations immediately before the previous line.
+
+#endif // !defined(AFX_GRIDCTRL_H__519FA702_722C_11D1_ABBA_00A0243D1382__INCLUDED_)
diff --git a/ReviewHistory/include/akGridCtrl/akGridCtrlLinker.h b/ReviewHistory/include/akGridCtrl/akGridCtrlLinker.h
new file mode 100644
index 0000000..6491106
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/akGridCtrlLinker.h
@@ -0,0 +1,65 @@
+#pragma once
+
+
+#ifdef _AKGRIDCTRL_EXPORTS
+#define AKGRIDCTRL_DLLSPEC    __declspec( dllexport )
+#else
+#define AKGRIDCTRL_DLLSPEC    __declspec( dllimport )
+#endif
+
+
+
+
+#ifndef _AKGRIDCTRL_EXPORTS
+
+	#undef _AUTOLIBNAME
+	#undef _AKPROJECTNAME
+	#undef _AKVCVER
+	#undef _AKDEBUG
+
+	#define _AKPROJECTNAME "akGridCtrl"
+	
+	#ifdef _DEBUG
+		#define _AKDEBUG "d"
+	#else
+		#define _AKDEBUG ""
+	#endif
+
+	#ifdef WIN64 
+		#define _AKX64 "_x64"
+	#elif _WIN64 
+		#define _AKX64 "_x64"
+	#else        
+		#define _AKX64 ""
+	#endif
+	
+	#if(_MSC_VER == 1200) //vs6.0
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER == 1300) //vs2003 vc7
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER == 1400) //vs2005 vc8
+		#define _AKVCVER "_vc8"
+	#elif(_MSC_VER == 1500) //vs2008 vc9
+		#define _AKVCVER "_vc9"
+	#elif(_MSC_VER == 1600) //vs2010
+		#define _AKVCVER "_vc10"
+	#elif(_MSC_VER == 1700) //vs2012
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER == 1800) //vs2013
+		#error 해당버전은 지원하지 않습니다.
+	#elif(_MSC_VER >= 1910 && _MSC_VER < 1950) //vs2017 15.0
+		#define _AKVCVER "_vc15"
+	#else   
+		//#define _AKVCVER ""
+		#pragma message( "해당버전은 지원하지 않습니다. " _MSC_VER )
+		#error _MSC_VER 해당버전은 지원하지 않습니다.
+	#endif
+
+	#define _AUTOLIBNAME _AKPROJECTNAME""_AKDEBUG""_AKX64""_AKVCVER".lib"
+	
+	// You may turn off this include message by defining _NOPSAUTOLIB
+	#ifndef _NOPSAUTOLIBMSG
+	#pragma message( ">>Kim Tae Hyun - akGrid<< Will automatically link with " _AUTOLIBNAME )
+	#endif
+	#pragma comment(lib, _AUTOLIBNAME)
+#endif
diff --git a/ReviewHistory/include/akGridCtrl/testCtrl.h b/ReviewHistory/include/akGridCtrl/testCtrl.h
new file mode 100644
index 0000000..c178507
--- /dev/null
+++ b/ReviewHistory/include/akGridCtrl/testCtrl.h
@@ -0,0 +1,25 @@
+#pragma once
+
+
+// ctest11
+#define WND_CLASSNAME    _T("testCtrl")  // Window class name
+
+class AFX_EXT_CLASS CtestCtrl : public CWnd
+{
+	DECLARE_DYNAMIC(CtestCtrl)
+
+public:
+	CtestCtrl();
+	virtual ~CtestCtrl();
+
+	static BOOL RegisterWindowClass(HINSTANCE hInstance);
+
+protected:
+	DECLARE_MESSAGE_MAP()
+	
+public:
+	virtual BOOL Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext = NULL);
+	afx_msg void OnPaint();
+};
+
+
diff --git a/ReviewHistory/include/akSTL/akColor.h b/ReviewHistory/include/akSTL/akColor.h
new file mode 100644
index 0000000..796fb2c
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akColor.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "akSTLLinker.h"
+
+
+//namespace akSTL
+//{
+	class AKSTL_DLLSPEC akColor4f
+	{
+	public:
+		akColor4f(void);
+		akColor4f(float R, float G, float B, float A=0.0f);
+		~akColor4f(void);
+
+
+		void set(float R, float G, float B, float A=0.0f);
+		inline akColor4f& operator=(const akColor4f& ksgcolor);
+
+	public:
+		float r,g,b,a;
+	};
+
+//};
diff --git a/ReviewHistory/include/akSTL/akPoint.h b/ReviewHistory/include/akSTL/akPoint.h
new file mode 100644
index 0000000..372fed3
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akPoint.h
@@ -0,0 +1,48 @@
+#pragma once
+
+#include "akSTLLinker.h"
+#include "akPointT.h"
+
+#define CakPointToCPoint(akPoint) CPoint(akPoint.x, akPoint.y)
+#define CPointToCakPoint(point) CakPoint(point.x, point.y)
+
+class AKSTL_DLLSPEC CakPoint : public CakPointT<long>
+{
+public:
+
+	CakPoint(){};
+	virtual ~CakPoint(){};
+
+	CakPoint(const long& X, const long& Y) 
+	{
+		x=X,y=Y;
+	};
+
+	void test();
+};
+
+class AKSTL_DLLSPEC CakPointf : public CakPointT<float>
+{
+public:
+
+	CakPointf(){};
+	virtual ~CakPointf(){};
+
+	CakPointf(const float& X, const float& Y) 
+	{
+		x=X,y=Y;
+	};
+};
+
+class AKSTL_DLLSPEC CakPointd : public CakPointT<double>
+{
+public:
+
+	CakPointd(){};
+	virtual ~CakPointd(){};
+
+	CakPointd(const double& X, const double& Y) 
+	{
+		x=X,y=Y;
+	};
+};
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/akPointT.h b/ReviewHistory/include/akSTL/akPointT.h
new file mode 100644
index 0000000..878f0bd
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akPointT.h
@@ -0,0 +1,37 @@
+#pragma once
+
+#include "akSTLLinker.h"
+
+template<typename T>
+class CakPointT
+{
+public:
+	CakPointT(void){};
+	CakPointT(const T& X, const T& Y):x(X),y(Y) {};
+	//~CakPointT(void){};
+
+	// Operations
+
+	// translate the point
+	void Offset(T xOffset, T yOffset) throw();
+	void Offset(CakPointT<T> point) throw();
+	void SetPoint(T X, T Y) throw();
+
+	bool operator==(CakPointT<T> point) const throw();
+	bool operator!=(CakPointT<T> point) const throw();
+	void operator+=(CakPointT<T> point) throw();
+	void operator-=(CakPointT<T> point) throw();
+
+	// Operators returning CPoint values
+	CakPointT<T> operator-() const throw();
+	CakPointT<T> operator+(CakPointT<T> point) const throw();
+	CakPointT<T> operator-(CakPointT<T> point) const throw();
+
+
+
+public:
+	T x;
+	T y;
+};
+
+#include "inl/akPointT.inl"
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/akQueue.h b/ReviewHistory/include/akSTL/akQueue.h
new file mode 100644
index 0000000..92c0046
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akQueue.h
@@ -0,0 +1,100 @@
+#pragma once
+
+
+#include "akSTLLinker.h"
+#include <memory.h>
+
+	class AKSTL_DLLSPEC CakQueue
+	{
+	public:
+		CakQueue(void);
+		~CakQueue(void);
+
+	public:
+		bool empty()
+		{	
+			return m_nDataSize == 0 ? true : false;
+		}
+
+		size_t size()
+		{
+			return m_nDataSize;
+		}
+
+		char* front()
+		{
+			return &m_pQueue[m_stPoint];
+		}
+
+		char* back()
+		{
+			return &m_pQueue[m_stPoint+m_nDataSize-1];
+		}
+
+		void push(char _Val)
+		{
+			if(m_stPoint+m_nDataSize >= m_nMemSize)
+			{
+				size_t newsize = m_nMemSize*2;
+				char* pNewQueue = new char [newsize];
+				memcpy(pNewQueue, &m_pQueue[m_stPoint], sizeof(char)*(m_nMemSize-m_stPoint));
+				m_nMemSize = newsize;
+				m_stPoint = 0;
+				char* pTemp = m_pQueue;
+				m_pQueue = pNewQueue;
+				delete [] pTemp;
+
+			}
+
+			
+			m_pQueue[m_stPoint+m_nDataSize] = _Val;
+			m_nDataSize++;
+		}
+
+		void push(char* pVal, int nSize)
+		{
+			if(m_stPoint+m_nDataSize + nSize >= m_nMemSize)
+			{
+				size_t newsize = m_nMemSize+nSize*2;
+				char* pNewQueue = new char [newsize];
+				memcpy(pNewQueue, &m_pQueue[m_stPoint], sizeof(char)*(m_nMemSize-m_stPoint));
+				m_nMemSize = newsize;
+				m_stPoint = 0;
+				char* pTemp = m_pQueue;
+				m_pQueue = pNewQueue;
+				delete [] pTemp;
+
+			}
+
+			//m_enPoint++;
+			memcpy(&m_pQueue[m_stPoint+m_nDataSize], pVal, sizeof(char)*nSize);
+			m_nDataSize+=nSize;
+		}
+
+		void pop()
+		{
+			m_stPoint++;
+			m_nDataSize--;
+
+			if(m_nDataSize == 0)
+			{
+				m_stPoint=m_nDataSize=0;
+			}
+		}
+		void pop(int nSize)
+		{
+			m_stPoint += nSize;
+			m_nDataSize -= nSize;
+			
+			if(m_nDataSize == 0)
+			{
+				m_stPoint=m_nDataSize=0;
+			}
+		}
+	private:
+		size_t m_stPoint; //메모리 시작위치
+		size_t m_nDataSize; //메모리 끝 위치
+		size_t m_nMemSize; //할당된 메모리 사이즈
+		char*  m_pQueue;
+		
+	};
diff --git a/ReviewHistory/include/akSTL/akQueueCircle.h b/ReviewHistory/include/akSTL/akQueueCircle.h
new file mode 100644
index 0000000..c0fb42a
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akQueueCircle.h
@@ -0,0 +1,151 @@
+#pragma once
+
+
+#include "akSTLLinker.h"
+
+	template <typename T> 
+	class CakQueueCircle
+	{
+	public:
+		CakQueueCircle();
+		~CakQueueCircle();
+		
+		
+		void clear(); //메모리 삭제는 안됨
+		void setMemSize(unsigned int memsize); //memsize가 0일때 메모리 삭제
+		
+		void pushData(T point);
+		void setData( unsigned int nindex , T point );
+		void getData(T* pPointBuffer, unsigned int nBufferLength);
+		
+		int size(){return m_nPointNum;};
+
+		T& operator [](unsigned int nindex);
+		CakQueueCircle& operator= (CakQueueCircle& traj);
+
+		//static unsigned int s_TrajectorySize;
+
+
+		//가능하면 아래의 멤버 변수에 직접 수정은 하지 말것!!
+	public:
+		int m_nMemSize; //확보 메모리 사이즈
+		int m_nPointIndex; //현재 인덱스
+		int m_nPointNum; //현재 입력된 Point 갯수
+		T* m_pPoints; //데이터 변수
+	public:
+		unsigned long m_nPushCount;
+	};
+
+
+	template <typename T>
+	 CakQueueCircle<T>::CakQueueCircle(void)
+	{
+		m_pPoints = NULL;
+		m_nMemSize = 0;
+		m_nPushCount = 0;
+
+		clear();
+		setMemSize(100);
+	};
+
+
+	template <typename T>
+	CakQueueCircle<T>::~CakQueueCircle(void)
+	{
+		setMemSize(0);
+	};
+
+	template <typename T> 
+	void CakQueueCircle<T>::clear() //메모리 삭제는 안됨
+	{
+		m_nMemSize; //확보 메모리 사이즈
+		m_nPointIndex = -1; //현재 인덱스
+		m_nPointNum = 0; //현재 입력된 Point 갯수
+		//m_pPoints; //데이터 변수
+		m_nPushCount = 0;
+	}
+
+	template <typename T> 
+	void CakQueueCircle<T>::setMemSize(unsigned int memsize) //memsize가 0일때 메모리 삭제
+	{
+		//clear
+		if(m_pPoints != NULL)
+		{
+			clear();
+			m_nMemSize = 0;
+			delete [] m_pPoints;
+			m_pPoints = NULL;
+		}
+
+		if(memsize > 0)
+		{
+			m_nMemSize = memsize;
+
+			m_pPoints = new T [m_nMemSize];
+		}
+
+	}
+
+	template <typename T> 
+	void CakQueueCircle<T>::pushData(T point)
+	{
+		m_nPointIndex++;
+		if(m_nPointIndex >= m_nMemSize)
+		{
+			m_nPointIndex = 0;
+		}
+
+		m_nPointNum++;
+		if(m_nPointNum >= m_nMemSize)
+		{
+			m_nPointNum = m_nMemSize;
+		}
+
+		m_pPoints[m_nPointIndex] = point;
+		m_nPushCount++;
+	}
+
+	template <typename T>
+	void CakQueueCircle<T>::setData( unsigned int nindex , T point )
+	{
+		int pointindex = m_nPointIndex-nindex;
+
+		if(pointindex<0) pointindex = m_nPointNum + pointindex;
+
+		m_pPoints[pointindex] = point;
+	}
+
+	template <typename T> 
+	T& CakQueueCircle<T>::operator[]( unsigned int nindex )
+	{
+		int pointindex = m_nPointIndex-nindex;
+
+		if(pointindex<0) pointindex = m_nPointNum + pointindex;
+
+		return m_pPoints[pointindex];
+	}
+
+	template <typename T> 
+	CakQueueCircle<T>& CakQueueCircle<T>::operator=( CakQueueCircle<T>& queuecircle )
+	{
+		if(m_nMemSize != queuecircle.m_nMemSize)
+		{
+			if(m_pPoints)
+			{
+				delete [] m_pPoints;
+			}
+
+			m_pPoints = new T[queuecircle.m_nMemSize];
+		}
+
+
+		m_nMemSize		= queuecircle.m_nMemSize; 
+		m_nPointIndex	= queuecircle.m_nPointIndex;
+		m_nPointNum		= queuecircle.m_nPointNum; 
+
+		memcpy(m_pPoints, queuecircle.m_pPoints, sizeof(T)*queuecircle.m_nMemSize);
+
+
+
+		return *this;
+	}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/akRect.h b/ReviewHistory/include/akSTL/akRect.h
new file mode 100644
index 0000000..22a9119
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akRect.h
@@ -0,0 +1,117 @@
+#pragma once
+
+#include "akSTLLinker.h"
+#include "akRectT.h"
+#include "akPoint.h"
+
+#define CakRectToCRect(akRect) CRect(akRect.left, akRect.top, akRect.right, akRect.bottom)
+#define CRectToCakRect(rect) CakRect(rect.left, rect.top, rect.right, rect.bottom)
+#define CakRectSet(rectDes, rectSrc) rectDes.SetRect(rectSrc.left, rectSrc.top, rectSrc.right, rectSrc.bottom)
+
+class AKSTL_DLLSPEC CakRect : public CakRectT<long>
+{
+public:
+
+	CakRect(){};
+	CakRect(const long l, const long t, const long r, const long b){
+		left=l,top=t,right=r,bottom=b;
+	};
+	virtual ~CakRect(){};
+	
+public:
+	
+	// reference to the top-left point
+	CakPoint TopLeft() throw();
+	// reference to the bottom-right point
+	CakPoint BottomRight() throw();
+	// const reference to the top-left point
+	const CakPoint TopLeft() const throw();
+	// const reference to the bottom-right point
+	const CakPoint BottomRight() const throw();
+	// the geometric center point of the rectangle
+	CakPoint CenterPoint() const throw();
+
+	bool PtInRect(CakPoint point) const throw();
+	
+};
+
+class AKSTL_DLLSPEC CakRectn : public CakRectT<int>
+{
+public:
+
+	CakRectn(){};
+	CakRectn(int l, int t, int r, int b){
+		left=l,top=t,right=r,bottom=b;
+	};
+	virtual ~CakRectn(){};
+	
+public:
+
+	// reference to the top-left point
+	CakPoint TopLeft() throw();
+	// reference to the bottom-right point
+	CakPoint BottomRight() throw();
+	// const reference to the top-left point
+	const CakPoint TopLeft() const throw();
+	// const reference to the bottom-right point
+	const CakPoint BottomRight() const throw();
+	// the geometric center point of the rectangle
+	CakPoint CenterPoint() const throw();
+
+	bool PtInRect(CakPoint point) const throw();
+
+};
+
+class AKSTL_DLLSPEC CakRectf : public CakRectT<float>
+{
+public:
+
+	CakRectf(){};
+	CakRectf(float l, float t, float r, float b){
+		left=l,top=t,right=r,bottom=b;
+	};
+	virtual ~CakRectf(){};
+
+public:
+
+	// reference to the top-left point
+	CakPointf& TopLeft() throw();
+	// reference to the bottom-right point
+	CakPointf& BottomRight() throw();
+	// const reference to the top-left point
+	const CakPointf& TopLeft() const throw();
+	// const reference to the bottom-right point
+	const CakPointf& BottomRight() const throw();
+	// the geometric center point of the rectangle
+	CakPointf CenterPoint() const throw();
+
+	bool PtInRect(CakPointf point) const throw();
+
+};
+
+class AKSTL_DLLSPEC CakRectd : public CakRectT<double>
+{
+public:
+
+	CakRectd(){};
+	CakRectd(double l, double t, double r, double b){
+		left=l,top=t,right=r,bottom=b;
+	};
+	virtual ~CakRectd(){};
+
+public:
+
+	// reference to the top-left point
+	CakPointd TopLeft() throw();
+	// reference to the bottom-right point
+	CakPointd BottomRight() throw();
+	// const reference to the top-left point
+	const CakPointd TopLeft() const throw();
+	// const reference to the bottom-right point
+	const CakPointd BottomRight() const throw();
+	// the geometric center point of the rectangle
+	CakPointd CenterPoint() const throw();
+
+	bool PtInRect(CakPointd point) const throw();
+
+};
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/akRectT.h b/ReviewHistory/include/akSTL/akRectT.h
new file mode 100644
index 0000000..c3f11bc
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akRectT.h
@@ -0,0 +1,196 @@
+#pragma once
+
+
+
+template<typename T>
+class CakRectT
+{
+public:
+	T left;
+	T top;
+	T right;
+	T bottom;
+
+public:	
+	CakRectT(void);
+	//CakRectT(T l, T t, T r, T b);
+	CakRectT(const T l, const T t, const T r, const T b):left(l),top(t),right(r),bottom(b) {};
+	virtual ~CakRectT(void);
+	
+ 
+ 	//Attirbute
+ 	// retrieves the width
+ 	T Width() const throw();
+ 	// returns the height
+ 	T Height() const throw();
+ 	
+	//{
+	//	// reference to the top-left point
+	//	CPoint& TopLeft() throw();
+	//	// reference to the bottom-right point
+	//	CPoint& BottomRight() throw();
+	//	// const reference to the top-left point
+	//	const CPoint& TopLeft() const throw();
+	//	// const reference to the bottom-right point
+	//	const CPoint& BottomRight() const throw();
+	//	// the geometric center point of the rectangle
+	//	CPoint CenterPoint() const throw();
+	//
+	//	bool PtInRect(POINT point) const throw();
+	//}
+
+ 	// swap the left and right
+	void SwapLeftRight() throw();
+ 	void SwapTopBottom() throw();
+ 
+ 
+ 
+ 	// returns TRUE if rectangle has no area
+ 	bool IsRectEmpty() const throw();
+ 	// returns TRUE if rectangle is at (0,0) and has no area
+ 	bool IsRectNull() const throw();
+ 	// returns TRUE if point is within rectangle
+ 	
+	bool PtInRect(T x, T y) const throw();
+ 
+ 	// Operations
+ 
+ 	// set rectangle from left, top, right, and bottom
+ 	void SetRect(T x1, T y1, T x2, T y2) throw();
+ 	//void SetRect(POINT topLeft, POINT bottomRight) throw();
+ 	// empty the rectangle
+ 	void SetRectEmpty() throw();
+ 	// copy from another rectangle
+ 	void CopyRect(const CakRectT<T>* lpSrcRect) throw();
+ 	// TRUE if exactly the same as another rectangle
+ 	bool EqualRect(const CakRectT<T>* lpRect) const throw();
+
+	// Inflate rectangle's width and height by
+	// x units to the left and right ends of the rectangle
+	// and y units to the top and bottom.
+	void InflateRect(T x, T y) throw();
+	void InflateRect(T l, T t, T r, T b) throw();
+	void InflateRect(CakRectT<T>* lpRect) throw();
+
+	// deflate the rectangle's width and height without
+	// moving its top or left
+	void DeflateRect(T x, T y) throw();
+	void DeflateRect(T l, T t, T r, T b) throw();
+	//void DeflateRect(SIZE size) throw();
+	void DeflateRect(CakRectT<T>* lpRect) throw();
+
+	// translate the rectangle by moving its top and left
+	void OffsetRect(T x, T y) throw();
+	//void OffsetRect(SIZE size) throw();
+	//void OffsetRect(POINT point) throw();
+	void NormalizeRect() throw();
+ 
+	// absolute position of rectangle
+	void MoveToY(T y) throw();
+	void MoveToX(T x) throw();
+	void MoveToXY(T x, T y) throw();
+	//void MoveToXY(POINT point) throw();
+
+ 	// 두사각형이 겹치는 부분만 검출 없을시 0으로 셋팅(Return은 겹치는 부분이 있으면 True)
+ 	bool IntersectRect(CakRectT<T>* lpRect1, CakRectT<T>* lpRect2) throw();
+ 
+ 	// 두 사각형의 테두리 부분 검출(Return은 겹치는 부분이 있으면 True)
+ 	bool UnionRect(CakRectT<T>* lpRect1, CakRectT<T>* lpRect2) throw();
+	
+ 	// set this rectangle to minimum of two others
+ 	//bool SubtractRect(CakRectT<T>* lpRectSrc1, CakRectT<T>* lpRectSrc2) throw();
+
+	// Additional Operations
+	void operator=(const CakRectT<T>& srcRect) throw();
+	bool operator==(const CakRectT<T>& rect) const throw();
+	bool operator!=(const CakRectT<T>& rect) const throw();
+	void operator+=(CakRectT<T>* lpRect) throw();
+	void operator-=(CakRectT<T>* lpRect) throw();
+	//void operator&=(const CakRectT<T>& rect) throw();
+	//void operator|=(const CakRectT<T>& rect) throw();
+
+  	// Operators returning CakRectT<T> values
+  	//CakRectT<T> operator+(POINT point) const throw();
+  	//CakRectT<T> operator-(POINT point) const throw();
+  	CakRectT<T> operator+(CakRectT<T>* lpRect) const throw();
+  	//CakRectT<T> operator+(SIZE size) const throw();
+  	//CakRectT<T> operator-(SIZE size) const throw();
+  	CakRectT<T> operator-(CakRectT<T>* lpRect) const throw();
+  	//CakRectT<T> operator&(const CakRectT<T>& rect2) const throw();
+  	//CakRectT<T> operator|(const CakRectT<T>& rect2) const throw();
+
+ 	CakRectT<T> MulDiv(T nMultiplier, T nDivisor) const throw();
+
+	//예전에 쓰던 함수들
+public:
+	inline void set(T l, T t, T r, T b)
+	{
+		left = l;
+		top = t;
+		right = r;
+		bottom = b;	
+	};
+	inline T getWidth(){return right-left;};
+	inline T getHeight(){return bottom-top;};
+	inline T getCenter(){return T(left+(right-left)/2.0);};
+	inline T getVCenter(){return T(top+(bottom-top)/2.0);};
+	void setAlign(){NormalizeRect();}; //작은값이 왼쪽, 위, 큰값이 오른쪽 아래로 가게 한다.
+	bool getCheckAreaIn(double x, double y); //사각형 영역에 x,y포인트가 있는지 검사
+	bool getCheckWidthIn(double p1); //x포인트 가운데 점이 있는지 검사
+	bool getCheckHeightIn(double p1); //y포인트 가운데 점이 있는지 검사
+
+
+
+};
+
+
+template<typename T>
+bool CakRectT<T>::IntersectRect( CakRectT<T>* lpRect1, CakRectT<T>* lpRect2 ) throw()
+{
+	
+	if ( lpRect1->left	<	lpRect2->right	&&
+		lpRect1->top	<	lpRect2->bottom	&&
+		lpRect1->right	>	lpRect2->left	&&
+		lpRect1->bottom	>	lpRect2->top		)
+	{
+		//*this = *lpRect2;
+
+		lpRect1->left	> lpRect2->left   ? left	 = lpRect1->left	: left  = lpRect2->left		;	
+		lpRect1->top	> lpRect2->top	  ? top		 = lpRect1->top		: top	= lpRect2->top		;
+		lpRect1->right	< lpRect2->right  ? right	 = lpRect1->right	: right	= lpRect2->right	;
+		lpRect1->bottom < lpRect2->bottom ? bottom	 = lpRect1->bottom	: bottom= lpRect2->bottom	;
+
+		return true;
+	}
+
+	set(0,0,0,0);
+
+	return false;
+}
+
+template<typename T>
+bool CakRectT<T>::UnionRect( CakRectT<T>* lpRect1, CakRectT<T>* lpRect2 ) throw()
+{
+
+	lpRect1->left	< lpRect2->left   ? left	 = lpRect1->left	: left  = lpRect2->left	;	
+	lpRect1->top	< lpRect2->top	  ? top		 = lpRect1->top		: top	= lpRect2->top		;
+	lpRect1->right	> lpRect2->right  ? right	 = lpRect1->right	: right	= lpRect2->right	;
+	lpRect1->bottom > lpRect2->bottom ? bottom	 = lpRect1->bottom	: bottom= lpRect2->bottom	;
+	
+	if ( lpRect1->left	<	lpRect2->right	&&
+		lpRect1->top	<	lpRect2->bottom	&&
+		lpRect1->right	>	lpRect2->left	&&
+		lpRect1->bottom	>	lpRect2->top		)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+
+
+
+
+
+#include "inl/akRectT.inl"
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/akSTLLinker.h b/ReviewHistory/include/akSTL/akSTLLinker.h
new file mode 100644
index 0000000..6074873
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akSTLLinker.h
@@ -0,0 +1,56 @@
+#pragma once
+
+//#pragma warning(disable:4251)
+// 
+// typedef unsigned int uint;
+// typedef unsigned char byte;
+
+#ifdef AKSTL_EXPORTS
+#define AKSTL_DLLSPEC    __declspec( dllexport )
+#else
+#define AKSTL_DLLSPEC    __declspec( dllimport )
+#endif
+
+
+
+#ifndef AKSTL_EXPORTS
+
+	#undef _AUTOLIBNAME
+	#undef _AKPROJECTNAME
+	#undef _AKVCVER
+	#undef _AKDEBUG
+	#undef _AKWINDOWSDK
+
+	#define _AKPROJECTNAME "akSTL"
+
+
+	#ifdef _DEBUG
+	#define _AKDEBUG "d"
+	#else
+	#define _AKDEBUG ""
+	#endif
+
+	#if(_MSC_VER < 1910)
+	#define _AKWINDOWSDK ""
+	#else
+	#define _AKWINDOWSDK "_WS10"
+	#endif   
+
+
+	#ifdef WIN64 
+	#define _AKX64 "_x64"
+	#elif _WIN64 
+	#define _AKX64 "_x64"
+	#else        
+	#define _AKX64 ""
+	#endif
+
+	#define _AUTOLIBNAME _AKPROJECTNAME""_AKDEBUG""_AKWINDOWSDK""_AKX64".lib"
+
+	// You may turn off this include message by defining _NOPSAUTOLIB
+	#ifndef _NOPSAUTOLIBMSG
+		//#pragma message( ">>Advance Kim Templet Library<< Will automatically link with " _AUTOLIBNAME )
+		#pragma message( ">>Kim Tae Hyun - akSTL<< Will automatically link with " _AUTOLIBNAME )
+	#endif
+		#pragma comment(lib, _AUTOLIBNAME)
+#endif
diff --git a/ReviewHistory/include/akSTL/akStruct.h b/ReviewHistory/include/akSTL/akStruct.h
new file mode 100644
index 0000000..06ede5d
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akStruct.h
@@ -0,0 +1,8 @@
+#pragma once
+
+#include "akSTLLinker.h"
+
+#include "akPoint.h"
+#include "akRect.h"
+#include "akColor.h"
+
diff --git a/ReviewHistory/include/akSTL/akTrace.h b/ReviewHistory/include/akSTL/akTrace.h
new file mode 100644
index 0000000..dd561cc
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akTrace.h
@@ -0,0 +1,61 @@
+#pragma once
+
+
+
+
+#include "akLinker.h"
+#include <queue>
+#include <windows.h>
+
+class akSTL_DLLSPEC CakTrace
+{
+public:
+	CakTrace(void);
+	virtual ~CakTrace(void);
+
+	enum Mode
+	{
+		TM_MEMORY = 0,
+		TM_FILE
+	};
+	//0은 메모리에 데이터 관리 하는 모드, 1은 파일에 데이터를 관리 하는 모드
+	virtual void setMode(Mode nMode);
+
+	//TRACE
+	virtual void setTrace(char* format, ...);
+
+
+
+
+	//////////////////////////////////////////////////////////////////////////
+	//파일모드 일경우 사용 함수
+	//////////////////////////////////////////////////////////////////////////
+	
+	//저장할 파일 이름 지정
+	bool setTraceFileName(char* filename, bool bClear = true);
+
+
+
+
+	//////////////////////////////////////////////////////////////////////////
+	//메모리 모드 일경우 사용 함수
+	//////////////////////////////////////////////////////////////////////////
+	//저장공간 초기화
+	void clear(); 
+	//데이터 갯수 획득
+	int getTraceNum();
+	//저장된 데이터 획득
+	char* getTraceFront();
+	//젤 앞에 데이터를 획득하고 삭제
+	void getTracePop(char* pBuffer);
+	//메모리에 있는 데이터를 파일로 저장
+	void setWriteFile(char* filename, bool bAdd = true);
+	
+
+protected:
+	std::queue<char*> m_vecTraceData;
+	char* m_pTraceFileName;
+	Mode m_nMode;
+	CRITICAL_SECTION	m_csTrace;
+	FILE* m_pf;
+};
diff --git a/ReviewHistory/include/akSTL/akTrajectory.h b/ReviewHistory/include/akSTL/akTrajectory.h
new file mode 100644
index 0000000..493caa5
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akTrajectory.h
@@ -0,0 +1,170 @@
+#pragma once
+
+
+#include "akLinker.h"
+//#include "akSTLVector.h"
+
+//namespace akSTL
+//{
+#include <vector>
+
+
+
+
+	template <typename T> 
+	class CakTrajectory
+	{
+	public:
+		CakTrajectory();
+		~CakTrajectory();
+		
+		
+		void clear(); //메모리 삭제는 안됨
+		void setMemSize(unsigned int memsize); //memsize가 0일때 메모리 삭제
+		
+		void pointAdd(T point);
+		void pointSet( unsigned int nindex , T point );
+		void getPoints(T* pPointBuffer, unsigned int nBufferLength);
+		
+		int size(){return m_nPointNum;};
+		T& operator [](unsigned int nindex);
+		CakTrajectory& operator= (CakTrajectory& traj);
+
+		static unsigned int s_TrajectorySize;
+
+
+		//가능하면 아래의 멤버 변수에 직접 수정은 하지 말것!!
+	public:
+		int m_nMemSize; //확보 메모리 사이즈
+		int m_nPointIndex; //현재 인덱스
+		int m_nPointNum; //현재 입력된 Point 갯수
+		T* m_pPoints; //데이터 변수
+	};
+
+
+
+	
+	//}
+
+	
+
+
+
+
+	
+	template <typename T> 
+	unsigned int  CakTrajectory<T>::s_TrajectorySize = 100;
+
+
+	template <typename T>
+	 CakTrajectory<T>::CakTrajectory(void)
+	{
+		m_pPoints = NULL;
+		m_nMemSize = 0;
+
+		clear();
+		setMemSize(s_TrajectorySize);
+	};
+
+
+	template <typename T>
+	CakTrajectory<T>::~CakTrajectory(void)
+	{
+		setMemSize(0);
+	};
+
+	template <typename T> 
+	void CakTrajectory<T>::clear() //메모리 삭제는 안됨
+	{
+		m_nMemSize; //확보 메모리 사이즈
+		m_nPointIndex = -1; //현재 인덱스
+		m_nPointNum = 0; //현재 입력된 Point 갯수
+		//m_pPoints; //데이터 변수
+	}
+
+	template <typename T> 
+	void CakTrajectory<T>::setMemSize(unsigned int memsize) //memsize가 0일때 메모리 삭제
+	{
+		//clear
+		if(m_pPoints != NULL)
+		{
+			clear();
+			m_nMemSize = 0;
+			delete [] m_pPoints;
+			m_pPoints = NULL;
+		}
+
+		if(memsize > 0)
+		{
+			m_nMemSize = memsize;
+
+			m_pPoints = new T [m_nMemSize];
+		}
+
+	}
+
+	template <typename T> 
+	void CakTrajectory<T>::pointAdd(T point)
+	{
+		m_nPointIndex++;
+		if(m_nPointIndex >= m_nMemSize)
+		{
+			m_nPointIndex = 0;
+		}
+
+		m_nPointNum++;
+		if(m_nPointNum >= m_nMemSize)
+		{
+			m_nPointNum = m_nMemSize;
+		}
+
+		m_pPoints[m_nPointIndex] = point;
+	}
+
+	template <typename T>
+	void CakTrajectory<T>::pointSet( unsigned int nindex , T point )
+	{
+		int pointindex = m_nPointIndex-nindex;
+
+		if(pointindex<0) pointindex = m_nPointNum + pointindex;
+
+		m_pPoints[pointindex] = point;
+	}
+
+	template <typename T> 
+	T& CakTrajectory<T>::operator[]( unsigned int nindex )
+	{
+		int pointindex = m_nPointIndex-nindex;
+
+		if(pointindex<0) pointindex = m_nPointNum + pointindex;
+
+		return m_pPoints[pointindex];
+	}
+
+	template <typename T> 
+	CakTrajectory<T>& CakTrajectory<T>::operator=( CakTrajectory<T>& traj )
+	{
+		if(m_nMemSize != traj.m_nMemSize)
+		{
+			if(m_pPoints)
+			{
+				delete [] m_pPoints;
+			}
+
+			m_pPoints = new T[traj.m_nMemSize];
+		}
+
+
+		m_nMemSize		= traj.m_nMemSize; 
+		m_nPointIndex	= traj.m_nPointIndex;
+		m_nPointNum		= traj.m_nPointNum; 
+
+		memcpy(m_pPoints, traj.m_pPoints, sizeof(khVector3d)*traj.m_nMemSize);
+
+
+
+
+
+
+		return *this;
+	}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/akVector.h b/ReviewHistory/include/akSTL/akVector.h
new file mode 100644
index 0000000..7ee2918
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akVector.h
@@ -0,0 +1,45 @@
+#pragma once
+
+#include "akSTLLinker.h"
+#include "akVectorT.h"
+
+//#define CakPointToCPoint(akPoint) CPoint(akPoint.x, akPoint.y)
+//#define CPointToCakPoint(point) CakPoint(point.x, point.y)
+
+
+class AKSTL_DLLSPEC akVector3d : public CakVectorT<double>
+{
+public:
+
+	akVector3d(){};
+	virtual ~akVector3d(){};
+
+	akVector3d(const double& X, const double& Y, const double& Z) 
+	{
+		x=X,y=Y,z=Z;
+	};
+
+	akVector3d operator*(double& a)
+	{
+		akVector3d returnval;
+
+		returnval.x = x * a;
+		returnval.y = y * a;
+		returnval.z = z * a;
+
+		return returnval;
+	};
+
+	akVector3d operator *(akVector3d &vec)
+	{
+		akVector3d vc;
+		vc.x = y*vec.z - z*vec.y;
+		vc.y = z*vec.x - x*vec.z;
+		vc.z = x*vec.y - y*vec.x;
+		return vc;
+	}
+
+	
+	
+
+};
diff --git a/ReviewHistory/include/akSTL/akVectorT.h b/ReviewHistory/include/akSTL/akVectorT.h
new file mode 100644
index 0000000..6cccbbb
--- /dev/null
+++ b/ReviewHistory/include/akSTL/akVectorT.h
@@ -0,0 +1,50 @@
+#pragma once
+
+#include "akSTLLinker.h"
+
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+template<typename T>
+class CakVectorT
+{
+public:
+	CakVectorT(void){};
+	CakVectorT(const T& X, const T& Y, const T& Z):x(X),y(Y),z(Z) {};
+	//~CakVectorT(void){};
+
+	// Operations
+
+	// translate the point
+	void Offset(T xOffset, T yOffset, T zOffset) throw();
+	void Offset(CakVectorT<T> vector) throw();
+	void set(T X, T Y, T Z) throw();
+
+	bool operator==(CakVectorT<T> vector) const throw();
+	bool operator!=(CakVectorT<T> vector) const throw();
+	void operator+=(CakVectorT<T> vector) throw();
+	void operator-=(CakVectorT<T> vector) throw();
+
+	// Operators returning CakVector values
+	CakVectorT<T> operator-() const throw();
+	CakVectorT<T> operator+(CakVectorT<T> vector) const throw();
+	CakVectorT<T> operator-(CakVectorT<T> vector) const throw();
+
+	CakVectorT<T> operator*(T& a) const throw();
+	CakVectorT<T> operator*(CakVectorT<T> &vec) const throw();
+	
+
+	//내적
+	T Dot(CakVectorT<T> vec){	return (vec.x * x + vec.y * y + vec.z * z);	};
+	T Mag()					{	return sqrt(x*x+y*y);		};
+	T getLength()			{	return sqrt(x*x+y*y+z*z);	};
+	void Normalize();
+public:
+	T x,y,z;
+};
+
+
+
+
+#include "inl/akVectorT.inl"
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akColorStruct.h b/ReviewHistory/include/akSTL/backup/akColorStruct.h
new file mode 100644
index 0000000..dc1b73e
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akColorStruct.h
@@ -0,0 +1,128 @@
+#pragma once
+
+#include "khLinker.h"
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+namespace KimHeart
+{
+	struct KIMHEART_DLLSPEC khVector3d
+	{
+		double pos[3];
+
+		khVector3d();
+		khVector3d(double x,double y, double z);
+		inline void set(double x,double y, double z);
+		inline double x(){return pos[0];};
+		inline double y(){return pos[1];};
+		inline double z(){return pos[2];};
+
+		double& operator()(int index){return pos[index];};
+
+		inline khVector3d operator+(const khVector3d& vec3d);
+		inline khVector3d operator-(const khVector3d& vec3d);
+		inline khVector3d& operator=(const khVector3d& vec3d);
+		inline khVector3d& operator+=(const khVector3d& vec3d);
+		inline khVector3d& operator-=(const khVector3d& vec3d);
+		khVector3d operator*(float& a)
+		{
+			khVector3d returnval;
+
+			returnval.pos[0] = pos[0] * a;
+			returnval.pos[1] = pos[1] * a;
+			returnval.pos[2] = pos[2] * a;
+
+			return returnval;
+		};
+
+		khVector3d operator *(khVector3d &vec)
+		{
+			khVector3d vc;
+			vc.pos[0] = pos[1]*vec.pos[2] - pos[2]*vec.pos[1];
+			vc.pos[1] = pos[2]*vec.pos[0] - pos[0]*vec.pos[2];
+			vc.pos[2] = pos[0]*vec.pos[1] - pos[1]*vec.pos[0];
+			return vc;
+		}
+
+		float Dot(khVector3d vec)
+		{
+			return (float)(vec.pos[0] * pos[0] + vec.pos[1] * pos[1] + vec.pos[2] * pos[2]);
+		};
+		float Mag()
+		{
+			return (float)sqrt(pos[0]*pos[0]+pos[1]*pos[1]);
+		};
+		void Normalize()
+		{
+			float length;
+
+			//벡터의 길이를 계산한다.
+			length = (float)sqrt((pos[0]*pos[0]) + (pos[1]*pos[1]) +(pos[2]*pos[2]));
+			// 길이가 0에 가까운 벡터에게 절절한 값을 항당하여 프로그램이 폭주하지 않도록 한다.
+			if(length == 0.0f) length = 1.0f;
+
+			// 각 성분을 벡터의 길이로 나누면 단위 벡터가 된다.
+			pos[0] = pos[0] / length;
+			pos[1] = pos[1] / length;
+			pos[2] = pos[2] / length;
+
+		};
+	};
+
+	struct KIMHEART_DLLSPEC khVector2d
+	{
+		double pos[2];
+
+		khVector2d();
+		khVector2d(double x,double y);
+		inline void set(double x,double y);
+		inline double x(){return pos[0];};
+		inline double y(){return pos[1];};
+
+		double& operator()(int index){return pos[index];};
+
+		inline khVector2d operator+(const khVector2d& vec3d);
+		inline khVector2d operator-(const khVector2d& vec3d);
+		inline khVector2d& operator=(const khVector2d& vec3d);
+		inline khVector2d& operator+=(const khVector2d& vec3d);
+		inline khVector2d& operator-=(const khVector2d& vec3d);
+		
+	};
+
+	struct KIMHEART_DLLSPEC khColor4f
+	{
+		float color[4];
+
+		khColor4f();
+		khColor4f(float R, float G, float B, float A=0.0f);
+		void set(float R, float G, float B, float A=0.0f);
+		inline float R(){return color[0];};
+		inline float G(){return color[1];};
+		inline float B(){return color[2];};
+		inline float A(){return color[3];};
+		inline khColor4f& operator=(const khColor4f& ksgcolor);
+	};
+
+	struct KIMHEART_DLLSPEC khRect
+	{
+		double pos[4];
+
+		khRect();
+		khRect(double left, double top, double right, double bottom);
+		void set(double left, double top, double right, double bottom);
+		inline khRect& operator=(const khRect& rect);
+		inline double Left(){return pos[0];};
+		inline double Top(){return pos[1];};
+		inline double Right(){return pos[2];};
+		inline double Bottom(){return pos[3];};
+		inline double Width(){return pos[2]-pos[0];};
+		inline double Height(){return pos[3]-pos[1];};
+		inline void SetAlign(); //작은값이 왼쪽, 위, 큰값이 오른쪽 아래로 가게 한다.
+		inline bool CheckAreaIn(double x, double y); //사각형 영역에 x,y포인트가 있는지 검사
+		inline bool CheckWidthIn(double p1); //x포인트 가운데 점이 있는지 검사
+		inline bool CheckHeightIn(double p1); //y포인트 가운데 점이 있는지 검사
+
+
+	};
+};
diff --git a/ReviewHistory/include/akSTL/backup/akCoordinate.h b/ReviewHistory/include/akSTL/backup/akCoordinate.h
new file mode 100644
index 0000000..a2e1caa
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akCoordinate.h
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+
+	class akSTL_DLLSPEC CakCoordinate
+	{
+	public:
+		CakCoordinate(void);
+		~CakCoordinate(void);
+
+		//Degree를 도분초로 변환
+		static double GetDMStoDgree(int  d, int  m, double  s);
+		//도분초를 Degree로 변환
+		static void GetDgreetoDMS(double degree, int* d, int* m, double* s);
+		//Degree값을 180방위 + 방향(W,E)로 변환
+		static void GetMakeDMS180(int degree, int* rDeg, char* rDir);
+		//Degree값을 90방위 + 방향(S,N)로 변환
+		static void GetMakeDMS90(int degree, int* rDeg, char* rDir);
+		//Degree값을 //-180~+180로 변환
+		static double GetMakeDegree180(double degree);
+		//Degree값을 //-90~+90로 변환
+		static double GetMakeDegree90(double degree);
+	};
+
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akFileMgr.h b/ReviewHistory/include/akSTL/backup/akFileMgr.h
new file mode 100644
index 0000000..158d0b9
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akFileMgr.h
@@ -0,0 +1,80 @@
+#pragma once
+
+
+
+#include "akLinker.h"
+#include <vector>
+
+struct akSTL_DLLSPEC _Attribute
+{
+	_Attribute()
+	{
+		memset(Title		, 0, sizeof(char)*128);
+		memset(Attribute	, 0, sizeof(char)*128);
+		memset(Value		, 0, sizeof(char)*128);
+	}
+	char Title[128];
+	char Attribute[128];
+	char Value[128];
+};
+
+struct akSTL_DLLSPEC _Title
+{
+	_Title(char* title)
+	{
+		strcpy(Title, title);
+	};
+	bool compare(char* title)
+	{
+		if(strcmp(title, Title) == 0 && strlen(title) == strlen(Title))
+		{
+			return true;
+		}
+		return false;
+	};
+	void clear()
+	{
+		memset(Title, 0, sizeof(char)*128);
+	};
+	char Title[128];
+};
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakFileMgr
+	{
+	public:
+		CakFileMgr(void);
+		~CakFileMgr(void);
+
+		//타이틀 설정(OpenFile()함수와 MakeFile()함수를 호출하면 타이틀셋팅은 Null이 된다)
+		void SetTitle(char* title);
+
+		//쓰기 관련
+		//타이틀을 정한다.
+		bool SetAttribute(char* Attribute, int value);
+		bool SetAttribute(char* Attribute, double value);
+		bool SetAttribute(char* Attribute, char* value);
+		bool SetAttribute(char* Attribute, float value);
+		//쓰기 버퍼에 저장된 데이터를 파일로 저장
+		bool MakeFile(char* filepath);
+		
+
+		//읽기 관련
+		//파일 열기(쓰기준비중이였다면 쓰기 버퍼는 초기화 된다)
+		bool OpenFile(char* filepath);
+		bool GetAttribute(char* Attribute, int& value);
+		bool GetAttribute(char* Attribute, double& value);
+		bool GetAttribute(char* Attribute, char* value);
+		bool GetAttribute(char* Attribute, float& value);
+		
+	private:
+		//빠른 찾기를 위해서 저장된 데이터 정렬
+		void DataSort();
+		char m_Title[128];
+		std::vector<_Attribute> m_data;
+
+		char* m_buffer;
+		int m_fastIndex;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akFileMgrAdv.h b/ReviewHistory/include/akSTL/backup/akFileMgrAdv.h
new file mode 100644
index 0000000..8bdf758
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akFileMgrAdv.h
@@ -0,0 +1,74 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include <vector>
+
+//파일 구조
+//float version;
+//size_t structTotalSize;//구조체 총 크기
+//size_t structNum;//구조체 갯수
+//char rev[128]; //예약된 임시공간
+//size_t nSize[] 각각의 구조체 크기
+//void* pData //실제 데이터 저장 공간
+
+namespace akSTL
+{
+	struct akSTL_DLLSPEC _akFileMgrHeader
+	{
+		float version;
+
+		size_t structTotalSize;//구조체 총 크기
+		size_t structNum;//
+		char rev[128];
+	};
+
+	class akSTL_DLLSPEC CakFileMgrAdv
+	{
+	public:
+		CakFileMgrAdv(void);
+		~CakFileMgrAdv(void);
+
+	public:
+		//파일 쓰기
+		bool writeFile(char* pFileName, float fVer=1.0);
+
+		//파일 읽기
+		//0은 실패 1은 정상
+		//10001 읽어올 구조체 크기가 파일보다 큼(struct size > file size)
+		//10002 읽어올 구조체 크기가 파일보다 큼(struct size > file size)
+		//10003 읽어올 구조체와 파일크기가 같음. 하지만 구조체 구성이 다름(struct size == file size)
+		int readFile(char* filepath, bool bErrorCheck = false);
+
+		//데이터/크기 수정(기존의 파일정보를 읽어서 새 데이터로 수정)
+		bool editFile(char* filepath, int nIndex, void* pData, size_t nSize);
+
+
+		//데이터/크기 초기화
+		void clear();
+		//데이터/크기 추가
+		void addDataSize(void* pData, size_t nSize);
+		//데이터/크기 수정
+		void setDataSize(int nIndex, void* pData, size_t nSize);
+
+		_akFileMgrHeader getFileHeaderInfo(char* pFileName);
+		
+	
+		
+		
+	private:
+		struct _datasize
+		{
+			_datasize(void* pData1, size_t nSize1)
+			{
+				pData = pData1;
+				nSize = nSize1;
+			}
+			void* pData;
+			size_t  nSize;
+		};
+		std::vector<_datasize> m_vecData;
+
+		
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akFileMgrB.h b/ReviewHistory/include/akSTL/backup/akFileMgrB.h
new file mode 100644
index 0000000..a2f377c
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akFileMgrB.h
@@ -0,0 +1,40 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include <vector>
+
+
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakFileMgrB
+	{
+	public:
+		CakFileMgrB(void);
+		~CakFileMgrB(void);
+
+		//쓰기 관련
+		void SetDataSize(unsigned int HeadSize, unsigned int BodySize);
+		bool SetHead(void* head);
+		bool AddBody(void* body);
+		void ClearWriteBuffer(); //쓰기할려고 저장한 데이터 모두 삭제
+
+		//읽기 관련
+		void MakeFile(char* filepath);
+		bool OpenFile(char* filepath);
+		void* GetBodyData();
+		void* GetHeadData();
+		int MoveNext();
+		void ClearReadBuffer();
+
+	private:
+		int m_headSize, m_bodySize;
+		void* m_WriteHead;
+		std::vector<void*> m_vecWriteBody;
+		int m_readindex;
+		void* m_ReadHead;
+		std::vector<void*> m_vecReadBody;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akFileUtil.h b/ReviewHistory/include/akSTL/backup/akFileUtil.h
new file mode 100644
index 0000000..7838e51
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akFileUtil.h
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "akLinker.h"
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC khFileUtil
+	{
+	public:
+		khFileUtil(void);
+		~khFileUtil(void);
+
+		static bool CopytoFile(char* srcfilename, char* cpyfilename);
+		//상대경로가 '/', '\\'로 시작하면 안됨(나중에 수정하도록 하자..API문제인듯)
+		static bool CopytoFolder(char* srcfilename, char* cpyFolder); 
+
+		//상대경로가 '/', '\\'로 시작하면 안됨, 와일드 카드 사용가능
+		static bool RemoveFile(char* filename);
+	};
+}
diff --git a/ReviewHistory/include/akSTL/backup/akInterpolation.h b/ReviewHistory/include/akSTL/backup/akInterpolation.h
new file mode 100644
index 0000000..57f4d4f
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akInterpolation.h
@@ -0,0 +1,48 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include <vector>
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakInterpolation
+	{
+	public:
+		struct _Data
+		{
+			_Data()
+			{
+				x = y = 0;
+			}
+			double x;
+			double y;
+		};
+
+	public:
+		CakInterpolation();
+		~CakInterpolation();
+
+		//폴리노미얼 데이터 생성(rate:데이터 간격)
+		void CaculationPolinomial(double min, double max, double rate);
+		//큐빅스플라인 데이터 생성(rate:점과 점사이의 데이터 갯수)
+		void CaculationCubicSpline(double rate);
+		//Linear(rate:점과 점사이의 데이터 갯수)
+		void CaculationLinear(int step);
+
+		void AddPoint(double x, double y);
+		inline void ClearPoint(){m_vecInterPoint.clear();};
+		
+		inline _Data GetData(int index);
+		inline int GetDataNum(){return (int)m_vecInterPoint.size();};
+
+		
+		
+		
+	protected:
+		std::vector<_Data> m_vecOrgPoint;
+		std::vector<_Data> m_vecInterPoint;
+	private:
+		void solveTridiag(double* khb, double* diag, double* khp, double* b, int n)	;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akMath.h b/ReviewHistory/include/akSTL/backup/akMath.h
new file mode 100644
index 0000000..7d84e61
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akMath.h
@@ -0,0 +1,30 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include "akSTL.h"
+
+namespace akSTL
+{
+
+	class akSTL_DLLSPEC CakMath
+	{
+	public:
+		CakMath(void);
+		~CakMath(void);
+
+	public:
+		//세점이 이루는 각도를 산출
+		double GetAngle3Point(double cX, double cY, double x1, double y1, double x2, double y2 );
+		//평면 폴리곤위에 점이 존재 하는지 검사
+		bool GetIsPointOnPolygon(khVector2d point, khVector2d* polygon, int length); 
+		//한 선위에 점이 있는지 검사
+		bool GetLineOnPoint(khVector3d point, khVector3d line1, khVector3d line2);
+		//2d 회전 좌표(중심점에서 
+		khVector2d GetRotatePosition(khVector2d center, khVector2d point1, double angle);
+
+		//두선의 교차점 구하기(교차점이 있으면 true 반환)
+		bool GetIntersectPoint(khVector2d a1, khVector2d a2, khVector2d b1, khVector2d b2, khVector2d* IP);
+	};
+
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akMatrix.h b/ReviewHistory/include/akSTL/backup/akMatrix.h
new file mode 100644
index 0000000..e8b8272
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akMatrix.h
@@ -0,0 +1,36 @@
+#pragma once
+
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakMatrix4x4
+	{
+	public:
+		CakMatrix4x4(void);
+		~CakMatrix4x4(void);
+
+		inline bool MatrixClear();	//매트릭스 리셋
+		inline bool SetMatrix(double *matrix);	//매트릭스 세팅
+		inline bool SetRotateH(double H);	//회전 매트리릭스 곱셈
+		inline bool SetRotateP(double P);	//회전 매트리릭스 곱셈
+		inline bool SetRotateR(double R);	//회전 매트리릭스 곱셈
+		inline bool SetTransform(double x, double y, double z);	//이동 매트리릭스 곱셈
+		inline bool MakeResult(double* x, double* y, double* z);//매트릭스 적용 좌표값 산출
+		inline bool MakeResult(float* x, float* y, float* z);//매트릭스 적용 좌표값 산출
+		inline void MatrixPrint();	//현재 매트릭스 출력
+		inline CakMatrix4x4& operator=(const CakMatrix4x4& matrix);
+		inline CakMatrix4x4& operator*(const CakMatrix4x4& matrix);
+	protected:
+		inline bool Multiplication(double* matrix);	//현재 매트릭스에 입력값 곱셈
+
+	public:
+		double m_Matrix[16];
+
+		
+	private:
+		bool m_bSet;	//초기화가 되어있는지 확인
+
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akMemory.h b/ReviewHistory/include/akSTL/backup/akMemory.h
new file mode 100644
index 0000000..22f4979
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akMemory.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
+#define SAFE_DELETE_ARRAY(p)  { if(p) { delete [] (p);     (p)=NULL; } }
+
+	class akSTL_DLLSPEC CakMemory
+	{
+	public:
+		CakMemory(void);
+		~CakMemory(void);
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akRandom.h b/ReviewHistory/include/akSTL/backup/akRandom.h
new file mode 100644
index 0000000..15d8119
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akRandom.h
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+//#define GetRandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
+
+	class akSTL_DLLSPEC CakRandom
+	{
+	public:
+		CakRandom(void);
+		~CakRandom(void);
+
+		//정규분포, Normal, 가우시안... (다 같은말)
+		double Gaussian(float stddev, float mean); //stddev:평균, mean:표준편차
+
+		static int GetRandom(int min, int max);
+		
+	private:
+		static int ms_randomseed;
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akString.h b/ReviewHistory/include/akSTL/backup/akString.h
new file mode 100644
index 0000000..652089d
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akString.h
@@ -0,0 +1,143 @@
+#pragma once
+
+
+#include "akLinker.h"
+
+#include <iostream>
+#include <tchar.h>
+
+
+extern akSTL_DLLSPEC wchar_t* m_pWstrTemp;
+akSTL_DLLSPEC wchar_t* charToWchar(char* pstrSrc);
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakString
+	{
+	public:
+		CakString(void);
+		~CakString(void);
+
+	public:
+		//wstring ToWString(const char * in_val);
+		//string ToString(const wstring &in_val);
+
+		
+
+		//찾고자하는 문자의 위치를 반환해주는 함수(-1이 반환되면 찾지 못한것임, 찾았으면 1이상의 값을 반환)
+		static int StringFind(const char* str, const char* keyward);
+		
+
+		static inline std::wstring ToWString(const char * in_val)
+		{
+			std::wstring temp;
+			while (*in_val != '\0')
+				temp += *in_val++;
+			return temp;
+		}
+
+		static inline std::string ToString(const std::wstring &in_val)
+		{
+			std::string temp;
+			std::wstring::const_iterator b = in_val.begin();
+			const std::wstring::const_iterator e = in_val.end();
+			while (b != e)
+			{
+				temp += static_cast<char>(*b);
+				++b;
+			}
+			return temp;
+		}
+
+		static bool IsNumber(char* strSource);
+		static void StringReplace(char* strSource, char cSourceChar, char cDestChar);
+		static void StringReplace(char* strSource, char* strSourceString, char* strDestString);
+		static bool GetFullPathName(char* strDest, int nDestSize, const char* strSourceFront, const char* strSourceEnd);
+		static void GetPath(char* strDest, int nDestSize, const char* strSource);
+		static void GetName(char* strDest, int nDestSize, const char* strSource);
+		static bool GetExt(char* strDest, int nDestSize, const char* strSource);
+		static char* GetExt(const char* strSource);
+		static int Find(const char* strSource, char cChar);
+		static int Find(const char* strSource, char* strFindString);
+		static int ReverseFind(const char* strSource, char cChar);
+		static void MakeLower(char* strSource);
+		static void MakeUpper(char* strSource);
+		static bool Left(const char* strSource, char* strDest, int nDestLength, int nLeftCount);
+		static bool Mid(const char* strSource, char* strDest, int nDestLength, int nFirstIndex, int nCount = -1);
+		static bool Right(const char* strSource, char* strDest, int nDestLength, int nRightCount);
+		
+
+
+	private:
+		
+	};
+}
+
+
+//
+//void CksgFontMaker::DrawStringOverray(
+//									  GLfloat x, 
+//									  GLfloat y,  
+//									  int windowWidth,
+//									  int windowHeight,
+//									  char* s
+//									  ,...)
+//{
+//	// Draws the given text string at the given location.
+//
+//	char text[256]={};
+//	va_list ap;
+//	va_start(ap, s);
+//	vsprintf(text, s, ap);
+//	va_end(ap);
+//
+//	GLsizei len = GLsizei(strlen(text));
+//	if (text && len > 0) 
+//	{
+//		glPushMatrix();
+//		{
+//			glPushAttrib( GL_LIGHTING_BIT );
+//			glDisable(GL_LIGHTING);
+//			glMatrixMode(GL_PROJECTION);
+//			glPushMatrix();
+//			{
+//				glLoadIdentity();
+//				gluOrtho2D(0, windowWidth, 0,windowHeight);
+//
+//				glMatrixMode(GL_MODELVIEW);
+//
+//				glPushMatrix();
+//				{
+//					glLoadIdentity();
+//
+//
+//
+//
+//					glRasterPos2i(x, windowHeight+m_logfont.lfHeight-y);
+//
+//					glPushAttrib(GL_LIST_BIT);
+//					{
+//						glListBase(m_fontListBase);
+//						glCallLists(len, GL_UNSIGNED_BYTE, (const GLvoid*)text);
+//					} glPopAttrib();
+//
+//
+//				}glPopMatrix();
+//
+//				glMatrixMode(GL_PROJECTION);
+//
+//			}glPopMatrix();
+//
+//			glMatrixMode(GL_MODELVIEW);
+//
+//
+//			glPopAttrib();
+//			//glEnable(GL_DEPTH_TEST);
+//
+//		}glPopMatrix();
+//
+//
+//
+//	}
+//}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akSyncObject.h b/ReviewHistory/include/akSTL/backup/akSyncObject.h
new file mode 100644
index 0000000..db91012
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akSyncObject.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakSyncObject
+	{
+	public:
+		CakSyncObject(void);
+		virtual ~CakSyncObject(void);
+
+	public:
+		//읽기 지정을 하였을때... 이미 어디서 쓰고 있다면.. 기다렸다가 다음을 수행한다.
+		//bWait = false 일경우.. 어딘가에서 쓰고 있다면 false를 반환하고 끝내버린다.
+		bool SetRead(bool bWait = true);  
+		//쓰기 지정을 하였을때... 이미 어디서 읽고 있다면.. 기다렸다가 다음을 수행한다.
+		bool SetWrite(bool bWait = true);
+		int SetReadRelease(); //현재 남아있는 읽기 카운트 반환
+		void SetWriteRelease();
+
+		int GetReadCount(){return m_nReadCount;}; //읽기 호출한 횟수 반환
+		bool GetWriteState(){return m_bWrite;}; //0이 될때까지 그리는 루틴은 무한 루프가 돈다.
+		
+
+	protected:
+		
+	private:
+		bool m_bWrite; 
+		int m_nReadCount;
+		
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akText.h b/ReviewHistory/include/akSTL/backup/akText.h
new file mode 100644
index 0000000..f22348f
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akText.h
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "akLinker.h"
+
+class akSTL_DLLSPEC CakText
+{
+public:
+	CakText(void);
+	virtual ~CakText(void);
+	
+	//////////////////////////////////////////////////////////////////////////
+	//시간 반환 함수
+	char* getTime();
+	char* getTime(char* pSeparator);
+	char* getTime(char* pSeparator1, char* pSeparator2, char* pSeparator3);
+
+	//////////////////////////////////////////////////////////////////////////
+	//날자 반환 함수
+	char* getDate();
+	char* getDate(char* pSeparator);
+	char* getDate(char* pSeparator1, char* pSeparator2, char* pSeparator3);
+	
+	//////////////////////////////////////////////////////////////////////////
+	//시스템 정보 반환
+	char* getModuleFileName(); //실행되는 파일 이름 반환
+	char* getCurrentDirectory(); //현재 작업 폴더 반환
+
+
+	//////////////////////////////////////////////////////////////////////////
+	//버퍼 관리 함수
+	//내부적으로 많은 양의 크기를 요구하는 문자열의 경우
+	//자동으로 크기를 재 할당하므로 별도의 버퍼크기를 조절 하지 않아도 괜찮아요~
+public:
+	char* getBuffer(int index){return m_pBuffer[index];};
+	int getBufferSize(){return m_nBuffersize;};
+	int getBufferNum(){return m_nBufferNum;};
+	void setBufferSize(int nNum, int nSize);
+	
+private:
+	char** m_pBuffer; //m_nBufferNum*m_nBuffersize
+	int m_nBufferNum; //기본 버퍼갯수8개
+	int m_nBuffersize; //기본크기 64
+	int m_nBufferCurIndex;
+};
+
+
diff --git a/ReviewHistory/include/akSTL/backup/akTextExt.h b/ReviewHistory/include/akSTL/backup/akTextExt.h
new file mode 100644
index 0000000..b834058
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akTextExt.h
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "akText.h"
+
+//응용1
+#define AKTEXT CakTextExt::getInstance()
+class akSTL_DLLSPEC CakTextExt : public CakText
+{
+public:
+	CakTextExt(void){};
+	virtual ~CakTextExt(void){};
+
+	static CakText* getInstance(){return &m_akText;};
+private:
+	static CakText m_akText;
+};
diff --git a/ReviewHistory/include/akSTL/backup/akTimeManager.h b/ReviewHistory/include/akSTL/backup/akTimeManager.h
new file mode 100644
index 0000000..376df37
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akTimeManager.h
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "akLinker.h"
+#include <Windows.h>
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakTimeManager
+	{
+	public:
+		enum PlayMode
+		{
+			Play,
+			Stop,
+			Pause,
+			Playing,
+			PlayEnd,
+			SettingTime
+		};
+	public:
+		CakTimeManager(void);
+		virtual ~CakTimeManager(void);
+
+		//시작 중지(구버전) //배속 적용 안받음
+		inline void SetBegin();
+		inline void SetEnd();
+		inline double GetRunTimeSec(); //시작시간 저장하고 종료시간까지의 타임(초단위)
+		inline double GetRunTimeMsec(); //시작시간 저장하고 종료시간까지의 타임(초단위)
+		inline double GetFrameRate();
+
+		//플레이바 기능(신버전)
+		void SetInit();//초기 설정으로 되돌림
+		virtual inline void SetPlay();
+		virtual inline void SetStop();
+		virtual inline void SetTime(int msec);
+		virtual inline void SetPause();
+		
+		
+		virtual inline double GetTime(int type=0); //0=Sec, 1=MSec
+		virtual inline void GetTime(int* h, int* m, int* s, int* ms);
+		virtual inline PlayMode GetPlayMode();
+		virtual inline void SetSpeedRate(double speedrate); //배속 설정(0보다 큰 실수 입력가능)
+		virtual inline double GetSpeedRate(); //배속 설정값 읽기
+
+	protected:
+		LARGE_INTEGER m_Frequency;
+		LARGE_INTEGER m_BeginTime;
+		LARGE_INTEGER m_Endtime;
+
+		double m_PauseTime;
+		double m_LastTime;
+		PlayMode m_PlayState;
+		double m_SpeedRate; //배속
+
+		//콜백 데이터 관리
+	public:
+		typedef void (*MsgCallbackFunc) (int msg, void*);
+		void setMsgCallbackFunc(MsgCallbackFunc userFunc, void* data = NULL)
+		{
+			m_msgCallbackFunc = userFunc;
+			m_MsgCallbackFuncData = data;
+		};
+	protected:
+		void* m_MsgCallbackFuncData;
+		MsgCallbackFunc m_msgCallbackFunc;
+		int m_nSyncObject;
+	};
+
+	class akSTL_DLLSPEC CakTimeManagerAdv : public CakTimeManager
+	{
+	public:
+		CakTimeManagerAdv(void);
+		virtual ~CakTimeManagerAdv(void);
+
+	public:
+		virtual inline void SetPlay();
+		virtual inline void SetTime(int msec);
+		virtual inline void SetStop();
+	protected:
+		void setEnd();//플레이 시간이 최대 시간을 넘었을 경우 호출
+	public:
+		double m_timeMax;
+
+	public:
+		static void threadPlayer(void* arg);
+		int m_flagThreadPlayer;
+
+	private:
+		bool m_bPlaying;
+		
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akTraceExt.h b/ReviewHistory/include/akSTL/backup/akTraceExt.h
new file mode 100644
index 0000000..c06ba33
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akTraceExt.h
@@ -0,0 +1,47 @@
+#pragma once
+
+#define _AKTRACE
+
+#if defined _AKTRACE
+#define AKTRACEEXT(fmt,...) CakTraceExt::setTraceWithDateTime(fmt,##__VA_ARGS__) 
+#else
+#define AKTRACEEXT(fmt,...)
+#endif
+
+#if defined _AKTRACE
+#define AKTRACE(fmt,...) CakTraceExt::getInstance()->setTrace(fmt,##__VA_ARGS__) 
+#else
+#define AKTRACE(fmt,...)
+#endif
+
+
+#include "akTrace.h"
+#include "akTextExt.h"
+#include <Windows.h>
+class akSTL_DLLSPEC CakTraceExt
+{
+protected:
+	CakTraceExt(void);
+	virtual ~CakTraceExt(void);
+
+public:
+	//////////////////////////////////////////////////////////////////////////
+	static CakTrace *getInstance() {return &m_Instance;};	
+	
+	static void setTraceWithDateTime(char* format, ...)
+	{
+		char text[512]={};
+		va_list ap;
+		va_start(ap, format);
+		vsprintf(text, format, ap);
+		va_end(ap);
+
+		m_Instance.setTrace("%s%s : %s", AKTEXT->getDate(), AKTEXT->getTime(), text);
+	};
+
+	
+
+protected:
+	static CakTrace m_Instance;
+	
+};
diff --git a/ReviewHistory/include/akSTL/backup/akTrajectoryModel.h b/ReviewHistory/include/akSTL/backup/akTrajectoryModel.h
new file mode 100644
index 0000000..c9e74bd
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akTrajectoryModel.h
@@ -0,0 +1,66 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include "akSTL.h"
+#include "akDE.h"
+#include <vector>
+namespace akSTL
+{
+	struct _Waypoint
+	{
+		double x;
+		double y;
+		double z;
+		double speed;
+	};
+
+	class akSTL_DLLSPEC CakTrajcetoryModel
+	{
+	public:
+		CakTrajcetoryModel(void);
+		~CakTrajcetoryModel(void);
+
+	public:
+		virtual int calculate(float dTime); //더이상 계산할 경로점이 없을 경우 2를 반환
+		void setCurrentByWaypoint(int nWaypointIndex); //현재값을 경로점 기준으로 셋팅
+
+	
+
+	public:
+		//현재 값
+		khVector3d m_position; //위치
+		khVector3d m_rotate; //자세
+		double m_velocity; //속도
+		double m_acc;	//가속도
+		khVector3d m_rotateAcc; //각속도
+
+		//부여 받은 명령 설정
+		khVector3d m_TaskPosition;
+		double m_TaskVelocity;
+		double m_TaskAcc;
+
+		//객체 정보 관리
+		double mass; //무게
+		double maxSpeed; //최대 속도
+		double minSpeed; //최저 속도
+		double maxAcceleration; //가속도
+		double maxDeceleration; //감속도
+
+		khVector3d m_rotateVelRate;
+
+		//경로점 관리
+	public:
+		int m_nWaypointType; //0 마지막 경로점이면 끝낸다, 1경로점 순회, 2경로점 왕복
+		int m_nWaypointSet; //현재 설정된 경로점
+		std::vector<_Waypoint> m_vecWaypoint;
+
+
+	protected:
+		void getAngle3d(double x1, double y1, double z1, double x2, double y2, double z2, double* heading, double* pitch);
+		double getHeading(double x , double y);
+	protected:
+		CakDE m_movementmodel;
+	};
+
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/backup/akWGS84.h b/ReviewHistory/include/akSTL/backup/akWGS84.h
new file mode 100644
index 0000000..7f8cb20
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akWGS84.h
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "akSTLLinker.h"
+
+class AKSTL_DLLSPEC CakWGS84
+{
+public:
+	CakWGS84(void);
+	~CakWGS84(void);
+
+	//- 중부원점: N38, E127
+	static void getPosition(double lat1 , double lon1 , double x , double y , double &lat2 , double &lon2);
+	static void getRange(double lat1 , double lon1 , double lat2 , double lon2 , double &x , double &y);
+
+	static void _TM2Bessel(double tm_x, double tm_y, double lonOrg, double latOrg, double *lon, double *lat);
+	static void _Bessel2TM(double lon, double lat, double lonOrg, double latOrg, double *tm_x, double *tm_y);
+	static void Bessel2TM (double alt, double lon, double lat, double lonOrg, double latOrg, double *tm_x, double *tm_y);
+
+	//태현추가
+	static double getBearing(double lon, double lat, double lonOrg, double latOrg);
+	static void getRangePosition(double bearing, double range, double lonOrg, double latOrg, double *lon, double *lat);
+};
diff --git a/ReviewHistory/include/akSTL/backup/akWaypoint.h b/ReviewHistory/include/akSTL/backup/akWaypoint.h
new file mode 100644
index 0000000..465d882
--- /dev/null
+++ b/ReviewHistory/include/akSTL/backup/akWaypoint.h
@@ -0,0 +1,36 @@
+#pragma once
+
+
+#include "akSTLLinker.h"
+#include "akSTLVector.h"
+
+namespace akSTL
+{
+	class AKSTL_DLLSPEC CakWaypoint
+	{
+	public:
+		CakWaypoint(void);
+		~CakWaypoint(void);
+
+	public:
+		void clear();
+		void pointAdd(khVector3d point);
+		void pointInsert(unsigned int index, khVector3d point);//범위를 넘어가면 젤 뒤에 추가
+		void pointDelete(unsigned int index);
+		
+		int size(){return m_nPointsNum;};
+		
+		khVector3d& operator [](unsigned int nindex){return m_pPoints[nindex];};
+		CakWaypoint& operator= (CakWaypoint& waypoint);
+
+	private:
+		void secureMemory();
+
+	private:
+		int m_nMakePoints; //확보 메모리 사이즈
+		int m_nPointsNum; //현재 입력된 Point 갯수
+		khVector3d* m_pPoints; //데이터 변수
+
+
+	};
+}
\ No newline at end of file
diff --git a/ReviewHistory/include/akSTL/inl/akPointT.inl b/ReviewHistory/include/akSTL/inl/akPointT.inl
new file mode 100644
index 0000000..9d0f5f7
--- /dev/null
+++ b/ReviewHistory/include/akSTL/inl/akPointT.inl
@@ -0,0 +1,70 @@
+
+//#include "../akPointT.h"
+#define AKINLINE inline
+
+
+
+template<typename T> AKINLINE
+CakPointT<T> CakPointT<T>::operator-( CakPointT<T> point ) const throw()
+{
+	return CakPointT(x - point.x, y - point.y);
+}
+
+template<typename T> AKINLINE
+CakPointT<T> CakPointT<T>::operator+( CakPointT<T> point ) const throw()
+{
+	return CakPointT(x + point.x, y + point.y);
+}
+
+template<typename T> AKINLINE
+CakPointT<T> CakPointT<T>::operator-() const throw()
+{
+	return CakPointT(-x,-y);
+}
+
+template<typename T> AKINLINE
+void CakPointT<T>::operator-=( CakPointT<T> point ) throw()
+{
+	x -= point.x;
+	y -= point.y;
+}
+
+template<typename T> AKINLINE
+void CakPointT<T>::operator+=( CakPointT<T> point ) throw()
+{
+	x += point.x;
+	y += point.y;
+}
+
+template<typename T> AKINLINE
+bool CakPointT<T>::operator!=( CakPointT<T> point ) const throw()
+{
+	return (x != point.x || y != point.y);
+}
+
+template<typename T> AKINLINE
+bool CakPointT<T>::operator==( CakPointT<T> point ) const throw()
+{
+	return (x == point.x && y == point.y);
+}
+
+template<typename T> AKINLINE
+void CakPointT<T>::SetPoint( T X, T Y ) throw()
+{
+	x = X; 
+	y = Y;
+}
+
+template<typename T> AKINLINE
+void CakPointT<T>::Offset( CakPointT<T> point ) throw()
+{
+	x += point.x;
+	y += point.y;
+}
+
+template<typename T> AKINLINE
+void CakPointT<T>::Offset( T xOffset, T yOffset ) throw()
+{
+	x += xOffset;
+	y += yOffset;
+}
diff --git a/ReviewHistory/include/akSTL/inl/akRectT.inl b/ReviewHistory/include/akSTL/inl/akRectT.inl
new file mode 100644
index 0000000..a0f0a7f
--- /dev/null
+++ b/ReviewHistory/include/akSTL/inl/akRectT.inl
@@ -0,0 +1,368 @@
+
+#define AKINLINE inline
+
+template<typename T> AKINLINE
+CakRectT<T>::CakRectT( void )
+{
+
+}
+
+// template<typename T> AKINLINE
+// CakRectT<T>::CakRectT( T l, T t, T r, T b )
+// {
+// 	left = l;
+// 	top = t;
+// 	right = r;
+// 	bottom = b;	
+// }
+
+// template<typename T> AKINLINE
+// CakRectT<T>::CakRectT( CakRectT<T> rect )
+// {
+// 	left = rect.left;
+// 	top = rect.top;
+// 	right = rect.right;
+// 	bottom = rect.bottom;	
+// }
+
+template<typename T> AKINLINE
+CakRectT<T>::~CakRectT( void )
+{
+
+}
+
+template<typename T> AKINLINE
+T CakRectT<T>::Width() const throw()
+{
+	return right - left; 
+}
+
+template<typename T> AKINLINE
+T CakRectT<T>::Height() const throw()
+{
+	return bottom - top;
+}
+
+
+
+
+
+template<typename T> AKINLINE
+bool CakRectT<T>::PtInRect( T x, T y ) const throw()
+{
+	if( x <= left || x >= right ||
+		y <= top  || y >= bottom )
+	{
+		return false;
+	}
+
+	return true;
+}
+
+template<typename T> AKINLINE
+bool CakRectT<T>::IsRectEmpty() const throw()
+{
+	if(left-right == 0) return true;
+	if(top-bottom == 0) return true;
+
+	return false;
+}
+
+template<typename T> AKINLINE
+bool CakRectT<T>::IsRectNull() const throw()
+{
+	return (left == 0 && right == 0 && top == 0 && bottom == 0);
+}
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::SwapLeftRight() throw()
+{
+	T temp = left; 
+	left = right; 
+	right = temp; 
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::SwapTopBottom() throw()
+{
+	T temp = top; 
+	top = bottom; 
+	bottom = temp; 
+}
+
+template<typename T> AKINLINE
+bool CakRectT<T>::EqualRect(const CakRectT<T>* lpRect ) const throw()
+{
+	if((left	== lpRect->left	&&
+		top		== lpRect->top	&&
+		right	== lpRect->right	&&
+		bottom	== lpRect->bottom) == true)
+		return true;
+
+	return false;
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::SetRect( T x1, T y1, T x2, T y2 ) throw()
+{
+	left = x1;
+	top = y1;
+	right = x2;
+	bottom = y2;	
+}
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::SetRectEmpty() throw()
+{
+	left = 0;
+	top = 0;
+	right = 0;
+	bottom = 0;	
+}
+
+
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::CopyRect(const CakRectT<T>* lpSrcRect ) throw()
+{
+	left	= lpSrcRect->left	;
+	top		= lpSrcRect->top	;
+	right	= lpSrcRect->right	;
+	bottom	= lpSrcRect->bottom	;	
+}
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::InflateRect( T x, T y ) throw()
+{
+	left -= x;
+	top -= y;
+	right += x;
+	bottom += y;
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::InflateRect( T l, T t, T r, T b ) throw()
+{
+	left -= l;
+	top -= t;
+	right += r;
+	bottom += b;
+}
+
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::DeflateRect( T x, T y ) throw()
+{
+	left += x;
+	top += y;
+	right -= x;
+	bottom -= y;
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::DeflateRect( T l, T t, T r, T b ) throw()
+{
+	left += l;
+	top += t;
+	right -= r;
+	bottom -= b;
+}
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::OffsetRect( T x, T y ) throw()
+{
+	left += x;
+	top += y;
+	right += x;
+	bottom += y;
+}
+
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::NormalizeRect() throw()
+{
+	T nTemp;
+	if (left > right)
+	{
+		nTemp = left;
+		left = right;
+		right = nTemp;
+	}
+	if (top > bottom)
+	{
+		nTemp = top;
+		top = bottom;
+		bottom = nTemp;
+	}
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::MoveToY( T y ) throw()
+{
+	bottom = Height() + y; top = y;
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::MoveToX( T x ) throw()
+{
+	right = Width() + x; left = x;
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::MoveToXY( T x, T y ) throw()
+{
+	MoveToX(x); MoveToY(y);
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::DeflateRect( CakRectT<T>* lpRect ) throw()
+{
+	left += lpRect->left;	top += lpRect->top;
+	right -= lpRect->right;	bottom -= lpRect->bottom;
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::InflateRect( CakRectT<T>* lpRect ) throw()
+{
+	left -= lpRect->left;		top -= lpRect->top;
+	right += lpRect->right;		bottom += lpRect->bottom;
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::operator=( const CakRectT<T>& srcRect ) throw()
+{
+	CopyRect(&srcRect);
+}
+template<typename T> AKINLINE
+bool CakRectT<T>::operator==( const CakRectT<T>& rect ) const throw()
+{
+	return EqualRect(&rect);
+}
+
+template<typename T> AKINLINE
+bool CakRectT<T>::operator!=( const CakRectT<T>& rect ) const throw()
+{
+	return !EqualRect(&rect);
+}
+
+template<typename T> AKINLINE
+void CakRectT<T>::operator+=( CakRectT<T>* lpRect ) throw()
+{
+	InflateRect(lpRect);
+}
+
+
+template<typename T> AKINLINE
+void CakRectT<T>::operator-=( CakRectT<T>* lpRect ) throw()
+{
+	DeflateRect(lpRect);
+}
+template<typename T> AKINLINE
+CakRectT<T> CakRectT<T>::operator+( CakRectT<T>* lpRect ) const throw()
+{
+	CakRectT<T> rect(left,top,right,bottom); 
+	rect.InflateRect(lpRect); return rect;
+}
+
+template<typename T> AKINLINE
+CakRectT<T> CakRectT<T>::operator-( CakRectT<T>* lpRect ) const throw()
+{
+	CakRectT<T> rect(left,top,right,bottom); 
+	rect.DeflateRect(lpRect); 
+	return rect;
+}
+
+
+
+
+template<typename T> AKINLINE
+CakRectT<T> CakRectT<T>::MulDiv( T nMultiplier, T nDivisor ) const throw()
+{
+	//나중에 다시 보자!!
+	return CakRectT<T>(
+		T((float)left*(float)nMultiplier/(float)nDivisor),
+		T((float)top*(float)nMultiplier/(float)nDivisor),
+		T((float)right*(float)nMultiplier/(float)nDivisor),
+		T((float)bottom*(float)nMultiplier/(float)nDivisor)
+		);
+	//::MulDiv(left, nMultiplier, nDivisor),
+	//::MulDiv(top, nMultiplier, nDivisor),
+	//::MulDiv(right, nMultiplier, nDivisor),
+	//::MulDiv(bottom, nMultiplier, nDivisor));
+}
+
+// template<typename T> AKINLINE
+// CakRectT<T>& CakRectT<T>::operator=(const CakRectT<T>& rect)
+// {
+// 	left	= rect.left		;
+// 	top		= rect.top		;
+// 	right	= rect.right	;
+// 	bottom	= rect.bottom	;
+// 
+// 	return *this;
+// }
+
+
+template<typename T>
+bool CakRectT<T>::getCheckHeightIn( double p1 )
+{
+	if(top < bottom)
+	{
+		if( (top <= p1 && bottom >= p1 ) )
+		{
+			return true;
+		}
+	}
+	else
+	{
+		if( (bottom <= p1 && top >= p1 ) )
+		{
+			return true;
+		}
+	}
+
+	return false;
+}
+
+template<typename T>
+bool CakRectT<T>::getCheckWidthIn( double p1 )
+{
+	if(left < right)
+	{
+		if( (left <= p1 && right >= p1 ) )
+		{
+			return true;
+		}
+	}
+	else
+	{
+		if( (right <= p1 && left >= p1 ) )
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
+template<typename T>
+bool CakRectT<T>::getCheckAreaIn( double x, double y )
+{
+	CakRectT<T> rectTemp = *this;
+	rectTemp.NormalizeRect();
+
+
+	if( (rectTemp.left <= x && rectTemp.right >= x )
+		&& (rectTemp.top <= y && rectTemp.bottom >= y ))
+	{
+		return true;
+	}
+
+	return false;
+}
diff --git a/ReviewHistory/include/akSTL/inl/akVectorT.inl b/ReviewHistory/include/akSTL/inl/akVectorT.inl
new file mode 100644
index 0000000..da0f966
--- /dev/null
+++ b/ReviewHistory/include/akSTL/inl/akVectorT.inl
@@ -0,0 +1,109 @@
+
+//#include "../akvectorT.h"
+#define AKINLINE inline
+
+
+
+template<typename T> AKINLINE
+CakVectorT<T> CakVectorT<T>::operator-( CakVectorT<T> vector ) const throw()
+{
+	return CakVectorT(x - vector.x, y - vector.y, z - vector.z);
+}
+
+template<typename T> AKINLINE
+CakVectorT<T> CakVectorT<T>::operator+( CakVectorT<T> vector ) const throw()
+{
+	return CakVectorT(x + vector.x, y + vector.y, z + vector.z);
+}
+
+template<typename T> AKINLINE
+CakVectorT<T> CakVectorT<T>::operator-() const throw()
+{
+	return CakVectorT(-x,-y,-z);
+}
+
+template<typename T> AKINLINE
+void CakVectorT<T>::operator-=( CakVectorT<T> vector ) throw()
+{
+	x -= vector.x;
+	y -= vector.y;
+	z -= vector.z;
+}
+
+template<typename T> AKINLINE
+void CakVectorT<T>::operator+=( CakVectorT<T> vector ) throw()
+{
+	x += vector.x;
+	y += vector.y;
+	z += vector.z;
+}
+
+template<typename T> AKINLINE
+bool CakVectorT<T>::operator!=( CakVectorT<T> vector ) const throw()
+{
+	return (x != vector.x || y != vector.y || z != vector.z);
+}
+
+template<typename T> AKINLINE
+bool CakVectorT<T>::operator==( CakVectorT<T> vector ) const throw()
+{
+	return (x == vector.x && y == vector.y && z == vector.z);
+}
+
+template<typename T> AKINLINE
+void CakVectorT<T>::set( T X, T Y, T Z ) throw()
+{
+	x = X; 
+	y = Y;
+	z = Z;
+}
+
+template<typename T> AKINLINE
+void CakVectorT<T>::Offset( CakVectorT<T> vector ) throw()
+{
+	x += vector.x;
+	y += vector.y;
+	z += vector.z;
+}
+
+template<typename T> AKINLINE
+void CakVectorT<T>::Offset( T xOffset, T yOffset, T zOffset) throw()
+{
+	x += xOffset;
+	y += yOffset;
+	z += zOffset;
+}
+
+template<typename T> AKINLINE
+CakVectorT<T> CakVectorT<T>::operator*(T& a) const throw()
+{
+	return CakVectorT(x * a, y * a, z * a);
+}
+
+
+template<typename T> AKINLINE
+CakVectorT<T> CakVectorT<T>::operator*( CakVectorT<T> &vec ) const throw()
+{
+	CakVectorT<T> vc;
+	vc.x = y*vec.z - z*vec.y;
+	vc.y = z*vec.x - x*vec.z;
+	vc.z = x*vec.y - y*vec.x;
+	return vc;
+};
+
+template<typename T> AKINLINE
+void CakVectorT<T>::Normalize()
+{
+	double length;
+
+	//벡터의 길이를 계산한다.
+	length = sqrt((x*x) + (y*y) +(z*z));
+	// 길이가 0에 가까운 벡터에게 절절한 값을 항당하여 프로그램이 폭주하지 않도록 한다.
+	if(length == 0.0f) length = 1.0f;
+
+	// 각 성분을 벡터의 길이로 나누면 단위 벡터가 된다.
+	x = x / length;
+	y = y / length;
+	z = z / length;
+
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akColorStruct.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akColorStruct.h"
new file mode 100644
index 0000000..dc1b73e
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akColorStruct.h"
@@ -0,0 +1,128 @@
+#pragma once
+
+#include "khLinker.h"
+
+#define _USE_MATH_DEFINES
+#include <math.h>
+
+namespace KimHeart
+{
+	struct KIMHEART_DLLSPEC khVector3d
+	{
+		double pos[3];
+
+		khVector3d();
+		khVector3d(double x,double y, double z);
+		inline void set(double x,double y, double z);
+		inline double x(){return pos[0];};
+		inline double y(){return pos[1];};
+		inline double z(){return pos[2];};
+
+		double& operator()(int index){return pos[index];};
+
+		inline khVector3d operator+(const khVector3d& vec3d);
+		inline khVector3d operator-(const khVector3d& vec3d);
+		inline khVector3d& operator=(const khVector3d& vec3d);
+		inline khVector3d& operator+=(const khVector3d& vec3d);
+		inline khVector3d& operator-=(const khVector3d& vec3d);
+		khVector3d operator*(float& a)
+		{
+			khVector3d returnval;
+
+			returnval.pos[0] = pos[0] * a;
+			returnval.pos[1] = pos[1] * a;
+			returnval.pos[2] = pos[2] * a;
+
+			return returnval;
+		};
+
+		khVector3d operator *(khVector3d &vec)
+		{
+			khVector3d vc;
+			vc.pos[0] = pos[1]*vec.pos[2] - pos[2]*vec.pos[1];
+			vc.pos[1] = pos[2]*vec.pos[0] - pos[0]*vec.pos[2];
+			vc.pos[2] = pos[0]*vec.pos[1] - pos[1]*vec.pos[0];
+			return vc;
+		}
+
+		float Dot(khVector3d vec)
+		{
+			return (float)(vec.pos[0] * pos[0] + vec.pos[1] * pos[1] + vec.pos[2] * pos[2]);
+		};
+		float Mag()
+		{
+			return (float)sqrt(pos[0]*pos[0]+pos[1]*pos[1]);
+		};
+		void Normalize()
+		{
+			float length;
+
+			//벡터의 길이를 계산한다.
+			length = (float)sqrt((pos[0]*pos[0]) + (pos[1]*pos[1]) +(pos[2]*pos[2]));
+			// 길이가 0에 가까운 벡터에게 절절한 값을 항당하여 프로그램이 폭주하지 않도록 한다.
+			if(length == 0.0f) length = 1.0f;
+
+			// 각 성분을 벡터의 길이로 나누면 단위 벡터가 된다.
+			pos[0] = pos[0] / length;
+			pos[1] = pos[1] / length;
+			pos[2] = pos[2] / length;
+
+		};
+	};
+
+	struct KIMHEART_DLLSPEC khVector2d
+	{
+		double pos[2];
+
+		khVector2d();
+		khVector2d(double x,double y);
+		inline void set(double x,double y);
+		inline double x(){return pos[0];};
+		inline double y(){return pos[1];};
+
+		double& operator()(int index){return pos[index];};
+
+		inline khVector2d operator+(const khVector2d& vec3d);
+		inline khVector2d operator-(const khVector2d& vec3d);
+		inline khVector2d& operator=(const khVector2d& vec3d);
+		inline khVector2d& operator+=(const khVector2d& vec3d);
+		inline khVector2d& operator-=(const khVector2d& vec3d);
+		
+	};
+
+	struct KIMHEART_DLLSPEC khColor4f
+	{
+		float color[4];
+
+		khColor4f();
+		khColor4f(float R, float G, float B, float A=0.0f);
+		void set(float R, float G, float B, float A=0.0f);
+		inline float R(){return color[0];};
+		inline float G(){return color[1];};
+		inline float B(){return color[2];};
+		inline float A(){return color[3];};
+		inline khColor4f& operator=(const khColor4f& ksgcolor);
+	};
+
+	struct KIMHEART_DLLSPEC khRect
+	{
+		double pos[4];
+
+		khRect();
+		khRect(double left, double top, double right, double bottom);
+		void set(double left, double top, double right, double bottom);
+		inline khRect& operator=(const khRect& rect);
+		inline double Left(){return pos[0];};
+		inline double Top(){return pos[1];};
+		inline double Right(){return pos[2];};
+		inline double Bottom(){return pos[3];};
+		inline double Width(){return pos[2]-pos[0];};
+		inline double Height(){return pos[3]-pos[1];};
+		inline void SetAlign(); //작은값이 왼쪽, 위, 큰값이 오른쪽 아래로 가게 한다.
+		inline bool CheckAreaIn(double x, double y); //사각형 영역에 x,y포인트가 있는지 검사
+		inline bool CheckWidthIn(double p1); //x포인트 가운데 점이 있는지 검사
+		inline bool CheckHeightIn(double p1); //y포인트 가운데 점이 있는지 검사
+
+
+	};
+};
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akCoordinate.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akCoordinate.h"
new file mode 100644
index 0000000..a2e1caa
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akCoordinate.h"
@@ -0,0 +1,28 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+
+	class akSTL_DLLSPEC CakCoordinate
+	{
+	public:
+		CakCoordinate(void);
+		~CakCoordinate(void);
+
+		//Degree를 도분초로 변환
+		static double GetDMStoDgree(int  d, int  m, double  s);
+		//도분초를 Degree로 변환
+		static void GetDgreetoDMS(double degree, int* d, int* m, double* s);
+		//Degree값을 180방위 + 방향(W,E)로 변환
+		static void GetMakeDMS180(int degree, int* rDeg, char* rDir);
+		//Degree값을 90방위 + 방향(S,N)로 변환
+		static void GetMakeDMS90(int degree, int* rDeg, char* rDir);
+		//Degree값을 //-180~+180로 변환
+		static double GetMakeDegree180(double degree);
+		//Degree값을 //-90~+90로 변환
+		static double GetMakeDegree90(double degree);
+	};
+
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgr.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgr.h"
new file mode 100644
index 0000000..158d0b9
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgr.h"
@@ -0,0 +1,80 @@
+#pragma once
+
+
+
+#include "akLinker.h"
+#include <vector>
+
+struct akSTL_DLLSPEC _Attribute
+{
+	_Attribute()
+	{
+		memset(Title		, 0, sizeof(char)*128);
+		memset(Attribute	, 0, sizeof(char)*128);
+		memset(Value		, 0, sizeof(char)*128);
+	}
+	char Title[128];
+	char Attribute[128];
+	char Value[128];
+};
+
+struct akSTL_DLLSPEC _Title
+{
+	_Title(char* title)
+	{
+		strcpy(Title, title);
+	};
+	bool compare(char* title)
+	{
+		if(strcmp(title, Title) == 0 && strlen(title) == strlen(Title))
+		{
+			return true;
+		}
+		return false;
+	};
+	void clear()
+	{
+		memset(Title, 0, sizeof(char)*128);
+	};
+	char Title[128];
+};
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakFileMgr
+	{
+	public:
+		CakFileMgr(void);
+		~CakFileMgr(void);
+
+		//타이틀 설정(OpenFile()함수와 MakeFile()함수를 호출하면 타이틀셋팅은 Null이 된다)
+		void SetTitle(char* title);
+
+		//쓰기 관련
+		//타이틀을 정한다.
+		bool SetAttribute(char* Attribute, int value);
+		bool SetAttribute(char* Attribute, double value);
+		bool SetAttribute(char* Attribute, char* value);
+		bool SetAttribute(char* Attribute, float value);
+		//쓰기 버퍼에 저장된 데이터를 파일로 저장
+		bool MakeFile(char* filepath);
+		
+
+		//읽기 관련
+		//파일 열기(쓰기준비중이였다면 쓰기 버퍼는 초기화 된다)
+		bool OpenFile(char* filepath);
+		bool GetAttribute(char* Attribute, int& value);
+		bool GetAttribute(char* Attribute, double& value);
+		bool GetAttribute(char* Attribute, char* value);
+		bool GetAttribute(char* Attribute, float& value);
+		
+	private:
+		//빠른 찾기를 위해서 저장된 데이터 정렬
+		void DataSort();
+		char m_Title[128];
+		std::vector<_Attribute> m_data;
+
+		char* m_buffer;
+		int m_fastIndex;
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgrAdv.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgrAdv.h"
new file mode 100644
index 0000000..8bdf758
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgrAdv.h"
@@ -0,0 +1,74 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include <vector>
+
+//파일 구조
+//float version;
+//size_t structTotalSize;//구조체 총 크기
+//size_t structNum;//구조체 갯수
+//char rev[128]; //예약된 임시공간
+//size_t nSize[] 각각의 구조체 크기
+//void* pData //실제 데이터 저장 공간
+
+namespace akSTL
+{
+	struct akSTL_DLLSPEC _akFileMgrHeader
+	{
+		float version;
+
+		size_t structTotalSize;//구조체 총 크기
+		size_t structNum;//
+		char rev[128];
+	};
+
+	class akSTL_DLLSPEC CakFileMgrAdv
+	{
+	public:
+		CakFileMgrAdv(void);
+		~CakFileMgrAdv(void);
+
+	public:
+		//파일 쓰기
+		bool writeFile(char* pFileName, float fVer=1.0);
+
+		//파일 읽기
+		//0은 실패 1은 정상
+		//10001 읽어올 구조체 크기가 파일보다 큼(struct size > file size)
+		//10002 읽어올 구조체 크기가 파일보다 큼(struct size > file size)
+		//10003 읽어올 구조체와 파일크기가 같음. 하지만 구조체 구성이 다름(struct size == file size)
+		int readFile(char* filepath, bool bErrorCheck = false);
+
+		//데이터/크기 수정(기존의 파일정보를 읽어서 새 데이터로 수정)
+		bool editFile(char* filepath, int nIndex, void* pData, size_t nSize);
+
+
+		//데이터/크기 초기화
+		void clear();
+		//데이터/크기 추가
+		void addDataSize(void* pData, size_t nSize);
+		//데이터/크기 수정
+		void setDataSize(int nIndex, void* pData, size_t nSize);
+
+		_akFileMgrHeader getFileHeaderInfo(char* pFileName);
+		
+	
+		
+		
+	private:
+		struct _datasize
+		{
+			_datasize(void* pData1, size_t nSize1)
+			{
+				pData = pData1;
+				nSize = nSize1;
+			}
+			void* pData;
+			size_t  nSize;
+		};
+		std::vector<_datasize> m_vecData;
+
+		
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgrB.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgrB.h"
new file mode 100644
index 0000000..a2f377c
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileMgrB.h"
@@ -0,0 +1,40 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include <vector>
+
+
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakFileMgrB
+	{
+	public:
+		CakFileMgrB(void);
+		~CakFileMgrB(void);
+
+		//쓰기 관련
+		void SetDataSize(unsigned int HeadSize, unsigned int BodySize);
+		bool SetHead(void* head);
+		bool AddBody(void* body);
+		void ClearWriteBuffer(); //쓰기할려고 저장한 데이터 모두 삭제
+
+		//읽기 관련
+		void MakeFile(char* filepath);
+		bool OpenFile(char* filepath);
+		void* GetBodyData();
+		void* GetHeadData();
+		int MoveNext();
+		void ClearReadBuffer();
+
+	private:
+		int m_headSize, m_bodySize;
+		void* m_WriteHead;
+		std::vector<void*> m_vecWriteBody;
+		int m_readindex;
+		void* m_ReadHead;
+		std::vector<void*> m_vecReadBody;
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileUtil.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileUtil.h"
new file mode 100644
index 0000000..7838e51
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akFileUtil.h"
@@ -0,0 +1,21 @@
+#pragma once
+
+#include "akLinker.h"
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC khFileUtil
+	{
+	public:
+		khFileUtil(void);
+		~khFileUtil(void);
+
+		static bool CopytoFile(char* srcfilename, char* cpyfilename);
+		//상대경로가 '/', '\\'로 시작하면 안됨(나중에 수정하도록 하자..API문제인듯)
+		static bool CopytoFolder(char* srcfilename, char* cpyFolder); 
+
+		//상대경로가 '/', '\\'로 시작하면 안됨, 와일드 카드 사용가능
+		static bool RemoveFile(char* filename);
+	};
+}
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akInterpolation.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akInterpolation.h"
new file mode 100644
index 0000000..57f4d4f
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akInterpolation.h"
@@ -0,0 +1,48 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include <vector>
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakInterpolation
+	{
+	public:
+		struct _Data
+		{
+			_Data()
+			{
+				x = y = 0;
+			}
+			double x;
+			double y;
+		};
+
+	public:
+		CakInterpolation();
+		~CakInterpolation();
+
+		//폴리노미얼 데이터 생성(rate:데이터 간격)
+		void CaculationPolinomial(double min, double max, double rate);
+		//큐빅스플라인 데이터 생성(rate:점과 점사이의 데이터 갯수)
+		void CaculationCubicSpline(double rate);
+		//Linear(rate:점과 점사이의 데이터 갯수)
+		void CaculationLinear(int step);
+
+		void AddPoint(double x, double y);
+		inline void ClearPoint(){m_vecInterPoint.clear();};
+		
+		inline _Data GetData(int index);
+		inline int GetDataNum(){return (int)m_vecInterPoint.size();};
+
+		
+		
+		
+	protected:
+		std::vector<_Data> m_vecOrgPoint;
+		std::vector<_Data> m_vecInterPoint;
+	private:
+		void solveTridiag(double* khb, double* diag, double* khp, double* b, int n)	;
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMath.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMath.h"
new file mode 100644
index 0000000..7d84e61
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMath.h"
@@ -0,0 +1,30 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include "akSTL.h"
+
+namespace akSTL
+{
+
+	class akSTL_DLLSPEC CakMath
+	{
+	public:
+		CakMath(void);
+		~CakMath(void);
+
+	public:
+		//세점이 이루는 각도를 산출
+		double GetAngle3Point(double cX, double cY, double x1, double y1, double x2, double y2 );
+		//평면 폴리곤위에 점이 존재 하는지 검사
+		bool GetIsPointOnPolygon(khVector2d point, khVector2d* polygon, int length); 
+		//한 선위에 점이 있는지 검사
+		bool GetLineOnPoint(khVector3d point, khVector3d line1, khVector3d line2);
+		//2d 회전 좌표(중심점에서 
+		khVector2d GetRotatePosition(khVector2d center, khVector2d point1, double angle);
+
+		//두선의 교차점 구하기(교차점이 있으면 true 반환)
+		bool GetIntersectPoint(khVector2d a1, khVector2d a2, khVector2d b1, khVector2d b2, khVector2d* IP);
+	};
+
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMatrix.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMatrix.h"
new file mode 100644
index 0000000..e8b8272
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMatrix.h"
@@ -0,0 +1,36 @@
+#pragma once
+
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakMatrix4x4
+	{
+	public:
+		CakMatrix4x4(void);
+		~CakMatrix4x4(void);
+
+		inline bool MatrixClear();	//매트릭스 리셋
+		inline bool SetMatrix(double *matrix);	//매트릭스 세팅
+		inline bool SetRotateH(double H);	//회전 매트리릭스 곱셈
+		inline bool SetRotateP(double P);	//회전 매트리릭스 곱셈
+		inline bool SetRotateR(double R);	//회전 매트리릭스 곱셈
+		inline bool SetTransform(double x, double y, double z);	//이동 매트리릭스 곱셈
+		inline bool MakeResult(double* x, double* y, double* z);//매트릭스 적용 좌표값 산출
+		inline bool MakeResult(float* x, float* y, float* z);//매트릭스 적용 좌표값 산출
+		inline void MatrixPrint();	//현재 매트릭스 출력
+		inline CakMatrix4x4& operator=(const CakMatrix4x4& matrix);
+		inline CakMatrix4x4& operator*(const CakMatrix4x4& matrix);
+	protected:
+		inline bool Multiplication(double* matrix);	//현재 매트릭스에 입력값 곱셈
+
+	public:
+		double m_Matrix[16];
+
+		
+	private:
+		bool m_bSet;	//초기화가 되어있는지 확인
+
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMemory.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMemory.h"
new file mode 100644
index 0000000..22f4979
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akMemory.h"
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+#define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } }
+#define SAFE_DELETE_ARRAY(p)  { if(p) { delete [] (p);     (p)=NULL; } }
+
+	class akSTL_DLLSPEC CakMemory
+	{
+	public:
+		CakMemory(void);
+		~CakMemory(void);
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akRandom.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akRandom.h"
new file mode 100644
index 0000000..15d8119
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akRandom.h"
@@ -0,0 +1,23 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+//#define GetRandom( min, max ) ((rand() % (int)(((max)+1) - (min))) + (min))
+
+	class akSTL_DLLSPEC CakRandom
+	{
+	public:
+		CakRandom(void);
+		~CakRandom(void);
+
+		//정규분포, Normal, 가우시안... (다 같은말)
+		double Gaussian(float stddev, float mean); //stddev:평균, mean:표준편차
+
+		static int GetRandom(int min, int max);
+		
+	private:
+		static int ms_randomseed;
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akString.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akString.h"
new file mode 100644
index 0000000..652089d
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akString.h"
@@ -0,0 +1,143 @@
+#pragma once
+
+
+#include "akLinker.h"
+
+#include <iostream>
+#include <tchar.h>
+
+
+extern akSTL_DLLSPEC wchar_t* m_pWstrTemp;
+akSTL_DLLSPEC wchar_t* charToWchar(char* pstrSrc);
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakString
+	{
+	public:
+		CakString(void);
+		~CakString(void);
+
+	public:
+		//wstring ToWString(const char * in_val);
+		//string ToString(const wstring &in_val);
+
+		
+
+		//찾고자하는 문자의 위치를 반환해주는 함수(-1이 반환되면 찾지 못한것임, 찾았으면 1이상의 값을 반환)
+		static int StringFind(const char* str, const char* keyward);
+		
+
+		static inline std::wstring ToWString(const char * in_val)
+		{
+			std::wstring temp;
+			while (*in_val != '\0')
+				temp += *in_val++;
+			return temp;
+		}
+
+		static inline std::string ToString(const std::wstring &in_val)
+		{
+			std::string temp;
+			std::wstring::const_iterator b = in_val.begin();
+			const std::wstring::const_iterator e = in_val.end();
+			while (b != e)
+			{
+				temp += static_cast<char>(*b);
+				++b;
+			}
+			return temp;
+		}
+
+		static bool IsNumber(char* strSource);
+		static void StringReplace(char* strSource, char cSourceChar, char cDestChar);
+		static void StringReplace(char* strSource, char* strSourceString, char* strDestString);
+		static bool GetFullPathName(char* strDest, int nDestSize, const char* strSourceFront, const char* strSourceEnd);
+		static void GetPath(char* strDest, int nDestSize, const char* strSource);
+		static void GetName(char* strDest, int nDestSize, const char* strSource);
+		static bool GetExt(char* strDest, int nDestSize, const char* strSource);
+		static char* GetExt(const char* strSource);
+		static int Find(const char* strSource, char cChar);
+		static int Find(const char* strSource, char* strFindString);
+		static int ReverseFind(const char* strSource, char cChar);
+		static void MakeLower(char* strSource);
+		static void MakeUpper(char* strSource);
+		static bool Left(const char* strSource, char* strDest, int nDestLength, int nLeftCount);
+		static bool Mid(const char* strSource, char* strDest, int nDestLength, int nFirstIndex, int nCount = -1);
+		static bool Right(const char* strSource, char* strDest, int nDestLength, int nRightCount);
+		
+
+
+	private:
+		
+	};
+}
+
+
+//
+//void CksgFontMaker::DrawStringOverray(
+//									  GLfloat x, 
+//									  GLfloat y,  
+//									  int windowWidth,
+//									  int windowHeight,
+//									  char* s
+//									  ,...)
+//{
+//	// Draws the given text string at the given location.
+//
+//	char text[256]={};
+//	va_list ap;
+//	va_start(ap, s);
+//	vsprintf(text, s, ap);
+//	va_end(ap);
+//
+//	GLsizei len = GLsizei(strlen(text));
+//	if (text && len > 0) 
+//	{
+//		glPushMatrix();
+//		{
+//			glPushAttrib( GL_LIGHTING_BIT );
+//			glDisable(GL_LIGHTING);
+//			glMatrixMode(GL_PROJECTION);
+//			glPushMatrix();
+//			{
+//				glLoadIdentity();
+//				gluOrtho2D(0, windowWidth, 0,windowHeight);
+//
+//				glMatrixMode(GL_MODELVIEW);
+//
+//				glPushMatrix();
+//				{
+//					glLoadIdentity();
+//
+//
+//
+//
+//					glRasterPos2i(x, windowHeight+m_logfont.lfHeight-y);
+//
+//					glPushAttrib(GL_LIST_BIT);
+//					{
+//						glListBase(m_fontListBase);
+//						glCallLists(len, GL_UNSIGNED_BYTE, (const GLvoid*)text);
+//					} glPopAttrib();
+//
+//
+//				}glPopMatrix();
+//
+//				glMatrixMode(GL_PROJECTION);
+//
+//			}glPopMatrix();
+//
+//			glMatrixMode(GL_MODELVIEW);
+//
+//
+//			glPopAttrib();
+//			//glEnable(GL_DEPTH_TEST);
+//
+//		}glPopMatrix();
+//
+//
+//
+//	}
+//}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akSyncObject.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akSyncObject.h"
new file mode 100644
index 0000000..db91012
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akSyncObject.h"
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "akLinker.h"
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakSyncObject
+	{
+	public:
+		CakSyncObject(void);
+		virtual ~CakSyncObject(void);
+
+	public:
+		//읽기 지정을 하였을때... 이미 어디서 쓰고 있다면.. 기다렸다가 다음을 수행한다.
+		//bWait = false 일경우.. 어딘가에서 쓰고 있다면 false를 반환하고 끝내버린다.
+		bool SetRead(bool bWait = true);  
+		//쓰기 지정을 하였을때... 이미 어디서 읽고 있다면.. 기다렸다가 다음을 수행한다.
+		bool SetWrite(bool bWait = true);
+		int SetReadRelease(); //현재 남아있는 읽기 카운트 반환
+		void SetWriteRelease();
+
+		int GetReadCount(){return m_nReadCount;}; //읽기 호출한 횟수 반환
+		bool GetWriteState(){return m_bWrite;}; //0이 될때까지 그리는 루틴은 무한 루프가 돈다.
+		
+
+	protected:
+		
+	private:
+		bool m_bWrite; 
+		int m_nReadCount;
+		
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akText.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akText.h"
new file mode 100644
index 0000000..f22348f
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akText.h"
@@ -0,0 +1,46 @@
+#pragma once
+
+#include "akLinker.h"
+
+class akSTL_DLLSPEC CakText
+{
+public:
+	CakText(void);
+	virtual ~CakText(void);
+	
+	//////////////////////////////////////////////////////////////////////////
+	//시간 반환 함수
+	char* getTime();
+	char* getTime(char* pSeparator);
+	char* getTime(char* pSeparator1, char* pSeparator2, char* pSeparator3);
+
+	//////////////////////////////////////////////////////////////////////////
+	//날자 반환 함수
+	char* getDate();
+	char* getDate(char* pSeparator);
+	char* getDate(char* pSeparator1, char* pSeparator2, char* pSeparator3);
+	
+	//////////////////////////////////////////////////////////////////////////
+	//시스템 정보 반환
+	char* getModuleFileName(); //실행되는 파일 이름 반환
+	char* getCurrentDirectory(); //현재 작업 폴더 반환
+
+
+	//////////////////////////////////////////////////////////////////////////
+	//버퍼 관리 함수
+	//내부적으로 많은 양의 크기를 요구하는 문자열의 경우
+	//자동으로 크기를 재 할당하므로 별도의 버퍼크기를 조절 하지 않아도 괜찮아요~
+public:
+	char* getBuffer(int index){return m_pBuffer[index];};
+	int getBufferSize(){return m_nBuffersize;};
+	int getBufferNum(){return m_nBufferNum;};
+	void setBufferSize(int nNum, int nSize);
+	
+private:
+	char** m_pBuffer; //m_nBufferNum*m_nBuffersize
+	int m_nBufferNum; //기본 버퍼갯수8개
+	int m_nBuffersize; //기본크기 64
+	int m_nBufferCurIndex;
+};
+
+
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTextExt.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTextExt.h"
new file mode 100644
index 0000000..b834058
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTextExt.h"
@@ -0,0 +1,16 @@
+#pragma once
+
+#include "akText.h"
+
+//응용1
+#define AKTEXT CakTextExt::getInstance()
+class akSTL_DLLSPEC CakTextExt : public CakText
+{
+public:
+	CakTextExt(void){};
+	virtual ~CakTextExt(void){};
+
+	static CakText* getInstance(){return &m_akText;};
+private:
+	static CakText m_akText;
+};
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTimeManager.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTimeManager.h"
new file mode 100644
index 0000000..376df37
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTimeManager.h"
@@ -0,0 +1,93 @@
+#pragma once
+
+#include "akLinker.h"
+#include <Windows.h>
+
+
+namespace akSTL
+{
+	class akSTL_DLLSPEC CakTimeManager
+	{
+	public:
+		enum PlayMode
+		{
+			Play,
+			Stop,
+			Pause,
+			Playing,
+			PlayEnd,
+			SettingTime
+		};
+	public:
+		CakTimeManager(void);
+		virtual ~CakTimeManager(void);
+
+		//시작 중지(구버전) //배속 적용 안받음
+		inline void SetBegin();
+		inline void SetEnd();
+		inline double GetRunTimeSec(); //시작시간 저장하고 종료시간까지의 타임(초단위)
+		inline double GetRunTimeMsec(); //시작시간 저장하고 종료시간까지의 타임(초단위)
+		inline double GetFrameRate();
+
+		//플레이바 기능(신버전)
+		void SetInit();//초기 설정으로 되돌림
+		virtual inline void SetPlay();
+		virtual inline void SetStop();
+		virtual inline void SetTime(int msec);
+		virtual inline void SetPause();
+		
+		
+		virtual inline double GetTime(int type=0); //0=Sec, 1=MSec
+		virtual inline void GetTime(int* h, int* m, int* s, int* ms);
+		virtual inline PlayMode GetPlayMode();
+		virtual inline void SetSpeedRate(double speedrate); //배속 설정(0보다 큰 실수 입력가능)
+		virtual inline double GetSpeedRate(); //배속 설정값 읽기
+
+	protected:
+		LARGE_INTEGER m_Frequency;
+		LARGE_INTEGER m_BeginTime;
+		LARGE_INTEGER m_Endtime;
+
+		double m_PauseTime;
+		double m_LastTime;
+		PlayMode m_PlayState;
+		double m_SpeedRate; //배속
+
+		//콜백 데이터 관리
+	public:
+		typedef void (*MsgCallbackFunc) (int msg, void*);
+		void setMsgCallbackFunc(MsgCallbackFunc userFunc, void* data = NULL)
+		{
+			m_msgCallbackFunc = userFunc;
+			m_MsgCallbackFuncData = data;
+		};
+	protected:
+		void* m_MsgCallbackFuncData;
+		MsgCallbackFunc m_msgCallbackFunc;
+		int m_nSyncObject;
+	};
+
+	class akSTL_DLLSPEC CakTimeManagerAdv : public CakTimeManager
+	{
+	public:
+		CakTimeManagerAdv(void);
+		virtual ~CakTimeManagerAdv(void);
+
+	public:
+		virtual inline void SetPlay();
+		virtual inline void SetTime(int msec);
+		virtual inline void SetStop();
+	protected:
+		void setEnd();//플레이 시간이 최대 시간을 넘었을 경우 호출
+	public:
+		double m_timeMax;
+
+	public:
+		static void threadPlayer(void* arg);
+		int m_flagThreadPlayer;
+
+	private:
+		bool m_bPlaying;
+		
+	};
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTraceExt.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTraceExt.h"
new file mode 100644
index 0000000..c06ba33
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTraceExt.h"
@@ -0,0 +1,47 @@
+#pragma once
+
+#define _AKTRACE
+
+#if defined _AKTRACE
+#define AKTRACEEXT(fmt,...) CakTraceExt::setTraceWithDateTime(fmt,##__VA_ARGS__) 
+#else
+#define AKTRACEEXT(fmt,...)
+#endif
+
+#if defined _AKTRACE
+#define AKTRACE(fmt,...) CakTraceExt::getInstance()->setTrace(fmt,##__VA_ARGS__) 
+#else
+#define AKTRACE(fmt,...)
+#endif
+
+
+#include "akTrace.h"
+#include "akTextExt.h"
+#include <Windows.h>
+class akSTL_DLLSPEC CakTraceExt
+{
+protected:
+	CakTraceExt(void);
+	virtual ~CakTraceExt(void);
+
+public:
+	//////////////////////////////////////////////////////////////////////////
+	static CakTrace *getInstance() {return &m_Instance;};	
+	
+	static void setTraceWithDateTime(char* format, ...)
+	{
+		char text[512]={};
+		va_list ap;
+		va_start(ap, format);
+		vsprintf(text, format, ap);
+		va_end(ap);
+
+		m_Instance.setTrace("%s%s : %s", AKTEXT->getDate(), AKTEXT->getTime(), text);
+	};
+
+	
+
+protected:
+	static CakTrace m_Instance;
+	
+};
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTrajectoryModel.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTrajectoryModel.h"
new file mode 100644
index 0000000..c9e74bd
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akTrajectoryModel.h"
@@ -0,0 +1,66 @@
+#pragma once
+
+
+#include "akLinker.h"
+#include "akSTL.h"
+#include "akDE.h"
+#include <vector>
+namespace akSTL
+{
+	struct _Waypoint
+	{
+		double x;
+		double y;
+		double z;
+		double speed;
+	};
+
+	class akSTL_DLLSPEC CakTrajcetoryModel
+	{
+	public:
+		CakTrajcetoryModel(void);
+		~CakTrajcetoryModel(void);
+
+	public:
+		virtual int calculate(float dTime); //더이상 계산할 경로점이 없을 경우 2를 반환
+		void setCurrentByWaypoint(int nWaypointIndex); //현재값을 경로점 기준으로 셋팅
+
+	
+
+	public:
+		//현재 값
+		khVector3d m_position; //위치
+		khVector3d m_rotate; //자세
+		double m_velocity; //속도
+		double m_acc;	//가속도
+		khVector3d m_rotateAcc; //각속도
+
+		//부여 받은 명령 설정
+		khVector3d m_TaskPosition;
+		double m_TaskVelocity;
+		double m_TaskAcc;
+
+		//객체 정보 관리
+		double mass; //무게
+		double maxSpeed; //최대 속도
+		double minSpeed; //최저 속도
+		double maxAcceleration; //가속도
+		double maxDeceleration; //감속도
+
+		khVector3d m_rotateVelRate;
+
+		//경로점 관리
+	public:
+		int m_nWaypointType; //0 마지막 경로점이면 끝낸다, 1경로점 순회, 2경로점 왕복
+		int m_nWaypointSet; //현재 설정된 경로점
+		std::vector<_Waypoint> m_vecWaypoint;
+
+
+	protected:
+		void getAngle3d(double x1, double y1, double z1, double x2, double y2, double z2, double* heading, double* pitch);
+		double getHeading(double x , double y);
+	protected:
+		CakDE m_movementmodel;
+	};
+
+}
\ No newline at end of file
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akWGS84.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akWGS84.h"
new file mode 100644
index 0000000..7f8cb20
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akWGS84.h"
@@ -0,0 +1,22 @@
+#pragma once
+
+#include "akSTLLinker.h"
+
+class AKSTL_DLLSPEC CakWGS84
+{
+public:
+	CakWGS84(void);
+	~CakWGS84(void);
+
+	//- 중부원점: N38, E127
+	static void getPosition(double lat1 , double lon1 , double x , double y , double &lat2 , double &lon2);
+	static void getRange(double lat1 , double lon1 , double lat2 , double lon2 , double &x , double &y);
+
+	static void _TM2Bessel(double tm_x, double tm_y, double lonOrg, double latOrg, double *lon, double *lat);
+	static void _Bessel2TM(double lon, double lat, double lonOrg, double latOrg, double *tm_x, double *tm_y);
+	static void Bessel2TM (double alt, double lon, double lat, double lonOrg, double latOrg, double *tm_x, double *tm_y);
+
+	//태현추가
+	static double getBearing(double lon, double lat, double lonOrg, double latOrg);
+	static void getRangePosition(double bearing, double range, double lonOrg, double latOrg, double *lon, double *lat);
+};
diff --git "a/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akWaypoint.h" "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akWaypoint.h"
new file mode 100644
index 0000000..465d882
--- /dev/null
+++ "b/ReviewHistory/include/akSTL/\354\203\210 \355\217\264\353\215\224/akWaypoint.h"
@@ -0,0 +1,36 @@
+#pragma once
+
+
+#include "akSTLLinker.h"
+#include "akSTLVector.h"
+
+namespace akSTL
+{
+	class AKSTL_DLLSPEC CakWaypoint
+	{
+	public:
+		CakWaypoint(void);
+		~CakWaypoint(void);
+
+	public:
+		void clear();
+		void pointAdd(khVector3d point);
+		void pointInsert(unsigned int index, khVector3d point);//범위를 넘어가면 젤 뒤에 추가
+		void pointDelete(unsigned int index);
+		
+		int size(){return m_nPointsNum;};
+		
+		khVector3d& operator [](unsigned int nindex){return m_pPoints[nindex];};
+		CakWaypoint& operator= (CakWaypoint& waypoint);
+
+	private:
+		void secureMemory();
+
+	private:
+		int m_nMakePoints; //확보 메모리 사이즈
+		int m_nPointsNum; //현재 입력된 Point 갯수
+		khVector3d* m_pPoints; //데이터 변수
+
+
+	};
+}
\ No newline at end of file
diff --git a/ReviewSystem/ReviewSystem/DitGlassRawClient.cpp b/ReviewSystem/ReviewSystem/DitGlassRawClient.cpp
index 7a3c5e6..98841f2 100644
--- a/ReviewSystem/ReviewSystem/DitGlassRawClient.cpp
+++ b/ReviewSystem/ReviewSystem/DitGlassRawClient.cpp
@@ -124,6 +124,11 @@
 	return SetCommand(grcReadBin);
 }
 
+BOOL CDitGlassRawClient::WriteReviewRawBinFile()
+{
+	return SetCommand(grcReviewWriteBIn);
+}
+
 BOOL CDitGlassRawClient::SetCommand( emGlassRawCommand nCmd )
 {
 	if(m_pGlassRawInfo == NULL) return FALSE;
@@ -132,14 +137,14 @@
 
 	int nCmdId = (m_pGlassRawInfo->m_nCommandIdxWrite+1) % COMMAND_MAXCOUNT;
 
-	if(m_pGlassRawInfo->m_nCommandIdxRead == nCmdId)//둘이 같다는것은 서큘러 버퍼가 한바퀴 돌았다는것!! [김태현 2018/11/12]
+	if(m_pGlassRawInfo->m_nCommandIdxRead == nCmdId)//占쏙옙占쏙옙 占쏙옙占쌕는곤옙占쏙옙 占쏙옙큘占쏙옙 占쏙옙占쌜곤옙 占싼뱄옙占쏙옙 占쏙옙占쌀다는곤옙!! [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	{
-		m_pGlassRawInfo->m_nCommandIdxRead++;//가장 오래된 명령 하나를 삭제한다. [김태현 2018/11/12]
+		m_pGlassRawInfo->m_nCommandIdxRead++;//占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占� 占싹놂옙占쏙옙 占쏙옙占쏙옙占싼댐옙. [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	}
 
 	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nCommand = (short)nCmd;
 	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].strParam;
-	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nResult = -1; //-1수행전, 0실패, 1성공 [김태현 2018/11/13]
+	m_pGlassRawInfo->m_nCommandBuffer[nCmdId].nResult = -1; //-1占쏙옙占쏙옙占쏙옙, 0占쏙옙占쏙옙, 1占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/13]
 
 
 	m_nLastCommandIdx = m_pGlassRawInfo->m_nCommandIdxWrite = nCmdId;
@@ -210,7 +215,7 @@
 void CDitGlassRawClient::RemoveReviewDefects()
 {
 	int nDefectNum = m_pGlassData->m_nDefectNum;
-	int nRightDefectNum = 0;//기준점 오른쪽에 위치한 결함 갯수
+	int nRightDefectNum = 0;//占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占십울옙 占쏙옙치占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	int nDefectDeleteNum = 0;
 	for(int i=nDefectNum-1; i>=0; i--)
 	{
diff --git a/ReviewSystem/ReviewSystem/DitGlassRawClient.h b/ReviewSystem/ReviewSystem/DitGlassRawClient.h
index ab06511..a3ce795 100644
--- a/ReviewSystem/ReviewSystem/DitGlassRawClient.h
+++ b/ReviewSystem/ReviewSystem/DitGlassRawClient.h
@@ -25,7 +25,7 @@
 
 	BOOL SetReviewComtomize();
 
-	void RemoveReviewDefects();//AOI에서 생성한 디펙 정보를 제외하고, 리뷰에서 생성한 User 혹은 Reflow 결함을 제외한다.
+	void RemoveReviewDefects();//AOI占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싹곤옙, 占쏙옙占썰에占쏙옙 占쏙옙占쏙옙占쏙옙 User 혹占쏙옙 Reflow 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占싼댐옙.
 
 	_grmDitMemInfo*	GetGlassMeminfo(){return (_grmDitMemInfo*)m_pGlassRawInfo;};
 	_grmGlassData*	GetGlassData(){return m_pGlassData;};
@@ -34,15 +34,17 @@
 	_grmDefectData*	GetDefectData(int nIndex){return &m_pDefectData[nIndex];};
 	_grmDefectData*	GetStackData(int nIndex) { return &m_pStackData[nIndex];};
 
-	//결과 파일 강제 쓰기 명령 [김태현 2018/11/12]
+	//占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占� [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	BOOL WriteAOIRawFile();
 
-	//결과파일 강제 바이너리 형태로 쓰기 [김태현 2018/11/12]
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占싱너몌옙 占쏙옙占승뤄옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	BOOL WriteAOIRawBinFile(); 
 
-	//결과파일 강제 바이너리 읽기 
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占싱너몌옙 占싻깍옙 
 	BOOL ReadAOIRawBinFile();
 
+	BOOL WriteReviewRawBinFile();
+
 protected:
 	BOOL ConnectGlassRawInfo();
 	BOOL ConnectGlassRawData();
diff --git a/ReviewSystem/ReviewSystem/DitGlassRawStruct.h b/ReviewSystem/ReviewSystem/DitGlassRawStruct.h
index 600196e..e84fb29 100644
--- a/ReviewSystem/ReviewSystem/DitGlassRawStruct.h
+++ b/ReviewSystem/ReviewSystem/DitGlassRawStruct.h
@@ -47,7 +47,7 @@
 		memset(this, 0, sizeof(_grmGlassData));
 	}
 
-	//Glass 정보
+	//Glass 占쏙옙占쏙옙
 	char m_strFileName[64];
 	char m_strPath[256];
 
@@ -56,12 +56,12 @@
 
 	int m_nOriginDirection;				//{ GD_LeftTop = 0, GD_RightTop = 1, GD_LeftBottom = 10, GD_RightBottom = 11 };
 	int m_nConerCutDirection;
-	int	m_nScanCoordinateY;				//여기가 0이면 일반, 1이면 Scan방향이 y축(즉 scan방향이 단축, offline 설비 같은)
+	int	m_nScanCoordinateY;				//占쏙옙占썩가 0占싱몌옙 占싹뱄옙, 1占싱몌옙 Scan占쏙옙占쏙옙占쏙옙 y占쏙옙(占쏙옙 scan占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙, offline 占쏙옙占쏙옙 占쏙옙占쏙옙)
 
 	int m_nGlassSizeWidth;
 	int m_nGlassSizeHeight;
 
-	//설비정보
+	//占쏙옙占쏙옙占쏙옙占쏙옙
 	char m_strLine[32];
 	char m_strEquipType[32];			
 	char m_strEquipID[32];				
@@ -74,7 +74,7 @@
 	CTime	m_tmReviewLoading;
 	CTime	m_tmReviewEnd;
 
-	//기본 물류정보
+	//占썩본 占쏙옙占쏙옙占쏙옙占쏙옙
 	char m_strGlassID[32];				//Glass ID
 	char m_strPPID[32];					
 	char m_strEPPID[32];				
@@ -91,7 +91,7 @@
 	char m_strVCRGlassID[32];
 
 
-	//결함 갯수 관리 변수
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	int			m_nDefectNumSizeSmall;
 	int			m_nDefectNumSizeMid;
 	int			m_nDefectNumSizeLarge;
@@ -126,14 +126,14 @@
 	int			m_nDefectNumStackSP;
 
 
-	//카메라/스캔 정보 [김태현 2018/12/5]
+	//카占쌨띰옙/占쏙옙캔 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
 	short		m_nCameraNum;
 	short		m_nScanNum;
 	unsigned char m_nGrayLevelAvg[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];		
 	unsigned char m_nGrayLevelMin[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];
 	unsigned char m_nGrayLevelMax[RAWMESSENGER_MAXCAMNUM*RAWMESSENGER_MAXSCANNUM];
 
-	//얼라인 정보 um[김태현 2018/12/10]
+	//占쏙옙占쏙옙占� 占쏙옙占쏙옙 um[占쏙옙占쏙옙占쏙옙 2018/12/10]
 	double	m_nAlignCcdTheta;
 	double	m_nAlignCcdShitftX;
 	double	m_nAlignCcdShitftY;
@@ -143,8 +143,11 @@
 	double	m_nAlignBasicTheta;
 	double	m_nAlignBasicShitftX;
 	double	m_nAlignBasicShitftY;
+	char	m_strAlignFirst[64];
+	char	m_strAlignSecond[64];
+// 	char	m_strAlignPath[256];
 
-	//CSOT용 물류 정보 [김태현 2018/12/5]
+	//CSOT占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
 	char m_strCassetteSequenceNo[16];
 	char m_strOwnerCode[16];			//2. OWNER_CODE
 	char m_strOwnerType[16];			//3. OWNER_TYPE
@@ -159,7 +162,7 @@
 	char m_strGroupID[16];				//14.GROUP_ID
 	char m_cAutoSampleFlag;				//15.AUTOSAMPLEFLAG
 
-	// CPRJ용 물류 정보
+	// CPRJ占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	char m_strProdType[3];
 	char m_strBatchID[13];
 	char m_strPairHPanelID[13];
@@ -185,17 +188,17 @@
 	BYTE m_nGlassDataBitSignal[4];
 	bool m_bJob_end;  
 
-	//201217 CJH - 찍은 Defect Review 개수
+	//201217 CJH - 占쏙옙占쏙옙 Defect Review 占쏙옙占쏙옙
 	int m_nReviewNum;
-	//201221 CJH - 파싱한 Stack 결과
+	//201221 CJH - 占식쏙옙占쏙옙 Stack 占쏙옙占�
 	int m_nStackNum;
 	BOOL m_bStackRead;
 
-	//210203 CJH - CutOff 대상 결함 수
+	//210203 CJH - CutOff 占쏙옙占� 占쏙옙占쏙옙 占쏙옙
 	int m_nCutOffDefectNum;
-	//210323 CJH - Server/Frame Shrink 정보 추가
+	//210323 CJH - Server/Frame Shrink 占쏙옙占쏙옙 占쌩곤옙
 	char m_strShrinked[6];
-	//210326 CJH - RAW 입력 Defect 수량 상한 사용여부
+	//210326 CJH - RAW 占쌉뤄옙 Defect 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙肉⑼옙占�
 	BOOL m_bRawCutoff;
 
 };
@@ -219,7 +222,7 @@
 	}
 	int getTotalDefectNum(){return m_nDefectNumTypeTB+m_nDefectNumTypeTW+m_nDefectNumTypeRB+m_nDefectNumTypeRW; };
 	int						m_nCellID;							//1. PANEL_ID
-	short					m_nModelIdx;				// 몇 번째 모델인가?
+	short					m_nModelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占싸곤옙?
 
 	char					m_strCellName[32];
 	int						m_rectCellLeft;
@@ -232,7 +235,7 @@
 	int						m_nJudgeGlade;
 
 
-	//결함 갯수 관리 변수
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	int			m_nDefectNumSizeSmall;
 	int			m_nDefectNumSizeMid;
 	int			m_nDefectNumSizeLarge;
@@ -256,12 +259,43 @@
 	char		m_strProImage[32];
 	char		m_strAvgGray_0[12];
 	char		m_strPortion_0[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_0[12];
+	char		m_strAvgAmp_0[12];
+	char		m_strFFTVar_0[12];
+	char		m_strFFTVah_0[12];
+	char		m_strFFTVaq_0[12];
+	char		m_strFFTPK_0[12];
+
 	char		m_strAvgGray_1[12];
 	char		m_strPortion_1[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_1[12];
+	char		m_strAvgAmp_1[12];
+	char		m_strFFTVar_1[12];
+	char		m_strFFTVah_1[12];
+	char		m_strFFTVaq_1[12];
+	char		m_strFFTPK_1[12];
+
 	char		m_strAvgGray_2[12];
 	char		m_strPortion_2[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_2[12];
+	char		m_strAvgAmp_2[12];
+	char		m_strFFTVar_2[12];
+	char		m_strFFTVah_2[12];
+	char		m_strFFTVaq_2[12];
+	char		m_strFFTPK_2[12];
+
 	char		m_strAvgGray_3[12];
 	char		m_strPortion_3[12];
+	//kyh Mura Data 占쌩곤옙 0622
+	char		m_strCorner_Gray_3[12];
+	char		m_strAvgAmp_3[12];
+	char		m_strFFTVar_3[12];
+	char		m_strFFTVah_3[12];
+	char		m_strFFTVaq_3[12];
+	char		m_strFFTPK_3[12];
 
 	int			m_nDefectNumJudgeOKWhite;
 	int			m_nDefectNumJudgeOKBlack;
@@ -274,17 +308,17 @@
 
 	int			m_nReflowResult[8];			// 0: Reflow X 1: Reflow OK 2: Reflow NG
 
-	// Filtering된 Stack별 수
+	// Filtering占쏙옙 Stack占쏙옙 占쏙옙
 	int			m_nDefectTDCount;
 	int			m_nDefectSDCount;
 	int			m_nDefectPDCount;
 	int			m_nDefectSPCount;
 
-	// Gate/Data 총 갯수
+	// Gate/Data 占쏙옙 占쏙옙占쏙옙
 	int			m_nGateNum;
 	int			m_nDataNum;
 
-	// 210129 CJH - Cell Origin 방향
+	// 210129 CJH - Cell Origin 占쏙옙占쏙옙
 	int			m_nCellXDir;
 	int			m_nCellYDir;
 };
@@ -297,26 +331,27 @@
 	}
 
 	//////////////////////////////////////////////////////////////////////////
-	//여기서 부터 리뷰 영역 [김태현 2019/1/19]
+	//占쏙옙占썩서 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/1/19]
 	ditRaw::ReviewPlanType			m_nPlanType	;	
 	int			m_nResultCode;  //0:None, 1:Success
-	int			m_nShotIndex; //리뷰 찍은 순번 [김태현 2018/12/5]
+	int			m_nShotIndex; //占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/12/5]
 	int			m_nModuleIndex;
 	int			m_nMagnificIndex;
 	float		m_fManification;
 	float		m_fManificResoultion;
 	char		m_strRevImageName[256];
+	char		m_strRevImagePath[256];
 
 	//////////////////////////////////////////////////////////////////////////
-	// Measure 영역
+	// Measure 占쏙옙占쏙옙
 	int			m_nMeasure_Index;
 	int			m_nMeasure_ResultCode; //0:None, 1:Success
 	float		m_fMesure_ResultData[8];	// 0:Type, 1:ShiftX, 2:ShiftY
 
 	//////////////////////////////////////////////////////////////////////////
-	// WSI영역
+	// WSI占쏙옙占쏙옙
 	int			m_nWsi_ResultCode; //0:None, 1:Success
-	int			m_nWsi_Type;									// 함몰 / 돌기
+	int			m_nWsi_Type;									// 占쌉몌옙 / 占쏙옙占쏙옙
 	float		m_fWsi_ResultData[8];			// 0:Type, 1:Height(um), 2:Width
 	char		m_strWsi_2DImageFilename[256];
 	char		m_strWsi_3DImageFilename[256]; 
@@ -324,14 +359,14 @@
 	int			m_nWsi_pReflowResultData[8];
 	double		m_dWsi_DamDistance;
 
-	double		m_dWsiMmMotorX;								// WSI 모터 좌표 20180223 HJH
+	double		m_dWsiMmMotorX;								// WSI 占쏙옙占쏙옙 占쏙옙표 20180223 HJH
 	double		m_dWsiMmMotorY;
-	float		m_fWsiManification;							// WSI 배율
+	float		m_fWsiManification;							// WSI 占쏙옙占쏙옙
 
 	//////////////////////////////////////////////////////////////////////////
-	// Reflow 영역	
+	// Reflow 占쏙옙占쏙옙	
 	int			m_nReflow_Index;
-	int			m_nReflow_ResultCode; //0:None, // 검출한 Line의 개수. 3 미만 : DAM2 Reflow 판정, 4~5 : DAM1 Reflow 판정, 6 : no Reflow 판정 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
+	int			m_nReflow_ResultCode; //0:None, // 占쏙옙占쏙옙占쏙옙 Line占쏙옙 占쏙옙占쏙옙. 3 占싱몌옙 : DAM2 Reflow 占쏙옙占쏙옙, 4~5 : DAM1 Reflow 占쏙옙占쏙옙, 6 : no Reflow 占쏙옙占쏙옙 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
 	float		m_fReflow_LinePosData[8];	
 	int			m_nReflow_Side;
 	int			m_nReflow_InspectionMode;
@@ -347,107 +382,108 @@
 	short			m_nDefectID;
 	short			m_nCameraID;
 	short			m_nScanIdx;
-	//short			m_nDefectIdx;				// 카메라에서의 결함 인덱스
-	int				m_nDefectIdx;				// 카메라에서의 결함 인덱스 201207 CJH - 자릿 수 넘침. int형으로 변경
+	//short			m_nDefectIdx;				// 카占쌨라에쇽옙占쏙옙 占쏙옙占쏙옙 占싸듸옙占쏙옙
+	int				m_nDefectIdx;				// 카占쌨라에쇽옙占쏙옙 占쏙옙占쏙옙 占싸듸옙占쏙옙 201207 CJH - 占쌘몌옙 占쏙옙 占쏙옙침. int占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 
-	int				m_nPixelConv;				// pixel 단위 좌표
-	int				m_nPixelScan;				// pixel 단위 좌표
+	int				m_nPixelConv;				// pixel 占쏙옙占쏙옙 占쏙옙표
+	int				m_nPixelScan;				// pixel 占쏙옙占쏙옙 占쏙옙표
 
-	short							m_nPixelSize;				// 결함크기		---------------------------------PS
-	short/*SERVER_DefectType*/		m_DefectType;				// 결함 타입	---------------------------------DT
-	short/*SERVER_DefectSubType*/	m_DefectSubType;			// 결함의 판정상태.
-	short/*SERVER_DefectBDType*/	m_DefectBDType;				// 결함 타입 - Bright, Dark, Both
+	short							m_nPixelSize;				// 占쏙옙占쏙옙크占쏙옙		---------------------------------PS
+	short/*SERVER_DefectType*/		m_DefectType;				// 占쏙옙占쏙옙 타占쏙옙	---------------------------------DT
+	short/*SERVER_DefectSubType*/	m_DefectSubType;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+	short/*SERVER_DefectBDType*/	m_DefectBDType;				// 占쏙옙占쏙옙 타占쏙옙 - Bright, Dark, Both
 
-	short			m_sPixelWidth;				// 픽셀단위 결함 너비
-	short			m_sPixelHeight;				// 픽셀단위 결함 높이
-	short			m_nLevelSrcMin;				// 결함 밝기 Min	-----------------------------SN
-	short			m_nLevelSrcMax;				// 결함 밝기 Max	-----------------------------SX
-	short			m_nLevelSrcAvg;				// 결함 밝기 Avg	-----------------------------SA
-	short			m_nLevelRefMin;				// 비교대상 밝기 Min	-------------------------RN
-	short			m_nLevelRefMax;				// 비교대상 밝기 Max	-------------------------RX
-	short			m_nLevelRefAvg;				// 비교대상 밝기 Avg	-------------------------RA
-	short			m_nLevelDiffMin;			// 비교차 Min	---------------------------------DN
-	short			m_nLevelDiffMax;			// 비교차 Max	---------------------------------DX
-	short			m_nLevelDiffAvg;			// 비교차 Avg	---------------------------------DA
+	short			m_sPixelWidth;				// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占십븝옙
+	short			m_sPixelHeight;				// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	short			m_nLevelSrcMin;				// 占쏙옙占쏙옙 占쏙옙占� Min	-----------------------------SN
+	short			m_nLevelSrcMax;				// 占쏙옙占쏙옙 占쏙옙占� Max	-----------------------------SX
+	short			m_nLevelSrcAvg;				// 占쏙옙占쏙옙 占쏙옙占� Avg	-----------------------------SA
+	short			m_nLevelRefMin;				// 占쏟교댐옙占� 占쏙옙占� Min	-------------------------RN
+	short			m_nLevelRefMax;				// 占쏟교댐옙占� 占쏙옙占� Max	-------------------------RX
+	short			m_nLevelRefAvg;				// 占쏟교댐옙占� 占쏙옙占� Avg	-------------------------RA
+	short			m_nLevelDiffMin;			// 占쏙옙占쏙옙 Min	---------------------------------DN
+	short			m_nLevelDiffMax;			// 占쏙옙占쏙옙 Max	---------------------------------DX
+	short			m_nLevelDiffAvg;			// 占쏙옙占쏙옙 Avg	---------------------------------DA
 
-	int				m_nDefectRScale;			// 픽셀단위 결함 높이	-------------------------RS
-	short			m_sThreshold;				// 결함을 검출할 때의 Threshold
-	short			m_sThresholdAvg;			// 결함을 검출할 때의 Threshold AVG
-	short			m_sDefectPeak;				// 결함의 Peak.
-	short			m_sDefectLevel;				// (DiffAvg - Th) BOE 8G 요청사항
+	int				m_nDefectRScale;			// 占싫쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙	-------------------------RS
+	short			m_sThreshold;				// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 Threshold
+	short			m_sThresholdAvg;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 Threshold AVG
+	short			m_sDefectPeak;				// 占쏙옙占쏙옙占쏙옙 Peak.
+	short			m_sDefectLevel;				// (DiffAvg - Th) BOE 8G 占쏙옙청占쏙옙占쏙옙
 
-	int				m_nPixelGlassStart;			// Glass 시작 픽셀
+	int				m_nPixelGlassStart;			// Glass 占쏙옙占쏙옙 占싫쇽옙
 	short			m_sDefectLoc;
 
-	short			m_sZonePixelCount[16];	// Zone별 결함 Pixel 수
-	short			m_sZoneValueMin[16];	// Zone별 결함 Min
-	short			m_sZoneValueMax[16];	// Zone별 결함 Max
-	short			m_sZoneValueAvg[16];	// Zone별 결함 Avg
+	short			m_sZoneClassPixelCount[16];
+	short			m_sZonePixelCount[16];	// Zone占쏙옙 占쏙옙占쏙옙 Pixel 占쏙옙
+	short			m_sZoneValueMin[16];	// Zone占쏙옙 占쏙옙占쏙옙 Min
+	short			m_sZoneValueMax[16];	// Zone占쏙옙 占쏙옙占쏙옙 Max
+	short			m_sZoneValueAvg[16];	// Zone占쏙옙 占쏙옙占쏙옙 Avg
 	short			m_sZonePixelPercent[16];	// --------------------------------------Z0~ZF
 
-	//210127 CJH - Zone별 Source Gray 입력
-	short			m_sZoneValueSrcMin[16];	// Zone별 Source Min
-	short			m_sZoneValueSrcMax[16];	// Zone별 Source Max
-	short			m_sZoneValueSrcAvg[16]; // Zone별 Source Avg
+	//210127 CJH - Zone占쏙옙 Source Gray 占쌉뤄옙
+	short			m_sZoneValueSrcMin[16];	// Zone占쏙옙 Source Min
+	short			m_sZoneValueSrcMax[16];	// Zone占쏙옙 Source Max
+	short			m_sZoneValueSrcAvg[16]; // Zone占쏙옙 Source Avg
 
-	int				m_nUMOriginX;				// um단위 x좌표 (원점기준)
-	int				m_nUMOriginY;				// um단위 y조표 (원점기준)
-	int				m_nUMCenterAlignX;			// um단위 X좌표 (Glass Center 기준, 얼라인보정 후)
-	int				m_nUMCenterAlignY;			// um단위 Y좌표 (Glass Center 기준, 얼라인보정 후)
-	int				m_nUMCenterX;				// um단위 X좌표 (Glass Center 기준, 얼라인보정 전)
-	int				m_nUMCenterY;				// um단위 Y좌표 (Glass Center 기준, 얼라인보정 전)
-	int				m_nUMSizeX;					// um단위 X 크기	-----------------------------UX
-	int				m_nUMSizeY;					// um단위 Y 크기	-----------------------------UY
-	int				m_nUMSize;					// um단위 크기.
-	CRect			m_RectUM;					// 디펙 센터 기준 사각형.
+	int				m_nUMOriginX;				// um占쏙옙占쏙옙 x占쏙옙표 (占쏙옙占쏙옙占쏙옙占쏙옙)
+	int				m_nUMOriginY;				// um占쏙옙占쏙옙 y占쏙옙표 (占쏙옙占쏙옙占쏙옙占쏙옙)
+	int				m_nUMCenterAlignX;			// um占쏙옙占쏙옙 X占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterAlignY;			// um占쏙옙占쏙옙 Y占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterX;				// um占쏙옙占쏙옙 X占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMCenterY;				// um占쏙옙占쏙옙 Y占쏙옙표 (Glass Center 占쏙옙占쏙옙, 占쏙옙占쏙옙觀占쏙옙占� 占쏙옙)
+	int				m_nUMSizeX;					// um占쏙옙占쏙옙 X 크占쏙옙	-----------------------------UX
+	int				m_nUMSizeY;					// um占쏙옙占쏙옙 Y 크占쏙옙	-----------------------------UY
+	int				m_nUMSize;					// um占쏙옙占쏙옙 크占쏙옙.
+	CRect			m_RectUM;					// 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占썹각占쏙옙.
 
-	short/*SERVER_DefectSizeType*/	m_DefectSizeType;			// 결함 크기 종류enum SERVER_DefectSizeType		{ SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
-	short/*SERVER_DefectPeakType*/	m_DefectPeakType;			// Peak의 종류.
-	short/*Judgement*/				m_DefectJudgement;			// 결함 판정.
-	BOOL					m_bDefectCutoff;			// 컷 오프 디펙(TRUE= Cutoff, FALSE)
-	short/*MAP16_DefectClass*/		m_DefectClass;				// BOE Defect Class 16등분 구분
-	int				m_nPadRegionIdx;			// PAD 영역 인덱스
+	short/*SERVER_DefectSizeType*/	m_DefectSizeType;			// 占쏙옙占쏙옙 크占쏙옙 占쏙옙占쏙옙enum SERVER_DefectSizeType		{ SizeType_Unknown = 0, SizeType_Small, SizeType_Mid, SizeType_Large, SizeType_Huge, SizeType_Ultra };
+	short/*SERVER_DefectPeakType*/	m_DefectPeakType;			// Peak占쏙옙 占쏙옙占쏙옙.
+	short/*Judgement*/				m_DefectJudgement;			// 占쏙옙占쏙옙 占쏙옙占쏙옙.
+	BOOL					m_bDefectCutoff;			// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙(TRUE= Cutoff, FALSE)
+	short/*MAP16_DefectClass*/		m_DefectClass;				// BOE Defect Class 16占쏙옙占� 占쏙옙占쏙옙
+	int				m_nPadRegionIdx;			// PAD 占쏙옙占쏙옙 占싸듸옙占쏙옙
 
-	int				m_nUMCellX;					// 셀 원점 기준 x 좌표
-	int				m_nUMCellY;					// 셀 원점 기준 y 좌표
-	short			m_nModelIdx;				// 몇 번째 모델인가?
-	short			m_nCellIdx;					// 몇번째 셀인가?
-	short			m_nCellGate;				// 셀별 Gate라인(얼라인 보정 전)
-	short			m_nCellData;				// 셀별 Data라인(얼라인 보정 전)
-	short			m_nCellGateAlign;			// 셀별 Gate라인(얼라인 보정 후)
-	short			m_nCellDataAlign;			// 셀별 Data라인(얼라인 보정 후)
+	int				m_nUMCellX;					// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 x 占쏙옙표
+	int				m_nUMCellY;					// 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 y 占쏙옙표
+	short			m_nModelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占싸곤옙?
+	short			m_nCellIdx;					// 占쏙옙占승� 占쏙옙占싸곤옙?
+	short			m_nCellGate;				// 占쏙옙占쏙옙 Gate占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellData;				// 占쏙옙占쏙옙 Data占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellGateAlign;			// 占쏙옙占쏙옙 Gate占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
+	short			m_nCellDataAlign;			// 占쏙옙占쏙옙 Data占쏙옙占쏙옙(占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙)
 
-	int				m_nUMShotX;					// 샷 기준 X좌표
-	int				m_nUMShotY;					// 샷 기준 Y좌표
-	short			m_nMaskDefectIdx;			// 한 Glass에서 발견된 마스크결함 묶음의 인덱스.
-	short			m_nShotIdx;					// 노광샷 번호
-	short			m_nMatchShotCount;			// 동일한 마스크 결함의 수.
-	short			m_nMatchMaxSize;			// 동일한 마스크 중 가장 큰 결함의 크기.
+	int				m_nUMShotX;					// 占쏙옙 占쏙옙占쏙옙 X占쏙옙표
+	int				m_nUMShotY;					// 占쏙옙 占쏙옙占쏙옙 Y占쏙옙표
+	short			m_nMaskDefectIdx;			// 占쏙옙 Glass占쏙옙占쏙옙 占쌩견듸옙 占쏙옙占쏙옙크占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙.
+	short			m_nShotIdx;					// 占쎈광占쏙옙 占쏙옙호
+	short			m_nMatchShotCount;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙크 占쏙옙占쏙옙占쏙옙 占쏙옙.
+	short			m_nMatchMaxSize;			// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙크 占쏙옙 占쏙옙占쏙옙 큰 占쏙옙占쏙옙占쏙옙 크占쏙옙.
 
-	short			m_nRepeatCount;				// 연속결함발견위한 동일좌표 반복수
+	short			m_nRepeatCount;				// 占쏙옙占쌈곤옙占쌉발곤옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙표 占쌥븝옙占쏙옙
 	short			m_nMaskRepeatCount;
 	int				m_StackInfo;				// Stack Flag
-	BOOL			m_bRealStack;				// Stack 머지에 의한 TD(TRUE) 인지, 필터링에 의한 TD(FALSE)구분할 수 있다.
-	short			m_nStackStepCount;			// Stack 수
-	short			m_nStackColorIdx;			// Color를 선택하는 인덱스.
+	BOOL			m_bRealStack;				// Stack 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 TD(TRUE) 占쏙옙占쏙옙, 占쏙옙占싶몌옙占쏙옙 占쏙옙占쏙옙 TD(FALSE)占쏙옙占쏙옙占쏙옙 占쏙옙 占쌍댐옙.
+	short			m_nStackStepCount;			// Stack 占쏙옙
+	short			m_nStackColorIdx;			// Color占쏙옙 占쏙옙占쏙옙占싹댐옙 占싸듸옙占쏙옙.
 	//CString			m_strStackStep[CFDEFECT_STACKCOUNT];			// Stack Step.
-	char			m_strStackFirst[60];			// Stack Step. //201221 CJH - 최대 사이즈 60bytes
-	char			m_strUnitID[16];				// 유닛아이디
+	char			m_strStackFirst[60];			// Stack Step. //201221 CJH - 占쌍댐옙 占쏙옙占쏙옙占쏙옙 60bytes
+	char			m_strUnitID[16];				// 占쏙옙占쌍억옙占싱듸옙
 
-	int				m_ClassificationType;				// enum ClassificationType			{ ClassType_None= 0, ClassType_PI_Over= 1, ClassType_PI_Under= 2, ClassType_TFE_Circle= 3, ClassType_Bubble, ClassType_Scratch, ClassType_Particle}; Classification Type, PI나 TFE등 추가 분류  알고리즘 적용 결과.
-	int				m_nAtomWidth;				// TFE 핵 너비
-	int				m_nAtomHeight;				// TFE 핵 높이
-	short/*ReKind*/			m_DefectKind;				// 결함 종류
+	int				m_ClassificationType;				// enum ClassificationType			{ ClassType_None= 0, ClassType_PI_Over= 1, ClassType_PI_Under= 2, ClassType_TFE_Circle= 3, ClassType_Bubble, ClassType_Scratch, ClassType_Particle}; Classification Type, PI占쏙옙 TFE占쏙옙 占쌩곤옙 占싻뤄옙  占싯곤옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占�.
+	int				m_nAtomWidth;				// TFE 占쏙옙 占십븝옙
+	int				m_nAtomHeight;				// TFE 占쏙옙 占쏙옙占쏙옙
+	short/*ReKind*/			m_DefectKind;				// 占쏙옙占쏙옙 占쏙옙占쏙옙
 
 	char			m_strDefectCode[32];			// Defect Code
 	BOOL			m_bMergeState;				// Merge Status
 	char			m_strAoiImageName[256];			// Defect Image Name(CCD Image)
-	int				m_nDefectMerge;		// 현재 디펙의 머지 여부
+	int				m_nDefectMerge;		// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 
 
 	int				m_nPixelSizeOrigin;
 	int				m_nScratchRatio;
-	int				m_nDensity;			// 원형 결함 구분을 위한 밀도 [2017.8.2 bhs]
+	int				m_nDensity;			// 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占싻듸옙 [2017.8.2 bhs]
 
 	char			m_strDefectName[16];
 	char			m_strDefectType[16];
@@ -455,19 +491,27 @@
 	double			m_dScanResolution;
 	double			m_dConvResolution;
 
-	int				m_nAngle;					// 각도
-	int				m_nMajor;					// 장축 길이(Long)
-	int				m_nMinor;					// 단축 길이(Short)
-	int				m_nCompact;					// Blob 장축을 지름으로 하는 원의 넓이와 Blob 넓이의 비율
-	int				m_nThickness;				// Blob 넓이와 장축의 비율 (Area / Major)
+	int				m_nAngle;					// 占쏙옙占쏙옙
+	int				m_nMajor;					// 占쏙옙占쏙옙 占쏙옙占쏙옙(Long)
+	int				m_nMinor;					// 占쏙옙占쏙옙 占쏙옙占쏙옙(Short)
+	int				m_nCompact;					// Blob 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占싹댐옙 占쏙옙占쏙옙 占쏙옙占싱울옙 Blob 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
+	int				m_nThickness;				// Blob 占쏙옙占싱울옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 (Area / Major)
 	
-	short			m_nHliLevelIdx;				// 몇 번째 레벨(채널)인가?
-	int				m_nHliLayers;				// 해당결함에 포함된 레이어 bit처리
+	short			m_nHliLevelIdx;				// 占쏙옙 占쏙옙째 占쏙옙占쏙옙(채占쏙옙)占싸곤옙?
+	int				m_nHliLayers;				// 占쌔댐옙占쏙옙篤占� 占쏙옙占쌉듸옙 占쏙옙占싱억옙 bit처占쏙옙
 
-	BOOL			m_bShrinked;				//210323 CJH - Frame Shrink 정보 추가
+	BOOL			m_bShrinked;				//210323 CJH - Frame Shrink 占쏙옙占쏙옙 占쌩곤옙
+
+	char			m_strAoiImagePath[255];
+	char			m_strReviewImagePath[255];
+
+	int				m_nAlignRectLeft;
+	int				m_nAlignRectTop;
+	int				m_nAlignRectBottom;
+	int				m_nAlignRectRight;
 
 
-	//리뷰 디펙 정보 [김태현 2019/1/19]
+	//占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/1/19]
 	_grmDefectReviewData m_ReviewDefect;
 };
 
@@ -491,6 +535,8 @@
 	grcWriteBin = 201,
 	grcReadBin = 202,
 
+	grcReviewWriteBIn = 301,
+
 	grcGlassRawCommand
 };
 
@@ -510,7 +556,7 @@
 
 struct _grmDitMemInfo
 {
-	//공유 메모리 생성할 공간 결정 [김태현 2018/11/12]
+	//占쏙옙占쏙옙 占쌨몌옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	size_t m_nGlassRawDataSize;
 	int m_nGlassMaxDataNum;
 	int m_nBlockMaxDataNum;
@@ -518,7 +564,7 @@
 	int m_nDefectMaxDataNum;
 	int m_nStackMaxDataNum;
 
-	//Char 기준 자료가 있는 시작 위치 [김태현 2018/11/12]
+	//Char 占쏙옙占쏙옙 占쌘료가 占쌍댐옙 占쏙옙占쏙옙 占쏙옙치 [占쏙옙占쏙옙占쏙옙 2018/11/12]
 	int m_nGlassDataPoint;
 	int m_nBlockDataPoint;
 	int m_nCellDataPoint;
@@ -534,8 +580,8 @@
 struct _grmDitGlassRawInfo : public _grmDitMemInfo, public _grmDitCommand
 {
 	size_t m_nGlassLoadingCount;
-	emAOIProcStep m_ClientProcStep; //AOI, Review가 보낸 명령
-	emAOIProcStep m_ServerProcStep; //GlassRaw Messenger(Server)가 처리 완료 한 명령
+	emAOIProcStep m_ClientProcStep; //AOI, Review占쏙옙 占쏙옙占쏙옙 占쏙옙占�
+	emAOIProcStep m_ServerProcStep; //GlassRaw Messenger(Server)占쏙옙 처占쏙옙 占싹뤄옙 占쏙옙 占쏙옙占�
 };
 
 class CgrmGlassRawData
@@ -622,7 +668,7 @@
 	{
 		if(pInfo == NULL || pData == NULL) return FALSE;
 
-		if(1) //new type //메모리 총 공간 크기에 상관없이 
+		if(1) //new type //占쌨몌옙 占쏙옙 占쏙옙占쏙옙 크占썩에 占쏙옙占쏙옙占쏙옙占� 
 		{
 			//if(pInfo->m_nGlassRawDataSize != m_MemInfo.m_nGlassRawDataSize) return FALSE;
 
diff --git a/ReviewSystem/ReviewSystem/ReviewProcessor.cpp b/ReviewSystem/ReviewSystem/ReviewProcessor.cpp
index 20fe4ad..ba9571d 100644
--- a/ReviewSystem/ReviewSystem/ReviewProcessor.cpp
+++ b/ReviewSystem/ReviewSystem/ReviewProcessor.cpp
@@ -233,6 +233,11 @@
 	m_strSaveImageUploadPath = strImagePath;
 }
 
+void CReviewProcessor::SetReviewImagePath(const CString& strImagePath)
+{
+	m_strSaveImageReviewPath = strImagePath;
+}
+
 void CReviewProcessor::GetSaveImageBasePath( CString& strPath )
 {
 	strPath = m_strSaveImageBasePath; 
@@ -243,6 +248,11 @@
  return m_strSaveImageUploadPath; 
 }
 
+CString CReviewProcessor::GetReviewUploadImagePath()
+{
+	return m_strSaveImageReviewPath;
+}
+
 void CReviewProcessor::SetRTMSUploadImagePath(const CString& strImagePath)
 {
 	m_strRTMSImagePath = strImagePath;
diff --git a/ReviewSystem/ReviewSystem/ReviewProcessor.h b/ReviewSystem/ReviewSystem/ReviewProcessor.h
index 89d785e..dbfb2ff 100644
--- a/ReviewSystem/ReviewSystem/ReviewProcessor.h
+++ b/ReviewSystem/ReviewSystem/ReviewProcessor.h
@@ -174,6 +174,8 @@
 	void	SetUploadImagePath(const CString& strImagePath);
 	void	SetRTMSUploadImagePath(const CString& strImagePath);
 
+	void	SetReviewImagePath(const CString& strReviewImagePath);
+
 	//Plan吏꾪뻾媛� Count �몴湲� 
 	void SetPlanReviewCount(int ncount) {
 		nPlanReviewCount = ncount;
@@ -196,6 +198,8 @@
 	void	GetSaveImageBasePath(CString& strPath);
 	CString	GetUploadImagePath();
 	CString GetRTMSUploadImagePath();
+
+	CString	GetReviewUploadImagePath();
 
 
 	// Cell function
@@ -265,6 +269,7 @@
 	// image path
 	CString						m_strSaveImageBasePath;
 	CString						m_strSaveImageUploadPath;
+	CString						m_strSaveImageReviewPath;
 	CString						m_strInspectImagePath;
 	CString						m_strRTMSImagePath;
 	int							m_nReviewCount;				// [2017:5:21]-[WEZASW] : Review �씠誘몄� �꽕�씠諛� 猷곗뿉 �쓽�븳 SequenceNo 移댁슫�듃(由щ럭 �룷�씤�듃 �닚�꽌)
diff --git a/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.cpp b/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.cpp
index 52ad15b..af864fc 100644
--- a/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.cpp
+++ b/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.cpp
@@ -88,7 +88,7 @@
 	int nEndResultIdx	= pReviewResult->GetEndSReviewResultIndex();
 						
 	
-	// 인덱스가 현재 마지막 인덱스 보다 클시..
+	// 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙 占쏙옙占쏙옙 클占쏙옙..
 	if (nCurResultIdx > nEndResultIdx)  
 	{
 		LeaveCriticalSection(&m_csUserCriticalSection);
@@ -97,7 +97,7 @@
 	}
 
 
-	// 현재 결과데이터 저장
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙
 
 	wsiResult.nWsi_ResultIndex = measureResut.nResultIndex;
 	wsiResult.nResultCode = measureResut.nResultCode;
@@ -138,8 +138,8 @@
 // 		g_pLog->DisplayMessage(_T("[ReviewProcessor]JugementR [%d] JugementG [%d] JugementB [%d]"), wsiResult.nJugementR, wsiResult.nJugementG, wsiResult.nJugementB);
 // 		g_pLog->DisplayMessage(_T("[ReviewProcessor]RZoneHeight [%.03lf] GZoneHeight [%.03lf] BZoneHeight [%.03lf]"), wsiResult.dRZoneHeight, wsiResult.dGZoneHeight, wsiResult.dBZoneHeight);
 
-// 		wsiResult.추가 하세요= measureResut.nMultiShot;
-// 		wsiResult.추가 하세요= measureResut.nCurrentShotNumber;
+// 		wsiResult.占쌩곤옙 占싹쇽옙占쏙옙= measureResut.nMultiShot;
+// 		wsiResult.占쌩곤옙 占싹쇽옙占쏙옙= measureResut.nCurrentShotNumber;
 		break;
 	case 3: //BANK
 		wsiResult.dRZoneHeight = measureResut.dRZoneHeight;
@@ -147,14 +147,14 @@
 		wsiResult.dBZoneHeight = measureResut.dBZoneHeight;
 		wsiResult.dDefectHeight = measureResut.dDefectHeight;
 		wsiResult.nWsi_DefectType = measureResut.nDefectType;
-// 		wsiResult.추가 하세요= measureResut.nMultiShot;
-// 		wsiResult.추가 하세요= measureResut.nCurrentShotNumber;
+// 		wsiResult.占쌩곤옙 占싹쇽옙占쏙옙= measureResut.nMultiShot;
+// 		wsiResult.占쌩곤옙 占싹쇽옙占쏙옙= measureResut.nCurrentShotNumber;
 		break;
 	case 4: //CS
 		wsiResult.dCSHeight = measureResut.dCSHeight;
 		wsiResult.dDefectHeight = measureResut.dDefectHeight;
 		wsiResult.nWsi_DefectType = measureResut.nDefectType;
-// 		wsiResult.추가 하세요= measureResut.nMultiShot;
+// 		wsiResult.占쌩곤옙 占싹쇽옙占쏙옙= measureResut.nMultiShot;
 		break;
 	}
 
@@ -163,7 +163,7 @@
 	memcpy(wsiResult.pWsi_ResultData, measureResut.pResultData, sizeof(wsiResult.pWsi_ResultData));
 
 
-	// 결과 데이터 추가
+	// 占쏙옙占� 占쏙옙占쏙옙占쏙옙 占쌩곤옙
 	SReviewResult *pProcessResult = NULL;
 	if (pGlassResult->SetWsiResultData(nModuleIndex, nCurResultIdx, wsiResult, nGlassPosX, nGlassPosY, nMotorPosX, nMotorPosY, dTime))
 	{
@@ -173,10 +173,10 @@
 		pProcessResult = pReviewResult->GetSReviewResult(nCurResultIdx);
 	}
 
-	// 저장 성공시, 리뷰 프로세서에 포인터 전달
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙, 占쏙옙占쏙옙 占쏙옙占싸쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	if (pProcessResult)
 	{
-		// 처리 쓰레드 수행
+		// 처占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 		if (AddReviewProcessData(pProcessResult)==1)
 		{
 			g_pLog->DisplayMessage(_T("[ReviewProcessor]Add Process Data module[%d] result[%d]"), nModuleIndex, nCurResultIdx);
@@ -192,7 +192,7 @@
 	
 	LeaveCriticalSection(&m_csUserCriticalSection);
 
-	// 결과 갱신.
+	// 占쏙옙占� 占쏙옙占쏙옙.
 	m_pRP2P->IRP2P_UpdateReviewResult(nModuleIndex, pGlassResult);
 	return;
 
@@ -238,7 +238,7 @@
 	int nEndResultIdx	= pReviewResult->GetEndSReviewResultIndex();
 
 
-	// 인덱스가 현재 마지막 인덱스 보다 클시..
+	// 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙 占쏙옙占쏙옙 클占쏙옙..
 	if (nCurResultIdx > nEndResultIdx)  
 	{
 		LeaveCriticalSection(&m_csUserCriticalSection);
@@ -246,14 +246,14 @@
 		g_pLog->DisplayMessage(_T("[ReviewProcessor]SetWsiResultData module[%d] point[%d] result[%d]"), nModuleIndex, measureResut.nResultIndex, nCurResultIdx);
 	}
 
-	// 현재 결과데이터 저장
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙
 	wsiUserResult.nWsi_ResultCode		= measureResut.nResultCode;
 	wsiUserResult.nWsi_Type				= measureResut.nResultType;
 	wsiUserResult.nWsi_SlopeWarn		= measureResut.nXSlopeWarn;
 	memcpy(wsiUserResult.pWsi_ResultData, measureResut.pResultData, sizeof(wsiUserResult.pWsi_ResultData));
 
 
-	// 결과 데이터 추가
+	// 占쏙옙占� 占쏙옙占쏙옙占쏙옙 占쌩곤옙
 	SReviewResult *pProcessResult = NULL;
 	if (pGlassResult->SetUserWsiResultData(nModuleIndex, nCurResultIdx, wsiUserResult, nGlassPosX, nGlassPosY, nMotorPosX, nMotorPosY, dTime))
 	{
@@ -263,10 +263,10 @@
 		pProcessResult = pReviewResult->GetSReviewResult(nCurResultIdx);
 	}
 
-	// 저장 성공시, 리뷰 프로세서에 포인터 전달
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙, 占쏙옙占쏙옙 占쏙옙占싸쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	if (pProcessResult)
 	{
-		// 처리 쓰레드 수행
+		// 처占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 		if (AddReviewProcessData(pProcessResult)==1)
 		{
 			g_pLog->DisplayMessage(_T("[ReviewProcessor]Add Process Data module[%d] result[%d]"), nModuleIndex, nCurResultIdx); 
@@ -282,7 +282,7 @@
 
 	LeaveCriticalSection(&m_csUserCriticalSection);
 
-	// 결과 갱신.
+	// 占쏙옙占� 占쏙옙占쏙옙.
 	m_pRP2P->IRP2P_UpdateReviewResult(nModuleIndex, pGlassResult);
 	return;
 
@@ -337,7 +337,7 @@
 	int nEndResultIdx = pReviewResult->GetEndSReviewResultIndex();
 
 
-	// 인덱스가 현재 마지막 인덱스 보다 클시..
+	// 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙 占쏙옙占쏙옙 클占쏙옙..
 	if (nCurResultIdx > nEndResultIdx)
 	{
 		LeaveCriticalSection(&m_csUserCriticalSection);
@@ -345,7 +345,7 @@
 		g_pLog->DisplayMessage(_T("[ReviewProcessor]SetWsiMultiShotResultData module[%d] point[%d] result[%d]"), nModuleIndex, measureResut.nResultIndex, nCurResultIdx);
 	}
 
-	// 현재 결과데이터 저장
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙
 	wsiResult.nWsi_ResultCode = measureResut.nResultCode;
 	wsiResult.nWsi_Type = measureResut.nResultType;
 	wsiResult.nWsi_SlopeWarn = measureResut.nXSlopeWarn;
@@ -353,7 +353,7 @@
 	memcpy(wsiResult.pWsi_ResultData, measureResut.pResultData, sizeof(wsiResult.pWsi_ResultData));
 
 
-	// 결과 데이터 추가
+	// 占쏙옙占� 占쏙옙占쏙옙占쏙옙 占쌩곤옙
 	SReviewResult *pProcessResult = NULL;
 	if (pGlassResult->SetWsiResultData(nModuleIndex, nCurResultIdx, wsiResult, nGlassPosX, nGlassPosY, nMotorPosX, nMotorPosY, dTime))
 	{
@@ -363,10 +363,10 @@
 		pProcessResult = pReviewResult->GetSReviewResult(nCurResultIdx);
 	}
 
-	// 저장 성공시, 리뷰 프로세서에 포인터 전달
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙, 占쏙옙占쏙옙 占쏙옙占싸쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	if (pProcessResult)
 	{
-		// 처리 쓰레드 수행
+		// 처占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 		if (AddReviewProcessData(pProcessResult) == 1)
 		{
 			g_pLog->DisplayMessage(_T("[ReviewProcessor]Add Process Data module[%d] result[%d]"), nModuleIndex, nCurResultIdx); 
@@ -382,7 +382,7 @@
 
 	LeaveCriticalSection(&m_csUserCriticalSection);
 
-	// 결과 갱신.
+	// 占쏙옙占� 占쏙옙占쏙옙.
 	m_pRP2P->IRP2P_UpdateReviewResult(nModuleIndex, pGlassResult);
 	return;
 
@@ -457,7 +457,7 @@
 	int nStartResultIdx	= pReviewResult->GetStartSReviewResultIndex();
 	int nEndResultIdx	= pReviewResult->GetEndSReviewResultIndex();
 	
-	// 인덱스가 현재 마지막 인덱스 보다 클시..
+	// 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙 占쏙옙占쏙옙 클占쏙옙..
 	if (nCurResultIdx > nEndResultIdx)  
 	{
 		LeaveCriticalSection(&m_csUserCriticalSection);
@@ -465,7 +465,7 @@
 		g_pLog->DisplayMessage(_T("[ReviewProcessor]SetReviewResultData module[%d] point[%d] result[%d]"), nModuleIndex, nResultIndex, nCurResultIdx);
 	}
 
-	// 현재 결과이미지 저장
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙譴占쏙옙占� 占쏙옙占쏙옙
 	SReviewResult *pProcessResult = NULL;
 	switch(GetReviewProcessStatus())
 	{
@@ -509,10 +509,10 @@
 		break;
 	}
 
-	// 저장 성공시, 리뷰 프로세서에 포인터 전달
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙, 占쏙옙占쏙옙 占쏙옙占싸쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	if (pProcessResult)
 	{
-		// 처리 쓰레드 수행
+		// 처占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 		if (AddReviewProcessData(pProcessResult)==1)
 		{
 			g_pLog->DisplayMessage(_T("[ReviewProcessor]Add Process Data module[%d] result[%d]"), nModuleIndex, nCurResultIdx); 
@@ -527,8 +527,8 @@
 	}
 		LeaveCriticalSection(&m_csUserCriticalSection);
 
-		//만약 어느 한쪽이포인트 진행을 다해버리면 아래 구문을 안타서 다시 모터좌표 안쏴줌 
-		// 신호처리 필요함 이거 ㄱㄱ 
+		//占쏙옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙트 占쏙옙占쏙옙占쏙옙 占쏙옙占쌔뱄옙占쏙옙占쏙옙 占싣뤄옙 占쏙옙占쏙옙占쏙옙 占쏙옙타占쏙옙 占쌕쏙옙 占쏙옙占쏙옙占쏙옙표 占싫쏙옙占쏙옙 
+		// 占쏙옙호처占쏙옙 占십울옙占쏙옙 占싱곤옙 占쏙옙占쏙옙 
 		if (nCurResultIdx + 1== pReviewResult->GetSReviewResultCount())
 		{
 			if (nModuleIndex == 0)
@@ -542,7 +542,7 @@
 
 			if (bLeftGantryReviewDone&&bRightGantryReviewDone)
 			{
-				::Sleep(3000); // 딜레이는 필수임. 없으면 동작 안함.
+				::Sleep(3000); // 占쏙옙占쏙옙甄占� 占십쇽옙占쏙옙. 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙.
 				g_pLog->DisplayMessage(_T("[ReviewProcessor]RemainReview Started module[%d]"), nModuleIndex);
 				CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 				switch (GetReviewProcessStatus())
@@ -567,13 +567,13 @@
 			}
 			else if(m_pRP2P->IRP2P_Recipe_GetRsRcpReviewInfo()->GetRcpSchedulingInfo()->GetSingleGantryPath()>0)
 			{
-				//20210302 싱글 겐트리 사용시 모터 로직상 두개의 겐트리가 완료된 상태에서 
-				//시작을 해야됨으로 Review 에서 Count 체크 하는 기능으로 한겐트리 사용시 200개에서 멈추는 현상 발생
-				//그래서 싱글 겐트리 사용시 예외처리 하여 동작하도록 바꿔야됨 CHM
+				//20210302 占싱깍옙 占쏙옙트占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸곤옙占쏙옙 占쏙옙트占쏙옙占쏙옙 占싹뤄옙占� 占쏙옙占승울옙占쏙옙 
+				//占쏙옙占쏙옙占쏙옙 占쌔야듸옙占쏙옙占쏙옙 Review 占쏙옙占쏙옙 Count 체크 占싹댐옙 占쏙옙占쏙옙占쏙옙占� 占싼곤옙트占쏙옙 占쏙옙占쏙옙 200占쏙옙占쏙옙占쏙옙 占쏙옙占쌩댐옙 占쏙옙占쏙옙 占쌩삼옙
+				//占쌓뤄옙占쏙옙 占싱깍옙 占쏙옙트占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙처占쏙옙 占싹울옙 占쏙옙占쏙옙占싹듸옙占쏙옙 占쌕뀐옙森占� CHM
 				g_pLog->DisplayMessage(_T("[ReviewProcessor]Single GantryPath Use"), nModuleIndex);
 				if (bLeftGantryReviewDone || bRightGantryReviewDone)
 				{
-					::Sleep(3000); // 딜레이는 필수임. 없으면 동작 안함.
+					::Sleep(3000); // 占쏙옙占쏙옙甄占� 占십쇽옙占쏙옙. 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙.
 					g_pLog->DisplayMessage(_T("[ReviewProcessor]RemainReview Started module[%d]"), nModuleIndex);
 					CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 					switch (GetReviewProcessStatus())
@@ -601,7 +601,7 @@
 
 		}
 		
-		// 마지막 포인트까지 왔고, 리뷰할 결과가 남아 있으면...
+		// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 占쌉곤옙, 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙...
 		if(nCurResultIdx==nEndResultIdx && nCurResultIdx+1 < pReviewResult->GetSReviewResultCount())
 	    {
 
@@ -624,8 +624,8 @@
 		pReviewResult->SetStartSReviewResultIndex(nStartResultIdx);
 		pReviewResult->SetEndSReviewResultIndex(nEndResultIdx);
 
-		// 나머지 포인트 리뷰 수행하자.
-		::Sleep(3000); // 딜레이는 필수임. 없으면 동작 안함.
+		// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+		::Sleep(3000); // 占쏙옙占쏙옙甄占� 占십쇽옙占쏙옙. 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙.
 		   if (bLeftGantryReviewDone&&bRightGantryReviewDone)
 		   {
 			
@@ -685,7 +685,7 @@
 		}
 	}
 
-	// 결과 갱신.
+	// 占쏙옙占� 占쏙옙占쏙옙.
 	m_pRP2P->IRP2P_UpdateReviewResult(nModuleIndex, pGlassResult, m_nReviewPlanIndex);
 	return;
 
@@ -729,7 +729,7 @@
 {
 	if (m_pRP2P==NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PCControl ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PCControl ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult==NULL || pSequenceProcessor==NULL) 
@@ -737,7 +737,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckReviewComplete())
 	{
 		// check motor ready!
@@ -763,7 +763,7 @@
 {
 	if (m_pRP2P==NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PCControl ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PCControl ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult==NULL || pSequenceProcessor==NULL) 
@@ -771,7 +771,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckUserComplete())
 	{
 		m_pRP2P->IRP2P_DisplayMessage(_T("User Last Point Complete! "));
@@ -796,7 +796,7 @@
 {
 	if (m_pRP2P==NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PLC ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PLC ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult==NULL || pSequenceProcessor==NULL) 
@@ -804,7 +804,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckReflowComplete())
 	{
 		m_pRP2P->IRP2P_DisplayMessage(_T("Reflow Last Point Complete! "));
@@ -829,7 +829,7 @@
 {
 	if (m_pRP2P==NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PCControl ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PCControl ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult==NULL || pSequenceProcessor==NULL) 
@@ -837,7 +837,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckWsiComplete())
 	{
 		m_pRP2P->IRP2P_DisplayMessage(_T("Wsi Last Point Complete! "));
@@ -863,7 +863,7 @@
 	g_pLog->DisplayMessage(_T("PostProcessMeasureResult[%d]"),nThreadIdx);
 	if (m_pRP2P==NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PCControl ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PCControl ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult==NULL || pSequenceProcessor==NULL) 
@@ -871,7 +871,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckMeasureComplete())
 	{
 		m_pRP2P->IRP2P_DisplayMessage(_T("Measure Last Point Complete! "));
@@ -900,7 +900,7 @@
 {
 	if (m_pRP2P==NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PCControl ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PCControl ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult==NULL || pSequenceProcessor==NULL) 
@@ -908,7 +908,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckWsiReflowComplete())
 	{
 		m_pRP2P->IRP2P_DisplayMessage(_T("Wsi Reflow Last Point Complete! "));
@@ -932,7 +932,7 @@
 {
 	if (m_pRP2P==NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PCControl ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PCControl ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult==NULL || pSequenceProcessor==NULL) 
@@ -940,7 +940,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckWsiUserComplete())
 	{
 		m_pRP2P->IRP2P_DisplayMessage(_T("Wsi Last Point Complete! "));
@@ -965,7 +965,7 @@
 {
 	if (m_pRP2P == NULL) return 0;
 
-	// 마지막 포인트인지 확인 후 PCControl ReviewEnd 전송
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 확占쏙옙 占쏙옙 PCControl ReviewEnd 占쏙옙占쏙옙
 	CGlassResult *pGlassResult = m_pRP2P->IRP2P_GetCurrentGlassResult();
 	CSequenceProcessor* pSequenceProcessor = m_pRP2P->IRP2P_GetSequenceProcessor();
 	if (pGlassResult == NULL || pSequenceProcessor == NULL)
@@ -973,7 +973,7 @@
 		return 1;
 	}
 
-	// 조건확인
+	// 占쏙옙占쏙옙확占쏙옙
 	if (pGlassResult->CheckWsiMultiShotComplete())
 	{
 		m_pRP2P->IRP2P_DisplayMessage(_T("WsiMultiShot Last Point Complete! "));
@@ -1138,23 +1138,23 @@
 		return ReviewResult_Process_Fail;
 	}
 	
-	// Snap 시간 저장.
+	// Snap 占시곤옙 占쏙옙占쏙옙.
 	CTime snapTime = CTime::GetCurrentTime();
 	pReviewResult->strSnapTime.Format(_T("%04d%02d%02d%02d%02d%02d"), snapTime.GetYear(), snapTime.GetMonth(), snapTime.GetDay(), 
 		snapTime.GetHour(), snapTime.GetMinute(), snapTime.GetSecond());	// snap_time
 
-	// 리뷰 업로드 이미지 파일 이름 만들기
+	// 占쏙옙占쏙옙 占쏙옙占싸듸옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占싱몌옙 占쏙옙占쏙옙占�
 	CString strImageFileName = _T("");
 	if (MakeReviewImageFileName(pReviewResult)==FALSE)
 	{
 		
 	}
 
-	//결과파일 공유 메모리 리뷰 이미지 이름 및 좌표 채워주기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨몌옙 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占싱몌옙 占쏙옙 占쏙옙표 채占쏙옙占쌍깍옙
 	if(!UpdateMemoryReviewPlan(pReviewResult))
 		m_pRP2P->IRP2P_DisplayMessage(_T("[ReviewPlan] Memory Update Fail!! DefectIdx : %d"), pReviewResult->nDefectidx2);
 	
-	// 로컬 이미지 저장 파일 이름
+	// 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占싱몌옙
 	pReviewResult->strImgFileName = m_strSaveImageBasePath + _T("\\") +pReviewResult->strImgFileName;
 	pReviewResult->nOpticType = 1;
 
@@ -1178,7 +1178,7 @@
 		//	UINT64 nSize = SaveReviewImage(&uploadImage, strPath, m_nReviewImageSize, m_nReviewImageQuality, m_nReviewImageStep);
 			//if (nSize > 0)
 			//	m_pRP2P->IRP2P_DisplayMessage(_T("Backup Review Image Save Success! Size: %d byte [%s]"), nSize, pReviewResult->strUploadImgFileName);
-			// 업로드 이미지 경로 수정 20190917 chm
+			// 占쏙옙占싸듸옙 占싱뱄옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙 20190917 chm
 			strPath.Format(_T("%s\\%s"), m_strSaveImageUploadPath, pReviewResult->strUploadImgFileName);
 			nSize = SaveReviewImage(&uploadImage, strPath, m_nReviewImageSize, m_nReviewImageQuality, m_nReviewImageStep);
 			m_pRP2P->IRP2P_DisplayMessage(_T("Backup Review Image Save Success! Size: %d byte [%s]"), nSize, strPath);
@@ -1193,13 +1193,13 @@
 				{
 					m_pRP2P->IRP2P_DisplayMessage(_T("RTMS Review Image Save Fail [%s] index[%d]"), strRTMSPath, pReviewResult->nDefectIdx);
 				}
-				else m_pRP2P->IRP2P_DisplayMessage(_T("RTMS Review Image Save Success! Size: %d byte [%s] index[%d]"), nSize, strRTMSPath, pReviewResult->nDefectIdx); //taek 210128 속도 문제로 임시로 로그 남기지 않음
+				else m_pRP2P->IRP2P_DisplayMessage(_T("RTMS Review Image Save Success! Size: %d byte [%s] index[%d]"), nSize, strRTMSPath, pReviewResult->nDefectIdx); //taek 210128 占쌈듸옙 占쏙옙占쏙옙占쏙옙 占쌈시뤄옙 占싸깍옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 			}
 
 			if (nSize > 0)
 			{
 				 int aoiindex = CDitGlassRawClient::GetInstance()->GetDefectData(pReviewResult->nDefectidx2)->m_nDefectIdx;
-				m_pRP2P->IRP2P_DisplayMessage(_T("Upload Review Image Save Success! Size: %d byte [%s] index[%d] AOI NO[%d]"), nSize, strRTMSPath, pReviewResult->nDefectIdx, aoiindex); //taek 210128 속도 문제로 임시로 로그 남기지 않음
+				m_pRP2P->IRP2P_DisplayMessage(_T("Upload Review Image Save Success! Size: %d byte [%s] index[%d] AOI NO[%d]"), nSize, strRTMSPath, pReviewResult->nDefectIdx, aoiindex); //taek 210128 占쌈듸옙 占쏙옙占쏙옙占쏙옙 占쌈시뤄옙 占싸깍옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 				//m_pRP2P->IRP2P_DisplayMessage(_T("Upload Review Image Save Success! Size: %d byte [%s]"), nSize, pReviewResult->strUploadImgFileName);
 			}
 			else
@@ -1235,7 +1235,7 @@
 	const CRsRcpReviewInfo*  psRcpReviewInfo = m_pRP2P->IRP2P_Recipe_GetRsRcpReviewInfo();
 	if(psRcpReviewInfo== NULL) m_pRP2P->IRP2P_DisplayMessage(_T("RcpReviewInfo is NULL"));
 	
-	if(psRcpReviewInfo->m_bDefocusUse) //190819chm 디포커스 알람 사용 
+	if(psRcpReviewInfo->m_bDefocusUse) //190819chm 占쏙옙占쏙옙커占쏙옙 占싯띰옙 占쏙옙占� 
 	{
 	  if(pReviewResult->nLocation == DefectLoc_ASG || pReviewResult->nLocation == DefectLoc_PAD || pReviewResult->nLocation == DefectLoc_C2C)
 	  {
@@ -1337,12 +1337,12 @@
 		return ReviewResult_Process_Fail;
 	}
 
-	// Snap 시간 저장.
+	// Snap 占시곤옙 占쏙옙占쏙옙.
 	CTime snapTime = CTime::GetCurrentTime();
 	pReviewResult->strSnapTime.Format(_T("%04d%02d%02d%02d%02d%02d"), snapTime.GetYear(), snapTime.GetMonth(), snapTime.GetDay(), 
 		snapTime.GetHour(), snapTime.GetMinute(), snapTime.GetSecond());	// snap_time
 
-	// 리뷰 업로드 이미지 파일 이름 만들기
+	// 占쏙옙占쏙옙 占쏙옙占싸듸옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占싱몌옙 占쏙옙占쏙옙占�
 	CString strImageFileName = _T("");
 	if (MakeUserImageFileName(pReviewResult)==FALSE)
 	{
@@ -1355,7 +1355,7 @@
 		m_pRP2P->IRP2P_DisplayMessage(_T("[UserPlan] Memory Update Fail!! DefectIdx : %d"), pReviewResult->nDefectidx2);
 
 
-	//// 로컬 이미지 저장 파일 이름
+	//// 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占싱몌옙
 	//strImageFileName.Format(_T("ModuleIdx[%d]_PointIdx[%d]_Zoom[%d]"), pReviewResult->nModuleIdx, pReviewResult->nResultIdx, pReviewResult->nZoomIdx);
 	//pReviewResult->strImgFileName = strImageFileName;
 
@@ -1374,10 +1374,10 @@
 			UINT64 nSize = SaveReviewImage(&uploadImage, strPath, m_nReviewImageSize, m_nReviewImageQuality, m_nReviewImageStep);
 			m_pRP2P->IRP2P_DisplayMessage(_T("Upload Review Image Save Success! Size: %d byte"), nSize);
 
-			//uploadImage.SaveImage(strPath, 40);  // 화질 60% 150k
+			//uploadImage.SaveImage(strPath, 40);  // 화占쏙옙 60% 150k
 			if(GetReviewProcessStatus() == ReviewProcessStatus_UserStart)
 			{
-				// 업로드 이미지 경로 수정 20190917 chm
+				// 占쏙옙占싸듸옙 占싱뱄옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙 20190917 chm
 				//strPath.Format(_T("%s\\%s\\%s"), m_strSaveImageUploadPath, m_strGlassID, pReviewResult->strUploadImgFileName);
 				strPath.Format(_T("%s\\%s"), m_strSaveImageUploadPath, pReviewResult->strUploadImgFileName);
 				nSize = SaveReviewImage(&uploadImage, strPath, m_nReviewImageSize, m_nReviewImageQuality, m_nReviewImageStep);
@@ -1399,7 +1399,7 @@
 	const CRsRcpReviewInfo*  psRcpReviewInfo = m_pRP2P->IRP2P_Recipe_GetRsRcpReviewInfo();
 	if(psRcpReviewInfo== NULL) m_pRP2P->IRP2P_DisplayMessage(_T("RcpReviewInfo is NULL"));
 
-	if(psRcpReviewInfo->m_bDefocusUse) //190819chm 디포커스 알람 사용 
+	if(psRcpReviewInfo->m_bDefocusUse) //190819chm 占쏙옙占쏙옙커占쏙옙 占싯띰옙 占쏙옙占� 
 	{
 		if(pReviewResult->nLocation == DefectLoc_ASG || pReviewResult->nLocation == DefectLoc_PAD || pReviewResult->nLocation == DefectLoc_C2C)
 		{
@@ -1457,7 +1457,7 @@
 
 	int nTestMode = FALSE;
 	
-	//시뮬 돌릴려는 이미지 파일 선택 20190827 chm
+	//占시뱄옙 占쏙옙占쏙옙占쏙옙占쏙옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 20190827 chm
 	if(nTestMode){
 		Sleep(500);
 		CString strPathName;
@@ -1479,12 +1479,12 @@
 		return ReviewResult_Process_Fail;
 	}
 
-	// Snap 시간 저장.
+	// Snap 占시곤옙 占쏙옙占쏙옙.
 	CTime snapTime = CTime::GetCurrentTime();
 	pReviewResult->strSnapTime.Format(_T("%04d%02d%02d%02d%02d%02d"), snapTime.GetYear(), snapTime.GetMonth(), snapTime.GetDay(), 
 		snapTime.GetHour(), snapTime.GetMinute(), snapTime.GetSecond());	// snap_time
 
-	// 리뷰 업로드 이미지 파일 이름 만들기
+	// 占쏙옙占쏙옙 占쏙옙占싸듸옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占싱몌옙 占쏙옙占쏙옙占�
 	CString strImageFileName = _T("");
 	if (MakeReflowImageFileName(pReviewResult)==FALSE)
 	{
@@ -1500,8 +1500,8 @@
 	}
 
 
-	reflowParam reParam; //Reflow 연산 정보 
-	reflowResult reResult;//Reflow 결과 정보
+	reflowParam reParam; //Reflow 占쏙옙占쏙옙 占쏙옙占쏙옙 
+	reflowResult reResult;//Reflow 占쏙옙占� 占쏙옙占쏙옙
 
 	//////////////////////////////////////////////////////////////////////////////////////////////
 	BOOL btFlag =0;
@@ -1513,10 +1513,10 @@
 	CCHImageData tempImage;
 	tempImageOrigin.CopyImageFrom(pImageData);
 
-	if(pReviewResult->nReflow_Side==7) // 바텀 연산
+	if(pReviewResult->nReflow_Side==7) // 占쏙옙占쏙옙 占쏙옙占쏙옙
 	{
 		btFlag=1;
-		CCHImageProcess::ImageRotate(pImageData,&tempImage,135);//바텀 이미지를 Right 회전 시켜 Right 연산 실행 
+		CCHImageProcess::ImageRotate(pImageData,&tempImage,135);//占쏙옙占쏙옙 占싱뱄옙占쏙옙占쏙옙 Right 회占쏙옙 占쏙옙占쏙옙 Right 占쏙옙占쏙옙 占쏙옙占쏙옙 
 		pImageData = &tempImage;
 		//reParam.nImageWidth = 2048;
 		//reParam.nImageHeight = 2432;
@@ -1626,9 +1626,9 @@
 
 	CCHImageData tmepData2;
 	if(btFlag==1){
-		CCHImageProcess::ImageRotate(pImageData,&tmepData2,135);//Right 연산후 다시 이미지 돌리기
+		CCHImageProcess::ImageRotate(pImageData,&tmepData2,135);//Right 占쏙옙占쏙옙占쏙옙 占쌕쏙옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙占쏙옙
 		pImageData= &tmepData2;
-		//pImageData->SaveImage(_T("D:\\Testafter.bmp"));//Test 를 위한 bmp 저장
+		//pImageData->SaveImage(_T("D:\\Testafter.bmp"));//Test 占쏙옙 占쏙옙占쏙옙 bmp 占쏙옙占쏙옙
 	}
 
 
@@ -1653,17 +1653,17 @@
 			UINT64 nSize = SaveReviewImage(&uploadImage, strPath, m_nReviewImageSize, m_nReviewImageQuality, m_nReviewImageStep);
 			m_pRP2P->IRP2P_DisplayMessage(_T("Upload Review Image Save Success! Size: %d byte"), nSize);
 
-			//uploadImage.SaveImage(strPath, 40);  // 화질 60% 150k
+			//uploadImage.SaveImage(strPath, 40);  // 화占쏙옙 60% 150k
 			if(GetReviewProcessStatus() == ReviewProcessStatus_ReflowStart)
 			{
-				// 업로드 이미지 경로 수정 20190917 chm
+				// 占쏙옙占싸듸옙 占싱뱄옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙 20190917 chm
 				//strPath.Format(_T("%s\\%s\\%s"), m_strSaveImageUploadPath, m_strGlassID, pReviewResult->strUploadImgFileName);
 				strPath.Format(_T("%s\\%s"), m_strSaveImageUploadPath, pReviewResult->strUploadImgFileName);
 				nSize = SaveReviewImage(&uploadImage, strPath, m_nReviewImageSize, m_nReviewImageQuality, m_nReviewImageStep);
 
 				m_pRP2P->IRP2P_DisplayMessage(_T("Upload Reflow Image Save Success! Size: %d byte"), nSize);
 				
-				//시뮬돌리고 이미지 자동으로 열어줌 20190927chm
+				//占시뮬듸옙占쏙옙占쏙옙 占싱뱄옙占쏙옙 占쌘듸옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 20190927chm
 				if(nTestMode)
 				{
 					CString csParam;
@@ -1683,7 +1683,7 @@
 		m_pRP2P->IRP2P_DisplayMessage(_T("Upload Reflow Image Save Fail![%s]"), pReviewResult->strUploadImgFileName);
 	}
 
-	//공유메모리 업데이트
+	//占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙占쏙옙트
 	if(!UpdateMemoryReflowPlan(pReviewResult))
 		m_pRP2P->IRP2P_DisplayMessage(_T("[ReflowPlan] Memory Update Fail!! DefectIdx : %d"), pReviewResult->nDefectidx2);
 
@@ -1896,7 +1896,7 @@
 
 
 
-//파일명 181227 cmark
+//占쏙옙占싹몌옙 181227 cmark
 BOOL CReviewProcessor_CPJT::MakeReviewImageFileName(SReviewResult* pReviewResult)
 {
 	if (m_pRP2P==NULL || pReviewResult==NULL) return FALSE;
@@ -1909,7 +1909,7 @@
 
 	if(GetReviewProcessStatus() == ReviewProcessStatus_ReviewStart)
 	{
-		// [2017:6:5]-[WEZASW] : Review Image 파일명에 '*' 사용 금지.(예외처리)
+		// [2017:6:5]-[WEZASW] : Review Image 占쏙옙占싹몌옙占� '*' 占쏙옙占� 占쏙옙占쏙옙.(占쏙옙占쏙옙처占쏙옙)
 		if (pReviewResult->strDefectCode.Compare(_T("***")) == 0)
 			strDefectCodeTemp = _T("DC");	
 		else 
@@ -2000,23 +2000,24 @@
 		snapTime.GetHour(), snapTime.GetMinute(), snapTime.GetSecond());	// snap_time
 
 
-	// [2017:4:10]-[WEZASW] : 고객사 요청에 의한 bmp 파일 추가 저장. (임시사용)
+	// [2017:4:10]-[WEZASW] : 占쏙옙占쏙옙占� 占쏙옙청占쏙옙 占쏙옙占쏙옙 bmp 占쏙옙占쏙옙 占쌩곤옙 占쏙옙占쏙옙. (占쌈시삼옙占�)
 	pReviewResult->strOrignalImgFileName = strFileName + _T(".bmp");
 
 	strFileName += _T(".jpg");
 	pReviewResult->strUploadImgFileName = strFileName;
 	pReviewResult->strImgFileName = strFileName;
+	pReviewResult->strImgFilePath = GetReviewUploadImagePath();
 	return TRUE;
 }
 
 
 int	CReviewProcessor_CPJT::ProcessWSIReflow(int nThreadIdx, SReviewResult* pReviewResult)
 {
-	// [2016:11:15]-[WEZASW] : 점검 필요
+	// [2016:11:15]-[WEZASW] : 占쏙옙占쏙옙 占십울옙
 	if(!UpdateMemoryWsiReflowPlan(pReviewResult))
 		m_pRP2P->IRP2P_DisplayMessage(_T("[WsiReflowPlan] Memory Update Fail!! DefectIdx : %d"), pReviewResult->nDefectidx2);
 
-	// wsi용 return 값으로 수정 [6/20/2017 bhs]
+	// wsi占쏙옙 return 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 [6/20/2017 bhs]
 	return WsiResultSuccess;
 }
 
@@ -2060,7 +2061,7 @@
 	
 	if(GetReviewProcessStatus() == ReviewProcessStatus_UserStart)
 	{
-		// [2017:6:5]-[WEZASW] : Review Image 파일명에 '*' 사용 금지.(예외처리)
+		// [2017:6:5]-[WEZASW] : Review Image 占쏙옙占싹몌옙占� '*' 占쏙옙占� 占쏙옙占쏙옙.(占쏙옙占쏙옙처占쏙옙)
 		if (pReviewResult->strDefectCode.Compare(_T("***")) == 0)
 			strDefectCodeTemp = _T("DC");	
 		else 
@@ -2154,12 +2155,13 @@
 	// 		strFileName += pReviewResult->strSnapTime;
 	// 	}
 
-	// [2017:4:10]-[WEZASW] : 고객사 요청에 의한 bmp 파일 추가 저장. (임시사용)
+	// [2017:4:10]-[WEZASW] : 占쏙옙占쏙옙占� 占쏙옙청占쏙옙 占쏙옙占쏙옙 bmp 占쏙옙占쏙옙 占쌩곤옙 占쏙옙占쏙옙. (占쌈시삼옙占�)
 	pReviewResult->strOrignalImgFileName = strFileName + _T(".bmp");
 
 	strFileName += _T(".jpg");
 	pReviewResult->strUploadImgFileName = strFileName;
 	pReviewResult->strImgFileName = strFileName;
+	pReviewResult->strImgFilePath = GetReviewUploadImagePath();
 	return TRUE;
 }
 
@@ -2230,13 +2232,13 @@
 
 void CReviewProcessor_CPJT::LoadAoiImage(const CString& strGlassID, int nOpticType, int nPosX, int nPosY, CCHImageData* pAoiDark, CCHImageData *pAoiBright)
 {
-	// 3. 검사 결함 이미지 찾기
+	// 3. 占싯삼옙 占쏙옙占쏙옙 占싱뱄옙占쏙옙 찾占쏙옙
 	CString strAoiDarkPath = _T("");
 	CString strAoiBrightPath = _T("");
 
 	FindAoiDefectImagePath(strGlassID, nOpticType, nPosX, nPosY, strAoiDarkPath, strAoiBrightPath);
 
-	// Dark, Bright 모두 찾기 위해 주석처리 [2017.7.1 bhs]
+	// Dark, Bright 占쏙옙占� 찾占쏙옙 占쏙옙占쏙옙 占쌍쇽옙처占쏙옙 [2017.7.1 bhs]
 	// Dark image
 	//if(nOpticType & DEFECT_OPTIC_DARK)
 	{
@@ -2281,7 +2283,7 @@
 	CFileFind finder;
 	CString strSearchPath = _T("");
 
-	// Dark, Bright 모두 찾기 위해 주석처리 [2017.7.1 bhs]
+	// Dark, Bright 占쏙옙占� 찾占쏙옙 占쏙옙占쏙옙 占쌍쇽옙처占쏙옙 [2017.7.1 bhs]
 	//if (nOpticType & DEFECT_OPTIC_DARK)
 	{
 		// Dark field
@@ -2355,7 +2357,7 @@
 			processTimer.End();
 		}
 
-		// 4-3. 리뷰평균 밝기
+		// 4-3. 占쏙옙占쏙옙占쏙옙占� 占쏙옙占�
 		double dAverageGray = 0.0;
 		if (CCHImageProcess::ImageAverage(&bandImage, dAverageGray)==1)
 		{
@@ -2392,14 +2394,14 @@
 	CCHImageData pReviewCam;
 	CCHImageData tempImage1;
 	
-	// 설정값 이미지 회전
+	// 占쏙옙占쏙옙占쏙옙 占싱뱄옙占쏙옙 회占쏙옙
 	if (m_nImageRotate > 0)
 	{
 		tempImage1.CopyImageFrom(pReviewCamSource);
 		CCHImageProcess::ImageRotate(pReviewCamSource, &tempImage1, (90.0*m_nImageRotate));
 	}
 
-	// 설정값 이미지 반전
+	// 占쏙옙占쏙옙占쏙옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙
 	if (m_nimageFlip > 0)
 	{
 		if(m_nImageRotate > 0)
@@ -2436,7 +2438,7 @@
 
 	// set total size * scale
 	int nTotalWidth		= int(m_nReviewResizeWidth * m_dReviewImageScale + 0.5);
-	// 20170817 smok Dark, Bright 이미지가 리뷰 이미지 아래에 붙도록 수정
+	// 20170817 smok Dark, Bright 占싱뱄옙占쏙옙占쏙옙 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占싣뤄옙占쏙옙 占쌕듸옙占쏙옙 占쏙옙占쏙옙
 	int nTotalHeight	= int(m_nReviewResizeHeight * m_dReviewImageScale + 0.5 + max(pAoiDark2.GetHeight(), pAoiBright2.GetHeight()));
 	int nTotalHeight2	= int(m_nReviewResizeHeight * m_dReviewImageScale + 0.5);
 
@@ -2462,14 +2464,14 @@
 	double dRulerGab = 20.0 / m_dReviewImageScale;
 	double dScaleResolution = pReviewResult->dMeasureResolution / m_dReviewImageScale;
 
-	//DrawRuler(&memDC, nTotalWidth, nTotalHeight2, dScaleResolution, dRulerGab); // resolution, ruler gab //taek 210127 사용 X
+	//DrawRuler(&memDC, nTotalWidth, nTotalHeight2, dScaleResolution, dRulerGab); // resolution, ruler gab //taek 210127 占쏙옙占� X
 
 	// draw text string
 	DrawDefectInfo(&memDC, findResult, pReviewResult);
 	
 	//DrawAoiImage(&memDC, &pAoiDark2, &pAoiBright2, &pAoiDark2, &pAoiBright2, nAoiWidth, nAoiHeight);
 
-	// draw line 히팅 검증용
+	// draw line 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙
 	//DrawCenterLine(&memDC, nTotalWidth, nTotalHeight);
    // DrawCenterRect(&memDC, nTotalWidth, nTotalHeight, 100, 100, pReviewResult->dMeasureResolution);
 
@@ -2497,7 +2499,7 @@
 
 	nWidthDark = nHeightDark = nWidthBright = nHeightBright = 0;
 
-	// 20170817 smok Dark, Bright 이미지가 리뷰 이미지 아래에 붙도록 수정
+	// 20170817 smok Dark, Bright 占싱뱄옙占쏙옙占쏙옙 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占싣뤄옙占쏙옙 占쌕듸옙占쏙옙 占쏙옙占쏙옙
 	// dark
 	CCHImageData subImage;
 	if(pAoiDark!=NULL && pAoiDark->GetImageExist())
@@ -2578,11 +2580,11 @@
 	int nTotalWidth		= int(m_nReviewResizeWidth * m_dReviewImageScale + 0.5);
 	int nTotalHeight	= int(m_nReviewResizeHeight * m_dReviewImageScale + 0.5);
 
-	// Dark, Bright 이미지가 나란히 붙도록 수정, Dark 위, Bright 아래 - 고객사 요청[2017.6.30 bhs]
+	// Dark, Bright 占싱뱄옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쌕듸옙占쏙옙 占쏙옙占쏙옙, Dark 占쏙옙, Bright 占싣뤄옙 - 占쏙옙占쏙옙占� 占쏙옙청[2017.6.30 bhs]
 	//int nX = nTotalWidth - nWidth;
 	//int nY = nTotalHeight - (nHeight * 2);
 
-	// 20170817 smok Dark, Bright 이미지가 리뷰 이미지 아래에 붙도록 수정
+	// 20170817 smok Dark, Bright 占싱뱄옙占쏙옙占쏙옙 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占싣뤄옙占쏙옙 占쌕듸옙占쏙옙 占쏙옙占쏙옙
 	int nX = 0;
 	int nY = nTotalHeight;
 	pAoiDark1->ShowImage(pDC->m_hDC, nX, nY, pAoiDark1->GetWidth(), pAoiDark1->GetHeight(), 0, 0);
@@ -2590,7 +2592,7 @@
 	//pAoiDark1->ShowImage(pDC->m_hDC,	nTotalWidth - nWidth,	nTotalHei4ght-nHeight,	pAoiDark1->GetWidth(), pAoiDark1->GetHeight(), 0, 0);
 	//pAoiBright1->ShowImage(pDC->m_hDC,	nTotalWidth - nWidth,	nTotalHeight-nHeight,	pAoiBright1->GetWidth(), pAoiBright1->GetHeight(), 0, 0);
 
-	// 검사 이미지 중앙에 화살표 표시 - 고객사 요청 [2017.6.30 bhs]
+	// 占싯삼옙 占싱뱄옙占쏙옙 占쌩앙울옙 화占쏙옙표 표占쏙옙 - 占쏙옙占쏙옙占� 占쏙옙청 [2017.6.30 bhs]
 	CFont Font;
 	VERIFY(Font.CreateFont(
 		50,                        // nHeight
@@ -2611,7 +2613,7 @@
 	CFont *pOldFont = pDC->SelectObject(&Font);
 	pDC->SetTextColor(RGB(255,0,0));
 
-	CString strArrow = _T("↗");
+	CString strArrow = _T("占쏙옙");
 	CSize size = pDC->GetTextExtent(strArrow);
 	int nCenterX = nX + (nWidth / 2) - size.cx;
 	int nCenterY = nY + (nHeight / 2)/* + (size.cy / 2)*/;
@@ -2814,7 +2816,7 @@
 	else {
 		wchar_t  pstrPrefix[128] ={};
 
-		//Zone 넘버 210127
+		//Zone 占싼뱄옙 210127
 		int nValue = 0;
 		for (int i = 15; i >= 0; i--)
 		{
@@ -2825,8 +2827,8 @@
 		}
 
 		//taek 210127
-		//결과파일 좌표값 y 는 *-1을 하자
-		//설비 ID, 검사 카메라 정보, 검사 Camera 정보 : (? ) 캠 ?, Cell ID,	Review Cam 정보 : Gantry 정보,	검출 Size,	검출 Zone 정보,	Stak Flag, CODE 정보, 좌표 정보
+		//占쏙옙占쏙옙占쏙옙占� 占쏙옙표占쏙옙 y 占쏙옙 *-1占쏙옙 占쏙옙占쏙옙
+		//占쏙옙占쏙옙 ID, 占싯삼옙 카占쌨띰옙 占쏙옙占쏙옙, 占싯삼옙 Camera 占쏙옙占쏙옙 : (? ) 캠 ?, Cell ID,	Review Cam 占쏙옙占쏙옙 : Gantry 占쏙옙占쏙옙,	占쏙옙占쏙옙 Size,	占쏙옙占쏙옙 Zone 占쏙옙占쏙옙,	Stak Flag, CODE 占쏙옙占쏙옙, 占쏙옙표 占쏙옙占쏙옙
 		
 		// PPID
 // 		strValue.Format(_T("Tool[%s].Recipe[%s].ScanNo[%d/%d].Time[%4d/%2d/%2d_%d:%d:%d].MaxGray[%d].RefGray[%d].REVCnt[%d]"),pReviewResult->strEquipID,pGlassResult->m_strPPID,pReviewResult->nAOIScanIdx,0,snapTime.GetYear(), snapTime.GetMonth(), snapTime.GetDay(),
@@ -3041,7 +3043,7 @@
 
 	if(GetReviewProcessStatus() == ReviewProcessStatus_ReflowStart)
 	{
-		// [2017:6:5]-[WEZASW] : Review Image 파일명에 '*' 사용 금지.(예외처리)
+		// [2017:6:5]-[WEZASW] : Review Image 占쏙옙占싹몌옙占� '*' 占쏙옙占� 占쏙옙占쏙옙.(占쏙옙占쏙옙처占쏙옙)
 		if (pReviewResult->strDefectCode.Compare(_T("***")) == 0)
 			strDefectCodeTemp = _T("DC");	
 		else 
@@ -3118,7 +3120,7 @@
 	// 		strFileName += pReviewResult->strSnapTime;
 	// 	}
 
-	// [2017:4:10]-[WEZASW] : 고객사 요청에 의한 bmp 파일 추가 저장. (임시사용)
+	// [2017:4:10]-[WEZASW] : 占쏙옙占쏙옙占� 占쏙옙청占쏙옙 占쏙옙占쏙옙 bmp 占쏙옙占쏙옙 占쌩곤옙 占쏙옙占쏙옙. (占쌈시삼옙占�)
 	pReviewResult->strOrignalImgFileName = strFileName + _T(".bmp");
 
 	strFileName += _T(".jpg");
@@ -3164,7 +3166,7 @@
 	int nStartResultIdx	= pReviewResult->GetStartSReviewResultIndex();
 	int nEndResultIdx	= pReviewResult->GetEndSReviewResultIndex();
 
-	// 인덱스가 현재 마지막 인덱스 보다 클시..
+	// 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙 占쏙옙占쏙옙 클占쏙옙..
 	if (nCurResultIdx > nEndResultIdx)  
 	{
 		LeaveCriticalSection(&m_csUserCriticalSection);
@@ -3172,7 +3174,7 @@
 		g_pLog->DisplayMessage(_T("[ReviewProcessor]SetWsiResultData module[%d] point[%d] result[%d]"), nModuleIndex, measureResut.nResultIndex, nCurResultIdx);
 	}
 
-	// 현재 결과데이터 저장
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙
 	wsiResult.nWsi_ResultCode		= measureResut.nResultCode;
 	wsiResult.dWsi_DamDistance		= measureResut.dDamDistance;
 
@@ -3182,7 +3184,7 @@
 	}
 	//memcpy(wsiResult.nWsi_pReflowResultData, measureResut.pReflowResultData, sizeof(wsiResult.nWsi_pReflowResultData));
 	
-	// 결과 데이터 추가
+	// 占쏙옙占� 占쏙옙占쏙옙占쏙옙 占쌩곤옙
 	SReviewResult *pProcessResult = NULL;
 	if (pGlassResult->SetWsiReflowResultData(nModuleIndex, nCurResultIdx, wsiResult, nGlassPosX, nGlassPosY, nMotorPosX, nMotorPosY, dTime))
 	{
@@ -3191,10 +3193,10 @@
 		pProcessResult = pReviewResult->GetSReviewResult(nCurResultIdx);
 	}
 
-	// 저장 성공시, 리뷰 프로세서에 포인터 전달
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙, 占쏙옙占쏙옙 占쏙옙占싸쇽옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	if (pProcessResult)
 	{
-		// 처리 쓰레드 수행
+		// 처占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 		if (AddReviewProcessData(pProcessResult)==1)
 		{
 			g_pLog->DisplayMessage(_T("[ReviewProcessor]Add Wsi Reflow Process Data module[%d] result[%d]"), nModuleIndex, nCurResultIdx);
@@ -3210,7 +3212,7 @@
 
 	LeaveCriticalSection(&m_csUserCriticalSection);
 
-	// 결과 갱신.
+	// 占쏙옙占� 占쏙옙占쏙옙.
 	m_pRP2P->IRP2P_UpdateReviewResult(nModuleIndex, pGlassResult, 5);
 	return;
 
@@ -3219,7 +3221,7 @@
 	return;
 }
 
-//0129cmark 원점 위치별 센터 좌표를 원점 좌표로 변형 
+//0129cmark 占쏙옙占쏙옙 占쏙옙치占쏙옙 占쏙옙占쏙옙 占쏙옙표占쏙옙 占쏙옙占쏙옙 占쏙옙표占쏙옙 占쏙옙占쏙옙 
 double CReviewProcessor_CPJT::GetCentertoOrginCoordinate(double dPosX,double dPosY,int nCornercut,int nOriginDirection){
 
 	double nResultPosX=0.0;
@@ -3228,60 +3230,60 @@
 	// CornerCutDirection	{ CLeftTop=0, CRightTop, CLeftBottom,   CRightBottom };
 	// OriginDirection	{ OLeftTop=0, ORightTop, OLeftBottom,   ORightBottom };
 
-	if(nOriginDirection==RPOLeftTop){//오리진좌상
+	if(nOriginDirection==RPOLeftTop){//占쏙옙占쏙옙占쏙옙占승삼옙
 
-		if(nCornercut == RPCLeftTop)//좌상 
+		if(nCornercut == RPCLeftTop)//占승삼옙 
 		{ 
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. - dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. - dPosY;
 
 		}
-		else if(nCornercut == RPCRightTop)//우상
+		else if(nCornercut == RPCRightTop)//占쏙옙占�
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. - dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. + dPosY;
 
 		}
-		else if(nCornercut == RPCLeftBottom)//좌하
+		else if(nCornercut == RPCLeftBottom)//占쏙옙占쏙옙
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. - dPosY;
 		}
-		else if(nCornercut == RPCRightBottom)//우하
+		else if(nCornercut == RPCRightBottom)//占쏙옙占쏙옙
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2 + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2 + dPosY;
 		}
 	}
 
-	else if(nOriginDirection==RPORightTop){//오리진우상
+	else if(nOriginDirection==RPORightTop){//占쏙옙占쏙옙占쏙옙占쏙옙占�
 
-		if(nCornercut == RPCLeftTop)//좌상 
+		if(nCornercut == RPCLeftTop)//占승삼옙 
 		{ 
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. - dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. + dPosY;
 
 		}
-		else if(nCornercut == RPCRightTop)//우상
+		else if(nCornercut == RPCRightTop)//占쏙옙占�
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. - dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. - dPosY;
 
 		}
-		else if(nCornercut == RPCLeftBottom)//좌하
+		else if(nCornercut == RPCLeftBottom)//占쏙옙占쏙옙
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. + dPosY;
 		}
-		else if(nCornercut == RPCRightBottom)//우하
+		else if(nCornercut == RPCRightBottom)//占쏙옙占쏙옙
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. - dPosY;
 		}
 	}
-	else if(nOriginDirection==RPOLeftBottom){//오리진좌하
+	else if(nOriginDirection==RPOLeftBottom){//占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙
 
-		if(nCornercut == RPCLeftTop)//좌상 
+		if(nCornercut == RPCLeftTop)//占승삼옙 
 		{ 
 			//210402
 		/*	nResultPosX = double(GLASS_SIZE_WIDTH)/2. + dPosX;
@@ -3290,13 +3292,13 @@
 			nResultPosX = double(GLASS_SIZE_WIDTH) / 2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT) / 2. + dPosY;
 		}
-		else if(nCornercut == RPCRightTop)//우상
+		else if(nCornercut == RPCRightTop)//占쏙옙占�
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. + dPosY;
 
 		}
-		else if(nCornercut == RPCLeftBottom)//좌하
+		else if(nCornercut == RPCLeftBottom)//占쏙옙占쏙옙
 		{
 			//210402
 			/*nResultPosX = double(GLASS_SIZE_WIDTH)/2. - dPosX;
@@ -3304,33 +3306,33 @@
 			nResultPosX = double(GLASS_SIZE_WIDTH) / 2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT) / 2. + dPosY;
 		}
-		else if(nCornercut == RPCRightBottom)//우하
+		else if(nCornercut == RPCRightBottom)//占쏙옙占쏙옙
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH) / 2. - dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT) / 2. + dPosY;
 		}
 	}
 	else if (nOriginDirection==RPORightBottom)
-	{//오리진우하
+	{//占쏙옙占쏙옙占쏙옙占쏙옙占쏙옙
 
-		if(nCornercut == RPCLeftTop)//좌상 
+		if(nCornercut == RPCLeftTop)//占승삼옙 
 		{ 
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. + dPosY;
 
 		}
-		else if(nCornercut == RPCRightTop)//우상
+		else if(nCornercut == RPCRightTop)//占쏙옙占�
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. + dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. - dPosY;
 
 		}
-		else if(nCornercut == RPCLeftBottom)//좌하
+		else if(nCornercut == RPCLeftBottom)//占쏙옙占쏙옙
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. - dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. + dPosY;
 		}
-		else if(nCornercut == RPCRightBottom)//우하
+		else if(nCornercut == RPCRightBottom)//占쏙옙占쏙옙
 		{
 			nResultPosX = double(GLASS_SIZE_WIDTH)/2. - dPosX;
 			nResultPosY = double(GLASS_SIZE_HEIGHT)/2. - dPosY;
@@ -3355,7 +3357,7 @@
 	CString strFileName = _T("");
 	CString strDefectCodeTemp = _T("");
 
-	// [2017:6:5]-[WEZASW] : Review Image 파일명에 '*' 사용 금지.(예외처리)
+	// [2017:6:5]-[WEZASW] : Review Image 占쏙옙占싹몌옙占� '*' 占쏙옙占� 占쏙옙占쏙옙.(占쏙옙占쏙옙처占쏙옙)
 	if (pReviewResult->strDefectCode.Compare(_T("***")) == 0)
 		strDefectCodeTemp = _T("DC");	
 	else 
@@ -3419,24 +3421,31 @@
 {
 	if(pReviewResult == NULL)	return FALSE;
 
-	//결과파일 공유 메모리 리뷰 이미지 이름 및 좌표 채워주기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨몌옙 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占싱몌옙 占쏙옙 占쏙옙표 채占쏙옙占쌍깍옙
 	CDitGlassRawClient *pDitGlassRawCleint = CDitGlassRawClient::GetInstance();
 	if(pDitGlassRawCleint->isConnect() == TRUE)
 	{
 		
 		_grmDefectData* pSharedDefect = pDitGlassRawCleint->GetDefectData(pReviewResult->nDefectidx2);
 		_grmDefectReviewData * pSharedDefectReview = &pSharedDefect->m_ReviewDefect;
+		_grmGlassData* pSharedGlassData = pDitGlassRawCleint->GetGlassData();
 		
 		//size_t CharactersConverted;
 		//wcstombs_s(&CharactersConverted, pSharedDefectReview->m_strRevImageName, pReviewResult->strImgFileName, _TRUNCATE);
 
 		strcpy(pSharedDefectReview->m_strRevImageName,pReviewResult->strImgFileName.MakeLower());
 		
+		//taek 210624 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙 占쏙옙占쌔댐옙.
 
-		pSharedDefectReview->m_nPlanType =  ditRaw::RPT_Review;	//0:None, 1:Location(User, Fiexed) Review, 4:reflower, ??:Wsi, 1000:AOI(외부 로컬 리뷰 명령)			
+		strcpy(pSharedDefectReview->m_strRevImagePath,pReviewResult->strImgFilePath.MakeLower());
+
+		strcpy(pSharedGlassData->m_strAlignFirst, m_strReviewFirst.MakeLower());
+		strcpy(pSharedGlassData->m_strAlignSecond, m_strReviewSecned.MakeLower());
+
+		pSharedDefectReview->m_nPlanType =  ditRaw::RPT_Review;	//0:None, 1:Location(User, Fiexed) Review, 4:reflower, ??:Wsi, 1000:AOI(占쌤븝옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占�)			
 		pSharedDefectReview->m_nResultCode = 1;  //0:None, 1:Success
 		pSharedDefectReview->m_nShotIndex = pReviewResult->nResultIdx; 
-		//pSharedDefectReview->m_nShotIndex = GetPlanReviewCount(); //RTMS 기준에 따라 통합 관리면 요거 아니면 나눠서 하는 걸로 taek 210128
+		//pSharedDefectReview->m_nShotIndex = GetPlanReviewCount(); //RTMS 占쏙옙占쌔울옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占� 占싣니몌옙 占쏙옙占쏙옙占쏙옙 占싹댐옙 占심뤄옙 taek 210128
 		pSharedDefectReview->m_nModuleIndex = pReviewResult->nModuleIdx;
 		pSharedDefectReview->m_nMagnificIndex = 20;
 		pSharedDefectReview->m_fManification =pReviewResult->dMagnification;
@@ -3450,11 +3459,11 @@
 
 BOOL CReviewProcessor_CPJT::UpdateMemoryUserPlan( SReviewResult* pReviewResult )
 {
-	//결과파일 공유 메모리 리뷰 이미지 이름 및 좌표 채워주기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨몌옙 占쏙옙占쏙옙 占싱뱄옙占쏙옙 占싱몌옙 占쏙옙 占쏙옙표 채占쏙옙占쌍깍옙
 	CDitGlassRawClient *pDitRawClient = CDitGlassRawClient::GetInstance();
 	if(pDitRawClient->isConnect() == TRUE)
 	{
-		int nDefectCount = pDitRawClient->GetGlassData()->m_nDefectNum; // user,reflow 는 검사 디펙 이후 생성되기에 디펙 카운트보다 같거나 큰값을 가지고 있다
+		int nDefectCount = pDitRawClient->GetGlassData()->m_nDefectNum; // user,reflow 占쏙옙 占싯삼옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占실기에 占쏙옙占쏙옙 카占쏙옙트占쏙옙占쏙옙 占쏙옙占신놂옙 큰占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쌍댐옙
 		if(pReviewResult->nDefectIdx <nDefectCount)
 		{	
 			return FALSE;
@@ -3467,14 +3476,16 @@
 		
 		strcpy(pSharedDefectReview->m_strRevImageName,pReviewResult->strImgFileName);
 	
-		pSharedDefectReview->m_nPlanType = ditRaw::RPT_User;	//0:None, 1:Location(User, Fiexed) Review, 4:reflower, ??:Wsi, 1000:AOI(외부 로컬 리뷰 명령)			
+		pSharedDefectReview->m_nPlanType = ditRaw::RPT_User;	//0:None, 1:Location(User, Fiexed) Review, 4:reflower, ??:Wsi, 1000:AOI(占쌤븝옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占�)			
 		pSharedDefectReview->m_nResultCode = 1;  //0:None, 1:Success
 		pSharedDefectReview->m_nShotIndex = pReviewResult->nResultIdx; 
+		pSharedDefect->m_nShotIdx = pReviewResult->nResultIdx;
 		pSharedDefectReview->m_nModuleIndex;
+		pSharedDefect->m_nModelIdx = pReviewResult->nModuleIdx;
 		pSharedDefectReview->m_nMagnificIndex = pReviewResult->dMagnification;
 		pSharedDefectReview->m_fManification = pReviewResult->dMagnification;
 		pSharedDefectReview->m_fManificResoultion = pReviewResult->dMagnification;
-			m_pRP2P->IRP2P_DisplayMessage(_T("[공유메모리접근]인덱스[%d]파일명[%s]"),pReviewResult->nDefectidx2, pReviewResult->strUploadImgFileName);
+			m_pRP2P->IRP2P_DisplayMessage(_T("[占쏙옙占쏙옙占쌨몌옙占쏙옙占쏙옙]占싸듸옙占쏙옙[%d]占쏙옙占싹몌옙[%s]"),pReviewResult->nDefectidx2, pReviewResult->strUploadImgFileName);
 	}
 
 
@@ -3484,7 +3495,7 @@
 BOOL CReviewProcessor_CPJT::UpdateMemoryReflowPlan( SReviewResult* pReviewResult )
 {
 	if(pReviewResult == NULL)	return FALSE;
-	//결과파일 공유 메모리에 결과 채워 넣기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨모리울옙 占쏙옙占� 채占쏙옙 占쌍깍옙
 	CDitGlassRawClient *pDitRawClient = CDitGlassRawClient::GetInstance();
 	//int nEqpID = m_pSP2P->ISP2P_System_GetSystemInfo()->m_nMachineType;
 	CString strCellID = _T("");
@@ -3506,7 +3517,7 @@
 				nReflowjuge=1;
 			}
 
-			// 고객사 요청으로 수정함. 0,1 Position은 Pass
+			// 占쏙옙占쏙옙占� 占쏙옙청占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙. 0,1 Position占쏙옙 Pass
 			else if(nReflowjuge == 3 || nReflowjuge == 2)
 			{
 				m_pRP2P->IRP2P_DisplayMessage(_T("[ReflowResult] Reflow Judge Is No OverFlow %d"),nReflowjuge);
@@ -3525,7 +3536,7 @@
 				nReflowjuge=0;
 			}
 			
-			//0:None, // 검출한 Line의 개수. 3 미만 : DAM2 Reflow 판정, 4~5 : DAM1 Reflow 판정, 6 : no Reflow 판정 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
+			//0:None, // 占쏙옙占쏙옙占쏙옙 Line占쏙옙 占쏙옙占쏙옙. 3 占싱몌옙 : DAM2 Reflow 占쏙옙占쏙옙, 4~5 : DAM1 Reflow 占쏙옙占쏙옙, 6 : no Reflow 占쏙옙占쏙옙 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
 			if(pReviewResult->nReflow_CellIndex > 7)
 			{
 				pReviewResult->nReflow_CellIndex = 0;
@@ -3542,7 +3553,7 @@
 
 	if(pDitRawClient->isConnect() == TRUE)
 	{
-		int nDefectCount = pDitRawClient->GetGlassData()->m_nDefectNum; // user,reflow 는 검사 디펙 이후 생성되기에 디펙 카운트보다 같거나 큰값을 가지고 있다
+		int nDefectCount = pDitRawClient->GetGlassData()->m_nDefectNum; // user,reflow 占쏙옙 占싯삼옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占실기에 占쏙옙占쏙옙 카占쏙옙트占쏙옙占쏙옙 占쏙옙占신놂옙 큰占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쌍댐옙
 		if(pReviewResult->nDefectidx2 <nDefectCount)
 		{
 			return FALSE;
@@ -3557,11 +3568,11 @@
 
 		pSharedDefectReview->m_nPlanType =  ditRaw::RTP_Reflow;			
 		pSharedDefectReview->m_nReflow_ResultCode = pReviewResult->nReflow_Result;// pReviewResult->nReflow_Result;  
-		//0:None, // 검출한 Line의 개수. 3 미만 : DAM2 Reflow 판정, 4~5 : DAM1 Reflow 판정, 6 : no Reflow 판정 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
+		//0:None, // 占쏙옙占쏙옙占쏙옙 Line占쏙옙 占쏙옙占쏙옙. 3 占싱몌옙 : DAM2 Reflow 占쏙옙占쏙옙, 4~5 : DAM1 Reflow 占쏙옙占쏙옙, 6 : no Reflow 占쏙옙占쏙옙 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
 		//pSharedDefectReview->m_fReflow_LinePosData;	
 		pSharedDefectReview->m_nReflow_Side = pReviewResult->nReflow_Side;
 		pSharedDefectReview->m_nReflow_InspectionMode = 0;
-		m_pRP2P->IRP2P_DisplayMessage(_T("[공유메모리접근]인덱스[%d]파일명[%s]"),pReviewResult->nDefectidx2, pReviewResult->strUploadImgFileName);
+		m_pRP2P->IRP2P_DisplayMessage(_T("[占쏙옙占쏙옙占쌨몌옙占쏙옙占쏙옙]占싸듸옙占쏙옙[%d]占쏙옙占싹몌옙[%s]"),pReviewResult->nDefectidx2, pReviewResult->strUploadImgFileName);
 	}
 	
 	return TRUE;
@@ -3571,7 +3582,7 @@
 {
 	if(pReviewResult == NULL)	return FALSE;
 
-	//결과파일 공유 메모리에 결과 채워 넣기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨모리울옙 占쏙옙占� 채占쏙옙 占쌍깍옙
 	CDitGlassRawClient *pDitGlassRawClient = CDitGlassRawClient::GetInstance();
 
 	if(pDitGlassRawClient->isConnect() == TRUE)
@@ -3588,7 +3599,7 @@
 
 		pSharedDefectReview->m_nPlanType =  ditRaw::RTP_WSI;			
 		pSharedDefectReview->m_nWsi_ResultCode=pReviewResult->nWsi_ResultCode; //0:None, 1:Success
-		pSharedDefectReview->m_nWsi_Type = 2;/* nWSIType;									// 함몰 / 돌기 //wsi 진행 */
+		pSharedDefectReview->m_nWsi_Type = 2;/* nWSIType;									// 占쌉몌옙 / 占쏙옙占쏙옙 //wsi 占쏙옙占쏙옙 */
 		pSharedDefectReview->m_fWsi_ResultData[0]= pReviewResult->nWsi_DefectType; // 0:normal 1:metal 2:huge 3:diffuse 4:trashy
 		pSharedDefectReview->m_fWsi_ResultData[1]=(float)(nWSIheight/1000.0); 
 		pSharedDefectReview->m_fWsi_ResultData[2]=(float)(nWSIWidth/1000.0);			// 0:Type, 1:Height, 2:Width
@@ -3598,7 +3609,7 @@
 		pSharedDefectReview->m_fWsi_ResultData[6] = pReviewResult->dBZoneHeight;
 		pSharedDefectReview->m_strWsi_2DImageFilename;
 		pSharedDefectReview->m_strWsi_3DImageFilename;
-		pSharedDefectReview->m_fWsiManification = 20;//20배 고정
+		pSharedDefectReview->m_fWsiManification = 20;//20占쏙옙 占쏙옙占쏙옙
 		pSharedDefectReview->m_dWsiMmMotorX=pReviewResult->dTargetMotorX;
 		pSharedDefectReview->m_dWsiMmMotorY=pReviewResult->dTargetMotorY;
 		
@@ -3613,7 +3624,7 @@
 BOOL CReviewProcessor_CPJT::UpdateMemoryWsiReflowPlan( SReviewResult* pReviewResult )
 {
 	if(pReviewResult == NULL)	return FALSE;
-	//결과파일 공유 메모리에 결과 채워 넣기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨모리울옙 占쏙옙占� 채占쏙옙 占쌍깍옙
 	CDitGlassRawClient *pDitRawClient = CDitGlassRawClient::GetInstance();
 	
 
@@ -3627,13 +3638,13 @@
 
 	/*
 	pPacket->GetInt(0)			= Index
-	pPacket->GetInt(1)			= Wsi 측정 결과
-	pPacket->GetInt(2)			= A존 판정 결과 (1 성공 0 실패)
-	pPacket->GetInt(3)          = B존 판정 결과
-	pPacket->GetInt(4)          = C존 판정 결과
-	pPacket->GetInt(5)          = D존 판정 결과
-	pPacket->GetInt(6)          = Review에서 보내줬던 PointIndex
-	pPacket->GetDouble(0)       = 댐에서 Monomo까지의 거리
+	pPacket->GetInt(1)			= Wsi 占쏙옙占쏙옙 占쏙옙占�
+	pPacket->GetInt(2)			= A占쏙옙 占쏙옙占쏙옙 占쏙옙占� (1 占쏙옙占쏙옙 0 占쏙옙占쏙옙)
+	pPacket->GetInt(3)          = B占쏙옙 占쏙옙占쏙옙 占쏙옙占�
+	pPacket->GetInt(4)          = C占쏙옙 占쏙옙占쏙옙 占쏙옙占�
+	pPacket->GetInt(5)          = D占쏙옙 占쏙옙占쏙옙 占쏙옙占�
+	pPacket->GetInt(6)          = Review占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占� PointIndex
+	pPacket->GetDouble(0)       = 占쏙에占쏙옙 Monomo占쏙옙占쏙옙占쏙옙 占신몌옙
 	*/
 	
 // 	int nReflowjuge=0;
@@ -3644,7 +3655,7 @@
 	
 	nWsiReflowJudge  = pReviewResult->nWsi_ResultCode;
 
-	//nWsiReflowResult += pReviewResult->nWsi_pReflowResultData[0] //A 1차 신경안씀 
+	//nWsiReflowResult += pReviewResult->nWsi_pReflowResultData[0] //A 1占쏙옙 占신곤옙횡占� 
 	nWsiReflowResult += pReviewResult->nWsi_pReflowResultData[1];//B
 	nWsiReflowResult += pReviewResult->nWsi_pReflowResultData[2];//C
 	//nWsiReflowResult += pReviewResult->nWsi_pReflowResultData[3];//D
@@ -3704,7 +3715,7 @@
 {
 	if(pReviewResult == NULL)	return FALSE;
 
-	//결과파일 공유 메모리에 결과 채워 넣기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨모리울옙 占쏙옙占� 채占쏙옙 占쌍깍옙
 	CDitGlassRawClient *pDitGlassRawClient = CDitGlassRawClient::GetInstance();
 
 	if(pDitGlassRawClient->isConnect() == TRUE)
@@ -3721,13 +3732,13 @@
 
 		pSharedDefectReview->m_nPlanType =  ditRaw::RTP_UserWsi;			
 		pSharedDefectReview->m_nWsi_ResultCode=pReviewResult->nWsi_ResultCode; //0:None, 1:Success
-		pSharedDefectReview->m_nWsi_Type=nWSIType;									// 함몰 / 돌기
+		pSharedDefectReview->m_nWsi_Type=nWSIType;									// 占쌉몌옙 / 占쏙옙占쏙옙
 		pSharedDefectReview->m_fWsi_ResultData[0]= nWSIType;
 		pSharedDefectReview->m_fWsi_ResultData[1]=(float)(nWSIheight/100.0);
 		pSharedDefectReview->m_fWsi_ResultData[2]=(float)(nWSIWidth/100.0);			// 0:Type, 1:Height, 2:Width
 		pSharedDefectReview->m_strWsi_2DImageFilename;
 		pSharedDefectReview->m_strWsi_3DImageFilename;
-		pSharedDefectReview->m_fWsiManification = 20;//20배 고정
+		pSharedDefectReview->m_fWsiManification = 20;//20占쏙옙 占쏙옙占쏙옙
 		pSharedDefectReview->m_dWsiMmMotorX=pReviewResult->dTargetMotorX;
 		pSharedDefectReview->m_dWsiMmMotorY=pReviewResult->dTargetMotorY;
 	}
@@ -3739,7 +3750,7 @@
 {
 	if (pReviewResult == NULL)	return FALSE;
 
-	//결과파일 공유 메모리에 결과 채워 넣기
+	//占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쌨모리울옙 占쏙옙占� 채占쏙옙 占쌍깍옙
 	CDitGlassRawClient *pDitGlassRawClient = CDitGlassRawClient::GetInstance();
 
 	if (pDitGlassRawClient->isConnect() == TRUE)
@@ -3756,13 +3767,13 @@
 
 		pSharedDefectReview->m_nPlanType = ditRaw::RTP_WSI;
 		pSharedDefectReview->m_nWsi_ResultCode = pReviewResult->nWsi_ResultCode; //0:None, 1:Success
-		pSharedDefectReview->m_nWsi_Type = nWSIType;									// 함몰 / 돌기
+		pSharedDefectReview->m_nWsi_Type = nWSIType;									// 占쌉몌옙 / 占쏙옙占쏙옙
 		pSharedDefectReview->m_fWsi_ResultData[0] = nWSIType;
 		pSharedDefectReview->m_fWsi_ResultData[1] = (float)(nWSIheight / 100.0);
 		pSharedDefectReview->m_fWsi_ResultData[2] = (float)(nWSIWidth / 100.0);			// 0:Type, 1:Height, 2:Width
 		pSharedDefectReview->m_strWsi_2DImageFilename;
 		pSharedDefectReview->m_strWsi_3DImageFilename;
-		pSharedDefectReview->m_fWsiManification = 20;//20배 고정
+		pSharedDefectReview->m_fWsiManification = 20;//20占쏙옙 占쏙옙占쏙옙
 		pSharedDefectReview->m_dWsiMmMotorX = pReviewResult->dTargetMotorX;
 		pSharedDefectReview->m_dWsiMmMotorY = pReviewResult->dTargetMotorY;
 
@@ -3793,7 +3804,7 @@
 	double TempValue = 0;
 	double m_nResultFocusValue = 0;
 
-	// 원점 XY 기준 X+1, Y+1에 대한 차영상
+	// 占쏙옙占쏙옙 XY 占쏙옙占쏙옙 X+1, Y+1占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙
 	for (int y = 0; y < nHeight - 1; y++)
 	{
 		for (int x = 0; x < nWidth - 1; x++)
diff --git a/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.h b/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.h
index c54f269..6f456d3 100644
--- a/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.h
+++ b/ReviewSystem/ReviewSystem/ReviewProcessor_CPJT.h
@@ -108,6 +108,9 @@
 
 	CMotorControlInfo* m_MotorControlInfo;
 
+	CString m_strReviewFirst;
+	CString m_strReviewSecned;
+
 protected:
 	CString				ErrorStringCode[ErrorCount];
 };
\ No newline at end of file
diff --git a/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp b/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp
index 613e945..8751217 100644
--- a/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp
+++ b/ReviewSystem/ReviewSystem/SequenceProcessor_CPJT.cpp
@@ -51,7 +51,7 @@
 #define AOIRAWBIN_NETWORK_DRIVE_PATH	"Y:\\RawBin"
 
 enum CPJT_MeasureMode { CPJT_ModeAuto = 0, CPJT_ModeManual };
-// [2017:4:18]-[WEZASW] : WSI Module 장착 설비의 경우 PlanType 번호 변경.
+// [2017:4:18]-[WEZASW] : WSI Module 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占� PlanType 占쏙옙호 占쏙옙占쏙옙.
 enum CPJT_PlanType { CPJT_PlanReview = 0, CPJT_PlanUser, CPJT_PlanWSI, CPJT_PlanMeasure, CPJT_PlanReflow, CPJT_PlanWsiReflow, CPJT_PlanWsiUser,CPJT_PlanWsiMultiShot
 };
 enum CPJT_InsepectionType{REVIEW_REFLOW = 0, WSI_REFLOW, REV_WSI,WSIUSER, USER,WSIMULTISHOT};
@@ -169,7 +169,7 @@
 	CDitGlassRawClient* pDitGlassRaw = CDitGlassRawClient::GetInstance();
 	if(pDitGlassRaw->ConnectServer() == FALSE)
 	{
-		g_pLog->DisplayMessage(_T("공유메모리 접근 실패!(Shared memory Access Fail)"));
+		g_pLog->DisplayMessage(_T("占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙 占쏙옙占쏙옙!(Shared memory Access Fail)"));
 	}
 }
     
@@ -184,16 +184,16 @@
 	
 	BOOL bReturn = FALSE;
 
-	// 현재 상태가 이전 상태와 다른가?
+	// 占쏙옙占쏙옙 占쏙옙占승곤옙 占쏙옙占쏙옙 占쏙옙占승울옙 占쌕몌옙占쏙옙?
 	
 	//if (nProcessStatus!=m_nProcessStatus || nProcessStatus==0)
 	if (1)//nProcessStatus!=m_nProcessStatus || nProcessStatus==0)
 	{
-		//if (nProcessStatus==0) // 초기(0) 상태이면..
+		//if (nProcessStatus==0) // 占십깍옙(0) 占쏙옙占쏙옙占싱몌옙..
 		//{
 		//	bReturn = TRUE;
 		//}
-		//	else if (nProcessStatus==(m_nProcessStatus+1)) // 이전 상태 다음(+1)이면..	
+		//	else if (nProcessStatus==(m_nProcessStatus+1)) // 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙(+1)占싱몌옙..	
 		//	{
 		//		bReturn = TRUE;
 		//	}
@@ -204,9 +204,9 @@
 		//	bReturn = FALSE;
 		//}
 		
-		if (bReturn) // 수행이면...
+		if (bReturn) // 占쏙옙占쏙옙占싱몌옙...
 		{
-			// Thread 생성 후 Thread 수행
+			// Thread 占쏙옙占쏙옙 占쏙옙 Thread 占쏙옙占쏙옙
 			CSequenceProcessData* pThreadData = new CSequenceProcessData(this);
 			if (pThreadData)
 			{
@@ -227,7 +227,7 @@
 			}
 		}
 		else if(nProcessStatus==2){
-			// Thread 생성 후 Thread 수행
+			// Thread 占쏙옙占쏙옙 占쏙옙 Thread 占쏙옙占쏙옙
 			CSequenceProcessData* pThreadData = new CSequenceProcessData(this);
 			if (pThreadData)
 			{
@@ -277,7 +277,7 @@
 	CReviewResult* pWsiResult = pGlassResult->GetWsiResult(nModuleIndex);
 	if (pWsiResult==NULL) goto RESULT_FAIL;
 
-	// 마지막 인덱스를 가져온다.
+	// 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙占승댐옙.
 	int nCurResultIdx	= pWsiResult->GetLastSReviewResultIndex() + 1; // last index + 1
 	int nStartResultIdx	= pWsiResult->GetStartSReviewResultIndex();
 	int nEndResultIdx	= pWsiResult->GetEndSReviewResultIndex();
@@ -291,13 +291,13 @@
 	int		nMPosY	= int(pPosition->dMotorPosY * 1000.0);
 	double	dTime	= (double) m_ProcessTimer.GetDurationMilliSecond();
 
-	// 인덱스가 다르면 비정상임.
+	// 占싸듸옙占쏙옙占쏙옙 占쌕몌옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
 	if (measureResut.nResultIndex != nCurResultIdx) 
 	{
 		goto RESULT_FAIL;
 	}
 
-	// 현재 데이터 저장.
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙.
 	// measureResut
 
 	if(pWsiResult->GetSReviewResultCount() == 0) return ;
@@ -324,7 +324,7 @@
 	// set last result idx
 	pWsiResult->SetLastSReviewResultIndex(nCurResultIdx);
 
-	// 마지막 포인트까지 왔고, WSI 결과가 남아 있으면...
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 占쌉곤옙, WSI 占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙...
 	if(nCurResultIdx==nEndResultIdx && nCurResultIdx<=pWsiResult->GetSReviewResultCount())
 	{
 		nStartResultIdx = nCurResultIdx + 1;
@@ -335,8 +335,8 @@
 		pWsiResult->SetStartSReviewResultIndex(nStartResultIdx);
 		pWsiResult->SetEndSReviewResultIndex(nEndResultIdx);
 
-		// 나머지 포인트 리뷰 수행하자.
-		::Sleep(3000); // 딜레이는 필수임. 없으면 동작 안함.
+		// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+		::Sleep(3000); // 占쏙옙占쏙옙甄占� 占십쇽옙占쏙옙. 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙.
 //		Process_RemainWsiPoint(nModuleIndex);
 	}
 
@@ -362,7 +362,7 @@
 	CReviewResult* pWsiResult = pGlassResult->GetWsiUserResult(nModuleIndex);
 	if (pWsiResult==NULL) goto RESULT_FAIL;
 
-	// 마지막 인덱스를 가져온다.
+	// 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙占승댐옙.
 	int nCurResultIdx	= pWsiResult->GetLastSReviewResultIndex() + 1; // last index + 1
 	int nStartResultIdx	= pWsiResult->GetStartSReviewResultIndex();
 	int nEndResultIdx	= pWsiResult->GetEndSReviewResultIndex();
@@ -376,13 +376,13 @@
 	int		nMPosY	= int(pPosition->dMotorPosY * 1000.0);
 	double	dTime	= (double) m_ProcessTimer.GetDurationMilliSecond();
 
-	// 인덱스가 다르면 비정상임.
+	// 占싸듸옙占쏙옙占쏙옙 占쌕몌옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
 	if (measureResut.nResultIndex != nCurResultIdx) 
 	{
 		goto RESULT_FAIL;
 	}
 
-	// 현재 데이터 저장.
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙.
 	// measureResut
 
 	if(pWsiResult->GetSReviewResultCount() == 0) return ;
@@ -407,7 +407,7 @@
 	// set last result idx
 	pWsiResult->SetLastSReviewResultIndex(nCurResultIdx);
 
-	// 마지막 포인트까지 왔고, WSI 결과가 남아 있으면...
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 占쌉곤옙, WSI 占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙...
 	if(nCurResultIdx==nEndResultIdx && nCurResultIdx<=pWsiResult->GetSReviewResultCount())
 	{
 		nStartResultIdx = nCurResultIdx + 1;
@@ -418,8 +418,8 @@
 		pWsiResult->SetStartSReviewResultIndex(nStartResultIdx);
 		pWsiResult->SetEndSReviewResultIndex(nEndResultIdx);
 
-		// 나머지 포인트 리뷰 수행하자.
-		::Sleep(3000); // 딜레이는 필수임. 없으면 동작 안함.
+		// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+		::Sleep(3000); // 占쏙옙占쏙옙甄占� 占십쇽옙占쏙옙. 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙.
 		//		Process_RemainWsiPoint(nModuleIndex);
 	}
 
@@ -449,7 +449,7 @@
  	CAlignResult *pAlignResult = &pGlassResult->m_AlignResult;
  	CAlignRecipe *pAlignRecipe = &pGlassResult->m_AlignRecipe; 
  
- 	// 얼라인 자동조명 결과 레시피에 저장하자. 
+ 	// 占쏙옙占쏙옙占� 占쌘듸옙占쏙옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙占실울옙 占쏙옙占쏙옙占쏙옙占쏙옙. 
  	CRsRcpAlignInfo *pRsRcpAlignInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpAlignInfo();
  	if (pRsRcpAlignInfo!=NULL && pRsRcpAlignInfo->m_bAutoProcess)
  	{
@@ -463,25 +463,25 @@
  			pRsRcpAlignInfo->m_dSecondCamExposure = pCurAlignResult->dExposureTime[1];
  		}
  
- 		// 레시피 데이타 저장
+ 		// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙타 占쏙옙占쏙옙
  		//m_pDoc->Recipe_WriteRecipeFile();
  	}
  
  
  	BOOL bLastAlignResult = FALSE;
  	CCoordCalibrator *pCoordCalibrator = m_pSP2P->ISP2P_GetCoordCalibrator();
- 	// 최종 얼라인 결과..
+ 	// 占쏙옙占쏙옙 占쏙옙占쏙옙占� 占쏙옙占�..
  	if (pCoordCalibrator && pCurAlignResult->nResultCode==Align_Success)
  	{
  		g_pLog->DisplayMessage(_T("[AlignResult] Align Find Success!"));
  
- 		// 얼라인 결과 글라스 정보에 갱신
+ 		// 占쏙옙占쏙옙占� 占쏙옙占� 占쌜띰옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
  		*pAlignResult = *pCurAlignResult;
  
  		pCoordCalibrator->SetFirstMarkPos(pAlignResult->dFindPositionX[0], pAlignResult->dFindPositionY[0], pAlignRecipe->dGlassPositionX[0], pAlignRecipe->dGlassPositionY[0]);
  		pCoordCalibrator->SetSecondMarkPos(pAlignResult->dFindPositionX[1], pAlignResult->dFindPositionY[1], pAlignRecipe->dGlassPositionX[1], pAlignRecipe->dGlassPositionY[1]);
  
- 		// 각도 계산
+ 		// 占쏙옙占쏙옙 占쏙옙占�
  		if(pCoordCalibrator->CalculateAlignResult() == TRUE)
  		{
  			sAlignResult = pCoordCalibrator->GetAlignResult();
@@ -490,38 +490,38 @@
  			bLastAlignResult = !pAlignRecipe->bRotateProcess;
  		}
  
- 		// 글라스 각도 보정 유무
+ 		// 占쌜띰옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
  		CCameraControlAlign *pAlignCameraControl	= m_pSP2P->ISP2P_GetAlignCameraControl();
  		SThetaMotorInfo* pThetaMotorInfo			= m_pSP2P->ISP2P_GetThetaMotorInfo();
  		CMotorControl* pMotorControl				= m_pSP2P->ISP2P_GetMotorControl();
  
  		if (pAlignRecipe->bRotateProcess && pAlignCameraControl && pMotorControl && pThetaMotorInfo)
  		{
- 			if (fabs(sAlignResult.dDegree) <= pAlignRecipe->dGlassAngleMin) // 현재 글라스 각도가 최소각보다 작으면 성공
+ 			if (fabs(sAlignResult.dDegree) <= pAlignRecipe->dGlassAngleMin) // 占쏙옙占쏙옙 占쌜띰옙 占쏙옙占쏙옙占쏙옙 占쌍소곤옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
  			{
  				bLastAlignResult = TRUE;
  				g_pLog->DisplayMessage(_T("[AlignResult] Success! Last Glass Angle : %.8lf degree, Retry Count : %d ea"), 
  					sAlignResult.dDegree,  pCurAlignResult->nFindCount);
  			}
- 			else if (fabs(sAlignResult.dDegree) > pAlignRecipe->dGlassAngleMax) // 현재 글라스 각도가 최대각보다 크면 실패
+ 			else if (fabs(sAlignResult.dDegree) > pAlignRecipe->dGlassAngleMax) // 占쏙옙占쏙옙 占쌜띰옙 占쏙옙占쏙옙占쏙옙 占쌍대각占쏙옙占쏙옙 크占쏙옙 占쏙옙占쏙옙
  			{
  				bLastAlignResult = FALSE;
  				g_pLog->DisplayMessage(_T("[AlignResult] FAIL! Last Glass Angle : %.8lf degree, Retry Count : %d ea"), 
  					sAlignResult.dDegree,  pCurAlignResult->nFindCount);
  			}
- 			else if (pCurAlignResult->nFindCount < pAlignRecipe->nRetryCount) // 재보정 횟수가 레시피 횟수 이하이면 재보정 수행
+ 			else if (pCurAlignResult->nFindCount < pAlignRecipe->nRetryCount) // 占썹보占쏙옙 횟占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 횟占쏙옙 占쏙옙占쏙옙占싱몌옙 占썹보占쏙옙 占쏙옙占쏙옙
  			{
  				g_pLog->DisplayMessage(_T("[AlignResult] Current Glass Angle : %.8lf degree, Retry Count : %d ea"), 
  					sAlignResult.dDegree,  pCurAlignResult->nFindCount);
  
- 				// 모터로 각도 보정..
+ 				// 占쏙옙占싶뤄옙 占쏙옙占쏙옙 占쏙옙占쏙옙..
  				double dCalAngle = sAlignResult.dDegree;
  				dCalAngle = pThetaMotorInfo->dPosition - dCalAngle ;
  				g_pLog->DisplayMessage(_T("[AlignResult] Move Rotate Glass Angle : %.8lf degree"), dCalAngle);
  				pMotorControl->AxisThetaManualGoEnd(dCalAngle);
  				::Sleep(100);
  
- 				// 얼라인 ReProcess
+ 				// 占쏙옙占쏙옙占� ReProcess
  				if (pAlignCameraControl->AlignProcess())
  				{
  					g_pLog->DisplayMessage(_T("[AlignResult] Align Find Process ReStarted!"));
@@ -556,8 +556,8 @@
  		//m_pView->SetAlignResult(pAlignResult->nResultCode, sAlignResult.dOriginX, sAlignResult.dOriginY, sAlignResult.dDegree);
  	}
  
-	// PCControl 얼라인 신호 전송.
-	if (bLastAlignResult) // 최종 얼라인결과...
+	// PCControl 占쏙옙占쏙옙占� 占쏙옙호 占쏙옙占쏙옙.
+	if (bLastAlignResult) // 占쏙옙占쏙옙 占쏙옙占쏙옙寬占쏙옙...
 	{	
 		SendResultToSignalControl(PCControlSendData_AlignResult_CPJT, SIGNAL_SEND_RESULT_SUCCESS);
 		m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::AlignStart] Send Align Success Data!"));
@@ -690,12 +690,12 @@
 		m_pSP2P->ISP2P_UpdateReviewProcessStatus(ReviewProcessStatus_None, nPlanIndex);
 		 
 
-		//데모용
+		//占쏙옙占쏙옙占�
 		AFM_SetAFMTracking(FALSE);
 		return;
 	}
 
-	//190727 chm WSI 진행시 End 체크 후 진행
+	//190727 chm WSI 占쏙옙占쏙옙占� End 체크 占쏙옙 占쏙옙占쏙옙
 	if(nBeforePlanIndex== CPJT_PlanWSI||nBeforePlanIndex== CPJT_PlanWsiReflow||nBeforePlanIndex== CPJT_PlanWsiUser)
 	{
 		if(pPlanInfo->m_nReviewType == CPJT_PlanWSI ||pPlanInfo->m_nReviewType == CPJT_PlanWsiReflow||pPlanInfo->m_nReviewType== CPJT_PlanWsiUser || pPlanInfo->m_nReviewType == CPJT_PlanWsiMultiShot)
@@ -724,13 +724,13 @@
 		}
 	}
 
-	//190727 chm WSI type 진행후 Review 플랜시 진행시 카메라가 글라스 밖에 있을경우를 위한... 
+	//190727 chm WSI type 占쏙옙占쏙옙占쏙옙 Review 占시뤄옙占쏙옙 占쏙옙占쏙옙占� 카占쌨띰옙 占쌜띰옙 占쌜울옙 占쏙옙占쏙옙占쏙옙痢� 占쏙옙占쏙옙... 
 	if(nBeforePlanIndex== CPJT_PlanWSI ||nBeforePlanIndex== CPJT_PlanWsiReflow||nBeforePlanIndex== CPJT_PlanWsiUser)
 	{
 		if(  pPlanInfo->m_nReviewType == CPJT_PlanReview|| pPlanInfo->m_nReviewType == CPJT_PlanUser|| pPlanInfo->m_nReviewType == CPJT_PlanMeasure|| pPlanInfo->m_nReviewType == CPJT_PlanReflow)
 		{
 
-			CTotalPitchMeasure* pTotapPithMeasure = m_pSP2P->ISP2P_GetTotalPitchMeasure(); // 빌려쓰기! 20190730 chm 나중에 함수로 따로....
+			CTotalPitchMeasure* pTotapPithMeasure = m_pSP2P->ISP2P_GetTotalPitchMeasure(); // 占쏙옙占쏙옙占쏙옙占�! 20190730 chm 占쏙옙占쌩울옙 占쌉쇽옙占쏙옙 占쏙옙占쏙옙....
 	
 			const CMotorControlInfo* pSystemMotorInfo = m_pSP2P->ISP2P_System_GetMotorInfo();
 			if(pSystemMotorInfo !=NULL) 
@@ -774,8 +774,8 @@
 		if(pPlanInfo == NULL) continue;
 
 		//210325
-		//END 나 언로딩이 되어버렸지만 해당 함수가 쓰레드로 돌아가고 있어 start 함수를 타버림 
-		//그것에 대한 예외처리 
+		//END 占쏙옙 占쏙옙琯占쏙옙占� 占실억옙占쏙옙占쏙옙占쏙옙占� 占쌔댐옙 占쌉쇽옙占쏙옙 占쏙옙占쏙옙占쏙옙占� 占쏙옙占싣곤옙占쏙옙 占쌍억옙 start 占쌉쇽옙占쏙옙 타占쏙옙占쏙옙 
+		//占쌓것울옙 占쏙옙占쏙옙 占쏙옙占쏙옙처占쏙옙 
 		if (GetProcessStatus() == ProcessReviewEnd_CPJT || GetProcessStatus() == ProcessReviewUnloding_CPJT)
 		{
 			g_pLog->DisplayMessage(_T("[ProcessStop] StartProcessing Sequence Stop Status : %d"), GetProcessStatus());
@@ -816,7 +816,7 @@
 				m_pSP2P->ISP2P_DisplayMessage(_T("[Sequence Processor] WSI Plan End!"));
 			}
 			break;
-		//미사용
+		//占싱삼옙占�
 		case CPJT_PlanMeasure:
 			if (( nTotalCount += pGlassResult->GetTotalSMeasureResultCount()) > 0)
 			{
@@ -925,8 +925,8 @@
 
 	AllAckSignalOff();
 	m_pSP2P->ISP2P_GetReviewProcessor()->ResetGantryDone();
-	SetCheckWSIEnd(-1); //190726 wsiend체크 초기화
-	SetWsiType(-1);    //wsi reflow 타입 구별 초기화
+	SetCheckWSIEnd(-1); //190726 wsiend체크 占십깍옙화
+	SetWsiType(-1);    //wsi reflow 타占쏙옙 占쏙옙占쏙옙 占십깍옙화
 	SetLastPointCheck(FALSE);
 
 	bFileFind = FALSE;
@@ -953,18 +953,18 @@
  	}
  	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] Glass Result Count : %d ea"), nGlassResultCount);
 	
-	pGlassResult->ResetDefocusCount();//로딩 부분에서 defocus count 초기화 190821 chm
+	pGlassResult->ResetDefocusCount();//占싸듸옙 占싸분울옙占쏙옙 defocus count 占십깍옙화 190821 chm
 
 
  	CTime time = CTime::GetCurrentTime();
  	pGlassResult->m_strResultDate.Format(_T("%04d.%02d.%02d"), time.GetYear(), time.GetMonth(), time.GetDay());
 
-	//if(Revolver_SetGoHome(0)) // 리볼버 HOME 시퀀스 
+	//if(Revolver_SetGoHome(0)) // 占쏙옙占쏙옙占쏙옙 HOME 占쏙옙占쏙옙占쏙옙 
 	//{
 	//	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] Revolver Set GoHome Success!"));
 	//}
 
-	//#3357 KYH Align Image 초기화 ADD START
+	//#3357 KYH Align Image 占십깍옙화 ADD START
 	CCameraControlAlign* pAlignCameraControl = m_pSP2P->ISP2P_GetAlignCameraControl();
 	if (pAlignCameraControl != NULL)
 	{
@@ -972,7 +972,7 @@
 
 		g_pLog->DisplayMessage(_T("[Align] Align Image Clear"));
 	}
-	//#3357 KYH Align Image 초기화 ADD END
+	//#3357 KYH Align Image 占십깍옙화 ADD END
 
  	// get transfer data
  	int nResultCode = 0;
@@ -999,7 +999,7 @@
 
 			if (pDitRawClient->isConnect()==FALSE)
 			{
-				m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]공유메모리 연결 끊김 재연결 시도 "));
+				m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占썹연占쏙옙 占시듸옙 "));
 				int nReconnect=0;
 				while (1)
 				{
@@ -1014,11 +1014,11 @@
 					Sleep(1000);
 					if (pDitRawClient->isConnect() == FALSE)
 					{
-						m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]공유메모리 연결 실패 Count[%d]"), nReconnect);
+						m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙 占쏙옙占쏙옙 Count[%d]"), nReconnect);
 					}
 					else
 					{
-						m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]공유메모리 연결 성공"));
+						m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙 占쏙옙占쏙옙"));
 						break;
 					}
 					nReconnect += 1;
@@ -1028,9 +1028,9 @@
 
 			}
 
-			// #3381 LYW CF AOI Review 전설비 FDC TackTime 오보고 현상 개선 ADD START
+			// #3381 LYW CF AOI Review 占쏙옙占쏙옙占쏙옙 FDC TackTime 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 ADD START
 			pDitRawClient->GetGlassData()->m_tmReviewLoading = CTime::GetCurrentTime();
-			// #3381 LYW CF AOI Review 전설비 FDC TackTime 오보고 현상 개선 ADD END
+			// #3381 LYW CF AOI Review 占쏙옙占쏙옙占쏙옙 FDC TackTime 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 ADD END
 			
 
 			CString strGlassIDTemp = NULL;
@@ -1047,7 +1047,7 @@
 			m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading] Send Loading Success Signal!"));
 
 			strFileName.Format(_T("%s_%s"), strGlassIDTemp, strGlassStepIdTemp);
-			//업데이트시
+			//占쏙옙占쏙옙占쏙옙트占쏙옙
 			//bFileFind = FindRawBinFile(strFileName);
 			bFileFind = TRUE;
 
@@ -1094,7 +1094,7 @@
  		}
  	}
 
-	//// 190725 고객사 요청사항 chm ASCEND 시 alarm
+	//// 190725 占쏙옙占쏙옙占� 占쏙옙청占쏙옙占쏙옙 chm ASCEND 占쏙옙 alarm
 	const CRsRcpReviewInfo* pRsRcpReviewInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpReviewInfo();
 
 	const CRcpSortingInfo *pSortingInfo = pRsRcpReviewInfo->GetRcpReviewSortInfo();
@@ -1111,7 +1111,7 @@
 
 	
 	
-	////레시피 세팅으로 옴김 190618
+	////占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占싫깍옙 190618
 	if(GetUseAfmHomePosition())
 	{
 	g_pLog->DisplayMessage(_T("[AFM] AFM Home Position Start!!!"));
@@ -1120,7 +1120,7 @@
 
 	}
 
-	//공유메모리 커멘드 리뷰 스타트(글라스 로딩) 
+	//占쏙옙占쏙옙占쌨몌옙 커占쏙옙占� 占쏙옙占쏙옙 占쏙옙타트(占쌜띰옙 占싸듸옙) 
 	CDitGlassRawClient* pDitSharedGlassRaw = CDitGlassRawClient::GetInstance();
 	if (pDitSharedGlassRaw->isConnect() == FALSE) {
 		m_pSP2P->ISP2P_DisplayMessage(_T("[DitGlassRawClient] Shared Memory Connect Fail"));
@@ -1173,7 +1173,7 @@
  	CReviewProcessor* pReviewProcessor = m_pSP2P->ISP2P_GetReviewProcessor();
  	if(pReviewProcessor == NULL) return ;	
  	pReviewProcessor->SetCellData(pGlassResult);
- 	pReviewProcessor->SetReviewCount(0);			// 리뷰 Sequence No 초기화.
+ 	pReviewProcessor->SetReviewCount(0);			// 占쏙옙占쏙옙 Sequence No 占십깍옙화.
 	pReviewProcessor->SetPlanReviewCount(0);
 	pReviewProcessor->SetPlanWSICount(0);
  	// Process Status Update
@@ -1214,7 +1214,7 @@
 
 	if (SendSignalToSignalControl(PCControlSendSignalIndex_Ack, PCControlSend_AlignStartAck_CPJT))
 		m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::AlignStart] Send Align Start Ack!"));
-	//Sleep(400);//프레임 문제 딜레이 주기 chm190602
+	//Sleep(400);//占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占� 占쌍깍옙 chm190602
 
  	// 1. get current glass result
  	CGlassResult* pGlassResult = m_pSP2P->ISP2P_GetCurrentGlassResult();
@@ -1238,7 +1238,7 @@
 	}
 	else
 	{
-		// 190710 SJB Align Camera Disconnect Check, Align Step 진행 전에 확인한다.
+		// 190710 SJB Align Camera Disconnect Check, Align Step 占쏙옙占쏙옙 占쏙옙占쏙옙 확占쏙옙占싼댐옙.
 		if(pAlignCameraControl)
 		{
 			if(pAlignCameraControl->AlignCameraDisconnectCheck() == FALSE)
@@ -1255,9 +1255,9 @@
 		}
 		else
 		{
-			//지워야됨
+			//占쏙옙占쏙옙占쌩듸옙
 			Sleep(1000);
-			//TEST 모드
+			//TEST 占쏙옙占�
 			{
 				SendResultToSignalControl(PCControlSendData_AlignResult_CPJT, SIGNAL_SEND_RESULT_SUCCESS);
 				m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::AlignStart] Send Align SUCCESS Data!"));
@@ -1266,7 +1266,7 @@
 		}
 
 
-			//주석 풀기
+			//占쌍쇽옙 풀占쏙옙
 			// 4. send align fail signal to plc
 			//SendResultToSignalControl(PCControlSendData_AlignResult_CPJT, SIGNAL_SEND_RESULT_FAIL);
 			//m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::AlignStart] Send Align Fail Data!"));
@@ -1300,7 +1300,7 @@
  	if (bFileFind == FALSE)
 	{
 		SendResultToSignalControl(PCControlSendData_ReviewResult_CPJT, SIGNAL_SEND_RESULT_FAIL);
-		m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReadRawFile] 결과파일 찾기 실패"));
+		m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReadRawFile] 占쏙옙占쏙옙占쏙옙占� 찾占쏙옙 占쏙옙占쏙옙"));
 		return;
 	}	
 
@@ -1308,7 +1308,7 @@
 	CGlassResult* pGlassResult = m_pSP2P->ISP2P_GetCurrentGlassResult();
 	if (pGlassResult==NULL) return;
 	
-	//공유메모리 커멘드 리뷰 스타트(글라스 로딩) 
+	//占쏙옙占쏙옙占쌨몌옙 커占쏙옙占� 占쏙옙占쏙옙 占쏙옙타트(占쌜띰옙 占싸듸옙) 
 	CDitGlassRawClient* pDitSharedGlassRaw = CDitGlassRawClient::GetInstance();
 	if(pDitSharedGlassRaw->isConnect() == FALSE)				m_pSP2P->ISP2P_DisplayMessage(_T("[DitGlassRawClient] Shared Memory Connect Fail"));
 
@@ -1335,7 +1335,7 @@
 		int nTotalPlanCount = CalculatePlanData(pGlassResult);
 		m_pSP2P->ISP2P_DisplayMessage(_T("[Read Raw File] Review All Plan Total Count : %d"), nTotalPlanCount);
 
-		//지워야됨
+		//占쏙옙占쏙옙占쌩듸옙
 		Sleep(1000);
 		// send review ready
 		SendResultToSignalControl(PCControlSendData_ReviewResult_CPJT, SIGNAL_SEND_RESULT_SUCCESS);
@@ -1348,7 +1348,7 @@
 		m_pSP2P->ISP2P_DisplayMessage(_T("[ReadRawFile] AOI Result File Read Fail![%.3f ms]"), processTimer.GetDurationMilliSecond());
 
 
-		//테스트 모드
+		//占쌓쏙옙트 占쏙옙占�
 		//{
 		//			// send review ready
 		//	SendResultToSignalControl(PCControlSendData_ReviewResult_CPJT, SIGNAL_SEND_RESULT_SUCCESS);
@@ -1356,7 +1356,7 @@
 		//			m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReadRawFile] Send Review Ready Signal!"));
 		//}
 
-		//주석 해제
+		//占쌍쇽옙 占쏙옙占쏙옙
 		int nCurPlanIndex = 0;
 		CRsRcpReviewInfo* pRsRcpReviewInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpReviewInfo();
 		if(pRsRcpReviewInfo)
@@ -1378,8 +1378,8 @@
 		}
 	}
 
-	//// [2017:5:24]-[WEZASW] : Review Image Upload Dir 생성.(FTPUploader에서 자동 삭제 되더라도 실제 리뷰시 생성)
-	//// '반복검사'시 FTPUploader에서 업로드 후 삭제 시점과 PCControl Glass Unloading 후 즉시 Loading시 Review에서의 업로드 경로(GlassID) 생성 시점 오류
+	//// [2017:5:24]-[WEZASW] : Review Image Upload Dir 占쏙옙占쏙옙.(FTPUploader占쏙옙占쏙옙 占쌘듸옙 占쏙옙占쏙옙 占실댐옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占� 占쏙옙占쏙옙)
+	//// '占쌥븝옙占싯삼옙'占쏙옙 FTPUploader占쏙옙占쏙옙 占쏙옙占싸듸옙 占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 PCControl Glass Unloading 占쏙옙 占쏙옙占� Loading占쏙옙 Review占쏙옙占쏙옙占쏙옙 占쏙옙占싸듸옙 占쏙옙占�(GlassID) 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	const CNetworkInfo *pNetworkInfo = m_pSP2P->ISP2P_System_GetNetworkInfo();
 	CString strPath = _T("");
 	//if(pNetworkInfo && pNetworkInfo->m_strUploadImagePath.IsEmpty() == FALSE)
@@ -1394,7 +1394,7 @@
 	if (CDitGlassRawClient::GetInstance()->GetGlassData() == NULL) return;
 
 	
-	//업로드 폴더가 없으면 폴더 생성후 다시 업로드 경로 Set 20190917chm
+	//占쏙옙占싸듸옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쌕쏙옙 占쏙옙占싸듸옙 占쏙옙占� Set 20190917chm
 	if(Uploadfile.FindFile(strPath)==FALSE)
 	{
 		CTime tmServerLoadingTime = CDitGlassRawClient::GetInstance()->GetGlassData()->m_tmGlassLoading;
@@ -1405,7 +1405,7 @@
 
 		
 
-		//taek 210126 rtms 보고용 이미지 폴더 생성 
+		//taek 210126 rtms 占쏙옙占쏙옙占� 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 
 		CreateDirectory(pReviewProcessor->GetRTMSUploadImagePath(),NULL);
 	}
 
@@ -1451,10 +1451,10 @@
 	//			_grmCellData* pCellData = pDitRawClient->GetCellData(0);
 	//			if(pCellData) 
 	//			{
-	//			//	pCellData->m_nTotalPitchData[0] = int(pTotapPithMeasure->GetTotalPitchBD() * 1000); // 장축, 작업자 기준 위쪽
-	//			//	pCellData->m_nTotalPitchData[1] = int(pTotapPithMeasure->GetTotalPitchAC() * 1000); // 장축, 작업자 기준 아래쪽
-	//			//	pCellData->m_nTotalPitchData[2] = int(pTotapPithMeasure->GetTotalPitchAB() * 1000); // 단축, 작업자 기준 왼쪽
-	//			//	pCellData->m_nTotalPitchData[3] = int(pTotapPithMeasure->GetTotalPitchCD() * 1000); // 단축, 작업자 기준 오른쪽
+	//			//	pCellData->m_nTotalPitchData[0] = int(pTotapPithMeasure->GetTotalPitchBD() * 1000); // 占쏙옙占쏙옙, 占쌜억옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	//			//	pCellData->m_nTotalPitchData[1] = int(pTotapPithMeasure->GetTotalPitchAC() * 1000); // 占쏙옙占쏙옙, 占쌜억옙占쏙옙 占쏙옙占쏙옙 占싣뤄옙占쏙옙
+	//			//	pCellData->m_nTotalPitchData[2] = int(pTotapPithMeasure->GetTotalPitchAB() * 1000); // 占쏙옙占쏙옙, 占쌜억옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
+	//			//	pCellData->m_nTotalPitchData[3] = int(pTotapPithMeasure->GetTotalPitchCD() * 1000); // 占쏙옙占쏙옙, 占쌜억옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙
 	//			}
 	//		}
 	//	}
@@ -1462,7 +1462,7 @@
 	//	{
 	//		m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor] TotalPitchMeasure Result Fail!"));
 
-	//		// 190711 SJB, TotalPitchMeasure Fail시에 바로 Motor로 명령을 날리기 보다는 Motion Enable 신호를 확인하자
+	//		// 190711 SJB, TotalPitchMeasure Fail占시울옙 占쌕뤄옙 Motor占쏙옙 占쏙옙占쏙옙占� 占쏙옙占쏙옙占쏙옙 占쏙옙占쌕댐옙 Motion Enable 占쏙옙호占쏙옙 확占쏙옙占쏙옙占쏙옙
 	//		
 	//		if(!pTotapPithMeasure->GetMotorEnable())
 	//		{
@@ -1494,9 +1494,9 @@
 	}
 	else
 	{
-		//지워야됨
+		//占쏙옙占쏙옙占쌩듸옙
 		//Sleep(1000);
-		//Test모드
+		//Test占쏙옙占�
 		//SendResultToSignalControl(PCControlSendData_ReviewComplete_CPJT, SIGNAL_SEND_RESULT_SUCCESS);
 		//SendSignalToSignalControl(PCControlSendSignalIndex_Seq, PCControlSend_ReviewComplete_CPJT);
 		//m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewStart] Send Review Success Signal!"));
@@ -1525,17 +1525,21 @@
 	}
 	if (GetLastPointCheck() == FALSE)
 	{
-		Sleep(2500);
+		Sleep(1000);
 	}
 	ReJudgeProcessing(m_pDitGlassRaw);
 	m_pDitGlassRaw->GetGlassData()->m_tmReviewEnd = CTime::GetCurrentTime();
-	if (m_pDitGlassRaw->isConnect() != FALSE)	m_pDitGlassRaw->SetReviewEnd();
+	if (m_pDitGlassRaw->isConnect() != FALSE) 
+	{
+		m_pDitGlassRaw->SetReviewEnd();
+		m_pDitGlassRaw->WriteReviewRawBinFile();
+	}
 	
 	m_pDitGlassRaw->GetGlassData()->m_nReviewNum = m_pSP2P->ISP2P_GetReviewProcessor()->GetPlanReviewCount();
-    //SendDVDataToSignalControl();// 안쓰쥬
+    //SendDVDataToSignalControl();// 占싫억옙占쏙옙
 
-	//OverTime 발생시 제어에서 END ACK를 기다리는게 아니라 걍 Conplete를 기다린다.
-	//음 ... 로직  오류인데일단 추가 
+	//OverTime 占쌩삼옙占쏙옙 占쏙옙占쏘에占쏙옙 END ACK占쏙옙 占쏙옙摸占쏙옙째占� 占싣니띰옙 占쏙옙 Conplete占쏙옙 占쏙옙摸占쏙옙占�.
+	//占쏙옙 ... 占쏙옙占쏙옙  占쏙옙占쏙옙占싸듸옙占싹댐옙 占쌩곤옙 
 
 	if (GetLastPointCheck() == FALSE)
 	{
@@ -1562,10 +1566,10 @@
 		m_pSP2P->ISP2P_GetWSIControl(0)->SendWsiAfmSafePosMove();
 		m_pSP2P->ISP2P_GetWSIControl(1)->SendWsiAfmSafePosMove();
 	}
-	// 결과파일 생성은 Review에서 관여 안함
+	// 占쏙옙占쏙옙占쏙옙占� 占쏙옙占쏙옙占쏙옙 Review占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 	if(m_pDitGlassRaw->isConnect()==FALSE)		WriteRawData(pGlassResult);
 	
-	//디포커스 알람 send 20190819chm
+	//占쏙옙占쏙옙커占쏙옙 占싯띰옙 send 20190819chm
 	if(pGlassResult->m_nDeFocusCount >0) 
 	{
 		SendSignalToSignalControl(PCControlSendSignalIndex_State,PCControlSend_Defoucs,1000);
@@ -1575,8 +1579,8 @@
 		CString strTime = _T("");
 		strTime.Format(_T("%04d-%02d-%02d %02d:%02d:%02d"), time.GetYear(), time.GetMonth(), time.GetDay(), time.GetHour(), time.GetMinute(), time.GetSecond());
 
-		CDlgDefocusList::GetInstance()->SetDefocusTotalCount(pGlassResult->m_nDeFocusCount);//토탈 카운트 Add 
-		CDlgDefocusList::GetInstance()->SetDefocusData(strTime,pGlassResult->m_strGlassID,pGlassResult->m_nDeFocusCount);//ui 추가후 갱신
+		CDlgDefocusList::GetInstance()->SetDefocusTotalCount(pGlassResult->m_nDeFocusCount);//占쏙옙탈 카占쏙옙트 Add 
+		CDlgDefocusList::GetInstance()->SetDefocusData(strTime,pGlassResult->m_strGlassID,pGlassResult->m_nDeFocusCount);//ui 占쌩곤옙占쏙옙 占쏙옙占쏙옙
 
 	}
 
@@ -1590,17 +1594,17 @@
 	g_pLog->DisplayMessage(_T("History Button Enable"));
 	m_pSP2P->ISP2P_GetDiagnosisHistory2();
 
-	/*int nModuleCount = m_pSP2P->ISP2P_GetModuleStatusCount(); //0503 리뷰 End시 조명값 0으로 초기화
+	/*int nModuleCount = m_pSP2P->ISP2P_GetModuleStatusCount(); //0503 占쏙옙占쏙옙 End占쏙옙 占쏙옙占쏙옙占� 0占쏙옙占쏙옙 占십깍옙화
 	for (int nModuleIdx = 0; nModuleIdx < nModuleCount; nModuleIdx++)
 	{
 		{
 			ReviewLight_SetLightLevel(nModuleIdx, 0);
-			g_pLog->DisplayMessage(_T("Module[%d] LightLevel 초기화"), nModuleIdx);
+			g_pLog->DisplayMessage(_T("Module[%d] LightLevel 占십깍옙화"), nModuleIdx);
 		}
 
 	}*/
 
-	//5. PCControl 신호 업데이트
+	//5. PCControl 占쏙옙호 占쏙옙占쏙옙占쏙옙트
 	if (pGlassResult)
 	{
 		m_pSP2P->ISP2P_UpdateProcessStatus(GetProcessStatus(), pGlassResult);
@@ -1642,8 +1646,8 @@
 
 	CString strCode = _T("");
 
-	int nDefectCount = pRawData->GetGlassData()->m_nDefectNum; // 디펙갯수
-	int nJudgeCount = pRcpReviewInfo->GetRcpZoneFilterInfoCount();// 필터 갯수
+	int nDefectCount = pRawData->GetGlassData()->m_nDefectNum; // 占쏙옙占썲갯占쏙옙
+	int nJudgeCount = pRcpReviewInfo->GetRcpZoneFilterInfoCount();// 占쏙옙占쏙옙 占쏙옙占쏙옙
 	int nFilterType = 0;
 	int nJudgeType = 0;
 	int nZoneNumber = 0;
@@ -1657,7 +1661,7 @@
 	int nJudgeCellOKCount = 0;
 	int nPixelSize = 0;
 	int nPixelFilterSize = 0;
-	//높이 데이터
+	//占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙
 	//1 wsi, 3 CS, 4 R, 5 G, 6 B
 	//pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_fWsi_ResultData[1];//Defect
 	//pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_fWsi_ResultData[3];//cs
@@ -1671,10 +1675,10 @@
 		{
 
 
-#pragma region 얼라인 fail
+#pragma region 占쏙옙占쏙옙占� fail
 			if (m_pSP2P->ISP2P_GetCurrentGlassResult()->GetAlignResult()->nResultCode != Align_Success)
 			{
-				m_pSP2P->ISP2P_DisplayMessage(_T("[TEST Process::ReviewEnd] 얼라인 실패 WSI 높이 재판정 진행 안함"));
+				m_pSP2P->ISP2P_DisplayMessage(_T("[TEST Process::ReviewEnd] 占쏙옙占쏙옙占� 占쏙옙占쏙옙 WSI 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙"));
 				break;
 			}
 #pragma endregion
@@ -1712,7 +1716,7 @@
 			
 			if (nPixelFilterSize <= nPixelSize && nPixelFilterSize != 0)
 			{
-				m_pSP2P->ISP2P_DisplayMessage(_T("[ReviewEnd] 사이즈 필터링 Pixel Size[%d] nPixelFilterSize [%d]"), nPixelSize,nPixelFilterSize);
+				m_pSP2P->ISP2P_DisplayMessage(_T("[ReviewEnd] 占쏙옙占쏙옙占쏙옙 占쏙옙占싶몌옙 Pixel Size[%d] nPixelFilterSize [%d]"), nPixelSize,nPixelFilterSize);
 				continue;	
 			}
 #pragma endregion
@@ -1722,13 +1726,13 @@
 			for (int nJudgeindex = 0; nJudgeindex < nJudgeCount; nJudgeindex++)
 			{
 				//nZoneType = GetZoneType();
-				dJudgeHight = pRcpReviewInfo->GetRcpZoneFilteringInfo(nJudgeindex)->GetJudgeHeight(); //높이
+				dJudgeHight = pRcpReviewInfo->GetRcpZoneFilteringInfo(nJudgeindex)->GetJudgeHeight(); //占쏙옙占쏙옙
 				nFilterType = pRcpReviewInfo->GetRcpZoneFilteringInfo(nJudgeindex)->m_nFilterType; //ZONE
 				nJudge = pRcpReviewInfo->GetRcpZoneFilteringInfo(nJudgeindex)->m_nFilterJudge; //OK TR
 
 				//nZoneNumber = pRcpReviewInfo->GetRcpZoneInfo(nFilterType)->m_vecZoneNumber[0];
 				
-				if (pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_nWsi_Type == 2) // 210330 kyh변경
+				if (pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_nWsi_Type == 2) // 210330 kyh占쏙옙占쏙옙
 				{
 
 					BOOL isZoneValue = FALSE;
@@ -1741,7 +1745,7 @@
 						}
 						else
 						{
-							m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] Zone[%d], DefectIndex[%d]"), nZoneNumber, pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 로그 추가
+							m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] Zone[%d], DefectIndex[%d]"), nZoneNumber, pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 占싸깍옙 占쌩곤옙
 							isZoneValue = TRUE;
 							//break;
 
@@ -1750,7 +1754,7 @@
 
 					if (isZoneValue == FALSE)
 					{
-						m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] NoFail DefectIndex[%d]"), pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 로그 추가
+						m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] NoFail DefectIndex[%d]"), pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 占싸깍옙 占쌩곤옙
 						continue;
 					}
 
@@ -1800,13 +1804,13 @@
 						}
 
 					}
-					else if (fWsiData<=0) // 0이하 값은 재판정 진행을 안한다.
+					else if (fWsiData<=0) // 0占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占싼댐옙.
 					{
-						m_pSP2P->ISP2P_DisplayMessage(_T("[TEST Process::ReviewEnd] WSI TYPE[%d] WSI 높이[%0.3lf] <= 0 판정 진행 안함"), nJudgeType, fWsiData);
+						m_pSP2P->ISP2P_DisplayMessage(_T("[TEST Process::ReviewEnd] WSI TYPE[%d] WSI 占쏙옙占쏙옙[%0.3lf] <= 0 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙"), nJudgeType, fWsiData);
 					}
 					else
 					{
-						//20210419 TR 고정으로 Judge 보다 낮을경우 OK ㄱㄱ 
+						//20210419 TR 占쏙옙占쏙옙占쏙옙占쏙옙 Judge 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占� OK 占쏙옙占쏙옙 
 						//if (nJudge == 1)//TR -> OK
 						//{
 							if (pRawData->GetDefectData(nDefectIdx)->m_DefectJudgement == DEFECT_JUDGE_CPJT_OK || pRawData->GetDefectData(nDefectIdx)->m_DefectJudgement == DEFECT_JUDGE_CPJT_Unknown)
@@ -1857,7 +1861,7 @@
 
 
 				}
-				else //WSI TYPE 이 아니면 
+				else //WSI TYPE 占쏙옙 占싣니몌옙 
 				{
 					continue;
 				}
@@ -1871,13 +1875,13 @@
 			for (int nJudgeindex = 0; nJudgeindex < nJudgeCount; nJudgeindex++)
 			{
 				//nZoneType = GetZoneType();
-				dJudgeHight = pRcpReviewInfo->GetRcpZoneFilteringInfo_PR(nJudgeindex)->GetJudgeHeight(); //높이
+				dJudgeHight = pRcpReviewInfo->GetRcpZoneFilteringInfo_PR(nJudgeindex)->GetJudgeHeight(); //占쏙옙占쏙옙
 				nFilterType = pRcpReviewInfo->GetRcpZoneFilteringInfo_PR(nJudgeindex)->m_nFilterType; //ZONE
 				nJudge = pRcpReviewInfo->GetRcpZoneFilteringInfo_PR(nJudgeindex)->m_nFilterJudge; //OK TR
 
 				//nZoneNumber = pRcpReviewInfo->GetRcpZoneInfo(nFilterType)->m_vecZoneNumber[0];
 
-				if (pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_nWsi_Type == 2) // 210330 kyh변경
+				if (pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_nWsi_Type == 2) // 210330 kyh占쏙옙占쏙옙
 				{
 
 					BOOL isZoneValue = FALSE;
@@ -1890,7 +1894,7 @@
 						}
 						else
 						{
-							m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] Zone[%d], DefectIndex[%d]"), nZoneNumber, pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 로그 추가
+							m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] Zone[%d], DefectIndex[%d]"), nZoneNumber, pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 占싸깍옙 占쌩곤옙
 							isZoneValue = TRUE;
 							//break;
 
@@ -1899,7 +1903,7 @@
 
 					if (isZoneValue == FALSE)
 					{
-						m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] NoFail DefectIndex[%d]"), pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 로그 추가
+						m_pSP2P->ISP2P_DisplayMessage(_T("[WSIZoneCheck] NoFail DefectIndex[%d]"), pRawData->GetDefectData(nDefectIdx)->m_nDefectIdx); //210330 kyh 占싸깍옙 占쌩곤옙
 						continue;
 					}
 
@@ -1953,7 +1957,7 @@
 					}
 					else
 					{
-						//20210419 TR 고정으로 Judge 보다 낮을경우 OK ㄱㄱ 
+						//20210419 TR 占쏙옙占쏙옙占쏙옙占쏙옙 Judge 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占� OK 占쏙옙占쏙옙 
 						//if (nJudge == 1)//TR -> OK
 						//{
 						if (pRawData->GetDefectData(nDefectIdx)->m_DefectJudgement == DEFECT_JUDGE_CPJT_OK || pRawData->GetDefectData(nDefectIdx)->m_DefectJudgement == DEFECT_JUDGE_CPJT_Unknown)
@@ -2005,7 +2009,7 @@
 
 
 				}
-				else //WSI TYPE 이 아니면 
+				else //WSI TYPE 占쏙옙 占싣니몌옙 
 				{
 					continue;
 				}
@@ -2020,7 +2024,7 @@
 				
 				strCode =pRcpReviewInfo->GetRcpZoneFilteringInfo_CODE(nJudgeindex)->m_FilterCode;
 
-				if (pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_nWsi_Type == 2) // 210330 kyh변경
+				if (pRawData->GetDefectData(nDefectIdx)->m_ReviewDefect.m_nWsi_Type == 2) // 210330 kyh占쏙옙占쏙옙
 				{
 
 					nJudgeType = ReJugdeWSIType(nFilterType);
@@ -2073,7 +2077,7 @@
 						m_pSP2P->ISP2P_DisplayMessage(_T("[TEST Process::ReviewEnd] CODE JUDGE WSI TYPE[%d] Defect CODE [%s] != [%s]"), nJudgeType, strCode, pRawData->GetDefectData(nDefectIdx)->m_strDefectCode);
 					}
 				}
-				else //WSI TYPE 이 아니면 
+				else //WSI TYPE 占쏙옙 占싣니몌옙 
 				{
 					continue;
 				}
@@ -2084,7 +2088,7 @@
 		}
 		
 #pragma region CELLJUDGE
-	//CELL 재판정////////////////////////////////////////////////////////////////
+	//CELL 占쏙옙占쏙옙占쏙옙////////////////////////////////////////////////////////////////
 
 	int nCellCount = pRawData->GetGlassData()->m_nCellNum;
 
@@ -2103,7 +2107,7 @@
 		else if (pRawData->GetCellData(nCellIndex)->m_nJudgement == Judge_OK_CPJT)
 		{
 			nCelllOKJuge = nCelllOKJuge + 1;
-		} //taek 21.01.25 Juge 구하는 곳을 새롭게 바꾸자...
+		} //taek 21.01.25 Juge 占쏙옙占싹댐옙 占쏙옙占쏙옙 占쏙옙占쌈곤옙 占쌕뀐옙占쏙옙...
 		else if (pRawData->GetCellData(nCellIndex)->m_nJudgement == Judge_PR_CPJT)
 		{
 			nCelllPRJuge = nCelllPRJuge + 1;
@@ -2147,7 +2151,7 @@
 				}
 				else
 				{
-					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] 카운트 개수가 음수임 [%02d]Cell DefectTRCount[%d] >= [%d]"), nCellIndex, pRawData->GetCellData(nCellIndex)->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetJudgeCount());
+					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] 카占쏙옙트 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 [%02d]Cell DefectTRCount[%d] >= [%d]"), nCellIndex, pRawData->GetCellData(nCellIndex)->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetJudgeCount());
 				}
 				break;
 			case JudgeType_T8_PR:
@@ -2197,7 +2201,7 @@
 				}
 				else
 				{
-					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] 카운트 개수가 음수임 [%02d]Cell DefectTRCount[%d] <= [%d]"), nCellIndex, pRawData->GetCellData(nCellIndex)->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetSubJudgeCount());
+					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] 카占쏙옙트 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 [%02d]Cell DefectTRCount[%d] <= [%d]"), nCellIndex, pRawData->GetCellData(nCellIndex)->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetSubJudgeCount());
 				}
 				break;
 			case JudgeType_T8_PR:
@@ -2361,7 +2365,7 @@
 	}
 	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] CELL COUNT OK:[%d] TR[%d] PR[%d]"), nCelllOKJuge, nCellTRJudge, nCelllPRJuge);
 #pragma endregion
-	//GLASS 재판정////////////////////////////////////////////////////////////////
+	//GLASS 占쏙옙占쏙옙占쏙옙////////////////////////////////////////////////////////////////
 #pragma region GLASSJUDGE
 	CRsRcpReviewInfo* pRsRcpReviewInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpReviewInfo();
 	if (pRsRcpReviewInfo == NULL) return FALSE;
@@ -2409,7 +2413,7 @@
 			}
 			else
 			{
-				m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] TR 카운트가 음수임 [%02d]GLASS Defect TR Count[%d] >= [%d]"), nIdx, pRawData->GetGlassData()->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetJudgeCount());
+				m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] TR 카占쏙옙트占쏙옙 占쏙옙占쏙옙占쏙옙 [%02d]GLASS Defect TR Count[%d] >= [%d]"), nIdx, pRawData->GetGlassData()->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetJudgeCount());
 			}
 			break;
 		case JudgeType_T8_PR:
@@ -2459,7 +2463,7 @@
 			}
 			else
 			{
-				m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd]TR카운트가 음수임 [%02d]GLASS Defect TR Count[%d] <= [%d]"), nIdx, pRawData->GetGlassData()->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetSubJudgeCount());
+				m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd]TR카占쏙옙트占쏙옙 占쏙옙占쏙옙占쏙옙 [%02d]GLASS Defect TR Count[%d] <= [%d]"), nIdx, pRawData->GetGlassData()->m_nDefectNumJudgeTR, pRcpJudgeInfo->GetSubJudgeCount());
 			}
 			break;
 		case JudgeType_T8_PR:
@@ -2647,7 +2651,7 @@
 		CakFileUtil akFileFinder;
 		while (nReTryTime--)
 		{
-			//#3359_LYW CF AOI Review REVIEW_LOADING_COMPLETE_TIMEOVER 알람 발생 원인 분석 START
+			//#3359_LYW CF AOI Review REVIEW_LOADING_COMPLETE_TIMEOVER 占싯띰옙 占쌩삼옙 占쏙옙占쏙옙 占싻쇽옙 START
 			if (nReTryTime%2 == 0)
 			{
 				strFilePath = AOIRAWBIN_PATH;
@@ -2656,9 +2660,9 @@
 
 			strWild.Format("%s\\%s_*.bin", strFilePath, strFileName);
 			 akFileFinder.FindFile(strWild.GetBuffer(0), FALSE);
-			//LYW LOG추가
+			//LYW LOG占쌩곤옙
 			g_pLog->DisplayMessage(_T("[GlassLoading][FindRawBinFile] Find Path = %s, RetryCount = %d, ResultCode = [%d]"), strFilePath, 30-nReTryTime, GetLastError());
-			//#3359_LYW CF AOI Review REVIEW_LOADING_COMPLETE_TIMEOVER 알람 발생 원인 분석 END
+			//#3359_LYW CF AOI Review REVIEW_LOADING_COMPLETE_TIMEOVER 占싯띰옙 占쌩삼옙 占쏙옙占쏙옙 占싻쇽옙 END
 			VECFINDDATA* pFindData = akFileFinder.getFindData();
 			int nFileNamePos = strlen(akFileFinder.getProcessPath());
 			std::map<LONGLONG, CString> mapSpanFileName;
@@ -2670,7 +2674,7 @@
 					parser.process(pFileName, "_.");
 					if (parser.getTokNum() < 4) continue;
 					
-					if (parser.getTokNum() >= 6) continue; // 0401 추가
+					if (parser.getTokNum() >= 6) continue; // 0401 占쌩곤옙
 
 					int nDataTime[8] = {};
 					{
@@ -2698,7 +2702,7 @@
 			{
 				if (mapSpanFileName.begin()->first < nCloseTime)
 				{
-					//가장 최근 결과파일 찾기 성공 [김태현 2019/7/17]
+					//占쏙옙占쏙옙 占쌍깍옙 占쏙옙占쏙옙占쏙옙占� 찾占쏙옙 占쏙옙占쏙옙 [占쏙옙占쏙옙占쏙옙 2019/7/17]
 					strFindFile = mapSpanFileName.begin()->second;
 					break;
 				}
@@ -2758,7 +2762,7 @@
 
 	int nPCControlReadDataCount = pSignalInfo->GetReadDataAddressCount();
 
-	// [2017:1:9]-[WEZASW] : PCControl GlassData 항목 재정의.
+	// [2017:1:9]-[WEZASW] : PCControl GlassData 占쌓몌옙 占쏙옙占쏙옙占쏙옙.
 	if(pSignalInfo->GetUseContinuousReadAddress())
 	{
 		CString strReadAddress = _T("");
@@ -3137,11 +3141,11 @@
 
 void CSequenceProcessor_CPJT::UpdateGlassResultFromTransferData(CGlassResult *pGlassResult, STransferData* pTransferData)
 {
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] Transfer Data 읽기!"));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] Transfer Data 占싻깍옙!"));
 
 	if (pGlassResult==NULL || pTransferData==NULL) return;
 
-	// [2017:1:9]-[WEZASW] : PCControl GlassData 항목 재정의
+	// [2017:1:9]-[WEZASW] : PCControl GlassData 占쌓몌옙 占쏙옙占쏙옙占쏙옙
 	// transfer data is not exist
 	if (pTransferData->strLotID.GetLength()<1)
 	{
@@ -3210,10 +3214,10 @@
 	pGlassResult->m_strPairFlag = pTransferData->strPairFlag;
 	pGlassResult->m_strOptionValue = pTransferData->strOptionValue;
 	pGlassResult->m_strReserved = pTransferData->strReserved;
-	pGlassResult->strGlassScanSchedule = pTransferData->strGlassScanSchedule;//분판 정보 cmark
+	pGlassResult->strGlassScanSchedule = pTransferData->strGlassScanSchedule;//占쏙옙占쏙옙 占쏙옙占쏙옙 cmark
 	pGlassResult->m_strRTMSStepID = pTransferData->strStepID; //taek 210126
 	
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] Transfer Data 끝!"));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] Transfer Data 占쏙옙!"));
 }
 
 void CSequenceProcessor_CPJT::UpdateHistoryResultFromTransferData(CGlassResult *pHistoryResult, CGlassResult* pGlassResult)
@@ -3271,7 +3275,7 @@
 	pHistoryResult->m_strPairFlag = pGlassResult->m_strPairFlag;
 	pHistoryResult->m_strOptionValue = pGlassResult->m_strOptionValue;
 	pHistoryResult->m_strReserved = pGlassResult->m_strReserved;
-	pHistoryResult->strGlassScanSchedule = pGlassResult->strGlassScanSchedule;//분판 정보 cmark
+	pHistoryResult->strGlassScanSchedule = pGlassResult->strGlassScanSchedule;//占쏙옙占쏙옙 占쏙옙占쏙옙 cmark
 	pHistoryResult->m_strStepID = pGlassResult->m_strRTMSStepID; //taek 210126
 	pHistoryResult->m_strEquipID = pGlassResult->m_strEquipID;
 	pHistoryResult->m_strProcessID = pGlassResult->m_strProcessID;
@@ -3283,7 +3287,7 @@
 
 void CSequenceProcessor_CPJT::CreateResultDirectory(const CString& strGlassID, const CString& strDate)
 {
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 디렉토리 만들기 시작"));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 占쏙옙占썰리 占쏙옙占쏙옙占� 占쏙옙占쏙옙"));
 	if (m_pSP2P==NULL) return;
 
 	const CNetworkInfo *pNetworkInfo = m_pSP2P->ISP2P_System_GetNetworkInfo();
@@ -3329,7 +3333,7 @@
 		strPath.Format(_T("%s\\%s"),pNetworkInfo->m_strAlignImagePath, strGlassID);
 		CreateDirectory(strPath, NULL);
 	}
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 디렉토리 만들기 끝"));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 占쏙옙占썰리 占쏙옙占쏙옙占� 占쏙옙"));
 }
 
 
@@ -3337,7 +3341,7 @@
 
 void CSequenceProcessor_CPJT::SetSaveImageBasePathToReviewProcessor(const CString& strGlassID, const CString& strResultDate)
 {
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 이미지 패스 만들기 시작"));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 占싱뱄옙占쏙옙 占싻쏙옙 占쏙옙占쏙옙占� 占쏙옙占쏙옙"));
 	const CNetworkInfo *pNetworkInfo = m_pSP2P->ISP2P_System_GetNetworkInfo();
 	if(pNetworkInfo == NULL) return;
 
@@ -3345,6 +3349,7 @@
 	if(pReviewProcessor == NULL) return;
 	
 	CString strPath = _T("");
+	CString strImagePath = _T("");
 	if(pNetworkInfo->m_strLocalImagePath.IsEmpty() == FALSE && strGlassID.IsEmpty() == FALSE)
 	{
 		CTime snapTime = CTime::GetCurrentTime();
@@ -3381,11 +3386,11 @@
 				Sleep(1000);
 				if (CDitGlassRawClient::GetInstance()->isConnect() == FALSE)
 				{
-					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]공유메모리 연결 실패 Count[%d]"), nReconnect);
+					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙 占쏙옙占쏙옙 Count[%d]"), nReconnect);
 				}
 				else
 				{
-					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]공유메모리 연결 성공"));
+					m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading]占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙 占쏙옙占쏙옙"));
 					break;
 				}
 				nReconnect += 1;
@@ -3400,25 +3405,29 @@
 		{
 			
 			strPath.Format(_T("%s\\%s_%04d%02d%02d%02d%02d%02d"), pNetworkInfo->m_strUploadImagePath, strGlassID, tmServerLoadingTime.GetYear(), tmServerLoadingTime.GetMonth(), tmServerLoadingTime.GetDay(), tmServerLoadingTime.GetHour(), tmServerLoadingTime.GetMinute(), tmServerLoadingTime.GetSecond());
+			strImagePath.Format(_T("%s_%04d%02d%02d%02d%02d%02d"), strGlassID, tmServerLoadingTime.GetYear(), tmServerLoadingTime.GetMonth(), tmServerLoadingTime.GetDay(), tmServerLoadingTime.GetHour(), tmServerLoadingTime.GetMinute(), tmServerLoadingTime.GetSecond());
 			CreateDirectory(strPath, NULL);
 			pReviewProcessor->SetUploadImagePath(strPath);
+			pReviewProcessor->SetReviewImagePath(strImagePath);
 		}
 		else
 		{
 			tmServerLoadingTime = CTime::GetCurrentTime();
-			m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading] 공유메모리 접근이상"));
+			m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::GlassLoading] 占쏙옙占쏙옙占쌨몌옙 占쏙옙占쏙옙占싱삼옙"));
 			strPath.Format(_T("%s\\%s_%04d%02d%02d%02d%02d%02d"), pNetworkInfo->m_strUploadImagePath, strGlassID, tmServerLoadingTime.GetYear(), tmServerLoadingTime.GetMonth(), tmServerLoadingTime.GetDay(), tmServerLoadingTime.GetHour(), tmServerLoadingTime.GetMinute(), tmServerLoadingTime.GetSecond());
+			strImagePath.Format(_T("%s\\%s_%04d%02d%02d%02d%02d%02d"), strGlassID, tmServerLoadingTime.GetYear(), tmServerLoadingTime.GetMonth(), tmServerLoadingTime.GetDay(), tmServerLoadingTime.GetHour(), tmServerLoadingTime.GetMinute(), tmServerLoadingTime.GetSecond());
 			CreateDirectory(strPath, NULL);
 			pReviewProcessor->SetUploadImagePath(strPath);
+			pReviewProcessor->SetReviewImagePath(strImagePath);
 		}
 
 	}
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 이미지 패스 만들기 끝"));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 占싱뱄옙占쏙옙 占싻쏙옙 占쏙옙占쏙옙占� 占쏙옙"));
 }
 
 void CSequenceProcessor_CPJT::SetSaveImageBasePathToAlignCameraControl(const CString& strGlassID)
 {
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 얼라인 이미지 패스 시작 "));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 占쏙옙占쏙옙占� 占싱뱄옙占쏙옙 占싻쏙옙 占쏙옙占쏙옙 "));
 	const CNetworkInfo *pNetworkInfo = m_pSP2P->ISP2P_System_GetNetworkInfo();
 	if(pNetworkInfo == NULL) return;
 
@@ -3431,7 +3440,7 @@
 		strPath.Format(_T("%s\\%s"), pNetworkInfo->m_strAlignImagePath, strGlassID);
 		pAlignCameraControl->SetSaveImageBasePath(strPath);
 	}
-	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 얼라인 이미지 패스 끝 "));
+	m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::Loading] 占쏙옙占쏙옙占� 占싱뱄옙占쏙옙 占싻쏙옙 占쏙옙 "));
 }
 
 BOOL CSequenceProcessor_CPJT::ReadRecipeDataFromRecipeFile(const CString& strPPID_RC, CString& strRecipeName)// const CString& strPPID, CString& strRecipeName
@@ -3498,14 +3507,14 @@
 {
 	if(pGlassResult == NULL) return FALSE;
 
-	// 레시피 설정
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	const CRsRcpReviewInfo* pRsRcpReviewInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpReviewInfo();
 	if (pRsRcpReviewInfo==NULL) return FALSE;
 
 	// system info
 	const CSystemInfo* pSystemInfo = m_pSP2P->ISP2P_System_GetSystemInfo();
 
-	// 글라스 정보
+	// 占쌜띰옙 占쏙옙占쏙옙
 	STransferData* pTransferData = m_pSP2P->ISP2P_GetCurrentTransferData();
 	if (pTransferData==NULL) return FALSE;
 	int nGlassTypeInfoIndex = 0;
@@ -3521,20 +3530,20 @@
 	if (pGlassTypeInfo == NULL) return FALSE;
 	m_pSP2P->ISP2P_DisplayMessage(_T("GlassTypeName : %s,GlassTypeIdx : %s"),pGlassTypeInfo->m_strGlassTypeName,pTransferData->strGlassScanSchedule);
 	
-	// 모터 정보
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙
 	const CMotorControlInfo *pMotorInfo = m_pSP2P->ISP2P_System_GetMotorInfo();
 
-	// 좌표 변환기
+	// 占쏙옙표 占쏙옙환占쏙옙
 	CCoordCalibrator* pCoordCalibrator = m_pSP2P->ISP2P_GetCoordCalibrator();
 
-	// 좌표계 설정
+	// 占쏙옙표占쏙옙 占쏙옙占쏙옙
 	if (pSystemInfo && pGlassTypeInfo && pMotorInfo && pCoordCalibrator)
 	{
 		// Get Direction		
 		int nDirectionX = GetDirectionX(pGlassTypeInfo->m_nOriginDirection, pMotorInfo->GetOriginDirection());
 		int nDirectionY = GetDirectionY(pGlassTypeInfo->m_nOriginDirection, pMotorInfo->GetOriginDirection());
 
-		// 좌표계 설정
+		// 占쏙옙표占쏙옙 占쏙옙占쏙옙
 		pCoordCalibrator->SetTransDirection(nDirectionX, nDirectionY);
 		pCoordCalibrator->SetOriginMotorPosition(pGlassTypeInfo->m_dOriginMotorX, pGlassTypeInfo->m_dOriginMotorY);
 		if (fabs(pGlassTypeInfo->m_dAlignAngle) > 0.0000001)
@@ -3543,7 +3552,7 @@
 				pGlassTypeInfo->m_dFirstAlignGlassX, pGlassTypeInfo->m_dFirstAlignGlassY, pGlassTypeInfo->m_dAlignAngle);
 		}
 
-		// 글라스 정보 설정
+		// 占쌜띰옙 占쏙옙占쏙옙 占쏙옙占쏙옙
 		pGlassResult->SetGlassSize(pGlassTypeInfo->m_nGlassSizeX * 1000, pGlassTypeInfo->m_nGlassSizeY * 1000);
 		pGlassResult->SetGlassOriginDirection(pGlassTypeInfo->m_nOriginDirection);
 		pGlassResult->SetCornerCutDirection(pGlassTypeInfo->m_nCornerCutDirection);
@@ -3552,34 +3561,34 @@
 		pGlassResult->SetCollisionDistanceX(int(pSystemInfo->m_dCollisionDistance*1000.));
 	}
 
-	// Align 정보
+	// Align 占쏙옙占쏙옙
 	const CRsRcpAlignInfo* pRsRcpAlignInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpAlignInfo();
 
-	// Align 정보 설정
+	// Align 占쏙옙占쏙옙 占쏙옙占쏙옙
 	if (pGlassTypeInfo && pRsRcpAlignInfo)
 	{
-		// Align 마크 정보 설정 (픽셀, 모터, 글라스 위치)
+		// Align 占쏙옙크 占쏙옙占쏙옙 占쏙옙占쏙옙 (占싫쇽옙, 占쏙옙占쏙옙, 占쌜띰옙 占쏙옙치)
 		pGlassResult->m_AlignRecipe.m_nUseAlignPosMove		= pGlassTypeInfo->m_nUseAlignPosMove;
 
-		// 픽셀 위치
+		// 占싫쇽옙 占쏙옙치
 		pGlassResult->m_AlignRecipe.dOriginPixelX[0]		= pGlassTypeInfo->m_nFirstAlignFindPixelX;
 		pGlassResult->m_AlignRecipe.dOriginPixelY[0]		= pGlassTypeInfo->m_nFirstAlignFindPixelY;
 		pGlassResult->m_AlignRecipe.dOriginPixelX[1]		= pGlassTypeInfo->m_nSecondAlignFindPixelX;
 		pGlassResult->m_AlignRecipe.dOriginPixelY[1]		= pGlassTypeInfo->m_nSecondAlignFindPixelY;
 
-		// 모터 위치
+		// 占쏙옙占쏙옙 占쏙옙치
 		pGlassResult->m_AlignRecipe.dOriginPositionX[0]		= pGlassTypeInfo->m_dFirstAlignMotorX;
 		pGlassResult->m_AlignRecipe.dOriginPositionY[0]		= pGlassTypeInfo->m_dFirstAlignMotorY;
 		pGlassResult->m_AlignRecipe.dOriginPositionX[1]		= pGlassTypeInfo->m_dSecondAlignMotorX;
 		pGlassResult->m_AlignRecipe.dOriginPositionY[1]		= pGlassTypeInfo->m_dSecondAlignMotorY;
 
-		// 글라스 위치
+		// 占쌜띰옙 占쏙옙치
 		pGlassResult->m_AlignRecipe.dGlassPositionX[0]		= pGlassTypeInfo->m_dFirstAlignGlassX;
 		pGlassResult->m_AlignRecipe.dGlassPositionY[0]		= pGlassTypeInfo->m_dFirstAlignGlassY;
 		pGlassResult->m_AlignRecipe.dGlassPositionX[1]		= pGlassTypeInfo->m_dSecondAlignGlassX;
 		pGlassResult->m_AlignRecipe.dGlassPositionY[1]		= pGlassTypeInfo->m_dSecondAlignGlassY;
 
-		// Align Recipe 정보 설정 자동광량 찾기 파라미터
+		// Align Recipe 占쏙옙占쏙옙 占쏙옙占쏙옙 占쌘듸옙占쏙옙占쏙옙 찾占쏙옙 占식띰옙占쏙옙占�
 		// Align Skip Mode
 		pGlassResult->m_AlignRecipe.bAlignSkipMode		= pRsRcpAlignInfo->m_bAlignSkipMode;
 		pGlassResult->m_AlignRecipe.bUseTotalPitchMeasure = pRsRcpAlignInfo->m_bTotalPitchMeasure;
@@ -3599,29 +3608,29 @@
 		pGlassResult->m_AlignRecipe.nMergeRange			= pRsRcpAlignInfo->m_nMergeRange;
 		pGlassResult->m_AlignRecipe.dEdgeRate			= pRsRcpAlignInfo->m_dEdgeRate;
 		
-		// 노출시간
+		// 占쏙옙占쏙옙챨占�
 		pGlassResult->m_AlignRecipe.bManualProcess			= pRsRcpAlignInfo->m_bManualProcess;
 		pGlassResult->m_AlignRecipe.dFirstCamExposure		= pRsRcpAlignInfo->m_dFirstCamExposure;
 		pGlassResult->m_AlignRecipe.dSecondCamExposure		= pRsRcpAlignInfo->m_dSecondCamExposure;
 
-		// 자동광량 조건
+		// 占쌘듸옙占쏙옙占쏙옙 占쏙옙占쏙옙
 		pGlassResult->m_AlignRecipe.bAutoProcess			= pRsRcpAlignInfo->m_bAutoProcess;
 		pGlassResult->m_AlignRecipe.dTargetMin				= pRsRcpAlignInfo->m_dTargetMin;
 		pGlassResult->m_AlignRecipe.dTargetMax				= pRsRcpAlignInfo->m_dTargetMax;
 		pGlassResult->m_AlignRecipe.dExposureMin			= pRsRcpAlignInfo->m_dExposureMin;
 		pGlassResult->m_AlignRecipe.dExposureMax			= pRsRcpAlignInfo->m_dExposureMax;
 
-		// Align Recipe 정보 설정 rotate info
+		// Align Recipe 占쏙옙占쏙옙 占쏙옙占쏙옙 rotate info
 		pGlassResult->m_AlignRecipe.bRotateProcess			= pRsRcpAlignInfo->m_bRotateProcess;
 		pGlassResult->m_AlignRecipe.nRetryCount				= pRsRcpAlignInfo->m_nRetryCount;
 		pGlassResult->m_AlignRecipe.dGlassAngleMin			= pRsRcpAlignInfo->m_dGlassAngleMin;
 		pGlassResult->m_AlignRecipe.dGlassAngleMax			= pRsRcpAlignInfo->m_dGlassAngleMax;
 
-		// Align 카메라 방향 및 해상도 설정		
+		// Align 카占쌨띰옙 占쏙옙占쏙옙 占쏙옙 占쌔삼옙 占쏙옙占쏙옙		
 		int nAlignCameraInfoCount = 2;
 		for(int nAlignCameraIdx = 0; nAlignCameraIdx < nAlignCameraInfoCount; nAlignCameraIdx++)
 		{
-			// Align 조명 값 가져오기.
+			// Align 占쏙옙占쏙옙 占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
 			int nLightValue = 0;
 			
 			
@@ -3629,10 +3638,10 @@
 			{
 				nLightValue = (nAlignCameraIdx==0) ? (int)pRsRcpAlignInfo->m_dFirstCamExposure: (int)pRsRcpAlignInfo->m_dSecondCamExposure;
 
-				// 얼라인 카메라 정보 가져오기 
+				// 占쏙옙占쏙옙占� 카占쌨띰옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 
 				const CAlignCameraInfo *pCameraInfo = m_pSP2P->ISP2P_System_GetAlignCameraInfo(nAlignCameraIdx);
 
-				 //조명값 변경.
+				 //占쏙옙占쏙옙占� 占쏙옙占쏙옙.
 				CLightControl *pLightControl = NULL;
 
 				const CLightControlInfo *AlignLightinfo = pCameraInfo->GetLightContorlInfo();
@@ -3641,8 +3650,8 @@
 				{
 					if (AlignLightinfo->GetMaster()==1&& nAlignCameraIdx==1)
 					{
-						//얼라인 컨틀롤러가 하나만 연결되어 있을때 마스터 여부로 확인 
-						//솔직히 이거 맞는지 모르겟다 아무도 안알랴쥼
+						//占쏙옙占쏙옙占� 占쏙옙틀占싼뤄옙占쏙옙 占싹놂옙占쏙옙 占쏙옙占쏙옙퓸占� 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占싸뤄옙 확占쏙옙 
+						//占쏙옙占쏙옙占쏙옙 占싱곤옙 占승댐옙占쏙옙 占쏜르겟댐옙 占싣뱄옙占쏙옙 占싫알뤄옙占쏙옙
 						pLightControl = m_pSP2P->ISP2P_GetAlignLightControl(0);
 
 					}
@@ -3677,7 +3686,7 @@
 			}
 			
 
-			// 얼라인 카메라 정보 가져오기 
+			// 占쏙옙占쏙옙占� 카占쌨띰옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 
 			const CAlignCameraInfo *pCameraInfo	= m_pSP2P->ISP2P_System_GetAlignCameraInfo(nAlignCameraIdx);
 			if (pCameraInfo)
 			{
@@ -3705,7 +3714,7 @@
 				}
 			}
 
-			// 얼라인 템플릿 정보 가져오기
+			// 占쏙옙占쏙옙占� 占쏙옙占시몌옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙
 			if((int)pGlassTypeInfo->m_vecTemplateImagePath.size() == nAlignCameraInfoCount)
 			{
 				pGlassResult->m_AlignRecipe.strTemplateName[nAlignCameraIdx] = pGlassTypeInfo->m_vecTemplateImagePath[nAlignCameraIdx];
@@ -3734,14 +3743,14 @@
 			if (pRcpReviewAFMInfo)
 			{
 				int nRealAFMIndex = pRcpReviewAFMInfo->m_nRecipeIndex;
-				if(nRealAFMIndex == -1)// 레시피에 선택된 배율의 실제 MagnificInfo Index를 알아옴
+				if(nRealAFMIndex == -1)// 占쏙옙占쏙옙占실울옙 占쏙옙占시듸옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 MagnificInfo Index占쏙옙 占싯아울옙
 				{
-					//-1의 경우 배율 인덱스 가져다 씀.
+					//-1占쏙옙 占쏙옙占� 占쏙옙占쏙옙 占싸듸옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙.
 					nRealAFMIndex = GetRealMagnification(nModuleIdx, pRcpReviewAFMInfo->m_nZoomIndex);
 				}
 				AFM_SetAFMRecipeName(nModuleIdx, strRecipeName, nRealAFMIndex);
 
-				if(pRcpReviewAFMInfo->m_bAFMHomeOffMode==TRUE) //190618AFM홈 시퀀스 진행 X
+				if(pRcpReviewAFMInfo->m_bAFMHomeOffMode==TRUE) //190618AFM홈 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 X
 				{
 					SetUseAfmHomePosition(FALSE);
 				}
@@ -3753,7 +3762,7 @@
 		}
 	}
 
-	// 결함 찾기 레시피 설정
+	// 占쏙옙占쏙옙 찾占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
 	CReviewProcessor* pReviewProcessor = m_pSP2P->ISP2P_GetReviewProcessor();
 	const CRsRcpDefectFindInfo* pRsRcpDefectFindInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpDefectFindInfo();
 	if(pReviewProcessor && pRsRcpDefectFindInfo)
@@ -3804,7 +3813,7 @@
 
 	CString strRawTDPath=_T(""), strRawCDPath=_T(""), strRawSDPath=_T("");
 
-	// 결과파일 이름 찾기
+	// 占쏙옙占쏙옙占쏙옙占� 占싱몌옙 찾占쏙옙
 	FindAOIRawFilePath(pGlassResult, &strRawTDPath, &strRawCDPath, &strRawSDPath);
 
 	bRet = m_pSP2P->ISP2P_ReadAOIRawFileToGlassResult(strRawTDPath);
@@ -3858,7 +3867,7 @@
 		if(finder.IsDots()) continue;
 		if(finder.IsDirectory()) continue;
 
-		// [2017:5:16]-[WEZASW] : AOI Server의 결함 파일 위치에 결함맵 이미지 파일 존재로 결합 파일만 추출
+		// [2017:5:16]-[WEZASW] : AOI Server占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙치占쏙옙 占쏙옙占쌉몌옙 占싱뱄옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占싹몌옙 占쏙옙占쏙옙
 		sRawFile.strFileName = finder.GetFileName();
 		strExtTemp = sRawFile.strFileName;
 		int nIdx = strExtTemp.Remove('.');		
@@ -4036,7 +4045,7 @@
 		CModuleStatus*					pModuleStatus	= Module_GetModuleStatus(nModuleIdx);		
 		if (pModuleStatus == NULL) continue;
 
-		//충돌거리 넣기
+		//占썸돌占신몌옙 占쌍깍옙
 		{
 
 		double dCollisionPosX = pReviewResult->GetCollisionPositionX() / 1000.0;
@@ -4077,13 +4086,13 @@
 
 		}
 
-		//좌우 겐트리 동시이동 
+		//占승울옙 占쏙옙트占쏙옙 占쏙옙占쏙옙占싱듸옙 
 		pMotorControl->GantrySetTwoGantrySyncModeSend(0);
 
 		// set result index
 		int nStartIdx = pReviewResult->GetStartSReviewResultIndex();
 		int nEndIdx = pReviewResult->GetEndSReviewResultIndex();
-		nEndIdx = min(nEndIdx, (pReviewResult->GetSReviewResultCount()-1)) + 1;		// End Index 다시설정
+		nEndIdx = min(nEndIdx, (pReviewResult->GetSReviewResultCount()-1)) + 1;		// End Index 占쌕시쇽옙占쏙옙
 
 		double xpostemp, ypostemp;
 		// get review pos
@@ -4093,7 +4102,7 @@
 			SReviewResult* pReview = pReviewResult->GetSReviewResult(nResultIdx);
 			if (pReview==NULL) continue;
 
-			//200개 어드레스를 보낸후 완료시점에서 중복체크
+			//200占쏙옙 占쏙옙藥뱄옙占쏙옙占� 占쏙옙占쏙옙占쏙옙 占싹뤄옙占쏙옙占쏙옙占쏙옙占� 占쌩븝옙체크
 			if (pReview->bCheckSendToMotor == FALSE)
 			{
 				pReview->bCheckSendToMotor = TRUE;
@@ -4140,7 +4149,7 @@
 			}
 		}
 
-		//보낼 포인트가 있는지 없는지 체크
+		//占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙 占쌍댐옙占쏙옙 占쏙옙占쏙옙占쏙옙 체크
 		if (vectorPosX.empty() ==TRUE)
 		{
 			g_pLog->DisplayMessage(_T("[GantryAutoGo] No Exist Send Point "), vectorPosX.size());
@@ -4172,13 +4181,13 @@
 			int nTickCount = GetTickCount();
 			while (1)
 			{
-				//5초 오버타임
+				//5占쏙옙 占쏙옙占쏙옙타占쏙옙
 				if ((GetTickCount() - nTickCount) > 5000)
 				{
 					bOverTime = TRUE;
 					break;
 				}
-				//모터 모션 End 체크 
+				//占쏙옙占쏙옙 占쏙옙占� End 체크 
 				if (pMotorControl->IsGantryMotionEnd(pModuleStatus->GetGantryIndex()) == TRUE)
 				{
 					if (pMotorControl->GantryAutoGo(pModuleStatus->GetGantryIndex(), vectorPosX, vectorPosY, TRUE))
@@ -4197,15 +4206,15 @@
 
 			}
 
-			//5초후에도 안움직인다? 그럼 3번 재시도 ㄱㄱ
-			//모션End 가 잘못 나올수도 있으니
+			//5占쏙옙占식울옙占쏙옙 占싫울옙占쏙옙占싸댐옙? 占쌓뤄옙 3占쏙옙 占쏙옙천占� 占쏙옙占쏙옙
+			//占쏙옙占폜nd 占쏙옙 占쌩몌옙 占쏙옙占시쇽옙占쏙옙 占쏙옙占쏙옙占쏙옙
 			if (bOverTime == TRUE)
 			{
 				for (int i = 0; i < 3; i++)
 				{
 					Sleep(1000);
 
-					//모터가 움직일수 없는상태일때 Send 신호시 Fail 발생 가능 Retry 3번 ㄱㄱ 
+					//占쏙옙占싶곤옙 占쏙옙占쏙옙占싹쇽옙 占쏙옙占승삼옙占쏙옙占싹띰옙 Send 占쏙옙호占쏙옙 Fail 占쌩삼옙 占쏙옙占쏙옙 Retry 3占쏙옙 占쏙옙占쏙옙 
 					if (pMotorControl->GantryAutoGo(pModuleStatus->GetGantryIndex(), vectorPosX, vectorPosY, TRUE))
 					{
 						nTotalCount += (int)vectorPosX.size();
@@ -4279,7 +4288,7 @@
 	if(pGlassResult && pReviewProcessor)
 	{
 		// UserStart
-		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	//pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 변경
+		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	//pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 占쏙옙占쏙옙
 		pReviewProcessor->SetOperID(pGlassResult->m_strOperID);
 		m_pSP2P->ISP2P_UpdateReviewProcessStatus(ReviewProcessStatus_UserStart, nPlanIndex);
 
@@ -4342,7 +4351,7 @@
 		CModuleStatus*					pModuleStatus = Module_GetModuleStatus(nModuleIdx);
 		if (pModuleStatus == NULL) continue;
 
-		//충돌거리 넣기
+		//占썸돌占신몌옙 占쌍깍옙
 		{
 
 			double dCollisionPosX = pReviewResult->GetCollisionPositionX() / 1000.0;
@@ -4385,9 +4394,9 @@
 		// set result index
 		int nStartIdx = pReviewResult->GetStartSReviewResultIndex();
 		int nEndIdx = pReviewResult->GetEndSReviewResultIndex();
-		nEndIdx = min(nEndIdx, (pReviewResult->GetSReviewResultCount() - 1)) + 1;		// End Index 다시설정
+		nEndIdx = min(nEndIdx, (pReviewResult->GetSReviewResultCount() - 1)) + 1;		// End Index 占쌕시쇽옙占쏙옙
 
-		// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+		// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 		double m_dMinOffset = -5.0;
 		double m_dMaxOffset = 5.0;
 		double xpostemp, ypostemp;
@@ -4398,7 +4407,7 @@
 			SReviewResult* pReview = pReviewResult->GetSReviewResult(nResultIdx);
 			if (pReview == NULL) continue;
 
-			//200개 어드레스를 보낸후 완료시점에서 중복체크
+			//200占쏙옙 占쏙옙藥뱄옙占쏙옙占� 占쏙옙占쏙옙占쏙옙 占싹뤄옙占쏙옙占쏙옙占쏙옙占� 占쌩븝옙체크
 			if (pReview->bCheckSendToMotor == FALSE)
 			{
 				pReview->bCheckSendToMotor = TRUE;
@@ -4446,7 +4455,7 @@
 			}
 		}
 
-		//보낼 포인트가 있는지 없는지 체크
+		//占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙 占쌍댐옙占쏙옙 占쏙옙占쏙옙占쏙옙 체크
 		if (vectorPosX.empty() == TRUE)
 		{
 			g_pLog->DisplayMessage(_T("[GantryAutoGo] No Exist Send Point "), vectorPosX.size());
@@ -4511,7 +4520,7 @@
 	if(pGlassResult && pReviewProcessor)
 	{
 		// WsiStart
-		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 변경
+		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 占쏙옙占쏙옙
 		pReviewProcessor->SetOperID(pGlassResult->m_strOperID);
 		m_pSP2P->ISP2P_UpdateReviewProcessStatus(ReviewProcessStatus_WSIStart, nPlanIndex);
 
@@ -4524,7 +4533,7 @@
 		MakeWSIUpLoadDirectory(pReviewProcessor->GetUploadImagePath());
 
 		//20190219 chm 
-		pReviewProcessor->SetReviewCount(0);			// 리뷰 Sequence No 초기화.
+		pReviewProcessor->SetReviewCount(0);			// 占쏙옙占쏙옙 Sequence No 占십깍옙화.
 
 		return TRUE;
 	}	
@@ -4537,7 +4546,7 @@
 	strPath  = strPath + _T("\\WSI");
 	if(CreateDirectory(strPath,NULL)==FALSE)
 	{
-		//LYW LOG추가
+		//LYW LOG占쌩곤옙
 		g_pLog->DisplayMessage(_T("[MakeWSIUpLoadDirectory]Directory Create Fail %s, ERROR CODE = %d "),strPath, GetLastError());
 	}
 	
@@ -4578,7 +4587,7 @@
 	VectorDouble vectorCollisionPosX;
 	vectorCollisionPosX.clear();
 
-	//WSI 좌우 겐트리 동시이동 
+	//WSI 占승울옙 占쏙옙트占쏙옙 占쏙옙占쏙옙占싱듸옙 
 	pMotorControl->GantrySetTwoGantrySyncModeSend(1);
 	
 
@@ -4592,7 +4601,7 @@
 		CModuleStatus*					pModuleStatus = Module_GetModuleStatus(nModuleIdx);
 		if (pModuleStatus == NULL) continue;
 
-		//충돌거리 넣기
+		//占썸돌占신몌옙 占쌍깍옙
 		{
 			double dCollisionPosX = pWsiResult->GetCollisionPositionX() / 1000.0;
 			double dCollisionPosY = 0.0;
@@ -4634,7 +4643,7 @@
 		int nEndIdx = pWsiResult->GetEndSReviewResultIndex();
 		nEndIdx = min(nEndIdx, (pWsiResult->GetSReviewResultCount() - 1)) + 1;		// set End Index 
 
-		// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+		// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 		double m_dMinOffset = -5.0;
 		double m_dMaxOffset = 5.0;
 
@@ -4646,7 +4655,7 @@
 			SReviewResult* pWsi = pWsiResult->GetSReviewResult(nResultIdx);
 			if (pWsi == NULL) continue;
 
-			//200개 어드레스를 보낸후 완료시점에서 중복체크
+			//200占쏙옙 占쏙옙藥뱄옙占쏙옙占� 占쏙옙占쏙옙占쏙옙 占싹뤄옙占쏙옙占쏙옙占쏙옙占� 占쌩븝옙체크
 			if (pWsi->bCheckWSISendToMotor == FALSE)
 			{
 				pWsi->bCheckWSISendToMotor = TRUE;
@@ -4693,14 +4702,14 @@
 			}
 		}
 
-		//보낼 포인트가 있는지 없는지 체크
+		//占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙 占쌍댐옙占쏙옙 占쏙옙占쏙옙占쏙옙 체크
 		if (vectorPosX.empty() == TRUE)
 		{
-			//3360 LYW_ CF AOI QD Review WSI XY MotorMoving Error 알람 발생 원인 분석 및 조치 START
+			//3360 LYW_ CF AOI QD Review WSI XY MotorMoving Error 占싯띰옙 占쌩삼옙 占쏙옙占쏙옙 占싻쇽옙 占쏙옙 占쏙옙치 START
 			g_pLog->DisplayMessage(_T("[GantryAutoGo] No Exist Send Point,TwoGantrySyncMode OFF!"), vectorPosX.size());
 			g_pLog->DisplayMessage(_T("[GantryAutoGo] (%d)Gantry Path Send Fail"), pModuleStatus->GetGantryIndex()); //taek 210128
 			pMotorControl->GantrySetTwoGantrySyncModeSend(0);
-			//3360 LYW_ CF AOI QD Review WSI XY MotorMoving Error 알람 발생 원인 분석 및 조치 END
+			//3360 LYW_ CF AOI QD Review WSI XY MotorMoving Error 占싯띰옙 占쌩삼옙 占쏙옙占쏙옙 占싻쇽옙 占쏙옙 占쏙옙치 END
 		}
 		else
 		{
@@ -4724,13 +4733,13 @@
 				int nTickCount = GetTickCount();
 				while (1)
 				{
-					//5초 오버타임
+					//5占쏙옙 占쏙옙占쏙옙타占쏙옙
 					if ((GetTickCount() - nTickCount) > 5000)
 					{
 						bOverTime = TRUE;
 						break;
 					}
-					//모터 모션 End 체크 
+					//占쏙옙占쏙옙 占쏙옙占� End 체크 
 					if (pMotorControl->IsGantryMotionEnd(pModuleStatus->GetGantryIndex()) == TRUE)
 					{
 						if (pMotorControl->GantryAutoGo(pModuleStatus->GetGantryIndex(), vectorPosX, vectorPosY, TRUE))
@@ -4749,15 +4758,15 @@
 
 				}
 
-				//5초후에도 안움직인다? 그럼 3번 재시도 ㄱㄱ
-				//모션End 가 잘못 나올수도 있으니
+				//5占쏙옙占식울옙占쏙옙 占싫울옙占쏙옙占싸댐옙? 占쌓뤄옙 3占쏙옙 占쏙옙천占� 占쏙옙占쏙옙
+				//占쏙옙占폜nd 占쏙옙 占쌩몌옙 占쏙옙占시쇽옙占쏙옙 占쏙옙占쏙옙占쏙옙
 				if (bOverTime == TRUE)
 				{
 					for (int i = 0; i < 3; i++)
 					{
 						Sleep(1000);
 
-						//모터가 움직일수 없는상태일때 Send 신호시 Fail 발생 가능 Retry 3번 ㄱㄱ 
+						//占쏙옙占싶곤옙 占쏙옙占쏙옙占싹쇽옙 占쏙옙占승삼옙占쏙옙占싹띰옙 Send 占쏙옙호占쏙옙 Fail 占쌩삼옙 占쏙옙占쏙옙 Retry 3占쏙옙 占쏙옙占쏙옙 
 						if (pMotorControl->GantryAutoGo(pModuleStatus->GetGantryIndex(), vectorPosX, vectorPosY, TRUE))
 						{
 							nTotalCount += (int)vectorPosX.size();
@@ -4892,9 +4901,9 @@
 		// get result index
 		int nStartIdx = pReviewResult->GetStartSReviewResultIndex();
 		int nEndIdx = pReviewResult->GetEndSReviewResultIndex();
-		nEndIdx = min(nEndIdx, (pReviewResult->GetSReviewResultCount()-1)) + 1;		// End Index 다시설정
+		nEndIdx = min(nEndIdx, (pReviewResult->GetSReviewResultCount()-1)) + 1;		// End Index 占쌕시쇽옙占쏙옙
 
-		// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+		// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 		double m_dMinOffset = -5.0; 
 		double m_dMaxOffset = 5.0;
 
@@ -4996,7 +5005,7 @@
 	if(pGlassResult && pReviewProcessor)
 	{
 		// MeasureStart
-		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 변경
+		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 占쏙옙占쏙옙
 		pReviewProcessor->SetOperID(pGlassResult->m_strOperID);
 		m_pSP2P->ISP2P_UpdateReviewProcessStatus(ReviewProcessStatus_MeasureStart, nPlanIndex);
 
@@ -5071,7 +5080,7 @@
 				const SCoordInfo* pCoordInfo = Module_GetCoordInfo(nModuleIdx);
 				if(pCoordInfo == NULL) continue;	
 
-				// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+				// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 				double m_dMinOffset = -5.0; 
 				double m_dMaxOffset = 5.0;
 
@@ -5177,7 +5186,7 @@
 	int nTotalCount = 0;
 	double dDefectPosX, dDefectPosY;
 
-	// Module의 위치에 따른 ModuleStatus sorting
+	// Module占쏙옙 占쏙옙치占쏙옙 占쏙옙占쏙옙 ModuleStatus sorting
 	std::vector<CModuleStatus*> SortedModuleStatus;
 	for(int nModuleIdx = 0; nModuleIdx < m_pSP2P->ISP2P_GetModuleStatusCount(); nModuleIdx++)
 	{
@@ -5231,7 +5240,7 @@
 				const SCoordInfo* pCoordInfo = Module_GetCoordInfo(pReviewResult->GetModuleIndex());
 				if(pCoordInfo == NULL) continue;				
 
-				// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+				// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 				double m_dMinOffset = -5.0; 
 				double m_dMaxOffset = 5.0;
 
@@ -5252,7 +5261,7 @@
 
 				if(nHeaderIdx == 0)
 				{
-					// 이동할 모터좌표 추가
+					// 占싱듸옙占쏙옙 占쏙옙占쏙옙占쏙옙표 占쌩곤옙
 					if((int)vectorPos.size() < MAX_MOTOR_ADDRESS_SIZE)
 					{
 						pSReviewResult->dTargetMotorX = dDefectPosX;
@@ -6521,7 +6530,7 @@
 			// add user schedule result
 			
 			
-			//공유메모리에 채워줄 리뷰할 갯수와 디펙 좌표를 구조체에 채워주는 장소  
+			//占쏙옙占쏙옙占쌨모리울옙 채占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙표占쏙옙 占쏙옙占쏙옙체占쏙옙 채占쏙옙占쌍댐옙 占쏙옙占�  
 			{
 
 
@@ -7236,7 +7245,7 @@
 				break;
 			}
 			break;
-		// 미사용
+		// 占싱삼옙占�
 		case CPJT_PlanMeasure:
 			{
 				const CRcpMeasureInfo *pRcpMeasureInfo = pRsRcpMeasureInfo->GetRcpMeasureInfo(0);
@@ -7369,7 +7378,7 @@
 }
 
 //CIM DV Data
-BOOL CSequenceProcessor_CPJT::SendDVDataToSignalControl() // 수정
+BOOL CSequenceProcessor_CPJT::SendDVDataToSignalControl() // 占쏙옙占쏙옙
 {
 	CGlassResult *pGlassResult = m_pSP2P->ISP2P_GetCurrentGlassResult();
 	if (pGlassResult==NULL) return FALSE;
@@ -7394,7 +7403,7 @@
 }
 
 
-int CSequenceProcessor_CPJT::MakeDVData(CGlassResult *pGlassResult, char* pDVData, int nIndex) // 수정
+int CSequenceProcessor_CPJT::MakeDVData(CGlassResult *pGlassResult, char* pDVData, int nIndex) // 占쏙옙占쏙옙
 {
 	g_pLog->DisplayMessage(_T("[SequenceProcessor] SendDVDataToSignalControl->MakeDVData IN."));
 
@@ -7403,16 +7412,16 @@
 	const CRsRcpReviewInfo* pRsRcpReviewInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpReviewInfo();
 	if (pRsRcpReviewInfo == NULL) return FALSE;
 
-	// Review 조명 정보
+	// Review 占쏙옙占쏙옙 占쏙옙占쏙옙
 	const CRcpLightInfo *pReviewLightInfo = pRsRcpReviewInfo->GetRcpLightInfo(nIndex);
-	// Review AFM 정보
+	// Review AFM 占쏙옙占쏙옙
 	const CRcpAFMRecipeInfo *pReviewAFMInfo = pRsRcpReviewInfo->GetRcpAFMRecipeInfo(nIndex);
 	// Review Align Info
 	const CAlignResult*	pAlignResult = pGlassResult->GetAlignResult();
 	// Review Defect Info
 	const CReviewResult* pReviewResult = pGlassResult->GetReviewResult(nIndex);
 
-	// Review 배율 정보
+	// Review 占쏙옙占쏙옙 占쏙옙占쏙옙
 	const CModuleStatus* pModuleStatus = Module_GetModuleStatus(nIndex);
 	const SMagnificInfo* pSMagnificInfo = pModuleStatus->GetMagnificInfo(pReviewAFMInfo->GetZoomIndex());
 	CSignalControl* pSignalControl = m_pSP2P->ISP2P_GetSignalControl();
@@ -7434,12 +7443,12 @@
 	// Write DVData Packet
 	//_DVDataPack_B7_8ver DVDataPack;
 	//**Review
-	//INLINE  : 10개 
-	//TFE-OFF : 20개 
-	//Hcut : 50개 
-	//LAMI : 5개 
+	//INLINE  : 10占쏙옙 
+	//TFE-OFF : 20占쏙옙 
+	//Hcut : 50占쏙옙 
+	//LAMI : 5占쏙옙 
 	//**WSI
-	//10개 고정 
+	//10占쏙옙 占쏙옙占쏙옙 
 	///////////////////////////////////////////////////////////////////////////
 
 
@@ -7486,8 +7495,8 @@
 	//nAlignResult = 1;
 
 	
-	//nAlignResult00 = pAlignResult->nFindAlign[0] * 1000;//기준 
-	//nAlignResult01 = pAlignResult->nFindAlign[1] * 1000;//보조
+	//nAlignResult00 = pAlignResult->nFindAlign[0] * 1000;//占쏙옙占쏙옙 
+	//nAlignResult01 = pAlignResult->nFindAlign[1] * 1000;//占쏙옙占쏙옙
 
 	//nAlignResult00 = pAlignResult->dFindScore[0];
 	//nAlignResult01 = pAlignResult->dFindScore[1];
@@ -7505,7 +7514,7 @@
 		nAlignResult01 = 0;
 	}
 
-	//파워?
+	//占식울옙?
 	nReviewAliveCamera00 = ReviewCamera_GetReviewCameraControl(0)->GetConnected() * 1000;
 	nReviewAliveCamera01 = ReviewCamera_GetReviewCameraControl(1)->GetConnected() * 1000;
 
@@ -7523,7 +7532,7 @@
 		wsprintf(DriveText, TEXT("%C:"), Drive);
 		UINT type = GetDriveType(DriveText);
 		if ((dwDrive & dwDriveCh) && (type == DRIVE_REMOVABLE || type == DRIVE_FIXED || type == DRIVE_RAMDISK)) {
-			// 하드용량         
+			// 占싹듸옙酉�         
 			ULARGE_INTEGER i64FreeBytesToCaller = { 0 }, i64TotalBytes = { 0 }, i64FreeBytes = { 0 };
 			BOOL bRsult = GetDiskFreeSpaceEx(DriveText, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes);
 			if (bRsult) {
@@ -7737,7 +7746,7 @@
 	pSignalControl->WritePacketData(_T("15100"), sizeof(DVDataPack_CPJT), (short*)&DVData);*/
 }
 
-//#3358 KYH FDC 데이터 전송 시점 개선 ADD START
+//#3358 KYH FDC 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 ADD START
 void CSequenceProcessor_CPJT::MakeDVData2()
 {
 
@@ -7750,9 +7759,9 @@
 	}
 	else
 	{
-	// Review 조명 정보
+	// Review 占쏙옙占쏙옙 占쏙옙占쏙옙
 		pReviewLightInfo = pRsRcpReviewInfo->GetRcpLightInfo(0);
-	// Review AFM 정보
+	// Review AFM 占쏙옙占쏙옙
 		pReviewAFMInfo = pRsRcpReviewInfo->GetRcpAFMRecipeInfo(0);
 	}
 
@@ -7776,7 +7785,7 @@
 
 
 
-	// Review 배율 정보
+	// Review 占쏙옙占쏙옙 占쏙옙占쏙옙
 	const CModuleStatus* pModuleStatus = Module_GetModuleStatus(0);
 	const SMagnificInfo* pSMagnificInfo = NULL;
 	if (pModuleStatus == NULL)
@@ -7878,8 +7887,8 @@
 	//nAlignResult = 1;
 
 
-	//nAlignResult00 = pAlignResult->nFindAlign[0] * 1000;//기준 
-	//nAlignResult01 = pAlignResult->nFindAlign[1] * 1000;//보조
+	//nAlignResult00 = pAlignResult->nFindAlign[0] * 1000;//占쏙옙占쏙옙 
+	//nAlignResult01 = pAlignResult->nFindAlign[1] * 1000;//占쏙옙占쏙옙
 
 	//nAlignResult00 = pAlignResult->dFindScore[0];
 	//nAlignResult01 = pAlignResult->dFindScore[1];
@@ -7919,7 +7928,7 @@
 		nAlignResult01 = 1000;
 	}
 
-	//파워?
+	//占식울옙?
 	if (ReviewCamera_GetReviewCameraControl(0) != NULL)
 	{
 		nReviewAliveCamera00 = ReviewCamera_GetReviewCameraControl(0)->GetConnected() * 1000;
@@ -7952,7 +7961,7 @@
 		wsprintf(DriveText, TEXT("%C:"), Drive);
 		UINT type = GetDriveType(DriveText);
 		if ((dwDrive & dwDriveCh) && (type == DRIVE_REMOVABLE || type == DRIVE_FIXED || type == DRIVE_RAMDISK)) {
-			// 하드용량         
+			// 占싹듸옙酉�         
 			ULARGE_INTEGER i64FreeBytesToCaller = { 0 }, i64TotalBytes = { 0 }, i64FreeBytes = { 0 };
 			BOOL bRsult = GetDiskFreeSpaceEx(DriveText, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes);
 			if (bRsult) {
@@ -7999,7 +8008,7 @@
 
 	return;
 }
-//#3358 KYH FDC 데이터 전송 시점 개선 ADD END
+//#3358 KYH FDC 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙 ADD END
 
 DWORD CSequenceProcessor_CPJT::GetDiskUsage()
 {
@@ -8037,7 +8046,7 @@
 
 	BOOL bResult = FALSE;
 
-	// PCControl D2300 (검사 영역)
+	// PCControl D2300 (占싯삼옙 占쏙옙占쏙옙)
 	switch(nSignalIndex)
 	{
 	case PCControlRecv_TimeChange:
@@ -8103,7 +8112,7 @@
  		g_pLog->DisplayMessage(_T("[SequenceProcessor] Success! SetLocalTime(), Current: %04d-%02d-%02d %02d-%02d-%02d, Changed: %04d-%02d-%02d %02d-%02d-%02d"), 
 			CurrentTime.wYear, CurrentTime.wMonth, CurrentTime.wDay, CurrentTime.wHour, CurrentTime.wMinute, CurrentTime.wSecond,
 			ChangedTime.wYear, ChangedTime.wMonth, ChangedTime.wDay, ChangedTime.wHour, ChangedTime.wMinute, ChangedTime.wSecond);
-		// AFM & WSI TIME 동기화
+		// AFM & WSI TIME 占쏙옙占쏙옙화
 		SendSystemTime(ChangedTime);
 	} else {
  		g_pLog->DisplayMessage(_T("[SequenceProcessor] Fail! SetLocalTime()"));
@@ -8130,7 +8139,7 @@
 	return TRUE;
 }
 
-// Local System 변경 시간과 변경 요청 컨트롤러의 시간차 처리 생각
+// Local System 占쏙옙占쏙옙 占시곤옙占쏙옙 占쏙옙占쏙옙 占쏙옙청 占쏙옙트占싼뤄옙占쏙옙 占시곤옙占쏙옙 처占쏙옙 占쏙옙占쏙옙
 BOOL CSequenceProcessor_CPJT::SendSystemTime(SYSTEMTIME sysTime)
 {
 	SYSTEMTIME CurrentTime;
@@ -8277,7 +8286,7 @@
 			case PCControlSend_Defoucs:
 				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Send] Defoucs! => %d"),0);
 				break;
-			case PCControlSend_Diagnosis: // 0412 자가진단 신호 추가
+			case PCControlSend_Diagnosis: // 0412 占쌘곤옙占쏙옙占쏙옙 占쏙옙호 占쌩곤옙
 				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Send] Diagnosis! => %d"), 0);
 				break;
 			}
@@ -8388,7 +8397,7 @@
 			case PCControlSend_Defoucs:
 				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Send] Defoucs! => %d"),0);
 				break;
-			case PCControlSend_Diagnosis: // 0412 자가진단 신호 추가
+			case PCControlSend_Diagnosis: // 0412 占쌘곤옙占쏙옙占쏙옙 占쏙옙호 占쌩곤옙
 				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Send] Diagnosis! => %d"), 0);
 				break;
 			}
@@ -8502,7 +8511,7 @@
 			if (bResult==FALSE) m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Mode] Manual Mode Error!"));
 
 			// lmk simul manual camera,motor stop
-			//ReviewCamera_CameraControl(CameraControlStop);	// 모터 멈추면 카메라 자동 스탑
+			//ReviewCamera_CameraControl(CameraControlStop);	// 占쏙옙占쏙옙 占쏙옙占쌩몌옙 카占쌨띰옙 占쌘듸옙 占쏙옙탑
 			CMotorControl*  pMotorControl = m_pSP2P->ISP2P_GetMotorControl();
 			if(pMotorControl)
 				pMotorControl->CommonSetAutoStop();
@@ -8673,10 +8682,10 @@
 
 			if (SetLocalTime(&sTime))
 			{
-				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Signal] 시간동기화성공 %s"), strtime);
+				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Signal] 占시곤옙占쏙옙占쏙옙화占쏙옙占쏙옙 %s"), strtime);
 			}
 			else
-				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Signal] 시간동기화실패 %s"), strtime);
+				m_pSP2P->ISP2P_DisplayMessage(_T("[PCControl_Signal] 占시곤옙占쏙옙占쏙옙화占쏙옙占쏙옙 %s"), strtime);
 
 
 			//memcpy(&time, strTime, 2);
@@ -8897,7 +8906,7 @@
 	CReviewResult* pWsiMultiShotResult = pGlassResult->GetWsiMultiShotResult(nModuleIndex);
 	if (pWsiMultiShotResult == NULL) goto RESULT_FAIL;
 
-	// 마지막 인덱스를 가져온다.
+	// 占쏙옙占쏙옙占쏙옙 占싸듸옙占쏙옙占쏙옙 占쏙옙占쏙옙占승댐옙.
 	int nCurResultIdx = pWsiMultiShotResult->GetLastSReviewResultIndex() + 1; // last index + 1
 	int nStartResultIdx = pWsiMultiShotResult->GetStartSReviewResultIndex();
 	int nEndResultIdx = pWsiMultiShotResult->GetEndSReviewResultIndex();
@@ -8911,13 +8920,13 @@
 	int		nMPosY = int(pPosition->dMotorPosY * 1000.0);
 	double	dTime = (double)m_ProcessTimer.GetDurationMilliSecond();
 
-	// 인덱스가 다르면 비정상임.
+	// 占싸듸옙占쏙옙占쏙옙 占쌕몌옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
 	if (measureResut.nResultIndex != nCurResultIdx)
 	{
 		goto RESULT_FAIL;
 	}
 
-	// 현재 데이터 저장.
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙.
 	// measureResut
 
 	if (pWsiMultiShotResult->GetSReviewResultCount() == 0) return;
@@ -8942,7 +8951,7 @@
 	// set last result idx
 	pWsiMultiShotResult->SetLastSReviewResultIndex(nCurResultIdx);
 
-	// 마지막 포인트까지 왔고, WSI 결과가 남아 있으면...
+	// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트占쏙옙占쏙옙 占쌉곤옙, WSI 占쏙옙占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙...
 	if (nCurResultIdx == nEndResultIdx && nCurResultIdx <= pWsiMultiShotResult->GetSReviewResultCount())
 	{
 		nStartResultIdx = nCurResultIdx + 1;
@@ -8953,8 +8962,8 @@
 		pWsiMultiShotResult->SetStartSReviewResultIndex(nStartResultIdx);
 		pWsiMultiShotResult->SetEndSReviewResultIndex(nEndResultIdx);
 
-		// 나머지 포인트 리뷰 수행하자.
-		::Sleep(3000); // 딜레이는 필수임. 없으면 동작 안함.
+		// 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙트 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙.
+		::Sleep(3000); // 占쏙옙占쏙옙甄占� 占십쇽옙占쏙옙. 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占쏙옙.
 	//	Process_RemainWsiPoint(nModuleIndex);
 	}
 
@@ -9020,7 +9029,7 @@
 	if(pGlassResult && pReviewProcessor)
 	{
 		// WsiStart
-		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 변경
+		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 占쏙옙占쏙옙
 		pReviewProcessor->SetOperID(pGlassResult->m_strOperID);
 		m_pSP2P->ISP2P_UpdateReviewProcessStatus(ReviewProcessStatus_WSIReflowStart, nPlanIndex);
 
@@ -9056,7 +9065,7 @@
 	if(pGlassResult && pReviewProcessor)
 	{
 		// WsiStart
-		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 변경
+		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 占쏙옙占쏙옙
 		pReviewProcessor->SetOperID(pGlassResult->m_strOperID);
 		m_pSP2P->ISP2P_UpdateReviewProcessStatus(ReviewProcessStatus_WSIStart, nPlanIndex);
 
@@ -9083,7 +9092,7 @@
 	WSIAllReadySignal(1);
 
 	// send wsi start
-	// 수정 사항 
+	// 占쏙옙占쏙옙 占쏙옙占쏙옙 
 	if (!WSIMultiShotAllStartSignal())
 	{
 		g_pLog->DisplayMessage(_T("[WSI] WSI MultiShot Start Fail!!"));
@@ -9094,7 +9103,7 @@
 	if (pGlassResult && pReviewProcessor)
 	{
 		// WsiStart
-		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 변경
+		pReviewProcessor->SetJobID(pGlassResult->m_strJobID);	// pGlassResult->m_strGlassID -> pGlassResult->m_strJobID 占쏙옙占쏙옙
 		pReviewProcessor->SetOperID(pGlassResult->m_strOperID);
 		m_pSP2P->ISP2P_UpdateReviewProcessStatus(ReviewProcessStatus_WSIMultiShotStart, nPlanIndex);
 
@@ -9157,7 +9166,7 @@
 		int nEndIdx = pWsiResult->GetEndSReviewResultIndex();
 		nEndIdx = min(nEndIdx, (pWsiResult->GetSReviewResultCount()-1)) + 1;		// set End Index 
 
-		// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+		// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 		double m_dMinOffset = -5.0; 
 		double m_dMaxOffset = 5.0;
 
@@ -9287,7 +9296,7 @@
 		CModuleStatus*					pModuleStatus	= Module_GetModuleStatus(nModuleIdx);		
 		if (pModuleStatus == NULL) continue;
 
-		//충돌거리 넣기
+		//占썸돌占신몌옙 占쌍깍옙
 		{
 			double dCollisionPosX = pWsiUserResult->GetCollisionPositionX() / 1000.0;
 			double dCollisionPosY = 0.0;
@@ -9330,7 +9339,7 @@
 		int nEndIdx = pWsiUserResult->GetEndSReviewResultIndex();
 		nEndIdx = min(nEndIdx, (pWsiUserResult->GetSReviewResultCount()-1)) + 1;		// set End Index 
 
-		// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+		// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 		double m_dMinOffset = -5.0; 
 		double m_dMaxOffset = 5.0;
 
@@ -9434,16 +9443,16 @@
 		
 		}
 
-		//기존꺼 삭제 
+		//占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙 
 		pWsiMultiShotResult->GetVectorSReviewResult()->clear();
 		int nResultCount = 0;
 		if (m_vecSReviewResult.size()>0)
 		{	
-			//스케줄링 순서 대로 집어넣은거라 걍 집어넣기 ㄱㄱ
+			//占쏙옙占쏙옙占쌕몌옙 占쏙옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙占쏙옙占쏙옙킷占� 占쏙옙 占쏙옙占쏙옙殮占� 占쏙옙占쏙옙
 			for(int i=0; i< m_vecSReviewResult.size(); i++)
 			{
-				//원래는 세팅에 분할 갯수 입력해야됨 그것만큼 돌리기!
-				//지금은 WSI FOV 4분할 기준에서 ㄱㄱ 
+				//占쏙옙占쏙옙占쏙옙 占쏙옙占시울옙 占쏙옙占쏙옙 占쏙옙占쏙옙 占쌉뤄옙占쌔야듸옙 占쌓것몌옙큼 占쏙옙占쏙옙占쏙옙!
+				//占쏙옙占쏙옙占쏙옙 WSI FOV 4占쏙옙占쏙옙 占쏙옙占쌔울옙占쏙옙 占쏙옙占쏙옙 
 				double dOringinX = m_vecSReviewResult[i].nUMOriginX;
 				double dOringinY = m_vecSReviewResult[i].nUMOriginY;
 
@@ -9713,7 +9722,7 @@
 		if (pModuleStatus == NULL) continue;
 
 
-		//충돌거리 넣기
+		//占썸돌占신몌옙 占쌍깍옙
 		{
 
 			double dCollisionPosX = pWsiMultiShotResult->GetCollisionPositionX() / 1000.0;
@@ -9741,7 +9750,7 @@
 			int nEndIdx = pWsiMultiShotResult->GetEndSReviewResultIndex();
 			nEndIdx = min(nEndIdx, (pWsiMultiShotResult->GetSReviewResultCount() - 1)) + 1;		// set End Index 
 
-			// [2017:3:8]-[WEZASW] : CameraOffset 범위 변경 (-1~1 => -5~5)
+			// [2017:3:8]-[WEZASW] : CameraOffset 占쏙옙占쏙옙 占쏙옙占쏙옙 (-1~1 => -5~5)
 			double m_dMinOffset = -5.0;
 			double m_dMaxOffset = 5.0;
 
@@ -10182,7 +10191,7 @@
 	CRsRcpReviewInfo* pRsRcpReviewInfo = m_pSP2P->ISP2P_Recipe_GetRsRcpReviewInfo();
 	if(pRsRcpReviewInfo == NULL)	return FALSE;
 
-	if(pRsRcpReviewInfo->GetRcpUserDefectInfoCount() < 1)	return TRUE;		// 고정리뷰 카운트가 없다면 넘어가자
+	if(pRsRcpReviewInfo->GetRcpUserDefectInfoCount() < 1)	return TRUE;		// 占쏙옙占쏙옙占쏙옙占쏙옙 카占쏙옙트占쏙옙 占쏙옙占쌕몌옙 占싼어가占쏙옙
 
 	double dCenterPosX, dCenterPosY;
 	
@@ -10241,18 +10250,18 @@
 	_grmGlassData* pSharedGlassData = pDitSharedGlassRaw->GetGlassData();
 	if(pSharedGlassData == NULL) return FALSE;
 
-	//pSharedGlassData->m_nUserReviewNum = 0; //공유 메모리 User plan 
+	//pSharedGlassData->m_nUserReviewNum = 0; //占쏙옙占쏙옙 占쌨몌옙 User plan 
 
 	_grmDefectData* pSharedDefect;
-	int nPointCount = pRecipeinfo->GetRcpUserDefectInfoCount(); // User 좌표 총 카운트
+	int nPointCount = pRecipeinfo->GetRcpUserDefectInfoCount(); // User 占쏙옙표 占쏙옙 카占쏙옙트
 
-	int nSharedDefectNum = pSharedGlassData->m_nDefectNum; // 디펙 총개수 User Idx 의 첫번째 Index 가 된다
-	int nStartIdx=nSharedDefectNum;// USER 디펙 종류 IDX 부여하기 위한 시작점 
+	int nSharedDefectNum = pSharedGlassData->m_nDefectNum; // 占쏙옙占쏙옙 占싼곤옙占쏙옙 User Idx 占쏙옙 첫占쏙옙째 Index 占쏙옙 占싫댐옙
+	int nStartIdx=nSharedDefectNum;// USER 占쏙옙占쏙옙 占쏙옙占쏙옙 IDX 占싸울옙占싹깍옙 占쏙옙占쏙옙 占쏙옙占쏙옙占쏙옙 
 
-	CRcpPlanInfo* pRcpPlanInfo; // 레시피 정보
-	CRcpUserDefectInfo *pDefectInfo;// 레시피 defect 정보 
+	CRcpPlanInfo* pRcpPlanInfo; // 占쏙옙占쏙옙占쏙옙 占쏙옙占쏙옙
+	CRcpUserDefectInfo *pDefectInfo;// 占쏙옙占쏙옙占쏙옙 defect 占쏙옙占쏙옙 
 	
-	int nInsepectionType;// User 타입 Reviewreflow = 0 wsiReflow =1; REV&WSI =2; WSIUSEr =3; USER =4; 
+	int nInsepectionType;// User 타占쏙옙 Reviewreflow = 0 wsiReflow =1; REV&WSI =2; WSIUSEr =3; USER =4; 
 
 	int nCount = 0;
 
@@ -10316,7 +10325,7 @@
 
 BOOL CSequenceProcessor_CPJT::CompareRevType(int nInsType,int nRevType)
 {
-	//Plan 타입과 InspectionMode 비교 
+	//Plan 타占쌉곤옙 InspectionMode 占쏙옙 
 	if(nRevType == CPJT_PlanUser)
 	{
 	  if(nInsType == USER) return TRUE;
@@ -10374,7 +10383,7 @@
 	CString strMessage, strResultFilePath, strUploadResultFilePath, strLocalRawPath;
 	CString	strUploadRawPath, strUploadImagePath, strAOIRawFileName, strAOIRawFilePath;
 
-	//3-1. 리뷰 결과 파일 쓰기
+	//3-1. 占쏙옙占쏙옙 占쏙옙占� 占쏙옙占쏙옙 占쏙옙占쏙옙
 	m_pSP2P->ISP2P_SetReviewResultData(pGlassResult);
 
 	strLocalRawPath		= pNetworkInfo->m_strLocalRawPath;
@@ -10401,7 +10410,7 @@
 
 			if(strUploadRawPath.IsEmpty() == FALSE && strAOIRawFilePath.IsEmpty() == FALSE)
 			{
-				// [2017:5:16]-[WEZASW] : 리뷰 PASS시의 설비 운영의 상황에 따라 AOI Server가 RAW 파일 직접 업로드 진행.
+				// [2017:5:16]-[WEZASW] : 占쏙옙占쏙옙 PASS占쏙옙占쏙옙 占쏙옙占쏙옙 占쏘영占쏙옙 占쏙옙황占쏙옙 占쏙옙占쏙옙 AOI Server占쏙옙 RAW 占쏙옙占쏙옙 占쏙옙占쏙옙 占쏙옙占싸듸옙 占쏙옙占쏙옙.
 				strUploadResultFilePath.Format(_T("%s\\%s"), strUploadRawPath, strAOIRawFileName);
 
 				if(CopyFile(strResultFilePath, strUploadResultFilePath, FALSE))
@@ -10422,9 +10431,9 @@
 	}
 
 	// delete file of Glass direction
-	DeleteFile(pNetworkInfo->m_strAOIRawPath + _T("\\") + pGlassResult->m_strJobID + _T("TD"));//pGlassResult->m_strGlassID -> m_StrJobID 변경
+	DeleteFile(pNetworkInfo->m_strAOIRawPath + _T("\\") + pGlassResult->m_strJobID + _T("TD"));//pGlassResult->m_strGlassID -> m_StrJobID 占쏙옙占쏙옙
 
-	// [2017:4:11]-[WEZASW] :CIM(DV Data) 보고 항목 추가.
+	// [2017:4:11]-[WEZASW] :CIM(DV Data) 占쏙옙占쏙옙 占쌓몌옙 占쌩곤옙.
 	if (SendDVDataToSignalControl()==FALSE) 
 	{
 		m_pSP2P->ISP2P_DisplayMessage(_T("[SequenceProcessor::ReviewEnd] DV Data Send FAIL!"));			
@@ -10444,8 +10453,8 @@
 
 BOOL CSequenceProcessor_CPJT::MoveReviewStartMotorPosition(CGlassResult* pGlassResult,int nReviewType)
 {
-	//혹시나 쓰일까봐 남겨듐 
-	//다음 플랜의 첫번째 위치로 이동
+	//혹占시놂옙 占쏙옙占싹깍옙占� 占쏙옙占쌤듸옙 
+	//占쏙옙占쏙옙 占시뤄옙占쏙옙 첫占쏙옙째 占쏙옙치占쏙옙 占싱듸옙
 	
 	double dDefectPosX,dDefectPosY = 0;
 	
@@ -10509,7 +10518,7 @@
 
 void CSequenceProcessor_CPJT::SendWsiErrorAlarm_CPJT(int Index) //190801 chm
 {	
-	//wsi 에러 알람
+	//wsi 占쏙옙占쏙옙 占싯띰옙
 	if(Index==1)
 	{
 		g_pLog->DisplayMessage(_T("[SequenceProcessor_CPJT] WSI Alive Error!!!"));
@@ -10523,7 +10532,7 @@
 
 void CSequenceProcessor_CPJT::SendWsiAlive_CPJT()//190801 chm
 {
-	//WSI Alive 신호 받음
+	//WSI Alive 占쏙옙호 占쏙옙占쏙옙
 	SetWSIAliveCheck(TRUE);
 }
 
@@ -10549,7 +10558,7 @@
 			if(bWsiAliveCheck ==FALSE){
 				m_pCSPC->SendWsiErrorAlarm_CPJT(1);
 			}
-			bWsiAliveCheck=FALSE; //30초에 한번씩 0으로 초기화
+			bWsiAliveCheck=FALSE; //30占십울옙 占싼뱄옙占쏙옙 0占쏙옙占쏙옙 占십깍옙화
 
 		}
 	}
diff --git a/ReviewSystem/include/CHReviewResult/ReviewResult.h b/ReviewSystem/include/CHReviewResult/ReviewResult.h
index c2f1a2a..08ced33 100644
--- a/ReviewSystem/include/CHReviewResult/ReviewResult.h
+++ b/ReviewSystem/include/CHReviewResult/ReviewResult.h
@@ -29,14 +29,14 @@
 	// 								Wsi_X_Right_4_A_Ratio,
 	// 								Wsi_Result_Info_Count };
 
-	// [2016:11:20]-[WEZASW] : WSI 결과 Data 항목 변경
+	// [2016:11:20]-[WEZASW] : WSI 占쏙옙占� Data 占쌓몌옙 占쏙옙占쏙옙
 	enum WSIResultInfo		{	Wsi_X_Height=0, 
 		Wsi_X_Width, 
 		Wsi_X_Area,
 		Wsi_X_A_Ratio, 
 		Wsi_Result_Info_Count };
 
-	// [2016:11:20]-[WEZASW] : WSI 결과 Data 항목 변경
+	// [2016:11:20]-[WEZASW] : WSI 占쏙옙占� Data 占쌓몌옙 占쏙옙占쏙옙
 	enum WSIReflowResultInfomation		{	WsiReflowInfo_AZoneJudge=0, 
 		WsiReflowInfo_BZoneJudge, 
 		WsiReflowInfo_CZoneJudge,										 
@@ -80,8 +80,8 @@
 	int					nExposureTime;			// exposure time
 	BOOL				bDigitalZoom;			// digital zoom ?
 	double				dRulerInterval;			// ruler Interval
-	double				dTargetMotorX;			// 모터 좌표
-	double				dTargetMotorY;			// 모터 좌표
+	double				dTargetMotorX;			// 占쏙옙占쏙옙 占쏙옙표
+	double				dTargetMotorY;			// 占쏙옙占쏙옙 占쏙옙표
 	int					nUMGrabPosX;			// Snap Pos
 	int					nUMGrabPosY;			// Snap Pos
 	int					nReviewSnapSerialNo;	// serial no
@@ -91,6 +91,7 @@
 	VectorImageData		vectorImageData;		// camera image 
 
 	CString				strImgFileName;
+	CString				strImgFilePath;
 
 	int					nMagnificationOffsetX;
 	int					nMagnificationOffsetY;
@@ -103,16 +104,16 @@
 	int					nReview_Square;
 	int					nReview_Stat;
 
-	// wsi data : 결과 파일 항목 추가
-	int					nWsi_ResultCode;							// 성공 여부
-	int					nWsi_Type;									// 함몰 / 돌기
+	// wsi data : 占쏙옙占� 占쏙옙占쏙옙 占쌓몌옙 占쌩곤옙
+	int					nWsi_ResultCode;							// 占쏙옙占쏙옙 占쏙옙占쏙옙
+	int					nWsi_Type;									// 占쌉몌옙 / 占쏙옙占쏙옙
 	int					nWsi_SlopeWarn;
 	double				pWsi_ResultData[Wsi_Result_Info_Count];		// um
 	int					nWsiReflowPositionIndex;					// WsiReflowPositionIndex
 	int					nWsi_pReflowResultData[WsiReflowInfo_Result_Info_Count];
 	double				dWsi_DamDistance;
 	bool	            bBigSizeDefect;
-	int					nMultiShotNum; //거대결함 촬영 순서
+	int					nMultiShotNum; //占신댐옙占쏙옙占� 占쌉울옙 占쏙옙占쏙옙
 
 	int					nGlassType; //TFE=0,MN=1,QD=2,BANK=3 CS =4 CSG = 5 
 
@@ -151,14 +152,14 @@
 	VectorResultFormula vecMeasure_ResultData;
 
 	// reflow data
-	int					nReflow_Result;							// 검출한 Line의 개수. 3 미만 : DAM2 Reflow 판정, 4~5 : DAM1 Reflow 판정, 6 : no Reflow 판정 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
-	int					pReflow_LinePosData[REFLOW_LINE_DATA];	// Line 좌표 출력 배열. DAM#2 바깥 2 Lines, DAM#2, DAM#1 순으로 좌표가 저장됨(즉, Pattern을 기준으로 바깥쪽부터 저장)
+	int					nReflow_Result;							// 占쏙옙占쏙옙占쏙옙 Line占쏙옙 占쏙옙占쏙옙. 3 占싱몌옙 : DAM2 Reflow 占쏙옙占쏙옙, 4~5 : DAM1 Reflow 占쏙옙占쏙옙, 6 : no Reflow 占쏙옙占쏙옙 / -1 : image not loaded, -2 : roi setting error, -3 : roi length error, -5 : select wrong side
+	int					pReflow_LinePosData[REFLOW_LINE_DATA];	// Line 占쏙옙표 占쏙옙占� 占썼열. DAM#2 占쌕깍옙 2 Lines, DAM#2, DAM#1 占쏙옙占쏙옙占쏙옙 占쏙옙표占쏙옙 占쏙옙占쏙옙占�(占쏙옙, Pattern占쏙옙 占쏙옙占쏙옙占쏙옙占쏙옙 占쌕깍옙占십븝옙占쏙옙 占쏙옙占쏙옙)
 	int					nReflow_Side;
 	int					nInspectionMode;
 	int					nReflow_CellIndex;
 
-	BOOL				bCheckWSISendToMotor;  //모터한테 좌표 보낸건지 확인 
-	BOOL				bCheckSendToMotor;  //WSI 진행시 모터한테 좌표 보낸건지 확인 
+	BOOL				bCheckWSISendToMotor;  //占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙표 占쏙옙占쏙옙占쏙옙占쏙옙 확占쏙옙 
+	BOOL				bCheckSendToMotor;  //WSI 占쏙옙占쏙옙占� 占쏙옙占쏙옙占쏙옙占쏙옙 占쏙옙표 占쏙옙占쏙옙占쏙옙占쏙옙 확占쏙옙 
 
 };
 typedef std::vector<SReviewResult>					VectorSReviewResult;

--
Gitblit v1.9.3