공개 — admin_basic 1.0.4 가 이전 소스로 빌드된 stale dist 를 릴리즈에 실어 주문 상세 합계행에 표현식 원문이 노출되던 회귀를 1.0.5 재빌드로 재수록. - admin_basic 1.0.5: --production 재빌드 + 서빙 번들 회귀 E2E(red→green) + 시나리오 매니페스트 - 전수 점검: sourcemap 잔존 9확장+코어 3번들 --production 재빌드, untracked .map 3개 삭제 (+1 bump: gdpr 1.0.3 / tosspayments 1.0.2 / verification_kginicis 1.0.3 / verification_nhnkcp 1.0.1 / basic 1.1.1 — 미공개 워킹 5건은 CHANGELOG 누적) - 리터럴 대조 전수: 기능 drift 는 admin_basic 단독 확정(타 대상 차집합 0), 릴리즈 패리티 7/7 일치 - board/page 사문 build 스크립트 제거 (vite.config 부재 — module:build --all 실패 요인) - audit 룰 신설: extension-dist-sourcemap-reference(error), extension-dist-source-literal-sync(warn) + coverage/룰 테스트/규정 문서 정정
1561 lines
193 KiB
JavaScript
1561 lines
193 KiB
JavaScript
var Ye=Object.defineProperty;var Xe=($,e,x)=>e in $?Ye($,e,{enumerable:!0,configurable:!0,writable:!0,value:x}):$[e]=x;var E=($,e,x)=>Xe($,typeof e!="symbol"?e+"":e,x);(function($,e,x){"use strict";const de=typeof window<"u"?window.G7Core?.__runtime:void 0;if(!de?.G7DevToolsCore)throw new Error("[devtools] window.G7Core.__runtime.G7DevToolsCore 이 없습니다. 코어 번들(template-engine.min.js)이 devtools 번들보다 먼저 로드되어야 합니다.");const G=de.G7DevToolsCore,J=[{id:"stale-closure",name:"Stale Closure",category:"state",symptoms:["이전 값이 전송됨","저장 시 오래된 데이터","API 호출 시 첫 값만 전송","클릭할 때마다 같은 값"],detector:d=>{const s=d.actionHistory.slice(-10).filter(a=>a.type==="apiCall");if(s.length<2)return!1;for(let a=1;a<s.length;a++){const g=JSON.stringify(s[a-1].params),r=JSON.stringify(s[a].params);if(g===r&&s[a].params)return!0}return!1},probability:.85,solution:"G7Core.state.get()._global 사용하여 최신 상태 참조",docLink:"troubleshooting-state.md#stale-closure",codeExample:`
|
|
// ❌ 문제: 클로저가 이전 상태 캡처
|
|
"body": { "email": "{{_global.email}}" }
|
|
|
|
// ✅ 해결: 최신 상태 참조
|
|
"body": { "email": "{{G7Core.state.get()._global.email}}" }
|
|
`},{id:"sequence-merge",name:"Sequence setState 병합 충돌",category:"state",symptoms:["sequence 내 setState 일부 누락","여러 setState 중 마지막만 적용","상태 업데이트 순서 문제"],detector:d=>d.actionHistory.filter(s=>s.type==="sequence").some(s=>s.children?.filter(a=>a.type==="setState").length>1),probability:.75,solution:"currentState 추적 패턴 사용 또는 단일 setState로 병합",docLink:"troubleshooting-state.md#사례3",codeExample:`
|
|
// ❌ 문제: sequence 내 여러 setState
|
|
"actions": [
|
|
{ "handler": "setState", "params": { "a": 1 } },
|
|
{ "handler": "setState", "params": { "b": 2 } }
|
|
]
|
|
|
|
// ✅ 해결: 단일 setState로 병합
|
|
"actions": [
|
|
{ "handler": "setState", "params": { "a": 1, "b": 2 } }
|
|
]
|
|
`},{id:"init-actions-timing",name:"init_actions 타이밍 이슈",category:"timing",symptoms:["init_actions 값이 렌더링에 반영 안됨","초기 상태가 undefined","첫 클릭 시 초기값 손실"],detector:d=>{if(d.stateHistory.length===0)return!1;const t=d.stateHistory[0];return t?.source==="init_actions"&&Object.keys(t.next||{}).length===0},probability:.7,solution:"init_actions 후 _global 상태 병합 확인",docLink:"troubleshooting-state.md#init_actions-관련-이슈"},{id:"datakey-global-init",name:'dataKey="_global.xxx" 초기화 누락',category:"form",symptoms:["Form dataKey가 전역 상태에 바인딩 안됨","Input 값이 _global에 저장 안됨","Form 제출 시 빈 값 전송"],detector:d=>d.form.filter(s=>s.dataKey?.startsWith("_global.")).length===0?!1:!d.stateHistory.some(s=>s.source==="init_actions"),probability:.95,solution:"init_actions에서 _global 상태 초기화 필수",docLink:"troubleshooting-state.md#datakey-자동-바인딩-이슈",codeExample:`
|
|
// init_actions에서 초기화 필요
|
|
"init_actions": [
|
|
{
|
|
"handler": "setState",
|
|
"params": {
|
|
"target": "global",
|
|
"loginForm": { "email": "", "password": "" }
|
|
}
|
|
}
|
|
]
|
|
`},{id:"cache-iteration",name:"캐시 반복 렌더링 문제",category:"cache",symptoms:["모든 행이 같은 값","iteration에서 첫 항목만 표시","DataGrid 데이터 중복"],detector:d=>(d.cacheStats.hitRate??0)>.9&&d.conditional.iterations.length>0,probability:.9,solution:"skipCache: true 추가",docLink:"troubleshooting-cache.md#사례4",codeExample:`
|
|
// ❌ 문제: 캐시된 값이 모든 행에 적용
|
|
"cellChildren": [{ "props": { "value": "{{item.name}}" } }]
|
|
|
|
// ✅ 해결: 렌더러에서 skipCache 옵션 사용
|
|
// 또는 ActionDispatcher에서 skipCache: true로 호출
|
|
`},{id:"cache-dynamic-query",name:"동적 쿼리 파라미터 캐싱",category:"cache",symptoms:["페이지네이션이 동작 안함","필터 변경해도 같은 결과","정렬이 적용 안됨"],detector:d=>{const t=d.network.requestHistory.slice(-5);if(t.length<2)return!1;const s=t.map(a=>a.url.split("?")[0]);return new Set(s).size<s.length},probability:.85,solution:"데이터소스 params에 skipCache: true 추가",docLink:"troubleshooting-cache.md#사례2"},{id:"orphaned-listener",name:"정리되지 않은 이벤트 리스너",category:"lifecycle",symptoms:["메모리 사용량 증가","이벤트가 여러 번 실행됨","페이지 이동 후에도 이벤트 발생"],detector:d=>d.lifecycle.orphanedListeners.length>0,probability:.8,solution:"useEffect cleanup 또는 removeEventListener 추가",docLink:"troubleshooting-components.md#lifecycle"},{id:"unmount-state-update",name:"언마운트 후 상태 업데이트",category:"lifecycle",symptoms:["Cannot update state on unmounted component","비동기 작업 완료 후 에러","모달 닫힘 후 에러"],detector:d=>d.actionHistory.some(t=>t.status==="error"&&t.error?.message?.includes("unmounted")),probability:.9,solution:"AbortController 또는 isMounted 플래그 사용",docLink:"troubleshooting-state.md#unmount-update"},{id:"excessive-rerenders",name:"과도한 리렌더링",category:"performance",symptoms:["UI가 느림","스크롤 버벅임","입력 지연"],detector:d=>{for(const t of d.performance.renderCounts.values())if(t>50)return!0;return!1},probability:.75,solution:"React.memo, useMemo, useCallback 사용",docLink:"troubleshooting-components.md#performance"},{id:"binding-eval-flood",name:"바인딩 평가 과다",category:"performance",symptoms:["페이지 로드 느림","CPU 사용량 높음"],detector:d=>d.performance.bindingEvalCount>1e3,probability:.85,solution:"불필요한 {{}} 바인딩 제거, 정적 값 사용",docLink:"troubleshooting-cache.md#binding-performance"},{id:"memory-leak",name:"잠재적 메모리 누수",category:"performance",symptoms:["시간이 지남에 따라 느려짐","브라우저 탭 메모리 증가","오래 사용 시 크래시"],detector:d=>d.performance.memoryWarnings.length>0,probability:.7,solution:"클린업 함수 확인, WeakMap 사용",docLink:"troubleshooting-state.md#memory-leak"},{id:"request-timeout",name:"API 요청 타임아웃",category:"network",symptoms:["데이터가 로딩 안됨","무한 로딩 스피너","타임아웃 에러"],detector:d=>d.network.requestHistory.some(t=>t.status==="timeout"||t.duration&&t.duration>3e4),probability:.9,solution:"서버 상태 확인, 타임아웃 설정 조정",docLink:"troubleshooting-backend.md#timeout"},{id:"duplicate-requests",name:"중복 API 요청",category:"network",symptoms:["같은 요청이 여러 번 실행","네트워크 탭에 동일 요청 반복","불필요한 서버 부하"],detector:d=>{const a=d.network.requestHistory.slice(-20).map(g=>`${g.method}:${g.url}`);return a.length!==new Set(a).size},probability:.85,solution:"debounce 추가, 데이터소스 의존성 확인",docLink:"troubleshooting-cache.md#duplicate-request"},{id:"datasource-not-loading",name:"데이터소스 미로딩",category:"network",symptoms:["데이터가 undefined","빈 테이블/목록","API 호출이 안됨"],detector:d=>d.network.pendingDataSources.length>0&&d.network.activeRequests.length===0,probability:.8,solution:"데이터소스 strategy 확인, 의존성 확인",docLink:"troubleshooting-backend.md#datasource"},{id:"permission-denied",name:"레이아웃 권한 거부 (403)",category:"network",symptoms:["403 Forbidden","권한이 없습니다","레이아웃 로드 실패","페이지 접근 불가","빈 화면"],detector:d=>d.network.requestHistory.some(t=>t.statusCode===403),probability:.9,solution:"사용자 권한 확인 또는 레이아웃 permissions 설정 확인",docLink:"frontend/layout-json.md#permissions",codeExample:`
|
|
// 레이아웃 JSON의 permissions 필드 확인
|
|
{
|
|
"permissions": ["core.products.read"] // 필요 권한
|
|
}
|
|
|
|
// 권한 없이 공개로 설정하려면:
|
|
{
|
|
"permissions": [] // 빈 배열 = 공개 레이아웃
|
|
}
|
|
`},{id:"auth-required",name:"인증 필요 (401)",category:"network",symptoms:["401 Unauthorized","로그인 필요","토큰 만료","인증되지 않음","Unauthenticated"],detector:d=>d.network.requestHistory.some(t=>t.statusCode===401),probability:.95,solution:"로그인 상태 확인 또는 토큰 갱신 필요",docLink:"frontend/auth-system.md"},{id:"infinite-scroll-state-reset",name:"무한 스크롤 상태 미초기화",category:"state",symptoms:["삭제 후 스크롤 안됨","무한 스크롤이 멈춤","hasMore가 false로 유지","더 이상 데이터 로드 안됨"],detector:d=>{const t=d.currentState;return d.actionHistory.some(a=>a.type==="refetchDataSource")&&t?._global?.infiniteScroll?.hasMore===!1},probability:.85,solution:"refetchDataSource 전에 infiniteScroll 상태 초기화 필요",docLink:"frontend/actions-handlers.md#appendDataSource",codeExample:`
|
|
// 삭제 성공 시 상태 초기화 후 refetch
|
|
"onSuccess": [
|
|
{
|
|
"handler": "setState",
|
|
"params": {
|
|
"target": "global",
|
|
"infiniteScroll": {
|
|
"currentPage": 1,
|
|
"hasMore": true,
|
|
"isLoadingMore": false
|
|
}
|
|
}
|
|
},
|
|
{ "handler": "refetchDataSource", "params": { "id": "list" } }
|
|
]
|
|
`},{id:"scroll-event-not-configured",name:"스크롤 이벤트 미설정",category:"lifecycle",symptoms:["스크롤해도 데이터 로드 안됨","무한 스크롤 작동 안함","스크롤 이벤트 안잡힘"],detector:d=>{const t=d.actionHistory.some(a=>a.type==="scroll"),s=d.actionHistory.some(a=>a.type==="appendDataSource");return!t&&!s&&d.actionHistory.length>5},probability:.7,solution:"scroll 이벤트 핸들러 설정 및 컨테이너 overflow 속성 확인",docLink:"frontend/actions.md#scroll-event",codeExample:`
|
|
// 무한 스크롤 컨테이너 설정 예시
|
|
{
|
|
"type": "Div",
|
|
"props": {
|
|
"className": "overflow-y-auto h-full"
|
|
},
|
|
"actions": {
|
|
"scroll": [
|
|
{
|
|
"handler": "appendDataSource",
|
|
"params": {
|
|
"id": "list",
|
|
"dataPath": "data",
|
|
"sourcePath": "{{_global.infiniteScroll.currentPage}}"
|
|
}
|
|
}
|
|
]
|
|
}
|
|
}
|
|
`},{id:"append-datasource-wrong-path",name:"appendDataSource 경로 오류",category:"state",symptoms:["무한 스크롤 시 데이터 덮어씀","기존 데이터가 사라짐","데이터가 병합 안됨"],detector:d=>{const t=d.actionHistory.filter(s=>s.type==="appendDataSource");return t.length>=2&&t.some(s=>s.status==="error")},probability:.75,solution:"dataPath와 sourcePath 설정 확인, 데이터소스 dataPath가 병합 대상인지 확인",docLink:"frontend/actions-handlers.md#appendDataSource"},{id:"websocket-disconnected",name:"WebSocket 연결 끊김",category:"websocket",symptoms:["실시간 업데이트 안됨","알림이 오지 않음"],detector:d=>d.websocket.connectionState==="disconnected",probability:.9,solution:"네트워크 상태 확인, 재연결 로직 확인",docLink:"troubleshooting-backend.md#websocket"},{id:"if-condition-always-false",name:"if 조건 항상 false",category:"conditional",symptoms:["컴포넌트가 표시 안됨","조건부 영역이 비어있음"],detector:d=>d.conditional.ifConditions.some(t=>t.evaluatedValue===!1&&t.evaluationCount>5),probability:.85,solution:"if 조건식 확인, 상태값 확인",docLink:"troubleshooting-state.md#if-condition"},{id:"iteration-empty",name:"iteration 소스 비어있음",category:"conditional",symptoms:["반복 영역이 비어있음","목록이 표시 안됨"],detector:d=>d.conditional.iterations.some(t=>t.sourceLength===0),probability:.8,solution:"iteration source 표현식 확인, 데이터 로딩 확인",docLink:"troubleshooting-guide.md#iteration"},{id:"iteration-item-var",name:"iteration 변수명 오류",category:"conditional",symptoms:["반복 항목 내 바인딩 빈값","올바른 개수는 표시되나 내용 없음"],detector:d=>d.conditional.iterations.some(t=>t.itemVar==="item"||t.indexVar==="index"),probability:.95,solution:"item_var, index_var 사용 (item, index 아님)",docLink:"troubleshooting-guide.md#iteration-바인딩-문제",codeExample:`
|
|
// ❌ 잘못된 속성명
|
|
"iteration": {
|
|
"source": "{{data}}",
|
|
"item": "file", // 잘못됨!
|
|
"index": "fileIdx" // 잘못됨!
|
|
}
|
|
|
|
// ✅ 올바른 속성명
|
|
"iteration": {
|
|
"source": "{{data}}",
|
|
"item_var": "file",
|
|
"index_var": "fileIdx"
|
|
}
|
|
`},{id:"form-no-datakey",name:"Form dataKey 미설정",category:"form",symptoms:["Input 값이 저장 안됨","Form 제출 시 빈 값"],detector:d=>d.form.some(t=>!t.dataKey),probability:.9,solution:"Form에 dataKey prop 추가",docLink:"troubleshooting-components.md#form-datakey"},{id:"input-no-name",name:"Input name 미설정",category:"form",symptoms:["자동 바인딩 안됨","Input 값 변경이 상태에 반영 안됨"],detector:d=>d.form.some(t=>t.inputs.some(s=>!s.name)),probability:.95,solution:"Input에 name prop 추가",docLink:"troubleshooting-components.md#input-name"},{id:"i18n-key-missing",name:"번역 키 누락",category:"i18n",symptoms:["$t:key가 그대로 표시됨","번역되지 않은 텍스트"],detector:d=>typeof document<"u"?document.body.innerHTML.includes("$t:"):!1,probability:.95,solution:"번역 파일에 키 추가",docLink:"troubleshooting-components.md#i18n"}];class Z{constructor(){E(this,"devTools");this.devTools=G.getInstance()}analyze(t){const s=this.buildContext(),a=[];for(const g of J){const r=t.some(p=>g.symptoms.some(v=>v.toLowerCase().includes(p.toLowerCase())||p.toLowerCase().includes(v.toLowerCase())));let o=!1;try{o=g.detector(s)}catch{}(r||o)&&a.push({rule:g,confidence:this.calculateConfidence(g,t,r,o),evidence:this.collectEvidence(g,s)})}return a.sort((g,r)=>r.confidence-g.confidence)}suggestFix(t){return{title:t.rule.name,description:t.rule.solution,codeExample:t.rule.codeExample,docLink:t.rule.docLink}}getCommonIssues(){const t=this.buildContext(),s=[];for(const a of J)try{a.detector(t)&&s.push({rule:a,count:1})}catch{}return s.sort((a,g)=>g.count-a.count).map(a=>({id:a.rule.id,name:a.rule.name,description:a.rule.solution,frequency:a.count}))}getRulesByCategory(t){return J.filter(s=>s.category===t)}getAllRules(){return[...J]}buildContext(){return{stateHistory:this.devTools.getStateHistory(),actionHistory:this.devTools.getActionHistory(),cacheStats:this.devTools.getCacheStats(),currentState:this.devTools.getState(),lifecycle:this.devTools.getLifecycleInfo(),performance:this.devTools.getPerformanceInfo(),network:this.devTools.getNetworkInfo(),conditional:this.devTools.getConditionalInfo(),form:this.devTools.getFormInfo(),websocket:this.devTools.getWebSocketInfo(),stateAtTime:t=>this.devTools.getStateAtTime(t),layoutHas:(t,s)=>this.checkLayoutHas(t,s)}}calculateConfidence(t,s,a,g){let r=t.probability;if(a){const o=s.filter(p=>t.symptoms.some(v=>v.toLowerCase().includes(p.toLowerCase())||p.toLowerCase().includes(v.toLowerCase()))).length;r+=o*.05}return g&&(r+=.1),Math.min(r,.99)}collectEvidence(t,s){const a=[];switch(t.category){case"state":s.stateHistory.length>0&&a.push(`상태 변경 이력: ${s.stateHistory.length}개`);break;case"cache":a.push(`캐시 히트율: ${((s.cacheStats.hitRate??0)*100).toFixed(1)}%`);break;case"lifecycle":s.lifecycle.orphanedListeners.length>0&&a.push(`정리되지 않은 리스너: ${s.lifecycle.orphanedListeners.length}개`);break;case"performance":a.push(`바인딩 평가 횟수: ${s.performance.bindingEvalCount}`);break;case"network":a.push(`진행 중인 요청: ${s.network.activeRequests.length}개`);break;case"form":a.push(`추적 중인 Form: ${s.form.length}개`);break}return a}checkLayoutHas(t,s){try{const g=window.G7Core?.getCurrentLayout?.();if(!g)return!1;const r=JSON.stringify(g);return r.includes(`"${t}":"${s}`)||r.includes(`"${t}": "${s}`)}catch{return!1}}}const pe=Object.freeze(Object.defineProperty({__proto__:null,DiagnosticEngine:Z},Symbol.toStringTag,{value:"Module"})),xe={dumpEndpoint:"/_boost/g7-debug/dump-state",logEndpoint:"/_boost/g7-debug/log",timeout:1e4,autoCapture:!1,autoCaptureInterval:3e4};class fe{constructor(t){E(this,"config");E(this,"devTools");E(this,"connected",!1);E(this,"autoCaptureTimer",null);E(this,"CHUNK_SIZE",2*1024*1024);E(this,"BULK_THRESHOLD",4*1024*1024);this.config={...xe,...t},this.devTools=G.getInstance(),this.config.autoCapture&&this.startAutoCapture()}async dumpState(t=!1){const s=`${Date.now()}_${Math.random().toString(36).substring(2,9)}`,a=Date.now(),g=this.devTools.getPerformanceInfo(),r={renderCounts:Object.fromEntries(g.renderCounts),bindingEvalCount:g.bindingEvalCount,memoryWarnings:g.memoryWarnings},o={state:()=>this.devTools.getState(),actions:()=>this.devTools.getActionHistory(),cache:()=>this.devTools.getCacheStats(),lifecycle:()=>this.devTools.getLifecycleInfo(),network:()=>this.devTools.getNetworkInfo(),expressions:()=>this.devTools.getExpressions(),forms:()=>this.devTools.getForms(),performance:()=>r,conditionals:()=>this.devTools.getConditionalInfo(),dataSources:()=>this.devTools.getDataSources(),handlers:()=>this.devTools.getHandlers(),componentEvents:()=>this.devTools.getComponentEventInfo(),stateRendering:()=>this.devTools.getStateRenderingInfo(),stateHierarchy:()=>this.devTools.getStateHierarchyInfo(),contextFlow:()=>this.devTools.getContextFlowInfo(),styleValidation:()=>this.devTools.getStyleValidationInfo(),authDebug:()=>this.devTools.getAuthDebugInfo(),logs:()=>this.devTools.getLogInfo(),layout:()=>this.devTools.getLayoutDebugInfo(),changeDetection:()=>this.devTools.getChangeDetectionInfo(),sequenceTracking:()=>this.devTools.getSequenceTrackingInfo(),staleClosureTracking:()=>this.devTools.getStaleClosureTrackingInfo(),cacheDecisionTracking:()=>this.devTools.getCacheDecisionTrackingInfo(),dataPathTransformTracking:()=>this.devTools.getDataPathTransformTrackingInfo(),nestedContextTracking:()=>this.devTools.getNestedContextTrackingInfo(),formBindingValidationTracking:()=>this.devTools.getFormBindingValidationTrackingInfo(),computedDependencyTracking:()=>this.devTools.getComputedDependencyTrackingInfo(),modalStateScopeTracking:()=>this.devTools.getModalStateScopeTrackingInfo(),namedActionTracking:()=>this.devTools.getNamedActionTrackingInfo()},p={},v=[];let l=0;for(const[h,y]of Object.entries(o))try{const n=y(),i=this.safeStringify(n,h);i===null?(v.push(`${h}: 직렬화 실패`),p[h]=JSON.stringify({_error:`${h} 섹션 직렬화 실패`})):p[h]=i,l+=p[h].length}catch(n){const i=n instanceof Error?n.message:String(n);v.push(`${h}: ${i}`),p[h]=JSON.stringify({_error:`${h} 섹션 수집 실패: ${i}`}),l+=p[h].length}const f=Object.keys(p).length,c=f-v.length;try{return l<=this.BULK_THRESHOLD?(await this.sendBulkDump(p,a,t),console.log(`[G7DevTools] 상태 덤프 완료 - 일괄 전송 (${(l/1024).toFixed(1)}KB, ${c}/${f} 섹션 성공)`)):(await this.sendChunkedDump(s,p,a,t),console.log(`[G7DevTools] 상태 덤프 완료 - 분할 전송 (${(l/1024/1024).toFixed(2)}MB, ${c}/${f} 섹션 성공)`)),this.connected=!0,v.length>0&&console.warn("[G7DevTools] 일부 섹션 실패:",v.join(", ")),s}catch(h){throw this.connected=!1,console.error("[G7DevTools] 상태 덤프 실패:",h),h}}async sendBulkDump(t,s,a){const g={};for(const[r,o]of Object.entries(t))try{g[r]=JSON.parse(o)}catch{g[r]={_error:"파싱 실패"}}await this.sendRequest(this.config.dumpEndpoint,{bulk:!0,sections:g,timestamp:s,saveHistory:a})}async sendChunkedDump(t,s,a,g){const r=Object.keys(s),o=r.length;for(let p=0;p<r.length;p++){const v=r[p],l=s[v],f=p===r.length-1;await this.sendChunkedSection(t,v,l,f,a,g,o)}}async sendChunkedSection(t,s,a,g,r,o,p){const v=this.splitIntoChunks(a),l=v.length;for(let f=0;f<v.length;f++){const c=f===v.length-1,h=v[f];await this.sendRequest(this.config.dumpEndpoint,{sessionId:t,sectionName:s,chunkData:h,chunkIndex:f,totalChunks:l,isLastChunk:c,isLastSection:g&&c,timestamp:r,saveHistory:o,totalSections:p})}}splitIntoChunks(t){const s=[];for(let a=0;a<t.length;a+=this.CHUNK_SIZE)s.push(t.slice(a,a+this.CHUNK_SIZE));return s.length>0?s:[""]}safeStringify(t,s){const a=new WeakSet;try{return JSON.stringify(t,(r,o)=>{if(typeof o=="object"&&o!==null){if(a.has(o))return"[Circular Reference]";a.add(o)}return typeof o=="function"?"[Function]":typeof o=="symbol"?"[Symbol]":typeof o=="bigint"?o.toString():o})}catch(g){return console.warn(`[G7DevTools] ${s} 직렬화 오류:`,g),null}}async sendLog(t){console.log("[G7:DEBUG]",JSON.stringify(t));try{await this.sendRequest(this.config.logEndpoint,{type:"debug",data:t,timestamp:Date.now()})}catch{}}async sendError(t,s){const a={name:t.name,message:t.message,stack:t.stack,context:s,state:this.devTools.getState(),actions:this.devTools.getActionHistory().slice(-10),timestamp:Date.now()};console.log("[G7:ERROR]",JSON.stringify(a));try{await this.sendRequest(this.config.logEndpoint,{type:"error",data:a,timestamp:Date.now()})}catch{}}async sendProfile(t){console.log("[G7:PROFILE]",JSON.stringify(t));try{await this.sendRequest(this.config.logEndpoint,{type:"profile",data:t,timestamp:Date.now()})}catch{}}isConnected(){return this.connected}async testConnection(){try{const t=await this.sendRequest(this.config.dumpEndpoint,{test:!0,timestamp:Date.now()});return this.connected=t.status==="success",this.connected}catch{return this.connected=!1,!1}}startAutoCapture(){this.autoCaptureTimer&&this.stopAutoCapture(),this.autoCaptureTimer=setInterval(()=>{this.devTools.isEnabled()&&this.dumpState().catch(()=>{})},this.config.autoCaptureInterval),console.log("[G7DevTools] 자동 캡처 시작 (간격:",this.config.autoCaptureInterval,"ms)")}stopAutoCapture(){this.autoCaptureTimer&&(clearInterval(this.autoCaptureTimer),this.autoCaptureTimer=null,console.log("[G7DevTools] 자동 캡처 중지"))}updateConfig(t){this.config={...this.config,...t},("autoCapture"in t||"autoCaptureInterval"in t)&&(this.stopAutoCapture(),this.config.autoCapture&&this.startAutoCapture())}async sendRequest(t,s){const a=new AbortController,g=setTimeout(()=>a.abort(),this.config.timeout);try{const r=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json","X-Requested-With":"XMLHttpRequest"},body:JSON.stringify(s),signal:a.signal});if(clearTimeout(g),!r.ok)throw new Error(`HTTP ${r.status}: ${r.statusText}`);const o=await r.text();if(o.trim().startsWith("<")||o.includes("<br />")||o.includes("<b>")){const p=this.extractErrorFromHtml(o);throw new Error(`서버 오류: ${p}`)}try{return JSON.parse(o)}catch{throw new Error(`잘못된 JSON 응답: ${o.substring(0,100)}...`)}}catch(r){throw clearTimeout(g),r instanceof Error&&r.name==="AbortError"?new Error("요청 타임아웃"):r}}extractErrorFromHtml(t){const s=[/<b>(Fatal error|Warning|Notice|Parse error)<\/b>:\s*([^<]+)/i,/Exception:\s*([^<\n]+)/i,/Error:\s*([^<\n]+)/i,/(TypeError|ArgumentCountError|ValueError)[^:]*:\s*([^<\n]+)/i];for(const g of s){const r=t.match(g);if(r)return(r[r.length-1]||r[1]).replace(/</g,"<").replace(/>/g,">").replace(/&/g,"&").replace(/"/g,'"').trim().substring(0,200)}return t.replace(/<[^>]+>/g," ").replace(/\s+/g," ").trim().substring(0,200)||"Unknown server error"}destroy(){this.stopAutoCapture()}}let Q=null;function R(){return Q||(Q=new fe),Q}const me=["display","visibility","opacity","position","zIndex","overflow","width","height","backgroundColor","color"],P=class P{constructor(){E(this,"enabled",!1);E(this,"trackedComponents",new Map);E(this,"mutationObserver",null);E(this,"scanInterval",null);E(this,"devTools");this.devTools=G.getInstance()}static getInstance(){return P.instance||(P.instance=new P),P.instance}enable(){this.enabled||(this.enabled=!0,this.setupMutationObserver(),this.scanInterval=setInterval(()=>{this.scanVisibleComponents()},5e3),console.log("[StyleTracker] 스타일 추적 활성화됨"))}disable(){this.enabled&&(this.enabled=!1,this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.scanInterval&&(clearInterval(this.scanInterval),this.scanInterval=null),this.trackedComponents.clear(),console.log("[StyleTracker] 스타일 추적 비활성화됨"))}trackComponent(t,s,a){if(!this.enabled||!this.devTools.isEnabled()||!a)return;const g=this.extractClasses(a),r=this.getComputedStyles(a);this.devTools.trackComponentStyle(t,s,g,r),this.trackedComponents.set(t,{componentId:t,componentName:s,classes:g,computedStyles:r,element:new WeakRef(a),timestamp:Date.now()}),this.detectIssues(t,s,a,g,r)}untrackComponent(t){this.trackedComponents.delete(t)}scanVisibleComponents(){if(!this.enabled||!this.devTools.isEnabled())return;(this.devTools.getLifecycleInfo().mountedComponents||[]).forEach(g=>{const r=g.id,o=g.name;let p=null;if(r&&(p=document.getElementById(r)),!p&&r&&(p=document.querySelector(`[data-component-id="${r}"]`)),!p&&r&&(p=document.querySelector(`[data-editor-id="${r}"]`)),!p)return;const v=this.extractClasses(p),l=this.getComputedStyles(p);this.devTools.trackComponentStyle(r,o,v,l),this.detectIssues(r,o,p,v,l),this.trackedComponents.set(r,{componentId:r,componentName:o,classes:v,computedStyles:l,element:new WeakRef(p),timestamp:Date.now()})}),document.querySelectorAll('[data-editor-id], [id^="comp-"]').forEach(g=>{if(!(g instanceof HTMLElement))return;const r=g.getAttribute("data-editor-id")||g.id,o=g.getAttribute("data-editor-name")||g.tagName;if(!r||this.trackedComponents.has(r))return;const p=this.extractClasses(g),v=this.getComputedStyles(g);this.devTools.trackComponentStyle(r,o,p,v),this.detectIssues(r,o,g,p,v),this.trackedComponents.set(r,{componentId:r,componentName:o,classes:p,computedStyles:v,element:new WeakRef(g),timestamp:Date.now()})})}detectIssues(t,s,a,g,r){r.display==="none"&&this.addIssue({type:"invisible-element",componentId:t,componentName:s,property:"display",currentValue:"none",severity:"info",description:"요소가 display:none으로 숨겨져 있습니다",suggestion:"의도적인 숨김이 아니라면 조건부 렌더링(if)을 확인하세요"}),r.visibility==="hidden"&&this.addIssue({type:"invisible-element",componentId:t,componentName:s,property:"visibility",currentValue:"hidden",severity:"info",description:"요소가 visibility:hidden으로 숨겨져 있습니다",suggestion:"공간은 유지되지만 보이지 않습니다. 의도적인지 확인하세요"}),r.opacity==="0"&&this.addIssue({type:"invisible-element",componentId:t,componentName:s,property:"opacity",currentValue:"0",severity:"warning",description:"요소가 opacity:0으로 투명합니다",suggestion:"애니메이션 상태가 아니라면 스타일을 확인하세요"}),(r.width==="0px"||r.height==="0px")&&this.addIssue({type:"invisible-element",componentId:t,componentName:s,property:r.width==="0px"?"width":"height",currentValue:"0px",severity:"warning",description:"요소의 크기가 0입니다",suggestion:"컨텐츠가 있는데 크기가 0이라면 레이아웃 문제일 수 있습니다"}),r.overflow==="hidden"&&(a.scrollWidth>a.clientWidth||a.scrollHeight>a.clientHeight)&&this.addIssue({type:"overflow-hidden",componentId:t,componentName:s,property:"overflow",currentValue:"hidden",severity:"warning",description:"컨텐츠가 overflow:hidden으로 잘리고 있습니다",suggestion:"overflow-auto 또는 컨테이너 크기를 확인하세요"});const o=g.some(y=>y.startsWith("dark:"));g.some(y=>(y.startsWith("bg-white")||y.startsWith("bg-gray-"))&&!y.startsWith("dark:"))&&!o&&this.addIssue({type:"dark-mode-missing",componentId:t,componentName:s,property:"className",currentValue:g.filter(y=>y.startsWith("bg-")).join(" "),severity:"info",description:"다크 모드 변형 클래스가 누락되었을 수 있습니다",suggestion:"bg-white 사용 시 dark:bg-gray-800 등을 함께 지정하세요"});const v=parseInt(r.zIndex,10);!isNaN(v)&&v>50&&r.position!=="static"&&this.addIssue({type:"z-index-conflict",componentId:t,componentName:s,property:"z-index",currentValue:r.zIndex,severity:"info",description:`높은 z-index(${v})가 설정되어 있습니다`,suggestion:"z-index 충돌을 피하려면 10, 20, 30, 40, 50 단위를 사용하세요"});const l=g.some(y=>y.startsWith("sm:")||y.startsWith("md:")||y.startsWith("lg:")||y.startsWith("xl:")),f=g.includes("hidden"),c=g.includes("portable:block")||g.includes("portable:flex"),h=g.includes("desktop:block")||g.includes("desktop:flex");f&&!l&&!c&&!h&&this.addIssue({type:"responsive-issue",componentId:t,componentName:s,property:"className",currentValue:"hidden",severity:"info",description:"반응형 표시 클래스 없이 hidden이 설정되어 있습니다",suggestion:"조건에 따라 표시하려면 sm:block, desktop:flex 등을 추가하세요"})}addIssue(t){this.devTools.addStyleIssue(t)}extractClasses(t){return(t.getAttribute("class")||"").split(/\s+/).filter(Boolean)}getComputedStyles(t){const s=window.getComputedStyle(t),a={};for(const g of me)a[g]=s.getPropertyValue(g.replace(/([A-Z])/g,"-$1").toLowerCase());return a}setupMutationObserver(){typeof MutationObserver>"u"||(this.mutationObserver=new MutationObserver(t=>{let s=!1;for(const a of t){if(a.type==="childList"&&a.addedNodes.length>0){s=!0;break}if(a.type==="attributes"&&(a.attributeName==="class"||a.attributeName==="style")){s=!0;break}}s&&setTimeout(()=>this.scanVisibleComponents(),100)}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["class","style"]}))}fullScan(){return this.scanVisibleComponents(),this.devTools.getStyleValidationInfo().issues}getIssues(){return this.devTools.getStyleValidationInfo().issues}getIssuesForComponent(t){return this.getIssues().filter(s=>s.componentId===t)}clear(){this.trackedComponents.clear(),this.devTools.clearStyleValidationData()}};E(P,"instance",null);let ee=P;function ae(){return ee.getInstance()}const be=`
|
|
#g7-devtools-root {
|
|
/* 기본 폰트 설정 */
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
font-size: 14px;
|
|
line-height: 1.5;
|
|
}
|
|
|
|
#g7-devtools-root * {
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* 패널 기본 스타일 */
|
|
.g7dt-panel {
|
|
position: fixed;
|
|
background-color: #111827;
|
|
color: #ffffff;
|
|
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
|
|
z-index: 9999;
|
|
display: flex;
|
|
flex-direction: column;
|
|
border-radius: 8px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.g7dt-panel.maximized {
|
|
border-radius: 0;
|
|
}
|
|
|
|
/* 리사이즈 핸들 */
|
|
.g7dt-resize-handle {
|
|
position: absolute;
|
|
z-index: 10001;
|
|
background: transparent;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.g7dt-resize-handle:hover {
|
|
background-color: rgba(59, 130, 246, 0.5);
|
|
}
|
|
|
|
.g7dt-resize-corner {
|
|
width: 12px;
|
|
height: 12px;
|
|
}
|
|
|
|
.g7dt-resize-edge-h {
|
|
height: 6px;
|
|
}
|
|
|
|
.g7dt-resize-edge-v {
|
|
width: 6px;
|
|
}
|
|
|
|
.g7dt-resize-nw { top: 0; left: 0; cursor: nw-resize; }
|
|
.g7dt-resize-ne { top: 0; right: 0; cursor: ne-resize; }
|
|
.g7dt-resize-sw { bottom: 0; left: 0; cursor: sw-resize; }
|
|
.g7dt-resize-se { bottom: 0; right: 0; cursor: se-resize; }
|
|
.g7dt-resize-n { top: 0; left: 12px; right: 12px; cursor: n-resize; }
|
|
.g7dt-resize-s { bottom: 0; left: 12px; right: 12px; cursor: s-resize; }
|
|
.g7dt-resize-w { left: 0; top: 12px; bottom: 12px; cursor: w-resize; }
|
|
.g7dt-resize-e { right: 0; top: 12px; bottom: 12px; cursor: e-resize; }
|
|
|
|
/* 헤더 */
|
|
.g7dt-header {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 8px 16px;
|
|
background-color: #1f2937;
|
|
border-bottom: 1px solid #374151;
|
|
flex-shrink: 0;
|
|
border-top-left-radius: 8px;
|
|
border-top-right-radius: 8px;
|
|
cursor: grab;
|
|
user-select: none;
|
|
}
|
|
|
|
.g7dt-header.dragging {
|
|
cursor: grabbing;
|
|
}
|
|
|
|
.g7dt-header-left {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.g7dt-header-title {
|
|
font-weight: 700;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.g7dt-header-badge {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: #374151;
|
|
}
|
|
|
|
.g7dt-header-badge.connected {
|
|
background-color: #059669;
|
|
}
|
|
|
|
.g7dt-header-right {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
.g7dt-btn {
|
|
background: none;
|
|
border: none;
|
|
color: #9ca3af;
|
|
cursor: pointer;
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
transition: all 0.15s ease;
|
|
font-size: 14px;
|
|
}
|
|
|
|
.g7dt-btn:hover {
|
|
color: #ffffff;
|
|
background-color: rgba(255, 255, 255, 0.1);
|
|
}
|
|
|
|
.g7dt-btn-primary {
|
|
background-color: #2563eb;
|
|
color: #ffffff;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.g7dt-btn-primary:hover {
|
|
background-color: #1d4ed8;
|
|
}
|
|
|
|
/* 탭 */
|
|
.g7dt-tabs {
|
|
display: flex;
|
|
border-bottom: 1px solid #374151;
|
|
overflow-x: auto;
|
|
flex-shrink: 0;
|
|
background-color: #111827;
|
|
}
|
|
|
|
.g7dt-tabs::-webkit-scrollbar {
|
|
height: 4px;
|
|
}
|
|
|
|
.g7dt-tabs::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
|
|
.g7dt-tabs::-webkit-scrollbar-thumb {
|
|
background: #374151;
|
|
border-radius: 2px;
|
|
}
|
|
|
|
.g7dt-tab {
|
|
padding: 8px 16px;
|
|
font-size: 13px;
|
|
white-space: nowrap;
|
|
background: none;
|
|
border: none;
|
|
color: #9ca3af;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
border-bottom: 2px solid transparent;
|
|
}
|
|
|
|
.g7dt-tab:hover {
|
|
color: #ffffff;
|
|
background-color: #1f2937;
|
|
}
|
|
|
|
.g7dt-tab.active {
|
|
color: #ffffff;
|
|
background-color: #1f2937;
|
|
border-bottom-color: #3b82f6;
|
|
}
|
|
|
|
/* 콘텐츠 영역 */
|
|
.g7dt-content {
|
|
flex: 1;
|
|
overflow: hidden;
|
|
padding: 16px;
|
|
min-width: 0;
|
|
min-height: 0;
|
|
background-color: #111827;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.g7dt-content::-webkit-scrollbar {
|
|
width: 8px;
|
|
height: 8px;
|
|
}
|
|
|
|
.g7dt-content::-webkit-scrollbar-track {
|
|
background: #1f2937;
|
|
}
|
|
|
|
.g7dt-content::-webkit-scrollbar-thumb {
|
|
background: #4b5563;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
.g7dt-content::-webkit-scrollbar-thumb:hover {
|
|
background: #6b7280;
|
|
}
|
|
|
|
/* 푸터 */
|
|
.g7dt-footer {
|
|
padding: 8px 16px;
|
|
background-color: #1f2937;
|
|
font-size: 11px;
|
|
color: #6b7280;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
border-top: 1px solid #374151;
|
|
flex-shrink: 0;
|
|
border-bottom-left-radius: 8px;
|
|
border-bottom-right-radius: 8px;
|
|
}
|
|
|
|
/* 플로팅 버튼 */
|
|
.g7dt-floating-btn {
|
|
position: fixed;
|
|
bottom: 16px;
|
|
right: 16px;
|
|
background-color: #2563eb;
|
|
color: #ffffff;
|
|
padding: 12px;
|
|
border-radius: 50%;
|
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
z-index: 9999;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.g7dt-floating-btn:hover {
|
|
background-color: #1d4ed8;
|
|
}
|
|
|
|
.g7dt-floating-btn svg {
|
|
width: 24px;
|
|
height: 24px;
|
|
}
|
|
|
|
/* 최소화 상태 */
|
|
.g7dt-minimized {
|
|
position: fixed;
|
|
bottom: 0;
|
|
right: 0;
|
|
background-color: #111827;
|
|
color: #ffffff;
|
|
box-shadow: 0 -4px 6px -1px rgba(0, 0, 0, 0.1);
|
|
z-index: 9999;
|
|
border-top-left-radius: 8px;
|
|
}
|
|
|
|
.g7dt-minimized-content {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 8px 16px;
|
|
gap: 8px;
|
|
}
|
|
|
|
/* 비활성화 알림 */
|
|
.g7dt-disabled-notice {
|
|
position: fixed;
|
|
bottom: 16px;
|
|
right: 16px;
|
|
background-color: #111827;
|
|
color: #ffffff;
|
|
padding: 16px;
|
|
border-radius: 8px;
|
|
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1);
|
|
z-index: 9999;
|
|
max-width: 320px;
|
|
}
|
|
|
|
/* 유틸리티 */
|
|
.g7dt-text-yellow { color: #facc15; }
|
|
.g7dt-text-cyan { color: #22d3ee; }
|
|
.g7dt-text-pink { color: #f472b6; }
|
|
.g7dt-text-orange { color: #fb923c; }
|
|
.g7dt-text-blue { color: #60a5fa; }
|
|
.g7dt-text-purple { color: #c084fc; }
|
|
.g7dt-text-green { color: #4ade80; }
|
|
.g7dt-text-red { color: #f87171; }
|
|
.g7dt-text-gray { color: #9ca3af; }
|
|
.g7dt-text-gray-dark { color: #6b7280; }
|
|
.g7dt-text-white { color: #ffffff; }
|
|
|
|
.g7dt-bg-gray-700 { background-color: #374151; }
|
|
.g7dt-bg-gray-800 { background-color: #1f2937; }
|
|
.g7dt-bg-green-600 { background-color: #059669; }
|
|
.g7dt-bg-red-600 { background-color: #dc2626; }
|
|
.g7dt-bg-blue-600 { background-color: #2563eb; }
|
|
.g7dt-bg-yellow-600 { background-color: #ca8a04; }
|
|
|
|
.g7dt-font-bold { font-weight: 700; }
|
|
.g7dt-font-mono { font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; }
|
|
.g7dt-text-xs { font-size: 11px; }
|
|
.g7dt-text-sm { font-size: 13px; }
|
|
|
|
.g7dt-flex { display: flex; }
|
|
.g7dt-flex-col { flex-direction: column; }
|
|
.g7dt-items-center { align-items: center; }
|
|
.g7dt-justify-between { justify-content: space-between; }
|
|
.g7dt-gap-1 { gap: 4px; }
|
|
.g7dt-gap-2 { gap: 8px; }
|
|
.g7dt-gap-3 { gap: 12px; }
|
|
|
|
.g7dt-ml-1 { margin-left: 4px; }
|
|
.g7dt-ml-2 { margin-left: 8px; }
|
|
.g7dt-ml-4 { margin-left: 16px; }
|
|
.g7dt-mt-1 { margin-top: 4px; }
|
|
.g7dt-mt-2 { margin-top: 8px; }
|
|
.g7dt-mb-1 { margin-bottom: 4px; }
|
|
.g7dt-mb-2 { margin-bottom: 8px; }
|
|
.g7dt-p-1 { padding: 4px; }
|
|
.g7dt-p-2 { padding: 8px; }
|
|
.g7dt-px-1 { padding-left: 4px; padding-right: 4px; }
|
|
.g7dt-px-2 { padding-left: 8px; padding-right: 8px; }
|
|
.g7dt-py-1 { padding-top: 4px; padding-bottom: 4px; }
|
|
|
|
.g7dt-rounded { border-radius: 4px; }
|
|
.g7dt-rounded-lg { border-radius: 8px; }
|
|
|
|
.g7dt-border { border: 1px solid #374151; }
|
|
.g7dt-border-l { border-left: 1px solid #374151; }
|
|
|
|
.g7dt-cursor-pointer { cursor: pointer; }
|
|
.g7dt-select-none { user-select: none; }
|
|
|
|
.g7dt-overflow-auto { overflow: auto; }
|
|
.g7dt-overflow-hidden { overflow: hidden; }
|
|
.g7dt-whitespace-nowrap { white-space: nowrap; }
|
|
.g7dt-truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
.g7dt-w-4 { width: 16px; }
|
|
.g7dt-w-full { width: 100%; }
|
|
.g7dt-h-6 { height: 24px; }
|
|
.g7dt-w-6 { width: 24px; }
|
|
|
|
.g7dt-ring-highlight {
|
|
box-shadow: 0 0 0 1px rgba(250, 204, 21, 0.5);
|
|
background-color: rgba(113, 63, 18, 0.3);
|
|
}
|
|
|
|
/* 입력 필드 */
|
|
.g7dt-input {
|
|
background-color: #1f2937;
|
|
border: 1px solid #374151;
|
|
border-radius: 4px;
|
|
padding: 6px 12px;
|
|
color: #ffffff;
|
|
font-size: 13px;
|
|
outline: none;
|
|
transition: border-color 0.15s ease;
|
|
}
|
|
|
|
.g7dt-input:focus {
|
|
border-color: #3b82f6;
|
|
}
|
|
|
|
.g7dt-input::placeholder {
|
|
color: #6b7280;
|
|
}
|
|
|
|
/* 트리 노드 호버 */
|
|
.g7dt-tree-node {
|
|
padding: 2px 4px;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition: background-color 0.1s ease;
|
|
}
|
|
|
|
.g7dt-tree-node:hover {
|
|
background-color: rgba(55, 65, 81, 0.5);
|
|
}
|
|
|
|
/* 리사이즈 중 하이라이트 */
|
|
.g7dt-resizing .g7dt-resize-handle {
|
|
background-color: rgba(59, 130, 246, 0.3);
|
|
}
|
|
|
|
/* 액션 아이템 */
|
|
.g7dt-action-item {
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
border: 1px solid #374151;
|
|
margin-bottom: 8px;
|
|
background-color: #1f2937;
|
|
}
|
|
|
|
.g7dt-action-item:hover {
|
|
background-color: #283548;
|
|
}
|
|
|
|
/* 액션 아이템 상태별 배경색 */
|
|
.g7dt-action-item.g7dt-status-success {
|
|
background-color: rgba(34, 197, 94, 0.15);
|
|
border-color: rgba(34, 197, 94, 0.4);
|
|
}
|
|
|
|
.g7dt-action-item.g7dt-status-error {
|
|
background-color: rgba(239, 68, 68, 0.15);
|
|
border-color: rgba(239, 68, 68, 0.4);
|
|
}
|
|
|
|
.g7dt-action-item.g7dt-status-started {
|
|
background-color: rgba(59, 130, 246, 0.15);
|
|
border-color: rgba(59, 130, 246, 0.4);
|
|
}
|
|
|
|
.g7dt-action-item.g7dt-status-default {
|
|
background-color: #1f2937;
|
|
border-color: #374151;
|
|
}
|
|
|
|
/* 액션 상세 영역 (토글 펼침) */
|
|
.g7dt-action-details {
|
|
margin-top: 8px;
|
|
padding: 8px;
|
|
background-color: rgba(0, 0, 0, 0.2);
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* 상태 뱃지 */
|
|
.g7dt-status-badge {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding: 2px 8px;
|
|
border-radius: 9999px;
|
|
font-size: 11px;
|
|
font-weight: 500;
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.g7dt-status-success { background-color: rgba(34, 197, 94, 0.3); color: #4ade80; }
|
|
.g7dt-status-error { background-color: rgba(239, 68, 68, 0.3); color: #f87171; }
|
|
.g7dt-status-warning { background-color: rgba(234, 179, 8, 0.3); color: #facc15; }
|
|
.g7dt-status-pending { background-color: rgba(59, 130, 246, 0.3); color: #60a5fa; }
|
|
.g7dt-status-info { background-color: rgba(107, 114, 128, 0.3); color: #9ca3af; }
|
|
.g7dt-status-started { background-color: rgba(59, 130, 246, 0.3); color: #60a5fa; }
|
|
.g7dt-status-default { background-color: rgba(107, 114, 128, 0.3); color: #9ca3af; }
|
|
|
|
/* 코드 블록 */
|
|
.g7dt-code {
|
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
font-size: 12px;
|
|
background-color: #1f2937;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* 선택 불가 */
|
|
.g7dt-noselect {
|
|
-webkit-user-select: none;
|
|
-moz-user-select: none;
|
|
-ms-user-select: none;
|
|
user-select: none;
|
|
}
|
|
|
|
/* 추가 유틸리티 클래스 - flex column으로 변경하여 자식이 늘어나도록 */
|
|
.g7dt-space-y-4 {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-height: 0;
|
|
gap: 16px;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-space-y-2 {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
/* 스크롤 리스트 내부용 - flex column 없이 gap만 */
|
|
.g7dt-space-y-2-flat {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.g7dt-space-y-1 {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 4px;
|
|
}
|
|
|
|
.g7dt-text-muted { color: #6b7280; }
|
|
.g7dt-text-center { text-align: center; }
|
|
.g7dt-text-xxs { font-size: 10px; }
|
|
.g7dt-text-lg { font-size: 18px; }
|
|
|
|
.g7dt-flex-1 { flex: 1; }
|
|
.g7dt-flex-shrink-0 { flex-shrink: 0; }
|
|
.g7dt-flex-wrap { flex-wrap: wrap; }
|
|
.g7dt-items-start { align-items: flex-start; }
|
|
.g7dt-justify-center { justify-content: center; }
|
|
.g7dt-mb-3 { margin-bottom: 12px; }
|
|
.g7dt-mt-3 { margin-top: 12px; }
|
|
.g7dt-pt-3 { padding-top: 12px; }
|
|
|
|
.g7dt-mono { font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace; }
|
|
.g7dt-uppercase { text-transform: uppercase; }
|
|
.g7dt-whitespace-pre-wrap { white-space: pre-wrap; }
|
|
|
|
.g7dt-w-32 { width: 128px; }
|
|
.g7dt-max-h-16 { max-height: 64px; }
|
|
.g7dt-max-h-40 { max-height: 160px; }
|
|
.g7dt-max-h-60 { max-height: 240px; }
|
|
.g7dt-overflow-auto { overflow: auto; }
|
|
.g7dt-border-t { border-top: 1px solid #374151; }
|
|
|
|
/* 그리드 레이아웃 */
|
|
.g7dt-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); }
|
|
.g7dt-stats-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 12px; }
|
|
.g7dt-stats-grid-2 { display: grid; grid-template-columns: repeat(2, 1fr); gap: 12px; }
|
|
.g7dt-stats-grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 12px; }
|
|
.g7dt-stats-grid-5 { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
|
|
.g7dt-stats-grid-6 { display: grid; grid-template-columns: repeat(6, 1fr); gap: 8px; }
|
|
|
|
/* 카드 및 리스트 스타일 */
|
|
.g7dt-card {
|
|
background-color: #1f2937;
|
|
padding: 12px;
|
|
border-radius: 4px;
|
|
border: 1px solid #374151;
|
|
}
|
|
|
|
.g7dt-stat-card {
|
|
background-color: #1f2937;
|
|
padding: 12px;
|
|
border-radius: 4px;
|
|
text-align: center;
|
|
border: 1px solid #374151;
|
|
}
|
|
|
|
.g7dt-stat-card-sm {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
text-align: center;
|
|
border: 1px solid #374151;
|
|
}
|
|
|
|
.g7dt-stat-value {
|
|
font-size: 20px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.g7dt-stat-value-sm {
|
|
font-size: 18px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.g7dt-stat-label {
|
|
font-size: 11px;
|
|
color: #6b7280;
|
|
}
|
|
|
|
/* 스크롤 리스트 - flex로 남은 공간 채움 */
|
|
.g7dt-scroll-list {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-scroll-list > * + * { margin-top: 4px; }
|
|
|
|
.g7dt-scroll-list-sm {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-scroll-list-sm > * + * { margin-top: 4px; }
|
|
|
|
.g7dt-scroll-list-lg {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-scroll-list-lg > * + * { margin-top: 4px; }
|
|
|
|
.g7dt-scroll-list-xs {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-scroll-list-xs > * + * { margin-top: 4px; }
|
|
|
|
/* 탭 콘텐츠 래퍼 - flex column으로 자식이 늘어나도록 */
|
|
.g7dt-tab-content {
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100%;
|
|
min-height: 0;
|
|
}
|
|
|
|
/* 섹션 래퍼 - flex로 스크롤 리스트가 늘어나도록 */
|
|
.g7dt-section {
|
|
display: flex;
|
|
flex-direction: column;
|
|
flex: 1;
|
|
min-height: 0;
|
|
}
|
|
|
|
/* 빈 상태 */
|
|
.g7dt-empty-state {
|
|
color: #6b7280;
|
|
font-size: 13px;
|
|
text-align: center;
|
|
padding: 16px;
|
|
}
|
|
|
|
/* 버튼 스타일 */
|
|
.g7dt-btn-secondary {
|
|
background-color: #374151;
|
|
color: #ffffff;
|
|
font-size: 12px;
|
|
padding: 4px 12px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.g7dt-btn-secondary:hover {
|
|
background-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-btn-danger {
|
|
background-color: #b91c1c;
|
|
color: #ffffff;
|
|
font-size: 12px;
|
|
padding: 4px 12px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.g7dt-btn-danger:hover {
|
|
background-color: #dc2626;
|
|
}
|
|
|
|
.g7dt-close-btn {
|
|
color: #9ca3af;
|
|
font-size: 12px;
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
padding: 4px;
|
|
}
|
|
|
|
.g7dt-close-btn:hover {
|
|
color: #ffffff;
|
|
}
|
|
|
|
.g7dt-filter-btn {
|
|
font-size: 12px;
|
|
padding: 4px 12px;
|
|
border-radius: 4px;
|
|
background-color: #1f2937;
|
|
color: #9ca3af;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-filter-btn:hover {
|
|
background-color: #374151;
|
|
}
|
|
|
|
.g7dt-filter-btn-active,
|
|
.g7dt-filter-btn-active-yellow {
|
|
background-color: #ca8a04;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.g7dt-prefix-btn {
|
|
font-size: 12px;
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
background-color: #1f2937;
|
|
border: 1px solid #374151;
|
|
color: #ffffff;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-prefix-btn:hover {
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-prefix-btn-active {
|
|
background-color: #2563eb;
|
|
border-color: #1d4ed8;
|
|
color: #ffffff;
|
|
}
|
|
|
|
/* Select 스타일 */
|
|
.g7dt-select {
|
|
background-color: #1f2937;
|
|
border: 1px solid #374151;
|
|
border-radius: 4px;
|
|
padding: 4px 12px;
|
|
color: #ffffff;
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* 리스트 아이템 */
|
|
.g7dt-list-item {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid #374151;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
.g7dt-list-item:hover {
|
|
background-color: #374151;
|
|
}
|
|
|
|
/* 렌더 로그 아이템 */
|
|
.g7dt-render-log-item {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid #374151;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-render-log-item:hover {
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-render-log-item.g7dt-selected {
|
|
border-color: #2563eb;
|
|
background-color: rgba(37, 99, 235, 0.2);
|
|
}
|
|
|
|
.g7dt-render-log-item.g7dt-warning {
|
|
border-color: rgba(161, 98, 7, 0.5);
|
|
}
|
|
|
|
.g7dt-render-log-item.g7dt-warning:hover {
|
|
border-color: #ca8a04;
|
|
}
|
|
|
|
.g7dt-render-comp-item {
|
|
background-color: #111827;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
}
|
|
|
|
/* 경고 박스 */
|
|
.g7dt-warning-box {
|
|
background-color: rgba(161, 98, 7, 0.2);
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
border: 1px solid rgba(161, 98, 7, 0.5);
|
|
}
|
|
|
|
.g7dt-list {
|
|
list-style-type: disc;
|
|
padding-left: 16px;
|
|
}
|
|
|
|
/* 태그 */
|
|
.g7dt-tag {
|
|
font-size: 12px;
|
|
background-color: #1f2937;
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
border: 1px solid #374151;
|
|
}
|
|
|
|
.g7dt-role-tag {
|
|
background-color: rgba(37, 99, 235, 0.3);
|
|
color: #93c5fd;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.g7dt-perm-tag {
|
|
background-color: rgba(147, 51, 234, 0.3);
|
|
color: #d8b4fe;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* Pre 스타일 */
|
|
.g7dt-pre {
|
|
margin-top: 4px;
|
|
padding: 8px;
|
|
background-color: #111827;
|
|
border-radius: 4px;
|
|
overflow: auto;
|
|
max-height: 80px;
|
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
font-size: 12px;
|
|
}
|
|
|
|
.g7dt-pre-stack {
|
|
margin-top: 4px;
|
|
padding: 8px;
|
|
background-color: #111827;
|
|
border-radius: 4px;
|
|
overflow: auto;
|
|
max-height: 128px;
|
|
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
|
|
font-size: 10px;
|
|
}
|
|
|
|
/* 인증 이벤트 아이템 */
|
|
.g7dt-auth-event-item {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid #374151;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-auth-event-item:hover {
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-auth-event-item.g7dt-selected {
|
|
border-color: #2563eb;
|
|
background-color: rgba(37, 99, 235, 0.2);
|
|
}
|
|
|
|
.g7dt-auth-event-item.g7dt-error {
|
|
border-color: rgba(185, 28, 28, 0.5);
|
|
}
|
|
|
|
.g7dt-auth-event-item.g7dt-error:hover {
|
|
border-color: #dc2626;
|
|
}
|
|
|
|
/* 헤더 아이템 */
|
|
.g7dt-header-item {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid #374151;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
}
|
|
|
|
/* 로그 아이템 */
|
|
.g7dt-log-item {
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-log-item.g7dt-selected {
|
|
border-color: #2563eb;
|
|
background-color: rgba(37, 99, 235, 0.2);
|
|
}
|
|
|
|
.g7dt-log-error {
|
|
background-color: rgba(185, 28, 28, 0.3);
|
|
border-color: #b91c1c;
|
|
}
|
|
|
|
.g7dt-log-warn {
|
|
background-color: rgba(161, 98, 7, 0.3);
|
|
border-color: #a16207;
|
|
}
|
|
|
|
.g7dt-log-info {
|
|
background-color: rgba(37, 99, 235, 0.3);
|
|
border-color: #2563eb;
|
|
}
|
|
|
|
.g7dt-log-debug {
|
|
background-color: #1f2937;
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-log-default {
|
|
background-color: #1f2937;
|
|
border-color: #374151;
|
|
}
|
|
|
|
/* 스타일 이슈 아이템 */
|
|
.g7dt-style-issue-item {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-style-issue-item:hover {
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-style-issue-item.g7dt-selected {
|
|
border-color: #2563eb;
|
|
background-color: rgba(37, 99, 235, 0.2);
|
|
}
|
|
|
|
.g7dt-severity-error { border-color: rgba(185, 28, 28, 0.5); }
|
|
.g7dt-severity-warning { border-color: rgba(161, 98, 7, 0.5); }
|
|
.g7dt-severity-info { border-color: rgba(37, 99, 235, 0.5); }
|
|
|
|
/* 뱃지 */
|
|
.g7dt-badge-error {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: rgba(185, 28, 28, 0.5);
|
|
color: #fca5a5;
|
|
}
|
|
|
|
.g7dt-badge-warning {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: rgba(161, 98, 7, 0.5);
|
|
color: #fcd34d;
|
|
}
|
|
|
|
.g7dt-badge-info {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: rgba(37, 99, 235, 0.5);
|
|
color: #93c5fd;
|
|
}
|
|
|
|
.g7dt-badge-success {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: rgba(34, 197, 94, 0.5);
|
|
color: #86efac;
|
|
}
|
|
|
|
.g7dt-badge-gray {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: rgba(107, 114, 128, 0.5);
|
|
color: #d1d5db;
|
|
}
|
|
|
|
.g7dt-badge-blue {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: rgba(59, 130, 246, 0.5);
|
|
color: #93c5fd;
|
|
}
|
|
|
|
.g7dt-badge-purple {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: rgba(147, 51, 234, 0.5);
|
|
color: #d8b4fe;
|
|
}
|
|
|
|
/* 미니 뱃지 */
|
|
.g7dt-mini-badge {
|
|
font-size: 10px;
|
|
padding: 1px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* 데이터소스 그리드 */
|
|
.g7dt-ds-grid {
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr);
|
|
gap: 12px;
|
|
}
|
|
|
|
.g7dt-ds-item {
|
|
background-color: #1f2937;
|
|
padding: 12px;
|
|
border-radius: 8px;
|
|
border: 1px solid #374151;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-ds-item:hover {
|
|
border-color: #4b5563;
|
|
background-color: #283548;
|
|
}
|
|
|
|
.g7dt-ds-selected {
|
|
border-color: #2563eb;
|
|
background-color: rgba(37, 99, 235, 0.15);
|
|
}
|
|
|
|
/* 액션 리스트 - flex 부모에서 늘어남 */
|
|
.g7dt-action-list {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-action-list > * + * { margin-top: 8px; }
|
|
|
|
/* 이벤트 리스트 - flex 부모에서 늘어남 */
|
|
.g7dt-event-list {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-event-list > * + * { margin-top: 4px; }
|
|
|
|
/* 핸들러 리스트 - flex 부모에서 늘어남 */
|
|
.g7dt-handler-list {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-handler-list > * + * { margin-top: 4px; }
|
|
|
|
/* 표현식 리스트 - flex 부모에서 늘어남 */
|
|
.g7dt-expr-list {
|
|
flex: 1;
|
|
min-height: 0;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.g7dt-expr-list > * + * { margin-top: 4px; }
|
|
|
|
.g7dt-expr-item {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid #374151;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-expr-item:hover {
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-expr-selected {
|
|
border-color: #2563eb;
|
|
background-color: rgba(37, 99, 235, 0.2);
|
|
}
|
|
|
|
.g7dt-expr-warning {
|
|
border-color: rgba(161, 98, 7, 0.5);
|
|
}
|
|
|
|
.g7dt-expr-warning:hover {
|
|
border-color: #ca8a04;
|
|
}
|
|
|
|
/* 조건 아이템 */
|
|
.g7dt-condition-item {
|
|
background-color: #1f2937;
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
font-size: 12px;
|
|
border: 1px solid #374151;
|
|
}
|
|
|
|
.g7dt-condition-true {
|
|
border-color: rgba(34, 197, 94, 0.5);
|
|
}
|
|
|
|
.g7dt-condition-false {
|
|
border-color: rgba(185, 28, 28, 0.5);
|
|
}
|
|
|
|
/* 키 태그 */
|
|
.g7dt-key-tag {
|
|
font-size: 11px;
|
|
background-color: #374151;
|
|
color: #d1d5db;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* 의존성 태그 */
|
|
.g7dt-dep-tag {
|
|
font-size: 11px;
|
|
background-color: rgba(34, 197, 94, 0.2);
|
|
color: #86efac;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* 타입 태그 */
|
|
.g7dt-type-tag {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: #374151;
|
|
}
|
|
|
|
/* 태그 블루 */
|
|
.g7dt-tag-blue {
|
|
background-color: rgba(59, 130, 246, 0.3);
|
|
color: #93c5fd;
|
|
}
|
|
|
|
/* 경고 태그 */
|
|
.g7dt-warning-tag {
|
|
font-size: 11px;
|
|
background-color: rgba(161, 98, 7, 0.3);
|
|
color: #fcd34d;
|
|
padding: 2px 6px;
|
|
border-radius: 4px;
|
|
}
|
|
|
|
/* 신뢰도 뱃지 */
|
|
.g7dt-confidence-badge {
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border-radius: 4px;
|
|
background-color: #374151;
|
|
}
|
|
|
|
/* 증상 버튼 */
|
|
.g7dt-symptom-btn {
|
|
font-size: 12px;
|
|
padding: 6px 12px;
|
|
border-radius: 4px;
|
|
background-color: #1f2937;
|
|
border: 1px solid #374151;
|
|
color: #9ca3af;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-symptom-btn:hover {
|
|
border-color: #4b5563;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.g7dt-symptom-active {
|
|
background-color: #2563eb;
|
|
border-color: #1d4ed8;
|
|
color: #ffffff;
|
|
}
|
|
|
|
/* 버튼 추가 스타일 */
|
|
.g7dt-btn-close {
|
|
color: #9ca3af;
|
|
background: none;
|
|
border: none;
|
|
cursor: pointer;
|
|
padding: 4px;
|
|
font-size: 14px;
|
|
transition: color 0.15s ease;
|
|
}
|
|
|
|
.g7dt-btn-close:hover {
|
|
color: #ffffff;
|
|
}
|
|
|
|
.g7dt-btn-danger-sm {
|
|
background-color: #b91c1c;
|
|
color: #ffffff;
|
|
font-size: 11px;
|
|
padding: 2px 8px;
|
|
border: none;
|
|
border-radius: 4px;
|
|
cursor: pointer;
|
|
transition: background-color 0.15s ease;
|
|
}
|
|
|
|
.g7dt-btn-danger-sm:hover {
|
|
background-color: #dc2626;
|
|
}
|
|
|
|
.g7dt-btn-disabled {
|
|
opacity: 0.5;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.g7dt-btn-text {
|
|
background: none;
|
|
border: none;
|
|
color: #60a5fa;
|
|
cursor: pointer;
|
|
font-size: 12px;
|
|
padding: 0;
|
|
}
|
|
|
|
.g7dt-btn-text:hover {
|
|
text-decoration: underline;
|
|
}
|
|
|
|
/* 필터 활성화 */
|
|
.g7dt-filter-active {
|
|
background-color: #2563eb;
|
|
color: #ffffff;
|
|
}
|
|
|
|
/* 체크박스 */
|
|
.g7dt-checkbox {
|
|
width: 16px;
|
|
height: 16px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.g7dt-checkbox-label {
|
|
font-size: 13px;
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 8px;
|
|
}
|
|
|
|
/* 카드 에러 */
|
|
.g7dt-card-error {
|
|
background-color: #1f2937;
|
|
padding: 12px;
|
|
border-radius: 4px;
|
|
border: 1px solid rgba(185, 28, 28, 0.5);
|
|
}
|
|
|
|
/* 에러 박스 */
|
|
.g7dt-error-box {
|
|
background-color: rgba(185, 28, 28, 0.2);
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
border: 1px solid rgba(185, 28, 28, 0.5);
|
|
}
|
|
|
|
.g7dt-error-inline {
|
|
color: #f87171;
|
|
font-size: 12px;
|
|
}
|
|
|
|
/* 경고 박스 라이트 */
|
|
.g7dt-warning-box-light {
|
|
background-color: rgba(161, 98, 7, 0.15);
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
border: 1px solid rgba(161, 98, 7, 0.3);
|
|
}
|
|
|
|
/* 경고 카드 (빨간 배경) */
|
|
.g7dt-warning-card {
|
|
background-color: rgba(185, 28, 28, 0.4);
|
|
padding: 12px;
|
|
border-radius: 4px;
|
|
border: 1px solid rgba(185, 28, 28, 0.6);
|
|
}
|
|
|
|
/* 빈 메시지 */
|
|
.g7dt-empty-message {
|
|
color: #6b7280;
|
|
font-size: 13px;
|
|
text-align: center;
|
|
}
|
|
|
|
/* 요약 (토글 헤더) - 투명 배경 */
|
|
.g7dt-summary {
|
|
font-size: 12px;
|
|
font-weight: 500;
|
|
cursor: pointer;
|
|
padding: 4px 0;
|
|
color: #9ca3af;
|
|
list-style: none;
|
|
}
|
|
|
|
.g7dt-summary::-webkit-details-marker {
|
|
display: none;
|
|
}
|
|
|
|
.g7dt-summary::before {
|
|
content: '▶ ';
|
|
font-size: 10px;
|
|
}
|
|
|
|
details[open] > .g7dt-summary::before {
|
|
content: '▼ ';
|
|
}
|
|
|
|
/* 상세 영역 - 배경 없음, 펼쳐진 내용만 스타일 */
|
|
.g7dt-details {
|
|
margin-top: 4px;
|
|
}
|
|
|
|
/* 펼쳐진 내용에만 배경색 적용 - 스크롤 제거 */
|
|
.g7dt-details > .g7dt-pre {
|
|
background-color: rgba(0, 0, 0, 0.3);
|
|
border-radius: 4px;
|
|
max-height: none;
|
|
overflow: visible;
|
|
}
|
|
|
|
/* 프로그레스 바 */
|
|
.g7dt-progress-bar {
|
|
width: 100%;
|
|
height: 8px;
|
|
background-color: #374151;
|
|
border-radius: 4px;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.g7dt-progress-fill {
|
|
height: 100%;
|
|
background-color: #2563eb;
|
|
transition: width 0.3s ease;
|
|
}
|
|
|
|
/* 대기 중 요청 */
|
|
.g7dt-pending-request {
|
|
background-color: rgba(59, 130, 246, 0.2);
|
|
border: 1px solid rgba(59, 130, 246, 0.5);
|
|
padding: 8px;
|
|
border-radius: 4px;
|
|
animation: pulse 2s infinite;
|
|
}
|
|
|
|
@keyframes pulse {
|
|
0%, 100% { opacity: 1; }
|
|
50% { opacity: 0.7; }
|
|
}
|
|
|
|
/* 추가 유틸리티 */
|
|
.g7dt-space-y-3 > * + * { margin-top: 12px; }
|
|
.g7dt-space-y-6 > * + * { margin-top: 24px; }
|
|
|
|
.g7dt-mr-2 { margin-right: 8px; }
|
|
.g7dt-pl-2 { padding-left: 8px; }
|
|
.g7dt-py-4 { padding-top: 16px; padding-bottom: 16px; }
|
|
.g7dt-py-8 { padding-top: 32px; padding-bottom: 32px; }
|
|
|
|
.g7dt-col-span-2 { grid-column: span 2; }
|
|
.g7dt-min-w-0 { min-width: 0; }
|
|
.g7dt-items-end { align-items: flex-end; }
|
|
|
|
.g7dt-text-lightgray { color: #d1d5db; }
|
|
.g7dt-text-darkgray { color: #4b5563; }
|
|
|
|
.g7dt-truncate-60 {
|
|
max-width: 60%;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.g7dt-stat-label-xs {
|
|
font-size: 10px;
|
|
color: #6b7280;
|
|
}
|
|
|
|
.g7dt-stat-value-lg {
|
|
font-size: 24px;
|
|
font-weight: 700;
|
|
}
|
|
|
|
.g7dt-status-default { background-color: rgba(107, 114, 128, 0.2); color: #9ca3af; }
|
|
.g7dt-status-started { background-color: rgba(59, 130, 246, 0.2); color: #60a5fa; }
|
|
|
|
/* Layout 탭 전용 스타일 */
|
|
.g7dt-btn-small {
|
|
padding: 4px 8px;
|
|
font-size: 11px;
|
|
border-radius: 4px;
|
|
background-color: #374151;
|
|
color: #9ca3af;
|
|
border: none;
|
|
cursor: pointer;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-btn-small:hover {
|
|
background-color: #4b5563;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.g7dt-section-btn {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 8px 12px;
|
|
background-color: #1f2937;
|
|
border: 1px solid #374151;
|
|
border-radius: 4px;
|
|
color: #d1d5db;
|
|
cursor: pointer;
|
|
font-size: 12px;
|
|
transition: all 0.15s ease;
|
|
}
|
|
|
|
.g7dt-section-btn:hover {
|
|
background-color: #374151;
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-section-btn.g7dt-selected {
|
|
background-color: #1e40af;
|
|
border-color: #3b82f6;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.g7dt-history-item {
|
|
padding: 8px;
|
|
background-color: #1f2937;
|
|
border-radius: 4px;
|
|
border: 1px solid #374151;
|
|
}
|
|
|
|
.g7dt-history-item:hover {
|
|
border-color: #4b5563;
|
|
}
|
|
|
|
.g7dt-max-h-96 {
|
|
max-height: 24rem;
|
|
}
|
|
|
|
.g7dt-overflow-auto {
|
|
overflow: auto;
|
|
}
|
|
|
|
.g7dt-list-disc {
|
|
list-style-type: disc;
|
|
}
|
|
|
|
.g7dt-cursor-pointer {
|
|
cursor: pointer;
|
|
}
|
|
`,ve=()=>{const d="g7-devtools-styles";if(document.getElementById(d))return;const t=document.createElement("style");t.id=d,t.textContent=be,document.head.appendChild(t)},le={state:"상태",actions:"액션",cache:"캐시",diagnose:"진단",performance:"성능",lifecycle:"라이프사이클",network:"네트워크",form:"Form",conditional:"조건부",expression:"표현식",handlers:"핸들러",events:"이벤트",datasources:"데이터소스",renders:"렌더링",styles:"스타일",auth:"인증",logs:"로그",layout:"레이아웃",changedetection:"변경감지",staleclosure:"Stale Closure",nestedcontext:"Context",modalscope:"모달스코프",namedactions:"Named Actions"},Ne=700,ue=500,re=400,ce=300,ne="g7-devtools-panel",te=d=>d===null||d===void 0?"g7dt-text-gray":typeof d=="string"?"g7dt-text-yellow":typeof d=="number"?"g7dt-text-cyan":typeof d=="boolean"?"g7dt-text-pink":Array.isArray(d)?"g7dt-text-orange":typeof d=="object"?"g7dt-text-blue":"g7dt-text-white",ye=d=>d===null?"null":d===void 0?"undefined":Array.isArray(d)?`Array(${d.length})`:typeof d=="object"?`Object(${Object.keys(d).length})`:typeof d,we=d=>d===null?"null":d===void 0?"undefined":typeof d=="string"?d.length>50?`"${d.substring(0,50)}..."`:`"${d}"`:typeof d=="boolean"?d?"true":"false":typeof d=="number"?String(d):"",oe=()=>{try{const d=localStorage.getItem(ne);if(d)return JSON.parse(d)}catch(d){console.warn("[G7DevTools] 설정 로드 실패:",d)}return{}},ie=d=>{try{const s={...oe(),...d};localStorage.setItem(ne,JSON.stringify(s))}catch(t){console.warn("[G7DevTools] 설정 저장 실패:",t)}},W=({keyName:d,value:t,path:s,expandedPaths:a,onToggle:g,searchTerm:r,depth:o=0})=>{const p=t!==null&&typeof t=="object",v=a.has(s),l=Array.isArray(t),f=r&&(d.toLowerCase().includes(r.toLowerCase())||typeof t=="string"&&t.toLowerCase().includes(r.toLowerCase())||typeof t=="number"&&String(t).includes(r)),c=y=>{y.stopPropagation(),p&&g(s)},h=p?Object.entries(t):[];return e.jsxs("div",{style:{marginLeft:o>0?"16px":"0"},children:[e.jsxs("div",{className:`g7dt-tree-node g7dt-flex g7dt-items-center g7dt-gap-1 ${f?"g7dt-ring-highlight":""}`,onClick:c,children:[p?e.jsx("span",{className:"g7dt-text-gray g7dt-w-4 g7dt-text-xs g7dt-select-none",style:{textAlign:"center"},children:v?"▼":"▶"}):e.jsx("span",{className:"g7dt-w-4"}),e.jsx("span",{className:"g7dt-text-purple g7dt-text-xs",children:d}),e.jsx("span",{className:"g7dt-text-gray-dark g7dt-text-xs",children:":"}),p?e.jsxs("span",{className:`g7dt-text-xs ${te(t)}`,children:[l?"[":"{",!v&&e.jsx("span",{className:"g7dt-text-gray",style:{margin:"0 4px"},children:ye(t)}),!v&&(l?"]":"}")]}):e.jsx("span",{className:`g7dt-text-xs ${te(t)}`,children:we(t)}),!p&&e.jsxs("span",{className:"g7dt-text-gray-dark g7dt-text-xs g7dt-ml-1",children:["(",typeof t,")"]})]}),p&&v&&e.jsxs("div",{className:"g7dt-border-l",style:{marginLeft:"8px"},children:[h.map(([y,n])=>e.jsx(W,{keyName:l?`[${y}]`:y,value:n,path:`${s}.${y}`,expandedPaths:a,onToggle:g,searchTerm:r,depth:o+1},`${s}.${y}`)),e.jsx("div",{className:"g7dt-ml-4 g7dt-text-xs",children:e.jsx("span",{className:te(t),children:l?"]":"}"})})]})]})},ke=({state:d,devTools:t})=>{const[s,a]=x.useState(new Set(["_global","_local","_computed","_isolated","$parent"])),[g,r]=x.useState(""),[o,p]=x.useState(!1),[v,l]=x.useState(!1),[f,c]=x.useState(null),h=x.useCallback(()=>{t&&c(t.getComputedDependencyTrackingInfo())},[t]);x.useEffect(()=>{if(v&&t){h();const w=setInterval(h,2e3);return()=>clearInterval(w)}},[v,t,h]);const y=w=>{switch(w){case"state-change":return"📊";case"prop-change":return"📥";case"dependency-change":return"🔗";case"manual":return"👆";case"initial":return"🚀";default:return"❓"}},n=x.useCallback(w=>{a(S=>{const z=new Set(S);return z.has(w)?z.delete(w):z.add(w),z})},[]),i=x.useCallback((w,S)=>{const z=[S];if(w!==null&&typeof w=="object")for(const[O,K]of Object.entries(w))z.push(...i(K,`${S}.${O}`));return z},[]),u=x.useCallback(()=>{if(o)a(new Set(["_global","_local","_computed","_isolated","$parent"]));else{const w=new Set;i(d._global,"_global").forEach(S=>w.add(S)),i(d._local,"_local").forEach(S=>w.add(S)),i(d._computed,"_computed").forEach(S=>w.add(S)),i(d._isolated,"_isolated").forEach(S=>w.add(S)),d.$parent&&i(d.$parent,"$parent").forEach(S=>w.add(S)),a(w)}p(!o)},[o,d,i]),m=Object.keys(d._global||{}).length,k=Object.keys(d._local||{}).length,b=Object.keys(d._computed||{}).length,N=Object.keys(d._isolated||{}).length,C=Object.keys(d.$parent||{}).length;return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-items-center g7dt-flex-shrink-0",children:[e.jsx("input",{type:"text",placeholder:"키 또는 값 검색...",value:g,onChange:w=>r(w.target.value),className:"g7dt-input g7dt-flex-1"}),e.jsx("button",{onClick:u,className:"g7dt-btn g7dt-bg-gray-700",children:o?"모두 접기":"모두 펼치기"})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-3 g7dt-text-xs g7dt-text-gray g7dt-flex-wrap g7dt-flex-shrink-0",children:[e.jsxs("span",{children:[e.jsx("span",{className:"g7dt-text-yellow",children:"●"})," string"]}),e.jsxs("span",{children:[e.jsx("span",{className:"g7dt-text-cyan",children:"●"})," number"]}),e.jsxs("span",{children:[e.jsx("span",{className:"g7dt-text-pink",children:"●"})," boolean"]}),e.jsxs("span",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"●"})," null"]}),e.jsxs("span",{children:[e.jsx("span",{className:"g7dt-text-orange",children:"●"})," array"]}),e.jsxs("span",{children:[e.jsx("span",{className:"g7dt-text-blue",children:"●"})," object"]})]}),e.jsxs("div",{className:"g7dt-bg-gray-800 g7dt-rounded g7dt-p-2 g7dt-overflow-auto g7dt-border",style:{flex:1,minHeight:0},children:[e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-sm g7dt-font-bold g7dt-text-green g7dt-mb-1 g7dt-cursor-pointer",onClick:()=>n("_global"),children:[e.jsx("span",{children:s.has("_global")?"▼":"▶"}),e.jsx("span",{children:"_global"}),e.jsxs("span",{className:"g7dt-text-gray g7dt-text-xs",style:{fontWeight:"normal"},children:["(",m,"개 키)"]})]}),s.has("_global")&&e.jsx("div",{className:"g7dt-ml-2 g7dt-border-l",children:Object.entries(d._global||{}).map(([w,S])=>e.jsx(W,{keyName:w,value:S,path:`_global.${w}`,expandedPaths:s,onToggle:n,searchTerm:g},`_global.${w}`))})]}),e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-sm g7dt-font-bold g7dt-text-blue g7dt-mb-1 g7dt-cursor-pointer",onClick:()=>n("_local"),children:[e.jsx("span",{children:s.has("_local")?"▼":"▶"}),e.jsx("span",{children:"_local"}),e.jsxs("span",{className:"g7dt-text-gray g7dt-text-xs",style:{fontWeight:"normal"},children:["(",k,"개 키)"]})]}),s.has("_local")&&e.jsx("div",{className:"g7dt-ml-2 g7dt-border-l",children:Object.entries(d._local||{}).map(([w,S])=>e.jsx(W,{keyName:w,value:S,path:`_local.${w}`,expandedPaths:s,onToggle:n,searchTerm:g},`_local.${w}`))})]}),e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-sm g7dt-font-bold g7dt-text-purple g7dt-mb-1 g7dt-cursor-pointer",onClick:()=>n("_computed"),children:[e.jsx("span",{children:s.has("_computed")?"▼":"▶"}),e.jsx("span",{children:"_computed"}),e.jsxs("span",{className:"g7dt-text-gray g7dt-text-xs",style:{fontWeight:"normal"},children:["(",b,"개 키)"]})]}),s.has("_computed")&&e.jsx("div",{className:"g7dt-ml-2 g7dt-border-l",children:Object.entries(d._computed||{}).map(([w,S])=>e.jsx(W,{keyName:w,value:S,path:`_computed.${w}`,expandedPaths:s,onToggle:n,searchTerm:g},`_computed.${w}`))})]}),N>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-sm g7dt-font-bold g7dt-text-orange g7dt-mb-1 g7dt-cursor-pointer",onClick:()=>n("_isolated"),children:[e.jsx("span",{children:s.has("_isolated")?"▼":"▶"}),e.jsx("span",{children:"_isolated"}),e.jsxs("span",{className:"g7dt-text-gray g7dt-text-xs",style:{fontWeight:"normal"},children:["(",N,"개 스코프)"]})]}),s.has("_isolated")&&e.jsx("div",{className:"g7dt-ml-2 g7dt-border-l",children:Object.entries(d._isolated||{}).map(([w,S])=>e.jsx(W,{keyName:w,value:S,path:`_isolated.${w}`,expandedPaths:s,onToggle:n,searchTerm:g},`_isolated.${w}`))})]}),C>0&&e.jsxs("div",{children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-sm g7dt-font-bold g7dt-text-cyan g7dt-mb-1 g7dt-cursor-pointer",onClick:()=>n("$parent"),children:[e.jsx("span",{children:s.has("$parent")?"▼":"▶"}),e.jsx("span",{children:"$parent"}),e.jsxs("span",{className:"g7dt-text-gray g7dt-text-xs",style:{fontWeight:"normal"},children:["(",C,"개 키)"]})]}),s.has("$parent")&&e.jsx("div",{className:"g7dt-ml-2 g7dt-border-l",children:Object.entries(d.$parent||{}).map(([w,S])=>e.jsx(W,{keyName:w,value:S,path:`$parent.${w}`,expandedPaths:s,onToggle:n,searchTerm:g},`$parent.${w}`))})]})]}),t&&e.jsx("div",{className:"g7dt-flex g7dt-justify-end g7dt-mt-2",children:e.jsx("button",{onClick:()=>l(!v),className:`g7dt-tab-button ${v?"g7dt-tab-active":""}`,children:"🧮 Computed 추적"})}),v&&f&&e.jsxs("div",{className:"g7dt-card g7dt-mt-2",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:["Computed 의존성 추적 (",f.properties.length,"개)"]}),e.jsxs("div",{className:"g7dt-stats-grid g7dt-mb-3",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-purple",children:f.stats.totalComputed}),e.jsx("div",{className:"g7dt-stat-label",children:"Computed"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-blue",children:f.stats.totalRecalculations}),e.jsx("div",{className:"g7dt-stat-label",children:"재계산"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-yellow",children:f.stats.unnecessaryRecalculations}),e.jsx("div",{className:"g7dt-stat-label",children:"불필요"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsxs("div",{className:"g7dt-stat-value g7dt-text-green",children:[f.stats.avgComputationTime.toFixed(1),"ms"]}),e.jsx("div",{className:"g7dt-stat-label",children:"평균시간"})]})]}),f.stats.cycleDetectionCount>0&&e.jsxs("div",{className:"g7dt-text-xs g7dt-text-red g7dt-mb-3 g7dt-p-2 g7dt-bg-red-900 g7dt-rounded",children:["⚠️ 순환 의존성 감지: ",f.stats.cycleDetectionCount,"건"]}),f.stats.topRecalculated.length>0&&e.jsxs("div",{className:"g7dt-mb-3",children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-2",children:"자주 재계산되는 속성"}),e.jsx("div",{className:"g7dt-space-y-1",children:f.stats.topRecalculated.slice(0,3).map((w,S)=>e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-text-xs",children:[e.jsx("span",{className:"g7dt-text-purple g7dt-font-mono",children:w.name}),e.jsxs("span",{className:"g7dt-text-muted",children:[w.count,"회"]})]},S))})]}),f.recalcLogs.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"재계산 로그가 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-40 g7dt-overflow-y-auto",children:f.recalcLogs.slice().reverse().slice(0,20).map(w=>e.jsxs("div",{className:`g7dt-list-item ${w.valueChanged?"":"g7dt-border-yellow"}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:y(w.trigger)}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-purple g7dt-font-mono",children:w.computedName}),!w.valueChanged&&e.jsx("span",{className:"g7dt-badge g7dt-text-xs g7dt-text-yellow",children:"값 변경 없음"}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:[w.computationTime.toFixed(1),"ms"]})]}),w.triggeredBy&&e.jsxs("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mt-1",children:["트리거: ",e.jsx("span",{className:"g7dt-text-blue",children:w.triggeredBy.path})]})]},w.id))})]})]})},Ce=({actions:d,devTools:t})=>{const[s,a]=x.useState(""),[g,r]=x.useState("actions"),[o,p]=x.useState(null),[v,l]=x.useState(null),f=x.useCallback(()=>{t&&p(t.getSequenceTrackingInfo())},[t]);x.useEffect(()=>{if(g==="sequences"&&t){f();const i=setInterval(f,2e3);return()=>clearInterval(i)}},[g,t,f]);const c=s?d.filter(i=>i.type.toLowerCase().includes(s.toLowerCase())||i.status===s):d,h=i=>{switch(i){case"success":return"g7dt-status-success";case"error":return"g7dt-status-error";case"started":return"g7dt-status-started";default:return"g7dt-status-default"}},y=i=>{switch(i){case"success":return"g7dt-badge-success";case"error":return"g7dt-badge-error";default:return"g7dt-badge-warning"}},n=v&&o?o.executions.find(i=>i.id===v):null;return e.jsxs("div",{className:"g7dt-space-y-4",children:[t&&e.jsx("div",{className:"g7dt-card",children:e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsxs("button",{className:`g7dt-tab-button ${g==="actions"?"g7dt-tab-active":""}`,onClick:()=>r("actions"),children:["📋 액션 (",d.length,")"]}),e.jsxs("button",{className:`g7dt-tab-button ${g==="sequences"?"g7dt-tab-active":""}`,onClick:()=>r("sequences"),children:["🔗 Sequence (",o?.executions.length||0,")"]})]})}),g==="actions"&&e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-flex-shrink-0",children:[e.jsx("input",{type:"text",placeholder:"액션 타입 또는 상태로 필터...",value:s,onChange:i=>a(i.target.value),className:"g7dt-input g7dt-flex-1"}),e.jsx("button",{onClick:()=>a(""),className:"g7dt-btn-text",children:"초기화"})]}),g==="sequences"&&o&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"Sequence 통계"}),e.jsxs("div",{className:"g7dt-stats-grid-3",children:[e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-blue",children:o.stats.totalSequences}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"총 실행"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-green",children:o.stats.successCount}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"성공"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-red",children:o.stats.errorCount}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"실패"})]})]})]}),e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"Sequence 실행 목록"}),o.executions.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"실행된 Sequence가 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-40 g7dt-overflow-y-auto",children:o.executions.slice().reverse().map(i=>e.jsx("div",{className:`g7dt-list-item g7dt-cursor-pointer ${v===i.id?"g7dt-selected":""} ${i.status==="error"?"g7dt-border-red":""}`,onClick:()=>l(v===i.id?null:i.id),children:e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:i.status==="completed"?"✅":i.status==="error"?"❌":"⏳"}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-white",children:[i.actions.length,"개 액션"]}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:[i.totalDuration.toFixed(0),"ms"]})]})},i.id))})]}),n&&e.jsxs("div",{className:"g7dt-card g7dt-border-blue",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:["🔗 Sequence 상세 (",n.actions.length,"개 액션)"]}),e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:n.actions.map((i,u)=>e.jsxs("div",{className:`g7dt-list-item ${i.status==="error"?"g7dt-border-red":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted",children:["#",i.index+1]}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-white g7dt-font-mono",children:i.handler}),e.jsx("span",{className:`g7dt-text-xs ${i.status==="success"?"g7dt-text-green":"g7dt-text-red"}`,children:i.status==="success"?"✓":"✕"}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:[i.duration.toFixed(0),"ms"]})]}),i.stateChanges&&i.stateChanges.length>0&&e.jsxs("div",{className:"g7dt-mt-1",children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"상태 변경:"}),i.stateChanges.slice(0,3).map((m,k)=>e.jsx("div",{className:"g7dt-text-xs g7dt-text-yellow g7dt-ml-2",children:m.path},k)),i.stateChanges.length>3&&e.jsxs("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-2",children:["...외 ",i.stateChanges.length-3,"개"]})]})]},u))})]})]}),g==="actions"&&e.jsx("div",{className:"g7dt-section",children:e.jsx("div",{className:"g7dt-scroll-list g7dt-space-y-2-flat g7dt-action-list",children:c.length===0?e.jsx("div",{className:"g7dt-empty-message",children:"액션 이력이 없습니다"}):c.slice(-30).reverse().map((i,u)=>e.jsxs("div",{className:`g7dt-action-item ${h(i.status)}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-start",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-font-mono g7dt-font-bold",children:i.type}),e.jsx("span",{className:`g7dt-status-badge ${y(i.status)}`,children:i.status})]}),e.jsx("span",{className:"g7dt-text-gray",children:i.duration?`${i.duration.toFixed(2)}ms`:"-"})]}),i.error&&e.jsx("div",{className:"g7dt-error-box",children:i.error.message}),i.params&&Object.keys(i.params).length>0&&e.jsxs("details",{className:"g7dt-details",children:[e.jsx("summary",{className:"g7dt-summary",children:"파라미터"}),e.jsx("pre",{className:"g7dt-pre",children:JSON.stringify(i.params,null,2)})]})]},`${i.id}-${u}`))})})]})},Se=({stats:d,devTools:t})=>{const[s,a]=x.useState(null),[g,r]=x.useState(!1),o=x.useCallback(()=>{a(t.getCacheDecisionTrackingInfo())},[t]);x.useEffect(()=>{if(g){o();const l=setInterval(o,2e3);return()=>clearInterval(l)}},[g,o]);const p=()=>{t.resetCacheStats(),console.log("[G7DevTools] 캐시 통계 초기화")},v=l=>{switch(l){case"use_cache":return"✅";case"skip_cache":return"⏭️";case"invalidate":return"🗑️";default:return"❓"}};return e.jsxs("div",{className:"g7dt-space-y-6",children:[e.jsxs("div",{className:"g7dt-stats-grid",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-green",children:d.hits}),e.jsx("div",{className:"g7dt-stat-label",children:"Cache Hits"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-red",children:d.misses}),e.jsx("div",{className:"g7dt-stat-label",children:"Cache Misses"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-blue",children:d.entries}),e.jsx("div",{className:"g7dt-stat-label",children:"Entries"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsxs("div",{className:"g7dt-stat-value g7dt-text-purple",children:[(d.hitRate*100).toFixed(1),"%"]}),e.jsx("div",{className:"g7dt-stat-label",children:"Hit Rate"})]})]}),e.jsxs("div",{className:"g7dt-space-y-2",children:[e.jsx("div",{className:"g7dt-text-sm g7dt-text-gray",children:"캐시 히트율"}),e.jsx("div",{className:"g7dt-progress-bar",children:e.jsx("div",{className:"g7dt-progress-fill",style:{width:`${d.hitRate*100}%`}})})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsx("button",{onClick:p,className:"g7dt-btn-danger",children:"캐시 통계 초기화"}),e.jsx("button",{onClick:()=>r(!g),className:`g7dt-tab-button ${g?"g7dt-tab-active":""}`,children:"📋 Decision Log"})]}),g&&s&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:["캐시 결정 로그 (",s.decisions.length,"개)"]}),s.decisions.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"캐시 결정 기록이 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:s.decisions.slice().reverse().slice(0,50).map(l=>e.jsxs("div",{className:`g7dt-list-item ${l.decision==="skip_cache"?"g7dt-border-yellow":l.decision==="invalidate"?"g7dt-border-red":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:v(l.decision)}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-white g7dt-font-mono g7dt-truncate",style:{maxWidth:"200px"},children:l.expression}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:l.decision})]}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mt-1",children:l.reason}),l.context&&e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-mt-1",children:[l.context.isInIteration&&e.jsx("span",{className:"g7dt-badge g7dt-text-xs",children:"🔄 iteration"}),l.context.isInAction&&e.jsx("span",{className:"g7dt-badge g7dt-text-xs",children:"⚡ action"})]})]},l.id))})]})]})},Ie=()=>{const[d,t]=x.useState([]),[s,a]=x.useState([]),[g,r]=x.useState(""),o=["이전 값이 전송됨","모든 행이 같은 값","상태가 업데이트 안됨","API 호출이 안됨","초기값이 없음","무한 로딩","Form 값이 저장 안됨","iteration 데이터 중복"],p=f=>{t(c=>c.includes(f)?c.filter(h=>h!==f):[...c,f])},v=()=>{g&&!d.includes(g)&&(t(f=>[...f,g]),r(""))},l=async()=>{const{DiagnosticEngine:f}=await Promise.resolve().then(()=>pe),h=new f().analyze(d);a(h)};return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"증상 선택"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-2",children:o.map(f=>e.jsx("button",{onClick:()=>p(f),className:d.includes(f)?"g7dt-symptom-btn g7dt-symptom-active":"g7dt-symptom-btn",children:f},f))})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsx("input",{type:"text",placeholder:"직접 증상 입력...",value:g,onChange:f=>r(f.target.value),onKeyDown:f=>f.key==="Enter"&&v(),className:"g7dt-input g7dt-flex-1"}),e.jsx("button",{onClick:v,className:"g7dt-btn-secondary",children:"추가"})]}),e.jsxs("button",{onClick:l,disabled:d.length===0,className:d.length===0?"g7dt-btn-primary g7dt-btn-disabled g7dt-w-full":"g7dt-btn-primary g7dt-w-full",children:["진단 실행 (",d.length,"개 증상)"]}),s.length>0&&e.jsxs("div",{className:"g7dt-space-y-3",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:"진단 결과"}),s.slice(0,5).map((f,c)=>e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("span",{className:"g7dt-font-bold g7dt-text-yellow",children:f.rule.name}),e.jsxs("span",{className:"g7dt-confidence-badge",children:[(f.confidence*100).toFixed(0),"%"]})]}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-lightgray",children:f.rule.solution}),f.rule.codeExample&&e.jsx("pre",{className:"g7dt-pre g7dt-mt-2",children:f.rule.codeExample})]},c))]})]})},Te=({devTools:d})=>{const t=d.getPerformanceInfo();return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-stats-grid-2",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-blue",children:t.bindingEvalCount}),e.jsx("div",{className:"g7dt-stat-label",children:"바인딩 평가 횟수"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-purple",children:t.renderCounts.size}),e.jsx("div",{className:"g7dt-stat-label",children:"렌더링된 컴포넌트"})]})]}),t.memoryWarnings.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-red g7dt-mb-2",children:"메모리 경고"}),e.jsx("div",{className:"g7dt-space-y-2",children:t.memoryWarnings.map((s,a)=>e.jsxs("div",{className:"g7dt-warning-card",children:[e.jsx("div",{className:"g7dt-font-bold",children:s.type}),e.jsx("div",{className:"g7dt-text-lightgray",children:s.message}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-gray g7dt-mt-1",children:s.suggestion})]},a))})]}),t.renderCounts.size>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"컴포넌트별 렌더링"}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-scroll-list",children:Array.from(t.renderCounts.entries()).sort((s,a)=>a[1]-s[1]).slice(0,10).map(([s,a])=>e.jsxs("div",{className:"g7dt-list-item",children:[e.jsx("span",{className:"g7dt-text-lightgray g7dt-truncate",children:s}),e.jsxs("span",{className:a>50?"g7dt-text-red":"g7dt-text-gray",children:[a,"회"]})]},s))})]})]})},De=({devTools:d})=>{const t=d.getLifecycleInfo();return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-section",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-green g7dt-mb-2 g7dt-flex-shrink-0",children:["마운트된 컴포넌트 (",t.mountedComponents.length,")"]}),e.jsx("div",{className:"g7dt-scroll-list",children:t.mountedComponents.length===0?e.jsx("div",{className:"g7dt-empty-message",children:"추적된 컴포넌트 없음"}):t.mountedComponents.map(s=>e.jsxs("div",{className:"g7dt-list-item g7dt-text-xs",children:[e.jsx("span",{className:"g7dt-text-lightgray",children:s.name}),e.jsx("span",{className:"g7dt-text-gray",children:s.id})]},s.id))})]}),t.orphanedListeners.length>0&&e.jsxs("div",{className:"g7dt-section",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-red g7dt-mb-2 g7dt-flex-shrink-0",children:["정리되지 않은 리스너 (",t.orphanedListeners.length,")"]}),e.jsx("div",{className:"g7dt-scroll-list",children:t.orphanedListeners.map((s,a)=>e.jsxs("div",{className:"g7dt-warning-card g7dt-text-xs",children:[e.jsx("span",{className:"g7dt-text-lightgray",children:s.type}),e.jsxs("span",{className:"g7dt-text-gray g7dt-ml-2",children:["on ",s.target]})]},a))})]})]})},Le=({devTools:d})=>{const t=d.getNetworkInfo(),s=o=>{switch(o){case"success":return"g7dt-text-green";case"error":return"g7dt-text-red";case"pending":return"g7dt-text-yellow";default:return"g7dt-text-gray"}},a=o=>o.queryParams&&Object.keys(o.queryParams).length>0,g=o=>Object.entries(o).map(([p,v])=>e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-text-xs",children:[e.jsxs("span",{className:"g7dt-text-purple",children:[p,":"]}),e.jsx("span",{className:"g7dt-text-lightgray",children:Array.isArray(v)?JSON.stringify(v):v})]},p)),r=(o,p=5e3)=>{try{const v=JSON.stringify(o,null,2);return v.length>p?v.substring(0,p)+`
|
|
... (truncated)`:v}catch{return"(직렬화 불가)"}};return e.jsxs("div",{className:"g7dt-space-y-4",children:[t.activeRequests.length>0&&e.jsxs("div",{children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-yellow g7dt-mb-2",children:["진행 중 (",t.activeRequests.length,")"]}),e.jsx("div",{className:"g7dt-space-y-1",children:t.activeRequests.map(o=>e.jsxs("details",{className:"g7dt-details",children:[e.jsxs("summary",{className:"g7dt-summary g7dt-pending-request",children:[e.jsx("span",{className:"g7dt-font-bold",children:o.method}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-lightgray g7dt-truncate",children:o.fullUrl||o.url})]}),e.jsxs("div",{className:"g7dt-card g7dt-mt-1 g7dt-text-xs",children:[a(o)&&e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsx("div",{className:"g7dt-text-blue g7dt-font-bold g7dt-mb-1",children:"쿼리 파라미터"}),e.jsx("div",{className:"g7dt-pl-2 g7dt-border-l-2 g7dt-border-blue",children:g(o.queryParams)})]}),o.requestBody&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-orange g7dt-font-bold g7dt-mb-1",children:"요청 본문"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-xs",children:r(o.requestBody,2e3)})]})]})]},o.id))})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"요청 이력"}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-scroll-list-lg",children:t.requestHistory.length===0?e.jsx("div",{className:"g7dt-empty-message",children:"요청 이력 없음"}):t.requestHistory.slice(-20).reverse().map(o=>e.jsxs("details",{className:"g7dt-details",children:[e.jsxs("summary",{className:"g7dt-summary g7dt-card g7dt-text-xs",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-w-full",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-font-bold",children:o.method}),e.jsx("span",{className:`g7dt-ml-2 ${s(o.status)}`,children:o.statusCode||o.status})]}),e.jsxs("span",{className:"g7dt-text-gray",children:[o.duration,"ms"]})]}),e.jsx("div",{className:"g7dt-text-gray g7dt-truncate g7dt-mt-1",children:o.fullUrl||o.url})]}),e.jsxs("div",{className:"g7dt-card g7dt-mt-1 g7dt-text-xs g7dt-ml-2 g7dt-border-l-2 g7dt-border-gray",children:[e.jsx("div",{className:"g7dt-mb-2",children:e.jsxs("div",{className:"g7dt-text-xs g7dt-space-y-1",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"URL:"})," ",e.jsx("span",{className:"g7dt-text-lightgray",children:o.fullUrl||o.url})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"상태:"})," ",e.jsx("span",{className:s(o.status),children:o.statusCode||o.status})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"소요시간:"})," ",e.jsxs("span",{className:"g7dt-text-lightgray",children:[o.duration,"ms"]})]}),o.dataSourceId&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"데이터소스:"})," ",e.jsx("span",{className:"g7dt-text-blue",children:o.dataSourceId})]}),o.error&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"에러:"})," ",e.jsx("span",{className:"g7dt-text-red",children:o.error})]})]})}),a(o)&&e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsx("div",{className:"g7dt-text-blue g7dt-font-bold g7dt-mb-1",children:"쿼리 파라미터"}),e.jsx("div",{className:"g7dt-pl-2 g7dt-border-l-2 g7dt-border-blue",children:g(o.queryParams)})]}),o.requestBody&&e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsx("div",{className:"g7dt-text-orange g7dt-font-bold g7dt-mb-1",children:"요청 본문"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-xs g7dt-max-h-40 g7dt-overflow-auto",children:r(o.requestBody,2e3)})]}),o.response!==void 0&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-green g7dt-font-bold g7dt-mb-1",children:"응답 내용"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-xs g7dt-max-h-60 g7dt-overflow-auto",children:r(o.response,5e3)})]})]})]},o.id))})]}),t.pendingDataSources.length>0&&e.jsxs("div",{children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-blue g7dt-mb-2",children:["대기 중인 데이터소스 (",t.pendingDataSources.length,")"]}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-2",children:t.pendingDataSources.map(o=>e.jsx("span",{className:"g7dt-tag-blue",children:o},o))})]})]})},Ee=({devTools:d})=>{const t=d.getFormInfo(),[s,a]=x.useState(!1),[g,r]=x.useState(null),o=x.useCallback(()=>{r(d.getFormBindingValidationTrackingInfo())},[d]);x.useEffect(()=>{if(s){o();const l=setInterval(o,2e3);return()=>clearInterval(l)}},[s,o]);const p=l=>{switch(l){case"missing-datakey":return"🔑";case"missing-input-name":return"📝";case"context-not-propagated":return"🔗";case"sortable-context-break":return"📊";case"modal-context-isolation":return"🪟";case"duplicate-input-name":return"👯";case"value-type-mismatch":return"⚠️";case"binding-path-invalid":return"❌";default:return"❓"}},v=l=>{switch(l){case"error":return"g7dt-text-red";case"warning":return"g7dt-text-yellow";case"info":return"g7dt-text-blue";default:return"g7dt-text-gray"}};return e.jsxs("div",{className:"g7dt-space-y-4",children:[t.length===0?e.jsx("div",{className:"g7dt-empty-message g7dt-py-8",children:"추적된 Form이 없습니다"}):t.map(l=>e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("span",{className:"g7dt-font-bold g7dt-text-blue",children:l.dataKey||"(no dataKey)"}),!l.dataKey&&e.jsx("span",{className:"g7dt-text-red g7dt-text-xs",children:"dataKey 필요"})]}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-mb-2",children:l.inputs.map((f,c)=>e.jsxs("div",{className:"g7dt-text-xs g7dt-flex g7dt-justify-between",children:[e.jsx("span",{children:f.name||e.jsx("span",{className:"g7dt-text-red",children:"name 없음"})}),e.jsx("span",{className:"g7dt-text-gray",children:f.type})]},c))}),e.jsxs("details",{className:"g7dt-details",children:[e.jsx("summary",{className:"g7dt-summary",children:"현재 값 보기"}),e.jsx("pre",{className:"g7dt-pre",children:JSON.stringify(l,null,2)})]})]},l.id)),e.jsx("div",{className:"g7dt-flex g7dt-justify-end",children:e.jsx("button",{onClick:()=>a(!s),className:`g7dt-tab-button ${s?"g7dt-tab-active":""}`,children:"🔍 Auto-Binding Check"})}),s&&g&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"Form 바인딩 검증 결과"}),e.jsxs("div",{className:"g7dt-stats-grid g7dt-mb-3",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-blue",children:g.stats.totalFormsValidated}),e.jsx("div",{className:"g7dt-stat-label",children:"검증된 Form"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-green",children:g.stats.validForms}),e.jsx("div",{className:"g7dt-stat-label",children:"유효"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-red",children:g.stats.formsWithIssues}),e.jsx("div",{className:"g7dt-stat-label",children:"문제 있음"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-yellow",children:g.stats.totalIssues}),e.jsx("div",{className:"g7dt-stat-label",children:"총 이슈"})]})]}),g.stats.topIssues.length>0&&e.jsxs("div",{className:"g7dt-mb-3",children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-2",children:"자주 발생하는 이슈"}),e.jsx("div",{className:"g7dt-space-y-1",children:g.stats.topIssues.slice(0,3).map((l,f)=>e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-xs",children:[e.jsx("span",{children:p(l.type)}),e.jsx("span",{className:"g7dt-text-white",children:l.description}),e.jsxs("span",{className:"g7dt-text-muted",children:["(",l.count,")"]})]},f))})]}),g.issues.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"바인딩 이슈가 없습니다 ✅"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:g.issues.slice().reverse().slice(0,30).map(l=>e.jsxs("div",{className:`g7dt-list-item ${l.severity==="error"?"g7dt-border-red":l.severity==="warning"?"g7dt-border-yellow":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:p(l.type)}),e.jsx("span",{className:`g7dt-text-xs g7dt-font-bold ${v(l.severity)}`,children:l.type}),l.formDataKey&&e.jsx("span",{className:"g7dt-text-xs g7dt-text-blue g7dt-font-mono",children:l.formDataKey})]}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-white g7dt-mt-1",children:l.description}),e.jsxs("div",{className:"g7dt-text-xs g7dt-text-green g7dt-mt-1",children:["💡 ",l.suggestion]}),l.contextInfo&&e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-mt-1",children:[l.contextInfo.isInsideModal&&e.jsx("span",{className:"g7dt-badge g7dt-text-xs",children:"🪟 modal"}),l.contextInfo.isInsideSortable&&e.jsx("span",{className:"g7dt-badge g7dt-text-xs",children:"📊 sortable"}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted",children:["depth: ",l.contextInfo.depth]})]})]},l.id))})]})]})},$e=({devTools:d})=>{const t=d.getConditionalInfo();return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-purple g7dt-mb-2",children:["if 조건 (",t.ifConditions.length,")"]}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-scroll-list",children:t.ifConditions.length===0?e.jsx("div",{className:"g7dt-empty-message",children:"추적된 if 조건 없음"}):t.ifConditions.map(s=>e.jsx("div",{className:`g7dt-condition-item ${s.evaluatedValue?"g7dt-condition-true":"g7dt-condition-false"}`,children:e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsx("span",{className:"g7dt-font-mono g7dt-text-lightgray g7dt-truncate-60",children:s.expression}),e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{className:s.evaluatedValue?"g7dt-badge-success":"g7dt-badge-error",children:s.evaluatedValue?"true":"false"}),e.jsxs("span",{className:"g7dt-text-gray",children:[s.evaluationCount,"회"]})]})]})},s.id))})]}),e.jsxs("div",{children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-cyan g7dt-mb-2",children:["iteration (",t.iterations.length,")"]}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-scroll-list",children:t.iterations.length===0?e.jsx("div",{className:"g7dt-empty-message",children:"추적된 iteration 없음"}):t.iterations.map(s=>e.jsxs("div",{className:"g7dt-card g7dt-text-xs",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-1",children:[e.jsx("span",{className:"g7dt-font-mono g7dt-text-lightgray g7dt-truncate-60",children:s.source}),e.jsxs("span",{className:s.sourceLength>0?"g7dt-badge-blue":"g7dt-badge-warning",children:[s.sourceLength,"개 항목"]})]}),e.jsxs("div",{className:"g7dt-text-gray",children:[e.jsxs("span",{className:"g7dt-mr-2",children:["item_var: ",s.itemVar]}),s.indexVar&&e.jsxs("span",{children:["index_var: ",s.indexVar]})]})]},s.id))})]}),(t.ifConditions.some(s=>s.evaluatedValue===!1&&s.evaluationCount>5)||t.iterations.some(s=>s.sourceLength===0))&&e.jsxs("div",{className:"g7dt-warning-box",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-yellow g7dt-mb-2",children:"잠재적 문제"}),e.jsxs("div",{className:"g7dt-space-y-1 g7dt-text-xs",children:[t.ifConditions.filter(s=>s.evaluatedValue===!1&&s.evaluationCount>5).map(s=>e.jsxs("div",{className:"g7dt-text-lightgray",children:["⚠️ if 조건 항상 false: ",s.expression]},s.id)),t.iterations.filter(s=>s.sourceLength===0).map(s=>e.jsxs("div",{className:"g7dt-text-lightgray",children:["⚠️ iteration 소스 비어있음: ",s.source]},s.id))]})]})]})},ze=({devTools:d})=>{const[t,s]=x.useState([]),[a,g]=x.useState({totalEvaluations:0,uniqueExpressions:0,warningCount:0,cacheHitRate:0,averageDuration:0,byType:{},byWarning:{}}),[r,o]=x.useState(""),[p,v]=x.useState(!1),[l,f]=x.useState(null),c=x.useCallback(()=>{const m=d.getExpressionInfo();s(m.expressions),g(m.stats)},[d]);x.useEffect(()=>{c();const m=d.watchExpressions(()=>{c()}),k=setInterval(c,2e3);return()=>{m(),clearInterval(k)}},[d,c]);const h=t.filter(m=>{if(p&&!m.warning)return!1;if(r){const k=r.toLowerCase();return m.expression.toLowerCase().includes(k)||m.componentName?.toLowerCase().includes(k)||m.propName?.toLowerCase().includes(k)||m.resultType.toLowerCase().includes(k)}return!0}),y=m=>{switch(m){case"string":return"g7dt-text-green";case"number":return"g7dt-text-blue";case"boolean":return"g7dt-text-purple";case"array":return"g7dt-text-cyan";case"object":return"g7dt-text-yellow";case"undefined":case"null":return"g7dt-text-red";default:return"g7dt-text-gray"}},n=m=>{switch(m){case"undefined-result":return"undefined 결과";case"null-result":return"null 결과";case"array-to-string":return"배열→문자열";case"object-to-string":return"객체→문자열";case"missing-optional-chain":return"?. 누락 의심";case"wrong-iteration-var":return"잘못된 반복 변수";case"type-mismatch":return"타입 불일치";case"cache-stale":return"캐시 오래됨";case"slow-evaluation":return"느린 평가";default:return m}},i=(m,k)=>k==="undefined"?"undefined":k==="null"?"null":k==="string"?`"${String(m).substring(0,50)}${String(m).length>50?"...":""}"`:k==="array"?`Array(${Array.isArray(m)?m.length:"?"})`:k==="object"?"Object{...}":String(m),u=()=>{d.clearExpressions(),s([]),f(null)};return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-stats-grid-5",children:[e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-lg g7dt-text-blue",children:a.totalEvaluations}),e.jsx("div",{className:"g7dt-stat-label-xs",children:"총 평가"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-lg g7dt-text-green",children:a.uniqueExpressions}),e.jsx("div",{className:"g7dt-stat-label-xs",children:"고유 표현식"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-lg g7dt-text-yellow",children:a.warningCount}),e.jsx("div",{className:"g7dt-stat-label-xs",children:"경고"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsxs("div",{className:"g7dt-stat-value-lg g7dt-text-purple",children:[(a.cacheHitRate*100).toFixed(0),"%"]}),e.jsx("div",{className:"g7dt-stat-label-xs",children:"캐시 히트"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsxs("div",{className:"g7dt-stat-value-lg g7dt-text-cyan",children:[a.averageDuration.toFixed(1),"ms"]}),e.jsx("div",{className:"g7dt-stat-label-xs",children:"평균 시간"})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-items-center",children:[e.jsx("input",{type:"text",placeholder:"표현식, 컴포넌트, prop 검색...",value:r,onChange:m=>o(m.target.value),className:"g7dt-input g7dt-flex-1"}),e.jsxs("label",{className:"g7dt-checkbox-label",children:[e.jsx("input",{type:"checkbox",checked:p,onChange:m=>v(m.target.checked),className:"g7dt-checkbox"}),"경고만"]}),e.jsx("button",{onClick:u,className:"g7dt-btn-danger-sm",children:"초기화"})]}),Object.keys(a.byType).length>0&&e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1",children:Object.entries(a.byType).map(([m,k])=>e.jsxs("span",{className:`g7dt-type-tag ${y(m)}`,children:[m,": ",k]},m))}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-expr-list",children:h.length===0?e.jsx("div",{className:"g7dt-empty-message g7dt-py-4",children:r||p?"조건에 맞는 표현식이 없습니다":"추적된 표현식이 없습니다"}):h.slice(-50).reverse().map(m=>e.jsx("div",{onClick:()=>f(m),className:`g7dt-expr-item ${l?.id===m.id?"g7dt-expr-selected":m.warning?"g7dt-expr-warning":""}`,children:e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-start g7dt-gap-2",children:[e.jsxs("div",{className:"g7dt-flex-1 g7dt-min-w-0",children:[e.jsx("div",{className:"g7dt-font-mono g7dt-text-white g7dt-truncate",title:m.expression,children:m.expression}),e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-mt-1 g7dt-text-xxs",children:[m.componentName&&e.jsxs("span",{className:"g7dt-text-gray",children:[m.componentName,m.propName&&`.${m.propName}`]}),e.jsx("span",{className:y(m.resultType),children:i(m.result,m.resultType)})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-flex-col g7dt-items-end g7dt-gap-1",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-1",children:[m.fromCache&&e.jsx("span",{className:"g7dt-mini-badge g7dt-badge-success",children:"캐시"}),m.warning&&e.jsx("span",{className:"g7dt-mini-badge g7dt-badge-warning",children:n(m.warning.type)})]}),m.duration!==void 0&&e.jsxs("span",{className:"g7dt-text-xxs g7dt-text-gray",children:[m.duration.toFixed(2),"ms"]})]})]})},m.id))}),l&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:"표현식 상세"}),e.jsx("button",{onClick:()=>f(null),className:"g7dt-btn-close",children:"✕"})]}),e.jsxs("div",{className:"g7dt-space-y-2 g7dt-text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"표현식:"}),e.jsx("code",{className:"g7dt-code g7dt-text-green",children:l.expression})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"결과:"}),e.jsx("span",{className:`g7dt-ml-2 ${y(l.resultType)}`,children:JSON.stringify(l.result,null,2)?.substring(0,200)}),e.jsxs("span",{className:"g7dt-ml-2 g7dt-text-darkgray",children:["(",l.resultType,")"]})]}),l.componentName&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"컴포넌트:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-blue",children:l.componentName}),l.propName&&e.jsxs("span",{className:"g7dt-text-gray",children:[".",l.propName]})]}),l.method&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"메서드:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-purple",children:l.method})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"캐시:"}),e.jsxs("span",{className:`g7dt-ml-2 ${l.fromCache?"g7dt-text-green":"g7dt-text-gray"}`,children:[l.fromCache?"캐시에서 로드":"새로 평가",l.skipCache&&" (skipCache)"]})]}),l.duration!==void 0&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"소요 시간:"}),e.jsxs("span",{className:`g7dt-ml-2 ${l.duration>10?"g7dt-text-red":"g7dt-text-lightgray"}`,children:[l.duration.toFixed(3),"ms"]})]}),l.warning&&e.jsxs("div",{className:"g7dt-warning-box-light",children:[e.jsxs("div",{className:"g7dt-text-yellow g7dt-font-bold",children:["⚠️ ",n(l.warning.type)]}),e.jsx("div",{className:"g7dt-text-lightgray g7dt-mt-1",children:l.warning.message}),l.warning.suggestion&&e.jsxs("div",{className:"g7dt-text-gray g7dt-mt-1 g7dt-text-xxs",children:["💡 ",l.warning.suggestion]})]}),l.steps&&l.steps.length>0&&e.jsxs("details",{className:"g7dt-details",children:[e.jsxs("summary",{className:"g7dt-summary",children:["평가 단계 (",l.steps.length,")"]}),e.jsx("div",{className:"g7dt-mt-1 g7dt-space-y-1 g7dt-pl-2 g7dt-border-l",children:l.steps.map((m,k)=>e.jsxs("div",{className:"g7dt-text-xxs",children:[e.jsx("span",{className:"g7dt-text-purple",children:m.step}),m.path&&e.jsx("span",{className:"g7dt-text-gray g7dt-ml-1",children:m.path}),m.fromCache&&e.jsx("span",{className:"g7dt-text-green g7dt-ml-1",children:"(cached)"}),m.error&&e.jsx("span",{className:"g7dt-text-red g7dt-ml-1",children:m.error})]},k))})]})]})]}),Object.keys(a.byWarning).length>0&&e.jsxs("div",{className:"g7dt-warning-box-light",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-text-yellow g7dt-mb-2",children:"경고 요약"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-2",children:Object.entries(a.byWarning).map(([m,k])=>e.jsxs("span",{className:"g7dt-warning-tag",children:[n(m),": ",k]},m))})]})]})},_e=({devTools:d})=>{const t=d.getHandlers(),[s,a]=x.useState(""),[g,r]=x.useState("all"),o={"built-in":t.filter(l=>l.category==="built-in"),custom:t.filter(l=>l.category==="custom"),module:t.filter(l=>l.category==="module"),plugin:t.filter(l=>l.category==="plugin")},p={all:t.length,"built-in":o["built-in"].length,custom:o.custom.length,module:o.module.length,plugin:o.plugin.length},v=t.filter(l=>g!=="all"&&l.category!==g?!1:s?l.name.toLowerCase().includes(s.toLowerCase())||l.description?.toLowerCase().includes(s.toLowerCase()):!0);return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsx("div",{className:"g7dt-flex g7dt-gap-2",children:["all","built-in","custom","module","plugin"].map(l=>e.jsxs("button",{onClick:()=>r(l),className:g===l?"g7dt-filter-btn g7dt-filter-active":"g7dt-filter-btn",children:[l==="all"?"전체":l," (",p[l],")"]},l))}),e.jsx("input",{type:"text",placeholder:"핸들러 이름 검색...",value:s,onChange:l=>a(l.target.value),className:"g7dt-input g7dt-w-full"}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-handler-list",children:v.length===0?e.jsx("div",{className:"g7dt-empty-message g7dt-py-4",children:"등록된 핸들러가 없습니다"}):v.map(l=>e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsx("span",{className:"g7dt-font-mono g7dt-text-blue",children:l.name}),e.jsx("span",{className:l.category==="built-in"?"g7dt-mini-badge g7dt-badge-success":l.category==="module"?"g7dt-mini-badge g7dt-badge-purple":l.category==="plugin"?"g7dt-mini-badge g7dt-badge-info":"g7dt-mini-badge g7dt-badge-warning",children:l.category})]}),l.description&&e.jsx("div",{className:"g7dt-text-xs g7dt-text-gray g7dt-mt-1",children:l.description})]},l.name))}),e.jsxs("div",{className:"g7dt-text-xs g7dt-text-gray",children:["총 ",t.length,"개 핸들러 | 빌트인 ",p["built-in"]," | 커스텀 ",p.custom," | 모듈 ",p.module," | 플러그인 ",p.plugin]})]})},je=({devTools:d})=>{const[t,s]=x.useState(d.getComponentEventInfo()),[a,g]=x.useState(null),r=x.useCallback(()=>{s(d.getComponentEventInfo())},[d]);x.useEffect(()=>{r();const p=setInterval(r,2e3);return()=>clearInterval(p)},[r]);const o=a?t.emitHistory.filter(p=>p.eventName===a):t.emitHistory;return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-stats-grid-3",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value-lg g7dt-text-blue",children:t.subscriptions.length}),e.jsx("div",{className:"g7dt-stat-label",children:"이벤트 타입"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value-lg g7dt-text-green",children:t.totalSubscribers}),e.jsx("div",{className:"g7dt-stat-label",children:"총 구독자"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value-lg g7dt-text-purple",children:t.totalEmits}),e.jsx("div",{className:"g7dt-stat-label",children:"총 발행"})]})]}),e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"구독된 이벤트"}),e.jsxs("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-2",children:[e.jsx("button",{onClick:()=>g(null),className:a===null?"g7dt-filter-btn g7dt-filter-active":"g7dt-filter-btn",children:"전체"}),t.subscriptions.map(p=>e.jsxs("button",{onClick:()=>g(p.eventName),className:a===p.eventName?"g7dt-filter-btn g7dt-filter-active":"g7dt-filter-btn",children:[p.eventName," (",p.subscriberCount,")"]},p.eventName))]})]}),e.jsxs("div",{children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:["발행 이력 ",a&&`(${a})`]}),e.jsx("div",{className:"g7dt-space-y-1 g7dt-event-list",children:o.length===0?e.jsx("div",{className:"g7dt-empty-message g7dt-py-4",children:"이벤트 발행 이력이 없습니다"}):o.slice(-30).reverse().map(p=>e.jsxs("div",{className:`g7dt-card g7dt-text-xs ${p.hasError?"g7dt-card-error":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsx("span",{className:"g7dt-font-mono g7dt-text-green",children:p.eventName}),e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsxs("span",{className:"g7dt-text-gray",children:[p.listenerCount," listeners"]}),p.hasError&&e.jsx("span",{className:"g7dt-text-red g7dt-text-xxs",children:"에러"})]})]}),p.data!==void 0&&e.jsxs("details",{className:"g7dt-details g7dt-mt-1",children:[e.jsx("summary",{className:"g7dt-summary",children:"데이터"}),e.jsx("pre",{className:"g7dt-pre",children:JSON.stringify(p.data,null,2)})]}),p.hasError&&p.errorMessage&&e.jsx("div",{className:"g7dt-error-inline",children:p.errorMessage})]},p.id))})]}),e.jsx("button",{onClick:r,className:"g7dt-btn-secondary",children:"새로고침"})]})},Ae=({devTools:d})=>{const t=d.getDataSources(),[s,a]=x.useState("all"),[g,r]=x.useState(null),[o,p]=x.useState(!1),[v,l]=x.useState(null),f=x.useCallback(()=>{l(d.getDataPathTransformTrackingInfo())},[d]);x.useEffect(()=>{if(o){f();const u=setInterval(f,2e3);return()=>clearInterval(u)}},[o,f]);const c=u=>{switch(u){case"api_response":return"📥";case"extract_data":return"📄";case"apply_path":return"🔗";case"init_global":return"🌐";case"init_local":return"📌";default:return"❓"}},h=t.filter(u=>s==="all"?!0:u.status===s),y={all:t.length,idle:t.filter(u=>u.status==="idle").length,loading:t.filter(u=>u.status==="loading").length,loaded:t.filter(u=>u.status==="loaded").length,error:t.filter(u=>u.status==="error").length},n=u=>{switch(u){case"loaded":return"g7dt-badge-success";case"loading":return"g7dt-badge-warning";case"error":return"g7dt-badge-error";default:return"g7dt-badge-gray"}},i=g?t.find(u=>u.id===g):null;return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsx("div",{className:"g7dt-flex g7dt-gap-2",children:["all","idle","loading","loaded","error"].map(u=>e.jsxs("button",{onClick:()=>a(u),className:s===u?"g7dt-filter-btn g7dt-filter-active":"g7dt-filter-btn",children:[u==="all"?"전체":u," (",y[u],")"]},u))}),e.jsx("div",{className:"g7dt-ds-grid",children:h.length===0?e.jsx("div",{className:"g7dt-empty-message g7dt-col-span-2 g7dt-py-4",children:"데이터소스가 없습니다"}):h.map(u=>e.jsxs("div",{onClick:()=>r(u.id),className:`g7dt-ds-item ${g===u.id?"g7dt-ds-selected":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsx("span",{className:"g7dt-font-mono g7dt-text-blue g7dt-truncate",children:u.id}),e.jsx("span",{className:`g7dt-mini-badge ${n(u.status)}`,children:u.status})]}),e.jsx("div",{className:"g7dt-text-gray g7dt-mt-1 g7dt-truncate",children:u.endpoint||"(endpoint 없음)"}),u.itemCount!==void 0&&e.jsxs("div",{className:"g7dt-text-lightgray g7dt-mt-1",children:[u.itemCount,"개 항목"]})]},u.id))}),i&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:i.id}),e.jsx("button",{onClick:()=>r(null),className:"g7dt-btn-close",children:"✕"})]}),e.jsxs("div",{className:"g7dt-space-y-2 g7dt-text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"엔드포인트:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-green",children:i.endpoint||"-"})]}),i.dataPath&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"데이터 경로:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-yellow",children:i.dataPath})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"상태:"}),e.jsx("span",{className:`g7dt-ml-2 g7dt-mini-badge ${n(i.status)}`,children:i.status})]}),i.itemCount!==void 0&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"항목 수:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-blue",children:i.itemCount})]}),i.keys&&i.keys.length>0&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"키:"}),e.jsxs("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1 g7dt-mt-1",children:[i.keys.slice(0,10).map(u=>e.jsx("span",{className:"g7dt-key-tag",children:u},u)),i.keys.length>10&&e.jsxs("span",{className:"g7dt-text-gray",children:["+",i.keys.length-10,"개"]})]})]}),i.dependencies&&i.dependencies.length>0&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-gray",children:"의존성:"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1 g7dt-mt-1",children:i.dependencies.map(u=>e.jsx("span",{className:"g7dt-dep-tag",children:u},u))})]})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("div",{className:"g7dt-text-xs g7dt-text-gray",children:["총 ",t.length,"개 데이터소스 | 로드됨 ",y.loaded," | 로딩중 ",y.loading," | 에러 ",y.error]}),e.jsx("button",{onClick:()=>p(!o),className:`g7dt-tab-button ${o?"g7dt-tab-active":""}`,children:"🔀 Path Transform"})]}),o&&v&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:["데이터 경로 변환 추적 (",v.transforms.length,"개)"]}),e.jsxs("div",{className:"g7dt-stats-grid-3 g7dt-mb-3",children:[e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-xl g7dt-font-bold g7dt-text-blue",children:v.stats.totalTransforms}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"총 변환"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-xl g7dt-font-bold g7dt-text-purple",children:Object.keys(v.stats.byDataSource).length}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"데이터소스"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-xl g7dt-font-bold g7dt-text-yellow",children:v.stats.warningsCount}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"경고"})]})]}),v.transforms.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"변환 기록이 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:v.transforms.slice().reverse().slice(0,20).map((u,m)=>e.jsxs("div",{className:`g7dt-list-item ${u.warnings.length>0?"g7dt-border-yellow":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{className:"g7dt-text-xs g7dt-text-blue g7dt-font-mono",children:u.dataSourceId}),u.warnings.length>0&&e.jsxs("span",{className:"g7dt-badge g7dt-text-xs g7dt-text-yellow",children:["⚠️ ",u.warnings.length]})]}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1 g7dt-mt-1",children:u.transformSteps.map((k,b)=>e.jsxs("span",{className:"g7dt-badge g7dt-text-xs",title:`${k.inputPath} → ${k.outputPath}`,children:[c(k.step)," ",k.step]},b))}),u.finalBinding&&e.jsxs("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mt-1",children:["최종: ",e.jsx("span",{className:"g7dt-text-green",children:u.finalBinding.expression}),"→ ",e.jsx("span",{className:"g7dt-text-blue",children:u.finalBinding.resolvedPath})]}),u.warnings.length>0&&e.jsx("div",{className:"g7dt-text-xs g7dt-text-yellow g7dt-mt-1",children:u.warnings[0]})]},`${u.dataSourceId}-${m}`))}),v.stats.commonWarnings.length>0&&e.jsxs("div",{className:"g7dt-mt-3",children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-1",children:"자주 발생하는 경고"}),e.jsx("div",{className:"g7dt-space-y-1",children:v.stats.commonWarnings.slice(0,5).map((u,m)=>e.jsxs("div",{className:"g7dt-text-xs g7dt-text-yellow",children:[u.warning," (",u.count,"회)"]},m))})]})]})]})},Oe=({devTools:d})=>{const[t,s]=x.useState(d.getStateRenderingInfo()),[a,g]=x.useState(null),[r,o]=x.useState(!1),[p,v]=x.useState(""),l=x.useCallback(()=>{s(d.getStateRenderingInfo())},[d]);x.useEffect(()=>{l();const n=setInterval(l,2e3);return()=>clearInterval(n)},[l]);const f=t.logs.filter(n=>!(r&&n.renderedComponents.length>0||p&&!n.statePath.toLowerCase().includes(p.toLowerCase()))),c=a?t.logs.find(n=>n.setStateId===a):null,h=t.stats,y=t.logs.filter(n=>n.renderedComponents.length===0).length;return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-stats-grid",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-blue",children:h.totalStateChanges}),e.jsx("div",{className:"g7dt-stat-label",children:"상태 변경"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-green",children:h.totalRenders}),e.jsx("div",{className:"g7dt-stat-label",children:"총 렌더링"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsxs("div",{className:"g7dt-stat-value g7dt-text-purple",children:[h.avgRenderDuration.toFixed(1),"ms"]}),e.jsx("div",{className:"g7dt-stat-label",children:"평균 렌더 시간"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:`g7dt-stat-value ${y>0?"g7dt-text-yellow":"g7dt-text-green"}`,children:y}),e.jsx("div",{className:"g7dt-stat-label",children:"렌더링 없음"})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsx("input",{type:"text",placeholder:"상태 경로 필터 (예: _global.user)",value:p,onChange:n=>v(n.target.value),className:"g7dt-input g7dt-flex-1"}),e.jsx("button",{onClick:()=>o(!r),className:r?"g7dt-filter-btn-active-yellow":"g7dt-filter-btn",children:"렌더링 없음만"})]}),e.jsx("div",{className:"g7dt-scroll-list",children:f.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"상태-렌더링 로그가 없습니다"}):f.slice(-30).reverse().map(n=>{const i=n.renderedComponents.length>0,u=i?"✅":"⚠️",m=new Date(n.timestamp).toLocaleTimeString();return e.jsxs("div",{onClick:()=>g(n.setStateId),className:`g7dt-render-log-item ${a===n.setStateId?"g7dt-selected":i?"":"g7dt-warning"}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("span",{className:"g7dt-mono g7dt-text-blue",children:[u," ",n.statePath]}),e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[i?e.jsxs("span",{className:"g7dt-text-green",children:[n.renderedComponents.length,"개 렌더"]}):e.jsx("span",{className:"g7dt-text-yellow",children:"렌더링 없음"}),e.jsx("span",{className:"g7dt-text-muted",children:m})]})]}),n.triggeredBy?.handlerType&&e.jsxs("div",{className:"g7dt-text-muted g7dt-mt-1",children:["트리거: ",n.triggeredBy.handlerType]})]},n.setStateId)})}),c&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:c.statePath}),e.jsx("button",{onClick:()=>g(null),className:"g7dt-close-btn",children:"✕"})]}),e.jsxs("div",{className:"g7dt-space-y-2 g7dt-text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"setStateId:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-purple g7dt-mono",children:c.setStateId})]}),c.triggeredBy&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"트리거:"}),e.jsxs("span",{className:"g7dt-ml-2 g7dt-text-yellow",children:[c.triggeredBy.handlerType,c.triggeredBy.actionId&&` (${c.triggeredBy.actionId})`]})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"이전 값:"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-red",children:JSON.stringify(c.oldValue,null,2)?.slice(0,200)})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"새 값:"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-green",children:JSON.stringify(c.newValue,null,2)?.slice(0,200)})]}),c.renderedComponents.length>0?e.jsxs("div",{children:[e.jsxs("span",{className:"g7dt-text-muted",children:["렌더링된 컴포넌트 (",c.renderedComponents.length,"개):"]}),e.jsxs("div",{className:"g7dt-mt-1 g7dt-space-y-1",children:[c.renderedComponents.slice(0,10).map((n,i)=>e.jsxs("div",{className:"g7dt-render-comp-item",children:[e.jsx("span",{className:"g7dt-text-blue",children:n.componentName}),e.jsxs("span",{className:"g7dt-text-muted",children:[n.renderDuration.toFixed(2),"ms"]})]},i)),c.renderedComponents.length>10&&e.jsxs("div",{className:"g7dt-text-muted g7dt-text-center",children:["... 외 ",c.renderedComponents.length-10,"개"]})]}),e.jsxs("div",{className:"g7dt-mt-2 g7dt-text-muted",children:["총 렌더 시간: ",c.totalRenderDuration.toFixed(2),"ms"]})]}):e.jsxs("div",{className:"g7dt-warning-box",children:[e.jsx("span",{className:"g7dt-text-yellow",children:"⚠️ 렌더링이 발생하지 않았습니다"}),e.jsxs("div",{className:"g7dt-text-muted g7dt-mt-1 g7dt-text-xxs",children:["가능한 원인:",e.jsxs("ul",{className:"g7dt-list g7dt-mt-1",children:[e.jsx("li",{children:"해당 상태를 바인딩하는 컴포넌트가 없음"}),e.jsx("li",{children:"컴포넌트가 마운트되지 않은 상태"}),e.jsx("li",{children:"동일한 값으로 상태 설정"})]})]})]})]})]}),h.topRenderedComponents.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"가장 많이 렌더링된 컴포넌트"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-2",children:h.topRenderedComponents.slice(0,5).map((n,i)=>e.jsxs("span",{className:"g7dt-tag",children:[n.name,": ",e.jsx("span",{className:"g7dt-text-blue",children:n.count})]},i))})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsx("button",{onClick:l,className:"g7dt-btn-secondary",children:"새로고침"}),e.jsx("button",{onClick:()=>{d.clearStateRenderingLogs(),l()},className:"g7dt-btn-danger",children:"로그 초기화"})]})]})},Me=({devTools:d})=>{const[t,s]=x.useState(null),[a,g]=x.useState(null),[r,o]=x.useState("all"),p=x.useCallback(()=>{s(d.getStyleValidationInfo())},[d]);if(x.useEffect(()=>{p();const c=setInterval(p,2e3);return()=>clearInterval(c)},[p]),!t)return e.jsx("div",{className:"g7dt-empty-state",children:"로딩 중..."});const v=t.issues.filter(c=>r==="all"?!0:c.type===r),l=a?t.issues.find(c=>c.componentId===a):null,f=t.stats;return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-stats-grid",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value g7dt-text-blue",children:f.totalComponents}),e.jsx("div",{className:"g7dt-stat-label",children:"총 컴포넌트"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:`g7dt-stat-value ${f.invisibleCount>0?"g7dt-text-red":"g7dt-text-green"}`,children:f.invisibleCount}),e.jsx("div",{className:"g7dt-stat-label",children:"숨겨진 요소"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:`g7dt-stat-value ${f.tailwindIssueCount>0?"g7dt-text-yellow":"g7dt-text-green"}`,children:f.tailwindIssueCount}),e.jsx("div",{className:"g7dt-stat-label",children:"Tailwind 이슈"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:`g7dt-stat-value ${f.darkModeIssueCount>0?"g7dt-text-purple":"g7dt-text-green"}`,children:f.darkModeIssueCount}),e.jsx("div",{className:"g7dt-stat-label",children:"다크모드 이슈"})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsxs("select",{value:r,onChange:c=>o(c.target.value),className:"g7dt-select",children:[e.jsx("option",{value:"all",children:"모든 이슈"}),e.jsx("option",{value:"invisible-element",children:"숨겨진 요소"}),e.jsx("option",{value:"tailwind-purging",children:"Tailwind 퍼징"}),e.jsx("option",{value:"dark-mode-missing",children:"다크모드 누락"})]}),e.jsx("button",{onClick:p,className:"g7dt-btn-secondary",children:"새로고침"})]}),e.jsx("div",{className:"g7dt-scroll-list",children:v.length===0?e.jsx("div",{className:"g7dt-empty-state",children:t.issues.length===0?"스타일 이슈가 없습니다 ✓":"필터에 맞는 이슈가 없습니다"}):v.map(c=>{const h=c.type==="invisible-element"?"👁️":c.type==="tailwind-purging"?"🎨":"🌙",y=c.severity==="error"?"g7dt-severity-error":c.severity==="warning"?"g7dt-severity-warning":"g7dt-severity-info";return e.jsxs("div",{onClick:()=>g(c.componentId),className:`g7dt-style-issue-item ${y} ${a===c.componentId?"g7dt-selected":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("span",{className:"g7dt-mono g7dt-text-blue",children:[h," ",c.componentName]}),e.jsx("span",{className:c.severity==="error"?"g7dt-badge-error":c.severity==="warning"?"g7dt-badge-warning":"g7dt-badge-info",children:c.type})]}),e.jsx("div",{className:"g7dt-text-muted g7dt-mt-1 g7dt-truncate",children:c.description})]},c.componentId)})}),l&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:l.componentName}),e.jsx("button",{onClick:()=>g(null),className:"g7dt-close-btn",children:"✕"})]}),e.jsxs("div",{className:"g7dt-space-y-2 g7dt-text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"이슈 타입:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-yellow",children:l.type})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"설명:"}),e.jsx("div",{className:"g7dt-mt-1 g7dt-text-white",children:l.description})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"CSS 속성:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-purple",children:l.property}),e.jsxs("span",{className:"g7dt-ml-2 g7dt-text-muted",children:["= ",l.currentValue]}),l.expectedValue&&e.jsxs("span",{className:"g7dt-ml-2 g7dt-text-green",children:["(예상: ",l.expectedValue,")"]})]}),l.suggestion&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"해결 방법:"}),e.jsx("div",{className:"g7dt-mt-1 g7dt-text-green",children:l.suggestion})]})]})]}),t.componentStyles.length>0&&e.jsxs("div",{children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:["컴포넌트 스타일 (",t.componentStyles.length,")"]}),e.jsx("div",{className:"g7dt-scroll-list-sm",children:t.componentStyles.slice(0,20).map((c,h)=>e.jsxs("div",{className:"g7dt-list-item",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-blue",children:c.componentName}),e.jsxs("span",{className:"g7dt-text-muted",children:[c.classes.length," classes"]})]}),c.classes.length>0&&e.jsxs("div",{className:"g7dt-text-muted g7dt-mt-1 g7dt-truncate",children:[c.classes.slice(0,5).join(" "),c.classes.length>5&&"..."]})]},h))})]})]})},Pe=({devTools:d})=>{const[t,s]=x.useState(null),[a,g]=x.useState(null),[r,o]=x.useState("all"),p=x.useCallback(()=>{s(d.getAuthDebugInfo())},[d]);if(x.useEffect(()=>{p();const h=setInterval(p,2e3);return()=>clearInterval(h)},[p]),!t)return e.jsx("div",{className:"g7dt-empty-state",children:"로딩 중..."});const v=t.events.filter(h=>r==="all"?!0:h.type===r),l=a?t.events.find(h=>h.id===a):null,f=t.stats,c=t.state;return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-justify-between g7dt-mb-3",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:"현재 인증 상태"}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted",children:["소스: ",c.source||"unknown"]})]}),e.jsxs("div",{className:"g7dt-stats-grid-3 g7dt-mb-3",children:[e.jsx("div",{className:"g7dt-text-center",children:e.jsx("div",{className:`g7dt-text-lg g7dt-font-bold ${c.isAuthenticated?"g7dt-text-green":"g7dt-text-red"}`,children:c.isAuthenticated?"✓ 인증됨":"✕ 미인증"})}),e.jsx("div",{className:"g7dt-text-center",children:e.jsx("div",{className:`g7dt-text-lg g7dt-font-bold ${c.tokens.hasAccessToken?"g7dt-text-green":"g7dt-text-yellow"}`,children:c.tokens.hasAccessToken?"✓ 토큰 유효":"⚠ 토큰 없음"})}),e.jsx("div",{className:"g7dt-text-center",children:e.jsx("div",{className:"g7dt-text-lg g7dt-font-bold g7dt-text-blue",children:c.user?.name||c.user?.email||"익명"})})]}),c.user&&e.jsxs("div",{className:"g7dt-border-t g7dt-pt-3 g7dt-mt-3",children:[e.jsxs("div",{className:"g7dt-grid-2 g7dt-gap-2 g7dt-text-xs",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"ID:"}),e.jsx("span",{className:"g7dt-text-white g7dt-mono",children:c.user.id})]}),e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"이메일:"}),e.jsx("span",{className:"g7dt-text-white g7dt-truncate g7dt-ml-2",title:c.user.email,children:c.user.email})]}),c.user.name&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"이름:"}),e.jsx("span",{className:"g7dt-text-white",children:c.user.name})]}),c.user.nickname&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"닉네임:"}),e.jsx("span",{className:"g7dt-text-white",children:c.user.nickname})]}),c.user.phone&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"전화번호:"}),e.jsx("span",{className:"g7dt-text-white",children:c.user.phone})]}),c.user.status&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"상태:"}),e.jsx("span",{className:c.user.status==="active"?"g7dt-text-green":"g7dt-text-yellow",children:c.user.status})]}),c.user.locale&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"언어:"}),e.jsx("span",{className:"g7dt-text-white",children:c.user.locale})]})]}),c.user.roles&&c.user.roles.length>0&&e.jsxs("div",{className:"g7dt-mt-2",children:[e.jsx("span",{className:"g7dt-text-muted g7dt-text-xs",children:"역할: "}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1 g7dt-mt-1",children:c.user.roles.map((h,y)=>e.jsx("span",{className:"g7dt-role-tag",title:h.guard_name?`guard: ${h.guard_name}`:void 0,children:typeof h=="string"?h:h.name},y))})]}),c.user.permissions&&c.user.permissions.length>0&&e.jsxs("div",{className:"g7dt-mt-2",children:[e.jsx("span",{className:"g7dt-text-muted g7dt-text-xs",children:"권한: "}),e.jsxs("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1 g7dt-mt-1 g7dt-max-h-16 g7dt-overflow-auto",children:[c.user.permissions.slice(0,10).map((h,y)=>e.jsx("span",{className:"g7dt-perm-tag",title:h.guard_name?`guard: ${h.guard_name}`:void 0,children:typeof h=="string"?h:h.name},y)),c.user.permissions.length>10&&e.jsxs("span",{className:"g7dt-text-muted g7dt-text-xs",children:["+",c.user.permissions.length-10,"개"]})]})]}),e.jsxs("div",{className:"g7dt-mt-2 g7dt-grid-2 g7dt-gap-2 g7dt-text-xs",children:[c.user.created_at&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"가입일:"}),e.jsx("span",{className:"g7dt-text-muted",children:new Date(c.user.created_at).toLocaleDateString()})]}),c.user.last_login_at&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"마지막 로그인:"}),e.jsx("span",{className:"g7dt-text-muted",children:new Date(c.user.last_login_at).toLocaleString()})]}),c.user.email_verified_at&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"이메일 인증:"}),e.jsx("span",{className:"g7dt-text-green",children:"✓ 인증됨"})]})]})]}),e.jsx("div",{className:"g7dt-border-t g7dt-pt-3 g7dt-mt-3",children:e.jsxs("div",{className:"g7dt-grid-2 g7dt-gap-2 g7dt-text-xs",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"저장소:"}),e.jsx("span",{className:"g7dt-text-white",children:c.tokens.storage})]}),c.tokens.accessTokenPreview&&e.jsxs("div",{className:"g7dt-flex g7dt-justify-between",children:[e.jsx("span",{className:"g7dt-text-muted",children:"토큰:"}),e.jsx("span",{className:"g7dt-text-muted g7dt-mono",children:c.tokens.accessTokenPreview})]})]})}),c.tokens.accessTokenExpiresAt&&e.jsxs("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mt-2 g7dt-text-center",children:["토큰 만료: ",new Date(c.tokens.accessTokenExpiresAt).toLocaleString()]})]}),e.jsxs("div",{className:"g7dt-stats-grid-5",children:[e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-sm g7dt-text-blue",children:f.loginAttempts}),e.jsx("div",{className:"g7dt-stat-label",children:"로그인 시도"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-sm g7dt-text-green",children:f.successfulLogins}),e.jsx("div",{className:"g7dt-stat-label",children:"성공"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:`g7dt-stat-value-sm ${f.failedLogins>0?"g7dt-text-red":"g7dt-text-muted"}`,children:f.failedLogins}),e.jsx("div",{className:"g7dt-stat-label",children:"실패"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-sm g7dt-text-purple",children:f.tokenRefreshes}),e.jsx("div",{className:"g7dt-stat-label",children:"토큰 갱신"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:`g7dt-stat-value-sm ${f.unauthorizedResponses>0?"g7dt-text-red":"g7dt-text-muted"}`,children:f.unauthorizedResponses}),e.jsx("div",{className:"g7dt-stat-label",children:"401 응답"})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsxs("select",{value:r,onChange:h=>o(h.target.value),className:"g7dt-select",children:[e.jsx("option",{value:"all",children:"모든 이벤트"}),e.jsx("option",{value:"login",children:"로그인"}),e.jsx("option",{value:"logout",children:"로그아웃"}),e.jsx("option",{value:"token-refresh",children:"토큰 갱신"}),e.jsx("option",{value:"token-expired",children:"토큰 만료"}),e.jsx("option",{value:"api-unauthorized",children:"401 응답"})]}),e.jsx("button",{onClick:p,className:"g7dt-btn-secondary",children:"새로고침"})]}),e.jsx("div",{className:"g7dt-scroll-list-sm",children:v.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"인증 이벤트가 없습니다"}):v.slice(-20).reverse().map(h=>{const y=h.success?"✅":"❌",n=new Date(h.timestamp).toLocaleTimeString();return e.jsxs("div",{onClick:()=>g(h.id),className:`g7dt-auth-event-item ${a===h.id?"g7dt-selected":h.success?"":"g7dt-error"}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("span",{className:"g7dt-mono",children:[y," ",h.type]}),e.jsx("span",{className:"g7dt-text-muted",children:n})]}),h.error&&e.jsx("div",{className:"g7dt-text-red g7dt-mt-1 g7dt-truncate",children:h.error})]},h.id)})}),l&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:l.type}),e.jsx("button",{onClick:()=>g(null),className:"g7dt-close-btn",children:"✕"})]}),e.jsxs("div",{className:"g7dt-space-y-2 g7dt-text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"결과:"}),e.jsx("span",{className:`g7dt-ml-2 ${l.success?"g7dt-text-green":"g7dt-text-red"}`,children:l.success?"성공":"실패"})]}),l.error&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"에러:"}),e.jsx("div",{className:"g7dt-mt-1 g7dt-text-red",children:l.error})]}),l.details&&Object.keys(l.details).length>0&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"상세:"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-green",children:JSON.stringify(l.details,null,2)})]})]})]}),t.headerAnalysis.length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"최근 API 인증 헤더"}),e.jsx("div",{className:"g7dt-scroll-list-xs",children:t.headerAnalysis.slice(-10).reverse().map((h,y)=>e.jsxs("div",{className:"g7dt-header-item",children:[e.jsx("span",{className:"g7dt-text-blue g7dt-truncate g7dt-flex-1",children:h.url}),e.jsx("span",{className:`g7dt-ml-2 ${h.hasAuthHeader?"g7dt-text-green":"g7dt-text-yellow"}`,children:h.hasAuthHeader?`✓ ${h.headerType}`:"✕ 헤더 없음"}),h.responseStatus&&e.jsx("span",{className:`g7dt-ml-2 ${h.responseStatus<400?"g7dt-text-muted":"g7dt-text-red"}`,children:h.responseStatus})]},y))})]})]})},He=({devTools:d})=>{const[t,s]=x.useState([]),[a,g]=x.useState(null),[r,o]=x.useState(null),[p,v]=x.useState("all"),[l,f]=x.useState(""),[c,h]=x.useState(""),y=x.useCallback(()=>{const b=d.getLogInfo();s(b.entries),g(b.stats)},[d]);x.useEffect(()=>{y();const b=setInterval(y,1e3);return()=>clearInterval(b)},[y]);const n=t.filter(b=>!(p!=="all"&&b.level!==p||l&&!b.prefix.toLowerCase().includes(l.toLowerCase())||c&&!b.message.toLowerCase().includes(c.toLowerCase()))),i=r?t.find(b=>b.id===r):null,u=()=>{d.clearLogs(),y(),o(null)},m=b=>{switch(b){case"error":return"g7dt-text-red";case"warn":return"g7dt-text-yellow";case"info":return"g7dt-text-blue";case"debug":return"g7dt-text-muted";default:return"g7dt-text-white"}},k=b=>{switch(b){case"error":return"g7dt-log-error";case"warn":return"g7dt-log-warn";case"info":return"g7dt-log-info";case"debug":return"g7dt-log-debug";default:return"g7dt-log-default"}};return e.jsxs("div",{className:"g7dt-space-y-4",children:[a&&e.jsxs("div",{className:"g7dt-stats-grid-6",children:[e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-sm g7dt-text-white",children:a.totalLogs}),e.jsx("div",{className:"g7dt-stat-label",children:"전체"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-sm g7dt-text-red",children:a.byLevel.error}),e.jsx("div",{className:"g7dt-stat-label",children:"에러"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-sm g7dt-text-yellow",children:a.byLevel.warn}),e.jsx("div",{className:"g7dt-stat-label",children:"경고"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:"g7dt-stat-value-sm g7dt-text-blue",children:a.byLevel.info}),e.jsx("div",{className:"g7dt-stat-label",children:"정보"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:`g7dt-stat-value-sm ${a.recentErrors>0?"g7dt-text-red":"g7dt-text-green"}`,children:a.recentErrors}),e.jsx("div",{className:"g7dt-stat-label",children:"최근 에러"})]}),e.jsxs("div",{className:"g7dt-stat-card-sm",children:[e.jsx("div",{className:`g7dt-stat-value-sm ${a.recentWarnings>0?"g7dt-text-yellow":"g7dt-text-green"}`,children:a.recentWarnings}),e.jsx("div",{className:"g7dt-stat-label",children:"최근 경고"})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-flex-wrap",children:[e.jsxs("select",{value:p,onChange:b=>v(b.target.value),className:"g7dt-select",children:[e.jsx("option",{value:"all",children:"모든 레벨"}),e.jsx("option",{value:"error",children:"에러"}),e.jsx("option",{value:"warn",children:"경고"}),e.jsx("option",{value:"info",children:"정보"}),e.jsx("option",{value:"log",children:"로그"}),e.jsx("option",{value:"debug",children:"디버그"})]}),e.jsx("input",{type:"text",placeholder:"prefix 필터",value:l,onChange:b=>f(b.target.value),className:"g7dt-input g7dt-w-32"}),e.jsx("input",{type:"text",placeholder:"메시지 검색",value:c,onChange:b=>h(b.target.value),className:"g7dt-input g7dt-flex-1"}),e.jsx("button",{onClick:y,className:"g7dt-btn-secondary",children:"새로고침"}),e.jsx("button",{onClick:u,className:"g7dt-btn-danger",children:"초기화"})]}),e.jsx("div",{className:"g7dt-scroll-list-lg",children:n.length===0?e.jsx("div",{className:"g7dt-empty-state",children:t.length===0?"로그가 없습니다":"필터에 맞는 로그가 없습니다"}):n.slice(-50).reverse().map(b=>{const N=new Date(b.timestamp).toLocaleTimeString();return e.jsxs("div",{onClick:()=>o(b.id),className:`g7dt-log-item ${r===b.id?"g7dt-selected":k(b.level)}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{className:`g7dt-font-bold g7dt-uppercase ${m(b.level)}`,children:b.level}),e.jsxs("span",{className:"g7dt-text-purple",children:["[",b.prefix,"]"]})]}),e.jsx("span",{className:"g7dt-text-muted",children:N})]}),e.jsx("div",{className:"g7dt-text-white g7dt-mt-1 g7dt-truncate",children:b.message})]},b.id)})}),i&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold",children:[e.jsx("span",{className:m(i.level),children:i.level.toUpperCase()})," ",e.jsxs("span",{className:"g7dt-text-purple",children:["[",i.prefix,"]"]})]}),e.jsx("button",{onClick:()=>o(null),className:"g7dt-close-btn",children:"✕"})]}),e.jsxs("div",{className:"g7dt-space-y-2 g7dt-text-xs",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"시간:"}),e.jsx("span",{className:"g7dt-ml-2 g7dt-text-white",children:new Date(i.timestamp).toLocaleString()})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"메시지:"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-white g7dt-whitespace-pre-wrap",children:i.message})]}),i.args.length>0&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"인수:"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-green",children:JSON.stringify(i.args,null,2)})]}),i.stack&&e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"스택 트레이스:"}),e.jsx("pre",{className:"g7dt-pre-stack g7dt-text-red",children:i.stack})]})]})]}),a&&Object.keys(a.byPrefix).length>0&&e.jsxs("div",{children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"Prefix별 로그 수"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-2",children:Object.entries(a.byPrefix).sort((b,N)=>N[1]-b[1]).slice(0,10).map(([b,N])=>e.jsxs("button",{onClick:()=>f(b),className:l===b?"g7dt-prefix-btn-active":"g7dt-prefix-btn",children:[b,": ",e.jsx("span",{className:"g7dt-text-blue",children:N})]},b))})]})]})},Fe=({devTools:d})=>{const[t,s]=x.useState(d.getLayoutDebugInfo()),[a,g]=x.useState(!1),[r,o]=x.useState(null),[p,v]=x.useState(!1),[l,f]=x.useState({});x.useEffect(()=>{const m=setInterval(()=>{s(d.getLayoutDebugInfo())},1e3);return()=>clearInterval(m)},[d]),x.useEffect(()=>{(async()=>{try{const k=await fetch("/api/admin/permissions",{headers:{Authorization:`Bearer ${localStorage.getItem("auth_token")}`,Accept:"application/json"}});if(k.ok){const b=await k.json(),N={},C=w=>{w.forEach(S=>{N[S.identifier]=S.name,S.children?.length&&C(S.children)})};Object.values(b.data?.permissions||{}).forEach(w=>{w.permissions&&C(w.permissions)}),f(N)}}catch(k){console.warn("[G7DevTools] 권한 목록 조회 실패:",k)}})()},[]);const c=t.current,h=c?.layoutJson,y=t.history,n=t.stats,i=h?[{key:"components",label:"컴포넌트",count:Array.isArray(h.components)?h.components.length:0},{key:"data_sources",label:"데이터소스",count:Array.isArray(h.data_sources)?h.data_sources.length:0},{key:"computed",label:"Computed",count:h.computed?Object.keys(h.computed).length:0},{key:"defines",label:"Defines",count:h.defines?Object.keys(h.defines).length:0},{key:"slots",label:"Slots",count:h.slots?Object.keys(h.slots).length:0},{key:"modals",label:"Modals",count:h.modals?Object.keys(h.modals).length:0},{key:"init_actions",label:"초기화 액션",count:Array.isArray(h.init_actions)?h.init_actions.length:0},{key:"scripts",label:"스크립트",count:Array.isArray(h.scripts)?h.scripts.length:0},{key:"meta",label:"메타데이터",count:h.meta?Object.keys(h.meta).length:0},{key:"errorHandling",label:"에러핸들링",count:h.errorHandling?Object.keys(h.errorHandling).length:0},{key:"permissions",label:"권한",count:Array.isArray(h.permissions)?h.permissions.length:0}]:[],u=m=>{navigator.clipboard.writeText(JSON.stringify(m,null,2))};return c?e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"📊 로드 통계"}),e.jsxs("div",{className:"g7dt-grid-3",children:[e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"총 로드:"}),e.jsx("span",{className:"g7dt-text-blue",children:n.totalLoads})]}),e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"캐시 히트:"}),e.jsx("span",{className:"g7dt-text-green",children:n.cacheHits})]}),e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"API 로드:"}),e.jsx("span",{className:"g7dt-text-yellow",children:n.apiLoads})]})]})]}),e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:"📋 현재 레이아웃"}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsx("button",{onClick:()=>u(h),className:"g7dt-btn-small",title:"전체 JSON 복사",children:"📋 복사"}),e.jsx("button",{onClick:()=>g(!a),className:"g7dt-btn-small",children:a?"요약 보기":"전체 보기"})]})]}),e.jsxs("div",{className:"g7dt-space-y-2 g7dt-text-xs",children:[e.jsxs("div",{className:"g7dt-flex g7dt-gap-4",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"경로:"}),e.jsx("span",{className:"g7dt-ml-1 g7dt-text-white g7dt-font-mono",children:c.layoutPath})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"템플릿:"}),e.jsx("span",{className:"g7dt-ml-1 g7dt-text-blue",children:c.templateId})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-4",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"버전:"}),e.jsx("span",{className:"g7dt-ml-1 g7dt-text-white",children:c.version||"-"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"소스:"}),e.jsx("span",{className:`g7dt-ml-1 ${c.source==="cache"?"g7dt-text-green":"g7dt-text-yellow"}`,children:c.source==="cache"?"💾 캐시":"🌐 API"})]}),e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"로드 시간:"}),e.jsx("span",{className:"g7dt-ml-1 g7dt-text-white",children:c.loadedAt?new Date(c.loadedAt).toLocaleTimeString():"-"})]})]}),e.jsx("div",{className:"g7dt-flex g7dt-gap-4 g7dt-mt-2",children:e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-text-muted",children:"권한:"}),h.permissions&&h.permissions.length>0?e.jsxs("span",{className:"g7dt-ml-1 g7dt-text-yellow",children:["🔒 ",h.permissions.map(m=>l[m]||m).join(", ")]}):h.permissions&&h.permissions.length===0?e.jsx("span",{className:"g7dt-ml-1 g7dt-text-green",children:"🌐 공개"}):e.jsx("span",{className:"g7dt-ml-1 g7dt-text-muted",children:"미정의 (부모 상속)"})]})})]})]}),!a&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"🏗️ 레이아웃 구조"}),e.jsx("div",{className:"g7dt-grid-2",children:i.map(m=>e.jsxs("button",{onClick:()=>o(r===m.key?null:m.key),className:`g7dt-section-btn ${r===m.key?"g7dt-selected":""}`,children:[e.jsx("span",{children:m.label}),e.jsxs("span",{className:"g7dt-text-blue",children:[m.count,"개"]})]},m.key))})]}),(a||r)&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:a?"📄 전체 레이아웃 JSON":`📎 ${r} 섹션`}),e.jsx("button",{onClick:()=>{a?u(h):r&&h&&u(h[r])},className:"g7dt-btn-small",children:"복사"})]}),r==="permissions"&&!a?e.jsx("div",{className:"g7dt-text-xs",children:h.permissions&&h.permissions.length>0?e.jsxs("table",{className:"g7dt-table g7dt-w-full",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"g7dt-border-b g7dt-border-gray-700",children:[e.jsx("th",{className:"g7dt-text-left g7dt-p-2 g7dt-text-muted",children:"권한 ID"}),e.jsx("th",{className:"g7dt-text-left g7dt-p-2 g7dt-text-muted",children:"명칭"})]})}),e.jsx("tbody",{children:h.permissions.map(m=>e.jsxs("tr",{className:"g7dt-border-b g7dt-border-gray-800",children:[e.jsx("td",{className:"g7dt-p-2 g7dt-font-mono g7dt-text-blue",children:m}),e.jsx("td",{className:"g7dt-p-2 g7dt-text-white",children:l[m]||e.jsx("span",{className:"g7dt-text-muted",children:"-"})})]},m))})]}):h.permissions&&h.permissions.length===0?e.jsx("p",{className:"g7dt-text-muted g7dt-p-2",children:"🌐 공개 레이아웃 (permissions: [])"}):e.jsx("p",{className:"g7dt-text-muted g7dt-p-2",children:"권한 미정의 (부모 레이아웃 상속)"})}):e.jsx("pre",{className:"g7dt-pre g7dt-text-green g7dt-max-h-96 g7dt-overflow-auto",children:JSON.stringify(a?h:r&&h?h[r]:null,null,2)})]}),y.length>0&&e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-cursor-pointer",onClick:()=>v(!p),children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold",children:["📜 로드 이력 (",y.length,")"]}),e.jsx("span",{className:"g7dt-text-muted",children:p?"▼":"▶"})]}),p&&e.jsx("div",{className:"g7dt-mt-2 g7dt-space-y-1",children:y.slice(-20).reverse().map(m=>e.jsxs("div",{className:"g7dt-history-item",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsx("span",{className:"g7dt-font-mono g7dt-text-xs",children:m.layoutPath}),e.jsx("span",{className:`g7dt-text-xs ${m.source==="cache"?"g7dt-text-green":"g7dt-text-yellow"}`,children:m.source==="cache"?"💾":"🌐"})]}),e.jsxs("div",{className:"g7dt-text-xs g7dt-text-muted",children:[m.templateId," · ",m.loadedAt?new Date(m.loadedAt).toLocaleTimeString():"-"]})]},m.id))})]}),e.jsxs("div",{className:"g7dt-card g7dt-text-xs g7dt-text-muted",children:["💡 레이아웃 캐시 문제가 의심되면:",e.jsxs("ul",{className:"g7dt-ml-4 g7dt-list-disc",children:[e.jsx("li",{children:'"소스" 항목이 💾 캐시인지 🌐 API인지 확인'}),e.jsx("li",{children:"캐시에서 로드된 경우, JSON 내용이 최신인지 확인"}),e.jsxs("li",{children:["문제가 있으면 ",e.jsx("code",{className:"g7dt-code",children:"php artisan template:refresh-layout"})," 실행"]})]})]})]}):e.jsx("div",{className:"g7dt-space-y-4",children:e.jsxs("div",{className:"g7dt-empty-state",children:["현재 로드된 레이아웃이 없습니다.",e.jsx("br",{}),"페이지를 새로고침하거나 라우트를 변경해보세요."]})})},We=({devTools:d})=>{const[t,s]=x.useState(d.getChangeDetectionInfo()),[a,g]=x.useState(null),[r,o]=x.useState(!1),[p,v]=x.useState(new Set);x.useEffect(()=>{const b=setInterval(()=>{s(d.getChangeDetectionInfo())},500);return()=>clearInterval(b)},[d]);const{executionDetails:l,alerts:f,stats:c}=t,h=r?l.filter(b=>b.alerts.length>0||b.stateChanges.length===0):l,y=a?l.find(b=>b.executionId===a):null,n=b=>{v(N=>{const C=new Set(N);return C.has(b)?C.delete(b):C.add(b),C})},i=b=>{switch(b){case"normal":return"✅";case"early-return-condition":return"⏎";case"early-return-validation":return"❌";case"error":return"💥";default:return"❓"}},u=b=>{switch(b){case"no-state-change":return"⚠️";case"no-datasource-change":return"📊";case"expected-not-fulfilled":return"❗";case"object-reference-same":return"🔄";case"early-return-detected":return"⏎";case"async-timing-issue":return"⏱️";default:return"📢"}},m=b=>{switch(b){case"error":return"g7dt-text-red";case"warning":return"g7dt-text-yellow";case"info":return"g7dt-text-blue";default:return"g7dt-text-white"}},k=b=>new Date(b).toLocaleTimeString("ko-KR",{hour:"2-digit",minute:"2-digit",second:"2-digit",fractionalSecondDigits:3});return e.jsxs("div",{className:"g7dt-space-y-4",children:[f.filter(b=>b.severity==="error"||b.severity==="warning").length>0&&e.jsx("div",{className:"g7dt-card",style:{backgroundColor:"#7f1d1d",borderColor:"#991b1b"},children:e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("span",{className:"g7dt-font-bold",children:["⚠️ 변경 감지 알림: ",f.filter(b=>b.severity==="error").length,"개 에러,"," ",f.filter(b=>b.severity==="warning").length,"개 경고"]}),e.jsx("button",{onClick:()=>d.clearChangeDetectionData(),className:"g7dt-btn-small",children:"초기화"})]})}),e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"📊 변경 감지 통계"}),e.jsxs("div",{className:"g7dt-grid-3",children:[e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"총 실행:"}),e.jsx("span",{className:"g7dt-text-blue",children:c.totalExecutions})]}),e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"상태 변경 있음:"}),e.jsx("span",{className:"g7dt-text-green",children:c.executionsWithStateChange})]}),e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"상태 변경 없음:"}),e.jsx("span",{className:c.executionsWithoutStateChange>0?"g7dt-text-yellow":"g7dt-text-gray",children:c.executionsWithoutStateChange})]}),e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"Early Return:"}),e.jsx("span",{className:"g7dt-text-orange",children:c.earlyReturnCount})]}),e.jsxs("div",{className:"g7dt-stat-item",children:[e.jsx("span",{className:"g7dt-text-muted",children:"알림:"}),e.jsx("span",{className:c.alertCount>0?"g7dt-text-red":"g7dt-text-gray",children:c.alertCount})]})]})]}),f.length>0&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"🔔 최근 알림"}),e.jsx("div",{className:"g7dt-space-y-2",style:{maxHeight:"200px",overflowY:"auto"},children:f.slice(-10).reverse().map(b=>e.jsxs("div",{className:"g7dt-list-item",onClick:()=>n(b.id),style:{cursor:"pointer"},children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-start",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:u(b.type)}),e.jsx("span",{className:`g7dt-text-xs ${m(b.severity)}`,children:b.message})]}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted",children:k(b.timestamp)})]}),p.has(b.id)&&e.jsxs("div",{className:"g7dt-mt-2 g7dt-text-xs g7dt-text-muted g7dt-pl-6",children:[e.jsx("p",{children:b.description}),b.statePath&&e.jsxs("p",{className:"g7dt-mt-1",children:[e.jsx("span",{className:"g7dt-text-cyan",children:"경로:"})," ",b.statePath]}),b.suggestion&&e.jsxs("p",{className:"g7dt-mt-1",children:[e.jsx("span",{className:"g7dt-text-green",children:"제안:"})," ",b.suggestion]}),b.docLink&&e.jsxs("p",{className:"g7dt-mt-1",children:[e.jsx("span",{className:"g7dt-text-blue",children:"문서:"})," ",e.jsx("code",{className:"g7dt-code",children:b.docLink})]})]})]},b.id))})]}),e.jsxs("div",{className:"g7dt-card",children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center g7dt-mb-2",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold",children:"🔧 핸들러 실행 이력"}),e.jsxs("label",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-xs",children:[e.jsx("input",{type:"checkbox",checked:r,onChange:b=>o(b.target.checked)}),e.jsx("span",{children:"경고만 표시"})]})]}),h.length===0?e.jsxs("div",{className:"g7dt-empty-state",children:["핸들러 실행 이력이 없습니다.",e.jsx("br",{}),"액션을 실행하면 여기에 표시됩니다."]}):e.jsx("div",{className:"g7dt-space-y-1",style:{maxHeight:"300px",overflowY:"auto"},children:h.slice(-20).reverse().map(b=>e.jsxs("div",{className:`g7dt-list-item ${a===b.executionId?"g7dt-selected":""}`,onClick:()=>g(a===b.executionId?null:b.executionId),style:{cursor:"pointer"},children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:i(b.exitReason)}),e.jsx("span",{className:"g7dt-text-white g7dt-font-mono g7dt-text-xs",children:b.handlerName}),b.alerts.length>0&&e.jsx("span",{className:"g7dt-badge g7dt-badge-warning",children:b.alerts.length})]}),e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-xs",children:[e.jsxs("span",{className:"g7dt-text-muted",children:["상태: ",b.stateChanges.length]}),e.jsx("span",{className:"g7dt-text-muted",children:b.duration?`${b.duration}ms`:"-"}),e.jsx("span",{className:"g7dt-text-muted",children:k(b.startTime)})]})]}),a===b.executionId&&y&&e.jsxs("div",{className:"g7dt-mt-3 g7dt-pt-3 g7dt-border-t g7dt-border-gray-700",children:[e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted",children:"종료 사유: "}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-white",children:y.exitReason||"unknown"}),y.exitLocation&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-2",children:"위치: "}),e.jsx("code",{className:"g7dt-code g7dt-text-xs",children:y.exitLocation})]})]}),y.exitDescription&&e.jsx("div",{className:"g7dt-mb-2 g7dt-text-xs g7dt-text-muted",children:y.exitDescription}),y.stateChanges.length>0&&e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsxs("span",{className:"g7dt-text-xs g7dt-font-bold g7dt-text-green",children:["상태 변경 (",y.stateChanges.length,")"]}),e.jsx("div",{className:"g7dt-mt-1 g7dt-space-y-1",children:y.stateChanges.map(N=>e.jsxs("div",{className:"g7dt-text-xs g7dt-pl-2",children:[e.jsx("span",{className:"g7dt-text-cyan",children:N.path}),e.jsxs("span",{className:"g7dt-text-muted",children:[" (",N.changeType,")"]}),N.comparison.changedKeys&&e.jsxs("span",{className:"g7dt-text-muted g7dt-ml-1",children:["[변경: ",N.comparison.changedKeys.join(", "),"]"]})]},N.id))})]}),y.dataSourceChanges.length>0&&e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsxs("span",{className:"g7dt-text-xs g7dt-font-bold g7dt-text-blue",children:["데이터소스 변경 (",y.dataSourceChanges.length,")"]}),e.jsx("div",{className:"g7dt-mt-1 g7dt-space-y-1",children:y.dataSourceChanges.map((N,C)=>e.jsxs("div",{className:"g7dt-text-xs g7dt-pl-2",children:[e.jsx("span",{className:"g7dt-text-cyan",children:N.dataSourceId}),e.jsxs("span",{className:"g7dt-text-muted",children:[" ","(",N.changeType,": ",N.previousStatus," → ",N.newStatus,")"]})]},C))})]}),y.expectedChanges&&e.jsxs("div",{className:"g7dt-mb-2",children:[e.jsx("span",{className:"g7dt-text-xs g7dt-font-bold g7dt-text-yellow",children:"기대 변경"}),e.jsxs("div",{className:"g7dt-mt-1 g7dt-text-xs g7dt-pl-2 g7dt-text-muted",children:["상태: ",y.expectedChanges.expectedStatePaths.join(", ")||"없음",e.jsx("br",{}),"데이터소스: ",y.expectedChanges.expectedDataSources.join(", ")||"없음"]})]}),y.alerts.length>0&&e.jsxs("div",{children:[e.jsxs("span",{className:"g7dt-text-xs g7dt-font-bold g7dt-text-red",children:["알림 (",y.alerts.length,")"]}),e.jsx("div",{className:"g7dt-mt-1 g7dt-space-y-1",children:y.alerts.map(N=>e.jsxs("div",{className:"g7dt-text-xs g7dt-pl-2",children:[e.jsx("span",{children:u(N.type)}),e.jsx("span",{className:`g7dt-ml-1 ${m(N.severity)}`,children:N.message})]},N.id))})]})]})]},b.executionId))})]}),e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-2",children:"💡 변경 감지 가이드"}),e.jsxs("ul",{className:"g7dt-help-list",children:[e.jsx("li",{children:"핸들러 실행 후 상태 변경이 없으면 ⚠️ 경고가 표시됩니다"}),e.jsx("li",{children:"early return으로 종료된 경우 ⏎ 아이콘으로 표시됩니다"}),e.jsx("li",{children:"객체 변경 시 참조가 동일하면 🔄 경고가 발생합니다"}),e.jsx("li",{children:"문제 해결: exitLocation 확인 → 조건문 검토 → 불변성 확인"})]})]})]})},Ve=({devTools:d})=>{const[t,s]=x.useState(null),[a,g]=x.useState(null),[r,o]=x.useState("all"),p=x.useCallback(()=>{s(d.getStaleClosureTrackingInfo())},[d]);if(x.useEffect(()=>{p();const n=setInterval(p,2e3);return()=>clearInterval(n)},[p]),!t)return e.jsx("div",{className:"g7dt-empty-state",children:"로딩 중..."});const{warnings:v,stats:l}=t,f=v.filter(n=>r==="all"?!0:n.severity===r),c=a?v.find(n=>n.id===a):null,h=n=>{switch(n){case"error":return"❌";case"warning":return"⚠️";default:return"❓"}},y=n=>{switch(n){case"state-changed-during-async":return"⏳";case"captured-in-callback":return"📸";case"stale-in-handler":return"🔄";default:return"❓"}};return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"Stale Closure 통계"}),e.jsxs("div",{className:"g7dt-stats-grid-3",children:[e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-yellow",children:l.totalWarnings||0}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"총 경고"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-red",children:l.warningsBySeverity?.error||0}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"에러"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-orange",children:l.warningsBySeverity?.warning||0}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"경고"})]})]})]}),l.warningsByType&&Object.keys(l.warningsByType).length>0&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"타입별 분포"}),e.jsx("div",{className:"g7dt-space-y-2",children:Object.entries(l.warningsByType).map(([n,i])=>e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-text-xs",children:[e.jsxs("span",{className:"g7dt-text-muted",children:[y(n)," ",n]}),e.jsx("span",{className:"g7dt-text-white g7dt-font-mono",children:i})]},n))})]}),e.jsx("div",{className:"g7dt-card",children:e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted",children:"심각도:"}),e.jsxs("select",{value:r,onChange:n=>o(n.target.value),className:"g7dt-select",children:[e.jsx("option",{value:"all",children:"전체"}),e.jsx("option",{value:"error",children:"에러"}),e.jsx("option",{value:"warning",children:"경고"})]}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:[f.length,"개 표시"]})]})}),e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"Stale Closure 경고"}),f.length===0?e.jsx("div",{className:"g7dt-empty-state g7dt-text-green",children:"✅ Stale Closure 경고가 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:f.slice().reverse().map(n=>e.jsxs("div",{className:`g7dt-list-item g7dt-cursor-pointer ${a===n.id?"g7dt-selected":""}`,onClick:()=>g(a===n.id?null:n.id),children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:h(n.severity)}),e.jsx("span",{children:y(n.type)}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-white g7dt-truncate",children:n.location}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:new Date(n.timestamp).toLocaleTimeString()})]}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mt-1 g7dt-truncate",children:n.statePath})]},n.id))})]}),c&&e.jsxs("div",{className:"g7dt-card g7dt-border-yellow",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:[h(c.severity)," 경고 상세"]}),e.jsxs("div",{className:"g7dt-space-y-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"위치"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-white g7dt-mono",children:c.location})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"타입"}),e.jsxs("div",{className:"g7dt-text-sm g7dt-text-white",children:[y(c.type)," ",c.type]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"상태 경로"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-yellow g7dt-mono",children:c.statePath})]}),e.jsxs("div",{className:"g7dt-grid-2 g7dt-gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"캡처된 값"}),e.jsx("pre",{className:"g7dt-code-block g7dt-text-red",children:JSON.stringify(c.capturedValue,null,2)})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"현재 값"}),e.jsx("pre",{className:"g7dt-code-block g7dt-text-green",children:JSON.stringify(c.currentValue,null,2)})]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"시간 차이"}),e.jsxs("div",{className:"g7dt-text-sm g7dt-text-white",children:[c.timeDiff,"ms"]})]}),c.suggestion&&e.jsxs("div",{className:"g7dt-bg-blue-dark g7dt-p-2 g7dt-rounded",children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-blue",children:"💡 제안"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-white g7dt-mt-1",children:c.suggestion})]})]})]})]})},Be=({devTools:d})=>{const[t,s]=x.useState(null),[a,g]=x.useState(null),[r,o]=x.useState("all"),p=x.useCallback(()=>{s(d.getNestedContextTrackingInfo())},[d]);if(x.useEffect(()=>{p();const n=setInterval(p,2e3);return()=>clearInterval(n)},[p]),!t)return e.jsx("div",{className:"g7dt-empty-state",children:"로딩 중..."});const{contexts:v,stats:l}=t,f=v.filter(n=>r==="all"?!0:n.componentType===r),c=a?v.find(n=>n.id===a):null,h=n=>{switch(n){case"expandChildren":return"📂";case"cellChildren":return"📊";case"iteration":return"🔄";case"modal":return"🪟";case"slot":return"🔲";default:return"❓"}},y=n=>"│".repeat(Math.max(0,n-1))+(n>0?"├─":"");return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"Nested Context 통계"}),e.jsxs("div",{className:"g7dt-stats-grid-3",children:[e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-blue",children:l.totalContexts||0}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"총 컨텍스트"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-purple",children:l.maxDepth||0}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"최대 깊이"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-red",children:l.failedAccessCount||0}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"접근 오류"})]})]})]}),l.byType&&Object.keys(l.byType).length>0&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"타입별 분포"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-3",children:Object.entries(l.byType).map(([n,i])=>e.jsxs("div",{className:`g7dt-badge g7dt-cursor-pointer ${r===n?"g7dt-badge-selected":""}`,onClick:()=>o(r===n?"all":n),children:[h(n)," ",n,": ",i]},n))})]}),e.jsx("div",{className:"g7dt-card",children:e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted",children:"타입:"}),e.jsxs("select",{value:r,onChange:n=>o(n.target.value),className:"g7dt-select",children:[e.jsx("option",{value:"all",children:"전체"}),e.jsx("option",{value:"expandChildren",children:"expandChildren"}),e.jsx("option",{value:"cellChildren",children:"cellChildren"}),e.jsx("option",{value:"iteration",children:"iteration"}),e.jsx("option",{value:"modal",children:"modal"}),e.jsx("option",{value:"slot",children:"slot"})]}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:[f.length,"개 표시"]})]})}),e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"컨텍스트 목록"}),f.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"추적된 Nested Context가 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:f.slice().reverse().map(n=>{const i=n.accessAttempts?.some(m=>!m.found),u=n.mergedContext?.all||[];return e.jsxs("div",{className:`g7dt-list-item g7dt-cursor-pointer ${a===n.id?"g7dt-selected":""} ${i?"g7dt-border-red":""}`,onClick:()=>g(a===n.id?null:n.id),children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{className:"g7dt-text-muted g7dt-mono g7dt-text-xs",children:y(n.depth)}),e.jsx("span",{children:h(n.componentType)}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-white",children:n.componentId||n.componentType}),i&&e.jsx("span",{className:"g7dt-text-red g7dt-text-xs",children:"⚠️ 오류"}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:["깊이: ",n.depth]})]}),e.jsxs("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mt-1",children:["변수: ",u.slice(0,5).join(", "),u.length>5&&"..."]})]},n.id)})})]}),c&&e.jsxs("div",{className:"g7dt-card g7dt-border-blue",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:[h(c.componentType)," 컨텍스트 상세"]}),e.jsxs("div",{className:"g7dt-space-y-3",children:[e.jsxs("div",{className:"g7dt-grid-2 g7dt-gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"타입"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-white",children:c.componentType})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"깊이"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-white",children:c.depth})]})]}),c.componentId&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"컴포넌트 ID"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-blue g7dt-mono",children:c.componentId})]}),c.parentId&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"부모 컨텍스트"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-purple g7dt-mono",children:c.parentId})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-2",children:"사용 가능한 변수"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1",children:(c.mergedContext?.all||[]).map(n=>e.jsx("span",{className:"g7dt-badge g7dt-badge-blue g7dt-text-xs",children:n},n))})]}),c.ownContext?.added&&c.ownContext.added.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-2",children:"추가된 변수 (이 컨텍스트에서)"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1",children:c.ownContext.added.map(n=>e.jsxs("span",{className:"g7dt-badge g7dt-badge-green g7dt-text-xs",children:["+ ",n]},n))})]}),c.accessAttempts&&c.accessAttempts.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-2",children:"접근 시도"}),e.jsx("div",{className:"g7dt-space-y-1",children:c.accessAttempts.slice(0,10).map((n,i)=>e.jsxs("div",{className:`g7dt-flex g7dt-justify-between g7dt-text-xs ${n.found?"":"g7dt-text-red"}`,children:[e.jsx("span",{className:"g7dt-mono",children:n.path}),e.jsx("span",{children:n.found?"✓":"✕"})]},i))})]})]})]})]})},Ge=({devTools:d})=>{const[t,s]=x.useState(null),[a,g]=x.useState(null),[r,o]=x.useState(null),[p,v]=x.useState("modals"),l=x.useCallback(()=>{s(d.getModalStateScopeTrackingInfo())},[d]);if(x.useEffect(()=>{l();const N=setInterval(l,2e3);return()=>clearInterval(N)},[l]),!t)return e.jsx("div",{className:"g7dt-empty-state",children:"로딩 중..."});const{modals:f,issues:c,relations:h,changeLogs:y,stats:n}=t,i=a?f.find(N=>N.modalId===a):null,u=r?c.find(N=>N.id===r):null,m=N=>{switch(N){case"isolated":return"🔒";case"shared":return"🔓";case"inherited":return"📥";default:return"❓"}},k=N=>{switch(N){case"state-leakage":return"💧";case"isolation-violation":return"🔓";case"parent-mutation":return"👆";case"orphaned-state":return"👻";case"scope-mismatch":return"🔀";case"cleanup-failure":return"🧹";case"missing-definition":return"🚫";default:return"❓"}},b=N=>{switch(N){case"error":return"❌";case"warning":return"⚠️";default:return"❓"}};return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"모달 상태 스코프 통계"}),e.jsxs("div",{className:"g7dt-stats-grid-3",children:[e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-blue",children:n.totalModals}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"총 모달"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-green",children:n.openModals}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"열린 모달"})]}),e.jsxs("div",{className:"g7dt-text-center",children:[e.jsx("div",{className:"g7dt-text-2xl g7dt-font-bold g7dt-text-red",children:n.totalIssues}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"이슈"})]})]})]}),e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"스코프별 / 이슈별"}),e.jsxs("div",{className:"g7dt-grid-2 g7dt-gap-4",children:[e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-2",children:"스코프 타입"}),e.jsx("div",{className:"g7dt-space-y-1",children:Object.entries(n.byScope).map(([N,C])=>e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-text-xs",children:[e.jsxs("span",{children:[m(N)," ",N]}),e.jsx("span",{className:"g7dt-font-mono",children:C})]},N))})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-2",children:"이슈 타입"}),e.jsxs("div",{className:"g7dt-space-y-1",children:[Object.entries(n.issuesByType).filter(([N,C])=>C>0).map(([N,C])=>e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-text-xs",children:[e.jsxs("span",{children:[k(N)," ",N]}),e.jsx("span",{className:"g7dt-font-mono g7dt-text-red",children:C})]},N)),Object.values(n.issuesByType).every(N=>N===0)&&e.jsx("div",{className:"g7dt-text-xs g7dt-text-green",children:"✅ 이슈 없음"})]})]})]})]}),e.jsx("div",{className:"g7dt-card",children:e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsxs("button",{className:`g7dt-tab-button ${p==="modals"?"g7dt-tab-active":""}`,onClick:()=>v("modals"),children:["🪟 모달 (",f.length,")"]}),e.jsxs("button",{className:`g7dt-tab-button ${p==="issues"?"g7dt-tab-active":""}`,onClick:()=>v("issues"),children:["⚠️ 이슈 (",c.length,")"]}),e.jsxs("button",{className:`g7dt-tab-button ${p==="logs"?"g7dt-tab-active":""}`,onClick:()=>v("logs"),children:["📝 로그 (",y.length,")"]})]})}),p==="modals"&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"모달 목록"}),f.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"추적된 모달이 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:f.map(N=>{const C=c.some(w=>w.modalId===N.modalId);return e.jsx("div",{className:`g7dt-list-item g7dt-cursor-pointer ${a===N.modalId?"g7dt-selected":""} ${C?"g7dt-border-red":""}`,onClick:()=>g(a===N.modalId?null:N.modalId),children:e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:N.closedAt===null?"📭":"📪"}),e.jsx("span",{children:m(N.scopeType)}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-white",children:N.modalName}),C&&e.jsx("span",{className:"g7dt-text-red",children:"⚠️"}),e.jsxs("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:["변경: ",N.stateChangeCount]})]})},N.modalId)})})]}),p==="issues"&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"이슈 목록"}),c.length===0?e.jsx("div",{className:"g7dt-empty-state g7dt-text-green",children:"✅ 모달 상태 이슈가 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:c.slice().reverse().map(N=>e.jsxs("div",{className:`g7dt-list-item g7dt-cursor-pointer ${r===N.id?"g7dt-selected":""}`,onClick:()=>o(r===N.id?null:N.id),children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{children:b(N.severity)}),e.jsx("span",{children:k(N.type)}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-white",children:N.modalName}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:new Date(N.timestamp).toLocaleTimeString()})]}),e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mt-1 g7dt-truncate",children:N.description})]},N.id))})]}),p==="logs"&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"상태 변경 로그"}),y.length===0?e.jsx("div",{className:"g7dt-empty-state",children:"상태 변경 로그가 없습니다"}):e.jsx("div",{className:"g7dt-space-y-2 g7dt-max-h-60 g7dt-overflow-y-auto",children:y.slice().reverse().slice(0,50).map(N=>e.jsxs("div",{className:`g7dt-list-item ${N.violatesIsolation?"g7dt-border-red":""}`,children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2",children:[e.jsx("span",{className:"g7dt-text-xs g7dt-text-white",children:N.modalName}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-blue g7dt-mono",children:N.stateKey}),N.violatesIsolation&&e.jsx("span",{className:"g7dt-text-red",children:"⚠️ 격리 위반"}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted g7dt-ml-auto",children:new Date(N.timestamp).toLocaleTimeString()})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2 g7dt-text-xs g7dt-mt-1",children:[e.jsx("span",{className:"g7dt-text-red g7dt-truncate",style:{maxWidth:"45%"},children:JSON.stringify(N.previousValue)}),e.jsx("span",{className:"g7dt-text-muted",children:"→"}),e.jsx("span",{className:"g7dt-text-green g7dt-truncate",style:{maxWidth:"45%"},children:JSON.stringify(N.newValue)})]})]},N.id))})]}),i&&p==="modals"&&e.jsxs("div",{className:"g7dt-card g7dt-border-blue",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:[m(i.scopeType)," 모달 상세: ",i.modalName]}),e.jsxs("div",{className:"g7dt-space-y-3",children:[e.jsxs("div",{className:"g7dt-grid-2 g7dt-gap-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"스코프"}),e.jsxs("div",{className:"g7dt-text-sm g7dt-text-white",children:[m(i.scopeType)," ",i.scopeType]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"상태"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-white",children:i.closedAt===null?"📭 열림":"📪 닫힘"})]})]}),i.parentModalId&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"부모 모달"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-purple g7dt-mono",children:i.parentModalId})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"상태 변경 횟수"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-white",children:i.stateChangeCount})]}),i.isolatedStateKeys.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-1",children:"격리된 상태 키"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1",children:i.isolatedStateKeys.map(N=>e.jsxs("span",{className:"g7dt-badge g7dt-badge-red g7dt-text-xs",children:["🔒 ",N]},N))})]}),i.sharedStateKeys.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted g7dt-mb-1",children:"공유된 상태 키"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1",children:i.sharedStateKeys.map(N=>e.jsxs("span",{className:"g7dt-badge g7dt-badge-blue g7dt-text-xs",children:["🔓 ",N]},N))})]})]})]}),u&&p==="issues"&&e.jsxs("div",{className:"g7dt-card g7dt-border-red",children:[e.jsxs("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:[b(u.severity)," 이슈 상세"]}),e.jsxs("div",{className:"g7dt-space-y-3",children:[e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"타입"}),e.jsxs("div",{className:"g7dt-text-sm g7dt-text-white",children:[k(u.type)," ",u.type]})]}),e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"설명"}),e.jsx("div",{className:"g7dt-text-sm g7dt-text-white",children:u.description})]}),u.affectedStateKeys.length>0&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"영향 받는 상태 키"}),e.jsx("div",{className:"g7dt-flex g7dt-flex-wrap g7dt-gap-1 g7dt-mt-1",children:u.affectedStateKeys.map(N=>e.jsx("span",{className:"g7dt-badge g7dt-text-xs",children:N},N))})]}),u.leakedValue!==void 0&&e.jsxs("div",{children:[e.jsx("div",{className:"g7dt-text-xs g7dt-text-muted",children:"유출된 값"}),e.jsx("pre",{className:"g7dt-code-block g7dt-text-red",children:JSON.stringify(u.leakedValue,null,2)})]})]})]}),h.length>0&&e.jsxs("div",{className:"g7dt-card",children:[e.jsx("h3",{className:"g7dt-text-sm g7dt-font-bold g7dt-mb-3",children:"모달 관계"}),e.jsx("div",{className:"g7dt-space-y-2",children:h.map((N,C)=>e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-gap-2 g7dt-text-xs",children:[e.jsx("span",{className:"g7dt-text-purple",children:N.parentModalId}),e.jsx("span",{className:"g7dt-text-muted",children:"→"}),e.jsx("span",{className:"g7dt-text-blue",children:N.childModalId}),e.jsx("span",{className:"g7dt-badge g7dt-text-xs g7dt-ml-auto",children:N.relationType})]},C))})]})]})},Je=({devTools:d})=>{const[t,s]=x.useState("definitions"),[a,g]=x.useState(null),[r,o]=x.useState(""),p=x.useCallback(()=>{d&&g(d.getNamedActionTrackingInfo())},[d]);if(x.useEffect(()=>{p();const n=setInterval(p,2e3);return()=>clearInterval(n)},[p]),!a)return e.jsx("div",{className:"g7dt-empty-message g7dt-py-4",children:"데이터 로딩 중..."});const{definitions:v,refLogs:l,stats:f}=a,c=Object.keys(v),h=c.filter(n=>!r||n.toLowerCase().includes(r.toLowerCase())||v[n]?.handler?.toLowerCase().includes(r.toLowerCase())),y=l.filter(n=>!r||n.actionRefName.toLowerCase().includes(r.toLowerCase())||n.resolvedHandler.toLowerCase().includes(r.toLowerCase()));return e.jsxs("div",{className:"g7dt-space-y-4",children:[e.jsxs("div",{className:"g7dt-grid g7dt-grid-cols-3 g7dt-gap-2",children:[e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value",children:f.totalDefinitions}),e.jsx("div",{className:"g7dt-stat-label",children:"정의"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value",children:f.totalRefs}),e.jsx("div",{className:"g7dt-stat-label",children:"참조"})]}),e.jsxs("div",{className:"g7dt-stat-card",children:[e.jsx("div",{className:"g7dt-stat-value",style:{color:f.unusedDefinitions.length>0?"#f59e0b":"#10b981"},children:f.unusedDefinitions.length}),e.jsx("div",{className:"g7dt-stat-label",children:"미사용"})]})]}),e.jsxs("div",{className:"g7dt-flex g7dt-gap-2",children:[e.jsxs("button",{onClick:()=>s("definitions"),className:t==="definitions"?"g7dt-filter-btn g7dt-filter-active":"g7dt-filter-btn",children:["정의 목록 (",c.length,")"]}),e.jsxs("button",{onClick:()=>s("refs"),className:t==="refs"?"g7dt-filter-btn g7dt-filter-active":"g7dt-filter-btn",children:["참조 이력 (",l.length,")"]}),e.jsx("button",{onClick:p,className:"g7dt-filter-btn",title:"새로고침",children:"↻"})]}),e.jsx("input",{type:"text",placeholder:t==="definitions"?"액션 이름 검색...":"actionRef 검색...",value:r,onChange:n=>o(n.target.value),className:"g7dt-input g7dt-w-full"}),t==="definitions"&&e.jsx("div",{className:"g7dt-space-y-1",children:h.length===0?e.jsx("div",{className:"g7dt-empty-message g7dt-py-4",children:c.length===0?"정의된 named_actions가 없습니다":"검색 결과 없음"}):h.map(n=>{const i=v[n],u=f.refCountByName[n]||0,m=f.unusedDefinitions.includes(n);return e.jsxs("div",{className:"g7dt-card",style:{borderLeft:m?"3px solid #f59e0b":"3px solid #10b981"},children:[e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-font-bold",children:n}),e.jsxs("span",{className:"g7dt-text-muted g7dt-ml-2",children:["→ ",i.handler]})]}),e.jsxs("span",{className:"g7dt-badge",title:"참조 횟수",children:[u,"회"]})]}),i.params&&e.jsxs("details",{className:"g7dt-mt-1",children:[e.jsx("summary",{className:"g7dt-text-xs g7dt-text-muted g7dt-cursor-pointer",children:"params"}),e.jsx("pre",{className:"g7dt-pre g7dt-text-xs g7dt-mt-1",style:{maxHeight:"200px",overflow:"auto"},children:JSON.stringify(i.params,null,2)})]}),m&&e.jsx("div",{className:"g7dt-text-xs",style:{color:"#f59e0b",marginTop:"4px"},children:"⚠ 미사용 정의"})]},n)})}),t==="refs"&&e.jsx("div",{className:"g7dt-space-y-1",children:y.length===0?e.jsx("div",{className:"g7dt-empty-message g7dt-py-4",children:l.length===0?"actionRef 해석 이력이 없습니다":"검색 결과 없음"}):[...y].reverse().map(n=>e.jsx("div",{className:"g7dt-card",children:e.jsxs("div",{className:"g7dt-flex g7dt-justify-between g7dt-items-center",children:[e.jsxs("div",{children:[e.jsx("span",{className:"g7dt-font-bold",children:n.actionRefName}),e.jsxs("span",{className:"g7dt-text-muted g7dt-ml-2",children:["→ ",n.resolvedHandler]})]}),e.jsx("span",{className:"g7dt-text-xs g7dt-text-muted",children:new Date(n.timestamp).toLocaleTimeString()})]})},n.id))})]})},ge=()=>{x.useEffect(()=>{ve()},[]);const d=x.useRef(oe()),[t,s]=x.useState(d.current.isOpen??!1),[a,g]=x.useState(!1),[r,o]=x.useState("state"),[p,v]=x.useState({_global:{},_local:{},_computed:{}}),[l,f]=x.useState([]),[c,h]=x.useState({hits:0,misses:0,entries:0,hitRate:0}),[y,n]=x.useState(!1),[i,u]=x.useState(d.current.position??{x:-1,y:-1}),[m,k]=x.useState(!1),b=x.useRef(null),N=x.useRef(null),[C,w]=x.useState(d.current.size??{width:Ne,height:ue}),[S,z]=x.useState(!1),[O,K]=x.useState(null),L=x.useRef(null),[V,he]=x.useState(!1),q=x.useRef(null),I=G.getInstance(),se=R();x.useEffect(()=>{if(i.x===-1&&i.y===-1){const T=window.innerWidth-C.width-16;u({x:T,y:16})}},[i,C.width]),x.useEffect(()=>{if(i.x===-1&&i.y===-1||m||S)return;const T=setTimeout(()=>{ie({position:i,size:C})},300);return()=>clearTimeout(T)},[i,C,m,S]),x.useEffect(()=>{ie({isOpen:t})},[t]);const Ke=x.useCallback(T=>{T.target.tagName!=="BUTTON"&&(k(!0),b.current={x:T.clientX,y:T.clientY,posX:i.x,posY:i.y},T.preventDefault())},[i]);x.useEffect(()=>{if(!m)return;const T=_=>{if(!b.current)return;const Y=_.clientX-b.current.x,X=_.clientY-b.current.y;let j=b.current.posX+Y,A=b.current.posY+X;const H=window.innerWidth-C.width,F=window.innerHeight-C.height;j=Math.max(0,Math.min(j,H)),A=Math.max(0,Math.min(A,F)),u({x:j,y:A})},D=()=>{k(!1),b.current=null};return document.addEventListener("mousemove",T),document.addEventListener("mouseup",D),()=>{document.removeEventListener("mousemove",T),document.removeEventListener("mouseup",D)}},[m,C.width,C.height]);const M=x.useCallback(T=>D=>{D.preventDefault(),D.stopPropagation(),z(!0),K(T),L.current={x:D.clientX,y:D.clientY,width:C.width,height:C.height,posX:i.x,posY:i.y}},[C,i]);x.useEffect(()=>{if(!S||!O)return;const T=_=>{if(!L.current)return;const Y=_.clientX-L.current.x,X=_.clientY-L.current.y;let j=L.current.width,A=L.current.height,H=L.current.posX,F=L.current.posY;if(O.includes("e")&&(j=Math.max(re,L.current.width+Y)),O.includes("w")){const B=Math.min(Y,L.current.width-re);j=L.current.width-B,H=L.current.posX+B}if(O.includes("s")&&(A=Math.max(ce,L.current.height+X)),O.includes("n")){const B=Math.min(X,L.current.height-ce);A=L.current.height-B,F=L.current.posY+B}j=Math.min(j,window.innerWidth-H),A=Math.min(A,window.innerHeight-F),H=Math.max(0,H),F=Math.max(0,F),w({width:j,height:A}),u({x:H,y:F})},D=()=>{z(!1),K(null),L.current=null};return document.addEventListener("mousemove",T),document.addEventListener("mouseup",D),()=>{document.removeEventListener("mousemove",T),document.removeEventListener("mouseup",D)}},[S,O]);const qe=x.useCallback(()=>{V?(q.current&&(u(q.current.position),w(q.current.size)),he(!1)):(q.current={position:i,size:C},u({x:0,y:0}),w({width:window.innerWidth,height:window.innerHeight}),he(!0))},[V,i,C]),U=x.useCallback(()=>{I.isEnabled()&&(v(I.getState()),f(I.getActionHistory()),h(I.getCacheStats()),n(se.isConnected()))},[I,se]);x.useEffect(()=>{const T=D=>{D.ctrlKey&&D.shiftKey&&D.key==="G"&&(D.preventDefault(),s(_=>!_))};return window.addEventListener("keydown",T),()=>window.removeEventListener("keydown",T)},[]),x.useEffect(()=>{if(!t||!I.isEnabled())return;U();const T=I.watchState("*",()=>{v(I.getState())}),D=I.watchActions(()=>{f(I.getActionHistory()),h(I.getCacheStats())}),_=setInterval(U,5e3);return()=>{T(),D(),clearInterval(_)}},[t,I,U]);const Ue=async()=>{try{const T=await se.dumpState();console.log("[G7DevTools] 상태 덤프 완료:",T),n(!0)}catch(T){console.error("[G7DevTools] 상태 덤프 실패:",T),n(!1)}};return I.isEnabled()?t?a?e.jsx("div",{className:"g7dt-minimized",children:e.jsxs("div",{className:"g7dt-minimized-content",children:[e.jsx("span",{className:"g7dt-font-bold g7dt-text-sm",children:"G7 DevTools"}),e.jsx("button",{onClick:()=>g(!1),className:"g7dt-btn g7dt-text-xs",title:"확장",children:"▲"}),e.jsx("button",{onClick:()=>s(!1),className:"g7dt-btn g7dt-text-xs",children:"✕"})]})}):e.jsxs("div",{ref:N,className:`g7dt-panel ${V?"maximized":""} ${S?"g7dt-resizing":""}`,style:{left:`${i.x>=0?i.x:0}px`,top:`${i.y>=0?i.y:0}px`,width:`${C.width}px`,height:`${C.height}px`},children:[!V&&e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-corner g7dt-resize-nw",onMouseDown:M("nw")}),e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-corner g7dt-resize-ne",onMouseDown:M("ne")}),e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-corner g7dt-resize-sw",onMouseDown:M("sw")}),e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-corner g7dt-resize-se",onMouseDown:M("se")}),e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-edge-h g7dt-resize-n",onMouseDown:M("n")}),e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-edge-h g7dt-resize-s",onMouseDown:M("s")}),e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-edge-v g7dt-resize-w",onMouseDown:M("w")}),e.jsx("div",{className:"g7dt-resize-handle g7dt-resize-edge-v g7dt-resize-e",onMouseDown:M("e")})]}),e.jsxs("div",{className:`g7dt-header ${m?"dragging":""}`,onMouseDown:Ke,children:[e.jsxs("div",{className:"g7dt-header-left",children:[e.jsx("span",{className:"g7dt-header-title",children:"G7 DevTools"}),e.jsx("span",{className:`g7dt-header-badge ${y?"connected":""}`,title:y?"서버 덤프 성공":"서버에 덤프되지 않음 (덤프 버튼 클릭)",children:y?"덤프 완료":"로컬 모드"})]}),e.jsxs("div",{className:"g7dt-header-right",children:[e.jsx("button",{onClick:Ue,className:"g7dt-btn g7dt-btn-primary",title:"서버로 상태 덤프",children:"덤프"}),e.jsx("button",{onClick:U,className:"g7dt-btn",title:"새로고침",children:"↻"}),e.jsx("button",{onClick:qe,className:"g7dt-btn",title:V?"복원":"최대화",children:V?"❐":"□"}),e.jsx("button",{onClick:()=>g(!0),className:"g7dt-btn",title:"최소화",children:"▼"}),e.jsx("button",{onClick:()=>s(!1),className:"g7dt-btn",children:"✕"})]})]}),e.jsx("div",{className:"g7dt-tabs",children:Object.keys(le).map(T=>e.jsx("button",{onClick:()=>o(T),className:`g7dt-tab ${r===T?"active":""}`,children:le[T]},T))}),e.jsxs("div",{className:"g7dt-content",children:[r==="state"&&e.jsx(ke,{state:p,devTools:I}),r==="actions"&&e.jsx(Ce,{actions:l,devTools:I}),r==="cache"&&e.jsx(Se,{stats:c,devTools:I}),r==="diagnose"&&e.jsx(Ie,{}),r==="performance"&&e.jsx(Te,{devTools:I}),r==="lifecycle"&&e.jsx(De,{devTools:I}),r==="network"&&e.jsx(Le,{devTools:I}),r==="form"&&e.jsx(Ee,{devTools:I}),r==="conditional"&&e.jsx($e,{devTools:I}),r==="expression"&&e.jsx(ze,{devTools:I}),r==="handlers"&&e.jsx(_e,{devTools:I}),r==="events"&&e.jsx(je,{devTools:I}),r==="datasources"&&e.jsx(Ae,{devTools:I}),r==="renders"&&e.jsx(Oe,{devTools:I}),r==="styles"&&e.jsx(Me,{devTools:I}),r==="auth"&&e.jsx(Pe,{devTools:I}),r==="logs"&&e.jsx(He,{devTools:I}),r==="layout"&&e.jsx(Fe,{devTools:I}),r==="changedetection"&&e.jsx(We,{devTools:I}),r==="staleclosure"&&e.jsx(Ve,{devTools:I}),r==="nestedcontext"&&e.jsx(Be,{devTools:I}),r==="modalscope"&&e.jsx(Ge,{devTools:I}),r==="namedactions"&&e.jsx(Je,{devTools:I})]}),e.jsxs("div",{className:"g7dt-footer",children:[e.jsx("span",{children:"Ctrl+Shift+G 토글 | 헤더 드래그로 이동"}),e.jsxs("span",{children:["액션: ",l.length," | 캐시 히트율: ",(c.hitRate*100).toFixed(1),"%"]})]})]}):e.jsx("button",{onClick:()=>s(!0),className:"g7dt-floating-btn",title:"G7 DevTools (Ctrl+Shift+G)",children:e.jsxs("svg",{xmlns:"http://www.w3.org/2000/svg",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"}),e.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M15 12a3 3 0 11-6 0 3 3 0 016 0z"})]})}):t?e.jsxs("div",{className:"g7dt-disabled-notice",children:[e.jsxs("div",{className:"g7dt-flex g7dt-items-center g7dt-justify-between g7dt-mb-2",children:[e.jsx("span",{className:"g7dt-font-bold g7dt-text-yellow",children:"G7 DevTools"}),e.jsx("button",{onClick:()=>s(!1),className:"g7dt-btn",children:"✕"})]}),e.jsx("p",{className:"g7dt-text-sm g7dt-text-gray",children:"DevTools가 비활성화되어 있습니다."}),e.jsx("p",{className:"g7dt-text-xs g7dt-text-gray-dark g7dt-mt-2",children:"환경설정 > 고급 설정 > 디버그 모드를 켜세요."})]}):null};if(typeof window<"u"){const d=window.G7Core||(window.G7Core={});if(d.__devtools={DiagnosticEngine:Z,getServerConnector:R,getStyleTracker:ae,DevToolsPanel:ge},typeof d.__onDevToolsReady=="function")try{d.__onDevToolsReady()}catch{}}$.DevToolsPanel=ge,$.DiagnosticEngine=Z,$.getServerConnector=R,$.getStyleTracker=ae,Object.defineProperty($,Symbol.toStringTag,{value:"Module"})})(this.G7DevToolsBundle=this.G7DevToolsBundle||{},ReactJSXRuntime,React);
|