// 전 프로세스 공유 상수 /** 처리 대상 이미지 확장자 (소문자, 점 포함) */ export const SUPPORTED_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.webp'] as const /** 처리 대상 영상 확장자 (소문자, 점 포함) */ export const SUPPORTED_VIDEO_EXTENSIONS = [ '.mp4', '.mov', '.avi', '.mkv', '.webm', '.m4v' ] as const /** 미검출/인식실패 사진이 들어가는 폴더명 (언어 중립 — 영어 모드에서 한글 노출 방지) */ export const UNMATCHED_FOLDER = 'Unsorted' /** 영상 파일이 들어가는 폴더명 (얼굴인식 없이 날짜 기준 이동) */ export const MOVIE_FOLDER = 'Movie' /** 로컬 참조 이미지를 UI 창에 안전하게 표시하기 위한 커스텀 프로토콜 스킴 */ export const MEDIA_SCHEME = 'photoai-media' /** 로그 폴더명 (출력 루트 하위) */ export const LOG_FOLDER = '_PhotoAI_logs' /** 프로필 영속화 파일명 (userData 하위) */ export const PROFILE_STORE_FILE = 'profiles.json' /** 앱 설정 영속화 파일명 (userData 하위) */ export const SETTINGS_FILE = 'settings.json' /** 프리셋(인물 라이브러리) 영속화 파일명 (userData 하위, 로컬 전용) */ export const PRESET_STORE_FILE = 'presets.json' /** 최대 프로필 인원 (PRD) */ export const MAX_PROFILES = 3 /** 최대 프리셋(저장 인물) 수 */ export const MAX_PRESETS = 5 /** 기본 잡 옵션 */ export const DEFAULT_JOB_OPTIONS = { matchThreshold: 0.5, concurrency: 3, detector: 'ssd' as const } /** 추론 시 이미지 장변 최대 픽셀 (다운스케일 기준) */ export const MAX_IMAGE_DIMENSION = 1024 /** 썸네일 장변 픽셀 */ export const THUMBNAIL_SIZE = 256 /** 품질 분석 시 이미지 장변 픽셀 (초점/노출/얼굴 계산용) */ export const ANALYZE_SIZE = 512 /** 품질 판정 기본 임계값 (Phase 1) */ export const QUALITY_THRESHOLDS = { /** 라플라시안 분산이 이 값 미만이면 흐림 (512px 기준) */ focus: 60, /** 노출 점수(0~1)가 이 값 미만이면 노출 불량 */ exposure: 0.35, /** EAR(눈 종횡비)이 이 값 미만이면 눈 감음 */ eyes: 0.18 } /** IPC 채널명 */ export const IPC = { // UI → Main (invoke) PROFILES_LIST: 'profiles:list', PROFILES_UPSERT: 'profiles:upsert', PROFILES_REMOVE: 'profiles:remove', PROFILES_ADD_REFERENCE: 'profiles:addReference', PROFILES_ADD_REFERENCE_DATA: 'profiles:addReferenceData', PROFILES_REMOVE_REFERENCE: 'profiles:removeReference', PROFILES_APPLY_PRESET: 'profiles:applyPreset', // 프리셋(인물 라이브러리) PRESETS_LIST: 'presets:list', PRESETS_SAVE_FROM: 'presets:saveFrom', PRESETS_REMOVE: 'presets:remove', DIALOG_PICK_SOURCE: 'dialog:pickSource', DIALOG_PICK_OUTPUT: 'dialog:pickOutput', DIALOG_PICK_IMAGES: 'dialog:pickImages', JOB_RUN: 'job:run', JOB_CANCEL: 'job:cancel', // 설정 SETTINGS_GET: 'settings:get', SETTINGS_SET: 'settings:set', SETTINGS_CHANGED: 'settings:changed', // 라이브러리 / 색인 (Phase 0) LIBRARY_LIST: 'library:list', LIBRARY_ADD: 'library:add', LIBRARY_REMOVE: 'library:remove', INDEX_RUN: 'index:run', INDEX_CANCEL: 'index:cancel', INDEX_PROGRESS: 'index:progress', INDEX_DONE: 'index:done', INDEX_ASSETS: 'index:assets', INDEX_SET_RATING: 'index:setRating', INDEX_SET_LABEL: 'index:setLabel', // 검색 (Phase 2) SEARCH_BUILD: 'search:build', SEARCH_CANCEL: 'search:cancel', SEARCH_STATUS: 'search:status', SEARCH_QUERY: 'search:query', SEARCH_PROGRESS: 'search:progress', SEARCH_DONE: 'search:done', // Main → UI (send) JOB_PROGRESS: 'job:progress', JOB_FILE_PROCESSED: 'job:fileProcessed', JOB_DONE: 'job:done', JOB_ERROR: 'job:error', // Main ↔ Inference INFER_READY: 'infer:ready', INFER_DETECT: 'infer:detect', INFER_DESCRIBE: 'infer:describe', INFER_INIT: 'infer:init' } as const