import { useState } from 'react' import { HNSLeftPanel } from '../layout/HNSLeftPanel' import { HNSRightPanel } from '../layout/HNSRightPanel' import { MapView } from '../map/MapView' import { HNSAnalysisListTable } from '../analysis/HNSAnalysisListTable' import { HNSTheoryView } from '../analysis/HNSTheoryView' import { HNSSubstanceView } from '../analysis/HNSSubstanceView' import { HNSScenarioView } from '../analysis/HNSScenarioView' import { HNSRecalcModal } from '../analysis/HNSRecalcModal' import { useSubMenu, navigateToTab, setReportGenCategory } from '../../hooks/useSubMenu' /* ─── HNS 매뉴얼 뷰어 컴포넌트 ─── */ function HNSManualViewer() { const card = 'rounded-[10px] p-4 mb-3' const cardBg: React.CSSProperties = { background: 'var(--bg3)', border: '1px solid var(--bd)' } return (
{/* 헤더 */}
📖 해양 HNS 대응 매뉴얼
Marine HNS Response Manual — Bonn Agreement / HELCOM / REMPEC (WestMOPoCo 2024 한국어판)
{/* 목차 카드 그리드 */}
{[ { icon: '📘', title: '1. 서론', desc: 'HNS 정의 · OPRC-HNS 의정서 · HNS 협약 범위 및 목적', color: 'var(--cyan)' }, { icon: '⚖️', title: '2. IMO 협약·의정서·규칙', desc: 'SOLAS · MARPOL · IBC Code · IMDG Code · IGC Code', color: 'var(--cyan)' }, { icon: '🔬', title: '3. HNS 거동 및 유해요소', desc: 'SEBC 거동분류 · MSDS · GESAMP · 물리화학적 특성', color: 'var(--purple)' }, { icon: '🛡️', title: '4. 대비', desc: '위험 평가 · 비상 계획 · 교육훈련 · 장비 비축', color: 'var(--orange)' }, { icon: '🚨', title: '5. 대응', desc: '최초 조치 · 안전구역 · PPE · 모니터링 · 대응 기술', color: 'var(--red)' }, { icon: '🔄', title: '6. 유출 후 관리', desc: '비용 문서화 · 환경 회복 · 사고 검토 · 교훈', color: 'var(--cyan)' }, { icon: '📋', title: '7. 사례연구', desc: '실제 HNS 해양사고 사례 분석 및 교훈', color: 'var(--cyan)' }, { icon: '📊', title: '8. 자료표', desc: '물질별 데이터시트 · AEGL · 노출 한계값', color: 'var(--cyan)' }, ].map(ch => (
{ch.icon}
{ch.title}
{ch.desc}
))}
{/* SEBC 거동 분류 */}
SEBC 거동 분류 (Standard European Behaviour Classification)
물질의 물리적·화학적 특성(용해도, 밀도, 증기압, 점도)에 따라 이론적 거동을 5가지 주요 범주 + 7가지 하위 범주로 분류
{[ { icon: '💨', label: 'G — 가스', desc: '대기 중 확산\n증기압 > 101.3kPa\n예: 암모니아, 염소', color: 'rgba(139,92,246' }, { icon: '🌫️', label: 'E — 증발', desc: '수면→대기 증발\n증기압 > 3kPa\n예: 벤젠, 톨루엔', color: 'rgba(249,115,22' }, { icon: '🟡', label: 'F — 부유', desc: '해수면에 부유\n밀도 < 1.025\n예: 스티렌, 크실렌', color: 'rgba(251,191,36' }, { icon: '💧', label: 'D — 용해', desc: '해수에 용해\n용해도 > 5%\n예: 메탄올, 염산', color: 'rgba(6,182,212' }, { icon: '⬇️', label: 'S — 침강', desc: '해저로 침강\n밀도 > 1.025\n예: EDC, 사염화탄소', color: 'rgba(139,148,158' }, ].map(s => (
{s.icon}
{s.label}
{s.desc}
))}
{/* IMDG Code 위험물 등급 */}
IMDG Code 위험물 등급 (Hazard Classification)
{[ { icon: '💥', label: 'Class 1 — 폭발물', sub: 'Explosives', bg: 'rgba(249,115,22,.15)' }, { icon: '🫧', label: 'Class 2 — 가스', sub: '인화성/비인화성/독성', bg: 'rgba(34,197,94,.12)' }, { icon: '🔥', label: 'Class 3 — 인화성 액체', sub: 'Flammable Liquids', bg: 'rgba(239,68,68,.12)' }, { icon: '🧱', label: 'Class 4 — 인화성 고체', sub: '자연발화성/물반응성', bg: 'rgba(251,191,36,.12)' }, { icon: '⚡', label: 'Class 5 — 산화제', sub: '산화성 물질/유기과산화물', bg: 'rgba(251,191,36,.12)' }, { icon: '☠️', label: 'Class 6 — 독성물질', sub: '독성/감염성 물질', bg: 'rgba(139,92,246,.12)' }, { icon: '☢️', label: 'Class 7 — 방사성', sub: 'Radioactive Material', bg: 'rgba(251,191,36,.12)' }, { icon: '🧪', label: 'Class 8 — 부식성', sub: 'Corrosive Substances', bg: 'rgba(139,148,158,.12)' }, { icon: '⚠️', label: 'Class 9 — 기타', sub: '환경유해물질 포함', bg: 'rgba(139,148,158,.12)' }, ].map(c => (
{c.icon}
{c.label}
{c.sub}
))}
{/* HNS 사고 대응 프로세스 */}
HNS 사고 대응 프로세스
{[ { icon: '🚨', step: '1단계: 사고 통보', desc: 'HNS 유출 감지\nGMDSS/DSC 신호\n관계기관 통보', color: 'rgba(239,68,68', textColor: '#f87171' }, { icon: '🔍', step: '2단계: 상황 평가', desc: '물질 식별 (UN번호)\nSEBC 거동 판단\n위험 구역 설정', color: 'rgba(249,115,22', textColor: '#fb923c' }, { icon: '🛡️', step: '3단계: 최초 조치', desc: '선원/대응인력 보호\nPPE 착용\n안전구역 설정', color: 'rgba(251,191,36', textColor: '#fbbf24' }, { icon: '⚙️', step: '4단계: 현장 대응', desc: '선박 중심 조치\n오염물질 중심 조치\n모니터링 수행', color: 'rgba(6,182,212', textColor: 'var(--cyan)' }, { icon: '🔄', step: '5단계: 유출후 관리', desc: '환경 회복/복원\n비용 문서화\n사고 검토/교훈', color: 'rgba(34,197,94', textColor: '#22c55e' }, ].map((s, i) => (
{s.icon}
{s.step}
{s.desc}
{i < 4 &&
}
))}
{/* 대응 기술 매트릭스 */}
{/* 선박 중심 조치 */}
🚢 선박 중심 조치
{[ { icon: '🚁', title: '긴급 승선 (Emergency Boarding)', desc: '전문 대응팀의 사고 선박 접근 및 상황 파악' }, { icon: '🔗', title: '긴급 예인 (Emergency Towing)', desc: '사고 선박을 안전 해역으로 이동' }, { icon: '⚓', title: '피난 지역 (Place of Refuge)', desc: '선박이 수리/하역할 수 있는 보호 구역' }, { icon: '🔄', title: '화물 이송 (Cargo Transfer)', desc: '위험 화물을 다른 선박/탱크로 이적' }, { icon: '🔧', title: '밀봉/마개 (Sealing & Plugging)', desc: '유출 지점 임시 차단 및 봉쇄' }, ].map(item => (
{item.icon}
{item.title}
{item.desc}
))}
{/* 오염물질 중심 조치 */}
🧪 오염물질 중심 조치
{[ { icon: '💨', title: '대기 확산 모니터링', desc: '가스/증발 물질의 대기 농도 감시 (ALOHA/CAMEO)' }, { icon: '🌊', title: '해수면 회수 (Surface Recovery)', desc: '부유 물질 흡착재/스키머로 회수' }, { icon: '💧', title: '희석/분산 (Dilution/Dispersion)', desc: '용해 물질의 자연 희석 촉진' }, { icon: '⬇️', title: '해저 회수 (Subsea Recovery)', desc: '침강 물질 ROV/잠수 회수' }, { icon: '🔥', title: '제어 연소 (Controlled Burning)', desc: '인화성 물질 현장 소각 처리' }, ].map(item => (
{item.icon}
{item.title}
{item.desc}
))}
{/* PPE / 안전구역 / 노출한계 */}
{/* PPE */}
🦺 개인보호장비 (PPE)
{[ { level: 'Level A', desc: '완전 밀폐형 화학보호복 + SCBA\n증기/가스 직접 노출 구역', color: '#ef4444' }, { level: 'Level B', desc: '비밀폐형 화학보호복 + SCBA\n액체 스플래시 위험 구역', color: '#f97316' }, { level: 'Level C', desc: '화학보호복 + 공기정화식 호흡기\n물질 확인 완료, 농도 기준 이하', color: '#fbbf24' }, { level: 'Level D', desc: '작업복 + 안전장화\n오염 위험 최소 구역', color: '#22c55e' }, ].map(p => (
{p.level}
{p.desc}
))}
{/* 안전구역 */}
🔴 안전 구역 설정
HOT ZONE 직접 위험구역
Level A/B PPE 필수
WARM ZONE — 오염제거/전환 구역
COLD ZONE — 지휘/지원 구역
{/* 노출한계 (AEGL) */}
📊 노출한계 (AEGL 기준)
Acute Exposure Guideline Levels (EPA)
암모니아(NH₃) 예시 — ppm 기준
{[ { label: 'AEGL-1', color: '#22c55e', vals: [30, 30, 30, 30] }, { label: 'AEGL-2', color: '#fbbf24', vals: [220, 220, 160, 110] }, { label: 'AEGL-3', color: '#f87171', vals: [2700, 1600, 1100, 550] }, ].map((row, ri) => ( {row.vals.map((v, vi) => ( ))} ))}
구분 10분 30분 60분 4시간
{row.label}{v}
AEGL-1: 불쾌감 (비장애성)
AEGL-2: 심각한 건강 영향 (비가역적)
AEGL-3: 생명 위협 또는 사망
{/* 출처 */}
출처: Marine HNS Response Manual — Bonn Agreement / HELCOM / REMPEC (WestMOPoCo Project, 2024 한국어판)
번역: 원해민, 이시연, 양보경, 강성길, 이성엽 — KRISO 선박해양플랜트연구소 / NOWPAP MERRAC
원본: Alcaro L., Brandt J., Giraud W., Mannozzi M., Nicolas-Kopec A. (2021) ISBN: 978-2-87893-147-1
) } /* ─── 메인 HNSView ─── */ export function HNSView() { const { activeSubTab, setActiveSubTab } = useSubMenu('hns') const [incidentCoord, setIncidentCoord] = useState({ lon: 129.3542, lat: 35.4215 }) const [isSelectingLocation, setIsSelectingLocation] = useState(false) const [isRunningPrediction, setIsRunningPrediction] = useState(false) // eslint-disable-next-line @typescript-eslint/no-explicit-any const [dispersionResult, setDispersionResult] = useState(null) const [recalcModalOpen, setRecalcModalOpen] = useState(false) const handleMapClick = (lon: number, lat: number) => { if (isSelectingLocation) { setIncidentCoord({ lon, lat }) setIsSelectingLocation(false) } } const handleRunPrediction = async () => { setIsRunningPrediction(true) try { console.log('대기확산 예측 실행 요청:', { location: incidentCoord }) // TODO: 백엔드 API 호출 await new Promise(resolve => setTimeout(resolve, 2000)) const windAngle = 225 const result = { zones: [ { level: 'AEGL-3', color: 'rgba(239,68,68,0.4)', radius: 500, angle: windAngle }, { level: 'AEGL-2', color: 'rgba(249,115,22,0.3)', radius: 1000, angle: windAngle }, { level: 'AEGL-1', color: 'rgba(234,179,8,0.25)', radius: 1500, angle: windAngle }, ], timestamp: new Date().toISOString(), windDirection: windAngle, substance: 'Toluene', concentration: { 'AEGL-3': '500 ppm', 'AEGL-2': '150 ppm', 'AEGL-1': '37 ppm' } } setDispersionResult(result) console.log('대기확산 예측 완료:', result) } catch (error) { console.error('대기확산 예측 오류:', error) alert('대기확산 예측 중 오류가 발생했습니다.') } finally { setIsRunningPrediction(false) } } if (activeSubTab === 'scenario') { return } if (activeSubTab === 'manual') { return } if (activeSubTab === 'theory') { return } if (activeSubTab === 'substance') { return } return (
{/* Left Panel - 분석 목록일 때는 숨김 */} {activeSubTab === 'analysis' && ( setIsSelectingLocation(true)} onRunPrediction={handleRunPrediction} isRunningPrediction={isRunningPrediction} /> )} {/* Center - Map/Content Area */}
{activeSubTab === 'list' ? ( setActiveSubTab(typeof v === 'function' ? v(activeSubTab as 'analysis' | 'list') : v)} /> ) : ( )}
{/* Right Panel - 분석 목록일 때는 숨김 */} {activeSubTab === 'analysis' && ( setRecalcModalOpen(true)} onOpenReport={() => { setReportGenCategory(1); navigateToTab('reports', 'generate') }} /> )} {/* HNS 재계산 모달 */} setRecalcModalOpen(false)} onSubmit={() => handleRunPrediction()} />
) }